REDROOM
PHP 8.2.30
Path:
Logout
Edit File
Size: 6.19 MB
Close
//usr/local/sbin/wp
Text
Base64
IyEvdXNyL2Jpbi9lbnYgcGhwCjw/cGhwClBoYXI6Om1hcFBoYXIoKTsKaW5jbHVkZSAncGhhcjovL3dwLWNsaS5waGFyL3BocC9ib290LXBoYXIucGhwJzsKX19IQUxUX0NPTVBJTEVSKCk7ID8+DQqOdwEAYAQAABEAAAABAAsAAAB3cC1jbGkucGhhcgAAAAAjAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL3dwLWNsaS5waHAfBAAA4o3wYR8EAADmrOHxpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9FeGl0RXhjZXB0aW9uLnBocFMAAADijfBhUwAAAHt114SkAQAAAAAAADIAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1N5bm9wc2lzUGFyc2VyLnBocHASAADijfBhcBIAAJxXh12kAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0NvbnRleHQvRnJvbnRlbmQucGhwqgEAAOKN8GGqAQAAQnKBvKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQ29udGV4dC9BZG1pbi5waHAlCgAA4o3wYSUKAABlr2XIpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db250ZXh0L0NsaS5waHCYAQAA4o3wYZgBAADOQenApAEAAAAAAAAwAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db250ZXh0L0F1dG8ucGhwuAcAAOKN8GG4BwAAhB8yjKQBAAAAAAAAKwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQ29udGV4dC5waHBNAgAA4o3wYU0CAACGW05HpAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Gb3JtYXR0ZXIucGhwFSUAAOKN8GEVJQAAy1enq6QBAAAAAAAAMAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvVXBncmFkZXJTa2luLnBocI4GAADijfBhjgYAABvis/ekAQAAAAAAAEoAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0NvbXBhdC9NaW5fUEhQXzVfNi9GZWVkYmFja01ldGhvZFRyYWl0LnBocLMBAADijfBhswEAADyqTtOkAQAAAAAAAEoAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0NvbXBhdC9NaW5fUEhQXzVfNC9GZWVkYmFja01ldGhvZFRyYWl0LnBocAcBAADijfBhBwEAANygmtOkAQAAAAAAAD4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0NvbXBhdC9GZWVkYmFja01ldGhvZFRyYWl0LnBocM4BAADijfBhzgEAAMj46ZakAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0xvZ2dlcnMvRXhlY3V0aW9uLnBocGEHAADijfBhYQcAAHSGFFekAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0xvZ2dlcnMvUmVndWxhci5waHAbCAAA4o3wYRsIAAA1msEhpAEAAAAAAAAwAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Mb2dnZXJzL0Jhc2UucGhw1wgAAOKN8GHXCAAAq59FZaQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvTG9nZ2Vycy9RdWlldC5waHAJBQAA4o3wYQkFAAAtbq6vpAEAAAAAAAAyAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db250ZXh0TWFuYWdlci5waHDdBQAA4o3wYd0FAADGWsHPpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9XcEh0dHBDYWNoZU1hbmFnZXIucGhwawwAAOKN8GFrDAAAFWqhGaQBAAAAAAAAKgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvUnVubmVyLnBocJXeAADijfBhld4AAJs8pAukAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1N5bm9wc2lzVmFsaWRhdG9yLnBocNkOAADijfBh2Q4AAGvqlSWkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0NvbXBsZXRpb25zLnBocDkRAADijfBhOREAAJNq+tukAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0F1dG9sb2FkZXIucGhwLRIAAOKN8GEtEgAACWzx0aQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRG9jUGFyc2VyLnBocBAQAADijfBhEBAAAAoLeFCkAQAAAAAAAEAAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9Jbml0aWFsaXplQ29udGV4dHMucGhwAQQAAOKN8GEBBAAAMENhuaQBAAAAAAAAOgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0xhdW5jaFJ1bm5lci5waHB/AgAA4o3wYX8CAABBgV5VpAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvQm9vdHN0cmFwU3RhdGUucGhwpAUAAOKN8GGkBQAAosCC16QBAAAAAAAASAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0RlY2xhcmVBYnN0cmFjdEJhc2VDb21tYW5kLnBocEECAADijfBhQQIAAK9APECkAQAAAAAAAD4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9EZWNsYXJlTWFpbkNsYXNzLnBocBQCAADijfBhFAIAALcFVGqkAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9Mb2FkRGlzcGF0Y2hlci5waHA1AgAA4o3wYTUCAABVoNs0pAEAAAAAAABEAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5pdGlhbGl6ZUNvbG9yaXphdGlvbi5waHBMAgAA4o3wYUwCAACk2Cc9pAEAAAAAAAA9AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvQ29uZmlndXJlUnVubmVyLnBocDUCAADijfBhNQIAAInfti2kAQAAAAAAAEUAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9EZWZpbmVQcm90ZWN0ZWRDb21tYW5kcy5waHDnBAAA4o3wYecEAAA4xT4ypAEAAAAAAABGAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvRGVjbGFyZUZhbGxiYWNrRnVuY3Rpb25zLnBocEMCAADijfBhQwIAAEAqQmekAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9Mb2FkRXhlY0NvbW1hbmQucGhwVwMAAOKN8GFXAwAABXl+paQBAAAAAAAAOwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0Jvb3RzdHJhcFN0ZXAucGhwxwEAAOKN8GHHAQAAQTcvDKQBAAAAAAAAQQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0xvYWRSZXF1aXJlZENvbW1hbmQucGhwogYAAOKN8GGiBgAA/tju06QBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0xvYWRVdGlsaXR5RnVuY3Rpb25zLnBocCkCAADijfBhKQIAAFRZTd2kAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9BdXRvbG9hZGVyU3RlcC5waHApCQAA4o3wYSkJAACD68KspAEAAAAAAABHAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvUmVnaXN0ZXJGcmFtZXdvcmtDb21tYW5kcy5waHBnBAAA4o3wYWcEAADWPutWpAEAAAAAAAA+AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5pdGlhbGl6ZUxvZ2dlci5waHAqBAAA4o3wYSoEAABcqbAzpAEAAAAAAABIAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5jbHVkZUZyYW1ld29ya0F1dG9sb2FkZXIucGhwygUAAOKN8GHKBQAAh3Q/36QBAAAAAAAARgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL1JlZ2lzdGVyRGVmZXJyZWRDb21tYW5kcy5waHCVBwAA4o3wYZUHAAD4FGsJpAEAAAAAAABHAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5jbHVkZUZhbGxiYWNrQXV0b2xvYWRlci5waHC1AwAA4o3wYbUDAACw+M5TpAEAAAAAAABGAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5jbHVkZVBhY2thZ2VBdXRvbG9hZGVyLnBocAEFAADijfBhAQUAAPDvH0akAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9SdW5uZXJJbnN0YW5jZS5waHCjAgAA4o3wYaMCAACyaxKPpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9GZXRjaGVycy9CYXNlLnBocJUEAADijfBhlQQAAJiKwlWkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0ZldGNoZXJzL1Bvc3QucGhwOQIAAOKN8GE5AgAAyNHy66QBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRmV0Y2hlcnMvVXNlci5waHAwAwAA4o3wYTADAAD+5gb2pAEAAAAAAAA0AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9GZXRjaGVycy9Db21tZW50LnBocH0CAADijfBhfQIAAOjh2gGkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0ZldGNoZXJzL1NpdGUucGhwmAMAAOKN8GGYAwAAeBZrWKQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSXRlcmF0b3JzL1F1ZXJ5LnBocBoMAADijfBhGgwAAOnt1r2kAQAAAAAAADcAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0l0ZXJhdG9ycy9UcmFuc2Zvcm0ucGhwxwEAAOKN8GHHAQAA04B0WaQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSXRlcmF0b3JzL1RhYmxlLnBocGUKAADijfBhZQoAABFAFSukAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0l0ZXJhdG9ycy9DU1YucGhwoQYAAOKN8GGhBgAA+I9iT6QBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSXRlcmF0b3JzL0V4Y2VwdGlvbi5waHBoAAAA4o3wYWgAAAAwTDbSpAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9FeHRyYWN0b3IucGhwQicAAOKN8GFCJwAAPNNaz6QBAAAAAAAAMAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQ29uZmlndXJhdG9yLnBocI4lAADijfBhjiUAAC48eQmkAQAAAAAAAEEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1BhY2thZ2VNYW5hZ2VyRXZlbnRTdWJzY3JpYmVyLnBocKgGAADijfBhqAYAAGc5nsOkAQAAAAAAACwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1dwT3JnQXBpLnBocK0fAADijfBhrR8AANQ5D9ykAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1Byb2Nlc3NSdW4ucGhwKAUAAOKN8GEoBQAAY8ztmaQBAAAAAAAAPQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRGlzcGF0Y2hlci9Db21tYW5kRmFjdG9yeS5waHAKIgAA4o3wYQoiAADB3m42pAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9EaXNwYXRjaGVyL0NvbW1hbmROYW1lc3BhY2UucGhwqwQAAOKN8GGrBAAAckZ8EaQBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRGlzcGF0Y2hlci9Db21wb3NpdGVDb21tYW5kLnBocJcbAADijfBhlxsAAL/4HJekAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Rpc3BhdGNoZXIvUm9vdENvbW1hbmQucGhwSwMAAOKN8GFLAwAAn3kW1aQBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRGlzcGF0Y2hlci9TdWJjb21tYW5kLnBocIo1AADijfBhijUAAHBzF92kAQAAAAAAAD4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Rpc3BhdGNoZXIvQ29tbWFuZEFkZGl0aW9uLnBocCMEAADijfBhIwQAAM/oupukAQAAAAAAACgAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL05vT3AucGhw3QAAAOKN8GHdAAAARMoxBKQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSW5mbGVjdG9yLnBocOY/AADijfBh5j8AAGLK5eikAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1Byb2Nlc3MucGhwVAsAAOKN8GFUCwAA6URrHqQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRmlsZUNhY2hlLnBocLIhAADijfBhsiEAAGsgytOkAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0NvbXBvc2VySU8ucGhwggMAAOKN8GGCAwAAkckrUaQBAAAAAAAAJQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC91dGlscy13cC5waHCVOQAA4o3wYZU5AADTgBiZpAEAAAAAAAAjAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbXBhdC5waHBuEAAA4o3wYW4QAAAdunplpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2ZhbGxiYWNrLWZ1bmN0aW9ucy5waHD0AAAA4o3wYfQAAACGWwRGpAEAAAAAAAAsAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL3dwLXNldHRpbmdzLWNsaS5waHBvQwAA4o3wYW9DAAC1EYJnpAEAAAAAAAApAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NsYXNzLXdwLWNsaS5waHCAqQAA4o3wYYCpAAC8xnZ5pAEAAAAAAAAiAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL3V0aWxzLnBocMTEAADijfBhxMQAAGmhEfqkAQAAAAAAACYAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvYm9vdHN0cmFwLnBocKUIAADijfBhpQgAAF5Zl2akAQAAAAAAACgAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY29uZmlnLXNwZWMucGhwAg4AAOKN8GECDgAAAY38iKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9jbGFzcy13cC1jbGktY29tbWFuZC5waHCNAAAA4o3wYY0AAADJKsP6pAEAAAAAAAAnAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2Rpc3BhdGNoZXIucGhwTQEAAOKN8GFNAQAA4dc6SqQBAAAAAAAAJAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9ib290LWZzLnBocJIBAADijfBhkgEAADz517KkAQAAAAAAADsAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY29tbWFuZHMvc3JjL0NMSV9DYWNoZV9Db21tYW5kLnBocLcEAADijfBhtwQAAP1uP+2kAQAAAAAAADsAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY29tbWFuZHMvc3JjL0NMSV9BbGlhc19Db21tYW5kLnBocHkzAADijfBheTMAALw+2WmkAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY29tbWFuZHMvc3JjL0NMSV9Db21tYW5kLnBocP1OAADijfBh/U4AALsIZ2GkAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY29tbWFuZHMvc3JjL0hlbHBfQ29tbWFuZC5waHBXHAAA4o3wYVccAAAB77xxpAEAAAAAAAAqAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbW1hbmRzL2hlbHAucGhwlAAAAOKN8GGUAAAAbESzBaQBAAAAAAAAKQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9jb21tYW5kcy9jbGkucGhw1AEAAOKN8GHUAQAAam6S/KQBAAAAAAAAEQAAAHBocC9ib290LXBoYXIucGhwOQIAAOKN8GE5AgAAWZC9c6QBAAAAAAAAMAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9iaW4vYnVpbGRfYm9vdHN0cmFwLnBocDsVAADijfBhOxUAAK3Az/qkAQAAAAAAADAAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvYWRlci5waHBCAgAA4o3wYUICAABRgMd5pAEAAAAAAAAwAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9FbmdpbmUucGhw+GMAAOKN8GH4YwAANeMO4aQBAAAAAAAAMQAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvQ29udGV4dC5waHDxGgAA4o3wYfEaAACN/hxEpAEAAAAAAAAwAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2dnZXIucGhwJA0AAOKN8GEkDQAA90BZOaQBAAAAAAAAMgAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvQ29tcGlsZXIucGhwLlgAAOKN8GEuWAAAnvYtoaQBAAAAAAAAQQAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9hZGVyL0ZpbGVzeXN0ZW1Mb2FkZXIucGhw0xAAAOKN8GHTEAAATCR5n6QBAAAAAAAAQAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9hZGVyL0Nhc2NhZGluZ0xvYWRlci5waHD6BgAA4o3wYfoGAAAV5RyppAEAAAAAAAA9AAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2FkZXIvSW5saW5lTG9hZGVyLnBocO4OAADijfBh7g4AAFyJCeGkAQAAAAAAAD4AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvYWRlci9NdXRhYmxlTG9hZGVyLnBocLACAADijfBhsAIAAOG4z2ekAQAAAAAAAEsAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvYWRlci9Qcm9kdWN0aW9uRmlsZXN5c3RlbUxvYWRlci5waHBmCwAA4o3wYWYLAAAUi7GPpAEAAAAAAAA8AAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2FkZXIvQXJyYXlMb2FkZXIucGhw4wcAAOKN8GHjBwAA2yGTD6QBAAAAAAAAPQAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9hZGVyL1N0cmluZ0xvYWRlci5waHDQAwAA4o3wYdADAAA8JaERpAEAAAAAAAAwAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9QYXJzZXIucGhwnCoAAOKN8GGcKgAA21bKhKQBAAAAAAAATAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvRXhjZXB0aW9uL0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbi5waHCiAQAA4o3wYaIBAACsHthRpAEAAAAAAABCAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9FeGNlcHRpb24vTG9naWNFeGNlcHRpb24ucGhwgwEAAOKN8GGDAQAAwn1Br6QBAAAAAAAAQwAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvRXhjZXB0aW9uL1N5bnRheEV4Y2VwdGlvbi5waHCZAwAA4o3wYZkDAAD/ToOapAEAAAAAAABMAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9FeGNlcHRpb24vVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uLnBocNsDAADijfBh2wMAAC24WwCkAQAAAAAAAEoAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi9Vbmtub3duRmlsdGVyRXhjZXB0aW9uLnBocMUDAADijfBhxQMAAOlm/d6kAQAAAAAAAEoAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi9Vbmtub3duSGVscGVyRXhjZXB0aW9uLnBocMUDAADijfBhxQMAAOtI3mqkAQAAAAAAAEQAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi9SdW50aW1lRXhjZXB0aW9uLnBocIkBAADijfBhiQEAADFd0NOkAQAAAAAAAD0AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0NhY2hlL0Fic3RyYWN0Q2FjaGUucGhw4QUAAOKN8GHhBQAAtR9ZYKQBAAAAAAAAOQAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvQ2FjaGUvTm9vcENhY2hlLnBocEEEAADijfBhQQQAAJSIjtmkAQAAAAAAAD8AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0NhY2hlL0ZpbGVzeXN0ZW1DYWNoZS5waHBoEQAA4o3wYWgRAAAofTQZpAEAAAAAAAAvAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9DYWNoZS5waHCiAwAA4o3wYaIDAADyf1empAEAAAAAAAAwAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Tb3VyY2UucGhwGgQAAOKN8GEaBAAAYte2baQBAAAAAAAAPQAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9nZ2VyL1N0cmVhbUxvZ2dlci5waHC5FQAA4o3wYbkVAAC2i/1KpAEAAAAAAAA/AAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2dnZXIvQWJzdHJhY3RMb2dnZXIucGhwdgwAAOKN8GF2DAAAbuVZNqQBAAAAAAAANgAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTGFtYmRhSGVscGVyLnBocNwHAADijfBh3AcAAAiKcNWkAQAAAAAAADoAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0hlbHBlckNvbGxlY3Rpb24ucGhwnw4AAOKN8GGfDgAAHYeO06QBAAAAAAAAMgAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvVGVtcGxhdGUucGhwixMAAOKN8GGLEwAAOAgEqaQBAAAAAAAANAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvQXV0b2xvYWRlci5waHAZCAAA4o3wYRkIAAA9Y6vWpAEAAAAAAABBAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Tb3VyY2UvRmlsZXN5c3RlbVNvdXJjZS5waHCQBwAA4o3wYZAHAABWwI6DpAEAAAAAAAAzAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9FeGNlcHRpb24ucGhwUgEAAOKN8GFSAQAABF11t6QBAAAAAAAAMwAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvVG9rZW5pemVyLnBocIEtAADijfBhgS0AALkhWKmkAQAAAAAAADYAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvQ29va2llL0phci5waHAZDwAA4o3wYRkPAACpgfHxpAEAAAAAAAA0AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1Jlc3BvbnNlLnBocNMJAADijfBh0wkAAHGz+YmkAQAAAAAAADEAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvSG9va3MucGhweAUAAOKN8GF4BQAAS5ZsNaQBAAAAAAAALwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9TU0wucGhw5g4AAOKN8GHmDgAApf02yqQBAAAAAAAAMgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9Ib29rZXIucGhwxQIAAOKN8GHFAgAAPYJ1iaQBAAAAAAAAOgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9UcmFuc3BvcnQvY1VSTC5waHC+QgAA4o3wYb5CAAAo2X3hpAEAAAAAAAA/AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1RyYW5zcG9ydC9mc29ja29wZW4ucGhwzDIAAOKN8GHMMgAAnm0F7KQBAAAAAAAARAAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vVHJhbnNwb3J0L2NVUkwucGhwlwMAAOKN8GGXAwAAXfGQkqQBAAAAAAAAOgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC5waHCMBQAA4o3wYYwFAACm6I5ypAEAAAAAAABCAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQL1Vua25vd24ucGhwZAMAAOKN8GFkAwAAAfG156QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTAucGhwbwEAAOKN8GFvAQAA/F+NN6QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MjgucGhw+gEAAOKN8GH6AQAASpT4MqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDkucGhwewEAAOKN8GF7AQAAhndaQqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MDQucGhwkAEAAOKN8GGQAQAAj9ZZAaQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTYucGhwwAEAAOKN8GHAAQAAxOLpcqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDUucGhwmQEAAOKN8GGZAQAAkHpd8KQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MDEucGhwkAEAAOKN8GGQAQAAYTSNoqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MDUucGhwsQEAAOKN8GGxAQAAuI8rZqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTgucGhw3wEAAOKN8GHfAQAAHwTdhKQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDcucGhwugEAAOKN8GG6AQAAa2+9kaQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDIucGhwkwEAAOKN8GGTAQAAHUhhnaQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTUucGhwpQEAAOKN8GGlAQAAUq0716QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDQucGhwfgEAAOKN8GF+AQAAHl8fuqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDgucGhwkAEAAOKN8GGQAQAA7zGKIqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MzEucGhwGAIAAOKN8GEYAgAAzxjWjaQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDMucGhwfgEAAOKN8GF+AQAAAbpEMaQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDAucGhwhAEAAOKN8GGEAQAARGmnUaQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC8zMDYucGhwhwEAAOKN8GGHAQAATYxvlqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MTEucGhwGAIAAOKN8GEYAgAAmhXpZqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MDMucGhwnAEAAOKN8GGcAQAA2Enb6aQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDEucGhwhwEAAOKN8GGHAQAAaoj5WKQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MDIucGhwhAEAAOKN8GGEAQAA7y4E9qQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTMucGhwqwEAAOKN8GGrAQAAp81I/aQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTQucGhwogEAAOKN8GGiAQAA4s6wG6QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC8zMDQucGhwhwEAAOKN8GGHAQAAOfZBSqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTIucGhwnAEAAOKN8GGcAQAAHu/4t6QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC8zMDUucGhwfgEAAOKN8GF+AQAANC1Pk6QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC81MDAucGhwogEAAOKN8GGiAQAAnWc/HKQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTEucGhwkAEAAOKN8GGQAQAA43nuiKQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MjkucGhwJgIAAOKN8GEmAgAAbU1jJ6QBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MDYucGhwjQEAAOKN8GGNAQAAE1bnIqQBAAAAAAAAPgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vSFRUUC80MTcucGhwmQEAAOKN8GGZAQAACRpFg6QBAAAAAAAAPwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vVHJhbnNwb3J0LnBocEoAAADijfBhSgAAAMU5W6GkAQAAAAAAADYAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvQXV0aC9CYXNpYy5waHCTBwAA4o3wYZMHAADnStRBpAEAAAAAAAAwAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0F1dGgucGhwKgMAAOKN8GEqAwAAdRCQ6aQBAAAAAAAANgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9Qcm94eS9IVFRQLnBocKANAADijfBhoA0AAEGwFySkAQAAAAAAADAAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvSVB2Ni5waHCSEwAA4o3wYZITAADzanttpAEAAAAAAAAxAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1Byb3h5LnBocC0DAADijfBhLQMAAMvfyaekAQAAAAAAADcAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvSUROQUVuY29kZXIucGhwGy0AAOKN8GEbLQAA68yT8KQBAAAAAAAANQAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24ucGhwAwQAAOKN8GEDBAAA7Bgl0KQBAAAAAAAAMgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9Db29raWUucGhw6TIAAOKN8GHpMgAAn5qF4aQBAAAAAAAAMwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9TZXNzaW9uLnBocAAcAADijfBhABwAALHzcBqkAQAAAAAAAE0AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVXRpbGl0eS9DYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5LnBocPsHAADijfBh+wcAAJH38USkAQAAAAAAAEQAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVXRpbGl0eS9GaWx0ZXJlZEl0ZXJhdG9yLnBocJwEAADijfBhnAQAAAmZ8l6kAQAAAAAAAC8AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvSVJJLnBocIlvAADijfBhiW8AAA0Gbg2kAQAAAAAAADwAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvUmVzcG9uc2UvSGVhZGVycy5waHBXCAAA4o3wYVcIAAD2PVE3pAEAAAAAAAA1AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1RyYW5zcG9ydC5waHDFBAAA4o3wYcUEAADk/Sr5pAEAAAAAAAArAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzLnBocN92AADijfBh33YAAJO63UykAQAAAAAAAB8AAAB2ZW5kb3IvY29tcG9zZXIvQ2xhc3NMb2FkZXIucGhwxD4AAOKN8GHEPgAAxjVLeaQBAAAAAAAAPgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvQ2xhc3NMb2FkZXIucGhwxD4AAOKN8GHEPgAAxjVLeaQBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvUGhwRmlsZUNsZWFuZXIucGhw7BwAAOKN8GHsHAAAS9ii6KQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvQXV0b2xvYWRHZW5lcmF0b3IucGhwJcgAAOKN8GElyAAASCCW7aQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvQ2xhc3NNYXBHZW5lcmF0b3IucGhwuTEAAOKN8GG5MQAACM5ShKQBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29uZmlnL0NvbmZpZ1NvdXJjZUludGVyZmFjZS5waHATCQAA4o3wYRMJAACWjf1vpAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25maWcvSnNvbkNvbmZpZ1NvdXJjZS5waHBCKQAA4o3wYUIpAABQ8RTupAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1BhdGhEb3dubG9hZGVyLnBocIguAADijfBhiC4AAGc7eIykAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvRm9zc2lsRG93bmxvYWRlci5waHC4EAAA4o3wYbgQAACruIf9pAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0hnRG93bmxvYWRlci5waHCHDQAA4o3wYYcNAAC0GXxwpAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0d6aXBEb3dubG9hZGVyLnBocHgIAADijfBheAgAALTLlZKkAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvRmlsZXN5c3RlbUV4Y2VwdGlvbi5waHAjAwAA4o3wYSMDAABRe7AopAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0FyY2hpdmVEb3dubG9hZGVyLnBocLwhAADijfBhvCEAADMoHWmkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvUmFyRG93bmxvYWRlci5waHCoCQAA4o3wYagJAACMS5wPpAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1h6RG93bmxvYWRlci5waHACBAAA4o3wYQIEAACbkMnKpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1ppcERvd25sb2FkZXIucGhwCSwAAOKN8GEJLAAAR1tj6aQBAAAAAAAASAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9Eb3dubG9hZGVySW50ZXJmYWNlLnBocIIPAADijfBhgg8AAHip+USkAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvUGVyZm9yY2VEb3dubG9hZGVyLnBocC8NAADijfBhLw0AAJMAkDqkAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvRmlsZURvd25sb2FkZXIucGhwd0wAAOKN8GF3TAAAwJ+4mqQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9Tdm5Eb3dubG9hZGVyLnBocIIiAADijfBhgiIAABsSOCukAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvRHZjc0Rvd25sb2FkZXJJbnRlcmZhY2UucGhwDgMAAOKN8GEOAwAA6nagKKQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9Eb3dubG9hZE1hbmFnZXIucGhwYT4AAOKN8GFhPgAAG9Hm+aQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9DaGFuZ2VSZXBvcnRJbnRlcmZhY2UucGhw/gIAAOKN8GH+AgAA2SnFuKQBAAAAAAAAUQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9NYXhGaWxlU2l6ZUV4Y2VlZGVkRXhjZXB0aW9uLnBocG8BAADijfBhbwEAAL86rqekAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvUGhhckRvd25sb2FkZXIucGhwFAQAAOKN8GEUBAAAhwGZYKQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9UYXJEb3dubG9hZGVyLnBocCQDAADijfBhJAMAAP2y8zOkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvR2l0RG93bmxvYWRlci5waHDPYQAA4o3wYc9hAACwN3lqpAEAAAAAAABHAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1RyYW5zcG9ydEV4Y2VwdGlvbi5waHApBwAA4o3wYSkHAAA0BQBOpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1Zjc0Rvd25sb2FkZXIucGhwSjIAAOKN8GFKMgAABtfAe6QBAAAAAAAAUgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9WY3NDYXBhYmxlRG93bmxvYWRlckludGVyZmFjZS5waHAbAwAA4o3wYRsDAAAGDJyZpAEAAAAAAABNAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9RdWVzdGlvbi9TdHJpY3RDb25maXJtYXRpb25RdWVzdGlvbi5waHC3CgAA4o3wYbcKAADsA0+mpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vQ29tbWFuZEV2ZW50LnBocK0HAADijfBhrQcAAKeoWT6kAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsdWdpbi9Qb3N0RmlsZURvd25sb2FkRXZlbnQucGhwjQ0AAOKN8GGNDQAAyuxRqKQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL1BsdWdpbkV2ZW50cy5waHAnCAAA4o3wYScIAAD10j3tpAEAAAAAAABFAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vUHJlRmlsZURvd25sb2FkRXZlbnQucGhwsQ4AAOKN8GGxDgAAysoEUqQBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL0NhcGFiaWxpdHkvQ2FwYWJpbGl0eS5waHDlAQAA4o3wYeUBAABZObEzpAEAAAAAAABLAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vQ2FwYWJpbGl0eS9Db21tYW5kUHJvdmlkZXIucGhwXwMAAOKN8GFfAwAAgs686KQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL1ByZVBvb2xDcmVhdGVFdmVudC5waHDkEwAA4o3wYeQTAADkcgeipAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vUGx1Z2luSW50ZXJmYWNlLnBocP4GAADijfBh/gYAAEwzf12kAQAAAAAAADgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsdWdpbi9DYXBhYmxlLnBocJsEAADijfBhmwQAACcP8X2kAQAAAAAAAD4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsdWdpbi9QbHVnaW5NYW5hZ2VyLnBocJt6AADijfBhm3oAAE4XeWikAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsdWdpbi9QcmVDb21tYW5kUnVuRXZlbnQucGhwTQUAAOKN8GFNBQAAw5JACaQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9Ob1Byb3h5UGF0dGVybi5waHCyLAAA4o3wYbIsAACBuLxnpAEAAAAAAAA+AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1Byb2Nlc3NFeGVjdXRvci5waHBXOgAA4o3wYVc6AAD3cDKlpAEAAAAAAAAxAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0hnLnBocEsNAADijfBhSw0AAJUyinSkAQAAAAAAADcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvUGVyZm9yY2UucGhwp1EAAOKN8GGnUQAAemw3XqQBAAAAAAAAOwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9FcnJvckhhbmRsZXIucGhw+goAAOKN8GH6CgAAAXswuaQBAAAAAAAAMgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9Tdm4ucGhwaSgAAOKN8GFpKAAAyW3eo6QBAAAAAAAANQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9HaXRMYWIucGhwtBwAAOKN8GG0HAAAoa7ij6QBAAAAAAAAMgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9aaXAucGhwxA0AAOKN8GHEDQAAZt1VOqQBAAAAAAAAMgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9HaXQucGhwDlEAAOKN8GEOUQAAwyKiyKQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9SZW1vdGVGaWxlc3lzdGVtLnBocKeHAADijfBhp4cAAODz+nKkAQAAAAAAADkAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvQXV0aEhlbHBlci5waHC9MwAA4o3wYb0zAACybYG5pAEAAAAAAAA+AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0NvbmZpZ1ZhbGlkYXRvci5waHCkIgAA4o3wYaQiAACRk14MpAEAAAAAAAA3AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1NpbGVuY2VyLnBocJEIAADijfBhkQgAAPk+vOWkAQAAAAAAADgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvVGxzSGVscGVyLnBocHEaAADijfBhcRoAAHoZIHekAQAAAAAAADgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvQml0YnVja2V0LnBocHIkAADijfBhciQAAPNBWtSkAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSHR0cERvd25sb2FkZXIucGhwVUcAAOKN8GFVRwAA3eIrf6QBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9NZXRhZGF0YU1pbmlmaWVyLnBocHECAADijfBhcQIAAPGSdFikAQAAAAAAADwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSHR0cC9SZXNwb25zZS5waHDZCwAA4o3wYdkLAADkntqmpAEAAAAAAAA/AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0h0dHAvUHJveHlIZWxwZXIucGhwrBUAAOKN8GGsFQAAOxI6aKQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9IdHRwL1Byb3h5TWFuYWdlci5waHCMEwAA4o3wYYwTAAB01s3CpAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0h0dHAvUmVxdWVzdFByb3h5LnBocM8HAADijfBhzwcAAI8sOk6kAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSHR0cC9DdXJsRG93bmxvYWRlci5waHASbAAA4o3wYRJsAACqi4ZPpAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0h0dHAvQ3VybFJlc3BvbnNlLnBocIsFAADijfBhiwUAAIEBdKykAQAAAAAAADIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvVGFyLnBocFgHAADijfBhWAcAAKtXCVekAQAAAAAAADkAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvRmlsZXN5c3RlbS5waHA2bwAA4o3wYTZvAACFCxnGpAEAAAAAAAA3AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1BsYXRmb3JtLnBocPIdAADijfBh8h0AABUZT5ekAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvU3RyZWFtQ29udGV4dEZhY3RvcnkucGhwRiUAAOKN8GFGJQAAeylBeqQBAAAAAAAAOQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9TeW5jSGVscGVyLnBocM0JAADijfBhzQkAAOPbimSkAQAAAAAAADUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvR2l0SHViLnBocFsfAADijfBhWx8AALyEh6mkAQAAAAAAADgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSW5pSGVscGVyLnBocGMGAADijfBhYwYAAM8ELK6kAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvQ29tcG9zZXJNaXJyb3IucGhwFgoAAOKN8GEWCgAA8UTn8aQBAAAAAAAAPAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9QYWNrYWdlU29ydGVyLnBocIcKAADijfBhhwoAACn7hVykAQAAAAAAADMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvTG9vcC5waHAeDgAA4o3wYR4OAACYPSzNpAEAAAAAAAAyAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1VybC5waHCwFAAA4o3wYbAUAAAIvkyOpAEAAAAAAAAwAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25maWcucGhwtFgAAOKN8GG0WAAAV+PPQaQBAAAAAAAANgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvU2NyaXB0L0V2ZW50LnBocFsLAADijfBhWwsAACZtpNSkAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1NjcmlwdC9TY3JpcHRFdmVudHMucGhwJw4AAOKN8GEnDgAA+SCBxqQBAAAAAAAAMgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tcGlsZXIucGhwVjAAAOKN8GFWMAAAUNqIBaQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRXhjZXB0aW9uL05vU3NsRXhjZXB0aW9uLnBocNoBAADijfBh2gEAADhNNe2kAQAAAAAAAFIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0V4Y2VwdGlvbi9JcnJlY292ZXJhYmxlRG93bmxvYWRFeGNlcHRpb24ucGhwpgEAAOKN8GGmAQAAih+LLaQBAAAAAAAAOwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVkVmVyc2lvbnMucGhwjzoAAOKN8GGPOgAAVPDTIqQBAAAAAAAALwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ2FjaGUucGhwjCgAAOKN8GGMKAAAwKiWf6QBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9QbGF0Zm9ybVJlcG9zaXRvcnkucGhwv30AAOKN8GG/fQAA8MsG36QBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9Db21wb3NlclJlcG9zaXRvcnkucGhwIvoAAOKN8GEi+gAAtycleqQBAAAAAAAASAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9Mb2NrQXJyYXlSZXBvc2l0b3J5LnBocG0CAADijfBhbQIAAM/+IYekAQAAAAAAAE0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvSW5zdGFsbGVkQXJyYXlSZXBvc2l0b3J5LnBocMMDAADijfBhwwMAABuwaZWkAQAAAAAAAEoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUm9vdFBhY2thZ2VSZXBvc2l0b3J5LnBocAoDAADijfBhCgMAAGJTwCKkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzUmVwb3NpdG9yeS5waHCAUQAA4o3wYYBRAAAoAKV1pAEAAAAAAABEAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0FycmF5UmVwb3NpdG9yeS5waHD5KQAA4o3wYfkpAAC1rWJapAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0luc3RhbGxlZFJlcG9zaXRvcnkucGhw2jIAAOKN8GHaMgAAhTgbaKQBAAAAAAAAVAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9Db25maWd1cmFibGVSZXBvc2l0b3J5SW50ZXJmYWNlLnBocAUCAADijfBhBQIAANbrh++kAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvRmlsdGVyUmVwb3NpdG9yeS5waHDyFAAA4o3wYfIUAACs/eUtpAEAAAAAAABHAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0FydGlmYWN0UmVwb3NpdG9yeS5waHBfEQAA4o3wYV8RAAAxzgeFpAEAAAAAAABPAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0ludmFsaWRSZXBvc2l0b3J5RXhjZXB0aW9uLnBocN8BAADijfBh3wEAAOac5ySkAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvV3JpdGFibGVBcnJheVJlcG9zaXRvcnkucGhwugcAAOKN8GG6BwAA5CdhcKQBAAAAAAAAUAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9Xcml0YWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UucGhwFAcAAOKN8GEUBwAAKZDrhqQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WZXJzaW9uQ2FjaGVJbnRlcmZhY2UucGhwlgIAAOKN8GGWAgAAlm3bWaQBAAAAAAAAUAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9SZXBvc2l0b3J5U2VjdXJpdHlFeGNlcHRpb24ucGhw4gEAAOKN8GHiAQAAEDw576QBAAAAAAAASAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9SZXBvc2l0b3J5SW50ZXJmYWNlLnBocMoSAADijfBhyhIAAALc1zmkAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUGF0aFJlcG9zaXRvcnkucGhwOiAAAOKN8GE6IAAAc3VQeaQBAAAAAAAAUgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9JbnN0YWxsZWRGaWxlc3lzdGVtUmVwb3NpdG9yeS5waHDOAgAA4o3wYc4CAAC/3qF4pAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1JlcG9zaXRvcnlGYWN0b3J5LnBocI4dAADijfBhjh0AAFdsYT+kAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUGVhclJlcG9zaXRvcnkucGhwMgMAAOKN8GEyAwAAm8jbJ6QBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9QYWNrYWdlUmVwb3NpdG9yeS5waHAaBwAA4o3wYRoHAADOfqLQpAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0NvbXBvc2l0ZVJlcG9zaXRvcnkucGhwaxUAAOKN8GFrFQAAIQZgVaQBAAAAAAAAUQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9JbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlLnBocL8CAADijfBhvwIAAN/J2sCkAQAAAAAAAEkAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvRmlsZXN5c3RlbVJlcG9zaXRvcnkucGhwuC8AAOKN8GG4LwAA6tliy6QBAAAAAAAARQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvR2l0SHViRHJpdmVyLnBocDdSAADijfBhN1IAAOUrdROkAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL1BlcmZvcmNlRHJpdmVyLnBocB4QAADijfBhHhAAAP9oo2OkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL0dpdERyaXZlci5waHC+HgAA4o3wYb4eAAApTAVwpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9Tdm5Ecml2ZXIucGhw7jAAAOKN8GHuMAAApjuRHaQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvVmNzRHJpdmVyLnBocKQTAADijfBhpBMAADdShm2kAQAAAAAAAEsAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL1Zjc0RyaXZlckludGVyZmFjZS5waHAlDQAA4o3wYSUNAADKCyW1pAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9IZ0RyaXZlci5waHADHAAA4o3wYQMcAAAyluxlpAEAAAAAAABFAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9HaXRMYWJEcml2ZXIucGhwEk8AAOKN8GESTwAABaluNqQBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvR2l0Qml0YnVja2V0RHJpdmVyLnBocDg/AADijfBhOD8AAFe4l6ukAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL0Zvc3NpbERyaXZlci5waHAOHgAA4o3wYQ4eAABkFBhypAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1JlcG9zaXRvcnlNYW5hZ2VyLnBocLAYAADijfBhsBgAAABnfbmkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUmVwb3NpdG9yeVNldC5waHD6MgAA4o3wYfoyAACO4I0bpAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvTWV0YXBhY2thZ2VJbnN0YWxsZXIucGhwlAwAAOKN8GGUDAAA3RcSe6QBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL0xpYnJhcnlJbnN0YWxsZXIucGhweSkAAOKN8GF5KQAAuIxpA6QBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL1BsdWdpbkluc3RhbGxlci5waHCeDwAA4o3wYZ4PAACkt++hpAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvTm9vcEluc3RhbGxlci5waHARCwAA4o3wYRELAADI1n/BpAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvSW5zdGFsbGVySW50ZXJmYWNlLnBocLYSAADijfBhthIAAPx9knukAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9JbnN0YWxsZXJFdmVudC5waHD4BwAA4o3wYfgHAAB+uCwIpAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvQmluYXJ5SW5zdGFsbGVyLnBocEE5AADijfBhQTkAAKnIiw6kAQAAAAAAAEAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9QYWNrYWdlRXZlbnQucGhwTQoAAOKN8GFNCgAAP3nHJaQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL1Byb2plY3RJbnN0YWxsZXIucGhwkA0AAOKN8GGQDQAA3TMrlaQBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL0JpbmFyeVByZXNlbmNlSW50ZXJmYWNlLnBocPYCAADijfBh9gIAAIr3mfekAQAAAAAAAE0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9TdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyLnBocBkhAADijfBhGSEAAIxLKVOkAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9JbnN0YWxsYXRpb25NYW5hZ2VyLnBocKpiAADijfBhqmIAAJ3jdSOkAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9JbnN0YWxsZXJFdmVudHMucGhwewIAAOKN8GF7AgAA9Nkz46QBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL1BhY2thZ2VFdmVudHMucGhw5AcAAOKN8GHkBwAAWrtWrKQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvU2VsZlVwZGF0ZS9WZXJzaW9ucy5waHA2DAAA4o3wYTYMAADWRaHIpAEAAAAAAAA5AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9TZWxmVXBkYXRlL0tleXMucGhwzAMAAOKN8GHMAwAARKoHCKQBAAAAAAAAbgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRmlsdGVyL1BsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIvSWdub3JlTGlzdFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIucGhwDQkAAOKN8GENCQAAaeUeAKQBAAAAAAAAawAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRmlsdGVyL1BsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIvUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3RvcnkucGhwhgQAAOKN8GGGBAAAfpMN8qQBAAAAAAAAbQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRmlsdGVyL1BsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIvUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZS5waHDRAAAA4o3wYdEAAABWH+6kpAEAAAAAAABxAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9GaWx0ZXIvUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlci9JZ25vcmVOb3RoaW5nUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlci5waHAnAQAA4o3wYScBAAB1sMM4pAEAAAAAAABtAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9GaWx0ZXIvUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlci9JZ25vcmVBbGxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLnBocHUBAADijfBhdQEAAA12DbCkAQAAAAAAAFIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0V2ZW50RGlzcGF0Y2hlci9TY3JpcHRFeGVjdXRpb25FeGNlcHRpb24ucGhwpgEAAOKN8GGmAQAAXCEnxqQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRXZlbnREaXNwYXRjaGVyL0V2ZW50LnBocJEIAADijfBhkQgAAEp2VcGkAQAAAAAAAFIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0V2ZW50RGlzcGF0Y2hlci9FdmVudFN1YnNjcmliZXJJbnRlcmZhY2UucGhwXAYAAOKN8GFcBgAAnbm/KqQBAAAAAAAASQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRXZlbnREaXNwYXRjaGVyL0V2ZW50RGlzcGF0Y2hlci5waHBnXQAA4o3wYWddAADDU2HXpAEAAAAAAABLAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUnVsZVdhdGNoR3JhcGgucGhwVxkAAOKN8GFXGQAAQZFc0KQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1Bvb2xPcHRpbWl6ZXIucGhwrkUAAOKN8GGuRQAA05ICU6QBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1NvbHZlci5waHCxaAAA4o3wYbFoAACLpdL9pAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUnVsZS5waHCiTwAA4o3wYaJPAAADrGRrpAEAAAAAAABUAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvU29sdmVyUHJvYmxlbXNFeGNlcHRpb24ucGhw9hUAAOKN8GH2FQAAl+lS8qQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGUyTGl0ZXJhbHMucGhwfAoAAOKN8GF8CgAA8J4BqqQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGVXYXRjaE5vZGUucGhwdAsAAOKN8GF0CwAAj2eMh6QBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGVTZXQucGhwFBQAAOKN8GEUFAAAKQCOeaQBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1Bvb2wucGhw0CEAAOKN8GHQIQAA0SJncKQBAAAAAAAATgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL011bHRpQ29uZmxpY3RSdWxlLnBocDcKAADijfBhNwoAANhsWKukAQAAAAAAAGQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9PcGVyYXRpb24vTWFya0FsaWFzVW5pbnN0YWxsZWRPcGVyYXRpb24ucGhwDQUAAOKN8GENBQAAOADMy6QBAAAAAAAAVgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL09wZXJhdGlvbi9Tb2x2ZXJPcGVyYXRpb24ucGhwEQMAAOKN8GERAwAAaWCFPKQBAAAAAAAAVgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL09wZXJhdGlvbi9VcGRhdGVPcGVyYXRpb24ucGhwTgsAAOKN8GFOCwAA/n0FpKQBAAAAAAAAWQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL09wZXJhdGlvbi9PcGVyYXRpb25JbnRlcmZhY2UucGhwkwMAAOKN8GGTAwAAClkveqQBAAAAAAAAYgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL09wZXJhdGlvbi9NYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb24ucGhwBwUAAOKN8GEHBQAARBQK0KQBAAAAAAAAWQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL09wZXJhdGlvbi9Vbmluc3RhbGxPcGVyYXRpb24ucGhwKgUAAOKN8GEqBQAALvJuHKQBAAAAAAAAVwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL09wZXJhdGlvbi9JbnN0YWxsT3BlcmF0aW9uLnBocEAFAADijfBhQAUAAAEkWkCkAQAAAAAAAFEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9Mb2NhbFJlcG9UcmFuc2FjdGlvbi5waHAVAwAA4o3wYRUDAAAsNIIZpAEAAAAAAABMAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvTG9ja1RyYW5zYWN0aW9uLnBocF8WAADijfBhXxYAAERYuJikAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9SdWxlU2V0SXRlcmF0b3IucGhwcAsAAOKN8GFwCwAAk+8Qa6QBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGVXYXRjaENoYWluLnBocL0FAADijfBhvQUAAOEU1bukAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9HZW5lcmljUnVsZS5waHCjBwAA4o3wYaMHAABQ93uGpAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvRGVjaXNpb25zLnBocN8cAADijfBh3xwAAD3fFM6kAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9Qb2xpY3lJbnRlcmZhY2UucGhwiQMAAOKN8GGJAwAAD95QaqQBAAAAAAAATwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1NvbHZlckJ1Z0V4Y2VwdGlvbi5waHAsAwAA4o3wYSwDAABmsW8cpAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUG9vbEJ1aWxkZXIucGhwmHgAAOKN8GGYeAAAntTu5KQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1Byb2JsZW0ucGhwJGoAAOKN8GEkagAAOlyV9KQBAAAAAAAATQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGVTZXRHZW5lcmF0b3IucGhwjzQAAOKN8GGPNAAAtRTTn6QBAAAAAAAASAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1RyYW5zYWN0aW9uLnBocJA2AADijfBhkDYAAPqygRSkAQAAAAAAAEQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9SZXF1ZXN0LnBocCogAADijfBhKiAAADUmPnekAQAAAAAAAEoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9EZWZhdWx0UG9saWN5LnBocPodAADijfBh+h0AAFoFCMWkAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbnNvbGUvSHRtbE91dHB1dEZvcm1hdHRlci5waHD4CwAA4o3wYfgLAAALOgBCpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25zb2xlL0FwcGxpY2F0aW9uLnBocP1iAADijfBh/WIAABlCmfukAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbnNvbGUvR2l0aHViQWN0aW9uRXJyb3IucGhwJAkAAOKN8GEkCQAAVBHESKQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9SdW5TY3JpcHRDb21tYW5kLnBocGcUAADijfBhZxQAAA+O4rakAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvSW5pdENvbW1hbmQucGhwmq0AAOKN8GGarQAAZE4UIqQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9TY3JpcHRBbGlhc0NvbW1hbmQucGhwlwgAAOKN8GGXCAAAXmaPzKQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9SZXF1aXJlQ29tbWFuZC5waHD1WAAA4o3wYfVYAACb+gRHpAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0RlcGVuZHNDb21tYW5kLnBocBwHAADijfBhHAcAAIxtD8CkAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQ3JlYXRlUHJvamVjdENvbW1hbmQucGhwj14AAOKN8GGPXgAAOFdluKQBAAAAAAAARQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9EdW1wQXV0b2xvYWRDb21tYW5kLnBocKUUAADijfBhpRQAAPgoNLukAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvUmVpbnN0YWxsQ29tbWFuZC5waHCuHwAA4o3wYa4fAACu6XB2pAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0NsZWFyQ2FjaGVDb21tYW5kLnBocPgIAADijfBh+AgAAFgwPMukAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvUmVtb3ZlQ29tbWFuZC5waHAuOAAA4o3wYS44AADas4bVpAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0luc3RhbGxDb21tYW5kLnBocDUeAADijfBhNR4AAJoFyK+kAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvT3V0ZGF0ZWRDb21tYW5kLnBocNwTAADijfBh3BMAAPtM74ekAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvRGlhZ25vc2VDb21tYW5kLnBocNZsAADijfBh1mwAAD255aKkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvUHJvaGliaXRzQ29tbWFuZC5waHDWBwAA4o3wYdYHAACVmUREpAEAAAAAAAA/AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL1NlYXJjaENvbW1hbmQucGhwvxIAAOKN8GG/EgAA9kGQlKQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9Db25maWdDb21tYW5kLnBocHuJAADijfBhe4kAAHM+tPykAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQmFzZUNvbW1hbmQucGhwKCYAAOKN8GEoJgAAhqm3DKQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9FeGVjQ29tbWFuZC5waHDTDQAA4o3wYdMNAADOksv8pAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0hvbWVDb21tYW5kLnBocA4WAADijfBhDhYAAHzMkNikAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvVXBkYXRlQ29tbWFuZC5waHCFQQAA4o3wYYVBAACTSn5YpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL1Nob3dDb21tYW5kLnBocLnXAADijfBhudcAAMdRddWkAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvU3RhdHVzQ29tbWFuZC5waHAvIQAA4o3wYS8hAAD5osG/pAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0xpY2Vuc2VzQ29tbWFuZC5waHBPHAAA4o3wYU8cAAAE0XftpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0Z1bmRDb21tYW5kLnBocCQVAADijfBhJBUAADLKHEOkAQAAAAAAAEoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQ2hlY2tQbGF0Zm9ybVJlcXNDb21tYW5kLnBocEMfAADijfBhQx8AAMKal7SkAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvR2xvYmFsQ29tbWFuZC5waHCnDwAA4o3wYacPAAB6QAt+pAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0FyY2hpdmVDb21tYW5kLnBocHUeAADijfBhdR4AAACGezykAQAAAAAAAD4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQWJvdXRDb21tYW5kLnBocBwFAADijfBhHAUAAHGneTmkAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvU2VsZlVwZGF0ZUNvbW1hbmQucGhws2QAAOKN8GGzZAAACMVK9KQBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9CYXNlRGVwZW5kZW5jeUNvbW1hbmQucGhwhiMAAOKN8GGGIwAAm25HOqQBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9TdWdnZXN0c0NvbW1hbmQucGhw8Q8AAOKN8GHxDwAAquxRY6QBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9WYWxpZGF0ZUNvbW1hbmQucGhw2SsAAOKN8GHZKwAARfxN4aQBAAAAAAAAMQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRmFjdG9yeS5waHDBbwAA4o3wYcFvAACTVTCYpAEAAAAAAAAzAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIucGhwJM8AAOKN8GEkzwAA0eGJp6QBAAAAAAAANgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSU8vQ29uc29sZUlPLnBocB4qAADijfBhHioAAGomVYWkAQAAAAAAADMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0lPL051bGxJTy5waHDqCAAA4o3wYeoIAACH5b5EpAEAAAAAAAAzAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JTy9CYXNlSU8ucGhwdBwAAOKN8GF0HAAAD3jKGaQBAAAAAAAAOAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSU8vSU9JbnRlcmZhY2UucGhwIB8AAOKN8GEgHwAAk9ZaC6QBAAAAAAAANQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSU8vQnVmZmVySU8ucGhwnQsAAOKN8GGdCwAASUwbW6QBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9QYWNrYWdlSW50ZXJmYWNlLnBocB0tAADijfBhHS0AAPmeigakAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQ29tcGxldGVQYWNrYWdlLnBocFUSAADijfBhVRIAAGRv99akAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvTG9hZGVyL0xvYWRlckludGVyZmFjZS5waHB6BAAA4o3wYXoEAACU8zNIpAEAAAAAAABQAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xvYWRlci9JbnZhbGlkUGFja2FnZUV4Y2VwdGlvbi5waHAmBQAA4o3wYSYFAADVSR6bpAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xvYWRlci9Kc29uTG9hZGVyLnBocMgFAADijfBhyAUAALQPWbKkAQAAAAAAAE4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvTG9hZGVyL1ZhbGlkYXRpbmdBcnJheUxvYWRlci5waHBacQAA4o3wYVpxAAD9YDZlpAEAAAAAAABEAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xvYWRlci9BcnJheUxvYWRlci5waHCNRQAA4o3wYY1FAAD1gZihpAEAAAAAAABKAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xvYWRlci9Sb290UGFja2FnZUxvYWRlci5waHC7LAAA4o3wYbssAABZKrPepAEAAAAAAAA+AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FsaWFzUGFja2FnZS5waHATJQAA4o3wYRMlAADpiSv1pAEAAAAAAAA4AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xvY2tlci5waHAiRAAA4o3wYSJEAAAJsCn8pAEAAAAAAAA5AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL1BhY2thZ2UucGhwGUYAAOKN8GEZRgAAX4JOkqQBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Db21wbGV0ZUFsaWFzUGFja2FnZS5waHBwDgAA4o3wYXAOAAC9TlyUpAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0NvbXBhcmVyL0NvbXBhcmVyLnBocDcRAADijfBhNxEAAErpsYSkAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvUm9vdFBhY2thZ2UucGhwwQoAAOKN8GHBCgAAerjQ66QBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Sb290QWxpYXNQYWNrYWdlLnBocJISAADijfBhkhIAANXlOyukAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvUm9vdFBhY2thZ2VJbnRlcmZhY2UucGhw/BIAAOKN8GH8EgAABz9zP6QBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9QaGFyQXJjaGl2ZXIucGhwHwwAAOKN8GEfDAAAUn32lqQBAAAAAAAAUAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9BcmNoaXZhYmxlRmlsZXNGaW5kZXIucGhwagsAAOKN8GFqCwAA3F9draQBAAAAAAAATAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9CYXNlRXhjbHVkZUZpbHRlci5waHCyEAAA4o3wYbIQAAABbeW2pAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FyY2hpdmVyL1ppcEFyY2hpdmVyLnBocB0LAADijfBhHQsAALmkKS6kAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQXJjaGl2ZXIvQXJjaGl2ZXJJbnRlcmZhY2UucGhwagUAAOKN8GFqBQAAEl1hQ6QBAAAAAAAASQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9BcmNoaXZlTWFuYWdlci5waHCeGwAA4o3wYZ4bAACtcYPbpAEAAAAAAABQAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FyY2hpdmVyL0NvbXBvc2VyRXhjbHVkZUZpbHRlci5waHBaAwAA4o3wYVoDAAD86JxrpAEAAAAAAABQAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FyY2hpdmVyL0FyY2hpdmFibGVGaWxlc0ZpbHRlci5waHBdBAAA4o3wYV0EAABh+YcEpAEAAAAAAABLAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FyY2hpdmVyL0dpdEV4Y2x1ZGVGaWx0ZXIucGhwwgYAAOKN8GHCBgAAss2A1aQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Db21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UucGhwwxIAAOKN8GHDEgAAvEeboKQBAAAAAAAANgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9MaW5rLnBocKkPAADijfBhqQ8AAE+RnUWkAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvVmVyc2lvbi9WZXJzaW9uUGFyc2VyLnBocJ0MAADijfBhnQwAADORTdWkAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvVmVyc2lvbi9WZXJzaW9uR3Vlc3Nlci5waHDOPwAA4o3wYc4/AADQ29sLpAEAAAAAAABJAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL1ZlcnNpb24vVmVyc2lvblNlbGVjdG9yLnBocJsoAADijfBhmygAAFpiE12kAQAAAAAAAEkAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvVmVyc2lvbi9TdGFiaWxpdHlGaWx0ZXIucGhwKQcAAOKN8GEpBwAAP1rVoKQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9EdW1wZXIvQXJyYXlEdW1wZXIucGhwMxQAAOKN8GEzFAAAkyOTg6QBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9CYXNlUGFja2FnZS5waHDSHAAA4o3wYdIcAABI216+pAEAAAAAAAAyAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21wb3Nlci5waHAIGgAA4o3wYQgaAAC/jr46pAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Kc29uL0pzb25WYWxpZGF0aW9uRXhjZXB0aW9uLnBocGUDAADijfBhZQMAAAOyecykAQAAAAAAAD4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0pzb24vSnNvbk1hbmlwdWxhdG9yLnBocCtRAADijfBhK1EAAAJAtJCkAQAAAAAAADwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0pzb24vSnNvbkZvcm1hdHRlci5waHC6EQAA4o3wYboRAADWRHzgpAEAAAAAAAA3AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Kc29uL0pzb25GaWxlLnBocEsrAADijfBhSysAAFs5kbqkAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsYXRmb3JtL0hodm1EZXRlY3Rvci5waHAQCAAA4o3wYRAIAACgY8uypAEAAAAAAAA6AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbGF0Zm9ybS9WZXJzaW9uLnBocJgLAADijfBhmAsAADTTbrOkAQAAAAAAADoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsYXRmb3JtL1J1bnRpbWUucGhwTgkAAOKN8GFOCQAAidIqYKQBAAAAAAAAKgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvYm9vdHN0cmFwLnBocBIDAADijfBhEgMAAKC7dSmkAQAAAAAAACEAAAB2ZW5kb3IvY29tcG9zZXIvYXV0b2xvYWRfcmVhbC5waHBFCgAA4o3wYUUKAACrHmRWpAEAAAAAAAAlAAAAdmVuZG9yL2NvbXBvc2VyL2F1dG9sb2FkX2NsYXNzbWFwLnBocIABAADijfBhgAEAAAU767SkAQAAAAAAADIAAAB2ZW5kb3IvY29tcG9zZXIvc3BkeC1saWNlbnNlcy9zcmMvU3BkeExpY2Vuc2VzLnBocHcmAADijfBhdyYAAMtOGrGkAQAAAAAAACoAAAB2ZW5kb3IvY29tcG9zZXIvY2EtYnVuZGxlL3NyYy9DYUJ1bmRsZS5waHDbRAAA4o3wYdtEAABB9hHKpAEAAAAAAAAdAAAAdmVuZG9yL2NvbXBvc2VyL2luc3RhbGxlZC5waHBRUwAA4o3wYVFTAADXlUQHpAEAAAAAAAAtAAAAdmVuZG9yL2NvbXBvc2VyL3hkZWJ1Zy1oYW5kbGVyL3NyYy9TdGF0dXMucGhwKxUAAOKN8GErFQAAGyZl56QBAAAAAAAAMAAAAHZlbmRvci9jb21wb3Nlci94ZGVidWctaGFuZGxlci9zcmMvUGhwQ29uZmlnLnBocI0IAADijfBhjQgAAFE9RPWkAQAAAAAAADQAAAB2ZW5kb3IvY29tcG9zZXIveGRlYnVnLWhhbmRsZXIvc3JjL1hkZWJ1Z0hhbmRsZXIucGhwb1UAAOKN8GFvVQAAv7KlvKQBAAAAAAAALgAAAHZlbmRvci9jb21wb3Nlci94ZGVidWctaGFuZGxlci9zcmMvUHJvY2Vzcy5waHB3DAAA4o3wYXcMAADDw7ANpAEAAAAAAAAjAAAAdmVuZG9yL2NvbXBvc2VyL2F1dG9sb2FkX3N0YXRpYy5waHCgLgAA4o3wYaAuAAAhIkRzpAEAAAAAAAAqAAAAdmVuZG9yL2NvbXBvc2VyL3BjcmUvc3JjL1BjcmVFeGNlcHRpb24ucGhw3QUAAOKN8GHdBQAAZQcsjKQBAAAAAAAANgAAAHZlbmRvci9jb21wb3Nlci9wY3JlL3NyYy9NYXRjaEFsbFdpdGhPZmZzZXRzUmVzdWx0LnBocJUEAADijfBhlQQAAA+xii2kAQAAAAAAACIAAAB2ZW5kb3IvY29tcG9zZXIvcGNyZS9zcmMvUmVnZXgucGhwYRIAAOKN8GFhEgAAWM9+5aQBAAAAAAAAIQAAAHZlbmRvci9jb21wb3Nlci9wY3JlL3NyYy9QcmVnLnBocD4qAADijfBhPioAADYlDcakAQAAAAAAACgAAAB2ZW5kb3IvY29tcG9zZXIvcGNyZS9zcmMvTWF0Y2hSZXN1bHQucGhw7gIAAOKN8GHuAgAABom44qQBAAAAAAAAKwAAAHZlbmRvci9jb21wb3Nlci9wY3JlL3NyYy9NYXRjaEFsbFJlc3VsdC5waHB2AwAA4o3wYXYDAAD00So6pAEAAAAAAAAqAAAAdmVuZG9yL2NvbXBvc2VyL3BjcmUvc3JjL1JlcGxhY2VSZXN1bHQucGhw+AIAAOKN8GH4AgAAtkvTMqQBAAAAAAAAMwAAAHZlbmRvci9jb21wb3Nlci9wY3JlL3NyYy9NYXRjaFdpdGhPZmZzZXRzUmVzdWx0LnBocNoDAADijfBh2gMAAHBhOHekAQAAAAAAACcAAAB2ZW5kb3IvY29tcG9zZXIvYXV0b2xvYWRfbmFtZXNwYWNlcy5waHDDAQAA4o3wYcMBAAAnb+azpAEAAAAAAAAlAAAAdmVuZG9yL2NvbXBvc2VyL0luc3RhbGxlZFZlcnNpb25zLnBocI86AADijfBhjzoAAFTw0yKkAQAAAAAAACIAAAB2ZW5kb3IvY29tcG9zZXIvYXV0b2xvYWRfZmlsZXMucGhw2gwAAOKN8GHaDAAA5m2R5qQBAAAAAAAALAAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL1ZlcnNpb25QYXJzZXIucGhwFVQAAOKN8GEVVAAAd9dO8KQBAAAAAAAAJwAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0ludGVydmFsLnBocH4HAADijfBhfgcAAEV8vFakAQAAAAAAADQAAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9Db25zdHJhaW50L0NvbnN0cmFpbnQucGhw9jEAAOKN8GH2MQAA9ZMu5aQBAAAAAAAAOQAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0NvbnN0cmFpbnQvTXVsdGlDb25zdHJhaW50LnBocEElAADijfBhQSUAAOLEd5ukAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9Db25zdHJhaW50L0NvbnN0cmFpbnRJbnRlcmZhY2UucGhwtgcAAOKN8GG2BwAA2M92eKQBAAAAAAAALwAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0NvbnN0cmFpbnQvQm91bmQucGhwZQoAAOKN8GFlCgAAHqpNtaQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0NvbnN0cmFpbnQvTWF0Y2hOb25lQ29uc3RyYWludC5waHC+BQAA4o3wYb4FAAA/VD69pAEAAAAAAAA8AAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvQ29uc3RyYWludC9NYXRjaEFsbENvbnN0cmFpbnQucGhwxAUAAOKN8GHEBQAA7kTF5aQBAAAAAAAAKAAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0ludGVydmFscy5waHCcTwAA4o3wYZxPAAAEM/f6pAEAAAAAAAApAAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvQ29tcGFyYXRvci5waHBECgAA4o3wYUQKAADImNyBpAEAAAAAAAAvAAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvQ29tcGlsaW5nTWF0Y2hlci5waHC9CAAA4o3wYb0IAACA0B+4pAEAAAAAAAAlAAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvU2VtdmVyLnBocD8NAADijfBhPw0AAD278vukAQAAAAAAADoAAAB2ZW5kb3IvY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIvc3JjL01ldGFkYXRhTWluaWZpZXIucGhwsgoAAOKN8GGyCgAA1mzvM6QBAAAAAAAAIQAAAHZlbmRvci9jb21wb3Nlci9hdXRvbG9hZF9wc3I0LnBocFwMAADijfBhXAwAADPF+9WkAQAAAAAAACIAAAB2ZW5kb3IvY29tcG9zZXIvcGxhdGZvcm1fY2hlY2sucGhwnQMAAOKN8GGdAwAAVJGRdKQBAAAAAAAAJwAAAHZlbmRvci9zeW1mb255L3BvbHlmaWxsLWN0eXBlL0N0eXBlLnBocH0YAADijfBhfRgAAFyK6LCkAQAAAAAAACsAAAB2ZW5kb3Ivc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZS9ib290c3RyYXAucGhwBAYAAOKN8GEEBgAAwDAx9qQBAAAAAAAAKQAAAHZlbmRvci9zeW1mb255L2ZpbGVzeXN0ZW0vTG9ja0hhbmRsZXIucGhwPg8AAOKN8GE+DwAAOABIC6QBAAAAAAAAPAAAAHZlbmRvci9zeW1mb255L2ZpbGVzeXN0ZW0vRXhjZXB0aW9uL0lPRXhjZXB0aW9uSW50ZXJmYWNlLnBocKYCAADijfBhpgIAAKiZaZSkAQAAAAAAADMAAAB2ZW5kb3Ivc3ltZm9ueS9maWxlc3lzdGVtL0V4Y2VwdGlvbi9JT0V4Y2VwdGlvbi5waHCqAwAA4o3wYaoDAADRkYRBpAEAAAAAAAA6AAAAdmVuZG9yL3N5bWZvbnkvZmlsZXN5c3RlbS9FeGNlcHRpb24vRXhjZXB0aW9uSW50ZXJmYWNlLnBocL0BAADijfBhvQEAABdoqqCkAQAAAAAAAD0AAAB2ZW5kb3Ivc3ltZm9ueS9maWxlc3lzdGVtL0V4Y2VwdGlvbi9GaWxlTm90Rm91bmRFeGNlcHRpb24ucGhwtwMAAOKN8GG3AwAA/jB6wqQBAAAAAAAAKAAAAHZlbmRvci9zeW1mb255L2ZpbGVzeXN0ZW0vRmlsZXN5c3RlbS5waHBHdAAA4o3wYUd0AAAuV1iIpAEAAAAAAABEAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXBlbmRlbmN5SW5qZWN0aW9uL0FkZENvbnNvbGVDb21tYW5kUGFzcy5waHCaDwAA4o3wYZoPAABBfFwHpAEAAAAAAAAwAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9JbnB1dERlZmluaXRpb24ucGhw0ysAAOKN8GHTKwAAuwN8BqQBAAAAAAAALAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvU3RyaW5nSW5wdXQucGhwRgkAAOKN8GFGCQAA/aVjOqQBAAAAAAAALgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvSW5wdXRBcmd1bWVudC5waHBPDQAA4o3wYU8NAAAo0MDipAEAAAAAAAAmAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9JbnB1dC5waHByEwAA4o3wYXITAABVgmp4pAEAAAAAAAA5AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9TdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2UucGhwaQMAAOKN8GFpAwAA9ReZ7aQBAAAAAAAALwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvSW5wdXRJbnRlcmZhY2UucGhwsRMAAOKN8GGxEwAA9c6I2qQBAAAAAAAANAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvSW5wdXRBd2FyZUludGVyZmFjZS5waHA6AgAA4o3wYToCAACxICe0pAEAAAAAAAArAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9BcnJheUlucHV0LnBocDAWAADijfBhMBYAAG0aUWqkAQAAAAAAACoAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0lucHV0L0FyZ3ZJbnB1dC5waHAmLwAA4o3wYSYvAACME/yDpAEAAAAAAAAsAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9JbnB1dE9wdGlvbi5waHCiFwAA4o3wYaIXAACcqzZdpAEAAAAAAAAsAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9RdWVzdGlvbi9RdWVzdGlvbi5waHDhFQAA4o3wYeEVAACPzoqBpAEAAAAAAAAyAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9RdWVzdGlvbi9DaG9pY2VRdWVzdGlvbi5waHBdEwAA4o3wYV0TAACPNYgnpAEAAAAAAAA4AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9RdWVzdGlvbi9Db25maXJtYXRpb25RdWVzdGlvbi5waHAjBgAA4o3wYSMGAADPgfsbpAEAAAAAAAAmAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9BcHBsaWNhdGlvbi5waHA2rQAA4o3wYTatAAD3QadjpAEAAAAAAAAvAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9UZXN0ZXIvQ29tbWFuZFRlc3Rlci5waHDtEQAA4o3wYe0RAACbRGSepAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9UZXN0ZXIvQXBwbGljYXRpb25UZXN0ZXIucGhwChYAAOKN8GEKFgAAWpnn6aQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXhjZXB0aW9uL0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbi5waHC+AQAA4o3wYb4BAADudSBppAEAAAAAAAA9AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FeGNlcHRpb24vQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uLnBocL0EAADijfBhvQQAAC6Xb6OkAQAAAAAAADMAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V4Y2VwdGlvbi9Mb2dpY0V4Y2VwdGlvbi5waHCqAQAA4o3wYaoBAABTTUyPpAEAAAAAAAA3AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FeGNlcHRpb24vRXhjZXB0aW9uSW50ZXJmYWNlLnBocJYBAADijfBhlgEAAOPr2lWkAQAAAAAAADsAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V4Y2VwdGlvbi9JbnZhbGlkT3B0aW9uRXhjZXB0aW9uLnBocPwBAADijfBh/AEAAO2TOxOkAQAAAAAAADUAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V4Y2VwdGlvbi9SdW50aW1lRXhjZXB0aW9uLnBocK4BAADijfBhrgEAABe2KmKkAQAAAAAAADgAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Rlc2NyaXB0b3IvTWFya2Rvd25EZXNjcmlwdG9yLnBocL0XAADijfBhvRcAAGYgMD6kAQAAAAAAADMAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Rlc2NyaXB0b3IvWG1sRGVzY3JpcHRvci5waHDxIwAA4o3wYfEjAADH0GRLpAEAAAAAAAA5AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXNjcmlwdG9yL0Rlc2NyaXB0b3JJbnRlcmZhY2UucGhwgwIAAOKN8GGDAgAAUNpa9qQBAAAAAAAANAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRGVzY3JpcHRvci9Kc29uRGVzY3JpcHRvci5waHASFAAA4o3wYRIUAABu9AcVpAEAAAAAAAA8AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXNjcmlwdG9yL0FwcGxpY2F0aW9uRGVzY3JpcHRpb24ucGhwiw8AAOKN8GGLDwAA1dEGrKQBAAAAAAAAMAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRGVzY3JpcHRvci9EZXNjcmlwdG9yLnBocGQMAADijfBhZAwAAKHW5VSkAQAAAAAAADQAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Rlc2NyaXB0b3IvVGV4dERlc2NyaXB0b3IucGhwZjAAAOKN8GFmMAAAo8dXEaQBAAAAAAAANgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXZlbnRMaXN0ZW5lci9FcnJvckxpc3RlbmVyLnBocPQKAADijfBh9AoAAGU/w9+kAQAAAAAAADYAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9EZWJ1Z0Zvcm1hdHRlckhlbHBlci5waHBIEAAA4o3wYUgQAABdUmBBpAEAAAAAAAAoAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvSGVscGVyLnBocLAOAADijfBhsA4AAH1LdbekAQAAAAAAAC0AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9Qcm9ncmVzc0Jhci5waHA/QwAA4o3wYT9DAAA4mbAIpAEAAAAAAAAxAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvSGVscGVySW50ZXJmYWNlLnBocHADAADijfBhcAMAAJHg8W6kAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9UYWJsZVN0eWxlLnBocHsUAADijfBhexQAALJwbhWkAQAAAAAAADAAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9RdWVzdGlvbkhlbHBlci5waHAAQgAA4o3wYQBCAACn3ZdepAEAAAAAAAAnAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvVGFibGUucGhwuE0AAOKN8GG4TQAA6x4hPKQBAAAAAAAAMgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0lucHV0QXdhcmVIZWxwZXIucGhw6wIAAOKN8GHrAgAAFLydF6QBAAAAAAAAMAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL1RhYmxlU2VwYXJhdG9yLnBocBMCAADijfBhEwIAACaKqg2kAQAAAAAAADMAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9Qcm9ncmVzc0luZGljYXRvci5waHCmHgAA4o3wYaYeAACK0JRQpAEAAAAAAAArAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvVGFibGVDZWxsLnBocFIGAADijfBhUgYAAO1Ke7+kAQAAAAAAADEAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9Gb3JtYXR0ZXJIZWxwZXIucGhw4QoAAOKN8GHhCgAADVX69qQBAAAAAAAAKwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0hlbHBlclNldC5waHDBCQAA4o3wYcEJAADDM0MMpAEAAAAAAAAyAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvRGVzY3JpcHRvckhlbHBlci5waHCRCQAA4o3wYZEJAADLEvv+pAEAAAAAAAA3AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvU3ltZm9ueVF1ZXN0aW9uSGVscGVyLnBocIcPAADijfBhhw8AADmL9PCkAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9Qcm9jZXNzSGVscGVyLnBocM8TAADijfBhzxMAABP+dPukAQAAAAAAAD8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0NvbW1hbmRMb2FkZXIvQ29tbWFuZExvYWRlckludGVyZmFjZS5waHCgAwAA4o3wYaADAAC6x/YSpAEAAAAAAAA/AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Db21tYW5kTG9hZGVyL0NvbnRhaW5lckNvbW1hbmRMb2FkZXIucGhwPgYAAOKN8GE+BgAAI7qTKqQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29tbWFuZExvYWRlci9GYWN0b3J5Q29tbWFuZExvYWRlci5waHA3BQAA4o3wYTcFAACCbV/ypAEAAAAAAAAvAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Mb2dnZXIvQ29uc29sZUxvZ2dlci5waHDaEAAA4o3wYdoQAAAH94ZVpAEAAAAAAAAvAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9PdXRwdXQvQ29uc29sZU91dHB1dC5waHCnDwAA4o3wYacPAAC3SkRipAEAAAAAAAAxAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9PdXRwdXQvT3V0cHV0SW50ZXJmYWNlLnBocA8NAADijfBhDw0AAJKz6SakAQAAAAAAADAAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9CdWZmZXJlZE91dHB1dC5waHBJAwAA4o3wYUkDAAAIhVz8pAEAAAAAAAAoAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9PdXRwdXQvT3V0cHV0LnBocHsRAADijfBhexEAAO6e+DekAQAAAAAAADgAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9Db25zb2xlT3V0cHV0SW50ZXJmYWNlLnBocN4CAADijfBh3gIAAL8RoIOkAQAAAAAAAC4AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9TdHJlYW1PdXRwdXQucGhwbw4AAOKN8GFvDgAACxDDfqQBAAAAAAAALAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvT3V0cHV0L051bGxPdXRwdXQucGhwbggAAOKN8GFuCAAAdI9Eu6QBAAAAAAAAIwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvVGVybWluYWwucGhw0hMAAOKN8GHSEwAAG3W+76QBAAAAAAAALgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29tbWFuZC9IZWxwQ29tbWFuZC5waHA/CQAA4o3wYT8JAAD4jeQnpAEAAAAAAAAqAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Db21tYW5kL0NvbW1hbmQucGhwhkwAAOKN8GGGTAAARvrl/aQBAAAAAAAAMAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29tbWFuZC9Mb2NrYWJsZVRyYWl0LnBocOQGAADijfBh5AYAAIruTwKkAQAAAAAAAC4AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0NvbW1hbmQvTGlzdENvbW1hbmQucGhw/wkAAOKN8GH/CQAAHvGbI6QBAAAAAAAALwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvU3R5bGUvU3R5bGVJbnRlcmZhY2UucGhwKAwAAOKN8GEoDAAArzUg8aQBAAAAAAAALQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvU3R5bGUvU3ltZm9ueVN0eWxlLnBocE8vAADijfBhTy8AABtBC3qkAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL1N0eWxlL091dHB1dFN0eWxlLnBocP4LAADijfBh/gsAAJOxon6kAQAAAAAAADkAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Zvcm1hdHRlci9PdXRwdXRGb3JtYXR0ZXJTdHlsZS5waHAyFgAA4o3wYTIWAAAeU7ubpAEAAAAAAABCAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Gb3JtYXR0ZXIvT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UucGhwPAUAAOKN8GE8BQAAn73QWqQBAAAAAAAANAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRm9ybWF0dGVyL091dHB1dEZvcm1hdHRlci5waHChGgAA4o3wYaEaAABOiJF4pAEAAAAAAAA+AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Gb3JtYXR0ZXIvT3V0cHV0Rm9ybWF0dGVyU3R5bGVTdGFjay5waHC1CQAA4o3wYbUJAACXv4vSpAEAAAAAAAA9AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Gb3JtYXR0ZXIvT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlLnBocKYGAADijfBhpgYAACM36nWkAQAAAAAAADYAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V2ZW50L0NvbnNvbGVUZXJtaW5hdGVFdmVudC5waHAaBQAA4o3wYRoFAAB7ZfATpAEAAAAAAAAtAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FdmVudC9Db25zb2xlRXZlbnQucGhwxAUAAOKN8GHEBQAAeFMqD6QBAAAAAAAANgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXZlbnQvQ29uc29sZUV4Y2VwdGlvbkV2ZW50LnBocFQHAADijfBhVAcAAMPe4xCkAQAAAAAAADIAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V2ZW50L0NvbnNvbGVFcnJvckV2ZW50LnBocMUIAADijfBhxQgAAGybEp2kAQAAAAAAADQAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V2ZW50L0NvbnNvbGVDb21tYW5kRXZlbnQucGhwJQUAAOKN8GElBQAAe8u+4KQBAAAAAAAAKAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29uc29sZUV2ZW50cy5waHAhBwAA4o3wYSEHAACfk86ppAEAAAAAAAAlAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL1NwbEZpbGVJbmZvLnBocFcHAADijfBhVwcAACF0VmKkAQAAAAAAADYAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvRXhjZXB0aW9uL0V4Y2VwdGlvbkludGVyZmFjZS5waHAiAgAA4o3wYSICAADagGZXpAEAAAAAAAA5AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0V4Y2VwdGlvbi9BY2Nlc3NEZW5pZWRFeGNlcHRpb24ucGhwqwEAAOKN8GGrAQAAymNX3qQBAAAAAAAAMwAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9Db21wYXJhdG9yL0RhdGVDb21wYXJhdG9yLnBocJ4FAADijfBhngUAAIq8R8OkAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvQ29tcGFyYXRvci9Db21wYXJhdG9yLnBocAMIAADijfBhAwgAAH40kNikAQAAAAAAADUAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvQ29tcGFyYXRvci9OdW1iZXJDb21wYXJhdG9yLnBocBMKAADijfBhEwoAANjZB7qkAQAAAAAAADoAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvRGF0ZVJhbmdlRmlsdGVySXRlcmF0b3IucGhwpQUAAOKN8GGlBQAAESQ5OaQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9JdGVyYXRvci9SZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvci5waHAuEgAA4o3wYS4SAADzj3PTpAEAAAAAAAA5AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL0ZpbGVuYW1lRmlsdGVySXRlcmF0b3IucGhwlQQAAOKN8GGVBAAADMtwwKQBAAAAAAAAOgAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9JdGVyYXRvci9TaXplUmFuZ2VGaWx0ZXJJdGVyYXRvci5waHCCBQAA4o3wYYIFAAAdOEu1pAEAAAAAAAA3AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL0N1c3RvbUZpbHRlckl0ZXJhdG9yLnBocOkFAADijfBh6QUAALXfIA2kAQAAAAAAADMAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvU29ydGFibGVJdGVyYXRvci5waHBACgAA4o3wYUAKAADOWwwApAEAAAAAAAA8AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL0ZpbGVjb250ZW50RmlsdGVySXRlcmF0b3IucGhwpgUAAOKN8GGmBQAADnLcfqQBAAAAAAAAMQAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9JdGVyYXRvci9GaWx0ZXJJdGVyYXRvci5waHDJBgAA4o3wYckGAABWQVNzpAEAAAAAAABBAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL0V4Y2x1ZGVEaXJlY3RvcnlGaWx0ZXJJdGVyYXRvci5waHCWCQAA4o3wYZYJAAB08OikpAEAAAAAAAA9AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL011bHRpcGxlUGNyZUZpbHRlckl0ZXJhdG9yLnBocHoMAADijfBhegwAADap7KakAQAAAAAAADUAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvUGF0aEZpbHRlckl0ZXJhdG9yLnBocKsFAADijfBhqwUAAH2jrBSkAQAAAAAAADsAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvRGVwdGhSYW5nZUZpbHRlckl0ZXJhdG9yLnBocMwEAADijfBhzAQAANsqrB2kAQAAAAAAADkAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvRmlsZVR5cGVGaWx0ZXJJdGVyYXRvci5waHA+BQAA4o3wYT4FAABwwJ9ZpAEAAAAAAAAgAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0ZpbmRlci5waHB7TgAA4o3wYXtOAACZSe7tpAEAAAAAAAAeAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0dsb2IucGhw7Q4AAOKN8GHtDgAAmb6ye6QBAAAAAAAARAAAAHZlbmRvci9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nL1Jlc291cmNlcy9tYl9jb252ZXJ0X3ZhcmlhYmxlcy5waHA4PwMAAOKN8GE/AwAA8hbvoKQBAAAAAAAARgAAAHZlbmRvci9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nL1Jlc291cmNlcy91bmlkYXRhL3RpdGxlQ2FzZVJlZ2V4cC5waHA5GAAA4o3wYTkYAAA+fHpLpAEAAAAAAABAAAAAdmVuZG9yL3N5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcvUmVzb3VyY2VzL3VuaWRhdGEvdXBwZXJDYXNlLnBocPJgAADijfBh8mAAAIpT6f2kAQAAAAAAAEAAAAB2ZW5kb3Ivc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9SZXNvdXJjZXMvdW5pZGF0YS9sb3dlckNhc2UucGhw2V8AAOKN8GHZXwAAWrafiqQBAAAAAAAALgAAAHZlbmRvci9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nL2Jvb3RzdHJhcC5waHCNHAAA4o3wYY0cAABtoHxEpAEAAAAAAAAtAAAAdmVuZG9yL3N5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcvTWJzdHJpbmcucGhwA24AAOKN8GEDbgAAcF7nQ6QBAAAAAAAAJQAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvUGhwUHJvY2Vzcy5waHDACQAA4o3wYcAJAAD4obYDpAEAAAAAAAApAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9Qcm9jZXNzQnVpbGRlci5waHAKGgAA4o3wYQoaAABqJ1VopAEAAAAAAAAuAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9QaHBFeGVjdXRhYmxlRmluZGVyLnBocEcJAADijfBhRwkAAB1fpCOkAQAAAAAAAD0AAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL0V4Y2VwdGlvbi9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24ucGhw8AEAAOKN8GHwAQAAy4WN66QBAAAAAAAAMwAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvRXhjZXB0aW9uL0xvZ2ljRXhjZXB0aW9uLnBocNIBAADijfBh0gEAAB2wqFekAQAAAAAAADsAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL0V4Y2VwdGlvbi9Qcm9jZXNzRmFpbGVkRXhjZXB0aW9uLnBocI0FAADijfBhjQUAAFDBtDWkAQAAAAAAADcAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL0V4Y2VwdGlvbi9FeGNlcHRpb25JbnRlcmZhY2UucGhwrwEAAOKN8GGvAQAAGo08nqQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvRXhjZXB0aW9uL1Byb2Nlc3NUaW1lZE91dEV4Y2VwdGlvbi5waHB7BgAA4o3wYXsGAAA0sRACpAEAAAAAAAA1AAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9FeGNlcHRpb24vUnVudGltZUV4Y2VwdGlvbi5waHDhAQAA4o3wYeEBAAA+SJaZpAEAAAAAAAAvAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9QaXBlcy9QaXBlc0ludGVyZmFjZS5waHD4BQAA4o3wYfgFAADjK5KzpAEAAAAAAAAqAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9QaXBlcy9Vbml4UGlwZXMucGhwLA4AAOKN8GEsDgAABBJxG6QBAAAAAAAALQAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvUGlwZXMvV2luZG93c1BpcGVzLnBocHUWAADijfBhdRYAAHUTB7mkAQAAAAAAAC4AAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1BpcGVzL0Fic3RyYWN0UGlwZXMucGhwrhMAAOKN8GGuEwAAhvMDPKQBAAAAAAAAJgAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvSW5wdXRTdHJlYW0ucGhwFAkAAOKN8GEUCQAAdyeYyKQBAAAAAAAAKwAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvRXhlY3V0YWJsZUZpbmRlci5waHAiCgAA4o3wYSIKAAAlIni0pAEAAAAAAAAnAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9Qcm9jZXNzVXRpbHMucGhwrQ8AAOKN8GGtDwAAYR5YYaQBAAAAAAAAIgAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvUHJvY2Vzcy5waHDT2QAA4o3wYdPZAAD2zJ4npAEAAAAAAAAsAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL1JlamVjdGVkUHJvbWlzZS5waHChCAAA4o3wYaEIAACdTa4wpAEAAAAAAAAlAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL0RlZmVycmVkLnBocLwFAADijfBhvAUAAAofBcykAQAAAAAAACYAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvZnVuY3Rpb25zLnBocIwvAADijfBhjC8AAApoeuykAQAAAAAAADgAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvQ2FuY2VsbGFibGVQcm9taXNlSW50ZXJmYWNlLnBocLYBAADijfBhtgEAALJcbGKkAQAAAAAAAC4AAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvUHJvbWlzb3JJbnRlcmZhY2UucGhwwwAAAOKN8GHDAAAAd7U7AaQBAAAAAAAALQAAAHZlbmRvci9yZWFjdC9wcm9taXNlL3NyYy9Qcm9taXNlSW50ZXJmYWNlLnBocPgGAADijfBh+AYAAF6pDcekAQAAAAAAADYAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvRXhjZXB0aW9uL0xlbmd0aEV4Y2VwdGlvbi5waHBeAAAA4o3wYV4AAAAEP3EEpAEAAAAAAAAkAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL1Byb21pc2UucGhwjCIAAOKN8GGMIgAAyeBtBKQBAAAAAAAANQAAAHZlbmRvci9yZWFjdC9wcm9taXNlL3NyYy9FeHRlbmRlZFByb21pc2VJbnRlcmZhY2UucGhwdg0AAOKN8GF2DQAAjslJHqQBAAAAAAAAKAAAAHZlbmRvci9yZWFjdC9wcm9taXNlL3NyYy9MYXp5UHJvbWlzZS5waHDPBgAA4o3wYc8GAACUTYVKpAEAAAAAAAA4AAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL1VuaGFuZGxlZFJlamVjdGlvbkV4Y2VwdGlvbi5waHBlAgAA4o3wYWUCAABnNB/fpAEAAAAAAAAuAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL2Z1bmN0aW9uc19pbmNsdWRlLnBocGEAAADijfBhYQAAAIV8B+KkAQAAAAAAAC0AAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvRnVsZmlsbGVkUHJvbWlzZS5waHBeBwAA4o3wYV4HAAAeBsF2pAEAAAAAAAAuAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL0NhbmNlbGxhdGlvblF1ZXVlLnBocHUEAADijfBhdQQAAJyNpG6kAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9NZW51X0l0ZW1fQ29tbWFuZC5waHCaOQAA4o3wYZo5AADi0dFopAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvTmV0d29ya19OYW1lc3BhY2UucGhwKgEAAOKN8GEqAQAAe95kH6QBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSS9Db21tYW5kV2l0aERCT2JqZWN0LnBocKMTAADijfBhoxMAAIMalCOkAQAAAAAAAEoAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9XUF9DTEkvRW50aXR5L05vbkV4aXN0ZW50S2V5RXhjZXB0aW9uLnBocMsBAADijfBhywEAAM3MsWikAQAAAAAAAFIAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9XUF9DTEkvRW50aXR5L1JlY3Vyc2l2ZURhdGFTdHJ1Y3R1cmVUcmF2ZXJzZXIucGhwBxAAAOKN8GEHEAAAwxFMbaQBAAAAAAAAOAAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSS9FbnRpdHkvVXRpbHMucGhwgQEAAOKN8GGBAQAAt3njpqQBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSS9Db21tYW5kV2l0aFRlcm1zLnBocGUeAADijfBhZR4AAChRPqekAQAAAAAAADsAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9XUF9DTEkvQ29tbWFuZFdpdGhNZXRhLnBocDs5AADijfBhOzkAAHmA/AykAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Qb3N0X01ldGFfQ29tbWFuZC5waHCTEQAA4o3wYZMRAADX/9T7pAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvVXNlcl9Db21tYW5kLnBocMWJAADijfBhxYkAAJQycLKkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Qb3N0X0NvbW1hbmQucGhwHHEAAOKN8GEccQAA7IBulqQBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL0NvbW1lbnRfTWV0YV9Db21tYW5kLnBocP0RAADijfBh/REAAENxqPCkAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Db21tZW50X0NvbW1hbmQucGhwBEIAAOKN8GEEQgAAwFwdS6QBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1NpdGVfQ29tbWFuZC5waHCOVQAA4o3wYY5VAAAQGM69pAEAAAAAAABGAAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvVXNlcl9BcHBsaWNhdGlvbl9QYXNzd29yZF9Db21tYW5kLnBocFJAAADijfBhUkAAAONZPvakAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Qb3N0X1Rlcm1fQ29tbWFuZC5waHAeAgAA4o3wYR4CAAApN4y/pAEAAAAAAAA5AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvVXNlcl9TZXNzaW9uX0NvbW1hbmQucGhw5BQAAOKN8GHkFAAAzGn9jKQBAAAAAAAAOAAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1NpdGVfT3B0aW9uX0NvbW1hbmQucGhwgCcAAOKN8GGAJwAAV1eZ+aQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1VzZXJfTWV0YV9Db21tYW5kLnBocLskAADijfBhuyQAAFJJfEukAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9NZW51X0NvbW1hbmQucGhwCRIAAOKN8GEJEgAA9cTPzaQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1Rlcm1fTWV0YV9Db21tYW5kLnBocJMRAADijfBhkxEAAJ9C0XOkAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9NZW51X0xvY2F0aW9uX0NvbW1hbmQucGhwuw8AAOKN8GG7DwAAZPsC8aQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1Rlcm1fQ29tbWFuZC5waHDASwAA4o3wYcBLAAAerUccpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvT3B0aW9uX0NvbW1hbmQucGhwLD8AAOKN8GEsPwAAdRoH+qQBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL05ldHdvcmtfTWV0YV9Db21tYW5kLnBocF0BAADijfBhXQEAAOlrAk6kAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9UYXhvbm9teV9Db21tYW5kLnBocBYeAADijfBhFh4AALNvlj+kAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Vc2VyX1Rlcm1fQ29tbWFuZC5waHAmAQAA4o3wYSYBAAAYoXtipAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvU2l0ZV9NZXRhX0NvbW1hbmQucGhwjxEAAOKN8GGPEQAA2naUraQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1Bvc3RfVHlwZV9Db21tYW5kLnBocOcYAADijfBh5xgAAM16m1+kAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL2VudGl0eS1jb21tYW5kLnBocOoKAADijfBh6goAAIGwPa2kAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvUGhwQ29kZUV4dHJhY3Rvci5waHCdBwAA4o3wYZ0HAABnroiUpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL0Jsb2NrRXh0cmFjdG9yLnBocJwHAADijfBhnAcAAGr2e1SkAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvTWFwQ29kZUV4dHJhY3Rvci5waHCBBgAA4o3wYYEGAACoY7pkpAEAAAAAAAA4AAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL0l0ZXJhYmxlQ29kZUV4dHJhY3Rvci5waHAIIgAA4o3wYQgiAADfULhypAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL0pzRnVuY3Rpb25zU2Nhbm5lci5waHA4LgAA4o3wYTguAACAhzhLpAEAAAAAAAAyAAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL0pzQ29kZUV4dHJhY3Rvci5waHAABwAA4o3wYQAHAAAtk0vnpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL0NvbW1hbmROYW1lc3BhY2UucGhwlgEAAOKN8GGWAQAA9WxomqQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9QaHBGdW5jdGlvbnNTY2FubmVyLnBocC0JAADijfBhLQkAAOSgzT6kAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvVGhlbWVKc29uRXh0cmFjdG9yLnBocPEdAADijfBh8R0AANlLn3ekAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvTWFrZVBvdENvbW1hbmQucGhw1n4AAOKN8GHWfgAAluH0JqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9Qb3RHZW5lcmF0b3IucGhwkA8AAOKN8GGQDwAAzf6sw6QBAAAAAAAAMgAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9NYWtlSnNvbkNvbW1hbmQucGhwKS8AAOKN8GEpLwAAeGsbjqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9KZWRHZW5lcmF0b3IucGhwbQgAAOKN8GFtCAAAocqTB6QBAAAAAAAAMAAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9NYWtlTW9Db21tYW5kLnBocEYIAADijfBhRggAALrxviakAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9pMThuLWNvbW1hbmQucGhw8wIAAOKN8GHzAgAA/+YFcKQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvY29uZmlnLWNvbW1hbmQvc3JjL0NvbmZpZ19Db21tYW5kLnBocG6AAADijfBhboAAAM871VykAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL2NvbmZpZy1jb21tYW5kL2NvbmZpZy1jb21tYW5kLnBocA8BAADijfBhDwEAADfMyFGkAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL3dpZGdldC1jb21tYW5kL3NyYy9TaWRlYmFyX0NvbW1hbmQucGhw0gYAAOKN8GHSBgAAgWSzg6QBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvd2lkZ2V0LWNvbW1hbmQvc3JjL1dpZGdldF9Db21tYW5kLnBocGpHAADijfBhakcAAPe6xeCkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL3dpZGdldC1jb21tYW5kL3dpZGdldC1jb21tYW5kLnBocEQBAADijfBhRAEAAN3uDK+kAQAAAAAAAEUAAAB2ZW5kb3Ivd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZC9zcmMvTWFpbnRlbmFuY2VNb2RlQ29tbWFuZC5waHA3DQAA4o3wYTcNAAAwMj1ApAEAAAAAAABDAAAAdmVuZG9yL3dwLWNsaS9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQvbWFpbnRlbmFuY2UtbW9kZS1jb21tYW5kLnBocEwBAADijfBhTAEAADnMdjSkAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3NoZWxsLWNvbW1hbmQvc3JjL1dQX0NMSS9TaGVsbC9SRVBMLnBocNoMAADijfBh2gwAABNEBGKkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3NoZWxsLWNvbW1hbmQvc3JjL1NoZWxsX0NvbW1hbmQucGhwVQUAAOKN8GFVBQAAw24eKqQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvc2hlbGwtY29tbWFuZC9zaGVsbC1jb21tYW5kLnBocAoBAADijfBhCgEAAAHV2bekAQAAAAAAACMAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS91dGlscy9maW5kLXBocFwBAADijfBhXAEAAJZchimkAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS91dGlscy9jb250cmliLWxpc3QucGhwwxsAAOKN8GHDGwAAHVRFOqQBAAAAAAAAQAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3V0aWxzL2dldC1wYWNrYWdlLXJlcXVpcmUtZnJvbS1jb21wb3Nlci5waHDkAQAA4o3wYeQBAAAQ5p8MpAEAAAAAAABCAAAAdmVuZG9yL3dwLWNsaS9zZWFyY2gtcmVwbGFjZS1jb21tYW5kL3NyYy9XUF9DTEkvU2VhcmNoUmVwbGFjZXIucGhwUhcAAOKN8GFSFwAAEyRlrKQBAAAAAAAAQwAAAHZlbmRvci93cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC9zcmMvU2VhcmNoX1JlcGxhY2VfQ29tbWFuZC5waHBfkwAA4o3wYV+TAADmFIMkpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9zZWFyY2gtcmVwbGFjZS1jb21tYW5kL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQucGhwNwEAAOKN8GE3AQAArtTmAaQBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvcGFja2FnZS1jb21tYW5kL3NyYy9XUF9DTEkvSnNvbk1hbmlwdWxhdG9yLnBocAhTAADijfBhCFMAAM+ih+ikAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3BhY2thZ2UtY29tbWFuZC9zcmMvUGFja2FnZV9Db21tYW5kLnBocEjQAADijfBhSNAAAOKNO0+kAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3BhY2thZ2UtY29tbWFuZC9wYWNrYWdlLWNvbW1hbmQucGhwOgEAAOKN8GE6AQAAYIb1N6QBAAAAAAAALAAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9odHRwLWNvbnNvbGUucGhwHwcAAOKN8GEfBwAA55HIPqQBAAAAAAAAJAAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy90ZXN0LnBocGkCAADijfBhaQIAADNNmRWkAQAAAAAAADAAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9Qcm9ncmVzcy5waHDJDQAA4o3wYckNAAC0DmGqpAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvU2hlbGwucGhwRg0AAOKN8GFGDQAANr99XqQBAAAAAAAANAAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3Byb2dyZXNzL0Jhci5waHC2CQAA4o3wYbYJAABuoChPpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvbm90aWZ5L1NwaW5uZXIucGhwBwUAAOKN8GEHBQAAOPt1B6QBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL25vdGlmeS9Eb3RzLnBocGQHAADijfBhZAcAANt34XqkAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9Db2xvcnMucGhwayEAAOKN8GFrIQAAHXk2KaQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL0FyZ3VtZW50cy5waHAGLwAA4o3wYQYvAADgLDd7pAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvVGFibGUucGhwoRkAAOKN8GGhGQAAdOGIKqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL1N0cmVhbXMucGhwCCMAAOKN8GEIIwAAADZvLaQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL2FyZ3VtZW50cy9JbnZhbGlkQXJndW1lbnRzLnBocBoEAADijfBhGgQAALX62COkAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9hcmd1bWVudHMvQXJndW1lbnQucGhwIAsAAOKN8GEgCwAAPcbp6aQBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL2FyZ3VtZW50cy9MZXhlci5waHBeCQAA4o3wYV4JAAD8R9gHpAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvYXJndW1lbnRzL0hlbHBTY3JlZW4ucGhwoAoAAOKN8GGgCgAA/U8kdqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL01lbW9pemUucGhw+wMAAOKN8GH7AwAA3gH0DqQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RyZWUvUmVuZGVyZXIucGhwTwIAAOKN8GFPAgAAm2Mi06QBAAAAAAAAMgAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RyZWUvQXNjaWkucGhweAMAAOKN8GF4AwAAOY/V9qQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RyZWUvTWFya2Rvd24ucGhwqAUAAOKN8GGoBQAAjFTpraQBAAAAAAAAKwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL2NsaS5waHDHQAAA4o3wYcdAAAD9fnrXpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvdGFibGUvUmVuZGVyZXIucGhwRwUAAOKN8GFHBQAAWYbfkqQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RhYmxlL1RhYnVsYXIucGhwsgIAAOKN8GGyAgAA+YihbKQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RhYmxlL0FzY2lpLnBocAsbAADijfBhCxsAAJ1AJT2kAQAAAAAAACwAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9UcmVlLnBocLMFAADijfBhswUAAB7u/UCkAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9Ob3RpZnkucGhwzREAAOKN8GHNEQAALKemFKQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3VuaWNvZGUvcmVnZXgucGhwYhYAAOKN8GFiFgAAybY5zaQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvZW1iZWQtY29tbWFuZC9zcmMvRmV0Y2hfQ29tbWFuZC5waHDJJAAA4o3wYckkAACbiRv+pAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9lbWJlZC1jb21tYW5kL3NyYy9DYWNoZV9Db21tYW5kLnBocJoTAADijfBhmhMAAG3zUPikAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL2VtYmVkLWNvbW1hbmQvc3JjL0VtYmVkc19OYW1lc3BhY2UucGhw2AAAAOKN8GHYAAAA8PxxpaQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvZW1iZWQtY29tbWFuZC9zcmMvSGFuZGxlcl9Db21tYW5kLnBocBcIAADijfBhFwgAAGDGV+ekAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL2VtYmVkLWNvbW1hbmQvc3JjL1Byb3ZpZGVyX0NvbW1hbmQucGhwuRUAAOKN8GG5FQAAfXQ0lKQBAAAAAAAAKgAAAHZlbmRvci93cC1jbGkvZW1iZWQtY29tbWFuZC9zcmMvb0VtYmVkLnBocPcFAADijfBh9wUAAOhw/z6kAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL2VtYmVkLWNvbW1hbmQvZW1iZWQtY29tbWFuZC5waHB4AgAA4o3wYXgCAAAjvRjOpAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS9jb3JlLWNvbW1hbmQvY29yZS1jb21tYW5kLnBocAUBAADijfBhBQEAAKk6iK+kAQAAAAAAAEkAAAB2ZW5kb3Ivd3AtY2xpL2NvcmUtY29tbWFuZC9zcmMvV1BfQ0xJL0NvcmUvTm9uRGVzdHJ1Y3RpdmVDb3JlVXBncmFkZXIucGhwnwEAAOKN8GGfAQAAkCF6fqQBAAAAAAAAOwAAAHZlbmRvci93cC1jbGkvY29yZS1jb21tYW5kL3NyYy9XUF9DTEkvQ29yZS9Db3JlVXBncmFkZXIucGhwvhYAAOKN8GG+FgAAWsFOKqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvY29yZS1jb21tYW5kL3NyYy9Db3JlX0NvbW1hbmQucGhwproAAOKN8GGmugAA+NeuoKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvY2FjaGUtY29tbWFuZC9zcmMvQ2FjaGVfQ29tbWFuZC5waHAxHwAA4o3wYTEfAADJNb7FpAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS9jYWNoZS1jb21tYW5kL3NyYy9UcmFuc2llbnRfQ29tbWFuZC5waHD2RAAA4o3wYfZEAAAFSm+GpAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS9jYWNoZS1jb21tYW5kL2NhY2hlLWNvbW1hbmQucGhwQwEAAOKN8GFDAQAAJidlFaQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvbWVkaWEtY29tbWFuZC9zcmMvTWVkaWFfQ29tbWFuZC5waHAmnwAA4o3wYSafAAD9+YJ2pAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS9tZWRpYS1jb21tYW5kL21lZGlhLWNvbW1hbmQucGhwkgIAAOKN8GGSAgAANohYk6QBAAAAAAAARwAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvV1BfQ0xJL0ZldGNoZXJzL1VuZmlsdGVyZWRQbHVnaW4ucGhwOgMAAOKN8GE6AwAAPKcCZ6QBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvQ2hlY2tzdW1fQmFzZV9Db21tYW5kLnBocAUJAADijfBhBQkAAE4ZirqkAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQvc3JjL0NoZWNrc3VtX0NvcmVfQ29tbWFuZC5waHDQFwAA4o3wYdAXAADJIU0TpAEAAAAAAAA+AAAAdmVuZG9yL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL3NyYy9DaGVja3N1bV9QbHVnaW5fQ29tbWFuZC5waHAxIQAA4o3wYTEhAAAzZzIxpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL3NyYy9QbHVnaW5fQ29tbWFuZF9OYW1lc3BhY2UucGhwvQAAAOKN8GG9AAAApjoFZqQBAAAAAAAAPQAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvQ29yZV9Db21tYW5kX05hbWVzcGFjZS5waHDAAAAA4o3wYcAAAAB70urxpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL2NoZWNrc3VtLWNvbW1hbmQucGhw8AEAAOKN8GHwAQAAW3rfc6QBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljL3NyYy9TcHljLnBocMuFAADijfBhy4UAAOgAfuOkAQAAAAAAACkAAAB2ZW5kb3Ivd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9TcHljLnBocMsDAADijfBhywMAAJaq0XikAQAAAAAAADcAAAB2ZW5kb3Ivd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9pbmNsdWRlcy9mdW5jdGlvbnMucGhwGwQAAOKN8GEbBAAAuAKxOqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljL3BocDQvc3B5Yy5waHA0SXUAAOKN8GFJdQAA/S0uBaQBAAAAAAAALgAAAHZlbmRvci93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljL3BocDQvNXRvNC5waHDYAgAA4o3wYdgCAAB1U10ppAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMvcGhwNC90ZXN0LnBocDSHEQAA4o3wYYcRAAAgZjNQpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS93cC1jb25maWctdHJhbnNmb3JtZXIvc3JjL1dQQ29uZmlnVHJhbnNmb3JtZXIucGhw8ykAAOKN8GHzKQAAYwMIiaQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvY3Jvbi1jb21tYW5kL3NyYy9Dcm9uX0V2ZW50X0NvbW1hbmQucGhw3zkAAOKN8GHfOQAAq8W7iaQBAAAAAAAAOAAAAHZlbmRvci93cC1jbGkvY3Jvbi1jb21tYW5kL3NyYy9Dcm9uX1NjaGVkdWxlX0NvbW1hbmQucGhwaQwAAOKN8GFpDAAAn79Af6QBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvY3Jvbi1jb21tYW5kL3NyYy9Dcm9uX0NvbW1hbmQucGhw+AsAAOKN8GH4CwAArKBTmqQBAAAAAAAAKwAAAHZlbmRvci93cC1jbGkvY3Jvbi1jb21tYW5kL2Nyb24tY29tbWFuZC5waHCBAQAA4o3wYYEBAAABsrIupAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS9yZXdyaXRlLWNvbW1hbmQvc3JjL1Jld3JpdGVfQ29tbWFuZC5waHAfMAAA4o3wYR8wAADmOxa/pAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9yZXdyaXRlLWNvbW1hbmQvcmV3cml0ZS1jb21tYW5kLnBocBQBAADijfBhFAEAAB0XS6ukAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL2V2YWwtY29tbWFuZC9ldmFsLWNvbW1hbmQucGhwPQEAAOKN8GE9AQAAtodBa6QBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvZXZhbC1jb21tYW5kL3NyYy9FdmFsRmlsZV9Db21tYW5kLnBocCsHAADijfBhKwcAADeniT6kAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL2V2YWwtY29tbWFuZC9zcmMvRXZhbF9Db21tYW5kLnBocF0DAADijfBhXQMAACemrJOkAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvc2NhZmZvbGQtY29tbWFuZC5waHAZAQAA4o3wYRkBAADmtIMPpAEAAAAAAAA3AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3NyYy9TY2FmZm9sZF9Db21tYW5kLnBocKCWAADijfBhoJYAAEUEkEGkAQAAAAAAADsAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL2Jsb2NrLXBocC5tdXN0YWNoZS4HAADijfBhLgcAAEYcXoKkAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL3N1cGVyLWFkbWluLWNvbW1hbmQvc3VwZXItYWRtaW4tY29tbWFuZC5waHC+AQAA4o3wYb4BAACcGP+IpAEAAAAAAAA9AAAAdmVuZG9yL3dwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kL3NyYy9TdXBlcl9BZG1pbl9Db21tYW5kLnBocLMbAADijfBhsxsAAOiwAkWkAQAAAAAAAEMAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9XUF9DTEkvUGFyc2VQbHVnaW5OYW1lSW5wdXQucGhwiAUAAOKN8GGIBQAARzCULaQBAAAAAAAASAAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1dQX0NMSS9EZXN0cnVjdGl2ZVBsdWdpblVwZ3JhZGVyLnBocKsBAADijfBhqwEAAB9JjcmkAQAAAAAAAEcAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9XUF9DTEkvRGVzdHJ1Y3RpdmVUaGVtZVVwZ3JhZGVyLnBocKgBAADijfBhqAEAAFOM/Q+kAQAAAAAAAD4AAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9XUF9DTEkvRmV0Y2hlcnMvUGx1Z2luLnBocCIDAADijfBhIgMAAAtG5CCkAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9XUF9DTEkvRmV0Y2hlcnMvVGhlbWUucGhwDAcAAOKN8GEMBwAA2PozrKQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1dQX0NMSS9QYXJzZVRoZW1lTmFtZUlucHV0LnBocGgTAADijfBhaBMAAPRHgBakAQAAAAAAAEEAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9XUF9DTEkvQ29tbWFuZFdpdGhVcGdyYWRlLnBocOxcAADijfBh7FwAAMG0vsWkAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9UaGVtZV9Nb2RfQ29tbWFuZC5waHDOFgAA4o3wYc4WAADxe68opAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMvUGx1Z2luX0NvbW1hbmQucGhwNpMAAOKN8GE2kwAAwcaSvKQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1BsdWdpbl9BdXRvVXBkYXRlc19Db21tYW5kLnBocGAbAADijfBhYBsAAJ7yKICkAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9UaGVtZV9Db21tYW5kLnBocChgAADijfBhKGAAAKbFnjOkAQAAAAAAAEEAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9UaGVtZV9BdXRvVXBkYXRlc19Db21tYW5kLnBocOIbAADijfBh4hsAAITY6hWkAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL2V4dGVuc2lvbi1jb21tYW5kLnBocCkDAADijfBhKQMAALADGBOkAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYy9XUF9NYXBfSXRlcmF0b3IucGhwQAEAAOKN8GFAAQAA0bERkKQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL0V4cG9ydF9Db21tYW5kLnBocFozAADijfBhWjMAAEm0Y36kAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYy9XUF9FeHBvcnRfUXVlcnkucGhwMjUAAOKN8GEyNQAAm4sZ/KQBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9SZXR1cm5lci5waHBCBAAA4o3wYUIEAACz19dNpAEAAAAAAAA9AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X1Rlcm1fRXhjZXB0aW9uLnBocEMAAADijfBhQwAAAOofAsekAQAAAAAAAEEAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYy9XUF9FeHBvcnRfU3BsaXRfRmlsZXNfV3JpdGVyLnBocC0LAADijfBhLQsAAA4lQGmkAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYy9XUF9FeHBvcnRfRmlsZV9Xcml0ZXIucGhwPgMAAOKN8GE+AwAAUn1Um6QBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9PeHltZWwucGhw9gEAAOKN8GH2AQAA7Gw77KQBAAAAAAAAOgAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9CYXNlX1dyaXRlci5waHCsAQAA4o3wYawBAADHtGL3pAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X1dYUl9Gb3JtYXR0ZXIucGhw2iYAAOKN8GHaJgAAW+d7NKQBAAAAAAAAOgAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0l0ZXJhdG9yX0V4Y2VwdGlvbi5waHA5AAAA4o3wYTkAAACmfwd3pAEAAAAAAAA5AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfUG9zdF9JRHNfSXRlcmF0b3IucGhwSQYAAOKN8GFJBgAAp9pDFqQBAAAAAAAAOAAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9FeGNlcHRpb24ucGhwPgAAAOKN8GE+AAAATRzLAKQBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9YTUxfT3Zlcl9IVFRQLnBocGEFAADijfBhYQUAAF2Anr+kAQAAAAAAACoAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL2Z1bmN0aW9ucy5waHBwBQAA4o3wYXAFAAAU6JEbpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9leHBvcnQtY29tbWFuZC5waHAPAQAA4o3wYQ8BAADf/zJkpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9zZXJ2ZXItY29tbWFuZC9zcmMvU2VydmVyX0NvbW1hbmQucGhwLAwAAOKN8GEsDAAAmp02XKQBAAAAAAAAJwAAAHZlbmRvci93cC1jbGkvc2VydmVyLWNvbW1hbmQvcm91dGVyLnBocE4OAADijfBhTg4AADemHf2kAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL3NlcnZlci1jb21tYW5kL3NlcnZlci1jb21tYW5kLnBocPYBAADijfBh9gEAAKorwR2kAQAAAAAAAEQAAAB2ZW5kb3Ivd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjL1dQX0NMSS9Db21tYW5kV2l0aFRyYW5zbGF0aW9uLnBocN0gAADijfBh3SAAACySFtmkAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjL1dQX0NMSS9MYW5ndWFnZVBhY2tVcGdyYWRlci5waHDxDQAA4o3wYfENAACLbrAWpAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL3NyYy9Db3JlX0xhbmd1YWdlX0NvbW1hbmQucGhwmyYAAOKN8GGbJgAAKcsJyqQBAAAAAAAAPgAAAHZlbmRvci93cC1jbGkvbGFuZ3VhZ2UtY29tbWFuZC9zcmMvUGx1Z2luX0xhbmd1YWdlX0NvbW1hbmQucGhwETMAAOKN8GERMwAAhUJNuqQBAAAAAAAAQwAAAHZlbmRvci93cC1jbGkvbGFuZ3VhZ2UtY29tbWFuZC9zcmMvU2l0ZV9Td2l0Y2hfTGFuZ3VhZ2VfQ29tbWFuZC5waHCCAwAA4o3wYYIDAACHFTF/pAEAAAAAAAA9AAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL3NyYy9UaGVtZV9MYW5ndWFnZV9Db21tYW5kLnBocF0xAADijfBhXTEAAO3b9mukAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjL0xhbmd1YWdlX05hbWVzcGFjZS5waHDhAgAA4o3wYeECAAC/KXyDpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL2xhbmd1YWdlLWNvbW1hbmQucGhwMQQAAOKN8GExBAAAnjfIZ6QBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvcm9sZS1jb21tYW5kL3NyYy9DYXBhYmlsaXRpZXNfQ29tbWFuZC5waHAzFQAA4o3wYTMVAAAP5RH3pAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9yb2xlLWNvbW1hbmQvc3JjL1JvbGVfQ29tbWFuZC5waHByKQAA4o3wYXIpAACAtS/UpAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS9yb2xlLWNvbW1hbmQvcm9sZS1jb21tYW5kLnBocDsBAADijfBhOwEAAGHwdgekAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2ltcG9ydC1jb21tYW5kL3NyYy9JbXBvcnRfQ29tbWFuZC5waHAQOQAA4o3wYRA5AACFEYwDpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9pbXBvcnQtY29tbWFuZC9pbXBvcnQtY29tbWFuZC5waHAPAQAA4o3wYQ8BAACHE+TKpAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS9kYi1jb21tYW5kL3NyYy9EQl9Db21tYW5kLnBocGUAAQDijfBhZQABAIH6z4ikAQAAAAAAACcAAAB2ZW5kb3Ivd3AtY2xpL2RiLWNvbW1hbmQvZGItY29tbWFuZC5waHD7AAAA4o3wYfsAAADM/e1rpAEAAAAAAAAbAAAAdmVuZG9yL25iL294eW1lbC9PeHltZWwucGhwKRcAAOKN8GEpFwAA6Chy1aQBAAAAAAAAHwAAAHZlbmRvci9uYi9veHltZWwvT3h5bWVsVGVzdC5waHCCEwAA4o3wYYITAABCTKlWpAEAAAAAAAAzAAAAdmVuZG9yL3Bzci9sb2cvUHNyL0xvZy9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24ucGhwYAAAAOKN8GFgAAAAIIhYMaQBAAAAAAAALwAAAHZlbmRvci9wc3IvbG9nL1Bzci9Mb2cvTG9nZ2VyQXdhcmVJbnRlcmZhY2UucGhwKQEAAOKN8GEpAQAAyGoMsaQBAAAAAAAAKwAAAHZlbmRvci9wc3IvbG9nL1Bzci9Mb2cvTG9nZ2VyQXdhcmVUcmFpdC5waHCSAQAA4o3wYZIBAAAZUSevpAEAAAAAAAApAAAAdmVuZG9yL3Bzci9sb2cvUHNyL0xvZy9BYnN0cmFjdExvZ2dlci5waHAgDAAA4o3wYSAMAABHnOvipAEAAAAAAAAqAAAAdmVuZG9yL3Bzci9sb2cvUHNyL0xvZy9Mb2dnZXJJbnRlcmZhY2UucGhwKgwAAOKN8GEqDAAAMWIhcaQBAAAAAAAAJQAAAHZlbmRvci9wc3IvbG9nL1Bzci9Mb2cvTnVsbExvZ2dlci5waHDDAgAA4o3wYcMCAADR4tVJpAEAAAAAAAAjAAAAdmVuZG9yL3Bzci9sb2cvUHNyL0xvZy9Mb2dMZXZlbC5waHBQAQAA4o3wYVABAACd8roUpAEAAAAAAAAmAAAAdmVuZG9yL3Bzci9sb2cvUHNyL0xvZy9Mb2dnZXJUcmFpdC5waHBXDQAA4o3wYVcNAAC5V+VqpAEAAAAAAAA1AAAAdmVuZG9yL3NlbGQvanNvbmxpbnQvc3JjL1NlbGQvSnNvbkxpbnQvSnNvblBhcnNlci5waHAoUQAA4o3wYShRAAAZCMt7pAEAAAAAAAAwAAAAdmVuZG9yL3NlbGQvanNvbmxpbnQvc3JjL1NlbGQvSnNvbkxpbnQvTGV4ZXIucGhwBxkAAOKN8GEHGQAAYH8Vn6QBAAAAAAAANAAAAHZlbmRvci9zZWxkL2pzb25saW50L3NyYy9TZWxkL0pzb25MaW50L1VuZGVmaW5lZC5waHAcAQAA4o3wYRwBAACCZ/AXpAEAAAAAAABAAAAAdmVuZG9yL3NlbGQvanNvbmxpbnQvc3JjL1NlbGQvSnNvbkxpbnQvRHVwbGljYXRlS2V5RXhjZXB0aW9uLnBocFIEAADijfBhUgQAAOujeSOkAQAAAAAAADsAAAB2ZW5kb3Ivc2VsZC9qc29ubGludC9zcmMvU2VsZC9Kc29uTGludC9QYXJzaW5nRXhjZXB0aW9uLnBocNYDAADijfBh1gMAANQ7pxakAQAAAAAAACkAAAB2ZW5kb3Ivc2VsZC9waGFyLXV0aWxzL3NyYy9UaW1lc3RhbXBzLnBocCcWAADijfBhJxYAAN8ldpykAQAAAAAAACUAAAB2ZW5kb3Ivc2VsZC9waGFyLXV0aWxzL3NyYy9MaW50ZXIucGhw6w0AAOKN8GHrDQAAJzQjjaQBAAAAAAAARgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0VudGl0eS9Kc29uUG9pbnRlci5waHA+DQAA4o3wYT4NAACQHVcEpAEAAAAAAABJAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpUmV0cmlldmVySW50ZXJmYWNlLnBocAUCAADijfBhBQIAADXUfFukAQAAAAAAADsAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9SZmMzMzM5LnBocHYDAADijfBhdgMAAHjBJJCkAQAAAAAAAEEAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9TY2hlbWFTdG9yYWdlLnBocCsVAADijfBhKxUAAKGeGF+kAQAAAAAAAFYAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9FeGNlcHRpb24vSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uLnBocHkBAADijfBheQEAAIBXzpakAQAAAAAAAF0AAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9FeGNlcHRpb24vSW52YWxpZFNjaGVtYU1lZGlhVHlwZUV4Y2VwdGlvbi5waHBXAQAA4o3wYVcBAAAlKinWpAEAAAAAAABUAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL0ludmFsaWRDb25maWdFeGNlcHRpb24ucGhwUQEAAOKN8GFRAQAAANZK76QBAAAAAAAAUgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9VcmlSZXNvbHZlckV4Y2VwdGlvbi5waHBKAQAA4o3wYUoBAADv8AYtpAEAAAAAAABQAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL0V4Y2VwdGlvbkludGVyZmFjZS5waHBJAAAA4o3wYUkAAAAlfBmwpAEAAAAAAABeAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL1VucmVzb2x2YWJsZUpzb25Qb2ludGVyRXhjZXB0aW9uLnBocIoBAADijfBhigEAAC66bWmkAQAAAAAAAFQAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9FeGNlcHRpb24vSW52YWxpZFNjaGVtYUV4Y2VwdGlvbi5waHBOAQAA4o3wYU4BAACPr92gpAEAAAAAAABTAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL0pzb25EZWNvZGluZ0V4Y2VwdGlvbi5waHDbBAAA4o3wYdsEAADZoxa9pAEAAAAAAABRAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL1ZhbGlkYXRpb25FeGNlcHRpb24ucGhwGQEAAOKN8GEZAQAAReVCKqQBAAAAAAAATgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9SdW50aW1lRXhjZXB0aW9uLnBocGEBAADijfBhYQEAAGDaGZekAQAAAAAAAFcAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9FeGNlcHRpb24vUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbi5waHBUAQAA4o3wYVQBAADw2B06pAEAAAAAAABXAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL0ludmFsaWRTb3VyY2VVcmlFeGNlcHRpb24ucGhwXAEAAOKN8GFcAQAAqhlpUqQBAAAAAAAASAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1VyaVJlc29sdmVySW50ZXJmYWNlLnBocBICAADijfBhEgIAAEnL0NGkAQAAAAAAAEoAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9Db25zdHJhaW50LnBocI4ZAADijfBhjhkAALDXk/GkAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9TY2hlbWFDb25zdHJhaW50LnBocM8OAADijfBhzw4AAMJmSwukAQAAAAAAAFQAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9Db2xsZWN0aW9uQ29uc3RyYWludC5waHDGEwAA4o3wYcYTAABOiOjmpAEAAAAAAABcAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvVHlwZUNoZWNrL1R5cGVDaGVja0ludGVyZmFjZS5waHChAQAA4o3wYaEBAABjPrDPpAEAAAAAAABZAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvVHlwZUNoZWNrL1N0cmljdFR5cGVDaGVjay5waHArAwAA4o3wYSsDAAD7slHcpAEAAAAAAABYAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvVHlwZUNoZWNrL0xvb3NlVHlwZUNoZWNrLnBocBYGAADijfBhFgYAALkK/MCkAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9Gb3JtYXRDb25zdHJhaW50LnBocJUiAADijfBhlSIAAM2lI0ukAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9OdW1iZXJDb25zdHJhaW50LnBocIcNAADijfBhhw0AALHpOXykAQAAAAAAAFMAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9Db25zdHJhaW50SW50ZXJmYWNlLnBocB0GAADijfBhHQYAAHSxZeSkAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9TdHJpbmdDb25zdHJhaW50LnBocMYHAADijfBhxgcAAH66yEekAQAAAAAAAEcAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9GYWN0b3J5LnBocEYWAADijfBhRhYAADowwC+kAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9PYmplY3RDb25zdHJhaW50LnBocI8fAADijfBhjx8AAEZnY4SkAQAAAAAAAFMAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9VbmRlZmluZWRDb25zdHJhaW50LnBocLE+AADijfBhsT4AABR9yMGkAQAAAAAAAE4AAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9UeXBlQ29uc3RyYWludC5waHAmHwAA4o3wYSYfAADZjBFdpAEAAAAAAABOAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvRW51bUNvbnN0cmFpbnQucGhwcQYAAOKN8GFxBgAAxWDIIKQBAAAAAAAATgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL0Jhc2VDb25zdHJhaW50LnBocCUPAADijfBhJQ8AAJLdMqOkAQAAAAAAAEsAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9JdGVyYXRvci9PYmplY3RJdGVyYXRvci5waHDnCgAA4o3wYecKAABIuKl/pAEAAAAAAABDAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpL1VyaVJlc29sdmVyLnBocDsSAADijfBhOxIAABbzx+SkAQAAAAAAAEQAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9VcmkvVXJpUmV0cmlldmVyLnBocLokAADijfBhuiQAAFjLaLGkAQAAAAAAAFgAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9VcmkvUmV0cmlldmVycy9VcmlSZXRyaWV2ZXJJbnRlcmZhY2UucGhw6gIAAOKN8GHqAgAAP8lyQKQBAAAAAAAAUgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1VyaS9SZXRyaWV2ZXJzL1ByZWRlZmluZWRBcnJheS5waHAUBQAA4o3wYRQFAAAfMBXhpAEAAAAAAABSAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpL1JldHJpZXZlcnMvRmlsZUdldENvbnRlbnRzLnBocGoKAADijfBhagoAAFt9eCOkAQAAAAAAAEcAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9VcmkvUmV0cmlldmVycy9DdXJsLnBocG8IAADijfBhbwgAAIZuEwWkAQAAAAAAAFQAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9VcmkvUmV0cmlldmVycy9BYnN0cmFjdFJldHJpZXZlci5waHByAgAA4o3wYXICAACWivpNpAEAAAAAAAA9AAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVmFsaWRhdG9yLnBocO4KAADijfBh7goAADiUm+ukAQAAAAAAAEoAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9TY2hlbWFTdG9yYWdlSW50ZXJmYWNlLnBocCIDAADijfBhIgMAAHgBJjekAQAAAAAAADIAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9UcmFuc2xhdG9ySW50ZXJmYWNlLnBocCUKAADijfBhJQoAAM34naSkAQAAAAAAACoAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9UcmFuc2xhdGlvbi5waHCUKwAA4o3wYZQrAADP2znipAEAAAAAAAAzAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvUGFyc2VkRnVuY3Rpb24ucGhwfw4AAOKN8GF/DgAAj4xihaQBAAAAAAAANQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0Z1bmN0aW9uc1NjYW5uZXIucGhwSRUAAOKN8GFJFQAAYWhrJKQBAAAAAAAANwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0pzRnVuY3Rpb25zU2Nhbm5lci5waHDqJAAA4o3wYeokAAAoje1kpAEAAAAAAAAyAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvUGFyc2VkQ29tbWVudC5waHBcDAAA4o3wYVwMAACL3LpDpAEAAAAAAAA0AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvRGljdGlvbmFyeVRyYWl0LnBocO4FAADijfBh7gUAANh/J4+kAQAAAAAAADgAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9VdGlscy9QaHBGdW5jdGlvbnNTY2FubmVyLnBocOIWAADijfBh4hYAAJwobNCkAQAAAAAAADEAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9VdGlscy9TdHJpbmdSZWFkZXIucGhwswMAAOKN8GGzAwAAUI31jaQBAAAAAAAAOgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0hlYWRlcnNFeHRyYWN0b3JUcmFpdC5waHB+BgAA4o3wYX4GAAD9vcPQpAEAAAAAAAA/AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQucGhwvAwAAOKN8GG8DAAAxGkkYaQBAAAAAAAALQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0NzdlRyYWl0LnBocI8FAADijfBhjwUAAFPiGyqkAQAAAAAAADoAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9VdGlscy9IZWFkZXJzR2VuZXJhdG9yVHJhaXQucGhwNwIAAOKN8GE3AgAANsOJR6QBAAAAAAAAMgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dlbmVyYXRvcnMvUGhwQXJyYXkucGhwqwMAAOKN8GGrAwAArkjWO6QBAAAAAAAANwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dlbmVyYXRvcnMvQ3N2RGljdGlvbmFyeS5waHCmAwAA4o3wYaYDAABDVCATpAEAAAAAAAA4AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9Kc29uRGljdGlvbmFyeS5waHA9AgAA4o3wYT0CAAAF0ul7pAEAAAAAAAAtAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9KZWQucGhwcAcAAOKN8GFwBwAAoyxrLqQBAAAAAAAALwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dlbmVyYXRvcnMvWGxpZmYucGhwNhEAAOKN8GE2EQAAw75RpqQBAAAAAAAAPAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dlbmVyYXRvcnMvR2VuZXJhdG9ySW50ZXJmYWNlLnBocKcCAADijfBhpwIAABejC2ekAQAAAAAAACwAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9HZW5lcmF0b3JzL01vLnBocOsSAADijfBh6xIAADAUqdCkAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9HZW5lcmF0b3JzL0Nzdi5waHCHBQAA4o3wYYcFAACR6ot7pAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9Kc29uLnBocE8CAADijfBhTwIAAGaYJ06kAQAAAAAAADMAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9HZW5lcmF0b3JzL0dlbmVyYXRvci5waHC8AQAA4o3wYbwBAAAVszMDpAEAAAAAAAA4AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9ZYW1sRGljdGlvbmFyeS5waHDOAgAA4o3wYc4CAABMNaKspAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9ZYW1sLnBocNoCAADijfBh2gIAANX9tq+kAQAAAAAAACwAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9HZW5lcmF0b3JzL1BvLnBocAoQAADijfBhChAAAJq5KFOkAQAAAAAAACsAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9UcmFuc2xhdGlvbnMucGhw5UAAAOKN8GHlQAAA/juaAaQBAAAAAAAAKQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1RyYW5zbGF0b3IucGhwpB4AAOKN8GGkHgAAA0r0PqQBAAAAAAAAMAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dldHRleHRUcmFuc2xhdG9yLnBocL4OAADijfBhvg4AAN68o3ykAQAAAAAAACQAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9NZXJnZS5waHBEGAAA4o3wYUQYAACHbTZQpAEAAAAAAAAzAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvdHJhbnNsYXRvcl9mdW5jdGlvbnMucGhwMBAAAOKN8GEwEAAA9BTryKQBAAAAAAAAMgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvUGhwQXJyYXkucGhwRwMAAOKN8GFHAwAAhy9E0aQBAAAAAAAANwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvQ3N2RGljdGlvbmFyeS5waHBSBAAA4o3wYVIEAABXgkeHpAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Ud2lnLnBocDwEAADijfBhPAQAAP/zS/OkAQAAAAAAADgAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL0pzb25EaWN0aW9uYXJ5LnBocCgCAADijfBhKAIAALIt0SqkAQAAAAAAADwAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL0V4dHJhY3RvckludGVyZmFjZS5waHANAwAA4o3wYQ0DAABwfVnQpAEAAAAAAAAvAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9WdWVKcy5waHBuNgAA4o3wYW42AACFB5g+pAEAAAAAAABBAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9FeHRyYWN0b3JNdWx0aUludGVyZmFjZS5waHCVAwAA4o3wYZUDAAC5pl2HpAEAAAAAAAAtAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9KZWQucGhwHgYAAOKN8GEeBgAAe39jvqQBAAAAAAAALwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvWGxpZmYucGhwmQsAAOKN8GGZCwAAV30b9KQBAAAAAAAAMAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvSnNDb2RlLnBocCgIAADijfBhKAgAADiRdlWkAQAAAAAAACwAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL01vLnBocG0PAADijfBhbQ8AAB9lqHCkAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL0Nzdi5waHAYBQAA4o3wYRgFAACYbTjCpAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Kc29uLnBocC4CAADijfBhLgIAAMV3PXWkAQAAAAAAADEAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL1BocENvZGUucGhwPxMAAOKN8GE/EwAAwoWQJ6QBAAAAAAAALwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvQmxhZGUucGhw+wMAAOKN8GH7AwAANQt4F6QBAAAAAAAAOAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvWWFtbERpY3Rpb25hcnkucGhwUQIAAOKN8GFRAgAAlXS3c6QBAAAAAAAAMwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvRXh0cmFjdG9yLnBocIwHAADijfBhjAcAAAt76m6kAQAAAAAAAC4AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL1lhbWwucGhwXQIAAOKN8GFdAgAAatGPIqQBAAAAAAAALAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvUG8ucGhwkxsAAOKN8GGTGwAA25gdD6QBAAAAAAAALQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0Jhc2VUcmFuc2xhdG9yLnBocKYCAADijfBhpgIAADN29MSkAQAAAAAAACkAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9hdXRvbG9hZGVyLnBocBwBAADijfBhHAEAAEGrcAKkAQAAAAAAACkAAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0NsZHJEYXRhLnBocE02AADijfBhTTYAANrHDy2kAQAAAAAAACkAAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0NhdGVnb3J5LnBocNEQAADijfBh0RAAAISxapqkAQAAAAAAADEAAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0Zvcm11bGFDb252ZXJ0ZXIucGhwshsAAOKN8GGyGwAAM+N8TKQBAAAAAAAAKQAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvTGFuZ3VhZ2UucGhw9T4AAOKN8GH1PgAAejq+iKQBAAAAAAAAKwAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvYXV0b2xvYWRlci5waHBaAQAA4o3wYVoBAACOLvNypAEAAAAAAAAtAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9YbWwucGhw/QgAAOKN8GH9CAAAZSRluaQBAAAAAAAANAAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvRXhwb3J0ZXIvUHJldHR5anNvbi5waHBEAwAA4o3wYUQDAABWJgqApAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9Eb2NzLnBocH0HAADijfBhfQcAAKhZ4OGkAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0V4cG9ydGVyL1BocC5waHAaCAAA4o3wYRoIAADUrUXspAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9Kc29uLnBocOAHAADijfBh4AcAAMZu9kekAQAAAAAAADIAAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0V4cG9ydGVyL0V4cG9ydGVyLnBocA4RAADijfBhDhEAAPw86S6kAQAAAAAAAC4AAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0V4cG9ydGVyL1J1YnkucGhwwAcAAOKN8GHABwAA/TUJVaQBAAAAAAAALgAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvRXhwb3J0ZXIvSHRtbC5waHAQCgAA4o3wYRAKAABLkeUvpAEAAAAAAAAsAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9Qby5waHC6AwAA4o3wYboDAABB//znpAEAAAAAAAApAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9SZW5kZXJlci5waHBBpAAA4o3wYUGkAADUKPA1pAEAAAAAAAAmAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9QZWFzdC5waHCRGgAA4o3wYZEaAACy931wpAEAAAAAAAAmAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9RdWVyeS5waHBACwAA4o3wYUALAACn3pbYpAEAAAAAAAA4AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL1BhcnQvUGFydC5waHByAwAA4o3wYXIDAAChvFknpAEAAAAAAAA/AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL1BhcnQvUHNldWRvSW5kZXgucGhwLQkAAOKN8GEtCQAAtEaeqKQBAAAAAAAAQAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9QYXJ0L1BzZXVkb1NpbXBsZS5waHBrBgAA4o3wYWsGAAB4mde3pAEAAAAAAABCAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL1BhcnQvUHNldWRvU2VsZWN0b3IucGhwXwUAAOKN8GFfBQAA+MuXC6QBAAAAAAAAOgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9QYXJ0L1BzZXVkby5waHC2AgAA4o3wYbYCAABALe2VpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL1BhcnQvQXR0cmlidXRlLnBocMEWAADijfBhwRYAABPXMr+kAQAAAAAAADgAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1NlbGVjdG9yL05vZGUvUGFydC9UeXBlLnBocAYEAADijfBhBgQAALDiKR6kAQAAAAAAADQAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1NlbGVjdG9yL05vZGUvR3JvdXAucGhwDQQAAOKN8GENBAAASDvzHaQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9TZWxlY3Rvci5waHD3BAAA4o3wYfcEAACKOnLVpAEAAAAAAAA5AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL0NvbWJpbmF0b3IucGhwUw8AAOKN8GFTDwAAuK7dCKQBAAAAAAAAMAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvUGFyc2VyLnBocItCAADijfBhi0IAAEcJZOKkAQAAAAAAADMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1NlbGVjdG9yL0V4Y2VwdGlvbi5waHDXAQAA4o3wYdcBAABCUTqNpAEAAAAAAAAxAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9NYXRjaGVzLnBocN8PAADijfBh3w8AAJnehk2kAQAAAAAAACoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1RyYXZlcnNlci5waHCuGgAA4o3wYa4aAAA4/Su7pAEAAAAAAAA3AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvRVMyMDIxL0ZlYXR1cmVzLnBocJYCAADijfBhlgIAAEtZmEGkAQAAAAAAAC8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9TY2FubmVyLnBocM7fAADijfBhzt8AAAIJdjikAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMjIvRmVhdHVyZXMucGhwQwQAAOKN8GFDBAAAjgubEqQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0VTMjAxNS9GZWF0dXJlcy5waHCeAQAA4o3wYZ4BAACtprZApAEAAAAAAAA2AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvUGFyc2VyQWJzdHJhY3QucGhwXiQAAOKN8GFeJAAA5zQTkqQBAAAAAAAAMwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0pTWC9TY2FubmVyLnBocHMNAADijfBhcw0AANaZAdSkAQAAAAAAADIAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9KU1gvUGFyc2VyLnBocAY2AADijfBhBjYAAJDit9WkAQAAAAAAADgAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Db21tZW50c1JlZ2lzdHJ5LnBocKEoAADijfBhoSgAAJojp+CkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1N3aXRjaFN0YXRlbWVudC5waHDuBgAA4o3wYe4GAAClwRDopAEAAAAAAAA6AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9OZXdFeHByZXNzaW9uLnBocK4BAADijfBhrgEAAO+wPqykAQAAAAAAADQAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1Byb2dyYW0ucGhwjwkAAOKN8GGPCQAAvNSAdqQBAAAAAAAAPAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSW1wb3J0U3BlY2lmaWVyLnBocPoEAADijfBh+gQAALghqEmkAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1Rocm93U3RhdGVtZW50LnBocGwEAADijfBhbAQAAIOisYCkAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0ZvckluU3RhdGVtZW50LnBocBQJAADijfBhFAkAAFAX45ukAQAAAAAAAD8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1Byb3BlcnR5RGVmaW5pdGlvbi5waHDhDAAA4o3wYeEMAACJtdBIpAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JbXBvcnREZWZhdWx0U3BlY2lmaWVyLnBocOcBAADijfBh5wEAAOEf5EqkAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1dpdGhTdGF0ZW1lbnQucGhwaQYAAOKN8GFpBgAAJLzf6aQBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRnVuY3Rpb25fLnBocNkNAADijfBh2Q0AAHefdvGkAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0JpbmFyeUV4cHJlc3Npb24ucGhwzggAAOKN8GHOCAAAdlgLJKQBAAAAAAAAOQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRm9yU3RhdGVtZW50LnBocEMLAADijfBhQwsAADGhD6qkAQAAAAAAADgAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1Jlc3RFbGVtZW50LnBocJkEAADijfBhmQQAADdeZ/2kAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL051bWVyaWNMaXRlcmFsLnBocKITAADijfBhohMAAKnQ9g2kAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1VuYXJ5RXhwcmVzc2lvbi5waHBSCQAA4o3wYVIJAAArJTYHpAEAAAAAAAA5AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9UcnlTdGF0ZW1lbnQucGhwBQkAAOKN8GEFCQAAiji1IqQBAAAAAAAARQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyLnBocN0BAADijfBh3QEAAE3znmOkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0F3YWl0RXhwcmVzc2lvbi5waHBVBAAA4o3wYVUEAAChDtz4pAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9FeHBvcnROYW1lZERlY2xhcmF0aW9uLnBocNEJAADijfBh0QkAAJ73o4CkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0FycmF5RXhwcmVzc2lvbi5waHATBQAA4o3wYRMFAAB0OKzupAEAAAAAAABAAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9GdW5jdGlvbkRlY2xhcmF0aW9uLnBocOQCAADijfBh5AIAADes0gykAQAAAAAAADkAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01ldGFQcm9wZXJ0eS5waHAFBgAA4o3wYQUGAACZ+ToLpAEAAAAAAAA4AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JZlN0YXRlbWVudC5waHCiCgAA4o3wYaIKAAAlHx6RpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9DbGFzc0RlY2xhcmF0aW9uLnBocNACAADijfBh0AIAACVe6WqkAQAAAAAAAD8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1ZhcmlhYmxlRGVjbGFyYXRvci5waHCrBgAA4o3wYasGAADRYvbZpAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Qcml2YXRlSWRlbnRpZmllci5waHAGBAAA4o3wYQYEAACpb5cgpAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYSWRlbnRpZmllci5waHC0AQAA4o3wYbQBAACDmeBMpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYQXR0cmlidXRlLnBocH0HAADijfBhfQcAAK8b1hykAQAAAAAAAEMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hTcHJlYWRBdHRyaWJ1dGUucGhwxQEAAOKN8GHFAQAASyZRj6QBAAAAAAAAQgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWENsb3NpbmdFbGVtZW50LnBocKYBAADijfBhpgEAAN1m86GkAQAAAAAAAEcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hFeHByZXNzaW9uQ29udGFpbmVyLnBocLQFAADijfBhtAUAAF1791ekAQAAAAAAAD8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hTcHJlYWRDaGlsZC5waHCkBAAA4o3wYaQEAABpTWK+pAEAAAAAAAA4AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYVGV4dC5waHD4BQAA4o3wYfgFAACZxpG5pAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYT3BlbmluZ0ZyYWdtZW50LnBocLcBAADijfBhtwEAAJXktAikAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hGcmFnbWVudC5waHCbCgAA4o3wYZsKAADMjNS3pAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYQ2xvc2luZ0ZyYWdtZW50LnBocLcBAADijfBhtwEAAE7oh1ykAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hFbGVtZW50LnBocMAKAADijfBhwAoAAC4qa0KkAQAAAAAAAEMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hFbXB0eUV4cHJlc3Npb24ucGhwswEAAOKN8GGzAQAAOrY4/6QBAAAAAAAAQgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWE5hbWVzcGFjZWROYW1lLnBocHoGAADijfBhegYAAMLUhD2kAQAAAAAAAEIAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hPcGVuaW5nRWxlbWVudC5waHDVBwAA4o3wYdUHAACoRCaJpAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYQm91bmRhcnlFbGVtZW50LnBocIgFAADijfBhiAUAAO8RoeekAQAAAAAAAEQAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hNZW1iZXJFeHByZXNzaW9uLnBocGYHAADijfBhZgcAAGgZ8K+kAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01ldGhvZERlZmluaXRpb24ucGhw+g8AAOKN8GH6DwAAtXcaXKQBAAAAAAAAQAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRXhwcmVzc2lvblN0YXRlbWVudC5waHCMBAAA4o3wYYwEAABbtAJtpAEAAAAAAAA2AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9DbGFzc0JvZHkucGhwLAUAAOKN8GEsBQAApzeyoqQBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTnVsbExpdGVyYWwucGhwAQMAAOKN8GEBAwAA3UvaD6QBAAAAAAAAPQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRG9XaGlsZVN0YXRlbWVudC5waHAyBgAA4o3wYTIGAACopaGBpAEAAAAAAAA6AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9PYmplY3RQYXR0ZXJuLnBocNYEAADijfBh1gQAAL/959ykAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0Zvck9mU3RhdGVtZW50LnBocJoEAADijfBhmgQAAP2/LOmkAQAAAAAAADQAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1BhdHRlcm4ucGhwgQEAAOKN8GGBAQAAxdUAvqQBAAAAAAAAMQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTm9kZS5waHCzIAAA4o3wYbMgAACkXBuEpAEAAAAAAABFAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9UYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb24ucGhwXAYAAOKN8GFcBgAAuy2/8qQBAAAAAAAAPAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvVGVtcGxhdGVFbGVtZW50LnBocPQJAADijfBh9AkAADeG/9GkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1RlbXBsYXRlTGl0ZXJhbC5waHBrDQAA4o3wYWsNAACrpjtgpAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9XaGlsZVN0YXRlbWVudC5waHAqBgAA4o3wYSoGAADqrpOHpAEAAAAAAAA4AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9TdGF0aWNCbG9jay5waHCSAQAA4o3wYZIBAAD0WH5WpAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Mb2dpY2FsRXhwcmVzc2lvbi5waHBaCAAA4o3wYVoIAAC/0VOepAEAAAAAAAA6AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9CaWdJbnRMaXRlcmFsLnBocBAFAADijfBhEAUAAEECE82kAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NoYWluRXhwcmVzc2lvbi5waHCJBAAA4o3wYYkEAAAa+IJlpAEAAAAAAAA3AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Td2l0Y2hDYXNlLnBocFgHAADijfBhWAcAAPtFAwukAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1JlZ0V4cExpdGVyYWwucGhwSgoAAOKN8GFKCgAAdHH0pqQBAAAAAAAARAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24ucGhw/QUAAOKN8GH9BQAA0YXP96QBAAAAAAAAPgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ29udGludWVTdGF0ZW1lbnQucGhwggQAAOKN8GGCBAAA7MhaWaQBAAAAAAAANAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTGl0ZXJhbC5waHAeBgAA4o3wYR4GAAATxDXKpAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9DYWxsRXhwcmVzc2lvbi5waHBXBwAA4o3wYVcHAAD7jpsNpAEAAAAAAAA3AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JZGVudGlmaWVyLnBocPAHAADijfBh8AcAAAcdn0+kAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0V4cHJlc3Npb24ucGhwhwEAAOKN8GGHAQAAenf3IaQBAAAAAAAAPgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSW1wb3J0RGVjbGFyYXRpb24ucGhwggcAAOKN8GGCBwAAAFifOaQBAAAAAAAAOQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQXJyYXlQYXR0ZXJuLnBocJcEAADijfBhlwQAAN7KkSikAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1N0cmluZ0xpdGVyYWwucGhwvwkAAOKN8GG/CQAANb924qQBAAAAAAAARQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uLnBocCIFAADijfBhIgUAAFMo7zakAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0xhYmVsZWRTdGF0ZW1lbnQucGhw5gUAAOKN8GHmBQAAKAaOkqQBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvU3RhdGVtZW50LnBocIUBAADijfBhhQEAAIWXkgakAQAAAAAAAD4AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01vZHVsZURlY2xhcmF0aW9uLnBocJABAADijfBhkAEAANRudKukAQAAAAAAADgAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NhdGNoQ2xhdXNlLnBocMMGAADijfBhwwYAAOUFpLGkAQAAAAAAAEAAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1ZhcmlhYmxlRGVjbGFyYXRpb24ucGhwYwgAAOKN8GFjCAAAFLejSaQBAAAAAAAAOwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQm9vbGVhbkxpdGVyYWwucGhwSQMAAOKN8GFJAwAAbc7OfKQBAAAAAAAARAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvUGFyZW50aGVzaXplZEV4cHJlc3Npb24ucGhwiAQAAOKN8GGIBAAAKILl06QBAAAAAAAAOwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQnJlYWtTdGF0ZW1lbnQucGhweQQAAOKN8GF5BAAAkQyLMqQBAAAAAAAAPAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvWWllbGRFeHByZXNzaW9uLnBocDAHAADijfBhMAcAAIUpBRikAQAAAAAAAEEAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0V4cG9ydEFsbERlY2xhcmF0aW9uLnBocOAGAADijfBh4AYAAO8fIqykAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1RoaXNFeHByZXNzaW9uLnBocKABAADijfBhoAEAAOIlYYKkAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1NwcmVhZEVsZW1lbnQucGhwigQAAOKN8GGKBAAAJFX+Z6QBAAAAAAAAOQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ2hhaW5FbGVtZW50LnBocMcEAADijfBhxwQAACLMDSukAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0V4cG9ydFNwZWNpZmllci5waHDuBAAA4o3wYe4EAAAaKPWZpAEAAAAAAAAyAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9TdXBlci5waHCCAQAA4o3wYYIBAABSQ9wopAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9FbXB0eVN0YXRlbWVudC5waHCjAQAA4o3wYaMBAABusr0PpAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9EZWJ1Z2dlclN0YXRlbWVudC5waHC+AQAA4o3wYb4BAABkaeMfpAEAAAAAAAA0AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Db21tZW50LnBocHMQAADijfBhcxAAAI7oyZakAQAAAAAAAD8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1NlcXVlbmNlRXhwcmVzc2lvbi5waHDKBAAA4o3wYcoEAADy3NMOpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9PYmplY3RFeHByZXNzaW9uLnBocM0EAADijfBhzQQAACchRX+kAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01vZHVsZVNwZWNpZmllci5waHC2BAAA4o3wYbYEAADwR2pDpAEAAAAAAABCAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Db25kaXRpb25hbEV4cHJlc3Npb24ucGhwEQkAAOKN8GERCQAAlvqoiaQBAAAAAAAAPQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvVXBkYXRlRXhwcmVzc2lvbi5waHA7CQAA4o3wYTsJAAANHxOVpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JbXBvcnRFeHByZXNzaW9uLnBocE8EAADijfBhTwQAAKuETPKkAQAAAAAAADgAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0RlY2xhcmF0aW9uLnBocJsBAADijfBhmwEAADizNOWkAQAAAAAAADUAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1Byb3BlcnR5LnBocAMTAADijfBhAxMAAHLzh+ekAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01lbWJlckV4cHJlc3Npb24ucGhwYAoAAOKN8GFgCgAAvJNHnqQBAAAAAAAAPwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRnVuY3Rpb25FeHByZXNzaW9uLnBocNUBAADijfBh1QEAAMG9wVWkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NsYXNzRXhwcmVzc2lvbi5waHDCAQAA4o3wYcIBAABwfqrDpAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Bc3NpZ25tZW50UGF0dGVybi5waHCxBgAA4o3wYbEGAAAVwFJZpAEAAAAAAAA8AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9SZXR1cm5TdGF0ZW1lbnQucGhw9QQAAOKN8GH1BAAA1jpD66QBAAAAAAAAQQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQXNzaWdubWVudEV4cHJlc3Npb24ucGhwMgkAAOKN8GEyCQAAnfpUjqQBAAAAAAAAPwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQXNzaWdubWVudFByb3BlcnR5LnBocJkFAADijfBhmQUAAPqXQdukAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0Jsb2NrU3RhdGVtZW50LnBocJ4EAADijfBhngQAAJ/gAIakAQAAAAAAADMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NsYXNzXy5waHB5CAAA4o3wYXkIAAAQbuCQpAEAAAAAAAAuAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvUGFyc2VyLnBocDf+AQDijfBhN/4BAGD38nCkAQAAAAAAADAAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9GZWF0dXJlcy5waHDZCwAA4o3wYdkLAACLDtObpAEAAAAAAAAtAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvVG9rZW4ucGhwxw4AAOKN8GHHDgAAsINCFaQBAAAAAAAAMAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L1Bvc2l0aW9uLnBocPwGAADijfBh/AYAAGucd0ekAQAAAAAAADUAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FdmVudHNFbWl0dGVyLnBocBcGAADijfBhFwYAAIZ7EHWkAQAAAAAAADEAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FeGNlcHRpb24ucGhwCwQAAOKN8GELBAAAN10BaaQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0VTMjAxOS9GZWF0dXJlcy5waHCaAgAA4o3wYZoCAAAwgYRepAEAAAAAAAAtAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvVXRpbHMucGhwoCYAAOKN8GGgJgAA2Uzpc6QBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L1NvdXJjZUxvY2F0aW9uLnBocLIGAADijfBhsgYAALc88+ekAQAAAAAAACsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9MU00ucGhw1REAAOKN8GHVEQAAD/rsL6QBAAAAAAAAOQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0VuY29kaW5nRXhjZXB0aW9uLnBocPcBAADijfBh9wEAAEwSyHCkAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMTgvRmVhdHVyZXMucGhwKAMAAOKN8GEoAwAAhqFwZqQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0VTMjAxNy9GZWF0dXJlcy5waHACAwAA4o3wYQIDAACVkkhApAEAAAAAAAA3AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvRVMyMDE2L0ZlYXR1cmVzLnBocBcCAADijfBhFwIAAKF0frakAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMjAvRmVhdHVyZXMucGhwEwQAAOKN8GETBAAAGLcXT6QBAAAAAAAAMwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvRm9ybWF0dGVyL0V4cGFuZGVkLnBocOcCAADijfBh5wIAAL4TqHikAQAAAAAAADIAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L0Zvcm1hdHRlci9Db21wYWN0LnBocLcDAADijfBhtwMAAPsa6nSkAQAAAAAAAC8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L0Zvcm1hdHRlci9CYXNlLnBocPYKAADijfBh9goAAOo2idSkAQAAAAAAADYAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L0Zvcm1hdHRlci9QcmV0dHlQcmludC5waHByAQAA4o3wYXIBAACMaunPpAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvdGVtcGxhdGVzL21hbi5tdXN0YWNoZf4AAADijfBh/gAAAKlJHjykAQAAAAAAADIAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS90ZW1wbGF0ZXMvbWFuLXBhcmFtcy5tdXN0YWNoZT8BAADijfBhPwEAAJMTzW6kAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL2NvbmZpZy1jb21tYW5kL3RlbXBsYXRlcy93cC1jb25maWcubXVzdGFjaGU2DQAA4o3wYTYNAAAGeOHHpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9jb3JlLWNvbW1hbmQvdGVtcGxhdGVzL3ZlcnNpb25zLm11c3RhY2hljAAAAOKN8GGMAAAAU1UitKQBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvdGVtcGxhdGVzL3RoZW1lLXN0YXR1cy5tdXN0YWNoZXgAAADijfBheAAAAMeBZ9GkAQAAAAAAAEAAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tc3RhdHVzLm11c3RhY2hlmgAAAOKN8GGaAAAAb1vGNaQBAAAAAAAAPgAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvdGhlbWUtc3RhdHVzLm11c3RhY2hleAAAAOKN8GF4AAAAx4Fn0aQBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGhwdW5pdC54bWwuZGlzdIUBAADijfBhhQEAACXV9UakAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1naXRpZ25vcmUubXVzdGFjaGVeAAAA4o3wYV4AAADHweaApAEAAAAAAABBAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tcGFja2FnZXMubXVzdGFjaGVeAQAA4o3wYV4BAACjNYkrpAEAAAAAAABBAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy90aGVtZS1ib290c3RyYXAubXVzdGFjaGWZBQAA4o3wYZkFAAA+6/rKpAEAAAAAAABEAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tdGVzdC1zYW1wbGUubXVzdGFjaGUnAQAA4o3wYScBAAAWXH6npAEAAAAAAABDAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy90YXhvbm9teV9leHRlbmRlZC5tdXN0YWNoZegDAADijfBh6AMAAJt71yykAQAAAAAAADgAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi5tdXN0YWNoZXEBAADijfBhcQEAAEeJcdKkAQAAAAAAADgAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzLy5waHBjcy54bWwuZGlzdD0IAADijfBhPQgAAFseui2kAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1ncnVudGZpbGUubXVzdGFjaGWlBAAA4o3wYaUEAADRVIsEpAEAAAAAAABDAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy90aGVtZS10ZXN0LXNhbXBsZS5tdXN0YWNoZSYBAADijfBhJgEAAH/9le6kAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3RheG9ub215Lm11c3RhY2hlaQoAAOKN8GFpCgAA+K5SeKQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvLmVkaXRvcmNvbmZpZ8ABAADijfBhwAEAABKmaNGkAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL2Jsb2NrLWVkaXRvci1jc3MubXVzdGFjaGXLAAAA4o3wYcsAAACTLFZdpAEAAAAAAABBAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9ibG9jay1zdHlsZS1jc3MubXVzdGFjaGUBAQAA4o3wYQEBAAAerpfYpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tY2lyY2xlLm11c3RhY2hlPAsAAOKN8GE8CwAABXnpNaQBAAAAAAAAQwAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGx1Z2luLWRpc3RpZ25vcmUubXVzdGFjaGVIAgAA4o3wYUgCAAAxRUGopAEAAAAAAABAAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9ibG9jay1pbmRleC1qcy5tdXN0YWNoZeQKAADijfBh5AoAACK9tTCkAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1iaXRidWNrZXQubXVzdGFjaGWRFQAA4o3wYZEVAABaQmdtpAEAAAAAAABEAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wb3N0X3R5cGVfZXh0ZW5kZWQubXVzdGFjaGWNEAAA4o3wYY0QAACHO35lpAEAAAAAAABCAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tYm9vdHN0cmFwLm11c3RhY2hlgAQAAOKN8GGABAAAhX+9qqQBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGx1Z2luLWdpdGxhYi5tdXN0YWNoZVwFAADijfBhXAUAAOL8oAykAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL2luc3RhbGwtd3AtdGVzdHMuc2h0FwAA4o3wYXQXAAClGKa9pAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tcmVhZG1lLm11c3RhY2hlGhEAAOKN8GEaEQAAA2IM+6QBAAAAAAAAPQAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvY2hpbGRfdGhlbWUubXVzdGFjaGXUAAAA4o3wYdQAAADp/fa5pAEAAAAAAABHAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9jaGlsZF90aGVtZV9mdW5jdGlvbnMubXVzdGFjaGVOAgAA4o3wYU4CAAAukd8PpAEAAAAAAAA7AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wb3N0X3R5cGUubXVzdGFjaGW0CgAA4o3wYbQKAAChMySnpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tdHJhdmlzLm11c3RhY2hl+QYAAOKN8GH5BgAAYUeVUqQBAAAAAAAAEwAAAHZlbmRvci9hdXRvbG9hZC5waHCyAAAA4o3wYbIAAACKzQpRpAEAAAAAAAAgAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL0xJQ0VOU0UsBAAA4o3wYSwEAABWhmeCpAEAAAAAAAAxAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3Jlcy9jb21wb3Nlci1zY2hlbWEuanNvboWyAADijfBhhbIAALMfkC2kAQAAAAAAADwAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVHJhbnNwb3J0L2NhY2VydC5wZW1/PgMA4o3wYX8+AwC2EFVWpAEAAAAAAAAmAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvQ09NUE9TRVJfVkVSU0lPTlOfDgAA4o3wYZ8OAABpE3ntpAEAAAAAAAAcAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvVkVSU0lPTgUAAADijfBhBQAAAFRkFlCkAQAAAAAAADw/cGhwCgovLyBDYW4gYmUgdXNlZCBieSBwbHVnaW5zL3RoZW1lcyB0byBjaGVjayBpZiBXUC1DTEkgaXMgcnVubmluZyBvciBub3QuCmRlZmluZSggJ1dQX0NMSScsIHRydWUgKTsKZGVmaW5lKCAnV1BfQ0xJX1ZFUlNJT04nLCB0cmltKCBmaWxlX2dldF9jb250ZW50cyggV1BfQ0xJX1JPT1QgLiAnL1ZFUlNJT04nICkgKSApOwpkZWZpbmUoICdXUF9DTElfU1RBUlRfTUlDUk9USU1FJywgbWljcm90aW1lKCB0cnVlICkgKTsKCmlmICggZmlsZV9leGlzdHMoIFdQX0NMSV9ST09UIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJyApICkgewoJZGVmaW5lKCAnV1BfQ0xJX1ZFTkRPUl9ESVInLCBXUF9DTElfUk9PVCAuICcvdmVuZG9yJyApOwp9IGVsc2VpZiAoIGZpbGVfZXhpc3RzKCBkaXJuYW1lKCBkaXJuYW1lKCBXUF9DTElfUk9PVCApICkgLiAnL2F1dG9sb2FkLnBocCcgKSApIHsKCWRlZmluZSggJ1dQX0NMSV9WRU5ET1JfRElSJywgZGlybmFtZSggZGlybmFtZSggV1BfQ0xJX1JPT1QgKSApICk7Cn0gZWxzZWlmICggZmlsZV9leGlzdHMoIGRpcm5hbWUoIFdQX0NMSV9ST09UICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnICkgKSB7CglkZWZpbmUoICdXUF9DTElfVkVORE9SX0RJUicsIGRpcm5hbWUoIFdQX0NMSV9ST09UICkgLiAnL3ZlbmRvcicgKTsKfSBlbHNlIHsKCWRlZmluZSggJ1dQX0NMSV9WRU5ET1JfRElSJywgV1BfQ0xJX1JPT1QgLiAnL3ZlbmRvcicgKTsKfQoKcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvY29tcGF0LnBocCc7CgovLyBTZXQgY29tbW9uIGhlYWRlcnMsIHRvIHByZXZlbnQgd2FybmluZ3MgZnJvbSBwbHVnaW5zLgokX1NFUlZFUlsnU0VSVkVSX1BST1RPQ09MJ10gPSAnSFRUUC8xLjAnOwokX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10gPSAnJzsKJF9TRVJWRVJbJ1JFUVVFU1RfTUVUSE9EJ10gID0gJ0dFVCc7CiRfU0VSVkVSWydSRU1PVEVfQUREUiddICAgICA9ICcxMjcuMC4wLjEnOwoKcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvYm9vdHN0cmFwLnBocCc7CldQX0NMSVxib290c3RyYXAoKTsKPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgRXhjZXB0aW9uOwoKY2xhc3MgRXhpdEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7fQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBHZW5lcmF0ZSBhIHN5bm9wc2lzIGZyb20gYSBjb21tYW5kJ3MgUEhQZG9jIGFyZ3VtZW50cy4KICogVHVybnMgc29tZXRoaW5nIGxpa2UgIjxvYmplY3QtaWQ+Li4uIgogKiBpbnRvIFsgb3B0aW9uYWw9PmZhbHNlLCB0eXBlPT5wb3NpdGlvbmFsLCByZXBlYXRpbmc9PnRydWUsIG5hbWU9Pm9iamVjdC1pZCBdCiAqLwpjbGFzcyBTeW5vcHNpc1BhcnNlciB7CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRzeW5vcHNpcyBBIHN5bm9wc2lzCgkgKiBAcmV0dXJuIGFycmF5IExpc3Qgb2YgcGFyYW1ldGVycwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhcnNlKCAkc3lub3BzaXMgKSB7CgkJJHRva2VucyA9IGFycmF5X2ZpbHRlciggcHJlZ19zcGxpdCggJy9bXHNcdF0rLycsICRzeW5vcHNpcyApICk7CgoJCSRwYXJhbXMgPSBbXTsKCQlmb3JlYWNoICggJHRva2VucyBhcyAkdG9rZW4gKSB7CgkJCSRwYXJhbSA9IHNlbGY6OmNsYXNzaWZ5X3Rva2VuKCAkdG9rZW4gKTsKCgkJCS8vIFNvbWUgdHlwZXMgb2YgcGFyYW1ldGVycyBzaG91bGRuJ3QgYmUgbWFuZGF0b3J5CgkJCWlmICggaXNzZXQoICRwYXJhbVsnb3B0aW9uYWwnXSApICYmICEgJHBhcmFtWydvcHRpb25hbCddICkgewoJCQkJaWYgKCAnZmxhZycgPT09ICRwYXJhbVsndHlwZSddIHx8ICggJ2Fzc29jJyA9PT0gJHBhcmFtWyd0eXBlJ10gJiYgJHBhcmFtWyd2YWx1ZSddWydvcHRpb25hbCddICkgKSB7CgkJCQkJJHBhcmFtWyd0eXBlJ10gPSAndW5rbm93bic7CgkJCQl9CgkJCX0KCgkJCSRwYXJhbVsndG9rZW4nXSA9ICR0b2tlbjsKCQkJJHBhcmFtc1tdICAgICAgID0gJHBhcmFtOwoJCX0KCgkJcmV0dXJuICRwYXJhbXM7Cgl9CgoJLyoqCgkgKiBSZW5kZXIgdGhlIFN5bm9wc2lzIGludG8gYSBmb3JtYXQgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkc3lub3BzaXMgQSBzdHJ1Y3R1cmVkIHN5bm9wc2lzLiBUaGlzIG1pZ2h0IGdldCByZW9yZGVyZWQKCSAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gbWF0Y2ggdGhlIHBhcnNlZCBvdXRwdXQuCgkgKiBAcmV0dXJuIHN0cmluZyBSZW5kZXJlZCBzeW5vcHNpcy4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZW5kZXIoICYkc3lub3BzaXMgKSB7CgkJaWYgKCAhIGlzX2FycmF5KCAkc3lub3BzaXMgKSApIHsKCQkJcmV0dXJuICcnOwoJCX0KCQkkYml0cyAgICAgICAgICAgICAgID0gWwoJCQkncG9zaXRpb25hbCcgPT4gJycsCgkJCSdhc3NvYycgICAgICA9PiAnJywKCQkJJ2dlbmVyaWMnICAgID0+ICcnLAoJCQknZmxhZycgICAgICAgPT4gJycsCgkJXTsKCQkkcmVvcmRlcmVkX3N5bm9wc2lzID0gWwoJCQkncG9zaXRpb25hbCcgPT4gW10sCgkJCSdhc3NvYycgICAgICA9PiBbXSwKCQkJJ2dlbmVyaWMnICAgID0+IFtdLAoJCQknZmxhZycgICAgICAgPT4gW10sCgkJXTsKCQlmb3JlYWNoICggJGJpdHMgYXMgJGtleSA9PiAmJHZhbHVlICkgewoJCQlmb3JlYWNoICggJHN5bm9wc2lzIGFzICRhcmcgKSB7CgkJCQlpZiAoIGVtcHR5KCAkYXJnWyd0eXBlJ10gKQoJCQkJCXx8ICRrZXkgIT09ICRhcmdbJ3R5cGUnXSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoIGVtcHR5KCAkYXJnWyduYW1lJ10gKSAmJiAnZ2VuZXJpYycgIT09ICRhcmdbJ3R5cGUnXSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoICdwb3NpdGlvbmFsJyA9PT0gJGtleSApIHsKCQkJCQkkcmVuZGVyZWRfYXJnID0gIjx7JGFyZ1snbmFtZSddfT4iOwoKCQkJCQkkcmVvcmRlcmVkX3N5bm9wc2lzWydwb3NpdGlvbmFsJ10gW10gPSAkYXJnOwoJCQkJfSBlbHNlaWYgKCAnYXNzb2MnID09PSAka2V5ICkgewoJCQkJCSRhcmdfdmFsdWUgICAgPSBpc3NldCggJGFyZ1sndmFsdWUnXVsnbmFtZSddICkgPyAkYXJnWyd2YWx1ZSddWyduYW1lJ10gOiAkYXJnWyduYW1lJ107CgkJCQkJJHJlbmRlcmVkX2FyZyA9ICItLXskYXJnWyduYW1lJ119PTx7JGFyZ192YWx1ZX0+IjsKCgkJCQkJJHJlb3JkZXJlZF9zeW5vcHNpc1snYXNzb2MnXSBbXSA9ICRhcmc7CgkJCQl9IGVsc2VpZiAoICdnZW5lcmljJyA9PT0gJGtleSApIHsKCQkJCQkkcmVuZGVyZWRfYXJnID0gJy0tPGZpZWxkPj08dmFsdWU+JzsKCgkJCQkJJHJlb3JkZXJlZF9zeW5vcHNpc1snZ2VuZXJpYyddIFtdID0gJGFyZzsKCQkJCX0gZWxzZWlmICggJ2ZsYWcnID09PSAka2V5ICkgewoJCQkJCSRyZW5kZXJlZF9hcmcgPSAiLS17JGFyZ1snbmFtZSddfSI7CgoJCQkJCSRyZW9yZGVyZWRfc3lub3BzaXNbJ2ZsYWcnXSBbXSA9ICRhcmc7CgkJCQl9CgkJCQlpZiAoICEgZW1wdHkoICRhcmdbJ3JlcGVhdGluZyddICkgKSB7CgkJCQkJJHJlbmRlcmVkX2FyZyA9ICJ7JHJlbmRlcmVkX2FyZ30uLi4iOwoJCQkJfQoJCQkJaWYgKCAhIGVtcHR5KCAkYXJnWydvcHRpb25hbCddICkgKSB7CgkJCQkJJHJlbmRlcmVkX2FyZyA9ICJbeyRyZW5kZXJlZF9hcmd9XSI7CgkJCQl9CgkJCQkkdmFsdWUgLj0gInskcmVuZGVyZWRfYXJnfSAiOwoJCQl9CgkJfQoJCSRyZW5kZXJlZCA9ICcnOwoJCWZvcmVhY2ggKCAkYml0cyBhcyAkdiApIHsKCQkJaWYgKCAhIGVtcHR5KCAkdiApICkgewoJCQkJJHJlbmRlcmVkIC49ICR2OwoJCQl9CgkJfQoKCQkkc3lub3BzaXMgPSBhcnJheV9tZXJnZSgKCQkJJHJlb3JkZXJlZF9zeW5vcHNpc1sncG9zaXRpb25hbCddLAoJCQkkcmVvcmRlcmVkX3N5bm9wc2lzWydhc3NvYyddLAoJCQkkcmVvcmRlcmVkX3N5bm9wc2lzWydnZW5lcmljJ10sCgkJCSRyZW9yZGVyZWRfc3lub3BzaXNbJ2ZsYWcnXQoJCSk7CgoJCXJldHVybiBydHJpbSggJHJlbmRlcmVkLCAnICcgKTsKCX0KCgkvKioKCSAqIENsYXNzaWZ5IGFyZ3VtZW50IGF0dHJpYnV0ZXMgYmFzZWQgb24gaXRzIHN5bnRheC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0b2tlbgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjbGFzc2lmeV90b2tlbiggJHRva2VuICkgewoJCSRwYXJhbSA9IFtdOwoKCQlsaXN0KCAkcGFyYW1bJ29wdGlvbmFsJ10sICR0b2tlbiApICA9IHNlbGY6OmlzX29wdGlvbmFsKCAkdG9rZW4gKTsKCQlsaXN0KCAkcGFyYW1bJ3JlcGVhdGluZyddLCAkdG9rZW4gKSA9IHNlbGY6OmlzX3JlcGVhdGluZyggJHRva2VuICk7CgoJCSRwX25hbWUgID0gJyhbYS16LV8wLTldKyknOwoJCSRwX3ZhbHVlID0gJyhbYS16QS1aLV98LDAtOV0rKSc7CgoJCWlmICggJy0tPGZpZWxkPj08dmFsdWU+JyA9PT0gJHRva2VuICkgewoJCQkkcGFyYW1bJ3R5cGUnXSA9ICdnZW5lcmljJzsKCQl9IGVsc2VpZiAoIHByZWdfbWF0Y2goICIvXjwoJHBfdmFsdWUpPiQvIiwgJHRva2VuLCAkbWF0Y2hlcyApICkgewoJCQkkcGFyYW1bJ3R5cGUnXSA9ICdwb3NpdGlvbmFsJzsKCQkJJHBhcmFtWyduYW1lJ10gPSAkbWF0Y2hlc1sxXTsKCQl9IGVsc2VpZiAoIHByZWdfbWF0Y2goICIvXi0tKD86XFxbbm8tXFxdKT8kcF9uYW1lLyIsICR0b2tlbiwgJG1hdGNoZXMgKSApIHsKCQkJJHBhcmFtWyduYW1lJ10gPSAkbWF0Y2hlc1sxXTsKCgkJCSR2YWx1ZSA9IHN1YnN0ciggJHRva2VuLCBzdHJsZW4oICRtYXRjaGVzWzBdICkgKTsKCgkJCS8vIHN1YnN0ciByZXR1cm5zIGZhbHNlIDw9IFBIUCA1LjYsIGFuZCAnJyBQSFAgNysKCQkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlIHx8ICcnID09PSAkdmFsdWUgKSB7CgkJCQkkcGFyYW1bJ3R5cGUnXSA9ICdmbGFnJzsKCQkJfSBlbHNlIHsKCQkJCSRwYXJhbVsndHlwZSddID0gJ2Fzc29jJzsKCgkJCQlsaXN0KCAkcGFyYW1bJ3ZhbHVlJ11bJ29wdGlvbmFsJ10sICR2YWx1ZSApID0gc2VsZjo6aXNfb3B0aW9uYWwoICR2YWx1ZSApOwoKCQkJCWlmICggcHJlZ19tYXRjaCggIi9ePTwkcF92YWx1ZT4kLyIsICR2YWx1ZSwgJG1hdGNoZXMgKSApIHsKCQkJCQkkcGFyYW1bJ3ZhbHVlJ11bJ25hbWUnXSA9ICRtYXRjaGVzWzFdOwoJCQkJfSBlbHNlIHsKCQkJCQkkcGFyYW0gPSBbCgkJCQkJCSd0eXBlJyA9PiAndW5rbm93bicsCgkJCQkJXTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCSRwYXJhbVsndHlwZSddID0gJ3Vua25vd24nOwoJCX0KCgkJcmV0dXJuICRwYXJhbTsKCX0KCgkvKioKCSAqIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBpcyBzdXJyb3VuZGVkIGJ5IHNxdWFyZSBicmFja2V0cy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0b2tlbgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc19vcHRpb25hbCggJHRva2VuICkgewoJCWlmICggJ1snID09PSBzdWJzdHIoICR0b2tlbiwgMCwgMSApICYmICddJyA9PT0gc3Vic3RyKCAkdG9rZW4sIC0xICkgKSB7CgkJCXJldHVybiBbIHRydWUsIHN1YnN0ciggJHRva2VuLCAxLCAtMSApIF07CgkJfQoKCQlyZXR1cm4gWyBmYWxzZSwgJHRva2VuIF07Cgl9CgoJLyoqCgkgKiBBIHJlcGVhdGluZyBwYXJhbWV0ZXIgaXMgZm9sbG93ZWQgYnkgYW4gZWxsaXBzaXMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdG9rZW4KCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaXNfcmVwZWF0aW5nKCAkdG9rZW4gKSB7CgkJaWYgKCAnLi4uJyA9PT0gc3Vic3RyKCAkdG9rZW4sIC0zICkgKSB7CgkJCXJldHVybiBbIHRydWUsIHN1YnN0ciggJHRva2VuLCAwLCAtMyApIF07CgkJfQoKCQlyZXR1cm4gWyBmYWxzZSwgJHRva2VuIF07Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29udGV4dDsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcQ29udGV4dDsKCi8qKgogKiBDb250ZXh0IHdoaWNoIHNpbXVsYXRlcyBhIGZyb250ZW5kIHJlcXVlc3QuCiAqLwpmaW5hbCBjbGFzcyBGcm9udGVuZCBpbXBsZW1lbnRzIENvbnRleHQgewoKCS8qKgoJICogUHJvY2VzcyB0aGUgY29udGV4dCB0byBzZXQgdXAgdGhlIGVudmlyb25tZW50IGNvcnJlY3RseS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGNvbmZpZyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBjb25maWd1cmF0aW9uIGRhdGEuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCAkY29uZmlnICkgewoJCS8vIFRPRE86IEZyb250ZW5kIGNvbnRleHQgbmVlZHMgdG8gYmUgc2ltdWxhdGVkIGhlcmUuCgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29udGV4dDsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcQ29udGV4dDsKdXNlIFdQX1Nlc3Npb25fVG9rZW5zOwoKLyoqCiAqIENvbnRleHQgd2hpY2ggc2ltdWxhdGVzIHRoZSBhZG1pbmlzdHJhdG9yIGJhY2tlbmQuCiAqLwpmaW5hbCBjbGFzcyBBZG1pbiBpbXBsZW1lbnRzIENvbnRleHQgewoKCS8qKgoJICogUHJvY2VzcyB0aGUgY29udGV4dCB0byBzZXQgdXAgdGhlIGVudmlyb25tZW50IGNvcnJlY3RseS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGNvbmZpZyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBjb25maWd1cmF0aW9uIGRhdGEuCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoICRjb25maWcgKSB7CgkJaWYgKCBkZWZpbmVkKCAnV1BfQURNSU4nICkgKSB7CgkJCWlmICggISBXUF9BRE1JTiApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJ0NvdWxkIG5vdCBmYWtlIGFkbWluIHJlcXVlc3QuJyApOwoJCQl9CgoJCQlyZXR1cm47CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAnRmFraW5nIGFuIGFkbWluIHJlcXVlc3QnLCBDb250ZXh0OjpERUJVR19HUk9VUCApOwoKCQkvLyBEZWZpbmUgYFdQX0FETUlOYCBhcyBiZWluZyB0cnVlLiBUaGlzIGNhdXNlcyB0aGUgaGVscGVyIG1ldGhvZAoJCS8vIGBpc19hZG1pbigpYCB0byByZXR1cm4gdHJ1ZSBhcyB3ZWxsLgoJCWRlZmluZSggJ1dQX0FETUlOJywgdHJ1ZSApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kCgoJCS8vIFNldCBhIGZha2UgZW50cnkgcG9pbnQgdG8gZW5zdXJlIHdwLWluY2x1ZGVzL3ZhcnMucGhwIGRvZXMgbm90IHRocm93CgkJLy8gbm90aWNlcy9lcnJvcnMuIFRoaXMgd2lsbCBiZSByZWZsZWN0ZWQgaW4gdGhlIGdsb2JhbCBgJHBhZ2Vub3dgCgkJLy8gdmFyaWFibGUgYmVpbmcgc2V0IHRvICd3cC1jbGktZmFrZS1hZG1pbi1maWxlLnBocCcuCgkJJF9TRVJWRVJbJ1BIUF9TRUxGJ10gPSAnL3dwLWFkbWluL3dwLWNsaS1mYWtlLWFkbWluLWZpbGUucGhwJzsKCgkJLy8gQm9vdHN0cmFwIHRoZSBXb3JkUHJlc3MgYWRtaW5pc3RyYXRpb24gYXJlYS4KCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknYWRtaW5faW5pdCcsCgkJCWZ1bmN0aW9uICgpIHsKCQkJCWdsb2JhbCAkd3BfZGJfdmVyc2lvbiwgJF93cF9zdWJtZW51X25vcHJpdjsKCgkJCQkvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgdHJpZ2dlciBhIERCIHVwZ3JhZGUgYXMgdGhhdCB0cmllcyB0byByZWRpcmVjdAoJCQkJLy8gdGhlIHBhZ2UuCgkJCQkkd3BfZGJfdmVyc2lvbiA9IChpbnQpIGdldF9vcHRpb24oICdkYl92ZXJzaW9uJyApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQKCgkJCQkvLyBFbnN1cmUgV1AgZG9lcyBub3QgaXRlcmF0ZSBvdmVyIGFuIHVuZGVmaW5lZCB2YXJpYWJsZSBpbgoJCQkJLy8gYHVzZXJfY2FuX2FjY2Vzc19hZG1pbl9wYWdlKClgLgoJCQkJaWYgKCAhIGlzc2V0KCAkX3dwX3N1Ym1lbnVfbm9wcml2ICkgKSB7CgkJCQkJJF93cF9zdWJtZW51X25vcHJpdiA9IFtdOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQKCQkJCX0KCgkJCQkkdGhpcy0+bG9nX2luX2FzX2FkbWluX3VzZXIoKTsKCgkJCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9hZG1pbi5waHAnOwoJCQl9LAoJCQkwCgkJKTsKCX0KCgkvKioKCSAqIEVuc3VyZSB0aGUgY3VycmVudCByZXF1ZXN0IGlzIGRvbmUgdW5kZXIgYSBsb2dnZWQtaW4gYWRtaW5pc3RyYXRvcgoJICogYWNjb3VudC4KCSAqCgkgKiBBIGxvdCBvZiBwcmVtaXVtIHBsdWdpbnMvdGhlbWVzIGhhdmUgdGhlaXIgY3VzdG9tIHVwZGF0ZSByb3V0aW5lcyBsb2NrZWQKCSAqIGJlaGluZCBhbiBpc19hZG1pbigpIGNhbGwuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gbG9nX2luX2FzX2FkbWluX3VzZXIoKSB7CgkJLy8gVE9ETzogQWRkIGxvZ2ljIHRvIGZpbmQgYW4gYWRtaW5pc3RyYXRvciB1c2VyLgoJCSRhZG1pbl91c2VyX2lkID0gMTsKCgkJd3Bfc2V0X2N1cnJlbnRfdXNlciggJGFkbWluX3VzZXJfaWQgKTsKCgkJJGV4cGlyYXRpb24gPSB0aW1lKCkgKyBEQVlfSU5fU0VDT05EUzsKCQkkbWFuYWdlciAgICA9IFdQX1Nlc3Npb25fVG9rZW5zOjpnZXRfaW5zdGFuY2UoICRhZG1pbl91c2VyX2lkICk7CgkJJHRva2VuICAgICAgPSAkbWFuYWdlci0+Y3JlYXRlKCAkZXhwaXJhdGlvbiApOwoKCQkkX0NPT0tJRVsgQVVUSF9DT09LSUUgXSA9IHdwX2dlbmVyYXRlX2F1dGhfY29va2llKAoJCQkkYWRtaW5fdXNlcl9pZCwKCQkJJGV4cGlyYXRpb24sCgkJCSdhdXRoJywKCQkJJHRva2VuCgkJKTsKCgkJJF9DT09LSUVbIFNFQ1VSRV9BVVRIX0NPT0tJRSBdID0gd3BfZ2VuZXJhdGVfYXV0aF9jb29raWUoCgkJCSRhZG1pbl91c2VyX2lkLAoJCQkkZXhwaXJhdGlvbiwKCQkJJ3NlY3VyZV9hdXRoJywKCQkJJHRva2VuCgkJKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxDb250ZXh0OwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxDb250ZXh0OwoKLyoqCiAqIERlZmF1bHQgV1AtQ0xJIGNvbnRleHQuCiAqLwpmaW5hbCBjbGFzcyBDbGkgaW1wbGVtZW50cyBDb250ZXh0IHsKCgkvKioKCSAqIFByb2Nlc3MgdGhlIGNvbnRleHQgdG8gc2V0IHVwIHRoZSBlbnZpcm9ubWVudCBjb3JyZWN0bHkuCgkgKgoJICogQHBhcmFtIGFycmF5ICRjb25maWcgQXNzb2NpYXRpdmUgYXJyYXkgb2YgY29uZmlndXJhdGlvbiBkYXRhLgoJICoKCSAqIEByZXR1cm4gdm9pZAoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggJGNvbmZpZyApIHsKCQkvLyBOb3RoaW5nIG5lZWRzIHRvIGJlIGRvbmUgZm9yIG5vdywgYXMgdGhpcyBpcyB0aGUgZGVmYXVsdC4KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxDb250ZXh0OwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxDb250ZXh0Owp1c2UgV1BfQ0xJXENvbnRleHRNYW5hZ2VyOwoKLyoqCiAqIENvbnRleHQgd2hpY2ggc3dpdGNoZXMgdG8gb3RoZXIgY29udGV4dHMgYXV0b21hdGljYWxseSBiYXNlZCBvbiBjb25kaXRpb25zLgogKi8KZmluYWwgY2xhc3MgQXV0byBpbXBsZW1lbnRzIENvbnRleHQgewoKCS8qKgoJICogQXJyYXkgb2YgY29tbWFuZHMgdG8gaW50ZXJjZXB0LgoJICoKCSAqIEB2YXIgYXJyYXk8YXJyYXk+CgkgKi8KCWNvbnN0IENPTU1BTkRTX1RPX1JVTl9BU19BRE1JTiA9IFsKCQlbICdwbHVnaW4nIF0sCgkJWyAndGhlbWUnIF0sCgldOwoKCS8qKgoJICogQ29udGV4dCBtYW5hZ2VyIGluc3RhbmNlIHRvIHVzZS4KCSAqCgkgKiBAdmFyIENvbnRleHRNYW5hZ2VyCgkgKi8KCXByaXZhdGUgJGNvbnRleHRfbWFuYWdlcjsKCgkvKioKCSAqIEluc3RhbnRpYXRlIGFuIEF1dG8gb2JqZWN0LgoJICoKCSAqIEBwYXJhbSBDb250ZXh0TWFuYWdlciAkY29udGV4dF9tYW5hZ2VyIENvbnRleHQgbWFuYWdlciBpbnN0YW5jZSB0byB1c2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggQ29udGV4dE1hbmFnZXIgJGNvbnRleHRfbWFuYWdlciApIHsKCQkkdGhpcy0+Y29udGV4dF9tYW5hZ2VyID0gJGNvbnRleHRfbWFuYWdlcjsKCX0KCgkvKioKCSAqIFByb2Nlc3MgdGhlIGNvbnRleHQgdG8gc2V0IHVwIHRoZSBlbnZpcm9ubWVudCBjb3JyZWN0bHkuCgkgKgoJICogQHBhcmFtIGFycmF5ICRjb25maWcgQXNzb2NpYXRpdmUgYXJyYXkgb2YgY29uZmlndXJhdGlvbiBkYXRhLgoJICogQHJldHVybiB2b2lkCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uIElmIGFuIGludmFsaWQgY29udGV4dCB3YXMgZGVkdWNlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoICRjb25maWcgKSB7CgkJJGNvbmZpZ1snY29udGV4dCddID0gJHRoaXMtPmRlZHVjZV9iZXN0X2NvbnRleHQoKTsKCgkJJHRoaXMtPmNvbnRleHRfbWFuYWdlci0+c3dpdGNoX2NvbnRleHQoICRjb25maWcgKTsKCX0KCgkvKioKCSAqIERlZHVjZSB0aGUgYmVzdCBjb250ZXh0IHRvIHJ1biB0aGUgY3VycmVudCBjb21tYW5kIGluLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIENvbnRleHQgdG8gdXNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGRlZHVjZV9iZXN0X2NvbnRleHQoKSB7CgkJaWYgKCAkdGhpcy0+aXNfY29tbWFuZF90b19ydW5fYXNfYWRtaW4oKSApIHsKCQkJcmV0dXJuIENvbnRleHQ6OkFETUlOOwoJCX0KCgkJcmV0dXJuIENvbnRleHQ6OkNMSTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgdGhlIGN1cnJlbnQgV1AtQ0xJIGNvbW1hbmQgaXMgYW1vbmdzdCB0aG9zZSB3ZSB3YW50IHRvCgkgKiBydW4gYXMgYWRtaW4uCgkgKgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGN1cnJlbnQgY29tbWFuZCBzaG91bGQgYmUgcnVuIGFzIGFkbWluLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX2NvbW1hbmRfdG9fcnVuX2FzX2FkbWluKCkgewoJCSRjb21tYW5kID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmFyZ3VtZW50czsKCgkJZm9yZWFjaCAoIHNlbGY6OkNPTU1BTkRTX1RPX1JVTl9BU19BRE1JTiBhcyAkY29tbWFuZF90b19ydW5fYXNfYWRtaW4gKSB7CgkJCWlmICgKCQkJCWFycmF5X3NsaWNlKCAkY29tbWFuZCwgMCwgY291bnQoICRjb21tYW5kX3RvX3J1bl9hc19hZG1pbiApICkKCQkJCT09PQoJCQkJJGNvbW1hbmRfdG9fcnVuX2FzX2FkbWluCgkJCSkgewoJCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCQknRGV0ZWN0ZWQgYSBjb21tYW5kIHRvIGJlIGludGVyY2VwdGVkOiAnCgkJCQkJLiBpbXBsb2RlKCAnICcsICRjb21tYW5kICksCgkJCQkJQ29udGV4dDo6REVCVUdfR1JPVVAKCQkJCSk7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKLyoqCiAqIENvbnRleHQgdGhhdCBjYW4gYmUgc2VsZWN0ZWQgaW4gb3JkZXIgdG8gcnVuIGNvbW1hbmRzIHdpdGhpbiBhIHByb3Blcmx5CiAqIHNldC11cCBlbnZpcm9ubWVudC4KICovCmludGVyZmFjZSBDb250ZXh0IHsKCgljb25zdCBBRE1JTiAgICA9ICdhZG1pbic7Cgljb25zdCBBVVRPICAgICA9ICdhdXRvJzsKCWNvbnN0IENMSSAgICAgID0gJ2NsaSc7Cgljb25zdCBGUk9OVEVORCA9ICdmcm9udGVuZCc7CgoJLyoqCgkgKiBEZWJ1Z2dpbmcgZ3JvdXAgdG8gdXNlIGZvciBhbGwgY29udGV4dC1yZWxhdGVkIGRlYnVnIG1lc3NhZ2VzLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IERFQlVHX0dST1VQID0gJ2NvbnRleHQnOwoKCS8qKgoJICogUHJvY2VzcyB0aGUgY29udGV4dCB0byBzZXQgdXAgdGhlIGVudmlyb25tZW50IGNvcnJlY3RseS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGNvbmZpZyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBjb25maWd1cmF0aW9uIGRhdGEuCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoICRjb25maWcgKTsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBjbGlcQ29sb3JzOwp1c2UgY2xpXFRhYmxlOwp1c2UgSXRlcmF0b3I7CnVzZSBNdXN0YW5nb3N0YW5nXFNweWM7CnVzZSBXUF9DTEk7CgovKioKICogT3V0cHV0IG9uZSBvciBtb3JlIGl0ZW1zIGluIGEgZ2l2ZW4gZm9ybWF0IChlLmcuIHRhYmxlLCBKU09OKS4KICovCmNsYXNzIEZvcm1hdHRlciB7CgoJLyoqCgkgKiBIb3cgdGhlIGl0ZW1zIHNob3VsZCBiZSBvdXRwdXQuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRhcmdzOwoKCS8qKgoJICogU3RhbmRhcmQgcHJlZml4IGZvciBvYmplY3QgZmllbGRzLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByaXZhdGUgJHByZWZpeDsKCgkvKioKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBPdXRwdXQgZm9ybWF0IGFyZ3VtZW50cy4KCSAqIEBwYXJhbSBhcnJheSAkZmllbGRzIEZpZWxkcyB0byBkaXNwbGF5IG9mIGVhY2ggaXRlbS4KCSAqIEBwYXJhbSBzdHJpbmd8Ym9vbCAkcHJlZml4IENoZWNrIGlmIGZpZWxkcyBoYXZlIGEgc3RhbmRhcmQgcHJlZml4LgoJICogRmFsc2UgaW5kaWNhdGVzIGVtcHR5IHByZWZpeC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAmJGFzc29jX2FyZ3MsICRmaWVsZHMgPSBudWxsLCAkcHJlZml4ID0gZmFsc2UgKSB7CgkJJGZvcm1hdF9hcmdzID0gWwoJCQknZm9ybWF0JyA9PiAndGFibGUnLAoJCQknZmllbGRzJyA9PiAkZmllbGRzLAoJCQknZmllbGQnICA9PiBudWxsLAoJCV07CgoJCWZvcmVhY2ggKCBbICdmb3JtYXQnLCAnZmllbGRzJywgJ2ZpZWxkJyBdIGFzICRrZXkgKSB7CgkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAka2V5IF0gKSApIHsKCQkJCSRmb3JtYXRfYXJnc1sgJGtleSBdID0gJGFzc29jX2FyZ3NbICRrZXkgXTsKCQkJCXVuc2V0KCAkYXNzb2NfYXJnc1sgJGtleSBdICk7CgkJCX0KCQl9CgoJCWlmICggISBpc19hcnJheSggJGZvcm1hdF9hcmdzWydmaWVsZHMnXSApICkgewoJCQkkZm9ybWF0X2FyZ3NbJ2ZpZWxkcyddID0gZXhwbG9kZSggJywnLCAkZm9ybWF0X2FyZ3NbJ2ZpZWxkcyddICk7CgkJfQoKCQkkZm9ybWF0X2FyZ3NbJ2ZpZWxkcyddID0gYXJyYXlfbWFwKCAndHJpbScsICRmb3JtYXRfYXJnc1snZmllbGRzJ10gKTsKCgkJJHRoaXMtPmFyZ3MgICA9ICRmb3JtYXRfYXJnczsKCQkkdGhpcy0+cHJlZml4ID0gJHByZWZpeDsKCX0KCgkvKioKCSAqIE1hZ2ljIGdldHRlciBmb3IgYXJndW1lbnRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleQoJICogQHJldHVybiBtaXhlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19nZXQoICRrZXkgKSB7CgkJcmV0dXJuICR0aGlzLT5hcmdzWyAka2V5IF07Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IG11bHRpcGxlIGl0ZW1zIGFjY29yZGluZyB0byB0aGUgb3V0cHV0IGFyZ3VtZW50cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXl8SXRlcmF0b3IgJGl0ZW1zIFRoZSBpdGVtcyB0byBkaXNwbGF5LgoJICogQHBhcmFtIGJvb2x8YXJyYXkgICAgICAkYXNjaWlfcHJlX2NvbG9yaXplZCBPcHRpb25hbC4gQSBib29sZWFuIG9yIGFuIGFycmF5IG9mIGJvb2xlYW5zIHRvIHBhc3MgdG8gYGZvcm1hdCgpYCBpZiBpdGVtcyBpbiB0aGUgdGFibGUgYXJlIHByZS1jb2xvcml6ZWQuIERlZmF1bHQgZmFsc2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5X2l0ZW1zKCAkaXRlbXMsICRhc2NpaV9wcmVfY29sb3JpemVkID0gZmFsc2UgKSB7CgkJaWYgKCAkdGhpcy0+YXJnc1snZmllbGQnXSApIHsKCQkJJHRoaXMtPnNob3dfc2luZ2xlX2ZpZWxkKCAkaXRlbXMsICR0aGlzLT5hcmdzWydmaWVsZCddICk7CgkJfSBlbHNlIHsKCQkJaWYgKCBpbl9hcnJheSggJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddLCBbICdjc3YnLCAnanNvbicsICd0YWJsZScgXSwgdHJ1ZSApICkgewoJCQkJJGl0ZW0gPSBpc19hcnJheSggJGl0ZW1zICkgJiYgISBlbXB0eSggJGl0ZW1zICkgPyBhcnJheV9zaGlmdCggJGl0ZW1zICkgOiBmYWxzZTsKCQkJCWlmICggJGl0ZW0gJiYgISBlbXB0eSggJHRoaXMtPmFyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCQkJZm9yZWFjaCAoICR0aGlzLT5hcmdzWydmaWVsZHMnXSBhcyAmJGZpZWxkICkgewoJCQkJCQkkZmllbGQgPSAkdGhpcy0+ZmluZF9pdGVtX2tleSggJGl0ZW0sICRmaWVsZCApOwoJCQkJCX0KCQkJCQlhcnJheV91bnNoaWZ0KCAkaXRlbXMsICRpdGVtICk7CgkJCQl9CgkJCX0KCgkJCWlmICggaW5fYXJyYXkoICR0aGlzLT5hcmdzWydmb3JtYXQnXSwgWyAndGFibGUnLCAnY3N2JyBdLCB0cnVlICkgKSB7CgkJCQlpZiAoICRpdGVtcyBpbnN0YW5jZW9mIEl0ZXJhdG9yICkgewoJCQkJCSRpdGVtcyA9IFV0aWxzXGl0ZXJhdG9yX21hcCggJGl0ZW1zLCBbICR0aGlzLCAndHJhbnNmb3JtX2l0ZW1fdmFsdWVzX3RvX2pzb24nIF0gKTsKCQkJCX0gZWxzZSB7CgkJCQkJJGl0ZW1zID0gYXJyYXlfbWFwKCBbICR0aGlzLCAndHJhbnNmb3JtX2l0ZW1fdmFsdWVzX3RvX2pzb24nIF0sICRpdGVtcyApOwoJCQkJfQoJCQl9CgoJCQkkdGhpcy0+Zm9ybWF0KCAkaXRlbXMsICRhc2NpaV9wcmVfY29sb3JpemVkICk7CgkJfQoJfQoKCS8qKgoJICogRGlzcGxheSBhIHNpbmdsZSBpdGVtIGFjY29yZGluZyB0byB0aGUgb3V0cHV0IGFyZ3VtZW50cy4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgICAgICAkaXRlbQoJICogQHBhcmFtIGJvb2x8YXJyYXkgJGFzY2lpX3ByZV9jb2xvcml6ZWQgT3B0aW9uYWwuIEEgYm9vbGVhbiBvciBhbiBhcnJheSBvZiBib29sZWFucyB0byBwYXNzIHRvIGBzaG93X211bHRpcGxlX2ZpZWxkcygpYCBpZiB0aGUgaXRlbSBpbiB0aGUgdGFibGUgaXMgcHJlLWNvbG9yaXplZC4gRGVmYXVsdCBmYWxzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BsYXlfaXRlbSggJGl0ZW0sICRhc2NpaV9wcmVfY29sb3JpemVkID0gZmFsc2UgKSB7CgkJaWYgKCBpc3NldCggJHRoaXMtPmFyZ3NbJ2ZpZWxkJ10gKSApIHsKCQkJJGl0ZW0gID0gKG9iamVjdCkgJGl0ZW07CgkJCSRrZXkgICA9ICR0aGlzLT5maW5kX2l0ZW1fa2V5KCAkaXRlbSwgJHRoaXMtPmFyZ3NbJ2ZpZWxkJ10gKTsKCQkJJHZhbHVlID0gJGl0ZW0tPiRrZXk7CgkJCWlmICggaW5fYXJyYXkoICR0aGlzLT5hcmdzWydmb3JtYXQnXSwgWyAndGFibGUnLCAnY3N2JyBdLCB0cnVlICkgJiYgKCBpc19vYmplY3QoICR2YWx1ZSApIHx8IGlzX2FycmF5KCAkdmFsdWUgKSApICkgewoJCQkJJHZhbHVlID0ganNvbl9lbmNvZGUoICR2YWx1ZSApOwoJCQl9CgkJCVdQX0NMSTo6cHJpbnRfdmFsdWUoCgkJCQkkdmFsdWUsCgkJCQlbCgkJCQkJJ2Zvcm1hdCcgPT4gJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddLAoJCQkJXQoJCQkpOwoJCX0gZWxzZSB7CgkJCSR0aGlzLT5zaG93X211bHRpcGxlX2ZpZWxkcyggJGl0ZW0sICR0aGlzLT5hcmdzWydmb3JtYXQnXSwgJGFzY2lpX3ByZV9jb2xvcml6ZWQgKTsKCQl9Cgl9CgoJLyoqCgkgKiBGb3JtYXQgaXRlbXMgYWNjb3JkaW5nIHRvIGFyZ3VtZW50cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICAgICAkaXRlbXMKCSAqIEBwYXJhbSBib29sfGFycmF5ICRhc2NpaV9wcmVfY29sb3JpemVkIE9wdGlvbmFsLiBBIGJvb2xlYW4gb3IgYW4gYXJyYXkgb2YgYm9vbGVhbnMgdG8gcGFzcyB0byBgc2hvd190YWJsZSgpYCBpZiBpdGVtcyBpbiB0aGUgdGFibGUgYXJlIHByZS1jb2xvcml6ZWQuIERlZmF1bHQgZmFsc2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZm9ybWF0KCAkaXRlbXMsICRhc2NpaV9wcmVfY29sb3JpemVkID0gZmFsc2UgKSB7CgkJJGZpZWxkcyA9ICR0aGlzLT5hcmdzWydmaWVsZHMnXTsKCgkJc3dpdGNoICggJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddICkgewoJCQljYXNlICdjb3VudCc6CgkJCQlpZiAoICEgaXNfYXJyYXkoICRpdGVtcyApICkgewoJCQkJCSRpdGVtcyA9IGl0ZXJhdG9yX3RvX2FycmF5KCAkaXRlbXMgKTsKCQkJCX0KCQkJCWVjaG8gY291bnQoICRpdGVtcyApOwoJCQkJYnJlYWs7CgoJCQljYXNlICdpZHMnOgoJCQkJaWYgKCAhIGlzX2FycmF5KCAkaXRlbXMgKSApIHsKCQkJCQkkaXRlbXMgPSBpdGVyYXRvcl90b19hcnJheSggJGl0ZW1zICk7CgkJCQl9CgkJCQllY2hvIGltcGxvZGUoICcgJywgJGl0ZW1zICk7CgkJCQlicmVhazsKCgkJCWNhc2UgJ3RhYmxlJzoKCQkJCXNlbGY6OnNob3dfdGFibGUoICRpdGVtcywgJGZpZWxkcywgJGFzY2lpX3ByZV9jb2xvcml6ZWQgKTsKCQkJCWJyZWFrOwoKCQkJY2FzZSAnY3N2JzoKCQkJCVV0aWxzXHdyaXRlX2NzdiggU1RET1VULCAkaXRlbXMsICRmaWVsZHMgKTsKCQkJCWJyZWFrOwoKCQkJY2FzZSAnanNvbic6CgkJCWNhc2UgJ3lhbWwnOgoJCQkJJG91dCA9IFtdOwoJCQkJZm9yZWFjaCAoICRpdGVtcyBhcyAkaXRlbSApIHsKCQkJCQkkb3V0W10gPSBVdGlsc1xwaWNrX2ZpZWxkcyggJGl0ZW0sICRmaWVsZHMgKTsKCQkJCX0KCgkJCQlpZiAoICdqc29uJyA9PT0gJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddICkgewoJCQkJCWlmICggZGVmaW5lZCggJ0pTT05fUEFSVElBTF9PVVRQVVRfT05fRVJST1InICkgKSB7CgkJCQkJCS8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5LkNvbnN0YW50cy5OZXdDb25zdGFudHMuanNvbl9wYXJ0aWFsX291dHB1dF9vbl9lcnJvckZvdW5kCgkJCQkJCWVjaG8ganNvbl9lbmNvZGUoICRvdXQsIEpTT05fUEFSVElBTF9PVVRQVVRfT05fRVJST1IgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQllY2hvIGpzb25fZW5jb2RlKCAkb3V0ICk7CgkJCQkJfQoJCQkJfSBlbHNlaWYgKCAneWFtbCcgPT09ICR0aGlzLT5hcmdzWydmb3JtYXQnXSApIHsKCQkJCQllY2hvIFNweWM6OllBTUxEdW1wKCAkb3V0LCAyLCAwICk7CgkJCQl9CgkJCQlicmVhazsKCgkJCWRlZmF1bHQ6CgkJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBmb3JtYXQ6ICcgLiAkdGhpcy0+YXJnc1snZm9ybWF0J10gKTsKCQl9Cgl9CgoJLyoqCgkgKiBTaG93IGEgc2luZ2xlIGZpZWxkIGZyb20gYSBsaXN0IG9mIGl0ZW1zLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkaXRlbXMgQXJyYXkgb2Ygb2JqZWN0cyB0byBzaG93IGZpZWxkcyBmcm9tCgkgKiBAcGFyYW0gc3RyaW5nICRmaWVsZCBUaGUgZmllbGQgdG8gc2hvdwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHNob3dfc2luZ2xlX2ZpZWxkKCAkaXRlbXMsICRmaWVsZCApIHsKCQkka2V5ICAgID0gbnVsbDsKCQkkdmFsdWVzID0gW107CgoJCWZvcmVhY2ggKCAkaXRlbXMgYXMgJGl0ZW0gKSB7CgkJCSRpdGVtID0gKG9iamVjdCkgJGl0ZW07CgoJCQlpZiAoIG51bGwgPT09ICRrZXkgKSB7CgkJCQkka2V5ID0gJHRoaXMtPmZpbmRfaXRlbV9rZXkoICRpdGVtLCAkZmllbGQgKTsKCQkJfQoKCQkJaWYgKCAnanNvbicgPT09ICR0aGlzLT5hcmdzWydmb3JtYXQnXSApIHsKCQkJCSR2YWx1ZXNbXSA9ICRpdGVtLT4ka2V5OwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpwcmludF92YWx1ZSgKCQkJCQkkaXRlbS0+JGtleSwKCQkJCQlbCgkJCQkJCSdmb3JtYXQnID0+ICR0aGlzLT5hcmdzWydmb3JtYXQnXSwKCQkJCQldCgkJCQkpOwoJCQl9CgkJfQoKCQlpZiAoICdqc29uJyA9PT0gJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddICkgewoJCQllY2hvIGpzb25fZW5jb2RlKCAkdmFsdWVzICk7CgkJfQoJfQoKCS8qKgoJICogRmluZCBhbiBvYmplY3QncyBrZXkuCgkgKiBJZiAkcHJlZml4IGlzIHNldCwgYSBrZXkgd2l0aCB0aGF0IHByZWZpeCB3aWxsIGJlIHByaW9yaXRpemVkLgoJICoKCSAqIEBwYXJhbSBvYmplY3QgJGl0ZW0KCSAqIEBwYXJhbSBzdHJpbmcgJGZpZWxkCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGZpbmRfaXRlbV9rZXkoICRpdGVtLCAkZmllbGQgKSB7CgkJZm9yZWFjaCAoIFsgJGZpZWxkLCAkdGhpcy0+cHJlZml4IC4gJ18nIC4gJGZpZWxkIF0gYXMgJG1heWJlX2tleSApIHsKCQkJaWYgKCAoIGlzX29iamVjdCggJGl0ZW0gKSAmJiAoIHByb3BlcnR5X2V4aXN0cyggJGl0ZW0sICRtYXliZV9rZXkgKSB8fCBpc3NldCggJGl0ZW0tPiRtYXliZV9rZXkgKSApICkgfHwgKCBpc19hcnJheSggJGl0ZW0gKSAmJiBhcnJheV9rZXlfZXhpc3RzKCAkbWF5YmVfa2V5LCAkaXRlbSApICkgKSB7CgkJCQkka2V5ID0gJG1heWJlX2tleTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQlpZiAoICEgaXNzZXQoICRrZXkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgZmllbGQ6ICRmaWVsZC4iICk7CgkJfQoKCQlyZXR1cm4gJGtleTsKCX0KCgkvKioKCSAqIFNob3cgbXVsdGlwbGUgZmllbGRzIG9mIGFuIG9iamVjdC4KCSAqCgkgKiBAcGFyYW0gb2JqZWN0fGFycmF5ICRkYXRhICAgICAgICAgICAgICAgIERhdGEgdG8gZGlzcGxheQoJICogQHBhcmFtIHN0cmluZyAgICAgICAkZm9ybWF0ICAgICAgICAgICAgICBGb3JtYXQgdG8gZGlzcGxheSB0aGUgZGF0YSBpbgoJICogQHBhcmFtIGJvb2x8YXJyYXkgICAkYXNjaWlfcHJlX2NvbG9yaXplZCBPcHRpb25hbC4gQSBib29sZWFuIG9yIGFuIGFycmF5IG9mIGJvb2xlYW5zIHRvIHBhc3MgdG8gYHNob3dfdGFibGUoKWAgaWYgdGhlIGl0ZW0gaW4gdGhlIHRhYmxlIGlzIHByZS1jb2xvcml6ZWQuIERlZmF1bHQgZmFsc2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gc2hvd19tdWx0aXBsZV9maWVsZHMoICRkYXRhLCAkZm9ybWF0LCAkYXNjaWlfcHJlX2NvbG9yaXplZCA9IGZhbHNlICkgewoKCQkkdHJ1ZV9maWVsZHMgPSBbXTsKCQlmb3JlYWNoICggJHRoaXMtPmFyZ3NbJ2ZpZWxkcyddIGFzICRmaWVsZCApIHsKCQkJJHRydWVfZmllbGRzW10gPSAkdGhpcy0+ZmluZF9pdGVtX2tleSggJGRhdGEsICRmaWVsZCApOwoJCX0KCgkJZm9yZWFjaCAoICRkYXRhIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQlpZiAoICEgaW5fYXJyYXkoICRrZXksICR0cnVlX2ZpZWxkcywgdHJ1ZSApICkgewoJCQkJaWYgKCBpc19hcnJheSggJGRhdGEgKSApIHsKCQkJCQl1bnNldCggJGRhdGFbICRrZXkgXSApOwoJCQkJfSBlbHNlaWYgKCBpc19vYmplY3QoICRkYXRhICkgKSB7CgkJCQkJdW5zZXQoICRkYXRhLT4ka2V5ICk7CgkJCQl9CgkJCX0KCQl9CgoJCXN3aXRjaCAoICRmb3JtYXQgKSB7CgoJCQljYXNlICd0YWJsZSc6CgkJCWNhc2UgJ2Nzdic6CgkJCQkkcm93cyAgID0gJHRoaXMtPmFzc29jX2FycmF5X3RvX3Jvd3MoICRkYXRhICk7CgkJCQkkZmllbGRzID0gWyAnRmllbGQnLCAnVmFsdWUnIF07CgkJCQlpZiAoICd0YWJsZScgPT09ICRmb3JtYXQgKSB7CgkJCQkJc2VsZjo6c2hvd190YWJsZSggJHJvd3MsICRmaWVsZHMsICRhc2NpaV9wcmVfY29sb3JpemVkICk7CgkJCQl9IGVsc2VpZiAoICdjc3YnID09PSAkZm9ybWF0ICkgewoJCQkJCVV0aWxzXHdyaXRlX2NzdiggU1RET1VULCAkcm93cywgJGZpZWxkcyApOwoJCQkJfQoJCQkJYnJlYWs7CgoJCQljYXNlICd5YW1sJzoKCQkJY2FzZSAnanNvbic6CgkJCQlXUF9DTEk6OnByaW50X3ZhbHVlKAoJCQkJCSRkYXRhLAoJCQkJCVsKCQkJCQkJJ2Zvcm1hdCcgPT4gJGZvcm1hdCwKCQkJCQldCgkJCQkpOwoJCQkJYnJlYWs7CgoJCQlkZWZhdWx0OgoJCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgZm9ybWF0OiAnIC4gJGZvcm1hdCApOwoJCQkJYnJlYWs7CgoJCX0KCgl9CgoJLyoqCgkgKiBTaG93IGl0ZW1zIGluIGEgXGNsaVxUYWJsZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICAgICAkaXRlbXMKCSAqIEBwYXJhbSBhcnJheSAgICAgICRmaWVsZHMKCSAqIEBwYXJhbSBib29sfGFycmF5ICRhc2NpaV9wcmVfY29sb3JpemVkIE9wdGlvbmFsLiBBIGJvb2xlYW4gb3IgYW4gYXJyYXkgb2YgYm9vbGVhbnMgdG8gcGFzcyB0byBgVGFibGU6OnNldEFzY2lpUHJlQ29sb3JpemVkKClgIGlmIGl0ZW1zIGluIHRoZSB0YWJsZSBhcmUgcHJlLWNvbG9yaXplZC4gRGVmYXVsdCBmYWxzZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc2hvd190YWJsZSggJGl0ZW1zLCAkZmllbGRzLCAkYXNjaWlfcHJlX2NvbG9yaXplZCA9IGZhbHNlICkgewoJCSR0YWJsZSA9IG5ldyBUYWJsZSgpOwoKCQkkZW5hYmxlZCA9IENvbG9yczo6c2hvdWxkQ29sb3JpemUoKTsKCQlpZiAoICRlbmFibGVkICkgewoJCQlDb2xvcnM6OmRpc2FibGUoIHRydWUgKTsKCQl9CgoJCSR0YWJsZS0+c2V0QXNjaWlQcmVDb2xvcml6ZWQoICRhc2NpaV9wcmVfY29sb3JpemVkICk7CgkJJHRhYmxlLT5zZXRIZWFkZXJzKCAkZmllbGRzICk7CgoJCWZvcmVhY2ggKCAkaXRlbXMgYXMgJGl0ZW0gKSB7CgkJCSR0YWJsZS0+YWRkUm93KCBhcnJheV92YWx1ZXMoIFV0aWxzXHBpY2tfZmllbGRzKCAkaXRlbSwgJGZpZWxkcyApICkgKTsKCQl9CgoJCWZvcmVhY2ggKCAkdGFibGUtPmdldERpc3BsYXlMaW5lcygpIGFzICRsaW5lICkgewoJCQlXUF9DTEk6OmxpbmUoICRsaW5lICk7CgkJfQoKCQlpZiAoICRlbmFibGVkICkgewoJCQlDb2xvcnM6OmVuYWJsZSggdHJ1ZSApOwoJCX0KCX0KCgkvKioKCSAqIEZvcm1hdCBhbiBhc3NvY2lhdGl2ZSBhcnJheSBhcyBhIHRhYmxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgICAgJGZpZWxkcyAgICBGaWVsZHMgYW5kIHZhbHVlcyB0byBmb3JtYXQKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBhc3NvY19hcnJheV90b19yb3dzKCAkZmllbGRzICkgewoJCSRyb3dzID0gW107CgoJCWZvcmVhY2ggKCAkZmllbGRzIGFzICRmaWVsZCA9PiAkdmFsdWUgKSB7CgoJCQlpZiAoICEgaXNfc3RyaW5nKCAkdmFsdWUgKSApIHsKCQkJCSR2YWx1ZSA9IGpzb25fZW5jb2RlKCAkdmFsdWUgKTsKCQkJfQoKCQkJJHJvd3NbXSA9IChvYmplY3QpIFsKCQkJCSdGaWVsZCcgPT4gJGZpZWxkLAoJCQkJJ1ZhbHVlJyA9PiAkdmFsdWUsCgkJCV07CgkJfQoKCQlyZXR1cm4gJHJvd3M7Cgl9CgoJLyoqCgkgKiBUcmFuc2Zvcm1zIG9iamVjdHMgYW5kIGFycmF5cyB0byBKU09OIGFzIG5lY2Vzc2FyeQoJICoKCSAqIEBwYXJhbSBtaXhlZCAkaXRlbQoJICogQHJldHVybiBtaXhlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gdHJhbnNmb3JtX2l0ZW1fdmFsdWVzX3RvX2pzb24oICRpdGVtICkgewoJCWZvcmVhY2ggKCAkdGhpcy0+YXJnc1snZmllbGRzJ10gYXMgJGZpZWxkICkgewoJCQkkdHJ1ZV9maWVsZCA9ICR0aGlzLT5maW5kX2l0ZW1fa2V5KCAkaXRlbSwgJGZpZWxkICk7CgkJCSR2YWx1ZSAgICAgID0gaXNfb2JqZWN0KCAkaXRlbSApID8gJGl0ZW0tPiR0cnVlX2ZpZWxkIDogJGl0ZW1bICR0cnVlX2ZpZWxkIF07CgkJCWlmICggaXNfYXJyYXkoICR2YWx1ZSApIHx8IGlzX29iamVjdCggJHZhbHVlICkgKSB7CgkJCQlpZiAoIGlzX29iamVjdCggJGl0ZW0gKSApIHsKCQkJCQkkaXRlbS0+JHRydWVfZmllbGQgPSBqc29uX2VuY29kZSggJHZhbHVlICk7CgkJCQl9IGVsc2VpZiAoIGlzX2FycmF5KCAkaXRlbSApICkgewoJCQkJCSRpdGVtWyAkdHJ1ZV9maWVsZCBdID0ganNvbl9lbmNvZGUoICR2YWx1ZSApOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiAkaXRlbTsKCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfVXBncmFkZXJfU2tpbjsKCi8qKgogKiBBIFVwZ3JhZGVyIFNraW4gZm9yIFdvcmRQcmVzcyB0aGF0IG9ubHkgZ2VuZXJhdGVzIHBsYWluLXRleHQKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBVcGdyYWRlclNraW4gZXh0ZW5kcyBXUF9VcGdyYWRlcl9Ta2luIHsKCgl1c2UgV1BfQ0xJXENvbXBhdFxGZWVkYmFja01ldGhvZFRyYWl0OwoKCXB1YmxpYyAkYXBpOwoKCXB1YmxpYyBmdW5jdGlvbiBoZWFkZXIoKSB7fQoJcHVibGljIGZ1bmN0aW9uIGZvb3RlcigpIHt9CglwdWJsaWMgZnVuY3Rpb24gYnVsa19oZWFkZXIoKSB7fQoJcHVibGljIGZ1bmN0aW9uIGJ1bGtfZm9vdGVyKCkge30KCgkvKioKCSAqIFNob3cgZXJyb3IgbWVzc2FnZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRlcnJvciBFcnJvciBtZXNzYWdlLgoJICoKCSAqIEByZXR1cm4gdm9pZAoJICovCglwdWJsaWMgZnVuY3Rpb24gZXJyb3IoICRlcnJvciApIHsKCQlpZiAoICEgJGVycm9yICkgewoJCQlyZXR1cm47CgkJfQoKCQlpZiAoIGlzX3N0cmluZyggJGVycm9yICkgJiYgaXNzZXQoICR0aGlzLT51cGdyYWRlci0+c3RyaW5nc1sgJGVycm9yIF0gKSApIHsKCQkJJGVycm9yID0gJHRoaXMtPnVwZ3JhZGVyLT5zdHJpbmdzWyAkZXJyb3IgXTsKCQl9CgoJCS8vIFRPRE86IHNob3cgYWxsIGVycm9ycywgbm90IGp1c3QgdGhlIGZpcnN0IG9uZQoJCVdQX0NMSTo6d2FybmluZyggJGVycm9yICk7Cgl9CgoJLyoqCgkgKiBQcm9jZXNzIHRoZSBmZWVkYmFjayBjb2xsZWN0ZWQgdGhyb3VnaCB0aGUgY29tcGF0IGluZGlyZWN0aW9uLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBTdHJpbmcgdG8gdXNlIGFzIGZlZWRiYWNrIG1lc3NhZ2UuCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgQXJyYXkgb2YgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcHJvY2Vzcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3NfZmVlZGJhY2soICRzdHJpbmcsICRhcmdzICkgewoKCQlpZiAoICdwYXJlbnRfdGhlbWVfcHJlcGFyZV9pbnN0YWxsJyA9PT0gJHN0cmluZyApIHsKCQkJV1BfQ0xJOjpnZXRfaHR0cF9jYWNoZV9tYW5hZ2VyKCktPndoaXRlbGlzdF9wYWNrYWdlKCAkdGhpcy0+YXBpLT5kb3dubG9hZF9saW5rLCAndGhlbWUnLCAkdGhpcy0+YXBpLT5zbHVnLCAkdGhpcy0+YXBpLT52ZXJzaW9uICk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkdGhpcy0+dXBncmFkZXItPnN0cmluZ3NbICRzdHJpbmcgXSApICkgewoJCQkkc3RyaW5nID0gJHRoaXMtPnVwZ3JhZGVyLT5zdHJpbmdzWyAkc3RyaW5nIF07CgkJfQoKCQlpZiAoICEgZW1wdHkoICRhcmdzICkgJiYgc3RycG9zKCAkc3RyaW5nLCAnJScgKSAhPT0gZmFsc2UgKSB7CgkJCSRzdHJpbmcgPSB2c3ByaW50ZiggJHN0cmluZywgJGFyZ3MgKTsKCQl9CgoJCWlmICggZW1wdHkoICRzdHJpbmcgKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCAnJiM4MjMwOycsICcuLi4nLCBVdGlsc1xzdHJpcF90YWdzKCAkc3RyaW5nICkgKTsKCQkkc3RyaW5nID0gaHRtbF9lbnRpdHlfZGVjb2RlKCAkc3RyaW5nLCBFTlRfUVVPVEVTLCBnZXRfYmxvZ2luZm8oICdjaGFyc2V0JyApICk7CgoJCVdQX0NMSTo6bG9nKCAkc3RyaW5nICk7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXENvbXBhdFxNaW5fUEhQXzVfNjsKCnRyYWl0IEZlZWRiYWNrTWV0aG9kVHJhaXQgewoKCS8qKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCgkgKiBAcGFyYW0gbWl4ZWQgIC4uLiRhcmdzIE9wdGlvbmFsIHRleHQgcmVwbGFjZW1lbnRzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZmVlZGJhY2soICRzdHJpbmcsIC4uLiRhcmdzICkgeyAvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5MYW5ndWFnZUNvbnN0cnVjdHMuTmV3TGFuZ3VhZ2VDb25zdHJ1Y3RzLnRfZWxsaXBzaXNGb3VuZAoJCSRhcmdzX2FycmF5ID0gW107CgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgkJCSRhcmdzX2FycmF5W10gPSAkYXJnczsKCQl9CgoJCSR0aGlzLT5wcm9jZXNzX2ZlZWRiYWNrKCAkc3RyaW5nLCAkYXJncyApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXENvbXBhdFxNaW5fUEhQXzVfNDsKCnRyYWl0IEZlZWRiYWNrTWV0aG9kVHJhaXQgewoKCS8qKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmZWVkYmFjayggJHN0cmluZyApIHsKCQkkYXJncyA9IGZ1bmNfZ2V0X2FyZ3MoKTsKCQkkYXJncyA9IGFycmF5X3NwbGljZSggJGFyZ3MsIDEgKTsKCgkJJHRoaXMtPnByb2Nlc3NfZmVlZGJhY2soICRzdHJpbmcsICRhcmdzICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29tcGF0OwoKLy8gcGhwY3M6ZGlzYWJsZSBHZW5lcmljLkZpbGVzLk9uZU9iamVjdFN0cnVjdHVyZVBlckZpbGUuTXVsdGlwbGVGb3VuZCxHZW5lcmljLkNsYXNzZXMuRHVwbGljYXRlQ2xhc3NOYW1lLkZvdW5kCgppZiAoIFBIUF9WRVJTSU9OX0lEID49IDUwNjAwICkgewoJcmVxdWlyZV9vbmNlIF9fRElSX18gLiAnL01pbl9QSFBfNV82L0ZlZWRiYWNrTWV0aG9kVHJhaXQucGhwJzsKCgl0cmFpdCBGZWVkYmFja01ldGhvZFRyYWl0IHsKCgkJdXNlIE1pbl9QSFBfNV82XEZlZWRiYWNrTWV0aG9kVHJhaXQ7Cgl9CgoJcmV0dXJuOwp9CgpyZXF1aXJlX29uY2UgX19ESVJfXyAuICcvTWluX1BIUF81XzQvRmVlZGJhY2tNZXRob2RUcmFpdC5waHAnOwoKdHJhaXQgRmVlZGJhY2tNZXRob2RUcmFpdCB7CgoJdXNlIE1pbl9QSFBfNV80XEZlZWRiYWNrTWV0aG9kVHJhaXQ7Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcTG9nZ2VyczsKCnVzZSBXUF9DTEk7CgovKioKICogRXhlY3V0aW9uIGxvZ2dlciBjYXB0dXJlcyBhbGwgU1RET1VUIGFuZCBTVERFUlIgd3JpdGVzCiAqLwpjbGFzcyBFeGVjdXRpb24gZXh0ZW5kcyBSZWd1bGFyIHsKCgkvKioKCSAqIENhcHR1cmVkIHdyaXRlcyB0byBTVERPVVQuCgkgKi8KCXB1YmxpYyAkc3Rkb3V0ID0gJyc7CgoJLyoqCgkgKiBDYXB0dXJlZCB3cml0ZXMgdG8gU1RERVJSLgoJICovCglwdWJsaWMgJHN0ZGVyciA9ICcnOwoKCS8qKgoJICogQHBhcmFtIGJvb2wgJGluX2NvbG9yIFdoZXRoZXIgb3Igbm90IHRvIENvbG9yaXplIHN0cmluZ3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGluX2NvbG9yID0gZmFsc2UgKSB7IC8vIHBocGNzOmlnbm9yZSBHZW5lcmljLkNvZGVBbmFseXNpcy5Vc2VsZXNzT3ZlcnJpZGluZ01ldGhvZC5Gb3VuZCAtLSBQcm92aWRlcyBhIGRlZmF1bHQgdmFsdWUuCgkJcGFyZW50OjpfX2NvbnN0cnVjdCggJGluX2NvbG9yICk7Cgl9CgoJLyoqCgkgKiBTaW1pbGFyIHRvIGVycm9yKCAkbWVzc2FnZSApLCBidXQgb3V0cHV0cyAkbWVzc2FnZSBpbiBhIHJlZCBib3guCgkgKgoJICogQHBhcmFtIGFycmF5ICRtZXNzYWdlX2xpbmVzIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlcnJvcl9tdWx0aV9saW5lKCAkbWVzc2FnZV9saW5lcyApIHsKCQkkbWVzc2FnZSA9IGltcGxvZGUoICJcbiIsICRtZXNzYWdlX2xpbmVzICk7CgoJCSR0aGlzLT53cml0ZSggU1RERVJSLCBXUF9DTEk6OmNvbG9yaXplKCAiJVJFcnJvcjolblxuJG1lc3NhZ2VcbiIgKSApOwoJCSR0aGlzLT53cml0ZSggU1RERVJSLCBXUF9DTEk6OmNvbG9yaXplKCAiJVItLS0tLS0tLS0lblxuXG4iICkgKTsKCX0KCgkvKioKCSAqIFdyaXRlIGEgc3RyaW5nIHRvIGEgcmVzb3VyY2UuCgkgKgoJICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUgQ29tbW9ubHkgU1RET1VUIG9yIFNUREVSUi4KCSAqIEBwYXJhbSBzdHJpbmcgJHN0ciBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoICRoYW5kbGUsICRzdHIgKSB7CgkJc3dpdGNoICggJGhhbmRsZSApIHsKCQkJY2FzZSBTVERPVVQ6CgkJCQkkdGhpcy0+c3Rkb3V0IC49ICRzdHI7CgkJCQlicmVhazsKCQkJY2FzZSBTVERFUlI6CgkJCQkkdGhpcy0+c3RkZXJyIC49ICRzdHI7CgkJCQlicmVhazsKCQl9Cgl9CgoJLyoqCgkgKiBTdGFydHMgb3V0cHV0IGJ1ZmZlcmluZywgdXNpbmcgYSBjYWxsYmFjayB0byBjYXB0dXJlIG91dHB1dCBmcm9tIGBlY2hvYCwgYHByaW50YCwgYHByaW50ZmAgKHdoaWNoIHdyaXRlIHRvIHRoZSBvdXRwdXQgYnVmZmVyICdwaHA6Ly9vdXRwdXQnIHJhdGhlciB0aGFuIFNURE9VVCkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvYl9zdGFydCgpIHsKCQlvYl9zdGFydCggWyAkdGhpcywgJ29iX3N0YXJ0X2NhbGxiYWNrJyBdLCAxICk7Cgl9CgoJLyoqCgkgKiBDYWxsYmFjayBmb3IgYG9iX3N0YXJ0KClgLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0ciBTdHJpbmcgdG8gd3JpdGUuCgkgKiBAcmV0dXJuIHN0cmluZyBSZXR1cm5zIHplcm8tbGVuZ3RoIHN0cmluZyBzbyBub3RoaW5nIGdldHMgd3JpdHRlbiB0byB0aGUgb3V0cHV0IGJ1ZmZlci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9iX3N0YXJ0X2NhbGxiYWNrKCAkc3RyICkgewoJCSR0aGlzLT53cml0ZSggU1RET1VULCAkc3RyICk7CgkJcmV0dXJuICcnOwoJfQoKCS8qKgoJICogVG8gbWF0Y2ggYG9iX3N0YXJ0KCkgYWJvdmUuIERvZXMgYW4gYG9iX2VuZF9mbHVzaCgpYC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9iX2VuZCgpIHsKCQlvYl9lbmRfZmx1c2goKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxMb2dnZXJzOwoKdXNlIGNsaVxDb2xvcnM7CgovKioKICogRGVmYXVsdCBsb2dnZXIgZm9yIHN1Y2Nlc3MsIHdhcm5pbmcsIGVycm9yLCBhbmQgc3RhbmRhcmQgbWVzc2FnZXMuCiAqLwpjbGFzcyBSZWd1bGFyIGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBAcGFyYW0gYm9vbCAkaW5fY29sb3IgV2hldGhlciBvciBub3QgdG8gQ29sb3JpemUgc3RyaW5ncy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkaW5fY29sb3IgKSB7CgkJJHRoaXMtPmluX2NvbG9yID0gJGluX2NvbG9yOwoJfQoKCS8qKgoJICogV3JpdGUgYW4gaW5mb3JtYXRpb25hbCBtZXNzYWdlIHRvIFNURE9VVC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbmZvKCAkbWVzc2FnZSApIHsKCQkkdGhpcy0+d3JpdGUoIFNURE9VVCwgJG1lc3NhZ2UgLiAiXG4iICk7Cgl9CgoJLyoqCgkgKiBXcml0ZSBhIHN1Y2Nlc3MgbWVzc2FnZSwgcHJlZml4ZWQgd2l0aCAiU3VjY2VzczogIi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdWNjZXNzKCAkbWVzc2FnZSApIHsKCQkkdGhpcy0+X2xpbmUoICRtZXNzYWdlLCAnU3VjY2VzcycsICclRycgKTsKCX0KCgkvKioKCSAqIFdyaXRlIGEgd2FybmluZyBtZXNzYWdlIHRvIFNUREVSUiwgcHJlZml4ZWQgd2l0aCAiV2FybmluZzogIi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB3YXJuaW5nKCAkbWVzc2FnZSApIHsKCQkkdGhpcy0+X2xpbmUoICRtZXNzYWdlLCAnV2FybmluZycsICclQycsIFNUREVSUiApOwoJfQoKCS8qKgoJICogV3JpdGUgYW4gbWVzc2FnZSB0byBTVERFUlIsIHByZWZpeGVkIHdpdGggIkVycm9yOiAiLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgTWVzc2FnZSB0byB3cml0ZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVycm9yKCAkbWVzc2FnZSApIHsKCQkkdGhpcy0+X2xpbmUoICRtZXNzYWdlLCAnRXJyb3InLCAnJVInLCBTVERFUlIgKTsKCX0KCgkvKioKCSAqIFNpbWlsYXIgdG8gZXJyb3IoICRtZXNzYWdlICksIGJ1dCBvdXRwdXRzICRtZXNzYWdlIGluIGEgcmVkIGJveC4KCSAqCgkgKiBAcGFyYW0gIGFycmF5ICRtZXNzYWdlX2xpbmVzIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlcnJvcl9tdWx0aV9saW5lKCAkbWVzc2FnZV9saW5lcyApIHsKCQkvLyBDb252ZXJ0IHRhYnMgdG8gZm91ciBzcGFjZXMsIGFzIHNvbWUgc2hlbGxzIHdpbGwgb3V0cHV0IHRoZSB0YWJzIGFzIHZhcmlhYmxlLWxlbmd0aC4KCQkkbWVzc2FnZV9saW5lcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRsaW5lICkgewoJCQkJcmV0dXJuIHN0cl9yZXBsYWNlKCAiXHQiLCAnICAgICcsICRsaW5lICk7CgkJCX0sCgkJCSRtZXNzYWdlX2xpbmVzCgkJKTsKCgkJJGxvbmdlc3QgPSBtYXgoIGFycmF5X21hcCggJ3N0cmxlbicsICRtZXNzYWdlX2xpbmVzICkgKTsKCgkJLy8gV3JpdGUgYW4gZW1wdHkgbGluZSBiZWZvcmUgdGhlIG1lc3NhZ2UuCgkJJGVtcHR5X2xpbmUgPSBDb2xvcnM6OmNvbG9yaXplKCAnJXclMSAnIC4gc3RyX3JlcGVhdCggJyAnLCAkbG9uZ2VzdCApIC4gJyAlbicgKTsKCQkkdGhpcy0+d3JpdGUoIFNUREVSUiwgIlxuXHQkZW1wdHlfbGluZVxuIiApOwoKCQlmb3JlYWNoICggJG1lc3NhZ2VfbGluZXMgYXMgJGxpbmUgKSB7CgkJCSRwYWRkaW5nID0gc3RyX3JlcGVhdCggJyAnLCAkbG9uZ2VzdCAtIHN0cmxlbiggJGxpbmUgKSApOwoJCQkkbGluZSAgICA9IENvbG9yczo6Y29sb3JpemUoICIldyUxICRsaW5lICRwYWRkaW5nJW4iICk7CgkJCSR0aGlzLT53cml0ZSggU1RERVJSLCAiXHQkbGluZVxuIiApOwoJCX0KCgkJLy8gV3JpdGUgYW4gZW1wdHkgbGluZSBhZnRlciB0aGUgbWVzc2FnZS4KCQkkdGhpcy0+d3JpdGUoIFNUREVSUiwgIlx0JGVtcHR5X2xpbmVcblxuIiApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXExvZ2dlcnM7Cgp1c2UgY2xpXENvbG9yczsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxSdW5uZXI7CgovKioKICogQmFzZSBsb2dnZXIgY2xhc3MKICovCmFic3RyYWN0IGNsYXNzIEJhc2UgewoKCXByb3RlY3RlZCAkaW5fY29sb3IgPSBmYWxzZTsKCglhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gaW5mbyggJG1lc3NhZ2UgKTsKCglhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gc3VjY2VzcyggJG1lc3NhZ2UgKTsKCglhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gd2FybmluZyggJG1lc3NhZ2UgKTsKCgkvKioKCSAqIFJldHJpZXZlIHRoZSBydW5uZXIgaW5zdGFuY2UgZnJvbSB0aGUgYmFzZSBDTEkgb2JqZWN0LiBUaGlzIGZhY2lsaXRhdGVzCgkgKiB1bml0IHRlc3RpbmcsIHdoZXJlIHRoZSBXUF9DTEkgaW5zdGFuY2UgaXNuJ3QgYXZhaWxhYmxlCgkgKgoJICogQHJldHVybiBSdW5uZXIgSW5zdGFuY2Ugb2YgdGhlIHJ1bm5lciBjbGFzcwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3J1bm5lcigpIHsKCQlyZXR1cm4gV1BfQ0xJOjpnZXRfcnVubmVyKCk7Cgl9CgoJLyoqCgkgKiBXcml0ZSBhIG1lc3NhZ2UgdG8gU1RERVJSLCBwcmVmaXhlZCB3aXRoICJEZWJ1ZzogIi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKiBAcGFyYW0gc3RyaW5nfGJvb2wgJGdyb3VwIE9yZ2FuaXplIGRlYnVnIG1lc3NhZ2UgdG8gYSBzcGVjaWZpYyBncm91cC4KCSAqIFVzZSBgZmFsc2VgIGZvciBubyBncm91cC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlYnVnKCAkbWVzc2FnZSwgJGdyb3VwID0gZmFsc2UgKSB7CgkJc3RhdGljICRzdGFydF90aW1lID0gbnVsbDsKCQlpZiAoIG51bGwgPT09ICRzdGFydF90aW1lICkgewoJCQkkc3RhcnRfdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApOwoJCX0KCQkkZGVidWcgPSAkdGhpcy0+Z2V0X3J1bm5lcigpLT5jb25maWdbJ2RlYnVnJ107CgkJaWYgKCAhICRkZWJ1ZyApIHsKCQkJcmV0dXJuOwoJCX0KCQlpZiAoIHRydWUgIT09ICRkZWJ1ZyAmJiAkZ3JvdXAgIT09ICRkZWJ1ZyApIHsKCQkJcmV0dXJuOwoJCX0KCQkkdGltZSAgID0gcm91bmQoIG1pY3JvdGltZSggdHJ1ZSApIC0gKCBkZWZpbmVkKCAnV1BfQ0xJX1NUQVJUX01JQ1JPVElNRScgKSA/IFdQX0NMSV9TVEFSVF9NSUNST1RJTUUgOiAkc3RhcnRfdGltZSApLCAzICk7CgkJJHByZWZpeCA9ICdEZWJ1Zyc7CgkJaWYgKCAkZ3JvdXAgJiYgdHJ1ZSA9PT0gJGRlYnVnICkgewoJCQkkcHJlZml4ID0gJ0RlYnVnICgnIC4gJGdyb3VwIC4gJyknOwoJCX0KCQkkdGhpcy0+X2xpbmUoICIkbWVzc2FnZSAoeyR0aW1lfXMpIiwgJHByZWZpeCwgJyVCJywgU1RERVJSICk7Cgl9CgoJLyoqCgkgKiBXcml0ZSBhIHN0cmluZyB0byBhIHJlc291cmNlLgoJICoKCSAqIEBwYXJhbSByZXNvdXJjZSAkaGFuZGxlIENvbW1vbmx5IFNURE9VVCBvciBTVERFUlIuCgkgKiBAcGFyYW0gc3RyaW5nICRzdHIgTWVzc2FnZSB0byB3cml0ZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlKCAkaGFuZGxlLCAkc3RyICkgewoJCWZ3cml0ZSggJGhhbmRsZSwgJHN0ciApOwoJfQoKCS8qKgoJICogT3V0cHV0IG9uZSBsaW5lIG9mIG1lc3NhZ2UgdG8gYSByZXNvdXJjZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKiBAcGFyYW0gc3RyaW5nICRsYWJlbCBQcmVmaXggbWVzc2FnZSB3aXRoIGEgbGFiZWwuCgkgKiBAcGFyYW0gc3RyaW5nICRjb2xvciBDb2xvcml6ZSBsYWJlbCB3aXRoIGEgZ2l2ZW4gY29sb3IuCgkgKiBAcGFyYW0gcmVzb3VyY2UgJGhhbmRsZSBSZXNvdXJjZSB0byB3cml0ZSB0by4gRGVmYXVsdHMgdG8gU1RET1VULgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gX2xpbmUoICRtZXNzYWdlLCAkbGFiZWwsICRjb2xvciwgJGhhbmRsZSA9IFNURE9VVCApIHsgLy8gcGhwY3M6aWdub3JlIFBTUjIuTWV0aG9kcy5NZXRob2REZWNsYXJhdGlvbi5VbmRlcnNjb3JlIC0tIFVzZWQgaW4gdGhpcmQgcGFydHkgZXh0ZW5zaW9ucy4KCQlpZiAoIGNsYXNzX2V4aXN0cyggJ2NsaVxDb2xvcnMnICkgKSB7CgkJCSRsYWJlbCA9IENvbG9yczo6Y29sb3JpemUoICIkY29sb3IkbGFiZWw6JW4iLCAkdGhpcy0+aW5fY29sb3IgKTsKCQl9IGVsc2UgewoJCQkkbGFiZWwgPSAiJGxhYmVsOiI7CgkJfQoJCSR0aGlzLT53cml0ZSggJGhhbmRsZSwgIiRsYWJlbCAkbWVzc2FnZVxuIiApOwoJfQoKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxMb2dnZXJzOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBRdWlldCBsb2dnZXIgb25seSBsb2dzIGVycm9ycy4KICovCmNsYXNzIFF1aWV0IGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBAcGFyYW0gYm9vbCAkaW5fY29sb3IgV2hldGhlciBvciBub3QgdG8gQ29sb3JpemUgc3RyaW5ncy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkaW5fY29sb3IgPSBmYWxzZSApIHsKCQkkdGhpcy0+aW5fY29sb3IgPSAkaW5fY29sb3I7Cgl9CgoJLyoqCgkgKiBJbmZvcm1hdGlvbmFsIG1lc3NhZ2VzIGFyZW4ndCBsb2dnZWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5mbyggJG1lc3NhZ2UgKSB7CgkJLy8gTm90aGluZy4KCX0KCgkvKioKCSAqIFN1Y2Nlc3MgbWVzc2FnZXMgYXJlbid0IGxvZ2dlZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdWNjZXNzKCAkbWVzc2FnZSApIHsKCQkvLyBOb3RoaW5nLgoJfQoKCS8qKgoJICogV2FybmluZyBtZXNzYWdlcyBhcmVuJ3QgbG9nZ2VkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgTWVzc2FnZSB0byB3cml0ZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoICRtZXNzYWdlICkgewoJCS8vIE5vdGhpbmcuCgl9CgoJLyoqCgkgKiBXcml0ZSBhbiBlcnJvciBtZXNzYWdlIHRvIFNUREVSUiwgcHJlZml4ZWQgd2l0aCAiRXJyb3I6ICIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZXJyb3IoICRtZXNzYWdlICkgewoJCSR0aGlzLT5fbGluZSggJG1lc3NhZ2UsICdFcnJvcicsICclUicsIFNUREVSUiApOwoJfQoKCS8qKgoJICogU2ltaWxhciB0byBlcnJvciggJG1lc3NhZ2UgKSwgYnV0IG91dHB1dHMgJG1lc3NhZ2UgaW4gYSByZWQgYm94LgoJICoKCSAqIEBwYXJhbSAgYXJyYXkgJG1lc3NhZ2VfbGluZXMgTWVzc2FnZSB0byB3cml0ZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVycm9yX211bHRpX2xpbmUoICRtZXNzYWdlX2xpbmVzICkgewoJCSRtZXNzYWdlID0gaW1wbG9kZSggIlxuIiwgJG1lc3NhZ2VfbGluZXMgKTsKCgkJJHRoaXMtPl9saW5lKCAkbWVzc2FnZSwgJ0Vycm9yJywgJyVSJywgU1RERVJSICk7CgkJJHRoaXMtPl9saW5lKCAnJywgJy0tLS0tLS0tLScsICclUicsIFNUREVSUiApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDb250ZXh0IG1hbmFnZXIgdG8gcmVnaXN0ZXJfY29udGV4dCBhbmQgcHJvY2VzcyBkaWZmZXJlbnQgY29udGV4dHMgdGhhdCBjb21tYW5kcyBjYW4KICogcnVuIHdpdGhpbi4KICovCmZpbmFsIGNsYXNzIENvbnRleHRNYW5hZ2VyIHsKCgkvKioKCSAqIEFzc29jaWF0aXZlIGFycmF5IG9mIGNvbnRleHQgaW1wbGVtZW50YXRpb25zLgoJICoKCSAqIEB2YXIgYXJyYXk8c3RyaW5nLCBDb250ZXh0PgoJICovCglwcml2YXRlICRjb250ZXh0cyA9IFtdOwoKCS8qKgoJICogU3RvcmUgdGhlIGN1cnJlbnQgY29udGV4dC4KCSAqCgkgKiBAdmFyIHN0cmluZyBDdXJyZW50IGNvbnRleHQuCgkgKi8KCXByaXZhdGUgJGN1cnJlbnRfY29udGV4dCA9IENvbnRleHQ6OkNMSTsKCgkvKioKCSAqIFJlZ2lzdGVyIGEgY29udGV4dCB3aXRoIFdQLUNMSS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkbmFtZSAgICAgICAgICAgTmFtZSBvZiB0aGUgY29udGV4dC4KCSAqIEBwYXJhbSBDb250ZXh0ICRpbXBsZW1lbnRhdGlvbiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29udGV4dC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyX2NvbnRleHQoICRuYW1lLCBDb250ZXh0ICRpbXBsZW1lbnRhdGlvbiApIHsKCQkkdGhpcy0+Y29udGV4dHNbICRuYW1lIF0gPSAkaW1wbGVtZW50YXRpb247Cgl9CgoJLyoqCgkgKiBTd2l0Y2ggdGhlIGNvbnRleHQgaW4gd2hpY2ggdG8gcnVuIFdQLUNMSS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGNvbmZpZyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBjb25maWd1cmF0aW9uIGRhdGEuCgkgKiBAcmV0dXJuIHZvaWQKCSAqCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gV2hlbiBhbiBpbnZhbGlkIGNvbnRleHQgd2FzIHJlcXVlc3RlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHN3aXRjaF9jb250ZXh0KCAkY29uZmlnICkgewoJCSRjb250ZXh0ID0gaXNzZXQoICRjb25maWdbJ2NvbnRleHQnXSApCgkJCT8gJGNvbmZpZ1snY29udGV4dCddCgkJCTogJHRoaXMtPmN1cnJlbnRfY29udGV4dDsKCgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRjb250ZXh0LCAkdGhpcy0+Y29udGV4dHMgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlVua25vd24gY29udGV4dCAneyRjb250ZXh0fSciICk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAiVXNpbmcgY29udGV4dCAneyRjb250ZXh0fSciLCBDb250ZXh0OjpERUJVR19HUk9VUCApOwoKCQkkdGhpcy0+Y3VycmVudF9jb250ZXh0ID0gJGNvbnRleHQ7CgkJJHRoaXMtPmNvbnRleHRzWyAkY29udGV4dCBdLT5wcm9jZXNzKCAkY29uZmlnICk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIGN1cnJlbnQgY29udGV4dC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBDdXJyZW50IGNvbnRleHQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfY29udGV4dCgpIHsKCQlyZXR1cm4gJHRoaXMtPmN1cnJlbnRfY29udGV4dDsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CgovKioKICogTWFuYWdlIGNhY2hpbmcgd2l0aCB3aGl0ZWxpc3RpbmcKICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBXcEh0dHBDYWNoZU1hbmFnZXIgewoKCS8qKgoJICogQHZhciBhcnJheSBtYXAgd2hpdGVsaXN0ZWQgdXJscyB0byBrZXlzIGFuZCB0dGxzCgkgKi8KCXByb3RlY3RlZCAkd2hpdGVsaXN0ID0gW107CgoJLyoqCgkgKiBAdmFyIEZpbGVDYWNoZQoJICovCglwcm90ZWN0ZWQgJGNhY2hlOwoKCS8qKgoJICogQHBhcmFtIEZpbGVDYWNoZSAkY2FjaGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCBGaWxlQ2FjaGUgJGNhY2hlICkgewoJCSR0aGlzLT5jYWNoZSA9ICRjYWNoZTsKCgkJLy8gaG9vayBpbnRvIHdwIGh0dHAgYXBpCgkJYWRkX2ZpbHRlciggJ3ByZV9odHRwX3JlcXVlc3QnLCBbICR0aGlzLCAnZmlsdGVyX3ByZV9odHRwX3JlcXVlc3QnIF0sIDEwLCAzICk7CgkJYWRkX2ZpbHRlciggJ2h0dHBfcmVzcG9uc2UnLCBbICR0aGlzLCAnZmlsdGVyX2h0dHBfcmVzcG9uc2UnIF0sIDEwLCAzICk7Cgl9CgoJLyoqCgkgKiBzaG9ydCBjaXJjdWl0IHdwIGh0dHAgYXBpIHdpdGggY2FjaGVkIGZpbGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbHRlcl9wcmVfaHR0cF9yZXF1ZXN0KCAkcmVzcG9uc2UsICRhcmdzLCAkdXJsICkgewoJCS8vIGNoZWNrIGlmIHdoaXRlbGlzdGVkCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF0gKSApIHsKCQkJcmV0dXJuICRyZXNwb25zZTsKCQl9CgkJLy8gY2hlY2sgaWYgZG93bmxvYWRpbmcKCQlpZiAoICdHRVQnICE9PSAkYXJnc1snbWV0aG9kJ10gfHwgZW1wdHkoICRhcmdzWydmaWxlbmFtZSddICkgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoJCS8vIGNoZWNrIGNhY2hlIGFuZCBleHBvcnQgdG8gZGVzaWduYXRlZCBsb2NhdGlvbgoJCSRmaWxlbmFtZSA9ICR0aGlzLT5jYWNoZS0+aGFzKCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF1bJ2tleSddLCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF1bJ3R0bCddICk7CgkJaWYgKCAkZmlsZW5hbWUgKSB7CgkJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnVXNpbmcgY2FjaGVkIGZpbGUgXCclc1wnLi4uJywgJGZpbGVuYW1lICkgKTsKCQkJaWYgKCBjb3B5KCAkZmlsZW5hbWUsICRhcmdzWydmaWxlbmFtZSddICkgKSB7CgkJCQkvLyBzaW11bGF0ZSBzdWNjZXNzZnVsIGRvd25sb2FkIHJlc3BvbnNlCgkJCQlyZXR1cm4gWwoJCQkJCSdyZXNwb25zZScgPT4gWwoJCQkJCQknY29kZScgICAgPT4gMjAwLAoJCQkJCQknbWVzc2FnZScgPT4gJ09LJywKCQkJCQldLAoJCQkJCSdmaWxlbmFtZScgPT4gJGFyZ3NbJ2ZpbGVuYW1lJ10sCgkJCQldOwoJCQl9CgoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnRXJyb3IgY29weWluZyBjYWNoZWQgZmlsZSAlcyB0byAlcycsICRmaWxlbmFtZSwgJHVybCApICk7CgkJfQoJCXJldHVybiAkcmVzcG9uc2U7Cgl9CgoKCS8qKgoJICogY2FjaGUgd3AgaHR0cCBhcGkgZG93bmxvYWRzCgkgKgoJICogQHBhcmFtIGFycmF5ICRyZXNwb25zZQoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbHRlcl9odHRwX3Jlc3BvbnNlKCAkcmVzcG9uc2UsICRhcmdzLCAkdXJsICkgewoJCS8vIGNoZWNrIGlmIHdoaXRlbGlzdGVkCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF0gKSApIHsKCQkJcmV0dXJuICRyZXNwb25zZTsKCQl9CgkJLy8gY2hlY2sgaWYgZG93bmxvYWRpbmcKCQlpZiAoICdHRVQnICE9PSAkYXJnc1snbWV0aG9kJ10gfHwgZW1wdHkoICRhcmdzWydmaWxlbmFtZSddICkgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoJCS8vIGNoZWNrIGlmIGRvd25sb2FkIHdhcyBzdWNjZXNzZnVsCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkgfHwgMjAwICE9PSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfY29kZSggJHJlc3BvbnNlICkgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoJCS8vIGNhY2hlIGRvd25sb2FkZWQgZmlsZQoJCSR0aGlzLT5jYWNoZS0+aW1wb3J0KCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF1bJ2tleSddLCAkcmVzcG9uc2VbJ2ZpbGVuYW1lJ10gKTsKCQlyZXR1cm4gJHJlc3BvbnNlOwoJfQoKCS8qKgoJICogd2hpdGVsaXN0IGEgcGFja2FnZSB1cmwKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBzdHJpbmcgJGdyb3VwICAgcGFja2FnZSBncm91cCAodGhlbWVzLCBwbHVnaW5zLCAuLi4pCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnICAgIHBhY2thZ2Ugc2x1ZwoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBwYWNrYWdlIHZlcnNpb24KCSAqIEBwYXJhbSBpbnQgICAgJHR0bAoJICovCglwdWJsaWMgZnVuY3Rpb24gd2hpdGVsaXN0X3BhY2thZ2UoICR1cmwsICRncm91cCwgJHNsdWcsICR2ZXJzaW9uLCAkdHRsID0gbnVsbCApIHsKCQkkZXh0ID0gcGF0aGluZm8oIFV0aWxzXHBhcnNlX3VybCggJHVybCwgUEhQX1VSTF9QQVRIICksIFBBVEhJTkZPX0VYVEVOU0lPTiApOwoJCSRrZXkgPSAiJGdyb3VwLyRzbHVnLSR2ZXJzaW9uLiRleHQiOwoJCSR0aGlzLT53aGl0ZWxpc3RfdXJsKCAkdXJsLCAka2V5LCAkdHRsICk7CgkJd3BfdXBkYXRlX3BsdWdpbnMoKTsKCX0KCgkvKioKCSAqIHdoaXRlbGlzdCBhIHVybAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybAoJICogQHBhcmFtIHN0cmluZyAka2V5CgkgKiBAcGFyYW0gaW50ICAgICR0dGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHdoaXRlbGlzdF91cmwoICR1cmwsICRrZXkgPSBudWxsLCAkdHRsID0gbnVsbCApIHsKCQkka2V5ICAgICAgICAgICAgICAgICAgICAgPSAka2V5ID8gOiAkdXJsOwoJCSR0aGlzLT53aGl0ZWxpc3RbICR1cmwgXSA9IGNvbXBhY3QoICdrZXknLCAndHRsJyApOwoJfQoKCS8qKgoJICogY2hlY2sgaWYgdXJsIGlzIHdoaXRlbGlzdGVkCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX3doaXRlbGlzdGVkKCAkdXJsICkgewoJCXJldHVybiBpc3NldCggJHRoaXMtPndoaXRlbGlzdFsgJHVybCBdICk7Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tcG9zaXRlQ29tbWFuZDsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXFN1YmNvbW1hbmQ7CnVzZSBXUF9DTElcRmV0Y2hlcnM7CnVzZSBXUF9DTElcSXRlcmF0b3JzXEV4Y2VwdGlvbjsKdXNlIFdQX0NMSVxMb2dnZXJzOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfRXJyb3I7CgovKioKICogUGVyZm9ybXMgdGhlIGV4ZWN1dGlvbiBvZiBhIGNvbW1hbmQuCiAqCiAqIEBwcm9wZXJ0eS1yZWFkIHN0cmluZyAgICAgICAgICRnbG9iYWxfY29uZmlnX3BhdGgKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICAgICAgICAgJHByb2plY3RfY29uZmlnX3BhdGgKICogQHByb3BlcnR5LXJlYWQgYXJyYXkgICAgICAgICAgJGNvbmZpZwogKiBAcHJvcGVydHktcmVhZCBhcnJheSAgICAgICAgICAkZXh0cmFfY29uZmlnCiAqIEBwcm9wZXJ0eS1yZWFkIENvbnRleHRNYW5hZ2VyICRjb250ZXh0X21hbmFnZXIKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICAgICAgICAgJGFsaWFzCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAgICAgICAgICRhbGlhc2VzCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAgICAgICAgICRhcmd1bWVudHMKICogQHByb3BlcnR5LXJlYWQgYXJyYXkgICAgICAgICAgJGFzc29jX2FyZ3MKICogQHByb3BlcnR5LXJlYWQgYXJyYXkgICAgICAgICAgJHJ1bnRpbWVfY29uZmlnCiAqIEBwcm9wZXJ0eS1yZWFkIGJvb2wgICAgICAgICAgICRjb2xvcml6ZQogKiBAcHJvcGVydHktcmVhZCBhcnJheSAgICAgICAgICAkZWFybHlfaW52b2tlCiAqIEBwcm9wZXJ0eS1yZWFkIHN0cmluZyAgICAgICAgICRnbG9iYWxfY29uZmlnX3BhdGhfZGVidWcKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICAgICAgICAgJHByb2plY3RfY29uZmlnX3BhdGhfZGVidWcKICogQHByb3BlcnR5LXJlYWQgYXJyYXkgICAgICAgICAgJHJlcXVpcmVkX2ZpbGVzCiAqCiAqIEBwYWNrYWdlIFdQX0NMSQogKi8KY2xhc3MgUnVubmVyIHsKCgkvKioKCSAqIExpc3Qgb2YgYnl0ZS1vcmRlciBtYXJrcyAoQk9NcykgdG8gZGV0ZWN0LgoJICoKCSAqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+CgkgKi8KCWNvbnN0IEJZVEVfT1JERVJfTUFSS1MgPSBbCgkJJ1VURi04JyAgICAgICA9PiAiXHhFRlx4QkJceEJGIiwKCQknVVRGLTE2IChCRSknID0+ICJceEZFXHhGRiIsCgkJJ1VURi0xNiAoTEUpJyA9PiAiXHhGRlx4RkUiLAoJXTsKCglwcml2YXRlICRnbG9iYWxfY29uZmlnX3BhdGg7Cglwcml2YXRlICRwcm9qZWN0X2NvbmZpZ19wYXRoOwoKCXByaXZhdGUgJGNvbmZpZzsKCXByaXZhdGUgJGV4dHJhX2NvbmZpZzsKCglwcml2YXRlICRjb250ZXh0X21hbmFnZXI7CgoJcHJpdmF0ZSAkYWxpYXM7CgoJcHJpdmF0ZSAkYWxpYXNlczsKCglwcml2YXRlICRhcmd1bWVudHM7Cglwcml2YXRlICRhc3NvY19hcmdzOwoJcHJpdmF0ZSAkcnVudGltZV9jb25maWc7CgoJcHJpdmF0ZSAkY29sb3JpemUgPSBmYWxzZTsKCglwcml2YXRlICRlYXJseV9pbnZva2UgPSBbXTsKCglwcml2YXRlICRnbG9iYWxfY29uZmlnX3BhdGhfZGVidWc7CgoJcHJpdmF0ZSAkcHJvamVjdF9jb25maWdfcGF0aF9kZWJ1ZzsKCglwcml2YXRlICRyZXF1aXJlZF9maWxlczsKCglwdWJsaWMgZnVuY3Rpb24gX19nZXQoICRrZXkgKSB7CgkJaWYgKCAnXycgPT09ICRrZXlbMF0gKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJcmV0dXJuICR0aGlzLT4ka2V5OwoJfQoKCXB1YmxpYyBmdW5jdGlvbiByZWdpc3Rlcl9jb250ZXh0X21hbmFnZXIoIENvbnRleHRNYW5hZ2VyICRjb250ZXh0X21hbmFnZXIgKSB7CgkJJHRoaXMtPmNvbnRleHRfbWFuYWdlciA9ICRjb250ZXh0X21hbmFnZXI7Cgl9CgoJLyoqCgkgKiBSZWdpc3RlciBhIGNvbW1hbmQgZm9yIGVhcmx5IGludm9jYXRpb24sIGdlbmVyYWxseSBiZWZvcmUgV29yZFByZXNzIGxvYWRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdoZW4gTmFtZWQgZXhlY3V0aW9uIGhvb2sKCSAqIEBwYXJhbSBTdWJjb21tYW5kICRjb21tYW5kCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZWdpc3Rlcl9lYXJseV9pbnZva2UoICR3aGVuLCAkY29tbWFuZCApIHsKCQkkdGhpcy0+ZWFybHlfaW52b2tlWyAkd2hlbiBdW10gPSBhcnJheV9zbGljZSggRGlzcGF0Y2hlclxnZXRfcGF0aCggJGNvbW1hbmQgKSwgMSApOwoJfQoKCS8qKgoJICogUGVyZm9ybSB0aGUgZWFybHkgaW52b2NhdGlvbiBvZiBhIGNvbW1hbmQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd2hlbiBOYW1lZCBleGVjdXRpb24gaG9vawoJICovCglwcml2YXRlIGZ1bmN0aW9uIGRvX2Vhcmx5X2ludm9rZSggJHdoZW4gKSB7CgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+ZWFybHlfaW52b2tlWyAkd2hlbiBdICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIFNlYXJjaCB0aGUgdmFsdWUgb2YgQHdoZW4gZnJvbSB0aGUgY29tbWFuZCBtZXRob2QuCgkJJHJlYWxfd2hlbiA9ICcnOwoJCSRyICAgICAgICAgPSAkdGhpcy0+ZmluZF9jb21tYW5kX3RvX3J1biggJHRoaXMtPmFyZ3VtZW50cyApOwoJCWlmICggaXNfYXJyYXkoICRyICkgKSB7CgkJCWxpc3QoICRjb21tYW5kLCAkZmluYWxfYXJncywgJGNtZF9wYXRoICkgPSAkcjsKCgkJCWZvcmVhY2ggKCAkdGhpcy0+ZWFybHlfaW52b2tlIGFzICRfd2hlbiA9PiAkX3BhdGggKSB7CgkJCQlmb3JlYWNoICggJF9wYXRoIGFzICRjbWQgKSB7CgkJCQkJaWYgKCAkY21kID09PSAkY21kX3BhdGggKSB7CgkJCQkJCSRyZWFsX3doZW4gPSAkX3doZW47CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoKCQlmb3JlYWNoICggJHRoaXMtPmVhcmx5X2ludm9rZVsgJHdoZW4gXSBhcyAkcGF0aCApIHsKCQkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCAkcGF0aCApICkgewoJCQkJaWYgKCBlbXB0eSggJHJlYWxfd2hlbiApIHx8ICggJHJlYWxfd2hlbiAmJiAkcmVhbF93aGVuID09PSAkd2hlbiApICkgewoJCQkJCSR0aGlzLT5ydW5fY29tbWFuZF9hbmRfZXhpdCgpOwoJCQkJfQoJCQl9CgkJfQoJfQoKCS8qKgoJICogR2V0IHRoZSBwYXRoIHRvIHRoZSBnbG9iYWwgY29uZmlndXJhdGlvbiBZQU1MIGZpbGUuCgkgKgoJICogQHBhcmFtIGJvb2wgJGNyZWF0ZV9jb25maWdfZmlsZSBPcHRpb25hbC4gSWYgYSBjb25maWcgZmlsZSBkb2Vzbid0IGV4aXN0LAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGQgaXQgYmUgY3JlYXRlZD8gRGVmYXVsdHMgdG8gZmFsc2UuCgkgKgoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9nbG9iYWxfY29uZmlnX3BhdGgoICRjcmVhdGVfY29uZmlnX2ZpbGUgPSBmYWxzZSApIHsKCgkJaWYgKCBnZXRlbnYoICdXUF9DTElfQ09ORklHX1BBVEgnICkgKSB7CgkJCSRjb25maWdfcGF0aCAgICAgICAgICAgICAgICAgICAgPSBnZXRlbnYoICdXUF9DTElfQ09ORklHX1BBVEgnICk7CgkJCSR0aGlzLT5nbG9iYWxfY29uZmlnX3BhdGhfZGVidWcgPSAnVXNpbmcgZ2xvYmFsIGNvbmZpZyBmcm9tIFdQX0NMSV9DT05GSUdfUEFUSCBlbnYgdmFyOiAnIC4gJGNvbmZpZ19wYXRoOwoJCX0gZWxzZSB7CgkJCSRjb25maWdfcGF0aCAgICAgICAgICAgICAgICAgICAgPSBVdGlsc1xnZXRfaG9tZV9kaXIoKSAuICcvLndwLWNsaS9jb25maWcueW1sJzsKCQkJJHRoaXMtPmdsb2JhbF9jb25maWdfcGF0aF9kZWJ1ZyA9ICdVc2luZyBkZWZhdWx0IGdsb2JhbCBjb25maWc6ICcgLiAkY29uZmlnX3BhdGg7CgkJfQoKCQkvLyBJZiBnbG9iYWwgY29uZmlnIGRvZXNuJ3QgZXhpc3QgY3JlYXRlIG9uZS4KCQlpZiAoIHRydWUgPT09ICRjcmVhdGVfY29uZmlnX2ZpbGUgJiYgISBmaWxlX2V4aXN0cyggJGNvbmZpZ19wYXRoICkgKSB7CgkJCSR0aGlzLT5nbG9iYWxfY29uZmlnX3BhdGhfZGVidWcgPSAiRGVmYXVsdCBnbG9iYWwgY29uZmlnIGRvZXNuJ3QgZXhpc3QsIGNyZWF0aW5nIG9uZSBpbiB7JGNvbmZpZ19wYXRofSI7CgkJCVByb2Nlc3M6OmNyZWF0ZSggVXRpbHNcZXNjX2NtZCggJ3RvdWNoICVzJywgJGNvbmZpZ19wYXRoICkgKS0+cnVuKCk7CgkJfQoKCQlpZiAoIGlzX3JlYWRhYmxlKCAkY29uZmlnX3BhdGggKSApIHsKCQkJcmV0dXJuICRjb25maWdfcGF0aDsKCQl9CgoJCSR0aGlzLT5nbG9iYWxfY29uZmlnX3BhdGhfZGVidWcgPSAnTm8gcmVhZGFibGUgZ2xvYmFsIGNvbmZpZyBmb3VuZCc7CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgcGF0aCB0byB0aGUgcHJvamVjdC1zcGVjaWZpYyBjb25maWd1cmF0aW9uCgkgKiBZQU1MIGZpbGUuCgkgKiB3cC1jbGkubG9jYWwueW1sIHRha2VzIHByaW9yaXR5IG92ZXIgd3AtY2xpLnltbC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3Byb2plY3RfY29uZmlnX3BhdGgoKSB7CgkJJGNvbmZpZ19maWxlcyA9IFsKCQkJJ3dwLWNsaS5sb2NhbC55bWwnLAoJCQknd3AtY2xpLnltbCcsCgkJXTsKCgkJLy8gU3RvcCBsb29raW5nIHVwd2FyZCB3aGVuIHdlIGZpbmQgd2UgaGF2ZSBlbWVyZ2VkIGZyb20gYSBzdWJkaXJlY3RvcnkKCQkvLyBpbnN0YWxsYXRpb24gaW50byBhIHBhcmVudCBpbnN0YWxsYXRpb24KCQkkcHJvamVjdF9jb25maWdfcGF0aCA9IFV0aWxzXGZpbmRfZmlsZV91cHdhcmQoCgkJCSRjb25maWdfZmlsZXMsCgkJCWdldGN3ZCgpLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkZGlyICkgewoJCQkJc3RhdGljICR3cF9sb2FkX2NvdW50ID0gMDsKCQkJCSR3cF9sb2FkX3BhdGggICAgICAgICA9ICRkaXIgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJ3dwLWxvYWQucGhwJzsKCQkJCWlmICggZmlsZV9leGlzdHMoICR3cF9sb2FkX3BhdGggKSApIHsKCQkJCQkrKyAkd3BfbG9hZF9jb3VudDsKCQkJCX0KCQkJCXJldHVybiAkd3BfbG9hZF9jb3VudCA+IDE7CgkJCX0KCQkpOwoKCQkkdGhpcy0+cHJvamVjdF9jb25maWdfcGF0aF9kZWJ1ZyA9ICdObyBwcm9qZWN0IGNvbmZpZyBmb3VuZCc7CgoJCWlmICggISBlbXB0eSggJHByb2plY3RfY29uZmlnX3BhdGggKSApIHsKCQkJJHRoaXMtPnByb2plY3RfY29uZmlnX3BhdGhfZGVidWcgPSAnVXNpbmcgcHJvamVjdCBjb25maWc6ICcgLiAkcHJvamVjdF9jb25maWdfcGF0aDsKCQl9CgoJCXJldHVybiAkcHJvamVjdF9jb25maWdfcGF0aDsKCX0KCgkvKioKCSAqIEdldCB0aGUgcGF0aCB0byB0aGUgcGFja2FnZXMgZGlyZWN0b3J5CgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9wYWNrYWdlc19kaXJfcGF0aCgpIHsKCQlpZiAoIGdldGVudiggJ1dQX0NMSV9QQUNLQUdFU19ESVInICkgKSB7CgkJCSRwYWNrYWdlc19kaXIgPSBVdGlsc1x0cmFpbGluZ3NsYXNoaXQoIGdldGVudiggJ1dQX0NMSV9QQUNLQUdFU19ESVInICkgKTsKCQl9IGVsc2UgewoJCQkkcGFja2FnZXNfZGlyID0gVXRpbHNcZ2V0X2hvbWVfZGlyKCkgLiAnLy53cC1jbGkvcGFja2FnZXMvJzsKCQl9CgkJcmV0dXJuICRwYWNrYWdlc19kaXI7Cgl9CgoJLyoqCgkgKiBBdHRlbXB0cyB0byBmaW5kIHRoZSBwYXRoIHRvIHRoZSBXUCBpbnN0YWxsYXRpb24gaW5zaWRlIGluZGV4LnBocAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGluZGV4X3BhdGgKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3Rfc3ViZGlyX3BhdGgoICRpbmRleF9wYXRoICkgewoJCSRpbmRleF9jb2RlID0gZmlsZV9nZXRfY29udGVudHMoICRpbmRleF9wYXRoICk7CgoJCWlmICggISBwcmVnX21hdGNoKCAnfF5ccypyZXF1aXJlXHMqXCg/XHMqKC4rPykvd3AtYmxvZy1oZWFkZXJcLnBocChbXCciXSl8bScsICRpbmRleF9jb2RlLCAkbWF0Y2hlcyApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkd3BfcGF0aF9zcmMgPSAkbWF0Y2hlc1sxXSAuICRtYXRjaGVzWzJdOwoJCSR3cF9wYXRoX3NyYyA9IFV0aWxzXHJlcGxhY2VfcGF0aF9jb25zdHMoICR3cF9wYXRoX3NyYywgJGluZGV4X3BhdGggKTsKCgkJJHdwX3BhdGggPSBldmFsKCAicmV0dXJuICR3cF9wYXRoX3NyYzsiICk7IC8vIHBocGNzOmlnbm9yZSBTcXVpei5QSFAuRXZhbC5EaXNjb3VyYWdlZAoKCQlpZiAoICEgVXRpbHNcaXNfcGF0aF9hYnNvbHV0ZSggJHdwX3BhdGggKSApIHsKCQkJJHdwX3BhdGggPSBkaXJuYW1lKCAkaW5kZXhfcGF0aCApIC4gIi8kd3BfcGF0aCI7CgkJfQoKCQlyZXR1cm4gJHdwX3BhdGg7Cgl9CgoJLyoqCgkgKiBGaW5kIHRoZSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyB0aGUgV29yZFByZXNzIGZpbGVzLgoJICogRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXIuCgkgKgoJICogQHJldHVybiBzdHJpbmcgQW4gYWJzb2x1dGUgcGF0aAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGZpbmRfd3Bfcm9vdCgpIHsKCQlpZiAoICEgZW1wdHkoICR0aGlzLT5jb25maWdbJ3BhdGgnXSApICkgewoJCQkkcGF0aCA9ICR0aGlzLT5jb25maWdbJ3BhdGgnXTsKCQkJaWYgKCAhIFV0aWxzXGlzX3BhdGhfYWJzb2x1dGUoICRwYXRoICkgKSB7CgkJCQkkcGF0aCA9IGdldGN3ZCgpIC4gJy8nIC4gJHBhdGg7CgkJCX0KCgkJCXJldHVybiAkcGF0aDsKCQl9CgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnY29yZScsICdkb3dubG9hZCcgXSApICkgewoJCQlyZXR1cm4gZ2V0Y3dkKCk7CgkJfQoKCQkkZGlyID0gZ2V0Y3dkKCk7CgoJCXdoaWxlICggaXNfcmVhZGFibGUoICRkaXIgKSApIHsKCQkJaWYgKCBmaWxlX2V4aXN0cyggIiRkaXIvd3AtbG9hZC5waHAiICkgKSB7CgkJCQlyZXR1cm4gJGRpcjsKCQkJfQoKCQkJaWYgKCBmaWxlX2V4aXN0cyggIiRkaXIvaW5kZXgucGhwIiApICkgewoJCQkJJHBhdGggPSBzZWxmOjpleHRyYWN0X3N1YmRpcl9wYXRoKCAiJGRpci9pbmRleC5waHAiICk7CgkJCQlpZiAoICEgZW1wdHkoICRwYXRoICkgKSB7CgkJCQkJcmV0dXJuICRwYXRoOwoJCQkJfQoJCQl9CgoJCQkkcGFyZW50X2RpciA9IGRpcm5hbWUoICRkaXIgKTsKCQkJaWYgKCBlbXB0eSggJHBhcmVudF9kaXIgKSB8fCAkcGFyZW50X2RpciA9PT0gJGRpciApIHsKCQkJCWJyZWFrOwoJCQl9CgkJCSRkaXIgPSAkcGFyZW50X2RpcjsKCQl9Cgl9CgoJLyoqCgkgKiBTZXQgV29yZFByZXNzIHJvb3QgYXMgYSBnaXZlbiBwYXRoLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc2V0X3dwX3Jvb3QoICRwYXRoICkgewoJCWlmICggISBkZWZpbmVkKCAnQUJTUEFUSCcgKSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkQ29uc3RhbnRGb3VuZCAtLSBEZWNsYXJpbmcgYSBXUCBuYXRpdmUgY29uc3RhbnQuCgkJCWRlZmluZSggJ0FCU1BBVEgnLCBVdGlsc1xub3JtYWxpemVfcGF0aCggVXRpbHNcdHJhaWxpbmdzbGFzaGl0KCAkcGF0aCApICkgKTsKCQl9IGVsc2VpZiAoICEgaXNfbnVsbCggJHBhdGggKSApIHsKCQkJV1BfQ0xJOjplcnJvcl9tdWx0aV9saW5lKAoJCQkJWwoJCQkJCSdUaGUgLS1wYXRoIHBhcmFtZXRlciBjYW5ub3QgYmUgdXNlZCB3aGVuIEFCU1BBVEggaXMgYWxyZWFkeSBkZWZpbmVkIGVsc2V3aGVyZScsCgkJCQkJJ0FCU1BBVEggaXMgZGVmaW5lZCBhczogIicgLiBBQlNQQVRIIC4gJyInLAoJCQkJXQoJCQkpOwoJCX0KCQlXUF9DTEk6OmRlYnVnKCAnQUJTUEFUSCBkZWZpbmVkOiAnIC4gQUJTUEFUSCwgJ2Jvb3RzdHJhcCcgKTsKCgkJJF9TRVJWRVJbJ0RPQ1VNRU5UX1JPT1QnXSA9IHJlYWxwYXRoKCAkcGF0aCApOwoJfQoKCS8qKgoJICogR3Vlc3Mgd2hpY2ggVVJMIGNvbnRleHQgV1AtQ0xJIGhhcyBiZWVuIGludm9rZWQgdW5kZXIuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBndWVzc191cmwoICRhc3NvY19hcmdzICkgewoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydibG9nJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3VybCddID0gJGFzc29jX2FyZ3NbJ2Jsb2cnXTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd1cmwnXSApICkgewoJCQkkdXJsID0gJGFzc29jX2FyZ3NbJ3VybCddOwoKCQkJaWYgKCB0cnVlID09PSAkdXJsICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAnVGhlIC0tdXJsIHBhcmFtZXRlciBleHBlY3RzIGEgdmFsdWUuJyApOwoJCQl9CgoJCQlyZXR1cm4gJHVybDsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNtZF9zdGFydHNfd2l0aCggJHByZWZpeCApIHsKCQlyZXR1cm4gYXJyYXlfc2xpY2UoICR0aGlzLT5hcmd1bWVudHMsIDAsIGNvdW50KCAkcHJlZml4ICkgKSA9PT0gJHByZWZpeDsKCX0KCgkvKioKCSAqIEdpdmVuIHBvc2l0aW9uYWwgYXJndW1lbnRzLCBmaW5kIHRoZSBjb21tYW5kIHRvIGV4ZWN1dGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcmV0dXJuIGFycmF5fHN0cmluZyBDb21tYW5kLCBhcmdzLCBhbmQgcGF0aCBvbiBzdWNjZXNzOyBlcnJvciBtZXNzYWdlIG9uIGZhaWx1cmUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbmRfY29tbWFuZF90b19ydW4oICRhcmdzICkgewoJCSRjb21tYW5kID0gV1BfQ0xJOjpnZXRfcm9vdF9jb21tYW5kKCk7CgoJCVdQX0NMSTo6ZG9faG9vayggJ2ZpbmRfY29tbWFuZF90b19ydW5fcHJlJyApOwoKCQkkY21kX3BhdGggPSBbXTsKCgkJd2hpbGUgKCAhIGVtcHR5KCAkYXJncyApICYmICRjb21tYW5kLT5jYW5faGF2ZV9zdWJjb21tYW5kcygpICkgewoJCQkkY21kX3BhdGhbXSA9ICRhcmdzWzBdOwoJCQkkZnVsbF9uYW1lICA9IGltcGxvZGUoICcgJywgJGNtZF9wYXRoICk7CgoJCQkkc3ViY29tbWFuZCA9ICRjb21tYW5kLT5maW5kX3N1YmNvbW1hbmQoICRhcmdzICk7CgoJCQlpZiAoICEgJHN1YmNvbW1hbmQgKSB7CgkJCQlpZiAoIGNvdW50KCAkY21kX3BhdGggKSA+IDEgKSB7CgkJCQkJJGNoaWxkICAgICAgID0gYXJyYXlfcG9wKCAkY21kX3BhdGggKTsKCQkJCQkkcGFyZW50X25hbWUgPSBpbXBsb2RlKCAnICcsICRjbWRfcGF0aCApOwoJCQkJCSRzdWdnZXN0aW9uICA9ICR0aGlzLT5nZXRfc3ViY29tbWFuZF9zdWdnZXN0aW9uKCAkY2hpbGQsICRjb21tYW5kICk7CgkJCQkJcmV0dXJuIHNwcmludGYoCgkJCQkJCSInJXMnIGlzIG5vdCBhIHJlZ2lzdGVyZWQgc3ViY29tbWFuZCBvZiAnJXMnLiBTZWUgJ3dwIGhlbHAgJXMnIGZvciBhdmFpbGFibGUgc3ViY29tbWFuZHMuJXMiLAoJCQkJCQkkY2hpbGQsCgkJCQkJCSRwYXJlbnRfbmFtZSwKCQkJCQkJJHBhcmVudF9uYW1lLAoJCQkJCQkhIGVtcHR5KCAkc3VnZ2VzdGlvbiApID8gUEhQX0VPTCAuICJEaWQgeW91IG1lYW4gJ3skc3VnZ2VzdGlvbn0nPyIgOiAnJwoJCQkJCSk7CgkJCQl9CgoJCQkJJHN1Z2dlc3Rpb24gPSAkdGhpcy0+Z2V0X3N1YmNvbW1hbmRfc3VnZ2VzdGlvbiggJGZ1bGxfbmFtZSwgJGNvbW1hbmQgKTsKCgkJCQlyZXR1cm4gc3ByaW50ZigKCQkJCQkiJyVzJyBpcyBub3QgYSByZWdpc3RlcmVkIHdwIGNvbW1hbmQuIFNlZSAnd3AgaGVscCcgZm9yIGF2YWlsYWJsZSBjb21tYW5kcy4lcyIsCgkJCQkJJGZ1bGxfbmFtZSwKCQkJCQkhIGVtcHR5KCAkc3VnZ2VzdGlvbiApID8gUEhQX0VPTCAuICJEaWQgeW91IG1lYW4gJ3skc3VnZ2VzdGlvbn0nPyIgOiAnJwoJCQkJKTsKCQkJfQoKCQkJaWYgKCAkdGhpcy0+aXNfY29tbWFuZF9kaXNhYmxlZCggJHN1YmNvbW1hbmQgKSApIHsKCQkJCXJldHVybiBzcHJpbnRmKAoJCQkJCSJUaGUgJyVzJyBjb21tYW5kIGhhcyBiZWVuIGRpc2FibGVkIGZyb20gdGhlIGNvbmZpZyBmaWxlLiIsCgkJCQkJJGZ1bGxfbmFtZQoJCQkJKTsKCQkJfQoKCQkJJGNvbW1hbmQgPSAkc3ViY29tbWFuZDsKCQl9CgoJCXJldHVybiBbICRjb21tYW5kLCAkYXJncywgJGNtZF9wYXRoIF07Cgl9CgoJLyoqCgkgKiBGaW5kIHRoZSBXUC1DTEkgY29tbWFuZCB0byBydW4gZ2l2ZW4gYXJndW1lbnRzLCBhbmQgaW52b2tlIGl0LgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyAgICAgICAgUG9zaXRpb25hbCBhcmd1bWVudHMgaW5jbHVkaW5nIGNvbW1hbmQgbmFtZQoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzICBBc3NvY2lhdGl2ZSBhcmd1bWVudHMgZm9yIHRoZSBjb21tYW5kLgoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zICAgICBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBmdW5jdGlvbi4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJ1bl9jb21tYW5kKCAkYXJncywgJGFzc29jX2FyZ3MgPSBbXSwgJG9wdGlvbnMgPSBbXSApIHsKCQlXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfcnVuX2NvbW1hbmQnLCAkYXJncywgJGFzc29jX2FyZ3MsICRvcHRpb25zICk7CgoJCWlmICggISBlbXB0eSggJG9wdGlvbnNbJ2JhY2tfY29tcGF0X2NvbnZlcnNpb25zJ10gKSApIHsKCQkJbGlzdCggJGFyZ3MsICRhc3NvY19hcmdzICkgPSBzZWxmOjpiYWNrX2NvbXBhdF9jb252ZXJzaW9ucyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJfQoJCSRyID0gJHRoaXMtPmZpbmRfY29tbWFuZF90b19ydW4oICRhcmdzICk7CgkJaWYgKCBpc19zdHJpbmcoICRyICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRyICk7CgkJfQoKCQlsaXN0KCAkY29tbWFuZCwgJGZpbmFsX2FyZ3MsICRjbWRfcGF0aCApID0gJHI7CgoJCSRuYW1lID0gaW1wbG9kZSggJyAnLCAkY21kX3BhdGggKTsKCgkJJGV4dHJhX2FyZ3MgPSBbXTsKCgkJaWYgKCBpc3NldCggJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJG5hbWUgXSApICkgewoJCQkkZXh0cmFfYXJncyA9ICR0aGlzLT5leHRyYV9jb25maWdbICRuYW1lIF07CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAnUnVubmluZyBjb21tYW5kOiAnIC4gJG5hbWUsICdib290c3RyYXAnICk7CgkJdHJ5IHsKCQkJJGNvbW1hbmQtPmludm9rZSggJGZpbmFsX2FyZ3MsICRhc3NvY19hcmdzLCAkZXh0cmFfYXJncyApOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9Cgl9CgoJLyoqCgkgKiBTaG93IHN5bm9wc2lzIGlmIHRoZSBjYWxsZWQgY29tbWFuZCBpcyBhIGNvbXBvc2l0ZSBjb21tYW5kCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaG93X3N5bm9wc2lzX2lmX2NvbXBvc2l0ZV9jb21tYW5kKCkgewoJCSRyID0gJHRoaXMtPmZpbmRfY29tbWFuZF90b19ydW4oICR0aGlzLT5hcmd1bWVudHMgKTsKCQlpZiAoIGlzX2FycmF5KCAkciApICkgewoJCQlsaXN0KCAkY29tbWFuZCApID0gJHI7CgoJCQlpZiAoICRjb21tYW5kLT5jYW5faGF2ZV9zdWJjb21tYW5kcygpICkgewoJCQkJJGNvbW1hbmQtPnNob3dfdXNhZ2UoKTsKCQkJCWV4aXQ7CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBydW5fY29tbWFuZF9hbmRfZXhpdCggJGhlbHBfZXhpdF93YXJuaW5nID0gJycgKSB7CgkJJHRoaXMtPnNob3dfc3lub3BzaXNfaWZfY29tcG9zaXRlX2NvbW1hbmQoKTsKCQkkdGhpcy0+cnVuX2NvbW1hbmQoICR0aGlzLT5hcmd1bWVudHMsICR0aGlzLT5hc3NvY19hcmdzICk7CgkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdoZWxwJyBdICkgKSB7CgkJCS8vIEhlbHAgY291bGRuJ3QgZmluZCB0aGUgY29tbWFuZCBzbyBleGl0IHdpdGggc3VnZ2VzdGlvbi4KCQkJJHN1Z2dlc3Rpb25fb3JfZGlzYWJsZWQgPSAkdGhpcy0+ZmluZF9jb21tYW5kX3RvX3J1biggYXJyYXlfc2xpY2UoICR0aGlzLT5hcmd1bWVudHMsIDEgKSApOwoJCQlpZiAoIGlzX3N0cmluZyggJHN1Z2dlc3Rpb25fb3JfZGlzYWJsZWQgKSApIHsKCQkJCWlmICggJGhlbHBfZXhpdF93YXJuaW5nICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggJGhlbHBfZXhpdF93YXJuaW5nICk7CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCAkc3VnZ2VzdGlvbl9vcl9kaXNhYmxlZCApOwoJCQl9CgkJCS8vIFNob3VsZCBuZXZlciBnZXQgaGVyZS4KCQl9CgkJZXhpdDsKCX0KCgkvKioKCSAqIFBlcmZvcm0gYSBjb21tYW5kIGFnYWluc3QgYSByZW1vdGUgc2VydmVyIG92ZXIgU1NIIChvciBhIGNvbnRhaW5lciB1c2luZwoJICogc2NoZW1lIG9mICJkb2NrZXIiIG9yICJkb2NrZXItY29tcG9zZSIpLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbm5lY3Rpb25fc3RyaW5nIFBhc3NlZCBjb25uZWN0aW9uIHN0cmluZy4KCSAqIEByZXR1cm4gdm9pZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJ1bl9zc2hfY29tbWFuZCggJGNvbm5lY3Rpb25fc3RyaW5nICkgewoKCQlXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfc3NoJyApOwoKCQkkYml0cyA9IFV0aWxzXHBhcnNlX3NzaF91cmwoICRjb25uZWN0aW9uX3N0cmluZyApOwoKCQkkcHJlX2NtZCA9IGdldGVudiggJ1dQX0NMSV9TU0hfUFJFX0NNRCcgKTsKCQlpZiAoICRwcmVfY21kICkgewoJCQkkbWVzc2FnZSA9IFdQX0NMSTo6d2FybmluZyggIldQX0NMSV9TU0hfUFJFX0NNRCBmb3VuZCwgZXhlY3V0aW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZChzKSBvbiB0aGUgcmVtb3RlIG1hY2hpbmU6XG4gJHByZV9jbWQiICk7CgoJCQlXUF9DTEk6OmxvZyggJG1lc3NhZ2UgKTsKCgkJCSRwcmVfY21kID0gcnRyaW0oICRwcmVfY21kLCAnOycgKSAuICc7ICc7CgkJfQoJCWlmICggISBlbXB0eSggJGJpdHNbJ3BhdGgnXSApICkgewoJCQkkcHJlX2NtZCAuPSAnY2QgJyAuIGVzY2FwZXNoZWxsYXJnKCAkYml0c1sncGF0aCddICkgLiAnOyAnOwoJCX0KCgkJJGVudl92YXJzID0gJyc7CgkJaWYgKCBnZXRlbnYoICdXUF9DTElfU1RSSUNUX0FSR1NfTU9ERScgKSApIHsKCQkJJGVudl92YXJzIC49ICdXUF9DTElfU1RSSUNUX0FSR1NfTU9ERT0xICc7CgkJfQoKCQkkd3BfYmluYXJ5ID0gJ3dwJzsKCQkkd3BfYXJncyAgID0gYXJyYXlfc2xpY2UoICRHTE9CQUxTWydhcmd2J10sIDEgKTsKCgkJaWYgKCAkdGhpcy0+YWxpYXMgJiYgISBlbXB0eSggJHdwX2FyZ3NbMF0gKSAmJiAkdGhpcy0+YWxpYXMgPT09ICR3cF9hcmdzWzBdICkgewoJCQlhcnJheV9zaGlmdCggJHdwX2FyZ3MgKTsKCQkJJHJ1bnRpbWVfYWxpYXMgPSBbXTsKCQkJZm9yZWFjaCAoICR0aGlzLT5hbGlhc2VzWyAkdGhpcy0+YWxpYXMgXSBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCWlmICggJ3NzaCcgPT09ICRrZXkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkcnVudGltZV9hbGlhc1sgJGtleSBdID0gJHZhbHVlOwoJCQl9CgkJCWlmICggISBlbXB0eSggJHJ1bnRpbWVfYWxpYXMgKSApIHsKCQkJCSRlbmNvZGVkX2FsaWFzID0ganNvbl9lbmNvZGUoCgkJCQkJWwoJCQkJCQkkdGhpcy0+YWxpYXMgPT4gJHJ1bnRpbWVfYWxpYXMsCgkJCQkJXQoJCQkJKTsKCQkJCSR3cF9iaW5hcnkgICAgID0gIldQX0NMSV9SVU5USU1FX0FMSUFTPSd7JGVuY29kZWRfYWxpYXN9JyB7JHdwX2JpbmFyeX0geyR0aGlzLT5hbGlhc30iOwoJCQl9CgkJfQoKCQlmb3JlYWNoICggJHdwX2FyZ3MgYXMgJGsgPT4gJHYgKSB7CgkJCWlmICggcHJlZ19tYXRjaCggJyMtLXNzaD0jJywgJHYgKSApIHsKCQkJCXVuc2V0KCAkd3BfYXJnc1sgJGsgXSApOwoJCQl9CgkJfQoKCQkkd3BfY29tbWFuZCAgICAgID0gJHByZV9jbWQgLiAkZW52X3ZhcnMgLiAkd3BfYmluYXJ5IC4gJyAnIC4gaW1wbG9kZSggJyAnLCBhcnJheV9tYXAoICdlc2NhcGVzaGVsbGFyZycsICR3cF9hcmdzICkgKTsKCQkkZXNjYXBlZF9jb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlX3NzaF9jb21tYW5kKCAkYml0cywgJHdwX2NvbW1hbmQgKTsKCgkJcGFzc3RocnUoICRlc2NhcGVkX2NvbW1hbmQsICRleGl0X2NvZGUgKTsKCQlpZiAoIDI1NSA9PT0gJGV4aXRfY29kZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0Nhbm5vdCBjb25uZWN0IG92ZXIgU1NIIHVzaW5nIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24uJywgMjU1ICk7CgkJfSBlbHNlIHsKCQkJZXhpdCggJGV4aXRfY29kZSApOwoJCX0KCX0KCgkvKioKCSAqIEdlbmVyYXRlIGEgc2hlbGwgY29tbWFuZCBmcm9tIHRoZSBwYXJzZWQgY29ubmVjdGlvbiBzdHJpbmcuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkYml0cyAgICAgICBQYXJzZWQgY29ubmVjdGlvbiBzdHJpbmcuCgkgKiBAcGFyYW0gc3RyaW5nICR3cF9jb21tYW5kIFdQLUNMSSBjb21tYW5kIHRvIHJ1bi4KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2VuZXJhdGVfc3NoX2NvbW1hbmQoICRiaXRzLCAkd3BfY29tbWFuZCApIHsKCQkkZXNjYXBlZF9jb21tYW5kID0gJyc7CgoJCS8vIFNldCBkZWZhdWx0IHZhbHVlcy4KCQlmb3JlYWNoICggWyAnc2NoZW1lJywgJ3VzZXInLCAnaG9zdCcsICdwb3J0JywgJ3BhdGgnLCAna2V5JyBdIGFzICRiaXQgKSB7CgkJCWlmICggISBpc3NldCggJGJpdHNbICRiaXQgXSApICkgewoJCQkJJGJpdHNbICRiaXQgXSA9IG51bGw7CgkJCX0KCgkJCVdQX0NMSTo6ZGVidWcoICdTU0ggJyAuICRiaXQgLiAnOiAnIC4gJGJpdHNbICRiaXQgXSwgJ2Jvb3RzdHJhcCcgKTsKCQl9CgoJCSRpc190dHkgPSBmdW5jdGlvbl9leGlzdHMoICdwb3NpeF9pc2F0dHknICkgJiYgcG9zaXhfaXNhdHR5KCBTVERPVVQgKTsKCgkJaWYgKCAnZG9ja2VyJyA9PT0gJGJpdHNbJ3NjaGVtZSddICkgewoJCQkkY29tbWFuZCA9ICdkb2NrZXIgZXhlYyAlcyVzJXMgc2ggLWMgJXMnOwoKCQkJJGVzY2FwZWRfY29tbWFuZCA9IHNwcmludGYoCgkJCQkkY29tbWFuZCwKCQkJCSRiaXRzWyd1c2VyJ10gPyAnLS11c2VyICcgLiBlc2NhcGVzaGVsbGFyZyggJGJpdHNbJ3VzZXInXSApIC4gJyAnIDogJycsCgkJCQkkaXNfdHR5ID8gJy10ICcgOiAnJywKCQkJCWVzY2FwZXNoZWxsYXJnKCAkYml0c1snaG9zdCddICksCgkJCQllc2NhcGVzaGVsbGFyZyggJHdwX2NvbW1hbmQgKQoJCQkpOwoJCX0KCgkJaWYgKCAnZG9ja2VyLWNvbXBvc2UnID09PSAkYml0c1snc2NoZW1lJ10gKSB7CgkJCSRjb21tYW5kID0gJ2RvY2tlci1jb21wb3NlIGV4ZWMgJXMlcyVzIHNoIC1jICVzJzsKCgkJCSRlc2NhcGVkX2NvbW1hbmQgPSBzcHJpbnRmKAoJCQkJJGNvbW1hbmQsCgkJCQkkYml0c1sndXNlciddID8gJy0tdXNlciAnIC4gZXNjYXBlc2hlbGxhcmcoICRiaXRzWyd1c2VyJ10gKSAuICcgJyA6ICcnLAoJCQkJJGlzX3R0eSA/ICcnIDogJy1UICcsCgkJCQllc2NhcGVzaGVsbGFyZyggJGJpdHNbJ2hvc3QnXSApLAoJCQkJZXNjYXBlc2hlbGxhcmcoICR3cF9jb21tYW5kICkKCQkJKTsKCQl9CgoJCS8vIFZhZ3JhbnQgc3NoLWNvbmZpZy4KCQlpZiAoICd2YWdyYW50JyA9PT0gJGJpdHNbJ3NjaGVtZSddICkgewoJCQkkY2FjaGUgICAgID0gV1BfQ0xJOjpnZXRfY2FjaGUoKTsKCQkJJGNhY2hlX2tleSA9ICd2YWdyYW50OicgLiAkdGhpcy0+cHJvamVjdF9jb25maWdfcGF0aDsKCQkJaWYgKCAkY2FjaGUtPmhhcyggJGNhY2hlX2tleSApICkgewoJCQkJJGNhY2hlZCA9ICRjYWNoZS0+cmVhZCggJGNhY2hlX2tleSApOwoJCQkJJHZhbHVlcyA9IGpzb25fZGVjb2RlKCAkY2FjaGVkLCB0cnVlICk7CgkJCX0gZWxzZSB7CgkJCQkkc3NoX2NvbmZpZyA9IHNoZWxsX2V4ZWMoICd2YWdyYW50IHNzaC1jb25maWcgMj4vZGV2L251bGwnICk7CgkJCQlpZiAoIHByZWdfbWF0Y2hfYWxsKCAnI1xzKig/PE5BTUU+W2EtekEtWl0rKVxzKD88VkFMVUU+LispXHMqIycsICRzc2hfY29uZmlnLCAkbWF0Y2hlcyApICkgewoJCQkJCSR2YWx1ZXMgPSBhcnJheV9jb21iaW5lKCAkbWF0Y2hlc1snTkFNRSddLCAkbWF0Y2hlc1snVkFMVUUnXSApOwoJCQkJCSRjYWNoZS0+d3JpdGUoICRjYWNoZV9rZXksIGpzb25fZW5jb2RlKCAkdmFsdWVzICkgKTsKCQkJCX0KCQkJfQoKCQkJaWYgKCBlbXB0eSggJGJpdHNbJ2hvc3QnXSApIHx8ICggaXNzZXQoICR2YWx1ZXNbJ0hvc3QnXSApICYmICRiaXRzWydob3N0J10gPT09ICR2YWx1ZXNbJ0hvc3QnXSApICkgewoJCQkJJGJpdHNbJ3NjaGVtZSddID0gJ3NzaCc7CgkJCQkkYml0c1snaG9zdCddICAgPSAkdmFsdWVzWydIb3N0TmFtZSddOwoJCQkJJGJpdHNbJ3BvcnQnXSAgID0gJHZhbHVlc1snUG9ydCddOwoJCQkJJGJpdHNbJ3VzZXInXSAgID0gJHZhbHVlc1snVXNlciddOwoJCQkJJGJpdHNbJ2tleSddICAgID0gJHZhbHVlc1snSWRlbnRpdHlGaWxlJ107CgkJCX0KCgkJCS8vIElmIHdlIGNvdWxkIG5vdCByZXNvbHZlIHRoZSBiaXRzIHN0aWxsLCBmYWxsYmFjayB0byBqdXN0IGB2YWdyYW50IHNzaGAKCQkJaWYgKCAndmFncmFudCcgPT09ICRiaXRzWydzY2hlbWUnXSApIHsKCQkJCSRjb21tYW5kID0gJ3ZhZ3JhbnQgc3NoIC1jICVzICVzJzsKCgkJCQkkZXNjYXBlZF9jb21tYW5kID0gc3ByaW50ZigKCQkJCQkkY29tbWFuZCwKCQkJCQllc2NhcGVzaGVsbGFyZyggJHdwX2NvbW1hbmQgKSwKCQkJCQllc2NhcGVzaGVsbGFyZyggJGJpdHNbJ2hvc3QnXSApCgkJCQkpOwoJCQl9CgkJfQoKCQkvLyBEZWZhdWx0IHNjaGVtZSBpcyBTU0guCgkJaWYgKCAnc3NoJyA9PT0gJGJpdHNbJ3NjaGVtZSddIHx8IG51bGwgPT09ICRiaXRzWydzY2hlbWUnXSApIHsKCQkJJGNvbW1hbmQgPSAnc3NoIC1xICVzICVzICVzJzsKCgkJCWlmICggJGJpdHNbJ3VzZXInXSApIHsKCQkJCSRiaXRzWydob3N0J10gPSAkYml0c1sndXNlciddIC4gJ0AnIC4gJGJpdHNbJ2hvc3QnXTsKCQkJfQoKCQkJJGNvbW1hbmRfYXJncyA9IFsKCQkJCSRiaXRzWydwb3J0J10gPyAnLXAgJyAuIChpbnQpICRiaXRzWydwb3J0J10gLiAnICcgOiAnJywKCQkJCSRiaXRzWydrZXknXSA/IHNwcmludGYoICctaSAlcycsICRiaXRzWydrZXknXSApIDogJycsCgkJCQkkaXNfdHR5ID8gJy10JyA6ICctVCcsCgkJCV07CgoJCQkkZXNjYXBlZF9jb21tYW5kID0gc3ByaW50ZigKCQkJCSRjb21tYW5kLAoJCQkJaW1wbG9kZSggJyAnLCBhcnJheV9maWx0ZXIoICRjb21tYW5kX2FyZ3MgKSApLAoJCQkJZXNjYXBlc2hlbGxhcmcoICRiaXRzWydob3N0J10gKSwKCQkJCWVzY2FwZXNoZWxsYXJnKCAkd3BfY29tbWFuZCApCgkJCSk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAnUnVubmluZyBTU0ggY29tbWFuZDogJyAuICRlc2NhcGVkX2NvbW1hbmQsICdib290c3RyYXAnICk7CgoJCXJldHVybiAkZXNjYXBlZF9jb21tYW5kOwoJfQoKCS8qKgoJICogQ2hlY2sgd2hldGhlciBhIGdpdmVuIGNvbW1hbmQgaXMgZGlzYWJsZWQgYnkgdGhlIGNvbmZpZy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2NvbW1hbmRfZGlzYWJsZWQoICRjb21tYW5kICkgewoJCSRwYXRoID0gaW1wbG9kZSggJyAnLCBhcnJheV9zbGljZSggRGlzcGF0Y2hlclxnZXRfcGF0aCggJGNvbW1hbmQgKSwgMSApICk7CgkJcmV0dXJuIGluX2FycmF5KCAkcGF0aCwgJHRoaXMtPmNvbmZpZ1snZGlzYWJsZWRfY29tbWFuZHMnXSwgdHJ1ZSApOwoJfQoKCS8qKgoJICogUmV0dXJucyB3cC1jb25maWcucGhwIGNvZGUsIHNraXBwaW5nIHRoZSBsb2FkaW5nIG9mIHdwLXNldHRpbmdzLnBocC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3cF9jb25maWdfcGF0aCBPcHRpb25hbC4gQ29uZmlnIGZpbGUgcGF0aC4gSWYgbGVmdCBlbXB0eSwgaXQgdHJpZXMgdG8KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0ZSB0aGUgd3AtY29uZmlnLnBocCBmaWxlIGF1dG9tYXRpY2FsbHkuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF93cF9jb25maWdfY29kZSggJHdwX2NvbmZpZ19wYXRoID0gJycgKSB7CgkJaWYgKCBlbXB0eSggJHdwX2NvbmZpZ19wYXRoICkgKSB7CgkJCSR3cF9jb25maWdfcGF0aCA9IFV0aWxzXGxvY2F0ZV93cF9jb25maWcoKTsKCQl9CgoJCSR3cF9jb25maWdfY29kZSA9IGV4cGxvZGUoICJcbiIsIGZpbGVfZ2V0X2NvbnRlbnRzKCAkd3BfY29uZmlnX3BhdGggKSApOwoKCQkvLyBEZXRlY3QgYW5kIHN0cmlwIGJ5dGUtb3JkZXIgbWFya3MgKEJPTXMpLgoJCS8vIFRoaXMgY29kZSBhc3N1bWVzIHRoZXkgY2FuIG9ubHkgYmUgZm91bmQgb24gdGhlIGZpcnN0IGxpbmUuCgkJZm9yZWFjaCAoIHNlbGY6OkJZVEVfT1JERVJfTUFSS1MgYXMgJGJvbV9uYW1lID0+ICRib21fc2VxdWVuY2UgKSB7CgkJCVdQX0NMSTo6ZGVidWcoICJMb29raW5nIGZvciB7JGJvbV9uYW1lfSBCT00iLCAnYm9vdHN0cmFwJyApOwoKCQkJJGxlbmd0aCA9IHN0cmxlbiggJGJvbV9zZXF1ZW5jZSApOwoKCQkJd2hpbGUgKCBzdWJzdHIoICR3cF9jb25maWdfY29kZVswXSwgMCwgJGxlbmd0aCApID09PSAkYm9tX3NlcXVlbmNlICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCSJ7JGJvbV9uYW1lfSBieXRlLW9yZGVyIG1hcmsgKEJPTSkgZGV0ZWN0ZWQgaW4gd3AtY29uZmlnLnBocCBmaWxlLCBzdHJpcHBpbmcgaXQgZm9yIHBhcnNpbmcuIgoJCQkJKTsKCgkJCQkkd3BfY29uZmlnX2NvZGVbMF0gPSBzdWJzdHIoICR3cF9jb25maWdfY29kZVswXSwgJGxlbmd0aCApOwoJCQl9CgkJfQoKCQkkZm91bmRfd3Bfc2V0dGluZ3MgPSBmYWxzZTsKCgkJJGxpbmVzX3RvX3J1biA9IFtdOwoKCQlmb3JlYWNoICggJHdwX2NvbmZpZ19jb2RlIGFzICRsaW5lICkgewoJCQlpZiAoIHByZWdfbWF0Y2goICcvXlxzKnJlcXVpcmUuK3dwLXNldHRpbmdzXC5waHAvJywgJGxpbmUgKSApIHsKCQkJCSRmb3VuZF93cF9zZXR0aW5ncyA9IHRydWU7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGxpbmVzX3RvX3J1bltdID0gJGxpbmU7CgkJfQoKCQlpZiAoICEgJGZvdW5kX3dwX3NldHRpbmdzICkgewoJCQlXUF9DTEk6OmVycm9yKCAnU3RyYW5nZSB3cC1jb25maWcucGhwIGZpbGU6IHdwLXNldHRpbmdzLnBocCBpcyBub3QgbG9hZGVkIGRpcmVjdGx5LicgKTsKCQl9CgoJCSRzb3VyY2UgPSBpbXBsb2RlKCAiXG4iLCAkbGluZXNfdG9fcnVuICk7CgkJJHNvdXJjZSA9IFV0aWxzXHJlcGxhY2VfcGF0aF9jb25zdHMoICRzb3VyY2UsICR3cF9jb25maWdfcGF0aCApOwoJCXJldHVybiBwcmVnX3JlcGxhY2UoICd8XlxzKlw8XD9waHBccyp8JywgJycsICRzb3VyY2UgKTsKCX0KCgkvKioKCSAqIFRyYW5zcGFyZW50bHkgY29udmVydCBkZXByZWNhdGVkIHN5bnRheGVzCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYmFja19jb21wYXRfY29udmVyc2lvbnMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdG9wX2xldmVsX2FsaWFzZXMgPSBbCgkJCSdzcWwnICA9PiAnZGInLAoJCQknYmxvZycgPT4gJ3NpdGUnLAoJCV07CgkJaWYgKCBjb3VudCggJGFyZ3MgKSA+IDAgKSB7CgkJCWZvcmVhY2ggKCAkdG9wX2xldmVsX2FsaWFzZXMgYXMgJG9sZCA9PiAkbmV3ICkgewoJCQkJaWYgKCAkb2xkID09PSAkYXJnc1swXSApIHsKCQkJCQkkYXJnc1swXSA9ICRuZXc7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCS8vICotbWV0YSAgLT4gICogbWV0YQoJCWlmICggISBlbXB0eSggJGFyZ3MgKSAmJiBwcmVnX21hdGNoKCAnLyhwb3N0fGNvbW1lbnR8dXNlcnxuZXR3b3JrKS1tZXRhLycsICRhcmdzWzBdLCAkbWF0Y2hlcyApICkgewoJCQlhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkJYXJyYXlfdW5zaGlmdCggJGFyZ3MsICdtZXRhJyApOwoJCQlhcnJheV91bnNoaWZ0KCAkYXJncywgJG1hdGNoZXNbMV0gKTsKCQl9CgoJCS8vIGNsaSBhbGlhc2VzICAtPiAgY2xpIGFsaWFzIGxpc3QKCQlpZiAoIFsgJ2NsaScsICdhbGlhc2VzJyBdID09PSBhcnJheV9zbGljZSggJGFyZ3MsIDAsIDIgKSApIHsKCQkJbGlzdCggJGFyZ3NbMF0sICRhcmdzWzFdLCAkYXJnc1syXSApID0gWyAnY2xpJywgJ2FsaWFzJywgJ2xpc3QnIF07CgkJfQoKCQkvLyBjb3JlIChtdWx0c2l0ZS0paW5zdGFsbCAtLWFkbWluX25hbWU9ICAtPiAgLS1hZG1pbl91c2VyPQoJCWlmICggY291bnQoICRhcmdzICkgPiAwICYmICdjb3JlJyA9PT0gJGFyZ3NbMF0gJiYgaXNzZXQoICRhc3NvY19hcmdzWydhZG1pbl9uYW1lJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2FkbWluX3VzZXInXSA9ICRhc3NvY19hcmdzWydhZG1pbl9uYW1lJ107CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snYWRtaW5fbmFtZSddICk7CgkJfQoKCQkvLyBjb3JlIGNvbmZpZyAgLT4gIGNvbmZpZyBjcmVhdGUKCQlpZiAoIFsgJ2NvcmUnLCAnY29uZmlnJyBdID09PSBhcnJheV9zbGljZSggJGFyZ3MsIDAsIDIgKSApIHsKCQkJbGlzdCggJGFyZ3NbMF0sICRhcmdzWzFdICkgPSBbICdjb25maWcnLCAnY3JlYXRlJyBdOwoJCX0KCQkvLyBjb3JlIGxhbmd1YWdlICAtPiAgbGFuZ3VhZ2UgY29yZQoJCWlmICggWyAnY29yZScsICdsYW5ndWFnZScgXSA9PT0gYXJyYXlfc2xpY2UoICRhcmdzLCAwLCAyICkgKSB7CgkJCWxpc3QoICRhcmdzWzBdLCAkYXJnc1sxXSApID0gWyAnbGFuZ3VhZ2UnLCAnY29yZScgXTsKCQl9CgoJCS8vIGNoZWNrc3VtIGNvcmUgIC0+ICBjb3JlIHZlcmlmeS1jaGVja3N1bXMKCQlpZiAoIFsgJ2NoZWNrc3VtJywgJ2NvcmUnIF0gPT09IGFycmF5X3NsaWNlKCAkYXJncywgMCwgMiApICkgewoJCQlsaXN0KCAkYXJnc1swXSwgJGFyZ3NbMV0gKSA9IFsgJ2NvcmUnLCAndmVyaWZ5LWNoZWNrc3VtcycgXTsKCQl9CgoJCS8vIGNoZWNrc3VtIHBsdWdpbiAgLT4gIHBsdWdpbiB2ZXJpZnktY2hlY2tzdW1zCgkJaWYgKCBbICdjaGVja3N1bScsICdwbHVnaW4nIF0gPT09IGFycmF5X3NsaWNlKCAkYXJncywgMCwgMiApICkgewoJCQlsaXN0KCAkYXJnc1swXSwgJGFyZ3NbMV0gKSA9IFsgJ3BsdWdpbicsICd2ZXJpZnktY2hlY2tzdW1zJyBdOwoJCX0KCgkJLy8gc2l0ZSBjcmVhdGUgLS1zaXRlX2lkPSAgLT4gIHNpdGUgY3JlYXRlIC0tbmV0d29ya19pZD0KCQlpZiAoIGNvdW50KCAkYXJncyApID49IDIgJiYgJ3NpdGUnID09PSAkYXJnc1swXSAmJiAnY3JlYXRlJyA9PT0gJGFyZ3NbMV0gJiYgaXNzZXQoICRhc3NvY19hcmdzWydzaXRlX2lkJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ25ldHdvcmtfaWQnXSA9ICRhc3NvY19hcmdzWydzaXRlX2lkJ107CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snc2l0ZV9pZCddICk7CgkJfQoKCQkvLyB7cGx1Z2lufHRoZW1lfSB1cGRhdGUtYWxsICAtPiAge3BsdWdpbnx0aGVtZX0gdXBkYXRlIC0tYWxsCgkJaWYgKCBjb3VudCggJGFyZ3MgKSA+IDEgJiYgaW5fYXJyYXkoICRhcmdzWzBdLCBbICdwbHVnaW4nLCAndGhlbWUnIF0sIHRydWUgKQoJCQkmJiAndXBkYXRlLWFsbCcgPT09ICRhcmdzWzFdCgkJKSB7CgkJCSRhcmdzWzFdICAgICAgICAgICA9ICd1cGRhdGUnOwoJCQkkYXNzb2NfYXJnc1snYWxsJ10gPSB0cnVlOwoJCX0KCgkJLy8gdHJhbnNpZW50IGRlbGV0ZS1leHBpcmVkICAtPiAgdHJhbnNpZW50IGRlbGV0ZSAtLWV4cGlyZWQKCQlpZiAoIGNvdW50KCAkYXJncyApID4gMSAmJiAndHJhbnNpZW50JyA9PT0gJGFyZ3NbMF0gJiYgJ2RlbGV0ZS1leHBpcmVkJyA9PT0gJGFyZ3NbMV0gKSB7CgkJCSRhcmdzWzFdICAgICAgICAgICAgICAgPSAnZGVsZXRlJzsKCQkJJGFzc29jX2FyZ3NbJ2V4cGlyZWQnXSA9IHRydWU7CgkJfQoKCQkvLyB0cmFuc2llbnQgZGVsZXRlLWFsbCAgLT4gIHRyYW5zaWVudCBkZWxldGUgLS1hbGwKCQlpZiAoIGNvdW50KCAkYXJncyApID4gMSAmJiAndHJhbnNpZW50JyA9PT0gJGFyZ3NbMF0gJiYgJ2RlbGV0ZS1hbGwnID09PSAkYXJnc1sxXSApIHsKCQkJJGFyZ3NbMV0gICAgICAgICAgID0gJ2RlbGV0ZSc7CgkJCSRhc3NvY19hcmdzWydhbGwnXSA9IHRydWU7CgkJfQoKCQkvLyBwbHVnaW4gc2NhZmZvbGQgIC0+ICBzY2FmZm9sZCBwbHVnaW4KCQlpZiAoIFsgJ3BsdWdpbicsICdzY2FmZm9sZCcgXSA9PT0gYXJyYXlfc2xpY2UoICRhcmdzLCAwLCAyICkgKSB7CgkJCWxpc3QoICRhcmdzWzBdLCAkYXJnc1sxXSApID0gWyAkYXJnc1sxXSwgJGFyZ3NbMF0gXTsKCQl9CgoJCS8vIGZvbyAtLWhlbHAgIC0+ICBoZWxwIGZvbwoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydoZWxwJ10gKSApIHsKCQkJYXJyYXlfdW5zaGlmdCggJGFyZ3MsICdoZWxwJyApOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ2hlbHAnXSApOwoJCX0KCgkJLy8ge3Bvc3R8dXNlcn0gbGlzdCAtLWlkcyAgLT4gIHtwb3N0fHVzZXJ9IGxpc3QgLS1mb3JtYXQ9aWRzCgkJaWYgKCBjb3VudCggJGFyZ3MgKSA+IDEgJiYgaW5fYXJyYXkoICRhcmdzWzBdLCBbICdwb3N0JywgJ3VzZXInIF0sIHRydWUgKQoJCQkmJiAnbGlzdCcgPT09ICRhcmdzWzFdCgkJCSYmIGlzc2V0KCAkYXNzb2NfYXJnc1snaWRzJ10gKQoJCSkgewoJCQkkYXNzb2NfYXJnc1snZm9ybWF0J10gPSAnaWRzJzsKCQkJdW5zZXQoICRhc3NvY19hcmdzWydpZHMnXSApOwoJCX0KCgkJLy8gLS1qc29uICAtPiAgLS1mb3JtYXQ9anNvbgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydqc29uJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2Zvcm1hdCddID0gJ2pzb24nOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ2pzb24nXSApOwoJCX0KCgkJLy8gLS17dmVyc2lvbnxpbmZvfSAgLT4gIGNsaSB7dmVyc2lvbnxpbmZvfQoJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCSRzcGVjaWFsX2ZsYWdzID0gWyAndmVyc2lvbicsICdpbmZvJyBdOwoJCQlmb3JlYWNoICggJHNwZWNpYWxfZmxhZ3MgYXMgJGtleSApIHsKCQkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAka2V5IF0gKSApIHsKCQkJCQkkYXJncyA9IFsgJ2NsaScsICRrZXkgXTsKCQkJCQl1bnNldCggJGFzc29jX2FyZ3NbICRrZXkgXSApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyAocG9zdHxjb21tZW50fHNpdGV8dGVybSkgdXJsICAtLT4gKHBvc3R8Y29tbWVudHxzaXRlfHRlcm0pIGxpc3QgLS0qX19pbiAtLWZpZWxkPXVybAoJCWlmICggY291bnQoICRhcmdzICkgPj0gMiAmJiBpbl9hcnJheSggJGFyZ3NbMF0sIFsgJ3Bvc3QnLCAnY29tbWVudCcsICdzaXRlJywgJ3Rlcm0nIF0sIHRydWUgKSAmJiAndXJsJyA9PT0gJGFyZ3NbMV0gKSB7CgkJCXN3aXRjaCAoICRhcmdzWzBdICkgewoJCQkJY2FzZSAncG9zdCc6CgkJCQkJJHBvc3RfaWRzICAgICAgICAgICAgICAgID0gYXJyYXlfc2xpY2UoICRhcmdzLCAyICk7CgkJCQkJJGFyZ3MgICAgICAgICAgICAgICAgICAgID0gWyAncG9zdCcsICdsaXN0JyBdOwoJCQkJCSRhc3NvY19hcmdzWydwb3N0X19pbiddICA9IGltcGxvZGUoICcsJywgJHBvc3RfaWRzICk7CgkJCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfdHlwZSddID0gJ2FueSc7CgkJCQkJJGFzc29jX2FyZ3NbJ29yZGVyYnknXSAgID0gJ3Bvc3RfX2luJzsKCQkJCQkkYXNzb2NfYXJnc1snZmllbGQnXSAgICAgPSAndXJsJzsKCQkJCQlicmVhazsKCQkJCWNhc2UgJ2NvbW1lbnQnOgoJCQkJCSRjb21tZW50X2lkcyAgICAgICAgICAgICAgID0gYXJyYXlfc2xpY2UoICRhcmdzLCAyICk7CgkJCQkJJGFyZ3MgICAgICAgICAgICAgICAgICAgICAgPSBbICdjb21tZW50JywgJ2xpc3QnIF07CgkJCQkJJGFzc29jX2FyZ3NbJ2NvbW1lbnRfX2luJ10gPSBpbXBsb2RlKCAnLCcsICRjb21tZW50X2lkcyApOwoJCQkJCSRhc3NvY19hcmdzWydvcmRlcmJ5J10gICAgID0gJ2NvbW1lbnRfX2luJzsKCQkJCQkkYXNzb2NfYXJnc1snZmllbGQnXSAgICAgICA9ICd1cmwnOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnc2l0ZSc6CgkJCQkJJHNpdGVfaWRzICAgICAgICAgICAgICAgPSBhcnJheV9zbGljZSggJGFyZ3MsIDIgKTsKCQkJCQkkYXJncyAgICAgICAgICAgICAgICAgICA9IFsgJ3NpdGUnLCAnbGlzdCcgXTsKCQkJCQkkYXNzb2NfYXJnc1snc2l0ZV9faW4nXSA9IGltcGxvZGUoICcsJywgJHNpdGVfaWRzICk7CgkJCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkJ10gICAgPSAndXJsJzsKCQkJCQlicmVhazsKCQkJCWNhc2UgJ3Rlcm0nOgoJCQkJCSR0YXhvbm9teSA9ICcnOwoJCQkJCWlmICggaXNzZXQoICRhcmdzWzJdICkgKSB7CgkJCQkJCSR0YXhvbm9teSA9ICRhcmdzWzJdOwoJCQkJCX0KCQkJCQkkdGVybV9pZHMgICAgICAgICAgICAgID0gYXJyYXlfc2xpY2UoICRhcmdzLCAzICk7CgkJCQkJJGFyZ3MgICAgICAgICAgICAgICAgICA9IFsgJ3Rlcm0nLCAnbGlzdCcsICR0YXhvbm9teSBdOwoJCQkJCSRhc3NvY19hcmdzWydpbmNsdWRlJ10gPSBpbXBsb2RlKCAnLCcsICR0ZXJtX2lkcyApOwoJCQkJCSRhc3NvY19hcmdzWydvcmRlcmJ5J10gPSAnaW5jbHVkZSc7CgkJCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkJ10gICA9ICd1cmwnOwoJCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQkvLyBjb25maWcgZ2V0IC0tW2dsb2JhbHxjb25zdGFudF09PGdsb2JhbHxjb25zdGFudD4gLS0+IGNvbmZpZyBnZXQgPG5hbWU+IC0tdHlwZT1jb25zdGFudHx2YXJpYWJsZQoJCS8vIGNvbmZpZyBnZXQgLS0+IGNvbmZpZyBsaXN0CgkJaWYgKCBjb3VudCggJGFyZ3MgKSA9PT0gMgoJCQkmJiAnY29uZmlnJyA9PT0gJGFyZ3NbMF0KCQkJJiYgJ2dldCcgPT09ICRhcmdzWzFdICkgewoJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZ2xvYmFsJ10gKSApIHsKCQkJCSRuYW1lID0gJGFzc29jX2FyZ3NbJ2dsb2JhbCddOwoJCQkJJHR5cGUgPSAndmFyaWFibGUnOwoJCQkJdW5zZXQoICRhc3NvY19hcmdzWydnbG9iYWwnXSApOwoJCQl9IGVsc2VpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snY29uc3RhbnQnXSApICkgewoJCQkJJG5hbWUgPSAkYXNzb2NfYXJnc1snY29uc3RhbnQnXTsKCQkJCSR0eXBlID0gJ2NvbnN0YW50JzsKCQkJCXVuc2V0KCAkYXNzb2NfYXJnc1snY29uc3RhbnQnXSApOwoJCQl9CgkJCWlmICggISBlbXB0eSggJG5hbWUgKSAmJiAhIGVtcHR5KCAkdHlwZSApICkgewoJCQkJJGFyZ3NbXSAgICAgICAgICAgICA9ICRuYW1lOwoJCQkJJGFzc29jX2FyZ3NbJ3R5cGUnXSA9ICR0eXBlOwoJCQl9IGVsc2UgewoJCQkJLy8gV2UgaGFkIGEgJ2NvbmZpZyBnZXQnIHdpdGhvdXQgYSAnPG5hbWU+Jywgc28gYXNzdW1lICdsaXN0JyB3YXMgd2FudGVkLgoJCQkJJGFyZ3NbMV0gPSAnbGlzdCc7CgkJCX0KCQl9CgoJCXJldHVybiBbICRhcmdzLCAkYXNzb2NfYXJncyBdOwoJfQoKCS8qKgoJICogV2hldGhlciBvciBub3QgdGhlIG91dHB1dCBzaG91bGQgYmUgcmVuZGVyZWQgaW4gY29sb3IKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluX2NvbG9yKCkgewoJCXJldHVybiAkdGhpcy0+Y29sb3JpemU7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGluaXRfY29sb3JpemF0aW9uKCkgewoJCWlmICggJ2F1dG8nID09PSAkdGhpcy0+Y29uZmlnWydjb2xvciddICkgewoJCQkkdGhpcy0+Y29sb3JpemUgPSAoICEgVXRpbHNcaXNQaXBlZCgpICYmICEgVXRpbHNcaXNfd2luZG93cygpICk7CgkJfSBlbHNlIHsKCQkJJHRoaXMtPmNvbG9yaXplID0gJHRoaXMtPmNvbmZpZ1snY29sb3InXTsKCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGluaXRfbG9nZ2VyKCkgewoJCWlmICggJHRoaXMtPmNvbmZpZ1sncXVpZXQnXSApIHsKCQkJJGxvZ2dlciA9IG5ldyBMb2dnZXJzXFF1aWV0KCAkdGhpcy0+aW5fY29sb3IoKSApOwoJCX0gZWxzZSB7CgkJCSRsb2dnZXIgPSBuZXcgTG9nZ2Vyc1xSZWd1bGFyKCAkdGhpcy0+aW5fY29sb3IoKSApOwoJCX0KCgkJV1BfQ0xJOjpzZXRfbG9nZ2VyKCAkbG9nZ2VyICk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldF9yZXF1aXJlZF9maWxlcygpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVpcmVkX2ZpbGVzOwoJfQoKCS8qKgoJICogRG8gV29yZFByZXNzIGNvcmUgZmlsZXMgZXhpc3Q/CgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gd3BfZXhpc3RzKCkgewoJCXJldHVybiBmaWxlX2V4aXN0cyggQUJTUEFUSCAuICd3cC1pbmNsdWRlcy92ZXJzaW9uLnBocCcgKTsKCX0KCgkvKioKCSAqIEFyZSBXb3JkUHJlc3MgY29yZSBmaWxlcyByZWFkYWJsZT8KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB3cF9pc19yZWFkYWJsZSgpIHsKCQlyZXR1cm4gaXNfcmVhZGFibGUoIEFCU1BBVEggLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja193cF92ZXJzaW9uKCkgewoJCSR3cF9leGlzdHMgICAgICA9ICR0aGlzLT53cF9leGlzdHMoKTsKCQkkd3BfaXNfcmVhZGFibGUgPSAkdGhpcy0+d3BfaXNfcmVhZGFibGUoKTsKCQlpZiAoICEgJHdwX2V4aXN0cyB8fCAhICR3cF9pc19yZWFkYWJsZSApIHsKCQkJJHRoaXMtPnNob3dfc3lub3BzaXNfaWZfY29tcG9zaXRlX2NvbW1hbmQoKTsKCQkJLy8gSWYgdGhlIGNvbW1hbmQgZG9lc24ndCBleGlzdCB1c2UgYXMgZXJyb3IuCgkJCSRhcmdzICAgICAgICAgICAgICAgICAgID0gJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaGVscCcgXSApID8gYXJyYXlfc2xpY2UoICR0aGlzLT5hcmd1bWVudHMsIDEgKSA6ICR0aGlzLT5hcmd1bWVudHM7CgkJCSRzdWdnZXN0aW9uX29yX2Rpc2FibGVkID0gJHRoaXMtPmZpbmRfY29tbWFuZF90b19ydW4oICRhcmdzICk7CgkJCWlmICggaXNfc3RyaW5nKCAkc3VnZ2VzdGlvbl9vcl9kaXNhYmxlZCApICkgewoJCQkJaWYgKCAhIHByZWdfbWF0Y2goICcvZGlzYWJsZWQgZnJvbSB0aGUgY29uZmlnIGZpbGUuJC8nLCAkc3VnZ2VzdGlvbl9vcl9kaXNhYmxlZCApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIk5vIFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gZm91bmQuIElmIHRoZSBjb21tYW5kICciIC4gaW1wbG9kZSggJyAnLCAkYXJncyApIC4gIicgaXMgaW4gYSBwbHVnaW4gb3IgdGhlbWUsIHBhc3MgLS1wYXRoPWBwYXRoL3RvL3dvcmRwcmVzc2AuIiApOwoJCQkJfQoJCQkJV1BfQ0xJOjplcnJvciggJHN1Z2dlc3Rpb25fb3JfZGlzYWJsZWQgKTsKCQkJfQoKCQkJaWYgKCAkd3BfZXhpc3RzICYmICEgJHdwX2lzX3JlYWRhYmxlICkgewoJCQkJV1BfQ0xJOjplcnJvcigKCQkJCQknSXQgc2VlbXMsIHRoZSBXb3JkUHJlc3MgY29yZSBmaWxlcyBkbyBub3QgaGF2ZSB0aGUgcHJvcGVyIGZpbGUgcGVybWlzc2lvbnMuJwoJCQkJKTsKCQkJfQoJCQlXUF9DTEk6OmVycm9yKAoJCQkJIlRoaXMgZG9lcyBub3Qgc2VlbSB0byBiZSBhIFdvcmRQcmVzcyBpbnN0YWxsYXRpb24uXG4iIC4KCQkJCSdQYXNzIC0tcGF0aD1gcGF0aC90by93b3JkcHJlc3NgIG9yIHJ1biBgd3AgY29yZSBkb3dubG9hZGAuJwoJCQkpOwoJCX0KCgkJZ2xvYmFsICR3cF92ZXJzaW9uOwoJCWluY2x1ZGUgQUJTUEFUSCAuICd3cC1pbmNsdWRlcy92ZXJzaW9uLnBocCc7CgoJCSRtaW5pbXVtX3ZlcnNpb24gPSAnMy43JzsKCgkJaWYgKCB2ZXJzaW9uX2NvbXBhcmUoICR3cF92ZXJzaW9uLCAkbWluaW11bV92ZXJzaW9uLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJXUC1DTEkgbmVlZHMgV29yZFByZXNzICRtaW5pbXVtX3ZlcnNpb24gb3IgbGF0ZXIgdG8gd29yayBwcm9wZXJseS4gIiAuCgkJCQkiVGhlIHZlcnNpb24gY3VycmVudGx5IGluc3RhbGxlZCBpcyAkd3BfdmVyc2lvbi5cbiIgLgoJCQkJJ1RyeSBydW5uaW5nIGB3cCBjb3JlIGRvd25sb2FkIC0tZm9yY2VgLicKCQkJKTsKCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGluaXRfY29uZmlnKCkgewoJCSRjb25maWd1cmF0b3IgPSBXUF9DTEk6OmdldF9jb25maWd1cmF0b3IoKTsKCgkJJGFyZ3YgPSBhcnJheV9zbGljZSggJEdMT0JBTFNbJ2FyZ3YnXSwgMSApOwoKCQkkdGhpcy0+YWxpYXMgPSBudWxsOwoJCWlmICggISBlbXB0eSggJGFyZ3ZbMF0gKSAmJiBwcmVnX21hdGNoKCAnIycgLiBDb25maWd1cmF0b3I6OkFMSUFTX1JFR0VYIC4gJyMnLCAkYXJndlswXSwgJG1hdGNoZXMgKSApIHsKCQkJJHRoaXMtPmFsaWFzID0gYXJyYXlfc2hpZnQoICRhcmd2ICk7CgkJfQoKCQkvLyBGaWxlIGNvbmZpZwoJCXsKCQkJJHRoaXMtPmdsb2JhbF9jb25maWdfcGF0aCAgPSAkdGhpcy0+Z2V0X2dsb2JhbF9jb25maWdfcGF0aCgpOwoJCQkkdGhpcy0+cHJvamVjdF9jb25maWdfcGF0aCA9ICR0aGlzLT5nZXRfcHJvamVjdF9jb25maWdfcGF0aCgpOwoKCQkJJGNvbmZpZ3VyYXRvci0+bWVyZ2VfeW1sKCAkdGhpcy0+Z2xvYmFsX2NvbmZpZ19wYXRoLCAkdGhpcy0+YWxpYXMgKTsKCQkJJGNvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgICA9ICRjb25maWd1cmF0b3ItPnRvX2FycmF5KCk7CgkJCSR0aGlzLT5yZXF1aXJlZF9maWxlc1snZ2xvYmFsJ10gPSAkY29uZmlnWzBdWydyZXF1aXJlJ107CgkJCSRjb25maWd1cmF0b3ItPm1lcmdlX3ltbCggJHRoaXMtPnByb2plY3RfY29uZmlnX3BhdGgsICR0aGlzLT5hbGlhcyApOwoJCQkkY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICA9ICRjb25maWd1cmF0b3ItPnRvX2FycmF5KCk7CgkJCSR0aGlzLT5yZXF1aXJlZF9maWxlc1sncHJvamVjdCddID0gJGNvbmZpZ1swXVsncmVxdWlyZSddOwoJCX0KCgkJLy8gUnVudGltZSBjb25maWcgYW5kIGFyZ3MKCQl7CgkJCWxpc3QoICRhcmdzLCAkYXNzb2NfYXJncywgJHRoaXMtPnJ1bnRpbWVfY29uZmlnICkgPSAkY29uZmlndXJhdG9yLT5wYXJzZV9hcmdzKCAkYXJndiApOwoKCQkJbGlzdCggJHRoaXMtPmFyZ3VtZW50cywgJHRoaXMtPmFzc29jX2FyZ3MgKSA9IHNlbGY6OmJhY2tfY29tcGF0X2NvbnZlcnNpb25zKAoJCQkJJGFyZ3MsCgkJCQkkYXNzb2NfYXJncwoJCQkpOwoKCQkJJGNvbmZpZ3VyYXRvci0+bWVyZ2VfYXJyYXkoICR0aGlzLT5ydW50aW1lX2NvbmZpZyApOwoJCX0KCgkJbGlzdCggJHRoaXMtPmNvbmZpZywgJHRoaXMtPmV4dHJhX2NvbmZpZyApID0gJGNvbmZpZ3VyYXRvci0+dG9fYXJyYXkoKTsKCQkkdGhpcy0+YWxpYXNlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAkY29uZmlndXJhdG9yLT5nZXRfYWxpYXNlcygpOwoJCWlmICggY291bnQoICR0aGlzLT5hbGlhc2VzICkgJiYgISBpc3NldCggJHRoaXMtPmFsaWFzZXNbJ0BhbGwnXSApICkgewoJCQkkdGhpcy0+YWxpYXNlcyAgICAgICAgID0gYXJyYXlfcmV2ZXJzZSggJHRoaXMtPmFsaWFzZXMgKTsKCQkJJHRoaXMtPmFsaWFzZXNbJ0BhbGwnXSA9ICdSdW4gY29tbWFuZCBhZ2FpbnN0IGV2ZXJ5IHJlZ2lzdGVyZWQgYWxpYXMuJzsKCQkJJHRoaXMtPmFsaWFzZXMgICAgICAgICA9IGFycmF5X3JldmVyc2UoICR0aGlzLT5hbGlhc2VzICk7CgkJfQoJCSR0aGlzLT5yZXF1aXJlZF9maWxlc1sncnVudGltZSddID0gJHRoaXMtPmNvbmZpZ1sncmVxdWlyZSddOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfcm9vdCgpIHsKCQlpZiAoICR0aGlzLT5jb25maWdbJ2FsbG93LXJvb3QnXSB8fCBnZXRlbnYoICdXUF9DTElfQUxMT1dfUk9PVCcgKSApIHsKCQkJcmV0dXJuOyAjIHRoZXkncmUgYXdhcmUgb2YgdGhlIHJpc2tzIQoJCX0KCQlpZiAoIGNvdW50KCAkdGhpcy0+YXJndW1lbnRzICkgPj0gMiAmJiAnY2xpJyA9PT0gJHRoaXMtPmFyZ3VtZW50c1swXSAmJiBpbl9hcnJheSggJHRoaXMtPmFyZ3VtZW50c1sxXSwgWyAndXBkYXRlJywgJ2luZm8nIF0sIHRydWUgKSApIHsKCQkJcmV0dXJuOyAjIG1ha2UgaXQgZWFzaWVyIHRvIHVwZGF0ZSByb290LW93bmVkIGNvcGllcwoJCX0KCQlpZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAncG9zaXhfZ2V0ZXVpZCcgKSApIHsKCQkJcmV0dXJuOyAjIHBvc2l4IGZ1bmN0aW9ucyBub3QgYXZhaWxhYmxlCgkJfQoJCWlmICggcG9zaXhfZ2V0ZXVpZCgpICE9PSAwICkgewoJCQlyZXR1cm47ICMgbm90IHJvb3QKCQl9CgoJCVdQX0NMSTo6ZXJyb3IoCgkJCSJZSUtFUyEgSXQgbG9va3MgbGlrZSB5b3UncmUgcnVubmluZyB0aGlzIGFzIHJvb3QuIFlvdSBwcm9iYWJseSBtZWFudCB0byAiIC4KCQkJInJ1biB0aGlzIGFzIHRoZSB1c2VyIHRoYXQgeW91ciBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGV4aXN0cyB1bmRlci5cbiIgLgoJCQkiXG4iIC4KCQkJIklmIHlvdSBSRUFMTFkgbWVhbiB0byBydW4gdGhpcyBhcyByb290LCB3ZSB3b24ndCBzdG9wIHlvdSwgYnV0IGp1c3QgIiAuCgkJCSdiZWFyIGluIG1pbmQgdGhhdCBhbnkgY29kZSBvbiB0aGlzIHNpdGUgd2lsbCB0aGVuIGhhdmUgZnVsbCBjb250cm9sIG9mICcgLgoJCQkieW91ciBzZXJ2ZXIsIG1ha2luZyBpdCBxdWl0ZSBEQU5HRVJPVVMuXG4iIC4KCQkJIlxuIiAuCgkJCSJJZiB5b3UnZCBsaWtlIHRvIGNvbnRpbnVlIGFzIHJvb3QsIHBsZWFzZSBydW4gdGhpcyBhZ2FpbiwgYWRkaW5nIHRoaXMgIiAuCgkJCSJmbGFnOiAgLS1hbGxvdy1yb290XG4iIC4KCQkJIlxuIiAuCgkJCSJJZiB5b3UnZCBsaWtlIHRvIHJ1biBpdCBhcyB0aGUgdXNlciB0aGF0IHRoaXMgc2l0ZSBpcyB1bmRlciwgeW91IGNhbiAiIC4KCQkJInJ1biB0aGUgZm9sbG93aW5nIHRvIGJlY29tZSB0aGUgcmVzcGVjdGl2ZSB1c2VyOlxuIiAuCgkJCSJcbiIgLgoJCQkiICAgIHN1ZG8gLXUgVVNFUiAtaSAtLSB3cCA8Y29tbWFuZD5cbiIgLgoJCQkiXG4iCgkJKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHJ1bl9hbGlhc19ncm91cCggJGFsaWFzZXMgKSB7CgkJVXRpbHNcY2hlY2tfcHJvY19hdmFpbGFibGUoICdncm91cCBhbGlhcycgKTsKCgkJJHBocF9iaW4gPSBlc2NhcGVzaGVsbGFyZyggVXRpbHNcZ2V0X3BocF9iaW5hcnkoKSApOwoKCQkkc2NyaXB0X3BhdGggPSAkR0xPQkFMU1snYXJndiddWzBdOwoKCQlpZiAoIGdldGVudiggJ1dQX0NMSV9DT05GSUdfUEFUSCcgKSApIHsKCQkJJGNvbmZpZ19wYXRoID0gZ2V0ZW52KCAnV1BfQ0xJX0NPTkZJR19QQVRIJyApOwoJCX0gZWxzZSB7CgkJCSRjb25maWdfcGF0aCA9IFV0aWxzXGdldF9ob21lX2RpcigpIC4gJy8ud3AtY2xpL2NvbmZpZy55bWwnOwoJCX0KCQkkY29uZmlnX3BhdGggPSBlc2NhcGVzaGVsbGFyZyggJGNvbmZpZ19wYXRoICk7CgoJCWZvcmVhY2ggKCAkYWxpYXNlcyBhcyAkYWxpYXMgKSB7CgkJCVdQX0NMSTo6bG9nKCAkYWxpYXMgKTsKCQkJJGFyZ3MgICAgICAgICAgID0gaW1wbG9kZSggJyAnLCBhcnJheV9tYXAoICdlc2NhcGVzaGVsbGFyZycsICR0aGlzLT5hcmd1bWVudHMgKSApOwoJCQkkYXNzb2NfYXJncyAgICAgPSBVdGlsc1xhc3NvY19hcmdzX3RvX3N0ciggJHRoaXMtPmFzc29jX2FyZ3MgKTsKCQkJJHJ1bnRpbWVfY29uZmlnID0gVXRpbHNcYXNzb2NfYXJnc190b19zdHIoICR0aGlzLT5ydW50aW1lX2NvbmZpZyApOwoJCQkkZnVsbF9jb21tYW5kICAgPSAiV1BfQ0xJX0NPTkZJR19QQVRIPXskY29uZmlnX3BhdGh9IHskcGhwX2Jpbn0geyRzY3JpcHRfcGF0aH0geyRhbGlhc30geyRhcmdzfXskYXNzb2NfYXJnc317JHJ1bnRpbWVfY29uZmlnfSI7CgkJCSRwaXBlcyAgICAgICAgICA9IFtdOwoJCQkkcHJvYyAgICAgICAgICAgPSBVdGlsc1xwcm9jX29wZW5fY29tcGF0KCAkZnVsbF9jb21tYW5kLCBbIFNURElOLCBTVERPVVQsIFNUREVSUiBdLCAkcGlwZXMgKTsKCQkJcHJvY19jbG9zZSggJHByb2MgKTsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzZXRfYWxpYXMoICRhbGlhcyApIHsKCQkkb3JpZ19jb25maWcgID0gJHRoaXMtPmNvbmZpZzsKCQkkYWxpYXNfY29uZmlnID0gJHRoaXMtPmFsaWFzZXNbICRhbGlhcyBdOwoJCSR0aGlzLT5jb25maWcgPSBhcnJheV9tZXJnZSggJG9yaWdfY29uZmlnLCAkYWxpYXNfY29uZmlnICk7CgkJZm9yZWFjaCAoICRhbGlhc19jb25maWcgYXMgJGtleSA9PiAkXyApIHsKCQkJaWYgKCBpc3NldCggJG9yaWdfY29uZmlnWyAka2V5IF0gKSAmJiAhIGlzX251bGwoICRvcmlnX2NvbmZpZ1sgJGtleSBdICkgKSB7CgkJCQkkdGhpcy0+YXNzb2NfYXJnc1sgJGtleSBdID0gJG9yaWdfY29uZmlnWyAka2V5IF07CgkJCX0KCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHN0YXJ0KCkgewoJCS8vIEVuYWJsZSBQSFAgZXJyb3IgcmVwb3J0aW5nIHRvIHN0ZGVyciBpZiB0ZXN0aW5nLiBXaWxsIG5lZWQgdG8gYmUgcmUtZW5hYmxlZCBhZnRlciBXUCBsb2Fkcy4KCQlpZiAoIGdldGVudiggJ0JFSEFUX1JVTicgKSApIHsKCQkJJHRoaXMtPmVuYWJsZV9lcnJvcl9yZXBvcnRpbmcoKTsKCQl9CgoJCVdQX0NMSTo6ZGVidWcoICR0aGlzLT5nbG9iYWxfY29uZmlnX3BhdGhfZGVidWcsICdib290c3RyYXAnICk7CgkJV1BfQ0xJOjpkZWJ1ZyggJHRoaXMtPnByb2plY3RfY29uZmlnX3BhdGhfZGVidWcsICdib290c3RyYXAnICk7CgkJV1BfQ0xJOjpkZWJ1ZyggJ2FyZ3Y6ICcgLiBpbXBsb2RlKCAnICcsICRHTE9CQUxTWydhcmd2J10gKSwgJ2Jvb3RzdHJhcCcgKTsKCgkJJHRoaXMtPmNoZWNrX3Jvb3QoKTsKCQlpZiAoICR0aGlzLT5hbGlhcyApIHsKCQkJaWYgKCAnQGFsbCcgPT09ICR0aGlzLT5hbGlhcyAmJiAhIGlzc2V0KCAkdGhpcy0+YWxpYXNlc1snQGFsbCddICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ2Fubm90IHVzZSAnQGFsbCcgd2hlbiBubyBhbGlhc2VzIGFyZSByZWdpc3RlcmVkLiIgKTsKCQkJfQoKCQkJaWYgKCAnQGFsbCcgPT09ICR0aGlzLT5hbGlhcyAmJiBpc19zdHJpbmcoICR0aGlzLT5hbGlhc2VzWydAYWxsJ10gKSApIHsKCQkJCSRhbGlhc2VzID0gYXJyYXlfa2V5cyggJHRoaXMtPmFsaWFzZXMgKTsKCQkJCSRrICAgICAgID0gYXJyYXlfc2VhcmNoKCAnQGFsbCcsICRhbGlhc2VzLCB0cnVlICk7CgkJCQl1bnNldCggJGFsaWFzZXNbICRrIF0gKTsKCQkJCSR0aGlzLT5ydW5fYWxpYXNfZ3JvdXAoICRhbGlhc2VzICk7CgkJCQlleGl0OwoJCQl9CgoJCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJHRoaXMtPmFsaWFzLCAkdGhpcy0+YWxpYXNlcyApICkgewoJCQkJJGVycm9yX21zZyAgPSAiQWxpYXMgJ3skdGhpcy0+YWxpYXN9JyBub3QgZm91bmQuIjsKCQkJCSRzdWdnZXN0aW9uID0gVXRpbHNcZ2V0X3N1Z2dlc3Rpb24oICR0aGlzLT5hbGlhcywgYXJyYXlfa2V5cyggJHRoaXMtPmFsaWFzZXMgKSwgJHRocmVzaG9sZCA9IDIgKTsKCQkJCWlmICggJHN1Z2dlc3Rpb24gKSB7CgkJCQkJJGVycm9yX21zZyAuPSBQSFBfRU9MIC4gIkRpZCB5b3UgbWVhbiAneyRzdWdnZXN0aW9ufSc/IjsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoICRlcnJvcl9tc2cgKTsKCQkJfQoJCQkvLyBOdW1lcmljYWxseSBpbmRleGVkIG1lYW5zIGEgZ3JvdXAgb2YgYWxpYXNlcwoJCQlpZiAoIGlzc2V0KCAkdGhpcy0+YWxpYXNlc1sgJHRoaXMtPmFsaWFzIF1bMF0gKSApIHsKCQkJCSRncm91cF9hbGlhc2VzID0gJHRoaXMtPmFsaWFzZXNbICR0aGlzLT5hbGlhcyBdOwoJCQkJJGFsbF9hbGlhc2VzICAgPSBhcnJheV9rZXlzKCAkdGhpcy0+YWxpYXNlcyApOwoJCQkJJGRpZmYgICAgICAgICAgPSBhcnJheV9kaWZmKCAkZ3JvdXBfYWxpYXNlcywgJGFsbF9hbGlhc2VzICk7CgkJCQlpZiAoICEgZW1wdHkoICRkaWZmICkgKSB7CgkJCQkJV1BfQ0xJOjplcnJvciggIkdyb3VwICd7JHRoaXMtPmFsaWFzfScgY29udGFpbnMgb25lIG9yIG1vcmUgaW52YWxpZCBhbGlhc2VzOiAiIC4gaW1wbG9kZSggJywgJywgJGRpZmYgKSApOwoJCQkJfQoJCQkJJHRoaXMtPnJ1bl9hbGlhc19ncm91cCggJGdyb3VwX2FsaWFzZXMgKTsKCQkJCWV4aXQ7CgkJCX0KCgkJCSR0aGlzLT5zZXRfYWxpYXMoICR0aGlzLT5hbGlhcyApOwoJCX0KCgkJaWYgKCBlbXB0eSggJHRoaXMtPmFyZ3VtZW50cyApICkgewoJCQkkdGhpcy0+YXJndW1lbnRzW10gPSAnaGVscCc7CgkJfQoKCQkvLyBQcm90ZWN0ICdjbGkgaW5mbycgZnJvbSBtb3N0IG9mIHRoZSBydW50aW1lLAoJCS8vIGV4Y2VwdCB3aGVuIHRoZSBjb21tYW5kIHdpbGwgYmUgcnVuIG92ZXIgU1NICgkJaWYgKCAnY2xpJyA9PT0gJHRoaXMtPmFyZ3VtZW50c1swXSAmJiAhIGVtcHR5KCAkdGhpcy0+YXJndW1lbnRzWzFdICkgJiYgJ2luZm8nID09PSAkdGhpcy0+YXJndW1lbnRzWzFdICYmICEgJHRoaXMtPmNvbmZpZ1snc3NoJ10gKSB7CgkJCSR0aGlzLT5ydW5fY29tbWFuZF9hbmRfZXhpdCgpOwoJCX0KCgkJaWYgKCBpc3NldCggJHRoaXMtPmNvbmZpZ1snaHR0cCddICkgJiYgISBjbGFzc19leGlzdHMoICdcV1BfUkVTVF9DTElcUnVubmVyJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiUkVTVGZ1bCBXUC1DTEkgbmVlZHMgdG8gYmUgaW5zdGFsbGVkLiBUcnkgJ3dwIHBhY2thZ2UgaW5zdGFsbCB3cC1jbGkvcmVzdGZ1bCcuIiApOwoJCX0KCgkJaWYgKCAkdGhpcy0+Y29uZmlnWydzc2gnXSApIHsKCQkJJHRoaXMtPnJ1bl9zc2hfY29tbWFuZCggJHRoaXMtPmNvbmZpZ1snc3NoJ10gKTsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gSGFuZGxlIC0tcGF0aCBwYXJhbWV0ZXIKCQlzZWxmOjpzZXRfd3Bfcm9vdCggJHRoaXMtPmZpbmRfd3Bfcm9vdCgpICk7CgoJCS8vIEZpcnN0IHRyeSBhdCBzaG93aW5nIG1hbiBwYWdlIC0gaWYgaGVscCBjb21tYW5kIGFuZCBlaXRoZXIgaGF2ZW4ndCBmb3VuZCAndmVyc2lvbi5waHAnIG9yICd3cC1jb25maWcucGhwJyAoc28gd29uJ3QgYmUgbG9hZGluZyBXUCAmIGFkZGluZyBjb21tYW5kcykgb3IgaGVscCBvbiBzdWJjb21tYW5kLgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaGVscCcgXSApCgkJCSYmICggISAkdGhpcy0+d3BfZXhpc3RzKCkKCQkJCXx8ICEgVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpCgkJCQl8fCBjb3VudCggJHRoaXMtPmFyZ3VtZW50cyApID4gMgoJCQkpICkgewoJCQkkdGhpcy0+YXV0b19jaGVja191cGRhdGUoKTsKCQkJJHRoaXMtPnJ1bl9jb21tYW5kKCAkdGhpcy0+YXJndW1lbnRzLCAkdGhpcy0+YXNzb2NfYXJncyApOwoJCQkvLyBIZWxwIGRpZG4ndCBleGl0IHNvIGZhaWxlZCB0byBmaW5kIHRoZSBjb21tYW5kIGF0IHRoaXMgc3RhZ2UuCgkJfQoKCQkvLyBIYW5kbGUgLS11cmwgcGFyYW1ldGVyCgkJJHVybCA9IHNlbGY6Omd1ZXNzX3VybCggJHRoaXMtPmNvbmZpZyApOwoJCWlmICggJHVybCApIHsKCQkJV1BfQ0xJOjpzZXRfdXJsKCAkdXJsICk7CgkJfQoKCQkkdGhpcy0+ZG9fZWFybHlfaW52b2tlKCAnYmVmb3JlX3dwX2xvYWQnICk7CgoJCSR0aGlzLT5jaGVja193cF92ZXJzaW9uKCk7CgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnY29uZmlnJywgJ2NyZWF0ZScgXSApICkgewoJCQkkdGhpcy0+cnVuX2NvbW1hbmRfYW5kX2V4aXQoKTsKCQl9CgoJCWlmICggISBVdGlsc1xsb2NhdGVfd3BfY29uZmlnKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkiJ3dwLWNvbmZpZy5waHAnIG5vdCBmb3VuZC5cbiIgLgoJCQkJJ0VpdGhlciBjcmVhdGUgb25lIG1hbnVhbGx5IG9yIHVzZSBgd3AgY29uZmlnIGNyZWF0ZWAuJwoJCQkpOwoJCX0KCgkJLyoKCQkgKiBTZXQgdGhlIE15U1FMaSBlcnJvciByZXBvcnRpbmcgb2ZmIGJlY2F1c2UgV29yZFByZXNzIGhhbmRsZXMgaXRzIG93bi4KCQkgKiBUaGlzIGlzIGR1ZSB0byB0aGUgZGVmYXVsdCB2YWx1ZSBjaGFuZ2UgZnJvbSBgTVlTUUxJX1JFUE9SVF9PRkZgCgkJICogdG8gYE1ZU1FMSV9SRVBPUlRfRVJST1J8TVlTUUxJX1JFUE9SVF9TVFJJQ1RgIGluIFBIUCA4LjEuCgkJICovCgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdteXNxbGlfcmVwb3J0JyApICkgewoJCQlteXNxbGlfcmVwb3J0KCAwICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUmVzdHJpY3RlZEZ1bmN0aW9ucy5teXNxbF9teXNxbGlfcmVwb3J0CgkJfQoKCQkvLyBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkQ29uc3RhbnRGb3VuZCAtLSBEZWNsYXJpbmcgV1AgbmF0aXZlIGNvbnN0YW50cy4KCgkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdjb3JlJywgJ2lzLWluc3RhbGxlZCcgXSApCgkJCXx8ICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2NvcmUnLCAndXBkYXRlLWRiJyBdICkgKSB7CgkJCWRlZmluZSggJ1dQX0lOU1RBTExJTkcnLCB0cnVlICk7CgkJfQoKCQlpZiAoCgkJCWNvdW50KCAkdGhpcy0+YXJndW1lbnRzICkgPj0gMiAmJgoJCQknY29yZScgPT09ICR0aGlzLT5hcmd1bWVudHNbMF0gJiYKCQkJaW5fYXJyYXkoICR0aGlzLT5hcmd1bWVudHNbMV0sIFsgJ2luc3RhbGwnLCAnbXVsdGlzaXRlLWluc3RhbGwnIF0sIHRydWUgKQoJCSkgewoJCQlkZWZpbmUoICdXUF9JTlNUQUxMSU5HJywgdHJ1ZSApOwoKCQkJLy8gV2UgcmVhbGx5IG5lZWQgYSBVUkwgaGVyZQoJCQlpZiAoICEgaXNzZXQoICRfU0VSVkVSWydIVFRQX0hPU1QnXSApICkgewoJCQkJJHVybCA9ICdodHRwczovL2V4YW1wbGUuY29tJzsKCQkJCVdQX0NMSTo6c2V0X3VybCggJHVybCApOwoJCQl9CgoJCQlpZiAoICdtdWx0aXNpdGUtaW5zdGFsbCcgPT09ICR0aGlzLT5hcmd1bWVudHNbMV0gKSB7CgkJCQkvLyBuZWVkIHRvIGZha2Ugc29tZSBnbG9iYWxzIHRvIHNraXAgdGhlIGNoZWNrcyBpbiB3cC1pbmNsdWRlcy9tcy1zZXR0aW5ncy5waHAKCQkJCSR1cmxfcGFydHMgPSBVdGlsc1xwYXJzZV91cmwoICR1cmwgKTsKCQkJCXNlbGY6OmZha2VfY3VycmVudF9zaXRlX2Jsb2coICR1cmxfcGFydHMgKTsKCgkJCQlpZiAoICEgZGVmaW5lZCggJ0NPT0tJRUhBU0gnICkgKSB7CgkJCQkJZGVmaW5lKCAnQ09PS0lFSEFTSCcsIG1kNSggJHVybF9wYXJ0c1snaG9zdCddICkgKTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdpbXBvcnQnIF0gKSApIHsKCQkJZGVmaW5lKCAnV1BfTE9BRF9JTVBPUlRFUlMnLCB0cnVlICk7CgkJCWRlZmluZSggJ1dQX0lNUE9SVElORycsIHRydWUgKTsKCQl9CgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnY3JvbicsICdldmVudCcsICdydW4nIF0gKSApIHsKCQkJZGVmaW5lKCAnRE9JTkdfQ1JPTicsIHRydWUgKTsKCQl9CgkJLy8gcGhwY3M6ZW5hYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkQ29uc3RhbnRGb3VuZAoKCQkkdGhpcy0+bG9hZF93b3JkcHJlc3MoKTsKCgkJJHRoaXMtPnJ1bl9jb21tYW5kX2FuZF9leGl0KCk7CgoJfQoKCS8qKgoJICogTG9hZCBXb3JkUHJlc3MsIGlmIGl0IGhhc24ndCBhbHJlYWR5IGJlZW4gbG9hZGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsb2FkX3dvcmRwcmVzcygpIHsKCQlzdGF0aWMgJHdwX2NsaV9pc19sb2FkZWQ7CgkJLy8gR2xvYmFscyBub3QgZXhwbGljaXRseSBnbG9iYWxpemVkIGluIFdvcmRQcmVzcwoJCWdsb2JhbCAkc2l0ZV9pZCwgJHdwZGIsICRwdWJsaWMsICRjdXJyZW50X3NpdGUsICRjdXJyZW50X2Jsb2csICRwYXRoLCAkc2hvcnRjb2RlX3RhZ3M7CgoJCWlmICggISBlbXB0eSggJHdwX2NsaV9pc19sb2FkZWQgKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHdwX2NsaV9pc19sb2FkZWQgPSB0cnVlOwoKCQkvLyBIYW5kbGUgLS1jb250ZXh0IGZsYWcuCgkJJHRoaXMtPmNvbnRleHRfbWFuYWdlci0+c3dpdGNoX2NvbnRleHQoICR0aGlzLT5jb25maWcgKTsKCgkJV1BfQ0xJOjpkZWJ1ZyggJ0JlZ2luIFdvcmRQcmVzcyBsb2FkJywgJ2Jvb3RzdHJhcCcgKTsKCQlXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfd3BfbG9hZCcgKTsKCgkJJHRoaXMtPmNoZWNrX3dwX3ZlcnNpb24oKTsKCgkJJHdwX2NvbmZpZ19wYXRoID0gVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpOwoJCWlmICggISAkd3BfY29uZmlnX3BhdGggKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkiJ3dwLWNvbmZpZy5waHAnIG5vdCBmb3VuZC5cbiIgLgoJCQkJJ0VpdGhlciBjcmVhdGUgb25lIG1hbnVhbGx5IG9yIHVzZSBgd3AgY29uZmlnIGNyZWF0ZWAuJwoJCQkpOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ3dwLWNvbmZpZy5waHAgcGF0aDogJyAuICR3cF9jb25maWdfcGF0aCwgJ2Jvb3RzdHJhcCcgKTsKCQlXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfd3BfY29uZmlnX2xvYWQnICk7CgoJCS8vIExvYWQgd3AtY29uZmlnLnBocCBjb2RlLCBpbiB0aGUgZ2xvYmFsIHNjb3BlCgkJJHdwX2NsaV9vcmlnaW5hbF9kZWZpbmVkX3ZhcnMgPSBnZXRfZGVmaW5lZF92YXJzKCk7CgoJCWV2YWwoICR0aGlzLT5nZXRfd3BfY29uZmlnX2NvZGUoKSApOyAvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkV2YWwuRGlzY291cmFnZWQKCgkJZm9yZWFjaCAoIGdldF9kZWZpbmVkX3ZhcnMoKSBhcyAka2V5ID0+ICR2YXIgKSB7CgkJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJGtleSwgJHdwX2NsaV9vcmlnaW5hbF9kZWZpbmVkX3ZhcnMgKSB8fCAnd3BfY2xpX29yaWdpbmFsX2RlZmluZWRfdmFycycgPT09ICRrZXkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuVmFyaWFibGVzLkZvcmJpZGRlbkdsb2JhbFZhcmlhYmxlVmFyaWFibGUuTm9uQmFyZVZhcmlhYmxlRm91bmQKCQkJZ2xvYmFsICR7JGtleX07CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZFZhcmlhYmxlRm91bmQKCQkJJHska2V5fSA9ICR2YXI7CgkJfQoKCQkkdGhpcy0+bWF5YmVfdXBkYXRlX3VybF9mcm9tX2RvbWFpbl9jb25zdGFudCgpOwoJCVdQX0NMSTo6ZG9faG9vayggJ2FmdGVyX3dwX2NvbmZpZ19sb2FkJyApOwoJCSR0aGlzLT5kb19lYXJseV9pbnZva2UoICdhZnRlcl93cF9jb25maWdfbG9hZCcgKTsKCgkJLy8gUHJldmVudCBlcnJvciBub3RpY2UgZnJvbSB3cF9ndWVzc191cmwoKSB3aGVuIGNvcmUgaXNuJ3QgaW5zdGFsbGVkCgkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdjb3JlJywgJ2lzLWluc3RhbGxlZCcgXSApCgkJCSYmICEgZGVmaW5lZCggJ0NPT0tJRUhBU0gnICkgKSB7CgkJCWRlZmluZSggJ0NPT0tJRUhBU0gnLCBtZDUoICd3cC1jbGknICkgKTsKCQl9CgoJCS8vIExvYWQgV1AtQ0xJIHV0aWxpdGllcwoJCXJlcXVpcmUgV1BfQ0xJX1JPT1QgLiAnL3BocC91dGlscy13cC5waHAnOwoKCQkvLyBTZXQgdXAgV29yZFByZXNzIGJvb3RzdHJhcCBhY3Rpb25zIGFuZCBmaWx0ZXJzCgkJJHRoaXMtPnNldHVwX2Jvb3RzdHJhcF9ob29rcygpOwoKCQkvLyBMb2FkIENvcmUsIG11LXBsdWdpbnMsIHBsdWdpbnMsIHRoZW1lcyBldGMuCgkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjYtYWxwaGEtMzc1NzUnLCAnPj0nICkgKSB7CgkJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaGVscCcgXSApICkgewoJCQkJLy8gSGFjazogZGVmaW5lIGBXUF9ERUJVR2AgYW5kIGBXUF9ERUJVR19ESVNQTEFZYCB0byBnZXQgYHdwZGI6OmJhaWwoKWAgdG8gYHdwX2RpZSgpYC4KCQkJCWlmICggISBkZWZpbmVkKCAnV1BfREVCVUcnICkgKSB7CgkJCQkJZGVmaW5lKCAnV1BfREVCVUcnLCB0cnVlICk7CgkJCQl9CgkJCQlpZiAoICEgZGVmaW5lZCggJ1dQX0RFQlVHX0RJU1BMQVknICkgKSB7CgkJCQkJZGVmaW5lKCAnV1BfREVCVUdfRElTUExBWScsIHRydWUgKTsKCQkJCX0KCQkJfQoJCQlyZXF1aXJlIEFCU1BBVEggLiAnd3Atc2V0dGluZ3MucGhwJzsKCQl9IGVsc2UgewoJCQlyZXF1aXJlIFdQX0NMSV9ST09UIC4gJy9waHAvd3Atc2V0dGluZ3MtY2xpLnBocCc7CgkJfQoKCQkvLyBGaXggbWVtb3J5IGxpbWl0LiBTZWUgaHR0cHM6Ly9jb3JlLnRyYWMud29yZHByZXNzLm9yZy90aWNrZXQvMTQ4ODkKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5JbmlTZXQubWVtb3J5X2xpbWl0X0JsYWNrbGlzdGVkIC0tIFRoaXMgaXMgcGVyZmVjdGx5IGZpbmUgZm9yIENMSSB1c2FnZS4KCQlpbmlfc2V0KCAnbWVtb3J5X2xpbWl0JywgLTEgKTsKCgkJLy8gTG9hZCBhbGwgdGhlIGFkbWluIEFQSXMsIGZvciBjb252ZW5pZW5jZQoJCXJlcXVpcmUgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy9hZG1pbi5waHAnOwoKCQlhZGRfZmlsdGVyKAoJCQknZmlsZXN5c3RlbV9tZXRob2QnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJcmV0dXJuICdkaXJlY3QnOwoJCQl9LAoJCQk5OQoJCSk7CgoJCS8vIFJlLWVuYWJsZSBQSFAgZXJyb3IgcmVwb3J0aW5nIHRvIHN0ZGVyciBpZiB0ZXN0aW5nLgoJCWlmICggZ2V0ZW52KCAnQkVIQVRfUlVOJyApICkgewoJCQkkdGhpcy0+ZW5hYmxlX2Vycm9yX3JlcG9ydGluZygpOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ0xvYWRlZCBXb3JkUHJlc3MnLCAnYm9vdHN0cmFwJyApOwoJCVdQX0NMSTo6ZG9faG9vayggJ2FmdGVyX3dwX2xvYWQnICk7CgoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGZha2VfY3VycmVudF9zaXRlX2Jsb2coICR1cmxfcGFydHMgKSB7CgkJZ2xvYmFsICRjdXJyZW50X3NpdGUsICRjdXJyZW50X2Jsb2c7CgoJCWlmICggISBpc3NldCggJHVybF9wYXJ0c1sncGF0aCddICkgKSB7CgkJCSR1cmxfcGFydHNbJ3BhdGgnXSA9ICcvJzsKCQl9CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBJbnRlbnRpb25hbCBvdmVycmlkZS4KCQkkY3VycmVudF9zaXRlID0gKG9iamVjdCkgWwoJCQknaWQnICAgICAgICAgICAgPT4gMSwKCQkJJ2Jsb2dfaWQnICAgICAgID0+IDEsCgkJCSdkb21haW4nICAgICAgICA9PiAkdXJsX3BhcnRzWydob3N0J10sCgkJCSdwYXRoJyAgICAgICAgICA9PiAkdXJsX3BhcnRzWydwYXRoJ10sCgkJCSdjb29raWVfZG9tYWluJyA9PiAkdXJsX3BhcnRzWydob3N0J10sCgkJCSdzaXRlX25hbWUnICAgICA9PiAnV29yZFByZXNzJywKCQldOwoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gSW50ZW50aW9uYWwgb3ZlcnJpZGUuCgkJJGN1cnJlbnRfYmxvZyA9IChvYmplY3QpIFsKCQkJJ2Jsb2dfaWQnICA9PiAxLAoJCQknc2l0ZV9pZCcgID0+IDEsCgkJCSdkb21haW4nICAgPT4gJHVybF9wYXJ0c1snaG9zdCddLAoJCQkncGF0aCcgICAgID0+ICR1cmxfcGFydHNbJ3BhdGgnXSwKCQkJJ3B1YmxpYycgICA9PiAnMScsCgkJCSdhcmNoaXZlZCcgPT4gJzAnLAoJCQknbWF0dXJlJyAgID0+ICcwJywKCQkJJ3NwYW0nICAgICA9PiAnMCcsCgkJCSdkZWxldGVkJyAgPT4gJzAnLAoJCQknbGFuZ19pZCcgID0+ICcwJywKCQldOwoJfQoKCS8qKgoJICogQ2FsbGVkIGFmdGVyIHdwLWNvbmZpZy5waHAgaXMgZXZhbCdkLCB0byBwb3RlbnRpYWxseSByZXNldCBgLS11cmxgCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gbWF5YmVfdXBkYXRlX3VybF9mcm9tX2RvbWFpbl9jb25zdGFudCgpIHsKCQlpZiAoICEgZW1wdHkoICR0aGlzLT5jb25maWdbJ3VybCddICkgfHwgISBlbXB0eSggJHRoaXMtPmNvbmZpZ1snYmxvZyddICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggZGVmaW5lZCggJ0RPTUFJTl9DVVJSRU5UX1NJVEUnICkgKSB7CgkJCSR1cmwgPSBET01BSU5fQ1VSUkVOVF9TSVRFOwoJCQlpZiAoIGRlZmluZWQoICdQQVRIX0NVUlJFTlRfU0lURScgKSApIHsKCQkJCSR1cmwgLj0gUEFUSF9DVVJSRU5UX1NJVEU7CgkJCX0KCQkJV1BfQ0xJOjpzZXRfdXJsKCAkdXJsICk7CgkJfQoJfQoKCS8qKgoJICogU2V0IHVwIGhvb2tzIG1lYW50IHRvIHJ1biBkdXJpbmcgdGhlIFdvcmRQcmVzcyBib290c3RyYXAgcHJvY2VzcwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHNldHVwX2Jvb3RzdHJhcF9ob29rcygpIHsKCgkJaWYgKCAkdGhpcy0+Y29uZmlnWydza2lwLXBsdWdpbnMnXSApIHsKCQkJJHRoaXMtPnNldHVwX3NraXBfcGx1Z2luc19maWx0ZXJzKCk7CgkJfQoKCQlpZiAoICR0aGlzLT5jb25maWdbJ3NraXAtdGhlbWVzJ10gKSB7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soICdzZXR1cF90aGVtZScsIFsgJHRoaXMsICdhY3Rpb25fc2V0dXBfdGhlbWVfd3BfY2xpX3NraXBfdGhlbWVzJyBdLCA5OTkgKTsKCQl9CgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaGVscCcgXSApICkgewoJCQkvLyBUcnkgdG8gdHJhcCBlcnJvcnMgb24gaGVscC4KCQkJJGhlbHBfaGFuZGxlciA9IFsgJHRoaXMsICdoZWxwX3dwX2RpZV9oYW5kbGVyJyBdOyAvLyBBdm9pZCBhbnkgY3Jvc3MgUEhQIHZlcnNpb24gaXNzdWVzIGJ5IG5vdCB1c2luZyAkdGhpcyBpbiBhbm9uIGZ1bmN0aW9uLgoJCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQkJJ3dwX2RpZV9oYW5kbGVyJywKCQkJCWZ1bmN0aW9uICgpIHVzZSAoICRoZWxwX2hhbmRsZXIgKSB7CgkJCQkJcmV0dXJuICRoZWxwX2hhbmRsZXI7CgkJCQl9CgkJCSk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJCSd3cF9kaWVfaGFuZGxlcicsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJCXJldHVybiAnXFdQX0NMSVxVdGlsc1x3cF9kaWVfaGFuZGxlcic7CgkJCQl9CgkJCSk7CgkJfQoKCQkvLyBQcmV2ZW50IGNvZGUgZnJvbSBwZXJmb3JtaW5nIGEgcmVkaXJlY3QKCQlXUF9DTEk6OmFkZF93cF9ob29rKCAnd3BfcmVkaXJlY3QnLCAnV1BfQ0xJXFxVdGlsc1xcd3BfcmVkaXJlY3RfaGFuZGxlcicgKTsKCgkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJJ25vY2FjaGVfaGVhZGVycycsCgkJCXN0YXRpYyBmdW5jdGlvbiAoICRoZWFkZXJzICkgewoJCQkJLy8gV29yZFByZXNzIG1pZ2h0IGJlIGNhbGxpbmcgbm9jYWNoZV9oZWFkZXJzKCkgYmVjYXVzZSBvZiBhIGRlYWQgZGIKCQkJCWdsb2JhbCAkd3BkYjsKCQkJCWlmICggISBlbXB0eSggJHdwZGItPmVycm9yICkgKSB7CgkJCQkJVXRpbHNcd3BfZGllX2hhbmRsZXIoICR3cGRiLT5lcnJvciApOwoJCQkJfQoJCQkJLy8gT3RoZXJ3aXNlLCBXUCBtaWdodCBiZSBjYWxsaW5nIG5vY2FjaGVfaGVhZGVycygpIGJlY2F1c2UgV1AgaXNuJ3QgaW5zdGFsbGVkCgkJCQlVdGlsc1x3cF9ub3RfaW5zdGFsbGVkKCk7CgkJCQlyZXR1cm4gJGhlYWRlcnM7CgkJCX0KCQkpOwoKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknc2V0dXBfdGhlbWUnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJLy8gUG9seWZpbGwgaXNfY3VzdG9taXplX3ByZXZpZXcoKSwgYXMgaXQgaXMgbmVlZGVkIGJ5IFR3ZW50eVR3ZW50eSB0bwoJCQkJLy8gY2hlY2sgZm9yIHN0YXJ0ZXIgY29udGVudC4KCQkJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICdpc19jdXN0b21pemVfcHJldmlldycgKSApIHsKCQkJCQlmdW5jdGlvbiBpc19jdXN0b21pemVfcHJldmlldygpIHsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfSwKCQkJMAoJCSk7CgoJCS8vIEFMVEVSTkFURV9XUF9DUk9OIG1pZ2h0IHRyaWdnZXIgYSByZWRpcmVjdCwgd2hpY2ggd2UgY2FuJ3QgaGFuZGxlCgkJaWYgKCBkZWZpbmVkKCAnQUxURVJOQVRFX1dQX0NST04nICkgJiYgQUxURVJOQVRFX1dQX0NST04gKSB7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCQknbXVwbHVnaW5zX2xvYWRlZCcsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJCXJlbW92ZV9hY3Rpb24oICdpbml0JywgJ3dwX2Nyb24nICk7CgkJCQl9CgkJCSk7CgkJfQoKCQkvLyBHZXQgcmlkIG9mIHdhcm5pbmdzIHdoZW4gY29udmVydGluZyBzaW5nbGUgc2l0ZSB0byBtdWx0aXNpdGUKCQlpZiAoIGRlZmluZWQoICdXUF9JTlNUQUxMSU5HJyApICYmICR0aGlzLT5pc19tdWx0aXNpdGUoKSApIHsKCQkJJHZhbHVlcyA9IFsKCQkJCSdtc19maWxlc19yZXdyaXRpbmcnICAgICAgICAgICAgID0+IG51bGwsCgkJCQknYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMnICAgICAgICA9PiBbXSwKCQkJCSdfc2l0ZV90cmFuc2llbnRfdXBkYXRlX2NvcmUnICAgID0+IG51bGwsCgkJCQknX3NpdGVfdHJhbnNpZW50X3VwZGF0ZV90aGVtZXMnICA9PiBudWxsLAoJCQkJJ19zaXRlX3RyYW5zaWVudF91cGRhdGVfcGx1Z2lucycgPT4gbnVsbCwKCQkJCSdXUExBTkcnICAgICAgICAgICAgICAgICAgICAgICAgID0+ICcnLAoJCQldOwoJCQlmb3JlYWNoICggJHZhbHVlcyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCQkJInByZV9zaXRlX29wdGlvbl8ka2V5IiwKCQkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgdXNlICggJHZhbHVlcywgJGtleSApIHsKCQkJCQkJcmV0dXJuICR2YWx1ZXNbICRrZXkgXTsKCQkJCQl9CgkJCQkpOwoJCQl9CgkJfQoKCQkvLyBBbHdheXMgcGVybWl0IG9wZXJhdGlvbnMgYWdhaW5zdCBzaXRlcywgcmVnYXJkbGVzcyBvZiBzdGF0dXMKCQlXUF9DTEk6OmFkZF93cF9ob29rKCAnbXNfc2l0ZV9jaGVjaycsICdfX3JldHVybl90cnVlJyApOwoKCQkvLyBBbHdheXMgcGVybWl0IG9wZXJhdGlvbnMgYWdhaW5zdCBXb3JkUHJlc3MsIHJlZ2FyZGxlc3Mgb2YgbWFpbnRlbmFuY2UgbW9kZQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdlbmFibGVfbWFpbnRlbmFuY2VfbW9kZScsCgkJCXN0YXRpYyBmdW5jdGlvbiAoKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkpOwoKCQkvLyBVc2Ugb3VyIG93biBkZWJ1ZyBtb2RlIGhhbmRsaW5nIGluc3RlYWQgb2YgV1AgY29yZQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdlbmFibGVfd3BfZGVidWdfbW9kZV9jaGVja3MnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkcmV0ICkgewoJCQkJVXRpbHNcd3BfZGVidWdfbW9kZSgpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJKTsKCgkJLy8gTmV2ZXIgbG9hZCBhZHZhbmNlZC1jYWNoZS5waHAgZHJvcC1pbiB3aGVuIFdQLUNMSSBpcyBvcGVyYXRpbmcKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknZW5hYmxlX2xvYWRpbmdfYWR2YW5jZWRfY2FjaGVfZHJvcGluJywKCQkJc3RhdGljIGZ1bmN0aW9uICgpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCSk7CgoJCS8vIEluIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbiwgZGllIGlmIHVuYWJsZSB0byBmaW5kIHNpdGUgZ2l2ZW4gaW4gLS11cmwgcGFyYW1ldGVyCgkJaWYgKCAkdGhpcy0+aXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRydW5fb25fc2l0ZV9ub3RfZm91bmQgPSBmYWxzZTsKCQkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdjYWNoZScsICdmbHVzaCcgXSApICkgewoJCQkJJHJ1bl9vbl9zaXRlX25vdF9mb3VuZCA9ICdjYWNoZSBmbHVzaCc7CgkJCX0KCQkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdzZWFyY2gtcmVwbGFjZScgXSApICkgewoJCQkJLy8gVGFibGUtc3BlY2lmaWVkCgkJCQkvLyBCaXRzOiBzZWFyY2gtcmVwbGFjZSA8c2VhcmNoPiA8cmVwbGFjZT4gWzx0YWJsZT4uLi5dCgkJCQkvLyBPciBub3QgYWdhaW5zdCBhIHNwZWNpZmljIGJsb2cKCQkJCWlmICggY291bnQoICR0aGlzLT5hcmd1bWVudHMgKSA+IDMKCQkJCQl8fCAhIGVtcHR5KCAkdGhpcy0+YXNzb2NfYXJnc1snbmV0d29yayddICkKCQkJCQl8fCAhIGVtcHR5KCAkdGhpcy0+YXNzb2NfYXJnc1snYWxsLXRhYmxlcyddICkKCQkJCQl8fCAhIGVtcHR5KCAkdGhpcy0+YXNzb2NfYXJnc1snYWxsLXRhYmxlcy13aXRoLXByZWZpeCddICkgKSB7CgkJCQkJJHJ1bl9vbl9zaXRlX25vdF9mb3VuZCA9ICdzZWFyY2gtcmVwbGFjZSc7CgkJCQl9CgkJCX0KCQkJaWYgKCAkcnVuX29uX3NpdGVfbm90X2ZvdW5kCgkJCQkmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjAnLCAnPj0nICkgKSB7CgkJCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQkJCSdtc19zaXRlX25vdF9mb3VuZCcsCgkJCQkJc3RhdGljIGZ1bmN0aW9uICgpIHVzZSAoICRydW5fb25fc2l0ZV9ub3RfZm91bmQgKSB7CgkJCQkJCS8vIGVzY19zcWwoKSBpc24ndCB5ZXQgbG9hZGVkLCBidXQgbmVlZGVkLgoJCQkJCQlpZiAoICdzZWFyY2gtcmVwbGFjZScgPT09ICRydW5fb25fc2l0ZV9ub3RfZm91bmQgKSB7CgkJCQkJCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuIFdQSU5DIC4gJy9mb3JtYXR0aW5nLnBocCc7CgkJCQkJCX0KCQkJCQkJLy8gUEhQIDUuMyBjb21wYXRpYmxlIGltcGxlbWVudGF0aW9uIG9mIHJ1bl9jb21tYW5kX2FuZF9leGl0KCkuCgkJCQkJCSRydW5uZXIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKTsKCQkJCQkJJHJ1bm5lci0+cnVuX2NvbW1hbmQoICRydW5uZXItPmFyZ3VtZW50cywgJHJ1bm5lci0+YXNzb2NfYXJncyApOwoJCQkJCQlleGl0OwoJCQkJCX0sCgkJCQkJMQoJCQkJKTsKCQkJfQoJCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQkJJ21zX3NpdGVfbm90X2ZvdW5kJywKCQkJCXN0YXRpYyBmdW5jdGlvbiAoICRjdXJyZW50X3NpdGUsICRkb21haW4sICRwYXRoICkgewoJCQkJCSR1cmwgICAgICAgICA9ICRkb21haW4gLiAkcGF0aDsKCQkJCQkkbWVzc2FnZSAgICAgPSAkdXJsID8gIlNpdGUgJ3skdXJsfScgbm90IGZvdW5kLiIgOiAnU2l0ZSBub3QgZm91bmQuJzsKCQkJCQkkaGFzX3BhcmFtICAgPSBpc3NldCggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1sndXJsJ10gKTsKCQkJCQkkaGFzX2NvbnN0ICAgPSBkZWZpbmVkKCAnRE9NQUlOX0NVUlJFTlRfU0lURScgKTsKCQkJCQkkZXhwbGFuYXRpb24gPSAnJzsKCQkJCQlpZiAoICRoYXNfcGFyYW0gKSB7CgkJCQkJCSRleHBsYW5hdGlvbiA9ICdWZXJpZnkgYC0tdXJsPTx1cmw+YCBtYXRjaGVzIGFuIGV4aXN0aW5nIHNpdGUuJzsKCQkJCQl9IGVsc2UgewoJCQkJCQkkZXhwbGFuYXRpb24gPSAiRGVmaW5lIERPTUFJTl9DVVJSRU5UX1NJVEUgaW4gJ3dwLWNvbmZpZy5waHAnIG9yIHVzZSBgLS11cmw9PHVybD5gIHRvIG92ZXJyaWRlLiI7CgoJCQkJCQlpZiAoICRoYXNfY29uc3QgKSB7CgkJCQkJCQkkZXhwbGFuYXRpb24gPSAnVmVyaWZ5IERPTUFJTl9DVVJSRU5UX1NJVEUgbWF0Y2hlcyBhbiBleGlzdGluZyBzaXRlIG9yIHVzZSBgLS11cmw9PHVybD5gIHRvIG92ZXJyaWRlLic7CgkJCQkJCX0KCQkJCQl9CgkJCQkJaWYgKCAkZXhwbGFuYXRpb24gKSB7CgkJCQkJCSRtZXNzYWdlIC49ICcgJyAuICRleHBsYW5hdGlvbjsKCQkJCQl9CgkJCQkJV1BfQ0xJOjplcnJvciggJG1lc3NhZ2UgKTsKCQkJCX0sCgkJCQkxMCwKCQkJCTMKCQkJKTsKCQl9CgoJCS8vIFRoZSBBUEMgY2FjaGUgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGUgY29tbWFuZC1saW5lLCBzbyBiYWlsLCB0byBwcmV2ZW50IGNhY2hlIHBvaXNvbmluZwoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdtdXBsdWdpbnNfbG9hZGVkJywKCQkJc3RhdGljIGZ1bmN0aW9uICgpIHsKCQkJCWlmICggJEdMT0JBTFNbJ193cF91c2luZ19leHRfb2JqZWN0X2NhY2hlJ10gJiYgY2xhc3NfZXhpc3RzKCAnQVBDX09iamVjdF9DYWNoZScgKSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICdSdW5uaW5nIFdQLUNMSSB3aGlsZSB0aGUgQVBDIG9iamVjdCBjYWNoZSBpcyBhY3RpdmF0ZWQgY2FuIHJlc3VsdCBpbiBjYWNoZSBjb3JydXB0aW9uLicgKTsKCQkJCQlXUF9DTEk6OmNvbmZpcm0oICdHaXZlbiB0aGUgY29uc2VxdWVuY2VzLCBkbyB5b3Ugd2lzaCB0byBjb250aW51ZT8nICk7CgkJCQl9CgkJCX0sCgkJCTAKCQkpOwoKCQkvLyBIYW5kbGUgLS11c2VyIHBhcmFtZXRlcgoJCWlmICggISBkZWZpbmVkKCAnV1BfSU5TVEFMTElORycgKSApIHsKCQkJJGNvbmZpZyA9ICR0aGlzLT5jb25maWc7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCQknaW5pdCcsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgdXNlICggJGNvbmZpZyApIHsKCQkJCQlpZiAoIGlzc2V0KCAkY29uZmlnWyd1c2VyJ10gKSApIHsKCQkJCQkJJGZldGNoZXIgPSBuZXcgRmV0Y2hlcnNcVXNlcigpOwoJCQkJCQkkdXNlciAgICA9ICRmZXRjaGVyLT5nZXRfY2hlY2soICRjb25maWdbJ3VzZXInXSApOwoJCQkJCQl3cF9zZXRfY3VycmVudF91c2VyKCAkdXNlci0+SUQgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlhZGRfYWN0aW9uKCAnaW5pdCcsICdrc2VzX3JlbW92ZV9maWx0ZXJzJywgMTEgKTsKCQkJCQl9CgkJCQl9LAoJCQkJMAoJCQkpOwoJCX0KCgkJLy8gQXZvaWQgdW5jYXVnaHQgZXhjZXB0aW9uIHdoZW4gdXNpbmcgd3BfbWFpbCgpIHdpdGhvdXQgZGVmaW5lZCAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSd3cF9tYWlsX2Zyb20nLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkZnJvbV9lbWFpbCApIHsKCQkJCWlmICggJ3dvcmRwcmVzc0AnID09PSAkZnJvbV9lbWFpbCApIHsKCQkJCQkkc2l0ZW5hbWUgPSBzdHJ0b2xvd2VyKCBVdGlsc1xwYXJzZV91cmwoIHNpdGVfdXJsKCksIFBIUF9VUkxfSE9TVCApICk7CgkJCQkJaWYgKCBzdWJzdHIoICRzaXRlbmFtZSwgMCwgNCApID09PSAnd3d3LicgKSB7CgkJCQkJCSRzaXRlbmFtZSA9IHN1YnN0ciggJHNpdGVuYW1lLCA0ICk7CgkJCQkJfQoJCQkJCSRmcm9tX2VtYWlsID0gJ3dvcmRwcmVzc0AnIC4gJHNpdGVuYW1lOwoJCQkJfQoJCQkJcmV0dXJuICRmcm9tX2VtYWlsOwoJCQl9CgkJKTsKCgkJLy8gRG9uJ3QgYXBwbHkgc2V0X3VybF9zY2hlbWUgaW4gZ2V0X2hvbWVfdXJsKCkgb3IgZ2V0X3NpdGVfdXJsKCkuCgkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJJ2hvbWVfdXJsJywKCQkJc3RhdGljIGZ1bmN0aW9uICggJHVybCwgJHBhdGgsICRzY2hlbWUsICRibG9nX2lkICkgewoJCQkJaWYgKCBlbXB0eSggJGJsb2dfaWQgKSB8fCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQkJCSR1cmwgPSBnZXRfb3B0aW9uKCAnaG9tZScgKTsKCQkJCX0gZWxzZSB7CgkJCQkJc3dpdGNoX3RvX2Jsb2coICRibG9nX2lkICk7CgkJCQkJJHVybCA9IGdldF9vcHRpb24oICdob21lJyApOwoJCQkJCXJlc3RvcmVfY3VycmVudF9ibG9nKCk7CgkJCQl9CgoJCQkJaWYgKCAkcGF0aCAmJiBpc19zdHJpbmcoICRwYXRoICkgKSB7CgkJCQkJJHVybCAuPSAnLycgLiBsdHJpbSggJHBhdGgsICcvJyApOwoJCQkJfQoKCQkJCXJldHVybiAkdXJsOwoJCQl9LAoJCQkwLAoJCQk0CgkJKTsKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknc2l0ZV91cmwnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkdXJsLCAkcGF0aCwgJHNjaGVtZSwgJGJsb2dfaWQgKSB7CgkJCQlpZiAoIGVtcHR5KCAkYmxvZ19pZCApIHx8ICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQkJJHVybCA9IGdldF9vcHRpb24oICdzaXRldXJsJyApOwoJCQkJfSBlbHNlIHsKCQkJCQlzd2l0Y2hfdG9fYmxvZyggJGJsb2dfaWQgKTsKCQkJCQkkdXJsID0gZ2V0X29wdGlvbiggJ3NpdGV1cmwnICk7CgkJCQkJcmVzdG9yZV9jdXJyZW50X2Jsb2coKTsKCQkJCX0KCgkJCQlpZiAoICRwYXRoICYmIGlzX3N0cmluZyggJHBhdGggKSApIHsKCQkJCQkkdXJsIC49ICcvJyAuIGx0cmltKCAkcGF0aCwgJy8nICk7CgkJCQl9CgoJCQkJcmV0dXJuICR1cmw7CgkJCX0sCgkJCTAsCgkJCTQKCQkpOwoKCQkvLyBTZXQgdXAgaG9vayBmb3IgcGx1Z2lucyBhbmQgdGhlbWVzIHRvIGNvbmRpdGlvbmFsbHkgYWRkIFdQLUNMSSBjb21tYW5kcy4KCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknaW5pdCcsCgkJCXN0YXRpYyBmdW5jdGlvbiAoKSB7CgkJCQlkb19hY3Rpb24oICdjbGlfaW5pdCcgKTsKCQkJfQoJCSk7Cgl9CgoJLyoqCgkgKiBTZXQgdXAgdGhlIGZpbHRlcnMgdG8gc2tpcCB0aGUgbG9hZGVkIHBsdWdpbnMKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBzZXR1cF9za2lwX3BsdWdpbnNfZmlsdGVycygpIHsKCQkkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfcGx1Z2lucyA9IHN0YXRpYyBmdW5jdGlvbiAoICRwbHVnaW5zICkgewoJCQkkc2tpcHBlZF9wbHVnaW5zID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1snc2tpcC1wbHVnaW5zJ107CgkJCWlmICggdHJ1ZSA9PT0gJHNraXBwZWRfcGx1Z2lucyApIHsKCQkJCXJldHVybiBbXTsKCQkJfQoJCQlpZiAoICEgaXNfYXJyYXkoICRwbHVnaW5zICkgKSB7CgkJCQlyZXR1cm4gJHBsdWdpbnM7CgkJCX0KCQkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRhID0+ICRiICkgewoJCQkJLy8gYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMgc3RvcmVzIHBsdWdpbiBuYW1lIGFzIHRoZSBrZXkuCgkJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoIGN1cnJlbnRfZmlsdGVyKCksICdhY3RpdmVfc2l0ZXdpZGVfcGx1Z2lucycgKSAmJiBVdGlsc1xpc19wbHVnaW5fc2tpcHBlZCggJGEgKSApIHsKCQkJCQl1bnNldCggJHBsdWdpbnNbICRhIF0gKTsKCQkJCQkvLyBhY3RpdmVfcGx1Z2lucyBzdG9yZXMgcGx1Z2luIG5hbWUgYXMgdGhlIHZhbHVlLgoJCQkJfSBlbHNlaWYgKCBmYWxzZSAhPT0gc3RycG9zKCBjdXJyZW50X2ZpbHRlcigpLCAnYWN0aXZlX3BsdWdpbnMnICkgJiYgVXRpbHNcaXNfcGx1Z2luX3NraXBwZWQoICRiICkgKSB7CgkJCQkJdW5zZXQoICRwbHVnaW5zWyAkYSBdICk7CgkJCQl9CgkJCX0KCQkJLy8gUmVpbmRleCBiZWNhdXNlIGFjdGl2ZV9wbHVnaW5zIGV4cGVjdHMgYSBudW1lcmljIGluZGV4LgoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoIGN1cnJlbnRfZmlsdGVyKCksICdhY3RpdmVfcGx1Z2lucycgKSApIHsKCQkJCSRwbHVnaW5zID0gYXJyYXlfdmFsdWVzKCAkcGx1Z2lucyApOwoJCQl9CgkJCXJldHVybiAkcGx1Z2luczsKCQl9OwoKCQkkaG9va3MgPSBbCgkJCSdwcmVfc2l0ZV9vcHRpb25fYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMnLAoJCQknc2l0ZV9vcHRpb25fYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMnLAoJCQkncHJlX29wdGlvbl9hY3RpdmVfcGx1Z2lucycsCgkJCSdvcHRpb25fYWN0aXZlX3BsdWdpbnMnLAoJCV07CgkJZm9yZWFjaCAoICRob29rcyBhcyAkaG9vayApIHsKCQkJV1BfQ0xJOjphZGRfd3BfaG9vayggJGhvb2ssICR3cF9jbGlfZmlsdGVyX2FjdGl2ZV9wbHVnaW5zLCA5OTkgKTsKCQl9CgkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJJ3BsdWdpbnNfbG9hZGVkJywKCQkJc3RhdGljIGZ1bmN0aW9uICgpIHVzZSAoICRob29rcywgJHdwX2NsaV9maWx0ZXJfYWN0aXZlX3BsdWdpbnMgKSB7CgkJCQlmb3JlYWNoICggJGhvb2tzIGFzICRob29rICkgewoJCQkJCXJlbW92ZV9maWx0ZXIoICRob29rLCAkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfcGx1Z2lucywgOTk5ICk7CgkJCQl9CgkJCX0sCgkJCTAKCQkpOwoJfQoKCS8qKgoJICogU2V0IHVwIHRoZSBmaWx0ZXJzIHRvIHNraXAgdGhlIGxvYWRlZCB0aGVtZQoJICovCglwdWJsaWMgZnVuY3Rpb24gYWN0aW9uX3NldHVwX3RoZW1lX3dwX2NsaV9za2lwX3RoZW1lcygpIHsKCQkkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfdGhlbWUgPSBzdGF0aWMgZnVuY3Rpb24gKCAkdmFsdWUgKSB7CgkJCSRza2lwcGVkX3RoZW1lcyA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5jb25maWdbJ3NraXAtdGhlbWVzJ107CgkJCWlmICggdHJ1ZSA9PT0gJHNraXBwZWRfdGhlbWVzICkgewoJCQkJcmV0dXJuICcnOwoJCQl9CgkJCWlmICggISBpc19hcnJheSggJHNraXBwZWRfdGhlbWVzICkgKSB7CgkJCQkkc2tpcHBlZF90aGVtZXMgPSBleHBsb2RlKCAnLCcsICRza2lwcGVkX3RoZW1lcyApOwoJCQl9CgoJCQkkY2hlY2tlZF92YWx1ZSA9ICR2YWx1ZTsKCQkJLy8gQWx3YXlzIGNoZWNrIGFnYWluc3QgdGhlIHN0eWxlc2hlZXQgdmFsdWUKCQkJLy8gVGhpcyBlbnN1cmVzIGEgY2hpbGQgdGhlbWUgY2FuIGJlIHNraXBwZWQgd2hlbiB0ZW1wbGF0ZSBkaWZmZXJzCgkJCWlmICggZmFsc2UgIT09IHN0cmlwb3MoIGN1cnJlbnRfZmlsdGVyKCksICdvcHRpb25fdGVtcGxhdGUnICkgKSB7CgkJCQkkY2hlY2tlZF92YWx1ZSA9IGdldF9vcHRpb24oICdzdHlsZXNoZWV0JyApOwoJCQl9CgoJCQlpZiAoICcnID09PSAkY2hlY2tlZF92YWx1ZSB8fCBpbl9hcnJheSggJGNoZWNrZWRfdmFsdWUsICRza2lwcGVkX3RoZW1lcywgdHJ1ZSApICkgewoJCQkJcmV0dXJuICcnOwoJCQl9CgkJCXJldHVybiAkdmFsdWU7CgkJfTsKCQkkaG9va3MgICAgICAgICAgICAgICAgICAgICAgPSBbCgkJCSdwcmVfb3B0aW9uX3RlbXBsYXRlJywKCQkJJ29wdGlvbl90ZW1wbGF0ZScsCgkJCSdwcmVfb3B0aW9uX3N0eWxlc2hlZXQnLAoJCQknb3B0aW9uX3N0eWxlc2hlZXQnLAoJCV07CgkJZm9yZWFjaCAoICRob29rcyBhcyAkaG9vayApIHsKCQkJYWRkX2ZpbHRlciggJGhvb2ssICR3cF9jbGlfZmlsdGVyX2FjdGl2ZV90aGVtZSwgOTk5ICk7CgkJfQoJCS8vIENsZWFuIHVwIGFmdGVyIHRoZSBURU1QTEFURVBBVEggYW5kIFNUWUxFU0hFRVRQQVRIIGNvbnN0YW50cyBhcmUgZGVmaW5lZAoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdhZnRlcl9zZXR1cF90aGVtZScsCgkJCXN0YXRpYyBmdW5jdGlvbiAoKSB1c2UgKCAkaG9va3MsICR3cF9jbGlfZmlsdGVyX2FjdGl2ZV90aGVtZSApIHsKCQkJCWZvcmVhY2ggKCAkaG9va3MgYXMgJGhvb2sgKSB7CgkJCQkJcmVtb3ZlX2ZpbHRlciggJGhvb2ssICR3cF9jbGlfZmlsdGVyX2FjdGl2ZV90aGVtZSwgOTk5ICk7CgkJCQl9CgkJCX0sCgkJCTAKCQkpOwoJfQoKCS8qKgoJICogV2hldGhlciBvciBub3QgdGhpcyBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGlzIG11bHRpc2l0ZS4KCSAqCgkgKiBGb3IgdXNlIGFmdGVyIHdwLWNvbmZpZy5waHAgaGFzIGxvYWRlZCwgYnV0IGJlZm9yZSB0aGUgcmVzdCBvZiBXb3JkUHJlc3MKCSAqIGlzIGxvYWRlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpc19tdWx0aXNpdGUoKSB7CgkJaWYgKCBkZWZpbmVkKCAnTVVMVElTSVRFJyApICkgewoJCQlyZXR1cm4gTVVMVElTSVRFOwoJCX0KCgkJaWYgKCBkZWZpbmVkKCAnU1VCRE9NQUlOX0lOU1RBTEwnICkgfHwgZGVmaW5lZCggJ1ZIT1NUJyApIHx8IGRlZmluZWQoICdTVU5SSVNFJyApICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEVycm9yIGhhbmRsZXIgZm9yIGB3cF9kaWUoKWAgd2hlbiB0aGUgY29tbWFuZCBpcyBoZWxwIHRvIHRyeSB0byB0cmFwIGVycm9ycyAoZGIgY29ubmVjdGlvbiBmYWlsdXJlIGluIHBhcnRpY3VsYXIpIGR1cmluZyBXb3JkUHJlc3MgbG9hZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGhlbHBfd3BfZGllX2hhbmRsZXIoICRtZXNzYWdlICkgewoJCSRoZWxwX2V4aXRfd2FybmluZyA9ICdFcnJvciBkdXJpbmcgV29yZFByZXNzIGxvYWQuJzsKCQlpZiAoICRtZXNzYWdlIGluc3RhbmNlb2YgV1BfRXJyb3IgKSB7CgkJCSRoZWxwX2V4aXRfd2FybmluZyA9IFV0aWxzXHdwX2NsZWFuX2Vycm9yX21lc3NhZ2UoICRtZXNzYWdlLT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJfSBlbHNlaWYgKCBpc19zdHJpbmcoICRtZXNzYWdlICkgKSB7CgkJCSRoZWxwX2V4aXRfd2FybmluZyA9IFV0aWxzXHdwX2NsZWFuX2Vycm9yX21lc3NhZ2UoICRtZXNzYWdlICk7CgkJfQoJCSR0aGlzLT5ydW5fY29tbWFuZF9hbmRfZXhpdCggJGhlbHBfZXhpdF93YXJuaW5nICk7Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIHRoZXJlJ3MgYSBXUC1DTEkgdXBkYXRlIGF2YWlsYWJsZSwgYW5kIHN1Z2dlc3QgdXBkYXRlIGlmIHNvLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGF1dG9fY2hlY2tfdXBkYXRlKCkgewoKCQkvLyBgd3AgY2xpIHVwZGF0ZWAgb25seSB3b3JrcyB3aXRoIFBoYXJzIGF0IHRoaXMgdGltZS4KCQlpZiAoICEgVXRpbHNcaW5zaWRlX3BoYXIoKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJGV4aXN0aW5nX3BoYXIgPSByZWFscGF0aCggJF9TRVJWRVJbJ2FyZ3YnXVswXSApOwoJCS8vIFBoYXIgbmVlZHMgdG8gYmUgd3JpdGFibGUgdG8gYmUgZWFzaWx5IHVwZGF0ZWFibGUuCgkJaWYgKCAhIGlzX3dyaXRhYmxlKCAkZXhpc3RpbmdfcGhhciApIHx8ICEgaXNfd3JpdGFibGUoIGRpcm5hbWUoICRleGlzdGluZ19waGFyICkgKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gT25seSBjaGVjayBmb3IgdXBkYXRlIHdoZW4gYSBodW1hbiBpcyBvcGVyYXRpbmcuCgkJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3Bvc2l4X2lzYXR0eScgKSB8fCAhIHBvc2l4X2lzYXR0eSggU1RET1VUICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIEFsbG93IGhvc3RzIGFuZCBvdGhlciBwcm92aWRlcnMgdG8gZGlzYWJsZSBhdXRvbWF0aWMgY2hlY2sgdXBkYXRlLgoJCWlmICggZ2V0ZW52KCAnV1BfQ0xJX0RJU0FCTEVfQVVUT19DSEVDS19VUERBVEUnICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIFBlcm1pdCBjb25maWd1cmF0aW9uIG9mIG51bWJlciBvZiBkYXlzIGJldHdlZW4gY2hlY2tzLgoJCSRkYXlzX2JldHdlZW5fY2hlY2tzID0gZ2V0ZW52KCAnV1BfQ0xJX0FVVE9fQ0hFQ0tfVVBEQVRFX0RBWVMnICk7CgkJaWYgKCBmYWxzZSA9PT0gJGRheXNfYmV0d2Vlbl9jaGVja3MgKSB7CgkJCSRkYXlzX2JldHdlZW5fY2hlY2tzID0gMTsKCQl9CgoJCSRjYWNoZSAgICAgPSBXUF9DTEk6OmdldF9jYWNoZSgpOwoJCSRjYWNoZV9rZXkgPSAnd3AtY2xpLXVwZGF0ZS1jaGVjayc7CgkJLy8gQmFpbCBlYXJseSBvbiB0aGUgZmlyc3QgY2hlY2ssIHNvIHdlIGRvbid0IGFsd2F5cyBjaGVjayBvbiBhbiB1bndyaXRhYmxlIGNhY2hlLgoJCWlmICggISAkY2FjaGUtPmhhcyggJGNhY2hlX2tleSApICkgewoJCQkkY2FjaGUtPndyaXRlKCAkY2FjaGVfa2V5LCB0aW1lKCkgKTsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gQmFpbCBpZiBsYXN0IGNoZWNrIGlzIHN0aWxsIHdpdGhpbiBvdXIgdXBkYXRlIGNoZWNrIHRpbWUgcGVyaW9kLgoJCSRsYXN0X2NoZWNrID0gKGludCkgJGNhY2hlLT5yZWFkKCAkY2FjaGVfa2V5ICk7CgkJaWYgKCAoIHRpbWUoKSAtICggMjQgKiA2MCAqIDYwICogJGRheXNfYmV0d2Vlbl9jaGVja3MgKSApIDwgJGxhc3RfY2hlY2sgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIEluIGNhc2UgdGhlIG9wZXJhdGlvbiBmYWlscywgZW5zdXJlIHRoZSB0aW1lc3RhbXAgaGFzIGJlZW4gdXBkYXRlZC4KCQkkY2FjaGUtPndyaXRlKCAkY2FjaGVfa2V5LCB0aW1lKCkgKTsKCgkJLy8gQ2hlY2sgd2hldGhlciBhbnkgdXBkYXRlcyBhcmUgYXZhaWxhYmxlLgoJCW9iX3N0YXJ0KCk7CgkJV1BfQ0xJOjpydW5fY29tbWFuZCgKCQkJWyAnY2xpJywgJ2NoZWNrLXVwZGF0ZScgXSwKCQkJWwoJCQkJJ2Zvcm1hdCcgPT4gJ2NvdW50JywKCQkJXQoJCSk7CgkJJGNvdW50ID0gb2JfZ2V0X2NsZWFuKCk7CgkJaWYgKCAhICRjb3VudCApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gTG9va3MgbGlrZSBhbiB1cGRhdGUgaXMgYXZhaWxhYmxlLCBzbyBsZXQncyBwcm9tcHQgdG8gdXBkYXRlLgoJCVdQX0NMSTo6cnVuX2NvbW1hbmQoIFsgJ2NsaScsICd1cGRhdGUnIF0gKTsKCQkvLyBJZiB0aGUgUGhhciB3YXMgcmVwbGFjZWQsIHdlIGNhbid0IHByb2NlZWQgd2l0aCB0aGUgb3JpZ2luYWwgcHJvY2Vzcy4KCQlleGl0OwoJfQoKCS8qKgoJICogR2V0IGEgc3VnZ2VzdGlvbiBvbiBzaW1pbGFyIChzdWIpY29tbWFuZHMgd2hlbiB0aGUgdXNlciBlbnRlcmVkIGFuCgkgKiB1bmtub3duIChzdWIpY29tbWFuZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkZW50cnkgICAgICAgIFVzZXIgZW50cnkgdGhhdCBkaWRuJ3QgbWF0Y2ggYW4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcgY29tbWFuZC4KCSAqIEBwYXJhbSBDb21wb3NpdGVDb21tYW5kICRyb290X2NvbW1hbmQgUm9vdCBjb21tYW5kIHRvIHN0YXJ0IHNlYXJjaCBmb3IKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VnZ2VzdGlvbnMgYXQuCgkgKgoJICogQHJldHVybiBzdHJpbmcgU3VnZ2VzdGlvbiB0aGF0IGZpdHMgdGhlIHVzZXIgZW50cnksIG9yIGFuIGVtcHR5IHN0cmluZy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfc3ViY29tbWFuZF9zdWdnZXN0aW9uKCAkZW50cnksIENvbXBvc2l0ZUNvbW1hbmQgJHJvb3RfY29tbWFuZCA9IG51bGwgKSB7CgkJJGNvbW1hbmRzID0gW107CgkJJHRoaXMtPmVudW1lcmF0ZV9jb21tYW5kcyggJHJvb3RfY29tbWFuZCA/OiBXUF9DTEk6OmdldF9yb290X2NvbW1hbmQoKSwgJGNvbW1hbmRzICk7CgoJCXJldHVybiBVdGlsc1xnZXRfc3VnZ2VzdGlvbiggJGVudHJ5LCAkY29tbWFuZHMsICR0aHJlc2hvbGQgPSAyICk7Cgl9CgoJLyoqCgkgKiBSZWN1cnNpdmUgbWV0aG9kIHRvIGVudW1lcmF0ZSBhbGwga25vd24gY29tbWFuZHMuCgkgKgoJICogQHBhcmFtIENvbXBvc2l0ZUNvbW1hbmQgJGNvbW1hbmQgQ29tcG9zaXRlIGNvbW1hbmQgdG8gcmVjdXJzZSBvdmVyLgoJICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgJGxpc3QgICAgUmVmZXJlbmNlIHRvIGxpc3QgYWNjdW11bGF0aW5nIHJlc3VsdHMuCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkcGFyZW50ICBQYXJlbnQgY29tbWFuZCB0byB1c2UgYXMgcHJlZml4LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGVudW1lcmF0ZV9jb21tYW5kcyggQ29tcG9zaXRlQ29tbWFuZCAkY29tbWFuZCwgYXJyYXkgJiRsaXN0LCAkcGFyZW50ID0gJycgKSB7CgkJZm9yZWFjaCAoICRjb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSBhcyAkc3ViY29tbWFuZCApIHsKCQkJLyoqIEB2YXIgQ29tcG9zaXRlQ29tbWFuZCAkc3ViY29tbWFuZCAqLwoJCQkkY29tbWFuZF9zdHJpbmcgPSBlbXB0eSggJHBhcmVudCApCgkJCQk/ICRzdWJjb21tYW5kLT5nZXRfbmFtZSgpCgkJCQk6ICJ7JHBhcmVudH0geyRzdWJjb21tYW5kLT5nZXRfbmFtZSgpfSI7CgoJCQkkbGlzdFtdID0gJGNvbW1hbmRfc3RyaW5nOwoKCQkJJHRoaXMtPmVudW1lcmF0ZV9jb21tYW5kcyggJHN1YmNvbW1hbmQsICRsaXN0LCAkY29tbWFuZF9zdHJpbmcgKTsKCQl9Cgl9CgoJLyoqCgkgKiBFbmFibGVzIChhbG1vc3QpIGZ1bGwgUEhQIGVycm9yIHJlcG9ydGluZyB0byBzdGRlcnIuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZW5hYmxlX2Vycm9yX3JlcG9ydGluZygpIHsKCQlpZiAoIEVfQUxMICE9PSBlcnJvcl9yZXBvcnRpbmcoKSApIHsKCQkJLy8gRG9uJ3QgZW5hYmxlIEVfREVQUkVDQVRFRCBhcyBvbGQgdmVyc2lvbnMgb2YgV1AgdXNlIFBIUCA0IHN0eWxlIGNvbnN0cnVjdG9ycyBhbmQgdGhlIG15c3FsIGV4dGVuc2lvbi4KCQkJZXJyb3JfcmVwb3J0aW5nKCBFX0FMTCAmIH5FX0RFUFJFQ0FURUQgKTsKCQl9CgkJaW5pX3NldCggJ2Rpc3BsYXlfZXJyb3JzJywgJ3N0ZGVycicgKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuSW5pU2V0LmRpc3BsYXlfZXJyb3JzX0JsYWNrbGlzdGVkCgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7CgovKioKICogQ2hlY2tzIGlmIHRoZSBsaXN0IG9mIHBhcmFtZXRlcnMgbWF0Y2hlcyB0aGUgc3BlY2lmaWNhdGlvbiBkZWZpbmVkIGluIHRoZSBzeW5vcHNpcy4KICovCmNsYXNzIFN5bm9wc2lzVmFsaWRhdG9yIHsKCgkvKioKCSAqIFN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgY29tbWFuZCBzeW5vcHNpcy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJHNwZWM7CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRzeW5vcHNpcyBDb21tYW5kJ3Mgc3lub3BzaXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJHN5bm9wc2lzICkgewoJCSR0aGlzLT5zcGVjID0gU3lub3BzaXNQYXJzZXI6OnBhcnNlKCAkc3lub3BzaXMgKTsKCX0KCgkvKioKCSAqIEdldCBhbnkgdW5rbm93biBhcmd1bWVudHMuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3Vua25vd24oKSB7CgkJcmV0dXJuIGFycmF5X2NvbHVtbigKCQkJJHRoaXMtPnF1ZXJ5X3NwZWMoCgkJCQlbCgkJCQkJJ3R5cGUnID0+ICd1bmtub3duJywKCQkJCV0KCQkJKSwKCQkJJ3Rva2VuJwoJCSk7Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIHRoZXJlIGFyZSBlbm91Z2ggcG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzIFBvc2l0aW9uYWwgYXJndW1lbnRzLgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlbm91Z2hfcG9zaXRpb25hbHMoICRhcmdzICkgewoJCSRwb3NpdGlvbmFsID0gJHRoaXMtPnF1ZXJ5X3NwZWMoCgkJCVsKCQkJCSd0eXBlJyAgICAgPT4gJ3Bvc2l0aW9uYWwnLAoJCQkJJ29wdGlvbmFsJyA9PiBmYWxzZSwKCQkJXQoJCSk7CgoJCXJldHVybiBjb3VudCggJGFyZ3MgKSA+PSBjb3VudCggJHBvc2l0aW9uYWwgKTsKCX0KCgkvKioKCSAqIENoZWNrIGZvciBhbnkgdW5rbm93biBwb3NpdGlvbmFscy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgUG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bmtub3duX3Bvc2l0aW9uYWxzKCAkYXJncyApIHsKCQkkcG9zaXRpb25hbF9yZXBlYXRpbmcgPSAkdGhpcy0+cXVlcnlfc3BlYygKCQkJWwoJCQkJJ3R5cGUnICAgICAgPT4gJ3Bvc2l0aW9uYWwnLAoJCQkJJ3JlcGVhdGluZycgPT4gdHJ1ZSwKCQkJXQoJCSk7CgoJCS8vIEF0IGxlYXN0IG9uZSBwb3NpdGlvbmFsIHN1cHBvcnRzIGFzIG1hbnkgYXMgcG9zc2libGUuCgkJaWYgKCAhIGVtcHR5KCAkcG9zaXRpb25hbF9yZXBlYXRpbmcgKSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJJHBvc2l0aW9uYWwgPSAkdGhpcy0+cXVlcnlfc3BlYygKCQkJWwoJCQkJJ3R5cGUnICAgICAgPT4gJ3Bvc2l0aW9uYWwnLAoJCQkJJ3JlcGVhdGluZycgPT4gZmFsc2UsCgkJCV0KCQkpOwoKCQlyZXR1cm4gYXJyYXlfc2xpY2UoICRhcmdzLCBjb3VudCggJHBvc2l0aW9uYWwgKSApOwoJfQoKCS8qKgoJICogQ2hlY2sgdGhhdCBhbGwgcmVxdWlyZWQga2V5cyBhcmUgcHJlc2VudCBhbmQgdGhhdCB0aGV5IGhhdmUgdmFsdWVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBQYXJhbWV0ZXJzIHBhc3NlZCB0byBjb21tYW5kLgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGVfYXNzb2MoICRhc3NvY19hcmdzICkgewoJCSRhc3NvY19zcGVjID0gJHRoaXMtPnF1ZXJ5X3NwZWMoCgkJCVsKCQkJCSd0eXBlJyA9PiAnYXNzb2MnLAoJCQldCgkJKTsKCgkJJGVycm9ycyA9IFsKCQkJJ2ZhdGFsJyAgID0+IFtdLAoJCQknd2FybmluZycgPT4gW10sCgkJXTsKCgkJJHRvX3Vuc2V0ID0gW107CgoJCWZvcmVhY2ggKCAkYXNzb2Nfc3BlYyBhcyAkcGFyYW0gKSB7CgkJCSRrZXkgPSAkcGFyYW1bJ25hbWUnXTsKCgkJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbICRrZXkgXSApICkgewoJCQkJaWYgKCAhICRwYXJhbVsnb3B0aW9uYWwnXSApIHsKCQkJCQkkZXJyb3JzWydmYXRhbCddWyAka2V5IF0gPSAibWlzc2luZyAtLSRrZXkgcGFyYW1ldGVyIjsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmICggdHJ1ZSA9PT0gJGFzc29jX2FyZ3NbICRrZXkgXSAmJiAhICRwYXJhbVsndmFsdWUnXVsnb3B0aW9uYWwnXSApIHsKCQkJCQkkZXJyb3JfdHlwZSAgICAgICAgICAgICAgICAgICAgPSAoICEgJHBhcmFtWydvcHRpb25hbCddICkgPyAnZmF0YWwnIDogJ3dhcm5pbmcnOwoJCQkJCSRlcnJvcnNbICRlcnJvcl90eXBlIF1bICRrZXkgXSA9ICItLSRrZXkgcGFyYW1ldGVyIG5lZWRzIGEgdmFsdWUiOwoKCQkJCQkkdG9fdW5zZXRbXSA9ICRrZXk7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBbICRlcnJvcnMsICR0b191bnNldCBdOwoJfQoKCS8qKgoJICogQ2hlY2sgd2hldGhlciB0aGVyZSBhcmUgdW5rbm93biBwYXJhbWV0ZXJzIHN1cHBsaWVkLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBQYXJhbWV0ZXJzIHBhc3NlZCB0byBjb21tYW5kLgoJICogQHJldHVybiBhcnJheXxmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5rbm93bl9hc3NvYyggJGFzc29jX2FyZ3MgKSB7CgkJJGdlbmVyaWMgPSAkdGhpcy0+cXVlcnlfc3BlYygKCQkJWwoJCQkJJ3R5cGUnID0+ICdnZW5lcmljJywKCQkJXQoJCSk7CgoJCWlmICggY291bnQoICRnZW5lcmljICkgKSB7CgkJCXJldHVybiBbXTsKCQl9CgoJCSRrbm93bl9hc3NvYyA9IFtdOwoKCQlmb3JlYWNoICggJHRoaXMtPnNwZWMgYXMgJHBhcmFtICkgewoJCQlpZiAoIGluX2FycmF5KCAkcGFyYW1bJ3R5cGUnXSwgWyAnYXNzb2MnLCAnZmxhZycgXSwgdHJ1ZSApICkgewoJCQkJJGtub3duX2Fzc29jW10gPSAkcGFyYW1bJ25hbWUnXTsKCQkJfQoJCX0KCgkJcmV0dXJuIGFycmF5X2RpZmYoIGFycmF5X2tleXMoICRhc3NvY19hcmdzICksICRrbm93bl9hc3NvYyApOwoJfQoKCS8qKgoJICogRmlsdGVycyBhIGxpc3Qgb2YgYXNzb2NpYXRpdmUgYXJyYXlzLCBiYXNlZCBvbiBhIHNldCBvZiBrZXkgPT4gdmFsdWUgYXJndW1lbnRzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBBbiBhcnJheSBvZiBrZXkgPT4gdmFsdWUgYXJndW1lbnRzIHRvIG1hdGNoIGFnYWluc3QKCSAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcXVlcnlfc3BlYyggJGFyZ3MsICRvcGVyYXRvciA9ICdBTkQnICkgewoJCSRvcGVyYXRvciA9IHN0cnRvdXBwZXIoICRvcGVyYXRvciApOwoJCSRjb3VudCAgICA9IGNvdW50KCAkYXJncyApOwoJCSRmaWx0ZXJlZCA9IFtdOwoKCQlmb3JlYWNoICggJHRoaXMtPnNwZWMgYXMgJGtleSA9PiAkdG9fbWF0Y2ggKSB7CgkJCSRtYXRjaGVkID0gMDsKCQkJZm9yZWFjaCAoICRhcmdzIGFzICRtX2tleSA9PiAkbV92YWx1ZSApIHsKCQkJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJG1fa2V5LCAkdG9fbWF0Y2ggKSAmJiAkbV92YWx1ZSA9PT0gJHRvX21hdGNoWyAkbV9rZXkgXSApIHsKCQkJCQkkbWF0Y2hlZCsrOwoJCQkJfQoJCQl9CgoJCQlpZiAoICggJ0FORCcgPT09ICRvcGVyYXRvciAmJiAkbWF0Y2hlZCA9PT0gJGNvdW50ICkKCQkJCXx8ICggJ09SJyA9PT0gJG9wZXJhdG9yICYmICRtYXRjaGVkID4gMCApCgkJCQl8fCAoICdOT1QnID09PSAkb3BlcmF0b3IgJiYgMCA9PT0gJG1hdGNoZWQgKSApIHsKCQkJCQkkZmlsdGVyZWRbICRrZXkgXSA9ICR0b19tYXRjaDsKCQkJfQoJCX0KCgkJcmV0dXJuICRmaWx0ZXJlZDsKCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwoKY2xhc3MgQ29tcGxldGlvbnMgewoKCXByaXZhdGUgJHdvcmRzOwoJcHJpdmF0ZSAkb3B0cyA9IFtdOwoKCS8qKgoJICogSW5zdGFudGlhdGUgYSBDb21wbGV0aW9ucyBvYmplY3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbGluZSBMaW5lIG9mIHNoZWxsIGlucHV0IHRvIGNvbXB1dGUgYSBjb21wbGV0aW9uIGZvci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkbGluZSApIHsKCQkvLyBUT0RPOiBwcm9wZXJseSBwYXJzZSBzaW5nbGUgYW5kIGRvdWJsZSBxdW90ZXMKCQkkdGhpcy0+d29yZHMgPSBleHBsb2RlKCAnICcsICRsaW5lICk7CgoJCS8vIEZpcnN0IHdvcmQgaXMgYWx3YXlzIGB3cGAuCgkJYXJyYXlfc2hpZnQoICR0aGlzLT53b3JkcyApOwoKCQkvLyBMYXN0IHdvcmQgaXMgZWl0aGVyIGVtcHR5IG9yIGFuIGluY29tcGxldGUgc3ViY29tbWFuZC4KCQkkdGhpcy0+Y3VyX3dvcmQgPSBlbmQoICR0aGlzLT53b3JkcyApOwoJCWlmICggJycgIT09ICR0aGlzLT5jdXJfd29yZCAmJiAhIHByZWdfbWF0Y2goICcvXlwtLycsICR0aGlzLT5jdXJfd29yZCApICkgewoJCQlhcnJheV9wb3AoICR0aGlzLT53b3JkcyApOwoJCX0KCgkJJGlzX2FsaWFzID0gZmFsc2U7CgkJJGlzX2hlbHAgID0gZmFsc2U7CgkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+d29yZHNbMF0gKSAmJiBwcmVnX21hdGNoKCAnL15ALycsICR0aGlzLT53b3Jkc1swXSApICkgewoJCQlhcnJheV9zaGlmdCggJHRoaXMtPndvcmRzICk7CgkJCS8vIGB3cCBAYWxgIGlzIGZhbHNlLCBidXQgYHdwIEBhbGwgYCBpcyB0cnVlLgoJCQlpZiAoIGNvdW50KCAkdGhpcy0+d29yZHMgKSApIHsKCQkJCSRpc19hbGlhcyA9IHRydWU7CgkJCX0KCQl9IGVsc2VpZiAoICEgZW1wdHkoICR0aGlzLT53b3Jkc1swXSApICYmICdoZWxwJyA9PT0gJHRoaXMtPndvcmRzWzBdICkgewoJCQlhcnJheV9zaGlmdCggJHRoaXMtPndvcmRzICk7CgkJCSRpc19oZWxwID0gdHJ1ZTsKCQl9CgoJCSRyID0gJHRoaXMtPmdldF9jb21tYW5kKCAkdGhpcy0+d29yZHMgKTsKCQlpZiAoICEgaXNfYXJyYXkoICRyICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCWxpc3QoICRjb21tYW5kLCAkYXJncywgJGFzc29jX2FyZ3MgKSA9ICRyOwoKCQkkc3BlYyA9IFN5bm9wc2lzUGFyc2VyOjpwYXJzZSggJGNvbW1hbmQtPmdldF9zeW5vcHNpcygpICk7CgoJCWZvcmVhY2ggKCAkc3BlYyBhcyAkYXJnICkgewoJCQlpZiAoICdwb3NpdGlvbmFsJyA9PT0gJGFyZ1sndHlwZSddICYmICdmaWxlJyA9PT0gJGFyZ1snbmFtZSddICkgewoJCQkJJHRoaXMtPmFkZCggJzxmaWxlPiAnICk7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgoJCWlmICggJGNvbW1hbmQtPmNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgKSB7CgkJCS8vIEFkZCBjb21wbGV0aW9uIHdoZW4gY29tbWFuZCBpcyBgd3BgIGFuZCBhbGlhcyBpc24ndCBzZXQuCgkJCWlmICggJ3dwJyA9PT0gJGNvbW1hbmQtPmdldF9uYW1lKCkgJiYgZmFsc2UgPT09ICRpc19hbGlhcyAmJiBmYWxzZSA9PT0gJGlzX2hlbHAgKSB7CgkJCQkkYWxpYXNlcyA9IFdQX0NMSTo6Z2V0X2NvbmZpZ3VyYXRvcigpLT5nZXRfYWxpYXNlcygpOwoJCQkJZm9yZWFjaCAoICRhbGlhc2VzIGFzICRuYW1lID0+ICRfICkgewoJCQkJCSR0aGlzLT5hZGQoICIkbmFtZSAiICk7CgkJCQl9CgkJCX0KCQkJZm9yZWFjaCAoICRjb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSBhcyAkbmFtZSA9PiAkXyApIHsKCQkJCSR0aGlzLT5hZGQoICIkbmFtZSAiICk7CgkJCX0KCQl9IGVsc2UgewoJCQlmb3JlYWNoICggJHNwZWMgYXMgJGFyZyApIHsKCQkJCWlmICggaW5fYXJyYXkoICRhcmdbJ3R5cGUnXSwgWyAnZmxhZycsICdhc3NvYycgXSwgdHJ1ZSApICkgewoJCQkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkYXJnWyduYW1lJ10gXSApICkgewoJCQkJCQljb250aW51ZTsKCQkJCQl9CgoJCQkJCSRvcHQgPSAiLS17JGFyZ1snbmFtZSddfSI7CgoJCQkJCWlmICggJ2ZsYWcnID09PSAkYXJnWyd0eXBlJ10gKSB7CgkJCQkJCSRvcHQgLj0gJyAnOwoJCQkJCX0gZWxzZWlmICggISAkYXJnWyd2YWx1ZSddWydvcHRpb25hbCddICkgewoJCQkJCQkkb3B0IC49ICc9JzsKCQkJCQl9CgoJCQkJCSR0aGlzLT5hZGQoICRvcHQgKTsKCQkJCX0KCQkJfQoKCQkJZm9yZWFjaCAoICR0aGlzLT5nZXRfZ2xvYmFsX3BhcmFtZXRlcnMoKSBhcyAkcGFyYW0gPT4gJHJ1bnRpbWUgKSB7CgkJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJHBhcmFtIF0gKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkb3B0ID0gIi0teyRwYXJhbX0iOwoKCQkJCWlmICggJycgPT09ICRydW50aW1lIHx8ICEgaXNfc3RyaW5nKCAkcnVudGltZSApICkgewoJCQkJCSRvcHQgLj0gJyAnOwoJCQkJfSBlbHNlIHsKCQkJCQkkb3B0IC49ICc9JzsKCQkJCX0KCgkJCQkkdGhpcy0+YWRkKCAkb3B0ICk7CgkJCX0KCQl9CgoJfQoKCS8qKgoJICogR2V0IHRoZSBzcGVjaWZpYyBXUC1DTEkgY29tbWFuZCB0aGF0IGlzIGJlaW5nIHJlZmVyZW5jZWQuCgkgKgoJICogQHBhcmFtIGFycmF5ICR3b3JkcyBJbmRpdmlkdWFsIGlucHV0IGxpbmUgd29yZHMuCgkgKgoJICogQHJldHVybiBhcnJheXxtaXhlZCBBcnJheSB3aXRoIGNvbW1hbmQgYW5kIGFyZ3VtZW50cywgb3IgZXJyb3IgcmVzdWx0IGlmIGNvbW1hbmQgZGV0ZWN0aW9uIGZhaWxlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29tbWFuZCggJHdvcmRzICkgewoJCSRwb3NpdGlvbmFsX2FyZ3MgPSBbXTsKCQkkYXNzb2NfYXJncyAgICAgID0gW107CgoJCWZvcmVhY2ggKCAkd29yZHMgYXMgJGFyZyApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAnfF4tLShbXj1dKyk9P3wnLCAkYXJnLCAkbWF0Y2hlcyApICkgewoJCQkJJGFzc29jX2FyZ3NbICRtYXRjaGVzWzFdIF0gPSB0cnVlOwoJCQl9IGVsc2UgewoJCQkJJHBvc2l0aW9uYWxfYXJnc1tdID0gJGFyZzsKCQkJfQoJCX0KCgkJJHIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+ZmluZF9jb21tYW5kX3RvX3J1biggJHBvc2l0aW9uYWxfYXJncyApOwoJCWlmICggISBpc19hcnJheSggJHIgKSAmJiBhcnJheV9wb3AoICRwb3NpdGlvbmFsX2FyZ3MgKSA9PT0gJHRoaXMtPmN1cl93b3JkICkgewoJCQkkciA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5maW5kX2NvbW1hbmRfdG9fcnVuKCAkcG9zaXRpb25hbF9hcmdzICk7CgkJfQoKCQlpZiAoICEgaXNfYXJyYXkoICRyICkgKSB7CgkJCXJldHVybiAkcjsKCQl9CgoJCWxpc3QoICRjb21tYW5kLCAkYXJncyApID0gJHI7CgoJCXJldHVybiBbICRjb21tYW5kLCAkYXJncywgJGFzc29jX2FyZ3MgXTsKCX0KCgkvKioKCSAqIEdldCBnbG9iYWwgcGFyYW1ldGVycy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFzc29jaWF0aXZlIGFycmF5IG9mIGdsb2JhbCBwYXJhbWV0ZXJzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9nbG9iYWxfcGFyYW1ldGVycygpIHsKCQkkcGFyYW1zID0gW107CgkJZm9yZWFjaCAoIFdQX0NMSTo6Z2V0X2NvbmZpZ3VyYXRvcigpLT5nZXRfc3BlYygpIGFzICRrZXkgPT4gJGRldGFpbHMgKSB7CgkJCWlmICggZmFsc2UgPT09ICRkZXRhaWxzWydydW50aW1lJ10gKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCBpc3NldCggJGRldGFpbHNbJ2RlcHJlY2F0ZWQnXSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggaXNzZXQoICRkZXRhaWxzWydoaWRkZW4nXSApICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJJHBhcmFtc1sgJGtleSBdID0gJGRldGFpbHNbJ3J1bnRpbWUnXTsKCgkJCS8vIEFkZCBhZGRpdGlvbmFsIG9wdGlvbiBsaWtlIGAtLVtuby1dY29sb3JgLgoJCQlpZiAoIHRydWUgPT09ICRkZXRhaWxzWydydW50aW1lJ10gKSB7CgkJCQkkcGFyYW1zWyAnbm8tJyAuICRrZXkgXSA9ICcnOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHBhcmFtczsKCX0KCgkvKioKCSAqIFN0b3JlIGluZGl2aWR1YWwgb3B0aW9uLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG9wdCBPcHRpb24gdG8gc3RvcmUuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYWRkKCAkb3B0ICkgewoJCWlmICggJycgIT09ICR0aGlzLT5jdXJfd29yZCApIHsKCQkJaWYgKCAwICE9PSBzdHJwb3MoICRvcHQsICR0aGlzLT5jdXJfd29yZCApICkgewoJCQkJcmV0dXJuOwoJCQl9CgkJfQoKCQkkdGhpcy0+b3B0c1tdID0gJG9wdDsKCX0KCgkvKioKCSAqIFJlbmRlciB0aGUgc3RvcmVkIG9wdGlvbnMuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW5kZXIoKSB7CgkJZm9yZWFjaCAoICR0aGlzLT5vcHRzIGFzICRvcHQgKSB7CgkJCVdQX0NMSTo6bGluZSggJG9wdCApOwoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBDbGFzcyBBdXRvbG9hZGVyLgogKgogKiBUaGlzIGlzIGEgY3VzdG9tIGF1dG9sb2FkZXIgdG8gcmVwbGFjZSB0aGUgZnVuY3Rpb25hbGl0eSB0aGF0IHdlIHdvdWxkCiAqIG5vcm1hbGx5IGdldCB0aHJvdWdoIHRoZSBhdXRvbG9hZGVyIGdlbmVyYXRlZCBieSBDb21wb3Nlci4KICoKICogV2UgbmVlZCB0aGlzIHNlcGFyYXRlIGF1dG9sb2FkZXIgZm9yIHRoZSBib290c3RyYXBwaW5nIHByb2Nlc3MsIHdoaWNoIGhhcHBlbnMKICogYmVmb3JlIHRoZSBDb21wb3NlciBhdXRvbG9hZGVyKHMpIGNvdWxkIGJlIGxvYWRlZC4KICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBBdXRvbG9hZGVyIHsKCgkvKioKCSAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIHJlZ2lzdGVyZWQgbmFtZXNwYWNlIHN0cnVjdHVyZXMKCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkbmFtZXNwYWNlcyA9IFtdOwoKCS8qKgoJICogRGVzdHJ1Y3RvciBmb3IgdGhlIEF1dG9sb2FkZXIgY2xhc3MuCgkgKgoJICogVGhlIGRlc3RydWN0b3IgYXV0b21hdGljYWxseSB1bnJlZ2lzdGVycyB0aGUgYXV0b2xvYWQgY2FsbGJhY2sgZnVuY3Rpb24KCSAqIHdpdGggdGhlIFNQTCBhdXRvbG9hZCBzeXN0ZW0uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2Rlc3RydWN0KCkgewoJCSR0aGlzLT51bnJlZ2lzdGVyKCk7Cgl9CgoJLyoqCgkgKiBSZWdpc3RlcnMgdGhlIGF1dG9sb2FkIGNhbGxiYWNrIHdpdGggdGhlIFNQTCBhdXRvbG9hZCBzeXN0ZW0uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZWdpc3RlcigpIHsKCQlzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoIFsgJHRoaXMsICdhdXRvbG9hZCcgXSApOwoJfQoKCS8qKgoJICogVW5yZWdpc3RlcnMgdGhlIGF1dG9sb2FkIGNhbGxiYWNrIHdpdGggdGhlIFNQTCBhdXRvbG9hZCBzeXN0ZW0uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bnJlZ2lzdGVyKCkgewoJCXNwbF9hdXRvbG9hZF91bnJlZ2lzdGVyKCBbICR0aGlzLCAnYXV0b2xvYWQnIF0gKTsKCX0KCgkvKioKCSAqIEFkZCBhIHNwZWNpZmljIG5hbWVzcGFjZSBzdHJ1Y3R1cmUgd2l0aCBvdXIgY3VzdG9tIGF1dG9sb2FkZXIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJHJvb3QgICAgICAgIFJvb3QgbmFtZXNwYWNlIG5hbWUuCgkgKiBAcGFyYW0gc3RyaW5nICAkYmFzZV9kaXIgICAgRGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIGNsYXNzIGZpbGVzLgoJICogQHBhcmFtIHN0cmluZyAgJHByZWZpeCAgICAgIFByZWZpeCB0byBiZSBhZGRlZCBiZWZvcmUgdGhlIGNsYXNzLgoJICogQHBhcmFtIHN0cmluZyAgJHN1ZmZpeCAgICAgIFN1ZmZpeCB0byBiZSBhZGRlZCBhZnRlciB0aGUgY2xhc3MuCgkgKiBAcGFyYW0gYm9vbGVhbiAkbG93ZXJjYXNlICAgV2hldGhlciB0aGUgY2xhc3Mgc2hvdWxkIGJlIGNoYW5nZWQgdG8KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlcmNhc2UuCgkgKiBAcGFyYW0gYm9vbGVhbiAkdW5kZXJzY29yZXMgV2hldGhlciB0aGUgdW5kZXJzY29yZXMgc2hvdWxkIGJlIGNoYW5nZWQgdG8KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeXBoZW5zLgoJICoKCSAqIEByZXR1cm4gc2VsZgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX25hbWVzcGFjZSgKCQkkcm9vdCwKCQkkYmFzZV9kaXIsCgkJJHByZWZpeCA9ICcnLAoJCSRzdWZmaXggPSAnLnBocCcsCgkJJGxvd2VyY2FzZSA9IGZhbHNlLAoJCSR1bmRlcnNjb3JlcyA9IGZhbHNlCgkpIHsKCQkkdGhpcy0+bmFtZXNwYWNlc1tdID0gWwoJCQkncm9vdCcgICAgICAgID0+ICR0aGlzLT5ub3JtYWxpemVfcm9vdCggKHN0cmluZykgJHJvb3QgKSwKCQkJJ2Jhc2VfZGlyJyAgICA9PiAkdGhpcy0+YWRkX3RyYWlsaW5nX3NsYXNoKCAoc3RyaW5nKSAkYmFzZV9kaXIgKSwKCQkJJ3ByZWZpeCcgICAgICA9PiAoc3RyaW5nKSAkcHJlZml4LAoJCQknc3VmZml4JyAgICAgID0+IChzdHJpbmcpICRzdWZmaXgsCgkJCSdsb3dlcmNhc2UnICAgPT4gKGJvb2wpICRsb3dlcmNhc2UsCgkJCSd1bmRlcnNjb3JlcycgPT4gKGJvb2wpICR1bmRlcnNjb3JlcywKCQldOwoKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJLyoqCgkgKiBUaGUgYXV0b2xvYWQgZnVuY3Rpb24gdGhhdCBnZXRzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgU1BMIEF1dG9sb2FkZXIKCSAqIHN5c3RlbS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjbGFzcyBUaGUgY2xhc3MgdGhhdCBnb3QgcmVxdWVzdGVkIGJ5IHRoZSBzcGxfYXV0b2xvYWRlci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGF1dG9sb2FkKCAkY2xhc3MgKSB7CgoJCS8vIEl0ZXJhdGUgb3ZlciBuYW1lc3BhY2VzIHRvIGZpbmQgYSBtYXRjaC4KCQlmb3JlYWNoICggJHRoaXMtPm5hbWVzcGFjZXMgYXMgJG5hbWVzcGFjZSApIHsKCgkJCS8vIE1vdmUgb24gaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBiZWxvbmcgdG8gdGhlIGN1cnJlbnQgbmFtZXNwYWNlLgoJCQlpZiAoIDAgIT09IHN0cnBvcyggJGNsYXNzLCAkbmFtZXNwYWNlWydyb290J10gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBSZW1vdmUgbmFtZXNwYWNlIHJvb3QgbGV2ZWwgdG8gY29ycmVzcG9uZCB3aXRoIHJvb3QgZmlsZXN5c3RlbSwgYW5kCgkJCS8vIHJlcGxhY2UgdGhlIG5hbWVzcGFjZSBzZXBhcmF0b3IgIlwiIGJ5IHRoZSBzeXN0ZW0tZGVwZW5kZW50IGRpcmVjdG9yeSBzZXBhcmF0b3IuCgkJCSRmaWxlbmFtZSA9IHN0cl9yZXBsYWNlKAoJCQkJWyAkbmFtZXNwYWNlWydyb290J10sICdcXCcgXSwKCQkJCVsgJycsIERJUkVDVE9SWV9TRVBBUkFUT1IgXSwKCQkJCSRjbGFzcwoJCQkpOwoKCQkJLy8gUmVtb3ZlIGEgbGVhZGluZyBiYWNrc2xhc2ggZnJvbSB0aGUgY2xhc3MgbmFtZS4KCQkJJGZpbGVuYW1lID0gJHRoaXMtPnJlbW92ZV9sZWFkaW5nX2JhY2tzbGFzaCggJGZpbGVuYW1lICk7CgoJCQkvLyBDaGFuZ2UgdG8gbG93ZXIgY2FzZSBpZiByZXF1ZXN0ZWQuCgkJCWlmICggJG5hbWVzcGFjZVsnbG93ZXJjYXNlJ10gKSB7CgkJCQkkZmlsZW5hbWUgPSBzdHJ0b2xvd2VyKCAkZmlsZW5hbWUgKTsKCQkJfQoKCQkJLy8gQ2hhbmdlIHVuZGVyc2NvcmVzIGludG8gaHlwaGVucyBpZiByZXF1ZXN0ZWQuCgkJCWlmICggJG5hbWVzcGFjZVsndW5kZXJzY29yZXMnXSApIHsKCQkJCSRmaWxlbmFtZSA9IHN0cl9yZXBsYWNlKCAnXycsICctJywgJGZpbGVuYW1lICk7CgkJCX0KCgkJCS8vIEFkZCBiYXNlX2RpciwgcHJlZml4IGFuZCBzdWZmaXguCgkJCSRmaWxlcGF0aCA9ICRuYW1lc3BhY2VbJ2Jhc2VfZGlyJ10KCQkJCS4gJG5hbWVzcGFjZVsncHJlZml4J10KCQkJCS4gJGZpbGVuYW1lCgkJCQkuICRuYW1lc3BhY2VbJ3N1ZmZpeCddOwoKCQkJLy8gVGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSBmaWxlIGRvZXMgbm90IGV4aXN0IG9yIGlzIG5vdCByZWFkYWJsZS4KCQkJaWYgKCBpc19yZWFkYWJsZSggJGZpbGVwYXRoICkgKSB7CgkJCQlyZXF1aXJlX29uY2UgJGZpbGVwYXRoOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogTm9ybWFsaXplIGEgbmFtZXNwYWNlIHJvb3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcm9vdCBOYW1lc3BhY2Ugcm9vdCB0aGF0IG5lZWRzIHRvIGJlIG5vcm1hbGl6ZWQuCgkgKgoJICogQHJldHVybiBzdHJpbmcgTm9ybWFsaXplZCBuYW1lc3BhY2Ugcm9vdC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIG5vcm1hbGl6ZV9yb290KCAkcm9vdCApIHsKCQkkcm9vdCA9ICR0aGlzLT5yZW1vdmVfbGVhZGluZ19iYWNrc2xhc2goICRyb290ICk7CgoJCXJldHVybiAkdGhpcy0+YWRkX3RyYWlsaW5nX2JhY2tzbGFzaCggJHJvb3QgKTsKCX0KCgkvKioKCSAqIFJlbW92ZSBhIGxlYWRpbmcgYmFja3NsYXNoIGZyb20gYSBzdHJpbmcuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFN0cmluZyB0byByZW1vdmUgdGhlIGxlYWRpbmcgYmFja3NsYXNoIGZyb20uCgkgKgoJICogQHJldHVybiBzdHJpbmcgTW9kaWZpZWQgc3RyaW5nLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gcmVtb3ZlX2xlYWRpbmdfYmFja3NsYXNoKCAkc3RyaW5nICkgewoJCXJldHVybiBsdHJpbSggJHN0cmluZywgJ1xcJyApOwoJfQoKCS8qKgoJICogTWFrZSBzdXJlIGEgc3RyaW5nIGVuZHMgd2l0aCBhIHRyYWlsaW5nIGJhY2tzbGFzaC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgU3RyaW5nIHRvIGNoZWNrIHRoZSB0cmFpbGluZyBiYWNrc2xhc2ggb2YuCgkgKgoJICogQHJldHVybiBzdHJpbmcgTW9kaWZpZWQgc3RyaW5nLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkX3RyYWlsaW5nX2JhY2tzbGFzaCggJHN0cmluZyApIHsKCQlyZXR1cm4gcnRyaW0oICRzdHJpbmcsICdcXCcgKSAuICdcXCc7Cgl9CgoJLyoqCgkgKiBNYWtlIHN1cmUgYSBzdHJpbmcgZW5kcyB3aXRoIGEgdHJhaWxpbmcgc2xhc2guCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFN0cmluZyB0byBjaGVjayB0aGUgdHJhaWxpbmcgc2xhc2ggb2YuCgkgKgoJICogQHJldHVybiBzdHJpbmcgTW9kaWZpZWQgc3RyaW5nLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkX3RyYWlsaW5nX3NsYXNoKCAkc3RyaW5nICkgewoJCXJldHVybiBydHJpbSggJHN0cmluZywgJy9cXCcgKSAuICcvJzsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBNdXN0YW5nb3N0YW5nXFNweWM7CgovKioKICogUGFyc2UgY29tbWFuZCBhdHRyaWJ1dGVzIGZyb20gaXRzIFBIUGRvYy4KICogVXNlZCB0byBkZXRlcm1pbmUgZXhlY3V0aW9uIGNoYXJhY3RlcmlzdGljcyAoYXJndW1lbnRzLCBldGMuKS4KICovCmNsYXNzIERvY1BhcnNlciB7CgoJLyoqCgkgKiBQSFBkb2MgY29tbWFuZCBmb3IgdGhlIGNvbW1hbmQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRkb2NfY29tbWVudDsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJGRvY19jb21tZW50CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGRvY19jb21tZW50ICkgewoJCS8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGEga25vd24gbGluZSBlbmRpbmcgaW4gZG9jdW1lbnQgKi8KCQkkZG9jX2NvbW1lbnQgICAgICAgPSBzdHJfcmVwbGFjZSggIlxyXG4iLCAiXG4iLCAkZG9jX2NvbW1lbnQgKTsKCQkkdGhpcy0+ZG9jX2NvbW1lbnQgPSBzZWxmOjpyZW1vdmVfZGVjb3JhdGlvbnMoICRkb2NfY29tbWVudCApOwoJfQoKCS8qKgoJICogUmVtb3ZlIHVudXNlZCBjcnVmdCBmcm9tIFBIUGRvYyBjb21tZW50LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1lbnQgUEhQZG9jIGNvbW1lbnQuCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiByZW1vdmVfZGVjb3JhdGlvbnMoICRjb21tZW50ICkgewoJCSRjb21tZW50ID0gcHJlZ19yZXBsYWNlKCAnfF4vXCpcKltcclxuXSt8JywgJycsICRjb21tZW50ICk7CgkJJGNvbW1lbnQgPSBwcmVnX3JlcGxhY2UoICd8XG5bXHQgXSpcKi8kfCcsICcnLCAkY29tbWVudCApOwoJCSRjb21tZW50ID0gcHJlZ19yZXBsYWNlKCAnfF5bXHQgXSpcKiA/fG0nLCAnJywgJGNvbW1lbnQgKTsKCgkJcmV0dXJuICRjb21tZW50OwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb21tYW5kJ3Mgc2hvcnQgZGVzY3JpcHRpb24gKGUuZy4gc3VtbWFyeSkuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9zaG9ydGRlc2MoKSB7CgkJaWYgKCAhIHByZWdfbWF0Y2goICd8XihbXkBdW15cbl0rKVxuKnwnLCAkdGhpcy0+ZG9jX2NvbW1lbnQsICRtYXRjaGVzICkgKSB7CgkJCXJldHVybiAnJzsKCQl9CgoJCXJldHVybiAkbWF0Y2hlc1sxXTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29tbWFuZCdzIGZ1bGwgZGVzY3JpcHRpb24KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2xvbmdkZXNjKCkgewoJCSRzaG9ydGRlc2MgPSAkdGhpcy0+Z2V0X3Nob3J0ZGVzYygpOwoJCWlmICggISAkc2hvcnRkZXNjICkgewoJCQlyZXR1cm4gJyc7CgkJfQoKCQkkbG9uZ2Rlc2MgPSBzdWJzdHIoICR0aGlzLT5kb2NfY29tbWVudCwgc3RybGVuKCAkc2hvcnRkZXNjICkgKTsKCgkJJGxpbmVzID0gW107CgkJZm9yZWFjaCAoIGV4cGxvZGUoICJcbiIsICRsb25nZGVzYyApIGFzICRsaW5lICkgewoJCQlpZiAoIDAgPT09IHN0cnBvcyggJGxpbmUsICdAJyApICkgewoJCQkJYnJlYWs7CgkJCX0KCgkJCSRsaW5lc1tdID0gJGxpbmU7CgkJfQoKCQlyZXR1cm4gdHJpbSggaW1wbG9kZSggIlxuIiwgJGxpbmVzICkgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgZm9yIGEgZ2l2ZW4gdGFnIChlLmcuICJAYWxpYXMiIG9yICJAc3ViY29tbWFuZCIpCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBOYW1lIGZvciB0aGUgdGFnLCB3aXRob3V0ICdAJwoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF90YWcoICRuYW1lICkgewoJCWlmICggcHJlZ19tYXRjaCggJ3xeQCcgLiAkbmFtZSAuICdccysoW2Etei1fMC05XSspfG0nLCAkdGhpcy0+ZG9jX2NvbW1lbnQsICRtYXRjaGVzICkgKSB7CgkJCXJldHVybiAkbWF0Y2hlc1sxXTsKCQl9CgoJCXJldHVybiAnJzsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29tbWFuZCdzIHN5bm9wc2lzLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc3lub3BzaXMoKSB7CgkJaWYgKCAhIHByZWdfbWF0Y2goICd8XkBzeW5vcHNpc1xzKyguKyl8bScsICR0aGlzLT5kb2NfY29tbWVudCwgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICcnOwoJCX0KCgkJcmV0dXJuICRtYXRjaGVzWzFdOwoJfQoKCS8qKgoJICogR2V0IHRoZSBkZXNjcmlwdGlvbiBmb3IgYSBnaXZlbiBhcmd1bWVudC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIEFyZ3VtZW50J3MgZG9jIG5hbWUuCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2FyZ19kZXNjKCAkbmFtZSApIHsKCgkJaWYgKCBwcmVnX21hdGNoKCAiL1xbPzx7JG5hbWV9Pi4rXG46ICguKz8pKFxufCQpLyIsICR0aGlzLT5kb2NfY29tbWVudCwgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICRtYXRjaGVzWzFdOwoJCX0KCgkJcmV0dXJuICcnOwoKCX0KCgkvKioKCSAqIEdldCB0aGUgYXJndW1lbnRzIGZvciBhIGdpdmVuIGFyZ3VtZW50LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgQXJndW1lbnQncyBkb2MgbmFtZS4KCSAqIEByZXR1cm4gbWl4ZWR8bnVsbAoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2FyZ19hcmdzKCAkbmFtZSApIHsKCQlyZXR1cm4gJHRoaXMtPmdldF9hcmdfb3JfcGFyYW1fYXJncyggIi9eXFs/PHskbmFtZX0+LiovIiApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBkZXNjcmlwdGlvbiBmb3IgYSBnaXZlbiBwYXJhbWV0ZXIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IFBhcmFtZXRlcidzIGtleS4KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfcGFyYW1fZGVzYyggJGtleSApIHsKCgkJaWYgKCBwcmVnX21hdGNoKCAiL1xbPy0teyRrZXl9PS4rXG46ICguKz8pKFxufCQpLyIsICR0aGlzLT5kb2NfY29tbWVudCwgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICRtYXRjaGVzWzFdOwoJCX0KCgkJcmV0dXJuICcnOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhcmd1bWVudHMgZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBQYXJhbWV0ZXIncyBrZXkuCgkgKiBAcmV0dXJuIG1peGVkfG51bGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9wYXJhbV9hcmdzKCAka2V5ICkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2FyZ19vcl9wYXJhbV9hcmdzKCAiL15cWz8tLXska2V5fT0uKi8iICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGFyZ3MgZm9yIGFuIGFyZyBvciBwYXJhbQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlZ2V4IFBhdHRlcm4gdG8gbWF0Y2ggYWdhaW5zdAoJICogQHJldHVybiBhcnJheXxudWxsIEludGVycHJldGVkIFlBTUwgZG9jdW1lbnQsIG9yIG51bGwuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2FyZ19vcl9wYXJhbV9hcmdzKCAkcmVnZXggKSB7CgkJJGJpdHMgICAgICAgPSBleHBsb2RlKCAiXG4iLCAkdGhpcy0+ZG9jX2NvbW1lbnQgKTsKCQkkd2l0aGluX2FyZyA9IGZhbHNlOwoJCSR3aXRoaW5fZG9jID0gZmFsc2U7CgkJJGRvY3VtZW50ICAgPSBbXTsKCQlmb3JlYWNoICggJGJpdHMgYXMgJGJpdCApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAkcmVnZXgsICRiaXQgKSApIHsKCQkJCSR3aXRoaW5fYXJnID0gdHJ1ZTsKCQkJfQoKCQkJaWYgKCAkd2l0aGluX2FyZyAmJiAkd2l0aGluX2RvYyAmJiAnLS0tJyA9PT0gJGJpdCApIHsKCQkJCSR3aXRoaW5fZG9jID0gZmFsc2U7CgkJCX0KCgkJCWlmICggJHdpdGhpbl9hcmcgJiYgISAkd2l0aGluX2RvYyAmJiAnLS0tJyA9PT0gJGJpdCApIHsKCQkJCSR3aXRoaW5fZG9jID0gdHJ1ZTsKCQkJfQoKCQkJaWYgKCAkd2l0aGluX2RvYyApIHsKCQkJCSRkb2N1bWVudFtdID0gJGJpdDsKCQkJfQoKCQkJaWYgKCAkd2l0aGluX2FyZyAmJiAnJyA9PT0gJGJpdCApIHsKCQkJCSR3aXRoaW5fYXJnID0gZmFsc2U7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCAkZG9jdW1lbnQgKSB7CgkJCXJldHVybiBTcHljOjpZQU1MTG9hZFN0cmluZyggaW1wbG9kZSggIlxuIiwgJGRvY3VtZW50ICkgKTsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcQ29udGV4dDsKdXNlIFdQX0NMSVxDb250ZXh0TWFuYWdlcjsKCi8qKgogKiBDbGFzcyBJbml0aWFsaXplQ29udGV4dHMuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIEluaXRpYWxpemVDb250ZXh0cyBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQkkY29udGV4dF9tYW5hZ2VyID0gbmV3IENvbnRleHRNYW5hZ2VyKCk7CgoJCSRjb250ZXh0cyA9IFsKCQkJQ29udGV4dDo6Q0xJICAgICAgPT4gbmV3IENvbnRleHRcQ2xpKCksCgkJCUNvbnRleHQ6OkFETUlOICAgID0+IG5ldyBDb250ZXh0XEFkbWluKCksCgkJCUNvbnRleHQ6OkZST05URU5EID0+IG5ldyBDb250ZXh0XEZyb250ZW5kKCksCgkJCUNvbnRleHQ6OkFVVE8gICAgID0+IG5ldyBDb250ZXh0XEF1dG8oICRjb250ZXh0X21hbmFnZXIgKSwKCQldOwoKCQkkY29udGV4dHMgPSBXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfcmVnaXN0ZXJpbmdfY29udGV4dHMnLCAkY29udGV4dHMgKTsKCgkJZm9yZWFjaCAoICRjb250ZXh0cyBhcyAkbmFtZSA9PiAkaW1wbGVtZW50YXRpb24gKSB7CgkJCSRjb250ZXh0X21hbmFnZXItPnJlZ2lzdGVyX2NvbnRleHQoICRuYW1lLCAkaW1wbGVtZW50YXRpb24gKTsKCQl9CgoJCSRzdGF0ZS0+c2V0VmFsdWUoICdjb250ZXh0X21hbmFnZXInLCAkY29udGV4dF9tYW5hZ2VyICk7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKLyoqCiAqIENsYXNzIExhdW5jaFJ1bm5lci4KICoKICogS2ljayBvZmYgdGhlIFJ1bm5lciBvYmplY3QgdGhhdCBzdGFydHMgdGhlIGFjdHVhbCBjb21tYW5kcy4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgTGF1bmNoUnVubmVyIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCSRydW5uZXIgPSBuZXcgUnVubmVySW5zdGFuY2UoKTsKCgkJJHJ1bm5lcigpLT5yZWdpc3Rlcl9jb250ZXh0X21hbmFnZXIoCgkJCSRzdGF0ZS0+Z2V0VmFsdWUoICdjb250ZXh0X21hbmFnZXInICkKCQkpOwoKCQkkcnVubmVyKCktPnN0YXJ0KCk7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKLyoqCiAqIENsYXNzIEJvb3RzdHJhcFN0YXRlLgogKgogKiBSZXByZXNlbnRzIHRoZSBzdGF0ZSB0aGF0IGlzIHBhc3NlZCBmcm9tIG9uZSBib290c3RyYXAgc3RlcCB0byB0aGUgbmV4dC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKgogKiBNYWludGFpbiBCQzogQ2hhbmdpbmcgdGhlIG1ldGhvZCBuYW1lcyBpbiB0aGlzIGNsYXNzIGJyZWFrcyBhdXRvbG9hZCBpbnRlcmFjdGlvbnMgYmV0d2VlbiBQaGFyCiAqICYgZnJhbWV3b3JrL2NvbW1hbmRzIHlvdSB1c2Ugb3V0c2lkZSBvZiBQaGFyIChsaWtlIHdoZW4gcnVubmluZyB0aGUgUGhhciBXUCBpbnNpZGUgb2YgYSBjb21tYW5kIGZvbGRlcikuCiAqIEBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5WYWxpZEZ1bmN0aW9uTmFtZS5NZXRob2ROYW1lSW52YWxpZAogKi8KY2xhc3MgQm9vdHN0cmFwU3RhdGUgewoKCS8qKgoJICogV2hldGhlciB0aGUgY29tbWFuZCBjdXJyZW50bHkgYmVpbmcgcnVuIGlzICJwcm90ZWN0ZWQiLgoJICoKCSAqIFRoaXMgbWVhbnMgdGhhdCB0aGUgY29tbWFuZCBzaG91bGQgbm90IGJlIGFsbG93ZWQgdG8gYnJlYWsgZHVlIHRvCgkgKiBleHRlbnNpb24gY29kZS4KCSAqLwoJY29uc3QgSVNfUFJPVEVDVEVEX0NPTU1BTkQgPSAnaXNfcHJvdGVjdGVkX2NvbW1hbmQnOwoKCS8qKgoJICogSW50ZXJuYWwgc3RvcmFnZSBvZiB0aGUgc3RhdGUgdmFsdWVzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkc3RhdGUgPSBbXTsKCgkvKioKCSAqIEdldCB0aGUgc3RhdGUgdmFsdWUgZm9yIGEgZ2l2ZW4ga2V5LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSAgICAgIEtleSB0byBnZXQgdGhlIHN0YXRlIGZyb20uCgkgKiBAcGFyYW0gbWl4ZWQgICRmYWxsYmFjayBGYWxsYmFjayB2YWx1ZSB0byB1c2UgaWYgdGhlIGtleSBpcyBub3QgZGVmaW5lZC4KCSAqCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSggJGtleSwgJGZhbGxiYWNrID0gbnVsbCApIHsKCQlyZXR1cm4gYXJyYXlfa2V5X2V4aXN0cyggJGtleSwgJHRoaXMtPnN0YXRlICkKCQkJPyAkdGhpcy0+c3RhdGVbICRrZXkgXQoJCQk6ICRmYWxsYmFjazsKCX0KCgkvKioKCSAqIFNldCB0aGUgc3RhdGUgdmFsdWUgZm9yIGEgZ2l2ZW4ga2V5LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSAgIEtleSB0byBzZXQgdGhlIHN0YXRlIGZvci4KCSAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlIFZhbHVlIHRvIHNldCB0aGUgc3RhdGUgZm9yIHRoZSBnaXZlbiBrZXkgdG8uCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSggJGtleSwgJHZhbHVlICkgewoJCSR0aGlzLT5zdGF0ZVsgJGtleSBdID0gJHZhbHVlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCi8qKgogKiBDbGFzcyBEZWNsYXJlQWJzdHJhY3RCYXNlQ29tbWFuZC4KICoKICogRGVjbGFyZXMgdGhlIGFic3RyYWN0IGBXUF9DTElfQ29tbWFuZGAgYmFzZSBjbGFzcy4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgRGVjbGFyZUFic3RyYWN0QmFzZUNvbW1hbmQgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvY2xhc3Mtd3AtY2xpLWNvbW1hbmQucGhwJzsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgRGVjbGFyZU1haW5DbGFzcy4KICoKICogRGVjbGFyZXMgdGhlIG1haW4gYFdQX0NMSWAgY2xhc3MuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIERlY2xhcmVNYWluQ2xhc3MgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvY2xhc3Mtd3AtY2xpLnBocCc7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKLyoqCiAqIENsYXNzIExvYWREaXNwYXRjaGVyLgogKgogKiBMb2FkcyB0aGUgZGlzcGF0Y2hlciB0aGF0IHdpbGwgZGlzcGF0Y2ggY29tbWFuZCBuYW1lcyB0byBmaWxlIGxvY2F0aW9ucy4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgTG9hZERpc3BhdGNoZXIgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvZGlzcGF0Y2hlci5waHAnOwoKCQlyZXR1cm4gJHN0YXRlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCi8qKgogKiBDbGFzcyBJbml0aWFsaXplQ29sb3JpemF0aW9uLgogKgogKiBJbml0aWFsaXplIHRoZSBjb2xvcml6YXRpb24gdGhyb3VnaCB0aGUgYFdQX0NMSVxSdW5uZXJgIG9iamVjdC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgSW5pdGlhbGl6ZUNvbG9yaXphdGlvbiBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQkkcnVubmVyID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgkJJHJ1bm5lcigpLT5pbml0X2NvbG9yaXphdGlvbigpOwoKCQlyZXR1cm4gJHN0YXRlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCi8qKgogKiBDbGFzcyBDb25maWd1cmVSdW5uZXIuCiAqCiAqIEluaXRpYWxpemUgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBgV1BfQ0xJXFJ1bm5lcmAgb2JqZWN0LgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBDb25maWd1cmVSdW5uZXIgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJJHJ1bm5lciA9IG5ldyBSdW5uZXJJbnN0YW5jZSgpOwoJCSRydW5uZXIoKS0+aW5pdF9jb25maWcoKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgRGVmaW5lUHJvdGVjdGVkQ29tbWFuZHMuCiAqCiAqIERlZmluZSB0aGUgY29tbWFuZHMgdGhhdCBhcmUgInByb3RlY3RlZCIsIG1lYW5pbmcgdGhhdCB0aGV5IHNob3VsZG4ndCBiZSBhYmxlCiAqIHRvIGJyZWFrIGR1ZSB0byBleHRlbnNpb24gY29kZS4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgRGVmaW5lUHJvdGVjdGVkQ29tbWFuZHMgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJJGNvbW1hbmRzICAgICAgICA9ICR0aGlzLT5nZXRfcHJvdGVjdGVkX2NvbW1hbmRzKCk7CgkJJGN1cnJlbnRfY29tbWFuZCA9ICR0aGlzLT5nZXRfY3VycmVudF9jb21tYW5kKCk7CgoJCWZvcmVhY2ggKCAkY29tbWFuZHMgYXMgJGNvbW1hbmQgKSB7CgkJCWlmICggMCA9PT0gc3RycG9zKCAkY3VycmVudF9jb21tYW5kLCAkY29tbWFuZCApICkgewoJCQkJJHN0YXRlLT5zZXRWYWx1ZSggQm9vdHN0cmFwU3RhdGU6OklTX1BST1RFQ1RFRF9DT01NQU5ELCB0cnVlICk7CgkJCX0KCQl9CgoJCXJldHVybiAkc3RhdGU7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGxpc3Qgb2YgcHJvdGVjdGVkIGNvbW1hbmRzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcHJvdGVjdGVkX2NvbW1hbmRzKCkgewoJCXJldHVybiBbCgkJCSdjbGkgaW5mbycsCgkJCSdwYWNrYWdlJywKCQldOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjdXJyZW50IGNvbW1hbmQgYXMgYSBzdHJpbmcuCgkgKgoJICogQHJldHVybiBzdHJpbmcgQ3VycmVudCBjb21tYW5kIHRvIGJlIGV4ZWN1dGVkLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jdXJyZW50X2NvbW1hbmQoKSB7CgkJJHJ1bm5lciA9IG5ldyBSdW5uZXJJbnN0YW5jZSgpOwoKCQlyZXR1cm4gaW1wbG9kZSggJyAnLCAoYXJyYXkpICRydW5uZXIoKS0+YXJndW1lbnRzICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKLyoqCiAqIENsYXNzIERlY2xhcmVGYWxsYmFja0Z1bmN0aW9ucy4KICoKICogRGVjbGFyZXMgZnVuY3Rpb25zIHRoYXQgbWlnaHQgaGF2ZSBiZWVuIGRpc2FibGVkIGJ1dCBhcmUgcmVxdWlyZWQuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIERlY2xhcmVGYWxsYmFja0Z1bmN0aW9ucyBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCWluY2x1ZGUgX19ESVJfXyAuICcvLi4vLi4vZmFsbGJhY2stZnVuY3Rpb25zLnBocCc7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDbGFzcyBMb2FkRXh0cmFDb21tYW5kLgogKgogKiBMb2FkcyBhIGNvbW1hbmQgdGhhdCB3YXMgcGFzc2VkIHRocm91Z2ggdGhlIGAtLWV4ZWM9PHBocC1jb2RlPmAgb3B0aW9uLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBMb2FkRXhlY0NvbW1hbmQgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJaWYgKCAkc3RhdGUtPmdldFZhbHVlKCBCb290c3RyYXBTdGF0ZTo6SVNfUFJPVEVDVEVEX0NPTU1BTkQsIGZhbHNlICkgKSB7CgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQkkcnVubmVyID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgkJaWYgKCAhIGlzc2V0KCAkcnVubmVyKCktPmNvbmZpZ1snZXhlYyddICkgKSB7CgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQlmb3JlYWNoICggJHJ1bm5lcigpLT5jb25maWdbJ2V4ZWMnXSBhcyAkcGhwX2NvZGUgKSB7CgkJCWV2YWwoICRwaHBfY29kZSApOyAvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkV2YWwuRGlzY291cmFnZWQKCQl9CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKLyoqCiAqIEludGVyZmFjZSBCb290c3RyYXBTdGVwLgogKgogKiBSZXByZXNlbnRzIGEgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcCB0aGF0IGNhbiBiZSBwcm9jZXNzZWQuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmludGVyZmFjZSBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKTsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIENsYXNzIExvYWRSZXF1aXJlZENvbW1hbmQuCiAqCiAqIExvYWRzIGEgY29tbWFuZCB0aGF0IHdhcyBwYXNzZWQgdGhyb3VnaCB0aGUgYC0tcmVxdWlyZT08Y29tbWFuZD5gIG9wdGlvbi4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgTG9hZFJlcXVpcmVkQ29tbWFuZCBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQlpZiAoICRzdGF0ZS0+Z2V0VmFsdWUoIEJvb3RzdHJhcFN0YXRlOjpJU19QUk9URUNURURfQ09NTUFORCwgZmFsc2UgKSApIHsKCQkJcmV0dXJuICRzdGF0ZTsKCQl9CgoJCSRydW5uZXIgPSBuZXcgUnVubmVySW5zdGFuY2UoKTsKCQlpZiAoICEgaXNzZXQoICRydW5uZXIoKS0+Y29uZmlnWydyZXF1aXJlJ10gKSApIHsKCQkJcmV0dXJuICRzdGF0ZTsKCQl9CgoJCWZvcmVhY2ggKCAkcnVubmVyKCktPmNvbmZpZ1sncmVxdWlyZSddIGFzICRwYXRoICkgewoJCQlpZiAoICEgZmlsZV9leGlzdHMoICRwYXRoICkgKSB7CgkJCQkkY29udGV4dCAgICAgICAgPSAnJzsKCQkJCSRyZXF1aXJlZF9maWxlcyA9ICRydW5uZXIoKS0+Z2V0X3JlcXVpcmVkX2ZpbGVzKCk7CgkJCQlmb3JlYWNoICggWyAnZ2xvYmFsJywgJ3Byb2plY3QnLCAncnVudGltZScgXSBhcyAkc2NvcGUgKSB7CgkJCQkJaWYgKCBpbl9hcnJheSggJHBhdGgsICRyZXF1aXJlZF9maWxlc1sgJHNjb3BlIF0sIHRydWUgKSApIHsKCQkJCQkJc3dpdGNoICggJHNjb3BlICkgewoJCQkJCQkJY2FzZSAnZ2xvYmFsJzoKCQkJCQkJCQkkY29udGV4dCA9ICcgKGZyb20gZ2xvYmFsICcgLiBVdGlsc1xiYXNlbmFtZSggJHJ1bm5lcigpLT5nZXRfZ2xvYmFsX2NvbmZpZ19wYXRoKCkgKSAuICcpJzsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3Byb2plY3QnOgoJCQkJCQkJCSRjb250ZXh0ID0gJyAoZnJvbSBwcm9qZWN0XCdzICcgLiBVdGlsc1xiYXNlbmFtZSggJHJ1bm5lcigpLT5nZXRfcHJvamVjdF9jb25maWdfcGF0aCgpICkgLiAnKSc7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdydW50aW1lJzoKCQkJCQkJCQkkY29udGV4dCA9ICcgKGZyb20gcnVudGltZSBhcmd1bWVudCknOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJSZXF1aXJlZCBmaWxlICclcycgZG9lc24ndCBleGlzdCVzLiIsIFV0aWxzXGJhc2VuYW1lKCAkcGF0aCApLCAkY29udGV4dCApICk7CgkJCX0KCQkJVXRpbHNcbG9hZF9maWxlKCAkcGF0aCApOwoJCQlXUF9DTEk6OmRlYnVnKCAnUmVxdWlyZWQgZmlsZSBmcm9tIGNvbmZpZzogJyAuICRwYXRoLCAnYm9vdHN0cmFwJyApOwoJCX0KCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgTG9hZFV0aWxpdHlGdW5jdGlvbnMuCiAqCiAqIExvYWRzIHRoZSBmdW5jdGlvbnMgYXZhaWxhYmxlIHRocm91Z2ggYFdQX0NMSVxVdGlsc2AuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIExvYWRVdGlsaXR5RnVuY3Rpb25zIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCXJlcXVpcmVfb25jZSBXUF9DTElfUk9PVCAuICcvcGhwL3V0aWxzLnBocCc7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIFdQX0NMSTsKCi8qKgogKiBBYnN0cmFjdCBjbGFzcyBBdXRvbG9hZGVyU3RlcC4KICoKICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3Igc3RlcHMgdGhhdCBpbmNsdWRlIGFuIGF1dG9sb2FkZXIuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmFic3RyYWN0IGNsYXNzIEF1dG9sb2FkZXJTdGVwIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBTdG9yZSBzdGF0ZSBmb3Igc3ViY2xhc3NlcyB0byBoYXZlIGFjY2Vzcy4KCSAqCgkgKiBAdmFyIEJvb3RzdHJhcFN0YXRlCgkgKi8KCXByb3RlY3RlZCAkc3RhdGU7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCSR0aGlzLT5zdGF0ZSA9ICRzdGF0ZTsKCgkJJGZvdW5kX2F1dG9sb2FkZXIgPSBmYWxzZTsKCQkkYXV0b2xvYWRlcl9wYXRocyA9ICR0aGlzLT5nZXRfYXV0b2xvYWRlcl9wYXRocygpOwoKCQlpZiAoIGZhbHNlID09PSAkYXV0b2xvYWRlcl9wYXRocyApIHsKCQkJLy8gU2tpcCB0aGlzIGF1dG9sb2FkaW5nIHN0ZXAuCgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQlmb3JlYWNoICggJGF1dG9sb2FkZXJfcGF0aHMgYXMgJGF1dG9sb2FkZXJfcGF0aCApIHsKCQkJaWYgKCBpc19yZWFkYWJsZSggJGF1dG9sb2FkZXJfcGF0aCApICkgewoJCQkJdHJ5IHsKCQkJCQlXUF9DTEk6OmRlYnVnKAoJCQkJCQlzcHJpbnRmKAoJCQkJCQkJJ0xvYWRpbmcgZGV0ZWN0ZWQgYXV0b2xvYWRlcjogJXMnLAoJCQkJCQkJJGF1dG9sb2FkZXJfcGF0aAoJCQkJCQkpLAoJCQkJCQknYm9vdHN0cmFwJwoJCQkJCSk7CgkJCQkJcmVxdWlyZSAkYXV0b2xvYWRlcl9wYXRoOwoJCQkJCSRmb3VuZF9hdXRvbG9hZGVyID0gdHJ1ZTsKCQkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJCSJGYWlsZWQgdG8gbG9hZCBhdXRvbG9hZGVyICd7JGF1dG9sb2FkZXJfcGF0aH0nLiBSZWFzb246ICIKCQkJCQkJLiAkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkKCQkJCQkpOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICEgJGZvdW5kX2F1dG9sb2FkZXIgKSB7CgkJCSR0aGlzLT5oYW5kbGVfZmFpbHVyZSgpOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5zdGF0ZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgbmFtZSBvZiB0aGUgY3VzdG9tIHZlbmRvciBmb2xkZXIgYXMgc2V0IGluIGBjb21wb3Nlci5qc29uYC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBOYW1lIG9mIHRoZSBjdXN0b20gdmVuZG9yIGZvbGRlciBvciBmYWxzZSBpZiBub25lLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2N1c3RvbV92ZW5kb3JfZm9sZGVyKCkgewoJCSRtYXliZV9jb21wb3Nlcl9qc29uID0gV1BfQ0xJX1JPT1QgLiAnLy4uLy4uLy4uL2NvbXBvc2VyLmpzb24nOwoJCWlmICggISBpc19yZWFkYWJsZSggJG1heWJlX2NvbXBvc2VyX2pzb24gKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJGNvbXBvc2VyID0ganNvbl9kZWNvZGUoIGZpbGVfZ2V0X2NvbnRlbnRzKCAkbWF5YmVfY29tcG9zZXJfanNvbiApICk7CgoJCWlmICggISBlbXB0eSggJGNvbXBvc2VyLT5jb25maWcgKQoJCQkmJiAhIGVtcHR5KCAkY29tcG9zZXItPmNvbmZpZy0+eyd2ZW5kb3ItZGlyJ30gKQoJCSkgewoJCQlyZXR1cm4gJGNvbXBvc2VyLT5jb25maWctPnsndmVuZG9yLWRpcid9OwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogSGFuZGxlIHRoZSBmYWlsdXJlIHRvIGZpbmQgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGhhbmRsZV9mYWlsdXJlKCkgeyB9CgoJLyoqCgkgKiBHZXQgdGhlIGF1dG9sb2FkZXIgcGF0aHMgdG8gc2NhbiBmb3IgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ1tdfGZhbHNlIEFycmF5IG9mIHN0cmluZ3Mgd2l0aCBhdXRvbG9hZGVyIHBhdGhzLCBvciBmYWxzZQoJICogICAgICAgICAgICAgICAgICAgICAgICB0byBza2lwLgoJICovCglhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2F1dG9sb2FkZXJfcGF0aHMoKTsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7Cgp1c2UgRGlyZWN0b3J5SXRlcmF0b3I7CnVzZSBFeGNlcHRpb247CnVzZSBXUF9DTEk7CgovKioKICogQ2xhc3MgUmVnaXN0ZXJGcmFtZXdvcmtDb21tYW5kcy4KICoKICogUmVnaXN0ZXIgdGhlIGNvbW1hbmRzIHRoYXQgYXJlIGRpcmVjdGx5IGluY2x1ZGVkIHdpdGggdGhlIGZyYW1ld29yay4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgUmVnaXN0ZXJGcmFtZXdvcmtDb21tYW5kcyBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQkkY21kX2RpciA9IFdQX0NMSV9ST09UIC4gJy9waHAvY29tbWFuZHMnOwoKCQkkaXRlcmF0b3IgPSBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRjbWRfZGlyICk7CgoJCWZvcmVhY2ggKCAkaXRlcmF0b3IgYXMgJGZpbGVuYW1lICkgewoJCQlpZiAoICcucGhwJyAhPT0gc3Vic3RyKCAkZmlsZW5hbWUsIC0gNCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCXRyeSB7CgkJCQlXUF9DTEk6OmRlYnVnKAoJCQkJCXNwcmludGYoCgkJCQkJCSdBZGRpbmcgZnJhbWV3b3JrIGNvbW1hbmQ6ICVzJywKCQkJCQkJIiRjbWRfZGlyLyRmaWxlbmFtZSIKCQkJCQkpLAoJCQkJCSdib290c3RyYXAnCgkJCQkpOwoKCQkJCWluY2x1ZGVfb25jZSAiJGNtZF9kaXIvJGZpbGVuYW1lIjsKCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCSJDb3VsZCBub3QgYWRkIGNvbW1hbmQgeyRjbWRfZGlyfS97JGZpbGVuYW1lfS4gUmVhc29uOiAiIC4gJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpCgkJCQkpOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHN0YXRlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCnVzZSBEaXJlY3RvcnlJdGVyYXRvcjsKCi8qKgogKiBDbGFzcyBJbml0aWFsaXplTG9nZ2VyLgogKgogKiBJbml0aWFsaXplIHRoZSBsb2dnZXIgdGhyb3VnaCB0aGUgYFdQX0NMSVxSdW5uZXJgIG9iamVjdC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgSW5pdGlhbGl6ZUxvZ2dlciBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQkkdGhpcy0+ZGVjbGFyZV9sb2dnZXJzKCk7CgkJJHJ1bm5lciA9IG5ldyBSdW5uZXJJbnN0YW5jZSgpOwoJCSRydW5uZXIoKS0+aW5pdF9sb2dnZXIoKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIGNsYXNzIGRlY2xhcmF0aW9ucyBmb3IgdGhlIGxvZ2dlcnMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZGVjbGFyZV9sb2dnZXJzKCkgewoJCSRsb2dnZXJfZGlyID0gV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvTG9nZ2Vycyc7CgkJJGl0ZXJhdG9yICAgPSBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRsb2dnZXJfZGlyICk7CgoJCS8vIE1ha2Ugc3VyZSB0aGUgYmFzZSBjbGFzcyBpcyBkZWNsYXJlZCBmaXJzdC4KCQlpbmNsdWRlX29uY2UgIiRsb2dnZXJfZGlyL0Jhc2UucGhwIjsKCgkJZm9yZWFjaCAoICRpdGVyYXRvciBhcyAkZmlsZW5hbWUgKSB7CgkJCWlmICggJy5waHAnICE9PSBzdWJzdHIoICRmaWxlbmFtZSwgLSA0ICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaW5jbHVkZV9vbmNlICIkbG9nZ2VyX2Rpci8kZmlsZW5hbWUiOwoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7Cgp1c2UgV1BfQ0xJXEF1dG9sb2FkZXI7CgovKioKICogQ2xhc3MgSW5jbHVkZUZyYW1ld29ya0F1dG9sb2FkZXIuCiAqCiAqIExvYWRzIHRoZSBmcmFtZXdvcmsgYXV0b2xvYWRlciB0aHJvdWdoIGFuIGF1dG9sYW9kZXIgc2VwYXJhdGUgZnJvbSB0aGUKICogQ29tcG9zZXIgb25lLCB0byBhdm9pZCBjb3VwbGluZyB0aGUgbG9hZGluZyBvZiB0aGUgZnJhbWV3b3JrIHdpdGggYnVuZGxlZAogKiBjb21tYW5kcy4KICoKICogVGhpcyBvbmx5IGNvbnRhaW5zIGNsYXNzZXMgZm9yIHRoZSBmcmFtZXdvcmsuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIEluY2x1ZGVGcmFtZXdvcmtBdXRvbG9hZGVyIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCWlmICggISBjbGFzc19leGlzdHMoICdXUF9DTElcQXV0b2xvYWRlcicgKSApIHsKCQkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvV1BfQ0xJL0F1dG9sb2FkZXIucGhwJzsKCQl9CgoJCSRhdXRvbG9hZGVyID0gbmV3IEF1dG9sb2FkZXIoKTsKCgkJJG1hcHBpbmdzID0gWwoJCQknV1BfQ0xJJyAgICAgICAgICAgICAgICAgICA9PiBXUF9DTElfUk9PVCAuICcvcGhwL1dQX0NMSScsCgkJCSdjbGknICAgICAgICAgICAgICAgICAgICAgID0+IFdQX0NMSV9WRU5ET1JfRElSIC4gJy93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpJywKCQkJJ1JlcXVlc3RzJyAgICAgICAgICAgICAgICAgPT4gV1BfQ0xJX1ZFTkRPUl9ESVIgLiAnL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzJywKCQkJJ1N5bWZvbnlcQ29tcG9uZW50XEZpbmRlcicgPT4gV1BfQ0xJX1ZFTkRPUl9ESVIgLiAnL3N5bWZvbnkvZmluZGVyLycsCgkJXTsKCgkJZm9yZWFjaCAoICRtYXBwaW5ncyBhcyAkbmFtZXNwYWNlID0+ICRmb2xkZXIgKSB7CgkJCSRhdXRvbG9hZGVyLT5hZGRfbmFtZXNwYWNlKAoJCQkJJG5hbWVzcGFjZSwKCQkJCSRmb2xkZXIKCQkJKTsKCQl9CgoJCWluY2x1ZGVfb25jZSBXUF9DTElfVkVORE9SX0RJUiAuICcvcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMucGhwJzsKCQlpbmNsdWRlX29uY2UgV1BfQ0xJX1ZFTkRPUl9ESVIgLiAnL3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMvU3B5Yy5waHAnOwoKCQkkYXV0b2xvYWRlci0+cmVnaXN0ZXIoKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIENsYXNzIFJlZ2lzdGVyRGVmZXJyZWRDb21tYW5kcy4KICoKICogUmVnaXN0ZXJzIHRoZSBkZWZlcnJlZCBjb21tYW5kcyB0aGF0IGZvciB3aGljaCBubyBwYXJlbnQgd2FzIHJlZ2lzdGVyZWQgeWV0LgogKiBUaGlzIGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSB3ZSBjYW4gaGF2ZSBzdWItY29tbWFuZHMgdGhhdCBoYXZlIG5vIGRpcmVjdAogKiBwYXJlbnQsIGxpa2UgYHdwIG5ldHdvcmsgbWV0YWAuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIFJlZ2lzdGVyRGVmZXJyZWRDb21tYW5kcyBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCgkJLy8gUHJvY2VzcyBkZWZlcnJlZCBjb21tYW5kIGFkZGl0aW9ucyBmb3IgZXh0ZXJuYWwgcGFja2FnZXMuCgkJJHRoaXMtPmFkZF9kZWZlcnJlZF9jb21tYW5kcygpOwoKCQkvLyBQcm9jZXNzIGRlZmVycmVkIGNvbW1hbmQgYWRkaXRpb25zIGZvciBjb21tYW5kcyBhZGRlZCB0aHJvdWdoCgkJLy8gcGx1Z2lucy4KCQlXUF9DTEk6OmFkZF9ob29rKAoJCQknYmVmb3JlX3J1bl9jb21tYW5kJywKCQkJWyAkdGhpcywgJ2FkZF9kZWZlcnJlZF9jb21tYW5kcycgXQoJCSk7CgoJCXJldHVybiAkc3RhdGU7Cgl9CgoJLyoqCgkgKiBBZGQgZGVmZXJyZWQgY29tbWFuZHMgdGhhdCBhcmUgc3RpbGwgd2FpdGluZyB0byBiZSBwcm9jZXNzZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfZGVmZXJyZWRfY29tbWFuZHMoKSB7CgkJJGRlZmVycmVkX2FkZGl0aW9ucyA9IFdQX0NMSTo6Z2V0X2RlZmVycmVkX2FkZGl0aW9ucygpOwoKCQlmb3JlYWNoICggJGRlZmVycmVkX2FkZGl0aW9ucyBhcyAkbmFtZSA9PiAkYWRkaXRpb24gKSB7CgkJCSRhZGRpdGlvbl9kYXRhID0gW107CgkJCWZvcmVhY2ggKCAkYWRkaXRpb24gYXMgJGFkZGl0aW9uX2tleSA9PiAkYWRkaXRpb25fdmFsdWUgKSB7CgkJCQkvLyBEZXNjcmliZSB0aGUgY2FsbGFibGUgYXMgYSBzdHJpbmcgaW5zdGVhZCBvZiBkaXJlY3RseSBwcmludGluZyBpdAoJCQkJLy8gZm9yIGJldHRlciBkZWJ1ZyBpbmZvLgoJCQkJaWYgKCAnY2FsbGFibGUnID09PSAkYWRkaXRpb25fa2V5ICkgewoJCQkJCSRhZGRpdGlvbl92YWx1ZSA9IFV0aWxzXGRlc2NyaWJlX2NhbGxhYmxlKCAkYWRkaXRpb25fdmFsdWUgKTsKCgkJCQl9IGVsc2VpZiAoIGlzX2FycmF5KCAkYWRkaXRpb25fdmFsdWUgKSApIHsKCQkJCQkkYWRkaXRpb25fdmFsdWUgPSBqc29uX2VuY29kZSggJGFkZGl0aW9uX3ZhbHVlICk7CgkJCQl9CgoJCQkJJGFkZGl0aW9uX2RhdGFbXSA9IHNwcmludGYoCgkJCQkJJyVzOiAlcycsCgkJCQkJJGFkZGl0aW9uX2tleSwKCQkJCQkkYWRkaXRpb25fdmFsdWUKCQkJCSk7CgkJCX0KCgkJCVdQX0NMSTo6ZGVidWcoCgkJCQlzcHJpbnRmKAoJCQkJCSdBZGRpbmcgZGVmZXJyZWQgY29tbWFuZDogJXMgKCVzKScsCgkJCQkJJG5hbWUsCgkJCQkJaW1wbG9kZSggJywgJywgJGFkZGl0aW9uX2RhdGEgKQoJCQkJKSwKCQkJCSdib290c3RyYXAnCgkJCSk7CgoJCQlXUF9DTEk6OmFkZF9jb21tYW5kKAoJCQkJJG5hbWUsCgkJCQkkYWRkaXRpb25bJ2NhbGxhYmxlJ10sCgkJCQkkYWRkaXRpb25bJ2FyZ3MnXQoJCQkpOwoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7Cgp1c2UgV1BfQ0xJOwoKLyoqCiAqIENsYXNzIEluY2x1ZGVGYWxsYmFja0F1dG9sb2FkZXIuCiAqCiAqIExvYWRzIHRoZSBmYWxsYmFjayBhdXRvbG9hZGVyIHRoYXQgaXMgcHJvdmlkZWQgdGhyb3VnaCB0aGUgYGNvbXBvc2VyLmpzb25gCiAqIGZpbGUuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIEluY2x1ZGVGYWxsYmFja0F1dG9sb2FkZXIgZXh0ZW5kcyBBdXRvbG9hZGVyU3RlcCB7CgoJLyoqCgkgKiBHZXQgdGhlIGF1dG9sb2FkZXIgcGF0aHMgdG8gc2NhbiBmb3IgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ1tdfGZhbHNlIEFycmF5IG9mIHN0cmluZ3Mgd2l0aCBhdXRvbG9hZGVyIHBhdGhzLCBvciBmYWxzZQoJICogICAgICAgICAgICAgICAgICAgICAgICB0byBza2lwLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2F1dG9sb2FkZXJfcGF0aHMoKSB7CgkJJGF1dG9sb2FkZXJfcGF0aHMgPSBbCgkJCVdQX0NMSV9WRU5ET1JfRElSIC4gJy9hdXRvbG9hZC5waHAnLAoJCV07CgoJCSRjdXN0b21fdmVuZG9yID0gJHRoaXMtPmdldF9jdXN0b21fdmVuZG9yX2ZvbGRlcigpOwoJCWlmICggZmFsc2UgIT09ICRjdXN0b21fdmVuZG9yICkgewoJCQlhcnJheV91bnNoaWZ0KAoJCQkJJGF1dG9sb2FkZXJfcGF0aHMsCgkJCQlXUF9DTElfUk9PVCAuICcvLi4vLi4vLi4vJyAuICRjdXN0b21fdmVuZG9yIC4gJy9hdXRvbG9hZC5waHAnCgkJCSk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKAoJCQlzcHJpbnRmKAoJCQkJJ0ZhbGxiYWNrIGF1dG9sb2FkZXIgcGF0aHM6ICVzJywKCQkJCWltcGxvZGUoICcsICcsICRhdXRvbG9hZGVyX3BhdGhzICkKCQkJKSwKCQkJJ2Jvb3RzdHJhcCcKCQkpOwoKCQlyZXR1cm4gJGF1dG9sb2FkZXJfcGF0aHM7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDbGFzcyBJbmNsdWRlUGFja2FnZUF1dG9sb2FkZXIuCiAqCiAqIExvYWRzIHRoZSBwYWNrYWdlIGF1dG9sb2FkZXIgdGhhdCBpbmNsdWRlcyBhbGwgdGhlIGV4dGVybmFsIHBhY2thZ2VzLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBJbmNsdWRlUGFja2FnZUF1dG9sb2FkZXIgZXh0ZW5kcyBBdXRvbG9hZGVyU3RlcCB7CgoJLyoqCgkgKiBHZXQgdGhlIGF1dG9sb2FkZXIgcGF0aHMgdG8gc2NhbiBmb3IgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ1tdfGZhbHNlIEFycmF5IG9mIHN0cmluZ3Mgd2l0aCBhdXRvbG9hZGVyIHBhdGhzLCBvciBmYWxzZQoJICogICAgICAgICAgICAgICAgICAgICAgICB0byBza2lwLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2F1dG9sb2FkZXJfcGF0aHMoKSB7CgkJaWYgKCAkdGhpcy0+c3RhdGUtPmdldFZhbHVlKCBCb290c3RyYXBTdGF0ZTo6SVNfUFJPVEVDVEVEX0NPTU1BTkQsIGZhbHNlICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRydW5uZXIgICAgICAgID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgkJJHNraXBfcGFja2FnZXMgPSAkcnVubmVyKCktPmNvbmZpZ1snc2tpcC1wYWNrYWdlcyddOwoJCWlmICggdHJ1ZSA9PT0gJHNraXBfcGFja2FnZXMgKSB7CgkJCVdQX0NMSTo6ZGVidWcoICdTa2lwcGVkIGxvYWRpbmcgcGFja2FnZXMuJywgJ2Jvb3RzdHJhcCcgKTsKCgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRhdXRvbG9hZGVyX3BhdGggPSAkcnVubmVyKCktPmdldF9wYWNrYWdlc19kaXJfcGF0aCgpIC4gJ3ZlbmRvci9hdXRvbG9hZC5waHAnOwoKCQlpZiAoIGlzX3JlYWRhYmxlKCAkYXV0b2xvYWRlcl9wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZGVidWcoCgkJCQknTG9hZGluZyBwYWNrYWdlcyBmcm9tOiAnIC4gJGF1dG9sb2FkZXJfcGF0aCwKCQkJCSdib290c3RyYXAnCgkJCSk7CgoJCQlyZXR1cm4gWwoJCQkJJGF1dG9sb2FkZXJfcGF0aCwKCQkJXTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEhhbmRsZSB0aGUgZmFpbHVyZSB0byBmaW5kIGFuIGF1dG9sb2FkZXIuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBoYW5kbGVfZmFpbHVyZSgpIHsKCQlXUF9DTEk6OmRlYnVnKCAnTm8gcGFja2FnZSBhdXRvbG9hZCBmb3VuZCB0byBsb2FkLicsICdib290c3RyYXAnICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxSdW5uZXI7CgovKioKICogQ2xhc3MgUnVubmVySW5zdGFuY2UuCiAqCiAqIENvbnZlbmllbmNlIGNsYXNzIGZvciBzdGVwcyB0aGF0IG1ha2UgdXNlIG9mIHRoZSBgV1BfQ0xJXFJ1bm5lcmAgb2JqZWN0LgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBSdW5uZXJJbnN0YW5jZSB7CgoJLyoqCgkgKiBSZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIGBXUF9DTElcUnVubmVyYCBvYmplY3QuCgkgKgoJICogSW5jbHVkZXMgbmVjZXNzYXJ5IGNsYXNzIGZpbGVzIGZpcnN0IGFzIG5lZWRlZC4KCSAqCgkgKiBAcmV0dXJuIFJ1bm5lcgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoKSB7CgkJaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSVxSdW5uZXInICkgKSB7CgkJCXJlcXVpcmVfb25jZSBXUF9DTElfUk9PVCAuICcvcGhwL1dQX0NMSS9SdW5uZXIucGhwJzsKCQl9CgoJCWlmICggISBjbGFzc19leGlzdHMoICdXUF9DTElcQ29uZmlndXJhdG9yJyApICkgewoJCQlyZXF1aXJlX29uY2UgV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvQ29uZmlndXJhdG9yLnBocCc7CgkJfQoKCQlyZXR1cm4gV1BfQ0xJOjpnZXRfcnVubmVyKCk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRmV0Y2hlcnM7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXEV4aXRFeGNlcHRpb247CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3MgZW50aXR5IGZvciB1c2UgaW4gYSBzdWJjb21tYW5kLgogKi8KYWJzdHJhY3QgY2xhc3MgQmFzZSB7CgoJLyoqCgkgKiBUaGUgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gYW4gaXRlbSBpcyBub3QgZm91bmQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRtc2c7CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRhcmcgVGhlIHJhdyBDTEkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIG1peGVkfGZhbHNlIFRoZSBpdGVtIGlmIGZvdW5kOyBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCWFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmcgKTsKCgkvKioKCSAqIExpa2UgZ2V0KCksIGJ1dCBjYWxscyBXUF9DTEk6OmVycm9yKCkgaW5zdGVhZCBvZiByZXR1cm5pbmcgZmFsc2UuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkYXJnIFRoZSByYXcgQ0xJIGFyZ3VtZW50LgoJICogQHJldHVybiBtaXhlZCBUaGUgaXRlbSBpZiBmb3VuZC4KCSAqIEB0aHJvd3MgRXhpdEV4Y2VwdGlvbiBJZiB0aGUgaXRlbSBpcyBub3QgZm91bmQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfY2hlY2soICRhcmcgKSB7CgkJJGl0ZW0gPSAkdGhpcy0+Z2V0KCAkYXJnICk7CgoJCWlmICggISAkaXRlbSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJHRoaXMtPm1zZywgJGFyZyApICk7CgkJfQoKCQlyZXR1cm4gJGl0ZW07Cgl9CgoJLyoqCgkgKiBHZXQgbXVsdGlwbGUgaXRlbXMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzIFRoZSByYXcgQ0xJIGFyZ3VtZW50cy4KCSAqIEByZXR1cm4gYXJyYXkgVGhlIGxpc3Qgb2YgZm91bmQgaXRlbXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfbWFueSggJGFyZ3MgKSB7CgkJJGl0ZW1zID0gW107CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkYXJnICkgewoJCQkkaXRlbSA9ICR0aGlzLT5nZXQoICRhcmcgKTsKCgkJCWlmICggJGl0ZW0gKSB7CgkJCQkkaXRlbXNbXSA9ICRpdGVtOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAkdGhpcy0+bXNnLCAkYXJnICkgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRpdGVtczsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRmV0Y2hlcnM7Cgp1c2UgV1BfUG9zdDsKCi8qKgogKiBGZXRjaCBhIFdvcmRQcmVzcyBwb3N0IGJhc2VkIG9uIG9uZSBvZiBpdHMgYXR0cmlidXRlcy4KICovCmNsYXNzIFBvc3QgZXh0ZW5kcyBCYXNlIHsKCgkvKioKCSAqIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiBhbiBpdGVtIGlzIG5vdCBmb3VuZC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJG1zZyA9ICdDb3VsZCBub3QgZmluZCB0aGUgcG9zdCB3aXRoIElEICVkLic7CgoJLyoqCgkgKiBHZXQgYSBwb3N0IG9iamVjdCBieSBJRAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGFyZyBUaGUgcmF3IENMSSBhcmd1bWVudC4KCSAqIEByZXR1cm4gV1BfUG9zdHxhcnJheXxmYWxzZSBUaGUgaXRlbSBpZiBmb3VuZDsgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJnICkgewoJCSRwb3N0ID0gZ2V0X3Bvc3QoICRhcmcgKTsKCgkJaWYgKCBudWxsID09PSAkcG9zdCApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRwb3N0OwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxGZXRjaGVyczsKCnVzZSBXUF9Vc2VyOwoKLyoqCiAqIEZldGNoIGEgV29yZFByZXNzIHVzZXIgYmFzZWQgb24gb25lIG9mIGl0cyBhdHRyaWJ1dGVzLgogKi8KY2xhc3MgVXNlciBleHRlbmRzIEJhc2UgewoKCS8qKgoJICogVGhlIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIGFuIGl0ZW0gaXMgbm90IGZvdW5kLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkbXNnID0gIkludmFsaWQgdXNlciBJRCwgZW1haWwgb3IgbG9naW46ICclcyciOwoKCS8qKgoJICogR2V0IGEgdXNlciBvYmplY3QgYnkgb25lIG9mIGl0cyBpZGVudGlmeWluZyBhdHRyaWJ1dGVzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGFyZyBUaGUgcmF3IENMSSBhcmd1bWVudC4KCSAqIEByZXR1cm4gV1BfVXNlcnxmYWxzZSBUaGUgaXRlbSBpZiBmb3VuZDsgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJnICkgewoKCQlpZiAoIGlzX251bWVyaWMoICRhcmcgKSApIHsKCQkJJHVzZXIgPSBnZXRfdXNlcl9ieSggJ2lkJywgJGFyZyApOwoJCX0gZWxzZWlmICggaXNfZW1haWwoICRhcmcgKSApIHsKCQkJJHVzZXIgPSBnZXRfdXNlcl9ieSggJ2VtYWlsJywgJGFyZyApOwoJCQkvLyBMb2dpbnMgY2FuIGJlIGVtYWlscy4KCQkJaWYgKCAhICR1c2VyICkgewoJCQkJJHVzZXIgPSBnZXRfdXNlcl9ieSggJ2xvZ2luJywgJGFyZyApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHVzZXIgPSBnZXRfdXNlcl9ieSggJ2xvZ2luJywgJGFyZyApOwoJCX0KCgkJcmV0dXJuICR1c2VyOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxGZXRjaGVyczsKCnVzZSBXUF9Db21tZW50OwoKLyoqCiAqIEZldGNoIGEgV29yZFByZXNzIGNvbW1lbnQgYmFzZWQgb24gb25lIG9mIGl0cyBhdHRyaWJ1dGVzLgogKi8KY2xhc3MgQ29tbWVudCBleHRlbmRzIEJhc2UgewoKCS8qKgoJICogVGhlIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIGFuIGl0ZW0gaXMgbm90IGZvdW5kLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkbXNnID0gJ0NvdWxkIG5vdCBmaW5kIHRoZSBjb21tZW50IHdpdGggSUQgJWQuJzsKCgkvKioKCSAqIEdldCBhIGNvbW1lbnQgb2JqZWN0IGJ5IElECgkgKgoJICogQHBhcmFtIHN0cmluZyAkYXJnIFRoZSByYXcgQ0xJIGFyZ3VtZW50LgoJICogQHJldHVybiBXUF9Db21tZW50fGFycmF5fGZhbHNlIFRoZSBpdGVtIGlmIGZvdW5kOyBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmcgKSB7CgkJJGNvbW1lbnRfaWQgPSAoaW50KSAkYXJnOwoJCSRjb21tZW50ICAgID0gZ2V0X2NvbW1lbnQoICRjb21tZW50X2lkICk7CgoJCWlmICggbnVsbCA9PT0gJGNvbW1lbnQgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkY29tbWVudDsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRmV0Y2hlcnM7CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3Mgc2l0ZSBiYXNlZCBvbiBvbmUgb2YgaXRzIGF0dHJpYnV0ZXMuCiAqLwpjbGFzcyBTaXRlIGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBUaGUgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gYW4gaXRlbSBpcyBub3QgZm91bmQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRtc2cgPSAnQ291bGQgbm90IGZpbmQgdGhlIHNpdGUgd2l0aCBJRCAlZC4nOwoKCS8qKgoJICogR2V0IGEgc2l0ZSBvYmplY3QgYnkgSUQKCSAqCgkgKiBAcGFyYW0gaW50ICRzaXRlX2lkCgkgKiBAcmV0dXJuIG9iamVjdHxmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkc2l0ZV9pZCApIHsKCQlyZXR1cm4gJHRoaXMtPmdldF9zaXRlKCAkc2l0ZV9pZCApOwoJfQoKCS8qKgoJICogR2V0IHNpdGUgKGJsb2cpIGRhdGEgZm9yIGEgZ2l2ZW4gaWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkYXJnIFRoZSByYXcgQ0xJIGFyZ3VtZW50LgoJICogQHJldHVybiBhcnJheXxmYWxzZSBUaGUgaXRlbSBpZiBmb3VuZDsgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9zaXRlKCAkYXJnICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJLy8gTG9hZCBzaXRlIGRhdGEKCQkkc2l0ZSA9ICR3cGRiLT5nZXRfcm93KAoJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCSJTRUxFQ1QgKiBGUk9NIHskd3BkYi0+YmxvZ3N9IFdIRVJFIGJsb2dfaWQgPSAlZCIsCgkJCQkkYXJnCgkJCSkKCQkpOwoKCQlpZiAoICEgZW1wdHkoICRzaXRlICkgKSB7CgkJCS8vIE9ubHkgY2FyZSBhYm91dCBkb21haW4gYW5kIHBhdGggd2hpY2ggYXJlIHNldCBoZXJlCgkJCXJldHVybiAkc2l0ZTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJdGVyYXRvcnM7Cgp1c2UgSXRlcmF0b3I7CgovKioKICogSXRlcmF0ZXMgb3ZlciByZXN1bHRzIG9mIGEgcXVlcnksIHNwbGl0IGludG8gbWFueSBxdWVyaWVzIHZpYSBMSU1JVCBhbmQgT0ZGU0VUCiAqCiAqIEBzb3VyY2UgaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vNDA2MDAwNQogKi8KY2xhc3MgUXVlcnkgaW1wbGVtZW50cyBJdGVyYXRvciB7CgoJcHJpdmF0ZSAkY2h1bmtfc2l6ZTsKCXByaXZhdGUgJHF1ZXJ5ICAgICAgID0gJyc7Cglwcml2YXRlICRjb3VudF9xdWVyeSA9ICcnOwoKCXByaXZhdGUgJGdsb2JhbF9pbmRleCAgICAgPSAwOwoJcHJpdmF0ZSAkaW5kZXhfaW5fcmVzdWx0cyA9IDA7Cglwcml2YXRlICRyZXN1bHRzICAgICAgICAgID0gW107Cglwcml2YXRlICRyb3dfY291bnQgICAgICAgID0gMDsKCXByaXZhdGUgJG9mZnNldCAgICAgICAgICAgPSAwOwoJcHJpdmF0ZSAkZGIgICAgICAgICAgICAgICA9IG51bGw7Cglwcml2YXRlICRkZXBsZXRlZCAgICAgICAgID0gZmFsc2U7CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IHF1ZXJ5IGl0ZXJhdG9yCgkgKgoJICogVGhpcyB3aWxsIGxvb3Agb3ZlciBhbGwgdXNlcnMsIGJ1dCB3aWxsIHJldHJpZXZlIHRoZW0gMTAwIGJ5IDEwMDoKCSAqIDxjb2RlPgoJICogZm9yZWFjaCggbmV3IEl0ZXJhdG9yc1xRdWVyeSggJ1NFTEVDVCAqIEZST00gdXNlcnMnLCAxMDAgKSBhcyAkdXNlciApIHsKCSAqICAgICB0aWNrbGUoICR1c2VyICk7CgkgKiB9CgkgKiA8L2NvZGU+CgkgKgoJICogQHBhcmFtIHN0cmluZyAkcXVlcnkgVGhlIHF1ZXJ5IGFzIGEgc3RyaW5nLiBJdCBzaG91bGRuJ3QgaW5jbHVkZSBhbnkgTElNSVQgY2xhdXNlcwoJICogQHBhcmFtIGludCAkY2h1bmtfc2l6ZSBIb3cgbWFueSByb3dzIHRvIHJldHJpZXZlIGF0IG9uY2U7IGRlZmF1bHQgdmFsdWUgaXMgNTAwIChvcHRpb25hbCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkcXVlcnksICRjaHVua19zaXplID0gNTAwICkgewoJCSR0aGlzLT5xdWVyeSA9ICRxdWVyeTsKCgkJJHRoaXMtPmNvdW50X3F1ZXJ5ID0gcHJlZ19yZXBsYWNlKCAnL14uKj8gRlJPTSAvJywgJ1NFTEVDVCBDT1VOVCgqKSBGUk9NICcsICRxdWVyeSwgMSwgJHJlcGxhY2VtZW50cyApOwoJCWlmICggMSAhPT0gJHJlcGxhY2VtZW50cyApIHsKCQkJJHRoaXMtPmNvdW50X3F1ZXJ5ID0gJyc7CgkJfQoKCQkkdGhpcy0+Y2h1bmtfc2l6ZSA9ICRjaHVua19zaXplOwoKCQkkdGhpcy0+ZGIgPSAkR0xPQkFMU1snd3BkYiddOwoJfQoKCS8qKgoJICogUmVkdWNlcyB0aGUgb2Zmc2V0IHdoZW4gdGhlIHF1ZXJ5IHJvdyBjb3VudCBzaHJpbmtzCgkgKgoJICogSW4gY2FzZXMgd2hlcmUgdGhlIGl0ZXJhdGVkIHJvd3MgYXJlIGJlaW5nIHVwZGF0ZWQgc3VjaCB0aGF0IHRoZXkgd2lsbCBubwoJICogbG9uZ2VyIGJlIHJldHVybmVkIGJ5IHRoZSBvcmlnaW5hbCBxdWVyeSwgdGhlIG9mZnNldCBtdXN0IGJlIHJlZHVjZWQgdG8KCSAqIGl0ZXJhdGUgb3ZlciBhbGwgcmVtYWluaW5nIHJvd3MuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYWRqdXN0X29mZnNldF9mb3Jfc2hyaW5raW5nX3Jlc3VsdF9zZXQoKSB7CgkJaWYgKCBlbXB0eSggJHRoaXMtPmNvdW50X3F1ZXJ5ICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRyb3dfY291bnQgPSAkdGhpcy0+ZGItPmdldF92YXIoICR0aGlzLT5jb3VudF9xdWVyeSApOwoKCQlpZiAoICRyb3dfY291bnQgPCAkdGhpcy0+cm93X2NvdW50ICkgewoJCQkkdGhpcy0+b2Zmc2V0IC09ICR0aGlzLT5yb3dfY291bnQgLSAkcm93X2NvdW50OwoJCX0KCgkJJHRoaXMtPnJvd19jb3VudCA9ICRyb3dfY291bnQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBsb2FkX2l0ZW1zX2Zyb21fZGIoKSB7CgkJJHRoaXMtPmFkanVzdF9vZmZzZXRfZm9yX3Nocmlua2luZ19yZXN1bHRfc2V0KCk7CgoJCSRxdWVyeSAgICAgICAgID0gJHRoaXMtPnF1ZXJ5IC4gc3ByaW50ZiggJyBMSU1JVCAlZCBPRkZTRVQgJWQnLCAkdGhpcy0+Y2h1bmtfc2l6ZSwgJHRoaXMtPm9mZnNldCApOwoJCSR0aGlzLT5yZXN1bHRzID0gJHRoaXMtPmRiLT5nZXRfcmVzdWx0cyggJHF1ZXJ5ICk7CgoJCWlmICggISAkdGhpcy0+cmVzdWx0cyApIHsKCQkJaWYgKCAkdGhpcy0+ZGItPmxhc3RfZXJyb3IgKSB7CgkJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnRGF0YWJhc2UgZXJyb3I6ICcgLiAkdGhpcy0+ZGItPmxhc3RfZXJyb3IgKTsKCQkJfQoKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHRoaXMtPm9mZnNldCArPSAkdGhpcy0+Y2h1bmtfc2l6ZTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpIHsKCQlyZXR1cm4gJHRoaXMtPnJlc3VsdHNbICR0aGlzLT5pbmRleF9pbl9yZXN1bHRzIF07Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGtleSgpIHsKCQlyZXR1cm4gJHRoaXMtPmdsb2JhbF9pbmRleDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gbmV4dCgpIHsKCQkkdGhpcy0+aW5kZXhfaW5fcmVzdWx0cysrOwoJCSR0aGlzLT5nbG9iYWxfaW5kZXgrKzsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcmV3aW5kKCkgewoJCSR0aGlzLT5yZXN1bHRzICAgICAgICAgID0gW107CgkJJHRoaXMtPmdsb2JhbF9pbmRleCAgICAgPSAwOwoJCSR0aGlzLT5pbmRleF9pbl9yZXN1bHRzID0gMDsKCQkkdGhpcy0+b2Zmc2V0ICAgICAgICAgICA9IDA7CgkJJHRoaXMtPmRlcGxldGVkICAgICAgICAgPSBmYWxzZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKSB7CgkJaWYgKCAkdGhpcy0+ZGVwbGV0ZWQgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWlmICggISBpc3NldCggJHRoaXMtPnJlc3VsdHNbICR0aGlzLT5pbmRleF9pbl9yZXN1bHRzIF0gKSApIHsKCQkJJGl0ZW1zX2xvYWRlZCA9ICR0aGlzLT5sb2FkX2l0ZW1zX2Zyb21fZGIoKTsKCgkJCWlmICggISAkaXRlbXNfbG9hZGVkICkgewoJCQkJJHRoaXMtPnJld2luZCgpOwoJCQkJJHRoaXMtPmRlcGxldGVkID0gdHJ1ZTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoKCQkJJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMgPSAwOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEl0ZXJhdG9yczsKCnVzZSBJdGVyYXRvckl0ZXJhdG9yOwoKLyoqCiAqIEFwcGxpZXMgb25lIG9yIG1vcmUgY2FsbGJhY2tzIHRvIGFuIGl0ZW0gYmVmb3JlIHJldHVybmluZyBpdC4KICovCmNsYXNzIFRyYW5zZm9ybSBleHRlbmRzIEl0ZXJhdG9ySXRlcmF0b3IgewoKCXByaXZhdGUgJHRyYW5zZm9ybWVycyA9IFtdOwoKCXB1YmxpYyBmdW5jdGlvbiBhZGRfdHJhbnNmb3JtKCAkZm4gKSB7CgkJJHRoaXMtPnRyYW5zZm9ybWVyc1tdID0gJGZuOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkgewoJCSR2YWx1ZSA9IHBhcmVudDo6Y3VycmVudCgpOwoKCQlmb3JlYWNoICggJHRoaXMtPnRyYW5zZm9ybWVycyBhcyAkZm4gKSB7CgkJCSR2YWx1ZSA9IGNhbGxfdXNlcl9mdW5jKCAkZm4sICR2YWx1ZSApOwoJCX0KCgkJcmV0dXJuICR2YWx1ZTsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSXRlcmF0b3JzOwoKLyoqCiAqIEBzb3VyY2UgaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vNDA2MDAwNQogKi8KY2xhc3MgVGFibGUgZXh0ZW5kcyBRdWVyeSB7CgoJLyoqCgkgKiBDcmVhdGVzIGFuIGl0ZXJhdG9yIG92ZXIgYSBkYXRhYmFzZSB0YWJsZS4KCSAqCgkgKiA8Y29kZT4KCSAqIGZvcmVhY2goIG5ldyBJdGVyYXRvcnNcVGFibGUoIGFycmF5KCAndGFibGUnID0+ICR3cGRiLT5wb3N0cywgJ2ZpZWxkcycgPT4gYXJyYXkoICdJRCcsICdwb3N0X2NvbnRlbnQnICkgKSApIGFzICRwb3N0ICkgewoJICogICAgIGNvdW50X3dvcmRzX2ZvciggJHBvc3QtPklELCAkcG9zdC0+cG9zdF9jb250ZW50ICk7CgkgKiB9CgkgKiA8L2NvZGU+CgkgKgoJICogPGNvZGU+CgkgKiBmb3JlYWNoKCBuZXcgSXRlcmF0b3JzXFRhYmxlKCBhcnJheSggJ3RhYmxlJyA9PiAkd3BkYi0+cG9zdHMsICd3aGVyZScgPT4gJ0lEID0gOCBPUiBwb3N0X3N0YXR1cyA9ICJwdWJsaXNoIicgKSApIGFzICRwb3N0ICkgewoJICogICAgIOKApgoJICogfQoJICogPC9jb2RlPgoJICoKCSAqIDxjb2RlPgoJICogZm9yZWFjaCggbmV3IFBvc3RJdGVyYXRvciggYXJyYXkoICd0YWJsZScgPT4gJHdwZGItPnBvc3RzLCAnd2hlcmUnID0+IGFycmF5KCAncG9zdF9zdGF0dXMnID0+ICdwdWJsaXNoJywgJ3Bvc3RfZGF0ZV9nbXQgQkVUV0VFTiB4IEFORCB5JyApICkgKSBhcyAkcG9zdCApIHsKCSAqICAgICDigKYKCSAqIH0KCSAqIDwvY29kZT4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgU3VwcG9ydGVkIGFyZ3VtZW50czoKCSAqICAgICAgdGFibGUg4oCTIHRoZSBuYW1lIG9mIHRoZSBkYXRhYmFzZSB0YWJsZQoJICogICAgICBmaWVsZHMg4oCTIGFuIGFycmF5IG9mIGNvbHVtbnMgdG8gZ2V0IGZyb20gdGhlIHRhYmxlLCAnKicgaXMgYSB2YWxpZCB2YWx1ZSBhbmQgdGhlIGRlZmF1bHQKCSAqICAgICAgd2hlcmUg4oCTIGNvbmRpdGlvbnMgZm9yIGZpbHRlcmluZyByb3dzLiBTdXBwb3J0cyB0d28gZm9ybWF0czoKCSAqICAgICAgICAgICAgICA9IHN0cmluZyDigJMgdGhpcyB3aWxsIGJlIHRoZSB3aGVyZSBjbGF1c2UKCSAqICAgICAgICAgICAgICA9IGFycmF5IOKAkyBlYWNoIGVsZW1lbnQgaXMgdHJlYXRlZCBhcyBhIGNvbmRpdGlvbiBpZiBpdCdzIHBvc2l0aW9uYWwsIG9yIGFzIGNvbHVtbiA9PiB2YWx1ZSBpZgoJICogICAgICAgICAgICAgICAgaXQncyBhIGtleS92YWx1ZSBwYWlyLiBJbiB0aGUgbGF0dGVyIGNhc2UgdGhlIHZhbHVlIGlzIGF1dG9tYXRpY2FsbHkgcXVvdGVkIGFuZCBlc2NhcGVkCgkgKiAgICAgIGFwcGVuZCAtIGFkZCBhcmJpdHJhcnkgZXh0cmEgU1FMCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGFyZ3MgPSBbXSApIHsKCQkkZGVmYXVsdHMgPSBbCgkJCSdmaWVsZHMnICAgICA9PiAnKicsCgkJCSd3aGVyZScgICAgICA9PiBbXSwKCQkJJ2FwcGVuZCcgICAgID0+ICcnLAoJCQkndGFibGUnICAgICAgPT4gbnVsbCwKCQkJJ2NodW5rX3NpemUnID0+IDUwMCwKCQldOwoJCSR0YWJsZSAgICA9ICRhcmdzWyd0YWJsZSddOwoJCSRhcmdzICAgICA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhcmdzICk7CgoJCSRmaWVsZHMgICAgID0gc2VsZjo6YnVpbGRfZmllbGRzKCAkYXJnc1snZmllbGRzJ10gKTsKCQkkY29uZGl0aW9ucyA9IHNlbGY6OmJ1aWxkX3doZXJlX2NvbmRpdGlvbnMoICRhcmdzWyd3aGVyZSddICk7CgkJJHdoZXJlX3NxbCAgPSAkY29uZGl0aW9ucyA/ICIgV0hFUkUgJGNvbmRpdGlvbnMiIDogJyc7CgkJJHF1ZXJ5ICAgICAgPSAiU0VMRUNUICRmaWVsZHMgRlJPTSBgJHRhYmxlYCAkd2hlcmVfc3FsIHskYXJnc1snYXBwZW5kJ119IjsKCgkJcGFyZW50OjpfX2NvbnN0cnVjdCggJHF1ZXJ5LCAkYXJnc1snY2h1bmtfc2l6ZSddICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYnVpbGRfZmllbGRzKCAkZmllbGRzICkgewoJCWlmICggJyonID09PSAkZmllbGRzICkgewoJCQlyZXR1cm4gJGZpZWxkczsKCQl9CgoJCXJldHVybiBpbXBsb2RlKAoJCQknLCAnLAoJCQlhcnJheV9tYXAoCgkJCQlmdW5jdGlvbiAoICR2ICkgewoJCQkJCXJldHVybiAiYCR2YCI7CgkJCQl9LAoJCQkJJGZpZWxkcwoJCQkpCgkJKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBidWlsZF93aGVyZV9jb25kaXRpb25zKCAkd2hlcmUgKSB7CgkJZ2xvYmFsICR3cGRiOwoJCWlmICggaXNfYXJyYXkoICR3aGVyZSApICkgewoJCQkkY29uZGl0aW9ucyA9IFtdOwoJCQlmb3JlYWNoICggJHdoZXJlIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQkJaWYgKCBpc19hcnJheSggJHZhbHVlICkgKSB7CgkJCQkJJGNvbmRpdGlvbnNbXSA9ICRrZXkgLiAnIElOICgnIC4gZXNjX3NxbCggaW1wbG9kZSggJywnLCAkdmFsdWUgKSApIC4gJyknOwoJCQkJfSBlbHNlaWYgKCBpc19udW1lcmljKCAka2V5ICkgKSB7CgkJCQkJJGNvbmRpdGlvbnNbXSA9ICR2YWx1ZTsKCQkJCX0gZWxzZSB7CgkJCQkJJGNvbmRpdGlvbnNbXSA9ICRrZXkgLiAkd3BkYi0+cHJlcGFyZSggJyA9ICVzJywgJHZhbHVlICk7CgkJCQl9CgkJCX0KCQkJJHdoZXJlID0gaW1wbG9kZSggJyBBTkQgJywgJGNvbmRpdGlvbnMgKTsKCQl9CgkJcmV0dXJuICR3aGVyZTsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSXRlcmF0b3JzOwoKdXNlIENvdW50YWJsZTsKdXNlIEl0ZXJhdG9yOwp1c2UgU3BsRmlsZU9iamVjdDsKdXNlIFdQX0NMSTsKCi8qKgogKiBBbGxvd3MgaW5jcmVtZW50YWxseSByZWFkaW5nIGFuZCBwYXJzaW5nIGxpbmVzIGZyb20gYSBDU1YgZmlsZS4KICovCmNsYXNzIENTViBpbXBsZW1lbnRzIENvdW50YWJsZSwgSXRlcmF0b3IgewoKCWNvbnN0IFJPV19TSVpFID0gNDA5NjsKCglwcml2YXRlICRmaWxlbmFtZTsKCXByaXZhdGUgJGZpbGVfcG9pbnRlcjsKCglwcml2YXRlICRkZWxpbWl0ZXI7Cglwcml2YXRlICRjb2x1bW5zOwoKCXByaXZhdGUgJGN1cnJlbnRfaW5kZXg7Cglwcml2YXRlICRjdXJyZW50X2VsZW1lbnQ7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZmlsZW5hbWUsICRkZWxpbWl0ZXIgPSAnLCcgKSB7CgkJJHRoaXMtPmZpbGVuYW1lICAgICA9ICRmaWxlbmFtZTsKCQkkdGhpcy0+ZmlsZV9wb2ludGVyID0gZm9wZW4oICRmaWxlbmFtZSwgJ3JiJyApOwoJCWlmICggISAkdGhpcy0+ZmlsZV9wb2ludGVyICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnQ291bGQgbm90IG9wZW4gZmlsZTogJXMnLCAkZmlsZW5hbWUgKSApOwoJCX0KCgkJJHRoaXMtPmRlbGltaXRlciA9ICRkZWxpbWl0ZXI7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHJld2luZCgpIHsKCQlyZXdpbmQoICR0aGlzLT5maWxlX3BvaW50ZXIgKTsKCgkJJHRoaXMtPmNvbHVtbnMgPSBmZ2V0Y3N2KCAkdGhpcy0+ZmlsZV9wb2ludGVyLCBzZWxmOjpST1dfU0laRSwgJHRoaXMtPmRlbGltaXRlciApOwoKCQkkdGhpcy0+Y3VycmVudF9pbmRleCA9IC0xOwoJCSR0aGlzLT5uZXh0KCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJcmV0dXJuICR0aGlzLT5jdXJyZW50X2VsZW1lbnQ7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGtleSgpIHsKCQlyZXR1cm4gJHRoaXMtPmN1cnJlbnRfaW5kZXg7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG5leHQoKSB7CgkJJHRoaXMtPmN1cnJlbnRfZWxlbWVudCA9IGZhbHNlOwoKCQl3aGlsZSAoIHRydWUgKSB7CgkJCSRzdHIgPSBmZ2V0cyggJHRoaXMtPmZpbGVfcG9pbnRlciApOwoKCQkJaWYgKCBmYWxzZSA9PT0gJHN0ciApIHsKCQkJCWJyZWFrOwoJCQl9CgoJCQkkcm93ID0gc3RyX2dldGNzdiggJHN0ciwgJHRoaXMtPmRlbGltaXRlciApOwoKCQkJJGVsZW1lbnQgPSBbXTsKCQkJZm9yZWFjaCAoICR0aGlzLT5jb2x1bW5zIGFzICRpID0+ICRrZXkgKSB7CgkJCQlpZiAoIGlzc2V0KCAkcm93WyAkaSBdICkgKSB7CgkJCQkJJGVsZW1lbnRbICRrZXkgXSA9ICRyb3dbICRpIF07CgkJCQl9CgkJCX0KCgkJCWlmICggISBlbXB0eSggJGVsZW1lbnQgKSApIHsKCQkJCSR0aGlzLT5jdXJyZW50X2VsZW1lbnQgPSAkZWxlbWVudDsKCQkJCSR0aGlzLT5jdXJyZW50X2luZGV4Kys7CgoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNvdW50KCkgewoJCSRmaWxlID0gbmV3IFNwbEZpbGVPYmplY3QoICR0aGlzLT5maWxlbmFtZSwgJ3InICk7CgkJJGZpbGUtPnNlZWsoIFBIUF9JTlRfTUFYICk7CgkJcmV0dXJuICRmaWxlLT5rZXkoKSArIDE7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHZhbGlkKCkgewoJCXJldHVybiBpc19hcnJheSggJHRoaXMtPmN1cnJlbnRfZWxlbWVudCApOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJdGVyYXRvcnM7Cgp1c2UgUnVudGltZUV4Y2VwdGlvbjsKCmNsYXNzIEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24ge30KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIERpcmVjdG9yeUl0ZXJhdG9yOwp1c2UgRXhjZXB0aW9uOwp1c2UgUGhhckRhdGE7CnVzZSBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjsKdXNlIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I7CnVzZSBXUF9DTEk7CnVzZSBaaXBBcmNoaXZlOwoKLyoqCiAqIEV4dHJhY3QgYSBwcm92aWRlZCBhcmNoaXZlIGZpbGUuCiAqLwpjbGFzcyBFeHRyYWN0b3IgewoKCS8qKgoJICogRXh0cmFjdCB0aGUgYXJjaGl2ZSBmaWxlIHRvIGEgc3BlY2lmaWMgZGVzdGluYXRpb24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZGVzdAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3QoICR0YXJiYWxsX29yX3ppcCwgJGRlc3QgKSB7CgkJaWYgKCBwcmVnX21hdGNoKCAnL1wuemlwJC8nLCAkdGFyYmFsbF9vcl96aXAgKSApIHsKCQkJcmV0dXJuIHNlbGY6OmV4dHJhY3RfemlwKCAkdGFyYmFsbF9vcl96aXAsICRkZXN0ICk7CgkJfQoKCQlpZiAoIHByZWdfbWF0Y2goICcvXC50YXJcLmd6JC8nLCAkdGFyYmFsbF9vcl96aXAgKSApIHsKCQkJcmV0dXJuIHNlbGY6OmV4dHJhY3RfdGFyYmFsbCggJHRhcmJhbGxfb3JfemlwLCAkZGVzdCApOwoJCX0KCgkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggIkV4dHJhY3Rpb24gb25seSBzdXBwb3J0ZWQgZm9yICcuemlwJyBhbmQgJy50YXIuZ3onIGZpbGUgdHlwZXMuIiApOwoJfQoKCS8qKgoJICogRXh0cmFjdCBhIFpJUCBmaWxlIHRvIGEgc3BlY2lmaWMgZGVzdGluYXRpb24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkemlwZmlsZQoJICogQHBhcmFtIHN0cmluZyAkZGVzdAoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0X3ppcCggJHppcGZpbGUsICRkZXN0ICkgewoJCWlmICggISBjbGFzc19leGlzdHMoICdaaXBBcmNoaXZlJyApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnRXh0cmFjdGluZyBhIHppcCBmaWxlIHJlcXVpcmVzIFppcEFyY2hpdmUuJyApOwoJCX0KCgkJLy8gRW5zdXJlIHRoZSBkZXN0aW5hdGlvbiBmb2xkZXIgZXhpc3RzIG9yIGNhbiBiZSBjcmVhdGVkLgoJCWlmICggISBzZWxmOjplbnN1cmVfZGlyX2V4aXN0cyggJGRlc3QgKSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggIkNvdWxkIG5vdCBjcmVhdGUgZm9sZGVyICd7JGRlc3R9Jy4iICk7CgkJfQoKCQlpZiAoICEgZmlsZSggJHppcGZpbGUgKQoJCQl8fCAhIGlzX3JlYWRhYmxlKCAkemlwZmlsZSApCgkJCXx8IGZpbGVzaXplKCAkemlwZmlsZSApIDw9IDAgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICJJbnZhbGlkIHppcCBmaWxlICd7JHppcGZpbGV9Jy4iICk7CgkJfQoKCQkkemlwID0gbmV3IFppcEFyY2hpdmUoKTsKCQkkcmVzID0gJHppcC0+b3BlbiggJHppcGZpbGUgKTsKCgkJaWYgKCB0cnVlID09PSAkcmVzICkgewoJCQkkbmFtZSAgICA9IFV0aWxzXGJhc2VuYW1lKCAkemlwZmlsZSApOwoJCQkkdGVtcGRpciA9IFV0aWxzXGdldF90ZW1wX2RpcigpCgkJCQkJCS4gdW5pcWlkKCAnd3AtY2xpLWV4dHJhY3QtemlwZmlsZS0nLCB0cnVlICkKCQkJCQkJLiAiLXskbmFtZX0iOwoKCQkJJHppcC0+ZXh0cmFjdFRvKCAkdGVtcGRpciApOwoJCQkkemlwLT5jbG9zZSgpOwoKCQkJc2VsZjo6Y29weV9vdmVyd3JpdGVfZmlsZXMoCgkJCQlzZWxmOjpnZXRfZmlyc3Rfc3ViZm9sZGVyKCAkdGVtcGRpciApLAoJCQkJJGRlc3QKCQkJKTsKCgkJCXNlbGY6OnJtZGlyKCAkdGVtcGRpciApOwoJCX0gZWxzZSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oCgkJCQlzcHJpbnRmKAoJCQkJCSJaaXBBcmNoaXZlIGZhaWxlZCB0byB1bnppcCAnJXMnOiAlcy4iLAoJCQkJCSR6aXBmaWxlLAoJCQkJCXNlbGY6OnppcF9lcnJvcl9tc2coICRyZXMgKQoJCQkJKQoJCQkpOwoJCX0KCX0KCgkvKioKCSAqIEV4dHJhY3QgYSB0YXJiYWxsIHRvIGEgc3BlY2lmaWMgZGVzdGluYXRpb24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGFyYmFsbAoJICogQHBhcmFtIHN0cmluZyAkZGVzdAoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0X3RhcmJhbGwoICR0YXJiYWxsLCAkZGVzdCApIHsKCQkvLyBFbnN1cmUgdGhlIGRlc3RpbmF0aW9uIGZvbGRlciBleGlzdHMgb3IgY2FuIGJlIGNyZWF0ZWQuCgkJaWYgKCAhIHNlbGY6OmVuc3VyZV9kaXJfZXhpc3RzKCAkZGVzdCApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiQ291bGQgbm90IGNyZWF0ZSBmb2xkZXIgJ3skZGVzdH0nLiIgKTsKCQl9CgoJCWlmICggY2xhc3NfZXhpc3RzKCAnUGhhckRhdGEnICkgKSB7CgkJCXRyeSB7CgkJCQkkcGhhciAgICA9IG5ldyBQaGFyRGF0YSggJHRhcmJhbGwgKTsKCQkJCSRuYW1lICAgID0gVXRpbHNcYmFzZW5hbWUoICR0YXJiYWxsICk7CgkJCQkkdGVtcGRpciA9IFV0aWxzXGdldF90ZW1wX2RpcigpCgkJCQkJCQkuIHVuaXFpZCggJ3dwLWNsaS1leHRyYWN0LXRhcmJhbGwtJywgdHJ1ZSApCgkJCQkJCQkuICIteyRuYW1lfSI7CgoJCQkJJHBoYXItPmV4dHJhY3RUbyggJHRlbXBkaXIgKTsKCgkJCQlzZWxmOjpjb3B5X292ZXJ3cml0ZV9maWxlcygKCQkJCQlzZWxmOjpnZXRfZmlyc3Rfc3ViZm9sZGVyKCAkdGVtcGRpciApLAoJCQkJCSRkZXN0CgkJCQkpOwoKCQkJCXNlbGY6OnJtZGlyKCAkdGVtcGRpciApOwoJCQkJcmV0dXJuOwoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCSJQaGFyRGF0YSBmYWlsZWQsIGZhbGxpbmcgYmFjayB0byAndGFyIHh6JyAoIgoJCQkJCS4gJGUtPmdldE1lc3NhZ2UoKSAuICcpJwoJCQkJKTsKCQkJCS8vIEZhbGwgdGhyb3VnaCB0byB0cnlpbmcgYHRhciB4emAgYmVsb3cuCgkJCX0KCQl9CgoJCS8vIEVuc3VyZSByZWxhdGl2ZSBwYXRocyBjYW5ub3QgYmUgbWlzaW50ZXJwcmV0ZWQgYXMgaG9zdG5hbWVzLgoJCS8vIFByZXBlbmRpbmcgYC4vYCB3aWxsIGZvcmNlIHRhciB0byBpbnRlcnByZXQgaXQgYXMgYSBmaWxlc3lzdGVtIHBhdGguCgkJaWYgKCBzZWxmOjpwYXRoX2lzX3JlbGF0aXZlKCAkdGFyYmFsbCApICkgewoJCQkkdGFyYmFsbCA9ICIuL3skdGFyYmFsbH0iOwoJCX0KCgkJaWYgKCAhIGZpbGUoICR0YXJiYWxsICkKCQkJfHwgISBpc19yZWFkYWJsZSggJHRhcmJhbGwgKQoJCQl8fCBmaWxlc2l6ZSggJHRhcmJhbGwgKSA8PSAwICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiSW52YWxpZCB6aXAgZmlsZSAneyR0YXJiYWxsfScuIiApOwoJCX0KCgkJLy8gTm90ZTogZGlyZWN0b3J5IG11c3QgZXhpc3QgZm9yIHRhciAtLWRpcmVjdG9yeSB0byB3b3JrLgoJCSRjbWQgPSBVdGlsc1xlc2NfY21kKAoJCQkndGFyIHh6IC0tc3RyaXAtY29tcG9uZW50cz0xIC0tZGlyZWN0b3J5PSVzIC1mICVzJywKCQkJJGRlc3QsCgkJCSR0YXJiYWxsCgkJKTsKCgkJJHByb2Nlc3NfcnVuID0gV1BfQ0xJOjpsYXVuY2goCgkJCSRjbWQsCgkJCWZhbHNlIC8qZXhpdF9vbl9lcnJvciovLAoJCQl0cnVlIC8qcmV0dXJuX2RldGFpbGVkKi8KCQkpOwoKCQlpZiAoIDAgIT09ICRwcm9jZXNzX3J1bi0+cmV0dXJuX2NvZGUgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oCgkJCQlzcHJpbnRmKAoJCQkJCSdGYWlsZWQgdG8gZXhlY3V0ZSBgJXNgOiAlcy4nLAoJCQkJCSRjbWQsCgkJCQkJc2VsZjo6dGFyX2Vycm9yX21zZyggJHByb2Nlc3NfcnVuICkKCQkJCSkKCQkJKTsKCQl9Cgl9CgoJLyoqCgkgKiBDb3B5IGZpbGVzIGZyb20gc291cmNlIGRpcmVjdG9yeSB0byBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuIFNvdXJjZQoJICogZGlyZWN0b3J5IG11c3QgZXhpc3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc291cmNlCgkgKiBAcGFyYW0gc3RyaW5nICRkZXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29weV9vdmVyd3JpdGVfZmlsZXMoICRzb3VyY2UsICRkZXN0ICkgewoJCSRpdGVyYXRvciA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKAoJCQluZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoCgkJCQkkc291cmNlLAoJCQkJUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlNLSVBfRE9UUwoJCQkpLAoJCQlSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yOjpTRUxGX0ZJUlNUCgkJKTsKCgkJJGVycm9yID0gMDsKCgkJaWYgKCAhIGlzX2RpciggJGRlc3QgKSApIHsKCQkJbWtkaXIoICRkZXN0LCAwNzc3LCB0cnVlICk7CgkJfQoKCQlmb3JlYWNoICggJGl0ZXJhdG9yIGFzICRpdGVtICkgewoKCQkJJGRlc3RfcGF0aCA9ICRkZXN0IC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRpdGVyYXRvci0+Z2V0U3ViUGF0aE5hbWUoKTsKCgkJCWlmICggJGl0ZW0tPmlzRGlyKCkgKSB7CgkJCQlpZiAoICEgaXNfZGlyKCAkZGVzdF9wYXRoICkgKSB7CgkJCQkJbWtkaXIoICRkZXN0X3BhdGggKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmICggZmlsZV9leGlzdHMoICRkZXN0X3BhdGggKSAmJiBpc193cml0YWJsZSggJGRlc3RfcGF0aCApICkgewoJCQkJCWNvcHkoICRpdGVtLCAkZGVzdF9wYXRoICk7CgkJCQl9IGVsc2VpZiAoICEgZmlsZV9leGlzdHMoICRkZXN0X3BhdGggKSApIHsKCQkJCQljb3B5KCAkaXRlbSwgJGRlc3RfcGF0aCApOwoJCQkJfSBlbHNlIHsKCQkJCQkkZXJyb3IgPSAxOwoJCQkJCVdQX0NMSTo6d2FybmluZyggIlVuYWJsZSB0byBjb3B5ICciIC4gJGl0ZXJhdG9yLT5nZXRTdWJQYXRoTmFtZSgpIC4gIicgdG8gY3VycmVudCBkaXJlY3RvcnkuIiApOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICRlcnJvciApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggJ1RoZXJlIHdhcyBhbiBlcnJvciBvdmVyd3JpdGluZyBleGlzdGluZyBmaWxlcy4nICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlIGFsbCBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgcmVjdXJzaXZlbHkgZnJvbSBkaXJlY3RvcnkuIERpcmVjdG9yeQoJICogbXVzdCBleGlzdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkaXIKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBybWRpciggJGRpciApIHsKCQkkZmlsZXMgPSBuZXcgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigKCQkJbmV3IFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKAoJCQkJJGRpciwKCQkJCVJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMKCQkJKSwKCQkJUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjo6Q0hJTERfRklSU1QKCQkpOwoKCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlaW5mbyApIHsKCQkJJHRvZG8gPSAkZmlsZWluZm8tPmlzRGlyKCkgPyAncm1kaXInIDogJ3VubGluayc7CgkJCSRwYXRoID0gJGZpbGVpbmZvLT5nZXRSZWFsUGF0aCgpOwoJCQlpZiAoIDAgIT09IHN0cnBvcyggJHBhdGgsICRmaWxlaW5mby0+Z2V0UmVhbFBhdGgoKSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCSJUZW1wb3JhcnkgZmlsZSBvciBmb2xkZXIgdG8gYmUgcmVtb3ZlZCB3YXMgZm91bmQgb3V0c2lkZSBvZiB0ZW1wb3JhcnkgZm9sZGVyLCBhYm9ydGluZyByZW1vdmFsOiAneyRwYXRofSciCgkJCQkpOwoJCQl9CgkJCSR0b2RvKCAkcGF0aCApOwoJCX0KCQlybWRpciggJGRpciApOwoJfQoKCS8qKgoJICogUmV0dXJuIGZvcm1hdHRlZCBaaXBBcmNoaXZlIGVycm9yIG1lc3NhZ2UgZnJvbSBlcnJvciBjb2RlLgoJICoKCSAqIEBwYXJhbSBpbnQgJGVycm9yX2NvZGUKCSAqIEByZXR1cm4gc3RyaW5nfGludCBUaGUgZXJyb3IgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQKCSAqICAgICAgICAgICAgICAgICAgICBjb2RlLCBpZiBmb3VuZDsgT3RoZXIgd2lzZSB0aGUgc2FtZSBlcnJvciBjb2RlLAoJICogICAgICAgICAgICAgICAgICAgIHVubW9kaWZpZWQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gemlwX2Vycm9yX21zZyggJGVycm9yX2NvZGUgKSB7CgkJLy8gRnJvbSBodHRwczovL2dpdGh1Yi5jb20vcGhwL3BocC1zcmMvYmxvYi9waHAtNS4zLjAvZXh0L3ppcC9waHBfemlwLmMjTDI2MjMtTDI2NDYuCgkJc3RhdGljICR6aXBfZXJyX21zZ3MgPSBbCgkJCVppcEFyY2hpdmU6OkVSX09LICAgICAgICAgID0+ICdObyBlcnJvcicsCgkJCVppcEFyY2hpdmU6OkVSX01VTFRJRElTSyAgID0+ICdNdWx0aS1kaXNrIHppcCBhcmNoaXZlcyBub3Qgc3VwcG9ydGVkJywKCQkJWmlwQXJjaGl2ZTo6RVJfUkVOQU1FICAgICAgPT4gJ1JlbmFtaW5nIHRlbXBvcmFyeSBmaWxlIGZhaWxlZCcsCgkJCVppcEFyY2hpdmU6OkVSX0NMT1NFICAgICAgID0+ICdDbG9zaW5nIHppcCBhcmNoaXZlIGZhaWxlZCcsCgkJCVppcEFyY2hpdmU6OkVSX1NFRUsgICAgICAgID0+ICdTZWVrIGVycm9yJywKCQkJWmlwQXJjaGl2ZTo6RVJfUkVBRCAgICAgICAgPT4gJ1JlYWQgZXJyb3InLAoJCQlaaXBBcmNoaXZlOjpFUl9XUklURSAgICAgICA9PiAnV3JpdGUgZXJyb3InLAoJCQlaaXBBcmNoaXZlOjpFUl9DUkMgICAgICAgICA9PiAnQ1JDIGVycm9yJywKCQkJWmlwQXJjaGl2ZTo6RVJfWklQQ0xPU0VEICAgPT4gJ0NvbnRhaW5pbmcgemlwIGFyY2hpdmUgd2FzIGNsb3NlZCcsCgkJCVppcEFyY2hpdmU6OkVSX05PRU5UICAgICAgID0+ICdObyBzdWNoIGZpbGUnLAoJCQlaaXBBcmNoaXZlOjpFUl9FWElTVFMgICAgICA9PiAnRmlsZSBhbHJlYWR5IGV4aXN0cycsCgkJCVppcEFyY2hpdmU6OkVSX09QRU4gICAgICAgID0+ICdDYW5cJ3Qgb3BlbiBmaWxlJywKCQkJWmlwQXJjaGl2ZTo6RVJfVE1QT1BFTiAgICAgPT4gJ0ZhaWx1cmUgdG8gY3JlYXRlIHRlbXBvcmFyeSBmaWxlJywKCQkJWmlwQXJjaGl2ZTo6RVJfWkxJQiAgICAgICAgPT4gJ1psaWIgZXJyb3InLAoJCQlaaXBBcmNoaXZlOjpFUl9NRU1PUlkgICAgICA9PiAnTWFsbG9jIGZhaWx1cmUnLAoJCQlaaXBBcmNoaXZlOjpFUl9DSEFOR0VEICAgICA9PiAnRW50cnkgaGFzIGJlZW4gY2hhbmdlZCcsCgkJCVppcEFyY2hpdmU6OkVSX0NPTVBOT1RTVVBQID0+ICdDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZCcsCgkJCVppcEFyY2hpdmU6OkVSX0VPRiAgICAgICAgID0+ICdQcmVtYXR1cmUgRU9GJywKCQkJWmlwQXJjaGl2ZTo6RVJfSU5WQUwgICAgICAgPT4gJ0ludmFsaWQgYXJndW1lbnQnLAoJCQlaaXBBcmNoaXZlOjpFUl9OT1pJUCAgICAgICA9PiAnTm90IGEgemlwIGFyY2hpdmUnLAoJCQlaaXBBcmNoaXZlOjpFUl9JTlRFUk5BTCAgICA9PiAnSW50ZXJuYWwgZXJyb3InLAoJCQlaaXBBcmNoaXZlOjpFUl9JTkNPTlMgICAgICA9PiAnWmlwIGFyY2hpdmUgaW5jb25zaXN0ZW50JywKCQkJWmlwQXJjaGl2ZTo6RVJfUkVNT1ZFICAgICAgPT4gJ0NhblwndCByZW1vdmUgZmlsZScsCgkJCVppcEFyY2hpdmU6OkVSX0RFTEVURUQgICAgID0+ICdFbnRyeSBoYXMgYmVlbiBkZWxldGVkJywKCQldOwoKCQlpZiAoIGlzc2V0KCAkemlwX2Vycl9tc2dzWyAkZXJyb3JfY29kZSBdICkgKSB7CgkJCXJldHVybiBzcHJpbnRmKAoJCQkJJyVzICglZCknLAoJCQkJJHppcF9lcnJfbXNnc1sgJGVycm9yX2NvZGUgXSwKCQkJCSRlcnJvcl9jb2RlCgkJCSk7CgkJfQoJCXJldHVybiAkZXJyb3JfY29kZTsKCX0KCgkvKioKCSAqIFJldHVybiBmb3JtYXR0ZWQgZXJyb3IgbWVzc2FnZSBmcm9tIFByb2Nlc3NSdW4gb2YgdGFyIGNvbW1hbmQuCgkgKgoJICogQHBhcmFtIFByb2Nlc3NydW4gJHByb2Nlc3NfcnVuCgkgKiBAcmV0dXJuIHN0cmluZ3xpbnQgVGhlIGVycm9yIG1lc3NhZ2Ugb2YgdGhlIHByb2Nlc3MsIGlmIGF2YWlsYWJsZTsKCSAqICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UgdGhlIHJldHVybiBjb2RlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRhcl9lcnJvcl9tc2coICRwcm9jZXNzX3J1biApIHsKCQkkc3RkZXJyID0gdHJpbSggJHByb2Nlc3NfcnVuLT5zdGRlcnIgKTsKCQkkbmxfcG9zID0gc3RycG9zKCAkc3RkZXJyLCAiXG4iICk7CgkJaWYgKCBmYWxzZSAhPT0gJG5sX3BvcyApIHsKCQkJJHN0ZGVyciA9IHRyaW0oIHN1YnN0ciggJHN0ZGVyciwgMCwgJG5sX3BvcyApICk7CgkJfQoJCWlmICggJHN0ZGVyciApIHsKCQkJcmV0dXJuIHNwcmludGYoICclcyAoJWQpJywgJHN0ZGVyciwgJHByb2Nlc3NfcnVuLT5yZXR1cm5fY29kZSApOwoJCX0KCQlyZXR1cm4gJHByb2Nlc3NfcnVuLT5yZXR1cm5fY29kZTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgZmlyc3Qgc3ViZm9sZGVyIHdpdGhpbiBhIGdpdmVuIHBhdGguCgkgKgoJICogRmFsbHMgYmFjayB0byB0aGUgcHJvdmlkZWQgcGF0aCBpZiBubyBzdWJmb2xkZXIgd2FzIGRldGVjdGVkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byBmaW5kIHRoZSBmaXJzdCBzdWJmb2xkZXIgaW4uCgkgKiBAcmV0dXJuIHN0cmluZyBGaXJzdCBzdWJmb2xkZXIsIG9yIHNhbWUgYXMgJHBhdGggaWYgbm9uZSBmb3VuZC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2ZpcnN0X3N1YmZvbGRlciggJHBhdGggKSB7CgkJJGl0ZXJhdG9yID0gbmV3IERpcmVjdG9yeUl0ZXJhdG9yKCAkcGF0aCApOwoKCQlmb3JlYWNoICggJGl0ZXJhdG9yIGFzICRmaWxlaW5mbyApIHsKCQkJaWYgKCAkZmlsZWluZm8tPmlzRGlyKCkgJiYgISAkZmlsZWluZm8tPmlzRG90KCkgKSB7CgkJCQlyZXR1cm4gInskcGF0aH0veyRmaWxlaW5mby0+Z2V0RmlsZW5hbWUoKX0iOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHBhdGg7Cgl9CgoJLyoqCgkgKiBFbnN1cmUgZGlyZWN0b3J5IGV4aXN0cy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkaXIgRGlyZWN0b3J5IHRvIGVuc3VyZSB0aGUgZXhpc3RlbmNlIG9mLgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGV4aXN0ZW5jZSBjb3VsZCBiZSBhc3NlcnRlZC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZW5zdXJlX2Rpcl9leGlzdHMoICRkaXIgKSB7CgkJaWYgKCAhIGlzX2RpciggJGRpciApICkgewoJCQlpZiAoICEgQG1rZGlyKCAkZGlyLCAwNzc3LCB0cnVlICkgKSB7CgkJCQkkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCXNwcmludGYoCgkJCQkJCSJGYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAnJXMnOiAlcy4iLAoJCQkJCQkkZGlyLAoJCQkJCQkkZXJyb3JbJ21lc3NhZ2UnXQoJCQkJCSkKCQkJCSk7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQ2hlY2sgd2hldGhlciBhIHBhdGggaXMgcmVsYXRpdmUtCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBQYXRoIHRvIGNoZWNrLgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHBhdGggaXMgcmVsYXRpdmUuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHBhdGhfaXNfcmVsYXRpdmUoICRwYXRoICkgewoJCWlmICggJycgPT09ICRwYXRoICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCS8vIFN0cmlwIHNjaGVtZS4KCQkkc2NoZW1lX3Bvc2l0aW9uID0gc3RycG9zKCAkcGF0aCwgJzovLycgKTsKCQlpZiAoIGZhbHNlICE9PSAkc2NoZW1lX3Bvc2l0aW9uICkgewoJCQkkcGF0aCA9IHN1YnN0ciggJHBhdGgsICRzY2hlbWVfcG9zaXRpb24gKyAzICk7CgkJfQoKCQkvLyBVTklYIHJvb3QgIi8iIG9yICJcIiAoV2luZG93cyBzdHlsZSkuCgkJaWYgKCAnLycgPT09ICRwYXRoWzBdIHx8ICdcXCcgPT09ICRwYXRoWzBdICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBXaW5kb3dzIHJvb3QuCgkJaWYgKCBzdHJsZW4oICRwYXRoICkgPiAxICYmIGN0eXBlX2FscGhhKCAkcGF0aFswXSApICYmICc6JyA9PT0gJHBhdGhbMV0gKSB7CgoJCQkvLyBTcGVjaWFsIGNhc2U6IG9ubHkgZHJpdmUgbGV0dGVyLCBsaWtlICJDOiIuCgkJCWlmICggMiA9PT0gc3RybGVuKCAkcGF0aCApICkgewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQkvLyBSZWd1bGFyIFdpbmRvd3MgcGF0aCBzdGFydGluZyB3aXRoIGRyaXZlIGxldHRlciwgbGlrZSAiQzovIG9yICJDOlwiLgoJCQlpZiAoICcvJyA9PT0gJHBhdGhbMl0gfHwgJ1xcJyA9PT0gJHBhdGhbMl0gKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIE11c3Rhbmdvc3RhbmdcU3B5YzsKCi8qKgogKiBIYW5kbGVzIGZpbGUtIGFuZCBydW50aW1lLWJhc2VkIGNvbmZpZ3VyYXRpb24gdmFsdWVzLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbmZpZ3VyYXRvciB7CgoJLyoqCgkgKiBDb25maWd1cmF0b3IgYXJndW1lbnQgc3BlY2lmaWNhdGlvbi4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJHNwZWM7CgoJLyoqCgkgKiBWYWx1ZXMgZm9yIGtleXMgZGVmaW5lZCBpbiBDb25maWd1cmF0b3Igc3BlYy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJGNvbmZpZyA9IFtdOwoKCS8qKgoJICogRXh0cmEgY29uZmlnIHZhbHVlcyBub3Qgc3BlY2lmaWVkIGluIHNwZWMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRleHRyYV9jb25maWcgPSBbXTsKCgkvKioKCSAqIEFueSBhbGlhc2VzIGRlZmluZWQgaW4gY29uZmlnIGZpbGVzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkYWxpYXNlcyA9IFtdOwoKCS8qKgoJICogUmVnZXggcGF0dGVybiB1c2VkIHRvIGRlZmluZSBhbiBhbGlhcy4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBBTElBU19SRUdFWCA9ICdeQFtBLVphLXowLTktX1wuXC1dKyQnOwoKCS8qKgoJICogQXJndW1lbnRzIHRoYXQgY2FuIGJlIHVzZWQgaW4gYW4gYWxpYXMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyAkYWxpYXNfc3BlYyA9IFsKCQkndXNlcicsCgkJJ3VybCcsCgkJJ3BhdGgnLAoJCSdzc2gnLAoJCSdodHRwJywKCV07CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gY29uZmlnIHNwZWMgZmlsZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkcGF0aCApIHsKCQkkdGhpcy0+c3BlYyA9IGluY2x1ZGUgJHBhdGg7CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3J1bnRpbWUnICA9PiBmYWxzZSwKCQkJJ2ZpbGUnICAgICA9PiBmYWxzZSwKCQkJJ3N5bm9wc2lzJyA9PiAnJywKCQkJJ2RlZmF1bHQnICA9PiBudWxsLAoJCQknbXVsdGlwbGUnID0+IGZhbHNlLAoJCV07CgoJCWZvcmVhY2ggKCAkdGhpcy0+c3BlYyBhcyAka2V5ID0+ICYkZGV0YWlscyApIHsKCQkJJGRldGFpbHMgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkZGV0YWlscyApOwoKCQkJJHRoaXMtPmNvbmZpZ1sgJGtleSBdID0gJGRldGFpbHNbJ2RlZmF1bHQnXTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXQgZGVjbGFyZWQgY29uZmlndXJhdGlvbiB2YWx1ZXMgYXMgYW4gYXJyYXkuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gdG9fYXJyYXkoKSB7CgkJcmV0dXJuIFsgJHRoaXMtPmNvbmZpZywgJHRoaXMtPmV4dHJhX2NvbmZpZyBdOwoJfQoKCS8qKgoJICogR2V0IGNvbmZpZ3VyYXRpb24gc3BlY2lmaWNhdGlvbiwgaS5lLiBsaXN0IG9mIGFjY2VwdGVkIGtleXMuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3NwZWMoKSB7CgkJcmV0dXJuICR0aGlzLT5zcGVjOwoJfQoKCS8qKgoJICogR2V0IGFueSBhbGlhc2VzIGRlZmluZWQgaW4gY29uZmlnIGZpbGVzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9hbGlhc2VzKCkgewoJCSRydW50aW1lX2FsaWFzID0gZ2V0ZW52KCAnV1BfQ0xJX1JVTlRJTUVfQUxJQVMnICk7CgkJaWYgKCBmYWxzZSAhPT0gJHJ1bnRpbWVfYWxpYXMgKSB7CgkJCSRyZXR1cm5lZF9hbGlhc2VzID0gW107CgkJCWZvcmVhY2ggKCBqc29uX2RlY29kZSggJHJ1bnRpbWVfYWxpYXMsIHRydWUgKSBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCWlmICggcHJlZ19tYXRjaCggJyMnIC4gc2VsZjo6QUxJQVNfUkVHRVggLiAnIycsICRrZXkgKSApIHsKCQkJCQkkcmV0dXJuZWRfYWxpYXNlc1sgJGtleSBdID0gW107CgkJCQkJZm9yZWFjaCAoIHNlbGY6OiRhbGlhc19zcGVjIGFzICRpICkgewoJCQkJCQlpZiAoIGlzc2V0KCAkdmFsdWVbICRpIF0gKSApIHsKCQkJCQkJCSRyZXR1cm5lZF9hbGlhc2VzWyAka2V5IF1bICRpIF0gPSAkdmFsdWVbICRpIF07CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJcmV0dXJuICRyZXR1cm5lZF9hbGlhc2VzOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5hbGlhc2VzOwoJfQoKCS8qKgoJICogU3BsaXRzIGEgbGlzdCBvZiBhcmd1bWVudHMgaW50byBwb3NpdGlvbmFsLCBhc3NvY2lhdGl2ZSBhbmQgY29uZmlnLgoJICoKCSAqIEBwYXJhbSBhcnJheShzdHJpbmcpICRhcmd1bWVudHMKCSAqIEByZXR1cm4gYXJyYXkoYXJyYXkpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwYXJzZV9hcmdzKCAkYXJndW1lbnRzICkgewoJCWxpc3QoICRwb3NpdGlvbmFsX2FyZ3MsICRtaXhlZF9hcmdzLCAkZ2xvYmFsX2Fzc29jLCAkbG9jYWxfYXNzb2MgKSA9IHNlbGY6OmV4dHJhY3RfYXNzb2MoICRhcmd1bWVudHMgKTsKCQlsaXN0KCAkYXNzb2NfYXJncywgJHJ1bnRpbWVfY29uZmlnICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAkdGhpcy0+dW5taXhfYXNzb2NfYXJncyggJG1peGVkX2FyZ3MsICRnbG9iYWxfYXNzb2MsICRsb2NhbF9hc3NvYyApOwoJCXJldHVybiBbICRwb3NpdGlvbmFsX2FyZ3MsICRhc3NvY19hcmdzLCAkcnVudGltZV9jb25maWcgXTsKCX0KCgkvKioKCSAqIFNwbGl0cyBwb3NpdGlvbmFsIGFyZ3MgZnJvbSBhc3NvY2lhdGl2ZSBhcmdzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJndW1lbnRzCgkgKiBAcmV0dXJuIGFycmF5KGFycmF5KQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3RfYXNzb2MoICRhcmd1bWVudHMgKSB7CgkJJHBvc2l0aW9uYWxfYXJncyA9IFtdOwoJCSRhc3NvY19hcmdzICAgICAgPSBbXTsKCQkkZ2xvYmFsX2Fzc29jICAgID0gW107CgkJJGxvY2FsX2Fzc29jICAgICA9IFtdOwoKCQlmb3JlYWNoICggJGFyZ3VtZW50cyBhcyAkYXJnICkgewoJCQkkcG9zaXRpb25hbCA9IG51bGw7CgkJCSRhc3NvY19hcmcgID0gbnVsbDsKCgkJCWlmICggcHJlZ19tYXRjaCggJ3xeLS1uby0oW149XSspJHwnLCAkYXJnLCAkbWF0Y2hlcyApICkgewoJCQkJJGFzc29jX2FyZyA9IFsgJG1hdGNoZXNbMV0sIGZhbHNlIF07CgkJCX0gZWxzZWlmICggcHJlZ19tYXRjaCggJ3xeLS0oW149XSspJHwnLCAkYXJnLCAkbWF0Y2hlcyApICkgewoJCQkJJGFzc29jX2FyZyA9IFsgJG1hdGNoZXNbMV0sIHRydWUgXTsKCQkJfSBlbHNlaWYgKCBwcmVnX21hdGNoKCAnfF4tLShbXj1dKyk9KC4qKXxzJywgJGFyZywgJG1hdGNoZXMgKSApIHsKCQkJCSRhc3NvY19hcmcgPSBbICRtYXRjaGVzWzFdLCAkbWF0Y2hlc1syXSBdOwoJCQl9IGVsc2UgewoJCQkJJHBvc2l0aW9uYWwgPSAkYXJnOwoJCQl9CgoJCQlpZiAoICEgaXNfbnVsbCggJGFzc29jX2FyZyApICkgewoJCQkJJGFzc29jX2FyZ3NbXSA9ICRhc3NvY19hcmc7CgkJCQlpZiAoIGNvdW50KCAkcG9zaXRpb25hbF9hcmdzICkgKSB7CgkJCQkJJGxvY2FsX2Fzc29jW10gPSAkYXNzb2NfYXJnOwoJCQkJfSBlbHNlIHsKCQkJCQkkZ2xvYmFsX2Fzc29jW10gPSAkYXNzb2NfYXJnOwoJCQkJfQoJCQl9IGVsc2VpZiAoICEgaXNfbnVsbCggJHBvc2l0aW9uYWwgKSApIHsKCQkJCSRwb3NpdGlvbmFsX2FyZ3NbXSA9ICRwb3NpdGlvbmFsOwoJCQl9CgkJfQoKCQlyZXR1cm4gWyAkcG9zaXRpb25hbF9hcmdzLCAkYXNzb2NfYXJncywgJGdsb2JhbF9hc3NvYywgJGxvY2FsX2Fzc29jIF07Cgl9CgoJLyoqCgkgKiBTZXBhcmF0ZSBydW50aW1lIHBhcmFtZXRlcnMgZnJvbSBjb21tYW5kLXNwZWNpZmljIHBhcmFtZXRlcnMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRtaXhlZF9hcmdzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdW5taXhfYXNzb2NfYXJncyggJG1peGVkX2FyZ3MsICRnbG9iYWxfYXNzb2MgPSBbXSwgJGxvY2FsX2Fzc29jID0gW10gKSB7CgkJJGFzc29jX2FyZ3MgICAgID0gW107CgkJJHJ1bnRpbWVfY29uZmlnID0gW107CgoJCWlmICggZ2V0ZW52KCAnV1BfQ0xJX1NUUklDVF9BUkdTX01PREUnICkgKSB7CgkJCWZvcmVhY2ggKCAkZ2xvYmFsX2Fzc29jIGFzICR0bXAgKSB7CgkJCQlsaXN0KCAka2V5LCAkdmFsdWUgKSA9ICR0bXA7CgkJCQlpZiAoIGlzc2V0KCAkdGhpcy0+c3BlY1sgJGtleSBdICkgJiYgZmFsc2UgIT09ICR0aGlzLT5zcGVjWyAka2V5IF1bJ3J1bnRpbWUnXSApIHsKCQkJCQkkdGhpcy0+YXNzb2NfYXJnX3RvX3J1bnRpbWVfY29uZmlnKCAka2V5LCAkdmFsdWUsICRydW50aW1lX2NvbmZpZyApOwoJCQkJfQoJCQl9CgkJCWZvcmVhY2ggKCAkbG9jYWxfYXNzb2MgYXMgJHRtcCApIHsKCQkJCSRhc3NvY19hcmdzWyAkdG1wWzBdIF0gPSAkdG1wWzFdOwoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yZWFjaCAoICRtaXhlZF9hcmdzIGFzICR0bXAgKSB7CgkJCQlsaXN0KCAka2V5LCAkdmFsdWUgKSA9ICR0bXA7CgoJCQkJaWYgKCBpc3NldCggJHRoaXMtPnNwZWNbICRrZXkgXSApICYmIGZhbHNlICE9PSAkdGhpcy0+c3BlY1sgJGtleSBdWydydW50aW1lJ10gKSB7CgkJCQkJJHRoaXMtPmFzc29jX2FyZ190b19ydW50aW1lX2NvbmZpZyggJGtleSwgJHZhbHVlLCAkcnVudGltZV9jb25maWcgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJGFzc29jX2FyZ3NbICRrZXkgXSA9ICR2YWx1ZTsKCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIFsgJGFzc29jX2FyZ3MsICRydW50aW1lX2NvbmZpZyBdOwoJfQoKCS8qKgoJICogSGFuZGxlIHR1cm5pbmcgYW4gJGFzc29jX2FyZyBpbnRvIGEgcnVudGltZSBhcmcuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYXNzb2NfYXJnX3RvX3J1bnRpbWVfY29uZmlnKCAka2V5LCAkdmFsdWUsICYkcnVudGltZV9jb25maWcgKSB7CgkJJGRldGFpbHMgPSAkdGhpcy0+c3BlY1sgJGtleSBdOwoJCWlmICggaXNzZXQoICRkZXRhaWxzWydkZXByZWNhdGVkJ10gKSApIHsKCQkJZndyaXRlKCBTVERFUlIsICJXUC1DTEk6IFRoZSAtLXska2V5fSBnbG9iYWwgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQuIHskZGV0YWlsc1snZGVwcmVjYXRlZCddfVxuIiApOwoJCX0KCgkJaWYgKCAkZGV0YWlsc1snbXVsdGlwbGUnXSApIHsKCQkJJHJ1bnRpbWVfY29uZmlnWyAka2V5IF1bXSA9ICR2YWx1ZTsKCQl9IGVsc2UgewoJCQkkcnVudGltZV9jb25maWdbICRrZXkgXSA9ICR2YWx1ZTsKCQl9Cgl9CgoJLyoqCgkgKiBMb2FkIGEgWUFNTCBmaWxlIG9mIHBhcmFtZXRlcnMgaW50byBzY29wZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gWUFNTCBmaWxlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gbWVyZ2VfeW1sKCAkcGF0aCwgJGN1cnJlbnRfYWxpYXMgPSBudWxsICkgewoJCSR5YW1sID0gc2VsZjo6bG9hZF95bWwoICRwYXRoICk7CgkJaWYgKCAhIGVtcHR5KCAkeWFtbFsnXyddWydpbmhlcml0J10gKSApIHsKCQkJJHRoaXMtPm1lcmdlX3ltbCggJHlhbWxbJ18nXVsnaW5oZXJpdCddLCAkY3VycmVudF9hbGlhcyApOwoJCX0KCQkvLyBQcmVwYXJlIHRoZSBiYXNlIHBhdGggZm9yIGFic29sdXRpemVkIGFsaWFzIHBhdGhzLgoJCSR5bWxfZmlsZV9kaXIgPSAkcGF0aCA/IGRpcm5hbWUoICRwYXRoICkgOiBmYWxzZTsKCQlmb3JlYWNoICggJHlhbWwgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCWlmICggcHJlZ19tYXRjaCggJyMnIC4gc2VsZjo6QUxJQVNfUkVHRVggLiAnIycsICRrZXkgKSApIHsKCQkJCSR0aGlzLT5hbGlhc2VzWyAka2V5IF0gPSBbXTsKCQkJCSRpc19hbGlhcyAgICAgICAgICAgICAgPSBmYWxzZTsKCQkJCWZvcmVhY2ggKCBzZWxmOjokYWxpYXNfc3BlYyBhcyAkaSApIHsKCQkJCQlpZiAoIGlzc2V0KCAkdmFsdWVbICRpIF0gKSApIHsKCQkJCQkJaWYgKCAncGF0aCcgPT09ICRpICYmICEgaXNzZXQoICR2YWx1ZVsnc3NoJ10gKSApIHsKCQkJCQkJCXNlbGY6OmFic29sdXRpemUoICR2YWx1ZVsgJGkgXSwgJHltbF9maWxlX2RpciApOwoJCQkJCQl9CgkJCQkJCSR0aGlzLT5hbGlhc2VzWyAka2V5IF1bICRpIF0gPSAkdmFsdWVbICRpIF07CgkJCQkJCSRpc19hbGlhcyAgICAgICAgICAgICAgICAgICAgPSB0cnVlOwoJCQkJCX0KCQkJCX0KCQkJCS8vIElmIGl0J3Mgbm90IGFuIGFsaWFzLCBpdCBtaWdodCBiZSBhIGdyb3VwIG9mIGFsaWFzZXMuCgkJCQlpZiAoICEgJGlzX2FsaWFzICYmIGlzX2FycmF5KCAkdmFsdWUgKSApIHsKCQkJCQkkYWxpYXNfZ3JvdXAgPSBbXTsKCQkJCQlmb3JlYWNoICggJHZhbHVlIGFzICRrICkgewoJCQkJCQlpZiAoIHByZWdfbWF0Y2goICcjJyAuIHNlbGY6OkFMSUFTX1JFR0VYIC4gJyMnLCAkayApICkgewoJCQkJCQkJJGFsaWFzX2dyb3VwW10gPSAkazsKCQkJCQkJfQoJCQkJCX0KCQkJCQkkdGhpcy0+YWxpYXNlc1sgJGtleSBdID0gJGFsaWFzX2dyb3VwOwoJCQkJfQoJCQl9IGVsc2VpZiAoICEgaXNzZXQoICR0aGlzLT5zcGVjWyAka2V5IF0gKSB8fCBmYWxzZSA9PT0gJHRoaXMtPnNwZWNbICRrZXkgXVsnZmlsZSddICkgewoJCQkJaWYgKCBpc3NldCggJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJGtleSBdICkKCQkJCQkmJiAhIGVtcHR5KCAkeWFtbFsnXyddWydtZXJnZSddICkKCQkJCQkmJiBpc19hcnJheSggJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJGtleSBdICkKCQkJCQkmJiBpc19hcnJheSggJHZhbHVlICkgKSB7CgkJCQkJJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJGtleSBdID0gYXJyYXlfbWVyZ2UoICR0aGlzLT5leHRyYV9jb25maWdbICRrZXkgXSwgJHZhbHVlICk7CgkJCQl9IGVsc2UgewoJCQkJCSR0aGlzLT5leHRyYV9jb25maWdbICRrZXkgXSA9ICR2YWx1ZTsKCQkJCX0KCQkJfSBlbHNlaWYgKCAkdGhpcy0+c3BlY1sgJGtleSBdWydtdWx0aXBsZSddICkgewoJCQkJc2VsZjo6YXJyYXlpZnkoICR2YWx1ZSApOwoJCQkJJHRoaXMtPmNvbmZpZ1sgJGtleSBdID0gYXJyYXlfbWVyZ2UoICR0aGlzLT5jb25maWdbICRrZXkgXSwgJHZhbHVlICk7CgkJCX0gZWxzZSB7CgkJCQlpZiAoICRjdXJyZW50X2FsaWFzICYmIGluX2FycmF5KCAka2V5LCBzZWxmOjokYWxpYXNfc3BlYywgdHJ1ZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJJHRoaXMtPmNvbmZpZ1sgJGtleSBdID0gJHZhbHVlOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogTWVyZ2UgYW4gYXJyYXkgb2YgdmFsdWVzIGludG8gdGhlIGNvbmZpZ3VyYXRvciBjb25maWcuCgkgKgoJICogQHBhcmFtIGFycmF5ICRjb25maWcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG1lcmdlX2FycmF5KCAkY29uZmlnICkgewoJCWZvcmVhY2ggKCAkdGhpcy0+c3BlYyBhcyAka2V5ID0+ICRkZXRhaWxzICkgewoJCQlpZiAoIGZhbHNlICE9PSAkZGV0YWlsc1sncnVudGltZSddICYmIGlzc2V0KCAkY29uZmlnWyAka2V5IF0gKSApIHsKCQkJCSR2YWx1ZSA9ICRjb25maWdbICRrZXkgXTsKCgkJCQlpZiAoICdyZXF1aXJlJyA9PT0gJGtleSApIHsKCQkJCQkkdmFsdWUgPSBVdGlsc1xleHBhbmRfZ2xvYnMoICR2YWx1ZSApOwoJCQkJfQoKCQkJCWlmICggJGRldGFpbHNbJ211bHRpcGxlJ10gKSB7CgkJCQkJc2VsZjo6YXJyYXlpZnkoICR2YWx1ZSApOwoJCQkJCSR0aGlzLT5jb25maWdbICRrZXkgXSA9IGFycmF5X21lcmdlKCAkdGhpcy0+Y29uZmlnWyAka2V5IF0sICR2YWx1ZSApOwoJCQkJfSBlbHNlIHsKCQkJCQkkdGhpcy0+Y29uZmlnWyAka2V5IF0gPSAkdmFsdWU7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBMb2FkIHZhbHVlcyBmcm9tIGEgWUFNTCBmaWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHltbF9maWxlIFBhdGggdG8gdGhlIFlBTUwgZmlsZQoJICogQHJldHVybiBhcnJheSBEZWNsYXJlZCBjb25maWd1cmF0aW9uIHZhbHVlcwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBsb2FkX3ltbCggJHltbF9maWxlICkgewoJCWlmICggISAkeW1sX2ZpbGUgKSB7CgkJCXJldHVybiBbXTsKCQl9CgoJCSRjb25maWcgPSBTcHljOjpZQU1MTG9hZCggJHltbF9maWxlICk7CgoJCS8vIE1ha2Ugc3VyZSBjb25maWctZmlsZS1yZWxhdGl2ZSBwYXRocyBhcmUgbWFkZSBhYnNvbHV0ZS4KCQkkeW1sX2ZpbGVfZGlyID0gZGlybmFtZSggJHltbF9maWxlICk7CgoJCWlmICggaXNzZXQoICRjb25maWdbJ3BhdGgnXSApICkgewoJCQlzZWxmOjphYnNvbHV0aXplKCAkY29uZmlnWydwYXRoJ10sICR5bWxfZmlsZV9kaXIgKTsKCQl9CgoJCWlmICggaXNzZXQoICRjb25maWdbJ3JlcXVpcmUnXSApICkgewoJCQlzZWxmOjphcnJheWlmeSggJGNvbmZpZ1sncmVxdWlyZSddICk7CgkJCSRjb25maWdbJ3JlcXVpcmUnXSA9IFV0aWxzXGV4cGFuZF9nbG9icyggJGNvbmZpZ1sncmVxdWlyZSddICk7CgkJCWZvcmVhY2ggKCAkY29uZmlnWydyZXF1aXJlJ10gYXMgJiRwYXRoICkgewoJCQkJc2VsZjo6YWJzb2x1dGl6ZSggJHBhdGgsICR5bWxfZmlsZV9kaXIgKTsKCQkJfQoJCX0KCgkJLy8gQmFja3dhcmRzIGNvbXBhdAoJCS8vIENvbW1hbmQgJ2NvcmUgY29uZmlnJyB3YXMgbW92ZWQgdG8gJ2NvbmZpZyBjcmVhdGUnLgoJCWlmICggaXNzZXQoICRjb25maWdbJ2NvcmUgY29uZmlnJ10gKSApIHsKCQkJJGNvbmZpZ1snY29uZmlnIGNyZWF0ZSddID0gJGNvbmZpZ1snY29yZSBjb25maWcnXTsKCQkJdW5zZXQoICRjb25maWdbJ2NvcmUgY29uZmlnJ10gKTsKCQl9CgkJLy8gQ29tbWFuZCAnY2hlY2tzdW0gY29yZScgd2FzIG1vdmVkIHRvICdjb3JlIHZlcmlmeS1jaGVja3N1bXMnLgoJCWlmICggaXNzZXQoICRjb25maWdbJ2NoZWNrc3VtIGNvcmUnXSApICkgewoJCQkkY29uZmlnWydjb3JlIHZlcmlmeS1jaGVja3N1bXMnXSA9ICRjb25maWdbJ2NoZWNrc3VtIGNvcmUnXTsKCQkJdW5zZXQoICRjb25maWdbJ2NoZWNrc3VtIGNvcmUnXSApOwoJCX0KCQkvLyBDb21tYW5kICdjaGVja3N1bSBwbHVnaW4nIHdhcyBtb3ZlZCB0byAncGx1Z2luIHZlcmlmeS1jaGVja3N1bXMnLgoJCWlmICggaXNzZXQoICRjb25maWdbJ2NoZWNrc3VtIHBsdWdpbiddICkgKSB7CgkJCSRjb25maWdbJ3BsdWdpbiB2ZXJpZnktY2hlY2tzdW1zJ10gPSAkY29uZmlnWydjaGVja3N1bSBwbHVnaW4nXTsKCQkJdW5zZXQoICRjb25maWdbJ2NoZWNrc3VtIHBsdWdpbiddICk7CgkJfQoKCQlyZXR1cm4gJGNvbmZpZzsKCX0KCgkvKioKCSAqIENvbmZvcm0gYSB2YXJpYWJsZSB0byBhbiBhcnJheS4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHZhbCBBIHN0cmluZyBvciBhbiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBhcnJheWlmeSggJiR2YWwgKSB7CgkJJHZhbCA9IChhcnJheSkgJHZhbDsKCX0KCgkvKioKCSAqIE1ha2UgYSBwYXRoIGFic29sdXRlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byBmaWxlLgoJICogQHBhcmFtIHN0cmluZyAkYmFzZSBCYXNlIHBhdGggdG8gcHJlcGVuZC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYWJzb2x1dGl6ZSggJiRwYXRoLCAkYmFzZSApIHsKCQlpZiAoICEgZW1wdHkoICRwYXRoICkgJiYgISBVdGlsc1xpc19wYXRoX2Fic29sdXRlKCAkcGF0aCApICkgewoJCQkkcGF0aCA9ICRiYXNlIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRwYXRoOwoJCX0KCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFJ1bGU7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudDsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnRzOwp1c2UgV1BfQ0xJOwoKLyoqCiAqIEEgQ29tcG9zZXIgRXZlbnQgc3Vic2NyaWJlciBzbyB3ZSBjYW4ga2VlcCB0cmFjayBvZiB3aGF0J3MgaGFwcGVuaW5nIGluc2lkZSBDb21wb3NlcgogKi8KY2xhc3MgUGFja2FnZU1hbmFnZXJFdmVudFN1YnNjcmliZXIgaW1wbGVtZW50cyBFdmVudFN1YnNjcmliZXJJbnRlcmZhY2UgewoKCS8qKgoJICogR2V0IHN1YnNjcmliZWQgZXZlbnRzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTdWJzY3JpYmVkRXZlbnRzKCkgewoKCQlyZXR1cm4gWwoJCQlQYWNrYWdlRXZlbnRzOjpQUkVfUEFDS0FHRV9JTlNUQUxMICA9PiAncHJlX2luc3RhbGwnLAoJCQlQYWNrYWdlRXZlbnRzOjpQT1NUX1BBQ0tBR0VfSU5TVEFMTCA9PiAncG9zdF9pbnN0YWxsJywKCQldOwoJfQoKCS8qKgoJICogUHJlLWluc3RhbGwgb3BlcmF0aW9uIG1lc3NhZ2UuCgkgKgoJICogQHBhcmFtIFxDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50ICRldmVudAoJICoKCSAqIEByZXR1cm4gdm9pZAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByZV9pbnN0YWxsKCBQYWNrYWdlRXZlbnQgJGV2ZW50ICkgewoJCSRvcGVyYXRpb25fbWVzc2FnZSA9ICRldmVudC0+Z2V0T3BlcmF0aW9uKCktPl9fdG9TdHJpbmcoKTsKCQlXUF9DTEk6OmxvZyggJyAtICcgLiAkb3BlcmF0aW9uX21lc3NhZ2UgKTsKCX0KCgkvKioKCSAqIFBvc3QtaW5zdGFsbCBvcGVyYXRpb24gbG9nLgoJICoKCSAqIEBwYXJhbSBcQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudCAkZXZlbnQKCSAqCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwb3N0X2luc3RhbGwoIFBhY2thZ2VFdmVudCAkZXZlbnQgKSB7CgoJCSRvcGVyYXRpb24gPSAkZXZlbnQtPmdldE9wZXJhdGlvbigpOwoKCQkvLyBnZXRSZWFzb24oKSB3YXMgcmVtb3ZlZCBpbiBDb21wb3NlciB2MiB3aXRob3V0IHJlcGxhY2VtZW50LgoJCWlmICggISBtZXRob2RfZXhpc3RzKCAkb3BlcmF0aW9uLCAnZ2V0UmVhc29uJyApICkgewoJCQlyZXR1cm47CgkJfQoKCQkkcmVhc29uID0gJG9wZXJhdGlvbi0+Z2V0UmVhc29uKCk7CgkJaWYgKCAkcmVhc29uIGluc3RhbmNlb2YgUnVsZSApIHsKCgkJCXN3aXRjaCAoICRyZWFzb24tPmdldFJlYXNvbigpICkgewoKCQkJCWNhc2UgUnVsZTo6UlVMRV9QQUNLQUdFX0NPTkZMSUNUOgoJCQkJY2FzZSBSdWxlOjpSVUxFX1BBQ0tBR0VfU0FNRV9OQU1FOgoJCQkJY2FzZSBSdWxlOjpSVUxFX1BBQ0tBR0VfUkVRVUlSRVM6CgkJCQkJJGNvbXBvc2VyX2Vycm9yID0gJHJlYXNvbi0+Z2V0UHJldHR5U3RyaW5nKCAkZXZlbnQtPmdldFBvb2woKSApOwoJCQkJCWJyZWFrOwoKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkY29tcG9zZXJfZXJyb3IgKSApIHsKCQkJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnIC0gV2FybmluZzogJXMnLCAkY29tcG9zZXJfZXJyb3IgKSApOwoJCQl9CgkJfQoKCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgUnVudGltZUV4Y2VwdGlvbjsKCi8qKgogKiBDbGFzcyBXcE9yZ0FwaS4KICoKICogVGhpcyBpcyBhbiBhYnN0cmFjdGlvbiBvZiB0aGUgV29yZFByZXNzLm9yZyBBUEkuCiAqCiAqIEBzZWUgaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1dvcmRQcmVzcy5vcmdfQVBJCiAqCiAqIEBwYWNrYWdlIFdQX0NMSQogKi8KZmluYWwgY2xhc3MgV3BPcmdBcGkgewoKCS8qKgoJICogV29yZFByZXNzLm9yZyBBUEkgcm9vdCBVUkwuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgQVBJX1JPT1QgPSAnaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZyc7CgoJLyoqCgkgKiBXb3JkUHJlc3Mub3JnIEFQSSByb290IFVSTC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBET1dOTE9BRFNfUk9PVCA9ICdodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnJzsKCgkvKioKCSAqIENvcmUgY2hlY2tzdW1zIGVuZHBvaW50LgoJICoKCSAqIEBzZWUgaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1dvcmRQcmVzcy5vcmdfQVBJI0NoZWNrc3VtCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgQ09SRV9DSEVDS1NVTVNfRU5EUE9JTlQgPSBzZWxmOjpBUElfUk9PVCAuICcvY29yZS9jaGVja3N1bXMvMS4wLyc7CgoJLyoqCgkgKiBQbHVnaW4gY2hlY2tzdW1zIGVuZHBvaW50LgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFBMVUdJTl9DSEVDS1NVTVNfRU5EUE9JTlQgPSBzZWxmOjpET1dOTE9BRFNfUk9PVCAuICcvcGx1Z2luLWNoZWNrc3Vtcy8nOwoKCS8qKgoJICogUGx1Z2luIGluZm8gZW5kcG9pbnQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgUExVR0lOX0lORk9fRU5EUE9JTlQgPSBzZWxmOjpBUElfUk9PVCAuICcvcGx1Z2lucy9pbmZvLzEuMi8nOwoKCS8qKgoJICogVGhlbWUgaW5mbyBlbmRwb2ludC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBUSEVNRV9JTkZPX0VORFBPSU5UID0gc2VsZjo6QVBJX1JPT1QgLiAnL3RoZW1lcy9pbmZvLzEuMi8nOwoKCS8qKgoJICogU2FsdCBlbmRwb2ludC4KCSAqCgkgKiBAc2VlIGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9Xb3JkUHJlc3Mub3JnX0FQSSNTZWNyZXRfS2V5CgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgU0FMVF9FTkRQT0lOVCA9IHNlbGY6OkFQSV9ST09UIC4gJy9zZWNyZXQta2V5LzEuMS9zYWx0Lyc7CgoJLyoqCgkgKiBWZXJzaW9uIGNoZWNrIGVuZHBvaW50LgoJICoKCSAqIEBzZWUgaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1dvcmRQcmVzcy5vcmdfQVBJI1ZlcnNpb25fQ2hlY2sKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBWRVJTSU9OX0NIRUNLX0VORFBPSU5UID0gc2VsZjo6QVBJX1JPT1QgLiAnL2NvcmUvdmVyc2lvbi1jaGVjay8xLjcvJzsKCgkvKioKCSAqIE9wdGlvbnMgdG8gcGFzcyBvbnRvIHRoZSBSZXF1ZXN0cyBsaWJyYXJ5IGZvciBleGVjdXRpbmcgdGhlIHJlbW90ZSBjYWxscy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJG9wdGlvbnM7CgoJLyoqCgkgKiBXcE9yZ0FwaSBjb25zdHJ1Y3Rvci4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgQXNzb2NpYXRpdmUgYXJyYXkgb2Ygb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBBUEkgYWJzdHJhY3Rpb24uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJG9wdGlvbnMgPSBbXSApIHsKCQkkdGhpcy0+b3B0aW9ucyA9ICRvcHRpb25zOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgY2hlY2tzdW1zIGZvciB0aGUgZ2l2ZW4gdmVyc2lvbiBvZiBXb3JkUHJlc3MgY29yZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uIFZlcnNpb24gc3RyaW5nIHRvIHF1ZXJ5LgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlICBPcHRpb25hbC4gTG9jYWxlIHRvIHF1ZXJ5LiBEZWZhdWx0cyB0byAnZW5fVVMnLgoJICogQHJldHVybiBib29sfGFycmF5IEZhbHNlIG9uIGZhaWx1cmUuIEFuIGFycmF5IG9mIGNoZWNrc3VtcyBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlscy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9jb3JlX2NoZWNrc3VtcyggJHZlcnNpb24sICRsb2NhbGUgPSAnZW5fVVMnICkgewoJCSR1cmwgPSBzcHJpbnRmKAoJCQknJXM/JXMnLAoJCQlzZWxmOjpDT1JFX0NIRUNLU1VNU19FTkRQT0lOVCwKCQkJaHR0cF9idWlsZF9xdWVyeSggY29tcGFjdCggJ3ZlcnNpb24nLCAnbG9jYWxlJyApLCBudWxsLCAnJicgKQoJCSk7CgoJCSRyZXNwb25zZSA9ICR0aGlzLT5qc29uX2dldF9yZXF1ZXN0KCAkdXJsICk7CgoJCWlmICgKCQkJISBpc19hcnJheSggJHJlc3BvbnNlICkKCQkJfHwgISBpc3NldCggJHJlc3BvbnNlWydjaGVja3N1bXMnXSApCgkJCXx8ICEgaXNfYXJyYXkoICRyZXNwb25zZVsnY2hlY2tzdW1zJ10gKQoJCSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJHJlc3BvbnNlWydjaGVja3N1bXMnXTsKCX0KCgkvKioKCSAqIEdldHMgYSBjb3JlIHZlcnNpb24gY2hlY2suCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlIE9wdGlvbmFsLiBMb2NhbGUgdG8gcmVxdWVzdCBhIHZlcnNpb24gY2hlY2sgZm9yLiBEZWZhdWx0cyB0byAnZW5fVVMnLgoJICogQHJldHVybiBhcnJheXxmYWxzZSBGYWxzZSBvbiBmYWlsdXJlLiBBc3NvY2lhdGl2ZSBhcnJheSBvZiB0aGUgb2ZmZXIgb24gc3VjY2Vzcy4KCSAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgcmVtb3RlIHJlcXVlc3QgZmFpbGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2NvcmVfdmVyc2lvbl9jaGVjayggJGxvY2FsZSA9ICdlbl9VUycgKSB7CgkJJHVybCA9IHNwcmludGYoCgkJCSclcz8lcycsCgkJCXNlbGY6OlZFUlNJT05fQ0hFQ0tfRU5EUE9JTlQsCgkJCWh0dHBfYnVpbGRfcXVlcnkoIGNvbXBhY3QoICdsb2NhbGUnICksIG51bGwsICcmJyApCgkJKTsKCgkJJHJlc3BvbnNlID0gJHRoaXMtPmpzb25fZ2V0X3JlcXVlc3QoICR1cmwgKTsKCgkJaWYgKCAhIGlzX2FycmF5KCAkcmVzcG9uc2UgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRyZXNwb25zZTsKCX0KCgkvKioKCSAqIEdldHMgYSBkb3dubG9hZCBvZmZlci4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUgT3B0aW9uYWwuIExvY2FsZSB0byByZXF1ZXN0IGFuIG9mZmVyIGZyb20uIERlZmF1bHRzIHRvICdlbl9VUycuCgkgKiBAcmV0dXJuIGFycmF5fGZhbHNlIEZhbHNlIG9uIGZhaWx1cmUuIEFzc29jaWF0aXZlIGFycmF5IG9mIHRoZSBvZmZlciBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlsZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfY29yZV9kb3dubG9hZF9vZmZlciggJGxvY2FsZSA9ICdlbl9VUycgKSB7CgkJJHJlc3BvbnNlID0gJHRoaXMtPmdldF9jb3JlX3ZlcnNpb25fY2hlY2soICRsb2NhbGUgKTsKCgkJaWYgKAoJCQkhIGlzX2FycmF5KCAkcmVzcG9uc2UgKQoJCQl8fCAhIGlzc2V0KCAkcmVzcG9uc2VbJ29mZmVycyddICkKCQkJfHwgISBpc19hcnJheSggJHJlc3BvbnNlWydvZmZlcnMnXSApCgkJKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRvZmZlciA9ICRyZXNwb25zZVsnb2ZmZXJzJ11bMF07CgoJCWlmICggISBhcnJheV9rZXlfZXhpc3RzKCAnbG9jYWxlJywgJG9mZmVyICkgfHwgJGxvY2FsZSAhPT0gJG9mZmVyWydsb2NhbGUnXSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRvZmZlcjsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGNoZWNrc3VtcyBmb3IgdGhlIGdpdmVuIHZlcnNpb24gb2YgcGx1Z2luLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBsdWdpbiAgUGx1Z2luIHNsdWcgdG8gcXVlcnkuCgkgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uIFZlcnNpb24gc3RyaW5nIHRvIHF1ZXJ5LgoJICogQHJldHVybiBib29sfGFycmF5IEZhbHNlIG9uIGZhaWx1cmUuIEFuIGFycmF5IG9mIGNoZWNrc3VtcyBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlscy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9wbHVnaW5fY2hlY2tzdW1zKCAkcGx1Z2luLCAkdmVyc2lvbiApIHsKCQkkdXJsID0gc3ByaW50ZigKCQkJJyVzJXMvJXMuanNvbicsCgkJCXNlbGY6OlBMVUdJTl9DSEVDS1NVTVNfRU5EUE9JTlQsCgkJCSRwbHVnaW4sCgkJCSR2ZXJzaW9uCgkJKTsKCgkJJHJlc3BvbnNlID0gJHRoaXMtPmpzb25fZ2V0X3JlcXVlc3QoICR1cmwgKTsKCgkJaWYgKAoJCQkhIGlzX2FycmF5KCAkcmVzcG9uc2UgKQoJCQl8fCAhIGlzc2V0KCAkcmVzcG9uc2VbJ2ZpbGVzJ10gKQoJCQl8fCAhIGlzX2FycmF5KCAkcmVzcG9uc2VbJ2ZpbGVzJ10gKQoJCSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJHJlc3BvbnNlWydmaWxlcyddOwoJfQoKCS8qKgoJICogR2V0cyBhIHBsdWdpbidzIGluZm8uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGx1Z2luIFBsdWdpbiBzbHVnIHRvIHF1ZXJ5LgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlIE9wdGlvbmFsLiBMb2NhbGUgdG8gcmVxdWVzdCBpbmZvIGZvci4gRGVmYXVsdHMgdG8gJ2VuX1VTJy4KCSAqIEByZXR1cm4gYXJyYXl8ZmFsc2UgRmFsc2Ugb24gZmFpbHVyZS4gQXNzb2NpYXRpdmUgYXJyYXkgb2YgdGhlIG9mZmVyIG9uIHN1Y2Nlc3MuCgkgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHJlbW90ZSByZXF1ZXN0IGZhaWxlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9wbHVnaW5faW5mbyggJHBsdWdpbiwgJGxvY2FsZSA9ICdlbl9VUycgKSB7CgkJJGFjdGlvbiAgPSAncGx1Z2luX2luZm9ybWF0aW9uJzsKCQkkcmVxdWVzdCA9IFsKCQkJJ2xvY2FsZScgPT4gJGxvY2FsZSwKCQkJJ3NsdWcnICAgPT4gJHBsdWdpbiwKCQldOwoKCQkkdXJsID0gc3ByaW50ZigKCQkJJyVzPyVzJywKCQkJc2VsZjo6UExVR0lOX0lORk9fRU5EUE9JTlQsCgkJCWh0dHBfYnVpbGRfcXVlcnkoIGNvbXBhY3QoICdhY3Rpb24nLCAncmVxdWVzdCcgKSwgbnVsbCwgJyYnICkKCQkpOwoKCQkkcmVzcG9uc2UgPSAkdGhpcy0+anNvbl9nZXRfcmVxdWVzdCggJHVybCApOwoKCQlpZiAoICEgaXNfYXJyYXkoICRyZXNwb25zZSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJHJlc3BvbnNlOwoJfQoKCS8qKgoJICogR2V0cyBhIHRoZW1lJ3MgaW5mby4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0aGVtZSAgVGhlbWUgc2x1ZyB0byBxdWVyeS4KCSAqIEBwYXJhbSBzdHJpbmcgJGxvY2FsZSBPcHRpb25hbC4gTG9jYWxlIHRvIHJlcXVlc3QgaW5mbyBmb3IuIERlZmF1bHRzIHRvICdlbl9VUycuCgkgKiBAcmV0dXJuIGFycmF5fGZhbHNlIEZhbHNlIG9uIGZhaWx1cmUuIEFzc29jaWF0aXZlIGFycmF5IG9mIHRoZSBvZmZlciBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlsZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfdGhlbWVfaW5mbyggJHRoZW1lLCAkbG9jYWxlID0gJ2VuX1VTJyApIHsKCQkkYWN0aW9uICA9ICd0aGVtZV9pbmZvcm1hdGlvbic7CgkJJHJlcXVlc3QgPSBbCgkJCSdsb2NhbGUnID0+ICRsb2NhbGUsCgkJCSdzbHVnJyAgID0+ICR0aGVtZSwKCQldOwoKCQkkdXJsID0gc3ByaW50ZigKCQkJJyVzPyVzJywKCQkJc2VsZjo6VEhFTUVfSU5GT19FTkRQT0lOVCwKCQkJaHR0cF9idWlsZF9xdWVyeSggY29tcGFjdCggJ2FjdGlvbicsICdyZXF1ZXN0JyApLCBudWxsLCAnJicgKQoJCSk7CgoJCSRyZXNwb25zZSA9ICR0aGlzLT5qc29uX2dldF9yZXF1ZXN0KCAkdXJsICk7CgoJCWlmICggISBpc19hcnJheSggJHJlc3BvbnNlICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkcmVzcG9uc2U7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgc2V0IG9mIHNhbHRzIGluIHRoZSBmb3JtYXQgcmVxdWlyZWQgYnkgYHdwLWNvbmZpZy5waHBgLgoJICoKCSAqIEByZXR1cm4gYm9vbHxzdHJpbmcgRmFsc2Ugb24gZmFpbHVyZS4gQSBzdHJpbmcgb2YgUEhQIGRlZmluZSgpIHN0YXRlbWVudHMgb24gc3VjY2Vzcy4KCSAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgcmVtb3RlIHJlcXVlc3QgZmFpbHMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc2FsdHMoKSB7CgkJcmV0dXJuICR0aGlzLT5nZXRfcmVxdWVzdCggc2VsZjo6U0FMVF9FTkRQT0lOVCApOwoJfQoKCS8qKgoJICogRXhlY3V0ZSBhIHJlbW90ZSBHRVQgcmVxdWVzdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgICAgIFVSTCB0byBleGVjdXRlIHRoZSBHRVQgcmVxdWVzdCBvbi4KCSAqIEBwYXJhbSBhcnJheSAgJGhlYWRlcnMgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIGhlYWRlcnMuCgkgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zIE9wdGlvbmFsLiBBc3NvY2lhdGl2ZSBhcnJheSBvZiBvcHRpb25zLgoJICogQHJldHVybiBtaXhlZHxmYWxzZSBGYWxzZSBvbiBmYWlsdXJlLiBEZWNvZGVkIEpTT04gb24gc3VjY2Vzcy4KCSAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgSlNPTiBjb3VsZCBub3QgYmUgZGVjb2RlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBqc29uX2dldF9yZXF1ZXN0KCAkdXJsLCAkaGVhZGVycyA9IFtdLCAkb3B0aW9ucyA9IFtdICkgewoJCSRoZWFkZXJzID0gYXJyYXlfbWVyZ2UoCgkJCVsKCQkJCSdBY2NlcHQnID0+ICdhcHBsaWNhdGlvbi9qc29uJywKCQkJXSwKCQkJJGhlYWRlcnMKCQkpOwoKCQkkcmVzcG9uc2UgPSAkdGhpcy0+Z2V0X3JlcXVlc3QoICR1cmwsICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQlpZiAoIGZhbHNlID09PSAkcmVzcG9uc2UgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoKCQkkZGF0YSA9IGpzb25fZGVjb2RlKCAkcmVzcG9uc2UsIHRydWUgKTsKCgkJaWYgKCBKU09OX0VSUk9SX05PTkUgIT09IGpzb25fbGFzdF9lcnJvcigpICkgewoJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbiggJ0ZhaWxlZCB0byBkZWNvZGUgSlNPTjogJyAuIGpzb25fbGFzdF9lcnJvcl9tc2coKSApOwoJCX0KCgkJcmV0dXJuICRkYXRhOwoJfQoKCS8qKgoJICogRXhlY3V0ZSBhIHJlbW90ZSBHRVQgcmVxdWVzdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgICAgIFVSTCB0byBleGVjdXRlIHRoZSBHRVQgcmVxdWVzdCBvbi4KCSAqIEBwYXJhbSBhcnJheSAgJGhlYWRlcnMgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIGhlYWRlcnMuCgkgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zIE9wdGlvbmFsLiBBc3NvY2lhdGl2ZSBhcnJheSBvZiBvcHRpb25zLgoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UgRmFsc2Ugb24gZmFpbHVyZS4gUmVzcG9uc2UgYm9keSBzdHJpbmcgb24gc3VjY2Vzcy4KCSAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgcmVtb3RlIHJlcXVlc3QgZmFpbHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3JlcXVlc3QoICR1cmwsICRoZWFkZXJzID0gW10sICRvcHRpb25zID0gW10gKSB7CgkJJG9wdGlvbnMgPSBhcnJheV9tZXJnZSgKCQkJJHRoaXMtPm9wdGlvbnMsCgkJCVsKCQkJCSdoYWx0X29uX2Vycm9yJyA9PiBmYWxzZSwKCQkJXSwKCQkJJG9wdGlvbnMKCQkpOwoKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkdXJsLCBudWxsLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCgkJaWYgKAoJCQkhICRyZXNwb25zZS0+c3VjY2VzcwoJCQl8fCAyMDAgPiAoaW50KSAkcmVzcG9uc2UtPnN0YXR1c19jb2RlCgkJCXx8IDMwMCA8PSAkcmVzcG9uc2UtPnN0YXR1c19jb2RlCgkJKSB7CgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAoJCQkJIkNvdWxkbid0IGZldGNoIHJlc3BvbnNlIGZyb20geyR1cmx9IChIVFRQIGNvZGUgeyRyZXNwb25zZS0+c3RhdHVzX2NvZGV9KS4iCgkJCSk7CgkJfQoKCQlyZXR1cm4gdHJpbSggJHJlc3BvbnNlLT5ib2R5ICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7CgovKioKICogUmVzdWx0cyBvZiBhbiBleGVjdXRlZCBjb21tYW5kLgogKi8KY2xhc3MgUHJvY2Vzc1J1biB7CgoJLyoqCgkgKiBUaGUgZnVsbCBjb21tYW5kIGV4ZWN1dGVkIGJ5IHRoZSBzeXN0ZW0uCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRjb21tYW5kOwoKCS8qKgoJICogQ2FwdHVyZWQgb3V0cHV0IGZyb20gdGhlIHByb2Nlc3MnIFNURE9VVC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHN0ZG91dDsKCgkvKioKCSAqIENhcHR1cmVkIG91dHB1dCBmcm9tIHRoZSBwcm9jZXNzJyBTVERFUlIuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRzdGRlcnI7CgoJLyoqCgkgKiBUaGUgcGF0aCBvZiB0aGUgd29ya2luZyBkaXJlY3RvcnkgZm9yIHRoZSBwcm9jZXNzIG9yIE5VTEwgaWYgbm90IHNwZWNpZmllZC4KCSAqCgkgKiBUaGlzIGRlZmF1bHRzIHRvIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuCgkgKgoJICogQHZhciBzdHJpbmd8bnVsbAoJICovCglwdWJsaWMgJGN3ZDsKCgkvKioKCSAqIEVudmlyb25tZW50IHZhcmlhYmxlcyBzZXQgZm9yIHRoaXMgcHJvY2Vzcy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXB1YmxpYyAkZW52OwoKCS8qKgoJICogRXhpdCBjb2RlIG9mIHRoZSBwcm9jZXNzLgoJICoKCSAqIEB2YXIgaW50CgkgKi8KCXB1YmxpYyAkcmV0dXJuX2NvZGU7CgoJLyoqCgkgKiBUaGUgcnVuIHRpbWUgb2YgdGhlIHByb2Nlc3MuCgkgKgoJICogQHZhciBmbG9hdAoJICovCglwdWJsaWMgJHJ1bl90aW1lOwoKCS8qKgoJICogQHBhcmFtIGFycmF5ICRwcm9wcyBQcm9wZXJ0aWVzIG9mIGV4ZWN1dGVkIGNvbW1hbmQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJHByb3BzICkgewoJCWZvcmVhY2ggKCAkcHJvcHMgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCSR0aGlzLT4ka2V5ID0gJHZhbHVlOwoJCX0KCX0KCgkvKioKCSAqIFJldHVybiBwcm9wZXJ0aWVzIG9mIGV4ZWN1dGVkIGNvbW1hbmQgYXMgYSBzdHJpbmcuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKSB7CgkJJG91dCAgPSAiJCAkdGhpcy0+Y29tbWFuZFxuIjsKCQkkb3V0IC49ICIkdGhpcy0+c3Rkb3V0XG4kdGhpcy0+c3RkZXJyIjsKCQkkb3V0IC49ICJjd2Q6ICR0aGlzLT5jd2RcbiI7CgkJJG91dCAuPSAicnVuIHRpbWU6ICR0aGlzLT5ydW5fdGltZVxuIjsKCQkkb3V0IC49ICJleGl0IHN0YXR1czogJHRoaXMtPnJldHVybl9jb2RlIjsKCgkJcmV0dXJuICRvdXQ7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRGlzcGF0Y2hlcjsKCnVzZSBDbG9zdXJlOwp1c2UgUmVmbGVjdGlvbkNsYXNzOwp1c2UgUmVmbGVjdGlvbkZ1bmN0aW9uOwp1c2UgUmVmbGVjdGlvbk1ldGhvZDsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxEb2NQYXJzZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQ3JlYXRlcyBDb21wb3NpdGVDb21tYW5kIG9yIFN1YmNvbW1hbmQgaW5zdGFuY2VzLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbW1hbmRGYWN0b3J5IHsKCgkvLyBDYWNoZSBvZiBmaWxlIGNvbnRlbnRzLCBpbmRleGVkIGJ5IGZpbGVuYW1lLiBPbmx5IHVzZWQgaWYgb3BjYWNoZS5zYXZlX2NvbW1lbnRzIGlzIGRpc2FibGVkLgoJcHJpdmF0ZSBzdGF0aWMgJGZpbGVfY29udGVudHMgPSBbXTsKCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBDb21wb3NpdGVDb21tYW5kIChvciBTdWJjb21tYW5kIGlmIGNsYXNzIGhhcyBfX2ludm9rZSgpKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgUmVwcmVzZW50cyBob3cgdGhlIGNvbW1hbmQgc2hvdWxkIGJlIGludm9rZWQKCSAqIEBwYXJhbSBzdHJpbmcgJGNhbGxhYmxlIEEgc3ViY2xhc3Mgb2YgV1BfQ0xJX0NvbW1hbmQsIGEgZnVuY3Rpb24sIG9yIGEgY2xvc3VyZQoJICogQHBhcmFtIG1peGVkICRwYXJlbnQgVGhlIG5ldyBjb21tYW5kJ3MgcGFyZW50IENvbXBvc2l0ZSAob3IgUm9vdCkgY29tbWFuZAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZSggJG5hbWUsICRjYWxsYWJsZSwgJHBhcmVudCApIHsKCgkJaWYgKCAoIGlzX29iamVjdCggJGNhbGxhYmxlICkgJiYgKCAkY2FsbGFibGUgaW5zdGFuY2VvZiBDbG9zdXJlICkgKQoJCQl8fCAoIGlzX3N0cmluZyggJGNhbGxhYmxlICkgJiYgZnVuY3Rpb25fZXhpc3RzKCAkY2FsbGFibGUgKSApICkgewoJCQkkcmVmbGVjdGlvbiA9IG5ldyBSZWZsZWN0aW9uRnVuY3Rpb24oICRjYWxsYWJsZSApOwoJCQkkY29tbWFuZCAgICA9IHNlbGY6OmNyZWF0ZV9zdWJjb21tYW5kKCAkcGFyZW50LCAkbmFtZSwgJGNhbGxhYmxlLCAkcmVmbGVjdGlvbiApOwoJCX0gZWxzZWlmICggaXNfYXJyYXkoICRjYWxsYWJsZSApICYmICggaXNfY2FsbGFibGUoICRjYWxsYWJsZSApIHx8IFV0aWxzXGlzX3ZhbGlkX2NsYXNzX2FuZF9tZXRob2RfcGFpciggJGNhbGxhYmxlICkgKSApIHsKCQkJJHJlZmxlY3Rpb24gPSBuZXcgUmVmbGVjdGlvbkNsYXNzKCAkY2FsbGFibGVbMF0gKTsKCQkJJGNvbW1hbmQgICAgPSBzZWxmOjpjcmVhdGVfc3ViY29tbWFuZCgKCQkJCSRwYXJlbnQsCgkJCQkkbmFtZSwKCQkJCVsgJGNhbGxhYmxlWzBdLCAkY2FsbGFibGVbMV0gXSwKCQkJCSRyZWZsZWN0aW9uLT5nZXRNZXRob2QoICRjYWxsYWJsZVsxXSApCgkJCSk7CgkJfSBlbHNlIHsKCQkJJHJlZmxlY3Rpb24gPSBuZXcgUmVmbGVjdGlvbkNsYXNzKCAkY2FsbGFibGUgKTsKCQkJaWYgKCAkcmVmbGVjdGlvbi0+aXNTdWJjbGFzc09mKCAnXFdQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmROYW1lc3BhY2UnICkgKSB7CgkJCQkkY29tbWFuZCA9IHNlbGY6OmNyZWF0ZV9uYW1lc3BhY2UoICRwYXJlbnQsICRuYW1lLCAkY2FsbGFibGUgKTsKCQkJfSBlbHNlaWYgKCAkcmVmbGVjdGlvbi0+aGFzTWV0aG9kKCAnX19pbnZva2UnICkgKSB7CgkJCQkkY2xhc3MgICA9IGlzX29iamVjdCggJGNhbGxhYmxlICkgPyAkY2FsbGFibGUgOiAkcmVmbGVjdGlvbi0+bmFtZTsKCQkJCSRjb21tYW5kID0gc2VsZjo6Y3JlYXRlX3N1YmNvbW1hbmQoCgkJCQkJJHBhcmVudCwKCQkJCQkkbmFtZSwKCQkJCQlbICRjbGFzcywgJ19faW52b2tlJyBdLAoJCQkJCSRyZWZsZWN0aW9uLT5nZXRNZXRob2QoICdfX2ludm9rZScgKQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCSRjb21tYW5kID0gc2VsZjo6Y3JlYXRlX2NvbXBvc2l0ZV9jb21tYW5kKCAkcGFyZW50LCAkbmFtZSwgJGNhbGxhYmxlICk7CgkJCX0KCQl9CgoJCXJldHVybiAkY29tbWFuZDsKCX0KCgkvKioKCSAqIENsZWFyIHRoZSBmaWxlIGNvbnRlbnRzIGNhY2hlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNsZWFyX2ZpbGVfY29udGVudHNfY2FjaGUoKSB7CgkJc2VsZjo6JGZpbGVfY29udGVudHMgPSBbXTsKCX0KCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBTdWJjb21tYW5kIGluc3RhbmNlLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkcGFyZW50IFRoZSBuZXcgY29tbWFuZCdzIHBhcmVudCBDb21wb3NpdGUgY29tbWFuZAoJICogQHBhcmFtIHN0cmluZ3xib29sICRuYW1lIFJlcHJlc2VudHMgaG93IHRoZSBjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkLgoJICogSWYgZmFsc2UsIHdpbGwgYmUgZGV0ZXJtaW5lZCBmcm9tIHRoZSBkb2N1bWVudGVkIHN1YmplY3QsIHJlcHJlc2VudGVkIGJ5IGAkcmVmbGVjdGlvbmAuCgkgKiBAcGFyYW0gbWl4ZWQgJGNhbGxhYmxlIEEgY2FsbGFibGUgZnVuY3Rpb24gb3IgY2xvc3VyZSwgb3IgY2xhc3MgbmFtZSBhbmQgbWV0aG9kCgkgKiBAcGFyYW0gb2JqZWN0ICRyZWZsZWN0aW9uIFJlZmxlY3Rpb24gaW5zdGFuY2UsIGZvciBkb2MgcGFyc2luZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVfc3ViY29tbWFuZCggJHBhcmVudCwgJG5hbWUsICRjYWxsYWJsZSwgJHJlZmxlY3Rpb24gKSB7CgkJJGRvY19jb21tZW50ID0gc2VsZjo6Z2V0X2RvY19jb21tZW50KCAkcmVmbGVjdGlvbiApOwoJCSRkb2NwYXJzZXIgICA9IG5ldyBEb2NQYXJzZXIoICRkb2NfY29tbWVudCApOwoKCQlpZiAoIGlzX2FycmF5KCAkY2FsbGFibGUgKSApIHsKCQkJaWYgKCAhICRuYW1lICkgewoJCQkJJG5hbWUgPSAkZG9jcGFyc2VyLT5nZXRfdGFnKCAnc3ViY29tbWFuZCcgKTsKCQkJfQoKCQkJaWYgKCAhICRuYW1lICkgewoJCQkJJG5hbWUgPSAkcmVmbGVjdGlvbi0+bmFtZTsKCQkJfQoJCX0KCQlpZiAoICEgJGRvY19jb21tZW50ICkgewoJCQlXUF9DTEk6OmRlYnVnKCBudWxsID09PSAkZG9jX2NvbW1lbnQgPyAiRmFpbGVkIHRvIGdldCBkb2MgY29tbWVudCBmb3IgeyRuYW1lfS4iIDogIk5vIGRvYyBjb21tZW50IGZvciB7JG5hbWV9LiIsICdjb21tYW5kZmFjdG9yeScgKTsKCQl9CgoJCSR3aGVuX2ludm9rZWQgPSBmdW5jdGlvbiAoICRhcmdzLCAkYXNzb2NfYXJncyApIHVzZSAoICRjYWxsYWJsZSApIHsKCQkJaWYgKCBpc19hcnJheSggJGNhbGxhYmxlICkgKSB7CgkJCQkkY2FsbGFibGVbMF0gPSBpc19vYmplY3QoICRjYWxsYWJsZVswXSApID8gJGNhbGxhYmxlWzBdIDogbmV3ICRjYWxsYWJsZVswXSgpOwoJCQkJY2FsbF91c2VyX2Z1bmMoIFsgJGNhbGxhYmxlWzBdLCAkY2FsbGFibGVbMV0gXSwgJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJCX0gZWxzZSB7CgkJCQljYWxsX3VzZXJfZnVuYyggJGNhbGxhYmxlLCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQkJfQoJCX07CgoJCXJldHVybiBuZXcgU3ViY29tbWFuZCggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIsICR3aGVuX2ludm9rZWQgKTsKCX0KCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBDb21wb3NpdGUgY29tbWFuZCBpbnN0YW5jZS4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHBhcmVudCBUaGUgbmV3IGNvbW1hbmQncyBwYXJlbnQgUm9vdCBvciBDb21wb3NpdGUgY29tbWFuZAoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBSZXByZXNlbnRzIGhvdyB0aGUgY29tbWFuZCBzaG91bGQgYmUgaW52b2tlZAoJICogQHBhcmFtIG1peGVkICRjYWxsYWJsZQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVfY29tcG9zaXRlX2NvbW1hbmQoICRwYXJlbnQsICRuYW1lLCAkY2FsbGFibGUgKSB7CgkJJHJlZmxlY3Rpb24gID0gbmV3IFJlZmxlY3Rpb25DbGFzcyggJGNhbGxhYmxlICk7CgkJJGRvY19jb21tZW50ID0gc2VsZjo6Z2V0X2RvY19jb21tZW50KCAkcmVmbGVjdGlvbiApOwoJCWlmICggISAkZG9jX2NvbW1lbnQgKSB7CgkJCVdQX0NMSTo6ZGVidWcoIG51bGwgPT09ICRkb2NfY29tbWVudCA/ICJGYWlsZWQgdG8gZ2V0IGRvYyBjb21tZW50IGZvciB7JG5hbWV9LiIgOiAiTm8gZG9jIGNvbW1lbnQgZm9yIHskbmFtZX0uIiwgJ2NvbW1hbmRmYWN0b3J5JyApOwoJCX0KCQkkZG9jcGFyc2VyID0gbmV3IERvY1BhcnNlciggJGRvY19jb21tZW50ICk7CgoJCSRjb250YWluZXIgPSBuZXcgQ29tcG9zaXRlQ29tbWFuZCggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIgKTsKCgkJZm9yZWFjaCAoICRyZWZsZWN0aW9uLT5nZXRNZXRob2RzKCkgYXMgJG1ldGhvZCApIHsKCQkJaWYgKCAhIHNlbGY6OmlzX2dvb2RfbWV0aG9kKCAkbWV0aG9kICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNsYXNzICAgICAgPSBpc19vYmplY3QoICRjYWxsYWJsZSApID8gJGNhbGxhYmxlIDogJHJlZmxlY3Rpb24tPm5hbWU7CgkJCSRzdWJjb21tYW5kID0gc2VsZjo6Y3JlYXRlX3N1YmNvbW1hbmQoICRjb250YWluZXIsIGZhbHNlLCBbICRjbGFzcywgJG1ldGhvZC0+bmFtZSBdLCAkbWV0aG9kICk7CgoJCQkkc3ViY29tbWFuZF9uYW1lID0gJHN1YmNvbW1hbmQtPmdldF9uYW1lKCk7CgoJCQkkY29udGFpbmVyLT5hZGRfc3ViY29tbWFuZCggJHN1YmNvbW1hbmRfbmFtZSwgJHN1YmNvbW1hbmQgKTsKCQl9CgoJCXJldHVybiAkY29udGFpbmVyOwoJfQoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IGNvbW1hbmQgbmFtZXNwYWNlIGluc3RhbmNlLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkcGFyZW50IFRoZSBuZXcgbmFtZXNwYWNlJ3MgcGFyZW50IFJvb3Qgb3IgQ29tcG9zaXRlIGNvbW1hbmQuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFJlcHJlc2VudHMgaG93IHRoZSBjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkCgkgKiBAcGFyYW0gbWl4ZWQgJGNhbGxhYmxlCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZV9uYW1lc3BhY2UoICRwYXJlbnQsICRuYW1lLCAkY2FsbGFibGUgKSB7CgkJJHJlZmxlY3Rpb24gID0gbmV3IFJlZmxlY3Rpb25DbGFzcyggJGNhbGxhYmxlICk7CgkJJGRvY19jb21tZW50ID0gc2VsZjo6Z2V0X2RvY19jb21tZW50KCAkcmVmbGVjdGlvbiApOwoJCWlmICggISAkZG9jX2NvbW1lbnQgKSB7CgkJCVdQX0NMSTo6ZGVidWcoIG51bGwgPT09ICRkb2NfY29tbWVudCA/ICJGYWlsZWQgdG8gZ2V0IGRvYyBjb21tZW50IGZvciB7JG5hbWV9LiIgOiAiTm8gZG9jIGNvbW1lbnQgZm9yIHskbmFtZX0uIiwgJ2NvbW1hbmRmYWN0b3J5JyApOwoJCX0KCQkkZG9jcGFyc2VyID0gbmV3IERvY1BhcnNlciggJGRvY19jb21tZW50ICk7CgoJCXJldHVybiBuZXcgQ29tbWFuZE5hbWVzcGFjZSggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIgKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYSBtZXRob2QgaXMgYWN0dWFsbHkgY2FsbGFibGUuCgkgKgoJICogQHBhcmFtIFJlZmxlY3Rpb25NZXRob2QgJG1ldGhvZAoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzX2dvb2RfbWV0aG9kKCAkbWV0aG9kICkgewoJCXJldHVybiAkbWV0aG9kLT5pc1B1YmxpYygpICYmICEgJG1ldGhvZC0+aXNTdGF0aWMoKSAmJiAwICE9PSBzdHJwb3MoICRtZXRob2QtPmdldE5hbWUoKSwgJ19fJyApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgZG9jdW1lbnQgY29tbWVudC4gQ2F0ZXJzIGZvciBQSFAgZGlyZWN0aXZlIGBvcGNhY2hlLnNhdmUgY29tbWVudHNgIGJlaW5nIGRpc2FibGVkLgoJICoKCSAqIEBwYXJhbSBSZWZsZWN0aW9uTWV0aG9kfFJlZmxlY3Rpb25DbGFzc3xSZWZsZWN0aW9uRnVuY3Rpb24gJHJlZmxlY3Rpb24gUmVmbGVjdGlvbiBpbnN0YW5jZS4KCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlfG51bGwgRG9jIGNvbW1lbnQgc3RyaW5nIGlmIGFueSwgZmFsc2UgaWYgbm9uZSAoc2FtZSBhcyBgUmVmbGVjdGlvbio6OmdldERvY0NvbW1lbnQoKWApLCBudWxsIGlmIGVycm9yLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfZG9jX2NvbW1lbnQoICRyZWZsZWN0aW9uICkgewoJCSRjb250ZW50cyAgICA9IG51bGw7CgkJJGRvY19jb21tZW50ID0gJHJlZmxlY3Rpb24tPmdldERvY0NvbW1lbnQoKTsKCgkJaWYgKCBmYWxzZSAhPT0gJGRvY19jb21tZW50IHx8ICEgKCBpbmlfZ2V0KCAnb3BjYWNoZS5lbmFibGVfY2xpJyApICYmICEgaW5pX2dldCggJ29wY2FjaGUuc2F2ZV9jb21tZW50cycgKSApICkgeyAvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5JbmlEaXJlY3RpdmVzLk5ld0luaURpcmVjdGl2ZXMKCQkJLy8gRWl0aGVyIGhhdmUgZG9jIGNvbW1lbnQsIG9yIG5vIGRvYyBjb21tZW50IGFuZCBzYXZlIGNvbW1lbnRzIGVuYWJsZWQgLSBzdGFuZGFyZCBzaXR1YXRpb24uCgkJCWlmICggISBnZXRlbnYoICdXUF9DTElfVEVTVF9HRVRfRE9DX0NPTU1FTlQnICkgKSB7CgkJCQlyZXR1cm4gJGRvY19jb21tZW50OwoJCQl9CgkJfQoKCQkkZmlsZW5hbWUgPSAkcmVmbGVjdGlvbi0+Z2V0RmlsZU5hbWUoKTsKCgkJaWYgKCBpc3NldCggc2VsZjo6JGZpbGVfY29udGVudHNbICRmaWxlbmFtZSBdICkgKSB7CgkJCSRjb250ZW50cyA9IHNlbGY6OiRmaWxlX2NvbnRlbnRzWyAkZmlsZW5hbWUgXTsKCQl9IGVsc2VpZiAoIGlzX3JlYWRhYmxlKCAkZmlsZW5hbWUgKSApIHsKCQkJJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoICRmaWxlbmFtZSApOwoJCQlpZiAoIGlzX3N0cmluZyggJGNvbnRlbnRzICkgJiYgJycgIT09ICRjb250ZW50cyApIHsKCQkJCSRjb250ZW50cyAgICAgICAgICAgICAgICAgICAgICAgICA9IGV4cGxvZGUoICJcbiIsICRjb250ZW50cyApOwoJCQkJc2VsZjo6JGZpbGVfY29udGVudHNbICRmaWxlbmFtZSBdID0gJGNvbnRlbnRzOwoJCQl9CgkJfQoKCQlpZiAoICEgZW1wdHkoICRjb250ZW50cyApICkgewoJCQlyZXR1cm4gc2VsZjo6ZXh0cmFjdF9sYXN0X2RvY19jb21tZW50KCBpbXBsb2RlKCAiXG4iLCBhcnJheV9zbGljZSggJGNvbnRlbnRzLCAwLCAkcmVmbGVjdGlvbi0+Z2V0U3RhcnRMaW5lKCkgKSApICk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAiQ291bGQgbm90IHJlYWQgY29udGVudHMgZm9yIGZpbGVuYW1lICd7JGZpbGVuYW1lfScuIiwgJ2NvbW1hbmRmYWN0b3J5JyApOwoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgbGFzdCBkb2MgY29tbWVudCBpZiBhbnkgaW4gYCRjb250ZW50YC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb250ZW50IFRoZSBjb250ZW50LCB3aGljaCBzaG91bGQgZW5kIGF0IHRoZSBjbGFzcyBvciBmdW5jdGlvbiBkZWNsYXJhdGlvbi4KCSAqIEByZXR1cm4gc3RyaW5nfGJvb2wgVGhlIGxhc3QgZG9jIGNvbW1lbnQgaWYgYW55LCBvciBmYWxzZSBpZiBub25lLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0X2xhc3RfZG9jX2NvbW1lbnQoICRjb250ZW50ICkgewoJCSRjb250ZW50ICAgICAgICAgPSB0cmltKCAkY29udGVudCApOwoJCSRjb21tZW50X2VuZF9wb3MgPSBzdHJycG9zKCAkY29udGVudCwgJyovJyApOwoJCWlmICggZmFsc2UgPT09ICRjb21tZW50X2VuZF9wb3MgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJLy8gTWFrZSBzdXJlIGNvbW1lbnQgZW5kIGJlbG9uZ3MgdG8gdGhpcyBjbGFzcy9mdW5jdGlvbi4KCQlpZiAoIHByZWdfbWF0Y2hfYWxsKCAnLyg/Ol58W1xzO31dKSg/OmNsYXNzfGZ1bmN0aW9uKVxzKy8nLCBzdWJzdHIoICRjb250ZW50LCAkY29tbWVudF9lbmRfcG9zICsgMiApLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApID4gMSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkY29udGVudCAgICAgICAgICAgPSBzdWJzdHIoICRjb250ZW50LCAwLCAkY29tbWVudF9lbmRfcG9zICsgMiApOwoJCSRjb21tZW50X3N0YXJ0X3BvcyA9IHN0cnJwb3MoICRjb250ZW50LCAnLyoqJyApOwoJCWlmICggZmFsc2UgPT09ICRjb21tZW50X3N0YXJ0X3BvcyB8fCAoICRjb21tZW50X3N0YXJ0X3BvcyArIDIgKSA9PT0gJGNvbW1lbnRfZW5kX3BvcyApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBNYWtlIHN1cmUgY29tbWVudCBzdGFydCBiZWxvbmdzIHRvIHRoaXMgY29tbWVudCBlbmQuCgkJJGNvbW1lbnRfZW5kMl9wb3MgPSBzdHJwb3MoIHN1YnN0ciggJGNvbnRlbnQsICRjb21tZW50X3N0YXJ0X3BvcyApLCAnKi8nICk7CgkJaWYgKCBmYWxzZSAhPT0gJGNvbW1lbnRfZW5kMl9wb3MgJiYgKCAkY29tbWVudF9zdGFydF9wb3MgKyAkY29tbWVudF9lbmQyX3BvcyApIDwgJGNvbW1lbnRfZW5kX3BvcyApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBBbGxvdyBmb3IgJy8qKicgd2l0aGluIGRvYyBjb21tZW50LgoJCSRzdWJjb250ZW50ID0gc3Vic3RyKCAkY29udGVudCwgMCwgJGNvbW1lbnRfc3RhcnRfcG9zICk7CgkJd2hpbGUgKCBmYWxzZSAhPT0gKCAkY29tbWVudF9zdGFydDJfcG9zID0gc3RycnBvcyggJHN1YmNvbnRlbnQsICcvKionICkgKSAmJiBmYWxzZSA9PT0gc3RycG9zKCAkc3ViY29udGVudCwgJyovJywgJGNvbW1lbnRfc3RhcnQyX3BvcyApICkgewoJCQkkY29tbWVudF9zdGFydF9wb3MgPSAkY29tbWVudF9zdGFydDJfcG9zOwoJCQkkc3ViY29udGVudCAgICAgICAgPSBzdWJzdHIoICRzdWJjb250ZW50LCAwLCAkY29tbWVudF9zdGFydF9wb3MgKTsKCQl9CgkJcmV0dXJuIHN1YnN0ciggJGNvbnRlbnQsICRjb21tZW50X3N0YXJ0X3BvcywgJGNvbW1lbnRfZW5kX3BvcyArIDIgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBBZGRzIGEgY29tbWFuZCBuYW1lc3BhY2Ugd2l0aG91dCBhY3R1YWwgZnVuY3Rpb25hbGl0eS4KICoKICogVGhpcyBpcyBtZWFudCB0byBwcm92aWRlIHRoZSBtZWFucyB0byBhdHRhY2ggbWV0YSBpbmZvcm1hdGlvbiB0byBhIG5hbWVzcGFjZQogKiB3aGVuIHRoZXJlJ3Mgbm8gYWN0dWFsIGNvbW1hbmQgbmVlZGVkLgogKgogKiBJbiBjYXNlIGEgcmVhbCBjb21tYW5kIGdldHMgcmVnaXN0ZXJlZCBmb3IgdGhlIHNhbWUgbmFtZSwgaXQgcmVwbGFjZXMgdGhlCiAqIGNvbW1hbmQgbmFtZXNwYWNlLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbW1hbmROYW1lc3BhY2UgZXh0ZW5kcyBDb21wb3NpdGVDb21tYW5kIHsKCgkvKioKCSAqIFNob3cgdGhlIHVzYWdlIGZvciBhbGwgc3ViY29tbWFuZHMgY29udGFpbmVkCgkgKiBieSB0aGUgY29tcG9zaXRlIGNvbW1hbmQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaG93X3VzYWdlKCkgewoJCSRtZXRob2RzID0gJHRoaXMtPmdldF9zdWJjb21tYW5kcygpOwoKCQkkaSAgICAgPSAwOwoJCSRjb3VudCA9IDA7CgoJCWZvcmVhY2ggKCAkbWV0aG9kcyBhcyAkc3ViY29tbWFuZCApIHsKCQkJJHByZWZpeCA9ICggMCA9PT0gJGkgKSA/ICd1c2FnZTogJyA6ICcgICBvcjogJzsKCQkJJGkrKzsKCgkJCWlmICggXFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5pc19jb21tYW5kX2Rpc2FibGVkKCAkc3ViY29tbWFuZCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCVxXUF9DTEk6OmxpbmUoICRzdWJjb21tYW5kLT5nZXRfdXNhZ2UoICRwcmVmaXggKSApOwoJCQkkY291bnQrKzsKCQl9CgoJCSRjbWRfbmFtZSA9IGltcGxvZGUoICcgJywgYXJyYXlfc2xpY2UoIGdldF9wYXRoKCAkdGhpcyApLCAxICkgKTsKCQkkbWVzc2FnZSAgPSAkY291bnQgPiAwCgkJCT8gIlNlZSAnd3AgaGVscCAkY21kX25hbWUgPGNvbW1hbmQ+JyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBhIHNwZWNpZmljIGNvbW1hbmQuIgoJCQk6ICJUaGUgbmFtZXNwYWNlICRjbWRfbmFtZSBkb2VzIG5vdCBjb250YWluIGFueSB1c2FibGUgY29tbWFuZHMgaW4gdGhlIGN1cnJlbnQgY29udGV4dC4iOwoKCQlcV1BfQ0xJOjpsaW5lKCk7CgkJXFdQX0NMSTo6bGluZSggJG1lc3NhZ2UgKTsKCgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRGlzcGF0Y2hlcjsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcRG9jUGFyc2VyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIEEgbm9uLWxlYWYgbm9kZSBpbiB0aGUgY29tbWFuZCB0cmVlLgogKiBDb250YWlucyBvbmUgb3IgbW9yZSBTdWJjb21tYW5kcy4KICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBDb21wb3NpdGVDb21tYW5kIHsKCglwcm90ZWN0ZWQgJG5hbWU7Cglwcm90ZWN0ZWQgJHNob3J0ZGVzYzsKCXByb3RlY3RlZCAkc3lub3BzaXM7Cglwcm90ZWN0ZWQgJGRvY3BhcnNlcjsKCglwcm90ZWN0ZWQgJHBhcmVudDsKCXByb3RlY3RlZCAkc3ViY29tbWFuZHMgPSBbXTsKCgkvKioKCSAqIEluc3RhbnRpYXRlIGEgbmV3IENvbXBvc2l0ZUNvbW1hbmQKCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHBhcmVudCBQYXJlbnQgY29tbWFuZCAoZWl0aGVyIFJvb3Qgb3IgQ29tcG9zaXRlKQoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBSZXByZXNlbnRzIGhvdyBjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkCgkgKiBAcGFyYW0gRG9jUGFyc2VyICRkb2NwYXJzZXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkcGFyZW50LCAkbmFtZSwgJGRvY3BhcnNlciApIHsKCQkkdGhpcy0+cGFyZW50ID0gJHBhcmVudDsKCgkJJHRoaXMtPm5hbWUgPSAkbmFtZTsKCgkJJHRoaXMtPnNob3J0ZGVzYyA9ICRkb2NwYXJzZXItPmdldF9zaG9ydGRlc2MoKTsKCQkkdGhpcy0+bG9uZ2Rlc2MgID0gJGRvY3BhcnNlci0+Z2V0X2xvbmdkZXNjKCk7CgkJJHRoaXMtPmRvY3BhcnNlciA9ICRkb2NwYXJzZXI7CgoJCSR3aGVuX3RvX2ludm9rZSA9ICRkb2NwYXJzZXItPmdldF90YWcoICd3aGVuJyApOwoJCWlmICggJHdoZW5fdG9faW52b2tlICkgewoJCQlXUF9DTEk6OmdldF9ydW5uZXIoKS0+cmVnaXN0ZXJfZWFybHlfaW52b2tlKCAkd2hlbl90b19pbnZva2UsICR0aGlzICk7CgkJfQoJfQoKCS8qKgoJICogR2V0IHRoZSBwYXJlbnQgY29tcG9zaXRlIChvciByb290KSBjb21tYW5kCgkgKgoJICogQHJldHVybiBtaXhlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3BhcmVudCgpIHsKCQlyZXR1cm4gJHRoaXMtPnBhcmVudDsKCX0KCgkvKioKCSAqIEFkZCBhIG5hbWVkIHN1YmNvbW1hbmQgdG8gdGhpcyBjb21wb3NpdGUgY29tbWFuZCdzCgkgKiBzZXQgb2YgY29udGFpbmVkIHN1YmNvbW1hbmRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgJG5hbWUgICAgIFJlcHJlc2VudHMgaG93IHN1YmNvbW1hbmQgc2hvdWxkIGJlIGludm9rZWQKCSAqIEBwYXJhbSBTdWJjb21tYW5kfENvbXBvc2l0ZUNvbW1hbmQgJGNvbW1hbmQgIEN1Yi1jb21tYW5kIHRvIGFkZC4KCSAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICAgJG92ZXJyaWRlIE9wdGlvbmFsLiBXaGV0aGVyIHRvIG92ZXJyaWRlIGFuIGV4aXN0aW5nIHN1YmNvbW1hbmQgb2YgdGhlIHNhbWUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfc3ViY29tbWFuZCggJG5hbWUsICRjb21tYW5kLCAkb3ZlcnJpZGUgPSB0cnVlICkgewoJCWlmICggJG92ZXJyaWRlIHx8ICEgYXJyYXlfa2V5X2V4aXN0cyggJG5hbWUsICR0aGlzLT5zdWJjb21tYW5kcyApICkgewoJCQkkdGhpcy0+c3ViY29tbWFuZHNbICRuYW1lIF0gPSAkY29tbWFuZDsKCQl9Cgl9CgoJLyoqCgkgKiBSZW1vdmUgYSBuYW1lZCBzdWJjb21tYW5kIGZyb20gdGhpcyBjb21wb3NpdGUgY29tbWFuZCdzIHNldCBvZiBjb250YWluZWQKCSAqIHN1YmNvbW1hbmRzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBSZXByZXNlbnRzIGhvdyBzdWJjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW1vdmVfc3ViY29tbWFuZCggJG5hbWUgKSB7CgkJaWYgKCBpc3NldCggJHRoaXMtPnN1YmNvbW1hbmRzWyAkbmFtZSBdICkgKSB7CgkJCXVuc2V0KCAkdGhpcy0+c3ViY29tbWFuZHNbICRuYW1lIF0gKTsKCQl9Cgl9CgoKCS8qKgoJICogQ29tcG9zaXRlIGNvbW1hbmRzIGFsd2F5cyBjb250YWluIHN1YmNvbW1hbmRzLgoJICoKCSAqIEByZXR1cm4gdHJ1ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gY2FuX2hhdmVfc3ViY29tbWFuZHMoKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHN1YmNvbW1hbmRzIGNvbnRhaW5lZCBieSB0aGlzIGNvbXBvc2l0ZQoJICogY29tbWFuZC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc3ViY29tbWFuZHMoKSB7CgkJa3NvcnQoICR0aGlzLT5zdWJjb21tYW5kcyApOwoKCQlyZXR1cm4gJHRoaXMtPnN1YmNvbW1hbmRzOwoJfQoKCS8qKgoJICogR2V0IHRoZSBuYW1lIG9mIHRoaXMgY29tcG9zaXRlIGNvbW1hbmQuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9uYW1lKCkgewoJCXJldHVybiAkdGhpcy0+bmFtZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgc2hvcnQgZGVzY3JpcHRpb24gZm9yIHRoaXMgY29tcG9zaXRlCgkgKiBjb21tYW5kLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc2hvcnRkZXNjKCkgewoJCXJldHVybiAkdGhpcy0+c2hvcnRkZXNjOwoJfQoKCS8qKgoJICogU2V0IHRoZSBzaG9ydCBkZXNjcmlwdGlvbiBmb3IgdGhpcyBjb21wb3NpdGUgY29tbWFuZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzaG9ydGRlc2MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldF9zaG9ydGRlc2MoICRzaG9ydGRlc2MgKSB7CgkJJHRoaXMtPnNob3J0ZGVzYyA9IFV0aWxzXG5vcm1hbGl6ZV9lb2xzKCAkc2hvcnRkZXNjICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGxvbmcgZGVzY3JpcHRpb24gZm9yIHRoaXMgY29tcG9zaXRlCgkgKiBjb21tYW5kLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfbG9uZ2Rlc2MoKSB7CgkJcmV0dXJuICR0aGlzLT5sb25nZGVzYyAuICR0aGlzLT5nZXRfZ2xvYmFsX3BhcmFtcygpOwoJfQoKCS8qKgoJICogU2V0IHRoZSBsb25nIGRlc2NyaXB0aW9uIGZvciB0aGlzIGNvbXBvc2l0ZSBjb21tYW5kCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbG9uZ2Rlc2MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldF9sb25nZGVzYyggJGxvbmdkZXNjICkgewoJCSR0aGlzLT5sb25nZGVzYyA9IFV0aWxzXG5vcm1hbGl6ZV9lb2xzKCAkbG9uZ2Rlc2MgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgc3lub3BzaXMgZm9yIHRoaXMgY29tcG9zaXRlIGNvbW1hbmQuCgkgKiBBcyBhIGNvbGxlY3Rpb24gb2Ygc3ViY29tbWFuZHMsIHRoZSBjb21wb3NpdGUKCSAqIGNvbW1hbmQgaXMgb25seSBpbnRlbmRlZCB0byBpbnZva2UgdGhvc2UKCSAqIHN1YmNvbW1hbmRzLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc3lub3BzaXMoKSB7CgkJcmV0dXJuICc8Y29tbWFuZD4nOwoJfQoKCS8qKgoJICogR2V0IHRoZSB1c2FnZSBmb3IgdGhpcyBjb21wb3NpdGUgY29tbWFuZC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3VzYWdlKCAkcHJlZml4ICkgewoJCXJldHVybiBzcHJpbnRmKAoJCQknJXMlcyAlcycsCgkJCSRwcmVmaXgsCgkJCWltcGxvZGUoICcgJywgZ2V0X3BhdGgoICR0aGlzICkgKSwKCQkJJHRoaXMtPmdldF9zeW5vcHNpcygpCgkJKTsKCX0KCgkvKioKCSAqIFNob3cgdGhlIHVzYWdlIGZvciBhbGwgc3ViY29tbWFuZHMgY29udGFpbmVkCgkgKiBieSB0aGUgY29tcG9zaXRlIGNvbW1hbmQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaG93X3VzYWdlKCkgewoJCSRtZXRob2RzID0gJHRoaXMtPmdldF9zdWJjb21tYW5kcygpOwoKCQkkaSA9IDA7CgoJCWZvcmVhY2ggKCAkbWV0aG9kcyBhcyAkc3ViY29tbWFuZCApIHsKCQkJJHByZWZpeCA9ICggMCA9PT0gJGkgKSA/ICd1c2FnZTogJyA6ICcgICBvcjogJzsKCQkJJGkrKzsKCgkJCWlmICggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmlzX2NvbW1hbmRfZGlzYWJsZWQoICRzdWJjb21tYW5kICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJV1BfQ0xJOjpsaW5lKCAkc3ViY29tbWFuZC0+Z2V0X3VzYWdlKCAkcHJlZml4ICkgKTsKCQl9CgoJCSRjbWRfbmFtZSA9IGltcGxvZGUoICcgJywgYXJyYXlfc2xpY2UoIGdldF9wYXRoKCAkdGhpcyApLCAxICkgKTsKCgkJV1BfQ0xJOjpsaW5lKCk7CgkJV1BfQ0xJOjpsaW5lKCAiU2VlICd3cCBoZWxwICRjbWRfbmFtZSA8Y29tbWFuZD4nIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGEgc3BlY2lmaWMgY29tbWFuZC4iICk7Cgl9CgoJLyoqCgkgKiBXaGVuIGEgY29tcG9zaXRlIGNvbW1hbmQgaXMgaW52b2tlZCwgaXQgc2hvd3MgdXNhZ2UKCSAqIGRvY3MgZm9yIGl0cyBzdWJjb21tYW5kcy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncwoJICogQHBhcmFtIGFycmF5ICRleHRyYV9hcmdzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncywgJGV4dHJhX2FyZ3MgKSB7CgkJJHRoaXMtPnNob3dfdXNhZ2UoKTsKCX0KCgkvKioKCSAqIEdpdmVuIHN1cHBsaWVkIGFyZ3VtZW50cywgZmluZCBhIGNvbnRhaW5lZAoJICogc3ViY29tbWFuZAoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncwoJICogQHJldHVybiBTdWJjb21tYW5kfGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmaW5kX3N1YmNvbW1hbmQoICYkYXJncyApIHsKCQkkbmFtZSA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCQkkc3ViY29tbWFuZHMgPSAkdGhpcy0+Z2V0X3N1YmNvbW1hbmRzKCk7CgoJCWlmICggISBpc3NldCggJHN1YmNvbW1hbmRzWyAkbmFtZSBdICkgKSB7CgkJCSRhbGlhc2VzID0gc2VsZjo6Z2V0X2FsaWFzZXMoICRzdWJjb21tYW5kcyApOwoKCQkJaWYgKCBpc3NldCggJGFsaWFzZXNbICRuYW1lIF0gKSApIHsKCQkJCSRuYW1lID0gJGFsaWFzZXNbICRuYW1lIF07CgkJCX0KCQl9CgoJCWlmICggISBpc3NldCggJHN1YmNvbW1hbmRzWyAkbmFtZSBdICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkc3ViY29tbWFuZHNbICRuYW1lIF07Cgl9CgoJLyoqCgkgKiBHZXQgYW55IHJlZ2lzdGVyZWQgYWxpYXNlcyBmb3IgdGhpcyBjb21wb3NpdGUgY29tbWFuZCdzCgkgKiBzdWJjb21tYW5kcy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHN1YmNvbW1hbmRzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9hbGlhc2VzKCAkc3ViY29tbWFuZHMgKSB7CgkJJGFsaWFzZXMgPSBbXTsKCgkJZm9yZWFjaCAoICRzdWJjb21tYW5kcyBhcyAkbmFtZSA9PiAkc3ViY29tbWFuZCApIHsKCQkJJGFsaWFzID0gJHN1YmNvbW1hbmQtPmdldF9hbGlhcygpOwoJCQlpZiAoICRhbGlhcyApIHsKCQkJCSRhbGlhc2VzWyAkYWxpYXMgXSA9ICRuYW1lOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGFsaWFzZXM7Cgl9CgoJLyoqCgkgKiBDb21wb3NpdGUgY29tbWFuZHMgY2FuIG9ubHkgYmUga25vd24gYnkgb25lIG5hbWUuCgkgKgoJICogQHJldHVybiBmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2FsaWFzKCkgewoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioqCgkgKiBHZXQgdGhlIGxpc3Qgb2YgZ2xvYmFsIHBhcmFtZXRlcnMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRyb290X2NvbW1hbmQgd2hldGhlciB0byBpbmNsdWRlIG9yIG5vdCByb290IGNvbW1hbmQgc3BlY2lmaWMgZGVzY3JpcHRpb24KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZ2xvYmFsX3BhcmFtcyggJHJvb3RfY29tbWFuZCA9IGZhbHNlICkgewoJCSRiaW5kaW5nICAgICAgICAgICAgICAgICA9IFtdOwoJCSRiaW5kaW5nWydyb290X2NvbW1hbmQnXSA9ICRyb290X2NvbW1hbmQ7CgoJCWlmICggISAkdGhpcy0+Y2FuX2hhdmVfc3ViY29tbWFuZHMoKSB8fCAoIGlzX29iamVjdCggJHRoaXMtPnBhcmVudCApICYmIGdldF9jbGFzcyggJHRoaXMtPnBhcmVudCApID09PSAnV1BfQ0xJXERpc3BhdGNoZXJcQ29tcG9zaXRlQ29tbWFuZCcgKSApIHsKCQkJJGJpbmRpbmdbJ2lzX3N1YmNvbW1hbmQnXSA9IHRydWU7CgkJfQoKCQlmb3JlYWNoICggV1BfQ0xJOjpnZXRfY29uZmlndXJhdG9yKCktPmdldF9zcGVjKCkgYXMgJGtleSA9PiAkZGV0YWlscyApIHsKCQkJaWYgKCBmYWxzZSA9PT0gJGRldGFpbHNbJ3J1bnRpbWUnXSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoIGlzc2V0KCAkZGV0YWlsc1snZGVwcmVjYXRlZCddICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCBpc3NldCggJGRldGFpbHNbJ2hpZGRlbiddICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCB0cnVlID09PSAkZGV0YWlsc1sncnVudGltZSddICkgewoJCQkJJHN5bm9wc2lzID0gIi0tW25vLV0ka2V5IjsKCQkJfSBlbHNlIHsKCQkJCSRzeW5vcHNpcyA9ICItLSRrZXkiIC4gJGRldGFpbHNbJ3J1bnRpbWUnXTsKCQkJfQoKCQkJLy8gQ2hlY2sgaWYgZ2xvYmFsIHBhcmFtZXRlcnMgc3lub3BzaXMgc2hvdWxkIGJlIGRpc3BsYXllZCBvciBub3QuCgkJCWlmICggJ3RydWUnICE9PSBnZXRlbnYoICdXUF9DTElfU1VQUFJFU1NfR0xPQkFMX1BBUkFNUycgKSApIHsKCQkJCSRiaW5kaW5nWydwYXJhbWV0ZXJzJ11bXSAgID0gWwoJCQkJCSdzeW5vcHNpcycgPT4gJHN5bm9wc2lzLAoJCQkJCSdkZXNjJyAgICAgPT4gJGRldGFpbHNbJ2Rlc2MnXSwKCQkJCV07CgkJCQkkYmluZGluZ1snaGFzX3BhcmFtZXRlcnMnXSA9IHRydWU7CgkJCX0KCQl9CgoJCWlmICggJHRoaXMtPmdldF9zdWJjb21tYW5kcygpICkgewoJCQkkYmluZGluZ1snaGFzX3N1YmNvbW1hbmRzJ10gPSB0cnVlOwoJCX0KCgkJcmV0dXJuIFV0aWxzXG11c3RhY2hlX3JlbmRlciggJ21hbi1wYXJhbXMubXVzdGFjaGUnLCAkYmluZGluZyApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXERpc3BhdGNoZXI7Cgp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIFRoZSByb290IG5vZGUgaW4gdGhlIGNvbW1hbmQgdHJlZS4KICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBSb290Q29tbWFuZCBleHRlbmRzIENvbXBvc2l0ZUNvbW1hbmQgewoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQkkdGhpcy0+cGFyZW50ID0gZmFsc2U7CgoJCSR0aGlzLT5uYW1lID0gJ3dwJzsKCgkJJHRoaXMtPnNob3J0ZGVzYyA9ICdNYW5hZ2UgV29yZFByZXNzIHRocm91Z2ggdGhlIGNvbW1hbmQtbGluZS4nOwoJfQoKCS8qKgoJICogR2V0IHRoZSBodW1hbi1yZWFkYWJsZSBsb25nIGRlc2NyaXB0aW9uLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfbG9uZ2Rlc2MoKSB7CgkJcmV0dXJuICR0aGlzLT5nZXRfZ2xvYmFsX3BhcmFtcyggdHJ1ZSApOwoJfQoKCS8qKgoJICogRmluZCBhIHN1YmNvbW1hbmQgcmVnaXN0ZXJlZCBvbiB0aGUgcm9vdAoJICogY29tbWFuZC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEByZXR1cm4gU3ViY29tbWFuZHxmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZmluZF9zdWJjb21tYW5kKCAmJGFyZ3MgKSB7CgkJJGNvbW1hbmQgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJVXRpbHNcbG9hZF9jb21tYW5kKCAkY29tbWFuZCApOwoKCQlpZiAoICEgaXNzZXQoICR0aGlzLT5zdWJjb21tYW5kc1sgJGNvbW1hbmQgXSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPnN1YmNvbW1hbmRzWyAkY29tbWFuZCBdOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXERpc3BhdGNoZXI7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXERvY1BhcnNlcjsKdXNlIFdQX0NMSVxTeW5vcHNpc1BhcnNlcjsKdXNlIFdQX0NMSVxTeW5vcHNpc1ZhbGlkYXRvcjsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBBIGxlYWYgbm9kZSBpbiB0aGUgY29tbWFuZCB0cmVlLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIFN1YmNvbW1hbmQgZXh0ZW5kcyBDb21wb3NpdGVDb21tYW5kIHsKCglwcml2YXRlICRhbGlhczsKCglwcml2YXRlICR3aGVuX2ludm9rZWQ7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkcGFyZW50LCAkbmFtZSwgJGRvY3BhcnNlciwgJHdoZW5faW52b2tlZCApIHsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCAkcGFyZW50LCAkbmFtZSwgJGRvY3BhcnNlciApOwoKCQkkdGhpcy0+d2hlbl9pbnZva2VkID0gJHdoZW5faW52b2tlZDsKCgkJJHRoaXMtPmFsaWFzID0gJGRvY3BhcnNlci0+Z2V0X3RhZyggJ2FsaWFzJyApOwoKCQkkdGhpcy0+c3lub3BzaXMgPSAkZG9jcGFyc2VyLT5nZXRfc3lub3BzaXMoKTsKCQlpZiAoICEgJHRoaXMtPnN5bm9wc2lzICYmICR0aGlzLT5sb25nZGVzYyApIHsKCQkJJHRoaXMtPnN5bm9wc2lzID0gc2VsZjo6ZXh0cmFjdF9zeW5vcHNpcyggJHRoaXMtPmxvbmdkZXNjICk7CgkJfQoJfQoKCS8qKgoJICogRXh0cmFjdCB0aGUgc3lub3BzaXMgZnJvbSBQSFBkb2Mgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGxvbmdkZXNjIENvbW1hbmQgZG9jcyB2aWEgUEhQZG9jCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0X3N5bm9wc2lzKCAkbG9uZ2Rlc2MgKSB7CgkJcHJlZ19tYXRjaF9hbGwoICcvKC4rPylbXHJcbl0rOi8nLCAkbG9uZ2Rlc2MsICRtYXRjaGVzICk7CgkJcmV0dXJuIGltcGxvZGUoICcgJywgJG1hdGNoZXNbMV0gKTsKCX0KCgkvKioKCSAqIFN1YmNvbW1hbmRzIGNhbid0IGhhdmUgc3ViY29tbWFuZHMgYmVjYXVzZSB0aGV5CgkgKiByZXByZXNlbnQgY29kZSB0byBiZSBleGVjdXRlZC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgewoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgc3lub3BzaXMgc3RyaW5nIGZvciB0aGlzIHN1YmNvbW1hbmQuCgkgKiBBIHN5bm9wc2lzIGRlZmluZXMgd2hhdCBydW50aW1lIGFyZ3VtZW50cyBhcmUKCSAqIGV4cGVjdGVkLCB1c2VmdWwgdG8gaHVtYW5zIGFuZCBhcmd1bWVudCB2YWxpZGF0aW9uLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc3lub3BzaXMoKSB7CgkJcmV0dXJuICR0aGlzLT5zeW5vcHNpczsKCX0KCgkvKioKCSAqIFNldCB0aGUgc3lub3BzaXMgc3RyaW5nIGZvciB0aGlzIHN1YmNvbW1hbmQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3lub3BzaXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldF9zeW5vcHNpcyggJHN5bm9wc2lzICkgewoJCSR0aGlzLT5zeW5vcHNpcyA9ICRzeW5vcHNpczsKCX0KCgkvKioKCSAqIElmIGFuIGFsaWFzIGlzIHNldCwgZ3JhbnQgYWNjZXNzIHRvIGl0LgoJICogQWxpYXNlcyBwZXJtaXQgc3ViY29tbWFuZHMgdG8gYmUgaW5zdGFudGlhdGVkCgkgKiB3aXRoIGEgc2Vjb25kYXJ5IGlkZW50aXR5LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfYWxpYXMoKSB7CgkJcmV0dXJuICR0aGlzLT5hbGlhczsKCX0KCgkvKioKCSAqIFByaW50IHRoZSB1c2FnZSBkZXRhaWxzIHRvIHRoZSBlbmQgdXNlci4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwcmVmaXgKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNob3dfdXNhZ2UoICRwcmVmaXggPSAndXNhZ2U6ICcgKSB7CgkJXFdQX0NMSTo6bGluZSggJHRoaXMtPmdldF91c2FnZSggJHByZWZpeCApICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHVzYWdlIG9mIHRoZSBzdWJjb21tYW5kIGFzIGEgZm9ybWF0dGVkIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwcmVmaXgKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfdXNhZ2UoICRwcmVmaXggKSB7CgkJcmV0dXJuIHNwcmludGYoCgkJCSclcyVzICVzJywKCQkJJHByZWZpeCwKCQkJaW1wbG9kZSggJyAnLCBnZXRfcGF0aCggJHRoaXMgKSApLAoJCQkkdGhpcy0+Z2V0X3N5bm9wc2lzKCkKCQkpOwoJfQoKCS8qKgoJICogV3JhcHBlciBmb3IgQ0xJIFRvb2xzJyBwcm9tcHQoKSBtZXRob2QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24KCSAqIEBwYXJhbSBzdHJpbmcgJGRlZmF1bHQKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcHJvbXB0KCAkcXVlc3Rpb24sICRkZWZhdWx0ICkgewoKCQkkcXVlc3Rpb24gLj0gJzogJzsKCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ3JlYWRsaW5lJyApICkgewoJCQlyZXR1cm4gcmVhZGxpbmUoICRxdWVzdGlvbiApOwoJCX0KCgkJZWNobyAkcXVlc3Rpb247CgoJCSRyZXQgPSBzdHJlYW1fZ2V0X2xpbmUoIFNURElOLCAxMDI0LCAiXG4iICk7CgkJaWYgKCBVdGlsc1xpc193aW5kb3dzKCkgJiYgIlxyIiA9PT0gc3Vic3RyKCAkcmV0LCAtMSApICkgewoJCQkkcmV0ID0gc3Vic3RyKCAkcmV0LCAwLCAtMSApOwoJCX0KCQlyZXR1cm4gJHJldDsKCX0KCgkvKioKCSAqIEludGVyYWN0aXZlbHkgcHJvbXB0IHRoZSB1c2VyIGZvciBpbnB1dAoJICogYmFzZWQgb24gZGVmaW5lZCBzeW5vcHNpcyBhbmQgcGFzc2VkIGFyZ3VtZW50cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncwoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIHByb21wdF9hcmdzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRzeW5vcHNpcyA9ICR0aGlzLT5nZXRfc3lub3BzaXMoKTsKCgkJaWYgKCAhICRzeW5vcHNpcyApIHsKCQkJcmV0dXJuIFsgJGFyZ3MsICRhc3NvY19hcmdzIF07CgkJfQoKCQkvLyBUbyBza2lwIHRoZSBhbHJlYWR5IHByb3ZpZGVkIHBvc2l0aW9uYWwgYXJndW1lbnRzLCB3ZSBuZWVkIHRvIGNvdW50CgkJLy8gaG93IG1hbnkgd2UgaGFkIGFscmVhZHkgcmVjZWl2ZWQuCgkJJGFyZ19pbmRleCA9IDA7CgoJCSRzcGVjID0gYXJyYXlfZmlsdGVyKAoJCQlTeW5vcHNpc1BhcnNlcjo6cGFyc2UoICRzeW5vcHNpcyApLAoJCQlmdW5jdGlvbiggJHNwZWNfYXJnICkgdXNlICggJGFyZ3MsICRhc3NvY19hcmdzLCAmJGFyZ19pbmRleCApIHsKCQkJCXN3aXRjaCAoICRzcGVjX2FyZ1sndHlwZSddICkgewoJCQkJCWNhc2UgJ3Bvc2l0aW9uYWwnOgoJCQkJCQkvLyBPbmx5IHByb21wdCBmb3IgdGhlIHBvc2l0aW9uYWwgYXJndW1lbnRzIHRoYXQgYXJlIG5vdAoJCQkJCQkvLyB5ZXQgcHJvdmlkZWQsIGJhc2VkIHB1cmVseSBvbiBudW1iZXIuCgkJCQkJCXJldHVybiAkYXJnX2luZGV4KysgPj0gY291bnQoICRhcmdzICk7CgkJCQkJY2FzZSAnZ2VuZXJpYyc6CgkJCQkJCS8vIEFsd2F5cyBwcm9tcHQgZm9yIGdlbmVyaWMgYXJndW1lbnRzLgoJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQljYXNlICdhc3NvYyc6CgkJCQkJY2FzZSAnZmxhZyc6CgkJCQkJZGVmYXVsdDoKCQkJCQkJLy8gUHJvbXB0IGZvciB0aGUgc3BlY2lmaWMgZmxhZ3MgdGhhdCB3ZXJlIG5vdCBwcm92aWRlZAoJCQkJCQkvLyB5ZXQsIGJhc2VkIG9uIG5hbWUuCgkJCQkJCXJldHVybiAhIGlzc2V0KCAkYXNzb2NfYXJnc1sgJHNwZWNfYXJnWyduYW1lJ10gXSApOwoJCQkJfQoJCQl9CgkJKTsKCgkJJHNwZWMgPSBhcnJheV92YWx1ZXMoICRzcGVjICk7CgoJCSRwcm9tcHRfYXJncyA9IFdQX0NMSTo6Z2V0X2NvbmZpZyggJ3Byb21wdCcgKTsKCQlpZiAoIHRydWUgIT09ICRwcm9tcHRfYXJncyApIHsKCQkJJHByb21wdF9hcmdzID0gZXhwbG9kZSggJywnLCAkcHJvbXB0X2FyZ3MgKTsKCQl9CgoJCS8vICdwb3NpdGlvbmFsJyBhcmd1bWVudHMgYXJlIHBvc2l0aW9uYWwgKGFrYSB6ZXJvLWluZGV4ZWQpCgkJLy8gc28gJGFyZ3MgbmVlZHMgdG8gYmUgcmVzZXQgYmVmb3JlIHByb21wdGluZyBmb3IgbmV3IGFyZ3VtZW50cwoJCSRhcmdzID0gW107CgoJCWZvcmVhY2ggKCAkc3BlYyBhcyAka2V5ID0+ICRzcGVjX2FyZyApIHsKCgkJCS8vIFdoZW4gcHJvbXB0aW5nIGZvciBzcGVjaWZpYyBhcmd1bWVudHMgKGUuZy4gLS1wcm9tcHQ9dXNlcl9wYXNzKSwKCQkJLy8gaWdub3JlIGFsbCBhcmd1bWVudHMgdGhhdCBkb24ndCBtYXRjaC4KCQkJaWYgKCBpc19hcnJheSggJHByb21wdF9hcmdzICkgKSB7CgkJCQlpZiAoICdhc3NvYycgIT09ICRzcGVjX2FyZ1sndHlwZSddICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJaWYgKCAhIGluX2FycmF5KCAkc3BlY19hcmdbJ25hbWUnXSwgJHByb21wdF9hcmdzLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCX0KCgkJCSRjdXJyZW50X3Byb21wdCA9ICggJGtleSArIDEgKSAuICcvJyAuIGNvdW50KCAkc3BlYyApIC4gJyAnOwoJCQkkZGVmYXVsdCAgICAgICAgPSAkc3BlY19hcmdbJ29wdGlvbmFsJ10gPyAnJyA6IGZhbHNlOwoKCQkJLy8gJ2dlbmVyaWMnIHBlcm1pdHMgYXJiaXRyYXJ5IGtleT12YWx1ZSAoZS5nLiBbLS08ZmllbGQ+PTx2YWx1ZT5dICkKCQkJaWYgKCAnZ2VuZXJpYycgPT09ICRzcGVjX2FyZ1sndHlwZSddICkgewoKCQkJCWxpc3QoICRrZXlfdG9rZW4sICR2YWx1ZV90b2tlbiApID0gZXhwbG9kZSggJz0nLCAkc3BlY19hcmdbJ3Rva2VuJ10gKTsKCgkJCQkkcmVwZWF0ID0gZmFsc2U7CgkJCQlkbyB7CgkJCQkJaWYgKCAhICRyZXBlYXQgKSB7CgkJCQkJCSRrZXlfcHJvbXB0ID0gJGN1cnJlbnRfcHJvbXB0IC4gJGtleV90b2tlbjsKCQkJCQl9IGVsc2UgewoJCQkJCQkka2V5X3Byb21wdCA9IHN0cl9yZXBlYXQoICcgJywgc3RybGVuKCAkY3VycmVudF9wcm9tcHQgKSApIC4gJGtleV90b2tlbjsKCQkJCQl9CgoJCQkJCSRrZXkgPSAkdGhpcy0+cHJvbXB0KCAka2V5X3Byb21wdCwgJGRlZmF1bHQgKTsKCQkJCQlpZiAoIGZhbHNlID09PSAka2V5ICkgewoJCQkJCQlyZXR1cm4gWyAkYXJncywgJGFzc29jX2FyZ3MgXTsKCQkJCQl9CgoJCQkJCWlmICggJGtleSApIHsKCQkJCQkJJGtleV9wcm9tcHRfY291bnQgPSBzdHJsZW4oICRrZXlfcHJvbXB0ICkgLSBzdHJsZW4oICR2YWx1ZV90b2tlbiApIC0gMTsKCQkJCQkJJHZhbHVlX3Byb21wdCAgICAgPSBzdHJfcmVwZWF0KCAnICcsICRrZXlfcHJvbXB0X2NvdW50ICkgLiAnPScgLiAkdmFsdWVfdG9rZW47CgoJCQkJCQkkdmFsdWUgPSAkdGhpcy0+cHJvbXB0KCAkdmFsdWVfcHJvbXB0LCAkZGVmYXVsdCApOwoJCQkJCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCQkJCQlyZXR1cm4gWyAkYXJncywgJGFzc29jX2FyZ3MgXTsKCQkJCQkJfQoKCQkJCQkJJGFzc29jX2FyZ3NbICRrZXkgXSA9ICR2YWx1ZTsKCgkJCQkJCSRyZXBlYXQgPSB0cnVlOwoJCQkJCX0gZWxzZSB7CgkJCQkJCSRyZXBlYXQgPSBmYWxzZTsKCQkJCQl9CgkJCQl9IHdoaWxlICggJHJlcGVhdCApOwoKCQkJfSBlbHNlIHsKCQkJCSRwcm9tcHQgPSAkY3VycmVudF9wcm9tcHQgLiAkc3BlY19hcmdbJ3Rva2VuJ107CgkJCQlpZiAoICdmbGFnJyA9PT0gJHNwZWNfYXJnWyd0eXBlJ10gKSB7CgkJCQkJJHByb21wdCAuPSAnIChZL24pJzsKCQkJCX0KCgkJCQkkcmVzcG9uc2UgPSAkdGhpcy0+cHJvbXB0KCAkcHJvbXB0LCAkZGVmYXVsdCApOwoJCQkJaWYgKCBmYWxzZSA9PT0gJHJlc3BvbnNlICkgewoJCQkJCXJldHVybiBbICRhcmdzLCAkYXNzb2NfYXJncyBdOwoJCQkJfQoKCQkJCWlmICggJHJlc3BvbnNlICkgewoJCQkJCXN3aXRjaCAoICRzcGVjX2FyZ1sndHlwZSddICkgewoJCQkJCQljYXNlICdwb3NpdGlvbmFsJzoKCQkJCQkJCWlmICggJHNwZWNfYXJnWydyZXBlYXRpbmcnXSApIHsKCQkJCQkJCQkkcmVzcG9uc2UgPSBleHBsb2RlKCAnICcsICRyZXNwb25zZSApOwoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkkcmVzcG9uc2UgPSBbICRyZXNwb25zZSBdOwoJCQkJCQkJfQoJCQkJCQkJJGFyZ3MgPSBhcnJheV9tZXJnZSggJGFyZ3MsICRyZXNwb25zZSApOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2Fzc29jJzoKCQkJCQkJCSRhc3NvY19hcmdzWyAkc3BlY19hcmdbJ25hbWUnXSBdID0gJHJlc3BvbnNlOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2ZsYWcnOgoJCQkJCQkJaWYgKCAnWScgPT09IHN0cnRvdXBwZXIoICRyZXNwb25zZSApICkgewoJCQkJCQkJCSRhc3NvY19hcmdzWyAkc3BlY19hcmdbJ25hbWUnXSBdID0gdHJ1ZTsKCQkJCQkJCX0KCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIFsgJGFyZ3MsICRhc3NvY19hcmdzIF07Cgl9CgoJLyoqCgkgKiBWYWxpZGF0ZSB0aGUgc3VwcGxpZWQgYXJndW1lbnRzIHRvIHRoZSBjb21tYW5kLgoJICogVGhyb3dzIHdhcm5pbmdzIG9yIGVycm9ycyBpZiBhcmd1bWVudHMgYXJlIG1pc3NpbmcKCSAqIG9yIGludmFsaWQuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqIEBwYXJhbSBhcnJheSAkZXh0cmFfYXJncwoJICogQHJldHVybiBhcnJheSBsaXN0IG9mIGludmFsaWQgJGFzc29jX2FyZ3Mga2V5cyB0byB1bnNldAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlX2FyZ3MoICRhcmdzLCAkYXNzb2NfYXJncywgJGV4dHJhX2FyZ3MgKSB7CgkJJHN5bm9wc2lzID0gJHRoaXMtPmdldF9zeW5vcHNpcygpOwoJCWlmICggISAkc3lub3BzaXMgKSB7CgkJCXJldHVybiBbIFtdLCAkYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzIF07CgkJfQoKCQkkdmFsaWRhdG9yID0gbmV3IFN5bm9wc2lzVmFsaWRhdG9yKCAkc3lub3BzaXMgKTsKCgkJJGNtZF9wYXRoID0gaW1wbG9kZSggJyAnLCBnZXRfcGF0aCggJHRoaXMgKSApOwoJCWZvcmVhY2ggKCAkdmFsaWRhdG9yLT5nZXRfdW5rbm93bigpIGFzICR0b2tlbiApIHsKCQkJXFdQX0NMSTo6d2FybmluZygKCQkJCXNwcmludGYoCgkJCQkJJ1RoZSBgJXNgIGNvbW1hbmQgaGFzIGFuIGludmFsaWQgc3lub3BzaXMgcGFydDogJXMnLAoJCQkJCSRjbWRfcGF0aCwKCQkJCQkkdG9rZW4KCQkJCSkKCQkJKTsKCQl9CgoJCWlmICggISAkdmFsaWRhdG9yLT5lbm91Z2hfcG9zaXRpb25hbHMoICRhcmdzICkgKSB7CgkJCSR0aGlzLT5zaG93X3VzYWdlKCk7CgkJCWV4aXQoIDEgKTsKCQl9CgoJCSR1bmtub3duX3Bvc2l0aW9uYWxzID0gJHZhbGlkYXRvci0+dW5rbm93bl9wb3NpdGlvbmFscyggJGFyZ3MgKTsKCQlpZiAoICEgZW1wdHkoICR1bmtub3duX3Bvc2l0aW9uYWxzICkgKSB7CgkJCVxXUF9DTEk6OmVycm9yKAoJCQkJJ1RvbyBtYW55IHBvc2l0aW9uYWwgYXJndW1lbnRzOiAnIC4KCQkJCWltcGxvZGUoICcgJywgJHVua25vd25fcG9zaXRpb25hbHMgKQoJCQkpOwoJCX0KCgkJJHN5bm9wc2lzX3NwZWMgPSBTeW5vcHNpc1BhcnNlcjo6cGFyc2UoICRzeW5vcHNpcyApOwoJCSRpICAgICAgICAgICAgID0gMDsKCQkkZXJyb3JzICAgICAgICA9IFsKCQkJJ2ZhdGFsJyAgID0+IFtdLAoJCQknd2FybmluZycgPT4gW10sCgkJXTsKCQkkbW9ja19kb2MgICAgICA9IFsgJHRoaXMtPmdldF9zaG9ydGRlc2MoKSwgJycgXTsKCQkkbW9ja19kb2MgICAgICA9IGFycmF5X21lcmdlKCAkbW9ja19kb2MsIGV4cGxvZGUoICJcbiIsICR0aGlzLT5nZXRfbG9uZ2Rlc2MoKSApICk7CgkJJG1vY2tfZG9jICAgICAgPSAnLyoqJyAuIFBIUF9FT0wgLiAnKiAnIC4gaW1wbG9kZSggUEhQX0VPTCAuICcqICcsICRtb2NrX2RvYyApIC4gUEhQX0VPTCAuICcqLyc7CgkJJGRvY3BhcnNlciAgICAgPSBuZXcgRG9jUGFyc2VyKCAkbW9ja19kb2MgKTsKCQlmb3JlYWNoICggJHN5bm9wc2lzX3NwZWMgYXMgJHNwZWMgKSB7CgkJCWlmICggJ3Bvc2l0aW9uYWwnID09PSAkc3BlY1sndHlwZSddICkgewoJCQkJJHNwZWNfYXJncyA9ICRkb2NwYXJzZXItPmdldF9hcmdfYXJncyggJHNwZWNbJ25hbWUnXSApOwoJCQkJaWYgKCAhIGlzc2V0KCAkYXJnc1sgJGkgXSApICkgewoJCQkJCWlmICggaXNzZXQoICRzcGVjX2FyZ3NbJ2RlZmF1bHQnXSApICkgewoJCQkJCQkkYXJnc1sgJGkgXSA9ICRzcGVjX2FyZ3NbJ2RlZmF1bHQnXTsKCQkJCQl9CgkJCQl9CgkJCQlpZiAoIGlzc2V0KCAkc3BlY19hcmdzWydvcHRpb25zJ10gKSApIHsKCQkJCQlpZiAoICEgZW1wdHkoICRzcGVjWydyZXBlYXRpbmcnXSApICkgewoJCQkJCQlkbyB7CgkJCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5TdHJpY3RJbkFycmF5Lk1pc3NpbmdUcnVlU3RyaWN0IC0tIFRoaXMgaXMgYSBsb29zZSBjb21wYXJpc29uIGJ5IGRlc2lnbi4KCQkJCQkJCWlmICggaXNzZXQoICRhcmdzWyAkaSBdICkgJiYgISBpbl9hcnJheSggJGFyZ3NbICRpIF0sICRzcGVjX2FyZ3NbJ29wdGlvbnMnXSApICkgewoJCQkJCQkJCVxXUF9DTEk6OmVycm9yKCAnSW52YWxpZCB2YWx1ZSBzcGVjaWZpZWQgZm9yIHBvc2l0aW9uYWwgYXJnLicgKTsKCQkJCQkJCX0KCQkJCQkJCSRpKys7CgkJCQkJCX0gd2hpbGUgKCBpc3NldCggJGFyZ3NbICRpIF0gKSApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuUEhQLlN0cmljdEluQXJyYXkuTWlzc2luZ1RydWVTdHJpY3QgLS0gVGhpcyBpcyBhIGxvb3NlIGNvbXBhcmlzb24gYnkgZGVzaWduLgoJCQkJCQlpZiAoIGlzc2V0KCAkYXJnc1sgJGkgXSApICYmICEgaW5fYXJyYXkoICRhcmdzWyAkaSBdLCAkc3BlY19hcmdzWydvcHRpb25zJ10gKSApIHsKCQkJCQkJCVxXUF9DTEk6OmVycm9yKCAnSW52YWxpZCB2YWx1ZSBzcGVjaWZpZWQgZm9yIHBvc2l0aW9uYWwgYXJnLicgKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCSRpKys7CgkJCX0gZWxzZWlmICggJ2Fzc29jJyA9PT0gJHNwZWNbJ3R5cGUnXSApIHsKCQkJCSRzcGVjX2FyZ3MgPSAkZG9jcGFyc2VyLT5nZXRfcGFyYW1fYXJncyggJHNwZWNbJ25hbWUnXSApOwoJCQkJaWYgKCAhIGlzc2V0KCAkYXNzb2NfYXJnc1sgJHNwZWNbJ25hbWUnXSBdICkgJiYgISBpc3NldCggJGV4dHJhX2FyZ3NbICRzcGVjWyduYW1lJ10gXSApICkgewoJCQkJCWlmICggaXNzZXQoICRzcGVjX2FyZ3NbJ2RlZmF1bHQnXSApICkgewoJCQkJCQkkYXNzb2NfYXJnc1sgJHNwZWNbJ25hbWUnXSBdID0gJHNwZWNfYXJnc1snZGVmYXVsdCddOwoJCQkJCX0KCQkJCX0KCQkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkc3BlY1snbmFtZSddIF0gKSAmJiBpc3NldCggJHNwZWNfYXJnc1snb3B0aW9ucyddICkgKSB7CgkJCQkJJHZhbHVlICAgPSAkYXNzb2NfYXJnc1sgJHNwZWNbJ25hbWUnXSBdOwoJCQkJCSRvcHRpb25zID0gJHNwZWNfYXJnc1snb3B0aW9ucyddOwoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuUEhQLlN0cmljdEluQXJyYXkuTWlzc2luZ1RydWVTdHJpY3QgLS0gVGhpcyBpcyBhIGxvb3NlIGNvbXBhcmlzb24gYnkgZGVzaWduLgoJCQkJCWlmICggISBpbl9hcnJheSggJHZhbHVlLCAkb3B0aW9ucyApICkgewoJCQkJCQkvLyBUcnkgd2hldGhlciBpdCBtaWdodCBiZSBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIG11bHRpcGxlIHZhbHVlcy4KCQkJCQkJJHZhbHVlcyA9IGFycmF5X21hcCggJ3RyaW0nLCBleHBsb2RlKCAnLCcsICR2YWx1ZSApICk7CgkJCQkJCSRjb3VudCAgPSBjb3VudCggJHZhbHVlcyApOwoJCQkJCQlpZiAoCgkJCQkJCQkkY291bnQgPiAxCgkJCQkJCQkmJgoJCQkJCQkJY291bnQoCgkJCQkJCQkJYXJyYXlfZmlsdGVyKAoJCQkJCQkJCQkkdmFsdWVzLAoJCQkJCQkJCQlzdGF0aWMgZnVuY3Rpb24gKCAkdmFsdWUgKSB1c2UgKCAkb3B0aW9ucyApIHsKCQkJCQkJCQkJCXJldHVybiBpbl9hcnJheSggJHZhbHVlLCAkb3B0aW9ucywgdHJ1ZSApOwoJCQkJCQkJCQl9CgkJCQkJCQkJKQoJCQkJCQkJKSA9PT0gJGNvdW50CgkJCQkJCSkgewoJCQkJCQkJY29udGludWU7CgkJCQkJCX0KCQkJCQkJJGVycm9yc1snZmF0YWwnXVsgJHNwZWNbJ25hbWUnXSBdID0gIkludmFsaWQgdmFsdWUgc3BlY2lmaWVkIGZvciAneyRzcGVjWyduYW1lJ119JyI7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoKCQlsaXN0KCAkcmV0dXJuZWRfZXJyb3JzLCAkdG9fdW5zZXQgKSA9ICR2YWxpZGF0b3ItPnZhbGlkYXRlX2Fzc29jKAoJCQlhcnJheV9tZXJnZSggXFdQX0NMSTo6Z2V0X2NvbmZpZygpLCAkZXh0cmFfYXJncywgJGFzc29jX2FyZ3MgKQoJCSk7CgkJZm9yZWFjaCAoIFsgJ2ZhdGFsJywgJ3dhcm5pbmcnIF0gYXMgJGVycm9yX3R5cGUgKSB7CgkJCSRlcnJvcnNbICRlcnJvcl90eXBlIF0gPSBhcnJheV9tZXJnZSggJGVycm9yc1sgJGVycm9yX3R5cGUgXSwgJHJldHVybmVkX2Vycm9yc1sgJGVycm9yX3R5cGUgXSApOwoJCX0KCgkJaWYgKCAnaGVscCcgIT09ICR0aGlzLT5uYW1lICkgewoJCQlmb3JlYWNoICggJHZhbGlkYXRvci0+dW5rbm93bl9hc3NvYyggJGFzc29jX2FyZ3MgKSBhcyAka2V5ICkgewoJCQkJJHN1Z2dlc3Rpb24gICAgPSBVdGlsc1xnZXRfc3VnZ2VzdGlvbigKCQkJCQkka2V5LAoJCQkJCSR0aGlzLT5nZXRfcGFyYW1ldGVycyggJHN5bm9wc2lzX3NwZWMgKSwKCQkJCQkkdGhyZXNob2xkID0gMgoJCQkJKTsKCgkJCQkkZXJyb3JzWydmYXRhbCddW10gPSBzcHJpbnRmKAoJCQkJCSd1bmtub3duIC0tJXMgcGFyYW1ldGVyJXMnLAoJCQkJCSRrZXksCgkJCQkJISBlbXB0eSggJHN1Z2dlc3Rpb24gKSA/IFBIUF9FT0wgLiAiRGlkIHlvdSBtZWFuICctLXskc3VnZ2VzdGlvbn0nPyIgOiAnJwoJCQkJKTsKCQkJfQoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkZXJyb3JzWydmYXRhbCddICkgKSB7CgkJCSRvdXQgPSAnUGFyYW1ldGVyIGVycm9yczonOwoJCQlmb3JlYWNoICggJGVycm9yc1snZmF0YWwnXSBhcyAka2V5ID0+ICRlcnJvciApIHsKCQkJCSRvdXQgLj0gIlxuIHskZXJyb3J9IjsKCQkJCSRkZXNjID0gJGRvY3BhcnNlci0+Z2V0X3BhcmFtX2Rlc2MoICRrZXkgKTsKCQkJCWlmICggJycgIT09ICRkZXNjICkgewoJCQkJCSRvdXQgLj0gIiAoeyRkZXNjfSkiOwoJCQkJfQoJCQl9CgoJCQlcV1BfQ0xJOjplcnJvciggJG91dCApOwoJCX0KCgkJYXJyYXlfbWFwKCAnXFxXUF9DTEk6Ondhcm5pbmcnLCAkZXJyb3JzWyd3YXJuaW5nJ10gKTsKCgkJcmV0dXJuIFsgJHRvX3Vuc2V0LCAkYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzIF07Cgl9CgoJLyoqCgkgKiBJbnZva2UgdGhlIHN1YmNvbW1hbmQgd2l0aCB0aGUgc3VwcGxpZWQgYXJndW1lbnRzLgoJICogR2l2ZW4gYSAtLXByb21wdCBhcmd1bWVudCwgaW50ZXJhY3RpdmVseSByZXF1ZXN0IGlucHV0CgkgKiBmcm9tIHRoZSBlbmQgdXNlci4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncwoJICovCglwdWJsaWMgZnVuY3Rpb24gaW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzICkgewoJCXN0YXRpYyAkcHJvbXB0ZWRfb25jZSA9IGZhbHNlOwoKCQlpZiAoICdoZWxwJyAhPT0gJHRoaXMtPm5hbWUgKSB7CgkJCWlmICggXFdQX0NMSTo6Z2V0X2NvbmZpZyggJ3Byb21wdCcgKSAmJiAhICRwcm9tcHRlZF9vbmNlICkgewoJCQkJbGlzdCggJF9hcmdzLCAkYXNzb2NfYXJncyApID0gJHRoaXMtPnByb21wdF9hcmdzKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQkJCSRhcmdzICAgICAgICAgICAgICAgICAgICAgICA9IGFycmF5X21lcmdlKCAkYXJncywgJF9hcmdzICk7CgkJCQkkcHJvbXB0ZWRfb25jZSAgICAgICAgICAgICAgPSB0cnVlOwoJCQl9CgkJfQoKCQkkZXh0cmFfcG9zaXRpb25hbHMgPSBbXTsKCQlmb3JlYWNoICggJGV4dHJhX2FyZ3MgYXMgJGsgPT4gJHYgKSB7CgkJCWlmICggaXNfbnVtZXJpYyggJGsgKSApIHsKCQkJCWlmICggISBpc3NldCggJGFyZ3NbICRrIF0gKSApIHsKCQkJCQkkZXh0cmFfcG9zaXRpb25hbHNbICRrIF0gPSAkdjsKCQkJCX0KCQkJCXVuc2V0KCAkZXh0cmFfYXJnc1sgJGsgXSApOwoJCQl9CgkJfQoJCSRhcmdzICs9ICRleHRyYV9wb3NpdGlvbmFsczsKCgkJbGlzdCggJHRvX3Vuc2V0LCAkYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzICkgPSAkdGhpcy0+dmFsaWRhdGVfYXJncyggJGFyZ3MsICRhc3NvY19hcmdzLCAkZXh0cmFfYXJncyApOwoKCQlmb3JlYWNoICggJHRvX3Vuc2V0IGFzICRrZXkgKSB7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1sgJGtleSBdICk7CgkJfQoKCQkkcGF0aCAgID0gZ2V0X3BhdGgoICR0aGlzLT5nZXRfcGFyZW50KCkgKTsKCQkkcGFyZW50ID0gaW1wbG9kZSggJyAnLCBhcnJheV9zbGljZSggJHBhdGgsIDEgKSApOwoJCSRjbWQgICAgPSAkdGhpcy0+bmFtZTsKCQlpZiAoICRwYXJlbnQgKSB7CgkJCVdQX0NMSTo6ZG9faG9vayggImJlZm9yZV9pbnZva2U6eyRwYXJlbnR9IiApOwoJCQkkY21kID0gJHBhcmVudCAuICcgJyAuICRjbWQ7CgkJfQoJCVdQX0NMSTo6ZG9faG9vayggImJlZm9yZV9pbnZva2U6eyRjbWR9IiApOwoKCQkvLyBDaGVjayBpZiBgLS1wcm9tcHRgIGFyZyBwYXNzZWQgb3Igbm90LgoJCWlmICggJHByb21wdGVkX29uY2UgKSB7CgkJCS8vIFVuc2V0IGVtcHR5IGFyZ3MuCgkJCSRhY3R1YWxfYXJncyA9ICRhc3NvY19hcmdzOwoJCQlmb3JlYWNoICggJGFjdHVhbF9hcmdzIGFzICRrZXkgKSB7CgkJCQlpZiAoIGVtcHR5KCAkYWN0dWFsX2FyZ3NbICRrZXkgXSApICkgewoJCQkJCXVuc2V0KCAkYWN0dWFsX2FyZ3NbICRrZXkgXSApOwoJCQkJfQoJCQl9CgoJCQlXUF9DTEk6OmxvZygKCQkJCXNwcmludGYoCgkJCQkJJ3dwICVzICVzJywKCQkJCQkkY21kLAoJCQkJCWx0cmltKCBVdGlsc1xhc3NvY19hcmdzX3RvX3N0ciggJGFjdHVhbF9hcmdzICksICcgJyApCgkJCQkpCgkJCSk7CgkJfQoKCQljYWxsX3VzZXJfZnVuYyggJHRoaXMtPndoZW5faW52b2tlZCwgJGFyZ3MsIGFycmF5X21lcmdlKCAkZXh0cmFfYXJncywgJGFzc29jX2FyZ3MgKSApOwoKCQlpZiAoICRwYXJlbnQgKSB7CgkJCVdQX0NMSTo6ZG9faG9vayggImFmdGVyX2ludm9rZTp7JHBhcmVudH0iICk7CgkJfQoJCVdQX0NMSTo6ZG9faG9vayggImFmdGVyX2ludm9rZTp7JGNtZH0iICk7Cgl9CgoJLyoqCgkgKiBHZXQgYW4gYXJyYXkgb2YgcGFyYW1ldGVyIG5hbWVzLCBieSBtZXJnaW5nIHRoZSBjb21tYW5kLXNwZWNpZmljIGFuZCB0aGUKCSAqIGdsb2JhbCBwYXJhbWV0ZXJzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHNwZWMgT3B0aW9uYWwuIFNwZWNpZmljYXRpb24gb2YgdGhlIGN1cnJlbnQgY29tbWFuZC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIHBhcmFtZXRlciBuYW1lcwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9wYXJhbWV0ZXJzKCAkc3BlYyA9IFtdICkgewoJCSRsb2NhbF9wYXJhbWV0ZXJzICA9IGFycmF5X2NvbHVtbiggJHNwZWMsICduYW1lJyApOwoJCSRnbG9iYWxfcGFyYW1ldGVycyA9IGFycmF5X2NvbHVtbigKCQkJU3lub3BzaXNQYXJzZXI6OnBhcnNlKCAkdGhpcy0+Z2V0X2dsb2JhbF9wYXJhbXMoKSApLAoJCQknbmFtZScKCQkpOwoKCQlyZXR1cm4gYXJyYXlfdW5pcXVlKCBhcnJheV9tZXJnZSggJGxvY2FsX3BhcmFtZXRlcnMsICRnbG9iYWxfcGFyYW1ldGVycyApICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRGlzcGF0Y2hlcjsKCnVzZSBXUF9DTEk7CgovKioKICogQ29udHJvbHMgd2hldGhlciBhZGRpbmcgb2YgYSBjb21tYW5kIHNob3VsZCBiZSBjb21wbGV0ZWQgb3Igbm90LgogKgogKiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIHdlIGNhbid0IHJlbGlhYmx5IHBhc3Mgc2NhbGFyIHZhbHVlcyBieSByZWZlcmVuY2UKICogdGhyb3VnaCB0aGUgaG9va3MgbWVjaGFuaXNtLiBBbiBvYmplY3QgaXMgYWx3YXlzIHBhc3NlZCBieSByZWZlcmVuY2UuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSQogKi8KZmluYWwgY2xhc3MgQ29tbWFuZEFkZGl0aW9uIHsKCgkvKioKCSAqIFdoZXRoZXIgdGhlIGNvbW1hbmQgYWRkaXRpb24gd2FzIGFib3J0ZWQgb3Igbm90LgoJICoKCSAqIEB2YXIgYm9vbAoJICovCglwcml2YXRlICRhYm9ydCA9IGZhbHNlOwoKCS8qKgoJICogUmVhc29uIGZvciB3aGljaCB0aGUgYWRkaXRpb24gd2FzIGFib3J0ZWQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJpdmF0ZSAkcmVhc29uID0gJyc7CgoJLyoqCgkgKiBBYm9ydCB0aGUgY3VycmVudCBjb21tYW5kIGFkZGl0aW9uLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlYXNvbiBSZWFzb24gYXMgdG8gd2h5IHRoZSBhZGRpdGlvbiB3YXMgYWJvcnRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFib3J0KCAkcmVhc29uID0gJycgKSB7CgkJJHRoaXMtPmFib3J0ICA9IHRydWU7CgkJJHRoaXMtPnJlYXNvbiA9IChzdHJpbmcpICRyZWFzb247Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIHRoZSBjb21tYW5kIGFkZGl0aW9uIHdhcyBhYm9ydGVkLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gd2FzX2Fib3J0ZWQoKSB7CgkJcmV0dXJuICR0aGlzLT5hYm9ydDsKCX0KCgkvKioKCSAqIEdldCB0aGUgcmVhc29uIGFzIHRvIHdoeSB0aGUgYWRkaXRpb24gd2FzIGFib3J0ZWQuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9yZWFzb24oKSB7CgkJcmV0dXJuICR0aGlzLT5yZWFzb247Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7CgovKioKICogRXNjYXBlIHJvdXRlIGZvciBub3QgZG9pbmcgYW55dGhpbmcuCiAqLwpmaW5hbCBjbGFzcyBOb09wIHsKCglwdWJsaWMgZnVuY3Rpb24gX19zZXQoICRrZXksICR2YWx1ZSApIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJcHVibGljIGZ1bmN0aW9uIF9fY2FsbCggJG1ldGhvZCwgJGFyZ3MgKSB7CgkJLy8gZG8gbm90aGluZwoJfQp9Cgo8P3BocAovKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCiAqICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAogKiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqCiAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55IGluZGl2aWR1YWxzCiAqIGFuZCBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUKICogPGh0dHBzOi8vd3d3LmRvY3RyaW5lLXByb2plY3Qub3JnPi4KICovCgpuYW1lc3BhY2UgV1BfQ0xJOwoKLyoqCiAqIERvY3RyaW5lIGluZmxlY3RvciBoYXMgc3RhdGljIG1ldGhvZHMgZm9yIGluZmxlY3RpbmcgdGV4dC4KICoKICogVGhlIG1ldGhvZHMgaW4gdGhlc2UgY2xhc3NlcyBhcmUgZnJvbSBzZXZlcmFsIGRpZmZlcmVudCBzb3VyY2VzIGNvbGxlY3RlZAogKiBhY3Jvc3Mgc2V2ZXJhbCBkaWZmZXJlbnQgcGhwIHByb2plY3RzIGFuZCBzZXZlcmFsIGRpZmZlcmVudCBhdXRob3JzLiBUaGUKICogb3JpZ2luYWwgYXV0aG9yIG5hbWVzIGFuZCBlbWFpbHMgYXJlIG5vdCBrbm93bi4KICoKICogUGx1cmFsaXplICYgU2luZ3VsYXJpemUgaW1wbGVtZW50YXRpb24gYXJlIGJvcnJvd2VkIGZyb20gQ2FrZVBIUCB3aXRoIHNvbWUgbW9kaWZpY2F0aW9ucy4KICoKICogQGxpbmsgICB3d3cuZG9jdHJpbmUtcHJvamVjdC5vcmcKICogQHNpbmNlICAxLjAKICogQGF1dGhvciBLb25zdGEgVmVzdGVyaW5lbiA8a3Zlc3RlcmlAY2MuaHV0LmZpPgogKiBAYXV0aG9yIEpvbmF0aGFuIEguIFdhZ2UgPGpvbndhZ2VAZ21haWwuY29tPgogKi8KY2xhc3MgSW5mbGVjdG9yIHsKCgkvKioKCSAqIFBsdXJhbCBpbmZsZWN0b3IgcnVsZXMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyAkcGx1cmFsID0gWwoJCSdydWxlcycgICAgICAgPT4gWwoJCQknLyhzKXRhdHVzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMnRhdHVzZXMnLAoJCQknLyhxdWl6KSQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDF6ZXMnLAoJCQknL14ob3gpJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMmVuJywKCQkJJy8oW218bF0pb3VzZSQvaScgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxaWNlJywKCQkJJy8obWF0cnx2ZXJ0fGluZCkoaXh8ZXgpJC9pJyAgICAgICAgICAgPT4gJ1wxaWNlcycsCgkJCScvKHh8Y2h8c3N8c2gpJC9pJyAgICAgICAgICAgICAgICAgICAgID0+ICdcMWVzJywKCQkJJy8oW15hZWlvdXldfHF1KXkkL2knICAgICAgICAgICAgICAgICAgPT4gJ1wxaWVzJywKCQkJJy8oaGl2ZSkkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxcycsCgkJCScvKD86KFteZl0pZmV8KFtscl0pZikkL2knICAgICAgICAgICAgID0+ICdcMVwydmVzJywKCQkJJy9zaXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ3NlcycsCgkJCScvKFt0aV0pdW0kL2knICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWEnLAoJCQknLyhwKWVyc29uJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFlb3BsZScsCgkJCScvKG0pYW4kL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWVuJywKCQkJJy8oYyloaWxkJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxaGlsZHJlbicsCgkJCScvKGYpb290JC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWVldCcsCgkJCScvKGJ1ZmZhbHxoZXJ8cG90YXR8dG9tYXR8dm9sY2FuKW8kL2knID0+ICdcMVwyb2VzJywKCQkJJy8oYWx1bW58YmFjaWxsfGNhY3R8Zm9jfGZ1bmd8bnVjbGV8cmFkaXxzdGltdWx8c3lsbGFifHRlcm1pbnx2aXIpdXMkL2knID0+ICdcMWknLAoJCQknL3VzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAndXNlcycsCgkJCScvKGFsaWFzKSQvaScgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWVzJywKCQkJJy8oYW5hbHlzfGF4fGNyaXN8dGVzdHx0aGVzKWlzJC9pJyAgICAgPT4gJ1wxZXMnLAoJCQknL3MkLycgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAncycsCgkJCScvXiQvJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICcnLAoJCQknLyQvJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAncycsCgkJXSwKCQkndW5pbmZsZWN0ZWQnID0+IFsKCQkJJy4qW25ybG1dZXNlJywKCQkJJy4qZGVlcicsCgkJCScuKmZpc2gnLAoJCQknLiptZWFzbGVzJywKCQkJJy4qb2lzJywKCQkJJy4qcG94JywKCQkJJy4qc2hlZXAnLAoJCQkncGVvcGxlJywKCQkJJ2Nvb2tpZScsCgkJXSwKCQknaXJyZWd1bGFyJyAgID0+IFsKCQkJJ2F0bGFzJyAgICAgICAgPT4gJ2F0bGFzZXMnLAoJCQknYXhlJyAgICAgICAgICA9PiAnYXhlcycsCgkJCSdiZWVmJyAgICAgICAgID0+ICdiZWVmcycsCgkJCSdicm90aGVyJyAgICAgID0+ICdicm90aGVycycsCgkJCSdjYWZlJyAgICAgICAgID0+ICdjYWZlcycsCgkJCSdjaGF0ZWF1JyAgICAgID0+ICdjaGF0ZWF1eCcsCgkJCSdjaGlsZCcgICAgICAgID0+ICdjaGlsZHJlbicsCgkJCSdjb29raWUnICAgICAgID0+ICdjb29raWVzJywKCQkJJ2NvcnB1cycgICAgICAgPT4gJ2NvcnB1c2VzJywKCQkJJ2NvdycgICAgICAgICAgPT4gJ2Nvd3MnLAoJCQknY3JpdGVyaW9uJyAgICA9PiAnY3JpdGVyaWEnLAoJCQknY3VycmljdWx1bScgICA9PiAnY3VycmljdWxhJywKCQkJJ2RlbW8nICAgICAgICAgPT4gJ2RlbW9zJywKCQkJJ2RvbWlubycgICAgICAgPT4gJ2RvbWlub2VzJywKCQkJJ2VjaG8nICAgICAgICAgPT4gJ2VjaG9lcycsCgkJCSdmb290JyAgICAgICAgID0+ICdmZWV0JywKCQkJJ2Z1bmd1cycgICAgICAgPT4gJ2Z1bmdpJywKCQkJJ2dhbmdsaW9uJyAgICAgPT4gJ2dhbmdsaW9ucycsCgkJCSdnZW5pZScgICAgICAgID0+ICdnZW5pZXMnLAoJCQknZ2VudXMnICAgICAgICA9PiAnZ2VuZXJhJywKCQkJJ2dyYWZmaXRvJyAgICAgPT4gJ2dyYWZmaXRpJywKCQkJJ2hpcHBvcG90YW11cycgPT4gJ2hpcHBvcG90YW1pJywKCQkJJ2hvb2YnICAgICAgICAgPT4gJ2hvb2ZzJywKCQkJJ2h1bWFuJyAgICAgICAgPT4gJ2h1bWFucycsCgkJCSdpcmlzJyAgICAgICAgID0+ICdpcmlzZXMnLAoJCQknbGVhZicgICAgICAgICA9PiAnbGVhdmVzJywKCQkJJ2xvYWYnICAgICAgICAgPT4gJ2xvYXZlcycsCgkJCSdtYW4nICAgICAgICAgID0+ICdtZW4nLAoJCQknbWVkaXVtJyAgICAgICA9PiAnbWVkaWEnLAoJCQknbWVtb3JhbmR1bScgICA9PiAnbWVtb3JhbmRhJywKCQkJJ21vbmV5JyAgICAgICAgPT4gJ21vbmllcycsCgkJCSdtb25nb29zZScgICAgID0+ICdtb25nb29zZXMnLAoJCQknbW90dG8nICAgICAgICA9PiAnbW90dG9lcycsCgkJCSdtb3ZlJyAgICAgICAgID0+ICdtb3ZlcycsCgkJCSdteXRob3MnICAgICAgID0+ICdteXRob2knLAoJCQknbmljaGUnICAgICAgICA9PiAnbmljaGVzJywKCQkJJ251Y2xldXMnICAgICAgPT4gJ251Y2xlaScsCgkJCSdudW1lbicgICAgICAgID0+ICdudW1pbmEnLAoJCQknb2NjaXB1dCcgICAgICA9PiAnb2NjaXB1dHMnLAoJCQknb2N0b3B1cycgICAgICA9PiAnb2N0b3B1c2VzJywKCQkJJ29wdXMnICAgICAgICAgPT4gJ29wdXNlcycsCgkJCSdveCcgICAgICAgICAgID0+ICdveGVuJywKCQkJJ3BlbmlzJyAgICAgICAgPT4gJ3BlbmlzZXMnLAoJCQkncGVyc29uJyAgICAgICA9PiAncGVvcGxlJywKCQkJJ3BsYXRlYXUnICAgICAgPT4gJ3BsYXRlYXV4JywKCQkJJ3J1bm5lci11cCcgICAgPT4gJ3J1bm5lcnMtdXAnLAoJCQknc2V4JyAgICAgICAgICA9PiAnc2V4ZXMnLAoJCQknc29saWxvcXV5JyAgICA9PiAnc29saWxvcXVpZXMnLAoJCQknc29uLWluLWxhdycgICA9PiAnc29ucy1pbi1sYXcnLAoJCQknc3lsbGFidXMnICAgICA9PiAnc3lsbGFiaScsCgkJCSd0ZXN0aXMnICAgICAgID0+ICd0ZXN0ZXMnLAoJCQkndGhpZWYnICAgICAgICA9PiAndGhpZXZlcycsCgkJCSd0b290aCcgICAgICAgID0+ICd0ZWV0aCcsCgkJCSd0b3JuYWRvJyAgICAgID0+ICd0b3JuYWRvZXMnLAoJCQkndHJpbGJ5JyAgICAgICA9PiAndHJpbGJ5cycsCgkJCSd0dXJmJyAgICAgICAgID0+ICd0dXJmcycsCgkJCSd2b2xjYW5vJyAgICAgID0+ICd2b2xjYW5vZXMnLAoJCV0sCgldOwoKCS8qKgoJICogU2luZ3VsYXIgaW5mbGVjdG9yIHJ1bGVzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgJHNpbmd1bGFyID0gWwoJCSdydWxlcycgICAgICAgPT4gWwoJCQknLyhzKXRhdHVzZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMVwydGF0dXMnLAoJCQknL14oLiopKG1lbnUpcyQvaScgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMVwyJywKCQkJJy8ocXVpeil6ZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXFwxJywKCQkJJy8obWF0cilpY2VzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFpeCcsCgkJCScvKHZlcnR8aW5kKWljZXMkL2knICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxZXgnLAoJCQknL14ob3gpZW4vaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKGFsaWFzKShlcykqJC9pJyAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy8oYnVmZmFsfGhlcnxwb3RhdHx0b21hdHx2b2xjYW4pb2VzJC9pJyA9PiAnXDFvJywKCQkJJy8oYWx1bW58YmFjaWxsfGNhY3R8Zm9jfGZ1bmd8bnVjbGV8cmFkaXxzdGltdWx8c3lsbGFifHRlcm1pbnx2aXJpPylpJC9pJyA9PiAnXDF1cycsCgkJCScvKFtmdHddYXgpZXMvaScgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy8oYW5hbHlzfGF4fGNyaXN8dGVzdHx0aGVzKWVzJC9pJyAgICAgICA9PiAnXDFpcycsCgkJCScvKHNob2V8c2xhdmUpcyQvaScgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy8obyllcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDEnLAoJCQknL291c2VzJC8nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdvdXNlJywKCQkJJy8oW15hXSl1c2VzJC8nICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDF1cycsCgkJCScvKFttfGxdKWljZSQvaScgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxb3VzZScsCgkJCScvKHh8Y2h8c3N8c2gpZXMkL2knICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy8obSlvdmllcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMm92aWUnLAoJCQknLyhzKWVyaWVzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMVwyZXJpZXMnLAoJCQknLyhbXmFlaW91eV18cXUpaWVzJC9pJyAgICAgICAgICAgICAgICAgID0+ICdcMXknLAoJCQknLyhbbHJdKXZlcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWYnLAoJCQknLyh0aXZlKXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKGhpdmUpcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy8oZHJpdmUpcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDEnLAoJCQknLyhbXmZvXSl2ZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWZlJywKCQkJJy8oXmFuYWx5KXNlcyQvaScgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFzaXMnLAoJCQknLyhhbmFseXxkaWFnbm98XmJhfChwKWFyZW50aGV8KHApcm9nbm98KHMpeW5vcHwodCloZSlzZXMkL2knID0+ICdcMVwyc2lzJywKCQkJJy8oW3RpXSlhJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDF1bScsCgkJCScvKHApZW9wbGUkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxXDJlcnNvbicsCgkJCScvKG0pZW4kL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxYW4nLAoJCQknLyhjKWhpbGRyZW4kL2knICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMVwyaGlsZCcsCgkJCScvKGYpZWV0JC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxb290JywKCQkJJy8obilld3MkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMmV3cycsCgkJCScvZWF1cyQvJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ2VhdScsCgkJCScvXiguKnVzKSQvJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1xcMScsCgkJCScvcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJycsCgkJXSwKCQkndW5pbmZsZWN0ZWQnID0+IFsKCQkJJy4qW25ybG1dZXNlJywKCQkJJy4qZGVlcicsCgkJCScuKmZpc2gnLAoJCQknLiptZWFzbGVzJywKCQkJJy4qb2lzJywKCQkJJy4qcG94JywKCQkJJy4qc2hlZXAnLAoJCQknLipzcycsCgkJXSwKCQknaXJyZWd1bGFyJyAgID0+IFsKCQkJJ2NyaXRlcmlhJyA9PiAnY3JpdGVyaW9uJywKCQkJJ2N1cnZlcycgICA9PiAnY3VydmUnLAoJCQknZW1waGFzZXMnID0+ICdlbXBoYXNpcycsCgkJCSdmb2VzJyAgICAgPT4gJ2ZvZScsCgkJCSdob2F4ZXMnICAgPT4gJ2hvYXgnLAoJCQknbWVkaWEnICAgID0+ICdtZWRpdW0nLAoJCQknbmV1cm9zZXMnID0+ICduZXVyb3NpcycsCgkJCSd3YXZlcycgICAgPT4gJ3dhdmUnLAoJCQknb2FzZXMnICAgID0+ICdvYXNpcycsCgkJXSwKCV07CgoJLyoqCgkgKiBXb3JkcyB0aGF0IHNob3VsZCBub3QgYmUgaW5mbGVjdGVkLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgJHVuaW5mbGVjdGVkID0gWwoJCSdBbW95ZXNlJywKCQknYmlzb24nLAoJCSdCb3JnaGVzZScsCgkJJ2JyZWFtJywKCQknYnJlZWNoZXMnLAoJCSdicml0Y2hlcycsCgkJJ2J1ZmZhbG8nLAoJCSdjYW50dXMnLAoJCSdjYXJwJywKCQknY2hhc3NpcycsCgkJJ2NsaXBwZXJzJywKCQknY29kJywKCQknY29pdHVzJywKCQknQ29uZ29lc2UnLAoJCSdjb250cmV0ZW1wcycsCgkJJ2NvcnBzJywKCQknZGVicmlzJywKCQknZGlhYmV0ZXMnLAoJCSdkamlubicsCgkJJ2VsYW5kJywKCQknZWxrJywKCQknZXF1aXBtZW50JywKCQknRmFyb2VzZScsCgkJJ2Zsb3VuZGVyJywKCQknRm9vY2hvd2VzZScsCgkJJ2dhbGxvd3MnLAoJCSdHZW5ldmVzZScsCgkJJ0dlbm9lc2UnLAoJCSdHaWxiZXJ0ZXNlJywKCQknZ3JhZmZpdGknLAoJCSdoZWFkcXVhcnRlcnMnLAoJCSdoZXJwZXMnLAoJCSdoaWppbmtzJywKCQknSG90dGVudG90ZXNlJywKCQknaW5mb3JtYXRpb24nLAoJCSdpbm5pbmdzJywKCQknamFja2FuYXBlcycsCgkJJ0tpcGxpbmdlc2UnLAoJCSdLb25nb2VzZScsCgkJJ0x1Y2NoZXNlJywKCQknbWFja2VyZWwnLAoJCSdNYWx0ZXNlJywKCQknLio/bWVkaWEnLAoJCSdtZXdzJywKCQknbW9vc2UnLAoJCSdtdW1wcycsCgkJJ05hbmtpbmdlc2UnLAoJCSduZXdzJywKCQknbmV4dXMnLAoJCSdOaWFzZXNlJywKCQknUGVraW5nZXNlJywKCQknUGllZG1vbnRlc2UnLAoJCSdwaW5jZXJzJywKCQknUGlzdG9pZXNlJywKCQkncGxpZXJzJywKCQknUG9ydHVndWVzZScsCgkJJ3Byb2NlZWRpbmdzJywKCQkncmFiaWVzJywKCQkncmljZScsCgkJJ3JoaW5vY2Vyb3MnLAoJCSdzYWxtb24nLAoJCSdTYXJhd2FrZXNlJywKCQknc2Npc3NvcnMnLAoJCSdzZWFbLSBdYmFzcycsCgkJJ3NlcmllcycsCgkJJ1NoYXZlc2UnLAoJCSdzaGVhcnMnLAoJCSdzaWVtZW5zJywKCQknc3BlY2llcycsCgkJJ3N0YWZmJywKCQknc3dpbmUnLAoJCSd0ZXN0ZXMnLAoJCSd0cm91c2VycycsCgkJJ3Ryb3V0JywKCQkndHVuYScsCgkJJ1Zlcm1vbnRlc2UnLAoJCSdXZW5jaG93ZXNlJywKCQknd2hpdGluZycsCgkJJ3dpbGRlYmVlc3QnLAoJCSdZZW5nZWVzZScsCgldOwoKCS8qKgoJICogTWV0aG9kIGNhY2hlIGFycmF5LgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgJGNhY2hlID0gW107CgoJLyoqCgkgKiBUaGUgaW5pdGlhbCBzdGF0ZSBvZiBJbmZsZWN0b3Igc28gcmVzZXQoKSB3b3Jrcy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljICRpbml0aWFsX3N0YXRlID0gW107CgoJLyoqCgkgKiBDb252ZXJ0cyBhIHdvcmQgaW50byB0aGUgZm9ybWF0IGZvciBhIERvY3RyaW5lIHRhYmxlIG5hbWUuIENvbnZlcnRzICdNb2RlbE5hbWUnIHRvICdtb2RlbF9uYW1lJy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3b3JkIFRoZSB3b3JkIHRvIHRhYmxlaXplLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFRoZSB0YWJsZWl6ZWQgd29yZC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0YWJsZWl6ZSggJHdvcmQgKSB7CgkJcmV0dXJuIHN0cnRvbG93ZXIoIHByZWdfcmVwbGFjZSggJ34oPzw9XFx3KShbQS1aXSl+JywgJ18kMScsICR3b3JkICkgKTsKCX0KCgkvKioKCSAqIENvbnZlcnRzIGEgd29yZCBpbnRvIHRoZSBmb3JtYXQgZm9yIGEgRG9jdHJpbmUgY2xhc3MgbmFtZS4gQ29udmVydHMgJ3RhYmxlX25hbWUnIHRvICdUYWJsZU5hbWUnLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdvcmQgVGhlIHdvcmQgdG8gY2xhc3NpZnkuCgkgKgoJICogQHJldHVybiBzdHJpbmcgVGhlIGNsYXNzaWZpZWQgd29yZC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjbGFzc2lmeSggJHdvcmQgKSB7CgkJcmV0dXJuIHN0cl9yZXBsYWNlKCAnICcsICcnLCB1Y3dvcmRzKCBzdHJ0ciggJHdvcmQsICdfLScsICcgICcgKSApICk7Cgl9CgoJLyoqCgkgKiBDYW1lbGl6ZXMgYSB3b3JkLiBUaGlzIHVzZXMgdGhlIGNsYXNzaWZ5KCkgbWV0aG9kIGFuZCB0dXJucyB0aGUgZmlyc3QgY2hhcmFjdGVyIHRvIGxvd2VyY2FzZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3b3JkIFRoZSB3b3JkIHRvIGNhbWVsaXplLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFRoZSBjYW1lbGl6ZWQgd29yZC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjYW1lbGl6ZSggJHdvcmQgKSB7CgkJcmV0dXJuIGxjZmlyc3QoIHNlbGY6OmNsYXNzaWZ5KCAkd29yZCApICk7Cgl9CgoJLyoqCgkgKiBVcHBlcmNhc2VzIHdvcmRzIHdpdGggY29uZmlndXJhYmxlIGRlbGltZXRlcnMgYmV0d2VlbiB3b3Jkcy4KCSAqCgkgKiBUYWtlcyBhIHN0cmluZyBhbmQgY2FwaXRhbGl6ZXMgYWxsIG9mIHRoZSB3b3JkcywgbGlrZSBQSFAncyBidWlsdC1pbgoJICogdWN3b3JkcyBmdW5jdGlvbi4gIFRoaXMgZXh0ZW5kcyB0aGF0IGJlaGF2aW9yLCBob3dldmVyLCBieSBhbGxvd2luZyB0aGUKCSAqIHdvcmQgZGVsaW1ldGVycyB0byBiZSBjb25maWd1cmVkLCByYXRoZXIgdGhhbiBvbmx5IHNlcGFyYXRpbmcgb24KCSAqIHdoaXRlc3BhY2UuCgkgKgoJICogSGVyZSBpcyBhbiBleGFtcGxlOgoJICogPGNvZGU+CgkgKiA8P3BocAoJICogJHN0cmluZyA9ICd0b3Atby10aGUtbW9ybmluZyB0byBhbGxfb2ZfeW91ISc7CgkgKiBlY2hvIFxEb2N0cmluZVxDb21tb25cSW5mbGVjdG9yXEluZmxlY3Rvcjo6dWN3b3Jkcygkc3RyaW5nKTsKCSAqIC8vIFRvcC1PLVRoZS1Nb3JuaW5nIFRvIEFsbF9vZl95b3UhCgkgKgoJICogZWNobyBcRG9jdHJpbmVcQ29tbW9uXEluZmxlY3RvclxJbmZsZWN0b3I6OnVjd29yZHMoJHN0cmluZywgJy1fICcpOwoJICogLy8gVG9wLU8tVGhlLU1vcm5pbmcgVG8gQWxsX09mX1lvdSEKCSAqID8+CgkgKiA8L2NvZGU+CgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFRoZSBzdHJpbmcgdG8gb3BlcmF0ZSBvbi4KCSAqIEBwYXJhbSBzdHJpbmcgJGRlbGltaXRlcnMgQSBsaXN0IG9mIHdvcmQgc2VwYXJhdG9ycy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgc3RyaW5nIHdpdGggYWxsIGRlbGltZXRlci1zZXBhcmF0ZWQgd29yZHMgY2FwaXRhbGl6ZWQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdWN3b3JkcyggJHN0cmluZywgJGRlbGltaXRlcnMgPSAiIFxuXHRcclwwXHgwQi0iICkgewoJCXJldHVybiBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCgkJCScvW14nIC4gcHJlZ19xdW90ZSggJGRlbGltaXRlcnMsICcvJyApIC4gJ10rLycsCgkJCWZ1bmN0aW9uKCAkbWF0Y2hlcyApIHsKCQkJCXJldHVybiB1Y2ZpcnN0KCAkbWF0Y2hlc1swXSApOwoJCQl9LAoJCQkkc3RyaW5nCgkJKTsKCX0KCgkvKioKCSAqIENsZWFycyBJbmZsZWN0b3JzIGluZmxlY3RlZCB2YWx1ZSBjYWNoZXMsIGFuZCByZXNldHMgdGhlIGluZmxlY3Rpb24KCSAqIHJ1bGVzIHRvIHRoZSBpbml0aWFsIHZhbHVlcy4KCSAqCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXNldCgpIHsKCQlpZiAoIGVtcHR5KCBzZWxmOjokaW5pdGlhbF9zdGF0ZSApICkgewoJCQlzZWxmOjokaW5pdGlhbF9zdGF0ZSA9IGdldF9jbGFzc192YXJzKCAnSW5mbGVjdG9yJyApOwoKCQkJcmV0dXJuOwoJCX0KCgkJZm9yZWFjaCAoIHNlbGY6OiRpbml0aWFsX3N0YXRlIGFzICRrZXkgPT4gJHZhbCApIHsKCQkJaWYgKCAnaW5pdGlhbF9zdGF0ZScgIT09ICRrZXkgKSB7CgkJCQlzZWxmOjokeyRrZXl9ID0gJHZhbDsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEFkZHMgY3VzdG9tIGluZmxlY3Rpb24gJHJ1bGVzLCBvZiBlaXRoZXIgJ3BsdXJhbCcgb3IgJ3Npbmd1bGFyJyAkdHlwZS4KCSAqCgkgKiAjIyMgVXNhZ2U6CgkgKgoJICoge3t7CgkgKiBJbmZsZWN0b3I6OnJ1bGVzKCdwbHVyYWwnLCBhcnJheSgnL14oaW5mbGVjdClvciQvaScgPT4gJ1wxYWJsZXMnKSk7CgkgKiBJbmZsZWN0b3I6OnJ1bGVzKCdwbHVyYWwnLCBhcnJheSgKCSAqICAgICAncnVsZXMnID0+IGFycmF5KCcvXihpbmZsZWN0KW9ycyQvaScgPT4gJ1wxYWJsZXMnKSwKCSAqICAgICAndW5pbmZsZWN0ZWQnID0+IGFycmF5KCdkb250aW5mbGVjdG1lJyksCgkgKiAgICAgJ2lycmVndWxhcicgPT4gYXJyYXkoJ3JlZCcgPT4gJ3JlZGxpbmdzJykKCSAqICkpOwoJICogfX19CgkgKgoJICogQHBhcmFtIHN0cmluZyAgJHR5cGUgIFRoZSB0eXBlIG9mIGluZmxlY3Rpb24sIGVpdGhlciAncGx1cmFsJyBvciAnc2luZ3VsYXInCgkgKiBAcGFyYW0gYXJyYXkgICAkcnVsZXMgQW4gYXJyYXkgb2YgcnVsZXMgdG8gYmUgYWRkZWQuCgkgKiBAcGFyYW0gYm9vbGVhbiAkcmVzZXQgSWYgdHJ1ZSwgd2lsbCB1bnNldCBkZWZhdWx0IGluZmxlY3Rpb25zIGZvciBhbGwKCSAqICAgICAgICAgICAgICAgICAgICAgICBuZXcgcnVsZXMgdGhhdCBhcmUgYmVpbmcgZGVmaW5lZCBpbiAkcnVsZXMuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcnVsZXMoICR0eXBlLCAkcnVsZXMsICRyZXNldCA9IGZhbHNlICkgewoJCWZvcmVhY2ggKCAkcnVsZXMgYXMgJHJ1bGUgPT4gJHBhdHRlcm4gKSB7CgkJCWlmICggISBpc19hcnJheSggJHBhdHRlcm4gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICRyZXNldCApIHsKCQkJCXNlbGY6OiR7JHR5cGV9WyAkcnVsZSBdID0gJHBhdHRlcm47CgkJCX0gZWxzZSB7CgkJCQlzZWxmOjokeyR0eXBlfVsgJHJ1bGUgXSA9ICggJ3VuaW5mbGVjdGVkJyA9PT0gJHJ1bGUgKQoJCQkJCT8gYXJyYXlfbWVyZ2UoICRwYXR0ZXJuLCBzZWxmOjokeyR0eXBlfVsgJHJ1bGUgXSApCgkJCQkJOiAkcGF0dGVybiArIHNlbGY6OiR7JHR5cGV9WyAkcnVsZSBdOwoJCQl9CgoJCQl1bnNldCggJHJ1bGVzWyAkcnVsZSBdLCBzZWxmOjokeyR0eXBlfVsgJ2NhY2hlJyAuIHVjZmlyc3QoICRydWxlICkgXSApOwoKCQkJaWYgKCBpc3NldCggc2VsZjo6JHskdHlwZX1bJ21lcmdlZCddWyAkcnVsZSBdICkgKSB7CgkJCQl1bnNldCggc2VsZjo6JHskdHlwZX1bJ21lcmdlZCddWyAkcnVsZSBdICk7CgkJCX0KCgkJCWlmICggJ3BsdXJhbCcgPT09ICR0eXBlICkgewoJCQkJc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXSA9IFtdOwoJCQkJc2VsZjo6JGNhY2hlWyd0YWJsZWl6ZSddICA9IFtdOwoJCQl9IGVsc2VpZiAoICdzaW5ndWxhcicgPT09ICR0eXBlICkgewoJCQkJc2VsZjo6JGNhY2hlWydzaW5ndWxhcml6ZSddID0gW107CgkJCX0KCQl9CgoJCXNlbGY6OiR7JHR5cGV9WydydWxlcyddID0gJHJ1bGVzICsgc2VsZjo6JHskdHlwZX1bJ3J1bGVzJ107Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGEgd29yZCBpbiBwbHVyYWwgZm9ybS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3b3JkIFRoZSB3b3JkIGluIHNpbmd1bGFyIGZvcm0uCgkgKgoJICogQHJldHVybiBzdHJpbmcgVGhlIHdvcmQgaW4gcGx1cmFsIGZvcm0uCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGx1cmFsaXplKCAkd29yZCApIHsKCQlpZiAoIGlzc2V0KCBzZWxmOjokY2FjaGVbJ3BsdXJhbGl6ZSddWyAkd29yZCBdICkgKSB7CgkJCXJldHVybiBzZWxmOjokY2FjaGVbJ3BsdXJhbGl6ZSddWyAkd29yZCBdOwoJCX0KCgkJaWYgKCAhIGlzc2V0KCBzZWxmOjokcGx1cmFsWydtZXJnZWQnXVsnaXJyZWd1bGFyJ10gKSApIHsKCQkJc2VsZjo6JHBsdXJhbFsnbWVyZ2VkJ11bJ2lycmVndWxhciddID0gc2VsZjo6JHBsdXJhbFsnaXJyZWd1bGFyJ107CgkJfQoKCQlpZiAoICEgaXNzZXQoIHNlbGY6OiRwbHVyYWxbJ21lcmdlZCddWyd1bmluZmxlY3RlZCddICkgKSB7CgkJCXNlbGY6OiRwbHVyYWxbJ21lcmdlZCddWyd1bmluZmxlY3RlZCddID0gYXJyYXlfbWVyZ2UoIHNlbGY6OiRwbHVyYWxbJ3VuaW5mbGVjdGVkJ10sIHNlbGY6OiR1bmluZmxlY3RlZCApOwoJCX0KCgkJaWYgKCAhIGlzc2V0KCBzZWxmOjokcGx1cmFsWydjYWNoZVVuaW5mbGVjdGVkJ10gKSB8fCAhIGlzc2V0KCBzZWxmOjokcGx1cmFsWydjYWNoZUlycmVndWxhciddICkgKSB7CgkJCXNlbGY6OiRwbHVyYWxbJ2NhY2hlVW5pbmZsZWN0ZWQnXSA9ICcoPzonIC4gaW1wbG9kZSggJ3wnLCBzZWxmOjokcGx1cmFsWydtZXJnZWQnXVsndW5pbmZsZWN0ZWQnXSApIC4gJyknOwoJCQlzZWxmOjokcGx1cmFsWydjYWNoZUlycmVndWxhciddICAgPSAnKD86JyAuIGltcGxvZGUoICd8JywgYXJyYXlfa2V5cyggc2VsZjo6JHBsdXJhbFsnbWVyZ2VkJ11bJ2lycmVndWxhciddICkgKSAuICcpJzsKCQl9CgoJCWlmICggcHJlZ19tYXRjaCggJy8oLiopXFxiKCcgLiBzZWxmOjokcGx1cmFsWydjYWNoZUlycmVndWxhciddIC4gJykkL2knLCAkd29yZCwgJHJlZ3MgKSApIHsKCQkJc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXVsgJHdvcmQgXSA9ICRyZWdzWzFdIC4gc3Vic3RyKCAkd29yZCwgMCwgMSApIC4gc3Vic3RyKCBzZWxmOjokcGx1cmFsWydtZXJnZWQnXVsnaXJyZWd1bGFyJ11bIHN0cnRvbG93ZXIoICRyZWdzWzJdICkgXSwgMSApOwoKCQkJcmV0dXJuIHNlbGY6OiRjYWNoZVsncGx1cmFsaXplJ11bICR3b3JkIF07CgkJfQoKCQlpZiAoIHByZWdfbWF0Y2goICcvXignIC4gc2VsZjo6JHBsdXJhbFsnY2FjaGVVbmluZmxlY3RlZCddIC4gJykkL2knLCAkd29yZCwgJHJlZ3MgKSApIHsKCQkJc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXVsgJHdvcmQgXSA9ICR3b3JkOwoKCQkJcmV0dXJuICR3b3JkOwoJCX0KCgkJZm9yZWFjaCAoIHNlbGY6OiRwbHVyYWxbJ3J1bGVzJ10gYXMgJHJ1bGUgPT4gJHJlcGxhY2VtZW50ICkgewoJCQlpZiAoIHByZWdfbWF0Y2goICRydWxlLCAkd29yZCApICkgewoJCQkJc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXVsgJHdvcmQgXSA9IHByZWdfcmVwbGFjZSggJHJ1bGUsICRyZXBsYWNlbWVudCwgJHdvcmQgKTsKCgkJCQlyZXR1cm4gc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXVsgJHdvcmQgXTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgYSB3b3JkIGluIHNpbmd1bGFyIGZvcm0uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd29yZCBUaGUgd29yZCBpbiBwbHVyYWwgZm9ybS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgd29yZCBpbiBzaW5ndWxhciBmb3JtLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNpbmd1bGFyaXplKCAkd29yZCApIHsKCQlpZiAoIGlzc2V0KCBzZWxmOjokY2FjaGVbJ3Npbmd1bGFyaXplJ11bICR3b3JkIF0gKSApIHsKCQkJcmV0dXJuIHNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXVsgJHdvcmQgXTsKCQl9CgoJCWlmICggISBpc3NldCggc2VsZjo6JHNpbmd1bGFyWydtZXJnZWQnXVsndW5pbmZsZWN0ZWQnXSApICkgewoJCQlzZWxmOjokc2luZ3VsYXJbJ21lcmdlZCddWyd1bmluZmxlY3RlZCddID0gYXJyYXlfbWVyZ2UoCgkJCQlzZWxmOjokc2luZ3VsYXJbJ3VuaW5mbGVjdGVkJ10sCgkJCQlzZWxmOjokdW5pbmZsZWN0ZWQKCQkJKTsKCQl9CgoJCWlmICggISBpc3NldCggc2VsZjo6JHNpbmd1bGFyWydtZXJnZWQnXVsnaXJyZWd1bGFyJ10gKSApIHsKCQkJc2VsZjo6JHNpbmd1bGFyWydtZXJnZWQnXVsnaXJyZWd1bGFyJ10gPSBhcnJheV9tZXJnZSgKCQkJCXNlbGY6OiRzaW5ndWxhclsnaXJyZWd1bGFyJ10sCgkJCQlhcnJheV9mbGlwKCBzZWxmOjokcGx1cmFsWydpcnJlZ3VsYXInXSApCgkJCSk7CgkJfQoKCQlpZiAoICEgaXNzZXQoIHNlbGY6OiRzaW5ndWxhclsnY2FjaGVVbmluZmxlY3RlZCddICkgfHwgISBpc3NldCggc2VsZjo6JHNpbmd1bGFyWydjYWNoZUlycmVndWxhciddICkgKSB7CgkJCXNlbGY6OiRzaW5ndWxhclsnY2FjaGVVbmluZmxlY3RlZCddID0gJyg/OicgLiBqb2luKCAnfCcsIHNlbGY6OiRzaW5ndWxhclsnbWVyZ2VkJ11bJ3VuaW5mbGVjdGVkJ10gKSAuICcpJzsKCQkJc2VsZjo6JHNpbmd1bGFyWydjYWNoZUlycmVndWxhciddICAgPSAnKD86JyAuIGpvaW4oICd8JywgYXJyYXlfa2V5cyggc2VsZjo6JHNpbmd1bGFyWydtZXJnZWQnXVsnaXJyZWd1bGFyJ10gKSApIC4gJyknOwoJCX0KCgkJaWYgKCBwcmVnX21hdGNoKCAnLyguKilcXGIoJyAuIHNlbGY6OiRzaW5ndWxhclsnY2FjaGVJcnJlZ3VsYXInXSAuICcpJC9pJywgJHdvcmQsICRyZWdzICkgKSB7CgkJCXNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXVsgJHdvcmQgXSA9ICRyZWdzWzFdIC4gc3Vic3RyKCAkd29yZCwgMCwgMSApIC4gc3Vic3RyKCBzZWxmOjokc2luZ3VsYXJbJ21lcmdlZCddWydpcnJlZ3VsYXInXVsgc3RydG9sb3dlciggJHJlZ3NbMl0gKSBdLCAxICk7CgoJCQlyZXR1cm4gc2VsZjo6JGNhY2hlWydzaW5ndWxhcml6ZSddWyAkd29yZCBdOwoJCX0KCgkJaWYgKCBwcmVnX21hdGNoKCAnL14oJyAuIHNlbGY6OiRzaW5ndWxhclsnY2FjaGVVbmluZmxlY3RlZCddIC4gJykkL2knLCAkd29yZCwgJHJlZ3MgKSApIHsKCQkJc2VsZjo6JGNhY2hlWydzaW5ndWxhcml6ZSddWyAkd29yZCBdID0gJHdvcmQ7CgoJCQlyZXR1cm4gJHdvcmQ7CgkJfQoKCQlmb3JlYWNoICggc2VsZjo6JHNpbmd1bGFyWydydWxlcyddIGFzICRydWxlID0+ICRyZXBsYWNlbWVudCApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAkcnVsZSwgJHdvcmQgKSApIHsKCQkJCXNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXVsgJHdvcmQgXSA9IHByZWdfcmVwbGFjZSggJHJ1bGUsICRyZXBsYWNlbWVudCwgJHdvcmQgKTsKCgkJCQlyZXR1cm4gc2VsZjo6JGNhY2hlWydzaW5ndWxhcml6ZSddWyAkd29yZCBdOwoJCQl9CgkJfQoKCQlzZWxmOjokY2FjaGVbJ3Npbmd1bGFyaXplJ11bICR3b3JkIF0gPSAkd29yZDsKCgkJcmV0dXJuICR3b3JkOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFJ1bnRpbWVFeGNlcHRpb247CgovKioKICogUnVuIGEgc3lzdGVtIHByb2Nlc3MsIGFuZCBsZWFybiB3aGF0IGhhcHBlbmVkLgogKi8KY2xhc3MgUHJvY2VzcyB7CgkvKioKCSAqIEB2YXIgc3RyaW5nIFRoZSBmdWxsIGNvbW1hbmQgdG8gZXhlY3V0ZSBieSB0aGUgc3lzdGVtLgoJICovCglwcml2YXRlICRjb21tYW5kOwoKCS8qKgoJICogQHZhciBzdHJpbmd8bnVsbCBUaGUgcGF0aCBvZiB0aGUgd29ya2luZyBkaXJlY3RvcnkgZm9yIHRoZSBwcm9jZXNzIG9yIE5VTEwgaWYgbm90IHNwZWNpZmllZCAoZGVmYXVsdHMgdG8gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSkuCgkgKi8KCXByaXZhdGUgJGN3ZDsKCgkvKioKCSAqIEB2YXIgYXJyYXkgRW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHNldCB3aGVuIHJ1bm5pbmcgdGhlIGNvbW1hbmQuCgkgKi8KCXByaXZhdGUgJGVudjsKCgkvKioKCSAqIEB2YXIgYXJyYXkgRGVzY3JpcHRvciBzcGVjIGZvciBgcHJvY19vcGVuKClgLgoJICovCglwcml2YXRlIHN0YXRpYyAkZGVzY3JpcHRvcnMgPSBbCgkJMCA9PiBTVERJTiwKCQkxID0+IFsgJ3BpcGUnLCAndycgXSwKCQkyID0+IFsgJ3BpcGUnLCAndycgXSwKCV07CgoJLyoqCgkgKiBAdmFyIGJvb2wgV2hldGhlciB0byBsb2cgcnVuIHRpbWUgaW5mbyBvciBub3QuCgkgKi8KCXB1YmxpYyBzdGF0aWMgJGxvZ19ydW5fdGltZXMgPSBmYWxzZTsKCgkvKioKCSAqIEB2YXIgYXJyYXkgQXJyYXkgb2YgcHJvY2VzcyBydW4gdGltZSBpbmZvLCBrZXllZCBieSBwcm9jZXNzIGNvbW1hbmQsIGVhY2ggYSAyLWVsZW1lbnQgYXJyYXkgY29udGFpbmluZyBydW4gdGltZSBhbmQgcnVuIGNvdW50LgoJICovCglwdWJsaWMgc3RhdGljICRydW5fdGltZXMgPSBbXTsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQgQ29tbWFuZCB0byBleGVjdXRlLgoJICogQHBhcmFtIHN0cmluZyAkY3dkIERpcmVjdG9yeSB0byBleGVjdXRlIHRoZSBjb21tYW5kIGluLgoJICogQHBhcmFtIGFycmF5ICRlbnYgRW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHNldCB3aGVuIHJ1bm5pbmcgdGhlIGNvbW1hbmQuCgkgKgoJICogQHJldHVybiBQcm9jZXNzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKCAkY29tbWFuZCwgJGN3ZCA9IG51bGwsICRlbnYgPSBbXSApIHsKCQkkcHJvYyA9IG5ldyBzZWxmKCk7CgoJCSRwcm9jLT5jb21tYW5kID0gJGNvbW1hbmQ7CgkJJHByb2MtPmN3ZCAgICAgPSAkY3dkOwoJCSRwcm9jLT5lbnYgICAgID0gJGVudjsKCgkJcmV0dXJuICRwcm9jOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7fQoKCS8qKgoJICogUnVuIHRoZSBjb21tYW5kLgoJICoKCSAqIEByZXR1cm4gUHJvY2Vzc1J1bgoJICovCglwdWJsaWMgZnVuY3Rpb24gcnVuKCkgewoJCSRzdGFydF90aW1lID0gbWljcm90aW1lKCB0cnVlICk7CgoJCSRwaXBlcyA9IFtdOwoJCSRwcm9jICA9IFV0aWxzXHByb2Nfb3Blbl9jb21wYXQoICR0aGlzLT5jb21tYW5kLCBzZWxmOjokZGVzY3JpcHRvcnMsICRwaXBlcywgJHRoaXMtPmN3ZCwgJHRoaXMtPmVudiApOwoKCQkkc3Rkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cyggJHBpcGVzWzFdICk7CgkJZmNsb3NlKCAkcGlwZXNbMV0gKTsKCgkJJHN0ZGVyciA9IHN0cmVhbV9nZXRfY29udGVudHMoICRwaXBlc1syXSApOwoJCWZjbG9zZSggJHBpcGVzWzJdICk7CgoJCSRyZXR1cm5fY29kZSA9IHByb2NfY2xvc2UoICRwcm9jICk7CgoJCSRydW5fdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApIC0gJHN0YXJ0X3RpbWU7CgoJCWlmICggc2VsZjo6JGxvZ19ydW5fdGltZXMgKSB7CgkJCWlmICggISBpc3NldCggc2VsZjo6JHJ1bl90aW1lc1sgJHRoaXMtPmNvbW1hbmQgXSApICkgewoJCQkJc2VsZjo6JHJ1bl90aW1lc1sgJHRoaXMtPmNvbW1hbmQgXSA9IFsgMCwgMCBdOwoJCQl9CgkJCXNlbGY6OiRydW5fdGltZXNbICR0aGlzLT5jb21tYW5kIF1bMF0gKz0gJHJ1bl90aW1lOwoJCQlzZWxmOjokcnVuX3RpbWVzWyAkdGhpcy0+Y29tbWFuZCBdWzFdKys7CgkJfQoKCQlyZXR1cm4gbmV3IFByb2Nlc3NSdW4oCgkJCVsKCQkJCSdzdGRvdXQnICAgICAgPT4gJHN0ZG91dCwKCQkJCSdzdGRlcnInICAgICAgPT4gJHN0ZGVyciwKCQkJCSdyZXR1cm5fY29kZScgPT4gJHJldHVybl9jb2RlLAoJCQkJJ2NvbW1hbmQnICAgICA9PiAkdGhpcy0+Y29tbWFuZCwKCQkJCSdjd2QnICAgICAgICAgPT4gJHRoaXMtPmN3ZCwKCQkJCSdlbnYnICAgICAgICAgPT4gJHRoaXMtPmVudiwKCQkJCSdydW5fdGltZScgICAgPT4gJHJ1bl90aW1lLAoJCQldCgkJKTsKCX0KCgkvKioKCSAqIFJ1biB0aGUgY29tbWFuZCwgYnV0IHRocm93IGFuIEV4Y2VwdGlvbiBvbiBlcnJvci4KCSAqCgkgKiBAcmV0dXJuIFByb2Nlc3NSdW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJ1bl9jaGVjaygpIHsKCQkkciA9ICR0aGlzLT5ydW4oKTsKCgkJaWYgKCAkci0+cmV0dXJuX2NvZGUgKSB7CgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCAkciApOwoJCX0KCgkJcmV0dXJuICRyOwoJfQoKCS8qKgoJICogUnVuIHRoZSBjb21tYW5kLCBidXQgdGhyb3cgYW4gRXhjZXB0aW9uIG9uIGVycm9yLgoJICogU2FtZSBhcyBgcnVuX2NoZWNrKClgIGFib3ZlLCBidXQgY2hlY2tzIHRoZSBjb3JyZWN0IHN0ZGVyci4KCSAqCgkgKiBAcmV0dXJuIFByb2Nlc3NSdW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJ1bl9jaGVja19zdGRlcnIoKSB7CgkJJHIgPSAkdGhpcy0+cnVuKCk7CgoJCWlmICggJHItPnJldHVybl9jb2RlIHx8ICEgZW1wdHkoICRyLT5zdGRlcnIgKSApIHsKCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oICRyICk7CgkJfQoKCQlyZXR1cm4gJHI7Cgl9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBoZWF2aWx5IGluc3BpcmVkIGFuZCB1c2UgY29kZSBmcm9tIENvbXBvc2VyKGdldGNvbXBvc2VyLm9yZyksCiAqIGluIHBhcnRpY3VsYXIgQ29tcG9zZXIvQ2FjaGUgYW5kIENvbXBvc2VyL1V0aWwvRmlsZVN5c3RlbSBmcm9tIDEuMC4wLWFscGhhNwogKgogKiBUaGUgb3JpZ2luYWwgY29kZSBhbmQgdGhpcyBmaWxlIGFyZSBib3RoIHJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlLgogKgogKiBUaGUgY29weXJpZ2h0IGhvbGRlcnMgb2YgdGhlIG9yaWdpbmFsIGNvZGUgYXJlOgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgRGF0ZVRpbWU7CnVzZSBFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcRmluZGVyOwp1c2UgV1BfQ0xJOwoKLyoqCiAqIFJlYWRzL3dyaXRlcyB0byBhIGZpbGVzeXN0ZW0gY2FjaGUKICovCmNsYXNzIEZpbGVDYWNoZSB7CgoJLyoqCgkgKiBAdmFyIHN0cmluZyBjYWNoZSBwYXRoCgkgKi8KCXByb3RlY3RlZCAkcm9vdDsKCS8qKgoJICogQHZhciBib29sCgkgKi8KCXByb3RlY3RlZCAkZW5hYmxlZCA9IHRydWU7CgkvKioKCSAqIEB2YXIgaW50IGZpbGVzIHRpbWUgdG8gbGl2ZQoJICovCglwcm90ZWN0ZWQgJHR0bDsKCS8qKgoJICogQHZhciBpbnQgbWF4IHRvdGFsIHNpemUKCSAqLwoJcHJvdGVjdGVkICRtYXhfc2l6ZTsKCS8qKgoJICogQHZhciBzdHJpbmcga2V5IGFsbG93ZWQgY2hhcnMgKHJlZ2V4IGNsYXNzKQoJICovCglwcm90ZWN0ZWQgJHdoaXRlbGlzdDsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJGNhY2hlX2RpciAgbG9jYXRpb24gb2YgdGhlIGNhY2hlCgkgKiBAcGFyYW0gaW50ICAgICR0dGwgICAgICAgIGNhY2hlIGZpbGVzIGRlZmF1bHQgdGltZSB0byBsaXZlIChleHBpcmF0aW9uKQoJICogQHBhcmFtIGludCAgICAkbWF4X3NpemUgICBtYXggdG90YWwgY2FjaGUgc2l6ZQoJICogQHBhcmFtIHN0cmluZyAkd2hpdGVsaXN0ICBMaXN0IG9mIGNoYXJhY3RlcnMgdGhhdCBhcmUgYWxsb3dlZCBpbiBwYXRoIG5hbWVzICh1c2VkIGluIGEgcmVnZXggY2hhcmFjdGVyIGNsYXNzKQoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRjYWNoZV9kaXIsICR0dGwsICRtYXhfc2l6ZSwgJHdoaXRlbGlzdCA9ICdhLXowLTkuXy0nICkgewoJCSR0aGlzLT5yb290ICAgICAgPSBVdGlsc1x0cmFpbGluZ3NsYXNoaXQoICRjYWNoZV9kaXIgKTsKCQkkdGhpcy0+dHRsICAgICAgID0gKGludCkgJHR0bDsKCQkkdGhpcy0+bWF4X3NpemUgID0gKGludCkgJG1heF9zaXplOwoJCSR0aGlzLT53aGl0ZWxpc3QgPSAkd2hpdGVsaXN0OwoKCQlpZiAoICEgJHRoaXMtPmVuc3VyZV9kaXJfZXhpc3RzKCAkdGhpcy0+cm9vdCApICkgewoJCQkkdGhpcy0+ZW5hYmxlZCA9IGZhbHNlOwoJCX0KCgl9CgoJLyoqCgkgKiBDYWNoZSBpcyBlbmFibGVkCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc19lbmFibGVkKCkgewoJCXJldHVybiAkdGhpcy0+ZW5hYmxlZDsKCX0KCgkvKioKCSAqIENhY2hlIHJvb3QKCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3Jvb3QoKSB7CgkJcmV0dXJuICR0aGlzLT5yb290OwoJfQoKCgkvKioKCSAqIENoZWNrIGlmIGEgZmlsZSBpcyBpbiBjYWNoZSBhbmQgcmV0dXJuIGl0cyBmaWxlbmFtZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBjYWNoZSBrZXkKCSAqIEBwYXJhbSBpbnQgICAgJHR0bCB0aW1lIHRvIGxpdmUKCSAqIEByZXR1cm4gYm9vbHxzdHJpbmcgZmlsZW5hbWUgb3IgZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGhhcyggJGtleSwgJHR0bCA9IG51bGwgKSB7CgkJaWYgKCAhICR0aGlzLT5lbmFibGVkICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkZmlsZW5hbWUgPSAkdGhpcy0+ZmlsZW5hbWUoICRrZXkgKTsKCgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkZmlsZW5hbWUgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gVXNlIHR0bCBwYXJhbSBvciBnbG9iYWwgdHRsLgoJCWlmICggbnVsbCA9PT0gJHR0bCApIHsKCQkJJHR0bCA9ICR0aGlzLT50dGw7CgkJfSBlbHNlaWYgKCAkdGhpcy0+dHRsID4gMCApIHsKCQkJJHR0bCA9IG1pbiggKGludCkgJHR0bCwgJHRoaXMtPnR0bCApOwoJCX0gZWxzZSB7CgkJCSR0dGwgPSAoaW50KSAkdHRsOwoJCX0KCgkJLy8KCQlpZiAoICR0dGwgPiAwICYmICggZmlsZW10aW1lKCAkZmlsZW5hbWUgKSArICR0dGwgKSA8IHRpbWUoKSApIHsKCQkJaWYgKCAkdGhpcy0+dHRsID4gMCAmJiAkdHRsID49ICR0aGlzLT50dGwgKSB7CgkJCQl1bmxpbmsoICRmaWxlbmFtZSApOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkZmlsZW5hbWU7Cgl9CgoJLyoqCgkgKiBXcml0ZSB0byBjYWNoZSBmaWxlCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5ICAgICAgY2FjaGUga2V5CgkgKiBAcGFyYW0gc3RyaW5nICRjb250ZW50cyBmaWxlIGNvbnRlbnRzCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHdyaXRlKCAka2V5LCAkY29udGVudHMgKSB7CgkJJGZpbGVuYW1lID0gJHRoaXMtPnByZXBhcmVfd3JpdGUoICRrZXkgKTsKCgkJaWYgKCAkZmlsZW5hbWUgKSB7CgkJCXJldHVybiBmaWxlX3B1dF9jb250ZW50cyggJGZpbGVuYW1lLCAkY29udGVudHMgKSAmJiB0b3VjaCggJGZpbGVuYW1lICk7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZWFkIGZyb20gY2FjaGUgZmlsZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBjYWNoZSBrZXkKCSAqIEBwYXJhbSBpbnQgICAgJHR0bCB0aW1lIHRvIGxpdmUKCSAqIEByZXR1cm4gYm9vbHxzdHJpbmcgZmlsZSBjb250ZW50cyBvciBmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVhZCggJGtleSwgJHR0bCA9IG51bGwgKSB7CgkJJGZpbGVuYW1lID0gJHRoaXMtPmhhcyggJGtleSwgJHR0bCApOwoKCQlpZiAoICRmaWxlbmFtZSApIHsKCQkJcmV0dXJuIGZpbGVfZ2V0X2NvbnRlbnRzKCAkZmlsZW5hbWUgKTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIENvcHkgYSBmaWxlIGludG8gdGhlIGNhY2hlCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5ICAgIGNhY2hlIGtleQoJICogQHBhcmFtIHN0cmluZyAkc291cmNlIHNvdXJjZSBmaWxlbmFtZQoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbXBvcnQoICRrZXksICRzb3VyY2UgKSB7CgkJJGZpbGVuYW1lID0gJHRoaXMtPnByZXBhcmVfd3JpdGUoICRrZXkgKTsKCgkJaWYgKCAkZmlsZW5hbWUgKSB7CgkJCXJldHVybiBjb3B5KCAkc291cmNlLCAkZmlsZW5hbWUgKSAmJiB0b3VjaCggJGZpbGVuYW1lICk7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBDb3B5IGEgZmlsZSBvdXQgb2YgdGhlIGNhY2hlCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5ICAgIGNhY2hlIGtleQoJICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0IHRhcmdldCBmaWxlbmFtZQoJICogQHBhcmFtIGludCAgICAkdHRsICAgIHRpbWUgdG8gbGl2ZQoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBleHBvcnQoICRrZXksICR0YXJnZXQsICR0dGwgPSBudWxsICkgewoJCSRmaWxlbmFtZSA9ICR0aGlzLT5oYXMoICRrZXksICR0dGwgKTsKCgkJaWYgKCAkZmlsZW5hbWUgJiYgJHRoaXMtPmVuc3VyZV9kaXJfZXhpc3RzKCBkaXJuYW1lKCAkdGFyZ2V0ICkgKSApIHsKCQkJcmV0dXJuIGNvcHkoICRmaWxlbmFtZSwgJHRhcmdldCApOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogUmVtb3ZlIGZpbGUgZnJvbSBjYWNoZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBjYWNoZSBrZXkKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCAka2V5ICkgewoJCWlmICggISAkdGhpcy0+ZW5hYmxlZCApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJGZpbGVuYW1lID0gJHRoaXMtPmZpbGVuYW1lKCAka2V5ICk7CgoJCWlmICggZmlsZV9leGlzdHMoICRmaWxlbmFtZSApICkgewoJCQlyZXR1cm4gdW5saW5rKCAkZmlsZW5hbWUgKTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIENsZWFuIGNhY2hlIGJhc2VkIG9uIHRpbWUgdG8gbGl2ZSBhbmQgbWF4IHNpemUKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNsZWFuKCkgewoJCWlmICggISAkdGhpcy0+ZW5hYmxlZCApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHR0bCAgICAgID0gJHRoaXMtPnR0bDsKCQkkbWF4X3NpemUgPSAkdGhpcy0+bWF4X3NpemU7CgoJCS8vIFVubGluayBleHBpcmVkIGZpbGVzLgoJCWlmICggJHR0bCA+IDAgKSB7CgkJCXRyeSB7CgkJCQkkZXhwaXJlID0gbmV3IERhdGVUaW1lKCk7CgkJCQkkZXhwaXJlLT5tb2RpZnkoICctJyAuICR0dGwgLiAnIHNlY29uZHMnICk7CgoJCQkJJGZpbmRlciA9ICR0aGlzLT5nZXRfZmluZGVyKCktPmRhdGUoICd1bnRpbCAnIC4gJGV4cGlyZS0+Zm9ybWF0KCAnWS1tLWQgSDppOnMnICkgKTsKCQkJCWZvcmVhY2ggKCAkZmluZGVyIGFzICRmaWxlICkgewoJCQkJCXVubGluayggJGZpbGUtPmdldFJlYWxQYXRoKCkgKTsKCQkJCX0KCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJfQoJCX0KCgkJLy8gVW5saW5rIG9sZGVyIGZpbGVzIGlmIG1heCBjYWNoZSBzaXplIGlzIGV4Y2VlZGVkLgoJCWlmICggJG1heF9zaXplID4gMCApIHsKCQkJJGZpbGVzID0gYXJyYXlfcmV2ZXJzZSggaXRlcmF0b3JfdG9fYXJyYXkoICR0aGlzLT5nZXRfZmluZGVyKCktPnNvcnRCeUFjY2Vzc2VkVGltZSgpLT5nZXRJdGVyYXRvcigpICkgKTsKCQkJJHRvdGFsID0gMDsKCgkJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGUgKSB7CgkJCQlpZiAoICggJHRvdGFsICsgJGZpbGUtPmdldFNpemUoKSApIDw9ICRtYXhfc2l6ZSApIHsKCQkJCQkkdG90YWwgKz0gJGZpbGUtPmdldFNpemUoKTsKCQkJCX0gZWxzZSB7CgkJCQkJdW5saW5rKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSApOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFJlbW92ZSBhbGwgY2FjaGVkIGZpbGVzLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gY2xlYXIoKSB7CgkJaWYgKCAhICR0aGlzLT5lbmFibGVkICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkZmluZGVyID0gJHRoaXMtPmdldF9maW5kZXIoKTsKCgkJZm9yZWFjaCAoICRmaW5kZXIgYXMgJGZpbGUgKSB7CgkJCXVubGluayggJGZpbGUtPmdldFJlYWxQYXRoKCkgKTsKCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogUmVtb3ZlIGFsbCBjYWNoZWQgZmlsZXMgZXhjZXB0IGZvciB0aGUgbmV3ZXN0IHZlcnNpb24gb2Ygb25lLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJ1bmUoKSB7CgkJaWYgKCAhICR0aGlzLT5lbmFibGVkICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKiogQHZhciBGaW5kZXIgJGZpbmRlciAqLwoJCSRmaW5kZXIgPSAkdGhpcy0+Z2V0X2ZpbmRlcigpLT5zb3J0QnlOYW1lKCk7CgoJCSRmaWxlc190b19kZWxldGUgPSBbXTsKCgkJZm9yZWFjaCAoICRmaW5kZXIgYXMgJGZpbGUgKSB7CgkJCSRwaWVjZXMgICAgPSBleHBsb2RlKCAnLScsICRmaWxlLT5nZXRCYXNlbmFtZSggJGZpbGUtPmdldEV4dGVuc2lvbigpICkgKTsKCQkJJHRpbWVzdGFtcCA9IGVuZCggJHBpZWNlcyApOwoKCQkJLy8gTm8gd2F5IHRvIGNvbXBhcmUgdmVyc2lvbnMsIGRvIG5vdGhpbmcuCgkJCWlmICggISBpc19udW1lcmljKCAkdGltZXN0YW1wICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGJhc2VuYW1lX3dpdGhvdXRfdGltZXN0YW1wID0gc3RyX3JlcGxhY2UoICctJyAuICR0aW1lc3RhbXAsICcnLCAkZmlsZS0+Z2V0QmFzZW5hbWUoKSApOwoKCQkJLy8gVGhlcmUncyBhIGZpbGUgd2l0aCBhbiBvbGRlciB0aW1lc3RhbXAsIGRlbGV0ZSBpdC4KCQkJaWYgKCBpc3NldCggJGZpbGVzX3RvX2RlbGV0ZVsgJGJhc2VuYW1lX3dpdGhvdXRfdGltZXN0YW1wIF0gKSApIHsKCQkJCXVubGluayggJGZpbGVzX3RvX2RlbGV0ZVsgJGJhc2VuYW1lX3dpdGhvdXRfdGltZXN0YW1wIF0gKTsKCQkJfQoKCQkJJGZpbGVzX3RvX2RlbGV0ZVsgJGJhc2VuYW1lX3dpdGhvdXRfdGltZXN0YW1wIF0gPSAkZmlsZS0+Z2V0UmVhbFBhdGgoKTsKCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogRW5zdXJlIGRpcmVjdG9yeSBleGlzdHMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkaXIgZGlyZWN0b3J5CgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGVuc3VyZV9kaXJfZXhpc3RzKCAkZGlyICkgewoJCWlmICggISBpc19kaXIoICRkaXIgKSApIHsKCQkJLy8gRGlzYWJsZSB0aGUgY2FjaGUgaWYgYSBudWxsIGRldmljZSBsaWtlIC9kZXYvbnVsbCBpcyBiZWluZyB1c2VkLgoJCQlpZiAoIHByZWdfbWF0Y2goICd7KF58W1xcXFwvXSkoXCRudWxsfG51bHxOVUx8L2Rldi9udWxsKShbXFxcXC9dfCQpfScsICRkaXIgKSApIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoKCQkJaWYgKCAhIEBta2RpciggJGRpciwgMDc3NywgdHJ1ZSApICkgewoJCQkJJG1lc3NhZ2UgPSAiRmFpbGVkIHRvIGNyZWF0ZSBkaXJlY3RvcnkgJ3skZGlyfSciOwoJCQkJJGVycm9yICAgPSBlcnJvcl9nZXRfbGFzdCgpOwoJCQkJaWYgKCBpc19hcnJheSggJGVycm9yICkgJiYgYXJyYXlfa2V5X2V4aXN0cyggJ21lc3NhZ2UnLCAkZXJyb3IgKSApIHsKCQkJCQkkbWVzc2FnZSAuPSAiOiB7JGVycm9yWydtZXNzYWdlJ119IjsKCQkJCX0KCQkJCVdQX0NMSTo6d2FybmluZyggInskbWVzc2FnZX0uIiApOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFByZXBhcmUgY2FjaGUgd3JpdGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgY2FjaGUga2V5CgkgKiBAcmV0dXJuIGJvb2x8c3RyaW5nIGZpbGVuYW1lIG9yIGZhbHNlCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBwcmVwYXJlX3dyaXRlKCAka2V5ICkgewoJCWlmICggISAkdGhpcy0+ZW5hYmxlZCApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJGZpbGVuYW1lID0gJHRoaXMtPmZpbGVuYW1lKCAka2V5ICk7CgoJCWlmICggISAkdGhpcy0+ZW5zdXJlX2Rpcl9leGlzdHMoIGRpcm5hbWUoICRmaWxlbmFtZSApICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkZmlsZW5hbWU7Cgl9CgoJLyoqCgkgKiBWYWxpZGF0ZSBjYWNoZSBrZXkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgY2FjaGUga2V5CgkgKiBAcmV0dXJuIHN0cmluZyByZWxhdGl2ZSBmaWxlbmFtZQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVfa2V5KCAka2V5ICkgewoJCSR1cmxfcGFydHMgPSBVdGlsc1xwYXJzZV91cmwoICRrZXksIC0xLCBmYWxzZSApOwoJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJ3BhdGgnLCAkdXJsX3BhcnRzICkgJiYgISBlbXB0eSggJHVybF9wYXJ0c1snc2NoZW1lJ10gKSApIHsgLy8gaXMgdXJsCgkJCSRwYXJ0cyAgID0gWyAnbWlzYycgXTsKCQkJJHBhcnRzW10gPSAkdXJsX3BhcnRzWydzY2hlbWUnXSAuCgkJCQkoIGVtcHR5KCAkdXJsX3BhcnRzWydob3N0J10gKSA/ICcnIDogJy0nIC4gJHVybF9wYXJ0c1snaG9zdCddICkgLgoJCQkJKCBlbXB0eSggJHVybF9wYXJ0c1sncG9ydCddICkgPyAnJyA6ICctJyAuICR1cmxfcGFydHNbJ3BvcnQnXSApOwoJCQkkcGFydHNbXSA9IHN1YnN0ciggJHVybF9wYXJ0c1sncGF0aCddLCAxICkgLgoJCQkJKCBlbXB0eSggJHVybF9wYXJ0c1sncXVlcnknXSApID8gJycgOiAnLScgLiAkdXJsX3BhcnRzWydxdWVyeSddICk7CgkJfSBlbHNlIHsKCQkJJGtleSAgID0gc3RyX3JlcGxhY2UoICdcXCcsICcvJywgJGtleSApOwoJCQkkcGFydHMgPSBleHBsb2RlKCAnLycsIGx0cmltKCAka2V5ICkgKTsKCQl9CgoJCSRwYXJ0cyA9IHByZWdfcmVwbGFjZSggIiNbXnskdGhpcy0+d2hpdGVsaXN0fV0jaSIsICctJywgJHBhcnRzICk7CgoJCXJldHVybiBpbXBsb2RlKCAnLycsICRwYXJ0cyApOwoJfQoKCS8qKgoJICogRmlsZW5hbWUgZnJvbSBrZXkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkKCSAqIEByZXR1cm4gc3RyaW5nIGZpbGVuYW1lCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBmaWxlbmFtZSggJGtleSApIHsKCQlyZXR1cm4gJHRoaXMtPnJvb3QgLiAkdGhpcy0+dmFsaWRhdGVfa2V5KCAka2V5ICk7Cgl9CgoJLyoqCgkgKiBHZXQgYSBGaW5kZXIgdGhhdCBpdGVyYXRlcyBpbiBjYWNoZSByb290IG9ubHkgdGhlIGZpbGVzCgkgKgoJICogQHJldHVybiBGaW5kZXIKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9maW5kZXIoKSB7CgkJcmV0dXJuIEZpbmRlcjo6Y3JlYXRlKCktPmluKCAkdGhpcy0+cm9vdCApLT5maWxlcygpOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIENvbXBvc2VyXElPXE51bGxJTzsKdXNlIFdQX0NMSTsKCi8qKgogKiBBIENvbXBvc2VyIElPIGNsYXNzIHNvIHdlIGNhbiBwcm92aWRlIHNvbWUgbGV2ZWwgb2YgaW50ZXJhY3Rpdml0eSBmcm9tIFdQLUNMSQogKi8KY2xhc3MgQ29tcG9zZXJJTyBleHRlbmRzIE51bGxJTyB7CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB3cml0ZSggJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwgKSB7CgkJc2VsZjo6b3V0cHV0X2NsZWFuX21lc3NhZ2UoICRtZXNzYWdlcyApOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICovCglwdWJsaWMgZnVuY3Rpb24gd3JpdGVFcnJvciggJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwgKSB7CgkJc2VsZjo6b3V0cHV0X2NsZWFuX21lc3NhZ2UoICRtZXNzYWdlcyApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIG91dHB1dF9jbGVhbl9tZXNzYWdlKCAkbWVzc2FnZXMgKSB7CgkJJG1lc3NhZ2VzID0gKGFycmF5KSBwcmVnX3JlcGxhY2UoICcjPChodHRwcz8pKFtePl0rKT4jJywgJyQxJDInLCAkbWVzc2FnZXMgKTsKCQlmb3JlYWNoICggJG1lc3NhZ2VzIGFzICRtZXNzYWdlICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnN0cmlwX3RhZ3Nfc3RyaXBfdGFncwoJCQlXUF9DTEk6OmxvZyggc3RyaXBfdGFncyggdHJpbSggJG1lc3NhZ2UgKSApICk7CgkJfQoJfQoKfQo8P3BocAoKLy8gVXRpbGl0aWVzIHRoYXQgZGVwZW5kIG9uIFdvcmRQcmVzcyBjb2RlLgoKbmFtZXNwYWNlIFdQX0NMSVxVdGlsczsKCnVzZSBSZWZsZWN0aW9uQ2xhc3M7CnVzZSBSZWZsZWN0aW9uUGFyYW1ldGVyOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFVwZ3JhZGVyU2tpbjsKCmZ1bmN0aW9uIHdwX25vdF9pbnN0YWxsZWQoKSB7CglnbG9iYWwgJHdwZGIsICR0YWJsZV9wcmVmaXg7CglpZiAoICEgaXNfYmxvZ19pbnN0YWxsZWQoKSAmJiAhIGRlZmluZWQoICdXUF9JTlNUQUxMSU5HJyApICkgewoJCSR0YWJsZXMgICAgICAgICA9ICR3cGRiLT5nZXRfY29sKCAiU0hPVyBUQUJMRVMgTElLRSAnJV9vcHRpb25zJyIgKTsKCQkkZm91bmRfcHJlZml4ZXMgPSBbXTsKCQlpZiAoIGNvdW50KCAkdGFibGVzICkgKSB7CgkJCWZvcmVhY2ggKCAkdGFibGVzIGFzICR0YWJsZSApIHsKCQkJCSRtYXliZV9wcmVmaXggPSBzdWJzdHIoICR0YWJsZSwgMCwgLSBzdHJsZW4oICdvcHRpb25zJyApICk7CgkJCQlpZiAoICRtYXliZV9wcmVmaXggIT09ICR0YWJsZV9wcmVmaXggKSB7CgkJCQkJJGZvdW5kX3ByZWZpeGVzW10gPSAkbWF5YmVfcHJlZml4OwoJCQkJfQoJCQl9CgkJfQoJCWlmICggY291bnQoICRmb3VuZF9wcmVmaXhlcyApICkgewoJCQkkcHJlZml4X2xpc3QgICA9IGltcGxvZGUoICcsICcsICRmb3VuZF9wcmVmaXhlcyApOwoJCQkkaW5zdGFsbF9sYWJlbCA9IGNvdW50KCAkZm91bmRfcHJlZml4ZXMgKSA+IDEgPyAnaW5zdGFsbGF0aW9ucycgOiAnaW5zdGFsbGF0aW9uJzsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJUaGUgc2l0ZSB5b3UgaGF2ZSByZXF1ZXN0ZWQgaXMgbm90IGluc3RhbGxlZC5cbiIgLgoJCQkJIllvdXIgdGFibGUgcHJlZml4IGlzICd7JHRhYmxlX3ByZWZpeH0nLiBGb3VuZCB7JGluc3RhbGxfbGFiZWx9IHdpdGggdGFibGUgcHJlZml4OiB7JHByZWZpeF9saXN0fS5cbiIgLgoJCQkJJ09yLCBydW4gYHdwIGNvcmUgaW5zdGFsbGAgdG8gY3JlYXRlIGRhdGFiYXNlIHRhYmxlcy4nCgkJCSk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJUaGUgc2l0ZSB5b3UgaGF2ZSByZXF1ZXN0ZWQgaXMgbm90IGluc3RhbGxlZC5cbiIgLgoJCQkJJ1J1biBgd3AgY29yZSBpbnN0YWxsYCB0byBjcmVhdGUgZGF0YWJhc2UgdGFibGVzLicKCQkJKTsKCQl9Cgl9Cn0KCi8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLlBIUC5JbmlTZXQgLS0gSW50ZW50aW9uYWwgJiBjb3JyZWN0IHVzYWdlLgpmdW5jdGlvbiB3cF9kZWJ1Z19tb2RlKCkgewoJaWYgKCBXUF9DTEk6OmdldF9jb25maWcoICdkZWJ1ZycgKSApIHsKCQlpZiAoICEgZGVmaW5lZCggJ1dQX0RFQlVHJyApICkgewoJCQlkZWZpbmUoICdXUF9ERUJVRycsIHRydWUgKTsKCQl9CgoJCWVycm9yX3JlcG9ydGluZyggRV9BTEwgJiB+RV9ERVBSRUNBVEVEICYgfkVfU1RSSUNUICk7Cgl9IGVsc2UgewoJCWlmICggV1BfREVCVUcgKSB7CgkJCWVycm9yX3JlcG9ydGluZyggRV9BTEwgKTsKCgkJCWlmICggV1BfREVCVUdfRElTUExBWSApIHsKCQkJCWluaV9zZXQoICdkaXNwbGF5X2Vycm9ycycsIDEgKTsKCQkJfSBlbHNlaWYgKCBudWxsICE9PSBXUF9ERUJVR19ESVNQTEFZICkgewoJCQkJaW5pX3NldCggJ2Rpc3BsYXlfZXJyb3JzJywgMCApOwoJCQl9CgoJCQlpZiAoIGluX2FycmF5KCBzdHJ0b2xvd2VyKCAoc3RyaW5nKSBXUF9ERUJVR19MT0cgKSwgWyAndHJ1ZScsICcxJyBdLCB0cnVlICkgKSB7CgkJCQkkbG9nX3BhdGggPSBXUF9DT05URU5UX0RJUiAuICcvZGVidWcubG9nJzsKCQkJfSBlbHNlaWYgKCBpc19zdHJpbmcoIFdQX0RFQlVHX0xPRyApICkgewoJCQkJJGxvZ19wYXRoID0gV1BfREVCVUdfTE9HOwoJCQl9IGVsc2UgewoJCQkJJGxvZ19wYXRoID0gZmFsc2U7CgkJCX0KCgkJCWlmICggZmFsc2UgIT09ICRsb2dfcGF0aCApIHsKCQkJCWluaV9zZXQoICdsb2dfZXJyb3JzJywgMSApOwoJCQkJaW5pX3NldCggJ2Vycm9yX2xvZycsICRsb2dfcGF0aCApOwoJCQl9CgkJfSBlbHNlIHsKCQkJZXJyb3JfcmVwb3J0aW5nKCBFX0NPUkVfRVJST1IgfCBFX0NPUkVfV0FSTklORyB8IEVfQ09NUElMRV9FUlJPUiB8IEVfRVJST1IgfCBFX1dBUk5JTkcgfCBFX1BBUlNFIHwgRV9VU0VSX0VSUk9SIHwgRV9VU0VSX1dBUk5JTkcgfCBFX1JFQ09WRVJBQkxFX0VSUk9SICk7CgkJfQoKCQlpZiAoIGRlZmluZWQoICdYTUxSUENfUkVRVUVTVCcgKSB8fCBkZWZpbmVkKCAnUkVTVF9SRVFVRVNUJyApIHx8ICggZGVmaW5lZCggJ0RPSU5HX0FKQVgnICkgJiYgRE9JTkdfQUpBWCApICkgewoJCQlpbmlfc2V0KCAnZGlzcGxheV9lcnJvcnMnLCAwICk7CgkJfQoJfQoKCS8vIFhEZWJ1ZyBhbHJlYWR5IHNlbmRzIGVycm9ycyB0byBTVERFUlIuCglpbmlfc2V0KCAnZGlzcGxheV9lcnJvcnMnLCBmdW5jdGlvbl9leGlzdHMoICd4ZGVidWdfZGVidWdfenZhbCcgKSA/IGZhbHNlIDogJ1NUREVSUicgKTsKfQovLyBwaHBjczplbmFibGUKCmZ1bmN0aW9uIHJlcGxhY2Vfd3BfZGllX2hhbmRsZXIoKSB7CglccmVtb3ZlX2ZpbHRlciggJ3dwX2RpZV9oYW5kbGVyJywgJ19kZWZhdWx0X3dwX2RpZV9oYW5kbGVyJyApOwoJXGFkZF9maWx0ZXIoCgkJJ3dwX2RpZV9oYW5kbGVyJywKCQlmdW5jdGlvbigpIHsKCQkJcmV0dXJuIF9fTkFNRVNQQUNFX18gLiAnXFx3cF9kaWVfaGFuZGxlcic7CgkJfQoJKTsKfQoKZnVuY3Rpb24gd3BfZGllX2hhbmRsZXIoICRtZXNzYWdlICkgewoJaWYgKCAkbWVzc2FnZSBpbnN0YW5jZW9mIFxXUF9FcnJvciApIHsKCQkkbWVzc2FnZSA9ICRtZXNzYWdlLT5nZXRfZXJyb3JfbWVzc2FnZSgpOwoJfQoKCSRtZXNzYWdlID0gd3BfY2xlYW5fZXJyb3JfbWVzc2FnZSggJG1lc3NhZ2UgKTsKCglXUF9DTEk6OmVycm9yKCAkbWVzc2FnZSApOwp9CgovKioKICogQ2xlYW4gSFRNTCBlcnJvciBtZXNzYWdlIHNvIHN1aXRhYmxlIGZvciB0ZXh0IGRpc3BsYXkuCiAqLwpmdW5jdGlvbiB3cF9jbGVhbl9lcnJvcl9tZXNzYWdlKCAkbWVzc2FnZSApIHsKCSRvcmlnaW5hbF9tZXNzYWdlID0gdHJpbSggJG1lc3NhZ2UgKTsKCSRtZXNzYWdlICAgICAgICAgID0gJG9yaWdpbmFsX21lc3NhZ2U7CglpZiAoIHByZWdfbWF0Y2goICd8Xlw8aDE+KC4rPyk8L2gxPnwnLCAkb3JpZ2luYWxfbWVzc2FnZSwgJG1hdGNoZXMgKSApIHsKCQkkbWVzc2FnZSA9ICRtYXRjaGVzWzFdIC4gJy4nOwoJfQoJaWYgKCBwcmVnX21hdGNoKCAnfFw8cD4oLis/KTwvcD58JywgJG9yaWdpbmFsX21lc3NhZ2UsICRtYXRjaGVzICkgKSB7CgkJJG1lc3NhZ2UgLj0gJyAnIC4gJG1hdGNoZXNbMV07Cgl9CgoJJHNlYXJjaF9yZXBsYWNlID0gWwoJCSc8Y29kZT4nICA9PiAnYCcsCgkJJzwvY29kZT4nID0+ICdgJywKCV07CgkkbWVzc2FnZSAgICAgICAgPSBzdHJfcmVwbGFjZSggYXJyYXlfa2V5cyggJHNlYXJjaF9yZXBsYWNlICksIGFycmF5X3ZhbHVlcyggJHNlYXJjaF9yZXBsYWNlICksICRtZXNzYWdlICk7CgkkbWVzc2FnZSAgICAgICAgPSBuYW1lc3BhY2Vcc3RyaXBfdGFncyggJG1lc3NhZ2UgKTsKCSRtZXNzYWdlICAgICAgICA9IGh0bWxfZW50aXR5X2RlY29kZSggJG1lc3NhZ2UsIEVOVF9DT01QQVQsICdVVEYtOCcgKTsKCglyZXR1cm4gJG1lc3NhZ2U7Cn0KCmZ1bmN0aW9uIHdwX3JlZGlyZWN0X2hhbmRsZXIoICR1cmwgKSB7CglXUF9DTEk6Ondhcm5pbmcoICdTb21lIGNvZGUgaXMgdHJ5aW5nIHRvIGRvIGEgVVJMIHJlZGlyZWN0LiBCYWNrdHJhY2U6JyApOwoKCW9iX3N0YXJ0KCk7CglkZWJ1Z19wcmludF9iYWNrdHJhY2UoKTsKCWZ3cml0ZSggU1RERVJSLCBvYl9nZXRfY2xlYW4oKSApOwoKCXJldHVybiAkdXJsOwp9CgpmdW5jdGlvbiBtYXliZV9yZXF1aXJlKCAkc2luY2UsICRwYXRoICkgewoJaWYgKCB3cF92ZXJzaW9uX2NvbXBhcmUoICRzaW5jZSwgJz49JyApICkgewoJCXJlcXVpcmUgJHBhdGg7Cgl9Cn0KCmZ1bmN0aW9uIGdldF91cGdyYWRlciggJGNsYXNzLCAkaW5zZWN1cmUgPSBmYWxzZSApIHsKCWlmICggISBjbGFzc19leGlzdHMoICdcV1BfVXBncmFkZXInICkgKSB7CgkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvY2xhc3Mtd3AtdXBncmFkZXIucGhwJzsKCX0KCgkkdXNlc19pbnNlY3VyZV9mbGFnID0gZmFsc2U7CgoJJHJlZmxlY3Rpb24gPSBuZXcgUmVmbGVjdGlvbkNsYXNzKCAkY2xhc3MgKTsKCWlmICggJHJlZmxlY3Rpb24gKSB7CgkJJGNvbnN0cnVjdG9yID0gJHJlZmxlY3Rpb24tPmdldENvbnN0cnVjdG9yKCk7CgkJaWYgKCAkY29uc3RydWN0b3IgKSB7CgkJCSRhcmd1bWVudHMgPSAkY29uc3RydWN0b3ItPmdldFBhcmFtZXRlcnMoKTsKCQkJLyoqIEB2YXIgUmVmbGVjdGlvblBhcmFtZXRlciAkYXJndW1lbnQgKi8KCQkJZm9yZWFjaCAoICRhcmd1bWVudHMgYXMgJGFyZ3VtZW50ICkgewoJCQkJaWYgKCAnaW5zZWN1cmUnID09PSAkYXJndW1lbnQtPm5hbWUgKSB7CgkJCQkJJHVzZXNfaW5zZWN1cmVfZmxhZyA9IHRydWU7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJaWYgKCAkdXNlc19pbnNlY3VyZV9mbGFnICkgewoJCXJldHVybiBuZXcgJGNsYXNzKCBuZXcgVXBncmFkZXJTa2luKCksICRpbnNlY3VyZSApOwoJfSBlbHNlIHsKCQlyZXR1cm4gbmV3ICRjbGFzcyggbmV3IFVwZ3JhZGVyU2tpbigpICk7Cgl9Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHBsdWdpbiBiYXNlbmFtZSBiYWNrIGludG8gYSBmcmllbmRseSBzbHVnLgogKi8KZnVuY3Rpb24gZ2V0X3BsdWdpbl9uYW1lKCAkYmFzZW5hbWUgKSB7CglpZiAoIGZhbHNlID09PSBzdHJwb3MoICRiYXNlbmFtZSwgJy8nICkgKSB7CgkJJG5hbWUgPSBiYXNlbmFtZSggJGJhc2VuYW1lLCAnLnBocCcgKTsKCX0gZWxzZSB7CgkJJG5hbWUgPSBkaXJuYW1lKCAkYmFzZW5hbWUgKTsKCX0KCglyZXR1cm4gJG5hbWU7Cn0KCmZ1bmN0aW9uIGlzX3BsdWdpbl9za2lwcGVkKCAkZmlsZSApIHsKCSRuYW1lID0gZ2V0X3BsdWdpbl9uYW1lKCBzdHJfcmVwbGFjZSggV1BfUExVR0lOX0RJUiAuICcvJywgJycsICRmaWxlICkgKTsKCgkkc2tpcHBlZF9wbHVnaW5zID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1snc2tpcC1wbHVnaW5zJ107CglpZiAoIHRydWUgPT09ICRza2lwcGVkX3BsdWdpbnMgKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoJaWYgKCAhIGlzX2FycmF5KCAkc2tpcHBlZF9wbHVnaW5zICkgKSB7CgkJJHNraXBwZWRfcGx1Z2lucyA9IGV4cGxvZGUoICcsJywgJHNraXBwZWRfcGx1Z2lucyApOwoJfQoKCXJldHVybiBpbl9hcnJheSggJG5hbWUsIGFycmF5X2ZpbHRlciggJHNraXBwZWRfcGx1Z2lucyApLCB0cnVlICk7Cn0KCmZ1bmN0aW9uIGdldF90aGVtZV9uYW1lKCAkcGF0aCApIHsKCXJldHVybiBiYXNlbmFtZSggJHBhdGggKTsKfQoKZnVuY3Rpb24gaXNfdGhlbWVfc2tpcHBlZCggJHBhdGggKSB7CgkkbmFtZSA9IGdldF90aGVtZV9uYW1lKCAkcGF0aCApOwoKCSRza2lwcGVkX3RoZW1lcyA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5jb25maWdbJ3NraXAtdGhlbWVzJ107CglpZiAoIHRydWUgPT09ICRza2lwcGVkX3RoZW1lcyApIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglpZiAoICEgaXNfYXJyYXkoICRza2lwcGVkX3RoZW1lcyApICkgewoJCSRza2lwcGVkX3RoZW1lcyA9IGV4cGxvZGUoICcsJywgJHNraXBwZWRfdGhlbWVzICk7Cgl9CgoJcmV0dXJuIGluX2FycmF5KCAkbmFtZSwgYXJyYXlfZmlsdGVyKCAkc2tpcHBlZF90aGVtZXMgKSwgdHJ1ZSApOwp9CgovKioKICogUmVnaXN0ZXIgdGhlIHNpZGViYXIgZm9yIHVudXNlZCB3aWRnZXRzLgogKiBDb3JlIGRvZXMgdGhpcyBpbiAvd3AtYWRtaW4vd2lkZ2V0cy5waHAsIHdoaWNoIGlzbid0IGhlbHBmdWwuCiAqLwpmdW5jdGlvbiB3cF9yZWdpc3Rlcl91bnVzZWRfc2lkZWJhcigpIHsKCglyZWdpc3Rlcl9zaWRlYmFyKAoJCVsKCQkJJ25hbWUnICAgICAgICAgID0+IF9fKCAnSW5hY3RpdmUgV2lkZ2V0cycgKSwKCQkJJ2lkJyAgICAgICAgICAgID0+ICd3cF9pbmFjdGl2ZV93aWRnZXRzJywKCQkJJ2NsYXNzJyAgICAgICAgID0+ICdpbmFjdGl2ZS1zaWRlYmFyJywKCQkJJ2Rlc2NyaXB0aW9uJyAgID0+IF9fKCAnRHJhZyB3aWRnZXRzIGhlcmUgdG8gcmVtb3ZlIHRoZW0gZnJvbSB0aGUgc2lkZWJhciBidXQga2VlcCB0aGVpciBzZXR0aW5ncy4nICksCgkJCSdiZWZvcmVfd2lkZ2V0JyA9PiAnJywKCQkJJ2FmdGVyX3dpZGdldCcgID0+ICcnLAoJCQknYmVmb3JlX3RpdGxlJyAgPT4gJycsCgkJCSdhZnRlcl90aXRsZScgICA9PiAnJywKCQldCgkpOwoKfQoKLyoqCiAqIEF0dGVtcHRzIHRvIGRldGVybWluZSB3aGljaCBvYmplY3QgY2FjaGUgaXMgYmVpbmcgdXNlZC4KICoKICogTm90ZSB0aGF0IHRoZSBndWVzc2VzIG1hZGUgYnkgdGhpcyBmdW5jdGlvbiBhcmUgYmFzZWQgb24gdGhlIFdQX09iamVjdF9DYWNoZSBjbGFzc2VzCiAqIHRoYXQgZGVmaW5lIHRoZSAzcmQgcGFydHkgb2JqZWN0IGNhY2hlIGV4dGVuc2lvbi4gQ2hhbmdlcyB0byB0aG9zZSBjbGFzc2VzIGNvdWxkIHJlbmRlcgogKiBwcm9ibGVtcyB3aXRoIHRoaXMgZnVuY3Rpb24ncyBhYmlsaXR5IHRvIGRldGVybWluZSB3aGljaCBvYmplY3QgY2FjaGUgaXMgYmVpbmcgdXNlZC4KICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIHdwX2dldF9jYWNoZV90eXBlKCkgewoJZ2xvYmFsICRfd3BfdXNpbmdfZXh0X29iamVjdF9jYWNoZSwgJHdwX29iamVjdF9jYWNoZTsKCglpZiAoICEgZW1wdHkoICRfd3BfdXNpbmdfZXh0X29iamVjdF9jYWNoZSApICkgewoJCS8vIFRlc3QgZm9yIE1lbWNhY2hlZCBQRUNMIGV4dGVuc2lvbiBtZW1jYWNoZWQgb2JqZWN0IGNhY2hlIChodHRwczovL2dpdGh1Yi5jb20vdG9sbG1hbnovd29yZHByZXNzLW1lbWNhY2hlZC1iYWNrZW5kKQoJCWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPm0gKSAmJiAkd3Bfb2JqZWN0X2NhY2hlLT5tIGluc3RhbmNlb2YgXE1lbWNhY2hlZCApIHsKCQkJJG1lc3NhZ2UgPSAnTWVtY2FjaGVkJzsKCgkJCS8vIFRlc3QgZm9yIE1lbWNhY2hlIFBFQ0wgZXh0ZW5zaW9uIG1lbWNhY2hlZCBvYmplY3QgY2FjaGUgKGh0dHBzOi8vd29yZHByZXNzLm9yZy9leHRlbmQvcGx1Z2lucy9tZW1jYWNoZWQvKQoJCX0gZWxzZWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPm1jICkgKSB7CgkJCSRpc19tZW1jYWNoZSA9IHRydWU7CgkJCWZvcmVhY2ggKCAkd3Bfb2JqZWN0X2NhY2hlLT5tYyBhcyAkYnVja2V0ICkgewoJCQkJaWYgKCAhICRidWNrZXQgaW5zdGFuY2VvZiBcTWVtY2FjaGUgJiYgISAkYnVja2V0IGluc3RhbmNlb2YgXE1lbWNhY2hlZCApIHsKCQkJCQkkaXNfbWVtY2FjaGUgPSBmYWxzZTsKCQkJCX0KCQkJfQoKCQkJaWYgKCAkaXNfbWVtY2FjaGUgKSB7CgkJCQkkbWVzc2FnZSA9ICdNZW1jYWNoZSc7CgkJCX0KCgkJCS8vIFRlc3QgZm9yIFhjYWNoZSBvYmplY3QgY2FjaGUgKGh0dHBzOi8vcGx1Z2lucy5zdm4ud29yZHByZXNzLm9yZy94Y2FjaGUvdHJ1bmsvb2JqZWN0LWNhY2hlLnBocCkKCQl9IGVsc2VpZiAoICR3cF9vYmplY3RfY2FjaGUgaW5zdGFuY2VvZiBcWENhY2hlX09iamVjdF9DYWNoZSApIHsKCQkJJG1lc3NhZ2UgPSAnWGNhY2hlJzsKCgkJCS8vIFRlc3QgZm9yIFdpbkNhY2hlIG9iamVjdCBjYWNoZSAoaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2V4dGVuZC9wbHVnaW5zL3dpbmNhY2hlLW9iamVjdC1jYWNoZS1iYWNrZW5kLykKCQl9IGVsc2VpZiAoIGNsYXNzX2V4aXN0cyggJ1dpbkNhY2hlX09iamVjdF9DYWNoZScgKSApIHsKCQkJJG1lc3NhZ2UgPSAnV2luQ2FjaGUnOwoKCQkJLy8gVGVzdCBmb3IgQVBDIG9iamVjdCBjYWNoZSAoaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2V4dGVuZC9wbHVnaW5zL2FwYy8pCgkJfSBlbHNlaWYgKCBjbGFzc19leGlzdHMoICdBUENfT2JqZWN0X0NhY2hlJyApICkgewoJCQkkbWVzc2FnZSA9ICdBUEMnOwoKCQkJLy8gVGVzdCBmb3IgV1AgUmVkaXMgKGh0dHBzOi8vd29yZHByZXNzLm9yZy9wbHVnaW5zL3dwLXJlZGlzLykKCQl9IGVsc2VpZiAoIGlzc2V0KCAkd3Bfb2JqZWN0X2NhY2hlLT5yZWRpcyApICYmICR3cF9vYmplY3RfY2FjaGUtPnJlZGlzIGluc3RhbmNlb2YgXFJlZGlzICkgewoJCQkkbWVzc2FnZSA9ICdSZWRpcyc7CgoJCQkvLyBUZXN0IGZvciBSZWRpcyBPYmplY3QgQ2FjaGUgKGh0dHBzOi8vd29yZHByZXNzLm9yZy9wbHVnaW5zL3JlZGlzLWNhY2hlLykKCQl9IGVsc2VpZiAoIG1ldGhvZF9leGlzdHMoICR3cF9vYmplY3RfY2FjaGUsICdyZWRpc19pbnN0YW5jZScgKSAmJiBtZXRob2RfZXhpc3RzKCAkd3Bfb2JqZWN0X2NhY2hlLCAncmVkaXNfc3RhdHVzJyApICkgewoJCQkkbWVzc2FnZSA9ICdSZWRpcyc7CgoJCQkvLyBUZXN0IGZvciBXUCBMQ2FjaGUgT2JqZWN0IGNhY2hlIChodHRwczovL2dpdGh1Yi5jb20vbGNhY2hlL3dwLWxjYWNoZSkKCQl9IGVsc2VpZiAoIGlzc2V0KCAkd3Bfb2JqZWN0X2NhY2hlLT5sY2FjaGUgKSAmJiAkd3Bfb2JqZWN0X2NhY2hlLT5sY2FjaGUgaW5zdGFuY2VvZiBcTENhY2hlXEludGVncmF0ZWQgKSB7CgkJCSRtZXNzYWdlID0gJ1dQIExDYWNoZSc7CgoJCX0gZWxzZWlmICggZnVuY3Rpb25fZXhpc3RzKCAndzNfaW5zdGFuY2UnICkgKSB7CgkJCSRjb25maWcgID0gdzNfaW5zdGFuY2UoICdXM19Db25maWcnICk7CgkJCSRtZXNzYWdlID0gJ1Vua25vd24nOwoKCQkJaWYgKCAkY29uZmlnLT5nZXRfYm9vbGVhbiggJ29iamVjdGNhY2hlLmVuYWJsZWQnICkgKSB7CgkJCQkkbWVzc2FnZSA9ICdXM1RDICcgLiAkY29uZmlnLT5nZXRfc3RyaW5nKCAnb2JqZWN0Y2FjaGUuZW5naW5lJyApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJG1lc3NhZ2UgPSAnVW5rbm93bic7CgkJfQoJfSBlbHNlIHsKCQkkbWVzc2FnZSA9ICdEZWZhdWx0JzsKCX0KCXJldHVybiAkbWVzc2FnZTsKfQoKLyoqCiAqIENsZWFyIFdvcmRQcmVzcyBpbnRlcm5hbCBvYmplY3QgY2FjaGVzLgogKgogKiBJbiBsb25nLXJ1bm5pbmcgc2NyaXB0cywgdGhlIGludGVybmFsIGNhY2hlcyBvbiBgJHdwX29iamVjdF9jYWNoZWAgYW5kIGAkd3BkYmAKICogY2FuIGdyb3cgdG8gY29uc3VtZSBnaWdhYnl0ZXMgb2YgbWVtb3J5LiBQZXJpb2RpY2FsbHkgY2FsbGluZyB0aGlzIHV0aWxpdHkKICogY2FuIGhlbHAgd2l0aCBtZW1vcnkgbWFuYWdlbWVudC4KICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IFN5c3RlbQogKiBAZGVwcmVjYXRlZCAxLjUuMAogKi8KZnVuY3Rpb24gd3BfY2xlYXJfb2JqZWN0X2NhY2hlKCkgewoJZ2xvYmFsICR3cGRiLCAkd3Bfb2JqZWN0X2NhY2hlOwoKCSR3cGRiLT5xdWVyaWVzID0gW107CgoJaWYgKCAhIGlzX29iamVjdCggJHdwX29iamVjdF9jYWNoZSApICkgewoJCXJldHVybjsKCX0KCgkvLyBUaGUgZm9sbG93aW5nIGFyZSBNZW1jYWNoZWQgKFJlZHV4KSBwbHVnaW4gc3BlY2lmaWMgKHNlZSBodHRwczovL2NvcmUudHJhYy53b3JkcHJlc3Mub3JnL3RpY2tldC8zMTQ2MykuCglpZiAoIGlzc2V0KCAkd3Bfb2JqZWN0X2NhY2hlLT5ncm91cF9vcHMgKSApIHsKCQkkd3Bfb2JqZWN0X2NhY2hlLT5ncm91cF9vcHMgPSBbXTsKCX0KCWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPnN0YXRzICkgKSB7CgkJJHdwX29iamVjdF9jYWNoZS0+c3RhdHMgPSBbXTsKCX0KCWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPm1lbWNhY2hlX2RlYnVnICkgKSB7CgkJJHdwX29iamVjdF9jYWNoZS0+bWVtY2FjaGVfZGVidWcgPSBbXTsKCX0KCS8vIFVzZWQgYnkgYFdQX09iamVjdF9DYWNoZWAgYWxzby4KCWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPmNhY2hlICkgKSB7CgkJJHdwX29iamVjdF9jYWNoZS0+Y2FjaGUgPSBbXTsKCX0KfQoKLyoqCiAqIEdldCBhIHNldCBvZiB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlLgogKgogKiBJbnRlcnByZXRzIGNvbW1vbiBjb21tYW5kLWxpbmUgb3B0aW9ucyBpbnRvIGEgcmVzb2x2ZWQgc2V0IG9mIHRhYmxlIG5hbWVzLgogKgogKiBAcGFyYW0gYXJyYXkgJGFyZ3MgUHJvdmlkZWQgdGFibGUgbmFtZXMsIG9yIHRhYmxlcyB3aXRoIHdpbGRjYXJkcy4KICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIE9wdGlvbmFsIGZsYWdzIGZvciBncm91cHMgb2YgdGFibGVzIChlLmcuIC0tbmV0d29yaykKICogQHJldHVybiBhcnJheQogKi8KZnVuY3Rpb24gd3BfZ2V0X3RhYmxlX25hbWVzKCAkYXJncywgJGFzc29jX2FyZ3MgPSBbXSApIHsKCWdsb2JhbCAkd3BkYjsKCgkkdGFibGVzID0gW107CgoJLy8gQWJvcnQgaWYgaW5jb21wYXRpYmxlIGFyZ3Mgc3VwcGxpZWQuCglpZiAoIGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Jhc2UtdGFibGVzLW9ubHknICkgJiYgZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndmlld3Mtb25seScgKSApIHsKCQlXUF9DTEk6OmVycm9yKCAnWW91IGNhbm5vdCBzdXBwbHkgLS1iYXNlLXRhYmxlcy1vbmx5IGFuZCAtLXZpZXdzLW9ubHkgYXQgdGhlIHNhbWUgdGltZS4nICk7Cgl9CgoJLy8gUHJlLWxvYWQgdGFibGVzIFNRTCBxdWVyeSB3aXRoIFZpZXdzIHJlc3RyaWN0aW9uIGlmIG5lZWRlZC4KCWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYmFzZS10YWJsZXMtb25seScgKSApIHsKCQkkdGFibGVzX3NxbCA9ICdTSE9XIEZVTEwgVEFCTEVTIFdIRVJFIFRhYmxlX1R5cGUgPSAiQkFTRSBUQUJMRSInOwoKCX0gZWxzZWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndmlld3Mtb25seScgKSApIHsKCQkkdGFibGVzX3NxbCA9ICdTSE9XIEZVTEwgVEFCTEVTIFdIRVJFIFRhYmxlX1R5cGUgPSAiVklFVyInOwoKCX0KCglpZiAoIGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbC10YWJsZXMnICkgKSB7CgkJaWYgKCBlbXB0eSggJHRhYmxlc19zcWwgKSApIHsKCQkJJHRhYmxlc19zcWwgPSAnU0hPVyBUQUJMRVMnOwoJCX0KCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5Ob3RQcmVwYXJlZCAtLSBRdWVyeSBpcyBzYWZlLCBzZWUgYWJvdmUuCgkJJHRhYmxlcyA9ICR3cGRiLT5nZXRfY29sKCAkdGFibGVzX3NxbCwgMCApOwoKCX0gZWxzZWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsLXRhYmxlcy13aXRoLXByZWZpeCcgKSApIHsKCQlpZiAoIGVtcHR5KCAkdGFibGVzX3NxbCApICkgewoJCQkkdGFibGVzX3NxbCA9ICR3cGRiLT5wcmVwYXJlKCAnU0hPVyBUQUJMRVMgTElLRSAlcycsIGVzY19saWtlKCAkd3BkYi0+Z2V0X2Jsb2dfcHJlZml4KCkgKSAuICclJyApOwoJCX0gZWxzZSB7CgkJCSR0YWJsZXNfc3FsIC49IHNwcmludGYoICIgQU5EICVzIExJS0UgJyVzJyIsIGVzY19zcWxfaWRlbnQoICdUYWJsZXNfaW5fJyAuICR3cGRiLT5kYm5hbWUgKSwgZXNjX2xpa2UoICR3cGRiLT5nZXRfYmxvZ19wcmVmaXgoKSApIC4gJyUnICk7CgkJfQoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIFF1ZXJ5IGlzIHByZXBhcmVkLCBzZWUgYWJvdmUuCgkJJHRhYmxlcyA9ICR3cGRiLT5nZXRfY29sKCAkdGFibGVzX3NxbCwgMCApOwoKCX0gZWxzZSB7CgkJJHNjb3BlID0gZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2NvcGUnLCAnYWxsJyApOwoKCQkvLyBOb3RlOiBCQyBjaGFuZ2UgMS41LjAsIHRha2luZyBzY29wZSBpbnRvIGNvbnNpZGVyYXRpb24gZm9yIG5ldHdvcmsgYWxzby4KCQlpZiAoIGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICkgJiYgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRuZXR3b3JrX2dsb2JhbF9zY29wZSA9IGluX2FycmF5KCAkc2NvcGUsIFsgJ2FsbCcsICdnbG9iYWwnLCAnbXNfZ2xvYmFsJyBdLCB0cnVlICkgPyAoICdhbGwnID09PSAkc2NvcGUgPyAnZ2xvYmFsJyA6ICRzY29wZSApIDogJyc7CgkJCSR3cF90YWJsZXMgICAgICAgICAgICA9IGFycmF5X3ZhbHVlcyggJHdwZGItPnRhYmxlcyggJG5ldHdvcmtfZ2xvYmFsX3Njb3BlICkgKTsKCQkJaWYgKCBpbl9hcnJheSggJHNjb3BlLCBbICdhbGwnLCAnYmxvZycgXSwgdHJ1ZSApICkgewoJCQkJLy8gRG8gZGlyZWN0bHkgZm9yIGNvbXBhdCB3aXRoIG9sZCBXUCB2ZXJzaW9ucy4gTm90ZTogcHJpdmF0ZSwgZGVsZXRlZCwgYXJjaGl2ZWQgc2l0ZXMgYXJlIG5vdCBleGNsdWRlZC4KCQkJCSRibG9nX2lkcyA9ICR3cGRiLT5nZXRfY29sKCAiU0VMRUNUIGJsb2dfaWQgRlJPTSAkd3BkYi0+YmxvZ3MgV0hFUkUgc2l0ZV9pZCA9ICR3cGRiLT5zaXRlaWQiICk7CgkJCQlmb3JlYWNoICggJGJsb2dfaWRzIGFzICRibG9nX2lkICkgewoJCQkJCSR3cF90YWJsZXMgPSBhcnJheV9tZXJnZSggJHdwX3RhYmxlcywgYXJyYXlfdmFsdWVzKCAkd3BkYi0+dGFibGVzKCAnYmxvZycsIHRydWUgLypwcmVmaXgqLywgJGJsb2dfaWQgKSApICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQkkd3BfdGFibGVzID0gYXJyYXlfdmFsdWVzKCAkd3BkYi0+dGFibGVzKCAkc2NvcGUgKSApOwoJCX0KCgkJaWYgKCAhIGdsb2JhbF90ZXJtc19lbmFibGVkKCkgKSB7CgkJCS8vIE9ubHkgaW5jbHVkZSBzaXRlY2F0ZWdvcmllcyB3aGVuIGl0J3MgYWN0dWFsbHkgZW5hYmxlZC4KCQkJJHdwX3RhYmxlcyA9IGFycmF5X3ZhbHVlcyggYXJyYXlfZGlmZiggJHdwX3RhYmxlcywgWyAkd3BkYi0+c2l0ZWNhdGVnb3JpZXMgXSApICk7CgkJfQoKCQkvLyBOb3RlOiBCQyBjaGFuZ2UgMS41LjAsIHRhYmxlcyBhcmUgc29ydGVkICh2aWEgVEFCTEVTIHZpZXcpLgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gdXNlcyBlc2Nfc3FsX2lkZW50KCkgYW5kICR3cGRiLT5fZXNjYXBlKCkuCgkJJHRhYmxlcyA9ICR3cGRiLT5nZXRfY29sKCBzcHJpbnRmKCAiU0hPVyBUQUJMRVMgV0hFUkUgJXMgSU4gKCclcycpIiwgZXNjX3NxbF9pZGVudCggJ1RhYmxlc19pbl8nIC4gJHdwZGItPmRibmFtZSApLCBpbXBsb2RlKCAiJywgJyIsICR3cGRiLT5fZXNjYXBlKCAkd3BfdGFibGVzICkgKSApICk7CgoJCWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYmFzZS10YWJsZXMtb25seScgKSB8fCBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2aWV3cy1vbmx5JyApICkgewoJCQkvLyBBcHBseSBWaWV3cyByZXN0cmljdGlvbiBhcmdzIGlmIG5lZWRlZC4KCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5Ob3RQcmVwYXJlZCAtLSBRdWVyeSBpcyBwcmVwYXJlZCwgc2VlIGFib3ZlLgoJCQkkdmlld3NfcXVlcnlfdGFibGVzID0gJHdwZGItPmdldF9jb2woICR0YWJsZXNfc3FsLCAwICk7CgkJCSR0YWJsZXMgICAgICAgICAgICAgPSBhcnJheV9pbnRlcnNlY3QoICR0YWJsZXMsICR2aWV3c19xdWVyeV90YWJsZXMgKTsKCQl9Cgl9CgoJLy8gRmlsdGVyIGJ5IGAkYXJnc2AuCglpZiAoICRhcmdzICkgewoJCSRhcmdzX3RhYmxlcyA9IFtdOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkYXJnICkgewoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICRhcmcsICcqJyApIHx8IGZhbHNlICE9PSBzdHJwb3MoICRhcmcsICc/JyApICkgewoJCQkJJGFyZ3NfdGFibGVzID0gYXJyYXlfbWVyZ2UoCgkJCQkJJGFyZ3NfdGFibGVzLAoJCQkJCWFycmF5X2ZpbHRlcigKCQkJCQkJJHRhYmxlcywKCQkJCQkJZnVuY3Rpb24gKCAkdiApIHVzZSAoICRhcmcgKSB7CgkJCQkJCQlyZXR1cm4gZm5tYXRjaCggJGFyZywgJHYgKTsKCQkJCQkJfQoJCQkJCSkKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQkkYXJnc190YWJsZXNbXSA9ICRhcmc7CgkJCX0KCQl9CgkJJGFyZ3NfdGFibGVzID0gYXJyYXlfdmFsdWVzKCBhcnJheV91bmlxdWUoICRhcmdzX3RhYmxlcyApICk7CgkJJHRhYmxlcyAgICAgID0gYXJyYXlfdmFsdWVzKCBhcnJheV9pbnRlcnNlY3QoICR0YWJsZXMsICRhcmdzX3RhYmxlcyApICk7CgkJaWYgKCBlbXB0eSggJHRhYmxlcyApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiQ291bGRuJ3QgZmluZCBhbnkgdGFibGVzIG1hdGNoaW5nOiAlcyIsIGltcGxvZGUoICcgJywgJGFyZ3MgKSApICk7CgkJfQoJfQoKCXJldHVybiAkdGFibGVzOwp9CgovKioKICogRmFpbHNhZmUgdXNlIG9mIHRoZSBXb3JkUHJlc3Mgd3Bfc3RyaXBfYWxsX3RhZ3MoKSBmdW5jdGlvbi4KICoKICogQXV0b21hdGljYWxseSBmYWxscyBiYWNrIHRvIHN0cmlwX3RhZ3MoKSBmdW5jdGlvbiBpZiB0aGUgV1AgZnVuY3Rpb24gaXMgbm90CiAqIGF2YWlsYWJsZS4KICoKICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFN0cmluZyB0byBzdHJpcCB0aGUgdGFncyBmcm9tLgogKiBAcmV0dXJuIHN0cmluZyBTdHJpbmcgZGV2b2lkIG9mIHRhZ3MuCiAqLwpmdW5jdGlvbiBzdHJpcF90YWdzKCAkc3RyaW5nICkgewoJaWYgKCBmdW5jdGlvbl9leGlzdHMoICd3cF9zdHJpcF9hbGxfdGFncycgKSApIHsKCQlyZXR1cm4gXHdwX3N0cmlwX2FsbF90YWdzKCAkc3RyaW5nICk7Cgl9CgoJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgKCQknQDwoc2NyaXB0fHN0eWxlKVtePl0qPz4uKj88L1xcMT5Ac2knLAoJCScnLAoJCSRzdHJpbmcKCSk7CgoJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5zdHJpcF90YWdzX3N0cmlwX3RhZ3MgLS0gRmFsbGJhY2suCgkkc3RyaW5nID0gXHN0cmlwX3RhZ3MoICRzdHJpbmcgKTsKCglyZXR1cm4gdHJpbSggJHN0cmluZyApOwp9Cjw/cGhwCgovKioKICogQ29waWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3JhbXNleS9hcnJheV9jb2x1bW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqCiAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSBCZW4gUmFtc2V5IChodHRwczovL2JlbnJhbXNleS5jb20pCiAqIEBsaWNlbnNlIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVAogKgogKiBAcGhwY3M6ZGlzYWJsZSAtLSBDb2RlIGZyb20gZXh0ZXJuYWwgc291cmNlLiBMZWZ0IGFzLWlzIGZvciBlYXNpZXIgY29tcGFyZS4KICovCmlmICghZnVuY3Rpb25fZXhpc3RzKCdhcnJheV9jb2x1bW4nKSkgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZXMgZnJvbSBhIHNpbmdsZSBjb2x1bW4gb2YgdGhlIGlucHV0IGFycmF5LCBpZGVudGlmaWVkIGJ5CiAgICAgKiB0aGUgJGNvbHVtbktleS4KICAgICAqCiAgICAgKiBPcHRpb25hbGx5LCB5b3UgbWF5IHByb3ZpZGUgYW4gJGluZGV4S2V5IHRvIGluZGV4IHRoZSB2YWx1ZXMgaW4gdGhlIHJldHVybmVkCiAgICAgKiBhcnJheSBieSB0aGUgdmFsdWVzIGZyb20gdGhlICRpbmRleEtleSBjb2x1bW4gaW4gdGhlIGlucHV0IGFycmF5LgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkaW5wdXQgQSBtdWx0aS1kaW1lbnNpb25hbCBhcnJheSAocmVjb3JkIHNldCkgZnJvbSB3aGljaCB0byBwdWxsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIGEgY29sdW1uIG9mIHZhbHVlcy4KICAgICAqIEBwYXJhbSBtaXhlZCAkY29sdW1uS2V5IFRoZSBjb2x1bW4gb2YgdmFsdWVzIHRvIHJldHVybi4gVGhpcyB2YWx1ZSBtYXkgYmUgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlZ2VyIGtleSBvZiB0aGUgY29sdW1uIHlvdSB3aXNoIHRvIHJldHJpZXZlLCBvciBpdAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgbWF5IGJlIHRoZSBzdHJpbmcga2V5IG5hbWUgZm9yIGFuIGFzc29jaWF0aXZlIGFycmF5LgogICAgICogQHBhcmFtIG1peGVkICRpbmRleEtleSAoT3B0aW9uYWwuKSBUaGUgY29sdW1uIHRvIHVzZSBhcyB0aGUgaW5kZXgva2V5cyBmb3IKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHJldHVybmVkIGFycmF5LiBUaGlzIHZhbHVlIG1heSBiZSB0aGUgaW50ZWdlciBrZXkKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIGNvbHVtbiwgb3IgaXQgbWF5IGJlIHRoZSBzdHJpbmcga2V5IG5hbWUuCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIGZ1bmN0aW9uIGFycmF5X2NvbHVtbigkaW5wdXQgPSBudWxsLCAkY29sdW1uS2V5ID0gbnVsbCwgJGluZGV4S2V5ID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBVc2luZyBmdW5jX2dldF9hcmdzKCkgaW4gb3JkZXIgdG8gY2hlY2sgZm9yIHByb3BlciBudW1iZXIgb2YKICAgICAgICAvLyBwYXJhbWV0ZXJzIGFuZCB0cmlnZ2VyIGVycm9ycyBleGFjdGx5IGFzIHRoZSBidWlsdC1pbiBhcnJheV9jb2x1bW4oKQogICAgICAgIC8vIGRvZXMgaW4gUEhQIDUuNS4KICAgICAgICAkYXJnYyA9IGZ1bmNfbnVtX2FyZ3MoKTsKICAgICAgICAkcGFyYW1zID0gZnVuY19nZXRfYXJncygpOwoKICAgICAgICBpZiAoJGFyZ2MgPCAyKSB7CiAgICAgICAgICAgIHRyaWdnZXJfZXJyb3IoImFycmF5X2NvbHVtbigpIGV4cGVjdHMgYXQgbGVhc3QgMiBwYXJhbWV0ZXJzLCB7JGFyZ2N9IGdpdmVuIiwgRV9VU0VSX1dBUk5JTkcpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICghaXNfYXJyYXkoJHBhcmFtc1swXSkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcigKICAgICAgICAgICAgICAgICdhcnJheV9jb2x1bW4oKSBleHBlY3RzIHBhcmFtZXRlciAxIHRvIGJlIGFycmF5LCAnIC4gZ2V0dHlwZSgkcGFyYW1zWzBdKSAuICcgZ2l2ZW4nLAogICAgICAgICAgICAgICAgRV9VU0VSX1dBUk5JTkcKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX2ludCgkcGFyYW1zWzFdKQogICAgICAgICAgICAmJiAhaXNfZmxvYXQoJHBhcmFtc1sxXSkKICAgICAgICAgICAgJiYgIWlzX3N0cmluZygkcGFyYW1zWzFdKQogICAgICAgICAgICAmJiAkcGFyYW1zWzFdICE9PSBudWxsCiAgICAgICAgICAgICYmICEoaXNfb2JqZWN0KCRwYXJhbXNbMV0pICYmIG1ldGhvZF9leGlzdHMoJHBhcmFtc1sxXSwgJ19fdG9TdHJpbmcnKSkKICAgICAgICApIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignYXJyYXlfY29sdW1uKCk6IFRoZSBjb2x1bW4ga2V5IHNob3VsZCBiZSBlaXRoZXIgYSBzdHJpbmcgb3IgYW4gaW50ZWdlcicsIEVfVVNFUl9XQVJOSU5HKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRwYXJhbXNbMl0pCiAgICAgICAgICAgICYmICFpc19pbnQoJHBhcmFtc1syXSkKICAgICAgICAgICAgJiYgIWlzX2Zsb2F0KCRwYXJhbXNbMl0pCiAgICAgICAgICAgICYmICFpc19zdHJpbmcoJHBhcmFtc1syXSkKICAgICAgICAgICAgJiYgIShpc19vYmplY3QoJHBhcmFtc1syXSkgJiYgbWV0aG9kX2V4aXN0cygkcGFyYW1zWzJdLCAnX190b1N0cmluZycpKQogICAgICAgICkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdhcnJheV9jb2x1bW4oKTogVGhlIGluZGV4IGtleSBzaG91bGQgYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGFuIGludGVnZXInLCBFX1VTRVJfV0FSTklORyk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRwYXJhbXNJbnB1dCA9ICRwYXJhbXNbMF07CiAgICAgICAgJHBhcmFtc0NvbHVtbktleSA9ICgkcGFyYW1zWzFdICE9PSBudWxsKSA/IChzdHJpbmcpICRwYXJhbXNbMV0gOiBudWxsOwoKICAgICAgICAkcGFyYW1zSW5kZXhLZXkgPSBudWxsOwogICAgICAgIGlmIChpc3NldCgkcGFyYW1zWzJdKSkgewogICAgICAgICAgICBpZiAoaXNfZmxvYXQoJHBhcmFtc1syXSkgfHwgaXNfaW50KCRwYXJhbXNbMl0pKSB7CiAgICAgICAgICAgICAgICAkcGFyYW1zSW5kZXhLZXkgPSAoaW50KSAkcGFyYW1zWzJdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBhcmFtc0luZGV4S2V5ID0gKHN0cmluZykgJHBhcmFtc1syXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdEFycmF5ID0gW107CgogICAgICAgIGZvcmVhY2ggKCRwYXJhbXNJbnB1dCBhcyAkcm93KSB7CiAgICAgICAgICAgICRrZXkgPSAkdmFsdWUgPSBudWxsOwogICAgICAgICAgICAka2V5U2V0ID0gJHZhbHVlU2V0ID0gZmFsc2U7CgogICAgICAgICAgICBpZiAoJHBhcmFtc0luZGV4S2V5ICE9PSBudWxsICYmIGFycmF5X2tleV9leGlzdHMoJHBhcmFtc0luZGV4S2V5LCAkcm93KSkgewogICAgICAgICAgICAgICAgJGtleVNldCA9IHRydWU7CiAgICAgICAgICAgICAgICAka2V5ID0gKHN0cmluZykgJHJvd1skcGFyYW1zSW5kZXhLZXldOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHBhcmFtc0NvbHVtbktleSA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgJHZhbHVlU2V0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRyb3c7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc19hcnJheSgkcm93KSAmJiBhcnJheV9rZXlfZXhpc3RzKCRwYXJhbXNDb2x1bW5LZXksICRyb3cpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWVTZXQgPSB0cnVlOwogICAgICAgICAgICAgICAgJHZhbHVlID0gJHJvd1skcGFyYW1zQ29sdW1uS2V5XTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR2YWx1ZVNldCkgewogICAgICAgICAgICAgICAgaWYgKCRrZXlTZXQpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0QXJyYXlbJGtleV0gPSAkdmFsdWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRBcnJheVtdID0gJHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHRBcnJheTsKICAgIH0KCn0KLy8gcGhwY3M6ZW5hYmxlCjw/cGhwCgovKioKICogVGhpcyBmaWxlIGNvbnRhaW5zIGZhbGxiYWNrIGZ1bmN0aW9ucyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBkaXNhYmxlZCBidXQgYXJlIHJlcXVpcmVkIG5ldmVydGhlbGVzcy4KICovCgppZiAoIFBIUF9NQUpPUl9WRVJTSU9OID49IDggJiYgISBmdW5jdGlvbl9leGlzdHMoICdpbmlfc2V0JyApICkgewoJZnVuY3Rpb24gaW5pX3NldCggJG9wdGlvbiwgJHZhbHVlICkgewoJCXJldHVybiBmYWxzZTsKCX0KfQo8P3BocAovKioKICogQSBtb2RpZmllZCB2ZXJzaW9uIG9mIHdwLXNldHRpbmdzLnBocCwgdGFpbG9yZWQgZm9yIENMSSB1c2UuCiAqCiAqIE5vdGU6IFRoaXMgaXMgbm90IGJlaW5nIHVzZWQgYW55bW9yZSBmcm9tIFdvcmRQcmVzcyA0LjYtYWxwaGEtMzc1NzUgb253YXJkcy4KICoKICogQHBocGNzOmRpc2FibGUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlIC0tIFNldHRpbmcgdGhlIGdsb2JhbHMgaXMgdGhlIHBvaW50IG9mIHRoaXMgZmlsZS4KICogQHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIFRoZXNlIGFyZSBXUCBuYXRpdmUgY29uc3RhbnRzIHdoaWNoIGFyZSBuZWVkZWQuCiAqIEBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBBbGwgaG9vayBjYWxscyBpbiB0aGlzIGZpbGUgYXJlIHRvIFdQIG5hdGl2ZSBob29rcy4KICogQHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRWYXJpYWJsZUZvdW5kIC0tIEVuc3VyaW5nIG5hdGl2ZSBXUCB2YXJpYWJsZXMgYXJlIGF2YWlsYWJsZS4KICovCgp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIFN0b3JlcyB0aGUgbG9jYXRpb24gb2YgdGhlIFdvcmRQcmVzcyBkaXJlY3Rvcnkgb2YgZnVuY3Rpb25zLCBjbGFzc2VzLCBhbmQgY29yZSBjb250ZW50LgogKgogKiBAc2luY2UgMS4wLjAKICovCmRlZmluZSggJ1dQSU5DJywgJ3dwLWluY2x1ZGVzJyApOwoKLy8gSW5jbHVkZSBmaWxlcyByZXF1aXJlZCBmb3IgaW5pdGlhbGl6YXRpb24uCnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9sb2FkLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9kZWZhdWx0LWNvbnN0YW50cy5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcGx1Z2luLnBocCc7CgovKgogKiBUaGVzZSBjYW4ndCBiZSBkaXJlY3RseSBnbG9iYWxpemVkIGluIHZlcnNpb24ucGhwLiBXaGVuIHVwZGF0aW5nLAogKiB3ZSdyZSBpbmNsdWRpbmcgdmVyc2lvbi5waHAgZnJvbSBhbm90aGVyIGluc3RhbGxhdGlvbiBhbmQgZG9uJ3Qgd2FudAogKiB0aGVzZSB2YWx1ZXMgdG8gYmUgb3ZlcnJpZGRlbiBpZiBhbHJlYWR5IHNldC4KICovCmdsb2JhbCAkd3BfdmVyc2lvbiwgJHdwX2RiX3ZlcnNpb24sICR0aW55bWNlX3ZlcnNpb24sICRyZXF1aXJlZF9waHBfdmVyc2lvbiwgJHJlcXVpcmVkX215c3FsX3ZlcnNpb24sICR3cF9sb2NhbF9wYWNrYWdlOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvdmVyc2lvbi5waHAnOwoKLyoqCiAqIElmIG5vdCBhbHJlYWR5IGNvbmZpZ3VyZWQsIGAkYmxvZ19pZGAgd2lsbCBkZWZhdWx0IHRvIDEgaW4gYSBzaW5nbGUgc2l0ZQogKiBjb25maWd1cmF0aW9uLiBJbiBtdWx0aXNpdGUsIGl0IHdpbGwgYmUgb3ZlcnJpZGRlbiBieSBkZWZhdWx0IGluIG1zLXNldHRpbmdzLnBocC4KICoKICogQGdsb2JhbCBpbnQgJGJsb2dfaWQKICogQHNpbmNlIDIuMC4wCiAqLwpnbG9iYWwgJGJsb2dfaWQ7CgovLyBTZXQgaW5pdGlhbCBkZWZhdWx0IGNvbnN0YW50cyBpbmNsdWRpbmcgV1BfTUVNT1JZX0xJTUlULCBXUF9NQVhfTUVNT1JZX0xJTUlULCBXUF9ERUJVRywgV1BfQ09OVEVOVF9ESVIgYW5kIFdQX0NBQ0hFLgp3cF9pbml0aWFsX2NvbnN0YW50cygpOwoKLy8gQ2hlY2sgZm9yIHRoZSByZXF1aXJlZCBQSFAgdmVyc2lvbiBhbmQgZm9yIHRoZSBNeVNRTCBleHRlbnNpb24gb3IgYSBkYXRhYmFzZSBkcm9wLWluLgp3cF9jaGVja19waHBfbXlzcWxfdmVyc2lvbnMoKTsKCi8vIERpc2FibGUgbWFnaWMgcXVvdGVzIGF0IHJ1bnRpbWUuIE1hZ2ljIHF1b3RlcyBhcmUgYWRkZWQgdXNpbmcgd3BkYiBsYXRlciBpbiB3cC1zZXR0aW5ncy5waHAuCi8vIHBocGNzOmRpc2FibGUgUEhQQ29tcGF0aWJpbGl0eS5JbmlEaXJlY3RpdmVzLlJlbW92ZWRJbmlEaXJlY3RpdmVzLFdvcmRQcmVzcy5QSFAuSW5pU2V0LlJpc2t5CmluaV9zZXQoICdtYWdpY19xdW90ZXNfcnVudGltZScsIDAgKTsKaW5pX3NldCggJ21hZ2ljX3F1b3Rlc19zeWJhc2UnLCAwICk7Ci8vIHBocGM6ZW5hYmxlIFBIUENvbXBhdGliaWxpdHkuSW5pRGlyZWN0aXZlcy5SZW1vdmVkSW5pRGlyZWN0aXZlcyxXb3JkUHJlc3MuUEhQLkluaVNldAoKLy8gV29yZFByZXNzIGNhbGN1bGF0ZXMgb2Zmc2V0cyBmcm9tIFVUQy4KLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLnRpbWV6b25lX2NoYW5nZV9kYXRlX2RlZmF1bHRfdGltZXpvbmVfc2V0CmRhdGVfZGVmYXVsdF90aW1lem9uZV9zZXQoICdVVEMnICk7CgovLyBUdXJuIHJlZ2lzdGVyX2dsb2JhbHMgb2ZmLgp3cF91bnJlZ2lzdGVyX0dMT0JBTFMoKTsKCi8vIFN0YW5kYXJkaXplICRfU0VSVkVSIHZhcmlhYmxlcyBhY3Jvc3Mgc2V0dXBzLgp3cF9maXhfc2VydmVyX3ZhcnMoKTsKCi8vIENoZWNrIGlmIHdlJ3JlIGluIG1haW50ZW5hbmNlIG1vZGUuCi8vIFdQLUNMSTogcnVuIGVuYWJsZV9tYWludGVuYW5jZV9tb2RlIGZpbHRlciBlYXJseSBmb3IgY29tcGF0IHdpdGggPCBXUCA0LjYKLyoqCiAqIEZpbHRlcnMgd2hldGhlciB0byBlbmFibGUgbWFpbnRlbmFuY2UgbW9kZS4KICoKICogVGhpcyBmaWx0ZXIgcnVucyBiZWZvcmUgaXQgY2FuIGJlIHVzZWQgYnkgcGx1Z2lucy4gSXQgaXMgZGVzaWduZWQgZm9yCiAqIG5vbi13ZWIgcnVudGltZXMuIElmIHRoaXMgZmlsdGVyIHJldHVybnMgdHJ1ZSwgbWFpbnRlbmFuY2UgbW9kZSB3aWxsIGJlCiAqIGFjdGl2ZSBhbmQgdGhlIHJlcXVlc3Qgd2lsbCBlbmQuIElmIGZhbHNlLCB0aGUgcmVxdWVzdCB3aWxsIGJlIGFsbG93ZWQgdG8KICogY29udGludWUgcHJvY2Vzc2luZyBldmVuIGlmIG1haW50ZW5hbmNlIG1vZGUgc2hvdWxkIGJlIGFjdGl2ZS4KICoKICogQHNpbmNlIDQuNi4wCiAqCiAqIEBwYXJhbSBib29sICRlbmFibGVfY2hlY2tzIFdoZXRoZXIgdG8gZW5hYmxlIG1haW50ZW5hbmNlIG1vZGUuIERlZmF1bHQgdHJ1ZS4KICogQHBhcmFtIGludCAgJHVwZ3JhZGluZyAgICAgVGhlIHRpbWVzdGFtcCBzZXQgaW4gdGhlIC5tYWludGVuYW5jZSBmaWxlLgogKi8KaWYgKCBhcHBseV9maWx0ZXJzKCAnZW5hYmxlX21haW50ZW5hbmNlX21vZGUnLCB0cnVlICkgKSB7Cgl3cF9tYWludGVuYW5jZSgpOwp9CgovLyBTdGFydCBsb2FkaW5nIHRpbWVyLgp0aW1lcl9zdGFydCgpOwoKLy8gV1AtQ0xJOiBydW4gZW5hYmxlX3dwX2RlYnVnX21vZGVfY2hlY2tzIGZpbHRlciBlYXJseSBmb3IgY29tcGF0IHdpdGggPCBXUCA0LjYKLyoqCiAqIEZpbHRlcnMgd2hldGhlciB0byBhbGxvdyB0aGUgZGVidWcgbW9kZSBjaGVjayB0byBvY2N1ci4KICoKICogVGhpcyBmaWx0ZXIgcnVucyBiZWZvcmUgaXQgY2FuIGJlIHVzZWQgYnkgcGx1Z2lucy4gSXQgaXMgZGVzaWduZWQgZm9yCiAqIG5vbi13ZWIgcnVuLXRpbWVzLiBSZXR1cm5pbmcgZmFsc2UgY2F1c2VzIHRoZSBgV1BfREVCVUdgIGFuZCByZWxhdGVkCiAqIGNvbnN0YW50cyB0byBub3QgYmUgY2hlY2tlZCBhbmQgdGhlIGRlZmF1bHQgcGhwIHZhbHVlcyBmb3IgZXJyb3JzCiAqIHdpbGwgYmUgdXNlZCB1bmxlc3MgeW91IHRha2UgY2FyZSB0byB1cGRhdGUgdGhlbSB5b3Vyc2VsZi4KICoKICogQHNpbmNlIDQuNi4wCiAqCiAqIEBwYXJhbSBib29sICRlbmFibGVfZGVidWdfbW9kZSBXaGV0aGVyIHRvIGVuYWJsZSBkZWJ1ZyBtb2RlIGNoZWNrcyB0byBvY2N1ci4gRGVmYXVsdCB0cnVlLgogKi8KaWYgKCBhcHBseV9maWx0ZXJzKCAnZW5hYmxlX3dwX2RlYnVnX21vZGVfY2hlY2tzJywgdHJ1ZSApICkgewoJd3BfZGVidWdfbW9kZSgpOwp9CgovKioKICogRmlsdGVycyB3aGV0aGVyIHRvIGVuYWJsZSBsb2FkaW5nIG9mIHRoZSBhZHZhbmNlZC1jYWNoZS5waHAgZHJvcC1pbi4KICoKICogVGhpcyBmaWx0ZXIgcnVucyBiZWZvcmUgaXQgY2FuIGJlIHVzZWQgYnkgcGx1Z2lucy4gSXQgaXMgZGVzaWduZWQgZm9yIG5vbi13ZWIKICogcnVuLXRpbWVzLiBJZiBmYWxzZSBpcyByZXR1cm5lZCwgYWR2YW5jZS1jYWNoZS5waHAgd2lsbCBuZXZlciBiZSBsb2FkZWQuCiAqCiAqIEBzaW5jZSA0LjYuMAogKgogKiBAcGFyYW0gYm9vbCAkZW5hYmxlX2FkdmFuY2VkX2NhY2hlIFdoZXRoZXIgdG8gZW5hYmxlIGxvYWRpbmcgYWR2YW5jZWQtY2FjaGUucGhwIChpZiBwcmVzZW50KS4KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IHRydWUuCiAqLwppZiAoIFdQX0NBQ0hFICYmIGFwcGx5X2ZpbHRlcnMoICdlbmFibGVfbG9hZGluZ19hZHZhbmNlZF9jYWNoZV9kcm9waW4nLCB0cnVlICkgKSB7CgkvLyBGb3IgYW4gYWR2YW5jZWQgY2FjaGluZyBwbHVnaW4gdG8gdXNlLiBVc2VzIGEgc3RhdGljIGRyb3AtaW4gYmVjYXVzZSB5b3Ugd291bGQgb25seSB3YW50IG9uZS4KCWlmICggZmlsZV9leGlzdHMoIFdQX0NPTlRFTlRfRElSIC4gJy9hZHZhbmNlZC1jYWNoZS5waHAnICkgKSB7CgkJaW5jbHVkZSBXUF9DT05URU5UX0RJUiAuICcvYWR2YW5jZWQtY2FjaGUucGhwJzsKCX0KfQoKLy8gRGVmaW5lIFdQX0xBTkdfRElSIGlmIG5vdCBzZXQuCndwX3NldF9sYW5nX2RpcigpOwoKLy8gTG9hZCBlYXJseSBXb3JkUHJlc3MgZmlsZXMuCnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jb21wYXQucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2Z1bmN0aW9ucy5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLWVycm9yLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9wb21vL21vLnBocCc7CgovLyBJbmNsdWRlIHRoZSB3cGRiIGNsYXNzIGFuZCwgaWYgcHJlc2VudCwgYSBkYi5waHAgZGF0YWJhc2UgZHJvcC1pbi4KcmVxdWlyZV93cF9kYigpOwoKLy8gV1AtQ0xJOiBIYW5kbGUgZGIgZXJyb3Igb3Vyc2VsdmVzLCBpbnN0ZWFkIG9mIHdhaXRpbmcgZm9yIGRlYWRfZGIoKQpnbG9iYWwgJHdwZGI7CmlmICggISBlbXB0eSggJHdwZGItPmVycm9yICkgKSB7Cgl3cF9kaWUoICR3cGRiLT5lcnJvciApOwp9CgovLyBTZXQgdGhlIGRhdGFiYXNlIHRhYmxlIHByZWZpeCBhbmQgdGhlIGZvcm1hdCBzcGVjaWZpZXJzIGZvciBkYXRhYmFzZSB0YWJsZSBjb2x1bW5zLgokR0xPQkFMU1sndGFibGVfcHJlZml4J10gPSAkdGFibGVfcHJlZml4Owp3cF9zZXRfd3BkYl92YXJzKCk7CgovLyBTdGFydCB0aGUgV29yZFByZXNzIG9iamVjdCBjYWNoZSwgb3IgYW4gZXh0ZXJuYWwgb2JqZWN0IGNhY2hlIGlmIHRoZSBkcm9wLWluIGlzIHByZXNlbnQuCndwX3N0YXJ0X29iamVjdF9jYWNoZSgpOwoKLy8gQXR0YWNoIHRoZSBkZWZhdWx0IGZpbHRlcnMuCnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9kZWZhdWx0LWZpbHRlcnMucGhwJzsKCi8vIEluaXRpYWxpemUgbXVsdGlzaXRlIGlmIGVuYWJsZWQuCmlmICggaXNfbXVsdGlzaXRlKCkgKSB7CglVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC42LWFscGhhLTM3NTc1JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1zaXRlLXF1ZXJ5LnBocCcgKTsKCVV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjYtYWxwaGEtMzc4OTYnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLW5ldHdvcmstcXVlcnkucGhwJyApOwoJcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL21zLWJsb2dzLnBocCc7CglyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbXMtc2V0dGluZ3MucGhwJzsKfSBlbHNlaWYgKCAhIGRlZmluZWQoICdNVUxUSVNJVEUnICkgKSB7CglkZWZpbmUoICdNVUxUSVNJVEUnLCBmYWxzZSApOwp9CgpyZWdpc3Rlcl9zaHV0ZG93bl9mdW5jdGlvbiggJ3NodXRkb3duX2FjdGlvbl9ob29rJyApOwoKLy8gU3RvcCBtb3N0IG9mIFdvcmRQcmVzcyBmcm9tIGJlaW5nIGxvYWRlZCBpZiB3ZSBqdXN0IHdhbnQgdGhlIGJhc2ljcy4KaWYgKCBTSE9SVElOSVQgKSB7CglyZXR1cm4gZmFsc2U7Cn0KCi8vIExvYWQgdGhlIEwxMG4gbGlicmFyeS4KcmVxdWlyZV9vbmNlIEFCU1BBVEggLiBXUElOQyAuICcvbDEwbi5waHAnOwoKLy8gV1AtQ0xJOiBQZXJtaXQgVXRpbHNcd3Bfbm90X2luc3RhbGxlZCgpIHRvIHJ1biBvbiA8IFdQIDQuMAphcHBseV9maWx0ZXJzKCAnbm9jYWNoZV9oZWFkZXJzJywgW10gKTsKCi8vIFJ1biB0aGUgaW5zdGFsbGVyIGlmIFdvcmRQcmVzcyBpcyBub3QgaW5zdGFsbGVkLgp3cF9ub3RfaW5zdGFsbGVkKCk7CgovLyBMb2FkIG1vc3Qgb2YgV29yZFByZXNzLgpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3Atd2Fsa2VyLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1hamF4LXJlc3BvbnNlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9mb3JtYXR0aW5nLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jYXBhYmlsaXRpZXMucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3Atcm9sZXMucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1yb2xlLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtdXNlci5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9xdWVyeS5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnMy43LWFscGhhLTI1MTM5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9kYXRlLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3RoZW1lLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC10aGVtZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvdGVtcGxhdGUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3VzZXIucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtdXNlci1xdWVyeS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjAnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL3Nlc3Npb24ucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbWV0YS5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1tZXRhLXF1ZXJ5LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNS1hbHBoYS0zNTc3NicsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtbWV0YWRhdGEtbGF6eWxvYWRlci5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9nZW5lcmFsLXRlbXBsYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9saW5rLXRlbXBsYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9hdXRob3ItdGVtcGxhdGUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3Bvc3QucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd2Fsa2VyLXBhZ2UucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13YWxrZXItcGFnZS1kcm9wZG93bi5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjYtYWxwaGEtMzc4OTAnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXBvc3QtdHlwZS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXBvc3QucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcG9zdC10ZW1wbGF0ZS5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnMy42LWFscGhhLTIzNDUxJywgQUJTUEFUSCAuIFdQSU5DIC4gJy9yZXZpc2lvbi5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICczLjYtYWxwaGEtMjM0NTEnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL3Bvc3QtZm9ybWF0cy5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9wb3N0LXRodW1ibmFpbC10ZW1wbGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2F0ZWdvcnkucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd2Fsa2VyLWNhdGVnb3J5LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd2Fsa2VyLWNhdGVnb3J5LWRyb3Bkb3duLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NhdGVnb3J5LXRlbXBsYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jb21tZW50LnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLWNvbW1lbnQucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1jb21tZW50LXF1ZXJ5LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd2Fsa2VyLWNvbW1lbnQucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY29tbWVudC10ZW1wbGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcmV3cml0ZS5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1yZXdyaXRlLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2ZlZWQucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2Jvb2ttYXJrLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9ib29rbWFyay10ZW1wbGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcva3Nlcy5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY3Jvbi5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvZGVwcmVjYXRlZC5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvc2NyaXB0LWxvYWRlci5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvdGF4b25vbXkucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtdGVybS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjYtYWxwaGEtMzc1NzUnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXRlcm0tcXVlcnkucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC10YXgtcXVlcnkucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvdXBkYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jYW5vbmljYWwucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3Nob3J0Y29kZXMucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvZW1iZWQucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtZW1iZWQucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL21lZGlhLnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYWxwaGEtMzQ5MDMnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLW9lbWJlZC1jb250cm9sbGVyLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2h0dHAucGhwJzsKcmVxdWlyZV9vbmNlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3MtaHR0cC5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1odHRwLXN0cmVhbXMucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1odHRwLWN1cmwucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1odHRwLXByb3h5LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtaHR0cC1jb29raWUucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1odHRwLWVuY29kaW5nLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtaHR0cC1yZXNwb25zZS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjYtYWxwaGEtMzc0MzgnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLWh0dHAtcmVxdWVzdHMtcmVzcG9uc2UucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvd2lkZ2V0cy5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC13aWRnZXQucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC13aWRnZXQtZmFjdG9yeS5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9uYXYtbWVudS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbmF2LW1lbnUtdGVtcGxhdGUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2FkbWluLWJhci5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWFscGhhLTM0OTI4JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9yZXN0LWFwaS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL3Jlc3QtYXBpL2NsYXNzLXdwLXJlc3Qtc2VydmVyLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvcmVzdC1hcGkvY2xhc3Mtd3AtcmVzdC1yZXNwb25zZS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL3Jlc3QtYXBpL2NsYXNzLXdwLXJlc3QtcmVxdWVzdC5waHAnICk7CgovLyBMb2FkIG11bHRpc2l0ZS1zcGVjaWZpYyBmaWxlcy4KaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCXJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9tcy1mdW5jdGlvbnMucGhwJzsKCXJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9tcy1kZWZhdWx0LWZpbHRlcnMucGhwJzsKCXJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9tcy1kZXByZWNhdGVkLnBocCc7Cn0KCi8vIERlZmluZSBjb25zdGFudHMgdGhhdCByZWx5IG9uIHRoZSBBUEkgdG8gb2J0YWluIHRoZSBkZWZhdWx0IHZhbHVlLgovLyBEZWZpbmUgbXVzdC11c2UgcGx1Z2luIGRpcmVjdG9yeSBjb25zdGFudHMsIHdoaWNoIG1heSBiZSBvdmVycmlkZGVuIGluIHRoZSBzdW5yaXNlLnBocCBkcm9wLWluLgp3cF9wbHVnaW5fZGlyZWN0b3J5X2NvbnN0YW50cygpOwoKJHN5bWxpbmtlZF9wbHVnaW5zX3N1cHBvcnRlZCA9IGZ1bmN0aW9uX2V4aXN0cyggJ3dwX3JlZ2lzdGVyX3BsdWdpbl9yZWFscGF0aCcgKTsKaWYgKCAkc3ltbGlua2VkX3BsdWdpbnNfc3VwcG9ydGVkICkgewoJJEdMT0JBTFNbJ3dwX3BsdWdpbl9wYXRocyddID0gW107Cn0KCi8vIExvYWQgbXVzdC11c2UgcGx1Z2lucy4KZm9yZWFjaCAoIHdwX2dldF9tdV9wbHVnaW5zKCkgYXMgJG11X3BsdWdpbiApIHsKCWluY2x1ZGVfb25jZSAkbXVfcGx1Z2luOwp9CnVuc2V0KCAkbXVfcGx1Z2luICk7CgovLyBMb2FkIG5ldHdvcmsgYWN0aXZhdGVkIHBsdWdpbnMuCmlmICggaXNfbXVsdGlzaXRlKCkgKSB7Cglmb3JlYWNoICggd3BfZ2V0X2FjdGl2ZV9uZXR3b3JrX3BsdWdpbnMoKSBhcyAkbmV0d29ya19wbHVnaW4gKSB7CgkJaWYgKCAkc3ltbGlua2VkX3BsdWdpbnNfc3VwcG9ydGVkICkgewoJCQl3cF9yZWdpc3Rlcl9wbHVnaW5fcmVhbHBhdGgoICRuZXR3b3JrX3BsdWdpbiApOwoJCX0KCQlpbmNsdWRlX29uY2UgJG5ldHdvcmtfcGx1Z2luOwoJfQoJdW5zZXQoICRuZXR3b3JrX3BsdWdpbiApOwp9Cgpkb19hY3Rpb24oICdtdXBsdWdpbnNfbG9hZGVkJyApOwoKaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCW1zX2Nvb2tpZV9jb25zdGFudHMoKTsKfQoKLy8gRGVmaW5lIGNvbnN0YW50cyBhZnRlciBtdWx0aXNpdGUgaXMgbG9hZGVkLiBDb29raWUtcmVsYXRlZCBjb25zdGFudHMgbWF5IGJlIG92ZXJyaWRkZW4gaW4gbXNfbmV0d29ya19jb29raWVzKCkuCndwX2Nvb2tpZV9jb25zdGFudHMoKTsKCi8vIERlZmluZSBhbmQgZW5mb3JjZSBvdXIgU1NMIGNvbnN0YW50cy4Kd3Bfc3NsX2NvbnN0YW50cygpOwoKLy8gQ3JlYXRlIGNvbW1vbiBnbG9iYWxzLgpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvdmFycy5waHAnOwoKLy8gTWFrZSB0YXhvbm9taWVzIGFuZCBwb3N0cyBhdmFpbGFibGUgdG8gcGx1Z2lucyBhbmQgdGhlbWVzLgovLyBAcGx1Z2luIGF1dGhvcnM6IHdhcm5pbmc6IHRoZXNlIGdldCByZWdpc3RlcmVkIGFnYWluIG9uIHRoZSBpbml0IGhvb2suCmNyZWF0ZV9pbml0aWFsX3RheG9ub21pZXMoKTsKY3JlYXRlX2luaXRpYWxfcG9zdF90eXBlcygpOwoKLy8gUmVnaXN0ZXIgdGhlIGRlZmF1bHQgdGhlbWUgZGlyZWN0b3J5IHJvb3QKcmVnaXN0ZXJfdGhlbWVfZGlyZWN0b3J5KCBnZXRfdGhlbWVfcm9vdCgpICk7CgovLyBMb2FkIGFjdGl2ZSBwbHVnaW5zLgpmb3JlYWNoICggd3BfZ2V0X2FjdGl2ZV9hbmRfdmFsaWRfcGx1Z2lucygpIGFzICRwbHVnaW4gKSB7CglpZiAoICRzeW1saW5rZWRfcGx1Z2luc19zdXBwb3J0ZWQgKSB7CgkJd3BfcmVnaXN0ZXJfcGx1Z2luX3JlYWxwYXRoKCAkcGx1Z2luICk7Cgl9CglpbmNsdWRlX29uY2UgJHBsdWdpbjsKfQp1bnNldCggJHBsdWdpbiwgJHN5bWxpbmtlZF9wbHVnaW5zX3N1cHBvcnRlZCApOwoKLy8gTG9hZCBwbHVnZ2FibGUgZnVuY3Rpb25zLgpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcGx1Z2dhYmxlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9wbHVnZ2FibGUtZGVwcmVjYXRlZC5waHAnOwoKLy8gU2V0IGludGVybmFsIGVuY29kaW5nLgp3cF9zZXRfaW50ZXJuYWxfZW5jb2RpbmcoKTsKCi8vIFJ1biB3cF9jYWNoZV9wb3N0bG9hZCgpIGlmIG9iamVjdCBjYWNoZSBpcyBlbmFibGVkIGFuZCB0aGUgZnVuY3Rpb24gZXhpc3RzLgppZiAoIFdQX0NBQ0hFICYmIGZ1bmN0aW9uX2V4aXN0cyggJ3dwX2NhY2hlX3Bvc3Rsb2FkJyApICkgewoJd3BfY2FjaGVfcG9zdGxvYWQoKTsKfQoKZG9fYWN0aW9uKCAncGx1Z2luc19sb2FkZWQnICk7CgovLyBEZWZpbmUgY29uc3RhbnRzIHdoaWNoIGFmZmVjdCBmdW5jdGlvbmFsaXR5IGlmIG5vdCBhbHJlYWR5IGRlZmluZWQuCndwX2Z1bmN0aW9uYWxpdHlfY29uc3RhbnRzKCk7CgppZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAnZ2V0X21hZ2ljX3F1b3Rlc19ncGMnICkgKSB7CgkvLyBQcm92aWRlIGNvbXBhdCBmYWxsYmFjayBmb3IgbmV3ZXIgUEhQIHZlcnNpb24gKDcuNCspIG9uIG9sZGVyIFdvcmRQcmVzcyBjb3JlIHZlcnNpb25zLgoJZnVuY3Rpb24gZ2V0X21hZ2ljX3F1b3Rlc19ncGMoKSB7CgkJcmV0dXJuIGZhbHNlOwoJfQp9CgovLyBBZGQgbWFnaWMgcXVvdGVzIGFuZCBzZXQgdXAgJF9SRVFVRVNUICggJF9HRVQgKyAkX1BPU1QgKQp3cF9tYWdpY19xdW90ZXMoKTsKCmRvX2FjdGlvbiggJ3Nhbml0aXplX2NvbW1lbnRfY29va2llcycgKTsKCi8qKgogKiBXb3JkUHJlc3MgUXVlcnkgb2JqZWN0CiAqIEBnbG9iYWwgb2JqZWN0ICR3cF90aGVfcXVlcnkKICogQHNpbmNlIDIuMC4wCiAqLwokR0xPQkFMU1snd3BfdGhlX3F1ZXJ5J10gPSBuZXcgV1BfUXVlcnkoKTsKCi8qKgogKiBIb2xkcyB0aGUgcmVmZXJlbmNlIHRvIEBzZWUgJHdwX3RoZV9xdWVyeQogKiBVc2UgdGhpcyBnbG9iYWwgZm9yIFdvcmRQcmVzcyBxdWVyaWVzCiAqIEBnbG9iYWwgb2JqZWN0ICR3cF9xdWVyeQogKiBAc2luY2UgMS41LjAKICovCiRHTE9CQUxTWyd3cF9xdWVyeSddID0gJEdMT0JBTFNbJ3dwX3RoZV9xdWVyeSddOwoKLyoqCiAqIEhvbGRzIHRoZSBXb3JkUHJlc3MgUmV3cml0ZSBvYmplY3QgZm9yIGNyZWF0aW5nIHByZXR0eSBVUkxzCiAqIEBnbG9iYWwgb2JqZWN0ICR3cF9yZXdyaXRlCiAqIEBzaW5jZSAxLjUuMAogKi8KJEdMT0JBTFNbJ3dwX3Jld3JpdGUnXSA9IG5ldyBXUF9SZXdyaXRlKCk7CgovKioKICogV29yZFByZXNzIE9iamVjdAogKiBAZ2xvYmFsIG9iamVjdCAkd3AKICogQHNpbmNlIDIuMC4wCiAqLwokR0xPQkFMU1snd3AnXSA9IG5ldyBXUCgpOwoKLyoqCiAqIFdvcmRQcmVzcyBXaWRnZXQgRmFjdG9yeSBPYmplY3QKICogQGdsb2JhbCBvYmplY3QgJHdwX3dpZGdldF9mYWN0b3J5CiAqIEBzaW5jZSAyLjguMAogKi8KJEdMT0JBTFNbJ3dwX3dpZGdldF9mYWN0b3J5J10gPSBuZXcgV1BfV2lkZ2V0X0ZhY3RvcnkoKTsKCi8qKgogKiBXb3JkUHJlc3MgVXNlciBSb2xlcwogKiBAZ2xvYmFsIG9iamVjdCAkd3Bfcm9sZXMKICogQHNpbmNlIDIuMC4wCiAqLwokR0xPQkFMU1snd3Bfcm9sZXMnXSA9IG5ldyBXUF9Sb2xlcygpOwoKZG9fYWN0aW9uKCAnc2V0dXBfdGhlbWUnICk7CgovLyBEZWZpbmUgdGhlIHRlbXBsYXRlIHJlbGF0ZWQgY29uc3RhbnRzLgp3cF90ZW1wbGF0aW5nX2NvbnN0YW50cygpOwoKLy8gTG9hZCB0aGUgZGVmYXVsdCB0ZXh0IGxvY2FsaXphdGlvbiBkb21haW4uCmxvYWRfZGVmYXVsdF90ZXh0ZG9tYWluKCk7CgokbG9jYWxlICAgICAgPSBnZXRfbG9jYWxlKCk7CiRsb2NhbGVfZmlsZSA9IFdQX0xBTkdfRElSIC4gIi8kbG9jYWxlLnBocCI7CmlmICggKCAwID09PSB2YWxpZGF0ZV9maWxlKCAkbG9jYWxlICkgKSAmJiBpc19yZWFkYWJsZSggJGxvY2FsZV9maWxlICkgKSB7CglyZXF1aXJlICRsb2NhbGVfZmlsZTsKfQp1bnNldCggJGxvY2FsZV9maWxlICk7CgovLyBQdWxsIGluIGxvY2FsZSBkYXRhIGFmdGVyIGxvYWRpbmcgdGV4dCBkb21haW4uCnJlcXVpcmVfb25jZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2xvY2FsZS5waHAnOwoKLyoqCiAqIFdvcmRQcmVzcyBMb2NhbGUgb2JqZWN0IGZvciBsb2FkaW5nIGxvY2FsZSBkb21haW4gZGF0ZSBhbmQgdmFyaW91cyBzdHJpbmdzLgogKiBAZ2xvYmFsIG9iamVjdCAkd3BfbG9jYWxlCiAqIEBzaW5jZSAyLjEuMAogKi8KJEdMT0JBTFNbJ3dwX2xvY2FsZSddID0gbmV3IFdQX0xvY2FsZSgpOwoKLy8gTG9hZCB0aGUgZnVuY3Rpb25zIGZvciB0aGUgYWN0aXZlIHRoZW1lLCBmb3IgYm90aCBwYXJlbnQgYW5kIGNoaWxkIHRoZW1lIGlmIGFwcGxpY2FibGUuCi8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLldQLkRpc2NvdXJhZ2VkQ29uc3RhbnRzLlNUWUxFU0hFRVRQQVRIVXNhZ2VGb3VuZCxXb3JkUHJlc3MuV1AuRGlzY291cmFnZWRDb25zdGFudHMuVEVNUExBVEVQQVRIVXNhZ2VGb3VuZApnbG9iYWwgJHBhZ2Vub3c7CmlmICggISBkZWZpbmVkKCAnV1BfSU5TVEFMTElORycgKSB8fCAnd3AtYWN0aXZhdGUucGhwJyA9PT0gJHBhZ2Vub3cgKSB7CglpZiAoIFRFTVBMQVRFUEFUSCAhPT0gU1RZTEVTSEVFVFBBVEggJiYgZmlsZV9leGlzdHMoIFNUWUxFU0hFRVRQQVRIIC4gJy9mdW5jdGlvbnMucGhwJyApICkgewoJCWluY2x1ZGUgU1RZTEVTSEVFVFBBVEggLiAnL2Z1bmN0aW9ucy5waHAnOwoJfQoJaWYgKCBmaWxlX2V4aXN0cyggVEVNUExBVEVQQVRIIC4gJy9mdW5jdGlvbnMucGhwJyApICkgewoJCWluY2x1ZGUgVEVNUExBVEVQQVRIIC4gJy9mdW5jdGlvbnMucGhwJzsKCX0KfQovLyBwaHBjczplbmFibGUgV29yZFByZXNzLldQLkRpc2NvdXJhZ2VkQ29uc3RhbnRzCgpkb19hY3Rpb24oICdhZnRlcl9zZXR1cF90aGVtZScgKTsKCi8vIFNldCB1cCBjdXJyZW50IHVzZXIuCiRHTE9CQUxTWyd3cCddLT5pbml0KCk7CgovKioKICogTW9zdCBvZiBXUCBpcyBsb2FkZWQgYXQgdGhpcyBzdGFnZSwgYW5kIHRoZSB1c2VyIGlzIGF1dGhlbnRpY2F0ZWQuIFdQIGNvbnRpbnVlcwogKiB0byBsb2FkIG9uIHRoZSBpbml0IGhvb2sgdGhhdCBmb2xsb3dzIChlLmcuIHdpZGdldHMpLCBhbmQgbWFueSBwbHVnaW5zIGluc3RhbnRpYXRlCiAqIHRoZW1zZWx2ZXMgb24gaXQgZm9yIGFsbCBzb3J0cyBvZiByZWFzb25zIChlLmcuIHRoZXkgbmVlZCBhIHVzZXIsIGEgdGF4b25vbXksIGV0Yy4pLgogKgogKiBJZiB5b3Ugd2lzaCB0byBwbHVnIGFuIGFjdGlvbiBvbmNlIFdQIGlzIGxvYWRlZCwgdXNlIHRoZSB3cF9sb2FkZWQgaG9vayBiZWxvdy4KICovCmRvX2FjdGlvbiggJ2luaXQnICk7CgovLyBDaGVjayBzaXRlIHN0YXR1cwojIGlmICggaXNfbXVsdGlzaXRlKCkgKSB7ICAvLyBXUC1DTEkKaWYgKCBpc19tdWx0aXNpdGUoKSAmJiAhIGRlZmluZWQoICdXUF9JTlNUQUxMSU5HJyApICkgewoJJGZpbGUgPSBtc19zaXRlX2NoZWNrKCk7CglpZiAoIHRydWUgIT09ICRmaWxlICkgewoJCXJlcXVpcmUgJGZpbGU7CgkJZGllKCk7Cgl9Cgl1bnNldCggJGZpbGUgKTsKfQoKLyoqCiAqIFRoaXMgaG9vayBpcyBmaXJlZCBvbmNlIFdQLCBhbGwgcGx1Z2lucywgYW5kIHRoZSB0aGVtZSBhcmUgZnVsbHkgbG9hZGVkIGFuZCBpbnN0YW50aWF0ZWQuCiAqCiAqIEFKQVggcmVxdWVzdHMgc2hvdWxkIHVzZSB3cC1hZG1pbi9hZG1pbi1hamF4LnBocC4gYWRtaW4tYWpheC5waHAgY2FuIGhhbmRsZSByZXF1ZXN0cyBmb3IKICogdXNlcnMgbm90IGxvZ2dlZCBpbi4KICoKICogQGxpbmsgaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL0FKQVhfaW5fUGx1Z2lucwogKgogKiBAc2luY2UgMy4wLjAKICovCmRvX2FjdGlvbiggJ3dwX2xvYWRlZCcgKTsKPD9waHAKCnVzZSBjbGlcQ29sb3JzOwp1c2UgTXVzdGFuZ29zdGFuZ1xTcHljOwp1c2UgV1BfQ0xJXENvbmZpZ3VyYXRvcjsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZEFkZGl0aW9uOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZEZhY3Rvcnk7CnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tcG9zaXRlQ29tbWFuZDsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXFJvb3RDb21tYW5kOwp1c2UgV1BfQ0xJXERvY1BhcnNlcjsKdXNlIFdQX0NMSVxFeGl0RXhjZXB0aW9uOwp1c2UgV1BfQ0xJXEZpbGVDYWNoZTsKdXNlIFdQX0NMSVxMb2dnZXJzXEV4ZWN1dGlvbjsKdXNlIFdQX0NMSVxQcm9jZXNzOwp1c2UgV1BfQ0xJXFByb2Nlc3NSdW47CnVzZSBXUF9DTElcUnVubmVyOwp1c2UgV1BfQ0xJXFN5bm9wc2lzUGFyc2VyOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXFdwSHR0cENhY2hlTWFuYWdlcjsKCi8qKgogKiBWYXJpb3VzIHV0aWxpdGllcyBmb3IgV1AtQ0xJIGNvbW1hbmRzLgogKi8KY2xhc3MgV1BfQ0xJIHsKCglwcml2YXRlIHN0YXRpYyAkbG9nZ2VyOwoKCXByaXZhdGUgc3RhdGljICRob29rcyA9IFtdOwoKCXByaXZhdGUgc3RhdGljICRob29rc19wYXNzZWQgPSBbXTsKCglwcml2YXRlIHN0YXRpYyAkY2FwdHVyZV9leGl0ID0gZmFsc2U7CgoJcHJpdmF0ZSBzdGF0aWMgJGRlZmVycmVkX2FkZGl0aW9ucyA9IFtdOwoKCS8qKgoJICogU2V0IHRoZSBsb2dnZXIgaW5zdGFuY2UuCgkgKgoJICogQHBhcmFtIG9iamVjdCAkbG9nZ2VyIExvZ2dlciBpbnN0YW5jZSB0byBzZXQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0X2xvZ2dlciggJGxvZ2dlciApIHsKCQlzZWxmOjokbG9nZ2VyID0gJGxvZ2dlcjsKCX0KCgkvKioKCSAqIEdldCB0aGUgbG9nZ2VyIGluc3RhbmNlLgoJICoKCSAqIEByZXR1cm4gb2JqZWN0ICRsb2dnZXIgTG9nZ2VyIGluc3RhbmNlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9sb2dnZXIoKSB7CgkJcmV0dXJuIHNlbGY6OiRsb2dnZXI7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIENvbmZpZ3VyYXRvciBpbnN0YW5jZQoJICoKCSAqIEByZXR1cm4gQ29uZmlndXJhdG9yCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X2NvbmZpZ3VyYXRvcigpIHsKCQlzdGF0aWMgJGNvbmZpZ3VyYXRvcjsKCgkJaWYgKCAhICRjb25maWd1cmF0b3IgKSB7CgkJCSRjb25maWd1cmF0b3IgPSBuZXcgQ29uZmlndXJhdG9yKCBXUF9DTElfUk9PVCAuICcvcGhwL2NvbmZpZy1zcGVjLnBocCcgKTsKCQl9CgoJCXJldHVybiAkY29uZmlndXJhdG9yOwoJfQoKCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X3Jvb3RfY29tbWFuZCgpIHsKCQlzdGF0aWMgJHJvb3Q7CgoJCWlmICggISAkcm9vdCApIHsKCQkJJHJvb3QgPSBuZXcgUm9vdENvbW1hbmQoKTsKCQl9CgoJCXJldHVybiAkcm9vdDsKCX0KCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9ydW5uZXIoKSB7CgkJc3RhdGljICRydW5uZXI7CgoJCWlmICggISAkcnVubmVyICkgewoJCQkkcnVubmVyID0gbmV3IFJ1bm5lcigpOwoJCX0KCgkJcmV0dXJuICRydW5uZXI7Cgl9CgoJLyoqCgkgKiBAcmV0dXJuIEZpbGVDYWNoZQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9jYWNoZSgpIHsKCQlzdGF0aWMgJGNhY2hlOwoKCQlpZiAoICEgJGNhY2hlICkgewoJCQkkaG9tZSAgICAgPSBVdGlsc1xnZXRfaG9tZV9kaXIoKTsKCQkJJGRpciAgICAgID0gZ2V0ZW52KCAnV1BfQ0xJX0NBQ0hFX0RJUicgKSA/IDogIiRob21lLy53cC1jbGkvY2FjaGUiOwoJCQkkdHRsICAgICAgPSBnZXRlbnYoICdXUF9DTElfQ0FDSEVfRVhQSVJZJyApID8gOiAxNTU1MjAwMDsKCQkJJG1heF9zaXplID0gZ2V0ZW52KCAnV1BfQ0xJX0NBQ0hFX01BWF9TSVpFJyApID8gOiAzMTQ1NzI4MDA7CgkJCS8vIDYgbW9udGhzLCAzMDBtYgoJCQkkY2FjaGUgPSBuZXcgRmlsZUNhY2hlKCAkZGlyLCAkdHRsLCAkbWF4X3NpemUgKTsKCgkJCS8vIENsZWFuIG9sZGVyIGZpbGVzIG9uIHNodXRkb3duIHdpdGggMS81MCBwcm9iYWJpbGl0eS4KCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5yYW5kX210X3JhbmQgLS0gbm8gY3J5cHRvIGFuZCBXUCBub3QgbG9hZGVkLgoJCQlpZiAoIDAgPT09IG10X3JhbmQoIDAsIDUwICkgKSB7CgkJCQlyZWdpc3Rlcl9zaHV0ZG93bl9mdW5jdGlvbigKCQkJCQlmdW5jdGlvbiAoKSB1c2UgKCAkY2FjaGUgKSB7CgkJCQkJCSRjYWNoZS0+Y2xlYW4oKTsKCQkJCQl9CgkJCQkpOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGNhY2hlOwoJfQoKCS8qKgoJICogU2V0IHRoZSBjb250ZXh0IGluIHdoaWNoIFdQLUNMSSBzaG91bGQgYmUgcnVuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0X3VybCggJHVybCApIHsKCQlzZWxmOjpkZWJ1ZyggJ1NldCBVUkw6ICcgLiAkdXJsLCAnYm9vdHN0cmFwJyApOwoJCSR1cmxfcGFydHMgPSBVdGlsc1xwYXJzZV91cmwoICR1cmwgKTsKCQlzZWxmOjpzZXRfdXJsX3BhcmFtcyggJHVybF9wYXJ0cyApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHNldF91cmxfcGFyYW1zKCAkdXJsX3BhcnRzICkgewoJCSRmID0gZnVuY3Rpb24oICRrZXkgKSB1c2UgKCAkdXJsX3BhcnRzICkgewoJCQlyZXR1cm4gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICR1cmxfcGFydHMsICRrZXksICcnICk7CgkJfTsKCgkJaWYgKCBpc3NldCggJHVybF9wYXJ0c1snaG9zdCddICkgKSB7CgkJCWlmICggaXNzZXQoICR1cmxfcGFydHNbJ3NjaGVtZSddICkgJiYgJ2h0dHBzJyA9PT0gc3RydG9sb3dlciggJHVybF9wYXJ0c1snc2NoZW1lJ10gKSApIHsKCQkJCSRfU0VSVkVSWydIVFRQUyddID0gJ29uJzsKCQkJfQoKCQkJJF9TRVJWRVJbJ0hUVFBfSE9TVCddID0gJHVybF9wYXJ0c1snaG9zdCddOwoJCQlpZiAoIGlzc2V0KCAkdXJsX3BhcnRzWydwb3J0J10gKSApIHsKCQkJCSRfU0VSVkVSWydIVFRQX0hPU1QnXSAuPSAnOicgLiAkdXJsX3BhcnRzWydwb3J0J107CgkJCX0KCgkJCSRfU0VSVkVSWydTRVJWRVJfTkFNRSddID0gJHVybF9wYXJ0c1snaG9zdCddOwoJCX0KCgkJJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10gID0gJGYoICdwYXRoJyApIC4gKCBpc3NldCggJHVybF9wYXJ0c1sncXVlcnknXSApID8gJz8nIC4gJHVybF9wYXJ0c1sncXVlcnknXSA6ICcnICk7CgkJJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10gID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICR1cmxfcGFydHMsICdwb3J0JywgJzgwJyApOwoJCSRfU0VSVkVSWydRVUVSWV9TVFJJTkcnXSA9ICRmKCAncXVlcnknICk7Cgl9CgoJLyoqCgkgKiBAcmV0dXJuIFdwSHR0cENhY2hlTWFuYWdlcgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9odHRwX2NhY2hlX21hbmFnZXIoKSB7CgkJc3RhdGljICRodHRwX2NhY2hlcjsKCgkJaWYgKCAhICRodHRwX2NhY2hlciApIHsKCQkJJGh0dHBfY2FjaGVyID0gbmV3IFdwSHR0cENhY2hlTWFuYWdlciggc2VsZjo6Z2V0X2NhY2hlKCkgKTsKCQl9CgoJCXJldHVybiAkaHR0cF9jYWNoZXI7Cgl9CgoJLyoqCgkgKiBDb2xvcml6ZSBhIHN0cmluZyBmb3Igb3V0cHV0LgoJICoKCSAqIFllcywgeW91IGNhbiBjaGFuZ2UgdGhlIGNvbG9yIG9mIGNvbW1hbmQgbGluZSB0ZXh0IHRvby4gRm9yIGluc3RhbmNlLAoJICogaGVyZSdzIGhvdyBgV1BfQ0xJOjpzdWNjZXNzKClgIGNvbG9yaXplcyAiU3VjY2VzczogIgoJICoKCSAqIGBgYAoJICogV1BfQ0xJOjpjb2xvcml6ZSggIiVHU3VjY2VzczolbiAiICkKCSAqIGBgYAoJICoKCSAqIFVzZXMgYFxjbGlcQ29sb3JzOjpjb2xvcml6ZSgpYCB0byB0cmFuc2Zvcm0gY29sb3IgdG9rZW5zIHRvIGRpc3BsYXkKCSAqIHNldHRpbmdzLiBDaG9vc2UgZnJvbSB0aGUgZm9sbG93aW5nIHRva2VucyAoYW5kIG5vdGUgJ3Jlc2V0Jyk6CgkgKgoJICogKiAleSA9PiBbJ2NvbG9yJyA9PiAneWVsbG93J10sCgkgKiAqICVnID0+IFsnY29sb3InID0+ICdncmVlbiddLAoJICogKiAlYiA9PiBbJ2NvbG9yJyA9PiAnYmx1ZSddLAoJICogKiAlciA9PiBbJ2NvbG9yJyA9PiAncmVkJ10sCgkgKiAqICVwID0+IFsnY29sb3InID0+ICdtYWdlbnRhJ10sCgkgKiAqICVtID0+IFsnY29sb3InID0+ICdtYWdlbnRhJ10sCgkgKiAqICVjID0+IFsnY29sb3InID0+ICdjeWFuJ10sCgkgKiAqICV3ID0+IFsnY29sb3InID0+ICdncmV5J10sCgkgKiAqICVrID0+IFsnY29sb3InID0+ICdibGFjayddLAoJICogKiAlbiA9PiBbJ2NvbG9yJyA9PiAncmVzZXQnXSwKCSAqICogJVkgPT4gWydjb2xvcicgPT4gJ3llbGxvdycsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlRyA9PiBbJ2NvbG9yJyA9PiAnZ3JlZW4nLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJUIgPT4gWydjb2xvcicgPT4gJ2JsdWUnLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJVIgPT4gWydjb2xvcicgPT4gJ3JlZCcsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlUCA9PiBbJ2NvbG9yJyA9PiAnbWFnZW50YScsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlTSA9PiBbJ2NvbG9yJyA9PiAnbWFnZW50YScsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlQyA9PiBbJ2NvbG9yJyA9PiAnY3lhbicsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlVyA9PiBbJ2NvbG9yJyA9PiAnZ3JleScsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlSyA9PiBbJ2NvbG9yJyA9PiAnYmxhY2snLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJU4gPT4gWydjb2xvcicgPT4gJ3Jlc2V0JywgJ3N0eWxlJyA9PiAnYnJpZ2h0J10sCgkgKiAqICUzID0+IFsnYmFja2dyb3VuZCcgPT4gJ3llbGxvdyddLAoJICogKiAlMiA9PiBbJ2JhY2tncm91bmQnID0+ICdncmVlbiddLAoJICogKiAlNCA9PiBbJ2JhY2tncm91bmQnID0+ICdibHVlJ10sCgkgKiAqICUxID0+IFsnYmFja2dyb3VuZCcgPT4gJ3JlZCddLAoJICogKiAlNSA9PiBbJ2JhY2tncm91bmQnID0+ICdtYWdlbnRhJ10sCgkgKiAqICU2ID0+IFsnYmFja2dyb3VuZCcgPT4gJ2N5YW4nXSwKCSAqICogJTcgPT4gWydiYWNrZ3JvdW5kJyA9PiAnZ3JleSddLAoJICogKiAlMCA9PiBbJ2JhY2tncm91bmQnID0+ICdibGFjayddLAoJICogKiAlRiA9PiBbJ3N0eWxlJyA9PiAnYmxpbmsnXSwKCSAqICogJVUgPT4gWydzdHlsZScgPT4gJ3VuZGVybGluZSddLAoJICogKiAlOCA9PiBbJ3N0eWxlJyA9PiAnaW52ZXJzZSddLAoJICogKiAlOSA9PiBbJ3N0eWxlJyA9PiAnYnJpZ2h0J10sCgkgKiAqICVfID0+IFsnc3R5bGUnID0+ICdicmlnaHQnXQoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgT3V0cHV0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFN0cmluZyB0byBjb2xvcml6ZSBmb3Igb3V0cHV0LCB3aXRoIGNvbG9yIHRva2Vucy4KCSAqIEByZXR1cm4gc3RyaW5nIENvbG9yaXplZCBzdHJpbmcuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29sb3JpemUoICRzdHJpbmcgKSB7CgkJcmV0dXJuIENvbG9yczo6Y29sb3JpemUoICRzdHJpbmcsIHNlbGY6OmdldF9ydW5uZXIoKS0+aW5fY29sb3IoKSApOwoJfQoKCS8qKgoJICogU2NoZWR1bGUgYSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCBhdCBhIGNlcnRhaW4gcG9pbnQuCgkgKgoJICogSG9va3MgY29uY2VwdHVhbGx5IGFyZSB2ZXJ5IHNpbWlsYXIgdG8gV29yZFByZXNzIGFjdGlvbnMuIFdQLUNMSSBob29rcwoJICogYXJlIHR5cGljYWxseSBjYWxsZWQgYmVmb3JlIFdvcmRQcmVzcyBpcyBsb2FkZWQuCgkgKgoJICogV1AtQ0xJIGhvb2tzIGluY2x1ZGU6CgkgKgoJICogKiBgYmVmb3JlX2FkZF9jb21tYW5kOjxjb21tYW5kPmAgLSBCZWZvcmUgdGhlIGNvbW1hbmQgaXMgYWRkZWQuCgkgKiAqIGBhZnRlcl9hZGRfY29tbWFuZDo8Y29tbWFuZD5gIC0gQWZ0ZXIgdGhlIGNvbW1hbmQgd2FzIGFkZGVkLgoJICogKiBgYmVmb3JlX2ludm9rZTo8Y29tbWFuZD5gIC0gSnVzdCBiZWZvcmUgYSBjb21tYW5kIGlzIGludm9rZWQuCgkgKiAqIGBhZnRlcl9pbnZva2U6PGNvbW1hbmQ+YCAtIEp1c3QgYWZ0ZXIgYSBjb21tYW5kIGlzIGludm9rZWQuCgkgKiAqIGBmaW5kX2NvbW1hbmRfdG9fcnVuX3ByZWAgLSBKdXN0IGJlZm9yZSBXUC1DTEkgZmluZHMgdGhlIGNvbW1hbmQgdG8gcnVuLgoJICogKiBgYmVmb3JlX3JlZ2lzdGVyaW5nX2NvbnRleHRzYCAoMSkgLSBCZWZvcmUgdGhlIGNvbnRleHRzIGFyZSByZWdpc3RlcmVkLgoJICogKiBgYmVmb3JlX3dwX2xvYWRgIC0gSnVzdCBiZWZvcmUgdGhlIFdQIGxvYWQgcHJvY2VzcyBiZWdpbnMuCgkgKiAqIGBiZWZvcmVfd3BfY29uZmlnX2xvYWRgIC0gQWZ0ZXIgd3AtY29uZmlnLnBocCBoYXMgYmVlbiBsb2NhdGVkLgoJICogKiBgYWZ0ZXJfd3BfY29uZmlnX2xvYWRgIC0gQWZ0ZXIgd3AtY29uZmlnLnBocCBoYXMgYmVlbiBsb2FkZWQgaW50byBzY29wZS4KCSAqICogYGFmdGVyX3dwX2xvYWRgIC0gSnVzdCBhZnRlciB0aGUgV1AgbG9hZCBwcm9jZXNzIGhhcyBjb21wbGV0ZWQuCgkgKiAqIGBiZWZvcmVfcnVuX2NvbW1hbmRgICgzKSAtIEp1c3QgYmVmb3JlIHRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkLgoJICoKCSAqIFRoZSBwYXJlbnRoZXNlcyBiZWhpbmQgdGhlIGhvb2sgbmFtZSBkZW5vdGUgdGhlIG51bWJlciBvZiBhcmd1bWVudHMKCSAqIGJlaW5nIHBhc3NlZCBpbnRvIHRoZSBob29rLiBGb3Igc3VjaCBob29rcywgdGhlIGNhbGxiYWNrIHNob3VsZCByZXR1cm4KCSAqIHRoZSBmaXJzdCBhcmd1bWVudCBhZ2FpbiwgbWFraW5nIHRoZW0gd29yayBsaWtlIGEgV1AgZmlsdGVyLgoJICoKCSAqIFdQLUNMSSBjb21tYW5kcyBjYW4gY3JlYXRlIHRoZWlyIG93biBob29rcyB3aXRoIGBXUF9DTEk6OmRvX2hvb2soKWAuCgkgKgoJICogSWYgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHBhc3NlZCB0aHJvdWdoIHRoZSBgV1BfQ0xJOjpkb19ob29rKClgIGNhbGwsCgkgKiB0aGVzZSB3aWxsIGJlIHBhc3NlZCBvbiB0byB0aGUgY2FsbGJhY2sgcHJvdmlkZWQgYnkgYFdQX0NMSTo6YWRkX2hvb2soKWAuCgkgKgoJICogYGBgCgkgKiAjIGB3cCBuZXR3b3JrIG1ldGFgIGNvbmZpcm1zIGNvbW1hbmQgaXMgZXhlY3V0aW5nIGluIG11bHRpc2l0ZSBjb250ZXh0LgoJICogV1BfQ0xJOjphZGRfY29tbWFuZCggJ25ldHdvcmsgbWV0YScsICdOZXR3b3JrX01ldGFfQ29tbWFuZCcsIGFycmF5KAoJICogICAgJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uICgpIHsKCSAqICAgICAgICBpZiAoICFpc19tdWx0aXNpdGUoKSApIHsKCSAqICAgICAgICAgICAgV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkgKiAgICAgICAgfQoJICogICAgfQoJICogKSApOwoJICogYGBgCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBSZWdpc3RyYXRpb24KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3aGVuIElkZW50aWZpZXIgZm9yIHRoZSBob29rLgoJICogQHBhcmFtIG1peGVkICRjYWxsYmFjayBDYWxsYmFjayB0byBleGVjdXRlIHdoZW4gaG9vayBpcyBjYWxsZWQuCgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRfaG9vayggJHdoZW4sICRjYWxsYmFjayApIHsKCQlpZiAoIGFycmF5X2tleV9leGlzdHMoICR3aGVuLCBzZWxmOjokaG9va3NfcGFzc2VkICkgKSB7CgkJCXNlbGY6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknSW1tZWRpYXRlbHkgaW52b2tpbmcgb24gcGFzc2VkIGhvb2sgIiVzIjogJXMnLAoJCQkJCSR3aGVuLAoJCQkJCVV0aWxzXGRlc2NyaWJlX2NhbGxhYmxlKCAkY2FsbGJhY2sgKQoJCQkJKSwKCQkJCSdob29rcycKCQkJKTsKCQkJY2FsbF91c2VyX2Z1bmNfYXJyYXkoICRjYWxsYmFjaywgKGFycmF5KSBzZWxmOjokaG9va3NfcGFzc2VkWyAkd2hlbiBdICk7CgkJfQoKCQlzZWxmOjokaG9va3NbICR3aGVuIF1bXSA9ICRjYWxsYmFjazsKCX0KCgkvKioKCSAqIEV4ZWN1dGUgY2FsbGJhY2tzIHJlZ2lzdGVyZWQgdG8gYSBnaXZlbiBob29rLgoJICoKCSAqIFNlZSBgV1BfQ0xJOjphZGRfaG9vaygpYCBmb3IgZGV0YWlscyBvbiBXUC1DTEkncyBpbnRlcm5hbCBob29rIHN5c3RlbS4KCSAqIENvbW1hbmRzIGNhbiBwcm92aWRlIGFuZCBjYWxsIHRoZWlyIG93biBob29rcy4KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IFJlZ2lzdHJhdGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdoZW4gICAgSWRlbnRpZmllciBmb3IgdGhlIGhvb2suCgkgKiBAcGFyYW0gbWl4ZWQgIC4uLiRhcmdzIE9wdGlvbmFsLiBBcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCBvbnRvIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayBwcm92aWRlZCBieSBgV1BfQ0xJOjphZGRfaG9vaygpYC4KCSAqIEByZXR1cm4gbnVsbHxtaXhlZCBSZXR1cm5zIHRoZSBmaXJzdCBvcHRpb25hbCBhcmd1bWVudCBpZiBvcHRpb25hbAoJICogICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyB3ZXJlIHBhc3NlZCwgb3RoZXJ3aXNlIHJldHVybnMgbnVsbC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkb19ob29rKCAkd2hlbiwgLi4uJGFyZ3MgKSB7CgkJc2VsZjo6JGhvb2tzX3Bhc3NlZFsgJHdoZW4gXSA9ICRhcmdzOwoKCQkkaGFzX2FyZ3MgPSBjb3VudCggJGFyZ3MgKSA+IDA7CgoJCWlmICggISBpc3NldCggc2VsZjo6JGhvb2tzWyAkd2hlbiBdICkgKSB7CgkJCWlmICggJGhhc19hcmdzICkgewoJCQkJcmV0dXJuICRhcmdzWzBdOwoJCQl9CgoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXNlbGY6OmRlYnVnKAoJCQlzcHJpbnRmKAoJCQkJJ1Byb2Nlc3NpbmcgaG9vayAiJXMiIHdpdGggJWQgY2FsbGJhY2tzJywKCQkJCSR3aGVuLAoJCQkJY291bnQoIHNlbGY6OiRob29rc1sgJHdoZW4gXSApCgkJCSksCgkJCSdob29rcycKCQkpOwoKCQlmb3JlYWNoICggc2VsZjo6JGhvb2tzWyAkd2hlbiBdIGFzICRjYWxsYmFjayApIHsKCQkJc2VsZjo6ZGVidWcoCgkJCQlzcHJpbnRmKAoJCQkJCSdPbiBob29rICIlcyI6ICVzJywKCQkJCQkkd2hlbiwKCQkJCQlVdGlsc1xkZXNjcmliZV9jYWxsYWJsZSggJGNhbGxiYWNrICkKCQkJCSksCgkJCQknaG9va3MnCgkJCSk7CgoJCQlpZiAoICRoYXNfYXJncyApIHsKCQkJCSRyZXR1cm5fdmFsdWUgPSAkY2FsbGJhY2soIC4uLiRhcmdzICk7CgkJCQlpZiAoIGlzc2V0KCAkcmV0dXJuX3ZhbHVlICkgKSB7CgkJCQkJJGFyZ3NbMF0gPSAkcmV0dXJuX3ZhbHVlOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJGNhbGxiYWNrKCk7CgkJCX0KCQl9CgoJCWlmICggJGhhc19hcmdzICkgewoJCQlyZXR1cm4gJGFyZ3NbMF07CgkJfQoKCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIEFkZCBhIGNhbGxiYWNrIHRvIGEgV29yZFByZXNzIGFjdGlvbiBvciBmaWx0ZXIuCgkgKgoJICogYGFkZF9hY3Rpb24oKWAgd2l0aG91dCBuZWVkaW5nIGFjY2VzcyB0byBgYWRkX2FjdGlvbigpYC4gSWYgV29yZFByZXNzIGlzCgkgKiBhbHJlYWR5IGxvYWRlZCB0aG91Z2gsIHlvdSBzaG91bGQgdXNlIGBhZGRfYWN0aW9uKClgIChhbmQgYGFkZF9maWx0ZXIoKWApCgkgKiBpbnN0ZWFkLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgUmVnaXN0cmF0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGFnIE5hbWVkIFdvcmRQcmVzcyBhY3Rpb24gb3IgZmlsdGVyLgoJICogQHBhcmFtIG1peGVkICRmdW5jdGlvbl90b19hZGQgQ2FsbGFibGUgdG8gZXhlY3V0ZSB3aGVuIHRoZSBhY3Rpb24gb3IgZmlsdGVyIGlzIGV2YWx1YXRlZC4KCSAqIEBwYXJhbSBpbnRlZ2VyICRwcmlvcml0eSBQcmlvcml0eSB0byBhZGQgdGhlIGNhbGxiYWNrIGFzLgoJICogQHBhcmFtIGludGVnZXIgJGFjY2VwdGVkX2FyZ3MgTnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwYXNzIHRvIGNhbGxiYWNrLgoJICogQHJldHVybiB0cnVlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWRkX3dwX2hvb2soICR0YWcsICRmdW5jdGlvbl90b19hZGQsICRwcmlvcml0eSA9IDEwLCAkYWNjZXB0ZWRfYXJncyA9IDEgKSB7CgkJZ2xvYmFsICR3cF9maWx0ZXIsICRtZXJnZWRfZmlsdGVyczsKCgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdhZGRfZmlsdGVyJyApICkgewoJCQlhZGRfZmlsdGVyKCAkdGFnLCAkZnVuY3Rpb25fdG9fYWRkLCAkcHJpb3JpdHksICRhY2NlcHRlZF9hcmdzICk7CgkJfSBlbHNlIHsKCQkJJGlkeCA9IHNlbGY6OndwX2hvb2tfYnVpbGRfdW5pcXVlX2lkKCAkdGFnLCAkZnVuY3Rpb25fdG9fYWRkLCAkcHJpb3JpdHkgKTsKCgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBUaGlzIGlzIGludGVudGlvbmFsICYgdGhlIHB1cnBvc2Ugb2YgdGhpcyBmdW5jdGlvbi4KCQkJJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXVsgJGlkeCBdID0gWwoJCQkJJ2Z1bmN0aW9uJyAgICAgID0+ICRmdW5jdGlvbl90b19hZGQsCgkJCQknYWNjZXB0ZWRfYXJncycgPT4gJGFjY2VwdGVkX2FyZ3MsCgkJCV07CgkJCXVuc2V0KCAkbWVyZ2VkX2ZpbHRlcnNbICR0YWcgXSApOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBCdWlsZCBVbmlxdWUgSUQgZm9yIHN0b3JhZ2UgYW5kIHJldHJpZXZhbC4KCSAqCgkgKiBFc3NlbnRpYWxseSBfd3BfZmlsdGVyX2J1aWxkX3VuaXF1ZV9pZCgpIHdpdGhvdXQgbmVlZGluZyBhY2Nlc3MgdG8gX3dwX2ZpbHRlcl9idWlsZF91bmlxdWVfaWQoKQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB3cF9ob29rX2J1aWxkX3VuaXF1ZV9pZCggJHRhZywgJGZ1bmN0aW9uLCAkcHJpb3JpdHkgKSB7CgkJZ2xvYmFsICR3cF9maWx0ZXI7CgkJc3RhdGljICRmaWx0ZXJfaWRfY291bnQgPSAwOwoKCQlpZiAoIGlzX3N0cmluZyggJGZ1bmN0aW9uICkgKSB7CgkJCXJldHVybiAkZnVuY3Rpb247CgkJfQoKCQlpZiAoIGlzX29iamVjdCggJGZ1bmN0aW9uICkgKSB7CgkJCS8vIENsb3N1cmVzIGFyZSBjdXJyZW50bHkgaW1wbGVtZW50ZWQgYXMgb2JqZWN0cwoJCQkkZnVuY3Rpb24gPSBbICRmdW5jdGlvbiwgJycgXTsKCQl9IGVsc2UgewoJCQkkZnVuY3Rpb24gPSAoYXJyYXkpICRmdW5jdGlvbjsKCQl9CgoJCWlmICggaXNfb2JqZWN0KCAkZnVuY3Rpb25bMF0gKSApIHsKCQkJLy8gT2JqZWN0IENsYXNzIENhbGxpbmcKCQkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdzcGxfb2JqZWN0X2hhc2gnICkgKSB7CgkJCQlyZXR1cm4gc3BsX29iamVjdF9oYXNoKCAkZnVuY3Rpb25bMF0gKSAuICRmdW5jdGlvblsxXTsKCQkJfQoKCQkJJG9ial9pZHggPSBnZXRfY2xhc3MoICRmdW5jdGlvblswXSApIC4gJGZ1bmN0aW9uWzFdOwoJCQlpZiAoICEgaXNzZXQoICRmdW5jdGlvblswXS0+d3BfZmlsdGVyX2lkICkgKSB7CgkJCQlpZiAoIGZhbHNlID09PSAkcHJpb3JpdHkgKSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQkJJG9ial9pZHggICAgICAgICAgICAgICAgICAuPSBpc3NldCggJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXSApID8gY291bnQoIChhcnJheSkgJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXSApIDogJGZpbHRlcl9pZF9jb3VudDsKCQkJCSRmdW5jdGlvblswXS0+d3BfZmlsdGVyX2lkID0gJGZpbHRlcl9pZF9jb3VudDsKCQkJCSsrJGZpbHRlcl9pZF9jb3VudDsKCQkJfSBlbHNlIHsKCQkJCSRvYmpfaWR4IC49ICRmdW5jdGlvblswXS0+d3BfZmlsdGVyX2lkOwoJCQl9CgoJCQlyZXR1cm4gJG9ial9pZHg7CgkJfQoKCQlpZiAoIGlzX3N0cmluZyggJGZ1bmN0aW9uWzBdICkgKSB7CgkJCS8vIFN0YXRpYyBDYWxsaW5nCgkJCXJldHVybiAkZnVuY3Rpb25bMF0gLiAnOjonIC4gJGZ1bmN0aW9uWzFdOwoJCX0KCX0KCgkvKioKCSAqIFJlZ2lzdGVyIGEgY29tbWFuZCB0byBXUC1DTEkuCgkgKgoJICogV1AtQ0xJIHN1cHBvcnRzIHVzaW5nIGFueSBjYWxsYWJsZSBjbGFzcywgZnVuY3Rpb24sIG9yIGNsb3N1cmUgYXMgYQoJICogY29tbWFuZC4gYFdQX0NMSTo6YWRkX2NvbW1hbmQoKWAgaXMgdXNlZCBmb3IgYm90aCBpbnRlcm5hbCBhbmQKCSAqIHRoaXJkLXBhcnR5IGNvbW1hbmQgcmVnaXN0cmF0aW9uLgoJICoKCSAqIENvbW1hbmQgYXJndW1lbnRzIGFyZSBwYXJzZWQgZnJvbSBQSFBEb2MgYnkgZGVmYXVsdCwgYnV0IGFsc28gY2FuIGJlCgkgKiBzdXBwbGllZCBhcyBhbiBvcHRpb25hbCB0aGlyZCBhcmd1bWVudCBkdXJpbmcgcmVnaXN0cmF0aW9uLgoJICoKCSAqIGBgYAoJICogIyBSZWdpc3RlciBhIGN1c3RvbSAnZm9vJyBjb21tYW5kIHRvIG91dHB1dCBhIHN1cHBsaWVkIHBvc2l0aW9uYWwgcGFyYW0uCgkgKiAjCgkgKiAjICQgd3AgZm9vIGJhciAtLWFwcGVuZD1xdXgKCSAqICMgU3VjY2VzczogYmFyIHF1eAoJICoKCSAqIC8qKgoJICogICogTXkgYXdlc29tZSBjbG9zdXJlIGNvbW1hbmQKCSAqICAqCgkgKiAgKiA8bWVzc2FnZT4KCSAqICAqIDogQW4gYXdlc29tZSBtZXNzYWdlIHRvIGRpc3BsYXkKCSAqICAqCgkgKiAgKiAtLWFwcGVuZD08bWVzc2FnZT4KCSAqICAqIDogQW4gYXdlc29tZSBtZXNzYWdlIHRvIGFwcGVuZCB0byB0aGUgb3JpZ2luYWwgbWVzc2FnZS4KCSAqICAqCgkgKiAgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICogICpcLwoJICogJGZvbyA9IGZ1bmN0aW9uKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkgKiAgICAgV1BfQ0xJOjpzdWNjZXNzKCAkYXJnc1swXSAuICcgJyAuICRhc3NvY19hcmdzWydhcHBlbmQnXSApOwoJICogfTsKCSAqIFdQX0NMSTo6YWRkX2NvbW1hbmQoICdmb28nLCAkZm9vICk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IFJlZ2lzdHJhdGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAkbmFtZSBOYW1lIGZvciB0aGUgY29tbWFuZCAoZS5nLiAicG9zdCBsaXN0IiBvciAic2l0ZSBlbXB0eSIpLgoJICogQHBhcmFtIGNhbGxhYmxlICRjYWxsYWJsZSBDb21tYW5kIGltcGxlbWVudGF0aW9uIGFzIGEgY2xhc3MsIGZ1bmN0aW9uIG9yIGNsb3N1cmUuCgkgKiBAcGFyYW0gYXJyYXkgICAgJGFyZ3MgewoJICogICAgT3B0aW9uYWwuIEFuIGFzc29jaWF0aXZlIGFycmF5IHdpdGggYWRkaXRpb25hbCByZWdpc3RyYXRpb24gcGFyYW1ldGVycy4KCSAqCgkgKiAgICBAdHlwZSBjYWxsYWJsZSAkYmVmb3JlX2ludm9rZSBDYWxsYmFjayB0byBleGVjdXRlIGJlZm9yZSBpbnZva2luZyB0aGUgY29tbWFuZC4KCSAqICAgIEB0eXBlIGNhbGxhYmxlICRhZnRlcl9pbnZva2UgIENhbGxiYWNrIHRvIGV4ZWN1dGUgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbW1hbmQuCgkgKiAgICBAdHlwZSBzdHJpbmcgICAkc2hvcnRkZXNjICAgICBTaG9ydCBkZXNjcmlwdGlvbiAoODAgY2hhciBvciBsZXNzKSBmb3IgdGhlIGNvbW1hbmQuCgkgKiAgICBAdHlwZSBzdHJpbmcgICAkbG9uZ2Rlc2MgICAgICBEZXNjcmlwdGlvbiBvZiBhcmJpdHJhcnkgbGVuZ3RoIGZvciBleGFtcGxlcywgZXRjLgoJICogICAgQHR5cGUgc3RyaW5nICAgJHN5bm9wc2lzICAgICAgVGhlIHN5bm9wc2lzIGZvciB0aGUgY29tbWFuZCAoc3RyaW5nIG9yIGFycmF5KS4KCSAqICAgIEB0eXBlIHN0cmluZyAgICR3aGVuICAgICAgICAgIEV4ZWN1dGUgY2FsbGJhY2sgb24gYSBuYW1lZCBXUC1DTEkgaG9vayAoZS5nLiBiZWZvcmVfd3BfbG9hZCkuCgkgKiAgICBAdHlwZSBib29sICAgICAkaXNfZGVmZXJyZWQgICBXaGV0aGVyIHRoZSBjb21tYW5kIGFkZGl0aW9uIGhhZCBhbHJlYWR5IGJlZW4gZGVmZXJyZWQuCgkgKiB9CgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBpZiBkZWZlcnJlZCwgaGFyZCBlcnJvciBpZiByZWdpc3RyYXRpb24gZmFpbGVkLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFkZF9jb21tYW5kKCAkbmFtZSwgJGNhbGxhYmxlLCAkYXJncyA9IFtdICkgewoJCS8vIEJhaWwgaW1tZWRpYXRlbHkgaWYgdGhlIFdQLUNMSSBleGVjdXRhYmxlIGhhcyBub3QgYmVlbiBydW4uCgkJaWYgKCAhIGRlZmluZWQoICdXUF9DTEknICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSR2YWxpZCA9IGZhbHNlOwoJCWlmICggaXNfY2FsbGFibGUoICRjYWxsYWJsZSApICkgewoJCQkkdmFsaWQgPSB0cnVlOwoJCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkY2FsbGFibGUgKSAmJiBjbGFzc19leGlzdHMoIChzdHJpbmcpICRjYWxsYWJsZSApICkgewoJCQkkdmFsaWQgPSB0cnVlOwoJCX0gZWxzZWlmICggaXNfb2JqZWN0KCAkY2FsbGFibGUgKSApIHsKCQkJJHZhbGlkID0gdHJ1ZTsKCQl9IGVsc2VpZiAoIFV0aWxzXGlzX3ZhbGlkX2NsYXNzX2FuZF9tZXRob2RfcGFpciggJGNhbGxhYmxlICkgKSB7CgkJCSR2YWxpZCA9IHRydWU7CgkJfQoJCWlmICggISAkdmFsaWQgKSB7CgkJCWlmICggaXNfYXJyYXkoICRjYWxsYWJsZSApICkgewoJCQkJJGNhbGxhYmxlWzBdID0gaXNfb2JqZWN0KCAkY2FsbGFibGVbMF0gKSA/IGdldF9jbGFzcyggJGNhbGxhYmxlWzBdICkgOiAkY2FsbGFibGVbMF07CgkJCQkkY2FsbGFibGUgICAgPSBbICRjYWxsYWJsZVswXSwgJGNhbGxhYmxlWzFdIF07CgkJCX0KCQkJc2VsZjo6ZXJyb3IoIHNwcmludGYoICdDYWxsYWJsZSAlcyBkb2VzIG5vdCBleGlzdCwgYW5kIGNhbm5vdCBiZSByZWdpc3RlcmVkIGFzIGB3cCAlc2AuJywganNvbl9lbmNvZGUoICRjYWxsYWJsZSApLCAkbmFtZSApICk7CgkJfQoKCQkkYWRkaXRpb24gPSBuZXcgQ29tbWFuZEFkZGl0aW9uKCk7CgkJc2VsZjo6ZG9faG9vayggImJlZm9yZV9hZGRfY29tbWFuZDp7JG5hbWV9IiwgJGFkZGl0aW9uICk7CgoJCWlmICggJGFkZGl0aW9uLT53YXNfYWJvcnRlZCgpICkgewoJCQlzZWxmOjp3YXJuaW5nKCAiQWJvcnRpbmcgdGhlIGFkZGl0aW9uIG9mIHRoZSBjb21tYW5kICd7JG5hbWV9JyB3aXRoIHJlYXNvbjogeyRhZGRpdGlvbi0+Z2V0X3JlYXNvbigpfS4iICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWZvcmVhY2ggKCBbICdiZWZvcmVfaW52b2tlJywgJ2FmdGVyX2ludm9rZScgXSBhcyAkd2hlbiApIHsKCQkJaWYgKCBpc3NldCggJGFyZ3NbICR3aGVuIF0gKSApIHsKCQkJCXNlbGY6OmFkZF9ob29rKCAieyR3aGVufTp7JG5hbWV9IiwgJGFyZ3NbICR3aGVuIF0gKTsKCQkJfQoJCX0KCgkJJHBhdGggPSBwcmVnX3NwbGl0KCAnL1xzKy8nLCAkbmFtZSApOwoKCQkkbGVhZl9uYW1lID0gYXJyYXlfcG9wKCAkcGF0aCApOwoKCQkkY29tbWFuZCA9IHNlbGY6OmdldF9yb290X2NvbW1hbmQoKTsKCgkJd2hpbGUgKCAhIGVtcHR5KCAkcGF0aCApICkgewoJCQkkc3ViY29tbWFuZF9uYW1lID0gJHBhdGhbMF07CgkJCSRwYXJlbnQgICAgICAgICAgPSBpbXBsb2RlKCAnICcsICRwYXRoICk7CgkJCSRzdWJjb21tYW5kICAgICAgPSAkY29tbWFuZC0+ZmluZF9zdWJjb21tYW5kKCAkcGF0aCApOwoKCQkJLy8gUGFyZW50IG5vdCBmb3VuZC4gRGVmZXIgYWRkaXRpb24gb3IgY3JlYXRlIGFuIGVtcHR5IGNvbnRhaW5lciBhcwoJCQkvLyBuZWVkZWQuCgkJCWlmICggISAkc3ViY29tbWFuZCApIHsKCQkJCWlmICggaXNzZXQoICRhcmdzWydpc19kZWZlcnJlZCddICkgJiYgJGFyZ3NbJ2lzX2RlZmVycmVkJ10gKSB7CgkJCQkJJHN1YmNvbW1hbmQgPSBuZXcgQ29tcG9zaXRlQ29tbWFuZCgKCQkJCQkJJGNvbW1hbmQsCgkJCQkJCSRzdWJjb21tYW5kX25hbWUsCgkJCQkJCW5ldyBEb2NQYXJzZXIoICcnICkKCQkJCQkpOwoKCQkJCQlzZWxmOjpkZWJ1ZygKCQkJCQkJIkFkZGluZyBlbXB0eSBjb250YWluZXIgZm9yIGRlZmVycmVkIGNvbW1hbmQ6IHskbmFtZX0iLAoJCQkJCQknY29tbWFuZHMnCgkJCQkJKTsKCgkJCQkJJGNvbW1hbmQtPmFkZF9zdWJjb21tYW5kKCAkc3ViY29tbWFuZF9uYW1lLCAkc3ViY29tbWFuZCApOwoJCQkJfSBlbHNlIHsKCQkJCQlzZWxmOjpkZWJ1ZyggIkRlZmVycmluZyBjb21tYW5kOiB7JG5hbWV9IiwgJ2NvbW1hbmRzJyApOwoKCQkJCQlzZWxmOjpkZWZlcl9jb21tYW5kX2FkZGl0aW9uKAoJCQkJCQkkbmFtZSwKCQkJCQkJJHBhcmVudCwKCQkJCQkJJGNhbGxhYmxlLAoJCQkJCQkkYXJncwoJCQkJCSk7CgoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfQoKCQkJJGNvbW1hbmQgPSAkc3ViY29tbWFuZDsKCQl9CgoJCSRsZWFmX2NvbW1hbmQgPSBDb21tYW5kRmFjdG9yeTo6Y3JlYXRlKCAkbGVhZl9uYW1lLCAkY2FsbGFibGUsICRjb21tYW5kICk7CgoJCS8vIE9ubHkgYWRkIGEgY29tbWFuZCBuYW1lc3BhY2UgaWYgdGhlIGNvbW1hbmQgaXRzZWxmIGRvZXMgbm90IGV4aXN0IHlldC4KCQlpZiAoICRsZWFmX2NvbW1hbmQgaW5zdGFuY2VvZiBDb21tYW5kTmFtZXNwYWNlCgkJCSYmIGFycmF5X2tleV9leGlzdHMoICRsZWFmX25hbWUsICRjb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBSZWF0dGFjaCBjb21tYW5kcyBhdHRhY2hlZCB0byBuYW1lc3BhY2UgdG8gcmVhbCBjb21tYW5kLgoJCSRzdWJjb21tYW5kX25hbWUgID0gKGFycmF5KSAkbGVhZl9uYW1lOwoJCSRleGlzdGluZ19jb21tYW5kID0gJGNvbW1hbmQtPmZpbmRfc3ViY29tbWFuZCggJHN1YmNvbW1hbmRfbmFtZSApOwoJCWlmICggJGV4aXN0aW5nX2NvbW1hbmQgaW5zdGFuY2VvZiBDb21wb3NpdGVDb21tYW5kICYmICRleGlzdGluZ19jb21tYW5kLT5jYW5faGF2ZV9zdWJjb21tYW5kcygpICkgewoJCQlpZiAoICRsZWFmX2NvbW1hbmQgaW5zdGFuY2VvZiBDb21tYW5kTmFtZXNwYWNlIHx8ICEgJGxlYWZfY29tbWFuZC0+Y2FuX2hhdmVfc3ViY29tbWFuZHMoKSApIHsKCQkJCSRjb21tYW5kX3RvX2tlZXAgPSAkZXhpc3RpbmdfY29tbWFuZDsKCQkJfSBlbHNlIHsKCQkJCSRjb21tYW5kX3RvX2tlZXAgPSAkbGVhZl9jb21tYW5kOwoJCQl9CgoJCQlzZWxmOjptZXJnZV9zdWJfY29tbWFuZHMoICRjb21tYW5kX3RvX2tlZXAsICRleGlzdGluZ19jb21tYW5kLCAkbGVhZl9jb21tYW5kICk7CgkJfQoKCQkvKiogQHZhciBEaXNwYXRjaGVyXFN1YmNvbW1hbmR8RGlzcGF0Y2hlclxDb21wb3NpdGVDb21tYW5kfERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZSAkbGVhZl9jb21tYW5kICovCgoJCWlmICggISAkY29tbWFuZC0+Y2FuX2hhdmVfc3ViY29tbWFuZHMoKSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbigKCQkJCXNwcmludGYoCgkJCQkJIiclcycgY2FuJ3QgaGF2ZSBzdWJjb21tYW5kcy4iLAoJCQkJCWltcGxvZGUoICcgJywgZ2V0X3BhdGgoICRjb21tYW5kICkgKQoJCQkJKQoJCQkpOwoJCX0KCgkJaWYgKCBpc3NldCggJGFyZ3NbJ3Nob3J0ZGVzYyddICkgKSB7CgkJCSRsZWFmX2NvbW1hbmQtPnNldF9zaG9ydGRlc2MoICRhcmdzWydzaG9ydGRlc2MnXSApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFyZ3NbJ2xvbmdkZXNjJ10gKSApIHsKCQkJJGxlYWZfY29tbWFuZC0+c2V0X2xvbmdkZXNjKCAkYXJnc1snbG9uZ2Rlc2MnXSApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFyZ3NbJ3N5bm9wc2lzJ10gKSApIHsKCQkJaWYgKCBpc19zdHJpbmcoICRhcmdzWydzeW5vcHNpcyddICkgKSB7CgkJCQkkbGVhZl9jb21tYW5kLT5zZXRfc3lub3BzaXMoICRhcmdzWydzeW5vcHNpcyddICk7CgkJCX0gZWxzZWlmICggaXNfYXJyYXkoICRhcmdzWydzeW5vcHNpcyddICkgKSB7CgkJCQkkc3lub3BzaXMgPSBTeW5vcHNpc1BhcnNlcjo6cmVuZGVyKCAkYXJnc1snc3lub3BzaXMnXSApOwoJCQkJJGxlYWZfY29tbWFuZC0+c2V0X3N5bm9wc2lzKCAkc3lub3BzaXMgKTsKCQkJCSRsb25nX2Rlc2MgPSAnJzsKCQkJCSRiaXRzICAgICAgPSBleHBsb2RlKCAnICcsICRzeW5vcHNpcyApOwoJCQkJZm9yZWFjaCAoICRhcmdzWydzeW5vcHNpcyddIGFzICRrZXkgPT4gJGFyZyApIHsKCQkJCQkkbG9uZ19kZXNjIC49ICRiaXRzWyAka2V5IF0gLiAiXG4iOwoJCQkJCWlmICggISBlbXB0eSggJGFyZ1snZGVzY3JpcHRpb24nXSApICkgewoJCQkJCQkkbG9uZ19kZXNjIC49ICc6ICcgLiAkYXJnWydkZXNjcmlwdGlvbiddIC4gIlxuIjsKCQkJCQl9CgkJCQkJJHlhbWxpZnkgPSBbXTsKCQkJCQlmb3JlYWNoICggWyAnZGVmYXVsdCcsICdvcHRpb25zJyBdIGFzICRrZXkgKSB7CgkJCQkJCWlmICggaXNzZXQoICRhcmdbICRrZXkgXSApICkgewoJCQkJCQkJJHlhbWxpZnlbICRrZXkgXSA9ICRhcmdbICRrZXkgXTsKCQkJCQkJfQoJCQkJCX0KCQkJCQlpZiAoICEgZW1wdHkoICR5YW1saWZ5ICkgKSB7CgkJCQkJCSRsb25nX2Rlc2MgLj0gU3B5Yzo6WUFNTER1bXAoICR5YW1saWZ5ICk7CgkJCQkJCSRsb25nX2Rlc2MgLj0gJy0tLScgLiAiXG4iOwoJCQkJCX0KCQkJCQkkbG9uZ19kZXNjIC49ICJcbiI7CgkJCQl9CgkJCQlpZiAoICEgZW1wdHkoICRsb25nX2Rlc2MgKSApIHsKCQkJCQkkbG9uZ19kZXNjID0gcnRyaW0oICRsb25nX2Rlc2MsICJcclxuIiApOwoJCQkJCSRsb25nX2Rlc2MgPSAnIyMgT1BUSU9OUycgLiAiXG5cbiIgLiAkbG9uZ19kZXNjOwoJCQkJCWlmICggISBlbXB0eSggJGFyZ3NbJ2xvbmdkZXNjJ10gKSApIHsKCQkJCQkJJGxvbmdfZGVzYyAuPSAiXG5cbiIgLiBsdHJpbSggJGFyZ3NbJ2xvbmdkZXNjJ10sICJcclxuIiApOwoJCQkJCX0KCQkJCQkkbGVhZl9jb21tYW5kLT5zZXRfbG9uZ2Rlc2MoICRsb25nX2Rlc2MgKTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCBpc3NldCggJGFyZ3NbJ3doZW4nXSApICkgewoJCQlzZWxmOjpnZXRfcnVubmVyKCktPnJlZ2lzdGVyX2Vhcmx5X2ludm9rZSggJGFyZ3NbJ3doZW4nXSwgJGxlYWZfY29tbWFuZCApOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkcGFyZW50ICkgKSB7CgkJCSRzdWJfY29tbWFuZCA9IHRyaW0oIHN0cl9yZXBsYWNlKCAkcGFyZW50LCAnJywgJG5hbWUgKSApOwoJCQlzZWxmOjpkZWJ1ZyggIkFkZGluZyBjb21tYW5kOiB7JHN1Yl9jb21tYW5kfSBpbiB7JHBhcmVudH0gTmFtZXNwYWNlIiwgJ2NvbW1hbmRzJyApOwoJCX0gZWxzZSB7CgkJCXNlbGY6OmRlYnVnKCAiQWRkaW5nIGNvbW1hbmQ6IHskbmFtZX0iLCAnY29tbWFuZHMnICk7CgkJfQoKCQkkY29tbWFuZC0+YWRkX3N1YmNvbW1hbmQoICRsZWFmX25hbWUsICRsZWFmX2NvbW1hbmQgKTsKCgkJc2VsZjo6ZG9faG9vayggImFmdGVyX2FkZF9jb21tYW5kOnskbmFtZX0iICk7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBNZXJnZSB0aGUgc3ViLWNvbW1hbmRzIG9mIHR3byBjb21tYW5kcyBpbnRvIGEgc2luZ2xlIGNvbW1hbmQgdG8ga2VlcC4KCSAqCgkgKiBAcGFyYW0gQ29tcG9zaXRlQ29tbWFuZCAkY29tbWFuZF90b19rZWVwIENvbW1hbmQgdG8gbWVyZ2UgdGhlIHN1YiBjb21tYW5kcyBpbnRvLiBUaGlzIGlzIHR5cGljYWxseSBvbmUgb2YgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR3byBvdGhlcnMuCgkgKiBAcGFyYW0gQ29tcG9zaXRlQ29tbWFuZCAkb2xkX2NvbW1hbmQgICAgIENvbW1hbmQgdGhhdCB3YXMgYWxyZWFkeSByZWdpc3RlcmVkLgoJICogQHBhcmFtIENvbXBvc2l0ZUNvbW1hbmQgJG5ld19jb21tYW5kICAgICBOZXcgY29tbWFuZCB0aGF0IGlzIGJlaW5nIGFkZGVkLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBtZXJnZV9zdWJfY29tbWFuZHMoCgkJQ29tcG9zaXRlQ29tbWFuZCAkY29tbWFuZF90b19rZWVwLAoJCUNvbXBvc2l0ZUNvbW1hbmQgJG9sZF9jb21tYW5kLAoJCUNvbXBvc2l0ZUNvbW1hbmQgJG5ld19jb21tYW5kCgkpIHsKCQlmb3JlYWNoICggJG9sZF9jb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSBhcyAkc3VibmFtZSA9PiAkc3ViY29tbWFuZCApIHsKCQkJJGNvbW1hbmRfdG9fa2VlcC0+YWRkX3N1YmNvbW1hbmQoICRzdWJuYW1lLCAkc3ViY29tbWFuZCwgZmFsc2UgKTsKCQl9CgoJCWZvcmVhY2ggKCAkbmV3X2NvbW1hbmQtPmdldF9zdWJjb21tYW5kcygpIGFzICRzdWJuYW1lID0+ICRzdWJjb21tYW5kICkgewoJCQkkY29tbWFuZF90b19rZWVwLT5hZGRfc3ViY29tbWFuZCggJHN1Ym5hbWUsICRzdWJjb21tYW5kLCB0cnVlICk7CgkJfQoJfQoKCS8qKgoJICogRGVmZXIgY29tbWFuZCBhZGRpdGlvbiBmb3IgYSBzdWItY29tbWFuZCBpZiB0aGUgcGFyZW50IGNvbW1hbmQgaXMgbm90IHlldAoJICogcmVnaXN0ZXJlZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgICBOYW1lIGZvciB0aGUgc3ViLWNvbW1hbmQuCgkgKiBAcGFyYW0gc3RyaW5nICRwYXJlbnQgICBOYW1lIGZvciB0aGUgcGFyZW50IGNvbW1hbmQuCgkgKiBAcGFyYW0gc3RyaW5nICRjYWxsYWJsZSBDb21tYW5kIGltcGxlbWVudGF0aW9uIGFzIGEgY2xhc3MsIGZ1bmN0aW9uIG9yIGNsb3N1cmUuCgkgKiBAcGFyYW0gYXJyYXkgICRhcmdzICAgICBPcHRpb25hbC4gU2VlIGBXUF9DTEk6OmFkZF9jb21tYW5kKClgIGZvciBkZXRhaWxzLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBkZWZlcl9jb21tYW5kX2FkZGl0aW9uKCAkbmFtZSwgJHBhcmVudCwgJGNhbGxhYmxlLCAkYXJncyA9IFtdICkgewoJCSRhcmdzWydpc19kZWZlcnJlZCddICAgICAgICAgICAgICAgPSB0cnVlOwoJCXNlbGY6OiRkZWZlcnJlZF9hZGRpdGlvbnNbICRuYW1lIF0gPSBbCgkJCSdwYXJlbnQnICAgPT4gJHBhcmVudCwKCQkJJ2NhbGxhYmxlJyA9PiAkY2FsbGFibGUsCgkJCSdhcmdzJyAgICAgPT4gJGFyZ3MsCgkJXTsKCQlzZWxmOjphZGRfaG9vaygKCQkJImFmdGVyX2FkZF9jb21tYW5kOiRwYXJlbnQiLAoJCQlmdW5jdGlvbiAoKSB1c2UgKCAkbmFtZSApIHsKCQkJCSRkZWZlcnJlZF9hZGRpdGlvbnMgPSBXUF9DTEk6OmdldF9kZWZlcnJlZF9hZGRpdGlvbnMoKTsKCgkJCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJG5hbWUsICRkZWZlcnJlZF9hZGRpdGlvbnMgKSApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJJGNhbGxhYmxlID0gJGRlZmVycmVkX2FkZGl0aW9uc1sgJG5hbWUgXVsnY2FsbGFibGUnXTsKCQkJCSRhcmdzICAgICA9ICRkZWZlcnJlZF9hZGRpdGlvbnNbICRuYW1lIF1bJ2FyZ3MnXTsKCQkJCVdQX0NMSTo6cmVtb3ZlX2RlZmVycmVkX2FkZGl0aW9uKCAkbmFtZSApOwoKCQkJCVdQX0NMSTo6YWRkX2NvbW1hbmQoICRuYW1lLCAkY2FsbGFibGUsICRhcmdzICk7CgkJCX0KCQkpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBsaXN0IG9mIG91dHN0YW5kaW5nIGRlZmVycmVkIGNvbW1hbmQgYWRkaXRpb25zLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgb2Ygb3V0c3RhbmRpbmcgY29tbWFuZCBhZGRpdGlvbnMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X2RlZmVycmVkX2FkZGl0aW9ucygpIHsKCQlyZXR1cm4gc2VsZjo6JGRlZmVycmVkX2FkZGl0aW9uczsKCX0KCgkvKioKCSAqIFJlbW92ZSBhIGNvbW1hbmQgYWRkaXRpb24gZnJvbSB0aGUgbGlzdCBvZiBvdXRzdGFuZGluZyBkZWZlcnJlZCBhZGRpdGlvbnMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVtb3ZlX2RlZmVycmVkX2FkZGl0aW9uKCAkbmFtZSApIHsKCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJG5hbWUsIHNlbGY6OiRkZWZlcnJlZF9hZGRpdGlvbnMgKSApIHsKCQkJc2VsZjo6d2FybmluZyggIlRyeWluZyB0byByZW1vdmUgYSBub24tZXhpc3RlbnQgY29tbWFuZCBhZGRpdGlvbiAneyRuYW1lfScuIiApOwoJCX0KCgkJdW5zZXQoIHNlbGY6OiRkZWZlcnJlZF9hZGRpdGlvbnNbICRuYW1lIF0gKTsKCX0KCgkvKioKCSAqIERpc3BsYXkgaW5mb3JtYXRpb25hbCBtZXNzYWdlIHdpdGhvdXQgcHJlZml4LCBhbmQgaWdub3JlIGAtLXF1aWV0YC4KCSAqCgkgKiBNZXNzYWdlIGlzIHdyaXR0ZW4gdG8gU1RET1VULiBgV1BfQ0xJOjpsb2coKWAgaXMgdHlwaWNhbGx5IHJlY29tbWVuZGVkOwoJICogYFdQX0NMSTo6bGluZSgpYCBpcyBpbmNsdWRlZCBmb3IgaGlzdG9yaWNhbCBjb21wYXQuCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBPdXRwdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gZGlzcGxheSB0byB0aGUgZW5kIHVzZXIuCgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBsaW5lKCAkbWVzc2FnZSA9ICcnICkgewoJCWVjaG8gJG1lc3NhZ2UgLiAiXG4iOwoJfQoKCS8qKgoJICogRGlzcGxheSBpbmZvcm1hdGlvbmFsIG1lc3NhZ2Ugd2l0aG91dCBwcmVmaXguCgkgKgoJICogTWVzc2FnZSBpcyB3cml0dGVuIHRvIFNURE9VVCwgb3IgZGlzY2FyZGVkIHdoZW4gYC0tcXVpZXRgIGZsYWcgaXMgc3VwcGxpZWQuCgkgKgoJICogYGBgCgkgKiAjIGB3cCBjbGkgdXBkYXRlYCBsZXRzIHVzZXIga25vdyBvZiBlYWNoIHN0ZXAgaW4gdGhlIHVwZGF0ZSBwcm9jZXNzLgoJICogV1BfQ0xJOjpsb2coIHNwcmludGYoICdEb3dubG9hZGluZyBmcm9tICVzLi4uJywgJGRvd25sb2FkX3VybCApICk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IE91dHB1dAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgTWVzc2FnZSB0byB3cml0ZSB0byBTVERPVVQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbG9nKCAkbWVzc2FnZSApIHsKCQlpZiAoIG51bGwgPT09IHNlbGY6OiRsb2dnZXIgKSB7CgkJCXJldHVybjsKCQl9CgoJCXNlbGY6OiRsb2dnZXItPmluZm8oICRtZXNzYWdlICk7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IHN1Y2Nlc3MgbWVzc2FnZSBwcmVmaXhlZCB3aXRoICJTdWNjZXNzOiAiLgoJICoKCSAqIFN1Y2Nlc3MgbWVzc2FnZSBpcyB3cml0dGVuIHRvIFNURE9VVC4KCSAqCgkgKiBUeXBpY2FsbHkgcmVjb21tZW5kZWQgdG8gaW5mb3JtIHVzZXIgb2Ygc3VjY2Vzc2Z1bCBzY3JpcHQgY29uY2x1c2lvbi4KCSAqCgkgKiBgYGAKCSAqICMgd3AgcmV3cml0ZSBmbHVzaCBleHBlY3RzICdyZXdyaXRlX3J1bGVzJyBvcHRpb24gdG8gYmUgc2V0IGFmdGVyIGZsdXNoLgoJICogZmx1c2hfcmV3cml0ZV9ydWxlcyggXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoYXJkJyApICk7CgkgKiBpZiAoICEgZ2V0X29wdGlvbiggJ3Jld3JpdGVfcnVsZXMnICkgKSB7CgkgKiAgICAgV1BfQ0xJOjp3YXJuaW5nKCAiUmV3cml0ZSBydWxlcyBhcmUgZW1wdHkuIiApOwoJICogfSBlbHNlIHsKCSAqICAgICBXUF9DTEk6OnN1Y2Nlc3MoICdSZXdyaXRlIHJ1bGVzIGZsdXNoZWQuJyApOwoJICogfQoJICogYGBgCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBPdXRwdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUgdG8gU1RET1VULgoJICogQHJldHVybiBudWxsCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VjY2VzcyggJG1lc3NhZ2UgKSB7CgkJaWYgKCBudWxsID09PSBzZWxmOjokbG9nZ2VyICkgewoJCQlyZXR1cm47CgkJfQoKCQlzZWxmOjokbG9nZ2VyLT5zdWNjZXNzKCAkbWVzc2FnZSApOwoJfQoKCS8qKgoJICogRGlzcGxheSBkZWJ1ZyBtZXNzYWdlIHByZWZpeGVkIHdpdGggIkRlYnVnOiAiIHdoZW4gYC0tZGVidWdgIGlzIHVzZWQuCgkgKgoJICogRGVidWcgbWVzc2FnZSBpcyB3cml0dGVuIHRvIFNUREVSUiwgYW5kIGluY2x1ZGVzIHNjcmlwdCBleGVjdXRpb24gdGltZS4KCSAqCgkgKiBIZWxwZnVsIGZvciBvcHRpb25hbGx5IHNob3dpbmcgZ3JlYXRlciBkZXRhaWwgd2hlbiBuZWVkZWQuIFVzZWQgdGhyb3VnaG91dAoJICogV1AtQ0xJIGJvb3RzdHJhcCBwcm9jZXNzIGZvciBlYXNpZXIgZGVidWdnaW5nIGFuZCBwcm9maWxpbmcuCgkgKgoJICogYGBgCgkgKiAjIENhbGxlZCBpbiBgV1BfQ0xJXFJ1bm5lcjo6c2V0X3dwX3Jvb3QoKWAuCgkgKiBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzZXRfd3Bfcm9vdCggJHBhdGggKSB7CgkgKiAgICAgZGVmaW5lKCAnQUJTUEFUSCcsIFV0aWxzXHRyYWlsaW5nc2xhc2hpdCggJHBhdGggKSApOwoJICogICAgIFdQX0NMSTo6ZGVidWcoICdBQlNQQVRIIGRlZmluZWQ6ICcgLiBBQlNQQVRIICk7CgkgKiAgICAgJF9TRVJWRVJbJ0RPQ1VNRU5UX1JPT1QnXSA9IHJlYWxwYXRoKCAkcGF0aCApOwoJICogfQoJICoKCSAqICMgRGVidWcgZGV0YWlscyBvbmx5IGFwcGVhciB3aGVuIGAtLWRlYnVnYCBpcyB1c2VkLgoJICogIyAkIHdwIC0tZGVidWcKCSAqICMgWy4uLl0KCSAqICMgRGVidWc6IEFCU1BBVEggZGVmaW5lZDogL3Nydi93d3cvd29yZHByZXNzLWRldmVsb3AuZGV2L3NyYy8gKDAuMjI1cykKCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgT3V0cHV0CgkgKgoJICogQHBhcmFtIHN0cmluZ3xXUF9FcnJvcnxFeGNlcHRpb258VGhyb3dhYmxlICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUgdG8gU1RERVJSLgoJICogQHBhcmFtIHN0cmluZ3xib29sICRncm91cCBPcmdhbml6ZSBkZWJ1ZyBtZXNzYWdlIHRvIGEgc3BlY2lmaWMgZ3JvdXAuCgkgKiBVc2UgYGZhbHNlYCB0byBub3QgZ3JvdXAgdGhlIG1lc3NhZ2UuCgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkZWJ1ZyggJG1lc3NhZ2UsICRncm91cCA9IGZhbHNlICkgewoJCXN0YXRpYyAkc3RvcmFnZSA9IFtdOwoKCQlpZiAoICEgc2VsZjo6JGxvZ2dlciApIHsKCQkJJHN0b3JhZ2VbXSA9IFsgJG1lc3NhZ2UsICRncm91cCBdOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoICEgZW1wdHkoICRzdG9yYWdlICkgJiYgc2VsZjo6JGxvZ2dlciApIHsKCQkJZm9yZWFjaCAoICRzdG9yYWdlIGFzICRlbnRyeSApIHsKCQkJCWxpc3QoICRzdG9yZWRfbWVzc2FnZSwgJHN0b3JlZF9ncm91cCApID0gJGVudHJ5OwoJCQkJc2VsZjo6JGxvZ2dlci0+ZGVidWcoIHNlbGY6OmVycm9yX3RvX3N0cmluZyggJHN0b3JlZF9tZXNzYWdlICksICRzdG9yZWRfZ3JvdXAgKTsKCQkJfQoJCQkkc3RvcmFnZSA9IFtdOwoJCX0KCgkJc2VsZjo6JGxvZ2dlci0+ZGVidWcoIHNlbGY6OmVycm9yX3RvX3N0cmluZyggJG1lc3NhZ2UgKSwgJGdyb3VwICk7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IHdhcm5pbmcgbWVzc2FnZSBwcmVmaXhlZCB3aXRoICJXYXJuaW5nOiAiLgoJICoKCSAqIFdhcm5pbmcgbWVzc2FnZSBpcyB3cml0dGVuIHRvIFNUREVSUi4KCSAqCgkgKiBVc2UgaW5zdGVhZCBvZiBgV1BfQ0xJOjpkZWJ1ZygpYCB3aGVuIHNjcmlwdCBleGVjdXRpb24gc2hvdWxkIGJlIHBlcm1pdHRlZAoJICogdG8gY29udGludWUuCgkgKgoJICogYGBgCgkgKiAjIGB3cCBwbHVnaW4gYWN0aXZhdGVgIHNraXBzIGFjdGl2YXRpb24gd2hlbiBwbHVnaW4gaXMgbmV0d29yayBhY3RpdmUuCgkgKiAkc3RhdHVzID0gJHRoaXMtPmdldF9zdGF0dXMoICRwbHVnaW4tPmZpbGUgKTsKCSAqIC8vIE5ldHdvcmstYWN0aXZlIGlzIHRoZSBoaWdoZXN0IGxldmVsIG9mIGFjdGl2YXRpb24gc3RhdHVzCgkgKiBpZiAoICdhY3RpdmUtbmV0d29yaycgPT09ICRzdGF0dXMgKSB7CgkgKiAgIFdQX0NMSTo6d2FybmluZyggIlBsdWdpbiAneyRwbHVnaW4tPm5hbWV9JyBpcyBhbHJlYWR5IG5ldHdvcmsgYWN0aXZlLiIgKTsKCSAqICAgY29udGludWU7CgkgKiB9CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IE91dHB1dAoJICoKCSAqIEBwYXJhbSBzdHJpbmd8V1BfRXJyb3J8RXhjZXB0aW9ufFRocm93YWJsZSAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlIHRvIFNUREVSUi4KCSAqIEByZXR1cm4gbnVsbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHdhcm5pbmcoICRtZXNzYWdlICkgewoJCWlmICggbnVsbCA9PT0gc2VsZjo6JGxvZ2dlciApIHsKCQkJcmV0dXJuOwoJCX0KCgkJc2VsZjo6JGxvZ2dlci0+d2FybmluZyggc2VsZjo6ZXJyb3JfdG9fc3RyaW5nKCAkbWVzc2FnZSApICk7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IGVycm9yIG1lc3NhZ2UgcHJlZml4ZWQgd2l0aCAiRXJyb3I6ICIgYW5kIGV4aXQgc2NyaXB0LgoJICoKCSAqIEVycm9yIG1lc3NhZ2UgaXMgd3JpdHRlbiB0byBTVERFUlIuIERlZmF1bHRzIHRvIGhhbHRpbmcgc2NyaXB0IGV4ZWN1dGlvbgoJICogd2l0aCByZXR1cm4gY29kZSAxLgoJICoKCSAqIFVzZSBgV1BfQ0xJOjp3YXJuaW5nKClgIGluc3RlYWQgd2hlbiBzY3JpcHQgZXhlY3V0aW9uIHNob3VsZCBiZSBwZXJtaXR0ZWQKCSAqIHRvIGNvbnRpbnVlLgoJICoKCSAqIGBgYAoJICogIyBgd3AgY2FjaGUgZmx1c2hgIGNvbnNpZGVycyBmbHVzaCBmYWlsdXJlIHRvIGJlIGEgZmF0YWwgZXJyb3IuCgkgKiBpZiAoIGZhbHNlID09PSB3cF9jYWNoZV9mbHVzaCgpICkgewoJICogICAgIFdQX0NMSTo6ZXJyb3IoICdUaGUgb2JqZWN0IGNhY2hlIGNvdWxkIG5vdCBiZSBmbHVzaGVkLicgKTsKCSAqIH0KCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgT3V0cHV0CgkgKgoJICogQHBhcmFtIHN0cmluZ3xXUF9FcnJvcnxFeGNlcHRpb258VGhyb3dhYmxlICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUgdG8gU1RERVJSLgoJICogQHBhcmFtIGJvb2xlYW58aW50ZWdlciAgICAgICAgICAgICRleGl0ICAgIFRydWUgZGVmYXVsdHMgdG8gZXhpdCgxKS4KCSAqIEByZXR1cm4gbnVsbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVycm9yKCAkbWVzc2FnZSwgJGV4aXQgPSB0cnVlICkgewoJCWlmICggbnVsbCAhPT0gc2VsZjo6JGxvZ2dlciAmJiAhIGlzc2V0KCBzZWxmOjpnZXRfcnVubmVyKCktPmFzc29jX2FyZ3NbJ2NvbXBsZXRpb25zJ10gKSApIHsKCQkJc2VsZjo6JGxvZ2dlci0+ZXJyb3IoIHNlbGY6OmVycm9yX3RvX3N0cmluZyggJG1lc3NhZ2UgKSApOwoJCX0KCgkJJHJldHVybl9jb2RlID0gZmFsc2U7CgkJaWYgKCB0cnVlID09PSAkZXhpdCApIHsKCQkJJHJldHVybl9jb2RlID0gMTsKCQl9IGVsc2VpZiAoIGlzX2ludCggJGV4aXQgKSAmJiAkZXhpdCA+PSAxICkgewoJCQkkcmV0dXJuX2NvZGUgPSAkZXhpdDsKCQl9CgoJCWlmICggJHJldHVybl9jb2RlICkgewoJCQlpZiAoIHNlbGY6OiRjYXB0dXJlX2V4aXQgKSB7CgkJCQl0aHJvdyBuZXcgRXhpdEV4Y2VwdGlvbiggbnVsbCwgJHJldHVybl9jb2RlICk7CgkJCX0KCQkJZXhpdCggJHJldHVybl9jb2RlICk7CgkJfQoJfQoKCS8qKgoJICogSGFsdCBzY3JpcHQgZXhlY3V0aW9uIHdpdGggYSBzcGVjaWZpYyByZXR1cm4gY29kZS4KCSAqCgkgKiBQZXJtaXRzIHNjcmlwdCBleGVjdXRpb24gdG8gYmUgb3ZlcmxvYWRlZCBieSBgV1BfQ0xJOjpydW5jb21tYW5kKClgCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBPdXRwdXQKCSAqCgkgKiBAcGFyYW0gaW50ZWdlciAkcmV0dXJuX2NvZGUKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYWx0KCAkcmV0dXJuX2NvZGUgKSB7CgkJaWYgKCBzZWxmOjokY2FwdHVyZV9leGl0ICkgewoJCQl0aHJvdyBuZXcgRXhpdEV4Y2VwdGlvbiggbnVsbCwgJHJldHVybl9jb2RlICk7CgkJfQoJCWV4aXQoICRyZXR1cm5fY29kZSApOwoJfQoKCS8qKgoJICogRGlzcGxheSBhIG11bHRpLWxpbmUgZXJyb3IgbWVzc2FnZSBpbiBhIHJlZCBib3guIERvZXNuJ3QgZXhpdCBzY3JpcHQuCgkgKgoJICogRXJyb3IgbWVzc2FnZSBpcyB3cml0dGVuIHRvIFNUREVSUi4KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IE91dHB1dAoJICoKCSAqIEBwYXJhbSBhcnJheSAkbWVzc2FnZV9saW5lcyBNdWx0aS1saW5lIGVycm9yIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVycm9yX211bHRpX2xpbmUoICRtZXNzYWdlX2xpbmVzICkgewoJCWlmICggbnVsbCA9PT0gc2VsZjo6JGxvZ2dlciApIHsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAhIGlzc2V0KCBzZWxmOjpnZXRfcnVubmVyKCktPmFzc29jX2FyZ3NbJ2NvbXBsZXRpb25zJ10gKSAmJiBpc19hcnJheSggJG1lc3NhZ2VfbGluZXMgKSApIHsKCQkJc2VsZjo6JGxvZ2dlci0+ZXJyb3JfbXVsdGlfbGluZSggYXJyYXlfbWFwKCBbIF9fQ0xBU1NfXywgJ2Vycm9yX3RvX3N0cmluZycgXSwgJG1lc3NhZ2VfbGluZXMgKSApOwoJCX0KCX0KCgkvKioKCSAqIEFzayBmb3IgY29uZmlybWF0aW9uIGJlZm9yZSBydW5uaW5nIGEgZGVzdHJ1Y3RpdmUgb3BlcmF0aW9uLgoJICoKCSAqIElmICd5JyBpcyBwcm92aWRlZCB0byB0aGUgcXVlc3Rpb24sIHRoZSBzY3JpcHQgZXhlY3V0aW9uIGNvbnRpbnVlcy4gSWYKCSAqICduJyBvciBhbnkgb3RoZXIgcmVzcG9uc2UgaXMgcHJvdmlkZWQgdG8gdGhlIHF1ZXN0aW9uLCBzY3JpcHQgZXhpdHMuCgkgKgoJICogYGBgCgkgKiAjIGB3cCBkYiBkcm9wYCBhc2tzIGZvciBjb25maXJtYXRpb24gYmVmb3JlIGRyb3BwaW5nIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBXUF9DTEk6OmNvbmZpcm0oICJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZHJvcCB0aGUgZGF0YWJhc2U/IiwgJGFzc29jX2FyZ3MgKTsKCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgSW5wdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRxdWVzdGlvbiBRdWVzdGlvbiB0byBkaXNwbGF5IGJlZm9yZSB0aGUgcHJvbXB0LgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFNraXBzIHByb21wdCBpZiAneWVzJyBpcyBwcm92aWRlZC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb25maXJtKCAkcXVlc3Rpb24sICRhc3NvY19hcmdzID0gW10gKSB7CgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3llcycgKSApIHsKCQkJZndyaXRlKCBTVERPVVQsICRxdWVzdGlvbiAuICcgW3kvbl0gJyApOwoKCQkJJGFuc3dlciA9IHN0cnRvbG93ZXIoIHRyaW0oIGZnZXRzKCBTVERJTiApICkgKTsKCgkJCWlmICggJ3knICE9PSAkYW5zd2VyICkgewoJCQkJZXhpdDsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFJlYWQgdmFsdWUgZnJvbSBhIHBvc2l0aW9uYWwgYXJndW1lbnQgb3IgZnJvbSBTVERJTi4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgVGhlIGxpc3Qgb2YgcG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gaW50ICRpbmRleCBBdCB3aGljaCBwb3NpdGlvbiB0byBjaGVjayBmb3IgdGhlIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgJGluZGV4ICkgewoJCWlmICggaXNzZXQoICRhcmdzWyAkaW5kZXggXSApICkgewoJCQkkcmF3X3ZhbHVlID0gJGFyZ3NbICRpbmRleCBdOwoJCX0gZWxzZSB7CgkJCS8vIFdlIGRvbid0IHVzZSBmaWxlX2dldF9jb250ZW50cygpIGhlcmUgYmVjYXVzZSBpdCBkb2Vzbid0IGhhbmRsZQoJCQkvLyBDdHJsLUQgcHJvcGVybHksIHdoZW4gdHlwaW5nIGluIHRoZSB2YWx1ZSBpbnRlcmFjdGl2ZWx5LgoJCQkkcmF3X3ZhbHVlID0gJyc7CgkJCXdoaWxlICggZmFsc2UgIT09ICggJGxpbmUgPSBmZ2V0cyggU1RESU4gKSApICkgewoJCQkJJHJhd192YWx1ZSAuPSAkbGluZTsKCQkJfQoJCX0KCgkJcmV0dXJuICRyYXdfdmFsdWU7Cgl9CgoJLyoqCgkgKiBSZWFkIGEgdmFsdWUsIGZyb20gdmFyaW91cyBmb3JtYXRzLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgSW5wdXQKCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHJhd192YWx1ZQoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVhZF92YWx1ZSggJHJhd192YWx1ZSwgJGFzc29jX2FyZ3MgPSBbXSApIHsKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKSA9PT0gJ2pzb24nICkgewoJCQkkdmFsdWUgPSBqc29uX2RlY29kZSggJHJhd192YWx1ZSwgdHJ1ZSApOwoJCQlpZiAoIG51bGwgPT09ICR2YWx1ZSApIHsKCQkJCXNlbGY6OmVycm9yKCBzcHJpbnRmKCAnSW52YWxpZCBKU09OOiAlcycsICRyYXdfdmFsdWUgKSApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHZhbHVlID0gJHJhd192YWx1ZTsKCQl9CgoJCXJldHVybiAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IGEgdmFsdWUsIGluIHZhcmlvdXMgZm9ybWF0cwoJICoKCSAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUgdG8gZGlzcGxheS4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBjb21tYW5kLCBkZXRlcm1pbmluZyBmb3JtYXQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgPSBbXSApIHsKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKSA9PT0gJ2pzb24nICkgewoJCQkkdmFsdWUgPSBqc29uX2VuY29kZSggJHZhbHVlICk7CgkJfSBlbHNlaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgPT09ICd5YW1sJyApIHsKCQkJJHZhbHVlID0gU3B5Yzo6WUFNTER1bXAoICR2YWx1ZSwgMiwgMCApOwoJCX0gZWxzZWlmICggaXNfYXJyYXkoICR2YWx1ZSApIHx8IGlzX29iamVjdCggJHZhbHVlICkgKSB7CgkJCSR2YWx1ZSA9IHZhcl9leHBvcnQoICR2YWx1ZSwgdHJ1ZSApOwoJCX0KCgkJZWNobyAkdmFsdWUgLiAiXG4iOwoJfQoKCS8qKgoJICogQ29udmVydCBhIFdQX0Vycm9yIG9yIEV4Y2VwdGlvbiBpbnRvIGEgc3RyaW5nCgkgKgoJICogQHBhcmFtIHN0cmluZ3xXUF9FcnJvcnxFeGNlcHRpb258VGhyb3dhYmxlICRlcnJvcnMKCSAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcnJvcl90b19zdHJpbmcoICRlcnJvcnMgKSB7CgkJaWYgKCBpc19zdHJpbmcoICRlcnJvcnMgKSApIHsKCQkJcmV0dXJuICRlcnJvcnM7CgkJfQoKCQkvLyBPbmx5IGpzb25fZW5jb2RlKCkgdGhlIGRhdGEgd2hlbiBpdCBuZWVkcyBpdAoJCSRyZW5kZXJfZGF0YSA9IGZ1bmN0aW9uKCAkZGF0YSApIHsKCQkJaWYgKCBpc19hcnJheSggJGRhdGEgKSB8fCBpc19vYmplY3QoICRkYXRhICkgKSB7CgkJCQlyZXR1cm4ganNvbl9lbmNvZGUoICRkYXRhICk7CgkJCX0KCgkJCXJldHVybiAnIicgLiAkZGF0YSAuICciJzsKCQl9OwoKCQlpZiAoICRlcnJvcnMgaW5zdGFuY2VvZiBXUF9FcnJvciApIHsKCQkJZm9yZWFjaCAoICRlcnJvcnMtPmdldF9lcnJvcl9tZXNzYWdlcygpIGFzICRtZXNzYWdlICkgewoJCQkJaWYgKCAkZXJyb3JzLT5nZXRfZXJyb3JfZGF0YSgpICkgewoJCQkJCXJldHVybiAkbWVzc2FnZSAuICcgJyAuICRyZW5kZXJfZGF0YSggJGVycm9ycy0+Z2V0X2Vycm9yX2RhdGEoKSApOwoJCQkJfQoKCQkJCXJldHVybiAkbWVzc2FnZTsKCQkJfQoJCX0KCgkJLy8gUEhQIDcrOiBpbnRlcm5hbCBhbmQgdXNlciBleGNlcHRpb25zIG11c3QgaW1wbGVtZW50IFRocm93YWJsZSBpbnRlcmZhY2UuCgkJLy8gUEhQIDU6IGludGVybmFsIGFuZCB1c2VyIGV4Y2VwdGlvbnMgbXVzdCBleHRlbmQgRXhjZXB0aW9uIGNsYXNzLgoJCWlmICggaW50ZXJmYWNlX2V4aXN0cyggJ1Rocm93YWJsZScgKSAmJiAoICRlcnJvcnMgaW5zdGFuY2VvZiBUaHJvd2FibGUgKSB8fCAoICRlcnJvcnMgaW5zdGFuY2VvZiBFeGNlcHRpb24gKSApIHsKCQkJcmV0dXJuIGdldF9jbGFzcyggJGVycm9ycyApIC4gJzogJyAuICRlcnJvcnMtPmdldE1lc3NhZ2UoKTsKCQl9CgoJCXRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCgkJCXNwcmludGYoCgkJCQkiVW5zdXBwb3J0ZWQgYXJndW1lbnQgdHlwZSBwYXNzZWQgdG8gV1BfQ0xJOjplcnJvcl90b19zdHJpbmcoKTogJyVzJyIsCgkJCQlnZXR0eXBlKCAkZXJyb3JzICkKCQkJKQoJCSk7Cgl9CgoJLyoqCgkgKiBMYXVuY2ggYW4gYXJiaXRyYXJ5IGV4dGVybmFsIHByb2Nlc3MgdGhhdCB0YWtlcyBvdmVyIEkvTy4KCSAqCgkgKiBgYGAKCSAqICMgYHdwIGNvcmUgZG93bmxvYWRgIGZhbGxzIGJhY2sgdG8gdGhlIGB0YXJgIGJpbmFyeSB3aGVuIFBoYXJEYXRhIGlzbid0IGF2YWlsYWJsZQoJICogaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1BoYXJEYXRhJyApICkgewoJICogICAgICRjbWQgPSAidGFyIHh6IC0tc3RyaXAtY29tcG9uZW50cz0xIC0tZGlyZWN0b3J5PSVzIC1mICR0YXJiYWxsIjsKCSAqICAgICBXUF9DTEk6OmxhdW5jaCggVXRpbHNcZXNjX2NtZCggJGNtZCwgJGRlc3QgKSApOwoJICogICAgIHJldHVybjsKCSAqIH0KCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgRXhlY3V0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29tbWFuZCBFeHRlcm5hbCBwcm9jZXNzIHRvIGxhdW5jaC4KCSAqIEBwYXJhbSBib29sZWFuICRleGl0X29uX2Vycm9yIFdoZXRoZXIgdG8gZXhpdCBpZiB0aGUgY29tbWFuZCByZXR1cm5zIGFuIGVsZXZhdGVkIHJldHVybiBjb2RlLgoJICogQHBhcmFtIGJvb2xlYW4gJHJldHVybl9kZXRhaWxlZCBXaGV0aGVyIHRvIHJldHVybiBhbiBleGl0IHN0YXR1cyAoZGVmYXVsdCkgb3IgZGV0YWlsZWQgZXhlY3V0aW9uIHJlc3VsdHMuCgkgKiBAcmV0dXJuIGludHxQcm9jZXNzUnVuIFRoZSBjb21tYW5kIGV4aXQgc3RhdHVzLCBvciBhIFByb2Nlc3NSdW4gb2JqZWN0IGZvciBmdWxsIGRldGFpbHMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbGF1bmNoKCAkY29tbWFuZCwgJGV4aXRfb25fZXJyb3IgPSB0cnVlLCAkcmV0dXJuX2RldGFpbGVkID0gZmFsc2UgKSB7CgkJVXRpbHNcY2hlY2tfcHJvY19hdmFpbGFibGUoICdsYXVuY2gnICk7CgoJCSRwcm9jICAgID0gUHJvY2Vzczo6Y3JlYXRlKCAkY29tbWFuZCApOwoJCSRyZXN1bHRzID0gJHByb2MtPnJ1bigpOwoKCQlpZiAoIC0xID09PSAkcmVzdWx0cy0+cmV0dXJuX2NvZGUgKSB7CgkJCXNlbGY6Ondhcm5pbmcoICJTcGF3bmVkIHByb2Nlc3MgcmV0dXJuZWQgZXhpdCBjb2RlIHskcmVzdWx0cy0+cmV0dXJuX2NvZGV9LCB3aGljaCBjb3VsZCBiZSBjYXVzZWQgYnkgYSBjdXN0b20gY29tcGlsZWQgdmVyc2lvbiBvZiBQSFAgdGhhdCB1c2VzIHRoZSAtLWVuYWJsZS1zaWdjaGlsZCBvcHRpb24uIiApOwoJCX0KCgkJaWYgKCAkcmVzdWx0cy0+cmV0dXJuX2NvZGUgJiYgJGV4aXRfb25fZXJyb3IgKSB7CgkJCWV4aXQoICRyZXN1bHRzLT5yZXR1cm5fY29kZSApOwoJCX0KCgkJaWYgKCAkcmV0dXJuX2RldGFpbGVkICkgewoJCQlyZXR1cm4gJHJlc3VsdHM7CgkJfQoKCQlyZXR1cm4gJHJlc3VsdHMtPnJldHVybl9jb2RlOwoJfQoKCS8qKgoJICogUnVuIGEgV1AtQ0xJIGNvbW1hbmQgaW4gYSBuZXcgcHJvY2VzcyByZXVzaW5nIHRoZSBjdXJyZW50IHJ1bnRpbWUgYXJndW1lbnRzLgoJICoKCSAqIFVzZSBgV1BfQ0xJOjpydW5jb21tYW5kKClgIGluc3RlYWQsIHdoaWNoIGlzIGVhc2llciB0byB1c2UgYW5kIHdvcmtzIGJldHRlci4KCSAqCgkgKiBOb3RlOiBXaGlsZSB0aGlzIGNvbW1hbmQgZG9lcyBwZXJzaXN0IGEgbGltaXRlZCBzZXQgb2YgcnVudGltZSBhcmd1bWVudHMsCgkgKiBpdCAqZG9lcyBub3QqIHBlcnNpc3QgZW52aXJvbm1lbnQgdmFyaWFibGVzLiBQcmFjdGljYWxseSBzcGVha2luZywgV1AtQ0xJCgkgKiBwYWNrYWdlcyB3b24ndCBiZSBsb2FkZWQgd2hlbiB1c2luZyBXUF9DTEk6OmxhdW5jaF9zZWxmKCkgYmVjYXVzZSB0aGUKCSAqIGxhdW5jaGVkIHByb2Nlc3MgZG9lc24ndCBoYXZlIGFjY2VzcyB0byB0aGUgY3VycmVudCBwcm9jZXNzICRIT01FLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgRXhlY3V0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29tbWFuZCBXUC1DTEkgY29tbWFuZCB0byBjYWxsLgoJICogQHBhcmFtIGFycmF5ICRhcmdzIFBvc2l0aW9uYWwgYXJndW1lbnRzIHRvIGluY2x1ZGUgd2hlbiBjYWxsaW5nIHRoZSBjb21tYW5kLgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEFzc29jaWF0aXZlIGFyZ3VtZW50cyB0byBpbmNsdWRlIHdoZW4gY2FsbGluZyB0aGUgY29tbWFuZC4KCSAqIEBwYXJhbSBib29sICRleGl0X29uX2Vycm9yIFdoZXRoZXIgdG8gZXhpdCBpZiB0aGUgY29tbWFuZCByZXR1cm5zIGFuIGVsZXZhdGVkIHJldHVybiBjb2RlLgoJICogQHBhcmFtIGJvb2wgJHJldHVybl9kZXRhaWxlZCBXaGV0aGVyIHRvIHJldHVybiBhbiBleGl0IHN0YXR1cyAoZGVmYXVsdCkgb3IgZGV0YWlsZWQgZXhlY3V0aW9uIHJlc3VsdHMuCgkgKiBAcGFyYW0gYXJyYXkgJHJ1bnRpbWVfYXJncyBPdmVycmlkZSBvbmUgb3IgbW9yZSBnbG9iYWwgYXJncyAocGF0aCx1cmwsdXNlcixhbGxvdy1yb290KQoJICogQHJldHVybiBpbnR8UHJvY2Vzc1J1biBUaGUgY29tbWFuZCBleGl0IHN0YXR1cywgb3IgYSBQcm9jZXNzUnVuIGluc3RhbmNlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbGF1bmNoX3NlbGYoICRjb21tYW5kLCAkYXJncyA9IFtdLCAkYXNzb2NfYXJncyA9IFtdLCAkZXhpdF9vbl9lcnJvciA9IHRydWUsICRyZXR1cm5fZGV0YWlsZWQgPSBmYWxzZSwgJHJ1bnRpbWVfYXJncyA9IFtdICkgewoJCSRyZXVzZWRfcnVudGltZV9hcmdzID0gWwoJCQkncGF0aCcsCgkJCSd1cmwnLAoJCQkndXNlcicsCgkJCSdhbGxvdy1yb290JywKCQldOwoKCQlmb3JlYWNoICggJHJldXNlZF9ydW50aW1lX2FyZ3MgYXMgJGtleSApIHsKCQkJaWYgKCBpc3NldCggJHJ1bnRpbWVfYXJnc1sgJGtleSBdICkgKSB7CgkJCQkkYXNzb2NfYXJnc1sgJGtleSBdID0gJHJ1bnRpbWVfYXJnc1sgJGtleSBdOwoJCQkJY29udGludWU7CgkJCX0KCgkJCSR2YWx1ZSA9IHNlbGY6OmdldF9ydW5uZXIoKS0+Y29uZmlnWyAka2V5IF07CgkJCWlmICggJHZhbHVlICkgewoJCQkJJGFzc29jX2FyZ3NbICRrZXkgXSA9ICR2YWx1ZTsKCQkJfQoJCX0KCgkJJHBocF9iaW4gPSBlc2NhcGVzaGVsbGFyZyggVXRpbHNcZ2V0X3BocF9iaW5hcnkoKSApOwoKCQkkc2NyaXB0X3BhdGggPSAkR0xPQkFMU1snYXJndiddWzBdOwoKCQlpZiAoIGdldGVudiggJ1dQX0NMSV9DT05GSUdfUEFUSCcgKSApIHsKCQkJJGNvbmZpZ19wYXRoID0gZ2V0ZW52KCAnV1BfQ0xJX0NPTkZJR19QQVRIJyApOwoJCX0gZWxzZSB7CgkJCSRjb25maWdfcGF0aCA9IFV0aWxzXGdldF9ob21lX2RpcigpIC4gJy8ud3AtY2xpL2NvbmZpZy55bWwnOwoJCX0KCQkkY29uZmlnX3BhdGggPSBlc2NhcGVzaGVsbGFyZyggJGNvbmZpZ19wYXRoICk7CgoJCSRhcmdzICAgICAgID0gaW1wbG9kZSggJyAnLCBhcnJheV9tYXAoICdlc2NhcGVzaGVsbGFyZycsICRhcmdzICkgKTsKCQkkYXNzb2NfYXJncyA9IFV0aWxzXGFzc29jX2FyZ3NfdG9fc3RyKCAkYXNzb2NfYXJncyApOwoKCQkkZnVsbF9jb21tYW5kID0gIldQX0NMSV9DT05GSUdfUEFUSD17JGNvbmZpZ19wYXRofSB7JHBocF9iaW59IHskc2NyaXB0X3BhdGh9IHskY29tbWFuZH0geyRhcmdzfSB7JGFzc29jX2FyZ3N9IjsKCgkJcmV0dXJuIHNlbGY6OmxhdW5jaCggJGZ1bGxfY29tbWFuZCwgJGV4aXRfb25fZXJyb3IsICRyZXR1cm5fZGV0YWlsZWQgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgcGF0aCB0byB0aGUgUEhQIGJpbmFyeSB1c2VkIHdoZW4gZXhlY3V0aW5nIFdQLUNMSS4KCSAqCgkgKiBFbnZpcm9ubWVudCB2YWx1ZXMgcGVybWl0IHNwZWNpZmljIGJpbmFyaWVzIHRvIGJlIGluZGljYXRlZC4KCSAqCgkgKiBOb3RlOiBtb3ZlZCB0byBVdGlscywgbGVmdCBmb3IgQkMuCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBTeXN0ZW0KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9waHBfYmluYXJ5KCkgewoJCXJldHVybiBVdGlsc1xnZXRfcGhwX2JpbmFyeSgpOwoJfQoKCS8qKgoJICogQ29uZmlybSB0aGF0IGEgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyIGRvZXMgZXhpc3QuCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBJbnB1dAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBDb25maWcgcGFyYW1ldGVyIGtleSB0byBjaGVjay4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYXNfY29uZmlnKCAka2V5ICkgewoJCXJldHVybiBhcnJheV9rZXlfZXhpc3RzKCAka2V5LCBzZWxmOjpnZXRfcnVubmVyKCktPmNvbmZpZyApOwoJfQoKCS8qKgoJICogR2V0IHZhbHVlcyBvZiBnbG9iYWwgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzLgoJICoKCSAqIFByb3ZpZGVzIGFjY2VzcyB0byBgLS1wYXRoPTxwYXRoPmAsIGAtLXVybD08dXJsPmAsIGFuZCBvdGhlciB2YWx1ZXMgb2YKCSAqIHRoZSBbZ2xvYmFsIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyc10oaHR0cHM6Ly93cC1jbGkub3JnL2NvbmZpZy8pLgoJICoKCSAqIGBgYAoJICogV1BfQ0xJOjpsb2coICdUaGUgLS11cmw9PHVybD4gdmFsdWUgaXM6ICcgLiBXUF9DTEk6OmdldF9jb25maWcoICd1cmwnICkgKTsKCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgSW5wdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgR2V0IHZhbHVlIGZvciBhIHNwZWNpZmljIGdsb2JhbCBjb25maWd1cmF0aW9uIHBhcmFtZXRlci4KCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRfY29uZmlnKCAka2V5ID0gbnVsbCApIHsKCQlpZiAoIG51bGwgPT09ICRrZXkgKSB7CgkJCXJldHVybiBzZWxmOjpnZXRfcnVubmVyKCktPmNvbmZpZzsKCQl9CgoJCWlmICggISBpc3NldCggc2VsZjo6Z2V0X3J1bm5lcigpLT5jb25maWdbICRrZXkgXSApICkgewoJCQlzZWxmOjp3YXJuaW5nKCAiVW5rbm93biBjb25maWcgb3B0aW9uICcka2V5Jy4iICk7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJcmV0dXJuIHNlbGY6OmdldF9ydW5uZXIoKS0+Y29uZmlnWyAka2V5IF07Cgl9CgoJLyoqCgkgKiBSdW4gYSBXUC1DTEkgY29tbWFuZC4KCSAqCgkgKiBMYXVuY2hlcyBhIG5ldyBjaGlsZCBwcm9jZXNzIHRvIHJ1biBhIHNwZWNpZmllZCBXUC1DTEkgY29tbWFuZC4KCSAqIE9wdGlvbmFsbHk6CgkgKgoJICogKiBSdW4gdGhlIGNvbW1hbmQgaW4gYW4gZXhpc3RpbmcgcHJvY2Vzcy4KCSAqICogUHJldmVudCBoYWx0aW5nIHNjcmlwdCBleGVjdXRpb24gb24gZXJyb3IuCgkgKiAqIENhcHR1cmUgYW5kIHJldHVybiBTVERPVVQsIG9yIGZ1bGwgZGV0YWlscyBhYm91dCBjb21tYW5kIGV4ZWN1dGlvbi4KCSAqICogUGFyc2UgSlNPTiBvdXRwdXQgaWYgdGhlIGNvbW1hbmQgcmVuZGVyZWQgaXQuCgkgKgoJICogYGBgCgkgKiAkb3B0aW9ucyA9IGFycmF5KAoJICogICAncmV0dXJuJyAgICAgPT4gdHJ1ZSwgICAvLyBSZXR1cm4gJ1NURE9VVCc7IHVzZSAnYWxsJyBmb3IgZnVsbCBvYmplY3QuCgkgKiAgICdwYXJzZScgICAgICA9PiAnanNvbicsIC8vIFBhcnNlIGNhcHR1cmVkIFNURE9VVCB0byBKU09OIGFycmF5LgoJICogICAnbGF1bmNoJyAgICAgPT4gZmFsc2UsICAvLyBSZXVzZSB0aGUgY3VycmVudCBwcm9jZXNzLgoJICogICAnZXhpdF9lcnJvcicgPT4gdHJ1ZSwgICAvLyBIYWx0IHNjcmlwdCBleGVjdXRpb24gb24gZXJyb3IuCgkgKiApOwoJICogJHBsdWdpbnMgPSBXUF9DTEk6OnJ1bmNvbW1hbmQoICdwbHVnaW4gbGlzdCAtLWZvcm1hdD1qc29uJywgJG9wdGlvbnMgKTsKCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgRXhlY3V0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29tbWFuZCBXUC1DTEkgY29tbWFuZCB0byBydW4sIGluY2x1ZGluZyBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgY29tbWFuZCBleGVjdXRpb24uCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcnVuY29tbWFuZCggJGNvbW1hbmQsICRvcHRpb25zID0gW10gKSB7CgkJJGRlZmF1bHRzICAgPSBbCgkJCSdsYXVuY2gnICAgICA9PiB0cnVlLCAvLyBMYXVuY2ggYSBuZXcgcHJvY2Vzcywgb3IgcmV1c2UgdGhlIGV4aXN0aW5nLgoJCQknZXhpdF9lcnJvcicgPT4gdHJ1ZSwgLy8gRXhpdCBvbiBlcnJvciBieSBkZWZhdWx0LgoJCQkncmV0dXJuJyAgICAgPT4gZmFsc2UsIC8vIENhcHR1cmUgYW5kIHJldHVybiBvdXRwdXQsIG9yIHJlbmRlciBpbiByZWFsdGltZS4KCQkJJ3BhcnNlJyAgICAgID0+IGZhbHNlLCAvLyBQYXJzZSByZXR1cm5lZCBvdXRwdXQgYXMgYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCQldOwoJCSRvcHRpb25zICAgID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJG9wdGlvbnMgKTsKCQkkbGF1bmNoICAgICA9ICRvcHRpb25zWydsYXVuY2gnXTsKCQkkZXhpdF9lcnJvciA9ICRvcHRpb25zWydleGl0X2Vycm9yJ107CgkJJHJldHVybiAgICAgPSAkb3B0aW9uc1sncmV0dXJuJ107CgkJJHBhcnNlICAgICAgPSAkb3B0aW9uc1sncGFyc2UnXTsKCQkkcmV0dmFsICAgICA9IG51bGw7CgkJaWYgKCAkbGF1bmNoICkgewoJCQlVdGlsc1xjaGVja19wcm9jX2F2YWlsYWJsZSggJ2xhdW5jaCBvcHRpb24nICk7CgoJCQkkZGVzY3JpcHRvcnMgPSBbCgkJCQkwID0+IFNURElOLAoJCQkJMSA9PiBTVERPVVQsCgkJCQkyID0+IFNUREVSUiwKCQkJXTsKCgkJCWlmICggJHJldHVybiApIHsKCQkJCSRkZXNjcmlwdG9ycyA9IFsKCQkJCQkwID0+IFNURElOLAoJCQkJCTEgPT4gWyAncGlwZScsICd3JyBdLAoJCQkJCTIgPT4gWyAncGlwZScsICd3JyBdLAoJCQkJXTsKCQkJfQoKCQkJJHBocF9iaW4gICAgID0gZXNjYXBlc2hlbGxhcmcoIFV0aWxzXGdldF9waHBfYmluYXJ5KCkgKTsKCQkJJHNjcmlwdF9wYXRoID0gJEdMT0JBTFNbJ2FyZ3YnXVswXTsKCgkJCS8vIFBlcnNpc3QgcnVudGltZSBhcmd1bWVudHMgdW5sZXNzIHRoZXkndmUgYmVlbiBzcGVjaWZpZWQgb3RoZXJ3aXNlLgoJCQkkY29uZmlndXJhdG9yID0gc2VsZjo6Z2V0X2NvbmZpZ3VyYXRvcigpOwoJCQkkYXJndiAgICAgICAgID0gYXJyYXlfc2xpY2UoICRHTE9CQUxTWydhcmd2J10sIDEgKTsKCgkJCWxpc3QoICRpZ25vcmUxLCAkaWdub3JlMiwgJHJ1bnRpbWVfY29uZmlnICkgPSAkY29uZmlndXJhdG9yLT5wYXJzZV9hcmdzKCAkYXJndiApOwoJCQlmb3JlYWNoICggJHJ1bnRpbWVfY29uZmlnIGFzICRrID0+ICR2ICkgewoJCQkJaWYgKCBwcmVnX21hdGNoKCAifF4tLXska309PyR8IiwgJGNvbW1hbmQgKSApIHsKCQkJCQl1bnNldCggJHJ1bnRpbWVfY29uZmlnWyAkayBdICk7CgkJCQl9CgkJCX0KCQkJJHJ1bnRpbWVfY29uZmlnID0gVXRpbHNcYXNzb2NfYXJnc190b19zdHIoICRydW50aW1lX2NvbmZpZyApOwoKCQkJJHJ1bmNvbW1hbmQgPSAieyRwaHBfYmlufSB7JHNjcmlwdF9wYXRofSB7JHJ1bnRpbWVfY29uZmlnfSB7JGNvbW1hbmR9IjsKCgkJCSRwaXBlcyA9IFtdOwoJCQkkcHJvYyAgPSBVdGlsc1xwcm9jX29wZW5fY29tcGF0KCAkcnVuY29tbWFuZCwgJGRlc2NyaXB0b3JzLCAkcGlwZXMsIGdldGN3ZCgpICk7CgoJCQlpZiAoICRyZXR1cm4gKSB7CgkJCQkkc3Rkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cyggJHBpcGVzWzFdICk7CgkJCQlmY2xvc2UoICRwaXBlc1sxXSApOwoJCQkJJHN0ZGVyciA9IHN0cmVhbV9nZXRfY29udGVudHMoICRwaXBlc1syXSApOwoJCQkJZmNsb3NlKCAkcGlwZXNbMl0gKTsKCQkJfQoJCQkkcmV0dXJuX2NvZGUgPSBwcm9jX2Nsb3NlKCAkcHJvYyApOwoJCQlpZiAoIC0xID09PSAkcmV0dXJuX2NvZGUgKSB7CgkJCQlzZWxmOjp3YXJuaW5nKCAnU3Bhd25lZCBwcm9jZXNzIHJldHVybmVkIGV4aXQgY29kZSAtMSwgd2hpY2ggY291bGQgYmUgY2F1c2VkIGJ5IGEgY3VzdG9tIGNvbXBpbGVkIHZlcnNpb24gb2YgUEhQIHRoYXQgdXNlcyB0aGUgLS1lbmFibGUtc2lnY2hpbGQgb3B0aW9uLicgKTsKCQkJfSBlbHNlaWYgKCAkcmV0dXJuX2NvZGUgJiYgJGV4aXRfZXJyb3IgKSB7CgkJCQlleGl0KCAkcmV0dXJuX2NvZGUgKTsKCQkJfQoJCQlpZiAoIHRydWUgPT09ICRyZXR1cm4gfHwgJ3N0ZG91dCcgPT09ICRyZXR1cm4gKSB7CgkJCQkkcmV0dmFsID0gdHJpbSggJHN0ZG91dCApOwoJCQl9IGVsc2VpZiAoICdzdGRlcnInID09PSAkcmV0dXJuICkgewoJCQkJJHJldHZhbCA9IHRyaW0oICRzdGRlcnIgKTsKCQkJfSBlbHNlaWYgKCAncmV0dXJuX2NvZGUnID09PSAkcmV0dXJuICkgewoJCQkJJHJldHZhbCA9ICRyZXR1cm5fY29kZTsKCQkJfSBlbHNlaWYgKCAnYWxsJyA9PT0gJHJldHVybiApIHsKCQkJCSRyZXR2YWwgPSAob2JqZWN0KSBbCgkJCQkJJ3N0ZG91dCcgICAgICA9PiB0cmltKCAkc3Rkb3V0ICksCgkJCQkJJ3N0ZGVycicgICAgICA9PiB0cmltKCAkc3RkZXJyICksCgkJCQkJJ3JldHVybl9jb2RlJyA9PiAkcmV0dXJuX2NvZGUsCgkJCQldOwoJCQl9CgkJfSBlbHNlIHsKCQkJJGNvbmZpZ3VyYXRvciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHNlbGY6OmdldF9jb25maWd1cmF0b3IoKTsKCQkJJGFyZ3YgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFV0aWxzXHBhcnNlX3N0cl90b19hcmd2KCAkY29tbWFuZCApOwoJCQlsaXN0KCAkYXJncywgJGFzc29jX2FyZ3MsICRydW50aW1lX2NvbmZpZyApID0gJGNvbmZpZ3VyYXRvci0+cGFyc2VfYXJncyggJGFyZ3YgKTsKCQkJaWYgKCAkcmV0dXJuICkgewoJCQkJJGV4aXN0aW5nX2xvZ2dlciA9IHNlbGY6OiRsb2dnZXI7CgkJCQlzZWxmOjokbG9nZ2VyICAgID0gbmV3IEV4ZWN1dGlvbigpOwoJCQkJc2VsZjo6JGxvZ2dlci0+b2Jfc3RhcnQoKTsKCQkJfQoJCQlpZiAoICEgJGV4aXRfZXJyb3IgKSB7CgkJCQlzZWxmOjokY2FwdHVyZV9leGl0ID0gdHJ1ZTsKCQkJfQoJCQl0cnkgewoJCQkJc2VsZjo6Z2V0X3J1bm5lcigpLT5ydW5fY29tbWFuZCgKCQkJCQkkYXJncywKCQkJCQkkYXNzb2NfYXJncywKCQkJCQlbCgkJCQkJCSdiYWNrX2NvbXBhdF9jb252ZXJzaW9ucycgPT4gdHJ1ZSwKCQkJCQldCgkJCQkpOwoJCQkJJHJldHVybl9jb2RlID0gMDsKCQkJfSBjYXRjaCAoIEV4aXRFeGNlcHRpb24gJGUgKSB7CgkJCQkkcmV0dXJuX2NvZGUgPSAkZS0+Z2V0Q29kZSgpOwoJCQl9CgkJCWlmICggJHJldHVybiApIHsKCQkJCSRleGVjdXRpb25fbG9nZ2VyID0gc2VsZjo6JGxvZ2dlcjsKCQkJCSRleGVjdXRpb25fbG9nZ2VyLT5vYl9lbmQoKTsKCQkJCXNlbGY6OiRsb2dnZXIgPSAkZXhpc3RpbmdfbG9nZ2VyOwoJCQkJJHN0ZG91dCAgICAgICA9ICRleGVjdXRpb25fbG9nZ2VyLT5zdGRvdXQ7CgkJCQkkc3RkZXJyICAgICAgID0gJGV4ZWN1dGlvbl9sb2dnZXItPnN0ZGVycjsKCQkJCWlmICggdHJ1ZSA9PT0gJHJldHVybiB8fCAnc3Rkb3V0JyA9PT0gJHJldHVybiApIHsKCQkJCQkkcmV0dmFsID0gdHJpbSggJHN0ZG91dCApOwoJCQkJfSBlbHNlaWYgKCAnc3RkZXJyJyA9PT0gJHJldHVybiApIHsKCQkJCQkkcmV0dmFsID0gdHJpbSggJHN0ZGVyciApOwoJCQkJfSBlbHNlaWYgKCAncmV0dXJuX2NvZGUnID09PSAkcmV0dXJuICkgewoJCQkJCSRyZXR2YWwgPSAkcmV0dXJuX2NvZGU7CgkJCQl9IGVsc2VpZiAoICdhbGwnID09PSAkcmV0dXJuICkgewoJCQkJCSRyZXR2YWwgPSAob2JqZWN0KSBbCgkJCQkJCSdzdGRvdXQnICAgICAgPT4gdHJpbSggJHN0ZG91dCApLAoJCQkJCQknc3RkZXJyJyAgICAgID0+IHRyaW0oICRzdGRlcnIgKSwKCQkJCQkJJ3JldHVybl9jb2RlJyA9PiAkcmV0dXJuX2NvZGUsCgkJCQkJXTsKCQkJCX0KCQkJfQoJCQlpZiAoICEgJGV4aXRfZXJyb3IgKSB7CgkJCQlzZWxmOjokY2FwdHVyZV9leGl0ID0gZmFsc2U7CgkJCX0KCQl9CgkJaWYgKCAoIHRydWUgPT09ICRyZXR1cm4gfHwgJ3N0ZG91dCcgPT09ICRyZXR1cm4gKQoJCQkmJiAnanNvbicgPT09ICRwYXJzZSApIHsKCQkJJHJldHZhbCA9IGpzb25fZGVjb2RlKCAkcmV0dmFsLCB0cnVlICk7CgkJfQoJCXJldHVybiAkcmV0dmFsOwoJfQoKCS8qKgoJICogUnVuIGEgZ2l2ZW4gY29tbWFuZCB3aXRoaW4gdGhlIGN1cnJlbnQgcHJvY2VzcyB1c2luZyB0aGUgc2FtZSBnbG9iYWwKCSAqIHBhcmFtZXRlcnMuCgkgKgoJICogVXNlIGBXUF9DTEk6OnJ1bmNvbW1hbmQoKWAgaW5zdGVhZCwgd2hpY2ggaXMgZWFzaWVyIHRvIHVzZSBhbmQgd29ya3MgYmV0dGVyLgoJICoKCSAqIFRvIHJ1biBhIGNvbW1hbmQgdXNpbmcgYSBuZXcgcHJvY2VzcyB3aXRoIHRoZSBzYW1lIGdsb2JhbCBwYXJhbWV0ZXJzLAoJICogdXNlIFdQX0NMSTo6bGF1bmNoX3NlbGYoKS4gVG8gcnVuIGEgY29tbWFuZCB1c2luZyBhIG5ldyBwcm9jZXNzIHdpdGgKCSAqIGRpZmZlcmVudCBnbG9iYWwgcGFyYW1ldGVycywgdXNlIFdQX0NMSTo6bGF1bmNoKCkuCgkgKgoJICogYGBgCgkgKiBvYl9zdGFydCgpOwoJICogV1BfQ0xJOjpydW5fY29tbWFuZCggYXJyYXkoICdjbGknLCAnY21kLWR1bXAnICkgKTsKCSAqICRyZXQgPSBvYl9nZXRfY2xlYW4oKTsKCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgRXhlY3V0aW9uCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzIFBvc2l0aW9uYWwgYXJndW1lbnRzIGluY2x1ZGluZyBjb21tYW5kIG5hbWUuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBydW5fY29tbWFuZCggJGFyZ3MsICRhc3NvY19hcmdzID0gW10gKSB7CgkJc2VsZjo6Z2V0X3J1bm5lcigpLT5ydW5fY29tbWFuZCggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoKCgkvLyBERVBSRUNBVEVEIFNUVUZGCgoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRfbWFuX2RpcigpIHsKCQl0cmlnZ2VyX2Vycm9yKCAnV1BfQ0xJOjphZGRfbWFuX2RpcigpIGlzIGRlcHJlY2F0ZWQuIEFkZCBkb2NzIGlubGluZS4nLCBFX1VTRVJfV0FSTklORyApOwoJfQoKCS8vIGJhY2stY29tcGF0CglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG91dCggJHN0ciApIHsKCQlmd3JpdGUoIFNURE9VVCwgJHN0ciApOwoJfQoKCS8vIGJhY2stY29tcGF0CgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlZhbGlkRnVuY3Rpb25OYW1lLk1ldGhvZE5hbWVJbnZhbGlkIC0tIERlcHJlY2F0ZWQgbWV0aG9kLgoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRDb21tYW5kKCAkbmFtZSwgJGNsYXNzICkgewoJCXRyaWdnZXJfZXJyb3IoCgkJCXNwcmludGYoCgkJCQknd3AgJXM6ICVzIGlzIGRlcHJlY2F0ZWQuIHVzZSBXUF9DTEk6OmFkZF9jb21tYW5kKCkgaW5zdGVhZC4nLAoJCQkJJG5hbWUsCgkJCQlfX0ZVTkNUSU9OX18KCQkJKSwKCQkJRV9VU0VSX1dBUk5JTkcKCQkpOwoJCXNlbGY6OmFkZF9jb21tYW5kKCAkbmFtZSwgJGNsYXNzICk7Cgl9Cn0KPD9waHAKCi8vIFV0aWxpdGllcyB0aGF0IGRvIE5PVCBkZXBlbmQgb24gV29yZFByZXNzIGNvZGUuCgpuYW1lc3BhY2UgV1BfQ0xJXFV0aWxzOwoKdXNlIEFycmF5SXRlcmF0b3I7CnVzZSBjbGk7CnVzZSBjbGlccHJvZ3Jlc3NcQmFyOwp1c2UgY2xpXFNoZWxsOwp1c2UgQ2xvc3VyZTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb21wYXJhdG9yOwp1c2UgQ29tcG9zZXJcU2VtdmVyXFNlbXZlcjsKdXNlIEV4Y2VwdGlvbjsKdXNlIE11c3RhY2hlX0VuZ2luZTsKdXNlIFJlZmxlY3Rpb25GdW5jdGlvbjsKdXNlIFJlcXVlc3RzOwp1c2UgUmVxdWVzdHNfRXhjZXB0aW9uOwp1c2UgUnVudGltZUV4Y2VwdGlvbjsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxFeGl0RXhjZXB0aW9uOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxJbmZsZWN0b3I7CnVzZSBXUF9DTElcSXRlcmF0b3JzXFRyYW5zZm9ybTsKdXNlIFdQX0NMSVxOb09wOwp1c2UgV1BfQ0xJXFByb2Nlc3M7Cgpjb25zdCBQSEFSX1NUUkVBTV9QUkVGSVggPSAncGhhcjovLyc7CgovKioKICogUmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4gdG8gbWF0Y2ggX19GSUxFX18gYW5kIF9fRElSX18gY29uc3RhbnRzLgogKgogKiBXZSB0cnkgdG8gYmUgc21hcnQgYW5kIG9ubHkgcmVwbGFjZSB0aGUgY29uc3RhbnRzIHdoZW4gdGhleSBhcmUgbm90IHdpdGhpbiBxdW90ZXMuCiAqIFJlZ3VsYXIgZXhwcmVzc2lvbnMgYmVpbmcgc3RhdGVsZXNzLCB0aGlzIGlzIHByb2JhYmx5IG5vdCAxMDAlIGNvcnJlY3QgZm9yIGVkZ2UgY2FzZXMuCiAqCiAqIEBzZWUgaHR0cHM6Ly9yZWdleDEwMS5jb20vci85aFhwNWQvMTEKICogQHNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTcxNDk5LzkzMzA2NQogKgogKiBAdmFyIHN0cmluZwogKi8KY29uc3QgRklMRV9ESVJfUEFUVEVSTiA9ICclKD8+Iy4qPyQpfCg/Pi8vLio/JCl8KD8+L1wqLio/XCovKXwoPz5cJyg/Oig/PShcXFxcPykpXDEuKSo/XCcpfCg/PiIoPzooPz0oXFxcXD8pKVwyLikqPyIpfCg/PGZpbGU+XGJfX0ZJTEVfX1xiKXwoPzxkaXI+XGJfX0RJUl9fXGIpJW1zJzsKCmZ1bmN0aW9uIGluc2lkZV9waGFyKCkgewoJcmV0dXJuIDAgPT09IHN0cnBvcyggV1BfQ0xJX1JPT1QsIFBIQVJfU1RSRUFNX1BSRUZJWCApOwp9CgovLyBGaWxlcyB0aGF0IG5lZWQgdG8gYmUgcmVhZCBieSBleHRlcm5hbCBwcm9ncmFtcyBoYXZlIHRvIGJlIGV4dHJhY3RlZCBmcm9tIHRoZSBQaGFyIGFyY2hpdmUuCmZ1bmN0aW9uIGV4dHJhY3RfZnJvbV9waGFyKCAkcGF0aCApIHsKCWlmICggISBpbnNpZGVfcGhhcigpICkgewoJCXJldHVybiAkcGF0aDsKCX0KCgkkZm5hbWUgPSBiYXNlbmFtZSggJHBhdGggKTsKCgkkdG1wX3BhdGggPSBnZXRfdGVtcF9kaXIoKSAuIHVuaXFpZCggJ3dwLWNsaS1leHRyYWN0LWZyb20tcGhhci0nLCB0cnVlICkgLiAiLSRmbmFtZSI7CgoJY29weSggJHBhdGgsICR0bXBfcGF0aCApOwoKCXJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKAoJCWZ1bmN0aW9uKCkgdXNlICggJHRtcF9wYXRoICkgewoJCQlpZiAoIGZpbGVfZXhpc3RzKCAkdG1wX3BhdGggKSApIHsKCQkJCXVubGluayggJHRtcF9wYXRoICk7CgkJCX0KCQl9CgkpOwoKCXJldHVybiAkdG1wX3BhdGg7Cn0KCmZ1bmN0aW9uIGxvYWRfZGVwZW5kZW5jaWVzKCkgewoJaWYgKCBpbnNpZGVfcGhhcigpICkgewoJCWlmICggZmlsZV9leGlzdHMoIFdQX0NMSV9ST09UIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJyApICkgewoJCQlyZXF1aXJlIFdQX0NMSV9ST09UIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCQl9IGVsc2VpZiAoIGZpbGVfZXhpc3RzKCBkaXJuYW1lKCBkaXJuYW1lKCBXUF9DTElfUk9PVCApICkgLiAnL2F1dG9sb2FkLnBocCcgKSApIHsKCQkJcmVxdWlyZSBkaXJuYW1lKCBkaXJuYW1lKCBXUF9DTElfUk9PVCApICkgLiAnL2F1dG9sb2FkLnBocCc7CgkJfQoJCXJldHVybjsKCX0KCgkkaGFzX2F1dG9sb2FkID0gZmFsc2U7CgoJZm9yZWFjaCAoIGdldF92ZW5kb3JfcGF0aHMoKSBhcyAkdmVuZG9yX3BhdGggKSB7CgkJaWYgKCBmaWxlX2V4aXN0cyggJHZlbmRvcl9wYXRoIC4gJy9hdXRvbG9hZC5waHAnICkgKSB7CgkJCXJlcXVpcmUgJHZlbmRvcl9wYXRoIC4gJy9hdXRvbG9hZC5waHAnOwoJCQkkaGFzX2F1dG9sb2FkID0gdHJ1ZTsKCQkJYnJlYWs7CgkJfQoJfQoKCWlmICggISAkaGFzX2F1dG9sb2FkICkgewoJCWZ3cml0ZSggU1RERVJSLCAiSW50ZXJuYWwgZXJyb3I6IENhbid0IGZpbmQgQ29tcG9zZXIgYXV0b2xvYWRlci5cblRyeSBydW5uaW5nOiBjb21wb3NlciBpbnN0YWxsXG4iICk7CgkJZXhpdCggMyApOwoJfQp9CgpmdW5jdGlvbiBnZXRfdmVuZG9yX3BhdGhzKCkgewoJJHZlbmRvcl9wYXRocyAgICAgICAgPSBbCgkJV1BfQ0xJX1JPT1QgLiAnLy4uLy4uLy4uL3ZlbmRvcicsICAvLyBQYXJ0IG9mIGEgbGFyZ2VyIHByb2plY3QgLyBpbnN0YWxsZWQgdmlhIENvbXBvc2VyIChwcmVmZXJyZWQpLgoJCVdQX0NMSV9ST09UIC4gJy92ZW5kb3InLCAgICAgICAgICAgLy8gVG9wLWxldmVsIHByb2plY3QgLyBpbnN0YWxsZWQgYXMgR2l0IGNsb25lLgoJXTsKCSRtYXliZV9jb21wb3Nlcl9qc29uID0gV1BfQ0xJX1JPT1QgLiAnLy4uLy4uLy4uL2NvbXBvc2VyLmpzb24nOwoJaWYgKCBmaWxlX2V4aXN0cyggJG1heWJlX2NvbXBvc2VyX2pzb24gKSAmJiBpc19yZWFkYWJsZSggJG1heWJlX2NvbXBvc2VyX2pzb24gKSApIHsKCQkkY29tcG9zZXIgPSBqc29uX2RlY29kZSggZmlsZV9nZXRfY29udGVudHMoICRtYXliZV9jb21wb3Nlcl9qc29uICkgKTsKCQlpZiAoICEgZW1wdHkoICRjb21wb3Nlci0+Y29uZmlnICkgJiYgISBlbXB0eSggJGNvbXBvc2VyLT5jb25maWctPnsndmVuZG9yLWRpcid9ICkgKSB7CgkJCWFycmF5X3Vuc2hpZnQoICR2ZW5kb3JfcGF0aHMsIFdQX0NMSV9ST09UIC4gJy8uLi8uLi8uLi8nIC4gJGNvbXBvc2VyLT5jb25maWctPnsndmVuZG9yLWRpcid9ICk7CgkJfQoJfQoJcmV0dXJuICR2ZW5kb3JfcGF0aHM7Cn0KCi8vIFVzaW5nIHJlcXVpcmUoKSBkaXJlY3RseSBpbnNpZGUgYSBjbGFzcyBncmFudHMgYWNjZXNzIHRvIHByaXZhdGUgbWV0aG9kcyB0byB0aGUgbG9hZGVkIGNvZGUuCmZ1bmN0aW9uIGxvYWRfZmlsZSggJHBhdGggKSB7CglyZXF1aXJlX29uY2UgJHBhdGg7Cn0KCmZ1bmN0aW9uIGxvYWRfY29tbWFuZCggJG5hbWUgKSB7CgkkcGF0aCA9IFdQX0NMSV9ST09UIC4gIi9waHAvY29tbWFuZHMvJG5hbWUucGhwIjsKCglpZiAoIGlzX3JlYWRhYmxlKCAkcGF0aCApICkgewoJCWluY2x1ZGVfb25jZSAkcGF0aDsKCX0KfQoKLyoqCiAqIExpa2UgYXJyYXlfbWFwKCksIGV4Y2VwdCBpdCByZXR1cm5zIGEgbmV3IGl0ZXJhdG9yLCBpbnN0ZWFkIG9mIGEgbW9kaWZpZWQgYXJyYXkuCiAqCiAqIEV4YW1wbGU6CiAqCiAqICAgICAkYXJyID0gYXJyYXkoJ0Zvb3RiYWxsJywgJ1NvY2tlcicpOwogKgogKiAgICAgJGl0ID0gaXRlcmF0b3JfbWFwKCRhcnIsICdzdHJ0b2xvd2VyJywgZnVuY3Rpb24oJHZhbCkgewogKiAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJ2ZvbycsICdiYXInLCAkdmFsKTsKICogICAgIH0pOwogKgogKiAgICAgZm9yZWFjaCAoICRpdCBhcyAkdmFsICkgewogKiAgICAgICB2YXJfZHVtcCgkdmFsKTsKICogICAgIH0KICoKICogQHBhcmFtIGFycmF5fG9iamVjdCAkaXQgRWl0aGVyIGEgcGxhaW4gYXJyYXkgb3IgYW5vdGhlciBpdGVyYXRvci4KICogQHBhcmFtIGNhbGxiYWNrICAgICAkZm4gVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGFuIGVsZW1lbnQuCiAqIEByZXR1cm4gb2JqZWN0IEFuIGl0ZXJhdG9yIHRoYXQgYXBwbGllcyB0aGUgZ2l2ZW4gY2FsbGJhY2socykuCiAqLwpmdW5jdGlvbiBpdGVyYXRvcl9tYXAoICRpdCwgJGZuICkgewoJaWYgKCBpc19hcnJheSggJGl0ICkgKSB7CgkJJGl0ID0gbmV3IEFycmF5SXRlcmF0b3IoICRpdCApOwoJfQoKCWlmICggISBtZXRob2RfZXhpc3RzKCAkaXQsICdhZGRfdHJhbnNmb3JtJyApICkgewoJCSRpdCA9IG5ldyBUcmFuc2Zvcm0oICRpdCApOwoJfQoKCWZvcmVhY2ggKCBhcnJheV9zbGljZSggZnVuY19nZXRfYXJncygpLCAxICkgYXMgJGZuICkgewoJCSRpdC0+YWRkX3RyYW5zZm9ybSggJGZuICk7Cgl9CgoJcmV0dXJuICRpdDsKfQoKLyoqCiAqIFNlYXJjaCBmb3IgZmlsZSBieSB3YWxraW5nIHVwIHRoZSBkaXJlY3RvcnkgdHJlZSB1bnRpbCB0aGUgZmlyc3QgZmlsZSBpcyBmb3VuZCBvciB1bnRpbCAkc3RvcF9jaGVjaygkZGlyKSByZXR1cm5zIHRydWUuCiAqCiAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGZpbGVzICAgICAgVGhlIGZpbGVzIChvciBmaWxlKSB0byBzZWFyY2ggZm9yLgogKiBAcGFyYW0gc3RyaW5nfG51bGwgICRkaXIgICAgICAgIFRoZSBkaXJlY3RvcnkgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb207IGRlZmF1bHRzIHRvIENXRC4KICogQHBhcmFtIGNhbGxhYmxlICAgICAkc3RvcF9jaGVjayBGdW5jdGlvbiB3aGljaCBpcyBwYXNzZWQgdGhlIGN1cnJlbnQgZGlyIGVhY2ggdGltZSBhIGRpcmVjdG9yeSBsZXZlbCBpcyB0cmF2ZXJzZWQuCiAqIEByZXR1cm4gbnVsbHxzdHJpbmcgTnVsbCBpZiB0aGUgZmlsZSB3YXMgbm90IGZvdW5kLgogKi8KZnVuY3Rpb24gZmluZF9maWxlX3Vwd2FyZCggJGZpbGVzLCAkZGlyID0gbnVsbCwgJHN0b3BfY2hlY2sgPSBudWxsICkgewoJJGZpbGVzID0gKGFycmF5KSAkZmlsZXM7CglpZiAoIGlzX251bGwoICRkaXIgKSApIHsKCQkkZGlyID0gZ2V0Y3dkKCk7Cgl9Cgl3aGlsZSAoIGlzX3JlYWRhYmxlKCAkZGlyICkgKSB7CgkJLy8gU3RvcCB3YWxraW5nIHVwIHdoZW4gdGhlIHN1cHBsaWVkIGNhbGxhYmxlIHJldHVybnMgdHJ1ZSBiZWluZyBwYXNzZWQgdGhlICRkaXIKCQlpZiAoIGlzX2NhbGxhYmxlKCAkc3RvcF9jaGVjayApICYmIGNhbGxfdXNlcl9mdW5jKCAkc3RvcF9jaGVjaywgJGRpciApICkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGUgKSB7CgkJCSRwYXRoID0gJGRpciAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkZmlsZTsKCQkJaWYgKCBmaWxlX2V4aXN0cyggJHBhdGggKSApIHsKCQkJCXJldHVybiAkcGF0aDsKCQkJfQoJCX0KCgkJJHBhcmVudF9kaXIgPSBkaXJuYW1lKCAkZGlyICk7CgkJaWYgKCBlbXB0eSggJHBhcmVudF9kaXIgKSB8fCAkcGFyZW50X2RpciA9PT0gJGRpciApIHsKCQkJYnJlYWs7CgkJfQoJCSRkaXIgPSAkcGFyZW50X2RpcjsKCX0KCXJldHVybiBudWxsOwp9CgpmdW5jdGlvbiBpc19wYXRoX2Fic29sdXRlKCAkcGF0aCApIHsKCS8vIFdpbmRvd3MKCWlmICggaXNzZXQoICRwYXRoWzFdICkgJiYgJzonID09PSAkcGF0aFsxXSApIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglyZXR1cm4gJy8nID09PSAkcGF0aFswXTsKfQoKLyoqCiAqIENvbXBvc2VzIHBvc2l0aW9uYWwgYXJndW1lbnRzIGludG8gYSBjb21tYW5kIHN0cmluZy4KICoKICogQHBhcmFtIGFycmF5ICRhcmdzIFBvc2l0aW9uYWwgYXJndW1lbnRzIHRvIGNvbXBvc2UuCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBhcmdzX3RvX3N0ciggJGFyZ3MgKSB7CglyZXR1cm4gJyAnIC4gaW1wbG9kZSggJyAnLCBhcnJheV9tYXAoICdlc2NhcGVzaGVsbGFyZycsICRhcmdzICkgKTsKfQoKLyoqCiAqIENvbXBvc2VzIGFzc29jaWF0aXZlIGFyZ3VtZW50cyBpbnRvIGEgY29tbWFuZCBzdHJpbmcuCiAqCiAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcmd1bWVudHMgdG8gY29tcG9zZS4KICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGFzc29jX2FyZ3NfdG9fc3RyKCAkYXNzb2NfYXJncyApIHsKCSRzdHIgPSAnJzsKCglmb3JlYWNoICggJGFzc29jX2FyZ3MgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJaWYgKCB0cnVlID09PSAkdmFsdWUgKSB7CgkJCSRzdHIgLj0gIiAtLSRrZXkiOwoJCX0gZWxzZWlmICggaXNfYXJyYXkoICR2YWx1ZSApICkgewoJCQlmb3JlYWNoICggJHZhbHVlIGFzICR2ICkgewoJCQkJJHN0ciAuPSBhc3NvY19hcmdzX3RvX3N0cigKCQkJCQlbCgkJCQkJCSRrZXkgPT4gJHYsCgkJCQkJXQoJCQkJKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRzdHIgLj0gIiAtLSRrZXk9IiAuIGVzY2FwZXNoZWxsYXJnKCAkdmFsdWUgKTsKCQl9Cgl9CgoJcmV0dXJuICRzdHI7Cn0KCi8qKgogKiBHaXZlbiBhIHRlbXBsYXRlIHN0cmluZyBhbmQgYW4gYXJiaXRyYXJ5IG51bWJlciBvZiBhcmd1bWVudHMsCiAqIHJldHVybnMgdGhlIGZpbmFsIGNvbW1hbmQsIHdpdGggdGhlIHBhcmFtZXRlcnMgZXNjYXBlZC4KICovCmZ1bmN0aW9uIGVzY19jbWQoICRjbWQgKSB7CglpZiAoIGZ1bmNfbnVtX2FyZ3MoKSA8IDIgKSB7CgkJdHJpZ2dlcl9lcnJvciggJ2VzY19jbWQoKSByZXF1aXJlcyBhdCBsZWFzdCB0d28gYXJndW1lbnRzLicsIEVfVVNFUl9XQVJOSU5HICk7Cgl9CgoJJGFyZ3MgPSBmdW5jX2dldF9hcmdzKCk7CgoJJGNtZCA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCXJldHVybiB2c3ByaW50ZiggJGNtZCwgYXJyYXlfbWFwKCAnZXNjYXBlc2hlbGxhcmcnLCAkYXJncyApICk7Cn0KCi8qKgogKiBHZXRzIHBhdGggdG8gV29yZFByZXNzIGNvbmZpZ3VyYXRpb24uCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBsb2NhdGVfd3BfY29uZmlnKCkgewoJc3RhdGljICRwYXRoOwoKCWlmICggbnVsbCA9PT0gJHBhdGggKSB7CgkJJHBhdGggPSBmYWxzZTsKCgkJaWYgKCBnZXRlbnYoICdXUF9DT05GSUdfUEFUSCcgKSAmJiBmaWxlX2V4aXN0cyggZ2V0ZW52KCAnV1BfQ09ORklHX1BBVEgnICkgKSApIHsKCQkJJHBhdGggPSBnZXRlbnYoICdXUF9DT05GSUdfUEFUSCcgKTsKCQl9IGVsc2VpZiAoIGZpbGVfZXhpc3RzKCBBQlNQQVRIIC4gJ3dwLWNvbmZpZy5waHAnICkgKSB7CgkJCSRwYXRoID0gQUJTUEFUSCAuICd3cC1jb25maWcucGhwJzsKCQl9IGVsc2VpZiAoIGZpbGVfZXhpc3RzKCBkaXJuYW1lKCBBQlNQQVRIICkgLiAnL3dwLWNvbmZpZy5waHAnICkgJiYgISBmaWxlX2V4aXN0cyggZGlybmFtZSggQUJTUEFUSCApIC4gJy93cC1zZXR0aW5ncy5waHAnICkgKSB7CgkJCSRwYXRoID0gZGlybmFtZSggQUJTUEFUSCApIC4gJy93cC1jb25maWcucGhwJzsKCQl9CgoJCWlmICggJHBhdGggKSB7CgkJCSRwYXRoID0gcmVhbHBhdGgoICRwYXRoICk7CgkJfQoJfQoKCXJldHVybiAkcGF0aDsKfQoKZnVuY3Rpb24gd3BfdmVyc2lvbl9jb21wYXJlKCAkc2luY2UsICRvcGVyYXRvciApIHsKCSR3cF92ZXJzaW9uID0gc3RyX3JlcGxhY2UoICctc3JjJywgJycsICRHTE9CQUxTWyd3cF92ZXJzaW9uJ10gKTsKCSRzaW5jZSAgICAgID0gc3RyX3JlcGxhY2UoICctc3JjJywgJycsICRzaW5jZSApOwoJcmV0dXJuIHZlcnNpb25fY29tcGFyZSggJHdwX3ZlcnNpb24sICRzaW5jZSwgJG9wZXJhdG9yICk7Cn0KCi8qKgogKiBSZW5kZXIgYSBjb2xsZWN0aW9uIG9mIGl0ZW1zIGFzIGFuIEFTQ0lJIHRhYmxlLCBKU09OLCBDU1YsIFlBTUwsIGxpc3Qgb2YgaWRzLCBvciBjb3VudC4KICoKICogR2l2ZW4gYSBjb2xsZWN0aW9uIG9mIGl0ZW1zIHdpdGggYSBjb25zaXN0ZW50IGRhdGEgc3RydWN0dXJlOgogKgogKiBgYGAKICogJGl0ZW1zID0gYXJyYXkoCiAqICAgICBhcnJheSgKICogICAgICAgICAna2V5JyAgID0+ICdmb28nLAogKiAgICAgICAgICd2YWx1ZScgID0+ICdiYXInLAogKiAgICAgKQogKiApOwogKiBgYGAKICoKICogUmVuZGVyIGAkaXRlbXNgIGFzIGFuIEFTQ0lJIHRhYmxlOgogKgogKiBgYGAKICogV1BfQ0xJXFV0aWxzXGZvcm1hdF9pdGVtcyggJ3RhYmxlJywgJGl0ZW1zLCBhcnJheSggJ2tleScsICd2YWx1ZScgKSApOwogKgogKiAjICstLS0tLSstLS0tLS0tKwogKiAjIHwga2V5IHwgdmFsdWUgfAogKiAjICstLS0tLSstLS0tLS0tKwogKiAjIHwgZm9vIHwgYmFyICAgfAogKiAjICstLS0tLSstLS0tLS0tKwogKiBgYGAKICoKICogT3IgcmVuZGVyIGAkaXRlbXNgIGFzIFlBTUw6CiAqCiAqIGBgYAogKiBXUF9DTElcVXRpbHNcZm9ybWF0X2l0ZW1zKCAneWFtbCcsICRpdGVtcywgYXJyYXkoICdrZXknLCAndmFsdWUnICkgKTsKICoKICogIyAtLS0KICogIyAtCiAqICMgICBrZXk6IGZvbwogKiAjICAgdmFsdWU6IGJhcgogKiBgYGAKICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IE91dHB1dAogKgogKiBAcGFyYW0gc3RyaW5nICAgICAgICRmb3JtYXQgRm9ybWF0IHRvIHVzZTogJ3RhYmxlJywgJ2pzb24nLCAnY3N2JywgJ3lhbWwnLCAnaWRzJywgJ2NvdW50Jy4KICogQHBhcmFtIGFycmF5ICAgICAgICAkaXRlbXMgIEFuIGFycmF5IG9mIGl0ZW1zIHRvIG91dHB1dC4KICogQHBhcmFtIGFycmF5fHN0cmluZyAkZmllbGRzIE5hbWVkIGZpZWxkcyBmb3IgZWFjaCBpdGVtIG9mIGRhdGEuIENhbiBiZSBhcnJheSBvciBjb21tYS1zZXBhcmF0ZWQgbGlzdC4KICovCmZ1bmN0aW9uIGZvcm1hdF9pdGVtcyggJGZvcm1hdCwgJGl0ZW1zLCAkZmllbGRzICkgewoJJGFzc29jX2FyZ3MgPSBjb21wYWN0KCAnZm9ybWF0JywgJ2ZpZWxkcycgKTsKCSRmb3JtYXR0ZXIgID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpdGVtcyApOwp9CgovKioKICogV3JpdGUgZGF0YSBhcyBDU1YgdG8gYSBnaXZlbiBmaWxlLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKgogKiBAcGFyYW0gcmVzb3VyY2UgJGZkICAgICAgRmlsZSBkZXNjcmlwdG9yLgogKiBAcGFyYW0gYXJyYXkgICAgJHJvd3MgICAgQXJyYXkgb2Ygcm93cyB0byBvdXRwdXQuCiAqIEBwYXJhbSBhcnJheSAgICAkaGVhZGVycyBMaXN0IG9mIENTViBjb2x1bW5zIChvcHRpb25hbCkuCiAqLwpmdW5jdGlvbiB3cml0ZV9jc3YoICRmZCwgJHJvd3MsICRoZWFkZXJzID0gW10gKSB7CglpZiAoICEgZW1wdHkoICRoZWFkZXJzICkgKSB7CgkJZnB1dGNzdiggJGZkLCAkaGVhZGVycyApOwoJfQoKCWZvcmVhY2ggKCAkcm93cyBhcyAkcm93ICkgewoJCWlmICggISBlbXB0eSggJGhlYWRlcnMgKSApIHsKCQkJJHJvdyA9IHBpY2tfZmllbGRzKCAkcm93LCAkaGVhZGVycyApOwoJCX0KCgkJZnB1dGNzdiggJGZkLCBhcnJheV92YWx1ZXMoICRyb3cgKSApOwoJfQp9CgovKioKICogUGljayBmaWVsZHMgZnJvbSBhbiBhc3NvY2lhdGl2ZSBhcnJheSBvciBvYmplY3QuCiAqCiAqIEBwYXJhbSAgYXJyYXl8b2JqZWN0ICRpdGVtICAgIEFzc29jaWF0aXZlIGFycmF5IG9yIG9iamVjdCB0byBwaWNrIGZpZWxkcyBmcm9tLgogKiBAcGFyYW0gIGFycmF5ICAgICAgICAkZmllbGRzICBMaXN0IG9mIGZpZWxkcyB0byBwaWNrLgogKiBAcmV0dXJuIGFycmF5CiAqLwpmdW5jdGlvbiBwaWNrX2ZpZWxkcyggJGl0ZW0sICRmaWVsZHMgKSB7CgkkdmFsdWVzID0gW107CgoJaWYgKCBpc19vYmplY3QoICRpdGVtICkgKSB7CgkJZm9yZWFjaCAoICRmaWVsZHMgYXMgJGZpZWxkICkgewoJCQkkdmFsdWVzWyAkZmllbGQgXSA9IGlzc2V0KCAkaXRlbS0+JGZpZWxkICkgPyAkaXRlbS0+JGZpZWxkIDogbnVsbDsKCQl9Cgl9IGVsc2UgewoJCWZvcmVhY2ggKCAkZmllbGRzIGFzICRmaWVsZCApIHsKCQkJJHZhbHVlc1sgJGZpZWxkIF0gPSBpc3NldCggJGl0ZW1bICRmaWVsZCBdICkgPyAkaXRlbVsgJGZpZWxkIF0gOiBudWxsOwoJCX0KCX0KCglyZXR1cm4gJHZhbHVlczsKfQoKLyoqCiAqIExhdW5jaCBzeXN0ZW0ncyAkRURJVE9SIGZvciB0aGUgdXNlciB0byBlZGl0IHNvbWUgdGV4dC4KICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IElucHV0CiAqCiAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFNvbWUgZm9ybSBvZiB0ZXh0IHRvIGVkaXQgKGUuZy4gcG9zdCBjb250ZW50KS4KICogQHBhcmFtIHN0cmluZyAkdGl0bGUgVGl0bGUgdG8gZGlzcGxheSBpbiB0aGUgZWRpdG9yLgogKiBAcGFyYW0gc3RyaW5nICRleHQgICBFeHRlbnNpb24gdG8gdXNlIHdpdGggdGhlIHRlbXAgZmlsZS4KICogQHJldHVybiBzdHJpbmd8Ym9vbCAgRWRpdGVkIHRleHQsIGlmIGZpbGUgaXMgc2F2ZWQgZnJvbSBlZGl0b3I7IGZhbHNlLCBpZiBubyBjaGFuZ2UgdG8gZmlsZS4KICovCmZ1bmN0aW9uIGxhdW5jaF9lZGl0b3JfZm9yX2lucHV0KCAkaW5wdXQsICR0aXRsZSA9ICdXUC1DTEknLCAkZXh0ID0gJ3RtcCcgKSB7CgoJY2hlY2tfcHJvY19hdmFpbGFibGUoICdsYXVuY2hfZWRpdG9yX2Zvcl9pbnB1dCcgKTsKCgkkdG1wZGlyID0gZ2V0X3RlbXBfZGlyKCk7CgoJZG8gewoJCSR0bXBmaWxlICA9IGJhc2VuYW1lKCAkdGl0bGUgKTsKCQkkdG1wZmlsZSAgPSBwcmVnX3JlcGxhY2UoICd8XC5bXi5dKiR8JywgJycsICR0bXBmaWxlICk7CgkJJHRtcGZpbGUgLj0gJy0nIC4gc3Vic3RyKCBtZDUoIG10X3JhbmQoKSApLCAwLCA2ICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuQWx0ZXJuYXRpdmVGdW5jdGlvbnMucmFuZF9tdF9yYW5kIC0tIG5vIGNyeXB0byBhbmQgV1Agbm90IGxvYWRlZC4KCQkkdG1wZmlsZSAgPSAkdG1wZGlyIC4gJHRtcGZpbGUgLiAnLicgLiAkZXh0OwoJCSRmcCAgICAgICA9IGZvcGVuKCAkdG1wZmlsZSwgJ3hiJyApOwoJCWlmICggISAkZnAgJiYgaXNfd3JpdGFibGUoICR0bXBkaXIgKSAmJiBmaWxlX2V4aXN0cyggJHRtcGZpbGUgKSApIHsKCQkJJHRtcGZpbGUgPSAnJzsKCQkJY29udGludWU7CgkJfQoJCWlmICggJGZwICkgewoJCQlmY2xvc2UoICRmcCApOwoJCX0KCX0gd2hpbGUgKCAhICR0bXBmaWxlICk7CgoJaWYgKCAhICR0bXBmaWxlICkgewoJCVdQX0NMSTo6ZXJyb3IoICdFcnJvciBjcmVhdGluZyB0ZW1wb3JhcnkgZmlsZS4nICk7Cgl9CgoJZmlsZV9wdXRfY29udGVudHMoICR0bXBmaWxlLCAkaW5wdXQgKTsKCgkkZWRpdG9yID0gZ2V0ZW52KCAnRURJVE9SJyApOwoJaWYgKCAhICRlZGl0b3IgKSB7CgkJJGVkaXRvciA9IGlzX3dpbmRvd3MoKSA/ICdub3RlcGFkJyA6ICd2aSc7Cgl9CgoJJGRlc2NyaXB0b3JzcGVjID0gWyBTVERJTiwgU1RET1VULCBTVERFUlIgXTsKCSRwcm9jZXNzICAgICAgICA9IHByb2Nfb3Blbl9jb21wYXQoICIkZWRpdG9yICIgLiBlc2NhcGVzaGVsbGFyZyggJHRtcGZpbGUgKSwgJGRlc2NyaXB0b3JzcGVjLCAkcGlwZXMgKTsKCSRyICAgICAgICAgICAgICA9IHByb2NfY2xvc2UoICRwcm9jZXNzICk7CglpZiAoICRyICkgewoJCWV4aXQoICRyICk7Cgl9CgoJJG91dHB1dCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkdG1wZmlsZSApOwoKCXVubGluayggJHRtcGZpbGUgKTsKCglpZiAoICRvdXRwdXQgPT09ICRpbnB1dCApIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcmV0dXJuICRvdXRwdXQ7Cn0KCi8qKgogKiBAcGFyYW0gc3RyaW5nICRyYXdfaG9zdCBNeVNRTCBob3N0IHN0cmluZywgYXMgZGVmaW5lZCBpbiB3cC1jb25maWcucGhwLgogKgogKiBAcmV0dXJuIGFycmF5CiAqLwpmdW5jdGlvbiBteXNxbF9ob3N0X3RvX2NsaV9hcmdzKCAkcmF3X2hvc3QgKSB7CgkkYXNzb2NfYXJncyA9IFtdOwoKCS8qKgoJICogSWYgdGhlIGhvc3Qgc3RyaW5nIGJlZ2lucyB3aXRoICdwOicgZm9yIGEgcGVyc2lzdGVudCBkYiBjb25uZWN0aW9uLAoJICogcmVwbGFjZSAncDonIHdpdGggbm90aGluZy4KCSAqLwoJaWYgKCBzdWJzdHIoICRyYXdfaG9zdCwgMCwgMiApID09PSAncDonICkgewoJCSRyYXdfaG9zdCA9IHN1YnN0cl9yZXBsYWNlKCAkcmF3X2hvc3QsICcnLCAwLCAyICk7Cgl9CgoJJGhvc3RfcGFydHMgPSBleHBsb2RlKCAnOicsICRyYXdfaG9zdCApOwoJaWYgKCBjb3VudCggJGhvc3RfcGFydHMgKSA9PT0gMiApIHsKCQlsaXN0KCAkYXNzb2NfYXJnc1snaG9zdCddLCAkZXh0cmEgKSA9ICRob3N0X3BhcnRzOwoJCSRleHRyYSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gdHJpbSggJGV4dHJhICk7CgkJaWYgKCBpc19udW1lcmljKCAkZXh0cmEgKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3BvcnQnXSAgICAgPSAoaW50KSAkZXh0cmE7CgkJCSRhc3NvY19hcmdzWydwcm90b2NvbCddID0gJ3RjcCc7CgkJfSBlbHNlaWYgKCAnJyAhPT0gJGV4dHJhICkgewoJCQkkYXNzb2NfYXJnc1snc29ja2V0J10gPSAkZXh0cmE7CgkJfQoJfSBlbHNlIHsKCQkkYXNzb2NfYXJnc1snaG9zdCddID0gJHJhd19ob3N0OwoJfQoKCXJldHVybiAkYXNzb2NfYXJnczsKfQoKLyoqCiAqIFJ1biBhIE15U1FMIGNvbW1hbmQgYW5kIG9wdGlvbmFsbHkgcmV0dXJuIHRoZSBvdXRwdXQuCiAqCiAqIEBzaW5jZSB2Mi41LjAgRGVwcmVjYXRlZCAkZGVzY3JpcHRvcnMgYXJndW1lbnQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNtZCAgICAgICAgICAgQ29tbWFuZCB0byBydW4uCiAqIEBwYXJhbSBhcnJheSAgJGFzc29jX2FyZ3MgICAgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHVzZS4KICogQHBhcmFtIG1peGVkICAkXyAgICAgICAgICAgICBEZXByZWNhdGVkLiBGb3JtZXIgJGRlc2NyaXB0b3JzIGFyZ3VtZW50LgogKiBAcGFyYW0gYm9vbCAgICRzZW5kX3RvX3NoZWxsIE9wdGlvbmFsLiBXaGV0aGVyIHRvIHNlbmQgU1RET1VUIGFuZCBTVERFUlIKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW1lZGlhdGVseSB0byB0aGUgc2hlbGwuIERlZmF1bHRzIHRvIHRydWUuCiAqIEBwYXJhbSBib29sICAgJGludGVyYWN0aXZlICAgT3B0aW9uYWwuIFdoZXRoZXIgTXlTUUwgaXMgbWVhbnQgdG8gYmUKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZCBhcyBhbiBpbnRlcmFjdGl2ZSBwcm9jZXNzLiBEZWZhdWx0cwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGZhbHNlLgogKgogKiBAcmV0dXJuIGFycmF5IHsKICogICAgIEFzc29jaWF0aXZlIGFycmF5IGNvbnRhaW5pbmcgU1RET1VUIGFuZCBTVERFUlIgb3V0cHV0LgogKgogKiAgICAgQHR5cGUgc3RyaW5nICRzdGRvdXQgICAgT3V0cHV0IHRoYXQgd2FzIHNlbnQgdG8gU1RET1VULgogKiAgICAgQHR5cGUgc3RyaW5nICRzdGRlcnIgICAgT3V0cHV0IHRoYXQgd2FzIHNlbnQgdG8gU1RERVJSLgogKiAgICAgQHR5cGUgaW50ICAgICRleGl0X2NvZGUgRXhpdCBjb2RlIG9mIHRoZSBwcm9jZXNzLgogKiB9CiAqLwpmdW5jdGlvbiBydW5fbXlzcWxfY29tbWFuZCggJGNtZCwgJGFzc29jX2FyZ3MsICRfID0gbnVsbCwgJHNlbmRfdG9fc2hlbGwgPSB0cnVlLCAkaW50ZXJhY3RpdmUgPSBmYWxzZSApIHsKCWNoZWNrX3Byb2NfYXZhaWxhYmxlKCAncnVuX215c3FsX2NvbW1hbmQnICk7CgoJJGRlc2NyaXB0b3JzID0gKCAkaW50ZXJhY3RpdmUgfHwgJHNlbmRfdG9fc2hlbGwgKSA/CgkJWwoJCQkwID0+IFNURElOLAoJCQkxID0+IFNURE9VVCwKCQkJMiA9PiBTVERFUlIsCgkJXSA6CgkJWwoJCQkwID0+IFNURElOLAoJCQkxID0+IFsgJ3BpcGUnLCAndycgXSwKCQkJMiA9PiBbICdwaXBlJywgJ3cnIF0sCgkJXTsKCgkkc3Rkb3V0ID0gJyc7Cgkkc3RkZXJyID0gJyc7CgkkcGlwZXMgID0gW107CgoJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2hvc3QnXSApICkgewoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUmVzdHJpY3RlZEZ1bmN0aW9ucy5teXNxbF9teXNxbF9ob3N0X3RvX2NsaV9hcmdzIC0tIE1pc2lkZW50aWZpZWQgYXMgUEhQIG5hdGl2ZSBNeVNRTCBmdW5jdGlvbi4KCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkYXNzb2NfYXJncywgbXlzcWxfaG9zdF90b19jbGlfYXJncyggJGFzc29jX2FyZ3NbJ2hvc3QnXSApICk7Cgl9CgoJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3Bhc3MnXSApICkgewoJCSRvbGRfcGFzc3dvcmQgPSBnZXRlbnYoICdNWVNRTF9QV0QnICk7CgkJcHV0ZW52KCAnTVlTUUxfUFdEPScgLiAkYXNzb2NfYXJnc1sncGFzcyddICk7CgkJdW5zZXQoICRhc3NvY19hcmdzWydwYXNzJ10gKTsKCX0KCgkkZmluYWxfY21kID0gZm9yY2VfZW52X29uX25peF9zeXN0ZW1zKCAkY21kICkgLiBhc3NvY19hcmdzX3RvX3N0ciggJGFzc29jX2FyZ3MgKTsKCglXUF9DTEk6OmRlYnVnKCAnRmluYWwgTXlTUUwgY29tbWFuZDogJyAuICRmaW5hbF9jbWQsICdkYicgKTsKCSRwcm9jZXNzID0gcHJvY19vcGVuX2NvbXBhdCggJGZpbmFsX2NtZCwgJGRlc2NyaXB0b3JzLCAkcGlwZXMgKTsKCglpZiAoIGlzc2V0KCAkb2xkX3Bhc3N3b3JkICkgKSB7CgkJcHV0ZW52KCAnTVlTUUxfUFdEPScgLiAkb2xkX3Bhc3N3b3JkICk7Cgl9CgoJaWYgKCAhICRwcm9jZXNzICkgewoJCVdQX0NMSTo6ZGVidWcoICdGYWlsZWQgdG8gY3JlYXRlIGEgdmFsaWQgcHJvY2VzcyB1c2luZyBwcm9jX29wZW5fY29tcGF0KCknLCAnZGInICk7CgkJZXhpdCggMSApOwoJfQoKCWlmICggaXNfcmVzb3VyY2UoICRwcm9jZXNzICkgJiYgISAkc2VuZF90b19zaGVsbCAmJiAhICRpbnRlcmFjdGl2ZSApIHsKCQkkc3Rkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cyggJHBpcGVzWzFdICk7CgkJJHN0ZGVyciA9IHN0cmVhbV9nZXRfY29udGVudHMoICRwaXBlc1syXSApOwoKCQlmY2xvc2UoICRwaXBlc1sxXSApOwoJCWZjbG9zZSggJHBpcGVzWzJdICk7Cgl9CgoJJGV4aXRfY29kZSA9IHByb2NfY2xvc2UoICRwcm9jZXNzICk7CgoJaWYgKCAkZXhpdF9jb2RlICYmICggJHNlbmRfdG9fc2hlbGwgfHwgJGludGVyYWN0aXZlICkgKSB7CgkJZXhpdCggJGV4aXRfY29kZSApOwoJfQoKCXJldHVybiBbCgkJJHN0ZG91dCwKCQkkc3RkZXJyLAoJCSRleGl0X2NvZGUsCgldOwp9CgovKioKICogUmVuZGVyIFBIUCBvciBvdGhlciB0eXBlcyBvZiBmaWxlcyB1c2luZyBNdXN0YWNoZSB0ZW1wbGF0ZXMuCiAqCiAqIElNUE9SVEFOVDogQXV0b21hdGljIEhUTUwgZXNjYXBpbmcgaXMgZGlzYWJsZWQhCiAqLwpmdW5jdGlvbiBtdXN0YWNoZV9yZW5kZXIoICR0ZW1wbGF0ZV9uYW1lLCAkZGF0YSA9IFtdICkgewoJaWYgKCAhIGZpbGVfZXhpc3RzKCAkdGVtcGxhdGVfbmFtZSApICkgewoJCSR0ZW1wbGF0ZV9uYW1lID0gV1BfQ0xJX1JPT1QgLiAiL3RlbXBsYXRlcy8kdGVtcGxhdGVfbmFtZSI7Cgl9CgoJJHRlbXBsYXRlID0gZmlsZV9nZXRfY29udGVudHMoICR0ZW1wbGF0ZV9uYW1lICk7CgoJJG11c3RhY2hlID0gbmV3IE11c3RhY2hlX0VuZ2luZSgKCQlbCgkJCSdlc2NhcGUnID0+IGZ1bmN0aW9uICggJHZhbCApIHsKCQkJCXJldHVybiAkdmFsOyB9LAoJCV0KCSk7CgoJcmV0dXJuICRtdXN0YWNoZS0+cmVuZGVyKCAkdGVtcGxhdGUsICRkYXRhICk7Cn0KCi8qKgogKiBDcmVhdGUgYSBwcm9ncmVzcyBiYXIgdG8gZGlzcGxheSBwZXJjZW50IGNvbXBsZXRpb24gb2YgYSBnaXZlbiBvcGVyYXRpb24uCiAqCiAqIFByb2dyZXNzIGJhciBpcyB3cml0dGVuIHRvIFNURE9VVCwgYW5kIGRpc2FibGVkIHdoZW4gY29tbWFuZCBpcyBwaXBlZC4gUHJvZ3Jlc3MKICogYWR2YW5jZXMgd2l0aCBgJHByb2dyZXNzLT50aWNrKClgLCBhbmQgY29tcGxldGVzIHdpdGggYCRwcm9ncmVzcy0+ZmluaXNoKClgLgogKiBQcm9jZXNzIGJhciBhbHNvIGluZGljYXRlcyBlbGFwc2VkIHRpbWUgYW5kIGV4cGVjdGVkIHRvdGFsIHRpbWUuCiAqCiAqIGBgYAogKiAjIGB3cCB1c2VyIGdlbmVyYXRlYCB0aWNrcyBwcm9ncmVzcyBiYXIgZWFjaCB0aW1lIGEgbmV3IHVzZXIgaXMgY3JlYXRlZC4KICogIwogKiAjICQgd3AgdXNlciBnZW5lcmF0ZSAtLWNvdW50PTUwMAogKiAjIEdlbmVyYXRpbmcgdXNlcnMgIDIyICUgWz09PT09PT0+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdIDA6MDUgLyAwOjIzCiAqCiAqICRwcm9ncmVzcyA9IFxXUF9DTElcVXRpbHNcbWFrZV9wcm9ncmVzc19iYXIoICdHZW5lcmF0aW5nIHVzZXJzJywgJGNvdW50ICk7CiAqIGZvciAoICRpID0gMDsgJGkgPCAkY291bnQ7ICRpKysgKSB7CiAqICAgICAvLyB1c2VzIHdwX2luc2VydF91c2VyKCkgdG8gaW5zZXJ0IHRoZSB1c2VyCiAqICAgICAkcHJvZ3Jlc3MtPnRpY2soKTsKICogfQogKiAkcHJvZ3Jlc3MtPmZpbmlzaCgpOwogKiBgYGAKICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IE91dHB1dAogKgogKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZSAgVGV4dCB0byBkaXNwbGF5IGJlZm9yZSB0aGUgcHJvZ3Jlc3MgYmFyLgogKiBAcGFyYW0gaW50ZWdlciAkY291bnQgICAgVG90YWwgbnVtYmVyIG9mIHRpY2tzIHRvIGJlIHBlcmZvcm1lZC4KICogQHBhcmFtIGludCAgICAgJGludGVydmFsIE9wdGlvbmFsLiBUaGUgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gdXBkYXRlcy4gRGVmYXVsdCAxMDAuCiAqIEByZXR1cm4gY2xpXHByb2dyZXNzXEJhcnxOb09wCiAqLwpmdW5jdGlvbiBtYWtlX3Byb2dyZXNzX2JhciggJG1lc3NhZ2UsICRjb3VudCwgJGludGVydmFsID0gMTAwICkgewoJaWYgKCBTaGVsbDo6aXNQaXBlZCgpICkgewoJCXJldHVybiBuZXcgTm9PcCgpOwoJfQoKCXJldHVybiBuZXcgQmFyKCAkbWVzc2FnZSwgJGNvdW50LCAkaW50ZXJ2YWwgKTsKfQoKLyoqCiAqIEhlbHBlciBmdW5jdGlvbiB0byB1c2Ugd3BfcGFyc2VfdXJsIHdoZW4gYXZhaWxhYmxlIG9yIGZhbGwgYmFjayB0byBQSFAncwogKiBwYXJzZV91cmwgaWYgbm90LgogKgogKiBBZGRpdGlvbmFsbHksIHRoaXMgYWRkcyAnaHR0cDovLycgdG8gdGhlIFVSTCBpZiBubyBzY2hlbWUgd2FzIGZvdW5kLgogKgogKiBAcGFyYW0gc3RyaW5nICR1cmwgICAgICAgICAgICAgVGhlIFVSTCB0byBwYXJzZS4KICogQHBhcmFtIGludCAgICAkY29tcG9uZW50ICAgICAgIE9wdGlvbmFsLiBUaGUgc3BlY2lmaWMgY29tcG9uZW50IHRvIHJldHJpZXZlLgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNlIG9uZSBvZiB0aGUgUEhQIHByZWRlZmluZWQgY29uc3RhbnRzIHRvCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZ5IHdoaWNoIG9uZS4gRGVmYXVsdHMgdG8gLTEgKD0gcmV0dXJuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGwgcGFydHMgYXMgYW4gYXJyYXkpLgogKiBAcGFyYW0gYm9vbCAgICRhdXRvX2FkZF9zY2hlbWUgT3B0aW9uYWwuIEF1dG9tYXRpY2FsbHkgYWRkIGFuIGh0dHA6Ly8gc2NoZW1lIGlmCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub25lIHdhcyBmb3VuZC4gRGVmYXVsdHMgdG8gdHJ1ZS4KICogQHJldHVybiBtaXhlZCBGYWxzZSBvbiBwYXJzZSBmYWlsdXJlOyBBcnJheSBvZiBVUkwgY29tcG9uZW50cyBvbiBzdWNjZXNzOwogKiAgICAgICAgICAgICAgIFdoZW4gYSBzcGVjaWZpYyBjb21wb25lbnQgaGFzIGJlZW4gcmVxdWVzdGVkOiBudWxsIGlmIHRoZQogKiAgICAgICAgICAgICAgIGNvbXBvbmVudCBkb2Vzbid0IGV4aXN0IGluIHRoZSBnaXZlbiBVUkw7IGEgc3RyaW5nIG9yIC0gaW4gdGhlCiAqICAgICAgICAgICAgICAgY2FzZSBvZiBQSFBfVVJMX1BPUlQgLSBpbnRlZ2VyIHdoZW4gaXQgZG9lcy4gU2VlIHBhcnNlX3VybCgpJ3MKICogICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzLgogKi8KZnVuY3Rpb24gcGFyc2VfdXJsKCAkdXJsLCAkY29tcG9uZW50ID0gLSAxLCAkYXV0b19hZGRfc2NoZW1lID0gdHJ1ZSApIHsKCWlmICgKCQlmdW5jdGlvbl9leGlzdHMoICd3cF9wYXJzZV91cmwnICkKCQkmJiAoCgkJCS0xID09PSAkY29tcG9uZW50CgkJCXx8IHdwX3ZlcnNpb25fY29tcGFyZSggJzQuNycsICc+PScgKQoJCSkKCSkgewoJCSR1cmxfcGFydHMgPSB3cF9wYXJzZV91cmwoICR1cmwsICRjb21wb25lbnQgKTsKCX0gZWxzZSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5wYXJzZV91cmxfcGFyc2VfdXJsIC0tIEZhbGxiYWNrLgoJCSR1cmxfcGFydHMgPSBccGFyc2VfdXJsKCAkdXJsLCAkY29tcG9uZW50ICk7Cgl9CgoJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5wYXJzZV91cmxfcGFyc2VfdXJsIC0tIE93biB2ZXJzaW9uIGJhc2VkIG9uIFdQIG9uZS4KCWlmICggJGF1dG9fYWRkX3NjaGVtZSAmJiAhIHBhcnNlX3VybCggJHVybCwgUEhQX1VSTF9TQ0hFTUUsIGZhbHNlICkgKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5wYXJzZV91cmxfcGFyc2VfdXJsIC0tIE93biB2ZXJzaW9uIGJhc2VkIG9uIFdQIG9uZS4KCQkkdXJsX3BhcnRzID0gcGFyc2VfdXJsKCAnaHR0cDovLycgLiAkdXJsLCAkY29tcG9uZW50LCBmYWxzZSApOwoJfQoKCXJldHVybiAkdXJsX3BhcnRzOwp9CgovKioKICogQ2hlY2sgaWYgd2UncmUgcnVubmluZyBpbiBhIFdpbmRvd3MgZW52aXJvbm1lbnQgKGNtZC5leGUpLgogKgogKiBAcmV0dXJuIGJvb2wKICovCmZ1bmN0aW9uIGlzX3dpbmRvd3MoKSB7CgkkdGVzdF9pc193aW5kb3dzID0gZ2V0ZW52KCAnV1BfQ0xJX1RFU1RfSVNfV0lORE9XUycgKTsKCXJldHVybiBmYWxzZSAhPT0gJHRlc3RfaXNfd2luZG93cyA/IChib29sKSAkdGVzdF9pc193aW5kb3dzIDogc3RydG91cHBlciggc3Vic3RyKCBQSFBfT1MsIDAsIDMgKSApID09PSAnV0lOJzsKfQoKLyoqCiAqIFJlcGxhY2UgbWFnaWMgY29uc3RhbnRzIGluIHNvbWUgUEhQIHNvdXJjZSBjb2RlLgogKgogKiBSZXBsYWNlcyB0aGUgX19GSUxFX18gYW5kIF9fRElSX18gbWFnaWMgY29uc3RhbnRzIHdpdGggdGhlIHZhbHVlcyB0aGV5IGFyZQogKiBzdXBwb3NlZCB0byByZXByZXNlbnQgYXQgcnVudGltZS4KICoKICogQHBhcmFtIHN0cmluZyAkc291cmNlIFRoZSBQSFAgY29kZSB0byBtYW5pcHVsYXRlLgogKiBAcGFyYW0gc3RyaW5nICRwYXRoIFRoZSBwYXRoIHRvIHVzZSBpbnN0ZWFkIG9mIHRoZSBtYWdpYyBjb25zdGFudHMuCiAqIEByZXR1cm4gc3RyaW5nIEFkYXB0ZWQgUEhQIGNvZGUuCiAqLwpmdW5jdGlvbiByZXBsYWNlX3BhdGhfY29uc3RzKCAkc291cmNlLCAkcGF0aCApIHsKCS8vIFNvbHZlIGlzc3VlIHdpdGggV2luZG93cyBhbGxvd2luZyBzaW5nbGUgcXVvdGVzIGluIGFjY291bnQgbmFtZXMuCgkkZmlsZSA9IGFkZHNsYXNoZXMoICRwYXRoICk7CgoJaWYgKCBmaWxlX2V4aXN0cyggJGZpbGUgKSApIHsKCQkkZmlsZSA9IHJlYWxwYXRoKCAkZmlsZSApOwoJfQoKCSRkaXIgPSBkaXJuYW1lKCAkZmlsZSApOwoKCS8vIFJlcGxhY2UgX19GSUxFX18gYW5kIF9fRElSX18gY29uc3RhbnRzIHdpdGggdmFsdWUgb2YgJGZpbGUgb3IgJGRpci4KCXJldHVybiBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCgkJRklMRV9ESVJfUEFUVEVSTiwKCQlzdGF0aWMgZnVuY3Rpb24gKCAkbWF0Y2hlcyApIHVzZSAoICRmaWxlLCAkZGlyICkgewoJCQlpZiAoICEgZW1wdHkoICRtYXRjaGVzWydmaWxlJ10gKSApIHsKCQkJCXJldHVybiAiJ3skZmlsZX0nIjsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkbWF0Y2hlc1snZGlyJ10gKSApIHsKCQkJCXJldHVybiAiJ3skZGlyfSciOwoJCQl9CgoJCQlyZXR1cm4gJG1hdGNoZXNbMF07CgkJfSwKCQkkc291cmNlCgkpOwp9CgovKioKICogTWFrZSBhIEhUVFAgcmVxdWVzdCB0byBhIHJlbW90ZSBVUkwuCiAqCiAqIFdyYXBzIHRoZSBSZXF1ZXN0cyBIVFRQIGxpYnJhcnkgdG8gZW5zdXJlIGV2ZXJ5IHJlcXVlc3QgaW5jbHVkZXMgYSBjZXJ0LgogKgogKiBgYGAKICogIyBgd3AgY29yZSBkb3dubG9hZGAgdmVyaWZpZXMgdGhlIGhhc2ggZm9yIGEgZG93bmxvYWRlZCBXb3JkUHJlc3MgYXJjaGl2ZQogKgogKiAkbWQ1X3Jlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJGRvd25sb2FkX3VybCAuICcubWQ1JyApOwogKiBpZiAoIDIwICE9IHN1YnN0ciggJG1kNV9yZXNwb25zZS0+c3RhdHVzX2NvZGUsIDAsIDIgKSApIHsKICogICAgICBXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgYWNjZXNzIG1kNSBoYXNoIGZvciByZWxlYXNlIChIVFRQIGNvZGUgeyRyZXNwb25zZS0+c3RhdHVzX2NvZGV9KSIgKTsKICogfQogKiBgYGAKICoKICogQGFjY2VzcyBwdWJsaWMKICoKICogQHBhcmFtIHN0cmluZyAkbWV0aG9kICBIVFRQIG1ldGhvZCAoR0VULCBQT1NULCBERUxFVEUsIGV0Yy4pLgogKiBAcGFyYW0gc3RyaW5nICR1cmwgICAgIFVSTCB0byBtYWtlIHRoZSBIVFRQIHJlcXVlc3QgdG8uCiAqIEBwYXJhbSBhcnJheSAgJGhlYWRlcnMgQWRkIHNwZWNpZmljIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3QuCiAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgewogKiAgICAgT3B0aW9uYWwuIEFuIGFzc29jaWF0aXZlIGFycmF5IG9mIGFkZGl0aW9uYWwgcmVxdWVzdCBvcHRpb25zLgogKgogKiAgICAgQHR5cGUgYm9vbCAkaGFsdF9vbl9lcnJvciBXaGV0aGVyIG9yIG5vdCBjb21tYW5kIGV4ZWN1dGlvbiBzaG91bGQgYmUgaGFsdGVkIG9uIGVycm9yLiBEZWZhdWx0OiB0cnVlCiAqICAgICBAdHlwZSBib29sfHN0cmluZyAkdmVyaWZ5IEEgYm9vbGVhbiB0byB1c2UgZW5hYmxlL2Rpc2FibGUgU1NMIHZlcmlmaWNhdGlvbgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBzdHJpbmcgYWJzb2x1dGUgcGF0aCB0byBDQSBjZXJ0IHRvIHVzZS4KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gZGV0ZWN0ZWQgQ0EgY2VydCBidW5kbGVkIHdpdGggdGhlIFJlcXVlc3RzIGxpYnJhcnkuCiAqICAgICBAdHlwZSBib29sICRpbnNlY3VyZSAgICAgIFdoZXRoZXIgdG8gcmV0cnkgYXV0b21hdGljYWxseSB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24uCiAqIH0KICogQHJldHVybiBvYmplY3QKICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZXF1ZXN0IGZhaWxlZC4KICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIHRoZSByZXF1ZXN0IGZhaWxlZCBhbmQgJGhhbHRfb25fZXJyb3IgaXMgdHJ1ZS4KICovCmZ1bmN0aW9uIGh0dHBfcmVxdWVzdCggJG1ldGhvZCwgJHVybCwgJGRhdGEgPSBudWxsLCAkaGVhZGVycyA9IFtdLCAkb3B0aW9ucyA9IFtdICkgewoKCWlmICggISBjbGFzc19leGlzdHMoICdSZXF1ZXN0c19Ib29rcycgKSApIHsKCQkvLyBBdXRvbG9hZGVyIGZvciB0aGUgUmVxdWVzdHMgbGlicmFyeSBoYXMgbm90IGJlZW4gcmVnaXN0ZXJlZCB5ZXQuCgkJUmVxdWVzdHM6OnJlZ2lzdGVyX2F1dG9sb2FkZXIoKTsKCX0KCgkkaW5zZWN1cmUgICAgICA9IGlzc2V0KCAkb3B0aW9uc1snaW5zZWN1cmUnXSApICYmIChib29sKSAkb3B0aW9uc1snaW5zZWN1cmUnXTsKCSRoYWx0X29uX2Vycm9yID0gISBpc3NldCggJG9wdGlvbnNbJ2hhbHRfb25fZXJyb3InXSApIHx8IChib29sKSAkb3B0aW9uc1snaGFsdF9vbl9lcnJvciddOwoJdW5zZXQoICRvcHRpb25zWydoYWx0X29uX2Vycm9yJ10gKTsKCglpZiAoICEgaXNzZXQoICRvcHRpb25zWyd2ZXJpZnknXSApICkgewoJCS8vICdjdXJsLmNhaW5mbycgZW5mb3JjZXMgdGhlIENBIGZpbGUgdG8gdXNlLCBvdGhlcndpc2UgZmFsbGJhY2sgdG8gc3lzdGVtLXdpZGUgZGVmYXVsdHMgdGhlbiB1c2UgdGhlIGVtYmVkZGVkIENBIGZpbGUuCgkJJG9wdGlvbnNbJ3ZlcmlmeSddID0gISBlbXB0eSggaW5pX2dldCggJ2N1cmwuY2FpbmZvJyApICkgPyBpbmlfZ2V0KCAnY3VybC5jYWluZm8nICkgOiB0cnVlOwoJfQoKCXRyeSB7CgkJdHJ5IHsKCQkJcmV0dXJuIFJlcXVlc3RzOjpyZXF1ZXN0KCAkdXJsLCAkaGVhZGVycywgJGRhdGEsICRtZXRob2QsICRvcHRpb25zICk7CgkJfSBjYXRjaCAoIFJlcXVlc3RzX0V4Y2VwdGlvbiAkZXggKSB7CgkJCWlmICggdHJ1ZSAhPT0gJG9wdGlvbnNbJ3ZlcmlmeSddIHx8ICdjdXJsZXJyb3InICE9PSAkZXgtPmdldFR5cGUoKSB8fCBjdXJsX2Vycm5vKCAkZXgtPmdldERhdGEoKSApICE9PSBDVVJMRV9TU0xfQ0FDRVJUICkgewoJCQkJdGhyb3cgJGV4OwoJCQl9CgoJCQkkb3B0aW9uc1sndmVyaWZ5J10gPSBnZXRfZGVmYXVsdF9jYWNlcnQoICRoYWx0X29uX2Vycm9yICk7CgoJCQlyZXR1cm4gUmVxdWVzdHM6OnJlcXVlc3QoICR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG1ldGhvZCwgJG9wdGlvbnMgKTsKCQl9Cgl9IGNhdGNoICggUmVxdWVzdHNfRXhjZXB0aW9uICRleCApIHsKCQkvLyBDVVJMRV9TU0xfQ0FDRVJUX0JBREZJTEUgb25seSBkZWZpbmVkIGZvciBQSFAgPj0gNy4KCQlpZiAoCgkJCSEgJGluc2VjdXJlCgkJCXx8CgkJCSdjdXJsZXJyb3InICE9PSAkZXgtPmdldFR5cGUoKQoJCQl8fAoJCQkhIGluX2FycmF5KCBjdXJsX2Vycm5vKCAkZXgtPmdldERhdGEoKSApLCBbIENVUkxFX1NTTF9DT05ORUNUX0VSUk9SLCBDVVJMRV9TU0xfQ0VSVFBST0JMRU0sIDc3IC8qQ1VSTEVfU1NMX0NBQ0VSVF9CQURGSUxFKi8gXSwgdHJ1ZSApCgkJKSB7CgkJCSRlcnJvcl9tc2cgPSBzcHJpbnRmKCAiRmFpbGVkIHRvIGdldCB1cmwgJyVzJzogJXMuIiwgJHVybCwgJGV4LT5nZXRNZXNzYWdlKCkgKTsKCQkJaWYgKCAkaGFsdF9vbl9lcnJvciApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRlcnJvcl9tc2cgKTsKCQkJfQoJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbiggJGVycm9yX21zZywgbnVsbCwgJGV4ICk7CgkJfQoKCQkkd2FybmluZyA9IHNwcmludGYoCgkJCSJSZS10cnlpbmcgd2l0aG91dCB2ZXJpZnkgYWZ0ZXIgZmFpbGluZyB0byBnZXQgdmVyaWZpZWQgdXJsICclcycgJXMuIiwKCQkJJHVybCwKCQkJJGV4LT5nZXRNZXNzYWdlKCkKCQkpOwoJCVdQX0NMSTo6d2FybmluZyggJHdhcm5pbmcgKTsKCgkJLy8gRGlzYWJsZSBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGZvciB0aGUgbmV4dCB0cnkuCgkJJG9wdGlvbnNbJ3ZlcmlmeSddID0gZmFsc2U7CgoJCXRyeSB7CgkJCXJldHVybiBSZXF1ZXN0czo6cmVxdWVzdCggJHVybCwgJGhlYWRlcnMsICRkYXRhLCAkbWV0aG9kLCAkb3B0aW9ucyApOwoJCX0gY2F0Y2ggKCBSZXF1ZXN0c19FeGNlcHRpb24gJGV4ICkgewoJCQkkZXJyb3JfbXNnID0gc3ByaW50ZiggIkZhaWxlZCB0byBnZXQgbm9uLXZlcmlmaWVkIHVybCAnJXMnICVzLiIsICR1cmwsICRleC0+Z2V0TWVzc2FnZSgpICk7CgkJCWlmICggJGhhbHRfb25fZXJyb3IgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAkZXJyb3JfbXNnICk7CgkJCX0KCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oICRlcnJvcl9tc2csIG51bGwsICRleCApOwoJCX0KCX0KfQoKLyoqCiAqIEdldHMgdGhlIGZ1bGwgcGF0aCB0byB0aGUgZGVmYXVsdCBDQSBjZXJ0LgogKgogKiBAcGFyYW0gYm9vbCAkaGFsdF9vbl9lcnJvciBXaGV0aGVyIG9yIG5vdCBjb21tYW5kIGV4ZWN1dGlvbiBzaG91bGQgYmUgaGFsdGVkIG9uIGVycm9yLiBEZWZhdWx0OiBmYWxzZQogKiBAcmV0dXJuIHN0cmluZyBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBkZWZhdWx0IENBIGNlcnQuCiAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB1bmFibGUgdG8gbG9jYXRlIHRoZSBjZXJ0LgogKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdW5hYmxlIHRvIGxvY2F0ZSB0aGUgY2VydCBhbmQgJGhhbHRfb25fZXJyb3IgaXMgdHJ1ZS4KICovCmZ1bmN0aW9uIGdldF9kZWZhdWx0X2NhY2VydCggJGhhbHRfb25fZXJyb3IgPSBmYWxzZSApIHsKCSRjZXJ0X3BhdGggPSAnL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1RyYW5zcG9ydC9jYWNlcnQucGVtJzsKCSRlcnJvcl9tc2cgPSAnQ2Fubm90IGZpbmQgU1NMIGNlcnRpZmljYXRlLic7CgoJaWYgKCBpbnNpZGVfcGhhcigpICkgewoJCS8vIGNVUkwgY2FuJ3QgcmVhZCBQaGFyIGFyY2hpdmVzCgkJcmV0dXJuIGV4dHJhY3RfZnJvbV9waGFyKCBXUF9DTElfVkVORE9SX0RJUiAuICRjZXJ0X3BhdGggKTsKCX0KCglmb3JlYWNoICggZ2V0X3ZlbmRvcl9wYXRocygpIGFzICR2ZW5kb3JfcGF0aCApIHsKCQlpZiAoIGZpbGVfZXhpc3RzKCAkdmVuZG9yX3BhdGggLiAkY2VydF9wYXRoICkgKSB7CgkJCXJldHVybiAkdmVuZG9yX3BhdGggLiAkY2VydF9wYXRoOwoJCX0KCX0KCglpZiAoICRoYWx0X29uX2Vycm9yICkgewoJCVdQX0NMSTo6ZXJyb3IoICRlcnJvcl9tc2cgKTsKCX0KCgl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbiggJGVycm9yX21zZyApOwp9CgovKioKICogSW5jcmVtZW50cyBhIHZlcnNpb24gc3RyaW5nIHVzaW5nIHRoZSAieC55LnotcHJlIiBmb3JtYXQuCiAqCiAqIENhbiBpbmNyZW1lbnQgdGhlIG1ham9yLCBtaW5vciBvciBwYXRjaCBudW1iZXIgYnkgb25lLgogKiBJZiAkbmV3X3ZlcnNpb24gPT0gInNhbWUiIHRoZSB2ZXJzaW9uIHN0cmluZyBpcyBub3QgY2hhbmdlZC4KICogSWYgJG5ld192ZXJzaW9uIGlzIG5vdCBhIGtub3duIGtleXdvcmQsIGl0IHdpbGwgYmUgdXNlZCBhcyB0aGUgbmV3IHZlcnNpb24gc3RyaW5nIGRpcmVjdGx5LgogKgogKiBAcGFyYW0gc3RyaW5nICRjdXJyZW50X3ZlcnNpb24KICogQHBhcmFtIHN0cmluZyAkbmV3X3ZlcnNpb24KICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGluY3JlbWVudF92ZXJzaW9uKCAkY3VycmVudF92ZXJzaW9uLCAkbmV3X3ZlcnNpb24gKSB7CgkvLyBzcGxpdCB2ZXJzaW9uIGFzc3VtaW5nIHRoZSBmb3JtYXQgaXMgeC55LnotcHJlCgkkY3VycmVudF92ZXJzaW9uICAgID0gZXhwbG9kZSggJy0nLCAkY3VycmVudF92ZXJzaW9uLCAyICk7CgkkY3VycmVudF92ZXJzaW9uWzBdID0gZXhwbG9kZSggJy4nLCAkY3VycmVudF92ZXJzaW9uWzBdICk7CgoJc3dpdGNoICggJG5ld192ZXJzaW9uICkgewoJCWNhc2UgJ3NhbWUnOgoJCQkvLyBkbyBub3RoaW5nCgkJCWJyZWFrOwoKCQljYXNlICdwYXRjaCc6CgkJCSRjdXJyZW50X3ZlcnNpb25bMF1bMl0rKzsKCgkJCSRjdXJyZW50X3ZlcnNpb24gPSBbICRjdXJyZW50X3ZlcnNpb25bMF0gXTsgLy8gRHJvcCBwb3NzaWJsZSBwcmUtcmVsZWFzZSBpbmZvLgoJCQlicmVhazsKCgkJY2FzZSAnbWlub3InOgoJCQkkY3VycmVudF92ZXJzaW9uWzBdWzFdKys7CgkJCSRjdXJyZW50X3ZlcnNpb25bMF1bMl0gPSAwOwoKCQkJJGN1cnJlbnRfdmVyc2lvbiA9IFsgJGN1cnJlbnRfdmVyc2lvblswXSBdOyAvLyBEcm9wIHBvc3NpYmxlIHByZS1yZWxlYXNlIGluZm8uCgkJCWJyZWFrOwoKCQljYXNlICdtYWpvcic6CgkJCSRjdXJyZW50X3ZlcnNpb25bMF1bMF0rKzsKCQkJJGN1cnJlbnRfdmVyc2lvblswXVsxXSA9IDA7CgkJCSRjdXJyZW50X3ZlcnNpb25bMF1bMl0gPSAwOwoKCQkJJGN1cnJlbnRfdmVyc2lvbiA9IFsgJGN1cnJlbnRfdmVyc2lvblswXSBdOyAvLyBEcm9wIHBvc3NpYmxlIHByZS1yZWxlYXNlIGluZm8uCgkJCWJyZWFrOwoKCQlkZWZhdWx0OiAvLyBub3QgYSBrZXl3b3JkCgkJCSRjdXJyZW50X3ZlcnNpb24gPSBbIFsgJG5ld192ZXJzaW9uIF0gXTsKCQkJYnJlYWs7Cgl9CgoJLy8gUmVjb25zdHJ1Y3QgdmVyc2lvbiBzdHJpbmcuCgkkY3VycmVudF92ZXJzaW9uWzBdID0gaW1wbG9kZSggJy4nLCAkY3VycmVudF92ZXJzaW9uWzBdICk7CgkkY3VycmVudF92ZXJzaW9uICAgID0gaW1wbG9kZSggJy0nLCAkY3VycmVudF92ZXJzaW9uICk7CgoJcmV0dXJuICRjdXJyZW50X3ZlcnNpb247Cn0KCi8qKgogKiBDb21wYXJlIHR3byB2ZXJzaW9uIHN0cmluZ3MgdG8gZ2V0IHRoZSBuYW1lZCBzZW1hbnRpYyB2ZXJzaW9uLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKgogKiBAcGFyYW0gc3RyaW5nICRuZXdfdmVyc2lvbgogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbF92ZXJzaW9uCiAqIEByZXR1cm4gc3RyaW5nICdtYWpvcicsICdtaW5vcicsICdwYXRjaCcKICovCmZ1bmN0aW9uIGdldF9uYW1lZF9zZW1fdmVyKCAkbmV3X3ZlcnNpb24sICRvcmlnaW5hbF92ZXJzaW9uICkgewoKCWlmICggISBDb21wYXJhdG9yOjpncmVhdGVyVGhhbiggJG5ld192ZXJzaW9uLCAkb3JpZ2luYWxfdmVyc2lvbiApICkgewoJCXJldHVybiAnJzsKCX0KCgkkcGFydHMgPSBleHBsb2RlKCAnLScsICRvcmlnaW5hbF92ZXJzaW9uICk7CgkkYml0cyAgPSBleHBsb2RlKCAnLicsICRwYXJ0c1swXSApOwoJJG1ham9yID0gJGJpdHNbMF07CglpZiAoIGlzc2V0KCAkYml0c1sxXSApICkgewoJCSRtaW5vciA9ICRiaXRzWzFdOwoJfQoJaWYgKCBpc3NldCggJGJpdHNbMl0gKSApIHsKCQkkcGF0Y2ggPSAkYml0c1syXTsKCX0KCglpZiAoIGlzc2V0KCAkbWlub3IgKSAmJiBTZW12ZXI6OnNhdGlzZmllcyggJG5ld192ZXJzaW9uLCAieyRtYWpvcn0ueyRtaW5vcn0ueCIgKSApIHsKCQlyZXR1cm4gJ3BhdGNoJzsKCX0KCglpZiAoIFNlbXZlcjo6c2F0aXNmaWVzKCAkbmV3X3ZlcnNpb24sICJ7JG1ham9yfS54LngiICkgKSB7CgkJcmV0dXJuICdtaW5vcic7Cgl9CgoJcmV0dXJuICdtYWpvcic7Cn0KCi8qKgogKiBSZXR1cm4gdGhlIGZsYWcgdmFsdWUgb3IsIGlmIGl0J3Mgbm90IHNldCwgdGhlICRkZWZhdWx0IHZhbHVlLgogKgogKiBCZWNhdXNlIGZsYWdzIGNhbiBiZSBuZWdhdGVkIChlLmcuIC0tbm8tcXVpZXQgdG8gbmVnYXRlIC0tcXVpZXQpLCB0aGlzCiAqIGZ1bmN0aW9uIHByb3ZpZGVzIGEgc2FmZXIgYWx0ZXJuYXRpdmUgdG8gdXNpbmcKICogYGlzc2V0KCAkYXNzb2NfYXJnc1sncXVpZXQnXSApYCBvciBzaW1pbGFyLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgSW5wdXQKICoKICogQHBhcmFtIGFycmF5ICAkYXNzb2NfYXJncyBBcmd1bWVudHMgYXJyYXkuCiAqIEBwYXJhbSBzdHJpbmcgJGZsYWcgICAgICAgRmxhZyB0byBnZXQgdGhlIHZhbHVlLgogKiBAcGFyYW0gbWl4ZWQgICRkZWZhdWx0ICAgIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBmbGFnLiBEZWZhdWx0OiBOVUxMLgogKiBAcmV0dXJuIG1peGVkCiAqLwpmdW5jdGlvbiBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICRmbGFnLCAkZGVmYXVsdCA9IG51bGwgKSB7CglyZXR1cm4gaXNzZXQoICRhc3NvY19hcmdzWyAkZmxhZyBdICkgPyAkYXNzb2NfYXJnc1sgJGZsYWcgXSA6ICRkZWZhdWx0Owp9CgovKioKICogR2V0IHRoZSBob21lIGRpcmVjdG9yeS4KICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IFN5c3RlbQogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gZ2V0X2hvbWVfZGlyKCkgewoJJGhvbWUgPSBnZXRlbnYoICdIT01FJyApOwoJaWYgKCAhICRob21lICkgewoJCS8vIEluIFdpbmRvd3MgJEhPTUUgbWF5IG5vdCBiZSBkZWZpbmVkCgkJJGhvbWUgPSBnZXRlbnYoICdIT01FRFJJVkUnICkgLiBnZXRlbnYoICdIT01FUEFUSCcgKTsKCX0KCglyZXR1cm4gcnRyaW0oICRob21lLCAnL1xcJyApOwp9CgovKioKICogQXBwZW5kcyBhIHRyYWlsaW5nIHNsYXNoLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgU3lzdGVtCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBXaGF0IHRvIGFkZCB0aGUgdHJhaWxpbmcgc2xhc2ggdG8uCiAqIEByZXR1cm4gc3RyaW5nIFN0cmluZyB3aXRoIHRyYWlsaW5nIHNsYXNoIGFkZGVkLgogKi8KZnVuY3Rpb24gdHJhaWxpbmdzbGFzaGl0KCAkc3RyaW5nICkgewoJcmV0dXJuIHJ0cmltKCAkc3RyaW5nLCAnL1xcJyApIC4gJy8nOwp9CgovKioKICogTm9ybWFsaXplIGEgZmlsZXN5c3RlbSBwYXRoLgogKgogKiBPbiBXaW5kb3dzIHN5c3RlbXMsIHJlcGxhY2VzIGJhY2tzbGFzaGVzIHdpdGggZm9yd2FyZCBzbGFzaGVzCiAqIGFuZCBmb3JjZXMgdXBwZXItY2FzZSBkcml2ZSBsZXR0ZXJzLgogKiBBbGxvd3MgZm9yIHR3byBsZWFkaW5nIHNsYXNoZXMgZm9yIFdpbmRvd3MgbmV0d29yayBzaGFyZXMsIGJ1dAogKiBlbnN1cmVzIHRoYXQgYWxsIG90aGVyIGR1cGxpY2F0ZSBzbGFzaGVzIGFyZSByZWR1Y2VkIHRvIGEgc2luZ2xlIG9uZS4KICogRW5zdXJlcyB1cHBlci1jYXNlIGRyaXZlIGxldHRlcnMgb24gV2luZG93cyBzeXN0ZW1zLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgU3lzdGVtCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byBub3JtYWxpemUuCiAqIEByZXR1cm4gc3RyaW5nIE5vcm1hbGl6ZWQgcGF0aC4KICovCmZ1bmN0aW9uIG5vcm1hbGl6ZV9wYXRoKCAkcGF0aCApIHsKCSRwYXRoID0gc3RyX3JlcGxhY2UoICdcXCcsICcvJywgJHBhdGggKTsKCSRwYXRoID0gcHJlZ19yZXBsYWNlKCAnfCg/PD0uKS8rfCcsICcvJywgJHBhdGggKTsKCWlmICggJzonID09PSBzdWJzdHIoICRwYXRoLCAxLCAxICkgKSB7CgkJJHBhdGggPSB1Y2ZpcnN0KCAkcGF0aCApOwoJfQoJcmV0dXJuICRwYXRoOwp9CgoKLyoqCiAqIENvbnZlcnQgV2luZG93cyBFT0xzIHRvICpuaXguCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHN0ciBTdHJpbmcgdG8gY29udmVydC4KICogQHJldHVybiBzdHJpbmcgU3RyaW5nIHdpdGggY2FycmlhZ2UgcmV0dXJuIC8gbmV3bGluZSBwYWlycyByZWR1Y2VkIHRvIG5ld2xpbmVzLgogKi8KZnVuY3Rpb24gbm9ybWFsaXplX2VvbHMoICRzdHIgKSB7CglyZXR1cm4gc3RyX3JlcGxhY2UoICJcclxuIiwgIlxuIiwgJHN0ciApOwp9CgovKioKICogR2V0IHRoZSBzeXN0ZW0ncyB0ZW1wIGRpcmVjdG9yeS4gV2FybnMgdXNlciBpZiBpdCBpc24ndCB3cml0YWJsZS4KICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IFN5c3RlbQogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gZ2V0X3RlbXBfZGlyKCkgewoJc3RhdGljICR0ZW1wID0gJyc7CgoJaWYgKCAkdGVtcCApIHsKCQlyZXR1cm4gJHRlbXA7Cgl9CgoJLy8gYHN5c19nZXRfdGVtcF9kaXIoKWAgaW50cm9kdWNlZCBQSFAgNS4yLjEuIFdpbGwgYWx3YXlzIHJldHVybiBzb21ldGhpbmcuCgkkdGVtcCA9IHRyYWlsaW5nc2xhc2hpdCggc3lzX2dldF90ZW1wX2RpcigpICk7CgoJaWYgKCAhIGlzX3dyaXRhYmxlKCAkdGVtcCApICkgewoJCVdQX0NMSTo6d2FybmluZyggIlRlbXAgZGlyZWN0b3J5IGlzbid0IHdyaXRhYmxlOiB7JHRlbXB9IiApOwoJfQoKCXJldHVybiAkdGVtcDsKfQoKLyoqCiAqIFBhcnNlIGEgU1NIIHVybCBmb3IgaXRzIGhvc3QsIHBvcnQsIGFuZCBwYXRoLgogKgogKiBTaW1pbGFyIHRvIHBhcnNlX3VybCgpLCBidXQgYWRkcyBzdXBwb3J0IGZvciBkZWZpbmVkIFNTSCBhbGlhc2VzLgogKgogKiBgYGAKICogaG9zdCBPUiBob3N0L3BhdGgvdG8vd29yZHByZXNzIE9SIGhvc3Q6cG9ydC9wYXRoL3RvL3dvcmRwcmVzcwogKiBgYGAKICoKICogQGFjY2VzcyBwdWJsaWMKICoKICogQHJldHVybiBtaXhlZAogKi8KZnVuY3Rpb24gcGFyc2Vfc3NoX3VybCggJHVybCwgJGNvbXBvbmVudCA9IC0xICkgewoJcHJlZ19tYXRjaCggJyNeKChkb2NrZXJ8ZG9ja2VyXC1jb21wb3NlfHNzaHx2YWdyYW50KTopPygoW15AOl0rKUApPyhbXjovfl0rKSg6KFtcZF0qKSk/KCgvfH4pKC4rKSk/JCMnLCAkdXJsLCAkbWF0Y2hlcyApOwoJJGJpdHMgPSBbXTsKCWZvcmVhY2ggKCBbCgkJMiA9PiAnc2NoZW1lJywKCQk0ID0+ICd1c2VyJywKCQk1ID0+ICdob3N0JywKCQk3ID0+ICdwb3J0JywKCQk4ID0+ICdwYXRoJywKCV0gYXMgJGkgPT4gJGtleSApIHsKCQlpZiAoICEgZW1wdHkoICRtYXRjaGVzWyAkaSBdICkgKSB7CgkJCSRiaXRzWyAka2V5IF0gPSAkbWF0Y2hlc1sgJGkgXTsKCQl9Cgl9CgoJLy8gRmluZCB0aGUgaG9zdG5hbWUgZnJvbSBgdmFncmFudCBzc2gtY29uZmlnYCBhdXRvbWF0aWNhbGx5LgoJaWYgKCBwcmVnX21hdGNoKCAnL152YWdyYW50Oj8vJywgJHVybCApICkgewoJCWlmICggJ3ZhZ3JhbnQnID09PSAkYml0c1snaG9zdCddICYmIGVtcHR5KCAkYml0c1snc2NoZW1lJ10gKSApIHsKCQkJJGJpdHNbJ3NjaGVtZSddID0gJ3ZhZ3JhbnQnOwoJCQkkYml0c1snaG9zdCddICAgPSAnJzsKCQl9Cgl9CgoJc3dpdGNoICggJGNvbXBvbmVudCApIHsKCQljYXNlIFBIUF9VUkxfU0NIRU1FOgoJCQlyZXR1cm4gaXNzZXQoICRiaXRzWydzY2hlbWUnXSApID8gJGJpdHNbJ3NjaGVtZSddIDogbnVsbDsKCQljYXNlIFBIUF9VUkxfVVNFUjoKCQkJcmV0dXJuIGlzc2V0KCAkYml0c1sndXNlciddICkgPyAkYml0c1sndXNlciddIDogbnVsbDsKCQljYXNlIFBIUF9VUkxfSE9TVDoKCQkJcmV0dXJuIGlzc2V0KCAkYml0c1snaG9zdCddICkgPyAkYml0c1snaG9zdCddIDogbnVsbDsKCQljYXNlIFBIUF9VUkxfUEFUSDoKCQkJcmV0dXJuIGlzc2V0KCAkYml0c1sncGF0aCddICkgPyAkYml0c1sncGF0aCddIDogbnVsbDsKCQljYXNlIFBIUF9VUkxfUE9SVDoKCQkJcmV0dXJuIGlzc2V0KCAkYml0c1sncG9ydCddICkgPyAkYml0c1sncG9ydCddIDogbnVsbDsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gJGJpdHM7Cgl9Cn0KCi8qKgogKiBSZXBvcnQgdGhlIHJlc3VsdHMgb2YgdGhlIHNhbWUgb3BlcmF0aW9uIGFnYWluc3QgbXVsdGlwbGUgcmVzb3VyY2VzLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgSW5wdXQKICoKICogQHBhcmFtIHN0cmluZyAgICAgICAkbm91biAgICAgIFJlc291cmNlIGJlaW5nIGFmZmVjdGVkIChlLmcuIHBsdWdpbikuCiAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHZlcmIgICAgICBUeXBlIG9mIGFjdGlvbiBoYXBwZW5pbmcgdG8gdGhlIG5vdW4gKGUuZy4gYWN0aXZhdGUpLgogKiBAcGFyYW0gaW50ZWdlciAgICAgICR0b3RhbCAgICAgVG90YWwgbnVtYmVyIG9mIHJlc291cmNlIGJlaW5nIGFmZmVjdGVkLgogKiBAcGFyYW0gaW50ZWdlciAgICAgICRzdWNjZXNzZXMgTnVtYmVyIG9mIHN1Y2Nlc3NmdWwgb3BlcmF0aW9ucy4KICogQHBhcmFtIGludGVnZXIgICAgICAkZmFpbHVyZXMgIE51bWJlciBvZiBmYWlsdXJlcy4KICogQHBhcmFtIG51bGx8aW50ZWdlciAkc2tpcHMgICAgIE9wdGlvbmFsLiBOdW1iZXIgb2Ygc2tpcHBlZCBvcGVyYXRpb25zLiBEZWZhdWx0IG51bGwgKGRvbid0IHNob3cgc2tpcHMpLgogKi8KZnVuY3Rpb24gcmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAkbm91biwgJHZlcmIsICR0b3RhbCwgJHN1Y2Nlc3NlcywgJGZhaWx1cmVzLCAkc2tpcHMgPSBudWxsICkgewoJJHBsdXJhbF9ub3VuICAgICAgICAgICA9ICRub3VuIC4gJ3MnOwoJJHBhc3RfdGVuc2VfdmVyYiAgICAgICA9IHBhc3RfdGVuc2VfdmVyYiggJHZlcmIgKTsKCSRwYXN0X3RlbnNlX3ZlcmJfdXBwZXIgPSB1Y2ZpcnN0KCAkcGFzdF90ZW5zZV92ZXJiICk7CglpZiAoICRmYWlsdXJlcyApIHsKCQkkZmFpbGVkX3NraXBwZWRfbWVzc2FnZSA9IG51bGwgPT09ICRza2lwcyA/ICcnIDogIiAoeyRmYWlsdXJlc30gZmFpbGVkIiAuICggJHNraXBzID8gIiwgeyRza2lwc30gc2tpcHBlZCIgOiAnJyApIC4gJyknOwoJCWlmICggJHN1Y2Nlc3NlcyApIHsKCQkJV1BfQ0xJOjplcnJvciggIk9ubHkgeyRwYXN0X3RlbnNlX3ZlcmJ9IHskc3VjY2Vzc2VzfSBvZiB7JHRvdGFsfSB7JHBsdXJhbF9ub3VufXskZmFpbGVkX3NraXBwZWRfbWVzc2FnZX0uIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJObyB7JHBsdXJhbF9ub3VufSB7JHBhc3RfdGVuc2VfdmVyYn17JGZhaWxlZF9za2lwcGVkX21lc3NhZ2V9LiIgKTsKCQl9Cgl9IGVsc2UgewoJCSRza2lwcGVkX21lc3NhZ2UgPSAkc2tpcHMgPyAiICh7JHNraXBzfSBza2lwcGVkKSIgOiAnJzsKCQlpZiAoICRzdWNjZXNzZXMgfHwgJHNraXBzICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJ7JHBhc3RfdGVuc2VfdmVyYl91cHBlcn0geyRzdWNjZXNzZXN9IG9mIHskdG90YWx9IHskcGx1cmFsX25vdW59eyRza2lwcGVkX21lc3NhZ2V9LiIgKTsKCQl9IGVsc2UgewoJCQkkbWVzc2FnZSA9ICR0b3RhbCA+IDEgPyB1Y2ZpcnN0KCAkcGx1cmFsX25vdW4gKSA6IHVjZmlyc3QoICRub3VuICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggInskbWVzc2FnZX0gYWxyZWFkeSB7JHBhc3RfdGVuc2VfdmVyYn0uIiApOwoJCX0KCX0KfQoKLyoqCiAqIFBhcnNlIGEgc3RyaW5nIG9mIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgaW50byBhbiAkYXJndi1lc3FlIHZhcmlhYmxlLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgSW5wdXQKICoKICogQHBhcmFtIHN0cmluZyAkYXJndW1lbnRzCiAqIEByZXR1cm4gYXJyYXkKICovCmZ1bmN0aW9uIHBhcnNlX3N0cl90b19hcmd2KCAkYXJndW1lbnRzICkgewoJcHJlZ19tYXRjaF9hbGwoICcvKD86LS1bXlxzPV0rPShbIlwnXSkoKFxcezJ9KSp8KD86W15cMV0rP1teXFxcXF0oXFx7Mn0pKikpXDF8LS1bXlxzPV0rPVteXHNdK3wtLVteXHM9XSt8KFsiXCddKSgoXFx7Mn0pKnwoPzpbXlw1XSs/W15cXFxcXShcXHsyfSkqKSlcNXxbXlxzXSspLycsICRhcmd1bWVudHMsICRtYXRjaGVzICk7CgkkYXJndiA9IGlzc2V0KCAkbWF0Y2hlc1swXSApID8gJG1hdGNoZXNbMF0gOiBbXTsKCXJldHVybiBhcnJheV9tYXAoCgkJc3RhdGljIGZ1bmN0aW9uICggJGFyZyApIHsKCQkJZm9yZWFjaCAoIFsgJyInLCAiJyIgXSBhcyAkY2hhciApIHsKCQkJCWlmICggc3Vic3RyKCAkYXJnLCAwLCAxICkgPT09ICRjaGFyICYmIHN1YnN0ciggJGFyZywgLTEgKSA9PT0gJGNoYXIgKSB7CgkJCQkJJGFyZyA9IHN1YnN0ciggJGFyZywgMSwgLTEgKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQkJcmV0dXJuICRhcmc7CgkJfSwKCQkkYXJndgoJKTsKfQoKLyoqCiAqIExvY2FsZS1pbmRlcGVuZGVudCB2ZXJzaW9uIG9mIGJhc2VuYW1lKCkKICoKICogQGFjY2VzcyBwdWJsaWMKICoKICogQHBhcmFtIHN0cmluZyAkcGF0aAogKiBAcGFyYW0gc3RyaW5nICRzdWZmaXgKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGJhc2VuYW1lKCAkcGF0aCwgJHN1ZmZpeCA9ICcnICkgewoJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuRGlzY291cmFnZWRQSFBGdW5jdGlvbnMudXJsZW5jb2RlX3VybGVuY29kZSAtLSBGb3JtYXQgcmVxdWlyZWQgYnkgd29yZHByZXNzLm9yZyBBUEkuCglyZXR1cm4gdXJsZGVjb2RlKCBcYmFzZW5hbWUoIHN0cl9yZXBsYWNlKCBbICclMkYnLCAnJTVDJyBdLCAnLycsIHVybGVuY29kZSggJHBhdGggKSApLCAkc3VmZml4ICkgKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIHRoZSBvdXRwdXQgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGlzIGEgVFRZIG9yIGEgcGlwZSAvIHJlZGlyZWN0CiAqCiAqIFJldHVybnMgdHJ1ZSBpZiBTVERPVVQgb3V0cHV0IGlzIGJlaW5nIHJlZGlyZWN0ZWQgdG8gYSBwaXBlIG9yIGEgZmlsZTsgZmFsc2UgaXMKICogb3V0cHV0IGlzIGJlaW5nIHNlbnQgZGlyZWN0bHkgdG8gdGhlIHRlcm1pbmFsLgogKgogKiBJZiBhbiBlbnYgdmFyaWFibGUgU0hFTExfUElQRSBleGlzdHMsIHJldHVybmVkIHJlc3VsdCBkZXBlbmRzIG9uIGl0cwogKiB2YWx1ZS4gU3RyaW5ncyBsaWtlIDEsIDAsIHllcywgbm8sIHRoYXQgdmFsaWRhdGUgdG8gYm9vbGVhbnMgYXJlIGFjY2VwdGVkLgogKgogKiBUbyBlbmFibGUgQVNDSUkgZm9ybWF0dGluZyBldmVuIHdoZW4gdGhlIHNoZWxsIGlzIHBpcGVkLCB1c2UgdGhlCiAqIEVOViB2YXJpYWJsZSBTSEVMTF9QSVBFPTAuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gaXNQaXBlZCgpIHsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5WYWxpZEZ1bmN0aW9uTmFtZS5GdW5jdGlvbk5hbWVJbnZhbGlkIC0tIFJlbmFtaW5nIHdvdWxkIGJyZWFrIEJDLgoJJHNoZWxsX3BpcGUgPSBnZXRlbnYoICdTSEVMTF9QSVBFJyApOwoKCWlmICggZmFsc2UgIT09ICRzaGVsbF9waXBlICkgewoJCXJldHVybiBmaWx0ZXJfdmFyKCAkc2hlbGxfcGlwZSwgRklMVEVSX1ZBTElEQVRFX0JPT0xFQU4gKTsKCX0KCglyZXR1cm4gZnVuY3Rpb25fZXhpc3RzKCAncG9zaXhfaXNhdHR5JyApICYmICEgcG9zaXhfaXNhdHR5KCBTVERPVVQgKTsKfQoKLyoqCiAqIEV4cGFuZCB3aXRoaW4gcGF0aHMgdG8gdGhlaXIgbWF0Y2hpbmcgcGF0aHMuCiAqCiAqIEhhcyBubyBlZmZlY3Qgb24gcGF0aHMgd2hpY2ggZG8gbm90IHVzZSBnbG9iIHBhdHRlcm5zLgogKgogKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRwYXRocyBTaW5nbGUgcGF0aCBhcyBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2YgcGF0aHMuCiAqIEBwYXJhbSBpbnQgICAgICAgICAgJGZsYWdzIE9wdGlvbmFsLiBGbGFncyB0byBwYXNzIHRvIGdsb2IuIERlZmF1bHRzIHRvIEdMT0JfQlJBQ0UuCiAqIEByZXR1cm4gYXJyYXkgRXhwYW5kZWQgcGF0aHMuCiAqLwpmdW5jdGlvbiBleHBhbmRfZ2xvYnMoICRwYXRocywgJGZsYWdzID0gJ2RlZmF1bHQnICkgewoJLy8gQ29tcGF0aWJpbGl0eSBmb3Igc3lzdGVtcyB3aXRob3V0IEdMT0JfQlJBQ0UuCgkkZ2xvYl9mdW5jID0gJ2dsb2InOwoJaWYgKCAnZGVmYXVsdCcgPT09ICRmbGFncyApIHsKCQlpZiAoICEgZGVmaW5lZCggJ0dMT0JfQlJBQ0UnICkgfHwgZ2V0ZW52KCAnV1BfQ0xJX1RFU1RfRVhQQU5EX0dMT0JTX05PX0dMT0JfQlJBQ0UnICkgKSB7CgkJCSRnbG9iX2Z1bmMgPSAnV1BfQ0xJXFV0aWxzXGdsb2JfYnJhY2UnOwoJCX0gZWxzZSB7CgkJCSRmbGFncyA9IEdMT0JfQlJBQ0U7CgkJfQoJfQoKCSRleHBhbmRlZCA9IFtdOwoKCWZvcmVhY2ggKCAoYXJyYXkpICRwYXRocyBhcyAkcGF0aCApIHsKCQkkbWF0Y2hpbmcgPSBbICRwYXRoIF07CgoJCWlmICggcHJlZ19tYXRjaCggJy9bJyAuIHByZWdfcXVvdGUoICcqP1tde30hJywgJy8nICkgLiAnXS8nLCAkcGF0aCApICkgewoJCQkkbWF0Y2hpbmcgPSAkZ2xvYl9mdW5jKCAkcGF0aCwgJGZsYWdzICkgPzogW107CgkJfQoJCSRleHBhbmRlZCA9IGFycmF5X21lcmdlKCAkZXhwYW5kZWQsICRtYXRjaGluZyApOwoJfQoKCXJldHVybiBhcnJheV92YWx1ZXMoIGFycmF5X3VuaXF1ZSggJGV4cGFuZGVkICkgKTsKfQoKLyoqCiAqIFNpbXVsYXRlIGEgYGdsb2IoKWAgd2l0aCB0aGUgYEdMT0JfQlJBQ0VgIGZsYWcgc2V0LiBGb3Igc3lzdGVtcyAoZWcgQWxwaW5lIExpbnV4KSBidWlsdCBhZ2FpbnN0IGEgbGliYyBsaWJyYXJ5IChlZyBodHRwczovL3d3dy5tdXNsLWxpYmMub3JnLykgdGhhdCBsYWNrcyBpdC4KICogQ29waWVkIGFuZCBhZGFwdGVkIGZyb20gWmVuZCBGcmFtZXdvcmsncyBgR2xvYjo6ZmFsbGJhY2tHbG9iKClgIGFuZCBHbG9iOjpuZXh0QnJhY2VTdWIoKWAuCiAqCiAqIFplbmQgRnJhbWV3b3JrIChodHRwczovL2ZyYW1ld29yay56ZW5kLmNvbS8pCiAqCiAqIEBsaW5rICAgICAgaHR0cHM6Ly9naXRodWIuY29tL3plbmRmcmFtZXdvcmsvemYyIGZvciB0aGUgY2Fub25pY2FsIHNvdXJjZSByZXBvc2l0b3J5CiAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSAyMDA1LTIwMTUgWmVuZCBUZWNobm9sb2dpZXMgVVNBIEluYy4gKGh0dHBzOi8vd3d3LnplbmQuY29tKQogKiBAbGljZW5zZSAgIGh0dHBzOi8vZnJhbWV3b3JrLnplbmQuY29tL2xpY2Vuc2UvbmV3LWJzZCBOZXcgQlNEIExpY2Vuc2UKICoKICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiAgICAgRmlsZW5hbWUgcGF0dGVybi4KICogQHBhcmFtIHZvaWQgICAkZHVtbXlfZmxhZ3MgTm90IHVzZWQuCiAqIEByZXR1cm4gYXJyYXkgQXJyYXkgb2YgcGF0aHMuCiAqLwpmdW5jdGlvbiBnbG9iX2JyYWNlKCAkcGF0dGVybiwgJGR1bW15X2ZsYWdzID0gbnVsbCApIHsKCglzdGF0aWMgJG5leHRfYnJhY2Vfc3ViOwoJaWYgKCAhICRuZXh0X2JyYWNlX3N1YiApIHsKCQkvLyBGaW5kIHRoZSBlbmQgb2YgdGhlIHN1YnBhdHRlcm4gaW4gYSBicmFjZSBleHByZXNzaW9uLgoJCSRuZXh0X2JyYWNlX3N1YiA9IGZ1bmN0aW9uICggJHBhdHRlcm4sICRjdXJyZW50ICkgewoJCQkkbGVuZ3RoID0gc3RybGVuKCAkcGF0dGVybiApOwoJCQkkZGVwdGggID0gMDsKCgkJCXdoaWxlICggJGN1cnJlbnQgPCAkbGVuZ3RoICkgewoJCQkJaWYgKCAnXFwnID09PSAkcGF0dGVyblsgJGN1cnJlbnQgXSApIHsKCQkJCQlpZiAoICsrJGN1cnJlbnQgPT09ICRsZW5ndGggKSB7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQkkY3VycmVudCsrOwoJCQkJfSBlbHNlIHsKCQkJCQlpZiAoICggJ30nID09PSAkcGF0dGVyblsgJGN1cnJlbnQgXSAmJiAwID09PSAkZGVwdGgtLSApIHx8ICggJywnID09PSAkcGF0dGVyblsgJGN1cnJlbnQgXSAmJiAwID09PSAkZGVwdGggKSApIHsKCQkJCQkJYnJlYWs7CgkJCQkJfQoKCQkJCQlpZiAoICd7JyA9PT0gJHBhdHRlcm5bICRjdXJyZW50KysgXSApIHsKCQkJCQkJJGRlcHRoKys7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gJGN1cnJlbnQgPCAkbGVuZ3RoID8gJGN1cnJlbnQgOiBudWxsOwoJCX07Cgl9CgoJJGxlbmd0aCA9IHN0cmxlbiggJHBhdHRlcm4gKTsKCgkvLyBGaW5kIGZpcnN0IG9wZW5pbmcgYnJhY2UuCglmb3IgKCAkYmVnaW4gPSAwOyAkYmVnaW4gPCAkbGVuZ3RoOyAkYmVnaW4rKyApIHsKCQlpZiAoICdcXCcgPT09ICRwYXR0ZXJuWyAkYmVnaW4gXSApIHsKCQkJJGJlZ2luKys7CgkJfSBlbHNlaWYgKCAneycgPT09ICRwYXR0ZXJuWyAkYmVnaW4gXSApIHsKCQkJYnJlYWs7CgkJfQoJfQoKCS8vIEZpbmQgY29tbWEgb3IgbWF0Y2hpbmcgY2xvc2luZyBicmFjZS4KCSRuZXh0ID0gJG5leHRfYnJhY2Vfc3ViKCAkcGF0dGVybiwgJGJlZ2luICsgMSApOwoJaWYgKCBudWxsID09PSAkbmV4dCApIHsKCQlyZXR1cm4gZ2xvYiggJHBhdHRlcm4gKTsKCX0KCgkkcmVzdCA9ICRuZXh0OwoKCS8vIFBvaW50IGAkcmVzdGAgdG8gbWF0Y2hpbmcgY2xvc2luZyBicmFjZS4KCXdoaWxlICggJ30nICE9PSAkcGF0dGVyblsgJHJlc3QgXSApIHsKCQkkcmVzdCA9ICRuZXh0X2JyYWNlX3N1YiggJHBhdHRlcm4sICRyZXN0ICsgMSApOwoJCWlmICggbnVsbCA9PT0gJHJlc3QgKSB7CgkJCXJldHVybiBnbG9iKCAkcGF0dGVybiApOwoJCX0KCX0KCgkkcGF0aHMgPSBbXTsKCSRwICAgICA9ICRiZWdpbiArIDE7CgoJLy8gRm9yIGVhY2ggY29tbWEtc2VwYXJhdGVkIHN1YnBhdHRlcm4uCglkbyB7CgkJJHN1YnBhdHRlcm4gPSBzdWJzdHIoICRwYXR0ZXJuLCAwLCAkYmVnaW4gKQoJCQkJCS4gc3Vic3RyKCAkcGF0dGVybiwgJHAsICRuZXh0IC0gJHAgKQoJCQkJCS4gc3Vic3RyKCAkcGF0dGVybiwgJHJlc3QgKyAxICk7CgoJCSRyZXN1bHQgPSBnbG9iX2JyYWNlKCAkc3VicGF0dGVybiApOwoJCWlmICggISBlbXB0eSggJHJlc3VsdCApICkgewoJCQkkcGF0aHMgPSBhcnJheV9tZXJnZSggJHBhdGhzLCAkcmVzdWx0ICk7CgkJfQoKCQlpZiAoICd9JyA9PT0gJHBhdHRlcm5bICRuZXh0IF0gKSB7CgkJCWJyZWFrOwoJCX0KCgkJJHAgICAgPSAkbmV4dCArIDE7CgkJJG5leHQgPSAkbmV4dF9icmFjZV9zdWIoICRwYXR0ZXJuLCAkcCApOwoJfSB3aGlsZSAoIG51bGwgIT09ICRuZXh0ICk7CgoJcmV0dXJuIGFycmF5X3ZhbHVlcyggYXJyYXlfdW5pcXVlKCAkcGF0aHMgKSApOwp9CgovKioKICogR2V0IHRoZSBjbG9zZXN0IHN1Z2dlc3Rpb24gZm9yIGEgbWlzLXR5cGVkIHRhcmdldCB0ZXJtIGFtb25nc3QgYSBsaXN0IG9mCiAqIG9wdGlvbnMuCiAqCiAqIFVzZXMgdGhlIExldmVuc2h0ZWluIGFsZ29yaXRobSB0byBjYWxjdWxhdGUgdGhlIHJlbGF0aXZlICJkaXN0YW5jZSIgYmV0d2VlbgogKiB0ZXJtcy4KICoKICogSWYgdGhlICJkaXN0YW5jZSIgdG8gdGhlIGNsb3Nlc3QgdGVybSBpcyBoaWdoZXIgdGhhbiB0aGUgdGhyZXNob2xkLCBhbiBlbXB0eQogKiBzdHJpbmcgaXMgcmV0dXJuZWQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldCAgICBUYXJnZXQgdGVybSB0byBnZXQgYSBzdWdnZXN0aW9uIGZvci4KICogQHBhcmFtIGFycmF5ICAkb3B0aW9ucyAgIEFycmF5IHdpdGggcG9zc2libGUgb3B0aW9ucy4KICogQHBhcmFtIGludCAgICAkdGhyZXNob2xkIFRocmVzaG9sZCBhYm92ZSB3aGljaCB0byByZXR1cm4gYW4gZW1wdHkgc3RyaW5nLgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gZ2V0X3N1Z2dlc3Rpb24oICR0YXJnZXQsIGFycmF5ICRvcHRpb25zLCAkdGhyZXNob2xkID0gMiApIHsKCgkkc3VnZ2VzdGlvbl9tYXAgPSBbCgkJJ2FkZCcgICAgICAgID0+ICdjcmVhdGUnLAoJCSdjaGVjaycgICAgICA9PiAnY2hlY2stdXBkYXRlJywKCQknY2FwYWJpbGl0eScgPT4gJ2NhcCcsCgkJJ2NsZWFyJyAgICAgID0+ICdmbHVzaCcsCgkJJ2RlY3JlbWVudCcgID0+ICdkZWNyJywKCQknZGVsJyAgICAgICAgPT4gJ2RlbGV0ZScsCgkJJ2RpcmVjdG9yeScgID0+ICdkaXInLAoJCSdleGVjJyAgICAgICA9PiAnZXZhbCcsCgkJJ2V4ZWMtZmlsZScgID0+ICdldmFsLWZpbGUnLAoJCSdpbmNyZW1lbnQnICA9PiAnaW5jcicsCgkJJ2xhbmd1YWdlJyAgID0+ICdsb2NhbGUnLAoJCSdsYW5nJyAgICAgICA9PiAnbG9jYWxlJywKCQknbmV3JyAgICAgICAgPT4gJ2NyZWF0ZScsCgkJJ251bWJlcicgICAgID0+ICdjb3VudCcsCgkJJ3JlbW92ZScgICAgID0+ICdkZWxldGUnLAoJCSdyZWdlbicgICAgICA9PiAncmVnZW5lcmF0ZScsCgkJJ3JlcCcgICAgICAgID0+ICdyZXBsYWNlJywKCQkncmVwbCcgICAgICAgPT4gJ3JlcGxhY2UnLAoJCSd0cmFzaCcgICAgICA9PiAnZGVsZXRlJywKCQkndicgICAgICAgICAgPT4gJ3ZlcnNpb24nLAoJXTsKCglpZiAoIGFycmF5X2tleV9leGlzdHMoICR0YXJnZXQsICRzdWdnZXN0aW9uX21hcCApICYmIGluX2FycmF5KCAkc3VnZ2VzdGlvbl9tYXBbICR0YXJnZXQgXSwgJG9wdGlvbnMsIHRydWUgKSApIHsKCQlyZXR1cm4gJHN1Z2dlc3Rpb25fbWFwWyAkdGFyZ2V0IF07Cgl9CgoJaWYgKCBlbXB0eSggJG9wdGlvbnMgKSApIHsKCQlyZXR1cm4gJyc7Cgl9Cglmb3JlYWNoICggJG9wdGlvbnMgYXMgJG9wdGlvbiApIHsKCQkkZGlzdGFuY2UgICAgICAgICAgICAgICA9IGxldmVuc2h0ZWluKCAkb3B0aW9uLCAkdGFyZ2V0ICk7CgkJJGxldmVuc2h0ZWluWyAkb3B0aW9uIF0gPSAkZGlzdGFuY2U7Cgl9CgoJLy8gU29ydCBrbm93biBjb21tYW5kIHN0cmluZ3MgYnkgZGlzdGFuY2UgdG8gdXNlciBlbnRyeS4KCWFzb3J0KCAkbGV2ZW5zaHRlaW4gKTsKCgkvLyBGZXRjaCB0aGUgY2xvc2VzdCBjb21tYW5kIHN0cmluZy4KCXJlc2V0KCAkbGV2ZW5zaHRlaW4gKTsKCSRzdWdnZXN0aW9uID0ga2V5KCAkbGV2ZW5zaHRlaW4gKTsKCgkvLyBPbmx5IHJldHVybiBhIHN1Z2dlc3Rpb24gaWYgYmVsb3cgYSBnaXZlbiB0aHJlc2hvbGQuCglyZXR1cm4gJGxldmVuc2h0ZWluWyAkc3VnZ2VzdGlvbiBdIDw9ICR0aHJlc2hvbGQgJiYgJHN1Z2dlc3Rpb24gIT09ICR0YXJnZXQKCQk/IChzdHJpbmcpICRzdWdnZXN0aW9uCgkJOiAnJzsKfQoKLyoqCiAqIEdldCBhIFBoYXItc2FmZSB2ZXJzaW9uIG9mIGEgcGF0aC4KICoKICogRm9yIHBhdGhzIGluc2lkZSBhIFBoYXIsIHRoaXMgc3RyaXBzIHRoZSBvdXRlciBmaWxlc3lzdGVtJ3MgbG9jYXRpb24gdG8KICogcmVkdWNlIHRoZSBwYXRoIHRvIHdoYXQgaXQgbmVlZHMgdG8gYmUgd2l0aGluIHRoZSBQaGFyIGFyY2hpdmUuCiAqCiAqIFVzZSB0aGUgX19GSUxFX18gb3IgX19ESVJfXyBjb25zdGFudHMgYXMgYSBzdGFydGluZyBwb2ludC4KICoKICogQHBhcmFtIHN0cmluZyAkcGF0aCBBbiBhYnNvbHV0ZSBwYXRoIHRoYXQgbWlnaHQgYmUgd2l0aGluIGEgUGhhci4KICogQHJldHVybiBzdHJpbmcgQSBQaGFyLXNhZmUgdmVyc2lvbiBvZiB0aGUgcGF0aC4KICovCmZ1bmN0aW9uIHBoYXJfc2FmZV9wYXRoKCAkcGF0aCApIHsKCglpZiAoICEgaW5zaWRlX3BoYXIoKSApIHsKCQlyZXR1cm4gJHBhdGg7Cgl9CgoJcmV0dXJuIHN0cl9yZXBsYWNlKAoJCVBIQVJfU1RSRUFNX1BSRUZJWCAuIFdQX0NMSV9QSEFSX1BBVEggLiAnLycsCgkJUEhBUl9TVFJFQU1fUFJFRklYLAoJCSRwYXRoCgkpOwp9CgovKioKICogTWF5YmUgcHJlZml4IGNvbW1hbmQgc3RyaW5nIHdpdGggIi91c3IvYmluL2VudiIuCiAqIFJlbW92ZXMgKGlmIHRoZXJlKSBpZiBXaW5kb3dzLCBhZGRzIChpZiBub3QgdGhlcmUpIGlmIG5vdC4KICoKICogQHBhcmFtIHN0cmluZyAkY29tbWFuZAogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gZm9yY2VfZW52X29uX25peF9zeXN0ZW1zKCAkY29tbWFuZCApIHsKCSRlbnZfcHJlZml4ICAgICA9ICcvdXNyL2Jpbi9lbnYgJzsKCSRlbnZfcHJlZml4X2xlbiA9IHN0cmxlbiggJGVudl9wcmVmaXggKTsKCWlmICggaXNfd2luZG93cygpICkgewoJCWlmICggMCA9PT0gc3RybmNtcCggJGNvbW1hbmQsICRlbnZfcHJlZml4LCAkZW52X3ByZWZpeF9sZW4gKSApIHsKCQkJJGNvbW1hbmQgPSBzdWJzdHIoICRjb21tYW5kLCAkZW52X3ByZWZpeF9sZW4gKTsKCQl9Cgl9IGVsc2VpZiAoIDAgIT09IHN0cm5jbXAoICRjb21tYW5kLCAkZW52X3ByZWZpeCwgJGVudl9wcmVmaXhfbGVuICkgKSB7CgkJJGNvbW1hbmQgPSAkZW52X3ByZWZpeCAuICRjb21tYW5kOwoJfQoJcmV0dXJuICRjb21tYW5kOwp9CgovKioKICogQ2hlY2sgdGhhdCBgcHJvY19vcGVuKClgIGFuZCBgcHJvY19jbG9zZSgpYCBoYXZlbid0IGJlZW4gZGlzYWJsZWQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQgT3B0aW9uYWwuIElmIHNldCB3aWxsIGFwcGVhciBpbiBlcnJvciBtZXNzYWdlLiBEZWZhdWx0IG51bGwuCiAqIEBwYXJhbSBib29sICAgJHJldHVybiAgT3B0aW9uYWwuIElmIHNldCB3aWxsIHJldHVybiBmYWxzZSByYXRoZXIgdGhhbiBlcnJvciBvdXQuIERlZmF1bHQgZmFsc2UuCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gY2hlY2tfcHJvY19hdmFpbGFibGUoICRjb250ZXh0ID0gbnVsbCwgJHJldHVybiA9IGZhbHNlICkgewoJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3Byb2Nfb3BlbicgKSB8fCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3Byb2NfY2xvc2UnICkgKSB7CgkJaWYgKCAkcmV0dXJuICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCSRtc2cgPSAnVGhlIFBIUCBmdW5jdGlvbnMgYHByb2Nfb3BlbigpYCBhbmQvb3IgYHByb2NfY2xvc2UoKWAgYXJlIGRpc2FibGVkLiBQbGVhc2UgY2hlY2sgeW91ciBQSFAgaW5pIGRpcmVjdGl2ZSBgZGlzYWJsZV9mdW5jdGlvbnNgIG9yIHN1aG9zaW4gc2V0dGluZ3MuJzsKCQlpZiAoICRjb250ZXh0ICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiQ2Fubm90IGRvICclcyc6ICVzIiwgJGNvbnRleHQsICRtc2cgKSApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRtc2cgKTsKCQl9Cgl9CglyZXR1cm4gdHJ1ZTsKfQoKLyoqCiAqIFJldHVybnMgcGFzdCB0ZW5zZSBvZiB2ZXJiLCB3aXRoIGxpbWl0ZWQgYWNjdXJhY3kuIE9ubHkgcmVndWxhciB2ZXJicyBjYXRlcmVkIGZvciwgYXBhcnQgZnJvbSAicmVzZXQiLgogKgogKiBAcGFyYW0gc3RyaW5nICR2ZXJiIFZlcmIgdG8gcmV0dXJuIHBhc3QgdGVuc2Ugb2YuCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBwYXN0X3RlbnNlX3ZlcmIoICR2ZXJiICkgewoJc3RhdGljICRpcnJlZ3VsYXIgPSBbCgkJJ3Jlc2V0JyA9PiAncmVzZXQnLAoJXTsKCWlmICggaXNzZXQoICRpcnJlZ3VsYXJbICR2ZXJiIF0gKSApIHsKCQlyZXR1cm4gJGlycmVndWxhclsgJHZlcmIgXTsKCX0KCSRsYXN0ID0gc3Vic3RyKCAkdmVyYiwgLTEgKTsKCWlmICggJ2UnID09PSAkbGFzdCApIHsKCQkkdmVyYiA9IHN1YnN0ciggJHZlcmIsIDAsIC0xICk7Cgl9IGVsc2VpZiAoICd5JyA9PT0gJGxhc3QgJiYgISBwcmVnX21hdGNoKCAnL1thZWlvdV15JC8nLCAkdmVyYiApICkgewoJCSR2ZXJiID0gc3Vic3RyKCAkdmVyYiwgMCwgLTEgKSAuICdpJzsKCX0gZWxzZWlmICggcHJlZ19tYXRjaCggJy9eW15hZWlvdV0qW2FlaW91XVteYWVpb3Vod3h5XSQvJywgJHZlcmIgKSApIHsKCQkvLyBSdWxlIG9mIHRodW1iIHRoYXQgbW9zdCAoYWxsPykgb25lLXZvd2VsZWQgcmVndWxhciB2ZXJicyBlbmRpbmcgaW4gdm93ZWwgKyBjb25zb25hbnQgKGV4Y2x1ZGluZyAiaCIsICJ3IiwgIngiLCAieSIpIGRvdWJsZSB0aGVpciBmaW5hbCBjb25zb25hbnQgLSBtaXNzZXMgbWFueSBjYXNlcyAoZWcgInN1Ym1pdCIpLgoJCSR2ZXJiIC49ICRsYXN0OwoJfQoJcmV0dXJuICR2ZXJiIC4gJ2VkJzsKfQoKLyoqCiAqIEdldCB0aGUgcGF0aCB0byB0aGUgUEhQIGJpbmFyeSB1c2VkIHdoZW4gZXhlY3V0aW5nIFdQLUNMSS4KICoKICogRW52aXJvbm1lbnQgdmFsdWVzIHBlcm1pdCBzcGVjaWZpYyBiaW5hcmllcyB0byBiZSBpbmRpY2F0ZWQuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqIEBjYXRlZ29yeSBTeXN0ZW0KICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGdldF9waHBfYmluYXJ5KCkgewoJJHdwX2NsaV9waHBfdXNlZCA9IGdldGVudiggJ1dQX0NMSV9QSFBfVVNFRCcgKTsKCWlmICggZmFsc2UgIT09ICR3cF9jbGlfcGhwX3VzZWQgKSB7CgkJcmV0dXJuICR3cF9jbGlfcGhwX3VzZWQ7Cgl9CgoJJHdwX2NsaV9waHAgPSBnZXRlbnYoICdXUF9DTElfUEhQJyApOwoJaWYgKCBmYWxzZSAhPT0gJHdwX2NsaV9waHAgKSB7CgkJcmV0dXJuICR3cF9jbGlfcGhwOwoJfQoKCXJldHVybiBQSFBfQklOQVJZOwp9CgovKioKICogV2luZG93cyBjb21wYXRpYmxlIGBwcm9jX29wZW4oKWAuCiAqIFdvcmtzIGFyb3VuZCBidWcgaW4gUEhQLCBhbmQgYWxzbyBkZWFscyB3aXRoICpuaXgtbGlrZSBgRU5WX1ZBUj1ibGFoIGNtZGAgZW52aXJvbm1lbnQgdmFyaWFibGUgcHJlZml4ZXMuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNtZCAgICAgICAgICAgIENvbW1hbmQgdG8gZXhlY3V0ZS4KICogQHBhcmFtIGFycmF5ICAkZGVzY3JpcHRvcnNwZWMgSW5kZXhlZCBhcnJheSBvZiBkZXNjcmlwdG9yIG51bWJlcnMgYW5kIHRoZWlyIHZhbHVlcy4KICogQHBhcmFtIGFycmF5ICAmJHBpcGVzICAgICAgICAgSW5kZXhlZCBhcnJheSBvZiBmaWxlIHBvaW50ZXJzIHRoYXQgY29ycmVzcG9uZCB0byBQSFAncyBlbmQgb2YgYW55IHBpcGVzIHRoYXQgYXJlIGNyZWF0ZWQuCiAqIEBwYXJhbSBzdHJpbmcgJGN3ZCAgICAgICAgICAgIEluaXRpYWwgd29ya2luZyBkaXJlY3RvcnkgZm9yIHRoZSBjb21tYW5kLgogKiBAcGFyYW0gYXJyYXkgICRlbnYgICAgICAgICAgICBBcnJheSBvZiBlbnZpcm9ubWVudCB2YXJpYWJsZXMuCiAqIEBwYXJhbSBhcnJheSAgJG90aGVyX29wdGlvbnMgIEFycmF5IG9mIGFkZGl0aW9uYWwgb3B0aW9ucyAoV2luZG93cyBvbmx5KS4KICogQHJldHVybiByZXNvdXJjZSBDb21tYW5kIHN0cmlwcGVkIG9mIGFueSBlbnZpcm9ubWVudCB2YXJpYWJsZSBzZXR0aW5ncy4KICovCmZ1bmN0aW9uIHByb2Nfb3Blbl9jb21wYXQoICRjbWQsICRkZXNjcmlwdG9yc3BlYywgJiRwaXBlcywgJGN3ZCA9IG51bGwsICRlbnYgPSBudWxsLCAkb3RoZXJfb3B0aW9ucyA9IG51bGwgKSB7CglpZiAoIGlzX3dpbmRvd3MoKSApIHsKCQkvLyBOZWVkIHRvIGVuY29tcGFzcyB0aGUgd2hvbGUgY29tbWFuZCBpbiBkb3VibGUgcXVvdGVzIC0gUEhQIGJ1ZyBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTQ5MTM5CgkJJGNtZCA9ICciJyAuIF9wcm9jX29wZW5fY29tcGF0X3dpbl9lbnYoICRjbWQsICRlbnYgKSAuICciJzsKCX0KCXJldHVybiBwcm9jX29wZW4oICRjbWQsICRkZXNjcmlwdG9yc3BlYywgJHBpcGVzLCAkY3dkLCAkZW52LCAkb3RoZXJfb3B0aW9ucyApOwp9CgovKioKICogRm9yIHVzZSBieSBgcHJvY19vcGVuX2NvbXBhdCgpYCBvbmx5LiBTZXBhcmF0ZWQgb3V0IGZvciBlYXNlIG9mIHRlc3RpbmcuIFdpbmRvd3Mgb25seS4KICogVHVybnMgKm5peC1saWtlIGBFTlZfVkFSPWJsYWggY29tbWFuZGAgZW52aXJvbm1lbnQgdmFyaWFibGUgcHJlZml4ZXMgaW50byBzdHJpcHBlZCBgY21kYCB3aXRoIHByZWZpeGVkIGVudmlyb25tZW50IHZhcmlhYmxlcyBhZGRlZCB0byBwYXNzZWQgaW4gZW52aXJvbm1lbnQgYXJyYXkuCiAqCiAqIEBhY2Nlc3MgcHJpdmF0ZQogKgogKiBAcGFyYW0gc3RyaW5nICRjbWQgQ29tbWFuZCB0byBleGVjdXRlLgogKiBAcGFyYW0gYXJyYXkgJiRlbnYgQXJyYXkgb2YgZXhpc3RpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzLiBXaWxsIGJlIG1vZGlmaWVkIGlmIGFueSBzZXR0aW5ncyBpbiBjb21tYW5kLgogKiBAcmV0dXJuIHN0cmluZyBDb21tYW5kIHN0cmlwcGVkIG9mIGFueSBlbnZpcm9ubWVudCB2YXJpYWJsZSBzZXR0aW5ncy4KICovCmZ1bmN0aW9uIF9wcm9jX29wZW5fY29tcGF0X3dpbl9lbnYoICRjbWQsICYkZW52ICkgewoJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkY21kLCAnPScgKSApIHsKCQl3aGlsZSAoIHByZWdfbWF0Y2goICcvXihbQS1aYS16X11bQS1aYS16MC05X10qKT0oIlteIl0qInxbXiBdKikgLycsICRjbWQsICRtYXRjaGVzICkgKSB7CgkJCSRjbWQgPSBzdWJzdHIoICRjbWQsIHN0cmxlbiggJG1hdGNoZXNbMF0gKSApOwoJCQlpZiAoIG51bGwgPT09ICRlbnYgKSB7CgkJCQkkZW52ID0gW107CgkJCX0KCQkJJGVudlsgJG1hdGNoZXNbMV0gXSA9IGlzc2V0KCAkbWF0Y2hlc1syXVswXSApICYmICciJyA9PT0gJG1hdGNoZXNbMl1bMF0gPyBzdWJzdHIoICRtYXRjaGVzWzJdLCAxLCAtMSApIDogJG1hdGNoZXNbMl07CgkJfQoJfQoJcmV0dXJuICRjbWQ7Cn0KCi8qKgogKiBGaXJzdCBoYWxmIG9mIGVzY2FwaW5nIGZvciBMSUtFIHNwZWNpYWwgY2hhcmFjdGVycyAlIGFuZCBfIGJlZm9yZSBwcmVwYXJpbmcgZm9yIE15U1FMLgogKgogKiBVc2UgdGhpcyBvbmx5IGJlZm9yZSB3cGRiOjpwcmVwYXJlKCkgb3IgZXNjX3NxbCgpLiAgUmV2ZXJzaW5nIHRoZSBvcmRlciBpcyB2ZXJ5IGJhZCBmb3Igc2VjdXJpdHkuCiAqCiAqIENvcGllZCBmcm9tIGNvcmUgIndwLWluY2x1ZGVzL3dwLWRiLnBocCIuIEF2b2lkcyBkZXBlbmRlbmN5IG9uIFdQIDQuNCB3cGRiLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKgogKiBAcGFyYW0gc3RyaW5nICR0ZXh0IFRoZSByYXcgdGV4dCB0byBiZSBlc2NhcGVkLiBUaGUgaW5wdXQgdHlwZWQgYnkgdGhlIHVzZXIgc2hvdWxkIGhhdmUgbm8KICogICAgICAgICAgICAgICAgICAgICBleHRyYSBvciBkZWxldGVkIHNsYXNoZXMuCiAqIEByZXR1cm4gc3RyaW5nIFRleHQgaW4gdGhlIGZvcm0gb2YgYSBMSUtFIHBocmFzZS4gVGhlIG91dHB1dCBpcyBub3QgU1FMIHNhZmUuIENhbGwgJHdwZGI6OnByZXBhcmUoKQogKiAgICAgICAgICAgICAgICBvciByZWFsX2VzY2FwZSBuZXh0LgogKi8KZnVuY3Rpb24gZXNjX2xpa2UoICR0ZXh0ICkgewoJcmV0dXJuIGFkZGNzbGFzaGVzKCAkdGV4dCwgJ18lXFwnICk7Cn0KCi8qKgogKiBFc2NhcGVzIChiYWNrdGlja3MpIE15U1FMIGlkZW50aWZpZXJzIChha2Egc2NoZW1hIG9iamVjdCBuYW1lcykgLSBpLmUuIGNvbHVtbiBuYW1lcywgdGFibGUgbmFtZXMsIGFuZCBkYXRhYmFzZS9pbmRleC9hbGlhcy92aWV3IGV0YyBuYW1lcy4KICogU2VlIGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvcmVmbWFuLzUuNS9lbi9pZGVudGlmaWVycy5odG1sCiAqCiAqIEBwYXJhbSAgc3RyaW5nfGFycmF5ICRpZGVudHMgQSBzaW5nbGUgaWRlbnRpZmllciBvciBhbiBhcnJheSBvZiBpZGVudGlmaWVycy4KICogQHJldHVybiBzdHJpbmd8YXJyYXkgQW4gZXNjYXBlZCBzdHJpbmcgaWYgZ2l2ZW4gYSBzdHJpbmcsIG9yIGFuIGFycmF5IG9mIGVzY2FwZWQgc3RyaW5ncyBpZiBnaXZlbiBhbiBhcnJheSBvZiBzdHJpbmdzLgogKi8KZnVuY3Rpb24gZXNjX3NxbF9pZGVudCggJGlkZW50cyApIHsKCSRiYWNrdGljayA9IHN0YXRpYyBmdW5jdGlvbiAoICR2ICkgewoJCS8vIEVzY2FwZSBhbnkgYmFja3RpY2tzIGluIHRoZSBpZGVudGlmaWVyIGJ5IGRvdWJsaW5nLgoJCXJldHVybiAnYCcgLiBzdHJfcmVwbGFjZSggJ2AnLCAnYGAnLCAkdiApIC4gJ2AnOwoJfTsKCWlmICggaXNfc3RyaW5nKCAkaWRlbnRzICkgKSB7CgkJcmV0dXJuICRiYWNrdGljayggJGlkZW50cyApOwoJfQoJcmV0dXJuIGFycmF5X21hcCggJGJhY2t0aWNrLCAkaWRlbnRzICk7Cn0KCi8qKgogKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gc3RyaW5nIGlzIGEgdmFsaWQgSlNPTiByZXByZXNlbnRhdGlvbi4KICoKICogQHBhcmFtIHN0cmluZyAkYXJndW1lbnQgICAgICAgU3RyaW5nIHRvIGV2YWx1YXRlLgogKiBAcGFyYW0gYm9vbCAgICRpZ25vcmVfc2NhbGFycyBPcHRpb25hbC4gV2hldGhlciB0byBpZ25vcmUgc2NhbGFyIHZhbHVlcy4KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gdHJ1ZS4KICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHByb3ZpZGVkIHN0cmluZyBpcyBhIHZhbGlkIEpTT04gcmVwcmVzZW50YXRpb24uCiAqLwpmdW5jdGlvbiBpc19qc29uKCAkYXJndW1lbnQsICRpZ25vcmVfc2NhbGFycyA9IHRydWUgKSB7CglpZiAoICEgaXNfc3RyaW5nKCAkYXJndW1lbnQgKSB8fCAnJyA9PT0gJGFyZ3VtZW50ICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglpZiAoICRpZ25vcmVfc2NhbGFycyAmJiAhIGluX2FycmF5KCAkYXJndW1lbnRbMF0sIFsgJ3snLCAnWycgXSwgdHJ1ZSApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglqc29uX2RlY29kZSggJGFyZ3VtZW50LCAkYXNzb2MgPSB0cnVlICk7CgoJcmV0dXJuIGpzb25fbGFzdF9lcnJvcigpID09PSBKU09OX0VSUk9SX05PTkU7Cn0KCi8qKgogKiBQYXJzZSBrbm93biBzaGVsbCBhcnJheXMgaW5jbHVkZWQgaW4gdGhlICRhc3NvY19hcmdzIGFycmF5LgogKgogKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgICAgICBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhcmd1bWVudHMuCiAqIEBwYXJhbSBhcnJheSAkYXJyYXlfYXJndW1lbnRzIEFycmF5IG9mIGFyZ3VtZW50IGtleXMgdGhhdCBzaG91bGQgcmVjZWl2ZSBhbgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSB0aHJvdWdoIHRoZSBzaGVsbC4KICogQHJldHVybiBhcnJheQogKi8KZnVuY3Rpb24gcGFyc2Vfc2hlbGxfYXJyYXlzKCAkYXNzb2NfYXJncywgJGFycmF5X2FyZ3VtZW50cyApIHsKCWlmICggZW1wdHkoICRhc3NvY19hcmdzICkgfHwgZW1wdHkoICRhcnJheV9hcmd1bWVudHMgKSApIHsKCQlyZXR1cm4gJGFzc29jX2FyZ3M7Cgl9CgoJZm9yZWFjaCAoICRhcnJheV9hcmd1bWVudHMgYXMgJGtleSApIHsKCQlpZiAoIGFycmF5X2tleV9leGlzdHMoICRrZXksICRhc3NvY19hcmdzICkgJiYgaXNfanNvbiggJGFzc29jX2FyZ3NbICRrZXkgXSApICkgewoJCQkkYXNzb2NfYXJnc1sgJGtleSBdID0ganNvbl9kZWNvZGUoICRhc3NvY19hcmdzWyAka2V5IF0sICRhc3NvYyA9IHRydWUgKTsKCQl9Cgl9CgoJcmV0dXJuICRhc3NvY19hcmdzOwp9CgovKioKICogRGVzY3JpYmUgYSBjYWxsYWJsZSBhcyBhIHN0cmluZy4KICoKICogQHBhcmFtIGNhbGxhYmxlICRjYWxsYWJsZSBUaGUgY2FsbGFibGUgdG8gZGVzY3JpYmUuCiAqIEByZXR1cm4gc3RyaW5nIFN0cmluZyBkZXNjcmlwdGlvbiBvZiB0aGUgY2FsbGFibGUuCiAqLwpmdW5jdGlvbiBkZXNjcmliZV9jYWxsYWJsZSggJGNhbGxhYmxlICkgewoJdHJ5IHsKCQlpZiAoICRjYWxsYWJsZSBpbnN0YW5jZW9mIENsb3N1cmUgKSB7CgkJCSRyZWZsZWN0aW9uID0gbmV3IFJlZmxlY3Rpb25GdW5jdGlvbiggJGNhbGxhYmxlICk7CgoJCQlyZXR1cm4gIkNsb3N1cmUgaW4gZmlsZSB7JHJlZmxlY3Rpb24tPmdldEZpbGVOYW1lKCl9IGF0IGxpbmUgeyRyZWZsZWN0aW9uLT5nZXRTdGFydExpbmUoKX0iOwoJCX0KCgkJaWYgKCBpc19hcnJheSggJGNhbGxhYmxlICkgKSB7CgkJCWlmICggaXNfb2JqZWN0KCAkY2FsbGFibGVbMF0gKSApIHsKCQkJCXJldHVybiBzcHJpbnRmKAoJCQkJCSclcy0+JXMoKScsCgkJCQkJZ2V0X2NsYXNzKCAkY2FsbGFibGVbMF0gKSwKCQkJCQkkY2FsbGFibGVbMV0KCQkJCSk7CgkJCX0KCgkJCXJldHVybiBzcHJpbnRmKCAnJXM6OiVzKCknLCAkY2FsbGFibGVbMF0sICRjYWxsYWJsZVsxXSApOwoJCX0KCgkJcmV0dXJuIGdldHR5cGUoICRjYWxsYWJsZSApOwoJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCXJldHVybiAnQ2FsbGFibGUgb2YgdW5rbm93biB0eXBlJzsKCX0KfQoKLyoqCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gY2xhc3MgYW5kIG1ldGhvZCBwYWlyIGlzIGEgdmFsaWQgY2FsbGFibGUuCiAqCiAqIFRoaXMgYWNjb21tb2RhdGVzIGNoYW5nZXMgdG8gYGlzX2NhbGxhYmxlKClgIGluIFBIUCA4IHRoYXQgbWVhbiBhbiBhcnJheSBvZiBhCiAqIGNsYXNzbmFtZSBhbmQgaW5zdGFuY2UgbWV0aG9kIGlzIG5vIGxvbmdlciBjYWxsYWJsZS4KICoKICogQHBhcmFtIGFycmF5ICRwYWlyIFRoZSBjbGFzcyBhbmQgbWV0aG9kIHBhaXIgdG8gY2hlY2suCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gaXNfdmFsaWRfY2xhc3NfYW5kX21ldGhvZF9wYWlyKCAkcGFpciApIHsKCWlmICggISBpc19hcnJheSggJHBhaXIgKSB8fCAyICE9PSBjb3VudCggJHBhaXIgKSApIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJaWYgKCAhIGlzX3N0cmluZyggJHBhaXJbMF0gKSB8fCAhIGlzX3N0cmluZyggJHBhaXJbMV0gKSApIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJaWYgKCAhIGNsYXNzX2V4aXN0cyggJHBhaXJbMF0gKSApIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJaWYgKCAhIG1ldGhvZF9leGlzdHMoICRwYWlyWzBdLCAkcGFpclsxXSApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglyZXR1cm4gdHJ1ZTsKfQoKLyoqCiAqIFBsdXJhbGl6ZXMgYSBub3VuIGluIGEgZ3JhbW1hdGljYWxseSBjb3JyZWN0IHdheS4KICoKICogQHBhcmFtIHN0cmluZyAgICRub3VuICBOb3VuIHRvIGJlIHBsdXJhbGl6ZWQuIE5lZWRzIHRvIGJlIGluIHNpbmd1bGFyIGZvcm0uCiAqIEBwYXJhbSBpbnR8bnVsbCAkY291bnQgT3B0aW9uYWwuIENvdW50IG9mIHRoZSBub3VucywgdG8gZGVjaWRlIHdoZXRoZXIgdG8KICogICAgICAgICAgICAgICAgICAgICAgICBwbHVyYWxpemUuIFdpbGwgcGx1cmFsaXplIHVuY29uZGl0aW9uYWxseSBpZiBub25lCiAqICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZWQuCiAqIEByZXR1cm4gc3RyaW5nIFBsdXJhbGl6ZWQgbm91bi4KICovCmZ1bmN0aW9uIHBsdXJhbGl6ZSggJG5vdW4sICRjb3VudCA9IG51bGwgKSB7CglpZiAoIDEgPT09ICRjb3VudCApIHsKCQlyZXR1cm4gJG5vdW47Cgl9CgoJcmV0dXJuIEluZmxlY3Rvcjo6cGx1cmFsaXplKCAkbm91biApOwp9CgovKioKICogR2V0IHRoZSBwYXRoIHRvIHRoZSBteXNxbCBiaW5hcnkuCiAqCiAqIEByZXR1cm4gc3RyaW5nIFBhdGggdG8gdGhlIG15c3FsIGJpbmFyeSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vdCBmb3VuZC4KICovCmZ1bmN0aW9uIGdldF9teXNxbF9iaW5hcnlfcGF0aCgpIHsKCXN0YXRpYyAkcGF0aCA9IG51bGw7CgoJaWYgKCBudWxsID09PSAkcGF0aCApIHsKCQkkcmVzdWx0ID0gUHJvY2Vzczo6Y3JlYXRlKCAnL3Vzci9iaW4vZW52IHdoaWNoIG15c3FsJywgbnVsbCwgbnVsbCApLT5ydW4oKTsKCgkJaWYgKCAwICE9PSAkcmVzdWx0LT5yZXR1cm5fY29kZSApIHsKCQkJJHBhdGggPSAnJzsKCQl9IGVsc2UgewoJCQkkcGF0aCA9IHRyaW0oICRyZXN1bHQtPnN0ZG91dCApOwoJCX0KCX0KCglyZXR1cm4gJHBhdGg7Cn0KCi8qKgogKiBHZXQgdGhlIHZlcnNpb24gb2YgdGhlIE15U1FMIGRhdGFiYXNlLgogKgogKiBAcmV0dXJuIHN0cmluZyBWZXJzaW9uIG9mIHRoZSBNeVNRTCBkYXRhYmFzZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vdAogKiAgICAgICAgICAgICAgICBmb3VuZC4KICovCmZ1bmN0aW9uIGdldF9teXNxbF92ZXJzaW9uKCkgewoJc3RhdGljICR2ZXJzaW9uID0gbnVsbDsKCglpZiAoIG51bGwgPT09ICR2ZXJzaW9uICkgewoJCSRyZXN1bHQgPSBQcm9jZXNzOjpjcmVhdGUoICcvdXNyL2Jpbi9lbnYgbXlzcWwgLS12ZXJzaW9uJywgbnVsbCwgbnVsbCApLT5ydW4oKTsKCgkJaWYgKCAwICE9PSAkcmVzdWx0LT5yZXR1cm5fY29kZSApIHsKCQkJJHZlcnNpb24gPSAnJzsKCQl9IGVsc2UgewoJCQkkdmVyc2lvbiA9IHRyaW0oICRyZXN1bHQtPnN0ZG91dCApOwoJCX0KCX0KCglyZXR1cm4gJHZlcnNpb247Cn0KCi8qKgogKiBHZXQgdGhlIFNRTCBtb2RlcyBvZiB0aGUgTXlTUUwgc2Vzc2lvbi4KICoKICogQHJldHVybiBzdHJpbmdbXSBBcnJheSBvZiBTUUwgbW9kZXMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHRoZXkgY291bGRuJ3QgYmUKICogICAgICAgICAgICAgICAgICByZWFkLgogKi8KZnVuY3Rpb24gZ2V0X3NxbF9tb2RlcygpIHsKCXN0YXRpYyAkc3FsX21vZGVzID0gbnVsbDsKCglpZiAoIG51bGwgPT09ICRzcWxfbW9kZXMgKSB7CgkJJHJlc3VsdCA9IFByb2Nlc3M6OmNyZWF0ZSggJy91c3IvYmluL2VudiBteXNxbCAtLW5vLWF1dG8tcmVoYXNoIC0tYmF0Y2ggLS1za2lwLWNvbHVtbi1uYW1lcyAtLWV4ZWN1dGU9IlNFTEVDVCBAQFNFU1NJT04uc3FsX21vZGUiJywgbnVsbCwgbnVsbCApLT5ydW4oKTsKCgkJaWYgKCAwICE9PSAkcmVzdWx0LT5yZXR1cm5fY29kZSApIHsKCQkJJHNxbF9tb2RlcyA9IFtdOwoJCX0gZWxzZSB7CgkJCSRzcWxfbW9kZXMgPSBhcnJheV9maWx0ZXIoCgkJCQlhcnJheV9tYXAoCgkJCQkJJ3RyaW0nLAoJCQkJCXByZWdfc3BsaXQoICIvXHJcbnxcbnxcci8iLCAkcmVzdWx0LT5zdGRvdXQgKQoJCQkJKQoJCQkpOwoJCX0KCX0KCglyZXR1cm4gJHNxbF9tb2RlczsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTElcQm9vdHN0cmFwXEJvb3RzdHJhcFN0YXRlOwp1c2UgV1BfQ0xJXEJvb3RzdHJhcFxCb290c3RyYXBTdGVwOwoKLyoqCiAqIEdldCB0aGUgbGlzdCBvZiBvcmRlcmVkIHN0ZXBzIHRoYXQgbmVlZCB0byBiZSBwcm9jZXNzZWQgdG8gYm9vdHN0cmFwIFdQLUNMSS4KICoKICogRWFjaCBlbnRyeSBpcyBhIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIGZvciBhIGNsYXNzIGltcGxlbWVudGluZyB0aGUKICogYFdQX0NMSVxCb290c3RyYXBcQm9vdHN0cmFwU3RlcGAgaW50ZXJmYWNlLgogKgogKiBAcmV0dXJuIHN0cmluZ1tdCiAqLwpmdW5jdGlvbiBnZXRfYm9vdHN0cmFwX3N0ZXBzKCkgewoJcmV0dXJuIFsKCQknV1BfQ0xJXEJvb3RzdHJhcFxEZWNsYXJlRmFsbGJhY2tGdW5jdGlvbnMnLAoJCSdXUF9DTElcQm9vdHN0cmFwXExvYWRVdGlsaXR5RnVuY3Rpb25zJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxMb2FkRGlzcGF0Y2hlcicsCgkJJ1dQX0NMSVxCb290c3RyYXBcRGVjbGFyZU1haW5DbGFzcycsCgkJJ1dQX0NMSVxCb290c3RyYXBcRGVjbGFyZUFic3RyYWN0QmFzZUNvbW1hbmQnLAoJCSdXUF9DTElcQm9vdHN0cmFwXEluY2x1ZGVGcmFtZXdvcmtBdXRvbG9hZGVyJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxDb25maWd1cmVSdW5uZXInLAoJCSdXUF9DTElcQm9vdHN0cmFwXEluaXRpYWxpemVDb2xvcml6YXRpb24nLAoJCSdXUF9DTElcQm9vdHN0cmFwXEluaXRpYWxpemVMb2dnZXInLAoJCSdXUF9DTElcQm9vdHN0cmFwXERlZmluZVByb3RlY3RlZENvbW1hbmRzJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxMb2FkRXhlY0NvbW1hbmQnLAoJCSdXUF9DTElcQm9vdHN0cmFwXExvYWRSZXF1aXJlZENvbW1hbmQnLAoJCSdXUF9DTElcQm9vdHN0cmFwXEluY2x1ZGVQYWNrYWdlQXV0b2xvYWRlcicsCgkJJ1dQX0NMSVxCb290c3RyYXBcSW5jbHVkZUZhbGxiYWNrQXV0b2xvYWRlcicsCgkJJ1dQX0NMSVxCb290c3RyYXBcUmVnaXN0ZXJGcmFtZXdvcmtDb21tYW5kcycsCgkJJ1dQX0NMSVxCb290c3RyYXBcUmVnaXN0ZXJEZWZlcnJlZENvbW1hbmRzJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxJbml0aWFsaXplQ29udGV4dHMnLAoJCSdXUF9DTElcQm9vdHN0cmFwXExhdW5jaFJ1bm5lcicsCgldOwp9CgovKioKICogUmVnaXN0ZXIgdGhlIGNsYXNzZXMgbmVlZGVkIGZvciB0aGUgYm9vdHN0cmFwIHByb2Nlc3MuCiAqCiAqIFRoZSBDb21wb3NlciBhdXRvbG9hZGVyIGlzIG5vdCBhY3RpdmUgeWV0IGF0IHRoaXMgcG9pbnQsIHNvIHdlIG5lZWQgdG8gdXNlIGEKICogY3VzdG9tIGF1dG9sb2FkZXIgdG8gZmV0Y2ggdGhlIGJvb3RzdHJhcCBjbGFzc2VzIGluIGEgZmxleGlibGUgd2F5LgogKi8KZnVuY3Rpb24gcHJlcGFyZV9ib290c3RyYXAoKSB7CglyZXF1aXJlX29uY2UgV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvQXV0b2xvYWRlci5waHAnOwoKCSRhdXRvbG9hZGVyID0gbmV3IEF1dG9sb2FkZXIoKTsKCgkkYXV0b2xvYWRlci0+YWRkX25hbWVzcGFjZSgKCQknV1BfQ0xJXEJvb3RzdHJhcCcsCgkJV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvQm9vdHN0cmFwJwoJKS0+cmVnaXN0ZXIoKTsKfQoKLyoqCiAqIEluaXRpYWxpemUgYW5kIHJldHVybiB0aGUgYm9vdHN0cmFwIHN0YXRlIHRvIHBhc3MgZnJvbSBzdGVwIHRvIHN0ZXAuCiAqCiAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUKICovCmZ1bmN0aW9uIGluaXRpYWxpemVfYm9vdHN0cmFwX3N0YXRlKCkgewoJcmV0dXJuIG5ldyBCb290c3RyYXBTdGF0ZSgpOwp9CgovKioKICogUHJvY2VzcyB0aGUgYm9vdHN0cmFwcGluZyBzdGVwcy4KICoKICogTG9vcHMgb3ZlciBlYWNoIG9mIHRoZSBwcm92aWRlZCBzdGVwcywgaW5zdGFudGlhdGVzIGl0IGFuZCB0aGVuIGNhbGxzIGl0cwogKiBgcHJvY2VzcygpYCBtZXRob2QuCiAqLwpmdW5jdGlvbiBib290c3RyYXAoKSB7CglwcmVwYXJlX2Jvb3RzdHJhcCgpOwoJJHN0YXRlID0gaW5pdGlhbGl6ZV9ib290c3RyYXBfc3RhdGUoKTsKCglmb3JlYWNoICggZ2V0X2Jvb3RzdHJhcF9zdGVwcygpIGFzICRzdGVwICkgewoJCS8qKiBAdmFyIEJvb3RzdHJhcFN0ZXAgJHN0ZXBfaW5zdGFuY2UgKi8KCQkkc3RlcF9pbnN0YW5jZSA9IG5ldyAkc3RlcCgpOwoJCSRzdGF0ZSAgICAgICAgID0gJHN0ZXBfaW5zdGFuY2UtPnByb2Nlc3MoICRzdGF0ZSApOwoJfQp9Cjw/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+IHRydWUsCgkJJ2RlZmF1bHQnICA9PiBbXSwKCV0sCgoJJ2NvbnRleHQnICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICc9PGNvbnRleHQ+JywKCQknZmlsZScgICAgPT4gJzxjb250ZXh0PicsCgkJJ2RlZmF1bHQnID0+ICdjbGknLAoJCSdkZXNjJyAgICA9PiAnTG9hZCBXb3JkUHJlc3MgaW4gYSBnaXZlbiBjb250ZXh0LicsCgldLAoKCSdkaXNhYmxlZF9jb21tYW5kcycgPT4gWwoJCSdmaWxlJyAgICA9PiAnPGxpc3Q+JywKCQknZGVmYXVsdCcgPT4gW10sCgkJJ2Rlc2MnICAgID0+ICcoU3ViKWNvbW1hbmRzIHRvIGRpc2FibGUuJywKCV0sCgoJJ2NvbG9yJyAgICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+IHRydWUsCgkJJ2ZpbGUnICAgID0+ICc8Ym9vbD4nLAoJCSdkZWZhdWx0JyA9PiAnYXV0bycsCgkJJ2Rlc2MnICAgID0+ICdXaGV0aGVyIHRvIGNvbG9yaXplIHRoZSBvdXRwdXQuJywKCV0sCgoJJ2RlYnVnJyAgICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICdbPTxncm91cD5dJywKCQknZmlsZScgICAgPT4gJzxncm91cD4nLAoJCSdkZWZhdWx0JyA9PiBmYWxzZSwKCQknZGVzYycgICAgPT4gJ1Nob3cgYWxsIFBIUCBlcnJvcnMgYW5kIGFkZCB2ZXJib3NpdHkgdG8gV1AtQ0xJIG91dHB1dC4gQnVpbHQtaW4gZ3JvdXBzIGluY2x1ZGU6IGJvb3RzdHJhcCwgY29tbWFuZGZhY3RvcnksIGFuZCBoZWxwLicsCgldLAoKCSdwcm9tcHQnICAgICAgICAgICAgPT4gWwoJCSdydW50aW1lJyA9PiAnWz08YXNzb2M+XScsCgkJJ2ZpbGUnICAgID0+IGZhbHNlLAoJCSdkZWZhdWx0JyA9PiBmYWxzZSwKCQknZGVzYycgICAgPT4gJ1Byb21wdCB0aGUgdXNlciB0byBlbnRlciB2YWx1ZXMgZm9yIGFsbCBjb21tYW5kIGFyZ3VtZW50cywgb3IgYSBzdWJzZXQgc3BlY2lmaWVkIGFzIGNvbW1hLXNlcGFyYXRlZCB2YWx1ZXMuJywKCV0sCgoJJ3F1aWV0JyAgICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICcnLAoJCSdmaWxlJyAgICA9PiAnPGJvb2w+JywKCQknZGVmYXVsdCcgPT4gZmFsc2UsCgkJJ2Rlc2MnICAgID0+ICdTdXBwcmVzcyBpbmZvcm1hdGlvbmFsIG1lc3NhZ2VzLicsCgldLAoKCSdhcGFjaGVfbW9kdWxlcycgICAgPT4gWwoJCSdmaWxlJyAgICAgPT4gJzxsaXN0PicsCgkJJ2Rlc2MnICAgICA9PiAnTGlzdCBvZiBBcGFjaGUgTW9kdWxlcyB0aGF0IGFyZSB0byBiZSByZXBvcnRlZCBhcyBsb2FkZWQuJywKCQknbXVsdGlwbGUnID0+IHRydWUsCgkJJ2RlZmF1bHQnICA9PiBbXSwKCV0sCgoJIyAtLWFsbG93LXJvb3QgPT4gKE5PVCBSRUNPTU1FTkRFRCkgQWxsb3cgd3AtY2xpIHRvIHJ1biBhcyByb290LiBUaGlzIHBvc2VzCgkjIGEgc2VjdXJpdHkgcmlzaywgc28geW91IHByb2JhYmx5IGRvIG5vdCB3YW50IHRvIGRvIHRoaXMuCgknYWxsb3ctcm9vdCcgICAgICAgID0+IFsKCQknZmlsZScgICAgPT4gZmFsc2UsICMgRXhwbGljaXQuIEp1c3QgaW4gY2FzZSB0aGUgZGVmYXVsdCBjaGFuZ2VzLgoJCSdydW50aW1lJyA9PiAnJywKCQknaGlkZGVuJyAgPT4gdHJ1ZSwKCV0sCgpdOwo8P3BocAoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIFdQLUNMSSBjb21tYW5kcwogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmFic3RyYWN0IGNsYXNzIFdQX0NMSV9Db21tYW5kIHsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7fQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKLyoqCiAqIEdldCB0aGUgcGF0aCB0byBhIGNvbW1hbmQsIGUuZy4gImNvcmUgZG93bmxvYWQiCiAqCiAqIEBwYXJhbSBTdWJjb21tYW5kfENvbXBvc2l0ZUNvbW1hbmQgJGNvbW1hbmQKICogQHJldHVybiBzdHJpbmdbXQogKi8KZnVuY3Rpb24gZ2V0X3BhdGgoICRjb21tYW5kICkgewoJJHBhdGggPSBbXTsKCglkbyB7CgkJYXJyYXlfdW5zaGlmdCggJHBhdGgsICRjb21tYW5kLT5nZXRfbmFtZSgpICk7Cgl9IHdoaWxlICggJGNvbW1hbmQgPSAkY29tbWFuZC0+Z2V0X3BhcmVudCgpICk7CgoJcmV0dXJuICRwYXRoOwp9Cgo8P3BocAoKLy8gVGhpcyBmaWxlIG5lZWRzIHRvIHBhcnNlIHdpdGhvdXQgZXJyb3IgaW4gUEhQIDwgNS4zCgppZiAoICdjbGknICE9PSBQSFBfU0FQSSApIHsKCWVjaG8gIk9ubHkgQ0xJIGFjY2Vzcy5cbiI7CglkaWUoIC0xICk7Cn0KCmlmICggdmVyc2lvbl9jb21wYXJlKCBQSFBfVkVSU0lPTiwgJzUuNi4wJywgJzwnICkgKSB7CglwcmludGYoICJFcnJvcjogV1AtQ0xJIHJlcXVpcmVzIFBIUCAlcyBvciBuZXdlci4gWW91IGFyZSBydW5uaW5nIHZlcnNpb24gJXMuXG4iLCAnNS42LjAnLCBQSFBfVkVSU0lPTiApOwoJZGllKCAtMSApOwp9CgpkZWZpbmUoICdXUF9DTElfUk9PVCcsIGRpcm5hbWUoIF9fRElSX18gKSApOwoKcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvd3AtY2xpLnBocCc7Cgo8P3BocAoKLyoqCiAqIE1hbmFnZXMgdGhlIGludGVybmFsIFdQLUNMSSBjYWNoZSwuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFJlbW92ZSBhbGwgY2FjaGVkIGZpbGVzLgogKiAgICAgJCB3cCBjbGkgY2FjaGUgY2xlYXIKICogICAgIFN1Y2Nlc3M6IENhY2hlIGNsZWFyZWQuCiAqCiAqICAgICAjIFJlbW92ZSBhbGwgY2FjaGVkIGZpbGVzIGV4Y2VwdCBmb3IgdGhlIG5ld2VzdCB2ZXJzaW9uIG9mIGVhY2ggb25lLgogKiAgICAgJCB3cCBjbGkgY2FjaGUgcHJ1bmUKICogICAgIFN1Y2Nlc3M6IENhY2hlIHBydW5lZC4KICoKICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKICovCmNsYXNzIENMSV9DYWNoZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogQ2xlYXJzIHRoZSBpbnRlcm5hbCBjYWNoZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGNsaSBjYWNoZSBjbGVhcgoJICogICAgIFN1Y2Nlc3M6IENhY2hlIGNsZWFyZWQuCgkgKgoJICogQHN1YmNvbW1hbmQgY2xlYXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNhY2hlX2NsZWFyKCkgewoJCSRjYWNoZSA9IFdQX0NMSTo6Z2V0X2NhY2hlKCk7CgoJCWlmICggISAkY2FjaGUtPmlzX2VuYWJsZWQoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0NhY2hlIGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdC4nICk7CgkJfQoKCQkkY2FjaGUtPmNsZWFyKCk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0NhY2hlIGNsZWFyZWQuJyApOwoJfQoKCS8qKgoJICogUHJ1bmVzIHRoZSBpbnRlcm5hbCBjYWNoZS4KCSAqCgkgKiBSZW1vdmVzIGFsbCBjYWNoZWQgZmlsZXMgZXhjZXB0IGZvciB0aGUgbmV3ZXN0IHZlcnNpb24gb2YgZWFjaCBvbmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBjbGkgY2FjaGUgcHJ1bmUKCSAqICAgICBTdWNjZXNzOiBDYWNoZSBwcnVuZWQuCgkgKgoJICogQHN1YmNvbW1hbmQgcHJ1bmUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNhY2hlX3BydW5lKCkgewoJCSRjYWNoZSA9IFdQX0NMSTo6Z2V0X2NhY2hlKCk7CgoJCWlmICggISAkY2FjaGUtPmlzX2VuYWJsZWQoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0NhY2hlIGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdC4nICk7CgkJfQoKCQkkY2FjaGUtPnBydW5lKCk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0NhY2hlIHBydW5lZC4nICk7Cgl9Cn0KPD9waHAKCi8qKgogKiBSZXRyaWV2ZXMsIHNldHMgYW5kIHVwZGF0ZXMgYWxpYXNlcyBmb3IgV29yZFByZXNzIEluc3RhbGxhdGlvbnMuCiAqLwoKdXNlIE11c3Rhbmdvc3RhbmdcU3B5YzsKdXNlIFdQX0NMSVxFeGl0RXhjZXB0aW9uOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIFJldHJpZXZlcywgc2V0cyBhbmQgdXBkYXRlcyBhbGlhc2VzIGZvciBXb3JkUHJlc3MgSW5zdGFsbGF0aW9ucy4KICoKICogQWxpYXNlcyBhcmUgc2hvcnRoYW5kIHJlZmVyZW5jZXMgdG8gV29yZFByZXNzIGluc3RhbGxzLiBGb3IgaW5zdGFuY2UsCiAqIGBAZGV2YCBjb3VsZCByZWZlciB0byBhIGRldmVsb3BtZW50IGluc3RhbGwgYW5kIGBAcHJvZGAgY291bGQgcmVmZXIgdG8gYSBwcm9kdWN0aW9uIGluc3RhbGwuCiAqIFRoaXMgY29tbWFuZCBnaXZlcyB5b3UgYW5kIG9wdGlvbiB0byBhZGQsIHVwZGF0ZSBhbmQgZGVsZXRlLCB0aGUgcmVnaXN0ZXJlZCBhbGlhc2VzIHlvdSBoYXZlIGF2YWlsYWJsZS4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgTGlzdCBhbGlhcyBpbmZvcm1hdGlvbi4KICogICAgICQgd3AgY2xpIGFsaWFzIGxpc3QKICogICAgIGxpc3QKICogICAgIC0tLQogKiAgICAgQGFsbDogUnVuIGNvbW1hbmQgYWdhaW5zdCBldmVyeSByZWdpc3RlcmVkIGFsaWFzLgogKiAgICAgQGxvY2FsOgogKiAgICAgICB1c2VyOiB3cGNsaQogKiAgICAgICBwYXRoOiAvVXNlcnMvd3BjbGkvc2l0ZXMvdGVzdHNpdGUKICoKICogICAgICMgR2V0IGFsaWFzIGluZm9ybWF0aW9uLgogKiAgICAgJCB3cCBjbGkgYWxpYXMgZ2V0IEBkZXYKICogICAgIHNzaDogZGV2QHNvbWVkZXZlLmVudjoxMjM0NS9ob21lL2Rldi8KICoKICogICAgICMgQWRkIGFsaWFzLgogKiAgICAgJCB3cCBjbGkgYWxpYXMgYWRkIEBwcm9kIC0tc2V0LXNzaD1sb2dpbkBob3N0IC0tc2V0LXBhdGg9L3BhdGgvdG8vd29yZHByZXNzL2luc3RhbGwvIC0tc2V0LXVzZXI9d3BjbGkKICogICAgIFN1Y2Nlc3M6IEFkZGVkICdAcHJvZCcgYWxpYXMuCiAqCiAqICAgICAjIFVwZGF0ZSBhbGlhcy4KICogICAgICQgd3AgY2xpIGFsaWFzIHVwZGF0ZSBAcHJvZCAtLXNldC11c2VyPW5ld3VzZXIgLS1zZXQtcGF0aD0vbmV3L3BhdGgvdG8vd29yZHByZXNzL2luc3RhbGwvCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdwcm9kJyBhbGlhcy4KICoKICogICAgICMgRGVsZXRlIGFsaWFzLgogKiAgICAgJCB3cCBjbGkgYWxpYXMgZGVsZXRlIEBwcm9kCiAqICAgICBTdWNjZXNzOiBEZWxldGVkICdAcHJvZCcgYWxpYXMuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKiBAd2hlbiAgICBiZWZvcmVfd3BfbG9hZAogKi8KY2xhc3MgQ0xJX0FsaWFzX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBMaXN0cyBhdmFpbGFibGUgV1AtQ0xJIGFsaWFzZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB5YW1sCgkgKiBvcHRpb25zOgoJICogICAtIHlhbWwKCSAqICAgLSBqc29uCgkgKiAgIC0gdmFyX2V4cG9ydAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGFsbCBhdmFpbGFibGUgYWxpYXNlcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBsaXN0CgkgKiAgICAgLS0tCgkgKiAgICAgQGFsbDogUnVuIGNvbW1hbmQgYWdhaW5zdCBldmVyeSByZWdpc3RlcmVkIGFsaWFzLgoJICogICAgIEBwcm9kOgoJICogICAgICAgc3NoOiBydW5jb21tYW5kQHJ1bmNvbW1hbmQuaW9+L3dlYmFwcHMvcHJvZHVjdGlvbgoJICogICAgIEBkZXY6CgkgKiAgICAgICBzc2g6IHZhZ3JhbnRAMTkyLjE2OC41MC4xMC9zcnYvd3d3L3J1bmNvbW1hbmQuZGV2CgkgKiAgICAgQGJvdGg6CgkgKiAgICAgICAtIEBwcm9kCgkgKiAgICAgICAtIEBkZXYKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoIFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5hbGlhc2VzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgdmFsdWUgZm9yIGFuIGFsaWFzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBLZXkgZm9yIHRoZSBhbGlhcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBhbGlhcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBnZXQgQHByb2QKCSAqICAgICBzc2g6IGRldkBzb21lZGV2ZS5lbnY6MTIzNDUvaG9tZS9kZXYvCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkYWxpYXMgKSA9ICRhcmdzOwoKCQkkYWxpYXNlcyA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5hbGlhc2VzOwoKCQlpZiAoIGVtcHR5KCAkYWxpYXNlc1sgJGFsaWFzIF0gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIk5vIGFsaWFzIGZvdW5kIHdpdGgga2V5ICd7JGFsaWFzfScuIiApOwoJCX0KCgkJZm9yZWFjaCAoICRhbGlhc2VzWyAkYWxpYXMgXSBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJV1BfQ0xJOjpsb2coICJ7JGtleX06IHskdmFsdWV9IiApOwoJCX0KCX0KCgkvKioKCSAqIENyZWF0ZXMgYW4gYWxpYXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IEtleSBmb3IgdGhlIGFsaWFzLgoJICoKCSAqIFstLXNldC11c2VyPTx1c2VyPl0KCSAqIDogU2V0IHVzZXIgZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC11cmw9PHVybD5dCgkgKiA6IFNldCB1cmwgZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC1wYXRoPTxwYXRoPl0KCSAqIDogU2V0IHBhdGggZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC1zc2g9PHNzaD5dCgkgKiA6IFNldCBzc2ggZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC1odHRwPTxodHRwPl0KCSAqIDogU2V0IGh0dHAgZm9yIGFsaWFzLgoJICoKCSAqIFstLWdyb3VwaW5nPTxncm91cGluZz5dCgkgKiA6IEZvciBncm91cGluZyBtdWx0aXBsZSBhbGlhc2VzLgoJICoKCSAqIFstLWNvbmZpZz08Y29uZmlnPl0KCSAqIDogQ29uZmlnIGZpbGUgdG8gYmUgY29uc2lkZXJlZCBmb3Igb3BlcmF0aW9ucy4KCSAqIC0tLQoJICogZGVmYXVsdDogZ2xvYmFsCgkgKiBvcHRpb25zOgoJICogICAtIGdsb2JhbAoJICogICAtIHByb2plY3QKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQWRkIGFsaWFzIHRvIGdsb2JhbCBjb25maWcuCgkgKiAgICAgJCB3cCBjbGkgYWxpYXMgYWRkIEBwcm9kICAtLXNldC1zc2g9bG9naW5AaG9zdCAtLXNldC1wYXRoPS9wYXRoL3RvL3dvcmRwcmVzcy9pbnN0YWxsLyAtLXNldC11c2VyPXdwY2xpCgkgKiAgICAgU3VjY2VzczogQWRkZWQgJ0Bwcm9kJyBhbGlhcy4KCSAqCgkgKiAgICAgIyBBZGQgYWxpYXMgdG8gcHJvamVjdCBjb25maWcuCgkgKiAgICAgJCB3cCBjbGkgYWxpYXMgYWRkIEBwcm9kIC0tc2V0LXNzaD1sb2dpbkBob3N0IC0tc2V0LXBhdGg9L3BhdGgvdG8vd29yZHByZXNzL2luc3RhbGwvIC0tc2V0LXVzZXI9d3BjbGkgLS1jb25maWc9cHJvamVjdAoJICogICAgIFN1Y2Nlc3M6IEFkZGVkICdAcHJvZCcgYWxpYXMuCgkgKgoJICogICAgICMgQWRkIGdyb3VwIG9mIGFsaWFzZXMuCgkgKiAgICAgJCB3cCBjbGkgYWxpYXMgYWRkIEBtdWx0aXNlcnZlcnMgLS1ncm91cGluZz1zZXJ2ZXJhLHNlcnZlcmIKCSAqICAgICBTdWNjZXNzOiBBZGRlZCAnQG11bHRpc2VydmVycycgYWxpYXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbmZpZyA9ICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2NvbmZpZyddICkgPyAkYXNzb2NfYXJnc1snY29uZmlnJ10gOiAnZ2xvYmFsJyApOwoKCQlsaXN0KCAkY29uZmlnX3BhdGgsICRhbGlhc2VzICkgPSAkdGhpcy0+Z2V0X2FsaWFzZXNfZGF0YSggJGNvbmZpZywgJycsIHRydWUgKTsKCgkJJHRoaXMtPnZhbGlkYXRlX2NvbmZpZ19maWxlKCAkY29uZmlnX3BhdGggKTsKCgkJJGFsaWFzICAgID0gJGFyZ3NbMF07CgkJJGdyb3VwaW5nID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZ3JvdXBpbmcnICk7CgoJCSR0aGlzLT52YWxpZGF0ZV9pbnB1dCggJGFzc29jX2FyZ3MsICRncm91cGluZyApOwoKCQlpZiAoIGlzc2V0KCAkYWxpYXNlc1sgJGFsaWFzIF0gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIktleSAneyRhbGlhc30nIGV4aXN0cyBhbHJlYWR5LiIgKTsKCQl9CgoJCWlmICggbnVsbCA9PT0gJGdyb3VwaW5nICkgewoJCQkkYWxpYXNlcyA9ICR0aGlzLT5idWlsZF9hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkYXNzb2NfYXJncywgZmFsc2UgKTsKCQl9IGVsc2UgewoJCQkkYWxpYXNlcyA9ICR0aGlzLT5idWlsZF9hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkYXNzb2NfYXJncywgdHJ1ZSwgJGdyb3VwaW5nICk7CgkJfQoKCQkkdGhpcy0+cHJvY2Vzc19hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkY29uZmlnX3BhdGgsICdBZGRlZCcgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgYW4gYWxpYXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IEtleSBmb3IgdGhlIGFsaWFzLgoJICoKCSAqIFstLWNvbmZpZz08Y29uZmlnPl0KCSAqIDogQ29uZmlnIGZpbGUgdG8gYmUgY29uc2lkZXJlZCBmb3Igb3BlcmF0aW9ucy4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBnbG9iYWwKCSAqICAgLSBwcm9qZWN0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSBhbGlhcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBkZWxldGUgQHByb2QKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICdAcHJvZCcgYWxpYXMuCgkgKgoJICogICAgICMgRGVsZXRlIHByb2plY3QgYWxpYXMuCgkgKiAgICAgJCB3cCBjbGkgYWxpYXMgZGVsZXRlIEBwcm9kIC0tY29uZmlnPXByb2plY3QKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICdAcHJvZCcgYWxpYXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJGFsaWFzICkgPSAkYXJnczsKCgkJJGNvbmZpZyA9ICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2NvbmZpZyddICkgPyAkYXNzb2NfYXJnc1snY29uZmlnJ10gOiAnJyApOwoKCQlsaXN0KCAkY29uZmlnX3BhdGgsICRhbGlhc2VzICkgPSAkdGhpcy0+Z2V0X2FsaWFzZXNfZGF0YSggJGNvbmZpZywgJGFsaWFzICk7CgoJCSR0aGlzLT52YWxpZGF0ZV9jb25maWdfZmlsZSggJGNvbmZpZ19wYXRoICk7CgoJCWlmICggZW1wdHkoICRhbGlhc2VzWyAkYWxpYXMgXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiTm8gYWxpYXMgZm91bmQgd2l0aCBrZXkgJ3skYWxpYXN9Jy4iICk7CgkJfQoKCQl1bnNldCggJGFsaWFzZXNbICRhbGlhcyBdICk7CgkJJHRoaXMtPnByb2Nlc3NfYWxpYXNlcyggJGFsaWFzZXMsICRhbGlhcywgJGNvbmZpZ19wYXRoLCAnRGVsZXRlZCcgKTsKCgl9CgoJLyoqCgkgKiBVcGRhdGVzIGFuIGFsaWFzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBLZXkgZm9yIHRoZSBhbGlhcy4KCSAqCgkgKiBbLS1zZXQtdXNlcj08dXNlcj5dCgkgKiA6IFNldCB1c2VyIGZvciBhbGlhcy4KCSAqCgkgKiBbLS1zZXQtdXJsPTx1cmw+XQoJICogOiBTZXQgdXJsIGZvciBhbGlhcy4KCSAqCgkgKiBbLS1zZXQtcGF0aD08cGF0aD5dCgkgKiA6IFNldCBwYXRoIGZvciBhbGlhcy4KCSAqCgkgKiBbLS1zZXQtc3NoPTxzc2g+XQoJICogOiBTZXQgc3NoIGZvciBhbGlhcy4KCSAqCgkgKiBbLS1zZXQtaHR0cD08aHR0cD5dCgkgKiA6IFNldCBodHRwIGZvciBhbGlhcy4KCSAqCgkgKiBbLS1ncm91cGluZz08Z3JvdXBpbmc+XQoJICogOiBGb3IgZ3JvdXBpbmcgbXVsdGlwbGUgYWxpYXNlcy4KCSAqCgkgKiBbLS1jb25maWc9PGNvbmZpZz5dCgkgKiA6IENvbmZpZyBmaWxlIHRvIGJlIGNvbnNpZGVyZWQgZm9yIG9wZXJhdGlvbnMuCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0gZ2xvYmFsCgkgKiAgIC0gcHJvamVjdAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgYWxpYXMuCgkgKiAgICAgJCB3cCBjbGkgYWxpYXMgdXBkYXRlIEBwcm9kIC0tc2V0LXVzZXI9bmV3dXNlciAtLXNldC1wYXRoPS9uZXcvcGF0aC90by93b3JkcHJlc3MvaW5zdGFsbC8KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdwcm9kJyBhbGlhcy4KCSAqCgkgKiAgICAgIyBVcGRhdGUgcHJvamVjdCBhbGlhcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyB1cGRhdGUgQHByb2QgLS1zZXQtdXNlcj1uZXd1c2VyIC0tc2V0LXBhdGg9L25ldy9wYXRoL3RvL3dvcmRwcmVzcy9pbnN0YWxsLyAtLWNvbmZpZz1wcm9qZWN0CgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAncHJvZCcgYWxpYXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbmZpZyAgID0gKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snY29uZmlnJ10gKSA/ICRhc3NvY19hcmdzWydjb25maWcnXSA6ICcnICk7CgkJJGFsaWFzICAgID0gJGFyZ3NbMF07CgkJJGdyb3VwaW5nID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZ3JvdXBpbmcnICk7CgoJCWxpc3QoICRjb25maWdfcGF0aCwgJGFsaWFzZXMgKSA9ICR0aGlzLT5nZXRfYWxpYXNlc19kYXRhKCAkY29uZmlnLCAkYWxpYXMsIHRydWUgKTsKCgkJJHRoaXMtPnZhbGlkYXRlX2NvbmZpZ19maWxlKCAkY29uZmlnX3BhdGggKTsKCgkJJHRoaXMtPnZhbGlkYXRlX2lucHV0KCAkYXNzb2NfYXJncywgJGdyb3VwaW5nICk7CgoJCWlmICggZW1wdHkoICRhbGlhc2VzWyAkYWxpYXMgXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiTm8gYWxpYXMgZm91bmQgd2l0aCBrZXkgJ3skYWxpYXN9Jy4iICk7CgkJfQoKCQlpZiAoIG51bGwgPT09ICRncm91cGluZyApIHsKCQkJJGFsaWFzZXMgPSAkdGhpcy0+YnVpbGRfYWxpYXNlcyggJGFsaWFzZXMsICRhbGlhcywgJGFzc29jX2FyZ3MsIGZhbHNlLCAnJywgdHJ1ZSApOwoJCX0gZWxzZSB7CgkJCSRhbGlhc2VzID0gJHRoaXMtPmJ1aWxkX2FsaWFzZXMoICRhbGlhc2VzLCAkYWxpYXMsICRhc3NvY19hcmdzLCB0cnVlLCAkZ3JvdXBpbmcsIHRydWUgKTsKCQl9CgoJCSR0aGlzLT5wcm9jZXNzX2FsaWFzZXMoICRhbGlhc2VzLCAkYWxpYXMsICRjb25maWdfcGF0aCwgJ1VwZGF0ZWQnICk7Cgl9CgoJLyoqCgkgKiBHZXQgY29uZmlnIHBhdGggYW5kIGFsaWFzZXMgZGF0YSBiYXNlZCBvbiBjb25maWcgdHlwZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb25maWcgICAgICAgICAgICAgVHlwZSBvZiBjb25maWcgdG8gZ2V0IGRhdGEgZnJvbS4KCSAqIEBwYXJhbSBzdHJpbmcgJGFsaWFzICAgICAgICAgICAgICBBbGlhcyB0byBiZSB1c2VkIGZvciBBZGQvVXBkYXRlL0RlbGV0ZS4KCSAqIEBwYXJhbSBib29sICAgJGNyZWF0ZV9jb25maWdfZmlsZSBPcHRpb25hbC4gSWYgYSBjb25maWcgZmlsZSBkb2Vzbid0IGV4aXN0LAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBpdCBiZSBjcmVhdGVkPyBEZWZhdWx0cyB0byBmYWxzZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IENvbmZpZyBQYXRoIGFuZCBBbGlhc2VzIGluIGl0LgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2FsaWFzZXNfZGF0YSggJGNvbmZpZywgJGFsaWFzLCAkY3JlYXRlX2NvbmZpZ19maWxlID0gZmFsc2UgKSB7CgoJCSRnbG9iYWxfY29uZmlnX3BhdGggPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Z2V0X2dsb2JhbF9jb25maWdfcGF0aCggJGNyZWF0ZV9jb25maWdfZmlsZSApOwoJCSRnbG9iYWxfYWxpYXNlcyAgICAgPSBTcHljOjpZQU1MTG9hZCggJGdsb2JhbF9jb25maWdfcGF0aCApOwoKCQkkcHJvamVjdF9jb25maWdfcGF0aCA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5nZXRfcHJvamVjdF9jb25maWdfcGF0aCgpOwoJCSRwcm9qZWN0X2FsaWFzZXMgICAgID0gU3B5Yzo6WUFNTExvYWQoICRwcm9qZWN0X2NvbmZpZ19wYXRoICk7CgoJCWlmICggJ2dsb2JhbCcgPT09ICRjb25maWcgKSB7CgkJCSRjb25maWdfcGF0aCA9ICRnbG9iYWxfY29uZmlnX3BhdGg7CgkJCSRhbGlhc2VzICAgICA9ICRnbG9iYWxfYWxpYXNlczsKCQl9IGVsc2VpZiAoICdwcm9qZWN0JyA9PT0gJGNvbmZpZyApIHsKCQkJJGNvbmZpZ19wYXRoID0gJHByb2plY3RfY29uZmlnX3BhdGg7CgkJCSRhbGlhc2VzICAgICA9ICRwcm9qZWN0X2FsaWFzZXM7CgkJfSBlbHNlIHsKCgkJCSRpc19nbG9iYWxfYWxpYXMgID0gYXJyYXlfa2V5X2V4aXN0cyggJGFsaWFzLCAkZ2xvYmFsX2FsaWFzZXMgKTsKCQkJJGlzX3Byb2plY3RfYWxpYXMgPSBhcnJheV9rZXlfZXhpc3RzKCAkYWxpYXMsICRwcm9qZWN0X2FsaWFzZXMgKTsKCgkJCWlmICggJGlzX2dsb2JhbF9hbGlhcyAmJiAkaXNfcHJvamVjdF9hbGlhcyApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJLZXkgJ3skYWxpYXN9JyBmb3VuZCBpbiBtb3JlIHRoYW4gb25lIHBhdGguIFBsZWFzZSBwYXNzIC0tY29uZmlnIHBhcmFtLiIgKTsKCQkJfSBlbHNlaWYgKCAkaXNfZ2xvYmFsX2FsaWFzICkgewoJCQkJJGNvbmZpZ19wYXRoID0gJGdsb2JhbF9jb25maWdfcGF0aDsKCQkJCSRhbGlhc2VzICAgICA9ICRnbG9iYWxfYWxpYXNlczsKCQkJfSBlbHNlIHsKCQkJCSRjb25maWdfcGF0aCA9ICRwcm9qZWN0X2NvbmZpZ19wYXRoOwoJCQkJJGFsaWFzZXMgICAgID0gJHByb2plY3RfYWxpYXNlczsKCQkJfQoJCX0KCgkJcmV0dXJuIFsgJGNvbmZpZ19wYXRoLCAkYWxpYXNlcyBdOwoKCX0KCgkvKioKCSAqIENoZWNrIGlmIHRoZSBjb25maWcgZmlsZSBleGlzdHMgYW5kIGlzIHdyaXRhYmxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZ19wYXRoIFBhdGggdG8gY29uZmlnIGZpbGUuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVfY29uZmlnX2ZpbGUoICRjb25maWdfcGF0aCApIHsKCQlpZiAoICEgZmlsZV9leGlzdHMoICRjb25maWdfcGF0aCApIHx8ICEgaXNfd3JpdGFibGUoICRjb25maWdfcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ29uZmlnIGZpbGUgZG9lcyBub3QgZXhpc3Q6IHskY29uZmlnX3BhdGh9IiApOwoJCX0KCX0KCgkvKioKCSAqIFJldHVybiBhbGlhc2VzIGFycmF5LgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGFsaWFzZXMgICAgIEN1cnJlbnQgYWxpYXNlcyBkYXRhLgoJICogQHBhcmFtIHN0cmluZyAkYWxpYXMgICAgICAgTmFtZSBvZiBhbGlhcy4KCSAqIEBwYXJhbSBhcnJheSAgJGFzc29jX2FyZ3MgIEFzc29jaWF0aXZlIGFyZ3VtZW50cy4KCSAqIEBwYXJhbSBib29sICAgJGlzX2dyb3VwaW5nIENoZWNrIGlmIGl0cyBhIGdyb3VwaW5nIG9wZXJhdGlvbi4KCSAqIEBwYXJhbSBzdHJpbmcgJGdyb3VwaW5nICAgIEdyb3VwaW5nIHZhbHVlLgoJICogQHBhcmFtIGJvb2wgICAkaXNfdXBkYXRlICAgSXMgdGhpcyBhbiB1cGRhdGUgb3BlcmF0aW9uPwoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBidWlsZF9hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkYXNzb2NfYXJncywgJGlzX2dyb3VwaW5nLCAkZ3JvdXBpbmcgPSAnJywgJGlzX3VwZGF0ZSA9IGZhbHNlICkgewoKCQlpZiAoICRpc19ncm91cGluZyApIHsKCQkJJHZhbGlkX2Fzc29jX2FyZ3MgPSBbICdjb25maWcnLCAnZ3JvdXBpbmcnIF07CgkJCSRpbnZhbGlkX2FyZ3MgICAgID0gYXJyYXlfZGlmZiggYXJyYXlfa2V5cyggJGFzc29jX2FyZ3MgKSwgJHZhbGlkX2Fzc29jX2FyZ3MgKTsKCgkJCS8vIENoZWNrIGZvciBpbnZhbGlkIGFyZ3MuCgkJCWlmICggISBlbXB0eSggJGludmFsaWRfYXJncyApICkgewoJCQkJJGFyZ3NfaW5mbyA9IGltcGxvZGUoICcsJywgJGludmFsaWRfYXJncyApOwoJCQkJV1BfQ0xJOjplcnJvciggIi0tZ3JvdXBpbmcgYXJndW1lbnQgd29ya3MgYWxvbmUuIEZvdW5kIGludmFsaWQgYXJnKHMpICckYXJnc19pbmZvJy4iICk7CgkJCX0KCQl9CgoJCWlmICggJGlzX3VwZGF0ZSApIHsKCQkJJHRoaXMtPnZhbGlkYXRlX2FsaWFzX3R5cGUoICRhbGlhc2VzLCAkYWxpYXMsICRhc3NvY19hcmdzLCAkZ3JvdXBpbmcgKTsKCQl9CgoJCWlmICggISAkaXNfZ3JvdXBpbmcgKSB7CgkJCWZvcmVhY2ggKCAkYXNzb2NfYXJncyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCWlmICggc3RycG9zKCAka2V5LCAnc2V0LScgKSAhPT0gZmFsc2UgKSB7CgkJCQkJJGFsaWFzX2tleV9pbmZvID0gZXhwbG9kZSggJy0nLCAka2V5ICk7CgkJCQkJJGFsaWFzX2tleSAgICAgID0gZW1wdHkoICRhbGlhc19rZXlfaW5mb1sxXSApID8gJycgOiAkYWxpYXNfa2V5X2luZm9bMV07CgkJCQkJaWYgKCAhIGVtcHR5KCAkYWxpYXNfa2V5ICkgJiYgISBlbXB0eSggJHZhbHVlICkgKSB7CgkJCQkJCSRhbGlhc2VzWyAkYWxpYXMgXVsgJGFsaWFzX2tleSBdID0gJHZhbHVlOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgoJCQlpZiAoICEgZW1wdHkoICRncm91cGluZyApICkgewoJCQkJJGdyb3VwX2FsaWFzX2xpc3QgID0gZXhwbG9kZSggJywnLCAkZ3JvdXBpbmcgKTsKCQkJCSRncm91cF9hbGlhcyAgICAgICA9IGFycmF5X21hcCgKCQkJCQlmdW5jdGlvbiAoICRjdXJyZW50X2FsaWFzICkgewoJCQkJCQlyZXR1cm4gJ0AnIC4gbHRyaW0oICRjdXJyZW50X2FsaWFzLCAnQCcgKTsKCQkJCQl9LAoJCQkJCSRncm91cF9hbGlhc19saXN0CgkJCQkpOwoJCQkJJGFsaWFzZXNbICRhbGlhcyBdID0gJGdyb3VwX2FsaWFzOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGFsaWFzZXM7Cgl9CgoJLyoqCgkgKiBWYWxpZGF0ZSBpbnB1dCBvZiBwYXNzZWQgYXJndW1lbnRzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGFzc29jX2FyZ3MgQXJndW1lbnRzIGFycmF5LgoJICogQHBhcmFtIHN0cmluZyAkZ3JvdXBpbmcgICBHcm91cGluZyBhcmd1bWVudCB2YWx1ZS4KCSAqCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZV9pbnB1dCggJGFzc29jX2FyZ3MsICRncm91cGluZyApIHsKCQkvLyBDaGVjayBpZiB2YWxpZCBhcmd1bWVudHMgd2VyZSBwYXNzZWQuCgkJJGFyZ19tYXRjaCA9IHByZWdfZ3JlcCggJy9ec2V0LShcdyspL2knLCBhcnJheV9rZXlzKCAkYXNzb2NfYXJncyApICk7CgoJCS8vIFZlcmlmeSBwYXNzZWQtYXJndW1lbnRzLgoJCWlmICggZW1wdHkoICRncm91cGluZyApICYmIGVtcHR5KCAkYXJnX21hdGNoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyB2YWxpZCBhcmd1bWVudHMgcGFzc2VkLicgKTsKCQl9CgoJCS8vIENoZWNrIHdoZXRoZXIgcGFzc2VkIGFyZ3VtZW50cyBjb250YWluIHZhbHVlIG9yIG5vdC4KCQkkYXNzb2NfYXJnX3ZhbHVlcyA9IGFycmF5X2ZpbHRlciggYXJyYXlfaW50ZXJzZWN0X2tleSggJGFzc29jX2FyZ3MsIGFycmF5X2ZsaXAoICRhcmdfbWF0Y2ggKSApICk7CgoJCWlmICggZW1wdHkoICRncm91cGluZyApICYmIGVtcHR5KCAkYXNzb2NfYXJnX3ZhbHVlcyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gdmFsdWUgcGFzc2VkIHRvIGFyZ3VtZW50cy4nICk7CgkJfQoJfQoKCS8qKgoJICogVmFsaWRhdGUgYWxpYXMgdHlwZSBiZWZvcmUgdXBkYXRlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGFsaWFzZXMgICAgRXhpc3RpbmcgYWxpYXNlcyBkYXRhLgoJICogQHBhcmFtIHN0cmluZyAkYWxpYXMgICAgICBBbGlhcyBOYW1lLgoJICogQHBhcmFtIGFycmF5ICAkYXNzb2NfYXJncyBBcmd1bWVudHMgYXJyYXkuCgkgKiBAcGFyYW0gc3RyaW5nICRncm91cGluZyAgIEdyb3VwaW5nIGFyZ3VtZW50IHZhbHVlLgoJICoKCSAqIEB0aHJvd3MgRXhpdEV4Y2VwdGlvbgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlX2FsaWFzX3R5cGUoICRhbGlhc2VzLCAkYWxpYXMsICRhc3NvY19hcmdzLCAkZ3JvdXBpbmcgKSB7CgoJCSRhbGlhc19kYXRhID0gJGFsaWFzZXNbICRhbGlhcyBdOwoKCQkkZ3JvdXBfYWxpYXNlc19tYXRjaCA9IHByZWdfZ3JlcCggJy9eQChcdyspL2knLCAkYWxpYXNfZGF0YSApOwoJCSRhcmdfbWF0Y2ggICAgICAgICAgID0gcHJlZ19ncmVwKCAnL15zZXQtKFx3KykvaScsIGFycmF5X2tleXMoICRhc3NvY19hcmdzICkgKTsKCgkJaWYgKCAhIGVtcHR5KCAkZ3JvdXBfYWxpYXNlc19tYXRjaCApICYmICEgZW1wdHkoICRhcmdfbWF0Y2ggKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RyeWluZyB0byB1cGRhdGUgZ3JvdXAgYWxpYXMgd2l0aCBpbnZhbGlkIGFyZ3VtZW50cy4nICk7CgkJfSBlbHNlaWYgKCBlbXB0eSggJGdyb3VwX2FsaWFzZXNfbWF0Y2ggKSAmJiAhIGVtcHR5KCAkZ3JvdXBpbmcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RyeWluZyB0byB1cGRhdGUgc2ltcGxlIGFsaWFzIHdpdGggaW52YWxpZCAtLWdyb3VwaW5nIGFyZ3VtZW50LicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBTYXZlIGFsaWFzZXMgZGF0YSB0byBjb25maWcgZmlsZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRhbGlhc2VzICAgICBDdXJyZW50IGFsaWFzZXMgZGF0YS4KCSAqIEBwYXJhbSBzdHJpbmcgJGFsaWFzICAgICAgIE5hbWUgb2YgYWxpYXMuCgkgKiBAcGFyYW0gc3RyaW5nICRjb25maWdfcGF0aCBQYXRoIHRvIGNvbmZpZyBmaWxlLgoJICogQHBhcmFtIHN0cmluZyAkb3BlcmF0aW9uICAgQ3VycmVudCBvcGVyYXRpb24gc3RyaW5nIGZybyBtZXNzYWdlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHByb2Nlc3NfYWxpYXNlcyggJGFsaWFzZXMsICRhbGlhcywgJGNvbmZpZ19wYXRoLCAkb3BlcmF0aW9uID0gJycgKSB7CgkJLy8gQ29udmVydCBkYXRhIHRvIFlBTUwgc3RyaW5nLgoJCSR5YW1sX2RhdGEgPSBTcHljOjpZQU1MRHVtcCggJGFsaWFzZXMgKTsKCgkJLy8gQWRkIGRhdGEgaW4gY29uZmlnIGZpbGUuCgkJaWYgKCBmaWxlX3B1dF9jb250ZW50cyggJGNvbmZpZ19wYXRoLCAkeWFtbF9kYXRhICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIiRvcGVyYXRpb24gJ3skYWxpYXN9JyBhbGlhcy4iICk7CgkJfQoJfQp9Cjw/cGhwCgp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBhcmF0b3I7CnVzZSBXUF9DTElcQ29tcGxldGlvbnM7CnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFByb2Nlc3M7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogUmV2aWV3cyBjdXJyZW50IFdQLUNMSSBpbmZvLCBjaGVja3MgZm9yIHVwZGF0ZXMsIG9yIHZpZXdzIGRlZmluZWQgYWxpYXNlcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgRGlzcGxheSB0aGUgdmVyc2lvbiBjdXJyZW50bHkgaW5zdGFsbGVkLgogKiAgICAgJCB3cCBjbGkgdmVyc2lvbgogKiAgICAgV1AtQ0xJIDAuMjQuMQogKgogKiAgICAgIyBDaGVjayBmb3IgdXBkYXRlcyB0byBXUC1DTEkuCiAqICAgICAkIHdwIGNsaSBjaGVjay11cGRhdGUKICogICAgIFN1Y2Nlc3M6IFdQLUNMSSBpcyBhdCB0aGUgbGF0ZXN0IHZlcnNpb24uCiAqCiAqICAgICAjIFVwZGF0ZSBXUC1DTEkgdG8gdGhlIGxhdGVzdCBzdGFibGUgcmVsZWFzZS4KICogICAgICQgd3AgY2xpIHVwZGF0ZQogKiAgICAgWW91IGhhdmUgdmVyc2lvbiAwLjI0LjAuIFdvdWxkIHlvdSBsaWtlIHRvIHVwZGF0ZSB0byAwLjI0LjE/IFt5L25dIHkKICogICAgIERvd25sb2FkaW5nIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS93cC1jbGkvcmVsZWFzZXMvZG93bmxvYWQvdjAuMjQuMS93cC1jbGktMC4yNC4xLnBoYXIuLi4KICogICAgIE5ldyB2ZXJzaW9uIHdvcmtzLiBQcm9jZWVkaW5nIHRvIHJlcGxhY2UuCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIFdQLUNMSSB0byAwLjI0LjEuCiAqCiAqICAgICAjIENsZWFyIHRoZSBpbnRlcm5hbCBXUC1DTEkgY2FjaGUuCiAqICAgICAkIHdwIGNsaSBjYWNoZSBjbGVhcgogKiAgICAgU3VjY2VzczogQ2FjaGUgY2xlYXJlZC4KICoKICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKICovCmNsYXNzIENMSV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgZnVuY3Rpb24gY29tbWFuZF90b19hcnJheSggJGNvbW1hbmQgKSB7CgkJJGR1bXAgPSBbCgkJCSduYW1lJyAgICAgICAgPT4gJGNvbW1hbmQtPmdldF9uYW1lKCksCgkJCSdkZXNjcmlwdGlvbicgPT4gJGNvbW1hbmQtPmdldF9zaG9ydGRlc2MoKSwKCQkJJ2xvbmdkZXNjJyAgICA9PiAkY29tbWFuZC0+Z2V0X2xvbmdkZXNjKCksCgkJXTsKCgkJZm9yZWFjaCAoICRjb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSBhcyAkc3ViY29tbWFuZCApIHsKCQkJJGR1bXBbJ3N1YmNvbW1hbmRzJ11bXSA9ICR0aGlzLT5jb21tYW5kX3RvX2FycmF5KCAkc3ViY29tbWFuZCApOwoJCX0KCgkJaWYgKCBlbXB0eSggJGR1bXBbJ3N1YmNvbW1hbmRzJ10gKSApIHsKCQkJJGR1bXBbJ3N5bm9wc2lzJ10gPSAoc3RyaW5nKSAkY29tbWFuZC0+Z2V0X3N5bm9wc2lzKCk7CgkJfQoKCQlyZXR1cm4gJGR1bXA7Cgl9CgoJLyoqCgkgKiBQcmludHMgV1AtQ0xJIHZlcnNpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEaXNwbGF5IENMSSB2ZXJzaW9uLgoJICogICAgICQgd3AgY2xpIHZlcnNpb24KCSAqICAgICBXUC1DTEkgMC4yNC4xCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB2ZXJzaW9uKCkgewoJCVdQX0NMSTo6bGluZSggJ1dQLUNMSSAnIC4gV1BfQ0xJX1ZFUlNJT04gKTsKCX0KCgkvKioKCSAqIFByaW50cyB2YXJpb3VzIGRldGFpbHMgYWJvdXQgdGhlIFdQLUNMSSBlbnZpcm9ubWVudC4KCSAqCgkgKiBIZWxwZnVsIGZvciBkaWFnbm9zdGljIHB1cnBvc2VzLCB0aGlzIGNvbW1hbmQgc2hhcmVzOgoJICoKCSAqICogT1MgaW5mb3JtYXRpb24uCgkgKiAqIFNoZWxsIGluZm9ybWF0aW9uLgoJICogKiBQSFAgYmluYXJ5IHVzZWQuCgkgKiAqIFBIUCBiaW5hcnkgdmVyc2lvbi4KCSAqICogcGhwLmluaSBjb25maWd1cmF0aW9uIGZpbGUgdXNlZCAod2hpY2ggaXMgdHlwaWNhbGx5IGRpZmZlcmVudCB0aGFuIHdlYikuCgkgKiAqIFdQLUNMSSByb290IGRpcjogd2hlcmUgV1AtQ0xJIGlzIGluc3RhbGxlZCAoaWYgbm9uLVBoYXIgaW5zdGFsbCkuCgkgKiAqIFdQLUNMSSBnbG9iYWwgY29uZmlnOiB3aGVyZSB0aGUgZ2xvYmFsIGNvbmZpZyBZQU1MIGZpbGUgaXMgbG9jYXRlZC4KCSAqICogV1AtQ0xJIHByb2plY3QgY29uZmlnOiB3aGVyZSB0aGUgcHJvamVjdCBjb25maWcgWUFNTCBmaWxlIGlzIGxvY2F0ZWQuCgkgKiAqIFdQLUNMSSB2ZXJzaW9uOiBjdXJyZW50bHkgaW5zdGFsbGVkIHZlcnNpb24uCgkgKgoJICogU2VlIFtjb25maWcgZG9jc10oaHR0cHM6Ly93cC1jbGkub3JnL2NvbmZpZy8pIGZvciBtb3JlIGRldGFpbHMgb24gZ2xvYmFsCgkgKiBhbmQgcHJvamVjdCBjb25maWcgWUFNTCBmaWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGxpc3QKCSAqIG9wdGlvbnM6CgkgKiAgIC0gbGlzdAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzcGxheSB2YXJpb3VzIGRhdGEgYWJvdXQgdGhlIENMSSBlbnZpcm9ubWVudC4KCSAqICAgICAkIHdwIGNsaSBpbmZvCgkgKiAgICAgT1M6ICBMaW51eCA0LjEwLjAtNDItZ2VuZXJpYyAjNDZ+MTYuMDQuMS1VYnVudHUgU01QIE1vbiBEZWMgNCAxNTo1Nzo1OSBVVEMgMjAxNyB4ODZfNjQKCSAqICAgICBTaGVsbDogICAvdXNyL2Jpbi96c2gKCSAqICAgICBQSFAgYmluYXJ5OiAgL3Vzci9iaW4vcGhwCgkgKiAgICAgUEhQIHZlcnNpb246IDcuMS4xMi0xK3VidW50dTE2LjA0LjErZGViLnN1cnkub3JnKzEKCSAqICAgICBwaHAuaW5pIHVzZWQ6ICAgIC9ldGMvcGhwLzcuMS9jbGkvcGhwLmluaQoJICogICAgIFdQLUNMSSByb290IGRpcjogICAgcGhhcjovL3dwLWNsaS5waGFyCgkgKiAgICAgV1AtQ0xJIHBhY2thZ2VzIGRpcjogICAgL2hvbWUvcGVyc29uLy53cC1jbGkvcGFja2FnZXMvCgkgKiAgICAgV1AtQ0xJIGdsb2JhbCBjb25maWc6CgkgKiAgICAgV1AtQ0xJIHByb2plY3QgY29uZmlnOgoJICogICAgIFdQLUNMSSB2ZXJzaW9uOiAxLjUuMAoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5mbyggJF8sICRhc3NvY19hcmdzICkgewoJCS8vIHBocF91bmFtZSgpICRtb2RlIGFyZ3VtZW50IHdhcyBvbmx5IGFkZGVkIHdpdGggUEhQIDcuMCsuIEZhbGwgYmFjayB0bwoJCS8vIGVudGlyZSBzdHJpbmcgZm9yIG9sZGVyIHZlcnNpb25zLgoJCSRzeXN0ZW1fb3MgPSBQSFBfTUFKT1JfVkVSU0lPTiA8IDcKCQkJPyBwaHBfdW5hbWUoKQoJCQk6IHNwcmludGYoCgkJCQknJXMgJXMgJXMgJXMnLAoJCQkJcGhwX3VuYW1lKCAncycgKSwKCQkJCXBocF91bmFtZSggJ3InICksCgkJCQlwaHBfdW5hbWUoICd2JyApLAoJCQkJcGhwX3VuYW1lKCAnbScgKQoJCQkpOwoKCQkkc2hlbGwgPSBnZXRlbnYoICdTSEVMTCcgKTsKCQlpZiAoICEgJHNoZWxsICYmIFV0aWxzXGlzX3dpbmRvd3MoKSApIHsKCQkJJHNoZWxsID0gZ2V0ZW52KCAnQ29tU3BlYycgKTsKCQl9CgoJCSRwaHBfYmluID0gVXRpbHNcZ2V0X3BocF9iaW5hcnkoKTsKCgkJJHJ1bm5lciA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpOwoKCQkkcGFja2FnZXNfZGlyID0gJHJ1bm5lci0+Z2V0X3BhY2thZ2VzX2Rpcl9wYXRoKCk7CgkJaWYgKCAhIGlzX2RpciggJHBhY2thZ2VzX2RpciApICkgewoJCQkkcGFja2FnZXNfZGlyID0gbnVsbDsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApID09PSAnanNvbicgKSB7CgkJCSRpbmZvID0gWwoJCQkJJ3N5c3RlbV9vcycgICAgICAgICAgICAgICAgPT4gJHN5c3RlbV9vcywKCQkJCSdzaGVsbCcgICAgICAgICAgICAgICAgICAgID0+ICRzaGVsbCwKCQkJCSdwaHBfYmluYXJ5X3BhdGgnICAgICAgICAgID0+ICRwaHBfYmluLAoJCQkJJ3BocF92ZXJzaW9uJyAgICAgICAgICAgICAgPT4gUEhQX1ZFUlNJT04sCgkJCQkncGhwX2luaV91c2VkJyAgICAgICAgICAgICA9PiBnZXRfY2ZnX3ZhciggJ2NmZ19maWxlX3BhdGgnICksCgkJCQknbXlzcWxfYmluYXJ5X3BhdGgnICAgICAgICA9PiBVdGlsc1xnZXRfbXlzcWxfYmluYXJ5X3BhdGgoKSwKCQkJCSdteXNxbF92ZXJzaW9uJyAgICAgICAgICAgID0+IFV0aWxzXGdldF9teXNxbF92ZXJzaW9uKCksCgkJCQknc3FsX21vZGVzJyAgICAgICAgICAgICAgICA9PiBVdGlsc1xnZXRfc3FsX21vZGVzKCksCgkJCQknd3BfY2xpX2Rpcl9wYXRoJyAgICAgICAgICA9PiBXUF9DTElfUk9PVCwKCQkJCSd3cF9jbGlfdmVuZG9yX3BhdGgnICAgICAgID0+IFdQX0NMSV9WRU5ET1JfRElSLAoJCQkJJ3dwX2NsaV9waGFyX3BhdGgnICAgICAgICAgPT4gZGVmaW5lZCggJ1dQX0NMSV9QSEFSX1BBVEgnICkgPyBXUF9DTElfUEhBUl9QQVRIIDogJycsCgkJCQknd3BfY2xpX3BhY2thZ2VzX2Rpcl9wYXRoJyA9PiAkcGFja2FnZXNfZGlyLAoJCQkJJ2dsb2JhbF9jb25maWdfcGF0aCcgICAgICAgPT4gJHJ1bm5lci0+Z2xvYmFsX2NvbmZpZ19wYXRoLAoJCQkJJ3Byb2plY3RfY29uZmlnX3BhdGgnICAgICAgPT4gJHJ1bm5lci0+cHJvamVjdF9jb25maWdfcGF0aCwKCQkJCSd3cF9jbGlfdmVyc2lvbicgICAgICAgICAgID0+IFdQX0NMSV9WRVJTSU9OLAoJCQldOwoKCQkJV1BfQ0xJOjpsaW5lKCBqc29uX2VuY29kZSggJGluZm8gKSApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6bGluZSggIk9TOlx0IiAuICRzeXN0ZW1fb3MgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiU2hlbGw6XHQiIC4gJHNoZWxsICk7CgkJCVdQX0NMSTo6bGluZSggIlBIUCBiaW5hcnk6XHQiIC4gJHBocF9iaW4gKTsKCQkJV1BfQ0xJOjpsaW5lKCAiUEhQIHZlcnNpb246XHQiIC4gUEhQX1ZFUlNJT04gKTsKCQkJV1BfQ0xJOjpsaW5lKCAicGhwLmluaSB1c2VkOlx0IiAuIGdldF9jZmdfdmFyKCAnY2ZnX2ZpbGVfcGF0aCcgKSApOwoJCQlXUF9DTEk6OmxpbmUoICJNeVNRTCBiaW5hcnk6XHQiIC4gVXRpbHNcZ2V0X215c3FsX2JpbmFyeV9wYXRoKCkgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiTXlTUUwgdmVyc2lvbjpcdCIgLiBVdGlsc1xnZXRfbXlzcWxfdmVyc2lvbigpICk7CgkJCVdQX0NMSTo6bGluZSggIlNRTCBtb2RlczpcdCIgLiBpbXBsb2RlKCAnLCcsIFV0aWxzXGdldF9zcWxfbW9kZXMoKSApICk7CgkJCVdQX0NMSTo6bGluZSggIldQLUNMSSByb290IGRpcjpcdCIgLiBXUF9DTElfUk9PVCApOwoJCQlXUF9DTEk6OmxpbmUoICJXUC1DTEkgdmVuZG9yIGRpcjpcdCIgLiBXUF9DTElfVkVORE9SX0RJUiApOwoJCQlXUF9DTEk6OmxpbmUoICJXUF9DTEkgcGhhciBwYXRoOlx0IiAuICggZGVmaW5lZCggJ1dQX0NMSV9QSEFSX1BBVEgnICkgPyBXUF9DTElfUEhBUl9QQVRIIDogJycgKSApOwoJCQlXUF9DTEk6OmxpbmUoICJXUC1DTEkgcGFja2FnZXMgZGlyOlx0IiAuICRwYWNrYWdlc19kaXIgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiV1AtQ0xJIGdsb2JhbCBjb25maWc6XHQiIC4gJHJ1bm5lci0+Z2xvYmFsX2NvbmZpZ19wYXRoICk7CgkJCVdQX0NMSTo6bGluZSggIldQLUNMSSBwcm9qZWN0IGNvbmZpZzpcdCIgLiAkcnVubmVyLT5wcm9qZWN0X2NvbmZpZ19wYXRoICk7CgkJCVdQX0NMSTo6bGluZSggIldQLUNMSSB2ZXJzaW9uOlx0IiAuIFdQX0NMSV9WRVJTSU9OICk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2tzIHRvIHNlZSBpZiB0aGVyZSBpcyBhIG5ld2VyIHZlcnNpb24gb2YgV1AtQ0xJIGF2YWlsYWJsZS4KCSAqCgkgKiBRdWVyaWVzIHRoZSBHaXRodWIgcmVsZWFzZXMgQVBJLiBSZXR1cm5zIGF2YWlsYWJsZSB2ZXJzaW9ucyBpZiB0aGVyZSBhcmUKCSAqIHVwZGF0ZXMgYXZhaWxhYmxlLCBvciBzdWNjZXNzIG1lc3NhZ2UgaWYgdXNpbmcgdGhlIGxhdGVzdCByZWxlYXNlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1wYXRjaF0KCSAqIDogT25seSBsaXN0IHBhdGNoIHVwZGF0ZXMuCgkgKgoJICogWy0tbWlub3JdCgkgKiA6IE9ubHkgbGlzdCBtaW5vciB1cGRhdGVzLgoJICoKCSAqIFstLW1ham9yXQoJICogOiBPbmx5IGxpc3QgbWFqb3IgdXBkYXRlcy4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHVwZGF0ZS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4gRGVmYXVsdHMgdG8gdmVyc2lvbix1cGRhdGVfdHlwZSxwYWNrYWdlX3VybC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIGZvciB1cGRhdGUuCgkgKiAgICAgJCB3cCBjbGkgY2hlY2stdXBkYXRlCgkgKiAgICAgU3VjY2VzczogV1AtQ0xJIGlzIGF0IHRoZSBsYXRlc3QgdmVyc2lvbi4KCSAqCgkgKiAgICAgIyBDaGVjayBmb3IgdXBkYXRlIGFuZCBuZXcgdmVyc2lvbiBpcyBhdmFpbGFibGUuCgkgKiAgICAgJCB3cCBjbGkgY2hlY2stdXBkYXRlCgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCB2ZXJzaW9uIHwgdXBkYXRlX3R5cGUgfCBwYWNrYWdlX3VybCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCAwLjI0LjEgIHwgcGF0Y2ggICAgICAgfCBodHRwczovL2dpdGh1Yi5jb20vd3AtY2xpL3dwLWNsaS9yZWxlYXNlcy9kb3dubG9hZC92MC4yNC4xL3dwLWNsaS0wLjI0LjEucGhhciB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgY2hlY2stdXBkYXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjaGVja191cGRhdGUoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkdXBkYXRlcyA9ICR0aGlzLT5nZXRfdXBkYXRlcyggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCAkdXBkYXRlcyApIHsKCQkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoCgkJCQkkYXNzb2NfYXJncywKCQkJCVsgJ3ZlcnNpb24nLCAndXBkYXRlX3R5cGUnLCAncGFja2FnZV91cmwnIF0KCQkJKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHVwZGF0ZXMgKTsKCQl9IGVsc2VpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB8fCAndGFibGUnID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCSR1cGRhdGVfdHlwZSA9ICR0aGlzLT5nZXRfdXBkYXRlX3R5cGVfc3RyKCAkYXNzb2NfYXJncyApOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXUC1DTEkgaXMgYXQgdGhlIGxhdGVzdHskdXBkYXRlX3R5cGV9dmVyc2lvbi4iICk7CgkJfQoJfQoKCS8qKgoJICogVXBkYXRlcyBXUC1DTEkgdG8gdGhlIGxhdGVzdCByZWxlYXNlLgoJICoKCSAqIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gY2hlY2sgdGhlIHJlbGVhc2VzIEFQSSBmb3IgdGhlIG5ld2VzdCBzdGFibGUKCSAqIHZlcnNpb24sIGFuZCBwcm9tcHQgaWYgb25lIGlzIGF2YWlsYWJsZS4KCSAqCgkgKiBVc2UgYC0tc3RhYmxlYCB0byBpbnN0YWxsIG9yIHJlaW5zdGFsbCB0aGUgbGF0ZXN0IHN0YWJsZSB2ZXJzaW9uLgoJICoKCSAqIFVzZSBgLS1uaWdodGx5YCB0byBpbnN0YWxsIHRoZSBsYXRlc3QgYnVpbHQgdmVyc2lvbiBvZiB0aGUgbWFzdGVyIGJyYW5jaC4KCSAqIFdoaWxlIG5vdCByZWNvbW1lbmRlZCBmb3IgcHJvZHVjdGlvbiwgbmlnaHRseSBjb250YWlucyB0aGUgbGF0ZXN0IGFuZAoJICogZ3JlYXRlc3QsIGFuZCBzaG91bGQgYmUgc3RhYmxlIGVub3VnaCBmb3IgZGV2ZWxvcG1lbnQgYW5kIHN0YWdpbmcKCSAqIGVudmlyb25tZW50cy4KCSAqCgkgKiBPbmx5IHdvcmtzIGZvciB0aGUgUGhhciBpbnN0YWxsYXRpb24gbWVjaGFuaXNtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1wYXRjaF0KCSAqIDogT25seSBwZXJmb3JtIHBhdGNoIHVwZGF0ZXMuCgkgKgoJICogWy0tbWlub3JdCgkgKiA6IE9ubHkgcGVyZm9ybSBtaW5vciB1cGRhdGVzLgoJICoKCSAqIFstLW1ham9yXQoJICogOiBPbmx5IHBlcmZvcm0gbWFqb3IgdXBkYXRlcy4KCSAqCgkgKiBbLS1zdGFibGVdCgkgKiA6IFVwZGF0ZSB0byB0aGUgbGF0ZXN0IHN0YWJsZSByZWxlYXNlLiBTa2lwcyB1cGRhdGUgY2hlY2suCgkgKgoJICogWy0tbmlnaHRseV0KCSAqIDogVXBkYXRlIHRvIHRoZSBsYXRlc3QgYnVpbHQgdmVyc2lvbiBvZiB0aGUgbWFzdGVyIGJyYW5jaC4gUG90ZW50aWFsbHkgdW5zdGFibGUuCgkgKgoJICogWy0teWVzXQoJICogOiBEbyBub3QgcHJvbXB0IGZvciBjb25maXJtYXRpb24uCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSBDTEkuCgkgKiAgICAgJCB3cCBjbGkgdXBkYXRlCgkgKiAgICAgWW91IGhhdmUgdmVyc2lvbiAwLjI0LjAuIFdvdWxkIHlvdSBsaWtlIHRvIHVwZGF0ZSB0byAwLjI0LjE/IFt5L25dIHkKCSAqICAgICBEb3dubG9hZGluZyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS93cC1jbGkvd3AtY2xpL3JlbGVhc2VzL2Rvd25sb2FkL3YwLjI0LjEvd3AtY2xpLTAuMjQuMS5waGFyLi4uCgkgKiAgICAgTmV3IHZlcnNpb24gd29ya3MuIFByb2NlZWRpbmcgdG8gcmVwbGFjZS4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIFdQLUNMSSB0byAwLjI0LjEuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRfLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICEgVXRpbHNcaW5zaWRlX3BoYXIoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1lvdSBjYW4gb25seSBzZWxmLXVwZGF0ZSBQaGFyIGZpbGVzLicgKTsKCQl9CgoJCSRvbGRfcGhhciA9IHJlYWxwYXRoKCAkX1NFUlZFUlsnYXJndiddWzBdICk7CgoJCWlmICggISBpc193cml0YWJsZSggJG9sZF9waGFyICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICclcyBpcyBub3Qgd3JpdGFibGUgYnkgY3VycmVudCB1c2VyLicsICRvbGRfcGhhciApICk7CgkJfSBlbHNlaWYgKCAhIGlzX3dyaXRhYmxlKCBkaXJuYW1lKCAkb2xkX3BoYXIgKSApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnJXMgaXMgbm90IHdyaXRhYmxlIGJ5IGN1cnJlbnQgdXNlci4nLCBkaXJuYW1lKCAkb2xkX3BoYXIgKSApICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25pZ2h0bHknICkgKSB7CgkJCVdQX0NMSTo6Y29uZmlybSggc3ByaW50ZiggJ1lvdSBoYXZlIHZlcnNpb24gJXMuIFdvdWxkIHlvdSBsaWtlIHRvIHVwZGF0ZSB0byB0aGUgbGF0ZXN0IG5pZ2h0bHk/JywgV1BfQ0xJX1ZFUlNJT04gKSwgJGFzc29jX2FyZ3MgKTsKCQkJJGRvd25sb2FkX3VybCA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vd3AtY2xpL2J1aWxkcy9naC1wYWdlcy9waGFyL3dwLWNsaS1uaWdodGx5LnBoYXInOwoJCQkkbWQ1X3VybCAgICAgID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS93cC1jbGkvYnVpbGRzL2doLXBhZ2VzL3BoYXIvd3AtY2xpLW5pZ2h0bHkucGhhci5tZDUnOwoJCX0gZWxzZWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc3RhYmxlJyApICkgewoJCQlXUF9DTEk6OmNvbmZpcm0oIHNwcmludGYoICdZb3UgaGF2ZSB2ZXJzaW9uICVzLiBXb3VsZCB5b3UgbGlrZSB0byB1cGRhdGUgdG8gdGhlIGxhdGVzdCBzdGFibGUgcmVsZWFzZT8nLCBXUF9DTElfVkVSU0lPTiApLCAkYXNzb2NfYXJncyApOwoJCQkkZG93bmxvYWRfdXJsID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS93cC1jbGkvYnVpbGRzL2doLXBhZ2VzL3BoYXIvd3AtY2xpLnBoYXInOwoJCQkkbWQ1X3VybCAgICAgID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS93cC1jbGkvYnVpbGRzL2doLXBhZ2VzL3BoYXIvd3AtY2xpLnBoYXIubWQ1JzsKCQl9IGVsc2UgewoKCQkJJHVwZGF0ZXMgPSAkdGhpcy0+Z2V0X3VwZGF0ZXMoICRhc3NvY19hcmdzICk7CgoJCQlpZiAoIGVtcHR5KCAkdXBkYXRlcyApICkgewoJCQkJJHVwZGF0ZV90eXBlID0gJHRoaXMtPmdldF91cGRhdGVfdHlwZV9zdHIoICRhc3NvY19hcmdzICk7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXUC1DTEkgaXMgYXQgdGhlIGxhdGVzdHskdXBkYXRlX3R5cGV9dmVyc2lvbi4iICk7CgkJCQlyZXR1cm47CgkJCX0KCgkJCSRuZXdlc3QgPSAkdXBkYXRlc1swXTsKCgkJCVdQX0NMSTo6Y29uZmlybSggc3ByaW50ZiggJ1lvdSBoYXZlIHZlcnNpb24gJXMuIFdvdWxkIHlvdSBsaWtlIHRvIHVwZGF0ZSB0byAlcz8nLCBXUF9DTElfVkVSU0lPTiwgJG5ld2VzdFsndmVyc2lvbiddICksICRhc3NvY19hcmdzICk7CgoJCQkkZG93bmxvYWRfdXJsID0gJG5ld2VzdFsncGFja2FnZV91cmwnXTsKCQkJJG1kNV91cmwgICAgICA9IHN0cl9yZXBsYWNlKCAnLnBoYXInLCAnLnBoYXIubWQ1JywgJGRvd25sb2FkX3VybCApOwoJCX0KCgkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdEb3dubG9hZGluZyBmcm9tICVzLi4uJywgJGRvd25sb2FkX3VybCApICk7CgoJCSR0ZW1wID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkgLiB1bmlxaWQoICd3cF8nLCB0cnVlICkgLiAnLnBoYXInOwoKCQkkaGVhZGVycyA9IFtdOwoJCSRvcHRpb25zID0gWwoJCQkndGltZW91dCcgID0+IDYwMCwgIC8vIDEwIG1pbnV0ZXMgb3VnaHQgdG8gYmUgZW5vdWdoIGZvciBldmVyeWJvZHkuCgkJCSdmaWxlbmFtZScgPT4gJHRlbXAsCgkJCSdpbnNlY3VyZScgPT4gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKSwKCQldOwoKCQlVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkZG93bmxvYWRfdXJsLCBudWxsLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCgkJdW5zZXQoICRvcHRpb25zWydmaWxlbmFtZSddICk7CgkJJG1kNV9yZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICRtZDVfdXJsLCBudWxsLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCQlpZiAoICcyMCcgIT09IHN1YnN0ciggJG1kNV9yZXNwb25zZS0+c3RhdHVzX2NvZGUsIDAsIDIgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGFjY2VzcyBtZDUgaGFzaCBmb3IgcmVsZWFzZSAoSFRUUCBjb2RlIHskbWQ1X3Jlc3BvbnNlLT5zdGF0dXNfY29kZX0pLiIgKTsKCQl9CgkJJG1kNV9maWxlICAgICA9IG1kNV9maWxlKCAkdGVtcCApOwoJCSRyZWxlYXNlX2hhc2ggPSB0cmltKCAkbWQ1X3Jlc3BvbnNlLT5ib2R5ICk7CgkJaWYgKCAkbWQ1X2ZpbGUgPT09ICRyZWxlYXNlX2hhc2ggKSB7CgkJCVdQX0NMSTo6bG9nKCAnbWQ1IGhhc2ggdmVyaWZpZWQ6ICcgLiAkcmVsZWFzZV9oYXNoICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggIm1kNSBoYXNoIGZvciBkb3dubG9hZCAoeyRtZDVfZmlsZX0pIGlzIGRpZmZlcmVudCB0aGFuIHRoZSByZWxlYXNlIGhhc2ggKHskcmVsZWFzZV9oYXNofSkuIiApOwoJCX0KCgkJJGFsbG93X3Jvb3QgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Y29uZmlnWydhbGxvdy1yb290J10gPyAnLS1hbGxvdy1yb290JyA6ICcnOwoJCSRwaHBfYmluYXJ5ID0gVXRpbHNcZ2V0X3BocF9iaW5hcnkoKTsKCQkkcHJvY2VzcyAgICA9IFByb2Nlc3M6OmNyZWF0ZSggInskcGhwX2JpbmFyeX0gJHRlbXAgLS1pbmZvIHskYWxsb3dfcm9vdH0iICk7CgkJJHJlc3VsdCAgICAgPSAkcHJvY2Vzcy0+cnVuKCk7CgkJaWYgKCAwICE9PSAkcmVzdWx0LT5yZXR1cm5fY29kZSB8fCBmYWxzZSA9PT0gc3RyaXBvcyggJHJlc3VsdC0+c3Rkb3V0LCAnV1AtQ0xJIHZlcnNpb24nICkgKSB7CgkJCSRtdWx0aV9saW5lID0gZXhwbG9kZSggUEhQX0VPTCwgJHJlc3VsdC0+c3RkZXJyICk7CgkJCVdQX0NMSTo6ZXJyb3JfbXVsdGlfbGluZSggJG11bHRpX2xpbmUgKTsKCQkJV1BfQ0xJOjplcnJvciggJ1RoZSBkb3dubG9hZGVkIFBIQVIgaXMgYnJva2VuLCB0cnkgcnVubmluZyB3cCBjbGkgdXBkYXRlIGFnYWluLicgKTsKCQl9CgoJCVdQX0NMSTo6bG9nKCAnTmV3IHZlcnNpb24gd29ya3MuIFByb2NlZWRpbmcgdG8gcmVwbGFjZS4nICk7CgoJCSRtb2RlID0gZmlsZXBlcm1zKCAkb2xkX3BoYXIgKSAmIDUxMTsKCgkJaWYgKCBmYWxzZSA9PT0gY2htb2QoICR0ZW1wLCAkbW9kZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnQ2Fubm90IGNobW9kICVzLicsICR0ZW1wICkgKTsKCQl9CgoJCWNsYXNzX2V4aXN0cyggJ1xjbGlcQ29sb3JzJyApOyAvLyBUaGlzIGF1dG9sb2FkcyBcY2xpXENvbG9ycyAtIGFmdGVyIHdlIG1vdmUgdGhlIGZpbGUgd2Ugbm8gbG9uZ2VyIGhhdmUgYWNjZXNzIHRvIHRoaXMgY2xhc3MuCgoJCWlmICggZmFsc2UgPT09IHJlbmFtZSggJHRlbXAsICRvbGRfcGhhciApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnQ2Fubm90IG1vdmUgJXMgdG8gJXMnLCAkdGVtcCwgJG9sZF9waGFyICkgKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmlnaHRseScsIGZhbHNlICkgKSB7CgkJCSR1cGRhdGVkX3ZlcnNpb24gPSAndGhlIGxhdGVzdCBuaWdodGx5IHJlbGVhc2UnOwoJCX0gZWxzZWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc3RhYmxlJywgZmFsc2UgKSApIHsKCQkJJHVwZGF0ZWRfdmVyc2lvbiA9ICd0aGUgbGF0ZXN0IHN0YWJsZSByZWxlYXNlJzsKCQl9IGVsc2UgewoJCQkkdXBkYXRlZF92ZXJzaW9uID0gaXNzZXQoICRuZXdlc3RbJ3ZlcnNpb24nXSApID8gJG5ld2VzdFsndmVyc2lvbiddIDogJzxub3QgcHJvdmlkZWQ+JzsKCQl9CgkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAnVXBkYXRlZCBXUC1DTEkgdG8gJXMuJywgJHVwZGF0ZWRfdmVyc2lvbiApICk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHVwZGF0ZSBpbmZvcm1hdGlvbi4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfdXBkYXRlcyggJGFzc29jX2FyZ3MgKSB7CgkJJHVybCA9ICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL3dwLWNsaS93cC1jbGkvcmVsZWFzZXM/cGVyX3BhZ2U9MTAwJzsKCgkJJG9wdGlvbnMgPSBbCgkJCSd0aW1lb3V0JyAgPT4gMzAsCgkJCSdpbnNlY3VyZScgPT4gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKSwKCQldOwoKCQkkaGVhZGVycyA9IFsKCQkJJ0FjY2VwdCcgPT4gJ2FwcGxpY2F0aW9uL2pzb24nLAoJCV07CgoJCSRnaXRodWJfdG9rZW4gPSBnZXRlbnYoICdHSVRIVUJfVE9LRU4nICk7CgkJaWYgKCBmYWxzZSAhPT0gJGdpdGh1Yl90b2tlbiApIHsKCQkJJGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9ICd0b2tlbiAnIC4gJGdpdGh1Yl90b2tlbjsKCQl9CgoJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICR1cmwsIG51bGwsICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQlpZiAoICEgJHJlc3BvbnNlLT5zdWNjZXNzIHx8IDIwMCAhPT0gJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0ZhaWxlZCB0byBnZXQgbGF0ZXN0IHZlcnNpb24gKEhUVFAgY29kZSAlZCkuJywgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApICk7CgkJfQoKCQkkcmVsZWFzZV9kYXRhID0ganNvbl9kZWNvZGUoICRyZXNwb25zZS0+Ym9keSApOwoKCQkkdXBkYXRlcyA9IFsKCQkJJ21ham9yJyA9PiBmYWxzZSwKCQkJJ21pbm9yJyA9PiBmYWxzZSwKCQkJJ3BhdGNoJyA9PiBmYWxzZSwKCQldOwoJCWZvcmVhY2ggKCAkcmVsZWFzZV9kYXRhIGFzICRyZWxlYXNlICkgewoKCQkJLy8gR2V0IHJpZCBvZiBsZWFkaW5nICJ2IiBpZiB0aGVyZSBpcyBvbmUgc2V0LgoJCQkkcmVsZWFzZV92ZXJzaW9uID0gJHJlbGVhc2UtPnRhZ19uYW1lOwoJCQlpZiAoICd2JyA9PT0gc3Vic3RyKCAkcmVsZWFzZV92ZXJzaW9uLCAwLCAxICkgKSB7CgkJCQkkcmVsZWFzZV92ZXJzaW9uID0gbHRyaW0oICRyZWxlYXNlX3ZlcnNpb24sICd2JyApOwoJCQl9CgoJCQkkdXBkYXRlX3R5cGUgPSBVdGlsc1xnZXRfbmFtZWRfc2VtX3ZlciggJHJlbGVhc2VfdmVyc2lvbiwgV1BfQ0xJX1ZFUlNJT04gKTsKCQkJaWYgKCAhICR1cGRhdGVfdHlwZSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICEgaXNzZXQoICRyZWxlYXNlLT5hc3NldHNbMF0tPmJyb3dzZXJfZG93bmxvYWRfdXJsICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkdXBkYXRlc1sgJHVwZGF0ZV90eXBlIF0gKSAmJiAhIENvbXBhcmF0b3I6OmdyZWF0ZXJUaGFuKCAkcmVsZWFzZV92ZXJzaW9uLCAkdXBkYXRlc1sgJHVwZGF0ZV90eXBlIF1bJ3ZlcnNpb24nXSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSR1cGRhdGVzWyAkdXBkYXRlX3R5cGUgXSA9IFsKCQkJCSd2ZXJzaW9uJyAgICAgPT4gJHJlbGVhc2VfdmVyc2lvbiwKCQkJCSd1cGRhdGVfdHlwZScgPT4gJHVwZGF0ZV90eXBlLAoJCQkJJ3BhY2thZ2VfdXJsJyA9PiAkcmVsZWFzZS0+YXNzZXRzWzBdLT5icm93c2VyX2Rvd25sb2FkX3VybCwKCQkJXTsKCQl9CgoJCWZvcmVhY2ggKCAkdXBkYXRlcyBhcyAkdHlwZSA9PiAkdmFsdWUgKSB7CgkJCWlmICggZW1wdHkoICR2YWx1ZSApICkgewoJCQkJdW5zZXQoICR1cGRhdGVzWyAkdHlwZSBdICk7CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCBbICdtYWpvcicsICdtaW5vcicsICdwYXRjaCcgXSBhcyAkdHlwZSApIHsKCQkJaWYgKCB0cnVlID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICR0eXBlICkgKSB7CgkJCQlyZXR1cm4gISBlbXB0eSggJHVwZGF0ZXNbICR0eXBlIF0gKSA/IFsgJHVwZGF0ZXNbICR0eXBlIF0gXSA6IGZhbHNlOwoJCQl9CgkJfQoKCQlpZiAoIGVtcHR5KCAkdXBkYXRlcyApICYmIHByZWdfbWF0Y2goICcjLWFscGhhLSguKykkIycsIFdQX0NMSV9WRVJTSU9OLCAkbWF0Y2hlcyApICkgewoJCQkkdmVyc2lvbl91cmwgPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dwLWNsaS9idWlsZHMvZ2gtcGFnZXMvcGhhci9OSUdIVExZX1ZFUlNJT04nOwoJCQkkcmVzcG9uc2UgICAgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkdmVyc2lvbl91cmwsIG51bGwsIFtdLCAkb3B0aW9ucyApOwoJCQlpZiAoICEgJHJlc3BvbnNlLT5zdWNjZXNzIHx8IDIwMCAhPT0gJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICdGYWlsZWQgdG8gZ2V0IGN1cnJlbnQgbmlnaHRseSB2ZXJzaW9uIChIVFRQIGNvZGUgJWQpJywgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApICk7CgkJCX0KCQkJJG5pZ2h0bHlfdmVyc2lvbiA9IHRyaW0oICRyZXNwb25zZS0+Ym9keSApOwoJCQlpZiAoIFdQX0NMSV9WRVJTSU9OICE9PSAkbmlnaHRseV92ZXJzaW9uICkgewoJCQkJJHVwZGF0ZXNbJ25pZ2h0bHknXSA9IFsKCQkJCQkndmVyc2lvbicgICAgID0+ICRuaWdodGx5X3ZlcnNpb24sCgkJCQkJJ3VwZGF0ZV90eXBlJyA9PiAnbmlnaHRseScsCgkJCQkJJ3BhY2thZ2VfdXJsJyA9PiAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dwLWNsaS9idWlsZHMvZ2gtcGFnZXMvcGhhci93cC1jbGktbmlnaHRseS5waGFyJywKCQkJCV07CgkJCX0KCQl9CgoJCXJldHVybiBhcnJheV92YWx1ZXMoICR1cGRhdGVzICk7Cgl9CgoJLyoqCgkgKiBEdW1wcyB0aGUgbGlzdCBvZiBnbG9iYWwgcGFyYW1ldGVycywgYXMgSlNPTiBvciBpbiB2YXJfZXhwb3J0IGZvcm1hdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0td2l0aC12YWx1ZXNdCgkgKiA6IERpc3BsYXkgY3VycmVudCB2YWx1ZXMgYWxzby4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDoganNvbgoJICogb3B0aW9uczoKCSAqICAgLSB2YXJfZXhwb3J0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEdW1wIHRoZSBsaXN0IG9mIGdsb2JhbCBwYXJhbWV0ZXJzLgoJICogICAgICQgd3AgY2xpIHBhcmFtLWR1bXAgLS1mb3JtYXQ9dmFyX2V4cG9ydAoJICogICAgIGFycmF5ICgKCSAqICAgICAgICdwYXRoJyA9PgoJICogICAgICAgYXJyYXkgKAoJICogICAgICAgICAncnVudGltZScgPT4gJz08cGF0aD4nLAoJICogICAgICAgICAnZmlsZScgPT4gJzxwYXRoPicsCgkgKiAgICAgICAgICdzeW5vcHNpcycgPT4gJycsCgkgKiAgICAgICAgICdkZWZhdWx0JyA9PiBOVUxMLAoJICogICAgICAgICAnbXVsdGlwbGUnID0+IGZhbHNlLAoJICogICAgICAgICAnZGVzYycgPT4gJ1BhdGggdG8gdGhlIFdvcmRQcmVzcyBmaWxlcy4nLAoJICogICAgICAgKSwKCSAqICAgICAgICd1cmwnID0+CgkgKiAgICAgICBhcnJheSAoCgkgKgoJICogQHN1YmNvbW1hbmQgcGFyYW0tZHVtcAoJICovCglwdWJsaWMgZnVuY3Rpb24gcGFyYW1fZHVtcCggJF8sICRhc3NvY19hcmdzICkgewoJCSRzcGVjID0gV1BfQ0xJOjpnZXRfY29uZmlndXJhdG9yKCktPmdldF9zcGVjKCk7CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnd2l0aC12YWx1ZXMnICkgKSB7CgkJCSRjb25maWcgPSBXUF9DTEk6OmdldF9jb25maWd1cmF0b3IoKS0+dG9fYXJyYXkoKTsKCQkJLy8gQ29weSBjdXJyZW50IGNvbmZpZyB2YWx1ZXMgdG8gJHNwZWMuCgkJCWZvcmVhY2ggKCAkc3BlYyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCSRjdXJyZW50ID0gbnVsbDsKCQkJCWlmICggaXNzZXQoICRjb25maWdbMF1bICRrZXkgXSApICkgewoJCQkJCSRjdXJyZW50ID0gJGNvbmZpZ1swXVsgJGtleSBdOwoJCQkJfQoJCQkJJHNwZWNbICRrZXkgXVsnY3VycmVudCddID0gJGN1cnJlbnQ7CgkJCX0KCQl9CgoJCWlmICggJ3Zhcl9leHBvcnQnID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgKSB7CgkJCXZhcl9leHBvcnQoICRzcGVjICk7CgkJfSBlbHNlIHsKCQkJZWNobyBqc29uX2VuY29kZSggJHNwZWMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEdW1wcyB0aGUgbGlzdCBvZiBpbnN0YWxsZWQgY29tbWFuZHMsIGFzIEpTT04uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEdW1wIHRoZSBsaXN0IG9mIGluc3RhbGxlZCBjb21tYW5kcy4KCSAqICAgICAkIHdwIGNsaSBjbWQtZHVtcAoJICogICAgIHsibmFtZSI6IndwIiwiZGVzY3JpcHRpb24iOiJNYW5hZ2UgV29yZFByZXNzIHRocm91Z2ggdGhlIGNvbW1hbmQtbGluZS4iLCJsb25nZGVzYyI6IlxuXG4jIyBHTE9CQUwgUEFSQU1FVEVSU1xuXG4gIC0tcGF0aD08cGF0aD5cbiAgICAgIFBhdGggdG8gdGhlIFdvcmRQcmVzcyBmaWxlcy5cblxuICAtLXNzaD08c3NoPlxuICAgICAgUGVyZm9ybSBvcGVyYXRpb24gYWdhaW5zdCBhIHJlbW90ZSBzZXJ2ZXIgb3ZlciBTU0ggKG9yIGEgY29udGFpbmVyIHVzaW5nIHNjaGVtZSBvZiAiZG9ja2VyIiBvciAiZG9ja2VyLWNvbXBvc2UiKS5cblxuICAtLXVybD08dXJsPlxuICAgICAgUHJldGVuZCByZXF1ZXN0IGNhbWUgZnJvbSBnaXZlbiBVUkwuIEluIG11bHRpc2l0ZSwgdGhpcyBhcmd1bWVudCBpcyBob3cgdGhlIHRhcmdldCBzaXRlIGlzIHNwZWNpZmllZC4gXG5cbiAgLS11c2VyPTxpZHxsb2dpbnxlbWFpbD5cbgoJICoKCSAqIEBzdWJjb21tYW5kIGNtZC1kdW1wCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjbWRfZHVtcCgpIHsKCQllY2hvIGpzb25fZW5jb2RlKCAkdGhpcy0+Y29tbWFuZF90b19hcnJheSggV1BfQ0xJOjpnZXRfcm9vdF9jb21tYW5kKCkgKSApOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIHRhYiBjb21wbGV0aW9uIHN0cmluZ3MuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIC0tbGluZT08bGluZT4KCSAqIDogVGhlIGN1cnJlbnQgY29tbWFuZCBsaW5lIHRvIGJlIGV4ZWN1dGVkLgoJICoKCSAqIC0tcG9pbnQ9PHBvaW50PgoJICogOiBUaGUgaW5kZXggdG8gdGhlIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNvbW1hbmQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSB0YWIgY29tcGxldGlvbiBzdHJpbmdzLgoJICogICAgICQgd3AgY2xpIGNvbXBsZXRpb25zIC0tbGluZT0nd3AgZXZhJyAtLXBvaW50PTEwMAoJICogICAgIGV2YWwKCSAqICAgICBldmFsLWZpbGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNvbXBsZXRpb25zKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJJGxpbmUgID0gc3Vic3RyKCAkYXNzb2NfYXJnc1snbGluZSddLCAwLCAkYXNzb2NfYXJnc1sncG9pbnQnXSApOwoJCSRjb21wbCA9IG5ldyBDb21wbGV0aW9ucyggJGxpbmUgKTsKCQkkY29tcGwtPnJlbmRlcigpOwoJfQoKCS8qKgoJICogR2V0IGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdHlwZSBvZiB1cGRhdGUgYmVpbmcgY2hlY2tlZCBmb3IuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3VwZGF0ZV90eXBlX3N0ciggJGFzc29jX2FyZ3MgKSB7CgkJJHVwZGF0ZV90eXBlID0gJyAnOwoJCWZvcmVhY2ggKCBbICdtYWpvcicsICdtaW5vcicsICdwYXRjaCcgXSBhcyAkdHlwZSApIHsKCQkJaWYgKCB0cnVlID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICR0eXBlICkgKSB7CgkJCQkkdXBkYXRlX3R5cGUgPSAnICcgLiAkdHlwZSAuICcgJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXJldHVybiAkdXBkYXRlX3R5cGU7Cgl9CgoJLyoqCgkgKiBEZXRlY3RzIGlmIGEgY29tbWFuZCBleGlzdHMKCSAqCgkgKiBUaGlzIGNvbW1hbmRzIGNoZWNrcyBpZiBhIGNvbW1hbmQgaXMgcmVnaXN0ZXJlZCB3aXRoIFdQLUNMSS4KCSAqIElmIHRoZSBjb21tYW5kIGlzIGZvdW5kIHRoZW4gaXQgcmV0dXJucyB3aXRoIGV4aXQgc3RhdHVzIDAuCgkgKiBJZiB0aGUgY29tbWFuZCBkb2Vzbid0IGV4aXN0LCB0aGVuIGl0IHdpbGwgZXhpdCB3aXRoIHN0YXR1cyAxLgoJICoKCSAqICMjIE9QVElPTlMKCSAqIDxjb21tYW5kX25hbWU+Li4uCgkgKiA6IFRoZSBjb21tYW5kCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBUaGUgInNpdGUgZGVsZXRlIiBjb21tYW5kIGlzIHJlZ2lzdGVyZWQuCgkgKiAgICAgJCB3cCBjbGkgaGFzLWNvbW1hbmQgInNpdGUgZGVsZXRlIgoJICogICAgICQgZWNobyAkPwoJICogICAgIDAKCSAqCgkgKiAgICAgIyBUaGUgImZvbyBiYXIiIGNvbW1hbmQgaXMgbm90IHJlZ2lzdGVyZWQuCgkgKiAgICAgJCB3cCBjbGkgaGFzLWNvbW1hbmQgImZvbyBiYXIiCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGhhcy1jb21tYW5kCgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaGFzX2NvbW1hbmQoICRfLCAkYXNzb2NfYXJncyApIHsKCgkJLy8gSWYgY29tbWFuZCBpcyBpbnB1dCBhcyBhIHN0cmluZywgdGhlbiBleHBsb2RlIGl0IGludG8gYXJyYXkuCgkJJGNvbW1hbmQgPSBleHBsb2RlKCAnICcsIGltcGxvZGUoICcgJywgJF8gKSApOwoKCQlXUF9DTEk6OmhhbHQoIGlzX2FycmF5KCBXUF9DTEk6OmdldF9ydW5uZXIoKS0+ZmluZF9jb21tYW5kX3RvX3J1biggJGNvbW1hbmQgKSApID8gMCA6IDEgKTsKCX0KfQo8P3BocAoKdXNlIGNsaVxTaGVsbDsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKY2xhc3MgSGVscF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogR2V0cyBoZWxwIG9uIFdQLUNMSSwgb3Igb24gYSBzcGVjaWZpYyBjb21tYW5kLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGNvbW1hbmQ+Li4uXQoJICogOiBHZXQgaGVscCBvbiBhIHNwZWNpZmljIGNvbW1hbmQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBnZXQgaGVscCBmb3IgYGNvcmVgIGNvbW1hbmQKCSAqICAgICB3cCBoZWxwIGNvcmUKCSAqCgkgKiAgICAgIyBnZXQgaGVscCBmb3IgYGNvcmUgZG93bmxvYWRgIHN1YmNvbW1hbmQKCSAqICAgICB3cCBoZWxwIGNvcmUgZG93bmxvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+ZmluZF9jb21tYW5kX3RvX3J1biggJGFyZ3MgKTsKCgkJaWYgKCBpc19hcnJheSggJHIgKSApIHsKCQkJbGlzdCggJGNvbW1hbmQgKSA9ICRyOwoKCQkJc2VsZjo6c2hvd19oZWxwKCAkY29tbWFuZCApOwoJCQlleGl0OwoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzaG93X2hlbHAoICRjb21tYW5kICkgewoJCSRvdXQgPSBzZWxmOjpnZXRfaW5pdGlhbF9tYXJrZG93biggJGNvbW1hbmQgKTsKCgkJLy8gUmVtb3ZlIHN1YmNvbW1hbmRzIGlmIGluIGNvbHVtbnMgLSB3aWxsIHdvcmR3cmFwIHNlcGFyYXRlbHkuCgkJJHN1YmNvbW1hbmRzICAgICAgID0gJyc7CgkJJGNvbHVtbl9zdWJwYXR0ZXJuID0gJ1sgXHRdK1teXHRdK1x0Kyc7CgkJaWYgKCBwcmVnX21hdGNoKCAnLyheIyMgU1VCQ09NTUFORFNbXlxuXSpcbisnIC4gJGNvbHVtbl9zdWJwYXR0ZXJuIC4gJy4rPykoPzpeIyN8XHopL21zJywgJG91dCwgJG1hdGNoZXMsIFBSRUdfT0ZGU0VUX0NBUFRVUkUgKSApIHsKCQkJJHN1YmNvbW1hbmRzICAgICAgICA9ICRtYXRjaGVzWzFdWzBdOwoJCQkkc3ViY29tbWFuZHNfaGVhZGVyID0gIiMjIFNVQkNPTU1BTkRTXG4iOwoJCQkkb3V0ICAgICAgICAgICAgICAgID0gc3Vic3RyX3JlcGxhY2UoICRvdXQsICRzdWJjb21tYW5kc19oZWFkZXIsICRtYXRjaGVzWzFdWzFdLCBzdHJsZW4oICRzdWJjb21tYW5kcyApICk7CgkJfQoKCQkkb3V0IC49IHNlbGY6OnBhcnNlX3JlZmVyZW5jZV9saW5rcyggJGNvbW1hbmQtPmdldF9sb25nZGVzYygpICk7CgoJCS8vIERlZmluaXRpb24gbGlzdHMuCgkJJG91dCA9IHByZWdfcmVwbGFjZV9jYWxsYmFjayggJy8oW15cbl0rKVxuOiAoLis/KShcblxufCQpL3MnLCBbIF9fQ0xBU1NfXywgJ3Jld3JhcF9wYXJhbV9kZXNjJyBdLCAkb3V0ICk7CgoJCS8vIEVuc3VyZSBsaW5lcyB3aXRoIG5vIGxlYWRpbmcgd2hpdGVzcGFjZSB0aGF0IGFyZW4ndCBzZWN0aW9uIGhlYWRlcnMgYXJlIGluZGVudGVkLgoJCSRvdXQgPSBwcmVnX3JlcGxhY2UoICcvXigoPyEgfFx0fCMjKS4pL20nLCAiXHQkMSIsICRvdXQgKTsKCgkJJHRhYiA9IHN0cl9yZXBlYXQoICcgJywgMiApOwoKCQkvLyBOZWVkIHRvIGRlLXRhYiBmb3Igd29yZHdyYXBwaW5nIHRvIHdvcmsgcHJvcGVybHkuCgkJJG91dCA9IHN0cl9yZXBsYWNlKCAiXHQiLCAkdGFiLCAkb3V0ICk7CgoJCSR3b3Jkd3JhcF93aWR0aCA9IFNoZWxsOjpjb2x1bW5zKCk7CgoJCS8vIFdvcmR3cmFwIHdpdGggaW5kZW50LgoJCSRvdXQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCgkJCScvXiggKikoW15cbl0rKVxuL20nLAoJCQlmdW5jdGlvbiAoICRtYXRjaGVzICkgdXNlICggJHdvcmR3cmFwX3dpZHRoICkgewoJCQkJcmV0dXJuICRtYXRjaGVzWzFdIC4gc3RyX3JlcGxhY2UoICJcbiIsICJcbnskbWF0Y2hlc1sxXX0iLCB3b3Jkd3JhcCggJG1hdGNoZXNbMl0sICR3b3Jkd3JhcF93aWR0aCAtIHN0cmxlbiggJG1hdGNoZXNbMV0gKSApICkgLiAiXG4iOwoJCQl9LAoJCQkkb3V0CgkJKTsKCgkJaWYgKCAkc3ViY29tbWFuZHMgKSB7CgkJCS8vIFdvcmR3cmFwIHdpdGggY29sdW1uIGluZGVudC4KCQkJJHN1YmNvbW1hbmRzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAoJCQkJJy9eKCcgLiAkY29sdW1uX3N1YnBhdHRlcm4gLiAnKShbXlxuXSspXG4vbScsCgkJCQlmdW5jdGlvbiAoICRtYXRjaGVzICkgdXNlICggJHdvcmR3cmFwX3dpZHRoLCAkdGFiICkgewoJCQkJCS8vIE5lZWQgdG8gZGUtdGFiIGZvciB3b3Jkd3JhcHBpbmcgdG8gd29yayBwcm9wZXJseS4KCQkJCQkkbWF0Y2hlc1sxXSAgPSBzdHJfcmVwbGFjZSggIlx0IiwgJHRhYiwgJG1hdGNoZXNbMV0gKTsKCQkJCQkkbWF0Y2hlc1syXSAgPSBzdHJfcmVwbGFjZSggIlx0IiwgJHRhYiwgJG1hdGNoZXNbMl0gKTsKCQkJCQkkcGFkZGluZ19sZW4gPSBzdHJsZW4oICRtYXRjaGVzWzFdICk7CgkJCQkJJHBhZGRpbmcgICAgID0gc3RyX3JlcGVhdCggJyAnLCAkcGFkZGluZ19sZW4gKTsKCQkJCQlyZXR1cm4gJG1hdGNoZXNbMV0gLiBzdHJfcmVwbGFjZSggIlxuIiwgIlxuJHBhZGRpbmciLCB3b3Jkd3JhcCggJG1hdGNoZXNbMl0sICR3b3Jkd3JhcF93aWR0aCAtICRwYWRkaW5nX2xlbiApICkgLiAiXG4iOwoJCQkJfSwKCQkJCSRzdWJjb21tYW5kcwoJCQkpOwoKCQkJLy8gUHV0IHN1YmNvbW1hbmRzIGJhY2suCgkJCSRvdXQgPSBzdHJfcmVwbGFjZSggJHN1YmNvbW1hbmRzX2hlYWRlciwgJHN1YmNvbW1hbmRzLCAkb3V0ICk7CgkJfQoKCQkvLyBTZWN0aW9uIGhlYWRlcnMuCgkJJG91dCA9IHByZWdfcmVwbGFjZSggJy9eIyMgKFtBLVogXSspL20nLCBXUF9DTEk6OmNvbG9yaXplKCAnJTlcMSVuJyApLCAkb3V0ICk7CgoJCXNlbGY6OnBhc3NfdGhyb3VnaF9wYWdlciggJG91dCApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHJld3JhcF9wYXJhbV9kZXNjKCAkbWF0Y2hlcyApIHsKCQkkcGFyYW0gPSAkbWF0Y2hlc1sxXTsKCQkkZGVzYyAgPSBzZWxmOjppbmRlbnQoICJcdFx0IiwgJG1hdGNoZXNbMl0gKTsKCQlyZXR1cm4gIlx0JHBhcmFtXG4kZGVzY1xuXG4iOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluZGVudCggJHdoaXRlc3BhY2UsICR0ZXh0ICkgewoJCSRsaW5lcyA9IGV4cGxvZGUoICJcbiIsICR0ZXh0ICk7CgkJZm9yZWFjaCAoICRsaW5lcyBhcyAmJGxpbmUgKSB7CgkJCSRsaW5lID0gJHdoaXRlc3BhY2UgLiAkbGluZTsKCQl9CgkJcmV0dXJuIGltcGxvZGUoICJcbiIsICRsaW5lcyApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHBhc3NfdGhyb3VnaF9wYWdlciggJG91dCApIHsKCgkJaWYgKCAhIFV0aWxzXGNoZWNrX3Byb2NfYXZhaWxhYmxlKCBudWxsIC8qY29udGV4dCovLCB0cnVlIC8qcmV0dXJuKi8gKSApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkb3V0ICk7CgkJCVdQX0NMSTo6ZGVidWcoICdXYXJuaW5nOiBjaGVja19wcm9jX2F2YWlsYWJsZSgpIGZhaWxlZCBpbiBwYXNzX3Rocm91Z2hfcGFnZXIoKS4nLCAnaGVscCcgKTsKCQkJcmV0dXJuIC0xOwoJCX0KCgkJJHBhZ2VyID0gZ2V0ZW52KCAnUEFHRVInICk7CgkJaWYgKCBmYWxzZSA9PT0gJHBhZ2VyICkgewoJCQkkcGFnZXIgPSBVdGlsc1xpc193aW5kb3dzKCkgPyAnbW9yZScgOiAnbGVzcyAtcic7CgkJfQoKCQkvLyBGb3IgV2luZG93cyA3IG5lZWQgdG8gc2V0IGNvZGUgcGFnZSB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBVbmljb2RlICg2NTAwMSkgdG8gZ2V0IGFyb3VuZCAiTm90IGVub3VnaCBtZW1vcnkuIiBlcnJvciB3aXRoIGBtb3JlLmNvbWAgb24gUEhQIDcuMSsuCgkJaWYgKCAnbW9yZScgPT09ICRwYWdlciAmJiBkZWZpbmVkKCAnUEhQX1dJTkRPV1NfVkVSU0lPTl9NQUpPUicgKSAmJiBQSFBfV0lORE9XU19WRVJTSU9OX01BSk9SIDwgMTAgJiYgZnVuY3Rpb25fZXhpc3RzKCAnc2FwaV93aW5kb3dzX2NwX3NldCcgKSApIHsKCQkJLy8gTm90ZSB3aWxsIGFsc28gYXBwbHkgdG8gV2luZG93cyA4IChzZWUgaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS93aW5kb3dzL2Rlc2t0b3AvbXM3MjQ4MzIuYXNweCkgYnV0IHByb2JhYmx5IGhhcm1sZXNzIGFueXdheS4KCQkJJGNwID0gZ2V0ZW52KCAnV1BfQ0xJX1dJTkRPV1NfQ09ERV9QQUdFJyApID86IDEyNTI7IC8vIENvZGUgcGFnZSAxMjUyIGlzIHRoZSBtb3N0IHVzZWQgc28gcHJvYmFibHkgdGhlIG1vc3QgY29tcGF0LgoJCQkvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5GdW5jdGlvblVzZS5OZXdGdW5jdGlvbnMgLS0gV3JhcHBlZCBpbiBmdW5jdGlvbl9leGlzdHMoKSBjYWxsLgoJCQlzYXBpX3dpbmRvd3NfY3Bfc2V0KCAkY3AgKTsgLy8gYHNhcGlfd2luZG93c19jcF9zZXQoKWAgaW50cm9kdWNlZCBQSFAgNy4xLgoJCX0KCgkJLy8gQ29udmVydCBzdHJpbmcgdG8gZmlsZSBoYW5kbGUuCgkJJGZkID0gZm9wZW4oICdwaHA6Ly90ZW1wJywgJ3IrYicgKTsKCQlmd3JpdGUoICRmZCwgJG91dCApOwoJCXJld2luZCggJGZkICk7CgoJCSRkZXNjcmlwdG9yc3BlYyA9IFsKCQkJMCA9PiAkZmQsCgkJCTEgPT4gU1RET1VULAoJCQkyID0+IFNUREVSUiwKCQldOwoKCQlyZXR1cm4gcHJvY19jbG9zZSggVXRpbHNccHJvY19vcGVuX2NvbXBhdCggJHBhZ2VyLCAkZGVzY3JpcHRvcnNwZWMsICRwaXBlcyApICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2luaXRpYWxfbWFya2Rvd24oICRjb21tYW5kICkgewoJCSRuYW1lID0gaW1wbG9kZSggJyAnLCBEaXNwYXRjaGVyXGdldF9wYXRoKCAkY29tbWFuZCApICk7CgoJCSRiaW5kaW5nID0gWwoJCQknbmFtZScgICAgICA9PiAkbmFtZSwKCQkJJ3Nob3J0ZGVzYycgPT4gJGNvbW1hbmQtPmdldF9zaG9ydGRlc2MoKSwKCQldOwoKCQkkYmluZGluZ1snc3lub3BzaXMnXSA9ICIkbmFtZSAiIC4gJGNvbW1hbmQtPmdldF9zeW5vcHNpcygpOwoKCQkkYWxpYXMgPSAkY29tbWFuZC0+Z2V0X2FsaWFzKCk7CgkJaWYgKCAkYWxpYXMgKSB7CgkJCSRiaW5kaW5nWydhbGlhcyddID0gJGFsaWFzOwoJCX0KCgkJaWYgKCAkY29tbWFuZC0+Y2FuX2hhdmVfc3ViY29tbWFuZHMoKSApIHsKCQkJJGJpbmRpbmdbJ2hhcy1zdWJjb21tYW5kcyddWydzdWJjb21tYW5kcyddID0gc2VsZjo6cmVuZGVyX3N1YmNvbW1hbmRzKCAkY29tbWFuZCApOwoJCX0KCgkJcmV0dXJuIFV0aWxzXG11c3RhY2hlX3JlbmRlciggJ21hbi5tdXN0YWNoZScsICRiaW5kaW5nICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcmVuZGVyX3N1YmNvbW1hbmRzKCAkY29tbWFuZCApIHsKCQkkc3ViY29tbWFuZHMgPSBbXTsKCQlmb3JlYWNoICggJGNvbW1hbmQtPmdldF9zdWJjb21tYW5kcygpIGFzICRzdWJjb21tYW5kICkgewoKCQkJaWYgKCBXUF9DTEk6OmdldF9ydW5uZXIoKS0+aXNfY29tbWFuZF9kaXNhYmxlZCggJHN1YmNvbW1hbmQgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkc3ViY29tbWFuZHNbICRzdWJjb21tYW5kLT5nZXRfbmFtZSgpIF0gPSAkc3ViY29tbWFuZC0+Z2V0X3Nob3J0ZGVzYygpOwoJCX0KCgkJJG1heF9sZW4gPSBzZWxmOjpnZXRfbWF4X2xlbiggYXJyYXlfa2V5cyggJHN1YmNvbW1hbmRzICkgKTsKCgkJJGxpbmVzID0gW107CgkJZm9yZWFjaCAoICRzdWJjb21tYW5kcyBhcyAkbmFtZSA9PiAkZGVzYyApIHsKCQkJJGxpbmVzW10gPSBzdHJfcGFkKCAkbmFtZSwgJG1heF9sZW4gKSAuICJcdFx0XHQiIC4gJGRlc2M7CgkJfQoKCQlyZXR1cm4gJGxpbmVzOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9tYXhfbGVuKCAkc3RyaW5ncyApIHsKCQkkbWF4X2xlbiA9IDA7CgkJZm9yZWFjaCAoICRzdHJpbmdzIGFzICRzdHIgKSB7CgkJCSRsZW4gPSBzdHJsZW4oICRzdHIgKTsKCQkJaWYgKCAkbGVuID4gJG1heF9sZW4gKSB7CgkJCQkkbWF4X2xlbiA9ICRsZW47CgkJCX0KCQl9CgoJCXJldHVybiAkbWF4X2xlbjsKCX0KCgkvKioKCSAqIFBhcnNlIHJlZmVyZW5jZSBsaW5rcyBmcm9tIGxvbmdkZXNjcmlwdGlvbi4KCSAqCgkgKiBAcGFyYW0gIHN0cmluZyAkbG9uZ2Rlc2MgVGhlIGxvbmdkZXNjcmlwdGlvbiBmcm9tIHRoZSBgJGNvbW1hbmQtPmdldF9sb25nZGVzYygpYC4KCSAqIEByZXR1cm4gc3RyaW5nIFRoZSBsb25nZGVzY3JpcHRpb24gd2hpY2ggaGFzIGxpbmtzIGFzIGZvb3Rub3RlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBwYXJzZV9yZWZlcmVuY2VfbGlua3MoICRsb25nZGVzYyApIHsKCQkkZGVzY3JpcHRpb24gPSAnJzsKCQlmb3JlYWNoICggZXhwbG9kZSggIlxuIiwgJGxvbmdkZXNjICkgYXMgJGxpbmUgKSB7CgkJCWlmICggMCA9PT0gc3RycG9zKCAkbGluZSwgJyMnICkgKSB7CgkJCQlicmVhazsKCQkJfQoJCQkkZGVzY3JpcHRpb24gLj0gJGxpbmUgLiAiXG4iOwoJCX0KCgkJLy8gRmlyZXMgaWYgaXQgaGFzIGRlc2NyaXB0aW9uIHRleHQgYXQgdGhlIGhlYWQgb2YgYCRsb25nZGVzY2AuCgkJaWYgKCAkZGVzY3JpcHRpb24gKSB7CgkJCSRsaW5rcyAgID0gW107IC8vIEFuIGFycmF5IG9mIFVSTHMgZnJvbSB0aGUgZGVzY3JpcHRpb24uCgkJCSRwYXR0ZXJuID0gJy9cWy4rP1xdXCgoaHR0cHM/OlwvXC8uKz8pXCkvJzsKCQkJJG5ld2Rlc2MgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCgkJCQkkcGF0dGVybiwKCQkJCWZ1bmN0aW9uKCAkbWF0Y2hlcyApIHVzZSAoICYkbGlua3MgKSB7CgkJCQkJc3RhdGljICRjb3VudCA9IDA7CgkJCQkJJGNvdW50Kys7CgkJCQkJJGxpbmtzW10gPSAkbWF0Y2hlc1sxXTsKCQkJCQlyZXR1cm4gc3RyX3JlcGxhY2UoICcoJyAuICRtYXRjaGVzWzFdIC4gJyknLCAnWycgLiAkY291bnQgLiAnXScsICRtYXRjaGVzWzBdICk7CgkJCQl9LAoJCQkJJGRlc2NyaXB0aW9uCgkJCSk7CgoJCQkkZm9vdG5vdGUgICA9ICcnOwoJCQkkbGlua19jb3VudCA9IGNvdW50KCAkbGlua3MgKTsKCQkJZm9yICggJGkgPSAwOyAkaSA8ICRsaW5rX2NvdW50OyAkaSsrICkgewoJCQkJJG4gICAgICAgICA9ICRpICsgMTsKCQkJCSRmb290bm90ZSAuPSAnWycgLiAkbiAuICddICcgLiAkbGlua3NbICRpIF0gLiAiXG4iOwoJCQl9CgoJCQlpZiAoICRmb290bm90ZSApIHsKCQkJCSRuZXdkZXNjICA9IHRyaW0oICRuZXdkZXNjICkgLiAiXG5cbi0tLVxuIiAuICRmb290bm90ZTsKCQkJCSRsb25nZGVzYyA9IHN0cl9yZXBsYWNlKCB0cmltKCAkZGVzY3JpcHRpb24gKSwgdHJpbSggJG5ld2Rlc2MgKSwgJGxvbmdkZXNjICk7CgkJCX0KCQl9CgoJCXJldHVybiAkbG9uZ2Rlc2M7Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdIZWxwX0NvbW1hbmQnICkgKSB7CglyZXF1aXJlX29uY2UgX19ESVJfXyAuICcvc3JjL0hlbHBfQ29tbWFuZC5waHAnOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnaGVscCcsICdIZWxwX0NvbW1hbmQnICk7Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnQ0xJX0NvbW1hbmQnICkgKSB7CglyZXF1aXJlX29uY2UgX19ESVJfXyAuICcvc3JjL0NMSV9Db21tYW5kLnBocCc7Cn0KCmlmICggISBjbGFzc19leGlzdHMoICdDTElfQ2FjaGVfQ29tbWFuZCcgKSApIHsKCXJlcXVpcmVfb25jZSBfX0RJUl9fIC4gJy9zcmMvQ0xJX0NhY2hlX0NvbW1hbmQucGhwJzsKfQoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ0NMSV9BbGlhc19Db21tYW5kJyApICkgewoJcmVxdWlyZV9vbmNlIF9fRElSX18gLiAnL3NyYy9DTElfQWxpYXNfQ29tbWFuZC5waHAnOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY2xpJywgJ0NMSV9Db21tYW5kJyApOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NsaSBjYWNoZScsICdDTElfQ2FjaGVfQ29tbWFuZCcgKTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjbGkgYWxpYXMnLCAnQ0xJX0FsaWFzX0NvbW1hbmQnICk7Cjw/cGhwCgovLyBTdG9yZSB0aGUgcGF0aCB0byB0aGUgUGhhciBlYXJseSBvbiBmb3IgYFV0aWxzXHBoYXItc2FmZS1wYXRoKClgIGZ1bmN0aW9uLgpkZWZpbmUoICdXUF9DTElfUEhBUl9QQVRIJywgZ2V0Y3dkKCkgKTsKCmlmICggZmlsZV9leGlzdHMoICdwaGFyOi8vd3AtY2xpLnBoYXIvcGhwL3dwLWNsaS5waHAnICkgKSB7CglkZWZpbmUoICdXUF9DTElfUk9PVCcsICdwaGFyOi8vd3AtY2xpLnBoYXInICk7CglpbmNsdWRlIFdQX0NMSV9ST09UIC4gJy9waHAvd3AtY2xpLnBocCc7Cn0gZWxzZWlmICggZmlsZV9leGlzdHMoICdwaGFyOi8vd3AtY2xpLnBoYXIvdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL3dwLWNsaS5waHAnICkgKSB7CglkZWZpbmUoICdXUF9DTElfUk9PVCcsICdwaGFyOi8vd3AtY2xpLnBoYXIvdmVuZG9yL3dwLWNsaS93cC1jbGknICk7CglpbmNsdWRlIFdQX0NMSV9ST09UIC4gJy9waHAvd3AtY2xpLnBocCc7Cn0gZWxzZSB7CgllY2hvICJDb3VsZG4ndCBmaW5kICdwaHAvd3AtY2xpLnBocCcuIFdhcyB0aGlzIFBoYXIgYnVpbHQgY29ycmVjdGx5PyI7CglleGl0KCAxICk7Cn0KIyEvdXNyL2Jpbi9lbnYgcGhwCjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTUgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEEgc2hlbGwgc2NyaXB0IHRvIGNyZWF0ZSBhIHNpbmdsZS1maWxlIGNsYXNzIGNhY2hlIG9mIHRoZSBlbnRpcmUgTXVzdGFjaGUKICogbGlicmFyeS4KICoKICogICAgICQgYmluL2J1aWxkX2Jvb3RzdHJhcC5waHAKICoKICogLi4uIHdpbGwgY3JlYXRlIGEgYG11c3RhY2hlLnBocGAgYm9vdHN0cmFwIGZpbGUgaW4gdGhlIHByb2plY3QgZGlyZWN0b3J5LAogKiBjb250YWluaW5nIGFsbCBNdXN0YWNoZSBsaWJyYXJ5IGNsYXNzZXMuIFRoaXMgZmlsZSBjYW4gdGhlbiBiZSBpbmNsdWRlZCBpbgogKiB5b3VyIHByb2plY3QsIHJhdGhlciB0aGFuIHJlcXVpcmluZyB0aGUgTXVzdGFjaGUgQXV0b2xvYWRlci4KICovCiRiYXNlRGlyID0gcmVhbHBhdGgoZGlybmFtZShfX0ZJTEVfXykgLiAnLy4uJyk7CgpyZXF1aXJlICRiYXNlRGlyIC4gJy9zcmMvTXVzdGFjaGUvQXV0b2xvYWRlci5waHAnOwpNdXN0YWNoZV9BdXRvbG9hZGVyOjpyZWdpc3RlcigpOwoKLy8gZGVsZXRlIHRoZSBvbGQgZmlsZQokZmlsZSA9ICRiYXNlRGlyIC4gJy9tdXN0YWNoZS5waHAnOwppZiAoZmlsZV9leGlzdHMoJGZpbGUpKSB7CiAgICB1bmxpbmsoJGZpbGUpOwp9CgovLyBhbmQgbG9hZCB0aGUgbmV3IG9uZQpTeW1mb255Q2xhc3NDb2xsZWN0aW9uTG9hZGVyOjpsb2FkKGFycmF5KAogICAgJ011c3RhY2hlX0VuZ2luZScsCiAgICAnTXVzdGFjaGVfQ2FjaGUnLAogICAgJ011c3RhY2hlX0NhY2hlX0Fic3RyYWN0Q2FjaGUnLAogICAgJ011c3RhY2hlX0NhY2hlX0ZpbGVzeXN0ZW1DYWNoZScsCiAgICAnTXVzdGFjaGVfQ2FjaGVfTm9vcENhY2hlJywKICAgICdNdXN0YWNoZV9Db21waWxlcicsCiAgICAnTXVzdGFjaGVfQ29udGV4dCcsCiAgICAnTXVzdGFjaGVfRXhjZXB0aW9uJywKICAgICdNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uJywKICAgICdNdXN0YWNoZV9FeGNlcHRpb25fTG9naWNFeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uJywKICAgICdNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uJywKICAgICdNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93bkZpbHRlckV4Y2VwdGlvbicsCiAgICAnTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25IZWxwZXJFeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0hlbHBlckNvbGxlY3Rpb24nLAogICAgJ011c3RhY2hlX0xhbWJkYUhlbHBlcicsCiAgICAnTXVzdGFjaGVfTG9hZGVyJywKICAgICdNdXN0YWNoZV9Mb2FkZXJfQXJyYXlMb2FkZXInLAogICAgJ011c3RhY2hlX0xvYWRlcl9DYXNjYWRpbmdMb2FkZXInLAogICAgJ011c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyJywKICAgICdNdXN0YWNoZV9Mb2FkZXJfSW5saW5lTG9hZGVyJywKICAgICdNdXN0YWNoZV9Mb2FkZXJfTXV0YWJsZUxvYWRlcicsCiAgICAnTXVzdGFjaGVfTG9hZGVyX1N0cmluZ0xvYWRlcicsCiAgICAnTXVzdGFjaGVfTG9nZ2VyJywKICAgICdNdXN0YWNoZV9Mb2dnZXJfQWJzdHJhY3RMb2dnZXInLAogICAgJ011c3RhY2hlX0xvZ2dlcl9TdHJlYW1Mb2dnZXInLAogICAgJ011c3RhY2hlX1BhcnNlcicsCiAgICAnTXVzdGFjaGVfVGVtcGxhdGUnLAogICAgJ011c3RhY2hlX1Rva2VuaXplcicsCiksIGRpcm5hbWUoJGZpbGUpLCBiYXNlbmFtZSgkZmlsZSwgJy5waHAnKSk7CgovKioKICogU3ltZm9ueUNsYXNzQ29sbGVjdGlvbkxvYWRlci4KICoKICogQmFzZWQgaGVhdmlseSBvbiB0aGUgU3ltZm9ueSBDbGFzc0NvbGxlY3Rpb25Mb2FkZXIgY29tcG9uZW50LCB3aXRoIGFsbAogKiB0aGUgdW5uZWNlc3NhcnkgYml0cyByZW1vdmVkLgogKgogKiBAbGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVAogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIFN5bWZvbnlDbGFzc0NvbGxlY3Rpb25Mb2FkZXIKewogICAgcHJpdmF0ZSBzdGF0aWMgJGxvYWRlZDsKCiAgICBjb25zdCBIRUFERVIgPSA8PDwnRU9TJwo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0lZCBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCkVPUzsKCiAgICAvKioKICAgICAqIExvYWRzIGEgbGlzdCBvZiBjbGFzc2VzIGFuZCBjYWNoZXMgdGhlbSBpbiBvbmUgYmlnIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkY2xhc3NlcyAgIEFuIGFycmF5IG9mIGNsYXNzZXMgdG8gbG9hZAogICAgICogQHBhcmFtIHN0cmluZyAkY2FjaGVEaXIgIEEgY2FjaGUgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgICAgVGhlIGNhY2hlIG5hbWUgcHJlZml4CiAgICAgKiBAcGFyYW0gc3RyaW5nICRleHRlbnNpb24gRmlsZSBleHRlbnNpb24gb2YgdGhlIHJlc3VsdGluZyBmaWxlCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBjbGFzcyBjYW4ndCBiZSBsb2FkZWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBsb2FkKGFycmF5ICRjbGFzc2VzLCAkY2FjaGVEaXIsICRuYW1lLCAkZXh0ZW5zaW9uID0gJy5waHAnKQogICAgewogICAgICAgIC8vIGVhY2ggJG5hbWUgY2FuIG9ubHkgYmUgbG9hZGVkIG9uY2UgcGVyIFBIUCBwcm9jZXNzCiAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRsb2FkZWRbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzZWxmOjokbG9hZGVkWyRuYW1lXSA9IHRydWU7CgogICAgICAgICRjb250ZW50ID0gJyc7CiAgICAgICAgZm9yZWFjaCAoJGNsYXNzZXMgYXMgJGNsYXNzKSB7CiAgICAgICAgICAgIGlmICghY2xhc3NfZXhpc3RzKCRjbGFzcykgJiYgIWludGVyZmFjZV9leGlzdHMoJGNsYXNzKSAmJiAoIWZ1bmN0aW9uX2V4aXN0cygndHJhaXRfZXhpc3RzJykgfHwgIXRyYWl0X2V4aXN0cygkY2xhc3MpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdVbmFibGUgdG8gbG9hZCBjbGFzcyAiJXMiJywgJGNsYXNzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyID0gbmV3IFJlZmxlY3Rpb25DbGFzcygkY2xhc3MpOwogICAgICAgICAgICAkY29udGVudCAuPSBwcmVnX3JlcGxhY2UoYXJyYXkoJy9eXHMqPFw/cGhwLycsICcvXD8+XHMqJC8nKSwgJycsIGZpbGVfZ2V0X2NvbnRlbnRzKCRyLT5nZXRGaWxlTmFtZSgpKSk7CiAgICAgICAgfQoKICAgICAgICAkY2FjaGUgID0gJGNhY2hlRGlyIC4gJy8nIC4gJG5hbWUgLiAkZXh0ZW5zaW9uOwogICAgICAgICRoZWFkZXIgPSBzcHJpbnRmKHNlbGY6OkhFQURFUiwgc3RyZnRpbWUoJyVZJykpOwogICAgICAgIHNlbGY6OndyaXRlQ2FjaGVGaWxlKCRjYWNoZSwgJGhlYWRlciAuIHN1YnN0cihzZWxmOjpzdHJpcENvbW1lbnRzKCc8P3BocCAnIC4gJGNvbnRlbnQpLCA1KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZXMgYSBjYWNoZSBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgICAgRmlsZW5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnQgVGVtcG9yYXJ5IGZpbGUgY29udGVudAogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB3aGVuIGEgY2FjaGUgZmlsZSBjYW5ub3QgYmUgd3JpdHRlbgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB3cml0ZUNhY2hlRmlsZSgkZmlsZSwgJGNvbnRlbnQpCiAgICB7CiAgICAgICAgJHRtcEZpbGUgPSB0ZW1wbmFtKGRpcm5hbWUoJGZpbGUpLCBiYXNlbmFtZSgkZmlsZSkpOwogICAgICAgIGlmIChmYWxzZSAhPT0gQGZpbGVfcHV0X2NvbnRlbnRzKCR0bXBGaWxlLCAkY29udGVudCkgJiYgQHJlbmFtZSgkdG1wRmlsZSwgJGZpbGUpKSB7CiAgICAgICAgICAgIGNobW9kKCRmaWxlLCAwNjY2ICYgfnVtYXNrKCkpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHdyaXRlIGNhY2hlIGZpbGUgIiVzIi4nLCAkZmlsZSkpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBjb21tZW50cyBmcm9tIGEgUEhQIHNvdXJjZSBzdHJpbmcuCiAgICAgKgogICAgICogV2UgZG9uJ3QgdXNlIHRoZSBQSFAgcGhwX3N0cmlwX3doaXRlc3BhY2UoKSBmdW5jdGlvbgogICAgICogYXMgd2Ugd2FudCB0aGUgY29udGVudCB0byBiZSByZWFkYWJsZSBhbmQgd2VsbC1mb3JtYXR0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlIEEgUEhQIHN0cmluZwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBQSFAgc3RyaW5nIHdpdGggdGhlIGNvbW1lbnRzIHJlbW92ZWQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc3RyaXBDb21tZW50cygkc291cmNlKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCd0b2tlbl9nZXRfYWxsJykpIHsKICAgICAgICAgICAgcmV0dXJuICRzb3VyY2U7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0ID0gJyc7CiAgICAgICAgZm9yZWFjaCAodG9rZW5fZ2V0X2FsbCgkc291cmNlKSBhcyAkdG9rZW4pIHsKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdG9rZW4pKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR0b2tlbjsKICAgICAgICAgICAgfSBlbHNlaWYgKCFpbl9hcnJheSgkdG9rZW5bMF0sIGFycmF5KFRfQ09NTUVOVCwgVF9ET0NfQ09NTUVOVCkpKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR0b2tlblsxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gcmVwbGFjZSBtdWx0aXBsZSBuZXcgbGluZXMgd2l0aCBhIHNpbmdsZSBuZXdsaW5lCiAgICAgICAgJG91dHB1dCA9IHByZWdfcmVwbGFjZShhcnJheSgnL1xzKyQvU20nLCAnL1xuKy9TJyksICJcbiIsICRvdXRwdXQpOwoKICAgICAgICByZXR1cm4gJG91dHB1dDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBUZW1wbGF0ZSBMb2FkZXIgaW50ZXJmYWNlLgogKi8KaW50ZXJmYWNlIE11c3RhY2hlX0xvYWRlcgp7CiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZSBieSBuYW1lLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbiBJZiBhIHRlbXBsYXRlIGZpbGUgaXMgbm90IGZvdW5kCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfE11c3RhY2hlX1NvdXJjZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJG5hbWUpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEEgTXVzdGFjaGUgaW1wbGVtZW50YXRpb24gaW4gUEhQLgogKgogKiB7QGxpbmsgaHR0cDovL2RlZnVua3QuZ2l0aHViLmNvbS9tdXN0YWNoZX0KICoKICogTXVzdGFjaGUgaXMgYSBmcmFtZXdvcmstYWdub3N0aWMgbG9naWMtbGVzcyB0ZW1wbGF0aW5nIGxhbmd1YWdlLiBJdCBlbmZvcmNlcyBzZXBhcmF0aW9uIG9mIHZpZXcKICogbG9naWMgZnJvbSB0ZW1wbGF0ZSBmaWxlcy4gSW4gZmFjdCwgaXQgaXMgbm90IGV2ZW4gcG9zc2libGUgdG8gZW1iZWQgbG9naWMgaW4gdGhlIHRlbXBsYXRlLgogKgogKiBUaGlzIGlzIHZlcnksIHZlcnkgcmFkLgogKgogKiBAYXV0aG9yIEp1c3RpbiBIaWxlbWFuIHtAbGluayBodHRwOi8vanVzdGluaGlsZW1hbi5jb219CiAqLwpjbGFzcyBNdXN0YWNoZV9FbmdpbmUKewogICAgY29uc3QgVkVSU0lPTiAgICAgICAgPSAnMi4xNC4wJzsKICAgIGNvbnN0IFNQRUNfVkVSU0lPTiAgID0gJzEuMi4yJzsKCiAgICBjb25zdCBQUkFHTUFfRklMVEVSUyAgICAgID0gJ0ZJTFRFUlMnOwogICAgY29uc3QgUFJBR01BX0JMT0NLUyAgICAgICA9ICdCTE9DS1MnOwogICAgY29uc3QgUFJBR01BX0FOQ0hPUkVEX0RPVCA9ICdBTkNIT1JFRC1ET1QnOwoKICAgIC8vIEtub3duIHByYWdtYXMKICAgIHByaXZhdGUgc3RhdGljICRrbm93blByYWdtYXMgPSBhcnJheSgKICAgICAgICBzZWxmOjpQUkFHTUFfRklMVEVSUyAgICAgID0+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+bG9nKCRsZXZlbCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgcmVuZGVyaW5nIENvbnRleHQuCiAqLwpjbGFzcyBNdXN0YWNoZV9Db250ZXh0CnsKICAgIHByaXZhdGUgJHN0YWNrICAgICAgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkYmxvY2tTdGFjayA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBNdXN0YWNoZSByZW5kZXJpbmcgQ29udGV4dCBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGNvbnRleHQgRGVmYXVsdCByZW5kZXJpbmcgY29udGV4dCAoZGVmYXVsdDogbnVsbCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb250ZXh0ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGNvbnRleHQgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnN0YWNrID0gYXJyYXkoJGNvbnRleHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFB1c2ggYSBuZXcgQ29udGV4dCBmcmFtZSBvbnRvIHRoZSBzdGFjay4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIE9iamVjdCBvciBhcnJheSB0byB1c2UgZm9yIGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHB1c2goJHZhbHVlKQogICAgewogICAgICAgIGFycmF5X3B1c2goJHRoaXMtPnN0YWNrLCAkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogUHVzaCBhIG5ldyBDb250ZXh0IGZyYW1lIG9udG8gdGhlIGJsb2NrIGNvbnRleHQgc3RhY2suCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSBPYmplY3Qgb3IgYXJyYXkgdG8gdXNlIGZvciBibG9jayBjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwdXNoQmxvY2tDb250ZXh0KCR2YWx1ZSkKICAgIHsKICAgICAgICBhcnJheV9wdXNoKCR0aGlzLT5ibG9ja1N0YWNrLCAkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogUG9wIHRoZSBsYXN0IENvbnRleHQgZnJhbWUgZnJvbSB0aGUgc3RhY2suCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBMYXN0IENvbnRleHQgZnJhbWUgKG9iamVjdCBvciBhcnJheSkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBvcCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X3BvcCgkdGhpcy0+c3RhY2spOwogICAgfQoKICAgIC8qKgogICAgICogUG9wIHRoZSBsYXN0IGJsb2NrIENvbnRleHQgZnJhbWUgZnJvbSB0aGUgc3RhY2suCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBMYXN0IGJsb2NrIENvbnRleHQgZnJhbWUgKG9iamVjdCBvciBhcnJheSkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBvcEJsb2NrQ29udGV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X3BvcCgkdGhpcy0+YmxvY2tTdGFjayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGxhc3QgQ29udGV4dCBmcmFtZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIExhc3QgQ29udGV4dCBmcmFtZSAob2JqZWN0IG9yIGFycmF5KQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbGFzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGVuZCgkdGhpcy0+c3RhY2spOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBhIHZhcmlhYmxlIGluIHRoZSBDb250ZXh0IHN0YWNrLgogICAgICoKICAgICAqIFN0YXJ0aW5nIHdpdGggdGhlIGxhc3QgQ29udGV4dCBmcmFtZSAodGhlIGNvbnRleHQgb2YgdGhlIGlubmVybW9zdCBzZWN0aW9uKSwgYW5kIHdvcmtpbmcgYmFjayB0byB0aGUgdG9wLWxldmVsCiAgICAgKiByZW5kZXJpbmcgY29udGV4dCwgbG9vayBmb3IgYSB2YXJpYWJsZSB3aXRoIHRoZSBnaXZlbiBuYW1lOgogICAgICoKICAgICAqICAqIElmIHRoZSBDb250ZXh0IGZyYW1lIGlzIGFuIGFzc29jaWF0aXZlIGFycmF5IHdoaWNoIGNvbnRhaW5zIHRoZSBrZXkgJGlkLCByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGF0IGVsZW1lbnQuCiAgICAgKiAgKiBJZiB0aGUgQ29udGV4dCBmcmFtZSBpcyBhbiBvYmplY3QsIHRoaXMgd2lsbCBjaGVjayBmaXJzdCBmb3IgYSBwdWJsaWMgbWV0aG9kLCB0aGVuIGEgcHVibGljIHByb3BlcnR5IG5hbWVkCiAgICAgKiAgICAkaWQuIEZhaWxpbmcgYm90aCBvZiB0aGVzZSwgaXQgd2lsbCB0cnkgYF9faXNzZXRgIGFuZCBgX19nZXRgIG1hZ2ljIG1ldGhvZHMuCiAgICAgKiAgKiBJZiBhIHZhbHVlIG5hbWVkICRpZCBpcyBub3QgZm91bmQgaW4gYW55IENvbnRleHQgZnJhbWUsIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkIFZhcmlhYmxlIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFZhcmlhYmxlIHZhbHVlLCBvciAnJyBpZiBub3QgZm91bmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmQoJGlkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmluZFZhcmlhYmxlSW5TdGFjaygkaWQsICR0aGlzLT5zdGFjayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kIGEgJ2RvdCBub3RhdGlvbicgdmFyaWFibGUgaW4gdGhlIENvbnRleHQgc3RhY2suCiAgICAgKgogICAgICogTm90ZSB0aGF0IGRvdCBub3RhdGlvbiB0cmF2ZXJzYWwgYnViYmxlcyB0aHJvdWdoIHNjb3BlIGRpZmZlcmVudGx5IHRoYW4gdGhlIHJlZ3VsYXIgZmluZCBtZXRob2QuIEFmdGVyIGZpbmRpbmcKICAgICAqIHRoZSBpbml0aWFsIGNodW5rIG9mIHRoZSBkb3R0ZWQgbmFtZSwgZWFjaCBzdWJzZXF1ZW50IGNodW5rIGlzIHNlYXJjaGVkIGZvciBvbmx5IHdpdGhpbiB0aGUgdmFsdWUgb2YgdGhlIHByZXZpb3VzCiAgICAgKiByZXN1bHQuIEZvciBleGFtcGxlLCBnaXZlbiB0aGUgZm9sbG93aW5nIGNvbnRleHQgc3RhY2s6CiAgICAgKgogICAgICogICAgICRkYXRhID0gYXJyYXkoCiAgICAgKiAgICAgICAgICduYW1lJyA9PiAnRnJlZCcsCiAgICAgKiAgICAgICAgICdjaGlsZCcgPT4gYXJyYXkoCiAgICAgKiAgICAgICAgICAgICAnbmFtZScgPT4gJ0JvYicKICAgICAqICAgICAgICAgKSwKICAgICAqICAgICApOwogICAgICoKICAgICAqIC4uLiBhbmQgdGhlIE11c3RhY2hlIGZvbGxvd2luZyB0ZW1wbGF0ZToKICAgICAqCiAgICAgKiAgICAge3sgY2hpbGQubmFtZSB9fQogICAgICoKICAgICAqIC4uLiB0aGUgYG5hbWVgIHZhbHVlIGlzIG9ubHkgc2VhcmNoZWQgZm9yIHdpdGhpbiB0aGUgYGNoaWxkYCB2YWx1ZSBvZiB0aGUgZ2xvYmFsIENvbnRleHQsIG5vdCB3aXRoaW4gcGFyZW50CiAgICAgKiBDb250ZXh0IGZyYW1lcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCBEb3R0ZWQgdmFyaWFibGUgc2VsZWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFZhcmlhYmxlIHZhbHVlLCBvciAnJyBpZiBub3QgZm91bmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmREb3QoJGlkKQogICAgewogICAgICAgICRjaHVua3MgPSBleHBsb2RlKCcuJywgJGlkKTsKICAgICAgICAkZmlyc3QgID0gYXJyYXlfc2hpZnQoJGNodW5rcyk7CiAgICAgICAgJHZhbHVlICA9ICR0aGlzLT5maW5kVmFyaWFibGVJblN0YWNrKCRmaXJzdCwgJHRoaXMtPnN0YWNrKTsKCiAgICAgICAgZm9yZWFjaCAoJGNodW5rcyBhcyAkY2h1bmspIHsKICAgICAgICAgICAgaWYgKCR2YWx1ZSA9PT0gJycpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5maW5kVmFyaWFibGVJblN0YWNrKCRjaHVuaywgYXJyYXkoJHZhbHVlKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBhbiAnYW5jaG9yZWQgZG90IG5vdGF0aW9uJyB2YXJpYWJsZSBpbiB0aGUgQ29udGV4dCBzdGFjay4KICAgICAqCiAgICAgKiBUaGlzIGlzIHRoZSBzYW1lIGFzIGZpbmREb3QoKSwgZXhjZXB0IGl0IGxvb2tzIGluIHRoZSB0b3Agb2YgdGhlIGNvbnRleHQKICAgICAqIHN0YWNrIGZvciB0aGUgZmlyc3QgdmFsdWUsIHJhdGhlciB0aGFuIHNlYXJjaGluZyB0aGUgd2hvbGUgY29udGV4dCBzdGFjawogICAgICogYW5kIHN0YXJ0aW5nIGZyb20gdGhlcmUuCiAgICAgKgogICAgICogQHNlZSBNdXN0YWNoZV9Db250ZXh0OjpmaW5kRG90CiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGdpdmVuIGFuIGludmFsaWQgYW5jaG9yZWQgZG90ICRpZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkIERvdHRlZCB2YXJpYWJsZSBzZWxlY3RvcgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgVmFyaWFibGUgdmFsdWUsIG9yICcnIGlmIG5vdCBmb3VuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZEFuY2hvcmVkRG90KCRpZCkKICAgIHsKICAgICAgICAkY2h1bmtzID0gZXhwbG9kZSgnLicsICRpZCk7CiAgICAgICAgJGZpcnN0ICA9IGFycmF5X3NoaWZ0KCRjaHVua3MpOwogICAgICAgIGlmICgkZmlyc3QgIT09ICcnKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1VuZXhwZWN0ZWQgaWQgZm9yIGZpbmRBbmNob3JlZERvdDogJXMnLCAkaWQpKTsKICAgICAgICB9CgogICAgICAgICR2YWx1ZSAgPSAkdGhpcy0+bGFzdCgpOwoKICAgICAgICBmb3JlYWNoICgkY2h1bmtzIGFzICRjaHVuaykgewogICAgICAgICAgICBpZiAoJHZhbHVlID09PSAnJykgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmZpbmRWYXJpYWJsZUluU3RhY2soJGNodW5rLCBhcnJheSgkdmFsdWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kIGFuIGFyZ3VtZW50IGluIHRoZSBibG9jayBjb250ZXh0IHN0YWNrLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBWYXJpYWJsZSB2YWx1ZSwgb3IgJycgaWYgbm90IGZvdW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kSW5CbG9jaygkaWQpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmJsb2NrU3RhY2sgYXMgJGNvbnRleHQpIHsKICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJGlkLCAkY29udGV4dCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29udGV4dFskaWRdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJyc7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gZmluZCBhIHZhcmlhYmxlIGluIHRoZSBDb250ZXh0IHN0YWNrLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfQ29udGV4dDo6ZmluZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgIFZhcmlhYmxlIG5hbWUKICAgICAqIEBwYXJhbSBhcnJheSAgJHN0YWNrIENvbnRleHQgc3RhY2sKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFZhcmlhYmxlIHZhbHVlLCBvciAnJyBpZiBub3QgZm91bmQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaW5kVmFyaWFibGVJblN0YWNrKCRpZCwgYXJyYXkgJHN0YWNrKQogICAgewogICAgICAgIGZvciAoJGkgPSBjb3VudCgkc3RhY2spIC0gMTsgJGkgPj0gMDsgJGktLSkgewogICAgICAgICAgICAkZnJhbWUgPSAmJHN0YWNrWyRpXTsKCiAgICAgICAgICAgIHN3aXRjaCAoZ2V0dHlwZSgkZnJhbWUpKSB7CiAgICAgICAgICAgICAgICBjYXNlICdvYmplY3QnOgogICAgICAgICAgICAgICAgICAgIGlmICghKCRmcmFtZSBpbnN0YW5jZW9mIENsb3N1cmUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCBpc19jYWxsYWJsZSgpICp3aWxsIG5vdCB3b3JrIGhlcmUqCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYm9idGhlY293L211c3RhY2hlLnBocC93aWtpL01hZ2ljLU1ldGhvZHMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJGZyYW1lLCAkaWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZyYW1lLT4kaWQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRmcmFtZS0+JGlkKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmcmFtZS0+JGlkOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGZyYW1lIGluc3RhbmNlb2YgQXJyYXlBY2Nlc3MgJiYgaXNzZXQoJGZyYW1lWyRpZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZyYW1lWyRpZF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnYXJyYXknOgogICAgICAgICAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCRpZCwgJGZyYW1lKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZyYW1lWyRpZF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJyc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogRGVzY3JpYmVzIGEgTXVzdGFjaGUgbG9nZ2VyIGluc3RhbmNlLgogKgogKiBUaGlzIGlzIGlkZW50aWNhbCB0byB0aGUgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2UuCiAqCiAqIFRoZSBtZXNzYWdlIE1VU1QgYmUgYSBzdHJpbmcgb3Igb2JqZWN0IGltcGxlbWVudGluZyBfX3RvU3RyaW5nKCkuCiAqCiAqIFRoZSBtZXNzYWdlIE1BWSBjb250YWluIHBsYWNlaG9sZGVycyBpbiB0aGUgZm9ybToge2Zvb30gd2hlcmUgZm9vCiAqIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIGNvbnRleHQgZGF0YSBpbiBrZXkgImZvbyIuCiAqCiAqIFRoZSBjb250ZXh0IGFycmF5IGNhbiBjb250YWluIGFyYml0cmFyeSBkYXRhLCB0aGUgb25seSBhc3N1bXB0aW9uIHRoYXQKICogY2FuIGJlIG1hZGUgYnkgaW1wbGVtZW50b3JzIGlzIHRoYXQgaWYgYW4gRXhjZXB0aW9uIGluc3RhbmNlIGlzIGdpdmVuCiAqIHRvIHByb2R1Y2UgYSBzdGFjayB0cmFjZSwgaXQgTVVTVCBiZSBpbiBhIGtleSBuYW1lZCAiZXhjZXB0aW9uIi4KICoKICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9waHAtZmlnL2ZpZy1zdGFuZGFyZHMvYmxvYi9tYXN0ZXIvYWNjZXB0ZWQvUFNSLTMtbG9nZ2VyLWludGVyZmFjZS5tZAogKiBmb3IgdGhlIGZ1bGwgaW50ZXJmYWNlIHNwZWNpZmljYXRpb24uCiAqLwppbnRlcmZhY2UgTXVzdGFjaGVfTG9nZ2VyCnsKICAgIC8qKgogICAgICogUHNyXExvZyBjb21wYXRpYmxlIGxvZyBsZXZlbHMuCiAgICAgKi8KICAgIGNvbnN0IEVNRVJHRU5DWSA9ICdlbWVyZ2VuY3knOwogICAgY29uc3QgQUxFUlQgICAgID0gJ2FsZXJ0JzsKICAgIGNvbnN0IENSSVRJQ0FMICA9ICdjcml0aWNhbCc7CiAgICBjb25zdCBFUlJPUiAgICAgPSAnZXJyb3InOwogICAgY29uc3QgV0FSTklORyAgID0gJ3dhcm5pbmcnOwogICAgY29uc3QgTk9USUNFICAgID0gJ25vdGljZSc7CiAgICBjb25zdCBJTkZPICAgICAgPSAnaW5mbyc7CiAgICBjb25zdCBERUJVRyAgICAgPSAnZGVidWcnOwoKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVtZXJnZW5jeSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIEFjdGlvbiBtdXN0IGJlIHRha2VuIGltbWVkaWF0ZWx5LgogICAgICoKICAgICAqIEV4YW1wbGU6IEVudGlyZSB3ZWJzaXRlIGRvd24sIGRhdGFiYXNlIHVuYXZhaWxhYmxlLCBldGMuIFRoaXMgc2hvdWxkCiAgICAgKiB0cmlnZ2VyIHRoZSBTTVMgYWxlcnRzIGFuZCB3YWtlIHlvdSB1cC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGVydCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIENyaXRpY2FsIGNvbmRpdGlvbnMuCiAgICAgKgogICAgICogRXhhbXBsZTogQXBwbGljYXRpb24gY29tcG9uZW50IHVuYXZhaWxhYmxlLCB1bmV4cGVjdGVkIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcml0aWNhbCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIFJ1bnRpbWUgZXJyb3JzIHRoYXQgZG8gbm90IHJlcXVpcmUgaW1tZWRpYXRlIGFjdGlvbiBidXQgc2hvdWxkIHR5cGljYWxseQogICAgICogYmUgbG9nZ2VkIGFuZCBtb25pdG9yZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXJyb3IoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBFeGNlcHRpb25hbCBvY2N1cnJlbmNlcyB0aGF0IGFyZSBub3QgZXJyb3JzLgogICAgICoKICAgICAqIEV4YW1wbGU6IFVzZSBvZiBkZXByZWNhdGVkIEFQSXMsIHBvb3IgdXNlIG9mIGFuIEFQSSwgdW5kZXNpcmFibGUgdGhpbmdzCiAgICAgKiB0aGF0IGFyZSBub3QgbmVjZXNzYXJpbHkgd3JvbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FybmluZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIE5vcm1hbCBidXQgc2lnbmlmaWNhbnQgZXZlbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdGljZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIEludGVyZXN0aW5nIGV2ZW50cy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBVc2VyIGxvZ3MgaW4sIFNRTCBsb2dzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluZm8oJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBEZXRhaWxlZCBkZWJ1ZyBpbmZvcm1hdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWJ1ZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIExvZ3Mgd2l0aCBhbiBhcmJpdHJhcnkgbGV2ZWwuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIENvbXBpbGVyIGNsYXNzLgogKgogKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciB0dXJuaW5nIGEgTXVzdGFjaGUgdG9rZW4gcGFyc2UgdHJlZSBpbnRvIG5vcm1hbCBQSFAgc291cmNlIGNvZGUuCiAqLwpjbGFzcyBNdXN0YWNoZV9Db21waWxlcgp7CiAgICBwcml2YXRlICRwcmFnbWFzOwogICAgcHJpdmF0ZSAkZGVmYXVsdFByYWdtYXMgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkc2VjdGlvbnM7CiAgICBwcml2YXRlICRibG9ja3M7CiAgICBwcml2YXRlICRzb3VyY2U7CiAgICBwcml2YXRlICRpbmRlbnROZXh0TGluZTsKICAgIHByaXZhdGUgJGN1c3RvbUVzY2FwZTsKICAgIHByaXZhdGUgJGVudGl0eUZsYWdzOwogICAgcHJpdmF0ZSAkY2hhcnNldDsKICAgIHByaXZhdGUgJHN0cmljdENhbGxhYmxlczsKCiAgICAvKioKICAgICAqIENvbXBpbGUgYSBNdXN0YWNoZSB0b2tlbiBwYXJzZSB0cmVlIGludG8gUEhQIHNvdXJjZSBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZSAgICAgICAgICBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UgY29kZQogICAgICogQHBhcmFtIHN0cmluZyAkdHJlZSAgICAgICAgICAgIFBhcnNlIHRyZWUgb2YgTXVzdGFjaGUgdG9rZW5zCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgICAgICAgICAgTXVzdGFjaGUgVGVtcGxhdGUgY2xhc3MgbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAkY3VzdG9tRXNjYXBlICAgIChkZWZhdWx0OiBmYWxzZSkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNoYXJzZXQgICAgICAgICAoZGVmYXVsdDogJ1VURi04JykKICAgICAqIEBwYXJhbSBib29sICAgJHN0cmljdENhbGxhYmxlcyAoZGVmYXVsdDogZmFsc2UpCiAgICAgKiBAcGFyYW0gaW50ICAgICRlbnRpdHlGbGFncyAgICAgKGRlZmF1bHQ6IEVOVF9DT01QQVQpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGlsZSgkc291cmNlLCBhcnJheSAkdHJlZSwgJG5hbWUsICRjdXN0b21Fc2NhcGUgPSBmYWxzZSwgJGNoYXJzZXQgPSAnVVRGLTgnLCAkc3RyaWN0Q2FsbGFibGVzID0gZmFsc2UsICRlbnRpdHlGbGFncyA9IEVOVF9DT01QQVQpCiAgICB7CiAgICAgICAgJHRoaXMtPnByYWdtYXMgICAgICAgICA9ICR0aGlzLT5kZWZhdWx0UHJhZ21hczsKICAgICAgICAkdGhpcy0+c2VjdGlvbnMgICAgICAgID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+YmxvY2tzICAgICAgICAgID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+c291cmNlICAgICAgICAgID0gJHNvdXJjZTsKICAgICAgICAkdGhpcy0+aW5kZW50TmV4dExpbmUgID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+Y3VzdG9tRXNjYXBlICAgID0gJGN1c3RvbUVzY2FwZTsKICAgICAgICAkdGhpcy0+ZW50aXR5RmxhZ3MgICAgID0gJGVudGl0eUZsYWdzOwogICAgICAgICR0aGlzLT5jaGFyc2V0ICAgICAgICAgPSAkY2hhcnNldDsKICAgICAgICAkdGhpcy0+c3RyaWN0Q2FsbGFibGVzID0gJHN0cmljdENhbGxhYmxlczsKCiAgICAgICAgcmV0dXJuICR0aGlzLT53cml0ZUNvZGUoJHRyZWUsICRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZSBwcmFnbWFzIGFjcm9zcyBhbGwgdGVtcGxhdGVzLCByZWdhcmRsZXNzIG9mIHRoZSBwcmVzZW5jZSBvZiBwcmFnbWEKICAgICAqIHRhZ3MgaW4gdGhlIGluZGl2aWR1YWwgdGVtcGxhdGVzLgogICAgICoKICAgICAqIEBpbnRlcm5hbCBVc2VycyBzaG91bGQgc2V0IGdsb2JhbCBwcmFnbWFzIGluIE11c3RhY2hlX0VuZ2luZSwgbm90IGhlcmUgOikKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHByYWdtYXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByYWdtYXMoYXJyYXkgJHByYWdtYXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnByYWdtYXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwcmFnbWFzIGFzICRwcmFnbWEpIHsKICAgICAgICAgICAgJHRoaXMtPnByYWdtYXNbJHByYWdtYV0gPSB0cnVlOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZGVmYXVsdFByYWdtYXMgPSAkdGhpcy0+cHJhZ21hczsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBmdW5jdGlvbiBmb3Igd2Fsa2luZyB0aGUgTXVzdGFjaGUgdG9rZW4gcGFyc2UgdHJlZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24gdXBvbiBlbmNvdW50ZXJpbmcgdW5rbm93biB0b2tlbiB0eXBlcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdHJlZSAgUGFyc2UgdHJlZSBvZiBNdXN0YWNoZSB0b2tlbnMKICAgICAqIEBwYXJhbSBpbnQgICAkbGV2ZWwgKGRlZmF1bHQ6IDApCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdhbGsoYXJyYXkgJHRyZWUsICRsZXZlbCA9IDApCiAgICB7CiAgICAgICAgJGNvZGUgPSAnJzsKICAgICAgICAkbGV2ZWwrKzsKICAgICAgICBmb3JlYWNoICgkdHJlZSBhcyAkbm9kZSkgewogICAgICAgICAgICBzd2l0Y2ggKCRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6VFlQRV0pIHsKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1BSQUdNQToKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cHJhZ21hc1skbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfU0VDVElPTjoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+c2VjdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOT0RFU10sCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgIGlzc2V0KCRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RklMVEVSU10pID8gJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpGSUxURVJTXSA6IGFycmF5KCksCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6SU5ERVhdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkVORF0sCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6T1RBR10sCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6Q1RBR10sCiAgICAgICAgICAgICAgICAgICAgICAgICRsZXZlbAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfSU5WRVJURUQ6CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPmludmVydGVkU2VjdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOT0RFU10sCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgIGlzc2V0KCRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RklMVEVSU10pID8gJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpGSUxURVJTXSA6IGFycmF5KCksCiAgICAgICAgICAgICAgICAgICAgICAgICRsZXZlbAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfUEFSVElBTDoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cGFydGlhbCgKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNzZXQoJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFTlRdKSA/ICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6SU5ERU5UXSA6ICcnLAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1BBUkVOVDoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cGFyZW50KAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICBpc3NldCgkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OklOREVOVF0pID8gJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFTlRdIDogJycsCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6Tk9ERVNdLAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0JMT0NLX0FSRzoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+YmxvY2tBcmcoCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6Tk9ERVNdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OklOREVYXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpFTkRdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok9UQUddLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkNUQUddLAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0JMT0NLX1ZBUjoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+YmxvY2tWYXIoCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6Tk9ERVNdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OklOREVYXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpFTkRdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok9UQUddLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkNUQUddLAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0NPTU1FTlQ6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfRVNDQVBFRDoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1VORVNDQVBFRDoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1VORVNDQVBFRF8yOgogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT52YXJpYWJsZSgKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNzZXQoJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpGSUxURVJTXSkgPyAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkZJTFRFUlNdIDogYXJyYXkoKSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSA9PT0gTXVzdGFjaGVfVG9rZW5pemVyOjpUX0VTQ0FQRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICRsZXZlbAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfVEVYVDoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+dGV4dCgkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OlZBTFVFXSwgJGxldmVsKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uKHNwcmludGYoJ1Vua25vd24gdG9rZW4gdHlwZTogJXMnLCAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OlRZUEVdKSwgJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvZGU7CiAgICB9CgogICAgY29uc3QgS0xBU1MgPSAnPD9waHAKCiAgICAgICAgY2xhc3MgJXMgZXh0ZW5kcyBNdXN0YWNoZV9UZW1wbGF0ZQogICAgICAgIHsKICAgICAgICAgICAgcHJpdmF0ZSAkbGFtYmRhSGVscGVyOyVzCgogICAgICAgICAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVySW50ZXJuYWwoTXVzdGFjaGVfQ29udGV4dCAkY29udGV4dCwgJGluZGVudCA9IFwnXCcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICR0aGlzLT5sYW1iZGFIZWxwZXIgPSBuZXcgTXVzdGFjaGVfTGFtYmRhSGVscGVyKCR0aGlzLT5tdXN0YWNoZSwgJGNvbnRleHQpOwogICAgICAgICAgICAgICAgJGJ1ZmZlciA9IFwnXCc7CiAgICAgICAgJXMKCiAgICAgICAgICAgICAgICByZXR1cm4gJGJ1ZmZlcjsKICAgICAgICAgICAgfQogICAgICAgICVzCiAgICAgICAgJXMKICAgICAgICB9JzsKCiAgICBjb25zdCBLTEFTU19OT19MQU1CREFTID0gJzw/cGhwCgogICAgICAgIGNsYXNzICVzIGV4dGVuZHMgTXVzdGFjaGVfVGVtcGxhdGUKICAgICAgICB7JXMKICAgICAgICAgICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlckludGVybmFsKE11c3RhY2hlX0NvbnRleHQgJGNvbnRleHQsICRpbmRlbnQgPSBcJ1wnKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAkYnVmZmVyID0gXCdcJzsKICAgICAgICAlcwoKICAgICAgICAgICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgICAgICAgICB9CiAgICAgICAgfSc7CgogICAgY29uc3QgU1RSSUNUX0NBTExBQkxFID0gJ3Byb3RlY3RlZCAkc3RyaWN0Q2FsbGFibGVzID0gdHJ1ZTsnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgY2xhc3MgUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICR0cmVlIFBhcnNlIHRyZWUgb2YgTXVzdGFjaGUgdG9rZW5zCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIE11c3RhY2hlIFRlbXBsYXRlIGNsYXNzIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgUEhQIHNvdXJjZSBjb2RlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gd3JpdGVDb2RlKCR0cmVlLCAkbmFtZSkKICAgIHsKICAgICAgICAkY29kZSAgICAgPSAkdGhpcy0+d2FsaygkdHJlZSk7CiAgICAgICAgJHNlY3Rpb25zID0gaW1wbG9kZSgiXG4iLCAkdGhpcy0+c2VjdGlvbnMpOwogICAgICAgICRibG9ja3MgICA9IGltcGxvZGUoIlxuIiwgJHRoaXMtPmJsb2Nrcyk7CiAgICAgICAgJGtsYXNzICAgID0gZW1wdHkoJHRoaXMtPnNlY3Rpb25zKSAmJiBlbXB0eSgkdGhpcy0+YmxvY2tzKSA/IHNlbGY6OktMQVNTX05PX0xBTUJEQVMgOiBzZWxmOjpLTEFTUzsKCiAgICAgICAgJGNhbGxhYmxlID0gJHRoaXMtPnN0cmljdENhbGxhYmxlcyA/ICR0aGlzLT5wcmVwYXJlKHNlbGY6OlNUUklDVF9DQUxMQUJMRSkgOiAnJzsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoJGtsYXNzLCAwLCBmYWxzZSwgdHJ1ZSksICRuYW1lLCAkY2FsbGFibGUsICRjb2RlLCAkc2VjdGlvbnMsICRibG9ja3MpOwogICAgfQoKICAgIGNvbnN0IEJMT0NLX1ZBUiA9ICcKICAgICAgICAkYmxvY2tGdW5jdGlvbiA9ICRjb250ZXh0LT5maW5kSW5CbG9jayglcyk7CiAgICAgICAgaWYgKGlzX2NhbGxhYmxlKCRibG9ja0Z1bmN0aW9uKSkgewogICAgICAgICAgICAkYnVmZmVyIC49IGNhbGxfdXNlcl9mdW5jKCRibG9ja0Z1bmN0aW9uLCAkY29udGV4dCk7CiAgICAgICAgJXN9CiAgICAnOwoKICAgIGNvbnN0IEJMT0NLX1ZBUl9FTFNFID0gJ30gZWxzZSB7JXMnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgaW5oZXJpdGFuY2UgYmxvY2sgdmFyaWFibGUgUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICRub2RlcyBBcnJheSBvZiBjaGlsZCB0b2tlbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgIFNlY3Rpb24gbmFtZQogICAgICogQHBhcmFtIGludCAgICAkc3RhcnQgU2VjdGlvbiBzdGFydCBvZmZzZXQKICAgICAqIEBwYXJhbSBpbnQgICAgJGVuZCAgIFNlY3Rpb24gZW5kIG9mZnNldAogICAgICogQHBhcmFtIHN0cmluZyAkb3RhZyAgQ3VycmVudCBNdXN0YWNoZSBvcGVuaW5nIHRhZwogICAgICogQHBhcmFtIHN0cmluZyAkY3RhZyAgQ3VycmVudCBNdXN0YWNoZSBjbG9zaW5nIHRhZwogICAgICogQHBhcmFtIGludCAgICAkbGV2ZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgUEhQIHNvdXJjZSBjb2RlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYmxvY2tWYXIoJG5vZGVzLCAkaWQsICRzdGFydCwgJGVuZCwgJG90YWcsICRjdGFnLCAkbGV2ZWwpCiAgICB7CiAgICAgICAgJGlkID0gdmFyX2V4cG9ydCgkaWQsIHRydWUpOwoKICAgICAgICAkZWxzZSA9ICR0aGlzLT53YWxrKCRub2RlcywgJGxldmVsKTsKICAgICAgICBpZiAoJGVsc2UgIT09ICcnKSB7CiAgICAgICAgICAgICRlbHNlID0gc3ByaW50ZigkdGhpcy0+cHJlcGFyZShzZWxmOjpCTE9DS19WQVJfRUxTRSwgJGxldmVsICsgMSwgZmFsc2UsIHRydWUpLCAkZWxzZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZigkdGhpcy0+cHJlcGFyZShzZWxmOjpCTE9DS19WQVIsICRsZXZlbCksICRpZCwgJGVsc2UpOwogICAgfQoKICAgIGNvbnN0IEJMT0NLX0FSRyA9ICclcyA9PiBhcnJheSgkdGhpcywgXCdibG9jayVzXCcpLCc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBpbmhlcml0YW5jZSBibG9jayBhcmd1bWVudCBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgJG5vZGVzIEFycmF5IG9mIGNoaWxkIHRva2VucwogICAgICogQHBhcmFtIHN0cmluZyAkaWQgICAgU2VjdGlvbiBuYW1lCiAgICAgKiBAcGFyYW0gaW50ICAgICRzdGFydCBTZWN0aW9uIHN0YXJ0IG9mZnNldAogICAgICogQHBhcmFtIGludCAgICAkZW5kICAgU2VjdGlvbiBlbmQgb2Zmc2V0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvdGFnICBDdXJyZW50IE11c3RhY2hlIG9wZW5pbmcgdGFnCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjdGFnICBDdXJyZW50IE11c3RhY2hlIGNsb3NpbmcgdGFnCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBQSFAgc291cmNlIGNvZGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBibG9ja0FyZygkbm9kZXMsICRpZCwgJHN0YXJ0LCAkZW5kLCAkb3RhZywgJGN0YWcsICRsZXZlbCkKICAgIHsKICAgICAgICAka2V5ID0gJHRoaXMtPmJsb2NrKCRub2Rlcyk7CiAgICAgICAgJGlkID0gdmFyX2V4cG9ydCgkaWQsIHRydWUpOwoKICAgICAgICByZXR1cm4gc3ByaW50ZigkdGhpcy0+cHJlcGFyZShzZWxmOjpCTE9DS19BUkcsICRsZXZlbCksICRpZCwgJGtleSk7CiAgICB9CgogICAgY29uc3QgQkxPQ0tfRlVOQ1RJT04gPSAnCiAgICAgICAgcHVibGljIGZ1bmN0aW9uIGJsb2NrJXMoJGNvbnRleHQpCiAgICAgICAgewogICAgICAgICAgICAkaW5kZW50ID0gJGJ1ZmZlciA9IFwnXCc7JXMKCiAgICAgICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgICAgIH0KICAgICc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBpbmhlcml0YW5jZSBibG9jayBmdW5jdGlvbiBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkbm9kZXMgQXJyYXkgb2YgY2hpbGQgdG9rZW5zCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcga2V5IG9mIG5ldyBibG9jayBmdW5jdGlvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGJsb2NrKCRub2RlcykKICAgIHsKICAgICAgICAkY29kZSA9ICR0aGlzLT53YWxrKCRub2RlcywgMCk7CiAgICAgICAgJGtleSA9IHVjZmlyc3QobWQ1KCRjb2RlKSk7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmJsb2Nrc1ska2V5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPmJsb2Nrc1ska2V5XSA9IHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6QkxPQ0tfRlVOQ1RJT04sIDApLCAka2V5LCAkY29kZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGtleTsKICAgIH0KCiAgICBjb25zdCBTRUNUSU9OX0NBTEwgPSAnCiAgICAgICAgJHZhbHVlID0gJGNvbnRleHQtPiVzKCVzKTslcwogICAgICAgICRidWZmZXIgLj0gJHRoaXMtPnNlY3Rpb24lcygkY29udGV4dCwgJGluZGVudCwgJHZhbHVlKTsKICAgICc7CgogICAgY29uc3QgU0VDVElPTiA9ICcKICAgICAgICBwcml2YXRlIGZ1bmN0aW9uIHNlY3Rpb24lcyhNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0LCAkaW5kZW50LCAkdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICAkYnVmZmVyID0gXCdcJzsKCiAgICAgICAgICAgIGlmICglcykgewogICAgICAgICAgICAgICAgJHNvdXJjZSA9ICVzOwogICAgICAgICAgICAgICAgJHJlc3VsdCA9IChzdHJpbmcpIGNhbGxfdXNlcl9mdW5jKCR2YWx1ZSwgJHNvdXJjZSwgJXMpOwogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkcmVzdWx0LCBcJ3t7XCcpID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJHJlc3VsdDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkdGhpcy0+bXVzdGFjaGUKICAgICAgICAgICAgICAgICAgICAgICAgLT5sb2FkTGFtYmRhKCRyZXN1bHQlcykKICAgICAgICAgICAgICAgICAgICAgICAgLT5yZW5kZXJJbnRlcm5hbCgkY29udGV4dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICghZW1wdHkoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgJHZhbHVlcyA9ICR0aGlzLT5pc0l0ZXJhYmxlKCR2YWx1ZSkgPyAkdmFsdWUgOiBhcnJheSgkdmFsdWUpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlcyBhcyAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkY29udGV4dC0+cHVzaCgkdmFsdWUpOwogICAgICAgICAgICAgICAgICAgICVzCiAgICAgICAgICAgICAgICAgICAgJGNvbnRleHQtPnBvcCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGJ1ZmZlcjsKICAgICAgICB9CiAgICAnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgc2VjdGlvbiBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgICAkbm9kZXMgICBBcnJheSBvZiBjaGlsZCB0b2tlbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkaWQgICAgICBTZWN0aW9uIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkZmlsdGVycyBBcnJheSBvZiBmaWx0ZXJzCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJHN0YXJ0ICAgU2VjdGlvbiBzdGFydCBvZmZzZXQKICAgICAqIEBwYXJhbSBpbnQgICAgICAkZW5kICAgICBTZWN0aW9uIGVuZCBvZmZzZXQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkb3RhZyAgICBDdXJyZW50IE11c3RhY2hlIG9wZW5pbmcgdGFnCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJGN0YWcgICAgQ3VycmVudCBNdXN0YWNoZSBjbG9zaW5nIHRhZwogICAgICogQHBhcmFtIGludCAgICAgICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBzZWN0aW9uIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNlY3Rpb24oJG5vZGVzLCAkaWQsICRmaWx0ZXJzLCAkc3RhcnQsICRlbmQsICRvdGFnLCAkY3RhZywgJGxldmVsKQogICAgewogICAgICAgICRzb3VyY2UgICA9IHZhcl9leHBvcnQoc3Vic3RyKCR0aGlzLT5zb3VyY2UsICRzdGFydCwgJGVuZCAtICRzdGFydCksIHRydWUpOwogICAgICAgICRjYWxsYWJsZSA9ICR0aGlzLT5nZXRDYWxsYWJsZSgpOwoKICAgICAgICBpZiAoJG90YWcgIT09ICd7eycgfHwgJGN0YWcgIT09ICd9fScpIHsKICAgICAgICAgICAgJGRlbGltVGFnID0gdmFyX2V4cG9ydChzcHJpbnRmKCd7ez0gJXMgJXMgPX19JywgJG90YWcsICRjdGFnKSwgdHJ1ZSk7CiAgICAgICAgICAgICRoZWxwZXIgPSBzcHJpbnRmKCckdGhpcy0+bGFtYmRhSGVscGVyLT53aXRoRGVsaW1pdGVycyglcyknLCAkZGVsaW1UYWcpOwogICAgICAgICAgICAkZGVsaW1zID0gJywgJyAuICRkZWxpbVRhZzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaGVscGVyID0gJyR0aGlzLT5sYW1iZGFIZWxwZXInOwogICAgICAgICAgICAkZGVsaW1zID0gJyc7CiAgICAgICAgfQoKICAgICAgICAka2V5ID0gdWNmaXJzdChtZDUoJGRlbGltcyAuICJcbiIgLiAkc291cmNlKSk7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnNlY3Rpb25zWyRrZXldKSkgewogICAgICAgICAgICAkdGhpcy0+c2VjdGlvbnNbJGtleV0gPSBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OlNFQ1RJT04pLCAka2V5LCAkY2FsbGFibGUsICRzb3VyY2UsICRoZWxwZXIsICRkZWxpbXMsICR0aGlzLT53YWxrKCRub2RlcywgMikpOwogICAgICAgIH0KCiAgICAgICAgJG1ldGhvZCAgPSAkdGhpcy0+Z2V0RmluZE1ldGhvZCgkaWQpOwogICAgICAgICRpZCAgICAgID0gdmFyX2V4cG9ydCgkaWQsIHRydWUpOwogICAgICAgICRmaWx0ZXJzID0gJHRoaXMtPmdldEZpbHRlcnMoJGZpbHRlcnMsICRsZXZlbCk7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OlNFQ1RJT05fQ0FMTCwgJGxldmVsKSwgJG1ldGhvZCwgJGlkLCAkZmlsdGVycywgJGtleSk7CiAgICB9CgogICAgY29uc3QgSU5WRVJURURfU0VDVElPTiA9ICcKICAgICAgICAkdmFsdWUgPSAkY29udGV4dC0+JXMoJXMpOyVzCiAgICAgICAgaWYgKGVtcHR5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgJXMKICAgICAgICB9CiAgICAnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgaW52ZXJ0ZWQgc2VjdGlvbiBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgICAkbm9kZXMgICBBcnJheSBvZiBjaGlsZCB0b2tlbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkaWQgICAgICBTZWN0aW9uIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkZmlsdGVycyBBcnJheSBvZiBmaWx0ZXJzCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGxldmVsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIGludmVydGVkIHNlY3Rpb24gUEhQIHNvdXJjZSBjb2RlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaW52ZXJ0ZWRTZWN0aW9uKCRub2RlcywgJGlkLCAkZmlsdGVycywgJGxldmVsKQogICAgewogICAgICAgICRtZXRob2QgID0gJHRoaXMtPmdldEZpbmRNZXRob2QoJGlkKTsKICAgICAgICAkaWQgICAgICA9IHZhcl9leHBvcnQoJGlkLCB0cnVlKTsKICAgICAgICAkZmlsdGVycyA9ICR0aGlzLT5nZXRGaWx0ZXJzKCRmaWx0ZXJzLCAkbGV2ZWwpOwoKICAgICAgICByZXR1cm4gc3ByaW50ZigkdGhpcy0+cHJlcGFyZShzZWxmOjpJTlZFUlRFRF9TRUNUSU9OLCAkbGV2ZWwpLCAkbWV0aG9kLCAkaWQsICRmaWx0ZXJzLCAkdGhpcy0+d2Fsaygkbm9kZXMsICRsZXZlbCkpOwogICAgfQoKICAgIGNvbnN0IFBBUlRJQUxfSU5ERU5UID0gJywgJGluZGVudCAuICVzJzsKICAgIGNvbnN0IFBBUlRJQUwgPSAnCiAgICAgICAgaWYgKCRwYXJ0aWFsID0gJHRoaXMtPm11c3RhY2hlLT5sb2FkUGFydGlhbCglcykpIHsKICAgICAgICAgICAgJGJ1ZmZlciAuPSAkcGFydGlhbC0+cmVuZGVySW50ZXJuYWwoJGNvbnRleHQlcyk7CiAgICAgICAgfQogICAgJzsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlIE11c3RhY2hlIFRlbXBsYXRlIHBhcnRpYWwgY2FsbCBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgICBQYXJ0aWFsIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGluZGVudCBXaGl0ZXNwYWNlIGluZGVudCB0byBhcHBseSB0byBwYXJ0aWFsCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBwYXJ0aWFsIGNhbGwgUEhQIHNvdXJjZSBjb2RlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcGFydGlhbCgkaWQsICRpbmRlbnQsICRsZXZlbCkKICAgIHsKICAgICAgICBpZiAoJGluZGVudCAhPT0gJycpIHsKICAgICAgICAgICAgJGluZGVudFBhcmFtID0gc3ByaW50ZihzZWxmOjpQQVJUSUFMX0lOREVOVCwgdmFyX2V4cG9ydCgkaW5kZW50LCB0cnVlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGluZGVudFBhcmFtID0gJyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZigKICAgICAgICAgICAgJHRoaXMtPnByZXBhcmUoc2VsZjo6UEFSVElBTCwgJGxldmVsKSwKICAgICAgICAgICAgdmFyX2V4cG9ydCgkaWQsIHRydWUpLAogICAgICAgICAgICAkaW5kZW50UGFyYW0KICAgICAgICApOwogICAgfQoKICAgIGNvbnN0IFBBUkVOVCA9ICcKICAgICAgICBpZiAoJHBhcmVudCA9ICR0aGlzLT5tdXN0YWNoZS0+bG9hZFBhcnRpYWwoJXMpKSB7CiAgICAgICAgICAgICRjb250ZXh0LT5wdXNoQmxvY2tDb250ZXh0KGFycmF5KCVzCiAgICAgICAgICAgICkpOwogICAgICAgICAgICAkYnVmZmVyIC49ICRwYXJlbnQtPnJlbmRlckludGVybmFsKCRjb250ZXh0LCAkaW5kZW50KTsKICAgICAgICAgICAgJGNvbnRleHQtPnBvcEJsb2NrQ29udGV4dCgpOwogICAgICAgIH0KICAgICc7CgogICAgY29uc3QgUEFSRU5UX05PX0NPTlRFWFQgPSAnCiAgICAgICAgaWYgKCRwYXJlbnQgPSAkdGhpcy0+bXVzdGFjaGUtPmxvYWRQYXJ0aWFsKCVzKSkgewogICAgICAgICAgICAkYnVmZmVyIC49ICRwYXJlbnQtPnJlbmRlckludGVybmFsKCRjb250ZXh0LCAkaW5kZW50KTsKICAgICAgICB9CiAgICAnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgaW5oZXJpdGFuY2UgcGFyZW50IGNhbGwgUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCAgICAgICBQYXJlbnQgdGFnIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGluZGVudCAgIFdoaXRlc3BhY2UgaW5kZW50IHRvIGFwcGx5IHRvIHBhcmVudAogICAgICogQHBhcmFtIGFycmF5ICAkY2hpbGRyZW4gQ2hpbGQgbm9kZXMKICAgICAqIEBwYXJhbSBpbnQgICAgJGxldmVsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcmVudCgkaWQsICRpbmRlbnQsIGFycmF5ICRjaGlsZHJlbiwgJGxldmVsKQogICAgewogICAgICAgICRyZWFsQ2hpbGRyZW4gPSBhcnJheV9maWx0ZXIoJGNoaWxkcmVuLCBhcnJheShfX0NMQVNTX18sICdvbmx5QmxvY2tBcmdzJykpOwoKICAgICAgICBpZiAoZW1wdHkoJHJlYWxDaGlsZHJlbikpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6UEFSRU5UX05PX0NPTlRFWFQsICRsZXZlbCksIHZhcl9leHBvcnQoJGlkLCB0cnVlKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZigKICAgICAgICAgICAgJHRoaXMtPnByZXBhcmUoc2VsZjo6UEFSRU5ULCAkbGV2ZWwpLAogICAgICAgICAgICB2YXJfZXhwb3J0KCRpZCwgdHJ1ZSksCiAgICAgICAgICAgICR0aGlzLT53YWxrKCRyZWFsQ2hpbGRyZW4sICRsZXZlbCArIDEpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBtZXRob2QgZm9yIGZpbHRlcmluZyBvdXQgbm9uLWJsb2NrLWFyZyB0b2tlbnMuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRub2RlCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgJG5vZGUgaXMgYSBibG9jayBhcmcgdG9rZW4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gb25seUJsb2NrQXJncyhhcnJheSAkbm9kZSkKICAgIHsKICAgICAgICByZXR1cm4gJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSA9PT0gTXVzdGFjaGVfVG9rZW5pemVyOjpUX0JMT0NLX0FSRzsKICAgIH0KCiAgICBjb25zdCBWQVJJQUJMRSA9ICcKICAgICAgICAkdmFsdWUgPSAkdGhpcy0+cmVzb2x2ZVZhbHVlKCRjb250ZXh0LT4lcyglcyksICRjb250ZXh0KTslcwogICAgICAgICRidWZmZXIgLj0gJXMoJHZhbHVlID09PSBudWxsID8gXCdcJyA6ICVzKTsKICAgICc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSB2YXJpYWJsZSBpbnRlcnBvbGF0aW9uIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRpZCAgICAgIFZhcmlhYmxlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkZmlsdGVycyBBcnJheSBvZiBmaWx0ZXJzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgJGVzY2FwZSAgRXNjYXBlIHRoZSB2YXJpYWJsZSB2YWx1ZSBmb3Igb3V0cHV0PwogICAgICogQHBhcmFtIGludCAgICAgICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCB2YXJpYWJsZSBpbnRlcnBvbGF0aW9uIFBIUCBzb3VyY2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YXJpYWJsZSgkaWQsICRmaWx0ZXJzLCAkZXNjYXBlLCAkbGV2ZWwpCiAgICB7CiAgICAgICAgJG1ldGhvZCAgPSAkdGhpcy0+Z2V0RmluZE1ldGhvZCgkaWQpOwogICAgICAgICRpZCAgICAgID0gKCRtZXRob2QgIT09ICdsYXN0JykgPyB2YXJfZXhwb3J0KCRpZCwgdHJ1ZSkgOiAnJzsKICAgICAgICAkZmlsdGVycyA9ICR0aGlzLT5nZXRGaWx0ZXJzKCRmaWx0ZXJzLCAkbGV2ZWwpOwogICAgICAgICR2YWx1ZSAgID0gJGVzY2FwZSA/ICR0aGlzLT5nZXRFc2NhcGUoKSA6ICckdmFsdWUnOwoKICAgICAgICByZXR1cm4gc3ByaW50ZigkdGhpcy0+cHJlcGFyZShzZWxmOjpWQVJJQUJMRSwgJGxldmVsKSwgJG1ldGhvZCwgJGlkLCAkZmlsdGVycywgJHRoaXMtPmZsdXNoSW5kZW50KCksICR2YWx1ZSk7CiAgICB9CgogICAgY29uc3QgRklMVEVSID0gJwogICAgICAgICRmaWx0ZXIgPSAkY29udGV4dC0+JXMoJXMpOwogICAgICAgIGlmICghKCVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25GaWx0ZXJFeGNlcHRpb24oJXMpOwogICAgICAgIH0KICAgICAgICAkdmFsdWUgPSBjYWxsX3VzZXJfZnVuYygkZmlsdGVyLCAkdmFsdWUpOyVzCiAgICAnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgdmFyaWFibGUgZmlsdGVyaW5nIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRmaWx0ZXJzIEFycmF5IG9mIGZpbHRlcnMKICAgICAqIEBwYXJhbSBpbnQgICAgICAkbGV2ZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgZmlsdGVyIFBIUCBzb3VyY2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRGaWx0ZXJzKGFycmF5ICRmaWx0ZXJzLCAkbGV2ZWwpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRmaWx0ZXJzKSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICAkbmFtZSAgICAgPSBhcnJheV9zaGlmdCgkZmlsdGVycyk7CiAgICAgICAgJG1ldGhvZCAgID0gJHRoaXMtPmdldEZpbmRNZXRob2QoJG5hbWUpOwogICAgICAgICRmaWx0ZXIgICA9ICgkbWV0aG9kICE9PSAnbGFzdCcpID8gdmFyX2V4cG9ydCgkbmFtZSwgdHJ1ZSkgOiAnJzsKICAgICAgICAkY2FsbGFibGUgPSAkdGhpcy0+Z2V0Q2FsbGFibGUoJyRmaWx0ZXInKTsKICAgICAgICAkbXNnICAgICAgPSB2YXJfZXhwb3J0KCRuYW1lLCB0cnVlKTsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6RklMVEVSLCAkbGV2ZWwpLCAkbWV0aG9kLCAkZmlsdGVyLCAkY2FsbGFibGUsICRtc2csICR0aGlzLT5nZXRGaWx0ZXJzKCRmaWx0ZXJzLCAkbGV2ZWwpKTsKICAgIH0KCiAgICBjb25zdCBMSU5FID0gJyRidWZmZXIgLj0gIlxuIjsnOwogICAgY29uc3QgVEVYVCA9ICckYnVmZmVyIC49ICVzJXM7JzsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlIE11c3RhY2hlIFRlbXBsYXRlIG91dHB1dCBCdWZmZXIgY2FsbCBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQKICAgICAqIEBwYXJhbSBpbnQgICAgJGxldmVsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIG91dHB1dCBCdWZmZXIgY2FsbCBQSFAgc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdGV4dCgkdGV4dCwgJGxldmVsKQogICAgewogICAgICAgICRpbmRlbnROZXh0TGluZSA9IChzdWJzdHIoJHRleHQsIC0xKSA9PT0gIlxuIik7CiAgICAgICAgJGNvZGUgPSBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OlRFWFQsICRsZXZlbCksICR0aGlzLT5mbHVzaEluZGVudCgpLCB2YXJfZXhwb3J0KCR0ZXh0LCB0cnVlKSk7CiAgICAgICAgJHRoaXMtPmluZGVudE5leHRMaW5lID0gJGluZGVudE5leHRMaW5lOwoKICAgICAgICByZXR1cm4gJGNvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmVwYXJlIFBIUCBzb3VyY2UgY29kZSBzbmlwcGV0IGZvciBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGV4dAogICAgICogQHBhcmFtIGludCAgICAkYm9udXMgICAgICAgICAgQWRkaXRpb25hbCBpbmRlbnQgbGV2ZWwgKGRlZmF1bHQ6IDApCiAgICAgKiBAcGFyYW0gYm9vbCAgICRwcmVwZW5kTmV3bGluZSBQcmVwZW5kIGEgbmV3bGluZSB0byB0aGUgc25pcHBldD8gKGRlZmF1bHQ6IHRydWUpCiAgICAgKiBAcGFyYW0gYm9vbCAgICRhcHBlbmROZXdsaW5lICBBcHBlbmQgYSBuZXdsaW5lIHRvIHRoZSBzbmlwcGV0PyAoZGVmYXVsdDogZmFsc2UpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUEhQIHNvdXJjZSBjb2RlIHNuaXBwZXQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwcmVwYXJlKCR0ZXh0LCAkYm9udXMgPSAwLCAkcHJlcGVuZE5ld2xpbmUgPSB0cnVlLCAkYXBwZW5kTmV3bGluZSA9IGZhbHNlKQogICAgewogICAgICAgICR0ZXh0ID0gKCRwcmVwZW5kTmV3bGluZSA/ICJcbiIgOiAnJykgLiB0cmltKCR0ZXh0KTsKICAgICAgICBpZiAoJHByZXBlbmROZXdsaW5lKSB7CiAgICAgICAgICAgICRib251cysrOwogICAgICAgIH0KICAgICAgICBpZiAoJGFwcGVuZE5ld2xpbmUpIHsKICAgICAgICAgICAgJHRleHQgLj0gIlxuIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2UoIi9cbiggezh9KT8vIiwgIlxuIiAuIHN0cl9yZXBlYXQoJyAnLCAkYm9udXMgKiA0KSwgJHRleHQpOwogICAgfQoKICAgIGNvbnN0IERFRkFVTFRfRVNDQVBFID0gJ2h0bWxzcGVjaWFsY2hhcnMoJXMsICVzLCAlcyknOwogICAgY29uc3QgQ1VTVE9NX0VTQ0FQRSAgPSAnY2FsbF91c2VyX2Z1bmMoJHRoaXMtPm11c3RhY2hlLT5nZXRFc2NhcGUoKSwgJXMpJzsKCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBlc2NhcGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIChkZWZhdWx0OiAnJHZhbHVlJykKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBFaXRoZXIgYSBjdXN0b20gY2FsbGJhY2ssIG9yIGFuIGlubGluZSBjYWxsIHRvIGBodG1sc3BlY2lhbGNoYXJzYAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEVzY2FwZSgkdmFsdWUgPSAnJHZhbHVlJykKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmN1c3RvbUVzY2FwZSkgewogICAgICAgICAgICByZXR1cm4gc3ByaW50ZihzZWxmOjpDVVNUT01fRVNDQVBFLCAkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNwcmludGYoc2VsZjo6REVGQVVMVF9FU0NBUEUsICR2YWx1ZSwgdmFyX2V4cG9ydCgkdGhpcy0+ZW50aXR5RmxhZ3MsIHRydWUpLCB2YXJfZXhwb3J0KCR0aGlzLT5jaGFyc2V0LCB0cnVlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZWxlY3QgdGhlIGFwcHJvcHJpYXRlIENvbnRleHQgYGZpbmRgIG1ldGhvZCBmb3IgYSBnaXZlbiAkaWQuCiAgICAgKgogICAgICogVGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIG9uZSBvZiBgZmluZGAsIGBmaW5kRG90YCwgYGZpbmRBbmNob3JlZERvdGAgb3IgYGxhc3RgLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfQ29udGV4dDo6ZmluZAogICAgICogQHNlZSBNdXN0YWNoZV9Db250ZXh0OjpmaW5kRG90CiAgICAgKiBAc2VlIE11c3RhY2hlX0NvbnRleHQ6Omxhc3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCBWYXJpYWJsZSBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgYGZpbmRgIG1ldGhvZCBuYW1lCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RmluZE1ldGhvZCgkaWQpCiAgICB7CiAgICAgICAgaWYgKCRpZCA9PT0gJy4nKSB7CiAgICAgICAgICAgIHJldHVybiAnbGFzdCc7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByYWdtYXNbTXVzdGFjaGVfRW5naW5lOjpQUkFHTUFfQU5DSE9SRURfRE9UXSkgJiYgJHRoaXMtPnByYWdtYXNbTXVzdGFjaGVfRW5naW5lOjpQUkFHTUFfQU5DSE9SRURfRE9UXSkgewogICAgICAgICAgICBpZiAoc3Vic3RyKCRpZCwgMCwgMSkgPT09ICcuJykgewogICAgICAgICAgICAgICAgcmV0dXJuICdmaW5kQW5jaG9yZWREb3QnOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCRpZCwgJy4nKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICdmaW5kJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnZmluZERvdCc7CiAgICB9CgogICAgY29uc3QgSVNfQ0FMTEFCTEUgICAgICAgID0gJyFpc19zdHJpbmcoJXMpICYmIGlzX2NhbGxhYmxlKCVzKSc7CiAgICBjb25zdCBTVFJJQ1RfSVNfQ0FMTEFCTEUgPSAnaXNfb2JqZWN0KCVzKSAmJiBpc19jYWxsYWJsZSglcyknOwoKICAgIC8qKgogICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGNvbXBpbGUgc3RyaWN0IHZzIGxheCAiaXMgY2FsbGFibGUiIGxvZ2ljLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhcmlhYmxlIChkZWZhdWx0OiAnJHZhbHVlJykKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyAiaXMgY2FsbGFibGUiIGxvZ2ljCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q2FsbGFibGUoJHZhcmlhYmxlID0gJyR2YWx1ZScpCiAgICB7CiAgICAgICAgJHRwbCA9ICR0aGlzLT5zdHJpY3RDYWxsYWJsZXMgPyBzZWxmOjpTVFJJQ1RfSVNfQ0FMTEFCTEUgOiBzZWxmOjpJU19DQUxMQUJMRTsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRwbCwgJHZhcmlhYmxlLCAkdmFyaWFibGUpOwogICAgfQoKICAgIGNvbnN0IExJTkVfSU5ERU5UID0gJyRpbmRlbnQgLiAnOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50ICRpbmRlbnQgcHJlZml4IHRvIHdyaXRlIHRvIHRoZSBidWZmZXIuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgIiRpbmRlbnQgLiAiIG9yICIiCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmx1c2hJbmRlbnQoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmluZGVudE5leHRMaW5lKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pbmRlbnROZXh0TGluZSA9IGZhbHNlOwoKICAgICAgICByZXR1cm4gc2VsZjo6TElORV9JTkRFTlQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgZmlsZXN5c3RlbSBMb2FkZXIgaW1wbGVtZW50YXRpb24uCiAqCiAqIEEgRmlsZXN5c3RlbUxvYWRlciBpbnN0YW5jZSBsb2FkcyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UgZnJvbSB0aGUgZmlsZXN5c3RlbSBieSBuYW1lOgogKgogKiAgICAgJGxvYWRlciA9IG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihkaXJuYW1lKF9fRklMRV9fKS4nL3ZpZXdzJyk7CiAqICAgICAkdHBsID0gJGxvYWRlci0+bG9hZCgnZm9vJyk7IC8vIGVxdWl2YWxlbnQgdG8gYGZpbGVfZ2V0X2NvbnRlbnRzKGRpcm5hbWUoX19GSUxFX18pLicvdmlld3MvZm9vLm11c3RhY2hlJyk7CiAqCiAqIFRoaXMgaXMgcHJvYmFibHkgdGhlIG1vc3QgdXNlZnVsIE11c3RhY2hlIExvYWRlciBpbXBsZW1lbnRhdGlvbi4gSXQgY2FuIGJlIHVzZWQgZm9yIHBhcnRpYWxzIGFuZCBub3JtYWwgVGVtcGxhdGVzOgogKgogKiAgICAgJG0gPSBuZXcgTXVzdGFjaGUoYXJyYXkoCiAqICAgICAgICAgICdsb2FkZXInICAgICAgICAgID0+IG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihkaXJuYW1lKF9fRklMRV9fKS4nL3ZpZXdzJyksCiAqICAgICAgICAgICdwYXJ0aWFsc19sb2FkZXInID0+IG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihkaXJuYW1lKF9fRklMRV9fKS4nL3ZpZXdzL3BhcnRpYWxzJyksCiAqICAgICApKTsKICovCmNsYXNzIE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyIGltcGxlbWVudHMgTXVzdGFjaGVfTG9hZGVyCnsKICAgIHByaXZhdGUgJGJhc2VEaXI7CiAgICBwcml2YXRlICRleHRlbnNpb24gPSAnLm11c3RhY2hlJzsKICAgIHByaXZhdGUgJHRlbXBsYXRlcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBNdXN0YWNoZSBmaWxlc3lzdGVtIExvYWRlciBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBQYXNzaW5nIGFuICRvcHRpb25zIGFycmF5IGFsbG93cyBvdmVycmlkaW5nIGNlcnRhaW4gTG9hZGVyIG9wdGlvbnMgZHVyaW5nIGluc3RhbnRpYXRpb246CiAgICAgKgogICAgICogICAgICRvcHRpb25zID0gYXJyYXkoCiAgICAgKiAgICAgICAgIC8vIFRoZSBmaWxlbmFtZSBleHRlbnNpb24gdXNlZCBmb3IgTXVzdGFjaGUgdGVtcGxhdGVzLiBEZWZhdWx0cyB0byAnLm11c3RhY2hlJwogICAgICogICAgICAgICAnZXh0ZW5zaW9uJyA9PiAnLm1zJywKICAgICAqICAgICApOwogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24gaWYgJGJhc2VEaXIgZG9lcyBub3QgZXhpc3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlRGlyIEJhc2UgZGlyZWN0b3J5IGNvbnRhaW5pbmcgTXVzdGFjaGUgdGVtcGxhdGUgZmlsZXMKICAgICAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgQXJyYXkgb2YgTG9hZGVyIG9wdGlvbnMgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5iYXNlRGlyID0gJGJhc2VEaXI7CgogICAgICAgIGlmIChzdHJwb3MoJHRoaXMtPmJhc2VEaXIsICc6Ly8nKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJHRoaXMtPmJhc2VEaXIgPSByZWFscGF0aCgkdGhpcy0+YmFzZURpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENoZWNrUGF0aCgpICYmICFpc19kaXIoJHRoaXMtPmJhc2VEaXIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGaWxlc3lzdGVtTG9hZGVyIGJhc2VEaXIgbXVzdCBiZSBhIGRpcmVjdG9yeTogJXMnLCAkYmFzZURpcikpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ2V4dGVuc2lvbicsICRvcHRpb25zKSkgewogICAgICAgICAgICBpZiAoZW1wdHkoJG9wdGlvbnNbJ2V4dGVuc2lvbiddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmV4dGVuc2lvbiA9ICcnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmV4dGVuc2lvbiA9ICcuJyAuIGx0cmltKCRvcHRpb25zWydleHRlbnNpb24nXSwgJy4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZSBieSBuYW1lLgogICAgICoKICAgICAqICAgICAkbG9hZGVyID0gbmV3IE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyKGRpcm5hbWUoX19GSUxFX18pLicvdmlld3MnKTsKICAgICAqICAgICAkbG9hZGVyLT5sb2FkKCdhZG1pbi9kYXNoYm9hcmQnKTsgLy8gbG9hZHMgIi4vdmlld3MvYWRtaW4vZGFzaGJvYXJkLm11c3RhY2hlIjsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRuYW1lKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnRlbXBsYXRlc1skbmFtZV0pKSB7CiAgICAgICAgICAgICR0aGlzLT50ZW1wbGF0ZXNbJG5hbWVdID0gJHRoaXMtPmxvYWRGaWxlKCRuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVtcGxhdGVzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBmdW5jdGlvbiBmb3IgbG9hZGluZyBhIE11c3RhY2hlIGZpbGUgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gSWYgYSB0ZW1wbGF0ZSBmaWxlIGlzIG5vdCBmb3VuZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRGaWxlKCRuYW1lKQogICAgewogICAgICAgICRmaWxlTmFtZSA9ICR0aGlzLT5nZXRGaWxlTmFtZSgkbmFtZSk7CgogICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2hlY2tQYXRoKCkgJiYgIWZpbGVfZXhpc3RzKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24oJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlTmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGdldHRpbmcgYSBNdXN0YWNoZSB0ZW1wbGF0ZSBmaWxlIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRlbXBsYXRlIGZpbGUgbmFtZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0RmlsZU5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmJhc2VEaXIgLiAnLycgLiAkbmFtZTsKICAgICAgICBpZiAoc3Vic3RyKCRmaWxlTmFtZSwgMCAtIHN0cmxlbigkdGhpcy0+ZXh0ZW5zaW9uKSkgIT09ICR0aGlzLT5leHRlbnNpb24pIHsKICAgICAgICAgICAgJGZpbGVOYW1lIC49ICR0aGlzLT5leHRlbnNpb247CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGVOYW1lOwogICAgfQoKICAgIC8qKgogICAgICogT25seSBjaGVjayBpZiBiYXNlRGlyIGlzIGEgZGlyZWN0b3J5IGFuZCByZXF1ZXN0ZWQgdGVtcGxhdGVzIGFyZSBmaWxlcyBpZgogICAgICogYmFzZURpciBpcyB1c2luZyB0aGUgZmlsZXN5c3RlbSBzdHJlYW0gd3JhcHBlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0byBjaGVjayBgaXNfZGlyYCBhbmQgYGZpbGVfZXhpc3RzYAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2hvdWxkQ2hlY2tQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gc3RycG9zKCR0aGlzLT5iYXNlRGlyLCAnOi8vJykgPT09IGZhbHNlIHx8IHN0cnBvcygkdGhpcy0+YmFzZURpciwgJ2ZpbGU6Ly8nKSA9PT0gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBBIE11c3RhY2hlIFRlbXBsYXRlIGNhc2NhZGluZyBsb2FkZXIgaW1wbGVtZW50YXRpb24sIHdoaWNoIGRlbGVnYXRlcyB0byBvdGhlcgogKiBMb2FkZXIgaW5zdGFuY2VzLgogKi8KY2xhc3MgTXVzdGFjaGVfTG9hZGVyX0Nhc2NhZGluZ0xvYWRlciBpbXBsZW1lbnRzIE11c3RhY2hlX0xvYWRlcgp7CiAgICBwcml2YXRlICRsb2FkZXJzOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgQ2FzY2FkaW5nTG9hZGVyIHdpdGggYW4gYXJyYXkgb2YgbG9hZGVycy4KICAgICAqCiAgICAgKiAgICAgJGxvYWRlciA9IG5ldyBNdXN0YWNoZV9Mb2FkZXJfQ2FzY2FkaW5nTG9hZGVyKGFycmF5KAogICAgICogICAgICAgICBuZXcgTXVzdGFjaGVfTG9hZGVyX0lubGluZUxvYWRlcihfX0ZJTEVfXywgX19DT01QSUxFUl9IQUxUX09GRlNFVF9fKSwKICAgICAqICAgICAgICAgbmV3IE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyKF9fRElSX18uJy90ZW1wbGF0ZXMnKQogICAgICogICAgICkpOwogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Mb2FkZXJbXSAkbG9hZGVycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGxvYWRlcnMgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2FkZXJzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbG9hZGVycyBhcyAkbG9hZGVyKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRMb2FkZXIoJGxvYWRlcik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgTG9hZGVyIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Mb2FkZXIgJGxvYWRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTG9hZGVyKE11c3RhY2hlX0xvYWRlciAkbG9hZGVyKQogICAgewogICAgICAgICR0aGlzLT5sb2FkZXJzW10gPSAkbG9hZGVyOwogICAgfQoKICAgIC8qKgogICAgICogTG9hZCBhIFRlbXBsYXRlIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uIElmIGEgdGVtcGxhdGUgZmlsZSBpcyBub3QgZm91bmQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRuYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5sb2FkZXJzIGFzICRsb2FkZXIpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAkbG9hZGVyLT5sb2FkKCRuYW1lKTsKICAgICAgICAgICAgfSBjYXRjaCAoTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZywgY2hlY2sgdGhlIG5leHQgbG9hZGVyLgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbigkbmFtZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQSBNdXN0YWNoZSBUZW1wbGF0ZSBsb2FkZXIgZm9yIGlubGluZSB0ZW1wbGF0ZXMuCiAqCiAqIFdpdGggdGhlIElubGluZUxvYWRlciwgdGVtcGxhdGVzIGNhbiBiZSBkZWZpbmVkIGF0IHRoZSBlbmQgb2YgYW55IFBIUCBzb3VyY2UKICogZmlsZToKICoKICogICAgICRsb2FkZXIgID0gbmV3IE11c3RhY2hlX0xvYWRlcl9JbmxpbmVMb2FkZXIoX19GSUxFX18sIF9fQ09NUElMRVJfSEFMVF9PRkZTRVRfXyk7CiAqICAgICAkaGVsbG8gICA9ICRsb2FkZXItPmxvYWQoJ2hlbGxvJyk7CiAqICAgICAkZ29vZGJ5ZSA9ICRsb2FkZXItPmxvYWQoJ2dvb2RieWUnKTsKICoKICogICAgIF9faGFsdF9jb21waWxlcigpOwogKgogKiAgICAgQEAgaGVsbG8KICogICAgIEhlbGxvLCB7eyBwbGFuZXQgfX0hCiAqCiAqICAgICBAQCBnb29kYnllCiAqICAgICBHb29kYnllLCBjcnVlbCB7eyBwbGFuZXQgfX0KICoKICogVGVtcGxhdGVzIGFyZSBkZWxpbmlhdGVkIGJ5IGxpbmVzIGNvbnRhaW5pbmcgb25seSBgQEAgbmFtZWAuCiAqCiAqIFRoZSBJbmxpbmVMb2FkZXIgaXMgd2VsbC1zdWl0ZWQgdG8gbWljcm8tZnJhbWV3b3JrcyBzdWNoIGFzIFNpbGV4OgogKgogKiAgICAgJGFwcC0+cmVnaXN0ZXIobmV3IE11c3RhY2hlU2VydmljZVByb3ZpZGVyLCBhcnJheSgKICogICAgICAgICAnbXVzdGFjaGUubG9hZGVyJyA9PiBuZXcgTXVzdGFjaGVfTG9hZGVyX0lubGluZUxvYWRlcihfX0ZJTEVfXywgX19DT01QSUxFUl9IQUxUX09GRlNFVF9fKQogKiAgICAgKSk7CiAqCiAqICAgICAkYXBwLT5nZXQoJy97bmFtZX0nLCBmdW5jdGlvbiAoJG5hbWUpIHVzZSAoJGFwcCkgewogKiAgICAgICAgIHJldHVybiAkYXBwWydtdXN0YWNoZSddLT5yZW5kZXIoJ2hlbGxvJywgY29tcGFjdCgnbmFtZScpKTsKICogICAgIH0pCiAqICAgICAtPnZhbHVlKCduYW1lJywgJ3dvcmxkJyk7CiAqCiAqICAgICAvLyAuLi4KICoKICogICAgIF9faGFsdF9jb21waWxlcigpOwogKgogKiAgICAgQEAgaGVsbG8KICogICAgIEhlbGxvLCB7eyBuYW1lIH19IQogKi8KY2xhc3MgTXVzdGFjaGVfTG9hZGVyX0lubGluZUxvYWRlciBpbXBsZW1lbnRzIE11c3RhY2hlX0xvYWRlcgp7CiAgICBwcm90ZWN0ZWQgJGZpbGVOYW1lOwogICAgcHJvdGVjdGVkICRvZmZzZXQ7CiAgICBwcm90ZWN0ZWQgJHRlbXBsYXRlczsKCiAgICAvKioKICAgICAqIFRoZSBJbmxpbmVMb2FkZXIgcmVxdWlyZXMgYSBmaWxlbmFtZSBhbmQgb2Zmc2V0IHRvIHByb2Nlc3MgdGVtcGxhdGVzLgogICAgICoKICAgICAqIFRoZSBtYWdpYyBjb25zdGFudHMgYF9fRklMRV9fYCBhbmQgYF9fQ09NUElMRVJfSEFMVF9PRkZTRVRfX2AgYXJlIHVzdWFsbHkKICAgICAqIHBlcmZlY3RseSBzdWl0ZWQgdG8gdGhlIGpvYjoKICAgICAqCiAgICAgKiAgICAgJGxvYWRlciA9IG5ldyBNdXN0YWNoZV9Mb2FkZXJfSW5saW5lTG9hZGVyKF9fRklMRV9fLCBfX0NPTVBJTEVSX0hBTFRfT0ZGU0VUX18pOwogICAgICoKICAgICAqIE5vdGUgdGhhdCB0aGlzIG9ubHkgd29ya3MgaWYgdGhlIGxvYWRlciBpcyBpbnN0YW50aWF0ZWQgaW5zaWRlIHRoZSBzYW1lCiAgICAgKiBmaWxlIGFzIHRoZSBpbmxpbmUgdGVtcGxhdGVzLiBJZiB0aGUgdGVtcGxhdGVzIGFyZSBsb2NhdGVkIGluIGFub3RoZXIKICAgICAqIGZpbGUsIGl0IHdvdWxkIGJlIG5lY2Vzc2FyeSB0byBtYW51YWxseSBzcGVjaWZ5IHRoZSBmaWxlbmFtZSBhbmQgb2Zmc2V0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVOYW1lIFRoZSBmaWxlIHRvIHBhcnNlIGZvciBpbmxpbmUgdGVtcGxhdGVzCiAgICAgKiBAcGFyYW0gaW50ICAgICRvZmZzZXQgICBBIHN0cmluZyBvZmZzZXQgZm9yIHRoZSBzdGFydCBvZiB0aGUgdGVtcGxhdGVzLgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyB1c3VhbGx5IGNvaW5jaWRlcyB3aXRoIHRoZSBgX19oYWx0X2NvbXBpbGVyYAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY2FsbCwgYW5kIHRoZSBgX19DT01QSUxFUl9IQUxUX09GRlNFVF9fYAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGZpbGVOYW1lLCAkb2Zmc2V0KQogICAgewogICAgICAgIGlmICghaXNfZmlsZSgkZmlsZU5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbmxpbmVMb2FkZXIgZXhwZWN0cyBhIHZhbGlkIGZpbGVuYW1lLicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc19pbnQoJG9mZnNldCkgfHwgJG9mZnNldCA8IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0lubGluZUxvYWRlciBleHBlY3RzIGEgdmFsaWQgZmlsZSBvZmZzZXQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZmlsZU5hbWUgPSAkZmlsZU5hbWU7CiAgICAgICAgJHRoaXMtPm9mZnNldCAgID0gJG9mZnNldDsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZSBieSBuYW1lLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbiBJZiBhIHRlbXBsYXRlIGZpbGUgaXMgbm90IGZvdW5kCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIE11c3RhY2hlIFRlbXBsYXRlIHNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZCgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9hZFRlbXBsYXRlcygpOwoKICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoJG5hbWUsICR0aGlzLT50ZW1wbGF0ZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uKCRuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVtcGxhdGVzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlIGFuZCBsb2FkIHRlbXBsYXRlcyBmcm9tIHRoZSBlbmQgb2YgYSBzb3VyY2UgZmlsZS4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRUZW1wbGF0ZXMoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+dGVtcGxhdGVzID09PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT50ZW1wbGF0ZXMgPSBhcnJheSgpOwogICAgICAgICAgICAkZGF0YSA9IGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlTmFtZSwgZmFsc2UsIG51bGwsICR0aGlzLT5vZmZzZXQpOwogICAgICAgICAgICBmb3JlYWNoIChwcmVnX3NwbGl0KCIvXkBAKD89IFtcd1xkXC5dKyQpL20iLCAkZGF0YSwgLTEpIGFzICRjaHVuaykgewogICAgICAgICAgICAgICAgaWYgKHRyaW0oJGNodW5rKSkgewogICAgICAgICAgICAgICAgICAgIGxpc3QoJG5hbWUsICRjb250ZW50KSAgICAgICAgID0gZXhwbG9kZSgiXG4iLCAkY2h1bmssIDIpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT50ZW1wbGF0ZXNbdHJpbSgkbmFtZSldID0gdHJpbSgkY29udGVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgbXV0YWJsZSBMb2FkZXIgaW50ZXJmYWNlLgogKi8KaW50ZXJmYWNlIE11c3RhY2hlX0xvYWRlcl9NdXRhYmxlTG9hZGVyCnsKICAgIC8qKgogICAgICogU2V0IGFuIGFzc29jaWF0aXZlIGFycmF5IG9mIFRlbXBsYXRlIHNvdXJjZXMgZm9yIHRoaXMgbG9hZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdGVtcGxhdGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZW1wbGF0ZXMoYXJyYXkgJHRlbXBsYXRlcyk7CgogICAgLyoqCiAgICAgKiBTZXQgYSBUZW1wbGF0ZSBzb3VyY2UgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZW1wbGF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlbXBsYXRlKCRuYW1lLCAkdGVtcGxhdGUpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIFRlbXBsYXRlIHByb2R1Y3Rpb24gZmlsZXN5c3RlbSBMb2FkZXIgaW1wbGVtZW50YXRpb24uCiAqCiAqIEEgcHJvZHVjdGlvbi1yZWFkeSBGaWxlc3lzdGVtTG9hZGVyLCB3aGljaCBkb2Vzbid0IHJlcXVpcmUgcmVhZGluZyBhIGZpbGUgaWYgaXQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHRlbXBsYXRlIGNhY2hlLgogKgogKiB7QGluaGVyaXRkb2N9CiAqLwpjbGFzcyBNdXN0YWNoZV9Mb2FkZXJfUHJvZHVjdGlvbkZpbGVzeXN0ZW1Mb2FkZXIgZXh0ZW5kcyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcgp7CiAgICBwcml2YXRlICRzdGF0UHJvcHM7CgogICAgLyoqCiAgICAgKiBNdXN0YWNoZSBwcm9kdWN0aW9uIGZpbGVzeXN0ZW0gTG9hZGVyIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIFBhc3NpbmcgYW4gJG9wdGlvbnMgYXJyYXkgYWxsb3dzIG92ZXJyaWRpbmcgY2VydGFpbiBMb2FkZXIgb3B0aW9ucyBkdXJpbmcgaW5zdGFudGlhdGlvbjoKICAgICAqCiAgICAgKiAgICAgJG9wdGlvbnMgPSBhcnJheSgKICAgICAqICAgICAgICAgLy8gVGhlIGZpbGVuYW1lIGV4dGVuc2lvbiB1c2VkIGZvciBNdXN0YWNoZSB0ZW1wbGF0ZXMuIERlZmF1bHRzIHRvICcubXVzdGFjaGUnCiAgICAgKiAgICAgICAgICdleHRlbnNpb24nID0+ICcubXMnLAogICAgICogICAgICAgICAnc3RhdF9wcm9wcycgPT4gYXJyYXkoJ3NpemUnLCAnbXRpbWUnKSwKICAgICAqICAgICApOwogICAgICoKICAgICAqIFNwZWNpZnlpbmcgJ3N0YXRfcHJvcHMnIG92ZXJyaWRlcyB0aGUgc3RhdCBwcm9wZXJ0aWVzIHVzZWQgdG8gaW52YWxpZGF0ZSB0aGUgdGVtcGxhdGUgY2FjaGUuIEJ5IGRlZmF1bHQsIHRoaXMKICAgICAqIHVzZXMgJ210aW1lJyBhbmQgJ3NpemUnLCBidXQgdGhpcyBjYW4gYmUgc2V0IHRvIGFueSBvZiB0aGUgcHJvcGVydGllcyBzdXBwb3J0ZWQgYnkgc3RhdCgpOgogICAgICoKICAgICAqICAgICBodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RhdC5waHAKICAgICAqCiAgICAgKiBZb3UgY2FuIGFsc28gZGlzYWJsZSBmaWxlc3lzdGVtIHN0YXQgZW50aXJlbHk6CiAgICAgKgogICAgICogICAgICRvcHRpb25zID0gYXJyYXkoJ3N0YXRfcHJvcHMnID0+IG51bGwpOwogICAgICoKICAgICAqIEJ1dCB3aXRoIGdyZWF0IHBvd2VyIGNvbWVzIGdyZWF0IHJlc3BvbnNpYmlsaXR5LiBOYW1lbHksIGlmIHlvdSBkaXNhYmxlIHN0YXQtYmFzZWQgY2FjaGUgaW52YWxpZGF0aW9uLAogICAgICogWU9VIE1VU1QgQ0xFQVIgVEhFIFRFTVBMQVRFIENBQ0hFIFlPVVJTRUxGIHdoZW4geW91ciB0ZW1wbGF0ZXMgY2hhbmdlLiBNYWtlIGl0IHBhcnQgb2YgeW91ciBidWlsZCBvciBkZXBsb3kKICAgICAqIHByb2Nlc3Mgc28geW91IGRvbid0IGZvcmdldCEKICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uIGlmICRiYXNlRGlyIGRvZXMgbm90IGV4aXN0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VEaXIgQmFzZSBkaXJlY3RvcnkgY29udGFpbmluZyBNdXN0YWNoZSB0ZW1wbGF0ZSBmaWxlcy4KICAgICAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgQXJyYXkgb2YgTG9hZGVyIG9wdGlvbnMgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGJhc2VEaXIsICRvcHRpb25zKTsKCiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3N0YXRfcHJvcHMnLCAkb3B0aW9ucykpIHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRvcHRpb25zWydzdGF0X3Byb3BzJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3RhdFByb3BzID0gYXJyYXkoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdGF0UHJvcHMgPSAkb3B0aW9uc1snc3RhdF9wcm9wcyddOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnN0YXRQcm9wcyA9IGFycmF5KCdzaXplJywgJ210aW1lJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciBsb2FkaW5nIGEgTXVzdGFjaGUgZmlsZSBieSBuYW1lLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbiBJZiBhIHRlbXBsYXRlIGZpbGUgaXMgbm90IGZvdW5kLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX1NvdXJjZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRGaWxlKCRuYW1lKQogICAgewogICAgICAgICRmaWxlTmFtZSA9ICR0aGlzLT5nZXRGaWxlTmFtZSgkbmFtZSk7CgogICAgICAgIGlmICghZmlsZV9leGlzdHMoJGZpbGVOYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbigkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IE11c3RhY2hlX1NvdXJjZV9GaWxlc3lzdGVtU291cmNlKCRmaWxlTmFtZSwgJHRoaXMtPnN0YXRQcm9wcyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgYXJyYXkgTG9hZGVyIGltcGxlbWVudGF0aW9uLgogKgogKiBBbiBBcnJheUxvYWRlciBpbnN0YW5jZSBsb2FkcyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UgYnkgbmFtZSBmcm9tIGFuIGluaXRpYWwgYXJyYXk6CiAqCiAqICAgICAkbG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKAogKiAgICAgICAgICdmb28nID0+ICd7eyBiYXIgfX0nLAogKiAgICAgICAgICdiYXonID0+ICdIZXkge3sgcXV4IH19IScKICogICAgICk7CiAqCiAqICAgICAkdHBsID0gJGxvYWRlci0+bG9hZCgnZm9vJyk7IC8vICd7eyBiYXIgfX0nCiAqCiAqIFRoZSBBcnJheUxvYWRlciBpcyB1c2VkIGludGVybmFsbHkgYXMgYSBwYXJ0aWFscyBsb2FkZXIgYnkgTXVzdGFjaGVfRW5naW5lIGluc3RhbmNlIHdoZW4gYW4gYXJyYXkgb2YgcGFydGlhbHMKICogaXMgc2V0LiBJdCBjYW4gYWxzbyBiZSB1c2VkIGFzIGEgcXVpY2stYW5kLWRpcnR5IFRlbXBsYXRlIGxvYWRlci4KICovCmNsYXNzIE11c3RhY2hlX0xvYWRlcl9BcnJheUxvYWRlciBpbXBsZW1lbnRzIE11c3RhY2hlX0xvYWRlciwgTXVzdGFjaGVfTG9hZGVyX011dGFibGVMb2FkZXIKewogICAgcHJpdmF0ZSAkdGVtcGxhdGVzOwoKICAgIC8qKgogICAgICogQXJyYXlMb2FkZXIgY29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICR0ZW1wbGF0ZXMgQXNzb2NpYXRpdmUgYXJyYXkgb2YgVGVtcGxhdGUgc291cmNlIChkZWZhdWx0OiBhcnJheSgpKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHRlbXBsYXRlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPnRlbXBsYXRlcyA9ICR0ZW1wbGF0ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2FkIGEgVGVtcGxhdGUuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uIElmIGEgdGVtcGxhdGUgZmlsZSBpcyBub3QgZm91bmQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRuYW1lKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnRlbXBsYXRlc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uKCRuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVtcGxhdGVzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhbiBhc3NvY2lhdGl2ZSBhcnJheSBvZiBUZW1wbGF0ZSBzb3VyY2VzIGZvciB0aGlzIGxvYWRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRlbXBsYXRlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVtcGxhdGVzKGFycmF5ICR0ZW1wbGF0ZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnRlbXBsYXRlcyA9ICR0ZW1wbGF0ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgYSBUZW1wbGF0ZSBzb3VyY2UgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZW1wbGF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlbXBsYXRlKCRuYW1lLCAkdGVtcGxhdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnRlbXBsYXRlc1skbmFtZV0gPSAkdGVtcGxhdGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgc3RyaW5nIExvYWRlciBpbXBsZW1lbnRhdGlvbi4KICoKICogQSBTdHJpbmdMb2FkZXIgaW5zdGFuY2UgaXMgZXNzZW50aWFsbHkgYSBub29wLiBJdCBzaW1wbHkgcGFzc2VzIHRoZSAnbmFtZScgYXJndW1lbnQgc3RyYWlnaHQgdGhyb3VnaDoKICoKICogICAgICRsb2FkZXIgPSBuZXcgU3RyaW5nTG9hZGVyOwogKiAgICAgJHRwbCA9ICRsb2FkZXItPmxvYWQoJ3t7IGZvbyB9fScpOyAvLyAne3sgZm9vIH19JwogKgogKiBUaGlzIGlzIHRoZSBkZWZhdWx0IFRlbXBsYXRlIExvYWRlciBpbnN0YW5jZSB1c2VkIGJ5IE11c3RhY2hlOgogKgogKiAgICAgJG0gPSBuZXcgTXVzdGFjaGU7CiAqICAgICAkdHBsID0gJG0tPmxvYWRUZW1wbGF0ZSgne3sgZm9vIH19Jyk7CiAqICAgICBlY2hvICR0cGwtPnJlbmRlcihhcnJheSgnZm9vJyA9PiAnYmFyJykpOyAvLyAiYmFyIgogKi8KY2xhc3MgTXVzdGFjaGVfTG9hZGVyX1N0cmluZ0xvYWRlciBpbXBsZW1lbnRzIE11c3RhY2hlX0xvYWRlcgp7CiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZSBieSBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuICRuYW1lOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIFBhcnNlciBjbGFzcy4KICoKICogVGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgdHVybmluZyBhIHNldCBvZiBNdXN0YWNoZSB0b2tlbnMgaW50byBhIHBhcnNlIHRyZWUuCiAqLwpjbGFzcyBNdXN0YWNoZV9QYXJzZXIKewogICAgcHJpdmF0ZSAkbGluZU51bTsKICAgIHByaXZhdGUgJGxpbmVUb2tlbnM7CiAgICBwcml2YXRlICRwcmFnbWFzOwogICAgcHJpdmF0ZSAkZGVmYXVsdFByYWdtYXMgPSBhcnJheSgpOwoKICAgIHByaXZhdGUgJHByYWdtYUZpbHRlcnM7CiAgICBwcml2YXRlICRwcmFnbWFCbG9ja3M7CgogICAgLyoqCiAgICAgKiBQcm9jZXNzIGFuIGFycmF5IG9mIE11c3RhY2hlIHRva2VucyBhbmQgY29udmVydCB0aGVtIGludG8gYSBwYXJzZSB0cmVlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdG9rZW5zIFNldCBvZiBNdXN0YWNoZSB0b2tlbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IE11c3RhY2hlIHRva2VuIHBhcnNlIHRyZWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlKGFycmF5ICR0b2tlbnMgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5saW5lTnVtICAgID0gLTE7CiAgICAgICAgJHRoaXMtPmxpbmVUb2tlbnMgPSAwOwogICAgICAgICR0aGlzLT5wcmFnbWFzICAgID0gJHRoaXMtPmRlZmF1bHRQcmFnbWFzOwoKICAgICAgICAkdGhpcy0+cHJhZ21hRmlsdGVycyA9IGlzc2V0KCR0aGlzLT5wcmFnbWFzW011c3RhY2hlX0VuZ2luZTo6UFJBR01BX0ZJTFRFUlNdKTsKICAgICAgICAkdGhpcy0+cHJhZ21hQmxvY2tzICA9IGlzc2V0KCR0aGlzLT5wcmFnbWFzW011c3RhY2hlX0VuZ2luZTo6UFJBR01BX0JMT0NLU10pOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmJ1aWxkVHJlZSgkdG9rZW5zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZSBwcmFnbWFzIGFjcm9zcyBhbGwgdGVtcGxhdGVzLCByZWdhcmRsZXNzIG9mIHRoZSBwcmVzZW5jZSBvZiBwcmFnbWEKICAgICAqIHRhZ3MgaW4gdGhlIGluZGl2aWR1YWwgdGVtcGxhdGVzLgogICAgICoKICAgICAqIEBpbnRlcm5hbCBVc2VycyBzaG91bGQgc2V0IGdsb2JhbCBwcmFnbWFzIGluIE11c3RhY2hlX0VuZ2luZSwgbm90IGhlcmUgOikKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHByYWdtYXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByYWdtYXMoYXJyYXkgJHByYWdtYXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnByYWdtYXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwcmFnbWFzIGFzICRwcmFnbWEpIHsKICAgICAgICAgICAgJHRoaXMtPmVuYWJsZVByYWdtYSgkcHJhZ21hKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmRlZmF1bHRQcmFnbWFzID0gJHRoaXMtPnByYWdtYXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgbWV0aG9kIGZvciByZWN1cnNpdmVseSBidWlsZGluZyBhIHBhcnNlIHRyZWUuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uIHdoZW4gbmVzdGluZyBlcnJvcnMgb3IgbWlzbWF0Y2hlZCBzZWN0aW9uIHRhZ3MgYXJlIGVuY291bnRlcmVkCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICYkdG9rZW5zIFNldCBvZiBNdXN0YWNoZSB0b2tlbnMKICAgICAqIEBwYXJhbSBhcnJheSAkcGFyZW50ICBQYXJlbnQgdG9rZW4gKGRlZmF1bHQ6IG51bGwpCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBNdXN0YWNoZSBUb2tlbiBwYXJzZSB0cmVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYnVpbGRUcmVlKGFycmF5ICYkdG9rZW5zLCBhcnJheSAkcGFyZW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkbm9kZXMgPSBhcnJheSgpOwoKICAgICAgICB3aGlsZSAoIWVtcHR5KCR0b2tlbnMpKSB7CiAgICAgICAgICAgICR0b2tlbiA9IGFycmF5X3NoaWZ0KCR0b2tlbnMpOwoKICAgICAgICAgICAgaWYgKCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6OkxJTkVdID09PSAkdGhpcy0+bGluZU51bSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmxpbmVUb2tlbnMrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5saW5lTnVtICAgID0gJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TElORV07CiAgICAgICAgICAgICAgICAkdGhpcy0+bGluZVRva2VucyA9IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+cHJhZ21hRmlsdGVycyAmJiBpc3NldCgkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSkpIHsKICAgICAgICAgICAgICAgIGxpc3QoJG5hbWUsICRmaWx0ZXJzKSA9ICR0aGlzLT5nZXROYW1lQW5kRmlsdGVycygkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSk7CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRmaWx0ZXJzKSkgewogICAgICAgICAgICAgICAgICAgICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdICAgID0gJG5hbWU7CiAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6RklMVEVSU10gPSAkZmlsdGVyczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICgkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSkgewogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfREVMSU1fQ0hBTkdFOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja0lmVG9rZW5Jc0FsbG93ZWRJblBhcmVudCgkcGFyZW50LCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jbGVhclN0YW5kYWxvbmVMaW5lcygkbm9kZXMsICR0b2tlbnMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1NFQ1RJT046CiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9JTlZFUlRFRDoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tJZlRva2VuSXNBbGxvd2VkSW5QYXJlbnQoJHBhcmVudCwgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xlYXJTdGFuZGFsb25lTGluZXMoJG5vZGVzLCAkdG9rZW5zKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZXNbXSA9ICR0aGlzLT5idWlsZFRyZWUoJHRva2VucywgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9FTkRfU0VDVElPTjoKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRwYXJlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtc2cgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1VuZXhwZWN0ZWQgY2xvc2luZyB0YWc6IC8lcyBvbiBsaW5lICVkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TElORV0KICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24oJG1zZywgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSAhPT0gJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtc2cgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ05lc3RpbmcgZXJyb3I6ICVzIChvbiBsaW5lICVkKSB2cy4gJXMgKG9uIGxpbmUgJWQpJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpMSU5FXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TElORV0KICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24oJG1zZywgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jbGVhclN0YW5kYWxvbmVMaW5lcygkbm9kZXMsICR0b2tlbnMpOwogICAgICAgICAgICAgICAgICAgICRwYXJlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpFTkRdICAgPSAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFWF07CiAgICAgICAgICAgICAgICAgICAgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5PREVTXSA9ICRub2RlczsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYXJlbnQ7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfUEFSVElBTDoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tJZlRva2VuSXNBbGxvd2VkSW5QYXJlbnQoJHBhcmVudCwgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICAvL3N0b3JlIHRoZSB3aGl0ZXNwYWNlIHByZWZpeCBmb3IgbGF0ZXJzIQogICAgICAgICAgICAgICAgICAgIGlmICgkaW5kZW50ID0gJHRoaXMtPmNsZWFyU3RhbmRhbG9uZUxpbmVzKCRub2RlcywgJHRva2VucykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6SU5ERU5UXSA9ICRpbmRlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpWQUxVRV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJHRva2VuOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1BBUkVOVDoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tJZlRva2VuSXNBbGxvd2VkSW5QYXJlbnQoJHBhcmVudCwgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZXNbXSA9ICR0aGlzLT5idWlsZFRyZWUoJHRva2VucywgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9CTE9DS19WQVI6CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5wcmFnbWFCbG9ja3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQkxPQ0tTIHByYWdtYSBpcyBlbmFibGVkLCBsZXQncyBkbyB0aGlzIQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhcmVudCkgJiYgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6OlRZUEVdID09PSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfUEFSRU5UKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSA9IE11c3RhY2hlX1Rva2VuaXplcjo6VF9CTE9DS19BUkc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNsZWFyU3RhbmRhbG9uZUxpbmVzKCRub2RlcywgJHRva2Vucyk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJHRoaXMtPmJ1aWxkVHJlZSgkdG9rZW5zLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByZXRlbmQgdGhpcyB3YXMganVzdCBhIG5vcm1hbCAiZXNjYXBlZCIgdG9rZW4uLi4KICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6VFlQRV0gPSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfRVNDQVBFRDsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogZmlndXJlIG91dCBob3cgdG8gZmlndXJlIG91dCBpZiB0aGVyZSB3YXMgYSBzcGFjZSBhZnRlciB0aGlzIGRvbGxhcjoKICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0gPSAnJCcgLiAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVzW10gPSAkdG9rZW47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1BSQUdNQToKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZW5hYmxlUHJhZ21hKCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdKTsKICAgICAgICAgICAgICAgICAgICAvLyBubyBicmVhawoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0NPTU1FTlQ6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNsZWFyU3RhbmRhbG9uZUxpbmVzKCRub2RlcywgJHRva2Vucyk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGVzW10gPSAkdG9rZW47CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAkbm9kZXNbXSA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRwYXJlbnQpKSB7CiAgICAgICAgICAgICRtc2cgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgJ01pc3NpbmcgY2xvc2luZyB0YWc6ICVzIG9wZW5lZCBvbiBsaW5lICVkJywKICAgICAgICAgICAgICAgICRwYXJlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICRwYXJlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpMSU5FXQogICAgICAgICAgICApOwogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbigkbXNnLCAkcGFyZW50KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbm9kZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhciBzdGFuZGFsb25lIGxpbmUgdG9rZW5zLgogICAgICoKICAgICAqIFJldHVybnMgYSB3aGl0ZXNwYWNlIHRva2VuIGZvciBpbmRlbnRpbmcgcGFydGlhbHMsIGlmIGFwcGxpY2FibGUuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRub2RlcyAgUGFyc2VkIG5vZGVzCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRva2VucyBUb2tlbnMgdG8gYmUgcGFyc2VkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxudWxsIFJlc3VsdGluZyBpbmRlbnQgdG9rZW4sIGlmIGFueQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNsZWFyU3RhbmRhbG9uZUxpbmVzKGFycmF5ICYkbm9kZXMsIGFycmF5ICYkdG9rZW5zKQogICAgewogICAgICAgIGlmICgkdGhpcy0+bGluZVRva2VucyA+IDEpIHsKICAgICAgICAgICAgLy8gdGhpcyBpcyB0aGUgdGhpcmQgb3IgbGF0ZXIgbm9kZSBvbiB0aGlzIGxpbmUsIHNvIGl0IGNhbid0IGJlIHN0YW5kYWxvbmUKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHByZXYgPSBudWxsOwogICAgICAgIGlmICgkdGhpcy0+bGluZVRva2VucyA9PT0gMSkgewogICAgICAgICAgICAvLyB0aGlzIGlzIHRoZSBzZWNvbmQgbm9kZSBvbiB0aGlzIGxpbmUsIHNvIGl0IGNhbid0IGJlIHN0YW5kYWxvbmUKICAgICAgICAgICAgLy8gdW5sZXNzIHRoZSBwcmV2aW91cyBub2RlIGlzIHdoaXRlc3BhY2UuCiAgICAgICAgICAgIGlmICgkcHJldiA9IGVuZCgkbm9kZXMpKSB7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT50b2tlbklzV2hpdGVzcGFjZSgkcHJldikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkbmV4dCA9IHJlc2V0KCR0b2tlbnMpKSB7CiAgICAgICAgICAgIC8vIElmIHdlJ3JlIG9uIGEgbmV3IGxpbmUsIGJhaWwuCiAgICAgICAgICAgIGlmICgkbmV4dFtNdXN0YWNoZV9Ub2tlbml6ZXI6OkxJTkVdICE9PSAkdGhpcy0+bGluZU51bSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiB0aGUgbmV4dCB0b2tlbiBpc24ndCB3aGl0ZXNwYWNlLCBiYWlsLgogICAgICAgICAgICBpZiAoISR0aGlzLT50b2tlbklzV2hpdGVzcGFjZSgkbmV4dCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvdW50KCR0b2tlbnMpICE9PSAxKSB7CiAgICAgICAgICAgICAgICAvLyBVbmxlc3MgaXQncyB0aGUgbGFzdCB0b2tlbiBpbiB0aGUgdGVtcGxhdGUsIHRoZSBuZXh0IHRva2VuCiAgICAgICAgICAgICAgICAvLyBtdXN0IGVuZCBpbiBuZXdsaW5lIGZvciB0aGlzIHRvIGJlIHN0YW5kYWxvbmUuCiAgICAgICAgICAgICAgICBpZiAoc3Vic3RyKCRuZXh0W011c3RhY2hlX1Rva2VuaXplcjo6VkFMVUVdLCAtMSkgIT09ICJcbiIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIERpc2NhcmQgdGhlIHdoaXRlc3BhY2Ugc3VmZml4CiAgICAgICAgICAgIGFycmF5X3NoaWZ0KCR0b2tlbnMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwcmV2KSB7CiAgICAgICAgICAgIC8vIFJldHVybiB0aGUgd2hpdGVzcGFjZSBwcmVmaXgsIGlmIGFueQogICAgICAgICAgICByZXR1cm4gYXJyYXlfcG9wKCRub2Rlcyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciB0b2tlbiBpcyBhIHdoaXRlc3BhY2UgdG9rZW4uCiAgICAgKgogICAgICogVHJ1ZSBpZiB0b2tlbiB0eXBlIGlzIFRfVEVYVCBhbmQgdmFsdWUgaXMgYWxsIHdoaXRlc3BhY2UgY2hhcmFjdGVycy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRva2VuCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgdG9rZW4gaXMgYSB3aGl0ZXNwYWNlIHRva2VuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdG9rZW5Jc1doaXRlc3BhY2UoYXJyYXkgJHRva2VuKQogICAgewogICAgICAgIGlmICgkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSA9PT0gTXVzdGFjaGVfVG9rZW5pemVyOjpUX1RFWFQpIHsKICAgICAgICAgICAgcmV0dXJuIHByZWdfbWF0Y2goJy9eXHMqJC8nLCAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpWQUxVRV0pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciBhIHRva2VuIGlzIGFsbG93ZWQgaW5zaWRlIGEgcGFyZW50IHRhZy4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24gaWYgYW4gaW52YWxpZCB0b2tlbiBpcyBmb3VuZCBpbnNpZGUgYSBwYXJlbnQgdGFnCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5fG51bGwgJHBhcmVudAogICAgICogQHBhcmFtIGFycmF5ICAgICAgJHRva2VuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tJZlRva2VuSXNBbGxvd2VkSW5QYXJlbnQoJHBhcmVudCwgYXJyYXkgJHRva2VuKQogICAgewogICAgICAgIGlmIChpc3NldCgkcGFyZW50KSAmJiAkcGFyZW50W011c3RhY2hlX1Rva2VuaXplcjo6VFlQRV0gPT09IE11c3RhY2hlX1Rva2VuaXplcjo6VF9QQVJFTlQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24oJ0lsbGVnYWwgY29udGVudCBpbiA8IHBhcmVudCB0YWcnLCAkdG9rZW4pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNwbGl0IGEgdGFnIG5hbWUgaW50byBuYW1lIGFuZCBmaWx0ZXJzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFtUYWcgbmFtZSwgQXJyYXkgb2YgZmlsdGVyc10KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXROYW1lQW5kRmlsdGVycygkbmFtZSkKICAgIHsKICAgICAgICAkZmlsdGVycyA9IGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJ3wnLCAkbmFtZSkpOwogICAgICAgICRuYW1lICAgID0gYXJyYXlfc2hpZnQoJGZpbHRlcnMpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJG5hbWUsICRmaWx0ZXJzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZSBhIHByYWdtYS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZW5hYmxlUHJhZ21hKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5wcmFnbWFzWyRuYW1lXSA9IHRydWU7CgogICAgICAgIHN3aXRjaCAoJG5hbWUpIHsKICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9FbmdpbmU6OlBSQUdNQV9CTE9DS1M6CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJhZ21hQmxvY2tzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9FbmdpbmU6OlBSQUdNQV9GSUxURVJTOgogICAgICAgICAgICAgICAgJHRoaXMtPnByYWdtYUZpbHRlcnMgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEludmFsaWQgYXJndW1lbnQgZXhjZXB0aW9uLgogKi8KY2xhc3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBleHRlbmRzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpbXBsZW1lbnRzIE11c3RhY2hlX0V4Y2VwdGlvbgp7CiAgICAvLyBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBMb2dpYyBleGNlcHRpb24uCiAqLwpjbGFzcyBNdXN0YWNoZV9FeGNlcHRpb25fTG9naWNFeGNlcHRpb24gZXh0ZW5kcyBMb2dpY0V4Y2VwdGlvbiBpbXBsZW1lbnRzIE11c3RhY2hlX0V4Y2VwdGlvbgp7CiAgICAvLyBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBzeW50YXggZXhjZXB0aW9uLgogKi8KY2xhc3MgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbiBleHRlbmRzIExvZ2ljRXhjZXB0aW9uIGltcGxlbWVudHMgTXVzdGFjaGVfRXhjZXB0aW9uCnsKICAgIHByb3RlY3RlZCAkdG9rZW47CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICRtc2cKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJHRva2VuCiAgICAgKiBAcGFyYW0gRXhjZXB0aW9uICRwcmV2aW91cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1zZywgYXJyYXkgJHRva2VuLCBFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+dG9rZW4gPSAkdG9rZW47CiAgICAgICAgaWYgKHZlcnNpb25fY29tcGFyZShQSFBfVkVSU0lPTiwgJzUuMy4wJywgJz49JykpIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbXNnLCAwLCAkcHJldmlvdXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1zZyk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUb2tlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50b2tlbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBVbmtub3duIHRlbXBsYXRlIGV4Y2VwdGlvbi4KICovCmNsYXNzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gZXh0ZW5kcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgcHJvdGVjdGVkICR0ZW1wbGF0ZU5hbWU7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICR0ZW1wbGF0ZU5hbWUKICAgICAqIEBwYXJhbSBFeGNlcHRpb24gJHByZXZpb3VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdGVtcGxhdGVOYW1lLCBFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+dGVtcGxhdGVOYW1lID0gJHRlbXBsYXRlTmFtZTsKICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoJ1Vua25vd24gdGVtcGxhdGU6ICVzJywgJHRlbXBsYXRlTmFtZSk7CiAgICAgICAgaWYgKHZlcnNpb25fY29tcGFyZShQSFBfVkVSU0lPTiwgJzUuMy4wJywgJz49JykpIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgMCwgJHByZXZpb3VzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlKTsgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVtcGxhdGVOYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRlbXBsYXRlTmFtZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBVbmtub3duIGZpbHRlciBleGNlcHRpb24uCiAqLwpjbGFzcyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93bkZpbHRlckV4Y2VwdGlvbiBleHRlbmRzIFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiBpbXBsZW1lbnRzIE11c3RhY2hlX0V4Y2VwdGlvbgp7CiAgICBwcm90ZWN0ZWQgJGZpbHRlck5hbWU7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICRmaWx0ZXJOYW1lCiAgICAgKiBAcGFyYW0gRXhjZXB0aW9uICRwcmV2aW91cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGZpbHRlck5hbWUsIEV4Y2VwdGlvbiAkcHJldmlvdXMgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5maWx0ZXJOYW1lID0gJGZpbHRlck5hbWU7CiAgICAgICAgJG1lc3NhZ2UgPSBzcHJpbnRmKCdVbmtub3duIGZpbHRlcjogJXMnLCAkZmlsdGVyTmFtZSk7CiAgICAgICAgaWYgKHZlcnNpb25fY29tcGFyZShQSFBfVkVSU0lPTiwgJzUuMy4wJywgJz49JykpIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgMCwgJHByZXZpb3VzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlKTsgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsdGVyTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5maWx0ZXJOYW1lOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIFVua25vd24gaGVscGVyIGV4Y2VwdGlvbi4KICovCmNsYXNzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duSGVscGVyRXhjZXB0aW9uIGV4dGVuZHMgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGltcGxlbWVudHMgTXVzdGFjaGVfRXhjZXB0aW9uCnsKICAgIHByb3RlY3RlZCAkaGVscGVyTmFtZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJGhlbHBlck5hbWUKICAgICAqIEBwYXJhbSBFeGNlcHRpb24gJHByZXZpb3VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaGVscGVyTmFtZSwgRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmhlbHBlck5hbWUgPSAkaGVscGVyTmFtZTsKICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoJ1Vua25vd24gaGVscGVyOiAlcycsICRoZWxwZXJOYW1lKTsKICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNS4zLjAnLCAnPj0nKSkgewogICAgICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAwLCAkcHJldmlvdXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UpOyAvLyBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIZWxwZXJOYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhlbHBlck5hbWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogUnVudGltZSBleGNlcHRpb24uCiAqLwpjbGFzcyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQWJzdHJhY3QgTXVzdGFjaGUgQ2FjaGUgY2xhc3MuCiAqCiAqIFByb3ZpZGVzIGxvZ2dpbmcgc3VwcG9ydCB0byBjaGlsZCBpbXBsZW1lbnRhdGlvbnMuCiAqCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgTXVzdGFjaGVfQ2FjaGVfQWJzdHJhY3RDYWNoZSBpbXBsZW1lbnRzIE11c3RhY2hlX0NhY2hlCnsKICAgIHByaXZhdGUgJGxvZ2dlciA9IG51bGw7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgbG9nZ2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfTG9nZ2VyfFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2dnZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IGEgbG9nZ2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Mb2dnZXJ8UHNyXExvZ1xMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9nZ2VyKCRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgIGlmICgkbG9nZ2VyICE9PSBudWxsICYmICEoJGxvZ2dlciBpbnN0YW5jZW9mIE11c3RhY2hlX0xvZ2dlciB8fCBpc19hKCRsb2dnZXIsICdQc3JcXExvZ1xcTG9nZ2VySW50ZXJmYWNlJykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdFeHBlY3RlZCBhbiBpbnN0YW5jZSBvZiBNdXN0YWNoZV9Mb2dnZXIgb3IgUHNyXFxMb2dcXExvZ2dlckludGVyZmFjZS4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2dnZXIgPSAkbG9nZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgbG9nIHJlY29yZCBpZiBsb2dnaW5nIGlzIGVuYWJsZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGV2ZWwgICBUaGUgbG9nZ2luZyBsZXZlbAogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQgVGhlIGxvZyBjb250ZXh0CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBsb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+bG9nZ2VyKSkgewogICAgICAgICAgICAkdGhpcy0+bG9nZ2VyLT5sb2coJGxldmVsLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBDYWNoZSBpbi1tZW1vcnkgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoZSBpbi1tZW1vcnkgY2FjaGUgaXMgdXNlZCBmb3IgdW5jYWNoZWQgbGFtYmRhIHNlY3Rpb24gdGVtcGxhdGVzLiBJdCdzIGFsc28gdXNlZnVsIGR1cmluZyBkZXZlbG9wbWVudCwgYnV0IGlzIG5vdAogKiByZWNvbW1lbmRlZCBmb3IgcHJvZHVjdGlvbiB1c2UuCiAqLwpjbGFzcyBNdXN0YWNoZV9DYWNoZV9Ob29wQ2FjaGUgZXh0ZW5kcyBNdXN0YWNoZV9DYWNoZV9BYnN0cmFjdENhY2hlCnsKICAgIC8qKgogICAgICogTG9hZHMgbm90aGluZy4gTW92ZSBhbG9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRrZXkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJGtleSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2FkcyB0aGUgY29tcGlsZWQgTXVzdGFjaGUgVGVtcGxhdGUgY2xhc3Mgd2l0aG91dCBjYWNoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNhY2hlKCRrZXksICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKAogICAgICAgICAgICBNdXN0YWNoZV9Mb2dnZXI6OldBUk5JTkcsCiAgICAgICAgICAgICdUZW1wbGF0ZSBjYWNoZSBkaXNhYmxlZCwgZXZhbHVhdGluZyAie2NsYXNzTmFtZX0iIGNsYXNzIGF0IHJ1bnRpbWUnLAogICAgICAgICAgICBhcnJheSgnY2xhc3NOYW1lJyA9PiAka2V5KQogICAgICAgICk7CiAgICAgICAgZXZhbCgnPz4nIC4gJHZhbHVlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBDYWNoZSBmaWxlc3lzdGVtIGltcGxlbWVudGF0aW9uLgogKgogKiBBIEZpbGVzeXN0ZW1DYWNoZSBpbnN0YW5jZSBjYWNoZXMgTXVzdGFjaGUgVGVtcGxhdGUgY2xhc3NlcyBmcm9tIHRoZSBmaWxlc3lzdGVtIGJ5IG5hbWU6CiAqCiAqICAgICAkY2FjaGUgPSBuZXcgTXVzdGFjaGVfQ2FjaGVfRmlsZXN5c3RlbUNhY2hlKGRpcm5hbWUoX19GSUxFX18pLicvY2FjaGUnKTsKICogICAgICRjYWNoZS0+Y2FjaGUoJGNsYXNzTmFtZSwgJGNvbXBpbGVkU291cmNlKTsKICoKICogVGhlIEZpbGVzeXN0ZW1DYWNoZSBiZW5lZml0cyBmcm9tIGFueSBvcGNvZGUgY2FjaGluZyB0aGF0IG1heSBiZSBzZXR1cCBpbiB5b3VyIGVudmlyb25tZW50LiBTbyBkbyB0aGF0LCBrPwogKi8KY2xhc3MgTXVzdGFjaGVfQ2FjaGVfRmlsZXN5c3RlbUNhY2hlIGV4dGVuZHMgTXVzdGFjaGVfQ2FjaGVfQWJzdHJhY3RDYWNoZQp7CiAgICBwcml2YXRlICRiYXNlRGlyOwogICAgcHJpdmF0ZSAkZmlsZU1vZGU7CgogICAgLyoqCiAgICAgKiBGaWxlc3lzdGVtIGNhY2hlIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VEaXIgIERpcmVjdG9yeSBmb3IgY29tcGlsZWQgdGVtcGxhdGVzCiAgICAgKiBAcGFyYW0gaW50ICAgICRmaWxlTW9kZSBPdmVycmlkZSBkZWZhdWx0IHBlcm1pc3Npb25zIGZvciBjYWNoZSBmaWxlcy4gRGVmYXVsdHMgdG8gdXNpbmcgdGhlIHN5c3RlbS1kZWZpbmVkIHVtYXNrCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciwgJGZpbGVNb2RlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YmFzZURpciA9ICRiYXNlRGlyOwogICAgICAgICR0aGlzLT5maWxlTW9kZSA9ICRmaWxlTW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgdGhlIGNsYXNzIGZyb20gY2FjaGUgdXNpbmcgYHJlcXVpcmVfb25jZWAuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRrZXkpCiAgICB7CiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmdldENhY2hlRmlsZW5hbWUoJGtleSk7CiAgICAgICAgaWYgKCFpc19maWxlKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmVxdWlyZV9vbmNlICRmaWxlTmFtZTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWNoZSBhbmQgbG9hZCB0aGUgY29tcGlsZWQgY2xhc3MuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2FjaGUoJGtleSwgJHZhbHVlKQogICAgewogICAgICAgICRmaWxlTmFtZSA9ICR0aGlzLT5nZXRDYWNoZUZpbGVuYW1lKCRrZXkpOwoKICAgICAgICAkdGhpcy0+bG9nKAogICAgICAgICAgICBNdXN0YWNoZV9Mb2dnZXI6OkRFQlVHLAogICAgICAgICAgICAnV3JpdGluZyB0byB0ZW1wbGF0ZSBjYWNoZTogIntmaWxlTmFtZX0iJywKICAgICAgICAgICAgYXJyYXkoJ2ZpbGVOYW1lJyA9PiAkZmlsZU5hbWUpCiAgICAgICAgKTsKCiAgICAgICAgJHRoaXMtPndyaXRlRmlsZSgkZmlsZU5hbWUsICR2YWx1ZSk7CiAgICAgICAgJHRoaXMtPmxvYWQoJGtleSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZCB0aGUgY2FjaGUgZmlsZW5hbWUuCiAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSBmb3IgY3VzdG9tIGNhY2hlIGRpcmVjdG9yeSBzdHJ1Y3R1cmVzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q2FjaGVGaWxlbmFtZSgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gc3ByaW50ZignJXMvJXMucGhwJywgJHRoaXMtPmJhc2VEaXIsICRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBjYWNoZSBkaXJlY3RvcnkuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbiBJZiB1bmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVOYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBidWlsZERpcmVjdG9yeUZvckZpbGVuYW1lKCRmaWxlTmFtZSkKICAgIHsKICAgICAgICAkZGlyTmFtZSA9IGRpcm5hbWUoJGZpbGVOYW1lKTsKICAgICAgICBpZiAoIWlzX2RpcigkZGlyTmFtZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6SU5GTywKICAgICAgICAgICAgICAgICdDcmVhdGluZyBNdXN0YWNoZSB0ZW1wbGF0ZSBjYWNoZSBkaXJlY3Rvcnk6ICJ7ZGlyTmFtZX0iJywKICAgICAgICAgICAgICAgIGFycmF5KCdkaXJOYW1lJyA9PiAkZGlyTmFtZSkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIEBta2RpcigkZGlyTmFtZSwgMDc3NywgdHJ1ZSk7CiAgICAgICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVTdGFydAogICAgICAgICAgICBpZiAoIWlzX2RpcigkZGlyTmFtZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY3JlYXRlIGNhY2hlIGRpcmVjdG9yeSAiJXMiLicsICRkaXJOYW1lKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZUVuZAogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkaXJOYW1lOwogICAgfQoKICAgIC8qKgogICAgICogV3JpdGUgY2FjaGUgZmlsZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uIElmIHVuYWJsZSB0byB3cml0ZSBmaWxlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZU5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gd3JpdGVGaWxlKCRmaWxlTmFtZSwgJHZhbHVlKQogICAgewogICAgICAgICRkaXJOYW1lID0gJHRoaXMtPmJ1aWxkRGlyZWN0b3J5Rm9yRmlsZW5hbWUoJGZpbGVOYW1lKTsKCiAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgTXVzdGFjaGVfTG9nZ2VyOjpERUJVRywKICAgICAgICAgICAgJ0NhY2hpbmcgY29tcGlsZWQgdGVtcGxhdGUgdG8gIntmaWxlTmFtZX0iJywKICAgICAgICAgICAgYXJyYXkoJ2ZpbGVOYW1lJyA9PiAkZmlsZU5hbWUpCiAgICAgICAgKTsKCiAgICAgICAgJHRlbXBGaWxlID0gdGVtcG5hbSgkZGlyTmFtZSwgYmFzZW5hbWUoJGZpbGVOYW1lKSk7CiAgICAgICAgaWYgKGZhbHNlICE9PSBAZmlsZV9wdXRfY29udGVudHMoJHRlbXBGaWxlLCAkdmFsdWUpKSB7CiAgICAgICAgICAgIGlmIChAcmVuYW1lKCR0ZW1wRmlsZSwgJGZpbGVOYW1lKSkgewogICAgICAgICAgICAgICAgJG1vZGUgPSBpc3NldCgkdGhpcy0+ZmlsZU1vZGUpID8gJHRoaXMtPmZpbGVNb2RlIDogKDA2NjYgJiB+dW1hc2soKSk7CiAgICAgICAgICAgICAgICBAY2htb2QoJGZpbGVOYW1lLCAkbW9kZSk7CgogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKICAgICAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6RVJST1IsCiAgICAgICAgICAgICAgICAnVW5hYmxlIHRvIHJlbmFtZSBNdXN0YWNoZSB0ZW1wIGNhY2hlIGZpbGU6ICJ7dGVtcE5hbWV9IiAtPiAie2ZpbGVOYW1lfSInLAogICAgICAgICAgICAgICAgYXJyYXkoJ3RlbXBOYW1lJyA9PiAkdGVtcEZpbGUsICdmaWxlTmFtZScgPT4gJGZpbGVOYW1lKQogICAgICAgICAgICApOwogICAgICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCiAgICAgICAgfQoKICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHdyaXRlIGNhY2hlIGZpbGUgIiVzIi4nLCAkZmlsZU5hbWUpKTsKICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgQ2FjaGUgaW50ZXJmYWNlLgogKgogKiBJbnRlcmZhY2UgZm9yIGNhY2hpbmcgYW5kIGxvYWRpbmcgTXVzdGFjaGVfVGVtcGxhdGUgY2xhc3NlcwogKiBnZW5lcmF0ZWQgYnkgdGhlIE11c3RhY2hlX0NvbXBpbGVyLgogKi8KaW50ZXJmYWNlIE11c3RhY2hlX0NhY2hlCnsKICAgIC8qKgogICAgICogTG9hZCBhIGNvbXBpbGVkIE11c3RhY2hlX1RlbXBsYXRlIGNsYXNzIGZyb20gY2FjaGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKgogICAgICogQHJldHVybiBib29sIGluZGljYXRlcyBzdWNjZXNzZnVsbHkgY2xhc3MgbG9hZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZCgka2V5KTsKCiAgICAvKioKICAgICAqIENhY2hlIGFuZCBsb2FkIGEgY29tcGlsZWQgTXVzdGFjaGVfVGVtcGxhdGUgY2xhc3MuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2FjaGUoJGtleSwgJHZhbHVlKTsKCiAgICAvKioKICAgICAqIFNldCBhIGxvZ2dlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfTG9nZ2VyfFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvZ2dlcigkbG9nZ2VyID0gbnVsbCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgdGVtcGxhdGUgU291cmNlIGludGVyZmFjZS4KICovCmludGVyZmFjZSBNdXN0YWNoZV9Tb3VyY2UKewogICAgLyoqCiAgICAgKiBHZXQgdGhlIFNvdXJjZSBrZXkgKHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGNvbXBpbGVkIGNsYXNzIG5hbWUpLgogICAgICoKICAgICAqIFRoaXMgbXVzdCByZXR1cm4gYSBkaXN0aW5jdCBrZXkgZm9yIGVhY2ggdGVtcGxhdGUgc291cmNlLiBGb3IgZXhhbXBsZSwgYW4KICAgICAqIE1ENSBoYXNoIG9mIHRoZSB0ZW1wbGF0ZSBjb250ZW50cyB3b3VsZCBwcm9iYWJseSBkbyB0aGUgdHJpY2suIFRoZQogICAgICogUHJvZHVjdGlvbkZpbGVzeXN0ZW1Mb2FkZXIgdXNlcyBtdGltZSBhbmQgZmlsZSBwYXRoLiBJZiB5b3VyIHByb2R1Y3Rpb24KICAgICAqIHNvdXJjZSBkaXJlY3RvcnkgaXMgdW5kZXIgdmVyc2lvbiBjb250cm9sLCB5b3UgY291bGQgdXNlIHRoZSBjdXJyZW50IEdpdAogICAgICogcmV2IGFuZCB0aGUgZmlsZSBwYXRoLi4uCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHdoZW4gYSBzb3VyY2UgZmlsZSBjYW5ub3QgYmUgcmVhZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXkoKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgdGVtcGxhdGUgU291cmNlLgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB3aGVuIGEgc291cmNlIGZpbGUgY2Fubm90IGJlIHJlYWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQSBNdXN0YWNoZSBTdHJlYW0gTG9nZ2VyLgogKgogKiBUaGUgU3RyZWFtIExvZ2dlciB3cmFwcyBhIGZpbGUgcmVzb3VyY2UgaW5zdGFuY2UgKHN1Y2ggYXMgYSBzdHJlYW0pIG9yIGEKICogc3RyZWFtIFVSTC4gQWxsIGxvZyBtZXNzYWdlcyBvdmVyIHRoZSB0aHJlc2hvbGQgbGV2ZWwgd2lsbCBiZSBhcHBlbmRlZCB0bwogKiB0aGlzIHN0cmVhbS4KICoKICogSGludDogVHJ5IGBwaHA6Ly9zdGRlcnJgIGZvciB5b3VyIHN0cmVhbSBVUkwuCiAqLwpjbGFzcyBNdXN0YWNoZV9Mb2dnZXJfU3RyZWFtTG9nZ2VyIGV4dGVuZHMgTXVzdGFjaGVfTG9nZ2VyX0Fic3RyYWN0TG9nZ2VyCnsKICAgIHByb3RlY3RlZCBzdGF0aWMgJGxldmVscyA9IGFycmF5KAogICAgICAgIHNlbGY6OkRFQlVHICAgICA9PiAxMDAsCiAgICAgICAgc2VsZjo6SU5GTyAgICAgID0+IDIwMCwKICAgICAgICBzZWxmOjpOT1RJQ0UgICAgPT4gMjUwLAogICAgICAgIHNlbGY6OldBUk5JTkcgICA9PiAzMDAsCiAgICAgICAgc2VsZjo6RVJST1IgICAgID0+IDQwMCwKICAgICAgICBzZWxmOjpDUklUSUNBTCAgPT4gNTAwLAogICAgICAgIHNlbGY6OkFMRVJUICAgICA9PiA1NTAsCiAgICAgICAgc2VsZjo6RU1FUkdFTkNZID0+IDYwMCwKICAgICk7CgogICAgcHJvdGVjdGVkICRsZXZlbDsKICAgIHByb3RlY3RlZCAkc3RyZWFtID0gbnVsbDsKICAgIHByb3RlY3RlZCAkdXJsICAgID0gbnVsbDsKCiAgICAvKioKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2dnaW5nIGxldmVsIGlzIHVua25vd24KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8c3RyaW5nICRzdHJlYW0gUmVzb3VyY2UgaW5zdGFuY2Ugb3IgVVJMCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRsZXZlbCAgVGhlIG1pbmltdW0gbG9nZ2luZyBsZXZlbCBhdCB3aGljaCB0aGlzIGhhbmRsZXIgd2lsbCBiZSB0cmlnZ2VyZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzdHJlYW0sICRsZXZlbCA9IE11c3RhY2hlX0xvZ2dlcjo6RVJST1IpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldExldmVsKCRsZXZlbCk7CgogICAgICAgIGlmIChpc19yZXNvdXJjZSgkc3RyZWFtKSkgewogICAgICAgICAgICAkdGhpcy0+c3RyZWFtID0gJHN0cmVhbTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+dXJsID0gJHN0cmVhbTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbG9zZSBzdHJlYW0gcmVzb3VyY2VzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpCiAgICB7CiAgICAgICAgaWYgKGlzX3Jlc291cmNlKCR0aGlzLT5zdHJlYW0pKSB7CiAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+c3RyZWFtKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIG1pbmltdW0gbG9nZ2luZyBsZXZlbC4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvZ2dpbmcgbGV2ZWwgaXMgdW5rbm93bgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGxldmVsIFRoZSBtaW5pbXVtIGxvZ2dpbmcgbGV2ZWwgd2hpY2ggd2lsbCBiZSB3cml0dGVuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZXZlbCgkbGV2ZWwpCiAgICB7CiAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRsZXZlbCwgc2VsZjo6JGxldmVscykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5leHBlY3RlZCBsb2dnaW5nIGxldmVsOiAlcycsICRsZXZlbCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxldmVsID0gJGxldmVsOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50IG1pbmltdW0gbG9nZ2luZyBsZXZlbC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGV2ZWwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGV2ZWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbG9nZ2luZyBsZXZlbCBpcyB1bmtub3duCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRsZXZlbCwgc2VsZjo6JGxldmVscykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5leHBlY3RlZCBsb2dnaW5nIGxldmVsOiAlcycsICRsZXZlbCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6OiRsZXZlbHNbJGxldmVsXSA+PSBzZWxmOjokbGV2ZWxzWyR0aGlzLT5sZXZlbF0pIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlTG9nKCRsZXZlbCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZSBhIHJlY29yZCB0byB0aGUgbG9nLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0xvZ2ljRXhjZXB0aW9uICAgSWYgbmVpdGhlciBhIHN0cmVhbSByZXNvdXJjZSBub3IgdXJsIGlzIHByZXNlbnQKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHN0cmVhbSB1cmwgY2Fubm90IGJlIG9wZW5lZAogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICAgJGxldmVsICAgVGhlIGxvZ2dpbmcgbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgVGhlIGxvZyBtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0IFRoZSBsb2cgY29udGV4dAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGVMb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmICghaXNfcmVzb3VyY2UoJHRoaXMtPnN0cmVhbSkpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Mb2dpY0V4Y2VwdGlvbignTWlzc2luZyBzdHJlYW0gdXJsLCB0aGUgc3RyZWFtIGNhbiBub3QgYmUgb3BlbmVkLiBUaGlzIG1heSBiZSBjYXVzZWQgYnkgYSBwcmVtYXR1cmUgY2FsbCB0byBjbG9zZSgpLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+c3RyZWFtID0gZm9wZW4oJHRoaXMtPnVybCwgJ2EnKTsKICAgICAgICAgICAgaWYgKCFpc19yZXNvdXJjZSgkdGhpcy0+c3RyZWFtKSkgewogICAgICAgICAgICAgICAgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZVN0YXJ0CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVGhlIHN0cmVhbSBvciBmaWxlICIlcyIgY291bGQgbm90IGJlIG9wZW5lZC4nLCAkdGhpcy0+dXJsKSk7CiAgICAgICAgICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ3cml0ZSgkdGhpcy0+c3RyZWFtLCBzZWxmOjpmb3JtYXRMaW5lKCRsZXZlbCwgJG1lc3NhZ2UsICRjb250ZXh0KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBsb2dnaW5nIGxldmVsLgogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2dnaW5nIGxldmVsIGlzIHVua25vd24KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0TGV2ZWxOYW1lKCRsZXZlbCkKICAgIHsKICAgICAgICByZXR1cm4gc3RydG91cHBlcigkbGV2ZWwpOwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0IGEgbG9nIGxpbmUgZm9yIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbCAgIFRoZSBsb2dnaW5nIGxldmVsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dCBUaGUgbG9nIGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdExpbmUoJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKAogICAgICAgICAgICAiJXM6ICVzXG4iLAogICAgICAgICAgICBzZWxmOjpnZXRMZXZlbE5hbWUoJGxldmVsKSwKICAgICAgICAgICAgc2VsZjo6aW50ZXJwb2xhdGVNZXNzYWdlKCRtZXNzYWdlLCAkY29udGV4dCkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogSW50ZXJwb2xhdGUgY29udGV4dCB2YWx1ZXMgaW50byB0aGUgbWVzc2FnZSBwbGFjZWhvbGRlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gaW50ZXJwb2xhdGVNZXNzYWdlKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkbWVzc2FnZSwgJ3snKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgICAgIH0KCiAgICAgICAgLy8gYnVpbGQgYSByZXBsYWNlbWVudCBhcnJheSB3aXRoIGJyYWNlcyBhcm91bmQgdGhlIGNvbnRleHQga2V5cwogICAgICAgICRyZXBsYWNlID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkY29udGV4dCBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgJHJlcGxhY2VbJ3snIC4gJGtleSAuICd9J10gPSAkdmFsOwogICAgICAgIH0KCiAgICAgICAgLy8gaW50ZXJwb2xhdGUgcmVwbGFjZW1lbnQgdmFsdWVzIGludG8gdGhlIHRoZSBtZXNzYWdlIGFuZCByZXR1cm4KICAgICAgICByZXR1cm4gc3RydHIoJG1lc3NhZ2UsICRyZXBsYWNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBUaGlzIGlzIGEgc2ltcGxlIExvZ2dlciBpbXBsZW1lbnRhdGlvbiB0aGF0IG90aGVyIExvZ2dlcnMgY2FuIGluaGVyaXQgZnJvbS4KICoKICogVGhpcyBpcyBpZGVudGljYWwgdG8gdGhlIFBzclxMb2dcQWJzdHJhY3RMb2dnZXIuCiAqCiAqIEl0IHNpbXBseSBkZWxlZ2F0ZXMgYWxsIGxvZy1sZXZlbC1zcGVjaWZpYyBtZXRob2RzIHRvIHRoZSBgbG9nYCBtZXRob2QgdG8KICogcmVkdWNlIGJvaWxlcnBsYXRlIGNvZGUgdGhhdCBhIHNpbXBsZSBMb2dnZXIgdGhhdCBkb2VzIHRoZSBzYW1lIHRoaW5nIHdpdGgKICogbWVzc2FnZXMgcmVnYXJkbGVzcyBvZiB0aGUgZXJyb3IgbGV2ZWwgaGFzIHRvIGltcGxlbWVudC4KICovCmFic3RyYWN0IGNsYXNzIE11c3RhY2hlX0xvZ2dlcl9BYnN0cmFjdExvZ2dlciBpbXBsZW1lbnRzIE11c3RhY2hlX0xvZ2dlcgp7CiAgICAvKioKICAgICAqIFN5c3RlbSBpcyB1bnVzYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbWVyZ2VuY3koJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKE11c3RhY2hlX0xvZ2dlcjo6RU1FUkdFTkNZLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkuCiAgICAgKgogICAgICogRXhhbXBsZTogRW50aXJlIHdlYnNpdGUgZG93biwgZGF0YWJhc2UgdW5hdmFpbGFibGUsIGV0Yy4gVGhpcyBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhlIFNNUyBhbGVydHMgYW5kIHdha2UgeW91IHVwLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFsZXJ0KCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhNdXN0YWNoZV9Mb2dnZXI6OkFMRVJULCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JpdGljYWwgY29uZGl0aW9ucy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBBcHBsaWNhdGlvbiBjb21wb25lbnQgdW5hdmFpbGFibGUsIHVuZXhwZWN0ZWQgZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyaXRpY2FsKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhNdXN0YWNoZV9Mb2dnZXI6OkNSSVRJQ0FMLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUnVudGltZSBlcnJvcnMgdGhhdCBkbyBub3QgcmVxdWlyZSBpbW1lZGlhdGUgYWN0aW9uIGJ1dCBzaG91bGQgdHlwaWNhbGx5CiAgICAgKiBiZSBsb2dnZWQgYW5kIG1vbml0b3JlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTXVzdGFjaGVfTG9nZ2VyOjpFUlJPUiwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbmFsIG9jY3VycmVuY2VzIHRoYXQgYXJlIG5vdCBlcnJvcnMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlIG9mIGRlcHJlY2F0ZWQgQVBJcywgcG9vciB1c2Ugb2YgYW4gQVBJLCB1bmRlc2lyYWJsZSB0aGluZ3MKICAgICAqIHRoYXQgYXJlIG5vdCBuZWNlc3NhcmlseSB3cm9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3YXJuaW5nKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhNdXN0YWNoZV9Mb2dnZXI6OldBUk5JTkcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKE11c3RhY2hlX0xvZ2dlcjo6Tk9USUNFLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogSW50ZXJlc3RpbmcgZXZlbnRzLgogICAgICoKICAgICAqIEV4YW1wbGU6IFVzZXIgbG9ncyBpbiwgU1FMIGxvZ3MuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5mbygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTXVzdGFjaGVfTG9nZ2VyOjpJTkZPLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogRGV0YWlsZWQgZGVidWcgaW5mb3JtYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVidWcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKE11c3RhY2hlX0xvZ2dlcjo6REVCVUcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgTGFtYmRhIEhlbHBlci4KICoKICogUGFzc2VkIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gc2VjdGlvbiBsYW1iZGFzIChoaWdoZXIgb3JkZXIgc2VjdGlvbnMpLAogKiBnaXZpbmcgdGhlbSBhY2Nlc3MgdG8gYSBgcmVuZGVyYCBtZXRob2QgZm9yIHJlbmRlcmluZyBhIHN0cmluZyB3aXRoIHRoZQogKiBjdXJyZW50IGNvbnRleHQuCiAqLwpjbGFzcyBNdXN0YWNoZV9MYW1iZGFIZWxwZXIKewogICAgcHJpdmF0ZSAkbXVzdGFjaGU7CiAgICBwcml2YXRlICRjb250ZXh0OwogICAgcHJpdmF0ZSAkZGVsaW1zOwoKICAgIC8qKgogICAgICogTXVzdGFjaGUgTGFtYmRhIEhlbHBlciBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfRW5naW5lICAkbXVzdGFjaGUgTXVzdGFjaGUgZW5naW5lIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfQ29udGV4dCAkY29udGV4dCAgUmVuZGVyaW5nIGNvbnRleHQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRkZWxpbXMgICBPcHRpb25hbCBjdXN0b20gZGVsaW1pdGVycywgaW4gdGhlIGZvcm1hdCBge3s9IDwlICU+ID19fWAuIChkZWZhdWx0OiBudWxsKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoTXVzdGFjaGVfRW5naW5lICRtdXN0YWNoZSwgTXVzdGFjaGVfQ29udGV4dCAkY29udGV4dCwgJGRlbGltcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm11c3RhY2hlID0gJG11c3RhY2hlOwogICAgICAgICR0aGlzLT5jb250ZXh0ICA9ICRjb250ZXh0OwogICAgICAgICR0aGlzLT5kZWxpbXMgICA9ICRkZWxpbXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXIgYSBzdHJpbmcgYXMgYSBNdXN0YWNoZSB0ZW1wbGF0ZSB3aXRoIHRoZSBjdXJyZW50IHJlbmRlcmluZyBjb250ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFJlbmRlcmVkIHRlbXBsYXRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXIoJHN0cmluZykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm11c3RhY2hlCiAgICAgICAgICAgIC0+bG9hZExhbWJkYSgoc3RyaW5nKSAkc3RyaW5nLCAkdGhpcy0+ZGVsaW1zKQogICAgICAgICAgICAtPnJlbmRlckludGVybmFsKCR0aGlzLT5jb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlciBhIHN0cmluZyBhcyBhIE11c3RhY2hlIHRlbXBsYXRlIHdpdGggdGhlIGN1cnJlbnQgcmVuZGVyaW5nIGNvbnRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUmVuZGVyZWQgdGVtcGxhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCRzdHJpbmcpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW5kZXIoJHN0cmluZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBMYW1iZGEgSGVscGVyIHdpdGggY3VzdG9tIGRlbGltaXRlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZGVsaW1zIEN1c3RvbSBkZWxpbWl0ZXJzLCBpbiB0aGUgZm9ybWF0IGB7ez0gPCUgJT4gPX19YAogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfTGFtYmRhSGVscGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3aXRoRGVsaW1pdGVycygkZGVsaW1zKQogICAgewogICAgICAgIHJldHVybiBuZXcgc2VsZigkdGhpcy0+bXVzdGFjaGUsICR0aGlzLT5jb250ZXh0LCAkZGVsaW1zKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBBIGNvbGxlY3Rpb24gb2YgaGVscGVycyBmb3IgYSBNdXN0YWNoZSBpbnN0YW5jZS4KICovCmNsYXNzIE11c3RhY2hlX0hlbHBlckNvbGxlY3Rpb24KewogICAgcHJpdmF0ZSAkaGVscGVycyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBIZWxwZXIgQ29sbGVjdGlvbiBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBPcHRpb25hbGx5IGFjY2VwdHMgYW4gYXJyYXkgKG9yIFRyYXZlcnNhYmxlKSBvZiBgJG5hbWUgPT4gJGhlbHBlcmAgcGFpcnMuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSAkaGVscGVycyBhcmd1bWVudCBpc24ndCBhbiBhcnJheSBvciBUcmF2ZXJzYWJsZQogICAgICoKICAgICAqIEBwYXJhbSBhcnJheXxUcmF2ZXJzYWJsZSAkaGVscGVycyAoZGVmYXVsdDogbnVsbCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRoZWxwZXJzID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGhlbHBlcnMgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc19hcnJheSgkaGVscGVycykgJiYgISRoZWxwZXJzIGluc3RhbmNlb2YgVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0hlbHBlckNvbGxlY3Rpb24gY29uc3RydWN0b3IgZXhwZWN0cyBhbiBhcnJheSBvZiBoZWxwZXJzJyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkaGVscGVycyBhcyAkbmFtZSA9PiAkaGVscGVyKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGQoJG5hbWUsICRoZWxwZXIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG11dGF0b3IuCiAgICAgKgogICAgICogQHNlZSBNdXN0YWNoZV9IZWxwZXJDb2xsZWN0aW9uOjphZGQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRoZWxwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fc2V0KCRuYW1lLCAkaGVscGVyKQogICAgewogICAgICAgICR0aGlzLT5hZGQoJG5hbWUsICRoZWxwZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgaGVscGVyIHRvIHRoaXMgY29sbGVjdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRoZWxwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZCgkbmFtZSwgJGhlbHBlcikKICAgIHsKICAgICAgICAkdGhpcy0+aGVscGVyc1skbmFtZV0gPSAkaGVscGVyOwogICAgfQoKICAgIC8qKgogICAgICogTWFnaWMgYWNjZXNzb3IuCiAgICAgKgogICAgICogQHNlZSBNdXN0YWNoZV9IZWxwZXJDb2xsZWN0aW9uOjpnZXQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBIZWxwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fZ2V0KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIGhlbHBlciBieSBuYW1lLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25IZWxwZXJFeGNlcHRpb24gSWYgaGVscGVyIGRvZXMgbm90IGV4aXN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgSGVscGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzKCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25IZWxwZXJFeGNlcHRpb24oJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5oZWxwZXJzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIGlzc2V0KCkuCiAgICAgKgogICAgICogQHNlZSBNdXN0YWNoZV9IZWxwZXJDb2xsZWN0aW9uOjpoYXMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgaGVscGVyIGlzIHByZXNlbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9faXNzZXQoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXMoJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciBhIGdpdmVuIGhlbHBlciBpcyBwcmVzZW50IGluIHRoZSBjb2xsZWN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiBoZWxwZXIgaXMgcHJlc2VudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9rZXlfZXhpc3RzKCRuYW1lLCAkdGhpcy0+aGVscGVycyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWdpYyB1bnNldCgpLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbjo6cmVtb3ZlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX191bnNldCgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+cmVtb3ZlKCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBoZWxwZXIgaXMgcHJlc2VudCBpbiB0aGUgY29sbGVjdGlvbi4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duSGVscGVyRXhjZXB0aW9uIGlmIHRoZSByZXF1ZXN0ZWQgaGVscGVyIGlzIG5vdCBwcmVzZW50CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhcygkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duSGVscGVyRXhjZXB0aW9uKCRuYW1lKTsKICAgICAgICB9CgogICAgICAgIHVuc2V0KCR0aGlzLT5oZWxwZXJzWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhciB0aGUgaGVscGVyIGNvbGxlY3Rpb24uCiAgICAgKgogICAgICogUmVtb3ZlcyBhbGwgaGVscGVycyBmcm9tIHRoaXMgY29sbGVjdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYXIoKQogICAgewogICAgICAgICR0aGlzLT5oZWxwZXJzID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIGhlbHBlciBjb2xsZWN0aW9uIGlzIGVtcHR5LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBUcnVlIGlmIHRoZSBjb2xsZWN0aW9uIGlzIGVtcHR5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0VtcHR5KCkKICAgIHsKICAgICAgICByZXR1cm4gZW1wdHkoJHRoaXMtPmhlbHBlcnMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEFic3RyYWN0IE11c3RhY2hlIFRlbXBsYXRlIGNsYXNzLgogKgogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIE11c3RhY2hlX1RlbXBsYXRlCnsKICAgIC8qKgogICAgICogQHZhciBNdXN0YWNoZV9FbmdpbmUKICAgICAqLwogICAgcHJvdGVjdGVkICRtdXN0YWNoZTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0cmljdENhbGxhYmxlcyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogTXVzdGFjaGUgVGVtcGxhdGUgY29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIE11c3RhY2hlX0VuZ2luZSAkbXVzdGFjaGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KE11c3RhY2hlX0VuZ2luZSAkbXVzdGFjaGUpCiAgICB7CiAgICAgICAgJHRoaXMtPm11c3RhY2hlID0gJG11c3RhY2hlOwogICAgfQoKICAgIC8qKgogICAgICogTXVzdGFjaGUgVGVtcGxhdGUgaW5zdGFuY2VzIGNhbiBiZSB0cmVhdGVkIGFzIGEgZnVuY3Rpb24gYW5kIHJlbmRlcmVkIGJ5IHNpbXBseSBjYWxsaW5nIHRoZW0uCiAgICAgKgogICAgICogICAgICRtID0gbmV3IE11c3RhY2hlX0VuZ2luZTsKICAgICAqICAgICAkdHBsID0gJG0tPmxvYWRUZW1wbGF0ZSgnSGVsbG8sIHt7IG5hbWUgfX0hJyk7CiAgICAgKiAgICAgZWNobyAkdHBsKGFycmF5KCduYW1lJyA9PiAnV29ybGQnKSk7IC8vICJIZWxsbywgV29ybGQhIgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfVGVtcGxhdGU6OnJlbmRlcgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkY29udGV4dCBBcnJheSBvciBvYmplY3QgcmVuZGVyaW5nIGNvbnRleHQgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUmVuZGVyZWQgdGVtcGxhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbmRlcigkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXIgdGhpcyB0ZW1wbGF0ZSBnaXZlbiB0aGUgcmVuZGVyaW5nIGNvbnRleHQuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICRjb250ZXh0IEFycmF5IG9yIG9iamVjdCByZW5kZXJpbmcgY29udGV4dCAoZGVmYXVsdDogYXJyYXkoKSkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBSZW5kZXJlZCB0ZW1wbGF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVyKCRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbmRlckludGVybmFsKAogICAgICAgICAgICAkdGhpcy0+cHJlcGFyZUNvbnRleHRTdGFjaygkY29udGV4dCkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogSW50ZXJuYWwgcmVuZGVyaW5nIG1ldGhvZCBpbXBsZW1lbnRlZCBieSBNdXN0YWNoZSBUZW1wbGF0ZSBjb25jcmV0ZSBzdWJjbGFzc2VzLgogICAgICoKICAgICAqIFRoaXMgaXMgd2hlcmUgdGhlIG1hZ2ljIGhhcHBlbnMgOikKICAgICAqCiAgICAgKiBOT1RFOiBUaGlzIG1ldGhvZCBpcyBub3QgcGFydCBvZiB0aGUgTXVzdGFjaGUucGhwIHB1YmxpYyBBUEkuCiAgICAgKgogICAgICogQHBhcmFtIE11c3RhY2hlX0NvbnRleHQgJGNvbnRleHQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRpbmRlbnQgIChkZWZhdWx0OiAnJykKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBSZW5kZXJlZCB0ZW1wbGF0ZQogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gcmVuZGVySW50ZXJuYWwoTXVzdGFjaGVfQ29udGV4dCAkY29udGV4dCwgJGluZGVudCA9ICcnKTsKCiAgICAvKioKICAgICAqIFRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBzaG91bGQgYmUgaXRlcmF0ZWQgb3ZlciAoZS5nLiBpbiBhIHNlY3Rpb24gY29udGV4dCkuCiAgICAgKgogICAgICogSW4gbW9zdCBsYW5ndWFnZXMgdGhlcmUgYXJlIHR3byBkaXN0aW5jdCBhcnJheSB0eXBlczogbGlzdCBhbmQgaGFzaCAob3Igd2hhdGV2ZXIgeW91IHdhbnQgdG8gY2FsbCB0aGVtKS4gTGlzdHMKICAgICAqIHNob3VsZCBiZSBpdGVyYXRlZCwgaGFzaGVzIHNob3VsZCBiZSB0cmVhdGVkIGFzIG9iamVjdHMuIE11c3RhY2hlIGZvbGxvd3MgdGhpcyBwYXJhZGlnbSBmb3IgUnVieSwgSmF2YXNjcmlwdCwKICAgICAqIEphdmEsIFB5dGhvbiwgZXRjLgogICAgICoKICAgICAqIFBIUCwgaG93ZXZlciwgdHJlYXRzIGxpc3RzIGFuZCBoYXNoZXMgYXMgb25lIHByaW1pdGl2ZSB0eXBlOiBhcnJheS4gU28gTXVzdGFjaGUucGhwIG5lZWRzIGEgd2F5IHRvIGRpc3Rpbmd1aXNoCiAgICAgKiBiZXR3ZWVuIGJldHdlZW4gYSBsaXN0IG9mIHRoaW5ncyAobnVtZXJpYywgbm9ybWFsaXplZCBhcnJheSkgYW5kIGEgc2V0IG9mIHZhcmlhYmxlcyB0byBiZSB1c2VkIGFzIHNlY3Rpb24gY29udGV4dAogICAgICogKGFzc29jaWF0aXZlIGFycmF5KS4gSW4gb3RoZXIgd29yZHMsIHRoaXMgd2lsbCBiZSBpdGVyYXRlZCBvdmVyOgogICAgICoKICAgICAqICAgICAkaXRlbXMgPSBhcnJheSgKICAgICAqICAgICAgICAgYXJyYXkoJ25hbWUnID0+ICdmb28nKSwKICAgICAqICAgICAgICAgYXJyYXkoJ25hbWUnID0+ICdiYXInKSwKICAgICAqICAgICAgICAgYXJyYXkoJ25hbWUnID0+ICdiYXonKSwKICAgICAqICAgICApOwogICAgICoKICAgICAqIC4uLiBidXQgdGhpcyB3aWxsIGJlIHVzZWQgYXMgYSBzZWN0aW9uIGNvbnRleHQgYmxvY2s6CiAgICAgKgogICAgICogICAgICRpdGVtcyA9IGFycmF5KAogICAgICogICAgICAgICAxICAgICAgICA9PiBhcnJheSgnbmFtZScgPT4gJ2ZvbycpLAogICAgICogICAgICAgICAnYmFuYW5hJyA9PiBhcnJheSgnbmFtZScgPT4gJ2JhcicpLAogICAgICogICAgICAgICA0MiAgICAgICA9PiBhcnJheSgnbmFtZScgPT4gJ2JheicpLAogICAgICogICAgICk7CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBUcnVlIGlmIHRoZSB2YWx1ZSBpcyAnaXRlcmFibGUnCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc0l0ZXJhYmxlKCR2YWx1ZSkKICAgIHsKICAgICAgICBzd2l0Y2ggKGdldHR5cGUoJHZhbHVlKSkgewogICAgICAgICAgICBjYXNlICdvYmplY3QnOgogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZSBpbnN0YW5jZW9mIFRyYXZlcnNhYmxlOwoKICAgICAgICAgICAgY2FzZSAnYXJyYXknOgogICAgICAgICAgICAgICAgJGkgPSAwOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlIGFzICRrID0+ICR2KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRrICE9PSAkaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBtZXRob2QgdG8gcHJlcGFyZSB0aGUgQ29udGV4dCBzdGFjay4KICAgICAqCiAgICAgKiBBZGRzIHRoZSBNdXN0YWNoZSBIZWxwZXJDb2xsZWN0aW9uIHRvIHRoZSBzdGFjaydzIHRvcCBjb250ZXh0IGZyYW1lIGlmIGhlbHBlcnMgYXJlIHByZXNlbnQuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICRjb250ZXh0IE9wdGlvbmFsIGZpcnN0IGNvbnRleHQgZnJhbWUgKGRlZmF1bHQ6IG51bGwpCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9Db250ZXh0CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmVwYXJlQ29udGV4dFN0YWNrKCRjb250ZXh0ID0gbnVsbCkKICAgIHsKICAgICAgICAkc3RhY2sgPSBuZXcgTXVzdGFjaGVfQ29udGV4dCgpOwoKICAgICAgICAkaGVscGVycyA9ICR0aGlzLT5tdXN0YWNoZS0+Z2V0SGVscGVycygpOwogICAgICAgIGlmICghJGhlbHBlcnMtPmlzRW1wdHkoKSkgewogICAgICAgICAgICAkc3RhY2stPnB1c2goJGhlbHBlcnMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkY29udGV4dCkpIHsKICAgICAgICAgICAgJHN0YWNrLT5wdXNoKCRjb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3RhY2s7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXNvbHZlIGEgY29udGV4dCB2YWx1ZS4KICAgICAqCiAgICAgKiBJbnZva2UgdGhlIHZhbHVlIGlmIGl0IGlzIGNhbGxhYmxlLCBvdGhlcndpc2UgcmV0dXJuIHRoZSB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlc29sdmVWYWx1ZSgkdmFsdWUsIE11c3RhY2hlX0NvbnRleHQgJGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKCgkdGhpcy0+c3RyaWN0Q2FsbGFibGVzID8gaXNfb2JqZWN0KCR2YWx1ZSkgOiAhaXNfc3RyaW5nKCR2YWx1ZSkpICYmIGlzX2NhbGxhYmxlKCR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tdXN0YWNoZQogICAgICAgICAgICAgICAgLT5sb2FkTGFtYmRhKChzdHJpbmcpIGNhbGxfdXNlcl9mdW5jKCR2YWx1ZSkpCiAgICAgICAgICAgICAgICAtPnJlbmRlckludGVybmFsKCRjb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgY2xhc3MgYXV0b2xvYWRlci4KICovCmNsYXNzIE11c3RhY2hlX0F1dG9sb2FkZXIKewogICAgcHJpdmF0ZSAkYmFzZURpcjsKCiAgICAvKioKICAgICAqIEFuIGFycmF5IHdoZXJlIHRoZSBrZXkgaXMgdGhlIGJhc2VEaXIgYW5kIHRoZSBrZXkgaXMgYW4gaW5zdGFuY2Ugb2YgdGhpcwogICAgICogY2xhc3MuCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkaW5zdGFuY2VzOwoKICAgIC8qKgogICAgICogQXV0b2xvYWRlciBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlRGlyIE11c3RhY2hlIGxpYnJhcnkgYmFzZSBkaXJlY3RvcnkgKGRlZmF1bHQ6IGRpcm5hbWUoX19GSUxFX18pLicvLi4nKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGJhc2VEaXIgPSBudWxsKQogICAgewogICAgICAgIGlmICgkYmFzZURpciA9PT0gbnVsbCkgewogICAgICAgICAgICAkYmFzZURpciA9IGRpcm5hbWUoX19GSUxFX18pIC4gJy8uLic7CiAgICAgICAgfQoKICAgICAgICAvLyByZWFscGF0aCBkb2Vzbid0IGFsd2F5cyB3b3JrLCBmb3IgZXhhbXBsZSwgd2l0aCBzdHJlYW0gVVJJcwogICAgICAgICRyZWFsRGlyID0gcmVhbHBhdGgoJGJhc2VEaXIpOwogICAgICAgIGlmIChpc19kaXIoJHJlYWxEaXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5iYXNlRGlyID0gJHJlYWxEaXI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmJhc2VEaXIgPSAkYmFzZURpcjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhIG5ldyBpbnN0YW5jZSBhcyBhbiBTUEwgYXV0b2xvYWRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlRGlyIE11c3RhY2hlIGxpYnJhcnkgYmFzZSBkaXJlY3RvcnkgKGRlZmF1bHQ6IGRpcm5hbWUoX19GSUxFX18pLicvLi4nKQogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfQXV0b2xvYWRlciBSZWdpc3RlcmVkIEF1dG9sb2FkZXIgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZWdpc3RlcigkYmFzZURpciA9IG51bGwpCiAgICB7CiAgICAgICAgJGtleSA9ICRiYXNlRGlyID8gJGJhc2VEaXIgOiAwOwoKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRpbnN0YW5jZXNbJGtleV0pKSB7CiAgICAgICAgICAgIHNlbGY6OiRpbnN0YW5jZXNbJGtleV0gPSBuZXcgc2VsZigkYmFzZURpcik7CiAgICAgICAgfQoKICAgICAgICAkbG9hZGVyID0gc2VsZjo6JGluc3RhbmNlc1ska2V5XTsKICAgICAgICBzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJGxvYWRlciwgJ2F1dG9sb2FkJykpOwoKICAgICAgICByZXR1cm4gJGxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEF1dG9sb2FkIE11c3RhY2hlIGNsYXNzZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2xhc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGF1dG9sb2FkKCRjbGFzcykKICAgIHsKICAgICAgICBpZiAoJGNsYXNzWzBdID09PSAnXFwnKSB7CiAgICAgICAgICAgICRjbGFzcyA9IHN1YnN0cigkY2xhc3MsIDEpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkY2xhc3MsICdNdXN0YWNoZScpICE9PSAwKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRmaWxlID0gc3ByaW50ZignJXMvJXMucGhwJywgJHRoaXMtPmJhc2VEaXIsIHN0cl9yZXBsYWNlKCdfJywgJy8nLCAkY2xhc3MpKTsKICAgICAgICBpZiAoaXNfZmlsZSgkZmlsZSkpIHsKICAgICAgICAgICAgcmVxdWlyZSAkZmlsZTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgdGVtcGxhdGUgRmlsZXN5c3RlbSBTb3VyY2UuCiAqCiAqIFRoaXMgdGVtcGxhdGUgU291cmNlIHVzZXMgc3RhdCgpIHRvIGdlbmVyYXRlIHRoZSBTb3VyY2Uga2V5LCBzbyB0aGF0IHVzaW5nCiAqIHByZS1jb21waWxlZCB0ZW1wbGF0ZXMgZG9lc24ndCByZXF1aXJlIGhpdHRpbmcgdGhlIGRpc2sgdG8gcmVhZCB0aGUgc291cmNlLgogKiBJdCBpcyBtb3JlIHN1aXRhYmxlIGZvciBwcm9kdWN0aW9uIHVzZSwgYW5kIGlzIHVzZWQgYnkgZGVmYXVsdCBpbiB0aGUKICogUHJvZHVjdGlvbkZpbGVzeXN0ZW1Mb2FkZXIuCiAqLwpjbGFzcyBNdXN0YWNoZV9Tb3VyY2VfRmlsZXN5c3RlbVNvdXJjZSBpbXBsZW1lbnRzIE11c3RhY2hlX1NvdXJjZQp7CiAgICBwcml2YXRlICRmaWxlTmFtZTsKICAgIHByaXZhdGUgJHN0YXRQcm9wczsKICAgIHByaXZhdGUgJHN0YXQ7CgogICAgLyoqCiAgICAgKiBGaWxlc3lzdGVtIFNvdXJjZSBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlTmFtZQogICAgICogQHBhcmFtIGFycmF5ICAkc3RhdFByb3BzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZmlsZU5hbWUsIGFycmF5ICRzdGF0UHJvcHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmZpbGVOYW1lID0gJGZpbGVOYW1lOwogICAgICAgICR0aGlzLT5zdGF0UHJvcHMgPSAkc3RhdFByb3BzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBTb3VyY2Uga2V5ICh1c2VkIHRvIGdlbmVyYXRlIHRoZSBjb21waWxlZCBjbGFzcyBuYW1lKS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uIHdoZW4gYSBzb3VyY2UgZmlsZSBjYW5ub3QgYmUgcmVhZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXkoKQogICAgewogICAgICAgICRjaHVua3MgPSBhcnJheSgKICAgICAgICAgICAgJ2ZpbGVOYW1lJyA9PiAkdGhpcy0+ZmlsZU5hbWUsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+c3RhdFByb3BzKSkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5zdGF0KSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnN0YXQgPSBAc3RhdCgkdGhpcy0+ZmlsZU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPnN0YXQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHJlYWQgc291cmNlIGZpbGUgIiVzIi4nLCAkdGhpcy0+ZmlsZU5hbWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnN0YXRQcm9wcyBhcyAkcHJvcCkgewogICAgICAgICAgICAgICAgJGNodW5rc1skcHJvcF0gPSAkdGhpcy0+c3RhdFskcHJvcF07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBqc29uX2VuY29kZSgkY2h1bmtzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgdGVtcGxhdGUgU291cmNlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+ZmlsZU5hbWUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEEgTXVzdGFjaGUgRXhjZXB0aW9uIGludGVyZmFjZS4KICovCmludGVyZmFjZSBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVG9rZW5pemVyIGNsYXNzLgogKgogKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciB0dXJuaW5nIHJhdyB0ZW1wbGF0ZSBzb3VyY2UgaW50byBhIHNldCBvZiBNdXN0YWNoZSB0b2tlbnMuCiAqLwpjbGFzcyBNdXN0YWNoZV9Ub2tlbml6ZXIKewogICAgLy8gRmluaXRlIHN0YXRlIG1hY2hpbmUgc3RhdGVzCiAgICBjb25zdCBJTl9URVhUICAgICA9IDA7CiAgICBjb25zdCBJTl9UQUdfVFlQRSA9IDE7CiAgICBjb25zdCBJTl9UQUcgICAgICA9IDI7CgogICAgLy8gVG9rZW4gdHlwZXMKICAgIGNvbnN0IFRfU0VDVElPTiAgICAgID0gJyMnOwogICAgY29uc3QgVF9JTlZFUlRFRCAgICAgPSAnXic7CiAgICBjb25zdCBUX0VORF9TRUNUSU9OICA9ICcvJzsKICAgIGNvbnN0IFRfQ09NTUVOVCAgICAgID0gJyEnOwogICAgY29uc3QgVF9QQVJUSUFMICAgICAgPSAnPic7CiAgICBjb25zdCBUX1BBUkVOVCAgICAgICA9ICc8JzsKICAgIGNvbnN0IFRfREVMSU1fQ0hBTkdFID0gJz0nOwogICAgY29uc3QgVF9FU0NBUEVEICAgICAgPSAnX3YnOwogICAgY29uc3QgVF9VTkVTQ0FQRUQgICAgPSAneyc7CiAgICBjb25zdCBUX1VORVNDQVBFRF8yICA9ICcmJzsKICAgIGNvbnN0IFRfVEVYVCAgICAgICAgID0gJ190JzsKICAgIGNvbnN0IFRfUFJBR01BICAgICAgID0gJyUnOwogICAgY29uc3QgVF9CTE9DS19WQVIgICAgPSAnJCc7CiAgICBjb25zdCBUX0JMT0NLX0FSRyAgICA9ICckYXJnJzsKCiAgICAvLyBWYWxpZCB0b2tlbiB0eXBlcwogICAgcHJpdmF0ZSBzdGF0aWMgJHRhZ1R5cGVzID0gYXJyYXkoCiAgICAgICAgc2VsZjo6VF9TRUNUSU9OICAgICAgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX0lOVkVSVEVEICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfRU5EX1NFQ1RJT04gID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9DT01NRU5UICAgICAgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX1BBUlRJQUwgICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfUEFSRU5UICAgICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9ERUxJTV9DSEFOR0UgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX0VTQ0FQRUQgICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfVU5FU0NBUEVEICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9VTkVTQ0FQRURfMiAgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX1BSQUdNQSAgICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfQkxPQ0tfVkFSICAgID0+IHRydWUsCiAgICApOwoKICAgIC8vIFRva2VuIHByb3BlcnRpZXMKICAgIGNvbnN0IFRZUEUgICAgPSAndHlwZSc7CiAgICBjb25zdCBOQU1FICAgID0gJ25hbWUnOwogICAgY29uc3QgT1RBRyAgICA9ICdvdGFnJzsKICAgIGNvbnN0IENUQUcgICAgPSAnY3RhZyc7CiAgICBjb25zdCBMSU5FICAgID0gJ2xpbmUnOwogICAgY29uc3QgSU5ERVggICA9ICdpbmRleCc7CiAgICBjb25zdCBFTkQgICAgID0gJ2VuZCc7CiAgICBjb25zdCBJTkRFTlQgID0gJ2luZGVudCc7CiAgICBjb25zdCBOT0RFUyAgID0gJ25vZGVzJzsKICAgIGNvbnN0IFZBTFVFICAgPSAndmFsdWUnOwogICAgY29uc3QgRklMVEVSUyA9ICdmaWx0ZXJzJzsKCiAgICBwcml2YXRlICRzdGF0ZTsKICAgIHByaXZhdGUgJHRhZ1R5cGU7CiAgICBwcml2YXRlICRidWZmZXI7CiAgICBwcml2YXRlICR0b2tlbnM7CiAgICBwcml2YXRlICRzZWVuVGFnOwogICAgcHJpdmF0ZSAkbGluZTsKCiAgICBwcml2YXRlICRvdGFnOwogICAgcHJpdmF0ZSAkb3RhZ0NoYXI7CiAgICBwcml2YXRlICRvdGFnTGVuOwoKICAgIHByaXZhdGUgJGN0YWc7CiAgICBwcml2YXRlICRjdGFnQ2hhcjsKICAgIHByaXZhdGUgJGN0YWdMZW47CgogICAgLyoqCiAgICAgKiBTY2FuIGFuZCB0b2tlbml6ZSB0ZW1wbGF0ZSBzb3VyY2UuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uIHdoZW4gbWlzbWF0Y2hlZCBzZWN0aW9uIHRhZ3MgYXJlIGVuY291bnRlcmVkCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gd2hlbiAkZGVsaW1pdGVycyBzdHJpbmcgaXMgaW52YWxpZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQgICAgICAgTXVzdGFjaGUgdGVtcGxhdGUgc291cmNlIHRvIHRva2VuaXplCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkZWxpbWl0ZXJzIE9wdGlvbmFsbHksIHBhc3MgaW5pdGlhbCBvcGVuaW5nIGFuZCBjbG9zaW5nIGRlbGltaXRlcnMgKGRlZmF1bHQ6IGVtcHR5IHN0cmluZykKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFNldCBvZiBNdXN0YWNoZSB0b2tlbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNjYW4oJHRleHQsICRkZWxpbWl0ZXJzID0gJycpCiAgICB7CiAgICAgICAgLy8gU2V0dGluZyBtYnN0cmluZy5mdW5jX292ZXJsb2FkIG1ha2VzIHRoaW5ncyAqcmVhbGx5KiBzbG93LgogICAgICAgIC8vIExldCdzIGRvIGV2ZXJ5b25lIGEgZmF2b3IgYW5kIHNjYW4gdGhpcyBzdHJpbmcgYXMgQVNDSUkgaW5zdGVhZC4KICAgICAgICAvLwogICAgICAgIC8vIFRoZSBJTkkgZGlyZWN0aXZlIHdhcyByZW1vdmVkIGluIFBIUCA4LjAgc28gd2UgZG9uJ3QgbmVlZCB0byBjaGVjayB0aGVyZSAoYW5kIGNhbiBkcm9wIGl0CiAgICAgICAgLy8gd2hlbiB3ZSByZW1vdmUgc3VwcG9ydCBmb3Igb2xkZXIgdmVyc2lvbnMgb2YgUEhQKS4KICAgICAgICAvLwogICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVTdGFydAogICAgICAgICRlbmNvZGluZyA9IG51bGw7CiAgICAgICAgaWYgKHZlcnNpb25fY29tcGFyZShQSFBfVkVSU0lPTiwgJzguMC4wJywgJzwnKSkgewogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdtYl9pbnRlcm5hbF9lbmNvZGluZycpICYmIGluaV9nZXQoJ21ic3RyaW5nLmZ1bmNfb3ZlcmxvYWQnKSAmIDIpIHsKICAgICAgICAgICAgICAgICRlbmNvZGluZyA9IG1iX2ludGVybmFsX2VuY29kaW5nKCk7CiAgICAgICAgICAgICAgICBtYl9pbnRlcm5hbF9lbmNvZGluZygnQVNDSUknKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCgogICAgICAgICR0aGlzLT5yZXNldCgpOwoKICAgICAgICBpZiAoaXNfc3RyaW5nKCRkZWxpbWl0ZXJzKSAmJiAkZGVsaW1pdGVycyA9IHRyaW0oJGRlbGltaXRlcnMpKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREZWxpbWl0ZXJzKCRkZWxpbWl0ZXJzKTsKICAgICAgICB9CgogICAgICAgICRsZW4gPSBzdHJsZW4oJHRleHQpOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRsZW47ICRpKyspIHsKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+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+Y3RhZ0xlbiAtIDE7CiAgICB9Cn0KPD9waHAKLyoqCiAqIENvb2tpZSBob2xkZXIgb2JqZWN0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIENvb2tpZXMKICovCgovKioKICogQ29va2llIGhvbGRlciBvYmplY3QKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQ29va2llcwogKi8KY2xhc3MgUmVxdWVzdHNfQ29va2llX0phciBpbXBsZW1lbnRzIEFycmF5QWNjZXNzLCBJdGVyYXRvckFnZ3JlZ2F0ZSB7CgkvKioKCSAqIEFjdHVhbCBpdGVtIGRhdGEKCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkY29va2llcyA9IGFycmF5KCk7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgamFyCgkgKgoJICogQHBhcmFtIGFycmF5ICRjb29raWVzIEV4aXN0aW5nIGNvb2tpZSB2YWx1ZXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb29raWVzID0gYXJyYXkoKSkgewoJCSR0aGlzLT5jb29raWVzID0gJGNvb2tpZXM7Cgl9CgoJLyoqCgkgKiBOb3JtYWxpc2UgY29va2llIGRhdGEgaW50byBhIFJlcXVlc3RzX0Nvb2tpZQoJICoKCSAqIEBwYXJhbSBzdHJpbmd8UmVxdWVzdHNfQ29va2llICRjb29raWUKCSAqIEByZXR1cm4gUmVxdWVzdHNfQ29va2llCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemVfY29va2llKCRjb29raWUsICRrZXkgPSBudWxsKSB7CgkJaWYgKCRjb29raWUgaW5zdGFuY2VvZiBSZXF1ZXN0c19Db29raWUpIHsKCQkJcmV0dXJuICRjb29raWU7CgkJfQoKCQlyZXR1cm4gUmVxdWVzdHNfQ29va2llOjpwYXJzZSgkY29va2llLCAka2V5KTsKCX0KCgkvKioKCSAqIE5vcm1hbGlzZSBjb29raWUgZGF0YSBpbnRvIGEgUmVxdWVzdHNfQ29va2llCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQGRlcHJlY2F0ZWQgVXNlIHtAc2VlIFJlcXVlc3RzX0Nvb2tpZV9KYXI6Om5vcm1hbGl6ZV9jb29raWV9CgkgKiBAcmV0dXJuIFJlcXVlc3RzX0Nvb2tpZQoJICovCglwdWJsaWMgZnVuY3Rpb24gbm9ybWFsaXplQ29va2llKCRjb29raWUsICRrZXkgPSBudWxsKSB7CgkJcmV0dXJuICR0aGlzLT5ub3JtYWxpemVfY29va2llKCRjb29raWUsICRrZXkpOwoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIGdpdmVuIGl0ZW0gZXhpc3RzCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0ga2V5CgkgKiBAcmV0dXJuIGJvb2xlYW4gRG9lcyB0aGUgaXRlbSBleGlzdD8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldEV4aXN0cygka2V5KSB7CgkJcmV0dXJuIGlzc2V0KCR0aGlzLT5jb29raWVzWyRrZXldKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBpdGVtCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0ga2V5CgkgKiBAcmV0dXJuIHN0cmluZ3xudWxsIEl0ZW0gdmFsdWUgKG51bGwgaWYgb2Zmc2V0RXhpc3RzIGlzIGZhbHNlKQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0R2V0KCRrZXkpIHsKCQlpZiAoIWlzc2V0KCR0aGlzLT5jb29raWVzWyRrZXldKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiAkdGhpcy0+Y29va2llc1ska2V5XTsKCX0KCgkvKioKCSAqIFNldCB0aGUgZ2l2ZW4gaXRlbQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGF0dGVtcHRpbmcgdG8gdXNlIGRpY3Rpb25hcnkgYXMgbGlzdCAoYGludmFsaWRzZXRgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBJdGVtIG5hbWUKCSAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIEl0ZW0gdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldFNldCgka2V5LCAkdmFsdWUpIHsKCQlpZiAoJGtleSA9PT0gbnVsbCkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdPYmplY3QgaXMgYSBkaWN0aW9uYXJ5LCBub3QgYSBsaXN0JywgJ2ludmFsaWRzZXQnKTsKCQl9CgoJCSR0aGlzLT5jb29raWVzWyRrZXldID0gJHZhbHVlOwoJfQoKCS8qKgoJICogVW5zZXQgdGhlIGdpdmVuIGhlYWRlcgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0VW5zZXQoJGtleSkgewoJCXVuc2V0KCR0aGlzLT5jb29raWVzWyRrZXldKTsKCX0KCgkvKioKCSAqIEdldCBhbiBpdGVyYXRvciBmb3IgdGhlIGRhdGEKCSAqCgkgKiBAcmV0dXJuIEFycmF5SXRlcmF0b3IKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCkgewoJCXJldHVybiBuZXcgQXJyYXlJdGVyYXRvcigkdGhpcy0+Y29va2llcyk7Cgl9CgoJLyoqCgkgKiBSZWdpc3RlciB0aGUgY29va2llIGhhbmRsZXIgd2l0aCB0aGUgcmVxdWVzdCdzIGhvb2tpbmcgc3lzdGVtCgkgKgoJICogQHBhcmFtIFJlcXVlc3RzX0hvb2tlciAkaG9va3MgSG9va2luZyBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tlciAkaG9va3MpIHsKCQkkaG9va3MtPnJlZ2lzdGVyKCdyZXF1ZXN0cy5iZWZvcmVfcmVxdWVzdCcsIGFycmF5KCR0aGlzLCAnYmVmb3JlX3JlcXVlc3QnKSk7CgkJJGhvb2tzLT5yZWdpc3RlcigncmVxdWVzdHMuYmVmb3JlX3JlZGlyZWN0X2NoZWNrJywgYXJyYXkoJHRoaXMsICdiZWZvcmVfcmVkaXJlY3RfY2hlY2snKSk7Cgl9CgoJLyoqCgkgKiBBZGQgQ29va2llIGhlYWRlciB0byBhIHJlcXVlc3QgaWYgd2UgaGF2ZSBhbnkKCSAqCgkgKiBBcyBwZXIgUkZDIDYyNjUsIGNvb2tpZXMgYXJlIHNlcGFyYXRlZCBieSAnOyAnCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsCgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMKCSAqIEBwYXJhbSBhcnJheSAkZGF0YQoJICogQHBhcmFtIHN0cmluZyAkdHlwZQoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBiZWZvcmVfcmVxdWVzdCgkdXJsLCAmJGhlYWRlcnMsICYkZGF0YSwgJiR0eXBlLCAmJG9wdGlvbnMpIHsKCQlpZiAoISR1cmwgaW5zdGFuY2VvZiBSZXF1ZXN0c19JUkkpIHsKCQkJJHVybCA9IG5ldyBSZXF1ZXN0c19JUkkoJHVybCk7CgkJfQoKCQlpZiAoIWVtcHR5KCR0aGlzLT5jb29raWVzKSkgewoJCQkkY29va2llcyA9IGFycmF5KCk7CgkJCWZvcmVhY2ggKCR0aGlzLT5jb29raWVzIGFzICRrZXkgPT4gJGNvb2tpZSkgewoJCQkJJGNvb2tpZSA9ICR0aGlzLT5ub3JtYWxpemVfY29va2llKCRjb29raWUsICRrZXkpOwoKCQkJCS8vIFNraXAgZXhwaXJlZCBjb29raWVzCgkJCQlpZiAoJGNvb2tpZS0+aXNfZXhwaXJlZCgpKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaWYgKCRjb29raWUtPmRvbWFpbl9tYXRjaGVzKCR1cmwtPmhvc3QpKSB7CgkJCQkJJGNvb2tpZXNbXSA9ICRjb29raWUtPmZvcm1hdF9mb3JfaGVhZGVyKCk7CgkJCQl9CgkJCX0KCgkJCSRoZWFkZXJzWydDb29raWUnXSA9IGltcGxvZGUoJzsgJywgJGNvb2tpZXMpOwoJCX0KCX0KCgkvKioKCSAqIFBhcnNlIGFsbCBjb29raWVzIGZyb20gYSByZXNwb25zZSBhbmQgYXR0YWNoIHRoZW0gdG8gdGhlIHJlc3BvbnNlCgkgKgoJICogQHZhciBSZXF1ZXN0c19SZXNwb25zZSAkcmVzcG9uc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGJlZm9yZV9yZWRpcmVjdF9jaGVjayhSZXF1ZXN0c19SZXNwb25zZSAkcmV0dXJuKSB7CgkJJHVybCA9ICRyZXR1cm4tPnVybDsKCQlpZiAoISR1cmwgaW5zdGFuY2VvZiBSZXF1ZXN0c19JUkkpIHsKCQkJJHVybCA9IG5ldyBSZXF1ZXN0c19JUkkoJHVybCk7CgkJfQoKCQkkY29va2llcyAgICAgICAgID0gUmVxdWVzdHNfQ29va2llOjpwYXJzZV9mcm9tX2hlYWRlcnMoJHJldHVybi0+aGVhZGVycywgJHVybCk7CgkJJHRoaXMtPmNvb2tpZXMgICA9IGFycmF5X21lcmdlKCR0aGlzLT5jb29raWVzLCAkY29va2llcyk7CgkJJHJldHVybi0+Y29va2llcyA9ICR0aGlzOwoJfQp9Cjw/cGhwCi8qKgogKiBIVFRQIHJlc3BvbnNlIGNsYXNzCiAqCiAqIENvbnRhaW5zIGEgcmVzcG9uc2UgZnJvbSBSZXF1ZXN0czo6cmVxdWVzdCgpCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEhUVFAgcmVzcG9uc2UgY2xhc3MKICoKICogQ29udGFpbnMgYSByZXNwb25zZSBmcm9tIFJlcXVlc3RzOjpyZXF1ZXN0KCkKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX1Jlc3BvbnNlIHsKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5oZWFkZXJzID0gbmV3IFJlcXVlc3RzX1Jlc3BvbnNlX0hlYWRlcnMoKTsKCQkkdGhpcy0+Y29va2llcyA9IG5ldyBSZXF1ZXN0c19Db29raWVfSmFyKCk7Cgl9CgoJLyoqCgkgKiBSZXNwb25zZSBib2R5CgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRib2R5ID0gJyc7CgoJLyoqCgkgKiBSYXcgSFRUUCBkYXRhIGZyb20gdGhlIHRyYW5zcG9ydAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXB1YmxpYyAkcmF3ID0gJyc7CgoJLyoqCgkgKiBIZWFkZXJzLCBhcyBhbiBhc3NvY2lhdGl2ZSBhcnJheQoJICoKCSAqIEB2YXIgUmVxdWVzdHNfUmVzcG9uc2VfSGVhZGVycyBBcnJheS1saWtlIG9iamVjdCByZXByZXNlbnRpbmcgaGVhZGVycwoJICovCglwdWJsaWMgJGhlYWRlcnMgPSBhcnJheSgpOwoKCS8qKgoJICogU3RhdHVzIGNvZGUsIGZhbHNlIGlmIG5vbi1ibG9ja2luZwoJICoKCSAqIEB2YXIgaW50ZWdlcnxib29sZWFuCgkgKi8KCXB1YmxpYyAkc3RhdHVzX2NvZGUgPSBmYWxzZTsKCgkvKioKCSAqIFByb3RvY29sIHZlcnNpb24sIGZhbHNlIGlmIG5vbi1ibG9ja2luZwoJICoKCSAqIEB2YXIgZmxvYXR8Ym9vbGVhbgoJICovCglwdWJsaWMgJHByb3RvY29sX3ZlcnNpb24gPSBmYWxzZTsKCgkvKioKCSAqIFdoZXRoZXIgdGhlIHJlcXVlc3Qgc3VjY2VlZGVkIG9yIG5vdAoJICoKCSAqIEB2YXIgYm9vbGVhbgoJICovCglwdWJsaWMgJHN1Y2Nlc3MgPSBmYWxzZTsKCgkvKioKCSAqIE51bWJlciBvZiByZWRpcmVjdHMgdGhlIHJlcXVlc3QgdXNlZAoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwdWJsaWMgJHJlZGlyZWN0cyA9IDA7CgoJLyoqCgkgKiBVUkwgcmVxdWVzdGVkCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICR1cmwgPSAnJzsKCgkvKioKCSAqIFByZXZpb3VzIHJlcXVlc3RzIChmcm9tIHJlZGlyZWN0cykKCSAqCgkgKiBAdmFyIGFycmF5IEFycmF5IG9mIFJlcXVlc3RzX1Jlc3BvbnNlIG9iamVjdHMKCSAqLwoJcHVibGljICRoaXN0b3J5ID0gYXJyYXkoKTsKCgkvKioKCSAqIENvb2tpZXMgZnJvbSB0aGUgcmVxdWVzdAoJICoKCSAqIEB2YXIgUmVxdWVzdHNfQ29va2llX0phciBBcnJheS1saWtlIG9iamVjdCByZXByZXNlbnRpbmcgYSBjb29raWUgamFyCgkgKi8KCXB1YmxpYyAkY29va2llcyA9IGFycmF5KCk7CgoJLyoqCgkgKiBJcyB0aGUgcmVzcG9uc2UgYSByZWRpcmVjdD8KCSAqCgkgKiBAcmV0dXJuIGJvb2xlYW4gVHJ1ZSBpZiByZWRpcmVjdCAoM3h4IHN0YXR1cyksIGZhbHNlIGlmIG5vdC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX3JlZGlyZWN0KCkgewoJCSRjb2RlID0gJHRoaXMtPnN0YXR1c19jb2RlOwoJCXJldHVybiBpbl9hcnJheSgkY29kZSwgYXJyYXkoMzAwLCAzMDEsIDMwMiwgMzAzLCAzMDcpLCB0cnVlKSB8fCAkY29kZSA+IDMwNyAmJiAkY29kZSA8IDQwMDsKCX0KCgkvKioKCSAqIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIHJlcXVlc3Qgd2FzIG5vdCBzdWNjZXNzZnVsCgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gSWYgYCRhbGxvd19yZWRpcmVjdHNgIGlzIGZhbHNlLCBhbmQgY29kZSBpcyAzeHggKGByZXNwb25zZS5ub19yZWRpcmVjdHNgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCBPbiBub24tc3VjY2Vzc2Z1bCBzdGF0dXMgY29kZS4gRXhjZXB0aW9uIGNsYXNzIGNvcnJlc3BvbmRzIHRvIGNvZGUgKGUuZy4ge0BzZWUgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA0fSkKCSAqIEBwYXJhbSBib29sZWFuICRhbGxvd19yZWRpcmVjdHMgU2V0IHRvIGZhbHNlIHRvIHRocm93IG9uIGEgM3h4IGFzIHdlbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRocm93X2Zvcl9zdGF0dXMoJGFsbG93X3JlZGlyZWN0cyA9IHRydWUpIHsKCQlpZiAoJHRoaXMtPmlzX3JlZGlyZWN0KCkpIHsKCQkJaWYgKCEkYWxsb3dfcmVkaXJlY3RzKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdSZWRpcmVjdGlvbiBub3QgYWxsb3dlZCcsICdyZXNwb25zZS5ub19yZWRpcmVjdHMnLCAkdGhpcyk7CgkJCX0KCQl9CgkJZWxzZWlmICghJHRoaXMtPnN1Y2Nlc3MpIHsKCQkJJGV4Y2VwdGlvbiA9IFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQOjpnZXRfY2xhc3MoJHRoaXMtPnN0YXR1c19jb2RlKTsKCQkJdGhyb3cgbmV3ICRleGNlcHRpb24obnVsbCwgJHRoaXMpOwoJCX0KCX0KfQo8P3BocAovKioKICogSGFuZGxlcyBhZGRpbmcgYW5kIGRpc3BhdGNoaW5nIGV2ZW50cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogSGFuZGxlcyBhZGRpbmcgYW5kIGRpc3BhdGNoaW5nIGV2ZW50cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCmNsYXNzIFJlcXVlc3RzX0hvb2tzIGltcGxlbWVudHMgUmVxdWVzdHNfSG9va2VyIHsKCS8qKgoJICogUmVnaXN0ZXJlZCBjYWxsYmFja3MgZm9yIGVhY2ggaG9vawoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRob29rcyA9IGFycmF5KCk7CgoJLyoqCgkgKiBDb25zdHJ1Y3RvcgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJLy8gcGFzcwoJfQoKCS8qKgoJICogUmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgYSBob29rCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaG9vayBIb29rIG5hbWUKCSAqIEBwYXJhbSBjYWxsYmFjayAkY2FsbGJhY2sgRnVuY3Rpb24vbWV0aG9kIHRvIGNhbGwgb24gZXZlbnQKCSAqIEBwYXJhbSBpbnQgJHByaW9yaXR5IFByaW9yaXR5IG51bWJlci4gPDAgaXMgZXhlY3V0ZWQgZWFybGllciwgPjAgaXMgZXhlY3V0ZWQgbGF0ZXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRob29rLCAkY2FsbGJhY2ssICRwcmlvcml0eSA9IDApIHsKCQlpZiAoIWlzc2V0KCR0aGlzLT5ob29rc1skaG9va10pKSB7CgkJCSR0aGlzLT5ob29rc1skaG9va10gPSBhcnJheSgpOwoJCX0KCQlpZiAoIWlzc2V0KCR0aGlzLT5ob29rc1skaG9va11bJHByaW9yaXR5XSkpIHsKCQkJJHRoaXMtPmhvb2tzWyRob29rXVskcHJpb3JpdHldID0gYXJyYXkoKTsKCQl9CgoJCSR0aGlzLT5ob29rc1skaG9va11bJHByaW9yaXR5XVtdID0gJGNhbGxiYWNrOwoJfQoKCS8qKgoJICogRGlzcGF0Y2ggYSBtZXNzYWdlCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaG9vayBIb29rIG5hbWUKCSAqIEBwYXJhbSBhcnJheSAkcGFyYW1ldGVycyBQYXJhbWV0ZXJzIHRvIHBhc3MgdG8gY2FsbGJhY2tzCgkgKiBAcmV0dXJuIGJvb2xlYW4gU3VjY2Vzc2Z1bG5lc3MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoKCRob29rLCAkcGFyYW1ldGVycyA9IGFycmF5KCkpIHsKCQlpZiAoZW1wdHkoJHRoaXMtPmhvb2tzWyRob29rXSkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJZm9yZWFjaCAoJHRoaXMtPmhvb2tzWyRob29rXSBhcyAkcHJpb3JpdHkgPT4gJGhvb2tlZCkgewoJCQlmb3JlYWNoICgkaG9va2VkIGFzICRjYWxsYmFjaykgewoJCQkJY2FsbF91c2VyX2Z1bmNfYXJyYXkoJGNhbGxiYWNrLCAkcGFyYW1ldGVycyk7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQp9Cjw/cGhwCi8qKgogKiBTU0wgdXRpbGl0aWVzIGZvciBSZXF1ZXN0cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogU1NMIHV0aWxpdGllcyBmb3IgUmVxdWVzdHMKICoKICogQ29sbGVjdGlvbiBvZiB1dGlsaXRpZXMgZm9yIHdvcmtpbmcgd2l0aCBhbmQgdmVyaWZ5aW5nIFNTTCBjZXJ0aWZpY2F0ZXMuCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KY2xhc3MgUmVxdWVzdHNfU1NMIHsKCS8qKgoJICogVmVyaWZ5IHRoZSBjZXJ0aWZpY2F0ZSBhZ2FpbnN0IGNvbW1vbiBuYW1lIGFuZCBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWVzCgkgKgoJICogVW5mb3J0dW5hdGVseSwgUEhQIGRvZXNuJ3QgY2hlY2sgdGhlIGNlcnRpZmljYXRlIGFnYWluc3QgdGhlIGFsdGVybmF0aXZlCgkgKiBuYW1lcywgbGVhZGluZyB0aGluZ3MgbGlrZSAnaHR0cHM6Ly93d3cuZ2l0aHViLmNvbS8nIHRvIGJlIGludmFsaWQuCgkgKgoJICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgxOCNzZWN0aW9uLTMuMSBSRkMyODE4LCBTZWN0aW9uIDMuMQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIG5vdCBvYnRhaW5pbmcgYSBtYXRjaCBmb3IgdGhlIGhvc3QgKGBmc29ja29wZW4uc3NsLm5vX21hdGNoYCkKCSAqIEBwYXJhbSBzdHJpbmcgJGhvc3QgSG9zdCBuYW1lIHRvIHZlcmlmeSBhZ2FpbnN0CgkgKiBAcGFyYW0gYXJyYXkgJGNlcnQgQ2VydGlmaWNhdGUgZGF0YSBmcm9tIG9wZW5zc2xfeDUwOV9wYXJzZSgpCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB2ZXJpZnlfY2VydGlmaWNhdGUoJGhvc3QsICRjZXJ0KSB7CgkJJGhhc19kbnNfYWx0ID0gZmFsc2U7CgoJCS8vIENoZWNrIHRoZSBzdWJqZWN0QWx0TmFtZQoJCWlmICghZW1wdHkoJGNlcnRbJ2V4dGVuc2lvbnMnXSkgJiYgIWVtcHR5KCRjZXJ0WydleHRlbnNpb25zJ11bJ3N1YmplY3RBbHROYW1lJ10pKSB7CgkJCSRhbHRuYW1lcyA9IGV4cGxvZGUoJywnLCAkY2VydFsnZXh0ZW5zaW9ucyddWydzdWJqZWN0QWx0TmFtZSddKTsKCQkJZm9yZWFjaCAoJGFsdG5hbWVzIGFzICRhbHRuYW1lKSB7CgkJCQkkYWx0bmFtZSA9IHRyaW0oJGFsdG5hbWUpOwoJCQkJaWYgKHN0cnBvcygkYWx0bmFtZSwgJ0ROUzonKSAhPT0gMCkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCSRoYXNfZG5zX2FsdCA9IHRydWU7CgoJCQkJLy8gU3RyaXAgdGhlICdETlM6JyBwcmVmaXggYW5kIHRyaW0gd2hpdGVzcGFjZQoJCQkJJGFsdG5hbWUgPSB0cmltKHN1YnN0cigkYWx0bmFtZSwgNCkpOwoKCQkJCS8vIENoZWNrIGZvciBhIG1hdGNoCgkJCQlpZiAoc2VsZjo6bWF0Y2hfZG9tYWluKCRob3N0LCAkYWx0bmFtZSkgPT09IHRydWUpIHsKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0KCQkJfQoJCX0KCgkJLy8gRmFsbCBiYWNrIHRvIGNoZWNraW5nIHRoZSBjb21tb24gbmFtZSBpZiB3ZSBkaWRuJ3QgZ2V0IGFueSBkTlNOYW1lCgkJLy8gYWx0IG5hbWVzLCBhcyBwZXIgUkZDMjgxOAoJCWlmICghJGhhc19kbnNfYWx0ICYmICFlbXB0eSgkY2VydFsnc3ViamVjdCddWydDTiddKSkgewoJCQkvLyBDaGVjayBmb3IgYSBtYXRjaAoJCQlpZiAoc2VsZjo6bWF0Y2hfZG9tYWluKCRob3N0LCAkY2VydFsnc3ViamVjdCddWydDTiddKSA9PT0gdHJ1ZSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFZlcmlmeSB0aGF0IGEgcmVmZXJlbmNlIG5hbWUgaXMgdmFsaWQKCSAqCgkgKiBWZXJpZmllcyBhIGROU05hbWUgZm9yIEhUVFBTIHVzYWdlLCAoYWxtb3N0KSBhcyBwZXIgRmlyZWZveCdzIHJ1bGVzOgoJICogLSBXaWxkY2FyZHMgY2FuIG9ubHkgb2NjdXIgaW4gYSBuYW1lIHdpdGggbW9yZSB0aGFuIDMgY29tcG9uZW50cwoJICogLSBXaWxkY2FyZHMgY2FuIG9ubHkgb2NjdXIgYXMgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBmaXJzdAoJICogICBjb21wb25lbnQKCSAqIC0gV2lsZGNhcmRzIG1heSBiZSBwcmVjZWRlZCBieSBhZGRpdGlvbmFsIGNoYXJhY3RlcnMKCSAqCgkgKiBXZSBtb2RpZnkgdGhlc2UgcnVsZXMgdG8gYmUgYSBiaXQgc3RyaWN0ZXIgYW5kIG9ubHkgYWxsb3cgdGhlIHdpbGRjYXJkCgkgKiBjaGFyYWN0ZXIgdG8gYmUgdGhlIGZ1bGwgZmlyc3QgY29tcG9uZW50OyB0aGF0IGlzLCB3aXRoIHRoZSBleGNsdXNpb24gb2YKCSAqIHRoZSB0aGlyZCBydWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZSBSZWZlcmVuY2UgZE5TTmFtZQoJICogQHJldHVybiBib29sZWFuIElzIHRoZSBuYW1lIHZhbGlkPwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZlcmlmeV9yZWZlcmVuY2VfbmFtZSgkcmVmZXJlbmNlKSB7CgkJJHBhcnRzID0gZXhwbG9kZSgnLicsICRyZWZlcmVuY2UpOwoKCQkvLyBDaGVjayB0aGUgZmlyc3QgcGFydCBvZiB0aGUgbmFtZQoJCSRmaXJzdCA9IGFycmF5X3NoaWZ0KCRwYXJ0cyk7CgoJCWlmIChzdHJwb3MoJGZpcnN0LCAnKicpICE9PSBmYWxzZSkgewoJCQkvLyBDaGVjayB0aGF0IHRoZSB3aWxkY2FyZCBpcyB0aGUgZnVsbCBwYXJ0CgkJCWlmICgkZmlyc3QgIT09ICcqJykgewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQkvLyBDaGVjayB0aGF0IHdlIGhhdmUgYXQgbGVhc3QgMyBjb21wb25lbnRzIChpbmNsdWRpbmcgZmlyc3QpCgkJCWlmIChjb3VudCgkcGFydHMpIDwgMikgewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoKCQkvLyBDaGVjayB0aGUgcmVtYWluaW5nIHBhcnRzCgkJZm9yZWFjaCAoJHBhcnRzIGFzICRwYXJ0KSB7CgkJCWlmIChzdHJwb3MoJHBhcnQsICcqJykgIT09IGZhbHNlKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCS8vIE5vdGhpbmcgZm91bmQsIHZlcmlmaWVkIQoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogTWF0Y2ggYSBob3N0bmFtZSBhZ2FpbnN0IGEgZE5TTmFtZSByZWZlcmVuY2UKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRob3N0IFJlcXVlc3RlZCBob3N0CgkgKiBAcGFyYW0gc3RyaW5nICRyZWZlcmVuY2UgZE5TTmFtZSB0byBtYXRjaCBhZ2FpbnN0CgkgKiBAcmV0dXJuIGJvb2xlYW4gRG9lcyB0aGUgZG9tYWluIG1hdGNoPwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1hdGNoX2RvbWFpbigkaG9zdCwgJHJlZmVyZW5jZSkgewoJCS8vIENoZWNrIGlmIHRoZSByZWZlcmVuY2UgaXMgYmxvY2tsaXN0ZWQgZmlyc3QKCQlpZiAoc2VsZjo6dmVyaWZ5X3JlZmVyZW5jZV9uYW1lKCRyZWZlcmVuY2UpICE9PSB0cnVlKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8vIENoZWNrIGZvciBhIGRpcmVjdCBtYXRjaAoJCWlmICgkaG9zdCA9PT0gJHJlZmVyZW5jZSkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCS8vIENhbGN1bGF0ZSB0aGUgdmFsaWQgd2lsZGNhcmQgbWF0Y2ggaWYgdGhlIGhvc3QgaXMgbm90IGFuIElQIGFkZHJlc3MKCQkvLyBBbHNvIHZhbGlkYXRlcyB0aGF0IHRoZSBob3N0IGhhcyAzIHBhcnRzIG9yIG1vcmUsIGFzIHBlciBGaXJlZm94J3MKCQkvLyBydWxlc2V0LgoJCWlmIChpcDJsb25nKCRob3N0KSA9PT0gZmFsc2UpIHsKCQkJJHBhcnRzICAgID0gZXhwbG9kZSgnLicsICRob3N0KTsKCQkJJHBhcnRzWzBdID0gJyonOwoJCQkkd2lsZGNhcmQgPSBpbXBsb2RlKCcuJywgJHBhcnRzKTsKCQkJaWYgKCR3aWxkY2FyZCA9PT0gJHJlZmVyZW5jZSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KfQo8P3BocAovKioKICogRXZlbnQgZGlzcGF0Y2hlcgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogRXZlbnQgZGlzcGF0Y2hlcgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCmludGVyZmFjZSBSZXF1ZXN0c19Ib29rZXIgewoJLyoqCgkgKiBSZWdpc3RlciBhIGNhbGxiYWNrIGZvciBhIGhvb2sKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRob29rIEhvb2sgbmFtZQoJICogQHBhcmFtIGNhbGxiYWNrICRjYWxsYmFjayBGdW5jdGlvbi9tZXRob2QgdG8gY2FsbCBvbiBldmVudAoJICogQHBhcmFtIGludCAkcHJpb3JpdHkgUHJpb3JpdHkgbnVtYmVyLiA8MCBpcyBleGVjdXRlZCBlYXJsaWVyLCA+MCBpcyBleGVjdXRlZCBsYXRlcgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoJGhvb2ssICRjYWxsYmFjaywgJHByaW9yaXR5ID0gMCk7CgoJLyoqCgkgKiBEaXNwYXRjaCBhIG1lc3NhZ2UKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRob29rIEhvb2sgbmFtZQoJICogQHBhcmFtIGFycmF5ICRwYXJhbWV0ZXJzIFBhcmFtZXRlcnMgdG8gcGFzcyB0byBjYWxsYmFja3MKCSAqIEByZXR1cm4gYm9vbGVhbiBTdWNjZXNzZnVsbmVzcwoJICovCglwdWJsaWMgZnVuY3Rpb24gZGlzcGF0Y2goJGhvb2ssICRwYXJhbWV0ZXJzID0gYXJyYXkoKSk7Cn0KPD9waHAKLyoqCiAqIGNVUkwgSFRUUCB0cmFuc3BvcnQKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVHJhbnNwb3J0CiAqLwoKLyoqCiAqIGNVUkwgSFRUUCB0cmFuc3BvcnQKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVHJhbnNwb3J0CiAqLwpjbGFzcyBSZXF1ZXN0c19UcmFuc3BvcnRfY1VSTCBpbXBsZW1lbnRzIFJlcXVlc3RzX1RyYW5zcG9ydCB7Cgljb25zdCBDVVJMXzdfMTBfNSA9IDB4MDcwQTA1OwoJY29uc3QgQ1VSTF83XzE2XzIgPSAweDA3MTAwMjsKCgkvKioKCSAqIFJhdyBIVFRQIGRhdGEKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJGhlYWRlcnMgPSAnJzsKCgkvKioKCSAqIFJhdyBib2R5IGRhdGEKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHJlc3BvbnNlX2RhdGEgPSAnJzsKCgkvKioKCSAqIEluZm9ybWF0aW9uIG9uIHRoZSBjdXJyZW50IHJlcXVlc3QKCSAqCgkgKiBAdmFyIGFycmF5IGNVUkwgaW5mb3JtYXRpb24gYXJyYXksIHNlZSB7QHNlZSBodHRwczovL3NlY3VyZS5waHAubmV0L2N1cmxfZ2V0aW5mb30KCSAqLwoJcHVibGljICRpbmZvOwoKCS8qKgoJICogY1VSTCB2ZXJzaW9uIG51bWJlcgoJICoKCSAqIEB2YXIgaW50CgkgKi8KCXB1YmxpYyAkdmVyc2lvbjsKCgkvKioKCSAqIGNVUkwgaGFuZGxlCgkgKgoJICogQHZhciByZXNvdXJjZQoJICovCglwcm90ZWN0ZWQgJGhhbmRsZTsKCgkvKioKCSAqIEhvb2sgZGlzcGF0Y2hlciBpbnN0YW5jZQoJICoKCSAqIEB2YXIgUmVxdWVzdHNfSG9va3MKCSAqLwoJcHJvdGVjdGVkICRob29rczsKCgkvKioKCSAqIEhhdmUgd2UgZmluaXNoZWQgdGhlIGhlYWRlcnMgeWV0PwoJICoKCSAqIEB2YXIgYm9vbGVhbgoJICovCglwcm90ZWN0ZWQgJGRvbmVfaGVhZGVycyA9IGZhbHNlOwoKCS8qKgoJICogSWYgc3RyZWFtaW5nIHRvIGEgZmlsZSwga2VlcCB0aGUgZmlsZSBwb2ludGVyCgkgKgoJICogQHZhciByZXNvdXJjZQoJICovCglwcm90ZWN0ZWQgJHN0cmVhbV9oYW5kbGU7CgoJLyoqCgkgKiBIb3cgbWFueSBieXRlcyBhcmUgaW4gdGhlIHJlc3BvbnNlIGJvZHk/CgkgKgoJICogQHZhciBpbnQKCSAqLwoJcHJvdGVjdGVkICRyZXNwb25zZV9ieXRlczsKCgkvKioKCSAqIFdoYXQncyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgd2Ugc2hvdWxkIGtlZXA/CgkgKgoJICogQHZhciBpbnR8Ym9vbCBCeXRlIGNvdW50LCBvciBmYWxzZSBpZiBubyBsaW1pdC4KCSAqLwoJcHJvdGVjdGVkICRyZXNwb25zZV9ieXRlX2xpbWl0OwoKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSRjdXJsICAgICAgICAgID0gY3VybF92ZXJzaW9uKCk7CgkJJHRoaXMtPnZlcnNpb24gPSAkY3VybFsndmVyc2lvbl9udW1iZXInXTsKCQkkdGhpcy0+aGFuZGxlICA9IGN1cmxfaW5pdCgpOwoKCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0hFQURFUiwgZmFsc2UpOwoJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsIDEpOwoJCWlmICgkdGhpcy0+dmVyc2lvbiA+PSBzZWxmOjpDVVJMXzdfMTBfNSkgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0VOQ09ESU5HLCAnJyk7CgkJfQoJCWlmIChkZWZpbmVkKCdDVVJMT1BUX1BST1RPQ09MUycpKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5LkNvbnN0YW50cy5OZXdDb25zdGFudHMuY3VybG9wdF9wcm90b2NvbHNGb3VuZAoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1BST1RPQ09MUywgQ1VSTFBST1RPX0hUVFAgfCBDVVJMUFJPVE9fSFRUUFMpOwoJCX0KCQlpZiAoZGVmaW5lZCgnQ1VSTE9QVF9SRURJUl9QUk9UT0NPTFMnKSkgewoJCQkvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5Db25zdGFudHMuTmV3Q29uc3RhbnRzLmN1cmxvcHRfcmVkaXJfcHJvdG9jb2xzRm91bmQKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9SRURJUl9QUk9UT0NPTFMsIENVUkxQUk9UT19IVFRQIHwgQ1VSTFBST1RPX0hUVFBTKTsKCQl9Cgl9CgoJLyoqCgkgKiBEZXN0cnVjdG9yCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2Rlc3RydWN0KCkgewoJCWlmIChpc19yZXNvdXJjZSgkdGhpcy0+aGFuZGxlKSkgewoJCQljdXJsX2Nsb3NlKCR0aGlzLT5oYW5kbGUpOwoJCX0KCX0KCgkvKioKCSAqIFBlcmZvcm0gYSByZXF1ZXN0CgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gYSBjVVJMIGVycm9yIChgY3VybGVycm9yYCkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgVVJMIHRvIHJlcXVlc3QKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBBc3NvY2lhdGl2ZSBhcnJheSBvZiByZXF1ZXN0IGhlYWRlcnMKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyB0aGUgUE9TVCBib2R5LCBvciBhcyBwYXJhbWV0ZXJzIGluIHRoZSBVUkwgZm9yIGEgR0VUL0hFQUQKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBSZXF1ZXN0IG9wdGlvbnMsIHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVzcG9uc2UoKX0gZm9yIGRvY3VtZW50YXRpb24KCSAqIEByZXR1cm4gc3RyaW5nIFJhdyBIVFRQIHJlc3VsdAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVxdWVzdCgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRkYXRhID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJJHRoaXMtPmhvb2tzID0gJG9wdGlvbnNbJ2hvb2tzJ107CgoJCSR0aGlzLT5zZXR1cF9oYW5kbGUoJHVybCwgJGhlYWRlcnMsICRkYXRhLCAkb3B0aW9ucyk7CgoJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgnY3VybC5iZWZvcmVfc2VuZCcsIGFycmF5KCYkdGhpcy0+aGFuZGxlKSk7CgoJCWlmICgkb3B0aW9uc1snZmlsZW5hbWUnXSAhPT0gZmFsc2UpIHsKCQkJJHRoaXMtPnN0cmVhbV9oYW5kbGUgPSBmb3Blbigkb3B0aW9uc1snZmlsZW5hbWUnXSwgJ3diJyk7CgkJfQoKCQkkdGhpcy0+cmVzcG9uc2VfZGF0YSAgICAgICA9ICcnOwoJCSR0aGlzLT5yZXNwb25zZV9ieXRlcyAgICAgID0gMDsKCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZV9saW1pdCA9IGZhbHNlOwoJCWlmICgkb3B0aW9uc1snbWF4X2J5dGVzJ10gIT09IGZhbHNlKSB7CgkJCSR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0ID0gJG9wdGlvbnNbJ21heF9ieXRlcyddOwoJCX0KCgkJaWYgKGlzc2V0KCRvcHRpb25zWyd2ZXJpZnknXSkpIHsKCQkJaWYgKCRvcHRpb25zWyd2ZXJpZnknXSA9PT0gZmFsc2UpIHsKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfU1NMX1ZFUklGWUhPU1QsIDApOwoJCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9TU0xfVkVSSUZZUEVFUiwgMCk7CgkJCX0KCQkJZWxzZWlmIChpc19zdHJpbmcoJG9wdGlvbnNbJ3ZlcmlmeSddKSkgewoJCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9DQUlORk8sICRvcHRpb25zWyd2ZXJpZnknXSk7CgkJCX0KCQl9CgoJCWlmIChpc3NldCgkb3B0aW9uc1sndmVyaWZ5bmFtZSddKSAmJiAkb3B0aW9uc1sndmVyaWZ5bmFtZSddID09PSBmYWxzZSkgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1NTTF9WRVJJRllIT1NULCAwKTsKCQl9CgoJCWN1cmxfZXhlYygkdGhpcy0+aGFuZGxlKTsKCQkkcmVzcG9uc2UgPSAkdGhpcy0+cmVzcG9uc2VfZGF0YTsKCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdjdXJsLmFmdGVyX3NlbmQnLCBhcnJheSgpKTsKCgkJaWYgKGN1cmxfZXJybm8oJHRoaXMtPmhhbmRsZSkgPT09IDIzIHx8IGN1cmxfZXJybm8oJHRoaXMtPmhhbmRsZSkgPT09IDYxKSB7CgkJCS8vIFJlc2V0IGVuY29kaW5nIGFuZCB0cnkgYWdhaW4KCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9FTkNPRElORywgJ25vbmUnKTsKCgkJCSR0aGlzLT5yZXNwb25zZV9kYXRhICA9ICcnOwoJCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZXMgPSAwOwoJCQljdXJsX2V4ZWMoJHRoaXMtPmhhbmRsZSk7CgkJCSRyZXNwb25zZSA9ICR0aGlzLT5yZXNwb25zZV9kYXRhOwoJCX0KCgkJJHRoaXMtPnByb2Nlc3NfcmVzcG9uc2UoJHJlc3BvbnNlLCAkb3B0aW9ucyk7CgoJCS8vIE5lZWQgdG8gcmVtb3ZlIHRoZSAkdGhpcyByZWZlcmVuY2UgZnJvbSB0aGUgY3VybCBoYW5kbGUuCgkJLy8gT3RoZXJ3aXNlIFJlcXVlc3RzX1RyYW5zcG9ydF9jVVJMIHdvbnQgYmUgZ2FyYmFnZSBjb2xsZWN0ZWQgYW5kIHRoZSBjdXJsX2Nsb3NlKCkgd2lsbCBuZXZlciBiZSBjYWxsZWQuCgkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9IRUFERVJGVU5DVElPTiwgbnVsbCk7CgkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9XUklURUZVTkNUSU9OLCBudWxsKTsKCgkJcmV0dXJuICR0aGlzLT5oZWFkZXJzOwoJfQoKCS8qKgoJICogU2VuZCBtdWx0aXBsZSByZXF1ZXN0cyBzaW11bHRhbmVvdXNseQoJICoKCSAqIEBwYXJhbSBhcnJheSAkcmVxdWVzdHMgUmVxdWVzdCBkYXRhCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgR2xvYmFsIG9wdGlvbnMKCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgb2YgUmVxdWVzdHNfUmVzcG9uc2Ugb2JqZWN0cyAobWF5IGNvbnRhaW4gUmVxdWVzdHNfRXhjZXB0aW9uIG9yIHN0cmluZyByZXNwb25zZXMgYXMgd2VsbCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3RfbXVsdGlwbGUoJHJlcXVlc3RzLCAkb3B0aW9ucykgewoJCS8vIElmIHlvdSdyZSBub3QgcmVxdWVzdGluZywgd2UgY2FuJ3QgZ2V0IGFueSByZXNwb25zZXMgwq9cXyjjg4QpXy/CrwoJCWlmIChlbXB0eSgkcmVxdWVzdHMpKSB7CgkJCXJldHVybiBhcnJheSgpOwoJCX0KCgkJJG11bHRpaGFuZGxlID0gY3VybF9tdWx0aV9pbml0KCk7CgkJJHN1YnJlcXVlc3RzID0gYXJyYXkoKTsKCQkkc3ViaGFuZGxlcyAgPSBhcnJheSgpOwoKCQkkY2xhc3MgPSBnZXRfY2xhc3MoJHRoaXMpOwoJCWZvcmVhY2ggKCRyZXF1ZXN0cyBhcyAkaWQgPT4gJHJlcXVlc3QpIHsKCQkJJHN1YnJlcXVlc3RzWyRpZF0gPSBuZXcgJGNsYXNzKCk7CgkJCSRzdWJoYW5kbGVzWyRpZF0gID0gJHN1YnJlcXVlc3RzWyRpZF0tPmdldF9zdWJyZXF1ZXN0X2hhbmRsZSgkcmVxdWVzdFsndXJsJ10sICRyZXF1ZXN0WydoZWFkZXJzJ10sICRyZXF1ZXN0WydkYXRhJ10sICRyZXF1ZXN0WydvcHRpb25zJ10pOwoJCQkkcmVxdWVzdFsnb3B0aW9ucyddWydob29rcyddLT5kaXNwYXRjaCgnY3VybC5iZWZvcmVfbXVsdGlfYWRkJywgYXJyYXkoJiRzdWJoYW5kbGVzWyRpZF0pKTsKCQkJY3VybF9tdWx0aV9hZGRfaGFuZGxlKCRtdWx0aWhhbmRsZSwgJHN1YmhhbmRsZXNbJGlkXSk7CgkJfQoKCQkkY29tcGxldGVkICAgICAgID0gMDsKCQkkcmVzcG9uc2VzICAgICAgID0gYXJyYXkoKTsKCQkkc3VicmVxdWVzdGNvdW50ID0gY291bnQoJHN1YnJlcXVlc3RzKTsKCgkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYmVmb3JlX211bHRpX2V4ZWMnLCBhcnJheSgmJG11bHRpaGFuZGxlKSk7CgoJCWRvIHsKCQkJJGFjdGl2ZSA9IDA7CgoJCQlkbyB7CgkJCQkkc3RhdHVzID0gY3VybF9tdWx0aV9leGVjKCRtdWx0aWhhbmRsZSwgJGFjdGl2ZSk7CgkJCX0KCQkJd2hpbGUgKCRzdGF0dXMgPT09IENVUkxNX0NBTExfTVVMVElfUEVSRk9STSk7CgoJCQkkdG9fcHJvY2VzcyA9IGFycmF5KCk7CgoJCQkvLyBSZWFkIHRoZSBpbmZvcm1hdGlvbiBhcyBuZWVkZWQKCQkJd2hpbGUgKCRkb25lID0gY3VybF9tdWx0aV9pbmZvX3JlYWQoJG11bHRpaGFuZGxlKSkgewoJCQkJJGtleSA9IGFycmF5X3NlYXJjaCgkZG9uZVsnaGFuZGxlJ10sICRzdWJoYW5kbGVzLCB0cnVlKTsKCQkJCWlmICghaXNzZXQoJHRvX3Byb2Nlc3NbJGtleV0pKSB7CgkJCQkJJHRvX3Byb2Nlc3NbJGtleV0gPSAkZG9uZTsKCQkJCX0KCQkJfQoKCQkJLy8gUGFyc2UgdGhlIGZpbmlzaGVkIHJlcXVlc3RzIGJlZm9yZSB3ZSBzdGFydCBnZXR0aW5nIHRoZSBuZXcgb25lcwoJCQlmb3JlYWNoICgkdG9fcHJvY2VzcyBhcyAka2V5ID0+ICRkb25lKSB7CgkJCQkkb3B0aW9ucyA9ICRyZXF1ZXN0c1ska2V5XVsnb3B0aW9ucyddOwoJCQkJaWYgKCRkb25lWydyZXN1bHQnXSAhPT0gQ1VSTEVfT0spIHsKCQkJCQkvL2dldCBlcnJvciBzdHJpbmcgZm9yIGhhbmRsZS4KCQkJCQkkcmVhc29uICAgICAgICAgID0gY3VybF9lcnJvcigkZG9uZVsnaGFuZGxlJ10pOwoJCQkJCSRleGNlcHRpb24gICAgICAgPSBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uX1RyYW5zcG9ydF9jVVJMKAoJCQkJCQkkcmVhc29uLAoJCQkJCQlSZXF1ZXN0c19FeGNlcHRpb25fVHJhbnNwb3J0X2NVUkw6OkVBU1ksCgkJCQkJCSRkb25lWydoYW5kbGUnXSwKCQkJCQkJJGRvbmVbJ3Jlc3VsdCddCgkJCQkJKTsKCQkJCQkkcmVzcG9uc2VzWyRrZXldID0gJGV4Y2VwdGlvbjsKCQkJCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ3RyYW5zcG9ydC5pbnRlcm5hbC5wYXJzZV9lcnJvcicsIGFycmF5KCYkcmVzcG9uc2VzWyRrZXldLCAkcmVxdWVzdHNbJGtleV0pKTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCSRyZXNwb25zZXNbJGtleV0gPSAkc3VicmVxdWVzdHNbJGtleV0tPnByb2Nlc3NfcmVzcG9uc2UoJHN1YnJlcXVlc3RzWyRrZXldLT5yZXNwb25zZV9kYXRhLCAkb3B0aW9ucyk7CgoJCQkJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgndHJhbnNwb3J0LmludGVybmFsLnBhcnNlX3Jlc3BvbnNlJywgYXJyYXkoJiRyZXNwb25zZXNbJGtleV0sICRyZXF1ZXN0c1ska2V5XSkpOwoJCQkJfQoKCQkJCWN1cmxfbXVsdGlfcmVtb3ZlX2hhbmRsZSgkbXVsdGloYW5kbGUsICRkb25lWydoYW5kbGUnXSk7CgkJCQljdXJsX2Nsb3NlKCRkb25lWydoYW5kbGUnXSk7CgoJCQkJaWYgKCFpc19zdHJpbmcoJHJlc3BvbnNlc1ska2V5XSkpIHsKCQkJCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ211bHRpcGxlLnJlcXVlc3QuY29tcGxldGUnLCBhcnJheSgmJHJlc3BvbnNlc1ska2V5XSwgJGtleSkpOwoJCQkJfQoJCQkJJGNvbXBsZXRlZCsrOwoJCQl9CgkJfQoJCXdoaWxlICgkYWN0aXZlIHx8ICRjb21wbGV0ZWQgPCAkc3VicmVxdWVzdGNvdW50KTsKCgkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYWZ0ZXJfbXVsdGlfZXhlYycsIGFycmF5KCYkbXVsdGloYW5kbGUpKTsKCgkJY3VybF9tdWx0aV9jbG9zZSgkbXVsdGloYW5kbGUpOwoKCQlyZXR1cm4gJHJlc3BvbnNlczsKCX0KCgkvKioKCSAqIEdldCB0aGUgY1VSTCBoYW5kbGUgZm9yIHVzZSBpbiBhIG11bHRpLXJlcXVlc3QKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgVVJMIHRvIHJlcXVlc3QKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBBc3NvY2lhdGl2ZSBhcnJheSBvZiByZXF1ZXN0IGhlYWRlcnMKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyB0aGUgUE9TVCBib2R5LCBvciBhcyBwYXJhbWV0ZXJzIGluIHRoZSBVUkwgZm9yIGEgR0VUL0hFQUQKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBSZXF1ZXN0IG9wdGlvbnMsIHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVzcG9uc2UoKX0gZm9yIGRvY3VtZW50YXRpb24KCSAqIEByZXR1cm4gcmVzb3VyY2UgU3VicmVxdWVzdCdzIGNVUkwgaGFuZGxlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiAmZ2V0X3N1YnJlcXVlc3RfaGFuZGxlKCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG9wdGlvbnMpIHsKCQkkdGhpcy0+c2V0dXBfaGFuZGxlKCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG9wdGlvbnMpOwoKCQlpZiAoJG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIT09IGZhbHNlKSB7CgkJCSR0aGlzLT5zdHJlYW1faGFuZGxlID0gZm9wZW4oJG9wdGlvbnNbJ2ZpbGVuYW1lJ10sICd3YicpOwoJCX0KCgkJJHRoaXMtPnJlc3BvbnNlX2RhdGEgICAgICAgPSAnJzsKCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZXMgICAgICA9IDA7CgkJJHRoaXMtPnJlc3BvbnNlX2J5dGVfbGltaXQgPSBmYWxzZTsKCQlpZiAoJG9wdGlvbnNbJ21heF9ieXRlcyddICE9PSBmYWxzZSkgewoJCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZV9saW1pdCA9ICRvcHRpb25zWydtYXhfYnl0ZXMnXTsKCQl9CgkJJHRoaXMtPmhvb2tzID0gJG9wdGlvbnNbJ2hvb2tzJ107CgoJCXJldHVybiAkdGhpcy0+aGFuZGxlOwoJfQoKCS8qKgoJICogU2V0dXAgdGhlIGNVUkwgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gZGF0YQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgdG8gcmVxdWVzdAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIEFzc29jaWF0aXZlIGFycmF5IG9mIHJlcXVlc3QgaGVhZGVycwoJICogQHBhcmFtIHN0cmluZ3xhcnJheSAkZGF0YSBEYXRhIHRvIHNlbmQgZWl0aGVyIGFzIHRoZSBQT1NUIGJvZHksIG9yIGFzIHBhcmFtZXRlcnMgaW4gdGhlIFVSTCBmb3IgYSBHRVQvSEVBRAoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIFJlcXVlc3Qgb3B0aW9ucywgc2VlIHtAc2VlIFJlcXVlc3RzOjpyZXNwb25zZSgpfSBmb3IgZG9jdW1lbnRhdGlvbgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0dXBfaGFuZGxlKCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG9wdGlvbnMpIHsKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYmVmb3JlX3JlcXVlc3QnLCBhcnJheSgmJHRoaXMtPmhhbmRsZSkpOwoKCQkvLyBGb3JjZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uIGZvciBvbGQgdmVyc2lvbnMgb2YgY1VSTCAoPDcuMjIpLgoJCWlmICghaXNzZXQoJGhlYWRlcnNbJ0Nvbm5lY3Rpb24nXSkpIHsKCQkJJGhlYWRlcnNbJ0Nvbm5lY3Rpb24nXSA9ICdjbG9zZSc7CgkJfQoKCQkvKioKCQkgKiBBZGQgIkV4cGVjdCIgaGVhZGVyLgoJCSAqCgkJICogQnkgZGVmYXVsdCwgY1VSTCBhZGRzIGEgIkV4cGVjdDogMTAwLUNvbnRpbnVlIiB0byBtb3N0IHJlcXVlc3RzLiBUaGlzIGhlYWRlciBjYW4KCQkgKiBhZGQgYXMgbXVjaCBhcyBhIHNlY29uZCB0byB0aGUgdGltZSBpdCB0YWtlcyBmb3IgY1VSTCB0byBwZXJmb3JtIGEgcmVxdWVzdC4gVG8KCQkgKiBwcmV2ZW50IHRoaXMsIHdlIG5lZWQgdG8gc2V0IGFuIGVtcHR5ICJFeHBlY3QiIGhlYWRlci4gVG8gbWF0Y2ggdGhlIGJlaGF2aW91ciBvZgoJCSAqIEd1enpsZSwgd2UnbGwgYWRkIHRoZSBlbXB0eSBoZWFkZXIgdG8gcmVxdWVzdHMgdGhhdCBhcmUgc21hbGxlciB0aGFuIDEgTUIgYW5kIHVzZQoJCSAqIEhUVFAvMS4xLgoJCSAqCgkJICogaHR0cHM6Ly9jdXJsLnNlL21haWwvbGliLTIwMTctMDcvMDAxMy5odG1sCgkJICovCgkJaWYgKCFpc3NldCgkaGVhZGVyc1snRXhwZWN0J10pICYmICRvcHRpb25zWydwcm90b2NvbF92ZXJzaW9uJ10gPT09IDEuMSkgewoJCQkkaGVhZGVyc1snRXhwZWN0J10gPSAkdGhpcy0+Z2V0X2V4cGVjdF9oZWFkZXIoJGRhdGEpOwoJCX0KCgkJJGhlYWRlcnMgPSBSZXF1ZXN0czo6ZmxhdHRlbigkaGVhZGVycyk7CgoJCWlmICghZW1wdHkoJGRhdGEpKSB7CgkJCSRkYXRhX2Zvcm1hdCA9ICRvcHRpb25zWydkYXRhX2Zvcm1hdCddOwoKCQkJaWYgKCRkYXRhX2Zvcm1hdCA9PT0gJ3F1ZXJ5JykgewoJCQkJJHVybCAgPSBzZWxmOjpmb3JtYXRfZ2V0KCR1cmwsICRkYXRhKTsKCQkJCSRkYXRhID0gJyc7CgkJCX0KCQkJZWxzZWlmICghaXNfc3RyaW5nKCRkYXRhKSkgewoJCQkJJGRhdGEgPSBodHRwX2J1aWxkX3F1ZXJ5KCRkYXRhLCBudWxsLCAnJicpOwoJCQl9CgkJfQoKCQlzd2l0Y2ggKCRvcHRpb25zWyd0eXBlJ10pIHsKCQkJY2FzZSBSZXF1ZXN0czo6UE9TVDoKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfUE9TVCwgdHJ1ZSk7CgkJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1BPU1RGSUVMRFMsICRkYXRhKTsKCQkJCWJyZWFrOwoJCQljYXNlIFJlcXVlc3RzOjpIRUFEOgoJCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9DVVNUT01SRVFVRVNULCAkb3B0aW9uc1sndHlwZSddKTsKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfTk9CT0RZLCB0cnVlKTsKCQkJCWJyZWFrOwoJCQljYXNlIFJlcXVlc3RzOjpUUkFDRToKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfQ1VTVE9NUkVRVUVTVCwgJG9wdGlvbnNbJ3R5cGUnXSk7CgkJCQlicmVhazsKCQkJY2FzZSBSZXF1ZXN0czo6UEFUQ0g6CgkJCWNhc2UgUmVxdWVzdHM6OlBVVDoKCQkJY2FzZSBSZXF1ZXN0czo6REVMRVRFOgoJCQljYXNlIFJlcXVlc3RzOjpPUFRJT05TOgoJCQlkZWZhdWx0OgoJCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9DVVNUT01SRVFVRVNULCAkb3B0aW9uc1sndHlwZSddKTsKCQkJCWlmICghZW1wdHkoJGRhdGEpKSB7CgkJCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9QT1NURklFTERTLCAkZGF0YSk7CgkJCQl9CgkJfQoKCQkvLyBjVVJMIHJlcXVpcmVzIGEgbWluaW11bSB0aW1lb3V0IG9mIDEgc2Vjb25kIHdoZW4gdXNpbmcgdGhlIHN5c3RlbQoJCS8vIEROUyByZXNvbHZlciwgYXMgaXQgdXNlcyBgYWxhcm0oKWAsIHdoaWNoIGlzIHNlY29uZCByZXNvbHV0aW9uIG9ubHkuCgkJLy8gVGhlcmUncyBubyB3YXkgdG8gZGV0ZWN0IHdoaWNoIEROUyByZXNvbHZlciBpcyBiZWluZyB1c2VkIGZyb20gb3VyCgkJLy8gZW5kLCBzbyB3ZSBuZWVkIHRvIHJvdW5kIHVwIHJlZ2FyZGxlc3Mgb2YgdGhlIHN1cHBsaWVkIHRpbWVvdXQuCgkJLy8KCQkvLyBodHRwczovL2dpdGh1Yi5jb20vY3VybC9jdXJsL2Jsb2IvNGY0NTI0MGJjODRhOWFhNjQ4YzhmNzI0M2JlN2I3OWU5ZjkzMjNhNS9saWIvaG9zdGlwLmMjTDYwNi1MNjA5CgkJJHRpbWVvdXQgPSBtYXgoJG9wdGlvbnNbJ3RpbWVvdXQnXSwgMSk7CgoJCWlmIChpc19pbnQoJHRpbWVvdXQpIHx8ICR0aGlzLT52ZXJzaW9uIDwgc2VsZjo6Q1VSTF83XzE2XzIpIHsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9USU1FT1VULCBjZWlsKCR0aW1lb3V0KSk7CgkJfQoJCWVsc2UgewoJCQkvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5Db25zdGFudHMuTmV3Q29uc3RhbnRzLmN1cmxvcHRfdGltZW91dF9tc0ZvdW5kCgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfVElNRU9VVF9NUywgcm91bmQoJHRpbWVvdXQgKiAxMDAwKSk7CgkJfQoKCQlpZiAoaXNfaW50KCRvcHRpb25zWydjb25uZWN0X3RpbWVvdXQnXSkgfHwgJHRoaXMtPnZlcnNpb24gPCBzZWxmOjpDVVJMXzdfMTZfMikgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0NPTk5FQ1RUSU1FT1VULCBjZWlsKCRvcHRpb25zWydjb25uZWN0X3RpbWVvdXQnXSkpOwoJCX0KCQllbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuQ29uc3RhbnRzLk5ld0NvbnN0YW50cy5jdXJsb3B0X2Nvbm5lY3R0aW1lb3V0X21zRm91bmQKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9DT05ORUNUVElNRU9VVF9NUywgcm91bmQoJG9wdGlvbnNbJ2Nvbm5lY3RfdGltZW91dCddICogMTAwMCkpOwoJCX0KCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1VSTCwgJHVybCk7CgkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9SRUZFUkVSLCAkdXJsKTsKCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1VTRVJBR0VOVCwgJG9wdGlvbnNbJ3VzZXJhZ2VudCddKTsKCQlpZiAoIWVtcHR5KCRoZWFkZXJzKSkgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0hUVFBIRUFERVIsICRoZWFkZXJzKTsKCQl9CgkJaWYgKCRvcHRpb25zWydwcm90b2NvbF92ZXJzaW9uJ10gPT09IDEuMSkgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0hUVFBfVkVSU0lPTiwgQ1VSTF9IVFRQX1ZFUlNJT05fMV8xKTsKCQl9CgkJZWxzZSB7CgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfSFRUUF9WRVJTSU9OLCBDVVJMX0hUVFBfVkVSU0lPTl8xXzApOwoJCX0KCgkJaWYgKCRvcHRpb25zWydibG9ja2luZyddID09PSB0cnVlKSB7CgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfSEVBREVSRlVOQ1RJT04sIGFycmF5KCR0aGlzLCAnc3RyZWFtX2hlYWRlcnMnKSk7CgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfV1JJVEVGVU5DVElPTiwgYXJyYXkoJHRoaXMsICdzdHJlYW1fYm9keScpKTsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9CVUZGRVJTSVpFLCBSZXF1ZXN0czo6QlVGRkVSX1NJWkUpOwoJCX0KCX0KCgkvKioKCSAqIFByb2Nlc3MgYSByZXNwb25zZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlc3BvbnNlIFJlc3BvbnNlIGRhdGEgZnJvbSB0aGUgYm9keQoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIFJlcXVlc3Qgb3B0aW9ucwoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UgSFRUUCByZXNwb25zZSBkYXRhIGluY2x1ZGluZyBoZWFkZXJzLiBGYWxzZSBpZiBub24tYmxvY2tpbmcuCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2Vzc19yZXNwb25zZSgkcmVzcG9uc2UsICRvcHRpb25zKSB7CgkJaWYgKCRvcHRpb25zWydibG9ja2luZyddID09PSBmYWxzZSkgewoJCQkkZmFrZV9oZWFkZXJzID0gJyc7CgkJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgnY3VybC5hZnRlcl9yZXF1ZXN0JywgYXJyYXkoJiRmYWtlX2hlYWRlcnMpKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlpZiAoJG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIT09IGZhbHNlICYmICR0aGlzLT5zdHJlYW1faGFuZGxlKSB7CgkJCWZjbG9zZSgkdGhpcy0+c3RyZWFtX2hhbmRsZSk7CgkJCSR0aGlzLT5oZWFkZXJzID0gdHJpbSgkdGhpcy0+aGVhZGVycyk7CgkJfQoJCWVsc2UgewoJCQkkdGhpcy0+aGVhZGVycyAuPSAkcmVzcG9uc2U7CgkJfQoKCQlpZiAoY3VybF9lcnJubygkdGhpcy0+aGFuZGxlKSkgewoJCQkkZXJyb3IgPSBzcHJpbnRmKAoJCQkJJ2NVUkwgZXJyb3IgJXM6ICVzJywKCQkJCWN1cmxfZXJybm8oJHRoaXMtPmhhbmRsZSksCgkJCQljdXJsX2Vycm9yKCR0aGlzLT5oYW5kbGUpCgkJCSk7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJGVycm9yLCAnY3VybGVycm9yJywgJHRoaXMtPmhhbmRsZSk7CgkJfQoJCSR0aGlzLT5pbmZvID0gY3VybF9nZXRpbmZvKCR0aGlzLT5oYW5kbGUpOwoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYWZ0ZXJfcmVxdWVzdCcsIGFycmF5KCYkdGhpcy0+aGVhZGVycywgJiR0aGlzLT5pbmZvKSk7CgkJcmV0dXJuICR0aGlzLT5oZWFkZXJzOwoJfQoKCS8qKgoJICogQ29sbGVjdCB0aGUgaGVhZGVycyBhcyB0aGV5IGFyZSByZWNlaXZlZAoJICoKCSAqIEBwYXJhbSByZXNvdXJjZSAkaGFuZGxlIGNVUkwgcmVzb3VyY2UKCSAqIEBwYXJhbSBzdHJpbmcgJGhlYWRlcnMgSGVhZGVyIHN0cmluZwoJICogQHJldHVybiBpbnRlZ2VyIExlbmd0aCBvZiBwcm92aWRlZCBoZWFkZXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHN0cmVhbV9oZWFkZXJzKCRoYW5kbGUsICRoZWFkZXJzKSB7CgkJLy8gV2h5IGRvIHdlIGRvIHRoaXM/IGNVUkwgd2lsbCBzZW5kIGJvdGggdGhlIGZpbmFsIHJlc3BvbnNlIGFuZCBhbnkKCQkvLyBpbnRlcmltIHJlc3BvbnNlcywgc3VjaCBhcyBhIDEwMCBDb250aW51ZS4gV2UgZG9uJ3QgbmVlZCB0aGF0LgoJCS8vIChXZSBtYXkgd2FudCB0byBrZWVwIHRoaXMgc29tZXdoZXJlIGp1c3QgaW4gY2FzZSkKCQlpZiAoJHRoaXMtPmRvbmVfaGVhZGVycykgewoJCQkkdGhpcy0+aGVhZGVycyAgICAgID0gJyc7CgkJCSR0aGlzLT5kb25lX2hlYWRlcnMgPSBmYWxzZTsKCQl9CgkJJHRoaXMtPmhlYWRlcnMgLj0gJGhlYWRlcnM7CgoJCWlmICgkaGVhZGVycyA9PT0gIlxyXG4iKSB7CgkJCSR0aGlzLT5kb25lX2hlYWRlcnMgPSB0cnVlOwoJCX0KCQlyZXR1cm4gc3RybGVuKCRoZWFkZXJzKTsKCX0KCgkvKioKCSAqIENvbGxlY3QgZGF0YSBhcyBpdCdzIHJlY2VpdmVkCgkgKgoJICogQHNpbmNlIDEuNi4xCgkgKgoJICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUgY1VSTCByZXNvdXJjZQoJICogQHBhcmFtIHN0cmluZyAkZGF0YSBCb2R5IGRhdGEKCSAqIEByZXR1cm4gaW50ZWdlciBMZW5ndGggb2YgcHJvdmlkZWQgZGF0YQoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RyZWFtX2JvZHkoJGhhbmRsZSwgJGRhdGEpIHsKCQkkdGhpcy0+aG9va3MtPmRpc3BhdGNoKCdyZXF1ZXN0LnByb2dyZXNzJywgYXJyYXkoJGRhdGEsICR0aGlzLT5yZXNwb25zZV9ieXRlcywgJHRoaXMtPnJlc3BvbnNlX2J5dGVfbGltaXQpKTsKCQkkZGF0YV9sZW5ndGggPSBzdHJsZW4oJGRhdGEpOwoKCQkvLyBBcmUgd2UgbGltaXRpbmcgdGhlIHJlc3BvbnNlIHNpemU/CgkJaWYgKCR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0KSB7CgkJCWlmICgkdGhpcy0+cmVzcG9uc2VfYnl0ZXMgPT09ICR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0KSB7CgkJCQkvLyBBbHJlYWR5IGF0IG1heGltdW0sIG1vdmUgb24KCQkJCXJldHVybiAkZGF0YV9sZW5ndGg7CgkJCX0KCgkJCWlmICgoJHRoaXMtPnJlc3BvbnNlX2J5dGVzICsgJGRhdGFfbGVuZ3RoKSA+ICR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0KSB7CgkJCQkvLyBMaW1pdCB0aGUgbGVuZ3RoCgkJCQkkbGltaXRlZF9sZW5ndGggPSAoJHRoaXMtPnJlc3BvbnNlX2J5dGVfbGltaXQgLSAkdGhpcy0+cmVzcG9uc2VfYnl0ZXMpOwoJCQkJJGRhdGEgICAgICAgICAgID0gc3Vic3RyKCRkYXRhLCAwLCAkbGltaXRlZF9sZW5ndGgpOwoJCQl9CgkJfQoKCQlpZiAoJHRoaXMtPnN0cmVhbV9oYW5kbGUpIHsKCQkJZndyaXRlKCR0aGlzLT5zdHJlYW1faGFuZGxlLCAkZGF0YSk7CgkJfQoJCWVsc2UgewoJCQkkdGhpcy0+cmVzcG9uc2VfZGF0YSAuPSAkZGF0YTsKCQl9CgoJCSR0aGlzLT5yZXNwb25zZV9ieXRlcyArPSBzdHJsZW4oJGRhdGEpOwoJCXJldHVybiAkZGF0YV9sZW5ndGg7Cgl9CgoJLyoqCgkgKiBGb3JtYXQgYSBVUkwgZ2l2ZW4gR0VUIGRhdGEKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBhcnJheXxvYmplY3QgJGRhdGEgRGF0YSB0byBidWlsZCBxdWVyeSB1c2luZywgc2VlIHtAc2VlIGh0dHBzOi8vc2VjdXJlLnBocC5uZXQvaHR0cF9idWlsZF9xdWVyeX0KCSAqIEByZXR1cm4gc3RyaW5nIFVSTCB3aXRoIGRhdGEKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXRfZ2V0KCR1cmwsICRkYXRhKSB7CgkJaWYgKCFlbXB0eSgkZGF0YSkpIHsKCQkJJHF1ZXJ5ICAgICA9ICcnOwoJCQkkdXJsX3BhcnRzID0gcGFyc2VfdXJsKCR1cmwpOwoJCQlpZiAoZW1wdHkoJHVybF9wYXJ0c1sncXVlcnknXSkpIHsKCQkJCSR1cmxfcGFydHNbJ3F1ZXJ5J10gPSAnJzsKCQkJfQoJCQllbHNlIHsKCQkJCSRxdWVyeSA9ICR1cmxfcGFydHNbJ3F1ZXJ5J107CgkJCX0KCgkJCSRxdWVyeSAuPSAnJicgLiBodHRwX2J1aWxkX3F1ZXJ5KCRkYXRhLCBudWxsLCAnJicpOwoJCQkkcXVlcnkgID0gdHJpbSgkcXVlcnksICcmJyk7CgoJCQlpZiAoZW1wdHkoJHVybF9wYXJ0c1sncXVlcnknXSkpIHsKCQkJCSR1cmwgLj0gJz8nIC4gJHF1ZXJ5OwoJCQl9CgkJCWVsc2UgewoJCQkJJHVybCA9IHN0cl9yZXBsYWNlKCR1cmxfcGFydHNbJ3F1ZXJ5J10sICRxdWVyeSwgJHVybCk7CgkJCX0KCQl9CgkJcmV0dXJuICR1cmw7Cgl9CgoJLyoqCgkgKiBXaGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIHZhbGlkCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQHJldHVybiBib29sZWFuIFRydWUgaWYgdGhlIHRyYW5zcG9ydCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRlc3QoJGNhcGFiaWxpdGllcyA9IGFycmF5KCkpIHsKCQlpZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3VybF9pbml0JykgfHwgIWZ1bmN0aW9uX2V4aXN0cygnY3VybF9leGVjJykpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gSWYgbmVlZGVkLCBjaGVjayB0aGF0IG91ciBpbnN0YWxsZWQgY3VybCB2ZXJzaW9uIHN1cHBvcnRzIFNTTAoJCWlmIChpc3NldCgkY2FwYWJpbGl0aWVzWydzc2wnXSkgJiYgJGNhcGFiaWxpdGllc1snc3NsJ10pIHsKCQkJJGN1cmxfdmVyc2lvbiA9IGN1cmxfdmVyc2lvbigpOwoJCQlpZiAoIShDVVJMX1ZFUlNJT05fU1NMICYgJGN1cmxfdmVyc2lvblsnZmVhdHVyZXMnXSkpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGNvcnJlY3QgIkV4cGVjdCIgaGVhZGVyIGZvciB0aGUgZ2l2ZW4gcmVxdWVzdCBkYXRhLgoJICoKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyB0aGUgUE9TVCBib2R5LCBvciBhcyBwYXJhbWV0ZXJzIGluIHRoZSBVUkwgZm9yIGEgR0VUL0hFQUQuCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgIkV4cGVjdCIgaGVhZGVyLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2V4cGVjdF9oZWFkZXIoJGRhdGEpIHsKCQlpZiAoIWlzX2FycmF5KCRkYXRhKSkgewoJCQlyZXR1cm4gc3RybGVuKChzdHJpbmcpICRkYXRhKSA+PSAxMDQ4NTc2ID8gJzEwMC1Db250aW51ZScgOiAnJzsKCQl9CgoJCSRieXRlc2l6ZSA9IDA7CgkJJGl0ZXJhdG9yID0gbmV3IFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IobmV3IFJlY3Vyc2l2ZUFycmF5SXRlcmF0b3IoJGRhdGEpKTsKCgkJZm9yZWFjaCAoJGl0ZXJhdG9yIGFzICRkYXR1bSkgewoJCQkkYnl0ZXNpemUgKz0gc3RybGVuKChzdHJpbmcpICRkYXR1bSk7CgoJCQlpZiAoJGJ5dGVzaXplID49IDEwNDg1NzYpIHsKCQkJCXJldHVybiAnMTAwLUNvbnRpbnVlJzsKCQkJfQoJCX0KCgkJcmV0dXJuICcnOwoJfQp9Cjw/cGhwCi8qKgogKiBmc29ja29wZW4gSFRUUCB0cmFuc3BvcnQKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVHJhbnNwb3J0CiAqLwoKLyoqCiAqIGZzb2Nrb3BlbiBIVFRQIHRyYW5zcG9ydAogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBUcmFuc3BvcnQKICovCmNsYXNzIFJlcXVlc3RzX1RyYW5zcG9ydF9mc29ja29wZW4gaW1wbGVtZW50cyBSZXF1ZXN0c19UcmFuc3BvcnQgewoJLyoqCgkgKiBTZWNvbmQgdG8gbWljcm9zZWNvbmQgY29udmVyc2lvbgoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCgljb25zdCBTRUNPTkRfSU5fTUlDUk9TRUNPTkRTID0gMTAwMDAwMDsKCgkvKioKCSAqIFJhdyBIVFRQIGRhdGEKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJGhlYWRlcnMgPSAnJzsKCgkvKioKCSAqIFN0cmVhbSBtZXRhZGF0YQoJICoKCSAqIEB2YXIgYXJyYXkgQXNzb2NpYXRpdmUgYXJyYXkgb2YgcHJvcGVydGllcywgc2VlIHtAc2VlIGh0dHBzOi8vc2VjdXJlLnBocC5uZXQvc3RyZWFtX2dldF9tZXRhX2RhdGF9CgkgKi8KCXB1YmxpYyAkaW5mbzsKCgkvKioKCSAqIFdoYXQncyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgd2Ugc2hvdWxkIGtlZXA/CgkgKgoJICogQHZhciBpbnR8Ym9vbCBCeXRlIGNvdW50LCBvciBmYWxzZSBpZiBubyBsaW1pdC4KCSAqLwoJcHJvdGVjdGVkICRtYXhfYnl0ZXMgPSBmYWxzZTsKCglwcm90ZWN0ZWQgJGNvbm5lY3RfZXJyb3IgPSAnJzsKCgkvKioKCSAqIFBlcmZvcm0gYSByZXF1ZXN0CgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gZmFpbHVyZSB0byBjb25uZWN0IHRvIHNvY2tldCAoYGZzb2Nrb3BlbmVycm9yYCkKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIHNvY2tldCB0aW1lb3V0IChgdGltZW91dGApCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsIFVSTCB0byByZXF1ZXN0CgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgQXNzb2NpYXRpdmUgYXJyYXkgb2YgcmVxdWVzdCBoZWFkZXJzCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRkYXRhIERhdGEgdG8gc2VuZCBlaXRoZXIgYXMgdGhlIFBPU1QgYm9keSwgb3IgYXMgcGFyYW1ldGVycyBpbiB0aGUgVVJMIGZvciBhIEdFVC9IRUFECgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgUmVxdWVzdCBvcHRpb25zLCBzZWUge0BzZWUgUmVxdWVzdHM6OnJlc3BvbnNlKCl9IGZvciBkb2N1bWVudGF0aW9uCgkgKiBAcmV0dXJuIHN0cmluZyBSYXcgSFRUUCByZXN1bHQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3QoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgnZnNvY2tvcGVuLmJlZm9yZV9yZXF1ZXN0Jyk7CgoJCSR1cmxfcGFydHMgPSBwYXJzZV91cmwoJHVybCk7CgkJaWYgKGVtcHR5KCR1cmxfcGFydHMpKSB7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0ludmFsaWQgVVJMLicsICdpbnZhbGlkdXJsJywgJHVybCk7CgkJfQoJCSRob3N0ICAgICAgICAgICAgICAgICAgICAgPSAkdXJsX3BhcnRzWydob3N0J107CgkJJGNvbnRleHQgICAgICAgICAgICAgICAgICA9IHN0cmVhbV9jb250ZXh0X2NyZWF0ZSgpOwoJCSR2ZXJpZnluYW1lICAgICAgICAgICAgICAgPSBmYWxzZTsKCQkkY2FzZV9pbnNlbnNpdGl2ZV9oZWFkZXJzID0gbmV3IFJlcXVlc3RzX1V0aWxpdHlfQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSgkaGVhZGVycyk7CgoJCS8vIEhUVFBTIHN1cHBvcnQKCQlpZiAoaXNzZXQoJHVybF9wYXJ0c1snc2NoZW1lJ10pICYmIHN0cnRvbG93ZXIoJHVybF9wYXJ0c1snc2NoZW1lJ10pID09PSAnaHR0cHMnKSB7CgkJCSRyZW1vdGVfc29ja2V0ID0gJ3NzbDovLycgLiAkaG9zdDsKCQkJaWYgKCFpc3NldCgkdXJsX3BhcnRzWydwb3J0J10pKSB7CgkJCQkkdXJsX3BhcnRzWydwb3J0J10gPSA0NDM7CgkJCX0KCgkJCSRjb250ZXh0X29wdGlvbnMgPSBhcnJheSgKCQkJCSd2ZXJpZnlfcGVlcicgICAgICAgPT4gdHJ1ZSwKCQkJCSdjYXB0dXJlX3BlZXJfY2VydCcgPT4gdHJ1ZSwKCQkJKTsKCQkJJHZlcmlmeW5hbWUgICAgICA9IHRydWU7CgoJCQkvLyBTTkksIGlmIGVuYWJsZWQgKE9wZW5TU0wgPj0wLjkuOGopCgkJCS8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5LkNvbnN0YW50cy5OZXdDb25zdGFudHMub3BlbnNzbF90bHNleHRfc2VydmVyX25hbWVGb3VuZAoJCQlpZiAoZGVmaW5lZCgnT1BFTlNTTF9UTFNFWFRfU0VSVkVSX05BTUUnKSAmJiBPUEVOU1NMX1RMU0VYVF9TRVJWRVJfTkFNRSkgewoJCQkJJGNvbnRleHRfb3B0aW9uc1snU05JX2VuYWJsZWQnXSA9IHRydWU7CgkJCQlpZiAoaXNzZXQoJG9wdGlvbnNbJ3ZlcmlmeW5hbWUnXSkgJiYgJG9wdGlvbnNbJ3ZlcmlmeW5hbWUnXSA9PT0gZmFsc2UpIHsKCQkJCQkkY29udGV4dF9vcHRpb25zWydTTklfZW5hYmxlZCddID0gZmFsc2U7CgkJCQl9CgkJCX0KCgkJCWlmIChpc3NldCgkb3B0aW9uc1sndmVyaWZ5J10pKSB7CgkJCQlpZiAoJG9wdGlvbnNbJ3ZlcmlmeSddID09PSBmYWxzZSkgewoJCQkJCSRjb250ZXh0X29wdGlvbnNbJ3ZlcmlmeV9wZWVyJ10gICAgICA9IGZhbHNlOwoJCQkJCSRjb250ZXh0X29wdGlvbnNbJ3ZlcmlmeV9wZWVyX25hbWUnXSA9IGZhbHNlOwoJCQkJCSR2ZXJpZnluYW1lICAgICAgICAgICAgICAgICAgICAgICAgICA9IGZhbHNlOwoJCQkJfQoJCQkJZWxzZWlmIChpc19zdHJpbmcoJG9wdGlvbnNbJ3ZlcmlmeSddKSkgewoJCQkJCSRjb250ZXh0X29wdGlvbnNbJ2NhZmlsZSddID0gJG9wdGlvbnNbJ3ZlcmlmeSddOwoJCQkJfQoJCQl9CgoJCQlpZiAoaXNzZXQoJG9wdGlvbnNbJ3ZlcmlmeW5hbWUnXSkgJiYgJG9wdGlvbnNbJ3ZlcmlmeW5hbWUnXSA9PT0gZmFsc2UpIHsKCQkJCSRjb250ZXh0X29wdGlvbnNbJ3ZlcmlmeV9wZWVyX25hbWUnXSA9IGZhbHNlOwoJCQkJJHZlcmlmeW5hbWUgICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2U7CgkJCX0KCgkJCXN0cmVhbV9jb250ZXh0X3NldF9vcHRpb24oJGNvbnRleHQsIGFycmF5KCdzc2wnID0+ICRjb250ZXh0X29wdGlvbnMpKTsKCQl9CgkJZWxzZSB7CgkJCSRyZW1vdGVfc29ja2V0ID0gJ3RjcDovLycgLiAkaG9zdDsKCQl9CgoJCSR0aGlzLT5tYXhfYnl0ZXMgPSAkb3B0aW9uc1snbWF4X2J5dGVzJ107CgoJCWlmICghaXNzZXQoJHVybF9wYXJ0c1sncG9ydCddKSkgewoJCQkkdXJsX3BhcnRzWydwb3J0J10gPSA4MDsKCQl9CgkJJHJlbW90ZV9zb2NrZXQgLj0gJzonIC4gJHVybF9wYXJ0c1sncG9ydCddOwoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5EZXZlbG9wbWVudEZ1bmN0aW9ucy5lcnJvcl9sb2dfc2V0X2Vycm9yX2hhbmRsZXIKCQlzZXRfZXJyb3JfaGFuZGxlcihhcnJheSgkdGhpcywgJ2Nvbm5lY3RfZXJyb3JfaGFuZGxlcicpLCBFX1dBUk5JTkcgfCBFX05PVElDRSk7CgoJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgnZnNvY2tvcGVuLnJlbW90ZV9zb2NrZXQnLCBhcnJheSgmJHJlbW90ZV9zb2NrZXQpKTsKCgkJJHNvY2tldCA9IHN0cmVhbV9zb2NrZXRfY2xpZW50KCRyZW1vdGVfc29ja2V0LCAkZXJybm8sICRlcnJzdHIsIGNlaWwoJG9wdGlvbnNbJ2Nvbm5lY3RfdGltZW91dCddKSwgU1RSRUFNX0NMSUVOVF9DT05ORUNULCAkY29udGV4dCk7CgoJCXJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKCQlpZiAoJHZlcmlmeW5hbWUgJiYgISR0aGlzLT52ZXJpZnlfY2VydGlmaWNhdGVfZnJvbV9jb250ZXh0KCRob3N0LCAkY29udGV4dCkpIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignU1NMIGNlcnRpZmljYXRlIGRpZCBub3QgbWF0Y2ggdGhlIHJlcXVlc3RlZCBkb21haW4gbmFtZScsICdzc2wubm9fbWF0Y2gnKTsKCQl9CgoJCWlmICghJHNvY2tldCkgewoJCQlpZiAoJGVycm5vID09PSAwKSB7CgkJCQkvLyBDb25uZWN0aW9uIGlzc3VlCgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKHJ0cmltKCR0aGlzLT5jb25uZWN0X2Vycm9yKSwgJ2Zzb2Nrb3Blbi5jb25uZWN0X2Vycm9yJyk7CgkJCX0KCgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJGVycnN0ciwgJ2Zzb2Nrb3BlbmVycm9yJywgbnVsbCwgJGVycm5vKTsKCQl9CgoJCSRkYXRhX2Zvcm1hdCA9ICRvcHRpb25zWydkYXRhX2Zvcm1hdCddOwoKCQlpZiAoJGRhdGFfZm9ybWF0ID09PSAncXVlcnknKSB7CgkJCSRwYXRoID0gc2VsZjo6Zm9ybWF0X2dldCgkdXJsX3BhcnRzLCAkZGF0YSk7CgkJCSRkYXRhID0gJyc7CgkJfQoJCWVsc2UgewoJCQkkcGF0aCA9IHNlbGY6OmZvcm1hdF9nZXQoJHVybF9wYXJ0cywgYXJyYXkoKSk7CgkJfQoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5yZW1vdGVfaG9zdF9wYXRoJywgYXJyYXkoJiRwYXRoLCAkdXJsKSk7CgoJCSRyZXF1ZXN0X2JvZHkgPSAnJzsKCQkkb3V0ICAgICAgICAgID0gc3ByaW50ZigiJXMgJXMgSFRUUC8lLjFGXHJcbiIsICRvcHRpb25zWyd0eXBlJ10sICRwYXRoLCAkb3B0aW9uc1sncHJvdG9jb2xfdmVyc2lvbiddKTsKCgkJaWYgKCRvcHRpb25zWyd0eXBlJ10gIT09IFJlcXVlc3RzOjpUUkFDRSkgewoJCQlpZiAoaXNfYXJyYXkoJGRhdGEpKSB7CgkJCQkkcmVxdWVzdF9ib2R5ID0gaHR0cF9idWlsZF9xdWVyeSgkZGF0YSwgJycsICcmJyk7CgkJCX0KCQkJZWxzZSB7CgkJCQkkcmVxdWVzdF9ib2R5ID0gJGRhdGE7CgkJCX0KCgkJCS8vIEFsd2F5cyBpbmNsdWRlIENvbnRlbnQtbGVuZ3RoIG9uIFBPU1QgcmVxdWVzdHMgdG8gcHJldmVudAoJCQkvLyA0MTEgZXJyb3JzIGZyb20gc29tZSBzZXJ2ZXJzIHdoZW4gdGhlIGJvZHkgaXMgZW1wdHkuCgkJCWlmICghZW1wdHkoJGRhdGEpIHx8ICRvcHRpb25zWyd0eXBlJ10gPT09IFJlcXVlc3RzOjpQT1NUKSB7CgkJCQlpZiAoIWlzc2V0KCRjYXNlX2luc2Vuc2l0aXZlX2hlYWRlcnNbJ0NvbnRlbnQtTGVuZ3RoJ10pKSB7CgkJCQkJJGhlYWRlcnNbJ0NvbnRlbnQtTGVuZ3RoJ10gPSBzdHJsZW4oJHJlcXVlc3RfYm9keSk7CgkJCQl9CgoJCQkJaWYgKCFpc3NldCgkY2FzZV9pbnNlbnNpdGl2ZV9oZWFkZXJzWydDb250ZW50LVR5cGUnXSkpIHsKCQkJCQkkaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04JzsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCFpc3NldCgkY2FzZV9pbnNlbnNpdGl2ZV9oZWFkZXJzWydIb3N0J10pKSB7CgkJCSRvdXQgLj0gc3ByaW50ZignSG9zdDogJXMnLCAkdXJsX3BhcnRzWydob3N0J10pOwoKCQkJaWYgKChzdHJ0b2xvd2VyKCR1cmxfcGFydHNbJ3NjaGVtZSddKSA9PT0gJ2h0dHAnICYmICR1cmxfcGFydHNbJ3BvcnQnXSAhPT0gODApIHx8IChzdHJ0b2xvd2VyKCR1cmxfcGFydHNbJ3NjaGVtZSddKSA9PT0gJ2h0dHBzJyAmJiAkdXJsX3BhcnRzWydwb3J0J10gIT09IDQ0MykpIHsKCQkJCSRvdXQgLj0gJzonIC4gJHVybF9wYXJ0c1sncG9ydCddOwoJCQl9CgkJCSRvdXQgLj0gIlxyXG4iOwoJCX0KCgkJaWYgKCFpc3NldCgkY2FzZV9pbnNlbnNpdGl2ZV9oZWFkZXJzWydVc2VyLUFnZW50J10pKSB7CgkJCSRvdXQgLj0gc3ByaW50ZigiVXNlci1BZ2VudDogJXNcclxuIiwgJG9wdGlvbnNbJ3VzZXJhZ2VudCddKTsKCQl9CgoJCSRhY2NlcHRfZW5jb2RpbmcgPSAkdGhpcy0+YWNjZXB0X2VuY29kaW5nKCk7CgkJaWYgKCFpc3NldCgkY2FzZV9pbnNlbnNpdGl2ZV9oZWFkZXJzWydBY2NlcHQtRW5jb2RpbmcnXSkgJiYgIWVtcHR5KCRhY2NlcHRfZW5jb2RpbmcpKSB7CgkJCSRvdXQgLj0gc3ByaW50ZigiQWNjZXB0LUVuY29kaW5nOiAlc1xyXG4iLCAkYWNjZXB0X2VuY29kaW5nKTsKCQl9CgoJCSRoZWFkZXJzID0gUmVxdWVzdHM6OmZsYXR0ZW4oJGhlYWRlcnMpOwoKCQlpZiAoIWVtcHR5KCRoZWFkZXJzKSkgewoJCQkkb3V0IC49IGltcGxvZGUoIlxyXG4iLCAkaGVhZGVycykgLiAiXHJcbiI7CgkJfQoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5hZnRlcl9oZWFkZXJzJywgYXJyYXkoJiRvdXQpKTsKCgkJaWYgKHN1YnN0cigkb3V0LCAtMikgIT09ICJcclxuIikgewoJCQkkb3V0IC49ICJcclxuIjsKCQl9CgoJCWlmICghaXNzZXQoJGNhc2VfaW5zZW5zaXRpdmVfaGVhZGVyc1snQ29ubmVjdGlvbiddKSkgewoJCQkkb3V0IC49ICJDb25uZWN0aW9uOiBDbG9zZVxyXG4iOwoJCX0KCgkJJG91dCAuPSAiXHJcbiIgLiAkcmVxdWVzdF9ib2R5OwoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5iZWZvcmVfc2VuZCcsIGFycmF5KCYkb3V0KSk7CgoJCWZ3cml0ZSgkc29ja2V0LCAkb3V0KTsKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5hZnRlcl9zZW5kJywgYXJyYXkoJG91dCkpOwoKCQlpZiAoISRvcHRpb25zWydibG9ja2luZyddKSB7CgkJCWZjbG9zZSgkc29ja2V0KTsKCQkJJGZha2VfaGVhZGVycyA9ICcnOwoJCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5hZnRlcl9yZXF1ZXN0JywgYXJyYXkoJiRmYWtlX2hlYWRlcnMpKTsKCQkJcmV0dXJuICcnOwoJCX0KCgkJJHRpbWVvdXRfc2VjID0gKGludCkgZmxvb3IoJG9wdGlvbnNbJ3RpbWVvdXQnXSk7CgkJaWYgKCR0aW1lb3V0X3NlYyA9PT0gJG9wdGlvbnNbJ3RpbWVvdXQnXSkgewoJCQkkdGltZW91dF9tc2VjID0gMDsKCQl9CgkJZWxzZSB7CgkJCSR0aW1lb3V0X21zZWMgPSBzZWxmOjpTRUNPTkRfSU5fTUlDUk9TRUNPTkRTICogJG9wdGlvbnNbJ3RpbWVvdXQnXSAlIHNlbGY6OlNFQ09ORF9JTl9NSUNST1NFQ09ORFM7CgkJfQoJCXN0cmVhbV9zZXRfdGltZW91dCgkc29ja2V0LCAkdGltZW91dF9zZWMsICR0aW1lb3V0X21zZWMpOwoKCQkkcmVzcG9uc2UgICA9ICcnOwoJCSRib2R5ICAgICAgID0gJyc7CgkJJGhlYWRlcnMgICAgPSAnJzsKCQkkdGhpcy0+aW5mbyA9IHN0cmVhbV9nZXRfbWV0YV9kYXRhKCRzb2NrZXQpOwoJCSRzaXplICAgICAgID0gMDsKCQkkZG9pbmdib2R5ICA9IGZhbHNlOwoJCSRkb3dubG9hZCAgID0gZmFsc2U7CgkJaWYgKCRvcHRpb25zWydmaWxlbmFtZSddKSB7CgkJCSRkb3dubG9hZCA9IGZvcGVuKCRvcHRpb25zWydmaWxlbmFtZSddLCAnd2InKTsKCQl9CgoJCXdoaWxlICghZmVvZigkc29ja2V0KSkgewoJCQkkdGhpcy0+aW5mbyA9IHN0cmVhbV9nZXRfbWV0YV9kYXRhKCRzb2NrZXQpOwoJCQlpZiAoJHRoaXMtPmluZm9bJ3RpbWVkX291dCddKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdmc29ja2V0IHRpbWVkIG91dCcsICd0aW1lb3V0Jyk7CgkJCX0KCgkJCSRibG9jayA9IGZyZWFkKCRzb2NrZXQsIFJlcXVlc3RzOjpCVUZGRVJfU0laRSk7CgkJCWlmICghJGRvaW5nYm9keSkgewoJCQkJJHJlc3BvbnNlIC49ICRibG9jazsKCQkJCWlmIChzdHJwb3MoJHJlc3BvbnNlLCAiXHJcblxyXG4iKSkgewoJCQkJCWxpc3QoJGhlYWRlcnMsICRibG9jaykgPSBleHBsb2RlKCJcclxuXHJcbiIsICRyZXNwb25zZSwgMik7CgkJCQkJJGRvaW5nYm9keSAgICAgICAgICAgICA9IHRydWU7CgkJCQl9CgkJCX0KCgkJCS8vIEFyZSB3ZSBpbiBib2R5IG1vZGUgbm93PwoJCQlpZiAoJGRvaW5nYm9keSkgewoJCQkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdyZXF1ZXN0LnByb2dyZXNzJywgYXJyYXkoJGJsb2NrLCAkc2l6ZSwgJHRoaXMtPm1heF9ieXRlcykpOwoJCQkJJGRhdGFfbGVuZ3RoID0gc3RybGVuKCRibG9jayk7CgkJCQlpZiAoJHRoaXMtPm1heF9ieXRlcykgewoJCQkJCS8vIEhhdmUgd2UgYWxyZWFkeSBoaXQgYSBsaW1pdD8KCQkJCQlpZiAoJHNpemUgPT09ICR0aGlzLT5tYXhfYnl0ZXMpIHsKCQkJCQkJY29udGludWU7CgkJCQkJfQoJCQkJCWlmICgoJHNpemUgKyAkZGF0YV9sZW5ndGgpID4gJHRoaXMtPm1heF9ieXRlcykgewoJCQkJCQkvLyBMaW1pdCB0aGUgbGVuZ3RoCgkJCQkJCSRsaW1pdGVkX2xlbmd0aCA9ICgkdGhpcy0+bWF4X2J5dGVzIC0gJHNpemUpOwoJCQkJCQkkYmxvY2sgICAgICAgICAgPSBzdWJzdHIoJGJsb2NrLCAwLCAkbGltaXRlZF9sZW5ndGgpOwoJCQkJCX0KCQkJCX0KCgkJCQkkc2l6ZSArPSBzdHJsZW4oJGJsb2NrKTsKCQkJCWlmICgkZG93bmxvYWQpIHsKCQkJCQlmd3JpdGUoJGRvd25sb2FkLCAkYmxvY2spOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJJGJvZHkgLj0gJGJsb2NrOwoJCQkJfQoJCQl9CgkJfQoJCSR0aGlzLT5oZWFkZXJzID0gJGhlYWRlcnM7CgoJCWlmICgkZG93bmxvYWQpIHsKCQkJZmNsb3NlKCRkb3dubG9hZCk7CgkJfQoJCWVsc2UgewoJCQkkdGhpcy0+aGVhZGVycyAuPSAiXHJcblxyXG4iIC4gJGJvZHk7CgkJfQoJCWZjbG9zZSgkc29ja2V0KTsKCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdmc29ja29wZW4uYWZ0ZXJfcmVxdWVzdCcsIGFycmF5KCYkdGhpcy0+aGVhZGVycywgJiR0aGlzLT5pbmZvKSk7CgkJcmV0dXJuICR0aGlzLT5oZWFkZXJzOwoJfQoKCS8qKgoJICogU2VuZCBtdWx0aXBsZSByZXF1ZXN0cyBzaW11bHRhbmVvdXNseQoJICoKCSAqIEBwYXJhbSBhcnJheSAkcmVxdWVzdHMgUmVxdWVzdCBkYXRhIChhcnJheSBvZiAndXJsJywgJ2hlYWRlcnMnLCAnZGF0YScsICdvcHRpb25zJykgYXMgcGVyIHtAc2VlIFJlcXVlc3RzX1RyYW5zcG9ydDo6cmVxdWVzdH0KCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBHbG9iYWwgb3B0aW9ucywgc2VlIHtAc2VlIFJlcXVlc3RzOjpyZXNwb25zZSgpfSBmb3IgZG9jdW1lbnRhdGlvbgoJICogQHJldHVybiBhcnJheSBBcnJheSBvZiBSZXF1ZXN0c19SZXNwb25zZSBvYmplY3RzIChtYXkgY29udGFpbiBSZXF1ZXN0c19FeGNlcHRpb24gb3Igc3RyaW5nIHJlc3BvbnNlcyBhcyB3ZWxsKQoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVxdWVzdF9tdWx0aXBsZSgkcmVxdWVzdHMsICRvcHRpb25zKSB7CgkJJHJlc3BvbnNlcyA9IGFycmF5KCk7CgkJJGNsYXNzICAgICA9IGdldF9jbGFzcygkdGhpcyk7CgkJZm9yZWFjaCAoJHJlcXVlc3RzIGFzICRpZCA9PiAkcmVxdWVzdCkgewoJCQl0cnkgewoJCQkJJGhhbmRsZXIgICAgICAgID0gbmV3ICRjbGFzcygpOwoJCQkJJHJlc3BvbnNlc1skaWRdID0gJGhhbmRsZXItPnJlcXVlc3QoJHJlcXVlc3RbJ3VybCddLCAkcmVxdWVzdFsnaGVhZGVycyddLCAkcmVxdWVzdFsnZGF0YSddLCAkcmVxdWVzdFsnb3B0aW9ucyddKTsKCgkJCQkkcmVxdWVzdFsnb3B0aW9ucyddWydob29rcyddLT5kaXNwYXRjaCgndHJhbnNwb3J0LmludGVybmFsLnBhcnNlX3Jlc3BvbnNlJywgYXJyYXkoJiRyZXNwb25zZXNbJGlkXSwgJHJlcXVlc3QpKTsKCQkJfQoJCQljYXRjaCAoUmVxdWVzdHNfRXhjZXB0aW9uICRlKSB7CgkJCQkkcmVzcG9uc2VzWyRpZF0gPSAkZTsKCQkJfQoKCQkJaWYgKCFpc19zdHJpbmcoJHJlc3BvbnNlc1skaWRdKSkgewoJCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+ZGlzcGF0Y2goJ211bHRpcGxlLnJlcXVlc3QuY29tcGxldGUnLCBhcnJheSgmJHJlc3BvbnNlc1skaWRdLCAkaWQpKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRyZXNwb25zZXM7Cgl9CgoJLyoqCgkgKiBSZXRyaWV2ZSB0aGUgZW5jb2RpbmdzIHdlIGNhbiBhY2NlcHQKCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBBY2NlcHQtRW5jb2RpbmcgaGVhZGVyIHZhbHVlCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gYWNjZXB0X2VuY29kaW5nKCkgewoJCSR0eXBlID0gYXJyYXkoKTsKCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCdnemluZmxhdGUnKSkgewoJCQkkdHlwZVtdID0gJ2RlZmxhdGU7cT0xLjAnOwoJCX0KCgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnZ3p1bmNvbXByZXNzJykpIHsKCQkJJHR5cGVbXSA9ICdjb21wcmVzcztxPTAuNSc7CgkJfQoKCQkkdHlwZVtdID0gJ2d6aXA7cT0wLjUnOwoKCQlyZXR1cm4gaW1wbG9kZSgnLCAnLCAkdHlwZSk7Cgl9CgoJLyoqCgkgKiBGb3JtYXQgYSBVUkwgZ2l2ZW4gR0VUIGRhdGEKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHVybF9wYXJ0cwoJICogQHBhcmFtIGFycmF5fG9iamVjdCAkZGF0YSBEYXRhIHRvIGJ1aWxkIHF1ZXJ5IHVzaW5nLCBzZWUge0BzZWUgaHR0cHM6Ly9zZWN1cmUucGhwLm5ldC9odHRwX2J1aWxkX3F1ZXJ5fQoJICogQHJldHVybiBzdHJpbmcgVVJMIHdpdGggZGF0YQoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdF9nZXQoJHVybF9wYXJ0cywgJGRhdGEpIHsKCQlpZiAoIWVtcHR5KCRkYXRhKSkgewoJCQlpZiAoZW1wdHkoJHVybF9wYXJ0c1sncXVlcnknXSkpIHsKCQkJCSR1cmxfcGFydHNbJ3F1ZXJ5J10gPSAnJzsKCQkJfQoKCQkJJHVybF9wYXJ0c1sncXVlcnknXSAuPSAnJicgLiBodHRwX2J1aWxkX3F1ZXJ5KCRkYXRhLCAnJywgJyYnKTsKCQkJJHVybF9wYXJ0c1sncXVlcnknXSAgPSB0cmltKCR1cmxfcGFydHNbJ3F1ZXJ5J10sICcmJyk7CgkJfQoJCWlmIChpc3NldCgkdXJsX3BhcnRzWydwYXRoJ10pKSB7CgkJCWlmIChpc3NldCgkdXJsX3BhcnRzWydxdWVyeSddKSkgewoJCQkJJGdldCA9ICR1cmxfcGFydHNbJ3BhdGgnXSAuICc/JyAuICR1cmxfcGFydHNbJ3F1ZXJ5J107CgkJCX0KCQkJZWxzZSB7CgkJCQkkZ2V0ID0gJHVybF9wYXJ0c1sncGF0aCddOwoJCQl9CgkJfQoJCWVsc2UgewoJCQkkZ2V0ID0gJy8nOwoJCX0KCQlyZXR1cm4gJGdldDsKCX0KCgkvKioKCSAqIEVycm9yIGhhbmRsZXIgZm9yIHN0cmVhbV9zb2NrZXRfY2xpZW50KCkKCSAqCgkgKiBAcGFyYW0gaW50ICRlcnJubyBFcnJvciBudW1iZXIgKGUuZy4gRV9XQVJOSU5HKQoJICogQHBhcmFtIHN0cmluZyAkZXJyc3RyIEVycm9yIG1lc3NhZ2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNvbm5lY3RfZXJyb3JfaGFuZGxlcigkZXJybm8sICRlcnJzdHIpIHsKCQkvLyBEb3VibGUtY2hlY2sgd2UgY2FuIGhhbmRsZSBpdAoJCWlmICgoJGVycm5vICYgRV9XQVJOSU5HKSA9PT0gMCAmJiAoJGVycm5vICYgRV9OT1RJQ0UpID09PSAwKSB7CgkJCS8vIFJldHVybiBmYWxzZSB0byBpbmRpY2F0ZSB0aGUgZGVmYXVsdCBlcnJvciBoYW5kbGVyIHNob3VsZCBlbmdhZ2UKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHRoaXMtPmNvbm5lY3RfZXJyb3IgLj0gJGVycnN0ciAuICJcbiI7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBWZXJpZnkgdGhlIGNlcnRpZmljYXRlIGFnYWluc3QgY29tbW9uIG5hbWUgYW5kIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMKCSAqCgkgKiBVbmZvcnR1bmF0ZWx5LCBQSFAgZG9lc24ndCBjaGVjayB0aGUgY2VydGlmaWNhdGUgYWdhaW5zdCB0aGUgYWx0ZXJuYXRpdmUKCSAqIG5hbWVzLCBsZWFkaW5nIHRoaW5ncyBsaWtlICdodHRwczovL3d3dy5naXRodWIuY29tLycgdG8gYmUgaW52YWxpZC4KCSAqIEluc3RlYWQKCSAqCgkgKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyODE4I3NlY3Rpb24tMy4xIFJGQzI4MTgsIFNlY3Rpb24gMy4xCgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gZmFpbHVyZSB0byBjb25uZWN0IHZpYSBUTFMgKGBmc29ja29wZW4uc3NsLmNvbm5lY3RfZXJyb3JgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gbm90IG9idGFpbmluZyBhIG1hdGNoIGZvciB0aGUgaG9zdCAoYGZzb2Nrb3Blbi5zc2wubm9fbWF0Y2hgKQoJICogQHBhcmFtIHN0cmluZyAkaG9zdCBIb3N0IG5hbWUgdG8gdmVyaWZ5IGFnYWluc3QKCSAqIEBwYXJhbSByZXNvdXJjZSAkY29udGV4dCBTdHJlYW0gY29udGV4dAoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB2ZXJpZnlfY2VydGlmaWNhdGVfZnJvbV9jb250ZXh0KCRob3N0LCAkY29udGV4dCkgewoJCSRtZXRhID0gc3RyZWFtX2NvbnRleHRfZ2V0X29wdGlvbnMoJGNvbnRleHQpOwoKCQkvLyBJZiB3ZSBkb24ndCBoYXZlIFNTTCBvcHRpb25zLCB0aGVuIHdlIGNvdWxkbid0IG1ha2UgdGhlIGNvbm5lY3Rpb24gYXQKCQkvLyBhbGwKCQlpZiAoZW1wdHkoJG1ldGEpIHx8IGVtcHR5KCRtZXRhWydzc2wnXSkgfHwgZW1wdHkoJG1ldGFbJ3NzbCddWydwZWVyX2NlcnRpZmljYXRlJ10pKSB7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24ocnRyaW0oJHRoaXMtPmNvbm5lY3RfZXJyb3IpLCAnc3NsLmNvbm5lY3RfZXJyb3InKTsKCQl9CgoJCSRjZXJ0ID0gb3BlbnNzbF94NTA5X3BhcnNlKCRtZXRhWydzc2wnXVsncGVlcl9jZXJ0aWZpY2F0ZSddKTsKCgkJcmV0dXJuIFJlcXVlc3RzX1NTTDo6dmVyaWZ5X2NlcnRpZmljYXRlKCRob3N0LCAkY2VydCk7Cgl9CgoJLyoqCgkgKiBXaGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIHZhbGlkCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQHJldHVybiBib29sZWFuIFRydWUgaWYgdGhlIHRyYW5zcG9ydCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRlc3QoJGNhcGFiaWxpdGllcyA9IGFycmF5KCkpIHsKCQlpZiAoIWZ1bmN0aW9uX2V4aXN0cygnZnNvY2tvcGVuJykpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gSWYgbmVlZGVkLCBjaGVjayB0aGF0IHN0cmVhbXMgc3VwcG9ydCBTU0wKCQlpZiAoaXNzZXQoJGNhcGFiaWxpdGllc1snc3NsJ10pICYmICRjYXBhYmlsaXRpZXNbJ3NzbCddKSB7CgkJCWlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpIHx8ICFmdW5jdGlvbl9leGlzdHMoJ29wZW5zc2xfeDUwOV9wYXJzZScpKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCS8vIEN1cnJlbnRseSBicm9rZW4sIHRoYW5rcyB0byBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svaGh2bS9pc3N1ZXMvMjE1NgoJCQlpZiAoZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9UcmFuc3BvcnRfY1VSTCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9UcmFuc3BvcnQgewoKCWNvbnN0IEVBU1kgID0gJ2NVUkxFYXN5JzsKCWNvbnN0IE1VTFRJID0gJ2NVUkxNdWx0aSc7Cgljb25zdCBTSEFSRSA9ICdjVVJMU2hhcmUnOwoKCS8qKgoJICogY1VSTCBlcnJvciBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IC0xOwoKCS8qKgoJICogV2hpY2ggdHlwZSBvZiBjVVJMIGVycm9yCgkgKgoJICogRUFTWXxNVUxUSXxTSEFSRQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkdHlwZSA9ICdVbmtub3duJzsKCgkvKioKCSAqIENsZWFyIHRleHQgZXJyb3IgbWVzc2FnZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1Vua25vd24nOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJHR5cGUsICRkYXRhID0gbnVsbCwgJGNvZGUgPSAwKSB7CgkJaWYgKCR0eXBlICE9PSBudWxsKSB7CgkJCSR0aGlzLT50eXBlID0gJHR5cGU7CgkJfQoKCQlpZiAoJGNvZGUgIT09IG51bGwpIHsKCQkJJHRoaXMtPmNvZGUgPSAkY29kZTsKCQl9CgoJCWlmICgkbWVzc2FnZSAhPT0gbnVsbCkgewoJCQkkdGhpcy0+cmVhc29uID0gJG1lc3NhZ2U7CgkJfQoKCQkkbWVzc2FnZSA9IHNwcmludGYoJyVkICVzJywgJHRoaXMtPmNvZGUsICR0aGlzLT5yZWFzb24pOwoJCXBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsICR0aGlzLT50eXBlLCAkZGF0YSwgJHRoaXMtPmNvZGUpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBlcnJvciBtZXNzYWdlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRSZWFzb24oKSB7CgkJcmV0dXJuICR0aGlzLT5yZWFzb247Cgl9Cgp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gYmFzZWQgb24gSFRUUCByZXNwb25zZQogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gYmFzZWQgb24gSFRUUCByZXNwb25zZQogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb24gewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDA7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnVW5rbm93bic7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgZXhjZXB0aW9uCgkgKgoJICogVGhlcmUgaXMgbm8gbWVjaGFuaXNtIHRvIHBhc3MgaW4gdGhlIHN0YXR1cyBjb2RlLCBhcyB0aGlzIGlzIHNldCBieSB0aGUKCSAqIHN1YmNsYXNzIHVzZWQuIFJlYXNvbiBwaHJhc2VzIGNhbiB2YXJ5LCBob3dldmVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcmVhc29uIFJlYXNvbiBwaHJhc2UKCSAqIEBwYXJhbSBtaXhlZCAkZGF0YSBBc3NvY2lhdGVkIGRhdGEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRyZWFzb24gPSBudWxsLCAkZGF0YSA9IG51bGwpIHsKCQlpZiAoJHJlYXNvbiAhPT0gbnVsbCkgewoJCQkkdGhpcy0+cmVhc29uID0gJHJlYXNvbjsKCQl9CgoJCSRtZXNzYWdlID0gc3ByaW50ZignJWQgJXMnLCAkdGhpcy0+Y29kZSwgJHRoaXMtPnJlYXNvbik7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJ2h0dHByZXNwb25zZScsICRkYXRhLCAkdGhpcy0+Y29kZSk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHN0YXR1cyBtZXNzYWdlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRSZWFzb24oKSB7CgkJcmV0dXJuICR0aGlzLT5yZWFzb247Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGNvcnJlY3QgZXhjZXB0aW9uIGNsYXNzIGZvciBhIGdpdmVuIGVycm9yIGNvZGUKCSAqCgkgKiBAcGFyYW0gaW50fGJvb2wgJGNvZGUgSFRUUCBzdGF0dXMgY29kZSwgb3IgZmFsc2UgaWYgdW5hdmFpbGFibGUKCSAqIEByZXR1cm4gc3RyaW5nIEV4Y2VwdGlvbiBjbGFzcyBuYW1lIHRvIHVzZQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9jbGFzcygkY29kZSkgewoJCWlmICghJGNvZGUpIHsKCQkJcmV0dXJuICdSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF9Vbmtub3duJzsKCQl9CgoJCSRjbGFzcyA9IHNwcmludGYoJ1JlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXyVkJywgJGNvZGUpOwoJCWlmIChjbGFzc19leGlzdHMoJGNsYXNzKSkgewoJCQlyZXR1cm4gJGNsYXNzOwoJCX0KCgkJcmV0dXJuICdSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF9Vbmtub3duJzsKCX0KfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciB1bmtub3duIHN0YXR1cyByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciB1bmtub3duIHN0YXR1cyByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQX1Vua25vd24gZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXJ8Ym9vbCBDb2RlIGlmIGF2YWlsYWJsZSwgZmFsc2UgaWYgYW4gZXJyb3Igb2NjdXJyZWQKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gMDsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVbmtub3duJzsKCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBleGNlcHRpb24KCSAqCgkgKiBJZiBgJGRhdGFgIGlzIGFuIGluc3RhbmNlIG9mIHtAc2VlIFJlcXVlc3RzX1Jlc3BvbnNlfSwgdXNlcyB0aGUgc3RhdHVzCgkgKiBjb2RlIGZyb20gaXQuIE90aGVyd2lzZSwgc2V0cyBhcyAwCgkgKgoJICogQHBhcmFtIHN0cmluZ3xudWxsICRyZWFzb24gUmVhc29uIHBocmFzZQoJICogQHBhcmFtIG1peGVkICRkYXRhIEFzc29jaWF0ZWQgZGF0YQoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlYXNvbiA9IG51bGwsICRkYXRhID0gbnVsbCkgewoJCWlmICgkZGF0YSBpbnN0YW5jZW9mIFJlcXVlc3RzX1Jlc3BvbnNlKSB7CgkJCSR0aGlzLT5jb2RlID0gJGRhdGEtPnN0YXR1c19jb2RlOwoJCX0KCgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkcmVhc29uLCAkZGF0YSk7Cgl9Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDEwIEdvbmUgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDEwIEdvbmUgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTAgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDEwOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0dvbmUnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQyOCBQcmVjb25kaXRpb24gUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY1ODUKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MjggUHJlY29uZGl0aW9uIFJlcXVpcmVkIHJlc3BvbnNlcwogKgogKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2NTg1CiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MjggZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDI4OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1ByZWNvbmRpdGlvbiBSZXF1aXJlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA5IENvbmZsaWN0IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwOSBDb25mbGljdCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQwOSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MDk7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnQ29uZmxpY3QnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwNCBHYXRld2F5IFRpbWVvdXQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTA0IEdhdGV3YXkgVGltZW91dCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzUwNCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA1MDQ7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnR2F0ZXdheSBUaW1lb3V0JzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTYgUmVxdWVzdGVkIFJhbmdlIE5vdCBTYXRpc2ZpYWJsZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MTYgUmVxdWVzdGVkIFJhbmdlIE5vdCBTYXRpc2ZpYWJsZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQxNiBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MTY7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnUmVxdWVzdGVkIFJhbmdlIE5vdCBTYXRpc2ZpYWJsZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA1IE1ldGhvZCBOb3QgQWxsb3dlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDUgTWV0aG9kIE5vdCBBbGxvd2VkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA1IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwNTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdNZXRob2QgTm90IEFsbG93ZWQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMSBOb3QgSW1wbGVtZW50ZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTAxIE5vdCBJbXBsZW1lbnRlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzUwMSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA1MDE7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnTm90IEltcGxlbWVudGVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA1MDUgSFRUUCBWZXJzaW9uIE5vdCBTdXBwb3J0ZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTA1IEhUVFAgVmVyc2lvbiBOb3QgU3VwcG9ydGVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNTA1IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDUwNTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdIVFRQIFZlcnNpb24gTm90IFN1cHBvcnRlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDE4IEknbSBBIFRlYXBvdCByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjMyNAogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxOCBJJ20gQSBUZWFwb3QgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzIzMjQKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQxOCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MTg7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAiSSdtIEEgVGVhcG90IjsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MDcgUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA3IFByb3h5IEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA3IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwNzsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdQcm94eSBBdXRoZW50aWNhdGlvbiBSZXF1aXJlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAyIFBheW1lbnQgUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAyIFBheW1lbnQgUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDIgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDAyOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1BheW1lbnQgUmVxdWlyZWQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNSBVbnN1cHBvcnRlZCBNZWRpYSBUeXBlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNSBVbnN1cHBvcnRlZCBNZWRpYSBUeXBlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDE1IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQxNTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVbnN1cHBvcnRlZCBNZWRpYSBUeXBlJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MDQgTm90IEZvdW5kIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwNCBOb3QgRm91bmQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDQgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDA0OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ05vdCBGb3VuZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA4IFJlcXVlc3QgVGltZW91dCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDggUmVxdWVzdCBUaW1lb3V0IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA4IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwODsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdSZXF1ZXN0IFRpbWVvdXQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQzMSBSZXF1ZXN0IEhlYWRlciBGaWVsZHMgVG9vIExhcmdlIHJlc3BvbnNlcwogKgogKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2NTg1CiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDMxIFJlcXVlc3QgSGVhZGVyIEZpZWxkcyBUb28gTGFyZ2UgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY1ODUKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQzMSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MzE7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAzIEZvcmJpZGRlbiByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDMgRm9yYmlkZGVuIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDAzIGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwMzsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdGb3JiaWRkZW4nOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwMCBCYWQgUmVxdWVzdCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDAgQmFkIFJlcXVlc3QgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDAgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDAwOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0JhZCBSZXF1ZXN0JzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciAzMDYgU3dpdGNoIFByb3h5IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDMwNiBTd2l0Y2ggUHJveHkgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF8zMDYgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gMzA2OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1N3aXRjaCBQcm94eSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTExIE5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY1ODUKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA1MTEgTmV0d29yayBBdXRoZW50aWNhdGlvbiBSZXF1aXJlZCByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjU4NQogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNTExIGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDUxMTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdOZXR3b3JrIEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA1MDMgU2VydmljZSBVbmF2YWlsYWJsZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA1MDMgU2VydmljZSBVbmF2YWlsYWJsZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzUwMyBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA1MDM7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnU2VydmljZSBVbmF2YWlsYWJsZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAxIFVuYXV0aG9yaXplZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDEgVW5hdXRob3JpemVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDAxIGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwMTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVbmF1dGhvcml6ZWQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMiBCYWQgR2F0ZXdheSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA1MDIgQmFkIEdhdGV3YXkgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF81MDIgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNTAyOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0JhZCBHYXRld2F5JzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTMgUmVxdWVzdCBFbnRpdHkgVG9vIExhcmdlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxMyBSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTMgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDEzOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDE0IFJlcXVlc3QtVVJJIFRvbyBMYXJnZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MTQgUmVxdWVzdC1VUkkgVG9vIExhcmdlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDE0IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQxNDsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdSZXF1ZXN0LVVSSSBUb28gTGFyZ2UnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDMwNCBOb3QgTW9kaWZpZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgMzA0IE5vdCBNb2RpZmllZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzMwNCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSAzMDQ7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnTm90IE1vZGlmaWVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTIgUHJlY29uZGl0aW9uIEZhaWxlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MTIgUHJlY29uZGl0aW9uIEZhaWxlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQxMiBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MTI7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnUHJlY29uZGl0aW9uIEZhaWxlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgMzA1IFVzZSBQcm94eSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciAzMDUgVXNlIFByb3h5IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfMzA1IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDMwNTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVc2UgUHJveHknOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMCBJbnRlcm5hbCBTZXJ2ZXIgRXJyb3IgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTAwIEludGVybmFsIFNlcnZlciBFcnJvciByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzUwMCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA1MDA7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnSW50ZXJuYWwgU2VydmVyIEVycm9yJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTEgTGVuZ3RoIFJlcXVpcmVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxMSBMZW5ndGggUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTEgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDExOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0xlbmd0aCBSZXF1aXJlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDI5IFRvbyBNYW55IFJlcXVlc3RzIHJlc3BvbnNlcwogKgogKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9kcmFmdC1ub3R0aW5naGFtLWh0dHAtbmV3LXN0YXR1cy0wNAogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQyOSBUb28gTWFueSBSZXF1ZXN0cyByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvZHJhZnQtbm90dGluZ2hhbS1odHRwLW5ldy1zdGF0dXMtMDQKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQyOSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0Mjk7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnVG9vIE1hbnkgUmVxdWVzdHMnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwNiBOb3QgQWNjZXB0YWJsZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDYgTm90IEFjY2VwdGFibGUgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDYgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDA2OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ05vdCBBY2NlcHRhYmxlJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTcgRXhwZWN0YXRpb24gRmFpbGVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNyBFeHBlY3RhdGlvbiBGYWlsZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTcgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDE3OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0V4cGVjdGF0aW9uIEZhaWxlZCc7Cn0KPD9waHAKCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9UcmFuc3BvcnQgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb24gewoKfQo8P3BocAovKioKICogQmFzaWMgQXV0aGVudGljYXRpb24gcHJvdmlkZXIKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQXV0aGVudGljYXRpb24KICovCgovKioKICogQmFzaWMgQXV0aGVudGljYXRpb24gcHJvdmlkZXIKICoKICogUHJvdmlkZXMgYSBoYW5kbGVyIGZvciBCYXNpYyBIVFRQIGF1dGhlbnRpY2F0aW9uIHZpYSB0aGUgQXV0aG9yaXphdGlvbgogKiBoZWFkZXIuCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIEF1dGhlbnRpY2F0aW9uCiAqLwpjbGFzcyBSZXF1ZXN0c19BdXRoX0Jhc2ljIGltcGxlbWVudHMgUmVxdWVzdHNfQXV0aCB7CgkvKioKCSAqIFVzZXJuYW1lCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICR1c2VyOwoKCS8qKgoJICogUGFzc3dvcmQKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHBhc3M7CgoJLyoqCgkgKiBDb25zdHJ1Y3RvcgoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGluY29ycmVjdCBudW1iZXIgb2YgYXJndW1lbnRzIChgYXV0aGJhc2ljYmFkYXJnc2ApCgkgKiBAcGFyYW0gYXJyYXl8bnVsbCAkYXJncyBBcnJheSBvZiB1c2VyIGFuZCBwYXNzd29yZC4gTXVzdCBoYXZlIGV4YWN0bHkgdHdvIGVsZW1lbnRzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYXJncyA9IG51bGwpIHsKCQlpZiAoaXNfYXJyYXkoJGFyZ3MpKSB7CgkJCWlmIChjb3VudCgkYXJncykgIT09IDIpIHsKCQkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0ludmFsaWQgbnVtYmVyIG9mIGFyZ3VtZW50cycsICdhdXRoYmFzaWNiYWRhcmdzJyk7CgkJCX0KCgkJCWxpc3QoJHRoaXMtPnVzZXIsICR0aGlzLT5wYXNzKSA9ICRhcmdzOwoJCX0KCX0KCgkvKioKCSAqIFJlZ2lzdGVyIHRoZSBuZWNlc3NhcnkgY2FsbGJhY2tzCgkgKgoJICogQHNlZSBjdXJsX2JlZm9yZV9zZW5kCgkgKiBAc2VlIGZzb2Nrb3Blbl9oZWFkZXIKCSAqIEBwYXJhbSBSZXF1ZXN0c19Ib29rcyAkaG9va3MgSG9vayBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tzICRob29rcykgewoJCSRob29rcy0+cmVnaXN0ZXIoJ2N1cmwuYmVmb3JlX3NlbmQnLCBhcnJheSgkdGhpcywgJ2N1cmxfYmVmb3JlX3NlbmQnKSk7CgkJJGhvb2tzLT5yZWdpc3RlcignZnNvY2tvcGVuLmFmdGVyX2hlYWRlcnMnLCBhcnJheSgkdGhpcywgJ2Zzb2Nrb3Blbl9oZWFkZXInKSk7Cgl9CgoJLyoqCgkgKiBTZXQgY1VSTCBwYXJhbWV0ZXJzIGJlZm9yZSB0aGUgZGF0YSBpcyBzZW50CgkgKgoJICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUgY1VSTCByZXNvdXJjZQoJICovCglwdWJsaWMgZnVuY3Rpb24gY3VybF9iZWZvcmVfc2VuZCgmJGhhbmRsZSkgewoJCWN1cmxfc2V0b3B0KCRoYW5kbGUsIENVUkxPUFRfSFRUUEFVVEgsIENVUkxBVVRIX0JBU0lDKTsKCQljdXJsX3NldG9wdCgkaGFuZGxlLCBDVVJMT1BUX1VTRVJQV0QsICR0aGlzLT5nZXRBdXRoU3RyaW5nKCkpOwoJfQoKCS8qKgoJICogQWRkIGV4dHJhIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3QgYmVmb3JlIHNlbmRpbmcKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRvdXQgSFRUUCBoZWFkZXIgc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmc29ja29wZW5faGVhZGVyKCYkb3V0KSB7CgkJJG91dCAuPSBzcHJpbnRmKCJBdXRob3JpemF0aW9uOiBCYXNpYyAlc1xyXG4iLCBiYXNlNjRfZW5jb2RlKCR0aGlzLT5nZXRBdXRoU3RyaW5nKCkpKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgYXV0aGVudGljYXRpb24gc3RyaW5nICh1c2VyOnBhc3MpCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEF1dGhTdHJpbmcoKSB7CgkJcmV0dXJuICR0aGlzLT51c2VyIC4gJzonIC4gJHRoaXMtPnBhc3M7Cgl9Cn0KPD9waHAKLyoqCiAqIEF1dGhlbnRpY2F0aW9uIHByb3ZpZGVyIGludGVyZmFjZQogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBBdXRoZW50aWNhdGlvbgogKi8KCi8qKgogKiBBdXRoZW50aWNhdGlvbiBwcm92aWRlciBpbnRlcmZhY2UKICoKICogSW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIHRvIGFjdCBhcyBhbiBhdXRoZW50aWNhdGlvbiBwcm92aWRlci4KICoKICogUGFyYW1ldGVycyBzaG91bGQgYmUgcGFzc2VkIHZpYSB0aGUgY29uc3RydWN0b3Igd2hlcmUgcG9zc2libGUsIGFzIHRoaXMKICogbWFrZXMgaXQgbXVjaCBlYXNpZXIgZm9yIHVzZXJzIHRvIHVzZSB5b3VyIHByb3ZpZGVyLgogKgogKiBAc2VlIFJlcXVlc3RzX0hvb2tzCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIEF1dGhlbnRpY2F0aW9uCiAqLwppbnRlcmZhY2UgUmVxdWVzdHNfQXV0aCB7CgkvKioKCSAqIFJlZ2lzdGVyIGhvb2tzIGFzIG5lZWRlZAoJICoKCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBpbiB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0gd2hlbiB0aGUgdXNlciBoYXMgc2V0CgkgKiBhbiBpbnN0YW5jZSBhcyB0aGUgJ2F1dGgnIG9wdGlvbi4gVXNlIHRoaXMgY2FsbGJhY2sgdG8gcmVnaXN0ZXIgYWxsIHRoZQoJICogaG9va3MgeW91J2xsIG5lZWQuCgkgKgoJICogQHNlZSBSZXF1ZXN0c19Ib29rczo6cmVnaXN0ZXIKCSAqIEBwYXJhbSBSZXF1ZXN0c19Ib29rcyAkaG9va3MgSG9vayBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tzICRob29rcyk7Cn0KPD9waHAKLyoqCiAqIEhUVFAgUHJveHkgY29ubmVjdGlvbiBpbnRlcmZhY2UKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgUHJveHkKICogQHNpbmNlIDEuNgogKi8KCi8qKgogKiBIVFRQIFByb3h5IGNvbm5lY3Rpb24gaW50ZXJmYWNlCiAqCiAqIFByb3ZpZGVzIGEgaGFuZGxlciBmb3IgY29ubmVjdGlvbiB2aWEgYW4gSFRUUCBwcm94eQogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBQcm94eQogKiBAc2luY2UgMS42CiAqLwpjbGFzcyBSZXF1ZXN0c19Qcm94eV9IVFRQIGltcGxlbWVudHMgUmVxdWVzdHNfUHJveHkgewoJLyoqCgkgKiBQcm94eSBob3N0IGFuZCBwb3J0CgkgKgoJICogTm90YXRpb246ICJob3N0OnBvcnQiIChlZyAxMjcuMC4wLjE6ODA4MCBvciBzb21lcHJveHkuY29tOjMxMjgpCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRwcm94eTsKCgkvKioKCSAqIFVzZXJuYW1lCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICR1c2VyOwoKCS8qKgoJICogUGFzc3dvcmQKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHBhc3M7CgoJLyoqCgkgKiBEbyB3ZSBuZWVkIHRvIGF1dGhlbnRpY2F0ZT8gKGllIHVzZXJuYW1lICYgcGFzc3dvcmQgaGF2ZSBiZWVuIHByb3ZpZGVkKQoJICoKCSAqIEB2YXIgYm9vbGVhbgoJICovCglwdWJsaWMgJHVzZV9hdXRoZW50aWNhdGlvbjsKCgkvKioKCSAqIENvbnN0cnVjdG9yCgkgKgoJICogQHNpbmNlIDEuNgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gaW5jb3JyZWN0IG51bWJlciBvZiBhcmd1bWVudHMgKGBhdXRoYmFzaWNiYWRhcmdzYCkKCSAqIEBwYXJhbSBhcnJheXxudWxsICRhcmdzIEFycmF5IG9mIHVzZXIgYW5kIHBhc3N3b3JkLiBNdXN0IGhhdmUgZXhhY3RseSB0d28gZWxlbWVudHMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRhcmdzID0gbnVsbCkgewoJCWlmIChpc19zdHJpbmcoJGFyZ3MpKSB7CgkJCSR0aGlzLT5wcm94eSA9ICRhcmdzOwoJCX0KCQllbHNlaWYgKGlzX2FycmF5KCRhcmdzKSkgewoJCQlpZiAoY291bnQoJGFyZ3MpID09PSAxKSB7CgkJCQlsaXN0KCR0aGlzLT5wcm94eSkgPSAkYXJnczsKCQkJfQoJCQllbHNlaWYgKGNvdW50KCRhcmdzKSA9PT0gMykgewoJCQkJbGlzdCgkdGhpcy0+cHJveHksICR0aGlzLT51c2VyLCAkdGhpcy0+cGFzcykgPSAkYXJnczsKCQkJCSR0aGlzLT51c2VfYXV0aGVudGljYXRpb24gICAgICAgICAgICAgICAgICAgID0gdHJ1ZTsKCQkJfQoJCQllbHNlIHsKCQkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0ludmFsaWQgbnVtYmVyIG9mIGFyZ3VtZW50cycsICdwcm94eWh0dHBiYWRhcmdzJyk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZWdpc3RlciB0aGUgbmVjZXNzYXJ5IGNhbGxiYWNrcwoJICoKCSAqIEBzaW5jZSAxLjYKCSAqIEBzZWUgY3VybF9iZWZvcmVfc2VuZAoJICogQHNlZSBmc29ja29wZW5fcmVtb3RlX3NvY2tldAoJICogQHNlZSBmc29ja29wZW5fcmVtb3RlX2hvc3RfcGF0aAoJICogQHNlZSBmc29ja29wZW5faGVhZGVyCgkgKiBAcGFyYW0gUmVxdWVzdHNfSG9va3MgJGhvb2tzIEhvb2sgc3lzdGVtCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZWdpc3RlcihSZXF1ZXN0c19Ib29rcyAkaG9va3MpIHsKCQkkaG9va3MtPnJlZ2lzdGVyKCdjdXJsLmJlZm9yZV9zZW5kJywgYXJyYXkoJHRoaXMsICdjdXJsX2JlZm9yZV9zZW5kJykpOwoKCQkkaG9va3MtPnJlZ2lzdGVyKCdmc29ja29wZW4ucmVtb3RlX3NvY2tldCcsIGFycmF5KCR0aGlzLCAnZnNvY2tvcGVuX3JlbW90ZV9zb2NrZXQnKSk7CgkJJGhvb2tzLT5yZWdpc3RlcignZnNvY2tvcGVuLnJlbW90ZV9ob3N0X3BhdGgnLCBhcnJheSgkdGhpcywgJ2Zzb2Nrb3Blbl9yZW1vdGVfaG9zdF9wYXRoJykpOwoJCWlmICgkdGhpcy0+dXNlX2F1dGhlbnRpY2F0aW9uKSB7CgkJCSRob29rcy0+cmVnaXN0ZXIoJ2Zzb2Nrb3Blbi5hZnRlcl9oZWFkZXJzJywgYXJyYXkoJHRoaXMsICdmc29ja29wZW5faGVhZGVyJykpOwoJCX0KCX0KCgkvKioKCSAqIFNldCBjVVJMIHBhcmFtZXRlcnMgYmVmb3JlIHRoZSBkYXRhIGlzIHNlbnQKCSAqCgkgKiBAc2luY2UgMS42CgkgKiBAcGFyYW0gcmVzb3VyY2UgJGhhbmRsZSBjVVJMIHJlc291cmNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjdXJsX2JlZm9yZV9zZW5kKCYkaGFuZGxlKSB7CgkJY3VybF9zZXRvcHQoJGhhbmRsZSwgQ1VSTE9QVF9QUk9YWVRZUEUsIENVUkxQUk9YWV9IVFRQKTsKCQljdXJsX3NldG9wdCgkaGFuZGxlLCBDVVJMT1BUX1BST1hZLCAkdGhpcy0+cHJveHkpOwoKCQlpZiAoJHRoaXMtPnVzZV9hdXRoZW50aWNhdGlvbikgewoJCQljdXJsX3NldG9wdCgkaGFuZGxlLCBDVVJMT1BUX1BST1hZQVVUSCwgQ1VSTEFVVEhfQU5ZKTsKCQkJY3VybF9zZXRvcHQoJGhhbmRsZSwgQ1VSTE9QVF9QUk9YWVVTRVJQV0QsICR0aGlzLT5nZXRfYXV0aF9zdHJpbmcoKSk7CgkJfQoJfQoKCS8qKgoJICogQWx0ZXIgcmVtb3RlIHNvY2tldCBpbmZvcm1hdGlvbiBiZWZvcmUgb3BlbmluZyBzb2NrZXQgY29ubmVjdGlvbgoJICoKCSAqIEBzaW5jZSAxLjYKCSAqIEBwYXJhbSBzdHJpbmcgJHJlbW90ZV9zb2NrZXQgU29ja2V0IGNvbm5lY3Rpb24gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmc29ja29wZW5fcmVtb3RlX3NvY2tldCgmJHJlbW90ZV9zb2NrZXQpIHsKCQkkcmVtb3RlX3NvY2tldCA9ICR0aGlzLT5wcm94eTsKCX0KCgkvKioKCSAqIEFsdGVyIHJlbW90ZSBwYXRoIGJlZm9yZSBnZXR0aW5nIHN0cmVhbSBkYXRhCgkgKgoJICogQHNpbmNlIDEuNgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBQYXRoIHRvIHNlbmQgaW4gSFRUUCByZXF1ZXN0IHN0cmluZyAoIkdFVCAuLi4iKQoJICogQHBhcmFtIHN0cmluZyAkdXJsIEZ1bGwgVVJMIHdlJ3JlIHJlcXVlc3RpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZzb2Nrb3Blbl9yZW1vdGVfaG9zdF9wYXRoKCYkcGF0aCwgJHVybCkgewoJCSRwYXRoID0gJHVybDsKCX0KCgkvKioKCSAqIEFkZCBleHRyYSBoZWFkZXJzIHRvIHRoZSByZXF1ZXN0IGJlZm9yZSBzZW5kaW5nCgkgKgoJICogQHNpbmNlIDEuNgoJICogQHBhcmFtIHN0cmluZyAkb3V0IEhUVFAgaGVhZGVyIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZnNvY2tvcGVuX2hlYWRlcigmJG91dCkgewoJCSRvdXQgLj0gc3ByaW50ZigiUHJveHktQXV0aG9yaXphdGlvbjogQmFzaWMgJXNcclxuIiwgYmFzZTY0X2VuY29kZSgkdGhpcy0+Z2V0X2F1dGhfc3RyaW5nKCkpKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgYXV0aGVudGljYXRpb24gc3RyaW5nICh1c2VyOnBhc3MpCgkgKgoJICogQHNpbmNlIDEuNgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9hdXRoX3N0cmluZygpIHsKCQlyZXR1cm4gJHRoaXMtPnVzZXIgLiAnOicgLiAkdGhpcy0+cGFzczsKCX0KfQo8P3BocAovKioKICogQ2xhc3MgdG8gdmFsaWRhdGUgYW5kIHRvIHdvcmsgd2l0aCBJUHY2IGFkZHJlc3NlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogQ2xhc3MgdG8gdmFsaWRhdGUgYW5kIHRvIHdvcmsgd2l0aCBJUHY2IGFkZHJlc3NlcwogKgogKiBUaGlzIHdhcyBvcmlnaW5hbGx5IGJhc2VkIG9uIHRoZSBQRUFSIGNsYXNzIG9mIHRoZSBzYW1lIG5hbWUsIGJ1dCBoYXMgYmVlbgogKiBlbnRpcmVseSByZXdyaXR0ZW4uCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KY2xhc3MgUmVxdWVzdHNfSVB2NiB7CgkvKioKCSAqIFVuY29tcHJlc3NlcyBhbiBJUHY2IGFkZHJlc3MKCSAqCgkgKiBSRkMgNDI5MSBhbGxvd3MgeW91IHRvIGNvbXByZXNzIGNvbnNlY3V0aXZlIHplcm8gcGllY2VzIGluIGFuIGFkZHJlc3MgdG8KCSAqICc6OicuIFRoaXMgbWV0aG9kIGV4cGVjdHMgYSB2YWxpZCBJUHY2IGFkZHJlc3MgYW5kIGV4cGFuZHMgdGhlICc6OicgdG8KCSAqIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgemVybyBwaWVjZXMuCgkgKgoJICogRXhhbXBsZTogIEZGMDE6OjEwMSAgIC0+ICBGRjAxOjA6MDowOjA6MDowOjEwMQoJICogICAgICAgICAgIDo6MSAgICAgICAgIC0+ICAwOjA6MDowOjA6MDowOjEKCSAqCgkgKiBAYXV0aG9yIEFsZXhhbmRlciBNZXJ6IDxhbGV4YW5kZXIubWVyekB3ZWIuZGU+CgkgKiBAYXV0aG9yIGVsZnJpbmsgYXQgaW50cm93ZWIgZG90IG5sCgkgKiBAYXV0aG9yIEpvc2ggUGVjayA8am1wIGF0IGpvc2hwZWNrIGRvdCBvcmc+CgkgKiBAY29weXJpZ2h0IDIwMDMtMjAwNSBUaGUgUEhQIEdyb3VwCgkgKiBAbGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2JzZC1saWNlbnNlLnBocAoJICogQHBhcmFtIHN0cmluZyAkaXAgQW4gSVB2NiBhZGRyZXNzCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgdW5jb21wcmVzc2VkIElQdjYgYWRkcmVzcwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHVuY29tcHJlc3MoJGlwKSB7CgkJaWYgKHN1YnN0cl9jb3VudCgkaXAsICc6OicpICE9PSAxKSB7CgkJCXJldHVybiAkaXA7CgkJfQoKCQlsaXN0KCRpcDEsICRpcDIpID0gZXhwbG9kZSgnOjonLCAkaXApOwoJCSRjMSAgICAgICAgICAgICAgPSAoJGlwMSA9PT0gJycpID8gLTEgOiBzdWJzdHJfY291bnQoJGlwMSwgJzonKTsKCQkkYzIgICAgICAgICAgICAgID0gKCRpcDIgPT09ICcnKSA/IC0xIDogc3Vic3RyX2NvdW50KCRpcDIsICc6Jyk7CgoJCWlmIChzdHJwb3MoJGlwMiwgJy4nKSAhPT0gZmFsc2UpIHsKCQkJJGMyKys7CgkJfQoJCS8vIDo6CgkJaWYgKCRjMSA9PT0gLTEgJiYgJGMyID09PSAtMSkgewoJCQkkaXAgPSAnMDowOjA6MDowOjA6MDowJzsKCQl9CgkJLy8gOjp4eHgKCQllbHNlaWYgKCRjMSA9PT0gLTEpIHsKCQkJJGZpbGwgPSBzdHJfcmVwZWF0KCcwOicsIDcgLSAkYzIpOwoJCQkkaXAgICA9IHN0cl9yZXBsYWNlKCc6OicsICRmaWxsLCAkaXApOwoJCX0KCQkvLyB4eHg6OgoJCWVsc2VpZiAoJGMyID09PSAtMSkgewoJCQkkZmlsbCA9IHN0cl9yZXBlYXQoJzowJywgNyAtICRjMSk7CgkJCSRpcCAgID0gc3RyX3JlcGxhY2UoJzo6JywgJGZpbGwsICRpcCk7CgkJfQoJCS8vIHh4eDo6eHh4CgkJZWxzZSB7CgkJCSRmaWxsID0gJzonIC4gc3RyX3JlcGVhdCgnMDonLCA2IC0gJGMyIC0gJGMxKTsKCQkJJGlwICAgPSBzdHJfcmVwbGFjZSgnOjonLCAkZmlsbCwgJGlwKTsKCQl9CgkJcmV0dXJuICRpcDsKCX0KCgkvKioKCSAqIENvbXByZXNzZXMgYW4gSVB2NiBhZGRyZXNzCgkgKgoJICogUkZDIDQyOTEgYWxsb3dzIHlvdSB0byBjb21wcmVzcyBjb25zZWN1dGl2ZSB6ZXJvIHBpZWNlcyBpbiBhbiBhZGRyZXNzIHRvCgkgKiAnOjonLiBUaGlzIG1ldGhvZCBleHBlY3RzIGEgdmFsaWQgSVB2NiBhZGRyZXNzIGFuZCBjb21wcmVzc2VzIGNvbnNlY3V0aXZlCgkgKiB6ZXJvIHBpZWNlcyB0byAnOjonLgoJICoKCSAqIEV4YW1wbGU6ICBGRjAxOjA6MDowOjA6MDowOjEwMSAgIC0+ICBGRjAxOjoxMDEKCSAqICAgICAgICAgICAwOjA6MDowOjA6MDowOjEgICAgICAgIC0+ICA6OjEKCSAqCgkgKiBAc2VlIHVuY29tcHJlc3MoKQoJICogQHBhcmFtIHN0cmluZyAkaXAgQW4gSVB2NiBhZGRyZXNzCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgY29tcHJlc3NlZCBJUHY2IGFkZHJlc3MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb21wcmVzcygkaXApIHsKCQkvLyBQcmVwYXJlIHRoZSBJUCB0byBiZSBjb21wcmVzc2VkCgkJJGlwICAgICAgID0gc2VsZjo6dW5jb21wcmVzcygkaXApOwoJCSRpcF9wYXJ0cyA9IHNlbGY6OnNwbGl0X3Y2X3Y0KCRpcCk7CgoJCS8vIFJlcGxhY2UgYWxsIGxlYWRpbmcgemVyb3MKCQkkaXBfcGFydHNbMF0gPSBwcmVnX3JlcGxhY2UoJy8oXnw6KTArKFswLTldKS8nLCAnXDFcMicsICRpcF9wYXJ0c1swXSk7CgoJCS8vIEZpbmQgYnVuY2hlcyBvZiB6ZXJvcwoJCWlmIChwcmVnX21hdGNoX2FsbCgnLyg/Ol58OikoPzowKD86OnwkKSkrLycsICRpcF9wYXJ0c1swXSwgJG1hdGNoZXMsIFBSRUdfT0ZGU0VUX0NBUFRVUkUpKSB7CgkJCSRtYXggPSAwOwoJCQkkcG9zID0gbnVsbDsKCQkJZm9yZWFjaCAoJG1hdGNoZXNbMF0gYXMgJG1hdGNoKSB7CgkJCQlpZiAoc3RybGVuKCRtYXRjaFswXSkgPiAkbWF4KSB7CgkJCQkJJG1heCA9IHN0cmxlbigkbWF0Y2hbMF0pOwoJCQkJCSRwb3MgPSAkbWF0Y2hbMV07CgkJCQl9CgkJCX0KCgkJCSRpcF9wYXJ0c1swXSA9IHN1YnN0cl9yZXBsYWNlKCRpcF9wYXJ0c1swXSwgJzo6JywgJHBvcywgJG1heCk7CgkJfQoKCQlpZiAoJGlwX3BhcnRzWzFdICE9PSAnJykgewoJCQlyZXR1cm4gaW1wbG9kZSgnOicsICRpcF9wYXJ0cyk7CgkJfQoJCWVsc2UgewoJCQlyZXR1cm4gJGlwX3BhcnRzWzBdOwoJCX0KCX0KCgkvKioKCSAqIFNwbGl0cyBhbiBJUHY2IGFkZHJlc3MgaW50byB0aGUgSVB2NiBhbmQgSVB2NCByZXByZXNlbnRhdGlvbiBwYXJ0cwoJICoKCSAqIFJGQyA0MjkxIGFsbG93cyB5b3UgdG8gcmVwcmVzZW50IHRoZSBsYXN0IHR3byBwYXJ0cyBvZiBhbiBJUHY2IGFkZHJlc3MKCSAqIHVzaW5nIHRoZSBzdGFuZGFyZCBJUHY0IHJlcHJlc2VudGF0aW9uCgkgKgoJICogRXhhbXBsZTogIDA6MDowOjA6MDowOjEzLjEuNjguMwoJICogICAgICAgICAgIDA6MDowOjA6MDpGRkZGOjEyOS4xNDQuNTIuMzgKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRpcCBBbiBJUHY2IGFkZHJlc3MKCSAqIEByZXR1cm4gc3RyaW5nW10gWzBdIGNvbnRhaW5zIHRoZSBJUHY2IHJlcHJlc2VudGVkIHBhcnQsIGFuZCBbMV0gdGhlIElQdjQgcmVwcmVzZW50ZWQgcGFydAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHNwbGl0X3Y2X3Y0KCRpcCkgewoJCWlmIChzdHJwb3MoJGlwLCAnLicpICE9PSBmYWxzZSkgewoJCQkkcG9zICAgICAgID0gc3RycnBvcygkaXAsICc6Jyk7CgkJCSRpcHY2X3BhcnQgPSBzdWJzdHIoJGlwLCAwLCAkcG9zKTsKCQkJJGlwdjRfcGFydCA9IHN1YnN0cigkaXAsICRwb3MgKyAxKTsKCQkJcmV0dXJuIGFycmF5KCRpcHY2X3BhcnQsICRpcHY0X3BhcnQpOwoJCX0KCQllbHNlIHsKCQkJcmV0dXJuIGFycmF5KCRpcCwgJycpOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyBhbiBJUHY2IGFkZHJlc3MKCSAqCgkgKiBDaGVja3MgaWYgdGhlIGdpdmVuIElQIGlzIGEgdmFsaWQgSVB2NiBhZGRyZXNzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXAgQW4gSVB2NiBhZGRyZXNzCgkgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiAkaXAgaXMgYSB2YWxpZCBJUHY2IGFkZHJlc3MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVja19pcHY2KCRpcCkgewoJCSRpcCAgICAgICAgICAgICAgICA9IHNlbGY6OnVuY29tcHJlc3MoJGlwKTsKCQlsaXN0KCRpcHY2LCAkaXB2NCkgPSBzZWxmOjpzcGxpdF92Nl92NCgkaXApOwoJCSRpcHY2ICAgICAgICAgICAgICA9IGV4cGxvZGUoJzonLCAkaXB2Nik7CgkJJGlwdjQgICAgICAgICAgICAgID0gZXhwbG9kZSgnLicsICRpcHY0KTsKCQlpZiAoY291bnQoJGlwdjYpID09PSA4ICYmIGNvdW50KCRpcHY0KSA9PT0gMSB8fCBjb3VudCgkaXB2NikgPT09IDYgJiYgY291bnQoJGlwdjQpID09PSA0KSB7CgkJCWZvcmVhY2ggKCRpcHY2IGFzICRpcHY2X3BhcnQpIHsKCQkJCS8vIFRoZSBzZWN0aW9uIGNhbid0IGJlIGVtcHR5CgkJCQlpZiAoJGlwdjZfcGFydCA9PT0gJycpIHsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgoJCQkJLy8gTm9yIGNhbiBpdCBiZSBvdmVyIGZvdXIgY2hhcmFjdGVycwoJCQkJaWYgKHN0cmxlbigkaXB2Nl9wYXJ0KSA+IDQpIHsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgoJCQkJLy8gUmVtb3ZlIGxlYWRpbmcgemVyb3MgKHRoaXMgaXMgc2FmZSBiZWNhdXNlIG9mIHRoZSBhYm92ZSkKCQkJCSRpcHY2X3BhcnQgPSBsdHJpbSgkaXB2Nl9wYXJ0LCAnMCcpOwoJCQkJaWYgKCRpcHY2X3BhcnQgPT09ICcnKSB7CgkJCQkJJGlwdjZfcGFydCA9ICcwJzsKCQkJCX0KCgkJCQkvLyBDaGVjayB0aGUgdmFsdWUgaXMgdmFsaWQKCQkJCSR2YWx1ZSA9IGhleGRlYygkaXB2Nl9wYXJ0KTsKCQkJCWlmIChkZWNoZXgoJHZhbHVlKSAhPT0gc3RydG9sb3dlcigkaXB2Nl9wYXJ0KSB8fCAkdmFsdWUgPCAwIHx8ICR2YWx1ZSA+IDB4RkZGRikgewoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfQoJCQlpZiAoY291bnQoJGlwdjQpID09PSA0KSB7CgkJCQlmb3JlYWNoICgkaXB2NCBhcyAkaXB2NF9wYXJ0KSB7CgkJCQkJJHZhbHVlID0gKGludCkgJGlwdjRfcGFydDsKCQkJCQlpZiAoKHN0cmluZykgJHZhbHVlICE9PSAkaXB2NF9wYXJ0IHx8ICR2YWx1ZSA8IDAgfHwgJHZhbHVlID4gMHhGRikgewoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCXJldHVybiB0cnVlOwoJCX0KCQllbHNlIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KfQo8P3BocAovKioKICogUHJveHkgY29ubmVjdGlvbiBpbnRlcmZhY2UKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgUHJveHkKICogQHNpbmNlIDEuNgogKi8KCi8qKgogKiBQcm94eSBjb25uZWN0aW9uIGludGVyZmFjZQogKgogKiBJbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgdG8gaGFuZGxlIHByb3h5IHNldHRpbmdzIGFuZCBhdXRoZW50aWNhdGlvbgogKgogKiBQYXJhbWV0ZXJzIHNob3VsZCBiZSBwYXNzZWQgdmlhIHRoZSBjb25zdHJ1Y3RvciB3aGVyZSBwb3NzaWJsZSwgYXMgdGhpcwogKiBtYWtlcyBpdCBtdWNoIGVhc2llciBmb3IgdXNlcnMgdG8gdXNlIHlvdXIgcHJvdmlkZXIuCiAqCiAqIEBzZWUgUmVxdWVzdHNfSG9va3MKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgUHJveHkKICogQHNpbmNlIDEuNgogKi8KaW50ZXJmYWNlIFJlcXVlc3RzX1Byb3h5IHsKCS8qKgoJICogUmVnaXN0ZXIgaG9va3MgYXMgbmVlZGVkCgkgKgoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGluIHtAc2VlIFJlcXVlc3RzOjpyZXF1ZXN0fSB3aGVuIHRoZSB1c2VyIGhhcyBzZXQKCSAqIGFuIGluc3RhbmNlIGFzIHRoZSAnYXV0aCcgb3B0aW9uLiBVc2UgdGhpcyBjYWxsYmFjayB0byByZWdpc3RlciBhbGwgdGhlCgkgKiBob29rcyB5b3UnbGwgbmVlZC4KCSAqCgkgKiBAc2VlIFJlcXVlc3RzX0hvb2tzOjpyZWdpc3RlcgoJICogQHBhcmFtIFJlcXVlc3RzX0hvb2tzICRob29rcyBIb29rIHN5c3RlbQoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoUmVxdWVzdHNfSG9va3MgJGhvb2tzKTsKfQo8P3BocAoKLyoqCiAqIElETkEgVVJMIGVuY29kZXIKICoKICogTm90ZTogTm90IGZ1bGx5IGNvbXBsaWFudCwgYXMgbmFtZXByZXAgZG9lcyBub3RoaW5nIHlldC4KICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTAgSUROQSBzcGVjaWZpY2F0aW9uCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTIgUHVueWNvZGUvQm9vdHN0cmFwIHNwZWNpZmljYXRpb24KICovCmNsYXNzIFJlcXVlc3RzX0lETkFFbmNvZGVyIHsKCS8qKgoJICogQUNFIHByZWZpeCB1c2VkIGZvciBJRE5BCgkgKgoJICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzQ5MCNzZWN0aW9uLTUKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IEFDRV9QUkVGSVggPSAneG4tLSc7CgoJLyoqI0ArCgkgKiBCb290c3RyYXAgY29uc3RhbnQgZm9yIFB1bnljb2RlCgkgKgoJICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzQ5MiNzZWN0aW9uLTUKCSAqIEB2YXIgaW50CgkgKi8KCWNvbnN0IEJPT1RTVFJBUF9CQVNFICAgICAgICAgPSAzNjsKCWNvbnN0IEJPT1RTVFJBUF9UTUlOICAgICAgICAgPSAxOwoJY29uc3QgQk9PVFNUUkFQX1RNQVggICAgICAgICA9IDI2OwoJY29uc3QgQk9PVFNUUkFQX1NLRVcgICAgICAgICA9IDM4OwoJY29uc3QgQk9PVFNUUkFQX0RBTVAgICAgICAgICA9IDcwMDsKCWNvbnN0IEJPT1RTVFJBUF9JTklUSUFMX0JJQVMgPSA3MjsKCWNvbnN0IEJPT1RTVFJBUF9JTklUSUFMX04gICAgPSAxMjg7CgkvKiojQC0qLwoKCS8qKgoJICogRW5jb2RlIGEgaG9zdG5hbWUgdXNpbmcgUHVueWNvZGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgSG9zdG5hbWUKCSAqIEByZXR1cm4gc3RyaW5nIFB1bnljb2RlLWVuY29kZWQgaG9zdG5hbWUKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlbmNvZGUoJHN0cmluZykgewoJCSRwYXJ0cyA9IGV4cGxvZGUoJy4nLCAkc3RyaW5nKTsKCQlmb3JlYWNoICgkcGFydHMgYXMgJiRwYXJ0KSB7CgkJCSRwYXJ0ID0gc2VsZjo6dG9fYXNjaWkoJHBhcnQpOwoJCX0KCQlyZXR1cm4gaW1wbG9kZSgnLicsICRwYXJ0cyk7Cgl9CgoJLyoqCgkgKiBDb252ZXJ0IGEgVVRGLTggc3RyaW5nIHRvIGFuIEFTQ0lJIHN0cmluZyB1c2luZyBQdW55Y29kZQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIFByb3ZpZGVkIHN0cmluZyBsb25nZXIgdGhhbiA2NCBBU0NJSSBjaGFyYWN0ZXJzIChgaWRuYS5wcm92aWRlZF90b29fbG9uZ2ApCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBQcmVwYXJlZCBzdHJpbmcgbG9uZ2VyIHRoYW4gNjQgQVNDSUkgY2hhcmFjdGVycyAoYGlkbmEucHJlcGFyZWRfdG9vX2xvbmdgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gUHJvdmlkZWQgc3RyaW5nIGFscmVhZHkgYmVnaW5zIHdpdGggeG4tLSAoYGlkbmEucHJvdmlkZWRfaXNfcHJlZml4ZWRgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gRW5jb2RlZCBzdHJpbmcgbG9uZ2VyIHRoYW4gNjQgQVNDSUkgY2hhcmFjdGVycyAoYGlkbmEuZW5jb2RlZF90b29fbG9uZ2ApCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIEFTQ0lJIG9yIFVURi04IHN0cmluZyAobWF4IGxlbmd0aCA2NCBjaGFyYWN0ZXJzKQoJICogQHJldHVybiBzdHJpbmcgQVNDSUkgc3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9fYXNjaWkoJHN0cmluZykgewoJCS8vIFN0ZXAgMTogQ2hlY2sgaWYgdGhlIHN0cmluZyBpcyBhbHJlYWR5IEFTQ0lJCgkJaWYgKHNlbGY6OmlzX2FzY2lpKCRzdHJpbmcpKSB7CgkJCS8vIFNraXAgdG8gc3RlcCA3CgkJCWlmIChzdHJsZW4oJHN0cmluZykgPCA2NCkgewoJCQkJcmV0dXJuICRzdHJpbmc7CgkJCX0KCgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ1Byb3ZpZGVkIHN0cmluZyBpcyB0b28gbG9uZycsICdpZG5hLnByb3ZpZGVkX3Rvb19sb25nJywgJHN0cmluZyk7CgkJfQoKCQkvLyBTdGVwIDI6IG5hbWVwcmVwCgkJJHN0cmluZyA9IHNlbGY6Om5hbWVwcmVwKCRzdHJpbmcpOwoKCQkvLyBTdGVwIDM6IFVzZVNURDNBU0NJSVJ1bGVzIGlzIGZhbHNlLCBjb250aW51ZQoJCS8vIFN0ZXAgNDogQ2hlY2sgaWYgaXQncyBBU0NJSSBub3cKCQlpZiAoc2VsZjo6aXNfYXNjaWkoJHN0cmluZykpIHsKCQkJLy8gU2tpcCB0byBzdGVwIDcKCQkJaWYgKHN0cmxlbigkc3RyaW5nKSA8IDY0KSB7CgkJCQlyZXR1cm4gJHN0cmluZzsKCQkJfQoKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignUHJlcGFyZWQgc3RyaW5nIGlzIHRvbyBsb25nJywgJ2lkbmEucHJlcGFyZWRfdG9vX2xvbmcnLCAkc3RyaW5nKTsKCQl9CgoJCS8vIFN0ZXAgNTogQ2hlY2sgQUNFIHByZWZpeAoJCWlmIChzdHJwb3MoJHN0cmluZywgc2VsZjo6QUNFX1BSRUZJWCkgPT09IDApIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignUHJvdmlkZWQgc3RyaW5nIGJlZ2lucyB3aXRoIEFDRSBwcmVmaXgnLCAnaWRuYS5wcm92aWRlZF9pc19wcmVmaXhlZCcsICRzdHJpbmcpOwoJCX0KCgkJLy8gU3RlcCA2OiBFbmNvZGUgd2l0aCBQdW55Y29kZQoJCSRzdHJpbmcgPSBzZWxmOjpwdW55Y29kZV9lbmNvZGUoJHN0cmluZyk7CgoJCS8vIFN0ZXAgNzogUHJlcGVuZCBBQ0UgcHJlZml4CgkJJHN0cmluZyA9IHNlbGY6OkFDRV9QUkVGSVggLiAkc3RyaW5nOwoKCQkvLyBTdGVwIDg6IENoZWNrIHNpemUKCQlpZiAoc3RybGVuKCRzdHJpbmcpIDwgNjQpIHsKCQkJcmV0dXJuICRzdHJpbmc7CgkJfQoKCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdFbmNvZGVkIHN0cmluZyBpcyB0b28gbG9uZycsICdpZG5hLmVuY29kZWRfdG9vX2xvbmcnLCAkc3RyaW5nKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBzdHJpbmcgY29udGFpbnMgb25seSBBU0NJSSBjaGFyYWN0ZXJzCgkgKgoJICogQGludGVybmFsIChUZXN0aW5nIGZvdW5kIHJlZ2V4IHdhcyB0aGUgZmFzdGVzdCBpbXBsZW1lbnRhdGlvbikKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKCSAqIEByZXR1cm4gYm9vbCBJcyB0aGUgc3RyaW5nIEFTQ0lJLW9ubHk/CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gaXNfYXNjaWkoJHN0cmluZykgewoJCXJldHVybiAocHJlZ19tYXRjaCgnLyg/OlteXHgwMC1ceDdGXSkvJywgJHN0cmluZykgIT09IDEpOwoJfQoKCS8qKgoJICogUHJlcGFyZSBhIHN0cmluZyBmb3IgdXNlIGFzIGFuIElETkEgbmFtZQoJICoKCSAqIEB0b2RvIEltcGxlbWVudCB0aGlzIGJhc2VkIG9uIFJGQyAzNDkxIGFuZCB0aGUgbmV3ZXIgNTg5MQoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCgkgKiBAcmV0dXJuIHN0cmluZyBQcmVwYXJlZCBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBuYW1lcHJlcCgkc3RyaW5nKSB7CgkJcmV0dXJuICRzdHJpbmc7Cgl9CgoJLyoqCgkgKiBDb252ZXJ0IGEgVVRGLTggc3RyaW5nIHRvIGEgVUNTLTQgY29kZXBvaW50IGFycmF5CgkgKgoJICogQmFzZWQgb24gUmVxdWVzdHNfSVJJOjpyZXBsYWNlX2ludmFsaWRfd2l0aF9wY3RfZW5jb2RpbmcoKQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIEludmFsaWQgVVRGLTggY29kZXBvaW50IChgaWRuYS5pbnZhbGlkY29kZXBvaW50YCkKCSAqIEBwYXJhbSBzdHJpbmcgJGlucHV0CgkgKiBAcmV0dXJuIGFycmF5IFVuaWNvZGUgY29kZSBwb2ludHMKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB1dGY4X3RvX2NvZGVwb2ludHMoJGlucHV0KSB7CgkJJGNvZGVwb2ludHMgPSBhcnJheSgpOwoKCQkvLyBHZXQgbnVtYmVyIG9mIGJ5dGVzCgkJJHN0cmxlbiA9IHN0cmxlbigkaW5wdXQpOwoKCQkvLyBwaHBjczppZ25vcmUgR2VuZXJpYy5Db2RlQW5hbHlzaXMuSnVtYmxlZEluY3JlbWVudGVyIC0tIFRoaXMgaXMgYSBkZWxpYmVyYXRlIGNob2ljZS4KCQlmb3IgKCRwb3NpdGlvbiA9IDA7ICRwb3NpdGlvbiA8ICRzdHJsZW47ICRwb3NpdGlvbisrKSB7CgkJCSR2YWx1ZSA9IG9yZCgkaW5wdXRbJHBvc2l0aW9uXSk7CgoJCQkvLyBPbmUgYnl0ZSBzZXF1ZW5jZToKCQkJaWYgKCh+JHZhbHVlICYgMHg4MCkgPT09IDB4ODApIHsKCQkJCSRjaGFyYWN0ZXIgPSAkdmFsdWU7CgkJCQkkbGVuZ3RoICAgID0gMTsKCQkJCSRyZW1haW5pbmcgPSAwOwoJCQl9CgkJCS8vIFR3byBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEUwKSA9PT0gMHhDMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDFGKSA8PCA2OwoJCQkJJGxlbmd0aCAgICA9IDI7CgkJCQkkcmVtYWluaW5nID0gMTsKCQkJfQoJCQkvLyBUaHJlZSBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEYwKSA9PT0gMHhFMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDBGKSA8PCAxMjsKCQkJCSRsZW5ndGggICAgPSAzOwoJCQkJJHJlbWFpbmluZyA9IDI7CgkJCX0KCQkJLy8gRm91ciBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEY4KSA9PT0gMHhGMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDA3KSA8PCAxODsKCQkJCSRsZW5ndGggICAgPSA0OwoJCQkJJHJlbWFpbmluZyA9IDM7CgkJCX0KCQkJLy8gSW52YWxpZCBieXRlOgoJCQllbHNlIHsKCQkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0ludmFsaWQgVW5pY29kZSBjb2RlcG9pbnQnLCAnaWRuYS5pbnZhbGlkY29kZXBvaW50JywgJHZhbHVlKTsKCQkJfQoKCQkJaWYgKCRyZW1haW5pbmcgPiAwKSB7CgkJCQlpZiAoJHBvc2l0aW9uICsgJGxlbmd0aCA+ICRzdHJsZW4pIHsKCQkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIFVuaWNvZGUgY29kZXBvaW50JywgJ2lkbmEuaW52YWxpZGNvZGVwb2ludCcsICRjaGFyYWN0ZXIpOwoJCQkJfQoJCQkJZm9yICgkcG9zaXRpb24rKzsgJHJlbWFpbmluZyA+IDA7ICRwb3NpdGlvbisrKSB7CgkJCQkJJHZhbHVlID0gb3JkKCRpbnB1dFskcG9zaXRpb25dKTsKCgkJCQkJLy8gSWYgaXQgaXMgaW52YWxpZCwgY291bnQgdGhlIHNlcXVlbmNlIGFzIGludmFsaWQgYW5kIHJlcHJvY2VzcyB0aGUgY3VycmVudCBieXRlOgoJCQkJCWlmICgoJHZhbHVlICYgMHhDMCkgIT09IDB4ODApIHsKCQkJCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignSW52YWxpZCBVbmljb2RlIGNvZGVwb2ludCcsICdpZG5hLmludmFsaWRjb2RlcG9pbnQnLCAkY2hhcmFjdGVyKTsKCQkJCQl9CgoJCQkJCS0tJHJlbWFpbmluZzsKCQkJCQkkY2hhcmFjdGVyIHw9ICgkdmFsdWUgJiAweDNGKSA8PCAoJHJlbWFpbmluZyAqIDYpOwoJCQkJfQoJCQkJJHBvc2l0aW9uLS07CgkJCX0KCgkJCWlmICgvLyBOb24tc2hvcnRlc3QgZm9ybSBzZXF1ZW5jZXMgYXJlIGludmFsaWQKCQkJCSRsZW5ndGggPiAxICYmICRjaGFyYWN0ZXIgPD0gMHg3RgoJCQkJfHwgJGxlbmd0aCA+IDIgJiYgJGNoYXJhY3RlciA8PSAweDdGRgoJCQkJfHwgJGxlbmd0aCA+IDMgJiYgJGNoYXJhY3RlciA8PSAweEZGRkYKCQkJCS8vIE91dHNpZGUgb2YgcmFuZ2Ugb2YgdWNzY2hhciBjb2RlcG9pbnRzCgkJCQkvLyBOb25jaGFyYWN0ZXJzCgkJCQl8fCAoJGNoYXJhY3RlciAmIDB4RkZGRSkgPT09IDB4RkZGRQoJCQkJfHwgJGNoYXJhY3RlciA+PSAweEZERDAgJiYgJGNoYXJhY3RlciA8PSAweEZERUYKCQkJCXx8ICgKCQkJCQkvLyBFdmVyeXRoaW5nIGVsc2Ugbm90IGluIHVjc2NoYXIKCQkJCQkkY2hhcmFjdGVyID4gMHhEN0ZGICYmICRjaGFyYWN0ZXIgPCAweEY5MDAKCQkJCQl8fCAkY2hhcmFjdGVyIDwgMHgyMAoJCQkJCXx8ICRjaGFyYWN0ZXIgPiAweDdFICYmICRjaGFyYWN0ZXIgPCAweEEwCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4RUZGRkQKCQkJCSkKCQkJKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIFVuaWNvZGUgY29kZXBvaW50JywgJ2lkbmEuaW52YWxpZGNvZGVwb2ludCcsICRjaGFyYWN0ZXIpOwoJCQl9CgoJCQkkY29kZXBvaW50c1tdID0gJGNoYXJhY3RlcjsKCQl9CgoJCXJldHVybiAkY29kZXBvaW50czsKCX0KCgkvKioKCSAqIFJGQzM0OTItY29tcGxpYW50IGVuY29kZXIKCSAqCgkgKiBAaW50ZXJuYWwgUHNldWRvLWNvZGUgZnJvbSBTZWN0aW9uIDYuMyBpcyBjb21tZW50ZWQgd2l0aCAiIyIgbmV4dCB0byByZWxldmFudCBjb2RlCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBjaGFyYWN0ZXIgb3V0c2lkZSBvZiB0aGUgZG9tYWluIChuZXZlciBoYXBwZW5zIHdpdGggUHVueWNvZGUpIChgaWRuYS5jaGFyYWN0ZXJfb3V0c2lkZV9kb21haW5gKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFVURi04IGVuY29kZWQgc3RyaW5nIHRvIGVuY29kZQoJICogQHJldHVybiBzdHJpbmcgUHVueWNvZGUtZW5jb2RlZCBzdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwdW55Y29kZV9lbmNvZGUoJGlucHV0KSB7CgkJJG91dHB1dCA9ICcnOwoJCS8vIGxldCBuID0gaW5pdGlhbF9uCgkJJG4gPSBzZWxmOjpCT09UU1RSQVBfSU5JVElBTF9OOwoJCS8vIGxldCBkZWx0YSA9IDAKCQkkZGVsdGEgPSAwOwoJCS8vIGxldCBiaWFzID0gaW5pdGlhbF9iaWFzCgkJJGJpYXMgPSBzZWxmOjpCT09UU1RSQVBfSU5JVElBTF9CSUFTOwoJCS8vIGxldCBoID0gYiA9IHRoZSBudW1iZXIgb2YgYmFzaWMgY29kZSBwb2ludHMgaW4gdGhlIGlucHV0CgkJJGggPSAwOwoJCSRiID0gMDsgLy8gc2VlIGxvb3AKCQkvLyBjb3B5IHRoZW0gdG8gdGhlIG91dHB1dCBpbiBvcmRlcgoJCSRjb2RlcG9pbnRzID0gc2VsZjo6dXRmOF90b19jb2RlcG9pbnRzKCRpbnB1dCk7CgkJJGV4dGVuZGVkICAgPSBhcnJheSgpOwoKCQlmb3JlYWNoICgkY29kZXBvaW50cyBhcyAkY2hhcikgewoJCQlpZiAoJGNoYXIgPCAxMjgpIHsKCQkJCS8vIENoYXJhY3RlciBpcyB2YWxpZCBBU0NJSQoJCQkJLy8gVE9ETzogdGhpcyBzaG91bGQgYWxzbyBjaGVjayBpZiBpdCdzIHZhbGlkIGZvciBhIFVSTAoJCQkJJG91dHB1dCAuPSBjaHIoJGNoYXIpOwoJCQkJJGgrKzsKCQkJfQoJCQkvLyBDaGVjayBpZiB0aGUgY2hhcmFjdGVyIGlzIG5vbi1BU0NJSSwgYnV0IGJlbG93IGluaXRpYWwgbgoJCQkvLyBUaGlzIG5ldmVyIG9jY3VycyBmb3IgUHVueWNvZGUsIHNvIGlnbm9yZSBpbiBjb3ZlcmFnZQoJCQkvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKCQkJZWxzZWlmICgkY2hhciA8ICRuKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIGNoYXJhY3RlcicsICdpZG5hLmNoYXJhY3Rlcl9vdXRzaWRlX2RvbWFpbicsICRjaGFyKTsKCQkJfQoJCQkvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCgkJCWVsc2UgewoJCQkJJGV4dGVuZGVkWyRjaGFyXSA9IHRydWU7CgkJCX0KCQl9CgkJJGV4dGVuZGVkID0gYXJyYXlfa2V5cygkZXh0ZW5kZWQpOwoJCXNvcnQoJGV4dGVuZGVkKTsKCQkkYiA9ICRoOwoJCS8vIFtjb3B5IHRoZW1dIGZvbGxvd2VkIGJ5IGEgZGVsaW1pdGVyIGlmIGIgPiAwCgkJaWYgKHN0cmxlbigkb3V0cHV0KSA+IDApIHsKCQkJJG91dHB1dCAuPSAnLSc7CgkJfQoJCS8vIHtpZiB0aGUgaW5wdXQgY29udGFpbnMgYSBub24tYmFzaWMgY29kZSBwb2ludCA8IG4gdGhlbiBmYWlsfQoJCS8vIHdoaWxlIGggPCBsZW5ndGgoaW5wdXQpIGRvIGJlZ2luCgkJJGNvZGVwb2ludGNvdW50ID0gY291bnQoJGNvZGVwb2ludHMpOwoJCXdoaWxlICgkaCA8ICRjb2RlcG9pbnRjb3VudCkgewoJCQkvLyBsZXQgbSA9IHRoZSBtaW5pbXVtIGNvZGUgcG9pbnQgPj0gbiBpbiB0aGUgaW5wdXQKCQkJJG0gPSBhcnJheV9zaGlmdCgkZXh0ZW5kZWQpOwoJCQkvL3ByaW50ZignbmV4dCBjb2RlIHBvaW50IHRvIGluc2VydCBpcyAlcycgLiBQSFBfRU9MLCBkZWNoZXgoJG0pKTsKCQkJLy8gbGV0IGRlbHRhID0gZGVsdGEgKyAobSAtIG4pICogKGggKyAxKSwgZmFpbCBvbiBvdmVyZmxvdwoJCQkkZGVsdGEgKz0gKCRtIC0gJG4pICogKCRoICsgMSk7CgkJCS8vIGxldCBuID0gbQoJCQkkbiA9ICRtOwoJCQkvLyBmb3IgZWFjaCBjb2RlIHBvaW50IGMgaW4gdGhlIGlucHV0IChpbiBvcmRlcikgZG8gYmVnaW4KCQkJZm9yICgkbnVtID0gMDsgJG51bSA8ICRjb2RlcG9pbnRjb3VudDsgJG51bSsrKSB7CgkJCQkkYyA9ICRjb2RlcG9pbnRzWyRudW1dOwoJCQkJLy8gaWYgYyA8IG4gdGhlbiBpbmNyZW1lbnQgZGVsdGEsIGZhaWwgb24gb3ZlcmZsb3cKCQkJCWlmICgkYyA8ICRuKSB7CgkJCQkJJGRlbHRhKys7CgkJCQl9CgkJCQkvLyBpZiBjID09IG4gdGhlbiBiZWdpbgoJCQkJZWxzZWlmICgkYyA9PT0gJG4pIHsKCQkJCQkvLyBsZXQgcSA9IGRlbHRhCgkJCQkJJHEgPSAkZGVsdGE7CgkJCQkJLy8gZm9yIGsgPSBiYXNlIHRvIGluZmluaXR5IGluIHN0ZXBzIG9mIGJhc2UgZG8gYmVnaW4KCQkJCQlmb3IgKCRrID0gc2VsZjo6Qk9PVFNUUkFQX0JBU0U7IDsgJGsgKz0gc2VsZjo6Qk9PVFNUUkFQX0JBU0UpIHsKCQkJCQkJLy8gbGV0IHQgPSB0bWluIGlmIGsgPD0gYmlhcyB7KyB0bWlufSwgb3IKCQkJCQkJLy8gICAgIHRtYXggaWYgayA+PSBiaWFzICsgdG1heCwgb3IgayAtIGJpYXMgb3RoZXJ3aXNlCgkJCQkJCWlmICgkayA8PSAoJGJpYXMgKyBzZWxmOjpCT09UU1RSQVBfVE1JTikpIHsKCQkJCQkJCSR0ID0gc2VsZjo6Qk9PVFNUUkFQX1RNSU47CgkJCQkJCX0KCQkJCQkJZWxzZWlmICgkayA+PSAoJGJpYXMgKyBzZWxmOjpCT09UU1RSQVBfVE1BWCkpIHsKCQkJCQkJCSR0ID0gc2VsZjo6Qk9PVFNUUkFQX1RNQVg7CgkJCQkJCX0KCQkJCQkJZWxzZSB7CgkJCQkJCQkkdCA9ICRrIC0gJGJpYXM7CgkJCQkJCX0KCQkJCQkJLy8gaWYgcSA8IHQgdGhlbiBicmVhawoJCQkJCQlpZiAoJHEgPCAkdCkgewoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQkJLy8gb3V0cHV0IHRoZSBjb2RlIHBvaW50IGZvciBkaWdpdCB0ICsgKChxIC0gdCkgbW9kIChiYXNlIC0gdCkpCgkJCQkJCSRkaWdpdCAgID0gJHQgKyAoKCRxIC0gJHQpICUgKHNlbGY6OkJPT1RTVFJBUF9CQVNFIC0gJHQpKTsKCQkJCQkJJG91dHB1dCAuPSBzZWxmOjpkaWdpdF90b19jaGFyKCRkaWdpdCk7CgkJCQkJCS8vIGxldCBxID0gKHEgLSB0KSBkaXYgKGJhc2UgLSB0KQoJCQkJCQkkcSA9IGZsb29yKCgkcSAtICR0KSAvIChzZWxmOjpCT09UU1RSQVBfQkFTRSAtICR0KSk7CgkJCQkJfSAvLyBlbmQKCQkJCQkvLyBvdXRwdXQgdGhlIGNvZGUgcG9pbnQgZm9yIGRpZ2l0IHEKCQkJCQkkb3V0cHV0IC49IHNlbGY6OmRpZ2l0X3RvX2NoYXIoJHEpOwoJCQkJCS8vIGxldCBiaWFzID0gYWRhcHQoZGVsdGEsIGggKyAxLCB0ZXN0IGggZXF1YWxzIGI/KQoJCQkJCSRiaWFzID0gc2VsZjo6YWRhcHQoJGRlbHRhLCAkaCArIDEsICRoID09PSAkYik7CgkJCQkJLy8gbGV0IGRlbHRhID0gMAoJCQkJCSRkZWx0YSA9IDA7CgkJCQkJLy8gaW5jcmVtZW50IGgKCQkJCQkkaCsrOwoJCQkJfSAvLyBlbmQKCQkJfSAvLyBlbmQKCQkJLy8gaW5jcmVtZW50IGRlbHRhIGFuZCBuCgkJCSRkZWx0YSsrOwoJCQkkbisrOwoJCX0gLy8gZW5kCgoJCXJldHVybiAkb3V0cHV0OwoJfQoKCS8qKgoJICogQ29udmVydCBhIGRpZ2l0IHRvIGl0cyByZXNwZWN0aXZlIGNoYXJhY3RlcgoJICoKCSAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTIjc2VjdGlvbi01CgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBpbnZhbGlkIGRpZ2l0IChgaWRuYS5pbnZhbGlkX2RpZ2l0YCkKCSAqCgkgKiBAcGFyYW0gaW50ICRkaWdpdCBEaWdpdCBpbiB0aGUgcmFuZ2UgMC0zNQoJICogQHJldHVybiBzdHJpbmcgU2luZ2xlIGNoYXJhY3RlciBjb3JyZXNwb25kaW5nIHRvIGRpZ2l0CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZGlnaXRfdG9fY2hhcigkZGlnaXQpIHsKCQkvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKCQkvLyBBcyBmYXIgYXMgSSBrbm93LCB0aGlzIG5ldmVyIGhhcHBlbnMsIGJ1dCBzdGlsbCBnb29kIHRvIGJlIHN1cmUuCgkJaWYgKCRkaWdpdCA8IDAgfHwgJGRpZ2l0ID4gMzUpIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbihzcHJpbnRmKCdJbnZhbGlkIGRpZ2l0ICVkJywgJGRpZ2l0KSwgJ2lkbmEuaW52YWxpZF9kaWdpdCcsICRkaWdpdCk7CgkJfQoJCS8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVFbmQKCQkkZGlnaXRzID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7CgkJcmV0dXJuIHN1YnN0cigkZGlnaXRzLCAkZGlnaXQsIDEpOwoJfQoKCS8qKgoJICogQWRhcHQgdGhlIGJpYXMKCSAqCgkgKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNDkyI3NlY3Rpb24tNi4xCgkgKiBAcGFyYW0gaW50ICRkZWx0YQoJICogQHBhcmFtIGludCAkbnVtcG9pbnRzCgkgKiBAcGFyYW0gYm9vbCAkZmlyc3R0aW1lCgkgKiBAcmV0dXJuIGludCBOZXcgYmlhcwoJICoKCSAqIGZ1bmN0aW9uIGFkYXB0KGRlbHRhLG51bXBvaW50cyxmaXJzdHRpbWUpOgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGFkYXB0KCRkZWx0YSwgJG51bXBvaW50cywgJGZpcnN0dGltZSkgewoJCS8vIGlmIGZpcnN0dGltZSB0aGVuIGxldCBkZWx0YSA9IGRlbHRhIGRpdiBkYW1wCgkJaWYgKCRmaXJzdHRpbWUpIHsKCQkJJGRlbHRhID0gZmxvb3IoJGRlbHRhIC8gc2VsZjo6Qk9PVFNUUkFQX0RBTVApOwoJCX0KCQkvLyBlbHNlIGxldCBkZWx0YSA9IGRlbHRhIGRpdiAyCgkJZWxzZSB7CgkJCSRkZWx0YSA9IGZsb29yKCRkZWx0YSAvIDIpOwoJCX0KCQkvLyBsZXQgZGVsdGEgPSBkZWx0YSArIChkZWx0YSBkaXYgbnVtcG9pbnRzKQoJCSRkZWx0YSArPSBmbG9vcigkZGVsdGEgLyAkbnVtcG9pbnRzKTsKCQkvLyBsZXQgayA9IDAKCQkkayA9IDA7CgkJLy8gd2hpbGUgZGVsdGEgPiAoKGJhc2UgLSB0bWluKSAqIHRtYXgpIGRpdiAyIGRvIGJlZ2luCgkJJG1heCA9IGZsb29yKCgoc2VsZjo6Qk9PVFNUUkFQX0JBU0UgLSBzZWxmOjpCT09UU1RSQVBfVE1JTikgKiBzZWxmOjpCT09UU1RSQVBfVE1BWCkgLyAyKTsKCQl3aGlsZSAoJGRlbHRhID4gJG1heCkgewoJCQkvLyBsZXQgZGVsdGEgPSBkZWx0YSBkaXYgKGJhc2UgLSB0bWluKQoJCQkkZGVsdGEgPSBmbG9vcigkZGVsdGEgLyAoc2VsZjo6Qk9PVFNUUkFQX0JBU0UgLSBzZWxmOjpCT09UU1RSQVBfVE1JTikpOwoJCQkvLyBsZXQgayA9IGsgKyBiYXNlCgkJCSRrICs9IHNlbGY6OkJPT1RTVFJBUF9CQVNFOwoJCX0gLy8gZW5kCgkJLy8gcmV0dXJuIGsgKyAoKChiYXNlIC0gdG1pbiArIDEpICogZGVsdGEpIGRpdiAoZGVsdGEgKyBza2V3KSkKCQlyZXR1cm4gJGsgKyBmbG9vcigoKHNlbGY6OkJPT1RTVFJBUF9CQVNFIC0gc2VsZjo6Qk9PVFNUUkFQX1RNSU4gKyAxKSAqICRkZWx0YSkgLyAoJGRlbHRhICsgc2VsZjo6Qk9PVFNUUkFQX1NLRVcpKTsKCX0KfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciBIVFRQIHJlcXVlc3RzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgSFRUUCByZXF1ZXN0cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKCS8qKgoJICogVHlwZSBvZiBleGNlcHRpb24KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHR5cGU7CgoJLyoqCgkgKiBEYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXhjZXB0aW9uCgkgKgoJICogQHZhciBtaXhlZAoJICovCglwcm90ZWN0ZWQgJGRhdGE7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgZXhjZXB0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBFeGNlcHRpb24gbWVzc2FnZQoJICogQHBhcmFtIHN0cmluZyAkdHlwZSBFeGNlcHRpb24gdHlwZQoJICogQHBhcmFtIG1peGVkICRkYXRhIEFzc29jaWF0ZWQgZGF0YQoJICogQHBhcmFtIGludGVnZXIgJGNvZGUgRXhjZXB0aW9uIG51bWVyaWNhbCBjb2RlLCBpZiBhcHBsaWNhYmxlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJHR5cGUsICRkYXRhID0gbnVsbCwgJGNvZGUgPSAwKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJGNvZGUpOwoKCQkkdGhpcy0+dHlwZSA9ICR0eXBlOwoJCSR0aGlzLT5kYXRhID0gJGRhdGE7Cgl9CgoJLyoqCgkgKiBMaWtlIHtAc2VlIGdldENvZGUoKX0sIGJ1dCBhIHN0cmluZyBjb2RlLgoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRUeXBlKCkgewoJCXJldHVybiAkdGhpcy0+dHlwZTsKCX0KCgkvKioKCSAqIEdpdmVzIGFueSByZWxldmFudCBkYXRhCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQHJldHVybiBtaXhlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0RGF0YSgpIHsKCQlyZXR1cm4gJHRoaXMtPmRhdGE7Cgl9Cn0KPD9waHAKLyoqCiAqIENvb2tpZSBzdG9yYWdlIG9iamVjdAogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBDb29raWVzCiAqLwoKLyoqCiAqIENvb2tpZSBzdG9yYWdlIG9iamVjdAogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBDb29raWVzCiAqLwpjbGFzcyBSZXF1ZXN0c19Db29raWUgewoJLyoqCgkgKiBDb29raWUgbmFtZS4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJG5hbWU7CgoJLyoqCgkgKiBDb29raWUgdmFsdWUuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICR2YWx1ZTsKCgkvKioKCSAqIENvb2tpZSBhdHRyaWJ1dGVzCgkgKgoJICogVmFsaWQga2V5cyBhcmUgKGN1cnJlbnRseSkgcGF0aCwgZG9tYWluLCBleHBpcmVzLCBtYXgtYWdlLCBzZWN1cmUgYW5kCgkgKiBodHRwb25seS4KCSAqCgkgKiBAdmFyIFJlcXVlc3RzX1V0aWxpdHlfQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeXxhcnJheSBBcnJheS1saWtlIG9iamVjdAoJICovCglwdWJsaWMgJGF0dHJpYnV0ZXMgPSBhcnJheSgpOwoKCS8qKgoJICogQ29va2llIGZsYWdzCgkgKgoJICogVmFsaWQga2V5cyBhcmUgKGN1cnJlbnRseSkgY3JlYXRpb24sIGxhc3QtYWNjZXNzLCBwZXJzaXN0ZW50IGFuZAoJICogaG9zdC1vbmx5LgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHVibGljICRmbGFncyA9IGFycmF5KCk7CgoJLyoqCgkgKiBSZWZlcmVuY2UgdGltZSBmb3IgcmVsYXRpdmUgY2FsY3VsYXRpb25zCgkgKgoJICogVGhpcyBpcyB1c2VkIGluIHBsYWNlIG9mIGB0aW1lKClgIHdoZW4gY2FsY3VsYXRpbmcgTWF4LUFnZSBleHBpcmF0aW9uIGFuZAoJICogY2hlY2tpbmcgdGltZSB2YWxpZGl0eS4KCSAqCgkgKiBAdmFyIGludAoJICovCglwdWJsaWMgJHJlZmVyZW5jZV90aW1lID0gMDsKCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBjb29raWUgb2JqZWN0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZQoJICogQHBhcmFtIHN0cmluZyAkdmFsdWUKCSAqIEBwYXJhbSBhcnJheXxSZXF1ZXN0c19VdGlsaXR5X0Nhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgJGF0dHJpYnV0ZXMgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXR0cmlidXRlIGRhdGEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCAkdmFsdWUsICRhdHRyaWJ1dGVzID0gYXJyYXkoKSwgJGZsYWdzID0gYXJyYXkoKSwgJHJlZmVyZW5jZV90aW1lID0gbnVsbCkgewoJCSR0aGlzLT5uYW1lICAgICAgID0gJG5hbWU7CgkJJHRoaXMtPnZhbHVlICAgICAgPSAkdmFsdWU7CgkJJHRoaXMtPmF0dHJpYnV0ZXMgPSAkYXR0cmlidXRlczsKCQkkZGVmYXVsdF9mbGFncyAgICA9IGFycmF5KAoJCQknY3JlYXRpb24nICAgID0+IHRpbWUoKSwKCQkJJ2xhc3QtYWNjZXNzJyA9PiB0aW1lKCksCgkJCSdwZXJzaXN0ZW50JyAgPT4gZmFsc2UsCgkJCSdob3N0LW9ubHknICAgPT4gdHJ1ZSwKCQkpOwoJCSR0aGlzLT5mbGFncyAgICAgID0gYXJyYXlfbWVyZ2UoJGRlZmF1bHRfZmxhZ3MsICRmbGFncyk7CgoJCSR0aGlzLT5yZWZlcmVuY2VfdGltZSA9IHRpbWUoKTsKCQlpZiAoJHJlZmVyZW5jZV90aW1lICE9PSBudWxsKSB7CgkJCSR0aGlzLT5yZWZlcmVuY2VfdGltZSA9ICRyZWZlcmVuY2VfdGltZTsKCQl9CgoJCSR0aGlzLT5ub3JtYWxpemUoKTsKCX0KCgkvKioKCSAqIENoZWNrIGlmIGEgY29va2llIGlzIGV4cGlyZWQuCgkgKgoJICogQ2hlY2tzIHRoZSBhZ2UgYWdhaW5zdCAkdGhpcy0+cmVmZXJlbmNlX3RpbWUgdG8gZGV0ZXJtaW5lIGlmIHRoZSBjb29raWUKCSAqIGlzIGV4cGlyZWQuCgkgKgoJICogQHJldHVybiBib29sZWFuIFRydWUgaWYgZXhwaXJlZCwgZmFsc2UgaWYgdGltZSBpcyB2YWxpZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2V4cGlyZWQoKSB7CgkJLy8gUkZDNjI2NSwgcy4gNC4xLjIuMjoKCQkvLyBJZiBhIGNvb2tpZSBoYXMgYm90aCB0aGUgTWF4LUFnZSBhbmQgdGhlIEV4cGlyZXMgYXR0cmlidXRlLCB0aGUgTWF4LQoJCS8vIEFnZSBhdHRyaWJ1dGUgaGFzIHByZWNlZGVuY2UgYW5kIGNvbnRyb2xzIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlCgkJLy8gY29va2llLgoJCWlmIChpc3NldCgkdGhpcy0+YXR0cmlidXRlc1snbWF4LWFnZSddKSkgewoJCQkkbWF4X2FnZSA9ICR0aGlzLT5hdHRyaWJ1dGVzWydtYXgtYWdlJ107CgkJCXJldHVybiAkbWF4X2FnZSA8ICR0aGlzLT5yZWZlcmVuY2VfdGltZTsKCQl9CgoJCWlmIChpc3NldCgkdGhpcy0+YXR0cmlidXRlc1snZXhwaXJlcyddKSkgewoJCQkkZXhwaXJlcyA9ICR0aGlzLT5hdHRyaWJ1dGVzWydleHBpcmVzJ107CgkJCXJldHVybiAkZXhwaXJlcyA8ICR0aGlzLT5yZWZlcmVuY2VfdGltZTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIENoZWNrIGlmIGEgY29va2llIGlzIHZhbGlkIGZvciBhIGdpdmVuIFVSSQoJICoKCSAqIEBwYXJhbSBSZXF1ZXN0c19JUkkgJHVyaSBVUkkgdG8gY2hlY2sKCSAqIEByZXR1cm4gYm9vbGVhbiBXaGV0aGVyIHRoZSBjb29raWUgaXMgdmFsaWQgZm9yIHRoZSBnaXZlbiBVUkkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVyaV9tYXRjaGVzKFJlcXVlc3RzX0lSSSAkdXJpKSB7CgkJaWYgKCEkdGhpcy0+ZG9tYWluX21hdGNoZXMoJHVyaS0+aG9zdCkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKCEkdGhpcy0+cGF0aF9tYXRjaGVzKCR1cmktPnBhdGgpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiBlbXB0eSgkdGhpcy0+YXR0cmlidXRlc1snc2VjdXJlJ10pIHx8ICR1cmktPnNjaGVtZSA9PT0gJ2h0dHBzJzsKCX0KCgkvKioKCSAqIENoZWNrIGlmIGEgY29va2llIGlzIHZhbGlkIGZvciBhIGdpdmVuIGRvbWFpbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBEb21haW4gdG8gY2hlY2sKCSAqIEByZXR1cm4gYm9vbGVhbiBXaGV0aGVyIHRoZSBjb29raWUgaXMgdmFsaWQgZm9yIHRoZSBnaXZlbiBkb21haW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRvbWFpbl9tYXRjaGVzKCRzdHJpbmcpIHsKCQlpZiAoIWlzc2V0KCR0aGlzLT5hdHRyaWJ1dGVzWydkb21haW4nXSkpIHsKCQkJLy8gQ29va2llcyBjcmVhdGVkIG1hbnVhbGx5OyBjb29raWVzIGNyZWF0ZWQgYnkgUmVxdWVzdHMgd2lsbCBzZXQKCQkJLy8gdGhlIGRvbWFpbiB0byB0aGUgcmVxdWVzdGVkIGRvbWFpbgoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSRkb21haW5fc3RyaW5nID0gJHRoaXMtPmF0dHJpYnV0ZXNbJ2RvbWFpbiddOwoJCWlmICgkZG9tYWluX3N0cmluZyA9PT0gJHN0cmluZykgewoJCQkvLyBUaGUgZG9tYWluIHN0cmluZyBhbmQgdGhlIHN0cmluZyBhcmUgaWRlbnRpY2FsLgoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCS8vIElmIHRoZSBjb29raWUgaXMgbWFya2VkIGFzIGhvc3Qtb25seSBhbmQgd2UgZG9uJ3QgaGF2ZSBhbiBleGFjdAoJCS8vIG1hdGNoLCByZWplY3QgdGhlIGNvb2tpZQoJCWlmICgkdGhpcy0+ZmxhZ3NbJ2hvc3Qtb25seSddID09PSB0cnVlKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWlmIChzdHJsZW4oJHN0cmluZykgPD0gc3RybGVuKCRkb21haW5fc3RyaW5nKSkgewoJCQkvLyBGb3Igb2J2aW91cyByZWFzb25zLCB0aGUgc3RyaW5nIGNhbm5vdCBiZSBhIHN1ZmZpeCBpZiB0aGUgZG9tYWluCgkJCS8vIGlzIHNob3J0ZXIgdGhhbiB0aGUgZG9tYWluIHN0cmluZwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoc3Vic3RyKCRzdHJpbmcsIC0xICogc3RybGVuKCRkb21haW5fc3RyaW5nKSkgIT09ICRkb21haW5fc3RyaW5nKSB7CgkJCS8vIFRoZSBkb21haW4gc3RyaW5nIHNob3VsZCBiZSBhIHN1ZmZpeCBvZiB0aGUgc3RyaW5nLgoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkcHJlZml4ID0gc3Vic3RyKCRzdHJpbmcsIDAsIHN0cmxlbigkc3RyaW5nKSAtIHN0cmxlbigkZG9tYWluX3N0cmluZykpOwoJCWlmIChzdWJzdHIoJHByZWZpeCwgLTEpICE9PSAnLicpIHsKCQkJLy8gVGhlIGxhc3QgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgdGhhdCBpcyBub3QgaW5jbHVkZWQgaW4gdGhlCgkJCS8vIGRvbWFpbiBzdHJpbmcgc2hvdWxkIGJlIGEgJXgyRSAoIi4iKSBjaGFyYWN0ZXIuCgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8vIFRoZSBzdHJpbmcgc2hvdWxkIGJlIGEgaG9zdCBuYW1lIChpLmUuLCBub3QgYW4gSVAgYWRkcmVzcykuCgkJcmV0dXJuICFwcmVnX21hdGNoKCcjXiguK1wuKVxkezEsM31cLlxkezEsM31cLlxkezEsM31cLlxkezEsM30kIycsICRzdHJpbmcpOwoJfQoKCS8qKgoJICogQ2hlY2sgaWYgYSBjb29raWUgaXMgdmFsaWQgZm9yIGEgZ2l2ZW4gcGF0aAoJICoKCSAqIEZyb20gdGhlIHBhdGgtbWF0Y2ggY2hlY2sgaW4gUkZDIDYyNjUgc2VjdGlvbiA1LjEuNAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlcXVlc3RfcGF0aCBQYXRoIHRvIGNoZWNrCgkgKiBAcmV0dXJuIGJvb2xlYW4gV2hldGhlciB0aGUgY29va2llIGlzIHZhbGlkIGZvciB0aGUgZ2l2ZW4gcGF0aAoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0aF9tYXRjaGVzKCRyZXF1ZXN0X3BhdGgpIHsKCQlpZiAoZW1wdHkoJHJlcXVlc3RfcGF0aCkpIHsKCQkJLy8gTm9ybWFsaXplIGVtcHR5IHBhdGggdG8gcm9vdAoJCQkkcmVxdWVzdF9wYXRoID0gJy8nOwoJCX0KCgkJaWYgKCFpc3NldCgkdGhpcy0+YXR0cmlidXRlc1sncGF0aCddKSkgewoJCQkvLyBDb29raWVzIGNyZWF0ZWQgbWFudWFsbHk7IGNvb2tpZXMgY3JlYXRlZCBieSBSZXF1ZXN0cyB3aWxsIHNldAoJCQkvLyB0aGUgcGF0aCB0byB0aGUgcmVxdWVzdGVkIHBhdGgKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkY29va2llX3BhdGggPSAkdGhpcy0+YXR0cmlidXRlc1sncGF0aCddOwoKCQlpZiAoJGNvb2tpZV9wYXRoID09PSAkcmVxdWVzdF9wYXRoKSB7CgkJCS8vIFRoZSBjb29raWUtcGF0aCBhbmQgdGhlIHJlcXVlc3QtcGF0aCBhcmUgaWRlbnRpY2FsLgoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCWlmIChzdHJsZW4oJHJlcXVlc3RfcGF0aCkgPiBzdHJsZW4oJGNvb2tpZV9wYXRoKSAmJiBzdWJzdHIoJHJlcXVlc3RfcGF0aCwgMCwgc3RybGVuKCRjb29raWVfcGF0aCkpID09PSAkY29va2llX3BhdGgpIHsKCQkJaWYgKHN1YnN0cigkY29va2llX3BhdGgsIC0xKSA9PT0gJy8nKSB7CgkJCQkvLyBUaGUgY29va2llLXBhdGggaXMgYSBwcmVmaXggb2YgdGhlIHJlcXVlc3QtcGF0aCwgYW5kIHRoZSBsYXN0CgkJCQkvLyBjaGFyYWN0ZXIgb2YgdGhlIGNvb2tpZS1wYXRoIGlzICV4MkYgKCIvIikuCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJaWYgKHN1YnN0cigkcmVxdWVzdF9wYXRoLCBzdHJsZW4oJGNvb2tpZV9wYXRoKSwgMSkgPT09ICcvJykgewoJCQkJLy8gVGhlIGNvb2tpZS1wYXRoIGlzIGEgcHJlZml4IG9mIHRoZSByZXF1ZXN0LXBhdGgsIGFuZCB0aGUKCQkJCS8vIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgcmVxdWVzdC1wYXRoIHRoYXQgaXMgbm90IGluY2x1ZGVkIGluCgkJCQkvLyB0aGUgY29va2llLXBhdGggaXMgYSAleDJGICgiLyIpIGNoYXJhY3Rlci4KCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBOb3JtYWxpemUgY29va2llIGFuZCBhdHRyaWJ1dGVzCgkgKgoJICogQHJldHVybiBib29sZWFuIFdoZXRoZXIgdGhlIGNvb2tpZSB3YXMgc3VjY2Vzc2Z1bGx5IG5vcm1hbGl6ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG5vcm1hbGl6ZSgpIHsKCQlmb3JlYWNoICgkdGhpcy0+YXR0cmlidXRlcyBhcyAka2V5ID0+ICR2YWx1ZSkgewoJCQkkb3JpZ192YWx1ZSA9ICR2YWx1ZTsKCQkJJHZhbHVlICAgICAgPSAkdGhpcy0+bm9ybWFsaXplX2F0dHJpYnV0ZSgka2V5LCAkdmFsdWUpOwoJCQlpZiAoJHZhbHVlID09PSBudWxsKSB7CgkJCQl1bnNldCgkdGhpcy0+YXR0cmlidXRlc1ska2V5XSk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCR2YWx1ZSAhPT0gJG9yaWdfdmFsdWUpIHsKCQkJCSR0aGlzLT5hdHRyaWJ1dGVzWyRrZXldID0gJHZhbHVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFBhcnNlIGFuIGluZGl2aWR1YWwgY29va2llIGF0dHJpYnV0ZQoJICoKCSAqIEhhbmRsZXMgcGFyc2luZyBpbmRpdmlkdWFsIGF0dHJpYnV0ZXMgZnJvbSB0aGUgY29va2llIHZhbHVlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIEF0dHJpYnV0ZSBuYW1lCgkgKiBAcGFyYW0gc3RyaW5nfGJvb2xlYW4gJHZhbHVlIEF0dHJpYnV0ZSB2YWx1ZSAoc3RyaW5nIHZhbHVlLCBvciB0cnVlIGlmIGVtcHR5L2ZsYWcpCgkgKiBAcmV0dXJuIG1peGVkIFZhbHVlIGlmIGF2YWlsYWJsZSwgb3IgbnVsbCBpZiB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIGludmFsaWQgKGFuZCBzaG91bGQgYmUgc2tpcHBlZCkKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIG5vcm1hbGl6ZV9hdHRyaWJ1dGUoJG5hbWUsICR2YWx1ZSkgewoJCXN3aXRjaCAoc3RydG9sb3dlcigkbmFtZSkpIHsKCQkJY2FzZSAnZXhwaXJlcyc6CgkJCQkvLyBFeHBpcmF0aW9uIHBhcnNpbmcsIGFzIHBlciBSRkMgNjI2NSBzZWN0aW9uIDUuMi4xCgkJCQlpZiAoaXNfaW50KCR2YWx1ZSkpIHsKCQkJCQlyZXR1cm4gJHZhbHVlOwoJCQkJfQoKCQkJCSRleHBpcnlfdGltZSA9IHN0cnRvdGltZSgkdmFsdWUpOwoJCQkJaWYgKCRleHBpcnlfdGltZSA9PT0gZmFsc2UpIHsKCQkJCQlyZXR1cm4gbnVsbDsKCQkJCX0KCgkJCQlyZXR1cm4gJGV4cGlyeV90aW1lOwoKCQkJY2FzZSAnbWF4LWFnZSc6CgkJCQkvLyBFeHBpcmF0aW9uIHBhcnNpbmcsIGFzIHBlciBSRkMgNjI2NSBzZWN0aW9uIDUuMi4yCgkJCQlpZiAoaXNfaW50KCR2YWx1ZSkpIHsKCQkJCQlyZXR1cm4gJHZhbHVlOwoJCQkJfQoKCQkJCS8vIENoZWNrIHRoYXQgd2UgaGF2ZSBhIHZhbGlkIGFnZQoJCQkJaWYgKCFwcmVnX21hdGNoKCcvXi0/XGQrJC8nLCAkdmFsdWUpKSB7CgkJCQkJcmV0dXJuIG51bGw7CgkJCQl9CgoJCQkJJGRlbHRhX3NlY29uZHMgPSAoaW50KSAkdmFsdWU7CgkJCQlpZiAoJGRlbHRhX3NlY29uZHMgPD0gMCkgewoJCQkJCSRleHBpcnlfdGltZSA9IDA7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkkZXhwaXJ5X3RpbWUgPSAkdGhpcy0+cmVmZXJlbmNlX3RpbWUgKyAkZGVsdGFfc2Vjb25kczsKCQkJCX0KCgkJCQlyZXR1cm4gJGV4cGlyeV90aW1lOwoKCQkJY2FzZSAnZG9tYWluJzoKCQkJCS8vIERvbWFpbnMgYXJlIG5vdCByZXF1aXJlZCBhcyBwZXIgUkZDIDYyNjUgc2VjdGlvbiA1LjIuMwoJCQkJaWYgKGVtcHR5KCR2YWx1ZSkpIHsKCQkJCQlyZXR1cm4gbnVsbDsKCQkJCX0KCgkJCQkvLyBEb21haW4gbm9ybWFsaXphdGlvbiwgYXMgcGVyIFJGQyA2MjY1IHNlY3Rpb24gNS4yLjMKCQkJCWlmICgkdmFsdWVbMF0gPT09ICcuJykgewoJCQkJCSR2YWx1ZSA9IHN1YnN0cigkdmFsdWUsIDEpOwoJCQkJfQoKCQkJCXJldHVybiAkdmFsdWU7CgoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuICR2YWx1ZTsKCQl9Cgl9CgoJLyoqCgkgKiBGb3JtYXQgYSBjb29raWUgZm9yIGEgQ29va2llIGhlYWRlcgoJICoKCSAqIFRoaXMgaXMgdXNlZCB3aGVuIHNlbmRpbmcgY29va2llcyB0byBhIHNlcnZlci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBDb29raWUgZm9ybWF0dGVkIGZvciBDb29raWUgaGVhZGVyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmb3JtYXRfZm9yX2hlYWRlcigpIHsKCQlyZXR1cm4gc3ByaW50ZignJXM9JXMnLCAkdGhpcy0+bmFtZSwgJHRoaXMtPnZhbHVlKTsKCX0KCgkvKioKCSAqIEZvcm1hdCBhIGNvb2tpZSBmb3IgYSBDb29raWUgaGVhZGVyCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQGRlcHJlY2F0ZWQgVXNlIHtAc2VlIFJlcXVlc3RzX0Nvb2tpZTo6Zm9ybWF0X2Zvcl9oZWFkZXJ9CgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZm9ybWF0Rm9ySGVhZGVyKCkgewoJCXJldHVybiAkdGhpcy0+Zm9ybWF0X2Zvcl9oZWFkZXIoKTsKCX0KCgkvKioKCSAqIEZvcm1hdCBhIGNvb2tpZSBmb3IgYSBTZXQtQ29va2llIGhlYWRlcgoJICoKCSAqIFRoaXMgaXMgdXNlZCB3aGVuIHNlbmRpbmcgY29va2llcyB0byBjbGllbnRzLiBUaGlzIGlzbid0IHJlYWxseQoJICogYXBwbGljYWJsZSB0byBjbGllbnQtc2lkZSB1c2FnZSwgYnV0IG1pZ2h0IGJlIGhhbmR5IGZvciBkZWJ1Z2dpbmcuCgkgKgoJICogQHJldHVybiBzdHJpbmcgQ29va2llIGZvcm1hdHRlZCBmb3IgU2V0LUNvb2tpZSBoZWFkZXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZvcm1hdF9mb3Jfc2V0X2Nvb2tpZSgpIHsKCQkkaGVhZGVyX3ZhbHVlID0gJHRoaXMtPmZvcm1hdF9mb3JfaGVhZGVyKCk7CgkJaWYgKCFlbXB0eSgkdGhpcy0+YXR0cmlidXRlcykpIHsKCQkJJHBhcnRzID0gYXJyYXkoKTsKCQkJZm9yZWFjaCAoJHRoaXMtPmF0dHJpYnV0ZXMgYXMgJGtleSA9PiAkdmFsdWUpIHsKCQkJCS8vIElnbm9yZSBub24tYXNzb2NpYXRpdmUgYXR0cmlidXRlcwoJCQkJaWYgKGlzX251bWVyaWMoJGtleSkpIHsKCQkJCQkkcGFydHNbXSA9ICR2YWx1ZTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCSRwYXJ0c1tdID0gc3ByaW50ZignJXM9JXMnLCAka2V5LCAkdmFsdWUpOwoJCQkJfQoJCQl9CgoJCQkkaGVhZGVyX3ZhbHVlIC49ICc7ICcgLiBpbXBsb2RlKCc7ICcsICRwYXJ0cyk7CgkJfQoJCXJldHVybiAkaGVhZGVyX3ZhbHVlOwoJfQoKCS8qKgoJICogRm9ybWF0IGEgY29va2llIGZvciBhIFNldC1Db29raWUgaGVhZGVyCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQGRlcHJlY2F0ZWQgVXNlIHtAc2VlIFJlcXVlc3RzX0Nvb2tpZTo6Zm9ybWF0X2Zvcl9zZXRfY29va2llfQoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZvcm1hdEZvclNldENvb2tpZSgpIHsKCQlyZXR1cm4gJHRoaXMtPmZvcm1hdF9mb3Jfc2V0X2Nvb2tpZSgpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb29raWUgdmFsdWUKCSAqCgkgKiBBdHRyaWJ1dGVzIGFuZCBvdGhlciBkYXRhIGNhbiBiZSBhY2Nlc3NlZCB2aWEgbWV0aG9kcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKSB7CgkJcmV0dXJuICR0aGlzLT52YWx1ZTsKCX0KCgkvKioKCSAqIFBhcnNlIGEgY29va2llIHN0cmluZyBpbnRvIGEgY29va2llIG9iamVjdAoJICoKCSAqIEJhc2VkIG9uIE1vemlsbGEncyBwYXJzaW5nIGNvZGUgaW4gRmlyZWZveCBhbmQgcmVsYXRlZCBwcm9qZWN0cywgd2hpY2gKCSAqIGlzIGFuIGludGVudGlvbmFsIGRldmlhdGlvbiBmcm9tIFJGQyAyMTA5IGFuZCBSRkMgMjYxNi4gUkZDIDYyNjUKCSAqIHNwZWNpZmllcyBzb21lIG9mIHRoaXMgaGFuZGxpbmcsIGJ1dCBub3QgaW4gYSB0aG9yb3VnaCBtYW5uZXIuCgkgKgoJICogQHBhcmFtIHN0cmluZyBDb29raWUgaGVhZGVyIHZhbHVlIChmcm9tIGEgU2V0LUNvb2tpZSBoZWFkZXIpCgkgKiBAcmV0dXJuIFJlcXVlc3RzX0Nvb2tpZSBQYXJzZWQgY29va2llIG9iamVjdAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhcnNlKCRzdHJpbmcsICRuYW1lID0gJycsICRyZWZlcmVuY2VfdGltZSA9IG51bGwpIHsKCQkkcGFydHMgICA9IGV4cGxvZGUoJzsnLCAkc3RyaW5nKTsKCQkka3ZwYXJ0cyA9IGFycmF5X3NoaWZ0KCRwYXJ0cyk7CgoJCWlmICghZW1wdHkoJG5hbWUpKSB7CgkJCSR2YWx1ZSA9ICRzdHJpbmc7CgkJfQoJCWVsc2VpZiAoc3RycG9zKCRrdnBhcnRzLCAnPScpID09PSBmYWxzZSkgewoJCQkvLyBTb21lIHNpdGVzIG1pZ2h0IG9ubHkgaGF2ZSBhIHZhbHVlIHdpdGhvdXQgdGhlIGVxdWFscyBzZXBhcmF0b3IuCgkJCS8vIERldmlhdGUgZnJvbSBSRkMgNjI2NSBhbmQgcHJldGVuZCBpdCB3YXMgYWN0dWFsbHkgYSBibGFuayBuYW1lCgkJCS8vIChgPWZvb2ApCgkJCS8vCgkJCS8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTE2OTA5MQoJCQkkbmFtZSAgPSAnJzsKCQkJJHZhbHVlID0gJGt2cGFydHM7CgkJfQoJCWVsc2UgewoJCQlsaXN0KCRuYW1lLCAkdmFsdWUpID0gZXhwbG9kZSgnPScsICRrdnBhcnRzLCAyKTsKCQl9CgkJJG5hbWUgID0gdHJpbSgkbmFtZSk7CgkJJHZhbHVlID0gdHJpbSgkdmFsdWUpOwoKCQkvLyBBdHRyaWJ1dGUga2V5IGFyZSBoYW5kbGVkIGNhc2UtaW5zZW5zaXRpdmVseQoJCSRhdHRyaWJ1dGVzID0gbmV3IFJlcXVlc3RzX1V0aWxpdHlfQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSgpOwoKCQlpZiAoIWVtcHR5KCRwYXJ0cykpIHsKCQkJZm9yZWFjaCAoJHBhcnRzIGFzICRwYXJ0KSB7CgkJCQlpZiAoc3RycG9zKCRwYXJ0LCAnPScpID09PSBmYWxzZSkgewoJCQkJCSRwYXJ0X2tleSAgID0gJHBhcnQ7CgkJCQkJJHBhcnRfdmFsdWUgPSB0cnVlOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJbGlzdCgkcGFydF9rZXksICRwYXJ0X3ZhbHVlKSA9IGV4cGxvZGUoJz0nLCAkcGFydCwgMik7CgkJCQkJJHBhcnRfdmFsdWUgICAgICAgICAgICAgICAgICA9IHRyaW0oJHBhcnRfdmFsdWUpOwoJCQkJfQoKCQkJCSRwYXJ0X2tleSAgICAgICAgICAgICAgPSB0cmltKCRwYXJ0X2tleSk7CgkJCQkkYXR0cmlidXRlc1skcGFydF9rZXldID0gJHBhcnRfdmFsdWU7CgkJCX0KCQl9CgoJCXJldHVybiBuZXcgUmVxdWVzdHNfQ29va2llKCRuYW1lLCAkdmFsdWUsICRhdHRyaWJ1dGVzLCBhcnJheSgpLCAkcmVmZXJlbmNlX3RpbWUpOwoJfQoKCS8qKgoJICogUGFyc2UgYWxsIFNldC1Db29raWUgaGVhZGVycyBmcm9tIHJlcXVlc3QgaGVhZGVycwoJICoKCSAqIEBwYXJhbSBSZXF1ZXN0c19SZXNwb25zZV9IZWFkZXJzICRoZWFkZXJzIEhlYWRlcnMgdG8gcGFyc2UgZnJvbQoJICogQHBhcmFtIFJlcXVlc3RzX0lSSXxudWxsICRvcmlnaW4gVVJJIGZvciBjb21wYXJpbmcgY29va2llIG9yaWdpbnMKCSAqIEBwYXJhbSBpbnR8bnVsbCAkdGltZSBSZWZlcmVuY2UgdGltZSBmb3IgZXhwaXJhdGlvbiBjYWxjdWxhdGlvbgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhcnNlX2Zyb21faGVhZGVycyhSZXF1ZXN0c19SZXNwb25zZV9IZWFkZXJzICRoZWFkZXJzLCBSZXF1ZXN0c19JUkkgJG9yaWdpbiA9IG51bGwsICR0aW1lID0gbnVsbCkgewoJCSRjb29raWVfaGVhZGVycyA9ICRoZWFkZXJzLT5nZXRWYWx1ZXMoJ1NldC1Db29raWUnKTsKCQlpZiAoZW1wdHkoJGNvb2tpZV9oZWFkZXJzKSkgewoJCQlyZXR1cm4gYXJyYXkoKTsKCQl9CgoJCSRjb29raWVzID0gYXJyYXkoKTsKCQlmb3JlYWNoICgkY29va2llX2hlYWRlcnMgYXMgJGhlYWRlcikgewoJCQkkcGFyc2VkID0gc2VsZjo6cGFyc2UoJGhlYWRlciwgJycsICR0aW1lKTsKCgkJCS8vIERlZmF1bHQgZG9tYWluL3BhdGggYXR0cmlidXRlcwoJCQlpZiAoZW1wdHkoJHBhcnNlZC0+YXR0cmlidXRlc1snZG9tYWluJ10pICYmICFlbXB0eSgkb3JpZ2luKSkgewoJCQkJJHBhcnNlZC0+YXR0cmlidXRlc1snZG9tYWluJ10gPSAkb3JpZ2luLT5ob3N0OwoJCQkJJHBhcnNlZC0+ZmxhZ3NbJ2hvc3Qtb25seSddICAgPSB0cnVlOwoJCQl9CgkJCWVsc2UgewoJCQkJJHBhcnNlZC0+ZmxhZ3NbJ2hvc3Qtb25seSddID0gZmFsc2U7CgkJCX0KCgkJCSRwYXRoX2lzX3ZhbGlkID0gKCFlbXB0eSgkcGFyc2VkLT5hdHRyaWJ1dGVzWydwYXRoJ10pICYmICRwYXJzZWQtPmF0dHJpYnV0ZXNbJ3BhdGgnXVswXSA9PT0gJy8nKTsKCQkJaWYgKCEkcGF0aF9pc192YWxpZCAmJiAhZW1wdHkoJG9yaWdpbikpIHsKCQkJCSRwYXRoID0gJG9yaWdpbi0+cGF0aDsKCgkJCQkvLyBEZWZhdWx0IHBhdGggbm9ybWFsaXphdGlvbiBhcyBwZXIgUkZDIDYyNjUgc2VjdGlvbiA1LjEuNAoJCQkJaWYgKHN1YnN0cigkcGF0aCwgMCwgMSkgIT09ICcvJykgewoJCQkJCS8vIElmIHRoZSB1cmktcGF0aCBpcyBlbXB0eSBvciBpZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCgkJCQkJLy8gdGhlIHVyaS1wYXRoIGlzIG5vdCBhICV4MkYgKCIvIikgY2hhcmFjdGVyLCBvdXRwdXQKCQkJCQkvLyAleDJGICgiLyIpIGFuZCBza2lwIHRoZSByZW1haW5pbmcgc3RlcHMuCgkJCQkJJHBhdGggPSAnLyc7CgkJCQl9CgkJCQllbHNlaWYgKHN1YnN0cl9jb3VudCgkcGF0aCwgJy8nKSA9PT0gMSkgewoJCQkJCS8vIElmIHRoZSB1cmktcGF0aCBjb250YWlucyBubyBtb3JlIHRoYW4gb25lICV4MkYgKCIvIikKCQkJCQkvLyBjaGFyYWN0ZXIsIG91dHB1dCAleDJGICgiLyIpIGFuZCBza2lwIHRoZSByZW1haW5pbmcKCQkJCQkvLyBzdGVwLgoJCQkJCSRwYXRoID0gJy8nOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJLy8gT3V0cHV0IHRoZSBjaGFyYWN0ZXJzIG9mIHRoZSB1cmktcGF0aCBmcm9tIHRoZSBmaXJzdAoJCQkJCS8vIGNoYXJhY3RlciB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIHRoZSByaWdodC1tb3N0CgkJCQkJLy8gJXgyRiAoIi8iKS4KCQkJCQkkcGF0aCA9IHN1YnN0cigkcGF0aCwgMCwgc3RycnBvcygkcGF0aCwgJy8nKSk7CgkJCQl9CgkJCQkkcGFyc2VkLT5hdHRyaWJ1dGVzWydwYXRoJ10gPSAkcGF0aDsKCQkJfQoKCQkJLy8gUmVqZWN0IGludmFsaWQgY29va2llIGRvbWFpbnMKCQkJaWYgKCFlbXB0eSgkb3JpZ2luKSAmJiAhJHBhcnNlZC0+ZG9tYWluX21hdGNoZXMoJG9yaWdpbi0+aG9zdCkpIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkY29va2llc1skcGFyc2VkLT5uYW1lXSA9ICRwYXJzZWQ7CgkJfQoKCQlyZXR1cm4gJGNvb2tpZXM7Cgl9CgoJLyoqCgkgKiBQYXJzZSBhbGwgU2V0LUNvb2tpZSBoZWFkZXJzIGZyb20gcmVxdWVzdCBoZWFkZXJzCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQGRlcHJlY2F0ZWQgVXNlIHtAc2VlIFJlcXVlc3RzX0Nvb2tpZTo6cGFyc2VfZnJvbV9oZWFkZXJzfQoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhcnNlRnJvbUhlYWRlcnMoUmVxdWVzdHNfUmVzcG9uc2VfSGVhZGVycyAkaGVhZGVycykgewoJCXJldHVybiBzZWxmOjpwYXJzZV9mcm9tX2hlYWRlcnMoJGhlYWRlcnMpOwoJfQp9Cjw/cGhwCi8qKgogKiBTZXNzaW9uIGhhbmRsZXIgZm9yIHBlcnNpc3RlbnQgcmVxdWVzdHMgYW5kIGRlZmF1bHQgcGFyYW1ldGVycwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBTZXNzaW9uIEhhbmRsZXIKICovCgovKioKICogU2Vzc2lvbiBoYW5kbGVyIGZvciBwZXJzaXN0ZW50IHJlcXVlc3RzIGFuZCBkZWZhdWx0IHBhcmFtZXRlcnMKICoKICogQWxsb3dzIHZhcmlvdXMgb3B0aW9ucyB0byBiZSBzZXQgYXMgZGVmYXVsdCB2YWx1ZXMsIGFuZCBtZXJnZXMgYm90aCB0aGUKICogb3B0aW9ucyBhbmQgVVJMIHByb3BlcnRpZXMgdG9nZXRoZXIuIEEgYmFzZSBVUkwgY2FuIGJlIHNldCBmb3IgYWxsIHJlcXVlc3RzLAogKiB3aXRoIGFsbCBzdWJyZXF1ZXN0cyByZXNvbHZlZCBmcm9tIHRoaXMuIEJhc2Ugb3B0aW9ucyBjYW4gYmUgc2V0IChpbmNsdWRpbmcKICogYSBzaGFyZWQgY29va2llIGphciksIHRoZW4gb3ZlcnJpZGRlbiBmb3IgaW5kaXZpZHVhbCByZXF1ZXN0cy4KICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgU2Vzc2lvbiBIYW5kbGVyCiAqLwpjbGFzcyBSZXF1ZXN0c19TZXNzaW9uIHsKCS8qKgoJICogQmFzZSBVUkwgZm9yIHJlcXVlc3RzCgkgKgoJICogVVJMcyB3aWxsIGJlIG1hZGUgYWJzb2x1dGUgdXNpbmcgdGhpcyBhcyB0aGUgYmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nfG51bGwKCSAqLwoJcHVibGljICR1cmwgPSBudWxsOwoKCS8qKgoJICogQmFzZSBoZWFkZXJzIGZvciByZXF1ZXN0cwoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHVibGljICRoZWFkZXJzID0gYXJyYXkoKTsKCgkvKioKCSAqIEJhc2UgZGF0YSBmb3IgcmVxdWVzdHMKCSAqCgkgKiBJZiBib3RoIHRoZSBiYXNlIGRhdGEgYW5kIHRoZSBwZXItcmVxdWVzdCBkYXRhIGFyZSBhcnJheXMsIHRoZSBkYXRhIHdpbGwKCSAqIGJlIG1lcmdlZCBiZWZvcmUgc2VuZGluZyB0aGUgcmVxdWVzdC4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXB1YmxpYyAkZGF0YSA9IGFycmF5KCk7CgoJLyoqCgkgKiBCYXNlIG9wdGlvbnMgZm9yIHJlcXVlc3RzCgkgKgoJICogVGhlIGJhc2Ugb3B0aW9ucyBhcmUgbWVyZ2VkIHdpdGggdGhlIHBlci1yZXF1ZXN0IGRhdGEgZm9yIGVhY2ggcmVxdWVzdC4KCSAqIFRoZSBvbmx5IGRlZmF1bHQgb3B0aW9uIGlzIGEgc2hhcmVkIGNvb2tpZSBqYXIgYmV0d2VlbiByZXF1ZXN0cy4KCSAqCgkgKiBWYWx1ZXMgaGVyZSBjYW4gYWxzbyBiZSBzZXQgZGlyZWN0bHkgdmlhIHByb3BlcnRpZXMgb24gdGhlIFNlc3Npb24KCSAqIG9iamVjdCwgZS5nLiBgJHNlc3Npb24tPnVzZXJhZ2VudCA9ICdYJztgCgkgKgoJICogQHZhciBhcnJheQoJICovCglwdWJsaWMgJG9wdGlvbnMgPSBhcnJheSgpOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IHNlc3Npb24KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHVybCBCYXNlIFVSTCBmb3IgcmVxdWVzdHMKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBEZWZhdWx0IGhlYWRlcnMgZm9yIHJlcXVlc3RzCgkgKiBAcGFyYW0gYXJyYXkgJGRhdGEgRGVmYXVsdCBkYXRhIGZvciByZXF1ZXN0cwoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIERlZmF1bHQgb3B0aW9ucyBmb3IgcmVxdWVzdHMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR1cmwgPSBudWxsLCAkaGVhZGVycyA9IGFycmF5KCksICRkYXRhID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJJHRoaXMtPnVybCAgICAgPSAkdXJsOwoJCSR0aGlzLT5oZWFkZXJzID0gJGhlYWRlcnM7CgkJJHRoaXMtPmRhdGEgICAgPSAkZGF0YTsKCQkkdGhpcy0+b3B0aW9ucyA9ICRvcHRpb25zOwoKCQlpZiAoZW1wdHkoJHRoaXMtPm9wdGlvbnNbJ2Nvb2tpZXMnXSkpIHsKCQkJJHRoaXMtPm9wdGlvbnNbJ2Nvb2tpZXMnXSA9IG5ldyBSZXF1ZXN0c19Db29raWVfSmFyKCk7CgkJfQoJfQoKCS8qKgoJICogR2V0IGEgcHJvcGVydHkncyB2YWx1ZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBQcm9wZXJ0eSBrZXkKCSAqIEByZXR1cm4gbWl4ZWR8bnVsbCBQcm9wZXJ0eSB2YWx1ZSwgbnVsbCBpZiBub25lIGZvdW5kCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgka2V5KSB7CgkJaWYgKGlzc2V0KCR0aGlzLT5vcHRpb25zWyRrZXldKSkgewoJCQlyZXR1cm4gJHRoaXMtPm9wdGlvbnNbJGtleV07CgkJfQoKCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFNldCBhIHByb3BlcnR5J3MgdmFsdWUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgUHJvcGVydHkga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFByb3BlcnR5IHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX3NldCgka2V5LCAkdmFsdWUpIHsKCQkkdGhpcy0+b3B0aW9uc1ska2V5XSA9ICR2YWx1ZTsKCX0KCgkvKioKCSAqIFJlbW92ZSBhIHByb3BlcnR5J3MgdmFsdWUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgUHJvcGVydHkga2V5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2lzc2V0KCRrZXkpIHsKCQlyZXR1cm4gaXNzZXQoJHRoaXMtPm9wdGlvbnNbJGtleV0pOwoJfQoKCS8qKgoJICogUmVtb3ZlIGEgcHJvcGVydHkncyB2YWx1ZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBQcm9wZXJ0eSBrZXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdW5zZXQoJGtleSkgewoJCWlmIChpc3NldCgkdGhpcy0+b3B0aW9uc1ska2V5XSkpIHsKCQkJdW5zZXQoJHRoaXMtPm9wdGlvbnNbJGtleV0pOwoJCX0KCX0KCgkvKiojQCsKCSAqIEBzZWUgcmVxdWVzdCgpCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycwoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1Jlc3BvbnNlCgkgKi8KCS8qKgoJICogU2VuZCBhIEdFVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsIG51bGwsIFJlcXVlc3RzOjpHRVQsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIFNlbmQgYSBIRUFEIHJlcXVlc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGhlYWQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsIG51bGwsIFJlcXVlc3RzOjpIRUFELCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgREVMRVRFIHJlcXVlc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiAkdGhpcy0+cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgbnVsbCwgUmVxdWVzdHM6OkRFTEVURSwgJG9wdGlvbnMpOwoJfQoJLyoqI0AtKi8KCgkvKiojQCsKCSAqIEBzZWUgcmVxdWVzdCgpCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycwoJICogQHBhcmFtIGFycmF5ICRkYXRhCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKCSAqIEByZXR1cm4gUmVxdWVzdHNfUmVzcG9uc2UKCSAqLwoJLyoqCgkgKiBTZW5kIGEgUE9TVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwb3N0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsICRkYXRhLCBSZXF1ZXN0czo6UE9TVCwgJG9wdGlvbnMpOwoJfQoKCS8qKgoJICogU2VuZCBhIFBVVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwdXQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiAkdGhpcy0+cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIFJlcXVlc3RzOjpQVVQsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIFNlbmQgYSBQQVRDSCByZXF1ZXN0CgkgKgoJICogTm90ZTogVW5saWtlIHtAc2VlIHBvc3R9IGFuZCB7QHNlZSBwdXR9LCBgJGhlYWRlcnNgIGlzIHJlcXVpcmVkLCBhcyB0aGUKCSAqIHNwZWNpZmljYXRpb24gcmVjb21tZW5kcyB0aGF0IHNob3VsZCBzZW5kIGFuIEVUYWcKCSAqCgkgKiBAbGluayBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTc4OQoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0Y2goJHVybCwgJGhlYWRlcnMsICRkYXRhID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJcmV0dXJuICR0aGlzLT5yZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgUmVxdWVzdHM6OlBBVENILCAkb3B0aW9ucyk7Cgl9CgkvKiojQC0qLwoKCS8qKgoJICogTWFpbiBpbnRlcmZhY2UgZm9yIEhUVFAgcmVxdWVzdHMKCSAqCgkgKiBUaGlzIG1ldGhvZCBpbml0aWF0ZXMgYSByZXF1ZXN0IGFuZCBzZW5kcyBpdCB2aWEgYSB0cmFuc3BvcnQgYmVmb3JlCgkgKiBwYXJzaW5nLgoJICoKCSAqIEBzZWUgUmVxdWVzdHM6OnJlcXVlc3QoKQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGludmFsaWQgVVJMcyAoYG5vbmh0dHBgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgdG8gcmVxdWVzdAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIEV4dHJhIGhlYWRlcnMgdG8gc2VuZCB3aXRoIHRoZSByZXF1ZXN0CgkgKiBAcGFyYW0gYXJyYXl8bnVsbCAkZGF0YSBEYXRhIHRvIHNlbmQgZWl0aGVyIGFzIGEgcXVlcnkgc3RyaW5nIGZvciBHRVQvSEVBRCByZXF1ZXN0cywgb3IgaW4gdGhlIGJvZHkgZm9yIFBPU1QgcmVxdWVzdHMKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgSFRUUCByZXF1ZXN0IHR5cGUgKHVzZSBSZXF1ZXN0cyBjb25zdGFudHMpCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHJlcXVlc3QgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0pCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1Jlc3BvbnNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXF1ZXN0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkdHlwZSA9IFJlcXVlc3RzOjpHRVQsICRvcHRpb25zID0gYXJyYXkoKSkgewoJCSRyZXF1ZXN0ID0gJHRoaXMtPm1lcmdlX3JlcXVlc3QoY29tcGFjdCgndXJsJywgJ2hlYWRlcnMnLCAnZGF0YScsICdvcHRpb25zJykpOwoKCQlyZXR1cm4gUmVxdWVzdHM6OnJlcXVlc3QoJHJlcXVlc3RbJ3VybCddLCAkcmVxdWVzdFsnaGVhZGVycyddLCAkcmVxdWVzdFsnZGF0YSddLCAkdHlwZSwgJHJlcXVlc3RbJ29wdGlvbnMnXSk7Cgl9CgoJLyoqCgkgKiBTZW5kIG11bHRpcGxlIEhUVFAgcmVxdWVzdHMgc2ltdWx0YW5lb3VzbHkKCSAqCgkgKiBAc2VlIFJlcXVlc3RzOjpyZXF1ZXN0X211bHRpcGxlKCkKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlcXVlc3RzIFJlcXVlc3RzIGRhdGEgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdF9tdWx0aXBsZX0pCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgR2xvYmFsIGFuZCBkZWZhdWx0IG9wdGlvbnMgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0pCgkgKiBAcmV0dXJuIGFycmF5IFJlc3BvbnNlcyAoZWl0aGVyIFJlcXVlc3RzX1Jlc3BvbnNlIG9yIGEgUmVxdWVzdHNfRXhjZXB0aW9uIG9iamVjdCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3RfbXVsdGlwbGUoJHJlcXVlc3RzLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlmb3JlYWNoICgkcmVxdWVzdHMgYXMgJGtleSA9PiAkcmVxdWVzdCkgewoJCQkkcmVxdWVzdHNbJGtleV0gPSAkdGhpcy0+bWVyZ2VfcmVxdWVzdCgkcmVxdWVzdCwgZmFsc2UpOwoJCX0KCgkJJG9wdGlvbnMgPSBhcnJheV9tZXJnZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwoKCQkvLyBEaXNhbGxvdyBmb3JjaW5nIHRoZSB0eXBlLCBhcyB0aGF0J3MgYSBwZXIgcmVxdWVzdCBzZXR0aW5nCgkJdW5zZXQoJG9wdGlvbnNbJ3R5cGUnXSk7CgoJCXJldHVybiBSZXF1ZXN0czo6cmVxdWVzdF9tdWx0aXBsZSgkcmVxdWVzdHMsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIE1lcmdlIGEgcmVxdWVzdCdzIGRhdGEgd2l0aCB0aGUgZGVmYXVsdCBkYXRhCgkgKgoJICogQHBhcmFtIGFycmF5ICRyZXF1ZXN0IFJlcXVlc3QgZGF0YSAoc2FtZSBmb3JtIGFzIHtAc2VlIHJlcXVlc3RfbXVsdGlwbGV9KQoJICogQHBhcmFtIGJvb2xlYW4gJG1lcmdlX29wdGlvbnMgU2hvdWxkIHdlIG1lcmdlIG9wdGlvbnMgYXMgd2VsbD8KCSAqIEByZXR1cm4gYXJyYXkgUmVxdWVzdCBkYXRhCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBtZXJnZV9yZXF1ZXN0KCRyZXF1ZXN0LCAkbWVyZ2Vfb3B0aW9ucyA9IHRydWUpIHsKCQlpZiAoJHRoaXMtPnVybCAhPT0gbnVsbCkgewoJCQkkcmVxdWVzdFsndXJsJ10gPSBSZXF1ZXN0c19JUkk6OmFic29sdXRpemUoJHRoaXMtPnVybCwgJHJlcXVlc3RbJ3VybCddKTsKCQkJJHJlcXVlc3RbJ3VybCddID0gJHJlcXVlc3RbJ3VybCddLT51cmk7CgkJfQoKCQlpZiAoZW1wdHkoJHJlcXVlc3RbJ2hlYWRlcnMnXSkpIHsKCQkJJHJlcXVlc3RbJ2hlYWRlcnMnXSA9IGFycmF5KCk7CgkJfQoJCSRyZXF1ZXN0WydoZWFkZXJzJ10gPSBhcnJheV9tZXJnZSgkdGhpcy0+aGVhZGVycywgJHJlcXVlc3RbJ2hlYWRlcnMnXSk7CgoJCWlmIChlbXB0eSgkcmVxdWVzdFsnZGF0YSddKSkgewoJCQlpZiAoaXNfYXJyYXkoJHRoaXMtPmRhdGEpKSB7CgkJCQkkcmVxdWVzdFsnZGF0YSddID0gJHRoaXMtPmRhdGE7CgkJCX0KCQl9CgkJZWxzZWlmIChpc19hcnJheSgkcmVxdWVzdFsnZGF0YSddKSAmJiBpc19hcnJheSgkdGhpcy0+ZGF0YSkpIHsKCQkJJHJlcXVlc3RbJ2RhdGEnXSA9IGFycmF5X21lcmdlKCR0aGlzLT5kYXRhLCAkcmVxdWVzdFsnZGF0YSddKTsKCQl9CgoJCWlmICgkbWVyZ2Vfb3B0aW9ucyAhPT0gZmFsc2UpIHsKCQkJJHJlcXVlc3RbJ29wdGlvbnMnXSA9IGFycmF5X21lcmdlKCR0aGlzLT5vcHRpb25zLCAkcmVxdWVzdFsnb3B0aW9ucyddKTsKCgkJCS8vIERpc2FsbG93IGZvcmNpbmcgdGhlIHR5cGUsIGFzIHRoYXQncyBhIHBlciByZXF1ZXN0IHNldHRpbmcKCQkJdW5zZXQoJHJlcXVlc3RbJ29wdGlvbnMnXVsndHlwZSddKTsKCQl9CgoJCXJldHVybiAkcmVxdWVzdDsKCX0KfQo8P3BocAovKioKICogQ2FzZS1pbnNlbnNpdGl2ZSBkaWN0aW9uYXJ5LCBzdWl0YWJsZSBmb3IgSFRUUCBoZWFkZXJzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KCi8qKgogKiBDYXNlLWluc2Vuc2l0aXZlIGRpY3Rpb25hcnksIHN1aXRhYmxlIGZvciBIVFRQIGhlYWRlcnMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwpjbGFzcyBSZXF1ZXN0c19VdGlsaXR5X0Nhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgaW1wbGVtZW50cyBBcnJheUFjY2VzcywgSXRlcmF0b3JBZ2dyZWdhdGUgewoJLyoqCgkgKiBBY3R1YWwgaXRlbSBkYXRhCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcm90ZWN0ZWQgJGRhdGEgPSBhcnJheSgpOwoKCS8qKgoJICogQ3JlYXRlcyBhIGNhc2UgaW5zZW5zaXRpdmUgZGljdGlvbmFyeS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGRhdGEgRGljdGlvbmFyeS9tYXAgdG8gY29udmVydCB0byBjYXNlLWluc2Vuc2l0aXZlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZGF0YSA9IGFycmF5KCkpIHsKCQlmb3JlYWNoICgkZGF0YSBhcyAka2V5ID0+ICR2YWx1ZSkgewoJCQkkdGhpcy0+b2Zmc2V0U2V0KCRrZXksICR2YWx1ZSk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIGdpdmVuIGl0ZW0gZXhpc3RzCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0ga2V5CgkgKiBAcmV0dXJuIGJvb2xlYW4gRG9lcyB0aGUgaXRlbSBleGlzdD8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldEV4aXN0cygka2V5KSB7CgkJJGtleSA9IHN0cnRvbG93ZXIoJGtleSk7CgkJcmV0dXJuIGlzc2V0KCR0aGlzLT5kYXRhWyRrZXldKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBpdGVtCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0ga2V5CgkgKiBAcmV0dXJuIHN0cmluZ3xudWxsIEl0ZW0gdmFsdWUgKG51bGwgaWYgb2Zmc2V0RXhpc3RzIGlzIGZhbHNlKQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0R2V0KCRrZXkpIHsKCQkka2V5ID0gc3RydG9sb3dlcigka2V5KTsKCQlpZiAoIWlzc2V0KCR0aGlzLT5kYXRhWyRrZXldKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiAkdGhpcy0+ZGF0YVska2V5XTsKCX0KCgkvKioKCSAqIFNldCB0aGUgZ2l2ZW4gaXRlbQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGF0dGVtcHRpbmcgdG8gdXNlIGRpY3Rpb25hcnkgYXMgbGlzdCAoYGludmFsaWRzZXRgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBJdGVtIG5hbWUKCSAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIEl0ZW0gdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldFNldCgka2V5LCAkdmFsdWUpIHsKCQlpZiAoJGtleSA9PT0gbnVsbCkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdPYmplY3QgaXMgYSBkaWN0aW9uYXJ5LCBub3QgYSBsaXN0JywgJ2ludmFsaWRzZXQnKTsKCQl9CgoJCSRrZXkgICAgICAgICAgICAgID0gc3RydG9sb3dlcigka2V5KTsKCQkkdGhpcy0+ZGF0YVska2V5XSA9ICR2YWx1ZTsKCX0KCgkvKioKCSAqIFVuc2V0IHRoZSBnaXZlbiBoZWFkZXIKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldFVuc2V0KCRrZXkpIHsKCQl1bnNldCgkdGhpcy0+ZGF0YVtzdHJ0b2xvd2VyKCRrZXkpXSk7Cgl9CgoJLyoqCgkgKiBHZXQgYW4gaXRlcmF0b3IgZm9yIHRoZSBkYXRhCgkgKgoJICogQHJldHVybiBBcnJheUl0ZXJhdG9yCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRJdGVyYXRvcigpIHsKCQlyZXR1cm4gbmV3IEFycmF5SXRlcmF0b3IoJHRoaXMtPmRhdGEpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBoZWFkZXJzIGFzIGFuIGFycmF5CgkgKgoJICogQHJldHVybiBhcnJheSBIZWFkZXIgZGF0YQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0QWxsKCkgewoJCXJldHVybiAkdGhpcy0+ZGF0YTsKCX0KfQo8P3BocAovKioKICogSXRlcmF0b3IgZm9yIGFycmF5cyByZXF1aXJpbmcgZmlsdGVyZWQgdmFsdWVzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KCi8qKgogKiBJdGVyYXRvciBmb3IgYXJyYXlzIHJlcXVpcmluZyBmaWx0ZXJlZCB2YWx1ZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwpjbGFzcyBSZXF1ZXN0c19VdGlsaXR5X0ZpbHRlcmVkSXRlcmF0b3IgZXh0ZW5kcyBBcnJheUl0ZXJhdG9yIHsKCS8qKgoJICogQ2FsbGJhY2sgdG8gcnVuIGFzIGEgZmlsdGVyCgkgKgoJICogQHZhciBjYWxsYWJsZQoJICovCglwcm90ZWN0ZWQgJGNhbGxiYWNrOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IGl0ZXJhdG9yCgkgKgoJICogQHBhcmFtIGFycmF5ICRkYXRhCgkgKiBAcGFyYW0gY2FsbGFibGUgJGNhbGxiYWNrIENhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBlYWNoIHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZGF0YSwgJGNhbGxiYWNrKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkZGF0YSk7CgoJCSR0aGlzLT5jYWxsYmFjayA9ICRjYWxsYmFjazsKCX0KCgkvKioKCSAqIEdldCB0aGUgY3VycmVudCBpdGVtJ3MgdmFsdWUgYWZ0ZXIgZmlsdGVyaW5nCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJJHZhbHVlID0gcGFyZW50OjpjdXJyZW50KCk7CgoJCWlmIChpc19jYWxsYWJsZSgkdGhpcy0+Y2FsbGJhY2spKSB7CgkJCSR2YWx1ZSA9IGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5jYWxsYmFjaywgJHZhbHVlKTsKCQl9CgoJCXJldHVybiAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBAaW5oZXJpdGRvYwoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zZXJpYWxpemUoJHNlcmlhbGl6ZWQpIHt9CgoJLyoqCgkgKiBAaW5oZXJpdGRvYwoJICoKCSAqIEBwaHBjczpkaXNhYmxlIFBIUENvbXBhdGliaWxpdHkuRnVuY3Rpb25OYW1lUmVzdHJpY3Rpb25zLk5ld01hZ2ljTWV0aG9kcy5fX3Vuc2VyaWFsaXplRm91bmQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdW5zZXJpYWxpemUoJHNlcmlhbGl6ZWQpIHt9CgoJcHVibGljIGZ1bmN0aW9uIF9fd2FrZXVwKCkgewoJCXVuc2V0KCR0aGlzLT5jYWxsYmFjayk7Cgl9Cn0KPD9waHAKLyoqCiAqIElSSSBwYXJzZXIvc2VyaWFsaXNlci9ub3JtYWxpc2VyCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KCi8qKgogKiBJUkkgcGFyc2VyL3NlcmlhbGlzZXIvbm9ybWFsaXNlcgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAxMCwgR2VvZmZyZXkgU25lZGRvbiBhbmQgU3RldmUgTWludXRpbGxvLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAqCiAqICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogKiAgICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCiAqICAgICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTaW1wbGVQaWUgVGVhbSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMKICogICAgICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlCiAqICAgICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTICJBUyBJUyIKICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgQkUKICogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRgogKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MKICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4KICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkKICogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUKICogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKiBAYXV0aG9yIEdlb2ZmcmV5IFNuZWRkb24KICogQGF1dGhvciBTdGV2ZSBNaW51dGlsbG8KICogQGNvcHlyaWdodCAyMDA3LTIwMDkgR2VvZmZyZXkgU25lZGRvbiBhbmQgU3RldmUgTWludXRpbGxvCiAqIEBsaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvYnNkLWxpY2Vuc2UucGhwCiAqIEBsaW5rIGh0dHA6Ly9oZy5nc25lZGRlcnMuY29tL2lyaS8KICoKICogQHByb3BlcnR5IHN0cmluZyAkaXJpIElSSSB3ZSdyZSB3b3JraW5nIHdpdGgKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICR1cmkgSVJJIGluIFVSSSBmb3JtLCB7QHNlZSB0b191cml9CiAqIEBwcm9wZXJ0eSBzdHJpbmcgJHNjaGVtZSBTY2hlbWUgcGFydCBvZiB0aGUgSVJJCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGF1dGhvcml0eSBBdXRob3JpdHkgcGFydCwgZm9ybWF0dGVkIGZvciBhIFVSSSAodXNlcmluZm8gKyBob3N0ICsgcG9ydCkKICogQHByb3BlcnR5IHN0cmluZyAkaWF1dGhvcml0eSBBdXRob3JpdHkgcGFydCBvZiB0aGUgSVJJICh1c2VyaW5mbyArIGhvc3QgKyBwb3J0KQogKiBAcHJvcGVydHkgc3RyaW5nICR1c2VyaW5mbyBVc2VyaW5mbyBwYXJ0LCBmb3JtYXR0ZWQgZm9yIGEgVVJJIChhZnRlciAnOi8vJyBhbmQgYmVmb3JlICdAJykKICogQHByb3BlcnR5IHN0cmluZyAkaXVzZXJpbmZvIFVzZXJpbmZvIHBhcnQgb2YgdGhlIElSSSAoYWZ0ZXIgJzovLycgYW5kIGJlZm9yZSAnQCcpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGhvc3QgSG9zdCBwYXJ0LCBmb3JtYXR0ZWQgZm9yIGEgVVJJCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGlob3N0IEhvc3QgcGFydCBvZiB0aGUgSVJJCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJHBvcnQgUG9ydCBwYXJ0IG9mIHRoZSBJUkkgKGFmdGVyICc6JykKICogQHByb3BlcnR5IHN0cmluZyAkcGF0aCBQYXRoIHBhcnQsIGZvcm1hdHRlZCBmb3IgYSBVUkkgKGFmdGVyIGZpcnN0ICcvJykKICogQHByb3BlcnR5IHN0cmluZyAkaXBhdGggUGF0aCBwYXJ0IG9mIHRoZSBJUkkgKGFmdGVyIGZpcnN0ICcvJykKICogQHByb3BlcnR5IHN0cmluZyAkcXVlcnkgUXVlcnkgcGFydCwgZm9ybWF0dGVkIGZvciBhIFVSSSAoYWZ0ZXIgJz8nKQogKiBAcHJvcGVydHkgc3RyaW5nICRpcXVlcnkgUXVlcnkgcGFydCBvZiB0aGUgSVJJIChhZnRlciAnPycpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGZyYWdtZW50IEZyYWdtZW50LCBmb3JtYXR0ZWQgZm9yIGEgVVJJIChhZnRlciAnIycpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGlmcmFnbWVudCBGcmFnbWVudCBwYXJ0IG9mIHRoZSBJUkkgKGFmdGVyICcjJykKICovCmNsYXNzIFJlcXVlc3RzX0lSSSB7CgkvKioKCSAqIFNjaGVtZQoJICoKCSAqIEB2YXIgc3RyaW5nfG51bGwKCSAqLwoJcHJvdGVjdGVkICRzY2hlbWUgPSBudWxsOwoKCS8qKgoJICogVXNlciBJbmZvcm1hdGlvbgoJICoKCSAqIEB2YXIgc3RyaW5nfG51bGwKCSAqLwoJcHJvdGVjdGVkICRpdXNlcmluZm8gPSBudWxsOwoKCS8qKgoJICogaWhvc3QKCSAqCgkgKiBAdmFyIHN0cmluZ3xudWxsCgkgKi8KCXByb3RlY3RlZCAkaWhvc3QgPSBudWxsOwoKCS8qKgoJICogUG9ydAoJICoKCSAqIEB2YXIgc3RyaW5nfG51bGwKCSAqLwoJcHJvdGVjdGVkICRwb3J0ID0gbnVsbDsKCgkvKioKCSAqIGlwYXRoCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRpcGF0aCA9ICcnOwoKCS8qKgoJICogaXF1ZXJ5CgkgKgoJICogQHZhciBzdHJpbmd8bnVsbAoJICovCglwcm90ZWN0ZWQgJGlxdWVyeSA9IG51bGw7CgoJLyoqCgkgKiBpZnJhZ21lbnR8bnVsbAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkaWZyYWdtZW50ID0gbnVsbDsKCgkvKioKCSAqIE5vcm1hbGl6YXRpb24gZGF0YWJhc2UKCSAqCgkgKiBFYWNoIGtleSBpcyB0aGUgc2NoZW1lLCBlYWNoIHZhbHVlIGlzIGFuIGFycmF5IHdpdGggZWFjaCBrZXkgYXMgdGhlIElSSQoJICogcGFydCBhbmQgdmFsdWUgYXMgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoYXQgcGFydC4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkbm9ybWFsaXphdGlvbiA9IGFycmF5KAoJCSdhY2FwJyA9PiBhcnJheSgKCQkJJ3BvcnQnID0+IDY3NAoJCSksCgkJJ2RpY3QnID0+IGFycmF5KAoJCQkncG9ydCcgPT4gMjYyOAoJCSksCgkJJ2ZpbGUnID0+IGFycmF5KAoJCQknaWhvc3QnID0+ICdsb2NhbGhvc3QnCgkJKSwKCQknaHR0cCcgPT4gYXJyYXkoCgkJCSdwb3J0JyA9PiA4MCwKCQkpLAoJCSdodHRwcycgPT4gYXJyYXkoCgkJCSdwb3J0JyA9PiA0NDMsCgkJKSwKCSk7CgoJLyoqCgkgKiBSZXR1cm4gdGhlIGVudGlyZSBJUkkgd2hlbiB5b3UgdHJ5IGFuZCByZWFkIHRoZSBvYmplY3QgYXMgYSBzdHJpbmcKCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpIHsKCQlyZXR1cm4gJHRoaXMtPmdldF9pcmkoKTsKCX0KCgkvKioKCSAqIE92ZXJsb2FkIF9fc2V0KCkgdG8gcHJvdmlkZSBhY2Nlc3MgdmlhIHByb3BlcnRpZXMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFByb3BlcnR5IG5hbWUKCSAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgUHJvcGVydHkgdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fc2V0KCRuYW1lLCAkdmFsdWUpIHsKCQlpZiAobWV0aG9kX2V4aXN0cygkdGhpcywgJ3NldF8nIC4gJG5hbWUpKSB7CgkJCWNhbGxfdXNlcl9mdW5jKGFycmF5KCR0aGlzLCAnc2V0XycgLiAkbmFtZSksICR2YWx1ZSk7CgkJfQoJCWVsc2VpZiAoCgkJCSAgICRuYW1lID09PSAnaWF1dGhvcml0eScKCQkJfHwgJG5hbWUgPT09ICdpdXNlcmluZm8nCgkJCXx8ICRuYW1lID09PSAnaWhvc3QnCgkJCXx8ICRuYW1lID09PSAnaXBhdGgnCgkJCXx8ICRuYW1lID09PSAnaXF1ZXJ5JwoJCQl8fCAkbmFtZSA9PT0gJ2lmcmFnbWVudCcKCQkpIHsKCQkJY2FsbF91c2VyX2Z1bmMoYXJyYXkoJHRoaXMsICdzZXRfJyAuIHN1YnN0cigkbmFtZSwgMSkpLCAkdmFsdWUpOwoJCX0KCX0KCgkvKioKCSAqIE92ZXJsb2FkIF9fZ2V0KCkgdG8gcHJvdmlkZSBhY2Nlc3MgdmlhIHByb3BlcnRpZXMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFByb3BlcnR5IG5hbWUKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fZ2V0KCRuYW1lKSB7CgkJLy8gaXNzZXQoKSByZXR1cm5zIGZhbHNlIGZvciBudWxsLCB3ZSBkb24ndCB3YW50IHRvIGRvIHRoYXQKCQkvLyBBbHNvIHdoeSB3ZSB1c2UgYXJyYXlfa2V5X2V4aXN0cyBiZWxvdyBpbnN0ZWFkIG9mIGlzc2V0KCkKCQkkcHJvcHMgPSBnZXRfb2JqZWN0X3ZhcnMoJHRoaXMpOwoKCQlpZiAoCgkJCSRuYW1lID09PSAnaXJpJyB8fAoJCQkkbmFtZSA9PT0gJ3VyaScgfHwKCQkJJG5hbWUgPT09ICdpYXV0aG9yaXR5JyB8fAoJCQkkbmFtZSA9PT0gJ2F1dGhvcml0eScKCQkpIHsKCQkJJG1ldGhvZCA9ICdnZXRfJyAuICRuYW1lOwoJCQkkcmV0dXJuID0gJHRoaXMtPiRtZXRob2QoKTsKCQl9CgkJZWxzZWlmIChhcnJheV9rZXlfZXhpc3RzKCRuYW1lLCAkcHJvcHMpKSB7CgkJCSRyZXR1cm4gPSAkdGhpcy0+JG5hbWU7CgkJfQoJCS8vIGhvc3QgLT4gaWhvc3QKCQllbHNlaWYgKCgkcHJvcCA9ICdpJyAuICRuYW1lKSAmJiBhcnJheV9rZXlfZXhpc3RzKCRwcm9wLCAkcHJvcHMpKSB7CgkJCSRuYW1lID0gJHByb3A7CgkJCSRyZXR1cm4gPSAkdGhpcy0+JHByb3A7CgkJfQoJCS8vIGlzY2hlbWUgLT4gc2NoZW1lCgkJZWxzZWlmICgoJHByb3AgPSBzdWJzdHIoJG5hbWUsIDEpKSAmJiBhcnJheV9rZXlfZXhpc3RzKCRwcm9wLCAkcHJvcHMpKSB7CgkJCSRuYW1lID0gJHByb3A7CgkJCSRyZXR1cm4gPSAkdGhpcy0+JHByb3A7CgkJfQoJCWVsc2UgewoJCQl0cmlnZ2VyX2Vycm9yKCdVbmRlZmluZWQgcHJvcGVydHk6ICcgLiBnZXRfY2xhc3MoJHRoaXMpIC4gJzo6JyAuICRuYW1lLCBFX1VTRVJfTk9USUNFKTsKCQkJJHJldHVybiA9IG51bGw7CgkJfQoKCQlpZiAoJHJldHVybiA9PT0gbnVsbCAmJiBpc3NldCgkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVskbmFtZV0pKSB7CgkJCXJldHVybiAkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVskbmFtZV07CgkJfQoJCWVsc2UgewoJCQlyZXR1cm4gJHJldHVybjsKCQl9Cgl9CgoJLyoqCgkgKiBPdmVybG9hZCBfX2lzc2V0KCkgdG8gcHJvdmlkZSBhY2Nlc3MgdmlhIHByb3BlcnRpZXMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFByb3BlcnR5IG5hbWUKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pc3NldCgkbmFtZSkgewoJCXJldHVybiAobWV0aG9kX2V4aXN0cygkdGhpcywgJ2dldF8nIC4gJG5hbWUpIHx8IGlzc2V0KCR0aGlzLT4kbmFtZSkpOwoJfQoKCS8qKgoJICogT3ZlcmxvYWQgX191bnNldCgpIHRvIHByb3ZpZGUgYWNjZXNzIHZpYSBwcm9wZXJ0aWVzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBQcm9wZXJ0eSBuYW1lCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX3Vuc2V0KCRuYW1lKSB7CgkJaWYgKG1ldGhvZF9leGlzdHMoJHRoaXMsICdzZXRfJyAuICRuYW1lKSkgewoJCQljYWxsX3VzZXJfZnVuYyhhcnJheSgkdGhpcywgJ3NldF8nIC4gJG5hbWUpLCAnJyk7CgkJfQoJfQoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IElSSSBvYmplY3QsIGZyb20gYSBzcGVjaWZpZWQgc3RyaW5nCgkgKgoJICogQHBhcmFtIHN0cmluZ3xudWxsICRpcmkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRpcmkgPSBudWxsKSB7CgkJJHRoaXMtPnNldF9pcmkoJGlyaSk7Cgl9CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgSVJJIG9iamVjdCBieSByZXNvbHZpbmcgYSByZWxhdGl2ZSBJUkkKCSAqCgkgKiBSZXR1cm5zIGZhbHNlIGlmICRiYXNlIGlzIG5vdCBhYnNvbHV0ZSwgb3RoZXJ3aXNlIGFuIElSSS4KCSAqCgkgKiBAcGFyYW0gUmVxdWVzdHNfSVJJfHN0cmluZyAkYmFzZSAoQWJzb2x1dGUpIEJhc2UgSVJJCgkgKiBAcGFyYW0gUmVxdWVzdHNfSVJJfHN0cmluZyAkcmVsYXRpdmUgUmVsYXRpdmUgSVJJCgkgKiBAcmV0dXJuIFJlcXVlc3RzX0lSSXxmYWxzZQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFic29sdXRpemUoJGJhc2UsICRyZWxhdGl2ZSkgewoJCWlmICghKCRyZWxhdGl2ZSBpbnN0YW5jZW9mIFJlcXVlc3RzX0lSSSkpIHsKCQkJJHJlbGF0aXZlID0gbmV3IFJlcXVlc3RzX0lSSSgkcmVsYXRpdmUpOwoJCX0KCQlpZiAoISRyZWxhdGl2ZS0+aXNfdmFsaWQoKSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWVsc2VpZiAoJHJlbGF0aXZlLT5zY2hlbWUgIT09IG51bGwpIHsKCQkJcmV0dXJuIGNsb25lICRyZWxhdGl2ZTsKCQl9CgoJCWlmICghKCRiYXNlIGluc3RhbmNlb2YgUmVxdWVzdHNfSVJJKSkgewoJCQkkYmFzZSA9IG5ldyBSZXF1ZXN0c19JUkkoJGJhc2UpOwoJCX0KCQlpZiAoJGJhc2UtPnNjaGVtZSA9PT0gbnVsbCB8fCAhJGJhc2UtPmlzX3ZhbGlkKCkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKCRyZWxhdGl2ZS0+Z2V0X2lyaSgpICE9PSAnJykgewoJCQlpZiAoJHJlbGF0aXZlLT5pdXNlcmluZm8gIT09IG51bGwgfHwgJHJlbGF0aXZlLT5paG9zdCAhPT0gbnVsbCB8fCAkcmVsYXRpdmUtPnBvcnQgIT09IG51bGwpIHsKCQkJCSR0YXJnZXQgPSBjbG9uZSAkcmVsYXRpdmU7CgkJCQkkdGFyZ2V0LT5zY2hlbWUgPSAkYmFzZS0+c2NoZW1lOwoJCQl9CgkJCWVsc2UgewoJCQkJJHRhcmdldCA9IG5ldyBSZXF1ZXN0c19JUkk7CgkJCQkkdGFyZ2V0LT5zY2hlbWUgPSAkYmFzZS0+c2NoZW1lOwoJCQkJJHRhcmdldC0+aXVzZXJpbmZvID0gJGJhc2UtPml1c2VyaW5mbzsKCQkJCSR0YXJnZXQtPmlob3N0ID0gJGJhc2UtPmlob3N0OwoJCQkJJHRhcmdldC0+cG9ydCA9ICRiYXNlLT5wb3J0OwoJCQkJaWYgKCRyZWxhdGl2ZS0+aXBhdGggIT09ICcnKSB7CgkJCQkJaWYgKCRyZWxhdGl2ZS0+aXBhdGhbMF0gPT09ICcvJykgewoJCQkJCQkkdGFyZ2V0LT5pcGF0aCA9ICRyZWxhdGl2ZS0+aXBhdGg7CgkJCQkJfQoJCQkJCWVsc2VpZiAoKCRiYXNlLT5pdXNlcmluZm8gIT09IG51bGwgfHwgJGJhc2UtPmlob3N0ICE9PSBudWxsIHx8ICRiYXNlLT5wb3J0ICE9PSBudWxsKSAmJiAkYmFzZS0+aXBhdGggPT09ICcnKSB7CgkJCQkJCSR0YXJnZXQtPmlwYXRoID0gJy8nIC4gJHJlbGF0aXZlLT5pcGF0aDsKCQkJCQl9CgkJCQkJZWxzZWlmICgoJGxhc3Rfc2VnbWVudCA9IHN0cnJwb3MoJGJhc2UtPmlwYXRoLCAnLycpKSAhPT0gZmFsc2UpIHsKCQkJCQkJJHRhcmdldC0+aXBhdGggPSBzdWJzdHIoJGJhc2UtPmlwYXRoLCAwLCAkbGFzdF9zZWdtZW50ICsgMSkgLiAkcmVsYXRpdmUtPmlwYXRoOwoJCQkJCX0KCQkJCQllbHNlIHsKCQkJCQkJJHRhcmdldC0+aXBhdGggPSAkcmVsYXRpdmUtPmlwYXRoOwoJCQkJCX0KCQkJCQkkdGFyZ2V0LT5pcGF0aCA9ICR0YXJnZXQtPnJlbW92ZV9kb3Rfc2VnbWVudHMoJHRhcmdldC0+aXBhdGgpOwoJCQkJCSR0YXJnZXQtPmlxdWVyeSA9ICRyZWxhdGl2ZS0+aXF1ZXJ5OwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJJHRhcmdldC0+aXBhdGggPSAkYmFzZS0+aXBhdGg7CgkJCQkJaWYgKCRyZWxhdGl2ZS0+aXF1ZXJ5ICE9PSBudWxsKSB7CgkJCQkJCSR0YXJnZXQtPmlxdWVyeSA9ICRyZWxhdGl2ZS0+aXF1ZXJ5OwoJCQkJCX0KCQkJCQllbHNlaWYgKCRiYXNlLT5pcXVlcnkgIT09IG51bGwpIHsKCQkJCQkJJHRhcmdldC0+aXF1ZXJ5ID0gJGJhc2UtPmlxdWVyeTsKCQkJCQl9CgkJCQl9CgkJCQkkdGFyZ2V0LT5pZnJhZ21lbnQgPSAkcmVsYXRpdmUtPmlmcmFnbWVudDsKCQkJfQoJCX0KCQllbHNlIHsKCQkJJHRhcmdldCA9IGNsb25lICRiYXNlOwoJCQkkdGFyZ2V0LT5pZnJhZ21lbnQgPSBudWxsOwoJCX0KCQkkdGFyZ2V0LT5zY2hlbWVfbm9ybWFsaXphdGlvbigpOwoJCXJldHVybiAkdGFyZ2V0OwoJfQoKCS8qKgoJICogUGFyc2UgYW4gSVJJIGludG8gc2NoZW1lL2F1dGhvcml0eS9wYXRoL3F1ZXJ5L2ZyYWdtZW50IHNlZ21lbnRzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXJpCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZV9pcmkoJGlyaSkgewoJCSRpcmkgPSB0cmltKCRpcmksICJceDIwXHgwOVx4MEFceDBDXHgwRCIpOwoJCSRoYXNfbWF0Y2ggPSBwcmVnX21hdGNoKCcvXigoP1A8c2NoZW1lPlteOlwvPyNdKyk6KT8oXC9cLyg/UDxhdXRob3JpdHk+W15cLz8jXSopKT8oP1A8cGF0aD5bXj8jXSopKFw/KD9QPHF1ZXJ5PlteI10qKSk/KCMoP1A8ZnJhZ21lbnQ+LiopKT8kLycsICRpcmksICRtYXRjaCk7CgkJaWYgKCEkaGFzX21hdGNoKSB7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0Nhbm5vdCBwYXJzZSBzdXBwbGllZCBJUkknLCAnaXJpLmNhbm5vdF9wYXJzZScsICRpcmkpOwoJCX0KCgkJaWYgKCRtYXRjaFsxXSA9PT0gJycpIHsKCQkJJG1hdGNoWydzY2hlbWUnXSA9IG51bGw7CgkJfQoJCWlmICghaXNzZXQoJG1hdGNoWzNdKSB8fCAkbWF0Y2hbM10gPT09ICcnKSB7CgkJCSRtYXRjaFsnYXV0aG9yaXR5J10gPSBudWxsOwoJCX0KCQlpZiAoIWlzc2V0KCRtYXRjaFs1XSkpIHsKCQkJJG1hdGNoWydwYXRoJ10gPSAnJzsKCQl9CgkJaWYgKCFpc3NldCgkbWF0Y2hbNl0pIHx8ICRtYXRjaFs2XSA9PT0gJycpIHsKCQkJJG1hdGNoWydxdWVyeSddID0gbnVsbDsKCQl9CgkJaWYgKCFpc3NldCgkbWF0Y2hbOF0pIHx8ICRtYXRjaFs4XSA9PT0gJycpIHsKCQkJJG1hdGNoWydmcmFnbWVudCddID0gbnVsbDsKCQl9CgkJcmV0dXJuICRtYXRjaDsKCX0KCgkvKioKCSAqIFJlbW92ZSBkb3Qgc2VnbWVudHMgZnJvbSBhIHBhdGgKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRpbnB1dAoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbW92ZV9kb3Rfc2VnbWVudHMoJGlucHV0KSB7CgkJJG91dHB1dCA9ICcnOwoJCXdoaWxlIChzdHJwb3MoJGlucHV0LCAnLi8nKSAhPT0gZmFsc2UgfHwgc3RycG9zKCRpbnB1dCwgJy8uJykgIT09IGZhbHNlIHx8ICRpbnB1dCA9PT0gJy4nIHx8ICRpbnB1dCA9PT0gJy4uJykgewoJCQkvLyBBOiBJZiB0aGUgaW5wdXQgYnVmZmVyIGJlZ2lucyB3aXRoIGEgcHJlZml4IG9mICIuLi8iIG9yICIuLyIsCgkJCS8vIHRoZW4gcmVtb3ZlIHRoYXQgcHJlZml4IGZyb20gdGhlIGlucHV0IGJ1ZmZlcjsgb3RoZXJ3aXNlLAoJCQlpZiAoc3RycG9zKCRpbnB1dCwgJy4uLycpID09PSAwKSB7CgkJCQkkaW5wdXQgPSBzdWJzdHIoJGlucHV0LCAzKTsKCQkJfQoJCQllbHNlaWYgKHN0cnBvcygkaW5wdXQsICcuLycpID09PSAwKSB7CgkJCQkkaW5wdXQgPSBzdWJzdHIoJGlucHV0LCAyKTsKCQkJfQoJCQkvLyBCOiBpZiB0aGUgaW5wdXQgYnVmZmVyIGJlZ2lucyB3aXRoIGEgcHJlZml4IG9mICIvLi8iIG9yICIvLiIsCgkJCS8vIHdoZXJlICIuIiBpcyBhIGNvbXBsZXRlIHBhdGggc2VnbWVudCwgdGhlbiByZXBsYWNlIHRoYXQgcHJlZml4CgkJCS8vIHdpdGggIi8iIGluIHRoZSBpbnB1dCBidWZmZXI7IG90aGVyd2lzZSwKCQkJZWxzZWlmIChzdHJwb3MoJGlucHV0LCAnLy4vJykgPT09IDApIHsKCQkJCSRpbnB1dCA9IHN1YnN0cigkaW5wdXQsIDIpOwoJCQl9CgkJCWVsc2VpZiAoJGlucHV0ID09PSAnLy4nKSB7CgkJCQkkaW5wdXQgPSAnLyc7CgkJCX0KCQkJLy8gQzogaWYgdGhlIGlucHV0IGJ1ZmZlciBiZWdpbnMgd2l0aCBhIHByZWZpeCBvZiAiLy4uLyIgb3IgIi8uLiIsCgkJCS8vIHdoZXJlICIuLiIgaXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQsIHRoZW4gcmVwbGFjZSB0aGF0IHByZWZpeAoJCQkvLyB3aXRoICIvIiBpbiB0aGUgaW5wdXQgYnVmZmVyIGFuZCByZW1vdmUgdGhlIGxhc3Qgc2VnbWVudCBhbmQgaXRzCgkJCS8vIHByZWNlZGluZyAiLyIgKGlmIGFueSkgZnJvbSB0aGUgb3V0cHV0IGJ1ZmZlcjsgb3RoZXJ3aXNlLAoJCQllbHNlaWYgKHN0cnBvcygkaW5wdXQsICcvLi4vJykgPT09IDApIHsKCQkJCSRpbnB1dCA9IHN1YnN0cigkaW5wdXQsIDMpOwoJCQkJJG91dHB1dCA9IHN1YnN0cl9yZXBsYWNlKCRvdXRwdXQsICcnLCBzdHJycG9zKCRvdXRwdXQsICcvJykpOwoJCQl9CgkJCWVsc2VpZiAoJGlucHV0ID09PSAnLy4uJykgewoJCQkJJGlucHV0ID0gJy8nOwoJCQkJJG91dHB1dCA9IHN1YnN0cl9yZXBsYWNlKCRvdXRwdXQsICcnLCBzdHJycG9zKCRvdXRwdXQsICcvJykpOwoJCQl9CgkJCS8vIEQ6IGlmIHRoZSBpbnB1dCBidWZmZXIgY29uc2lzdHMgb25seSBvZiAiLiIgb3IgIi4uIiwgdGhlbiByZW1vdmUKCQkJLy8gdGhhdCBmcm9tIHRoZSBpbnB1dCBidWZmZXI7IG90aGVyd2lzZSwKCQkJZWxzZWlmICgkaW5wdXQgPT09ICcuJyB8fCAkaW5wdXQgPT09ICcuLicpIHsKCQkJCSRpbnB1dCA9ICcnOwoJCQl9CgkJCS8vIEU6IG1vdmUgdGhlIGZpcnN0IHBhdGggc2VnbWVudCBpbiB0aGUgaW5wdXQgYnVmZmVyIHRvIHRoZSBlbmQgb2YKCQkJLy8gdGhlIG91dHB1dCBidWZmZXIsIGluY2x1ZGluZyB0aGUgaW5pdGlhbCAiLyIgY2hhcmFjdGVyIChpZiBhbnkpCgkJCS8vIGFuZCBhbnkgc3Vic2VxdWVudCBjaGFyYWN0ZXJzIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgdGhlIG5leHQKCQkJLy8gIi8iIGNoYXJhY3RlciBvciB0aGUgZW5kIG9mIHRoZSBpbnB1dCBidWZmZXIKCQkJZWxzZWlmICgoJHBvcyA9IHN0cnBvcygkaW5wdXQsICcvJywgMSkpICE9PSBmYWxzZSkgewoJCQkJJG91dHB1dCAuPSBzdWJzdHIoJGlucHV0LCAwLCAkcG9zKTsKCQkJCSRpbnB1dCA9IHN1YnN0cl9yZXBsYWNlKCRpbnB1dCwgJycsIDAsICRwb3MpOwoJCQl9CgkJCWVsc2UgewoJCQkJJG91dHB1dCAuPSAkaW5wdXQ7CgkJCQkkaW5wdXQgPSAnJzsKCQkJfQoJCX0KCQlyZXR1cm4gJG91dHB1dCAuICRpbnB1dDsKCX0KCgkvKioKCSAqIFJlcGxhY2UgaW52YWxpZCBjaGFyYWN0ZXIgd2l0aCBwZXJjZW50IGVuY29kaW5nCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIElucHV0IHN0cmluZwoJICogQHBhcmFtIHN0cmluZyAkZXh0cmFfY2hhcnMgVmFsaWQgY2hhcmFjdGVycyBub3QgaW4gaXVucmVzZXJ2ZWQgb3IKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlwcml2YXRlICh0aGlzIGlzIEFTQ0lJLW9ubHkpCgkgKiBAcGFyYW0gYm9vbCAkaXByaXZhdGUgQWxsb3cgaXByaXZhdGUKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiByZXBsYWNlX2ludmFsaWRfd2l0aF9wY3RfZW5jb2RpbmcoJHN0cmluZywgJGV4dHJhX2NoYXJzLCAkaXByaXZhdGUgPSBmYWxzZSkgewoJCS8vIE5vcm1hbGl6ZSBhcyBtYW55IHBjdC1lbmNvZGVkIHNlY3Rpb25zIGFzIHBvc3NpYmxlCgkJJHN0cmluZyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygnLyg/OiVbQS1GYS1mMC05XXsyfSkrLycsIGFycmF5KCR0aGlzLCAncmVtb3ZlX2l1bnJlc2VydmVkX3BlcmNlbnRfZW5jb2RlZCcpLCAkc3RyaW5nKTsKCgkJLy8gUmVwbGFjZSBpbnZhbGlkIHBlcmNlbnQgY2hhcmFjdGVycwoJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoJy8lKD8hW0EtRmEtZjAtOV17Mn0pLycsICclMjUnLCAkc3RyaW5nKTsKCgkJLy8gQWRkIHVucmVzZXJ2ZWQgYW5kICUgdG8gJGV4dHJhX2NoYXJzICh0aGUgbGF0dGVyIGlzIHNhZmUgYmVjYXVzZSBhbGwKCQkvLyBwY3QtZW5jb2RlZCBzZWN0aW9ucyBhcmUgbm93IHZhbGlkKS4KCQkkZXh0cmFfY2hhcnMgLj0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5LS5ffiUnOwoKCQkvLyBOb3cgcmVwbGFjZSBhbnkgYnl0ZXMgdGhhdCBhcmVuJ3QgYWxsb3dlZCB3aXRoIHRoZWlyIHBjdC1lbmNvZGVkIHZlcnNpb25zCgkJJHBvc2l0aW9uID0gMDsKCQkkc3RybGVuID0gc3RybGVuKCRzdHJpbmcpOwoJCXdoaWxlICgoJHBvc2l0aW9uICs9IHN0cnNwbigkc3RyaW5nLCAkZXh0cmFfY2hhcnMsICRwb3NpdGlvbikpIDwgJHN0cmxlbikgewoJCQkkdmFsdWUgPSBvcmQoJHN0cmluZ1skcG9zaXRpb25dKTsKCgkJCS8vIFN0YXJ0IHBvc2l0aW9uCgkJCSRzdGFydCA9ICRwb3NpdGlvbjsKCgkJCS8vIEJ5IGRlZmF1bHQgd2UgYXJlIHZhbGlkCgkJCSR2YWxpZCA9IHRydWU7CgoJCQkvLyBObyBvbmUgYnl0ZSBzZXF1ZW5jZXMgYXJlIHZhbGlkIGR1ZSB0byB0aGUgd2hpbGUuCgkJCS8vIFR3byBieXRlIHNlcXVlbmNlOgoJCQlpZiAoKCR2YWx1ZSAmIDB4RTApID09PSAweEMwKSB7CgkJCQkkY2hhcmFjdGVyID0gKCR2YWx1ZSAmIDB4MUYpIDw8IDY7CgkJCQkkbGVuZ3RoID0gMjsKCQkJCSRyZW1haW5pbmcgPSAxOwoJCQl9CgkJCS8vIFRocmVlIGJ5dGUgc2VxdWVuY2U6CgkJCWVsc2VpZiAoKCR2YWx1ZSAmIDB4RjApID09PSAweEUwKSB7CgkJCQkkY2hhcmFjdGVyID0gKCR2YWx1ZSAmIDB4MEYpIDw8IDEyOwoJCQkJJGxlbmd0aCA9IDM7CgkJCQkkcmVtYWluaW5nID0gMjsKCQkJfQoJCQkvLyBGb3VyIGJ5dGUgc2VxdWVuY2U6CgkJCWVsc2VpZiAoKCR2YWx1ZSAmIDB4RjgpID09PSAweEYwKSB7CgkJCQkkY2hhcmFjdGVyID0gKCR2YWx1ZSAmIDB4MDcpIDw8IDE4OwoJCQkJJGxlbmd0aCA9IDQ7CgkJCQkkcmVtYWluaW5nID0gMzsKCQkJfQoJCQkvLyBJbnZhbGlkIGJ5dGU6CgkJCWVsc2UgewoJCQkJJHZhbGlkID0gZmFsc2U7CgkJCQkkbGVuZ3RoID0gMTsKCQkJCSRyZW1haW5pbmcgPSAwOwoJCQl9CgoJCQlpZiAoJHJlbWFpbmluZykgewoJCQkJaWYgKCRwb3NpdGlvbiArICRsZW5ndGggPD0gJHN0cmxlbikgewoJCQkJCWZvciAoJHBvc2l0aW9uKys7ICRyZW1haW5pbmc7ICRwb3NpdGlvbisrKSB7CgkJCQkJCSR2YWx1ZSA9IG9yZCgkc3RyaW5nWyRwb3NpdGlvbl0pOwoKCQkJCQkJLy8gQ2hlY2sgdGhhdCB0aGUgYnl0ZSBpcyB2YWxpZCwgdGhlbiBhZGQgaXQgdG8gdGhlIGNoYXJhY3RlcjoKCQkJCQkJaWYgKCgkdmFsdWUgJiAweEMwKSA9PT0gMHg4MCkgewoJCQkJCQkJJGNoYXJhY3RlciB8PSAoJHZhbHVlICYgMHgzRikgPDwgKC0tJHJlbWFpbmluZyAqIDYpOwoJCQkJCQl9CgkJCQkJCS8vIElmIGl0IGlzIGludmFsaWQsIGNvdW50IHRoZSBzZXF1ZW5jZSBhcyBpbnZhbGlkIGFuZCByZXByb2Nlc3MgdGhlIGN1cnJlbnQgYnl0ZToKCQkJCQkJZWxzZSB7CgkJCQkJCQkkdmFsaWQgPSBmYWxzZTsKCQkJCQkJCSRwb3NpdGlvbi0tOwoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkkcG9zaXRpb24gPSAkc3RybGVuIC0gMTsKCQkJCQkkdmFsaWQgPSBmYWxzZTsKCQkJCX0KCQkJfQoKCQkJLy8gUGVyY2VudCBlbmNvZGUgYW55dGhpbmcgaW52YWxpZCBvciBub3QgaW4gdWNzY2hhcgoJCQlpZiAoCgkJCQkvLyBJbnZhbGlkIHNlcXVlbmNlcwoJCQkJISR2YWxpZAoJCQkJLy8gTm9uLXNob3J0ZXN0IGZvcm0gc2VxdWVuY2VzIGFyZSBpbnZhbGlkCgkJCQl8fCAkbGVuZ3RoID4gMSAmJiAkY2hhcmFjdGVyIDw9IDB4N0YKCQkJCXx8ICRsZW5ndGggPiAyICYmICRjaGFyYWN0ZXIgPD0gMHg3RkYKCQkJCXx8ICRsZW5ndGggPiAzICYmICRjaGFyYWN0ZXIgPD0gMHhGRkZGCgkJCQkvLyBPdXRzaWRlIG9mIHJhbmdlIG9mIHVjc2NoYXIgY29kZXBvaW50cwoJCQkJLy8gTm9uY2hhcmFjdGVycwoJCQkJfHwgKCRjaGFyYWN0ZXIgJiAweEZGRkUpID09PSAweEZGRkUKCQkJCXx8ICRjaGFyYWN0ZXIgPj0gMHhGREQwICYmICRjaGFyYWN0ZXIgPD0gMHhGREVGCgkJCQl8fCAoCgkJCQkJLy8gRXZlcnl0aGluZyBlbHNlIG5vdCBpbiB1Y3NjaGFyCgkJCQkJICAgJGNoYXJhY3RlciA+IDB4RDdGRiAmJiAkY2hhcmFjdGVyIDwgMHhGOTAwCgkJCQkJfHwgJGNoYXJhY3RlciA8IDB4QTAKCQkJCQl8fCAkY2hhcmFjdGVyID4gMHhFRkZGRAoJCQkJKQoJCQkJJiYgKAoJCQkJCS8vIEV2ZXJ5dGhpbmcgbm90IGluIGlwcml2YXRlLCBpZiBpdCBhcHBsaWVzCgkJCQkJICAgISRpcHJpdmF0ZQoJCQkJCXx8ICRjaGFyYWN0ZXIgPCAweEUwMDAKCQkJCQl8fCAkY2hhcmFjdGVyID4gMHgxMEZGRkQKCQkJCSkKCQkJKSB7CgkJCQkvLyBJZiB3ZSB3ZXJlIGEgY2hhcmFjdGVyLCBwcmV0ZW5kIHdlIHdlcmVuJ3QsIGJ1dCByYXRoZXIgYW4gZXJyb3IuCgkJCQlpZiAoJHZhbGlkKSB7CgkJCQkJJHBvc2l0aW9uLS07CgkJCQl9CgoJCQkJZm9yICgkaiA9ICRzdGFydDsgJGogPD0gJHBvc2l0aW9uOyAkaisrKSB7CgkJCQkJJHN0cmluZyA9IHN1YnN0cl9yZXBsYWNlKCRzdHJpbmcsIHNwcmludGYoJyUlJTAyWCcsIG9yZCgkc3RyaW5nWyRqXSkpLCAkaiwgMSk7CgkJCQkJJGogKz0gMjsKCQkJCQkkcG9zaXRpb24gKz0gMjsKCQkJCQkkc3RybGVuICs9IDI7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiAkc3RyaW5nOwoJfQoKCS8qKgoJICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIHByZWdfcmVwbGFjZV9jYWxsYmFjay4KCSAqCgkgKiBSZW1vdmVzIHNlcXVlbmNlcyBvZiBwZXJjZW50IGVuY29kZWQgYnl0ZXMgdGhhdCByZXByZXNlbnQgVVRGLTgKCSAqIGVuY29kZWQgY2hhcmFjdGVycyBpbiBpdW5yZXNlcnZlZAoJICoKCSAqIEBwYXJhbSBhcnJheSAkbWF0Y2ggUENSRSBtYXRjaAoJICogQHJldHVybiBzdHJpbmcgUmVwbGFjZW1lbnQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbW92ZV9pdW5yZXNlcnZlZF9wZXJjZW50X2VuY29kZWQoJG1hdGNoKSB7CgkJLy8gQXMgd2UganVzdCBoYXZlIHZhbGlkIHBlcmNlbnQgZW5jb2RlZCBzZXF1ZW5jZXMgd2UgY2FuIGp1c3QgZXhwbG9kZQoJCS8vIGFuZCBpZ25vcmUgdGhlIGZpcnN0IG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgKGFuIGVtcHR5IHN0cmluZykuCgkJJGJ5dGVzID0gZXhwbG9kZSgnJScsICRtYXRjaFswXSk7CgoJCS8vIEluaXRpYWxpemUgdGhlIG5ldyBzdHJpbmcgKHRoaXMgaXMgd2hhdCB3aWxsIGJlIHJldHVybmVkKSBhbmQgdGhhdAoJCS8vIHRoZXJlIGFyZSBubyBieXRlcyByZW1haW5pbmcgaW4gdGhlIGN1cnJlbnQgc2VxdWVuY2UgKHVuc3VycHJpc2luZwoJCS8vIGF0IHRoZSBmaXJzdCBieXRlISkuCgkJJHN0cmluZyA9ICcnOwoJCSRyZW1haW5pbmcgPSAwOwoKCQkvLyBMb29wIG92ZXIgZWFjaCBhbmQgZXZlcnkgYnl0ZSwgYW5kIHNldCAkdmFsdWUgdG8gaXRzIHZhbHVlCgkJZm9yICgkaSA9IDEsICRsZW4gPSBjb3VudCgkYnl0ZXMpOyAkaSA8ICRsZW47ICRpKyspIHsKCQkJJHZhbHVlID0gaGV4ZGVjKCRieXRlc1skaV0pOwoKCQkJLy8gSWYgd2UncmUgdGhlIGZpcnN0IGJ5dGUgb2Ygc2VxdWVuY2U6CgkJCWlmICghJHJlbWFpbmluZykgewoJCQkJLy8gU3RhcnQgcG9zaXRpb24KCQkJCSRzdGFydCA9ICRpOwoKCQkJCS8vIEJ5IGRlZmF1bHQgd2UgYXJlIHZhbGlkCgkJCQkkdmFsaWQgPSB0cnVlOwoKCQkJCS8vIE9uZSBieXRlIHNlcXVlbmNlOgoJCQkJaWYgKCR2YWx1ZSA8PSAweDdGKSB7CgkJCQkJJGNoYXJhY3RlciA9ICR2YWx1ZTsKCQkJCQkkbGVuZ3RoID0gMTsKCQkJCX0KCQkJCS8vIFR3byBieXRlIHNlcXVlbmNlOgoJCQkJZWxzZWlmICgoJHZhbHVlICYgMHhFMCkgPT09IDB4QzApIHsKCQkJCQkkY2hhcmFjdGVyID0gKCR2YWx1ZSAmIDB4MUYpIDw8IDY7CgkJCQkJJGxlbmd0aCA9IDI7CgkJCQkJJHJlbWFpbmluZyA9IDE7CgkJCQl9CgkJCQkvLyBUaHJlZSBieXRlIHNlcXVlbmNlOgoJCQkJZWxzZWlmICgoJHZhbHVlICYgMHhGMCkgPT09IDB4RTApIHsKCQkJCQkkY2hhcmFjdGVyID0gKCR2YWx1ZSAmIDB4MEYpIDw8IDEyOwoJCQkJCSRsZW5ndGggPSAzOwoJCQkJCSRyZW1haW5pbmcgPSAyOwoJCQkJfQoJCQkJLy8gRm91ciBieXRlIHNlcXVlbmNlOgoJCQkJZWxzZWlmICgoJHZhbHVlICYgMHhGOCkgPT09IDB4RjApIHsKCQkJCQkkY2hhcmFjdGVyID0gKCR2YWx1ZSAmIDB4MDcpIDw8IDE4OwoJCQkJCSRsZW5ndGggPSA0OwoJCQkJCSRyZW1haW5pbmcgPSAzOwoJCQkJfQoJCQkJLy8gSW52YWxpZCBieXRlOgoJCQkJZWxzZSB7CgkJCQkJJHZhbGlkID0gZmFsc2U7CgkJCQkJJHJlbWFpbmluZyA9IDA7CgkJCQl9CgkJCX0KCQkJLy8gQ29udGludWF0aW9uIGJ5dGU6CgkJCWVsc2UgewoJCQkJLy8gQ2hlY2sgdGhhdCB0aGUgYnl0ZSBpcyB2YWxpZCwgdGhlbiBhZGQgaXQgdG8gdGhlIGNoYXJhY3RlcjoKCQkJCWlmICgoJHZhbHVlICYgMHhDMCkgPT09IDB4ODApIHsKCQkJCQkkcmVtYWluaW5nLS07CgkJCQkJJGNoYXJhY3RlciB8PSAoJHZhbHVlICYgMHgzRikgPDwgKCRyZW1haW5pbmcgKiA2KTsKCQkJCX0KCQkJCS8vIElmIGl0IGlzIGludmFsaWQsIGNvdW50IHRoZSBzZXF1ZW5jZSBhcyBpbnZhbGlkIGFuZCByZXByb2Nlc3MgdGhlIGN1cnJlbnQgYnl0ZSBhcyB0aGUgc3RhcnQgb2YgYSBzZXF1ZW5jZToKCQkJCWVsc2UgewoJCQkJCSR2YWxpZCA9IGZhbHNlOwoJCQkJCSRyZW1haW5pbmcgPSAwOwoJCQkJCSRpLS07CgkJCQl9CgkJCX0KCgkJCS8vIElmIHdlJ3ZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgY3VycmVudCBieXRlIHNlcXVlbmNlLCBhcHBlbmQgaXQgdG8gVW5pY29kZTo6JGRhdGEKCQkJaWYgKCEkcmVtYWluaW5nKSB7CgkJCQkvLyBQZXJjZW50IGVuY29kZSBhbnl0aGluZyBpbnZhbGlkIG9yIG5vdCBpbiBpdW5yZXNlcnZlZAoJCQkJaWYgKAoJCQkJCS8vIEludmFsaWQgc2VxdWVuY2VzCgkJCQkJISR2YWxpZAoJCQkJCS8vIE5vbi1zaG9ydGVzdCBmb3JtIHNlcXVlbmNlcyBhcmUgaW52YWxpZAoJCQkJCXx8ICRsZW5ndGggPiAxICYmICRjaGFyYWN0ZXIgPD0gMHg3RgoJCQkJCXx8ICRsZW5ndGggPiAyICYmICRjaGFyYWN0ZXIgPD0gMHg3RkYKCQkJCQl8fCAkbGVuZ3RoID4gMyAmJiAkY2hhcmFjdGVyIDw9IDB4RkZGRgoJCQkJCS8vIE91dHNpZGUgb2YgcmFuZ2Ugb2YgaXVucmVzZXJ2ZWQgY29kZXBvaW50cwoJCQkJCXx8ICRjaGFyYWN0ZXIgPCAweDJECgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4RUZGRkQKCQkJCQkvLyBOb25jaGFyYWN0ZXJzCgkJCQkJfHwgKCRjaGFyYWN0ZXIgJiAweEZGRkUpID09PSAweEZGRkUKCQkJCQl8fCAkY2hhcmFjdGVyID49IDB4RkREMCAmJiAkY2hhcmFjdGVyIDw9IDB4RkRFRgoJCQkJCS8vIEV2ZXJ5dGhpbmcgZWxzZSBub3QgaW4gaXVucmVzZXJ2ZWQgKHRoaXMgaXMgYWxsIEJNUCkKCQkJCQl8fCAkY2hhcmFjdGVyID09PSAweDJGCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4MzkgJiYgJGNoYXJhY3RlciA8IDB4NDEKCQkJCQl8fCAkY2hhcmFjdGVyID4gMHg1QSAmJiAkY2hhcmFjdGVyIDwgMHg2MQoJCQkJCXx8ICRjaGFyYWN0ZXIgPiAweDdBICYmICRjaGFyYWN0ZXIgPCAweDdFCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4N0UgJiYgJGNoYXJhY3RlciA8IDB4QTAKCQkJCQl8fCAkY2hhcmFjdGVyID4gMHhEN0ZGICYmICRjaGFyYWN0ZXIgPCAweEY5MDAKCQkJCSkgewoJCQkJCWZvciAoJGogPSAkc3RhcnQ7ICRqIDw9ICRpOyAkaisrKSB7CgkJCQkJCSRzdHJpbmcgLj0gJyUnIC4gc3RydG91cHBlcigkYnl0ZXNbJGpdKTsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIHsKCQkJCQlmb3IgKCRqID0gJHN0YXJ0OyAkaiA8PSAkaTsgJGorKykgewoJCQkJCQkkc3RyaW5nIC49IGNocihoZXhkZWMoJGJ5dGVzWyRqXSkpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJLy8gSWYgd2UgaGF2ZSBhbnkgYnl0ZXMgbGVmdCBvdmVyIHRoZXkgYXJlIGludmFsaWQgKGkuZS4sIHdlIGFyZQoJCS8vIG1pZC13YXkgdGhyb3VnaCBhIG11bHRpLWJ5dGUgc2VxdWVuY2UpCgkJaWYgKCRyZW1haW5pbmcpIHsKCQkJZm9yICgkaiA9ICRzdGFydDsgJGogPCAkbGVuOyAkaisrKSB7CgkJCQkkc3RyaW5nIC49ICclJyAuIHN0cnRvdXBwZXIoJGJ5dGVzWyRqXSk7CgkJCX0KCQl9CgoJCXJldHVybiAkc3RyaW5nOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBzY2hlbWVfbm9ybWFsaXphdGlvbigpIHsKCQlpZiAoaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2l1c2VyaW5mbyddKSAmJiAkdGhpcy0+aXVzZXJpbmZvID09PSAkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsnaXVzZXJpbmZvJ10pIHsKCQkJJHRoaXMtPml1c2VyaW5mbyA9IG51bGw7CgkJfQoJCWlmIChpc3NldCgkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsnaWhvc3QnXSkgJiYgJHRoaXMtPmlob3N0ID09PSAkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsnaWhvc3QnXSkgewoJCQkkdGhpcy0+aWhvc3QgPSBudWxsOwoJCX0KCQlpZiAoaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ3BvcnQnXSkgJiYgJHRoaXMtPnBvcnQgPT09ICR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydwb3J0J10pIHsKCQkJJHRoaXMtPnBvcnQgPSBudWxsOwoJCX0KCQlpZiAoaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lwYXRoJ10pICYmICR0aGlzLT5pcGF0aCA9PT0gJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lwYXRoJ10pIHsKCQkJJHRoaXMtPmlwYXRoID0gJyc7CgkJfQoJCWlmIChpc3NldCgkdGhpcy0+aWhvc3QpICYmIGVtcHR5KCR0aGlzLT5pcGF0aCkpIHsKCQkJJHRoaXMtPmlwYXRoID0gJy8nOwoJCX0KCQlpZiAoaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lxdWVyeSddKSAmJiAkdGhpcy0+aXF1ZXJ5ID09PSAkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsnaXF1ZXJ5J10pIHsKCQkJJHRoaXMtPmlxdWVyeSA9IG51bGw7CgkJfQoJCWlmIChpc3NldCgkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsnaWZyYWdtZW50J10pICYmICR0aGlzLT5pZnJhZ21lbnQgPT09ICR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydpZnJhZ21lbnQnXSkgewoJCQkkdGhpcy0+aWZyYWdtZW50ID0gbnVsbDsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiB0aGUgb2JqZWN0IHJlcHJlc2VudHMgYSB2YWxpZCBJUkkuIFRoaXMgbmVlZHMgdG8gYmUgZG9uZSBvbiBlYWNoCgkgKiBjYWxsIGFzIHNvbWUgdGhpbmdzIGNoYW5nZSBkZXBlbmRpbmcgb24gYW5vdGhlciBwYXJ0IG9mIHRoZSBJUkkuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc192YWxpZCgpIHsKCQkkaXNhdXRob3JpdHkgPSAkdGhpcy0+aXVzZXJpbmZvICE9PSBudWxsIHx8ICR0aGlzLT5paG9zdCAhPT0gbnVsbCB8fCAkdGhpcy0+cG9ydCAhPT0gbnVsbDsKCQlpZiAoJHRoaXMtPmlwYXRoICE9PSAnJyAmJgoJCQkoCgkJCQkkaXNhdXRob3JpdHkgJiYgJHRoaXMtPmlwYXRoWzBdICE9PSAnLycgfHwKCQkJCSgKCQkJCQkkdGhpcy0+c2NoZW1lID09PSBudWxsICYmCgkJCQkJISRpc2F1dGhvcml0eSAmJgoJCQkJCXN0cnBvcygkdGhpcy0+aXBhdGgsICc6JykgIT09IGZhbHNlICYmCgkJCQkJKHN0cnBvcygkdGhpcy0+aXBhdGgsICcvJykgPT09IGZhbHNlID8gdHJ1ZSA6IHN0cnBvcygkdGhpcy0+aXBhdGgsICc6JykgPCBzdHJwb3MoJHRoaXMtPmlwYXRoLCAnLycpKQoJCQkJKQoJCQkpCgkJKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogU2V0IHRoZSBlbnRpcmUgSVJJLiBSZXR1cm5zIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZSAoaWYgdGhlcmUKCSAqIGFyZSBhbnkgaW52YWxpZCBjaGFyYWN0ZXJzKS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRpcmkKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X2lyaSgkaXJpKSB7CgkJc3RhdGljICRjYWNoZTsKCQlpZiAoISRjYWNoZSkgewoJCQkkY2FjaGUgPSBhcnJheSgpOwoJCX0KCgkJaWYgKCRpcmkgPT09IG51bGwpIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCWlmIChpc3NldCgkY2FjaGVbJGlyaV0pKSB7CgkJCWxpc3QoJHRoaXMtPnNjaGVtZSwKCQkJCSAkdGhpcy0+aXVzZXJpbmZvLAoJCQkJICR0aGlzLT5paG9zdCwKCQkJCSAkdGhpcy0+cG9ydCwKCQkJCSAkdGhpcy0+aXBhdGgsCgkJCQkgJHRoaXMtPmlxdWVyeSwKCQkJCSAkdGhpcy0+aWZyYWdtZW50LAoJCQkJICRyZXR1cm4pID0gJGNhY2hlWyRpcmldOwoJCQlyZXR1cm4gJHJldHVybjsKCQl9CgoJCSRwYXJzZWQgPSAkdGhpcy0+cGFyc2VfaXJpKChzdHJpbmcpICRpcmkpOwoKCQkkcmV0dXJuID0gJHRoaXMtPnNldF9zY2hlbWUoJHBhcnNlZFsnc2NoZW1lJ10pCgkJCSYmICR0aGlzLT5zZXRfYXV0aG9yaXR5KCRwYXJzZWRbJ2F1dGhvcml0eSddKQoJCQkmJiAkdGhpcy0+c2V0X3BhdGgoJHBhcnNlZFsncGF0aCddKQoJCQkmJiAkdGhpcy0+c2V0X3F1ZXJ5KCRwYXJzZWRbJ3F1ZXJ5J10pCgkJCSYmICR0aGlzLT5zZXRfZnJhZ21lbnQoJHBhcnNlZFsnZnJhZ21lbnQnXSk7CgoJCSRjYWNoZVskaXJpXSA9IGFycmF5KCR0aGlzLT5zY2hlbWUsCgkJCQkJCQkgJHRoaXMtPml1c2VyaW5mbywKCQkJCQkJCSAkdGhpcy0+aWhvc3QsCgkJCQkJCQkgJHRoaXMtPnBvcnQsCgkJCQkJCQkgJHRoaXMtPmlwYXRoLAoJCQkJCQkJICR0aGlzLT5pcXVlcnksCgkJCQkJCQkgJHRoaXMtPmlmcmFnbWVudCwKCQkJCQkJCSAkcmV0dXJuKTsKCQlyZXR1cm4gJHJldHVybjsKCX0KCgkvKioKCSAqIFNldCB0aGUgc2NoZW1lLiBSZXR1cm5zIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZSAoaWYgdGhlcmUgYXJlCgkgKiBhbnkgaW52YWxpZCBjaGFyYWN0ZXJzKS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzY2hlbWUKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X3NjaGVtZSgkc2NoZW1lKSB7CgkJaWYgKCRzY2hlbWUgPT09IG51bGwpIHsKCQkJJHRoaXMtPnNjaGVtZSA9IG51bGw7CgkJfQoJCWVsc2VpZiAoIXByZWdfbWF0Y2goJy9eW0EtWmEtel1bMC05QS1aYS16K1wtLl0qJC8nLCAkc2NoZW1lKSkgewoJCQkkdGhpcy0+c2NoZW1lID0gbnVsbDsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQllbHNlIHsKCQkJJHRoaXMtPnNjaGVtZSA9IHN0cnRvbG93ZXIoJHNjaGVtZSk7CgkJfQoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogU2V0IHRoZSBhdXRob3JpdHkuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlIChpZiB0aGVyZSBhcmUKCSAqIGFueSBpbnZhbGlkIGNoYXJhY3RlcnMpLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGF1dGhvcml0eQoJICogQHJldHVybiBib29sCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRfYXV0aG9yaXR5KCRhdXRob3JpdHkpIHsKCQlzdGF0aWMgJGNhY2hlOwoJCWlmICghJGNhY2hlKSB7CgkJCSRjYWNoZSA9IGFycmF5KCk7CgkJfQoKCQlpZiAoJGF1dGhvcml0eSA9PT0gbnVsbCkgewoJCQkkdGhpcy0+aXVzZXJpbmZvID0gbnVsbDsKCQkJJHRoaXMtPmlob3N0ID0gbnVsbDsKCQkJJHRoaXMtPnBvcnQgPSBudWxsOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJaWYgKGlzc2V0KCRjYWNoZVskYXV0aG9yaXR5XSkpIHsKCQkJbGlzdCgkdGhpcy0+aXVzZXJpbmZvLAoJCQkJICR0aGlzLT5paG9zdCwKCQkJCSAkdGhpcy0+cG9ydCwKCQkJCSAkcmV0dXJuKSA9ICRjYWNoZVskYXV0aG9yaXR5XTsKCgkJCXJldHVybiAkcmV0dXJuOwoJCX0KCgkJJHJlbWFpbmluZyA9ICRhdXRob3JpdHk7CgkJaWYgKCgkaXVzZXJpbmZvX2VuZCA9IHN0cnJwb3MoJHJlbWFpbmluZywgJ0AnKSkgIT09IGZhbHNlKSB7CgkJCSRpdXNlcmluZm8gPSBzdWJzdHIoJHJlbWFpbmluZywgMCwgJGl1c2VyaW5mb19lbmQpOwoJCQkkcmVtYWluaW5nID0gc3Vic3RyKCRyZW1haW5pbmcsICRpdXNlcmluZm9fZW5kICsgMSk7CgkJfQoJCWVsc2UgewoJCQkkaXVzZXJpbmZvID0gbnVsbDsKCQl9CgkJaWYgKCgkcG9ydF9zdGFydCA9IHN0cnBvcygkcmVtYWluaW5nLCAnOicsIHN0cnBvcygkcmVtYWluaW5nLCAnXScpKSkgIT09IGZhbHNlKSB7CgkJCSRwb3J0ID0gc3Vic3RyKCRyZW1haW5pbmcsICRwb3J0X3N0YXJ0ICsgMSk7CgkJCWlmICgkcG9ydCA9PT0gZmFsc2UgfHwgJHBvcnQgPT09ICcnKSB7CgkJCQkkcG9ydCA9IG51bGw7CgkJCX0KCQkJJHJlbWFpbmluZyA9IHN1YnN0cigkcmVtYWluaW5nLCAwLCAkcG9ydF9zdGFydCk7CgkJfQoJCWVsc2UgewoJCQkkcG9ydCA9IG51bGw7CgkJfQoKCQkkcmV0dXJuID0gJHRoaXMtPnNldF91c2VyaW5mbygkaXVzZXJpbmZvKSAmJgoJCQkJICAkdGhpcy0+c2V0X2hvc3QoJHJlbWFpbmluZykgJiYKCQkJCSAgJHRoaXMtPnNldF9wb3J0KCRwb3J0KTsKCgkJJGNhY2hlWyRhdXRob3JpdHldID0gYXJyYXkoJHRoaXMtPml1c2VyaW5mbywKCQkJCQkJCQkgICAkdGhpcy0+aWhvc3QsCgkJCQkJCQkJICAgJHRoaXMtPnBvcnQsCgkJCQkJCQkJICAgJHJldHVybik7CgoJCXJldHVybiAkcmV0dXJuOwoJfQoKCS8qKgoJICogU2V0IHRoZSBpdXNlcmluZm8uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXVzZXJpbmZvCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF91c2VyaW5mbygkaXVzZXJpbmZvKSB7CgkJaWYgKCRpdXNlcmluZm8gPT09IG51bGwpIHsKCQkJJHRoaXMtPml1c2VyaW5mbyA9IG51bGw7CgkJfQoJCWVsc2UgewoJCQkkdGhpcy0+aXVzZXJpbmZvID0gJHRoaXMtPnJlcGxhY2VfaW52YWxpZF93aXRoX3BjdF9lbmNvZGluZygkaXVzZXJpbmZvLCAnISQmXCcoKSorLDs9OicpOwoJCQkkdGhpcy0+c2NoZW1lX25vcm1hbGl6YXRpb24oKTsKCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogU2V0IHRoZSBpaG9zdC4gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUgKGlmIHRoZXJlIGFyZQoJICogYW55IGludmFsaWQgY2hhcmFjdGVycykuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaWhvc3QKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X2hvc3QoJGlob3N0KSB7CgkJaWYgKCRpaG9zdCA9PT0gbnVsbCkgewoJCQkkdGhpcy0+aWhvc3QgPSBudWxsOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJaWYgKHN1YnN0cigkaWhvc3QsIDAsIDEpID09PSAnWycgJiYgc3Vic3RyKCRpaG9zdCwgLTEpID09PSAnXScpIHsKCQkJaWYgKFJlcXVlc3RzX0lQdjY6OmNoZWNrX2lwdjYoc3Vic3RyKCRpaG9zdCwgMSwgLTEpKSkgewoJCQkJJHRoaXMtPmlob3N0ID0gJ1snIC4gUmVxdWVzdHNfSVB2Njo6Y29tcHJlc3Moc3Vic3RyKCRpaG9zdCwgMSwgLTEpKSAuICddJzsKCQkJfQoJCQllbHNlIHsKCQkJCSR0aGlzLT5paG9zdCA9IG51bGw7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgkJZWxzZSB7CgkJCSRpaG9zdCA9ICR0aGlzLT5yZXBsYWNlX2ludmFsaWRfd2l0aF9wY3RfZW5jb2RpbmcoJGlob3N0LCAnISQmXCcoKSorLDs9Jyk7CgoJCQkvLyBMb3dlcmNhc2UsIGJ1dCBpZ25vcmUgcGN0LWVuY29kZWQgc2VjdGlvbnMgKGFzIHRoZXkgc2hvdWxkCgkJCS8vIHJlbWFpbiB1cHBlcmNhc2UpLiBUaGlzIG11c3QgYmUgZG9uZSBhZnRlciB0aGUgcHJldmlvdXMgc3RlcAoJCQkvLyBhcyB0aGF0IGNhbiBhZGQgdW5lc2NhcGVkIGNoYXJhY3RlcnMuCgkJCSRwb3NpdGlvbiA9IDA7CgkJCSRzdHJsZW4gPSBzdHJsZW4oJGlob3N0KTsKCQkJd2hpbGUgKCgkcG9zaXRpb24gKz0gc3RyY3NwbigkaWhvc3QsICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiUnLCAkcG9zaXRpb24pKSA8ICRzdHJsZW4pIHsKCQkJCWlmICgkaWhvc3RbJHBvc2l0aW9uXSA9PT0gJyUnKSB7CgkJCQkJJHBvc2l0aW9uICs9IDM7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkkaWhvc3RbJHBvc2l0aW9uXSA9IHN0cnRvbG93ZXIoJGlob3N0WyRwb3NpdGlvbl0pOwoJCQkJCSRwb3NpdGlvbisrOwoJCQkJfQoJCQl9CgoJCQkkdGhpcy0+aWhvc3QgPSAkaWhvc3Q7CgkJfQoKCQkkdGhpcy0+c2NoZW1lX25vcm1hbGl6YXRpb24oKTsKCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIHBvcnQuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlIChpZiB0aGVyZSBhcmUKCSAqIGFueSBpbnZhbGlkIGNoYXJhY3RlcnMpLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBvcnQKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X3BvcnQoJHBvcnQpIHsKCQlpZiAoJHBvcnQgPT09IG51bGwpIHsKCQkJJHRoaXMtPnBvcnQgPSBudWxsOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCWlmIChzdHJzcG4oJHBvcnQsICcwMTIzNDU2Nzg5JykgPT09IHN0cmxlbigkcG9ydCkpIHsKCQkJJHRoaXMtPnBvcnQgPSAoaW50KSAkcG9ydDsKCQkJJHRoaXMtPnNjaGVtZV9ub3JtYWxpemF0aW9uKCk7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJJHRoaXMtPnBvcnQgPSBudWxsOwoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgaXBhdGguCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXBhdGgKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X3BhdGgoJGlwYXRoKSB7CgkJc3RhdGljICRjYWNoZTsKCQlpZiAoISRjYWNoZSkgewoJCQkkY2FjaGUgPSBhcnJheSgpOwoJCX0KCgkJJGlwYXRoID0gKHN0cmluZykgJGlwYXRoOwoKCQlpZiAoaXNzZXQoJGNhY2hlWyRpcGF0aF0pKSB7CgkJCSR0aGlzLT5pcGF0aCA9ICRjYWNoZVskaXBhdGhdWyhpbnQpICgkdGhpcy0+c2NoZW1lICE9PSBudWxsKV07CgkJfQoJCWVsc2UgewoJCQkkdmFsaWQgPSAkdGhpcy0+cmVwbGFjZV9pbnZhbGlkX3dpdGhfcGN0X2VuY29kaW5nKCRpcGF0aCwgJyEkJlwnKCkqKyw7PUA6LycpOwoJCQkkcmVtb3ZlZCA9ICR0aGlzLT5yZW1vdmVfZG90X3NlZ21lbnRzKCR2YWxpZCk7CgoJCQkkY2FjaGVbJGlwYXRoXSA9IGFycmF5KCR2YWxpZCwgJHJlbW92ZWQpOwoJCQkkdGhpcy0+aXBhdGggPSAoJHRoaXMtPnNjaGVtZSAhPT0gbnVsbCkgPyAkcmVtb3ZlZCA6ICR2YWxpZDsKCQl9CgkJJHRoaXMtPnNjaGVtZV9ub3JtYWxpemF0aW9uKCk7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGlxdWVyeS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRpcXVlcnkKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X3F1ZXJ5KCRpcXVlcnkpIHsKCQlpZiAoJGlxdWVyeSA9PT0gbnVsbCkgewoJCQkkdGhpcy0+aXF1ZXJ5ID0gbnVsbDsKCQl9CgkJZWxzZSB7CgkJCSR0aGlzLT5pcXVlcnkgPSAkdGhpcy0+cmVwbGFjZV9pbnZhbGlkX3dpdGhfcGN0X2VuY29kaW5nKCRpcXVlcnksICchJCZcJygpKissOz06QC8/JywgdHJ1ZSk7CgkJCSR0aGlzLT5zY2hlbWVfbm9ybWFsaXphdGlvbigpOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgaWZyYWdtZW50LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlmcmFnbWVudAoJICogQHJldHVybiBib29sCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRfZnJhZ21lbnQoJGlmcmFnbWVudCkgewoJCWlmICgkaWZyYWdtZW50ID09PSBudWxsKSB7CgkJCSR0aGlzLT5pZnJhZ21lbnQgPSBudWxsOwoJCX0KCQllbHNlIHsKCQkJJHRoaXMtPmlmcmFnbWVudCA9ICR0aGlzLT5yZXBsYWNlX2ludmFsaWRfd2l0aF9wY3RfZW5jb2RpbmcoJGlmcmFnbWVudCwgJyEkJlwnKCkqKyw7PTpALz8nKTsKCQkJJHRoaXMtPnNjaGVtZV9ub3JtYWxpemF0aW9uKCk7CgkJfQoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQ29udmVydCBhbiBJUkkgdG8gYSBVUkkgKG9yIHBhcnRzIHRoZXJlb2YpCgkgKgoJICogQHBhcmFtIHN0cmluZ3xib29sIElSSSB0byBjb252ZXJ0IChvciBmYWxzZSBmcm9tIHtAc2VlIGdldF9pcml9KQoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UgVVJJIGlmIElSSSBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdG9fdXJpKCRzdHJpbmcpIHsKCQlpZiAoIWlzX3N0cmluZygkc3RyaW5nKSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlzdGF0aWMgJG5vbl9hc2NpaTsKCQlpZiAoISRub25fYXNjaWkpIHsKCQkJJG5vbl9hc2NpaSA9IGltcGxvZGUoJycsIHJhbmdlKCJceDgwIiwgIlx4RkYiKSk7CgkJfQoKCQkkcG9zaXRpb24gPSAwOwoJCSRzdHJsZW4gPSBzdHJsZW4oJHN0cmluZyk7CgkJd2hpbGUgKCgkcG9zaXRpb24gKz0gc3RyY3Nwbigkc3RyaW5nLCAkbm9uX2FzY2lpLCAkcG9zaXRpb24pKSA8ICRzdHJsZW4pIHsKCQkJJHN0cmluZyA9IHN1YnN0cl9yZXBsYWNlKCRzdHJpbmcsIHNwcmludGYoJyUlJTAyWCcsIG9yZCgkc3RyaW5nWyRwb3NpdGlvbl0pKSwgJHBvc2l0aW9uLCAxKTsKCQkJJHBvc2l0aW9uICs9IDM7CgkJCSRzdHJsZW4gKz0gMjsKCQl9CgoJCXJldHVybiAkc3RyaW5nOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb21wbGV0ZSBJUkkKCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2lyaSgpIHsKCQlpZiAoISR0aGlzLT5pc192YWxpZCgpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRpcmkgPSAnJzsKCQlpZiAoJHRoaXMtPnNjaGVtZSAhPT0gbnVsbCkgewoJCQkkaXJpIC49ICR0aGlzLT5zY2hlbWUgLiAnOic7CgkJfQoJCWlmICgoJGlhdXRob3JpdHkgPSAkdGhpcy0+Z2V0X2lhdXRob3JpdHkoKSkgIT09IG51bGwpIHsKCQkJJGlyaSAuPSAnLy8nIC4gJGlhdXRob3JpdHk7CgkJfQoJCSRpcmkgLj0gJHRoaXMtPmlwYXRoOwoJCWlmICgkdGhpcy0+aXF1ZXJ5ICE9PSBudWxsKSB7CgkJCSRpcmkgLj0gJz8nIC4gJHRoaXMtPmlxdWVyeTsKCQl9CgkJaWYgKCR0aGlzLT5pZnJhZ21lbnQgIT09IG51bGwpIHsKCQkJJGlyaSAuPSAnIycgLiAkdGhpcy0+aWZyYWdtZW50OwoJCX0KCgkJcmV0dXJuICRpcmk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGNvbXBsZXRlIFVSSQoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXJpKCkgewoJCXJldHVybiAkdGhpcy0+dG9fdXJpKCR0aGlzLT5nZXRfaXJpKCkpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb21wbGV0ZSBpYXV0aG9yaXR5CgkgKgoJICogQHJldHVybiBzdHJpbmd8bnVsbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2lhdXRob3JpdHkoKSB7CgkJaWYgKCR0aGlzLT5pdXNlcmluZm8gPT09IG51bGwgJiYgJHRoaXMtPmlob3N0ID09PSBudWxsICYmICR0aGlzLT5wb3J0ID09PSBudWxsKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJJGlhdXRob3JpdHkgPSAnJzsKCQlpZiAoJHRoaXMtPml1c2VyaW5mbyAhPT0gbnVsbCkgewoJCQkkaWF1dGhvcml0eSAuPSAkdGhpcy0+aXVzZXJpbmZvIC4gJ0AnOwoJCX0KCQlpZiAoJHRoaXMtPmlob3N0ICE9PSBudWxsKSB7CgkJCSRpYXV0aG9yaXR5IC49ICR0aGlzLT5paG9zdDsKCQl9CgkJaWYgKCR0aGlzLT5wb3J0ICE9PSBudWxsKSB7CgkJCSRpYXV0aG9yaXR5IC49ICc6JyAuICR0aGlzLT5wb3J0OwoJCX0KCQlyZXR1cm4gJGlhdXRob3JpdHk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGNvbXBsZXRlIGF1dGhvcml0eQoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfYXV0aG9yaXR5KCkgewoJCSRpYXV0aG9yaXR5ID0gJHRoaXMtPmdldF9pYXV0aG9yaXR5KCk7CgkJaWYgKGlzX3N0cmluZygkaWF1dGhvcml0eSkpIHsKCQkJcmV0dXJuICR0aGlzLT50b191cmkoJGlhdXRob3JpdHkpOwoJCX0KCQllbHNlIHsKCQkJcmV0dXJuICRpYXV0aG9yaXR5OwoJCX0KCX0KfQo8P3BocAovKioKICogQ2FzZS1pbnNlbnNpdGl2ZSBkaWN0aW9uYXJ5LCBzdWl0YWJsZSBmb3IgSFRUUCBoZWFkZXJzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIENhc2UtaW5zZW5zaXRpdmUgZGljdGlvbmFyeSwgc3VpdGFibGUgZm9yIEhUVFAgaGVhZGVycwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfUmVzcG9uc2VfSGVhZGVycyBleHRlbmRzIFJlcXVlc3RzX1V0aWxpdHlfQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSB7CgkvKioKCSAqIEdldCB0aGUgZ2l2ZW4gaGVhZGVyCgkgKgoJICogVW5saWtlIHtAc2VlIHNlbGY6OmdldFZhbHVlcygpfSwgdGhpcyByZXR1cm5zIGEgc3RyaW5nLiBJZiB0aGVyZSBhcmUKCSAqIG11bHRpcGxlIHZhbHVlcywgaXQgY29uY2F0ZW5hdGVzIHRoZW0gd2l0aCBhIGNvbW1hIGFzIHBlciBSRkMyNjE2LgoJICoKCSAqIEF2b2lkIHVzaW5nIHRoaXMgd2hlcmUgY29tbWFzIG1heSBiZSB1c2VkIHVucXVvdGVkIGluIHZhbHVlcywgc3VjaCBhcwoJICogU2V0LUNvb2tpZSBoZWFkZXJzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleQoJICogQHJldHVybiBzdHJpbmd8bnVsbCBIZWFkZXIgdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldEdldCgka2V5KSB7CgkJJGtleSA9IHN0cnRvbG93ZXIoJGtleSk7CgkJaWYgKCFpc3NldCgkdGhpcy0+ZGF0YVska2V5XSkpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPmZsYXR0ZW4oJHRoaXMtPmRhdGFbJGtleV0pOwoJfQoKCS8qKgoJICogU2V0IHRoZSBnaXZlbiBpdGVtCgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gYXR0ZW1wdGluZyB0byB1c2UgZGljdGlvbmFyeSBhcyBsaXN0IChgaW52YWxpZHNldGApCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0gbmFtZQoJICogQHBhcmFtIHN0cmluZyAkdmFsdWUgSXRlbSB2YWx1ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0U2V0KCRrZXksICR2YWx1ZSkgewoJCWlmICgka2V5ID09PSBudWxsKSB7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ09iamVjdCBpcyBhIGRpY3Rpb25hcnksIG5vdCBhIGxpc3QnLCAnaW52YWxpZHNldCcpOwoJCX0KCgkJJGtleSA9IHN0cnRvbG93ZXIoJGtleSk7CgoJCWlmICghaXNzZXQoJHRoaXMtPmRhdGFbJGtleV0pKSB7CgkJCSR0aGlzLT5kYXRhWyRrZXldID0gYXJyYXkoKTsKCQl9CgoJCSR0aGlzLT5kYXRhWyRrZXldW10gPSAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBHZXQgYWxsIHZhbHVlcyBmb3IgYSBnaXZlbiBoZWFkZXIKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkKCSAqIEByZXR1cm4gYXJyYXl8bnVsbCBIZWFkZXIgdmFsdWVzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZXMoJGtleSkgewoJCSRrZXkgPSBzdHJ0b2xvd2VyKCRrZXkpOwoJCWlmICghaXNzZXQoJHRoaXMtPmRhdGFbJGtleV0pKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5kYXRhWyRrZXldOwoJfQoKCS8qKgoJICogRmxhdHRlbnMgYSB2YWx1ZSBpbnRvIGEgc3RyaW5nCgkgKgoJICogQ29udmVydHMgYW4gYXJyYXkgaW50byBhIHN0cmluZyBieSBpbXBsb2RpbmcgdmFsdWVzIHdpdGggYSBjb21tYSwgYXMgcGVyCgkgKiBSRkMyNjE2J3MgcnVsZXMgZm9yIGZvbGRpbmcgaGVhZGVycy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICR2YWx1ZSBWYWx1ZSB0byBmbGF0dGVuCgkgKiBAcmV0dXJuIHN0cmluZyBGbGF0dGVuZWQgdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZsYXR0ZW4oJHZhbHVlKSB7CgkJaWYgKGlzX2FycmF5KCR2YWx1ZSkpIHsKCQkJJHZhbHVlID0gaW1wbG9kZSgnLCcsICR2YWx1ZSk7CgkJfQoKCQlyZXR1cm4gJHZhbHVlOwoJfQoKCS8qKgoJICogR2V0IGFuIGl0ZXJhdG9yIGZvciB0aGUgZGF0YQoJICoKCSAqIENvbnZlcnRzIHRoZSBpbnRlcm5hbAoJICogQHJldHVybiBBcnJheUl0ZXJhdG9yCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRJdGVyYXRvcigpIHsKCQlyZXR1cm4gbmV3IFJlcXVlc3RzX1V0aWxpdHlfRmlsdGVyZWRJdGVyYXRvcigkdGhpcy0+ZGF0YSwgYXJyYXkoJHRoaXMsICdmbGF0dGVuJykpOwoJfQp9Cjw/cGhwCi8qKgogKiBCYXNlIEhUVFAgdHJhbnNwb3J0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFRyYW5zcG9ydAogKi8KCi8qKgogKiBCYXNlIEhUVFAgdHJhbnNwb3J0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFRyYW5zcG9ydAogKi8KaW50ZXJmYWNlIFJlcXVlc3RzX1RyYW5zcG9ydCB7CgkvKioKCSAqIFBlcmZvcm0gYSByZXF1ZXN0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsIFVSTCB0byByZXF1ZXN0CgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgQXNzb2NpYXRpdmUgYXJyYXkgb2YgcmVxdWVzdCBoZWFkZXJzCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRkYXRhIERhdGEgdG8gc2VuZCBlaXRoZXIgYXMgdGhlIFBPU1QgYm9keSwgb3IgYXMgcGFyYW1ldGVycyBpbiB0aGUgVVJMIGZvciBhIEdFVC9IRUFECgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgUmVxdWVzdCBvcHRpb25zLCBzZWUge0BzZWUgUmVxdWVzdHM6OnJlc3BvbnNlKCl9IGZvciBkb2N1bWVudGF0aW9uCgkgKiBAcmV0dXJuIHN0cmluZyBSYXcgSFRUUCByZXN1bHQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3QoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSk7CgoJLyoqCgkgKiBTZW5kIG11bHRpcGxlIHJlcXVlc3RzIHNpbXVsdGFuZW91c2x5CgkgKgoJICogQHBhcmFtIGFycmF5ICRyZXF1ZXN0cyBSZXF1ZXN0IGRhdGEgKGFycmF5IG9mICd1cmwnLCAnaGVhZGVycycsICdkYXRhJywgJ29wdGlvbnMnKSBhcyBwZXIge0BzZWUgUmVxdWVzdHNfVHJhbnNwb3J0OjpyZXF1ZXN0fQoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIEdsb2JhbCBvcHRpb25zLCBzZWUge0BzZWUgUmVxdWVzdHM6OnJlc3BvbnNlKCl9IGZvciBkb2N1bWVudGF0aW9uCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIFJlcXVlc3RzX1Jlc3BvbnNlIG9iamVjdHMgKG1heSBjb250YWluIFJlcXVlc3RzX0V4Y2VwdGlvbiBvciBzdHJpbmcgcmVzcG9uc2VzIGFzIHdlbGwpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXF1ZXN0X211bHRpcGxlKCRyZXF1ZXN0cywgJG9wdGlvbnMpOwoKCS8qKgoJICogU2VsZi10ZXN0IHdoZXRoZXIgdGhlIHRyYW5zcG9ydCBjYW4gYmUgdXNlZAoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdGVzdCgpOwp9Cjw/cGhwCi8qKgogKiBSZXF1ZXN0cyBmb3IgUEhQCiAqCiAqIEluc3BpcmVkIGJ5IFJlcXVlc3RzIGZvciBQeXRob24uCiAqCiAqIEJhc2VkIG9uIGNvbmNlcHRzIGZyb20gU2ltcGxlUGllX0ZpbGUsIFJlcXVlc3RDb3JlIGFuZCBXUF9IdHRwLgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBSZXF1ZXN0cyBmb3IgUEhQCiAqCiAqIEluc3BpcmVkIGJ5IFJlcXVlc3RzIGZvciBQeXRob24uCiAqCiAqIEJhc2VkIG9uIGNvbmNlcHRzIGZyb20gU2ltcGxlUGllX0ZpbGUsIFJlcXVlc3RDb3JlIGFuZCBXUF9IdHRwLgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHMgewoJLyoqCgkgKiBQT1NUIG1ldGhvZAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFBPU1QgPSAnUE9TVCc7CgoJLyoqCgkgKiBQVVQgbWV0aG9kCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgUFVUID0gJ1BVVCc7CgoJLyoqCgkgKiBHRVQgbWV0aG9kCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgR0VUID0gJ0dFVCc7CgoJLyoqCgkgKiBIRUFEIG1ldGhvZAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IEhFQUQgPSAnSEVBRCc7CgoJLyoqCgkgKiBERUxFVEUgbWV0aG9kCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgREVMRVRFID0gJ0RFTEVURSc7CgoJLyoqCgkgKiBPUFRJT05TIG1ldGhvZAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IE9QVElPTlMgPSAnT1BUSU9OUyc7CgoJLyoqCgkgKiBUUkFDRSBtZXRob2QKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBUUkFDRSA9ICdUUkFDRSc7CgoJLyoqCgkgKiBQQVRDSCBtZXRob2QKCSAqCgkgKiBAbGluayBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTc4OQoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgUEFUQ0ggPSAnUEFUQ0gnOwoKCS8qKgoJICogRGVmYXVsdCBzaXplIG9mIGJ1ZmZlciBzaXplIHRvIHJlYWQgc3RyZWFtcwoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCgljb25zdCBCVUZGRVJfU0laRSA9IDExNjA7CgoJLyoqCgkgKiBDdXJyZW50IHZlcnNpb24gb2YgUmVxdWVzdHMKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBWRVJTSU9OID0gJzEuOC4xJzsKCgkvKioKCSAqIFJlZ2lzdGVyZWQgdHJhbnNwb3J0IGNsYXNzZXMKCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgJHRyYW5zcG9ydHMgPSBhcnJheSgpOwoKCS8qKgoJICogU2VsZWN0ZWQgdHJhbnNwb3J0IG5hbWUKCSAqCgkgKiBVc2Uge0BzZWUgZ2V0X3RyYW5zcG9ydCgpfSBpbnN0ZWFkCgkgKgoJICogQHZhciBhcnJheQoJICovCglwdWJsaWMgc3RhdGljICR0cmFuc3BvcnQgPSBhcnJheSgpOwoKCS8qKgoJICogRGVmYXVsdCBjZXJ0aWZpY2F0ZSBwYXRoLgoJICoKCSAqIEBzZWUgUmVxdWVzdHM6OmdldF9jZXJ0aWZpY2F0ZV9wYXRoKCkKCSAqIEBzZWUgUmVxdWVzdHM6OnNldF9jZXJ0aWZpY2F0ZV9wYXRoKCkKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgc3RhdGljICRjZXJ0aWZpY2F0ZV9wYXRoOwoKCS8qKgoJICogVGhpcyBpcyBhIHN0YXRpYyBjbGFzcywgZG8gbm90IGluc3RhbnRpYXRlIGl0CgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkge30KCgkvKioKCSAqIEF1dG9sb2FkZXIgZm9yIFJlcXVlc3RzCgkgKgoJICogUmVnaXN0ZXIgdGhpcyB3aXRoIHtAc2VlIHJlZ2lzdGVyX2F1dG9sb2FkZXIoKX0gaWYgeW91J2QgbGlrZSB0byBhdm9pZAoJICogaGF2aW5nIHRvIGNyZWF0ZSB5b3VyIG93bi4KCSAqCgkgKiAoWW91IGNhbiBhbHNvIHVzZSBgc3BsX2F1dG9sb2FkX3JlZ2lzdGVyYCBkaXJlY3RseSBpZiB5b3UnZCBwcmVmZXIuKQoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjbGFzcyBDbGFzcyBuYW1lIHRvIGxvYWQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhdXRvbG9hZGVyKCRjbGFzcykgewoJCS8vIENoZWNrIHRoYXQgdGhlIGNsYXNzIHN0YXJ0cyB3aXRoICJSZXF1ZXN0cyIKCQlpZiAoc3RycG9zKCRjbGFzcywgJ1JlcXVlc3RzJykgIT09IDApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJGZpbGUgPSBzdHJfcmVwbGFjZSgnXycsICcvJywgJGNsYXNzKTsKCQlpZiAoZmlsZV9leGlzdHMoZGlybmFtZShfX0ZJTEVfXykgLiAnLycgLiAkZmlsZSAuICcucGhwJykpIHsKCQkJcmVxdWlyZV9vbmNlIGRpcm5hbWUoX19GSUxFX18pIC4gJy8nIC4gJGZpbGUgLiAnLnBocCc7CgkJfQoJfQoKCS8qKgoJICogUmVnaXN0ZXIgdGhlIGJ1aWx0LWluIGF1dG9sb2FkZXIKCSAqCgkgKiBAY29kZUNvdmVyYWdlSWdub3JlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVnaXN0ZXJfYXV0b2xvYWRlcigpIHsKCQlzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJ1JlcXVlc3RzJywgJ2F1dG9sb2FkZXInKSk7Cgl9CgoJLyoqCgkgKiBSZWdpc3RlciBhIHRyYW5zcG9ydAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRyYW5zcG9ydCBUcmFuc3BvcnQgY2xhc3MgdG8gYWRkLCBtdXN0IHN1cHBvcnQgdGhlIFJlcXVlc3RzX1RyYW5zcG9ydCBpbnRlcmZhY2UKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRfdHJhbnNwb3J0KCR0cmFuc3BvcnQpIHsKCQlpZiAoZW1wdHkoc2VsZjo6JHRyYW5zcG9ydHMpKSB7CgkJCXNlbGY6OiR0cmFuc3BvcnRzID0gYXJyYXkoCgkJCQknUmVxdWVzdHNfVHJhbnNwb3J0X2NVUkwnLAoJCQkJJ1JlcXVlc3RzX1RyYW5zcG9ydF9mc29ja29wZW4nLAoJCQkpOwoJCX0KCgkJc2VsZjo6JHRyYW5zcG9ydHMgPSBhcnJheV9tZXJnZShzZWxmOjokdHJhbnNwb3J0cywgYXJyYXkoJHRyYW5zcG9ydCkpOwoJfQoKCS8qKgoJICogR2V0IGEgd29ya2luZyB0cmFuc3BvcnQKCSAqCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBJZiBubyB2YWxpZCB0cmFuc3BvcnQgaXMgZm91bmQgKGBub3RyYW5zcG9ydGApCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1RyYW5zcG9ydAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF90cmFuc3BvcnQoJGNhcGFiaWxpdGllcyA9IGFycmF5KCkpIHsKCQkvLyBDYWNoaW5nIGNvZGUsIGRvbid0IGJvdGhlciB0ZXN0aW5nIGNvdmVyYWdlCgkJLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZVN0YXJ0CgkJLy8gYXJyYXkgb2YgY2FwYWJpbGl0aWVzIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYW4gYXJyYXkga2V5CgkJa3NvcnQoJGNhcGFiaWxpdGllcyk7CgkJJGNhcF9zdHJpbmcgPSBzZXJpYWxpemUoJGNhcGFiaWxpdGllcyk7CgoJCS8vIERvbid0IHNlYXJjaCBmb3IgYSB0cmFuc3BvcnQgaWYgaXQncyBhbHJlYWR5IGJlZW4gZG9uZSBmb3IgdGhlc2UgJGNhcGFiaWxpdGllcwoJCWlmIChpc3NldChzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXSkgJiYgc2VsZjo6JHRyYW5zcG9ydFskY2FwX3N0cmluZ10gIT09IG51bGwpIHsKCQkJJGNsYXNzID0gc2VsZjo6JHRyYW5zcG9ydFskY2FwX3N0cmluZ107CgkJCXJldHVybiBuZXcgJGNsYXNzKCk7CgkJfQoJCS8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVFbmQKCgkJaWYgKGVtcHR5KHNlbGY6OiR0cmFuc3BvcnRzKSkgewoJCQlzZWxmOjokdHJhbnNwb3J0cyA9IGFycmF5KAoJCQkJJ1JlcXVlc3RzX1RyYW5zcG9ydF9jVVJMJywKCQkJCSdSZXF1ZXN0c19UcmFuc3BvcnRfZnNvY2tvcGVuJywKCQkJKTsKCQl9CgoJCS8vIEZpbmQgdXMgYSB3b3JraW5nIHRyYW5zcG9ydAoJCWZvcmVhY2ggKHNlbGY6OiR0cmFuc3BvcnRzIGFzICRjbGFzcykgewoJCQlpZiAoIWNsYXNzX2V4aXN0cygkY2xhc3MpKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJlc3VsdCA9IGNhbGxfdXNlcl9mdW5jKGFycmF5KCRjbGFzcywgJ3Rlc3QnKSwgJGNhcGFiaWxpdGllcyk7CgkJCWlmICgkcmVzdWx0KSB7CgkJCQlzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXSA9ICRjbGFzczsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCWlmIChzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXSA9PT0gbnVsbCkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdObyB3b3JraW5nIHRyYW5zcG9ydHMgZm91bmQnLCAnbm90cmFuc3BvcnQnLCBzZWxmOjokdHJhbnNwb3J0cyk7CgkJfQoKCQkkY2xhc3MgPSBzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXTsKCQlyZXR1cm4gbmV3ICRjbGFzcygpOwoJfQoKCS8qKiNAKwoJICogQHNlZSByZXF1ZXN0KCkKCSAqIEBwYXJhbSBzdHJpbmcgJHVybAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKCSAqIEByZXR1cm4gUmVxdWVzdHNfUmVzcG9uc2UKCSAqLwoJLyoqCgkgKiBTZW5kIGEgR0VUIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgbnVsbCwgc2VsZjo6R0VULCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgSEVBRCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaGVhZCgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiBzZWxmOjpyZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCBudWxsLCBzZWxmOjpIRUFELCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgREVMRVRFIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkZWxldGUoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgbnVsbCwgc2VsZjo6REVMRVRFLCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgVFJBQ0UgcmVxdWVzdAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRyYWNlKCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJcmV0dXJuIHNlbGY6OnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsIG51bGwsIHNlbGY6OlRSQUNFLCAkb3B0aW9ucyk7Cgl9CgkvKiojQC0qLwoKCS8qKiNAKwoJICogQHNlZSByZXF1ZXN0KCkKCSAqIEBwYXJhbSBzdHJpbmcgJHVybAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzCgkgKiBAcGFyYW0gYXJyYXkgJGRhdGEKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwoJICogQHJldHVybiBSZXF1ZXN0c19SZXNwb25zZQoJICovCgkvKioKCSAqIFNlbmQgYSBQT1NUIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwb3N0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIHNlbGY6OlBPU1QsICRvcHRpb25zKTsKCX0KCS8qKgoJICogU2VuZCBhIFBVVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHV0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIHNlbGY6OlBVVCwgJG9wdGlvbnMpOwoJfQoKCS8qKgoJICogU2VuZCBhbiBPUFRJT05TIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBvcHRpb25zKCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIHNlbGY6Ok9QVElPTlMsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIFNlbmQgYSBQQVRDSCByZXF1ZXN0CgkgKgoJICogTm90ZTogVW5saWtlIHtAc2VlIHBvc3R9IGFuZCB7QHNlZSBwdXR9LCBgJGhlYWRlcnNgIGlzIHJlcXVpcmVkLCBhcyB0aGUKCSAqIHNwZWNpZmljYXRpb24gcmVjb21tZW5kcyB0aGF0IHNob3VsZCBzZW5kIGFuIEVUYWcKCSAqCgkgKiBAbGluayBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTc4OQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhdGNoKCR1cmwsICRoZWFkZXJzLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiBzZWxmOjpyZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgc2VsZjo6UEFUQ0gsICRvcHRpb25zKTsKCX0KCS8qKiNALSovCgoJLyoqCgkgKiBNYWluIGludGVyZmFjZSBmb3IgSFRUUCByZXF1ZXN0cwoJICoKCSAqIFRoaXMgbWV0aG9kIGluaXRpYXRlcyBhIHJlcXVlc3QgYW5kIHNlbmRzIGl0IHZpYSBhIHRyYW5zcG9ydCBiZWZvcmUKCSAqIHBhcnNpbmcuCgkgKgoJICogVGhlIGAkb3B0aW9uc2AgcGFyYW1ldGVyIHRha2VzIGFuIGFzc29jaWF0aXZlIGFycmF5IHdpdGggdGhlIGZvbGxvd2luZwoJICogb3B0aW9uczoKCSAqCgkgKiAtIGB0aW1lb3V0YDogSG93IGxvbmcgc2hvdWxkIHdlIHdhaXQgZm9yIGEgcmVzcG9uc2U/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+PSAzKSB7CgkJCSRwYXJ0c1swXSA9ICcqJzsKCQkJJHdpbGRjYXJkID0gaW1wbG9kZSgnLicsICRwYXJ0cyk7CgkJCWlmICgkd2lsZGNhcmQgPT09ICRyZWZlcmVuY2UpIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7CgovKioKICogQ2xhc3NMb2FkZXIgaW1wbGVtZW50cyBhIFBTUi0wLCBQU1ItNCBhbmQgY2xhc3NtYXAgY2xhc3MgbG9hZGVyLgogKgogKiAgICAgJGxvYWRlciA9IG5ldyBcQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXIoKTsKICoKICogICAgIC8vIHJlZ2lzdGVyIGNsYXNzZXMgd2l0aCBuYW1lc3BhY2VzCiAqICAgICAkbG9hZGVyLT5hZGQoJ1N5bWZvbnlcQ29tcG9uZW50JywgX19ESVJfXy4nL2NvbXBvbmVudCcpOwogKiAgICAgJGxvYWRlci0+YWRkKCdTeW1mb255JywgICAgICAgICAgIF9fRElSX18uJy9mcmFtZXdvcmsnKTsKICoKICogICAgIC8vIGFjdGl2YXRlIHRoZSBhdXRvbG9hZGVyCiAqICAgICAkbG9hZGVyLT5yZWdpc3RlcigpOwogKgogKiAgICAgLy8gdG8gZW5hYmxlIHNlYXJjaGluZyB0aGUgaW5jbHVkZSBwYXRoIChlZy4gZm9yIFBFQVIgcGFja2FnZXMpCiAqICAgICAkbG9hZGVyLT5zZXRVc2VJbmNsdWRlUGF0aCh0cnVlKTsKICoKICogSW4gdGhpcyBleGFtcGxlLCBpZiB5b3UgdHJ5IHRvIHVzZSBhIGNsYXNzIGluIHRoZSBTeW1mb255XENvbXBvbmVudAogKiBuYW1lc3BhY2Ugb3Igb25lIG9mIGl0cyBjaGlsZHJlbiAoU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZSBmb3IgaW5zdGFuY2UpLAogKiB0aGUgYXV0b2xvYWRlciB3aWxsIGZpcnN0IGxvb2sgZm9yIHRoZSBjbGFzcyB1bmRlciB0aGUgY29tcG9uZW50LwogKiBkaXJlY3RvcnksIGFuZCBpdCB3aWxsIHRoZW4gZmFsbGJhY2sgdG8gdGhlIGZyYW1ld29yay8gZGlyZWN0b3J5IGlmIG5vdAogKiBmb3VuZCBiZWZvcmUgZ2l2aW5nIHVwLgogKgogKiBUaGlzIGNsYXNzIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlIFN5bWZvbnkgVW5pdmVyc2FsQ2xhc3NMb2FkZXIuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBzZWUgICAgaHR0cHM6Ly93d3cucGhwLWZpZy5vcmcvcHNyL3Bzci0wLwogKiBAc2VlICAgIGh0dHBzOi8vd3d3LnBocC1maWcub3JnL3Bzci9wc3ItNC8KICovCmNsYXNzIENsYXNzTG9hZGVyCnsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJHZlbmRvckRpcjsKCiAgICAvLyBQU1ItNAogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5W10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGludD4+CiAgICAgKi8KICAgIHByaXZhdGUgJHByZWZpeExlbmd0aHNQc3I0ID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogQHZhciBhcnJheVtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYXJyYXk8aW50LCBzdHJpbmc+PgogICAgICovCiAgICBwcml2YXRlICRwcmVmaXhEaXJzUHNyNCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXlbXQogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSAkZmFsbGJhY2tEaXJzUHNyNCA9IGFycmF5KCk7CgogICAgLy8gUFNSLTAKICAgIC8qKgogICAgICogQHZhciBhcnJheVtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBzdHJpbmdbXT4+CiAgICAgKi8KICAgIHByaXZhdGUgJHByZWZpeGVzUHNyMCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXlbXQogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSAkZmFsbGJhY2tEaXJzUHNyMCA9IGFycmF5KCk7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkdXNlSW5jbHVkZVBhdGggPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJGNsYXNzTWFwID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRjbGFzc01hcEF1dGhvcml0YXRpdmUgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbFtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYm9vbD4KICAgICAqLwogICAgcHJpdmF0ZSAkbWlzc2luZ0NsYXNzZXMgPSBhcnJheSgpOwoKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJGFwY3VQcmVmaXg7CgogICAgLyoqCiAgICAgKiBAdmFyIHNlbGZbXQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkcmVnaXN0ZXJlZExvYWRlcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHBhcmFtID9zdHJpbmcgJHZlbmRvckRpcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHZlbmRvckRpciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnZlbmRvckRpciA9ICR2ZW5kb3JEaXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmaXhlcygpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+cHJlZml4ZXNQc3IwKSkgewogICAgICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgYXJyYXlfdmFsdWVzKCR0aGlzLT5wcmVmaXhlc1BzcjApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgYXJyYXk8aW50LCBzdHJpbmc+PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZml4ZXNQc3I0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZWZpeERpcnNQc3I0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmFsbGJhY2tEaXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5W10KICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGYWxsYmFja0RpcnNQc3I0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIEFycmF5IG9mIGNsYXNzbmFtZSA9PiBwYXRoCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2xhc3NNYXAoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2xhc3NNYXA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGNsYXNzTWFwIENsYXNzIHRvIGZpbGVuYW1lIG1hcAogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkY2xhc3NNYXAKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENsYXNzTWFwKGFycmF5ICRjbGFzc01hcCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNsYXNzTWFwKSB7CiAgICAgICAgICAgICR0aGlzLT5jbGFzc01hcCA9IGFycmF5X21lcmdlKCR0aGlzLT5jbGFzc01hcCwgJGNsYXNzTWFwKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Y2xhc3NNYXAgPSAkY2xhc3NNYXA7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi0wIGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIHByZWZpeCwgZWl0aGVyCiAgICAgKiBhcHBlbmRpbmcgb3IgcHJlcGVuZGluZyB0byB0aGUgb25lcyBwcmV2aW91c2x5IHNldCBmb3IgdGhpcyBwcmVmaXguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAkcHJlZml4ICBUaGUgcHJlZml4CiAgICAgKiBAcGFyYW0gc3RyaW5nW118c3RyaW5nICRwYXRocyAgIFRoZSBQU1ItMCByb290IGRpcmVjdG9yaWVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRwcmVwZW5kIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZCgkcHJlZml4LCAkcGF0aHMsICRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgIGlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3IwID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAsCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRmaXJzdCA9ICRwcmVmaXhbMF07CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF1bJHByZWZpeF0pKSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IChhcnJheSkgJHBhdGhzOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XQogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdLAogICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBzZXQgb2YgUFNSLTQgZGlyZWN0b3JpZXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLCBlaXRoZXIKICAgICAqIGFwcGVuZGluZyBvciBwcmVwZW5kaW5nIHRvIHRoZSBvbmVzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIG5hbWVzcGFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRwcmVmaXggIFRoZSBwcmVmaXgvbmFtZXNwYWNlLCB3aXRoIHRyYWlsaW5nICdcXCcKICAgICAqIEBwYXJhbSBzdHJpbmdbXXxzdHJpbmcgJHBhdGhzICAgVGhlIFBTUi00IGJhc2UgZGlyZWN0b3JpZXMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgJHByZXBlbmQgV2hldGhlciB0byBwcmVwZW5kIHRoZSBkaXJlY3RvcmllcwogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHNyNCgkcHJlZml4LCAkcGF0aHMsICRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGRpcmVjdG9yaWVzIGZvciB0aGUgcm9vdCBuYW1lc3BhY2UuCiAgICAgICAgICAgIGlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3I0ID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQsCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoIWlzc2V0KCR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSkpIHsKICAgICAgICAgICAgLy8gUmVnaXN0ZXIgZGlyZWN0b3JpZXMgZm9yIGEgbmV3IG5hbWVzcGFjZS4KICAgICAgICAgICAgJGxlbmd0aCA9IHN0cmxlbigkcHJlZml4KTsKICAgICAgICAgICAgaWYgKCdcXCcgIT09ICRwcmVmaXhbJGxlbmd0aCAtIDFdKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiQSBub24tZW1wdHkgUFNSLTQgcHJlZml4IG11c3QgZW5kIHdpdGggYSBuYW1lc3BhY2Ugc2VwYXJhdG9yLiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhMZW5ndGhzUHNyNFskcHJlZml4WzBdXVskcHJlZml4XSA9ICRsZW5ndGg7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZWlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAvLyBQcmVwZW5kIGRpcmVjdG9yaWVzIGZvciBhbiBhbHJlYWR5IHJlZ2lzdGVyZWQgbmFtZXNwYWNlLgogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzLAogICAgICAgICAgICAgICAgJHRoaXMtPnByZWZpeERpcnNQc3I0WyRwcmVmaXhdCiAgICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQXBwZW5kIGRpcmVjdG9yaWVzIGZvciBhbiBhbHJlYWR5IHJlZ2lzdGVyZWQgbmFtZXNwYWNlLgogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSwKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi0wIGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIHByZWZpeCwKICAgICAqIHJlcGxhY2luZyBhbnkgb3RoZXJzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIHByZWZpeC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRwcmVmaXggVGhlIHByZWZpeAogICAgICogQHBhcmFtIHN0cmluZ1tdfHN0cmluZyAkcGF0aHMgIFRoZSBQU1ItMCBiYXNlIGRpcmVjdG9yaWVzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXQoJHByZWZpeCwgJHBhdGhzKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMCA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJHByZWZpeFswXV1bJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBzZXQgb2YgUFNSLTQgZGlyZWN0b3JpZXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLAogICAgICogcmVwbGFjaW5nIGFueSBvdGhlcnMgcHJldmlvdXNseSBzZXQgZm9yIHRoaXMgbmFtZXNwYWNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJHByZWZpeCBUaGUgcHJlZml4L25hbWVzcGFjZSwgd2l0aCB0cmFpbGluZyAnXFwnCiAgICAgKiBAcGFyYW0gc3RyaW5nW118c3RyaW5nICRwYXRocyAgVGhlIFBTUi00IGJhc2UgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBzcjQoJHByZWZpeCwgJHBhdGhzKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNCA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsZW5ndGggPSBzdHJsZW4oJHByZWZpeCk7CiAgICAgICAgICAgIGlmICgnXFwnICE9PSAkcHJlZml4WyRsZW5ndGggLSAxXSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oIkEgbm9uLWVtcHR5IFBTUi00IHByZWZpeCBtdXN0IGVuZCB3aXRoIGEgbmFtZXNwYWNlIHNlcGFyYXRvci4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+cHJlZml4TGVuZ3Roc1BzcjRbJHByZWZpeFswXV1bJHByZWZpeF0gPSAkbGVuZ3RoOwogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyBvbiBzZWFyY2hpbmcgdGhlIGluY2x1ZGUgcGF0aCBmb3IgY2xhc3MgZmlsZXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHVzZUluY2x1ZGVQYXRoCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVc2VJbmNsdWRlUGF0aCgkdXNlSW5jbHVkZVBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPnVzZUluY2x1ZGVQYXRoID0gJHVzZUluY2x1ZGVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogQ2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgdGhlIGF1dG9sb2FkZXIgdXNlcyB0aGUgaW5jbHVkZSBwYXRoIHRvIGNoZWNrCiAgICAgKiBmb3IgY2xhc3Nlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVzZUluY2x1ZGVQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVzZUluY2x1ZGVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogVHVybnMgb2ZmIHNlYXJjaGluZyB0aGUgcHJlZml4IGFuZCBmYWxsYmFjayBkaXJlY3RvcmllcyBmb3IgY2xhc3NlcwogICAgICogdGhhdCBoYXZlIG5vdCBiZWVuIHJlZ2lzdGVyZWQgd2l0aCB0aGUgY2xhc3MgbWFwLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjbGFzc01hcEF1dGhvcml0YXRpdmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkY2xhc3NNYXBBdXRob3JpdGF0aXZlKQogICAgewogICAgICAgICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmUgPSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogU2hvdWxkIGNsYXNzIGxvb2t1cCBmYWlsIGlmIG5vdCBmb3VuZCBpbiB0aGUgY3VycmVudCBjbGFzcyBtYXA/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0NsYXNzTWFwQXV0aG9yaXRhdGl2ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBUEN1IHByZWZpeCB0byB1c2UgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMsIGlmIHRoZSBleHRlbnNpb24gaXMgZW5hYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGFwY3VQcmVmaXgKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFwY3VQcmVmaXgoJGFwY3VQcmVmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPmFwY3VQcmVmaXggPSBmdW5jdGlvbl9leGlzdHMoJ2FwY3VfZmV0Y2gnKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5lbmFibGVkJyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSA/ICRhcGN1UHJlZml4IDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBBUEN1IHByZWZpeCBpbiB1c2UsIG9yIG51bGwgaWYgQVBDdSBjYWNoaW5nIGlzIG5vdCBlbmFibGVkLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFwY3VQcmVmaXgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXBjdVByZWZpeDsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyB0aGlzIGluc3RhbmNlIGFzIGFuIGF1dG9sb2FkZXIuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHByZXBlbmQgV2hldGhlciB0byBwcmVwZW5kIHRoZSBhdXRvbG9hZGVyIG9yIG5vdAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoJHByZXBlbmQgPSBmYWxzZSkKICAgIHsKICAgICAgICBzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJHRoaXMsICdsb2FkQ2xhc3MnKSwgdHJ1ZSwgJHByZXBlbmQpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnZlbmRvckRpcikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzID0gYXJyYXkoJHRoaXMtPnZlbmRvckRpciA9PiAkdGhpcykgKyBzZWxmOjokcmVnaXN0ZXJlZExvYWRlcnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdW5zZXQoc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzWyR0aGlzLT52ZW5kb3JEaXJdKTsKICAgICAgICAgICAgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzWyR0aGlzLT52ZW5kb3JEaXJdID0gJHRoaXM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVW5yZWdpc3RlcnMgdGhpcyBpbnN0YW5jZSBhcyBhbiBhdXRvbG9hZGVyLgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5yZWdpc3RlcigpCiAgICB7CiAgICAgICAgc3BsX2F1dG9sb2FkX3VucmVnaXN0ZXIoYXJyYXkoJHRoaXMsICdsb2FkQ2xhc3MnKSk7CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+dmVuZG9yRGlyKSB7CiAgICAgICAgICAgIHVuc2V0KHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyc1skdGhpcy0+dmVuZG9yRGlyXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTG9hZHMgdGhlIGdpdmVuIGNsYXNzIG9yIGludGVyZmFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAkY2xhc3MgVGhlIG5hbWUgb2YgdGhlIGNsYXNzCiAgICAgKiBAcmV0dXJuIHRydWV8bnVsbCBUcnVlIGlmIGxvYWRlZCwgbnVsbCBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRDbGFzcygkY2xhc3MpCiAgICB7CiAgICAgICAgaWYgKCRmaWxlID0gJHRoaXMtPmZpbmRGaWxlKCRjbGFzcykpIHsKICAgICAgICAgICAgaW5jbHVkZUZpbGUoJGZpbGUpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBwYXRoIHRvIHRoZSBmaWxlIHdoZXJlIHRoZSBjbGFzcyBpcyBkZWZpbmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsYXNzIFRoZSBuYW1lIG9mIHRoZSBjbGFzcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFRoZSBwYXRoIGlmIGZvdW5kLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRGaWxlKCRjbGFzcykKICAgIHsKICAgICAgICAvLyBjbGFzcyBtYXAgbG9va3VwCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jbGFzc01hcFskY2xhc3NdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNsYXNzTWFwWyRjbGFzc107CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlIHx8IGlzc2V0KCR0aGlzLT5taXNzaW5nQ2xhc3Nlc1skY2xhc3NdKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+YXBjdVByZWZpeCkgewogICAgICAgICAgICAkZmlsZSA9IGFwY3VfZmV0Y2goJHRoaXMtPmFwY3VQcmVmaXguJGNsYXNzLCAkaGl0KTsKICAgICAgICAgICAgaWYgKCRoaXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGZpbGUgPSAkdGhpcy0+ZmluZEZpbGVXaXRoRXh0ZW5zaW9uKCRjbGFzcywgJy5waHAnKTsKCiAgICAgICAgLy8gU2VhcmNoIGZvciBIYWNrIGZpbGVzIGlmIHdlIGFyZSBydW5uaW5nIG9uIEhIVk0KICAgICAgICBpZiAoZmFsc2UgPT09ICRmaWxlICYmIGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CiAgICAgICAgICAgICRmaWxlID0gJHRoaXMtPmZpbmRGaWxlV2l0aEV4dGVuc2lvbigkY2xhc3MsICcuaGgnKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+YXBjdVByZWZpeCkgewogICAgICAgICAgICBhcGN1X2FkZCgkdGhpcy0+YXBjdVByZWZpeC4kY2xhc3MsICRmaWxlKTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJGZpbGUpIHsKICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhhdCB0aGlzIGNsYXNzIGRvZXMgbm90IGV4aXN0LgogICAgICAgICAgICAkdGhpcy0+bWlzc2luZ0NsYXNzZXNbJGNsYXNzXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgcmVnaXN0ZXJlZCBsb2FkZXJzIGluZGV4ZWQgYnkgdGhlaXIgY29ycmVzcG9uZGluZyB2ZW5kb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHJldHVybiBzZWxmW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSZWdpc3RlcmVkTG9hZGVycygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRjbGFzcwogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgJGV4dAogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaW5kRmlsZVdpdGhFeHRlbnNpb24oJGNsYXNzLCAkZXh0KQogICAgewogICAgICAgIC8vIFBTUi00IGxvb2t1cAogICAgICAgICRsb2dpY2FsUGF0aFBzcjQgPSBzdHJ0cigkY2xhc3MsICdcXCcsIERJUkVDVE9SWV9TRVBBUkFUT1IpIC4gJGV4dDsKCiAgICAgICAgJGZpcnN0ID0gJGNsYXNzWzBdOwogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cHJlZml4TGVuZ3Roc1BzcjRbJGZpcnN0XSkpIHsKICAgICAgICAgICAgJHN1YlBhdGggPSAkY2xhc3M7CiAgICAgICAgICAgIHdoaWxlIChmYWxzZSAhPT0gJGxhc3RQb3MgPSBzdHJycG9zKCRzdWJQYXRoLCAnXFwnKSkgewogICAgICAgICAgICAgICAgJHN1YlBhdGggPSBzdWJzdHIoJHN1YlBhdGgsIDAsICRsYXN0UG9zKTsKICAgICAgICAgICAgICAgICRzZWFyY2ggPSAkc3ViUGF0aCAuICdcXCc7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByZWZpeERpcnNQc3I0WyRzZWFyY2hdKSkgewogICAgICAgICAgICAgICAgICAgICRwYXRoRW5kID0gRElSRUNUT1JZX1NFUEFSQVRPUiAuIHN1YnN0cigkbG9naWNhbFBhdGhQc3I0LCAkbGFzdFBvcyArIDEpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcmVmaXhEaXJzUHNyNFskc2VhcmNoXSBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSA9ICRkaXIgLiAkcGF0aEVuZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUFNSLTQgZmFsbGJhY2sgZGlycwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5mYWxsYmFja0RpcnNQc3I0IGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlID0gJGRpciAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkbG9naWNhbFBhdGhQc3I0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBQU1ItMCBsb29rdXAKICAgICAgICBpZiAoZmFsc2UgIT09ICRwb3MgPSBzdHJycG9zKCRjbGFzcywgJ1xcJykpIHsKICAgICAgICAgICAgLy8gbmFtZXNwYWNlZCBjbGFzcyBuYW1lCiAgICAgICAgICAgICRsb2dpY2FsUGF0aFBzcjAgPSBzdWJzdHIoJGxvZ2ljYWxQYXRoUHNyNCwgMCwgJHBvcyArIDEpCiAgICAgICAgICAgICAgICAuIHN0cnRyKHN1YnN0cigkbG9naWNhbFBhdGhQc3I0LCAkcG9zICsgMSksICdfJywgRElSRUNUT1JZX1NFUEFSQVRPUik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gUEVBUi1saWtlIGNsYXNzIG5hbWUKICAgICAgICAgICAgJGxvZ2ljYWxQYXRoUHNyMCA9IHN0cnRyKCRjbGFzcywgJ18nLCBESVJFQ1RPUllfU0VQQVJBVE9SKSAuICRleHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF0gYXMgJHByZWZpeCA9PiAkZGlycykgewogICAgICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkY2xhc3MsICRwcmVmaXgpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRpcnMgYXMgJGRpcikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUgPSAkZGlyIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRsb2dpY2FsUGF0aFBzcjApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBTUi0wIGZhbGxiYWNrIGRpcnMKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMCBhcyAkZGlyKSB7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSA9ICRkaXIgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJGxvZ2ljYWxQYXRoUHNyMCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUFNSLTAgaW5jbHVkZSBwYXRocy4KICAgICAgICBpZiAoJHRoaXMtPnVzZUluY2x1ZGVQYXRoICYmICRmaWxlID0gc3RyZWFtX3Jlc29sdmVfaW5jbHVkZV9wYXRoKCRsb2dpY2FsUGF0aFBzcjApKSB7CiAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoKLyoqCiAqIFNjb3BlIGlzb2xhdGVkIGluY2x1ZGUuCiAqCiAqIFByZXZlbnRzIGFjY2VzcyB0byAkdGhpcy9zZWxmIGZyb20gaW5jbHVkZWQgZmlsZXMuCiAqCiAqIEBwYXJhbSAgc3RyaW5nICRmaWxlCiAqIEByZXR1cm4gdm9pZAogKiBAcHJpdmF0ZQogKi8KZnVuY3Rpb24gaW5jbHVkZUZpbGUoJGZpbGUpCnsKICAgIGluY2x1ZGUgJGZpbGU7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7CgovKioKICogQ2xhc3NMb2FkZXIgaW1wbGVtZW50cyBhIFBTUi0wLCBQU1ItNCBhbmQgY2xhc3NtYXAgY2xhc3MgbG9hZGVyLgogKgogKiAgICAgJGxvYWRlciA9IG5ldyBcQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXIoKTsKICoKICogICAgIC8vIHJlZ2lzdGVyIGNsYXNzZXMgd2l0aCBuYW1lc3BhY2VzCiAqICAgICAkbG9hZGVyLT5hZGQoJ1N5bWZvbnlcQ29tcG9uZW50JywgX19ESVJfXy4nL2NvbXBvbmVudCcpOwogKiAgICAgJGxvYWRlci0+YWRkKCdTeW1mb255JywgICAgICAgICAgIF9fRElSX18uJy9mcmFtZXdvcmsnKTsKICoKICogICAgIC8vIGFjdGl2YXRlIHRoZSBhdXRvbG9hZGVyCiAqICAgICAkbG9hZGVyLT5yZWdpc3RlcigpOwogKgogKiAgICAgLy8gdG8gZW5hYmxlIHNlYXJjaGluZyB0aGUgaW5jbHVkZSBwYXRoIChlZy4gZm9yIFBFQVIgcGFja2FnZXMpCiAqICAgICAkbG9hZGVyLT5zZXRVc2VJbmNsdWRlUGF0aCh0cnVlKTsKICoKICogSW4gdGhpcyBleGFtcGxlLCBpZiB5b3UgdHJ5IHRvIHVzZSBhIGNsYXNzIGluIHRoZSBTeW1mb255XENvbXBvbmVudAogKiBuYW1lc3BhY2Ugb3Igb25lIG9mIGl0cyBjaGlsZHJlbiAoU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZSBmb3IgaW5zdGFuY2UpLAogKiB0aGUgYXV0b2xvYWRlciB3aWxsIGZpcnN0IGxvb2sgZm9yIHRoZSBjbGFzcyB1bmRlciB0aGUgY29tcG9uZW50LwogKiBkaXJlY3RvcnksIGFuZCBpdCB3aWxsIHRoZW4gZmFsbGJhY2sgdG8gdGhlIGZyYW1ld29yay8gZGlyZWN0b3J5IGlmIG5vdAogKiBmb3VuZCBiZWZvcmUgZ2l2aW5nIHVwLgogKgogKiBUaGlzIGNsYXNzIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlIFN5bWZvbnkgVW5pdmVyc2FsQ2xhc3NMb2FkZXIuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBzZWUgICAgaHR0cHM6Ly93d3cucGhwLWZpZy5vcmcvcHNyL3Bzci0wLwogKiBAc2VlICAgIGh0dHBzOi8vd3d3LnBocC1maWcub3JnL3Bzci9wc3ItNC8KICovCmNsYXNzIENsYXNzTG9hZGVyCnsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJHZlbmRvckRpcjsKCiAgICAvLyBQU1ItNAogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5W10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGludD4+CiAgICAgKi8KICAgIHByaXZhdGUgJHByZWZpeExlbmd0aHNQc3I0ID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogQHZhciBhcnJheVtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYXJyYXk8aW50LCBzdHJpbmc+PgogICAgICovCiAgICBwcml2YXRlICRwcmVmaXhEaXJzUHNyNCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXlbXQogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSAkZmFsbGJhY2tEaXJzUHNyNCA9IGFycmF5KCk7CgogICAgLy8gUFNSLTAKICAgIC8qKgogICAgICogQHZhciBhcnJheVtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBzdHJpbmdbXT4+CiAgICAgKi8KICAgIHByaXZhdGUgJHByZWZpeGVzUHNyMCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXlbXQogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSAkZmFsbGJhY2tEaXJzUHNyMCA9IGFycmF5KCk7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkdXNlSW5jbHVkZVBhdGggPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJGNsYXNzTWFwID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRjbGFzc01hcEF1dGhvcml0YXRpdmUgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbFtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYm9vbD4KICAgICAqLwogICAgcHJpdmF0ZSAkbWlzc2luZ0NsYXNzZXMgPSBhcnJheSgpOwoKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJGFwY3VQcmVmaXg7CgogICAgLyoqCiAgICAgKiBAdmFyIHNlbGZbXQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkcmVnaXN0ZXJlZExvYWRlcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHBhcmFtID9zdHJpbmcgJHZlbmRvckRpcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHZlbmRvckRpciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnZlbmRvckRpciA9ICR2ZW5kb3JEaXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmaXhlcygpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+cHJlZml4ZXNQc3IwKSkgewogICAgICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgYXJyYXlfdmFsdWVzKCR0aGlzLT5wcmVmaXhlc1BzcjApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgYXJyYXk8aW50LCBzdHJpbmc+PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZml4ZXNQc3I0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZWZpeERpcnNQc3I0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmFsbGJhY2tEaXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5W10KICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGYWxsYmFja0RpcnNQc3I0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIEFycmF5IG9mIGNsYXNzbmFtZSA9PiBwYXRoCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2xhc3NNYXAoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2xhc3NNYXA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGNsYXNzTWFwIENsYXNzIHRvIGZpbGVuYW1lIG1hcAogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkY2xhc3NNYXAKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENsYXNzTWFwKGFycmF5ICRjbGFzc01hcCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNsYXNzTWFwKSB7CiAgICAgICAgICAgICR0aGlzLT5jbGFzc01hcCA9IGFycmF5X21lcmdlKCR0aGlzLT5jbGFzc01hcCwgJGNsYXNzTWFwKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Y2xhc3NNYXAgPSAkY2xhc3NNYXA7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi0wIGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIHByZWZpeCwgZWl0aGVyCiAgICAgKiBhcHBlbmRpbmcgb3IgcHJlcGVuZGluZyB0byB0aGUgb25lcyBwcmV2aW91c2x5IHNldCBmb3IgdGhpcyBwcmVmaXguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAkcHJlZml4ICBUaGUgcHJlZml4CiAgICAgKiBAcGFyYW0gc3RyaW5nW118c3RyaW5nICRwYXRocyAgIFRoZSBQU1ItMCByb290IGRpcmVjdG9yaWVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRwcmVwZW5kIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZCgkcHJlZml4LCAkcGF0aHMsICRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgIGlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3IwID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAsCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRmaXJzdCA9ICRwcmVmaXhbMF07CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF1bJHByZWZpeF0pKSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IChhcnJheSkgJHBhdGhzOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XQogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdLAogICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBzZXQgb2YgUFNSLTQgZGlyZWN0b3JpZXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLCBlaXRoZXIKICAgICAqIGFwcGVuZGluZyBvciBwcmVwZW5kaW5nIHRvIHRoZSBvbmVzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIG5hbWVzcGFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRwcmVmaXggIFRoZSBwcmVmaXgvbmFtZXNwYWNlLCB3aXRoIHRyYWlsaW5nICdcXCcKICAgICAqIEBwYXJhbSBzdHJpbmdbXXxzdHJpbmcgJHBhdGhzICAgVGhlIFBTUi00IGJhc2UgZGlyZWN0b3JpZXMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgJHByZXBlbmQgV2hldGhlciB0byBwcmVwZW5kIHRoZSBkaXJlY3RvcmllcwogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHNyNCgkcHJlZml4LCAkcGF0aHMsICRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGRpcmVjdG9yaWVzIGZvciB0aGUgcm9vdCBuYW1lc3BhY2UuCiAgICAgICAgICAgIGlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3I0ID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQsCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoIWlzc2V0KCR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSkpIHsKICAgICAgICAgICAgLy8gUmVnaXN0ZXIgZGlyZWN0b3JpZXMgZm9yIGEgbmV3IG5hbWVzcGFjZS4KICAgICAgICAgICAgJGxlbmd0aCA9IHN0cmxlbigkcHJlZml4KTsKICAgICAgICAgICAgaWYgKCdcXCcgIT09ICRwcmVmaXhbJGxlbmd0aCAtIDFdKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiQSBub24tZW1wdHkgUFNSLTQgcHJlZml4IG11c3QgZW5kIHdpdGggYSBuYW1lc3BhY2Ugc2VwYXJhdG9yLiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhMZW5ndGhzUHNyNFskcHJlZml4WzBdXVskcHJlZml4XSA9ICRsZW5ndGg7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZWlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAvLyBQcmVwZW5kIGRpcmVjdG9yaWVzIGZvciBhbiBhbHJlYWR5IHJlZ2lzdGVyZWQgbmFtZXNwYWNlLgogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzLAogICAgICAgICAgICAgICAgJHRoaXMtPnByZWZpeERpcnNQc3I0WyRwcmVmaXhdCiAgICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQXBwZW5kIGRpcmVjdG9yaWVzIGZvciBhbiBhbHJlYWR5IHJlZ2lzdGVyZWQgbmFtZXNwYWNlLgogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSwKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi0wIGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIHByZWZpeCwKICAgICAqIHJlcGxhY2luZyBhbnkgb3RoZXJzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIHByZWZpeC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRwcmVmaXggVGhlIHByZWZpeAogICAgICogQHBhcmFtIHN0cmluZ1tdfHN0cmluZyAkcGF0aHMgIFRoZSBQU1ItMCBiYXNlIGRpcmVjdG9yaWVzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXQoJHByZWZpeCwgJHBhdGhzKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMCA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJHByZWZpeFswXV1bJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBzZXQgb2YgUFNSLTQgZGlyZWN0b3JpZXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLAogICAgICogcmVwbGFjaW5nIGFueSBvdGhlcnMgcHJldmlvdXNseSBzZXQgZm9yIHRoaXMgbmFtZXNwYWNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJHByZWZpeCBUaGUgcHJlZml4L25hbWVzcGFjZSwgd2l0aCB0cmFpbGluZyAnXFwnCiAgICAgKiBAcGFyYW0gc3RyaW5nW118c3RyaW5nICRwYXRocyAgVGhlIFBTUi00IGJhc2UgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBzcjQoJHByZWZpeCwgJHBhdGhzKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNCA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsZW5ndGggPSBzdHJsZW4oJHByZWZpeCk7CiAgICAgICAgICAgIGlmICgnXFwnICE9PSAkcHJlZml4WyRsZW5ndGggLSAxXSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oIkEgbm9uLWVtcHR5IFBTUi00IHByZWZpeCBtdXN0IGVuZCB3aXRoIGEgbmFtZXNwYWNlIHNlcGFyYXRvci4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+cHJlZml4TGVuZ3Roc1BzcjRbJHByZWZpeFswXV1bJHByZWZpeF0gPSAkbGVuZ3RoOwogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyBvbiBzZWFyY2hpbmcgdGhlIGluY2x1ZGUgcGF0aCBmb3IgY2xhc3MgZmlsZXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHVzZUluY2x1ZGVQYXRoCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVc2VJbmNsdWRlUGF0aCgkdXNlSW5jbHVkZVBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPnVzZUluY2x1ZGVQYXRoID0gJHVzZUluY2x1ZGVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogQ2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgdGhlIGF1dG9sb2FkZXIgdXNlcyB0aGUgaW5jbHVkZSBwYXRoIHRvIGNoZWNrCiAgICAgKiBmb3IgY2xhc3Nlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVzZUluY2x1ZGVQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVzZUluY2x1ZGVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogVHVybnMgb2ZmIHNlYXJjaGluZyB0aGUgcHJlZml4IGFuZCBmYWxsYmFjayBkaXJlY3RvcmllcyBmb3IgY2xhc3NlcwogICAgICogdGhhdCBoYXZlIG5vdCBiZWVuIHJlZ2lzdGVyZWQgd2l0aCB0aGUgY2xhc3MgbWFwLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjbGFzc01hcEF1dGhvcml0YXRpdmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkY2xhc3NNYXBBdXRob3JpdGF0aXZlKQogICAgewogICAgICAgICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmUgPSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogU2hvdWxkIGNsYXNzIGxvb2t1cCBmYWlsIGlmIG5vdCBmb3VuZCBpbiB0aGUgY3VycmVudCBjbGFzcyBtYXA/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0NsYXNzTWFwQXV0aG9yaXRhdGl2ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBUEN1IHByZWZpeCB0byB1c2UgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMsIGlmIHRoZSBleHRlbnNpb24gaXMgZW5hYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGFwY3VQcmVmaXgKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFwY3VQcmVmaXgoJGFwY3VQcmVmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPmFwY3VQcmVmaXggPSBmdW5jdGlvbl9leGlzdHMoJ2FwY3VfZmV0Y2gnKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5lbmFibGVkJyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSA/ICRhcGN1UHJlZml4IDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBBUEN1IHByZWZpeCBpbiB1c2UsIG9yIG51bGwgaWYgQVBDdSBjYWNoaW5nIGlzIG5vdCBlbmFibGVkLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFwY3VQcmVmaXgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXBjdVByZWZpeDsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyB0aGlzIGluc3RhbmNlIGFzIGFuIGF1dG9sb2FkZXIuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHByZXBlbmQgV2hldGhlciB0byBwcmVwZW5kIHRoZSBhdXRvbG9hZGVyIG9yIG5vdAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoJHByZXBlbmQgPSBmYWxzZSkKICAgIHsKICAgICAgICBzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJHRoaXMsICdsb2FkQ2xhc3MnKSwgdHJ1ZSwgJHByZXBlbmQpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnZlbmRvckRpcikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzID0gYXJyYXkoJHRoaXMtPnZlbmRvckRpciA9PiAkdGhpcykgKyBzZWxmOjokcmVnaXN0ZXJlZExvYWRlcnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdW5zZXQoc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzWyR0aGlzLT52ZW5kb3JEaXJdKTsKICAgICAgICAgICAgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzWyR0aGlzLT52ZW5kb3JEaXJdID0gJHRoaXM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVW5yZWdpc3RlcnMgdGhpcyBpbnN0YW5jZSBhcyBhbiBhdXRvbG9hZGVyLgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5yZWdpc3RlcigpCiAgICB7CiAgICAgICAgc3BsX2F1dG9sb2FkX3VucmVnaXN0ZXIoYXJyYXkoJHRoaXMsICdsb2FkQ2xhc3MnKSk7CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+dmVuZG9yRGlyKSB7CiAgICAgICAgICAgIHVuc2V0KHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyc1skdGhpcy0+dmVuZG9yRGlyXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTG9hZHMgdGhlIGdpdmVuIGNsYXNzIG9yIGludGVyZmFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAkY2xhc3MgVGhlIG5hbWUgb2YgdGhlIGNsYXNzCiAgICAgKiBAcmV0dXJuIHRydWV8bnVsbCBUcnVlIGlmIGxvYWRlZCwgbnVsbCBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRDbGFzcygkY2xhc3MpCiAgICB7CiAgICAgICAgaWYgKCRmaWxlID0gJHRoaXMtPmZpbmRGaWxlKCRjbGFzcykpIHsKICAgICAgICAgICAgaW5jbHVkZUZpbGUoJGZpbGUpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBwYXRoIHRvIHRoZSBmaWxlIHdoZXJlIHRoZSBjbGFzcyBpcyBkZWZpbmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsYXNzIFRoZSBuYW1lIG9mIHRoZSBjbGFzcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFRoZSBwYXRoIGlmIGZvdW5kLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRGaWxlKCRjbGFzcykKICAgIHsKICAgICAgICAvLyBjbGFzcyBtYXAgbG9va3VwCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jbGFzc01hcFskY2xhc3NdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNsYXNzTWFwWyRjbGFzc107CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlIHx8IGlzc2V0KCR0aGlzLT5taXNzaW5nQ2xhc3Nlc1skY2xhc3NdKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+YXBjdVByZWZpeCkgewogICAgICAgICAgICAkZmlsZSA9IGFwY3VfZmV0Y2goJHRoaXMtPmFwY3VQcmVmaXguJGNsYXNzLCAkaGl0KTsKICAgICAgICAgICAgaWYgKCRoaXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGZpbGUgPSAkdGhpcy0+ZmluZEZpbGVXaXRoRXh0ZW5zaW9uKCRjbGFzcywgJy5waHAnKTsKCiAgICAgICAgLy8gU2VhcmNoIGZvciBIYWNrIGZpbGVzIGlmIHdlIGFyZSBydW5uaW5nIG9uIEhIVk0KICAgICAgICBpZiAoZmFsc2UgPT09ICRmaWxlICYmIGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CiAgICAgICAgICAgICRmaWxlID0gJHRoaXMtPmZpbmRGaWxlV2l0aEV4dGVuc2lvbigkY2xhc3MsICcuaGgnKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+YXBjdVByZWZpeCkgewogICAgICAgICAgICBhcGN1X2FkZCgkdGhpcy0+YXBjdVByZWZpeC4kY2xhc3MsICRmaWxlKTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJGZpbGUpIHsKICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhhdCB0aGlzIGNsYXNzIGRvZXMgbm90IGV4aXN0LgogICAgICAgICAgICAkdGhpcy0+bWlzc2luZ0NsYXNzZXNbJGNsYXNzXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgcmVnaXN0ZXJlZCBsb2FkZXJzIGluZGV4ZWQgYnkgdGhlaXIgY29ycmVzcG9uZGluZyB2ZW5kb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHJldHVybiBzZWxmW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSZWdpc3RlcmVkTG9hZGVycygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRjbGFzcwogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgJGV4dAogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaW5kRmlsZVdpdGhFeHRlbnNpb24oJGNsYXNzLCAkZXh0KQogICAgewogICAgICAgIC8vIFBTUi00IGxvb2t1cAogICAgICAgICRsb2dpY2FsUGF0aFBzcjQgPSBzdHJ0cigkY2xhc3MsICdcXCcsIERJUkVDVE9SWV9TRVBBUkFUT1IpIC4gJGV4dDsKCiAgICAgICAgJGZpcnN0ID0gJGNsYXNzWzBdOwogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cHJlZml4TGVuZ3Roc1BzcjRbJGZpcnN0XSkpIHsKICAgICAgICAgICAgJHN1YlBhdGggPSAkY2xhc3M7CiAgICAgICAgICAgIHdoaWxlIChmYWxzZSAhPT0gJGxhc3RQb3MgPSBzdHJycG9zKCRzdWJQYXRoLCAnXFwnKSkgewogICAgICAgICAgICAgICAgJHN1YlBhdGggPSBzdWJzdHIoJHN1YlBhdGgsIDAsICRsYXN0UG9zKTsKICAgICAgICAgICAgICAgICRzZWFyY2ggPSAkc3ViUGF0aCAuICdcXCc7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByZWZpeERpcnNQc3I0WyRzZWFyY2hdKSkgewogICAgICAgICAgICAgICAgICAgICRwYXRoRW5kID0gRElSRUNUT1JZX1NFUEFSQVRPUiAuIHN1YnN0cigkbG9naWNhbFBhdGhQc3I0LCAkbGFzdFBvcyArIDEpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcmVmaXhEaXJzUHNyNFskc2VhcmNoXSBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSA9ICRkaXIgLiAkcGF0aEVuZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUFNSLTQgZmFsbGJhY2sgZGlycwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5mYWxsYmFja0RpcnNQc3I0IGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlID0gJGRpciAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkbG9naWNhbFBhdGhQc3I0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBQU1ItMCBsb29rdXAKICAgICAgICBpZiAoZmFsc2UgIT09ICRwb3MgPSBzdHJycG9zKCRjbGFzcywgJ1xcJykpIHsKICAgICAgICAgICAgLy8gbmFtZXNwYWNlZCBjbGFzcyBuYW1lCiAgICAgICAgICAgICRsb2dpY2FsUGF0aFBzcjAgPSBzdWJzdHIoJGxvZ2ljYWxQYXRoUHNyNCwgMCwgJHBvcyArIDEpCiAgICAgICAgICAgICAgICAuIHN0cnRyKHN1YnN0cigkbG9naWNhbFBhdGhQc3I0LCAkcG9zICsgMSksICdfJywgRElSRUNUT1JZX1NFUEFSQVRPUik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gUEVBUi1saWtlIGNsYXNzIG5hbWUKICAgICAgICAgICAgJGxvZ2ljYWxQYXRoUHNyMCA9IHN0cnRyKCRjbGFzcywgJ18nLCBESVJFQ1RPUllfU0VQQVJBVE9SKSAuICRleHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF0gYXMgJHByZWZpeCA9PiAkZGlycykgewogICAgICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkY2xhc3MsICRwcmVmaXgpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRpcnMgYXMgJGRpcikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUgPSAkZGlyIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRsb2dpY2FsUGF0aFBzcjApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBTUi0wIGZhbGxiYWNrIGRpcnMKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMCBhcyAkZGlyKSB7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSA9ICRkaXIgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJGxvZ2ljYWxQYXRoUHNyMCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUFNSLTAgaW5jbHVkZSBwYXRocy4KICAgICAgICBpZiAoJHRoaXMtPnVzZUluY2x1ZGVQYXRoICYmICRmaWxlID0gc3RyZWFtX3Jlc29sdmVfaW5jbHVkZV9wYXRoKCRsb2dpY2FsUGF0aFBzcjApKSB7CiAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoKLyoqCiAqIFNjb3BlIGlzb2xhdGVkIGluY2x1ZGUuCiAqCiAqIFByZXZlbnRzIGFjY2VzcyB0byAkdGhpcy9zZWxmIGZyb20gaW5jbHVkZWQgZmlsZXMuCiAqCiAqIEBwYXJhbSAgc3RyaW5nICRmaWxlCiAqIEByZXR1cm4gdm9pZAogKiBAcHJpdmF0ZQogKi8KZnVuY3Rpb24gaW5jbHVkZUZpbGUoJGZpbGUpCnsKICAgIGluY2x1ZGUgJGZpbGU7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGludGVybmFsCiAqLwpjbGFzcyBQaHBGaWxlQ2xlYW5lcgp7CiAgICAvKiogQHZhciBhcnJheTxhcnJheXtuYW1lOiBzdHJpbmcsIGxlbmd0aDogaW50LCBwYXR0ZXJuOiBzdHJpbmd9PiAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHR5cGVDb25maWc7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlIHN0YXRpYyAkcmVzdFBhdHRlcm47CgogICAgLyoqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbnRlbnRzOwoKICAgIC8qKgogICAgICogQHJlYWRvbmx5CiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcml2YXRlICRsZW47CgogICAgLyoqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByaXZhdGUgJG1heE1hdGNoZXM7CgogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICRpbmRleCA9IDA7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHR5cGVzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRUeXBlQ29uZmlnKCR0eXBlcykKICAgIHsKICAgICAgICBmb3JlYWNoICgkdHlwZXMgYXMgJHR5cGUpIHsKICAgICAgICAgICAgc2VsZjo6JHR5cGVDb25maWdbJHR5cGVbMF1dID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnbmFtZScgPT4gJHR5cGUsCiAgICAgICAgICAgICAgICAnbGVuZ3RoJyA9PiBcc3RybGVuKCR0eXBlKSwKICAgICAgICAgICAgICAgICdwYXR0ZXJuJyA9PiAney5cYig/PCFbXCQ6Pl0pJy4kdHlwZS4nXHMrK1thLXpBLVpfXHg3Zi1ceGZmOl1bYS16QS1aMC05X1x4N2YtXHhmZjpcLV0qK31BaXMnLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JHJlc3RQYXR0ZXJuID0gJ3tbXj8iXCc8LycuaW1wbG9kZSgnJywgYXJyYXlfa2V5cyhzZWxmOjokdHlwZUNvbmZpZykpLiddK31BJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnRzCiAgICAgKiBAcGFyYW0gaW50ICRtYXhNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29udGVudHMsICRtYXhNYXRjaGVzKQogICAgewogICAgICAgICR0aGlzLT5jb250ZW50cyA9ICRjb250ZW50czsKICAgICAgICAkdGhpcy0+bGVuID0gXHN0cmxlbigkdGhpcy0+Y29udGVudHMpOwogICAgICAgICR0aGlzLT5tYXhNYXRjaGVzID0gJG1heE1hdGNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW4oKQogICAgewogICAgICAgICRjbGVhbiA9ICcnOwoKICAgICAgICB3aGlsZSAoJHRoaXMtPmluZGV4IDwgJHRoaXMtPmxlbikgewogICAgICAgICAgICAkdGhpcy0+c2tpcFRvUGhwKCk7CiAgICAgICAgICAgICRjbGVhbiAuPSAnPD8nOwoKICAgICAgICAgICAgd2hpbGUgKCR0aGlzLT5pbmRleCA8ICR0aGlzLT5sZW4pIHsKICAgICAgICAgICAgICAgICRjaGFyID0gJHRoaXMtPmNvbnRlbnRzWyR0aGlzLT5pbmRleF07CiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICc/JyAmJiAkdGhpcy0+cGVlaygnPicpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNsZWFuIC49ICc/Pic7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDI7CiAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICciJykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5za2lwU3RyaW5nKCciJyk7CiAgICAgICAgICAgICAgICAgICAgJGNsZWFuIC49ICdudWxsJzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICInIikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5za2lwU3RyaW5nKCInIik7CiAgICAgICAgICAgICAgICAgICAgJGNsZWFuIC49ICdudWxsJzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICI8IiAmJiAkdGhpcy0+cGVlaygnPCcpICYmICR0aGlzLT5tYXRjaCgnezw8PFsgXHRdKisoW1wnIl0/KShbYS16QS1aX1x4ODAtXHhmZl1bYS16QS1aMC05X1x4ODAtXHhmZl0qKylcXDEoPzpcclxufFxufFxyKX1BJywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSBcc3RybGVuKCRtYXRjaFswXSk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNraXBIZXJlZG9jKCRtYXRjaFsyXSk7CiAgICAgICAgICAgICAgICAgICAgJGNsZWFuIC49ICdudWxsJzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICcvJykgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cGVlaygnLycpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5za2lwVG9OZXdsaW5lKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnBlZWsoJyonKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2tpcENvbW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+bWF4TWF0Y2hlcyA9PT0gMSAmJiBpc3NldChzZWxmOjokdHlwZUNvbmZpZ1skY2hhcl0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHR5cGUgPSBzZWxmOjokdHlwZUNvbmZpZ1skY2hhcl07CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICBcc3Vic3RyKCR0aGlzLT5jb250ZW50cywgJHRoaXMtPmluZGV4LCAkdHlwZVsnbGVuZ3RoJ10pID09PSAkdHlwZVsnbmFtZSddCiAgICAgICAgICAgICAgICAgICAgICAgICYmIFByZWc6OmlzTWF0Y2goJHR5cGVbJ3BhdHRlcm4nXSwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gsIDAsICR0aGlzLT5pbmRleCAtIDEpCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjbGVhbiAuPSAkbWF0Y2hbMF07CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGNsZWFuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+bWF0Y2goc2VsZjo6JHJlc3RQYXR0ZXJuLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNsZWFuIC49ICRjaGFyIC4gJG1hdGNoWzBdOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSBcc3RybGVuKCRtYXRjaFswXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRjbGVhbiAuPSAkY2hhcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjbGVhbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNraXBUb1BocCgpCiAgICB7CiAgICAgICAgd2hpbGUgKCR0aGlzLT5pbmRleCA8ICR0aGlzLT5sZW4pIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5jb250ZW50c1skdGhpcy0+aW5kZXhdID09PSAnPCcgJiYgJHRoaXMtPnBlZWsoJz8nKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDE7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZGVsaW1pdGVyCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBza2lwU3RyaW5nKCRkZWxpbWl0ZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmluZGV4ICs9IDE7CiAgICAgICAgd2hpbGUgKCR0aGlzLT5pbmRleCA8ICR0aGlzLT5sZW4pIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5jb250ZW50c1skdGhpcy0+aW5kZXhdID09PSAnXFwnICYmICgkdGhpcy0+cGVlaygnXFwnKSB8fCAkdGhpcy0+cGVlaygkZGVsaW1pdGVyKSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAyOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5jb250ZW50c1skdGhpcy0+aW5kZXhdID09PSAkZGVsaW1pdGVyKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAxOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNraXBDb21tZW50KCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5kZXggKz0gMjsKICAgICAgICB3aGlsZSAoJHRoaXMtPmluZGV4IDwgJHRoaXMtPmxlbikgewogICAgICAgICAgICBpZiAoJHRoaXMtPmNvbnRlbnRzWyR0aGlzLT5pbmRleF0gPT09ICcqJyAmJiAkdGhpcy0+cGVlaygnLycpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBza2lwVG9OZXdsaW5lKCkKICAgIHsKICAgICAgICB3aGlsZSAoJHRoaXMtPmluZGV4IDwgJHRoaXMtPmxlbikgewogICAgICAgICAgICBpZiAoJHRoaXMtPmNvbnRlbnRzWyR0aGlzLT5pbmRleF0gPT09ICJcciIgfHwgJHRoaXMtPmNvbnRlbnRzWyR0aGlzLT5pbmRleF0gPT09ICJcbiIpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkZWxpbWl0ZXIKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNraXBIZXJlZG9jKCRkZWxpbWl0ZXIpCiAgICB7CiAgICAgICAgJGZpcnN0RGVsaW1pdGVyQ2hhciA9ICRkZWxpbWl0ZXJbMF07CiAgICAgICAgJGRlbGltaXRlckxlbmd0aCA9IFxzdHJsZW4oJGRlbGltaXRlcik7CiAgICAgICAgJGRlbGltaXRlclBhdHRlcm4gPSAneycucHJlZ19xdW90ZSgkZGVsaW1pdGVyKS4nKD8hW2EtekEtWjAtOV9ceDgwLVx4ZmZdKX1BJzsKCiAgICAgICAgd2hpbGUgKCR0aGlzLT5pbmRleCA8ICR0aGlzLT5sZW4pIHsKICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgZmluZCB0aGUgZGVsaW1pdGVyIGFmdGVyIHNvbWUgc3BhY2VzL3RhYnMKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+Y29udGVudHNbJHRoaXMtPmluZGV4XSkgewogICAgICAgICAgICAgICAgY2FzZSAiXHQiOgogICAgICAgICAgICAgICAgY2FzZSAiICI6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDE7CiAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgIGNhc2UgJGZpcnN0RGVsaW1pdGVyQ2hhcjoKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIFxzdWJzdHIoJHRoaXMtPmNvbnRlbnRzLCAkdGhpcy0+aW5kZXgsICRkZWxpbWl0ZXJMZW5ndGgpID09PSAkZGVsaW1pdGVyCiAgICAgICAgICAgICAgICAgICAgICAgICYmICR0aGlzLT5tYXRjaCgkZGVsaW1pdGVyUGF0dGVybikKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9ICRkZWxpbWl0ZXJMZW5ndGg7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBza2lwIHRoZSByZXN0IG9mIHRoZSBsaW5lCiAgICAgICAgICAgIHdoaWxlICgkdGhpcy0+aW5kZXggPCAkdGhpcy0+bGVuKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2tpcFRvTmV3bGluZSgpOwoKICAgICAgICAgICAgICAgIC8vIHNraXAgbmV3bGluZXMKICAgICAgICAgICAgICAgIHdoaWxlICgkdGhpcy0+aW5kZXggPCAkdGhpcy0+bGVuICYmICgkdGhpcy0+Y29udGVudHNbJHRoaXMtPmluZGV4XSA9PT0gIlxyIiB8fCAkdGhpcy0+Y29udGVudHNbJHRoaXMtPmluZGV4XSA9PT0gIlxuIikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNoYXIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBlZWsoJGNoYXIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmRleCArIDEgPCAkdGhpcy0+bGVuICYmICR0aGlzLT5jb250ZW50c1skdGhpcy0+aW5kZXggKyAxXSA9PT0gJGNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWdleAogICAgICogQHBhcmFtID9hcnJheTxpbnQsIHN0cmluZz4gJG1hdGNoCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXRjaCgkcmVnZXgsIGFycmF5ICYkbWF0Y2ggPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBQcmVnOjppc01hdGNoKCRyZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gsIDAsICR0aGlzLT5pbmRleCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXElnbm9yZUFsbFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQm91bmQ7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcUGFja2FnZVNvcnRlcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CgovKioKICogQGF1dGhvciBJZ29yIFdpZWRsZXIgPGlnb3JAd2llZGxlci5jaD4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQXV0b2xvYWRHZW5lcmF0b3IKewogICAgLyoqCiAgICAgKiBAdmFyIEV2ZW50RGlzcGF0Y2hlcgogICAgICovCiAgICBwcml2YXRlICRldmVudERpc3BhdGNoZXI7CgogICAgLyoqCiAgICAgKiBAdmFyID9JT0ludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRpbzsKCiAgICAvKioKICAgICAqIEB2YXIgP2Jvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkZGV2TW9kZSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkYXBjdSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcml2YXRlICRhcGN1UHJlZml4OwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJHJ1blNjcmlwdHMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciwgSU9JbnRlcmZhY2UgJGlvID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyID0gJGV2ZW50RGlzcGF0Y2hlcjsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CgogICAgICAgICR0aGlzLT5wbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID0gUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6Omlnbm9yZU5vdGhpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRkZXZNb2RlCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERldk1vZGUoJGRldk1vZGUgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5kZXZNb2RlID0gKGJvb2wpICRkZXZNb2RlOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciBnZW5lcmF0ZWQgYXV0b2xvYWRlciBjb25zaWRlcnMgdGhlIGNsYXNzIG1hcCBhdXRob3JpdGF0aXZlLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjbGFzc01hcEF1dGhvcml0YXRpdmUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2xhc3NNYXBBdXRob3JpdGF0aXZlKCRjbGFzc01hcEF1dGhvcml0YXRpdmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSA9IChib29sKSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciBnZW5lcmF0ZWQgYXV0b2xvYWRlciBjb25zaWRlcnMgQVBDdSBjYWNoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkYXBjdQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRhcGN1UHJlZml4CiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFwY3UoJGFwY3UsICRhcGN1UHJlZml4ID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YXBjdSA9IChib29sKSAkYXBjdTsKICAgICAgICAkdGhpcy0+YXBjdVByZWZpeCA9ICRhcGN1UHJlZml4ICE9PSBudWxsID8gKHN0cmluZykgJGFwY3VQcmVmaXggOiAkYXBjdVByZWZpeDsKICAgIH0KCiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8gcnVuIHNjcmlwdHMgb3Igbm90CiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHJ1blNjcmlwdHMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UnVuU2NyaXB0cygkcnVuU2NyaXB0cyA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnJ1blNjcmlwdHMgPSAoYm9vbCkgJHJ1blNjcmlwdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHBsYXRmb3JtIHJlcXVpcmVtZW50cyBzaG91bGQgYmUgaWdub3JlZC4KICAgICAqCiAgICAgKiBJZiB0aGlzIGlzIHNldCB0byB0cnVlLCB0aGUgcGxhdGZvcm0gY2hlY2sgZmlsZSB3aWxsIG5vdCBiZSBnZW5lcmF0ZWQKICAgICAqIElmIHRoaXMgaXMgc2V0IHRvIGZhbHNlLCB0aGUgcGxhdGZvcm0gY2hlY2sgZmlsZSB3aWxsIGJlIGdlbmVyYXRlZCB3aXRoIGFsbCByZXF1aXJlbWVudHMKICAgICAqIElmIHRoaXMgaXMgc2V0IHRvIHN0cmluZ1tdLCB0aG9zZSBwYWNrYWdlcyB3aWxsIGJlIGlnbm9yZWQgZnJvbSB0aGUgcGxhdGZvcm0gY2hlY2sgZmlsZQogICAgICoKICAgICAqIEBwYXJhbSBib29sfHN0cmluZ1tdICRpZ25vcmVQbGF0Zm9ybVJlcXMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHVzZSBzZXRQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RlYWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElnbm9yZVBsYXRmb3JtUmVxdWlyZW1lbnRzKCRpZ25vcmVQbGF0Zm9ybVJlcXMpCiAgICB7CiAgICAgICAgdHJpZ2dlcl9lcnJvcignQXV0b2xvYWRHZW5lcmF0b3I6OnNldElnbm9yZVBsYXRmb3JtUmVxdWlyZW1lbnRzIGlzIGRlcHJlY2F0ZWQgc2luY2UgQ29tcG9zZXIgMi4yLCB1c2Ugc2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbnN0ZWFkLicsIEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgJHRoaXMtPnNldFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6OmZyb21Cb29sT3JMaXN0KCRpZ25vcmVQbGF0Zm9ybVJlcXMpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcihQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKQogICAgewogICAgICAgICR0aGlzLT5wbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID0gJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXREaXIKICAgICAqIEBwYXJhbSBib29sICRzY2FuUHNyUGFja2FnZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1ZmZpeAogICAgICogQHJldHVybiBpbnQKICAgICAqIEB0aHJvd3MgXFNlbGRcSnNvbkxpbnRcUGFyc2luZ0V4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZHVtcChDb25maWcgJGNvbmZpZywgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvLCBSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UsIEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIsICR0YXJnZXREaXIsICRzY2FuUHNyUGFja2FnZXMgPSBmYWxzZSwgJHN1ZmZpeCA9ICcnKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlKSB7CiAgICAgICAgICAgIC8vIEZvcmNlIHNjYW5Qc3JQYWNrYWdlcyB3aGVuIGNsYXNzbWFwIGlzIGF1dGhvcml0YXRpdmUKICAgICAgICAgICAgJHNjYW5Qc3JQYWNrYWdlcyA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBhdXRvLXNldCBkZXZNb2RlIGJhc2VkIG9uIHdoZXRoZXIgZGV2IGRlcGVuZGVuY2llcyBhcmUgaW5zdGFsbGVkIG9yIG5vdAogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+ZGV2TW9kZSkgewogICAgICAgICAgICAvLyB3ZSBhc3N1bWUgbm8tZGV2IG1vZGUgaWYgbm8gdmVuZG9yIGRpciBpcyBwcmVzZW50IG9yIGl0IGlzIHRvbyBvbGQgdG8gY29udGFpbiBkZXYgaW5mb3JtYXRpb24KICAgICAgICAgICAgJHRoaXMtPmRldk1vZGUgPSBmYWxzZTsKCiAgICAgICAgICAgICRpbnN0YWxsZWRKc29uID0gbmV3IEpzb25GaWxlKCRjb25maWctPmdldCgndmVuZG9yLWRpcicpLicvY29tcG9zZXIvaW5zdGFsbGVkLmpzb24nKTsKICAgICAgICAgICAgaWYgKCRpbnN0YWxsZWRKc29uLT5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgJGluc3RhbGxlZEpzb24gPSAkaW5zdGFsbGVkSnNvbi0+cmVhZCgpOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRpbnN0YWxsZWRKc29uWydkZXYnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGV2TW9kZSA9ICRpbnN0YWxsZWRKc29uWydkZXYnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5ydW5TY3JpcHRzKSB7CiAgICAgICAgICAgIC8vIHNldCBDT01QT1NFUl9ERVZfTU9ERSBpbiBjYXNlIG5vdCBzZXQgeWV0IHNvIGl0IGlzIGF2YWlsYWJsZSBpbiB0aGUgZHVtcC1hdXRvbG9hZCBldmVudCBsaXN0ZW5lcnMKICAgICAgICAgICAgaWYgKCFpc3NldCgkX1NFUlZFUlsnQ09NUE9TRVJfREVWX01PREUnXSkpIHsKICAgICAgICAgICAgICAgIFBsYXRmb3JtOjpwdXRFbnYoJ0NPTVBPU0VSX0RFVl9NT0RFJywgJHRoaXMtPmRldk1vZGUgPyAnMScgOiAnMCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBSRV9BVVRPTE9BRF9EVU1QLCAkdGhpcy0+ZGV2TW9kZSwgYXJyYXkoKSwgYXJyYXkoCiAgICAgICAgICAgICAgICAnb3B0aW1pemUnID0+IChib29sKSAkc2NhblBzclBhY2thZ2VzLAogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgICRmaWxlc3lzdGVtID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRjb25maWctPmdldCgndmVuZG9yLWRpcicpKTsKICAgICAgICAvLyBEbyBub3QgcmVtb3ZlIGRvdWJsZSByZWFscGF0aCgpIGNhbGxzLgogICAgICAgIC8vIEZpeGVzIGZhaWxpbmcgV2luZG93cyByZWFscGF0aCgpIGltcGxlbWVudGF0aW9uLgogICAgICAgIC8vIFNlZSBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTcyNzM4CiAgICAgICAgJGJhc2VQYXRoID0gJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgocmVhbHBhdGgocmVhbHBhdGgoZ2V0Y3dkKCkpKSk7CiAgICAgICAgJHZlbmRvclBhdGggPSAkZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aChyZWFscGF0aChyZWFscGF0aCgkY29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKSkpKTsKICAgICAgICAkdXNlR2xvYmFsSW5jbHVkZVBhdGggPSAoYm9vbCkgJGNvbmZpZy0+Z2V0KCd1c2UtaW5jbHVkZS1wYXRoJyk7CiAgICAgICAgJHByZXBlbmRBdXRvbG9hZGVyID0gJGNvbmZpZy0+Z2V0KCdwcmVwZW5kLWF1dG9sb2FkZXInKSA9PT0gZmFsc2UgPyAnZmFsc2UnIDogJ3RydWUnOwogICAgICAgICR0YXJnZXREaXIgPSAkdmVuZG9yUGF0aC4nLycuJHRhcmdldERpcjsKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0YXJnZXREaXIpOwoKICAgICAgICAkdmVuZG9yUGF0aENvZGUgPSAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUocmVhbHBhdGgoJHRhcmdldERpciksICR2ZW5kb3JQYXRoLCB0cnVlKTsKICAgICAgICAkdmVuZG9yUGF0aENvZGU1MiA9IHN0cl9yZXBsYWNlKCdfX0RJUl9fJywgJ2Rpcm5hbWUoX19GSUxFX18pJywgJHZlbmRvclBhdGhDb2RlKTsKICAgICAgICAkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZSA9ICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZSgkdmVuZG9yUGF0aCwgcmVhbHBhdGgoJHRhcmdldERpciksIHRydWUpOwoKICAgICAgICAkYXBwQmFzZURpckNvZGUgPSAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUoJHZlbmRvclBhdGgsICRiYXNlUGF0aCwgdHJ1ZSk7CiAgICAgICAgJGFwcEJhc2VEaXJDb2RlID0gc3RyX3JlcGxhY2UoJ19fRElSX18nLCAnJHZlbmRvckRpcicsICRhcHBCYXNlRGlyQ29kZSk7CgogICAgICAgICRuYW1lc3BhY2VzRmlsZSA9IDw8PEVPRgo8P3BocAoKLy8gYXV0b2xvYWRfbmFtZXNwYWNlcy5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKXCR2ZW5kb3JEaXIgPSAkdmVuZG9yUGF0aENvZGU1MjsKXCRiYXNlRGlyID0gJGFwcEJhc2VEaXJDb2RlOwoKcmV0dXJuIGFycmF5KAoKRU9GOwoKICAgICAgICAkcHNyNEZpbGUgPSA8PDxFT0YKPD9waHAKCi8vIGF1dG9sb2FkX3BzcjQucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKClwkdmVuZG9yRGlyID0gJHZlbmRvclBhdGhDb2RlNTI7ClwkYmFzZURpciA9ICRhcHBCYXNlRGlyQ29kZTsKCnJldHVybiBhcnJheSgKCkVPRjsKCiAgICAgICAgLy8gQ29sbGVjdCBpbmZvcm1hdGlvbiBmcm9tIGFsbCBwYWNrYWdlcy4KICAgICAgICAkZGV2UGFja2FnZU5hbWVzID0gJGxvY2FsUmVwby0+Z2V0RGV2UGFja2FnZU5hbWVzKCk7CiAgICAgICAgJHBhY2thZ2VNYXAgPSAkdGhpcy0+YnVpbGRQYWNrYWdlTWFwKCRpbnN0YWxsYXRpb25NYW5hZ2VyLCAkcm9vdFBhY2thZ2UsICRsb2NhbFJlcG8tPmdldENhbm9uaWNhbFBhY2thZ2VzKCkpOwogICAgICAgIGlmICgkdGhpcy0+ZGV2TW9kZSkgewogICAgICAgICAgICAvLyBpZiBkZXYgbW9kZSBpcyBlbmFibGVkLCB0aGVuIHdlIGRvIG5vdCBmaWx0ZXIgYW55IGRldiBwYWNrYWdlcyBvdXQgc28gZGlzYWJsZSB0aGlzIGVudGlyZWx5CiAgICAgICAgICAgICRmaWx0ZXJlZERldlBhY2thZ2VzID0gZmFsc2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gaWYgdGhlIGxpc3Qgb2YgZGV2IHBhY2thZ2UgbmFtZXMgaXMgYXZhaWxhYmxlIHdlIHVzZSB0aGF0IHN0cmFpZ2h0LCBvdGhlcndpc2UgcGFzcyB0cnVlIHdoaWNoIG1lYW5zIHVzZSBsZWdhY3kgYWxnbyB0byBmaWd1cmUgdGhlbSBvdXQKICAgICAgICAgICAgJGZpbHRlcmVkRGV2UGFja2FnZXMgPSAkZGV2UGFja2FnZU5hbWVzID86IHRydWU7CiAgICAgICAgfQogICAgICAgICRhdXRvbG9hZHMgPSAkdGhpcy0+cGFyc2VBdXRvbG9hZHMoJHBhY2thZ2VNYXAsICRyb290UGFja2FnZSwgJGZpbHRlcmVkRGV2UGFja2FnZXMpOwoKICAgICAgICAvLyBQcm9jZXNzIHRoZSAncHNyLTAnIGJhc2UgZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2Fkc1sncHNyLTAnXSBhcyAkbmFtZXNwYWNlID0+ICRwYXRocykgewogICAgICAgICAgICAkZXhwb3J0ZWRQYXRocyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYXRocyBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJGV4cG9ydGVkUGF0aHNbXSA9ICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRleHBvcnRlZFByZWZpeCA9IHZhcl9leHBvcnQoJG5hbWVzcGFjZSwgdHJ1ZSk7CiAgICAgICAgICAgICRuYW1lc3BhY2VzRmlsZSAuPSAiICAgICRleHBvcnRlZFByZWZpeCA9PiAiOwogICAgICAgICAgICAkbmFtZXNwYWNlc0ZpbGUgLj0gImFycmF5KCIuaW1wbG9kZSgnLCAnLCAkZXhwb3J0ZWRQYXRocykuIiksXG4iOwogICAgICAgIH0KICAgICAgICAkbmFtZXNwYWNlc0ZpbGUgLj0gIik7XG4iOwoKICAgICAgICAvLyBQcm9jZXNzIHRoZSAncHNyLTQnIGJhc2UgZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2Fkc1sncHNyLTQnXSBhcyAkbmFtZXNwYWNlID0+ICRwYXRocykgewogICAgICAgICAgICAkZXhwb3J0ZWRQYXRocyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYXRocyBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJGV4cG9ydGVkUGF0aHNbXSA9ICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRleHBvcnRlZFByZWZpeCA9IHZhcl9leHBvcnQoJG5hbWVzcGFjZSwgdHJ1ZSk7CiAgICAgICAgICAgICRwc3I0RmlsZSAuPSAiICAgICRleHBvcnRlZFByZWZpeCA9PiAiOwogICAgICAgICAgICAkcHNyNEZpbGUgLj0gImFycmF5KCIuaW1wbG9kZSgnLCAnLCAkZXhwb3J0ZWRQYXRocykuIiksXG4iOwogICAgICAgIH0KICAgICAgICAkcHNyNEZpbGUgLj0gIik7XG4iOwoKICAgICAgICAkY2xhc3NtYXBGaWxlID0gPDw8RU9GCjw/cGhwCgovLyBhdXRvbG9hZF9jbGFzc21hcC5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKXCR2ZW5kb3JEaXIgPSAkdmVuZG9yUGF0aENvZGU1MjsKXCRiYXNlRGlyID0gJGFwcEJhc2VEaXJDb2RlOwoKcmV0dXJuIGFycmF5KAoKRU9GOwoKICAgICAgICAvLyBhZGQgY3VzdG9tIHBzci0wIGF1dG9sb2FkaW5nIGlmIHRoZSByb290IHBhY2thZ2UgaGFzIGEgdGFyZ2V0IGRpcgogICAgICAgICR0YXJnZXREaXJMb2FkZXIgPSBudWxsOwogICAgICAgICRtYWluQXV0b2xvYWQgPSAkcm9vdFBhY2thZ2UtPmdldEF1dG9sb2FkKCk7CiAgICAgICAgaWYgKCRyb290UGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkgJiYgIWVtcHR5KCRtYWluQXV0b2xvYWRbJ3Bzci0wJ10pKSB7CiAgICAgICAgICAgICRsZXZlbHMgPSBzdWJzdHJfY291bnQoJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHJvb3RQYWNrYWdlLT5nZXRUYXJnZXREaXIoKSksICcvJykgKyAxOwogICAgICAgICAgICAkcHJlZml4ZXMgPSBpbXBsb2RlKCcsICcsIGFycmF5X21hcChmdW5jdGlvbiAoJHByZWZpeCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhcl9leHBvcnQoJHByZWZpeCwgdHJ1ZSk7CiAgICAgICAgICAgIH0sIGFycmF5X2tleXMoJG1haW5BdXRvbG9hZFsncHNyLTAnXSkpKTsKICAgICAgICAgICAgJGJhc2VEaXJGcm9tVGFyZ2V0RGlyQ29kZSA9ICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZSgkdGFyZ2V0RGlyLCAkYmFzZVBhdGgsIHRydWUpOwoKICAgICAgICAgICAgJHRhcmdldERpckxvYWRlciA9IDw8PEVPRgoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYXV0b2xvYWQoXCRjbGFzcykKICAgIHsKICAgICAgICBcJGRpciA9ICRiYXNlRGlyRnJvbVRhcmdldERpckNvZGUgLiAnLyc7CiAgICAgICAgXCRwcmVmaXhlcyA9IGFycmF5KCRwcmVmaXhlcyk7CiAgICAgICAgZm9yZWFjaCAoXCRwcmVmaXhlcyBhcyBcJHByZWZpeCkgewogICAgICAgICAgICBpZiAoMCAhPT0gc3RycG9zKFwkY2xhc3MsIFwkcHJlZml4KSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgXCRwYXRoID0gXCRkaXIgLiBpbXBsb2RlKCcvJywgYXJyYXlfc2xpY2UoZXhwbG9kZSgnXFxcXCcsIFwkY2xhc3MpLCAkbGV2ZWxzKSkuJy5waHAnOwogICAgICAgICAgICBpZiAoIVwkcGF0aCA9IHN0cmVhbV9yZXNvbHZlX2luY2x1ZGVfcGF0aChcJHBhdGgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxdWlyZSBcJHBhdGg7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgpFT0Y7CiAgICAgICAgfQoKICAgICAgICAkZXhjbHVkZWQgPSBudWxsOwogICAgICAgIGlmICghZW1wdHkoJGF1dG9sb2Fkc1snZXhjbHVkZS1mcm9tLWNsYXNzbWFwJ10pKSB7CiAgICAgICAgICAgICRleGNsdWRlZCA9ICRhdXRvbG9hZHNbJ2V4Y2x1ZGUtZnJvbS1jbGFzc21hcCddOwogICAgICAgIH0KCiAgICAgICAgJGNsYXNzTWFwID0gYXJyYXkoKTsKICAgICAgICAkYW1iaWd1b3VzQ2xhc3NlcyA9IGFycmF5KCk7CiAgICAgICAgJHNjYW5uZWRGaWxlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2Fkc1snY2xhc3NtYXAnXSBhcyAkZGlyKSB7CiAgICAgICAgICAgICRjbGFzc01hcCA9ICR0aGlzLT5hZGRDbGFzc01hcENvZGUoJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICRkaXIsICRleGNsdWRlZCwgbnVsbCwgbnVsbCwgJGNsYXNzTWFwLCAkYW1iaWd1b3VzQ2xhc3NlcywgJHNjYW5uZWRGaWxlcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHNjYW5Qc3JQYWNrYWdlcykgewogICAgICAgICAgICAkbmFtZXNwYWNlc1RvU2NhbiA9IGFycmF5KCk7CgogICAgICAgICAgICAvLyBTY2FuIHRoZSBQU1ItMC80IGRpcmVjdG9yaWVzIGZvciBjbGFzcyBmaWxlcywgYW5kIGFkZCB0aGVtIHRvIHRoZSBjbGFzcyBtYXAKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3Bzci00JywgJ3Bzci0wJykgYXMgJHBzclR5cGUpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHNbJHBzclR5cGVdIGFzICRuYW1lc3BhY2UgPT4gJHBhdGhzKSB7CiAgICAgICAgICAgICAgICAgICAgJG5hbWVzcGFjZXNUb1NjYW5bJG5hbWVzcGFjZV1bXSA9IGFycmF5KCdwYXRocycgPT4gJHBhdGhzLCAndHlwZScgPT4gJHBzclR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBrcnNvcnQoJG5hbWVzcGFjZXNUb1NjYW4pOwoKICAgICAgICAgICAgZm9yZWFjaCAoJG5hbWVzcGFjZXNUb1NjYW4gYXMgJG5hbWVzcGFjZSA9PiAkZ3JvdXBzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZ3JvdXBzIGFzICRncm91cCkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRncm91cFsncGF0aHMnXSBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXIgPSAkZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aCgkZmlsZXN5c3RlbS0+aXNBYnNvbHV0ZVBhdGgoJGRpcikgPyAkZGlyIDogJGJhc2VQYXRoLicvJy4kZGlyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJGRpcikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkY2xhc3NNYXAgPSAkdGhpcy0+YWRkQ2xhc3NNYXBDb2RlKCRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkZGlyLCAkZXhjbHVkZWQsICRuYW1lc3BhY2UsICRncm91cFsndHlwZSddLCAkY2xhc3NNYXAsICRhbWJpZ3VvdXNDbGFzc2VzLCAkc2Nhbm5lZEZpbGVzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRhbWJpZ3VvdXNDbGFzc2VzIGFzICRjbGFzc05hbWUgPT4gJGFtYmlndW91c1BhdGhzKSB7CiAgICAgICAgICAgICRjbGVhblBhdGggPSBzdHJfcmVwbGFjZShhcnJheSgnJHZlbmRvckRpciAuIFwnJywgJyRiYXNlRGlyIC4gXCcnLCAiJyxcbiIpLCBhcnJheSgkdmVuZG9yUGF0aCwgJGJhc2VQYXRoLCAnJyksICRjbGFzc01hcFskY2xhc3NOYW1lXSk7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICAnPHdhcm5pbmc+V2FybmluZzogQW1iaWd1b3VzIGNsYXNzIHJlc29sdXRpb24sICInLiRjbGFzc05hbWUuJyInLgogICAgICAgICAgICAgICAgJyB3YXMgZm91bmQgJy4gKGNvdW50KCRhbWJpZ3VvdXNQYXRocykgKyAxKSAuJ3g6IGluICInLiRjbGVhblBhdGguJyIgYW5kICInLiBpbXBsb2RlKCciLCAiJywgJGFtYmlndW91c1BhdGhzKSAuJyIsIHRoZSBmaXJzdCB3aWxsIGJlIHVzZWQuPC93YXJuaW5nPicKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRjbGFzc01hcFsnQ29tcG9zZXJcXEluc3RhbGxlZFZlcnNpb25zJ10gPSAiXCR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL0luc3RhbGxlZFZlcnNpb25zLnBocCcsXG4iOwogICAgICAgIGtzb3J0KCRjbGFzc01hcCk7CiAgICAgICAgZm9yZWFjaCAoJGNsYXNzTWFwIGFzICRjbGFzcyA9PiAkY29kZSkgewogICAgICAgICAgICAkY2xhc3NtYXBGaWxlIC49ICcgICAgJy52YXJfZXhwb3J0KCRjbGFzcywgdHJ1ZSkuJyA9PiAnLiRjb2RlOwogICAgICAgIH0KICAgICAgICAkY2xhc3NtYXBGaWxlIC49ICIpO1xuIjsKCiAgICAgICAgaWYgKCEkc3VmZml4KSB7CiAgICAgICAgICAgIGlmICghJGNvbmZpZy0+Z2V0KCdhdXRvbG9hZGVyLXN1ZmZpeCcpICYmIEZpbGVzeXN0ZW06OmlzUmVhZGFibGUoJHZlbmRvclBhdGguJy9hdXRvbG9hZC5waHAnKSkgewogICAgICAgICAgICAgICAgJGNvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cygkdmVuZG9yUGF0aC4nL2F1dG9sb2FkLnBocCcpOwogICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3tDb21wb3NlckF1dG9sb2FkZXJJbml0KFteOlxzXSspOjp9JywgJGNvbnRlbnQsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkc3VmZml4ID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRzdWZmaXgpIHsKICAgICAgICAgICAgICAgICRzdWZmaXggPSAkY29uZmlnLT5nZXQoJ2F1dG9sb2FkZXItc3VmZml4JykgPzogbWQ1KHVuaXFpZCgnJywgdHJ1ZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkdGFyZ2V0RGlyLicvYXV0b2xvYWRfbmFtZXNwYWNlcy5waHAnLCAkbmFtZXNwYWNlc0ZpbGUpOwogICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR0YXJnZXREaXIuJy9hdXRvbG9hZF9wc3I0LnBocCcsICRwc3I0RmlsZSk7CiAgICAgICAgJGZpbGVzeXN0ZW0tPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHRhcmdldERpci4nL2F1dG9sb2FkX2NsYXNzbWFwLnBocCcsICRjbGFzc21hcEZpbGUpOwogICAgICAgICRpbmNsdWRlUGF0aEZpbGVQYXRoID0gJHRhcmdldERpci4nL2luY2x1ZGVfcGF0aHMucGhwJzsKICAgICAgICBpZiAoJGluY2x1ZGVQYXRoRmlsZUNvbnRlbnRzID0gJHRoaXMtPmdldEluY2x1ZGVQYXRoc0ZpbGUoJHBhY2thZ2VNYXAsICRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkdmVuZG9yUGF0aENvZGU1MiwgJGFwcEJhc2VEaXJDb2RlKSkgewogICAgICAgICAgICAkZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkaW5jbHVkZVBhdGhGaWxlUGF0aCwgJGluY2x1ZGVQYXRoRmlsZUNvbnRlbnRzKTsKICAgICAgICB9IGVsc2VpZiAoZmlsZV9leGlzdHMoJGluY2x1ZGVQYXRoRmlsZVBhdGgpKSB7CiAgICAgICAgICAgIHVubGluaygkaW5jbHVkZVBhdGhGaWxlUGF0aCk7CiAgICAgICAgfQogICAgICAgICRpbmNsdWRlRmlsZXNGaWxlUGF0aCA9ICR0YXJnZXREaXIuJy9hdXRvbG9hZF9maWxlcy5waHAnOwogICAgICAgIGlmICgkaW5jbHVkZUZpbGVzRmlsZUNvbnRlbnRzID0gJHRoaXMtPmdldEluY2x1ZGVGaWxlc0ZpbGUoJGF1dG9sb2Fkc1snZmlsZXMnXSwgJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICR2ZW5kb3JQYXRoQ29kZTUyLCAkYXBwQmFzZURpckNvZGUpKSB7CiAgICAgICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCRpbmNsdWRlRmlsZXNGaWxlUGF0aCwgJGluY2x1ZGVGaWxlc0ZpbGVDb250ZW50cyk7CiAgICAgICAgfSBlbHNlaWYgKGZpbGVfZXhpc3RzKCRpbmNsdWRlRmlsZXNGaWxlUGF0aCkpIHsKICAgICAgICAgICAgdW5saW5rKCRpbmNsdWRlRmlsZXNGaWxlUGF0aCk7CiAgICAgICAgfQogICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR0YXJnZXREaXIuJy9hdXRvbG9hZF9zdGF0aWMucGhwJywgJHRoaXMtPmdldFN0YXRpY0ZpbGUoJHN1ZmZpeCwgJHRhcmdldERpciwgJHZlbmRvclBhdGgsICRiYXNlUGF0aCwgJHN0YXRpY1BocFZlcnNpb24pKTsKICAgICAgICAkY2hlY2tQbGF0Zm9ybSA9ICRjb25maWctPmdldCgncGxhdGZvcm0tY2hlY2snKSAmJiAhKCR0aGlzLT5wbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RhbmNlb2YgSWdub3JlQWxsUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcik7CiAgICAgICAgJHBsYXRmb3JtQ2hlY2tDb250ZW50ID0gbnVsbDsKICAgICAgICBpZiAoJGNoZWNrUGxhdGZvcm0pIHsKICAgICAgICAgICAgJHBsYXRmb3JtQ2hlY2tDb250ZW50ID0gJHRoaXMtPmdldFBsYXRmb3JtQ2hlY2soJHBhY2thZ2VNYXAsICRjb25maWctPmdldCgncGxhdGZvcm0tY2hlY2snKSwgJGRldlBhY2thZ2VOYW1lcyk7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkcGxhdGZvcm1DaGVja0NvbnRlbnQpIHsKICAgICAgICAgICAgICAgICRjaGVja1BsYXRmb3JtID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCRjaGVja1BsYXRmb3JtKSB7CiAgICAgICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR0YXJnZXREaXIuJy9wbGF0Zm9ybV9jaGVjay5waHAnLCAkcGxhdGZvcm1DaGVja0NvbnRlbnQpOwogICAgICAgIH0gZWxzZWlmIChmaWxlX2V4aXN0cygkdGFyZ2V0RGlyLicvcGxhdGZvcm1fY2hlY2sucGhwJykpIHsKICAgICAgICAgICAgdW5saW5rKCR0YXJnZXREaXIuJy9wbGF0Zm9ybV9jaGVjay5waHAnKTsKICAgICAgICB9CiAgICAgICAgJGZpbGVzeXN0ZW0tPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHZlbmRvclBhdGguJy9hdXRvbG9hZC5waHAnLCAkdGhpcy0+Z2V0QXV0b2xvYWRGaWxlKCR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlLCAkc3VmZml4KSk7CiAgICAgICAgJGZpbGVzeXN0ZW0tPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHRhcmdldERpci4nL2F1dG9sb2FkX3JlYWwucGhwJywgJHRoaXMtPmdldEF1dG9sb2FkUmVhbEZpbGUodHJ1ZSwgKGJvb2wpICRpbmNsdWRlUGF0aEZpbGVDb250ZW50cywgJHRhcmdldERpckxvYWRlciwgKGJvb2wpICRpbmNsdWRlRmlsZXNGaWxlQ29udGVudHMsICR2ZW5kb3JQYXRoQ29kZSwgJGFwcEJhc2VEaXJDb2RlLCAkc3VmZml4LCAkdXNlR2xvYmFsSW5jbHVkZVBhdGgsICRwcmVwZW5kQXV0b2xvYWRlciwgJHN0YXRpY1BocFZlcnNpb24sICRjaGVja1BsYXRmb3JtKSk7CgogICAgICAgICRmaWxlc3lzdGVtLT5zYWZlQ29weShfX0RJUl9fLicvQ2xhc3NMb2FkZXIucGhwJywgJHRhcmdldERpci4nL0NsYXNzTG9hZGVyLnBocCcpOwogICAgICAgICRmaWxlc3lzdGVtLT5zYWZlQ29weShfX0RJUl9fLicvLi4vLi4vLi4vTElDRU5TRScsICR0YXJnZXREaXIuJy9MSUNFTlNFJyk7CgogICAgICAgIGlmICgkdGhpcy0+cnVuU2NyaXB0cykgewogICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBPU1RfQVVUT0xPQURfRFVNUCwgJHRoaXMtPmRldk1vZGUsIGFycmF5KCksIGFycmF5KAogICAgICAgICAgICAgICAgJ29wdGltaXplJyA9PiAoYm9vbCkgJHNjYW5Qc3JQYWNrYWdlcywKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY291bnQoJGNsYXNzTWFwKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZW5kb3JQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXIKICAgICAqIEBwYXJhbSA/YXJyYXk8aW50LCBzdHJpbmc+ICRleGNsdWRlZAogICAgICogQHBhcmFtID9zdHJpbmcgJG5hbWVzcGFjZUZpbHRlcgogICAgICogQHBhcmFtID9zdHJpbmcgJGF1dG9sb2FkVHlwZQogICAgICogQHBhcmFtIGFycmF5PGNsYXNzLXN0cmluZywgc3RyaW5nPiAkY2xhc3NNYXAKICAgICAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmcsIGFycmF5PGludCwgc3RyaW5nPj4gJGFtYmlndW91c0NsYXNzZXMKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHRydWU+ICRzY2FubmVkRmlsZXMKICAgICAqIEByZXR1cm4gYXJyYXk8Y2xhc3Mtc3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkQ2xhc3NNYXBDb2RlKEZpbGVzeXN0ZW0gJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICRkaXIsICRleGNsdWRlZCwgJG5hbWVzcGFjZUZpbHRlciwgJGF1dG9sb2FkVHlwZSwgYXJyYXkgJGNsYXNzTWFwLCBhcnJheSAmJGFtYmlndW91c0NsYXNzZXMsIGFycmF5ICYkc2Nhbm5lZEZpbGVzKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZW5lcmF0ZUNsYXNzTWFwKCRkaXIsICRleGNsdWRlZCwgJG5hbWVzcGFjZUZpbHRlciwgJGF1dG9sb2FkVHlwZSwgdHJ1ZSwgJHNjYW5uZWRGaWxlcykgYXMgJGNsYXNzID0+ICRwYXRoKSB7CiAgICAgICAgICAgICRwYXRoQ29kZSA9ICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpLiIsXG4iOwogICAgICAgICAgICBpZiAoIWlzc2V0KCRjbGFzc01hcFskY2xhc3NdKSkgewogICAgICAgICAgICAgICAgJGNsYXNzTWFwWyRjbGFzc10gPSAkcGF0aENvZGU7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+aW8gJiYgJGNsYXNzTWFwWyRjbGFzc10gIT09ICRwYXRoQ29kZSAmJiAhUHJlZzo6aXNNYXRjaCgney8odGVzdHxmaXh0dXJlfGV4YW1wbGV8c3R1YilzPy99aScsIHN0cnRyKCRjbGFzc01hcFskY2xhc3NdLicgJy4kcGF0aCwgJ1xcJywgJy8nKSkpIHsKICAgICAgICAgICAgICAgICRhbWJpZ3VvdXNDbGFzc2VzWyRjbGFzc11bXSA9ICRwYXRoOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNsYXNzTWFwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZGlyCiAgICAgKiBAcGFyYW0gP2FycmF5PGludCwgc3RyaW5nPiAkZXhjbHVkZWQKICAgICAqIEBwYXJhbSA/c3RyaW5nICRuYW1lc3BhY2VGaWx0ZXIKICAgICAqIEBwYXJhbSA/c3RyaW5nICRhdXRvbG9hZFR5cGUKICAgICAqIEBwYXJhbSBib29sICRzaG93QW1iaWd1b3VzV2FybmluZwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgdHJ1ZT4gJHNjYW5uZWRGaWxlcwogICAgICogQHJldHVybiBhcnJheTxjbGFzcy1zdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZW5lcmF0ZUNsYXNzTWFwKCRkaXIsICRleGNsdWRlZCwgJG5hbWVzcGFjZUZpbHRlciwgJGF1dG9sb2FkVHlwZSwgJHNob3dBbWJpZ3VvdXNXYXJuaW5nLCBhcnJheSAmJHNjYW5uZWRGaWxlcykKICAgIHsKICAgICAgICBpZiAoJGV4Y2x1ZGVkKSB7CiAgICAgICAgICAgIC8vIGZpbHRlciBleGNsdWRlZCBwYXR0ZXJucyBoZXJlIHRvIG9ubHkgdXNlIHRob3NlIG1hdGNoaW5nICRkaXIKICAgICAgICAgICAgLy8gZXhjbHVkZS1mcm9tLWNsYXNzbWFwIHBhdHRlcm5zIGFyZSBhbGwgcmVhbHBhdGgnZCBzbyB3ZSBjYW4gb25seSBmaWx0ZXIgdGhlbSBpZiAkZGlyIGV4aXN0cyBzbyB0aGF0IHJlYWxwYXRoKCRkaXIpIHdpbGwgd29yawogICAgICAgICAgICAvLyBpZiAkZGlyIGRvZXMgbm90IGV4aXN0LCBpdCBzaG91bGQgYW55d2F5IG5vdCBmaW5kIGFueXRoaW5nIHRoZXJlIHNvIG5vIHRyb3VibGUKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRkaXIpKSB7CiAgICAgICAgICAgICAgICAvLyB0cmFuc2Zvcm0gJGRpciBpbiB0aGUgc2FtZSB3YXkgdGhhdCBleGNsdWRlLWZyb20tY2xhc3NtYXAgcGF0dGVybnMgYXJlIHRyYW5zZm9ybWVkIHNvIHdlIGNhbiBtYXRjaCB0aGVtIGFnYWluc3QgZWFjaCBvdGhlcgogICAgICAgICAgICAgICAgJGRpck1hdGNoID0gcHJlZ19xdW90ZShzdHJ0cihyZWFscGF0aCgkZGlyKSwgJ1xcJywgJy8nKSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZXhjbHVkZWQgYXMgJGluZGV4ID0+ICRwYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmFjdCB0aGUgY29uc3RhbnQgc3RyaW5nIHByZWZpeCBvZiB0aGUgcGF0dGVybiBoZXJlLCB1bnRpbCB3ZSByZWFjaCBhIG5vbi1lc2NhcGVkIHJlZ2V4IHNwZWNpYWwgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAgICAgJHBhdHRlcm4gPSBQcmVnOjpyZXBsYWNlKCd7XigoW14uKyo/XFteXF0kKCl7fT0hPD58OlxcXFwjLV0rfFxcXFxbLisqP1xbXlxdJCgpe309ITw+fDojLV0pKikuKn0nLCAnJDEnLCAkcGF0dGVybik7CiAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHBhdHRlcm4gaXMgbm90IGEgc3Vic2V0IG9yIHN1cGVyc2V0IG9mICRkaXIsIGl0IGlzIHVucmVsYXRlZCBhbmQgd2Ugc2tpcCBpdAogICAgICAgICAgICAgICAgICAgIGlmICgwICE9PSBzdHJwb3MoJHBhdHRlcm4sICRkaXJNYXRjaCkgJiYgMCAhPT0gc3RycG9zKCRkaXJNYXRjaCwgJHBhdHRlcm4pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRleGNsdWRlZFskaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRleGNsdWRlZCA9ICRleGNsdWRlZCA/ICd7KCcgLiBpbXBsb2RlKCd8JywgJGV4Y2x1ZGVkKSAuICcpfScgOiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIENsYXNzTWFwR2VuZXJhdG9yOjpjcmVhdGVNYXAoJGRpciwgJGV4Y2x1ZGVkLCAkc2hvd0FtYmlndW91c1dhcm5pbmcgPyAkdGhpcy0+aW8gOiBudWxsLCAkbmFtZXNwYWNlRmlsdGVyLCAkYXV0b2xvYWRUeXBlLCAkc2Nhbm5lZEZpbGVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBJbnN0YWxsYXRpb25NYW5hZ2VyICRpbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdICRwYWNrYWdlcwogICAgICogQHJldHVybiBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBidWlsZFBhY2thZ2VNYXAoSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlciwgUGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UsIGFycmF5ICRwYWNrYWdlcykKICAgIHsKICAgICAgICAvLyBidWlsZCBwYWNrYWdlID0+IGluc3RhbGwgcGF0aCBtYXAKICAgICAgICAkcGFja2FnZU1hcCA9IGFycmF5KGFycmF5KCRyb290UGFja2FnZSwgJycpKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlUGFja2FnZSgkcGFja2FnZSk7CgogICAgICAgICAgICAkcGFja2FnZU1hcFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAkcGFja2FnZSwKICAgICAgICAgICAgICAgICRpbnN0YWxsYXRpb25NYW5hZ2VyLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSksCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2VNYXA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBUaHJvd3MgYW4gZXhjZXB0aW9uLCBpZiB0aGUgcGFja2FnZSBoYXMgaWxsZWdhbCBzZXR0aW5ncy4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRhdXRvbG9hZCA9ICRwYWNrYWdlLT5nZXRBdXRvbG9hZCgpOwogICAgICAgIGlmICghZW1wdHkoJGF1dG9sb2FkWydwc3ItNCddKSAmJiBudWxsICE9PSAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkpIHsKICAgICAgICAgICAgJG5hbWUgPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCk7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJQU1ItNCBhdXRvbG9hZGluZyBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgdGFyZ2V0LWRpciBwcm9wZXJ0eSwgcmVtb3ZlIHRoZSB0YXJnZXQtZGlyIGluIHBhY2thZ2UgJyRuYW1lJy4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlbXB0eSgkYXV0b2xvYWRbJ3Bzci00J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZFsncHNyLTQnXSBhcyAkbmFtZXNwYWNlID0+ICRkaXJzKSB7CiAgICAgICAgICAgICAgICBpZiAoJG5hbWVzcGFjZSAhPT0gJycgJiYgJ1xcJyAhPT0gc3Vic3RyKCRuYW1lc3BhY2UsIC0xKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJwc3ItNCBuYW1lc3BhY2VzIG11c3QgZW5kIHdpdGggYSBuYW1lc3BhY2Ugc2VwYXJhdG9yLCAnJG5hbWVzcGFjZScgZG9lcyBub3QsIHVzZSAnJG5hbWVzcGFjZVxcJy4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENvbXBpbGVzIGFuIG9yZGVyZWQgbGlzdCBvZiBuYW1lc3BhY2UgPT4gcGF0aCBtYXBwaW5ncwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+ICRwYWNrYWdlTWFwIGFycmF5IG9mIGFycmF5KHBhY2thZ2UsIGluc3RhbGxEaXItcmVsYXRpdmUtdG8tY29tcG9zZXIuanNvbikKICAgICAqIEBwYXJhbSBSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2Ugcm9vdCBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gYm9vbHxzdHJpbmdbXSAkZmlsdGVyZWREZXZQYWNrYWdlcyBJZiBhbiBhcnJheSwgdGhlIGxpc3Qgb2YgcGFja2FnZXMgdGhhdCBtdXN0IGJlIHJlbW92ZWQuIElmIGJvb2wsIHdoZXRoZXIgdG8gZmlsdGVyIG91dCByZXF1aXJlLWRldiBwYWNrYWdlcwogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5ewogICAgICogICAgICdwc3ItMCc6IGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nPj4sCiAgICAgKiAgICAgJ3Bzci00JzogYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmc+PiwKICAgICAqICAgICAnY2xhc3NtYXAnOiBhcnJheTxpbnQsIHN0cmluZz4sCiAgICAgKiAgICAgJ2ZpbGVzJzogYXJyYXk8c3RyaW5nLCBzdHJpbmc+LAogICAgICogICAgICdleGNsdWRlLWZyb20tY2xhc3NtYXAnOiBhcnJheTxpbnQsIHN0cmluZz4sCiAgICAgKiB9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUF1dG9sb2FkcyhhcnJheSAkcGFja2FnZU1hcCwgUGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UsICRmaWx0ZXJlZERldlBhY2thZ2VzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHJvb3RQYWNrYWdlTWFwID0gYXJyYXlfc2hpZnQoJHBhY2thZ2VNYXApOwogICAgICAgIGlmIChpc19hcnJheSgkZmlsdGVyZWREZXZQYWNrYWdlcykpIHsKICAgICAgICAgICAgJHBhY2thZ2VNYXAgPSBhcnJheV9maWx0ZXIoJHBhY2thZ2VNYXAsIGZ1bmN0aW9uICgkaXRlbSkgdXNlICgkZmlsdGVyZWREZXZQYWNrYWdlcykgewogICAgICAgICAgICAgICAgcmV0dXJuICFpbl9hcnJheSgkaXRlbVswXS0+Z2V0TmFtZSgpLCAkZmlsdGVyZWREZXZQYWNrYWdlcywgdHJ1ZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZWlmICgkZmlsdGVyZWREZXZQYWNrYWdlcykgewogICAgICAgICAgICAkcGFja2FnZU1hcCA9ICR0aGlzLT5maWx0ZXJQYWNrYWdlTWFwKCRwYWNrYWdlTWFwLCAkcm9vdFBhY2thZ2UpOwogICAgICAgIH0KICAgICAgICAkc29ydGVkUGFja2FnZU1hcCA9ICR0aGlzLT5zb3J0UGFja2FnZU1hcCgkcGFja2FnZU1hcCk7CiAgICAgICAgJHNvcnRlZFBhY2thZ2VNYXBbXSA9ICRyb290UGFja2FnZU1hcDsKICAgICAgICBhcnJheV91bnNoaWZ0KCRwYWNrYWdlTWFwLCAkcm9vdFBhY2thZ2VNYXApOwoKICAgICAgICAkcHNyMCA9ICR0aGlzLT5wYXJzZUF1dG9sb2Fkc1R5cGUoJHBhY2thZ2VNYXAsICdwc3ItMCcsICRyb290UGFja2FnZSk7CiAgICAgICAgJHBzcjQgPSAkdGhpcy0+cGFyc2VBdXRvbG9hZHNUeXBlKCRwYWNrYWdlTWFwLCAncHNyLTQnLCAkcm9vdFBhY2thZ2UpOwogICAgICAgICRjbGFzc21hcCA9ICR0aGlzLT5wYXJzZUF1dG9sb2Fkc1R5cGUoYXJyYXlfcmV2ZXJzZSgkc29ydGVkUGFja2FnZU1hcCksICdjbGFzc21hcCcsICRyb290UGFja2FnZSk7CiAgICAgICAgJGZpbGVzID0gJHRoaXMtPnBhcnNlQXV0b2xvYWRzVHlwZSgkc29ydGVkUGFja2FnZU1hcCwgJ2ZpbGVzJywgJHJvb3RQYWNrYWdlKTsKICAgICAgICAkZXhjbHVkZSA9ICR0aGlzLT5wYXJzZUF1dG9sb2Fkc1R5cGUoJHNvcnRlZFBhY2thZ2VNYXAsICdleGNsdWRlLWZyb20tY2xhc3NtYXAnLCAkcm9vdFBhY2thZ2UpOwoKICAgICAgICBrcnNvcnQoJHBzcjApOwogICAgICAgIGtyc29ydCgkcHNyNCk7CgogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3Bzci0wJyA9PiAkcHNyMCwKICAgICAgICAgICAgJ3Bzci00JyA9PiAkcHNyNCwKICAgICAgICAgICAgJ2NsYXNzbWFwJyA9PiAkY2xhc3NtYXAsCiAgICAgICAgICAgICdmaWxlcycgPT4gJGZpbGVzLAogICAgICAgICAgICAnZXhjbHVkZS1mcm9tLWNsYXNzbWFwJyA9PiAkZXhjbHVkZSwKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGFuIGF1dG9sb2FkZXIgYmFzZWQgb24gYW4gYXV0b2xvYWQtbWFwIHJldHVybmVkIGJ5IHBhcnNlQXV0b2xvYWRzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWRbXT4gJGF1dG9sb2FkcyBzZWUgcGFyc2VBdXRvbG9hZHMgcmV0dXJuIHZhbHVlCiAgICAgKiBAcGFyYW0gP3N0cmluZyAkdmVuZG9yRGlyCiAgICAgKiBAcmV0dXJuIENsYXNzTG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVMb2FkZXIoYXJyYXkgJGF1dG9sb2FkcywgJHZlbmRvckRpciA9IG51bGwpCiAgICB7CiAgICAgICAgJGxvYWRlciA9IG5ldyBDbGFzc0xvYWRlcigkdmVuZG9yRGlyKTsKCiAgICAgICAgaWYgKGlzc2V0KCRhdXRvbG9hZHNbJ3Bzci0wJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHNbJ3Bzci0wJ10gYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+YWRkKCRuYW1lc3BhY2UsICRwYXRoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRhdXRvbG9hZHNbJ3Bzci00J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHNbJ3Bzci00J10gYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+YWRkUHNyNCgkbmFtZXNwYWNlLCAkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkYXV0b2xvYWRzWydjbGFzc21hcCddKSkgewogICAgICAgICAgICAkZXhjbHVkZWQgPSBudWxsOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRhdXRvbG9hZHNbJ2V4Y2x1ZGUtZnJvbS1jbGFzc21hcCddKSkgewogICAgICAgICAgICAgICAgJGV4Y2x1ZGVkID0gJGF1dG9sb2Fkc1snZXhjbHVkZS1mcm9tLWNsYXNzbWFwJ107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzY2FubmVkRmlsZXMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkYXV0b2xvYWRzWydjbGFzc21hcCddIGFzICRkaXIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJGxvYWRlci0+YWRkQ2xhc3NNYXAoJHRoaXMtPmdlbmVyYXRlQ2xhc3NNYXAoJGRpciwgJGV4Y2x1ZGVkLCBudWxsLCBudWxsLCBmYWxzZSwgJHNjYW5uZWRGaWxlcykpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJGUtPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+ICRwYWNrYWdlTWFwCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yUGF0aENvZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFwcEJhc2VEaXJDb2RlCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEluY2x1ZGVQYXRoc0ZpbGUoYXJyYXkgJHBhY2thZ2VNYXAsIEZpbGVzeXN0ZW0gJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICR2ZW5kb3JQYXRoQ29kZSwgJGFwcEJhc2VEaXJDb2RlKQogICAgewogICAgICAgICRpbmNsdWRlUGF0aHMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU1hcCBhcyAkaXRlbSkgewogICAgICAgICAgICBsaXN0KCRwYWNrYWdlLCAkaW5zdGFsbFBhdGgpID0gJGl0ZW07CgogICAgICAgICAgICBpZiAobnVsbCAhPT0gJHBhY2thZ2UtPmdldFRhcmdldERpcigpICYmIHN0cmxlbigkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkpID4gMCkgewogICAgICAgICAgICAgICAgJGluc3RhbGxQYXRoID0gc3Vic3RyKCRpbnN0YWxsUGF0aCwgMCwgLXN0cmxlbignLycuJHBhY2thZ2UtPmdldFRhcmdldERpcigpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRJbmNsdWRlUGF0aHMoKSBhcyAkaW5jbHVkZVBhdGgpIHsKICAgICAgICAgICAgICAgICRpbmNsdWRlUGF0aCA9IHRyaW0oJGluY2x1ZGVQYXRoLCAnLycpOwogICAgICAgICAgICAgICAgJGluY2x1ZGVQYXRoc1tdID0gZW1wdHkoJGluc3RhbGxQYXRoKSA/ICRpbmNsdWRlUGF0aCA6ICRpbnN0YWxsUGF0aC4nLycuJGluY2x1ZGVQYXRoOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoISRpbmNsdWRlUGF0aHMpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkaW5jbHVkZVBhdGhzQ29kZSA9ICcnOwogICAgICAgIGZvcmVhY2ggKCRpbmNsdWRlUGF0aHMgYXMgJHBhdGgpIHsKICAgICAgICAgICAgJGluY2x1ZGVQYXRoc0NvZGUgLj0gIiAgICAiIC4gJHRoaXMtPmdldFBhdGhDb2RlKCRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkcGF0aCkgLiAiLFxuIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiA8PDxFT0YKPD9waHAKCi8vIGluY2x1ZGVfcGF0aHMucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKClwkdmVuZG9yRGlyID0gJHZlbmRvclBhdGhDb2RlOwpcJGJhc2VEaXIgPSAkYXBwQmFzZURpckNvZGU7CgpyZXR1cm4gYXJyYXkoCiRpbmNsdWRlUGF0aHNDb2RlKTsKCkVPRjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJGZpbGVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yUGF0aENvZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFwcEJhc2VEaXJDb2RlCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEluY2x1ZGVGaWxlc0ZpbGUoYXJyYXkgJGZpbGVzLCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkdmVuZG9yUGF0aENvZGUsICRhcHBCYXNlRGlyQ29kZSkKICAgIHsKICAgICAgICAkZmlsZXNDb2RlID0gJyc7CiAgICAgICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlSWRlbnRpZmllciA9PiAkZnVuY3Rpb25GaWxlKSB7CiAgICAgICAgICAgICRmaWxlc0NvZGUgLj0gJyAgICAnIC4gdmFyX2V4cG9ydCgkZmlsZUlkZW50aWZpZXIsIHRydWUpIC4gJyA9PiAnCiAgICAgICAgICAgICAgICAuICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJGZ1bmN0aW9uRmlsZSkgLiAiLFxuIjsKICAgICAgICB9CgogICAgICAgIGlmICghJGZpbGVzQ29kZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiA8PDxFT0YKPD9waHAKCi8vIGF1dG9sb2FkX2ZpbGVzLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpcJHZlbmRvckRpciA9ICR2ZW5kb3JQYXRoQ29kZTsKXCRiYXNlRGlyID0gJGFwcEJhc2VEaXJDb2RlOwoKcmV0dXJuIGFycmF5KAokZmlsZXNDb2RlKTsKCkVPRjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZW5kb3JQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGF0aENvZGUoRmlsZXN5c3RlbSAkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkZmlsZXN5c3RlbS0+aXNBYnNvbHV0ZVBhdGgoJHBhdGgpKSB7CiAgICAgICAgICAgICRwYXRoID0gJGJhc2VQYXRoIC4gJy8nIC4gJHBhdGg7CiAgICAgICAgfQogICAgICAgICRwYXRoID0gJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwoKICAgICAgICAkYmFzZURpciA9ICcnOwogICAgICAgIGlmIChzdHJwb3MoJHBhdGguJy8nLCAkdmVuZG9yUGF0aC4nLycpID09PSAwKSB7CiAgICAgICAgICAgICRwYXRoID0gc3Vic3RyKCRwYXRoLCBzdHJsZW4oJHZlbmRvclBhdGgpKTsKICAgICAgICAgICAgJGJhc2VEaXIgPSAnJHZlbmRvckRpcic7CgogICAgICAgICAgICBpZiAoJHBhdGggIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkYmFzZURpciAuPSAiIC4gIjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwYXRoID0gJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJGZpbGVzeXN0ZW0tPmZpbmRTaG9ydGVzdFBhdGgoJGJhc2VQYXRoLCAkcGF0aCwgdHJ1ZSkpOwogICAgICAgICAgICBpZiAoISRmaWxlc3lzdGVtLT5pc0Fic29sdXRlUGF0aCgkcGF0aCkpIHsKICAgICAgICAgICAgICAgICRiYXNlRGlyID0gJyRiYXNlRGlyIC4gJzsKICAgICAgICAgICAgICAgICRwYXRoID0gJy8nIC4gJHBhdGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJHBhdGgsICcucGhhcicpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkYmFzZURpciA9ICIncGhhcjovLycgLiAiIC4gJGJhc2VEaXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGJhc2VEaXIgLiB2YXJfZXhwb3J0KCRwYXRoLCB0cnVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+ICRwYWNrYWdlTWFwCiAgICAgKiBAcGFyYW0gYm9vbCAkY2hlY2tQbGF0Zm9ybQogICAgICogQHBhcmFtIHN0cmluZ1tdICRkZXZQYWNrYWdlTmFtZXMKICAgICAqIEByZXR1cm4gP3N0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGxhdGZvcm1DaGVjayhhcnJheSAkcGFja2FnZU1hcCwgJGNoZWNrUGxhdGZvcm0sIGFycmF5ICRkZXZQYWNrYWdlTmFtZXMpCiAgICB7CiAgICAgICAgJGxvd2VzdFBocFZlcnNpb24gPSBCb3VuZDo6emVybygpOwogICAgICAgICRyZXF1aXJlZEV4dGVuc2lvbnMgPSBhcnJheSgpOwogICAgICAgICRleHRlbnNpb25Qcm92aWRlcnMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU1hcCBhcyAkaXRlbSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRpdGVtWzBdOwogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSwgJHBhY2thZ2UtPmdldFByb3ZpZGVzKCkpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15leHQtKC4rKSR9aUQnLCAkbGluay0+Z2V0VGFyZ2V0KCksICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkZXh0ZW5zaW9uUHJvdmlkZXJzWyRtYXRjaFsxXV1bXSA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTWFwIGFzICRpdGVtKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJGl0ZW1bMF07CiAgICAgICAgICAgIC8vIHNraXAgZGV2IGRlcGVuZGVuY2llcyBwbGF0Zm9ybSByZXF1aXJlbWVudHMgYXMgcGxhdGZvcm0tY2hlY2sgcmVhbGx5IHNob3VsZCBvbmx5IGJlIGEgcHJvZHVjdGlvbiBzYWZlZ3VhcmQKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRkZXZQYWNrYWdlTmFtZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlci0+aXNJZ25vcmVkKCRsaW5rLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJ3BocCcgPT09ICRsaW5rLT5nZXRUYXJnZXQoKSkgewogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJGxpbmstPmdldENvbnN0cmFpbnQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQtPmdldExvd2VyQm91bmQoKS0+Y29tcGFyZVRvKCRsb3dlc3RQaHBWZXJzaW9uLCAnPicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRsb3dlc3RQaHBWZXJzaW9uID0gJGNvbnN0cmFpbnQtPmdldExvd2VyQm91bmQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRjaGVja1BsYXRmb3JtID09PSB0cnVlICYmIFByZWc6OmlzTWF0Y2goJ3teZXh0LSguKykkfWlEJywgJGxpbmstPmdldFRhcmdldCgpLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBleHRlbnNpb24gY2hlY2tzIGlmIHRoZXkgaGF2ZSBhIHZhbGlkIHByb3ZpZGVyL3JlcGxhY2VyCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRleHRlbnNpb25Qcm92aWRlcnNbJG1hdGNoWzFdXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGV4dGVuc2lvblByb3ZpZGVyc1skbWF0Y2hbMV1dIGFzICRwcm92aWRlZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwcm92aWRlZC0+bWF0Y2hlcygkbGluay0+Z2V0Q29uc3RyYWludCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkbWF0Y2hbMV0gPT09ICd6ZW5kLW9wY2FjaGUnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaFsxXSA9ICd6ZW5kIG9wY2FjaGUnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGV4dGVuc2lvbiA9IHZhcl9leHBvcnQoJG1hdGNoWzFdLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJG1hdGNoWzFdID09PSAncGNudGwnIHx8ICRtYXRjaFsxXSA9PT0gJ3JlYWRsaW5lJykgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZWRFeHRlbnNpb25zWyRleHRlbnNpb25dID0gIlBIUF9TQVBJICE9PSAnY2xpJyB8fCBleHRlbnNpb25fbG9hZGVkKCRleHRlbnNpb24pIHx8IFwkbWlzc2luZ0V4dGVuc2lvbnNbXSA9ICRleHRlbnNpb247XG4iOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXF1aXJlZEV4dGVuc2lvbnNbJGV4dGVuc2lvbl0gPSAiZXh0ZW5zaW9uX2xvYWRlZCgkZXh0ZW5zaW9uKSB8fCBcJG1pc3NpbmdFeHRlbnNpb25zW10gPSAkZXh0ZW5zaW9uO1xuIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGtzb3J0KCRyZXF1aXJlZEV4dGVuc2lvbnMpOwoKICAgICAgICAkZm9ybWF0VG9QaHBWZXJzaW9uSWQgPSBmdW5jdGlvbiAoQm91bmQgJGJvdW5kKSB7CiAgICAgICAgICAgIGlmICgkYm91bmQtPmlzWmVybygpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRib3VuZC0+aXNQb3NpdGl2ZUluZmluaXR5KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiA5OTk5OTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZlcnNpb24gPSBzdHJfcmVwbGFjZSgnLScsICcuJywgJGJvdW5kLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICAkY2h1bmtzID0gYXJyYXlfbWFwKCdpbnR2YWwnLCBleHBsb2RlKCcuJywgJHZlcnNpb24pKTsKCiAgICAgICAgICAgIHJldHVybiAkY2h1bmtzWzBdICogMTAwMDAgKyAkY2h1bmtzWzFdICogMTAwICsgJGNodW5rc1syXTsKICAgICAgICB9OwoKICAgICAgICAkZm9ybWF0VG9IdW1hblJlYWRhYmxlID0gZnVuY3Rpb24gKEJvdW5kICRib3VuZCkgewogICAgICAgICAgICBpZiAoJGJvdW5kLT5pc1plcm8oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkYm91bmQtPmlzUG9zaXRpdmVJbmZpbml0eSgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gOTk5OTk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2ZXJzaW9uID0gc3RyX3JlcGxhY2UoJy0nLCAnLicsICRib3VuZC0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgJGNodW5rcyA9IGV4cGxvZGUoJy4nLCAkdmVyc2lvbik7CiAgICAgICAgICAgICRjaHVua3MgPSBhcnJheV9zbGljZSgkY2h1bmtzLCAwLCAzKTsKCiAgICAgICAgICAgIHJldHVybiBpbXBsb2RlKCcuJywgJGNodW5rcyk7CiAgICAgICAgfTsKCiAgICAgICAgJHJlcXVpcmVkUGhwID0gJyc7CiAgICAgICAgJHJlcXVpcmVkUGhwRXJyb3IgPSAnJzsKICAgICAgICBpZiAoISRsb3dlc3RQaHBWZXJzaW9uLT5pc1plcm8oKSkgewogICAgICAgICAgICAkb3BlcmF0b3IgPSAkbG93ZXN0UGhwVmVyc2lvbi0+aXNJbmNsdXNpdmUoKSA/ICc+PScgOiAnPic7CiAgICAgICAgICAgICRyZXF1aXJlZFBocCA9ICdQSFBfVkVSU0lPTl9JRCAnLiRvcGVyYXRvci4nICcuJGZvcm1hdFRvUGhwVmVyc2lvbklkKCRsb3dlc3RQaHBWZXJzaW9uKTsKICAgICAgICAgICAgJHJlcXVpcmVkUGhwRXJyb3IgPSAnIicuJG9wZXJhdG9yLicgJy4kZm9ybWF0VG9IdW1hblJlYWRhYmxlKCRsb3dlc3RQaHBWZXJzaW9uKS4nIic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlcXVpcmVkUGhwKSB7CiAgICAgICAgICAgICRyZXF1aXJlZFBocCA9IDw8PFBIUF9DSEVDSwoKaWYgKCEoJHJlcXVpcmVkUGhwKSkgewogICAgXCRpc3N1ZXNbXSA9ICdZb3VyIENvbXBvc2VyIGRlcGVuZGVuY2llcyByZXF1aXJlIGEgUEhQIHZlcnNpb24gJHJlcXVpcmVkUGhwRXJyb3IuIFlvdSBhcmUgcnVubmluZyAnIC4gUEhQX1ZFUlNJT04gLiAnLic7Cn0KClBIUF9DSEVDSzsKICAgICAgICB9CgogICAgICAgICRyZXF1aXJlZEV4dGVuc2lvbnMgPSBpbXBsb2RlKCcnLCAkcmVxdWlyZWRFeHRlbnNpb25zKTsKICAgICAgICBpZiAoJycgIT09ICRyZXF1aXJlZEV4dGVuc2lvbnMpIHsKICAgICAgICAgICAgJHJlcXVpcmVkRXh0ZW5zaW9ucyA9IDw8PEVYVF9DSEVDS1MKClwkbWlzc2luZ0V4dGVuc2lvbnMgPSBhcnJheSgpOwokcmVxdWlyZWRFeHRlbnNpb25zCmlmIChcJG1pc3NpbmdFeHRlbnNpb25zKSB7CiAgICBcJGlzc3Vlc1tdID0gJ1lvdXIgQ29tcG9zZXIgZGVwZW5kZW5jaWVzIHJlcXVpcmUgdGhlIGZvbGxvd2luZyBQSFAgZXh0ZW5zaW9ucyB0byBiZSBpbnN0YWxsZWQ6ICcgLiBpbXBsb2RlKCcsICcsIFwkbWlzc2luZ0V4dGVuc2lvbnMpIC4gJy4nOwp9CgpFWFRfQ0hFQ0tTOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkcmVxdWlyZWRQaHAgJiYgISRyZXF1aXJlZEV4dGVuc2lvbnMpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gPDw8UExBVEZPUk1fQ0hFQ0sKPD9waHAKCi8vIHBsYXRmb3JtX2NoZWNrLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpcJGlzc3VlcyA9IGFycmF5KCk7CiR7cmVxdWlyZWRQaHB9JHtyZXF1aXJlZEV4dGVuc2lvbnN9CmlmIChcJGlzc3VlcykgewogICAgaWYgKCFoZWFkZXJzX3NlbnQoKSkgewogICAgICAgIGhlYWRlcignSFRUUC8xLjEgNTAwIEludGVybmFsIFNlcnZlciBFcnJvcicpOwogICAgfQogICAgaWYgKCFpbmlfZ2V0KCdkaXNwbGF5X2Vycm9ycycpKSB7CiAgICAgICAgaWYgKFBIUF9TQVBJID09PSAnY2xpJyB8fCBQSFBfU0FQSSA9PT0gJ3BocGRiZycpIHsKICAgICAgICAgICAgZndyaXRlKFNUREVSUiwgJ0NvbXBvc2VyIGRldGVjdGVkIGlzc3VlcyBpbiB5b3VyIHBsYXRmb3JtOicgLiBQSFBfRU9MLlBIUF9FT0wgLiBpbXBsb2RlKFBIUF9FT0wsIFwkaXNzdWVzKSAuIFBIUF9FT0wuUEhQX0VPTCk7CiAgICAgICAgfSBlbHNlaWYgKCFoZWFkZXJzX3NlbnQoKSkgewogICAgICAgICAgICBlY2hvICdDb21wb3NlciBkZXRlY3RlZCBpc3N1ZXMgaW4geW91ciBwbGF0Zm9ybTonIC4gUEhQX0VPTC5QSFBfRU9MIC4gc3RyX3JlcGxhY2UoJ1lvdSBhcmUgcnVubmluZyAnLlBIUF9WRVJTSU9OLicuJywgJycsIGltcGxvZGUoUEhQX0VPTCwgXCRpc3N1ZXMpKSAuIFBIUF9FT0wuUEhQX0VPTDsKICAgICAgICB9CiAgICB9CiAgICB0cmlnZ2VyX2Vycm9yKAogICAgICAgICdDb21wb3NlciBkZXRlY3RlZCBpc3N1ZXMgaW4geW91ciBwbGF0Zm9ybTogJyAuIGltcGxvZGUoJyAnLCBcJGlzc3VlcyksCiAgICAgICAgRV9VU0VSX0VSUk9SCiAgICApOwp9CgpQTEFURk9STV9DSEVDSzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkc3VmZml4CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0QXV0b2xvYWRGaWxlKCR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlLCAkc3VmZml4KQogICAgewogICAgICAgICRsYXN0Q2hhciA9ICR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlW3N0cmxlbigkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZSkgLSAxXTsKICAgICAgICBpZiAoIiciID09PSAkbGFzdENoYXIgfHwgJyInID09PSAkbGFzdENoYXIpIHsKICAgICAgICAgICAgJHZlbmRvclBhdGhUb1RhcmdldERpckNvZGUgPSBzdWJzdHIoJHZlbmRvclBhdGhUb1RhcmdldERpckNvZGUsIDAsIC0xKS4nL2F1dG9sb2FkX3JlYWwucGhwJy4kbGFzdENoYXI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHZlbmRvclBhdGhUb1RhcmdldERpckNvZGUgLj0gIiAuICcvYXV0b2xvYWRfcmVhbC5waHAnIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiA8PDxBVVRPTE9BRAo8P3BocAoKLy8gYXV0b2xvYWQucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKCnJlcXVpcmVfb25jZSAkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZTsKCnJldHVybiBDb21wb3NlckF1dG9sb2FkZXJJbml0JHN1ZmZpeDo6Z2V0TG9hZGVyKCk7CgpBVVRPTE9BRDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICR1c2VDbGFzc01hcAogICAgICogQHBhcmFtIGJvb2wgJHVzZUluY2x1ZGVQYXRoCiAgICAgKiBAcGFyYW0gP3N0cmluZyAkdGFyZ2V0RGlyTG9hZGVyCiAgICAgKiBAcGFyYW0gYm9vbCAkdXNlSW5jbHVkZUZpbGVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZW5kb3JQYXRoQ29kZSB1bnVzZWQgaW4gdGhpcyBtZXRob2QKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFwcEJhc2VEaXJDb2RlIHVudXNlZCBpbiB0aGlzIG1ldGhvZAogICAgICogQHBhcmFtIHN0cmluZyAkc3VmZml4CiAgICAgKiBAcGFyYW0gYm9vbCAkdXNlR2xvYmFsSW5jbHVkZVBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZXBlbmRBdXRvbG9hZGVyICd0cnVlJ3wnZmFsc2UnCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGF0aWNQaHBWZXJzaW9uCiAgICAgKiBAcGFyYW0gYm9vbCAkY2hlY2tQbGF0Zm9ybQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEF1dG9sb2FkUmVhbEZpbGUoJHVzZUNsYXNzTWFwLCAkdXNlSW5jbHVkZVBhdGgsICR0YXJnZXREaXJMb2FkZXIsICR1c2VJbmNsdWRlRmlsZXMsICR2ZW5kb3JQYXRoQ29kZSwgJGFwcEJhc2VEaXJDb2RlLCAkc3VmZml4LCAkdXNlR2xvYmFsSW5jbHVkZVBhdGgsICRwcmVwZW5kQXV0b2xvYWRlciwgJHN0YXRpY1BocFZlcnNpb24sICRjaGVja1BsYXRmb3JtKQogICAgewogICAgICAgICRmaWxlID0gPDw8SEVBREVSCjw/cGhwCgovLyBhdXRvbG9hZF9yZWFsLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpjbGFzcyBDb21wb3NlckF1dG9sb2FkZXJJbml0JHN1ZmZpeAp7CiAgICBwcml2YXRlIHN0YXRpYyBcJGxvYWRlcjsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvYWRDbGFzc0xvYWRlcihcJGNsYXNzKQogICAgewogICAgICAgIGlmICgnQ29tcG9zZXJcXEF1dG9sb2FkXFxDbGFzc0xvYWRlcicgPT09IFwkY2xhc3MpIHsKICAgICAgICAgICAgcmVxdWlyZSBfX0RJUl9fIC4gJy9DbGFzc0xvYWRlci5waHAnOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0TG9hZGVyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gc2VsZjo6XCRsb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OlwkbG9hZGVyOwogICAgICAgIH0KCgpIRUFERVI7CgogICAgICAgIGlmICgkY2hlY2tQbGF0Zm9ybSkgewogICAgICAgICAgICAkZmlsZSAuPSA8PDwnUExBVEZPUk1fQ0hFQ0snCiAgICAgICAgcmVxdWlyZSBfX0RJUl9fIC4gJy9wbGF0Zm9ybV9jaGVjay5waHAnOwoKClBMQVRGT1JNX0NIRUNLOwogICAgICAgIH0KCiAgICAgICAgJGZpbGUgLj0gPDw8Q0xBU1NMT0FERVJfSU5JVAogICAgICAgIHNwbF9hdXRvbG9hZF9yZWdpc3RlcihhcnJheSgnQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXgnLCAnbG9hZENsYXNzTG9hZGVyJyksIHRydWUsICRwcmVwZW5kQXV0b2xvYWRlcik7CiAgICAgICAgc2VsZjo6XCRsb2FkZXIgPSBcJGxvYWRlciA9IG5ldyBcXENvbXBvc2VyXFxBdXRvbG9hZFxcQ2xhc3NMb2FkZXIoXFxkaXJuYW1lKFxcZGlybmFtZShfX0ZJTEVfXykpKTsKICAgICAgICBzcGxfYXV0b2xvYWRfdW5yZWdpc3RlcihhcnJheSgnQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXgnLCAnbG9hZENsYXNzTG9hZGVyJykpOwoKCkNMQVNTTE9BREVSX0lOSVQ7CgogICAgICAgIGlmICgkdXNlSW5jbHVkZVBhdGgpIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8J0lOQ0xVREVfUEFUSCcKICAgICAgICAkaW5jbHVkZVBhdGhzID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9pbmNsdWRlX3BhdGhzLnBocCc7CiAgICAgICAgJGluY2x1ZGVQYXRoc1tdID0gZ2V0X2luY2x1ZGVfcGF0aCgpOwogICAgICAgIHNldF9pbmNsdWRlX3BhdGgoaW1wbG9kZShQQVRIX1NFUEFSQVRPUiwgJGluY2x1ZGVQYXRocykpOwoKCklOQ0xVREVfUEFUSDsKICAgICAgICB9CgogICAgICAgICRmaWxlIC49IDw8PFNUQVRJQ19JTklUCiAgICAgICAgXCR1c2VTdGF0aWNMb2FkZXIgPSBQSFBfVkVSU0lPTl9JRCA+PSAkc3RhdGljUGhwVmVyc2lvbiAmJiAhZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykgJiYgKCFmdW5jdGlvbl9leGlzdHMoJ3plbmRfbG9hZGVyX2ZpbGVfZW5jb2RlZCcpIHx8ICF6ZW5kX2xvYWRlcl9maWxlX2VuY29kZWQoKSk7CiAgICAgICAgaWYgKFwkdXNlU3RhdGljTG9hZGVyKSB7CiAgICAgICAgICAgIHJlcXVpcmUgX19ESVJfXyAuICcvYXV0b2xvYWRfc3RhdGljLnBocCc7CgogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYyhcQ29tcG9zZXJcQXV0b2xvYWRcQ29tcG9zZXJTdGF0aWNJbml0JHN1ZmZpeDo6Z2V0SW5pdGlhbGl6ZXIoXCRsb2FkZXIpKTsKICAgICAgICB9IGVsc2UgewoKU1RBVElDX0lOSVQ7CgogICAgICAgIGlmICghJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkgewogICAgICAgICAgICAkZmlsZSAuPSA8PDwnUFNSMDQnCiAgICAgICAgICAgICRtYXAgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX25hbWVzcGFjZXMucGhwJzsKICAgICAgICAgICAgZm9yZWFjaCAoJG1hcCBhcyAkbmFtZXNwYWNlID0+ICRwYXRoKSB7CiAgICAgICAgICAgICAgICAkbG9hZGVyLT5zZXQoJG5hbWVzcGFjZSwgJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWFwID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9hdXRvbG9hZF9wc3I0LnBocCc7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtYXAgYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+c2V0UHNyNCgkbmFtZXNwYWNlLCAkcGF0aCk7CiAgICAgICAgICAgIH0KCgpQU1IwNDsKICAgICAgICB9CgogICAgICAgIGlmICgkdXNlQ2xhc3NNYXApIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8J0NMQVNTTUFQJwogICAgICAgICAgICAkY2xhc3NNYXAgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX2NsYXNzbWFwLnBocCc7CiAgICAgICAgICAgIGlmICgkY2xhc3NNYXApIHsKICAgICAgICAgICAgICAgICRsb2FkZXItPmFkZENsYXNzTWFwKCRjbGFzc01hcCk7CiAgICAgICAgICAgIH0KCkNMQVNTTUFQOwogICAgICAgIH0KCiAgICAgICAgJGZpbGUgLj0gIiAgICAgICAgfVxuXG4iOwoKICAgICAgICBpZiAoJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkgewogICAgICAgICAgICAkZmlsZSAuPSA8PDwnQ0xBU1NNQVBBVVRIT1JJVEFUSVZFJwogICAgICAgICRsb2FkZXItPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSh0cnVlKTsKCkNMQVNTTUFQQVVUSE9SSVRBVElWRTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+YXBjdSkgewogICAgICAgICAgICAkYXBjdVByZWZpeCA9IHZhcl9leHBvcnQoKCR0aGlzLT5hcGN1UHJlZml4ICE9PSBudWxsID8gJHRoaXMtPmFwY3VQcmVmaXggOiBzdWJzdHIoYmFzZTY0X2VuY29kZShtZDUodW5pcWlkKCcnLCB0cnVlKSwgdHJ1ZSkpLCAwLCAtMykpLCB0cnVlKTsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8QVBDVQogICAgICAgIFwkbG9hZGVyLT5zZXRBcGN1UHJlZml4KCRhcGN1UHJlZml4KTsKCkFQQ1U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHVzZUdsb2JhbEluY2x1ZGVQYXRoKSB7CiAgICAgICAgICAgICRmaWxlIC49IDw8PCdJTkNMVURFUEFUSCcKICAgICAgICAkbG9hZGVyLT5zZXRVc2VJbmNsdWRlUGF0aCh0cnVlKTsKCklOQ0xVREVQQVRIOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0YXJnZXREaXJMb2FkZXIpIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8UkVHSVNURVJfVEFSR0VUX0RJUl9BVVRPTE9BRAogICAgICAgIHNwbF9hdXRvbG9hZF9yZWdpc3RlcihhcnJheSgnQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXgnLCAnYXV0b2xvYWQnKSwgdHJ1ZSwgdHJ1ZSk7CgoKUkVHSVNURVJfVEFSR0VUX0RJUl9BVVRPTE9BRDsKICAgICAgICB9CgogICAgICAgICRmaWxlIC49IDw8PFJFR0lTVEVSX0xPQURFUgogICAgICAgIFwkbG9hZGVyLT5yZWdpc3RlcigkcHJlcGVuZEF1dG9sb2FkZXIpOwoKClJFR0lTVEVSX0xPQURFUjsKCiAgICAgICAgaWYgKCR1c2VJbmNsdWRlRmlsZXMpIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8SU5DTFVERV9GSUxFUwogICAgICAgIGlmIChcJHVzZVN0YXRpY0xvYWRlcikgewogICAgICAgICAgICBcJGluY2x1ZGVGaWxlcyA9IENvbXBvc2VyXEF1dG9sb2FkXENvbXBvc2VyU3RhdGljSW5pdCRzdWZmaXg6OlwkZmlsZXM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgXCRpbmNsdWRlRmlsZXMgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX2ZpbGVzLnBocCc7CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKFwkaW5jbHVkZUZpbGVzIGFzIFwkZmlsZUlkZW50aWZpZXIgPT4gXCRmaWxlKSB7CiAgICAgICAgICAgIGNvbXBvc2VyUmVxdWlyZSRzdWZmaXgoXCRmaWxlSWRlbnRpZmllciwgXCRmaWxlKTsKICAgICAgICB9CgoKSU5DTFVERV9GSUxFUzsKICAgICAgICB9CgogICAgICAgICRmaWxlIC49IDw8PE1FVEhPRF9GT09URVIKICAgICAgICByZXR1cm4gXCRsb2FkZXI7CiAgICB9CgpNRVRIT0RfRk9PVEVSOwoKICAgICAgICAkZmlsZSAuPSAkdGFyZ2V0RGlyTG9hZGVyOwoKICAgICAgICBpZiAoJHVzZUluY2x1ZGVGaWxlcykgewogICAgICAgICAgICByZXR1cm4gJGZpbGUgLiA8PDxGT09URVIKfQoKLyoqCiAqIEBwYXJhbSBzdHJpbmcgXCRmaWxlSWRlbnRpZmllcgogKiBAcGFyYW0gc3RyaW5nIFwkZmlsZQogKiBAcmV0dXJuIHZvaWQKICovCmZ1bmN0aW9uIGNvbXBvc2VyUmVxdWlyZSRzdWZmaXgoXCRmaWxlSWRlbnRpZmllciwgXCRmaWxlKQp7CiAgICBpZiAoZW1wdHkoXCRHTE9CQUxTWydfX2NvbXBvc2VyX2F1dG9sb2FkX2ZpbGVzJ11bXCRmaWxlSWRlbnRpZmllcl0pKSB7CiAgICAgICAgXCRHTE9CQUxTWydfX2NvbXBvc2VyX2F1dG9sb2FkX2ZpbGVzJ11bXCRmaWxlSWRlbnRpZmllcl0gPSB0cnVlOwoKICAgICAgICByZXF1aXJlIFwkZmlsZTsKICAgIH0KfQoKRk9PVEVSOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaWxlIC4gPDw8Rk9PVEVSCn0KCkZPT1RFUjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1ZmZpeAogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0RGlyCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZW5kb3JQYXRoIGlucHV0IGZvciBmaW5kU2hvcnRlc3RQYXRoQ29kZQogICAgICogQHBhcmFtIHN0cmluZyAkYmFzZVBhdGggaW5wdXQgZm9yIGZpbmRTaG9ydGVzdFBhdGhDb2RlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGF0aWNQaHBWZXJzaW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0U3RhdGljRmlsZSgkc3VmZml4LCAkdGFyZ2V0RGlyLCAkdmVuZG9yUGF0aCwgJGJhc2VQYXRoLCAmJHN0YXRpY1BocFZlcnNpb24pCiAgICB7CiAgICAgICAgJHN0YXRpY1BocFZlcnNpb24gPSA1MDYwMDsKCiAgICAgICAgJGZpbGUgPSA8PDxIRUFERVIKPD9waHAKCi8vIGF1dG9sb2FkX3N0YXRpYy5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKbmFtZXNwYWNlIENvbXBvc2VyXEF1dG9sb2FkOwoKY2xhc3MgQ29tcG9zZXJTdGF0aWNJbml0JHN1ZmZpeAp7CgpIRUFERVI7CgogICAgICAgICRsb2FkZXIgPSBuZXcgQ2xhc3NMb2FkZXIoKTsKCiAgICAgICAgJG1hcCA9IHJlcXVpcmUgJHRhcmdldERpciAuICcvYXV0b2xvYWRfbmFtZXNwYWNlcy5waHAnOwogICAgICAgIGZvcmVhY2ggKCRtYXAgYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAkbG9hZGVyLT5zZXQoJG5hbWVzcGFjZSwgJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJG1hcCA9IHJlcXVpcmUgJHRhcmdldERpciAuICcvYXV0b2xvYWRfcHNyNC5waHAnOwogICAgICAgIGZvcmVhY2ggKCRtYXAgYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAkbG9hZGVyLT5zZXRQc3I0KCRuYW1lc3BhY2UsICRwYXRoKTsKICAgICAgICB9CgogICAgICAgICRjbGFzc01hcCA9IHJlcXVpcmUgJHRhcmdldERpciAuICcvYXV0b2xvYWRfY2xhc3NtYXAucGhwJzsKICAgICAgICBpZiAoJGNsYXNzTWFwKSB7CiAgICAgICAgICAgICRsb2FkZXItPmFkZENsYXNzTWFwKCRjbGFzc01hcCk7CiAgICAgICAgfQoKICAgICAgICAkZmlsZXN5c3RlbSA9IG5ldyBGaWxlc3lzdGVtKCk7CgogICAgICAgICR2ZW5kb3JQYXRoQ29kZSA9ICcgPT4gJyAuICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZShyZWFscGF0aCgkdGFyZ2V0RGlyKSwgJHZlbmRvclBhdGgsIHRydWUsIHRydWUpIC4gIiAuICcvIjsKICAgICAgICAkdmVuZG9yUGhhclBhdGhDb2RlID0gJyA9PiBcJ3BoYXI6Ly9cJyAuICcgLiAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUocmVhbHBhdGgoJHRhcmdldERpciksICR2ZW5kb3JQYXRoLCB0cnVlLCB0cnVlKSAuICIgLiAnLyI7CiAgICAgICAgJGFwcEJhc2VEaXJDb2RlID0gJyA9PiAnIC4gJGZpbGVzeXN0ZW0tPmZpbmRTaG9ydGVzdFBhdGhDb2RlKHJlYWxwYXRoKCR0YXJnZXREaXIpLCAkYmFzZVBhdGgsIHRydWUsIHRydWUpIC4gIiAuICcvIjsKICAgICAgICAkYXBwQmFzZURpclBoYXJDb2RlID0gJyA9PiBcJ3BoYXI6Ly9cJyAuICcgLiAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUocmVhbHBhdGgoJHRhcmdldERpciksICRiYXNlUGF0aCwgdHJ1ZSwgdHJ1ZSkgLiAiIC4gJy8iOwoKICAgICAgICAkYWJzb2x1dGVWZW5kb3JQYXRoQ29kZSA9ICcgPT4gJyAuIHN1YnN0cih2YXJfZXhwb3J0KHJ0cmltKCR2ZW5kb3JEaXIsICdcXC8nKSAuICcvJywgdHJ1ZSksIDAsIC0xKTsKICAgICAgICAkYWJzb2x1dGVWZW5kb3JQaGFyUGF0aENvZGUgPSAnID0+ICcgLiBzdWJzdHIodmFyX2V4cG9ydChydHJpbSgncGhhcjovLycgLiAkdmVuZG9yRGlyLCAnXFwvJykgLiAnLycsIHRydWUpLCAwLCAtMSk7CiAgICAgICAgJGFic29sdXRlQXBwQmFzZURpckNvZGUgPSAnID0+ICcgLiBzdWJzdHIodmFyX2V4cG9ydChydHJpbSgkYmFzZURpciwgJ1xcLycpIC4gJy8nLCB0cnVlKSwgMCwgLTEpOwogICAgICAgICRhYnNvbHV0ZUFwcEJhc2VEaXJQaGFyQ29kZSA9ICcgPT4gJyAuIHN1YnN0cih2YXJfZXhwb3J0KHJ0cmltKCdwaGFyOi8vJyAuICRiYXNlRGlyLCAnXFwvJykgLiAnLycsIHRydWUpLCAwLCAtMSk7CgogICAgICAgICRpbml0aWFsaXplciA9ICcnOwogICAgICAgICRwcmVmaXggPSAiXDBDb21wb3NlclxBdXRvbG9hZFxDbGFzc0xvYWRlclwwIjsKICAgICAgICAkcHJlZml4TGVuID0gc3RybGVuKCRwcmVmaXgpOwogICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGFyZ2V0RGlyIC4gJy9hdXRvbG9hZF9maWxlcy5waHAnKSkgewogICAgICAgICAgICAkbWFwcyA9IGFycmF5KCdmaWxlcycgPT4gcmVxdWlyZSAkdGFyZ2V0RGlyIC4gJy9hdXRvbG9hZF9maWxlcy5waHAnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbWFwcyA9IGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgoYXJyYXkpICRsb2FkZXIgYXMgJHByb3AgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmICgkdmFsdWUgJiYgMCA9PT0gc3RycG9zKCRwcm9wLCAkcHJlZml4KSkgewogICAgICAgICAgICAgICAgJG1hcHNbc3Vic3RyKCRwcm9wLCAkcHJlZml4TGVuKV0gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRtYXBzIGFzICRwcm9wID0+ICR2YWx1ZSkgewogICAgICAgICAgICBpZiAoY291bnQoJHZhbHVlKSA+IDMyNzY3KSB7CiAgICAgICAgICAgICAgICAvLyBTdGF0aWMgYXJyYXlzIGFyZSBsaW1pdGVkIHRvIDMyNzY3IHZhbHVlcyBvbiBQSFAgNS42CiAgICAgICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvNjgwNTcKICAgICAgICAgICAgICAgICRzdGF0aWNQaHBWZXJzaW9uID0gNzAwMDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZhbHVlID0gc3RydHIoCiAgICAgICAgICAgICAgICB2YXJfZXhwb3J0KCR2YWx1ZSwgdHJ1ZSksCiAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICAkYWJzb2x1dGVWZW5kb3JQYXRoQ29kZSA9PiAkdmVuZG9yUGF0aENvZGUsCiAgICAgICAgICAgICAgICAgICAgJGFic29sdXRlVmVuZG9yUGhhclBhdGhDb2RlID0+ICR2ZW5kb3JQaGFyUGF0aENvZGUsCiAgICAgICAgICAgICAgICAgICAgJGFic29sdXRlQXBwQmFzZURpckNvZGUgPT4gJGFwcEJhc2VEaXJDb2RlLAogICAgICAgICAgICAgICAgICAgICRhYnNvbHV0ZUFwcEJhc2VEaXJQaGFyQ29kZSA9PiAkYXBwQmFzZURpclBoYXJDb2RlLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgICAgICAkdmFsdWUgPSBsdHJpbShQcmVnOjpyZXBsYWNlKCcvXiAqL20nLCAnICAgICQwJDAnLCAkdmFsdWUpKTsKCiAgICAgICAgICAgICRmaWxlIC49IHNwcmludGYoIiAgICBwdWJsaWMgc3RhdGljICQlcyA9ICVzO1xuXG4iLCAkcHJvcCwgJHZhbHVlKTsKICAgICAgICAgICAgaWYgKCdmaWxlcycgIT09ICRwcm9wKSB7CiAgICAgICAgICAgICAgICAkaW5pdGlhbGl6ZXIgLj0gIiAgICAgICAgICAgIFwkbG9hZGVyLT4kcHJvcCA9IENvbXBvc2VyU3RhdGljSW5pdCRzdWZmaXg6OlwkJHByb3A7XG4iOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGUgLiA8PDxJTklUSUFMSVpFUgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRJbml0aWFsaXplcihDbGFzc0xvYWRlciBcJGxvYWRlcikKICAgIHsKICAgICAgICByZXR1cm4gXENsb3N1cmU6OmJpbmQoZnVuY3Rpb24gKCkgdXNlIChcJGxvYWRlcikgewokaW5pdGlhbGl6ZXIKICAgICAgICB9LCBudWxsLCBDbGFzc0xvYWRlcjo6Y2xhc3MpOwogICAgfQp9CgpJTklUSUFMSVpFUjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+ICRwYWNrYWdlTWFwCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIG9uZSBvZjogJ3Bzci0wJ3wncHNyLTQnfCdjbGFzc21hcCd8J2ZpbGVzJwogICAgICogQHJldHVybiBhcnJheTxpbnQsIHN0cmluZz58YXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmc+PnxhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQXV0b2xvYWRzVHlwZShhcnJheSAkcGFja2FnZU1hcCwgJHR5cGUsIFJvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZSkKICAgIHsKICAgICAgICAkYXV0b2xvYWRzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VNYXAgYXMgJGl0ZW0pIHsKICAgICAgICAgICAgbGlzdCgkcGFja2FnZSwgJGluc3RhbGxQYXRoKSA9ICRpdGVtOwoKICAgICAgICAgICAgJGF1dG9sb2FkID0gJHBhY2thZ2UtPmdldEF1dG9sb2FkKCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGV2TW9kZSAmJiAkcGFja2FnZSA9PT0gJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkYXV0b2xvYWQgPSBhcnJheV9tZXJnZV9yZWN1cnNpdmUoJGF1dG9sb2FkLCAkcGFja2FnZS0+Z2V0RGV2QXV0b2xvYWQoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNraXAgbWlzY29uZmlndXJlZCBwYWNrYWdlcwogICAgICAgICAgICBpZiAoIWlzc2V0KCRhdXRvbG9hZFskdHlwZV0pIHx8ICFpc19hcnJheSgkYXV0b2xvYWRbJHR5cGVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bGwgIT09ICRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKSAmJiAkcGFja2FnZSAhPT0gJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkaW5zdGFsbFBhdGggPSBzdWJzdHIoJGluc3RhbGxQYXRoLCAwLCAtc3RybGVuKCcvJy4kcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2FkWyR0eXBlXSBhcyAkbmFtZXNwYWNlID0+ICRwYXRocykgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoKGFycmF5KSAkcGF0aHMgYXMgJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKCR0eXBlID09PSAnZmlsZXMnIHx8ICR0eXBlID09PSAnY2xhc3NtYXAnIHx8ICR0eXBlID09PSAnZXhjbHVkZS1mcm9tLWNsYXNzbWFwJykgJiYgJHBhY2thZ2UtPmdldFRhcmdldERpcigpICYmICFGaWxlc3lzdGVtOjppc1JlYWRhYmxlKCRpbnN0YWxsUGF0aC4nLycuJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0YXJnZXQtZGlyIGZyb20gZmlsZSBwYXRocyBvZiB0aGUgcm9vdCBwYWNrYWdlCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSA9PT0gJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0RGlyID0gc3RyX3JlcGxhY2UoJ1xcPGRpcnNlcFxcPicsICdbXFxcXC9dJywgcHJlZ19xdW90ZShzdHJfcmVwbGFjZShhcnJheSgnLycsICdcXCcpLCAnPGRpcnNlcD4nLCAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aCA9IGx0cmltKFByZWc6OnJlcGxhY2UoJ3teJy4kdGFyZ2V0RGlyLid9JywgJycsIGx0cmltKCRwYXRoLCAnXFwvJykpLCAnXFwvJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGFyZ2V0LWRpciBmcm9tIGZpbGUgcGF0aHMgdGhhdCBkb24ndCBoYXZlIGl0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aCA9ICRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKSAuICcvJyAuICRwYXRoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdleGNsdWRlLWZyb20tY2xhc3NtYXAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcnN0IGVzY2FwZSB1c2VyIGlucHV0CiAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoID0gUHJlZzo6cmVwbGFjZSgney8rfScsICcvJywgcHJlZ19xdW90ZSh0cmltKHN0cnRyKCRwYXRoLCAnXFwnLCAnLycpLCAnLycpKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgc3VwcG9ydCBmb3Igd2lsZGNhcmRzICogYW5kICoqCiAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoID0gc3RydHIoJHBhdGgsIGFycmF5KCdcXCpcXConID0+ICcuKz8nLCAnXFwqJyA9PiAnW14vXSs/JykpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIHN1cHBvcnQgZm9yIHVwLWxldmVsIHJlbGF0aXZlIHBhdGhzCiAgICAgICAgICAgICAgICAgICAgICAgICR1cGRpciA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoID0gUHJlZzo6cmVwbGFjZUNhbGxiYWNrKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3teKCg/Oig/OlxcXFxcXC4pezEsMn0rLykrKX0nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCYkdXBkaXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVuZG8gcHJlZ19xdW90ZSBmb3IgdGhlIG1hdGNoZWQgc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR1cGRpciA9IHN0cl9yZXBsYWNlKCdcXC4nLCAnLicsICRtYXRjaGVzWzFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJGluc3RhbGxQYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxQYXRoID0gc3RydHIoZ2V0Y3dkKCksICdcXCcsICcvJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRyZXNvbHZlZFBhdGggPSByZWFscGF0aCgkaW5zdGFsbFBhdGggLiAnLycgLiAkdXBkaXIpOwogICAgICAgICAgICAgICAgICAgICAgICAkYXV0b2xvYWRzW10gPSBwcmVnX3F1b3RlKHN0cnRyKCRyZXNvbHZlZFBhdGgsICdcXCcsICcvJykpIC4gJy8nIC4gJHBhdGggLiAnKCR8LyknOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRyZWxhdGl2ZVBhdGggPSBlbXB0eSgkaW5zdGFsbFBhdGgpID8gKGVtcHR5KCRwYXRoKSA/ICcuJyA6ICRwYXRoKSA6ICRpbnN0YWxsUGF0aC4nLycuJHBhdGg7CgogICAgICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gJ2ZpbGVzJykgewogICAgICAgICAgICAgICAgICAgICAgICAkYXV0b2xvYWRzWyR0aGlzLT5nZXRGaWxlSWRlbnRpZmllcigkcGFja2FnZSwgJHBhdGgpXSA9ICRyZWxhdGl2ZVBhdGg7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdjbGFzc21hcCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGF1dG9sb2Fkc1tdID0gJHJlbGF0aXZlUGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkYXV0b2xvYWRzWyRuYW1lc3BhY2VdW10gPSAkcmVsYXRpdmVQYXRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGF1dG9sb2FkczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRGaWxlSWRlbnRpZmllcihQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gbWQ1KCRwYWNrYWdlLT5nZXROYW1lKCkgLiAnOicgLiAkcGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIG91dCBkZXYtZGVwZW5kZW5jaWVzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PGludCwgYXJyYXl7MDogUGFja2FnZUludGVyZmFjZSwgMTogc3RyaW5nfT4gJHBhY2thZ2VNYXAKICAgICAqIEBwYXJhbSAgUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHJvb3RQYWNrYWdlCiAgICAgKiBAcmV0dXJuIGFycmF5PGludCwgYXJyYXl7MDogUGFja2FnZUludGVyZmFjZSwgMTogc3RyaW5nfT4KICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+ICRwYWNrYWdlTWFwCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmaWx0ZXJQYWNrYWdlTWFwKGFycmF5ICRwYWNrYWdlTWFwLCBSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkaW5jbHVkZSA9IGFycmF5KCk7CiAgICAgICAgJHJlcGxhY2VkQnkgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU1hcCBhcyAkaXRlbSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRpdGVtWzBdOwogICAgICAgICAgICAkbmFtZSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgICRwYWNrYWdlc1skbmFtZV0gPSAkcGFja2FnZTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcGxhY2VzKCkgYXMgJHJlcGxhY2UpIHsKICAgICAgICAgICAgICAgICRyZXBsYWNlZEJ5WyRyZXBsYWNlLT5nZXRUYXJnZXQoKV0gPSAkbmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGFkZCA9IGZ1bmN0aW9uIChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKSB1c2UgKCYkYWRkLCAkcGFja2FnZXMsICYkaW5jbHVkZSwgJHJlcGxhY2VkQnkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICR0YXJnZXQgPSAkbGluay0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJlcGxhY2VkQnlbJHRhcmdldF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldCA9ICRyZXBsYWNlZEJ5WyR0YXJnZXRdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5jbHVkZVskdGFyZ2V0XSkpIHsKICAgICAgICAgICAgICAgICAgICAkaW5jbHVkZVskdGFyZ2V0XSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlc1skdGFyZ2V0XSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGFkZCgkcGFja2FnZXNbJHRhcmdldF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgJGFkZCgkcm9vdFBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gYXJyYXlfZmlsdGVyKAogICAgICAgICAgICAkcGFja2FnZU1hcCwKICAgICAgICAgICAgZnVuY3Rpb24gKCRpdGVtKSB1c2UgKCRpbmNsdWRlKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRpdGVtWzBdOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldE5hbWVzKCkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGluY2x1ZGVbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNvcnRzIHBhY2thZ2VzIGJ5IGRlcGVuZGVuY3kgd2VpZ2h0CiAgICAgKgogICAgICogUGFja2FnZXMgb2YgZXF1YWwgd2VpZ2h0IHJldGFpbiB0aGUgb3JpZ2luYWwgb3JkZXIKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8aW50LCBhcnJheXswOiBQYWNrYWdlSW50ZXJmYWNlLCAxOiBzdHJpbmd9PiAkcGFja2FnZU1hcAogICAgICogQHJldHVybiBhcnJheTxpbnQsIGFycmF5ezA6IFBhY2thZ2VJbnRlcmZhY2UsIDE6IHN0cmluZ30+CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzb3J0UGFja2FnZU1hcChhcnJheSAkcGFja2FnZU1hcCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRwYXRocyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTWFwIGFzICRpdGVtKSB7CiAgICAgICAgICAgIGxpc3QoJHBhY2thZ2UsICRwYXRoKSA9ICRpdGVtOwogICAgICAgICAgICAkbmFtZSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgICRwYWNrYWdlc1skbmFtZV0gPSAkcGFja2FnZTsKICAgICAgICAgICAgJHBhdGhzWyRuYW1lXSA9ICRwYXRoOwogICAgICAgIH0KCiAgICAgICAgJHNvcnRlZFBhY2thZ2VzID0gUGFja2FnZVNvcnRlcjo6c29ydFBhY2thZ2VzKCRwYWNrYWdlcyk7CgogICAgICAgICRzb3J0ZWRQYWNrYWdlTWFwID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHNvcnRlZFBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgJHNvcnRlZFBhY2thZ2VNYXBbXSA9IGFycmF5KCRwYWNrYWdlc1skbmFtZV0sICRwYXRoc1skbmFtZV0pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzb3J0ZWRQYWNrYWdlTWFwOwogICAgfQp9CgovKioKICogQHBhcmFtIHN0cmluZyAkZmlsZUlkZW50aWZpZXIKICogQHBhcmFtIHN0cmluZyAkZmlsZQogKiBAcmV0dXJuIHZvaWQKICovCmZ1bmN0aW9uIGNvbXBvc2VyUmVxdWlyZSgkZmlsZUlkZW50aWZpZXIsICRmaWxlKQp7CiAgICBpZiAoZW1wdHkoJEdMT0JBTFNbJ19fY29tcG9zZXJfYXV0b2xvYWRfZmlsZXMnXVskZmlsZUlkZW50aWZpZXJdKSkgewogICAgICAgICRHTE9CQUxTWydfX2NvbXBvc2VyX2F1dG9sb2FkX2ZpbGVzJ11bJGZpbGVJZGVudGlmaWVyXSA9IHRydWU7CgogICAgICAgIHJlcXVpcmUgJGZpbGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKgogKiBUaGlzIGZpbGUgaXMgY29waWVkIGZyb20gdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEZpbmRlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwoKLyoqCiAqIENsYXNzTWFwR2VuZXJhdG9yCiAqCiAqIEBhdXRob3IgR3l1bGEgU2FsbGFpIDxzYWxsYTAxNkBnbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENsYXNzTWFwR2VuZXJhdG9yCnsKICAgIC8qKgogICAgICogR2VuZXJhdGUgYSBjbGFzcyBtYXAgZmlsZQogICAgICoKICAgICAqIEBwYXJhbSBcVHJhdmVyc2FibGU8c3RyaW5nPnxhcnJheTxzdHJpbmc+ICRkaXJzIERpcmVjdG9yaWVzIG9yIGEgc2luZ2xlIHBhdGggdG8gc2VhcmNoIGluCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAgJGZpbGUgVGhlIG5hbWUgb2YgdGhlIGNsYXNzIG1hcCBmaWxlCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkdW1wKCRkaXJzLCAkZmlsZSkKICAgIHsKICAgICAgICAkbWFwcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRkaXJzIGFzICRkaXIpIHsKICAgICAgICAgICAgJG1hcHMgPSBhcnJheV9tZXJnZSgkbWFwcywgc3RhdGljOjpjcmVhdGVNYXAoJGRpcikpOwogICAgICAgIH0KCiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGZpbGUsIHNwcmludGYoJzw/cGhwIHJldHVybiAlczsnLCB2YXJfZXhwb3J0KCRtYXBzLCB0cnVlKSkpOwogICAgfQoKICAgIC8qKgogICAgICogSXRlcmF0ZSBvdmVyIGFsbCBmaWxlcyBpbiB0aGUgZ2l2ZW4gZGlyZWN0b3J5IHNlYXJjaGluZyBmb3IgY2xhc3NlcwogICAgICoKICAgICAqIEBwYXJhbSBcVHJhdmVyc2FibGU8XFNwbEZpbGVJbmZvPnxzdHJpbmd8YXJyYXk8c3RyaW5nPiAkcGF0aCBUaGUgcGF0aCB0byBzZWFyY2ggaW4gb3IgYW4gaXRlcmF0b3IKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICRleGNsdWRlZCAgICAgUmVnZXggdGhhdCBtYXRjaGVzIGZpbGUgcGF0aHMgdG8gYmUgZXhjbHVkZWQgZnJvbSB0aGUgY2xhc3NtYXAKICAgICAqIEBwYXJhbSA/SU9JbnRlcmZhY2UgICAgICAgICRpbyAgICAgICAgICAgSU8gb2JqZWN0CiAgICAgKiBAcGFyYW0gP3N0cmluZyAgICAgICAgICAgICAkbmFtZXNwYWNlICAgIE9wdGlvbmFsIG5hbWVzcGFjZSBwcmVmaXggdG8gZmlsdGVyIGJ5CiAgICAgKiBAcGFyYW0gP3N0cmluZyAgICAgICAgICAgICAkYXV0b2xvYWRUeXBlIHBzci0wfHBzci00IE9wdGlvbmFsIGF1dG9sb2FkIHN0YW5kYXJkIHRvIHVzZSBtYXBwaW5nIHJ1bGVzCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCB0cnVlPiAkc2Nhbm5lZEZpbGVzCiAgICAgKiBAcmV0dXJuIGFycmF5PGNsYXNzLXN0cmluZywgc3RyaW5nPiBBIGNsYXNzIG1hcCBhcnJheQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBXaGVuIHRoZSBwYXRoIGlzIG5laXRoZXIgYW4gZXhpc3RpbmcgZmlsZSBub3IgZGlyZWN0b3J5CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlTWFwKCRwYXRoLCAkZXhjbHVkZWQgPSBudWxsLCBJT0ludGVyZmFjZSAkaW8gPSBudWxsLCAkbmFtZXNwYWNlID0gbnVsbCwgJGF1dG9sb2FkVHlwZSA9IG51bGwsICYkc2Nhbm5lZEZpbGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkYmFzZVBhdGggPSAkcGF0aDsKICAgICAgICBpZiAoaXNfc3RyaW5nKCRwYXRoKSkgewogICAgICAgICAgICBpZiAoaXNfZmlsZSgkcGF0aCkpIHsKICAgICAgICAgICAgICAgICRwYXRoID0gYXJyYXkobmV3IFxTcGxGaWxlSW5mbygkcGF0aCkpOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNfZGlyKCRwYXRoKSB8fCBzdHJwb3MoJHBhdGgsICcqJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkcGF0aCA9IEZpbmRlcjo6Y3JlYXRlKCktPmZpbGVzKCktPmZvbGxvd0xpbmtzKCktPm5hbWUoJy9cLihwaHB8aW5jfGhoKSQvJyktPmluKCRwYXRoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAnQ291bGQgbm90IHNjYW4gZm9yIGNsYXNzZXMgaW5zaWRlICInLiRwYXRoLgogICAgICAgICAgICAgICAgICAgICciIHdoaWNoIGRvZXMgbm90IGFwcGVhciB0byBiZSBhIGZpbGUgbm9yIGEgZm9sZGVyJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChudWxsICE9PSAkYXV0b2xvYWRUeXBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignUGF0aCBtdXN0IGJlIGEgc3RyaW5nIHdoZW4gc3BlY2lmeWluZyBhbiBhdXRvbG9hZCB0eXBlJyk7CiAgICAgICAgfQoKICAgICAgICAkbWFwID0gYXJyYXkoKTsKICAgICAgICAkZmlsZXN5c3RlbSA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgJGN3ZCA9IHJlYWxwYXRoKGdldGN3ZCgpKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhdGggYXMgJGZpbGUpIHsKICAgICAgICAgICAgJGZpbGVQYXRoID0gJGZpbGUtPmdldFBhdGhuYW1lKCk7CiAgICAgICAgICAgIGlmICghaW5fYXJyYXkocGF0aGluZm8oJGZpbGVQYXRoLCBQQVRISU5GT19FWFRFTlNJT04pLCBhcnJheSgncGhwJywgJ2luYycsICdoaCcpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGZpbGVzeXN0ZW0tPmlzQWJzb2x1dGVQYXRoKCRmaWxlUGF0aCkpIHsKICAgICAgICAgICAgICAgICRmaWxlUGF0aCA9ICRjd2QgLiAnLycgLiAkZmlsZVBhdGg7CiAgICAgICAgICAgICAgICAkZmlsZVBhdGggPSAkZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aCgkZmlsZVBhdGgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGZpbGVQYXRoID0gUHJlZzo6cmVwbGFjZSgne1tcXFxcL117Mix9fScsICcvJywgJGZpbGVQYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlYWxQYXRoID0gcmVhbHBhdGgoJGZpbGVQYXRoKTsKCiAgICAgICAgICAgIC8vIGlmIGEgbGlzdCBvZiBzY2FubmVkIGZpbGVzIGlzIGdpdmVuLCBhdm9pZCBzY2FubmluZyB0d2ljZSB0aGUgc2FtZSBmaWxlIHRvIHNhdmUgY3ljbGVzIGFuZCBhdm9pZCBnZW5lcmF0aW5nIHdhcm5pbmdzCiAgICAgICAgICAgIC8vIGluIGNhc2UgYSBQU1ItMC80IGRlY2xhcmF0aW9uIGZvbGxvd3MgYW5vdGhlciBtb3JlIHNwZWNpZmljIG9uZSwgb3IgYSBjbGFzc21hcCBkZWNsYXJhdGlvbiwgd2hpY2ggY292ZXJlZCB0aGlzIGZpbGUgYWxyZWFkeQogICAgICAgICAgICBpZiAoaXNzZXQoJHNjYW5uZWRGaWxlc1skcmVhbFBhdGhdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNoZWNrIHRoZSByZWFscGF0aCBvZiB0aGUgZmlsZSBhZ2FpbnN0IHRoZSBleGNsdWRlZCBwYXRocyBhcyB0aGUgcGF0aCBtaWdodCBiZSBhIHN5bWxpbmsgYW5kIHRoZSBleGNsdWRlZCBwYXRoIGlzIHJlYWxwYXRoJ2Qgc28gc3ltbGluayBhcmUgcmVzb2x2ZWQKICAgICAgICAgICAgaWYgKCRleGNsdWRlZCAmJiBQcmVnOjppc01hdGNoKCRleGNsdWRlZCwgc3RydHIoJHJlYWxQYXRoLCAnXFwnLCAnLycpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY2hlY2sgbm9uLXJlYWxwYXRoIG9mIGZpbGUgZm9yIGRpcmVjdG9yaWVzIHN5bWxpbmsgaW4gcHJvamVjdCBkaXIKICAgICAgICAgICAgaWYgKCRleGNsdWRlZCAmJiBQcmVnOjppc01hdGNoKCRleGNsdWRlZCwgc3RydHIoJGZpbGVQYXRoLCAnXFwnLCAnLycpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjbGFzc2VzID0gc2VsZjo6ZmluZENsYXNzZXMoJGZpbGVQYXRoKTsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICRhdXRvbG9hZFR5cGUpIHsKICAgICAgICAgICAgICAgICRjbGFzc2VzID0gc2VsZjo6ZmlsdGVyQnlOYW1lc3BhY2UoJGNsYXNzZXMsICRmaWxlUGF0aCwgJG5hbWVzcGFjZSwgJGF1dG9sb2FkVHlwZSwgJGJhc2VQYXRoLCAkaW8pOwoKICAgICAgICAgICAgICAgIC8vIGlmIG5vIHZhbGlkIGNsYXNzIHdhcyBmb3VuZCBpbiB0aGUgZmlsZSB0aGVuIHdlIGRvIG5vdCBtYXJrIGl0IGFzIHNjYW5uZWQgYXMgaXQgbWlnaHQgc3RpbGwgYmUgbWF0Y2hlZCBieSBhbm90aGVyIHJ1bGUgbGF0ZXIKICAgICAgICAgICAgICAgIGlmICgkY2xhc3NlcykgewogICAgICAgICAgICAgICAgICAgICRzY2FubmVkRmlsZXNbJHJlYWxQYXRoXSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBjbGFzc21hcCBhdXRvbG9hZCBydWxlcyBhbHdheXMgY29sbGVjdCBhbGwgY2xhc3NlcyBzbyBmb3IgdGhlc2Ugd2UgZGVmaW5pdGVseSBkbyBub3Qgd2FudCB0byBzY2FuIGFnYWluCiAgICAgICAgICAgICAgICAkc2Nhbm5lZEZpbGVzWyRyZWFsUGF0aF0gPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkY2xhc3NlcyBhcyAkY2xhc3MpIHsKICAgICAgICAgICAgICAgIC8vIHNraXAgY2xhc3NlcyBub3Qgd2l0aGluIHRoZSBnaXZlbiBuYW1lc3BhY2UgcHJlZml4CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJGF1dG9sb2FkVHlwZSAmJiBudWxsICE9PSAkbmFtZXNwYWNlICYmICcnICE9PSAkbmFtZXNwYWNlICYmIDAgIT09IHN0cnBvcygkY2xhc3MsICRuYW1lc3BhY2UpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkbWFwWyRjbGFzc10pKSB7CiAgICAgICAgICAgICAgICAgICAgJG1hcFskY2xhc3NdID0gJGZpbGVQYXRoOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRpbyAmJiAkbWFwWyRjbGFzc10gIT09ICRmaWxlUGF0aCAmJiAhUHJlZzo6aXNNYXRjaCgney8odGVzdHxmaXh0dXJlfGV4YW1wbGV8c3R1YilzPy99aScsIHN0cnRyKCRtYXBbJGNsYXNzXS4nICcuJGZpbGVQYXRoLCAnXFwnLCAnLycpKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgJzx3YXJuaW5nPldhcm5pbmc6IEFtYmlndW91cyBjbGFzcyByZXNvbHV0aW9uLCAiJy4kY2xhc3MuJyInLgogICAgICAgICAgICAgICAgICAgICAgICAnIHdhcyBmb3VuZCBpbiBib3RoICInLiRtYXBbJGNsYXNzXS4nIiBhbmQgIicuJGZpbGVQYXRoLiciLCB0aGUgZmlyc3Qgd2lsbCBiZSB1c2VkLjwvd2FybmluZz4nCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtYXA7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmUgY2xhc3NlcyB3aGljaCBjb3VsZCBub3QgaGF2ZSBiZWVuIGxvYWRlZCBieSBuYW1lc3BhY2UgYXV0b2xvYWRlcnMKICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5PGludCwgY2xhc3Mtc3RyaW5nPiAkY2xhc3NlcyAgICAgICBmb3VuZCBjbGFzc2VzIGluIGdpdmVuIGZpbGUKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICRmaWxlUGF0aCAgICAgIGN1cnJlbnQgZmlsZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgJGJhc2VOYW1lc3BhY2UgcHJlZml4IG9mIGdpdmVuIGF1dG9sb2FkIG1hcHBpbmcKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICRuYW1lc3BhY2VUeXBlIHBzci0wfHBzci00CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAkYmFzZVBhdGggICAgICByb290IGRpcmVjdG9yeSBvZiBnaXZlbiBhdXRvbG9hZCBtYXBwaW5nCiAgICAgKiBAcGFyYW0gID9JT0ludGVyZmFjZSAgICAgICAgICAgICAkaW8gICAgICAgICAgICBJTyBvYmplY3QKICAgICAqIEByZXR1cm4gYXJyYXk8aW50LCBjbGFzcy1zdHJpbmc+IHZhbGlkIGNsYXNzZXMKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZmlsdGVyQnlOYW1lc3BhY2UoJGNsYXNzZXMsICRmaWxlUGF0aCwgJGJhc2VOYW1lc3BhY2UsICRuYW1lc3BhY2VUeXBlLCAkYmFzZVBhdGgsICRpbykKICAgIHsKICAgICAgICAkdmFsaWRDbGFzc2VzID0gYXJyYXkoKTsKICAgICAgICAkcmVqZWN0ZWRDbGFzc2VzID0gYXJyYXkoKTsKCiAgICAgICAgJHJlYWxTdWJQYXRoID0gc3Vic3RyKCRmaWxlUGF0aCwgc3RybGVuKCRiYXNlUGF0aCkgKyAxKTsKICAgICAgICAkcmVhbFN1YlBhdGggPSBzdWJzdHIoJHJlYWxTdWJQYXRoLCAwLCBzdHJycG9zKCRyZWFsU3ViUGF0aCwgJy4nKSk7CgogICAgICAgIGZvcmVhY2ggKCRjbGFzc2VzIGFzICRjbGFzcykgewogICAgICAgICAgICAvLyBzaWxlbnRseSBza2lwIGlmIG5zIGRvZXNuJ3QgaGF2ZSBjb21tb24gcm9vdAogICAgICAgICAgICBpZiAoJycgIT09ICRiYXNlTmFtZXNwYWNlICYmIDAgIT09IHN0cnBvcygkY2xhc3MsICRiYXNlTmFtZXNwYWNlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gdHJhbnNmb3JtIGNsYXNzIG5hbWUgdG8gZmlsZSBwYXRoIGFuZCB2YWxpZGF0ZQogICAgICAgICAgICBpZiAoJ3Bzci0wJyA9PT0gJG5hbWVzcGFjZVR5cGUpIHsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VMZW5ndGggPSBzdHJycG9zKCRjbGFzcywgJ1xcJyk7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRuYW1lc3BhY2VMZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAkbmFtZXNwYWNlID0gc3Vic3RyKCRjbGFzcywgMCwgJG5hbWVzcGFjZUxlbmd0aCArIDEpOwogICAgICAgICAgICAgICAgICAgICRjbGFzc05hbWUgPSBzdWJzdHIoJGNsYXNzLCAkbmFtZXNwYWNlTGVuZ3RoICsgMSk7CiAgICAgICAgICAgICAgICAgICAgJHN1YlBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkbmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICAuIHN0cl9yZXBsYWNlKCdfJywgRElSRUNUT1JZX1NFUEFSQVRPUiwgJGNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRzdWJQYXRoID0gc3RyX3JlcGxhY2UoJ18nLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkY2xhc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJ3Bzci00JyA9PT0gJG5hbWVzcGFjZVR5cGUpIHsKICAgICAgICAgICAgICAgICRzdWJOYW1lc3BhY2UgPSAoJycgIT09ICRiYXNlTmFtZXNwYWNlKSA/IHN1YnN0cigkY2xhc3MsIHN0cmxlbigkYmFzZU5hbWVzcGFjZSkpIDogJGNsYXNzOwogICAgICAgICAgICAgICAgJHN1YlBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkc3ViTmFtZXNwYWNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigibmFtZXNwYWNlVHlwZSBtdXN0IGJlIHBzci0wIG9yIHBzci00LCAkbmFtZXNwYWNlVHlwZSBnaXZlbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkc3ViUGF0aCA9PT0gJHJlYWxTdWJQYXRoKSB7CiAgICAgICAgICAgICAgICAkdmFsaWRDbGFzc2VzW10gPSAkY2xhc3M7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVqZWN0ZWRDbGFzc2VzW10gPSAkY2xhc3M7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gd2FybiBvbmx5IGlmIG5vIHZhbGlkIGNsYXNzZXMsIGVsc2Ugc2lsZW50bHkgc2tpcCBpbnZhbGlkCiAgICAgICAgaWYgKGVtcHR5KCR2YWxpZENsYXNzZXMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZWplY3RlZENsYXNzZXMgYXMgJGNsYXNzKSB7CiAgICAgICAgICAgICAgICBpZiAoJGlvKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCI8d2FybmluZz5DbGFzcyAkY2xhc3MgbG9jYXRlZCBpbiAiLlByZWc6OnJlcGxhY2UoJ3teJy5wcmVnX3F1b3RlKGdldGN3ZCgpKS4nfScsICcuJywgJGZpbGVQYXRoLCAxKS4iIGRvZXMgbm90IGNvbXBseSB3aXRoICRuYW1lc3BhY2VUeXBlIGF1dG9sb2FkaW5nIHN0YW5kYXJkLiBTa2lwcGluZy48L3dhcm5pbmc+Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWxpZENsYXNzZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0IHRoZSBjbGFzc2VzIGluIHRoZSBnaXZlbiBmaWxlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkcGF0aCBUaGUgZmlsZSB0byBjaGVjawogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBhcnJheTxpbnQsIGNsYXNzLXN0cmluZz4gVGhlIGZvdW5kIGNsYXNzZXMKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZmluZENsYXNzZXMoJHBhdGgpCiAgICB7CiAgICAgICAgJGV4dHJhVHlwZXMgPSBzZWxmOjpnZXRFeHRyYVR5cGVzKCk7CgogICAgICAgIC8vIFVzZSBAIGhlcmUgaW5zdGVhZCBvZiBTaWxlbmNlciB0byBhY3RpdmVseSBzdXBwcmVzcyAndW5oZWxwZnVsJyBvdXRwdXQKICAgICAgICAvLyBAbGluayBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC80ODg2CiAgICAgICAgJGNvbnRlbnRzID0gQHBocF9zdHJpcF93aGl0ZXNwYWNlKCRwYXRoKTsKICAgICAgICBpZiAoISRjb250ZW50cykgewogICAgICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnRmlsZSBhdCAiJXMiIGRvZXMgbm90IGV4aXN0LCBjaGVjayB5b3VyIGNsYXNzbWFwIGRlZmluaXRpb25zJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCFGaWxlc3lzdGVtOjppc1JlYWRhYmxlKCRwYXRoKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnRmlsZSBhdCAiJXMiIGlzIG5vdCByZWFkYWJsZSwgY2hlY2sgaXRzIHBlcm1pc3Npb25zJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCcnID09PSB0cmltKGZpbGVfZ2V0X2NvbnRlbnRzKCRwYXRoKSkpIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBpbnB1dCBmaWxlIHdhcyByZWFsbHkgZW1wdHkgYW5kIHRodXMgY29udGFpbnMgbm8gY2xhc3NlcwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdGaWxlIGF0ICIlcyIgY291bGQgbm90IGJlIHBhcnNlZCBhcyBQSFAsIGl0IG1heSBiZSBiaW5hcnkgb3IgY29ycnVwdGVkJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGVycm9yWydtZXNzYWdlJ10pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSBQSFBfRU9MIC4gJ1RoZSBmb2xsb3dpbmcgbWVzc2FnZSBtYXkgYmUgaGVscGZ1bDonIC4gUEhQX0VPTCAuICRlcnJvclsnbWVzc2FnZSddOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCRtZXNzYWdlLCAkcGF0aCkpOwogICAgICAgIH0KCiAgICAgICAgLy8gcmV0dXJuIGVhcmx5IGlmIHRoZXJlIGlzIG5vIGNoYW5jZSBvZiBtYXRjaGluZyBhbnl0aGluZyBpbiB0aGlzIGZpbGUKICAgICAgICBQcmVnOjptYXRjaEFsbCgne1xiKD86Y2xhc3N8aW50ZXJmYWNlJy4kZXh0cmFUeXBlcy4nKVxzfWknLCAkY29udGVudHMsICRtYXRjaGVzKTsKICAgICAgICBpZiAoISRtYXRjaGVzKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgJHAgPSBuZXcgUGhwRmlsZUNsZWFuZXIoJGNvbnRlbnRzLCBjb3VudCgkbWF0Y2hlc1swXSkpOwogICAgICAgICRjb250ZW50cyA9ICRwLT5jbGVhbigpOwogICAgICAgIHVuc2V0KCRwKTsKCiAgICAgICAgUHJlZzo6bWF0Y2hBbGwoJ3sKICAgICAgICAgICAgKD86CiAgICAgICAgICAgICAgICAgXGIoPzwhW1wkOj5dKSg/UDx0eXBlPmNsYXNzfGludGVyZmFjZScuJGV4dHJhVHlwZXMuJykgXHMrKyAoP1A8bmFtZT5bYS16QS1aX1x4N2YtXHhmZjpdW2EtekEtWjAtOV9ceDdmLVx4ZmY6XC1dKispCiAgICAgICAgICAgICAgIHwgXGIoPzwhW1wkOj5dKSg/UDxucz5uYW1lc3BhY2UpICg/UDxuc25hbWU+XHMrK1thLXpBLVpfXHg3Zi1ceGZmXVthLXpBLVowLTlfXHg3Zi1ceGZmXSorKD86XHMqK1xcXFxccyorW2EtekEtWl9ceDdmLVx4ZmZdW2EtekEtWjAtOV9ceDdmLVx4ZmZdKispKispPyBccyorIFtceztdCiAgICAgICAgICAgICkKICAgICAgICB9aXgnLCAkY29udGVudHMsICRtYXRjaGVzKTsKCiAgICAgICAgJGNsYXNzZXMgPSBhcnJheSgpOwogICAgICAgICRuYW1lc3BhY2UgPSAnJzsKCiAgICAgICAgZm9yICgkaSA9IDAsICRsZW4gPSBjb3VudCgkbWF0Y2hlc1sndHlwZSddKTsgJGkgPCAkbGVuOyAkaSsrKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoZXNbJ25zJ11bJGldKSkgewogICAgICAgICAgICAgICAgJG5hbWVzcGFjZSA9IHN0cl9yZXBsYWNlKGFycmF5KCcgJywgIlx0IiwgIlxyIiwgIlxuIiksICcnLCAkbWF0Y2hlc1snbnNuYW1lJ11bJGldKSAuICdcXCc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbmFtZSA9ICRtYXRjaGVzWyduYW1lJ11bJGldOwogICAgICAgICAgICAgICAgLy8gc2tpcCBhbm9uIGNsYXNzZXMgZXh0ZW5kaW5nL2ltcGxlbWVudGluZwogICAgICAgICAgICAgICAgaWYgKCRuYW1lID09PSAnZXh0ZW5kcycgfHwgJG5hbWUgPT09ICdpbXBsZW1lbnRzJykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRuYW1lWzBdID09PSAnOicpIHsKICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGFuIFhIUCBjbGFzcywgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3hocAogICAgICAgICAgICAgICAgICAgICRuYW1lID0gJ3hocCcuc3Vic3RyKHN0cl9yZXBsYWNlKGFycmF5KCctJywgJzonKSwgYXJyYXkoJ18nLCAnX18nKSwgJG5hbWUpLCAxKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkbWF0Y2hlc1sndHlwZSddWyRpXSA9PT0gJ2VudW0nKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSW4gSGFjaywgc29tZXRoaW5nIGxpa2U6CiAgICAgICAgICAgICAgICAgICAgLy8gICBlbnVtIEZvbzogaW50IHsgSEVSUCA9ICcxMjMnOyB9CiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlZ2V4IGFib3ZlIGNhcHR1cmVzIHRoZSBjb2xvbiwgd2hpY2ggaXNuJ3QgcGFydCBvZgogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjbGFzcyBuYW1lLgogICAgICAgICAgICAgICAgICAgICRuYW1lID0gcnRyaW0oJG5hbWUsICc6Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY2xhc3Nlc1tdID0gbHRyaW0oJG5hbWVzcGFjZSAuICRuYW1lLCAnXFwnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjbGFzc2VzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0RXh0cmFUeXBlcygpCiAgICB7CiAgICAgICAgc3RhdGljICRleHRyYVR5cGVzID0gbnVsbDsKICAgICAgICBpZiAobnVsbCA9PT0gJGV4dHJhVHlwZXMpIHsKICAgICAgICAgICAgJGV4dHJhVHlwZXMgPSBQSFBfVkVSU0lPTl9JRCA8IDUwNDAwID8gJycgOiAnfHRyYWl0JzsKICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDgwMTAwIHx8IChkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSAmJiB2ZXJzaW9uX2NvbXBhcmUoSEhWTV9WRVJTSU9OLCAnMy4zJywgJz49JykpKSB7CiAgICAgICAgICAgICAgICAkZXh0cmFUeXBlcyAuPSAnfGVudW0nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFBocEZpbGVDbGVhbmVyOjpzZXRUeXBlQ29uZmlnKGFycmF5X21lcmdlKGFycmF5KCdjbGFzcycsICdpbnRlcmZhY2UnKSwgYXJyYXlfZmlsdGVyKGV4cGxvZGUoJ3wnLCAkZXh0cmFUeXBlcykpKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGV4dHJhVHlwZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29uZmlnOwoKLyoqCiAqIENvbmZpZ3VyYXRpb24gU291cmNlIEludGVyZmFjZQogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgQmVhdSBTaW1lbnNlbiA8YmVhdUBkZmx5ZGV2LmNvbT4KICovCmludGVyZmFjZSBDb25maWdTb3VyY2VJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBBZGQgYSByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgJG5hbWUgICBOYW1lCiAgICAgKiBAcGFyYW0gbWl4ZWRbXXxmYWxzZSAkY29uZmlnIENvbmZpZ3VyYXRpb24KICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICRhcHBlbmQgV2hldGhlciB0aGUgcmVwbyBzaG91bGQgYmUgYXBwZW5kZWQgKHRydWUpIG9yIHByZXBlbmRlZCAoZmFsc2UpCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZXBvc2l0b3J5KCRuYW1lLCAkY29uZmlnLCAkYXBwZW5kID0gdHJ1ZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYSByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUmVwb3NpdG9yeSgkbmFtZSk7CgogICAgLyoqCiAgICAgKiBBZGQgYSBjb25maWcgc2V0dGluZwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIE5hbWUKICAgICAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlIFZhbHVlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb25maWdTZXR0aW5nKCRuYW1lLCAkdmFsdWUpOwoKICAgIC8qKgogICAgICogUmVtb3ZlIGEgY29uZmlnIHNldHRpbmcKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVDb25maWdTZXR0aW5nKCRuYW1lKTsKCiAgICAvKioKICAgICAqIEFkZCBhIHByb3BlcnR5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSAgTmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUgVmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFByb3BlcnR5KCRuYW1lLCAkdmFsdWUpOwoKICAgIC8qKgogICAgICogUmVtb3ZlIGEgcHJvcGVydHkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVQcm9wZXJ0eSgkbmFtZSk7CgogICAgLyoqCiAgICAgKiBBZGQgYSBwYWNrYWdlIGxpbmsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlICBUeXBlIChyZXF1aXJlLCByZXF1aXJlLWRldiwgcHJvdmlkZSwgc3VnZ2VzdCwgcmVwbGFjZSwgY29uZmxpY3QpCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICBOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBWYWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTGluaygkdHlwZSwgJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYSBwYWNrYWdlIGxpbmsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIFR5cGUgKHJlcXVpcmUsIHJlcXVpcmUtZGV2LCBwcm92aWRlLCBzdWdnZXN0LCByZXBsYWNlLCBjb25mbGljdCkKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgTmFtZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlTGluaygkdHlwZSwgJG5hbWUpOwoKICAgIC8qKgogICAgICogR2l2ZXMgYSB1c2VyLWZyaWVuZGx5IG5hbWUgdG8gdGhpcyBzb3VyY2UgKGZpbGUgcGF0aCBvciBzbykKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbmZpZzsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uTWFuaXB1bGF0b3I7CnVzZSBDb21wb3NlclxKc29uXEpzb25WYWxpZGF0aW9uRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKCi8qKgogKiBKU09OIENvbmZpZ3VyYXRpb24gU291cmNlCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBCZWF1IFNpbWVuc2VuIDxiZWF1QGRmbHlkZXYuY29tPgogKi8KY2xhc3MgSnNvbkNvbmZpZ1NvdXJjZSBpbXBsZW1lbnRzIENvbmZpZ1NvdXJjZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEB2YXIgSnNvbkZpbGUKICAgICAqLwogICAgcHJpdmF0ZSAkZmlsZTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcml2YXRlICRhdXRoQ29uZmlnOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gSnNvbkZpbGUgJGZpbGUKICAgICAqIEBwYXJhbSBib29sICAgICAkYXV0aENvbmZpZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSnNvbkZpbGUgJGZpbGUsICRhdXRoQ29uZmlnID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmZpbGUgPSAkZmlsZTsKICAgICAgICAkdGhpcy0+YXV0aENvbmZpZyA9ICRhdXRoQ29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoJG5hbWUsICRjb25maWcsICRhcHBlbmQgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5tYW5pcHVsYXRlSnNvbignYWRkUmVwb3NpdG9yeScsICRuYW1lLCAkY29uZmlnLCAkYXBwZW5kLCBmdW5jdGlvbiAoJiRjb25maWcsICRyZXBvLCAkcmVwb0NvbmZpZykgdXNlICgkYXBwZW5kKSB7CiAgICAgICAgICAgIC8vIGlmIGNvbnZlcnRpbmcgZnJvbSBhbiBhcnJheSBmb3JtYXQgdG8gaGFzaG1hcCBmb3JtYXQsIGFuZCB0aGVyZSBpcyBhIHsicGFja2FnaXN0Lm9yZyI6ZmFsc2V9IHJlcG8sIHdlIGhhdmUKICAgICAgICAgICAgLy8gdG8gY29udmVydCBpdCB0byAicGFja2FnaXN0Lm9yZyI6IGZhbHNlIGtleSBvbiB0aGUgaGFzaG1hcCBvdGhlcndpc2UgaXQgZmFpbHMgc2NoZW1hIHZhbGlkYXRpb24KICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3JlcG9zaXRvcmllcyddKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ10gYXMgJGluZGV4ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGluZGV4ID09PSAkcmVwbykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX251bWVyaWMoJGluZGV4KSAmJiAoJHZhbCA9PT0gYXJyYXkoJ3BhY2thZ2lzdCcgPT4gZmFsc2UpIHx8ICR2YWwgPT09IGFycmF5KCdwYWNrYWdpc3Qub3JnJyA9PiBmYWxzZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJ3JlcG9zaXRvcmllcyddWyRpbmRleF0pOwogICAgICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydyZXBvc2l0b3JpZXMnXVsncGFja2FnaXN0Lm9yZyddID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRhcHBlbmQpIHsKICAgICAgICAgICAgICAgICRjb25maWdbJ3JlcG9zaXRvcmllcyddWyRyZXBvXSA9ICRyZXBvQ29uZmlnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ10gPSBhcnJheSgkcmVwbyA9PiAkcmVwb0NvbmZpZykgKyAkY29uZmlnWydyZXBvc2l0b3JpZXMnXTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVJlcG9zaXRvcnkoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdyZW1vdmVSZXBvc2l0b3J5JywgJG5hbWUsIGZ1bmN0aW9uICgmJGNvbmZpZywgJHJlcG8pIHsKICAgICAgICAgICAgdW5zZXQoJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ11bJHJlcG9dKTsKICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb25maWdTZXR0aW5nKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgJGF1dGhDb25maWcgPSAkdGhpcy0+YXV0aENvbmZpZzsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ2FkZENvbmZpZ1NldHRpbmcnLCAkbmFtZSwgJHZhbHVlLCBmdW5jdGlvbiAoJiRjb25maWcsICRrZXksICR2YWwpIHVzZSAoJGF1dGhDb25maWcpIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKGJpdGJ1Y2tldC1vYXV0aHxnaXRodWItb2F1dGh8Z2l0bGFiLW9hdXRofGdpdGxhYi10b2tlbnxiZWFyZXJ8aHR0cC1iYXNpY3xwbGF0Zm9ybSlcLn0nLCAka2V5KSkgewogICAgICAgICAgICAgICAgbGlzdCgka2V5LCAkaG9zdCkgPSBleHBsb2RlKCcuJywgJGtleSwgMik7CiAgICAgICAgICAgICAgICBpZiAoJGF1dGhDb25maWcpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWyRrZXldWyRob3N0XSA9ICR2YWw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ2NvbmZpZyddWyRrZXldWyRob3N0XSA9ICR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29uZmlnWydjb25maWcnXVska2V5XSA9ICR2YWw7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVDb25maWdTZXR0aW5nKCRuYW1lKQogICAgewogICAgICAgICRhdXRoQ29uZmlnID0gJHRoaXMtPmF1dGhDb25maWc7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdyZW1vdmVDb25maWdTZXR0aW5nJywgJG5hbWUsIGZ1bmN0aW9uICgmJGNvbmZpZywgJGtleSkgdXNlICgkYXV0aENvbmZpZykgewogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne14oYml0YnVja2V0LW9hdXRofGdpdGh1Yi1vYXV0aHxnaXRsYWItb2F1dGh8Z2l0bGFiLXRva2VufGJlYXJlcnxodHRwLWJhc2ljfHBsYXRmb3JtKVwufScsICRrZXkpKSB7CiAgICAgICAgICAgICAgICBsaXN0KCRrZXksICRob3N0KSA9IGV4cGxvZGUoJy4nLCAka2V5LCAyKTsKICAgICAgICAgICAgICAgIGlmICgkYXV0aENvbmZpZykgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJGtleV1bJGhvc3RdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGNvbmZpZ1snY29uZmlnJ11bJGtleV1bJGhvc3RdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJ2NvbmZpZyddWyRrZXldKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFByb3BlcnR5KCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdhZGRQcm9wZXJ0eScsICRuYW1lLCAkdmFsdWUsIGZ1bmN0aW9uICgmJGNvbmZpZywgJGtleSwgJHZhbCkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRrZXksICdleHRyYS4nKSA9PT0gMCB8fCBzdHJwb3MoJGtleSwgJ3NjcmlwdHMuJykgPT09IDApIHsKICAgICAgICAgICAgICAgICRiaXRzID0gZXhwbG9kZSgnLicsICRrZXkpOwogICAgICAgICAgICAgICAgJGxhc3QgPSBhcnJheV9wb3AoJGJpdHMpOwogICAgICAgICAgICAgICAgJGFyciA9ICYkY29uZmlnW3Jlc2V0KCRiaXRzKV07CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYml0cyBhcyAkYml0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkYXJyWyRiaXRdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYXJyWyRiaXRdID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGFyciA9ICYkYXJyWyRiaXRdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGFyclskbGFzdF0gPSAkdmFsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbmZpZ1ska2V5XSA9ICR2YWw7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVQcm9wZXJ0eSgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ3JlbW92ZVByb3BlcnR5JywgJG5hbWUsIGZ1bmN0aW9uICgmJGNvbmZpZywgJGtleSkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRrZXksICdleHRyYS4nKSA9PT0gMCB8fCBzdHJwb3MoJGtleSwgJ3NjcmlwdHMuJykgPT09IDApIHsKICAgICAgICAgICAgICAgICRiaXRzID0gZXhwbG9kZSgnLicsICRrZXkpOwogICAgICAgICAgICAgICAgJGxhc3QgPSBhcnJheV9wb3AoJGJpdHMpOwogICAgICAgICAgICAgICAgJGFyciA9ICYkY29uZmlnW3Jlc2V0KCRiaXRzKV07CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYml0cyBhcyAkYml0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkYXJyWyRiaXRdKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRhcnIgPSAmJGFyclskYml0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHVuc2V0KCRhcnJbJGxhc3RdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJGtleV0pOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTGluaygkdHlwZSwgJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ2FkZExpbmsnLCAkdHlwZSwgJG5hbWUsICR2YWx1ZSwgZnVuY3Rpb24gKCYkY29uZmlnLCAkdHlwZSwgJG5hbWUsICR2YWx1ZSkgewogICAgICAgICAgICAkY29uZmlnWyR0eXBlXVskbmFtZV0gPSAkdmFsdWU7CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlTGluaygkdHlwZSwgJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdyZW1vdmVTdWJOb2RlJywgJHR5cGUsICRuYW1lLCBmdW5jdGlvbiAoJiRjb25maWcsICR0eXBlLCAkbmFtZSkgewogICAgICAgICAgICB1bnNldCgkY29uZmlnWyR0eXBlXVskbmFtZV0pOwogICAgICAgIH0pOwogICAgICAgICR0aGlzLT5tYW5pcHVsYXRlSnNvbigncmVtb3ZlTWFpbktleUlmRW1wdHknLCAkdHlwZSwgZnVuY3Rpb24gKCYkY29uZmlnLCAkdHlwZSkgewogICAgICAgICAgICBpZiAoMCA9PT0gY291bnQoJGNvbmZpZ1skdHlwZV0pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkY29uZmlnWyR0eXBlXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1ldGhvZAogICAgICogQHBhcmFtIG1peGVkIC4uLiRhcmdzCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGZhbGxiYWNrCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBtYW5pcHVsYXRlSnNvbigkbWV0aG9kLCAkYXJncywgJGZhbGxiYWNrKQogICAgewogICAgICAgICRhcmdzID0gZnVuY19nZXRfYXJncygpOwogICAgICAgIC8vIHJlbW92ZSBtZXRob2QgJiBmYWxsYmFjawogICAgICAgIGFycmF5X3NoaWZ0KCRhcmdzKTsKICAgICAgICAkZmFsbGJhY2sgPSBhcnJheV9wb3AoJGFyZ3MpOwoKICAgICAgICBpZiAoJHRoaXMtPmZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIGlmICghaXNfd3JpdGFibGUoJHRoaXMtPmZpbGUtPmdldFBhdGgoKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgZmlsZSAiJXMiIGlzIG5vdCB3cml0YWJsZS4nLCAkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghRmlsZXN5c3RlbTo6aXNSZWFkYWJsZSgkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1RoZSBmaWxlICIlcyIgaXMgbm90IHJlYWRhYmxlLicsICR0aGlzLT5maWxlLT5nZXRQYXRoKCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoJHRoaXMtPmZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5hdXRoQ29uZmlnKSB7CiAgICAgICAgICAgICRjb250ZW50cyA9ICJ7XG59XG4iOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb250ZW50cyA9ICJ7XG4gICAgXCJjb25maWdcIjoge1xuICAgIH1cbn1cbiI7CiAgICAgICAgfQoKICAgICAgICAkbWFuaXB1bGF0b3IgPSBuZXcgSnNvbk1hbmlwdWxhdG9yKCRjb250ZW50cyk7CgogICAgICAgICRuZXdGaWxlID0gISR0aGlzLT5maWxlLT5leGlzdHMoKTsKCiAgICAgICAgLy8gb3ZlcnJpZGUgbWFuaXB1bGF0b3IgbWV0aG9kIGZvciBhdXRoIGNvbmZpZyBmaWxlcwogICAgICAgIGlmICgkdGhpcy0+YXV0aENvbmZpZyAmJiAkbWV0aG9kID09PSAnYWRkQ29uZmlnU2V0dGluZycpIHsKICAgICAgICAgICAgJG1ldGhvZCA9ICdhZGRTdWJOb2RlJzsKICAgICAgICAgICAgbGlzdCgkbWFpbk5vZGUsICRuYW1lKSA9IGV4cGxvZGUoJy4nLCAkYXJnc1swXSwgMik7CiAgICAgICAgICAgICRhcmdzID0gYXJyYXkoJG1haW5Ob2RlLCAkbmFtZSwgJGFyZ3NbMV0pOwogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+YXV0aENvbmZpZyAmJiAkbWV0aG9kID09PSAncmVtb3ZlQ29uZmlnU2V0dGluZycpIHsKICAgICAgICAgICAgJG1ldGhvZCA9ICdyZW1vdmVTdWJOb2RlJzsKICAgICAgICAgICAgbGlzdCgkbWFpbk5vZGUsICRuYW1lKSA9IGV4cGxvZGUoJy4nLCAkYXJnc1swXSwgMik7CiAgICAgICAgICAgICRhcmdzID0gYXJyYXkoJG1haW5Ob2RlLCAkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvLyB0cnkgdG8gdXBkYXRlIGNsZWFubHkKICAgICAgICBpZiAoY2FsbF91c2VyX2Z1bmNfYXJyYXkoYXJyYXkoJG1hbmlwdWxhdG9yLCAkbWV0aG9kKSwgJGFyZ3MpKSB7CiAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCR0aGlzLT5maWxlLT5nZXRQYXRoKCksICRtYW5pcHVsYXRvci0+Z2V0Q29udGVudHMoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gb24gZmFpbGVkIGNsZWFuIHVwZGF0ZSwgY2FsbCB0aGUgZmFsbGJhY2sgYW5kIHJld3JpdGUgdGhlIHdob2xlIGZpbGUKICAgICAgICAgICAgJGNvbmZpZyA9ICR0aGlzLT5maWxlLT5yZWFkKCk7CiAgICAgICAgICAgICR0aGlzLT5hcnJheVVuc2hpZnRSZWYoJGFyZ3MsICRjb25maWcpOwogICAgICAgICAgICBjYWxsX3VzZXJfZnVuY19hcnJheSgkZmFsbGJhY2ssICRhcmdzKTsKICAgICAgICAgICAgLy8gYXZvaWQgZW5kaW5nIHVwIHdpdGggYXJyYXlzIGZvciBrZXlzIHRoYXQgc2hvdWxkIGJlIG9iamVjdHMKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3JlcXVpcmUnLCAncmVxdWlyZS1kZXYnLCAnY29uZmxpY3QnLCAncHJvdmlkZScsICdyZXBsYWNlJywgJ3N1Z2dlc3QnLCAnY29uZmlnJywgJ2F1dG9sb2FkJywgJ2F1dG9sb2FkLWRldicsICdzY3JpcHRzJywgJ3NjcmlwdHMtZGVzY3JpcHRpb25zJywgJ3N1cHBvcnQnKSBhcyAkcHJvcCkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJHByb3BdKSAmJiAkY29uZmlnWyRwcm9wXSA9PT0gYXJyYXkoKSkgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJHByb3BdID0gbmV3IFxzdGRDbGFzczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoIChhcnJheSgncHNyLTAnLCAncHNyLTQnKSBhcyAkcHJvcCkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2F1dG9sb2FkJ11bJHByb3BdKSAmJiAkY29uZmlnWydhdXRvbG9hZCddWyRwcm9wXSA9PT0gYXJyYXkoKSkgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ2F1dG9sb2FkJ11bJHByb3BdID0gbmV3IFxzdGRDbGFzczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWydhdXRvbG9hZC1kZXYnXVskcHJvcF0pICYmICRjb25maWdbJ2F1dG9sb2FkLWRldiddWyRwcm9wXSA9PT0gYXJyYXkoKSkgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ2F1dG9sb2FkLWRldiddWyRwcm9wXSA9IG5ldyBcc3RkQ2xhc3M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3BsYXRmb3JtJywgJ2h0dHAtYmFzaWMnLCAnYmVhcmVyJywgJ2dpdGxhYi10b2tlbicsICdnaXRsYWItb2F1dGgnLCAnZ2l0aHViLW9hdXRoJywgJ3ByZWZlcnJlZC1pbnN0YWxsJykgYXMgJHByb3ApIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWydjb25maWcnXVskcHJvcF0pICYmICRjb25maWdbJ2NvbmZpZyddWyRwcm9wXSA9PT0gYXJyYXkoKSkgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ2NvbmZpZyddWyRwcm9wXSA9IG5ldyBcc3RkQ2xhc3M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmZpbGUtPndyaXRlKCRjb25maWcpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHRoaXMtPmZpbGUtPnZhbGlkYXRlU2NoZW1hKEpzb25GaWxlOjpMQVhfU0NIRU1BKTsKICAgICAgICB9IGNhdGNoIChKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAvLyByZXN0b3JlIGNvbnRlbnRzIHRvIHRoZSBvcmlnaW5hbCBzdGF0ZQogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpLCAkY29udGVudHMpOwogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byB1cGRhdGUgY29tcG9zZXIuanNvbiB3aXRoIGEgdmFsaWQgZm9ybWF0LCByZXZlcnRpbmcgdG8gdGhlIG9yaWdpbmFsIGNvbnRlbnQuIFBsZWFzZSByZXBvcnQgYW4gaXNzdWUgdG8gdXMgd2l0aCBkZXRhaWxzIChjb21tYW5kIHlvdSBydW4gYW5kIGEgY29weSBvZiB5b3VyIGNvbXBvc2VyLmpzb24pLiAnLlBIUF9FT0wuaW1wbG9kZShQSFBfRU9MLCAkZS0+Z2V0RXJyb3JzKCkpLCAwLCAkZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG5ld0ZpbGUpIHsKICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2NobW9kJywgJHRoaXMtPmZpbGUtPmdldFBhdGgoKSwgMDYwMCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUHJlcGVuZCBhIHJlZmVyZW5jZSB0byBhbiBlbGVtZW50IHRvIHRoZSBiZWdpbm5pbmcgb2YgYW4gYXJyYXkuCiAgICAgKgogICAgICogQHBhcmFtICBtaXhlZFtdICRhcnJheQogICAgICogQHBhcmFtICBtaXhlZCAkdmFsdWUKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYXJyYXlVbnNoaWZ0UmVmKCYkYXJyYXksICYkdmFsdWUpCiAgICB7CiAgICAgICAgJHJldHVybiA9IGFycmF5X3Vuc2hpZnQoJGFycmF5LCAnJyk7CiAgICAgICAgJGFycmF5WzBdID0gJiR2YWx1ZTsKCiAgICAgICAgcmV0dXJuICRyZXR1cm47CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyXEFyY2hpdmFibGVGaWxlc0ZpbmRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcRHVtcGVyXEFycmF5RHVtcGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25HdWVzc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbVxFeGNlcHRpb25cSU9FeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEZpbGVzeXN0ZW0gYXMgU3ltZm9ueUZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVuaW5zdGFsbE9wZXJhdGlvbjsKCi8qKgogKiBEb3dubG9hZCBhIHBhY2thZ2UgZnJvbSBhIGxvY2FsIHBhdGguCiAqCiAqIEBhdXRob3IgU2FtdWVsIFJvemUgPHNhbXVlbC5yb3plQGdtYWlsLmNvbT4KICogQGF1dGhvciBKb2hhbm4gUmVpbmtlIDxqb2hhbm4ucmVpbmtlQGdtYWlsLmNvbT4KICovCmNsYXNzIFBhdGhEb3dubG9hZGVyIGV4dGVuZHMgRmlsZURvd25sb2FkZXIgaW1wbGVtZW50cyBWY3NDYXBhYmxlRG93bmxvYWRlckludGVyZmFjZQp7CiAgICBjb25zdCBTVFJBVEVHWV9TWU1MSU5LID0gMTA7CiAgICBjb25zdCBTVFJBVEVHWV9NSVJST1IgPSAyMDsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsLCAkb3V0cHV0ID0gdHJ1ZSkKICAgIHsKICAgICAgICAkcGF0aCA9IEZpbGVzeXN0ZW06OnRyaW1UcmFpbGluZ1NsYXNoKCRwYXRoKTsKICAgICAgICAkdXJsID0gJHBhY2thZ2UtPmdldERpc3RVcmwoKTsKICAgICAgICAkcmVhbFVybCA9IHJlYWxwYXRoKCR1cmwpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJHJlYWxVcmwgfHwgIWZpbGVfZXhpc3RzKCRyZWFsVXJsKSB8fCAhaXNfZGlyKCRyZWFsVXJsKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICdTb3VyY2UgcGF0aCAiJXMiIGlzIG5vdCBmb3VuZCBmb3IgcGFja2FnZSAlcycsCiAgICAgICAgICAgICAgICAkdXJsLAogICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldE5hbWUoKQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgIGlmIChyZWFscGF0aCgkcGF0aCkgPT09ICRyZWFsVXJsKSB7CiAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKHJlYWxwYXRoKCRwYXRoKSAuIERJUkVDVE9SWV9TRVBBUkFUT1IsICRyZWFsVXJsIC4gRElSRUNUT1JZX1NFUEFSQVRPUikgPT09IDApIHsKICAgICAgICAgICAgLy8gSU1QT1JUQU5UIE5PVElDRTogSWYgeW91IHdpc2ggdG8gY2hhbmdlIHRoaXMsIGRvbid0LiBZb3UgYXJlIHdhc3RpbmcgeW91ciB0aW1lIGFuZCBvdXJzLgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBQbGVhc2Ugc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9wdWxsLzU5NzQgYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9wdWxsLzYxNzQKICAgICAgICAgICAgLy8gZm9yIHByZXZpb3VzIGF0dGVtcHRzIHRoYXQgd2VyZSBzaHV0IGRvd24gYmVjYXVzZSB0aGV5IGRpZCBub3Qgd29yayB3ZWxsIGVub3VnaCBvciBpbnRyb2R1Y2VkIHRvbyBtYW55IHJpc2tzLgogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICdQYWNrYWdlICVzIGNhbm5vdCBpbnN0YWxsIHRvICIlcyIgaW5zaWRlIGl0cyBzb3VyY2UgYXQgIiVzIicsCiAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0TmFtZSgpLAogICAgICAgICAgICAgICAgcmVhbHBhdGgoJHBhdGgpLAogICAgICAgICAgICAgICAgJHJlYWxVcmwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgICRwYXRoID0gRmlsZXN5c3RlbTo6dHJpbVRyYWlsaW5nU2xhc2goJHBhdGgpOwogICAgICAgICR1cmwgPSAkcGFja2FnZS0+Z2V0RGlzdFVybCgpOwogICAgICAgICRyZWFsVXJsID0gcmVhbHBhdGgoJHVybCk7CgogICAgICAgIGlmIChyZWFscGF0aCgkcGF0aCkgPT09ICRyZWFsVXJsKSB7CiAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gSW5zdGFsbE9wZXJhdGlvbjo6Zm9ybWF0KCRwYWNrYWdlKSAuICR0aGlzLT5nZXRJbnN0YWxsT3BlcmF0aW9uQXBwZW5kaXgoJHBhY2thZ2UsICRwYXRoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBHZXQgdGhlIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggZGVmYXVsdCB2YWx1ZXMKICAgICAgICAkdHJhbnNwb3J0T3B0aW9ucyA9ICRwYWNrYWdlLT5nZXRUcmFuc3BvcnRPcHRpb25zKCkgKyBhcnJheSgncmVsYXRpdmUnID0+IHRydWUpOwoKICAgICAgICBsaXN0KCRjdXJyZW50U3RyYXRlZ3ksICRhbGxvd2VkU3RyYXRlZ2llcykgPSAkdGhpcy0+Y29tcHV0ZUFsbG93ZWRTdHJhdGVnaWVzKCR0cmFuc3BvcnRPcHRpb25zKTsKCiAgICAgICAgJHN5bWZvbnlGaWxlc3lzdGVtID0gbmV3IFN5bWZvbnlGaWxlc3lzdGVtKCk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkcGF0aCk7CgogICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBJbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpLic6ICcsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgICRpc0ZhbGxiYWNrID0gZmFsc2U7CiAgICAgICAgaWYgKHNlbGY6OlNUUkFURUdZX1NZTUxJTksgPT09ICRjdXJyZW50U3RyYXRlZ3kpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbXBsZW1lbnQgc3ltbGlua3MgYXMgTlRGUyBqdW5jdGlvbnMgb24gV2luZG93cwogICAgICAgICAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCdKdW5jdGlvbmluZyBmcm9tICVzJywgJHVybCksIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmp1bmN0aW9uKCRyZWFsVXJsLCAkcGF0aCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRhYnNvbHV0ZVBhdGggPSAkcGF0aDsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5maWxlc3lzdGVtLT5pc0Fic29sdXRlUGF0aCgkYWJzb2x1dGVQYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYWJzb2x1dGVQYXRoID0gZ2V0Y3dkKCkgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJHBhdGg7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRzaG9ydGVzdFBhdGggPSAkdGhpcy0+ZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aCgkYWJzb2x1dGVQYXRoLCAkcmVhbFVybCk7CiAgICAgICAgICAgICAgICAgICAgJHBhdGggPSBydHJpbSgkcGF0aCwgIi8iKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignU3ltbGlua2luZyBmcm9tICVzJywgJHVybCksIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0cmFuc3BvcnRPcHRpb25zWydyZWxhdGl2ZSddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzeW1mb255RmlsZXN5c3RlbS0+c3ltbGluaygkc2hvcnRlc3RQYXRoLCAkcGF0aCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHN5bWZvbnlGaWxlc3lzdGVtLT5zeW1saW5rKCRyZWFsVXJsLCAkcGF0aCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KHNlbGY6OlNUUkFURUdZX01JUlJPUiwgJGFsbG93ZWRTdHJhdGVnaWVzKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIDxlcnJvcj5TeW1saW5rIGZhaWxlZCwgZmFsbGJhY2sgdG8gdXNlIG1pcnJvcmluZyE8L2Vycm9yPicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfTUlSUk9SOwogICAgICAgICAgICAgICAgICAgICRpc0ZhbGxiYWNrID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1N5bWxpbmsgZnJvbSAiJXMiIHRvICIlcyIgZmFpbGVkIScsICRyZWFsVXJsLCAkcGF0aCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBGYWxsYmFjayBpZiBzeW1saW5rIGZhaWxlZCBvciBpZiBzeW1saW5rIGlzIG5vdCBhbGxvd2VkIGZvciB0aGUgcGFja2FnZQogICAgICAgIGlmIChzZWxmOjpTVFJBVEVHWV9NSVJST1IgPT09ICRjdXJyZW50U3RyYXRlZ3kpIHsKICAgICAgICAgICAgJHJlYWxVcmwgPSAkdGhpcy0+ZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aCgkcmVhbFVybCk7CgogICAgICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJyVzTWlycm9yaW5nIGZyb20gJXMnLCAkaXNGYWxsYmFjayA/ICcgICAgJyA6ICcnLCAkdXJsKSwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRpdGVyYXRvciA9IG5ldyBBcmNoaXZhYmxlRmlsZXNGaW5kZXIoJHJlYWxVcmwsIGFycmF5KCkpOwogICAgICAgICAgICAkc3ltZm9ueUZpbGVzeXN0ZW0tPm1pcnJvcigkcmVhbFVybCwgJHBhdGgsICRpdGVyYXRvcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgICRwYXRoID0gRmlsZXN5c3RlbTo6dHJpbVRyYWlsaW5nU2xhc2goJHBhdGgpOwogICAgICAgIC8qKgogICAgICAgICAqIHJlYWxwYXRoKCkgbWF5IHJlc29sdmUgV2luZG93cyBqdW5jdGlvbnMgdG8gdGhlIHNvdXJjZSBwYXRoLCBzbyB3ZSdsbCBjaGVjayBmb3IgYSBqdW5jdGlvbiBmaXJzdAogICAgICAgICAqIHRvIHByZXZlbnQgYSBmYWxzZSBwb3NpdGl2ZSB3aGVuIGNoZWNraW5nIGlmIHRoZSBkaXN0IGFuZCBpbnN0YWxsIHBhdGhzIGFyZSB0aGUgc2FtZS4KICAgICAgICAgKiBTZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD03NzYzOQogICAgICAgICAqCiAgICAgICAgICogRm9yIGp1bmN0aW9ucyBkb24ndCBibGluZGx5IHJlbHkgb24gRmlsZXN5c3RlbTo6cmVtb3ZlRGlyZWN0b3J5IGFzIGl0IG1heSBiZSBvdmVyemVhbG91cy4gSWYgYSBwcm9jZXNzCiAgICAgICAgICogaW5hZHZlcnRlbnRseSBsb2NrcyB0aGUgZmlsZSB0aGUgcmVtb3ZhbCB3aWxsIGZhaWwsIGJ1dCBpdCB3b3VsZCBmYWxsIGJhY2sgdG8gcmVjdXJzaXZlIGRlbGV0ZSB3aGljaAogICAgICAgICAqIGlzIGRpc2FzdHJvdXMgd2l0aGluIGEganVuY3Rpb24uIFNvIGluIHRoYXQgY2FzZSB3ZSBoYXZlIG5vIG90aGVyIHJlYWwgY2hvaWNlIGJ1dCB0byBmYWlsIGhhcmQuCiAgICAgICAgICovCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiAkdGhpcy0+ZmlsZXN5c3RlbS0+aXNKdW5jdGlvbigkcGF0aCkpIHsKICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBVbmluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkuIiwgc291cmNlIGlzIHN0aWxsIHByZXNlbnQgaW4gJHBhdGgiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVKdW5jdGlvbigkcGF0aCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAgIDx3YXJuaW5nPkNvdWxkIG5vdCByZW1vdmUganVuY3Rpb24gYXQgIiAuICRwYXRoIC4gIiAtIGlzIGFub3RoZXIgcHJvY2VzcyBsb2NraW5nIGl0Pzwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHJlbGlhYmx5IHJlbW92ZSBqdW5jdGlvbiBmb3IgcGFja2FnZSAnIC4gJHBhY2thZ2UtPmdldE5hbWUoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBlbnN1cmUgdGhhdCB0aGUgc291cmNlIHBhdGggKGRpc3QgdXJsKSBpcyBub3QgdGhlIHNhbWUgYXMgdGhlIGluc3RhbGwgcGF0aCwgd2hpY2gKICAgICAgICAvLyBjYW4gaGFwcGVuIHdoZW4gdXNpbmcgY3VzdG9tIGluc3RhbGxlcnMsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC85MTE2CiAgICAgICAgLy8gbm90IHVzaW5nIHJlYWxwYXRoIGhlcmUgYXMgd2UgZG8gbm90IHdhbnQgdG8gcmVzb2x2ZSB0aGUgc3ltbGluayB0byB0aGUgb3JpZ2luYWwgZGlzdCB1cmwKICAgICAgICAvLyBpdCBwb2ludHMgdG8KICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbTsKICAgICAgICAkYWJzUGF0aCA9ICRmcy0+aXNBYnNvbHV0ZVBhdGgoJHBhdGgpID8gJHBhdGggOiBnZXRjd2QoKSAuICcvJyAuICRwYXRoOwogICAgICAgICRhYnNEaXN0VXJsID0gJGZzLT5pc0Fic29sdXRlUGF0aCgkcGFja2FnZS0+Z2V0RGlzdFVybCgpKSA/ICRwYWNrYWdlLT5nZXREaXN0VXJsKCkgOiBnZXRjd2QoKSAuICcvJyAuICRwYWNrYWdlLT5nZXREaXN0VXJsKCk7CiAgICAgICAgaWYgKCRmcy0+bm9ybWFsaXplUGF0aCgkYWJzUGF0aCkgPT09ICRmcy0+bm9ybWFsaXplUGF0aCgkYWJzRGlzdFVybCkpIHsKICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBVbmluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkuIiwgc291cmNlIGlzIHN0aWxsIHByZXNlbnQgaW4gJHBhdGgiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OnJlbW92ZSgkcGFja2FnZSwgJHBhdGgsICRvdXRwdXQpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZjc1JlZmVyZW5jZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9IEZpbGVzeXN0ZW06OnRyaW1UcmFpbGluZ1NsYXNoKCRwYXRoKTsKICAgICAgICAkcGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgJGd1ZXNzZXIgPSBuZXcgVmVyc2lvbkd1ZXNzZXIoJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MsICRwYXJzZXIpOwogICAgICAgICRkdW1wZXIgPSBuZXcgQXJyYXlEdW1wZXI7CgogICAgICAgICRwYWNrYWdlQ29uZmlnID0gJGR1bXBlci0+ZHVtcCgkcGFja2FnZSk7CiAgICAgICAgaWYgKCRwYWNrYWdlVmVyc2lvbiA9ICRndWVzc2VyLT5ndWVzc1ZlcnNpb24oJHBhY2thZ2VDb25maWcsICRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gJHBhY2thZ2VWZXJzaW9uWydjb21taXQnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEluc3RhbGxPcGVyYXRpb25BcHBlbmRpeChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICAkcmVhbFVybCA9IHJlYWxwYXRoKCRwYWNrYWdlLT5nZXREaXN0VXJsKCkpOwoKICAgICAgICBpZiAocmVhbHBhdGgoJHBhdGgpID09PSAkcmVhbFVybCkgewogICAgICAgICAgICByZXR1cm4gJzogU291cmNlIGFscmVhZHkgcHJlc2VudCc7CiAgICAgICAgfQoKICAgICAgICBsaXN0KCRjdXJyZW50U3RyYXRlZ3kpID0gJHRoaXMtPmNvbXB1dGVBbGxvd2VkU3RyYXRlZ2llcygkcGFja2FnZS0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpKTsKCiAgICAgICAgaWYgKCRjdXJyZW50U3RyYXRlZ3kgPT09IHNlbGY6OlNUUkFURUdZX1NZTUxJTkspIHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICc6IEp1bmN0aW9uaW5nIGZyb20gJy4kcGFja2FnZS0+Z2V0RGlzdFVybCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJzogU3ltbGlua2luZyBmcm9tICcuJHBhY2thZ2UtPmdldERpc3RVcmwoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnOiBNaXJyb3JpbmcgZnJvbSAnLiRwYWNrYWdlLT5nZXREaXN0VXJsKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkdHJhbnNwb3J0T3B0aW9ucwogICAgICoKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheXtzZWxmOjpTVFJBVEVHWV8qLCBub24tZW1wdHktbGlzdDxzZWxmOjpTVFJBVEVHWV8qPn0KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjb21wdXRlQWxsb3dlZFN0cmF0ZWdpZXMoYXJyYXkgJHRyYW5zcG9ydE9wdGlvbnMpCiAgICB7CiAgICAgICAgLy8gV2hlbiBzeW1saW5rIHRyYW5zcG9ydCBvcHRpb24gaXMgbnVsbCwgYm90aCBzeW1saW5rIGFuZCBtaXJyb3IgYXJlIGFsbG93ZWQKICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfU1lNTElOSzsKICAgICAgICAkYWxsb3dlZFN0cmF0ZWdpZXMgPSBhcnJheShzZWxmOjpTVFJBVEVHWV9TWU1MSU5LLCBzZWxmOjpTVFJBVEVHWV9NSVJST1IpOwoKICAgICAgICAkbWlycm9yUGF0aFJlcG9zID0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfTUlSUk9SX1BBVEhfUkVQT1MnKTsKICAgICAgICBpZiAoJG1pcnJvclBhdGhSZXBvcykgewogICAgICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfTUlSUk9SOwogICAgICAgIH0KCiAgICAgICAgJHN5bWxpbmtPcHRpb24gPSBpc3NldCgkdHJhbnNwb3J0T3B0aW9uc1snc3ltbGluayddKSA/ICR0cmFuc3BvcnRPcHRpb25zWydzeW1saW5rJ10gOiBudWxsOwoKICAgICAgICBpZiAodHJ1ZSA9PT0gJHN5bWxpbmtPcHRpb24pIHsKICAgICAgICAgICAgJGN1cnJlbnRTdHJhdGVneSA9IHNlbGY6OlNUUkFURUdZX1NZTUxJTks7CiAgICAgICAgICAgICRhbGxvd2VkU3RyYXRlZ2llcyA9IGFycmF5KHNlbGY6OlNUUkFURUdZX1NZTUxJTkspOwogICAgICAgIH0gZWxzZWlmIChmYWxzZSA9PT0gJHN5bWxpbmtPcHRpb24pIHsKICAgICAgICAgICAgJGN1cnJlbnRTdHJhdGVneSA9IHNlbGY6OlNUUkFURUdZX01JUlJPUjsKICAgICAgICAgICAgJGFsbG93ZWRTdHJhdGVnaWVzID0gYXJyYXkoc2VsZjo6U1RSQVRFR1lfTUlSUk9SKTsKICAgICAgICB9CgogICAgICAgIC8vIENoZWNrIHdlIGNhbiB1c2UganVuY3Rpb25zIHNhZmVseSBpZiB3ZSBhcmUgb24gV2luZG93cwogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgc2VsZjo6U1RSQVRFR1lfU1lNTElOSyA9PT0gJGN1cnJlbnRTdHJhdGVneSAmJiAhJHRoaXMtPnNhZmVKdW5jdGlvbnMoKSkgewogICAgICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfTUlSUk9SOwogICAgICAgICAgICAkYWxsb3dlZFN0cmF0ZWdpZXMgPSBhcnJheShzZWxmOjpTVFJBVEVHWV9NSVJST1IpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCRjdXJyZW50U3RyYXRlZ3ksICRhbGxvd2VkU3RyYXRlZ2llcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYganVuY3Rpb25zIGNhbiBiZSBjcmVhdGVkIGFuZCBzYWZlbHkgdXNlZCBvbiBXaW5kb3dzCiAgICAgKgogICAgICogQSBQSFAgYnVnIG1ha2VzIGp1bmN0aW9uIGRldGVjdGlvbiBmcmFnaWxlLCBsZWFkaW5nIHRvIHBvc3NpYmxlIGRhdGEgbG9zcwogICAgICogd2hlbiByZW1vdmluZyBhIHBhY2thZ2UuIFNlZSBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTc3NTUyCiAgICAgKgogICAgICogRm9yIHNhZmV0eSB3ZSByZXF1aXJlIGEgbWluaW11bSB2ZXJzaW9uIG9mIFdpbmRvd3MgNywgc28gd2UgY2FuIGNhbGwgdGhlCiAgICAgKiBzeXN0ZW0gcm1kaXIgd2hpY2ggd2lsbCBwcmVzZXJ2ZSB0YXJnZXQgY29udGVudCBpZiBnaXZlbiBhIGp1bmN0aW9uLgogICAgICoKICAgICAqIFRoZSBQSFAgYnVnIHdhcyBmaXhlZCBpbiA3LjIuMTYgYW5kIDcuMy4zIChyZXF1aXJlcyBhdCBsZWFzdCBXaW5kb3dzIDcpLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNhZmVKdW5jdGlvbnMoKQogICAgewogICAgICAgIC8vIFdlIG5lZWQgdG8gY2FsbCBta2xpbmssIGFuZCBybWRpciBvbiBXaW5kb3dzIDcgKHZlcnNpb24gNi4xKQogICAgICAgIHJldHVybiBmdW5jdGlvbl9leGlzdHMoJ3Byb2Nfb3BlbicpICYmCiAgICAgICAgICAgIChQSFBfV0lORE9XU19WRVJTSU9OX01BSk9SID4gNiB8fAogICAgICAgICAgICAoUEhQX1dJTkRPV1NfVkVSU0lPTl9NQUpPUiA9PT0gNiAmJiBQSFBfV0lORE9XU19WRVJTSU9OX01JTk9SID49IDEpKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwoKLyoqCiAqIEBhdXRob3IgQm9od2FaIDxodHRwOi8vYm9od2F6Lm5ldC8+CiAqLwpjbGFzcyBGb3NzaWxEb3dubG9hZGVyIGV4dGVuZHMgVmNzRG93bmxvYWRlcgp7CiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0Rvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgLy8gRW5zdXJlIHdlIGFyZSBhbGxvd2VkIHRvIHVzZSB0aGlzIFVSTCBieSBjb25maWcKICAgICAgICAkdGhpcy0+Y29uZmlnLT5wcm9oaWJpdFVybEJ5Q29uZmlnKCR1cmwsICR0aGlzLT5pbyk7CgogICAgICAgICR1cmwgPSBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKTsKICAgICAgICAkcmVmID0gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKTsKICAgICAgICAkcmVwb0ZpbGUgPSAkcGF0aCAuICcuZm9zc2lsJzsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIkNsb25pbmcgIi4kcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZm9zc2lsIGNsb25lIC0tICVzICVzJywgJHVybCwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHJlcG9GaWxlKSk7CiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZm9zc2lsIG9wZW4gLS1uZXN0ZWQgLS0gJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVwb0ZpbGUpKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0LCByZWFscGF0aCgkcGF0aCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KICAgICAgICAkY29tbWFuZCA9IHNwcmludGYoJ2Zvc3NpbCB1cGRhdGUgLS0gJXMnLCAkcmVmKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0LCByZWFscGF0aCgkcGF0aCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1VwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgIC8vIEVuc3VyZSB3ZSBhcmUgYWxsb3dlZCB0byB1c2UgdGhpcyBVUkwgYnkgY29uZmlnCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdXJsLCAkdGhpcy0+aW8pOwoKICAgICAgICAkcmVmID0gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiIFVwZGF0aW5nIHRvICIuJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwoKICAgICAgICBpZiAoISR0aGlzLT5oYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIC5mc2xja291dCBmaWxlIGlzIG1pc3NpbmcgZnJvbSAnLiRwYXRoLicsIHNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9jb21taXQtZGVwcyBmb3IgbW9yZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdmb3NzaWwgcHVsbCAmJiBmb3NzaWwgdXAgJXMnLCAkcmVmKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0LCByZWFscGF0aCgkcGF0aCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdmb3NzaWwgY2hhbmdlcycsICRvdXRwdXQsIHJlYWxwYXRoKCRwYXRoKSk7CgogICAgICAgIHJldHVybiB0cmltKCRvdXRwdXQpID86IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q29tbWl0TG9ncygkZnJvbVJlZmVyZW5jZSwgJHRvUmVmZXJlbmNlLCAkcGF0aCkKICAgIHsKICAgICAgICAkY29tbWFuZCA9IHNwcmludGYoJ2Zvc3NpbCB0aW1lbGluZSAtdCBjaSAtVyAwIC1uIDAgYmVmb3JlICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRvUmVmZXJlbmNlKSk7CgogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJG91dHB1dCwgcmVhbHBhdGgoJHBhdGgpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CgogICAgICAgICRsb2cgPSAnJzsKICAgICAgICAkbWF0Y2ggPSAnL1xkXGQ6XGRcZDpcZFxkXHMrXFsnIC4gJHRvUmVmZXJlbmNlIC4gJ1xdLyc7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRsaW5lKSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRtYXRjaCwgJGxpbmUpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbG9nIC49ICRsaW5lOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRsb2c7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKQogICAgewogICAgICAgIHJldHVybiBpc19maWxlKCRwYXRoIC4gJy8uZnNsY2tvdXQnKSB8fCBpc19maWxlKCRwYXRoIC4gJy9fRk9TU0lMXycpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEhnIGFzIEhnVXRpbHM7CgovKioKICogQGF1dGhvciBQZXIgQmVybmhhcmR0IDxwbGJAd2ViZmFjdG9yeS5kZT4KICovCmNsYXNzIEhnRG93bmxvYWRlciBleHRlbmRzIFZjc0Rvd25sb2FkZXIKewogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Eb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSBIZ1V0aWxzOjpnZXRWZXJzaW9uKCR0aGlzLT5wcm9jZXNzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ2hnIHdhcyBub3QgZm91bmQgaW4geW91ciBQQVRILCBza2lwcGluZyBzb3VyY2UgZG93bmxvYWQnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9JbnN0YWxsKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgICRoZ1V0aWxzID0gbmV3IEhnVXRpbHMoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CgogICAgICAgICRjbG9uZUNvbW1hbmQgPSBmdW5jdGlvbiAoJHVybCkgdXNlICgkcGF0aCkgewogICAgICAgICAgICByZXR1cm4gc3ByaW50ZignaGcgY2xvbmUgLS0gJXMgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhdGgpKTsKICAgICAgICB9OwoKICAgICAgICAkaGdVdGlscy0+cnVuQ29tbWFuZCgkY2xvbmVDb21tYW5kLCAkdXJsLCAkcGF0aCk7CgogICAgICAgICRyZWYgPSBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignaGcgdXAgLS0gJXMnLCAkcmVmKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0LCByZWFscGF0aCgkcGF0aCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1VwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgICRoZ1V0aWxzID0gbmV3IEhnVXRpbHMoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CgogICAgICAgICRyZWYgPSAkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiBVcGRhdGluZyB0byAiLiR0YXJnZXQtPmdldFNvdXJjZVJlZmVyZW5jZSgpKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSAuaGcgZGlyZWN0b3J5IGlzIG1pc3NpbmcgZnJvbSAnLiRwYXRoLicsIHNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9jb21taXQtZGVwcyBmb3IgbW9yZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmQgPSBmdW5jdGlvbiAoJHVybCkgdXNlICgkcmVmKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdoZyBwdWxsIC0tICVzICYmIGhnIHVwIC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRyZWYpKTsKICAgICAgICB9OwoKICAgICAgICAkaGdVdGlscy0+cnVuQ29tbWFuZCgkY29tbWFuZCwgJHVybCwgJHBhdGgpOwoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2FsQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICBpZiAoIWlzX2RpcigkcGF0aC4nLy5oZycpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIHN0JywgJG91dHB1dCwgcmVhbHBhdGgoJHBhdGgpKTsKCiAgICAgICAgcmV0dXJuIHRyaW0oJG91dHB1dCkgPzogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDb21taXRMb2dzKCRmcm9tUmVmZXJlbmNlLCAkdG9SZWZlcmVuY2UsICRwYXRoKQogICAgewogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignaGcgbG9nIC1yICVzOiVzIC0tc3R5bGUgY29tcGFjdCcsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRmcm9tUmVmZXJlbmNlKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRvUmVmZXJlbmNlKSk7CgogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJG91dHB1dCwgcmVhbHBhdGgoJHBhdGgpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gaXNfZGlyKCRwYXRoIC4gJy8uaGcnKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKCi8qKgogKiBHWmlwIGFyY2hpdmUgZG93bmxvYWRlci4KICoKICogQGF1dGhvciBQYXZlbCBQdWNoa2luIDxpQG5lb2FzY2V0aWMubWU+CiAqLwpjbGFzcyBHemlwRG93bmxvYWRlciBleHRlbmRzIEFyY2hpdmVEb3dubG9hZGVyCnsKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleHRyYWN0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRmaWxlLCAkcGF0aCkKICAgIHsKICAgICAgICAkZmlsZW5hbWUgPSBwYXRoaW5mbyhwYXJzZV91cmwoJHBhY2thZ2UtPmdldERpc3RVcmwoKSwgUEhQX1VSTF9QQVRIKSwgUEFUSElORk9fRklMRU5BTUUpOwogICAgICAgICR0YXJnZXRGaWxlcGF0aCA9ICRwYXRoIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRmaWxlbmFtZTsKCiAgICAgICAgLy8gVHJ5IHRvIHVzZSBndW56aXAgb24gKm5peAogICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICRjb21tYW5kID0gJ2d6aXAgLWNkIC0tICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkgLiAnID4gJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0YXJnZXRGaWxlcGF0aCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ3psaWInKSkgewogICAgICAgICAgICAgICAgLy8gRmFsbGJhY2sgdG8gdXNpbmcgdGhlIFBIUCBleHRlbnNpb24uCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXh0cmFjdFVzaW5nRXh0KCRmaWxlLCAkdGFyZ2V0RmlsZXBhdGgpOwoKICAgICAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwcm9jZXNzRXJyb3IgPSAnRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkcHJvY2Vzc0Vycm9yKTsKICAgICAgICB9CgogICAgICAgIC8vIFdpbmRvd3MgdmVyc2lvbiBvZiBQSFAgaGFzIGJ1aWx0LWluIHN1cHBvcnQgb2YgZ3ppcCBmdW5jdGlvbnMKICAgICAgICAkdGhpcy0+ZXh0cmFjdFVzaW5nRXh0KCRmaWxlLCAkdGFyZ2V0RmlsZXBhdGgpOwoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0RmlsZXBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBleHRyYWN0VXNpbmdFeHQoJGZpbGUsICR0YXJnZXRGaWxlcGF0aCkKICAgIHsKICAgICAgICAkYXJjaGl2ZUZpbGUgPSBnem9wZW4oJGZpbGUsICdyYicpOwogICAgICAgICR0YXJnZXRGaWxlID0gZm9wZW4oJHRhcmdldEZpbGVwYXRoLCAnd2InKTsKICAgICAgICB3aGlsZSAoJHN0cmluZyA9IGd6cmVhZCgkYXJjaGl2ZUZpbGUsIDQwOTYpKSB7CiAgICAgICAgICAgIGZ3cml0ZSgkdGFyZ2V0RmlsZSwgJHN0cmluZywgUGxhdGZvcm06OnN0cmxlbigkc3RyaW5nKSk7CiAgICAgICAgfQogICAgICAgIGd6Y2xvc2UoJGFyY2hpdmVGaWxlKTsKICAgICAgICBmY2xvc2UoJHRhcmdldEZpbGUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7CgovKioKICogRXhjZXB0aW9uIHRocm93biB3aGVuIGlzc3VlcyBleGlzdCBvbiBsb2NhbCBmaWxlc3lzdGVtCiAqCiAqIEBhdXRob3IgSmF2aWVyIFNwYWdub2xldHRpIDxqc3BhZ25vbGV0dGlAamF2aWVyc3BhZ25vbGV0dGkuY29tLmFyPgogKi8KY2xhc3MgRmlsZXN5c3RlbUV4Y2VwdGlvbiBleHRlbmRzIFxFeGNlcHRpb24KewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRjb2RlCiAgICAgKiBAcGFyYW0gXEV4Y2VwdGlvbnxudWxsICRwcmV2aW91cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UgPSAnJywgJGNvZGUgPSAwLCBcRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgiRmlsZXN5c3RlbSBleGNlcHRpb246IFxuIi4kbWVzc2FnZSwgJGNvZGUsICRwcmV2aW91cyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcRmluZGVyOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uOwoKLyoqCiAqIEJhc2UgZG93bmxvYWRlciBmb3IgYXJjaGl2ZXMKICoKICogQGF1dGhvciBLaXJpbGwgY2hFYmJhIENoZWJ1bmluIDxpYW1AY2hlYmJhLm9yZz4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIEZyYW7Dp29pcyBQbHVjaGlubyA8ZnJhbmNvaXMucGx1Y2hpbm9Ab3BlbmRpc3BsYXkuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgQXJjaGl2ZURvd25sb2FkZXIgZXh0ZW5kcyBGaWxlRG93bmxvYWRlcgp7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCB0cnVlPgogICAgICogQHByb3RlY3RlZAogICAgICovCiAgICBwdWJsaWMgJGNsZWFudXBFeGVjdXRlZCA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICB1bnNldCgkdGhpcy0+Y2xlYW51cEV4ZWN1dGVkWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKCiAgICAgICAgcmV0dXJuIHBhcmVudDo6cHJlcGFyZSgkdHlwZSwgJHBhY2thZ2UsICRwYXRoLCAkcHJldlBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmNsZWFudXBFeGVjdXRlZFskcGFja2FnZS0+Z2V0TmFtZSgpXSA9IHRydWU7CgogICAgICAgIHJldHVybiBwYXJlbnQ6OmNsZWFudXAoJHR5cGUsICRwYWNrYWdlLCAkcGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG91dHB1dAogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEB0aHJvd3MgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJG91dHB1dCA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIEluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkgLiAkdGhpcy0+Z2V0SW5zdGFsbE9wZXJhdGlvbkFwcGVuZGl4KCRwYWNrYWdlLCAkcGF0aCkpOwogICAgICAgIH0KCiAgICAgICAgJHZlbmRvckRpciA9ICR0aGlzLT5jb25maWctPmdldCgndmVuZG9yLWRpcicpOwoKICAgICAgICAvLyBjbGVhbiB1cCB0aGUgdGFyZ2V0IGRpcmVjdG9yeSwgdW5sZXNzIGl0IGNvbnRhaW5zIHRoZSB2ZW5kb3IgZGlyLCBhcyB0aGUgdmVuZG9yIGRpciBjb250YWlucwogICAgICAgIC8vIHRoZSBhcmNoaXZlIHRvIGJlIGV4dHJhY3RlZC4gVGhpcyBpcyB0aGUgY2FzZSB3aGVuIGluc3RhbGxpbmcgd2l0aCBjcmVhdGUtcHJvamVjdCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkKICAgICAgICAvLyBidXQgaW4gdGhhdCBjYXNlIHdlIGVuc3VyZSB0aGUgZGlyZWN0b3J5IGlzIGVtcHR5IGFscmVhZHkgaW4gUHJvamVjdEluc3RhbGxlciBzbyBubyBuZWVkIHRvIGVtcHR5IGl0IGhlcmUuCiAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJHRoaXMtPmZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHZlbmRvckRpciksICR0aGlzLT5maWxlc3lzdGVtLT5ub3JtYWxpemVQYXRoKCRwYXRoLkRJUkVDVE9SWV9TRVBBUkFUT1IpKSkgewogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW1wdHlEaXJlY3RvcnkoJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgZG8gewogICAgICAgICAgICAkdGVtcG9yYXJ5RGlyID0gJHZlbmRvckRpci4nL2NvbXBvc2VyLycuc3Vic3RyKG1kNSh1bmlxaWQoJycsIHRydWUpKSwgMCwgOCk7CiAgICAgICAgfSB3aGlsZSAoaXNfZGlyKCR0ZW1wb3JhcnlEaXIpKTsKCiAgICAgICAgJHRoaXMtPmFkZENsZWFudXBQYXRoKCRwYWNrYWdlLCAkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAvLyBhdm9pZCBjbGVhbmluZyB1cCAkcGF0aCBpZiBpbnN0YWxsaW5nIGluICIuIiBmb3IgZWcgY3JlYXRlLXByb2plY3QgYXMgd2UgY2FuIG5vdAogICAgICAgIC8vIGRlbGV0ZSB0aGUgZGlyZWN0b3J5IHdlIGFyZSBjdXJyZW50bHkgaW4gb24gd2luZG93cwogICAgICAgIGlmICghaXNfZGlyKCRwYXRoKSB8fCByZWFscGF0aCgkcGF0aCkgIT09IGdldGN3ZCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRDbGVhbnVwUGF0aCgkcGFja2FnZSwgJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAkZmlsZU5hbWUgPSAkdGhpcy0+Z2V0RmlsZU5hbWUoJHBhY2thZ2UsICRwYXRoKTsKCiAgICAgICAgJGZpbGVzeXN0ZW0gPSAkdGhpcy0+ZmlsZXN5c3RlbTsKICAgICAgICAkc2VsZiA9ICR0aGlzOwoKICAgICAgICAkY2xlYW51cCA9IGZ1bmN0aW9uICgpIHVzZSAoJHBhdGgsICRmaWxlc3lzdGVtLCAkdGVtcG9yYXJ5RGlyLCAkcGFja2FnZSwgJHNlbGYpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIGNhY2hlIGlmIHRoZSBmaWxlIHdhcyBjb3JydXB0ZWQKICAgICAgICAgICAgJHNlbGYtPmNsZWFyTGFzdENhY2hlV3JpdGUoJHBhY2thZ2UpOwoKICAgICAgICAgICAgLy8gY2xlYW4gdXAKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAgICAgaWYgKGlzX2RpcigkcGF0aCkgJiYgcmVhbHBhdGgoJHBhdGgpICE9PSBnZXRjd2QoKSkgewogICAgICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNlbGYtPnJlbW92ZUNsZWFudXBQYXRoKCRwYWNrYWdlLCAkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAgICAgJHNlbGYtPnJlbW92ZUNsZWFudXBQYXRoKCRwYWNrYWdlLCByZWFscGF0aCgkcGF0aCkpOwogICAgICAgIH07CgogICAgICAgICRwcm9taXNlID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5leHRyYWN0KCRwYWNrYWdlLCAkZmlsZU5hbWUsICR0ZW1wb3JhcnlEaXIpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGNsZWFudXAoKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCRzZWxmLCAkcGFja2FnZSwgJGZpbGVzeXN0ZW0sICRmaWxlTmFtZSwgJHRlbXBvcmFyeURpciwgJHBhdGgpIHsKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnVubGluaygkZmlsZU5hbWUpOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJldHVybnMgdGhlIGZvbGRlciBjb250ZW50LCBleGNsdWRpbmcgLkRTX1N0b3JlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgJGRpciBEaXJlY3RvcnkKICAgICAgICAgICAgICogQHJldHVybiBcU3BsRmlsZUluZm9bXQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgJGdldEZvbGRlckNvbnRlbnQgPSBmdW5jdGlvbiAoJGRpcikgewogICAgICAgICAgICAgICAgJGZpbmRlciA9IEZpbmRlcjo6Y3JlYXRlKCkKICAgICAgICAgICAgICAgICAgICAtPmlnbm9yZVZDUyhmYWxzZSkKICAgICAgICAgICAgICAgICAgICAtPmlnbm9yZURvdEZpbGVzKGZhbHNlKQogICAgICAgICAgICAgICAgICAgIC0+bm90TmFtZSgnLkRTX1N0b3JlJykKICAgICAgICAgICAgICAgICAgICAtPmRlcHRoKDApCiAgICAgICAgICAgICAgICAgICAgLT5pbigkZGlyKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JfdG9fYXJyYXkoJGZpbmRlcik7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgICRyZW5hbWVSZWN1cnNpdmVseSA9IG51bGw7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZW5hbWVzIChhbmQgcmVjdXJzaXZlbHkgbWVyZ2VzIGlmIG5lZWRlZCkgYSBmb2xkZXIgaW50byBhbm90aGVyIG9uZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBGb3IgY3VzdG9tIGluc3RhbGxlcnMsIHdoZXJlIHBhY2thZ2VzIG1heSBzaGFyZSBwYXRocywgYW5kIGdpdmVuIENvbXBvc2VyIDIncyBwYXJhbGxlbGlzbSwgd2UgbmVlZCB0byBtYWtlIHN1cmUKICAgICAgICAgICAgICogdGhhdCB0aGUgc291cmNlIGRpcmVjdG9yeSBnZXRzIG1lcmdlZCBpbnRvIHRoZSB0YXJnZXQgb25lIGlmIHRoZSB0YXJnZXQgZXhpc3RzLiBPdGhlcndpc2UgcmVuYW1lKCkgYnkgZGVmYXVsdCB3b3VsZAogICAgICAgICAgICAgKiBwdXQgdGhlIHNvdXJjZSBpbnRvIHRoZSB0YXJnZXQgZS5nLiBzcmMvID0+IHRhcmdldC9zcmMvIChhc3N1bWluZyB0YXJnZXQgZXhpc3RzKSBpbnN0ZWFkIG9mIHNyYy8gPT4gdGFyZ2V0LwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0gIHN0cmluZyAkZnJvbSBEaXJlY3RvcnkKICAgICAgICAgICAgICogQHBhcmFtICBzdHJpbmcgJHRvICAgRGlyZWN0b3J5CiAgICAgICAgICAgICAqIEByZXR1cm4gdm9pZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgJHJlbmFtZVJlY3Vyc2l2ZWx5ID0gZnVuY3Rpb24gKCRmcm9tLCAkdG8pIHVzZSAoJGZpbGVzeXN0ZW0sICRnZXRGb2xkZXJDb250ZW50LCAkcGFja2FnZSwgJiRyZW5hbWVSZWN1cnNpdmVseSkgewogICAgICAgICAgICAgICAgJGNvbnRlbnREaXIgPSAkZ2V0Rm9sZGVyQ29udGVudCgkZnJvbSk7CgogICAgICAgICAgICAgICAgLy8gbW92ZSBmaWxlcyBiYWNrIG91dCBvZiB0aGUgdGVtcCBkaXIKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb250ZW50RGlyIGFzICRmaWxlKSB7CiAgICAgICAgICAgICAgICAgICAgJGZpbGUgPSAoc3RyaW5nKSAkZmlsZTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNfZGlyKCR0byAuICcvJyAuIGJhc2VuYW1lKCRmaWxlKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0luc3RhbGxpbmcgJy4kcGFja2FnZS4nIHdvdWxkIGxlYWQgdG8gb3ZlcndyaXRpbmcgdGhlICcuJHRvLicvJy5iYXNlbmFtZSgkZmlsZSkuJyBkaXJlY3Rvcnkgd2l0aCBhIGZpbGUgZnJvbSB0aGUgcGFja2FnZSwgaW52YWxpZCBvcGVyYXRpb24uJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHJlbmFtZVJlY3Vyc2l2ZWx5KCRmaWxlLCAkdG8gLiAnLycgLiBiYXNlbmFtZSgkZmlsZSkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmaWxlc3lzdGVtLT5yZW5hbWUoJGZpbGUsICR0byAuICcvJyAuIGJhc2VuYW1lKCRmaWxlKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgJHJlbmFtZUFzT25lID0gZmFsc2U7CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAkcmVuYW1lQXNPbmUgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2VpZiAoJGZpbGVzeXN0ZW0tPmlzRGlyRW1wdHkoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICgkZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5UGhwKCRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVuYW1lQXNPbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIGVycm9yLCBhbmQgc2ltcGx5IGRvIG5vdCByZW5hbWVBc09uZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29udGVudERpciA9ICRnZXRGb2xkZXJDb250ZW50KCR0ZW1wb3JhcnlEaXIpOwogICAgICAgICAgICAkc2luZ2xlRGlyQXRUb3BMZXZlbCA9IDEgPT09IGNvdW50KCRjb250ZW50RGlyKSAmJiBpc19kaXIocmVzZXQoJGNvbnRlbnREaXIpKTsKCiAgICAgICAgICAgIGlmICgkcmVuYW1lQXNPbmUpIHsKICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB0YXJnZXQgJHBhdGggaXMgY2xlYXIsIHdlIGNhbiByZW5hbWUgdGhlIHdob2xlIHBhY2thZ2UgaW4gb25lIGdvIGluc3RlYWQgb2YgbG9vcGluZyBvdmVyIHRoZSBjb250ZW50cwogICAgICAgICAgICAgICAgaWYgKCRzaW5nbGVEaXJBdFRvcExldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgJGV4dHJhY3RlZERpciA9IChzdHJpbmcpIHJlc2V0KCRjb250ZW50RGlyKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGV4dHJhY3RlZERpciA9ICR0ZW1wb3JhcnlEaXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkZmlsZXN5c3RlbS0+cmVuYW1lKCRleHRyYWN0ZWREaXIsICRwYXRoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIG9ubHkgb25lIGRpciBpbiB0aGUgYXJjaGl2ZSwgZXh0cmFjdCBpdHMgY29udGVudHMgb3V0IG9mIGl0CiAgICAgICAgICAgICAgICAkZnJvbSA9ICR0ZW1wb3JhcnlEaXI7CiAgICAgICAgICAgICAgICBpZiAoJHNpbmdsZURpckF0VG9wTGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgICAkZnJvbSA9IChzdHJpbmcpIHJlc2V0KCRjb250ZW50RGlyKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVuYW1lUmVjdXJzaXZlbHkoJGZyb20sICRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb21pc2UgPSAkZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5QXN5bmMoJHRlbXBvcmFyeURpcik7CgogICAgICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkc2VsZiwgJHBhY2thZ2UsICRwYXRoLCAkdGVtcG9yYXJ5RGlyKSB7CiAgICAgICAgICAgICAgICAkc2VsZi0+cmVtb3ZlQ2xlYW51cFBhdGgoJHBhY2thZ2UsICR0ZW1wb3JhcnlEaXIpOwogICAgICAgICAgICAgICAgJHNlbGYtPnJlbW92ZUNsZWFudXBQYXRoKCRwYWNrYWdlLCAkcGF0aCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sIGZ1bmN0aW9uICgkZSkgdXNlICgkY2xlYW51cCkgewogICAgICAgICAgICAkY2xlYW51cCgpOwoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0SW5zdGFsbE9wZXJhdGlvbkFwcGVuZGl4KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIHJldHVybiAnOiBFeHRyYWN0aW5nIGFyY2hpdmUnOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCBmaWxlIHRvIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgRXh0cmFjdGVkIGZpbGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggRGlyZWN0b3J5CiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uIElmIGNhbiBub3QgZXh0cmFjdCBkb3dubG9hZGVkIGZpbGUgdG8gcGF0aAogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZpbGUsICRwYXRoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFV0aWxcSW5pSGVscGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgUmFyQXJjaGl2ZTsKCi8qKgogKiBSQVIgYXJjaGl2ZSBkb3dubG9hZGVyLgogKgogKiBCYXNlZCBvbiBwcmV2aW91cyB3b3JrIGJ5IEpvcmRpIEJvZ2dpYW5vICh7QHNlZSBaaXBEb3dubG9hZGVyfSkuCiAqCiAqIEBhdXRob3IgRGVycmljayBOZWxzb24gPGRycmNrbmxzbkBnbWFpbC5jb20+CiAqLwpjbGFzcyBSYXJEb3dubG9hZGVyIGV4dGVuZHMgQXJjaGl2ZURvd25sb2FkZXIKewogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZpbGUsICRwYXRoKQogICAgewogICAgICAgICRwcm9jZXNzRXJyb3IgPSBudWxsOwoKICAgICAgICAvLyBUcnkgdG8gdXNlIHVucmFyIG9uICpuaXgKICAgICAgICBpZiAoIVBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAkY29tbWFuZCA9ICd1bnJhciB4IC0tICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkgLiAnICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGF0aCkgLiAnID4vZGV2L251bGwgJiYgY2htb2QgLVIgdSt3ICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGF0aCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb2Nlc3NFcnJvciA9ICdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgIGlmICghY2xhc3NfZXhpc3RzKCdSYXJBcmNoaXZlJykpIHsKICAgICAgICAgICAgLy8gcGhwLmluaSBwYXRoIGlzIGFkZGVkIHRvIHRoZSBlcnJvciBtZXNzYWdlIHRvIGhlbHAgdXNlcnMgZmluZCB0aGUgY29ycmVjdCBmaWxlCiAgICAgICAgICAgICRpbmlNZXNzYWdlID0gSW5pSGVscGVyOjpnZXRNZXNzYWdlKCk7CgogICAgICAgICAgICAkZXJyb3IgPSAiQ291bGQgbm90IGRlY29tcHJlc3MgdGhlIGFyY2hpdmUsIGVuYWJsZSB0aGUgUEhQIHJhciBleHRlbnNpb24gb3IgaW5zdGFsbCB1bnJhci5cbiIKICAgICAgICAgICAgICAgIC4gJGluaU1lc3NhZ2UgLiAiXG4iIC4gJHByb2Nlc3NFcnJvcjsKCiAgICAgICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICAkZXJyb3IgPSAiQ291bGQgbm90IGRlY29tcHJlc3MgdGhlIGFyY2hpdmUsIGVuYWJsZSB0aGUgUEhQIHJhciBleHRlbnNpb24uXG4iIC4gJGluaU1lc3NhZ2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkZXJyb3IpOwogICAgICAgIH0KCiAgICAgICAgJHJhckFyY2hpdmUgPSBSYXJBcmNoaXZlOjpvcGVuKCRmaWxlKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmFyQXJjaGl2ZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignQ291bGQgbm90IG9wZW4gUkFSIGFyY2hpdmU6ICcgLiAkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICAkZW50cmllcyA9ICRyYXJBcmNoaXZlLT5nZXRFbnRyaWVzKCk7CgogICAgICAgIGlmIChmYWxzZSA9PT0gJGVudHJpZXMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgcmV0cmlldmUgUkFSIGFyY2hpdmUgZW50cmllcycpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGVudHJpZXMgYXMgJGVudHJ5KSB7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGVudHJ5LT5leHRyYWN0KCRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgZXh0cmFjdCBlbnRyeScpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcmFyQXJjaGl2ZS0+Y2xvc2UoKTsKCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwoKLyoqCiAqIFh6IGFyY2hpdmUgZG93bmxvYWRlci4KICoKICogQGF1dGhvciBQYXZlbCBQdWNoa2luIDxpQG5lb2FzY2V0aWMubWU+CiAqIEBhdXRob3IgUGllcnJlIFJ1ZGxvZmYgPGNvbnRhY3RAcnVkbG9mZi5wcm8+CiAqLwpjbGFzcyBYekRvd25sb2FkZXIgZXh0ZW5kcyBBcmNoaXZlRG93bmxvYWRlcgp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXh0cmFjdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSAndGFyIC14SmYgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRmaWxlKSAuICcgLUMgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKTsKCiAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCkpIHsKICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgICRwcm9jZXNzRXJyb3IgPSAnRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkcHJvY2Vzc0Vycm9yKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcSW5pSGVscGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGVjdXRhYmxlRmluZGVyOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlSW50ZXJmYWNlOwp1c2UgWmlwQXJjaGl2ZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBaaXBEb3dubG9hZGVyIGV4dGVuZHMgQXJjaGl2ZURvd25sb2FkZXIKewogICAgLyoqIEB2YXIgYXJyYXk8aW50LCBhcnJheXswOiBzdHJpbmcsIDE6IHN0cmluZ30+ICovCiAgICBwcml2YXRlIHN0YXRpYyAkdW56aXBDb21tYW5kczsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgc3RhdGljICRoYXNaaXBBcmNoaXZlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGlzV2luZG93czsKCiAgICAvKiogQHZhciBaaXBBcmNoaXZlfG51bGwgKi8KICAgIHByaXZhdGUgJHppcEFyY2hpdmVPYmplY3Q7IC8vIEBwaHBzdGFuLWlnbm9yZS1saW5lIGhlbHBlciBwcm9wZXJ0eSB0aGF0IGlzIHNldCB2aWEgcmVmbGVjdGlvbiBmb3IgdGVzdGluZyBwdXJwb3NlcwoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokdW56aXBDb21tYW5kcykgewogICAgICAgICAgICBzZWxmOjokdW56aXBDb21tYW5kcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRmaW5kZXIgPSBuZXcgRXhlY3V0YWJsZUZpbmRlcjsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiAoJGNtZCA9ICRmaW5kZXItPmZpbmQoJzd6JywgbnVsbCwgYXJyYXkoJ0M6XFByb2dyYW0gRmlsZXNcNy1aaXAnKSkpKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokdW56aXBDb21tYW5kc1tdID0gYXJyYXkoJzd6JywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGNtZCkuJyB4IC1iYjAgLXkgJXMgLW8lcycpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkY21kID0gJGZpbmRlci0+ZmluZCgndW56aXAnKSkgewogICAgICAgICAgICAgICAgc2VsZjo6JHVuemlwQ29tbWFuZHNbXSA9IGFycmF5KCd1bnppcCcsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRjbWQpLicgLXFxICVzIC1kICVzJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgKCRjbWQgPSAkZmluZGVyLT5maW5kKCc3eicpKSkgeyAvLyA3eiBsaW51eC9tYWNPUyBzdXBwb3J0IGlzIG9ubHkgdXNlZCBpZiB1bnppcCBpcyBub3QgcHJlc2VudAogICAgICAgICAgICAgICAgc2VsZjo6JHVuemlwQ29tbWFuZHNbXSA9IGFycmF5KCc3eicsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRjbWQpLicgeCAtYmIwIC15ICVzIC1vJXMnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIVBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiAoJGNtZCA9ICRmaW5kZXItPmZpbmQoJzd6eicpKSkgeyAvLyA3enogbGludXgvbWFjT1Mgc3VwcG9ydCBpcyBvbmx5IHVzZWQgaWYgdW56aXAgaXMgbm90IHByZXNlbnQKICAgICAgICAgICAgICAgIHNlbGY6OiR1bnppcENvbW1hbmRzW10gPSBhcnJheSgnN3p6JywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGNtZCkuJyB4IC1iYjAgLXkgJXMgLW8lcycpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcHJvY09wZW5NaXNzaW5nID0gZmFsc2U7CiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3Byb2Nfb3BlbicpKSB7CiAgICAgICAgICAgIHNlbGY6OiR1bnppcENvbW1hbmRzID0gYXJyYXkoKTsKICAgICAgICAgICAgJHByb2NPcGVuTWlzc2luZyA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gc2VsZjo6JGhhc1ppcEFyY2hpdmUpIHsKICAgICAgICAgICAgc2VsZjo6JGhhc1ppcEFyY2hpdmUgPSBjbGFzc19leGlzdHMoJ1ppcEFyY2hpdmUnKTsKICAgICAgICB9CgogICAgICAgIGlmICghc2VsZjo6JGhhc1ppcEFyY2hpdmUgJiYgIXNlbGY6OiR1bnppcENvbW1hbmRzKSB7CiAgICAgICAgICAgIC8vIHBocC5pbmkgcGF0aCBpcyBhZGRlZCB0byB0aGUgZXJyb3IgbWVzc2FnZSB0byBoZWxwIHVzZXJzIGZpbmQgdGhlIGNvcnJlY3QgZmlsZQogICAgICAgICAgICAkaW5pTWVzc2FnZSA9IEluaUhlbHBlcjo6Z2V0TWVzc2FnZSgpOwogICAgICAgICAgICBpZiAoJHByb2NPcGVuTWlzc2luZykgewogICAgICAgICAgICAgICAgJGVycm9yID0gIlRoZSB6aXAgZXh0ZW5zaW9uIGlzIG1pc3NpbmcgYW5kIHVuemlwLzd6IGNvbW1hbmRzIGNhbm5vdCBiZSBjYWxsZWQgYXMgcHJvY19vcGVuIGlzIGRpc2FibGVkLCBza2lwcGluZy5cbiIgLiAkaW5pTWVzc2FnZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRlcnJvciA9ICJUaGUgemlwIGV4dGVuc2lvbiBhbmQgdW56aXAvN3ogY29tbWFuZHMgYXJlIGJvdGggbWlzc2luZywgc2tpcHBpbmcuXG4iIC4gJGluaU1lc3NhZ2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkZXJyb3IpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiRpc1dpbmRvd3MpIHsKICAgICAgICAgICAgc2VsZjo6JGlzV2luZG93cyA9IFBsYXRmb3JtOjppc1dpbmRvd3MoKTsKCiAgICAgICAgICAgIGlmICghc2VsZjo6JGlzV2luZG93cyAmJiAhc2VsZjo6JHVuemlwQ29tbWFuZHMpIHsKICAgICAgICAgICAgICAgIGlmICgkcHJvY09wZW5NaXNzaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCI8d2FybmluZz5wcm9jX29wZW4gaXMgZGlzYWJsZWQgc28gJ3VuemlwJyBhbmQgJzd6JyBjb21tYW5kcyBjYW5ub3QgYmUgdXNlZCwgemlwIGZpbGVzIGFyZSBiZWluZyB1bnBhY2tlZCB1c2luZyB0aGUgUEhQIHppcCBleHRlbnNpb24uPC93YXJuaW5nPiIpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiPHdhcm5pbmc+VGhpcyBtYXkgY2F1c2UgaW52YWxpZCByZXBvcnRzIG9mIGNvcnJ1cHRlZCBhcmNoaXZlcy4gQmVzaWRlcywgYW55IFVOSVggcGVybWlzc2lvbnMgKGUuZy4gZXhlY3V0YWJsZSkgZGVmaW5lZCBpbiB0aGUgYXJjaGl2ZXMgd2lsbCBiZSBsb3N0Ljwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIjx3YXJuaW5nPkVuYWJsaW5nIHByb2Nfb3BlbiBhbmQgaW5zdGFsbGluZyAndW56aXAnIG9yICc3eicgbWF5IHJlbWVkaWF0ZSB0aGVtLjwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCI8d2FybmluZz5BcyB0aGVyZSBpcyBubyAndW56aXAnIG5vciAnN3onIGNvbW1hbmQgaW5zdGFsbGVkIHppcCBmaWxlcyBhcmUgYmVpbmcgdW5wYWNrZWQgdXNpbmcgdGhlIFBIUCB6aXAgZXh0ZW5zaW9uLjwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIjx3YXJuaW5nPlRoaXMgbWF5IGNhdXNlIGludmFsaWQgcmVwb3J0cyBvZiBjb3JydXB0ZWQgYXJjaGl2ZXMuIEJlc2lkZXMsIGFueSBVTklYIHBlcm1pc3Npb25zIChlLmcuIGV4ZWN1dGFibGUpIGRlZmluZWQgaW4gdGhlIGFyY2hpdmVzIHdpbGwgYmUgbG9zdC48L3dhcm5pbmc+Iik7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCI8d2FybmluZz5JbnN0YWxsaW5nICd1bnppcCcgb3IgJzd6JyBtYXkgcmVtZWRpYXRlIHRoZW0uPC93YXJuaW5nPiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcGFyZW50Ojpkb3dubG9hZCgkcGFja2FnZSwgJHBhdGgsICRwcmV2UGFja2FnZSwgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBleHRyYWN0ICRmaWxlIHRvICRwYXRoIHdpdGggInVuemlwIiBjb21tYW5kCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRmaWxlIEZpbGUgdG8gZXh0cmFjdAogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRwYXRoIFBhdGggd2hlcmUgdG8gZXh0cmFjdCBmaWxlCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBleHRyYWN0V2l0aFN5c3RlbVVuemlwKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRmaWxlLCAkcGF0aCkKICAgIHsKICAgICAgICAvLyBGb3JjZSBFeGNlcHRpb24gdGhyb3dpbmcgaWYgdGhlIG90aGVyIGFsdGVybmF0aXZlIGV4dHJhY3Rpb24gbWV0aG9kIGlzIG5vdCBhdmFpbGFibGUKICAgICAgICAkaXNMYXN0Q2hhbmNlID0gIXNlbGY6OiRoYXNaaXBBcmNoaXZlOwoKICAgICAgICBpZiAoIXNlbGY6OiR1bnppcENvbW1hbmRzKSB7CiAgICAgICAgICAgIC8vIFRoaXMgd2FzIGNhbGwgYXMgdGhlIGZhdm9yaXRlIGV4dHJhY3Qgd2F5LCBidXQgaXMgbm90IGF2YWlsYWJsZQogICAgICAgICAgICAvLyBXZSBzd2l0Y2ggdG8gdGhlIGFsdGVybmF0aXZlCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXh0cmFjdFdpdGhaaXBBcmNoaXZlKCRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmRTcGVjID0gcmVzZXQoc2VsZjo6JHVuemlwQ29tbWFuZHMpOwogICAgICAgICRjb21tYW5kID0gc3ByaW50ZigkY29tbWFuZFNwZWNbMV0sIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRmaWxlKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhdGgpKTsKICAgICAgICAvLyBub3JtYWxpemUgc2VwYXJhdG9ycyB0byBiYWNrc2xhc2hlcyB0byBhdm9pZCBwcm9ibGVtcyB3aXRoIDctemlwIG9uIHdpbmRvd3MKICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy8xMDA1OAogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCRjb21tYW5kU3BlY1sxXSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoc3RydHIoJGZpbGUsICcvJywgJ1xcJykpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShzdHJ0cigkcGF0aCwgJy8nLCAnXFwnKSkpOwogICAgICAgIH0KCiAgICAgICAgJGV4ZWN1dGFibGUgPSAkY29tbWFuZFNwZWNbMF07CgogICAgICAgICRzZWxmID0gJHRoaXM7CiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICR0cnlGYWxsYmFjayA9IGZ1bmN0aW9uICgkcHJvY2Vzc0Vycm9yKSB1c2UgKCRpc0xhc3RDaGFuY2UsICRpbywgJHNlbGYsICRmaWxlLCAkcGF0aCwgJHBhY2thZ2UsICRleGVjdXRhYmxlKSB7CiAgICAgICAgICAgIGlmICgkaXNMYXN0Q2hhbmNlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkcHJvY2Vzc0Vycm9yOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWlzX2ZpbGUoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICA8d2FybmluZz4nLiRwcm9jZXNzRXJyb3ItPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgPHdhcm5pbmc+VGhpcyBtb3N0IGxpa2VseSBpcyBkdWUgdG8gYSBjdXN0b20gaW5zdGFsbGVyIHBsdWdpbiBub3QgaGFuZGxpbmcgdGhlIHJldHVybmVkIFByb21pc2UgZnJvbSB0aGUgZG93bmxvYWRlcjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIDx3YXJuaW5nPlNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvaW5zdGFsbGVycy9jb21taXQvNTAwNmQwYzI4NzMwYWRlMjMzYThmNDJlYzMxYWM2OGZiMWM1YzliYiBmb3IgYW4gZXhhbXBsZSBmaXg8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICA8d2FybmluZz4nLiRwcm9jZXNzRXJyb3ItPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgVGhlIGFyY2hpdmUgbWF5IGNvbnRhaW4gaWRlbnRpY2FsIGZpbGUgbmFtZXMgd2l0aCBkaWZmZXJlbnQgY2FwaXRhbGl6YXRpb24gKHdoaWNoIGZhaWxzIG9uIGNhc2UgaW5zZW5zaXRpdmUgZmlsZXN5c3RlbXMpJyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICBVbnppcCB3aXRoICcuJGV4ZWN1dGFibGUuJyBjb21tYW5kIGZhaWxlZCwgZmFsbGluZyBiYWNrIHRvIFppcEFyY2hpdmUgY2xhc3MnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRzZWxmLT5leHRyYWN0V2l0aFppcEFyY2hpdmUoJHBhY2thZ2UsICRmaWxlLCAkcGF0aCk7CiAgICAgICAgfTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZUFzeW5jKCRjb21tYW5kKTsKCiAgICAgICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoJHByb2Nlc3MpIHVzZSAoJHRyeUZhbGxiYWNrLCAkY29tbWFuZCwgJHBhY2thZ2UsICRmaWxlLCAkc2VsZikgewogICAgICAgICAgICAgICAgaWYgKCEkcHJvY2Vzcy0+aXNTdWNjZXNzZnVsKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNlbGYtPmNsZWFudXBFeGVjdXRlZFskcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXh0cmFjdCAnLiRwYWNrYWdlLT5nZXROYW1lKCkuJyBhcyB0aGUgaW5zdGFsbGF0aW9uIHdhcyBhYm9ydGVkIGJ5IGFub3RoZXIgcGFja2FnZSBvcGVyYXRpb24uJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJHByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgICAgICAgICAgICAgJG91dHB1dCA9IHN0cl9yZXBsYWNlKCcsICcuJGZpbGUuJy56aXAgb3IgJy4kZmlsZS4nLlpJUCcsICcnLCAkb3V0cHV0KTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0cnlGYWxsYmFjayhuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleHRyYWN0ICcuJHBhY2thZ2UtPmdldE5hbWUoKS4nOiAoJy4kcHJvY2Vzcy0+Z2V0RXhpdENvZGUoKS4nKSAnLiRjb21tYW5kLiJcblxuIi4kb3V0cHV0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgcmV0dXJuICR0cnlGYWxsYmFjaygkZSk7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZSkgewogICAgICAgICAgICByZXR1cm4gJHRyeUZhbGxiYWNrKCRlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBleHRyYWN0ICRmaWxlIHRvICRwYXRoIHdpdGggWmlwQXJjaGl2ZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkZmlsZSBGaWxlIHRvIGV4dHJhY3QKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCBQYXRoIHdoZXJlIHRvIGV4dHJhY3QgZmlsZQogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAgICAgKgogICAgICogVE9ETyB2MyBzaG91bGQgbWFrZSB0aGlzIHByaXZhdGUgb25jZSB3ZSBjYW4gZHJvcCBQSFAgNS4zIHN1cHBvcnQKICAgICAqIEBwcm90ZWN0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4dHJhY3RXaXRoWmlwQXJjaGl2ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpCiAgICB7CiAgICAgICAgJHByb2Nlc3NFcnJvciA9IG51bGw7CiAgICAgICAgJHppcEFyY2hpdmUgPSAkdGhpcy0+emlwQXJjaGl2ZU9iamVjdCA/OiBuZXcgWmlwQXJjaGl2ZSgpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAodHJ1ZSA9PT0gKCRyZXR2YWwgPSAkemlwQXJjaGl2ZS0+b3BlbigkZmlsZSkpKSB7CiAgICAgICAgICAgICAgICAkZXh0cmFjdFJlc3VsdCA9ICR6aXBBcmNoaXZlLT5leHRyYWN0VG8oJHBhdGgpOwoKICAgICAgICAgICAgICAgIGlmICh0cnVlID09PSAkZXh0cmFjdFJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICR6aXBBcmNoaXZlLT5jbG9zZSgpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRwcm9jZXNzRXJyb3IgPSBuZXcgXFJ1bnRpbWVFeGNlcHRpb24ocnRyaW0oIlRoZXJlIHdhcyBhbiBlcnJvciBleHRyYWN0aW5nIHRoZSBaSVAgZmlsZSwgaXQgaXMgZWl0aGVyIGNvcnJ1cHRlZCBvciB1c2luZyBhbiBpbnZhbGlkIGZvcm1hdC5cbiIpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcm9jZXNzRXJyb3IgPSBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbihydHJpbSgkdGhpcy0+Z2V0RXJyb3JNZXNzYWdlKCRyZXR2YWwsICRmaWxlKS4iXG4iKSwgJHJldHZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXJyb3JFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHByb2Nlc3NFcnJvciA9IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIGFyY2hpdmUgbWF5IGNvbnRhaW4gaWRlbnRpY2FsIGZpbGUgbmFtZXMgd2l0aCBkaWZmZXJlbnQgY2FwaXRhbGl6YXRpb24gKHdoaWNoIGZhaWxzIG9uIGNhc2UgaW5zZW5zaXRpdmUgZmlsZXN5c3RlbXMpOiAnLiRlLT5nZXRNZXNzYWdlKCksIDAsICRlKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRwcm9jZXNzRXJyb3IgPSAkZTsKICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgICAgICRwcm9jZXNzRXJyb3IgPSAkZTsKICAgICAgICB9CgogICAgICAgIHRocm93ICRwcm9jZXNzRXJyb3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBleHRyYWN0ICRmaWxlIHRvICRwYXRoCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJGZpbGUgRmlsZSB0byBleHRyYWN0CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAkcGF0aCBQYXRoIHdoZXJlIHRvIGV4dHJhY3QgZmlsZQogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByb3RlY3RlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXh0cmFjdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0V2l0aFN5c3RlbVVuemlwKCRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZSBhIG1lYW5pbmdmdWwgZXJyb3IgbWVzc2FnZSB0byB0aGUgdXNlci4KICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAgICAkcmV0dmFsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkZmlsZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZSgkcmV0dmFsLCAkZmlsZSkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRyZXR2YWwpIHsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9FWElTVFM6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiRmlsZSAnJXMnIGFscmVhZHkgZXhpc3RzLiIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9JTkNPTlM6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiWmlwIGFyY2hpdmUgJyVzJyBpcyBpbmNvbnNpc3RlbnQuIiwgJGZpbGUpOwogICAgICAgICAgICBjYXNlIFppcEFyY2hpdmU6OkVSX0lOVkFMOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIkludmFsaWQgYXJndW1lbnQgKCVzKSIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9NRU1PUlk6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiTWFsbG9jIGZhaWx1cmUgKCVzKSIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9OT0VOVDoKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCJObyBzdWNoIHppcCBmaWxlOiAnJXMnIiwgJGZpbGUpOwogICAgICAgICAgICBjYXNlIFppcEFyY2hpdmU6OkVSX05PWklQOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIiclcycgaXMgbm90IGEgemlwIGFyY2hpdmUuIiwgJGZpbGUpOwogICAgICAgICAgICBjYXNlIFppcEFyY2hpdmU6OkVSX09QRU46CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiQ2FuJ3Qgb3BlbiB6aXAgZmlsZTogJXMiLCAkZmlsZSk7CiAgICAgICAgICAgIGNhc2UgWmlwQXJjaGl2ZTo6RVJfUkVBRDoKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCJaaXAgcmVhZCBlcnJvciAoJXMpIiwgJGZpbGUpOwogICAgICAgICAgICBjYXNlIFppcEFyY2hpdmU6OkVSX1NFRUs6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiWmlwIHNlZWsgZXJyb3IgKCVzKSIsICRmaWxlKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCInJXMnIGlzIG5vdCBhIHZhbGlkIHppcCBhcmNoaXZlLCBnb3QgZXJyb3IgY29kZTogJXMiLCAkZmlsZSwgJHJldHZhbCk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlSW50ZXJmYWNlOwoKLyoqCiAqIERvd25sb2FkZXIgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgRG93bmxvYWRlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgaW5zdGFsbGF0aW9uIHNvdXJjZSAoZWl0aGVyIHNvdXJjZSBvciBkaXN0KS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyAic291cmNlIiBvciAiZGlzdCIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxhdGlvblNvdXJjZSgpOwoKICAgIC8qKgogICAgICogVGhpcyBzaG91bGQgZG8gYW55IG5ldHdvcmstcmVsYXRlZCB0YXNrcyB0byBwcmVwYXJlIGZvciBhbiB1cGNvbWluZyBpbnN0YWxsL3VwZGF0ZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYXRoIGRvd25sb2FkIHBhdGgKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKTsKCiAgICAvKioKICAgICAqIERvIGFueXRoaW5nIHRoYXQgbmVlZHMgdG8gYmUgZG9uZSBiZXR3ZWVuIGFsbCBkb3dubG9hZHMgaGF2ZSBiZWVuIGNvbXBsZXRlZCBhbmQgdGhlIGFjdHVhbCBvcGVyYXRpb24gaXMgZXhlY3V0ZWQKICAgICAqCiAgICAgKiBBbGwgcGFja2FnZXMgZ2V0IGZpcnN0IGRvd25sb2FkZWQsIHRoZW4gYWxsIHRvZ2V0aGVyIHByZXBhcmVkLCB0aGVuIGFsbCB0b2dldGhlciBpbnN0YWxsZWQvdXBkYXRlZC91bmluc3RhbGxlZC4gVGhlcmVmb3JlCiAgICAgKiBmb3IgZXJyb3IgcmVjb3ZlcnkgaXQgaXMgaW1wb3J0YW50IHRvIGF2b2lkIGZhaWxpbmcgZHVyaW5nIGluc3RhbGwvdXBkYXRlL3VuaW5zdGFsbCBhcyBtdWNoIGFzIHBvc3NpYmxlLCBhbmQgcmlza3kgdGhpbmdzIG9yCiAgICAgKiB1c2VyIHByb21wdHMgc2hvdWxkIGhhcHBlbiBpbiB0aGUgcHJlcGFyZSBzdGVwIHJhdGhlci4gSW4gY2FzZSBvZiBmYWlsdXJlLCBjbGVhbnVwKCkgd2lsbCBiZSBjYWxsZWQgc28gdGhhdCBjaGFuZ2VzIGNhbgogICAgICogYmUgdW5kb25lIGFzIG11Y2ggYXMgcG9zc2libGUuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHR5cGUgICAgICAgIG9uZSBvZiBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAkcGF0aCAgICAgICAgZG93bmxvYWQgcGF0aAogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHByZXZQYWNrYWdlIHByZXZpb3VzIHBhY2thZ2UgaW5zdGFuY2UgaW4gY2FzZSBvZiBhbiB1cGRhdGUKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcmVwYXJlKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKTsKCiAgICAvKioKICAgICAqIEluc3RhbGxzIHNwZWNpZmljIHBhY2thZ2UgaW50byBzcGVjaWZpYyBmb2xkZXIuCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHBhdGggICAgZG93bmxvYWQgcGF0aAogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwoKICAgIC8qKgogICAgICogVXBkYXRlcyBzcGVjaWZpYyBwYWNrYWdlIGluIHNwZWNpZmljIGZvbGRlciBmcm9tIGluaXRpYWwgdG8gdGFyZ2V0IHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJGluaXRpYWwgaW5pdGlhbCBwYWNrYWdlCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkdGFyZ2V0ICB1cGRhdGVkIHBhY2thZ2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICRwYXRoICAgIGRvd25sb2FkIHBhdGgKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0LCAkcGF0aCk7CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHNwZWNpZmljIHBhY2thZ2UgZnJvbSBzcGVjaWZpYyBmb2xkZXIuCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHBhdGggICAgZG93bmxvYWQgcGF0aAogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCk7CgogICAgLyoqCiAgICAgKiBEbyBhbnl0aGluZyB0byBjbGVhbnVwIGNoYW5nZXMgYXBwbGllZCBpbiB0aGUgcHJlcGFyZSBvciBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwgc3RlcHMKICAgICAqCiAgICAgKiBOb3RlIHRoYXQgY2xlYW51cCB3aWxsIGJlIGNhbGxlZCBmb3IgYWxsIHBhY2thZ2VzLCBlaXRoZXIgYWZ0ZXIgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsIGlzIGNvbXBsZXRlLAogICAgICogb3IgaWYgYW55IHBhY2thZ2UgZmFpbGVkIGFueSBvcGVyYXRpb24uIFRoaXMgaXMgdG8gZ2l2ZSBhbGwgaW5zdGFsbGVycyBhIGNoYW5nZSB0byBjbGVhbnVwIHRoaW5ncwogICAgICogdGhleSBkaWQgcHJldmlvdXNseSwgc28geW91IG5lZWQgdG8ga2VlcCB0cmFjayBvZiBjaGFuZ2VzIGFwcGxpZWQgaW4gdGhlIGluc3RhbGxlci9kb3dubG9hZGVyIHRoZW1zZWx2ZXMuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHR5cGUgICAgICAgIG9uZSBvZiBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAkcGF0aCAgICAgICAgZG93bmxvYWQgcGF0aAogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHByZXZQYWNrYWdlIHByZXZpb3VzIHBhY2thZ2UgaW5zdGFuY2UgaW4gY2FzZSBvZiBhbiB1cGRhdGUKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFV0aWxcUGVyZm9yY2U7CgovKioKICogQGF1dGhvciBNYXR0IFdoaXR0b20gPE1hdHQuV2hpdHRvbUB2ZXRlcmFuc3VuaXRlZC5jb20+CiAqLwpjbGFzcyBQZXJmb3JjZURvd25sb2FkZXIgZXh0ZW5kcyBWY3NEb3dubG9hZGVyCnsKICAgIC8qKiBAdmFyIFBlcmZvcmNlfG51bGwgKi8KICAgIHByb3RlY3RlZCAkcGVyZm9yY2U7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Eb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG9JbnN0YWxsKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgICRyZWYgPSAkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CiAgICAgICAgJGxhYmVsID0gJHRoaXMtPmdldExhYmVsRnJvbVNvdXJjZVJlZmVyZW5jZSgoc3RyaW5nKSAkcmVmKTsKCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdDbG9uaW5nICcgLiAkcmVmKTsKICAgICAgICAkdGhpcy0+aW5pdFBlcmZvcmNlKCRwYWNrYWdlLCAkcGF0aCwgJHVybCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5zZXRTdHJlYW0oJHJlZik7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5wNExvZ2luKCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT53cml0ZVA0Q2xpZW50U3BlYygpOwogICAgICAgICR0aGlzLT5wZXJmb3JjZS0+Y29ubmVjdENsaWVudCgpOwogICAgICAgICR0aGlzLT5wZXJmb3JjZS0+c3luY0NvZGVCYXNlKCRsYWJlbCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5jbGVhbnVwQ2xpZW50U3BlYygpOwoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVmCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldExhYmVsRnJvbVNvdXJjZVJlZmVyZW5jZSgkcmVmKQogICAgewogICAgICAgICRwb3MgPSBzdHJwb3MoJHJlZiwgJ0AnKTsKICAgICAgICBpZiAoZmFsc2UgIT09ICRwb3MpIHsKICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkcmVmLCAkcG9zICsgMSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdFBlcmZvcmNlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPnBlcmZvcmNlKSkgewogICAgICAgICAgICAkdGhpcy0+cGVyZm9yY2UtPmluaXRpYWxpemVQYXRoKCRwYXRoKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRyZXBvc2l0b3J5ID0gJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKTsKICAgICAgICAkcmVwb0NvbmZpZyA9IG51bGw7CiAgICAgICAgaWYgKCRyZXBvc2l0b3J5IGluc3RhbmNlb2YgVmNzUmVwb3NpdG9yeSkgewogICAgICAgICAgICAkcmVwb0NvbmZpZyA9ICR0aGlzLT5nZXRSZXBvQ29uZmlnKCRyZXBvc2l0b3J5KTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlID0gUGVyZm9yY2U6OmNyZWF0ZSgkcmVwb0NvbmZpZywgJHVybCwgJHBhdGgsICR0aGlzLT5wcm9jZXNzLCAkdGhpcy0+aW8pOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIG1peGVkPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFJlcG9Db25maWcoVmNzUmVwb3NpdG9yeSAkcmVwb3NpdG9yeSkKICAgIHsKICAgICAgICByZXR1cm4gJHJlcG9zaXRvcnktPmdldFJlcG9Db25maWcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1VwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZG9JbnN0YWxsKCR0YXJnZXQsICRwYXRoLCAkdXJsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdQZXJmb3JjZSBkcml2ZXIgZG9lcyBub3QgY2hlY2sgZm9yIGxvY2FsIGNoYW5nZXMgYmVmb3JlIG92ZXJyaWRpbmcnKTsKCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q29tbWl0TG9ncygkZnJvbVJlZmVyZW5jZSwgJHRvUmVmZXJlbmNlLCAkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBlcmZvcmNlLT5nZXRDb21taXRMb2dzKCRmcm9tUmVmZXJlbmNlLCAkdG9SZWZlcmVuY2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQZXJmb3JjZShQZXJmb3JjZSAkcGVyZm9yY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlID0gJHBlcmZvcmNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xOdWxsSU87CnVzZSBDb21wb3NlclxFeGNlcHRpb25cSXJyZWNvdmVyYWJsZURvd25sb2FkRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wYXJlclxDb21wYXJlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVXBkYXRlT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBvc3RGaWxlRG93bmxvYWRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQcmVGaWxlRG93bmxvYWRFdmVudDsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcVXJsIGFzIFVybFV0aWw7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBCYXNlIGRvd25sb2FkZXIgZm9yIGZpbGVzCiAqCiAqIEBhdXRob3IgS2lyaWxsIGNoRWJiYSBDaGVidW5pbiA8aWFtQGNoZWJiYS5vcmc+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEZpbGVEb3dubG9hZGVyIGltcGxlbWVudHMgRG93bmxvYWRlckludGVyZmFjZSwgQ2hhbmdlUmVwb3J0SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlvOwogICAgLyoqIEB2YXIgQ29uZmlnICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgRmlsZXN5c3RlbSAqLwogICAgcHJvdGVjdGVkICRmaWxlc3lzdGVtOwogICAgLyoqIEB2YXIgP0NhY2hlICovCiAgICBwcm90ZWN0ZWQgJGNhY2hlOwogICAgLyoqIEB2YXIgP0V2ZW50RGlzcGF0Y2hlciAqLwogICAgcHJvdGVjdGVkICRldmVudERpc3BhdGNoZXI7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKICAgIC8qKgogICAgICogQHZhciBhcnJheTxzdHJpbmcsIGludHxzdHJpbmc+CiAgICAgKiBAcHJpdmF0ZQogICAgICogQGludGVybmFsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgJGRvd25sb2FkTWV0YWRhdGEgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHByaXZhdGUgdGhpcyBpcyBvbmx5IHB1YmxpYyBmb3IgcGhwIDUuMyBzdXBwb3J0IGluIGNsb3N1cmVzCiAgICAgKgogICAgICogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gTWFwIG9mIHBhY2thZ2UgbmFtZSB0byBjYWNoZSBrZXkKICAgICAqLwogICAgcHVibGljICRsYXN0Q2FjaGVXcml0ZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmdbXT4gTWFwIG9mIHBhY2thZ2UgbmFtZSB0byBsaXN0IG9mIHBhdGhzICovCiAgICBwcml2YXRlICRhZGRpdGlvbmFsQ2xlYW51cFBhdGhzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgJGlvICAgICAgICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgJGNvbmZpZyAgICAgICAgICBUaGUgY29uZmlnCiAgICAgKiBAcGFyYW0gSHR0cERvd25sb2FkZXIgICRodHRwRG93bmxvYWRlciAgVGhlIHJlbW90ZSBmaWxlc3lzdGVtCiAgICAgKiBAcGFyYW0gRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgVGhlIGV2ZW50IGRpc3BhdGNoZXIKICAgICAqIEBwYXJhbSBDYWNoZSAgICAgICAgICAgJGNhY2hlICAgICAgICAgICBDYWNoZSBpbnN0YW5jZQogICAgICogQHBhcmFtIEZpbGVzeXN0ZW0gICAgICAkZmlsZXN5c3RlbSAgICAgIFRoZSBmaWxlc3lzdGVtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIsIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyID0gbnVsbCwgQ2FjaGUgJGNhY2hlID0gbnVsbCwgRmlsZXN5c3RlbSAkZmlsZXN5c3RlbSA9IG51bGwsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+Y2FjaGUgPSAkY2FjaGU7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzcyA/OiBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZmlsZXN5c3RlbSA/OiBuZXcgRmlsZXN5c3RlbSgkdGhpcy0+cHJvY2Vzcyk7CgogICAgICAgIGlmICgkdGhpcy0+Y2FjaGUgJiYgJHRoaXMtPmNhY2hlLT5nY0lzTmVjZXNzYXJ5KCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdSdW5uaW5nIGNhY2hlIGdhcmJhZ2UgY29sbGVjdGlvbicsIHRydWUsIElPSW50ZXJmYWNlOjpWRVJZX1ZFUkJPU0UpOwogICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPmdjKChpbnQpICRjb25maWctPmdldCgnY2FjaGUtZmlsZXMtdHRsJyksIChpbnQpICRjb25maWctPmdldCgnY2FjaGUtZmlsZXMtbWF4c2l6ZScpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGF0aW9uU291cmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2Rpc3QnOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkb3V0cHV0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsLCAkb3V0cHV0ID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoISRwYWNrYWdlLT5nZXREaXN0VXJsKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBnaXZlbiBwYWNrYWdlIGlzIG1pc3NpbmcgdXJsIGluZm9ybWF0aW9uJyk7CiAgICAgICAgfQoKICAgICAgICAkY2FjaGVLZXlHZW5lcmF0b3IgPSBmdW5jdGlvbiAoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGtleSkgewogICAgICAgICAgICAkY2FjaGVLZXkgPSBzaGExKCRrZXkpOwoKICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlLT5nZXROYW1lKCkuJy8nLiRjYWNoZUtleS4nLicuJHBhY2thZ2UtPmdldERpc3RUeXBlKCk7CiAgICAgICAgfTsKCiAgICAgICAgJHJldHJpZXMgPSAzOwogICAgICAgICRkaXN0VXJscyA9ICRwYWNrYWdlLT5nZXREaXN0VXJscygpOwogICAgICAgIC8qKiBAdmFyIGFycmF5PGFycmF5e2Jhc2U6IHN0cmluZywgcHJvY2Vzc2VkOiBzdHJpbmcsIGNhY2hlS2V5OiBzdHJpbmd9PiAkdXJscyAqLwogICAgICAgICR1cmxzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkZGlzdFVybHMgYXMgJGluZGV4ID0+ICR1cmwpIHsKICAgICAgICAgICAgJHByb2Nlc3NlZFVybCA9ICR0aGlzLT5wcm9jZXNzVXJsKCRwYWNrYWdlLCAkdXJsKTsKICAgICAgICAgICAgJHVybHNbJGluZGV4XSA9IGFycmF5KAogICAgICAgICAgICAgICAgJ2Jhc2UnID0+ICR1cmwsCiAgICAgICAgICAgICAgICAncHJvY2Vzc2VkJyA9PiAkcHJvY2Vzc2VkVXJsLAogICAgICAgICAgICAgICAgLy8gd2UgdXNlIHRoZSBjb21wbGV0ZSBkb3dubG9hZCB1cmwgaGVyZSB0byBhdm9pZCBjb25mbGljdGluZyBlbnRyaWVzCiAgICAgICAgICAgICAgICAvLyBmcm9tIGRpZmZlcmVudCBwYWNrYWdlcywgd2hpY2ggd291bGQgcG90ZW50aWFsbHkgYWxsb3cgYSBnaXZlbiBwYWNrYWdlCiAgICAgICAgICAgICAgICAvLyBpbiBhIHRoaXJkIHBhcnR5IHJlcG8gdG8gcHJlLXBvcHVsYXRlIHRoZSBjYWNoZSBmb3IgdGhlIHNhbWUgcGFja2FnZSBpbgogICAgICAgICAgICAgICAgLy8gcGFja2FnaXN0IGZvciBleGFtcGxlLgogICAgICAgICAgICAgICAgJ2NhY2hlS2V5JyA9PiAkY2FjaGVLZXlHZW5lcmF0b3IoJHBhY2thZ2UsICRwcm9jZXNzZWRVcmwpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmdldEZpbGVOYW1lKCRwYWNrYWdlLCAkcGF0aCk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkcGF0aCk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cyhkaXJuYW1lKCRmaWxlTmFtZSkpOwoKICAgICAgICAkaW8gPSAkdGhpcy0+aW87CiAgICAgICAgJGNhY2hlID0gJHRoaXMtPmNhY2hlOwogICAgICAgICRodHRwRG93bmxvYWRlciA9ICR0aGlzLT5odHRwRG93bmxvYWRlcjsKICAgICAgICAkZXZlbnREaXNwYXRjaGVyID0gJHRoaXMtPmV2ZW50RGlzcGF0Y2hlcjsKICAgICAgICAkZmlsZXN5c3RlbSA9ICR0aGlzLT5maWxlc3lzdGVtOwogICAgICAgICRzZWxmID0gJHRoaXM7CgogICAgICAgICRhY2NlcHQgPSBudWxsOwogICAgICAgICRyZWplY3QgPSBudWxsOwogICAgICAgICRkb3dubG9hZCA9IGZ1bmN0aW9uICgpIHVzZSAoJGlvLCAkb3V0cHV0LCAkaHR0cERvd25sb2FkZXIsICRjYWNoZSwgJGNhY2hlS2V5R2VuZXJhdG9yLCAkZXZlbnREaXNwYXRjaGVyLCAkcGFja2FnZSwgJGZpbGVOYW1lLCAmJHVybHMsICYkYWNjZXB0LCAmJHJlamVjdCwgJHNlbGYpIHsKICAgICAgICAgICAgLyoqIEB2YXIgYXJyYXl7YmFzZTogc3RyaW5nLCBwcm9jZXNzZWQ6IHN0cmluZywgY2FjaGVLZXk6IHN0cmluZ30gJHVybCAqLwogICAgICAgICAgICAkdXJsID0gcmVzZXQoJHVybHMpOwogICAgICAgICAgICAkaW5kZXggPSBrZXkoJHVybHMpOwoKICAgICAgICAgICAgaWYgKCRldmVudERpc3BhdGNoZXIpIHsKICAgICAgICAgICAgICAgICRwcmVGaWxlRG93bmxvYWRFdmVudCA9IG5ldyBQcmVGaWxlRG93bmxvYWRFdmVudChQbHVnaW5FdmVudHM6OlBSRV9GSUxFX0RPV05MT0FELCAkaHR0cERvd25sb2FkZXIsICR1cmxbJ3Byb2Nlc3NlZCddLCAncGFja2FnZScsICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICRldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0TmFtZSgpLCAkcHJlRmlsZURvd25sb2FkRXZlbnQpOwogICAgICAgICAgICAgICAgaWYgKCRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0Q3VzdG9tQ2FjaGVLZXkoKSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR1cmxbJ2NhY2hlS2V5J10gPSAkY2FjaGVLZXlHZW5lcmF0b3IoJHBhY2thZ2UsICRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0Q3VzdG9tQ2FjaGVLZXkoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRQcm9jZXNzZWRVcmwoKSAhPT0gJHVybFsncHJvY2Vzc2VkJ10pIHsKICAgICAgICAgICAgICAgICAgICAkdXJsWydjYWNoZUtleSddID0gJGNhY2hlS2V5R2VuZXJhdG9yKCRwYWNrYWdlLCAkcHJlRmlsZURvd25sb2FkRXZlbnQtPmdldFByb2Nlc3NlZFVybCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR1cmxbJ3Byb2Nlc3NlZCddID0gJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRQcm9jZXNzZWRVcmwoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHVybHNbJGluZGV4XSA9ICR1cmw7CgogICAgICAgICAgICAkY2hlY2tzdW0gPSAkcGFja2FnZS0+Z2V0RGlzdFNoYTFDaGVja3N1bSgpOwogICAgICAgICAgICAkY2FjaGVLZXkgPSAkdXJsWydjYWNoZUtleSddOwoKICAgICAgICAgICAgLy8gdXNlIGZyb20gY2FjaGUgaWYgaXQgaXMgcHJlc2VudCBhbmQgaGFzIGEgdmFsaWQgY2hlY2tzdW0gb3Igd2UgaGF2ZSBubyBjaGVja3N1bSB0byBjaGVjayBhZ2FpbnN0CiAgICAgICAgICAgIGlmICgkY2FjaGUgJiYgKCEkY2hlY2tzdW0gfHwgJGNoZWNrc3VtID09PSAkY2FjaGUtPnNoYTEoJGNhY2hlS2V5KSkgJiYgJGNhY2hlLT5jb3B5VG8oJGNhY2hlS2V5LCAkZmlsZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiICAtIExvYWRpbmcgPGluZm8+IiAuICRwYWNrYWdlLT5nZXROYW1lKCkgLiAiPC9pbmZvPiAoPGNvbW1lbnQ+IiAuICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpIC4gIjwvY29tbWVudD4pIGZyb20gY2FjaGUiLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSWV9WRVJCT1NFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIG1hcmsgdGhlIGZpbGUgYXMgaGF2aW5nIGJlZW4gd3JpdHRlbiBpbiBjYWNoZSBldmVuIHRob3VnaCBpdCBpcyBvbmx5IHJlYWQgZnJvbSBjYWNoZSwgc28gdGhhdCBpZgogICAgICAgICAgICAgICAgLy8gdGhlIGNhY2hlIGlzIGNvcnJ1cHQgdGhlIGFyY2hpdmUgd2lsbCBiZSBkZWxldGVkIGFuZCB0aGUgbmV4dCBhdHRlbXB0IHdpbGwgcmUtZG93bmxvYWQgaXQKICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzEwMDI4CiAgICAgICAgICAgICAgICBpZiAoISRjYWNoZS0+aXNSZWFkT25seSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHNlbGYtPmxhc3RDYWNoZVdyaXRlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRjYWNoZUtleTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXN1bHQgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCRmaWxlTmFtZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiICAtIERvd25sb2FkaW5nIDxpbmZvPiIgLiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4gIjwvaW5mbz4gKDxjb21tZW50PiIgLiAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAuICI8L2NvbW1lbnQ+KSIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkaHR0cERvd25sb2FkZXItPmFkZENvcHkoJHVybFsncHJvY2Vzc2VkJ10sICRmaWxlTmFtZSwgJHBhY2thZ2UtPmdldFRyYW5zcG9ydE9wdGlvbnMoKSkKICAgICAgICAgICAgICAgICAgICAtPnRoZW4oJGFjY2VwdCwgJHJlamVjdCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0LT50aGVuKGZ1bmN0aW9uICgkcmVzdWx0KSB1c2UgKCRmaWxlTmFtZSwgJGNoZWNrc3VtLCAkdXJsLCAkcGFja2FnZSwgJGV2ZW50RGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBvZiByZXRyeSwgdGhlIGZpcnN0IGNhbGwncyBQcm9taXNlIGNoYWluIGZpbmFsbHkgY2FsbHMgdGhpcyB0d2ljZSBhdCB0aGUgZW5kLAogICAgICAgICAgICAgICAgLy8gb25jZSB3aXRoICRyZXN1bHQgYmVpbmcgdGhlIHJldHVybmVkICRmaWxlTmFtZSBmcm9tICRhY2NlcHQsIGFuZCB0aGVuIG9uY2UgZm9yIGV2ZXJ5CiAgICAgICAgICAgICAgICAvLyBmYWlsZWQgcmVxdWVzdCB3aXRoIGEgbnVsbCByZXN1bHQsIHdoaWNoIGNhbiBiZSBza2lwcGVkLgogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZpbGVOYW1lOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJGZpbGVOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCR1cmxbJ2Jhc2UnXS4nIGNvdWxkIG5vdCBiZSBzYXZlZCB0byAnLiRmaWxlTmFtZS4nLCBtYWtlIHN1cmUgdGhlJwogICAgICAgICAgICAgICAgICAgICAgICAuJyBkaXJlY3RvcnkgaXMgd3JpdGFibGUgYW5kIHlvdSBoYXZlIGludGVybmV0IGNvbm5lY3Rpdml0eScpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkY2hlY2tzdW0gJiYgaGFzaF9maWxlKCdzaGExJywgJGZpbGVOYW1lKSAhPT0gJGNoZWNrc3VtKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1RoZSBjaGVja3N1bSB2ZXJpZmljYXRpb24gb2YgdGhlIGZpbGUgZmFpbGVkIChkb3dubG9hZGVkIGZyb20gJy4kdXJsWydiYXNlJ10uJyknKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGV2ZW50RGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgICAgICRwb3N0RmlsZURvd25sb2FkRXZlbnQgPSBuZXcgUG9zdEZpbGVEb3dubG9hZEV2ZW50KFBsdWdpbkV2ZW50czo6UE9TVF9GSUxFX0RPV05MT0FELCAkZmlsZU5hbWUsICRjaGVja3N1bSwgJHVybFsncHJvY2Vzc2VkJ10sICdwYWNrYWdlJywgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICRldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwb3N0RmlsZURvd25sb2FkRXZlbnQtPmdldE5hbWUoKSwgJHBvc3RGaWxlRG93bmxvYWRFdmVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlTmFtZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKCiAgICAgICAgJGFjY2VwdCA9IGZ1bmN0aW9uICgkcmVzcG9uc2UpIHVzZSAoJGNhY2hlLCAkcGFja2FnZSwgJGZpbGVOYW1lLCAkc2VsZiwgJiR1cmxzKSB7CiAgICAgICAgICAgICR1cmwgPSByZXNldCgkdXJscyk7CiAgICAgICAgICAgICRjYWNoZUtleSA9ICR1cmxbJ2NhY2hlS2V5J107CiAgICAgICAgICAgIEZpbGVEb3dubG9hZGVyOjokZG93bmxvYWRNZXRhZGF0YVskcGFja2FnZS0+Z2V0TmFtZSgpXSA9IEBmaWxlc2l6ZSgkZmlsZU5hbWUpID86ICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdDb250ZW50LUxlbmd0aCcpID86ICc/JzsKCiAgICAgICAgICAgIGlmICgkY2FjaGUgJiYgISRjYWNoZS0+aXNSZWFkT25seSgpKSB7CiAgICAgICAgICAgICAgICAkc2VsZi0+bGFzdENhY2hlV3JpdGVzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJGNhY2hlS2V5OwogICAgICAgICAgICAgICAgJGNhY2hlLT5jb3B5RnJvbSgkY2FjaGVLZXksICRmaWxlTmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZXNwb25zZS0+Y29sbGVjdCgpOwoKICAgICAgICAgICAgcmV0dXJuICRmaWxlTmFtZTsKICAgICAgICB9OwoKICAgICAgICAkcmVqZWN0ID0gZnVuY3Rpb24gKCRlKSB1c2UgKCRpbywgJiR1cmxzLCAkZG93bmxvYWQsICRmaWxlTmFtZSwgJHBhY2thZ2UsICYkcmV0cmllcywgJGZpbGVzeXN0ZW0sICRzZWxmKSB7CiAgICAgICAgICAgIC8vIGNsZWFuIHVwCiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZU5hbWUpKSB7CiAgICAgICAgICAgICAgICAkZmlsZXN5c3RlbS0+dW5saW5rKCRmaWxlTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNlbGYtPmNsZWFyTGFzdENhY2hlV3JpdGUoJHBhY2thZ2UpOwoKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgSXJyZWNvdmVyYWJsZURvd25sb2FkRXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgLy8gaWYgd2UgZ290IGFuIGh0dHAgcmVzcG9uc2Ugd2l0aCBhIHByb3BlciBjb2RlLCB0aGVuIHJlcXVlc3RpbmcgYWdhaW4gd2lsbCBwcm9iYWJseSBub3QgaGVscCwgYWJvcnQKICAgICAgICAgICAgICAgIGlmICgoMCAhPT0gJGUtPmdldENvZGUoKSAmJiAhaW5fYXJyYXkoJGUtPmdldENvZGUoKSwgYXJyYXkoNTAwLCA1MDIsIDUwMywgNTA0KSkpIHx8ICEkcmV0cmllcykgewogICAgICAgICAgICAgICAgICAgICRyZXRyaWVzID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3BlY2lhbCBlcnJvciBjb2RlIHJldHVybmVkIHdoZW4gbmV0d29yayBpcyBiZWluZyBhcnRpZmljaWFsbHkgZGlzYWJsZWQKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQ5OSkgewogICAgICAgICAgICAgICAgJHJldHJpZXMgPSAwOwogICAgICAgICAgICAgICAgJHVybHMgPSBhcnJheSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHJldHJpZXMpIHsKICAgICAgICAgICAgICAgIHVzbGVlcCg1MDAwMDApOwogICAgICAgICAgICAgICAgJHJldHJpZXMtLTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJGRvd25sb2FkKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFycmF5X3NoaWZ0KCR1cmxzKTsKICAgICAgICAgICAgaWYgKCR1cmxzKSB7CiAgICAgICAgICAgICAgICBpZiAoJGlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICBGYWlsZWQgZG93bmxvYWRpbmcgJy4kcGFja2FnZS0+Z2V0TmFtZSgpLic6IFsnLmdldF9jbGFzcygkZSkuJ10gJy4kZS0+Z2V0Q29kZSgpLic6ICcuJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgVHJ5aW5nIHRoZSBuZXh0IFVSTCBmb3IgJy4kcGFja2FnZS0+Z2V0TmFtZSgpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgRmFpbGVkIGRvd25sb2FkaW5nICcuJHBhY2thZ2UtPmdldE5hbWUoKS4nLCB0cnlpbmcgdGhlIG5leHQgVVJMICgnLiRlLT5nZXRDb2RlKCkuJzogJy4kZS0+Z2V0TWVzc2FnZSgpLicpJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJldHJpZXMgPSAzOwogICAgICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9OwoKICAgICAgICByZXR1cm4gJGRvd25sb2FkKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmdldEZpbGVOYW1lKCRwYWNrYWdlLCAkcGF0aCk7CiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnVubGluaygkZmlsZU5hbWUpOwogICAgICAgIH0KCiAgICAgICAgJGRpcnNUb0NsZWFuVXAgPSBhcnJheSgKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJykuJy9jb21wb3Nlci8nLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKSwKICAgICAgICAgICAgJHBhdGgsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hZGRpdGlvbmFsQ2xlYW51cFBhdGhzWyRwYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWRkaXRpb25hbENsZWFudXBQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXSBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZSgkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRkaXJzVG9DbGVhblVwIGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKGlzX2RpcigkZGlyKSAmJiAkdGhpcy0+ZmlsZXN5c3RlbS0+aXNEaXJFbXB0eSgkZGlyKSAmJiByZWFscGF0aCgkZGlyKSAhPT0gZ2V0Y3dkKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVEaXJlY3RvcnlQaHAoJGRpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRvdXRwdXQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBJbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbXB0eURpcmVjdG9yeSgkcGF0aCk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkcGF0aCk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbmFtZSgkdGhpcy0+Z2V0RmlsZU5hbWUoJHBhY2thZ2UsICRwYXRoKSwgJHBhdGggLiAnLycgLiBwYXRoaW5mbyhwYXJzZV91cmwoJHBhY2thZ2UtPmdldERpc3RVcmwoKSwgUEhQX1VSTF9QQVRIKSwgUEFUSElORk9fQkFTRU5BTUUpKTsKCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRCaW5hcmllcygpKSB7CiAgICAgICAgICAgIC8vIFNpbmdsZSBmaWxlcyBjYW4gbm90IGhhdmUgYSBtb2RlIHNldCBsaWtlIGZpbGVzIGluIGFyY2hpdmVzCiAgICAgICAgICAgIC8vIHNvIHdlIG1ha2Ugc3VyZSBpZiB0aGUgZmlsZSBpcyBhIGJpbmFyeSB0aGF0IGl0IGlzIGV4ZWN1dGFibGUKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldEJpbmFyaWVzKCkgYXMgJGJpbikgewogICAgICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRwYXRoIC4gJy8nIC4gJGJpbikgJiYgIWlzX2V4ZWN1dGFibGUoJHBhdGggLiAnLycgLiAkYmluKSkgewogICAgICAgICAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdjaG1vZCcsICRwYXRoIC4gJy8nIC4gJGJpbiwgMDc3NyAmIH51bWFzaygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRPRE8gbWFyayBwcml2YXRlIGluIHYzCiAgICAgKiBAcHJvdGVjdGVkIFRoaXMgaXMgcHVibGljIGR1ZSB0byBQSFAgNS4zCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhckxhc3RDYWNoZVdyaXRlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jYWNoZSAmJiBpc3NldCgkdGhpcy0+bGFzdENhY2hlV3JpdGVzWyRwYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPnJlbW92ZSgkdGhpcy0+bGFzdENhY2hlV3JpdGVzWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmxhc3RDYWNoZVdyaXRlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVE9ETyBtYXJrIHByaXZhdGUgaW4gdjMKICAgICAqIEBwcm90ZWN0ZWQgVGhpcyBpcyBwdWJsaWMgZHVlIHRvIFBIUCA1LjMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDbGVhbnVwUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+YWRkaXRpb25hbENsZWFudXBQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXVtdID0gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBUT0RPIG1hcmsgcHJpdmF0ZSBpbiB2MwogICAgICogQHByb3RlY3RlZCBUaGlzIGlzIHB1YmxpYyBkdWUgdG8gUEhQIDUuMwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUNsZWFudXBQYXRoKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+YWRkaXRpb25hbENsZWFudXBQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgJGlkeCA9IGFycmF5X3NlYXJjaCgkcGF0aCwgJHRoaXMtPmFkZGl0aW9uYWxDbGVhbnVwUGF0aHNbJHBhY2thZ2UtPmdldE5hbWUoKV0pOwogICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRpZHgpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5hZGRpdGlvbmFsQ2xlYW51cFBhdGhzWyRwYWNrYWdlLT5nZXROYW1lKCldWyRpZHhdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0LCAkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVXBkYXRlT3BlcmF0aW9uOjpmb3JtYXQoJGluaXRpYWwsICR0YXJnZXQpIC4gJHRoaXMtPmdldEluc3RhbGxPcGVyYXRpb25BcHBlbmRpeCgkdGFyZ2V0LCAkcGF0aCkpOwoKICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5yZW1vdmUoJGluaXRpYWwsICRwYXRoLCBmYWxzZSk7CiAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQogICAgICAgICRzZWxmID0gJHRoaXM7CiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwoKICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkc2VsZiwgJHRhcmdldCwgJHBhdGgpIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkc2VsZi0+aW5zdGFsbCgkdGFyZ2V0LCAkcGF0aCwgZmFsc2UpOwoKICAgICAgICAgICAgcmV0dXJuICRwcm9taXNlOwogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkb3V0cHV0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBVbmluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkpOwogICAgICAgIH0KICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVEaXJlY3RvcnlBc3luYygkcGF0aCk7CgogICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoJHJlc3VsdCkgdXNlICgkcGF0aCkgewogICAgICAgICAgICBpZiAoISRyZXN1bHQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IGNvbXBsZXRlbHkgZGVsZXRlICcuJHBhdGguJywgYWJvcnRpbmcuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgZmlsZSBuYW1lIGZvciBzcGVjaWZpYyBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgICAgZmlsZSBuYW1lCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRGaWxlTmFtZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gcnRyaW0oJHRoaXMtPmNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJykuJy9jb21wb3Nlci90bXAtJy5tZDUoJHBhY2thZ2Uuc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKSkuJy4nLnBhdGhpbmZvKHBhcnNlX3VybCgkcGFja2FnZS0+Z2V0RGlzdFVybCgpLCBQSFBfVVJMX1BBVEgpLCBQQVRISU5GT19FWFRFTlNJT04pLCAnLicpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhcHBlbmRpeCBtZXNzYWdlIHRvIGFkZCB0byB0aGUgIi0gVXBncmFkaW5nIHgiIHN0cmluZyBiZWluZyBvdXRwdXQgb24gdXBkYXRlCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0SW5zdGFsbE9wZXJhdGlvbkFwcGVuZGl4KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIHJldHVybiAnJzsKICAgIH0KCiAgICAvKioKICAgICAqIFByb2Nlc3MgdGhlIGRvd25sb2FkIHVybAogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgJHBhY2thZ2UgcGFja2FnZSB0aGUgdXJsIGlzIGNvbWluZyBmcm9tCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICR1cmwgICAgIGRvd25sb2FkIHVybAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBJZiBhbnkgcHJvYmxlbSB3aXRoIHRoZSB1cmwKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICAgdXJsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcm9jZXNzVXJsKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICR1cmwpCiAgICB7CiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykgJiYgMCA9PT0gc3RycG9zKCR1cmwsICdodHRwczonKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1lvdSBtdXN0IGVuYWJsZSB0aGUgb3BlbnNzbCBleHRlbnNpb24gdG8gZG93bmxvYWQgZmlsZXMgdmlhIGh0dHBzJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSkgewogICAgICAgICAgICAkdXJsID0gVXJsVXRpbDo6dXBkYXRlRGlzdFJlZmVyZW5jZSgkdGhpcy0+Y29uZmlnLCAkdXJsLCAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2FsQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyKQogICAgewogICAgICAgICRwcmV2SU8gPSAkdGhpcy0+aW87CgogICAgICAgICR0aGlzLT5pbyA9IG5ldyBOdWxsSU87CiAgICAgICAgJHRoaXMtPmlvLT5sb2FkQ29uZmlndXJhdGlvbigkdGhpcy0+Y29uZmlnKTsKICAgICAgICAkZSA9IG51bGw7CiAgICAgICAgJG91dHB1dCA9ICcnOwoKICAgICAgICAkdGFyZ2V0RGlyID0gRmlsZXN5c3RlbTo6dHJpbVRyYWlsaW5nU2xhc2goJHRhcmdldERpcik7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKGlzX2RpcigkdGFyZ2V0RGlyLidfY29tcGFyZScpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCR0YXJnZXREaXIuJ19jb21wYXJlJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5kb3dubG9hZCgkcGFja2FnZSwgJHRhcmdldERpci4nX2NvbXBhcmUnLCBudWxsLCBmYWxzZSk7CiAgICAgICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlci0+d2FpdCgpOwogICAgICAgICAgICAkdGhpcy0+aW5zdGFsbCgkcGFja2FnZSwgJHRhcmdldERpci4nX2NvbXBhcmUnLCBmYWxzZSk7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT53YWl0KCk7CgogICAgICAgICAgICAkY29tcGFyZXIgPSBuZXcgQ29tcGFyZXIoKTsKICAgICAgICAgICAgJGNvbXBhcmVyLT5zZXRTb3VyY2UoJHRhcmdldERpci4nX2NvbXBhcmUnKTsKICAgICAgICAgICAgJGNvbXBhcmVyLT5zZXRVcGRhdGUoJHRhcmdldERpcik7CiAgICAgICAgICAgICRjb21wYXJlci0+ZG9Db21wYXJlKCk7CiAgICAgICAgICAgICRvdXRwdXQgPSAkY29tcGFyZXItPmdldENoYW5nZWQodHJ1ZSwgdHJ1ZSk7CiAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVEaXJlY3RvcnkoJHRhcmdldERpci4nX2NvbXBhcmUnKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8gPSAkcHJldklPOwoKICAgICAgICBpZiAoJGUpIHsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJpbSgkb3V0cHV0KTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcU3ZuIGFzIFN2blV0aWw7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEJlbiBCaWVrZXIgPG1haWxAYmVuLWJpZWtlci5kZT4KICogQGF1dGhvciBUaWxsIEtsYW1wYWVja2VsIDx0aWxsQHBocC5uZXQ+CiAqLwpjbGFzcyBTdm5Eb3dubG9hZGVyIGV4dGVuZHMgVmNzRG93bmxvYWRlcgp7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGNhY2hlQ3JlZGVudGlhbHMgPSB0cnVlOwoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICBTdm5VdGlsOjpjbGVhbkVudigpOwogICAgICAgICR1dGlsID0gbmV3IFN2blV0aWwoJHVybCwgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgaWYgKG51bGwgPT09ICR1dGlsLT5iaW5hcnlWZXJzaW9uKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdzdm4gd2FzIG5vdCBmb3VuZCBpbiB5b3VyIFBBVEgsIHNraXBwaW5nIHNvdXJjZSBkb3dubG9hZCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgU3ZuVXRpbDo6Y2xlYW5FbnYoKTsKICAgICAgICAkcmVmID0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpOwoKICAgICAgICAkcmVwbyA9ICRwYWNrYWdlLT5nZXRSZXBvc2l0b3J5KCk7CiAgICAgICAgaWYgKCRyZXBvIGluc3RhbmNlb2YgVmNzUmVwb3NpdG9yeSkgewogICAgICAgICAgICAkcmVwb0NvbmZpZyA9ICRyZXBvLT5nZXRSZXBvQ29uZmlnKCk7CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdzdm4tY2FjaGUtY3JlZGVudGlhbHMnLCAkcmVwb0NvbmZpZykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZUNyZWRlbnRpYWxzID0gKGJvb2wpICRyZXBvQ29uZmlnWydzdm4tY2FjaGUtY3JlZGVudGlhbHMnXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgQ2hlY2tpbmcgb3V0ICIuJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZSgkcGFja2FnZSwgJHVybCwgInN2biBjbyIsIHNwcmludGYoIiVzLyVzIiwgJHVybCwgJHJlZiksIG51bGwsICRwYXRoKTsKCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1VwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgIFN2blV0aWw6OmNsZWFuRW52KCk7CiAgICAgICAgJHJlZiA9ICR0YXJnZXQtPmdldFNvdXJjZVJlZmVyZW5jZSgpOwoKICAgICAgICBpZiAoISR0aGlzLT5oYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIC5zdm4gZGlyZWN0b3J5IGlzIG1pc3NpbmcgZnJvbSAnLiRwYXRoLicsIHNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9jb21taXQtZGVwcyBmb3IgbW9yZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJHV0aWwgPSBuZXcgU3ZuVXRpbCgkdXJsLCAkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzKTsKICAgICAgICAkZmxhZ3MgPSAiIjsKICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKCR1dGlsLT5iaW5hcnlWZXJzaW9uKCksICcxLjcuMCcsICc+PScpKSB7CiAgICAgICAgICAgICRmbGFncyAuPSAnIC0taWdub3JlLWFuY2VzdHJ5JzsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiIENoZWNraW5nIG91dCAiIC4gJHJlZik7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGUoJHRhcmdldCwgJHVybCwgInN2biBzd2l0Y2giIC4gJGZsYWdzLCBzcHJpbnRmKCIlcy8lcyIsICR1cmwsICRyZWYpLCAkcGF0aCk7CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYWxDaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnc3ZuIHN0YXR1cyAtLWlnbm9yZS1leHRlcm5hbHMnLCAkb3V0cHV0LCAkcGF0aCk7CgogICAgICAgIHJldHVybiBQcmVnOjppc01hdGNoKCd7XiAqW15YIF0gK31tJywgJG91dHB1dCkgPyAkb3V0cHV0IDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGUgYW4gU1ZOIGNvbW1hbmQgYW5kIHRyeSB0byBmaXggdXAgdGhlIHByb2Nlc3Mgd2l0aCBjcmVkZW50aWFscwogICAgICogaWYgbmVjZXNzYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGJhc2VVcmwgQmFzZSBVUkwgb2YgdGhlIHJlcG9zaXRvcnkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGNvbW1hbmQgU1ZOIGNvbW1hbmQgdG8gcnVuCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICR1cmwgICAgIFNWTiB1cmwKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGN3ZCAgICAgV29ya2luZyBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGggICAgVGFyZ2V0IGZvciBhIGNoZWNrb3V0CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkYmFzZVVybCwgJGNvbW1hbmQsICR1cmwsICRjd2QgPSBudWxsLCAkcGF0aCA9IG51bGwpCiAgICB7CiAgICAgICAgJHV0aWwgPSBuZXcgU3ZuVXRpbCgkYmFzZVVybCwgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgJHV0aWwtPnNldENhY2hlQ3JlZGVudGlhbHMoJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAkdXRpbC0+ZXhlY3V0ZSgkY29tbWFuZCwgJHVybCwgJGN3ZCwgJHBhdGgsICR0aGlzLT5pby0+aXNWZXJib3NlKCkpOwogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBjb3VsZCBub3QgYmUgZG93bmxvYWRlZCwgJy4kZS0+Z2V0TWVzc2FnZSgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNsZWFuQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVwZGF0ZSkKICAgIHsKICAgICAgICBpZiAoISRjaGFuZ2VzID0gJHRoaXMtPmdldExvY2FsQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgIGlmICh0cnVlID09PSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2Rpc2NhcmQtY2hhbmdlcycpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRpc2NhcmRDaGFuZ2VzKCRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Y2xlYW5DaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCwgJHVwZGF0ZSk7CiAgICAgICAgfQoKICAgICAgICAkY2hhbmdlcyA9IGFycmF5X21hcChmdW5jdGlvbiAoJGVsZW0pIHsKICAgICAgICAgICAgcmV0dXJuICcgICAgJy4kZWxlbTsKICAgICAgICB9LCBQcmVnOjpzcGxpdCgne1xzKlxyP1xuXHMqfScsICRjaGFuZ2VzKSk7CiAgICAgICAgJGNvdW50Q2hhbmdlcyA9IGNvdW50KCRjaGFuZ2VzKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignICAgIDxlcnJvcj4nLiRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBoYXMgbW9kaWZpZWQgZmlsZSVzOjwvZXJyb3I+JywgJGNvdW50Q2hhbmdlcyA9PT0gMSA/ICcnIDogJ3MnKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5X3NsaWNlKCRjaGFuZ2VzLCAwLCAxMCkpOwogICAgICAgIGlmICgkY291bnRDaGFuZ2VzID4gMTApIHsKICAgICAgICAgICAgJHJlbWFpbmluZ0NoYW5nZXMgPSAkY291bnRDaGFuZ2VzIC0gMTA7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgIHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJyAgICA8aW5mbz4nLiRyZW1haW5pbmdDaGFuZ2VzLicgbW9yZSBmaWxlJXMgbW9kaWZpZWQsIGNob29zZSAidiIgdG8gdmlldyB0aGUgZnVsbCBsaXN0PC9pbmZvPicsCiAgICAgICAgICAgICAgICAgICAgJHJlbWFpbmluZ0NoYW5nZXMgPT09IDEgPyAnJyA6ICdzJwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+aW8tPmFzaygnICAgIDxpbmZvPkRpc2NhcmQgY2hhbmdlcyBbeSxuLHYsP10/PC9pbmZvPiAnLCAnPycpKSB7CiAgICAgICAgICAgICAgICBjYXNlICd5JzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzY2FyZENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CgogICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdVcGRhdGUgYWJvcnRlZCcpOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkY2hhbmdlcyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnPyc6CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICB5IC0gZGlzY2FyZCBjaGFuZ2VzIGFuZCBhcHBseSB0aGUgJy4oJHVwZGF0ZSA/ICd1cGRhdGUnIDogJ3VuaW5zdGFsbCcpLAogICAgICAgICAgICAgICAgICAgICAgICAnICAgIG4gLSBhYm9ydCB0aGUgJy4oJHVwZGF0ZSA/ICd1cGRhdGUnIDogJ3VuaW5zdGFsbCcpLicgYW5kIGxldCB5b3UgbWFudWFsbHkgY2xlYW4gdGhpbmdzIHVwJywKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICB2IC0gdmlldyBtb2RpZmllZCBmaWxlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICcgICAgPyAtIHByaW50IGhlbHAnLAogICAgICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3tAKFxkKykkfScsICRmcm9tUmVmZXJlbmNlKSAmJiBQcmVnOjppc01hdGNoKCd7QChcZCspJH0nLCAkdG9SZWZlcmVuY2UpKSB7CiAgICAgICAgICAgIC8vIHJldHJpZXZlIHRoZSBzdm4gYmFzZSB1cmwgZnJvbSB0aGUgY2hlY2tvdXQgZm9sZGVyCiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50Zignc3ZuIGluZm8gLS1ub24taW50ZXJhY3RpdmUgLS14bWwgLS0gJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGF0aCkpOwogICAgICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHVybFBhdHRlcm4gPSAnIzx1cmw+KC4qKTwvdXJsPiMnOwogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgkdXJsUGF0dGVybiwgJG91dHB1dCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAkYmFzZVVybCA9ICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdVbmFibGUgdG8gZGV0ZXJtaW5lIHN2biB1cmwgZm9yIHBhdGggJy4gJHBhdGgKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHN0cmlwIHBhdGhzIGZyb20gcmVmZXJlbmNlcyBhbmQgb25seSBrZWVwIHRoZSBhY3R1YWwgcmV2aXNpb24KICAgICAgICAgICAgJGZyb21SZXZpc2lvbiA9IFByZWc6OnJlcGxhY2UoJ3suKkAoXGQrKSR9JywgJyQxJywgJGZyb21SZWZlcmVuY2UpOwogICAgICAgICAgICAkdG9SZXZpc2lvbiA9IFByZWc6OnJlcGxhY2UoJ3suKkAoXGQrKSR9JywgJyQxJywgJHRvUmVmZXJlbmNlKTsKCiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50Zignc3ZuIGxvZyAtciVzOiVzIC0taW5jcmVtZW50YWwnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZnJvbVJldmlzaW9uKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRvUmV2aXNpb24pKTsKCiAgICAgICAgICAgICR1dGlsID0gbmV3IFN2blV0aWwoJGJhc2VVcmwsICR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICAgICAkdXRpbC0+c2V0Q2FjaGVDcmVkZW50aWFscygkdGhpcy0+Y2FjaGVDcmVkZW50aWFscyk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHV0aWwtPmV4ZWN1dGVMb2NhbCgkY29tbWFuZCwgJHBhdGgsIG51bGwsICR0aGlzLT5pby0+aXNWZXJib3NlKCkpOwogICAgICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIuJGUtPmdldE1lc3NhZ2UoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICJDb3VsZCBub3QgcmV0cmlldmUgY2hhbmdlcyBiZXR3ZWVuICRmcm9tUmVmZXJlbmNlIGFuZCAkdG9SZWZlcmVuY2UgZHVlIHRvIG1pc3NpbmcgcmV2aXNpb24gaW5mb3JtYXRpb24iOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGlzY2FyZENoYW5nZXMoJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdzdm4gcmV2ZXJ0IC1SIC4nLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJDb3VsZCBub3QgcmVzZXQgY2hhbmdlc1xuXG46Ii4kdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gaXNfZGlyKCRwYXRoLicvLnN2bicpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIERWQ1MgRG93bmxvYWRlciBpbnRlcmZhY2UuCiAqCiAqIEBhdXRob3IgSmFtZXMgVGl0Y3VtYiA8amFtZXNAYXNncmltLmNvbT4KICovCmludGVyZmFjZSBEdmNzRG93bmxvYWRlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENoZWNrcyBmb3IgdW5wdXNoZWQgY2hhbmdlcyB0byBhIGN1cnJlbnQgYnJhbmNoCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgJHBhdGggICAgcGFja2FnZSBkaXJlY3RvcnkKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgICAgICBjaGFuZ2VzIG9yIG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVucHVzaGVkQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXEV4Y2VwdGlvblxJcnJlY292ZXJhYmxlRG93bmxvYWRFeGNlcHRpb247CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogRG93bmxvYWRlcnMgbWFuYWdlci4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmNsYXNzIERvd25sb2FkTWFuYWdlcgp7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRwcmVmZXJEaXN0ID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRwcmVmZXJTb3VyY2U7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gKi8KICAgIHByaXZhdGUgJHBhY2thZ2VQcmVmZXJlbmNlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBGaWxlc3lzdGVtICovCiAgICBwcml2YXRlICRmaWxlc3lzdGVtOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBEb3dubG9hZGVySW50ZXJmYWNlPiAqLwogICAgcHJpdmF0ZSAkZG93bmxvYWRlcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgZG93bmxvYWQgbWFuYWdlci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICAgICAgVGhlIElucHV0IE91dHB1dCBJbnRlcmZhY2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgJHByZWZlclNvdXJjZSBwcmVmZXIgZG93bmxvYWRpbmcgZnJvbSBzb3VyY2UKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtfG51bGwgJGZpbGVzeXN0ZW0gICBjdXN0b20gRmlsZXN5c3RlbSBvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgJHByZWZlclNvdXJjZSA9IGZhbHNlLCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPnByZWZlclNvdXJjZSA9ICRwcmVmZXJTb3VyY2U7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZmlsZXN5c3RlbSA/OiBuZXcgRmlsZXN5c3RlbSgpOwogICAgfQoKICAgIC8qKgogICAgICogTWFrZXMgZG93bmxvYWRlciBwcmVmZXIgc291cmNlIGluc3RhbGxhdGlvbiBvdmVyIHRoZSBkaXN0LgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICRwcmVmZXJTb3VyY2UgcHJlZmVyIGRvd25sb2FkaW5nIGZyb20gc291cmNlCiAgICAgKiBAcmV0dXJuIERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZmVyU291cmNlKCRwcmVmZXJTb3VyY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlclNvdXJjZSA9ICRwcmVmZXJTb3VyY2U7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIE1ha2VzIGRvd25sb2FkZXIgcHJlZmVyIGRpc3QgaW5zdGFsbGF0aW9uIG92ZXIgdGhlIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAkcHJlZmVyRGlzdCBwcmVmZXIgZG93bmxvYWRpbmcgZnJvbSBkaXN0CiAgICAgKiBAcmV0dXJuIERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZmVyRGlzdCgkcHJlZmVyRGlzdCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJlZmVyRGlzdCA9ICRwcmVmZXJEaXN0OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGZpbmUgdHVuZWQgcHJlZmVyZW5jZSBzZXR0aW5ncyBmb3IgcGFja2FnZSBsZXZlbCBzb3VyY2UvZGlzdCBzZWxlY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkcHJlZmVyZW5jZXMgYXJyYXkgb2YgcHJlZmVyZW5jZXMgYnkgcGFja2FnZSBwYXR0ZXJucwogICAgICoKICAgICAqIEByZXR1cm4gRG93bmxvYWRNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmZXJlbmNlcyhhcnJheSAkcHJlZmVyZW5jZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VQcmVmZXJlbmNlcyA9ICRwcmVmZXJlbmNlczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBpbnN0YWxsZXIgZG93bmxvYWRlciBmb3IgYSBzcGVjaWZpYyBpbnN0YWxsYXRpb24gdHlwZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgJHR5cGUgICAgICAgaW5zdGFsbGF0aW9uIHR5cGUKICAgICAqIEBwYXJhbSAgRG93bmxvYWRlckludGVyZmFjZSAkZG93bmxvYWRlciBkb3dubG9hZGVyIGluc3RhbmNlCiAgICAgKiBAcmV0dXJuIERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RG93bmxvYWRlcigkdHlwZSwgRG93bmxvYWRlckludGVyZmFjZSAkZG93bmxvYWRlcikKICAgIHsKICAgICAgICAkdHlwZSA9IHN0cnRvbG93ZXIoJHR5cGUpOwogICAgICAgICR0aGlzLT5kb3dubG9hZGVyc1skdHlwZV0gPSAkZG93bmxvYWRlcjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBkb3dubG9hZGVyIGZvciBhIHNwZWNpZmljIGluc3RhbGxhdGlvbiB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkdHlwZSBpbnN0YWxsYXRpb24gdHlwZQogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGRvd25sb2FkZXIgZm9yIHByb3ZpZGVkIHR5cGUgaXMgbm90IHJlZ2lzdGVyZWQKICAgICAqIEByZXR1cm4gRG93bmxvYWRlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RG93bmxvYWRlcigkdHlwZSkKICAgIHsKICAgICAgICAkdHlwZSA9IHN0cnRvbG93ZXIoJHR5cGUpOwogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmRvd25sb2FkZXJzWyR0eXBlXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5rbm93biBkb3dubG9hZGVyIHR5cGU6ICVzLiBBdmFpbGFibGUgdHlwZXM6ICVzLicsICR0eXBlLCBpbXBsb2RlKCcsICcsIGFycmF5X2tleXMoJHRoaXMtPmRvd25sb2FkZXJzKSkpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZG93bmxvYWRlcnNbJHR5cGVdOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBkb3dubG9hZGVyIGZvciBhbHJlYWR5IGluc3RhbGxlZCBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICAgICAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgcGFja2FnZSBoYXMgbm8gaW5zdGFsbGF0aW9uIHNvdXJjZSBzcGVjaWZpZWQKICAgICAqIEB0aHJvd3MgXExvZ2ljRXhjZXB0aW9uICAgICAgICAgICBpZiBzcGVjaWZpYyBkb3dubG9hZGVyIHVzZWQgdG8gbG9hZCBwYWNrYWdlIHdpdGgKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyb25nIHR5cGUKICAgICAqIEByZXR1cm4gRG93bmxvYWRlckludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREb3dubG9hZGVyRm9yUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRpbnN0YWxsYXRpb25Tb3VyY2UgPSAkcGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCk7CgogICAgICAgIGlmICgnbWV0YXBhY2thZ2UnID09PSAkcGFja2FnZS0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdkaXN0JyA9PT0gJGluc3RhbGxhdGlvblNvdXJjZSkgewogICAgICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzLT5nZXREb3dubG9hZGVyKCRwYWNrYWdlLT5nZXREaXN0VHlwZSgpKTsKICAgICAgICB9IGVsc2VpZiAoJ3NvdXJjZScgPT09ICRpbnN0YWxsYXRpb25Tb3VyY2UpIHsKICAgICAgICAgICAgJGRvd25sb2FkZXIgPSAkdGhpcy0+Z2V0RG93bmxvYWRlcigkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICdQYWNrYWdlICcuJHBhY2thZ2UuJyBkb2VzIG5vdCBoYXZlIGFuIGluc3RhbGxhdGlvbiBzb3VyY2Ugc2V0JwogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnN0YWxsYXRpb25Tb3VyY2UgIT09ICRkb3dubG9hZGVyLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnRG93bmxvYWRlciAiJXMiIGlzIGEgJXMgdHlwZSBkb3dubG9hZGVyIGFuZCBjYW4gbm90IGJlIHVzZWQgdG8gZG93bmxvYWQgJXMgZm9yIHBhY2thZ2UgJXMnLAogICAgICAgICAgICAgICAgZ2V0X2NsYXNzKCRkb3dubG9hZGVyKSwKICAgICAgICAgICAgICAgICRkb3dubG9hZGVyLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSwKICAgICAgICAgICAgICAgICRpbnN0YWxsYXRpb25Tb3VyY2UsCiAgICAgICAgICAgICAgICAkcGFja2FnZQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZG93bmxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREb3dubG9hZGVyVHlwZShEb3dubG9hZGVySW50ZXJmYWNlICRkb3dubG9hZGVyKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9zZWFyY2goJGRvd25sb2FkZXIsICR0aGlzLT5kb3dubG9hZGVycyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEb3dubG9hZHMgcGFja2FnZSBpbnRvIHRhcmdldCBkaXIuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAkdGFyZ2V0RGlyICAgdGFyZ2V0IGRpcgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAkcHJldlBhY2thZ2UgcHJldmlvdXMgcGFja2FnZSBpbnN0YW5jZSBpbiBjYXNlIG9mIHVwZGF0ZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgcGFja2FnZSBoYXZlIG5vIHVybHMgdG8gZG93bmxvYWQgZnJvbQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRhcmdldERpciA9ICR0aGlzLT5ub3JtYWxpemVUYXJnZXREaXIoJHRhcmdldERpcik7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cyhkaXJuYW1lKCR0YXJnZXREaXIpKTsKCiAgICAgICAgJHNvdXJjZXMgPSAkdGhpcy0+Z2V0QXZhaWxhYmxlU291cmNlcygkcGFja2FnZSwgJHByZXZQYWNrYWdlKTsKCiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICRzZWxmID0gJHRoaXM7CgogICAgICAgICRkb3dubG9hZCA9IGZ1bmN0aW9uICgkcmV0cnkgPSBmYWxzZSkgdXNlICgmJHNvdXJjZXMsICRpbywgJHBhY2thZ2UsICRzZWxmLCAkdGFyZ2V0RGlyLCAmJGRvd25sb2FkLCAkcHJldlBhY2thZ2UpIHsKICAgICAgICAgICAgJHNvdXJjZSA9IGFycmF5X3NoaWZ0KCRzb3VyY2VzKTsKICAgICAgICAgICAgaWYgKCRyZXRyeSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgPHdhcm5pbmc+Tm93IHRyeWluZyB0byBkb3dubG9hZCBmcm9tICcgLiAkc291cmNlIC4gJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZS0+c2V0SW5zdGFsbGF0aW9uU291cmNlKCRzb3VyY2UpOwoKICAgICAgICAgICAgJGRvd25sb2FkZXIgPSAkc2VsZi0+Z2V0RG93bmxvYWRlckZvclBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICBpZiAoISRkb3dubG9hZGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaGFuZGxlRXJyb3IgPSBmdW5jdGlvbiAoJGUpIHVzZSAoJHNvdXJjZXMsICRzb3VyY2UsICRwYWNrYWdlLCAkaW8sICRkb3dubG9hZCkgewogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgXFJ1bnRpbWVFeGNlcHRpb24gJiYgISRlIGluc3RhbmNlb2YgSXJyZWNvdmVyYWJsZURvd25sb2FkRXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkc291cmNlcykgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICA8d2FybmluZz5GYWlsZWQgdG8gZG93bmxvYWQgJy4KICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4KICAgICAgICAgICAgICAgICAgICAgICAgJyBmcm9tICcgLiAkc291cmNlIC4gJzogJy4KICAgICAgICAgICAgICAgICAgICAgICAgJGUtPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGRvd25sb2FkKHRydWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkZG93bmxvYWRlci0+ZG93bmxvYWQoJHBhY2thZ2UsICR0YXJnZXREaXIsICRwcmV2UGFja2FnZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkaGFuZGxlRXJyb3IoJGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCRyZXN1bHQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzID0gJHJlc3VsdC0+dGhlbihmdW5jdGlvbiAoJHJlcykgewogICAgICAgICAgICAgICAgcmV0dXJuICRyZXM7CiAgICAgICAgICAgIH0sICRoYW5kbGVFcnJvcik7CgogICAgICAgICAgICByZXR1cm4gJHJlczsKICAgICAgICB9OwoKICAgICAgICByZXR1cm4gJGRvd25sb2FkKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmVwYXJlcyBhbiBvcGVyYXRpb24gZXhlY3V0aW9uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAkdHlwZSAgICAgICAgb25lIG9mIGluc3RhbGwvdXBkYXRlL3VuaW5zdGFsbAogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAkdGFyZ2V0RGlyICAgdGFyZ2V0IGRpcgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAkcHJldlBhY2thZ2UgcHJldmlvdXMgcGFja2FnZSBpbnN0YW5jZSBpbiBjYXNlIG9mIHVwZGF0ZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHRhcmdldERpciwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICR0YXJnZXREaXIgPSAkdGhpcy0+bm9ybWFsaXplVGFyZ2V0RGlyKCR0YXJnZXREaXIpOwogICAgICAgICRkb3dubG9hZGVyID0gJHRoaXMtPmdldERvd25sb2FkZXJGb3JQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJGRvd25sb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZGVyLT5wcmVwYXJlKCR0eXBlLCAkcGFja2FnZSwgJHRhcmdldERpciwgJHByZXZQYWNrYWdlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnN0YWxscyBwYWNrYWdlIGludG8gdGFyZ2V0IGRpci4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSAgIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICR0YXJnZXREaXIgdGFyZ2V0IGRpcgogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiBwYWNrYWdlIGhhdmUgbm8gdXJscyB0byBkb3dubG9hZCBmcm9tCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyKQogICAgewogICAgICAgICR0YXJnZXREaXIgPSAkdGhpcy0+bm9ybWFsaXplVGFyZ2V0RGlyKCR0YXJnZXREaXIpOwogICAgICAgICRkb3dubG9hZGVyID0gJHRoaXMtPmdldERvd25sb2FkZXJGb3JQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJGRvd25sb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZGVyLT5pbnN0YWxsKCRwYWNrYWdlLCAkdGFyZ2V0RGlyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBVcGRhdGVzIHBhY2thZ2UgZnJvbSBpbml0aWFsIHRvIHRhcmdldCB2ZXJzaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsICAgaW5pdGlhbCBwYWNrYWdlIHZlcnNpb24KICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQgICAgdGFyZ2V0IHBhY2thZ2UgdmVyc2lvbgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJHRhcmdldERpciB0YXJnZXQgZGlyCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGluaXRpYWwgcGFja2FnZSBpcyBub3QgaW5zdGFsbGVkCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHRhcmdldERpcikKICAgIHsKICAgICAgICAkdGFyZ2V0RGlyID0gJHRoaXMtPm5vcm1hbGl6ZVRhcmdldERpcigkdGFyZ2V0RGlyKTsKICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzLT5nZXREb3dubG9hZGVyRm9yUGFja2FnZSgkdGFyZ2V0KTsKICAgICAgICAkaW5pdGlhbERvd25sb2FkZXIgPSAkdGhpcy0+Z2V0RG93bmxvYWRlckZvclBhY2thZ2UoJGluaXRpYWwpOwoKICAgICAgICAvLyBubyBkb3dubG9hZGVycyBwcmVzZW50IG1lYW5zIHVwZGF0ZSBmcm9tIG1ldGFwYWNrYWdlIHRvIG1ldGFwYWNrYWdlLCBub3RoaW5nIHRvIGRvCiAgICAgICAgaWYgKCEkaW5pdGlhbERvd25sb2FkZXIgJiYgISRkb3dubG9hZGVyKSB7CiAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSBoYXZlIGEgZG93bmxvYWRlciBwcmVzZW50IGJlZm9yZSwgYnV0IG5vdCBhZnRlciwgdGhlIHBhY2thZ2UgYmVjYW1lIGEgbWV0YXBhY2thZ2UgYW5kIGl0cyBmaWxlcyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgIGlmICghJGRvd25sb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRpbml0aWFsRG93bmxvYWRlci0+cmVtb3ZlKCRpbml0aWFsLCAkdGFyZ2V0RGlyKTsKICAgICAgICB9CgogICAgICAgICRpbml0aWFsVHlwZSA9ICR0aGlzLT5nZXREb3dubG9hZGVyVHlwZSgkaW5pdGlhbERvd25sb2FkZXIpOwogICAgICAgICR0YXJnZXRUeXBlID0gJHRoaXMtPmdldERvd25sb2FkZXJUeXBlKCRkb3dubG9hZGVyKTsKICAgICAgICBpZiAoJGluaXRpYWxUeXBlID09PSAkdGFyZ2V0VHlwZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZGVyLT51cGRhdGUoJGluaXRpYWwsICR0YXJnZXQsICR0YXJnZXREaXIpOwogICAgICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+ICAgIFVwZGF0ZSBmYWlsZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKTwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+YXNrQ29uZmlybWF0aW9uKCcgICAgV291bGQgeW91IGxpa2UgdG8gdHJ5IHJlaW5zdGFsbGluZyB0aGUgcGFja2FnZSBpbnN0ZWFkIFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaWYgZG93bmxvYWRlciB0eXBlIGNoYW5nZWQsIG9yIHVwZGF0ZSBmYWlsZWQgYW5kIHVzZXIgYXNrcyBmb3IgcmVpbnN0YWxsLAogICAgICAgIC8vIHdlIHdpcGUgdGhlIGRpciBhbmQgZG8gYSBuZXcgaW5zdGFsbCBpbnN0ZWFkIG9mIHVwZGF0aW5nIGl0CiAgICAgICAgJHByb21pc2UgPSAkaW5pdGlhbERvd25sb2FkZXItPnJlbW92ZSgkaW5pdGlhbCwgJHRhcmdldERpcik7CiAgICAgICAgaWYgKCRwcm9taXNlKSB7CiAgICAgICAgICAgICRzZWxmID0gJHRoaXM7CgogICAgICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCRyZXMpIHVzZSAoJHNlbGYsICR0YXJnZXQsICR0YXJnZXREaXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkc2VsZi0+aW5zdGFsbCgkdGFyZ2V0LCAkdGFyZ2V0RGlyKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmluc3RhbGwoJHRhcmdldCwgJHRhcmdldERpcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHBhY2thZ2UgZnJvbSB0YXJnZXQgZGlyLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJHRhcmdldERpciB0YXJnZXQgZGlyCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyKQogICAgewogICAgICAgICR0YXJnZXREaXIgPSAkdGhpcy0+bm9ybWFsaXplVGFyZ2V0RGlyKCR0YXJnZXREaXIpOwogICAgICAgICRkb3dubG9hZGVyID0gJHRoaXMtPmdldERvd25sb2FkZXJGb3JQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJGRvd25sb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZGVyLT5yZW1vdmUoJHBhY2thZ2UsICR0YXJnZXREaXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENsZWFucyB1cCBhIGZhaWxlZCBvcGVyYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR0eXBlICAgICAgICBvbmUgb2YgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR0YXJnZXREaXIgICB0YXJnZXQgZGlyCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZXxudWxsICRwcmV2UGFja2FnZSBwcmV2aW91cyBwYWNrYWdlIGluc3RhbmNlIGluIGNhc2Ugb2YgdXBkYXRlcwogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRhcmdldERpciA9ICR0aGlzLT5ub3JtYWxpemVUYXJnZXREaXIoJHRhcmdldERpcik7CiAgICAgICAgJGRvd25sb2FkZXIgPSAkdGhpcy0+Z2V0RG93bmxvYWRlckZvclBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIGlmICgkZG93bmxvYWRlcikgewogICAgICAgICAgICByZXR1cm4gJGRvd25sb2FkZXItPmNsZWFudXAoJHR5cGUsICRwYWNrYWdlLCAkdGFyZ2V0RGlyLCAkcHJldlBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIERldGVybWluZXMgdGhlIGluc3RhbGwgcHJlZmVyZW5jZSBvZiBhIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlc29sdmVQYWNrYWdlSW5zdGFsbFByZWZlcmVuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFja2FnZVByZWZlcmVuY2VzIGFzICRwYXR0ZXJuID0+ICRwcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICRwYXR0ZXJuID0gJ3teJy5zdHJfcmVwbGFjZSgnXFwqJywgJy4qJywgcHJlZ19xdW90ZSgkcGF0dGVybikpLickfWknOwogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgkcGF0dGVybiwgJHBhY2thZ2UtPmdldE5hbWUoKSkpIHsKICAgICAgICAgICAgICAgIGlmICgnZGlzdCcgPT09ICRwcmVmZXJlbmNlIHx8ICghJHBhY2thZ2UtPmlzRGV2KCkgJiYgJ2F1dG8nID09PSAkcHJlZmVyZW5jZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2Rpc3QnOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAnc291cmNlJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlLT5pc0RldigpID8gJ3NvdXJjZScgOiAnZGlzdCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8J2Rpc3QnfCdzb3VyY2UnPiZub24tZW1wdHktYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRBdmFpbGFibGVTb3VyY2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAkc291cmNlVHlwZSA9ICRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCk7CiAgICAgICAgJGRpc3RUeXBlID0gJHBhY2thZ2UtPmdldERpc3RUeXBlKCk7CgogICAgICAgIC8vIGFkZCBzb3VyY2UgYmVmb3JlIGRpc3QgYnkgZGVmYXVsdAogICAgICAgICRzb3VyY2VzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJHNvdXJjZVR5cGUpIHsKICAgICAgICAgICAgJHNvdXJjZXNbXSA9ICdzb3VyY2UnOwogICAgICAgIH0KICAgICAgICBpZiAoJGRpc3RUeXBlKSB7CiAgICAgICAgICAgICRzb3VyY2VzW10gPSAnZGlzdCc7CiAgICAgICAgfQoKICAgICAgICBpZiAoZW1wdHkoJHNvdXJjZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlICcuJHBhY2thZ2UuJyBtdXN0IGhhdmUgYSBzb3VyY2Ugb3IgZGlzdCBzcGVjaWZpZWQnKTsKICAgICAgICB9CgogICAgICAgIGlmICgKICAgICAgICAgICAgJHByZXZQYWNrYWdlCiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSB1cGRhdGluZywgd2Ugd2FudCB0byBrZWVwIHRoZSBzYW1lIHNvdXJjZSBhcyB0aGUgcHJldmlvdXNseSBpbnN0YWxsZWQgcGFja2FnZSAoaWYgYXZhaWxhYmxlIGluIHRoZSBuZXcgb25lKQogICAgICAgICAgICAmJiBpbl9hcnJheSgkcHJldlBhY2thZ2UtPmdldEluc3RhbGxhdGlvblNvdXJjZSgpLCAkc291cmNlcywgdHJ1ZSkKICAgICAgICAgICAgLy8gdW5sZXNzIHRoZSBwcmV2aW91cyBwYWNrYWdlIHdhcyBzdGFibGUgZGlzdCAoYnkgZGVmYXVsdCkgYW5kIHRoZSBuZXcgcGFja2FnZSBpcyBkZXYsIHRoZW4gd2UgYWxsb3cgdGhlIG5ldyBkZWZhdWx0IHRvIHRha2Ugb3ZlcgogICAgICAgICAgICAmJiAhKCEkcHJldlBhY2thZ2UtPmlzRGV2KCkgJiYgJHByZXZQYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSA9PT0gJ2Rpc3QnICYmICRwYWNrYWdlLT5pc0RldigpKQogICAgICAgICkgewogICAgICAgICAgICAkcHJldlNvdXJjZSA9ICRwcmV2UGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCk7CiAgICAgICAgICAgIHVzb3J0KCRzb3VyY2VzLCBmdW5jdGlvbiAoJGEsICRiKSB1c2UgKCRwcmV2U291cmNlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGEgPT09ICRwcmV2U291cmNlID8gLTEgOiAxOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHJldHVybiAkc291cmNlczsKICAgICAgICB9CgogICAgICAgIC8vIHJldmVyc2Ugc291cmNlcyBpbiBjYXNlIGRpc3QgaXMgdGhlIHByZWZlcnJlZCBzb3VyY2UgZm9yIHRoaXMgcGFja2FnZQogICAgICAgIGlmICghJHRoaXMtPnByZWZlclNvdXJjZSAmJiAoJHRoaXMtPnByZWZlckRpc3QgfHwgJ2Rpc3QnID09PSAkdGhpcy0+cmVzb2x2ZVBhY2thZ2VJbnN0YWxsUHJlZmVyZW5jZSgkcGFja2FnZSkpKSB7CiAgICAgICAgICAgICRzb3VyY2VzID0gYXJyYXlfcmV2ZXJzZSgkc291cmNlcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNvdXJjZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEb3dubG9hZGVycyBleHBlY3QgYSAvcGF0aC90by9kaXIgd2l0aG91dCB0cmFpbGluZyBzbGFzaAogICAgICoKICAgICAqIElmIGFueSBJbnN0YWxsZXIgcHJvdmlkZXMgYSBwYXRoIHdpdGggYSB0cmFpbGluZyBzbGFzaCwgdGhpcyBjYW4gY2F1c2UgYnVncyBzbyBtYWtlIHN1cmUgd2UgcmVtb3ZlIHRoZW0KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG5vcm1hbGl6ZVRhcmdldERpcigkZGlyKQogICAgewogICAgICAgIGlmICgkZGlyID09PSAnXFwnIHx8ICRkaXIgPT09ICcvJykgewogICAgICAgICAgICByZXR1cm4gJGRpcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBydHJpbSgkZGlyLCAnXFwvJyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CgovKioKICogQ2hhbmdlUmVwb3J0IGludGVyZmFjZS4KICoKICogQGF1dGhvciBTYXNjaGEgRWdlcmVyIDxzYXNjaGEuZWdlcmVyQGRrZC5kZT4KICovCmludGVyZmFjZSBDaGFuZ2VSZXBvcnRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBDaGVja3MgZm9yIGNoYW5nZXMgdG8gdGhlIGxvY2FsIGNvcHkKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRwYXRoICAgIHBhY2thZ2UgZGlyZWN0b3J5CiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsICAgICAgY2hhbmdlcyBvciBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7CgpjbGFzcyBNYXhGaWxlU2l6ZUV4Y2VlZGVkRXhjZXB0aW9uIGV4dGVuZHMgVHJhbnNwb3J0RXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBEb3dubG9hZGVyIGZvciBwaGFyIGZpbGVzCiAqCiAqIEBhdXRob3IgS2lyaWxsIGNoRWJiYSBDaGVidW5pbiA8aWFtQGNoZWJiYS5vcmc+CiAqLwpjbGFzcyBQaGFyRG93bmxvYWRlciBleHRlbmRzIEFyY2hpdmVEb3dubG9hZGVyCnsKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZpbGUsICRwYXRoKQogICAgewogICAgICAgIC8vIENhbiB0aHJvdyBhbiBVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24KICAgICAgICAkYXJjaGl2ZSA9IG5ldyBcUGhhcigkZmlsZSk7CiAgICAgICAgJGFyY2hpdmUtPmV4dHJhY3RUbygkcGF0aCwgbnVsbCwgdHJ1ZSk7CiAgICAgICAgLyogVE9ETzogaGFuZGxlIG9wZW5zc2wgc2lnbmVkIHBoYXJzCiAgICAgICAgICogaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvMzMjaXNzdWVjb21tZW50LTIyNTA3NjgKICAgICAgICAgKiBodHRwczovL2dpdGh1Yi5jb20va290by9waGFyLXV0aWwKICAgICAgICAgKiBodHRwOi8vYmxvZy5rb3Rvd2ljei5uZXQvMjAxMC8wOC9oYXJkZW5pbmctcGhwLWhvdy10by1zZWN1cmVseS1pbmNsdWRlLmh0bWwKICAgICAgICAgKi8KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBEb3dubG9hZGVyIGZvciB0YXIgZmlsZXM6IHRhciwgdGFyLmd6IG9yIHRhci5iejIKICoKICogQGF1dGhvciBLaXJpbGwgY2hFYmJhIENoZWJ1bmluIDxpYW1AY2hlYmJhLm9yZz4KICovCmNsYXNzIFRhckRvd25sb2FkZXIgZXh0ZW5kcyBBcmNoaXZlRG93bmxvYWRlcgp7CiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleHRyYWN0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRmaWxlLCAkcGF0aCkKICAgIHsKICAgICAgICAvLyBDYW4gdGhyb3cgYW4gVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgICAgJGFyY2hpdmUgPSBuZXcgXFBoYXJEYXRhKCRmaWxlKTsKICAgICAgICAkYXJjaGl2ZS0+ZXh0cmFjdFRvKCRwYXRoLCBudWxsLCB0cnVlKTsKCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxHaXQgYXMgR2l0VXRpbDsKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcQ2FjaGU7CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgR2l0RG93bmxvYWRlciBleHRlbmRzIFZjc0Rvd25sb2FkZXIgaW1wbGVtZW50cyBEdmNzRG93bmxvYWRlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEB2YXIgYm9vbFtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBib29sPgogICAgICovCiAgICBwcml2YXRlICRoYXNTdGFzaGVkQ2hhbmdlcyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYm9vbFtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBib29sPgogICAgICovCiAgICBwcml2YXRlICRoYXNEaXNjYXJkZWRDaGFuZ2VzID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogQHZhciBHaXRVdGlsCiAgICAgKi8KICAgIHByaXZhdGUgJGdpdFV0aWw7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxpbnQsIGFycmF5PHN0cmluZywgYm9vbD4+CiAgICAgKi8KICAgIHByaXZhdGUgJGNhY2hlZFBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCwgRmlsZXN5c3RlbSAkZnMgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGlvLCAkY29uZmlnLCAkcHJvY2VzcywgJGZzKTsKICAgICAgICAkdGhpcy0+Z2l0VXRpbCA9IG5ldyBHaXRVdGlsKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MsICR0aGlzLT5maWxlc3lzdGVtKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0Rvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgJGNhY2hlUGF0aCA9ICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpLicvJy5QcmVnOjpyZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCAkdXJsKS4nLyc7CiAgICAgICAgJGdpdFZlcnNpb24gPSBHaXRVdGlsOjpnZXRWZXJzaW9uKCR0aGlzLT5wcm9jZXNzKTsKCiAgICAgICAgLy8gLS1kaXNzb2NpYXRlIG9wdGlvbiBpcyBvbmx5IGF2YWlsYWJsZSBzaW5jZSBnaXQgMi4zLjAtcmMwCiAgICAgICAgaWYgKCRnaXRWZXJzaW9uICYmIHZlcnNpb25fY29tcGFyZSgkZ2l0VmVyc2lvbiwgJzIuMy4wLXJjMCcsICc+PScpICYmIENhY2hlOjppc1VzYWJsZSgkY2FjaGVQYXRoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSBTeW5jaW5nIDxpbmZvPiIgLiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4gIjwvaW5mbz4gKDxjb21tZW50PiIgLiAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAuICI8L2NvbW1lbnQ+KSBpbnRvIGNhY2hlIik7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCcgICAgQ2xvbmluZyB0byBjYWNoZSBhdCAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRjYWNoZVBhdGgpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgJHJlZiA9ICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5naXRVdGlsLT5mZXRjaFJlZk9yU3luY01pcnJvcigkdXJsLCAkY2FjaGVQYXRoLCAkcmVmKSAmJiBpc19kaXIoJGNhY2hlUGF0aCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZWRQYWNrYWdlc1skcGFja2FnZS0+Z2V0SWQoKV1bJHJlZl0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKG51bGwgPT09ICRnaXRWZXJzaW9uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignZ2l0IHdhcyBub3QgZm91bmQgaW4geW91ciBQQVRILCBza2lwcGluZyBzb3VyY2UgZG93bmxvYWQnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9JbnN0YWxsKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgIEdpdFV0aWw6OmNsZWFuRW52KCk7CiAgICAgICAgJHBhdGggPSAkdGhpcy0+bm9ybWFsaXplUGF0aCgkcGF0aCk7CiAgICAgICAgJGNhY2hlUGF0aCA9ICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpLicvJy5QcmVnOjpyZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCAkdXJsKS4nLyc7CiAgICAgICAgJHJlZiA9ICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKICAgICAgICAkZmxhZyA9IFBsYXRmb3JtOjppc1dpbmRvd3MoKSA/ICcvRCAnIDogJyc7CgogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmNhY2hlZFBhY2thZ2VzWyRwYWNrYWdlLT5nZXRJZCgpXVskcmVmXSkpIHsKICAgICAgICAgICAgJG1zZyA9ICJDbG9uaW5nICIuJHRoaXMtPmdldFNob3J0SGFzaCgkcmVmKS4nIGZyb20gY2FjaGUnOwoKICAgICAgICAgICAgJGNsb25lRmxhZ3MgPSAnLS1kaXNzb2NpYXRlIC0tcmVmZXJlbmNlICVjYWNoZVBhdGglICc7CiAgICAgICAgICAgICR0cmFuc3BvcnRPcHRpb25zID0gJHBhY2thZ2UtPmdldFRyYW5zcG9ydE9wdGlvbnMoKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0cmFuc3BvcnRPcHRpb25zWydnaXQnXVsnc2luZ2xlX3VzZV9jbG9uZSddKSAmJiAkdHJhbnNwb3J0T3B0aW9uc1snZ2l0J11bJ3NpbmdsZV91c2VfY2xvbmUnXSkgewogICAgICAgICAgICAgICAgJGNsb25lRmxhZ3MgPSAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbW1hbmQgPQogICAgICAgICAgICAgICAgJ2dpdCBjbG9uZSAtLW5vLWNoZWNrb3V0ICVjYWNoZVBhdGglICVwYXRoJSAnIC4gJGNsb25lRmxhZ3MKICAgICAgICAgICAgICAgIC4gJyYmIGNkICcuJGZsYWcuJyVwYXRoJSAnCiAgICAgICAgICAgICAgICAuICcmJiBnaXQgcmVtb3RlIHNldC11cmwgb3JpZ2luIC0tICVzYW5pdGl6ZWRVcmwlICYmIGdpdCByZW1vdGUgYWRkIGNvbXBvc2VyIC0tICVzYW5pdGl6ZWRVcmwlJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbXNnID0gIkNsb25pbmcgIi4kdGhpcy0+Z2V0U2hvcnRIYXNoKCRyZWYpOwogICAgICAgICAgICAkY29tbWFuZCA9ICdnaXQgY2xvbmUgLS1uby1jaGVja291dCAtLSAldXJsJSAlcGF0aCUgJiYgY2QgJy4kZmxhZy4nJXBhdGglICYmIGdpdCByZW1vdGUgYWRkIGNvbXBvc2VyIC0tICV1cmwlICYmIGdpdCBmZXRjaCBjb21wb3NlciAmJiBnaXQgcmVtb3RlIHNldC11cmwgb3JpZ2luIC0tICVzYW5pdGl6ZWRVcmwlICYmIGdpdCByZW1vdGUgc2V0LXVybCBjb21wb3NlciAtLSAlc2FuaXRpemVkVXJsJSc7CiAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9ESVNBQkxFX05FVFdPUksnKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgcmVxdWlyZWQgZ2l0IHJlZmVyZW5jZSBmb3IgJy4kcGFja2FnZS0+Z2V0TmFtZSgpLicgaXMgbm90IGluIGNhY2hlIGFuZCBuZXR3b3JrIGlzIGRpc2FibGVkLCBhYm9ydGluZycpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJG1zZyk7CgogICAgICAgICRjb21tYW5kQ2FsbGFibGUgPSBmdW5jdGlvbiAoJHVybCkgdXNlICgkcGF0aCwgJGNvbW1hbmQsICRjYWNoZVBhdGgpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKAogICAgICAgICAgICAgICAgYXJyYXkoJyV1cmwlJywgJyVwYXRoJScsICclY2FjaGVQYXRoJScsICclc2FuaXRpemVkVXJsJScpLAogICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCksCiAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhdGgpLAogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRjYWNoZVBhdGgpLAogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKFByZWc6OnJlcGxhY2UoJ3s6Ly8oW15AXSs/KTooLis/KUB9JywgJzovLycsICR1cmwpKSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAkY29tbWFuZAogICAgICAgICAgICApOwogICAgICAgIH07CgogICAgICAgICR0aGlzLT5naXRVdGlsLT5ydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRwYXRoLCB0cnVlKTsKICAgICAgICAkc291cmNlVXJsID0gJHBhY2thZ2UtPmdldFNvdXJjZVVybCgpOwogICAgICAgIGlmICgkdXJsICE9PSAkc291cmNlVXJsICYmICRzb3VyY2VVcmwgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnVwZGF0ZU9yaWdpblVybCgkcGF0aCwgJHNvdXJjZVVybCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnNldFB1c2hVcmwoJHBhdGgsICR1cmwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRuZXdSZWYgPSAkdGhpcy0+dXBkYXRlVG9Db21taXQoJHBhdGgsICRyZWYsICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksICRwYWNrYWdlLT5nZXRSZWxlYXNlRGF0ZSgpKSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSA9PT0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0RGlzdFJlZmVyZW5jZSgkbmV3UmVmKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZS0+c2V0U291cmNlUmVmZXJlbmNlKCRuZXdSZWYpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1VwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoLCAkdXJsKQogICAgewogICAgICAgIEdpdFV0aWw6OmNsZWFuRW52KCk7CiAgICAgICAgJHBhdGggPSAkdGhpcy0+bm9ybWFsaXplUGF0aCgkcGF0aCk7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSAuZ2l0IGRpcmVjdG9yeSBpcyBtaXNzaW5nIGZyb20gJy4kcGF0aC4nLCBzZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvY29tbWl0LWRlcHMgZm9yIG1vcmUgaW5mb3JtYXRpb24nKTsKICAgICAgICB9CgogICAgICAgICRjYWNoZVBhdGggPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKS4nLycuUHJlZzo6cmVwbGFjZSgne1teYS16MC05Ll19aScsICctJywgJHVybCkuJy8nOwogICAgICAgICRyZWYgPSAkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+Y2FjaGVkUGFja2FnZXNbJHRhcmdldC0+Z2V0SWQoKV1bJHJlZl0pKSB7CiAgICAgICAgICAgICRtc2cgPSAiQ2hlY2tpbmcgb3V0ICIuJHRoaXMtPmdldFNob3J0SGFzaCgkcmVmKS4nIGZyb20gY2FjaGUnOwogICAgICAgICAgICAkY29tbWFuZCA9ICcoZ2l0IHJldi1wYXJzZSAtLXF1aWV0IC0tdmVyaWZ5ICVyZWYlIHx8IChnaXQgcmVtb3RlIHNldC11cmwgY29tcG9zZXIgLS0gJWNhY2hlUGF0aCUgJiYgZ2l0IGZldGNoIGNvbXBvc2VyICYmIGdpdCBmZXRjaCAtLXRhZ3MgY29tcG9zZXIpKSAmJiBnaXQgcmVtb3RlIHNldC11cmwgY29tcG9zZXIgLS0gJXNhbml0aXplZFVybCUnOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRtc2cgPSAiQ2hlY2tpbmcgb3V0ICIuJHRoaXMtPmdldFNob3J0SGFzaCgkcmVmKTsKICAgICAgICAgICAgJGNvbW1hbmQgPSAnKGdpdCByZW1vdGUgc2V0LXVybCBjb21wb3NlciAtLSAldXJsJSAmJiBnaXQgcmV2LXBhcnNlIC0tcXVpZXQgLS12ZXJpZnkgJXJlZiUgfHwgKGdpdCBmZXRjaCBjb21wb3NlciAmJiBnaXQgZmV0Y2ggLS10YWdzIGNvbXBvc2VyKSkgJiYgZ2l0IHJlbW90ZSBzZXQtdXJsIGNvbXBvc2VyIC0tICVzYW5pdGl6ZWRVcmwlJzsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX0RJU0FCTEVfTkVUV09SSycpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSByZXF1aXJlZCBnaXQgcmVmZXJlbmNlIGZvciAnLiR0YXJnZXQtPmdldE5hbWUoKS4nIGlzIG5vdCBpbiBjYWNoZSBhbmQgbmV0d29yayBpcyBkaXNhYmxlZCwgYWJvcnRpbmcnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtc2cpOwoKICAgICAgICAkY29tbWFuZENhbGxhYmxlID0gZnVuY3Rpb24gKCR1cmwpIHVzZSAoJHJlZiwgJGNvbW1hbmQsICRjYWNoZVBhdGgpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKAogICAgICAgICAgICAgICAgYXJyYXkoJyV1cmwlJywgJyVyZWYlJywgJyVjYWNoZVBhdGglJywgJyVzYW5pdGl6ZWRVcmwlJyksCiAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVmLidee2NvbW1pdH0nKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkY2FjaGVQYXRoKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShQcmVnOjpyZXBsYWNlKCd7Oi8vKFteQF0rPyk6KC4rPylAfScsICc6Ly8nLCAkdXJsKSksCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgJGNvbW1hbmQKICAgICAgICAgICAgKTsKICAgICAgICB9OwoKICAgICAgICAkdGhpcy0+Z2l0VXRpbC0+cnVuQ29tbWFuZCgkY29tbWFuZENhbGxhYmxlLCAkdXJsLCAkcGF0aCk7CiAgICAgICAgaWYgKCRuZXdSZWYgPSAkdGhpcy0+dXBkYXRlVG9Db21taXQoJHBhdGgsICRyZWYsICR0YXJnZXQtPmdldFByZXR0eVZlcnNpb24oKSwgJHRhcmdldC0+Z2V0UmVsZWFzZURhdGUoKSkpIHsKICAgICAgICAgICAgaWYgKCR0YXJnZXQtPmdldERpc3RSZWZlcmVuY2UoKSA9PT0gJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgICAgICR0YXJnZXQtPnNldERpc3RSZWZlcmVuY2UoJG5ld1JlZik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRhcmdldC0+c2V0U291cmNlUmVmZXJlbmNlKCRuZXdSZWYpOwogICAgICAgIH0KCiAgICAgICAgJHVwZGF0ZU9yaWdpblVybCA9IGZhbHNlOwogICAgICAgIGlmICgKICAgICAgICAgICAgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZW1vdGUgLXYnLCAkb3V0cHV0LCAkcGF0aCkKICAgICAgICAgICAgJiYgUHJlZzo6aXNNYXRjaCgne15vcmlnaW5ccysoP1A8dXJsPlxTKyl9bScsICRvdXRwdXQsICRvcmlnaW5NYXRjaCkKICAgICAgICAgICAgJiYgUHJlZzo6aXNNYXRjaCgne15jb21wb3NlclxzKyg/UDx1cmw+XFMrKX1tJywgJG91dHB1dCwgJGNvbXBvc2VyTWF0Y2gpCiAgICAgICAgKSB7CiAgICAgICAgICAgIGlmICgkb3JpZ2luTWF0Y2hbJ3VybCddID09PSAkY29tcG9zZXJNYXRjaFsndXJsJ10gJiYgJGNvbXBvc2VyTWF0Y2hbJ3VybCddICE9PSAkdGFyZ2V0LT5nZXRTb3VyY2VVcmwoKSkgewogICAgICAgICAgICAgICAgJHVwZGF0ZU9yaWdpblVybCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCR1cGRhdGVPcmlnaW5VcmwgJiYgJHRhcmdldC0+Z2V0U291cmNlVXJsKCkgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnVwZGF0ZU9yaWdpblVybCgkcGF0aCwgJHRhcmdldC0+Z2V0U291cmNlVXJsKCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKICAgICAgICBpZiAoISR0aGlzLT5oYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmQgPSAnZ2l0IHN0YXR1cyAtLXBvcmNlbGFpbiAtLXVudHJhY2tlZC1maWxlcz1ubyc7CiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJpbSgkb3V0cHV0KSA/OiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBudWxsfHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VW5wdXNoZWRDaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIEdpdFV0aWw6OmNsZWFuRW52KCk7CiAgICAgICAgJHBhdGggPSAkdGhpcy0+bm9ybWFsaXplUGF0aCgkcGF0aCk7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kID0gJ2dpdCBzaG93LXJlZiAtLWhlYWQgLWQnOwogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgJHJlZnMgPSB0cmltKCRvdXRwdXQpOwogICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgne14oW2EtZjAtOV0rKSBIRUFEJH1taScsICRyZWZzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIC8vIGNvdWxkIG5vdCBtYXRjaCB0aGUgSEVBRCBmb3Igc29tZSByZWFzb24KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkaGVhZFJlZiA9ICRtYXRjaFsxXTsKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2hBbGwoJ3teJy4kaGVhZFJlZi4nIHJlZnMvaGVhZHMvKC4rKSR9bWknLCAkcmVmcywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIG5vdCBvbiBhIGJyYW5jaCwgd2UgYXJlIGVpdGhlciBvbiBhIG5vdC1tb2RpZmllZCB0YWcgb3Igc29tZSBzb3J0IG9mIGRldGFjaGVkIGhlYWQsIHNvIHNraXAgdGhpcwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRjYW5kaWRhdGVCcmFuY2hlcyA9ICRtYXRjaGVzWzFdOwogICAgICAgIC8vIHVzZSB0aGUgZmlyc3QgbWF0Y2ggYXMgYnJhbmNoIG5hbWUgZm9yIG5vdwogICAgICAgICRicmFuY2ggPSAkY2FuZGlkYXRlQnJhbmNoZXNbMF07CiAgICAgICAgJHVucHVzaGVkQ2hhbmdlcyA9IG51bGw7CiAgICAgICAgJGJyYW5jaE5vdEZvdW5kRXJyb3IgPSBmYWxzZTsKCiAgICAgICAgLy8gZG8gdHdvIHBhc3NlcywgYXMgaWYgd2UgZmluZCBhbnl0aGluZyB3ZSB3YW50IHRvIGZldGNoIGFuZCB0aGVuIHJlLXRyeQogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8PSAxOyAkaSsrKSB7CiAgICAgICAgICAgICRyZW1vdGVCcmFuY2hlcyA9IGFycmF5KCk7CgogICAgICAgICAgICAvLyB0cnkgdG8gZmluZCBtYXRjaGluZyBicmFuY2ggbmFtZXMgaW4gcmVtb3RlIHJlcG9zCiAgICAgICAgICAgIGZvcmVhY2ggKCRjYW5kaWRhdGVCcmFuY2hlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaEFsbCgne15bYS1mMC05XSsgcmVmcy9yZW1vdGVzLygoPzpbXi9dKykvJy5wcmVnX3F1b3RlKCRjYW5kaWRhdGUpLicpJH1taScsICRyZWZzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlc1sxXSBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaCA9ICRjYW5kaWRhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZW1vdGVCcmFuY2hlc1tdID0gJG1hdGNoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgaXQgZG9lc24ndCBleGlzdCwgdGhlbiB3ZSBhc3N1bWUgaXQgaXMgYW4gdW5wdXNoZWQgYnJhbmNoCiAgICAgICAgICAgIC8vIHRoaXMgaXMgYmFkIGFzIHdlIGhhdmUgbm8gcmVmZXJlbmNlIHBvaW50IHRvIGRvIGEgZGlmZiBzbyB3ZSBqdXN0IGJhaWwgbGlzdGluZwogICAgICAgICAgICAvLyB0aGUgYnJhbmNoIGFzIGJlaW5nIHVucHVzaGVkCiAgICAgICAgICAgIGlmICghJHJlbW90ZUJyYW5jaGVzKSB7CiAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gJ0JyYW5jaCAnIC4gJGJyYW5jaCAuICcgY291bGQgbm90IGJlIGZvdW5kIG9uIGFueSByZW1vdGUgYW5kIGFwcGVhcnMgdG8gYmUgdW5wdXNoZWQnOwogICAgICAgICAgICAgICAgJGJyYW5jaE5vdEZvdW5kRXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gaWYgZmlyc3QgaXRlcmF0aW9uIGZvdW5kIG5vIHJlbW90ZSBicmFuY2ggYnV0IGl0IGhhcyBub3cgZm91bmQgc29tZSwgcmVzZXQgJHVucHVzaGVkQ2hhbmdlcwogICAgICAgICAgICAgICAgLy8gc28gd2UgZ2V0IHRoZSByZWFsIGRpZmYgb3V0cHV0IG5vIG1hdHRlciBpdHMgbGVuZ3RoCiAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaE5vdEZvdW5kRXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZW1vdGVCcmFuY2hlcyBhcyAkcmVtb3RlQnJhbmNoKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdnaXQgZGlmZiAtLW5hbWUtc3RhdHVzICVzLi4uJXMgLS0nLCAkcmVtb3RlQnJhbmNoLCAkYnJhbmNoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRvdXRwdXQgPSB0cmltKCRvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgdGhlIHNob3J0ZXN0IGRpZmYgZnJvbSBhbGwgcmVtb3RlIGJyYW5jaGVzIHdlIGNvbXBhcmUgYWdhaW5zdAogICAgICAgICAgICAgICAgICAgIGlmICgkdW5wdXNoZWRDaGFuZ2VzID09PSBudWxsIHx8IHN0cmxlbigkb3V0cHV0KSA8IHN0cmxlbigkdW5wdXNoZWRDaGFuZ2VzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gJG91dHB1dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZpcnN0IHBhc3MgYW5kIHdlIGZvdW5kIHVucHVzaGVkIGNoYW5nZXMsIGZldGNoIGZyb20gYWxsIHJlbW90ZXMgdG8gbWFrZSBzdXJlIHdlIGhhdmUgdXAgdG8gZGF0ZQogICAgICAgICAgICAvLyByZW1vdGVzIGFuZCB0aGVuIHRyeSBhZ2FpbiBhcyBvdXRkYXRlZCByZW1vdGVzIGNhbiBzb21ldGltZXMgY2F1c2UgZmFsc2UtcG9zaXRpdmVzCiAgICAgICAgICAgIGlmICgkdW5wdXNoZWRDaGFuZ2VzICYmICRpID09PSAwKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGZldGNoIC0tYWxsJywgJG91dHB1dCwgJHBhdGgpOwoKICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBsaXN0IG9mIHJlZnMgYWZ0ZXIgZmV0Y2hpbmcKICAgICAgICAgICAgICAgICRjb21tYW5kID0gJ2dpdCBzaG93LXJlZiAtLWhlYWQgLWQnOwogICAgICAgICAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZWZzID0gdHJpbSgkb3V0cHV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gYWJvcnQgYWZ0ZXIgZmlyc3QgcGFzcyBpZiB3ZSBkaWRuJ3QgZmluZCBhbnl0aGluZwogICAgICAgICAgICBpZiAoISR1bnB1c2hlZENoYW5nZXMpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHVucHVzaGVkQ2hhbmdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjbGVhbkNoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cGRhdGUpCiAgICB7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKCiAgICAgICAgJHVucHVzaGVkID0gJHRoaXMtPmdldFVucHVzaGVkQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgpOwogICAgICAgIGlmICgkdW5wdXNoZWQgJiYgKCR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpIHx8ICR0aGlzLT5jb25maWctPmdldCgnZGlzY2FyZC1jaGFuZ2VzJykgIT09IHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignU291cmNlIGRpcmVjdG9yeSAnIC4gJHBhdGggLiAnIGhhcyB1bnB1c2hlZCBjaGFuZ2VzIG9uIHRoZSBjdXJyZW50IGJyYW5jaDogJy4iXG4iLiR1bnB1c2hlZCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRjaGFuZ2VzID0gJHRoaXMtPmdldExvY2FsQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICRkaXNjYXJkQ2hhbmdlcyA9ICR0aGlzLT5jb25maWctPmdldCgnZGlzY2FyZC1jaGFuZ2VzJyk7CiAgICAgICAgICAgIGlmICh0cnVlID09PSAkZGlzY2FyZENoYW5nZXMpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZGlzY2FyZENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgnc3Rhc2gnID09PSAkZGlzY2FyZENoYW5nZXMpIHsKICAgICAgICAgICAgICAgIGlmICghJHVwZGF0ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmNsZWFuQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgsICR1cGRhdGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+c3Rhc2hDaGFuZ2VzKCRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Y2xlYW5DaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCwgJHVwZGF0ZSk7CiAgICAgICAgfQoKICAgICAgICAkY2hhbmdlcyA9IGFycmF5X21hcChmdW5jdGlvbiAoJGVsZW0pIHsKICAgICAgICAgICAgcmV0dXJuICcgICAgJy4kZWxlbTsKICAgICAgICB9LCBQcmVnOjpzcGxpdCgne1xzKlxyP1xuXHMqfScsICRjaGFuZ2VzKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgPGVycm9yPicuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGhhcyBtb2RpZmllZCBmaWxlczo8L2Vycm9yPicpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheV9zbGljZSgkY2hhbmdlcywgMCwgMTApKTsKICAgICAgICBpZiAoY291bnQoJGNoYW5nZXMpID4gMTApIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgPGluZm8+JyAuIChjb3VudCgkY2hhbmdlcykgLSAxMCkgLiAnIG1vcmUgZmlsZXMgbW9kaWZpZWQsIGNob29zZSAidiIgdG8gdmlldyB0aGUgZnVsbCBsaXN0PC9pbmZvPicpOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+aW8tPmFzaygnICAgIDxpbmZvPkRpc2NhcmQgY2hhbmdlcyBbeSxuLHYsZCwnLigkdXBkYXRlID8gJ3MsJyA6ICcnKS4nP10/PC9pbmZvPiAnLCAnPycpKSB7CiAgICAgICAgICAgICAgICBjYXNlICd5JzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzY2FyZENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CgogICAgICAgICAgICAgICAgY2FzZSAncyc6CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXBkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gaGVscDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFzaENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CgogICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdVcGRhdGUgYWJvcnRlZCcpOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkY2hhbmdlcyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnZCc6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZpZXdEaWZmKCRwYXRoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICc/JzoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaGVscCA6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnICAgIHkgLSBkaXNjYXJkIGNoYW5nZXMgYW5kIGFwcGx5IHRoZSAnLigkdXBkYXRlID8gJ3VwZGF0ZScgOiAndW5pbnN0YWxsJyksCiAgICAgICAgICAgICAgICAgICAgICAgICcgICAgbiAtIGFib3J0IHRoZSAnLigkdXBkYXRlID8gJ3VwZGF0ZScgOiAndW5pbnN0YWxsJykuJyBhbmQgbGV0IHlvdSBtYW51YWxseSBjbGVhbiB0aGluZ3MgdXAnLAogICAgICAgICAgICAgICAgICAgICAgICAnICAgIHYgLSB2aWV3IG1vZGlmaWVkIGZpbGVzJywKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICBkIC0gdmlldyBsb2NhbCBtb2RpZmljYXRpb25zIChkaWZmKScsCiAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR1cGRhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgcyAtIHN0YXNoIGNoYW5nZXMgYW5kIHRyeSB0byByZWFwcGx5IHRoZW0gYWZ0ZXIgdGhlIHVwZGF0ZScpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICA/IC0gcHJpbnQgaGVscCcpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlYXBwbHlDaGFuZ2VzKCRwYXRoKQogICAgewogICAgICAgICRwYXRoID0gJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmhhc1N0YXNoZWRDaGFuZ2VzWyRwYXRoXSkpIHsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmhhc1N0YXNoZWRDaGFuZ2VzWyRwYXRoXSk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIDxpbmZvPlJlLWFwcGx5aW5nIHN0YXNoZWQgY2hhbmdlczwvaW5mbz4nKTsKICAgICAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgc3Rhc2ggcG9wJywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIkZhaWxlZCB0byBhcHBseSBzdGFzaGVkIGNoYW5nZXM6XG5cbiIuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB1bnNldCgkdGhpcy0+aGFzRGlzY2FyZGVkQ2hhbmdlc1skcGF0aF0pOwogICAgfQoKICAgIC8qKgogICAgICogVXBkYXRlcyB0aGUgZ2l2ZW4gcGF0aCB0byB0aGUgZ2l2ZW4gY29tbWl0IHJlZgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGgKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHJlZmVyZW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkYnJhbmNoCiAgICAgKiBAcGFyYW0gIFxEYXRlVGltZSAgICAgICAgICRkYXRlCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIG51bGx8c3RyaW5nICAgICAgIGlmIGEgc3RyaW5nIGlzIHJldHVybmVkLCBpdCBpcyB0aGUgY29tbWl0IHJlZmVyZW5jZSB0aGF0IHdhcyBjaGVja2VkIG91dCBpZiB0aGUgb3JpZ2luYWwgY291bGQgbm90IGJlIGZvdW5kCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVUb0NvbW1pdCgkcGF0aCwgJHJlZmVyZW5jZSwgJGJyYW5jaCwgJGRhdGUpCiAgICB7CiAgICAgICAgJGZvcmNlID0gIWVtcHR5KCR0aGlzLT5oYXNEaXNjYXJkZWRDaGFuZ2VzWyRwYXRoXSkgfHwgIWVtcHR5KCR0aGlzLT5oYXNTdGFzaGVkQ2hhbmdlc1skcGF0aF0pID8gJy1mICcgOiAnJzsKCiAgICAgICAgLy8gVGhpcyB1c2VzIHRoZSAiLS0iIHNlcXVlbmNlIHRvIHNlcGFyYXRlIGJyYW5jaCBmcm9tIGZpbGUgcGFyYW1ldGVycy4KICAgICAgICAvLwogICAgICAgIC8vIE90aGVyd2lzZSBnaXQgdHJpZXMgdGhlIGJyYW5jaCBuYW1lIGFzIHdlbGwgYXMgZmlsZSBuYW1lLgogICAgICAgIC8vIElmIHRoZSBub24tZXhpc3RlbnQgYnJhbmNoIGlzIGFjdHVhbGx5IHRoZSBuYW1lIG9mIGEgZmlsZSwgdGhlIGZpbGUKICAgICAgICAvLyBpcyBjaGVja2VkIG91dC4KICAgICAgICAkdGVtcGxhdGUgPSAnZ2l0IGNoZWNrb3V0ICcuJGZvcmNlLiclcyAtLSAmJiBnaXQgcmVzZXQgLS1oYXJkICUxJHMgLS0nOwogICAgICAgICRicmFuY2ggPSBQcmVnOjpyZXBsYWNlKCd7KD86XmRldi18KD86XC54KT8tZGV2JCl9aScsICcnLCAkYnJhbmNoKTsKCiAgICAgICAgJGJyYW5jaGVzID0gbnVsbDsKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBicmFuY2ggLXInLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gJG91dHB1dDsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgbm9uLWNvbW1pdGlzaCBhcmUgYnJhbmNoZXMgb3IgdGFncywgYW5kIGZldGNoIGJyYW5jaGVzIHdpdGggdGhlIHJlbW90ZSBuYW1lCiAgICAgICAgJGdpdFJlZiA9ICRyZWZlcmVuY2U7CiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7XlthLWYwLTldezQwfSR9JywgJHJlZmVyZW5jZSkKICAgICAgICAgICAgJiYgJGJyYW5jaGVzCiAgICAgICAgICAgICYmIFByZWc6OmlzTWF0Y2goJ3teXHMrY29tcG9zZXIvJy5wcmVnX3F1b3RlKCRyZWZlcmVuY2UpLickfW0nLCAkYnJhbmNoZXMpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZ2l0IGNoZWNrb3V0ICcuJGZvcmNlLictQiAlcyAlcyAtLSAmJiBnaXQgcmVzZXQgLS1oYXJkICUyJHMgLS0nLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkYnJhbmNoKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJ2NvbXBvc2VyLycuJHJlZmVyZW5jZSkpOwogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHRyeSB0byBjaGVja291dCBicmFuY2ggYnkgbmFtZSBhbmQgdGhlbiByZXNldCBpdCBzbyBpdCdzIG9uIHRoZSBwcm9wZXIgYnJhbmNoIG5hbWUKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15bYS1mMC05XXs0MH0kfScsICRyZWZlcmVuY2UpKSB7CiAgICAgICAgICAgIC8vIGFkZCAndicgaW4gZnJvbnQgb2YgdGhlIGJyYW5jaCBpZiBpdCB3YXMgc3RyaXBwZWQgd2hlbiBnZW5lcmF0aW5nIHRoZSBwcmV0dHkgbmFtZQogICAgICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJ3teXHMrY29tcG9zZXIvJy5wcmVnX3F1b3RlKCRicmFuY2gpLickfW0nLCAkYnJhbmNoZXMpICYmIFByZWc6OmlzTWF0Y2goJ3teXHMrY29tcG9zZXIvdicucHJlZ19xdW90ZSgkYnJhbmNoKS4nJH1tJywgJGJyYW5jaGVzKSkgewogICAgICAgICAgICAgICAgJGJyYW5jaCA9ICd2JyAuICRicmFuY2g7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZ2l0IGNoZWNrb3V0ICVzIC0tJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGJyYW5jaCkpOwogICAgICAgICAgICAkZmFsbGJhY2tDb21tYW5kID0gc3ByaW50ZignZ2l0IGNoZWNrb3V0ICcuJGZvcmNlLictQiAlcyAlcyAtLScsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRicmFuY2gpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgnY29tcG9zZXIvJy4kYnJhbmNoKSk7CiAgICAgICAgICAgICRyZXNldENvbW1hbmQgPSBzcHJpbnRmKCdnaXQgcmVzZXQgLS1oYXJkICVzIC0tJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHJlZmVyZW5jZSkpOwoKICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCIoJGNvbW1hbmQgfHwgJGZhbGxiYWNrQ29tbWFuZCkgJiYgJHJlc2V0Q29tbWFuZCIsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21tYW5kID0gc3ByaW50ZigkdGVtcGxhdGUsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRnaXRSZWYpKTsKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIHJlZmVyZW5jZSB3YXMgbm90IGZvdW5kIChwcmludHMgImZhdGFsOiByZWZlcmVuY2UgaXMgbm90IGEgdHJlZTogJHJlZiIpCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICRyZWZlcmVuY2UpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIDx3YXJuaW5nPicuJHJlZmVyZW5jZS4nIGlzIGdvbmUgKGhpc3Rvcnkgd2FzIHJld3JpdHRlbj8pPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKFVybDo6c2FuaXRpemUoJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZU9yaWdpblVybCgkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZShzcHJpbnRmKCdnaXQgcmVtb3RlIHNldC11cmwgb3JpZ2luIC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCkpLCAkb3V0cHV0LCAkcGF0aCk7CiAgICAgICAgJHRoaXMtPnNldFB1c2hVcmwoJHBhdGgsICR1cmwpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXRQdXNoVXJsKCRwYXRoLCAkdXJsKQogICAgewogICAgICAgIC8vIHNldCBwdXNoIHVybCBmb3IgZ2l0aHViIHByb2plY3RzCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKD86aHR0cHM/fGdpdCk6Ly8nLkdpdFV0aWw6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKS4nLyhbXi9dKykvKFteL10rPykoPzpcLmdpdCk/JH0nLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICRwcm90b2NvbHMgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGh1Yi1wcm90b2NvbHMnKTsKICAgICAgICAgICAgJHB1c2hVcmwgPSAnZ2l0QCcuJG1hdGNoWzFdLic6Jy4kbWF0Y2hbMl0uJy8nLiRtYXRjaFszXS4nLmdpdCc7CiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJ3NzaCcsICRwcm90b2NvbHMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkcHVzaFVybCA9ICdodHRwczovLycgLiAkbWF0Y2hbMV0gLiAnLycuJG1hdGNoWzJdLicvJy4kbWF0Y2hbM10uJy5naXQnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjbWQgPSBzcHJpbnRmKCdnaXQgcmVtb3RlIHNldC11cmwgLS1wdXNoIG9yaWdpbiAtLSAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwdXNoVXJsKSk7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjbWQsICRpZ25vcmVkT3V0cHV0LCAkcGF0aCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSwgJHBhdGgpCiAgICB7CiAgICAgICAgJHBhdGggPSAkdGhpcy0+bm9ybWFsaXplUGF0aCgkcGF0aCk7CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdnaXQgbG9nICVzLi4lcyAtLXByZXR0eT1mb3JtYXQ6IiUlaCAtICUlYW46ICUlcyInLkdpdFV0aWw6OmdldE5vU2hvd1NpZ25hdHVyZUZsYWcoJHRoaXMtPnByb2Nlc3MpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZnJvbVJlZmVyZW5jZSksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0b1JlZmVyZW5jZSkpOwoKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRpc2NhcmRDaGFuZ2VzKCRwYXRoKQogICAgewogICAgICAgICRwYXRoID0gJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNsZWFuIC1kZiAmJiBnaXQgcmVzZXQgLS1oYXJkJywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiQ291bGQgbm90IHJlc2V0IGNoYW5nZXNcblxuOiIuJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aGFzRGlzY2FyZGVkQ2hhbmdlc1skcGF0aF0gPSB0cnVlOwoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHN0YXNoQ2hhbmdlcygkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBzdGFzaCAtLWluY2x1ZGUtdW50cmFja2VkJywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiQ291bGQgbm90IHN0YXNoIGNoYW5nZXNcblxuOiIuJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aGFzU3Rhc2hlZENoYW5nZXNbJHBhdGhdID0gdHJ1ZTsKCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2aWV3RGlmZigkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBkaWZmIEhFQUQnLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJDb3VsZCBub3QgdmlldyBkaWZmXG5cbjoiLiRvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRvdXRwdXQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBub3JtYWxpemVQYXRoKCRwYXRoKQogICAgewogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgc3RybGVuKCRwYXRoKSA+IDApIHsKICAgICAgICAgICAgJGJhc2VQYXRoID0gJHBhdGg7CiAgICAgICAgICAgICRyZW1vdmVkID0gYXJyYXkoKTsKCiAgICAgICAgICAgIHdoaWxlICghaXNfZGlyKCRiYXNlUGF0aCkgJiYgJGJhc2VQYXRoICE9PSAnXFwnKSB7CiAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRyZW1vdmVkLCBiYXNlbmFtZSgkYmFzZVBhdGgpKTsKICAgICAgICAgICAgICAgICRiYXNlUGF0aCA9IGRpcm5hbWUoJGJhc2VQYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRiYXNlUGF0aCA9PT0gJ1xcJykgewogICAgICAgICAgICAgICAgcmV0dXJuICRwYXRoOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGF0aCA9IHJ0cmltKHJlYWxwYXRoKCRiYXNlUGF0aCkgLiAnLycgLiBpbXBsb2RlKCcvJywgJHJlbW92ZWQpLCAnLycpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYXRoOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKCiAgICAgICAgcmV0dXJuIGlzX2RpcigkcGF0aC4nLy5naXQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRyZWZlcmVuY2UKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRTaG9ydEhhc2goJHJlZmVyZW5jZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNWZXJib3NlKCkgJiYgUHJlZzo6aXNNYXRjaCgne15bMC05YS1mXXs0MH0kfScsICRyZWZlcmVuY2UpKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHJlZmVyZW5jZSwgMCwgMTApOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZWZlcmVuY2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBUcmFuc3BvcnRFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbgp7CiAgICAvKiogQHZhciA/YXJyYXk8c3RyaW5nPiAqLwogICAgcHJvdGVjdGVkICRoZWFkZXJzOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRyZXNwb25zZTsKICAgIC8qKiBAdmFyID9pbnQgKi8KICAgIHByb3RlY3RlZCAkc3RhdHVzQ29kZTsKICAgIC8qKiBAdmFyIGFycmF5PG1peGVkPiAqLwogICAgcHJvdGVjdGVkICRyZXNwb25zZUluZm8gPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZz4gJGhlYWRlcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhlYWRlcnMoJGhlYWRlcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmhlYWRlcnMgPSAkaGVhZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gP2FycmF5PHN0cmluZz4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlYWRlcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aGVhZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSA/c3RyaW5nICRyZXNwb25zZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVzcG9uc2UoJHJlc3BvbnNlKQogICAgewogICAgICAgICR0aGlzLT5yZXNwb25zZSA9ICRyZXNwb25zZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gP3N0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVzcG9uc2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVzcG9uc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gP2ludCAkc3RhdHVzQ29kZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3RhdHVzQ29kZSgkc3RhdHVzQ29kZSkKICAgIHsKICAgICAgICAkdGhpcy0+c3RhdHVzQ29kZSA9ICRzdGF0dXNDb2RlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiA/aW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGF0dXNDb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXR1c0NvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5PG1peGVkPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVzcG9uc2VJbmZvKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlc3BvbnNlSW5mbzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxtaXhlZD4gJHJlc3BvbnNlSW5mbwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVzcG9uc2VJbmZvKGFycmF5ICRyZXNwb25zZUluZm8pCiAgICB7CiAgICAgICAgJHRoaXMtPnJlc3BvbnNlSW5mbyA9ICRyZXNwb25zZUluZm87CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uR3Vlc3NlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVXBkYXRlT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KYWJzdHJhY3QgY2xhc3MgVmNzRG93bmxvYWRlciBpbXBsZW1lbnRzIERvd25sb2FkZXJJbnRlcmZhY2UsIENoYW5nZVJlcG9ydEludGVyZmFjZSwgVmNzQ2FwYWJsZURvd25sb2FkZXJJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcm90ZWN0ZWQgJHByb2Nlc3M7CiAgICAvKiogQHZhciBGaWxlc3lzdGVtICovCiAgICBwcm90ZWN0ZWQgJGZpbGVzeXN0ZW07CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHRydWU+ICovCiAgICBwcm90ZWN0ZWQgJGhhc0NsZWFuZWRDaGFuZ2VzID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCwgRmlsZXN5c3RlbSAkZnMgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmcyA/OiBuZXcgRmlsZXN5c3RlbSgkdGhpcy0+cHJvY2Vzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGF0aW9uU291cmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3NvdXJjZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSAnLiRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBpcyBtaXNzaW5nIHJlZmVyZW5jZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJHVybHMgPSAkdGhpcy0+cHJlcGFyZVVybHMoJHBhY2thZ2UtPmdldFNvdXJjZVVybHMoKSk7CgogICAgICAgIHdoaWxlICgkdXJsID0gYXJyYXlfc2hpZnQoJHVybHMpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvRG93bmxvYWQoJHBhY2thZ2UsICRwYXRoLCAkdXJsLCAkcHJldlBhY2thZ2UpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyByZXRocm93IHBocHVuaXQgZXhjZXB0aW9ucyB0byBhdm9pZCBoYXJkIHRvIGRlYnVnIGJ1ZyBmYWlsdXJlcwogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgXFBIUFVuaXRcRnJhbWV3b3JrXEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdGYWlsZWQ6IFsnLmdldF9jbGFzcygkZSkuJ10gJy4kZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChjb3VudCgkdXJscykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBGYWlsZWQsIHRyeWluZyB0aGUgbmV4dCBVUkwnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghY291bnQoJHVybHMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHR5cGUgPT09ICd1cGRhdGUnKSB7CiAgICAgICAgICAgICR0aGlzLT5jbGVhbkNoYW5nZXMoJHByZXZQYWNrYWdlLCAkcGF0aCwgdHJ1ZSk7CiAgICAgICAgICAgICR0aGlzLT5oYXNDbGVhbmVkQ2hhbmdlc1skcHJldlBhY2thZ2UtPmdldFVuaXF1ZU5hbWUoKV0gPSB0cnVlOwogICAgICAgIH0gZWxzZWlmICgkdHlwZSA9PT0gJ2luc3RhbGwnKSB7CiAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbXB0eURpcmVjdG9yeSgkcGF0aCk7CiAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09PSAndW5pbnN0YWxsJykgewogICAgICAgICAgICAkdGhpcy0+Y2xlYW5DaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICgkdHlwZSA9PT0gJ3VwZGF0ZScgJiYgaXNzZXQoJHRoaXMtPmhhc0NsZWFuZWRDaGFuZ2VzWyRwcmV2UGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnJlYXBwbHlDaGFuZ2VzKCRwYXRoKTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmhhc0NsZWFuZWRDaGFuZ2VzWyRwcmV2UGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BhY2thZ2UgJy4kcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLicgaXMgbWlzc2luZyByZWZlcmVuY2UgaW5mb3JtYXRpb24nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBJbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpLic6ICcsIGZhbHNlKTsKCiAgICAgICAgJHVybHMgPSAkdGhpcy0+cHJlcGFyZVVybHMoJHBhY2thZ2UtPmdldFNvdXJjZVVybHMoKSk7CiAgICAgICAgd2hpbGUgKCR1cmwgPSBhcnJheV9zaGlmdCgkdXJscykpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICR0aGlzLT5kb0luc3RhbGwoJHBhY2thZ2UsICRwYXRoLCAkdXJsKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyByZXRocm93IHBocHVuaXQgZXhjZXB0aW9ucyB0byBhdm9pZCBoYXJkIHRvIGRlYnVnIGJ1ZyBmYWlsdXJlcwogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgXFBIUFVuaXRcRnJhbWV3b3JrXEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdGYWlsZWQ6IFsnLmdldF9jbGFzcygkZSkuJ10gJy4kZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChjb3VudCgkdXJscykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBGYWlsZWQsIHRyeWluZyB0aGUgbmV4dCBVUkwnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghY291bnQoJHVybHMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSAnLiR0YXJnZXQtPmdldFByZXR0eU5hbWUoKS4nIGlzIG1pc3NpbmcgcmVmZXJlbmNlIGluZm9ybWF0aW9uJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVXBkYXRlT3BlcmF0aW9uOjpmb3JtYXQoJGluaXRpYWwsICR0YXJnZXQpLic6ICcsIGZhbHNlKTsKCiAgICAgICAgJHVybHMgPSAkdGhpcy0+cHJlcGFyZVVybHMoJHRhcmdldC0+Z2V0U291cmNlVXJscygpKTsKCiAgICAgICAgJGV4Y2VwdGlvbiA9IG51bGw7CiAgICAgICAgd2hpbGUgKCR1cmwgPSBhcnJheV9zaGlmdCgkdXJscykpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICR0aGlzLT5kb1VwZGF0ZSgkaW5pdGlhbCwgJHRhcmdldCwgJHBhdGgsICR1cmwpOwoKICAgICAgICAgICAgICAgICRleGNlcHRpb24gPSBudWxsOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgLy8gcmV0aHJvdyBwaHB1bml0IGV4Y2VwdGlvbnMgdG8gYXZvaWQgaGFyZCB0byBkZWJ1ZyBidWcgZmFpbHVyZXMKICAgICAgICAgICAgICAgIGlmICgkZXhjZXB0aW9uIGluc3RhbmNlb2YgXFBIUFVuaXRcRnJhbWV3b3JrXEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRleGNlcHRpb247CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0ZhaWxlZDogWycuZ2V0X2NsYXNzKCRleGNlcHRpb24pLiddICcuJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChjb3VudCgkdXJscykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBGYWlsZWQsIHRyeWluZyB0aGUgbmV4dCBVUkwnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gcHJpbnQgdGhlIGNvbW1pdCBsb2dzIGlmIGluIHZlcmJvc2UgbW9kZSBhbmQgVkNTIG1ldGFkYXRhIGlzIHByZXNlbnQKICAgICAgICAvLyBiZWNhdXNlIGluIGNhc2Ugb2YgbWlzc2luZyBtZXRhZGF0YSBjb2RlIHdvdWxkIHRyaWdnZXIgYW5vdGhlciBleGNlcHRpb24KICAgICAgICBpZiAoISRleGNlcHRpb24gJiYgJHRoaXMtPmlvLT5pc1ZlcmJvc2UoKSAmJiAkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICAkbWVzc2FnZSA9ICdQdWxsaW5nIGluIGNoYW5nZXM6JzsKICAgICAgICAgICAgJGxvZ3MgPSAkdGhpcy0+Z2V0Q29tbWl0TG9ncygkaW5pdGlhbC0+Z2V0U291cmNlUmVmZXJlbmNlKCksICR0YXJnZXQtPmdldFNvdXJjZVJlZmVyZW5jZSgpLCAkcGF0aCk7CgogICAgICAgICAgICBpZiAoIXRyaW0oJGxvZ3MpKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdSb2xsaW5nIGJhY2sgY2hhbmdlczonOwogICAgICAgICAgICAgICAgJGxvZ3MgPSAkdGhpcy0+Z2V0Q29tbWl0TG9ncygkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKSwgJGluaXRpYWwtPmdldFNvdXJjZVJlZmVyZW5jZSgpLCAkcGF0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0cmltKCRsb2dzKSkgewogICAgICAgICAgICAgICAgJGxvZ3MgPSBpbXBsb2RlKCJcbiIsIGFycmF5X21hcChmdW5jdGlvbiAoJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJyAgICAgICcgLiAkbGluZTsKICAgICAgICAgICAgICAgIH0sIGV4cGxvZGUoIlxuIiwgJGxvZ3MpKSk7CgogICAgICAgICAgICAgICAgLy8gZXNjYXBlIGFuZ2xlIGJyYWNrZXRzIGZvciBwcm9wZXIgb3V0cHV0IGluIHRoZSBjb25zb2xlCiAgICAgICAgICAgICAgICAkbG9ncyA9IHN0cl9yZXBsYWNlKCc8JywgJ1w8JywgJGxvZ3MpOwoKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgICcuJG1lc3NhZ2UpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRsb2dzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdXJscyAmJiAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHRocm93ICRleGNlcHRpb247CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVW5pbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpKTsKCiAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5QXN5bmMoJHBhdGgpOwoKICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCRyZXN1bHQpIHVzZSAoJHBhdGgpIHsKICAgICAgICAgICAgaWYgKCEkcmVzdWx0KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBjb21wbGV0ZWx5IGRlbGV0ZSAnLiRwYXRoLicsIGFib3J0aW5nLicpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmNzUmVmZXJlbmNlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkZ3Vlc3NlciA9IG5ldyBWZXJzaW9uR3Vlc3NlcigkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHBhcnNlcik7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcjsKCiAgICAgICAgJHBhY2thZ2VDb25maWcgPSAkZHVtcGVyLT5kdW1wKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJHBhY2thZ2VWZXJzaW9uID0gJGd1ZXNzZXItPmd1ZXNzVmVyc2lvbigkcGFja2FnZUNvbmZpZywgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZVZlcnNpb25bJ2NvbW1pdCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9tcHQgdGhlIHVzZXIgdG8gY2hlY2sgaWYgY2hhbmdlcyBzaG91bGQgYmUgc3Rhc2hlZC9yZW1vdmVkIG9yIHRoZSBvcGVyYXRpb24gYWJvcnRlZAogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgJHBhY2thZ2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGgKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgJHVwZGF0ZSAgaWYgdHJ1ZSAodXBkYXRlKSB0aGUgY2hhbmdlcyBjYW4gYmUgc3Rhc2hlZCBhbmQgcmVhcHBsaWVkIGFmdGVyIGFuIHVwZGF0ZSwKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmFsc2UgKHJlbW92ZSkgdGhlIGNoYW5nZXMgc2hvdWxkIGJlIGFzc3VtZWQgdG8gYmUgbG9zdCBpZiB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhYm9ydGVkCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvcGVyYXRpb24gbXVzdCBiZSBhYm9ydGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjbGVhbkNoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cGRhdGUpCiAgICB7CiAgICAgICAgLy8gdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24ganVzdCBmYWlscyBpZiB0aGVyZSBhcmUgYW55IGNoYW5nZXMsIG92ZXJyaWRlIGluIGNoaWxkIGNsYXNzZXMgdG8gcHJvdmlkZSBzdGFzaC1hYmlsaXR5CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5nZXRMb2NhbENoYW5nZXMoJHBhY2thZ2UsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1NvdXJjZSBkaXJlY3RvcnkgJyAuICRwYXRoIC4gJyBoYXMgdW5jb21taXR0ZWQgY2hhbmdlcy4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFwcGx5IHByZXZpb3VzbHkgc3Rhc2hlcyBjaGFuZ2VzIGlmIGFwcGxpY2FibGUsIG9ubHkgY2FsbGVkIGFmdGVyIGFuIHVwZGF0ZSAocmVnYXJkbGVzcyBpZiBzdWNjZXNzZnVsIG9yIG5vdCkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvcGVyYXRpb24gbXVzdCBiZSBhYm9ydGVkIG9yIHRoZSBwYXRjaCBkb2VzIG5vdCBhcHBseSBjbGVhbmx5CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZWFwcGx5Q2hhbmdlcygkcGF0aCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIERvd25sb2FkcyBkYXRhIG5lZWRlZCB0byBydW4gYW4gaW5zdGFsbC91cGRhdGUgbGF0ZXIKICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICRwYXRoICAgICAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR1cmwgICAgICAgICBwYWNrYWdlIHVybAogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAkcHJldlBhY2thZ2UgcHJldmlvdXMgcGFja2FnZSAoaW4gY2FzZSBvZiBhbiB1cGRhdGUpCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBEb3dubG9hZHMgc3BlY2lmaWMgcGFja2FnZSBpbnRvIHNwZWNpZmljIGZvbGRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdXJsICAgICBwYWNrYWdlIHVybAogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpOwoKICAgIC8qKgogICAgICogVXBkYXRlcyBzcGVjaWZpYyBwYWNrYWdlIGluIHNwZWNpZmljIGZvbGRlciBmcm9tIGluaXRpYWwgdG8gdGFyZ2V0IHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwgaW5pdGlhbCBwYWNrYWdlCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0ICB1cGRhdGVkIHBhY2thZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRwYXRoICAgIGRvd25sb2FkIHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICR1cmwgICAgIHBhY2thZ2UgdXJsCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvVXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHBhdGgsICR1cmwpOwoKICAgIC8qKgogICAgICogRmV0Y2hlcyB0aGUgY29tbWl0IGxvZ3MgYmV0d2VlbiB0d28gY29tbWl0cwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRmcm9tUmVmZXJlbmNlIHRoZSBzb3VyY2UgcmVmZXJlbmNlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdG9SZWZlcmVuY2UgICB0aGUgdGFyZ2V0IHJlZmVyZW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGggICAgICAgICAgdGhlIHBhY2thZ2UgcGF0aAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSwgJHBhdGgpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIFZDUyBtZXRhZGF0YSByZXBvc2l0b3J5IGhhcyBiZWVuIGluaXRpYWxpemVkCiAgICAgKiByZXBvc2l0b3J5IGV4YW1wbGU6IC5naXR8LnN2bnwuaGcKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBoYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICR1cmxzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHByZXBhcmVVcmxzKGFycmF5ICR1cmxzKQogICAgewogICAgICAgIGZvcmVhY2ggKCR1cmxzIGFzICRpbmRleCA9PiAkdXJsKSB7CiAgICAgICAgICAgIGlmIChGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkdXJsKSkgewogICAgICAgICAgICAgICAgLy8gcmVhbHBhdGgoKSBiZWxvdyB3aWxsIG5vdCB1bmRlcnN0YW5kCiAgICAgICAgICAgICAgICAvLyB1cmwgdGhhdCBzdGFydHMgd2l0aCAiZmlsZTovLyIKICAgICAgICAgICAgICAgICRmaWxlUHJvdG9jb2wgPSAnZmlsZTovLyc7CiAgICAgICAgICAgICAgICAkaXNGaWxlUHJvdG9jb2wgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmICgwID09PSBzdHJwb3MoJHVybCwgJGZpbGVQcm90b2NvbCkpIHsKICAgICAgICAgICAgICAgICAgICAkdXJsID0gc3Vic3RyKCR1cmwsIHN0cmxlbigkZmlsZVByb3RvY29sKSk7CiAgICAgICAgICAgICAgICAgICAgJGlzRmlsZVByb3RvY29sID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyByZWFscGF0aCgpIGJlbG93IHdpbGwgbm90IHVuZGVyc3RhbmQgJTIwIHNwYWNlcyBldGMuCiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkdXJsLCAnJScpKSB7CiAgICAgICAgICAgICAgICAgICAgJHVybCA9IHJhd3VybGRlY29kZSgkdXJsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdXJsc1skaW5kZXhdID0gcmVhbHBhdGgoJHVybCk7CgogICAgICAgICAgICAgICAgaWYgKCRpc0ZpbGVQcm90b2NvbCkgewogICAgICAgICAgICAgICAgICAgICR1cmxzWyRpbmRleF0gPSAkZmlsZVByb3RvY29sIC4gJHVybHNbJGluZGV4XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR1cmxzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIFZDUyBDYXBhYmxlIERvd25sb2FkZXIgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIFN0ZXZlIEJ1em9uYXMgPHN0ZXZlQGZhbmN5Z3V5LmNvbT4KICovCmludGVyZmFjZSBWY3NDYXBhYmxlRG93bmxvYWRlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEdldHMgdGhlIFZDUyBSZWZlcmVuY2UgZm9yIHRoZSBwYWNrYWdlIGF0IHBhdGgKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBwYWNrYWdlIGRpcmVjdG9yeQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCAgICAgIHJlZmVyZW5jZSBvciBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWY3NSZWZlcmVuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFF1ZXN0aW9uOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cUXVlc3Rpb247CgovKioKICogUmVwcmVzZW50cyBhIHllcy9ubyBxdWVzdGlvbgogKiBFbmZvcmNlcyBzdHJpY3QgcmVzcG9uc2VzIHJhdGhlciB0aGFuIG5vbi1zdGFuZGFyZCBhbnN3ZXJzIGNvdW50aW5nIGFzIGRlZmF1bHQKICogQmFzZWQgb24gU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxDb25maXJtYXRpb25RdWVzdGlvbgogKgogKiBAYXV0aG9yIFRoZW8gVG9uZ2UgPHRoZW9AdGhlb3RvbmdlLmNvLnVrPgogKi8KY2xhc3MgU3RyaWN0Q29uZmlybWF0aW9uUXVlc3Rpb24gZXh0ZW5kcyBRdWVzdGlvbgp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJHRydWVBbnN3ZXJSZWdleDsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkZmFsc2VBbnN3ZXJSZWdleDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLnMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRxdWVzdGlvbiAgICAgICAgIFRoZSBxdWVzdGlvbiB0byBhc2sgdG8gdGhlIHVzZXIKICAgICAqIEBwYXJhbSBib29sICAgJGRlZmF1bHQgICAgICAgICAgVGhlIGRlZmF1bHQgYW5zd2VyIHRvIHJldHVybiwgdHJ1ZSBvciBmYWxzZQogICAgICogQHBhcmFtIHN0cmluZyAkdHJ1ZUFuc3dlclJlZ2V4ICBBIHJlZ2V4IHRvIG1hdGNoIHRoZSAieWVzIiBhbnN3ZXIKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZhbHNlQW5zd2VyUmVnZXggQSByZWdleCB0byBtYXRjaCB0aGUgIm5vIiBhbnN3ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRxdWVzdGlvbiwgJGRlZmF1bHQgPSB0cnVlLCAkdHJ1ZUFuc3dlclJlZ2V4ID0gJy9eeSg/OmVzKT8kL2knLCAkZmFsc2VBbnN3ZXJSZWdleCA9ICcvXm5vPyQvaScpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcXVlc3Rpb24sIChib29sKSAkZGVmYXVsdCk7CgogICAgICAgICR0aGlzLT50cnVlQW5zd2VyUmVnZXggPSAkdHJ1ZUFuc3dlclJlZ2V4OwogICAgICAgICR0aGlzLT5mYWxzZUFuc3dlclJlZ2V4ID0gJGZhbHNlQW5zd2VyUmVnZXg7CiAgICAgICAgJHRoaXMtPnNldE5vcm1hbGl6ZXIoJHRoaXMtPmdldERlZmF1bHROb3JtYWxpemVyKCkpOwogICAgICAgICR0aGlzLT5zZXRWYWxpZGF0b3IoJHRoaXMtPmdldERlZmF1bHRWYWxpZGF0b3IoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlciBub3JtYWxpemVyLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXREZWZhdWx0Tm9ybWFsaXplcigpCiAgICB7CiAgICAgICAgJGRlZmF1bHQgPSAkdGhpcy0+Z2V0RGVmYXVsdCgpOwogICAgICAgICR0cnVlUmVnZXggPSAkdGhpcy0+dHJ1ZUFuc3dlclJlZ2V4OwogICAgICAgICRmYWxzZVJlZ2V4ID0gJHRoaXMtPmZhbHNlQW5zd2VyUmVnZXg7CgogICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGFuc3dlcikgdXNlICgkZGVmYXVsdCwgJHRydWVSZWdleCwgJGZhbHNlUmVnZXgpIHsKICAgICAgICAgICAgaWYgKGlzX2Jvb2woJGFuc3dlcikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYW5zd2VyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChlbXB0eSgkYW5zd2VyKSAmJiAhZW1wdHkoJGRlZmF1bHQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCR0cnVlUmVnZXgsICRhbnN3ZXIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJGZhbHNlUmVnZXgsICRhbnN3ZXIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlciB2YWxpZGF0b3IuCiAgICAgKgogICAgICogQHJldHVybiBjYWxsYWJsZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERlZmF1bHRWYWxpZGF0b3IoKQogICAgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGFuc3dlcikgewogICAgICAgICAgICBpZiAoIWlzX2Jvb2woJGFuc3dlcikpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BsZWFzZSBhbnN3ZXIgeWVzLCB5LCBubywgb3Igbi4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRhbnN3ZXI7CiAgICAgICAgfTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBBbiBldmVudCBmb3IgYWxsIGNvbW1hbmRzLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQ29tbWFuZEV2ZW50IGV4dGVuZHMgRXZlbnQKewogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcml2YXRlICRjb21tYW5kTmFtZTsKCiAgICAvKioKICAgICAqIEB2YXIgSW5wdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW5wdXQ7CgogICAgLyoqCiAgICAgKiBAdmFyIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRvdXRwdXQ7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRuYW1lICAgICAgICBUaGUgZXZlbnQgbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAkY29tbWFuZE5hbWUgVGhlIGNvbW1hbmQgbmFtZQogICAgICogQHBhcmFtIElucHV0SW50ZXJmYWNlICAkaW5wdXQKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dAogICAgICogQHBhcmFtIG1peGVkW10gICAgICAgICAkYXJncyAgICAgICAgQXJndW1lbnRzIHBhc3NlZCBieSB0aGUgdXNlcgogICAgICogQHBhcmFtIG1peGVkW10gICAgICAgICAkZmxhZ3MgICAgICAgT3B0aW9uYWwgZmxhZ3MgdG8gcGFzcyBkYXRhIG5vdCBhcyBhcmd1bWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsICRjb21tYW5kTmFtZSwgJGlucHV0LCAkb3V0cHV0LCBhcnJheSAkYXJncyA9IGFycmF5KCksIGFycmF5ICRmbGFncyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbmFtZSwgJGFyZ3MsICRmbGFncyk7CiAgICAgICAgJHRoaXMtPmNvbW1hbmROYW1lID0gJGNvbW1hbmROYW1lOwogICAgICAgICR0aGlzLT5pbnB1dCA9ICRpbnB1dDsKICAgICAgICAkdGhpcy0+b3V0cHV0ID0gJG91dHB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1hbmQgaW5wdXQgaW50ZXJmYWNlCiAgICAgKgogICAgICogQHJldHVybiBJbnB1dEludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5wdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5wdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbW1hbmQgb3V0cHV0IGludGVyZmFjZQogICAgICoKICAgICAqIEByZXR1cm4gT3V0cHV0SW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmVzIHRoZSBuYW1lIG9mIHRoZSBjb21tYW5kIGJlaW5nIHJ1bgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21tYW5kTmFtZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIFRoZSBwb3N0IGZpbGUgZG93bmxvYWQgZXZlbnQuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQb3N0RmlsZURvd25sb2FkRXZlbnQgZXh0ZW5kcyBFdmVudAp7CiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJGZpbGVOYW1lOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcml2YXRlICRjaGVja3N1bTsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJHVybDsKCiAgICAvKioKICAgICAqIEB2YXIgbWl4ZWQKICAgICAqLwogICAgcHJpdmF0ZSAkY29udGV4dDsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJHR5cGU7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJG5hbWUgICAgIFRoZSBldmVudCBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGZpbGVOYW1lIFRoZSBmaWxlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY2hlY2tzdW0gVGhlIGNoZWNrc3VtCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHVybCAgICAgIFRoZSBwcm9jZXNzZWQgdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHR5cGUgICAgIFRoZSB0eXBlIChwYWNrYWdlIG9yIG1ldGFkYXRhKS4KICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkY29udGV4dCAgQWRkaXRpb25hbCBjb250ZXh0IGZvciB0aGUgZG93bmxvYWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJGZpbGVOYW1lLCAkY2hlY2tzdW0sICR1cmwsICR0eXBlLCAkY29udGV4dCA9IG51bGwpCiAgICB7CiAgICAgICAgLyoqIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUgKi8KICAgICAgICBpZiAoJGNvbnRleHQgPT09IG51bGwgJiYgJHR5cGUgaW5zdGFuY2VvZiBQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRjb250ZXh0ID0gJHR5cGU7CiAgICAgICAgICAgICR0eXBlID0gJ3BhY2thZ2UnOwogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdQb3N0RmlsZURvd25sb2FkRXZlbnQ6Ol9fY29uc3RydWN0IHNob3VsZCByZWNlaXZlIGEgJHR5cGU9cGFja2FnZSBhbmQgdGhlIHBhY2thZ2Ugb2JqZWN0IGluICRjb250ZXh0IHNpbmNlIENvbXBvc2VyIDIuMS4nLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRuYW1lKTsKICAgICAgICAkdGhpcy0+ZmlsZU5hbWUgPSAkZmlsZU5hbWU7CiAgICAgICAgJHRoaXMtPmNoZWNrc3VtID0gJGNoZWNrc3VtOwogICAgICAgICR0aGlzLT51cmwgPSAkdXJsOwogICAgICAgICR0aGlzLT5jb250ZXh0ID0gJGNvbnRleHQ7CiAgICAgICAgJHRoaXMtPnR5cGUgPSAkdHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUgdGFyZ2V0IGZpbGUgbmFtZSBsb2NhdGlvbi4KICAgICAqCiAgICAgKiBJZiB0aGlzIGRvd25sb2FkIGlzIG9mIHR5cGUgbWV0YWRhdGEsIG51bGwgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZU5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZU5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjaGVja3N1bS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGVja3N1bSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jaGVja3N1bTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByb2Nlc3NlZCBVUkwuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb250ZXh0IG9mIHRoaXMgZG93bmxvYWQsIGlmIGFueS4KICAgICAqCiAgICAgKiBJZiB0aGlzIGRvd25sb2FkIGlzIG9mIHR5cGUgcGFja2FnZSwgdGhlIHBhY2thZ2Ugb2JqZWN0IGlzIHJldHVybmVkLiBJZgogICAgICogdGhpcyBkb3dubG9hZCBpcyBvZiB0eXBlIG1ldGFkYXRhLCBhbiBhcnJheXtyZXNwb25zZTogUmVzcG9uc2UsIHJlcG9zaXRvcnk6IFJlcG9zaXRvcnlJbnRlcmZhY2V9IGlzIHJldHVybmVkLgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRleHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29udGV4dDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgcGFja2FnZS4KICAgICAqCiAgICAgKiBJZiB0aGlzIGRvd25sb2FkIGlzIG9mIHR5cGUgbWV0YWRhdGEsIG51bGwgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQHJldHVybiBcQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlfG51bGwgVGhlIHBhY2thZ2UuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgZ2V0Q29udGV4dCBpbnN0ZWFkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICB0cmlnZ2VyX2Vycm9yKCdQb3N0RmlsZURvd25sb2FkRXZlbnQ6OmdldFBhY2thZ2UgaXMgZGVwcmVjYXRlZCBzaW5jZSBDb21wb3NlciAyLjEsIHVzZSBnZXRDb250ZXh0IGluc3RlYWQuJywgRV9VU0VSX0RFUFJFQ0FURUQpOwogICAgICAgICRjb250ZXh0ID0gJHRoaXMtPmdldENvbnRleHQoKTsKCiAgICAgICAgcmV0dXJuICRjb250ZXh0IGluc3RhbmNlb2YgUGFja2FnZUludGVyZmFjZSA/ICRjb250ZXh0IDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhpcyBkb3dubG9hZCAocGFja2FnZSwgbWV0YWRhdGEpLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnR5cGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luOwoKLyoqCiAqIFRoZSBQbHVnaW4gRXZlbnRzLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUGx1Z2luRXZlbnRzCnsKICAgIC8qKgogICAgICogVGhlIElOSVQgZXZlbnQgb2NjdXJzIGFmdGVyIGEgQ29tcG9zZXIgaW5zdGFuY2UgaXMgZG9uZSBiZWluZyBpbml0aWFsaXplZAogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYQogICAgICogQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IElOSVQgPSAnaW5pdCc7CgogICAgLyoqCiAgICAgKiBUaGUgQ09NTUFORCBldmVudCBvY2N1cnMgYXMgYSBjb21tYW5kIGJlZ2lucwogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYQogICAgICogQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBDT01NQU5EID0gJ2NvbW1hbmQnOwoKICAgIC8qKgogICAgICogVGhlIFBSRV9GSUxFX0RPV05MT0FEIGV2ZW50IG9jY3VycyBiZWZvcmUgZG93bmxvYWRpbmcgYSBmaWxlCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhCiAgICAgKiBDb21wb3NlclxQbHVnaW5cUHJlRmlsZURvd25sb2FkRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX0ZJTEVfRE9XTkxPQUQgPSAncHJlLWZpbGUtZG93bmxvYWQnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfRklMRV9ET1dOTE9BRCBldmVudCBvY2N1cnMgYWZ0ZXIgZG93bmxvYWRpbmcgYSBwYWNrYWdlIGRpc3QgZmlsZQogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYQogICAgICogQ29tcG9zZXJcUGx1Z2luXFBvc3RGaWxlRG93bmxvYWRFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX0ZJTEVfRE9XTkxPQUQgPSAncG9zdC1maWxlLWRvd25sb2FkJzsKCiAgICAvKioKICAgICAqIFRoZSBQUkVfQ09NTUFORF9SVU4gZXZlbnQgb2NjdXJzIGJlZm9yZSBhIGNvbW1hbmQgaXMgZXhlY3V0ZWQgYW5kIGxldHMgeW91IG1vZGlmeSB0aGUgaW5wdXQgYXJndW1lbnRzL29wdGlvbnMKICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEKICAgICAqIENvbXBvc2VyXFBsdWdpblxQcmVDb21tYW5kUnVuRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX0NPTU1BTkRfUlVOID0gJ3ByZS1jb21tYW5kLXJ1bic7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX1BPT0xfQ1JFQVRFIGV2ZW50IG9jY3VycyBiZWZvcmUgdGhlIFBvb2wgb2YgcGFja2FnZXMgaXMgY3JlYXRlZCwgYW5kIGxldHMKICAgICAqIHlvdSBmaWx0ZXIgdGhlIGxpc3Qgb2YgcGFja2FnZXMgd2hpY2ggaXMgZ29pbmcgdG8gZW50ZXIgdGhlIFNvbHZlcgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYQogICAgICogQ29tcG9zZXJcUGx1Z2luXFByZVBvb2xDcmVhdGVFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfUE9PTF9DUkVBVEUgPSAncHJlLXBvb2wtY3JlYXRlJzsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKCi8qKgogKiBUaGUgcHJlIGZpbGUgZG93bmxvYWQgZXZlbnQuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQcmVGaWxlRG93bmxvYWRFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBIdHRwRG93bmxvYWRlcgogICAgICovCiAgICBwcml2YXRlICRodHRwRG93bmxvYWRlcjsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJHByb2Nlc3NlZFVybDsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSAkY3VzdG9tQ2FjaGVLZXk7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcml2YXRlICR0eXBlOwoKICAgIC8qKgogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcml2YXRlICRjb250ZXh0OwoKICAgIC8qKgogICAgICogQHZhciBtaXhlZFtdCiAgICAgKi8KICAgIHByaXZhdGUgJHRyYW5zcG9ydE9wdGlvbnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICRuYW1lICAgICAgICAgICBUaGUgZXZlbnQgbmFtZQogICAgICogQHBhcmFtIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICRwcm9jZXNzZWRVcmwKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAkdHlwZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyLCAkcHJvY2Vzc2VkVXJsLCAkdHlwZSwgJGNvbnRleHQgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG5hbWUpOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+cHJvY2Vzc2VkVXJsID0gJHByb2Nlc3NlZFVybDsKICAgICAgICAkdGhpcy0+dHlwZSA9ICR0eXBlOwogICAgICAgICR0aGlzLT5jb250ZXh0ID0gJGNvbnRleHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEh0dHBEb3dubG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIdHRwRG93bmxvYWRlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5odHRwRG93bmxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUgcHJvY2Vzc2VkIFVSTCB0aGF0IHdpbGwgYmUgZG93bmxvYWRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvY2Vzc2VkVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NlZFVybDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2Nlc3NlZCBVUkwgdGhhdCB3aWxsIGJlIGRvd25sb2FkZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJvY2Vzc2VkVXJsIE5ldyBwcm9jZXNzZWQgVVJMCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm9jZXNzZWRVcmwoJHByb2Nlc3NlZFVybCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvY2Vzc2VkVXJsID0gJHByb2Nlc3NlZFVybDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyBhIGN1c3RvbSBwYWNrYWdlIGNhY2hlIGtleSBmb3IgdGhpcyBkb3dubG9hZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDdXN0b21DYWNoZUtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jdXN0b21DYWNoZUtleTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBjdXN0b20gcGFja2FnZSBjYWNoZSBrZXkgZm9yIHRoaXMgZG93bmxvYWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjdXN0b21DYWNoZUtleSBOZXcgY2FjaGUga2V5CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDdXN0b21DYWNoZUtleSgkY3VzdG9tQ2FjaGVLZXkpCiAgICB7CiAgICAgICAgJHRoaXMtPmN1c3RvbUNhY2hlS2V5ID0gJGN1c3RvbUNhY2hlS2V5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGlzIGRvd25sb2FkIChwYWNrYWdlLCBtZXRhZGF0YSkuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnRleHQgb2YgdGhpcyBkb3dubG9hZCwgaWYgYW55LgogICAgICoKICAgICAqIElmIHRoaXMgZG93bmxvYWQgaXMgb2YgdHlwZSBwYWNrYWdlLCB0aGUgcGFja2FnZSBvYmplY3QgaXMgcmV0dXJuZWQuCiAgICAgKiBJZiB0aGUgdHlwZSBpcyBtZXRhZGF0YSwgYW4gYXJyYXl7cmVwb3NpdG9yeTogUmVwb3NpdG9yeUludGVyZmFjZX0gaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb250ZXh0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgdGhlIGRvd25sb2FkLgogICAgICoKICAgICAqIE9ubHkgYXZhaWxhYmxlIGZvciBldmVudHMgd2l0aCB0eXBlIG1ldGFkYXRhLCBmb3IgcGFja2FnZXMgc2V0IHRoZSB0cmFuc3BvcnQgb3B0aW9ucyBvbiB0aGUgcGFja2FnZSBpdHNlbGYuCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUcmFuc3BvcnRPcHRpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRyYW5zcG9ydE9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRyYW5zcG9ydCBvcHRpb25zIGZvciB0aGUgZG93bmxvYWQuCiAgICAgKgogICAgICogT25seSBhdmFpbGFibGUgZm9yIGV2ZW50cyB3aXRoIHR5cGUgbWV0YWRhdGEsIGZvciBwYWNrYWdlcyBzZXQgdGhlIHRyYW5zcG9ydCBvcHRpb25zIG9uIHRoZSBwYWNrYWdlIGl0c2VsZi4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhbnNwb3J0T3B0aW9ucyhhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+dHJhbnNwb3J0T3B0aW9ucyA9ICRvcHRpb25zOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsdWdpblxDYXBhYmlsaXR5OwoKLyoqCiAqIE1hcmtlciBpbnRlcmZhY2UgZm9yIFBsdWdpbiBjYXBhYmlsaXRpZXMuCiAqIEV2ZXJ5IG5ldyBDYXBhYmlsaXR5IHdoaWNoIGlzIGFkZGVkIHRvIHRoZSBQbHVnaW4gQVBJIG11c3QgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLgogKgogKiBAYXBpCiAqLwppbnRlcmZhY2UgQ2FwYWJpbGl0eQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luXENhcGFiaWxpdHk7CgovKioKICogQ29tbWFuZHMgUHJvdmlkZXIgSW50ZXJmYWNlCiAqCiAqIFRoaXMgY2FwYWJpbGl0eSB3aWxsIHJlY2VpdmUgYW4gYXJyYXkgd2l0aCAnY29tcG9zZXInIGFuZCAnaW8nIGtleXMgYXMKICogY29uc3RydWN0b3IgYXJndW1lbnQuIFRob3NlIGNvbnRhaW4gQ29tcG9zZXJcQ29tcG9zZXIgYW5kIENvbXBvc2VyXElPXElPSW50ZXJmYWNlCiAqIGluc3RhbmNlcy4gSXQgYWxzbyBjb250YWlucyBhICdwbHVnaW4nIGtleSBjb250YWluaW5nIHRoZSBwbHVnaW4gaW5zdGFuY2UgdGhhdAogKiBjcmVhdGVkIHRoZSBjYXBhYmlsaXR5LgogKgogKiBAYXV0aG9yIErDqXLDqW15IERlcnVzc8OpIDxqZXJlbXlAZGVydXNzZS5jb20+CiAqLwppbnRlcmZhY2UgQ29tbWFuZFByb3ZpZGVyIGV4dGVuZHMgQ2FwYWJpbGl0eQp7CiAgICAvKioKICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBjb21tYW5kcwogICAgICoKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXENvbW1hbmRcQmFzZUNvbW1hbmRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZHMoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFJlcXVlc3Q7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwoKLyoqCiAqIFRoZSBwcmUgY29tbWFuZCBydW4gZXZlbnQuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFByZVBvb2xDcmVhdGVFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBSZXBvc2l0b3J5SW50ZXJmYWNlW10KICAgICAqLwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yaWVzOwogICAgLyoqCiAgICAgKiBAdmFyIFJlcXVlc3QKICAgICAqLwogICAgcHJpdmF0ZSAkcmVxdWVzdDsKICAgIC8qKgogICAgICogQHZhciBpbnRbXSBhcnJheSBvZiBzdGFiaWxpdHkgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+CiAgICAgKi8KICAgIHByaXZhdGUgJGFjY2VwdGFibGVTdGFiaWxpdGllczsKICAgIC8qKgogICAgICogQHZhciBpbnRbXSBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+CiAgICAgKi8KICAgIHByaXZhdGUgJHN0YWJpbGl0eUZsYWdzOwogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5W10gb2YgcGFja2FnZSA9PiB2ZXJzaW9uID0+IFthbGlhcywgYWxpYXNfbm9ybWFsaXplZF0KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgYXJyYXl7YWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4+CiAgICAgKi8KICAgIHByaXZhdGUgJHJvb3RBbGlhc2VzOwogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ1tdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJHJvb3RSZWZlcmVuY2VzOwogICAgLyoqCiAgICAgKiBAdmFyIEJhc2VQYWNrYWdlW10KICAgICAqLwogICAgcHJpdmF0ZSAkcGFja2FnZXM7CiAgICAvKioKICAgICAqIEB2YXIgQmFzZVBhY2thZ2VbXQogICAgICovCiAgICBwcml2YXRlICR1bmFjY2VwdGFibGVGaXhlZFBhY2thZ2VzOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAkbmFtZSAgICAgICAgICAgICAgICAgICBUaGUgZXZlbnQgbmFtZQogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2VbXSAkcmVwb3NpdG9yaWVzCiAgICAgKiBAcGFyYW0gaW50W10gICAgICAgICAgICAgICAgICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgIGFycmF5IG9mIHN0YWJpbGl0eSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwYXJhbSBpbnRbXSAgICAgICAgICAgICAgICAgJHN0YWJpbGl0eUZsYWdzICAgICAgICAgYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBhcmFtIGFycmF5W10gICAgICAgICAgICAgICAkcm9vdEFsaWFzZXMgICAgICAgICAgICBhcnJheSBvZiBwYWNrYWdlID0+IHZlcnNpb24gPT4gW2FsaWFzLCBhbGlhc19ub3JtYWxpemVkXQogICAgICogQHBhcmFtIHN0cmluZ1tdICAgICAgICAgICAgICAkcm9vdFJlZmVyZW5jZXMKICAgICAqIEBwYXJhbSBCYXNlUGFja2FnZVtdICAgICAgICAgJHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gQmFzZVBhY2thZ2VbXSAgICAgICAgICR1bmFjY2VwdGFibGVGaXhlZFBhY2thZ2VzCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBhcnJheXthbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9Pj4gJHJvb3RBbGlhc2VzCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJHJvb3RSZWZlcmVuY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgYXJyYXkgJHJlcG9zaXRvcmllcywgUmVxdWVzdCAkcmVxdWVzdCwgYXJyYXkgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCBhcnJheSAkcm9vdEFsaWFzZXMsIGFycmF5ICRyb290UmVmZXJlbmNlcywgYXJyYXkgJHBhY2thZ2VzLCBhcnJheSAkdW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlcykKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRuYW1lKTsKCiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllcyA9ICRyZXBvc2l0b3JpZXM7CiAgICAgICAgJHRoaXMtPnJlcXVlc3QgPSAkcmVxdWVzdDsKICAgICAgICAkdGhpcy0+YWNjZXB0YWJsZVN0YWJpbGl0aWVzID0gJGFjY2VwdGFibGVTdGFiaWxpdGllczsKICAgICAgICAkdGhpcy0+c3RhYmlsaXR5RmxhZ3MgPSAkc3RhYmlsaXR5RmxhZ3M7CiAgICAgICAgJHRoaXMtPnJvb3RBbGlhc2VzID0gJHJvb3RBbGlhc2VzOwogICAgICAgICR0aGlzLT5yb290UmVmZXJlbmNlcyA9ICRyb290UmVmZXJlbmNlczsKICAgICAgICAkdGhpcy0+cGFja2FnZXMgPSAkcGFja2FnZXM7CiAgICAgICAgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXMgPSAkdW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeUludGVyZmFjZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3JpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb3NpdG9yaWVzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXF1ZXN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcXVlc3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludFtdIGFycmF5IG9mIHN0YWJpbGl0eSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFjY2VwdGFibGVTdGFiaWxpdGllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludFtdIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eUZsYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YWJpbGl0eUZsYWdzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdIG9mIHBhY2thZ2UgPT4gdmVyc2lvbiA9PiBbYWxpYXMsIGFsaWFzX25vcm1hbGl6ZWRdCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGFycmF5e2FsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdEFsaWFzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdEFsaWFzZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290UmVmZXJlbmNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290UmVmZXJlbmNlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQmFzZVBhY2thZ2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBCYXNlUGFja2FnZVtdICRwYWNrYWdlcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgICR0aGlzLT5wYWNrYWdlcyA9ICRwYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBCYXNlUGFja2FnZVtdICRwYWNrYWdlcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlcyhhcnJheSAkcGFja2FnZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXMgPSAkcGFja2FnZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgovKioKICogUGx1Z2luIGludGVyZmFjZQogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KaW50ZXJmYWNlIFBsdWdpbkludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcm5hbCBjb21wb3Nlci1wbHVnaW4tYXBpIHBhY2thZ2UKICAgICAqCiAgICAgKiBUaGlzIGlzIHVzZWQgdG8gZGVub3RlIHRoZSBBUEkgdmVyc2lvbiBvZiBQbHVnaW4gc3BlY2lmaWMKICAgICAqIGZlYXR1cmVzLCBidXQgaXMgYWxzbyBidW1wZWQgdG8gYSBuZXcgbWFqb3IgaWYgQ29tcG9zZXIKICAgICAqIGluY2x1ZGVzIGEgbWFqb3IgYnJlYWsgaW4gaW50ZXJuYWwgQVBJcyB3aGljaCBhcmUgc3VzY2VwdGlibGUKICAgICAqIHRvIGJlIHVzZWQgYnkgcGx1Z2lucy4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQTFVHSU5fQVBJX1ZFUlNJT04gPSAnMi4yLjAnOwoKICAgIC8qKgogICAgICogQXBwbHkgcGx1Z2luIG1vZGlmaWNhdGlvbnMgdG8gQ29tcG9zZXIKICAgICAqCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGNvbXBvc2VyCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY3RpdmF0ZShDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbyk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYW55IGhvb2tzIGZyb20gQ29tcG9zZXIKICAgICAqCiAgICAgKiBUaGlzIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBwbHVnaW4gaXMgZGVhY3RpdmF0ZWQgYmVmb3JlIGJlaW5nCiAgICAgKiB1bmluc3RhbGxlZCwgYnV0IGFsc28gYmVmb3JlIGl0IGdldHMgdXBncmFkZWQgdG8gYSBuZXcgdmVyc2lvbgogICAgICogc28gdGhlIG9sZCBvbmUgY2FuIGJlIGRlYWN0aXZhdGVkIGFuZCB0aGUgbmV3IG9uZSBhY3RpdmF0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZShDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbyk7CgogICAgLyoqCiAgICAgKiBQcmVwYXJlIHRoZSBwbHVnaW4gdG8gYmUgdW5pbnN0YWxsZWQKICAgICAqCiAgICAgKiBUaGlzIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGRlYWN0aXZhdGUuCiAgICAgKgogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKENvbXBvc2VyICRjb21wb3NlciwgSU9JbnRlcmZhY2UgJGlvKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47CgovKioKICogUGx1Z2lucyB3aGljaCBuZWVkIHRvIGV4cG9zZSB2YXJpb3VzIGltcGxlbWVudGF0aW9ucwogKiBvZiB0aGUgQ29tcG9zZXIgUGx1Z2luIENhcGFiaWxpdGllcyBtdXN0IGhhdmUgdGhlaXIKICogZGVjbGFyZWQgUGx1Z2luIGNsYXNzIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZS4KICoKICogQGFwaQogKi8KaW50ZXJmYWNlIENhcGFibGUKewogICAgLyoqCiAgICAgKiBNZXRob2QgYnkgd2hpY2ggYSBQbHVnaW4gYW5ub3VuY2VzIGl0cyBBUEkgaW1wbGVtZW50YXRpb25zLCB0aHJvdWdoIGFuIGFycmF5CiAgICAgKiB3aXRoIGEgc3BlY2lhbCBzdHJ1Y3R1cmUuCiAgICAgKgogICAgICogVGhlIGtleSBtdXN0IGJlIGEgc3RyaW5nLCByZXByZXNlbnRpbmcgYSBmdWxseSBxdWFsaWZpZWQgY2xhc3MvaW50ZXJmYWNlIG5hbWUKICAgICAqIHdoaWNoIENvbXBvc2VyIFBsdWdpbiBBUEkgZXhwb3Nlcy4KICAgICAqIFRoZSB2YWx1ZSBtdXN0IGJlIGEgc3RyaW5nIGFzIHdlbGwsIHJlcHJlc2VudGluZyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUKICAgICAqIG9mIHRoZSBpbXBsZW1lbnRpbmcgY2xhc3MuCiAgICAgKgogICAgICogQHR1dG9yaWFsCiAgICAgKgogICAgICogcmV0dXJuIGFycmF5KAogICAgICogICAgICdDb21wb3NlclxQbHVnaW5cQ2FwYWJpbGl0eVxDb21tYW5kUHJvdmlkZXInID0+ICdNeVxDb21tYW5kUHJvdmlkZXInLAogICAgICogICAgICdDb21wb3NlclxQbHVnaW5cQ2FwYWJpbGl0eVxWYWxpZGF0b3InICAgICAgID0+ICdNeVxWYWxpZGF0b3InLAogICAgICogKTsKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDYXBhYmlsaXRpZXMoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxlckludGVyZmFjZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cQ2FwYWJpbGl0eVxDYXBhYmlsaXR5Owp1c2UgQ29tcG9zZXJcVXRpbFxQYWNrYWdlU29ydGVyOwoKLyoqCiAqIFBsdWdpbiBtYW5hZ2VyCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBsdWdpbk1hbmFnZXIKewogICAgLyoqIEB2YXIgQ29tcG9zZXIgKi8KICAgIHByb3RlY3RlZCAkY29tcG9zZXI7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyID9Db21wb3NlciAqLwogICAgcHJvdGVjdGVkICRnbG9iYWxDb21wb3NlcjsKICAgIC8qKiBAdmFyIFZlcnNpb25QYXJzZXIgKi8KICAgIHByb3RlY3RlZCAkdmVyc2lvblBhcnNlcjsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkZGlzYWJsZVBsdWdpbnMgPSBmYWxzZTsKCiAgICAvKiogQHZhciBhcnJheTxQbHVnaW5JbnRlcmZhY2U+ICovCiAgICBwcm90ZWN0ZWQgJHBsdWdpbnMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBQbHVnaW5JbnRlcmZhY2V8SW5zdGFsbGVySW50ZXJmYWNlPiAqLwogICAgcHJvdGVjdGVkICRyZWdpc3RlcmVkUGx1Z2lucyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5PHN0cmluZywgYm9vbD58bnVsbAogICAgICovCiAgICBwcml2YXRlICRhbGxvd1BsdWdpblJ1bGVzOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheTxzdHJpbmcsIGJvb2w+fG51bGwKICAgICAqLwogICAgcHJpdmF0ZSAkYWxsb3dHbG9iYWxQbHVnaW5SdWxlczsKCiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByaXZhdGUgc3RhdGljICRjbGFzc0NvdW50ZXIgPSAwOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcGx1Z2luIG1hbmFnZXIKICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGNvbXBvc2VyCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGdsb2JhbENvbXBvc2VyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGRpc2FibGVQbHVnaW5zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbXBvc2VyICRjb21wb3NlciwgQ29tcG9zZXIgJGdsb2JhbENvbXBvc2VyID0gbnVsbCwgJGRpc2FibGVQbHVnaW5zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+Z2xvYmFsQ29tcG9zZXIgPSAkZ2xvYmFsQ29tcG9zZXI7CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICR0aGlzLT5kaXNhYmxlUGx1Z2lucyA9ICRkaXNhYmxlUGx1Z2luczsKCiAgICAgICAgJHRoaXMtPmFsbG93UGx1Z2luUnVsZXMgPSAkdGhpcy0+cGFyc2VBbGxvd2VkUGx1Z2lucygkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2FsbG93LXBsdWdpbnMnKSk7CiAgICAgICAgJHRoaXMtPmFsbG93R2xvYmFsUGx1Z2luUnVsZXMgPSAkdGhpcy0+cGFyc2VBbGxvd2VkUGx1Z2lucygkZ2xvYmFsQ29tcG9zZXIgIT09IG51bGwgPyAkZ2xvYmFsQ29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2FsbG93LXBsdWdpbnMnKSA6IGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWRzIGFsbCBwbHVnaW5zIGZyb20gY3VycmVudGx5IGluc3RhbGxlZCBwbHVnaW4gcGFja2FnZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRJbnN0YWxsZWRQbHVnaW5zKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmRpc2FibGVQbHVnaW5zKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRyZXBvID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAkZ2xvYmFsUmVwbyA9ICR0aGlzLT5nbG9iYWxDb21wb3NlciAhPT0gbnVsbCA/ICR0aGlzLT5nbG9iYWxDb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCkgOiBudWxsOwogICAgICAgICR0aGlzLT5sb2FkUmVwb3NpdG9yeSgkcmVwbywgZmFsc2UpOwogICAgICAgIGlmICgkZ2xvYmFsUmVwbykgewogICAgICAgICAgICAkdGhpcy0+bG9hZFJlcG9zaXRvcnkoJGdsb2JhbFJlcG8sIHRydWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERlYWN0aXZhdGUgYWxsIHBsdWdpbnMgZnJvbSBjdXJyZW50bHkgaW5zdGFsbGVkIHBsdWdpbiBwYWNrYWdlcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZUluc3RhbGxlZFBsdWdpbnMoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZGlzYWJsZVBsdWdpbnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHJlcG8gPSAkdGhpcy0+Y29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwogICAgICAgICRnbG9iYWxSZXBvID0gJHRoaXMtPmdsb2JhbENvbXBvc2VyID8gJHRoaXMtPmdsb2JhbENvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSA6IG51bGw7CiAgICAgICAgJHRoaXMtPmRlYWN0aXZhdGVSZXBvc2l0b3J5KCRyZXBvLCBmYWxzZSk7CiAgICAgICAgaWYgKCRnbG9iYWxSZXBvKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWFjdGl2YXRlUmVwb3NpdG9yeSgkZ2xvYmFsUmVwbywgdHJ1ZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhbGwgY3VycmVudGx5IGFjdGl2ZSBwbHVnaW4gaW5zdGFuY2VzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxQbHVnaW5JbnRlcmZhY2U+IHBsdWdpbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsdWdpbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGx1Z2luczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgZ2xvYmFsIGNvbXBvc2VyIG9yIG51bGwgd2hlbiBtYWluIGNvbXBvc2VyIGlzIG5vdCBmdWxseSBsb2FkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEdsb2JhbENvbXBvc2VyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdsb2JhbENvbXBvc2VyOwogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXIgYSBwbHVnaW4gcGFja2FnZSwgYWN0aXZhdGUgaXQgZXRjLgogICAgICoKICAgICAqIElmIGl0J3Mgb2YgdHlwZSBjb21wb3Nlci1pbnN0YWxsZXIgaXQgaXMgcmVnaXN0ZXJlZCBhcyBhbiBpbnN0YWxsZXIKICAgICAqIGluc3RlYWQgZm9yIEJDCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICRmYWlsT25NaXNzaW5nQ2xhc3NlcyBCeSBkZWZhdWx0IHRoaXMgc2lsZW50bHkgc2tpcHMgcGx1Z2lucyB0aGF0IGNhbiBub3QgYmUgZm91bmQsIGJ1dCBpZiBzZXQgdG8gdHJ1ZSBpdCBmYWlscyB3aXRoIGFuIGV4Y2VwdGlvbgogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgJGlzR2xvYmFsUGx1Z2luICAgICAgIFNldCB0byB0cnVlIHRvIGRlbm90ZSBwbHVnaW5zIHdoaWNoIGFyZSBpbnN0YWxsZWQgaW4gdGhlIGdsb2JhbCBDb21wb3NlciBkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmFpbE9uTWlzc2luZ0NsYXNzZXMgPSBmYWxzZSwgJGlzR2xvYmFsUGx1Z2luID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5kaXNhYmxlUGx1Z2lucykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5pc1BsdWdpbkFsbG93ZWQoJHBhY2thZ2UtPmdldE5hbWUoKSwgJGlzR2xvYmFsUGx1Z2luKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1NraXBwZWQgbG9hZGluZyAiJy4kcGFja2FnZS0+Z2V0TmFtZSgpIC4gJyIgJy4oJGlzR2xvYmFsUGx1Z2luID8gJyhpbnN0YWxsZWQgZ2xvYmFsbHkpICcgOiAnJykuJ2FzIGl0IGlzIG5vdCBpbiBjb25maWcuYWxsb3ctcGx1Z2lucycsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItcGx1Z2luJykgewogICAgICAgICAgICAkcmVxdWlyZXNDb21wb3NlciA9IG51bGw7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7IC8qKiBAdmFyIExpbmsgJGxpbmsgKi8KICAgICAgICAgICAgICAgIGlmICgnY29tcG9zZXItcGx1Z2luLWFwaScgPT09ICRsaW5rLT5nZXRUYXJnZXQoKSkgewogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlc0NvbXBvc2VyID0gJGxpbmstPmdldENvbnN0cmFpbnQoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkcmVxdWlyZXNDb21wb3NlcikgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJQbHVnaW4gIi4kcGFja2FnZS0+Z2V0TmFtZSgpLiIgaXMgbWlzc2luZyBhIHJlcXVpcmUgc3RhdGVtZW50IGZvciBhIHZlcnNpb24gb2YgdGhlIGNvbXBvc2VyLXBsdWdpbi1hcGkgcGFja2FnZS4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGN1cnJlbnRQbHVnaW5BcGlWZXJzaW9uID0gJHRoaXMtPmdldFBsdWdpbkFwaVZlcnNpb24oKTsKICAgICAgICAgICAgJGN1cnJlbnRQbHVnaW5BcGlDb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz09JywgJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkY3VycmVudFBsdWdpbkFwaVZlcnNpb24pKTsKCiAgICAgICAgICAgIGlmICgkcmVxdWlyZXNDb21wb3Nlci0+Z2V0UHJldHR5U3RyaW5nKCkgPT09ICR0aGlzLT5nZXRQbHVnaW5BcGlWZXJzaW9uKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+VGhlICInIC4gJHBhY2thZ2UtPmdldE5hbWUoKSAuICciIHBsdWdpbiByZXF1aXJlcyBjb21wb3Nlci1wbHVnaW4tYXBpICcuJHRoaXMtPmdldFBsdWdpbkFwaVZlcnNpb24oKS4nLCB0aGlzICpXSUxMKiBicmVhayBpbiB0aGUgZnV0dXJlIGFuZCBpdCBzaG91bGQgYmUgZml4ZWQgQVNBUCAocmVxdWlyZSBeJy4kdGhpcy0+Z2V0UGx1Z2luQXBpVmVyc2lvbigpLicgaW5zdGVhZCBmb3IgZXhhbXBsZSkuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9IGVsc2VpZiAoISRyZXF1aXJlc0NvbXBvc2VyLT5tYXRjaGVzKCRjdXJyZW50UGx1Z2luQXBpQ29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+VGhlICInIC4gJHBhY2thZ2UtPmdldE5hbWUoKSAuICciIHBsdWdpbiAnLigkaXNHbG9iYWxQbHVnaW4gPyAnKGluc3RhbGxlZCBnbG9iYWxseSkgJyA6ICcnKS4nd2FzIHNraXBwZWQgYmVjYXVzZSBpdCByZXF1aXJlcyBhIFBsdWdpbiBBUEkgdmVyc2lvbiAoIicgLiAkcmVxdWlyZXNDb21wb3Nlci0+Z2V0UHJldHR5U3RyaW5nKCkgLiAnIikgdGhhdCBkb2VzIG5vdCBtYXRjaCB5b3VyIENvbXBvc2VyIGluc3RhbGxhdGlvbiAoIicgLiAkY3VycmVudFBsdWdpbkFwaVZlcnNpb24gLiAnIikuIFlvdSBtYXkgbmVlZCB0byBydW4gY29tcG9zZXIgdXBkYXRlIHdpdGggdGhlICItLW5vLXBsdWdpbnMiIG9wdGlvbi48L3dhcm5pbmc+Jyk7CgogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldE5hbWUoKSA9PT0gJ3N5bWZvbnkvZmxleCcgJiYgUHJlZzo6aXNNYXRjaCgne15bMC05Ll0rJH0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSAmJiB2ZXJzaW9uX2NvbXBhcmUoJHBhY2thZ2UtPmdldFZlcnNpb24oKSwgJzEuOS44JywgJzwnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5UaGUgIicgLiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4gJyIgcGx1Z2luICcuKCRpc0dsb2JhbFBsdWdpbiA/ICcoaW5zdGFsbGVkIGdsb2JhbGx5KSAnIDogJycpLid3YXMgc2tpcHBlZCBiZWNhdXNlIGl0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggQ29tcG9zZXIgMisuIE1ha2Ugc3VyZSB0byB1cGRhdGUgaXQgdG8gdmVyc2lvbiAxLjkuOCBvciBncmVhdGVyLjwvd2FybmluZz4nKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRvbGRJbnN0YWxsZXJQbHVnaW4gPSAoJHBhY2thZ2UtPmdldFR5cGUoKSA9PT0gJ2NvbXBvc2VyLWluc3RhbGxlcicpOwoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkZXh0cmEgPSAkcGFja2FnZS0+Z2V0RXh0cmEoKTsKICAgICAgICBpZiAoZW1wdHkoJGV4dHJhWydjbGFzcyddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignRXJyb3Igd2hpbGUgaW5zdGFsbGluZyAnLiRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJywgY29tcG9zZXItcGx1Z2luIHBhY2thZ2VzIHNob3VsZCBoYXZlIGEgY2xhc3MgZGVmaW5lZCBpbiB0aGVpciBleHRyYSBrZXkgdG8gYmUgdXNhYmxlLicpOwogICAgICAgIH0KICAgICAgICAkY2xhc3NlcyA9IGlzX2FycmF5KCRleHRyYVsnY2xhc3MnXSkgPyAkZXh0cmFbJ2NsYXNzJ10gOiBhcnJheSgkZXh0cmFbJ2NsYXNzJ10pOwoKICAgICAgICAkbG9jYWxSZXBvID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAkZ2xvYmFsUmVwbyA9ICR0aGlzLT5nbG9iYWxDb21wb3NlciAhPT0gbnVsbCA/ICR0aGlzLT5nbG9iYWxDb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCkgOiBudWxsOwoKICAgICAgICAkcm9vdFBhY2thZ2UgPSBjbG9uZSAkdGhpcy0+Y29tcG9zZXItPmdldFBhY2thZ2UoKTsKCiAgICAgICAgLy8gY2xlYXIgZmlsZXMgYXV0b2xvYWQgcnVsZXMgZnJvbSB0aGUgcm9vdCBwYWNrYWdlIGFzIHRoZSByb290IGRlcGVuZGVuY2llcyBhcmUgbm90CiAgICAgICAgLy8gbmVjZXNzYXJpbHkgYWxsIHByZXNlbnQgeWV0IHdoZW4gYm9vdGluZyB0aGlzIHJ1bnRpbWUgYXV0b2xvYWRlcgogICAgICAgICRyb290UGFja2FnZUF1dG9sb2FkcyA9ICRyb290UGFja2FnZS0+Z2V0QXV0b2xvYWQoKTsKICAgICAgICAkcm9vdFBhY2thZ2VBdXRvbG9hZHNbJ2ZpbGVzJ10gPSBhcnJheSgpOwogICAgICAgICRyb290UGFja2FnZS0+c2V0QXV0b2xvYWQoJHJvb3RQYWNrYWdlQXV0b2xvYWRzKTsKICAgICAgICAkcm9vdFBhY2thZ2VBdXRvbG9hZHMgPSAkcm9vdFBhY2thZ2UtPmdldERldkF1dG9sb2FkKCk7CiAgICAgICAgJHJvb3RQYWNrYWdlQXV0b2xvYWRzWydmaWxlcyddID0gYXJyYXkoKTsKICAgICAgICAkcm9vdFBhY2thZ2UtPnNldERldkF1dG9sb2FkKCRyb290UGFja2FnZUF1dG9sb2Fkcyk7CiAgICAgICAgdW5zZXQoJHJvb3RQYWNrYWdlQXV0b2xvYWRzKTsKCiAgICAgICAgJHJvb3RQYWNrYWdlUmVwbyA9IG5ldyBSb290UGFja2FnZVJlcG9zaXRvcnkoJHJvb3RQYWNrYWdlKTsKICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRsb2NhbFJlcG8sICRyb290UGFja2FnZVJlcG8pKTsKICAgICAgICBpZiAoJGdsb2JhbFJlcG8pIHsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8tPmFkZFJlcG9zaXRvcnkoJGdsb2JhbFJlcG8pOwogICAgICAgIH0KCiAgICAgICAgJGF1dG9sb2FkUGFja2FnZXMgPSBhcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpID0+ICRwYWNrYWdlKTsKICAgICAgICAkYXV0b2xvYWRQYWNrYWdlcyA9ICR0aGlzLT5jb2xsZWN0RGVwZW5kZW5jaWVzKCRpbnN0YWxsZWRSZXBvLCAkYXV0b2xvYWRQYWNrYWdlcywgJHBhY2thZ2UpOwoKICAgICAgICAkZ2VuZXJhdG9yID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRBdXRvbG9hZEdlbmVyYXRvcigpOwogICAgICAgICRhdXRvbG9hZHMgPSBhcnJheShhcnJheSgkcm9vdFBhY2thZ2UsICcnKSk7CiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2FkUGFja2FnZXMgYXMgJGF1dG9sb2FkUGFja2FnZSkgewogICAgICAgICAgICBpZiAoJGF1dG9sb2FkUGFja2FnZSA9PT0gJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRvd25sb2FkUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkYXV0b2xvYWRQYWNrYWdlLCAkZ2xvYmFsUmVwbyAmJiAkZ2xvYmFsUmVwby0+aGFzUGFja2FnZSgkYXV0b2xvYWRQYWNrYWdlKSk7CiAgICAgICAgICAgICRhdXRvbG9hZHNbXSA9IGFycmF5KCRhdXRvbG9hZFBhY2thZ2UsICRkb3dubG9hZFBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJG1hcCA9ICRnZW5lcmF0b3ItPnBhcnNlQXV0b2xvYWRzKCRhdXRvbG9hZHMsICRyb290UGFja2FnZSk7CiAgICAgICAgJGNsYXNzTG9hZGVyID0gJGdlbmVyYXRvci0+Y3JlYXRlTG9hZGVyKCRtYXAsICR0aGlzLT5jb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgndmVuZG9yLWRpcicpKTsKICAgICAgICAkY2xhc3NMb2FkZXItPnJlZ2lzdGVyKGZhbHNlKTsKCiAgICAgICAgZm9yZWFjaCAoJG1hcFsnZmlsZXMnXSBhcyAkZmlsZUlkZW50aWZpZXIgPT4gJGZpbGUpIHsKICAgICAgICAgICAgLy8gZXhjbHVkZSBsYW1pbmFzL2xhbWluYXMtemVuZGZyYW1ld29yay1icmlkZ2U6c3JjL2F1dG9sb2FkLnBocCBhcyBpdCBicmVha3MgQ29tcG9zZXIgaW4gc29tZSBjb25kaXRpb25zCiAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzEwMzQ5IGFuZCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzEwNDAxCiAgICAgICAgICAgIC8vIHRoaXMgaGFjayBjYW4gYmUgcmVtb3ZlZCBvbmNlIHRoaXMgZGVwcmVjYXRlZCBwYWNrYWdlIHN0b3AgYmVpbmcgaW5zdGFsbGVkCiAgICAgICAgICAgIGlmICgkZmlsZUlkZW50aWZpZXIgPT09ICc3ZTliZDYxMmNjNDQ0YjNlZWQ3ODhlYmJlNDYyNjNhMCcpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFxDb21wb3NlclxBdXRvbG9hZFxjb21wb3NlclJlcXVpcmUoJGZpbGVJZGVudGlmaWVyLCAkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkY2xhc3NlcyBhcyAkY2xhc3MpIHsKICAgICAgICAgICAgaWYgKGNsYXNzX2V4aXN0cygkY2xhc3MsIGZhbHNlKSkgewogICAgICAgICAgICAgICAgJGNsYXNzID0gdHJpbSgkY2xhc3MsICdcXCcpOwogICAgICAgICAgICAgICAgJHBhdGggPSAkY2xhc3NMb2FkZXItPmZpbmRGaWxlKCRjbGFzcyk7CiAgICAgICAgICAgICAgICAkY29kZSA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRwYXRoKTsKICAgICAgICAgICAgICAgICRzZXBhcmF0b3JQb3MgPSBzdHJycG9zKCRjbGFzcywgJ1xcJyk7CiAgICAgICAgICAgICAgICAkY2xhc3NOYW1lID0gJGNsYXNzOwogICAgICAgICAgICAgICAgaWYgKCRzZXBhcmF0b3JQb3MpIHsKICAgICAgICAgICAgICAgICAgICAkY2xhc3NOYW1lID0gc3Vic3RyKCRjbGFzcywgJHNlcGFyYXRvclBvcyArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgPSBQcmVnOjpyZXBsYWNlKCd7XigoPzpmaW5hbFxzKyk/KD86XHMqKSljbGFzc1xzKygnLnByZWdfcXVvdGUoJGNsYXNzTmFtZSkuJyl9bWknLCAnJDFjbGFzcyAkMl9jb21wb3Nlcl90bXAnLnNlbGY6OiRjbGFzc0NvdW50ZXIsICRjb2RlLCAxKTsKICAgICAgICAgICAgICAgICRjb2RlID0gc3RydHIoJGNvZGUsIGFycmF5KAogICAgICAgICAgICAgICAgICAgICdfX0ZJTEVfXycgPT4gdmFyX2V4cG9ydCgkcGF0aCwgdHJ1ZSksCiAgICAgICAgICAgICAgICAgICAgJ19fRElSX18nID0+IHZhcl9leHBvcnQoZGlybmFtZSgkcGF0aCksIHRydWUpLAogICAgICAgICAgICAgICAgICAgICdfX0NMQVNTX18nID0+IHZhcl9leHBvcnQoJGNsYXNzLCB0cnVlKSwKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgJGNvZGUgPSBQcmVnOjpyZXBsYWNlKCcvXlxzKjxcPyhwaHApPy9pJywgJycsICRjb2RlLCAxKTsKICAgICAgICAgICAgICAgIGV2YWwoJGNvZGUpOwogICAgICAgICAgICAgICAgJGNsYXNzIC49ICdfY29tcG9zZXJfdG1wJy5zZWxmOjokY2xhc3NDb3VudGVyOwogICAgICAgICAgICAgICAgc2VsZjo6JGNsYXNzQ291bnRlcisrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG9sZEluc3RhbGxlclBsdWdpbikgewogICAgICAgICAgICAgICAgaWYgKCFpc19hKCRjbGFzcywgJ0NvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsZXJJbnRlcmZhY2UnLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IGFjdGl2YXRlIHBsdWdpbiAiJy4kcGFja2FnZS0+Z2V0TmFtZSgpLiciIGFzICInLiRjbGFzcy4nIiBkb2VzIG5vdCBpbXBsZW1lbnQgQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxlckludGVyZmFjZScpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Mb2FkaW5nICInLiRwYWNrYWdlLT5nZXROYW1lKCkgLiAnIiAnLigkaXNHbG9iYWxQbHVnaW4gPyAnKGluc3RhbGxlZCBnbG9iYWxseSkgJyA6ICcnKS4nd2hpY2ggaXMgYSBsZWdhY3kgY29tcG9zZXItaW5zdGFsbGVyIGJ1aWx0IGZvciBDb21wb3NlciAxLngsIGl0IGlzIGxpa2VseSB0byBjYXVzZSBpc3N1ZXMgYXMgeW91IGFyZSBydW5uaW5nIENvbXBvc2VyIDIueC48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVyID0gbmV3ICRjbGFzcygkdGhpcy0+aW8sICR0aGlzLT5jb21wb3Nlcik7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+YWRkSW5zdGFsbGVyKCRpbnN0YWxsZXIpOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJGluc3RhbGxlcjsKICAgICAgICAgICAgfSBlbHNlaWYgKGNsYXNzX2V4aXN0cygkY2xhc3MpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2EoJGNsYXNzLCAnQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkludGVyZmFjZScsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgYWN0aXZhdGUgcGx1Z2luICInLiRwYWNrYWdlLT5nZXROYW1lKCkuJyIgYXMgIicuJGNsYXNzLiciIGRvZXMgbm90IGltcGxlbWVudCBDb21wb3NlclxQbHVnaW5cUGx1Z2luSW50ZXJmYWNlJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcGx1Z2luID0gbmV3ICRjbGFzcygpOwogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBsdWdpbigkcGx1Z2luLCAkaXNHbG9iYWxQbHVnaW4sICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRwbHVnaW47CiAgICAgICAgICAgIH0gZWxzZWlmICgkZmFpbE9uTWlzc2luZ0NsYXNzZXMpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdQbHVnaW4gJy4kcGFja2FnZS0+Z2V0TmFtZSgpLicgY291bGQgbm90IGJlIGluaXRpYWxpemVkLCBjbGFzcyBub3QgZm91bmQ6ICcuJGNsYXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERlYWN0aXZhdGVzIGEgcGx1Z2luIHBhY2thZ2UKICAgICAqCiAgICAgKiBJZiBpdCdzIG9mIHR5cGUgY29tcG9zZXItaW5zdGFsbGVyIGl0IGlzIHVucmVnaXN0ZXJlZCBmcm9tIHRoZSBpbnN0YWxsZXJzCiAgICAgKiBpbnN0ZWFkIGZvciBCQwogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWFjdGl2YXRlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZGlzYWJsZVBsdWdpbnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cmVnaXN0ZXJlZFBsdWdpbnNbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRwbHVnaW4gPSAkdGhpcy0+cmVnaXN0ZXJlZFBsdWdpbnNbJHBhY2thZ2UtPmdldE5hbWUoKV07CiAgICAgICAgdW5zZXQoJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKICAgICAgICBpZiAoJHBsdWdpbiBpbnN0YW5jZW9mIEluc3RhbGxlckludGVyZmFjZSkgewogICAgICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+cmVtb3ZlSW5zdGFsbGVyKCRwbHVnaW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5yZW1vdmVQbHVnaW4oJHBsdWdpbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVW5pbnN0YWxsIGEgcGx1Z2luIHBhY2thZ2UKICAgICAqCiAgICAgKiBJZiBpdCdzIG9mIHR5cGUgY29tcG9zZXItaW5zdGFsbGVyIGl0IGlzIHVucmVnaXN0ZXJlZCBmcm9tIHRoZSBpbnN0YWxsZXJzCiAgICAgKiBpbnN0ZWFkIGZvciBCQwogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGxQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5kaXNhYmxlUGx1Z2lucykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHBsdWdpbiA9ICR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXTsKICAgICAgICBpZiAoJHBsdWdpbiBpbnN0YW5jZW9mIEluc3RhbGxlckludGVyZmFjZSkgewogICAgICAgICAgICAkdGhpcy0+ZGVhY3RpdmF0ZVBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXSk7CiAgICAgICAgICAgICR0aGlzLT5yZW1vdmVQbHVnaW4oJHBsdWdpbik7CiAgICAgICAgICAgICR0aGlzLT51bmluc3RhbGxQbHVnaW4oJHBsdWdpbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdmVyc2lvbiBvZiB0aGUgaW50ZXJuYWwgY29tcG9zZXItcGx1Z2luLWFwaSBwYWNrYWdlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQbHVnaW5BcGlWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gUGx1Z2luSW50ZXJmYWNlOjpQTFVHSU5fQVBJX1ZFUlNJT047CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgcGx1Z2luLCBhY3RpdmF0ZXMgaXQgYW5kIHJlZ2lzdGVycyBpdCB3aXRoIHRoZSBldmVudCBkaXNwYXRjaGVyCiAgICAgKgogICAgICogSWRlYWxseSBwbHVnaW4gcGFja2FnZXMgc2hvdWxkIGJlIHJlZ2lzdGVyZWQgdmlhIHJlZ2lzdGVyUGFja2FnZSwgYnV0IGlmIHlvdSB1c2UgQ29tcG9zZXIKICAgICAqIHByb2dyYW1tYXRpY2FsbHkgYW5kIHdhbnQgdG8gcmVnaXN0ZXIgYSBwbHVnaW4gY2xhc3MgZGlyZWN0bHkgdGhpcyBpcyBhIHZhbGlkIHdheQogICAgICogdG8gZG8gaXQuCiAgICAgKgogICAgICogQHBhcmFtIFBsdWdpbkludGVyZmFjZSAgICRwbHVnaW4gICAgICAgIHBsdWdpbiBpbnN0YW5jZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICRpc0dsb2JhbFBsdWdpbgogICAgICogQHBhcmFtID9QYWNrYWdlSW50ZXJmYWNlICRzb3VyY2VQYWNrYWdlIFBhY2thZ2UgZnJvbSB3aGljaCB0aGUgcGx1Z2luIGNvbWVzIGZyb20KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBsdWdpbihQbHVnaW5JbnRlcmZhY2UgJHBsdWdpbiwgJGlzR2xvYmFsUGx1Z2luID0gZmFsc2UsIFBhY2thZ2VJbnRlcmZhY2UgJHNvdXJjZVBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICgkc291cmNlUGFja2FnZSA9PT0gbnVsbCkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdDYWxsaW5nIFBsdWdpbk1hbmFnZXI6OmFkZFBsdWdpbiB3aXRob3V0ICRzb3VyY2VQYWNrYWdlIGlzIGRlcHJlY2F0ZWQsIGlmIHlvdSBhcmUgdXNpbmcgdGhpcyBwbGVhc2UgZ2V0IGluIHRvdWNoIHdpdGggdXMgdG8gZXhwbGFpbiB0aGUgdXNlIGNhc2UnLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+aXNQbHVnaW5BbGxvd2VkKCRzb3VyY2VQYWNrYWdlLT5nZXROYW1lKCksICRpc0dsb2JhbFBsdWdpbikpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdTa2lwcGVkIGxvYWRpbmcgIicuZ2V0X2NsYXNzKCRwbHVnaW4pLicgZnJvbSAnLiRzb3VyY2VQYWNrYWdlLT5nZXROYW1lKCkgLiAnIiAnLigkaXNHbG9iYWxQbHVnaW4gPyAnKGluc3RhbGxlZCBnbG9iYWxseSkgJyA6ICcnKS4nIGFzIGl0IGlzIG5vdCBpbiBjb25maWcuYWxsb3ctcGx1Z2lucycsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRkZXRhaWxzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJHNvdXJjZVBhY2thZ2UpIHsKICAgICAgICAgICAgJGRldGFpbHNbXSA9ICdmcm9tICcuJHNvdXJjZVBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRpc0dsb2JhbFBsdWdpbikgewogICAgICAgICAgICAkZGV0YWlsc1tdID0gJ2luc3RhbGxlZCBnbG9iYWxseSc7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignTG9hZGluZyBwbHVnaW4gJy5nZXRfY2xhc3MoJHBsdWdpbikuKCRkZXRhaWxzID8gJyAoJy5pbXBsb2RlKCcsICcsICRkZXRhaWxzKS4nKScgOiAnJyksIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgJHRoaXMtPnBsdWdpbnNbXSA9ICRwbHVnaW47CiAgICAgICAgJHBsdWdpbi0+YWN0aXZhdGUoJHRoaXMtPmNvbXBvc2VyLCAkdGhpcy0+aW8pOwoKICAgICAgICBpZiAoJHBsdWdpbiBpbnN0YW5jZW9mIEV2ZW50U3Vic2NyaWJlckludGVyZmFjZSkgewogICAgICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5hZGRTdWJzY3JpYmVyKCRwbHVnaW4pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgYSBwbHVnaW4sIGRlYWN0aXZhdGVzIGl0IGFuZCByZW1vdmVzIGFueSBsaXN0ZW5lciB0aGUgcGx1Z2luIGhhcyBzZXQgb24gdGhlIHBsdWdpbiBpbnN0YW5jZQogICAgICoKICAgICAqIElkZWFsbHkgcGx1Z2luIHBhY2thZ2VzIHNob3VsZCBiZSBkZWFjdGl2YXRlZCB2aWEgZGVhY3RpdmF0ZVBhY2thZ2UsIGJ1dCBpZiB5b3UgdXNlIENvbXBvc2VyCiAgICAgKiBwcm9ncmFtbWF0aWNhbGx5IGFuZCB3YW50IHRvIGRlcmVnaXN0ZXIgYSBwbHVnaW4gY2xhc3MgZGlyZWN0bHkgdGhpcyBpcyBhIHZhbGlkIHdheQogICAgICogdG8gZG8gaXQuCiAgICAgKgogICAgICogQHBhcmFtIFBsdWdpbkludGVyZmFjZSAkcGx1Z2luIHBsdWdpbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUGx1Z2luKFBsdWdpbkludGVyZmFjZSAkcGx1Z2luKQogICAgewogICAgICAgICRpbmRleCA9IGFycmF5X3NlYXJjaCgkcGx1Z2luLCAkdGhpcy0+cGx1Z2lucywgdHJ1ZSk7CiAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdVbmxvYWRpbmcgcGx1Z2luICcuZ2V0X2NsYXNzKCRwbHVnaW4pLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgIHVuc2V0KCR0aGlzLT5wbHVnaW5zWyRpbmRleF0pOwogICAgICAgICRwbHVnaW4tPmRlYWN0aXZhdGUoJHRoaXMtPmNvbXBvc2VyLCAkdGhpcy0+aW8pOwoKICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5yZW1vdmVMaXN0ZW5lcigkcGx1Z2luKTsKICAgIH0KCiAgICAvKioKICAgICAqIE5vdGlmaWVzIGEgcGx1Z2luIGl0IGlzIGJlaW5nIHVuaW5zdGFsbGVkIGFuZCBzaG91bGQgY2xlYW4gdXAKICAgICAqCiAgICAgKiBJZGVhbGx5IHBsdWdpbiBwYWNrYWdlcyBzaG91bGQgYmUgdW5pbnN0YWxsZWQgdmlhIHVuaW5zdGFsbFBhY2thZ2UsIGJ1dCBpZiB5b3UgdXNlIENvbXBvc2VyCiAgICAgKiBwcm9ncmFtbWF0aWNhbGx5IGFuZCB3YW50IHRvIGRlcmVnaXN0ZXIgYSBwbHVnaW4gY2xhc3MgZGlyZWN0bHkgdGhpcyBpcyBhIHZhbGlkIHdheQogICAgICogdG8gZG8gaXQuCiAgICAgKgogICAgICogQHBhcmFtIFBsdWdpbkludGVyZmFjZSAkcGx1Z2luIHBsdWdpbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsUGx1Z2luKFBsdWdpbkludGVyZmFjZSAkcGx1Z2luKQogICAgewogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignVW5pbnN0YWxsaW5nIHBsdWdpbiAnLmdldF9jbGFzcygkcGx1Z2luKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAkcGx1Z2luLT51bmluc3RhbGwoJHRoaXMtPmNvbXBvc2VyLCAkdGhpcy0+aW8pOwogICAgfQoKICAgIC8qKgogICAgICogTG9hZCBhbGwgcGx1Z2lucyBhbmQgaW5zdGFsbGVycyBmcm9tIGEgcmVwb3NpdG9yeQogICAgICoKICAgICAqIElmIGEgcGx1Z2luIHJlcXVpcmVzIGFub3RoZXIgcGx1Z2luLCB0aGUgcmVxdWlyZWQgb25lIHdpbGwgYmUgbG9hZGVkIGZpcnN0CiAgICAgKgogICAgICogTm90ZSB0aGF0IHBsdWdpbnMgaW4gdGhlIHNwZWNpZmllZCByZXBvc2l0b3J5IHRoYXQgcmVseSBvbiBldmVudHMgdGhhdAogICAgICogaGF2ZSBmaXJlZCBwcmlvciB0byBsb2FkaW5nIHdpbGwgYmUgbWlzc2VkLiBUaGlzIG1lYW5zIHlvdSBsaWtlbHkgd2FudCB0bwogICAgICogY2FsbCB0aGlzIG1ldGhvZCBhcyBlYXJseSBhcyBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyBSZXBvc2l0b3J5IHRvIHNjYW4gZm9yIHBsdWdpbnMgdG8gaW5zdGFsbAogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgJGlzR2xvYmFsUmVwbwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkUmVwb3NpdG9yeShSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCAkaXNHbG9iYWxSZXBvKQogICAgewogICAgICAgICRwYWNrYWdlcyA9ICRyZXBvLT5nZXRQYWNrYWdlcygpOwogICAgICAgICRzb3J0ZWRQYWNrYWdlcyA9IFBhY2thZ2VTb3J0ZXI6OnNvcnRQYWNrYWdlcygkcGFja2FnZXMpOwogICAgICAgIGZvcmVhY2ggKCRzb3J0ZWRQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoISgkcGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgnY29tcG9zZXItcGx1Z2luJyA9PT0gJHBhY2thZ2UtPmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlZ2lzdGVyUGFja2FnZSgkcGFja2FnZSwgZmFsc2UsICRpc0dsb2JhbFJlcG8pOwogICAgICAgICAgICAvLyBCYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgIH0gZWxzZWlmICgnY29tcG9zZXItaW5zdGFsbGVyJyA9PT0gJHBhY2thZ2UtPmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlZ2lzdGVyUGFja2FnZSgkcGFja2FnZSwgZmFsc2UsICRpc0dsb2JhbFJlcG8pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRGVhY3RpdmF0ZSBhbGwgcGx1Z2lucyBhbmQgaW5zdGFsbGVycyBmcm9tIGEgcmVwb3NpdG9yeQogICAgICoKICAgICAqIElmIGEgcGx1Z2luIHJlcXVpcmVzIGFub3RoZXIgcGx1Z2luLCB0aGUgcmVxdWlyZWQgb25lIHdpbGwgYmUgZGVhY3RpdmF0ZWQgbGFzdAogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvIFJlcG9zaXRvcnkgdG8gc2NhbiBmb3IgcGx1Z2lucyB0byBpbnN0YWxsCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAkaXNHbG9iYWxSZXBvCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZGVhY3RpdmF0ZVJlcG9zaXRvcnkoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgJGlzR2xvYmFsUmVwbykKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSAkcmVwby0+Z2V0UGFja2FnZXMoKTsKICAgICAgICAkc29ydGVkUGFja2FnZXMgPSBhcnJheV9yZXZlcnNlKFBhY2thZ2VTb3J0ZXI6OnNvcnRQYWNrYWdlcygkcGFja2FnZXMpKTsKCiAgICAgICAgZm9yZWFjaCAoJHNvcnRlZFBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCdjb21wb3Nlci1wbHVnaW4nID09PSAkcGFja2FnZS0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVhY3RpdmF0ZVBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICAvLyBCYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgIH0gZWxzZWlmICgnY29tcG9zZXItaW5zdGFsbGVyJyA9PT0gJHBhY2thZ2UtPmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRlYWN0aXZhdGVQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlY3Vyc2l2ZWx5IGdlbmVyYXRlcyBhIG1hcCBvZiBwYWNrYWdlIG5hbWVzIHRvIHBhY2thZ2VzIGZvciBhbGwgZGVwcwogICAgICoKICAgICAqIEBwYXJhbSBJbnN0YWxsZWRSZXBvc2l0b3J5ICAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvIFNldCBvZiBsb2NhbCByZXBvcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgUGFja2FnZUludGVyZmFjZT4gJGNvbGxlY3RlZCAgICAgQ3VycmVudCBzdGF0ZSBvZiB0aGUgbWFwIGZvciByZWN1cnNpb24KICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICAgICAgICAgICAgICAgICRwYWNrYWdlICAgICAgIFRoZSBwYWNrYWdlIHRvIGFuYWx5emUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgUGFja2FnZUludGVyZmFjZT4gTWFwIG9mIHBhY2thZ2UgbmFtZXMgdG8gcGFja2FnZXMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjb2xsZWN0RGVwZW5kZW5jaWVzKEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8sIGFycmF5ICRjb2xsZWN0ZWQsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJHJlcXVpcmVMaW5rKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsZWRSZXBvLT5maW5kUGFja2FnZXNXaXRoUmVwbGFjZXJzQW5kUHJvdmlkZXJzKCRyZXF1aXJlTGluay0+Z2V0VGFyZ2V0KCkpIGFzICRyZXF1aXJlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbGxlY3RlZFskcmVxdWlyZWRQYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICAgICAgICAgICRjb2xsZWN0ZWRbJHJlcXVpcmVkUGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRyZXF1aXJlZFBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgJGNvbGxlY3RlZCA9ICR0aGlzLT5jb2xsZWN0RGVwZW5kZW5jaWVzKCRpbnN0YWxsZWRSZXBvLCAkY29sbGVjdGVkLCAkcmVxdWlyZWRQYWNrYWdlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb2xsZWN0ZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIHBhdGggYSBwYWNrYWdlIGlzIGluc3RhbGxlZCB0by4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgJGdsb2JhbCAgV2hldGhlciB0aGlzIGlzIGEgZ2xvYmFsIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBJbnN0YWxsIHBhdGgKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbnN0YWxsUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZ2xvYmFsID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkZ2xvYmFsKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5nbG9iYWxDb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIFBsdWdpbkludGVyZmFjZSAgICRwbHVnaW4KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGNhcGFiaWxpdHkKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gT24gZW1wdHkgb3Igbm9uLXN0cmluZyBpbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lIHZhbHVlCiAgICAgKiBAcmV0dXJuIG51bGx8c3RyaW5nICAgICAgIFRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3Mgb2YgdGhlIGltcGxlbWVudGF0aW9uIG9yIG51bGwgaWYgUGx1Z2luIGlzIG5vdCBvZiBDYXBhYmxlIHR5cGUgb3IgZG9lcyBub3QgcHJvdmlkZSBpdAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q2FwYWJpbGl0eUltcGxlbWVudGF0aW9uQ2xhc3NOYW1lKFBsdWdpbkludGVyZmFjZSAkcGx1Z2luLCAkY2FwYWJpbGl0eSkKICAgIHsKICAgICAgICBpZiAoISgkcGx1Z2luIGluc3RhbmNlb2YgQ2FwYWJsZSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkY2FwYWJpbGl0aWVzID0gKGFycmF5KSAkcGx1Z2luLT5nZXRDYXBhYmlsaXRpZXMoKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkY2FwYWJpbGl0aWVzWyRjYXBhYmlsaXR5XSkgJiYgaXNfc3RyaW5nKCRjYXBhYmlsaXRpZXNbJGNhcGFiaWxpdHldKSAmJiB0cmltKCRjYXBhYmlsaXRpZXNbJGNhcGFiaWxpdHldKSkgewogICAgICAgICAgICByZXR1cm4gdHJpbSgkY2FwYWJpbGl0aWVzWyRjYXBhYmlsaXR5XSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoCiAgICAgICAgICAgIGFycmF5X2tleV9leGlzdHMoJGNhcGFiaWxpdHksICRjYXBhYmlsaXRpZXMpCiAgICAgICAgICAgICYmIChlbXB0eSgkY2FwYWJpbGl0aWVzWyRjYXBhYmlsaXR5XSkgfHwgIWlzX3N0cmluZygkY2FwYWJpbGl0aWVzWyRjYXBhYmlsaXR5XSkgfHwgIXRyaW0oJGNhcGFiaWxpdGllc1skY2FwYWJpbGl0eV0pKQogICAgICAgICkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignUGx1Z2luICcuZ2V0X2NsYXNzKCRwbHVnaW4pLicgcHJvdmlkZWQgaW52YWxpZCBjYXBhYmlsaXR5IGNsYXNzIG5hbWUocyksIGdvdCAnLnZhcl9leHBvcnQoJGNhcGFiaWxpdGllc1skY2FwYWJpbGl0eV0sIHRydWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHRlbXBsYXRlIENhcGFiaWxpdHlDbGFzcyBvZiBDYXBhYmlsaXR5CiAgICAgKiBAcGFyYW0gIFBsdWdpbkludGVyZmFjZSAgICAgICAgICAgICAgICRwbHVnaW4KICAgICAqIEBwYXJhbSAgY2xhc3Mtc3RyaW5nPENhcGFiaWxpdHlDbGFzcz4gJGNhcGFiaWxpdHlDbGFzc05hbWUgVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBBUEkgaW50ZXJmYWNlIHdoaWNoIHRoZSBwbHVnaW4gbWF5IHByb3ZpZGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gaW1wbGVtZW50YXRpb24gb2YuCiAgICAgKiBAcGFyYW0gIGFycmF5PG1peGVkPiAgICAgICAgICAgICAgICAgICRjdG9yQXJncyAgICAgICAgICAgIEFyZ3VtZW50cyBwYXNzZWQgdG8gQ2FwYWJpbGl0eSdzIGNvbnN0cnVjdG9yLgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZWVwaW5nIGl0IGFuIGFycmF5IHdpbGwgYWxsb3cgZnV0dXJlIHZhbHVlcyB0byBiZSBwYXNzZWQgd1xvIGNoYW5naW5nIHRoZSBzaWduYXR1cmUuCiAgICAgKiBAcmV0dXJuIG51bGx8Q2FwYWJpbGl0eQogICAgICogQHBocHN0YW4tcGFyYW0gY2xhc3Mtc3RyaW5nPENhcGFiaWxpdHlDbGFzcz4gJGNhcGFiaWxpdHlDbGFzc05hbWUKICAgICAqIEBwaHBzdGFuLXJldHVybiBudWxsfENhcGFiaWxpdHlDbGFzcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGx1Z2luQ2FwYWJpbGl0eShQbHVnaW5JbnRlcmZhY2UgJHBsdWdpbiwgJGNhcGFiaWxpdHlDbGFzc05hbWUsIGFycmF5ICRjdG9yQXJncyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKCRjYXBhYmlsaXR5Q2xhc3MgPSAkdGhpcy0+Z2V0Q2FwYWJpbGl0eUltcGxlbWVudGF0aW9uQ2xhc3NOYW1lKCRwbHVnaW4sICRjYXBhYmlsaXR5Q2xhc3NOYW1lKSkgewogICAgICAgICAgICBpZiAoIWNsYXNzX2V4aXN0cygkY2FwYWJpbGl0eUNsYXNzKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJDYW5ub3QgaW5zdGFudGlhdGUgQ2FwYWJpbGl0eSwgYXMgY2xhc3MgJGNhcGFiaWxpdHlDbGFzcyBmcm9tIHBsdWdpbiAiLmdldF9jbGFzcygkcGx1Z2luKS4iIGRvZXMgbm90IGV4aXN0LiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY3RvckFyZ3NbJ3BsdWdpbiddID0gJHBsdWdpbjsKICAgICAgICAgICAgJGNhcGFiaWxpdHlPYmogPSBuZXcgJGNhcGFiaWxpdHlDbGFzcygkY3RvckFyZ3MpOwoKICAgICAgICAgICAgLy8gRklYTUUgdGhlc2UgY291bGQgdXNlIGlzX2EgYW5kIGRvIHRoZSBjaGVjayAqYmVmb3JlKiBpbnN0YW50aWF0aW5nIG9uY2UgZHJvcCBzdXBwb3J0IGZvciBwaHA8NS4zLjkKICAgICAgICAgICAgaWYgKCEkY2FwYWJpbGl0eU9iaiBpbnN0YW5jZW9mIENhcGFiaWxpdHkgfHwgISRjYXBhYmlsaXR5T2JqIGluc3RhbmNlb2YgJGNhcGFiaWxpdHlDbGFzc05hbWUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAnQ2xhc3MgJyAuICRjYXBhYmlsaXR5Q2xhc3MgLiAnIG11c3QgaW1wbGVtZW50IGJvdGggQ29tcG9zZXJcUGx1Z2luXENhcGFiaWxpdHlcQ2FwYWJpbGl0eSBhbmQgJy4gJGNhcGFiaWxpdHlDbGFzc05hbWUgLiAnLicKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkY2FwYWJpbGl0eU9iajsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHRlbXBsYXRlIENhcGFiaWxpdHlDbGFzcyBvZiBDYXBhYmlsaXR5CiAgICAgKiBAcGFyYW0gIGNsYXNzLXN0cmluZzxDYXBhYmlsaXR5Q2xhc3M+ICRjYXBhYmlsaXR5Q2xhc3NOYW1lIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgQVBJIGludGVyZmFjZSB3aGljaCB0aGUgcGx1Z2luIG1heSBwcm92aWRlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuIGltcGxlbWVudGF0aW9uIG9mLgogICAgICogQHBhcmFtICBhcnJheTxtaXhlZD4gICAgICAgICAgICAgICAgICAkY3RvckFyZ3MgICAgICAgICAgICBBcmd1bWVudHMgcGFzc2VkIHRvIENhcGFiaWxpdHkncyBjb25zdHJ1Y3Rvci4KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2VlcGluZyBpdCBhbiBhcnJheSB3aWxsIGFsbG93IGZ1dHVyZSB2YWx1ZXMgdG8gYmUgcGFzc2VkIHdcbyBjaGFuZ2luZyB0aGUgc2lnbmF0dXJlLgogICAgICogQHJldHVybiBDYXBhYmlsaXR5Q2xhc3NbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGx1Z2luQ2FwYWJpbGl0aWVzKCRjYXBhYmlsaXR5Q2xhc3NOYW1lLCBhcnJheSAkY3RvckFyZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgICRjYXBhYmlsaXRpZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQbHVnaW5zKCkgYXMgJHBsdWdpbikgewogICAgICAgICAgICBpZiAoJGNhcGFiaWxpdHkgPSAkdGhpcy0+Z2V0UGx1Z2luQ2FwYWJpbGl0eSgkcGx1Z2luLCAkY2FwYWJpbGl0eUNsYXNzTmFtZSwgJGN0b3JBcmdzKSkgewogICAgICAgICAgICAgICAgJGNhcGFiaWxpdGllc1tdID0gJGNhcGFiaWxpdHk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2FwYWJpbGl0aWVzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBhcnJheTxzdHJpbmcsIGJvb2w+fGJvb2x8bnVsbCAkYWxsb3dQbHVnaW5zQ29uZmlnCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgYm9vbD58bnVsbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnNlQWxsb3dlZFBsdWdpbnMoJGFsbG93UGx1Z2luc0NvbmZpZykKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGFsbG93UGx1Z2luc0NvbmZpZykgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICh0cnVlID09PSAkYWxsb3dQbHVnaW5zQ29uZmlnKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgne30nID0+IHRydWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlID09PSAkYWxsb3dQbHVnaW5zQ29uZmlnKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgne14kfUQnID0+IGZhbHNlKTsKICAgICAgICB9CgogICAgICAgICRydWxlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGFsbG93UGx1Z2luc0NvbmZpZyBhcyAkcGF0dGVybiA9PiAkYWxsb3cpIHsKICAgICAgICAgICAgJHJ1bGVzW0Jhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCRwYXR0ZXJuKV0gPSAkYWxsb3c7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJ1bGVzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGFja2FnZQogICAgICogQHBhcmFtIGJvb2wgJGlzR2xvYmFsUGx1Z2luCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1BsdWdpbkFsbG93ZWQoJHBhY2thZ2UsICRpc0dsb2JhbFBsdWdpbikKICAgIHsKICAgICAgICBzdGF0aWMgJHdhcm5lZCA9IGFycmF5KCk7CiAgICAgICAgJHJ1bGVzID0gJGlzR2xvYmFsUGx1Z2luID8gJHRoaXMtPmFsbG93R2xvYmFsUGx1Z2luUnVsZXMgOiAkdGhpcy0+YWxsb3dQbHVnaW5SdWxlczsKCiAgICAgICAgaWYgKCRydWxlcyA9PT0gbnVsbCkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR3YXJuZWRbJ2FsbCddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Rm9yIGFkZGl0aW9uYWwgc2VjdXJpdHkgeW91IHNob3VsZCBkZWNsYXJlIHRoZSBhbGxvdy1wbHVnaW5zIGNvbmZpZyB3aXRoIGEgbGlzdCBvZiBwYWNrYWdlcyBuYW1lcyB0aGF0IGFyZSBhbGxvd2VkIHRvIHJ1biBjb2RlLiBTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvYWxsb3ctcGx1Z2luczwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBoYXZlIHVudGlsIEp1bHkgMjAyMiB0byBhZGQgdGhlIHNldHRpbmcuIENvbXBvc2VyIHdpbGwgdGhlbiBzd2l0Y2ggdGhlIGRlZmF1bHQgYmVoYXZpb3IgdG8gZGlzYWxsb3cgYWxsIHBsdWdpbnMuPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICR3YXJuZWRbJ2FsbCddID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBubyBjb25maWcgaXMgZGVmaW5lZCB3ZSBhbGxvdyBhbGwgcGx1Z2lucyBmb3IgQkMKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBrZWVwIGdvaW5nIGFuZCBwcm9tcHQgdGhlIHVzZXIKICAgICAgICAgICAgJHJ1bGVzID0gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRydWxlcyBhcyAkcGF0dGVybiA9PiAkYWxsb3cpIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJHBhdHRlcm4sICRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRhbGxvdyA9PT0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlID09PSAnY29tcG9zZXIvcGFja2FnZS12ZXJzaW9ucy1kZXByZWNhdGVkJykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR3YXJuZWRbJHBhY2thZ2VdKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9ICRpc0dsb2JhbFBsdWdpbiAmJiAkdGhpcy0+Z2xvYmFsQ29tcG9zZXIgIT09IG51bGwgPyAkdGhpcy0+Z2xvYmFsQ29tcG9zZXIgOiAkdGhpcy0+Y29tcG9zZXI7CgogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nLiRwYWNrYWdlLigkaXNHbG9iYWxQbHVnaW4gPyAnIChpbnN0YWxsZWQgZ2xvYmFsbHkpJyA6ICcnKS4nIGNvbnRhaW5zIGEgQ29tcG9zZXIgcGx1Z2luIHdoaWNoIGlzIGN1cnJlbnRseSBub3QgaW4geW91ciBhbGxvdy1wbHVnaW5zIGNvbmZpZy4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2FsbG93LXBsdWdpbnM8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJGFuc3dlciA9ICR0aGlzLT5pby0+YXNrKCdEbyB5b3UgdHJ1c3QgIjxpbmZvPicuJHBhY2thZ2UuJzwvaW5mbz4iIHRvIGV4ZWN1dGUgY29kZSBhbmQgd2lzaCB0byBlbmFibGUgaXQgbm93PyAod3JpdGVzICJhbGxvdy1wbHVnaW5zIiB0byBjb21wb3Nlci5qc29uKSBbPGNvbW1lbnQ+eSxuLGQsPzwvY29tbWVudD5dICcsICc/JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAneSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ24nOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRhbGxvdyA9ICRhbnN3ZXIgPT09ICd5JzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwZXJzaXN0IGFuc3dlciBpbiBjdXJyZW50IHJ1bGVzIHRvIGF2b2lkIHByb21wdGluZyBhZ2FpbiBpZiB0aGUgcGFja2FnZSBnZXRzIHJlbG9hZGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlzR2xvYmFsUGx1Z2luKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFsbG93R2xvYmFsUGx1Z2luUnVsZXNbQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lVG9SZWdleHAoJHBhY2thZ2UpXSA9ICRhbGxvdzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFsbG93UGx1Z2luUnVsZXNbQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lVG9SZWdleHAoJHBhY2thZ2UpXSA9ICRhbGxvdzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwZXJzaXN0IGFuc3dlciBpbiBjb21wb3Nlci5qc29uIGlmIGl0IHdhc24ndCBzaW1wbHkgZGlzY2FyZGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGFuc3dlciA9PT0gJ3knIHx8ICRhbnN3ZXIgPT09ICduJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldENvbmZpZ1NvdXJjZSgpLT5hZGRDb25maWdTZXR0aW5nKCdhbGxvdy1wbHVnaW5zLicuJHBhY2thZ2UsICRhbGxvdyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRhbGxvdzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJz8nOgogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd5IC0gYWRkIHBhY2thZ2UgdG8gYWxsb3ctcGx1Z2lucyBpbiBjb21wb3Nlci5qc29uIGFuZCBsZXQgaXQgcnVuIGltbWVkaWF0ZWx5JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbiAtIGFkZCBwYWNrYWdlIChhcyBkaXNhbGxvd2VkKSB0byBhbGxvdy1wbHVnaW5zIGluIGNvbXBvc2VyLmpzb24gdG8gc3VwcHJlc3MgZnVydGhlciBwcm9tcHRzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZCAtIGRpc2NhcmQgdGhpcywgZG8gbm90IGNoYW5nZSBjb21wb3Nlci5qc29uIGFuZCBkbyBub3QgYWxsb3cgdGhlIHBsdWdpbiB0byBydW4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc/IC0gcHJpbnQgaGVscCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nLiRwYWNrYWdlLigkaXNHbG9iYWxQbHVnaW4gPyAnIChpbnN0YWxsZWQgZ2xvYmFsbHkpJyA6ICcnKS4nIGNvbnRhaW5zIGEgQ29tcG9zZXIgcGx1Z2luIHdoaWNoIGlzIGJsb2NrZWQgYnkgeW91ciBhbGxvdy1wbHVnaW5zIGNvbmZpZy4gWW91IG1heSBhZGQgaXQgdG8gdGhlIGxpc3QgaWYgeW91IGNvbnNpZGVyIGl0IHNhZmUuIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9hbGxvdy1wbHVnaW5zPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgY2FuIHJ1biAiY29tcG9zZXIgJy4oJGlzR2xvYmFsUGx1Z2luID8gJ2dsb2JhbCAnIDogJycpLidjb25maWcgLS1uby1wbHVnaW5zIGFsbG93LXBsdWdpbnMuJy4kcGFja2FnZS4nIFt0cnVlfGZhbHNlXSIgdG8gZW5hYmxlIGl0ICh0cnVlKSBvciBrZWVwIGl0IGRpc2FibGVkIGFuZCBzdXBwcmVzcyB0aGlzIHdhcm5pbmcgKGZhbHNlKTwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkd2FybmVkWyRwYWNrYWdlXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luOwoKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CgovKioKICogVGhlIHByZSBjb21tYW5kIHJ1biBldmVudC4KICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUHJlQ29tbWFuZFJ1bkV2ZW50IGV4dGVuZHMgRXZlbnQKewogICAgLyoqCiAgICAgKiBAdmFyIElucHV0SW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJGlucHV0OwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkY29tbWFuZDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAkbmFtZSAgICBUaGUgZXZlbnQgbmFtZQogICAgICogQHBhcmFtIElucHV0SW50ZXJmYWNlICRpbnB1dAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICRjb21tYW5kIFRoZSBjb21tYW5kIGFib3V0IHRvIGJlIGV4ZWN1dGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgSW5wdXRJbnRlcmZhY2UgJGlucHV0LCAkY29tbWFuZCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRuYW1lKTsKICAgICAgICAkdGhpcy0+aW5wdXQgPSAkaW5wdXQ7CiAgICAgICAgJHRoaXMtPmNvbW1hbmQgPSAkY29tbWFuZDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnNvbGUgaW5wdXQKICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0SW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1hbmQgYWJvdXQgdG8gYmUgZXhlY3V0ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21tYW5kOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2Ugc3RkQ2xhc3M7CgovKioKICogVGVzdHMgVVJMcyBhZ2FpbnN0IE5PX1BST1hZIHBhdHRlcm5zCiAqLwpjbGFzcyBOb1Byb3h5UGF0dGVybgp7CiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqLwogICAgcHJvdGVjdGVkICRob3N0TmFtZXMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciAobnVsbHxvYmplY3QpW10KICAgICAqLwogICAgcHJvdGVjdGVkICRydWxlcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRub3Byb3h5OwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiBOT19QUk9YWSBwYXR0ZXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcGF0dGVybikKICAgIHsKICAgICAgICAkdGhpcy0+aG9zdE5hbWVzID0gUHJlZzo6c3BsaXQoJ3tbXHMsXSt9JywgJHBhdHRlcm4sIC0xLCBQUkVHX1NQTElUX05PX0VNUFRZKTsKICAgICAgICAkdGhpcy0+bm9wcm94eSA9IGVtcHR5KCR0aGlzLT5ob3N0TmFtZXMpIHx8ICcqJyA9PT0gJHRoaXMtPmhvc3ROYW1lc1swXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhIFVSTCBtYXRjaGVzIHRoZSBOT19QUk9YWSBwYXR0ZXJuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0ZXN0KCR1cmwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5ub3Byb3h5KSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdXJsRGF0YSA9ICR0aGlzLT5nZXRVcmxEYXRhKCR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ob3N0TmFtZXMgYXMgJGluZGV4ID0+ICRob3N0TmFtZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPm1hdGNoKCRpbmRleCwgJGhvc3ROYW1lLCAkdXJsRGF0YSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGZhbHNlIGlzIHRoZSB1cmwgY2Fubm90IGJlIHBhcnNlZCwgb3RoZXJ3aXNlIGEgZGF0YSBvYmplY3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RkQ2xhc3MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFVybERhdGEoJHVybCkKICAgIHsKICAgICAgICBpZiAoISRob3N0ID0gcGFyc2VfdXJsKCR1cmwsIFBIUF9VUkxfSE9TVCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHBvcnQgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9QT1JUKTsKCiAgICAgICAgaWYgKGVtcHR5KCRwb3J0KSkgewogICAgICAgICAgICBzd2l0Y2ggKHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1NDSEVNRSkpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ2h0dHAnOgogICAgICAgICAgICAgICAgICAgICRwb3J0ID0gODA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdodHRwcyc6CiAgICAgICAgICAgICAgICAgICAgJHBvcnQgPSA0NDM7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRob3N0TmFtZSA9ICRob3N0IC4gKCRwb3J0ID8gJzonIC4gJHBvcnQgOiAnJyk7CiAgICAgICAgbGlzdCgkaG9zdCwgJHBvcnQsICRlcnIpID0gJHRoaXMtPnNwbGl0SG9zdFBvcnQoJGhvc3ROYW1lKTsKCiAgICAgICAgaWYgKCRlcnIgfHwgISR0aGlzLT5pcENoZWNrRGF0YSgkaG9zdCwgJGlwZGF0YSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5tYWtlRGF0YSgkaG9zdCwgJHBvcnQsICRpcGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB1cmwgaXMgbWF0Y2hlZCBieSBhIHJ1bGUKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGluZGV4CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJGhvc3ROYW1lCiAgICAgKiBAcGFyYW0gc3RkQ2xhc3MgJHVybAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gbWF0Y2goJGluZGV4LCAkaG9zdE5hbWUsICR1cmwpCiAgICB7CiAgICAgICAgaWYgKCEkcnVsZSA9ICR0aGlzLT5nZXRSdWxlKCRpbmRleCwgJGhvc3ROYW1lKSkgewogICAgICAgICAgICAvLyBEYXRhIG11c3QgaGF2ZSBiZWVuIG1pc2Zvcm1hdHRlZAogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJ1bGUtPmlwZGF0YSkgewogICAgICAgICAgICAvLyBNYXRjaCBpcGRhdGEgZmlyc3QKICAgICAgICAgICAgaWYgKCEkdXJsLT5pcGRhdGEpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRydWxlLT5pcGRhdGEtPm5ldG1hc2spIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bWF0Y2hSYW5nZSgkcnVsZS0+aXBkYXRhLCAkdXJsLT5pcGRhdGEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWF0Y2ggPSAkcnVsZS0+aXBkYXRhLT5pcCA9PT0gJHVybC0+aXBkYXRhLT5pcDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBNYXRjaCBob3N0IGFuZCBwb3J0CiAgICAgICAgICAgICRoYXlzdGFjayA9IHN1YnN0cigkdXJsLT5uYW1lLCAtc3RybGVuKCRydWxlLT5uYW1lKSk7CiAgICAgICAgICAgICRtYXRjaCA9IHN0cmlwb3MoJGhheXN0YWNrLCAkcnVsZS0+bmFtZSkgPT09IDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1hdGNoICYmICRydWxlLT5wb3J0KSB7CiAgICAgICAgICAgICRtYXRjaCA9ICRydWxlLT5wb3J0ID09PSAkdXJsLT5wb3J0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtYXRjaDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFyZ2V0IGlwIGlzIGluIHRoZSBuZXR3b3JrIHJhbmdlCiAgICAgKgogICAgICogQHBhcmFtIHN0ZENsYXNzICRuZXR3b3JrCiAgICAgKiBAcGFyYW0gc3RkQ2xhc3MgJHRhcmdldAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gbWF0Y2hSYW5nZShzdGRDbGFzcyAkbmV0d29yaywgc3RkQ2xhc3MgJHRhcmdldCkKICAgIHsKICAgICAgICAkbmV0ID0gdW5wYWNrKCdDKicsICRuZXR3b3JrLT5pcCk7CiAgICAgICAgJG1hc2sgPSB1bnBhY2soJ0MqJywgJG5ldHdvcmstPm5ldG1hc2spOwogICAgICAgICRpcCA9IHVucGFjaygnQyonLCAkdGFyZ2V0LT5pcCk7CiAgICAgICAgaWYgKGZhbHNlID09PSAkbmV0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHBhcnNlIG5ldHdvcmsgSVAgJy4kbmV0d29yay0+aXApOwogICAgICAgIH0KICAgICAgICBpZiAoZmFsc2UgPT09ICRtYXNrKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHBhcnNlIG5ldG1hc2sgJy4kbmV0d29yay0+bmV0bWFzayk7CiAgICAgICAgfQogICAgICAgIGlmIChmYWxzZSA9PT0gJGlwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHBhcnNlIHRhcmdldCBJUCAnLiR0YXJnZXQtPmlwKTsKICAgICAgICB9CgogICAgICAgIGZvciAoJGkgPSAxOyAkaSA8IDE3OyArKyRpKSB7CiAgICAgICAgICAgIGlmICgoJG5ldFskaV0gJiAkbWFza1skaV0pICE9PSAoJGlwWyRpXSAmICRtYXNrWyRpXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kcyBvciBjcmVhdGVzIHJ1bGUgZGF0YSBmb3IgYSBob3N0bmFtZQogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICAgJGluZGV4CiAgICAgKiBAcGFyYW0gc3RyaW5nICRob3N0TmFtZQogICAgICoKICAgICAqIEByZXR1cm4gbnVsbHxzdGRDbGFzcyBOdWxsIGlmIHRoZSBob3N0bmFtZSBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UnVsZSgkaW5kZXgsICRob3N0TmFtZSkKICAgIHsKICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygkaW5kZXgsICR0aGlzLT5ydWxlcykpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlc1skaW5kZXhdOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJ1bGVzWyRpbmRleF0gPSBudWxsOwogICAgICAgIGxpc3QoJGhvc3QsICRwb3J0LCAkZXJyKSA9ICR0aGlzLT5zcGxpdEhvc3RQb3J0KCRob3N0TmFtZSk7CgogICAgICAgIGlmICgkZXJyIHx8ICEkdGhpcy0+aXBDaGVja0RhdGEoJGhvc3QsICRpcGRhdGEsIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJ1bGVzWyRpbmRleF0gPSAkdGhpcy0+bWFrZURhdGEoJGhvc3QsICRwb3J0LCAkaXBkYXRhKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlc1skaW5kZXhdOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29udGFpbmluZyBJUCBkYXRhIGlmIHRoZSBob3N0IGlzIGFuIElQIGFkZHJlc3MKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAkaG9zdAogICAgICogQHBhcmFtIG51bGx8c3RkQ2xhc3MgJGlwZGF0YSAgICAgIFNldCBieSBtZXRob2QgaWYgSVAgYWRkcmVzcyBmb3VuZAogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgJGFsbG93UHJlZml4IFdoZXRoZXIgYSBDSURSIHByZWZpeC1sZW5ndGggaXMgZXhwZWN0ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgRmFsc2UgaWYgdGhlIGhvc3QgY29udGFpbnMgaW52YWxpZCBkYXRhCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaXBDaGVja0RhdGEoJGhvc3QsICYkaXBkYXRhLCAkYWxsb3dQcmVmaXggPSBmYWxzZSkKICAgIHsKICAgICAgICAkaXBkYXRhID0gbnVsbDsKICAgICAgICAkbmV0bWFzayA9IG51bGw7CiAgICAgICAgJHByZWZpeCA9IG51bGw7CiAgICAgICAgJG1vZGlmaWVkID0gZmFsc2U7CgogICAgICAgIC8vIENoZWNrIGZvciBhIENJRFIgcHJlZml4LWxlbmd0aAogICAgICAgIGlmIChzdHJwb3MoJGhvc3QsICcvJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgIGxpc3QoJGhvc3QsICRwcmVmaXgpID0gZXhwbG9kZSgnLycsICRob3N0KTsKCiAgICAgICAgICAgIGlmICghJGFsbG93UHJlZml4IHx8ICEkdGhpcy0+dmFsaWRhdGVJbnQoJHByZWZpeCwgMCwgMTI4KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwcmVmaXggPSAoaW50KSAkcHJlZml4OwogICAgICAgICAgICAkbW9kaWZpZWQgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gU2VlIGlmIHRoaXMgaXMgYW4gaXAgYWRkcmVzcwogICAgICAgIGlmICghZmlsdGVyX3ZhcigkaG9zdCwgRklMVEVSX1ZBTElEQVRFX0lQKSkgewogICAgICAgICAgICByZXR1cm4gISRtb2RpZmllZDsKICAgICAgICB9CgogICAgICAgIGxpc3QoJGlwLCAkc2l6ZSkgPSAkdGhpcy0+aXBHZXRBZGRyKCRob3N0KTsKCiAgICAgICAgaWYgKCRwcmVmaXggIT09IG51bGwpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGEgdmFsaWQgcHJlZml4CiAgICAgICAgICAgIGlmICgkcHJlZml4ID4gJHNpemUgKiA4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxpc3QoJGlwLCAkbmV0bWFzaykgPSAkdGhpcy0+aXBHZXROZXR3b3JrKCRpcCwgJHNpemUsICRwcmVmaXgpOwogICAgICAgIH0KCiAgICAgICAgJGlwZGF0YSA9ICR0aGlzLT5tYWtlSXBEYXRhKCRpcCwgJHNpemUsICRuZXRtYXNrKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHRoZSBJUCBpbl9hZGRyIGFuZCBpdHMgYnl0ZSBzaXplCiAgICAgKgogICAgICogSVB2NCBhZGRyZXNzZXMgYXJlIGFsd2F5cyBtYXBwZWQgdG8gSVB2Niwgd2hpY2ggc2ltcGxpZmllcyBoYW5kbGluZwogICAgICogYW5kIGNvbXBhcmlzb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaG9zdAogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWRbXSBpbl9hZGRyLCBzaXplCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaXBHZXRBZGRyKCRob3N0KQogICAgewogICAgICAgICRpcCA9IGluZXRfcHRvbigkaG9zdCk7CiAgICAgICAgJHNpemUgPSBzdHJsZW4oJGlwKTsKICAgICAgICAkbWFwcGVkID0gJHRoaXMtPmlwTWFwVG82KCRpcCwgJHNpemUpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJG1hcHBlZCwgJHNpemUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYmluYXJ5IG5ldHdvcmsgbWFzayBtYXBwZWQgdG8gSVB2NgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJHByZWZpeCBDSURSIHByZWZpeC1sZW5ndGgKICAgICAqIEBwYXJhbSBpbnQgJHNpemUgICBCeXRlIHNpemUgb2YgaW5fYWRkcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaXBHZXRNYXNrKCRwcmVmaXgsICRzaXplKQogICAgewogICAgICAgICRtYXNrID0gJyc7CgogICAgICAgIGlmICgkb25lcyA9IGZsb29yKCRwcmVmaXggLyA4KSkgewogICAgICAgICAgICAkbWFzayA9IHN0cl9yZXBlYXQoY2hyKDI1NSksIChpbnQpICRvbmVzKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcmVtYWluZGVyID0gJHByZWZpeCAlIDgpIHsKICAgICAgICAgICAgJG1hc2sgLj0gY2hyKDB4ZmYgXiAoMHhmZiA+PiAkcmVtYWluZGVyKSk7CiAgICAgICAgfQoKICAgICAgICAkbWFzayA9IHN0cl9wYWQoJG1hc2ssICRzaXplLCBjaHIoMCkpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmlwTWFwVG82KCRtYXNrLCAkc2l6ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBuZXR3b3JrIGFuZCBtYXNrCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmFuZ2VJcCBJUCBpbl9hZGRyCiAgICAgKiBAcGFyYW0gaW50ICAgICRzaXplICAgIEJ5dGUgc2l6ZSBvZiBpbl9hZGRyCiAgICAgKiBAcGFyYW0gaW50ICAgICRwcmVmaXggIENJRFIgcHJlZml4LWxlbmd0aAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10gbmV0d29yayBpbl9hZGRyLCBiaW5hcnkgbWFzawogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlwR2V0TmV0d29yaygkcmFuZ2VJcCwgJHNpemUsICRwcmVmaXgpCiAgICB7CiAgICAgICAgJG5ldG1hc2sgPSAkdGhpcy0+aXBHZXRNYXNrKCRwcmVmaXgsICRzaXplKTsKCiAgICAgICAgLy8gR2V0IHRoZSBuZXR3b3JrIGZyb20gdGhlIGFkZHJlc3MgYW5kIG1hc2sKICAgICAgICAkbWFzayA9IHVucGFjaygnQyonLCAkbmV0bWFzayk7CiAgICAgICAgJGlwID0gdW5wYWNrKCdDKicsICRyYW5nZUlwKTsKICAgICAgICAkbmV0ID0gJyc7CiAgICAgICAgaWYgKGZhbHNlID09PSAkbWFzaykgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBwYXJzZSBuZXRtYXNrICcuJG5ldG1hc2spOwogICAgICAgIH0KICAgICAgICBpZiAoZmFsc2UgPT09ICRpcCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBwYXJzZSByYW5nZSBJUCAnLiRyYW5nZUlwKTsKICAgICAgICB9CgogICAgICAgIGZvciAoJGkgPSAxOyAkaSA8IDE3OyArKyRpKSB7CiAgICAgICAgICAgICRuZXQgLj0gY2hyKCRpcFskaV0gJiAkbWFza1skaV0pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCRuZXQsICRuZXRtYXNrKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hcHMgYW4gSVB2NCBhZGRyZXNzIHRvIElQdjYKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiaW5hcnkgaW5fYWRkcgogICAgICogQHBhcmFtIGludCAgICAkc2l6ZSAgIEJ5dGUgc2l6ZSBvZiBpbl9hZGRyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgTWFwcGVkIG9yIGV4aXN0aW5nIGluX2FkZHIKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpcE1hcFRvNigkYmluYXJ5LCAkc2l6ZSkKICAgIHsKICAgICAgICBpZiAoJHNpemUgPT09IDQpIHsKICAgICAgICAgICAgJHByZWZpeCA9IHN0cl9yZXBlYXQoY2hyKDApLCAxMCkgLiBzdHJfcmVwZWF0KGNocigyNTUpLCAyKTsKICAgICAgICAgICAgJGJpbmFyeSA9ICRwcmVmaXggLiAkYmluYXJ5OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRiaW5hcnk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgcnVsZSBkYXRhIG9iamVjdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICRob3N0CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAkcG9ydAogICAgICogQHBhcmFtIG51bGx8c3RkQ2xhc3MgJGlwZGF0YQogICAgICoKICAgICAqIEByZXR1cm4gc3RkQ2xhc3MKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYWtlRGF0YSgkaG9zdCwgJHBvcnQsICRpcGRhdGEpCiAgICB7CiAgICAgICAgcmV0dXJuIChvYmplY3QpIGFycmF5KAogICAgICAgICAgICAnaG9zdCcgPT4gJGhvc3QsCiAgICAgICAgICAgICduYW1lJyA9PiAnLicgLiBsdHJpbSgkaG9zdCwgJy4nKSwKICAgICAgICAgICAgJ3BvcnQnID0+ICRwb3J0LAogICAgICAgICAgICAnaXBkYXRhJyA9PiAkaXBkYXRhLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGFuIGlwIGRhdGEgb2JqZWN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRpcCAgICAgIGluX2FkZHIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkc2l6ZSAgICBCeXRlIHNpemUgb2YgaW5fYWRkcgogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRuZXRtYXNrIE5ldHdvcmsgbWFzawogICAgICoKICAgICAqIEByZXR1cm4gc3RkQ2xhc3MKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYWtlSXBEYXRhKCRpcCwgJHNpemUsICRuZXRtYXNrKQogICAgewogICAgICAgIHJldHVybiAob2JqZWN0KSBhcnJheSgKICAgICAgICAgICAgJ2lwJyA9PiAkaXAsCiAgICAgICAgICAgICdzaXplJyA9PiAkc2l6ZSwKICAgICAgICAgICAgJ25ldG1hc2snID0+ICRuZXRtYXNrLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTcGxpdHMgdGhlIGhvc3RuYW1lIGludG8gaG9zdCBhbmQgcG9ydCBjb21wb25lbnRzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaG9zdE5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkW10gaG9zdCwgcG9ydCwgaWYgdGhlcmUgd2FzIGVycm9yCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc3BsaXRIb3N0UG9ydCgkaG9zdE5hbWUpCiAgICB7CiAgICAgICAgLy8gaG9zdCwgcG9ydCwgZXJyCiAgICAgICAgJGVycm9yID0gYXJyYXkoJycsICcnLCB0cnVlKTsKICAgICAgICAkcG9ydCA9IDA7CiAgICAgICAgJGlwNiA9ICcnOwoKICAgICAgICAvLyBDaGVjayBmb3Igc3F1YXJlLWJyYWNrZXQgbm90YXRpb24KICAgICAgICBpZiAoJGhvc3ROYW1lWzBdID09PSAnWycpIHsKICAgICAgICAgICAgJGluZGV4ID0gc3RycG9zKCRob3N0TmFtZSwgJ10nKTsKCiAgICAgICAgICAgIC8vIFRoZSBzbWFsbGVzdCBpcDYgYWRkcmVzcyBpcyA6OgogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRpbmRleCB8fCAkaW5kZXggPCAzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGVycm9yOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaXA2ID0gc3Vic3RyKCRob3N0TmFtZSwgMSwgJGluZGV4IC0gMSk7CiAgICAgICAgICAgICRob3N0TmFtZSA9IHN1YnN0cigkaG9zdE5hbWUsICRpbmRleCArIDEpOwoKICAgICAgICAgICAgaWYgKHN0cnBicmsoJGhvc3ROYW1lLCAnW10nKSAhPT0gZmFsc2UgfHwgc3Vic3RyX2NvdW50KCRob3N0TmFtZSwgJzonKSA+IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZXJyb3I7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChzdWJzdHJfY291bnQoJGhvc3ROYW1lLCAnOicpID09PSAxKSB7CiAgICAgICAgICAgICRpbmRleCA9IHN0cnBvcygkaG9zdE5hbWUsICc6Jyk7CiAgICAgICAgICAgICRwb3J0ID0gc3Vic3RyKCRob3N0TmFtZSwgJGluZGV4ICsgMSk7CiAgICAgICAgICAgICRob3N0TmFtZSA9IHN1YnN0cigkaG9zdE5hbWUsIDAsICRpbmRleCk7CgogICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZUludCgkcG9ydCwgMSwgNjU1MzUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGVycm9yOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcG9ydCA9IChpbnQpICRwb3J0OwogICAgICAgIH0KCiAgICAgICAgJGhvc3QgPSAkaXA2IC4gJGhvc3ROYW1lOwoKICAgICAgICByZXR1cm4gYXJyYXkoJGhvc3QsICRwb3J0LCBmYWxzZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBXcmFwcGVyIGFyb3VuZCBmaWx0ZXJfdmFyIEZJTFRFUl9WQUxJREFURV9JTlQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnQKICAgICAqIEBwYXJhbSBpbnQgICAgJG1pbgogICAgICogQHBhcmFtIGludCAgICAkbWF4CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVJbnQoJGludCwgJG1pbiwgJG1heCkKICAgIHsKICAgICAgICAkb3B0aW9ucyA9IGFycmF5KAogICAgICAgICAgICAnb3B0aW9ucycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAnbWluX3JhbmdlJyA9PiAkbWluLAogICAgICAgICAgICAgICAgJ21heF9yYW5nZScgPT4gJG1heCwKICAgICAgICAgICAgKSwKICAgICAgICApOwoKICAgICAgICByZXR1cm4gZmFsc2UgIT09IGZpbHRlcl92YXIoJGludCwgRklMVEVSX1ZBTElEQVRFX0lOVCwgJG9wdGlvbnMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3M7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxSdW50aW1lRXhjZXB0aW9uOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBQcm9jZXNzRXhlY3V0b3IKewogICAgY29uc3QgU1RBVFVTX1FVRVVFRCA9IDE7CiAgICBjb25zdCBTVEFUVVNfU1RBUlRFRCA9IDI7CiAgICBjb25zdCBTVEFUVVNfQ09NUExFVEVEID0gMzsKICAgIGNvbnN0IFNUQVRVU19GQUlMRUQgPSA0OwogICAgY29uc3QgU1RBVFVTX0FCT1JURUQgPSA1OwoKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyAkdGltZW91dCA9IDMwMDsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGNhcHR1cmVPdXRwdXQgPSBmYWxzZTsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRlcnJvck91dHB1dCA9ICcnOwogICAgLyoqIEB2YXIgP0lPSW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlvOwoKICAgIC8qKgogICAgICogQHBocHN0YW4tdmFyIGFycmF5PGludCwgYXJyYXk8c3RyaW5nLCBtaXhlZD4+CiAgICAgKi8KICAgIHByaXZhdGUgJGpvYnMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICRydW5uaW5nSm9icyA9IDA7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByaXZhdGUgJG1heEpvYnMgPSAxMDsKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkaWRHZW4gPSAwOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkYWxsb3dBc3luYyA9IGZhbHNlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8gPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIHJ1bnMgYSBwcm9jZXNzIG9uIHRoZSBjb21tYW5kbGluZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAkY29tbWFuZCB0aGUgY29tbWFuZCB0byBleGVjdXRlCiAgICAgKiBAcGFyYW0gIG1peGVkICAgJG91dHB1dCAgdGhlIG91dHB1dCB3aWxsIGJlIHdyaXR0ZW4gaW50byB0aGlzIHZhciBpZiBwYXNzZWQgYnkgcmVmCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYSBjYWxsYWJsZSBpcyBwYXNzZWQgaXQgd2lsbCBiZSB1c2VkIGFzIG91dHB1dCBoYW5kbGVyCiAgICAgKiBAcGFyYW0gID9zdHJpbmcgJGN3ZCAgICAgdGhlIHdvcmtpbmcgZGlyZWN0b3J5CiAgICAgKiBAcmV0dXJuIGludCAgICAgc3RhdHVzY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZSgkY29tbWFuZCwgJiRvdXRwdXQgPSBudWxsLCAkY3dkID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoZnVuY19udW1fYXJncygpID4gMSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvRXhlY3V0ZSgkY29tbWFuZCwgJGN3ZCwgZmFsc2UsICRvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb0V4ZWN1dGUoJGNvbW1hbmQsICRjd2QsIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHJ1bnMgYSBwcm9jZXNzIG9uIHRoZSBjb21tYW5kbGluZSBpbiBUVFkgbW9kZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAkY29tbWFuZCB0aGUgY29tbWFuZCB0byBleGVjdXRlCiAgICAgKiBAcGFyYW0gID9zdHJpbmcgJGN3ZCAgICAgdGhlIHdvcmtpbmcgZGlyZWN0b3J5CiAgICAgKiBAcmV0dXJuIGludCAgICAgc3RhdHVzY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZVR0eSgkY29tbWFuZCwgJGN3ZCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1R0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9FeGVjdXRlKCRjb21tYW5kLCAkY3dkLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZG9FeGVjdXRlKCRjb21tYW5kLCAkY3dkLCBmYWxzZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgJGNvbW1hbmQKICAgICAqIEBwYXJhbSAgP3N0cmluZyAkY3dkCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgJHR0eQogICAgICogQHBhcmFtICBtaXhlZCAgICRvdXRwdXQKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9FeGVjdXRlKCRjb21tYW5kLCAkY3dkLCAkdHR5LCAmJG91dHB1dCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dENvbW1hbmRSdW4oJGNvbW1hbmQsICRjd2QsIGZhbHNlKTsKCiAgICAgICAgLy8gVE9ETyBpbiAyLjIsIHRoZXNlIHR3byBjaGVja3MgY2FuIGJlIGRyb3BwZWQgYXMgU3ltZm9ueSA0KyBzdXBwb3J0cyB0aGVtIG91dCBvZiB0aGUgYm94CiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgbnVsbCB0cmFuc2xhdGUgdG8gdGhlIHByb3BlciBkaXJlY3RvcnkgaW4gY2FzZSB0aGUgZGlyIGlzIGEgc3ltbGluawogICAgICAgIC8vIGFuZCB3ZSBjYWxsIGEgZ2l0IGNvbW1hbmQsIGJlY2F1c2UgbXN5c2dpdCBkb2VzIG5vdCBoYW5kbGUgc3ltbGlua3MgcHJvcGVybHkKICAgICAgICBpZiAobnVsbCA9PT0gJGN3ZCAmJiBQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgZmFsc2UgIT09IHN0cnBvcygkY29tbWFuZCwgJ2dpdCcpICYmIGdldGN3ZCgpKSB7CiAgICAgICAgICAgICRjd2QgPSByZWFscGF0aChnZXRjd2QoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkY3dkICYmICFpc19kaXIoJGN3ZCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgZ2l2ZW4gQ1dEIGZvciB0aGUgcHJvY2VzcyBkb2VzIG5vdCBleGlzdDogJy4kY3dkKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jYXB0dXJlT3V0cHV0ID0gZnVuY19udW1fYXJncygpID4gMzsKICAgICAgICAkdGhpcy0+ZXJyb3JPdXRwdXQgPSAnJzsKCiAgICAgICAgLy8gVE9ETyBpbiB2MywgY29tbWFuZHMgc2hvdWxkIGJlIHBhc3NlZCBpbiBhcyBhcnJheXMgb2YgY21kICsgYXJncwogICAgICAgIGlmIChtZXRob2RfZXhpc3RzKCdTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3MnLCAnZnJvbVNoZWxsQ29tbWFuZGxpbmUnKSkgewogICAgICAgICAgICAkcHJvY2VzcyA9IFByb2Nlc3M6OmZyb21TaGVsbENvbW1hbmRsaW5lKCRjb21tYW5kLCAkY3dkLCBudWxsLCBudWxsLCBzdGF0aWM6OmdldFRpbWVvdXQoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoqIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUgKi8KICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcygkY29tbWFuZCwgJGN3ZCwgbnVsbCwgbnVsbCwgc3RhdGljOjpnZXRUaW1lb3V0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIVBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiAkdHR5KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkcHJvY2Vzcy0+c2V0VHR5KHRydWUpOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyBpZ25vcmUgVFRZIGVuYWJsaW5nIGVycm9ycwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkY2FsbGJhY2sgPSBpc19jYWxsYWJsZSgkb3V0cHV0KSA/ICRvdXRwdXQgOiBhcnJheSgkdGhpcywgJ291dHB1dEhhbmRsZXInKTsKICAgICAgICAkcHJvY2Vzcy0+cnVuKCRjYWxsYmFjayk7CgogICAgICAgIGlmICgkdGhpcy0+Y2FwdHVyZU91dHB1dCAmJiAhaXNfY2FsbGFibGUoJG91dHB1dCkpIHsKICAgICAgICAgICAgJG91dHB1dCA9ICRwcm9jZXNzLT5nZXRPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5lcnJvck91dHB1dCA9ICRwcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwoKICAgICAgICByZXR1cm4gJHByb2Nlc3MtPmdldEV4aXRDb2RlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBzdGFydHMgYSBwcm9jZXNzIG9uIHRoZSBjb21tYW5kbGluZSBpbiBhc3luYyBtb2RlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRjb21tYW5kIHRoZSBjb21tYW5kIHRvIGV4ZWN1dGUKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkY3dkICAgICB0aGUgd29ya2luZyBkaXJlY3RvcnkKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZUFzeW5jKCRjb21tYW5kLCAkY3dkID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5hbGxvd0FzeW5jKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ1lvdSBtdXN0IHVzZSB0aGUgUHJvY2Vzc0V4ZWN1dG9yIGluc3RhbmNlIHdoaWNoIGlzIHBhcnQgb2YgYSBDb21wb3NlclxMb29wIGluc3RhbmNlIHRvIGJlIGFibGUgdG8gcnVuIGFzeW5jIHByb2Nlc3NlcycpOwogICAgICAgIH0KCiAgICAgICAgJGpvYiA9IGFycmF5KAogICAgICAgICAgICAnaWQnID0+ICR0aGlzLT5pZEdlbisrLAogICAgICAgICAgICAnc3RhdHVzJyA9PiBzZWxmOjpTVEFUVVNfUVVFVUVELAogICAgICAgICAgICAnY29tbWFuZCcgPT4gJGNvbW1hbmQsCiAgICAgICAgICAgICdjd2QnID0+ICRjd2QsCiAgICAgICAgKTsKCiAgICAgICAgJHJlc29sdmVyID0gZnVuY3Rpb24gKCRyZXNvbHZlLCAkcmVqZWN0KSB1c2UgKCYkam9iKSB7CiAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gUHJvY2Vzc0V4ZWN1dG9yOjpTVEFUVVNfUVVFVUVEOwogICAgICAgICAgICAkam9iWydyZXNvbHZlJ10gPSAkcmVzb2x2ZTsKICAgICAgICAgICAgJGpvYlsncmVqZWN0J10gPSAkcmVqZWN0OwogICAgICAgIH07CgogICAgICAgICRzZWxmID0gJHRoaXM7CgogICAgICAgICRjYW5jZWxlciA9IGZ1bmN0aW9uICgpIHVzZSAoJiRqb2IpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddID09PSBQcm9jZXNzRXhlY3V0b3I6OlNUQVRVU19RVUVVRUQpIHsKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gUHJvY2Vzc0V4ZWN1dG9yOjpTVEFUVVNfQUJPUlRFRDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGpvYlsnc3RhdHVzJ10gIT09IFByb2Nlc3NFeGVjdXRvcjo6U1RBVFVTX1NUQVJURUQpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IFByb2Nlc3NFeGVjdXRvcjo6U1RBVFVTX0FCT1JURUQ7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAoZGVmaW5lZCgnU0lHSU5UJykpIHsKICAgICAgICAgICAgICAgICAgICAkam9iWydwcm9jZXNzJ10tPnNpZ25hbChTSUdJTlQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyBzaWduYWwgY2FuIHRocm93IGluIHZhcmlvdXMgY29uZGl0aW9ucywgYnV0IHdlIGRvbid0IGNhcmUgaWYgaXQgZmFpbHMKICAgICAgICAgICAgfQogICAgICAgICAgICAkam9iWydwcm9jZXNzJ10tPnN0b3AoMSk7CgogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0Fib3J0ZWQgcHJvY2VzcycpOwogICAgICAgIH07CgogICAgICAgICRwcm9taXNlID0gbmV3IFByb21pc2UoJHJlc29sdmVyLCAkY2FuY2VsZXIpOwogICAgICAgICRwcm9taXNlID0gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgmJGpvYiwgJHNlbGYpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ3Byb2Nlc3MnXS0+aXNTdWNjZXNzZnVsKCkpIHsKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gUHJvY2Vzc0V4ZWN1dG9yOjpTVEFUVVNfQ09NUExFVEVEOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBQcm9jZXNzRXhlY3V0b3I6OlNUQVRVU19GQUlMRUQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRPRE8gMy4wIHRoaXMgc2hvdWxkIGJlIGRvbmUgZGlyZWN0bHkgb24gJHRoaXMgd2hlbiBQSFAgNS4zIGlzIGRyb3BwZWQKICAgICAgICAgICAgJHNlbGYtPm1hcmtKb2JEb25lKCk7CgogICAgICAgICAgICByZXR1cm4gJGpvYlsncHJvY2VzcyddOwogICAgICAgIH0sIGZ1bmN0aW9uICgkZSkgdXNlICgmJGpvYiwgJHNlbGYpIHsKICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBQcm9jZXNzRXhlY3V0b3I6OlNUQVRVU19GQUlMRUQ7CgogICAgICAgICAgICAkc2VsZi0+bWFya0pvYkRvbmUoKTsKCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0pOwogICAgICAgICR0aGlzLT5qb2JzWyRqb2JbJ2lkJ11dID0gJiRqb2I7CgogICAgICAgIGlmICgkdGhpcy0+cnVubmluZ0pvYnMgPCAkdGhpcy0+bWF4Sm9icykgewogICAgICAgICAgICAkdGhpcy0+c3RhcnRKb2IoJGpvYlsnaWQnXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByb21pc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludCAgJGlkCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzdGFydEpvYigkaWQpCiAgICB7CiAgICAgICAgJGpvYiA9ICYkdGhpcy0+am9ic1skaWRdOwogICAgICAgIGlmICgkam9iWydzdGF0dXMnXSAhPT0gc2VsZjo6U1RBVFVTX1FVRVVFRCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBzdGFydCBqb2IKICAgICAgICAkam9iWydzdGF0dXMnXSA9IHNlbGY6OlNUQVRVU19TVEFSVEVEOwogICAgICAgICR0aGlzLT5ydW5uaW5nSm9icysrOwoKICAgICAgICAkY29tbWFuZCA9ICRqb2JbJ2NvbW1hbmQnXTsKICAgICAgICAkY3dkID0gJGpvYlsnY3dkJ107CgogICAgICAgICR0aGlzLT5vdXRwdXRDb21tYW5kUnVuKCRjb21tYW5kLCAkY3dkLCB0cnVlKTsKCiAgICAgICAgLy8gVE9ETyBpbiAyLjIsIHRoZXNlIHR3byBjaGVja3MgY2FuIGJlIGRyb3BwZWQgYXMgU3ltZm9ueSA0KyBzdXBwb3J0cyB0aGVtIG91dCBvZiB0aGUgYm94CiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgbnVsbCB0cmFuc2xhdGUgdG8gdGhlIHByb3BlciBkaXJlY3RvcnkgaW4gY2FzZSB0aGUgZGlyIGlzIGEgc3ltbGluawogICAgICAgIC8vIGFuZCB3ZSBjYWxsIGEgZ2l0IGNvbW1hbmQsIGJlY2F1c2UgbXN5c2dpdCBkb2VzIG5vdCBoYW5kbGUgc3ltbGlua3MgcHJvcGVybHkKICAgICAgICBpZiAobnVsbCA9PT0gJGN3ZCAmJiBQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgZmFsc2UgIT09IHN0cnBvcygkY29tbWFuZCwgJ2dpdCcpICYmIGdldGN3ZCgpKSB7CiAgICAgICAgICAgICRjd2QgPSByZWFscGF0aChnZXRjd2QoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkY3dkICYmICFpc19kaXIoJGN3ZCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgZ2l2ZW4gQ1dEIGZvciB0aGUgcHJvY2VzcyBkb2VzIG5vdCBleGlzdDogJy4kY3dkKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIFRPRE8gaW4gdjMsIGNvbW1hbmRzIHNob3VsZCBiZSBwYXNzZWQgaW4gYXMgYXJyYXlzIG9mIGNtZCArIGFyZ3MKICAgICAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJ1N5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzcycsICdmcm9tU2hlbGxDb21tYW5kbGluZScpKSB7CiAgICAgICAgICAgICAgICAkcHJvY2VzcyA9IFByb2Nlc3M6OmZyb21TaGVsbENvbW1hbmRsaW5lKCRjb21tYW5kLCAkY3dkLCBudWxsLCBudWxsLCBzdGF0aWM6OmdldFRpbWVvdXQoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzKCRjb21tYW5kLCAkY3dkLCBudWxsLCBudWxsLCBzdGF0aWM6OmdldFRpbWVvdXQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGNhbGxfdXNlcl9mdW5jKCRqb2JbJ3JlamVjdCddLCAkZSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZSkgewogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYygkam9iWydyZWplY3QnXSwgJGUpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGpvYlsncHJvY2VzcyddID0gJHByb2Nlc3M7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRwcm9jZXNzLT5zdGFydCgpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJGpvYlsncmVqZWN0J10sICRlKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgICAgIGNhbGxfdXNlcl9mdW5jKCRqb2JbJ3JlamVjdCddLCAkZSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICA/aW50ICRpbmRleCBqb2IgaWQKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FpdCgkaW5kZXggPSBudWxsKQogICAgewogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmNvdW50QWN0aXZlSm9icygkaW5kZXgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzbGVlcCgxMDAwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZUFzeW5jKCkKICAgIHsKICAgICAgICAkdGhpcy0+YWxsb3dBc3luYyA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqCiAgICAgKiBAcGFyYW0gID9pbnQgJGluZGV4IGpvYiBpZAogICAgICogQHJldHVybiBpbnQgICAgICAgICBudW1iZXIgb2YgYWN0aXZlIChxdWV1ZWQgb3Igc3RhcnRlZCkgam9icwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY291bnRBY3RpdmVKb2JzKCRpbmRleCA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gdGljawogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5qb2JzIGFzICRqb2IpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddID09PSBzZWxmOjpTVEFUVVNfU1RBUlRFRCkgewogICAgICAgICAgICAgICAgaWYgKCEkam9iWydwcm9jZXNzJ10tPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJGpvYlsncmVzb2x2ZSddLCAkam9iWydwcm9jZXNzJ10pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRqb2JbJ3Byb2Nlc3MnXS0+Y2hlY2tUaW1lb3V0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+cnVubmluZ0pvYnMgPCAkdGhpcy0+bWF4Sm9icykgewogICAgICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddID09PSBzZWxmOjpTVEFUVVNfUVVFVUVEKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnN0YXJ0Sm9iKCRqb2JbJ2lkJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJGluZGV4KSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+am9ic1skaW5kZXhdWydzdGF0dXMnXSA8IHNlbGY6OlNUQVRVU19DT01QTEVURUQgPyAxIDogMDsKICAgICAgICB9CgogICAgICAgICRhY3RpdmUgPSAwOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5qb2JzIGFzICRqb2IpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddIDwgc2VsZjo6U1RBVFVTX0NPTVBMRVRFRCkgewogICAgICAgICAgICAgICAgJGFjdGl2ZSsrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmpvYnNbJGpvYlsnaWQnXV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGFjdGl2ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwcml2YXRlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtYXJrSm9iRG9uZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnJ1bm5pbmdKb2JzLS07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gID9zdHJpbmcgICRvdXRwdXQKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNwbGl0TGluZXMoJG91dHB1dCkKICAgIHsKICAgICAgICAkb3V0cHV0ID0gdHJpbSgoc3RyaW5nKSAkb3V0cHV0KTsKCiAgICAgICAgcmV0dXJuICRvdXRwdXQgPT09ICcnID8gYXJyYXkoKSA6IFByZWc6OnNwbGl0KCd7XHI/XG59JywgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYW55IGVycm9yIG91dHB1dCBmcm9tIHRoZSBsYXN0IGNvbW1hbmQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3JPdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcHJpdmF0ZQogICAgICoKICAgICAqIEBwYXJhbSBQcm9jZXNzOjpFUlJ8UHJvY2Vzczo6T1VUICR0eXBlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAkYnVmZmVyCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvdXRwdXRIYW5kbGVyKCR0eXBlLCAkYnVmZmVyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2FwdHVyZU91dHB1dCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmlvKSB7CiAgICAgICAgICAgIGVjaG8gJGJ1ZmZlcjsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChQcm9jZXNzOjpFUlIgPT09ICR0eXBlKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvclJhdygkYnVmZmVyLCBmYWxzZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZVJhdygkYnVmZmVyLCBmYWxzZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQgdGhlIHRpbWVvdXQgaW4gc2Vjb25kcwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFRpbWVvdXQoKQogICAgewogICAgICAgIHJldHVybiBzdGF0aWM6OiR0aW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgICR0aW1lb3V0IHRoZSB0aW1lb3V0IGluIHNlY29uZHMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldFRpbWVvdXQoJHRpbWVvdXQpCiAgICB7CiAgICAgICAgc3RhdGljOjokdGltZW91dCA9ICR0aW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgc2hlbGwgYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xmYWxzZXxudWxsICRhcmd1bWVudCBUaGUgYXJndW1lbnQgdGhhdCB3aWxsIGJlIGVzY2FwZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZXNjYXBlZCBhcmd1bWVudAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVzY2FwZSgkYXJndW1lbnQpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmVzY2FwZUFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkY29tbWFuZAogICAgICogQHBhcmFtID9zdHJpbmcgJGN3ZAogICAgICogQHBhcmFtIGJvb2wgICAgJGFzeW5jCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBvdXRwdXRDb21tYW5kUnVuKCRjb21tYW5kLCAkY3dkLCAkYXN5bmMpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5pbyB8fCAhJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHNhZmVDb21tYW5kID0gUHJlZzo6cmVwbGFjZUNhbGxiYWNrKCd7Oi8vKD9QPHVzZXI+W146L1xzXSspOig/UDxwYXNzd29yZD5bXkBccy9dKylAfWknLCBmdW5jdGlvbiAoJG0pIHsKICAgICAgICAgICAgLy8gaWYgdGhlIHVzZXJuYW1lIGxvb2tzIGxpa2UgYSBsb25nICgxMmNoYXIrKSBoZXggc3RyaW5nLCBvciBhIG1vZGVybiBnaXRodWIgdG9rZW4gKGUuZy4gZ2hwX3h4eCkgd2Ugb2JmdXNjYXRlIHRoYXQKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKFthLWYwLTldezEyLH18Z2hbYS16XV9bYS16QS1aMC05X10rKSR9JywgJG1bJ3VzZXInXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAnOi8vKioqOioqKkAnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XlthLWYwLTldezEyLH0kfScsICRtWyd1c2VyJ10pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJzovLyoqKjoqKipAJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICc6Ly8nLiRtWyd1c2VyJ10uJzoqKipAJzsKICAgICAgICB9LCAkY29tbWFuZCk7CiAgICAgICAgJHNhZmVDb21tYW5kID0gUHJlZzo6cmVwbGFjZSgiey0tcGFzc3dvcmQgKC4qW15cXFxcXVwnKSB9IiwgJy0tcGFzc3dvcmQgXCcqKipcJyAnLCAkc2FmZUNvbW1hbmQpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignRXhlY3V0aW5nJy4oJGFzeW5jID8gJyBhc3luYycgOiAnJykuJyBjb21tYW5kICgnLigkY3dkID86ICdDV0QnKS4nKTogJy4kc2FmZUNvbW1hbmQpOwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgc2hlbGwgYXJndW1lbnQgZm9yIFN5bWZvbnkgUHJvY2Vzcy4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBleHBlY3RzIGNtZC5leGUgdG8gYmUgc3RhcnRlZCB3aXRoIHRoZSAvVjpPTiBvcHRpb24sIHdoaWNoCiAgICAgKiBlbmFibGVzIGRlbGF5ZWQgZW52aXJvbm1lbnQgdmFyaWFibGUgZXhwYW5zaW9uIHVzaW5nICEgYXMgdGhlIGRlbGltaXRlci4KICAgICAqIElmIHRoaXMgaXMgbm90IHRoZSBjYXNlLCBhbnkgZXNjYXBlZCBeXiF2YXJeXiEgd2lsbCBiZSB0cmFuc2Zvcm1lZCB0bwogICAgICogXiF2YXJeISBhbmQgaW50cm9kdWNlIHR3byB1bmludGVuZGVkIGNhcmV0cy4KICAgICAqCiAgICAgKiBNb2RpZmllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9qb2huc3RldmVuc29uL3dpbmJveC1hcmdzCiAgICAgKiBNSVQgTGljZW5zZWQgKGMpIEpvaG4gU3RldmVuc29uIDxqb2huLXN0ZXZlbnNvbkBibHVleW9uZGVyLmNvLnVrPgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8ZmFsc2V8bnVsbCAkYXJndW1lbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGVBcmd1bWVudCgkYXJndW1lbnQpCiAgICB7CiAgICAgICAgaWYgKCcnID09PSAoJGFyZ3VtZW50ID0gKHN0cmluZykgJGFyZ3VtZW50KSkgewogICAgICAgICAgICByZXR1cm4gZXNjYXBlc2hlbGxhcmcoJGFyZ3VtZW50KTsKICAgICAgICB9CgogICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgIHJldHVybiAiJyIuc3RyX3JlcGxhY2UoIiciLCAiJ1xcJyciLCAkYXJndW1lbnQpLiInIjsKICAgICAgICB9CgogICAgICAgIC8vIE5ldyBsaW5lcyBicmVhayBjbWQuZXhlIGNvbW1hbmQgcGFyc2luZwogICAgICAgICRhcmd1bWVudCA9IHN0cnRyKCRhcmd1bWVudCwgIlxuIiwgJyAnKTsKCiAgICAgICAgJHF1b3RlID0gc3RycGJyaygkYXJndW1lbnQsICIgXHQiKSAhPT0gZmFsc2U7CiAgICAgICAgJGFyZ3VtZW50ID0gUHJlZzo6cmVwbGFjZSgnLyhcXFxcKikiLycsICckMSQxXFwiJywgJGFyZ3VtZW50LCAtMSwgJGRxdW90ZXMpOwogICAgICAgICRtZXRhID0gJGRxdW90ZXMgfHwgUHJlZzo6aXNNYXRjaCgnLyVbXiVdKyV8IVteIV0rIS8nLCAkYXJndW1lbnQpOwoKICAgICAgICBpZiAoISRtZXRhICYmICEkcXVvdGUpIHsKICAgICAgICAgICAgJHF1b3RlID0gc3RycGJyaygkYXJndW1lbnQsICdeJnw8PigpJykgIT09IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRxdW90ZSkgewogICAgICAgICAgICAkYXJndW1lbnQgPSAnIicuUHJlZzo6cmVwbGFjZSgnLyhcXFxcKikkLycsICckMSQxJywgJGFyZ3VtZW50KS4nIic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1ldGEpIHsKICAgICAgICAgICAgJGFyZ3VtZW50ID0gUHJlZzo6cmVwbGFjZSgnLyhbIl4mfDw+KCklXSkvJywgJ14kMScsICRhcmd1bWVudCk7CiAgICAgICAgICAgICRhcmd1bWVudCA9IFByZWc6OnJlcGxhY2UoJy8oISkvJywgJ15eJDEnLCAkYXJndW1lbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhcmd1bWVudDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgSm9uYXMgUmVuYXVkb3QgPGpvbmFzLnJlbmF1ZG90QGdtYWlsLmNvbT4KICovCmNsYXNzIEhnCnsKICAgIC8qKiBAdmFyIHN0cmluZ3xmYWxzZXxudWxsICovCiAgICBwcml2YXRlIHN0YXRpYyAkdmVyc2lvbiA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHZhciBcQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIFxDb21wb3NlclxDb25maWcKICAgICAqLwogICAgcHJpdmF0ZSAkY29uZmlnOwoKICAgIC8qKgogICAgICogQHZhciBcQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3IKICAgICAqLwogICAgcHJpdmF0ZSAkcHJvY2VzczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGNhbGxhYmxlICAgICRjb21tYW5kQ2FsbGFibGUKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGN3ZAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcnVuQ29tbWFuZCgkY29tbWFuZENhbGxhYmxlLCAkdXJsLCAkY3dkKQogICAgewogICAgICAgICR0aGlzLT5jb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJHVybCwgJHRoaXMtPmlvKTsKCiAgICAgICAgLy8gVHJ5IGFzIGlzCiAgICAgICAgJGNvbW1hbmQgPSBjYWxsX3VzZXJfZnVuYygkY29tbWFuZENhbGxhYmxlLCAkdXJsKTsKCiAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgJGN3ZCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gVHJ5IHdpdGggdGhlIGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uIGF2YWlsYWJsZQogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XihodHRwcz8pOi8vKCguKykoPzpcOiguKykpP0ApPyhbXi9dKykoLy4qKT99bWknLCAkdXJsLCAkbWF0Y2gpICYmICR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzVdKSkgewogICAgICAgICAgICAkYXV0aCA9ICR0aGlzLT5pby0+Z2V0QXV0aGVudGljYXRpb24oJG1hdGNoWzVdKTsKICAgICAgICAgICAgJGF1dGhlbnRpY2F0ZWRVcmwgPSAkbWF0Y2hbMV0gLiAnOi8vJyAuIHJhd3VybGVuY29kZSgkYXV0aFsndXNlcm5hbWUnXSkgLiAnOicgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3Bhc3N3b3JkJ10pIC4gJ0AnIC4gJG1hdGNoWzVdIC4gKCFlbXB0eSgkbWF0Y2hbNl0pID8gJG1hdGNoWzZdIDogbnVsbCk7CgogICAgICAgICAgICAkY29tbWFuZCA9IGNhbGxfdXNlcl9mdW5jKCRjb21tYW5kQ2FsbGFibGUsICRhdXRoZW50aWNhdGVkVXJsKTsKCiAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRlcnJvciA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRlcnJvciA9ICdUaGUgZ2l2ZW4gVVJMICgnIC4gJHVybCAuICcpIGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlZCBmb3JtYXQgKGh0dHAocyk6Ly8odXNlcm5hbWU6cGFzc3dvcmRAKWV4YW1wbGUuY29tL3BhdGgtdG8tcmVwb3NpdG9yeSknOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnRocm93RXhjZXB0aW9uKCdGYWlsZWQgdG8gY2xvbmUgJyAuICR1cmwgLiAnLCAnIC4gIlxuXG4iIC4gJGVycm9yLCAkdXJsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdXJsCiAgICAgKgogICAgICogQHJldHVybiBuZXZlcgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHRocm93RXhjZXB0aW9uKCRtZXNzYWdlLCAkdXJsKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjpnZXRWZXJzaW9uKCR0aGlzLT5wcm9jZXNzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oVXJsOjpzYW5pdGl6ZSgnRmFpbGVkIHRvIGNsb25lICcgLiAkdXJsIC4gJywgaGcgd2FzIG5vdCBmb3VuZCwgY2hlY2sgdGhhdCBpdCBpcyBpbnN0YWxsZWQgYW5kIGluIHlvdXIgUEFUSCBlbnYuJyAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKSk7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oVXJsOjpzYW5pdGl6ZSgkbWVzc2FnZSkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmVzIHRoZSBjdXJyZW50IGhnIHZlcnNpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgaGcgdmVyc2lvbiBudW1iZXIsIGlmIHByZXNlbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmVyc2lvbihQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSBzZWxmOjokdmVyc2lvbikgewogICAgICAgICAgICBzZWxmOjokdmVyc2lvbiA9IG51bGw7CiAgICAgICAgICAgIGlmICgwID09PSAkcHJvY2Vzcy0+ZXhlY3V0ZSgnaGcgLS12ZXJzaW9uJywgJG91dHB1dCkgJiYgUHJlZzo6aXNNYXRjaCgnL14uKz8gKFxkKyg/OlwuXGQrKSspXCk/XHI/XG4vJywgJG91dHB1dCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokdmVyc2lvbiA9ICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JHZlcnNpb247CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBAYXV0aG9yIE1hdHQgV2hpdHRvbSA8TWF0dC5XaGl0dG9tQHZldGVyYW5zdW5pdGVkLmNvbT4KICoKICogQHBocHN0YW4tdHlwZSBSZXBvQ29uZmlnIGFycmF5e3VuaXF1ZV9wZXJmb3JjZV9jbGllbnRfbmFtZT86IHN0cmluZywgZGVwb3Q/OiBzdHJpbmcsIGJyYW5jaD86IHN0cmluZywgcDR1c2VyPzogc3RyaW5nLCBwNHBhc3N3b3JkPzogc3RyaW5nfQogKi8KY2xhc3MgUGVyZm9yY2UKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHBhdGg7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHA0RGVwb3Q7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHA0Q2xpZW50OwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRwNFVzZXI7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHA0UGFzc3dvcmQ7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcDRQb3J0OwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRwNFN0cmVhbTsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRwNENsaWVudFNwZWM7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHA0RGVwb3RUeXBlOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRwNEJyYW5jaDsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHVuaXF1ZVBlcmZvcmNlQ2xpZW50TmFtZTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkd2luZG93c0ZsYWc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkY29tbWFuZFJlc3VsdDsKCiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKiogQHZhciA/RmlsZXN5c3RlbSAqLwogICAgcHJvdGVjdGVkICRmaWxlc3lzdGVtOwoKICAgIC8qKgogICAgICogQHBocHN0YW4tcGFyYW0gUmVwb0NvbmZpZyAkcmVwb0NvbmZpZwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAkcG9ydAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAkcGF0aAogICAgICogQHBhcmFtIFByb2Nlc3NFeGVjdXRvciAgICAkcHJvY2VzcwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAkaXNXaW5kb3dzCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICAgICRpbwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlcG9Db25maWcsICRwb3J0LCAkcGF0aCwgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzLCAkaXNXaW5kb3dzLCBJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgJHRoaXMtPndpbmRvd3NGbGFnID0gJGlzV2luZG93czsKICAgICAgICAkdGhpcy0+cDRQb3J0ID0gJHBvcnQ7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCRyZXBvQ29uZmlnKTsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBSZXBvQ29uZmlnICRyZXBvQ29uZmlnCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICRwb3J0CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICRwYXRoCiAgICAgKiBAcGFyYW0gUHJvY2Vzc0V4ZWN1dG9yICAgICRwcm9jZXNzCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICAgICRpbwogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZSgkcmVwb0NvbmZpZywgJHBvcnQsICRwYXRoLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MsIElPSW50ZXJmYWNlICRpbykKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFBlcmZvcmNlKCRyZXBvQ29uZmlnLCAkcG9ydCwgJHBhdGgsICRwcm9jZXNzLCBQbGF0Zm9ybTo6aXNXaW5kb3dzKCksICRpbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICR1cmwKICAgICAqIEBwYXJhbSBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3NFeGVjdXRvcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrU2VydmVyRXhpc3RzKCR1cmwsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2Vzc0V4ZWN1dG9yKQogICAgewogICAgICAgICRvdXRwdXQgPSBudWxsOwoKICAgICAgICByZXR1cm4gIDAgPT09ICRwcm9jZXNzRXhlY3V0b3ItPmV4ZWN1dGUoJ3A0IC1wICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKSAuICcgaW5mbyAtcycsICRvdXRwdXQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBocHN0YW4tcGFyYW0gUmVwb0NvbmZpZyAkcmVwb0NvbmZpZwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgkcmVwb0NvbmZpZykKICAgIHsKICAgICAgICAkdGhpcy0+dW5pcXVlUGVyZm9yY2VDbGllbnROYW1lID0gJHRoaXMtPmdlbmVyYXRlVW5pcXVlUGVyZm9yY2VDbGllbnROYW1lKCk7CiAgICAgICAgaWYgKCEkcmVwb0NvbmZpZykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkcmVwb0NvbmZpZ1sndW5pcXVlX3BlcmZvcmNlX2NsaWVudF9uYW1lJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT51bmlxdWVQZXJmb3JjZUNsaWVudE5hbWUgPSAkcmVwb0NvbmZpZ1sndW5pcXVlX3BlcmZvcmNlX2NsaWVudF9uYW1lJ107CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHJlcG9Db25maWdbJ2RlcG90J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5wNERlcG90ID0gJHJlcG9Db25maWdbJ2RlcG90J107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkcmVwb0NvbmZpZ1snYnJhbmNoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5wNEJyYW5jaCA9ICRyZXBvQ29uZmlnWydicmFuY2gnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRyZXBvQ29uZmlnWydwNHVzZXInXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnA0VXNlciA9ICRyZXBvQ29uZmlnWydwNHVzZXInXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cDRVc2VyID0gJHRoaXMtPmdldFA0dmFyaWFibGUoJ1A0VVNFUicpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHJlcG9Db25maWdbJ3A0cGFzc3dvcmQnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnA0UGFzc3dvcmQgPSAkcmVwb0NvbmZpZ1sncDRwYXNzd29yZCddOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZGVwb3QKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkYnJhbmNoCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplRGVwb3RBbmRCcmFuY2goJGRlcG90LCAkYnJhbmNoKQogICAgewogICAgICAgIGlmIChpc3NldCgkZGVwb3QpKSB7CiAgICAgICAgICAgICR0aGlzLT5wNERlcG90ID0gJGRlcG90OwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGJyYW5jaCkpIHsKICAgICAgICAgICAgJHRoaXMtPnA0QnJhbmNoID0gJGJyYW5jaDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIG5vbi1lbXB0eS1zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdlbmVyYXRlVW5pcXVlUGVyZm9yY2VDbGllbnROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gZ2V0aG9zdG5hbWUoKSAuICJfIiAuIHRpbWUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cENsaWVudFNwZWMoKQogICAgewogICAgICAgICRjbGllbnQgPSAkdGhpcy0+Z2V0Q2xpZW50KCk7CiAgICAgICAgJHRhc2sgPSAnY2xpZW50IC1kICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkY2xpZW50KTsKICAgICAgICAkdXNlUDRDbGllbnQgPSBmYWxzZTsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgkdGFzaywgJHVzZVA0Q2xpZW50KTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICRjbGllbnRTcGVjID0gJHRoaXMtPmdldFA0Q2xpZW50U3BlYygpOwogICAgICAgICRmaWxlU3lzdGVtID0gJHRoaXMtPmdldEZpbGVzeXN0ZW0oKTsKICAgICAgICAkZmlsZVN5c3RlbS0+cmVtb3ZlKCRjbGllbnRTcGVjKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICRjb21tYW5kCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kUmVzdWx0ID0gJyc7CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJHRoaXMtPmNvbW1hbmRSZXN1bHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENsaWVudCgpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cDRDbGllbnQpKSB7CiAgICAgICAgICAgICRjbGVhblN0cmVhbU5hbWUgPSBzdHJfcmVwbGFjZShhcnJheSgnLy8nLCAnLycsICdAJyksIGFycmF5KCcnLCAnXycsICcnKSwgJHRoaXMtPmdldFN0cmVhbSgpKTsKICAgICAgICAgICAgJHRoaXMtPnA0Q2xpZW50ID0gJ2NvbXBvc2VyX3BlcmZvcmNlXycgLiAkdGhpcy0+dW5pcXVlUGVyZm9yY2VDbGllbnROYW1lIC4gJ18nIC4gJGNsZWFuU3RyZWFtTmFtZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cDRDbGllbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGF0aCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXRoOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZVBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhdGggPSAkcGF0aDsKICAgICAgICAkZnMgPSAkdGhpcy0+Z2V0RmlsZXN5c3RlbSgpOwogICAgICAgICRmcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRwYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQb3J0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnA0UG9ydDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cmVhbQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3RyZWFtKCRzdHJlYW0pCiAgICB7CiAgICAgICAgJHRoaXMtPnA0U3RyZWFtID0gJHN0cmVhbTsKICAgICAgICAkaW5kZXggPSBzdHJycG9zKCRzdHJlYW0sICcvJyk7CiAgICAgICAgLy9TdHJlYW0gZm9ybWF0IGlzIC8vZGVwb3Qvc3RyZWFtLCB3aGlsZSBub24tc3RyZWFtaW5nIGRlcG90IGlzIC8vZGVwb3QKICAgICAgICBpZiAoJGluZGV4ID4gMikgewogICAgICAgICAgICAkdGhpcy0+cDREZXBvdFR5cGUgPSAnc3RyZWFtJzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU3RyZWFtKCkKICAgIHsKICAgICAgICByZXR1cm4gaXNfc3RyaW5nKCR0aGlzLT5wNERlcG90VHlwZSkgJiYgKHN0cmNtcCgkdGhpcy0+cDREZXBvdFR5cGUsICdzdHJlYW0nKSA9PT0gMCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RyZWFtKCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5wNFN0cmVhbSkpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5pc1N0cmVhbSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cDRTdHJlYW0gPSAnLy8nIC4gJHRoaXMtPnA0RGVwb3QgLiAnLycgLiAkdGhpcy0+cDRCcmFuY2g7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cDRTdHJlYW0gPSAnLy8nIC4gJHRoaXMtPnA0RGVwb3Q7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cDRTdHJlYW07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJlYW0KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RyZWFtV2l0aG91dExhYmVsKCRzdHJlYW0pCiAgICB7CiAgICAgICAgJGluZGV4ID0gc3RycG9zKCRzdHJlYW0sICdAJyk7CiAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRzdHJlYW07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3Vic3RyKCRzdHJlYW0sIDAsICRpbmRleCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIG5vbi1lbXB0eS1zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFA0Q2xpZW50U3BlYygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXRoIC4gJy8nIC4gJHRoaXMtPmdldENsaWVudCgpIC4gJy5wNC5zcGVjJzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVzZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cDRVc2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICR1c2VyCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVc2VyKCR1c2VyKQogICAgewogICAgICAgICR0aGlzLT5wNFVzZXIgPSAkdXNlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcXVlcnlQNFVzZXIoKQogICAgewogICAgICAgICR0aGlzLT5nZXRVc2VyKCk7CiAgICAgICAgaWYgKHN0cmxlbigoc3RyaW5nKSAkdGhpcy0+cDRVc2VyKSA+IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+cDRVc2VyID0gJHRoaXMtPmdldFA0dmFyaWFibGUoJ1A0VVNFUicpOwogICAgICAgIGlmIChzdHJsZW4oKHN0cmluZykgJHRoaXMtPnA0VXNlcikgPiAwKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnA0VXNlciA9ICR0aGlzLT5pby0+YXNrKCdFbnRlciBQNCBVc2VyOicpOwogICAgICAgIGlmICgkdGhpcy0+d2luZG93c0ZsYWcpIHsKICAgICAgICAgICAgJGNvbW1hbmQgPSAncDQgc2V0IFA0VVNFUj0nIC4gJHRoaXMtPnA0VXNlcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29tbWFuZCA9ICdleHBvcnQgUDRVU0VSPScgLiAkdGhpcy0+cDRVc2VyOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICRuYW1lCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFA0dmFyaWFibGUoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT53aW5kb3dzRmxhZykgewogICAgICAgICAgICAkY29tbWFuZCA9ICdwNCBzZXQnOwogICAgICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICAgICAkcmVzdWx0ID0gdHJpbSgkdGhpcy0+Y29tbWFuZFJlc3VsdCk7CiAgICAgICAgICAgICRyZXNBcnJheSA9IGV4cGxvZGUoUEhQX0VPTCwgJHJlc3VsdCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXNBcnJheSBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgJGZpZWxkcyA9IGV4cGxvZGUoJz0nLCAkbGluZSk7CiAgICAgICAgICAgICAgICBpZiAoc3RyY21wKCRuYW1lLCAkZmllbGRzWzBdKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgJGluZGV4ID0gc3RycG9zKCRmaWVsZHNbMV0sICcgJyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gJGZpZWxkc1sxXTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdWJzdHIoJGZpZWxkc1sxXSwgMCwgJGluZGV4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gdHJpbSgkdmFsdWUpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kID0gJ2VjaG8gJCcgLiAkbmFtZTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICRyZXN1bHQgPSB0cmltKCR0aGlzLT5jb21tYW5kUmVzdWx0KTsKCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBxdWVyeVA0UGFzc3dvcmQoKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cDRQYXNzd29yZCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wNFBhc3N3b3JkOwogICAgICAgIH0KICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+Z2V0UDR2YXJpYWJsZSgnUDRQQVNTV0QnKTsKICAgICAgICBpZiAoc3RybGVuKChzdHJpbmcpICRwYXNzd29yZCkgPD0gMCkgewogICAgICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJ0VudGVyIHBhc3N3b3JkIGZvciBQZXJmb3JjZSB1c2VyICcgLiAkdGhpcy0+Z2V0VXNlcigpIC4gJzogJyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5wNFBhc3N3b3JkID0gJHBhc3N3b3JkOwoKICAgICAgICByZXR1cm4gJHBhc3N3b3JkOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkY29tbWFuZAogICAgICogQHBhcmFtIGJvb2wgICAkdXNlQ2xpZW50CiAgICAgKgogICAgICogQHJldHVybiBub24tZW1wdHktc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZVA0Q29tbWFuZCgkY29tbWFuZCwgJHVzZUNsaWVudCA9IHRydWUpCiAgICB7CiAgICAgICAgJHA0Q29tbWFuZCA9ICdwNCAnOwogICAgICAgICRwNENvbW1hbmQgLj0gJy11ICcgLiAkdGhpcy0+Z2V0VXNlcigpIC4gJyAnOwogICAgICAgIGlmICgkdXNlQ2xpZW50KSB7CiAgICAgICAgICAgICRwNENvbW1hbmQgLj0gJy1jICcgLiAkdGhpcy0+Z2V0Q2xpZW50KCkgLiAnICc7CiAgICAgICAgfQogICAgICAgICRwNENvbW1hbmQgLj0gJy1wICcgLiAkdGhpcy0+Z2V0UG9ydCgpIC4gJyAnIC4gJGNvbW1hbmQ7CgogICAgICAgIHJldHVybiAkcDRDb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0xvZ2dlZEluKCkKICAgIHsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnbG9naW4gLXMnLCBmYWxzZSk7CiAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICBpZiAoJGV4aXRDb2RlKSB7CiAgICAgICAgICAgICRlcnJvck91dHB1dCA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAkaW5kZXggPSBzdHJwb3MoJGVycm9yT3V0cHV0LCAkdGhpcy0+Z2V0VXNlcigpKTsKICAgICAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICRpbmRleCA9IHN0cnBvcygkZXJyb3JPdXRwdXQsICdwNCcpOwogICAgICAgICAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigncDQgY29tbWFuZCBub3QgZm91bmQgaW4gcGF0aDogJyAuICRlcnJvck91dHB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oJ0ludmFsaWQgdXNlciBuYW1lOiAnIC4gJHRoaXMtPmdldFVzZXIoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29ubmVjdENsaWVudCgpCiAgICB7CiAgICAgICAgJHA0Q3JlYXRlQ2xpZW50Q29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgKICAgICAgICAgICAgJ2NsaWVudCAtaSA8ICcgLiBzdHJfcmVwbGFjZSgiICIsICJcXCAiLCAkdGhpcy0+Z2V0UDRDbGllbnRTcGVjKCkpCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJHA0Q3JlYXRlQ2xpZW50Q29tbWFuZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHNvdXJjZVJlZmVyZW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3luY0NvZGVCYXNlKCRzb3VyY2VSZWZlcmVuY2UpCiAgICB7CiAgICAgICAgJHByZXZEaXIgPSBnZXRjd2QoKTsKICAgICAgICBjaGRpcigkdGhpcy0+cGF0aCk7CiAgICAgICAgJHA0U3luY0NvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJ3N5bmMgLWYgJyk7CiAgICAgICAgaWYgKG51bGwgIT09ICRzb3VyY2VSZWZlcmVuY2UpIHsKICAgICAgICAgICAgJHA0U3luY0NvbW1hbmQgLj0gJ0AnIC4gJHNvdXJjZVJlZmVyZW5jZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRwNFN5bmNDb21tYW5kKTsKICAgICAgICBjaGRpcigkcHJldkRpcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8ZmFsc2UgJHNwZWMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlQ2xpZW50U3BlY1RvRmlsZSgkc3BlYykKICAgIHsKICAgICAgICBmd3JpdGUoJHNwZWMsICdDbGllbnQ6ICcgLiAkdGhpcy0+Z2V0Q2xpZW50KCkgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnVXBkYXRlOiAnIC4gZGF0ZSgnWS9tL2QgSDppOnMnKSAuIFBIUF9FT0wgLiBQSFBfRU9MKTsKICAgICAgICBmd3JpdGUoJHNwZWMsICdBY2Nlc3M6ICcgLiBkYXRlKCdZL20vZCBIOmk6cycpIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnT3duZXI6ICAnIC4gJHRoaXMtPmdldFVzZXIoKSAuIFBIUF9FT0wgLiBQSFBfRU9MKTsKICAgICAgICBmd3JpdGUoJHNwZWMsICdEZXNjcmlwdGlvbjonIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnICBDcmVhdGVkIGJ5ICcgLiAkdGhpcy0+Z2V0VXNlcigpIC4gJyBmcm9tIGNvbXBvc2VyLicgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnUm9vdDogJyAuICR0aGlzLT5nZXRQYXRoKCkgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnT3B0aW9uczogIG5vYWxsd3JpdGUgbm9jbG9iYmVyIG5vY29tcHJlc3MgdW5sb2NrZWQgbW9kdGltZSBybWRpcicgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnU3VibWl0T3B0aW9uczogIHJldmVydHVuY2hhbmdlZCcgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnTGluZUVuZDogIGxvY2FsJyAuIFBIUF9FT0wgLiBQSFBfRU9MKTsKICAgICAgICBpZiAoJHRoaXMtPmlzU3RyZWFtKCkpIHsKICAgICAgICAgICAgZndyaXRlKCRzcGVjLCAnU3RyZWFtOicgLiBQSFBfRU9MKTsKICAgICAgICAgICAgZndyaXRlKCRzcGVjLCAnICAnIC4gJHRoaXMtPmdldFN0cmVhbVdpdGhvdXRMYWJlbCgkdGhpcy0+cDRTdHJlYW0pIC4gUEhQX0VPTCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZndyaXRlKAogICAgICAgICAgICAgICAgJHNwZWMsCiAgICAgICAgICAgICAgICAnVmlldzogICcgLiAkdGhpcy0+Z2V0U3RyZWFtKCkgLiAnLy4uLiAgLy8nIC4gJHRoaXMtPmdldENsaWVudCgpIC4gJy8uLi4gJyAuIFBIUF9FT0wKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlUDRDbGllbnRTcGVjKCkKICAgIHsKICAgICAgICAkY2xpZW50U3BlYyA9ICR0aGlzLT5nZXRQNENsaWVudFNwZWMoKTsKICAgICAgICAkc3BlYyA9IGZvcGVuKCRjbGllbnRTcGVjLCAndycpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZUNsaWVudFNwZWNUb0ZpbGUoJHNwZWMpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgZmNsb3NlKCRzcGVjKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgICAgIGZjbG9zZSgkc3BlYyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJHBpcGUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcmVhZCgkcGlwZSwgJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKGZlb2YoJHBpcGUpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJGxpbmUgPSBmZ2V0cygkcGlwZSk7CiAgICAgICAgd2hpbGUgKCRsaW5lICE9PSBmYWxzZSkgewogICAgICAgICAgICAkbGluZSA9IGZnZXRzKCRwaXBlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHBhc3N3b3JkCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdpbmRvd3NMb2dpbigkcGFzc3dvcmQpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJyBsb2dpbiAtYScpOwoKICAgICAgICAvLyBUT0RPIGluIHYzIGdlbmVyYXRlIGNvbW1hbmQgYXMgYW4gYXJyYXkKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygnU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzJywgJ2Zyb21TaGVsbENvbW1hbmRsaW5lJykpIHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBQcm9jZXNzOjpmcm9tU2hlbGxDb21tYW5kbGluZSgkY29tbWFuZCwgbnVsbCwgbnVsbCwgJHBhc3N3b3JkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBAcGhwc3Rhbi1pZ25vcmUtbmV4dC1saW5lCiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3MoJGNvbW1hbmQsIG51bGwsIG51bGwsICRwYXNzd29yZCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByb2Nlc3MtPnJ1bigpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwNExvZ2luKCkKICAgIHsKICAgICAgICAkdGhpcy0+cXVlcnlQNFVzZXIoKTsKICAgICAgICBpZiAoISR0aGlzLT5pc0xvZ2dlZEluKCkpIHsKICAgICAgICAgICAgJHBhc3N3b3JkID0gJHRoaXMtPnF1ZXJ5UDRQYXNzd29yZCgpOwogICAgICAgICAgICBpZiAoJHRoaXMtPndpbmRvd3NGbGFnKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d2luZG93c0xvZ2luKCRwYXNzd29yZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29tbWFuZCA9ICdlY2hvICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGFzc3dvcmQpICAuICcgfCAnIC4gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCcgbG9naW4gLWEnLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICAgICAgICAgaWYgKCRleGl0Q29kZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJFcnJvciBsb2dnaW5nIGluOiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZHx2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICRjb21wb3NlckZpbGVDb250ZW50ID0gJHRoaXMtPmdldEZpbGVDb250ZW50KCdjb21wb3Nlci5qc29uJywgJGlkZW50aWZpZXIpOwoKICAgICAgICBpZiAoISRjb21wb3NlckZpbGVDb250ZW50KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBqc29uX2RlY29kZSgkY29tcG9zZXJGaWxlQ29udGVudCwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgICRwYXRoID0gJHRoaXMtPmdldEZpbGVQYXRoKCRmaWxlLCAkaWRlbnRpZmllcik7CgogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCcgcHJpbnQgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKSk7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CgogICAgICAgIGlmICghdHJpbSgkcmVzdWx0KSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVQYXRoKCRmaWxlLCAkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAkaW5kZXggPSBzdHJwb3MoJGlkZW50aWZpZXIsICdAJyk7CiAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRpZGVudGlmaWVyLiAnLycgLiAkZmlsZTsKICAgICAgICB9CgogICAgICAgICRwYXRoID0gc3Vic3RyKCRpZGVudGlmaWVyLCAwLCAkaW5kZXgpIC4gJy8nIC4gJGZpbGUgLiBzdWJzdHIoJGlkZW50aWZpZXIsICRpbmRleCk7CiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJyBmaWxlcyAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhdGgpLCBmYWxzZSk7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CiAgICAgICAgJGluZGV4MiA9IHN0cnBvcygkcmVzdWx0LCAnbm8gc3VjaCBmaWxlKHMpLicpOwogICAgICAgIGlmICgkaW5kZXgyID09PSBmYWxzZSkgewogICAgICAgICAgICAkaW5kZXgzID0gc3RycG9zKCRyZXN1bHQsICdjaGFuZ2UnKTsKICAgICAgICAgICAgaWYgKCRpbmRleDMgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkcGhyYXNlID0gdHJpbShzdWJzdHIoJHJlc3VsdCwgJGluZGV4MykpOwogICAgICAgICAgICAgICAgJGZpZWxkcyA9IGV4cGxvZGUoJyAnLCAkcGhyYXNlKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gc3Vic3RyKCRpZGVudGlmaWVyLCAwLCAkaW5kZXgpIC4gJy8nIC4gJGZpbGUgLiAnQCcgLiAkZmllbGRzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXl7bWFzdGVyOiBzdHJpbmd9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgJHBvc3NpYmxlQnJhbmNoZXMgPSBhcnJheSgpOwogICAgICAgIGlmICghJHRoaXMtPmlzU3RyZWFtKCkpIHsKICAgICAgICAgICAgJHBvc3NpYmxlQnJhbmNoZXNbJHRoaXMtPnA0QnJhbmNoXSA9ICR0aGlzLT5nZXRTdHJlYW0oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnc3RyZWFtcyAnLlByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCcvLycgLiAkdGhpcy0+cDREZXBvdCAuICcvLi4uJykpOwogICAgICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CiAgICAgICAgICAgICRyZXNBcnJheSA9IGV4cGxvZGUoUEhQX0VPTCwgJHJlc3VsdCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXNBcnJheSBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgJHJlc0JpdHMgPSBleHBsb2RlKCcgJywgJGxpbmUpOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRyZXNCaXRzKSA+IDQpIHsKICAgICAgICAgICAgICAgICAgICAkYnJhbmNoID0gUHJlZzo6cmVwbGFjZSgnL1teQS1aYS16MC05IF0vJywgJycsICRyZXNCaXRzWzRdKTsKICAgICAgICAgICAgICAgICAgICAkcG9zc2libGVCcmFuY2hlc1skYnJhbmNoXSA9ICRyZXNCaXRzWzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCdjaGFuZ2VzICcuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0aGlzLT5nZXRTdHJlYW0oKSAuICcvLi4uJyksIGZhbHNlKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y29tbWFuZFJlc3VsdDsKICAgICAgICAkcmVzQXJyYXkgPSBleHBsb2RlKFBIUF9FT0wsICRyZXN1bHQpOwogICAgICAgICRsYXN0Q29tbWl0ID0gJHJlc0FycmF5WzBdOwogICAgICAgICRsYXN0Q29tbWl0QXJyID0gZXhwbG9kZSgnICcsICRsYXN0Q29tbWl0KTsKICAgICAgICAkbGFzdENvbW1pdE51bSA9ICRsYXN0Q29tbWl0QXJyWzFdOwoKICAgICAgICByZXR1cm4gYXJyYXkoJ21hc3RlcicgPT4gJHBvc3NpYmxlQnJhbmNoZXNbJHRoaXMtPnA0QnJhbmNoXSAuICdAJy4gJGxhc3RDb21taXROdW0pOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhZ3MoKQogICAgewogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCdsYWJlbHMnKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y29tbWFuZFJlc3VsdDsKICAgICAgICAkcmVzQXJyYXkgPSBleHBsb2RlKFBIUF9FT0wsICRyZXN1bHQpOwogICAgICAgICR0YWdzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVzQXJyYXkgYXMgJGxpbmUpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygkbGluZSwgJ0xhYmVsJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkZmllbGRzID0gZXhwbG9kZSgnICcsICRsaW5lKTsKICAgICAgICAgICAgICAgICR0YWdzWyRmaWVsZHNbMV1dID0gJHRoaXMtPmdldFN0cmVhbSgpIC4gJ0AnIC4gJGZpZWxkc1sxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0YWdzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVja1N0cmVhbSgpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJ2RlcG90cycsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y29tbWFuZFJlc3VsdDsKICAgICAgICAkcmVzQXJyYXkgPSBleHBsb2RlKFBIUF9FT0wsICRyZXN1bHQpOwogICAgICAgIGZvcmVhY2ggKCRyZXNBcnJheSBhcyAkbGluZSkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRsaW5lLCAnRGVwb3QnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICRmaWVsZHMgPSBleHBsb2RlKCcgJywgJGxpbmUpOwogICAgICAgICAgICAgICAgaWYgKHN0cmNtcCgkdGhpcy0+cDREZXBvdCwgJGZpZWxkc1sxXSkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cDREZXBvdFR5cGUgPSAkZmllbGRzWzNdOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmlzU3RyZWFtKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAkcmVmZXJlbmNlCiAgICAgKiBAcmV0dXJuIG1peGVkfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENoYW5nZUxpc3QoJHJlZmVyZW5jZSkKICAgIHsKICAgICAgICAkaW5kZXggPSBzdHJwb3MoJHJlZmVyZW5jZSwgJ0AnKTsKICAgICAgICBpZiAoJGluZGV4ID09PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJGxhYmVsID0gc3Vic3RyKCRyZWZlcmVuY2UsICRpbmRleCk7CiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJyBjaGFuZ2VzIC1tMSAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGxhYmVsKSk7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkY2hhbmdlcyA9ICR0aGlzLT5jb21tYW5kUmVzdWx0OwogICAgICAgIGlmIChzdHJwb3MoJGNoYW5nZXMsICdDaGFuZ2UnKSAhPT0gMCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJGZpZWxkcyA9IGV4cGxvZGUoJyAnLCAkY2hhbmdlcyk7CgogICAgICAgIHJldHVybiAkZmllbGRzWzFdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICRmcm9tUmVmZXJlbmNlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgJHRvUmVmZXJlbmNlCiAgICAgKiBAcmV0dXJuIG1peGVkfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSkKICAgIHsKICAgICAgICAkZnJvbUNoYW5nZUxpc3QgPSAkdGhpcy0+Z2V0Q2hhbmdlTGlzdCgkZnJvbVJlZmVyZW5jZSk7CiAgICAgICAgaWYgKCRmcm9tQ2hhbmdlTGlzdCA9PT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJHRvQ2hhbmdlTGlzdCA9ICR0aGlzLT5nZXRDaGFuZ2VMaXN0KCR0b1JlZmVyZW5jZSk7CiAgICAgICAgaWYgKCR0b0NoYW5nZUxpc3QgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICRpbmRleCA9IHN0cnBvcygkZnJvbVJlZmVyZW5jZSwgJ0AnKTsKICAgICAgICAkbWFpbiA9IHN1YnN0cigkZnJvbVJlZmVyZW5jZSwgMCwgJGluZGV4KSAuICcvLi4uJzsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnZmlsZWxvZyAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJG1haW4gLiAnQCcgLiAkZnJvbUNoYW5nZUxpc3QuICcsJyAuICR0b0NoYW5nZUxpc3QpKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEZpbGVzeXN0ZW0KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVzeXN0ZW0oKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+ZmlsZXN5c3RlbSkgewogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9IG5ldyBGaWxlc3lzdGVtKCR0aGlzLT5wcm9jZXNzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZXN5c3RlbTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RmlsZXN5c3RlbShGaWxlc3lzdGVtICRmcykKICAgIHsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIENvbnZlcnQgUEhQIGVycm9ycyBpbnRvIGV4Y2VwdGlvbnMKICoKICogQGF1dGhvciBBcnRlbSBMb3BhdGEgPGJpb3pzaG9ja0BnbWFpbC5jb20+CiAqLwpjbGFzcyBFcnJvckhhbmRsZXIKewogICAgLyoqIEB2YXIgP0lPSW50ZXJmYWNlICovCiAgICBwcml2YXRlIHN0YXRpYyAkaW87CgogICAgLyoqCiAgICAgKiBFcnJvciBoYW5kbGVyCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAkbGV2ZWwgICBMZXZlbCBvZiB0aGUgZXJyb3IgcmFpc2VkCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIEVycm9yIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgICAgRmlsZW5hbWUgdGhhdCB0aGUgZXJyb3Igd2FzIHJhaXNlZCBpbgogICAgICogQHBhcmFtIGludCAgICAkbGluZSAgICBMaW5lIG51bWJlciB0aGUgZXJyb3Igd2FzIHJhaXNlZCBhdAogICAgICoKICAgICAqIEBzdGF0aWMKICAgICAqIEB0aHJvd3MgXEVycm9yRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYW5kbGUoJGxldmVsLCAkbWVzc2FnZSwgJGZpbGUsICRsaW5lKQogICAgewogICAgICAgIC8vIGVycm9yIGNvZGUgaXMgbm90IGluY2x1ZGVkIGluIGVycm9yX3JlcG9ydGluZwogICAgICAgIGlmICghKGVycm9yX3JlcG9ydGluZygpICYgJGxldmVsKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChmaWx0ZXJfdmFyKGluaV9nZXQoJ3hkZWJ1Zy5zY3JlYW0nKSwgRklMVEVSX1ZBTElEQVRFX0JPT0xFQU4pKSB7CiAgICAgICAgICAgICRtZXNzYWdlIC49ICJcblxuV2FybmluZzogWW91IGhhdmUgeGRlYnVnLnNjcmVhbSBlbmFibGVkLCB0aGUgd2FybmluZyBhYm92ZSBtYXkgYmUiLgogICAgICAgICAgICAiXG5hIGxlZ2l0aW1hdGVseSBzdXBwcmVzc2VkIGVycm9yIHRoYXQgeW91IHdlcmUgbm90IHN1cHBvc2VkIHRvIHNlZS4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsZXZlbCAhPT0gRV9ERVBSRUNBVEVEICYmICRsZXZlbCAhPT0gRV9VU0VSX0RFUFJFQ0FURUQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxFcnJvckV4Y2VwdGlvbigkbWVzc2FnZSwgMCwgJGxldmVsLCAkZmlsZSwgJGxpbmUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6OiRpbykgewogICAgICAgICAgICAvLyBpZ25vcmUgc3ltZm9ueS8qIGRlcHJlY2F0aW9uIHdhcm5pbmdzCiAgICAgICAgICAgIC8vIFRPRE8gcmVtb3ZlIGluIDIuMwogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15SZXR1cm4gdHlwZSBvZiBTeW1mb255XFxcXC4qUmV0dXJuVHlwZVdpbGxDaGFuZ2V9aXMnLCAkbWVzc2FnZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdHJwb3Moc3RydHIoJGZpbGUsICdcXCcsICcvJyksICd2ZW5kb3Ivc3ltZm9ueS8nKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzZWxmOjokaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkRlcHJlY2F0aW9uIE5vdGljZTogJy4kbWVzc2FnZS4nIGluICcuJGZpbGUuJzonLiRsaW5lLic8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIGlmIChzZWxmOjokaW8tPmlzVmVyYm9zZSgpKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlN0YWNrIHRyYWNlOjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgIHNlbGY6OiRpby0+d3JpdGVFcnJvcihhcnJheV9maWx0ZXIoYXJyYXlfbWFwKGZ1bmN0aW9uICgkYSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYVsnbGluZSddLCAkYVsnZmlsZSddKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzx3YXJuaW5nPiAnLiRhWydmaWxlJ10uJzonLiRhWydsaW5lJ10uJzwvd2FybmluZz4nOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9LCBhcnJheV9zbGljZShkZWJ1Z19iYWNrdHJhY2UoKSwgMikpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXIgZXJyb3IgaGFuZGxlci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2V8bnVsbCAkaW8KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZWdpc3RlcihJT0ludGVyZmFjZSAkaW8gPSBudWxsKQogICAgewogICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKGFycmF5KF9fQ0xBU1NfXywgJ2hhbmRsZScpKTsKICAgICAgICBlcnJvcl9yZXBvcnRpbmcoRV9BTEwgfCBFX1NUUklDVCk7CiAgICAgICAgc2VsZjo6JGlvID0gJGlvOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogQGF1dGhvciBUaWxsIEtsYW1wYWVja2VsIDx0aWxsQHBocC5uZXQ+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFN2bgp7CiAgICBjb25zdCBNQVhfUVRZX0FVVEhfVFJJRVMgPSA1OwoKICAgIC8qKgogICAgICogQHZhciA/YXJyYXl7dXNlcm5hbWU6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZ30KICAgICAqLwogICAgcHJvdGVjdGVkICRjcmVkZW50aWFsczsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGhhc0F1dGg7CgogICAgLyoqCiAgICAgKiBAdmFyIFxDb21wb3NlclxJT1xJT0ludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGlvOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICR1cmw7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRjYWNoZUNyZWRlbnRpYWxzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKCiAgICAvKioKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcXR5QXV0aFRyaWVzID0gMDsKCiAgICAvKioKICAgICAqIEB2YXIgXENvbXBvc2VyXENvbmZpZwogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHZlcnNpb247CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICR1cmwKICAgICAqIEBwYXJhbSBcQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gQ29uZmlnICAgICAgICAgICAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSBQcm9jZXNzRXhlY3V0b3IgICAgICAgICAgJHByb2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR1cmwsIElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnVybCA9ICR1cmw7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2xlYW5FbnYoKQogICAgewogICAgICAgIC8vIGNsZWFuIHVwIGVudiBmb3IgT1NYLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy8yMTQ2I2lzc3VlY29tbWVudC0zNTQ3ODk0MAogICAgICAgIFBsYXRmb3JtOjpjbGVhckVudignRFlMRF9MSUJSQVJZX1BBVEgnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGUgYW4gU1ZOIHJlbW90ZSBjb21tYW5kIGFuZCB0cnkgdG8gZml4IHVwIHRoZSBwcm9jZXNzIHdpdGggY3JlZGVudGlhbHMKICAgICAqIGlmIG5lY2Vzc2FyeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tYW5kIFNWTiBjb21tYW5kIHRvIHJ1bgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsICAgICBTVk4gdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjd2QgICAgIFdvcmtpbmcgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoICAgIFRhcmdldCBmb3IgYSBjaGVja291dAogICAgICogQHBhcmFtIGJvb2wgICAkdmVyYm9zZSBPdXRwdXQgYWxsIG91dHB1dCB0byB0aGUgdXNlcgogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlKCRjb21tYW5kLCAkdXJsLCAkY3dkID0gbnVsbCwgJHBhdGggPSBudWxsLCAkdmVyYm9zZSA9IGZhbHNlKQogICAgewogICAgICAgIC8vIEVuc3VyZSB3ZSBhcmUgYWxsb3dlZCB0byB1c2UgdGhpcyBVUkwgYnkgY29uZmlnCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdXJsLCAkdGhpcy0+aW8pOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4ZWN1dGVXaXRoQXV0aFJldHJ5KCRjb21tYW5kLCAkY3dkLCAkdXJsLCAkcGF0aCwgJHZlcmJvc2UpOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZSBhbiBTVk4gbG9jYWwgY29tbWFuZCBhbmQgdHJ5IHRvIGZpeCB1cCB0aGUgcHJvY2VzcyB3aXRoIGNyZWRlbnRpYWxzCiAgICAgKiBpZiBuZWNlc3NhcnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29tbWFuZCBTVk4gY29tbWFuZCB0byBydW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggICAgUGF0aCBhcmd1bWVudCBwYXNzZWQgdGhydSB0byB0aGUgY29tbWFuZAogICAgICogQHBhcmFtIHN0cmluZyAkY3dkICAgICBXb3JraW5nIGRpcmVjdG9yeQogICAgICogQHBhcmFtIGJvb2wgICAkdmVyYm9zZSBPdXRwdXQgYWxsIG91dHB1dCB0byB0aGUgdXNlcgogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlTG9jYWwoJGNvbW1hbmQsICRwYXRoLCAkY3dkID0gbnVsbCwgJHZlcmJvc2UgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBBIGxvY2FsIGNvbW1hbmQgaGFzIG5vIHJlbW90ZSB1cmwKICAgICAgICByZXR1cm4gJHRoaXMtPmV4ZWN1dGVXaXRoQXV0aFJldHJ5KCRjb21tYW5kLCAkY3dkLCAnJywgJHBhdGgsICR2ZXJib3NlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzdm5Db21tYW5kCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkY3dkCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aAogICAgICogQHBhcmFtICBib29sICAgJHZlcmJvc2UKICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBleGVjdXRlV2l0aEF1dGhSZXRyeSgkc3ZuQ29tbWFuZCwgJGN3ZCwgJHVybCwgJHBhdGgsICR2ZXJib3NlKQogICAgewogICAgICAgIC8vIFJlZ2VuZXJhdGUgdGhlIGNvbW1hbmQgYXQgZWFjaCB0cnksIHRvIHVzZSB0aGUgbmV3bHkgdXNlci1wcm92aWRlZCBjcmVkZW50aWFscwogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdldENvbW1hbmQoJHN2bkNvbW1hbmQsICR1cmwsICRwYXRoKTsKCiAgICAgICAgJG91dHB1dCA9IG51bGw7CiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICRoYW5kbGVyID0gZnVuY3Rpb24gKCR0eXBlLCAkYnVmZmVyKSB1c2UgKCYkb3V0cHV0LCAkaW8sICR2ZXJib3NlKSB7CiAgICAgICAgICAgIGlmICgkdHlwZSAhPT0gJ291dCcpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdHJwb3MoJGJ1ZmZlciwgJ1JlZGlyZWN0aW5nIHRvIFVSTCAnKSA9PT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG91dHB1dCAuPSAkYnVmZmVyOwogICAgICAgICAgICBpZiAoJHZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigkYnVmZmVyLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgICRzdGF0dXMgPSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGhhbmRsZXIsICRjd2QpOwogICAgICAgIGlmICgwID09PSAkc3RhdHVzKSB7CiAgICAgICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgICAgIH0KCiAgICAgICAgJGVycm9yT3V0cHV0ID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgJGZ1bGxPdXRwdXQgPSBpbXBsb2RlKCJcbiIsIGFycmF5KCRvdXRwdXQsICRlcnJvck91dHB1dCkpOwoKICAgICAgICAvLyB0aGUgZXJyb3IgaXMgbm90IGF1dGgtcmVsYXRlZAogICAgICAgIGlmIChmYWxzZSA9PT0gc3RyaXBvcygkZnVsbE91dHB1dCwgJ0NvdWxkIG5vdCBhdXRoZW50aWNhdGUgdG8gc2VydmVyOicpCiAgICAgICAgICAgICYmIGZhbHNlID09PSBzdHJpcG9zKCRmdWxsT3V0cHV0LCAnYXV0aG9yaXphdGlvbiBmYWlsZWQnKQogICAgICAgICAgICAmJiBmYWxzZSA9PT0gc3RyaXBvcygkZnVsbE91dHB1dCwgJ3N2bjogRTE3MDAwMTonKQogICAgICAgICAgICAmJiBmYWxzZSA9PT0gc3RyaXBvcygkZnVsbE91dHB1dCwgJ3N2bjogRTIxNTAwNDonKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGZ1bGxPdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+aGFzQXV0aCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5kb0F1dGhEYW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgLy8gdHJ5IHRvIGF1dGhlbnRpY2F0ZSBpZiBtYXhpbXVtIHF1YW50aXR5IG9mIHRyaWVzIG5vdCByZWFjaGVkCiAgICAgICAgaWYgKCR0aGlzLT5xdHlBdXRoVHJpZXMrKyA8IHNlbGY6Ok1BWF9RVFlfQVVUSF9UUklFUykgewogICAgICAgICAgICAvLyByZXN0YXJ0IHRoZSBwcm9jZXNzCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXhlY3V0ZVdpdGhBdXRoUmV0cnkoJHN2bkNvbW1hbmQsICRjd2QsICR1cmwsICRwYXRoLCAkdmVyYm9zZSk7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICd3cm9uZyBjcmVkZW50aWFscyBwcm92aWRlZCAoJy4kZnVsbE91dHB1dC4nKScKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sICRjYWNoZUNyZWRlbnRpYWxzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENhY2hlQ3JlZGVudGlhbHMoJGNhY2hlQ3JlZGVudGlhbHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMgPSAkY2FjaGVDcmVkZW50aWFsczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcG9zaXRvcmllcyByZXF1ZXN0cyBjcmVkZW50aWFscywgbGV0J3MgcHV0IHRoZW0gaW4uCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBcQ29tcG9zZXJcVXRpbFxTdm4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvQXV0aERhbmNlKCkKICAgIHsKICAgICAgICAvLyBjYW5ub3QgYXNrIGZvciBjcmVkZW50aWFscyBpbiBub24gaW50ZXJhY3RpdmUgbW9kZQogICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgJ2NhbiBub3QgYXNrIGZvciBhdXRoZW50aWNhdGlvbiBpbiBub24gaW50ZXJhY3RpdmUgbW9kZScKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiVGhlIFN1YnZlcnNpb24gc2VydmVyICh7JHRoaXMtPnVybH0pIHJlcXVlc3RlZCBjcmVkZW50aWFsczoiKTsKCiAgICAgICAgJHRoaXMtPmhhc0F1dGggPSB0cnVlOwogICAgICAgICR0aGlzLT5jcmVkZW50aWFscyA9IGFycmF5KAogICAgICAgICAgICAndXNlcm5hbWUnID0+IChzdHJpbmcpICR0aGlzLT5pby0+YXNrKCJVc2VybmFtZTogIiwgJycpLAogICAgICAgICAgICAncGFzc3dvcmQnID0+IChzdHJpbmcpICR0aGlzLT5pby0+YXNrQW5kSGlkZUFuc3dlcigiUGFzc3dvcmQ6ICIpLAogICAgICAgICk7CgogICAgICAgICR0aGlzLT5jYWNoZUNyZWRlbnRpYWxzID0gJHRoaXMtPmlvLT5hc2tDb25maXJtYXRpb24oIlNob3VsZCBTdWJ2ZXJzaW9uIGNhY2hlIHRoZXNlIGNyZWRlbnRpYWxzPyAoeWVzL25vKSAiKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQSBtZXRob2QgdG8gY3JlYXRlIHRoZSBzdm4gY29tbWFuZHMgcnVuLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNtZCAgVXN1YWxseSAnc3ZuIGxzJyBvciBzb21ldGhpbmcgbGlrZSB0aGF0LgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsICBSZXBvIFVSTC4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggVGFyZ2V0IGZvciBhIGNoZWNrb3V0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1hbmQoJGNtZCwgJHVybCwgJHBhdGggPSBudWxsKQogICAgewogICAgICAgICRjbWQgPSBzcHJpbnRmKAogICAgICAgICAgICAnJXMgJXMlcyAtLSAlcycsCiAgICAgICAgICAgICRjbWQsCiAgICAgICAgICAgICctLW5vbi1pbnRlcmFjdGl2ZSAnLAogICAgICAgICAgICAkdGhpcy0+Z2V0Q3JlZGVudGlhbFN0cmluZygpLAogICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKQogICAgICAgICk7CgogICAgICAgIGlmICgkcGF0aCkgewogICAgICAgICAgICAkY21kIC49ICcgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY21kOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjcmVkZW50aWFsIHN0cmluZyBmb3IgdGhlIHN2biBjb21tYW5kLgogICAgICoKICAgICAqIEFkZHMgLS1uby1hdXRoLWNhY2hlIHdoZW4gY3JlZGVudGlhbHMgYXJlIHByZXNlbnQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENyZWRlbnRpYWxTdHJpbmcoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc0F1dGgoKSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZigKICAgICAgICAgICAgJyAlcy0tdXNlcm5hbWUgJXMgLS1wYXNzd29yZCAlcyAnLAogICAgICAgICAgICAkdGhpcy0+Z2V0QXV0aENhY2hlKCksCiAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0aGlzLT5nZXRVc2VybmFtZSgpKSwKICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRoaXMtPmdldFBhc3N3b3JkKCkpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgcGFzc3dvcmQgZm9yIHRoZSBzdm4gY29tbWFuZC4gQ2FuIGJlIGVtcHR5LgogICAgICoKICAgICAqIEB0aHJvd3MgXExvZ2ljRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGFzc3dvcmQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y3JlZGVudGlhbHMgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbigiTm8gc3ZuIGF1dGggZGV0ZWN0ZWQuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWRlbnRpYWxzWydwYXNzd29yZCddOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB1c2VybmFtZSBmb3IgdGhlIHN2biBjb21tYW5kLgogICAgICoKICAgICAqIEB0aHJvd3MgXExvZ2ljRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0VXNlcm5hbWUoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y3JlZGVudGlhbHMgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbigiTm8gc3ZuIGF1dGggZGV0ZWN0ZWQuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWRlbnRpYWxzWyd1c2VybmFtZSddOwogICAgfQoKICAgIC8qKgogICAgICogRGV0ZWN0IFN2biBBdXRoLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaGFzQXV0aCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5oYXNBdXRoKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aDsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJHRoaXMtPmNyZWF0ZUF1dGhGcm9tQ29uZmlnKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmNyZWF0ZUF1dGhGcm9tVXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKGJvb2wpICR0aGlzLT5oYXNBdXRoOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBuby1hdXRoLWNhY2hlIHN3aXRjaC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0QXV0aENhY2hlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMgPyAnJyA6ICctLW5vLWF1dGgtY2FjaGUgJzsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSB0aGUgYXV0aCBwYXJhbXMgZnJvbSB0aGUgY29uZmlndXJhdGlvbiBmaWxlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZUF1dGhGcm9tQ29uZmlnKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5jb25maWctPmhhcygnaHR0cC1iYXNpYycpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGF1dGhDb25maWcgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2h0dHAtYmFzaWMnKTsKCiAgICAgICAgJGhvc3QgPSBwYXJzZV91cmwoJHRoaXMtPnVybCwgUEhQX1VSTF9IT1NUKTsKICAgICAgICBpZiAoaXNzZXQoJGF1dGhDb25maWdbJGhvc3RdKSkgewogICAgICAgICAgICAkdGhpcy0+Y3JlZGVudGlhbHMgPSBhcnJheSgKICAgICAgICAgICAgICAgICd1c2VybmFtZScgPT4gJGF1dGhDb25maWdbJGhvc3RdWyd1c2VybmFtZSddLAogICAgICAgICAgICAgICAgJ3Bhc3N3b3JkJyA9PiAkYXV0aENvbmZpZ1skaG9zdF1bJ3Bhc3N3b3JkJ10sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmhhc0F1dGggPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNBdXRoID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgdGhlIGF1dGggcGFyYW1zIGZyb20gdGhlIHVybAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZUF1dGhGcm9tVXJsKCkKICAgIHsKICAgICAgICAkdXJpID0gcGFyc2VfdXJsKCR0aGlzLT51cmwpOwogICAgICAgIGlmIChlbXB0eSgkdXJpWyd1c2VyJ10pKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNyZWRlbnRpYWxzID0gYXJyYXkoCiAgICAgICAgICAgICd1c2VybmFtZScgPT4gJHVyaVsndXNlciddLAogICAgICAgICAgICAncGFzc3dvcmQnID0+ICFlbXB0eSgkdXJpWydwYXNzJ10pID8gJHVyaVsncGFzcyddIDogJycsCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNBdXRoID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgdGhlIHN2biBiaW5hcnkgY29udGFpbmVkIGluIFBBVEgKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBiaW5hcnlWZXJzaW9uKCkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiR2ZXJzaW9uKSB7CiAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnc3ZuIC0tdmVyc2lvbicsICRvdXRwdXQpKSB7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgneyhcZCsoPzpcLlxkKykrKX0nLCAkb3V0cHV0LCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgc2VsZjo6JHZlcnNpb24gPSAkbWF0Y2hbMV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokdmVyc2lvbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgUm9zaGFuIEdhdXRhbSA8cm9zaGFuLmdhdXRhbUBob3RtYWlsLmNvbT4KICovCmNsYXNzIEdpdExhYgp7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAkaW8gICAgICAgICAgICAgVGhlIElPIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gQ29uZmlnICAgICAgICAgICRjb25maWcgICAgICAgICBUaGUgY29tcG9zZXIgY29uZmlndXJhdGlvbgogICAgICogQHBhcmFtIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyAgICAgICAgUHJvY2VzcyBpbnN0YW5jZSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICogQHBhcmFtIEh0dHBEb3dubG9hZGVyICAkaHR0cERvd25sb2FkZXIgUmVtb3RlIEZpbGVzeXN0ZW0sIGluamVjdGFibGUgZm9yIG1vY2tpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlciA/OiBGYWN0b3J5OjpjcmVhdGVIdHRwRG93bmxvYWRlcigkdGhpcy0+aW8sICRjb25maWcpOwogICAgfQoKICAgIC8qKgogICAgICogQXR0ZW1wdHMgdG8gYXV0aG9yaXplIGEgR2l0TGFiIGRvbWFpbiB2aWEgT0F1dGguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luVXJsIFRoZSBob3N0IHRoaXMgR2l0TGFiIGluc3RhbmNlIGlzIGxvY2F0ZWQgYXQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aCgkb3JpZ2luVXJsKQogICAgewogICAgICAgIC8vIGJlZm9yZSBjb21wb3NlciAxLjksIG9yaWdpbiBVUkxzIGhhZCBubyBwb3J0IG51bWJlciBpbiB0aGVtCiAgICAgICAgJGJjT3JpZ2luVXJsID0gUHJlZzo6cmVwbGFjZSgnezpcZCt9JywgJycsICRvcmlnaW5VcmwpOwoKICAgICAgICBpZiAoIWluX2FycmF5KCRvcmlnaW5VcmwsICR0aGlzLT5jb25maWctPmdldCgnZ2l0bGFiLWRvbWFpbnMnKSwgdHJ1ZSkgJiYgIWluX2FycmF5KCRiY09yaWdpblVybCwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBhdmFpbGFibGUgdXNlIHRva2VuIGZyb20gZ2l0IGNvbmZpZwogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNvbmZpZyBnaXRsYWIuYWNjZXNzdG9rZW4nLCAkb3V0cHV0KSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW5VcmwsIHRyaW0oJG91dHB1dCksICdvYXV0aDInKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gaWYgYXZhaWxhYmxlIHVzZSBkZXBsb3kgdG9rZW4gZnJvbSBnaXQgY29uZmlnCiAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgY29uZmlnIGdpdGxhYi5kZXBsb3l0b2tlbi51c2VyJywgJHRva2VuVXNlcikgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBjb25maWcgZ2l0bGFiLmRlcGxveXRva2VuLnRva2VuJywgJHRva2VuUGFzc3dvcmQpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpblVybCwgdHJpbSgkdG9rZW5Vc2VyKSwgdHJpbSgkdG9rZW5QYXNzd29yZCkpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBhdmFpbGFibGUgdXNlIHRva2VuIGZyb20gY29tcG9zZXIgY29uZmlnCiAgICAgICAgJGF1dGhUb2tlbnMgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGxhYi10b2tlbicpOwoKICAgICAgICBpZiAoaXNzZXQoJGF1dGhUb2tlbnNbJG9yaWdpblVybF0pKSB7CiAgICAgICAgICAgICR0b2tlbiA9ICRhdXRoVG9rZW5zWyRvcmlnaW5VcmxdOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRhdXRoVG9rZW5zWyRiY09yaWdpblVybF0pKSB7CiAgICAgICAgICAgICR0b2tlbiA9ICRhdXRoVG9rZW5zWyRiY09yaWdpblVybF07CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRva2VuKSkgewogICAgICAgICAgICAkdXNlcm5hbWUgPSBpc19hcnJheSgkdG9rZW4pICYmIGFycmF5X2tleV9leGlzdHMoInVzZXJuYW1lIiwgJHRva2VuKSA/ICR0b2tlblsidXNlcm5hbWUiXSA6ICR0b2tlbjsKICAgICAgICAgICAgJHBhc3N3b3JkID0gaXNfYXJyYXkoJHRva2VuKSAmJiBhcnJheV9rZXlfZXhpc3RzKCJ0b2tlbiIsICR0b2tlbikgPyAkdG9rZW5bInRva2VuIl0gOiAncHJpdmF0ZS10b2tlbic7CiAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpblVybCwgJHVzZXJuYW1lLCAkcGFzc3dvcmQpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdXRob3JpemVzIGEgR2l0TGFiIGRvbWFpbiBpbnRlcmFjdGl2ZWx5IHZpYSBPQXV0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzY2hlbWUgICAgU2NoZW1lIHVzZWQgaW4gdGhlIG9yaWdpbiBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpblVybCBUaGUgaG9zdCB0aGlzIEdpdExhYiBpbnN0YW5jZSBpcyBsb2NhdGVkIGF0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlICAgVGhlIHJlYXNvbiB0aGlzIGF1dGhvcml6YXRpb24gaXMgcmVxdWlyZWQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbnxcRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgb24gc3VjY2VzcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXV0aG9yaXplT0F1dGhJbnRlcmFjdGl2ZWx5KCRzY2hlbWUsICRvcmlnaW5VcmwsICRtZXNzYWdlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJG1lc3NhZ2UpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtZXNzYWdlKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCdBIHRva2VuIHdpbGwgYmUgY3JlYXRlZCBhbmQgc3RvcmVkIGluICIlcyIsIHlvdXIgcGFzc3dvcmQgd2lsbCBuZXZlciBiZSBzdG9yZWQnLCAkdGhpcy0+Y29uZmlnLT5nZXRBdXRoQ29uZmlnU291cmNlKCktPmdldE5hbWUoKSkpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignVG8gcmV2b2tlIGFjY2VzcyB0byB0aGlzIHRva2VuIHlvdSBjYW4gdmlzaXQgJy4kc2NoZW1lLic6Ly8nLiRvcmlnaW5VcmwuJy8tL3Byb2ZpbGUvcGVyc29uYWxfYWNjZXNzX3Rva2VucycpOwoKICAgICAgICAkYXR0ZW1wdENvdW50ZXIgPSAwOwoKICAgICAgICB3aGlsZSAoJGF0dGVtcHRDb3VudGVyKysgPCA1KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+Y3JlYXRlVG9rZW4oJHNjaGVtZSwgJG9yaWdpblVybCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gNDAxIGlzIGJhZCBjcmVkZW50aWFscywKICAgICAgICAgICAgICAgIC8vIDQwMyBpcyBtYXggbG9naW4gYXR0ZW1wdHMgZXhjZWVkZWQKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkZS0+Z2V0Q29kZSgpLCBhcnJheSg0MDMsIDQwMSkpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKDQwMSA9PT0gJGUtPmdldENvZGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSBqc29uX2RlY29kZSgkZS0+Z2V0UmVzcG9uc2UoKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcmVzcG9uc2VbJ2Vycm9yJ10pICYmICRyZXNwb25zZVsnZXJyb3InXSA9PT0gJ2ludmFsaWRfZ3JhbnQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0JhZCBjcmVkZW50aWFscy4gSWYgeW91IGhhdmUgdHdvIGZhY3RvciBhdXRoZW50aWNhdGlvbiBlbmFibGVkIHlvdSB3aWxsIGhhdmUgdG8gbWFudWFsbHkgY3JlYXRlIGEgcGVyc29uYWwgYWNjZXNzIHRva2VuJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0JhZCBjcmVkZW50aWFscy4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignTWF4aW11bSBudW1iZXIgb2YgbG9naW4gYXR0ZW1wdHMgZXhjZWVkZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1lvdSBjYW4gYWxzbyBtYW51YWxseSBjcmVhdGUgYSBwZXJzb25hbCBhY2Nlc3MgdG9rZW4gZW5hYmxpbmcgdGhlICJyZWFkX2FwaSIgc2NvcGUgYXQgJy4kc2NoZW1lLic6Ly8nLiRvcmlnaW5VcmwuJy9wcm9maWxlL3BlcnNvbmFsX2FjY2Vzc190b2tlbnMnKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0FkZCBpdCB1c2luZyAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tYXV0aCBnaXRsYWItdG9rZW4uJy4kb3JpZ2luVXJsLicgPHRva2VuPiInKTsKCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpblVybCwgJHJlc3BvbnNlWydhY2Nlc3NfdG9rZW4nXSwgJ29hdXRoMicpOwoKICAgICAgICAgICAgLy8gc3RvcmUgdmFsdWUgaW4gdXNlciBjb25maWcgaW4gYXV0aCBmaWxlCiAgICAgICAgICAgICR0aGlzLT5jb25maWctPmdldEF1dGhDb25maWdTb3VyY2UoKS0+YWRkQ29uZmlnU2V0dGluZygnZ2l0bGFiLW9hdXRoLicuJG9yaWdpblVybCwgJHJlc3BvbnNlWydhY2Nlc3NfdG9rZW4nXSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignSW52YWxpZCBHaXRMYWIgY3JlZGVudGlhbHMgNSB0aW1lcyBpbiBhIHJvdywgYWJvcnRpbmcuJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzY2hlbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpblVybAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7YWNjZXNzX3Rva2VuOiBub24tZW1wdHktc3RyaW5nLCB0b2tlbl90eXBlOiBub24tZW1wdHktc3RyaW5nLCBleHBpcmVzX2luOiBwb3NpdGl2ZS1pbnR9CiAgICAgKgogICAgICogQHNlZSBodHRwczovL2RvY3MuZ2l0bGFiLmNvbS9lZS9hcGkvb2F1dGgyLmh0bWwjcmVzb3VyY2Utb3duZXItcGFzc3dvcmQtY3JlZGVudGlhbHMtZmxvdwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVRva2VuKCRzY2hlbWUsICRvcmlnaW5VcmwpCiAgICB7CiAgICAgICAgJHVzZXJuYW1lID0gJHRoaXMtPmlvLT5hc2soJ1VzZXJuYW1lOiAnKTsKICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJ1Bhc3N3b3JkOiAnKTsKCiAgICAgICAgJGhlYWRlcnMgPSBhcnJheSgnQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTsKCiAgICAgICAgJGFwaVVybCA9ICRvcmlnaW5Vcmw7CiAgICAgICAgJGRhdGEgPSBodHRwX2J1aWxkX3F1ZXJ5KGFycmF5KAogICAgICAgICAgICAndXNlcm5hbWUnID0+ICR1c2VybmFtZSwKICAgICAgICAgICAgJ3Bhc3N3b3JkJyA9PiAkcGFzc3dvcmQsCiAgICAgICAgICAgICdncmFudF90eXBlJyA9PiAncGFzc3dvcmQnLAogICAgICAgICksICcnLCAnJicpOwogICAgICAgICRvcHRpb25zID0gYXJyYXkoCiAgICAgICAgICAgICdyZXRyeS1hdXRoLWZhaWx1cmUnID0+IGZhbHNlLAogICAgICAgICAgICAnaHR0cCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAnbWV0aG9kJyA9PiAnUE9TVCcsCiAgICAgICAgICAgICAgICAnaGVhZGVyJyA9PiAkaGVhZGVycywKICAgICAgICAgICAgICAgICdjb250ZW50JyA9PiAkZGF0YSwKICAgICAgICAgICAgKSwKICAgICAgICApOwoKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkc2NoZW1lLic6Ly8nLiRhcGlVcmwuJy9vYXV0aC90b2tlbicsICRvcHRpb25zKS0+ZGVjb2RlSnNvbigpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1Rva2VuIHN1Y2Nlc3NmdWxseSBjcmVhdGVkJyk7CgogICAgICAgIHJldHVybiAkdG9rZW47CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCi8qKgogKiBAYXV0aG9yIEFuZHJlYXMgU2NoZW1wcCA8YW5kcmVhcy5zY2hlbXBwQHRlcm1pbmFsNDIuY2g+CiAqLwpjbGFzcyBaaXAKewogICAgLyoqCiAgICAgKiBHZXRzIGNvbnRlbnQgb2YgdGhlIHJvb3QgY29tcG9zZXIuanNvbiBpbnNpZGUgYSBaSVAgYXJjaGl2ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoVG9aaXAKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJKc29uKCRwYXRoVG9aaXApCiAgICB7CiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCd6aXAnKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBaaXAgVXRpbCByZXF1aXJlcyBQSFBcJ3MgemlwIGV4dGVuc2lvbicpOwogICAgICAgIH0KCiAgICAgICAgJHppcCA9IG5ldyBcWmlwQXJjaGl2ZSgpOwogICAgICAgIGlmICgkemlwLT5vcGVuKCRwYXRoVG9aaXApICE9PSB0cnVlKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKDAgPT0gJHppcC0+bnVtRmlsZXMpIHsKICAgICAgICAgICAgJHppcC0+Y2xvc2UoKTsKCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGZvdW5kRmlsZUluZGV4ID0gc2VsZjo6bG9jYXRlRmlsZSgkemlwLCAnY29tcG9zZXIuanNvbicpOwoKICAgICAgICAkY29udGVudCA9IG51bGw7CiAgICAgICAgJGNvbmZpZ3VyYXRpb25GaWxlTmFtZSA9ICR6aXAtPmdldE5hbWVJbmRleCgkZm91bmRGaWxlSW5kZXgpOwogICAgICAgICRzdHJlYW0gPSAkemlwLT5nZXRTdHJlYW0oJGNvbmZpZ3VyYXRpb25GaWxlTmFtZSk7CgogICAgICAgIGlmIChmYWxzZSAhPT0gJHN0cmVhbSkgewogICAgICAgICAgICAkY29udGVudCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHN0cmVhbSk7CiAgICAgICAgfQoKICAgICAgICAkemlwLT5jbG9zZSgpOwoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kIGEgZmlsZSBieSBuYW1lLCByZXR1cm5pbmcgdGhlIG9uZSB0aGF0IGhhcyB0aGUgc2hvcnRlc3QgcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gIFxaaXBBcmNoaXZlICAgICAgICR6aXAKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGZpbGVuYW1lCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gbG9jYXRlRmlsZShcWmlwQXJjaGl2ZSAkemlwLCAkZmlsZW5hbWUpCiAgICB7CiAgICAgICAgLy8gcmV0dXJuIHJvb3QgY29tcG9zZXIuanNvbiBpZiBpdCBpcyB0aGVyZSBhbmQgaXMgYSBmaWxlCiAgICAgICAgaWYgKGZhbHNlICE9PSAoJGluZGV4ID0gJHppcC0+bG9jYXRlTmFtZSgkZmlsZW5hbWUpKSAmJiAkemlwLT5nZXRGcm9tSW5kZXgoJGluZGV4KSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRpbmRleDsKICAgICAgICB9CgogICAgICAgICR0b3BMZXZlbFBhdGhzID0gYXJyYXkoKTsKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkemlwLT5udW1GaWxlczsgJGkrKykgewogICAgICAgICAgICAkbmFtZSA9ICR6aXAtPmdldE5hbWVJbmRleCgkaSk7CiAgICAgICAgICAgICRkaXJuYW1lID0gZGlybmFtZSgkbmFtZSk7CgogICAgICAgICAgICAvLyBpZ25vcmUgT1NYIHNwZWNpZmljIHJlc291cmNlIGZvcmsgZm9sZGVyCiAgICAgICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICdfX01BQ09TWCcpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGhhbmRsZSBhcmNoaXZlcyB3aXRoIHByb3BlciBUT0MKICAgICAgICAgICAgaWYgKCRkaXJuYW1lID09PSAnLicpIHsKICAgICAgICAgICAgICAgICR0b3BMZXZlbFBhdGhzWyRuYW1lXSA9IHRydWU7CiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCR0b3BMZXZlbFBhdGhzKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0FyY2hpdmUgaGFzIG1vcmUgdGhhbiBvbmUgdG9wIGxldmVsIGRpcmVjdG9yaWVzLCBhbmQgbm8gY29tcG9zZXIuanNvbiB3YXMgZm91bmQgb24gdGhlIHRvcCBsZXZlbCwgc28gaXRcJ3MgYW4gaW52YWxpZCBhcmNoaXZlLiBUb3AgbGV2ZWwgcGF0aHMgZm91bmQgd2VyZTogJy5pbXBsb2RlKCcsJywgYXJyYXlfa2V5cygkdG9wTGV2ZWxQYXRocykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBoYW5kbGUgYXJjaGl2ZXMgd2hpY2ggZG8gbm90IGhhdmUgYSBUT0MgcmVjb3JkIGZvciB0aGUgZGlyZWN0b3J5IGl0c2VsZgogICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkZGlybmFtZSwgJ1xcJykgJiYgZmFsc2UgPT09IHN0cnBvcygkZGlybmFtZSwgJy8nKSkgewogICAgICAgICAgICAgICAgJHRvcExldmVsUGF0aHNbJGRpcm5hbWUuJy8nXSA9IHRydWU7CiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCR0b3BMZXZlbFBhdGhzKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0FyY2hpdmUgaGFzIG1vcmUgdGhhbiBvbmUgdG9wIGxldmVsIGRpcmVjdG9yaWVzLCBhbmQgbm8gY29tcG9zZXIuanNvbiB3YXMgZm91bmQgb24gdGhlIHRvcCBsZXZlbCwgc28gaXRcJ3MgYW4gaW52YWxpZCBhcmNoaXZlLiBUb3AgbGV2ZWwgcGF0aHMgZm91bmQgd2VyZTogJy5pbXBsb2RlKCcsJywgYXJyYXlfa2V5cygkdG9wTGV2ZWxQYXRocykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0b3BMZXZlbFBhdGhzICYmIGZhbHNlICE9PSAoJGluZGV4ID0gJHppcC0+bG9jYXRlTmFtZShrZXkoJHRvcExldmVsUGF0aHMpLiRmaWxlbmFtZSkpICYmICR6aXAtPmdldEZyb21JbmRleCgkaW5kZXgpICE9PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gJGluZGV4OwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdObyBjb21wb3Nlci5qc29uIGZvdW5kIGVpdGhlciBhdCB0aGUgdG9wIGxldmVsIG9yIHdpdGhpbiB0aGUgdG9wbW9zdCBkaXJlY3RvcnknKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdpdAp7CiAgICAvKiogQHZhciBzdHJpbmd8ZmFsc2V8bnVsbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHZlcnNpb24gPSBmYWxzZTsKCiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKICAgIC8qKiBAdmFyIEZpbGVzeXN0ZW0gKi8KICAgIHByb3RlY3RlZCAkZmlsZXN5c3RlbTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzLCBGaWxlc3lzdGVtICRmcykKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzczsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAgICAkY29tbWFuZENhbGxhYmxlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHVybAogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjd2QKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkaW5pdGlhbENsb25lCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRjd2QsICRpbml0aWFsQ2xvbmUgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBFbnN1cmUgd2UgYXJlIGFsbG93ZWQgdG8gdXNlIHRoaXMgVVJMIGJ5IGNvbmZpZwogICAgICAgICR0aGlzLT5jb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJHVybCwgJHRoaXMtPmlvKTsKCiAgICAgICAgaWYgKCRpbml0aWFsQ2xvbmUpIHsKICAgICAgICAgICAgJG9yaWdDd2QgPSAkY3dkOwogICAgICAgICAgICAkY3dkID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XnNzaDovL1teQF0rQFteOl0rOlteMC05XSt9JywgJHVybCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBzb3VyY2UgVVJMICcgLiAkdXJsIC4gJyBpcyBpbnZhbGlkLCBzc2ggVVJMcyBzaG91bGQgaGF2ZSBhIHBvcnQgbnVtYmVyIGFmdGVyICI6Ii4nIC4gIlxuIiAuICdVc2Ugc3NoOi8vZ2l0QGV4YW1wbGUuY29tOjIyL3BhdGggb3IganVzdCBnaXRAZXhhbXBsZS5jb206cGF0aCBpZiB5b3UgZG8gbm90IHdhbnQgdG8gcHJvdmlkZSBhIHBhc3N3b3JkIG9yIGN1c3RvbSBwb3J0LicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaW5pdGlhbENsb25lKSB7CiAgICAgICAgICAgIC8vIGNhcHR1cmUgdXNlcm5hbWUvcGFzc3dvcmQgZnJvbSBVUkwgaWYgdGhlcmUgaXMgb25lIGFuZCB3ZSBoYXZlIG5vIGF1dGggY29uZmlndXJlZCB5ZXQKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZW1vdGUgLXYnLCAkb3V0cHV0LCAkY3dkKTsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKD86Y29tcG9zZXJ8b3JpZ2luKVxzK2h0dHBzPzovLyguKyk6KC4rKUAoW14vXSspfWltJywgJG91dHB1dCwgJG1hdGNoKSAmJiAhJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbM10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFszXSwgcmF3dXJsZGVjb2RlKCRtYXRjaFsxXSksIHJhd3VybGRlY29kZSgkbWF0Y2hbMl0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHByb3RvY29scyA9ICR0aGlzLT5jb25maWctPmdldCgnZ2l0aHViLXByb3RvY29scycpOwogICAgICAgIGlmICghaXNfYXJyYXkoJHByb3RvY29scykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb25maWcgdmFsdWUgImdpdGh1Yi1wcm90b2NvbHMiIG11c3QgYmUgYW4gYXJyYXksIGdvdCAnIC4gZ2V0dHlwZSgkcHJvdG9jb2xzKSk7CiAgICAgICAgfQogICAgICAgIC8vIHB1YmxpYyBnaXRodWIsIGF1dG9zd2l0Y2ggcHJvdG9jb2xzCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKD86aHR0cHM/fGdpdCk6Ly8nIC4gc2VsZjo6Z2V0R2l0SHViRG9tYWluc1JlZ2V4KCR0aGlzLT5jb25maWcpIC4gJy8oLiopfScsICR1cmwsICRtYXRjaCkpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHByb3RvY29scyBhcyAkcHJvdG9jb2wpIHsKICAgICAgICAgICAgICAgIGlmICgnc3NoJyA9PT0gJHByb3RvY29sKSB7CiAgICAgICAgICAgICAgICAgICAgJHByb3RvVXJsID0gImdpdEAiIC4gJG1hdGNoWzFdIC4gIjoiIC4gJG1hdGNoWzJdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcHJvdG9VcmwgPSAkcHJvdG9jb2wgLiAiOi8vIiAuICRtYXRjaFsxXSAuICIvIiAuICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJHByb3RvVXJsKSwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSAnLSAnIC4gJHByb3RvVXJsIC4gIlxuIiAuIFByZWc6OnJlcGxhY2UoJyNeI20nLCAnICAnLCAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CgogICAgICAgICAgICAgICAgaWYgKCRpbml0aWFsQ2xvbmUgJiYgaXNzZXQoJG9yaWdDd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkb3JpZ0N3ZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZhaWxlZCB0byBjaGVja291dCwgZmlyc3QgY2hlY2sgZ2l0IGFjY2Vzc2liaWxpdHkKICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmhhc0F1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSkgJiYgISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dGhyb3dFeGNlcHRpb24oJ0ZhaWxlZCB0byBjbG9uZSAnIC4gJHVybCAuICcgdmlhICcgLiBpbXBsb2RlKCcsICcsICRwcm90b2NvbHMpIC4gJyBwcm90b2NvbHMsIGFib3J0aW5nLicgLiAiXG5cbiIgLiBpbXBsb2RlKCJcbiIsICRtZXNzYWdlcyksICR1cmwpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSBoYXZlIGEgcHJpdmF0ZSBnaXRodWIgdXJsIGFuZCB0aGUgc3NoIHByb3RvY29sIGlzIGRpc2FibGVkIHRoZW4gd2Ugc2tpcCBpdCBhbmQgZGlyZWN0bHkgZmFsbGJhY2sgdG8gaHR0cHMKICAgICAgICAkYnlwYXNzU3NoRm9yR2l0SHViID0gUHJlZzo6aXNNYXRjaCgne15naXRAJyAuIHNlbGY6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICc6KC4rPylcLmdpdCR9aScsICR1cmwpICYmICFpbl9hcnJheSgnc3NoJywgJHByb3RvY29scywgdHJ1ZSk7CgogICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJHVybCk7CgogICAgICAgICRhdXRoID0gbnVsbDsKICAgICAgICAkY3JlZGVudGlhbHMgPSBhcnJheSgpOwogICAgICAgIGlmICgkYnlwYXNzU3NoRm9yR2l0SHViIHx8IDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgJGN3ZCkpIHsKICAgICAgICAgICAgJGVycm9yTXNnID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgICAgIC8vIHByaXZhdGUgZ2l0aHViIHJlcG9zaXRvcnkgd2l0aG91dCBzc2gga2V5IGFjY2VzcywgdHJ5IGh0dHBzIHdpdGggYXV0aAogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15naXRAJyAuIHNlbGY6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICc6KC4rPylcLmdpdCR9aScsICR1cmwsICRtYXRjaCkKICAgICAgICAgICAgICAgIHx8IFByZWc6OmlzTWF0Y2goJ3teaHR0cHM/Oi8vJyAuIHNlbGY6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICcvKC4qPykoPzpcLmdpdCk/JH1pJywgJHVybCwgJG1hdGNoKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGdpdEh1YlV0aWwgPSBuZXcgR2l0SHViKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0Nsb25pbmcgZmFpbGVkIHVzaW5nIGFuIHNzaCBrZXkgZm9yIGF1dGhlbnRpY2F0aW9uLCBlbnRlciB5b3VyIEdpdEh1YiBjcmVkZW50aWFscyB0byBhY2Nlc3MgcHJpdmF0ZSByZXBvcyc7CgogICAgICAgICAgICAgICAgICAgIGlmICghJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoKCRtYXRjaFsxXSkgJiYgJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkbWF0Y2hbMV0sICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzFdKSkgewogICAgICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pOwogICAgICAgICAgICAgICAgICAgICRhdXRoVXJsID0gJ2h0dHBzOi8vJyAuIHJhd3VybGVuY29kZSgkYXV0aFsndXNlcm5hbWUnXSkgLiAnOicgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3Bhc3N3b3JkJ10pIC4gJ0AnIC4gJG1hdGNoWzFdIC4gJy8nIC4gJG1hdGNoWzJdIC4gJy5naXQnOwogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjcmVkZW50aWFscyA9IGFycmF5KHJhd3VybGVuY29kZSgkYXV0aFsndXNlcm5hbWUnXSksIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkpOwogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoUHJlZzo6aXNNYXRjaCgne15odHRwczovLyhiaXRidWNrZXRcLm9yZykvKC4qPykoPzpcLmdpdCk/JH1pJywgJHVybCwgJG1hdGNoKSkgeyAvL2JpdGJ1Y2tldCBvYXV0aAogICAgICAgICAgICAgICAgJGJpdGJ1Y2tldFV0aWwgPSBuZXcgQml0YnVja2V0KCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnRW50ZXIgeW91ciBCaXRidWNrZXQgY3JlZGVudGlhbHMgdG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRiaXRidWNrZXRVdGlsLT5hdXRob3JpemVPQXV0aCgkbWF0Y2hbMV0pICYmICR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRiaXRidWNrZXRVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJG1hdGNoWzFdLCAkbWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRhY2Nlc3NUb2tlbiA9ICRiaXRidWNrZXRVdGlsLT5nZXRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSwgJ3gtdG9rZW4tYXV0aCcsICRhY2Nlc3NUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsgLy9XZSdyZSBhdXRoZW50aWNhdGluZyB3aXRoIGEgbG9jYWxseSBzdG9yZWQgY29uc3VtZXIuCiAgICAgICAgICAgICAgICAgICAgJGF1dGggPSAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSk7CgogICAgICAgICAgICAgICAgICAgIC8vV2UgYWxyZWFkeSBoYXZlIGFuIGFjY2Vzc190b2tlbiBmcm9tIGEgcHJldmlvdXMgcmVxdWVzdC4KICAgICAgICAgICAgICAgICAgICBpZiAoJGF1dGhbJ3VzZXJuYW1lJ10gIT09ICd4LXRva2VuLWF1dGgnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhY2Nlc3NUb2tlbiA9ICRiaXRidWNrZXRVdGlsLT5yZXF1ZXN0VG9rZW4oJG1hdGNoWzFdLCAkYXV0aFsndXNlcm5hbWUnXSwgJGF1dGhbJ3Bhc3N3b3JkJ10pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRhY2Nlc3NUb2tlbikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG1hdGNoWzFdLCAneC10b2tlbi1hdXRoJywgJGFjY2Vzc1Rva2VuKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGF1dGggPSAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSk7CiAgICAgICAgICAgICAgICAgICAgJGF1dGhVcmwgPSAnaHR0cHM6Ly8nIC4gcmF3dXJsZW5jb2RlKCRhdXRoWyd1c2VybmFtZSddKSAuICc6JyAuIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkgLiAnQCcgLiAkbWF0Y2hbMV0gLiAnLycgLiAkbWF0Y2hbMl0gLiAnLmdpdCc7CgogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjcmVkZW50aWFscyA9IGFycmF5KHJhd3VybGVuY29kZSgkYXV0aFsndXNlcm5hbWUnXSksIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkpOwogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gRmFsbGluZyBiYWNrIHRvIHNzaAogICAgICAgICAgICAgICAgICAgICRzc2hVcmwgPSAnZ2l0QGJpdGJ1Y2tldC5vcmc6JyAuICRtYXRjaFsyXSAuICcuZ2l0JzsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBObyBiaXRidWNrZXQgYXV0aGVudGljYXRpb24gY29uZmlndXJlZC4gRmFsbGluZyBiYWNrIHRvIHNzaC4nKTsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZCA9IGNhbGxfdXNlcl9mdW5jKCRjb21tYW5kQ2FsbGFibGUsICRzc2hVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICBQcmVnOjppc01hdGNoKCd7XihnaXQpQCcgLiBzZWxmOjpnZXRHaXRMYWJEb21haW5zUmVnZXgoJHRoaXMtPmNvbmZpZykgLiAnOiguKz9cLmdpdCkkfWknLCAkdXJsLCAkbWF0Y2gpCiAgICAgICAgICAgICAgICB8fCBQcmVnOjppc01hdGNoKCd7XihodHRwcz8pOi8vJyAuIHNlbGY6OmdldEdpdExhYkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICcvKC4qKX1pJywgJHVybCwgJG1hdGNoKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICgkbWF0Y2hbMV0gPT09ICdnaXQnKSB7CiAgICAgICAgICAgICAgICAgICAgJG1hdGNoWzFdID0gJ2h0dHBzJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzJdKSkgewogICAgICAgICAgICAgICAgICAgICRnaXRMYWJVdGlsID0gbmV3IEdpdExhYigkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzKTsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDbG9uaW5nIGZhaWxlZCwgZW50ZXIgeW91ciBHaXRMYWIgY3JlZGVudGlhbHMgdG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aCgkbWF0Y2hbMl0pICYmICR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJG1hdGNoWzFdLCAkbWF0Y2hbMl0sICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzJdKSkgewogICAgICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMl0pOwogICAgICAgICAgICAgICAgICAgIGlmICgkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ3ByaXZhdGUtdG9rZW4nIHx8ICRhdXRoWydwYXNzd29yZCddID09PSAnb2F1dGgyJyB8fCAkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ2dpdGxhYi1jaS10b2tlbicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGF1dGhVcmwgPSAkbWF0Y2hbMV0gLiAnOi8vJyAuIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkgLiAnOicgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3VzZXJuYW1lJ10pIC4gJ0AnIC4gJG1hdGNoWzJdIC4gJy8nIC4gJG1hdGNoWzNdOyAvLyBzd2FwIHVzZXJuYW1lIGFuZCBwYXNzd29yZAogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhdXRoVXJsID0gJG1hdGNoWzFdIC4gJzovLycgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3VzZXJuYW1lJ10pIC4gJzonIC4gcmF3dXJsZW5jb2RlKCRhdXRoWydwYXNzd29yZCddKSAuICdAJyAuICRtYXRjaFsyXSAuICcvJyAuICRtYXRjaFszXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjcmVkZW50aWFscyA9IGFycmF5KHJhd3VybGVuY29kZSgkYXV0aFsndXNlcm5hbWUnXSksIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkpOwogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlzQXV0aGVudGljYXRpb25GYWlsdXJlKCR1cmwsICRtYXRjaCkpIHsgLy8gcHJpdmF0ZSBub24tZ2l0aHViL2dpdGxhYi9iaXRidWNrZXQgcmVwbyB0aGF0IGZhaWxlZCB0byBhdXRoZW50aWNhdGUKICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJG1hdGNoWzJdLCAnQCcpKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkYXV0aFBhcnRzLCAkbWF0Y2hbMl0pID0gZXhwbG9kZSgnQCcsICRtYXRjaFsyXSwgMik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHN0b3JlQXV0aCA9IGZhbHNlOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzJdKSkgewogICAgICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMl0pOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGRlZmF1bHRVc2VybmFtZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhdXRoUGFydHMpICYmICRhdXRoUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJGF1dGhQYXJ0cywgJzonKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgkZGVmYXVsdFVzZXJuYW1lLCApID0gZXhwbG9kZSgnOicsICRhdXRoUGFydHMsIDIpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlZmF1bHRVc2VybmFtZSA9ICRhdXRoUGFydHM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIEF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkICg8aW5mbz4nIC4gJG1hdGNoWzJdIC4gJzwvaW5mbz4pOicpOwogICAgICAgICAgICAgICAgICAgICRhdXRoID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICd1c2VybmFtZScgPT4gJHRoaXMtPmlvLT5hc2soJyAgICAgIFVzZXJuYW1lOiAnLCAkZGVmYXVsdFVzZXJuYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3Bhc3N3b3JkJyA9PiAkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJyAgICAgIFBhc3N3b3JkOiAnKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICRzdG9yZUF1dGggPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ3N0b3JlLWF1dGhzJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRhdXRoKSB7CiAgICAgICAgICAgICAgICAgICAgJGF1dGhVcmwgPSAkbWF0Y2hbMV0gLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3VzZXJuYW1lJ10pIC4gJzonIC4gcmF3dXJsZW5jb2RlKCRhdXRoWydwYXNzd29yZCddKSAuICdAJyAuICRtYXRjaFsyXSAuICRtYXRjaFszXTsKCiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmQgPSBjYWxsX3VzZXJfZnVuYygkY29tbWFuZENhbGxhYmxlLCAkYXV0aFVybCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgJGN3ZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMl0sICRhdXRoWyd1c2VybmFtZSddLCAkYXV0aFsncGFzc3dvcmQnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRhdXRoSGVscGVyID0gbmV3IEF1dGhIZWxwZXIoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGF1dGhIZWxwZXItPnN0b3JlQXV0aCgkbWF0Y2hbMl0sICRzdG9yZUF1dGgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGNyZWRlbnRpYWxzID0gYXJyYXkocmF3dXJsZW5jb2RlKCRhdXRoWyd1c2VybmFtZSddKSwgcmF3dXJsZW5jb2RlKCRhdXRoWydwYXNzd29yZCddKSk7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yTXNnID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkaW5pdGlhbENsb25lICYmIGlzc2V0KCRvcmlnQ3dkKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkb3JpZ0N3ZCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb3VudCgkY3JlZGVudGlhbHMpID4gMCkgewogICAgICAgICAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+bWFza0NyZWRlbnRpYWxzKCRjb21tYW5kLCAkY3JlZGVudGlhbHMpOwogICAgICAgICAgICAgICAgJGVycm9yTXNnID0gJHRoaXMtPm1hc2tDcmVkZW50aWFscygkZXJyb3JNc2csICRjcmVkZW50aWFscyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPnRocm93RXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkZXJyb3JNc2csICR1cmwpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICogQHBhcmFtIHN0cmluZyAkZGlyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzeW5jTWlycm9yKCR1cmwsICRkaXIpCiAgICB7CiAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX0RJU0FCTEVfTkVUV09SSycpICYmIFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX0RJU0FCTEVfTkVUV09SSycpICE9PSAncHJpbWUnKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QWJvcnRpbmcgZ2l0IG1pcnJvciBzeW5jIG9mICcuJHVybC4nIGFzIG5ldHdvcmsgaXMgZGlzYWJsZWQ8L3dhcm5pbmc+Jyk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyB1cGRhdGUgdGhlIHJlcG8gaWYgaXQgaXMgYSB2YWxpZCBnaXQgcmVwb3NpdG9yeQogICAgICAgIGlmIChpc19kaXIoJGRpcikgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZXYtcGFyc2UgLS1naXQtZGlyJywgJG91dHB1dCwgJGRpcikgJiYgdHJpbSgkb3V0cHV0KSA9PT0gJy4nKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkY29tbWFuZENhbGxhYmxlID0gZnVuY3Rpb24gKCR1cmwpIHsKICAgICAgICAgICAgICAgICAgICAkc2FuaXRpemVkVXJsID0gUHJlZzo6cmVwbGFjZSgnezovLyhbXkBdKz8pOiguKz8pQH0nLCAnOi8vJywgJHVybCk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdnaXQgcmVtb3RlIHNldC11cmwgb3JpZ2luIC0tICVzICYmIGdpdCByZW1vdGUgdXBkYXRlIC0tcHJ1bmUgb3JpZ2luICYmIGdpdCByZW1vdGUgc2V0LXVybCBvcmlnaW4gLS0gJXMgJiYgZ2l0IGdjIC0tYXV0bycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkc2FuaXRpemVkVXJsKSk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgJHRoaXMtPnJ1bkNvbW1hbmQoJGNvbW1hbmRDYWxsYWJsZSwgJHVybCwgJGRpcik7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPlN5bmMgbWlycm9yIGZhaWxlZDogJyAuICRlLT5nZXRNZXNzYWdlKCkgLiAnPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBjbGVhbiB1cCBkaXJlY3RvcnkgYW5kIGRvIGEgZnJlc2ggY2xvbmUgaW50byBpdAogICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVEaXJlY3RvcnkoJGRpcik7CgogICAgICAgICRjb21tYW5kQ2FsbGFibGUgPSBmdW5jdGlvbiAoJHVybCkgdXNlICgkZGlyKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdnaXQgY2xvbmUgLS1taXJyb3IgLS0gJXMgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGRpcikpOwogICAgICAgIH07CgogICAgICAgICR0aGlzLT5ydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRkaXIsIHRydWUpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICogQHBhcmFtIHN0cmluZyAkZGlyCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWYKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoUmVmT3JTeW5jTWlycm9yKCR1cmwsICRkaXIsICRyZWYpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jaGVja1JlZklzSW5NaXJyb3IoJGRpciwgJHJlZikpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnN5bmNNaXJyb3IoJHVybCwgJGRpcikpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jaGVja1JlZklzSW5NaXJyb3IoJGRpciwgJHJlZik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldE5vU2hvd1NpZ25hdHVyZUZsYWcoUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzKQogICAgewogICAgICAgICRnaXRWZXJzaW9uID0gc2VsZjo6Z2V0VmVyc2lvbigkcHJvY2Vzcyk7CiAgICAgICAgaWYgKCRnaXRWZXJzaW9uICYmIHZlcnNpb25fY29tcGFyZSgkZ2l0VmVyc2lvbiwgJzIuMTAuMC1yYzAnLCAnPj0nKSkgewogICAgICAgICAgICByZXR1cm4gJyAtLW5vLXNob3ctc2lnbmF0dXJlJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpcgogICAgICogQHBhcmFtIHN0cmluZyAkcmVmCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tSZWZJc0luTWlycm9yKCRkaXIsICRyZWYpCiAgICB7CiAgICAgICAgaWYgKGlzX2RpcigkZGlyKSAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IHJldi1wYXJzZSAtLWdpdC1kaXInLCAkb3V0cHV0LCAkZGlyKSAmJiB0cmltKCRvdXRwdXQpID09PSAnLicpIHsKICAgICAgICAgICAgJGVzY2FwZWRSZWYgPSBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVmLidee2NvbW1pdH0nKTsKICAgICAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoc3ByaW50ZignZ2l0IHJldi1wYXJzZSAtLXF1aWV0IC0tdmVyaWZ5ICVzJywgJGVzY2FwZWRSZWYpLCAkaWdub3JlZE91dHB1dCwgJGRpcik7CiAgICAgICAgICAgIGlmICgkZXhpdENvZGUgPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHVybAogICAgICogQHBhcmFtIHN0cmluZ1tdICRtYXRjaAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzQXV0aGVudGljYXRpb25GYWlsdXJlKCR1cmwsICYkbWF0Y2gpCiAgICB7CiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7XihodHRwcz86Ly8pKFteL10rKSguKikkfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRhdXRoRmFpbHVyZXMgPSBhcnJheSgKICAgICAgICAgICAgJ2ZhdGFsOiBBdXRoZW50aWNhdGlvbiBmYWlsZWQnLAogICAgICAgICAgICAncmVtb3RlIGVycm9yOiBJbnZhbGlkIHVzZXJuYW1lIG9yIHBhc3N3b3JkLicsCiAgICAgICAgICAgICdlcnJvcjogNDAxIFVuYXV0aG9yaXplZCcsCiAgICAgICAgICAgICdmYXRhbDogdW5hYmxlIHRvIGFjY2VzcycsCiAgICAgICAgICAgICdmYXRhbDogY291bGQgbm90IHJlYWQgVXNlcm5hbWUnLAogICAgICAgICk7CgogICAgICAgICRlcnJvck91dHB1dCA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgIGZvcmVhY2ggKCRhdXRoRmFpbHVyZXMgYXMgJGF1dGhGYWlsdXJlKSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJGVycm9yT3V0cHV0LCAkYXV0aEZhaWx1cmUpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNsZWFuRW52KCkKICAgIHsKICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDQwMCAmJiBpbmlfZ2V0KCdzYWZlX21vZGUnKSAmJiBmYWxzZSA9PT0gc3RycG9zKGluaV9nZXQoJ3NhZmVfbW9kZV9hbGxvd2VkX2Vudl92YXJzJyksICdHSVRfQVNLUEFTUycpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignc2FmZV9tb2RlIGlzIGVuYWJsZWQgYW5kIHNhZmVfbW9kZV9hbGxvd2VkX2Vudl92YXJzIGRvZXMgbm90IGNvbnRhaW4gR0lUX0FTS1BBU1MsIGNhbiBub3Qgc2V0IGVudiB2YXIuIFlvdSBjYW4gZGlzYWJsZSBzYWZlX21vZGUgd2l0aCAiLWRzYWZlX21vZGU9MCIgd2hlbiBydW5uaW5nIGNvbXBvc2VyJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBhZGRlZCBpbiBnaXQgMS43LjEsIHByZXZlbnRzIHByb21wdGluZyB0aGUgdXNlciBmb3IgdXNlcm5hbWUvcGFzc3dvcmQKICAgICAgICBpZiAoUGxhdGZvcm06OmdldEVudignR0lUX0FTS1BBU1MnKSAhPT0gJ2VjaG8nKSB7CiAgICAgICAgICAgIFBsYXRmb3JtOjpwdXRFbnYoJ0dJVF9BU0tQQVNTJywgJ2VjaG8nKTsKICAgICAgICB9CgogICAgICAgIC8vIGNsZWFuIHVwIHJvZ3VlIGdpdCBlbnYgdmFycyBpbiBjYXNlIHRoaXMgaXMgcnVubmluZyBpbiBhIGdpdCBob29rCiAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0dJVF9ESVInKSkgewogICAgICAgICAgICBQbGF0Zm9ybTo6Y2xlYXJFbnYoJ0dJVF9ESVInKTsKICAgICAgICB9CiAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0dJVF9XT1JLX1RSRUUnKSkgewogICAgICAgICAgICBQbGF0Zm9ybTo6Y2xlYXJFbnYoJ0dJVF9XT1JLX1RSRUUnKTsKICAgICAgICB9CgogICAgICAgIC8vIFJ1biBwcm9jZXNzZXMgd2l0aCBwcmVkaWN0YWJsZSBMQU5HVUFHRQogICAgICAgIGlmIChQbGF0Zm9ybTo6Z2V0RW52KCdMQU5HVUFHRScpICE9PSAnQycpIHsKICAgICAgICAgICAgUGxhdGZvcm06OnB1dEVudignTEFOR1VBR0UnLCAnQycpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2xlYW4gdXAgZW52IGZvciBPU1gsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzIxNDYjaXNzdWVjb21tZW50LTM1NDc4OTQwCiAgICAgICAgUGxhdGZvcm06OmNsZWFyRW52KCdEWUxEX0xJQlJBUllfUEFUSCcpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBub24tZW1wdHktc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0R2l0SHViRG9tYWluc1JlZ2V4KENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgIHJldHVybiAnKCcgLiBpbXBsb2RlKCd8JywgYXJyYXlfbWFwKCdwcmVnX3F1b3RlJywgJGNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpKSkgLiAnKSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIG5vbi1lbXB0eS1zdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRHaXRMYWJEb21haW5zUmVnZXgoQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgcmV0dXJuICcoJyAuIGltcGxvZGUoJ3wnLCBhcnJheV9tYXAoJ3ByZWdfcXVvdGUnLCAkY29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJykpKSAuICcpJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdXJsCiAgICAgKgogICAgICogQHJldHVybiBuZXZlcgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHRocm93RXhjZXB0aW9uKCRtZXNzYWdlLCAkdXJsKQogICAgewogICAgICAgIC8vIGdpdCBtaWdodCBkZWxldGUgYSBkaXJlY3Rvcnkgd2hlbiBpdCBmYWlscyBhbmQgcGhwIHdpbGwgbm90IGtub3cKICAgICAgICBjbGVhcnN0YXRjYWNoZSgpOwoKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCAtLXZlcnNpb24nLCAkaWdub3JlZE91dHB1dCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKFVybDo6c2FuaXRpemUoJ0ZhaWxlZCB0byBjbG9uZSAnIC4gJHVybCAuICcsIGdpdCB3YXMgbm90IGZvdW5kLCBjaGVjayB0aGF0IGl0IGlzIGluc3RhbGxlZCBhbmQgaW4geW91ciBQQVRIIGVudi4nIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihVcmw6OnNhbml0aXplKCRtZXNzYWdlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgZ2l0IHZlcnNpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgZ2l0IHZlcnNpb24gbnVtYmVyLCBpZiBwcmVzZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFZlcnNpb24oUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzKQogICAgewogICAgICAgIGlmIChmYWxzZSA9PT0gc2VsZjo6JHZlcnNpb24pIHsKICAgICAgICAgICAgc2VsZjo6JHZlcnNpb24gPSBudWxsOwogICAgICAgICAgICBpZiAoMCA9PT0gJHByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCAtLXZlcnNpb24nLCAkb3V0cHV0KSAmJiBQcmVnOjppc01hdGNoKCcvXmdpdCB2ZXJzaW9uIChcZCsoPzpcLlxkKykrKS9tJywgJG91dHB1dCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokdmVyc2lvbiA9ICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JHZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJGVycm9yCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGNyZWRlbnRpYWxzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXNrQ3JlZGVudGlhbHMoJGVycm9yLCBhcnJheSAkY3JlZGVudGlhbHMpCiAgICB7CiAgICAgICAgJG1hc2tlZENyZWRlbnRpYWxzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJGNyZWRlbnRpYWxzIGFzICRjcmVkZW50aWFsKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkY3JlZGVudGlhbCwgYXJyYXkoJ3ByaXZhdGUtdG9rZW4nLCAneC10b2tlbi1hdXRoJywgJ29hdXRoMicsICdnaXRsYWItY2ktdG9rZW4nLCAneC1vYXV0aC1iYXNpYycpKSkgewogICAgICAgICAgICAgICAgJG1hc2tlZENyZWRlbnRpYWxzW10gPSAkY3JlZGVudGlhbDsKICAgICAgICAgICAgfSBlbHNlaWYgKHN0cmxlbigkY3JlZGVudGlhbCkgPiA2KSB7CiAgICAgICAgICAgICAgICAkbWFza2VkQ3JlZGVudGlhbHNbXSA9IHN1YnN0cigkY3JlZGVudGlhbCwgMCwgMykgLiAnLi4uJyAuIHN1YnN0cigkY3JlZGVudGlhbCwgLTMpOwogICAgICAgICAgICB9IGVsc2VpZiAoc3RybGVuKCRjcmVkZW50aWFsKSA+IDMpIHsKICAgICAgICAgICAgICAgICRtYXNrZWRDcmVkZW50aWFsc1tdID0gc3Vic3RyKCRjcmVkZW50aWFsLCAwLCAzKSAuICcuLi4nOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG1hc2tlZENyZWRlbnRpYWxzW10gPSAnWFhYJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKCRjcmVkZW50aWFscywgJG1hc2tlZENyZWRlbnRpYWxzLCAkZXJyb3IpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxNYXhGaWxlU2l6ZUV4Y2VlZGVkRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXENhQnVuZGxlXENhQnVuZGxlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFByb3h5TWFuYWdlcjsKCi8qKgogKiBAaW50ZXJuYWwKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUmVtb3RlRmlsZXN5c3RlbQp7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkc2NoZW1lOwogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICRieXRlc01heDsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkb3JpZ2luVXJsOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRmaWxlVXJsOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJpdmF0ZSAkZmlsZU5hbWU7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRyZXRyeSA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkcHJvZ3Jlc3M7CiAgICAvKiogQHZhciA/aW50ICovCiAgICBwcml2YXRlICRsYXN0UHJvZ3Jlc3M7CiAgICAvKiogQHZhciBtaXhlZFtdICovCiAgICBwcml2YXRlICRvcHRpb25zID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgYXJyYXl7Y246IHN0cmluZywgZnA6IHN0cmluZ30+ICovCiAgICBwcml2YXRlICRwZWVyQ2VydGlmaWNhdGVNYXAgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkZGlzYWJsZVRscyA9IGZhbHNlOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByaXZhdGUgJGxhc3RIZWFkZXJzOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkc3RvcmVBdXRoID0gZmFsc2U7CiAgICAvKiogQHZhciBBdXRoSGVscGVyICovCiAgICBwcml2YXRlICRhdXRoSGVscGVyOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkZGVncmFkZWRNb2RlID0gZmFsc2U7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByaXZhdGUgJHJlZGlyZWN0czsKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkbWF4UmVkaXJlY3RzID0gMjA7CiAgICAvKiogQHZhciBQcm94eU1hbmFnZXIgKi8KICAgIHByaXZhdGUgJHByb3h5TWFuYWdlcjsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAkaW8gICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAkY29uZmlnICAgICBUaGUgY29uZmlnCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgICAgJG9wdGlvbnMgICAgVGhlIG9wdGlvbnMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkZGlzYWJsZVRscwogICAgICogQHBhcmFtIEF1dGhIZWxwZXIgICRhdXRoSGVscGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCksICRkaXNhYmxlVGxzID0gZmFsc2UsIEF1dGhIZWxwZXIgJGF1dGhIZWxwZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKCiAgICAgICAgLy8gU2V0dXAgVExTIG9wdGlvbnMKICAgICAgICAvLyBUaGUgY2FmaWxlIG9wdGlvbiBjYW4gYmUgc2V0IHZpYSBjb25maWcuanNvbgogICAgICAgIGlmICgkZGlzYWJsZVRscyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBTdHJlYW1Db250ZXh0RmFjdG9yeTo6Z2V0VGxzRGVmYXVsdHMoJG9wdGlvbnMsICRpbyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmRpc2FibGVUbHMgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIHRoZSBvdGhlciBleHRlcm5hbGx5IHNldCBvcHRpb25zIG5vcm1hbGx5LgogICAgICAgICR0aGlzLT5vcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJHRoaXMtPm9wdGlvbnMsICRvcHRpb25zKTsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+YXV0aEhlbHBlciA9IGlzc2V0KCRhdXRoSGVscGVyKSA/ICRhdXRoSGVscGVyIDogbmV3IEF1dGhIZWxwZXIoJGlvLCAkY29uZmlnKTsKICAgICAgICAkdGhpcy0+cHJveHlNYW5hZ2VyID0gUHJveHlNYW5hZ2VyOjpnZXRJbnN0YW5jZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ29weSB0aGUgcmVtb3RlIGZpbGUgaW4gbG9jYWwuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG9yaWdpblVybCBUaGUgb3JpZ2luIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAgJGZpbGVVcmwgICBUaGUgZmlsZSBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgICRmaWxlTmFtZSAgdGhlIGxvY2FsIGZpbGVuYW1lCiAgICAgKiBAcGFyYW0gYm9vbCAgICAkcHJvZ3Jlc3MgIERpc3BsYXkgdGhlIHByb2dyZXNzaW9uCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucyAgIEFkZGl0aW9uYWwgY29udGV4dCBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvcHkoJG9yaWdpblVybCwgJGZpbGVVcmwsICRmaWxlTmFtZSwgJHByb2dyZXNzID0gdHJ1ZSwgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCRvcmlnaW5VcmwsICRmaWxlVXJsLCAkb3B0aW9ucywgJGZpbGVOYW1lLCAkcHJvZ3Jlc3MpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjb250ZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRvcmlnaW5VcmwgVGhlIG9yaWdpbiBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgICRmaWxlVXJsICAgVGhlIGZpbGUgVVJMCiAgICAgKiBAcGFyYW0gYm9vbCAgICAkcHJvZ3Jlc3MgIERpc3BsYXkgdGhlIHByb2dyZXNzaW9uCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucyAgIEFkZGl0aW9uYWwgY29udGV4dCBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBib29sfHN0cmluZyBUaGUgY29udGVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGVudHMoJG9yaWdpblVybCwgJGZpbGVVcmwsICRwcm9ncmVzcyA9IHRydWUsICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldCgkb3JpZ2luVXJsLCAkZmlsZVVybCwgJG9wdGlvbnMsIG51bGwsICRwcm9ncmVzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSB0aGUgb3B0aW9ucyBzZXQgaW4gdGhlIGNvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZFtdIE9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlcyBuZXcgb3B0aW9ucwogICAgICoKICAgICAqIEBwYXJhbSAgbWl4ZWRbXSAkb3B0aW9ucwogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb25zKGFycmF5ICRvcHRpb25zKQogICAgewogICAgICAgICR0aGlzLT5vcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJHRoaXMtPm9wdGlvbnMsICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlzIGRpc2FibGUgVExTLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNUbHNEaXNhYmxlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kaXNhYmxlVGxzID09PSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaGVhZGVycyBvZiB0aGUgbGFzdCByZXF1ZXN0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGFzdEhlYWRlcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGFzdEhlYWRlcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZ1tdICRoZWFkZXJzIGFycmF5IG9mIHJldHVybmVkIGhlYWRlcnMgbGlrZSBmcm9tIGdldExhc3RIZWFkZXJzKCkKICAgICAqIEByZXR1cm4gaW50fG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmaW5kU3RhdHVzQ29kZShhcnJheSAkaGVhZGVycykKICAgIHsKICAgICAgICAkdmFsdWUgPSBudWxsOwogICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teSFRUUC9cUysgKFxkKyl9aScsICRoZWFkZXIsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIC8vIEluIGNhc2Ugb2YgcmVkaXJlY3RzLCBodHRwX3Jlc3BvbnNlX2hlYWRlcnMgY29udGFpbnMgdGhlIGhlYWRlcnMgb2YgYWxsIHJlc3BvbnNlcwogICAgICAgICAgICAgICAgLy8gc28gd2UgY2FuIG5vdCByZXR1cm4gZGlyZWN0bHkgYW5kIG5lZWQgdG8ga2VlcCBpdGVyYXRpbmcKICAgICAgICAgICAgICAgICR2YWx1ZSA9IChpbnQpICRtYXRjaFsxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nW10gICAgJGhlYWRlcnMgYXJyYXkgb2YgcmV0dXJuZWQgaGVhZGVycyBsaWtlIGZyb20gZ2V0TGFzdEhlYWRlcnMoKQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFN0YXR1c01lc3NhZ2UoYXJyYXkgJGhlYWRlcnMpCiAgICB7CiAgICAgICAgJHZhbHVlID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XkhUVFAvXFMrIFxkK31pJywgJGhlYWRlcikpIHsKICAgICAgICAgICAgICAgIC8vIEluIGNhc2Ugb2YgcmVkaXJlY3RzLCBodHRwX3Jlc3BvbnNlX2hlYWRlcnMgY29udGFpbnMgdGhlIGhlYWRlcnMgb2YgYWxsIHJlc3BvbnNlcwogICAgICAgICAgICAgICAgLy8gc28gd2UgY2FuIG5vdCByZXR1cm4gZGlyZWN0bHkgYW5kIG5lZWQgdG8ga2VlcCBpdGVyYXRpbmcKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRoZWFkZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgZmlsZSBjb250ZW50IG9yIGNvcHkgYWN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRvcmlnaW5VcmwgICAgICAgICBUaGUgb3JpZ2luIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAgJGZpbGVVcmwgICAgICAgICAgIFRoZSBmaWxlIFVSTAogICAgICogQHBhcmFtIG1peGVkW10gJGFkZGl0aW9uYWxPcHRpb25zIGNvbnRleHQgb3B0aW9ucwogICAgICogQHBhcmFtIHN0cmluZyAgJGZpbGVOYW1lICAgICAgICAgIHRoZSBsb2NhbCBmaWxlbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAgJHByb2dyZXNzICAgICAgICAgIERpc3BsYXkgdGhlIHByb2dyZXNzaW9uCiAgICAgKgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb258XEV4Y2VwdGlvbgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24gICAgICAgICAgICBXaGVuIHRoZSBmaWxlIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkCiAgICAgKgogICAgICogQHJldHVybiBib29sfHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0KCRvcmlnaW5VcmwsICRmaWxlVXJsLCAkYWRkaXRpb25hbE9wdGlvbnMgPSBhcnJheSgpLCAkZmlsZU5hbWUgPSBudWxsLCAkcHJvZ3Jlc3MgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5zY2hlbWUgPSBwYXJzZV91cmwoJGZpbGVVcmwsIFBIUF9VUkxfU0NIRU1FKTsKICAgICAgICAkdGhpcy0+Ynl0ZXNNYXggPSAwOwogICAgICAgICR0aGlzLT5vcmlnaW5VcmwgPSAkb3JpZ2luVXJsOwogICAgICAgICR0aGlzLT5maWxlVXJsID0gJGZpbGVVcmw7CiAgICAgICAgJHRoaXMtPmZpbGVOYW1lID0gJGZpbGVOYW1lOwogICAgICAgICR0aGlzLT5wcm9ncmVzcyA9ICRwcm9ncmVzczsKICAgICAgICAkdGhpcy0+bGFzdFByb2dyZXNzID0gbnVsbDsKICAgICAgICAkcmV0cnlBdXRoRmFpbHVyZSA9IHRydWU7CiAgICAgICAgJHRoaXMtPmxhc3RIZWFkZXJzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+cmVkaXJlY3RzID0gMTsgLy8gVGhlIGZpcnN0IHJlcXVlc3QgY291bnRzLgoKICAgICAgICAkdGVtcEFkZGl0aW9uYWxPcHRpb25zID0gJGFkZGl0aW9uYWxPcHRpb25zOwogICAgICAgIGlmIChpc3NldCgkdGVtcEFkZGl0aW9uYWxPcHRpb25zWydyZXRyeS1hdXRoLWZhaWx1cmUnXSkpIHsKICAgICAgICAgICAgJHJldHJ5QXV0aEZhaWx1cmUgPSAoYm9vbCkgJHRlbXBBZGRpdGlvbmFsT3B0aW9uc1sncmV0cnktYXV0aC1mYWlsdXJlJ107CgogICAgICAgICAgICB1bnNldCgkdGVtcEFkZGl0aW9uYWxPcHRpb25zWydyZXRyeS1hdXRoLWZhaWx1cmUnXSk7CiAgICAgICAgfQoKICAgICAgICAkaXNSZWRpcmVjdCA9IGZhbHNlOwogICAgICAgIGlmIChpc3NldCgkdGVtcEFkZGl0aW9uYWxPcHRpb25zWydyZWRpcmVjdHMnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnJlZGlyZWN0cyA9ICR0ZW1wQWRkaXRpb25hbE9wdGlvbnNbJ3JlZGlyZWN0cyddOwogICAgICAgICAgICAkaXNSZWRpcmVjdCA9IHRydWU7CgogICAgICAgICAgICB1bnNldCgkdGVtcEFkZGl0aW9uYWxPcHRpb25zWydyZWRpcmVjdHMnXSk7CiAgICAgICAgfQoKICAgICAgICAkb3B0aW9ucyA9ICR0aGlzLT5nZXRPcHRpb25zRm9yVXJsKCRvcmlnaW5VcmwsICR0ZW1wQWRkaXRpb25hbE9wdGlvbnMpOwogICAgICAgIHVuc2V0KCR0ZW1wQWRkaXRpb25hbE9wdGlvbnMpOwoKICAgICAgICAkb3JpZ0ZpbGVVcmwgPSAkZmlsZVVybDsKCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydnaXRsYWItdG9rZW4nXSkpIHsKICAgICAgICAgICAgJGZpbGVVcmwgLj0gKGZhbHNlID09PSBzdHJwb3MoJGZpbGVVcmwsICc/JykgPyAnPycgOiAnJicpIC4gJ2FjY2Vzc190b2tlbj0nLiRvcHRpb25zWydnaXRsYWItdG9rZW4nXTsKICAgICAgICAgICAgdW5zZXQoJG9wdGlvbnNbJ2dpdGxhYi10b2tlbiddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaHR0cCddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydpZ25vcmVfZXJyb3JzJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5kZWdyYWRlZE1vZGUgJiYgc3RycG9zKCRmaWxlVXJsLCAnaHR0cDovL3JlcG8ucGFja2FnaXN0Lm9yZy8nKSA9PT0gMCkgewogICAgICAgICAgICAvLyBhY2Nlc3MgcGFja2FnaXN0IHVzaW5nIHRoZSByZXNvbHZlZCBJUHY0IGluc3RlYWQgb2YgdGhlIGhvc3RuYW1lIHRvIGZvcmNlIElQdjQgcHJvdG9jb2wKICAgICAgICAgICAgJGZpbGVVcmwgPSAnaHR0cDovLycgLiBnZXRob3N0YnluYW1lKCdyZXBvLnBhY2thZ2lzdC5vcmcnKSAuIHN1YnN0cigkZmlsZVVybCwgMjApOwogICAgICAgICAgICAkZGVncmFkZWRQYWNrYWdpc3QgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJG1heEZpbGVTaXplID0gbnVsbDsKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ21heF9maWxlX3NpemUnXSkpIHsKICAgICAgICAgICAgJG1heEZpbGVTaXplID0gJG9wdGlvbnNbJ21heF9maWxlX3NpemUnXTsKICAgICAgICAgICAgdW5zZXQoJG9wdGlvbnNbJ21heF9maWxlX3NpemUnXSk7CiAgICAgICAgfQoKICAgICAgICAkY3R4ID0gU3RyZWFtQ29udGV4dEZhY3Rvcnk6OmdldENvbnRleHQoJGZpbGVVcmwsICRvcHRpb25zLCBhcnJheSgnbm90aWZpY2F0aW9uJyA9PiBhcnJheSgkdGhpcywgJ2NhbGxiYWNrR2V0JykpKTsKCiAgICAgICAgJHByb3h5ID0gJHRoaXMtPnByb3h5TWFuYWdlci0+Z2V0UHJveHlGb3JSZXF1ZXN0KCRmaWxlVXJsKTsKICAgICAgICAkdXNpbmdQcm94eSA9ICRwcm94eS0+Z2V0Rm9ybWF0dGVkVXJsKCcgdXNpbmcgcHJveHkgKCVzKScpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigoc3RycG9zKCRvcmlnRmlsZVVybCwgJ2h0dHAnKSA9PT0gMCA/ICdEb3dubG9hZGluZyAnIDogJ1JlYWRpbmcgJykgLiBVcmw6OnNhbml0aXplKCRvcmlnRmlsZVVybCkgLiAkdXNpbmdQcm94eSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICB1bnNldCgkb3JpZ0ZpbGVVcmwsICRwcm94eSwgJHVzaW5nUHJveHkpOwoKICAgICAgICAvLyBDaGVjayBmb3Igc2VjdXJlIEhUVFAsIGJ1dCBhbGxvdyBpbnNlY3VyZSBQYWNrYWdpc3QgY2FsbHMgdG8gJGhhc2hlZCBwcm92aWRlcnMgYXMgZmlsZSBpbnRlZ3JpdHkgaXMgdmVyaWZpZWQgd2l0aCBzaGEyNTYKICAgICAgICBpZiAoKCFQcmVnOjppc01hdGNoKCd7Xmh0dHA6Ly8ocmVwb1wuKT9wYWNrYWdpc3RcLm9yZy9wL30nLCAkZmlsZVVybCkgfHwgKGZhbHNlID09PSBzdHJwb3MoJGZpbGVVcmwsICckJykgJiYgZmFsc2UgPT09IHN0cnBvcygkZmlsZVVybCwgJyUyNCcpKSkgJiYgZW1wdHkoJGRlZ3JhZGVkUGFja2FnaXN0KSkgewogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLT5wcm9oaWJpdFVybEJ5Q29uZmlnKCRmaWxlVXJsLCAkdGhpcy0+aW8pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wcm9ncmVzcyAmJiAhJGlzUmVkaXJlY3QpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJEb3dubG9hZGluZyAoPGNvbW1lbnQ+Y29ubmVjdGluZy4uLjwvY29tbWVudD4pIiwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgJGVycm9yTWVzc2FnZSA9ICcnOwogICAgICAgICRlcnJvckNvZGUgPSAwOwogICAgICAgICRyZXN1bHQgPSBmYWxzZTsKICAgICAgICBzZXRfZXJyb3JfaGFuZGxlcihmdW5jdGlvbiAoJGNvZGUsICRtc2cpIHVzZSAoJiRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgaWYgKCRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICRlcnJvck1lc3NhZ2UgLj0gIlxuIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZXJyb3JNZXNzYWdlIC49IFByZWc6OnJlcGxhY2UoJ3teZmlsZV9nZXRfY29udGVudHNcKC4qP1wpOiB9JywgJycsICRtc2cpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSk7CiAgICAgICAgJGh0dHBfcmVzcG9uc2VfaGVhZGVyID0gYXJyYXkoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmdldFJlbW90ZUNvbnRlbnRzKCRvcmlnaW5VcmwsICRmaWxlVXJsLCAkY3R4LCAkaHR0cF9yZXNwb25zZV9oZWFkZXIsICRtYXhGaWxlU2l6ZSk7CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRodHRwX3Jlc3BvbnNlX2hlYWRlclswXSkpIHsKICAgICAgICAgICAgICAgICRzdGF0dXNDb2RlID0gc2VsZjo6ZmluZFN0YXR1c0NvZGUoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSA0MDAgJiYgUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdjb250ZW50LXR5cGUnKSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nKSB7CiAgICAgICAgICAgICAgICAgICAgSHR0cERvd25sb2FkZXI6Om91dHB1dFdhcm5pbmdzKCR0aGlzLT5pbywgJG9yaWdpblVybCwganNvbl9kZWNvZGUoJHJlc3VsdCwgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkc3RhdHVzQ29kZSwgYXJyYXkoNDAxLCA0MDMpKSAmJiAkcmV0cnlBdXRoRmFpbHVyZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wcm9tcHRBdXRoQW5kUmV0cnkoJHN0YXR1c0NvZGUsICR0aGlzLT5maW5kU3RhdHVzTWVzc2FnZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpLCAkaHR0cF9yZXNwb25zZV9oZWFkZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29udGVudExlbmd0aCA9ICFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0pID8gUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdjb250ZW50LWxlbmd0aCcpIDogbnVsbDsKICAgICAgICAgICAgaWYgKCRjb250ZW50TGVuZ3RoICYmIFBsYXRmb3JtOjpzdHJsZW4oJHJlc3VsdCkgPCAkY29udGVudExlbmd0aCkgewogICAgICAgICAgICAgICAgLy8gYWxhcywgdGhpcyBpcyBub3QgcG9zc2libGUgdmlhIHRoZSBzdHJlYW0gY2FsbGJhY2sgYmVjYXVzZSBTVFJFQU1fTk9USUZZX0NPTVBMRVRFRCBpcyBkb2N1bWVudGVkLCBidXQgbm90IGltcGxlbWVudGVkIGFueXdoZXJlIGluIFBIUAogICAgICAgICAgICAgICAgJGUgPSBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdDb250ZW50LUxlbmd0aCBtaXNtYXRjaCwgcmVjZWl2ZWQgJy5QbGF0Zm9ybTo6c3RybGVuKCRyZXN1bHQpLicgYnl0ZXMgb3V0IG9mIHRoZSBleHBlY3RlZCAnLiRjb250ZW50TGVuZ3RoKTsKICAgICAgICAgICAgICAgICRlLT5zZXRIZWFkZXJzKCRodHRwX3Jlc3BvbnNlX2hlYWRlcik7CiAgICAgICAgICAgICAgICAkZS0+c2V0U3RhdHVzQ29kZShzZWxmOjpmaW5kU3RhdHVzQ29kZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlKCR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRkaXNjYXJkZWQpIHsKICAgICAgICAgICAgICAgICAgICAkZS0+c2V0UmVzcG9uc2UoJHRoaXMtPm5vcm1hbGl6ZVJlc3VsdCgkcmVzdWx0KSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdDb250ZW50LUxlbmd0aCBtaXNtYXRjaCwgcmVjZWl2ZWQgJy5QbGF0Zm9ybTo6c3RybGVuKCRyZXN1bHQpLicgb3V0IG9mICcuJGNvbnRlbnRMZW5ndGguJyBieXRlczogKCcgLiBiYXNlNjRfZW5jb2RlKCRyZXN1bHQpLicpJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKCiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNTA2MDAgJiYgIWVtcHR5KCRvcHRpb25zWydzc2wnXVsncGVlcl9maW5nZXJwcmludCddKSkgewogICAgICAgICAgICAgICAgLy8gRW11bGF0ZSBmaW5nZXJwcmludCB2YWxpZGF0aW9uIG9uIFBIUCA8IDUuNgogICAgICAgICAgICAgICAgJHBhcmFtcyA9IHN0cmVhbV9jb250ZXh0X2dldF9wYXJhbXMoJGN0eCk7CiAgICAgICAgICAgICAgICAkZXhwZWN0ZWRQZWVyRmluZ2VycHJpbnQgPSAkb3B0aW9uc1snc3NsJ11bJ3BlZXJfZmluZ2VycHJpbnQnXTsKICAgICAgICAgICAgICAgICRwZWVyRmluZ2VycHJpbnQgPSBUbHNIZWxwZXI6OmdldENlcnRpZmljYXRlRmluZ2VycHJpbnQoJHBhcmFtc1snb3B0aW9ucyddWydzc2wnXVsncGVlcl9jZXJ0aWZpY2F0ZSddKTsKCiAgICAgICAgICAgICAgICAvLyBDb25zdGFudCB0aW1lIGNvbXBhcmU/PyEKICAgICAgICAgICAgICAgIGlmICgkZXhwZWN0ZWRQZWVyRmluZ2VycHJpbnQgIT09ICRwZWVyRmluZ2VycHJpbnQpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdQZWVyIGZpbmdlcnByaW50IGRpZCBub3QgbWF0Y2gnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0pKSB7CiAgICAgICAgICAgICAgICAkZS0+c2V0SGVhZGVycygkaHR0cF9yZXNwb25zZV9oZWFkZXIpOwogICAgICAgICAgICAgICAgJGUtPnNldFN0YXR1c0NvZGUoc2VsZjo6ZmluZFN0YXR1c0NvZGUoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRyZXN1bHQgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkZS0+c2V0UmVzcG9uc2UoJHRoaXMtPmRlY29kZVJlc3VsdCgkcmVzdWx0LCAkaHR0cF9yZXNwb25zZV9oZWFkZXIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVzdWx0ID0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICgkZXJyb3JNZXNzYWdlICYmICFmaWx0ZXJfdmFyKGluaV9nZXQoJ2FsbG93X3VybF9mb3BlbicpLCBGSUxURVJfVkFMSURBVEVfQk9PTEVBTikpIHsKICAgICAgICAgICAgJGVycm9yTWVzc2FnZSA9ICdhbGxvd191cmxfZm9wZW4gbXVzdCBiZSBlbmFibGVkIGluIHBocC5pbmkgKCcuJGVycm9yTWVzc2FnZS4nKSc7CiAgICAgICAgfQogICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwogICAgICAgIGlmIChpc3NldCgkZSkgJiYgISR0aGlzLT5yZXRyeSkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5kZWdyYWRlZE1vZGUgJiYgZmFsc2UgIT09IHN0cnBvcygkZS0+Z2V0TWVzc2FnZSgpLCAnT3BlcmF0aW9uIHRpbWVkIG91dCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVncmFkZWRNb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj4nLiRlLT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+JywKICAgICAgICAgICAgICAgICAgICAnPGVycm9yPlJldHJ5aW5nIHdpdGggZGVncmFkZWQgbW9kZSwgY2hlY2sgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jL2FydGljbGVzL3Ryb3VibGVzaG9vdGluZy5tZCNkZWdyYWRlZC1tb2RlIGZvciBtb3JlIGluZm88L2Vycm9yPicsCiAgICAgICAgICAgICAgICApKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldCgkdGhpcy0+b3JpZ2luVXJsLCAkdGhpcy0+ZmlsZVVybCwgJGFkZGl0aW9uYWxPcHRpb25zLCAkdGhpcy0+ZmlsZU5hbWUsICR0aGlzLT5wcm9ncmVzcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgJHN0YXR1c0NvZGUgPSBudWxsOwogICAgICAgICRjb250ZW50VHlwZSA9IG51bGw7CiAgICAgICAgJGxvY2F0aW9uSGVhZGVyID0gbnVsbDsKICAgICAgICBpZiAoIWVtcHR5KCRodHRwX3Jlc3BvbnNlX2hlYWRlclswXSkpIHsKICAgICAgICAgICAgJHN0YXR1c0NvZGUgPSBzZWxmOjpmaW5kU3RhdHVzQ29kZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpOwogICAgICAgICAgICAkY29udGVudFR5cGUgPSBSZXNwb25zZTo6ZmluZEhlYWRlclZhbHVlKCRodHRwX3Jlc3BvbnNlX2hlYWRlciwgJ2NvbnRlbnQtdHlwZScpOwogICAgICAgICAgICAkbG9jYXRpb25IZWFkZXIgPSBSZXNwb25zZTo6ZmluZEhlYWRlclZhbHVlKCRodHRwX3Jlc3BvbnNlX2hlYWRlciwgJ2xvY2F0aW9uJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBmb3IgYml0YnVja2V0IGxvZ2luIHBhZ2UgYXNraW5nIHRvIGF1dGhlbnRpY2F0ZQogICAgICAgIGlmICgkb3JpZ2luVXJsID09PSAnYml0YnVja2V0Lm9yZycKICAgICAgICAgICAgJiYgISR0aGlzLT5hdXRoSGVscGVyLT5pc1B1YmxpY0JpdEJ1Y2tldERvd25sb2FkKCRmaWxlVXJsKQogICAgICAgICAgICAmJiBzdWJzdHIoJGZpbGVVcmwsIC00KSA9PT0gJy56aXAnCiAgICAgICAgICAgICYmICghJGxvY2F0aW9uSGVhZGVyIHx8IHN1YnN0cihwYXJzZV91cmwoJGxvY2F0aW9uSGVhZGVyLCBQSFBfVVJMX1BBVEgpLCAtNCkgIT09ICcuemlwJykKICAgICAgICAgICAgJiYgJGNvbnRlbnRUeXBlICYmIFByZWc6OmlzTWF0Y2goJ3tedGV4dC9odG1sXGJ9aScsICRjb250ZW50VHlwZSkKICAgICAgICApIHsKICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgICAgICBpZiAoJHJldHJ5QXV0aEZhaWx1cmUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9tcHRBdXRoQW5kUmV0cnkoNDAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgZm9yIGdpdGxhYiA0MDQgd2hlbiBkb3dubG9hZGluZyBhcmNoaXZlcwogICAgICAgIGlmICgkc3RhdHVzQ29kZSA9PT0gNDA0CiAgICAgICAgICAgICYmIGluX2FycmF5KCRvcmlnaW5VcmwsICR0aGlzLT5jb25maWctPmdldCgnZ2l0bGFiLWRvbWFpbnMnKSwgdHJ1ZSkKICAgICAgICAgICAgJiYgZmFsc2UgIT09IHN0cnBvcygkZmlsZVVybCwgJ2FyY2hpdmUuemlwJykKICAgICAgICApIHsKICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgICAgICBpZiAoJHJldHJ5QXV0aEZhaWx1cmUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9tcHRBdXRoQW5kUmV0cnkoNDAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIDN4eCByZWRpcmVjdHMsIDMwNCBOb3QgTW9kaWZpZWQgaXMgZXhjbHVkZWQKICAgICAgICAkaGFzRm9sbG93ZWRSZWRpcmVjdCA9IGZhbHNlOwogICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSAzMDAgJiYgJHN0YXR1c0NvZGUgPD0gMzk5ICYmICRzdGF0dXNDb2RlICE9PSAzMDQgJiYgJHRoaXMtPnJlZGlyZWN0cyA8ICR0aGlzLT5tYXhSZWRpcmVjdHMpIHsKICAgICAgICAgICAgJGhhc0ZvbGxvd2VkUmVkaXJlY3QgPSB0cnVlOwogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmhhbmRsZVJlZGlyZWN0KCRodHRwX3Jlc3BvbnNlX2hlYWRlciwgJGFkZGl0aW9uYWxPcHRpb25zLCAkcmVzdWx0KTsKICAgICAgICB9CgogICAgICAgIC8vIGZhaWwgNHh4IGFuZCA1eHggcmVzcG9uc2VzIGFuZCBjYXB0dXJlIHRoZSByZXNwb25zZQogICAgICAgIGlmICgkc3RhdHVzQ29kZSAmJiAkc3RhdHVzQ29kZSA+PSA0MDAgJiYgJHN0YXR1c0NvZGUgPD0gNTk5KSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPnJldHJ5KSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnByb2dyZXNzICYmICEkaXNSZWRpcmVjdCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoIkRvd25sb2FkaW5nICg8ZXJyb3I+ZmFpbGVkPC9lcnJvcj4pIiwgZmFsc2UpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRlID0gbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiR0aGlzLT5maWxlVXJsLiciIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQgKCcuJGh0dHBfcmVzcG9uc2VfaGVhZGVyWzBdLicpJywgJHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgJGUtPnNldEhlYWRlcnMoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgICAgICRlLT5zZXRSZXNwb25zZSgkdGhpcy0+ZGVjb2RlUmVzdWx0KCRyZXN1bHQsICRodHRwX3Jlc3BvbnNlX2hlYWRlcikpOwogICAgICAgICAgICAgICAgJGUtPnNldFN0YXR1c0NvZGUoJHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wcm9ncmVzcyAmJiAhJHRoaXMtPnJldHJ5ICYmICEkaXNSZWRpcmVjdCkgewogICAgICAgICAgICAkdGhpcy0+aW8tPm92ZXJ3cml0ZUVycm9yKCJEb3dubG9hZGluZyAoIi4oJHJlc3VsdCA9PT0gZmFsc2UgPyAnPGVycm9yPmZhaWxlZDwvZXJyb3I+JyA6ICc8Y29tbWVudD4xMDAlPC9jb21tZW50PicpLiIpIiwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gZGVjb2RlIGd6aXAKICAgICAgICBpZiAoJHJlc3VsdCAmJiBleHRlbnNpb25fbG9hZGVkKCd6bGliJykgJiYgc3RycG9zKCRmaWxlVXJsLCAnaHR0cCcpID09PSAwICYmICEkaGFzRm9sbG93ZWRSZWRpcmVjdCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5kZWdyYWRlZE1vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVncmFkZWRNb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheSgKICAgICAgICAgICAgICAgICAgICAnJywKICAgICAgICAgICAgICAgICAgICAnPGVycm9yPkZhaWxlZCB0byBkZWNvZGUgcmVzcG9uc2U6ICcuJGUtPmdldE1lc3NhZ2UoKS4nPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+UmV0cnlpbmcgd2l0aCBkZWdyYWRlZCBtb2RlLCBjaGVjayBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvdHJvdWJsZXNob290aW5nLm1kI2RlZ3JhZGVkLW1vZGUgZm9yIG1vcmUgaW5mbzwvZXJyb3I+JywKICAgICAgICAgICAgICAgICkpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCR0aGlzLT5vcmlnaW5VcmwsICR0aGlzLT5maWxlVXJsLCAkYWRkaXRpb25hbE9wdGlvbnMsICR0aGlzLT5maWxlTmFtZSwgJHRoaXMtPnByb2dyZXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIGNvcHkgY29tbWFuZCBpZiBkb3dubG9hZCB3YXMgc3VjY2Vzc2Z1bAogICAgICAgIGlmIChmYWxzZSAhPT0gJHJlc3VsdCAmJiBudWxsICE9PSAkZmlsZU5hbWUgJiYgISRpc1JlZGlyZWN0KSB7CiAgICAgICAgICAgIGlmICgnJyA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignIicuJHRoaXMtPmZpbGVVcmwuJyIgYXBwZWFycyBicm9rZW4sIGFuZCByZXR1cm5lZCBhbiBlbXB0eSAyMDAgcmVzcG9uc2UnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVycm9yTWVzc2FnZSA9ICcnOwogICAgICAgICAgICBzZXRfZXJyb3JfaGFuZGxlcihmdW5jdGlvbiAoJGNvZGUsICRtc2cpIHVzZSAoJiRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgIGlmICgkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yTWVzc2FnZSAuPSAiXG4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGVycm9yTWVzc2FnZSAuPSBQcmVnOjpyZXBsYWNlKCd7XmZpbGVfcHV0X2NvbnRlbnRzXCguKj9cKTogfScsICcnLCAkbXNnKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICRyZXN1bHQgPSAoYm9vbCkgZmlsZV9wdXRfY29udGVudHMoJGZpbGVOYW1lLCAkcmVzdWx0KTsKICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiR0aGlzLT5maWxlVXJsLiciIGZpbGUgY291bGQgbm90IGJlIHdyaXR0ZW4gdG8gJy4kZmlsZU5hbWUuJzogJy4kZXJyb3JNZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSGFuZGxlIFNTTCBjZXJ0IG1hdGNoIGlzc3VlcwogICAgICAgIGlmIChmYWxzZSA9PT0gJHJlc3VsdCAmJiBmYWxzZSAhPT0gc3RycG9zKCRlcnJvck1lc3NhZ2UsICdQZWVyIGNlcnRpZmljYXRlJykgJiYgUEhQX1ZFUlNJT05fSUQgPCA1MDYwMCkgewogICAgICAgICAgICAvLyBDZXJ0aWZpY2F0ZSBuYW1lIGVycm9yLCBQSFAgZG9lc24ndCBzdXBwb3J0IHN1YmplY3RBbHROYW1lIG9uIFBIUCA8IDUuNgogICAgICAgICAgICAvLyBUaGUgcHJvY2VkdXJlIHRvIGhhbmRsZSBzQU4gZm9yIG9sZGVyIFBIUCdzIGlzOgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAxLiBPcGVuIHNvY2tldCB0byByZW1vdGUgc2VydmVyIGFuZCBmZXRjaCBjZXJ0aWZpY2F0ZSAoZGlzYWJsaW5nIHBlZXIKICAgICAgICAgICAgLy8gICAgdmFsaWRhdGlvbiBiZWNhdXNlIFBIUCBlcnJvcnMgd2l0aG91dCBnaXZpbmcgdXAgdGhlIGNlcnRpZmljYXRlLikKICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gMi4gVmVyaWZ5aW5nIHRoZSBkb21haW4gaW4gdGhlIFVSTCBhZ2FpbnN0IHRoZSBuYW1lcyBpbiB0aGUgc0FOIGZpZWxkLgogICAgICAgICAgICAvLyAgICBJZiB0aGVyZSBpcyBhIG1hdGNoIHJlY29yZCB0aGUgYXV0aG9yaXR5IFtob3N0L3BvcnRdLCBjZXJ0aWZpY2F0ZQogICAgICAgICAgICAvLyAgICBjb21tb24gbmFtZSwgYW5kIGNlcnRpZmljYXRlIGZpbmdlcnByaW50LgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAzLiBSZXRyeSB0aGUgb3JpZ2luYWwgcmVxdWVzdCBidXQgY2hhbmdpbmcgdGhlIENOX21hdGNoIHBhcmFtZXRlciB0bwogICAgICAgICAgICAvLyAgICB0aGUgY29tbW9uIG5hbWUgZXh0cmFjdGVkIGZyb20gdGhlIGNlcnRpZmljYXRlIGluIHN0ZXAgMi4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gNC4gVG8gcHJldmVudCBhbnkgYXR0ZW1wdCBhdCBiZWluZyBob29kd2lua2VkIGJ5IHN3aXRjaGluZyB0aGUKICAgICAgICAgICAgLy8gICAgY2VydGlmaWNhdGUgYmV0d2VlbiBzdGVwcyAyIGFuZCAzIHRoZSBmaW5nZXJwcmludCBvZiB0aGUgY2VydGlmaWNhdGUKICAgICAgICAgICAgLy8gICAgcHJlc2VudGVkIGluIHN0ZXAgMyBpcyBjb21wYXJlZCBhZ2FpbnN0IHRoZSBvbmUgcmVjb3JkZWQgaW4gc3RlcCAyLgogICAgICAgICAgICBpZiAoQ2FCdW5kbGU6OmlzT3BlbnNzbFBhcnNlU2FmZSgpKSB7CiAgICAgICAgICAgICAgICAkY2VydERldGFpbHMgPSAkdGhpcy0+Z2V0Q2VydGlmaWNhdGVDbkFuZEZwKCR0aGlzLT5maWxlVXJsLCAkb3B0aW9ucyk7CgogICAgICAgICAgICAgICAgaWYgKCRjZXJ0RGV0YWlscykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wZWVyQ2VydGlmaWNhdGVNYXBbJHRoaXMtPmdldFVybEF1dGhvcml0eSgkdGhpcy0+ZmlsZVVybCldID0gJGNlcnREZXRhaWxzOwoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmV0cnkgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcnKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+WW91ciB2ZXJzaW9uIG9mIFBIUCwgJXMsIGlzIGFmZmVjdGVkIGJ5IENWRS0yMDEzLTY0MjAgYW5kIGNhbm5vdCBzYWZlbHkgcGVyZm9ybSBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uLCB3ZSBzdHJvbmdseSBzdWdnZXN0IHlvdSB1cGdyYWRlLjwvZXJyb3I+JywKICAgICAgICAgICAgICAgICAgICBQSFBfVkVSU0lPTgogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cmV0cnkpIHsKICAgICAgICAgICAgJHRoaXMtPnJldHJ5ID0gZmFsc2U7CgogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmdldCgkdGhpcy0+b3JpZ2luVXJsLCAkdGhpcy0+ZmlsZVVybCwgJGFkZGl0aW9uYWxPcHRpb25zLCAkdGhpcy0+ZmlsZU5hbWUsICR0aGlzLT5wcm9ncmVzcyk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPnN0b3JlQXV0aCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmF1dGhIZWxwZXItPnN0b3JlQXV0aCgkdGhpcy0+b3JpZ2luVXJsLCAkdGhpcy0+c3RvcmVBdXRoKTsKICAgICAgICAgICAgICAgICR0aGlzLT5zdG9yZUF1dGggPSBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmFsc2UgPT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgJGUgPSBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgIicuJHRoaXMtPmZpbGVVcmwuJyIgZmlsZSBjb3VsZCBub3QgYmUgZG93bmxvYWRlZDogJy4kZXJyb3JNZXNzYWdlLCAkZXJyb3JDb2RlKTsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0pKSB7CiAgICAgICAgICAgICAgICAkZS0+c2V0SGVhZGVycygkaHR0cF9yZXNwb25zZV9oZWFkZXIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISR0aGlzLT5kZWdyYWRlZE1vZGUgJiYgZmFsc2UgIT09IHN0cnBvcygkZS0+Z2V0TWVzc2FnZSgpLCAnT3BlcmF0aW9uIHRpbWVkIG91dCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVncmFkZWRNb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj4nLiRlLT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+JywKICAgICAgICAgICAgICAgICAgICAnPGVycm9yPlJldHJ5aW5nIHdpdGggZGVncmFkZWQgbW9kZSwgY2hlY2sgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jL2FydGljbGVzL3Ryb3VibGVzaG9vdGluZy5tZCNkZWdyYWRlZC1tb2RlIGZvciBtb3JlIGluZm88L2Vycm9yPicsCiAgICAgICAgICAgICAgICApKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldCgkdGhpcy0+b3JpZ2luVXJsLCAkdGhpcy0+ZmlsZVVybCwgJGFkZGl0aW9uYWxPcHRpb25zLCAkdGhpcy0+ZmlsZU5hbWUsICR0aGlzLT5wcm9ncmVzcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0pKSB7CiAgICAgICAgICAgICR0aGlzLT5sYXN0SGVhZGVycyA9ICRodHRwX3Jlc3BvbnNlX2hlYWRlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGNvbnRlbnRzIG9mIHJlbW90ZSBVUkwuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRvcmlnaW5VcmwgICBUaGUgb3JpZ2luIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAgICRmaWxlVXJsICAgICBUaGUgZmlsZSBVUkwKICAgICAqIEBwYXJhbSByZXNvdXJjZSAkY29udGV4dCAgICAgVGhlIHN0cmVhbSBjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHJlc3BvbnNlSGVhZGVycwogICAgICogQHBhcmFtIGludCAgICAgICRtYXhGaWxlU2l6ZSBUaGUgbWF4aW11bSBhbGxvd2VkIGZpbGUgc2l6ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFRoZSByZXNwb25zZSBjb250ZW50cyBvciBmYWxzZSBvbiBmYWlsdXJlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRSZW1vdGVDb250ZW50cygkb3JpZ2luVXJsLCAkZmlsZVVybCwgJGNvbnRleHQsIGFycmF5ICYkcmVzcG9uc2VIZWFkZXJzID0gbnVsbCwgJG1heEZpbGVTaXplID0gbnVsbCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gZmFsc2U7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRlID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRtYXhGaWxlU2l6ZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlVXJsLCBmYWxzZSwgJGNvbnRleHQsIDAsICRtYXhGaWxlU2l6ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBwYXNzaW5nIGBudWxsYCB0byBmaWxlX2dldF9jb250ZW50cyB3aWxsIGNvbnZlcnQgYG51bGxgIHRvIGAwYCBhbmQgcmV0dXJuIDAgYnl0ZXMKICAgICAgICAgICAgICAgICRyZXN1bHQgPSBmaWxlX2dldF9jb250ZW50cygkZmlsZVVybCwgZmFsc2UsICRjb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1heEZpbGVTaXplICE9PSBudWxsICYmIFBsYXRmb3JtOjpzdHJsZW4oJHJlc3VsdCkgPj0gJG1heEZpbGVTaXplKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNYXhGaWxlU2l6ZUV4Y2VlZGVkRXhjZXB0aW9uKCdNYXhpbXVtIGFsbG93ZWQgZG93bmxvYWQgc2l6ZSByZWFjaGVkLiBEb3dubG9hZGVkICcgLiBQbGF0Zm9ybTo6c3RybGVuKCRyZXN1bHQpIC4gJyBvZiBhbGxvd2VkICcgLiAgJG1heEZpbGVTaXplIC4gJyBieXRlcycpOwogICAgICAgIH0KCiAgICAgICAgLy8gaHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vcmVzZXJ2ZWQudmFyaWFibGVzLmh0dHByZXNwb25zZWhlYWRlci5waHAKICAgICAgICAkcmVzcG9uc2VIZWFkZXJzID0gaXNzZXQoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSA/ICRodHRwX3Jlc3BvbnNlX2hlYWRlciA6IGFycmF5KCk7CgogICAgICAgIGlmIChudWxsICE9PSAkZSkgewogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IG5vdGlmaWNhdGlvbiBhY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAkbm90aWZpY2F0aW9uQ29kZSBUaGUgbm90aWZpY2F0aW9uIGNvZGUKICAgICAqIEBwYXJhbSBpbnQgICAgJHNldmVyaXR5ICAgICAgICAgVGhlIHNldmVyaXR5IGxldmVsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlICAgICAgICAgIFRoZSBtZXNzYWdlCiAgICAgKiBAcGFyYW0gaW50ICAgICRtZXNzYWdlQ29kZSAgICAgIFRoZSBtZXNzYWdlIGNvZGUKICAgICAqIEBwYXJhbSBpbnQgICAgJGJ5dGVzVHJhbnNmZXJyZWQgVGhlIGxvYWRlZCBzaXplCiAgICAgKiBAcGFyYW0gaW50ICAgICRieXRlc01heCAgICAgICAgIFRoZSB0b3RhbCBzaXplCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNhbGxiYWNrR2V0KCRub3RpZmljYXRpb25Db2RlLCAkc2V2ZXJpdHksICRtZXNzYWdlLCAkbWVzc2FnZUNvZGUsICRieXRlc1RyYW5zZmVycmVkLCAkYnl0ZXNNYXgpCiAgICB7CiAgICAgICAgc3dpdGNoICgkbm90aWZpY2F0aW9uQ29kZSkgewogICAgICAgICAgICBjYXNlIFNUUkVBTV9OT1RJRllfRkFJTFVSRToKICAgICAgICAgICAgICAgIGlmICg0MDAgPT09ICRtZXNzYWdlQ29kZSkgewogICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgbWlnaHQgaGFwcGVuIGlmIHlvdXIgaG9zdCBpcyBzZWN1cmVkIGJ5IHNzbCBjbGllbnQgY2VydGlmaWNhdGUgYXV0aGVudGljYXRpb24KICAgICAgICAgICAgICAgICAgICAvLyBidXQgeW91IGRvIG5vdCBzZW5kIGFuIGFwcHJvcHJpYXRlIGNlcnRpZmljYXRlCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbigiVGhlICciIC4gJHRoaXMtPmZpbGVVcmwgLiAiJyBVUkwgY291bGQgbm90IGJlIGFjY2Vzc2VkOiAiIC4gJG1lc3NhZ2UsICRtZXNzYWdlQ29kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU1RSRUFNX05PVElGWV9GSUxFX1NJWkVfSVM6CiAgICAgICAgICAgICAgICAkdGhpcy0+Ynl0ZXNNYXggPSAkYnl0ZXNNYXg7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU1RSRUFNX05PVElGWV9QUk9HUkVTUzoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Ynl0ZXNNYXggPiAwICYmICR0aGlzLT5wcm9ncmVzcykgewogICAgICAgICAgICAgICAgICAgICRwcm9ncmVzc2lvbiA9IG1pbigxMDAsIChpbnQpIHJvdW5kKCRieXRlc1RyYW5zZmVycmVkIC8gJHRoaXMtPmJ5dGVzTWF4ICogMTAwKSk7CgogICAgICAgICAgICAgICAgICAgIGlmICgoMCA9PT0gJHByb2dyZXNzaW9uICUgNSkgJiYgMTAwICE9PSAkcHJvZ3Jlc3Npb24gJiYgJHByb2dyZXNzaW9uICE9PSAkdGhpcy0+bGFzdFByb2dyZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5sYXN0UHJvZ3Jlc3MgPSAkcHJvZ3Jlc3Npb247CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoIkRvd25sb2FkaW5nICg8Y29tbWVudD4kcHJvZ3Jlc3Npb24lPC9jb21tZW50PikiLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHBvc2l0aXZlLWludCAkaHR0cFN0YXR1cwogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAkcmVhc29uCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgICRoZWFkZXJzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcm9tcHRBdXRoQW5kUmV0cnkoJGh0dHBTdGF0dXMsICRyZWFzb24gPSBudWxsLCAkaGVhZGVycyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5hdXRoSGVscGVyLT5wcm9tcHRBdXRoSWZOZWVkZWQoJHRoaXMtPmZpbGVVcmwsICR0aGlzLT5vcmlnaW5VcmwsICRodHRwU3RhdHVzLCAkcmVhc29uLCAkaGVhZGVycyk7CgogICAgICAgICR0aGlzLT5zdG9yZUF1dGggPSAkcmVzdWx0WydzdG9yZUF1dGgnXTsKICAgICAgICAkdGhpcy0+cmV0cnkgPSAkcmVzdWx0WydyZXRyeSddOwoKICAgICAgICBpZiAoJHRoaXMtPnJldHJ5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1JFVFJZJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgJG9yaWdpblVybAogICAgICogQHBhcmFtIG1peGVkW10gJGFkZGl0aW9uYWxPcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRPcHRpb25zRm9yVXJsKCRvcmlnaW5VcmwsICRhZGRpdGlvbmFsT3B0aW9ucykKICAgIHsKICAgICAgICAkdGxzT3B0aW9ucyA9IGFycmF5KCk7CgogICAgICAgIC8vIFNldHVwIHJlbWFpbmluZyBUTFMgb3B0aW9ucyAtIHRoZSBtYXRjaGluZyBtYXkgbmVlZCBtb25pdG9yaW5nLCBlc3AuIHd3dyB2cyBub25lIGluIENOCiAgICAgICAgaWYgKCR0aGlzLT5kaXNhYmxlVGxzID09PSBmYWxzZSAmJiBQSFBfVkVSU0lPTl9JRCA8IDUwNjAwICYmICFzdHJlYW1faXNfbG9jYWwoJHRoaXMtPmZpbGVVcmwpKSB7CiAgICAgICAgICAgICRob3N0ID0gcGFyc2VfdXJsKCR0aGlzLT5maWxlVXJsLCBQSFBfVVJMX0hPU1QpOwoKICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNTAzMDQpIHsKICAgICAgICAgICAgICAgIC8vIFBIUCA8IDUuMy40IGRvZXMgbm90IHN1cHBvcnQgZm9sbG93X2xvY2F0aW9uLCBmb3IgdGhvc2UgcGVvcGxlCiAgICAgICAgICAgICAgICAvLyBkbyBzb21lIHJlYWxseSBuYXN0eSBoYXJkIGNvZGVkIHRyYW5zZm9ybWF0aW9ucy4gVGhlc2Ugd2lsbAogICAgICAgICAgICAgICAgLy8gc3RpbGwgYnJlYWtkb3duIGlmIHRoZSBzaXRlIHJlZGlyZWN0cyB0byBhIGRvbWFpbiB3ZSBkb24ndAogICAgICAgICAgICAgICAgLy8gZXhwZWN0LgoKICAgICAgICAgICAgICAgIGlmICgkaG9zdCA9PT0gJ2dpdGh1Yi5jb20nIHx8ICRob3N0ID09PSAnYXBpLmdpdGh1Yi5jb20nKSB7CiAgICAgICAgICAgICAgICAgICAgJGhvc3QgPSAnKi5naXRodWIuY29tJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRsc09wdGlvbnNbJ3NzbCddWydDTl9tYXRjaCddID0gJGhvc3Q7CiAgICAgICAgICAgICR0bHNPcHRpb25zWydzc2wnXVsnU05JX3NlcnZlcl9uYW1lJ10gPSAkaG9zdDsKCiAgICAgICAgICAgICR1cmxBdXRob3JpdHkgPSAkdGhpcy0+Z2V0VXJsQXV0aG9yaXR5KCR0aGlzLT5maWxlVXJsKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+cGVlckNlcnRpZmljYXRlTWFwWyR1cmxBdXRob3JpdHldKSkgewogICAgICAgICAgICAgICAgLy8gSGFuZGxlIHN1YmplY3RBbHROYW1lIG9uIGxlc3NlciBQSFAncy4KICAgICAgICAgICAgICAgICRjZXJ0TWFwID0gJHRoaXMtPnBlZXJDZXJ0aWZpY2F0ZU1hcFskdXJsQXV0aG9yaXR5XTsKCiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnVXNpbmcgPGluZm8+JXM8L2luZm8+IGFzIENOIGZvciBzdWJqZWN0QWx0TmFtZSBlbmFibGVkIGhvc3QgPGluZm8+JXM8L2luZm8+JywKICAgICAgICAgICAgICAgICAgICAkY2VydE1hcFsnY24nXSwKICAgICAgICAgICAgICAgICAgICAkdXJsQXV0aG9yaXR5CiAgICAgICAgICAgICAgICApLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgICR0bHNPcHRpb25zWydzc2wnXVsnQ05fbWF0Y2gnXSA9ICRjZXJ0TWFwWydjbiddOwogICAgICAgICAgICAgICAgJHRsc09wdGlvbnNbJ3NzbCddWydwZWVyX2ZpbmdlcnByaW50J10gPSAkY2VydE1hcFsnZnAnXTsKICAgICAgICAgICAgfSBlbHNlaWYgKCFDYUJ1bmRsZTo6aXNPcGVuc3NsUGFyc2VTYWZlKCkgJiYgJGhvc3QgPT09ICdyZXBvLnBhY2thZ2lzdC5vcmcnKSB7CiAgICAgICAgICAgICAgICAvLyBoYW5kbGUgc3ViamVjdEFsdE5hbWUgZm9yIHBhY2thZ2lzdC5vcmcncyByZXBvIGRvbWFpbiBvbiB2ZXJ5IG9sZCBQSFBzCiAgICAgICAgICAgICAgICAkdGxzT3B0aW9uc1snc3NsJ11bJ0NOX21hdGNoJ10gPSAncGFja2FnaXN0Lm9yZyc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRoZWFkZXJzID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ3psaWInKSkgewogICAgICAgICAgICAkaGVhZGVyc1tdID0gJ0FjY2VwdC1FbmNvZGluZzogZ3ppcCc7CiAgICAgICAgfQoKICAgICAgICAkb3B0aW9ucyA9IGFycmF5X3JlcGxhY2VfcmVjdXJzaXZlKCR0aGlzLT5vcHRpb25zLCAkdGxzT3B0aW9ucywgJGFkZGl0aW9uYWxPcHRpb25zKTsKICAgICAgICBpZiAoISR0aGlzLT5kZWdyYWRlZE1vZGUpIHsKICAgICAgICAgICAgLy8gZGVncmFkZWQgbW9kZSBkaXNhYmxlcyBIVFRQLzEuMSB3aGljaCBjYXVzZXMgaXNzdWVzIHdpdGggc29tZSBiYWQKICAgICAgICAgICAgLy8gcHJveGllcy9zb2Z0d2FyZSBkdWUgdG8gdGhlIHVzZSBvZiBjaHVua2VkIGVuY29kaW5nCiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ3Byb3RvY29sX3ZlcnNpb24nXSA9IDEuMTsKICAgICAgICAgICAgJGhlYWRlcnNbXSA9ICdDb25uZWN0aW9uOiBjbG9zZSc7CiAgICAgICAgfQoKICAgICAgICAkaGVhZGVycyA9ICR0aGlzLT5hdXRoSGVscGVyLT5hZGRBdXRoZW50aWNhdGlvbkhlYWRlcigkaGVhZGVycywgJG9yaWdpblVybCwgJHRoaXMtPmZpbGVVcmwpOwoKICAgICAgICAkb3B0aW9uc1snaHR0cCddWydmb2xsb3dfbG9jYXRpb24nXSA9IDA7CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkgJiYgIWlzX2FycmF5KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IGV4cGxvZGUoIlxyXG4iLCB0cmltKCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddLCAiXHJcbiIpKTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJGhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gJGhlYWRlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAgICAgJGh0dHBfcmVzcG9uc2VfaGVhZGVyCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgICAgICRhZGRpdGlvbmFsT3B0aW9ucwogICAgICogQHBhcmFtIHN0cmluZ3xmYWxzZSAkcmVzdWx0CiAgICAgKgogICAgICogQHJldHVybiBib29sfHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGhhbmRsZVJlZGlyZWN0KGFycmF5ICRodHRwX3Jlc3BvbnNlX2hlYWRlciwgYXJyYXkgJGFkZGl0aW9uYWxPcHRpb25zLCAkcmVzdWx0KQogICAgewogICAgICAgIGlmICgkbG9jYXRpb25IZWFkZXIgPSBSZXNwb25zZTo6ZmluZEhlYWRlclZhbHVlKCRodHRwX3Jlc3BvbnNlX2hlYWRlciwgJ2xvY2F0aW9uJykpIHsKICAgICAgICAgICAgaWYgKHBhcnNlX3VybCgkbG9jYXRpb25IZWFkZXIsIFBIUF9VUkxfU0NIRU1FKSkgewogICAgICAgICAgICAgICAgLy8gQWJzb2x1dGUgVVJMOyBlLmcuIGh0dHBzOi8vZXhhbXBsZS5jb20vY29tcG9zZXIKICAgICAgICAgICAgICAgICR0YXJnZXRVcmwgPSAkbG9jYXRpb25IZWFkZXI7CiAgICAgICAgICAgIH0gZWxzZWlmIChwYXJzZV91cmwoJGxvY2F0aW9uSGVhZGVyLCBQSFBfVVJMX0hPU1QpKSB7CiAgICAgICAgICAgICAgICAvLyBTY2hlbWUgcmVsYXRpdmU7IGUuZy4gLy9leGFtcGxlLmNvbS9mb28KICAgICAgICAgICAgICAgICR0YXJnZXRVcmwgPSAkdGhpcy0+c2NoZW1lLic6Jy4kbG9jYXRpb25IZWFkZXI7CiAgICAgICAgICAgIH0gZWxzZWlmICgnLycgPT09ICRsb2NhdGlvbkhlYWRlclswXSkgewogICAgICAgICAgICAgICAgLy8gQWJzb2x1dGUgcGF0aDsgZS5nLiAvZm9vCiAgICAgICAgICAgICAgICAkdXJsSG9zdCA9IHBhcnNlX3VybCgkdGhpcy0+ZmlsZVVybCwgUEhQX1VSTF9IT1NUKTsKCiAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHBhdGggdXNpbmcgaG9zdG5hbWUgYXMgYW4gYW5jaG9yLgogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9IFByZWc6OnJlcGxhY2UoJ3teKC4rKD86Ly98QCknLnByZWdfcXVvdGUoJHVybEhvc3QpLicoPzo6XGQrKT8pKD86Wy9cP10uKik/JH0nLCAnXDEnLiRsb2NhdGlvbkhlYWRlciwgJHRoaXMtPmZpbGVVcmwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gUmVsYXRpdmUgcGF0aDsgZS5nLiBmb28KICAgICAgICAgICAgICAgIC8vIFRoaXMgYWN0dWFsbHkgZGlmZmVycyBmcm9tIFBIUCB3aGljaCBzZWVtcyB0byBhZGQgZHVwbGljYXRlIHNsYXNoZXMuCiAgICAgICAgICAgICAgICAkdGFyZ2V0VXJsID0gUHJlZzo6cmVwbGFjZSgne14oLisvKVteLz9dKig/Olw/LiopPyR9JywgJ1wxJy4kbG9jYXRpb25IZWFkZXIsICR0aGlzLT5maWxlVXJsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkdGFyZ2V0VXJsKSkgewogICAgICAgICAgICAkdGhpcy0+cmVkaXJlY3RzKys7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCdGb2xsb3dpbmcgcmVkaXJlY3QgKCV1KSAlcycsICR0aGlzLT5yZWRpcmVjdHMsIFVybDo6c2FuaXRpemUoJHRhcmdldFVybCkpLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgJGFkZGl0aW9uYWxPcHRpb25zWydyZWRpcmVjdHMnXSA9ICR0aGlzLT5yZWRpcmVjdHM7CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldChwYXJzZV91cmwoJHRhcmdldFVybCwgUEhQX1VSTF9IT1NUKSwgJHRhcmdldFVybCwgJGFkZGl0aW9uYWxPcHRpb25zLCAkdGhpcy0+ZmlsZU5hbWUsICR0aGlzLT5wcm9ncmVzcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5yZXRyeSkgewogICAgICAgICAgICAkZSA9IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1RoZSAiJy4kdGhpcy0+ZmlsZVVybC4nIiBmaWxlIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkLCBnb3QgcmVkaXJlY3Qgd2l0aG91dCBMb2NhdGlvbiAoJy4kaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0uJyknKTsKICAgICAgICAgICAgJGUtPnNldEhlYWRlcnMoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlKCR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSk7CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEZldGNoIGNlcnRpZmljYXRlIGNvbW1vbiBuYW1lIGFuZCBmaW5nZXJwcmludCBmb3IgdmFsaWRhdGlvbiBvZiBTQU4uCiAgICAgKgogICAgICogQHRvZG8gUmVtb3ZlIHdoZW4gUEhQIDUuNiBpcyBtaW5pbXVtIHN1cHBvcnRlZCB2ZXJzaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICR1cmwKICAgICAqIEBwYXJhbSBtaXhlZFtdICRvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiA/YXJyYXl7Y246IHN0cmluZywgZnA6IHN0cmluZ30KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDZXJ0aWZpY2F0ZUNuQW5kRnAoJHVybCwgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDUwNjAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcQmFkTWV0aG9kQ2FsbEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJyVzIG11c3Qgbm90IGJlIHVzZWQgb24gUEhQID49IDUuNicsCiAgICAgICAgICAgICAgICBfX01FVEhPRF9fCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJGNvbnRleHQgPSBTdHJlYW1Db250ZXh0RmFjdG9yeTo6Z2V0Q29udGV4dCgkdXJsLCAkb3B0aW9ucywgYXJyYXkoJ29wdGlvbnMnID0+IGFycmF5KAogICAgICAgICAgICAnc3NsJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgICdjYXB0dXJlX3BlZXJfY2VydCcgPT4gdHJ1ZSwKICAgICAgICAgICAgICAgICd2ZXJpZnlfcGVlcicgPT4gZmFsc2UsIC8vIFllcyB0aGlzIGlzIGZ1Y2tpbmcgaW5zYW5lISBCdXQgUEhQIGlzIGxhbWUuCiAgICAgICAgICAgICksICksCiAgICAgICAgKSk7CgogICAgICAgIC8vIElkZWFsbHkgdGhpcyB3b3VsZCBqdXN0IHVzZSBzdHJlYW1fc29ja2V0X2NsaWVudCgpIHRvIGF2b2lkIHNlbmRpbmcgYQogICAgICAgIC8vIEhUVFAgcmVxdWVzdCBidXQgdGhhdCBkb2VzIG5vdCBjYXB0dXJlIHRoZSBjZXJ0aWZpY2F0ZS4KICAgICAgICBpZiAoZmFsc2UgPT09ICRoYW5kbGUgPSBAZm9wZW4oJHVybCwgJ3JiJywgZmFsc2UsICRjb250ZXh0KSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIENsb3NlIG5vbiBhdXRoZW50aWNhdGVkIGNvbm5lY3Rpb24gd2l0aG91dCByZWFkaW5nIGFueSBjb250ZW50LgogICAgICAgIGZjbG9zZSgkaGFuZGxlKTsKICAgICAgICAkaGFuZGxlID0gbnVsbDsKCiAgICAgICAgJHBhcmFtcyA9IHN0cmVhbV9jb250ZXh0X2dldF9wYXJhbXMoJGNvbnRleHQpOwoKICAgICAgICBpZiAoIWVtcHR5KCRwYXJhbXNbJ29wdGlvbnMnXVsnc3NsJ11bJ3BlZXJfY2VydGlmaWNhdGUnXSkpIHsKICAgICAgICAgICAgJHBlZXJDZXJ0aWZpY2F0ZSA9ICRwYXJhbXNbJ29wdGlvbnMnXVsnc3NsJ11bJ3BlZXJfY2VydGlmaWNhdGUnXTsKCiAgICAgICAgICAgIGlmIChUbHNIZWxwZXI6OmNoZWNrQ2VydGlmaWNhdGVIb3N0KCRwZWVyQ2VydGlmaWNhdGUsIHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX0hPU1QpLCAkY29tbW9uTmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnY24nID0+ICRjb21tb25OYW1lLAogICAgICAgICAgICAgICAgICAgICdmcCcgPT4gVGxzSGVscGVyOjpnZXRDZXJ0aWZpY2F0ZUZpbmdlcnByaW50KCRwZWVyQ2VydGlmaWNhdGUpLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFVybEF1dGhvcml0eSgkdXJsKQogICAgewogICAgICAgICRkZWZhdWx0UG9ydHMgPSBhcnJheSgKICAgICAgICAgICAgJ2Z0cCcgPT4gMjEsCiAgICAgICAgICAgICdodHRwJyA9PiA4MCwKICAgICAgICAgICAgJ2h0dHBzJyA9PiA0NDMsCiAgICAgICAgICAgICdzc2gyLnNmdHAnID0+IDIyLAogICAgICAgICAgICAnc3NoMi5zY3AnID0+IDIyLAogICAgICAgICk7CgogICAgICAgICRzY2hlbWUgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9TQ0hFTUUpOwoKICAgICAgICBpZiAoIWlzc2V0KCRkZWZhdWx0UG9ydHNbJHNjaGVtZV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnQ291bGQgbm90IGdldCBkZWZhdWx0IHBvcnQgZm9yIHVua25vd24gc2NoZW1lOiAlcycsCiAgICAgICAgICAgICAgICAkc2NoZW1lCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJGRlZmF1bHRQb3J0ID0gJGRlZmF1bHRQb3J0c1skc2NoZW1lXTsKICAgICAgICAkcG9ydCA9IHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1BPUlQpID86ICRkZWZhdWx0UG9ydDsKCiAgICAgICAgcmV0dXJuIHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX0hPU1QpLic6Jy4kcG9ydDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8ZmFsc2UgJHJlc3VsdAogICAgICogQHBhcmFtIHN0cmluZ1tdICAgICAkaHR0cF9yZXNwb25zZV9oZWFkZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZGVjb2RlUmVzdWx0KCRyZXN1bHQsICRodHRwX3Jlc3BvbnNlX2hlYWRlcikKICAgIHsKICAgICAgICAvLyBkZWNvZGUgZ3ppcAogICAgICAgIGlmICgkcmVzdWx0ICYmIGV4dGVuc2lvbl9sb2FkZWQoJ3psaWInKSkgewogICAgICAgICAgICAkY29udGVudEVuY29kaW5nID0gUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdjb250ZW50LWVuY29kaW5nJyk7CiAgICAgICAgICAgICRkZWNvZGUgPSAkY29udGVudEVuY29kaW5nICYmICdnemlwJyA9PT0gc3RydG9sb3dlcigkY29udGVudEVuY29kaW5nKTsKCiAgICAgICAgICAgIGlmICgkZGVjb2RlKSB7CiAgICAgICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gNTA0MDApIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gemxpYl9kZWNvZGUoJHJlc3VsdCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIHdvcmsgYXJvdW5kIGlzc3VlIHdpdGggZ3p1bmNvbXByZXNzICYgY28gdGhhdCBkbyBub3Qgd29yayB3aXRoIGFsbCBnemlwIGNoZWNrc3VtcwogICAgICAgICAgICAgICAgICAgICRyZXN1bHQgPSBmaWxlX2dldF9jb250ZW50cygnY29tcHJlc3MuemxpYjovL2RhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCwnLmJhc2U2NF9lbmNvZGUoJHJlc3VsdCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkcmVzdWx0ID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ0ZhaWxlZCB0byBkZWNvZGUgemxpYiBzdHJlYW0nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5ub3JtYWxpemVSZXN1bHQoJHJlc3VsdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGZhbHNlICRyZXN1bHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbm9ybWFsaXplUmVzdWx0KCRyZXN1bHQpCiAgICB7CiAgICAgICAgaWYgKCRyZXN1bHQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEF1dGhIZWxwZXIKewogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiBvcmlnaW5zIHRvIG1lc3NhZ2UgZGlzcGxheWVkICovCiAgICBwcml2YXRlICRkaXNwbGF5ZWRPcmlnaW5BdXRoZW50aWNhdGlvbnMgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkb3JpZ2luCiAgICAgKiBAcGFyYW0gc3RyaW5nfGJvb2wgJHN0b3JlQXV0aAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RvcmVBdXRoKCRvcmlnaW4sICRzdG9yZUF1dGgpCiAgICB7CiAgICAgICAgJHN0b3JlID0gZmFsc2U7CiAgICAgICAgJGNvbmZpZ1NvdXJjZSA9ICR0aGlzLT5jb25maWctPmdldEF1dGhDb25maWdTb3VyY2UoKTsKICAgICAgICBpZiAoJHN0b3JlQXV0aCA9PT0gdHJ1ZSkgewogICAgICAgICAgICAkc3RvcmUgPSAkY29uZmlnU291cmNlOwogICAgICAgIH0gZWxzZWlmICgkc3RvcmVBdXRoID09PSAncHJvbXB0JykgewogICAgICAgICAgICAkYW5zd2VyID0gJHRoaXMtPmlvLT5hc2tBbmRWYWxpZGF0ZSgKICAgICAgICAgICAgICAgICdEbyB5b3Ugd2FudCB0byBzdG9yZSBjcmVkZW50aWFscyBmb3IgJy4kb3JpZ2luLicgaW4gJy4kY29uZmlnU291cmNlLT5nZXROYW1lKCkuJyA/IFtZbl0gJywKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkaW5wdXQgPSBzdHJ0b2xvd2VyKHN1YnN0cih0cmltKCR2YWx1ZSksIDAsIDEpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGlucHV0LCBhcnJheSgneScsJ24nKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRpbnB1dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdQbGVhc2UgYW5zd2VyICh5KWVzIG9yIChuKW8nKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgJ3knCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoJGFuc3dlciA9PT0gJ3knKSB7CiAgICAgICAgICAgICAgICAkc3RvcmUgPSAkY29uZmlnU291cmNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkc3RvcmUpIHsKICAgICAgICAgICAgJHN0b3JlLT5hZGRDb25maWdTZXR0aW5nKAogICAgICAgICAgICAgICAgJ2h0dHAtYmFzaWMuJy4kb3JpZ2luLAogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHVybAogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkb3JpZ2luCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICRzdGF0dXNDb2RlIEhUVFAgc3RhdHVzIGNvZGUgdGhhdCB0cmlnZ2VyZWQgdGhpcyBjYWxsCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xudWxsICRyZWFzb24gICAgIGEgbWVzc2FnZS9kZXNjcmlwdGlvbiBleHBsYWluaW5nIHdoeSB0aGlzIHdhcyBjYWxsZWQKICAgICAqIEBwYXJhbSAgc3RyaW5nW10gICAgJGhlYWRlcnMKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbCAgY29udGFpbmluZyByZXRyeSAoYm9vbCkgYW5kIHN0b3JlQXV0aCAoc3RyaW5nfGJvb2wpIGtleXMsIGlmIHJldHJ5IGlzIHRydWUgdGhlIHJlcXVlc3Qgc2hvdWxkIGJlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0cmllZCwgaWYgc3RvcmVBdXRoIGlzIHRydWUgdGhlbiBvbiBhIHN1Y2Nlc3NmdWwgcmV0cnkgdGhlIGF1dGhlbnRpY2F0aW9uIHNob3VsZCBiZSBwZXJzaXN0ZWQgdG8gYXV0aC5qc29uCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gP2FycmF5e3JldHJ5OiBib29sLCBzdG9yZUF1dGg6IHN0cmluZ3xib29sfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvbXB0QXV0aElmTmVlZGVkKCR1cmwsICRvcmlnaW4sICRzdGF0dXNDb2RlLCAkcmVhc29uID0gbnVsbCwgJGhlYWRlcnMgPSBhcnJheSgpKQogICAgewogICAgICAgICRzdG9yZUF1dGggPSBmYWxzZTsKCiAgICAgICAgaWYgKGluX2FycmF5KCRvcmlnaW4sICR0aGlzLT5jb25maWctPmdldCgnZ2l0aHViLWRvbWFpbnMnKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgJGdpdEh1YlV0aWwgPSBuZXcgR2l0SHViKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgbnVsbCk7CiAgICAgICAgICAgICRtZXNzYWdlID0gIlxuIjsKCiAgICAgICAgICAgICRyYXRlTGltaXRlZCA9ICRnaXRIdWJVdGlsLT5pc1JhdGVMaW1pdGVkKCRoZWFkZXJzKTsKICAgICAgICAgICAgJHJlcXVpcmVzU3NvID0gJGdpdEh1YlV0aWwtPnJlcXVpcmVzU3NvKCRoZWFkZXJzKTsKCiAgICAgICAgICAgIGlmICgkcmVxdWlyZXNTc28pIHsKICAgICAgICAgICAgICAgICRzc29VcmwgPSAkZ2l0SHViVXRpbC0+Z2V0U3NvVXJsKCRoZWFkZXJzKTsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0dpdEh1YiBBUEkgdG9rZW4gcmVxdWlyZXMgU1NPIGF1dGhvcml6YXRpb24uIEF1dGhvcml6ZSB0aGlzIHRva2VuIGF0ICcgLiAkc3NvVXJsIC4gIlxuIjsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbWVzc2FnZSk7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignQ291bGQgbm90IGF1dGhlbnRpY2F0ZSBhZ2FpbnN0ICcgLiAkb3JpZ2luLCA0MDMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5hc2soJ0FmdGVyIGF1dGhvcml6aW5nIHlvdXIgdG9rZW4sIGNvbmZpcm0gdGhhdCB5b3Ugd291bGQgbGlrZSB0byByZXRyeSB0aGUgcmVxdWVzdCcpOwoKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgncmV0cnknID0+IHRydWUsICdzdG9yZUF1dGgnID0+ICRzdG9yZUF1dGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHJhdGVMaW1pdGVkKSB7CiAgICAgICAgICAgICAgICAkcmF0ZUxpbWl0ID0gJGdpdEh1YlV0aWwtPmdldFJhdGVMaW1pdCgkaGVhZGVycyk7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ1JldmlldyB5b3VyIGNvbmZpZ3VyZWQgR2l0SHViIE9BdXRoIHRva2VuIG9yIGVudGVyIGEgbmV3IG9uZSB0byBnbyBvdmVyIHRoZSBBUEkgcmF0ZSBsaW1pdC4nOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDcmVhdGUgYSBHaXRIdWIgT0F1dGggdG9rZW4gdG8gZ28gb3ZlciB0aGUgQVBJIHJhdGUgbGltaXQuJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0dpdEh1YiBBUEkgbGltaXQgKCVkIGNhbGxzL2hyKSBpcyBleGhhdXN0ZWQsIGNvdWxkIG5vdCBmZXRjaCAnLiR1cmwuJy4gJy4kbWVzc2FnZS4nIFlvdSBjYW4gYWxzbyB3YWl0IHVudGlsICVzIGZvciB0aGUgcmF0ZSBsaW1pdCB0byByZXNldC4nLAogICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXRbJ2xpbWl0J10sCiAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdFsncmVzZXQnXQogICAgICAgICAgICAgICAgKS4iXG4iOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gJ0NvdWxkIG5vdCBmZXRjaCAnLiR1cmwuJywgcGxlYXNlICc7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICdyZXZpZXcgeW91ciBjb25maWd1cmVkIEdpdEh1YiBPQXV0aCB0b2tlbiBvciBlbnRlciBhIG5ldyBvbmUgdG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAnY3JlYXRlIGEgR2l0SHViIE9BdXRoIHRva2VuIHRvIGFjY2VzcyBwcml2YXRlIHJlcG9zJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkZ2l0SHViVXRpbC0+YXV0aG9yaXplT0F1dGgoJG9yaWdpbikKICAgICAgICAgICAgICAgICYmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkgfHwgISRnaXRIdWJVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJG9yaWdpbiwgJG1lc3NhZ2UpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ0NvdWxkIG5vdCBhdXRoZW50aWNhdGUgYWdhaW5zdCAnLiRvcmlnaW4sIDQwMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoaW5fYXJyYXkoJG9yaWdpbiwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpLCB0cnVlKSkgewogICAgICAgICAgICAkbWVzc2FnZSA9ICJcbiIuJ0NvdWxkIG5vdCBmZXRjaCAnLiR1cmwuJywgZW50ZXIgeW91ciAnIC4gJG9yaWdpbiAuICcgY3JlZGVudGlhbHMgJyAuKCRzdGF0dXNDb2RlID09PSA0MDEgPyAndG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnIDogJ3RvIGdvIG92ZXIgdGhlIEFQSSByYXRlIGxpbWl0Jyk7CiAgICAgICAgICAgICRnaXRMYWJVdGlsID0gbmV3IEdpdExhYigkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsIG51bGwpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG9yaWdpbikpIHsKICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luKTsKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkYXV0aFsncGFzc3dvcmQnXSwgYXJyYXkoJ2dpdGxhYi1jaS10b2tlbicsICdwcml2YXRlLXRva2VuJywgJ29hdXRoMicpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oIkludmFsaWQgY3JlZGVudGlhbHMgZm9yICciIC4gJHVybCAuICInLCBhYm9ydGluZy4iLCAkc3RhdHVzQ29kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGdpdExhYlV0aWwtPmF1dGhvcml6ZU9BdXRoKCRvcmlnaW4pCiAgICAgICAgICAgICAgICAmJiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpIHx8ICEkZ2l0TGFiVXRpbC0+YXV0aG9yaXplT0F1dGhJbnRlcmFjdGl2ZWx5KHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1NDSEVNRSksICRvcmlnaW4sICRtZXNzYWdlKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdDb3VsZCBub3QgYXV0aGVudGljYXRlIGFnYWluc3QgJy4kb3JpZ2luLCA0MDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCRvcmlnaW4gPT09ICdiaXRidWNrZXQub3JnJyB8fCAkb3JpZ2luID09PSAnYXBpLmJpdGJ1Y2tldC5vcmcnKSB7CiAgICAgICAgICAgICRhc2tGb3JPQXV0aFRva2VuID0gdHJ1ZTsKICAgICAgICAgICAgJG9yaWdpbiA9ICdiaXRidWNrZXQub3JnJzsKICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG9yaWdpbikpIHsKICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luKTsKICAgICAgICAgICAgICAgIGlmICgkYXV0aFsndXNlcm5hbWUnXSAhPT0gJ3gtdG9rZW4tYXV0aCcpIHsKICAgICAgICAgICAgICAgICAgICAkYml0YnVja2V0VXRpbCA9IG5ldyBCaXRidWNrZXQoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnKTsKICAgICAgICAgICAgICAgICAgICAkYWNjZXNzVG9rZW4gPSAkYml0YnVja2V0VXRpbC0+cmVxdWVzdFRva2VuKCRvcmlnaW4sICRhdXRoWyd1c2VybmFtZSddLCAkYXV0aFsncGFzc3dvcmQnXSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkYWNjZXNzVG9rZW4pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpbiwgJ3gtdG9rZW4tYXV0aCcsICRhY2Nlc3NUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICRhc2tGb3JPQXV0aFRva2VuID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdDb3VsZCBub3QgYXV0aGVudGljYXRlIGFnYWluc3QgJyAuICRvcmlnaW4sIDQwMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkYXNrRm9yT0F1dGhUb2tlbikgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiXG4iLidDb3VsZCBub3QgZmV0Y2ggJyAuICR1cmwgLiAnLCBwbGVhc2UgY3JlYXRlIGEgYml0YnVja2V0IE9BdXRoIHRva2VuIHRvICcgLiAoKCRzdGF0dXNDb2RlID09PSA0MDEgfHwgJHN0YXR1c0NvZGUgPT09IDQwMykgPyAnYWNjZXNzIHByaXZhdGUgcmVwb3MnIDogJ2dvIG92ZXIgdGhlIEFQSSByYXRlIGxpbWl0Jyk7CiAgICAgICAgICAgICAgICAkYml0QnVja2V0VXRpbCA9IG5ldyBCaXRidWNrZXQoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnKTsKICAgICAgICAgICAgICAgIGlmICghJGJpdEJ1Y2tldFV0aWwtPmF1dGhvcml6ZU9BdXRoKCRvcmlnaW4pCiAgICAgICAgICAgICAgICAgICAgJiYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSB8fCAhJGJpdEJ1Y2tldFV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkb3JpZ2luLCAkbWVzc2FnZSkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdDb3VsZCBub3QgYXV0aGVudGljYXRlIGFnYWluc3QgJyAuICRvcmlnaW4sIDQwMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyA0MDRzIGFyZSBvbmx5IGhhbmRsZWQgZm9yIGdpdGh1YgogICAgICAgICAgICBpZiAoJHN0YXR1c0NvZGUgPT09IDQwNCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZhaWwgaWYgdGhlIGNvbnNvbGUgaXMgbm90IGludGVyYWN0aXZlCiAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA9PT0gNDAxKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiVGhlICciIC4gJHVybCAuICInIFVSTCByZXF1aXJlZCBhdXRoZW50aWNhdGlvbi5cbllvdSBtdXN0IGJlIHVzaW5nIHRoZSBpbnRlcmFjdGl2ZSBjb25zb2xlIHRvIGF1dGhlbnRpY2F0ZSI7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXR1c0NvZGUgPT09IDQwMykgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIlRoZSAnIiAuICR1cmwgLiAiJyBVUkwgY291bGQgbm90IGJlIGFjY2Vzc2VkOiAiIC4gJHJlYXNvbjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiVW5rbm93biBlcnJvciBjb2RlICciIC4gJHN0YXR1c0NvZGUgLiAiJywgcmVhc29uOiAiIC4gJHJlYXNvbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCRtZXNzYWdlLCAkc3RhdHVzQ29kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gZmFpbCBpZiB3ZSBhbHJlYWR5IGhhdmUgYXV0aAogICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbigiSW52YWxpZCBjcmVkZW50aWFscyBmb3IgJyIgLiAkdXJsIC4gIicsIGFib3J0aW5nLiIsICRzdGF0dXNDb2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgQXV0aGVudGljYXRpb24gcmVxdWlyZWQgKDxpbmZvPicuJG9yaWdpbi4nPC9pbmZvPik6Jyk7CiAgICAgICAgICAgICR1c2VybmFtZSA9ICR0aGlzLT5pby0+YXNrKCcgICAgICBVc2VybmFtZTogJyk7CiAgICAgICAgICAgICRwYXNzd29yZCA9ICR0aGlzLT5pby0+YXNrQW5kSGlkZUFuc3dlcignICAgICAgUGFzc3dvcmQ6ICcpOwogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW4sICR1c2VybmFtZSwgJHBhc3N3b3JkKTsKICAgICAgICAgICAgJHN0b3JlQXV0aCA9ICR0aGlzLT5jb25maWctPmdldCgnc3RvcmUtYXV0aHMnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgncmV0cnknID0+IHRydWUsICdzdG9yZUF1dGgnID0+ICRzdG9yZUF1dGgpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRoZWFkZXJzCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJG9yaWdpbgogICAgICogQHBhcmFtIHN0cmluZyAgICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIHVwZGF0ZWQgaGVhZGVycyBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQXV0aGVudGljYXRpb25IZWFkZXIoYXJyYXkgJGhlYWRlcnMsICRvcmlnaW4sICR1cmwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG9yaWdpbikpIHsKICAgICAgICAgICAgJGF1dGhlbnRpY2F0aW9uRGlzcGxheU1lc3NhZ2UgPSBudWxsOwogICAgICAgICAgICAkYXV0aCA9ICR0aGlzLT5pby0+Z2V0QXV0aGVudGljYXRpb24oJG9yaWdpbik7CiAgICAgICAgICAgIGlmICgkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ2JlYXJlcicpIHsKICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQXV0aG9yaXphdGlvbjogQmVhcmVyICcuJGF1dGhbJ3VzZXJuYW1lJ107CiAgICAgICAgICAgIH0gZWxzZWlmICgnZ2l0aHViLmNvbScgPT09ICRvcmlnaW4gJiYgJ3gtb2F1dGgtYmFzaWMnID09PSAkYXV0aFsncGFzc3dvcmQnXSkgewogICAgICAgICAgICAgICAgLy8gb25seSBhZGQgdGhlIGFjY2Vzc190b2tlbiBpZiBpdCBpcyBhY3R1YWxseSBhIGdpdGh1YiBBUEkgVVJMCiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15odHRwcz86Ly9hcGlcLmdpdGh1YlwuY29tL30nLCAkdXJsKSkgewogICAgICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQXV0aG9yaXphdGlvbjogdG9rZW4gJy4kYXV0aFsndXNlcm5hbWUnXTsKICAgICAgICAgICAgICAgICAgICAkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSA9ICdVc2luZyBHaXRIdWIgdG9rZW4gYXV0aGVudGljYXRpb24nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICBpbl9hcnJheSgkb3JpZ2luLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyksIHRydWUpCiAgICAgICAgICAgICAgICAmJiBpbl9hcnJheSgkYXV0aFsncGFzc3dvcmQnXSwgYXJyYXkoJ29hdXRoMicsICdwcml2YXRlLXRva2VuJywgJ2dpdGxhYi1jaS10b2tlbicpLCB0cnVlKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICgkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ29hdXRoMicpIHsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVyc1tdID0gJ0F1dGhvcml6YXRpb246IEJlYXJlciAnLiRhdXRoWyd1c2VybmFtZSddOwogICAgICAgICAgICAgICAgICAgICRhdXRoZW50aWNhdGlvbkRpc3BsYXlNZXNzYWdlID0gJ1VzaW5nIEdpdExhYiBPQXV0aCB0b2tlbiBhdXRoZW50aWNhdGlvbic7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnUFJJVkFURS1UT0tFTjogJy4kYXV0aFsndXNlcm5hbWUnXTsKICAgICAgICAgICAgICAgICAgICAkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSA9ICdVc2luZyBHaXRMYWIgcHJpdmF0ZSB0b2tlbiBhdXRoZW50aWNhdGlvbic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgICAgICdiaXRidWNrZXQub3JnJyA9PT0gJG9yaWdpbgogICAgICAgICAgICAgICAgJiYgJHVybCAhPT0gQml0YnVja2V0OjpPQVVUSDJfQUNDRVNTX1RPS0VOX1VSTAogICAgICAgICAgICAgICAgJiYgJ3gtdG9rZW4tYXV0aCcgPT09ICRhdXRoWyd1c2VybmFtZSddCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aXNQdWJsaWNCaXRCdWNrZXREb3dubG9hZCgkdXJsKSkgewogICAgICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQXV0aG9yaXphdGlvbjogQmVhcmVyICcgLiAkYXV0aFsncGFzc3dvcmQnXTsKICAgICAgICAgICAgICAgICAgICAkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSA9ICdVc2luZyBCaXRidWNrZXQgT0F1dGggdG9rZW4gYXV0aGVudGljYXRpb24nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGF1dGhTdHIgPSBiYXNlNjRfZW5jb2RlKCRhdXRoWyd1c2VybmFtZSddIC4gJzonIC4gJGF1dGhbJ3Bhc3N3b3JkJ10pOwogICAgICAgICAgICAgICAgJGhlYWRlcnNbXSA9ICdBdXRob3JpemF0aW9uOiBCYXNpYyAnLiRhdXRoU3RyOwogICAgICAgICAgICAgICAgJGF1dGhlbnRpY2F0aW9uRGlzcGxheU1lc3NhZ2UgPSAnVXNpbmcgSFRUUCBiYXNpYyBhdXRoZW50aWNhdGlvbiB3aXRoIHVzZXJuYW1lICInIC4gJGF1dGhbJ3VzZXJuYW1lJ10gLiAnIic7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSAmJiAoIWlzc2V0KCR0aGlzLT5kaXNwbGF5ZWRPcmlnaW5BdXRoZW50aWNhdGlvbnNbJG9yaWdpbl0pIHx8ICR0aGlzLT5kaXNwbGF5ZWRPcmlnaW5BdXRoZW50aWNhdGlvbnNbJG9yaWdpbl0gIT09ICRhdXRoZW50aWNhdGlvbkRpc3BsYXlNZXNzYWdlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRhdXRoZW50aWNhdGlvbkRpc3BsYXlNZXNzYWdlLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXllZE9yaWdpbkF1dGhlbnRpY2F0aW9uc1skb3JpZ2luXSA9ICRhdXRoZW50aWNhdGlvbkRpc3BsYXlNZXNzYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCRvcmlnaW4sIGFycmF5KCdhcGkuYml0YnVja2V0Lm9yZycsICdhcGkuZ2l0aHViLmNvbScpLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmFkZEF1dGhlbnRpY2F0aW9uSGVhZGVyKCRoZWFkZXJzLCBzdHJfcmVwbGFjZSgnYXBpLicsICcnLCAkb3JpZ2luKSwgJHVybCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGhlYWRlcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAbGluayBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzU1ODQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmxUb0JpdEJ1Y2tldEZpbGUgVVJMIHRvIGEgZmlsZSBhdCBiaXRidWNrZXQub3JnLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBnaXZlbiBVUkwgaXMgYSBwdWJsaWMgQml0QnVja2V0IGRvd25sb2FkIHdoaWNoIHJlcXVpcmVzIG5vIGF1dGhlbnRpY2F0aW9uLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNQdWJsaWNCaXRCdWNrZXREb3dubG9hZCgkdXJsVG9CaXRCdWNrZXRGaWxlKQogICAgewogICAgICAgICRkb21haW4gPSBwYXJzZV91cmwoJHVybFRvQml0QnVja2V0RmlsZSwgUEhQX1VSTF9IT1NUKTsKICAgICAgICBpZiAoc3RycG9zKCRkb21haW4sICdiaXRidWNrZXQub3JnJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIC8vIEJpdGJ1Y2tldCBkb3dubG9hZHMgYXJlIGhvc3RlZCBvbiBhbWF6b25hd3MuCiAgICAgICAgICAgIC8vIFdlIGRvIG5vdCBuZWVkIHRvIGF1dGhlbnRpY2F0ZSB0aGVyZSBhdCBhbGwKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkcGF0aCA9IHBhcnNlX3VybCgkdXJsVG9CaXRCdWNrZXRGaWxlLCBQSFBfVVJMX1BBVEgpOwoKICAgICAgICAvLyBQYXRoIGZvciBhIHB1YmxpYyBkb3dubG9hZCBmb2xsb3dzIHRoaXMgcGF0dGVybiAve3VzZXJ9L3tyZXBvfS9kb3dubG9hZHMve3doYXRldmVyfQogICAgICAgIC8vIHtAbGluayBodHRwczovL2Jsb2cuYml0YnVja2V0Lm9yZy8yMDA5LzA0LzEyL25ldy1mZWF0dXJlLWRvd25sb2Fkcy99CiAgICAgICAgJHBhdGhQYXJ0cyA9IGV4cGxvZGUoJy8nLCAkcGF0aCk7CgogICAgICAgIHJldHVybiBjb3VudCgkcGF0aFBhcnRzKSA+PSA0ICYmICRwYXRoUGFydHNbM10gPT0gJ2Rvd25sb2Fkcyc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXFZhbGlkYXRpbmdBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXEludmFsaWRQYWNrYWdlRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFNwZHhcU3BkeExpY2Vuc2VzOwoKLyoqCiAqIFZhbGlkYXRlcyBhIGNvbXBvc2VyIGNvbmZpZ3VyYXRpb24uCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDb25maWdWYWxpZGF0b3IKewogICAgY29uc3QgQ0hFQ0tfVkVSU0lPTiA9IDE7CgogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBjb25maWcsIGFuZCByZXR1cm5zIHRoZSByZXN1bHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSAgICAgICAgICAgICAgICAgICAgICAgVGhlIHBhdGggdG8gdGhlIGZpbGUKICAgICAqIEBwYXJhbSBpbnQgICAgJGFycmF5TG9hZGVyVmFsaWRhdGlvbkZsYWdzIEZsYWdzIGZvciBBcnJheUxvYWRlciB2YWxpZGF0aW9uCiAgICAgKiBAcGFyYW0gaW50ICAgICRmbGFncyAgICAgICAgICAgICAgICAgICAgICBGbGFncyBmb3IgdmFsaWRhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7bGlzdDxzdHJpbmc+LCBsaXN0PHN0cmluZz4sIGxpc3Q8c3RyaW5nPn0gYSB0cmlwbGUgY29udGFpbmluZyB0aGUgZXJyb3JzLCBwdWJsaXNoYWJsZSBlcnJvcnMsIGFuZCB3YXJuaW5ncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGUoJGZpbGUsICRhcnJheUxvYWRlclZhbGlkYXRpb25GbGFncyA9IFZhbGlkYXRpbmdBcnJheUxvYWRlcjo6Q0hFQ0tfQUxMLCAkZmxhZ3MgPSBzZWxmOjpDSEVDS19WRVJTSU9OKQogICAgewogICAgICAgICRlcnJvcnMgPSBhcnJheSgpOwogICAgICAgICRwdWJsaXNoRXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkd2FybmluZ3MgPSBhcnJheSgpOwoKICAgICAgICAvLyB2YWxpZGF0ZSBqc29uIHNjaGVtYQogICAgICAgICRsYXhWYWxpZCA9IGZhbHNlOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRqc29uID0gbmV3IEpzb25GaWxlKCRmaWxlLCBudWxsLCAkdGhpcy0+aW8pOwogICAgICAgICAgICAkbWFuaWZlc3QgPSAkanNvbi0+cmVhZCgpOwoKICAgICAgICAgICAgJGpzb24tPnZhbGlkYXRlU2NoZW1hKEpzb25GaWxlOjpMQVhfU0NIRU1BKTsKICAgICAgICAgICAgJGxheFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgJGpzb24tPnZhbGlkYXRlU2NoZW1hKCk7CiAgICAgICAgfSBjYXRjaCAoSnNvblZhbGlkYXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGUtPmdldEVycm9ycygpIGFzICRtZXNzYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGxheFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgJHB1Ymxpc2hFcnJvcnNbXSA9ICRtZXNzYWdlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZXJyb3JzW10gPSAkbWVzc2FnZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGVycm9yc1tdID0gJGUtPmdldE1lc3NhZ2UoKTsKCiAgICAgICAgICAgIHJldHVybiBhcnJheSgkZXJyb3JzLCAkcHVibGlzaEVycm9ycywgJHdhcm5pbmdzKTsKICAgICAgICB9CgogICAgICAgIC8vIHZhbGlkYXRlIGFjdHVhbCBkYXRhCiAgICAgICAgaWYgKGVtcHR5KCRtYW5pZmVzdFsnbGljZW5zZSddKSkgewogICAgICAgICAgICAkd2FybmluZ3NbXSA9ICdObyBsaWNlbnNlIHNwZWNpZmllZCwgaXQgaXMgcmVjb21tZW5kZWQgdG8gZG8gc28uIEZvciBjbG9zZWQtc291cmNlIHNvZnR3YXJlIHlvdSBtYXkgdXNlICJwcm9wcmlldGFyeSIgYXMgbGljZW5zZS4nOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsaWNlbnNlcyA9IChhcnJheSkgJG1hbmlmZXN0WydsaWNlbnNlJ107CgogICAgICAgICAgICAvLyBzdHJpcCBwcm9wcmlldGFyeSBzaW5jZSBpdCdzIG5vdCBhIHZhbGlkIFNQRFggaWRlbnRpZmllciwgYnV0IGlzIGFjY2VwdGVkIGJ5IGNvbXBvc2VyCiAgICAgICAgICAgIGZvcmVhY2ggKCRsaWNlbnNlcyBhcyAka2V5ID0+ICRsaWNlbnNlKSB7CiAgICAgICAgICAgICAgICBpZiAoJ3Byb3ByaWV0YXJ5JyA9PT0gJGxpY2Vuc2UpIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkbGljZW5zZXNbJGtleV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGljZW5zZVZhbGlkYXRvciA9IG5ldyBTcGR4TGljZW5zZXMoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxpY2Vuc2VzIGFzICRsaWNlbnNlKSB7CiAgICAgICAgICAgICAgICAkc3BkeExpY2Vuc2UgPSAkbGljZW5zZVZhbGlkYXRvci0+Z2V0TGljZW5zZUJ5SWRlbnRpZmllcigkbGljZW5zZSk7CiAgICAgICAgICAgICAgICBpZiAoJHNwZHhMaWNlbnNlICYmICRzcGR4TGljZW5zZVszXSkgewogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XltBTF0/R1BMLVsxMjNdKFwuWzAxXSk/XCskfWknLCAkbGljZW5zZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHdhcm5pbmdzW10gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0xpY2Vuc2UgIiVzIiBpcyBhIGRlcHJlY2F0ZWQgU1BEWCBsaWNlbnNlIGlkZW50aWZpZXIsIHVzZSAiJy5zdHJfcmVwbGFjZSgnKycsICcnLCAkbGljZW5zZSkuJy1vci1sYXRlciIgaW5zdGVhZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGljZW5zZQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChQcmVnOjppc01hdGNoKCd7XltBTF0/R1BMLVsxMjNdKFwuWzAxXSk/JH1pJywgJGxpY2Vuc2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR3YXJuaW5nc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdMaWNlbnNlICIlcyIgaXMgYSBkZXByZWNhdGVkIFNQRFggbGljZW5zZSBpZGVudGlmaWVyLCB1c2UgIicuJGxpY2Vuc2UuJy1vbmx5IiBvciAiJy4kbGljZW5zZS4nLW9yLWxhdGVyIiBpbnN0ZWFkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHdhcm5pbmdzW10gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0xpY2Vuc2UgIiVzIiBpcyBhIGRlcHJlY2F0ZWQgU1BEWCBsaWNlbnNlIGlkZW50aWZpZXIsIHNlZSBodHRwczovL3NwZHgub3JnL2xpY2Vuc2VzLycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGljZW5zZQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCgkZmxhZ3MgJiBzZWxmOjpDSEVDS19WRVJTSU9OKSAmJiBpc3NldCgkbWFuaWZlc3RbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAnVGhlIHZlcnNpb24gZmllbGQgaXMgcHJlc2VudCwgaXQgaXMgcmVjb21tZW5kZWQgdG8gbGVhdmUgaXQgb3V0IGlmIHRoZSBwYWNrYWdlIGlzIHB1Ymxpc2hlZCBvbiBQYWNrYWdpc3QuJzsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJG1hbmlmZXN0WyduYW1lJ10pICYmIFByZWc6OmlzTWF0Y2goJ3tbQS1aXX0nLCAkbWFuaWZlc3RbJ25hbWUnXSkpIHsKICAgICAgICAgICAgJHN1Z2dlc3ROYW1lID0gUHJlZzo6cmVwbGFjZSgneyg/OihbYS16XSkoW0EtWl0pfChbQS1aXSkoW0EtWl1bYS16XSkpfScsICdcXDFcXDMtXFwyXFw0JywgJG1hbmlmZXN0WyduYW1lJ10pOwogICAgICAgICAgICAkc3VnZ2VzdE5hbWUgPSBzdHJ0b2xvd2VyKCRzdWdnZXN0TmFtZSk7CgogICAgICAgICAgICAkcHVibGlzaEVycm9yc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICdOYW1lICIlcyIgZG9lcyBub3QgbWF0Y2ggdGhlIGJlc3QgcHJhY3RpY2UgKGUuZy4gbG93ZXItY2FzZWQvd2l0aC1kYXNoZXMpLiBXZSBzdWdnZXN0IHVzaW5nICIlcyIgaW5zdGVhZC4gQXMgc3VjaCB5b3Ugd2lsbCBub3QgYmUgYWJsZSB0byBzdWJtaXQgaXQgdG8gUGFja2FnaXN0LicsCiAgICAgICAgICAgICAgICAkbWFuaWZlc3RbJ25hbWUnXSwKICAgICAgICAgICAgICAgICRzdWdnZXN0TmFtZQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkbWFuaWZlc3RbJ3R5cGUnXSkgJiYgJG1hbmlmZXN0Wyd0eXBlJ10gPT0gJ2NvbXBvc2VyLWluc3RhbGxlcicpIHsKICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAiVGhlIHBhY2thZ2UgdHlwZSAnY29tcG9zZXItaW5zdGFsbGVyJyBpcyBkZXByZWNhdGVkLiBQbGVhc2UgZGlzdHJpYnV0ZSB5b3VyIGN1c3RvbSBpbnN0YWxsZXJzIGFzIHBsdWdpbnMgZnJvbSBub3cgb24uIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvcGx1Z2lucy5tZCBmb3IgcGx1Z2luIGRvY3VtZW50YXRpb24uIjsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlLWRldiBvdmVycmlkZXMKICAgICAgICBpZiAoaXNzZXQoJG1hbmlmZXN0WydyZXF1aXJlJ10sICRtYW5pZmVzdFsncmVxdWlyZS1kZXYnXSkpIHsKICAgICAgICAgICAgJHJlcXVpcmVPdmVycmlkZXMgPSBhcnJheV9pbnRlcnNlY3Rfa2V5KCRtYW5pZmVzdFsncmVxdWlyZSddLCAkbWFuaWZlc3RbJ3JlcXVpcmUtZGV2J10pOwoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkcmVxdWlyZU92ZXJyaWRlcykpIHsKICAgICAgICAgICAgICAgICRwbHVyYWwgPSAoY291bnQoJHJlcXVpcmVPdmVycmlkZXMpID4gMSkgPyAnYXJlJyA6ICdpcyc7CiAgICAgICAgICAgICAgICAkd2FybmluZ3NbXSA9IGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkcmVxdWlyZU92ZXJyaWRlcykpLiAiIHskcGx1cmFsfSByZXF1aXJlZCBib3RoIGluIHJlcXVpcmUgYW5kIHJlcXVpcmUtZGV2LCB0aGlzIGNhbiBsZWFkIHRvIHVuZXhwZWN0ZWQgYmVoYXZpb3IiOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBmb3IgbWVhbmluZ2xlc3MgcHJvdmlkZS9yZXBsYWNlIHNhdGlzZnlpbmcgcmVxdWlyZW1lbnRzCiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3Byb3ZpZGUnLCAncmVwbGFjZScpIGFzICRsaW5rVHlwZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJG1hbmlmZXN0WyRsaW5rVHlwZV0pKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheSgncmVxdWlyZScsICdyZXF1aXJlLWRldicpIGFzICRyZXF1aXJlVHlwZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWFuaWZlc3RbJHJlcXVpcmVUeXBlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hbmlmZXN0WyRsaW5rVHlwZV0gYXMgJHByb3ZpZGUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWFuaWZlc3RbJHJlcXVpcmVUeXBlXVskcHJvdmlkZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAnVGhlIHBhY2thZ2UgJyAuICRwcm92aWRlIC4gJyBpbiAnLiRyZXF1aXJlVHlwZS4nIGlzIGFsc28gbGlzdGVkIGluICcuJGxpbmtUeXBlLicgd2hpY2ggc2F0aXNmaWVzIHRoZSByZXF1aXJlbWVudC4gUmVtb3ZlIGl0IGZyb20gJy4kbGlua1R5cGUuJyBpZiB5b3Ugd2lzaCB0byBpbnN0YWxsIGl0Lic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBjb21taXQgcmVmZXJlbmNlcwogICAgICAgICRyZXF1aXJlID0gaXNzZXQoJG1hbmlmZXN0WydyZXF1aXJlJ10pID8gJG1hbmlmZXN0WydyZXF1aXJlJ10gOiBhcnJheSgpOwogICAgICAgICRyZXF1aXJlRGV2ID0gaXNzZXQoJG1hbmlmZXN0WydyZXF1aXJlLWRldiddKSA/ICRtYW5pZmVzdFsncmVxdWlyZS1kZXYnXSA6IGFycmF5KCk7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJHJlcXVpcmUsICRyZXF1aXJlRGV2KTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UgPT4gJHZlcnNpb24pIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy8jLycsICR2ZXJzaW9uKSkgewogICAgICAgICAgICAgICAgJHdhcm5pbmdzW10gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdUaGUgcGFja2FnZSAiJXMiIGlzIHBvaW50aW5nIHRvIGEgY29tbWl0LXJlZiwgdGhpcyBpcyBiYWQgcHJhY3RpY2UgYW5kIGNhbiBjYXVzZSB1bmZvcmVzZWVuIGlzc3Vlcy4nLAogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZXBvcnQgc2NyaXB0cy1kZXNjcmlwdGlvbnMgZm9yIG5vbi1leGlzdGVudCBzY3JpcHRzCiAgICAgICAgJHNjcmlwdHNEZXNjcmlwdGlvbnMgPSBpc3NldCgkbWFuaWZlc3RbJ3NjcmlwdHMtZGVzY3JpcHRpb25zJ10pID8gJG1hbmlmZXN0WydzY3JpcHRzLWRlc2NyaXB0aW9ucyddIDogYXJyYXkoKTsKICAgICAgICAkc2NyaXB0cyA9IGlzc2V0KCRtYW5pZmVzdFsnc2NyaXB0cyddKSA/ICRtYW5pZmVzdFsnc2NyaXB0cyddIDogYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkc2NyaXB0c0Rlc2NyaXB0aW9ucyBhcyAkc2NyaXB0TmFtZSA9PiAkc2NyaXB0RGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRzY3JpcHROYW1lLCAkc2NyaXB0cykpIHsKICAgICAgICAgICAgICAgICR3YXJuaW5nc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnRGVzY3JpcHRpb24gZm9yIG5vbi1leGlzdGVudCBzY3JpcHQgIiVzIiBmb3VuZCBpbiAic2NyaXB0cy1kZXNjcmlwdGlvbnMiJywKICAgICAgICAgICAgICAgICAgICAkc2NyaXB0TmFtZQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgZm9yIGVtcHR5IHBzci0wL3Bzci00IG5hbWVzcGFjZSBwcmVmaXhlcwogICAgICAgIGlmIChpc3NldCgkbWFuaWZlc3RbJ2F1dG9sb2FkJ11bJ3Bzci0wJ11bJyddKSkgewogICAgICAgICAgICAkd2FybmluZ3NbXSA9ICJEZWZpbmluZyBhdXRvbG9hZC5wc3ItMCB3aXRoIGFuIGVtcHR5IG5hbWVzcGFjZSBwcmVmaXggaXMgYSBiYWQgaWRlYSBmb3IgcGVyZm9ybWFuY2UiOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJG1hbmlmZXN0WydhdXRvbG9hZCddWydwc3ItNCddWycnXSkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAiRGVmaW5pbmcgYXV0b2xvYWQucHNyLTQgd2l0aCBhbiBlbXB0eSBuYW1lc3BhY2UgcHJlZml4IGlzIGEgYmFkIGlkZWEgZm9yIHBlcmZvcm1hbmNlIjsKICAgICAgICB9CgogICAgICAgICRsb2FkZXIgPSBuZXcgVmFsaWRhdGluZ0FycmF5TG9hZGVyKG5ldyBBcnJheUxvYWRlcigpLCB0cnVlLCBudWxsLCAkYXJyYXlMb2FkZXJWYWxpZGF0aW9uRmxhZ3MpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJG1hbmlmZXN0Wyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkbWFuaWZlc3RbJ3ZlcnNpb24nXSA9ICcxLjAuMCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkbWFuaWZlc3RbJ25hbWUnXSkpIHsKICAgICAgICAgICAgICAgICRtYW5pZmVzdFsnbmFtZSddID0gJ2R1bW15L2R1bW15JzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbG9hZGVyLT5sb2FkKCRtYW5pZmVzdCk7CiAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhY2thZ2VFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGVycm9ycyA9IGFycmF5X21lcmdlKCRlcnJvcnMsICRlLT5nZXRFcnJvcnMoKSk7CiAgICAgICAgfQoKICAgICAgICAkd2FybmluZ3MgPSBhcnJheV9tZXJnZSgkd2FybmluZ3MsICRsb2FkZXItPmdldFdhcm5pbmdzKCkpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJGVycm9ycywgJHB1Ymxpc2hFcnJvcnMsICR3YXJuaW5ncyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCi8qKgogKiBUZW1wb3JhcmlseSBzdXBwcmVzcyBQSFAgZXJyb3IgcmVwb3J0aW5nLCB1c3VhbGx5IHdhcm5pbmdzIGFuZCBiZWxvdy4KICoKICogQGF1dGhvciBOaWVscyBLZXVyZW50amVzIDxuaWVscy5rZXVyZW50amVzQG9taW5lcy5jb20+CiAqLwpjbGFzcyBTaWxlbmNlcgp7CiAgICAvKioKICAgICAqIEB2YXIgaW50W10gVW5wb3Agc3RhY2sKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHN0YWNrID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFN1cHByZXNzZXMgZ2l2ZW4gbWFzayBvciBlcnJvcnMuCiAgICAgKgogICAgICogQHBhcmFtICBpbnR8bnVsbCAkbWFzayBFcnJvciBsZXZlbHMgdG8gc3VwcHJlc3MsIGRlZmF1bHQgdmFsdWUgTlVMTCBpbmRpY2F0ZXMgYWxsIHdhcm5pbmdzIGFuZCBiZWxvdy4KICAgICAqIEByZXR1cm4gaW50ICAgICAgVGhlIG9sZCBlcnJvciByZXBvcnRpbmcgbGV2ZWwuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcHJlc3MoJG1hc2sgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNzZXQoJG1hc2spKSB7CiAgICAgICAgICAgICRtYXNrID0gRV9XQVJOSU5HIHwgRV9OT1RJQ0UgfCBFX1VTRVJfV0FSTklORyB8IEVfVVNFUl9OT1RJQ0UgfCBFX0RFUFJFQ0FURUQgfCBFX1VTRVJfREVQUkVDQVRFRCB8IEVfU1RSSUNUOwogICAgICAgIH0KICAgICAgICAkb2xkID0gZXJyb3JfcmVwb3J0aW5nKCk7CiAgICAgICAgc2VsZjo6JHN0YWNrW10gPSAkb2xkOwogICAgICAgIGVycm9yX3JlcG9ydGluZygkb2xkICYgfiRtYXNrKTsKCiAgICAgICAgcmV0dXJuICRvbGQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXN0b3JlcyBhIHNpbmdsZSBzdGF0ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXN0b3JlKCkKICAgIHsKICAgICAgICBpZiAoIWVtcHR5KHNlbGY6OiRzdGFjaykpIHsKICAgICAgICAgICAgZXJyb3JfcmVwb3J0aW5nKGFycmF5X3BvcChzZWxmOjokc3RhY2spKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxscyBhIHNwZWNpZmllZCBmdW5jdGlvbiB3aGlsZSBzaWxlbmNpbmcgd2FybmluZ3MgYW5kIGJlbG93LgogICAgICoKICAgICAqIEZ1dHVyZSBpbXByb3ZlbWVudDogd2hlbiBQSFAgcmVxdWlyZW1lbnRzIGFyZSByYWlzZWQgYWRkIENhbGxhYmxlIHR5cGUgaGludCAoNS40KSBhbmQgdmFyaWFkaWMgcGFyYW1ldGVycyAoNS42KQogICAgICoKICAgICAqIEBwYXJhbSAgY2FsbGFibGUgICAkY2FsbGFibGUgRnVuY3Rpb24gdG8gZXhlY3V0ZS4KICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiBBbnkgZXhjZXB0aW9ucyBmcm9tIHRoZSBjYWxsYmFjayBhcmUgcmV0aHJvd24uCiAgICAgKiBAcmV0dXJuIG1peGVkICAgICAgUmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjYWxsKCRjYWxsYWJsZSAvKiwgLi4uJHBhcmFtZXRlcnMgKi8pCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc2VsZjo6c3VwcHJlc3MoKTsKICAgICAgICAgICAgJHJlc3VsdCA9IGNhbGxfdXNlcl9mdW5jX2FycmF5KCRjYWxsYWJsZSwgYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAxKSk7CiAgICAgICAgICAgIHNlbGY6OnJlc3RvcmUoKTsKCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gVXNlIGEgZmluYWxseSBibG9jayBmb3IgdGhpcyB3aGVuIHJlcXVpcmVtZW50cyBhcmUgcmFpc2VkIHRvIFBIUCA1LjUKICAgICAgICAgICAgc2VsZjo6cmVzdG9yZSgpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxDYUJ1bmRsZVxDYUJ1bmRsZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKCi8qKgogKiBAYXV0aG9yIENocmlzIFNtaXRoIDxjaHJpc0BjczI3OC5vcmc+CiAqLwpmaW5hbCBjbGFzcyBUbHNIZWxwZXIKewogICAgLyoqCiAgICAgKiBNYXRjaCBob3N0bmFtZSBhZ2FpbnN0IGEgY2VydGlmaWNhdGUuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkY2VydGlmaWNhdGUgWC41MDkgY2VydGlmaWNhdGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGhvc3RuYW1lICAgIEhvc3RuYW1lIGluIHRoZSBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNuICAgICAgICAgIFNldCB0byB0aGUgY29tbW9uIG5hbWUgb2YgdGhlIGNlcnRpZmljYXRlIGlmZiBtYXRjaCBmb3VuZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrQ2VydGlmaWNhdGVIb3N0KCRjZXJ0aWZpY2F0ZSwgJGhvc3RuYW1lLCAmJGNuID0gbnVsbCkKICAgIHsKICAgICAgICAkbmFtZXMgPSBzZWxmOjpnZXRDZXJ0aWZpY2F0ZU5hbWVzKCRjZXJ0aWZpY2F0ZSk7CgogICAgICAgIGlmIChlbXB0eSgkbmFtZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjb21iaW5lZE5hbWVzID0gYXJyYXlfbWVyZ2UoJG5hbWVzWydzYW4nXSwgYXJyYXkoJG5hbWVzWydjbiddKSk7CiAgICAgICAgJGhvc3RuYW1lID0gc3RydG9sb3dlcigkaG9zdG5hbWUpOwoKICAgICAgICBmb3JlYWNoICgkY29tYmluZWROYW1lcyBhcyAkY2VydE5hbWUpIHsKICAgICAgICAgICAgJG1hdGNoZXIgPSBzZWxmOjpjZXJ0TmFtZU1hdGNoZXIoJGNlcnROYW1lKTsKCiAgICAgICAgICAgIGlmICgkbWF0Y2hlciAmJiAkbWF0Y2hlcigkaG9zdG5hbWUpKSB7CiAgICAgICAgICAgICAgICAkY24gPSAkbmFtZXNbJ2NuJ107CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgRE5TIG5hbWVzIG91dCBvZiBhbiBYLjUwOSBjZXJ0aWZpY2F0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGNlcnRpZmljYXRlIFguNTA5IGNlcnRpZmljYXRlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXtjbjogc3RyaW5nLCBzYW46IHN0cmluZ1tdfXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Q2VydGlmaWNhdGVOYW1lcygkY2VydGlmaWNhdGUpCiAgICB7CiAgICAgICAgaWYgKGlzX2FycmF5KCRjZXJ0aWZpY2F0ZSkpIHsKICAgICAgICAgICAgJGluZm8gPSAkY2VydGlmaWNhdGU7CiAgICAgICAgfSBlbHNlaWYgKENhQnVuZGxlOjppc09wZW5zc2xQYXJzZVNhZmUoKSkgewogICAgICAgICAgICAkaW5mbyA9IG9wZW5zc2xfeDUwOV9wYXJzZSgkY2VydGlmaWNhdGUsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJGluZm9bJ3N1YmplY3QnXVsnY29tbW9uTmFtZSddKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRjb21tb25OYW1lID0gc3RydG9sb3dlcigkaW5mb1snc3ViamVjdCddWydjb21tb25OYW1lJ10pOwogICAgICAgICRzdWJqZWN0QWx0TmFtZXMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoaXNzZXQoJGluZm9bJ2V4dGVuc2lvbnMnXVsnc3ViamVjdEFsdE5hbWUnXSkpIHsKICAgICAgICAgICAgJHN1YmplY3RBbHROYW1lcyA9IFByZWc6OnNwbGl0KCd7XHMqLFxzKn0nLCAkaW5mb1snZXh0ZW5zaW9ucyddWydzdWJqZWN0QWx0TmFtZSddKTsKICAgICAgICAgICAgJHN1YmplY3RBbHROYW1lcyA9IGFycmF5X2ZpbHRlcihhcnJheV9tYXAoZnVuY3Rpb24gKCRuYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRuYW1lLCAnRE5TOicpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cnRvbG93ZXIobHRyaW0oc3Vic3RyKCRuYW1lLCA0KSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9LCAkc3ViamVjdEFsdE5hbWVzKSk7CiAgICAgICAgICAgICRzdWJqZWN0QWx0TmFtZXMgPSBhcnJheV92YWx1ZXMoJHN1YmplY3RBbHROYW1lcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICdjbicgPT4gJGNvbW1vbk5hbWUsCiAgICAgICAgICAgICdzYW4nID0+ICRzdWJqZWN0QWx0TmFtZXMsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY2VydGlmaWNhdGUgcGluLgogICAgICoKICAgICAqIEJ5IEtldmluIE1jQXJ0aHVyIG9mIFN0b3JtVGlkZSBEaWdpdGFsIFN0dWRpb3MgSW5jLgogICAgICogQEtldmluU01jQXJ0aHVyIC8gaHR0cHM6Ly9naXRodWIuY29tL1N0b3JtVGlkZQogICAgICoKICAgICAqIFNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvZHJhZnQtaWV0Zi13ZWJzZWMta2V5LXBpbm5pbmctMDIKICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCB3YXMgYWRhcHRlZCBmcm9tIFNzbHVycC4KICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9FdmFuRG90UHJvL1NzbHVycAogICAgICoKICAgICAqIChjKSBFdmFuIENvdXJ5IDxtZUBldmFuY291cnkuY29tPgogICAgICoKICAgICAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSBzZWUgYmVsb3c6CiAgICAgKgogICAgICogQ29weXJpZ2h0IChjKSAyMDEzLCBFdmFuIENvdXJ5CiAgICAgKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogICAgICoKICAgICAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sCiAgICAgKiBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAgICAgKgogICAgICogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogICAgICogICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAqCiAgICAgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCiAgICAgKiAgICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCiAgICAgKiAgICAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICAgICAqCiAgICAgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTICJBUyBJUyIgQU5ECiAgICAgKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAogICAgICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQogICAgICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUgogICAgICogQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCiAgICAgKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CiAgICAgKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04KICAgICAqIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAgICAgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUwogICAgICogU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2VydGlmaWNhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Q2VydGlmaWNhdGVGaW5nZXJwcmludCgkY2VydGlmaWNhdGUpCiAgICB7CiAgICAgICAgJHB1YmtleWRldGFpbHMgPSBvcGVuc3NsX3BrZXlfZ2V0X2RldGFpbHMob3BlbnNzbF9nZXRfcHVibGlja2V5KCRjZXJ0aWZpY2F0ZSkpOwogICAgICAgICRwdWJrZXlwZW0gPSAkcHVia2V5ZGV0YWlsc1sna2V5J107CiAgICAgICAgLy9Db252ZXJ0IFBFTSB0byBERVIgYmVmb3JlIFNIQTEnaW5nCiAgICAgICAgJHN0YXJ0ID0gJy0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tJzsKICAgICAgICAkZW5kID0gJy0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSc7CiAgICAgICAgJHBlbXRyaW0gPSBzdWJzdHIoJHB1YmtleXBlbSwgc3RycG9zKCRwdWJrZXlwZW0sICRzdGFydCkgKyBzdHJsZW4oJHN0YXJ0KSwgKHN0cmxlbigkcHVia2V5cGVtKSAtIHN0cnBvcygkcHVia2V5cGVtLCAkZW5kKSkgKiAoLTEpKTsKICAgICAgICAkZGVyID0gYmFzZTY0X2RlY29kZSgkcGVtdHJpbSk7CgogICAgICAgIHJldHVybiBzaGExKCRkZXIpOwogICAgfQoKICAgIC8qKgogICAgICogVGVzdCBpZiBpdCBpcyBzYWZlIHRvIHVzZSB0aGUgUEhQIGZ1bmN0aW9uIG9wZW5zc2xfeDUwOV9wYXJzZSgpLgogICAgICoKICAgICAqIFRoaXMgY2hlY2tzIGlmIE9wZW5TU0wgZXh0ZW5zaW9ucyBpcyB2dWxuZXJhYmxlIHRvIHJlbW90ZSBjb2RlIGV4ZWN1dGlvbgogICAgICogdmlhIHRoZSBleHBsb2l0IGRvY3VtZW50ZWQgYXMgQ1ZFLTIwMTMtNjQyMC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc09wZW5zc2xQYXJzZVNhZmUoKQogICAgewogICAgICAgIHJldHVybiBDYUJ1bmRsZTo6aXNPcGVuc3NsUGFyc2VTYWZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0IGNlcnRpZmljYXRlIG5hbWUgaW50byBtYXRjaGluZyBmdW5jdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjZXJ0TmFtZSBDTi9TQU4KICAgICAqCiAgICAgKiBAcmV0dXJuIGNhbGxhYmxlfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY2VydE5hbWVNYXRjaGVyKCRjZXJ0TmFtZSkKICAgIHsKICAgICAgICAkd2lsZGNhcmRzID0gc3Vic3RyX2NvdW50KCRjZXJ0TmFtZSwgJyonKTsKCiAgICAgICAgaWYgKDAgPT09ICR3aWxkY2FyZHMpIHsKICAgICAgICAgICAgLy8gTGl0ZXJhbCBtYXRjaC4KICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkaG9zdG5hbWUpIHVzZSAoJGNlcnROYW1lKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGhvc3RuYW1lID09PSAkY2VydE5hbWU7CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBpZiAoMSA9PT0gJHdpbGRjYXJkcykgewogICAgICAgICAgICAkY29tcG9uZW50cyA9IGV4cGxvZGUoJy4nLCAkY2VydE5hbWUpOwoKICAgICAgICAgICAgaWYgKDMgPiBjb3VudCgkY29tcG9uZW50cykpIHsKICAgICAgICAgICAgICAgIC8vIE11c3QgaGF2ZSAzKyBjb21wb25lbnRzCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGZpcnN0Q29tcG9uZW50ID0gJGNvbXBvbmVudHNbMF07CgogICAgICAgICAgICAvLyBXaWxkY2FyZCBtdXN0IGJlIHRoZSBsYXN0IGNoYXJhY3Rlci4KICAgICAgICAgICAgaWYgKCcqJyAhPT0gJGZpcnN0Q29tcG9uZW50W3N0cmxlbigkZmlyc3RDb21wb25lbnQpIC0gMV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkd2lsZGNhcmRSZWdleCA9IHByZWdfcXVvdGUoJGNlcnROYW1lKTsKICAgICAgICAgICAgJHdpbGRjYXJkUmVnZXggPSBzdHJfcmVwbGFjZSgnXFwqJywgJ1thLXowLTktXSsnLCAkd2lsZGNhcmRSZWdleCk7CiAgICAgICAgICAgICR3aWxkY2FyZFJlZ2V4ID0gInteeyR3aWxkY2FyZFJlZ2V4fSR9IjsKCiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGhvc3RuYW1lKSB1c2UgKCR3aWxkY2FyZFJlZ2V4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gUHJlZzo6aXNNYXRjaCgkd2lsZGNhcmRSZWdleCwgJGhvc3RuYW1lKTsKICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CgovKioKICogQGF1dGhvciBQYXVsIFdlbmtlIDx3ZW5rZS5wYXVsQGdtYWlsLmNvbT4KICovCmNsYXNzIEJpdGJ1Y2tldAp7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJpdmF0ZSAkcHJvY2VzczsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcml2YXRlICRodHRwRG93bmxvYWRlcjsKICAgIC8qKiBAdmFyIGFycmF5e2FjY2Vzc190b2tlbjogc3RyaW5nLCBleHBpcmVzX2luPzogaW50fXxudWxsICovCiAgICBwcml2YXRlICR0b2tlbiA9IG51bGw7CiAgICAvKiogQHZhciBpbnR8bnVsbCAqLwogICAgcHJpdmF0ZSAkdGltZTsKCiAgICBjb25zdCBPQVVUSDJfQUNDRVNTX1RPS0VOX1VSTCA9ICdodHRwczovL2JpdGJ1Y2tldC5vcmcvc2l0ZS9vYXV0aDIvYWNjZXNzX3Rva2VuJzsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgJGlvICAgICAgICAgICAgIFRoZSBJTyBpbnN0YW5jZQogICAgICogQHBhcmFtIENvbmZpZyAgICAgICAgICAkY29uZmlnICAgICAgICAgVGhlIGNvbXBvc2VyIGNvbmZpZ3VyYXRpb24KICAgICAqIEBwYXJhbSBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgICAgICAgIFByb2Nlc3MgaW5zdGFuY2UsIGluamVjdGFibGUgZm9yIG1vY2tpbmcKICAgICAqIEBwYXJhbSBIdHRwRG93bmxvYWRlciAgJGh0dHBEb3dubG9hZGVyIFJlbW90ZSBGaWxlc3lzdGVtLCBpbmplY3RhYmxlIGZvciBtb2NraW5nCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICR0aW1lICAgICAgICAgICBUaW1lc3RhbXAsIGluamVjdGFibGUgZm9yIG1vY2tpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciA9IG51bGwsICR0aW1lID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzcyA/OiBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyID86IEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCR0aGlzLT5pbywgJGNvbmZpZyk7CiAgICAgICAgJHRoaXMtPnRpbWUgPSAkdGltZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUb2tlbigpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dG9rZW5bJ2FjY2Vzc190b2tlbiddKSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRva2VuWydhY2Nlc3NfdG9rZW4nXTsKICAgIH0KCiAgICAvKioKICAgICAqIEF0dGVtcHRzIHRvIGF1dGhvcml6ZSBhIEJpdGJ1Y2tldCBkb21haW4gdmlhIE9BdXRoCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG9yaWdpblVybCBUaGUgaG9zdCB0aGlzIEJpdGJ1Y2tldCBpbnN0YW5jZSBpcyBsb2NhdGVkIGF0CiAgICAgKiBAcmV0dXJuIGJvb2wgICB0cnVlIG9uIHN1Y2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGF1dGhvcml6ZU9BdXRoKCRvcmlnaW5VcmwpCiAgICB7CiAgICAgICAgaWYgKCRvcmlnaW5VcmwgIT09ICdiaXRidWNrZXQub3JnJykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBhdmFpbGFibGUgdXNlIHRva2VuIGZyb20gZ2l0IGNvbmZpZwogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNvbmZpZyBiaXRidWNrZXQuYWNjZXNzdG9rZW4nLCAkb3V0cHV0KSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW5VcmwsICd4LXRva2VuLWF1dGgnLCB0cmltKCRvdXRwdXQpKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVxdWVzdEFjY2Vzc1Rva2VuKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldChzZWxmOjpPQVVUSDJfQUNDRVNTX1RPS0VOX1VSTCwgYXJyYXkoCiAgICAgICAgICAgICAgICAncmV0cnktYXV0aC1mYWlsdXJlJyA9PiBmYWxzZSwKICAgICAgICAgICAgICAgICdodHRwJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbWV0aG9kJyA9PiAnUE9TVCcsCiAgICAgICAgICAgICAgICAgICAgJ2NvbnRlbnQnID0+ICdncmFudF90eXBlPWNsaWVudF9jcmVkZW50aWFscycsCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICApKTsKCiAgICAgICAgICAgICR0b2tlbiA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICBpZiAoIWlzc2V0KCR0b2tlblsnZXhwaXJlc19pbiddKSB8fCAhaXNzZXQoJHRva2VuWydhY2Nlc3NfdG9rZW4nXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0V4cGVjdGVkIGEgdG9rZW4gY29uZmlndXJlZCB3aXRoIGV4cGlyZXNfaW4gYW5kIGFjY2Vzc190b2tlbiBwcmVzZW50LCBnb3QgJy5qc29uX2VuY29kZSgkdG9rZW4pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnRva2VuID0gJHRva2VuOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGUtPmdldENvZGUoKSA9PT0gNDAwKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5JbnZhbGlkIE9BdXRoIGNvbnN1bWVyIHByb3ZpZGVkLjwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1RoaXMgY2FuIGhhdmUgdHdvIHJlYXNvbnM6Jyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzEuIFlvdSBhcmUgYXV0aGVudGljYXRpbmcgd2l0aCBhIGJpdGJ1Y2tldCB1c2VybmFtZS9wYXNzd29yZCBjb21iaW5hdGlvbicpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcyLiBZb3UgYXJlIHVzaW5nIGFuIE9BdXRoIGNvbnN1bWVyLCBidXQgZGlkblwndCBjb25maWd1cmUgYSAoZHVtbXkpIGNhbGxiYWNrIHVybCcpOwoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGUtPmdldENvZGUoKSwgYXJyYXkoNDAzLCA0MDEpKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+SW52YWxpZCBPQXV0aCBjb25zdW1lciBwcm92aWRlZC48L2Vycm9yPicpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdZb3UgY2FuIGFsc28gYWRkIGl0IG1hbnVhbGx5IGxhdGVyIGJ5IHVzaW5nICJjb21wb3NlciBjb25maWcgLS1nbG9iYWwgLS1hdXRoIGJpdGJ1Y2tldC1vYXV0aC5iaXRidWNrZXQub3JnIDxjb25zdW1lci1rZXk+IDxjb25zdW1lci1zZWNyZXQ+IicpOwoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEF1dGhvcml6ZXMgYSBCaXRidWNrZXQgZG9tYWluIGludGVyYWN0aXZlbHkgdmlhIE9BdXRoCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkb3JpZ2luVXJsIFRoZSBob3N0IHRoaXMgQml0YnVja2V0IGluc3RhbmNlIGlzIGxvY2F0ZWQgYXQKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgICBUaGUgcmVhc29uIHRoaXMgYXV0aG9yaXphdGlvbiBpcyByZXF1aXJlZAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb258XEV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlIG9uIHN1Y2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkb3JpZ2luVXJsLCAkbWVzc2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRtZXNzYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbWVzc2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkdXJsID0gJ2h0dHBzOi8vc3VwcG9ydC5hdGxhc3NpYW4uY29tL2JpdGJ1Y2tldC1jbG91ZC9kb2NzL3VzZS1vYXV0aC1vbi1iaXRidWNrZXQtY2xvdWQvJzsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignRm9sbG93IHRoZSBpbnN0cnVjdGlvbnMgb24gJXMnLCAkdXJsKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJ3RvIGNyZWF0ZSBhIGNvbnN1bWVyLiBJdCB3aWxsIGJlIHN0b3JlZCBpbiAiJXMiIGZvciBmdXR1cmUgdXNlIGJ5IENvbXBvc2VyLicsICR0aGlzLT5jb25maWctPmdldEF1dGhDb25maWdTb3VyY2UoKS0+Z2V0TmFtZSgpKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdFbnN1cmUgeW91IGVudGVyIGEgIkNhbGxiYWNrIFVSTCIgKGh0dHA6Ly9leGFtcGxlLmNvbSBpcyBmaW5lKSBvciBpdCB3aWxsIG5vdCBiZSBwb3NzaWJsZSB0byBjcmVhdGUgYW4gQWNjZXNzIFRva2VuICh0aGlzIGNhbGxiYWNrIHVybCB3aWxsIG5vdCBiZSB1c2VkIGJ5IGNvbXBvc2VyKScpOwoKICAgICAgICAkY29uc3VtZXJLZXkgPSB0cmltKChzdHJpbmcpICR0aGlzLT5pby0+YXNrQW5kSGlkZUFuc3dlcignQ29uc3VtZXIgS2V5IChoaWRkZW4pOiAnKSk7CgogICAgICAgIGlmICghJGNvbnN1bWVyS2V5KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Tm8gY29uc3VtZXIga2V5IGdpdmVuLCBhYm9ydGluZy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IGNhbiBhbHNvIGFkZCBpdCBtYW51YWxseSBsYXRlciBieSB1c2luZyAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tYXV0aCBiaXRidWNrZXQtb2F1dGguYml0YnVja2V0Lm9yZyA8Y29uc3VtZXIta2V5PiA8Y29uc3VtZXItc2VjcmV0PiInKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjb25zdW1lclNlY3JldCA9IHRyaW0oKHN0cmluZykgJHRoaXMtPmlvLT5hc2tBbmRIaWRlQW5zd2VyKCdDb25zdW1lciBTZWNyZXQgKGhpZGRlbik6ICcpKTsKCiAgICAgICAgaWYgKCEkY29uc3VtZXJTZWNyZXQpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5ObyBjb25zdW1lciBzZWNyZXQgZ2l2ZW4sIGFib3J0aW5nLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdZb3UgY2FuIGFsc28gYWRkIGl0IG1hbnVhbGx5IGxhdGVyIGJ5IHVzaW5nICJjb21wb3NlciBjb25maWcgLS1nbG9iYWwgLS1hdXRoIGJpdGJ1Y2tldC1vYXV0aC5iaXRidWNrZXQub3JnIDxjb25zdW1lci1rZXk+IDxjb25zdW1lci1zZWNyZXQ+IicpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAkY29uc3VtZXJLZXksICRjb25zdW1lclNlY3JldCk7CgogICAgICAgIGlmICghJHRoaXMtPnJlcXVlc3RBY2Nlc3NUb2tlbigpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIHN0b3JlIHZhbHVlIGluIHVzZXIgY29uZmlnCiAgICAgICAgJHRoaXMtPnN0b3JlSW5BdXRoQ29uZmlnKCRvcmlnaW5VcmwsICRjb25zdW1lcktleSwgJGNvbnN1bWVyU2VjcmV0KTsKCiAgICAgICAgLy8gUmVtb3ZlIGNvbmZsaWN0aW5nIGJhc2ljIGF1dGggY3JlZGVudGlhbHMgKGlmIGF2YWlsYWJsZSkKICAgICAgICAkdGhpcy0+Y29uZmlnLT5nZXRBdXRoQ29uZmlnU291cmNlKCktPnJlbW92ZUNvbmZpZ1NldHRpbmcoJ2h0dHAtYmFzaWMuJyAuICRvcmlnaW5VcmwpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPkNvbnN1bWVyIHN0b3JlZCBzdWNjZXNzZnVsbHkuPC9pbmZvPicpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyBhbiBhY2Nlc3MgdG9rZW4gZnJvbSBCaXRidWNrZXQuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG9yaWdpblVybAogICAgICogQHBhcmFtICBzdHJpbmcgJGNvbnN1bWVyS2V5CiAgICAgKiBAcGFyYW0gIHN0cmluZyAkY29uc3VtZXJTZWNyZXQKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXF1ZXN0VG9rZW4oJG9yaWdpblVybCwgJGNvbnN1bWVyS2V5LCAkY29uc3VtZXJTZWNyZXQpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT50b2tlbiAhPT0gbnVsbCB8fCAkdGhpcy0+Z2V0VG9rZW5Gcm9tQ29uZmlnKCRvcmlnaW5VcmwpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dG9rZW5bJ2FjY2Vzc190b2tlbiddOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAkY29uc3VtZXJLZXksICRjb25zdW1lclNlY3JldCk7CiAgICAgICAgaWYgKCEkdGhpcy0+cmVxdWVzdEFjY2Vzc1Rva2VuKCkpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0b3JlSW5BdXRoQ29uZmlnKCRvcmlnaW5VcmwsICRjb25zdW1lcktleSwgJGNvbnN1bWVyU2VjcmV0KTsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dG9rZW5bJ2FjY2Vzc190b2tlbiddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdGYWlsZWQgdG8gaW5pdGlhbGl6ZSB0b2tlbiBhYm92ZScpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50b2tlblsnYWNjZXNzX3Rva2VuJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZSB0aGUgbmV3L3VwZGF0ZWQgY3JlZGVudGlhbHMgdG8gdGhlIGNvbmZpZ3VyYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5VcmwKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN1bWVyS2V5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25zdW1lclNlY3JldAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0b3JlSW5BdXRoQ29uZmlnKCRvcmlnaW5VcmwsICRjb25zdW1lcktleSwgJGNvbnN1bWVyU2VjcmV0KQogICAgewogICAgICAgICR0aGlzLT5jb25maWctPmdldENvbmZpZ1NvdXJjZSgpLT5yZW1vdmVDb25maWdTZXR0aW5nKCdiaXRidWNrZXQtb2F1dGguJy4kb3JpZ2luVXJsKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50b2tlbiB8fCAhaXNzZXQoJHRoaXMtPnRva2VuWydleHBpcmVzX2luJ10pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0V4cGVjdGVkIGEgdG9rZW4gY29uZmlndXJlZCB3aXRoIGV4cGlyZXNfaW4gcHJlc2VudCwgZ290ICcuanNvbl9lbmNvZGUoJHRoaXMtPnRva2VuKSk7CiAgICAgICAgfQoKICAgICAgICAkdGltZSA9IG51bGwgPT09ICR0aGlzLT50aW1lID8gdGltZSgpIDogJHRoaXMtPnRpbWU7CiAgICAgICAgJGNvbnN1bWVyID0gYXJyYXkoCiAgICAgICAgICAgICJjb25zdW1lci1rZXkiID0+ICRjb25zdW1lcktleSwKICAgICAgICAgICAgImNvbnN1bWVyLXNlY3JldCIgPT4gJGNvbnN1bWVyU2VjcmV0LAogICAgICAgICAgICAiYWNjZXNzLXRva2VuIiA9PiAkdGhpcy0+dG9rZW5bJ2FjY2Vzc190b2tlbiddLAogICAgICAgICAgICAiYWNjZXNzLXRva2VuLWV4cGlyYXRpb24iID0+ICR0aW1lICsgJHRoaXMtPnRva2VuWydleHBpcmVzX2luJ10sCiAgICAgICAgKTsKCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpLT5hZGRDb25maWdTZXR0aW5nKCdiaXRidWNrZXQtb2F1dGguJy4kb3JpZ2luVXJsLCAkY29uc3VtZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG9yaWdpblVybAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0VG9rZW5Gcm9tQ29uZmlnKCRvcmlnaW5VcmwpCiAgICB7CiAgICAgICAgJGF1dGhDb25maWcgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2JpdGJ1Y2tldC1vYXV0aCcpOwoKICAgICAgICBpZiAoCiAgICAgICAgICAgICFpc3NldCgkYXV0aENvbmZpZ1skb3JpZ2luVXJsXVsnYWNjZXNzLXRva2VuJ10sICRhdXRoQ29uZmlnWyRvcmlnaW5VcmxdWydhY2Nlc3MtdG9rZW4tZXhwaXJhdGlvbiddKQogICAgICAgICAgICB8fCB0aW1lKCkgPiAkYXV0aENvbmZpZ1skb3JpZ2luVXJsXVsnYWNjZXNzLXRva2VuLWV4cGlyYXRpb24nXQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dG9rZW4gPSBhcnJheSgKICAgICAgICAgICAgJ2FjY2Vzc190b2tlbicgPT4gJGF1dGhDb25maWdbJG9yaWdpblVybF1bJ2FjY2Vzcy10b2tlbiddLAogICAgICAgICk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cFxSZXNwb25zZTsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cFxDdXJsRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcRXhjZXB0aW9uXElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZTsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBwaHBzdGFuLXR5cGUgUmVxdWVzdCBhcnJheXt1cmw6IHN0cmluZywgb3B0aW9ucz86IG1peGVkW10sIGNvcHlUbz86ID9zdHJpbmd9CiAqIEBwaHBzdGFuLXR5cGUgSm9iIGFycmF5e2lkOiBpbnQsIHN0YXR1czogaW50LCByZXF1ZXN0OiBSZXF1ZXN0LCBzeW5jOiBib29sLCBvcmlnaW46IHN0cmluZywgcmVzb2x2ZT86IGNhbGxhYmxlLCByZWplY3Q/OiBjYWxsYWJsZSwgY3VybF9pZD86IGludCwgcmVzcG9uc2U/OiBSZXNwb25zZSwgZXhjZXB0aW9uPzogVHJhbnNwb3J0RXhjZXB0aW9ufQogKi8KY2xhc3MgSHR0cERvd25sb2FkZXIKewogICAgY29uc3QgU1RBVFVTX1FVRVVFRCA9IDE7CiAgICBjb25zdCBTVEFUVVNfU1RBUlRFRCA9IDI7CiAgICBjb25zdCBTVEFUVVNfQ09NUExFVEVEID0gMzsKICAgIGNvbnN0IFNUQVRVU19GQUlMRUQgPSA0OwogICAgY29uc3QgU1RBVFVTX0FCT1JURUQgPSA1OwoKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcml2YXRlICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJpdmF0ZSAkY29uZmlnOwogICAgLyoqIEB2YXIgYXJyYXk8Sm9iPiAqLwogICAgcHJpdmF0ZSAkam9icyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBtaXhlZFtdICovCiAgICBwcml2YXRlICRvcHRpb25zID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkcnVubmluZ0pvYnMgPSAwOwogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICRtYXhKb2JzID0gMTI7CiAgICAvKiogQHZhciA/Q3VybERvd25sb2FkZXIgKi8KICAgIHByaXZhdGUgJGN1cmw7CiAgICAvKiogQHZhciA/UmVtb3RlRmlsZXN5c3RlbSAqLwogICAgcHJpdmF0ZSAkcmZzOwogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICRpZEdlbiA9IDA7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRkaXNhYmxlZDsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGFsbG93QXN5bmMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAkaW8gICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAkY29uZmlnICAgICBUaGUgY29uZmlnCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgICAgJG9wdGlvbnMgICAgVGhlIG9wdGlvbnMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkZGlzYWJsZVRscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpLCAkZGlzYWJsZVRscyA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKCiAgICAgICAgJHRoaXMtPmRpc2FibGVkID0gKGJvb2wpIFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX0RJU0FCTEVfTkVUV09SSycpOwoKICAgICAgICAvLyBTZXR1cCBUTFMgb3B0aW9ucwogICAgICAgIC8vIFRoZSBjYWZpbGUgb3B0aW9uIGNhbiBiZSBzZXQgdmlhIGNvbmZpZy5qc29uCiAgICAgICAgaWYgKCRkaXNhYmxlVGxzID09PSBmYWxzZSkgewogICAgICAgICAgICAkdGhpcy0+b3B0aW9ucyA9IFN0cmVhbUNvbnRleHRGYWN0b3J5OjpnZXRUbHNEZWZhdWx0cygkb3B0aW9ucywgJGlvKTsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSB0aGUgb3RoZXIgZXh0ZXJuYWxseSBzZXQgb3B0aW9ucyBub3JtYWxseS4KICAgICAgICAkdGhpcy0+b3B0aW9ucyA9IGFycmF5X3JlcGxhY2VfcmVjdXJzaXZlKCR0aGlzLT5vcHRpb25zLCAkb3B0aW9ucyk7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CgogICAgICAgIGlmIChzZWxmOjppc0N1cmxFbmFibGVkKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmN1cmwgPSBuZXcgQ3VybERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkb3B0aW9ucywgJGRpc2FibGVUbHMpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJmcyA9IG5ldyBSZW1vdGVGaWxlc3lzdGVtKCRpbywgJGNvbmZpZywgJG9wdGlvbnMsICRkaXNhYmxlVGxzKTsKCiAgICAgICAgaWYgKGlzX251bWVyaWMoJG1heEpvYnMgPSBQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9NQVhfUEFSQUxMRUxfSFRUUCcpKSkgewogICAgICAgICAgICAkdGhpcy0+bWF4Sm9icyA9IG1heCgxLCBtaW4oNTAsIChpbnQpICRtYXhKb2JzKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRG93bmxvYWQgYSBmaWxlIHN5bmNocm9ub3VzbHkKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAkdXJsICAgICBVUkwgdG8gZG93bmxvYWQKICAgICAqIEBwYXJhbSAgbWl4ZWRbXSAgICAgICAgICAgICRvcHRpb25zIFN0cmVhbSBjb250ZXh0IG9wdGlvbnMgZS5nLiBodHRwczovL3d3dy5waHAubmV0L21hbnVhbC9lbi9jb250ZXh0Lmh0dHAucGhwCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHRob3VnaCBub3QgYWxsIG9wdGlvbnMgYXJlIHN1cHBvcnRlZCB3aGVuIHVzaW5nIHRoZSBkZWZhdWx0IGN1cmwgZG93bmxvYWRlcgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gUmVzcG9uc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkdXJsLCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgbGlzdCgkam9iKSA9ICR0aGlzLT5hZGRKb2IoYXJyYXkoJ3VybCcgPT4gJHVybCwgJ29wdGlvbnMnID0+ICRvcHRpb25zLCAnY29weVRvJyA9PiBudWxsKSwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPndhaXQoJGpvYlsnaWQnXSk7CgogICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5nZXRSZXNwb25zZSgkam9iWydpZCddKTsKCiAgICAgICAgLy8gY2hlY2sgZm9yIGZhaWxlZCBjdXJsIHJlc3BvbnNlIChlbXB0eSBib2R5IGJ1dCBzdWNjZXNzZnVsIGxvb2tpbmcgcmVzcG9uc2UpCiAgICAgICAgaWYgKAogICAgICAgICAgICAkdGhpcy0+Y3VybAogICAgICAgICAgICAmJiBQSFBfVkVSU0lPTl9JRCA8IDcwMDAwCiAgICAgICAgICAgICYmICRyZXNwb25zZS0+Z2V0Qm9keSgpID09PSBudWxsCiAgICAgICAgICAgICYmICRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID09PSAyMDAKICAgICAgICAgICAgJiYgJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2NvbnRlbnQtbGVuZ3RoJykgIT09ICcwJwogICAgICAgICkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPmNVUkwgZG93bmxvYWRlciBmYWlsZWQgdG8gcmV0dXJuIGEgcmVzcG9uc2UsIGRpc2FibGluZyBpdCBhbmQgcHJvY2VlZGluZyBpbiBzbG93IG1vZGUuPC93YXJuaW5nPicpOwoKICAgICAgICAgICAgJHRoaXMtPmN1cmwgPSBudWxsOwoKICAgICAgICAgICAgbGlzdCgkam9iKSA9ICR0aGlzLT5hZGRKb2IoYXJyYXkoJ3VybCcgPT4gJHVybCwgJ29wdGlvbnMnID0+ICRvcHRpb25zLCAnY29weVRvJyA9PiBudWxsKSwgdHJ1ZSk7CiAgICAgICAgICAgICR0aGlzLT53YWl0KCRqb2JbJ2lkJ10pOwoKICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmdldFJlc3BvbnNlKCRqb2JbJ2lkJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXNwb25zZTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBhc3luYyBkb3dubG9hZCBvcGVyYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAkdXJsICAgICBVUkwgdG8gZG93bmxvYWQKICAgICAqIEBwYXJhbSAgbWl4ZWRbXSAgICAgICAgICAgICRvcHRpb25zIFN0cmVhbSBjb250ZXh0IG9wdGlvbnMgZS5nLiBodHRwczovL3d3dy5waHAubmV0L21hbnVhbC9lbi9jb250ZXh0Lmh0dHAucGhwCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHRob3VnaCBub3QgYWxsIG9wdGlvbnMgYXJlIHN1cHBvcnRlZCB3aGVuIHVzaW5nIHRoZSBkZWZhdWx0IGN1cmwgZG93bmxvYWRlcgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkKCR1cmwsICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBsaXN0KCwgJHByb21pc2UpID0gJHRoaXMtPmFkZEpvYihhcnJheSgndXJsJyA9PiAkdXJsLCAnb3B0aW9ucycgPT4gJG9wdGlvbnMsICdjb3B5VG8nID0+IG51bGwpKTsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlOwogICAgfQoKICAgIC8qKgogICAgICogQ29weSBhIGZpbGUgc3luY2hyb25vdXNseQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICR1cmwgICAgIFVSTCB0byBkb3dubG9hZAogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgJHRvICAgICAgUGF0aCB0byBjb3B5IHRvCiAgICAgKiBAcGFyYW0gIG1peGVkW10gICAgICAgICAgICAkb3B0aW9ucyBTdHJlYW0gY29udGV4dCBvcHRpb25zIGUuZy4gaHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vY29udGV4dC5odHRwLnBocAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0aG91Z2ggbm90IGFsbCBvcHRpb25zIGFyZSBzdXBwb3J0ZWQgd2hlbiB1c2luZyB0aGUgZGVmYXVsdCBjdXJsIGRvd25sb2FkZXIKICAgICAqIEB0aHJvd3MgVHJhbnNwb3J0RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIFJlc3BvbnNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3B5KCR1cmwsICR0bywgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIGxpc3QoJGpvYikgPSAkdGhpcy0+YWRkSm9iKGFycmF5KCd1cmwnID0+ICR1cmwsICdvcHRpb25zJyA9PiAkb3B0aW9ucywgJ2NvcHlUbycgPT4gJHRvKSwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPndhaXQoJGpvYlsnaWQnXSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UmVzcG9uc2UoJGpvYlsnaWQnXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gYXN5bmMgY29weSBvcGVyYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAkdXJsICAgICBVUkwgdG8gZG93bmxvYWQKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICR0byAgICAgIFBhdGggdG8gY29weSB0bwogICAgICogQHBhcmFtICBtaXhlZFtdICAgICAgICAgICAgJG9wdGlvbnMgU3RyZWFtIGNvbnRleHQgb3B0aW9ucyBlLmcuIGh0dHBzOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2NvbnRleHQuaHR0cC5waHAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdGhvdWdoIG5vdCBhbGwgb3B0aW9ucyBhcmUgc3VwcG9ydGVkIHdoZW4gdXNpbmcgdGhlIGRlZmF1bHQgY3VybCBkb3dubG9hZGVyCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb3B5KCR1cmwsICR0bywgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIGxpc3QoLCAkcHJvbWlzZSkgPSAkdGhpcy0+YWRkSm9iKGFycmF5KCd1cmwnID0+ICR1cmwsICdvcHRpb25zJyA9PiAkb3B0aW9ucywgJ2NvcHlUbycgPT4gJHRvKSk7CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlIHRoZSBvcHRpb25zIHNldCBpbiB0aGUgY29uc3RydWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkW10gT3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2VzIG5ldyBvcHRpb25zCiAgICAgKgogICAgICogQHBhcmFtICBtaXhlZFtdICRvcHRpb25zCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbnMoYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFJlcXVlc3QgJHJlcXVlc3QKICAgICAqIEBwYXJhbSBib29sICAgICRzeW5jCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXtKb2IsIFByb21pc2VJbnRlcmZhY2V9CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkSm9iKCRyZXF1ZXN0LCAkc3luYyA9IGZhbHNlKQogICAgewogICAgICAgICRyZXF1ZXN0WydvcHRpb25zJ10gPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+b3B0aW9ucywgJHJlcXVlc3RbJ29wdGlvbnMnXSk7CgogICAgICAgIC8qKiBAdmFyIEpvYiAqLwogICAgICAgICRqb2IgPSBhcnJheSgKICAgICAgICAgICAgJ2lkJyA9PiAkdGhpcy0+aWRHZW4rKywKICAgICAgICAgICAgJ3N0YXR1cycgPT4gc2VsZjo6U1RBVFVTX1FVRVVFRCwKICAgICAgICAgICAgJ3JlcXVlc3QnID0+ICRyZXF1ZXN0LAogICAgICAgICAgICAnc3luYycgPT4gJHN5bmMsCiAgICAgICAgICAgICdvcmlnaW4nID0+IFVybDo6Z2V0T3JpZ2luKCR0aGlzLT5jb25maWcsICRyZXF1ZXN0Wyd1cmwnXSksCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCEkc3luYyAmJiAhJHRoaXMtPmFsbG93QXN5bmMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignWW91IG11c3QgdXNlIHRoZSBIdHRwRG93bmxvYWRlciBpbnN0YW5jZSB3aGljaCBpcyBwYXJ0IG9mIGEgQ29tcG9zZXJcTG9vcCBpbnN0YW5jZSB0byBiZSBhYmxlIHRvIHJ1biBhc3luYyBodHRwIHJlcXVlc3RzJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjYXB0dXJlIHVzZXJuYW1lL3Bhc3N3b3JkIGZyb20gVVJMIGlmIHRoZXJlIGlzIG9uZQogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7Xmh0dHBzPzovLyhbXjovXSspOihbXkAvXSspQChbXi9dKyl9aScsICRyZXF1ZXN0Wyd1cmwnXSwgJG1hdGNoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRqb2JbJ29yaWdpbiddLCByYXd1cmxkZWNvZGUoJG1hdGNoWzFdKSwgcmF3dXJsZGVjb2RlKCRtYXRjaFsyXSkpOwogICAgICAgIH0KCiAgICAgICAgJHJmcyA9ICR0aGlzLT5yZnM7CgogICAgICAgIGlmICgkdGhpcy0+Y2FuVXNlQ3VybCgkam9iKSkgewogICAgICAgICAgICAkcmVzb2x2ZXIgPSBmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QpIHVzZSAoJiRqb2IpIHsKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19RVUVVRUQ7CiAgICAgICAgICAgICAgICAkam9iWydyZXNvbHZlJ10gPSAkcmVzb2x2ZTsKICAgICAgICAgICAgICAgICRqb2JbJ3JlamVjdCddID0gJHJlamVjdDsKICAgICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcmVzb2x2ZXIgPSBmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QpIHVzZSAoJiRqb2IsICRyZnMpIHsKICAgICAgICAgICAgICAgIC8vIHN0YXJ0IGpvYgogICAgICAgICAgICAgICAgJHVybCA9ICRqb2JbJ3JlcXVlc3QnXVsndXJsJ107CiAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddOwoKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19TVEFSVEVEOwoKICAgICAgICAgICAgICAgIGlmICgkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddKSB7CiAgICAgICAgICAgICAgICAgICAgJHJmcy0+Y29weSgkam9iWydvcmlnaW4nXSwgJHVybCwgJGpvYlsncmVxdWVzdCddWydjb3B5VG8nXSwgZmFsc2UgLyogVE9ETyBwcm9ncmVzcyAqLywgJG9wdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICAkaGVhZGVycyA9ICRyZnMtPmdldExhc3RIZWFkZXJzKCk7CiAgICAgICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gbmV3IEh0dHBcUmVzcG9uc2UoJGpvYlsncmVxdWVzdCddLCAkcmZzLT5maW5kU3RhdHVzQ29kZSgkaGVhZGVycyksICRoZWFkZXJzLCAkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddLid+Jyk7CgogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCRyZXNwb25zZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHJmcy0+Z2V0Q29udGVudHMoJGpvYlsnb3JpZ2luJ10sICR1cmwsIGZhbHNlIC8qIFRPRE8gcHJvZ3Jlc3MgKi8sICRvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVycyA9ICRyZnMtPmdldExhc3RIZWFkZXJzKCk7CiAgICAgICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gbmV3IEh0dHBcUmVzcG9uc2UoJGpvYlsncmVxdWVzdCddLCAkcmZzLT5maW5kU3RhdHVzQ29kZSgkaGVhZGVycyksICRoZWFkZXJzLCAkYm9keSk7CgogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCRyZXNwb25zZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzOwogICAgICAgICRjdXJsID0gJHRoaXMtPmN1cmw7CgogICAgICAgICRjYW5jZWxlciA9IGZ1bmN0aW9uICgpIHVzZSAoJiRqb2IsICRjdXJsKSB7CiAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSA9PT0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19RVUVVRUQpIHsKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19BQk9SVEVEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSAhPT0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19TVEFSVEVEKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBIdHRwRG93bmxvYWRlcjo6U1RBVFVTX0FCT1JURUQ7CiAgICAgICAgICAgIGlmIChpc3NldCgkam9iWydjdXJsX2lkJ10pKSB7CiAgICAgICAgICAgICAgICAkY3VybC0+YWJvcnRSZXF1ZXN0KCRqb2JbJ2N1cmxfaWQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbignRG93bmxvYWQgb2YgJyAuIFVybDo6c2FuaXRpemUoJGpvYlsncmVxdWVzdCddWyd1cmwnXSkgLiAnIGNhbmNlbGVkJyk7CiAgICAgICAgfTsKCiAgICAgICAgJHByb21pc2UgPSBuZXcgUHJvbWlzZSgkcmVzb2x2ZXIsICRjYW5jZWxlcik7CiAgICAgICAgJHByb21pc2UgPSAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoJHJlc3BvbnNlKSB1c2UgKCYkam9iLCAkZG93bmxvYWRlcikgewogICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IEh0dHBEb3dubG9hZGVyOjpTVEFUVVNfQ09NUExFVEVEOwogICAgICAgICAgICAkam9iWydyZXNwb25zZSddID0gJHJlc3BvbnNlOwoKICAgICAgICAgICAgLy8gVE9ETyAzLjAgdGhpcyBzaG91bGQgYmUgZG9uZSBkaXJlY3RseSBvbiAkdGhpcyB3aGVuIFBIUCA1LjMgaXMgZHJvcHBlZAogICAgICAgICAgICAkZG93bmxvYWRlci0+bWFya0pvYkRvbmUoKTsKCiAgICAgICAgICAgIHJldHVybiAkcmVzcG9uc2U7CiAgICAgICAgfSwgZnVuY3Rpb24gKCRlKSB1c2UgKCYkam9iLCAkZG93bmxvYWRlcikgewogICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IEh0dHBEb3dubG9hZGVyOjpTVEFUVVNfRkFJTEVEOwogICAgICAgICAgICAkam9iWydleGNlcHRpb24nXSA9ICRlOwoKICAgICAgICAgICAgJGRvd25sb2FkZXItPm1hcmtKb2JEb25lKCk7CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9KTsKICAgICAgICAkdGhpcy0+am9ic1skam9iWydpZCddXSA9ICYkam9iOwoKICAgICAgICBpZiAoJHRoaXMtPnJ1bm5pbmdKb2JzIDwgJHRoaXMtPm1heEpvYnMpIHsKICAgICAgICAgICAgJHRoaXMtPnN0YXJ0Sm9iKCRqb2JbJ2lkJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCRqb2IsICRwcm9taXNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgaW50ICAkaWQKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0Sm9iKCRpZCkKICAgIHsKICAgICAgICAkam9iID0gJiR0aGlzLT5qb2JzWyRpZF07CiAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddICE9PSBzZWxmOjpTVEFUVVNfUVVFVUVEKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIHN0YXJ0IGpvYgogICAgICAgICRqb2JbJ3N0YXR1cyddID0gc2VsZjo6U1RBVFVTX1NUQVJURUQ7CiAgICAgICAgJHRoaXMtPnJ1bm5pbmdKb2JzKys7CgogICAgICAgICRyZXNvbHZlID0gJGpvYlsncmVzb2x2ZSddOwogICAgICAgICRyZWplY3QgPSAkam9iWydyZWplY3QnXTsKICAgICAgICAkdXJsID0gJGpvYlsncmVxdWVzdCddWyd1cmwnXTsKICAgICAgICAkb3B0aW9ucyA9ICRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddOwogICAgICAgICRvcmlnaW4gPSAkam9iWydvcmlnaW4nXTsKCiAgICAgICAgaWYgKCR0aGlzLT5kaXNhYmxlZCkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGpvYlsncmVxdWVzdCddWydvcHRpb25zJ11bJ2h0dHAnXVsnaGVhZGVyJ10pICYmIGZhbHNlICE9PSBzdHJpcG9zKGltcGxvZGUoJycsICRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddWydodHRwJ11bJ2hlYWRlciddKSwgJ2lmLW1vZGlmaWVkLXNpbmNlJykpIHsKICAgICAgICAgICAgICAgICRyZXNvbHZlKG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAkdXJsKSwgMzA0LCBhcnJheSgpLCAnJykpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGUgPSBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdOZXR3b3JrIGRpc2FibGVkLCByZXF1ZXN0IGNhbmNlbGVkOiAnLlVybDo6c2FuaXRpemUoJHVybCksIDQ5OSk7CiAgICAgICAgICAgICAgICAkZS0+c2V0U3RhdHVzQ29kZSg0OTkpOwogICAgICAgICAgICAgICAgJHJlamVjdCgkZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddKSB7CiAgICAgICAgICAgICAgICAkam9iWydjdXJsX2lkJ10gPSAkdGhpcy0+Y3VybC0+ZG93bmxvYWQoJHJlc29sdmUsICRyZWplY3QsICRvcmlnaW4sICR1cmwsICRvcHRpb25zLCAkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRqb2JbJ2N1cmxfaWQnXSA9ICR0aGlzLT5jdXJsLT5kb3dubG9hZCgkcmVzb2x2ZSwgJHJlamVjdCwgJG9yaWdpbiwgJHVybCwgJG9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICRyZWplY3QoJGV4Y2VwdGlvbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHByaXZhdGUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFya0pvYkRvbmUoKQogICAgewogICAgICAgICR0aGlzLT5ydW5uaW5nSm9icy0tOwogICAgfQoKICAgIC8qKgogICAgICogV2FpdCBmb3IgY3VycmVudCBhc3luYyBkb3dubG9hZCBqb2JzIHRvIGNvbXBsZXRlCiAgICAgKgogICAgICogQHBhcmFtIGludHxudWxsICRpbmRleCBGb3IgaW50ZXJuYWwgdXNlIG9ubHksIHRoZSBqb2IgaWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhaXQoJGluZGV4ID0gbnVsbCkKICAgIHsKICAgICAgICBkbyB7CiAgICAgICAgICAgICRqb2JDb3VudCA9ICR0aGlzLT5jb3VudEFjdGl2ZUpvYnMoJGluZGV4KTsKICAgICAgICB9IHdoaWxlICgkam9iQ291bnQpOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVBc3luYygpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsbG93QXN5bmMgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKgogICAgICogQHBhcmFtICBpbnR8bnVsbCAkaW5kZXggRm9yIGludGVybmFsIHVzZSBvbmx5LCB0aGUgam9iIGlkCiAgICAgKiBAcmV0dXJuIGludCAgICAgIG51bWJlciBvZiBhY3RpdmUgKHF1ZXVlZCBvciBzdGFydGVkKSBqb2JzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudEFjdGl2ZUpvYnMoJGluZGV4ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnJ1bm5pbmdKb2JzIDwgJHRoaXMtPm1heEpvYnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmpvYnMgYXMgJGpvYikgewogICAgICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddID09PSBzZWxmOjpTVEFUVVNfUVVFVUVEICYmICR0aGlzLT5ydW5uaW5nSm9icyA8ICR0aGlzLT5tYXhKb2JzKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnN0YXJ0Sm9iKCRqb2JbJ2lkJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmN1cmwpIHsKICAgICAgICAgICAgJHRoaXMtPmN1cmwtPnRpY2soKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkaW5kZXgpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5qb2JzWyRpbmRleF1bJ3N0YXR1cyddIDwgc2VsZjo6U1RBVFVTX0NPTVBMRVRFRCA/IDEgOiAwOwogICAgICAgIH0KCiAgICAgICAgJGFjdGl2ZSA9IDA7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmpvYnMgYXMgJGpvYikgewogICAgICAgICAgICBpZiAoJGpvYlsnc3RhdHVzJ10gPCBzZWxmOjpTVEFUVVNfQ09NUExFVEVEKSB7CiAgICAgICAgICAgICAgICAkYWN0aXZlKys7CiAgICAgICAgICAgIH0gZWxzZWlmICghJGpvYlsnc3luYyddKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+am9ic1skam9iWydpZCddXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkYWN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgJGluZGV4IEpvYiBpZAogICAgICogQHJldHVybiBSZXNwb25zZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFJlc3BvbnNlKCRpbmRleCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5qb2JzWyRpbmRleF0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0ludmFsaWQgcmVxdWVzdCBpZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5qb2JzWyRpbmRleF1bJ3N0YXR1cyddID09PSBzZWxmOjpTVEFUVVNfRkFJTEVEKSB7CiAgICAgICAgICAgIHRocm93ICR0aGlzLT5qb2JzWyRpbmRleF1bJ2V4Y2VwdGlvbiddOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+am9ic1skaW5kZXhdWydyZXNwb25zZSddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdSZXNwb25zZSBub3QgYXZhaWxhYmxlIHlldCwgY2FsbCB3YWl0KCkgZmlyc3QnKTsKICAgICAgICB9CgogICAgICAgICRyZXNwID0gJHRoaXMtPmpvYnNbJGluZGV4XVsncmVzcG9uc2UnXTsKCiAgICAgICAgdW5zZXQoJHRoaXMtPmpvYnNbJGluZGV4XSk7CgogICAgICAgIHJldHVybiAkcmVzcDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHVybAogICAgICogQHBhcmFtICBhcnJheXt3YXJuaW5nPzogc3RyaW5nLCBpbmZvPzogc3RyaW5nLCB3YXJuaW5nLXZlcnNpb25zPzogc3RyaW5nLCBpbmZvLXZlcnNpb25zPzogc3RyaW5nLCB3YXJuaW5ncz86IGFycmF5PGFycmF5e3ZlcnNpb25zOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZ30+LCBpbmZvcz86IGFycmF5PGFycmF5e3ZlcnNpb25zOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZ30+fSAkZGF0YQogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gb3V0cHV0V2FybmluZ3MoSU9JbnRlcmZhY2UgJGlvLCAkdXJsLCAkZGF0YSkKICAgIHsKICAgICAgICAvLyBsZWdhY3kgd2FybmluZy9pbmZvIGtleXMKICAgICAgICBmb3JlYWNoIChhcnJheSgnd2FybmluZycsICdpbmZvJykgYXMgJHR5cGUpIHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRkYXRhWyR0eXBlXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWyR0eXBlIC4gJy12ZXJzaW9ucyddKSkgewogICAgICAgICAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkZGF0YVskdHlwZSAuICctdmVyc2lvbnMnXSk7CiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkdmVyc2lvblBhcnNlci0+bm9ybWFsaXplKENvbXBvc2VyOjpnZXRWZXJzaW9uKCkpKTsKICAgICAgICAgICAgICAgIGlmICghJGNvbnN0cmFpbnQtPm1hdGNoZXMoJGNvbXBvc2VyKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzwnLiR0eXBlLic+Jy51Y2ZpcnN0KCR0eXBlKS4nIGZyb20gJy5Vcmw6OnNhbml0aXplKCR1cmwpLic6ICcuJGRhdGFbJHR5cGVdLic8LycuJHR5cGUuJz4nKTsKICAgICAgICB9CgogICAgICAgIC8vIG1vZGVybiBDb21wb3NlciAyLjIrIGZvcm1hdCB3aXRoIHN1cHBvcnQgZm9yIG11bHRpcGxlIHdhcm5pbmcvaW5mbyBtZXNzYWdlcwogICAgICAgIGZvcmVhY2ggKGFycmF5KCd3YXJuaW5ncycsICdpbmZvcycpIGFzICRrZXkpIHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRkYXRhWyRrZXldKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRhdGFbJGtleV0gYXMgJHNwZWMpIHsKICAgICAgICAgICAgICAgICR0eXBlID0gc3Vic3RyKCRrZXksIDAsIC0xKTsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJHNwZWNbJ3ZlcnNpb25zJ10pOwogICAgICAgICAgICAgICAgJGNvbXBvc2VyID0gbmV3IENvbnN0cmFpbnQoJz09JywgJHZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZShDb21wb3Nlcjo6Z2V0VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICBpZiAoISRjb25zdHJhaW50LT5tYXRjaGVzKCRjb21wb3NlcikpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzwnLiR0eXBlLic+Jy51Y2ZpcnN0KCR0eXBlKS4nIGZyb20gJy5Vcmw6OnNhbml0aXplKCR1cmwpLic6ICcuJHNwZWNbJ21lc3NhZ2UnXS4nPC8nLiR0eXBlLic+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEV4Y2VwdGlvbkhpbnRzKFxFeGNlcHRpb24gJGUpCiAgICB7CiAgICAgICAgaWYgKCEkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICgKICAgICAgICAgICAgZmFsc2UgIT09IHN0cnBvcygkZS0+Z2V0TWVzc2FnZSgpLCAnUmVzb2x2aW5nIHRpbWVkIG91dCcpCiAgICAgICAgICAgIHx8IGZhbHNlICE9PSBzdHJwb3MoJGUtPmdldE1lc3NhZ2UoKSwgJ0NvdWxkIG5vdCByZXNvbHZlIGhvc3QnKQogICAgICAgICkgewogICAgICAgICAgICBTaWxlbmNlcjo6c3VwcHJlc3MoKTsKICAgICAgICAgICAgJHRlc3RDb25uZWN0aXZpdHkgPSBmaWxlX2dldF9jb250ZW50cygnaHR0cHM6Ly84LjguOC44JywgZmFsc2UsIHN0cmVhbV9jb250ZXh0X2NyZWF0ZShhcnJheSgKICAgICAgICAgICAgICAgICdzc2wnID0+IGFycmF5KCd2ZXJpZnlfcGVlcicgPT4gZmFsc2UpLAogICAgICAgICAgICAgICAgJ2h0dHAnID0+IGFycmF5KCdmb2xsb3dfbG9jYXRpb24nID0+IGZhbHNlLCAnaWdub3JlX2Vycm9ycycgPT4gdHJ1ZSksCiAgICAgICAgICAgICkpKTsKICAgICAgICAgICAgU2lsZW5jZXI6OnJlc3RvcmUoKTsKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkdGVzdENvbm5lY3Rpdml0eSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+VGhlIGZvbGxvd2luZyBleGNlcHRpb24gcHJvYmFibHkgaW5kaWNhdGVzIHlvdSBoYXZlIG1pc2NvbmZpZ3VyZWQgRE5TIHJlc29sdmVyKHMpPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgJzxlcnJvcj5UaGUgZm9sbG93aW5nIGV4Y2VwdGlvbiBwcm9iYWJseSBpbmRpY2F0ZXMgeW91IGFyZSBvZmZsaW5lIG9yIGhhdmUgbWlzY29uZmlndXJlZCBETlMgcmVzb2x2ZXIocyk8L2Vycm9yPicsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSm9iICAkam9iCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYW5Vc2VDdXJsKGFycmF5ICRqb2IpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+Y3VybCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJ3teaHR0cHM/Oi8vfWknLCAkam9iWydyZXF1ZXN0J11bJ3VybCddKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddWydzc2wnXVsnYWxsb3dfc2VsZl9zaWduZWQnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzQ3VybEVuYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiBcZXh0ZW5zaW9uX2xvYWRlZCgnY3VybCcpICYmIFxmdW5jdGlvbl9leGlzdHMoJ2N1cmxfbXVsdGlfZXhlYycpICYmIFxmdW5jdGlvbl9leGlzdHMoJ2N1cmxfbXVsdGlfaW5pdCcpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7CgpAdHJpZ2dlcl9lcnJvcignQ29tcG9zZXJcVXRpbFxNZXRhZGF0YU1pbmlmaWVyIGlzIGRlcHJlY2F0ZWQsIHVzZSBDb21wb3NlclxNZXRhZGF0YU1pbmlmaWVyXE1ldGFkYXRhTWluaWZpZXIgZnJvbSBjb21wb3Nlci9tZXRhZGF0YS1taW5pZmllciBpbnN0ZWFkLicsIEVfVVNFUl9ERVBSRUNBVEVEKTsKCi8qKgogKiBAZGVwcmVjYXRlZCBVc2UgQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllclxNZXRhZGF0YU1pbmlmaWVyIGluc3RlYWQKICovCmNsYXNzIE1ldGFkYXRhTWluaWZpZXIgZXh0ZW5kcyBcQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllclxNZXRhZGF0YU1pbmlmaWVyCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsXEh0dHA7Cgp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CgovKioKICogQHBocHN0YW4taW1wb3J0LXR5cGUgUmVxdWVzdCBmcm9tIEh0dHBEb3dubG9hZGVyCiAqLwpjbGFzcyBSZXNwb25zZQp7CiAgICAvKiogQHZhciBSZXF1ZXN0ICovCiAgICBwcml2YXRlICRyZXF1ZXN0OwogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICRjb2RlOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByaXZhdGUgJGhlYWRlcnM7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcml2YXRlICRib2R5OwoKICAgIC8qKgogICAgICogQHBhcmFtIFJlcXVlc3QgICRyZXF1ZXN0CiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGNvZGUKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkaGVhZGVycwogICAgICogQHBhcmFtID9zdHJpbmcgICRib2R5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcmVxdWVzdCwgJGNvZGUsIGFycmF5ICRoZWFkZXJzLCAkYm9keSkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCRyZXF1ZXN0Wyd1cmwnXSkpIHsgLy8gQHBocHN0YW4taWdub3JlLWxpbmUKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbigndXJsIGtleSBtaXNzaW5nIGZyb20gcmVxdWVzdCBhcnJheScpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+cmVxdWVzdCA9ICRyZXF1ZXN0OwogICAgICAgICR0aGlzLT5jb2RlID0gKGludCkgJGNvZGU7CiAgICAgICAgJHRoaXMtPmhlYWRlcnMgPSAkaGVhZGVyczsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c0NvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c01lc3NhZ2UoKQogICAgewogICAgICAgICR2YWx1ZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15IVFRQL1xTKyBcZCt9aScsICRoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICAvLyBJbiBjYXNlIG9mIHJlZGlyZWN0cywgaGVhZGVycyBjb250YWluIHRoZSBoZWFkZXJzIG9mIGFsbCByZXNwb25zZXMKICAgICAgICAgICAgICAgIC8vIHNvIHdlIGNhbiBub3QgcmV0dXJuIGRpcmVjdGx5IGFuZCBuZWVkIHRvIGtlZXAgaXRlcmF0aW5nCiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkaGVhZGVyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVhZGVycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oZWFkZXJzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICRuYW1lCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlYWRlcigkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6ZmluZEhlYWRlclZhbHVlKCR0aGlzLT5oZWFkZXJzLCAkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlY29kZUpzb24oKQogICAgewogICAgICAgIHJldHVybiBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5ib2R5LCAkdGhpcy0+cmVxdWVzdFsndXJsJ10pOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKiBAcGhwc3Rhbi1pbXB1cmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbGxlY3QoKQogICAgewogICAgICAgIC8qKiBAcGhwc3Rhbi1pZ25vcmUtbmV4dC1saW5lICovCiAgICAgICAgJHRoaXMtPnJlcXVlc3QgPSAkdGhpcy0+Y29kZSA9ICR0aGlzLT5oZWFkZXJzID0gJHRoaXMtPmJvZHkgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmdbXSAgICAkaGVhZGVycyBhcnJheSBvZiByZXR1cm5lZCBoZWFkZXJzIGxpa2UgZnJvbSBnZXRMYXN0SGVhZGVycygpCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRuYW1lICAgIGhlYWRlciBuYW1lIChjYXNlIGluc2Vuc2l0aXZlKQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZpbmRIZWFkZXJWYWx1ZShhcnJheSAkaGVhZGVycywgJG5hbWUpCiAgICB7CiAgICAgICAgJHZhbHVlID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XicucHJlZ19xdW90ZSgkbmFtZSkuJzpccyooLis/KVxzKiR9aScsICRoZWFkZXIsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsXEh0dHA7CgovKioKICogUHJveHkgZGlzY292ZXJ5IGFuZCBoZWxwZXIgY2xhc3MKICoKICogQGludGVybmFsCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqLwpjbGFzcyBQcm94eUhlbHBlcgp7CiAgICAvKioKICAgICAqIFJldHVybnMgcHJveHkgZW52aXJvbm1lbnQgdmFsdWVzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXtzdHJpbmd8bnVsbCwgc3RyaW5nfG51bGwsIHN0cmluZ3xudWxsfSBodHRwUHJveHksIGh0dHBzUHJveHksIG5vUHJveHkgdmFsdWVzCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBvbiBtYWxmb3JtZWQgdXJsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UHJveHlEYXRhKCkKICAgIHsKICAgICAgICAkaHR0cFByb3h5ID0gbnVsbDsKICAgICAgICAkaHR0cHNQcm94eSA9IG51bGw7CgogICAgICAgIC8vIEhhbmRsZSBodHRwX3Byb3h5L0hUVFBfUFJPWFkgb24gQ0xJIG9ubHkgZm9yIHNlY3VyaXR5IHJlYXNvbnMKICAgICAgICBpZiAoUEhQX1NBUEkgPT09ICdjbGknIHx8IFBIUF9TQVBJID09PSAncGhwZGJnJykgewogICAgICAgICAgICBpZiAoJGVudiA9IHNlbGY6OmdldFByb3h5RW52KGFycmF5KCdodHRwX3Byb3h5JywgJ0hUVFBfUFJPWFknKSwgJG5hbWUpKSB7CiAgICAgICAgICAgICAgICAkaHR0cFByb3h5ID0gc2VsZjo6Y2hlY2tQcm94eSgkZW52LCAkbmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFByZWZlciBDR0lfSFRUUF9QUk9YWSBpZiBhdmFpbGFibGUKICAgICAgICBpZiAoJGVudiA9IHNlbGY6OmdldFByb3h5RW52KGFycmF5KCdDR0lfSFRUUF9QUk9YWScpLCAkbmFtZSkpIHsKICAgICAgICAgICAgJGh0dHBQcm94eSA9IHNlbGY6OmNoZWNrUHJveHkoJGVudiwgJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLy8gSGFuZGxlIGh0dHBzX3Byb3h5L0hUVFBTX1BST1hZCiAgICAgICAgaWYgKCRlbnYgPSBzZWxmOjpnZXRQcm94eUVudihhcnJheSgnaHR0cHNfcHJveHknLCAnSFRUUFNfUFJPWFknKSwgJG5hbWUpKSB7CiAgICAgICAgICAgICRodHRwc1Byb3h5ID0gc2VsZjo6Y2hlY2tQcm94eSgkZW52LCAkbmFtZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGh0dHBzUHJveHkgPSAkaHR0cFByb3h5OwogICAgICAgIH0KCiAgICAgICAgLy8gSGFuZGxlIG5vX3Byb3h5CiAgICAgICAgJG5vUHJveHkgPSBzZWxmOjpnZXRQcm94eUVudihhcnJheSgnbm9fcHJveHknLCAnTk9fUFJPWFknKSwgJG5hbWUpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJGh0dHBQcm94eSwgJGh0dHBzUHJveHksICRub1Byb3h5KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgaHR0cCBjb250ZXh0IG9wdGlvbnMgZm9yIHRoZSBwcm94eSB1cmwKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcm94eVVybAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7aHR0cDogYXJyYXl7cHJveHk6IHN0cmluZywgaGVhZGVyPzogc3RyaW5nfX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRDb250ZXh0T3B0aW9ucygkcHJveHlVcmwpCiAgICB7CiAgICAgICAgJHByb3h5ID0gcGFyc2VfdXJsKCRwcm94eVVybCk7CgogICAgICAgIC8vIFJlbW92ZSBhbnkgYXV0aG9yaXphdGlvbgogICAgICAgICRwcm94eVVybCA9IHNlbGY6OmZvcm1hdFBhcnNlZFVybCgkcHJveHksIGZhbHNlKTsKICAgICAgICAkcHJveHlVcmwgPSBzdHJfcmVwbGFjZShhcnJheSgnaHR0cDovLycsICdodHRwczovLycpLCBhcnJheSgndGNwOi8vJywgJ3NzbDovLycpLCAkcHJveHlVcmwpOwoKICAgICAgICAkb3B0aW9uc1snaHR0cCddWydwcm94eSddID0gJHByb3h5VXJsOwoKICAgICAgICAvLyBIYW5kbGUgYW55IGF1dGhvcml6YXRpb24KICAgICAgICBpZiAoaXNzZXQoJHByb3h5Wyd1c2VyJ10pKSB7CiAgICAgICAgICAgICRhdXRoID0gcmF3dXJsZGVjb2RlKCRwcm94eVsndXNlciddKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkcHJveHlbJ3Bhc3MnXSkpIHsKICAgICAgICAgICAgICAgICRhdXRoIC49ICc6JyAuIHJhd3VybGRlY29kZSgkcHJveHlbJ3Bhc3MnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGF1dGggPSBiYXNlNjRfZW5jb2RlKCRhdXRoKTsKICAgICAgICAgICAgLy8gU2V0IGhlYWRlciBhcyBhIHN0cmluZwogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9ICJQcm94eS1BdXRob3JpemF0aW9uOiBCYXNpYyB7JGF1dGh9IjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMvdW5zZXRzIHJlcXVlc3RfZnVsbHVyaSB2YWx1ZSBpbiBodHRwIGNvbnRleHQgb3B0aW9ucyBhcnJheQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRyZXF1ZXN0VXJsCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucyBTZXQgYnkgbWV0aG9kCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0UmVxdWVzdEZ1bGxVcmkoJHJlcXVlc3RVcmwsIGFycmF5ICYkb3B0aW9ucykKICAgIHsKICAgICAgICBpZiAoJ2h0dHAnID09PSBwYXJzZV91cmwoJHJlcXVlc3RVcmwsIFBIUF9VUkxfU0NIRU1FKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydyZXF1ZXN0X2Z1bGx1cmknXSA9IHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdW5zZXQoJG9wdGlvbnNbJ2h0dHAnXVsncmVxdWVzdF9mdWxsdXJpJ10pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNlYXJjaGVzICRfU0VSVkVSIGZvciBjYXNlLXNlbnNpdGl2ZSB2YWx1ZXMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgJG5hbWVzIE5hbWVzIHRvIHNlYXJjaCBmb3IKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkbmFtZSAgTmFtZSBvZiBhbnkgZm91bmQgdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSBmb3VuZCB2YWx1ZQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRQcm94eUVudihhcnJheSAkbmFtZXMsICYkbmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkbmFtZXMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkX1NFUlZFUlskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJF9TRVJWRVJbJG5hbWVdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhbmQgZm9ybWF0cyBhIHByb3h5IHVybCBmcm9tIHRoZSBlbnZpcm9ubWVudAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHByb3h5VXJsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRlbnZOYW1lCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIG9uIG1hbGZvcm1lZCB1cmwKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICAgVGhlIGZvcm1hdHRlZCBwcm94eSB1cmwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY2hlY2tQcm94eSgkcHJveHlVcmwsICRlbnZOYW1lKQogICAgewogICAgICAgICRlcnJvciA9IHNwcmludGYoJ21hbGZvcm1lZCAlcyB1cmwnLCAkZW52TmFtZSk7CiAgICAgICAgJHByb3h5ID0gcGFyc2VfdXJsKCRwcm94eVVybCk7CgogICAgICAgIC8vIFdlIG5lZWQgcGFyc2VfdXJsIHRvIGhhdmUgaWRlbnRpZmllZCBhIGhvc3QKICAgICAgICBpZiAoIWlzc2V0KCRwcm94eVsnaG9zdCddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGVycm9yKTsKICAgICAgICB9CgogICAgICAgICRwcm94eVVybCA9IHNlbGY6OmZvcm1hdFBhcnNlZFVybCgkcHJveHksIHRydWUpOwoKICAgICAgICAvLyBXZSBuZWVkIGEgcG9ydCBiZWNhdXNlIHN0cmVhbXMgYW5kIGN1cmwgdXNlIGRpZmZlcmVudCBkZWZhdWx0cwogICAgICAgIGlmICghcGFyc2VfdXJsKCRwcm94eVVybCwgUEhQX1VSTF9QT1JUKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGVycm9yKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJveHlVcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgdXJsIGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cwogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXl7c2NoZW1lPzogc3RyaW5nLCBob3N0OiBzdHJpbmcsIHBvcnQ/OiBpbnQsIHVzZXI/OiBzdHJpbmcsIHBhc3M/OiBzdHJpbmd9ICRwcm94eQogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGluY2x1ZGVBdXRoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGZvcm1hdHRlZCB2YWx1ZQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXRQYXJzZWRVcmwoYXJyYXkgJHByb3h5LCAkaW5jbHVkZUF1dGgpCiAgICB7CiAgICAgICAgJHByb3h5VXJsID0gaXNzZXQoJHByb3h5WydzY2hlbWUnXSkgPyBzdHJ0b2xvd2VyKCRwcm94eVsnc2NoZW1lJ10pIC4gJzovLycgOiAnJzsKCiAgICAgICAgaWYgKCRpbmNsdWRlQXV0aCAmJiBpc3NldCgkcHJveHlbJ3VzZXInXSkpIHsKICAgICAgICAgICAgJHByb3h5VXJsIC49ICRwcm94eVsndXNlciddOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRwcm94eVsncGFzcyddKSkgewogICAgICAgICAgICAgICAgJHByb3h5VXJsIC49ICc6JyAuICRwcm94eVsncGFzcyddOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwcm94eVVybCAuPSAnQCc7CiAgICAgICAgfQoKICAgICAgICAkcHJveHlVcmwgLj0gJHByb3h5Wydob3N0J107CgogICAgICAgIGlmIChpc3NldCgkcHJveHlbJ3BvcnQnXSkpIHsKICAgICAgICAgICAgJHByb3h5VXJsIC49ICc6JyAuICRwcm94eVsncG9ydCddOwogICAgICAgIH0gZWxzZWlmIChzdHJwb3MoJHByb3h5VXJsLCAnaHR0cDovLycpID09PSAwKSB7CiAgICAgICAgICAgICRwcm94eVVybCAuPSAnOjgwJzsKICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCRwcm94eVVybCwgJ2h0dHBzOi8vJykgPT09IDApIHsKICAgICAgICAgICAgJHByb3h5VXJsIC49ICc6NDQzJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJveHlVcmw7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbFxIdHRwOwoKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcVXRpbFxOb1Byb3h5UGF0dGVybjsKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwoKLyoqCiAqIEBpbnRlcm5hbAogKiBAYXV0aG9yIEpvaG4gU3RldmVuc29uIDxqb2huLXN0ZXZlbnNvbkBibHVleW9uZGVyLmNvLnVrPgogKi8KY2xhc3MgUHJveHlNYW5hZ2VyCnsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJGVycm9yID0gbnVsbDsKICAgIC8qKiBAdmFyIGFycmF5e2h0dHA6ID9zdHJpbmcsIGh0dHBzOiA/c3RyaW5nfSAqLwogICAgcHJpdmF0ZSAkZnVsbFByb3h5OwogICAgLyoqIEB2YXIgYXJyYXl7aHR0cDogP3N0cmluZywgaHR0cHM6ID9zdHJpbmd9ICovCiAgICBwcml2YXRlICRzYWZlUHJveHk7CiAgICAvKiogQHZhciBhcnJheXtodHRwOiBhcnJheXtvcHRpb25zOiBtaXhlZFtdfG51bGx9LCBodHRwczogYXJyYXl7b3B0aW9uczogbWl4ZWRbXXxudWxsfX0gKi8KICAgIHByaXZhdGUgJHN0cmVhbXM7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRoYXNQcm94eTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJGluZm8gPSBudWxsOwogICAgLyoqIEB2YXIgP05vUHJveHlQYXR0ZXJuICovCiAgICBwcml2YXRlICRub1Byb3h5SGFuZGxlciA9IG51bGw7CgogICAgLyoqIEB2YXIgP1Byb3h5TWFuYWdlciAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGluc3RhbmNlID0gbnVsbDsKCiAgICBwcml2YXRlIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+ZnVsbFByb3h5ID0gJHRoaXMtPnNhZmVQcm94eSA9IGFycmF5KAogICAgICAgICAgICAnaHR0cCcgPT4gbnVsbCwKICAgICAgICAgICAgJ2h0dHBzJyA9PiBudWxsLAogICAgICAgICk7CgogICAgICAgICR0aGlzLT5zdHJlYW1zWydodHRwJ10gPSAkdGhpcy0+c3RyZWFtc1snaHR0cHMnXSA9IGFycmF5KAogICAgICAgICAgICAnb3B0aW9ucycgPT4gbnVsbCwKICAgICAgICApOwoKICAgICAgICAkdGhpcy0+aGFzUHJveHkgPSBmYWxzZTsKICAgICAgICAkdGhpcy0+aW5pdFByb3h5RGF0YSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQcm94eU1hbmFnZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRJbnN0YW5jZSgpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokaW5zdGFuY2UpIHsKICAgICAgICAgICAgc2VsZjo6JGluc3RhbmNlID0gbmV3IHNlbGYoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokaW5zdGFuY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhcnMgdGhlIHBlcnNpc3RlbnQgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXNldCgpCiAgICB7CiAgICAgICAgc2VsZjo6JGluc3RhbmNlID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBSZXF1ZXN0UHJveHkgaW5zdGFuY2UgZm9yIHRoZSByZXF1ZXN0IHVybAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRyZXF1ZXN0VXJsCiAgICAgKiBAcmV0dXJuIFJlcXVlc3RQcm94eQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJveHlGb3JSZXF1ZXN0KCRyZXF1ZXN0VXJsKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZXJyb3IpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVW5hYmxlIHRvIHVzZSBhIHByb3h5OiAnLiR0aGlzLT5lcnJvcik7CiAgICAgICAgfQoKICAgICAgICAkc2NoZW1lID0gcGFyc2VfdXJsKCRyZXF1ZXN0VXJsLCBQSFBfVVJMX1NDSEVNRSkgPzogJ2h0dHAnOwogICAgICAgICRwcm94eVVybCA9ICcnOwogICAgICAgICRvcHRpb25zID0gYXJyYXkoKTsKICAgICAgICAkZm9ybWF0dGVkUHJveHlVcmwgPSAnJzsKCiAgICAgICAgaWYgKCR0aGlzLT5oYXNQcm94eSAmJiBpbl9hcnJheSgkc2NoZW1lLCBhcnJheSgnaHR0cCcsICdodHRwcycpLCB0cnVlKSAmJiAkdGhpcy0+ZnVsbFByb3h5WyRzY2hlbWVdKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bm9Qcm94eSgkcmVxdWVzdFVybCkpIHsKICAgICAgICAgICAgICAgICRmb3JtYXR0ZWRQcm94eVVybCA9ICdleGNsdWRlZCBieSBub19wcm94eSc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcHJveHlVcmwgPSAkdGhpcy0+ZnVsbFByb3h5WyRzY2hlbWVdOwogICAgICAgICAgICAgICAgJG9wdGlvbnMgPSAkdGhpcy0+c3RyZWFtc1skc2NoZW1lXVsnb3B0aW9ucyddOwogICAgICAgICAgICAgICAgUHJveHlIZWxwZXI6OnNldFJlcXVlc3RGdWxsVXJpKCRyZXF1ZXN0VXJsLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAkZm9ybWF0dGVkUHJveHlVcmwgPSAkdGhpcy0+c2FmZVByb3h5WyRzY2hlbWVdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFJlcXVlc3RQcm94eSgkcHJveHlVcmwsICRvcHRpb25zLCAkZm9ybWF0dGVkUHJveHlVcmwpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGEgcHJveHkgaXMgYmVpbmcgdXNlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBJZiBmYWxzZSBhbnkgZXJyb3Igd2lsbCBiZSBpbiAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNQcm94eWluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNQcm94eTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgcHJveHkgY29uZmlndXJhdGlvbiBpbmZvIHdoaWNoIGNhbiBiZSBzaG93biB0byB0aGUgdXNlcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgU2FmZSBwcm94eSBVUkwgb3IgYW4gZXJyb3IgbWVzc2FnZSBpZiBzZXR0aW5nIHVwIHByb3h5IGZhaWxlZCBvciBudWxsIGlmIG5vIHByb3h5IHdhcyBjb25maWd1cmVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXR0ZWRQcm94eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNQcm94eSA/ICR0aGlzLT5pbmZvIDogJHRoaXMtPmVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcHJveHkgdmFsdWVzIGZyb20gdGhlIGVudmlyb25tZW50CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaW5pdFByb3h5RGF0YSgpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbGlzdCgkaHR0cFByb3h5LCAkaHR0cHNQcm94eSwgJG5vUHJveHkpID0gUHJveHlIZWxwZXI6OmdldFByb3h5RGF0YSgpOwogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICR0aGlzLT5lcnJvciA9ICRlLT5nZXRNZXNzYWdlKCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkaW5mbyA9IGFycmF5KCk7CgogICAgICAgIGlmICgkaHR0cFByb3h5KSB7CiAgICAgICAgICAgICRpbmZvW10gPSAkdGhpcy0+c2V0RGF0YSgkaHR0cFByb3h5LCAnaHR0cCcpOwogICAgICAgIH0KICAgICAgICBpZiAoJGh0dHBzUHJveHkpIHsKICAgICAgICAgICAgJGluZm9bXSA9ICR0aGlzLT5zZXREYXRhKCRodHRwc1Byb3h5LCAnaHR0cHMnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5oYXNQcm94eSkgewogICAgICAgICAgICAkdGhpcy0+aW5mbyA9IGltcGxvZGUoJywgJywgJGluZm8pOwogICAgICAgICAgICBpZiAoJG5vUHJveHkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5ub1Byb3h5SGFuZGxlciA9IG5ldyBOb1Byb3h5UGF0dGVybigkbm9Qcm94eSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGluaXRpYWwgZGF0YQogICAgICoKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICR1cmwgICAgUHJveHkgdXJsCiAgICAgKiBAcGFyYW0gJ2h0dHAnfCdodHRwcycgICAkc2NoZW1lIEVudmlyb25tZW50IHZhcmlhYmxlIHNjaGVtZQogICAgICoKICAgICAqIEByZXR1cm4gbm9uLWVtcHR5LXN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldERhdGEoJHVybCwgJHNjaGVtZSkKICAgIHsKICAgICAgICAkc2FmZVByb3h5ID0gVXJsOjpzYW5pdGl6ZSgkdXJsKTsKICAgICAgICAkdGhpcy0+ZnVsbFByb3h5WyRzY2hlbWVdID0gJHVybDsKICAgICAgICAkdGhpcy0+c2FmZVByb3h5WyRzY2hlbWVdID0gJHNhZmVQcm94eTsKICAgICAgICAkdGhpcy0+c3RyZWFtc1skc2NoZW1lXVsnb3B0aW9ucyddID0gUHJveHlIZWxwZXI6OmdldENvbnRleHRPcHRpb25zKCR1cmwpOwogICAgICAgICR0aGlzLT5oYXNQcm94eSA9IHRydWU7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCclcz0lcycsICRzY2hlbWUsICRzYWZlUHJveHkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGEgdXJsIG1hdGNoZXMgbm9fcHJveHkgdmFsdWUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcmVxdWVzdFVybAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbm9Qcm94eSgkcmVxdWVzdFVybCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5vUHJveHlIYW5kbGVyICYmICR0aGlzLT5ub1Byb3h5SGFuZGxlci0+dGVzdCgkcmVxdWVzdFVybCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbFxIdHRwOwoKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwoKLyoqCiAqIEBpbnRlcm5hbAogKiBAYXV0aG9yIEpvaG4gU3RldmVuc29uIDxqb2huLXN0ZXZlbnNvbkBibHVleW9uZGVyLmNvLnVrPgogKi8KY2xhc3MgUmVxdWVzdFByb3h5CnsKICAgIC8qKiBAdmFyIG1peGVkW10gKi8KICAgIHByaXZhdGUgJGNvbnRleHRPcHRpb25zOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkaXNTZWN1cmU7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGZvcm1hdHRlZFVybDsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkdXJsOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgJHVybAogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHRPcHRpb25zCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkZm9ybWF0dGVkVXJsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdXJsLCBhcnJheSAkY29udGV4dE9wdGlvbnMsICRmb3JtYXR0ZWRVcmwpCiAgICB7CiAgICAgICAgJHRoaXMtPnVybCA9ICR1cmw7CiAgICAgICAgJHRoaXMtPmNvbnRleHRPcHRpb25zID0gJGNvbnRleHRPcHRpb25zOwogICAgICAgICR0aGlzLT5mb3JtYXR0ZWRVcmwgPSAkZm9ybWF0dGVkVXJsOwogICAgICAgICR0aGlzLT5pc1NlY3VyZSA9IDAgPT09IHN0cnBvcygkdXJsLCAnaHR0cHM6Ly8nKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgY29udGV4dCBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb250ZXh0T3B0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb250ZXh0T3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNhZmUgcHJveHkgdXJsIGZyb20gdGhlIGxhc3QgcmVxdWVzdAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgJGZvcm1hdCBPdXRwdXQgZm9ybWF0IHNwZWNpZmllcgogICAgICogQHJldHVybiBzdHJpbmcgICAgICBTYWZlIHByb3h5LCBubyBwcm94eSBvciBlbXB0eQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkVXJsKCRmb3JtYXQgPSAnJykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJyc7CiAgICAgICAgaWYgKCR0aGlzLT5mb3JtYXR0ZWRVcmwpIHsKICAgICAgICAgICAgJGZvcm1hdCA9ICRmb3JtYXQgPzogJyVzJzsKICAgICAgICAgICAgJHJlc3VsdCA9IHNwcmludGYoJGZvcm1hdCwgJHRoaXMtPmZvcm1hdHRlZFVybCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3h5IHVybAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFByb3h5IHVybCBvciBlbXB0eQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVybDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgc2VjdXJlLXByb3h5CiAgICAgKgogICAgICogQHJldHVybiBib29sIEZhbHNlIGlmIG5vdCBzZWN1cmUgb3IgdGhlcmUgaXMgbm8gcHJveHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU2VjdXJlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzU2VjdXJlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWxcSHR0cDsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXE1heEZpbGVTaXplRXhjZWVkZWRFeGNlcHRpb247CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxTdHJlYW1Db250ZXh0RmFjdG9yeTsKdXNlIENvbXBvc2VyXFV0aWxcQXV0aEhlbHBlcjsKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZTsKCi8qKgogKiBAaW50ZXJuYWwKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pY29sYXMgR3Jla2FzIDxwQHRjaHdvcmsuY29tPgogKiBAcGhwc3Rhbi10eXBlIEF0dHJpYnV0ZXMgYXJyYXl7cmV0cnlBdXRoRmFpbHVyZTogYm9vbCwgcmVkaXJlY3RzOiBpbnQsIHJldHJpZXM6IGludCwgc3RvcmVBdXRoOiBib29sfQogKiBAcGhwc3Rhbi10eXBlIEpvYiBhcnJheXt1cmw6IHN0cmluZywgb3JpZ2luOiBzdHJpbmcsIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZXMsIG9wdGlvbnM6IG1peGVkW10sIHByb2dyZXNzOiBtaXhlZFtdLCBjdXJsSGFuZGxlOiByZXNvdXJjZSwgZmlsZW5hbWU6IHN0cmluZ3xmYWxzZSwgaGVhZGVySGFuZGxlOiByZXNvdXJjZSwgYm9keUhhbmRsZTogcmVzb3VyY2UsIHJlc29sdmU6IGNhbGxhYmxlLCByZWplY3Q6IGNhbGxhYmxlfQogKi8KY2xhc3MgQ3VybERvd25sb2FkZXIKewogICAgLyoqIEB2YXIgP3Jlc291cmNlICovCiAgICBwcml2YXRlICRtdWx0aUhhbmRsZTsKICAgIC8qKiBAdmFyID9yZXNvdXJjZSAqLwogICAgcHJpdmF0ZSAkc2hhcmVIYW5kbGU7CiAgICAvKiogQHZhciBKb2JbXSAqLwogICAgcHJpdmF0ZSAkam9icyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKICAgIC8qKiBAdmFyIEF1dGhIZWxwZXIgKi8KICAgIHByaXZhdGUgJGF1dGhIZWxwZXI7CiAgICAvKiogQHZhciBmbG9hdCAqLwogICAgcHJpdmF0ZSAkc2VsZWN0VGltZW91dCA9IDUuMDsKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkbWF4UmVkaXJlY3RzID0gMjA7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByaXZhdGUgJG1heFJldHJpZXMgPSAzOwogICAgLyoqIEB2YXIgUHJveHlNYW5hZ2VyICovCiAgICBwcml2YXRlICRwcm94eU1hbmFnZXI7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRzdXBwb3J0c1NlY3VyZVByb3h5OwogICAgLyoqIEB2YXIgYXJyYXk8aW50LCBzdHJpbmdbXT4gKi8KICAgIHByb3RlY3RlZCAkbXVsdGlFcnJvcnMgPSBhcnJheSgKICAgICAgICBDVVJMTV9CQURfSEFORExFID0+IGFycmF5KCdDVVJMTV9CQURfSEFORExFJywgJ1RoZSBwYXNzZWQtaW4gaGFuZGxlIGlzIG5vdCBhIHZhbGlkIENVUkxNIGhhbmRsZS4nKSwKICAgICAgICBDVVJMTV9CQURfRUFTWV9IQU5ETEUgPT4gYXJyYXkoJ0NVUkxNX0JBRF9FQVNZX0hBTkRMRScsICJBbiBlYXN5IGhhbmRsZSB3YXMgbm90IGdvb2QvdmFsaWQuIEl0IGNvdWxkIG1lYW4gdGhhdCBpdCBpc24ndCBhbiBlYXN5IGhhbmRsZSBhdCBhbGwsIG9yIHBvc3NpYmx5IHRoYXQgdGhlIGhhbmRsZSBhbHJlYWR5IGlzIGluIHVzZWQgYnkgdGhpcyBvciBhbm90aGVyIG11bHRpIGhhbmRsZS4iKSwKICAgICAgICBDVVJMTV9PVVRfT0ZfTUVNT1JZID0+IGFycmF5KCdDVVJMTV9PVVRfT0ZfTUVNT1JZJywgJ1lvdSBhcmUgZG9vbWVkLicpLAogICAgICAgIENVUkxNX0lOVEVSTkFMX0VSUk9SID0+IGFycmF5KCdDVVJMTV9JTlRFUk5BTF9FUlJPUicsICdUaGlzIGNhbiBvbmx5IGJlIHJldHVybmVkIGlmIGxpYmN1cmwgYnVncy4gUGxlYXNlIHJlcG9ydCBpdCB0byB1cyEnKSwKICAgICk7CgogICAgLyoqIEB2YXIgbWl4ZWRbXSAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJG9wdGlvbnMgPSBhcnJheSgKICAgICAgICAnaHR0cCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdtZXRob2QnID0+IENVUkxPUFRfQ1VTVE9NUkVRVUVTVCwKICAgICAgICAgICAgJ2NvbnRlbnQnID0+IENVUkxPUFRfUE9TVEZJRUxEUywKICAgICAgICAgICAgJ2hlYWRlcicgPT4gQ1VSTE9QVF9IVFRQSEVBREVSLAogICAgICAgICAgICAndGltZW91dCcgPT4gQ1VSTE9QVF9USU1FT1VULAogICAgICAgICksCiAgICAgICAgJ3NzbCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdjYWZpbGUnID0+IENVUkxPUFRfQ0FJTkZPLAogICAgICAgICAgICAnY2FwYXRoJyA9PiBDVVJMT1BUX0NBUEFUSCwKICAgICAgICAgICAgJ3ZlcmlmeV9wZWVyJyA9PiBDVVJMT1BUX1NTTF9WRVJJRllQRUVSLAogICAgICAgICAgICAndmVyaWZ5X3BlZXJfbmFtZScgPT4gQ1VSTE9QVF9TU0xfVkVSSUZZSE9TVCwKICAgICAgICAgICAgJ2xvY2FsX2NlcnQnID0+IENVUkxPUFRfU1NMQ0VSVCwKICAgICAgICAgICAgJ2xvY2FsX3BrJyA9PiBDVVJMT1BUX1NTTEtFWSwKICAgICAgICAgICAgJ3Bhc3NwaHJhc2UnID0+IENVUkxPUFRfU1NMS0VZUEFTU1dELAogICAgICAgICksCiAgICApOwoKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgdHJ1ZT4gKi8KICAgIHByaXZhdGUgc3RhdGljICR0aW1lSW5mbyA9IGFycmF5KAogICAgICAgICd0b3RhbF90aW1lJyA9PiB0cnVlLAogICAgICAgICduYW1lbG9va3VwX3RpbWUnID0+IHRydWUsCiAgICAgICAgJ2Nvbm5lY3RfdGltZScgPT4gdHJ1ZSwKICAgICAgICAncHJldHJhbnNmZXJfdGltZScgPT4gdHJ1ZSwKICAgICAgICAnc3RhcnR0cmFuc2Zlcl90aW1lJyA9PiB0cnVlLAogICAgICAgICdyZWRpcmVjdF90aW1lJyA9PiB0cnVlLAogICAgKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBtaXhlZFtdICRvcHRpb25zCiAgICAgKiBAcGFyYW0gYm9vbCAgICAkZGlzYWJsZVRscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpLCAkZGlzYWJsZVRscyA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKCiAgICAgICAgJHRoaXMtPm11bHRpSGFuZGxlID0gJG1oID0gY3VybF9tdWx0aV9pbml0KCk7CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnY3VybF9tdWx0aV9zZXRvcHQnKSkgewogICAgICAgICAgICBjdXJsX211bHRpX3NldG9wdCgkbWgsIENVUkxNT1BUX1BJUEVMSU5JTkcsIFBIUF9WRVJTSU9OX0lEID49IDcwNDAwID8gLyogQ1VSTFBJUEVfTVVMVElQTEVYICovIDIgOiAvKkNVUkxQSVBFX0hUVFAxIHwgQ1VSTFBJUEVfTVVMVElQTEVYKi8gMyk7CiAgICAgICAgICAgIGlmIChkZWZpbmVkKCdDVVJMTU9QVF9NQVhfSE9TVF9DT05ORUNUSU9OUycpICYmICFkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICAgICAgY3VybF9tdWx0aV9zZXRvcHQoJG1oLCBDVVJMTU9QVF9NQVhfSE9TVF9DT05ORUNUSU9OUywgOCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2N1cmxfc2hhcmVfaW5pdCcpKSB7CiAgICAgICAgICAgICR0aGlzLT5zaGFyZUhhbmRsZSA9ICRzaCA9IGN1cmxfc2hhcmVfaW5pdCgpOwogICAgICAgICAgICBjdXJsX3NoYXJlX3NldG9wdCgkc2gsIENVUkxTSE9QVF9TSEFSRSwgQ1VSTF9MT0NLX0RBVEFfQ09PS0lFKTsKICAgICAgICAgICAgY3VybF9zaGFyZV9zZXRvcHQoJHNoLCBDVVJMU0hPUFRfU0hBUkUsIENVUkxfTE9DS19EQVRBX0ROUyk7CiAgICAgICAgICAgIGN1cmxfc2hhcmVfc2V0b3B0KCRzaCwgQ1VSTFNIT1BUX1NIQVJFLCBDVVJMX0xPQ0tfREFUQV9TU0xfU0VTU0lPTik7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YXV0aEhlbHBlciA9IG5ldyBBdXRoSGVscGVyKCRpbywgJGNvbmZpZyk7CiAgICAgICAgJHRoaXMtPnByb3h5TWFuYWdlciA9IFByb3h5TWFuYWdlcjo6Z2V0SW5zdGFuY2UoKTsKCiAgICAgICAgJHZlcnNpb24gPSBjdXJsX3ZlcnNpb24oKTsKICAgICAgICAkZmVhdHVyZXMgPSAkdmVyc2lvblsnZmVhdHVyZXMnXTsKICAgICAgICAkdGhpcy0+c3VwcG9ydHNTZWN1cmVQcm94eSA9IGRlZmluZWQoJ0NVUkxfVkVSU0lPTl9IVFRQU19QUk9YWScpICYmICgkZmVhdHVyZXMgJiBDVVJMX1ZFUlNJT05fSFRUUFNfUFJPWFkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRyZXNvbHZlCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJHJlamVjdAogICAgICogQHBhcmFtIHN0cmluZyAgICRvcmlnaW4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAkdXJsCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgJG9wdGlvbnMKICAgICAqIEBwYXJhbSA/c3RyaW5nICAkY29weVRvCiAgICAgKgogICAgICogQHJldHVybiBpbnQgaW50ZXJuYWwgam9iIGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZCgkcmVzb2x2ZSwgJHJlamVjdCwgJG9yaWdpbiwgJHVybCwgJG9wdGlvbnMsICRjb3B5VG8gPSBudWxsKQogICAgewogICAgICAgICRhdHRyaWJ1dGVzID0gYXJyYXkoKTsKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3JldHJ5LWF1dGgtZmFpbHVyZSddKSkgewogICAgICAgICAgICAkYXR0cmlidXRlc1sncmV0cnlBdXRoRmFpbHVyZSddID0gJG9wdGlvbnNbJ3JldHJ5LWF1dGgtZmFpbHVyZSddOwogICAgICAgICAgICB1bnNldCgkb3B0aW9uc1sncmV0cnktYXV0aC1mYWlsdXJlJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbml0RG93bmxvYWQoJHJlc29sdmUsICRyZWplY3QsICRvcmlnaW4sICR1cmwsICRvcHRpb25zLCAkY29weVRvLCAkYXR0cmlidXRlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJHJlc29sdmUKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkcmVqZWN0CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJG9yaWdpbgogICAgICogQHBhcmFtIHN0cmluZyAgICR1cmwKICAgICAqIEBwYXJhbSBtaXhlZFtdICAkb3B0aW9ucwogICAgICogQHBhcmFtID9zdHJpbmcgICRjb3B5VG8KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl7cmV0cnlBdXRoRmFpbHVyZT86IGJvb2wsIHJlZGlyZWN0cz86IGludCwgcmV0cmllcz86IGludCwgc3RvcmVBdXRoPzogYm9vbH0gJGF0dHJpYnV0ZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBpbnRlcm5hbCBqb2IgaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbml0RG93bmxvYWQoJHJlc29sdmUsICRyZWplY3QsICRvcmlnaW4sICR1cmwsICRvcHRpb25zLCAkY29weVRvID0gbnVsbCwgYXJyYXkgJGF0dHJpYnV0ZXMgPSBhcnJheSgpKQogICAgewogICAgICAgICRhdHRyaWJ1dGVzID0gYXJyYXlfbWVyZ2UoYXJyYXkoCiAgICAgICAgICAgICdyZXRyeUF1dGhGYWlsdXJlJyA9PiB0cnVlLAogICAgICAgICAgICAncmVkaXJlY3RzJyA9PiAwLAogICAgICAgICAgICAncmV0cmllcycgPT4gMCwKICAgICAgICAgICAgJ3N0b3JlQXV0aCcgPT4gZmFsc2UsCiAgICAgICAgKSwgJGF0dHJpYnV0ZXMpOwoKICAgICAgICAkb3JpZ2luYWxPcHRpb25zID0gJG9wdGlvbnM7CgogICAgICAgIC8vIGNoZWNrIFVSTCBjYW4gYmUgYWNjZXNzZWQgKGkuZS4gaXMgbm90IGluc2VjdXJlKSwgYnV0IGFsbG93IGluc2VjdXJlIFBhY2thZ2lzdCBjYWxscyB0byAkaGFzaGVkIHByb3ZpZGVycyBhcyBmaWxlIGludGVncml0eSBpcyB2ZXJpZmllZCB3aXRoIHNoYTI1NgogICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgne15odHRwOi8vKHJlcG9cLik/cGFja2FnaXN0XC5vcmcvcC99JywgJHVybCkgfHwgKGZhbHNlID09PSBzdHJwb3MoJHVybCwgJyQnKSAmJiBmYWxzZSA9PT0gc3RycG9zKCR1cmwsICclMjQnKSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdXJsLCAkdGhpcy0+aW8pOwogICAgICAgIH0KCiAgICAgICAgJGN1cmxIYW5kbGUgPSBjdXJsX2luaXQoKTsKICAgICAgICAkaGVhZGVySGFuZGxlID0gZm9wZW4oJ3BocDovL3RlbXAvbWF4bWVtb3J5OjMyNzY4JywgJ3crYicpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJGhlYWRlckhhbmRsZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBvcGVuIGEgdGVtcCBzdHJlYW0gdG8gc3RvcmUgY3VybCBoZWFkZXJzJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNvcHlUbykgewogICAgICAgICAgICAkZXJyb3JNZXNzYWdlID0gJyc7CiAgICAgICAgICAgIC8vIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUKICAgICAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoZnVuY3Rpb24gKCRjb2RlLCAkbXNnKSB1c2UgKCYkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGVycm9yTWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgICRlcnJvck1lc3NhZ2UgLj0gIlxuIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRlcnJvck1lc3NhZ2UgLj0gUHJlZzo6cmVwbGFjZSgne15mb3BlblwoLio/XCk6IH0nLCAnJywgJG1zZyk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkYm9keUhhbmRsZSA9IGZvcGVuKCRjb3B5VG8uJ34nLCAndytiJyk7CiAgICAgICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwogICAgICAgICAgICBpZiAoISRib2R5SGFuZGxlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgIicuJHVybC4nIiBmaWxlIGNvdWxkIG5vdCBiZSB3cml0dGVuIHRvICcuJGNvcHlUby4nOiAnLiRlcnJvck1lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGJvZHlIYW5kbGUgPSBAZm9wZW4oJ3BocDovL3RlbXAvbWF4bWVtb3J5OjUyNDI4OCcsICd3K2InKTsKICAgICAgICB9CgogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1VSTCwgJHVybCk7CiAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfRk9MTE9XTE9DQVRJT04sIGZhbHNlKTsKICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9DT05ORUNUVElNRU9VVCwgMTApOwogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1RJTUVPVVQsIG1heCgoaW50KSBpbmlfZ2V0KCJkZWZhdWx0X3NvY2tldF90aW1lb3V0IiksIDMwMCkpOwogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1dSSVRFSEVBREVSLCAkaGVhZGVySGFuZGxlKTsKICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9GSUxFLCAkYm9keUhhbmRsZSk7CiAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfRU5DT0RJTkcsICIiKTsgLy8gbGV0IGNVUkwgc2V0IHRoZSBBY2NlcHQtRW5jb2RpbmcgaGVhZGVyIHRvIHdoYXQgaXQgc3VwcG9ydHMKICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9QUk9UT0NPTFMsIENVUkxQUk9UT19IVFRQIHwgQ1VSTFBST1RPX0hUVFBTKTsKCiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnY3VybF9zaGFyZV9pbml0JykpIHsKICAgICAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfU0hBUkUsICR0aGlzLT5zaGFyZUhhbmRsZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IGFycmF5X2RpZmYoJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10sIGFycmF5KCdDb25uZWN0aW9uOiBjbG9zZScpKTsKICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gJ0Nvbm5lY3Rpb246IGtlZXAtYWxpdmUnOwoKICAgICAgICAkdmVyc2lvbiA9IGN1cmxfdmVyc2lvbigpOwogICAgICAgICRmZWF0dXJlcyA9ICR2ZXJzaW9uWydmZWF0dXJlcyddOwogICAgICAgIGlmICgwID09PSBzdHJwb3MoJHVybCwgJ2h0dHBzOi8vJykgJiYgXGRlZmluZWQoJ0NVUkxfVkVSU0lPTl9IVFRQMicpICYmIFxkZWZpbmVkKCdDVVJMX0hUVFBfVkVSU0lPTl8yXzAnKSAmJiAoQ1VSTF9WRVJTSU9OX0hUVFAyICYgJGZlYXR1cmVzKSkgewogICAgICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9IVFRQX1ZFUlNJT04sIENVUkxfSFRUUF9WRVJTSU9OXzJfMCk7CiAgICAgICAgfQoKICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9ICR0aGlzLT5hdXRoSGVscGVyLT5hZGRBdXRoZW50aWNhdGlvbkhlYWRlcigkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSwgJG9yaWdpbiwgJHVybCk7CiAgICAgICAgJG9wdGlvbnMgPSBTdHJlYW1Db250ZXh0RmFjdG9yeTo6aW5pdE9wdGlvbnMoJHVybCwgJG9wdGlvbnMsIHRydWUpOwoKICAgICAgICBmb3JlYWNoIChzZWxmOjokb3B0aW9ucyBhcyAkdHlwZSA9PiAkY3VybE9wdGlvbnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGN1cmxPcHRpb25zIGFzICRuYW1lID0+ICRjdXJsT3B0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJHR5cGVdWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdzc2wnICYmICRuYW1lID09PSAndmVyaWZ5X3BlZXJfbmFtZScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsICRjdXJsT3B0aW9uLCAkb3B0aW9uc1skdHlwZV1bJG5hbWVdID09PSB0cnVlID8gMiA6ICRvcHRpb25zWyR0eXBlXVskbmFtZV0pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCAkY3VybE9wdGlvbiwgJG9wdGlvbnNbJHR5cGVdWyRuYW1lXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBBbHdheXMgc2V0IENVUkxPUFRfUFJPWFkgdG8gZW5hYmxlL2Rpc2FibGUgcHJveHkgaGFuZGxpbmcKICAgICAgICAvLyBBbnkgcHJveHkgYXV0aG9yaXphdGlvbiBpcyBpbmNsdWRlZCBpbiB0aGUgcHJveHkgdXJsCiAgICAgICAgJHByb3h5ID0gJHRoaXMtPnByb3h5TWFuYWdlci0+Z2V0UHJveHlGb3JSZXF1ZXN0KCR1cmwpOwogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1BST1hZLCAkcHJveHktPmdldFVybCgpKTsKCiAgICAgICAgLy8gQ3VybCBuZWVkcyBjZXJ0aWZpY2F0ZSBsb2NhdGlvbnMgZm9yIHNlY3VyZSBwcm94aWVzLgogICAgICAgIC8vIENVUkxPUFRfUFJPWFlfU1NMX1ZFUklGWV9QRUVSL0hPU1QgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdAogICAgICAgIGlmICgkcHJveHktPmlzU2VjdXJlKCkpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+c3VwcG9ydHNTZWN1cmVQcm94eSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignQ29ubmVjdGluZyB0byBhIHNlY3VyZSBwcm94eSB1c2luZyBjdXJsIGlzIG5vdCBzdXBwb3J0ZWQgb24gUEhQIHZlcnNpb25zIGJlbG93IDcuMy4wLicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghZW1wdHkoJG9wdGlvbnNbJ3NzbCddWydjYWZpbGUnXSkpIHsKICAgICAgICAgICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1BST1hZX0NBSU5GTywgJG9wdGlvbnNbJ3NzbCddWydjYWZpbGUnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFlbXB0eSgkb3B0aW9uc1snc3NsJ11bJ2NhcGF0aCddKSkgewogICAgICAgICAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfUFJPWFlfQ0FQQVRILCAkb3B0aW9uc1snc3NsJ11bJ2NhcGF0aCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHByb2dyZXNzID0gYXJyYXlfZGlmZl9rZXkoY3VybF9nZXRpbmZvKCRjdXJsSGFuZGxlKSwgc2VsZjo6JHRpbWVJbmZvKTsKCiAgICAgICAgJHRoaXMtPmpvYnNbKGludCkgJGN1cmxIYW5kbGVdID0gYXJyYXkoCiAgICAgICAgICAgICd1cmwnID0+ICR1cmwsCiAgICAgICAgICAgICdvcmlnaW4nID0+ICRvcmlnaW4sCiAgICAgICAgICAgICdhdHRyaWJ1dGVzJyA9PiAkYXR0cmlidXRlcywKICAgICAgICAgICAgJ29wdGlvbnMnID0+ICRvcmlnaW5hbE9wdGlvbnMsCiAgICAgICAgICAgICdwcm9ncmVzcycgPT4gJHByb2dyZXNzLAogICAgICAgICAgICAnY3VybEhhbmRsZScgPT4gJGN1cmxIYW5kbGUsCiAgICAgICAgICAgICdmaWxlbmFtZScgPT4gJGNvcHlUbywKICAgICAgICAgICAgJ2hlYWRlckhhbmRsZScgPT4gJGhlYWRlckhhbmRsZSwKICAgICAgICAgICAgJ2JvZHlIYW5kbGUnID0+ICRib2R5SGFuZGxlLAogICAgICAgICAgICAncmVzb2x2ZScgPT4gJHJlc29sdmUsCiAgICAgICAgICAgICdyZWplY3QnID0+ICRyZWplY3QsCiAgICAgICAgKTsKCiAgICAgICAgJHVzaW5nUHJveHkgPSAkcHJveHktPmdldEZvcm1hdHRlZFVybCgnIHVzaW5nIHByb3h5ICglcyknKTsKICAgICAgICAkaWZNb2RpZmllZCA9IGZhbHNlICE9PSBzdHJpcG9zKGltcGxvZGUoJywnLCAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSksICdpZi1tb2RpZmllZC1zaW5jZTonKSA/ICcgaWYgbW9kaWZpZWQnIDogJyc7CiAgICAgICAgaWYgKCRhdHRyaWJ1dGVzWydyZWRpcmVjdHMnXSA9PT0gMCAmJiAkYXR0cmlidXRlc1sncmV0cmllcyddID09PSAwKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignRG93bmxvYWRpbmcgJyAuIFVybDo6c2FuaXRpemUoJHVybCkgLiAkdXNpbmdQcm94eSAuICRpZk1vZGlmaWVkLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNoZWNrQ3VybFJlc3VsdChjdXJsX211bHRpX2FkZF9oYW5kbGUoJHRoaXMtPm11bHRpSGFuZGxlLCAkY3VybEhhbmRsZSkpOwogICAgICAgIC8vIFRPRE8gcHJvZ3Jlc3MKCiAgICAgICAgcmV0dXJuIChpbnQpICRjdXJsSGFuZGxlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgICRpZAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhYm9ydFJlcXVlc3QoJGlkKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+am9ic1skaWRdLCAkdGhpcy0+am9ic1skaWRdWydjdXJsSGFuZGxlJ10pKSB7CiAgICAgICAgICAgICRqb2IgPSAkdGhpcy0+am9ic1skaWRdOwogICAgICAgICAgICBjdXJsX211bHRpX3JlbW92ZV9oYW5kbGUoJHRoaXMtPm11bHRpSGFuZGxlLCAkam9iWydjdXJsSGFuZGxlJ10pOwogICAgICAgICAgICBjdXJsX2Nsb3NlKCRqb2JbJ2N1cmxIYW5kbGUnXSk7CiAgICAgICAgICAgIGlmIChpc19yZXNvdXJjZSgkam9iWydoZWFkZXJIYW5kbGUnXSkpIHsKICAgICAgICAgICAgICAgIGZjbG9zZSgkam9iWydoZWFkZXJIYW5kbGUnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX3Jlc291cmNlKCRqb2JbJ2JvZHlIYW5kbGUnXSkpIHsKICAgICAgICAgICAgICAgIGZjbG9zZSgkam9iWydib2R5SGFuZGxlJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkam9iWydmaWxlbmFtZSddKSB7CiAgICAgICAgICAgICAgICBAdW5saW5rKCRqb2JbJ2ZpbGVuYW1lJ10uJ34nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bnNldCgkdGhpcy0+am9ic1skaWRdKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRpY2soKQogICAgewogICAgICAgIHN0YXRpYyAkdGltZW91dFdhcm5pbmcgPSBmYWxzZTsKCiAgICAgICAgaWYgKCEkdGhpcy0+am9icykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkYWN0aXZlID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+Y2hlY2tDdXJsUmVzdWx0KGN1cmxfbXVsdGlfZXhlYygkdGhpcy0+bXVsdGlIYW5kbGUsICRhY3RpdmUpKTsKICAgICAgICBpZiAoLTEgPT09IGN1cmxfbXVsdGlfc2VsZWN0KCR0aGlzLT5tdWx0aUhhbmRsZSwgJHRoaXMtPnNlbGVjdFRpbWVvdXQpKSB7CiAgICAgICAgICAgIC8vIHNsZWVwIGluIGNhc2Ugc2VsZWN0IHJldHVybnMgLTEgYXMgaXQgY2FuIGhhcHBlbiBvbiBvbGQgcGhwIHZlcnNpb25zIG9yIHNvbWUgcGxhdGZvcm1zIHdoZXJlIGN1cmwgZG9lcyBub3QgbWFuYWdlIHRvIGRvIHRoZSBzZWxlY3QKICAgICAgICAgICAgdXNsZWVwKDE1MCk7CiAgICAgICAgfQoKICAgICAgICB3aGlsZSAoJHByb2dyZXNzID0gY3VybF9tdWx0aV9pbmZvX3JlYWQoJHRoaXMtPm11bHRpSGFuZGxlKSkgewogICAgICAgICAgICAkY3VybEhhbmRsZSA9ICRwcm9ncmVzc1snaGFuZGxlJ107CiAgICAgICAgICAgICRyZXN1bHQgPSAkcHJvZ3Jlc3NbJ3Jlc3VsdCddOwogICAgICAgICAgICAkaSA9IChpbnQpICRjdXJsSGFuZGxlOwogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5qb2JzWyRpXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJvZ3Jlc3MgPSBjdXJsX2dldGluZm8oJGN1cmxIYW5kbGUpOwogICAgICAgICAgICAkam9iID0gJHRoaXMtPmpvYnNbJGldOwogICAgICAgICAgICB1bnNldCgkdGhpcy0+am9ic1skaV0pOwogICAgICAgICAgICAkZXJyb3IgPSBjdXJsX2Vycm9yKCRjdXJsSGFuZGxlKTsKICAgICAgICAgICAgJGVycm5vID0gY3VybF9lcnJubygkY3VybEhhbmRsZSk7CiAgICAgICAgICAgIGN1cmxfbXVsdGlfcmVtb3ZlX2hhbmRsZSgkdGhpcy0+bXVsdGlIYW5kbGUsICRjdXJsSGFuZGxlKTsKICAgICAgICAgICAgY3VybF9jbG9zZSgkY3VybEhhbmRsZSk7CgogICAgICAgICAgICAkaGVhZGVycyA9IG51bGw7CiAgICAgICAgICAgICRzdGF0dXNDb2RlID0gbnVsbDsKICAgICAgICAgICAgJHJlc3BvbnNlID0gbnVsbDsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIFRPRE8gcHJvZ3Jlc3MKICAgICAgICAgICAgICAgIGlmIChDVVJMRV9PSyAhPT0gJGVycm5vIHx8ICRlcnJvciB8fCAkcmVzdWx0ICE9PSBDVVJMRV9PSykgewogICAgICAgICAgICAgICAgICAgICRlcnJubyA9ICRlcnJubyA/OiAkcmVzdWx0OwogICAgICAgICAgICAgICAgICAgIGlmICghJGVycm9yICYmIGZ1bmN0aW9uX2V4aXN0cygnY3VybF9zdHJlcnJvcicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRlcnJvciA9IGN1cmxfc3RyZXJyb3IoJGVycm5vKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHByb2dyZXNzWydlcnJvcl9jb2RlJ10gPSAkZXJybm87CgogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKCFpc3NldCgkam9iWydvcHRpb25zJ11bJ2h0dHAnXVsnbWV0aG9kJ10pIHx8ICRqb2JbJ29wdGlvbnMnXVsnaHR0cCddWydtZXRob2QnXSA9PT0gJ0dFVCcpCiAgICAgICAgICAgICAgICAgICAgICAgICYmICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluX2FycmF5KCRlcnJubywgYXJyYXkoNyAvKiBDVVJMRV9DT1VMRE5UX0NPTk5FQ1QgKi8sIDE2IC8qIENVUkxFX0hUVFAyICovLCA5MiAvKiBDVVJMRV9IVFRQMl9TVFJFQU0gKi8pLCB0cnVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKCRlcnJubyA9PT0gMzUgLyogQ1VSTEVfU1NMX0NPTk5FQ1RfRVJST1IgKi8gJiYgZmFsc2UgIT09IHN0cnBvcygkZXJyb3IsICdDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXInKSkKICAgICAgICAgICAgICAgICAgICAgICAgKSAmJiAkam9iWydhdHRyaWJ1dGVzJ11bJ3JldHJpZXMnXSA8ICR0aGlzLT5tYXhSZXRyaWVzCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignUmV0cnlpbmcgKCcuKCRqb2JbJ2F0dHJpYnV0ZXMnXVsncmV0cmllcyddICsgMSkuJykgJyAuIFVybDo6c2FuaXRpemUoJGpvYlsndXJsJ10pIC4gJyBkdWUgdG8gY3VybCBlcnJvciAnLiAkZXJybm8sIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXN0YXJ0Sm9iKCRqb2IsICRqb2JbJ3VybCddLCBhcnJheSgncmV0cmllcycgPT4gJGpvYlsnYXR0cmlidXRlcyddWydyZXRyaWVzJ10gKyAxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCRlcnJubyA9PT0gMjggLyogQ1VSTEVfT1BFUkFUSU9OX1RJTUVET1VUICovICYmIGlzc2V0KCRwcm9ncmVzc1snbmFtZWxvb2t1cF90aW1lJ10pICYmICRwcm9ncmVzc1snbmFtZWxvb2t1cF90aW1lJ10gPT0gMCAmJiAhJHRpbWVvdXRXYXJuaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aW1lb3V0V2FybmluZyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QSBjb25uZWN0aW9uIHRpbWVvdXQgd2FzIGVuY291bnRlcmVkLiBJZiB5b3UgaW50ZW5kIHRvIHJ1biBDb21wb3NlciB3aXRob3V0IGNvbm5lY3RpbmcgdG8gdGhlIGludGVybmV0LCBydW4gdGhlIGNvbW1hbmQgYWdhaW4gcHJlZml4ZWQgd2l0aCBDT01QT1NFUl9ESVNBQkxFX05FVFdPUks9MSB0byBtYWtlIENvbXBvc2VyIHJ1biBpbiBvZmZsaW5lIG1vZGUuPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignY3VybCBlcnJvciAnLiRlcnJuby4nIHdoaWxlIGRvd25sb2FkaW5nICcuVXJsOjpzYW5pdGl6ZSgkcHJvZ3Jlc3NbJ3VybCddKS4nOiAnLiRlcnJvcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkc3RhdHVzQ29kZSA9ICRwcm9ncmVzc1snaHR0cF9jb2RlJ107CiAgICAgICAgICAgICAgICByZXdpbmQoJGpvYlsnaGVhZGVySGFuZGxlJ10pOwogICAgICAgICAgICAgICAgJGhlYWRlcnMgPSBleHBsb2RlKCJcclxuIiwgcnRyaW0oc3RyZWFtX2dldF9jb250ZW50cygkam9iWydoZWFkZXJIYW5kbGUnXSkpKTsKICAgICAgICAgICAgICAgIGZjbG9zZSgkam9iWydoZWFkZXJIYW5kbGUnXSk7CgogICAgICAgICAgICAgICAgaWYgKCRzdGF0dXNDb2RlID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignUmVjZWl2ZWQgdW5leHBlY3RlZCBodHRwIHN0YXR1cyBjb2RlIDAgd2l0aG91dCBlcnJvciBmb3IgJy5Vcmw6OnNhbml0aXplKCRwcm9ncmVzc1sndXJsJ10pLic6IGhlYWRlcnMgJy52YXJfZXhwb3J0KCRoZWFkZXJzLCB0cnVlKS4nIGN1cmwgaW5mbyAnLnZhcl9leHBvcnQoJHByb2dyZXNzLCB0cnVlKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gcHJlcGFyZSByZXNwb25zZSBvYmplY3QKICAgICAgICAgICAgICAgIGlmICgkam9iWydmaWxlbmFtZSddKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnRzID0gJGpvYlsnZmlsZW5hbWUnXS4nfic7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRzdGF0dXNDb2RlID49IDMwMCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXdpbmQoJGpvYlsnYm9keUhhbmRsZSddKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnRzID0gc3RyZWFtX2dldF9jb250ZW50cygkam9iWydib2R5SGFuZGxlJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSBuZXcgQ3VybFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICRwcm9ncmVzc1sndXJsJ10pLCAkc3RhdHVzQ29kZSwgJGhlYWRlcnMsICRjb250ZW50cywgJHByb2dyZXNzKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1snLiRzdGF0dXNDb2RlLiddICcuVXJsOjpzYW5pdGl6ZSgkcHJvZ3Jlc3NbJ3VybCddKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV3aW5kKCRqb2JbJ2JvZHlIYW5kbGUnXSk7CiAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnRzID0gc3RyZWFtX2dldF9jb250ZW50cygkam9iWydib2R5SGFuZGxlJ10pOwogICAgICAgICAgICAgICAgICAgICRyZXNwb25zZSA9IG5ldyBDdXJsUmVzcG9uc2UoYXJyYXkoJ3VybCcgPT4gJHByb2dyZXNzWyd1cmwnXSksICRzdGF0dXNDb2RlLCAkaGVhZGVycywgJGNvbnRlbnRzLCAkcHJvZ3Jlc3MpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWycuJHN0YXR1c0NvZGUuJ10gJy5Vcmw6OnNhbml0aXplKCRwcm9ncmVzc1sndXJsJ10pLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZmNsb3NlKCRqb2JbJ2JvZHlIYW5kbGUnXSk7CgogICAgICAgICAgICAgICAgaWYgKCRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID49IDQwMCAmJiAkcmVzcG9uc2UtPmdldEhlYWRlcignY29udGVudC10eXBlJykgPT09ICdhcHBsaWNhdGlvbi9qc29uJykgewogICAgICAgICAgICAgICAgICAgIEh0dHBEb3dubG9hZGVyOjpvdXRwdXRXYXJuaW5ncygkdGhpcy0+aW8sICRqb2JbJ29yaWdpbiddLCBqc29uX2RlY29kZSgkcmVzcG9uc2UtPmdldEJvZHkoKSwgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+aXNBdXRoZW50aWNhdGVkUmV0cnlOZWVkZWQoJGpvYiwgJHJlc3BvbnNlKTsKICAgICAgICAgICAgICAgIGlmICgkcmVzdWx0WydyZXRyeSddKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlc3RhcnRKb2IoJGpvYiwgJGpvYlsndXJsJ10sIGFycmF5KCdzdG9yZUF1dGgnID0+ICRyZXN1bHRbJ3N0b3JlQXV0aCddKSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaGFuZGxlIDN4eCByZWRpcmVjdHMsIDMwNCBOb3QgTW9kaWZpZWQgaXMgZXhjbHVkZWQKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSAzMDAgJiYgJHN0YXR1c0NvZGUgPD0gMzk5ICYmICRzdGF0dXNDb2RlICE9PSAzMDQgJiYgJGpvYlsnYXR0cmlidXRlcyddWydyZWRpcmVjdHMnXSA8ICR0aGlzLT5tYXhSZWRpcmVjdHMpIHsKICAgICAgICAgICAgICAgICAgICAkbG9jYXRpb24gPSAkdGhpcy0+aGFuZGxlUmVkaXJlY3QoJGpvYiwgJHJlc3BvbnNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxvY2F0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXN0YXJ0Sm9iKCRqb2IsICRsb2NhdGlvbiwgYXJyYXkoJ3JlZGlyZWN0cycgPT4gJGpvYlsnYXR0cmlidXRlcyddWydyZWRpcmVjdHMnXSArIDEpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGZhaWwgNHh4IGFuZCA1eHggcmVzcG9uc2VzIGFuZCBjYXB0dXJlIHRoZSByZXNwb25zZQogICAgICAgICAgICAgICAgaWYgKCRzdGF0dXNDb2RlID49IDQwMCAmJiAkc3RhdHVzQ29kZSA8PSA1OTkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICghaXNzZXQoJGpvYlsnb3B0aW9ucyddWydodHRwJ11bJ21ldGhvZCddKSB8fCAkam9iWydvcHRpb25zJ11bJ2h0dHAnXVsnbWV0aG9kJ10gPT09ICdHRVQnKQogICAgICAgICAgICAgICAgICAgICAgICAmJiBpbl9hcnJheSgkc3RhdHVzQ29kZSwgYXJyYXkoNDIzLCA0MjUsIDUwMCwgNTAyLCA1MDMsIDUwNCwgNTA3LCA1MTApLCB0cnVlKQogICAgICAgICAgICAgICAgICAgICAgICAmJiAkam9iWydhdHRyaWJ1dGVzJ11bJ3JldHJpZXMnXSA8ICR0aGlzLT5tYXhSZXRyaWVzCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignUmV0cnlpbmcgKCcuKCRqb2JbJ2F0dHJpYnV0ZXMnXVsncmV0cmllcyddICsgMSkuJykgJyAuIFVybDo6c2FuaXRpemUoJGpvYlsndXJsJ10pIC4gJyBkdWUgdG8gc3RhdHVzIGNvZGUgJy4gJHN0YXR1c0NvZGUsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXN0YXJ0Sm9iKCRqb2IsICRqb2JbJ3VybCddLCBhcnJheSgncmV0cmllcycgPT4gJGpvYlsnYXR0cmlidXRlcyddWydyZXRyaWVzJ10gKyAxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJHRoaXMtPmZhaWxSZXNwb25zZSgkam9iLCAkcmVzcG9uc2UsICRyZXNwb25zZS0+Z2V0U3RhdHVzTWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGpvYlsnYXR0cmlidXRlcyddWydzdG9yZUF1dGgnXSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hdXRoSGVscGVyLT5zdG9yZUF1dGgoJGpvYlsnb3JpZ2luJ10sICRqb2JbJ2F0dHJpYnV0ZXMnXVsnc3RvcmVBdXRoJ10pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHJlc29sdmUgcHJvbWlzZQogICAgICAgICAgICAgICAgaWYgKCRqb2JbJ2ZpbGVuYW1lJ10pIHsKICAgICAgICAgICAgICAgICAgICByZW5hbWUoJGpvYlsnZmlsZW5hbWUnXS4nficsICRqb2JbJ2ZpbGVuYW1lJ10pOwogICAgICAgICAgICAgICAgICAgIGNhbGxfdXNlcl9mdW5jKCRqb2JbJ3Jlc29sdmUnXSwgJHJlc3BvbnNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJGpvYlsncmVzb2x2ZSddLCAkcmVzcG9uc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJGhlYWRlcnMpIHsKICAgICAgICAgICAgICAgICAgICAkZS0+c2V0SGVhZGVycygkaGVhZGVycyk7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFN0YXR1c0NvZGUoJHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRyZXNwb25zZSkgewogICAgICAgICAgICAgICAgICAgICRlLT5zZXRSZXNwb25zZSgkcmVzcG9uc2UtPmdldEJvZHkoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJHByb2dyZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlSW5mbygkcHJvZ3Jlc3MpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RKb2IoJGpvYiwgJGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+am9icyBhcyAkaSA9PiAkY3VybEhhbmRsZSkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5qb2JzWyRpXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjdXJsSGFuZGxlID0gJHRoaXMtPmpvYnNbJGldWydjdXJsSGFuZGxlJ107CiAgICAgICAgICAgICRwcm9ncmVzcyA9IGFycmF5X2RpZmZfa2V5KGN1cmxfZ2V0aW5mbygkY3VybEhhbmRsZSksIHNlbGY6OiR0aW1lSW5mbyk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPmpvYnNbJGldWydwcm9ncmVzcyddICE9PSAkcHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5qb2JzWyRpXVsncHJvZ3Jlc3MnXSA9ICRwcm9ncmVzczsKCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmpvYnNbJGldWydvcHRpb25zJ11bJ21heF9maWxlX3NpemUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb21wYXJlIG1heF9maWxlX3NpemUgd2l0aCB0aGUgY29udGVudC1sZW5ndGggaGVhZGVyIHRoaXMgdmFsdWUgd2lsbCBiZSAtMSB1bnRpbCB0aGUgaGVhZGVyIGlzIHBhcnNlZAogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+am9ic1skaV1bJ29wdGlvbnMnXVsnbWF4X2ZpbGVfc2l6ZSddIDwgJHByb2dyZXNzWydkb3dubG9hZF9jb250ZW50X2xlbmd0aCddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RKb2IoJHRoaXMtPmpvYnNbJGldLCBuZXcgTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbignTWF4aW11bSBhbGxvd2VkIGRvd25sb2FkIHNpemUgcmVhY2hlZC4gQ29udGVudC1sZW5ndGggaGVhZGVyIGluZGljYXRlcyAnIC4gJHByb2dyZXNzWydkb3dubG9hZF9jb250ZW50X2xlbmd0aCddIC4gJyBieXRlcy4gQWxsb3dlZCAnIC4gICR0aGlzLT5qb2JzWyRpXVsnb3B0aW9ucyddWydtYXhfZmlsZV9zaXplJ10gLiAnIGJ5dGVzJykpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tcGFyZSBtYXhfZmlsZV9zaXplIHdpdGggdGhlIGRvd25sb2FkIHNpemUgaW4gYnl0ZXMKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmpvYnNbJGldWydvcHRpb25zJ11bJ21heF9maWxlX3NpemUnXSA8ICRwcm9ncmVzc1snc2l6ZV9kb3dubG9hZCddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RKb2IoJHRoaXMtPmpvYnNbJGldLCBuZXcgTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbignTWF4aW11bSBhbGxvd2VkIGRvd25sb2FkIHNpemUgcmVhY2hlZC4gRG93bmxvYWRlZCAnIC4gJHByb2dyZXNzWydzaXplX2Rvd25sb2FkJ10gLiAnIG9mIGFsbG93ZWQgJyAuICAkdGhpcy0+am9ic1skaV1bJ29wdGlvbnMnXVsnbWF4X2ZpbGVfc2l6ZSddIC4gJyBieXRlcycpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gVE9ETyBwcm9ncmVzcwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBKb2IgICAgJGpvYgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBoYW5kbGVSZWRpcmVjdChhcnJheSAkam9iLCBSZXNwb25zZSAkcmVzcG9uc2UpCiAgICB7CiAgICAgICAgaWYgKCRsb2NhdGlvbkhlYWRlciA9ICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdsb2NhdGlvbicpKSB7CiAgICAgICAgICAgIGlmIChwYXJzZV91cmwoJGxvY2F0aW9uSGVhZGVyLCBQSFBfVVJMX1NDSEVNRSkpIHsKICAgICAgICAgICAgICAgIC8vIEFic29sdXRlIFVSTDsgZS5nLiBodHRwczovL2V4YW1wbGUuY29tL2NvbXBvc2VyCiAgICAgICAgICAgICAgICAkdGFyZ2V0VXJsID0gJGxvY2F0aW9uSGVhZGVyOwogICAgICAgICAgICB9IGVsc2VpZiAocGFyc2VfdXJsKCRsb2NhdGlvbkhlYWRlciwgUEhQX1VSTF9IT1NUKSkgewogICAgICAgICAgICAgICAgLy8gU2NoZW1lIHJlbGF0aXZlOyBlLmcuIC8vZXhhbXBsZS5jb20vZm9vCiAgICAgICAgICAgICAgICAkdGFyZ2V0VXJsID0gcGFyc2VfdXJsKCRqb2JbJ3VybCddLCBQSFBfVVJMX1NDSEVNRSkuJzonLiRsb2NhdGlvbkhlYWRlcjsKICAgICAgICAgICAgfSBlbHNlaWYgKCcvJyA9PT0gJGxvY2F0aW9uSGVhZGVyWzBdKSB7CiAgICAgICAgICAgICAgICAvLyBBYnNvbHV0ZSBwYXRoOyBlLmcuIC9mb28KICAgICAgICAgICAgICAgICR1cmxIb3N0ID0gcGFyc2VfdXJsKCRqb2JbJ3VybCddLCBQSFBfVVJMX0hPU1QpOwoKICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgcGF0aCB1c2luZyBob3N0bmFtZSBhcyBhbiBhbmNob3IuCiAgICAgICAgICAgICAgICAkdGFyZ2V0VXJsID0gUHJlZzo6cmVwbGFjZSgne14oLisoPzovL3xAKScucHJlZ19xdW90ZSgkdXJsSG9zdCkuJyg/OjpcZCspPykoPzpbL1w/XS4qKT8kfScsICdcMScuJGxvY2F0aW9uSGVhZGVyLCAkam9iWyd1cmwnXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBSZWxhdGl2ZSBwYXRoOyBlLmcuIGZvbwogICAgICAgICAgICAgICAgLy8gVGhpcyBhY3R1YWxseSBkaWZmZXJzIGZyb20gUEhQIHdoaWNoIHNlZW1zIHRvIGFkZCBkdXBsaWNhdGUgc2xhc2hlcy4KICAgICAgICAgICAgICAgICR0YXJnZXRVcmwgPSBQcmVnOjpyZXBsYWNlKCd7XiguKy8pW14vP10qKD86XD8uKik/JH0nLCAnXDEnLiRsb2NhdGlvbkhlYWRlciwgJGpvYlsndXJsJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR0YXJnZXRVcmwpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCdGb2xsb3dpbmcgcmVkaXJlY3QgKCV1KSAlcycsICRqb2JbJ2F0dHJpYnV0ZXMnXVsncmVkaXJlY3RzJ10gKyAxLCBVcmw6OnNhbml0aXplKCR0YXJnZXRVcmwpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKCiAgICAgICAgICAgIHJldHVybiAkdGFyZ2V0VXJsOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiRqb2JbJ3VybCddLiciIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQsIGdvdCByZWRpcmVjdCB3aXRob3V0IExvY2F0aW9uICgnLiRyZXNwb25zZS0+Z2V0U3RhdHVzTWVzc2FnZSgpLicpJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIEpvYiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkam9iCiAgICAgKiBAcmV0dXJuIGFycmF5e3JldHJ5OiBib29sLCBzdG9yZUF1dGg6IHN0cmluZ3xib29sfQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzQXV0aGVudGljYXRlZFJldHJ5TmVlZGVkKGFycmF5ICRqb2IsIFJlc3BvbnNlICRyZXNwb25zZSkKICAgIHsKICAgICAgICBpZiAoaW5fYXJyYXkoJHJlc3BvbnNlLT5nZXRTdGF0dXNDb2RlKCksIGFycmF5KDQwMSwgNDAzKSkgJiYgJGpvYlsnYXR0cmlidXRlcyddWydyZXRyeUF1dGhGYWlsdXJlJ10pIHsKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5hdXRoSGVscGVyLT5wcm9tcHRBdXRoSWZOZWVkZWQoJGpvYlsndXJsJ10sICRqb2JbJ29yaWdpbiddLCAkcmVzcG9uc2UtPmdldFN0YXR1c0NvZGUoKSwgJHJlc3BvbnNlLT5nZXRTdGF0dXNNZXNzYWdlKCksICRyZXNwb25zZS0+Z2V0SGVhZGVycygpKTsKCiAgICAgICAgICAgIGlmICgkcmVzdWx0WydyZXRyeSddKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGxvY2F0aW9uSGVhZGVyID0gJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2xvY2F0aW9uJyk7CiAgICAgICAgJG5lZWRzQXV0aFJldHJ5ID0gZmFsc2U7CgogICAgICAgIC8vIGNoZWNrIGZvciBiaXRidWNrZXQgbG9naW4gcGFnZSBhc2tpbmcgdG8gYXV0aGVudGljYXRlCiAgICAgICAgaWYgKAogICAgICAgICAgICAkam9iWydvcmlnaW4nXSA9PT0gJ2JpdGJ1Y2tldC5vcmcnCiAgICAgICAgICAgICYmICEkdGhpcy0+YXV0aEhlbHBlci0+aXNQdWJsaWNCaXRCdWNrZXREb3dubG9hZCgkam9iWyd1cmwnXSkKICAgICAgICAgICAgJiYgc3Vic3RyKCRqb2JbJ3VybCddLCAtNCkgPT09ICcuemlwJwogICAgICAgICAgICAmJiAoISRsb2NhdGlvbkhlYWRlciB8fCBzdWJzdHIoJGxvY2F0aW9uSGVhZGVyLCAtNCkgIT09ICcuemlwJykKICAgICAgICAgICAgJiYgUHJlZzo6aXNNYXRjaCgne150ZXh0L2h0bWxcYn1pJywgJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKQogICAgICAgICkgewogICAgICAgICAgICAkbmVlZHNBdXRoUmV0cnkgPSAnQml0YnVja2V0IHJlcXVpcmVzIGF1dGhlbnRpY2F0aW9uIGFuZCBpdCB3YXMgbm90IHByb3ZpZGVkJzsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBnaXRsYWIgNDA0IHdoZW4gZG93bmxvYWRpbmcgYXJjaGl2ZXMKICAgICAgICBpZiAoCiAgICAgICAgICAgICRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0MDQKICAgICAgICAgICAgJiYgaW5fYXJyYXkoJGpvYlsnb3JpZ2luJ10sICR0aGlzLT5jb25maWctPmdldCgnZ2l0bGFiLWRvbWFpbnMnKSwgdHJ1ZSkKICAgICAgICAgICAgJiYgZmFsc2UgIT09IHN0cnBvcygkam9iWyd1cmwnXSwgJ2FyY2hpdmUuemlwJykKICAgICAgICApIHsKICAgICAgICAgICAgJG5lZWRzQXV0aFJldHJ5ID0gJ0dpdExhYiByZXF1aXJlcyBhdXRoZW50aWNhdGlvbiBhbmQgaXQgd2FzIG5vdCBwcm92aWRlZCc7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG5lZWRzQXV0aFJldHJ5KSB7CiAgICAgICAgICAgIGlmICgkam9iWydhdHRyaWJ1dGVzJ11bJ3JldHJ5QXV0aEZhaWx1cmUnXSkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5hdXRoSGVscGVyLT5wcm9tcHRBdXRoSWZOZWVkZWQoJGpvYlsndXJsJ10sICRqb2JbJ29yaWdpbiddLCA0MDEpOwogICAgICAgICAgICAgICAgaWYgKCRyZXN1bHRbJ3JldHJ5J10pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJHRoaXMtPmZhaWxSZXNwb25zZSgkam9iLCAkcmVzcG9uc2UsICRuZWVkc0F1dGhSZXRyeSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJ3JldHJ5JyA9PiBmYWxzZSwgJ3N0b3JlQXV0aCcgPT4gZmFsc2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBKb2IgICAgJGpvYgogICAgICogQHBhcmFtICBzdHJpbmcgJHVybAogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXl7cmV0cnlBdXRoRmFpbHVyZT86IGJvb2wsIHJlZGlyZWN0cz86IGludCwgc3RvcmVBdXRoPzogYm9vbH0gJGF0dHJpYnV0ZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXN0YXJ0Sm9iKGFycmF5ICRqb2IsICR1cmwsIGFycmF5ICRhdHRyaWJ1dGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoJGpvYlsnZmlsZW5hbWUnXSkgewogICAgICAgICAgICBAdW5saW5rKCRqb2JbJ2ZpbGVuYW1lJ10uJ34nKTsKICAgICAgICB9CgogICAgICAgICRhdHRyaWJ1dGVzID0gYXJyYXlfbWVyZ2UoJGpvYlsnYXR0cmlidXRlcyddLCAkYXR0cmlidXRlcyk7CiAgICAgICAgJG9yaWdpbiA9IFVybDo6Z2V0T3JpZ2luKCR0aGlzLT5jb25maWcsICR1cmwpOwoKICAgICAgICAkdGhpcy0+aW5pdERvd25sb2FkKCRqb2JbJ3Jlc29sdmUnXSwgJGpvYlsncmVqZWN0J10sICRvcmlnaW4sICR1cmwsICRqb2JbJ29wdGlvbnMnXSwgJGpvYlsnZmlsZW5hbWUnXSwgJGF0dHJpYnV0ZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBKb2IgICAgICAgICAgICAgICAgJGpvYgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgJGVycm9yTWVzc2FnZQogICAgICogQHJldHVybiBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmYWlsUmVzcG9uc2UoYXJyYXkgJGpvYiwgUmVzcG9uc2UgJHJlc3BvbnNlLCAkZXJyb3JNZXNzYWdlKQogICAgewogICAgICAgIGlmICgkam9iWydmaWxlbmFtZSddKSB7CiAgICAgICAgICAgIEB1bmxpbmsoJGpvYlsnZmlsZW5hbWUnXS4nficpOwogICAgICAgIH0KCiAgICAgICAgJGRldGFpbHMgPSAnJzsKICAgICAgICBpZiAoaW5fYXJyYXkoc3RydG9sb3dlcigkcmVzcG9uc2UtPmdldEhlYWRlcignY29udGVudC10eXBlJykpLCBhcnJheSgnYXBwbGljYXRpb24vanNvbicsICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04JyksIHRydWUpKSB7CiAgICAgICAgICAgICRkZXRhaWxzID0gJzonLlBIUF9FT0wuc3Vic3RyKCRyZXNwb25zZS0+Z2V0Qm9keSgpLCAwLCAyMDApLihzdHJsZW4oJHJlc3BvbnNlLT5nZXRCb2R5KCkpID4gMjAwID8gJy4uLicgOiAnJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiRqb2JbJ3VybCddLiciIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQgKCcuJGVycm9yTWVzc2FnZS4nKScgLiAkZGV0YWlscywgJHJlc3BvbnNlLT5nZXRTdGF0dXNDb2RlKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBKb2IgICAgICAgICAgICAgICAgJGpvYgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVqZWN0Sm9iKGFycmF5ICRqb2IsIFxFeGNlcHRpb24gJGUpCiAgICB7CiAgICAgICAgaWYgKGlzX3Jlc291cmNlKCRqb2JbJ2hlYWRlckhhbmRsZSddKSkgewogICAgICAgICAgICBmY2xvc2UoJGpvYlsnaGVhZGVySGFuZGxlJ10pOwogICAgICAgIH0KICAgICAgICBpZiAoaXNfcmVzb3VyY2UoJGpvYlsnYm9keUhhbmRsZSddKSkgewogICAgICAgICAgICBmY2xvc2UoJGpvYlsnYm9keUhhbmRsZSddKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRqb2JbJ2ZpbGVuYW1lJ10pIHsKICAgICAgICAgICAgQHVubGluaygkam9iWydmaWxlbmFtZSddLid+Jyk7CiAgICAgICAgfQogICAgICAgIGNhbGxfdXNlcl9mdW5jKCRqb2JbJ3JlamVjdCddLCAkZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludCAgJGNvZGUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrQ3VybFJlc3VsdCgkY29kZSkKICAgIHsKICAgICAgICBpZiAoJGNvZGUgIT0gQ1VSTE1fT0sgJiYgJGNvZGUgIT0gQ1VSTE1fQ0FMTF9NVUxUSV9QRVJGT1JNKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgIGlzc2V0KCR0aGlzLT5tdWx0aUVycm9yc1skY29kZV0pCiAgICAgICAgICAgICAgICA/ICJjVVJMIGVycm9yOiB7JGNvZGV9ICh7JHRoaXMtPm11bHRpRXJyb3JzWyRjb2RlXVswXX0pOiBjVVJMIG1lc3NhZ2U6IHskdGhpcy0+bXVsdGlFcnJvcnNbJGNvZGVdWzFdfSIKICAgICAgICAgICAgICAgIDogJ1VuZXhwZWN0ZWQgY1VSTCBlcnJvcjogJyAuICRjb2RlCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWxcSHR0cDsKCi8qKgogKiBAcGhwc3Rhbi10eXBlIEN1cmxJbmZvIGFycmF5e3VybDogbWl4ZWQsIGNvbnRlbnRfdHlwZTogbWl4ZWQsIGh0dHBfY29kZTogbWl4ZWQsIGhlYWRlcl9zaXplOiBtaXhlZCwgcmVxdWVzdF9zaXplOiBtaXhlZCwgZmlsZXRpbWU6IG1peGVkLCBzc2xfdmVyaWZ5X3Jlc3VsdDogbWl4ZWQsIHJlZGlyZWN0X2NvdW50OiBtaXhlZCwgdG90YWxfdGltZTogbWl4ZWQsIG5hbWVsb29rdXBfdGltZTogbWl4ZWQsIGNvbm5lY3RfdGltZTogbWl4ZWQsIHByZXRyYW5zZmVyX3RpbWU6IG1peGVkLCBzaXplX3VwbG9hZDogbWl4ZWQsIHNpemVfZG93bmxvYWQ6IG1peGVkLCBzcGVlZF9kb3dubG9hZDogbWl4ZWQsIHNwZWVkX3VwbG9hZDogbWl4ZWQsIGRvd25sb2FkX2NvbnRlbnRfbGVuZ3RoOiBtaXhlZCwgdXBsb2FkX2NvbnRlbnRfbGVuZ3RoOiBtaXhlZCwgc3RhcnR0cmFuc2Zlcl90aW1lOiBtaXhlZCwgcmVkaXJlY3RfdGltZTogbWl4ZWQsIGNlcnRpbmZvOiBtaXhlZCwgcHJpbWFyeV9pcDogbWl4ZWQsIHByaW1hcnlfcG9ydDogbWl4ZWQsIGxvY2FsX2lwOiBtaXhlZCwgbG9jYWxfcG9ydDogbWl4ZWQsIHJlZGlyZWN0X3VybDogbWl4ZWR9CiAqLwpjbGFzcyBDdXJsUmVzcG9uc2UgZXh0ZW5kcyBSZXNwb25zZQp7CiAgICAvKioKICAgICAqIEBzZWUgaHR0cHM6Ly93d3cucGhwLm5ldC9jdXJsX2dldGluZm8KICAgICAqIEB2YXIgQ3VybEluZm8KICAgICAqLwogICAgcHJpdmF0ZSAkY3VybEluZm87CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQ3VybEluZm8gJGN1cmxJbmZvCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcmVxdWVzdCwgJGNvZGUsIGFycmF5ICRoZWFkZXJzLCAkYm9keSwgYXJyYXkgJGN1cmxJbmZvKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHJlcXVlc3QsICRjb2RlLCAkaGVhZGVycywgJGJvZHkpOwogICAgICAgICR0aGlzLT5jdXJsSW5mbyA9ICRjdXJsSW5mbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ3VybEluZm8KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEN1cmxJbmZvKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmN1cmxJbmZvOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7CgovKioKICogQGF1dGhvciBXaXNzZW0gUmlhaGkgPHdpc3NlbXJAZ21haWwuY29tPgogKi8KY2xhc3MgVGFyCnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aFRvQXJjaGl2ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRDb21wb3Nlckpzb24oJHBhdGhUb0FyY2hpdmUpCiAgICB7CiAgICAgICAgJHBoYXIgPSBuZXcgXFBoYXJEYXRhKCRwYXRoVG9BcmNoaXZlKTsKCiAgICAgICAgaWYgKCEkcGhhci0+dmFsaWQoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjpleHRyYWN0Q29tcG9zZXJKc29uRnJvbUZvbGRlcigkcGhhcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gXFBoYXJEYXRhICRwaGFyCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3RDb21wb3Nlckpzb25Gcm9tRm9sZGVyKFxQaGFyRGF0YSAkcGhhcikKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHBoYXJbJ2NvbXBvc2VyLmpzb24nXSkpIHsKICAgICAgICAgICAgcmV0dXJuICRwaGFyWydjb21wb3Nlci5qc29uJ10tPmdldENvbnRlbnQoKTsKICAgICAgICB9CgogICAgICAgICR0b3BMZXZlbFBhdGhzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGhhciBhcyAkZm9sZGVyRmlsZSkgewogICAgICAgICAgICAkbmFtZSA9ICRmb2xkZXJGaWxlLT5nZXRCYXNlbmFtZSgpOwoKICAgICAgICAgICAgaWYgKCRmb2xkZXJGaWxlLT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICAkdG9wTGV2ZWxQYXRoc1skbmFtZV0gPSB0cnVlOwogICAgICAgICAgICAgICAgaWYgKFxjb3VudCgkdG9wTGV2ZWxQYXRocykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdBcmNoaXZlIGhhcyBtb3JlIHRoYW4gb25lIHRvcCBsZXZlbCBkaXJlY3RvcmllcywgYW5kIG5vIGNvbXBvc2VyLmpzb24gd2FzIGZvdW5kIG9uIHRoZSB0b3AgbGV2ZWwsIHNvIGl0XCdzIGFuIGludmFsaWQgYXJjaGl2ZS4gVG9wIGxldmVsIHBhdGhzIGZvdW5kIHdlcmU6ICcuaW1wbG9kZSgnLCcsIGFycmF5X2tleXMoJHRvcExldmVsUGF0aHMpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21wb3Nlckpzb25QYXRoID0ga2V5KCR0b3BMZXZlbFBhdGhzKS4nL2NvbXBvc2VyLmpzb24nOwogICAgICAgIGlmICgkdG9wTGV2ZWxQYXRocyAmJiBpc3NldCgkcGhhclskY29tcG9zZXJKc29uUGF0aF0pKSB7CiAgICAgICAgICAgIHJldHVybiAkcGhhclskY29tcG9zZXJKc29uUGF0aF0tPmdldENvbnRlbnQoKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignTm8gY29tcG9zZXIuanNvbiBmb3VuZCBlaXRoZXIgYXQgdGhlIHRvcCBsZXZlbCBvciB3aXRoaW4gdGhlIHRvcG1vc3QgZGlyZWN0b3J5Jyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CnVzZSBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjsKdXNlIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvblxJT0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgRmlsZXN5c3RlbQp7CiAgICAvKiogQHZhciA/UHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcml2YXRlICRwcm9jZXNzRXhlY3V0b3I7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFByb2Nlc3NFeGVjdXRvciAkZXhlY3V0b3IgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IgPSAkZXhlY3V0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmUoJGZpbGUpCiAgICB7CiAgICAgICAgaWYgKGlzX2RpcigkZmlsZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVEaXJlY3RvcnkoJGZpbGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnVubGluaygkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYSBkaXJlY3RvcnkgaXMgZW1wdHkKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkZGlyCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGlyRW1wdHkoJGRpcikKICAgIHsKICAgICAgICAkZmluZGVyID0gRmluZGVyOjpjcmVhdGUoKQogICAgICAgICAgICAtPmlnbm9yZVZDUyhmYWxzZSkKICAgICAgICAgICAgLT5pZ25vcmVEb3RGaWxlcyhmYWxzZSkKICAgICAgICAgICAgLT5kZXB0aCgwKQogICAgICAgICAgICAtPmluKCRkaXIpOwoKICAgICAgICByZXR1cm4gXGNvdW50KCRmaW5kZXIpID09PSAwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZGlyCiAgICAgKiBAcGFyYW0gYm9vbCAgICRlbnN1cmVEaXJlY3RvcnlFeGlzdHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVtcHR5RGlyZWN0b3J5KCRkaXIsICRlbnN1cmVEaXJlY3RvcnlFeGlzdHMgPSB0cnVlKQogICAgewogICAgICAgIGlmIChpc19saW5rKCRkaXIpICYmIGZpbGVfZXhpc3RzKCRkaXIpKSB7CiAgICAgICAgICAgICR0aGlzLT51bmxpbmsoJGRpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVuc3VyZURpcmVjdG9yeUV4aXN0cykgewogICAgICAgICAgICAkdGhpcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRkaXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX2RpcigkZGlyKSkgewogICAgICAgICAgICAkZmluZGVyID0gRmluZGVyOjpjcmVhdGUoKQogICAgICAgICAgICAgICAgLT5pZ25vcmVWQ1MoZmFsc2UpCiAgICAgICAgICAgICAgICAtPmlnbm9yZURvdEZpbGVzKGZhbHNlKQogICAgICAgICAgICAgICAgLT5kZXB0aCgwKQogICAgICAgICAgICAgICAgLT5pbigkZGlyKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRmaW5kZXIgYXMgJHBhdGgpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmUoKHN0cmluZykgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgcmVtb3ZlIGEgZGlyZWN0b3J5CiAgICAgKgogICAgICogVXNlcyB0aGUgcHJvY2VzcyBjb21wb25lbnQgaWYgcHJvY19vcGVuIGlzIGVuYWJsZWQgb24gdGhlIFBIUAogICAgICogaW5zdGFsbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGRpcmVjdG9yeQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVEaXJlY3RvcnkoJGRpcmVjdG9yeSkKICAgIHsKICAgICAgICAkZWRnZUNhc2VSZXN1bHQgPSAkdGhpcy0+cmVtb3ZlRWRnZUNhc2VzKCRkaXJlY3RvcnkpOwogICAgICAgIGlmICgkZWRnZUNhc2VSZXN1bHQgIT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuICRlZGdlQ2FzZVJlc3VsdDsKICAgICAgICB9CgogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgJGNtZCA9IHNwcmludGYoJ3JtZGlyIC9TIC9RICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUocmVhbHBhdGgoJGRpcmVjdG9yeSkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY21kID0gc3ByaW50Zigncm0gLXJmICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGRpcmVjdG9yeSkpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5nZXRQcm9jZXNzKCktPmV4ZWN1dGUoJGNtZCwgJG91dHB1dCkgPT09IDA7CgogICAgICAgIC8vIGNsZWFyIHN0YXQgY2FjaGUgYmVjYXVzZSBleHRlcm5hbCBwcm9jZXNzZXMgYXJlbid0IHRyYWNrZWQgYnkgdGhlIHBocCBzdGF0IGNhY2hlCiAgICAgICAgY2xlYXJzdGF0Y2FjaGUoKTsKCiAgICAgICAgaWYgKCRyZXN1bHQgJiYgIWlzX2RpcigkZGlyZWN0b3J5KSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlRGlyZWN0b3J5UGhwKCRkaXJlY3RvcnkpOwogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgcmVtb3ZlIGEgZGlyZWN0b3J5IGFzeW5jaHJvbm91c2x5CiAgICAgKgogICAgICogVXNlcyB0aGUgcHJvY2VzcyBjb21wb25lbnQgaWYgcHJvY19vcGVuIGlzIGVuYWJsZWQgb24gdGhlIFBIUAogICAgICogaW5zdGFsbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGRpcmVjdG9yeQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVEaXJlY3RvcnlBc3luYygkZGlyZWN0b3J5KQogICAgewogICAgICAgICRlZGdlQ2FzZVJlc3VsdCA9ICR0aGlzLT5yZW1vdmVFZGdlQ2FzZXMoJGRpcmVjdG9yeSk7CiAgICAgICAgaWYgKCRlZGdlQ2FzZVJlc3VsdCAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgkZWRnZUNhc2VSZXN1bHQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAkY21kID0gc3ByaW50Zigncm1kaXIgL1MgL1EgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShyZWFscGF0aCgkZGlyZWN0b3J5KSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjbWQgPSBzcHJpbnRmKCdybSAtcmYgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZGlyZWN0b3J5KSk7CiAgICAgICAgfQoKICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5nZXRQcm9jZXNzKCktPmV4ZWN1dGVBc3luYygkY21kKTsKCiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgkcHJvY2VzcykgdXNlICgkZGlyZWN0b3J5LCAkc2VsZikgewogICAgICAgICAgICAvLyBjbGVhciBzdGF0IGNhY2hlIGJlY2F1c2UgZXh0ZXJuYWwgcHJvY2Vzc2VzIGFyZW4ndCB0cmFja2VkIGJ5IHRoZSBwaHAgc3RhdCBjYWNoZQogICAgICAgICAgICBjbGVhcnN0YXRjYWNoZSgpOwoKICAgICAgICAgICAgaWYgKCRwcm9jZXNzLT5pc1N1Y2Nlc3NmdWwoKSkgewogICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSh0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoJHNlbGYtPnJlbW92ZURpcmVjdG9yeVBocCgkZGlyZWN0b3J5KSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBib29sICAgJGZhbGxiYWNrVG9QaHAKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8bnVsbCBSZXR1cm5zIG51bGwsIHdoZW4gbm8gZWRnZSBjYXNlIHdhcyBoaXQuIE90aGVyd2lzZSBhIGJvb2wgd2hldGhlciByZW1vdmFsIHdhcyBzdWNjZXNzZnVsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVtb3ZlRWRnZUNhc2VzKCRkaXJlY3RvcnksICRmYWxsYmFja1RvUGhwID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlzU3ltbGlua2VkRGlyZWN0b3J5KCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dW5saW5rU3ltbGlua2VkRGlyZWN0b3J5KCRkaXJlY3RvcnkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5pc0p1bmN0aW9uKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlSnVuY3Rpb24oJGRpcmVjdG9yeSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfbGluaygkZGlyZWN0b3J5KSkgewogICAgICAgICAgICByZXR1cm4gdW5saW5rKCRkaXJlY3RvcnkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc19kaXIoJGRpcmVjdG9yeSkgfHwgIWZpbGVfZXhpc3RzKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKD86W2Etel06KT9bL1xcXFxdKyR9aScsICRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQWJvcnRpbmcgYW4gYXR0ZW1wdGVkIGRlbGV0aW9uIG9mICcuJGRpcmVjdG9yeS4nLCB0aGlzIHdhcyBwcm9iYWJseSBub3QgaW50ZW5kZWQsIGlmIGl0IGlzIGEgcmVhbCB1c2UgY2FzZSBwbGVhc2UgcmVwb3J0IGl0LicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcZnVuY3Rpb25fZXhpc3RzKCdwcm9jX29wZW4nKSAmJiAkZmFsbGJhY2tUb1BocCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlbW92ZURpcmVjdG9yeVBocCgkZGlyZWN0b3J5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgZGVsZXRlIGRpcmVjdG9yeSB1c2luZyBQSFAgaXRlcmF0b3JzLgogICAgICoKICAgICAqIFVzZXMgYSBDSElMRF9GSVJTVCBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yIHRvIHNvcnQgZmlsZXMKICAgICAqIGJlZm9yZSBkaXJlY3RvcmllcywgY3JlYXRpbmcgYSBzaW5nbGUgbm9uLXJlY3Vyc2l2ZSBsb29wCiAgICAgKiB0byBkZWxldGUgZmlsZXMvZGlyZWN0b3JpZXMgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGRpcmVjdG9yeQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVEaXJlY3RvcnlQaHAoJGRpcmVjdG9yeSkKICAgIHsKICAgICAgICAkZWRnZUNhc2VSZXN1bHQgPSAkdGhpcy0+cmVtb3ZlRWRnZUNhc2VzKCRkaXJlY3RvcnksIGZhbHNlKTsKICAgICAgICBpZiAoJGVkZ2VDYXNlUmVzdWx0ICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkZWRnZUNhc2VSZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICAkaXQgPSBuZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJGRpcmVjdG9yeSwgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlNLSVBfRE9UUyk7CiAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAvLyByZS10cnkgb25jZSBhZnRlciBjbGVhcmluZyB0aGUgc3RhdCBjYWNoZSBpZiBpdCBmYWlsZWQgYXMgaXQKICAgICAgICAgICAgLy8gc29tZXRpbWVzIGZhaWxzIHdpdGhvdXQgYXBwYXJlbnQgcmVhc29uLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy80MDA5CiAgICAgICAgICAgIGNsZWFyc3RhdGNhY2hlKCk7CiAgICAgICAgICAgIHVzbGVlcCgxMDAwMDApOwogICAgICAgICAgICBpZiAoIWlzX2RpcigkZGlyZWN0b3J5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGl0ID0gbmV3IFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKCRkaXJlY3RvcnksIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMpOwogICAgICAgIH0KICAgICAgICAkcmkgPSBuZXcgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigkaXQsIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OkNISUxEX0ZJUlNUKTsKCiAgICAgICAgZm9yZWFjaCAoJHJpIGFzICRmaWxlKSB7CiAgICAgICAgICAgIGlmICgkZmlsZS0+aXNEaXIoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJtZGlyKCRmaWxlLT5nZXRQYXRobmFtZSgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT51bmxpbmsoJGZpbGUtPmdldFBhdGhuYW1lKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZWxlYXNlIGxvY2tzIG9uIHRoZSBkaXJlY3RvcnksIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzk5NDUKICAgICAgICB1bnNldCgkcmksICRpdCwgJGZpbGUpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnJtZGlyKCRkaXJlY3RvcnkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZGlyZWN0b3J5CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbnN1cmVEaXJlY3RvcnlFeGlzdHMoJGRpcmVjdG9yeSkKICAgIHsKICAgICAgICBpZiAoIWlzX2RpcigkZGlyZWN0b3J5KSkgewogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAkZGlyZWN0b3J5LicgZXhpc3RzIGFuZCBpcyBub3QgYSBkaXJlY3RvcnkuJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIUBta2RpcigkZGlyZWN0b3J5LCAwNzc3LCB0cnVlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICRkaXJlY3RvcnkuJyBkb2VzIG5vdCBleGlzdCBhbmQgY291bGQgbm90IGJlIGNyZWF0ZWQuJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEF0dGVtcHRzIHRvIHVubGluayBhIGZpbGUgYW5kIGluIGNhc2Ugb2YgZmFpbHVyZSByZXRyaWVzIGFmdGVyIDM1MG1zIG9uIHdpbmRvd3MKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwYXRoCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVubGluaygkcGF0aCkKICAgIHsKICAgICAgICAkdW5saW5rZWQgPSBAJHRoaXMtPnVubGlua0ltcGxlbWVudGF0aW9uKCRwYXRoKTsKICAgICAgICBpZiAoISR1bmxpbmtlZCkgewogICAgICAgICAgICAvLyByZXRyeSBhZnRlciBhIGJpdCBvbiB3aW5kb3dzIHNpbmNlIGl0IHRlbmRzIHRvIGJlIHRvdWNoeSB3aXRoIG1hc3MgcmVtb3ZhbHMKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgdXNsZWVwKDM1MDAwMCk7CiAgICAgICAgICAgICAgICAkdW5saW5rZWQgPSBAJHRoaXMtPnVubGlua0ltcGxlbWVudGF0aW9uKCRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkdW5saW5rZWQpIHsKICAgICAgICAgICAgICAgICRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDb3VsZCBub3QgZGVsZXRlICcuJHBhdGguJzogJyAuIEAkZXJyb3JbJ21lc3NhZ2UnXTsKICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiXG5UaGlzIGNhbiBiZSBkdWUgdG8gYW4gYW50aXZpcnVzIG9yIHRoZSBXaW5kb3dzIFNlYXJjaCBJbmRleGVyIGxvY2tpbmcgdGhlIGZpbGUgd2hpbGUgdGhleSBhcmUgYW5hbHl6ZWQiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkbWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQXR0ZW1wdHMgdG8gcm1kaXIgYSBmaWxlIGFuZCBpbiBjYXNlIG9mIGZhaWx1cmUgcmV0cmllcyBhZnRlciAzNTBtcyBvbiB3aW5kb3dzCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkcGF0aAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBybWRpcigkcGF0aCkKICAgIHsKICAgICAgICAkZGVsZXRlZCA9IEBybWRpcigkcGF0aCk7CiAgICAgICAgaWYgKCEkZGVsZXRlZCkgewogICAgICAgICAgICAvLyByZXRyeSBhZnRlciBhIGJpdCBvbiB3aW5kb3dzIHNpbmNlIGl0IHRlbmRzIHRvIGJlIHRvdWNoeSB3aXRoIG1hc3MgcmVtb3ZhbHMKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgdXNsZWVwKDM1MDAwMCk7CiAgICAgICAgICAgICAgICAkZGVsZXRlZCA9IEBybWRpcigkcGF0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGRlbGV0ZWQpIHsKICAgICAgICAgICAgICAgICRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDb3VsZCBub3QgZGVsZXRlICcuJHBhdGguJzogJyAuIEAkZXJyb3JbJ21lc3NhZ2UnXTsKICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiXG5UaGlzIGNhbiBiZSBkdWUgdG8gYW4gYW50aXZpcnVzIG9yIHRoZSBXaW5kb3dzIFNlYXJjaCBJbmRleGVyIGxvY2tpbmcgdGhlIGZpbGUgd2hpbGUgdGhleSBhcmUgYW5hbHl6ZWQiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkbWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQ29weSB0aGVuIGRlbGV0ZSBpcyBhIG5vbi1hdG9taWMgdmVyc2lvbiBvZiB7QGxpbmsgcmVuYW1lfS4KICAgICAqCiAgICAgKiBTb21lIHN5c3RlbXMgY2FuJ3QgcmVuYW1lIGFuZCBhbHNvIGRvbid0IGhhdmUgcHJvY19vcGVuLAogICAgICogd2hpY2ggcmVxdWlyZXMgdGhpcyBzb2x1dGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29weVRoZW5SZW1vdmUoJHNvdXJjZSwgJHRhcmdldCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29weSgkc291cmNlLCAkdGFyZ2V0KTsKICAgICAgICBpZiAoIWlzX2Rpcigkc291cmNlKSkgewogICAgICAgICAgICAkdGhpcy0+dW5saW5rKCRzb3VyY2UpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJlbW92ZURpcmVjdG9yeVBocCgkc291cmNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvcGllcyBhIGZpbGUgb3IgZGlyZWN0b3J5IGZyb20gJHNvdXJjZSB0byAkdGFyZ2V0LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzb3VyY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICR0YXJnZXQKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29weSgkc291cmNlLCAkdGFyZ2V0KQogICAgewogICAgICAgIGlmICghaXNfZGlyKCRzb3VyY2UpKSB7CiAgICAgICAgICAgIHJldHVybiBjb3B5KCRzb3VyY2UsICR0YXJnZXQpOwogICAgICAgIH0KCiAgICAgICAgJGl0ID0gbmV3IFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKCRzb3VyY2UsIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMpOwogICAgICAgICRyaSA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKCRpdCwgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjo6U0VMRl9GSVJTVCk7CiAgICAgICAgJHRoaXMtPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGFyZ2V0KTsKCiAgICAgICAgJHJlc3VsdCA9IHRydWU7CiAgICAgICAgLyoqIEB2YXIgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IgJHJpICovCiAgICAgICAgZm9yZWFjaCAoJHJpIGFzICRmaWxlKSB7CiAgICAgICAgICAgICR0YXJnZXRQYXRoID0gJHRhcmdldCAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkcmktPmdldFN1YlBhdGhuYW1lKCk7CiAgICAgICAgICAgIGlmICgkZmlsZS0+aXNEaXIoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGFyZ2V0UGF0aCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHJlc3VsdCAmJiBjb3B5KCRmaWxlLT5nZXRQYXRobmFtZSgpLCAkdGFyZ2V0UGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmFtZSgkc291cmNlLCAkdGFyZ2V0KQogICAgewogICAgICAgIGlmICh0cnVlID09PSBAcmVuYW1lKCRzb3VyY2UsICR0YXJnZXQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghXGZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgJHRoaXMtPmNvcHlUaGVuUmVtb3ZlKCRzb3VyY2UsICR0YXJnZXQpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAvLyBUcnkgdG8gY29weSAmIGRlbGV0ZSAtIHRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciByYW5kb20gIkFjY2VzcyBkZW5pZWQiIGVycm9ycy4KICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCd4Y29weSAlcyAlcyAvRSAvSSAvUSAvWScsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRzb3VyY2UpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdGFyZ2V0KSk7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Z2V0UHJvY2VzcygpLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0KTsKCiAgICAgICAgICAgIC8vIGNsZWFyIHN0YXQgY2FjaGUgYmVjYXVzZSBleHRlcm5hbCBwcm9jZXNzZXMgYXJlbid0IHRyYWNrZWQgYnkgdGhlIHBocCBzdGF0IGNhY2hlCiAgICAgICAgICAgIGNsZWFyc3RhdGNhY2hlKCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgkc291cmNlKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBXZSBkbyBub3QgdXNlIFBIUCdzICJyZW5hbWUiIGZ1bmN0aW9uIGhlcmUgc2luY2UgaXQgZG9lcyBub3Qgc3VwcG9ydAogICAgICAgICAgICAvLyB0aGUgY2FzZSB3aGVyZSAkc291cmNlLCBhbmQgJHRhcmdldCBhcmUgbG9jYXRlZCBvbiBkaWZmZXJlbnQgcGFydGl0aW9ucy4KICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdtdiAlcyAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRzb3VyY2UpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdGFyZ2V0KSk7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Z2V0UHJvY2VzcygpLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0KTsKCiAgICAgICAgICAgIC8vIGNsZWFyIHN0YXQgY2FjaGUgYmVjYXVzZSBleHRlcm5hbCBwcm9jZXNzZXMgYXJlbid0IHRyYWNrZWQgYnkgdGhlIHBocCBzdGF0IGNhY2hlCiAgICAgICAgICAgIGNsZWFyc3RhdGNhY2hlKCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29weVRoZW5SZW1vdmUoJHNvdXJjZSwgJHRhcmdldCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzaG9ydGVzdCBwYXRoIGZyb20gJGZyb20gdG8gJHRvCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRmcm9tCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJHRvCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAgJGRpcmVjdG9yaWVzIGlmIHRydWUsIHRoZSBzb3VyY2UvdGFyZ2V0IGFyZSBjb25zaWRlcmVkIHRvIGJlIGRpcmVjdG9yaWVzCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kU2hvcnRlc3RQYXRoKCRmcm9tLCAkdG8sICRkaXJlY3RvcmllcyA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlzQWJzb2x1dGVQYXRoKCRmcm9tKSB8fCAhJHRoaXMtPmlzQWJzb2x1dGVQYXRoKCR0bykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignJGZyb20gKCVzKSBhbmQgJHRvICglcykgbXVzdCBiZSBhYnNvbHV0ZSBwYXRocy4nLCAkZnJvbSwgJHRvKSk7CiAgICAgICAgfQoKICAgICAgICAkZnJvbSA9IGxjZmlyc3QoJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJGZyb20pKTsKICAgICAgICAkdG8gPSBsY2ZpcnN0KCR0aGlzLT5ub3JtYWxpemVQYXRoKCR0bykpOwoKICAgICAgICBpZiAoJGRpcmVjdG9yaWVzKSB7CiAgICAgICAgICAgICRmcm9tID0gcnRyaW0oJGZyb20sICcvJykgLiAnL2R1bW15X2ZpbGUnOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxkaXJuYW1lKCRmcm9tKSA9PT0gXGRpcm5hbWUoJHRvKSkgewogICAgICAgICAgICByZXR1cm4gJy4vJy5iYXNlbmFtZSgkdG8pOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vblBhdGggPSAkdG87CiAgICAgICAgd2hpbGUgKHN0cnBvcygkZnJvbS4nLycsICRjb21tb25QYXRoLicvJykgIT09IDAgJiYgJy8nICE9PSAkY29tbW9uUGF0aCAmJiAhUHJlZzo6aXNNYXRjaCgne15bYS16XTovPyR9aScsICRjb21tb25QYXRoKSkgewogICAgICAgICAgICAkY29tbW9uUGF0aCA9IHN0cnRyKFxkaXJuYW1lKCRjb21tb25QYXRoKSwgJ1xcJywgJy8nKTsKICAgICAgICB9CgogICAgICAgIGlmICgwICE9PSBzdHJwb3MoJGZyb20sICRjb21tb25QYXRoKSB8fCAnLycgPT09ICRjb21tb25QYXRoKSB7CiAgICAgICAgICAgIHJldHVybiAkdG87CiAgICAgICAgfQoKICAgICAgICAkY29tbW9uUGF0aCA9IHJ0cmltKCRjb21tb25QYXRoLCAnLycpIC4gJy8nOwogICAgICAgICRzb3VyY2VQYXRoRGVwdGggPSBzdWJzdHJfY291bnQoc3Vic3RyKCRmcm9tLCBcc3RybGVuKCRjb21tb25QYXRoKSksICcvJyk7CiAgICAgICAgJGNvbW1vblBhdGhDb2RlID0gc3RyX3JlcGVhdCgnLi4vJywgJHNvdXJjZVBhdGhEZXB0aCk7CgogICAgICAgIHJldHVybiAoJGNvbW1vblBhdGhDb2RlIC4gc3Vic3RyKCR0bywgXHN0cmxlbigkY29tbW9uUGF0aCkpKSA/OiAnLi8nOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBQSFAgY29kZSB0aGF0LCB3aGVuIGV4ZWN1dGVkIGluICRmcm9tLCB3aWxsIHJldHVybiB0aGUgcGF0aCB0byAkdG8KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJGZyb20KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkdG8KICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAkZGlyZWN0b3JpZXMgaWYgdHJ1ZSwgdGhlIHNvdXJjZS90YXJnZXQgYXJlIGNvbnNpZGVyZWQgdG8gYmUgZGlyZWN0b3JpZXMKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAkc3RhdGljQ29kZQogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFNob3J0ZXN0UGF0aENvZGUoJGZyb20sICR0bywgJGRpcmVjdG9yaWVzID0gZmFsc2UsICRzdGF0aWNDb2RlID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aXNBYnNvbHV0ZVBhdGgoJGZyb20pIHx8ICEkdGhpcy0+aXNBYnNvbHV0ZVBhdGgoJHRvKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCckZnJvbSAoJXMpIGFuZCAkdG8gKCVzKSBtdXN0IGJlIGFic29sdXRlIHBhdGhzLicsICRmcm9tLCAkdG8pKTsKICAgICAgICB9CgogICAgICAgICRmcm9tID0gbGNmaXJzdCgkdGhpcy0+bm9ybWFsaXplUGF0aCgkZnJvbSkpOwogICAgICAgICR0byA9IGxjZmlyc3QoJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHRvKSk7CgogICAgICAgIGlmICgkZnJvbSA9PT0gJHRvKSB7CiAgICAgICAgICAgIHJldHVybiAkZGlyZWN0b3JpZXMgPyAnX19ESVJfXycgOiAnX19GSUxFX18nOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vblBhdGggPSAkdG87CiAgICAgICAgd2hpbGUgKHN0cnBvcygkZnJvbS4nLycsICRjb21tb25QYXRoLicvJykgIT09IDAgJiYgJy8nICE9PSAkY29tbW9uUGF0aCAmJiAhUHJlZzo6aXNNYXRjaCgne15bYS16XTovPyR9aScsICRjb21tb25QYXRoKSAmJiAnLicgIT09ICRjb21tb25QYXRoKSB7CiAgICAgICAgICAgICRjb21tb25QYXRoID0gc3RydHIoXGRpcm5hbWUoJGNvbW1vblBhdGgpLCAnXFwnLCAnLycpOwogICAgICAgIH0KCiAgICAgICAgaWYgKDAgIT09IHN0cnBvcygkZnJvbSwgJGNvbW1vblBhdGgpIHx8ICcvJyA9PT0gJGNvbW1vblBhdGggfHwgJy4nID09PSAkY29tbW9uUGF0aCkgewogICAgICAgICAgICByZXR1cm4gdmFyX2V4cG9ydCgkdG8sIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vblBhdGggPSBydHJpbSgkY29tbW9uUGF0aCwgJy8nKSAuICcvJzsKICAgICAgICBpZiAoc3RycG9zKCR0bywgJGZyb20uJy8nKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gJ19fRElSX18gLiAnLnZhcl9leHBvcnQoc3Vic3RyKCR0bywgXHN0cmxlbigkZnJvbSkpLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgJHNvdXJjZVBhdGhEZXB0aCA9IHN1YnN0cl9jb3VudChzdWJzdHIoJGZyb20sIFxzdHJsZW4oJGNvbW1vblBhdGgpKSwgJy8nKSArICRkaXJlY3RvcmllczsKICAgICAgICBpZiAoJHN0YXRpY0NvZGUpIHsKICAgICAgICAgICAgJGNvbW1vblBhdGhDb2RlID0gIl9fRElSX18gLiAnIi5zdHJfcmVwZWF0KCcvLi4nLCAkc291cmNlUGF0aERlcHRoKS4iJyI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNvbW1vblBhdGhDb2RlID0gc3RyX3JlcGVhdCgnZGlybmFtZSgnLCAkc291cmNlUGF0aERlcHRoKS4nX19ESVJfXycuc3RyX3JlcGVhdCgnKScsICRzb3VyY2VQYXRoRGVwdGgpOwogICAgICAgIH0KICAgICAgICAkcmVsVGFyZ2V0ID0gc3Vic3RyKCR0bywgXHN0cmxlbigkY29tbW9uUGF0aCkpOwoKICAgICAgICByZXR1cm4gJGNvbW1vblBhdGhDb2RlIC4gKFxzdHJsZW4oJHJlbFRhcmdldCkgPyAnLicgLiB2YXJfZXhwb3J0KCcvJyAuICRyZWxUYXJnZXQsIHRydWUpIDogJycpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBwYXRoIGlzIGFic29sdXRlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBYnNvbHV0ZVBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuIHN0cnBvcygkcGF0aCwgJy8nKSA9PT0gMCB8fCBzdWJzdHIoJHBhdGgsIDEsIDEpID09PSAnOicgfHwgc3RycG9zKCRwYXRoLCAnXFxcXCcpID09PSAwOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBzaXplIG9mIGEgZmlsZSBvciBkaXJlY3Rvcnkgc3BlY2lmaWVkIGJ5IHBhdGguIElmIGEgZGlyZWN0b3J5IGlzCiAgICAgKiBnaXZlbiwgaXRzIHNpemUgd2lsbCBiZSBjb21wdXRlZCByZWN1cnNpdmVseS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwYXRoIFBhdGggdG8gdGhlIGZpbGUgb3IgZGlyZWN0b3J5CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2l6ZSgkcGF0aCkKICAgIHsKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIiRwYXRoIGRvZXMgbm90IGV4aXN0LiIpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNfZGlyKCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRpcmVjdG9yeVNpemUoJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZpbGVzaXplKCRwYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZSBhIHBhdGguIFRoaXMgcmVwbGFjZXMgYmFja3NsYXNoZXMgd2l0aCBzbGFzaGVzLCByZW1vdmVzIGVuZGluZwogICAgICogc2xhc2ggYW5kIGNvbGxhcHNlcyByZWR1bmRhbnQgc2VwYXJhdG9ycyBhbmQgdXAtbGV2ZWwgcmVmZXJlbmNlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aCBQYXRoIHRvIHRoZSBmaWxlIG9yIGRpcmVjdG9yeQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vcm1hbGl6ZVBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgJHBhcnRzID0gYXJyYXkoKTsKICAgICAgICAkcGF0aCA9IHN0cnRyKCRwYXRoLCAnXFwnLCAnLycpOwogICAgICAgICRwcmVmaXggPSAnJzsKICAgICAgICAkYWJzb2x1dGUgPSAnJzsKCiAgICAgICAgLy8gZXh0cmFjdCB3aW5kb3dzIFVOQyBwYXRocyBlLmcuIFxcZm9vXGJhcgogICAgICAgIGlmIChzdHJwb3MoJHBhdGgsICcvLycpID09PSAwICYmIFxzdHJsZW4oJHBhdGgpID4gMikgewogICAgICAgICAgICAkYWJzb2x1dGUgPSAnLy8nOwogICAgICAgICAgICAkcGF0aCA9IHN1YnN0cigkcGF0aCwgMik7CiAgICAgICAgfQoKICAgICAgICAvLyBleHRyYWN0IGEgcHJlZml4IGJlaW5nIGEgcHJvdG9jb2w6Ly8sIHByb3RvY29sOiwgcHJvdG9jb2w6Ly9kcml2ZTogb3Igc2ltcGx5IGRyaXZlOgogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XiggWzAtOWEtel17Mix9KzogKD86IC8vICg/OiBbYS16XTogKT8gKT8gfCBbYS16XTogKX1peCcsICRwYXRoLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICRwcmVmaXggPSAkbWF0Y2hbMV07CiAgICAgICAgICAgICRwYXRoID0gc3Vic3RyKCRwYXRoLCBcc3RybGVuKCRwcmVmaXgpKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJHBhdGgsICcvJykgPT09IDApIHsKICAgICAgICAgICAgJGFic29sdXRlID0gJy8nOwogICAgICAgICAgICAkcGF0aCA9IHN1YnN0cigkcGF0aCwgMSk7CiAgICAgICAgfQoKICAgICAgICAkdXAgPSBmYWxzZTsKICAgICAgICBmb3JlYWNoIChleHBsb2RlKCcvJywgJHBhdGgpIGFzICRjaHVuaykgewogICAgICAgICAgICBpZiAoJy4uJyA9PT0gJGNodW5rICYmICgkYWJzb2x1dGUgIT09ICcnIHx8ICR1cCkpIHsKICAgICAgICAgICAgICAgIGFycmF5X3BvcCgkcGFydHMpOwogICAgICAgICAgICAgICAgJHVwID0gIShlbXB0eSgkcGFydHMpIHx8ICcuLicgPT09IGVuZCgkcGFydHMpKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCcuJyAhPT0gJGNodW5rICYmICcnICE9PSAkY2h1bmspIHsKICAgICAgICAgICAgICAgICRwYXJ0c1tdID0gJGNodW5rOwogICAgICAgICAgICAgICAgJHVwID0gJy4uJyAhPT0gJGNodW5rOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByZWZpeC4oKHN0cmluZykgJGFic29sdXRlKS5pbXBsb2RlKCcvJywgJHBhcnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZSB0cmFpbGluZyBzbGFzaGVzIGlmIHByZXNlbnQgdG8gYXZvaWQgaXNzdWVzIHdpdGggc3ltbGlua3MKICAgICAqCiAgICAgKiBBbmQgb3RoZXIgcG9zc2libGUgdW5mb3Jlc2VlbiBkaXNhc3RlcnMsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC85NDIyCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdHJpbVRyYWlsaW5nU2xhc2goJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7XlsvXFxcXF0rJH0nLCAkcGF0aCkpIHsKICAgICAgICAgICAgJHBhdGggPSBydHJpbSgkcGF0aCwgJy9cXCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYXRoOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGlmIHRoZSBnaXZlbiBwYXRoIGlzIGxvY2FsCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzTG9jYWxQYXRoKCRwYXRoKQogICAgewogICAgICAgIHJldHVybiBQcmVnOjppc01hdGNoKCd7XihmaWxlOi8vKD8hLy8pfC8oPyEvKXwvP1thLXpdOltcXFxcL118XC5cLltcXFxcL118W2EtejAtOV8uLV0rW1xcXFwvXSl9aScsICRwYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBsYXRmb3JtUGF0aCgkcGF0aCkKICAgIHsKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICRwYXRoID0gUHJlZzo6cmVwbGFjZSgne14oPzpmaWxlOi8vLyhbYS16XSk6Py8pfWknLCAnZmlsZTovLyQxOi8nLCAkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKHN0cmluZykgUHJlZzo6cmVwbGFjZSgne15maWxlOi8vfWknLCAnJywgJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogQ3Jvc3MtcGxhdGZvcm0gc2FmZSB2ZXJzaW9uIG9mIGlzX3JlYWRhYmxlKCkKICAgICAqCiAgICAgKiBUaGlzIHdpbGwgYWxzbyBjaGVjayBmb3IgcmVhZGFiaWxpdHkgYnkgcmVhZGluZyB0aGUgZmlsZSBhcyBpc19yZWFkYWJsZSBjYW4gbm90IGJlIHRydXN0ZWQgb24gbmV0d29yay1tb3VudHMKICAgICAqIGFuZCBcXHdzbCQgcGF0aHMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzgyMzEgYW5kIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9Njg5MjYKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNSZWFkYWJsZSgkcGF0aCkKICAgIHsKICAgICAgICBpZiAoaXNfcmVhZGFibGUoJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX2ZpbGUoJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZSAhPT0gU2lsZW5jZXI6OmNhbGwoJ2ZpbGVfZ2V0X2NvbnRlbnRzJywgJHBhdGgsIGZhbHNlLCBudWxsLCAwLCAxKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc19kaXIoJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZSAhPT0gU2lsZW5jZXI6OmNhbGwoJ29wZW5kaXInLCAkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICAvLyBhc3N1bWUgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZGlyZWN0b3J5CiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRpcmVjdG9yeVNpemUoJGRpcmVjdG9yeSkKICAgIHsKICAgICAgICAkaXQgPSBuZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJGRpcmVjdG9yeSwgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlNLSVBfRE9UUyk7CiAgICAgICAgJHJpID0gbmV3IFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IoJGl0LCBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yOjpDSElMRF9GSVJTVCk7CgogICAgICAgICRzaXplID0gMDsKICAgICAgICBmb3JlYWNoICgkcmkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKCRmaWxlLT5pc0ZpbGUoKSkgewogICAgICAgICAgICAgICAgJHNpemUgKz0gJGZpbGUtPmdldFNpemUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzaXplOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQcm9jZXNzRXhlY3V0b3IKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFByb2Nlc3MoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnByb2Nlc3NFeGVjdXRvcikgewogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yID0gbmV3IFByb2Nlc3NFeGVjdXRvcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzRXhlY3V0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBkZWxldGUgc3ltYm9saWMgbGluayBpbXBsZW1lbnRhdGlvbiAoY29tbW9ubHkga25vd24gYXMgInVubGluaygpIikKICAgICAqCiAgICAgKiBzeW1ib2xpYyBsaW5rcyBvbiB3aW5kb3dzIHdoaWNoIGxpbmsgdG8gZGlyZWN0b3JpZXMgbmVlZCBybWRpciBpbnN0ZWFkIG9mIHVubGluawogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1bmxpbmtJbXBsZW1lbnRhdGlvbigkcGF0aCkKICAgIHsKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpICYmIGlzX2RpcigkcGF0aCkgJiYgaXNfbGluaygkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIHJtZGlyKCRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB1bmxpbmsoJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHJlbGF0aXZlIHN5bWxpbmsgZnJvbSAkbGluayB0byAkdGFyZ2V0CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHRhcmdldCBUaGUgcGF0aCBvZiB0aGUgYmluYXJ5IGZpbGUgdG8gYmUgc3ltbGlua2VkCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbGluayAgIFRoZSBwYXRoIHdoZXJlIHRoZSBzeW1saW5rIHNob3VsZCBiZSBjcmVhdGVkCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbGF0aXZlU3ltbGluaygkdGFyZ2V0LCAkbGluaykKICAgIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygnc3ltbGluaycpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjd2QgPSBnZXRjd2QoKTsKCiAgICAgICAgJHJlbGF0aXZlUGF0aCA9ICR0aGlzLT5maW5kU2hvcnRlc3RQYXRoKCRsaW5rLCAkdGFyZ2V0KTsKICAgICAgICBjaGRpcihcZGlybmFtZSgkbGluaykpOwogICAgICAgICRyZXN1bHQgPSBAc3ltbGluaygkcmVsYXRpdmVQYXRoLCAkbGluayk7CgogICAgICAgIGNoZGlyKCRjd2QpOwoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIHJldHVybiB0cnVlIGlmIHRoYXQgZGlyZWN0b3J5IGlzIGEgc3ltbGluay4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU3ltbGlua2VkRGlyZWN0b3J5KCRkaXJlY3RvcnkpCiAgICB7CiAgICAgICAgaWYgKCFpc19kaXIoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHJlc29sdmVkID0gJHRoaXMtPnJlc29sdmVTeW1saW5rZWREaXJlY3RvcnlTeW1saW5rKCRkaXJlY3RvcnkpOwoKICAgICAgICByZXR1cm4gaXNfbGluaygkcmVzb2x2ZWQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZGlyZWN0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdW5saW5rU3ltbGlua2VkRGlyZWN0b3J5KCRkaXJlY3RvcnkpCiAgICB7CiAgICAgICAgJHJlc29sdmVkID0gJHRoaXMtPnJlc29sdmVTeW1saW5rZWREaXJlY3RvcnlTeW1saW5rKCRkaXJlY3RvcnkpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnVubGluaygkcmVzb2x2ZWQpOwogICAgfQoKICAgIC8qKgogICAgICogcmVzb2x2ZSBwYXRobmFtZSB0byBzeW1ib2xpYyBsaW5rIG9mIGEgZGlyZWN0b3J5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aG5hbWUgZGlyZWN0b3J5IHBhdGggdG8gcmVzb2x2ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHJlc29sdmVkIHBhdGggdG8gc3ltYm9saWMgbGluayBvciBvcmlnaW5hbCBwYXRobmFtZSAodW5yZXNvbHZlZCkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXNvbHZlU3ltbGlua2VkRGlyZWN0b3J5U3ltbGluaygkcGF0aG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFpc19kaXIoJHBhdGhuYW1lKSkgewogICAgICAgICAgICByZXR1cm4gJHBhdGhuYW1lOwogICAgICAgIH0KCiAgICAgICAgJHJlc29sdmVkID0gcnRyaW0oJHBhdGhuYW1lLCAnLycpOwoKICAgICAgICBpZiAoIVxzdHJsZW4oJHJlc29sdmVkKSkgewogICAgICAgICAgICByZXR1cm4gJHBhdGhuYW1lOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXNvbHZlZDsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gTlRGUyBqdW5jdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGp1bmN0aW9uCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBqdW5jdGlvbigkdGFyZ2V0LCAkanVuY3Rpb24pCiAgICB7CiAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdGdW5jdGlvbiAlcyBpcyBub3QgYXZhaWxhYmxlIG9uIG5vbi1XaW5kb3dzIHBsYXRmb3JtJywgX19DTEFTU19fKSk7CiAgICAgICAgfQogICAgICAgIGlmICghaXNfZGlyKCR0YXJnZXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdDYW5ub3QganVuY3Rpb24gdG8gIiVzIiBhcyBpdCBpcyBub3QgYSBkaXJlY3RvcnkuJywgJHRhcmdldCksIDAsIG51bGwsICR0YXJnZXQpOwogICAgICAgIH0KICAgICAgICAkY21kID0gc3ByaW50ZigKICAgICAgICAgICAgJ21rbGluayAvSiAlcyAlcycsCiAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKHN0cl9yZXBsYWNlKCcvJywgRElSRUNUT1JZX1NFUEFSQVRPUiwgJGp1bmN0aW9uKSksCiAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKHJlYWxwYXRoKCR0YXJnZXQpKQogICAgICAgICk7CiAgICAgICAgaWYgKCR0aGlzLT5nZXRQcm9jZXNzKCktPmV4ZWN1dGUoJGNtZCwgJG91dHB1dCkgIT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjcmVhdGUganVuY3Rpb24gdG8gIiVzIiBhdCAiJXMiLicsICR0YXJnZXQsICRqdW5jdGlvbiksIDAsIG51bGwsICR0YXJnZXQpOwogICAgICAgIH0KICAgICAgICBjbGVhcnN0YXRjYWNoZSh0cnVlLCAkanVuY3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSB0YXJnZXQgZGlyZWN0b3J5IGlzIGEgV2luZG93cyBOVEZTIEp1bmN0aW9uLgogICAgICoKICAgICAqIFdlIHRlc3QgaWYgdGhlIHBhdGggaXMgYSBkaXJlY3RvcnkgYW5kIG5vdCBhbiBvcmRpbmFyeSBsaW5rLCB0aGVuIGNoZWNrCiAgICAgKiB0aGF0IHRoZSBtb2RlIHZhbHVlIHJldHVybmVkIGZyb20gbHN0YXQgKHdoaWNoIGdpdmVzIHRoZSBzdGF0dXMgb2YgdGhlCiAgICAgKiBsaW5rIGl0c2VsZikgaXMgbm90IGEgZGlyZWN0b3J5LCBieSByZXBsaWNhdGluZyB0aGUgUE9TSVggU19JU0RJUiB0ZXN0LgogICAgICoKICAgICAqIFRoaXMgbG9naWMgd29ya3MgYmVjYXVzZSBQSFAgZG9lcyBub3Qgc2V0IHRoZSBtb2RlIHZhbHVlIGZvciBhIGp1bmN0aW9uLAogICAgICogc2luY2UgdGhlcmUgaXMgbm8gdW5pdmVyc2FsIGZpbGUgdHlwZSBmbGFnIGZvciBpdC4gVW5mb3J0dW5hdGVseSBhbgogICAgICogdW5pbml0aWFsaXplZCB2YXJpYWJsZSBpbiBQSFAgcHJpb3IgdG8gNy4yLjE2IGFuZCA3LjMuMyBtYXkgY2F1c2UgYQogICAgICogcmFuZG9tIHZhbHVlIHRvIGJlIHJldHVybmVkLiBTZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD03NzU1MgogICAgICoKICAgICAqIElmIHRoaXMgcmFuZG9tIHZhbHVlIHBhc3NlcyB0aGUgU19JU0RJUiB0ZXN0LCB0aGVuIGEganVuY3Rpb24gd2lsbCBub3QgYmUKICAgICAqIGRldGVjdGVkIGFuZCBhIHJlY3Vyc2l2ZSBkZWxldGUgb3BlcmF0aW9uIGNvdWxkIGxlYWQgdG8gbG9zcyBvZiBkYXRhIGluCiAgICAgKiB0aGUgdGFyZ2V0IGRpcmVjdG9yeS4gTm90ZSB0aGF0IFdpbmRvd3Mgcm1kaXIgY2FuIGhhbmRsZSB0aGlzIHNpdHVhdGlvbgogICAgICogYW5kIHdpbGwgb25seSBkZWxldGUgdGhlIGp1bmN0aW9uIChmcm9tIFdpbmRvd3MgNyBvbndhcmRzKS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkanVuY3Rpb24gUGF0aCB0byBjaGVjay4KICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNKdW5jdGlvbigkanVuY3Rpb24pCiAgICB7CiAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gSW1wb3J0YW50IHRvIGNsZWFyIGFsbCBjYWNoZXMgZmlyc3QKICAgICAgICBjbGVhcnN0YXRjYWNoZSh0cnVlLCAkanVuY3Rpb24pOwoKICAgICAgICBpZiAoIWlzX2RpcigkanVuY3Rpb24pIHx8IGlzX2xpbmsoJGp1bmN0aW9uKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkc3RhdCA9IGxzdGF0KCRqdW5jdGlvbik7CgogICAgICAgIC8vIFNfSVNESVIgdGVzdCAoU19JRkRJUiBpcyAweDQwMDAsIFNfSUZNVCBpcyAweEYwMDAgYml0bWFzaykKICAgICAgICByZXR1cm4gJHN0YXQgPyAweDQwMDAgIT09ICgkc3RhdFsnbW9kZSddICYgMHhGMDAwKSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhIFdpbmRvd3MgTlRGUyBqdW5jdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkanVuY3Rpb24KICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlSnVuY3Rpb24oJGp1bmN0aW9uKQogICAgewogICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgJGp1bmN0aW9uID0gcnRyaW0oc3RyX3JlcGxhY2UoJy8nLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkanVuY3Rpb24pLCBESVJFQ1RPUllfU0VQQVJBVE9SKTsKICAgICAgICBpZiAoISR0aGlzLT5pc0p1bmN0aW9uKCRqdW5jdGlvbikpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJyVzIGlzIG5vdCBhIGp1bmN0aW9uIGFuZCB0aHVzIGNhbm5vdCBiZSByZW1vdmVkIGFzIG9uZScsICRqdW5jdGlvbikpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5ybWRpcigkanVuY3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudAogICAgICoKICAgICAqIEByZXR1cm4gaW50fGZhbHNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCRwYXRoLCAkY29udGVudCkKICAgIHsKICAgICAgICAkY3VycmVudENvbnRlbnQgPSBAZmlsZV9nZXRfY29udGVudHMoJHBhdGgpOwogICAgICAgIGlmICghJGN1cnJlbnRDb250ZW50IHx8ICgkY3VycmVudENvbnRlbnQgIT0gJGNvbnRlbnQpKSB7CiAgICAgICAgICAgIHJldHVybiBmaWxlX3B1dF9jb250ZW50cygkcGF0aCwgJGNvbnRlbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3B5IGZpbGUgdXNpbmcgc3RyZWFtX2NvcHlfdG9fc3RyZWFtIHRvIHdvcmsgYXJvdW5kIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NjQ2MwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZQogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzYWZlQ29weSgkc291cmNlLCAkdGFyZ2V0KQogICAgewogICAgICAgIGlmICghZmlsZV9leGlzdHMoJHRhcmdldCkgfHwgIWZpbGVfZXhpc3RzKCRzb3VyY2UpIHx8ICEkdGhpcy0+ZmlsZXNBcmVFcXVhbCgkc291cmNlLCAkdGFyZ2V0KSkgewogICAgICAgICAgICAkc291cmNlID0gZm9wZW4oJHNvdXJjZSwgJ3InKTsKICAgICAgICAgICAgJHRhcmdldCA9IGZvcGVuKCR0YXJnZXQsICd3KycpOwoKICAgICAgICAgICAgc3RyZWFtX2NvcHlfdG9fc3RyZWFtKCRzb3VyY2UsICR0YXJnZXQpOwogICAgICAgICAgICBmY2xvc2UoJHNvdXJjZSk7CiAgICAgICAgICAgIGZjbG9zZSgkdGFyZ2V0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBjb21wYXJlIDIgZmlsZXMKICAgICAqIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMwNjAxMjUvY2FuLWktdXNlLWZpbGUtZ2V0LWNvbnRlbnRzLXRvLWNvbXBhcmUtdHdvLWZpbGVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYQogICAgICogQHBhcmFtIHN0cmluZyAkYgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbGVzQXJlRXF1YWwoJGEsICRiKQogICAgewogICAgICAgIC8vIENoZWNrIGlmIGZpbGVzaXplIGlzIGRpZmZlcmVudAogICAgICAgIGlmIChmaWxlc2l6ZSgkYSkgIT09IGZpbGVzaXplKCRiKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50IGlzIGRpZmZlcmVudAogICAgICAgICRhaCA9IGZvcGVuKCRhLCAncmInKTsKICAgICAgICAkYmggPSBmb3BlbigkYiwgJ3JiJyk7CgogICAgICAgICRyZXN1bHQgPSB0cnVlOwogICAgICAgIHdoaWxlICghZmVvZigkYWgpKSB7CiAgICAgICAgICAgIGlmIChmcmVhZCgkYWgsIDgxOTIpICE9IGZyZWFkKCRiaCwgODE5MikpIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmY2xvc2UoJGFoKTsKICAgICAgICBmY2xvc2UoJGJoKTsKCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogUGxhdGZvcm0gaGVscGVyIGZvciB1bmlmb3JtIHBsYXRmb3JtLXNwZWNpZmljIHRlc3RzLgogKgogKiBAYXV0aG9yIE5pZWxzIEtldXJlbnRqZXMgPG5pZWxzLmtldXJlbnRqZXNAb21pbmVzLmNvbT4KICovCmNsYXNzIFBsYXRmb3JtCnsKICAgIC8qKiBAdmFyID9ib29sICovCiAgICBwcml2YXRlIHN0YXRpYyAkaXNWaXJ0dWFsQm94R3Vlc3QgPSBudWxsOwogICAgLyoqIEB2YXIgP2Jvb2wgKi8KICAgIHByaXZhdGUgc3RhdGljICRpc1dpbmRvd3NTdWJzeXN0ZW1Gb3JMaW51eCA9IG51bGw7CgogICAgLyoqCiAgICAgKiBnZXRlbnYoKSBlcXVpdmFsZW50IGJ1dCByZWFkcyBmcm9tIHRoZSBydW50aW1lIGdsb2JhbCB2YXJpYWJsZXMgZmlyc3QKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRFbnYoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJG5hbWUsICRfU0VSVkVSKSkgewogICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJF9TRVJWRVJbJG5hbWVdOwogICAgICAgIH0KICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygkbmFtZSwgJF9FTlYpKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSAkX0VOVlskbmFtZV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZ2V0ZW52KCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIHB1dGVudigpIGVxdWl2YWxlbnQgYnV0IHVwZGF0ZXMgdGhlIHJ1bnRpbWUgZ2xvYmFsIHZhcmlhYmxlcyB0b28KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtICBzdHJpbmcgJHZhbHVlCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwdXRFbnYoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdmFsdWUgPSAoc3RyaW5nKSAkdmFsdWU7CiAgICAgICAgcHV0ZW52KCRuYW1lIC4gJz0nIC4gJHZhbHVlKTsKICAgICAgICAkX1NFUlZFUlskbmFtZV0gPSAkX0VOVlskbmFtZV0gPSAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBwdXRlbnYoJ1gnKSBlcXVpdmFsZW50IGJ1dCB1cGRhdGVzIHRoZSBydW50aW1lIGdsb2JhbCB2YXJpYWJsZXMgdG9vCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNsZWFyRW52KCRuYW1lKQogICAgewogICAgICAgIHB1dGVudigkbmFtZSk7CiAgICAgICAgdW5zZXQoJF9TRVJWRVJbJG5hbWVdLCAkX0VOVlskbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIHRpbGRlcyBhbmQgZW52aXJvbm1lbnQgdmFyaWFibGVzIGluIHBhdGhzLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYXRoCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4cGFuZFBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyNefltcXC9dIycsICRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6Z2V0VXNlckRpcmVjdG9yeSgpIC4gc3Vic3RyKCRwYXRoLCAxKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJyNeKFwkfCg/UDxwZXJjZW50PiUpKSg/UDx2YXI+XHcrKykoPyhwZXJjZW50KSUpKD9QPHBhdGg+LiopIycsIGZ1bmN0aW9uICgkbWF0Y2hlcykgewogICAgICAgICAgICAvLyBUcmVhdCBIT01FIGFzIGFuIGFsaWFzIGZvciBVU0VSUFJPRklMRSBvbiBXaW5kb3dzIGZvciBsZWdhY3kgcmVhc29ucwogICAgICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpICYmICRtYXRjaGVzWyd2YXInXSA9PSAnSE9NRScpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoUGxhdGZvcm06OmdldEVudignSE9NRScpID86IFBsYXRmb3JtOjpnZXRFbnYoJ1VTRVJQUk9GSUxFJykpIC4gJG1hdGNoZXNbJ3BhdGgnXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFBsYXRmb3JtOjpnZXRFbnYoJG1hdGNoZXNbJ3ZhciddKSAuICRtYXRjaGVzWydwYXRoJ107CiAgICAgICAgfSwgJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgdXNlciBob21lIGNvdWxkIG5vdCByZWxpYWJseSBiZSBkZXRlcm1pbmVkCiAgICAgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgICAgIFRoZSBmb3JtYWwgdXNlciBob21lIGFzIGRldGVjdGVkIGZyb20gZW52aXJvbm1lbnQgcGFyYW1ldGVycwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFVzZXJEaXJlY3RvcnkoKQogICAgewogICAgICAgIGlmIChmYWxzZSAhPT0gKCRob21lID0gc2VsZjo6Z2V0RW52KCdIT01FJykpKSB7CiAgICAgICAgICAgIHJldHVybiAkaG9tZTsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjppc1dpbmRvd3MoKSAmJiBmYWxzZSAhPT0gKCRob21lID0gc2VsZjo6Z2V0RW52KCdVU0VSUFJPRklMRScpKSkgewogICAgICAgICAgICByZXR1cm4gJGhvbWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0dWlkJykgJiYgXGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0cHd1aWQnKSkgewogICAgICAgICAgICAkaW5mbyA9IHBvc2l4X2dldHB3dWlkKHBvc2l4X2dldHVpZCgpKTsKCiAgICAgICAgICAgIHJldHVybiAkaW5mb1snZGlyJ107CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBkZXRlcm1pbmUgdXNlciBkaXJlY3RvcnknKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBob3N0IG1hY2hpbmUgaXMgcnVubmluZyBvbiB0aGUgV2luZG93cyBTdWJzeXN0ZW0gZm9yIExpbnV4IChXU0wpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNXaW5kb3dzU3Vic3lzdGVtRm9yTGludXgoKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaXNXaW5kb3dzU3Vic3lzdGVtRm9yTGludXgpIHsKICAgICAgICAgICAgc2VsZjo6JGlzV2luZG93c1N1YnN5c3RlbUZvckxpbnV4ID0gZmFsc2U7CgogICAgICAgICAgICAvLyB3aGlsZSBXU0wgd2lsbCBiZSBob3N0ZWQgd2l0aGluIHdpbmRvd3MsIFdTTCBpdHNlbGYgY2Fubm90IGJlIHdpbmRvd3MgYmFzZWQgaXRzZWxmLgogICAgICAgICAgICBpZiAoc2VsZjo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxmOjokaXNXaW5kb3dzU3Vic3lzdGVtRm9yTGludXggPSBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgIWluaV9nZXQoJ29wZW5fYmFzZWRpcicpCiAgICAgICAgICAgICAgICAmJiBpc19yZWFkYWJsZSgnL3Byb2MvdmVyc2lvbicpCiAgICAgICAgICAgICAgICAmJiBmYWxzZSAhPT0gc3RyaXBvcyhTaWxlbmNlcjo6Y2FsbCgnZmlsZV9nZXRfY29udGVudHMnLCAnL3Byb2MvdmVyc2lvbicpLCAnbWljcm9zb2Z0JykKICAgICAgICAgICAgICAgICYmICFmaWxlX2V4aXN0cygnLy5kb2NrZXJlbnYnKSAvLyBkb2NrZXIgcnVubmluZyBpbnNpZGUgV1NMIHNob3VsZCBub3QgYmUgc2VlbiBhcyBXU0wKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGlzV2luZG93c1N1YnN5c3RlbUZvckxpbnV4ID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRpc1dpbmRvd3NTdWJzeXN0ZW1Gb3JMaW51eDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBob3N0IG1hY2hpbmUgaXMgcnVubmluZyBhIFdpbmRvd3MgT1MKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1dpbmRvd3MoKQogICAgewogICAgICAgIHJldHVybiBcZGVmaW5lZCgnUEhQX1dJTkRPV1NfVkVSU0lPTl9CVUlMRCcpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJHN0cgogICAgICogQHJldHVybiBpbnQgICAgcmV0dXJuIGEgZ3VhcmFudGVlZCBiaW5hcnkgbGVuZ3RoIG9mIHRoZSBzdHJpbmcsIHJlZ2FyZGxlc3Mgb2Ygc2lsbHkgbWJzdHJpbmcgY29uZmlncwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN0cmxlbigkc3RyKQogICAgewogICAgICAgIHN0YXRpYyAkdXNlTWJTdHJpbmcgPSBudWxsOwogICAgICAgIGlmIChudWxsID09PSAkdXNlTWJTdHJpbmcpIHsKICAgICAgICAgICAgJHVzZU1iU3RyaW5nID0gXGZ1bmN0aW9uX2V4aXN0cygnbWJfc3RybGVuJykgJiYgaW5pX2dldCgnbWJzdHJpbmcuZnVuY19vdmVybG9hZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR1c2VNYlN0cmluZykgewogICAgICAgICAgICByZXR1cm4gbWJfc3RybGVuKCRzdHIsICc4Yml0Jyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXHN0cmxlbigkc3RyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgP3Jlc291cmNlICRmZCBPcGVuIGZpbGUgZGVzY3JpcHRvciBvciBudWxsIHRvIGRlZmF1bHQgdG8gU1RET1VUCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1R0eSgkZmQgPSBudWxsKQogICAgewogICAgICAgIGlmICgkZmQgPT09IG51bGwpIHsKICAgICAgICAgICAgJGZkID0gZGVmaW5lZCgnU1RET1VUJykgPyBTVERPVVQgOiBmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKTsKICAgICAgICB9CgogICAgICAgIC8vIGRldGVjdCBtc3lzZ2l0L21pbmd3IGFuZCBhc3N1bWUgdGhpcyBpcyBhIHR0eSBiZWNhdXNlIGRldGVjdGlvbgogICAgICAgIC8vIGRvZXMgbm90IHdvcmsgY29ycmVjdGx5LCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy85NjkwCiAgICAgICAgaWYgKGluX2FycmF5KHN0cnRvdXBwZXIoc2VsZjo6Z2V0RW52KCdNU1lTVEVNJykgPzogJycpLCBhcnJheSgnTUlOR1czMicsICdNSU5HVzY0JyksIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbW9kZXJuIGNyb3NzLXBsYXRmb3JtIGZ1bmN0aW9uLCBpbmNsdWRlcyB0aGUgZnN0YXQKICAgICAgICAvLyBmYWxsYmFjayBzbyBpZiBpdCBpcyBwcmVzZW50IHdlIHRydXN0IGl0CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnc3RyZWFtX2lzYXR0eScpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJlYW1faXNhdHR5KCRmZCk7CiAgICAgICAgfQoKICAgICAgICAvLyBvbmx5IHRydXN0aW5nIHRoaXMgaWYgaXQgaXMgcG9zaXRpdmUsIG90aGVyd2lzZSBwcmVmZXIgZnN0YXQgZmFsbGJhY2sKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9pc2F0dHknKSAmJiBwb3NpeF9pc2F0dHkoJGZkKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRzdGF0ID0gQGZzdGF0KCRmZCk7CiAgICAgICAgLy8gQ2hlY2sgaWYgZm9ybWF0dGVkIG1vZGUgaXMgU19JRkNIUgogICAgICAgIHJldHVybiAkc3RhdCA/IDAwMjAwMDAgPT09ICgkc3RhdFsnbW9kZSddICYgMDE3MDAwMCkgOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHdvcmthcm91bmRGaWxlc3lzdGVtSXNzdWVzKCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6aXNWaXJ0dWFsQm94R3Vlc3QoKSkgewogICAgICAgICAgICB1c2xlZXAoMjAwMDAwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyBkZXRlY3Rpb24gb2YgVmlydHVhbEJveCBndWVzdCBWTXMKICAgICAqCiAgICAgKiBUaGlzIHdvcmtzIGJhc2VkIG9uIHRoZSBwcm9jZXNzJyB1c2VyIGJlaW5nICJ2YWdyYW50IiwgdGhlIENPTVBPU0VSX1JVTlRJTUVfRU5WIGVudiB2YXIgYmVpbmcgc2V0IHRvICJ2aXJ0dWFsYm94Iiwgb3IgbHNtb2Qgc2hvd2luZyB0aGUgdmlydHVhbGJveCBndWVzdCBhZGRpdGlvbnMgYXJlIGxvYWRlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc1ZpcnR1YWxCb3hHdWVzdCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiRpc1ZpcnR1YWxCb3hHdWVzdCkgewogICAgICAgICAgICBzZWxmOjokaXNWaXJ0dWFsQm94R3Vlc3QgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKHNlbGY6OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGlzVmlydHVhbEJveEd1ZXN0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRwd3VpZCcpICYmIGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0ZXVpZCcpKSB7CiAgICAgICAgICAgICAgICAkcHJvY2Vzc1VzZXIgPSBwb3NpeF9nZXRwd3VpZChwb3NpeF9nZXRldWlkKCkpOwogICAgICAgICAgICAgICAgaWYgKCRwcm9jZXNzVXNlciAmJiAkcHJvY2Vzc1VzZXJbJ25hbWUnXSA9PT0gJ3ZhZ3JhbnQnKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRpc1ZpcnR1YWxCb3hHdWVzdCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzZWxmOjpnZXRFbnYoJ0NPTVBPU0VSX1JVTlRJTUVfRU5WJykgPT09ICd2aXJ0dWFsYm94JykgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRpc1ZpcnR1YWxCb3hHdWVzdCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChkZWZpbmVkKCdQSFBfT1NfRkFNSUxZJykgJiYgUEhQX09TX0ZBTUlMWSA9PT0gJ0xpbnV4JykgewogICAgICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkcHJvY2Vzcy0+ZXhlY3V0ZSgnbHNtb2QgfCBncmVwIHZib3hndWVzdCcsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGlzVmlydHVhbEJveEd1ZXN0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbm9vcAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGlzVmlydHVhbEJveEd1ZXN0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxDYUJ1bmRsZVxDYUJ1bmRsZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBcUHJveHlNYW5hZ2VyOwp1c2UgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2U7CgovKioKICogQWxsb3dzIHRoZSBjcmVhdGlvbiBvZiBhIGJhc2ljIGNvbnRleHQgc3VwcG9ydGluZyBodHRwIHByb3h5CiAqCiAqIEBhdXRob3IgSm9yZGFuIEFsbGlvdCA8am9yZGFuLmFsbGlvdEBnbWFpbC5jb20+CiAqIEBhdXRob3IgTWFya3VzIFRhY2tlciA8bUBjb2RlcmJ5aGVhcnQuZGU+CiAqLwpmaW5hbCBjbGFzcyBTdHJlYW1Db250ZXh0RmFjdG9yeQp7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBjb250ZXh0IHN1cHBvcnRpbmcgSFRUUCBwcm94aWVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsIFVSTCB0aGUgY29udGV4dCBpcyB0byBiZSB1c2VkIGZvcgogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXl7aHR0cD86IGFycmF5e2ZvbGxvd19sb2NhdGlvbj86IGludCwgbWF4X3JlZGlyZWN0cz86IGludCwgaGVhZGVyPzogc3RyaW5nfGFycmF5PHN0cmluZz59fSAkZGVmYXVsdE9wdGlvbnMKICAgICAqIEBwYXJhbSAgbWl4ZWRbXSAgICAgICAgICAgJGRlZmF1bHRPcHRpb25zIE9wdGlvbnMgdG8gbWVyZ2Ugd2l0aCB0aGUgZGVmYXVsdAogICAgICogQHBhcmFtICBtaXhlZFtdICAgICAgICAgICAkZGVmYXVsdFBhcmFtcyAgUGFyYW1ldGVycyB0byBzcGVjaWZ5IG9uIHRoZSBjb250ZXh0CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIGlmIGh0dHBzIHByb3h5IHJlcXVpcmVkIGFuZCBPcGVuU1NMIHVuaW5zdGFsbGVkCiAgICAgKiBAcmV0dXJuIHJlc291cmNlICAgICAgICAgIERlZmF1bHQgY29udGV4dAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbnRleHQoJHVybCwgYXJyYXkgJGRlZmF1bHRPcHRpb25zID0gYXJyYXkoKSwgYXJyYXkgJGRlZmF1bHRQYXJhbXMgPSBhcnJheSgpKQogICAgewogICAgICAgICRvcHRpb25zID0gYXJyYXkoJ2h0dHAnID0+IGFycmF5KAogICAgICAgICAgICAvLyBzcGVjaWZ5IGRlZmF1bHRzIGFnYWluIHRvIHRyeSBhbmQgd29yayBiZXR0ZXIgd2l0aCBjdXJsd3JhcHBlcnMgZW5hYmxlZAogICAgICAgICAgICAnZm9sbG93X2xvY2F0aW9uJyA9PiAxLAogICAgICAgICAgICAnbWF4X3JlZGlyZWN0cycgPT4gMjAsCiAgICAgICAgKSk7CgogICAgICAgICRvcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJG9wdGlvbnMsIHNlbGY6OmluaXRPcHRpb25zKCR1cmwsICRkZWZhdWx0T3B0aW9ucykpOwogICAgICAgIHVuc2V0KCRkZWZhdWx0T3B0aW9uc1snaHR0cCddWydoZWFkZXInXSk7CiAgICAgICAgJG9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkb3B0aW9ucywgJGRlZmF1bHRPcHRpb25zKTsKCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IHNlbGY6OmZpeEh0dHBIZWFkZXJGaWVsZCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RyZWFtX2NvbnRleHRfY3JlYXRlKCRvcHRpb25zLCAkZGVmYXVsdFBhcmFtcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkdXJsCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucwogICAgICogQHBhcmFtIGJvb2wgICAgJGZvckN1cmwgV2hlbiB0cnVlLCB3aWxsIG5vdCBhZGQgcHJveHkgdmFsdWVzIGFzIHRoZXNlIGFyZSBoYW5kbGVkIHNlcGFyYXRlbHkKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheXtodHRwOiBhcnJheXtoZWFkZXI6IHN0cmluZ1tdLCBwcm94eT86IHN0cmluZywgcmVxdWVzdF9mdWxsdXJpOiBib29sfSwgc3NsPzogbWl4ZWRbXX0KICAgICAqIEByZXR1cm4gYXJyYXkgZm9ybWF0dGVkIGFzIGEgc3RyZWFtIGNvbnRleHQgYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpbml0T3B0aW9ucygkdXJsLCBhcnJheSAkb3B0aW9ucywgJGZvckN1cmwgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGhlYWRlcnMgYXJlIGluIGFuIGFycmF5IGZvcm0KICAgICAgICBpZiAoIWlzc2V0KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IGFycmF5KCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc19zdHJpbmcoJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gZXhwbG9kZSgiXHJcbiIsICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKTsKICAgICAgICB9CgogICAgICAgIC8vIEFkZCBzdHJlYW0gcHJveHkgb3B0aW9ucyBpZiB0aGVyZSBpcyBhIHByb3h5CiAgICAgICAgaWYgKCEkZm9yQ3VybCkgewogICAgICAgICAgICAkcHJveHkgPSBQcm94eU1hbmFnZXI6OmdldEluc3RhbmNlKCktPmdldFByb3h5Rm9yUmVxdWVzdCgkdXJsKTsKICAgICAgICAgICAgaWYgKCRwcm94eU9wdGlvbnMgPSAkcHJveHktPmdldENvbnRleHRPcHRpb25zKCkpIHsKICAgICAgICAgICAgICAgICRpc0h0dHBzUmVxdWVzdCA9IDAgPT09IHN0cnBvcygkdXJsLCAnaHR0cHM6Ly8nKTsKCiAgICAgICAgICAgICAgICBpZiAoJHByb3h5LT5pc1NlY3VyZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignWW91IG11c3QgZW5hYmxlIHRoZSBvcGVuc3NsIGV4dGVuc2lvbiB0byB1c2UgYSBzZWN1cmUgcHJveHkuJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkaXNIdHRwc1JlcXVlc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignWW91IG11c3QgZW5hYmxlIHRoZSBjdXJsIGV4dGVuc2lvbiB0byBtYWtlIGh0dHBzIHJlcXVlc3RzIHRocm91Z2ggYSBzZWN1cmUgcHJveHkuJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRpc0h0dHBzUmVxdWVzdCAmJiAhZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignWW91IG11c3QgZW5hYmxlIHRoZSBvcGVuc3NsIGV4dGVuc2lvbiB0byBtYWtlIGh0dHBzIHJlcXVlc3RzIHRocm91Z2ggYSBwcm94eS4nKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBIZWFkZXIgd2lsbCBiZSBhIFByb3h5LUF1dGhvcml6YXRpb24gc3RyaW5nIG9yIG5vdCBzZXQKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcHJveHlPcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddW10gPSAkcHJveHlPcHRpb25zWydodHRwJ11bJ2hlYWRlciddOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRwcm94eU9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkb3B0aW9ucywgJHByb3h5T3B0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICAkcGhwVmVyc2lvbiA9ICdISFZNICcgLiBISFZNX1ZFUlNJT047CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBocFZlcnNpb24gPSAnUEhQICcgLiBQSFBfTUFKT1JfVkVSU0lPTiAuICcuJyAuIFBIUF9NSU5PUl9WRVJTSU9OIC4gJy4nIC4gUEhQX1JFTEVBU0VfVkVSU0lPTjsKICAgICAgICB9CgogICAgICAgIGlmICgkZm9yQ3VybCkgewogICAgICAgICAgICAkY3VybCA9IGN1cmxfdmVyc2lvbigpOwogICAgICAgICAgICAkaHR0cFZlcnNpb24gPSAnY1VSTCAnLiRjdXJsWyd2ZXJzaW9uJ107CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGh0dHBWZXJzaW9uID0gJ3N0cmVhbXMnOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkgfHwgZmFsc2UgPT09IHN0cmlwb3MoaW1wbG9kZSgnJywgJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10pLCAndXNlci1hZ2VudCcpKSB7CiAgICAgICAgICAgICRwbGF0Zm9ybVBocFZlcnNpb24gPSBQbGF0Zm9ybVJlcG9zaXRvcnk6OmdldFBsYXRmb3JtUGhwVmVyc2lvbigpOwogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICdVc2VyLUFnZW50OiBDb21wb3Nlci8lcyAoJXM7ICVzOyAlczsgJXMlcyVzKScsCiAgICAgICAgICAgICAgICBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpLAogICAgICAgICAgICAgICAgZnVuY3Rpb25fZXhpc3RzKCdwaHBfdW5hbWUnKSA/IHBocF91bmFtZSgncycpIDogJ1Vua25vd24nLAogICAgICAgICAgICAgICAgZnVuY3Rpb25fZXhpc3RzKCdwaHBfdW5hbWUnKSA/IHBocF91bmFtZSgncicpIDogJ1Vua25vd24nLAogICAgICAgICAgICAgICAgJHBocFZlcnNpb24sCiAgICAgICAgICAgICAgICAkaHR0cFZlcnNpb24sCiAgICAgICAgICAgICAgICAkcGxhdGZvcm1QaHBWZXJzaW9uID8gJzsgUGxhdGZvcm0tUEhQICcuJHBsYXRmb3JtUGhwVmVyc2lvbiA6ICcnLAogICAgICAgICAgICAgICAgUGxhdGZvcm06OmdldEVudignQ0knKSA/ICc7IENJJyA6ICcnCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWRbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFRsc0RlZmF1bHRzKGFycmF5ICRvcHRpb25zLCBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlciA9IG51bGwpCiAgICB7CiAgICAgICAgJGNpcGhlcnMgPSBpbXBsb2RlKCc6JywgYXJyYXkoCiAgICAgICAgICAgICdFQ0RIRS1SU0EtQUVTMTI4LUdDTS1TSEEyNTYnLAogICAgICAgICAgICAnRUNESEUtRUNEU0EtQUVTMTI4LUdDTS1TSEEyNTYnLAogICAgICAgICAgICAnRUNESEUtUlNBLUFFUzI1Ni1HQ00tU0hBMzg0JywKICAgICAgICAgICAgJ0VDREhFLUVDRFNBLUFFUzI1Ni1HQ00tU0hBMzg0JywKICAgICAgICAgICAgJ0RIRS1SU0EtQUVTMTI4LUdDTS1TSEEyNTYnLAogICAgICAgICAgICAnREhFLURTUy1BRVMxMjgtR0NNLVNIQTI1NicsCiAgICAgICAgICAgICdrRURIK0FFU0dDTScsCiAgICAgICAgICAgICdFQ0RIRS1SU0EtQUVTMTI4LVNIQTI1NicsCiAgICAgICAgICAgICdFQ0RIRS1FQ0RTQS1BRVMxMjgtU0hBMjU2JywKICAgICAgICAgICAgJ0VDREhFLVJTQS1BRVMxMjgtU0hBJywKICAgICAgICAgICAgJ0VDREhFLUVDRFNBLUFFUzEyOC1TSEEnLAogICAgICAgICAgICAnRUNESEUtUlNBLUFFUzI1Ni1TSEEzODQnLAogICAgICAgICAgICAnRUNESEUtRUNEU0EtQUVTMjU2LVNIQTM4NCcsCiAgICAgICAgICAgICdFQ0RIRS1SU0EtQUVTMjU2LVNIQScsCiAgICAgICAgICAgICdFQ0RIRS1FQ0RTQS1BRVMyNTYtU0hBJywKICAgICAgICAgICAgJ0RIRS1SU0EtQUVTMTI4LVNIQTI1NicsCiAgICAgICAgICAgICdESEUtUlNBLUFFUzEyOC1TSEEnLAogICAgICAgICAgICAnREhFLURTUy1BRVMxMjgtU0hBMjU2JywKICAgICAgICAgICAgJ0RIRS1SU0EtQUVTMjU2LVNIQTI1NicsCiAgICAgICAgICAgICdESEUtRFNTLUFFUzI1Ni1TSEEnLAogICAgICAgICAgICAnREhFLVJTQS1BRVMyNTYtU0hBJywKICAgICAgICAgICAgJ0FFUzEyOC1HQ00tU0hBMjU2JywKICAgICAgICAgICAgJ0FFUzI1Ni1HQ00tU0hBMzg0JywKICAgICAgICAgICAgJ0FFUzEyOC1TSEEyNTYnLAogICAgICAgICAgICAnQUVTMjU2LVNIQTI1NicsCiAgICAgICAgICAgICdBRVMxMjgtU0hBJywKICAgICAgICAgICAgJ0FFUzI1Ni1TSEEnLAogICAgICAgICAgICAnQUVTJywKICAgICAgICAgICAgJ0NBTUVMTElBJywKICAgICAgICAgICAgJ0RFUy1DQkMzLVNIQScsCiAgICAgICAgICAgICchYU5VTEwnLAogICAgICAgICAgICAnIWVOVUxMJywKICAgICAgICAgICAgJyFFWFBPUlQnLAogICAgICAgICAgICAnIURFUycsCiAgICAgICAgICAgICchUkM0JywKICAgICAgICAgICAgJyFNRDUnLAogICAgICAgICAgICAnIVBTSycsCiAgICAgICAgICAgICchYUVDREgnLAogICAgICAgICAgICAnIUVESC1EU1MtREVTLUNCQzMtU0hBJywKICAgICAgICAgICAgJyFFREgtUlNBLURFUy1DQkMzLVNIQScsCiAgICAgICAgICAgICchS1JCNS1ERVMtQ0JDMy1TSEEnLAogICAgICAgICkpOwoKICAgICAgICAvKioKICAgICAgICAgKiBDTl9tYXRjaCBhbmQgU05JX3NlcnZlcl9uYW1lIGFyZSBvbmx5IGtub3duIG9uY2UgYSBVUkwgaXMgcGFzc2VkLgogICAgICAgICAqIFRoZXkgd2lsbCBiZSBzZXQgaW4gdGhlIGdldE9wdGlvbnNGb3JVcmwoKSBtZXRob2Qgd2hpY2ggcmVjZWl2ZXMgYSBVUkwuCiAgICAgICAgICoKICAgICAgICAgKiBjYWZpbGUgb3IgY2FwYXRoIGNhbiBiZSBvdmVycmlkZGVuIGJ5IHBhc3NpbmcgaW4gdGhvc2Ugb3B0aW9ucyB0byBjb25zdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAkZGVmYXVsdHMgPSBhcnJheSgKICAgICAgICAgICAgJ3NzbCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAnY2lwaGVycycgPT4gJGNpcGhlcnMsCiAgICAgICAgICAgICAgICAndmVyaWZ5X3BlZXInID0+IHRydWUsCiAgICAgICAgICAgICAgICAndmVyaWZ5X2RlcHRoJyA9PiA3LAogICAgICAgICAgICAgICAgJ1NOSV9lbmFibGVkJyA9PiB0cnVlLAogICAgICAgICAgICAgICAgJ2NhcHR1cmVfcGVlcl9jZXJ0JyA9PiB0cnVlLAogICAgICAgICAgICApLAogICAgICAgICk7CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snc3NsJ10pKSB7CiAgICAgICAgICAgICRkZWZhdWx0c1snc3NsJ10gPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkZGVmYXVsdHNbJ3NzbCddLCAkb3B0aW9uc1snc3NsJ10pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQXR0ZW1wdCB0byBmaW5kIGEgbG9jYWwgY2FmaWxlIG9yIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBub25lIHByZS1zZXQKICAgICAgICAgKiBUaGUgdXNlciBtYXkgZ28gZG93bmxvYWQgb25lIGlmIHRoaXMgb2NjdXJzLgogICAgICAgICAqLwogICAgICAgIGlmICghaXNzZXQoJGRlZmF1bHRzWydzc2wnXVsnY2FmaWxlJ10pICYmICFpc3NldCgkZGVmYXVsdHNbJ3NzbCddWydjYXBhdGgnXSkpIHsKICAgICAgICAgICAgJHJlc3VsdCA9IENhQnVuZGxlOjpnZXRTeXN0ZW1DYVJvb3RCdW5kbGVQYXRoKCRsb2dnZXIpOwoKICAgICAgICAgICAgaWYgKGlzX2RpcigkcmVzdWx0KSkgewogICAgICAgICAgICAgICAgJGRlZmF1bHRzWydzc2wnXVsnY2FwYXRoJ10gPSAkcmVzdWx0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGRlZmF1bHRzWydzc2wnXVsnY2FmaWxlJ10gPSAkcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGRlZmF1bHRzWydzc2wnXVsnY2FmaWxlJ10pICYmICghRmlsZXN5c3RlbTo6aXNSZWFkYWJsZSgkZGVmYXVsdHNbJ3NzbCddWydjYWZpbGUnXSkgfHwgIUNhQnVuZGxlOjp2YWxpZGF0ZUNhRmlsZSgkZGVmYXVsdHNbJ3NzbCddWydjYWZpbGUnXSwgJGxvZ2dlcikpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1RoZSBjb25maWd1cmVkIGNhZmlsZSB3YXMgbm90IHZhbGlkIG9yIGNvdWxkIG5vdCBiZSByZWFkLicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRkZWZhdWx0c1snc3NsJ11bJ2NhcGF0aCddKSAmJiAoIWlzX2RpcigkZGVmYXVsdHNbJ3NzbCddWydjYXBhdGgnXSkgfHwgIUZpbGVzeXN0ZW06OmlzUmVhZGFibGUoJGRlZmF1bHRzWydzc2wnXVsnY2FwYXRoJ10pKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgY29uZmlndXJlZCBjYXBhdGggd2FzIG5vdCB2YWxpZCBvciBjb3VsZCBub3QgYmUgcmVhZC4nKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIERpc2FibGUgVExTIGNvbXByZXNzaW9uIHRvIHByZXZlbnQgQ1JJTUUgYXR0YWNrcyB3aGVyZSBzdXBwb3J0ZWQuCiAgICAgICAgICovCiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDUwNDEzKSB7CiAgICAgICAgICAgICRkZWZhdWx0c1snc3NsJ11bJ2Rpc2FibGVfY29tcHJlc3Npb24nXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRlZmF1bHRzOwogICAgfQoKICAgIC8qKgogICAgICogQSBidWcgaW4gUEhQIHByZXZlbnRzIHRoZSBoZWFkZXJzIGZyb20gY29ycmVjdGx5IGJlaW5nIHNlbnQgd2hlbiBhIGNvbnRlbnQtdHlwZSBoZWFkZXIgaXMgcHJlc2VudCBhbmQKICAgICAqIE5PVCBhdCB0aGUgZW5kIG9mIHRoZSBhcnJheQogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGZpeGVzIHRoZSBhcnJheSBieSBtb3ZpbmcgdGhlIGNvbnRlbnQtdHlwZSBoZWFkZXIgdG8gdGhlIGVuZAogICAgICoKICAgICAqIEBsaW5rIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NjE1NDgKICAgICAqIEBwYXJhbSAgc3RyaW5nfHN0cmluZ1tdICRoZWFkZXIKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZml4SHR0cEhlYWRlckZpZWxkKCRoZWFkZXIpCiAgICB7CiAgICAgICAgaWYgKCFpc19hcnJheSgkaGVhZGVyKSkgewogICAgICAgICAgICAkaGVhZGVyID0gZXhwbG9kZSgiXHJcbiIsICRoZWFkZXIpOwogICAgICAgIH0KICAgICAgICB1YXNvcnQoJGhlYWRlciwgZnVuY3Rpb24gKCRlbCkgewogICAgICAgICAgICByZXR1cm4gc3RyaXBvcygkZWwsICdjb250ZW50LXR5cGUnKSA9PT0gMCA/IDEgOiAtMTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRoZWFkZXI7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxEb3dubG9hZGVyXERvd25sb2FkZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgpjbGFzcyBTeW5jSGVscGVyCnsKICAgIC8qKgogICAgICogSGVscHMgeW91IGRvd25sb2FkICsgaW5zdGFsbCBhIHNpbmdsZSBwYWNrYWdlIGluIGEgc3luY2hyb25vdXMgd2F5CiAgICAgKgogICAgICogVGhpcyBleGVjdXRlcyBhbGwgdGhlIHJlcXVpcmVkIHN0ZXBzIGFuZCB3YWl0cyBmb3IgcHJvbWlzZXMgdG8gY29tcGxldGUKICAgICAqCiAgICAgKiBAcGFyYW0gTG9vcCAgICAgICAgICAgICAgICAgICRsb29wICAgICAgICBMb29wIGluc3RhbmNlIHdoaWNoIHlvdSBjYW4gZ2V0IGZyb20gJGNvbXBvc2VyLT5nZXRMb29wKCkKICAgICAqIEBwYXJhbSBEb3dubG9hZGVySW50ZXJmYWNlICAgJGRvd25sb2FkZXIgIERvd25sb2FkZXIgaW5zdGFuY2UgeW91IGNhbiBnZXQgZnJvbSAkY29tcG9zZXItPmdldERvd25sb2FkTWFuYWdlcigpLT5nZXREb3dubG9hZGVyKCd6aXAnKSBmb3IgZXhhbXBsZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAkcGF0aCAgICAgICAgdGhlIGluc3RhbGxhdGlvbiBwYXRoIGZvciB0aGUgcGFja2FnZQogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgdGhlIHBhY2thZ2UgdG8gaW5zdGFsbAogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAkcHJldlBhY2thZ2UgdGhlIHByZXZpb3VzIHBhY2thZ2UgaWYgdGhpcyBpcyBhbiB1cGRhdGUgYW5kIG5vdCBhbiBpbml0aWFsIGluc3RhbGxhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGRvd25sb2FkQW5kSW5zdGFsbFBhY2thZ2VTeW5jKExvb3AgJGxvb3AsIERvd25sb2FkZXJJbnRlcmZhY2UgJGRvd25sb2FkZXIsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHR5cGUgPSAkcHJldlBhY2thZ2UgPyAndXBkYXRlJyA6ICdpbnN0YWxsJzsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc2VsZjo6YXdhaXQoJGxvb3AsICRkb3dubG9hZGVyLT5kb3dubG9hZCgkcGFja2FnZSwgJHBhdGgsICRwcmV2UGFja2FnZSkpOwoKICAgICAgICAgICAgc2VsZjo6YXdhaXQoJGxvb3AsICRkb3dubG9hZGVyLT5wcmVwYXJlKCR0eXBlLCAkcGFja2FnZSwgJHBhdGgsICRwcmV2UGFja2FnZSkpOwoKICAgICAgICAgICAgaWYgKCR0eXBlID09PSAndXBkYXRlJykgewogICAgICAgICAgICAgICAgc2VsZjo6YXdhaXQoJGxvb3AsICRkb3dubG9hZGVyLT51cGRhdGUoJHBhY2thZ2UsICRwcmV2UGFja2FnZSwgJHBhdGgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbGY6OmF3YWl0KCRsb29wLCAkZG93bmxvYWRlci0+aW5zdGFsbCgkcGFja2FnZSwgJHBhdGgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgc2VsZjo6YXdhaXQoJGxvb3AsICRkb3dubG9hZGVyLT5jbGVhbnVwKCR0eXBlLCAkcGFja2FnZSwgJHBhdGgsICRwcmV2UGFja2FnZSkpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OmF3YWl0KCRsb29wLCAkZG93bmxvYWRlci0+Y2xlYW51cCgkdHlwZSwgJHBhY2thZ2UsICRwYXRoLCAkcHJldlBhY2thZ2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdhaXRzIGZvciBhIHByb21pc2UgdG8gcmVzb2x2ZQogICAgICoKICAgICAqIEBwYXJhbSBMb29wICAgICAgICAgICAgICAgICAgJGxvb3AgICAgTG9vcCBpbnN0YW5jZSB3aGljaCB5b3UgY2FuIGdldCBmcm9tICRjb21wb3Nlci0+Z2V0TG9vcCgpCiAgICAgKiBAcGFyYW0gUHJvbWlzZUludGVyZmFjZXxudWxsICRwcm9taXNlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYXdhaXQoTG9vcCAkbG9vcCwgUHJvbWlzZUludGVyZmFjZSAkcHJvbWlzZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRwcm9taXNlKSB7CiAgICAgICAgICAgICRsb29wLT53YWl0KGFycmF5KCRwcm9taXNlKSk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgR2l0SHViCnsKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlvOwogICAgLyoqIEB2YXIgQ29uZmlnICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwogICAgLyoqIEB2YXIgSHR0cERvd25sb2FkZXIgKi8KICAgIHByb3RlY3RlZCAkaHR0cERvd25sb2FkZXI7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgJGNvbmZpZyAgICAgICAgIFRoZSBjb21wb3NlciBjb25maWd1cmF0aW9uCiAgICAgKiBAcGFyYW0gUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzICAgICAgICBQcm9jZXNzIGluc3RhbmNlLCBpbmplY3RhYmxlIGZvciBtb2NraW5nCiAgICAgKiBAcGFyYW0gSHR0cERvd25sb2FkZXIgICRodHRwRG93bmxvYWRlciBSZW1vdGUgRmlsZXN5c3RlbSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCwgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzcyA/OiBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyID86IEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCR0aGlzLT5pbywgJGNvbmZpZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBhdXRob3JpemUgYSBHaXRIdWIgZG9tYWluIHZpYSBPQXV0aAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRvcmlnaW5VcmwgVGhlIGhvc3QgdGhpcyBHaXRIdWIgaW5zdGFuY2UgaXMgbG9jYXRlZCBhdAogICAgICogQHJldHVybiBib29sICAgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aCgkb3JpZ2luVXJsKQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJG9yaWdpblVybCwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBhdmFpbGFibGUgdXNlIHRva2VuIGZyb20gZ2l0IGNvbmZpZwogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNvbmZpZyBnaXRodWIuYWNjZXNzdG9rZW4nLCAkb3V0cHV0KSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW5VcmwsIHRyaW0oJG91dHB1dCksICd4LW9hdXRoLWJhc2ljJyk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEF1dGhvcml6ZXMgYSBHaXRIdWIgZG9tYWluIGludGVyYWN0aXZlbHkgdmlhIE9BdXRoCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkb3JpZ2luVXJsIFRoZSBob3N0IHRoaXMgR2l0SHViIGluc3RhbmNlIGlzIGxvY2F0ZWQgYXQKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgICBUaGUgcmVhc29uIHRoaXMgYXV0aG9yaXphdGlvbiBpcyByZXF1aXJlZAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb258XEV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlIG9uIHN1Y2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkb3JpZ2luVXJsLCAkbWVzc2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRtZXNzYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbWVzc2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkbm90ZSA9ICdDb21wb3Nlcic7CiAgICAgICAgaWYgKCR0aGlzLT5jb25maWctPmdldCgnZ2l0aHViLWV4cG9zZS1ob3N0bmFtZScpID09PSB0cnVlICYmIDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdob3N0bmFtZScsICRvdXRwdXQpKSB7CiAgICAgICAgICAgICRub3RlIC49ICcgb24gJyAuIHRyaW0oJG91dHB1dCk7CiAgICAgICAgfQogICAgICAgICRub3RlIC49ICcgJyAuIGRhdGUoJ1ktbS1kIEhpJyk7CgogICAgICAgICR1cmwgPSAnaHR0cHM6Ly8nLiRvcmlnaW5VcmwuJy9zZXR0aW5ncy90b2tlbnMvbmV3P3Njb3Blcz0mZGVzY3JpcHRpb249JyAuIHN0cl9yZXBsYWNlKCclMjAnLCAnKycsIHJhd3VybGVuY29kZSgkbm90ZSkpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCdXaGVuIHdvcmtpbmcgd2l0aCBfcHVibGljXyBHaXRIdWIgcmVwb3NpdG9yaWVzIG9ubHksIGhlYWQgdG8gJXMgdG8gcmV0cmlldmUgYSB0b2tlbi4nLCAkdXJsKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdUaGlzIHRva2VuIHdpbGwgaGF2ZSByZWFkLW9ubHkgcGVybWlzc2lvbiBmb3IgcHVibGljIGluZm9ybWF0aW9uIG9ubHkuJyk7CgogICAgICAgICR1cmwgPSAnaHR0cHM6Ly8nLiRvcmlnaW5VcmwuJy9zZXR0aW5ncy90b2tlbnMvbmV3P3Njb3Blcz1yZXBvJmRlc2NyaXB0aW9uPScgLiBzdHJfcmVwbGFjZSgnJTIwJywgJysnLCByYXd1cmxlbmNvZGUoJG5vdGUpKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignV2hlbiB5b3UgbmVlZCB0byBhY2Nlc3MgX3ByaXZhdGVfIEdpdEh1YiByZXBvc2l0b3JpZXMgYXMgd2VsbCwgZ28gdG8gJXMnLCAkdXJsKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdOb3RlIHRoYXQgc3VjaCB0b2tlbnMgaGF2ZSBicm9hZCByZWFkL3dyaXRlIHBlcm1pc3Npb25zIG9uIHlvdXIgYmVoYWxmLCBldmVuIGlmIG5vdCBuZWVkZWQgYnkgQ29tcG9zZXIuJyk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJ1Rva2VucyB3aWxsIGJlIHN0b3JlZCBpbiBwbGFpbiB0ZXh0IGluICIlcyIgZm9yIGZ1dHVyZSB1c2UgYnkgQ29tcG9zZXIuJywgJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpLT5nZXROYW1lKCkpKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0ZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLCBjaGVjayBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvYXV0aGVudGljYXRpb24tZm9yLXByaXZhdGUtcGFja2FnZXMubWQjZ2l0aHViLW9hdXRoJyk7CgogICAgICAgICR0b2tlbiA9IHRyaW0oJHRoaXMtPmlvLT5hc2tBbmRIaWRlQW5zd2VyKCdUb2tlbiAoaGlkZGVuKTogJykpOwoKICAgICAgICBpZiAoISR0b2tlbikgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPk5vIHRva2VuIGdpdmVuLCBhYm9ydGluZy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IGNhbiBhbHNvIGFkZCBpdCBtYW51YWxseSBsYXRlciBieSB1c2luZyAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tYXV0aCBnaXRodWItb2F1dGguZ2l0aHViLmNvbSA8dG9rZW4+IicpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAkdG9rZW4sICd4LW9hdXRoLWJhc2ljJyk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRhcGlVcmwgPSAoJ2dpdGh1Yi5jb20nID09PSAkb3JpZ2luVXJsKSA/ICdhcGkuZ2l0aHViLmNvbS8nIDogJG9yaWdpblVybCAuICcvYXBpL3YzLyc7CgogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgnaHR0cHM6Ly8nLiAkYXBpVXJsLCBhcnJheSgKICAgICAgICAgICAgICAgICdyZXRyeS1hdXRoLWZhaWx1cmUnID0+IGZhbHNlLAogICAgICAgICAgICApKTsKICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRlLT5nZXRDb2RlKCksIGFycmF5KDQwMywgNDAxKSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkludmFsaWQgdG9rZW4gcHJvdmlkZWQuPC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IGNhbiBhbHNvIGFkZCBpdCBtYW51YWxseSBsYXRlciBieSB1c2luZyAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tYXV0aCBnaXRodWItb2F1dGguZ2l0aHViLmNvbSA8dG9rZW4+IicpOwoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpbiB1c2VyIGNvbmZpZwogICAgICAgICR0aGlzLT5jb25maWctPmdldENvbmZpZ1NvdXJjZSgpLT5yZW1vdmVDb25maWdTZXR0aW5nKCdnaXRodWItb2F1dGguJy4kb3JpZ2luVXJsKTsKICAgICAgICAkdGhpcy0+Y29uZmlnLT5nZXRBdXRoQ29uZmlnU291cmNlKCktPmFkZENvbmZpZ1NldHRpbmcoJ2dpdGh1Yi1vYXV0aC4nLiRvcmlnaW5VcmwsICR0b2tlbik7CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGluZm8+VG9rZW4gc3RvcmVkIHN1Y2Nlc3NmdWxseS48L2luZm8+Jyk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCByYXRlIGxpbWl0IGZyb20gcmVzcG9uc2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRoZWFkZXJzIEhlYWRlcnMgZnJvbSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e2xpbWl0OiBpbnR8Jz8nLCByZXNldDogc3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmF0ZUxpbWl0KGFycmF5ICRoZWFkZXJzKQogICAgewogICAgICAgICRyYXRlTGltaXQgPSBhcnJheSgKICAgICAgICAgICAgJ2xpbWl0JyA9PiAnPycsCiAgICAgICAgICAgICdyZXNldCcgPT4gJz8nLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKICAgICAgICAgICAgJGhlYWRlciA9IHRyaW0oJGhlYWRlcik7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gc3RycG9zKCRoZWFkZXIsICdYLVJhdGVMaW1pdC0nKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGlzdCgkdHlwZSwgJHZhbHVlKSA9IGV4cGxvZGUoJzonLCAkaGVhZGVyLCAyKTsKICAgICAgICAgICAgc3dpdGNoICgkdHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAnWC1SYXRlTGltaXQtTGltaXQnOgogICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXRbJ2xpbWl0J10gPSAoaW50KSB0cmltKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdYLVJhdGVMaW1pdC1SZXNldCc6CiAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdFsncmVzZXQnXSA9IGRhdGUoJ1ktbS1kIEg6aTpzJywgKGludCkgdHJpbSgkdmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyYXRlTGltaXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0IFNTTyBVUkwgZnJvbSByZXNwb25zZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGhlYWRlcnMgSGVhZGVycyBmcm9tIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNzb1VybChhcnJheSAkaGVhZGVycykKICAgIHsKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgICRoZWFkZXIgPSB0cmltKCRoZWFkZXIpOwogICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cmlwb3MoJGhlYWRlciwgJ3gtZ2l0aHViLXNzbzogcmVxdWlyZWQnKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3tcYnVybD0oP1A8dXJsPlteXHM7XSspfScsICRoZWFkZXIsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbWF0Y2hbJ3VybCddOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIHdoZXRoZXIgYSByZXF1ZXN0IGZhaWxlZCBkdWUgdG8gcmF0ZSBsaW1pdGluZwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkaGVhZGVycyBIZWFkZXJzIGZyb20gQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb24uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1JhdGVMaW1pdGVkKGFycmF5ICRoZWFkZXJzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teWC1SYXRlTGltaXQtUmVtYWluaW5nOiAqMCR9aScsIHRyaW0oJGhlYWRlcikpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgd2hldGhlciBhIHJlcXVlc3QgZmFpbGVkIGR1ZSB0byBsYWNraW5nIFNTTyBhdXRob3JpemF0aW9uCiAgICAgKgogICAgICogQHNlZSBodHRwczovL2RvY3MuZ2l0aHViLmNvbS9lbi9yZXN0L292ZXJ2aWV3L290aGVyLWF1dGhlbnRpY2F0aW9uLW1ldGhvZHMjYXV0aGVudGljYXRpbmctZm9yLXNhbWwtc3NvCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRoZWFkZXJzIEhlYWRlcnMgZnJvbSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlcXVpcmVzU3NvKGFycmF5ICRoZWFkZXJzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teWC1HaXRIdWItU1NPOiByZXF1aXJlZH1pJywgdHJpbSgkaGVhZGVyKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxYZGVidWdIYW5kbGVyXFhkZWJ1Z0hhbmRsZXI7CgovKioKICogUHJvdmlkZXMgaW5pIGZpbGUgbG9jYXRpb24gZnVuY3Rpb25zIHRoYXQgd29yayB3aXRoIGFuZCB3aXRob3V0IGEgcmVzdGFydC4KICogV2hlbiB0aGUgcHJvY2VzcyBoYXMgcmVzdGFydGVkIGl0IHVzZXMgYSB0bXAgaW5pIGFuZCBzdG9yZXMgdGhlIG9yaWdpbmFsCiAqIGluaSBsb2NhdGlvbnMgaW4gYW4gZW52aXJvbm1lbnQgdmFyaWFibGUuCiAqCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqLwpjbGFzcyBJbmlIZWxwZXIKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHBocC5pbmkgbG9jYXRpb25zIHdpdGggYXQgbGVhc3Qgb25lIGVudHJ5CiAgICAgKgogICAgICogVGhlIGVxdWl2YWxlbnQgb2YgY2FsbGluZyBwaHBfaW5pX2xvYWRlZF9maWxlIHRoZW4gcGhwX2luaV9zY2FubmVkX2ZpbGVzLgogICAgICogVGhlIGxvYWRlZCBpbmkgbG9jYXRpb24gaXMgdGhlIGZpcnN0IGVudHJ5IGFuZCBtYXkgYmUgZW1wdHkuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEFsbCgpCiAgICB7CiAgICAgICAgcmV0dXJuIFhkZWJ1Z0hhbmRsZXI6OmdldEFsbEluaUZpbGVzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgdGhlIGxvY2F0aW9uIG9mIHRoZSBsb2FkZWQgcGhwLmluaSBmaWxlKHMpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRNZXNzYWdlKCkKICAgIHsKICAgICAgICAkcGF0aHMgPSBzZWxmOjpnZXRBbGwoKTsKCiAgICAgICAgaWYgKGVtcHR5KCRwYXRoc1swXSkpIHsKICAgICAgICAgICAgYXJyYXlfc2hpZnQoJHBhdGhzKTsKICAgICAgICB9CgogICAgICAgICRpbmkgPSBhcnJheV9zaGlmdCgkcGF0aHMpOwoKICAgICAgICBpZiAoZW1wdHkoJGluaSkpIHsKICAgICAgICAgICAgcmV0dXJuICdBIHBocC5pbmkgZmlsZSBkb2VzIG5vdCBleGlzdC4gWW91IHdpbGwgaGF2ZSB0byBjcmVhdGUgb25lLic7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRwYXRocykpIHsKICAgICAgICAgICAgcmV0dXJuICdZb3VyIGNvbW1hbmQtbGluZSBQSFAgaXMgdXNpbmcgbXVsdGlwbGUgaW5pIGZpbGVzLiBSdW4gYHBocCAtLWluaWAgdG8gc2hvdyB0aGVtLic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ1RoZSBwaHAuaW5pIHVzZWQgYnkgeW91ciBjb21tYW5kLWxpbmUgUEhQIGlzOiAnLiRpbmk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogQ29tcG9zZXIgbWlycm9yIHV0aWxpdGllcwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDb21wb3Nlck1pcnJvcgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbWlycm9yVXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHZlcnNpb24KICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcmVmZXJlbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHR5cGUKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcHJldHR5VmVyc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvY2Vzc1VybCgkbWlycm9yVXJsLCAkcGFja2FnZU5hbWUsICR2ZXJzaW9uLCAkcmVmZXJlbmNlLCAkdHlwZSwgJHByZXR0eVZlcnNpb24gPSBudWxsKQogICAgewogICAgICAgIGlmICgkcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICRyZWZlcmVuY2UgPSBQcmVnOjppc01hdGNoKCd7XihbYS1mMC05XSp8JXJlZmVyZW5jZSUpJH0nLCAkcmVmZXJlbmNlKSA/ICRyZWZlcmVuY2UgOiBtZDUoJHJlZmVyZW5jZSk7CiAgICAgICAgfQogICAgICAgICR2ZXJzaW9uID0gc3RycG9zKCR2ZXJzaW9uLCAnLycpID09PSBmYWxzZSA/ICR2ZXJzaW9uIDogbWQ1KCR2ZXJzaW9uKTsKCiAgICAgICAgJGZyb20gPSBhcnJheSgnJXBhY2thZ2UlJywgJyV2ZXJzaW9uJScsICclcmVmZXJlbmNlJScsICcldHlwZSUnKTsKICAgICAgICAkdG8gPSBhcnJheSgkcGFja2FnZU5hbWUsICR2ZXJzaW9uLCAkcmVmZXJlbmNlLCAkdHlwZSk7CiAgICAgICAgaWYgKG51bGwgIT09ICRwcmV0dHlWZXJzaW9uKSB7CiAgICAgICAgICAgICRmcm9tW10gPSAnJXByZXR0eVZlcnNpb24lJzsKICAgICAgICAgICAgJHRvW10gPSAkcHJldHR5VmVyc2lvbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgkZnJvbSwgJHRvLCAkbWlycm9yVXJsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbWlycm9yVXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHVybAogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICR0eXBlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9jZXNzR2l0VXJsKCRtaXJyb3JVcmwsICRwYWNrYWdlTmFtZSwgJHVybCwgJHR5cGUpCiAgICB7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyNeKD86KD86aHR0cHM/fGdpdCk6Ly9naXRodWJcLmNvbS98Z2l0QGdpdGh1YlwuY29tOikoW14vXSspLyguKz8pKD86XC5naXQpPyQjJywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICAkdXJsID0gJ2doLScuJG1hdGNoWzFdLicvJy4kbWF0Y2hbMl07CiAgICAgICAgfSBlbHNlaWYgKFByZWc6OmlzTWF0Y2goJyNeaHR0cHM6Ly9iaXRidWNrZXRcLm9yZy8oW14vXSspLyguKz8pKD86XC5naXQpPy8/JCMnLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR1cmwgPSAnYmItJy4kbWF0Y2hbMV0uJy8nLiRtYXRjaFsyXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdXJsID0gUHJlZzo6cmVwbGFjZSgne1teYS16MC05Xy4tXX1pJywgJy0nLCB0cmltKCR1cmwsICcvJykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKAogICAgICAgICAgICBhcnJheSgnJXBhY2thZ2UlJywgJyVub3JtYWxpemVkVXJsJScsICcldHlwZSUnKSwKICAgICAgICAgICAgYXJyYXkoJHBhY2thZ2VOYW1lLCAkdXJsLCAkdHlwZSksCiAgICAgICAgICAgICRtaXJyb3JVcmwKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbWlycm9yVXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlTmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9jZXNzSGdVcmwoJG1pcnJvclVybCwgJHBhY2thZ2VOYW1lLCAkdXJsLCAkdHlwZSkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6cHJvY2Vzc0dpdFVybCgkbWlycm9yVXJsLCAkcGFja2FnZU5hbWUsICR1cmwsICR0eXBlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCmNsYXNzIFBhY2thZ2VTb3J0ZXIKewogICAgLyoqCiAgICAgKiBTb3J0cyBwYWNrYWdlcyBieSBkZXBlbmRlbmN5IHdlaWdodAogICAgICoKICAgICAqIFBhY2thZ2VzIG9mIGVxdWFsIHdlaWdodCByZXRhaW4gdGhlIG9yaWdpbmFsIG9yZGVyCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlW10gJHBhY2thZ2VzCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2VbXSBzb3J0ZWQgYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzb3J0UGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgICR1c2FnZUxpc3QgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCksICRwYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHRhcmdldCA9ICRsaW5rLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgICAgICR1c2FnZUxpc3RbJHRhcmdldF1bXSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGNvbXB1dGluZyA9IGFycmF5KCk7CiAgICAgICAgJGNvbXB1dGVkID0gYXJyYXkoKTsKICAgICAgICAkY29tcHV0ZUltcG9ydGFuY2UgPSBmdW5jdGlvbiAoJG5hbWUpIHVzZSAoJiRjb21wdXRlSW1wb3J0YW5jZSwgJiRjb21wdXRpbmcsICYkY29tcHV0ZWQsICR1c2FnZUxpc3QpIHsKICAgICAgICAgICAgLy8gcmV1c2luZyBjb21wdXRlZCBpbXBvcnRhbmNlCiAgICAgICAgICAgIGlmIChpc3NldCgkY29tcHV0ZWRbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRjb21wdXRlZFskbmFtZV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNhbmNlbGluZyBjaXJjdWxhciBkZXBlbmRlbmN5CiAgICAgICAgICAgIGlmIChpc3NldCgkY29tcHV0aW5nWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29tcHV0aW5nWyRuYW1lXSA9IHRydWU7CiAgICAgICAgICAgICR3ZWlnaHQgPSAwOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCR1c2FnZUxpc3RbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVzYWdlTGlzdFskbmFtZV0gYXMgJHVzZXIpIHsKICAgICAgICAgICAgICAgICAgICAkd2VpZ2h0IC09IDEgLSAkY29tcHV0ZUltcG9ydGFuY2UoJHVzZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB1bnNldCgkY29tcHV0aW5nWyRuYW1lXSk7CiAgICAgICAgICAgICRjb21wdXRlZFskbmFtZV0gPSAkd2VpZ2h0OwoKICAgICAgICAgICAgcmV0dXJuICR3ZWlnaHQ7CiAgICAgICAgfTsKCiAgICAgICAgJHdlaWdodExpc3QgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJGluZGV4ID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICR3ZWlnaHQgPSAkY29tcHV0ZUltcG9ydGFuY2UoJHBhY2thZ2UtPmdldE5hbWUoKSk7CiAgICAgICAgICAgICR3ZWlnaHRMaXN0WyRpbmRleF0gPSAkd2VpZ2h0OwogICAgICAgIH0KCiAgICAgICAgJHN0YWJsZV9zb3J0ID0gZnVuY3Rpb24gKCYkYXJyYXkpIHsKICAgICAgICAgICAgc3RhdGljICR0cmFuc2Zvcm0sICRyZXN0b3JlOwoKICAgICAgICAgICAgJGkgPSAwOwoKICAgICAgICAgICAgaWYgKCEkdHJhbnNmb3JtKSB7CiAgICAgICAgICAgICAgICAkdHJhbnNmb3JtID0gZnVuY3Rpb24gKCYkdiwgJGspIHVzZSAoJiRpKSB7CiAgICAgICAgICAgICAgICAgICAgJHYgPSBhcnJheSgkdiwgKyskaSwgJGssICR2KTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgJHJlc3RvcmUgPSBmdW5jdGlvbiAoJiR2KSB7CiAgICAgICAgICAgICAgICAgICAgJHYgPSAkdlszXTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFycmF5X3dhbGsoJGFycmF5LCAkdHJhbnNmb3JtKTsKICAgICAgICAgICAgYXNvcnQoJGFycmF5KTsKICAgICAgICAgICAgYXJyYXlfd2FsaygkYXJyYXksICRyZXN0b3JlKTsKICAgICAgICB9OwoKICAgICAgICAkc3RhYmxlX3NvcnQoJHdlaWdodExpc3QpOwoKICAgICAgICAkc29ydGVkUGFja2FnZXMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoIChhcnJheV9rZXlzKCR3ZWlnaHRMaXN0KSBhcyAkaW5kZXgpIHsKICAgICAgICAgICAgJHNvcnRlZFBhY2thZ2VzW10gPSAkcGFja2FnZXNbJGluZGV4XTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc29ydGVkUGFja2FnZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBSZWFjdFxQcm9taXNlXENhbmNlbGxhYmxlUHJvbWlzZUludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFByb2dyZXNzQmFyOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIExvb3AKewogICAgLyoqIEB2YXIgSHR0cERvd25sb2FkZXIgKi8KICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yfG51bGwgKi8KICAgIHByaXZhdGUgJHByb2Nlc3NFeGVjdXRvcjsKICAgIC8qKiBAdmFyIFByb21pc2VJbnRlcmZhY2VbXVtdICovCiAgICBwcml2YXRlICRjdXJyZW50UHJvbWlzZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcml2YXRlICR3YWl0SW5kZXggPSAwOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2Vzc0V4ZWN1dG9yID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5lbmFibGVBc3luYygpOwoKICAgICAgICAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yID0gJHByb2Nlc3NFeGVjdXRvcjsKICAgICAgICBpZiAoJHRoaXMtPnByb2Nlc3NFeGVjdXRvcikgewogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yLT5lbmFibGVBc3luYygpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gSHR0cERvd25sb2FkZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEh0dHBEb3dubG9hZGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmh0dHBEb3dubG9hZGVyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQcm9jZXNzRXhlY3V0b3J8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvY2Vzc0V4ZWN1dG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NFeGVjdXRvcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgUHJvbWlzZUludGVyZmFjZVtdICRwcm9taXNlcwogICAgICogQHBhcmFtICA/UHJvZ3Jlc3NCYXIgICAgICAgJHByb2dyZXNzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhaXQoYXJyYXkgJHByb21pc2VzLCBQcm9ncmVzc0JhciAkcHJvZ3Jlc3MgPSBudWxsKQogICAgewogICAgICAgIC8qKiBAdmFyIFxFeGNlcHRpb258bnVsbCAqLwogICAgICAgICR1bmNhdWdodCA9IG51bGw7CgogICAgICAgIFxSZWFjdFxQcm9taXNlXGFsbCgkcHJvbWlzZXMpLT50aGVuKAogICAgICAgICAgICBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGZ1bmN0aW9uICgkZSkgdXNlICgmJHVuY2F1Z2h0KSB7CiAgICAgICAgICAgICAgICAkdW5jYXVnaHQgPSAkZTsKICAgICAgICAgICAgfQogICAgICAgICk7CgogICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgZXZlcnkgZ3JvdXAgb2YgcHJvbWlzZXMgdGhhdCBpcyB3YWl0ZWQgb24sIHNvIGFib3J0Sm9icyBjYW4KICAgICAgICAvLyBjYW5jZWwgdGhlbSBhbGwsIGV2ZW4gaWYgd2FpdCgpIHdhcyBjYWxsZWQgd2l0aGluIGEgd2FpdCgpCiAgICAgICAgJHdhaXRJbmRleCA9ICR0aGlzLT53YWl0SW5kZXgrKzsKICAgICAgICAkdGhpcy0+Y3VycmVudFByb21pc2VzWyR3YWl0SW5kZXhdID0gJHByb21pc2VzOwoKICAgICAgICBpZiAoJHByb2dyZXNzKSB7CiAgICAgICAgICAgICR0b3RhbEpvYnMgPSAwOwogICAgICAgICAgICAkdG90YWxKb2JzICs9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Y291bnRBY3RpdmVKb2JzKCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yKSB7CiAgICAgICAgICAgICAgICAkdG90YWxKb2JzICs9ICR0aGlzLT5wcm9jZXNzRXhlY3V0b3ItPmNvdW50QWN0aXZlSm9icygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwcm9ncmVzcy0+c3RhcnQoJHRvdGFsSm9icyk7CiAgICAgICAgfQoKICAgICAgICAkbGFzdFVwZGF0ZSA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgJGFjdGl2ZUpvYnMgPSAwOwoKICAgICAgICAgICAgJGFjdGl2ZUpvYnMgKz0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5jb3VudEFjdGl2ZUpvYnMoKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5wcm9jZXNzRXhlY3V0b3IpIHsKICAgICAgICAgICAgICAgICRhY3RpdmVKb2JzICs9ICR0aGlzLT5wcm9jZXNzRXhlY3V0b3ItPmNvdW50QWN0aXZlSm9icygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHByb2dyZXNzICYmIG1pY3JvdGltZSh0cnVlKSAtICRsYXN0VXBkYXRlID4gMC4xKSB7CiAgICAgICAgICAgICAgICAkbGFzdFVwZGF0ZSA9IG1pY3JvdGltZSh0cnVlKTsKICAgICAgICAgICAgICAgICRwcm9ncmVzcy0+c2V0UHJvZ3Jlc3MoJHByb2dyZXNzLT5nZXRNYXhTdGVwcygpIC0gJGFjdGl2ZUpvYnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRhY3RpdmVKb2JzKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gYXMgd2Ugc2tpcCBwcm9ncmVzcyB1cGRhdGVzIGlmIHRoZXkgYXJlIHRvbyBxdWljaywgbWFrZSBzdXJlIHdlIGRvIG9uZSBsYXN0IG9uZSBoZXJlIGF0IDEwMCUKICAgICAgICBpZiAoJHByb2dyZXNzKSB7CiAgICAgICAgICAgICRwcm9ncmVzcy0+ZmluaXNoKCk7CiAgICAgICAgfQoKICAgICAgICB1bnNldCgkdGhpcy0+Y3VycmVudFByb21pc2VzWyR3YWl0SW5kZXhdKTsKICAgICAgICBpZiAoJHVuY2F1Z2h0KSB7CiAgICAgICAgICAgIHRocm93ICR1bmNhdWdodDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFib3J0Sm9icygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmN1cnJlbnRQcm9taXNlcyBhcyAkcHJvbWlzZUdyb3VwKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwcm9taXNlR3JvdXAgYXMgJHByb21pc2UpIHsKICAgICAgICAgICAgICAgIGlmICgkcHJvbWlzZSBpbnN0YW5jZW9mIENhbmNlbGxhYmxlUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgICAgICRwcm9taXNlLT5jYW5jZWwoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBVcmwKewogICAgLyoqCiAgICAgKiBAcGFyYW0gIENvbmZpZyAkY29uZmlnCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcmVmCiAgICAgKiBAcmV0dXJuIHN0cmluZyB0aGUgdXBkYXRlZCBVUkwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB1cGRhdGVEaXN0UmVmZXJlbmNlKENvbmZpZyAkY29uZmlnLCAkdXJsLCAkcmVmKQogICAgewogICAgICAgICRob3N0ID0gcGFyc2VfdXJsKCR1cmwsIFBIUF9VUkxfSE9TVCk7CgogICAgICAgIGlmICgkaG9zdCA9PT0gJ2FwaS5naXRodWIuY29tJyB8fCAkaG9zdCA9PT0gJ2dpdGh1Yi5jb20nIHx8ICRob3N0ID09PSAnd3d3LmdpdGh1Yi5jb20nKSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7Xmh0dHBzPzovLyg/Ond3d1wuKT9naXRodWJcLmNvbS8oW14vXSspLyhbXi9dKykvKHppcHx0YXIpYmFsbC8oLispJH1pJywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgLy8gdXBkYXRlIGxlZ2FjeSBnaXRodWIgYXJjaGl2ZXMgdG8gQVBJIGNhbGxzIHdpdGggdGhlIHByb3BlciByZWZlcmVuY2UKICAgICAgICAgICAgICAgICR1cmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8nIC4gJG1hdGNoWzFdIC4gJy8nLiAkbWF0Y2hbMl0gLiAnLycgLiAkbWF0Y2hbM10gLiAnYmFsbC8nIC4gJHJlZjsKICAgICAgICAgICAgfSBlbHNlaWYgKFByZWc6OmlzTWF0Y2goJ3teaHR0cHM/Oi8vKD86d3d3XC4pP2dpdGh1YlwuY29tLyhbXi9dKykvKFteL10rKS9hcmNoaXZlLy4rXC4oemlwfHRhcikoPzpcLmd6KT8kfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgY3VycmVudCBnaXRodWIgd2ViIGFyY2hpdmVzIHRvIEFQSSBjYWxscyB3aXRoIHRoZSBwcm9wZXIgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAkdXJsID0gJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJyAuICRtYXRjaFsxXSAuICcvJy4gJG1hdGNoWzJdIC4gJy8nIC4gJG1hdGNoWzNdIC4gJ2JhbGwvJyAuICRyZWY7CiAgICAgICAgICAgIH0gZWxzZWlmIChQcmVnOjppc01hdGNoKCd7Xmh0dHBzPzovL2FwaVwuZ2l0aHViXC5jb20vcmVwb3MvKFteL10rKS8oW14vXSspLyh6aXB8dGFyKWJhbGwoPzovLispPyR9aScsICR1cmwsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBhcGkgYXJjaGl2ZXMgdG8gdGhlIHByb3BlciByZWZlcmVuY2UKICAgICAgICAgICAgICAgICR1cmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8nIC4gJG1hdGNoWzFdIC4gJy8nLiAkbWF0Y2hbMl0gLiAnLycgLiAkbWF0Y2hbM10gLiAnYmFsbC8nIC4gJHJlZjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkaG9zdCA9PT0gJ2JpdGJ1Y2tldC5vcmcnIHx8ICRob3N0ID09PSAnd3d3LmJpdGJ1Y2tldC5vcmcnKSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7Xmh0dHBzPzovLyg/Ond3d1wuKT9iaXRidWNrZXRcLm9yZy8oW14vXSspLyhbXi9dKykvZ2V0LyguKylcLih6aXB8dGFyXC5nenx0YXJcLmJ6MikkfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgQml0YnVja2V0IGFyY2hpdmVzIHRvIHRoZSBwcm9wZXIgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAkdXJsID0gJ2h0dHBzOi8vYml0YnVja2V0Lm9yZy8nIC4gJG1hdGNoWzFdIC4gJy8nLiAkbWF0Y2hbMl0gLiAnL2dldC8nIC4gJHJlZiAuICcuJyAuICRtYXRjaFs0XTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkaG9zdCA9PT0gJ2dpdGxhYi5jb20nIHx8ICRob3N0ID09PSAnd3d3LmdpdGxhYi5jb20nKSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7Xmh0dHBzPzovLyg/Ond3d1wuKT9naXRsYWJcLmNvbS9hcGkvdlszNF0vcHJvamVjdHMvKFteL10rKS9yZXBvc2l0b3J5L2FyY2hpdmVcLih6aXB8dGFyXC5nenx0YXJcLmJ6Mnx0YXIpXD9zaGE9LiskfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgR2l0bGFiIGFyY2hpdmVzIHRvIHRoZSBwcm9wZXIgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAkdXJsID0gJ2h0dHBzOi8vZ2l0bGFiLmNvbS9hcGkvdjQvcHJvamVjdHMvJyAuICRtYXRjaFsxXSAuICcvcmVwb3NpdG9yeS9hcmNoaXZlLicgLiAkbWF0Y2hbMl0gLiAnP3NoYT0nIC4gJHJlZjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkaG9zdCwgJGNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpLCB0cnVlKSkgewogICAgICAgICAgICAkdXJsID0gUHJlZzo6cmVwbGFjZSgneygvcmVwb3MvW14vXSsvW14vXSsvKHppcHx0YXIpYmFsbCkoPzovLispPyR9aScsICckMS8nLiRyZWYsICR1cmwpOwogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkaG9zdCwgJGNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpLCB0cnVlKSkgewogICAgICAgICAgICAkdXJsID0gUHJlZzo6cmVwbGFjZSgneygvYXBpL3ZbMzRdL3Byb2plY3RzL1teL10rL3JlcG9zaXRvcnkvYXJjaGl2ZVwuKD86emlwfHRhclwuZ3p8dGFyXC5iejJ8dGFyKVw/c2hhPSkuKyR9aScsICckezF9Jy4kcmVmLCAkdXJsKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJHVybAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRPcmlnaW4oQ29uZmlnICRjb25maWcsICR1cmwpCiAgICB7CiAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkdXJsLCAnZmlsZTovLycpKSB7CiAgICAgICAgICAgIHJldHVybiAkdXJsOwogICAgICAgIH0KCiAgICAgICAgJG9yaWdpbiA9IChzdHJpbmcpIHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX0hPU1QpOwogICAgICAgIGlmICgkcG9ydCA9IHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1BPUlQpKSB7CiAgICAgICAgICAgICRvcmlnaW4gLj0gJzonLiRwb3J0OwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkb3JpZ2luLCAnLmdpdGh1Yi5jb20nKSA9PT0gKHN0cmxlbigkb3JpZ2luKSAtIDExKSkgewogICAgICAgICAgICByZXR1cm4gJ2dpdGh1Yi5jb20nOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRvcmlnaW4gPT09ICdyZXBvLnBhY2thZ2lzdC5vcmcnKSB7CiAgICAgICAgICAgIHJldHVybiAncGFja2FnaXN0Lm9yZyc7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG9yaWdpbiA9PT0gJycpIHsKICAgICAgICAgICAgJG9yaWdpbiA9ICR1cmw7CiAgICAgICAgfQoKICAgICAgICAvLyBHaXRsYWIgY2FuIGJlIGluc3RhbGxlZCBpbiBhIG5vbi1yb290IGNvbnRleHQgKGkuZS4gZ2l0bGFiLmNvbS9mb28pLiBXaGVuIGRvd25sb2FkaW5nIGFyY2hpdmVzIHRoZSBvcmlnaW5VcmwKICAgICAgICAvLyBpcyB0aGUgaG9zdCB3aXRob3V0IHRoZSBwYXRoLCBzbyB3ZSBsb29rIGZvciB0aGUgcmVnaXN0ZXJlZCBnaXRsYWItZG9tYWlucyBtYXRjaGluZyB0aGUgaG9zdCBoZXJlCiAgICAgICAgaWYgKAogICAgICAgICAgICBpc19hcnJheSgkY29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJykpCiAgICAgICAgICAgICYmIGZhbHNlID09PSBzdHJwb3MoJG9yaWdpbiwgJy8nKQogICAgICAgICAgICAmJiAhaW5fYXJyYXkoJG9yaWdpbiwgJGNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpKQogICAgICAgICkgewogICAgICAgICAgICBmb3JlYWNoICgkY29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJykgYXMgJGdpdGxhYkRvbWFpbikgewogICAgICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkZ2l0bGFiRG9tYWluLCAkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZ2l0bGFiRG9tYWluOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG9yaWdpbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICR1cmwKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FuaXRpemUoJHVybCkKICAgIHsKICAgICAgICAvLyBHaXRIdWIgcmVwb3NpdG9yeSByZW5hbWUgcmVzdWx0IGluIHJlZGlyZWN0IGxvY2F0aW9ucyBjb250YWluaW5nIHRoZSBhY2Nlc3NfdG9rZW4gYXMgR0VUIHBhcmFtZXRlcgogICAgICAgIC8vIGUuZy4gaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvc2l0b3JpZXMvOTk5OTk5OTk5OT9hY2Nlc3NfdG9rZW49Z2l0aHViX3Rva2VuCiAgICAgICAgJHVybCA9IFByZWc6OnJlcGxhY2UoJ3soWyY/XWFjY2Vzc190b2tlbj0pW14mXSt9JywgJyQxKioqJywgJHVybCk7CgogICAgICAgICR1cmwgPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJ3teKD9QPHByZWZpeD5bYS16MC05XSs6Ly8pPyg/UDx1c2VyPlteOi9cc0BdKyk6KD9QPHBhc3N3b3JkPlteQFxzL10rKUB9aScsIGZ1bmN0aW9uICgkbSkgewogICAgICAgICAgICAvLyBpZiB0aGUgdXNlcm5hbWUgbG9va3MgbGlrZSBhIGxvbmcgKDEyY2hhcispIGhleCBzdHJpbmcsIG9yIGEgbW9kZXJuIGdpdGh1YiB0b2tlbiAoZS5nLiBnaHBfeHh4KSB3ZSBvYmZ1c2NhdGUgdGhhdAogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne14oW2EtZjAtOV17MTIsfXxnaFthLXpdX1thLXpBLVowLTlfXSspJH0nLCAkbVsndXNlciddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRtWydwcmVmaXgnXS4nKioqOioqKkAnOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG1bJ3ByZWZpeCddLiRtWyd1c2VyJ10uJzoqKipAJzsKICAgICAgICB9LCAkdXJsKTsKCiAgICAgICAgcmV0dXJuICR1cmw7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXI7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnXENvbmZpZ1NvdXJjZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ29uZmlnCnsKICAgIGNvbnN0IFNPVVJDRV9ERUZBVUxUID0gJ2RlZmF1bHQnOwogICAgY29uc3QgU09VUkNFX0NPTU1BTkQgPSAnY29tbWFuZCc7CiAgICBjb25zdCBTT1VSQ0VfVU5LTk9XTiA9ICd1bmtub3duJzsKCiAgICBjb25zdCBSRUxBVElWRV9QQVRIUyA9IDE7CgogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBtaXhlZD4gKi8KICAgIHB1YmxpYyBzdGF0aWMgJGRlZmF1bHRDb25maWcgPSBhcnJheSgKICAgICAgICAncHJvY2Vzcy10aW1lb3V0JyA9PiAzMDAsCiAgICAgICAgJ3VzZS1pbmNsdWRlLXBhdGgnID0+IGZhbHNlLAogICAgICAgICdhbGxvdy1wbHVnaW5zJyA9PiBudWxsLCAvLyBudWxsIGZvciBCQyBmb3Igbm93LCB3aWxsIGJlY29tZSBhcnJheSgpIGFmdGVyIEp1bHkgMjAyMgogICAgICAgICd1c2UtcGFyZW50LWRpcicgPT4gJ3Byb21wdCcsCiAgICAgICAgJ3ByZWZlcnJlZC1pbnN0YWxsJyA9PiAnZGlzdCcsCiAgICAgICAgJ25vdGlmeS1vbi1pbnN0YWxsJyA9PiB0cnVlLAogICAgICAgICdnaXRodWItcHJvdG9jb2xzJyA9PiBhcnJheSgnaHR0cHMnLCAnc3NoJywgJ2dpdCcpLAogICAgICAgICdnaXRsYWItcHJvdG9jb2wnID0+IG51bGwsCiAgICAgICAgJ3ZlbmRvci1kaXInID0+ICd2ZW5kb3InLAogICAgICAgICdiaW4tZGlyJyA9PiAneyR2ZW5kb3ItZGlyfS9iaW4nLAogICAgICAgICdjYWNoZS1kaXInID0+ICd7JGhvbWV9L2NhY2hlJywKICAgICAgICAnZGF0YS1kaXInID0+ICd7JGhvbWV9JywKICAgICAgICAnY2FjaGUtZmlsZXMtZGlyJyA9PiAneyRjYWNoZS1kaXJ9L2ZpbGVzJywKICAgICAgICAnY2FjaGUtcmVwby1kaXInID0+ICd7JGNhY2hlLWRpcn0vcmVwbycsCiAgICAgICAgJ2NhY2hlLXZjcy1kaXInID0+ICd7JGNhY2hlLWRpcn0vdmNzJywKICAgICAgICAnY2FjaGUtdHRsJyA9PiAxNTU1MjAwMCwgLy8gNiBtb250aHMKICAgICAgICAnY2FjaGUtZmlsZXMtdHRsJyA9PiBudWxsLCAvLyBmYWxsYmFjayB0byBjYWNoZS10dGwKICAgICAgICAnY2FjaGUtZmlsZXMtbWF4c2l6ZScgPT4gJzMwME1pQicsCiAgICAgICAgJ2NhY2hlLXJlYWQtb25seScgPT4gZmFsc2UsCiAgICAgICAgJ2Jpbi1jb21wYXQnID0+ICdhdXRvJywKICAgICAgICAnZGlzY2FyZC1jaGFuZ2VzJyA9PiBmYWxzZSwKICAgICAgICAnYXV0b2xvYWRlci1zdWZmaXgnID0+IG51bGwsCiAgICAgICAgJ3NvcnQtcGFja2FnZXMnID0+IGZhbHNlLAogICAgICAgICdvcHRpbWl6ZS1hdXRvbG9hZGVyJyA9PiBmYWxzZSwKICAgICAgICAnY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScgPT4gZmFsc2UsCiAgICAgICAgJ2FwY3UtYXV0b2xvYWRlcicgPT4gZmFsc2UsCiAgICAgICAgJ3ByZXBlbmQtYXV0b2xvYWRlcicgPT4gdHJ1ZSwKICAgICAgICAnZ2l0aHViLWRvbWFpbnMnID0+IGFycmF5KCdnaXRodWIuY29tJyksCiAgICAgICAgJ2JpdGJ1Y2tldC1leHBvc2UtaG9zdG5hbWUnID0+IHRydWUsCiAgICAgICAgJ2Rpc2FibGUtdGxzJyA9PiBmYWxzZSwKICAgICAgICAnc2VjdXJlLWh0dHAnID0+IHRydWUsCiAgICAgICAgJ3NlY3VyZS1zdm4tZG9tYWlucycgPT4gYXJyYXkoKSwKICAgICAgICAnY2FmaWxlJyA9PiBudWxsLAogICAgICAgICdjYXBhdGgnID0+IG51bGwsCiAgICAgICAgJ2dpdGh1Yi1leHBvc2UtaG9zdG5hbWUnID0+IHRydWUsCiAgICAgICAgJ2dpdGxhYi1kb21haW5zJyA9PiBhcnJheSgnZ2l0bGFiLmNvbScpLAogICAgICAgICdzdG9yZS1hdXRocycgPT4gJ3Byb21wdCcsCiAgICAgICAgJ3BsYXRmb3JtJyA9PiBhcnJheSgpLAogICAgICAgICdhcmNoaXZlLWZvcm1hdCcgPT4gJ3RhcicsCiAgICAgICAgJ2FyY2hpdmUtZGlyJyA9PiAnLicsCiAgICAgICAgJ2h0YWNjZXNzLXByb3RlY3QnID0+IHRydWUsCiAgICAgICAgJ3VzZS1naXRodWItYXBpJyA9PiB0cnVlLAogICAgICAgICdsb2NrJyA9PiB0cnVlLAogICAgICAgICdwbGF0Zm9ybS1jaGVjaycgPT4gJ3BocC1vbmx5JywKICAgICAgICAvLyB2YWxpZCBrZXlzIHdpdGhvdXQgZGVmYXVsdHMgKGF1dGggY29uZmlnIHN0dWZmKToKICAgICAgICAvLyBiaXRidWNrZXQtb2F1dGgKICAgICAgICAvLyBnaXRodWItb2F1dGgKICAgICAgICAvLyBnaXRsYWItb2F1dGgKICAgICAgICAvLyBnaXRsYWItdG9rZW4KICAgICAgICAvLyBodHRwLWJhc2ljCiAgICAgICAgLy8gYmVhcmVyCiAgICApOwoKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgbWl4ZWQ+ICovCiAgICBwdWJsaWMgc3RhdGljICRkZWZhdWx0UmVwb3NpdG9yaWVzID0gYXJyYXkoCiAgICAgICAgJ3BhY2thZ2lzdC5vcmcnID0+IGFycmF5KAogICAgICAgICAgICAndHlwZScgPT4gJ2NvbXBvc2VyJywKICAgICAgICAgICAgJ3VybCcgPT4gJ2h0dHBzOi8vcmVwby5wYWNrYWdpc3Qub3JnJywKICAgICAgICApLAogICAgKTsKCiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIG1peGVkPiAqLwogICAgcHJpdmF0ZSAkY29uZmlnOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJpdmF0ZSAkYmFzZURpcjsKICAgIC8qKiBAdmFyIGFycmF5PGludHxzdHJpbmcsIG1peGVkPiAqLwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yaWVzOwogICAgLyoqIEB2YXIgQ29uZmlnU291cmNlSW50ZXJmYWNlICovCiAgICBwcml2YXRlICRjb25maWdTb3VyY2U7CiAgICAvKiogQHZhciBDb25maWdTb3VyY2VJbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGF1dGhDb25maWdTb3VyY2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICR1c2VFbnZpcm9ubWVudDsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgdHJ1ZT4gKi8KICAgIHByaXZhdGUgJHdhcm5lZEhvc3RzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgc3RyaW5nPiAqLwogICAgcHJpdmF0ZSAkc291cmNlT2ZDb25maWdWYWx1ZSA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAgICR1c2VFbnZpcm9ubWVudCBVc2UgQ09NUE9TRVJfIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byByZXBsYWNlIGNvbmZpZyBzZXR0aW5ncwogICAgICogQHBhcmFtIHN0cmluZyAkYmFzZURpciAgICAgICAgT3B0aW9uYWwgYmFzZSBkaXJlY3Rvcnkgb2YgdGhlIGNvbmZpZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVzZUVudmlyb25tZW50ID0gdHJ1ZSwgJGJhc2VEaXIgPSBudWxsKQogICAgewogICAgICAgIC8vIGxvYWQgZGVmYXVsdHMKICAgICAgICAkdGhpcy0+Y29uZmlnID0gc3RhdGljOjokZGVmYXVsdENvbmZpZzsKCiAgICAgICAgLy8gVE9ETyBhZnRlciBKdWx5IDIwMjIgcmVtb3ZlIHRoaXMgYW5kIHVwZGF0ZSB0aGUgZGVmYXVsdCB2YWx1ZSBhYm92ZSBpbiBzZWxmOjokZGVmYXVsdENvbmZpZyArIHJlbW92ZSBub3RlIGZyb20gMDYtY29uZmlnLm1kCiAgICAgICAgaWYgKHN0cnRvdGltZSgnMjAyMi0wNy0wMScpIDwgdGltZSgpKSB7CiAgICAgICAgICAgICR0aGlzLT5jb25maWdbJ2FsbG93LXBsdWdpbnMnXSA9IGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzID0gc3RhdGljOjokZGVmYXVsdFJlcG9zaXRvcmllczsKICAgICAgICAkdGhpcy0+dXNlRW52aXJvbm1lbnQgPSAoYm9vbCkgJHVzZUVudmlyb25tZW50OwogICAgICAgICR0aGlzLT5iYXNlRGlyID0gJGJhc2VEaXI7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWcgYXMgJGNvbmZpZ0tleSA9PiAkY29uZmlnVmFsdWUpIHsKICAgICAgICAgICAgJHRoaXMtPnNldFNvdXJjZU9mQ29uZmlnVmFsdWUoJGNvbmZpZ1ZhbHVlLCAkY29uZmlnS2V5LCBzZWxmOjpTT1VSQ0VfREVGQVVMVCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRjb25maWdLZXkgPT4gJGNvbmZpZ1ZhbHVlKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRTb3VyY2VPZkNvbmZpZ1ZhbHVlKCRjb25maWdWYWx1ZSwgJ3JlcG9zaXRvcmllcy4nIC4gJGNvbmZpZ0tleSwgc2VsZjo6U09VUkNFX0RFRkFVTFQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uZmlnU291cmNlKENvbmZpZ1NvdXJjZUludGVyZmFjZSAkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UgPSAkc291cmNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25maWdTb3VyY2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZpZ1NvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25maWdTb3VyY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dGhDb25maWdTb3VyY2UoQ29uZmlnU291cmNlSW50ZXJmYWNlICRzb3VyY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmF1dGhDb25maWdTb3VyY2UgPSAkc291cmNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25maWdTb3VyY2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dGhDb25maWdTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXV0aENvbmZpZ1NvdXJjZTsKICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlcyBuZXcgY29uZmlnIHZhbHVlcyB3aXRoIHRoZSBleGlzdGluZyBvbmVzIChvdmVycmlkaW5nKQogICAgICoKICAgICAqIEBwYXJhbSBhcnJheXtjb25maWc/OiBhcnJheTxzdHJpbmcsIG1peGVkPiwgcmVwb3NpdG9yaWVzPzogYXJyYXk8bWl4ZWQ+fSAkY29uZmlnCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1lcmdlKCRjb25maWcsICRzb3VyY2UgPSBzZWxmOjpTT1VSQ0VfVU5LTk9XTikKICAgIHsKICAgICAgICAvLyBvdmVycmlkZSBkZWZhdWx0cyB3aXRoIGdpdmVuIGNvbmZpZwogICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snY29uZmlnJ10pICYmIGlzX2FycmF5KCRjb25maWdbJ2NvbmZpZyddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkY29uZmlnWydjb25maWcnXSBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgka2V5LCBhcnJheSgnYml0YnVja2V0LW9hdXRoJywgJ2dpdGh1Yi1vYXV0aCcsICdnaXRsYWItb2F1dGgnLCAnZ2l0bGFiLXRva2VuJywgJ2h0dHAtYmFzaWMnLCAnYmVhcmVyJyksIHRydWUpICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1ska2V5XSA9IGFycmF5X21lcmdlKCR0aGlzLT5jb25maWdbJGtleV0sICR2YWwpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zZXRTb3VyY2VPZkNvbmZpZ1ZhbHVlKCR2YWwsICRrZXksICRzb3VyY2UpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCRrZXksIGFycmF5KCdhbGxvdy1wbHVnaW5zJyksIHRydWUpICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJGtleV0pICYmIGlzX2FycmF5KCR0aGlzLT5jb25maWdbJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbWVyZ2luZyAkdmFsIGZpcnN0IHRvIGdldCB0aGUgbG9jYWwgY29uZmlnIG9uIHRvcCBvZiB0aGUgZ2xvYmFsIG9uZSwgdGhlbiBhcHBlbmRpbmcgdGhlIGdsb2JhbCBjb25maWcsCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiBtZXJnaW5nIGxvY2FsIG9uZSBhZ2FpbiB0byBtYWtlIHN1cmUgdGhlIHZhbHVlcyBmcm9tIGxvY2FsIHdpbiBvdmVyIGdsb2JhbCBvbmVzIGZvciBrZXlzIHByZXNlbnQgaW4gYm90aAogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdbJGtleV0gPSBhcnJheV9tZXJnZSgkdmFsLCAkdGhpcy0+Y29uZmlnWyRrZXldLCAkdmFsKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2V0U291cmNlT2ZDb25maWdWYWx1ZSgkdmFsLCAka2V5LCAkc291cmNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgka2V5LCBhcnJheSgnZ2l0bGFiLWRvbWFpbnMnLCAnZ2l0aHViLWRvbWFpbnMnKSwgdHJ1ZSkgJiYgaXNzZXQoJHRoaXMtPmNvbmZpZ1ska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldID0gYXJyYXlfdW5pcXVlKGFycmF5X21lcmdlKCR0aGlzLT5jb25maWdbJGtleV0sICR2YWwpKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2V0U291cmNlT2ZDb25maWdWYWx1ZSgkdmFsLCAka2V5LCAkc291cmNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgncHJlZmVycmVkLWluc3RhbGwnID09PSAka2V5ICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWwpIHx8IGlzX2FycmF5KCR0aGlzLT5jb25maWdbJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHZhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWwgPSBhcnJheSgnKicgPT4gJHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdGhpcy0+Y29uZmlnWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1ska2V5XSA9IGFycmF5KCcqJyA9PiAkdGhpcy0+Y29uZmlnWyRrZXldKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zb3VyY2VPZkNvbmZpZ1ZhbHVlWyRrZXkgLiAnKiddID0gJHNvdXJjZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldID0gYXJyYXlfbWVyZ2UoJHRoaXMtPmNvbmZpZ1ska2V5XSwgJHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zZXRTb3VyY2VPZkNvbmZpZ1ZhbHVlKCR2YWwsICRrZXksICRzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZnVsbCBtYXRjaCBwYXR0ZXJuIG5lZWRzIHRvIGJlIGxhc3QKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25maWdbJGtleV1bJyonXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR3aWxkY2FyZCA9ICR0aGlzLT5jb25maWdbJGtleV1bJyonXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJGtleV1bJyonXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldWycqJ10gPSAkd2lsZGNhcmQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldID0gJHZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNldFNvdXJjZU9mQ29uZmlnVmFsdWUoJHZhbCwgJGtleSwgJHNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldID0gJHZhbDsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2V0U291cmNlT2ZDb25maWdWYWx1ZSgkdmFsLCAka2V5LCAkc291cmNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydyZXBvc2l0b3JpZXMnXSkgJiYgaXNfYXJyYXkoJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXMgPSBhcnJheV9yZXZlcnNlKCR0aGlzLT5yZXBvc2l0b3JpZXMsIHRydWUpOwogICAgICAgICAgICAkbmV3UmVwb3MgPSBhcnJheV9yZXZlcnNlKCRjb25maWdbJ3JlcG9zaXRvcmllcyddLCB0cnVlKTsKICAgICAgICAgICAgZm9yZWFjaCAoJG5ld1JlcG9zIGFzICRuYW1lID0+ICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICAvLyBkaXNhYmxlIGEgcmVwb3NpdG9yeSBieSBuYW1lCiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRpc2FibGVSZXBvQnlOYW1lKChzdHJpbmcpICRuYW1lKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBkaXNhYmxlIGEgcmVwb3NpdG9yeSB3aXRoIGFuIGFub255bW91cyB7Im5hbWUiOiBmYWxzZX0gcmVwbwogICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCRyZXBvc2l0b3J5KSAmJiAxID09PSBjb3VudCgkcmVwb3NpdG9yeSkgJiYgZmFsc2UgPT09IGN1cnJlbnQoJHJlcG9zaXRvcnkpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRpc2FibGVSZXBvQnlOYW1lKChzdHJpbmcpIGtleSgkcmVwb3NpdG9yeSkpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGF1dG8tZGVhY3RpdmF0ZSB0aGUgZGVmYXVsdCBwYWNrYWdpc3Qub3JnIHJlcG8gaWYgaXQgZ2V0cyByZWRlZmluZWQKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcmVwb3NpdG9yeVsndHlwZSddLCAkcmVwb3NpdG9yeVsndXJsJ10pICYmICRyZXBvc2l0b3J5Wyd0eXBlJ10gPT09ICdjb21wb3NlcicgJiYgUHJlZzo6aXNNYXRjaCgne15odHRwcz86Ly8oPzpbYS16MC05LS5dK1wuKT9wYWNrYWdpc3Qub3JnKC98JCl9JywgJHJlcG9zaXRvcnlbJ3VybCddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kaXNhYmxlUmVwb0J5TmFtZSgncGFja2FnaXN0Lm9yZycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHN0b3JlIHJlcG8KICAgICAgICAgICAgICAgIGlmIChpc19pbnQoJG5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllc1tdID0gJHJlcG9zaXRvcnk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNldFNvdXJjZU9mQ29uZmlnVmFsdWUoJHJlcG9zaXRvcnksICdyZXBvc2l0b3JpZXMuJyAuIGFycmF5X3NlYXJjaCgkcmVwb3NpdG9yeSwgJHRoaXMtPnJlcG9zaXRvcmllcywgdHJ1ZSksICRzb3VyY2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJG5hbWUgPT09ICdwYWNrYWdpc3QnKSB7IC8vIEJDIHN1cHBvcnQgZm9yIGRlZmF1bHQgInBhY2thZ2lzdCIgbmFtZWQgcmVwbwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzWyRuYW1lIC4gJy5vcmcnXSA9ICRyZXBvc2l0b3J5OwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2V0U291cmNlT2ZDb25maWdWYWx1ZSgkcmVwb3NpdG9yeSwgJ3JlcG9zaXRvcmllcy4nIC4gJG5hbWUgLiAnLm9yZycsICRzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXNbJG5hbWVdID0gJHJlcG9zaXRvcnk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zZXRTb3VyY2VPZkNvbmZpZ1ZhbHVlKCRyZXBvc2l0b3J5LCAncmVwb3NpdG9yaWVzLicgLiAkbmFtZSwgJHNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXMgPSBhcnJheV9yZXZlcnNlKCR0aGlzLT5yZXBvc2l0b3JpZXMsIHRydWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXk8aW50fHN0cmluZywgbWl4ZWQ+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3JpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb3NpdG9yaWVzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldHRpbmcKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRrZXkKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgICAgICAgJGZsYWdzIE9wdGlvbnMgKHNlZSBjbGFzcyBjb25zdGFudHMpCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0KCRrZXksICRmbGFncyA9IDApCiAgICB7CiAgICAgICAgc3dpdGNoICgka2V5KSB7CiAgICAgICAgICAgIC8vIHN0cmluZ3MvcGF0aHMgd2l0aCBlbnYgdmFyIGFuZCB7JHJlZnN9IHN1cHBvcnQKICAgICAgICAgICAgY2FzZSAndmVuZG9yLWRpcic6CiAgICAgICAgICAgIGNhc2UgJ2Jpbi1kaXInOgogICAgICAgICAgICBjYXNlICdwcm9jZXNzLXRpbWVvdXQnOgogICAgICAgICAgICBjYXNlICdkYXRhLWRpcic6CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLWRpcic6CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLWZpbGVzLWRpcic6CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLXJlcG8tZGlyJzoKICAgICAgICAgICAgY2FzZSAnY2FjaGUtdmNzLWRpcic6CiAgICAgICAgICAgIGNhc2UgJ2NhZmlsZSc6CiAgICAgICAgICAgIGNhc2UgJ2NhcGF0aCc6CiAgICAgICAgICAgICAgICAvLyBjb252ZXJ0IGZvby1iYXIgdG8gQ09NUE9TRVJfRk9PX0JBUiBhbmQgY2hlY2sgaWYgaXQgZXhpc3RzIHNpbmNlIGl0IG92ZXJyaWRlcyB0aGUgbG9jYWwgY29uZmlnCiAgICAgICAgICAgICAgICAkZW52ID0gJ0NPTVBPU0VSXycgLiBzdHJ0b3VwcGVyKHN0cnRyKCRrZXksICctJywgJ18nKSk7CgogICAgICAgICAgICAgICAgJHZhbCA9ICR0aGlzLT5nZXRDb21wb3NlckVudigkZW52KTsKICAgICAgICAgICAgICAgIGlmICgkdmFsICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zZXRTb3VyY2VPZkNvbmZpZ1ZhbHVlKCR2YWwsICRrZXksICRlbnYpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR2YWwgPSBydHJpbSgoc3RyaW5nKSAkdGhpcy0+cHJvY2VzcyhmYWxzZSAhPT0gJHZhbCA/ICR2YWwgOiAkdGhpcy0+Y29uZmlnWyRrZXldLCAkZmxhZ3MpLCAnL1xcJyk7CiAgICAgICAgICAgICAgICAkdmFsID0gUGxhdGZvcm06OmV4cGFuZFBhdGgoJHZhbCk7CgogICAgICAgICAgICAgICAgaWYgKHN1YnN0cigka2V5LCAtNCkgIT09ICctZGlyJykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAoKCRmbGFncyAmIHNlbGY6OlJFTEFUSVZFX1BBVEhTKSA9PSBzZWxmOjpSRUxBVElWRV9QQVRIUykgPyAkdmFsIDogJHRoaXMtPnJlYWxwYXRoKCR2YWwpOwoKICAgICAgICAgICAgLy8gYm9vbGVhbnMgd2l0aCBlbnYgdmFyIHN1cHBvcnQKICAgICAgICAgICAgY2FzZSAnY2FjaGUtcmVhZC1vbmx5JzoKICAgICAgICAgICAgY2FzZSAnaHRhY2Nlc3MtcHJvdGVjdCc6CiAgICAgICAgICAgICAgICAvLyBjb252ZXJ0IGZvby1iYXIgdG8gQ09NUE9TRVJfRk9PX0JBUiBhbmQgY2hlY2sgaWYgaXQgZXhpc3RzIHNpbmNlIGl0IG92ZXJyaWRlcyB0aGUgbG9jYWwgY29uZmlnCiAgICAgICAgICAgICAgICAkZW52ID0gJ0NPTVBPU0VSXycgLiBzdHJ0b3VwcGVyKHN0cnRyKCRrZXksICctJywgJ18nKSk7CgogICAgICAgICAgICAgICAgJHZhbCA9ICR0aGlzLT5nZXRDb21wb3NlckVudigkZW52KTsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHZhbCkgewogICAgICAgICAgICAgICAgICAgICR2YWwgPSAkdGhpcy0+Y29uZmlnWyRrZXldOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2V0U291cmNlT2ZDb25maWdWYWx1ZSgkdmFsLCAka2V5LCAkZW52KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHZhbDsKCiAgICAgICAgICAgIC8vIGJvb2xlYW5zIHdpdGhvdXQgZW52IHZhciBzdXBwb3J0CiAgICAgICAgICAgIGNhc2UgJ2Rpc2FibGUtdGxzJzoKICAgICAgICAgICAgY2FzZSAnc2VjdXJlLWh0dHAnOgogICAgICAgICAgICBjYXNlICd1c2UtZ2l0aHViLWFwaSc6CiAgICAgICAgICAgIGNhc2UgJ2xvY2snOgogICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlIGZvciBzZWN1cmUtaHR0cAogICAgICAgICAgICAgICAgaWYgKCRrZXkgPT09ICdzZWN1cmUtaHR0cCcgJiYgJHRoaXMtPmdldCgnZGlzYWJsZS10bHMnKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmZpZ1ska2V5XSAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHRoaXMtPmNvbmZpZ1ska2V5XTsKCiAgICAgICAgICAgIC8vIGludHMgd2l0aG91dCBlbnYgdmFyIHN1cHBvcnQKICAgICAgICAgICAgY2FzZSAnY2FjaGUtdHRsJzoKICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+Y29uZmlnWyRrZXldOwoKICAgICAgICAgICAgLy8gbnVtYmVycyB3aXRoIGtiL21iL2diIHN1cHBvcnQsIHdpdGhvdXQgZW52IHZhciBzdXBwb3J0CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLWZpbGVzLW1heHNpemUnOgogICAgICAgICAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCcvXlxzKihbMC05Ll0rKVxzKig/Oihba21nXSkoPzppP2IpPyk/XHMqJC9pJywgJHRoaXMtPmNvbmZpZ1ska2V5XSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IHBhcnNlIHRoZSB2YWx1ZSBvZiAnJGtleSc6IHskdGhpcy0+Y29uZmlnWyRrZXldfSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHNpemUgPSAkbWF0Y2hlc1sxXTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN0cnRvbG93ZXIoJG1hdGNoZXNbMl0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2cnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNpemUgKj0gMTAyNDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludGVudGlvbmFsIGZhbGx0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBicmVhawogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdtJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzaXplICo9IDEwMjQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRlbnRpb25hbCBmYWxsdGhyb3VnaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gYnJlYWsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnayc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2l6ZSAqPSAxMDI0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkc2l6ZTsKCiAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZXMgYmVsb3cKICAgICAgICAgICAgY2FzZSAnY2FjaGUtZmlsZXMtdHRsJzoKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+Y29uZmlnWyRrZXldOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+Y29uZmlnWydjYWNoZS10dGwnXTsKCiAgICAgICAgICAgIGNhc2UgJ2hvbWUnOgogICAgICAgICAgICAgICAgJHZhbCA9IFByZWc6OnJlcGxhY2UoJyNeKFwkSE9NRXx+KSgvfCQpIycsIHJ0cmltKFBsYXRmb3JtOjpnZXRFbnYoJ0hPTUUnKSA/OiBQbGF0Zm9ybTo6Z2V0RW52KCdVU0VSUFJPRklMRScpLCAnL1xcJykgLiAnLycsICR0aGlzLT5jb25maWdbJGtleV0pOwoKICAgICAgICAgICAgICAgIHJldHVybiBydHJpbSgkdGhpcy0+cHJvY2VzcygkdmFsLCAkZmxhZ3MpLCAnL1xcJyk7CgogICAgICAgICAgICBjYXNlICdiaW4tY29tcGF0JzoKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5nZXRDb21wb3NlckVudignQ09NUE9TRVJfQklOX0NPTVBBVCcpID86ICR0aGlzLT5jb25maWdbJGtleV07CgogICAgICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkdmFsdWUsIGFycmF5KCdhdXRvJywgJ2Z1bGwnLCAncHJveHknLCAnc3ltbGluaycpKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgdmFsdWUgZm9yICdiaW4tY29tcGF0JzogeyR2YWx1ZX0uIEV4cGVjdGVkIGF1dG8sIGZ1bGwgb3IgcHJveHkiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHZhbHVlID09PSAnc3ltbGluaycpIHsKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdjb25maWcuYmluLWNvbXBhdCAic3ltbGluayIgaXMgZGVwcmVjYXRlZCBzaW5jZSBDb21wb3NlciAyLjIsIHVzZSBhdXRvLCBmdWxsIChmb3IgV2luZG93cyBjb21wYXRpYmlsaXR5KSBvciBwcm94eSBpbnN0ZWFkLicsIEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbHVlOwoKICAgICAgICAgICAgY2FzZSAnZGlzY2FyZC1jaGFuZ2VzJzoKICAgICAgICAgICAgICAgIGlmICgkZW52ID0gJHRoaXMtPmdldENvbXBvc2VyRW52KCdDT01QT1NFUl9ESVNDQVJEX0NIQU5HRVMnKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJGVudiwgYXJyYXkoJ3N0YXNoJywgJ3RydWUnLCAnZmFsc2UnLCAnMScsICcwJyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHZhbHVlIGZvciBDT01QT1NFUl9ESVNDQVJEX0NIQU5HRVM6IHskZW52fS4gRXhwZWN0ZWQgMSwgMCwgdHJ1ZSwgZmFsc2Ugb3Igc3Rhc2giCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgnc3Rhc2gnID09PSAkZW52KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnc3Rhc2gnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gY29udmVydCBzdHJpbmcgdmFsdWUgdG8gYm9vbAogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZW52ICE9PSAnZmFsc2UnICYmIChib29sKSAkZW52OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHRoaXMtPmNvbmZpZ1ska2V5XSwgYXJyYXkodHJ1ZSwgZmFsc2UsICdzdGFzaCcpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgdmFsdWUgZm9yICdkaXNjYXJkLWNoYW5nZXMnOiB7JHRoaXMtPmNvbmZpZ1ska2V5XX0uIEV4cGVjdGVkIHRydWUsIGZhbHNlIG9yIHN0YXNoIgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb25maWdbJGtleV07CgogICAgICAgICAgICBjYXNlICdnaXRodWItcHJvdG9jb2xzJzoKICAgICAgICAgICAgICAgICRwcm90b3MgPSAkdGhpcy0+Y29uZmlnWydnaXRodWItcHJvdG9jb2xzJ107CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbmZpZ1snc2VjdXJlLWh0dHAnXSAmJiBmYWxzZSAhPT0gKCRpbmRleCA9IGFycmF5X3NlYXJjaCgnZ2l0JywgJHByb3RvcykpKSB7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHByb3Rvc1skaW5kZXhdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChyZXNldCgkcHJvdG9zKSA9PT0gJ2h0dHAnKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgaHR0cCBwcm90b2NvbCBmb3IgZ2l0aHViIGlzIG5vdCBhdmFpbGFibGUgYW55bW9yZSwgdXBkYXRlIHlvdXIgY29uZmlnXCdzIGdpdGh1Yi1wcm90b2NvbHMgdG8gdXNlICJodHRwcyIsICJnaXQiIG9yICJzc2giJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRwcm90b3M7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+Y29uZmlnWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2VzcygkdGhpcy0+Y29uZmlnWyRrZXldLCAkZmxhZ3MpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJGZsYWdzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIG1peGVkW10+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGwoJGZsYWdzID0gMCkKICAgIHsKICAgICAgICAkYWxsID0gYXJyYXkoCiAgICAgICAgICAgICdyZXBvc2l0b3JpZXMnID0+ICR0aGlzLT5nZXRSZXBvc2l0b3JpZXMoKSwKICAgICAgICApOwogICAgICAgIGZvcmVhY2ggKGFycmF5X2tleXMoJHRoaXMtPmNvbmZpZykgYXMgJGtleSkgewogICAgICAgICAgICAkYWxsWydjb25maWcnXVska2V5XSA9ICR0aGlzLT5nZXQoJGtleSwgJGZsYWdzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlT2ZWYWx1ZSgka2V5KQogICAgewogICAgICAgICR0aGlzLT5nZXQoJGtleSk7CgogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+c291cmNlT2ZDb25maWdWYWx1ZVska2V5XSkgPyAkdGhpcy0+c291cmNlT2ZDb25maWdWYWx1ZVska2V5XSA6IHNlbGY6OlNPVVJDRV9VTktOT1dOOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG1peGVkICAkY29uZmlnVmFsdWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldFNvdXJjZU9mQ29uZmlnVmFsdWUoJGNvbmZpZ1ZhbHVlLCAkcGF0aCwgJHNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlT2ZDb25maWdWYWx1ZVskcGF0aF0gPSAkc291cmNlOwoKICAgICAgICBpZiAoaXNfYXJyYXkoJGNvbmZpZ1ZhbHVlKSkgewogICAgICAgICAgICBmb3JlYWNoICgkY29uZmlnVmFsdWUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zZXRTb3VyY2VPZkNvbmZpZ1ZhbHVlKCR2YWx1ZSwgJHBhdGggLiAnLicgLiAka2V5LCAkc291cmNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBtaXhlZFtdPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmF3KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICdyZXBvc2l0b3JpZXMnID0+ICR0aGlzLT5nZXRSZXBvc2l0b3JpZXMoKSwKICAgICAgICAgICAgJ2NvbmZpZycgPT4gJHRoaXMtPmNvbmZpZywKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgYSBzZXR0aW5nIGV4aXN0cwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRrZXkKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRrZXkpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleV9leGlzdHMoJGtleSwgJHRoaXMtPmNvbmZpZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBsYWNlcyB7JHJlZnN9IGluc2lkZSBhIGNvbmZpZyBzdHJpbmcKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xpbnR8bnVsbCAkdmFsdWUgYSBjb25maWcgc3RyaW5nIHRoYXQgY2FuIGNvbnRhaW4geyRyZWZzLXRvLW90aGVyLWNvbmZpZ30KICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgICAgICRmbGFncyBPcHRpb25zIChzZWUgY2xhc3MgY29uc3RhbnRzKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGludHxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcHJvY2VzcygkdmFsdWUsICRmbGFncykKICAgIHsKICAgICAgICAkY29uZmlnID0gJHRoaXM7CgogICAgICAgIGlmICghaXNfc3RyaW5nKCR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJyNce1wkKC4rKVx9IycsIGZ1bmN0aW9uICgkbWF0Y2gpIHVzZSAoJGNvbmZpZywgJGZsYWdzKSB7CiAgICAgICAgICAgIHJldHVybiAkY29uZmlnLT5nZXQoJG1hdGNoWzFdLCAkZmxhZ3MpOwogICAgICAgIH0sICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyByZWxhdGl2ZSBwYXRocyBpbiBhYnNvbHV0ZSBwYXRocyB3aXRob3V0IHJlYWxwYXRoKCkKICAgICAqCiAgICAgKiBTaW5jZSB0aGUgZGlycyBtaWdodCBub3QgZXhpc3QgeWV0IHdlIGNhbiBub3QgY2FsbCByZWFscGF0aCBvciBpdCB3aWxsIGZhaWwuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVhbHBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKD86L3xbYS16XTp8W2EtejAtOS5dKzovLyl9aScsICRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gJHBhdGg7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmJhc2VEaXIgPyAkdGhpcy0+YmFzZURpciAuICcvJyAuICRwYXRoIDogJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkcyB0aGUgdmFsdWUgb2YgYSBDb21wb3NlciBlbnZpcm9ubWVudCB2YXJpYWJsZQogICAgICoKICAgICAqIFRoaXMgc2hvdWxkIGJlIHVzZWQgdG8gcmVhZCBDT01QT1NFUl8gZW52aXJvbm1lbnQgdmFyaWFibGVzCiAgICAgKiB0aGF0IG92ZXJsb2FkIGNvbmZpZyB2YWx1ZXMuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkdmFyCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q29tcG9zZXJFbnYoJHZhcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnVzZUVudmlyb25tZW50KSB7CiAgICAgICAgICAgIHJldHVybiBQbGF0Zm9ybTo6Z2V0RW52KCR2YXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRpc2FibGVSZXBvQnlOYW1lKCRuYW1lKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVwb3NpdG9yaWVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnJlcG9zaXRvcmllc1skbmFtZV0pOwogICAgICAgIH0gZWxzZWlmICgkbmFtZSA9PT0gJ3BhY2thZ2lzdCcpIHsgLy8gQkMgc3VwcG9ydCBmb3IgZGVmYXVsdCAicGFja2FnaXN0IiBuYW1lZCByZXBvCiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5yZXBvc2l0b3JpZXNbJ3BhY2thZ2lzdC5vcmcnXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoYXQgdGhlIHBhc3NlZCBVUkwgaXMgYWxsb3dlZCB0byBiZSB1c2VkIGJ5IGN1cnJlbnQgY29uZmlnLCBvciB0aHJvd3MgYW4gZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdXJsCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9oaWJpdFVybEJ5Q29uZmlnKCR1cmwsIElPSW50ZXJmYWNlICRpbyA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gUmV0dXJuIHJpZ2h0IGF3YXkgaWYgdGhlIFVSTCBpcyBtYWxmb3JtZWQgb3IgY3VzdG9tIChzZWUgaXNzdWUgIzUxNzMpCiAgICAgICAgaWYgKGZhbHNlID09PSBmaWx0ZXJfdmFyKCR1cmwsIEZJTFRFUl9WQUxJREFURV9VUkwpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIEV4dHJhY3Qgc2NoZW1lIGFuZCB0aHJvdyBleGNlcHRpb24gb24ga25vd24gaW5zZWN1cmUgcHJvdG9jb2xzCiAgICAgICAgJHNjaGVtZSA9IHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1NDSEVNRSk7CiAgICAgICAgJGhvc3RuYW1lID0gcGFyc2VfdXJsKCR1cmwsIFBIUF9VUkxfSE9TVCk7CiAgICAgICAgaWYgKGluX2FycmF5KCRzY2hlbWUsIGFycmF5KCdodHRwJywgJ2dpdCcsICdmdHAnLCAnc3ZuJykpKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+Z2V0KCdzZWN1cmUtaHR0cCcpKSB7CiAgICAgICAgICAgICAgICBpZiAoJHNjaGVtZSA9PT0gJ3N2bicpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGhvc3RuYW1lLCAkdGhpcy0+Z2V0KCdzZWN1cmUtc3ZuLWRvbWFpbnMnKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbigiWW91ciBjb25maWd1cmF0aW9uIGRvZXMgbm90IGFsbG93IGNvbm5lY3Rpb25zIHRvICR1cmwuIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDYtY29uZmlnLm1kI3NlY3VyZS1zdm4tZG9tYWlucyBmb3IgZGV0YWlscy4iKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCJZb3VyIGNvbmZpZ3VyYXRpb24gZG9lcyBub3QgYWxsb3cgY29ubmVjdGlvbnMgdG8gJHVybC4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wNi1jb25maWcubWQjc2VjdXJlLWh0dHAgZm9yIGRldGFpbHMuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRpbykgewogICAgICAgICAgICAgICAgJGhvc3QgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9IT1NUKTsKICAgICAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJGhvc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+d2FybmVkSG9zdHNbJGhvc3RdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoIjx3YXJuaW5nPldhcm5pbmc6IEFjY2Vzc2luZyAkaG9zdCBvdmVyICRzY2hlbWUgd2hpY2ggaXMgYW4gaW5zZWN1cmUgcHJvdG9jb2wuPC93YXJuaW5nPiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmVkSG9zdHNbJGhvc3RdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFVzZWQgYnkgbG9uZy1ydW5uaW5nIGN1c3RvbSBzY3JpcHRzIGluIGNvbXBvc2VyLmpzb24KICAgICAqCiAgICAgKiAic2NyaXB0cyI6IHsKICAgICAqICAgIndhdGNoIjogWwogICAgICogICAgICJDb21wb3NlclxcQ29uZmlnOjpkaXNhYmxlUHJvY2Vzc1RpbWVvdXQiLAogICAgICogICAgICJ2ZW5kb3IvYmluL2xvbmctcnVubmluZy1zY3JpcHQgLS13YXRjaCIKICAgICAqICAgXQogICAgICogfQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGRpc2FibGVQcm9jZXNzVGltZW91dCgpCiAgICB7CiAgICAgICAgLy8gT3ZlcnJpZGUgZ2xvYmFsIHRpbWVvdXQgc2V0IGVhcmxpZXIgYnkgZW52aXJvbm1lbnQgb3IgY29uZmlnCiAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjpzZXRUaW1lb3V0KDApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNjcmlwdDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50IGFzIEJhc2VFdmVudDsKCi8qKgogKiBUaGUgc2NyaXB0IGV2ZW50IGNsYXNzCiAqCiAqIEBhdXRob3IgRnJhbsOnb2lzIFBsdWNoaW5vIDxmcmFuY29pcy5wbHVjaGlub0BvcGVuZGlzcGxheS5jb20+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBFdmVudCBleHRlbmRzIEJhc2VFdmVudAp7CiAgICAvKioKICAgICAqIEB2YXIgQ29tcG9zZXIgVGhlIGNvbXBvc2VyIGluc3RhbmNlCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbXBvc2VyOwoKICAgIC8qKgogICAgICogQHZhciBJT0ludGVyZmFjZSBUaGUgSU8gaW5zdGFuY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wgRGV2IG1vZGUgZmxhZwogICAgICovCiAgICBwcml2YXRlICRkZXZNb2RlOwoKICAgIC8qKgogICAgICogQHZhciBCYXNlRXZlbnQKICAgICAqLwogICAgcHJpdmF0ZSAkb3JpZ2luYXRpbmdFdmVudDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGV2ZW50IG5hbWUKICAgICAqIEBwYXJhbSBDb21wb3NlciAkY29tcG9zZXIgVGhlIGNvbXBvc2VyIG9iamVjdAogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbyBUaGUgSU9JbnRlcmZhY2Ugb2JqZWN0CiAgICAgKiBAcGFyYW0gYm9vbCAkZGV2TW9kZSBXaGV0aGVyIG9yIG5vdCB3ZSBhcmUgaW4gZGV2IG1vZGUKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmd8aW50fGZsb2F0fGJvb2x8bnVsbD4gJGFyZ3MgQXJndW1lbnRzIHBhc3NlZCBieSB0aGUgdXNlcgogICAgICogQHBhcmFtIG1peGVkW10gJGZsYWdzIE9wdGlvbmFsIGZsYWdzIHRvIHBhc3MgZGF0YSBub3QgYXMgYXJndW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCBDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbywgJGRldk1vZGUgPSBmYWxzZSwgYXJyYXkgJGFyZ3MgPSBhcnJheSgpLCBhcnJheSAkZmxhZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG5hbWUsICRhcmdzLCAkZmxhZ3MpOwogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmRldk1vZGUgPSAkZGV2TW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbXBvc2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gQ29tcG9zZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBvc2VyOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgSU8gaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBJT0ludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SU8oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW87CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGRldiBtb2RlIGZsYWcKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGV2TW9kZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXZNb2RlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBvcmlnaW5hdGluZyBldmVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuID9CYXNlRXZlbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9yaWdpbmF0aW5nRXZlbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3JpZ2luYXRpbmdFdmVudDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgb3JpZ2luYXRpbmcgZXZlbnQuCiAgICAgKgogICAgICogQHBhcmFtICBCYXNlRXZlbnQgJGV2ZW50CiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcmlnaW5hdGluZ0V2ZW50KEJhc2VFdmVudCAkZXZlbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPm9yaWdpbmF0aW5nRXZlbnQgPSAkdGhpcy0+Y2FsY3VsYXRlT3JpZ2luYXRpbmdFdmVudCgkZXZlbnQpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB1cHBlci1tb3N0IGV2ZW50IGluIGNoYWluLgogICAgICoKICAgICAqIEBwYXJhbSAgQmFzZUV2ZW50ICRldmVudAogICAgICogQHJldHVybiBCYXNlRXZlbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYWxjdWxhdGVPcmlnaW5hdGluZ0V2ZW50KEJhc2VFdmVudCAkZXZlbnQpCiAgICB7CiAgICAgICAgaWYgKCRldmVudCBpbnN0YW5jZW9mIEV2ZW50ICYmICRldmVudC0+Z2V0T3JpZ2luYXRpbmdFdmVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y2FsY3VsYXRlT3JpZ2luYXRpbmdFdmVudCgkZXZlbnQtPmdldE9yaWdpbmF0aW5nRXZlbnQoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGV2ZW50OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNjcmlwdDsKCi8qKgogKiBUaGUgU2NyaXB0IEV2ZW50cy4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgU2NyaXB0RXZlbnRzCnsKICAgIC8qKgogICAgICogVGhlIFBSRV9JTlNUQUxMX0NNRCBldmVudCBvY2N1cnMgYmVmb3JlIHRoZSBpbnN0YWxsIGNvbW1hbmQgaXMgZXhlY3V0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfSU5TVEFMTF9DTUQgPSAncHJlLWluc3RhbGwtY21kJzsKCiAgICAvKioKICAgICAqIFRoZSBQT1NUX0lOU1RBTExfQ01EIGV2ZW50IG9jY3VycyBhZnRlciB0aGUgaW5zdGFsbCBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9JTlNUQUxMX0NNRCA9ICdwb3N0LWluc3RhbGwtY21kJzsKCiAgICAvKioKICAgICAqIFRoZSBQUkVfVVBEQVRFX0NNRCBldmVudCBvY2N1cnMgYmVmb3JlIHRoZSB1cGRhdGUgY29tbWFuZCBpcyBleGVjdXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9VUERBVEVfQ01EID0gJ3ByZS11cGRhdGUtY21kJzsKCiAgICAvKioKICAgICAqIFRoZSBQT1NUX1VQREFURV9DTUQgZXZlbnQgb2NjdXJzIGFmdGVyIHRoZSB1cGRhdGUgY29tbWFuZCBpcyBleGVjdXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfVVBEQVRFX0NNRCA9ICdwb3N0LXVwZGF0ZS1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBSRV9TVEFUVVNfQ01EIGV2ZW50IG9jY3VycyBiZWZvcmUgdGhlIHN0YXR1cyBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX1NUQVRVU19DTUQgPSAncHJlLXN0YXR1cy1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfU1RBVFVTX0NNRCBldmVudCBvY2N1cnMgYWZ0ZXIgdGhlIHN0YXR1cyBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9TVEFUVVNfQ01EID0gJ3Bvc3Qtc3RhdHVzLWNtZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX0FVVE9MT0FEX0RVTVAgZXZlbnQgb2NjdXJzIGJlZm9yZSB0aGUgYXV0b2xvYWQgZmlsZSBpcyBnZW5lcmF0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfQVVUT0xPQURfRFVNUCA9ICdwcmUtYXV0b2xvYWQtZHVtcCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9BVVRPTE9BRF9EVU1QIGV2ZW50IG9jY3VycyBhZnRlciB0aGUgYXV0b2xvYWQgZmlsZSBoYXMgYmVlbiBnZW5lcmF0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX0FVVE9MT0FEX0RVTVAgPSAncG9zdC1hdXRvbG9hZC1kdW1wJzsKCiAgICAvKioKICAgICAqIFRoZSBQT1NUX1JPT1RfUEFDS0FHRV9JTlNUQUxMIGV2ZW50IG9jY3VycyBhZnRlciB0aGUgcm9vdCBwYWNrYWdlIGhhcyBiZWVuIGluc3RhbGxlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfUk9PVF9QQUNLQUdFX0lOU1RBTEwgPSAncG9zdC1yb290LXBhY2thZ2UtaW5zdGFsbCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9DUkVBVEVfUFJPSkVDVCBldmVudCBvY2N1cnMgYWZ0ZXIgdGhlIGNyZWF0ZS1wcm9qZWN0IGNvbW1hbmQgaGFzIGJlZW4gZXhlY3V0ZWQuCiAgICAgKiBOb3RlOiBFdmVudCBvY2N1cnMgYWZ0ZXIgUE9TVF9JTlNUQUxMX0NNRAogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9DUkVBVEVfUFJPSkVDVF9DTUQgPSAncG9zdC1jcmVhdGUtcHJvamVjdC1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBSRV9BUkNISVZFX0NNRCBldmVudCBvY2N1cnMgYmVmb3JlIHRoZSB1cGRhdGUgY29tbWFuZCBpcyBleGVjdXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9BUkNISVZFX0NNRCA9ICdwcmUtYXJjaGl2ZS1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfQVJDSElWRV9DTUQgZXZlbnQgb2NjdXJzIGFmdGVyIHRoZSBzdGF0dXMgY29tbWFuZCBpcyBleGVjdXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfQVJDSElWRV9DTUQgPSAncG9zdC1hcmNoaXZlLWNtZCc7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXI7Cgp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXENhQnVuZGxlXENhQnVuZGxlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEZpbmRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKdXNlIFNlbGRcUGhhclV0aWxzXFRpbWVzdGFtcHM7CnVzZSBTZWxkXFBoYXJVdGlsc1xMaW50ZXI7CgovKioKICogVGhlIENvbXBpbGVyIGNsYXNzIGNvbXBpbGVzIGNvbXBvc2VyIGludG8gYSBwaGFyCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDb21waWxlcgp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJHZlcnNpb247CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGJyYW5jaEFsaWFzVmVyc2lvbiA9ICcnOwogICAgLyoqIEB2YXIgXERhdGVUaW1lICovCiAgICBwcml2YXRlICR2ZXJzaW9uRGF0ZTsKCiAgICAvKioKICAgICAqIENvbXBpbGVzIGNvbXBvc2VyIGludG8gYSBzaW5nbGUgcGhhciBmaWxlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGhhckZpbGUgVGhlIGZ1bGwgcGF0aCB0byB0aGUgZmlsZSB0byBjcmVhdGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21waWxlKCRwaGFyRmlsZSA9ICdjb21wb3Nlci5waGFyJykKICAgIHsKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHBoYXJGaWxlKSkgewogICAgICAgICAgICB1bmxpbmsoJHBoYXJGaWxlKTsKICAgICAgICB9CgogICAgICAgIC8vIFRPRE8gaW4gdjIuMyBhbHdheXMgY2FsbCB3aXRoIGFuIGFycmF5CiAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJ1N5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzcycsICdmcm9tU2hlbGxDb21tYW5kbGluZScpKSB7CiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3MoYXJyYXkoJ2dpdCcsICdsb2cnLCAnLS1wcmV0dHk9IiVIIicsICctbjEnLCAnSEVBRCcpLCBfX0RJUl9fKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBAcGhwc3Rhbi1pZ25vcmUtbmV4dC1saW5lCiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3MoJ2dpdCBsb2cgLS1wcmV0dHk9IiVIIiAtbjEgSEVBRCcsIF9fRElSX18pOwogICAgICAgIH0KICAgICAgICBpZiAoJHByb2Nlc3MtPnJ1bigpICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDYW5cJ3QgcnVuIGdpdCBsb2cuIFlvdSBtdXN0IGVuc3VyZSB0byBydW4gY29tcGlsZSBmcm9tIGNvbXBvc2VyIGdpdCByZXBvc2l0b3J5IGNsb25lIGFuZCB0aGF0IGdpdCBiaW5hcnkgaXMgYXZhaWxhYmxlLicpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+dmVyc2lvbiA9IHRyaW0oJHByb2Nlc3MtPmdldE91dHB1dCgpKTsKCiAgICAgICAgLy8gVE9ETyBpbiB2Mi4zIGFsd2F5cyBjYWxsIHdpdGggYW4gYXJyYXkKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygnU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzJywgJ2Zyb21TaGVsbENvbW1hbmRsaW5lJykpIHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcyhhcnJheSgnZ2l0JywgJ2xvZycsICctbjEnLCAnLS1wcmV0dHk9JWNpJywgJ0hFQUQnKSwgX19ESVJfXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQHBocHN0YW4taWdub3JlLW5leHQtbGluZQogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzKCdnaXQgbG9nIC1uMSAtLXByZXR0eT0lY2kgSEVBRCcsIF9fRElSX18pOwogICAgICAgIH0KICAgICAgICBpZiAoJHByb2Nlc3MtPnJ1bigpICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDYW5cJ3QgcnVuIGdpdCBsb2cuIFlvdSBtdXN0IGVuc3VyZSB0byBydW4gY29tcGlsZSBmcm9tIGNvbXBvc2VyIGdpdCByZXBvc2l0b3J5IGNsb25lIGFuZCB0aGF0IGdpdCBiaW5hcnkgaXMgYXZhaWxhYmxlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnZlcnNpb25EYXRlID0gbmV3IFxEYXRlVGltZSh0cmltKCRwcm9jZXNzLT5nZXRPdXRwdXQoKSkpOwogICAgICAgICR0aGlzLT52ZXJzaW9uRGF0ZS0+c2V0VGltZXpvbmUobmV3IFxEYXRlVGltZVpvbmUoJ1VUQycpKTsKCiAgICAgICAgLy8gVE9ETyBpbiB2Mi4zIGFsd2F5cyBjYWxsIHdpdGggYW4gYXJyYXkKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygnU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzJywgJ2Zyb21TaGVsbENvbW1hbmRsaW5lJykpIHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcyhhcnJheSgnZ2l0JywgJ2Rlc2NyaWJlJywgJy0tdGFncycsICctLWV4YWN0LW1hdGNoJywgJ0hFQUQnKSwgX19ESVJfXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQHBocHN0YW4taWdub3JlLW5leHQtbGluZQogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzKCdnaXQgZGVzY3JpYmUgLS10YWdzIC0tZXhhY3QtbWF0Y2ggSEVBRCcpOwogICAgICAgIH0KICAgICAgICBpZiAoJHByb2Nlc3MtPnJ1bigpID09IDApIHsKICAgICAgICAgICAgJHRoaXMtPnZlcnNpb24gPSB0cmltKCRwcm9jZXNzLT5nZXRPdXRwdXQoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gZ2V0IGJyYW5jaC1hbGlhcyBkZWZpbmVkIGluIGNvbXBvc2VyLmpzb24gZm9yIGRldi1tYWluIChpZiBhbnkpCiAgICAgICAgICAgICRsb2NhbENvbmZpZyA9IF9fRElSX18uJy8uLi8uLi9jb21wb3Nlci5qc29uJzsKICAgICAgICAgICAgJGZpbGUgPSBuZXcgSnNvbkZpbGUoJGxvY2FsQ29uZmlnKTsKICAgICAgICAgICAgJGxvY2FsQ29uZmlnID0gJGZpbGUtPnJlYWQoKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRsb2NhbENvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ11bJ2Rldi1tYWluJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YnJhbmNoQWxpYXNWZXJzaW9uID0gJGxvY2FsQ29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXVsnZGV2LW1haW4nXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHBoYXIgPSBuZXcgXFBoYXIoJHBoYXJGaWxlLCAwLCAnY29tcG9zZXIucGhhcicpOwogICAgICAgICRwaGFyLT5zZXRTaWduYXR1cmVBbGdvcml0aG0oXFBoYXI6OlNIQTUxMik7CgogICAgICAgICRwaGFyLT5zdGFydEJ1ZmZlcmluZygpOwoKICAgICAgICAkZmluZGVyU29ydCA9IGZ1bmN0aW9uICgkYSwgJGIpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmNtcChzdHJ0cigkYS0+Z2V0UmVhbFBhdGgoKSwgJ1xcJywgJy8nKSwgc3RydHIoJGItPmdldFJlYWxQYXRoKCksICdcXCcsICcvJykpOwogICAgICAgIH07CgogICAgICAgIC8vIEFkZCBDb21wb3NlciBzb3VyY2VzCiAgICAgICAgJGZpbmRlciA9IG5ldyBGaW5kZXIoKTsKICAgICAgICAkZmluZGVyLT5maWxlcygpCiAgICAgICAgICAgIC0+aWdub3JlVkNTKHRydWUpCiAgICAgICAgICAgIC0+bmFtZSgnKi5waHAnKQogICAgICAgICAgICAtPm5vdE5hbWUoJ0NvbXBpbGVyLnBocCcpCiAgICAgICAgICAgIC0+bm90TmFtZSgnQ2xhc3NMb2FkZXIucGhwJykKICAgICAgICAgICAgLT5ub3ROYW1lKCdJbnN0YWxsZWRWZXJzaW9ucy5waHAnKQogICAgICAgICAgICAtPmluKF9fRElSX18uJy8uLicpCiAgICAgICAgICAgIC0+c29ydCgkZmluZGVyU29ydCkKICAgICAgICA7CiAgICAgICAgZm9yZWFjaCAoJGZpbmRlciBhcyAkZmlsZSkgewogICAgICAgICAgICAkdGhpcy0+YWRkRmlsZSgkcGhhciwgJGZpbGUpOwogICAgICAgIH0KICAgICAgICAvLyBBZGQgcnVudGltZSB1dGlsaXRpZXMgc2VwYXJhdGVseSB0byBtYWtlIHN1cmUgdGhleSByZXRhaW5zIHRoZSBkb2NibG9ja3MgYXMgdGhlc2Ugd2lsbCBnZXQgY29waWVkIGludG8gcHJvamVjdHMKICAgICAgICAkdGhpcy0+YWRkRmlsZSgkcGhhciwgbmV3IFxTcGxGaWxlSW5mbyhfX0RJUl9fIC4gJy9BdXRvbG9hZC9DbGFzc0xvYWRlci5waHAnKSwgZmFsc2UpOwogICAgICAgICR0aGlzLT5hZGRGaWxlKCRwaGFyLCBuZXcgXFNwbEZpbGVJbmZvKF9fRElSX18gLiAnL0luc3RhbGxlZFZlcnNpb25zLnBocCcpLCBmYWxzZSk7CgogICAgICAgIC8vIEFkZCBDb21wb3NlciByZXNvdXJjZXMKICAgICAgICAkZmluZGVyID0gbmV3IEZpbmRlcigpOwogICAgICAgICRmaW5kZXItPmZpbGVzKCkKICAgICAgICAgICAgLT5pbihfX0RJUl9fLicvLi4vLi4vcmVzJykKICAgICAgICAgICAgLT5zb3J0KCRmaW5kZXJTb3J0KQogICAgICAgIDsKICAgICAgICBmb3JlYWNoICgkZmluZGVyIGFzICRmaWxlKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRGaWxlKCRwaGFyLCAkZmlsZSwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gQWRkIHZlbmRvciBmaWxlcwogICAgICAgICRmaW5kZXIgPSBuZXcgRmluZGVyKCk7CiAgICAgICAgJGZpbmRlci0+ZmlsZXMoKQogICAgICAgICAgICAtPmlnbm9yZVZDUyh0cnVlKQogICAgICAgICAgICAtPm5vdFBhdGgoJy9cLyhjb21wb3NlclwuKGpzb258bG9jayl8W0EtWl0rXC5tZHxcLmdpdGlnbm9yZXxhcHB2ZXlvci55bWx8cGhwdW5pdFwueG1sXC5kaXN0fHBocHN0YW5cLm5lb25cLmRpc3R8cGhwc3Rhbi1jb25maWdcLm5lb24pJC8nKQogICAgICAgICAgICAtPm5vdFBhdGgoJy9iaW5cLyhqc29ubGludHx2YWxpZGF0ZS1qc29ufHNpbXBsZS1waHB1bml0KShcLmJhdCk/JC8nKQogICAgICAgICAgICAtPm5vdFBhdGgoJ3N5bWZvbnkvZGVidWcvUmVzb3VyY2VzL2V4dC8nKQogICAgICAgICAgICAtPm5vdFBhdGgoJ2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvZGVtby8nKQogICAgICAgICAgICAtPm5vdFBhdGgoJ2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvZGlzdC8nKQogICAgICAgICAgICAtPm5vdFBhdGgoJ2NvbXBvc2VyL2luc3RhbGxlZC5qc29uJykKICAgICAgICAgICAgLT5ub3RQYXRoKCdjb21wb3Nlci9MSUNFTlNFJykKICAgICAgICAgICAgLT5leGNsdWRlKCdUZXN0cycpCiAgICAgICAgICAgIC0+ZXhjbHVkZSgndGVzdHMnKQogICAgICAgICAgICAtPmV4Y2x1ZGUoJ2RvY3MnKQogICAgICAgICAgICAtPmluKF9fRElSX18uJy8uLi8uLi92ZW5kb3IvJykKICAgICAgICAgICAgLT5zb3J0KCRmaW5kZXJTb3J0KQogICAgICAgIDsKCiAgICAgICAgJGV4dHJhRmlsZXMgPSBhcnJheSgKICAgICAgICAgICAgcmVhbHBhdGgoX19ESVJfXyAuICcvLi4vLi4vdmVuZG9yL2NvbXBvc2VyL3NwZHgtbGljZW5zZXMvcmVzL3NwZHgtZXhjZXB0aW9ucy5qc29uJyksCiAgICAgICAgICAgIHJlYWxwYXRoKF9fRElSX18gLiAnLy4uLy4uL3ZlbmRvci9jb21wb3Nlci9zcGR4LWxpY2Vuc2VzL3Jlcy9zcGR4LWxpY2Vuc2VzLmpzb24nKSwKICAgICAgICAgICAgcmVhbHBhdGgoQ2FCdW5kbGU6OmdldEJ1bmRsZWRDYUJ1bmRsZVBhdGgoKSksCiAgICAgICAgICAgIHJlYWxwYXRoKF9fRElSX18gLiAnLy4uLy4uL3ZlbmRvci9zeW1mb255L2NvbnNvbGUvUmVzb3VyY2VzL2Jpbi9oaWRkZW5pbnB1dC5leGUnKSwKICAgICAgICAgICAgcmVhbHBhdGgoX19ESVJfXyAuICcvLi4vLi4vdmVuZG9yL3N5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcvUmVzb3VyY2VzL21iX2NvbnZlcnRfdmFyaWFibGVzLnBocDgnKSwKICAgICAgICApOwogICAgICAgICR1bmV4cGVjdGVkRmlsZXMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkZmluZGVyIGFzICRmaWxlKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheShyZWFscGF0aCgkZmlsZSksICRleHRyYUZpbGVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgdW5zZXQoJGV4dHJhRmlsZXNbYXJyYXlfc2VhcmNoKHJlYWxwYXRoKCRmaWxlKSwgJGV4dHJhRmlsZXMsIHRydWUpXSk7CiAgICAgICAgICAgIH0gZWxzZWlmICghUHJlZzo6aXNNYXRjaCgneyhbL1xcXFxdTElDRU5TRXxcLnBocCkkfScsICRmaWxlKSkgewogICAgICAgICAgICAgICAgJHVuZXhwZWN0ZWRGaWxlc1tdID0gKHN0cmluZykgJGZpbGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XC5waHBbXGQuXSokfScsICRmaWxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEZpbGUoJHBoYXIsICRmaWxlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRGaWxlKCRwaGFyLCAkZmlsZSwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGV4dHJhRmlsZXMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGVzZSBmaWxlcyB3ZXJlIGV4cGVjdGVkIGJ1dCBub3QgYWRkZWQgdG8gdGhlIHBoYXIsIHRoZXkgbWlnaHQgYmUgZXhjbHVkZWQgb3IgZ29uZSBmcm9tIHRoZSBzb3VyY2UgcGFja2FnZTonLlBIUF9FT0wuaW1wbG9kZShQSFBfRU9MLCAkZXh0cmFGaWxlcykpOwogICAgICAgIH0KICAgICAgICBpZiAoJHVuZXhwZWN0ZWRGaWxlcykgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZXNlIGZpbGVzIHdlcmUgdW5leHBlY3RlZGx5IGFkZGVkIHRvIHRoZSBwaGFyLCBtYWtlIHN1cmUgdGhleSBhcmUgZXhjbHVkZWQgb3IgbGlzdGVkIGluICRleHRyYUZpbGVzOicuUEhQX0VPTC5pbXBsb2RlKFBIUF9FT0wsICR1bmV4cGVjdGVkRmlsZXMpKTsKICAgICAgICB9CgogICAgICAgIC8vIEFkZCBiaW4vY29tcG9zZXIKICAgICAgICAkdGhpcy0+YWRkQ29tcG9zZXJCaW4oJHBoYXIpOwoKICAgICAgICAvLyBTdHVicwogICAgICAgICRwaGFyLT5zZXRTdHViKCR0aGlzLT5nZXRTdHViKCkpOwoKICAgICAgICAkcGhhci0+c3RvcEJ1ZmZlcmluZygpOwoKICAgICAgICAvLyBkaXNhYmxlZCBmb3IgaW50ZXJvcGVyYWJpbGl0eSB3aXRoIHN5c3RlbXMgd2l0aG91dCBnemlwIGV4dAogICAgICAgIC8vICRwaGFyLT5jb21wcmVzc0ZpbGVzKFxQaGFyOjpHWik7CgogICAgICAgICR0aGlzLT5hZGRGaWxlKCRwaGFyLCBuZXcgXFNwbEZpbGVJbmZvKF9fRElSX18uJy8uLi8uLi9MSUNFTlNFJyksIGZhbHNlKTsKCiAgICAgICAgdW5zZXQoJHBoYXIpOwoKICAgICAgICAvLyByZS1zaWduIHRoZSBwaGFyIHdpdGggcmVwcm9kdWNpYmxlIHRpbWVzdGFtcCAvIHNpZ25hdHVyZQogICAgICAgICR1dGlsID0gbmV3IFRpbWVzdGFtcHMoJHBoYXJGaWxlKTsKICAgICAgICAkdXRpbC0+dXBkYXRlVGltZXN0YW1wcygkdGhpcy0+dmVyc2lvbkRhdGUpOwogICAgICAgICR1dGlsLT5zYXZlKCRwaGFyRmlsZSwgXFBoYXI6OlNIQTUxMik7CgogICAgICAgIExpbnRlcjo6bGludCgkcGhhckZpbGUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBcU3BsRmlsZUluZm8gJGZpbGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UmVsYXRpdmVGaWxlUGF0aCgkZmlsZSkKICAgIHsKICAgICAgICAkcmVhbFBhdGggPSAkZmlsZS0+Z2V0UmVhbFBhdGgoKTsKICAgICAgICAkcGF0aFByZWZpeCA9IGRpcm5hbWUoZGlybmFtZShfX0RJUl9fKSkuRElSRUNUT1JZX1NFUEFSQVRPUjsKCiAgICAgICAgJHBvcyA9IHN0cnBvcygkcmVhbFBhdGgsICRwYXRoUHJlZml4KTsKICAgICAgICAkcmVsYXRpdmVQYXRoID0gKCRwb3MgIT09IGZhbHNlKSA/IHN1YnN0cl9yZXBsYWNlKCRyZWFsUGF0aCwgJycsICRwb3MsIHN0cmxlbigkcGF0aFByZWZpeCkpIDogJHJlYWxQYXRoOwoKICAgICAgICByZXR1cm4gc3RydHIoJHJlbGF0aXZlUGF0aCwgJ1xcJywgJy8nKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRzdHJpcAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFkZEZpbGUoXFBoYXIgJHBoYXIsIFxTcGxGaWxlSW5mbyAkZmlsZSwgJHN0cmlwID0gdHJ1ZSkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5nZXRSZWxhdGl2ZUZpbGVQYXRoKCRmaWxlKTsKICAgICAgICAkY29udGVudCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlKTsKICAgICAgICBpZiAoJHN0cmlwKSB7CiAgICAgICAgICAgICRjb250ZW50ID0gJHRoaXMtPnN0cmlwV2hpdGVzcGFjZSgkY29udGVudCk7CiAgICAgICAgfSBlbHNlaWYgKCdMSUNFTlNFJyA9PT0gYmFzZW5hbWUoJGZpbGUpKSB7CiAgICAgICAgICAgICRjb250ZW50ID0gIlxuIi4kY29udGVudC4iXG4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYXRoID09PSAnc3JjL0NvbXBvc2VyL0NvbXBvc2VyLnBocCcpIHsKICAgICAgICAgICAgJGNvbnRlbnQgPSBzdHJ0cigKICAgICAgICAgICAgICAgICRjb250ZW50LAogICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ0BwYWNrYWdlX3ZlcnNpb25AJyA9PiAkdGhpcy0+dmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAnQHBhY2thZ2VfYnJhbmNoX2FsaWFzX3ZlcnNpb25AJyA9PiAkdGhpcy0+YnJhbmNoQWxpYXNWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICdAcmVsZWFzZV9kYXRlQCcgPT4gJHRoaXMtPnZlcnNpb25EYXRlLT5mb3JtYXQoJ1ktbS1kIEg6aTpzJyksCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRjb250ZW50ID0gUHJlZzo6cmVwbGFjZSgne1NPVVJDRV9WRVJTSU9OID0gXCdbXlwnXStcJzt9JywgJ1NPVVJDRV9WRVJTSU9OID0gXCdcJzsnLCAkY29udGVudCk7CiAgICAgICAgfQoKICAgICAgICAkcGhhci0+YWRkRnJvbVN0cmluZygkcGF0aCwgJGNvbnRlbnQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkQ29tcG9zZXJCaW4oXFBoYXIgJHBoYXIpCiAgICB7CiAgICAgICAgJGNvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cyhfX0RJUl9fLicvLi4vLi4vYmluL2NvbXBvc2VyJyk7CiAgICAgICAgJGNvbnRlbnQgPSBQcmVnOjpyZXBsYWNlKCd7XiMhL3Vzci9iaW4vZW52IHBocFxzKn0nLCAnJywgJGNvbnRlbnQpOwogICAgICAgICRwaGFyLT5hZGRGcm9tU3RyaW5nKCdiaW4vY29tcG9zZXInLCAkY29udGVudCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHdoaXRlc3BhY2UgZnJvbSBhIFBIUCBzb3VyY2Ugc3RyaW5nIHdoaWxlIHByZXNlcnZpbmcgbGluZSBudW1iZXJzLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzb3VyY2UgQSBQSFAgc3RyaW5nCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgUEhQIHN0cmluZyB3aXRoIHRoZSB3aGl0ZXNwYWNlIHJlbW92ZWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzdHJpcFdoaXRlc3BhY2UoJHNvdXJjZSkKICAgIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygndG9rZW5fZ2V0X2FsbCcpKSB7CiAgICAgICAgICAgIHJldHVybiAkc291cmNlOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dCA9ICcnOwogICAgICAgIGZvcmVhY2ggKHRva2VuX2dldF9hbGwoJHNvdXJjZSkgYXMgJHRva2VuKSB7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHRva2VuKSkgewogICAgICAgICAgICAgICAgJG91dHB1dCAuPSAkdG9rZW47CiAgICAgICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkdG9rZW5bMF0sIGFycmF5KFRfQ09NTUVOVCwgVF9ET0NfQ09NTUVOVCkpKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49IHN0cl9yZXBlYXQoIlxuIiwgc3Vic3RyX2NvdW50KCR0b2tlblsxXSwgIlxuIikpOwogICAgICAgICAgICB9IGVsc2VpZiAoVF9XSElURVNQQUNFID09PSAkdG9rZW5bMF0pIHsKICAgICAgICAgICAgICAgIC8vIHJlZHVjZSB3aWRlIHNwYWNlcwogICAgICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSBQcmVnOjpyZXBsYWNlKCd7WyBcdF0rfScsICcgJywgJHRva2VuWzFdKTsKICAgICAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSBuZXdsaW5lcyB0byBcbgogICAgICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSBQcmVnOjpyZXBsYWNlKCd7KD86XHJcbnxccnxcbil9JywgIlxuIiwgJHdoaXRlc3BhY2UpOwogICAgICAgICAgICAgICAgLy8gdHJpbSBsZWFkaW5nIHNwYWNlcwogICAgICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSBQcmVnOjpyZXBsYWNlKCd7XG4gK30nLCAiXG4iLCAkd2hpdGVzcGFjZSk7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR3aGl0ZXNwYWNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG91dHB1dCAuPSAkdG9rZW5bMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRTdHViKCkKICAgIHsKICAgICAgICAkc3R1YiA9IDw8PCdFT0YnCiMhL3Vzci9iaW4vZW52IHBocAo8P3BocAovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIGxpY2Vuc2UgdGhhdCBpcyBsb2NhdGVkIGF0IHRoZSBib3R0b20gb2YgdGhpcyBmaWxlLgogKi8KCi8vIEF2b2lkIEFQQyBjYXVzaW5nIHJhbmRvbSBmYXRhbCBlcnJvcnMgcGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvMjY0CmlmIChleHRlbnNpb25fbG9hZGVkKCdhcGMnKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5lbmFibGVfY2xpJyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5jYWNoZV9ieV9kZWZhdWx0JyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSkgewogICAgaWYgKHZlcnNpb25fY29tcGFyZShwaHB2ZXJzaW9uKCdhcGMnKSwgJzMuMC4xMicsICc+PScpKSB7CiAgICAgICAgaW5pX3NldCgnYXBjLmNhY2hlX2J5X2RlZmF1bHQnLCAwKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZndyaXRlKFNUREVSUiwgJ1dhcm5pbmc6IEFQQyA8PSAzLjAuMTIgbWF5IGNhdXNlIGZhdGFsIGVycm9ycyB3aGVuIHJ1bm5pbmcgY29tcG9zZXIgY29tbWFuZHMuJy5QSFBfRU9MKTsKICAgICAgICBmd3JpdGUoU1RERVJSLCAnVXBkYXRlIEFQQywgb3Igc2V0IGFwYy5lbmFibGVfY2xpIG9yIGFwYy5jYWNoZV9ieV9kZWZhdWx0IHRvIDAgaW4geW91ciBwaHAuaW5pLicuUEhQX0VPTCk7CiAgICB9Cn0KCmlmICghY2xhc3NfZXhpc3RzKCdQaGFyJykpIHsKICAgIGVjaG8gJ1BIUFwncyBwaGFyIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiBDb21wb3NlciByZXF1aXJlcyBpdCB0byBydW4uIEVuYWJsZSB0aGUgZXh0ZW5zaW9uIG9yIHJlY29tcGlsZSBwaHAgd2l0aG91dCAtLWRpc2FibGUtcGhhciB0aGVuIHRyeSBhZ2Fpbi4nIC4gUEhQX0VPTDsKICAgIGV4aXQoMSk7Cn0KClBoYXI6Om1hcFBoYXIoJ2NvbXBvc2VyLnBoYXInKTsKCkVPRjsKCiAgICAgICAgLy8gYWRkIHdhcm5pbmcgb25jZSB0aGUgcGhhciBpcyBvbGRlciB0aGFuIDYwIGRheXMKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15bYS1mMC05XSskfScsICR0aGlzLT52ZXJzaW9uKSkgewogICAgICAgICAgICAkd2FybmluZ1RpbWUgPSAoKGludCkgJHRoaXMtPnZlcnNpb25EYXRlLT5mb3JtYXQoJ1UnKSkgKyA2MCAqIDg2NDAwOwogICAgICAgICAgICAkc3R1YiAuPSAiZGVmaW5lKCdDT01QT1NFUl9ERVZfV0FSTklOR19USU1FJywgJHdhcm5pbmdUaW1lKTtcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHN0dWIgLiA8PDwnRU9GJwpyZXF1aXJlICdwaGFyOi8vY29tcG9zZXIucGhhci9iaW4vY29tcG9zZXInOwoKX19IQUxUX0NPTVBJTEVSKCk7CkVPRjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFeGNlcHRpb247CgovKioKICogU3BlY2lmaWMgZXhjZXB0aW9uIGZvciBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyIGNyZWF0aW9uLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBOb1NzbEV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSXJyZWNvdmVyYWJsZURvd25sb2FkRXhjZXB0aW9uIGV4dGVuZHMgXFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyOwoKdXNlIENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyOwp1c2UgQ29tcG9zZXJcU2VtdmVyXFZlcnNpb25QYXJzZXI7CgovKioKICogVGhpcyBjbGFzcyBpcyBjb3BpZWQgaW4gZXZlcnkgQ29tcG9zZXIgaW5zdGFsbGVkIHByb2plY3QgYW5kIGF2YWlsYWJsZSB0byBhbGwKICoKICogU2VlIGFsc28gaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzA3LXJ1bnRpbWUubWQjaW5zdGFsbGVkLXZlcnNpb25zCiAqCiAqIFRvIHJlcXVpcmUgaXRzIHByZXNlbmNlLCB5b3UgY2FuIHJlcXVpcmUgYGNvbXBvc2VyLXJ1bnRpbWUtYXBpIF4yLjBgCiAqLwpjbGFzcyBJbnN0YWxsZWRWZXJzaW9ucwp7CiAgICAvKioKICAgICAqIEB2YXIgbWl4ZWRbXXxudWxsCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5e3Jvb3Q6IGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZywgYWxpYXNlczogc3RyaW5nW10sIGRldjogYm9vbCwgaW5zdGFsbF9wYXRoOiBzdHJpbmcsIHR5cGU6IHN0cmluZ30sIHZlcnNpb25zOiBhcnJheTxzdHJpbmcsIGFycmF5e2Rldl9yZXF1aXJlbWVudDogYm9vbCwgcHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdLCBpbnN0YWxsX3BhdGg/OiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9Pn18YXJyYXl7fXxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRpbnN0YWxsZWQ7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2x8bnVsbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkY2FuR2V0VmVuZG9yczsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXlbXQogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIGFycmF5e3Jvb3Q6IGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZywgYWxpYXNlczogc3RyaW5nW10sIGRldjogYm9vbCwgaW5zdGFsbF9wYXRoOiBzdHJpbmcsIHR5cGU6IHN0cmluZ30sIHZlcnNpb25zOiBhcnJheTxzdHJpbmcsIGFycmF5e2Rldl9yZXF1aXJlbWVudDogYm9vbCwgcHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdLCBpbnN0YWxsX3BhdGg/OiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9Pn0+CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRpbnN0YWxsZWRCeVZlbmRvciA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgcGFja2FnZSBuYW1lcyB3aGljaCBhcmUgcHJlc2VudCwgZWl0aGVyIGJ5IGJlaW5nIGluc3RhbGxlZCwgcmVwbGFjZWQgb3IgcHJvdmlkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGxpc3Q8c3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEluc3RhbGxlZFBhY2thZ2VzKCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgJHBhY2thZ2VzW10gPSBhcnJheV9rZXlzKCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXNbMF07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfa2V5cyhhcnJheV9mbGlwKFxjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCAkcGFja2FnZXMpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgcGFja2FnZSBuYW1lcyB3aXRoIGEgc3BlY2lmaWMgdHlwZSBlLmcuICdsaWJyYXJ5JwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHR5cGUKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqIEBwc2FsbS1yZXR1cm4gbGlzdDxzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVkUGFja2FnZXNCeVR5cGUoJHR5cGUpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzQnlUeXBlID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewogICAgICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddIGFzICRuYW1lID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ3R5cGUnXSkgJiYgJHBhY2thZ2VbJ3R5cGUnXSA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNCeVR5cGVbXSA9ICRuYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2VzQnlUeXBlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIHBhY2thZ2UgaXMgaW5zdGFsbGVkCiAgICAgKgogICAgICogVGhpcyBhbHNvIHJldHVybnMgdHJ1ZSBpZiB0aGUgcGFja2FnZSBuYW1lIGlzIHByb3ZpZGVkIG9yIHJlcGxhY2VkIGJ5IGFub3RoZXIgcGFja2FnZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYWNrYWdlTmFtZQogICAgICogQHBhcmFtICBib29sICAgJGluY2x1ZGVEZXZSZXF1aXJlbWVudHMKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzSW5zdGFsbGVkKCRwYWNrYWdlTmFtZSwgJGluY2x1ZGVEZXZSZXF1aXJlbWVudHMgPSB0cnVlKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkaW5jbHVkZURldlJlcXVpcmVtZW50cyB8fCBlbXB0eSgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ2Rldl9yZXF1aXJlbWVudCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIHBhY2thZ2Ugc2F0aXNmaWVzIGEgdmVyc2lvbiBjb25zdHJhaW50CiAgICAgKgogICAgICogZS5nLiBJZiB5b3Ugd2FudCB0byBrbm93IHdoZXRoZXIgdmVyc2lvbiAyLjMrIG9mIHBhY2thZ2UgZm9vL2JhciBpcyBpbnN0YWxsZWQsIHlvdSB3b3VsZCBjYWxsOgogICAgICoKICAgICAqICAgQ29tcG9zZXJcSW5zdGFsbGVkVmVyc2lvbnM6OnNhdGlzZmllcyhuZXcgVmVyc2lvblBhcnNlciwgJ2Zvby9iYXInLCAnXjIuMycpCiAgICAgKgogICAgICogQHBhcmFtICBWZXJzaW9uUGFyc2VyICRwYXJzZXIgICAgICBJbnN0YWxsIGNvbXBvc2VyL3NlbXZlciB0byBoYXZlIGFjY2VzcyB0byB0aGlzIGNsYXNzIGFuZCBmdW5jdGlvbmFsaXR5CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xudWxsICAgJGNvbnN0cmFpbnQgIEEgdmVyc2lvbiBjb25zdHJhaW50IHRvIGNoZWNrIGZvciwgaWYgeW91IHBhc3Mgb25lIHlvdSBoYXZlIHRvIG1ha2Ugc3VyZSBjb21wb3Nlci9zZW12ZXIgaXMgcmVxdWlyZWQgYnkgeW91ciBwYWNrYWdlCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYXRpc2ZpZXMoVmVyc2lvblBhcnNlciAkcGFyc2VyLCAkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KQogICAgewogICAgICAgICRjb25zdHJhaW50ID0gJHBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCk7CiAgICAgICAgJHByb3ZpZGVkID0gJHBhcnNlci0+cGFyc2VDb25zdHJhaW50cyhzZWxmOjpnZXRWZXJzaW9uUmFuZ2VzKCRwYWNrYWdlTmFtZSkpOwoKICAgICAgICByZXR1cm4gJHByb3ZpZGVkLT5tYXRjaGVzKCRjb25zdHJhaW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSB2ZXJzaW9uIGNvbnN0cmFpbnQgcmVwcmVzZW50aW5nIGFsbCB0aGUgcmFuZ2Uocykgd2hpY2ggYXJlIGluc3RhbGxlZCBmb3IgYSBnaXZlbiBwYWNrYWdlCiAgICAgKgogICAgICogSXQgaXMgZWFzaWVyIHRvIHVzZSB0aGlzIHZpYSBpc0luc3RhbGxlZCgpIHdpdGggdGhlICRjb25zdHJhaW50IGFyZ3VtZW50IGlmIHlvdSBuZWVkIHRvIGNoZWNrCiAgICAgKiB3aGV0aGVyIGEgZ2l2ZW4gdmVyc2lvbiBvZiBhIHBhY2thZ2UgaXMgaW5zdGFsbGVkLCBhbmQgbm90IGp1c3Qgd2hldGhlciBpdCBleGlzdHMKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGFja2FnZU5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nIFZlcnNpb24gY29uc3RyYWludCB1c2FibGUgd2l0aCBjb21wb3Nlci9zZW12ZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRWZXJzaW9uUmFuZ2VzKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoIChzZWxmOjpnZXRJbnN0YWxsZWQoKSBhcyAkaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyYW5nZXMgPSBhcnJheSgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydwcmV0dHlfdmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgJHJhbmdlc1tdID0gJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydwcmV0dHlfdmVyc2lvbiddOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdhbGlhc2VzJywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgJHJhbmdlcyA9IGFycmF5X21lcmdlKCRyYW5nZXMsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsnYWxpYXNlcyddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygncmVwbGFjZWQnLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkcmFuZ2VzID0gYXJyYXlfbWVyZ2UoJHJhbmdlcywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydyZXBsYWNlZCddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygncHJvdmlkZWQnLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkcmFuZ2VzID0gYXJyYXlfbWVyZ2UoJHJhbmdlcywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydwcm92aWRlZCddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGltcGxvZGUoJyB8fCAnLCAkcmFuZ2VzKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBJZiB0aGUgcGFja2FnZSBpcyBiZWluZyByZXBsYWNlZCBvciBwcm92aWRlZCBidXQgaXMgbm90IHJlYWxseSBpbnN0YWxsZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZCBhcyB2ZXJzaW9uLCB1c2Ugc2F0aXNmaWVzIG9yIGdldFZlcnNpb25SYW5nZXMgaWYgeW91IG5lZWQgdG8ga25vdyBpZiBhIGdpdmVuIHZlcnNpb24gaXMgcHJlc2VudAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFZlcnNpb24oJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWyd2ZXJzaW9uJ107CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXE91dE9mQm91bmRzRXhjZXB0aW9uKCdQYWNrYWdlICInIC4gJHBhY2thZ2VOYW1lIC4gJyIgaXMgbm90IGluc3RhbGxlZCcpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkcGFja2FnZU5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgSWYgdGhlIHBhY2thZ2UgaXMgYmVpbmcgcmVwbGFjZWQgb3IgcHJvdmlkZWQgYnV0IGlzIG5vdCByZWFsbHkgaW5zdGFsbGVkLCBudWxsIHdpbGwgYmUgcmV0dXJuZWQgYXMgdmVyc2lvbiwgdXNlIHNhdGlzZmllcyBvciBnZXRWZXJzaW9uUmFuZ2VzIGlmIHlvdSBuZWVkIHRvIGtub3cgaWYgYSBnaXZlbiB2ZXJzaW9uIGlzIHByZXNlbnQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRQcmV0dHlWZXJzaW9uKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoIChzZWxmOjpnZXRJbnN0YWxsZWQoKSBhcyAkaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydwcmV0dHlfdmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ107CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXE91dE9mQm91bmRzRXhjZXB0aW9uKCdQYWNrYWdlICInIC4gJHBhY2thZ2VOYW1lIC4gJyIgaXMgbm90IGluc3RhbGxlZCcpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkcGFja2FnZU5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgSWYgdGhlIHBhY2thZ2UgaXMgYmVpbmcgcmVwbGFjZWQgb3IgcHJvdmlkZWQgYnV0IGlzIG5vdCByZWFsbHkgaW5zdGFsbGVkLCBudWxsIHdpbGwgYmUgcmV0dXJuZWQgYXMgcmVmZXJlbmNlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoIChzZWxmOjpnZXRJbnN0YWxsZWQoKSBhcyAkaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydyZWZlcmVuY2UnXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydyZWZlcmVuY2UnXTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBJZiB0aGUgcGFja2FnZSBpcyBiZWluZyByZXBsYWNlZCBvciBwcm92aWRlZCBidXQgaXMgbm90IHJlYWxseSBpbnN0YWxsZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZCBhcyBpbnN0YWxsIHBhdGguIFBhY2thZ2VzIG9mIHR5cGUgbWV0YXBhY2thZ2VzIGFsc28gaGF2ZSBhIG51bGwgaW5zdGFsbCBwYXRoLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEluc3RhbGxQYXRoKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoIChzZWxmOjpnZXRJbnN0YWxsZWQoKSBhcyAkaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ2luc3RhbGxfcGF0aCddKSA/ICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsnaW5zdGFsbF9wYXRoJ10gOiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignUGFja2FnZSAiJyAuICRwYWNrYWdlTmFtZSAuICciIGlzIG5vdCBpbnN0YWxsZWQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXl7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nLCBhbGlhc2VzOiBzdHJpbmdbXSwgZGV2OiBib29sLCBpbnN0YWxsX3BhdGg6IHN0cmluZywgdHlwZTogc3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFJvb3RQYWNrYWdlKCkKICAgIHsKICAgICAgICAkaW5zdGFsbGVkID0gc2VsZjo6Z2V0SW5zdGFsbGVkKCk7CgogICAgICAgIHJldHVybiAkaW5zdGFsbGVkWzBdWydyb290J107CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByYXcgaW5zdGFsbGVkLnBocCBkYXRhIGZvciBjdXN0b20gaW1wbGVtZW50YXRpb25zCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgVXNlIGdldEFsbFJhd0RhdGEoKSBpbnN0ZWFkIHdoaWNoIHJldHVybnMgYWxsIGRhdGFzZXRzIGZvciBhbGwgYXV0b2xvYWRlcnMgcHJlc2VudCBpbiB0aGUgcHJvY2Vzcy4gZ2V0UmF3RGF0YSBvbmx5IHJldHVybnMgdGhlIGZpcnN0IGRhdGFzZXQgbG9hZGVkLCB3aGljaCBtYXkgbm90IGJlIHdoYXQgeW91IGV4cGVjdC4KICAgICAqIEByZXR1cm4gYXJyYXlbXQogICAgICogQHBzYWxtLXJldHVybiBhcnJheXtyb290OiBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmcsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmcsIGFsaWFzZXM6IHN0cmluZ1tdLCBkZXY6IGJvb2wsIGluc3RhbGxfcGF0aDogc3RyaW5nLCB0eXBlOiBzdHJpbmd9LCB2ZXJzaW9uczogYXJyYXk8c3RyaW5nLCBhcnJheXtkZXZfcmVxdWlyZW1lbnQ6IGJvb2wsIHByZXR0eV92ZXJzaW9uPzogc3RyaW5nLCB2ZXJzaW9uPzogc3RyaW5nLCBhbGlhc2VzPzogc3RyaW5nW10sIHJlZmVyZW5jZT86IHN0cmluZywgcmVwbGFjZWQ/OiBzdHJpbmdbXSwgcHJvdmlkZWQ/OiBzdHJpbmdbXSwgaW5zdGFsbF9wYXRoPzogc3RyaW5nLCB0eXBlPzogc3RyaW5nfT59CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UmF3RGF0YSgpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3IoJ2dldFJhd0RhdGEgb25seSByZXR1cm5zIHRoZSBmaXJzdCBkYXRhc2V0IGxvYWRlZCwgd2hpY2ggbWF5IG5vdCBiZSB3aGF0IHlvdSBleHBlY3QuIFVzZSBnZXRBbGxSYXdEYXRhKCkgaW5zdGVhZCB3aGljaCByZXR1cm5zIGFsbCBkYXRhc2V0cyBmb3IgYWxsIGF1dG9sb2FkZXJzIHByZXNlbnQgaW4gdGhlIHByb2Nlc3MuJywgRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICBpZiAobnVsbCA9PT0gc2VsZjo6JGluc3RhbGxlZCkgewogICAgICAgICAgICAvLyBvbmx5IHJlcXVpcmUgdGhlIGluc3RhbGxlZC5waHAgZmlsZSBpZiB0aGlzIGZpbGUgaXMgbG9hZGVkIGZyb20gaXRzIGR1bXBlZCBsb2NhdGlvbiwKICAgICAgICAgICAgLy8gYW5kIG5vdCBmcm9tIGl0cyBzb3VyY2UgbG9jYXRpb24gaW4gdGhlIGNvbXBvc2VyL2NvbXBvc2VyIHBhY2thZ2UsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzk5MzcKICAgICAgICAgICAgaWYgKHN1YnN0cihfX0RJUl9fLCAtOCwgMSkgIT09ICdDJykgewogICAgICAgICAgICAgICAgc2VsZjo6JGluc3RhbGxlZCA9IGluY2x1ZGUgX19ESVJfXyAuICcvaW5zdGFsbGVkLnBocCc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWxmOjokaW5zdGFsbGVkID0gYXJyYXkoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRpbnN0YWxsZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByYXcgZGF0YSBvZiBhbGwgaW5zdGFsbGVkLnBocCB3aGljaCBhcmUgY3VycmVudGx5IGxvYWRlZCBmb3IgY3VzdG9tIGltcGxlbWVudGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXlbXQogICAgICogQHBzYWxtLXJldHVybiBsaXN0PGFycmF5e3Jvb3Q6IGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZywgYWxpYXNlczogc3RyaW5nW10sIGRldjogYm9vbCwgaW5zdGFsbF9wYXRoOiBzdHJpbmcsIHR5cGU6IHN0cmluZ30sIHZlcnNpb25zOiBhcnJheTxzdHJpbmcsIGFycmF5e2Rldl9yZXF1aXJlbWVudDogYm9vbCwgcHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdLCBpbnN0YWxsX3BhdGg/OiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9Pn0+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0QWxsUmF3RGF0YSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmdldEluc3RhbGxlZCgpOwogICAgfQoKICAgIC8qKgogICAgICogTGV0cyB5b3UgcmVsb2FkIHRoZSBzdGF0aWMgYXJyYXkgZnJvbSBhbm90aGVyIGZpbGUKICAgICAqCiAgICAgKiBUaGlzIGlzIG9ubHkgdXNlZnVsIGZvciBjb21wbGV4IGludGVncmF0aW9ucyBpbiB3aGljaCBhIHByb2plY3QgbmVlZHMgdG8gdXNlCiAgICAgKiB0aGlzIGNsYXNzIGJ1dCB0aGVuIGFsc28gbmVlZHMgdG8gZXhlY3V0ZSBhbm90aGVyIHByb2plY3QncyBhdXRvbG9hZGVyIGluIHByb2Nlc3MsCiAgICAgKiBhbmQgd2FudHMgdG8gZW5zdXJlIGJvdGggcHJvamVjdHMgaGF2ZSBhY2Nlc3MgdG8gdGhlaXIgdmVyc2lvbiBvZiBpbnN0YWxsZWQucGhwLgogICAgICoKICAgICAqIEEgdHlwaWNhbCBjYXNlIHdvdWxkIGJlIFBIUFVuaXQsIHdoZXJlIGl0IHdvdWxkIG5lZWQgdG8gbWFrZSBzdXJlIGl0IHJlYWRzIGFsbAogICAgICogdGhlIGRhdGEgaXQgbmVlZHMgZnJvbSB0aGlzIGNsYXNzLCB0aGVuIGNhbGwgcmVsb2FkKCkgd2l0aAogICAgICogYHJlcXVpcmUgJENXRC92ZW5kb3IvY29tcG9zZXIvaW5zdGFsbGVkLnBocGAgKG9yIHNpbWlsYXIpIGFzIGlucHV0IHRvIG1ha2Ugc3VyZQogICAgICogdGhlIHByb2plY3QgaW4gd2hpY2ggaXQgcnVucyBjYW4gdGhlbiBhbHNvIHVzZSB0aGlzIGNsYXNzIHNhZmVseSwgd2l0aG91dAogICAgICogaW50ZXJmZXJlbmNlIGJldHdlZW4gUEhQVW5pdCdzIGRlcGVuZGVuY2llcyBhbmQgdGhlIHByb2plY3QncyBkZXBlbmRlbmNpZXMuCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheVtdICRkYXRhIEEgdmVuZG9yL2NvbXBvc2VyL2luc3RhbGxlZC5waHAgZGF0YSBzZXQKICAgICAqIEByZXR1cm4gdm9pZAogICAgICoKICAgICAqIEBwc2FsbS1wYXJhbSBhcnJheXtyb290OiBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmcsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmcsIGFsaWFzZXM6IHN0cmluZ1tdLCBkZXY6IGJvb2wsIGluc3RhbGxfcGF0aDogc3RyaW5nLCB0eXBlOiBzdHJpbmd9LCB2ZXJzaW9uczogYXJyYXk8c3RyaW5nLCBhcnJheXtkZXZfcmVxdWlyZW1lbnQ6IGJvb2wsIHByZXR0eV92ZXJzaW9uPzogc3RyaW5nLCB2ZXJzaW9uPzogc3RyaW5nLCBhbGlhc2VzPzogc3RyaW5nW10sIHJlZmVyZW5jZT86IHN0cmluZywgcmVwbGFjZWQ/OiBzdHJpbmdbXSwgcHJvdmlkZWQ/OiBzdHJpbmdbXSwgaW5zdGFsbF9wYXRoPzogc3RyaW5nLCB0eXBlPzogc3RyaW5nfT59ICRkYXRhCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVsb2FkKCRkYXRhKQogICAgewogICAgICAgIHNlbGY6OiRpbnN0YWxsZWQgPSAkZGF0YTsKICAgICAgICBzZWxmOjokaW5zdGFsbGVkQnlWZW5kb3IgPSBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGxpc3Q8YXJyYXl7cm9vdDogYXJyYXl7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nLCBhbGlhc2VzOiBzdHJpbmdbXSwgZGV2OiBib29sLCBpbnN0YWxsX3BhdGg6IHN0cmluZywgdHlwZTogc3RyaW5nfSwgdmVyc2lvbnM6IGFycmF5PHN0cmluZywgYXJyYXl7ZGV2X3JlcXVpcmVtZW50OiBib29sLCBwcmV0dHlfdmVyc2lvbj86IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgYWxpYXNlcz86IHN0cmluZ1tdLCByZWZlcmVuY2U/OiBzdHJpbmcsIHJlcGxhY2VkPzogc3RyaW5nW10sIHByb3ZpZGVkPzogc3RyaW5nW10sIGluc3RhbGxfcGF0aD86IHN0cmluZywgdHlwZT86IHN0cmluZ30+fT4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVkKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gc2VsZjo6JGNhbkdldFZlbmRvcnMpIHsKICAgICAgICAgICAgc2VsZjo6JGNhbkdldFZlbmRvcnMgPSBtZXRob2RfZXhpc3RzKCdDb21wb3NlclxBdXRvbG9hZFxDbGFzc0xvYWRlcicsICdnZXRSZWdpc3RlcmVkTG9hZGVycycpOwogICAgICAgIH0KCiAgICAgICAgJGluc3RhbGxlZCA9IGFycmF5KCk7CgogICAgICAgIGlmIChzZWxmOjokY2FuR2V0VmVuZG9ycykgewogICAgICAgICAgICBmb3JlYWNoIChDbGFzc0xvYWRlcjo6Z2V0UmVnaXN0ZXJlZExvYWRlcnMoKSBhcyAkdmVuZG9yRGlyID0+ICRsb2FkZXIpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldChzZWxmOjokaW5zdGFsbGVkQnlWZW5kb3JbJHZlbmRvckRpcl0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxlZFtdID0gc2VsZjo6JGluc3RhbGxlZEJ5VmVuZG9yWyR2ZW5kb3JEaXJdOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2ZpbGUoJHZlbmRvckRpci4nL2NvbXBvc2VyL2luc3RhbGxlZC5waHAnKSkgewogICAgICAgICAgICAgICAgICAgICRpbnN0YWxsZWRbXSA9IHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvclskdmVuZG9yRGlyXSA9IHJlcXVpcmUgJHZlbmRvckRpci4nL2NvbXBvc2VyL2luc3RhbGxlZC5waHAnOwogICAgICAgICAgICAgICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaW5zdGFsbGVkICYmIHN0cnRyKCR2ZW5kb3JEaXIuJy9jb21wb3NlcicsICdcXCcsICcvJykgPT09IHN0cnRyKF9fRElSX18sICdcXCcsICcvJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZjo6JGluc3RhbGxlZCA9ICRpbnN0YWxsZWRbY291bnQoJGluc3RhbGxlZCkgLSAxXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIC8vIG9ubHkgcmVxdWlyZSB0aGUgaW5zdGFsbGVkLnBocCBmaWxlIGlmIHRoaXMgZmlsZSBpcyBsb2FkZWQgZnJvbSBpdHMgZHVtcGVkIGxvY2F0aW9uLAogICAgICAgICAgICAvLyBhbmQgbm90IGZyb20gaXRzIHNvdXJjZSBsb2NhdGlvbiBpbiB0aGUgY29tcG9zZXIvY29tcG9zZXIgcGFja2FnZSwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvOTkzNwogICAgICAgICAgICBpZiAoc3Vic3RyKF9fRElSX18sIC04LCAxKSAhPT0gJ0MnKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokaW5zdGFsbGVkID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9pbnN0YWxsZWQucGhwJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbGY6OiRpbnN0YWxsZWQgPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRpbnN0YWxsZWRbXSA9IHNlbGY6OiRpbnN0YWxsZWQ7CgogICAgICAgIHJldHVybiAkaW5zdGFsbGVkOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcU2lsZW5jZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcRmluZGVyOwoKLyoqCiAqIFJlYWRzL3dyaXRlcyB0byBhIGZpbGVzeXN0ZW0gY2FjaGUKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ2FjaGUKewogICAgLyoqIEB2YXIgYm9vbHxudWxsICovCiAgICBwcml2YXRlIHN0YXRpYyAkY2FjaGVDb2xsZWN0ZWQgPSBudWxsOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRyb290OwogICAgLyoqIEB2YXIgP2Jvb2wgKi8KICAgIHByaXZhdGUgJGVuYWJsZWQgPSBudWxsOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRhbGxvd2xpc3Q7CiAgICAvKiogQHZhciBGaWxlc3lzdGVtICovCiAgICBwcml2YXRlICRmaWxlc3lzdGVtOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkcmVhZE9ubHk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGNhY2hlRGlyICAgbG9jYXRpb24gb2YgdGhlIGNhY2hlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGFsbG93bGlzdCAgTGlzdCBvZiBjaGFyYWN0ZXJzIHRoYXQgYXJlIGFsbG93ZWQgaW4gcGF0aCBuYW1lcyAodXNlZCBpbiBhIHJlZ2V4IGNoYXJhY3RlciBjbGFzcykKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtICAkZmlsZXN5c3RlbSBvcHRpb25hbCBmaWxlc3lzdGVtIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJHJlYWRPbmx5ICAgd2hldGhlciB0aGUgY2FjaGUgaXMgaW4gcmVhZE9ubHkgbW9kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCAkY2FjaGVEaXIsICRhbGxvd2xpc3QgPSAnYS16MC05LicsIEZpbGVzeXN0ZW0gJGZpbGVzeXN0ZW0gPSBudWxsLCAkcmVhZE9ubHkgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPnJvb3QgPSBydHJpbSgkY2FjaGVEaXIsICcvXFwnKSAuICcvJzsKICAgICAgICAkdGhpcy0+YWxsb3dsaXN0ID0gJGFsbG93bGlzdDsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmaWxlc3lzdGVtID86IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgJHRoaXMtPnJlYWRPbmx5ID0gKGJvb2wpICRyZWFkT25seTsKCiAgICAgICAgaWYgKCFzZWxmOjppc1VzYWJsZSgkY2FjaGVEaXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5lbmFibGVkID0gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJHJlYWRPbmx5CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZWFkT25seSgkcmVhZE9ubHkpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlYWRPbmx5ID0gKGJvb2wpICRyZWFkT25seTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNSZWFkT25seSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZWFkT25seTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1VzYWJsZSgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gIVByZWc6OmlzTWF0Y2goJ3soXnxbXFxcXC9dKShcJG51bGx8bnVsfE5VTHwvZGV2L251bGwpKFtcXFxcL118JCl9JywgJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0VuYWJsZWQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZW5hYmxlZCA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+ZW5hYmxlZCA9IHRydWU7CgogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAoIWlzX2RpcigkdGhpcy0+cm9vdCkgJiYgIVNpbGVuY2VyOjpjYWxsKCdta2RpcicsICR0aGlzLT5yb290LCAwNzc3LCB0cnVlKSkKICAgICAgICAgICAgICAgIHx8ICFpc193cml0YWJsZSgkdGhpcy0+cm9vdCkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNhbm5vdCBjcmVhdGUgY2FjaGUgZGlyZWN0b3J5ICcgLiAkdGhpcy0+cm9vdCAuICcsIG9yIGRpcmVjdG9yeSBpcyBub3Qgd3JpdGFibGUuIFByb2NlZWRpbmcgd2l0aG91dCBjYWNoZTwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICR0aGlzLT5lbmFibGVkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZW5hYmxlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWQoJGZpbGUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc0VuYWJsZWQoKSkgewogICAgICAgICAgICAkZmlsZSA9IFByZWc6OnJlcGxhY2UoJ3tbXicuJHRoaXMtPmFsbG93bGlzdC4nXX1pJywgJy0nLCAkZmlsZSk7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGhpcy0+cm9vdCAuICRmaWxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdSZWFkaW5nICcuJHRoaXMtPnJvb3QgLiAkZmlsZS4nIGZyb20gY2FjaGUnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+cm9vdCAuICRmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRmaWxlLCAkY29udGVudHMpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc0VuYWJsZWQoKSAmJiAhJHRoaXMtPnJlYWRPbmx5KSB7CiAgICAgICAgICAgICRmaWxlID0gUHJlZzo6cmVwbGFjZSgne1teJy4kdGhpcy0+YWxsb3dsaXN0LiddfWknLCAnLScsICRmaWxlKTsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignV3JpdGluZyAnLiR0aGlzLT5yb290IC4gJGZpbGUuJyBpbnRvIGNhY2hlJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKCiAgICAgICAgICAgICR0ZW1wRmlsZU5hbWUgPSAkdGhpcy0+cm9vdCAuICRmaWxlIC4gdW5pcWlkKCcuJywgdHJ1ZSkgLiAnLnRtcCc7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmlsZV9wdXRfY29udGVudHMoJHRlbXBGaWxlTmFtZSwgJGNvbnRlbnRzKSAhPT0gZmFsc2UgJiYgcmVuYW1lKCR0ZW1wRmlsZU5hbWUsICR0aGlzLT5yb290IC4gJGZpbGUpOwogICAgICAgICAgICB9IGNhdGNoIChcRXJyb3JFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+RmFpbGVkIHRvIHdyaXRlIGludG8gY2FjaGU6ICcuJGUtPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15maWxlX3B1dF9jb250ZW50c1woXCk6IE9ubHkgKFswLTldKykgb2YgKFswLTldKykgYnl0ZXMgd3JpdHRlbn0nLCAkZS0+Z2V0TWVzc2FnZSgpLCAkbSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcGFydGlhbCBmaWxlLgogICAgICAgICAgICAgICAgICAgIHVubGluaygkdGVtcEZpbGVOYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAnPHdhcm5pbmc+V3JpdGluZyAlMSRzIGludG8gY2FjaGUgZmFpbGVkIGFmdGVyICUyJHUgb2YgJTMkdSBieXRlcyB3cml0dGVuLCBvbmx5ICU0JHUgYnl0ZXMgb2YgZnJlZSBzcGFjZSBhdmFpbGFibGU8L3dhcm5pbmc+JywKICAgICAgICAgICAgICAgICAgICAgICAgJHRlbXBGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgJG1bMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICRtWzJdLAogICAgICAgICAgICAgICAgICAgICAgICBAZGlza19mcmVlX3NwYWNlKGRpcm5hbWUoJHRlbXBGaWxlTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtZXNzYWdlKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3B5IGEgZmlsZSBpbnRvIHRoZSBjYWNoZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29weUZyb20oJGZpbGUsICRzb3VyY2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc0VuYWJsZWQoKSAmJiAhJHRoaXMtPnJlYWRPbmx5KSB7CiAgICAgICAgICAgICRmaWxlID0gUHJlZzo6cmVwbGFjZSgne1teJy4kdGhpcy0+YWxsb3dsaXN0LiddfWknLCAnLScsICRmaWxlKTsKICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cyhkaXJuYW1lKCR0aGlzLT5yb290IC4gJGZpbGUpKTsKCiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHNvdXJjZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPicuJHNvdXJjZS4nIGRvZXMgbm90IGV4aXN0LCBjYW4gbm90IHdyaXRlIGludG8gY2FjaGU8L2Vycm9yPicpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignV3JpdGluZyAnLiR0aGlzLT5yb290IC4gJGZpbGUuJyBpbnRvIGNhY2hlIGZyb20gJy4kc291cmNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGNvcHkoJHNvdXJjZSwgJHRoaXMtPnJvb3QgLiAkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3B5IGEgZmlsZSBvdXQgb2YgdGhlIGNhY2hlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3B5VG8oJGZpbGUsICR0YXJnZXQpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc0VuYWJsZWQoKSkgewogICAgICAgICAgICAkZmlsZSA9IFByZWc6OnJlcGxhY2UoJ3tbXicuJHRoaXMtPmFsbG93bGlzdC4nXX1pJywgJy0nLCAkZmlsZSk7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGhpcy0+cm9vdCAuICRmaWxlKSkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB0b3VjaCgkdGhpcy0+cm9vdCAuICRmaWxlLCBmaWxlbXRpbWUoJHRoaXMtPnJvb3QgLiAkZmlsZSksIHRpbWUoKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXJyb3JFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBmYWxsYmFjayBpbiBjYXNlIHRoZSBhYm92ZSBmYWlsZWQgZHVlIHRvIGluY29ycmVjdCBvd25lcnNoaXAKICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy80MDcwCiAgICAgICAgICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ3RvdWNoJywgJHRoaXMtPnJvb3QgLiAkZmlsZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdSZWFkaW5nICcuJHRoaXMtPnJvb3QgLiAkZmlsZS4nIGZyb20gY2FjaGUnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgIHJldHVybiBjb3B5KCR0aGlzLT5yb290IC4gJGZpbGUsICR0YXJnZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdjSXNOZWNlc3NhcnkoKQogICAgewogICAgICAgIGlmIChzZWxmOjokY2FjaGVDb2xsZWN0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JGNhY2hlQ29sbGVjdGVkID0gdHJ1ZTsKICAgICAgICBpZiAoUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfVEVTVF9TVUlURScpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+IDcwMDAwKSB7CiAgICAgICAgICAgIHJldHVybiAhcmFuZG9tX2ludCgwLCA1MCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gIW10X3JhbmQoMCwgNTApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCRmaWxlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgJGZpbGUgPSBQcmVnOjpyZXBsYWNlKCd7W14nLiR0aGlzLT5hbGxvd2xpc3QuJ119aScsICctJywgJGZpbGUpOwogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPnJvb3QgLiAkZmlsZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCR0aGlzLT5yb290IC4gJGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlzRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbXB0eURpcmVjdG9yeSgkdGhpcy0+cm9vdCk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUKICAgICAqIEByZXR1cm4gaW50fGZhbHNlCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gaW50PDAsIG1heD58ZmFsc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFnZSgkZmlsZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlzRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICRmaWxlID0gUHJlZzo6cmVwbGFjZSgne1teJy4kdGhpcy0+YWxsb3dsaXN0LiddfWknLCAnLScsICRmaWxlKTsKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCR0aGlzLT5yb290IC4gJGZpbGUpICYmICgkbXRpbWUgPSBmaWxlbXRpbWUoJHRoaXMtPnJvb3QgLiAkZmlsZSkpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFicyh0aW1lKCkgLSAkbXRpbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICR0dGwKICAgICAqIEBwYXJhbSBpbnQgJG1heFNpemUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdjKCR0dGwsICRtYXhTaXplKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgJGV4cGlyZSA9IG5ldyBcRGF0ZVRpbWUoKTsKICAgICAgICAgICAgJGV4cGlyZS0+bW9kaWZ5KCctJy4kdHRsLicgc2Vjb25kcycpOwoKICAgICAgICAgICAgJGZpbmRlciA9ICR0aGlzLT5nZXRGaW5kZXIoKS0+ZGF0ZSgndW50aWwgJy4kZXhwaXJlLT5mb3JtYXQoJ1ktbS1kIEg6aTpzJykpOwogICAgICAgICAgICBmb3JlYWNoICgkZmluZGVyIGFzICRmaWxlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCRmaWxlLT5nZXRQYXRobmFtZSgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRvdGFsU2l6ZSA9ICR0aGlzLT5maWxlc3lzdGVtLT5zaXplKCR0aGlzLT5yb290KTsKICAgICAgICAgICAgaWYgKCR0b3RhbFNpemUgPiAkbWF4U2l6ZSkgewogICAgICAgICAgICAgICAgJGl0ZXJhdG9yID0gJHRoaXMtPmdldEZpbmRlcigpLT5zb3J0QnlBY2Nlc3NlZFRpbWUoKS0+Z2V0SXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgIHdoaWxlICgkdG90YWxTaXplID4gJG1heFNpemUgJiYgJGl0ZXJhdG9yLT52YWxpZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGZpbGVwYXRoID0gJGl0ZXJhdG9yLT5jdXJyZW50KCktPmdldFBhdGhuYW1lKCk7CiAgICAgICAgICAgICAgICAgICAgJHRvdGFsU2l6ZSAtPSAkdGhpcy0+ZmlsZXN5c3RlbS0+c2l6ZSgkZmlsZXBhdGgpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT51bmxpbmsoJGZpbGVwYXRoKTsKICAgICAgICAgICAgICAgICAgICAkaXRlcmF0b3ItPm5leHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2VsZjo6JGNhY2hlQ29sbGVjdGVkID0gdHJ1ZTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzaGExKCRmaWxlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgJGZpbGUgPSBQcmVnOjpyZXBsYWNlKCd7W14nLiR0aGlzLT5hbGxvd2xpc3QuJ119aScsICctJywgJGZpbGUpOwogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPnJvb3QgLiAkZmlsZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzaGExX2ZpbGUoJHRoaXMtPnJvb3QgLiAkZmlsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hhMjU2KCRmaWxlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgJGZpbGUgPSBQcmVnOjpyZXBsYWNlKCd7W14nLiR0aGlzLT5hbGxvd2xpc3QuJ119aScsICctJywgJGZpbGUpOwogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPnJvb3QgLiAkZmlsZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoYXNoX2ZpbGUoJ3NoYTI1NicsICR0aGlzLT5yb290IC4gJGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEZpbmRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0RmluZGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gRmluZGVyOjpjcmVhdGUoKS0+aW4oJHRoaXMtPnJvb3QpLT5maWxlcygpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxQbGF0Zm9ybVxIaHZtRGV0ZWN0b3I7CnVzZSBDb21wb3NlclxQbGF0Zm9ybVxSdW50aW1lOwp1c2UgQ29tcG9zZXJcUGxhdGZvcm1cVmVyc2lvbjsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKdXNlIENvbXBvc2VyXFhkZWJ1Z0hhbmRsZXJcWGRlYnVnSGFuZGxlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBQbGF0Zm9ybVJlcG9zaXRvcnkgZXh0ZW5kcyBBcnJheVJlcG9zaXRvcnkKewogICAgY29uc3QgUExBVEZPUk1fUEFDS0FHRV9SRUdFWCA9ICd7Xig/OnBocCg/Oi02NGJpdHwtaXB2NnwtenRzfC1kZWJ1Zyk/fGhodm18KD86ZXh0fGxpYiktW2EtejAtOV0oPzpbXy4tXT9bYS16MC05XSspKnxjb21wb3Nlcig/Oi0oPzpwbHVnaW58cnVudGltZSktYXBpKT8pJH1pRCc7CgogICAgLyoqCiAgICAgKiBAdmFyID9zdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGxhc3RTZWVuUGxhdGZvcm1QaHAgPSBudWxsOwoKICAgIC8qKgogICAgICogQHZhciBWZXJzaW9uUGFyc2VyCiAgICAgKi8KICAgIHByaXZhdGUgJHZlcnNpb25QYXJzZXI7CgogICAgLyoqCiAgICAgKiBEZWZpbmVzIG92ZXJyaWRlcyBzbyB0aGF0IHRoZSBwbGF0Zm9ybSBjYW4gYmUgbW9ja2VkCiAgICAgKgogICAgICogS2V5ZWQgYnkgcGFja2FnZSBuYW1lIChsb3dlcmNhc2VkKQogICAgICoKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZ3xmYWxzZX0+CiAgICAgKi8KICAgIHByaXZhdGUgJG92ZXJyaWRlcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBTdG9yZXMgd2hpY2ggcGFja2FnZXMgaGF2ZSBiZWVuIGRpc2FibGVkIGFuZCB0aGVpciBhY3R1YWwgdmVyc2lvbgogICAgICoKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U+CiAgICAgKi8KICAgIHByaXZhdGUgJGRpc2FibGVkUGFja2FnZXMgPSBhcnJheSgpOwoKICAgIC8qKiBAdmFyIFJ1bnRpbWUgKi8KICAgIHByaXZhdGUgJHJ1bnRpbWU7CiAgICAvKiogQHZhciBIaHZtRGV0ZWN0b3IgKi8KICAgIHByaXZhdGUgJGhodm1EZXRlY3RvcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZ3xmYWxzZT4gJG92ZXJyaWRlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHBhY2thZ2VzID0gYXJyYXkoKSwgYXJyYXkgJG92ZXJyaWRlcyA9IGFycmF5KCksIFJ1bnRpbWUgJHJ1bnRpbWUgPSBudWxsLCBIaHZtRGV0ZWN0b3IgJGhodm1EZXRlY3RvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnJ1bnRpbWUgPSAkcnVudGltZSA/OiBuZXcgUnVudGltZSgpOwogICAgICAgICR0aGlzLT5oaHZtRGV0ZWN0b3IgPSAkaGh2bURldGVjdG9yID86IG5ldyBIaHZtRGV0ZWN0b3IoKTsKICAgICAgICBmb3JlYWNoICgkb3ZlcnJpZGVzIGFzICRuYW1lID0+ICR2ZXJzaW9uKSB7CiAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCR2ZXJzaW9uKSAmJiBmYWxzZSAhPT0gJHZlcnNpb24pIHsgLy8gQHBocHN0YW4taWdub3JlLWxpbmUKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdjb25maWcucGxhdGZvcm0uJy4kbmFtZS4nIHNob3VsZCBiZSBhIHN0cmluZyBvciBmYWxzZSwgYnV0IGdvdCAnLmdldHR5cGUoJHZlcnNpb24pLicgJy52YXJfZXhwb3J0KCR2ZXJzaW9uLCB0cnVlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRuYW1lID09PSAncGhwJyAmJiAkdmVyc2lvbiA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdjb25maWcucGxhdGZvcm0uJy4kbmFtZS4nIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2UgYXMgeW91IGNhbm5vdCBkaXNhYmxlIHBocCBlbnRpcmVseS4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+b3ZlcnJpZGVzW3N0cnRvbG93ZXIoJG5hbWUpXSA9IGFycmF5KCduYW1lJyA9PiAkbmFtZSwgJ3ZlcnNpb24nID0+ICR2ZXJzaW9uKTsKICAgICAgICB9CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcGFja2FnZXMpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdwbGF0Zm9ybSByZXBvJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAkbmFtZQogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1BsYXRmb3JtUGFja2FnZURpc2FibGVkKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZGlzYWJsZWRQYWNrYWdlc1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIENvbXBsZXRlUGFja2FnZUludGVyZmFjZT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc2FibGVkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGlzYWJsZWRQYWNrYWdlczsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKCiAgICAgICAgLy8gQWRkIGVhY2ggb2YgdGhlIG92ZXJyaWRlIHZlcnNpb25zIGFzIG9wdGlvbnMuCiAgICAgICAgLy8gTGF0ZXIgd2UgbWlnaHQgZXZlbiByZXBsYWNlIHRoZSBleHRlbnNpb25zIGluc3RlYWQuCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm92ZXJyaWRlcyBhcyAkb3ZlcnJpZGUpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCBpdCdzIGEgcGxhdGZvcm0gcGFja2FnZS4KICAgICAgICAgICAgaWYgKCFzZWxmOjppc1BsYXRmb3JtUGFja2FnZSgkb3ZlcnJpZGVbJ25hbWUnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIHBsYXRmb3JtIHBhY2thZ2UgbmFtZSBpbiBjb25maWcucGxhdGZvcm06ICcuJG92ZXJyaWRlWyduYW1lJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG92ZXJyaWRlWyd2ZXJzaW9uJ10gIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkT3ZlcnJpZGRlblBhY2thZ2UoJG92ZXJyaWRlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHByZXR0eVZlcnNpb24gPSBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpOwogICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJGNvbXBvc2VyID0gbmV3IENvbXBsZXRlUGFja2FnZSgnY29tcG9zZXInLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICRjb21wb3Nlci0+c2V0RGVzY3JpcHRpb24oJ0NvbXBvc2VyIHBhY2thZ2UnKTsKICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkY29tcG9zZXIpOwoKICAgICAgICAkcHJldHR5VmVyc2lvbiA9IFBsdWdpbkludGVyZmFjZTo6UExVR0lOX0FQSV9WRVJTSU9OOwogICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJGNvbXBvc2VyUGx1Z2luQXBpID0gbmV3IENvbXBsZXRlUGFja2FnZSgnY29tcG9zZXItcGx1Z2luLWFwaScsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJGNvbXBvc2VyUGx1Z2luQXBpLT5zZXREZXNjcmlwdGlvbignVGhlIENvbXBvc2VyIFBsdWdpbiBBUEknKTsKICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkY29tcG9zZXJQbHVnaW5BcGkpOwoKICAgICAgICAkcHJldHR5VmVyc2lvbiA9IENvbXBvc2VyOjpSVU5USU1FX0FQSV9WRVJTSU9OOwogICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJGNvbXBvc2VyUnVudGltZUFwaSA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJ2NvbXBvc2VyLXJ1bnRpbWUtYXBpJywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAkY29tcG9zZXJSdW50aW1lQXBpLT5zZXREZXNjcmlwdGlvbignVGhlIENvbXBvc2VyIFJ1bnRpbWUgQVBJJyk7CiAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJGNvbXBvc2VyUnVudGltZUFwaSk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdQSFBfVkVSU0lPTicpOwogICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHByZXR0eVZlcnNpb24pOwogICAgICAgIH0gY2F0Y2ggKFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSBQcmVnOjpyZXBsYWNlKCcjXihbXn4rLV0rKS4qJCMnLCAnJDEnLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1BIUF9WRVJTSU9OJykpOwogICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHByZXR0eVZlcnNpb24pOwogICAgICAgIH0KCiAgICAgICAgJHBocCA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJ3BocCcsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJHBocC0+c2V0RGVzY3JpcHRpb24oJ1RoZSBQSFAgaW50ZXJwcmV0ZXInKTsKICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGhwKTsKCiAgICAgICAgaWYgKCR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnUEhQX0RFQlVHJykpIHsKICAgICAgICAgICAgJHBocGRlYnVnID0gbmV3IENvbXBsZXRlUGFja2FnZSgncGhwLWRlYnVnJywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgJHBocGRlYnVnLT5zZXREZXNjcmlwdGlvbignVGhlIFBIUCBpbnRlcnByZXRlciwgd2l0aCBkZWJ1Z2dpbmcgc3ltYm9scycpOwogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGhwZGVidWcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5ydW50aW1lLT5oYXNDb25zdGFudCgnUEhQX1pUUycpICYmICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnUEhQX1pUUycpKSB7CiAgICAgICAgICAgICRwaHB6dHMgPSBuZXcgQ29tcGxldGVQYWNrYWdlKCdwaHAtenRzJywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgJHBocHp0cy0+c2V0RGVzY3JpcHRpb24oJ1RoZSBQSFAgaW50ZXJwcmV0ZXIsIHdpdGggWmVuZCBUaHJlYWQgU2FmZXR5Jyk7CiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRwaHB6dHMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnUEhQX0lOVF9TSVpFJykgPT09IDgpIHsKICAgICAgICAgICAgJHBocDY0ID0gbmV3IENvbXBsZXRlUGFja2FnZSgncGhwLTY0Yml0JywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgJHBocDY0LT5zZXREZXNjcmlwdGlvbignVGhlIFBIUCBpbnRlcnByZXRlciwgNjRiaXQnKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBocDY0KTsKICAgICAgICB9CgogICAgICAgIC8vIFRoZSBBRl9JTkVUNiBjb25zdGFudCBpcyBvbmx5IGRlZmluZWQgaWYgZXh0LXNvY2tldHMgaXMgYXZhaWxhYmxlIGJ1dAogICAgICAgIC8vIElQdjYgc3VwcG9ydCBtaWdodCBzdGlsbCBiZSBhdmFpbGFibGUuCiAgICAgICAgaWYgKCR0aGlzLT5ydW50aW1lLT5oYXNDb25zdGFudCgnQUZfSU5FVDYnKSB8fCBTaWxlbmNlcjo6Y2FsbChhcnJheSgkdGhpcy0+cnVudGltZSwgJ2ludm9rZScpLCAnaW5ldF9wdG9uJywgYXJyYXkoJzo6JykpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkcGhwSXB2NiA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJ3BocC1pcHY2JywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgJHBocElwdjYtPnNldERlc2NyaXB0aW9uKCdUaGUgUEhQIGludGVycHJldGVyLCB3aXRoIElQdjYgc3VwcG9ydCcpOwogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGhwSXB2Nik7CiAgICAgICAgfQoKICAgICAgICAkbG9hZGVkRXh0ZW5zaW9ucyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25zKCk7CgogICAgICAgIC8vIEV4dGVuc2lvbnMgc2Nhbm5pbmcKICAgICAgICBmb3JlYWNoICgkbG9hZGVkRXh0ZW5zaW9ucyBhcyAkbmFtZSkgewogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJG5hbWUsIGFycmF5KCdzdGFuZGFyZCcsICdDb3JlJykpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmFkZEV4dGVuc2lvbigkbmFtZSwgJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvblZlcnNpb24oJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIC8vIENoZWNrIGZvciBYZGVidWcgaW4gYSByZXN0YXJ0ZWQgcHJvY2VzcwogICAgICAgIGlmICghaW5fYXJyYXkoJ3hkZWJ1ZycsICRsb2FkZWRFeHRlbnNpb25zLCB0cnVlKSAmJiAoJHByZXR0eVZlcnNpb24gPSBYZGVidWdIYW5kbGVyOjpnZXRTa2lwcGVkVmVyc2lvbigpKSkgewogICAgICAgICAgICAkdGhpcy0+YWRkRXh0ZW5zaW9uKCd4ZGVidWcnLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgfQoKICAgICAgICAvLyBBbm90aGVyIHF1aWNrIGxvb3AsIGp1c3QgZm9yIHBvc3NpYmxlIGxpYnJhcmllcwogICAgICAgIC8vIERvaW5nIGl0IHRoaXMgd2F5IHRvIGtub3cgdGhhdCBmdW5jdGlvbnMgb3IgY29uc3RhbnRzIGV4aXN0IGJlZm9yZQogICAgICAgIC8vIHJlbHlpbmcgb24gdGhlbS4KICAgICAgICBmb3JlYWNoICgkbG9hZGVkRXh0ZW5zaW9ucyBhcyAkbmFtZSkgewogICAgICAgICAgICBzd2l0Y2ggKCRuYW1lKSB7CiAgICAgICAgICAgICAgICBjYXNlICdhbXFwJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gbGlicmFiYml0bXEgdmVyc2lvbiA9PiAwLjkuMAogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXmxpYnJhYmJpdG1xIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRsaWJyYWJiaXRtcU1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGlicmFiYml0bXEnLCAkbGlicmFiYml0bXFNYXRjaGVzWyd2ZXJzaW9uJ10sICdBTVFQIGxpYnJhYmJpdG1xIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEFNUVAgcHJvdG9jb2wgdmVyc2lvbiA9PiAwLTktMQogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXkFNUVAgcHJvdG9jb2wgdmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJHByb3RvY29sTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1wcm90b2NvbCcsIHN0cl9yZXBsYWNlKCctJywgJy4nLCAkcHJvdG9jb2xNYXRjaGVzWyd2ZXJzaW9uJ10pLCAnQU1RUCBwcm90b2NvbCB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2J6Mic6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIC8vIEJaaXAyIFZlcnNpb24gPT4gMS4wLjYsIDYtU2VwdC0yMDEwCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9eQlppcDIgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4qKSwvaW0nLCAkaW5mbywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCAkbWF0Y2hlc1sndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnY3VybCc6CiAgICAgICAgICAgICAgICAgICAgJGN1cmxWZXJzaW9uID0gJHRoaXMtPnJ1bnRpbWUtPmludm9rZSgnY3VybF92ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUsICRjdXJsVmVyc2lvblsndmVyc2lvbiddKTsKCiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIC8vIFNTTCBWZXJzaW9uID0+IE9wZW5TU0wvMS4wLjF0CiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teU1NMIFZlcnNpb24gPT4gKD88bGlicmFyeT5bXi9dKykvKD88dmVyc2lvbj4uKykkfWltJywgJGluZm8sICRzc2xNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGlicmFyeSA9IHN0cnRvbG93ZXIoJHNzbE1hdGNoZXNbJ2xpYnJhcnknXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGlicmFyeSA9PT0gJ29wZW5zc2wnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFyc2VkVmVyc2lvbiA9IFZlcnNpb246OnBhcnNlT3BlbnNzbCgkc3NsTWF0Y2hlc1sndmVyc2lvbiddLCAkaXNGaXBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictb3BlbnNzbCcuKCRpc0ZpcHMgPyAnLWZpcHMnIDogJycpLCAkcGFyc2VkVmVyc2lvbiwgJ2N1cmwgT3BlblNTTCB2ZXJzaW9uICgnLiRwYXJzZWRWZXJzaW9uLicpJywgYXJyYXkoKSwgJGlzRmlwcyA/IGFycmF5KCdjdXJsLW9wZW5zc2wnKSA6IGFycmF5KCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy0nLiRsaWJyYXJ5LCAkc3NsTWF0Y2hlc1sndmVyc2lvbiddLCAnY3VybCAnLiRsaWJyYXJ5LicgdmVyc2lvbiAoJy4kc3NsTWF0Y2hlc1sndmVyc2lvbiddLicpJywgYXJyYXkoJ2N1cmwtb3BlbnNzbCcpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gbGliU1NIIFZlcnNpb24gPT4gbGlic3NoMi8xLjQuMwogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XmxpYlNTSCBWZXJzaW9uID0+ICg/PGxpYnJhcnk+W14vXSspLyg/PHZlcnNpb24+Lis/KSg/Oi8uKik/JH1pbScsICRpbmZvLCAkc3NoTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy0nLnN0cnRvbG93ZXIoJHNzaE1hdGNoZXNbJ2xpYnJhcnknXSksICRzc2hNYXRjaGVzWyd2ZXJzaW9uJ10sICdjdXJsICcuJHNzaE1hdGNoZXNbJ2xpYnJhcnknXS4nIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFpMaWIgVmVyc2lvbiA9PiAxLjIuOAogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XlpMaWIgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSR9aW0nLCAkaW5mbywgJHpsaWJNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLXpsaWInLCAkemxpYk1hdGNoZXNbJ3ZlcnNpb24nXSwgJ2N1cmwgemxpYiB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2RhdGUnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyB0aW1lbGliIHZlcnNpb24gPT4gMjAxOC4wMwogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXnRpbWVsaWIgdmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJHRpbWVsaWJNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLXRpbWVsaWInLCAkdGltZWxpYk1hdGNoZXNbJ3ZlcnNpb24nXSwgJ2RhdGUgdGltZWxpYiB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUaW1lem9uZSBEYXRhYmFzZSA9PiBpbnRlcm5hbAogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXlRpbWV6b25lIERhdGFiYXNlID0+ICg/PHNvdXJjZT5pbnRlcm5hbHxleHRlcm5hbCkkL2ltJywgJGluZm8sICR6b25laW5mb1NvdXJjZU1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRleHRlcm5hbCA9ICR6b25laW5mb1NvdXJjZU1hdGNoZXNbJ3NvdXJjZSddID09PSAnZXh0ZXJuYWwnOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL14iT2xzb24iIFRpbWV6b25lIERhdGFiYXNlIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKz8pKFwuc3lzdGVtKT8kL2ltJywgJGluZm8sICR6b25laW5mb01hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdGltZXpvbmVkYiBpcyBwcm92aWRlZCBieSBleHQvdGltZXpvbmVkYiwgcmVnaXN0ZXIgdGhhdCB2ZXJzaW9uIGFzIGEgcmVwbGFjZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZXh0ZXJuYWwgJiYgaW5fYXJyYXkoJ3RpbWV6b25lZGInLCAkbG9hZGVkRXh0ZW5zaW9ucywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgndGltZXpvbmVkYi16b25laW5mbycsICR6b25laW5mb01hdGNoZXNbJ3ZlcnNpb24nXSwgJ3pvbmVpbmZvICgiT2xzb24iKSBkYXRhYmFzZSBmb3IgZGF0ZSAocmVwbGFjZWQgYnkgdGltZXpvbmVkYiknLCBhcnJheSgkbmFtZS4nLXpvbmVpbmZvJykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLXpvbmVpbmZvJywgJHpvbmVpbmZvTWF0Y2hlc1sndmVyc2lvbiddLCAnem9uZWluZm8gKCJPbHNvbiIpIGRhdGFiYXNlIGZvciBkYXRlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnZmlsZWluZm8nOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBsaWJtYWdpYyA9PiA1MzcKICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL15saWJtYWdpYyA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJG1hZ2ljTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJtYWdpYycsICRtYWdpY01hdGNoZXNbJ3ZlcnNpb24nXSwgJ2ZpbGVpbmZvIGxpYm1hZ2ljIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnZ2QnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ0dEX1ZFUlNJT04nKSk7CgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL15saWJKUEVHIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKz8pKD86IGNvbXBhdGlibGUpPyQvaW0nLCAkaW5mbywgJGxpYmpwZWdNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYmpwZWcnLCBWZXJzaW9uOjpwYXJzZUxpYmpwZWcoJGxpYmpwZWdNYXRjaGVzWyd2ZXJzaW9uJ10pLCAnbGlianBlZyB2ZXJzaW9uIGZvciBnZCcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9ebGliUE5HIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRsaWJwbmdNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYnBuZycsICRsaWJwbmdNYXRjaGVzWyd2ZXJzaW9uJ10sICdsaWJwbmcgdmVyc2lvbiBmb3IgZ2QnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXkZyZWVUeXBlIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRmcmVldHlwZU1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictZnJlZXR5cGUnLCAkZnJlZXR5cGVNYXRjaGVzWyd2ZXJzaW9uJ10sICdmcmVldHlwZSB2ZXJzaW9uIGZvciBnZCcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9ebGliWHBtIFZlcnNpb24gPT4gKD88dmVyc2lvbklkPlxkKykkL2ltJywgJGluZm8sICRsaWJ4cG1NYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYnhwbScsIFZlcnNpb246OmNvbnZlcnRMaWJ4cG1WZXJzaW9uSWQoJGxpYnhwbU1hdGNoZXNbJ3ZlcnNpb25JZCddKSwgJ2xpYnhwbSB2ZXJzaW9uIGZvciBnZCcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnZ21wJzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZSwgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdHTVBfVkVSU0lPTicpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdpY29udic6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnSUNPTlZfVkVSU0lPTicpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdpbnRsJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJ1RoZSBJQ1UgdW5pY29kZSBhbmQgZ2xvYmFsaXphdGlvbiBzdXBwb3J0IGxpYnJhcnknOwogICAgICAgICAgICAgICAgICAgIC8vIFRydXRoeSBjaGVjayBpcyBmb3IgdGVzdGluZyBvbmx5IHNvIHdlIGNhbiBtYWtlIHRoZSBjb25kaXRpb24gZmFpbAogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ0lOVExfSUNVX1ZFUlNJT04nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgnaWN1JywgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdJTlRMX0lDVV9WRVJTSU9OJyksICRkZXNjcmlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKFByZWc6OmlzTWF0Y2goJy9eSUNVIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgnaWN1JywgJG1hdGNoZXNbJ3ZlcnNpb24nXSwgJGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIElDVSBUWkRhdGEgdmVyc2lvbiA9PiAyMDE5YwogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXklDVSBUWkRhdGEgdmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4qKSQvaW0nLCAkaW5mbywgJHpvbmVpbmZvTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2ljdS16b25laW5mbycsIFZlcnNpb246OnBhcnNlWm9uZWluZm9WZXJzaW9uKCR6b25laW5mb01hdGNoZXNbJ3ZlcnNpb24nXSksICd6b25laW5mbyAoIk9sc29uIikgZGF0YWJhc2UgZm9yIGljdScpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGEgc2VwYXJhdGUgdmVyc2lvbiBmb3IgdGhlIENMRFIgbGlicmFyeSB2ZXJzaW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5ydW50aW1lLT5oYXNDbGFzcygnUmVzb3VyY2VCdW5kbGUnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY2xkclZlcnNpb24gPSAkdGhpcy0+cnVudGltZS0+aW52b2tlKGFycmF5KCdSZXNvdXJjZUJ1bmRsZScsICdjcmVhdGUnKSwgYXJyYXkoJ3Jvb3QnLCAnSUNVREFUQScsIGZhbHNlKSktPmdldCgnVmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgnaWN1LWNsZHInLCAkY2xkclZlcnNpb24sICdJQ1UgQ0xEUiBwcm9qZWN0IHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ2xhc3MoJ0ludGxDaGFyJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2ljdS11bmljb2RlJywgaW1wbG9kZSgnLicsIGFycmF5X3NsaWNlKCR0aGlzLT5ydW50aW1lLT5pbnZva2UoYXJyYXkoJ0ludGxDaGFyJywgJ2dldFVuaWNvZGVWZXJzaW9uJykpLCAwLCAzKSksICdJQ1UgdW5pY29kZSB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2ltYWdpY2snOgogICAgICAgICAgICAgICAgICAgICRpbWFnZU1hZ2lja1ZlcnNpb24gPSAkdGhpcy0+cnVudGltZS0+Y29uc3RydWN0KCdJbWFnaWNrJyktPmdldFZlcnNpb24oKTsKICAgICAgICAgICAgICAgICAgICAvLyA2Lng6IEltYWdlTWFnaWNrIDYuMi45IDA4LzI0LzA2IFExNiBodHRwOi8vd3d3LmltYWdlbWFnaWNrLm9yZwogICAgICAgICAgICAgICAgICAgIC8vIDcueDogSW1hZ2VNYWdpY2sgNy4wLjgtMzQgUTE2IHg4Nl82NCAyMDE5LTAzLTIzIGh0dHBzOi8vaW1hZ2VtYWdpY2sub3JnCiAgICAgICAgICAgICAgICAgICAgUHJlZzo6bWF0Y2goJy9eSW1hZ2VNYWdpY2sgKD88dmVyc2lvbj5bXGQuXSspKD86LSg/PHBhdGNoPlxkKykpPy8nLCAkaW1hZ2VNYWdpY2tWZXJzaW9uWyd2ZXJzaW9uU3RyaW5nJ10sICRtYXRjaGVzKTsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICRtYXRjaGVzWyd2ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWydwYXRjaCddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiAuPSAnLicuJG1hdGNoZXNbJ3BhdGNoJ107CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWltYWdlbWFnaWNrJywgJHZlcnNpb24sIG51bGwsIGFycmF5KCdpbWFnaWNrJykpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2xkYXAnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL15WZW5kb3IgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uSWQ+XGQrKSQvaW0nLCAkaW5mbywgJG1hdGNoZXMpICYmIFByZWc6OmlzTWF0Y2goJy9eVmVuZG9yIE5hbWUgPT4gKD88dmVuZG9yPi4rKSQvaW0nLCAkaW5mbywgJHZlbmRvck1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictJy5zdHJ0b2xvd2VyKCR2ZW5kb3JNYXRjaGVzWyd2ZW5kb3InXSksIFZlcnNpb246OmNvbnZlcnRPcGVubGRhcFZlcnNpb25JZCgkbWF0Y2hlc1sndmVyc2lvbklkJ10pLCAkdmVuZG9yTWF0Y2hlc1sndmVuZG9yJ10uJyB2ZXJzaW9uIG9mIGxkYXAnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnbGlieG1sJzoKICAgICAgICAgICAgICAgICAgICAvLyBleHQvZG9tLCBleHQvc2ltcGxleG1sLCBleHQveG1scmVhZGVyIGFuZCBleHQveG1sd3JpdGVyIHVzZSB0aGUgc2FtZSBsaWJ4bWwgYXMgdGhlIGV4dC9saWJ4bWwKICAgICAgICAgICAgICAgICAgICAkbGlieG1sUHJvdmlkZXMgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRleHRlbnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRleHRlbnNpb24gLiAnLWxpYnhtbCc7CiAgICAgICAgICAgICAgICAgICAgfSwgYXJyYXlfaW50ZXJzZWN0KCRsb2FkZWRFeHRlbnNpb25zLCBhcnJheSgnZG9tJywgJ3NpbXBsZXhtbCcsICd4bWwnLCAneG1scmVhZGVyJywgJ3htbHdyaXRlcicpKSk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnTElCWE1MX0RPVFRFRF9WRVJTSU9OJyksICdsaWJ4bWwgbGlicmFyeSB2ZXJzaW9uJywgYXJyYXkoKSwgJGxpYnhtbFByb3ZpZGVzKTsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnbWJzdHJpbmcnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBsaWJtYmZsIHZlcnNpb24gPT4gMS4zLjIKICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL15saWJtYmZsIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRsaWJtYmZsTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJtYmZsJywgJGxpYm1iZmxNYXRjaGVzWyd2ZXJzaW9uJ10sICdtYnN0cmluZyBsaWJtYmZsIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ01CX09OSUdVUlVNQV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1vbmlndXJ1bWEnLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ01CX09OSUdVUlVNQV9WRVJTSU9OJyksICdtYnN0cmluZyBvbmlndXJ1bWEgdmVyc2lvbicpOwoKICAgICAgICAgICAgICAgICAgICAvLyBNdWx0aWJ5dGUgcmVnZXggKG9uaWd1cnVtYSkgdmVyc2lvbiA9PiA1LjkuNQogICAgICAgICAgICAgICAgICAgIC8vIG9uaWd1cnVtYSB2ZXJzaW9uID0+IDYuOS4wCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKFByZWc6OmlzTWF0Y2goJy9eKD86b25pZ3VydW1hfE11bHRpYnl0ZSByZWdleCBcKG9uaWd1cnVtYVwpKSB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkb25pZ3VydW1hTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1vbmlndXJ1bWEnLCAkb25pZ3VydW1hTWF0Y2hlc1sndmVyc2lvbiddLCAnbWJzdHJpbmcgb25pZ3VydW1hIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ21lbWNhY2hlZCc6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIC8vIGxpYm1lbWNhY2hlZCB2ZXJzaW9uID0+IDEuMC4xOAogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXmxpYm1lbWNhY2hlZCB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJtZW1jYWNoZWQnLCAkbWF0Y2hlc1sndmVyc2lvbiddLCAnbGlibWVtY2FjaGVkIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnb3BlbnNzbCc6CiAgICAgICAgICAgICAgICAgICAgLy8gT3BlblNTTCAxLjEuMWcgIDIxIEFwciAyMDIwCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKD86T3BlblNTTHxMaWJyZVNTTCk/XHMqKD88dmVyc2lvbj5cUyspfWknLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ09QRU5TU0xfVkVSU0lPTl9URVhUJyksICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFyc2VkVmVyc2lvbiA9IFZlcnNpb246OnBhcnNlT3BlbnNzbCgkbWF0Y2hlc1sndmVyc2lvbiddLCAkaXNGaXBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuKCRpc0ZpcHMgPyAnLWZpcHMnIDogJycpLCAkcGFyc2VkVmVyc2lvbiwgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdPUEVOU1NMX1ZFUlNJT05fVEVYVCcpLCBhcnJheSgpLCAkaXNGaXBzID8gYXJyYXkoJG5hbWUpIDogYXJyYXkoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3BjcmUnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCBQcmVnOjpyZXBsYWNlKCd7XihcUyspLip9JywgJyQxJywgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdQQ1JFX1ZFUlNJT04nKSkpOwoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gUENSRSBVbmljb2RlIFZlcnNpb24gPT4gMTIuMS4wCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9eUENSRSBVbmljb2RlIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRwY3JlVW5pY29kZU1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictdW5pY29kZScsICRwY3JlVW5pY29kZU1hdGNoZXNbJ3ZlcnNpb24nXSwgJ1BDUkUgVW5pY29kZSB2ZXJzaW9uIHN1cHBvcnQnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsbmQnOgogICAgICAgICAgICAgICAgY2FzZSAncGRvX215c3FsJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9eKD86Q2xpZW50IEFQSSB2ZXJzaW9ufFZlcnNpb24pID0+IG15c3FsbmQgKD88dmVyc2lvbj4uKz8pIC9taScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1teXNxbG5kJywgJG1hdGNoZXNbJ3ZlcnNpb24nXSwgJ215c3FsbmQgbGlicmFyeSB2ZXJzaW9uIGZvciAnLiRuYW1lKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnbW9uZ29kYic6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXmxpYm1vbmdvYyBidW5kbGVkIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRsaWJtb25nb2NNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYm1vbmdvYycsICRsaWJtb25nb2NNYXRjaGVzWyd2ZXJzaW9uJ10sICdsaWJtb25nb2MgdmVyc2lvbiBvZiBtb25nb2RiJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL15saWJic29uIGJ1bmRsZWQgdmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJGxpYmJzb25NYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYmJzb24nLCAkbGliYnNvbk1hdGNoZXNbJ3ZlcnNpb24nXSwgJ2xpYmJzb24gdmVyc2lvbiBvZiBtb25nb2RiJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgIGNhc2UgJ3Bkb19wZ3NxbCc6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXlBvc3RncmVTUUxcKGxpYnBxXCkgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4qKSQvaW0nLCAkaW5mbywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGlicHEnLCAkbWF0Y2hlc1sndmVyc2lvbiddLCAnbGlicHEgZm9yICcuJG5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdsaWJzb2RpdW0nOgogICAgICAgICAgICAgICAgY2FzZSAnc29kaXVtJzoKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnJ1bnRpbWUtPmhhc0NvbnN0YW50KCdTT0RJVU1fTElCUkFSWV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2xpYnNvZGl1bScsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnU09ESVVNX0xJQlJBUllfVkVSU0lPTicpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnc3FsaXRlMyc6CiAgICAgICAgICAgICAgICBjYXNlICdwZG9fc3FsaXRlJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9eU1FMaXRlIExpYnJhcnkgPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLXNxbGl0ZScsICRtYXRjaGVzWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdzc2gyJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9ebGlic3NoMiB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJzc2gyJywgJG1hdGNoZXNbJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3hzbCc6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2xpYnhzbHQnLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ0xJQlhTTFRfRE9UVEVEX1ZFUlNJT04nKSwgbnVsbCwgYXJyYXkoJ3hzbCcpKTsKCiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygneHNsJyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9ebGlieHNsdCBjb21waWxlZCBhZ2FpbnN0IGxpYnhtbCBWZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2xpYnhzbHQtbGlieG1sJywgJG1hdGNoZXNbJ3ZlcnNpb24nXSwgJ2xpYnhtbCB2ZXJzaW9uIGxpYnhzbHQgaXMgY29tcGlsZWQgYWdhaW5zdCcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICd5YW1sJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCd5YW1sJyk7CgogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXkxpYllBTUwgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGlieWFtbCcsICRtYXRjaGVzWyd2ZXJzaW9uJ10sICdsaWJ5YW1sIHZlcnNpb24gb2YgeWFtbCcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICd6aXAnOgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ0xJQlpJUF9WRVJTSU9OJywgJ1ppcEFyY2hpdmUnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYnppcCcsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnTElCWklQX1ZFUlNJT04nLCAnWmlwQXJjaGl2ZScpLCBudWxsLCBhcnJheSgnemlwJykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICd6bGliJzoKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnJ1bnRpbWUtPmhhc0NvbnN0YW50KCdaTElCX1ZFUlNJT04nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZSwgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdaTElCX1ZFUlNJT04nKSk7CgogICAgICAgICAgICAgICAgICAgIC8vIExpbmtlZCBWZXJzaW9uID0+IDEuMi44CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKFByZWc6OmlzTWF0Y2goJy9eTGlua2VkIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUsICRtYXRjaGVzWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkaGh2bVZlcnNpb24gPSAkdGhpcy0+aGh2bURldGVjdG9yLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgaWYgKCRoaHZtVmVyc2lvbikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSAkaGh2bVZlcnNpb247CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9IFByZWc6OnJlcGxhY2UoJyNeKFtefistXSspLiokIycsICckMScsICRoaHZtVmVyc2lvbik7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaGh2bSA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJ2hodm0nLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICAkaGh2bS0+c2V0RGVzY3JpcHRpb24oJ1RoZSBISFZNIFJ1bnRpbWUgKDY0Yml0KScpOwogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkaGh2bSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoISRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdFeHBlY3RlZCBDb21wbGV0ZVBhY2thZ2UgYnV0IGdvdCAnLmdldF9jbGFzcygkcGFja2FnZSkpOwogICAgICAgIH0KCiAgICAgICAgLy8gU2tpcCBpZiBvdmVycmlkZGVuCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5vdmVycmlkZXNbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+b3ZlcnJpZGVzWyRwYWNrYWdlLT5nZXROYW1lKCldWyd2ZXJzaW9uJ10gPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRGlzYWJsZWRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG92ZXJyaWRlciA9ICR0aGlzLT5maW5kUGFja2FnZSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAnKicpOwogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFZlcnNpb24oKSA9PT0gJG92ZXJyaWRlci0+Z2V0VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICAkYWN0dWFsVGV4dCA9ICdzYW1lIGFzIGFjdHVhbCc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYWN0dWFsVGV4dCA9ICdhY3R1YWw6ICcuJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJG92ZXJyaWRlciBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJG92ZXJyaWRlci0+c2V0RGVzY3JpcHRpb24oJG92ZXJyaWRlci0+Z2V0RGVzY3JpcHRpb24oKS4nLCAnLiRhY3R1YWxUZXh0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU2tpcCBpZiBQSFAgaXMgb3ZlcnJpZGRlbiBhbmQgd2UgYXJlIGFkZGluZyBhIHBocC0qIHBhY2thZ2UKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm92ZXJyaWRlc1sncGhwJ10pICYmIDAgPT09IHN0cnBvcygkcGFja2FnZS0+Z2V0TmFtZSgpLCAncGhwLScpKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+b3ZlcnJpZGVzWyRwYWNrYWdlLT5nZXROYW1lKCldKSAmJiAkdGhpcy0+b3ZlcnJpZGVzWyRwYWNrYWdlLT5nZXROYW1lKCldWyd2ZXJzaW9uJ10gPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRGlzYWJsZWRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG92ZXJyaWRlciA9ICR0aGlzLT5hZGRPdmVycmlkZGVuUGFja2FnZSgkdGhpcy0+b3ZlcnJpZGVzWydwaHAnXSwgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSk7CiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0VmVyc2lvbigpID09PSAkb3ZlcnJpZGVyLT5nZXRWZXJzaW9uKCkpIHsKICAgICAgICAgICAgICAgICRhY3R1YWxUZXh0ID0gJ3NhbWUgYXMgYWN0dWFsJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRhY3R1YWxUZXh0ID0gJ2FjdHVhbDogJy4kcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRvdmVycmlkZXItPnNldERlc2NyaXB0aW9uKCRvdmVycmlkZXItPmdldERlc2NyaXB0aW9uKCkuJywgJy4kYWN0dWFsVGV4dCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6OmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5e3ZlcnNpb246IHN0cmluZywgbmFtZTogc3RyaW5nfSAkb3ZlcnJpZGUKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gQ29tcGxldGVQYWNrYWdlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkT3ZlcnJpZGRlblBhY2thZ2UoYXJyYXkgJG92ZXJyaWRlLCAkbmFtZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRvdmVycmlkZVsndmVyc2lvbiddKTsKICAgICAgICAkcGFja2FnZSA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJG5hbWUgPzogJG92ZXJyaWRlWyduYW1lJ10sICR2ZXJzaW9uLCAkb3ZlcnJpZGVbJ3ZlcnNpb24nXSk7CiAgICAgICAgJHBhY2thZ2UtPnNldERlc2NyaXB0aW9uKCdQYWNrYWdlIG92ZXJyaWRkZW4gdmlhIGNvbmZpZy5wbGF0Zm9ybScpOwogICAgICAgICRwYWNrYWdlLT5zZXRFeHRyYShhcnJheSgnY29uZmlnLnBsYXRmb3JtJyA9PiB0cnVlKSk7CiAgICAgICAgcGFyZW50OjphZGRQYWNrYWdlKCRwYWNrYWdlKTsKCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXROYW1lKCkgPT09ICdwaHAnKSB7CiAgICAgICAgICAgIHNlbGY6OiRsYXN0U2VlblBsYXRmb3JtUGhwID0gaW1wbG9kZSgnLicsIGFycmF5X3NsaWNlKGV4cGxvZGUoJy4nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSwgMCwgMykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkRGlzYWJsZWRQYWNrYWdlKENvbXBsZXRlUGFja2FnZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkcGFja2FnZS0+c2V0RGVzY3JpcHRpb24oJHBhY2thZ2UtPmdldERlc2NyaXB0aW9uKCkuJy4gPHdhcm5pbmc+UGFja2FnZSBkaXNhYmxlZCB2aWEgY29uZmlnLnBsYXRmb3JtPC93YXJuaW5nPicpOwogICAgICAgICRwYWNrYWdlLT5zZXRFeHRyYShhcnJheSgnY29uZmlnLnBsYXRmb3JtJyA9PiB0cnVlKSk7CgogICAgICAgICR0aGlzLT5kaXNhYmxlZFBhY2thZ2VzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIHZlcnNpb24gYW5kIGFkZHMgYSBuZXcgcGFja2FnZSB0byB0aGUgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbmFtZQogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRwcmV0dHlWZXJzaW9uCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkRXh0ZW5zaW9uKCRuYW1lLCAkcHJldHR5VmVyc2lvbikKICAgIHsKICAgICAgICAkZXh0cmFEZXNjcmlwdGlvbiA9IG51bGw7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkZXh0cmFEZXNjcmlwdGlvbiA9ICcgKGFjdHVhbCB2ZXJzaW9uOiAnLiRwcmV0dHlWZXJzaW9uLicpJzsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teKFxkK1wuXGQrXC5cZCsoPzpcLlxkKyk/KX0nLCAkcHJldHR5VmVyc2lvbiwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSAkbWF0Y2hbMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICcwJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHByZXR0eVZlcnNpb24pOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VOYW1lID0gJHRoaXMtPmJ1aWxkUGFja2FnZU5hbWUoJG5hbWUpOwogICAgICAgICRleHQgPSBuZXcgQ29tcGxldGVQYWNrYWdlKCRwYWNrYWdlTmFtZSwgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAkZXh0LT5zZXREZXNjcmlwdGlvbignVGhlICcuJG5hbWUuJyBQSFAgZXh0ZW5zaW9uJy4kZXh0cmFEZXNjcmlwdGlvbik7CgogICAgICAgIGlmICgkbmFtZSA9PT0gJ3V1aWQnKSB7CiAgICAgICAgICAgICRleHQtPnNldFJlcGxhY2VzKGFycmF5KAogICAgICAgICAgICAgICAgJ2xpYi11dWlkJyA9PiBuZXcgTGluaygnZXh0LXV1aWQnLCAnbGliLXV1aWQnLCBuZXcgQ29uc3RyYWludCgnPScsICR2ZXJzaW9uKSwgTGluazo6VFlQRV9SRVBMQUNFLCAkZXh0LT5nZXRQcmV0dHlWZXJzaW9uKCkpLAogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYnVpbGRQYWNrYWdlTmFtZSgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJ2V4dC0nIC4gc3RyX3JlcGxhY2UoJyAnLCAnLScsIHN0cnRvbG93ZXIoJG5hbWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRwcmV0dHlWZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGRlc2NyaXB0aW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgJHJlcGxhY2VzCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgJHByb3ZpZGVzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkTGlicmFyeSgkbmFtZSwgJHByZXR0eVZlcnNpb24sICRkZXNjcmlwdGlvbiA9IG51bGwsIGFycmF5ICRyZXBsYWNlcyA9IGFycmF5KCksIGFycmF5ICRwcm92aWRlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgkZGVzY3JpcHRpb24gPT09IG51bGwpIHsKICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJ1RoZSAnLiRuYW1lLicgbGlicmFyeSc7CiAgICAgICAgfQoKICAgICAgICAkbGliID0gbmV3IENvbXBsZXRlUGFja2FnZSgnbGliLScuJG5hbWUsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJGxpYi0+c2V0RGVzY3JpcHRpb24oJGRlc2NyaXB0aW9uKTsKCiAgICAgICAgJHJlcGxhY2VMaW5rcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcGxhY2VzIGFzICRyZXBsYWNlKSB7CiAgICAgICAgICAgICRyZXBsYWNlID0gc3RydG9sb3dlcigkcmVwbGFjZSk7CiAgICAgICAgICAgICRyZXBsYWNlTGlua3NbJHJlcGxhY2VdID0gbmV3IExpbmsoJ2xpYi0nLiRuYW1lLCAnbGliLScuJHJlcGxhY2UsIG5ldyBDb25zdHJhaW50KCc9JywgJHZlcnNpb24pLCBMaW5rOjpUWVBFX1JFUExBQ0UsICRsaWItPmdldFByZXR0eVZlcnNpb24oKSk7CiAgICAgICAgfQogICAgICAgICRwcm92aWRlTGlua3MgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwcm92aWRlcyBhcyAkcHJvdmlkZSkgewogICAgICAgICAgICAkcHJvdmlkZSA9IHN0cnRvbG93ZXIoJHByb3ZpZGUpOwogICAgICAgICAgICAkcHJvdmlkZUxpbmtzWyRwcm92aWRlXSA9IG5ldyBMaW5rKCdsaWItJy4kbmFtZSwgJ2xpYi0nLiRwcm92aWRlLCBuZXcgQ29uc3RyYWludCgnPScsICR2ZXJzaW9uKSwgTGluazo6VFlQRV9QUk9WSURFLCAkbGliLT5nZXRQcmV0dHlWZXJzaW9uKCkpOwogICAgICAgIH0KICAgICAgICAkbGliLT5zZXRSZXBsYWNlcygkcmVwbGFjZUxpbmtzKTsKICAgICAgICAkbGliLT5zZXRQcm92aWRlcygkcHJvdmlkZUxpbmtzKTsKCiAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJGxpYik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiBhIHBhY2thZ2UgbmFtZSBpcyBhIHBsYXRmb3JtIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKQogICAgewogICAgICAgIHN0YXRpYyAkY2FjaGUgPSBhcnJheSgpOwoKICAgICAgICBpZiAoaXNzZXQoJGNhY2hlWyRuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuICRjYWNoZVskbmFtZV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNhY2hlWyRuYW1lXSA9IFByZWc6OmlzTWF0Y2goUGxhdGZvcm1SZXBvc2l0b3J5OjpQTEFURk9STV9QQUNLQUdFX1JFR0VYLCAkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IHNlZW4gY29uZmlnLnBsYXRmb3JtLnBocCB2ZXJzaW9uIGlmIGRlZmluZWQKICAgICAqCiAgICAgKiBUaGlzIGlzIGEgYmVzdCBlZmZvcnQgYXR0ZW1wdCBmb3IgaW50ZXJuYWwgcHVycG9zZXMsIHJldHJpZXZlIHRoZSByZWFsCiAgICAgKiBwYWNrYWdlcyBmcm9tIGEgUGxhdGZvcm1SZXBvc2l0b3J5IGluc3RhbmNlIGlmIHlvdSBuZWVkIGEgdmVyc2lvbiBndWFyYW50ZWVkIHRvCiAgICAgKiBiZSBjb3JyZWN0LgogICAgICoKICAgICAqIEBpbnRlcm5hbAogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBsYXRmb3JtUGhwVmVyc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRsYXN0U2VlblBsYXRmb3JtUGhwOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZWFyY2goJHF1ZXJ5LCAkbW9kZSA9IDAsICR0eXBlID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBzdXBwcmVzcyB2ZW5kb3Igc2VhcmNoIGFzIHRoZXJlIGFyZSBubyB2ZW5kb3JzIHRvIG1hdGNoIGluIHBsYXRmb3JtIHBhY2thZ2VzCiAgICAgICAgaWYgKCRtb2RlID09PSBzZWxmOjpTRUFSQ0hfVkVORE9SKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDo6c2VhcmNoKCRxdWVyeSwgJG1vZGUsICR0eXBlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cU3RhYmlsaXR5RmlsdGVyOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxQbHVnaW5cUG9zdEZpbGVEb3dubG9hZEV2ZW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBpbGluZ01hdGNoZXI7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxMb29wOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFBsdWdpblxQcmVGaWxlRG93bmxvYWRFdmVudDsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwp1c2UgQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllclxNZXRhZGF0YU1pbmlmaWVyOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ29tcG9zZXJSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5IGltcGxlbWVudHMgQ29uZmlndXJhYmxlUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEB2YXIgbWl4ZWRbXQogICAgICogQHBocHN0YW4tdmFyIGFycmF5e3VybDogc3RyaW5nLCBvcHRpb25zPzogbWl4ZWRbXSwgdHlwZT86ICdjb21wb3NlcicsIGFsbG93X3NzbF9kb3duZ3JhZGU/OiBib29sfQogICAgICovCiAgICBwcml2YXRlICRyZXBvQ29uZmlnOwogICAgLyoqIEB2YXIgbWl4ZWRbXSAqLwogICAgcHJpdmF0ZSAkb3B0aW9uczsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkdXJsOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRiYXNlVXJsOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqIEB2YXIgSHR0cERvd25sb2FkZXIgKi8KICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgTG9vcCAqLwogICAgcHJpdmF0ZSAkbG9vcDsKICAgIC8qKiBAdmFyIENhY2hlICovCiAgICBwcm90ZWN0ZWQgJGNhY2hlOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRub3RpZnlVcmwgPSBudWxsOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRzZWFyY2hVcmwgPSBudWxsOwogICAgLyoqIEB2YXIgP3N0cmluZyBhIFVSTCBjb250YWluaW5nICVwYWNrYWdlJSB3aGljaCBjYW4gYmUgcXVlcmllZCB0byBnZXQgcHJvdmlkZXJzIG9mIGEgZ2l2ZW4gbmFtZSAqLwogICAgcHJvdGVjdGVkICRwcm92aWRlcnNBcGlVcmwgPSBudWxsOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRoYXNQcm92aWRlcnMgPSBmYWxzZTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcHJvdmlkZXJzVXJsID0gbnVsbDsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkbGlzdFVybCA9IG51bGw7CiAgICAvKiogQHZhciBib29sIEluZGljYXRlcyB3aGV0aGVyIGEgY29tcHJlaGVuc2l2ZSBsaXN0IG9mIHBhY2thZ2VzIHRoaXMgcmVwb3NpdG9yeSBtaWdodCBwcm92aWRlIGlzIGV4cHJlc3NlZCBpbiB0aGUgcmVwb3NpdG9yeSByb290LiAqKi8KICAgIHByb3RlY3RlZCAkaGFzQXZhaWxhYmxlUGFja2FnZUxpc3QgPSBmYWxzZTsKICAgIC8qKiBAdmFyID9hcnJheTxzdHJpbmc+ICovCiAgICBwcm90ZWN0ZWQgJGF2YWlsYWJsZVBhY2thZ2VzID0gbnVsbDsKICAgIC8qKiBAdmFyID9hcnJheTxzdHJpbmc+ICovCiAgICBwcm90ZWN0ZWQgJGF2YWlsYWJsZVBhY2thZ2VQYXR0ZXJucyA9IG51bGw7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJGxhenlQcm92aWRlcnNVcmwgPSBudWxsOwogICAgLyoqIEB2YXIgP2FycmF5PHN0cmluZywgYXJyYXl7c2hhMjU2OiBzdHJpbmd9PiAqLwogICAgcHJvdGVjdGVkICRwcm92aWRlckxpc3Rpbmc7CiAgICAvKiogQHZhciBBcnJheUxvYWRlciAqLwogICAgcHJvdGVjdGVkICRsb2FkZXI7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRhbGxvd1NzbERvd25ncmFkZSA9IGZhbHNlOwogICAgLyoqIEB2YXIgP0V2ZW50RGlzcGF0Y2hlciAqLwogICAgcHJpdmF0ZSAkZXZlbnREaXNwYXRjaGVyOwogICAgLyoqIEB2YXIgP2FycmF5PHN0cmluZywgYXJyYXk8aW50LCBhcnJheXt1cmw6IHN0cmluZywgcHJlZmVycmVkOiBib29sfT4+ICovCiAgICBwcml2YXRlICRzb3VyY2VNaXJyb3JzOwogICAgLyoqIEB2YXIgP2FycmF5PGludCwgYXJyYXl7dXJsOiBzdHJpbmcsIHByZWZlcnJlZDogYm9vbH0+ICovCiAgICBwcml2YXRlICRkaXN0TWlycm9yczsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGRlZ3JhZGVkTW9kZSA9IGZhbHNlOwogICAgLyoqIEB2YXIgbWl4ZWRbXXx0cnVlICovCiAgICBwcml2YXRlICRyb290RGF0YTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGhhc1BhcnRpYWxQYWNrYWdlcyA9IGZhbHNlOwogICAgLyoqIEB2YXIgP2FycmF5PHN0cmluZywgbWl4ZWRbXT4gKi8KICAgIHByaXZhdGUgJHBhcnRpYWxQYWNrYWdlc0J5TmFtZSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByaXZhdGUKICAgICAqIEB2YXIgYXJyYXkgbGlzdCBvZiBwYWNrYWdlIG5hbWVzIHdoaWNoIGFyZSBmcmVzaCBhbmQgY2FuIGJlIGxvYWRlZCBmcm9tIHRoZSBjYWNoZSBkaXJlY3RseSBpbiBjYXNlIGxvYWRQYWNrYWdlIGlzIGNhbGxlZCBzZXZlcmFsIHRpbWVzCiAgICAgKiAgICAgICAgICAgIHVzZWZ1bCBmb3IgdjIgbWV0YWRhdGEgcmVwb3NpdG9yaWVzIHdpdGggbGF6eSBwcm92aWRlcnMKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIHRydWU+CiAgICAgKi8KICAgIHB1YmxpYyAkZnJlc2hNZXRhZGF0YVVybHMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogVE9ETyB2MyBzaG91bGQgbWFrZSB0aGlzIHByaXZhdGUgb25jZSB3ZSBjYW4gZHJvcCBQSFAgNS4zIHN1cHBvcnQKICAgICAqIEBwcml2YXRlCiAgICAgKiBAdmFyIGFycmF5IGxpc3Qgb2YgcGFja2FnZSBuYW1lcyB3aGljaCByZXR1cm5lZCBhIDQwNCBhbmQgc2hvdWxkIG5vdCBiZSByZS1mZXRjaGVkIGluIGNhc2UgbG9hZFBhY2thZ2UgaXMgY2FsbGVkIHNldmVyYWwgdGltZXMKICAgICAqICAgICAgICAgICAgdXNlZnVsIGZvciB2MiBtZXRhZGF0YSByZXBvc2l0b3JpZXMgd2l0aCBsYXp5IHByb3ZpZGVycwogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHN0cmluZywgdHJ1ZT4KICAgICAqLwogICAgcHVibGljICRwYWNrYWdlc05vdEZvdW5kQ2FjaGUgPSBhcnJheSgpOwogICAgLyoqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByaXZhdGUKICAgICAqIEB2YXIgVmVyc2lvblBhcnNlcgogICAgICovCiAgICBwdWJsaWMgJHZlcnNpb25QYXJzZXI7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHJlcG9Db25maWcKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5e3VybDogc3RyaW5nLCBvcHRpb25zPzogbWl4ZWRbXSwgdHlwZT86ICdjb21wb3NlcicsIGFsbG93X3NzbF9kb3duZ3JhZGU/OiBib29sfSAkcmVwb0NvbmZpZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJlcG9Db25maWcsIElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciwgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoKTsKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJ3teW1x3Ll0rXD8/Oi8vfScsICRyZXBvQ29uZmlnWyd1cmwnXSkpIHsKICAgICAgICAgICAgLy8gYXNzdW1lIGh0dHAgYXMgdGhlIGRlZmF1bHQgcHJvdG9jb2wKICAgICAgICAgICAgJHJlcG9Db25maWdbJ3VybCddID0gJ2h0dHA6Ly8nLiRyZXBvQ29uZmlnWyd1cmwnXTsKICAgICAgICB9CiAgICAgICAgJHJlcG9Db25maWdbJ3VybCddID0gcnRyaW0oJHJlcG9Db25maWdbJ3VybCddLCAnLycpOwoKICAgICAgICBpZiAoc3RycG9zKCRyZXBvQ29uZmlnWyd1cmwnXSwgJ2h0dHBzPycpID09PSAwKSB7CiAgICAgICAgICAgICRyZXBvQ29uZmlnWyd1cmwnXSA9IChleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykgPyAnaHR0cHMnIDogJ2h0dHAnKSAuIHN1YnN0cigkcmVwb0NvbmZpZ1sndXJsJ10sIDYpOwogICAgICAgIH0KCiAgICAgICAgJHVybEJpdHMgPSBwYXJzZV91cmwoJHJlcG9Db25maWdbJ3VybCddKTsKICAgICAgICBpZiAoJHVybEJpdHMgPT09IGZhbHNlIHx8IGVtcHR5KCR1cmxCaXRzWydzY2hlbWUnXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0ludmFsaWQgdXJsIGdpdmVuIGZvciBDb21wb3NlciByZXBvc2l0b3J5OiAnLiRyZXBvQ29uZmlnWyd1cmwnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRyZXBvQ29uZmlnWydvcHRpb25zJ10pKSB7CiAgICAgICAgICAgICRyZXBvQ29uZmlnWydvcHRpb25zJ10gPSBhcnJheSgpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHJlcG9Db25maWdbJ2FsbG93X3NzbF9kb3duZ3JhZGUnXSkgJiYgdHJ1ZSA9PT0gJHJlcG9Db25maWdbJ2FsbG93X3NzbF9kb3duZ3JhZGUnXSkgewogICAgICAgICAgICAkdGhpcy0+YWxsb3dTc2xEb3duZ3JhZGUgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSAkcmVwb0NvbmZpZ1snb3B0aW9ucyddOwogICAgICAgICR0aGlzLT51cmwgPSAkcmVwb0NvbmZpZ1sndXJsJ107CgogICAgICAgIC8vIGZvcmNlIHVybCBmb3IgcGFja2FnaXN0Lm9yZyB0byByZXBvLnBhY2thZ2lzdC5vcmcKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne14oP1A8cHJvdG8+aHR0cHM/KTovL3BhY2thZ2lzdFwub3JnLz8kfWknLCAkdGhpcy0+dXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT51cmwgPSAkbWF0Y2hbJ3Byb3RvJ10uJzovL3JlcG8ucGFja2FnaXN0Lm9yZyc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YmFzZVVybCA9IHJ0cmltKFByZWc6OnJlcGxhY2UoJ3soPzovW14vXFxcXF0rXC5qc29uKT8oPzpbPyNdLiopPyR9JywgJycsICR0aGlzLT51cmwpLCAnLycpOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y2FjaGUgPSBuZXcgQ2FjaGUoJGlvLCAkY29uZmlnLT5nZXQoJ2NhY2hlLXJlcG8tZGlyJykuJy8nLlByZWc6OnJlcGxhY2UoJ3tbXmEtejAtOS5dfWknLCAnLScsIFVybDo6c2FuaXRpemUoJHRoaXMtPnVybCkpLCAnYS16MC05LiR+Jyk7CiAgICAgICAgJHRoaXMtPmNhY2hlLT5zZXRSZWFkT25seSgkY29uZmlnLT5nZXQoJ2NhY2hlLXJlYWQtb25seScpKTsKICAgICAgICAkdGhpcy0+dmVyc2lvblBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgJHRoaXMtPmxvYWRlciA9IG5ldyBBcnJheUxvYWRlcigkdGhpcy0+dmVyc2lvblBhcnNlcik7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyOwogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgICAgICR0aGlzLT5yZXBvQ29uZmlnID0gJHJlcG9Db25maWc7CiAgICAgICAgJHRoaXMtPmxvb3AgPSBuZXcgTG9vcCgkdGhpcy0+aHR0cERvd25sb2FkZXIpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdjb21wb3NlciByZXBvICgnLlVybDo6c2FuaXRpemUoJHRoaXMtPnVybCkuJyknOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvQ29uZmlnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9Db25maWc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KQogICAgewogICAgICAgIC8vIHRoaXMgY2FsbCBpbml0aWFsaXplcyBsb2FkUm9vdFNlcnZlckZpbGUgd2hpY2ggaXMgbmVlZGVkIGZvciB0aGUgcmVzdCBiZWxvdyB0byB3b3JrCiAgICAgICAgJGhhc1Byb3ZpZGVycyA9ICR0aGlzLT5oYXNQcm92aWRlcnMoKTsKCiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKICAgICAgICBpZiAoISRjb25zdHJhaW50IGluc3RhbmNlb2YgQ29uc3RyYWludEludGVyZmFjZSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpICYmIGlzc2V0KCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWVbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWx0ZXJQYWNrYWdlcygkdGhpcy0+d2hhdFByb3ZpZGVzKCRuYW1lKSwgJGNvbnN0cmFpbnQsIHRydWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0ICYmICEkdGhpcy0+bGF6eVByb3ZpZGVyc1JlcG9Db250YWlucygkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+bG9hZEFzeW5jUGFja2FnZXMoYXJyYXkoJG5hbWUgPT4gJGNvbnN0cmFpbnQpKTsKCiAgICAgICAgICAgIHJldHVybiByZXNldCgkcGFja2FnZXNbJ3BhY2thZ2VzJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRoYXNQcm92aWRlcnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFByb3ZpZGVyTmFtZXMoKSBhcyAkcHJvdmlkZXJOYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAoJG5hbWUgPT09ICRwcm92aWRlck5hbWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZpbHRlclBhY2thZ2VzKCR0aGlzLT53aGF0UHJvdmlkZXMoJHByb3ZpZGVyTmFtZSksICRjb25zdHJhaW50LCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcGFyZW50OjpmaW5kUGFja2FnZSgkbmFtZSwgJGNvbnN0cmFpbnQpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQgPSBudWxsKQogICAgewogICAgICAgIC8vIHRoaXMgY2FsbCBpbml0aWFsaXplcyBsb2FkUm9vdFNlcnZlckZpbGUgd2hpY2ggaXMgbmVlZGVkIGZvciB0aGUgcmVzdCBiZWxvdyB0byB3b3JrCiAgICAgICAgJGhhc1Byb3ZpZGVycyA9ICR0aGlzLT5oYXNQcm92aWRlcnMoKTsKCiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKICAgICAgICBpZiAobnVsbCAhPT0gJGNvbnN0cmFpbnQgJiYgISRjb25zdHJhaW50IGluc3RhbmNlb2YgQ29uc3RyYWludEludGVyZmFjZSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpICYmIGlzc2V0KCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWVbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWx0ZXJQYWNrYWdlcygkdGhpcy0+d2hhdFByb3ZpZGVzKCRuYW1lKSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0ICYmICEkdGhpcy0+bGF6eVByb3ZpZGVyc1JlcG9Db250YWlucygkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmxvYWRBc3luY1BhY2thZ2VzKGFycmF5KCRuYW1lID0+ICRjb25zdHJhaW50KSk7CgogICAgICAgICAgICByZXR1cm4gJHJlc3VsdFsncGFja2FnZXMnXTsKICAgICAgICB9CgogICAgICAgIGlmICgkaGFzUHJvdmlkZXJzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQcm92aWRlck5hbWVzKCkgYXMgJHByb3ZpZGVyTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKCRuYW1lID09PSAkcHJvdmlkZXJOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWx0ZXJQYWNrYWdlcygkdGhpcy0+d2hhdFByb3ZpZGVzKCRwcm92aWRlck5hbWUpLCAkY29uc3RyYWludCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDo6ZmluZFBhY2thZ2VzKCRuYW1lLCAkY29uc3RyYWludCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8QmFzZVBhY2thZ2U+ICRwYWNrYWdlcwogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2V8bnVsbCAkY29uc3RyYWludAogICAgICogQHBhcmFtIGJvb2wgJHJldHVybkZpcnN0TWF0Y2gKICAgICAqCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlfGFycmF5PEJhc2VQYWNrYWdlPnxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmlsdGVyUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzLCAkY29uc3RyYWludCA9IG51bGwsICRyZXR1cm5GaXJzdE1hdGNoID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmICgkcmV0dXJuRmlyc3RNYXRjaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlc2V0KCRwYWNrYWdlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICAgICAgfQoKICAgICAgICAkZmlsdGVyZWRQYWNrYWdlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkcGtnQ29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpOwoKICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50LT5tYXRjaGVzKCRwa2dDb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgaWYgKCRyZXR1cm5GaXJzdE1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRmaWx0ZXJlZFBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXR1cm5GaXJzdE1hdGNoKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaWx0ZXJlZFBhY2thZ2VzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlcygpCiAgICB7CiAgICAgICAgJGhhc1Byb3ZpZGVycyA9ICR0aGlzLT5oYXNQcm92aWRlcnMoKTsKCiAgICAgICAgaWYgKCR0aGlzLT5sYXp5UHJvdmlkZXJzVXJsKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdGhpcy0+YXZhaWxhYmxlUGFja2FnZXMpICYmICEkdGhpcy0+YXZhaWxhYmxlUGFja2FnZVBhdHRlcm5zKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZU1hcCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXZhaWxhYmxlUGFja2FnZXMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU1hcFskbmFtZV0gPSBuZXcgTWF0Y2hBbGxDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5sb2FkQXN5bmNQYWNrYWdlcygkcGFja2FnZU1hcCk7CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3ZhbHVlcygkcmVzdWx0WydwYWNrYWdlcyddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXMoKSkgewogICAgICAgICAgICAgICAgaWYgKCFpc19hcnJheSgkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ2hhc1BhcnRpYWxQYWNrYWdlcyBmYWlsZWQgdG8gaW5pdGlhbGl6ZSAkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWF0ZVBhY2thZ2VzKCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUsICdwYWNrYWdlcy5qc29uIGlubGluZSBwYWNrYWdlcycpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdDb21wb3NlciByZXBvc2l0b3JpZXMgdGhhdCBoYXZlIGxhenkgcHJvdmlkZXJzIGFuZCBubyBhdmFpbGFibGUtcGFja2FnZXMgbGlzdCBjYW4gbm90IGxvYWQgdGhlIGNvbXBsZXRlIGxpc3Qgb2YgcGFja2FnZXMsIHVzZSBnZXRQYWNrYWdlTmFtZXMgaW5zdGVhZC4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaGFzUHJvdmlkZXJzKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0NvbXBvc2VyIHJlcG9zaXRvcmllcyB0aGF0IGhhdmUgcHJvdmlkZXJzIGNhbiBub3QgbG9hZCB0aGUgY29tcGxldGUgbGlzdCBvZiBwYWNrYWdlcywgdXNlIGdldFBhY2thZ2VOYW1lcyBpbnN0ZWFkLicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0UGFja2FnZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcGFja2FnZUZpbHRlciBQYWNrYWdlIHBhdHRlcm4gZmlsdGVyIHdoaWNoIGNhbiBpbmNsdWRlICIqIiBhcyBhIHdpbGRjYXJkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZU5hbWVzKCRwYWNrYWdlRmlsdGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkaGFzUHJvdmlkZXJzID0gJHRoaXMtPmhhc1Byb3ZpZGVycygpOwoKICAgICAgICAkZmlsdGVyUmVzdWx0cyA9CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRyZXN1bHRzCiAgICAgICAgICAgICAqIEByZXR1cm4gbGlzdDxzdHJpbmc+CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmdW5jdGlvbiAoYXJyYXkgJHJlc3VsdHMpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzdWx0czsKICAgICAgICAgICAgfQogICAgICAgIDsKICAgICAgICBpZiAobnVsbCAhPT0gJHBhY2thZ2VGaWx0ZXIgJiYgJycgIT09ICRwYWNrYWdlRmlsdGVyKSB7CiAgICAgICAgICAgICRwYWNrYWdlRmlsdGVyUmVnZXggPSBCYXNlUGFja2FnZTo6cGFja2FnZU5hbWVUb1JlZ2V4cCgkcGFja2FnZUZpbHRlcik7CiAgICAgICAgICAgICRmaWx0ZXJSZXN1bHRzID0KICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogQHBhcmFtIGxpc3Q8c3RyaW5nPiAkcmVzdWx0cwogICAgICAgICAgICAgICAgICogQHJldHVybiBsaXN0PHN0cmluZz4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZnVuY3Rpb24gKGFycmF5ICRyZXN1bHRzKSB1c2UgKCRwYWNrYWdlRmlsdGVyUmVnZXgpIHsKICAgICAgICAgICAgICAgICAgICAvKiogQHZhciBsaXN0PHN0cmluZz4gJHJlc3VsdHMgKi8KICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJlZzo6Z3JlcCgkcGFja2FnZUZpbHRlclJlZ2V4LCAkcmVzdWx0cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VzKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRmaWx0ZXJSZXN1bHRzKGFycmF5X2tleXMoJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+bGlzdFVybCkgewogICAgICAgICAgICAgICAgLy8gbm8gbmVlZCB0byBjYWxsICRmaWx0ZXJSZXN1bHRzIGhlcmUgYXMgdGhlICRwYWNrYWdlRmlsdGVyIGlzIGFwcGxpZWQgaW4gdGhlIGZ1bmN0aW9uIGl0c2VsZgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkUGFja2FnZUxpc3QoJHBhY2thZ2VGaWx0ZXIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpICYmICR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsdGVyUmVzdWx0cyhhcnJheV9rZXlzKCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhc1Byb3ZpZGVycykgewogICAgICAgICAgICByZXR1cm4gJGZpbHRlclJlc3VsdHMoJHRoaXMtPmdldFByb3ZpZGVyTmFtZXMoKSk7CiAgICAgICAgfQoKICAgICAgICAkbmFtZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRuYW1lc1tdID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZmlsdGVyUmVzdWx0cygkbmFtZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBsaXN0PHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRWZW5kb3JOYW1lcygpCiAgICB7CiAgICAgICAgJGNhY2hlS2V5ID0gJ3ZlbmRvci1saXN0LnR4dCc7CiAgICAgICAgJGNhY2hlQWdlID0gJHRoaXMtPmNhY2hlLT5nZXRBZ2UoJGNhY2hlS2V5KTsKICAgICAgICBpZiAoZmFsc2UgIT09ICRjYWNoZUFnZSAmJiAkY2FjaGVBZ2UgPCA2MDAgJiYgKCRjYWNoZWREYXRhID0gJHRoaXMtPmNhY2hlLT5yZWFkKCRjYWNoZUtleSkpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkY2FjaGVkRGF0YSA9IGV4cGxvZGUoIlxuIiwgJGNhY2hlZERhdGEpOwoKICAgICAgICAgICAgcmV0dXJuICRjYWNoZWREYXRhOwogICAgICAgIH0KCiAgICAgICAgJG5hbWVzID0gJHRoaXMtPmdldFBhY2thZ2VOYW1lcygpOwoKICAgICAgICAkdW5pcXVlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJG5hbWVzIGFzICRuYW1lKSB7CiAgICAgICAgICAgIC8vIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUKICAgICAgICAgICAgJHVuaXF1ZXNbc3Vic3RyKCRuYW1lLCAwLCBzdHJwb3MoJG5hbWUsICcvJykpXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkdmVuZG9ycyA9IGFycmF5X2tleXMoJHVuaXF1ZXMpOwoKICAgICAgICBpZiAoISR0aGlzLT5jYWNoZS0+aXNSZWFkT25seSgpKSB7CiAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+d3JpdGUoJGNhY2hlS2V5LCBpbXBsb2RlKCJcbiIsICR2ZW5kb3JzKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZlbmRvcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHBhY2thZ2VGaWx0ZXIKICAgICAqIEByZXR1cm4gbGlzdDxzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbG9hZFBhY2thZ2VMaXN0KCRwYWNrYWdlRmlsdGVyID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmxpc3RVcmwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignTWFrZSBzdXJlIHRvIGNhbGwgbG9hZFJvb3RTZXJ2ZXJGaWxlIGJlZm9yZSBsb2FkUGFja2FnZUxpc3QnKTsKICAgICAgICB9CgogICAgICAgICR1cmwgPSAkdGhpcy0+bGlzdFVybDsKICAgICAgICBpZiAoaXNfc3RyaW5nKCRwYWNrYWdlRmlsdGVyKSAmJiAkcGFja2FnZUZpbHRlciAhPT0gJycpIHsKICAgICAgICAgICAgJHVybCAuPSAnP2ZpbHRlcj0nLnVybGVuY29kZSgkcGFja2FnZUZpbHRlcik7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkdXJsLCAkdGhpcy0+b3B0aW9ucyktPmRlY29kZUpzb24oKTsKCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0WydwYWNrYWdlTmFtZXMnXTsKICAgICAgICB9CgogICAgICAgICRjYWNoZUtleSA9ICdwYWNrYWdlLWxpc3QudHh0JzsKICAgICAgICAkY2FjaGVBZ2UgPSAkdGhpcy0+Y2FjaGUtPmdldEFnZSgkY2FjaGVLZXkpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJGNhY2hlQWdlICYmICRjYWNoZUFnZSA8IDYwMCAmJiAoJGNhY2hlZERhdGEgPSAkdGhpcy0+Y2FjaGUtPnJlYWQoJGNhY2hlS2V5KSkgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRjYWNoZWREYXRhID0gZXhwbG9kZSgiXG4iLCAkY2FjaGVkRGF0YSk7CgogICAgICAgICAgICByZXR1cm4gJGNhY2hlZERhdGE7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJHVybCwgJHRoaXMtPm9wdGlvbnMpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgaWYgKCEkdGhpcy0+Y2FjaGUtPmlzUmVhZE9ubHkoKSkgewogICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPndyaXRlKCRjYWNoZUtleSwgaW1wbG9kZSgiXG4iLCAkcmVzdWx0WydwYWNrYWdlTmFtZXMnXSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHRbJ3BhY2thZ2VOYW1lcyddOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VOYW1lTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAvLyB0aGlzIGNhbGwgaW5pdGlhbGl6ZXMgbG9hZFJvb3RTZXJ2ZXJGaWxlIHdoaWNoIGlzIG5lZWRlZCBmb3IgdGhlIHJlc3QgYmVsb3cgdG8gd29yawogICAgICAgICRoYXNQcm92aWRlcnMgPSAkdGhpcy0+aGFzUHJvdmlkZXJzKCk7CgogICAgICAgIGlmICghJGhhc1Byb3ZpZGVycyAmJiAhJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpICYmICEkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICByZXR1cm4gcGFyZW50Ojpsb2FkUGFja2FnZXMoJHBhY2thZ2VOYW1lTWFwLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsICRhbHJlYWR5TG9hZGVkKTsKICAgICAgICB9CgogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJG5hbWVzRm91bmQgPSBhcnJheSgpOwoKICAgICAgICBpZiAoJGhhc1Byb3ZpZGVycyB8fCAkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzKCkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VOYW1lTWFwIGFzICRuYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CgogICAgICAgICAgICAgICAgLy8gaWYgYSByZXBvIGhhcyBubyBwcm92aWRlcnMgYnV0IG9ubHkgcGFydGlhbCBwYWNrYWdlcyBhbmQgdGhlIHBhcnRpYWwgcGFja2FnZXMgYXJlIG1pc3NpbmcKICAgICAgICAgICAgICAgIC8vIHRoZW4gd2UgZG9uJ3Qgd2FudCB0byBjYWxsIHdoYXRQcm92aWRlcyBhcyBpdCB3b3VsZCB0cnkgdG8gbG9hZCBmcm9tIHRoZSBwcm92aWRlcnMgYW5kIGZhaWwKICAgICAgICAgICAgICAgIGlmICghJGhhc1Byb3ZpZGVycyAmJiAhaXNzZXQoJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZVskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGNhbmRpZGF0ZXMgPSAkdGhpcy0+d2hhdFByb3ZpZGVzKCRuYW1lLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsICRhbHJlYWR5TG9hZGVkKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjYW5kaWRhdGVzIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNhbmRpZGF0ZS0+Z2V0TmFtZSgpICE9PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCd3aGF0UHJvdmlkZXMgc2hvdWxkIG5ldmVyIHJldHVybiBhIHBhY2thZ2Ugd2l0aCBhIGRpZmZlcmVudCBuYW1lIHRoYW4gdGhlIHJlcXVlc3RlZCBvbmUnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5hbWVzRm91bmRbJG5hbWVdID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkY29uc3RyYWludCB8fCAkY29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkY2FuZGlkYXRlLT5nZXRWZXJzaW9uKCkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tzcGxfb2JqZWN0X2hhc2goJGNhbmRpZGF0ZSldID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGUgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgJiYgIWlzc2V0KCRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCkpXSA9ICRjYW5kaWRhdGUtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBhZGQgYWxpYXNlcyBvZiBtYXRjaGVkIHBhY2thZ2VzIGV2ZW4gaWYgdGhleSBkaWQgbm90IG1hdGNoIHRoZSBjb25zdHJhaW50CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkY2FuZGlkYXRlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGUgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlKV0gPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJHBhY2thZ2VzLCAkbWF0Y2hlcyk7CgogICAgICAgICAgICAgICAgdW5zZXQoJHBhY2thZ2VOYW1lTWFwWyRuYW1lXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCAmJiBjb3VudCgkcGFja2FnZU5hbWVNYXApKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aGFzQXZhaWxhYmxlUGFja2FnZUxpc3QpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTmFtZU1hcCBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmxhenlQcm92aWRlcnNSZXBvQ29udGFpbnMoc3RydG9sb3dlcigkbmFtZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlTmFtZU1hcFskbmFtZV0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5sb2FkQXN5bmNQYWNrYWdlcygkcGFja2FnZU5hbWVNYXAsICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsICRzdGFiaWxpdHlGbGFncywgJGFscmVhZHlMb2FkZWQpOwogICAgICAgICAgICAkcGFja2FnZXMgPSBhcnJheV9tZXJnZSgkcGFja2FnZXMsICRyZXN1bHRbJ3BhY2thZ2VzJ10pOwogICAgICAgICAgICAkbmFtZXNGb3VuZCA9IGFycmF5X21lcmdlKCRuYW1lc0ZvdW5kLCAkcmVzdWx0WyduYW1lc0ZvdW5kJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCduYW1lc0ZvdW5kJyA9PiBhcnJheV9rZXlzKCRuYW1lc0ZvdW5kKSwgJ3BhY2thZ2VzJyA9PiAkcGFja2FnZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlYXJjaCgkcXVlcnksICRtb2RlID0gMCwgJHR5cGUgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoNjAwKTsKCiAgICAgICAgaWYgKCR0aGlzLT5zZWFyY2hVcmwgJiYgJG1vZGUgPT09IHNlbGY6OlNFQVJDSF9GVUxMVEVYVCkgewogICAgICAgICAgICAkdXJsID0gc3RyX3JlcGxhY2UoYXJyYXkoJyVxdWVyeSUnLCAnJXR5cGUlJyksIGFycmF5KCRxdWVyeSwgJHR5cGUpLCAkdGhpcy0+c2VhcmNoVXJsKTsKCiAgICAgICAgICAgICRzZWFyY2ggPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkdXJsLCAkdGhpcy0+b3B0aW9ucyktPmRlY29kZUpzb24oKTsKCiAgICAgICAgICAgIGlmIChlbXB0eSgkc2VhcmNoWydyZXN1bHRzJ10pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlc3VsdHMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkc2VhcmNoWydyZXN1bHRzJ10gYXMgJHJlc3VsdCkgewogICAgICAgICAgICAgICAgLy8gZG8gbm90IHNob3cgdmlydHVhbCBwYWNrYWdlcyBpbiByZXN1bHRzIGFzIHRoZXkgYXJlIG5vdCBkaXJlY3RseSB1c2VmdWwgZnJvbSBhIGNvbXBvc2VyIHBlcnNwZWN0aXZlCiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRyZXN1bHRbJ3ZpcnR1YWwnXSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gJHJlc3VsdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHRzOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRtb2RlID09PSBzZWxmOjpTRUFSQ0hfVkVORE9SKSB7CiAgICAgICAgICAgICRyZXN1bHRzID0gYXJyYXkoKTsKICAgICAgICAgICAgJHJlZ2V4ID0gJ3soPzonLmltcGxvZGUoJ3wnLCBQcmVnOjpzcGxpdCgne1xzK30nLCAkcXVlcnkpKS4nKX1pJzsKCiAgICAgICAgICAgICR2ZW5kb3JOYW1lcyA9ICR0aGlzLT5nZXRWZW5kb3JOYW1lcygpOwogICAgICAgICAgICBmb3JlYWNoIChQcmVnOjpncmVwKCRyZWdleCwgJHZlbmRvck5hbWVzKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCduYW1lJyA9PiAkbmFtZSwgJ2Rlc2NyaXB0aW9uJyA9PiAnJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0czsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aGFzUHJvdmlkZXJzKCkgfHwgJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpIHsKICAgICAgICAgICAgLy8gb3B0aW1pemUgc2VhcmNoIGZvciAiXmZvby9iYXIiIHdoZXJlIGF0IGxlYXN0ICJeZm9vLyIgaXMgcHJlc2VudCBieSBsb2FkaW5nIHRoaXMgZGlyZWN0bHkgZnJvbSB0aGUgbGlzdFVybCBpZiBwcmVzZW50CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XlxeKD9QPHF1ZXJ5Pig/UDx2ZW5kb3I+W2EtejAtOV8uLV0rKS9bYS16MC05Xy4tXSopXCo/JH1pJywgJHF1ZXJ5LCAkbWF0Y2gpICYmICR0aGlzLT5saXN0VXJsICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkdXJsID0gJHRoaXMtPmxpc3RVcmwgLiAnP3ZlbmRvcj0nLnVybGVuY29kZSgkbWF0Y2hbJ3ZlbmRvciddKS4nJmZpbHRlcj0nLnVybGVuY29kZSgkbWF0Y2hbJ3F1ZXJ5J10uJyonKTsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkdXJsLCAkdGhpcy0+b3B0aW9ucyktPmRlY29kZUpzb24oKTsKCiAgICAgICAgICAgICAgICAkcmVzdWx0cyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVzdWx0WydwYWNrYWdlTmFtZXMnXSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgnbmFtZScgPT4gJG5hbWUsICdkZXNjcmlwdGlvbicgPT4gJycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzdWx0czsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlc3VsdHMgPSBhcnJheSgpOwogICAgICAgICAgICAkcmVnZXggPSAneyg/OicuaW1wbG9kZSgnfCcsIFByZWc6OnNwbGl0KCd7XHMrfScsICRxdWVyeSkpLicpfWknOwoKICAgICAgICAgICAgJHBhY2thZ2VOYW1lcyA9ICR0aGlzLT5nZXRQYWNrYWdlTmFtZXMoKTsKICAgICAgICAgICAgZm9yZWFjaCAoUHJlZzo6Z3JlcCgkcmVnZXgsICRwYWNrYWdlTmFtZXMpIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoJ25hbWUnID0+ICRuYW1lLCAnZGVzY3JpcHRpb24nID0+ICcnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHRzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDo6c2VhcmNoKCRxdWVyeSwgJG1vZGUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKTsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKCR0aGlzLT5wcm92aWRlcnNBcGlVcmwpIHsKICAgICAgICAgICAgJGFwaVJlc3VsdCA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KHN0cl9yZXBsYWNlKCclcGFja2FnZSUnLCAkcGFja2FnZU5hbWUsICR0aGlzLT5wcm92aWRlcnNBcGlVcmwpLCAkdGhpcy0+b3B0aW9ucyktPmRlY29kZUpzb24oKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRhcGlSZXN1bHRbJ3Byb3ZpZGVycyddIGFzICRwcm92aWRlcikgewogICAgICAgICAgICAgICAgJHJlc3VsdFskcHJvdmlkZXJbJ25hbWUnXV0gPSAkcHJvdmlkZXI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXMoKSkgewogICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdoYXNQYXJ0aWFsUGFja2FnZXMgZmFpbGVkIHRvIGluaXRpYWxpemUgJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZScpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUgYXMgJHZlcnNpb25zKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcmVzdWx0WyRjYW5kaWRhdGVbJ25hbWUnXV0pIHx8ICFpc3NldCgkY2FuZGlkYXRlWydwcm92aWRlJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGNhbmRpZGF0ZVsnbmFtZSddXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gJGNhbmRpZGF0ZVsnbmFtZSddLAogICAgICAgICAgICAgICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+IGlzc2V0KCRjYW5kaWRhdGVbJ2Rlc2NyaXB0aW9uJ10pID8gJGNhbmRpZGF0ZVsnZGVzY3JpcHRpb24nXSA6ICcnLAogICAgICAgICAgICAgICAgICAgICAgICAndHlwZScgPT4gaXNzZXQoJGNhbmRpZGF0ZVsndHlwZSddKSA/ICRjYW5kaWRhdGVbJ3R5cGUnXSA6ICcnLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cGFja2FnZXMpIHsKICAgICAgICAgICAgJHJlc3VsdCA9IGFycmF5X21lcmdlKCRyZXN1bHQsIHBhcmVudDo6Z2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UHJvdmlkZXJOYW1lcygpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnByb3ZpZGVyTGlzdGluZykgewogICAgICAgICAgICAkdGhpcy0+bG9hZFByb3ZpZGVyTGlzdGluZ3MoJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICAvLyBDYW4gbm90IGRldGVybWluZSBsaXN0IG9mIHByb3ZpZGVkIHBhY2thZ2VzIGZvciBsYXp5IHJlcG9zaXRvcmllcwogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cHJvdmlkZXJzVXJsKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheV9rZXlzKCR0aGlzLT5wcm92aWRlckxpc3RpbmcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZVBhY2thZ2VUcmFuc3BvcnRPcHRpb25zKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldERpc3RVcmxzKCkgYXMgJHVybCkgewogICAgICAgICAgICBpZiAoc3RycG9zKCR1cmwsICR0aGlzLT5iYXNlVXJsKSA9PT0gMCkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFRyYW5zcG9ydE9wdGlvbnMoJHRoaXMtPm9wdGlvbnMpOwoKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGhhc1Byb3ZpZGVycygpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc1Byb3ZpZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJG5hbWUgcGFja2FnZSBuYW1lCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBpbnQ+fG51bGwgJGFjY2VwdGFibGVTdGFiaWxpdGllcwogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+fG51bGwgJGFjY2VwdGFibGVTdGFiaWxpdGllcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgaW50PnxudWxsICRzdGFiaWxpdHlGbGFncyBhbiBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj58bnVsbCAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgUGFja2FnZUludGVyZmFjZT4+ICRhbHJlYWR5TG9hZGVkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdoYXRQcm92aWRlcygkbmFtZSwgYXJyYXkgJGFjY2VwdGFibGVTdGFiaWxpdGllcyA9IG51bGwsIGFycmF5ICRzdGFiaWxpdHlGbGFncyA9IG51bGwsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSBudWxsOwogICAgICAgIGlmICghJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpIHx8ICFpc3NldCgkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lWyRuYW1lXSkpIHsKICAgICAgICAgICAgLy8gc2tpcCBwbGF0Zm9ybSBwYWNrYWdlcywgcm9vdCBwYWNrYWdlIGFuZCBjb21wb3Nlci1wbHVnaW4tYXBpCiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSB8fCAnX19yb290X18nID09PSAkbmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cHJvdmlkZXJMaXN0aW5nKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZFByb3ZpZGVyTGlzdGluZ3MoJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHVzZUxhc3RNb2RpZmllZENoZWNrID0gZmFsc2U7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCAmJiAhaXNzZXQoJHRoaXMtPnByb3ZpZGVyTGlzdGluZ1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkaGFzaCA9IG51bGw7CiAgICAgICAgICAgICAgICAkdXJsID0gc3RyX3JlcGxhY2UoJyVwYWNrYWdlJScsICRuYW1lLCAkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCk7CiAgICAgICAgICAgICAgICAkY2FjaGVLZXkgPSAncHJvdmlkZXItJy5zdHJ0cigkbmFtZSwgJy8nLCAnJCcpLicuanNvbic7CiAgICAgICAgICAgICAgICAkdXNlTGFzdE1vZGlmaWVkQ2hlY2sgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPnByb3ZpZGVyc1VybCkgewogICAgICAgICAgICAgICAgLy8gcGFja2FnZSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHJlcG8KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnByb3ZpZGVyTGlzdGluZ1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGhhc2ggPSAkdGhpcy0+cHJvdmlkZXJMaXN0aW5nWyRuYW1lXVsnc2hhMjU2J107CiAgICAgICAgICAgICAgICAkdXJsID0gc3RyX3JlcGxhY2UoYXJyYXkoJyVwYWNrYWdlJScsICclaGFzaCUnKSwgYXJyYXkoJG5hbWUsICRoYXNoKSwgJHRoaXMtPnByb3ZpZGVyc1VybCk7CiAgICAgICAgICAgICAgICAkY2FjaGVLZXkgPSAncHJvdmlkZXItJy5zdHJ0cigkbmFtZSwgJy8nLCAnJCcpLicuanNvbic7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBhY2thZ2VzID0gbnVsbDsKICAgICAgICAgICAgaWYgKCEkdXNlTGFzdE1vZGlmaWVkQ2hlY2sgJiYgJGhhc2ggJiYgJHRoaXMtPmNhY2hlLT5zaGEyNTYoJGNhY2hlS2V5KSA9PT0gJGhhc2gpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9IGpzb25fZGVjb2RlKCR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpLCB0cnVlKTsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdjYWNoZWQgZmlsZSAoJy4kY2FjaGVLZXkuJyBvcmlnaW5hdGluZyBmcm9tICcuVXJsOjpzYW5pdGl6ZSgkdXJsKS4nKSc7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdXNlTGFzdE1vZGlmaWVkQ2hlY2spIHsKICAgICAgICAgICAgICAgIGlmICgkY29udGVudHMgPSAkdGhpcy0+Y2FjaGUtPnJlYWQoJGNhY2hlS2V5KSkgewogICAgICAgICAgICAgICAgICAgICRjb250ZW50cyA9IGpzb25fZGVjb2RlKCRjb250ZW50cywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgLy8gd2UgYWxyZWFkeSBsb2FkZWQgc29tZSBwYWNrYWdlcyBmcm9tIHRoaXMgZmlsZSwgc28gYXNzdW1lIGl0IGlzIGZyZXNoIGFuZCBhdm9pZCBmZXRjaGluZyBpdCBhZ2FpbgogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYWxyZWFkeUxvYWRlZFskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICRjb250ZW50czsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzU291cmNlID0gJ2NhY2hlZCBmaWxlICgnLiRjYWNoZUtleS4nIG9yaWdpbmF0aW5nIGZyb20gJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGNvbnRlbnRzWydsYXN0LW1vZGlmaWVkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5mZXRjaEZpbGVJZkxhc3RNb2RpZmllZCgkdXJsLCAkY2FjaGVLZXksICRjb250ZW50c1snbGFzdC1tb2RpZmllZCddKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gdHJ1ZSA9PT0gJHJlc3BvbnNlID8gJGNvbnRlbnRzIDogJHJlc3BvbnNlOwogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSB0cnVlID09PSAkcmVzcG9uc2UgPyAnY2FjaGVkIGZpbGUgKCcuJGNhY2hlS2V5Licgb3JpZ2luYXRpbmcgZnJvbSAnLlVybDo6c2FuaXRpemUoJHVybCkuJyknIDogJ2Rvd25sb2FkZWQgZmlsZSAoJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICR0aGlzLT5mZXRjaEZpbGUoJHVybCwgJGNhY2hlS2V5LCAkaGFzaCwgJHVzZUxhc3RNb2RpZmllZENoZWNrKTsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSAnZG93bmxvYWRlZCBmaWxlICgnLlVybDo6c2FuaXRpemUoJHVybCkuJyknOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gNDA0cyBhcmUgYWNjZXB0YWJsZSBmb3IgbGF6eSBwcm92aWRlciByZXBvcwogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCAmJiBpbl9hcnJheSgkZS0+Z2V0U3RhdHVzQ29kZSgpLCBhcnJheSg0MDQsIDQ5OSksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCdwYWNrYWdlcycgPT4gYXJyYXkoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdub3QtZm91bmQgZmlsZSAoJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQ5OSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5lcnJvcignPHdhcm5pbmc+JyAuICRlLT5nZXRNZXNzYWdlKCkgLiAnPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG9hZGluZ1BhcnRpYWxQYWNrYWdlID0gZmFsc2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoJ3BhY2thZ2VzJyA9PiBhcnJheSgndmVyc2lvbnMnID0+ICR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWVbJG5hbWVdKSk7CiAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdyb290IGZpbGUgKCcuVXJsOjpzYW5pdGl6ZSgkdGhpcy0+Z2V0UGFja2FnZXNKc29uVXJsKCkpLicpJzsKICAgICAgICAgICAgJGxvYWRpbmdQYXJ0aWFsUGFja2FnZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICAkdmVyc2lvbnNUb0xvYWQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlc1sncGFja2FnZXMnXSBhcyAkdmVyc2lvbnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHZlcnNpb25zIGFzICR2ZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAkbm9ybWFsaXplZE5hbWUgPSBzdHJ0b2xvd2VyKCR2ZXJzaW9uWyduYW1lJ10pOwoKICAgICAgICAgICAgICAgIC8vIG9ubHkgbG9hZCB0aGUgYWN0dWFsIG5hbWVkIHBhY2thZ2UsIG5vdCBvdGhlciBwYWNrYWdlcyB0aGF0IG1pZ2h0IGZpbmQgdGhlbXNlbHZlcyBpbiB0aGUgc2FtZSBmaWxlCiAgICAgICAgICAgICAgICBpZiAoJG5vcm1hbGl6ZWROYW1lICE9PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghJGxvYWRpbmdQYXJ0aWFsUGFja2FnZSAmJiAkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzKCkgJiYgaXNzZXQoJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZVskbm9ybWFsaXplZE5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHZlcnNpb25zVG9Mb2FkWyR2ZXJzaW9uWyd1aWQnXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHZlcnNpb25bJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9PT0gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxpbmcgb2YgZXhpc3RpbmcgcmVwb3Mgd2hpY2ggbmVlZCB0byByZW1haW4gY29tcG9zZXIgdjEgY29tcGF0aWJsZSwgaW4gY2FzZSB0aGUgdmVyc2lvbl9ub3JtYWxpemVkIGNvbnRhaW5lZCBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUywgd2UgcmVub3JtYWxpemUgaXQKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25bJ3ZlcnNpb25fbm9ybWFsaXplZCddID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkdmVyc2lvblsndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGxvYWRpbmcgcGFja2FnZXMgd2hpY2ggaGF2ZSBhbHJlYWR5IGJlZW4gbG9hZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhbHJlYWR5TG9hZGVkWyRuYW1lXVskdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ11dKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aXNWZXJzaW9uQWNjZXB0YWJsZShudWxsLCAkbm9ybWFsaXplZE5hbWUsICR2ZXJzaW9uLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uc1RvTG9hZFskdmVyc2lvblsndWlkJ11dID0gJHZlcnNpb247CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBsb2FkIGFjY2VwdGFibGUgcGFja2FnZXMgaW4gdGhlIHByb3ZpZGVycwogICAgICAgICRsb2FkZWRQYWNrYWdlcyA9ICR0aGlzLT5jcmVhdGVQYWNrYWdlcygkdmVyc2lvbnNUb0xvYWQsICRwYWNrYWdlc1NvdXJjZSk7CiAgICAgICAgJHVpZHMgPSBhcnJheV9rZXlzKCR2ZXJzaW9uc1RvTG9hZCk7CgogICAgICAgIGZvcmVhY2ggKCRsb2FkZWRQYWNrYWdlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldFJlcG9zaXRvcnkoJHRoaXMpOwogICAgICAgICAgICAkdWlkID0gJHVpZHNbJGluZGV4XTsKCiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgJGFsaWFzZWQgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgJGFsaWFzZWQtPnNldFJlcG9zaXRvcnkoJHRoaXMpOwoKICAgICAgICAgICAgICAgICRyZXN1bHRbJHVpZF0gPSAkYWxpYXNlZDsKICAgICAgICAgICAgICAgICRyZXN1bHRbJHVpZC4nLWFsaWFzJ10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbJHVpZF0gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgICRyZXBvRGF0YSA9ICR0aGlzLT5sb2FkRGF0YUZyb21TZXJ2ZXIoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNyZWF0ZVBhY2thZ2VzKCRyZXBvRGF0YSwgJ3Jvb3QgZmlsZSAoJy5Vcmw6OnNhbml0aXplKCR0aGlzLT5nZXRQYWNrYWdlc0pzb25VcmwoKSkuJyknKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBwYWNrYWdlIHRvIHRoZSByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBwYXJlbnQ6OmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICR0aGlzLT5jb25maWd1cmVQYWNrYWdlVHJhbnNwb3J0T3B0aW9ucygkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlfG51bGw+ICRwYWNrYWdlTmFtZXMgYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IENvbnN0cmFpbnRJbnRlcmZhY2V8bnVsbCAtIGlmIGEgY29uc3RyYWludCBpcyBwcm92aWRlZCwgb25seSBwYWNrYWdlcyBtYXRjaGluZyBpdCB3aWxsIGJlIGxvYWRlZAogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgaW50PnxudWxsICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPnxudWxsICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGludD58bnVsbCAkc3RhYmlsaXR5RmxhZ3MgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+fG51bGwgJHN0YWJpbGl0eUZsYWdzCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+PiAkYWxyZWFkeUxvYWRlZAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7bmFtZXNGb3VuZDogYXJyYXk8c3RyaW5nLCB0cnVlPiwgcGFja2FnZXM6IGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U+fQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRBc3luY1BhY2thZ2VzKGFycmF5ICRwYWNrYWdlTmFtZXMsIGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgPSBudWxsLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MgPSBudWxsLCBhcnJheSAkYWxyZWFkeUxvYWRlZCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpOwoKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRuYW1lc0ZvdW5kID0gYXJyYXkoKTsKICAgICAgICAkcHJvbWlzZXMgPSBhcnJheSgpOwogICAgICAgICRyZXBvID0gJHRoaXM7CgogICAgICAgIGlmICghJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignbG9hZEFzeW5jUGFja2FnZXMgb25seSBzdXBwb3J0cyB2MiBwcm90b2NvbCBjb21wb3NlciByZXBvcyB3aXRoIGEgbWV0YWRhdGEtdXJsJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBsb2FkIH5kZXYgdmVyc2lvbnMgb2YgdGhlIHBhY2thZ2VzIGFzIHdlbGwgaWYgbmVlZGVkCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VOYW1lcyBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoJGFjY2VwdGFibGVTdGFiaWxpdGllcyA9PT0gbnVsbCB8fCAkc3RhYmlsaXR5RmxhZ3MgPT09IG51bGwgfHwgU3RhYmlsaXR5RmlsdGVyOjppc1BhY2thZ2VBY2NlcHRhYmxlKCRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsICRzdGFiaWxpdHlGbGFncywgYXJyYXkoJG5hbWUpLCAnZGV2JykpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlTmFtZXNbJG5hbWUuJ35kZXYnXSA9ICRjb25zdHJhaW50OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGlmIG9ubHkgZGV2IHN0YWJpbGl0eSBpcyByZXF1ZXN0ZWQsIHdlIHNraXAgbG9hZGluZyB0aGUgbm9uIGRldiBmaWxlCiAgICAgICAgICAgIGlmIChpc3NldCgkYWNjZXB0YWJsZVN0YWJpbGl0aWVzWydkZXYnXSkgJiYgY291bnQoJGFjY2VwdGFibGVTdGFiaWxpdGllcykgPT09IDEgJiYgY291bnQoJHN0YWJpbGl0eUZsYWdzKSA9PT0gMCkgewogICAgICAgICAgICAgICAgdW5zZXQoJHBhY2thZ2VOYW1lc1skbmFtZV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU5hbWVzIGFzICRuYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CgogICAgICAgICAgICAkcmVhbE5hbWUgPSBQcmVnOjpyZXBsYWNlKCd7fmRldiR9JywgJycsICRuYW1lKTsKICAgICAgICAgICAgLy8gc2tpcCBwbGF0Zm9ybSBwYWNrYWdlcywgcm9vdCBwYWNrYWdlIGFuZCBjb21wb3Nlci1wbHVnaW4tYXBpCiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRyZWFsTmFtZSkgfHwgJ19fcm9vdF9fJyA9PT0gJHJlYWxOYW1lKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHVybCA9IHN0cl9yZXBsYWNlKCclcGFja2FnZSUnLCAkbmFtZSwgJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpOwogICAgICAgICAgICAkY2FjaGVLZXkgPSAncHJvdmlkZXItJy5zdHJ0cigkbmFtZSwgJy8nLCAnficpLicuanNvbic7CgogICAgICAgICAgICAkbGFzdE1vZGlmaWVkID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRjb250ZW50cyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpKSB7CiAgICAgICAgICAgICAgICAkY29udGVudHMgPSBqc29uX2RlY29kZSgkY29udGVudHMsIHRydWUpOwogICAgICAgICAgICAgICAgJGxhc3RNb2RpZmllZCA9IGlzc2V0KCRjb250ZW50c1snbGFzdC1tb2RpZmllZCddKSA/ICRjb250ZW50c1snbGFzdC1tb2RpZmllZCddIDogbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb21pc2VzW10gPSAkdGhpcy0+YXN5bmNGZXRjaEZpbGUoJHVybCwgJGNhY2hlS2V5LCAkbGFzdE1vZGlmaWVkKQogICAgICAgICAgICAgICAgLT50aGVuKGZ1bmN0aW9uICgkcmVzcG9uc2UpIHVzZSAoJiRwYWNrYWdlcywgJiRuYW1lc0ZvdW5kLCAkdXJsLCAkY2FjaGVLZXksICRjb250ZW50cywgJHJlYWxOYW1lLCAkY29uc3RyYWludCwgJHJlcG8sICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsICRzdGFiaWxpdHlGbGFncywgJGFscmVhZHlMb2FkZWQpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSAnZG93bmxvYWRlZCBmaWxlICgnLlVybDo6c2FuaXRpemUoJHVybCkuJyknOwoKICAgICAgICAgICAgICAgICAgICBpZiAodHJ1ZSA9PT0gJHJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdjYWNoZWQgZmlsZSAoJy4kY2FjaGVLZXkuJyBvcmlnaW5hdGluZyBmcm9tICcuVXJsOjpzYW5pdGl6ZSgkdXJsKS4nKSc7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICRjb250ZW50czsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHJlc3BvbnNlWydwYWNrYWdlcyddWyRyZWFsTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9ucyA9ICRyZXNwb25zZVsncGFja2FnZXMnXVskcmVhbE5hbWVdOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJlc3BvbnNlWydtaW5pZmllZCddKSAmJiAkcmVzcG9uc2VbJ21pbmlmaWVkJ10gPT09ICdjb21wb3Nlci8yLjAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9ucyA9IE1ldGFkYXRhTWluaWZpZXI6OmV4cGFuZCgkdmVyc2lvbnMpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJG5hbWVzRm91bmRbJHJlYWxOYW1lXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25zVG9Mb2FkID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ10gPSAkcmVwby0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCR2ZXJzaW9uWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHZlcnNpb25bJ3ZlcnNpb25fbm9ybWFsaXplZCddID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxpbmcgb2YgZXhpc3RpbmcgcmVwb3Mgd2hpY2ggbmVlZCB0byByZW1haW4gY29tcG9zZXIgdjEgY29tcGF0aWJsZSwgaW4gY2FzZSB0aGUgdmVyc2lvbl9ub3JtYWxpemVkIGNvbnRhaW5lZCBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUywgd2UgcmVub3JtYWxpemUgaXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICRyZXBvLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHZlcnNpb25bJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGxvYWRpbmcgcGFja2FnZXMgd2hpY2ggaGF2ZSBhbHJlYWR5IGJlZW4gbG9hZGVkCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYWxyZWFkeUxvYWRlZFskcmVhbE5hbWVdWyR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXBvLT5pc1ZlcnNpb25BY2NlcHRhYmxlKCRjb25zdHJhaW50LCAkcmVhbE5hbWUsICR2ZXJzaW9uLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNUb0xvYWRbXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkbG9hZGVkUGFja2FnZXMgPSAkcmVwby0+Y3JlYXRlUGFja2FnZXMoJHZlcnNpb25zVG9Mb2FkLCAkcGFja2FnZXNTb3VyY2UpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsb2FkZWRQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0UmVwb3NpdG9yeSgkcmVwbyk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICFpc3NldCgkcGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRBbGlhc09mKCktPnNldFJlcG9zaXRvcnkoJHJlcG8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZS0+Z2V0QWxpYXNPZigpKV0gPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9vcC0+d2FpdCgkcHJvbWlzZXMpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJ25hbWVzRm91bmQnID0+ICRuYW1lc0ZvdW5kLCAncGFja2FnZXMnID0+ICRwYWNrYWdlcyk7CiAgICAgICAgLy8gUmVwb3NpdG9yeVNldCBzaG91bGQgY2FsbCBsb2FkTWV0YWRhdGEsIGdldE1ldGFkYXRhIHdoZW4gYWxsIHByb21pc2VzIHJlc29sdmVkLCB0aGVuIG1ldGFkYXRhQ29tcGxldGUgd2hlbiBkb25lIHNvIHdlIGNhbiBHQyB0aGUgbG9hZGVkIGpzb24gYW5kIHdoYXRub3QgdGhlbiBhcyBuZWVkZWQKICAgIH0KCiAgICAvKioKICAgICAqIFRPRE8gdjMgc2hvdWxkIG1ha2UgdGhpcyBwcml2YXRlIG9uY2Ugd2UgY2FuIGRyb3AgUEhQIDUuMyBzdXBwb3J0CiAgICAgKgogICAgICogQHByaXZhdGUKICAgICAqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZXxudWxsICRjb25zdHJhaW50CiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIHBhY2thZ2UgbmFtZSAobXVzdCBiZSBsb3dlcmNhc2VkIGFscmVhZHkpCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHZlcnNpb25EYXRhCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBpbnQ+fG51bGwgJGFjY2VwdGFibGVTdGFiaWxpdGllcwogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+fG51bGwgJGFjY2VwdGFibGVTdGFiaWxpdGllcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgaW50PnxudWxsICRzdGFiaWxpdHlGbGFncyBhbiBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj58bnVsbCAkc3RhYmlsaXR5RmxhZ3MKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyc2lvbkFjY2VwdGFibGUoJGNvbnN0cmFpbnQsICRuYW1lLCAkdmVyc2lvbkRhdGEsIGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgPSBudWxsLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MgPSBudWxsKQogICAgewogICAgICAgICR2ZXJzaW9ucyA9IGFycmF5KCR2ZXJzaW9uRGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10pOwoKICAgICAgICBpZiAoJGFsaWFzID0gJHRoaXMtPmxvYWRlci0+Z2V0QnJhbmNoQWxpYXMoJHZlcnNpb25EYXRhKSkgewogICAgICAgICAgICAkdmVyc2lvbnNbXSA9ICRhbGlhczsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9ucyBhcyAkdmVyc2lvbikgewogICAgICAgICAgICBpZiAobnVsbCAhPT0gJGFjY2VwdGFibGVTdGFiaWxpdGllcyAmJiBudWxsICE9PSAkc3RhYmlsaXR5RmxhZ3MgJiYgIVN0YWJpbGl0eUZpbHRlcjo6aXNQYWNrYWdlQWNjZXB0YWJsZSgkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5KCRuYW1lKSwgVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHZlcnNpb24pKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY29uc3RyYWludCAmJiAhQ29tcGlsaW5nTWF0Y2hlcjo6bWF0Y2goJGNvbnN0cmFpbnQsIENvbnN0cmFpbnQ6Ok9QX0VRLCAkdmVyc2lvbikpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UGFja2FnZXNKc29uVXJsKCkKICAgIHsKICAgICAgICAkanNvblVybFBhcnRzID0gcGFyc2VfdXJsKCR0aGlzLT51cmwpOwoKICAgICAgICBpZiAoaXNzZXQoJGpzb25VcmxQYXJ0c1sncGF0aCddKSAmJiBmYWxzZSAhPT0gc3RycG9zKCRqc29uVXJsUGFydHNbJ3BhdGgnXSwgJy5qc29uJykpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT51cmw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnVybCAuICcvcGFja2FnZXMuanNvbic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50fG51bGwgJHJvb3RNYXhBZ2UKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBtaXhlZD4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRSb290U2VydmVyRmlsZSgkcm9vdE1heEFnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5yb290RGF0YSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3REYXRhOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykgJiYgc3RycG9zKCR0aGlzLT51cmwsICdodHRwcycpID09PSAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IG11c3QgZW5hYmxlIHRoZSBvcGVuc3NsIGV4dGVuc2lvbiBpbiB5b3VyIHBocC5pbmkgdG8gbG9hZCBpbmZvcm1hdGlvbiBmcm9tICcuJHRoaXMtPnVybCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhY2hlZERhdGEgPSAkdGhpcy0+Y2FjaGUtPnJlYWQoJ3BhY2thZ2VzLmpzb24nKSkgewogICAgICAgICAgICAkY2FjaGVkRGF0YSA9IGpzb25fZGVjb2RlKCRjYWNoZWREYXRhLCB0cnVlKTsKICAgICAgICAgICAgaWYgKCRyb290TWF4QWdlICE9PSBudWxsICYmICgkYWdlID0gJHRoaXMtPmNhY2hlLT5nZXRBZ2UoJ3BhY2thZ2VzLmpzb24nKSkgIT09IGZhbHNlICYmICRhZ2UgPD0gJHJvb3RNYXhBZ2UpIHsKICAgICAgICAgICAgICAgICRkYXRhID0gJGNhY2hlZERhdGE7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkY2FjaGVkRGF0YVsnbGFzdC1tb2RpZmllZCddKSkgewogICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmZldGNoRmlsZUlmTGFzdE1vZGlmaWVkKCR0aGlzLT5nZXRQYWNrYWdlc0pzb25VcmwoKSwgJ3BhY2thZ2VzLmpzb24nLCAkY2FjaGVkRGF0YVsnbGFzdC1tb2RpZmllZCddKTsKICAgICAgICAgICAgICAgICRkYXRhID0gdHJ1ZSA9PT0gJHJlc3BvbnNlID8gJGNhY2hlZERhdGEgOiAkcmVzcG9uc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJGRhdGEpKSB7CiAgICAgICAgICAgICRkYXRhID0gJHRoaXMtPmZldGNoRmlsZSgkdGhpcy0+Z2V0UGFja2FnZXNKc29uVXJsKCksICdwYWNrYWdlcy5qc29uJywgbnVsbCwgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydub3RpZnktYmF0Y2gnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPm5vdGlmeVVybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ25vdGlmeS1iYXRjaCddKTsKICAgICAgICB9IGVsc2VpZiAoIWVtcHR5KCRkYXRhWydub3RpZnknXSkpIHsKICAgICAgICAgICAgJHRoaXMtPm5vdGlmeVVybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ25vdGlmeSddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ3NlYXJjaCddKSkgewogICAgICAgICAgICAkdGhpcy0+c2VhcmNoVXJsID0gJHRoaXMtPmNhbm9uaWNhbGl6ZVVybCgkZGF0YVsnc2VhcmNoJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVsnbWlycm9ycyddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZGF0YVsnbWlycm9ycyddIGFzICRtaXJyb3IpIHsKICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJG1pcnJvclsnZ2l0LXVybCddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zb3VyY2VNaXJyb3JzWydnaXQnXVtdID0gYXJyYXkoJ3VybCcgPT4gJG1pcnJvclsnZ2l0LXVybCddLCAncHJlZmVycmVkJyA9PiAhZW1wdHkoJG1pcnJvclsncHJlZmVycmVkJ10pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJG1pcnJvclsnaGctdXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNvdXJjZU1pcnJvcnNbJ2hnJ11bXSA9IGFycmF5KCd1cmwnID0+ICRtaXJyb3JbJ2hnLXVybCddLCAncHJlZmVycmVkJyA9PiAhZW1wdHkoJG1pcnJvclsncHJlZmVycmVkJ10pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJG1pcnJvclsnZGlzdC11cmwnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzdE1pcnJvcnNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAndXJsJyA9PiAkdGhpcy0+Y2Fub25pY2FsaXplVXJsKCRtaXJyb3JbJ2Rpc3QtdXJsJ10pLAogICAgICAgICAgICAgICAgICAgICAgICAncHJlZmVycmVkJyA9PiAhZW1wdHkoJG1pcnJvclsncHJlZmVycmVkJ10pLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ3Byb3ZpZGVycy1sYXp5LXVybCddKSkgewogICAgICAgICAgICAkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ3Byb3ZpZGVycy1sYXp5LXVybCddKTsKICAgICAgICAgICAgJHRoaXMtPmhhc1Byb3ZpZGVycyA9IHRydWU7CgogICAgICAgICAgICAkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzID0gIWVtcHR5KCRkYXRhWydwYWNrYWdlcyddKSAmJiBpc19hcnJheSgkZGF0YVsncGFja2FnZXMnXSk7CiAgICAgICAgfQoKICAgICAgICAvLyBtZXRhZGF0YS11cmwgaW5kaWNhdGVzIFYyIHJlcG8gcHJvdG9jb2wgc28gaXQgdGFrZXMgb3ZlciBmcm9tIGFsbCB0aGUgVjEgdHlwZXMKICAgICAgICAvLyBWMiBvbmx5IGhhcyBsYXp5UHJvdmlkZXJzIGFuZCBwb3NzaWJseSBwYXJ0aWFsIHBhY2thZ2VzLCBidXQgbm8gYWJpbGl0eSB0byBwcm9jZXNzIGFueXRoaW5nIGVsc2UsCiAgICAgICAgLy8gVjIgYWxzbyBzdXBwb3J0cyBhc3luYyBsb2FkaW5nCiAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVsnbWV0YWRhdGEtdXJsJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5sYXp5UHJvdmlkZXJzVXJsID0gJHRoaXMtPmNhbm9uaWNhbGl6ZVVybCgkZGF0YVsnbWV0YWRhdGEtdXJsJ10pOwogICAgICAgICAgICAkdGhpcy0+cHJvdmlkZXJzVXJsID0gbnVsbDsKICAgICAgICAgICAgJHRoaXMtPmhhc1Byb3ZpZGVycyA9IGZhbHNlOwogICAgICAgICAgICAkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzID0gIWVtcHR5KCRkYXRhWydwYWNrYWdlcyddKSAmJiBpc19hcnJheSgkZGF0YVsncGFja2FnZXMnXSk7CiAgICAgICAgICAgICR0aGlzLT5hbGxvd1NzbERvd25ncmFkZSA9IGZhbHNlOwoKICAgICAgICAgICAgLy8gcHJvdmlkZXMgYSBsaXN0IG9mIHBhY2thZ2UgbmFtZXMgdGhhdCBhcmUgYXZhaWxhYmxlIGluIHRoaXMgcmVwbwogICAgICAgICAgICAvLyB0aGlzIGRpc2FibGVzIGxhenktcHJvdmlkZXIgYmVoYXZpb3IgaW4gdGhlIHNlbnNlIHRoYXQgaWYgYSBsaXN0IGlzIGF2YWlsYWJsZSB3ZSBhc3N1bWUgaXQgaXMgZmluaXRlIGFuZCB3b24ndCBzZWFyY2ggZm9yIG90aGVyIHBhY2thZ2VzIGluIHRoYXQgcmVwbwogICAgICAgICAgICAvLyB3aGlsZSBpZiBubyBsaXN0IGlzIHRoZXJlIGxhenlQcm92aWRlcnNVcmwgaXMgdXNlZCB3aGVuIGxvb2tpbmcgZm9yIGFueSBwYWNrYWdlIG5hbWUgdG8gc2VlIGlmIHRoZSByZXBvIGtub3dzIGl0CiAgICAgICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ2F2YWlsYWJsZS1wYWNrYWdlcyddKSkgewogICAgICAgICAgICAgICAgJGF2YWlsUGFja2FnZXMgPSBhcnJheV9tYXAoJ3N0cnRvbG93ZXInLCAkZGF0YVsnYXZhaWxhYmxlLXBhY2thZ2VzJ10pOwogICAgICAgICAgICAgICAgJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VzID0gYXJyYXlfY29tYmluZSgkYXZhaWxQYWNrYWdlcywgJGF2YWlsUGFja2FnZXMpOwogICAgICAgICAgICAgICAgJHRoaXMtPmhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0ID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUHJvdmlkZXMgYSBsaXN0IG9mIHBhY2thZ2UgbmFtZSBwYXR0ZXJucyAodXNpbmcgKiB3aWxkY2FyZHMgdG8gbWF0Y2ggYW55IHN1YnN0cmluZywgZS5nLiAidmVuZG9yLyoiKSB0aGF0IGFyZSBhdmFpbGFibGUgaW4gdGhpcyByZXBvCiAgICAgICAgICAgIC8vIERpc2FibGVzIGxhenktcHJvdmlkZXIgYmVoYXZpb3IgYXMgd2l0aCBhdmFpbGFibGUtcGFja2FnZXMsIGJ1dCBtYXkgYWxsb3cgbXVjaCBtb3JlIGNvbXBhY3QgZXhwcmVzc2lvbiBvZiBwYWNrYWdlcyBjb3ZlcmVkIGJ5IHRoaXMgcmVwb3NpdG9yeS4KICAgICAgICAgICAgLy8gT3Zlci1zcGVjaWZ5aW5nIGNvdmVyZWQgcGFja2FnZXMgaXMgc2FmZSwgYnV0IG1heSByZXN1bHQgaW4gaW5jcmVhc2VkIHRyYWZmaWMgdG8geW91ciByZXBvc2l0b3J5LgogICAgICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydhdmFpbGFibGUtcGFja2FnZS1wYXR0ZXJucyddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VQYXR0ZXJucyA9IGFycmF5X21hcChmdW5jdGlvbiAoJHBhdHRlcm4pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lVG9SZWdleHAoJHBhdHRlcm4pOwogICAgICAgICAgICAgICAgfSwgJGRhdGFbJ2F2YWlsYWJsZS1wYWNrYWdlLXBhdHRlcm5zJ10pOwogICAgICAgICAgICAgICAgJHRoaXMtPmhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0ID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUmVtb3ZlIGxlZ2FjeSBrZXlzIGFzIG1vc3QgcmVwb3MgbmVlZCB0byBiZSBjb21wYXRpYmxlIHdpdGggQ29tcG9zZXIgdjEKICAgICAgICAgICAgLy8gYXMgd2VsbCBidXQgd2UgYXJlIG5vdCBpbnRlcmVzdGVkIGluIHRoZSBvbGQgZm9ybWF0IGFueW1vcmUgYXQgdGhpcyBwb2ludAogICAgICAgICAgICB1bnNldCgkZGF0YVsncHJvdmlkZXJzLXVybCddLCAkZGF0YVsncHJvdmlkZXJzJ10sICRkYXRhWydwcm92aWRlcnMtaW5jbHVkZXMnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmFsbG93U3NsRG93bmdyYWRlKSB7CiAgICAgICAgICAgICR0aGlzLT51cmwgPSBzdHJfcmVwbGFjZSgnaHR0cHM6Ly8nLCAnaHR0cDovLycsICR0aGlzLT51cmwpOwogICAgICAgICAgICAkdGhpcy0+YmFzZVVybCA9IHN0cl9yZXBsYWNlKCdodHRwczovLycsICdodHRwOi8vJywgJHRoaXMtPmJhc2VVcmwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVsncHJvdmlkZXJzLXVybCddKSkgewogICAgICAgICAgICAkdGhpcy0+cHJvdmlkZXJzVXJsID0gJHRoaXMtPmNhbm9uaWNhbGl6ZVVybCgkZGF0YVsncHJvdmlkZXJzLXVybCddKTsKICAgICAgICAgICAgJHRoaXMtPmhhc1Byb3ZpZGVycyA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydsaXN0J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5saXN0VXJsID0gJHRoaXMtPmNhbm9uaWNhbGl6ZVVybCgkZGF0YVsnbGlzdCddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ3Byb3ZpZGVycyddKSB8fCAhZW1wdHkoJGRhdGFbJ3Byb3ZpZGVycy1pbmNsdWRlcyddKSkgewogICAgICAgICAgICAkdGhpcy0+aGFzUHJvdmlkZXJzID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ3Byb3ZpZGVycy1hcGknXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnByb3ZpZGVyc0FwaVVybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ3Byb3ZpZGVycy1hcGknXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3REYXRhID0gJGRhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNhbm9uaWNhbGl6ZVVybCgkdXJsKQogICAgewogICAgICAgIGlmICgnLycgPT09ICR1cmxbMF0pIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teW146XSsrOi8vW14vXSorfScsICR0aGlzLT51cmwsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWzBdIC4gJHVybDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT51cmw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gbWl4ZWRbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWREYXRhRnJvbVNlcnZlcigpCiAgICB7CiAgICAgICAgJGRhdGEgPSAkdGhpcy0+bG9hZFJvb3RTZXJ2ZXJGaWxlKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+bG9hZEluY2x1ZGVzKCRkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGhhc1BhcnRpYWxQYWNrYWdlcygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXMgJiYgbnVsbCA9PT0gJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZSkgewogICAgICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZVBhcnRpYWxQYWNrYWdlcygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl7cHJvdmlkZXJzPzogbWl4ZWRbXSwgcHJvdmlkZXItaW5jbHVkZXM/OiBtaXhlZFtdfSAkZGF0YQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRQcm92aWRlckxpc3RpbmdzKCRkYXRhKQogICAgewogICAgICAgIGlmIChpc3NldCgkZGF0YVsncHJvdmlkZXJzJ10pKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHRoaXMtPnByb3ZpZGVyTGlzdGluZykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm92aWRlckxpc3RpbmcgPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5wcm92aWRlckxpc3RpbmcgPSBhcnJheV9tZXJnZSgkdGhpcy0+cHJvdmlkZXJMaXN0aW5nLCAkZGF0YVsncHJvdmlkZXJzJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wcm92aWRlcnNVcmwgJiYgaXNzZXQoJGRhdGFbJ3Byb3ZpZGVyLWluY2x1ZGVzJ10pKSB7CiAgICAgICAgICAgICRpbmNsdWRlcyA9ICRkYXRhWydwcm92aWRlci1pbmNsdWRlcyddOwogICAgICAgICAgICBmb3JlYWNoICgkaW5jbHVkZXMgYXMgJGluY2x1ZGUgPT4gJG1ldGFkYXRhKSB7CiAgICAgICAgICAgICAgICAkdXJsID0gJHRoaXMtPmJhc2VVcmwgLiAnLycgLiBzdHJfcmVwbGFjZSgnJWhhc2glJywgJG1ldGFkYXRhWydzaGEyNTYnXSwgJGluY2x1ZGUpOwogICAgICAgICAgICAgICAgJGNhY2hlS2V5ID0gc3RyX3JlcGxhY2UoYXJyYXkoJyVoYXNoJScsJyQnKSwgJycsICRpbmNsdWRlKTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y2FjaGUtPnNoYTI1NigkY2FjaGVLZXkpID09PSAkbWV0YWRhdGFbJ3NoYTI1NiddKSB7CiAgICAgICAgICAgICAgICAgICAgJGluY2x1ZGVkRGF0YSA9IGpzb25fZGVjb2RlKCR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGluY2x1ZGVkRGF0YSA9ICR0aGlzLT5mZXRjaEZpbGUoJHVybCwgJGNhY2hlS2V5LCAkbWV0YWRhdGFbJ3NoYTI1NiddKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZFByb3ZpZGVyTGlzdGluZ3MoJGluY2x1ZGVkRGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkZGF0YQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWRbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRJbmNsdWRlcygkZGF0YSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwoKICAgICAgICAvLyBsZWdhY3kgcmVwbyBoYW5kbGluZwogICAgICAgIGlmICghaXNzZXQoJGRhdGFbJ3BhY2thZ2VzJ10pICYmICFpc3NldCgkZGF0YVsnaW5jbHVkZXMnXSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGRhdGEgYXMgJHBrZykgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwa2dbJ3ZlcnNpb25zJ10pICYmIGlzX2FycmF5KCRwa2dbJ3ZlcnNpb25zJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBrZ1sndmVyc2lvbnMnXSBhcyAkbWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkbWV0YWRhdGE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHBhY2thZ2VzOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydwYWNrYWdlcyddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZGF0YVsncGFja2FnZXMnXSBhcyAkcGFja2FnZSA9PiAkdmVyc2lvbnMpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9ucyBhcyAkdmVyc2lvbiA9PiAkbWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNbXSA9ICRtZXRhZGF0YTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydpbmNsdWRlcyddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZGF0YVsnaW5jbHVkZXMnXSBhcyAkaW5jbHVkZSA9PiAkbWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWV0YWRhdGFbJ3NoYTEnXSkgJiYgJHRoaXMtPmNhY2hlLT5zaGExKChzdHJpbmcpICRpbmNsdWRlKSA9PT0gJG1ldGFkYXRhWydzaGExJ10pIHsKICAgICAgICAgICAgICAgICAgICAkaW5jbHVkZWREYXRhID0ganNvbl9kZWNvZGUoJHRoaXMtPmNhY2hlLT5yZWFkKChzdHJpbmcpICRpbmNsdWRlKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpbmNsdWRlZERhdGEgPSAkdGhpcy0+ZmV0Y2hGaWxlKCRpbmNsdWRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5X21lcmdlKCRwYWNrYWdlcywgJHRoaXMtPmxvYWRJbmNsdWRlcygkaW5jbHVkZWREYXRhKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByaXZhdGUKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkcGFja2FnZXMKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkc291cmNlCiAgICAgKgogICAgICogQHJldHVybiBsaXN0PENvbXBsZXRlUGFja2FnZXxDb21wbGV0ZUFsaWFzUGFja2FnZT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyZWF0ZVBhY2thZ2VzKGFycmF5ICRwYWNrYWdlcywgJHNvdXJjZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCEkcGFja2FnZXMpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJiRkYXRhKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWydub3RpZmljYXRpb24tdXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ25vdGlmaWNhdGlvbi11cmwnXSA9ICR0aGlzLT5ub3RpZnlVcmw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwYWNrYWdlSW5zdGFuY2VzID0gJHRoaXMtPmxvYWRlci0+bG9hZFBhY2thZ2VzKCRwYWNrYWdlcyk7CgogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZUluc3RhbmNlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5zb3VyY2VNaXJyb3JzWyRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCldKSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRTb3VyY2VNaXJyb3JzKCR0aGlzLT5zb3VyY2VNaXJyb3JzWyRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXREaXN0TWlycm9ycygkdGhpcy0+ZGlzdE1pcnJvcnMpOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ3VyZVBhY2thZ2VUcmFuc3BvcnRPcHRpb25zKCRwYWNrYWdlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlSW5zdGFuY2VzOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgbG9hZCBwYWNrYWdlcyAnLihpc3NldCgkcGFja2FnZXNbMF1bJ25hbWUnXSkgPyAkcGFja2FnZXNbMF1bJ25hbWUnXSA6IGpzb25fZW5jb2RlKCRwYWNrYWdlcykpLicgaW4gJy4kdGhpcy0+Z2V0UmVwb05hbWUoKS4oJHNvdXJjZSA/ICcgZnJvbSAnLiRzb3VyY2UgOiAnJykuJzogWycuZ2V0X2NsYXNzKCRlKS4nXSAnLiRlLT5nZXRNZXNzYWdlKCksIDAsICRlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlbmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjYWNoZUtleQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRzaGEyNTYKICAgICAqIEBwYXJhbSBib29sICRzdG9yZUxhc3RNb2RpZmllZFRpbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PG1peGVkPgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZmV0Y2hGaWxlKCRmaWxlbmFtZSwgJGNhY2hlS2V5ID0gbnVsbCwgJHNoYTI1NiA9IG51bGwsICRzdG9yZUxhc3RNb2RpZmllZFRpbWUgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGNhY2hlS2V5KSB7CiAgICAgICAgICAgICRjYWNoZUtleSA9ICRmaWxlbmFtZTsKICAgICAgICAgICAgJGZpbGVuYW1lID0gJHRoaXMtPmJhc2VVcmwuJy8nLiRmaWxlbmFtZTsKICAgICAgICB9CgogICAgICAgIC8vIHVybC1lbmNvZGUgJCBzaWducyBpbiBVUkxzIGFzIGJhZCBwcm94aWVzIGNob2tlIG9uIHRoZW0KICAgICAgICBpZiAoKCRwb3MgPSBzdHJwb3MoJGZpbGVuYW1lLCAnJCcpKSAmJiBQcmVnOjppc01hdGNoKCd7Xmh0dHBzPzovL31pJywgJGZpbGVuYW1lKSkgewogICAgICAgICAgICAkZmlsZW5hbWUgPSBzdWJzdHIoJGZpbGVuYW1lLCAwLCAkcG9zKSAuICclMjQnIC4gc3Vic3RyKCRmaWxlbmFtZSwgJHBvcyArIDEpOwogICAgICAgIH0KCiAgICAgICAgJHJldHJpZXMgPSAzOwogICAgICAgIHdoaWxlICgkcmV0cmllcy0tKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICR0aGlzLT5vcHRpb25zOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5ldmVudERpc3BhdGNoZXIpIHsKICAgICAgICAgICAgICAgICAgICAkcHJlRmlsZURvd25sb2FkRXZlbnQgPSBuZXcgUHJlRmlsZURvd25sb2FkRXZlbnQoUGx1Z2luRXZlbnRzOjpQUkVfRklMRV9ET1dOTE9BRCwgJHRoaXMtPmh0dHBEb3dubG9hZGVyLCAkZmlsZW5hbWUsICdtZXRhZGF0YScsIGFycmF5KCdyZXBvc2l0b3J5JyA9PiAkdGhpcykpOwogICAgICAgICAgICAgICAgICAgICRwcmVGaWxlRG93bmxvYWRFdmVudC0+c2V0VHJhbnNwb3J0T3B0aW9ucygkdGhpcy0+b3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2goJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXROYW1lKCksICRwcmVGaWxlRG93bmxvYWRFdmVudCk7CiAgICAgICAgICAgICAgICAgICAgJGZpbGVuYW1lID0gJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRQcm9jZXNzZWRVcmwoKTsKICAgICAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRmaWxlbmFtZSwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgJGpzb24gPSAoc3RyaW5nKSAkcmVzcG9uc2UtPmdldEJvZHkoKTsKICAgICAgICAgICAgICAgIGlmICgkc2hhMjU2ICYmICRzaGEyNTYgIT09IGhhc2goJ3NoYTI1NicsICRqc29uKSkgewogICAgICAgICAgICAgICAgICAgIC8vIHVuZG8gZG93bmdyYWRlIGJlZm9yZSB0cnlpbmcgYWdhaW4gaWYgaHR0cCBzZWVtcyB0byBiZSBoaWphY2tlZCBvciBtb2RpZnlpbmcgY29udGVudCBzb21laG93CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5hbGxvd1NzbERvd25ncmFkZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXJsID0gc3RyX3JlcGxhY2UoJ2h0dHA6Ly8nLCAnaHR0cHM6Ly8nLCAkdGhpcy0+dXJsKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmJhc2VVcmwgPSBzdHJfcmVwbGFjZSgnaHR0cDovLycsICdodHRwczovLycsICR0aGlzLT5iYXNlVXJsKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGZpbGVuYW1lID0gc3RyX3JlcGxhY2UoJ2h0dHA6Ly8nLCAnaHR0cHM6Ly8nLCAkZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXRyaWVzID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB1c2xlZXAoMTAwMDAwKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyB1c2Ugc2NhcmllciB3b3JkaW5nIG9uY2Ugd2Uga25vdyBmb3Igc3VyZSBpdCBkb2Vzbid0IGRvIGZhbHNlIHBvc2l0aXZlcyBhbnltb3JlCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlcG9zaXRvcnlTZWN1cml0eUV4Y2VwdGlvbignVGhlIGNvbnRlbnRzIG9mICcuJGZpbGVuYW1lLicgZG8gbm90IG1hdGNoIGl0cyBzaWduYXR1cmUuIFRoaXMgY291bGQgaW5kaWNhdGUgYSBtYW4taW4tdGhlLW1pZGRsZSBhdHRhY2sgb3IgZS5nLiBhbnRpdmlydXMgc29mdHdhcmUgY29ycnVwdGluZyBmaWxlcy4gVHJ5IHJ1bm5pbmcgY29tcG9zZXIgYWdhaW4gYW5kIHJlcG9ydCB0aGlzIGlmIHlvdSB0aGluayBpdCBpcyBhIG1pc3Rha2UuJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5ldmVudERpc3BhdGNoZXIpIHsKICAgICAgICAgICAgICAgICAgICAkcG9zdEZpbGVEb3dubG9hZEV2ZW50ID0gbmV3IFBvc3RGaWxlRG93bmxvYWRFdmVudChQbHVnaW5FdmVudHM6OlBPU1RfRklMRV9ET1dOTE9BRCwgbnVsbCwgJHNoYTI1NiwgJGZpbGVuYW1lLCAnbWV0YWRhdGEnLCBhcnJheSgncmVzcG9uc2UnID0+ICRyZXNwb25zZSwgJ3JlcG9zaXRvcnknID0+ICR0aGlzKSk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2goJHBvc3RGaWxlRG93bmxvYWRFdmVudC0+Z2V0TmFtZSgpLCAkcG9zdEZpbGVEb3dubG9hZEV2ZW50KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkZGF0YSA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICAgICAgSHR0cERvd25sb2FkZXI6Om91dHB1dFdhcm5pbmdzKCR0aGlzLT5pbywgJHRoaXMtPnVybCwgJGRhdGEpOwoKICAgICAgICAgICAgICAgIGlmICgkY2FjaGVLZXkgJiYgISR0aGlzLT5jYWNoZS0+aXNSZWFkT25seSgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRzdG9yZUxhc3RNb2RpZmllZFRpbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxhc3RNb2RpZmllZERhdGUgPSAkcmVzcG9uc2UtPmdldEhlYWRlcignbGFzdC1tb2RpZmllZCcpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxhc3RNb2RpZmllZERhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkYXRhWydsYXN0LW1vZGlmaWVkJ10gPSAkbGFzdE1vZGlmaWVkRGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRqc29uID0gSnNvbkZpbGU6OmVuY29kZSgkZGF0YSwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNhY2hlLT53cml0ZSgkY2FjaGVLZXksICRqc29uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzcG9uc2UtPmNvbGxlY3QoKTsKCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgXExvZ2ljRXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQwNCkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFJlcG9zaXRvcnlTZWN1cml0eUV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkY2FjaGVLZXkgJiYgKCRjb250ZW50cyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmRlZ3JhZGVkTW9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJHRoaXMtPnVybC4nIGNvdWxkIG5vdCBiZSBmdWxseSBsb2FkZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKSwgcGFja2FnZSBpbmZvcm1hdGlvbiB3YXMgbG9hZGVkIGZyb20gdGhlIGxvY2FsIGNhY2hlIGFuZCBtYXkgYmUgb3V0IG9mIGRhdGU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kZWdyYWRlZE1vZGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICRkYXRhID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkY29udGVudHMsICR0aGlzLT5jYWNoZS0+Z2V0Um9vdCgpLiRjYWNoZUtleSk7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRkYXRhKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCJDb21wb3NlclJlcG9zaXRvcnk6IFVuZGVmaW5lZCBcJGRhdGEuIFBsZWFzZSByZXBvcnQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy9uZXcuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkY2FjaGVLZXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxhc3RNb2RpZmllZFRpbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PG1peGVkPnx0cnVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmV0Y2hGaWxlSWZMYXN0TW9kaWZpZWQoJGZpbGVuYW1lLCAkY2FjaGVLZXksICRsYXN0TW9kaWZpZWRUaW1lKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRvcHRpb25zID0gJHRoaXMtPm9wdGlvbnM7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICAgICAkcHJlRmlsZURvd25sb2FkRXZlbnQgPSBuZXcgUHJlRmlsZURvd25sb2FkRXZlbnQoUGx1Z2luRXZlbnRzOjpQUkVfRklMRV9ET1dOTE9BRCwgJHRoaXMtPmh0dHBEb3dubG9hZGVyLCAkZmlsZW5hbWUsICdtZXRhZGF0YScsIGFycmF5KCdyZXBvc2l0b3J5JyA9PiAkdGhpcykpOwogICAgICAgICAgICAgICAgJHByZUZpbGVEb3dubG9hZEV2ZW50LT5zZXRUcmFuc3BvcnRPcHRpb25zKCR0aGlzLT5vcHRpb25zKTsKICAgICAgICAgICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0TmFtZSgpLCAkcHJlRmlsZURvd25sb2FkRXZlbnQpOwogICAgICAgICAgICAgICAgJGZpbGVuYW1lID0gJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRQcm9jZXNzZWRVcmwoKTsKICAgICAgICAgICAgICAgICRvcHRpb25zID0gJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRUcmFuc3BvcnRPcHRpb25zKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkpIHsKICAgICAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gKGFycmF5KSAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gJ0lmLU1vZGlmaWVkLVNpbmNlOiAnLiRsYXN0TW9kaWZpZWRUaW1lOwogICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkZmlsZW5hbWUsICRvcHRpb25zKTsKICAgICAgICAgICAgJGpzb24gPSAoc3RyaW5nKSAkcmVzcG9uc2UtPmdldEJvZHkoKTsKICAgICAgICAgICAgaWYgKCRqc29uID09PSAnJyAmJiAkcmVzcG9uc2UtPmdldFN0YXR1c0NvZGUoKSA9PT0gMzA0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5ldmVudERpc3BhdGNoZXIpIHsKICAgICAgICAgICAgICAgICRwb3N0RmlsZURvd25sb2FkRXZlbnQgPSBuZXcgUG9zdEZpbGVEb3dubG9hZEV2ZW50KFBsdWdpbkV2ZW50czo6UE9TVF9GSUxFX0RPV05MT0FELCBudWxsLCBudWxsLCAkZmlsZW5hbWUsICdtZXRhZGF0YScsIGFycmF5KCdyZXNwb25zZScgPT4gJHJlc3BvbnNlLCAncmVwb3NpdG9yeScgPT4gJHRoaXMpKTsKICAgICAgICAgICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwb3N0RmlsZURvd25sb2FkRXZlbnQtPmdldE5hbWUoKSwgJHBvc3RGaWxlRG93bmxvYWRFdmVudCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRkYXRhID0gJHJlc3BvbnNlLT5kZWNvZGVKc29uKCk7CiAgICAgICAgICAgIEh0dHBEb3dubG9hZGVyOjpvdXRwdXRXYXJuaW5ncygkdGhpcy0+aW8sICR0aGlzLT51cmwsICRkYXRhKTsKCiAgICAgICAgICAgICRsYXN0TW9kaWZpZWREYXRlID0gJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2xhc3QtbW9kaWZpZWQnKTsKICAgICAgICAgICAgJHJlc3BvbnNlLT5jb2xsZWN0KCk7CiAgICAgICAgICAgIGlmICgkbGFzdE1vZGlmaWVkRGF0ZSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2xhc3QtbW9kaWZpZWQnXSA9ICRsYXN0TW9kaWZpZWREYXRlOwogICAgICAgICAgICAgICAgJGpzb24gPSBKc29uRmlsZTo6ZW5jb2RlKCRkYXRhLCAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISR0aGlzLT5jYWNoZS0+aXNSZWFkT25seSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPndyaXRlKCRjYWNoZUtleSwgJGpzb24pOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGRhdGE7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBcTG9naWNFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJGUtPmdldFN0YXR1c0NvZGUoKSA9PT0gNDA0KSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZGVncmFkZWRNb2RlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJHRoaXMtPnVybC4nIGNvdWxkIG5vdCBiZSBmdWxseSBsb2FkZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKSwgcGFja2FnZSBpbmZvcm1hdGlvbiB3YXMgbG9hZGVkIGZyb20gdGhlIGxvY2FsIGNhY2hlIGFuZCBtYXkgYmUgb3V0IG9mIGRhdGU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmRlZ3JhZGVkTW9kZSA9IHRydWU7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkY2FjaGVLZXkKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkbGFzdE1vZGlmaWVkVGltZQogICAgICoKICAgICAqIEByZXR1cm4gXFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFzeW5jRmV0Y2hGaWxlKCRmaWxlbmFtZSwgJGNhY2hlS2V5LCAkbGFzdE1vZGlmaWVkVGltZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wYWNrYWdlc05vdEZvdW5kQ2FjaGVbJGZpbGVuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoYXJyYXkoJ3BhY2thZ2VzJyA9PiBhcnJheSgpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmZyZXNoTWV0YWRhdGFVcmxzWyRmaWxlbmFtZV0pICYmICRsYXN0TW9kaWZpZWRUaW1lKSB7CiAgICAgICAgICAgIC8vIG1ha2UgaXQgbG9vayBsaWtlIHdlIGdvdCBhIDMwNCByZXNwb25zZQogICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSh0cnVlKTsKICAgICAgICB9CgogICAgICAgICRodHRwRG93bmxvYWRlciA9ICR0aGlzLT5odHRwRG93bmxvYWRlcjsKICAgICAgICAkb3B0aW9ucyA9ICR0aGlzLT5vcHRpb25zOwogICAgICAgIGlmICgkdGhpcy0+ZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICRwcmVGaWxlRG93bmxvYWRFdmVudCA9IG5ldyBQcmVGaWxlRG93bmxvYWRFdmVudChQbHVnaW5FdmVudHM6OlBSRV9GSUxFX0RPV05MT0FELCAkdGhpcy0+aHR0cERvd25sb2FkZXIsICRmaWxlbmFtZSwgJ21ldGFkYXRhJywgYXJyYXkoJ3JlcG9zaXRvcnknID0+ICR0aGlzKSk7CiAgICAgICAgICAgICRwcmVGaWxlRG93bmxvYWRFdmVudC0+c2V0VHJhbnNwb3J0T3B0aW9ucygkdGhpcy0+b3B0aW9ucyk7CiAgICAgICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0TmFtZSgpLCAkcHJlRmlsZURvd25sb2FkRXZlbnQpOwogICAgICAgICAgICAkZmlsZW5hbWUgPSAkcHJlRmlsZURvd25sb2FkRXZlbnQtPmdldFByb2Nlc3NlZFVybCgpOwogICAgICAgICAgICAkb3B0aW9ucyA9ICRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsYXN0TW9kaWZpZWRUaW1lKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkpIHsKICAgICAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gKGFycmF5KSAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gJ0lmLU1vZGlmaWVkLVNpbmNlOiAnLiRsYXN0TW9kaWZpZWRUaW1lOwogICAgICAgIH0KCiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICR1cmwgPSAkdGhpcy0+dXJsOwogICAgICAgICRjYWNoZSA9ICR0aGlzLT5jYWNoZTsKICAgICAgICAkZGVncmFkZWRNb2RlID0gJiR0aGlzLT5kZWdyYWRlZE1vZGU7CiAgICAgICAgJGV2ZW50RGlzcGF0Y2hlciA9ICR0aGlzLT5ldmVudERpc3BhdGNoZXI7CiAgICAgICAgJHJlcG8gPSAkdGhpczsKCiAgICAgICAgJGFjY2VwdCA9IGZ1bmN0aW9uICgkcmVzcG9uc2UpIHVzZSAoJGlvLCAkdXJsLCAkZmlsZW5hbWUsICRjYWNoZSwgJGNhY2hlS2V5LCAkZXZlbnREaXNwYXRjaGVyLCAkcmVwbykgewogICAgICAgICAgICAvLyBwYWNrYWdlIG5vdCBmb3VuZCBpcyBhY2NlcHRhYmxlIGZvciBhIHYyIHByb3RvY29sIHJlcG9zaXRvcnkKICAgICAgICAgICAgaWYgKCRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0MDQpIHsKICAgICAgICAgICAgICAgICRyZXBvLT5wYWNrYWdlc05vdEZvdW5kQ2FjaGVbJGZpbGVuYW1lXSA9IHRydWU7CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCdwYWNrYWdlcycgPT4gYXJyYXkoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRqc29uID0gKHN0cmluZykgJHJlc3BvbnNlLT5nZXRCb2R5KCk7CiAgICAgICAgICAgIGlmICgkanNvbiA9PT0gJycgJiYgJHJlc3BvbnNlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDMwNCkgewogICAgICAgICAgICAgICAgJHJlcG8tPmZyZXNoTWV0YWRhdGFVcmxzWyRmaWxlbmFtZV0gPSB0cnVlOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGV2ZW50RGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgJHBvc3RGaWxlRG93bmxvYWRFdmVudCA9IG5ldyBQb3N0RmlsZURvd25sb2FkRXZlbnQoUGx1Z2luRXZlbnRzOjpQT1NUX0ZJTEVfRE9XTkxPQUQsIG51bGwsIG51bGwsICRmaWxlbmFtZSwgJ21ldGFkYXRhJywgYXJyYXkoJ3Jlc3BvbnNlJyA9PiAkcmVzcG9uc2UsICdyZXBvc2l0b3J5JyA9PiAkcmVwbykpOwogICAgICAgICAgICAgICAgJGV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2goJHBvc3RGaWxlRG93bmxvYWRFdmVudC0+Z2V0TmFtZSgpLCAkcG9zdEZpbGVEb3dubG9hZEV2ZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRhdGEgPSAkcmVzcG9uc2UtPmRlY29kZUpzb24oKTsKICAgICAgICAgICAgSHR0cERvd25sb2FkZXI6Om91dHB1dFdhcm5pbmdzKCRpbywgJHVybCwgJGRhdGEpOwoKICAgICAgICAgICAgJGxhc3RNb2RpZmllZERhdGUgPSAkcmVzcG9uc2UtPmdldEhlYWRlcignbGFzdC1tb2RpZmllZCcpOwogICAgICAgICAgICAkcmVzcG9uc2UtPmNvbGxlY3QoKTsKICAgICAgICAgICAgaWYgKCRsYXN0TW9kaWZpZWREYXRlKSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnbGFzdC1tb2RpZmllZCddID0gJGxhc3RNb2RpZmllZERhdGU7CiAgICAgICAgICAgICAgICAkanNvbiA9IEpzb25GaWxlOjplbmNvZGUoJGRhdGEsIEpzb25GaWxlOjpKU09OX1VORVNDQVBFRF9TTEFTSEVTIHwgSnNvbkZpbGU6OkpTT05fVU5FU0NBUEVEX1VOSUNPREUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGNhY2hlLT5pc1JlYWRPbmx5KCkpIHsKICAgICAgICAgICAgICAgICRjYWNoZS0+d3JpdGUoJGNhY2hlS2V5LCAkanNvbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlcG8tPmZyZXNoTWV0YWRhdGFVcmxzWyRmaWxlbmFtZV0gPSB0cnVlOwoKICAgICAgICAgICAgcmV0dXJuICRkYXRhOwogICAgICAgIH07CgogICAgICAgICRyZWplY3QgPSBmdW5jdGlvbiAoJGUpIHVzZSAoJGZpbGVuYW1lLCAkYWNjZXB0LCAkaW8sICR1cmwsICYkZGVncmFkZWRNb2RlLCAkcmVwbywgJGxhc3RNb2RpZmllZFRpbWUpIHsKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQwNCkgewogICAgICAgICAgICAgICAgJHJlcG8tPnBhY2thZ2VzTm90Rm91bmRDYWNoZVskZmlsZW5hbWVdID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGRlZ3JhZGVkTW9kZSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nLiR1cmwuJyBjb3VsZCBub3QgYmUgZnVsbHkgbG9hZGVkICgnLiRlLT5nZXRNZXNzYWdlKCkuJyksIHBhY2thZ2UgaW5mb3JtYXRpb24gd2FzIGxvYWRlZCBmcm9tIHRoZSBsb2NhbCBjYWNoZSBhbmQgbWF5IGJlIG91dCBvZiBkYXRlPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRkZWdyYWRlZE1vZGUgPSB0cnVlOwoKICAgICAgICAgICAgLy8gaWYgdGhlIGZpbGUgaXMgaW4gdGhlIGNhY2hlLCB3ZSBmYWtlIGEgMzA0IE5vdCBNb2RpZmllZCB0byBhbGxvdyB0aGUgcHJvY2VzcyB0byBjb250aW51ZQogICAgICAgICAgICBpZiAoJGxhc3RNb2RpZmllZFRpbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYWNjZXB0KG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAkdXJsKSwgMzA0LCBhcnJheSgpLCAnJykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBzcGVjaWFsIGVycm9yIGNvZGUgcmV0dXJuZWQgd2hlbiBuZXR3b3JrIGlzIGJlaW5nIGFydGlmaWNpYWxseSBkaXNhYmxlZAogICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJGUtPmdldFN0YXR1c0NvZGUoKSA9PT0gNDk5KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGFjY2VwdChuZXcgUmVzcG9uc2UoYXJyYXkoJ3VybCcgPT4gJHVybCksIDQwNCwgYXJyYXkoKSwgJycpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfTsKCiAgICAgICAgcmV0dXJuICRodHRwRG93bmxvYWRlci0+YWRkKCRmaWxlbmFtZSwgJG9wdGlvbnMpLT50aGVuKCRhY2NlcHQsICRyZWplY3QpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbml0aWFsaXplcyB0aGUgcGFja2FnZXMga2V5IG9mIGEgcGFydGlhbCBwYWNrYWdlcy5qc29uIHRoYXQgY29udGFpbiBzb21lIHBhY2thZ2VzIGlubGluZWQgKyBhIHByb3ZpZGVycy1sYXp5LXVybAogICAgICoKICAgICAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbml0aWFsaXplUGFydGlhbFBhY2thZ2VzKCkKICAgIHsKICAgICAgICAkcm9vdERhdGEgPSAkdGhpcy0+bG9hZFJvb3RTZXJ2ZXJGaWxlKCk7CgogICAgICAgICR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRyb290RGF0YVsncGFja2FnZXMnXSBhcyAkcGFja2FnZSA9PiAkdmVyc2lvbnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHZlcnNpb25zIGFzICR2ZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lW3N0cnRvbG93ZXIoJHZlcnNpb25bJ25hbWUnXSldW10gPSAkdmVyc2lvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gd2lwZSByb290RGF0YSBhcyBpdCBpcyBmdWxseSBjb25zdW1lZCBhdCB0aGlzIHBvaW50IGFuZCB0aGlzIHNhdmVzIHNvbWUgbWVtb3J5CiAgICAgICAgJHRoaXMtPnJvb3REYXRhID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgcGFja2FnZSBuYW1lIGlzIHByZXNlbnQgaW4gdGhpcyBsYXp5IHByb3ZpZGVycyByZXBvCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gYm9vbCAgIHRydWUgaWYgdGhlIHBhY2thZ2UgbmFtZSBpcyBwcmVzZW50IGluIGF2YWlsYWJsZVBhY2thZ2VzIG9yIG1hdGNoZWQgYnkgYXZhaWxhYmxlUGFja2FnZVBhdHRlcm5zCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBsYXp5UHJvdmlkZXJzUmVwb0NvbnRhaW5zKCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ2xhenlQcm92aWRlcnNSZXBvQ29udGFpbnMgc2hvdWxkIG5vdCBiZSBjYWxsZWQgdW5sZXNzIGhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0IGlzIHRydWUnKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc19hcnJheSgkdGhpcy0+YXZhaWxhYmxlUGFja2FnZXMpICYmIGlzc2V0KCR0aGlzLT5hdmFpbGFibGVQYWNrYWdlc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX2FycmF5KCR0aGlzLT5hdmFpbGFibGVQYWNrYWdlUGF0dGVybnMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hdmFpbGFibGVQYWNrYWdlUGF0dGVybnMgYXMgJHByb3ZpZGVyUmVnZXgpIHsKICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRwcm92aWRlclJlZ2V4LCAkbmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgovKioKICogTG9jayBhcnJheSByZXBvc2l0b3J5LgogKgogKiBSZWd1bGFyIGFycmF5IHJlcG9zaXRvcnksIG9ubHkgdXNlcyBhIGRpZmZlcmVudCB0eXBlIHRvIGlkZW50aWZ5IHRoZSBsb2NrIGZpbGUgYXMgdGhlIHNvdXJjZSBvZiBpbmZvCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBMb2NrQXJyYXlSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5CnsKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdsb2NrIHJlcG8nOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgovKioKICogSW5zdGFsbGVkIGFycmF5IHJlcG9zaXRvcnkuCiAqCiAqIFRoaXMgaXMgdXNlZCBhcyBhbiBpbi1tZW1vcnkgSW5zdGFsbGVkUmVwb3NpdG9yeSBtb3N0bHkgZm9yIHRlc3RpbmcgcHVycG9zZXMKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSW5zdGFsbGVkQXJyYXlSZXBvc2l0b3J5IGV4dGVuZHMgV3JpdGFibGVBcnJheVJlcG9zaXRvcnkgaW1wbGVtZW50cyBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdpbnN0YWxsZWQgJy5wYXJlbnQ6OmdldFJlcG9OYW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNGcmVzaCgpCiAgICB7CiAgICAgICAgLy8gdGhpcyBpcyBub3QgYSBjb21wbGV0ZWx5IGNvcnJlY3QgaW1wbGVtZW50YXRpb24gYnV0IHRoZXJlIGlzIG5vIHdheSB0bwogICAgICAgIC8vIGRpc3Rpbmd1aXNoIGFuIGVtcHR5IHJlcG8gYW5kIGEgbmV3bHkgY3JlYXRlZCBvbmUgZ2l2ZW4gdGhpcyBpcyBhbGwgaW4tbWVtb3J5CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb3VudCgpID09PSAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBSb290IHBhY2thZ2UgcmVwb3NpdG9yeS4KICoKICogVGhpcyBpcyB1c2VkIGZvciBzZXJ2aW5nIHRoZSBSb290UGFja2FnZSBpbnNpZGUgYW4gaW4tbWVtb3J5IEluc3RhbGxlZFJlcG9zaXRvcnkKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUm9vdFBhY2thZ2VSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5CnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSb290UGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KGFycmF5KCRwYWNrYWdlKSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9OYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3Jvb3QgcGFja2FnZSByZXBvJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcVmNzRHJpdmVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXFZhbGlkYXRpbmdBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXEludmFsaWRQYWNrYWdlRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcTG9hZGVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFZjc1JlcG9zaXRvcnkgZXh0ZW5kcyBBcnJheVJlcG9zaXRvcnkgaW1wbGVtZW50cyBDb25maWd1cmFibGVSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICR1cmw7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2VOYW1lOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRpc1ZlcmJvc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGlzVmVyeVZlcmJvc2U7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBWZXJzaW9uUGFyc2VyICovCiAgICBwcm90ZWN0ZWQgJHZlcnNpb25QYXJzZXI7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdHlwZTsKICAgIC8qKiBAdmFyID9Mb2FkZXJJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkbG9hZGVyOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBtaXhlZD4gKi8KICAgIHByb3RlY3RlZCAkcmVwb0NvbmZpZzsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcm90ZWN0ZWQgJHByb2Nlc3NFeGVjdXRvcjsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkYnJhbmNoRXJyb3JPY2N1cnJlZCA9IGZhbHNlOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBjbGFzcy1zdHJpbmc8VmNzRHJpdmVySW50ZXJmYWNlPj4gKi8KICAgIHByaXZhdGUgJGRyaXZlcnM7CiAgICAvKiogQHZhciA/VmNzRHJpdmVySW50ZXJmYWNlICovCiAgICBwcml2YXRlICRkcml2ZXI7CiAgICAvKiogQHZhciA/VmVyc2lvbkNhY2hlSW50ZXJmYWNlICovCiAgICBwcml2YXRlICR2ZXJzaW9uQ2FjaGU7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJpdmF0ZSAkZW1wdHlSZWZlcmVuY2VzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PCd0YWdzJ3wnYnJhbmNoZXMnLCBhcnJheTxzdHJpbmcsIFRyYW5zcG9ydEV4Y2VwdGlvbj4+ICovCiAgICBwcml2YXRlICR2ZXJzaW9uVHJhbnNwb3J0RXhjZXB0aW9ucyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl7dXJsOiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9JmFycmF5PHN0cmluZywgbWl4ZWQ+ICRyZXBvQ29uZmlnCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBjbGFzcy1zdHJpbmc8VmNzRHJpdmVySW50ZXJmYWNlPj58bnVsbCAkZHJpdmVycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJlcG9Db25maWcsIElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciwgRXZlbnREaXNwYXRjaGVyICRkaXNwYXRjaGVyID0gbnVsbCwgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCwgYXJyYXkgJGRyaXZlcnMgPSBudWxsLCBWZXJzaW9uQ2FjaGVJbnRlcmZhY2UgJHZlcnNpb25DYWNoZSA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgpOwogICAgICAgICR0aGlzLT5kcml2ZXJzID0gJGRyaXZlcnMgPzogYXJyYXkoCiAgICAgICAgICAgICdnaXRodWInID0+ICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1xHaXRIdWJEcml2ZXInLAogICAgICAgICAgICAnZ2l0bGFiJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcR2l0TGFiRHJpdmVyJywKICAgICAgICAgICAgJ2JpdGJ1Y2tldCcgPT4gJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEdpdEJpdGJ1Y2tldERyaXZlcicsCiAgICAgICAgICAgICdnaXQtYml0YnVja2V0JyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcR2l0Qml0YnVja2V0RHJpdmVyJywKICAgICAgICAgICAgJ2dpdCcgPT4gJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEdpdERyaXZlcicsCiAgICAgICAgICAgICdoZycgPT4gJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEhnRHJpdmVyJywKICAgICAgICAgICAgJ3BlcmZvcmNlJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcUGVyZm9yY2VEcml2ZXInLAogICAgICAgICAgICAnZm9zc2lsJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcRm9zc2lsRHJpdmVyJywKICAgICAgICAgICAgLy8gc3ZuIG11c3QgYmUgbGFzdCBiZWNhdXNlIGlkZW50aWZ5aW5nIGEgc3VidmVyc2lvbiBzZXJ2ZXIgZm9yIHN1cmUgaXMgcHJhY3RpY2FsbHkgaW1wb3NzaWJsZQogICAgICAgICAgICAnc3ZuJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcU3ZuRHJpdmVyJywKICAgICAgICApOwoKICAgICAgICAkdGhpcy0+dXJsID0gJHJlcG9Db25maWdbJ3VybCddOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+dHlwZSA9IGlzc2V0KCRyZXBvQ29uZmlnWyd0eXBlJ10pID8gJHJlcG9Db25maWdbJ3R5cGUnXSA6ICd2Y3MnOwogICAgICAgICR0aGlzLT5pc1ZlcmJvc2UgPSAkaW8tPmlzVmVyYm9zZSgpOwogICAgICAgICR0aGlzLT5pc1ZlcnlWZXJib3NlID0gJGlvLT5pc1ZlcnlWZXJib3NlKCk7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnJlcG9Db25maWcgPSAkcmVwb0NvbmZpZzsKICAgICAgICAkdGhpcy0+dmVyc2lvbkNhY2hlID0gJHZlcnNpb25DYWNoZTsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPnByb2Nlc3NFeGVjdXRvciA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgICRkcml2ZXJDbGFzcyA9IGdldF9jbGFzcygkdGhpcy0+Z2V0RHJpdmVyKCkpOwogICAgICAgICRkcml2ZXJUeXBlID0gYXJyYXlfc2VhcmNoKCRkcml2ZXJDbGFzcywgJHRoaXMtPmRyaXZlcnMpOwogICAgICAgIGlmICghJGRyaXZlclR5cGUpIHsKICAgICAgICAgICAgJGRyaXZlclR5cGUgPSAkZHJpdmVyQ2xhc3M7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ3ZjcyByZXBvICgnLiRkcml2ZXJUeXBlLicgJy5Vcmw6OnNhbml0aXplKCR0aGlzLT51cmwpLicpJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb0NvbmZpZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvQ29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2FkZXIoTG9hZGVySW50ZXJmYWNlICRsb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRlciA9ICRsb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFZjc0RyaXZlckludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREcml2ZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZHJpdmVyOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5kcml2ZXJzWyR0aGlzLT50eXBlXSkpIHsKICAgICAgICAgICAgJGNsYXNzID0gJHRoaXMtPmRyaXZlcnNbJHRoaXMtPnR5cGVdOwogICAgICAgICAgICAkdGhpcy0+ZHJpdmVyID0gbmV3ICRjbGFzcygkdGhpcy0+cmVwb0NvbmZpZywgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+aHR0cERvd25sb2FkZXIsICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IpOwogICAgICAgICAgICAkdGhpcy0+ZHJpdmVyLT5pbml0aWFsaXplKCk7CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRyaXZlcjsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5kcml2ZXJzIGFzICRkcml2ZXIpIHsKICAgICAgICAgICAgaWYgKCRkcml2ZXI6OnN1cHBvcnRzKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnVybCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5kcml2ZXIgPSBuZXcgJGRyaXZlcigkdGhpcy0+cmVwb0NvbmZpZywgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+aHR0cERvd25sb2FkZXIsICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IpOwogICAgICAgICAgICAgICAgJHRoaXMtPmRyaXZlci0+aW5pdGlhbGl6ZSgpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZHJpdmVyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZHJpdmVycyBhcyAkZHJpdmVyKSB7CiAgICAgICAgICAgIGlmICgkZHJpdmVyOjpzdXBwb3J0cygkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT51cmwsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZHJpdmVyID0gbmV3ICRkcml2ZXIoJHRoaXMtPnJlcG9Db25maWcsICR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPmh0dHBEb3dubG9hZGVyLCAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yKTsKICAgICAgICAgICAgICAgICR0aGlzLT5kcml2ZXItPmluaXRpYWxpemUoKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRyaXZlcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhZEludmFsaWRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5icmFuY2hFcnJvck9jY3VycmVkOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RW1wdHlSZWZlcmVuY2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVtcHR5UmVmZXJlbmNlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXk8J3RhZ3MnfCdicmFuY2hlcycsIGFycmF5PHN0cmluZywgVHJhbnNwb3J0RXhjZXB0aW9uPj4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcnNpb25UcmFuc3BvcnRFeGNlcHRpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb25UcmFuc3BvcnRFeGNlcHRpb25zOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBwYXJlbnQ6OmluaXRpYWxpemUoKTsKCiAgICAgICAgJGlzVmVyYm9zZSA9ICR0aGlzLT5pc1ZlcmJvc2U7CiAgICAgICAgJGlzVmVyeVZlcmJvc2UgPSAkdGhpcy0+aXNWZXJ5VmVyYm9zZTsKCiAgICAgICAgJGRyaXZlciA9ICR0aGlzLT5nZXREcml2ZXIoKTsKICAgICAgICBpZiAoISRkcml2ZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ05vIGRyaXZlciBmb3VuZCB0byBoYW5kbGUgVkNTIHJlcG9zaXRvcnkgJy4kdGhpcy0+dXJsKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgaWYgKCEkdGhpcy0+bG9hZGVyKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIoJHRoaXMtPnZlcnNpb25QYXJzZXIpOwogICAgICAgIH0KCiAgICAgICAgJGhhc1Jvb3RJZGVudGlmaWVyQ29tcG9zZXJKc29uID0gZmFsc2U7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGhhc1Jvb3RJZGVudGlmaWVyQ29tcG9zZXJKc29uID0gJGRyaXZlci0+aGFzQ29tcG9zZXJGaWxlKCRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCkpOwogICAgICAgICAgICBpZiAoJGhhc1Jvb3RJZGVudGlmaWVyQ29tcG9zZXJKc29uKSB7CiAgICAgICAgICAgICAgICAkZGF0YSA9ICRkcml2ZXItPmdldENvbXBvc2VySW5mb3JtYXRpb24oJGRyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGFja2FnZU5hbWUgPSAhZW1wdHkoJGRhdGFbJ25hbWUnXSkgPyAkZGF0YVsnbmFtZSddIDogbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICR0aGlzLT5zaG91bGRSZXRocm93VHJhbnNwb3J0RXhjZXB0aW9uKCRlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+U2tpcHBlZCBwYXJzaW5nICcuJGRyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKS4nLCAnLiRlLT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRkcml2ZXItPmdldFRhZ3MoKSBhcyAkdGFnID0+ICRpZGVudGlmaWVyKSB7CiAgICAgICAgICAgICR0YWcgPSAoc3RyaW5nKSAkdGFnOwogICAgICAgICAgICAkbXNnID0gJ1JlYWRpbmcgY29tcG9zZXIuanNvbiBvZiA8aW5mbz4nIC4gKCR0aGlzLT5wYWNrYWdlTmFtZSA/OiAkdGhpcy0+dXJsKSAuICc8L2luZm8+ICg8Y29tbWVudD4nIC4gJHRhZyAuICc8L2NvbW1lbnQ+KSc7CiAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtc2cpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGlzVmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5vdmVyd3JpdGVFcnJvcigkbXNnLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHN0cmlwIHRoZSByZWxlYXNlLSBwcmVmaXggZnJvbSB0YWdzIGlmIHByZXNlbnQKICAgICAgICAgICAgJHRhZyA9IHN0cl9yZXBsYWNlKCdyZWxlYXNlLScsICcnLCAkdGFnKTsKCiAgICAgICAgICAgICRjYWNoZWRQYWNrYWdlID0gJHRoaXMtPmdldENhY2hlZFBhY2thZ2VWZXJzaW9uKCR0YWcsICRpZGVudGlmaWVyLCAkaXNWZXJib3NlLCAkaXNWZXJ5VmVyYm9zZSk7CiAgICAgICAgICAgIGlmICgkY2FjaGVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJGNhY2hlZFBhY2thZ2UpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkY2FjaGVkUGFja2FnZSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lbXB0eVJlZmVyZW5jZXNbXSA9ICRpZGVudGlmaWVyOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRwYXJzZWRUYWcgPSAkdGhpcy0+dmFsaWRhdGVUYWcoJHRhZykpIHsKICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCB0YWcgJy4kdGFnLicsIGludmFsaWQgdGFnIG5hbWU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmICghJGRhdGEgPSAkZHJpdmVyLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgdGFnICcuJHRhZy4nLCBubyBjb21wb3NlciBmaWxlPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZW1wdHlSZWZlcmVuY2VzW10gPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBtYW51YWxseSB2ZXJzaW9uZWQgcGFja2FnZQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRkYXRhWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkZGF0YVsndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYXV0by12ZXJzaW9uZWQgcGFja2FnZSwgcmVhZCB2YWx1ZSBmcm9tIHRhZwogICAgICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uJ10gPSAkdGFnOwogICAgICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICRwYXJzZWRUYWc7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRhZyBwYWNrYWdlcyBoYXZlIG5vIC1kZXYgZmxhZwogICAgICAgICAgICAgICAgJGRhdGFbJ3ZlcnNpb24nXSA9IFByZWc6OnJlcGxhY2UoJ3tbLi1dP2RldiR9aScsICcnLCAkZGF0YVsndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9IFByZWc6OnJlcGxhY2UoJ3soXmRldi18Wy4tXT9kZXYkKX1pJywgJycsICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSk7CgogICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRhZyBkbyBub3QgY29udGFpbiB0aGUgZGVmYXVsdC1icmFuY2ggbWFya2VyCiAgICAgICAgICAgICAgICB1bnNldCgkZGF0YVsnZGVmYXVsdC1icmFuY2gnXSk7CgogICAgICAgICAgICAgICAgLy8gYnJva2VuIHBhY2thZ2UsIHZlcnNpb24gZG9lc24ndCBtYXRjaCB0YWcKICAgICAgICAgICAgICAgIGlmICgkZGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10gIT09ICRwYXJzZWRUYWcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3soXmRldi18Wy4tXT9kZXYkKX1pJywgJHBhcnNlZFRhZykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCB0YWcgJy4kdGFnLicsIGludmFsaWQgdGFnIG5hbWUsIHRhZ3MgY2FuIG5vdCB1c2UgZGV2IHByZWZpeGVzIG9yIHN1ZmZpeGVzPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Ta2lwcGVkIHRhZyAnLiR0YWcuJywgdGFnICgnLiRwYXJzZWRUYWcuJykgZG9lcyBub3QgbWF0Y2ggdmVyc2lvbiAoJy4kZGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10uJykgaW4gY29tcG9zZXIuanNvbjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGFnUGFja2FnZU5hbWUgPSAkdGhpcy0+cGFja2FnZU5hbWUgPzogKGlzc2V0KCRkYXRhWyduYW1lJ10pID8gJGRhdGFbJ25hbWUnXSA6ICcnKTsKICAgICAgICAgICAgICAgIGlmICgkZXhpc3RpbmdQYWNrYWdlID0gJHRoaXMtPmZpbmRQYWNrYWdlKCR0YWdQYWNrYWdlTmFtZSwgJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgdGFnICcuJHRhZy4nLCBpdCBjb25mbGljdHMgd2l0aCBhbiBhbm90aGVyIHRhZyAoJy4kZXhpc3RpbmdQYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkuJykgYXMgYm90aCByZXNvbHZlIHRvICcuJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddLicgaW50ZXJuYWxseTwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdJbXBvcnRpbmcgdGFnICcuJHRhZy4nICgnLiRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXS4nKScpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCR0aGlzLT5sb2FkZXItPmxvYWQoJHRoaXMtPnByZVByb2Nlc3MoJGRyaXZlciwgJGRhdGEsICRpZGVudGlmaWVyKSkpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dmVyc2lvblRyYW5zcG9ydEV4Y2VwdGlvbnNbJ3RhZ3MnXVskdGFnXSA9ICRlOwogICAgICAgICAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpID09PSA0MDQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVtcHR5UmVmZXJlbmNlc1tdID0gJGlkZW50aWZpZXI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkUmV0aHJvd1RyYW5zcG9ydEV4Y2VwdGlvbigkZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Ta2lwcGVkIHRhZyAnLiR0YWcuJywgJy4oJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gPyAnbm8gY29tcG9zZXIgZmlsZSB3YXMgZm91bmQgKCcgLiAkZS0+Z2V0Q29kZSgpIC4gJyBIVFRQIHN0YXR1cyBjb2RlKScgOiAkZS0+Z2V0TWVzc2FnZSgpKS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT5vdmVyd3JpdGVFcnJvcignJywgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgJGJyYW5jaGVzID0gJGRyaXZlci0+Z2V0QnJhbmNoZXMoKTsKICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHJvb3QgaWRlbnRpZmllciBicmFuY2ggZ2V0cyBsb2FkZWQgZmlyc3QKICAgICAgICBpZiAoJGhhc1Jvb3RJZGVudGlmaWVyQ29tcG9zZXJKc29uICYmIGlzc2V0KCRicmFuY2hlc1skZHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpXSkpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gYXJyYXkoJGRyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKSA9PiAkYnJhbmNoZXNbJGRyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKV0pICsgJGJyYW5jaGVzOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGJyYW5jaGVzIGFzICRicmFuY2ggPT4gJGlkZW50aWZpZXIpIHsKICAgICAgICAgICAgJGJyYW5jaCA9IChzdHJpbmcpICRicmFuY2g7CiAgICAgICAgICAgICRtc2cgPSAnUmVhZGluZyBjb21wb3Nlci5qc29uIG9mIDxpbmZvPicgLiAoJHRoaXMtPnBhY2thZ2VOYW1lID86ICR0aGlzLT51cmwpIC4gJzwvaW5mbz4gKDxjb21tZW50PicgLiAkYnJhbmNoIC4gJzwvY29tbWVudD4pJzsKICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJG1zZyk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkaXNWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPm92ZXJ3cml0ZUVycm9yKCRtc2csIGZhbHNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkcGFyc2VkQnJhbmNoID0gJHRoaXMtPnZhbGlkYXRlQnJhbmNoKCRicmFuY2gpKSB7CiAgICAgICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgYnJhbmNoICcuJGJyYW5jaC4nLCBpbnZhbGlkIG5hbWU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGJyYW5jaCBwYWNrYWdlcyBoYXZlIGEgZGV2IGZsYWcKICAgICAgICAgICAgaWYgKHN0cnBvcygkcGFyc2VkQnJhbmNoLCAnZGV2LScpID09PSAwIHx8IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTID09PSAkcGFyc2VkQnJhbmNoKSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICdkZXYtJyAuICRicmFuY2g7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcHJlZml4ID0gc3RycG9zKCRicmFuY2gsICd2JykgPT09IDAgPyAndicgOiAnJzsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHByZWZpeCAuIFByZWc6OnJlcGxhY2UoJ3soXC45ezd9KSt9JywgJy54JywgJHBhcnNlZEJyYW5jaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjYWNoZWRQYWNrYWdlID0gJHRoaXMtPmdldENhY2hlZFBhY2thZ2VWZXJzaW9uKCR2ZXJzaW9uLCAkaWRlbnRpZmllciwgJGlzVmVyYm9zZSwgJGlzVmVyeVZlcmJvc2UsICRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCkgPT09ICRicmFuY2gpOwogICAgICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRjYWNoZWRQYWNrYWdlKTsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZW1wdHlSZWZlcmVuY2VzW10gPSAkaWRlbnRpZmllcjsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmICghJGRhdGEgPSAkZHJpdmVyLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgYnJhbmNoICcuJGJyYW5jaC4nLCBubyBjb21wb3NlciBmaWxlPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZW1wdHlSZWZlcmVuY2VzW10gPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBicmFuY2hlcyBhcmUgYWx3YXlzIGF1dG8tdmVyc2lvbmVkLCByZWFkIHZhbHVlIGZyb20gYnJhbmNoIG5hbWUKICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uJ10gPSAkdmVyc2lvbjsKICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICRwYXJzZWRCcmFuY2g7CgogICAgICAgICAgICAgICAgdW5zZXQoJGRhdGFbJ2RlZmF1bHQtYnJhbmNoJ10pOwogICAgICAgICAgICAgICAgaWYgKCRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCkgPT09ICRicmFuY2gpIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YVsnZGVmYXVsdC1icmFuY2gnXSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdJbXBvcnRpbmcgYnJhbmNoICcuJGJyYW5jaC4nICgnLiRkYXRhWyd2ZXJzaW9uJ10uJyknKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcGFja2FnZURhdGEgPSAkdGhpcy0+cHJlUHJvY2VzcygkZHJpdmVyLCAkZGF0YSwgJGlkZW50aWZpZXIpOwogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+bG9hZGVyLT5sb2FkKCRwYWNrYWdlRGF0YSk7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmxvYWRlciBpbnN0YW5jZW9mIFZhbGlkYXRpbmdBcnJheUxvYWRlciAmJiAkdGhpcy0+bG9hZGVyLT5nZXRXYXJuaW5ncygpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYWNrYWdlRXhjZXB0aW9uKCR0aGlzLT5sb2FkZXItPmdldEVycm9ycygpLCAkdGhpcy0+bG9hZGVyLT5nZXRXYXJuaW5ncygpLCAkcGFja2FnZURhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT52ZXJzaW9uVHJhbnNwb3J0RXhjZXB0aW9uc1snYnJhbmNoZXMnXVskYnJhbmNoXSA9ICRlOwogICAgICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgPT09IDQwNCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lbXB0eVJlZmVyZW5jZXNbXSA9ICRpZGVudGlmaWVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRSZXRocm93VHJhbnNwb3J0RXhjZXB0aW9uKCRlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Ta2lwcGVkIGJyYW5jaCAnLiRicmFuY2guJywgbm8gY29tcG9zZXIgZmlsZSB3YXMgZm91bmQgKCcgLiAkZS0+Z2V0Q29kZSgpIC4gJyBIVFRQIHN0YXR1cyBjb2RlKTwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoISRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5icmFuY2hFcnJvck9jY3VycmVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPlNraXBwZWQgYnJhbmNoICcuJGJyYW5jaC4nLCAnLiRlLT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGRyaXZlci0+Y2xlYW51cCgpOwoKICAgICAgICBpZiAoISRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoJycsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmdldFBhY2thZ2VzKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRSZXBvc2l0b3J5RXhjZXB0aW9uKCdObyB2YWxpZCBjb21wb3Nlci5qc29uIHdhcyBmb3VuZCBpbiBhbnkgYnJhbmNoIG9yIHRhZyBvZiAnLiR0aGlzLT51cmwuJywgY291bGQgbm90IGxvYWQgYSBwYWNrYWdlIGZyb20gaXQuJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFZjc0RyaXZlckludGVyZmFjZSAkZHJpdmVyCiAgICAgKiBAcGFyYW0gYXJyYXl7bmFtZT86IHN0cmluZywgZGlzdD86IGFycmF5e3R5cGU6IHN0cmluZywgdXJsOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBzaGFzdW06IHN0cmluZ30sIHNvdXJjZT86IGFycmF5e3R5cGU6IHN0cmluZywgdXJsOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nfX0gJGRhdGEKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkZW50aWZpZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e25hbWU6IHN0cmluZ3xudWxsLCBkaXN0OiBhcnJheXt0eXBlOiBzdHJpbmcsIHVybDogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgc2hhc3VtOiBzdHJpbmd9fG51bGwsIHNvdXJjZTogYXJyYXl7dHlwZTogc3RyaW5nLCB1cmw6IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmd9fQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJlUHJvY2VzcyhWY3NEcml2ZXJJbnRlcmZhY2UgJGRyaXZlciwgYXJyYXkgJGRhdGEsICRpZGVudGlmaWVyKQogICAgewogICAgICAgIC8vIGtlZXAgdGhlIG5hbWUgb2YgdGhlIG1haW4gaWRlbnRpZmllciBmb3IgYWxsIHBhY2thZ2VzCiAgICAgICAgLy8gdGhpcyBlbnN1cmVzIHRoYXQgYSBwYWNrYWdlIGNhbiBiZSByZW5hbWVkIGluIG9uZSBwbGFjZSBhbmQgdGhhdCBhbGwgb2xkIHRhZ3MKICAgICAgICAvLyB3aWxsIHN0aWxsIGJlIGluc3RhbGxhYmxlIHVzaW5nIHRoYXQgbmV3IG5hbWUgd2l0aG91dCByZXF1aXJpbmcgcmUtdGFnZ2luZwogICAgICAgICRkYXRhUGFja2FnZU5hbWUgPSBpc3NldCgkZGF0YVsnbmFtZSddKSA/ICRkYXRhWyduYW1lJ10gOiBudWxsOwogICAgICAgICRkYXRhWyduYW1lJ10gPSAkdGhpcy0+cGFja2FnZU5hbWUgPzogJGRhdGFQYWNrYWdlTmFtZTsKCiAgICAgICAgaWYgKCFpc3NldCgkZGF0YVsnZGlzdCddKSkgewogICAgICAgICAgICAkZGF0YVsnZGlzdCddID0gJGRyaXZlci0+Z2V0RGlzdCgkaWRlbnRpZmllcik7CiAgICAgICAgfQogICAgICAgIGlmICghaXNzZXQoJGRhdGFbJ3NvdXJjZSddKSkgewogICAgICAgICAgICAkZGF0YVsnc291cmNlJ10gPSAkZHJpdmVyLT5nZXRTb3VyY2UoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkYXRhOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkYnJhbmNoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZUJyYW5jaCgkYnJhbmNoKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRub3JtYWxpemVkQnJhbmNoID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZUJyYW5jaCgkYnJhbmNoKTsKCiAgICAgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgdGhlIGJyYW5jaCBuYW1lIGhhcyBubyB3ZWlyZCBjaGFyYWN0ZXJzIGNvbmZsaWN0aW5nIHdpdGggY29uc3RyYWludHMKICAgICAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJG5vcm1hbGl6ZWRCcmFuY2gpOwoKICAgICAgICAgICAgcmV0dXJuICRub3JtYWxpemVkQnJhbmNoOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlVGFnKCR2ZXJzaW9uKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCR2ZXJzaW9uKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKiBAcGFyYW0gYm9vbCAkaXNWZXJib3NlCiAgICAgKiBAcGFyYW0gYm9vbCAkaXNWZXJ5VmVyYm9zZQogICAgICogQHBhcmFtIGJvb2wgJGlzRGVmYXVsdEJyYW5jaAogICAgICoKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlfFxDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlQWxpYXNQYWNrYWdlfG51bGx8ZmFsc2UgbnVsbCBpZiBubyBjYWNoZSBwcmVzZW50LCBmYWxzZSBpZiB0aGUgYWJzZW5jZSBvZiBhIHZlcnNpb24gd2FzIGNhY2hlZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENhY2hlZFBhY2thZ2VWZXJzaW9uKCR2ZXJzaW9uLCAkaWRlbnRpZmllciwgJGlzVmVyYm9zZSwgJGlzVmVyeVZlcmJvc2UsICRpc0RlZmF1bHRCcmFuY2ggPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52ZXJzaW9uQ2FjaGUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkY2FjaGVkUGFja2FnZSA9ICR0aGlzLT52ZXJzaW9uQ2FjaGUtPmdldFZlcnNpb25QYWNrYWdlKCR2ZXJzaW9uLCAkaWRlbnRpZmllcik7CiAgICAgICAgaWYgKCRjYWNoZWRQYWNrYWdlID09PSBmYWxzZSkgewogICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCAnLiR2ZXJzaW9uLicsIG5vIGNvbXBvc2VyIGZpbGUgKGNhY2hlZCBmcm9tIHJlZiAnLiRpZGVudGlmaWVyLicpPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgJG1zZyA9ICdGb3VuZCBjYWNoZWQgY29tcG9zZXIuanNvbiBvZiA8aW5mbz4nIC4gKCR0aGlzLT5wYWNrYWdlTmFtZSA/OiAkdGhpcy0+dXJsKSAuICc8L2luZm8+ICg8Y29tbWVudD4nIC4gJHZlcnNpb24gLiAnPC9jb21tZW50PiknOwogICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbXNnKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRpc1ZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoJG1zZywgZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB1bnNldCgkY2FjaGVkUGFja2FnZVsnZGVmYXVsdC1icmFuY2gnXSk7CiAgICAgICAgICAgIGlmICgkaXNEZWZhdWx0QnJhbmNoKSB7CiAgICAgICAgICAgICAgICAkY2FjaGVkUGFja2FnZVsnZGVmYXVsdC1icmFuY2gnXSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZXhpc3RpbmdQYWNrYWdlID0gJHRoaXMtPmZpbmRQYWNrYWdlKCRjYWNoZWRQYWNrYWdlWyduYW1lJ10sIG5ldyBDb25zdHJhaW50KCc9JywgJGNhY2hlZFBhY2thZ2VbJ3ZlcnNpb25fbm9ybWFsaXplZCddKSkpIHsKICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCBjYWNoZWQgdmVyc2lvbiAnLiR2ZXJzaW9uLicsIGl0IGNvbmZsaWN0cyB3aXRoIGFuIGFub3RoZXIgdGFnICgnLiRleGlzdGluZ1BhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKS4nKSBhcyBib3RoIHJlc29sdmUgdG8gJy4kY2FjaGVkUGFja2FnZVsndmVyc2lvbl9ub3JtYWxpemVkJ10uJyBpbnRlcm5hbGx5PC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNhY2hlZFBhY2thZ2UgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkZXItPmxvYWQoJGNhY2hlZFBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzaG91bGRSZXRocm93VHJhbnNwb3J0RXhjZXB0aW9uKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkKICAgIHsKICAgICAgICByZXR1cm4gaW5fYXJyYXkoJGUtPmdldENvZGUoKSwgYXJyYXkoNDAxLCA0MDMsIDQyOSksIHRydWUpIHx8ICRlLT5nZXRDb2RlKCkgPj0gNTAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZUFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxTdGFiaWxpdHlGaWx0ZXI7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKCi8qKgogKiBBIHJlcG9zaXRvcnkgaW1wbGVtZW50YXRpb24gdGhhdCBzaW1wbHkgc3RvcmVzIHBhY2thZ2VzIGluIGFuIGFycmF5CiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBBcnJheVJlcG9zaXRvcnkgaW1wbGVtZW50cyBSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyID9hcnJheTxCYXNlUGFja2FnZT4gKi8KICAgIHByb3RlY3RlZCAkcGFja2FnZXMgPSBudWxsOwoKICAgIC8qKgogICAgICogQHZhciA/YXJyYXk8QmFzZVBhY2thZ2U+IGluZGV4ZWQgYnkgcGFja2FnZSB1bmlxdWUgbmFtZSBhbmQgdXNlZCB0byBjYWNoZSBoYXNQYWNrYWdlIGNhbGxzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcGFja2FnZU1hcCA9IG51bGw7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8UGFja2FnZUludGVyZmFjZT4gJHBhY2thZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcGFja2FnZXMgPSBhcnJheSgpKQogICAgewogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdhcnJheSByZXBvIChkZWZpbmluZyAnLiR0aGlzLT5jb3VudCgpLicgcGFja2FnZScuKCR0aGlzLT5jb3VudCgpID4gMSA/ICdzJyA6ICcnKS4nKSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+Z2V0UGFja2FnZXMoKTsKCiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgJG5hbWVzRm91bmQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcGFja2FnZU1hcCkpIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAoISRwYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldIHx8ICRwYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldLT5tYXRjaGVzKG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSkKICAgICAgICAgICAgICAgICAgICAmJiBTdGFiaWxpdHlGaWx0ZXI6OmlzUGFja2FnZUFjY2VwdGFibGUoJGFjY2VwdGFibGVTdGFiaWxpdGllcywgJHN0YWJpbGl0eUZsYWdzLCAkcGFja2FnZS0+Z2V0TmFtZXMoKSwgJHBhY2thZ2UtPmdldFN0YWJpbGl0eSgpKQogICAgICAgICAgICAgICAgICAgICYmICFpc3NldCgkYWxyZWFkeUxvYWRlZFskcGFja2FnZS0+Z2V0TmFtZSgpXVskcGFja2FnZS0+Z2V0VmVyc2lvbigpXSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIC8vIGFkZCBzZWxlY3RlZCBwYWNrYWdlcyB3aGljaCBtYXRjaCBzdGFiaWxpdHkgcmVxdWlyZW1lbnRzCiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgYWxpYXNlZCBwYWNrYWdlIGZvciBwYWNrYWdlcyB3aGVyZSB0aGUgYWxpYXMgbWF0Y2hlcwogICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAhaXNzZXQoJHJlc3VsdFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UtPmdldEFsaWFzT2YoKSldKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZS0+Z2V0QWxpYXNPZigpKV0gPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbmFtZXNGb3VuZFskcGFja2FnZS0+Z2V0TmFtZSgpXSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGFkZCBhbGlhc2VzIG9mIHBhY2thZ2VzIHRoYXQgd2VyZSBzZWxlY3RlZCwgZXZlbiBpZiB0aGUgYWxpYXNlcyBkaWQgbm90IG1hdGNoCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXN1bHRbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgnbmFtZXNGb3VuZCcgPT4gYXJyYXlfa2V5cygkbmFtZXNGb3VuZCksICdwYWNrYWdlcycgPT4gJHJlc3VsdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KQogICAgewogICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CgogICAgICAgIGlmICghJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBDb25zdHJhaW50SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJG5hbWUgPT09ICRwYWNrYWdlLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICRwa2dDb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz09JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQtPm1hdGNoZXMoJHBrZ0NvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBub3JtYWxpemUgbmFtZQogICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKG51bGwgIT09ICRjb25zdHJhaW50ICYmICEkY29uc3RyYWludCBpbnN0YW5jZW9mIENvbnN0cmFpbnRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICAgICAkY29uc3RyYWludCA9ICR2ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkbmFtZSA9PT0gJHBhY2thZ2UtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICRjb25zdHJhaW50IHx8ICRjb25zdHJhaW50LT5tYXRjaGVzKG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCRxdWVyeSwgJG1vZGUgPSAwLCAkdHlwZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRtb2RlID09PSBzZWxmOjpTRUFSQ0hfRlVMTFRFWFQpIHsKICAgICAgICAgICAgJHJlZ2V4ID0gJ3soPzonLmltcGxvZGUoJ3wnLCBQcmVnOjpzcGxpdCgne1xzK30nLCBwcmVnX3F1b3RlKCRxdWVyeSkpKS4nKX1pJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyB2ZW5kb3IvbmFtZSBzZWFyY2hlcyBleHBlY3QgdGhlIGNhbGxlciB0byBoYXZlIHByZWdfcXVvdGVkIHRoZSBxdWVyeQogICAgICAgICAgICAkcmVnZXggPSAneyg/OicuaW1wbG9kZSgnfCcsIFByZWc6OnNwbGl0KCd7XHMrfScsICRxdWVyeSkpLicpfWknOwogICAgICAgIH0KCiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgaWYgKCRtb2RlID09PSBzZWxmOjpTRUFSQ0hfVkVORE9SKSB7CiAgICAgICAgICAgICAgICBsaXN0KCRuYW1lKSA9IGV4cGxvZGUoJy8nLCAkbmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChudWxsICE9PSAkdHlwZSAmJiAkcGFja2FnZS0+Z2V0VHlwZSgpICE9PSAkdHlwZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRyZWdleCwgJG5hbWUpCiAgICAgICAgICAgICAgICB8fCAoJG1vZGUgPT09IHNlbGY6OlNFQVJDSF9GVUxMVEVYVCAmJiAkcGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAmJiBQcmVnOjppc01hdGNoKCRyZWdleCwgaW1wbG9kZSgnICcsIChhcnJheSkgJHBhY2thZ2UtPmdldEtleXdvcmRzKCkpIC4gJyAnIC4gJHBhY2thZ2UtPmdldERlc2NyaXB0aW9uKCkpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICgkbW9kZSA9PT0gc2VsZjo6U0VBUkNIX1ZFTkRPUikgewogICAgICAgICAgICAgICAgICAgICRtYXRjaGVzWyRuYW1lXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gbnVsbCwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1skbmFtZV0gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgPyAkcGFja2FnZS0+Z2V0RGVzY3JpcHRpb24oKSA6IG51bGwsCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICRwYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVzWyRuYW1lXVsnYWJhbmRvbmVkJ10gPSAkcGFja2FnZS0+Z2V0UmVwbGFjZW1lbnRQYWNrYWdlKCkgPzogdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheV92YWx1ZXMoJG1hdGNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1BhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnBhY2thZ2VNYXAgPT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2VNYXAgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAkcmVwb1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlTWFwWyRyZXBvUGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpXSA9ICRyZXBvUGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5wYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXRVbmlxdWVOYW1lKCldKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBuZXcgcGFja2FnZSB0byB0aGUgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBCYXNlUGFja2FnZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignT25seSBzdWJjbGFzc2VzIG9mIEJhc2VQYWNrYWdlIGFyZSBzdXBwb3J0ZWQnKTsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5wYWNrYWdlcykgewogICAgICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwogICAgICAgIH0KICAgICAgICAkcGFja2FnZS0+c2V0UmVwb3NpdG9yeSgkdGhpcyk7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzW10gPSAkcGFja2FnZTsKCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRhbGlhc2VkUGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkYWxpYXNlZFBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJGFsaWFzZWRQYWNrYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaW52YWxpZGF0ZSBwYWNrYWdlIG1hcCBjYWNoZQogICAgICAgICR0aGlzLT5wYWNrYWdlTWFwID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkcmVzdWx0WyRjYW5kaWRhdGUtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkY2FuZGlkYXRlLT5nZXRQcm92aWRlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2VOYW1lID09PSAkbGluay0+Z2V0VGFyZ2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WyRjYW5kaWRhdGUtPmdldE5hbWUoKV0gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+ICRjYW5kaWRhdGUtPmdldE5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ2Rlc2NyaXB0aW9uJyA9PiAkY2FuZGlkYXRlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlID8gJGNhbmRpZGF0ZS0+Z2V0RGVzY3JpcHRpb24oKSA6IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkY2FuZGlkYXRlLT5nZXRUeXBlKCksCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFsaWFzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcmV0dHlBbGlhcwogICAgICoKICAgICAqIEByZXR1cm4gQWxpYXNQYWNrYWdlfENvbXBsZXRlQWxpYXNQYWNrYWdlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVBbGlhc1BhY2thZ2UoQmFzZVBhY2thZ2UgJHBhY2thZ2UsICRhbGlhcywgJHByZXR0eUFsaWFzKQogICAgewogICAgICAgIHdoaWxlICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV0ZUFsaWFzUGFja2FnZSgkcGFja2FnZSwgJGFsaWFzLCAkcHJldHR5QWxpYXMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBBbGlhc1BhY2thZ2UoJHBhY2thZ2UsICRhbGlhcywgJHByZXR0eUFsaWFzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgcGFja2FnZSBmcm9tIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSAkcGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAka2V5ID0+ICRyZXBvUGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2VJZCA9PT0gJHJlcG9QYWNrYWdlLT5nZXRVbmlxdWVOYW1lKCkpIHsKICAgICAgICAgICAgICAgIGFycmF5X3NwbGljZSgkdGhpcy0+cGFja2FnZXMsICRrZXksIDEpOwoKICAgICAgICAgICAgICAgIC8vIGludmFsaWRhdGUgcGFja2FnZSBtYXAgY2FjaGUKICAgICAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlTWFwID0gbnVsbDsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cGFja2FnZXMpIHsKICAgICAgICAgICAgJHRoaXMtPmluaXRpYWxpemUoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cGFja2FnZXMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignaW5pdGlhbGl6ZSBmYWlsZWQgdG8gaW5pdGlhbGl6ZSB0aGUgcGFja2FnZXMgYXJyYXknKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcGFja2FnZXMgaW4gdGhpcyByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHJldHVybiBpbnQgTnVtYmVyIG9mIHBhY2thZ2VzCiAgICAgKi8KICAgICNbXFJldHVyblR5cGVXaWxsQ2hhbmdlXQogICAgcHVibGljIGZ1bmN0aW9uIGNvdW50KCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnBhY2thZ2VzKSB7CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPnBhY2thZ2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBwYWNrYWdlcyBhcnJheS4gTW9zdGx5IG1lYW50IGFzIGFuIGV4dGVuc2lvbiBwb2ludC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgICR0aGlzLT5wYWNrYWdlcyA9IGFycmF5KCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE1hdGNoQWxsQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CgovKioKICogSW5zdGFsbGVkIHJlcG9zaXRvcnkgaXMgYSBjb21wb3NpdGUgb2YgYWxsIGluc3RhbGxlZCByZXBvIHR5cGVzLgogKgogKiBUaGUgbWFpbiB1c2UgY2FzZSBpcyB0YWdnaW5nIGEgcmVwbyBhcyBhbiAiaW5zdGFsbGVkIiByZXBvc2l0b3J5LCBhbmQgb2ZmZXJpbmcgYSB3YXkgdG8gZ2V0IHByb3ZpZGVycy9yZXBsYWNlcnMgZWFzaWx5LgogKgogKiBJbnN0YWxsZWQgcmVwb3MgYXJlIExvY2tBcnJheVJlcG9zaXRvcnksIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UsIFJvb3RQYWNrYWdlUmVwb3NpdG9yeSBhbmQgUGxhdGZvcm1SZXBvc2l0b3J5CiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEluc3RhbGxlZFJlcG9zaXRvcnkgZXh0ZW5kcyBDb21wb3NpdGVSZXBvc2l0b3J5CnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2V8c3RyaW5nfG51bGwgJGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJG5hbWUpOwoKICAgICAgICBpZiAobnVsbCAhPT0gJGNvbnN0cmFpbnQgJiYgISRjb25zdHJhaW50IGluc3RhbmNlb2YgQ29uc3RyYWludEludGVyZmFjZSkgewogICAgICAgICAgICAkdmVyc2lvblBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgICAgICRjb25zdHJhaW50ID0gJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRSZXBvc2l0b3JpZXMoKSBhcyAkcmVwbykgewogICAgICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICBpZiAoJG5hbWUgPT09ICRjYW5kaWRhdGUtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChudWxsID09PSAkY29uc3RyYWludCB8fCAkY29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkY2FuZGlkYXRlLT5nZXRWZXJzaW9uKCkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tdID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoJGNhbmRpZGF0ZS0+Z2V0UHJvdmlkZXMoKSwgJGNhbmRpZGF0ZS0+Z2V0UmVwbGFjZXMoKSkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICRuYW1lID09PSAkbGluay0+Z2V0VGFyZ2V0KCkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKCRjb25zdHJhaW50ID09PSBudWxsIHx8ICRjb25zdHJhaW50LT5tYXRjaGVzKCRsaW5rLT5nZXRDb25zdHJhaW50KCkpKQogICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tdID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWF0Y2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGxpbmtzIGNhdXNpbmcgdGhlIHJlcXVlc3RlZCBuZWVkbGUgcGFja2FnZXMgdG8gYmUgaW5zdGFsbGVkLCBhcyBhbiBhc3NvY2lhdGl2ZSBhcnJheSB3aXRoIHRoZQogICAgICogZGVwZW5kZW50J3MgbmFtZSBhcyBrZXksIGFuZCBhbiBhcnJheSBjb250YWluaW5nIGluIG9yZGVyIHRoZSBQYWNrYWdlSW50ZXJmYWNlIGFuZCBMaW5rIGRlc2NyaWJpbmcgdGhlIHJlbGF0aW9uc2hpcAogICAgICogYXMgdmFsdWVzLiBJZiByZWN1cnNpdmUgbG9va3VwIHdhcyByZXF1ZXN0ZWQgYSB0aGlyZCB2YWx1ZSBpcyByZXR1cm5lZCBjb250YWluaW5nIGFuIGlkZW50aWNhbGx5IGZvcm1lZCBhcnJheSB1cAogICAgICogdG8gdGhlIHJvb3QgcGFja2FnZS4gVGhhdCB0aGlyZCB2YWx1ZSB3aWxsIGJlIGZhbHNlIGluIGNhc2UgYSBjaXJjdWxhciByZWN1cnNpb24gd2FzIGRldGVjdGVkLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nfHN0cmluZ1tdICAgICAgICAgICRuZWVkbGUgICAgICAgIFRoZSBwYWNrYWdlIG5hbWUocykgdG8gaW5zcGVjdC4KICAgICAqIEBwYXJhbSAgQ29uc3RyYWludEludGVyZmFjZXxudWxsICRjb25zdHJhaW50ICAgIE9wdGlvbmFsIGNvbnN0cmFpbnQgdG8gZmlsdGVyIGJ5LgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgJGludmVydCAgICAgICAgV2hldGhlciB0byBpbnZlcnQgbWF0Y2hlcyB0byBkaXNjb3ZlciByZWFzb25zIGZvciB0aGUgcGFja2FnZSAqTk9UKiB0byBiZSBpbnN0YWxsZWQuCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAkcmVjdXJzZSAgICAgICBXaGV0aGVyIHRvIHJlY3Vyc2l2ZWx5IGV4cGFuZCB0aGUgcmVxdWlyZW1lbnQgdHJlZSB1cCB0byB0aGUgcm9vdCBwYWNrYWdlLgogICAgICogQHBhcmFtICBzdHJpbmdbXSAgICAgICAgICAgICAgICAgJHBhY2thZ2VzRm91bmQgVXNlZCBpbnRlcm5hbGx5IHdoZW4gcmVjdXJyaW5nCiAgICAgKgogICAgICogQHJldHVybiBhcnJheVtdIEFuIGFzc29jaWF0aXZlIGFycmF5IG9mIGFycmF5cyBhcyBkZXNjcmliZWQgYWJvdmUuCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8YXJyYXl7MDogUGFja2FnZUludGVyZmFjZSwgMTogTGluaywgMjogbWl4ZWRbXXxib29sfT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlcGVuZGVudHMoJG5lZWRsZSwgJGNvbnN0cmFpbnQgPSBudWxsLCAkaW52ZXJ0ID0gZmFsc2UsICRyZWN1cnNlID0gdHJ1ZSwgJHBhY2thZ2VzRm91bmQgPSBudWxsKQogICAgewogICAgICAgICRuZWVkbGVzID0gYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgKGFycmF5KSAkbmVlZGxlKTsKICAgICAgICAkcmVzdWx0cyA9IGFycmF5KCk7CgogICAgICAgIC8vIGluaXRpYWxpemUgdGhlIGFycmF5IHdpdGggdGhlIG5lZWRsZXMgYmVmb3JlIGFueSByZWN1cnNpb24gb2NjdXJzCiAgICAgICAgaWYgKG51bGwgPT09ICRwYWNrYWdlc0ZvdW5kKSB7CiAgICAgICAgICAgICRwYWNrYWdlc0ZvdW5kID0gJG5lZWRsZXM7CiAgICAgICAgfQoKICAgICAgICAvLyBsb2NhdGUgcm9vdCBwYWNrYWdlIGZvciB1c2UgYmVsb3cKICAgICAgICAkcm9vdFBhY2thZ2UgPSBudWxsOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkcm9vdFBhY2thZ2UgPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBMb29wIG92ZXIgYWxsIGN1cnJlbnRseSBpbnN0YWxsZWQgcGFja2FnZXMuCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGxpbmtzID0gJHBhY2thZ2UtPmdldFJlcXVpcmVzKCk7CgogICAgICAgICAgICAvLyBlYWNoIGxvb3AgbmVlZHMgaXRzIG93biAidHJlZSIgYXMgd2Ugd2FudCB0byBzaG93IHRoZSBjb21wbGV0ZSBkZXBlbmRlbnQgc2V0IG9mIGV2ZXJ5IG5lZWRsZQogICAgICAgICAgICAvLyB3aXRob3V0IHdhcm5pbmcgYWxsIHRoZSB0aW1lIGFib3V0IGZpbmRpbmcgY2lyY3VsYXIgZGVwcwogICAgICAgICAgICAkcGFja2FnZXNJblRyZWUgPSAkcGFja2FnZXNGb3VuZDsKCiAgICAgICAgICAgIC8vIFJlcGxhY2VtZW50cyBhcmUgY29uc2lkZXJlZCB2YWxpZCByZWFzb25zIGZvciBhIHBhY2thZ2UgdG8gYmUgaW5zdGFsbGVkIGR1cmluZyBmb3J3YXJkIHJlc29sdXRpb24KICAgICAgICAgICAgaWYgKCEkaW52ZXJ0KSB7CiAgICAgICAgICAgICAgICAkbGlua3MgKz0gJHBhY2thZ2UtPmdldFJlcGxhY2VzKCk7CgogICAgICAgICAgICAgICAgLy8gT24gZm9yd2FyZCBzZWFyY2gsIGNoZWNrIGlmIGFueSByZXBsYWNlZCBwYWNrYWdlIHdhcyByZXF1aXJlZCBhbmQgYWRkIHRoZSByZXBsYWNlZAogICAgICAgICAgICAgICAgLy8gcGFja2FnZXMgdG8gdGhlIGxpc3Qgb2YgbmVlZGxlcy4gQ29udHJhcnkgdG8gdGhlIGNyb3NzLXJlZmVyZW5jZSBsaW5rIGNoZWNrIGJlbG93LAogICAgICAgICAgICAgICAgLy8gcmVwbGFjZWQgcGFja2FnZXMgYXJlIHRoZSB0YXJnZXQgb2YgbGlua3MuCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRuZWVkbGVzIGFzICRuZWVkbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsaW5rLT5nZXRTb3VyY2UoKSA9PT0gJG5lZWRsZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50ID09PSBudWxsIHx8ICgkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCRjb25zdHJhaW50KSA9PT0gdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IGRpc3BsYXllZCB0aGlzIG5vZGUncyBkZXBlbmRlbmNpZXMsIGN1dHRpbmcgc2hvcnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGxpbmstPmdldFRhcmdldCgpLCAkcGFja2FnZXNJblRyZWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZVtdID0gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZXBlbmRlbnRzID0gJHJlY3Vyc2UgPyAkdGhpcy0+Z2V0RGVwZW5kZW50cygkbGluay0+Z2V0VGFyZ2V0KCksIG51bGwsIGZhbHNlLCB0cnVlLCAkcGFja2FnZXNJblRyZWUpIDogYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoJHBhY2thZ2UsICRsaW5rLCAkZGVwZW5kZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5lZWRsZXNbXSA9ICRsaW5rLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUmVxdWlyZS1kZXYgaXMgb25seSByZWxldmFudCBmb3IgdGhlIHJvb3QgcGFja2FnZQogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJGxpbmtzICs9ICRwYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDcm9zcy1yZWZlcmVuY2UgYWxsIGRpc2NvdmVyZWQgbGlua3MgdG8gdGhlIG5lZWRsZXMKICAgICAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbmVlZGxlcyBhcyAkbmVlZGxlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRsaW5rLT5nZXRUYXJnZXQoKSA9PT0gJG5lZWRsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgKCRsaW5rLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMoJGNvbnN0cmFpbnQpID09PSAhJGludmVydCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgZGlzcGxheWVkIHRoaXMgbm9kZSdzIGRlcGVuZGVuY2llcywgY3V0dGluZyBzaG9ydAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRsaW5rLT5nZXRTb3VyY2UoKSwgJHBhY2thZ2VzSW5UcmVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZVtdID0gJGxpbmstPmdldFNvdXJjZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlcGVuZGVudHMgPSAkcmVjdXJzZSA/ICR0aGlzLT5nZXREZXBlbmRlbnRzKCRsaW5rLT5nZXRTb3VyY2UoKSwgbnVsbCwgZmFsc2UsIHRydWUsICRwYWNrYWdlc0luVHJlZSkgOiBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRwYWNrYWdlLCAkbGluaywgJGRlcGVuZGVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBXaGVuIGludmVydGluZywgd2UgbmVlZCB0byBjaGVjayBmb3IgY29uZmxpY3RzIG9mIHRoZSBuZWVkbGVzIGFnYWluc3QgaW5zdGFsbGVkIHBhY2thZ2VzCiAgICAgICAgICAgIGlmICgkaW52ZXJ0ICYmIGluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRuZWVkbGVzKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldENvbmZsaWN0cygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbmRQYWNrYWdlcygkbGluay0+Z2V0VGFyZ2V0KCkpIGFzICRwa2cpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSBuZXcgQ29uc3RyYWludCgnPScsICRwa2ctPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCR2ZXJzaW9uKSA9PT0gJGludmVydCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRwYWNrYWdlLCAkbGluaywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBMaXN0IGNvbmZsaWN0cyBhZ2FpbnN0IFggYXMgdGhleSBtYXkgZXhwbGFpbiB3aHkgdGhlIGN1cnJlbnQgdmVyc2lvbiB3YXMgc2VsZWN0ZWQsIG9yIGV4cGxhaW4gd2h5IGl0IGlzIHJlamVjdGVkIGlmIHRoZSBjb25mbGljdCBtYXRjaGVkIHdoZW4gaW52ZXJ0aW5nCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRDb25mbGljdHMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRsaW5rLT5nZXRUYXJnZXQoKSwgJG5lZWRsZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbmRQYWNrYWdlcygkbGluay0+Z2V0VGFyZ2V0KCkpIGFzICRwa2cpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSBuZXcgQ29uc3RyYWludCgnPScsICRwa2ctPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCR2ZXJzaW9uKSA9PT0gJGludmVydCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRwYWNrYWdlLCAkbGluaywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBXaGVuIGludmVydGluZywgd2UgbmVlZCB0byBjaGVjayBmb3IgY29uZmxpY3RzIG9mIHRoZSBuZWVkbGVzJyByZXF1aXJlbWVudHMgYWdhaW5zdCBpbnN0YWxsZWQgcGFja2FnZXMKICAgICAgICAgICAgaWYgKCRpbnZlcnQgJiYgJGNvbnN0cmFpbnQgJiYgaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJG5lZWRsZXMpICYmICRjb25zdHJhaW50LT5tYXRjaGVzKG5ldyBDb25zdHJhaW50KCc9JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSkpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRsaW5rLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5maW5kUGFja2FnZSgkbGluay0+Z2V0VGFyZ2V0KCksICRsaW5rLT5nZXRDb25zdHJhaW50KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJHBsYXRmb3JtUGtnID0gJHRoaXMtPmZpbmRQYWNrYWdlKCRsaW5rLT5nZXRUYXJnZXQoKSwgJyonKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJHBsYXRmb3JtUGtnID8gJ2J1dCAnLiRwbGF0Zm9ybVBrZy0+Z2V0UHJldHR5VmVyc2lvbigpLicgaXMgaW5zdGFsbGVkJyA6ICdidXQgaXQgaXMgbWlzc2luZyc7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgbmV3IExpbmsoJHBhY2thZ2UtPmdldE5hbWUoKSwgJGxpbmstPmdldFRhcmdldCgpLCBuZXcgTWF0Y2hBbGxDb25zdHJhaW50LCBMaW5rOjpUWVBFX1JFUVVJUkUsICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkuJyAnLiRkZXNjcmlwdGlvbiksIGZhbHNlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBhY2thZ2VzKCkgYXMgJHBrZykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCRsaW5rLT5nZXRUYXJnZXQoKSwgJHBrZy0+Z2V0TmFtZXMoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiA9IG5ldyBDb25zdHJhaW50KCc9JywgJHBrZy0+Z2V0VmVyc2lvbigpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0VGFyZ2V0KCkgIT09ICRwa2ctPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoJHBrZy0+Z2V0UmVwbGFjZXMoKSwgJHBrZy0+Z2V0UHJvdmlkZXMoKSkgYXMgJHByb3YpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFRhcmdldCgpID09PSAkcHJvdi0+Z2V0VGFyZ2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkcHJvdi0+Z2V0Q29uc3RyYWludCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJGxpbmstPmdldENvbnN0cmFpbnQoKS0+bWF0Y2hlcygkdmVyc2lvbikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlIGhhdmUgYSByb290IHBhY2thZ2UgKHdlIHNob3VsZCBidXQgY2FuIG5vdCBndWFyYW50ZWUuLikgd2Ugc2hvdwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHJvb3QgcmVxdWlyZXMgYXMgd2VsbCB0byBwZXJoYXBzIGFsbG93IHRvIGZpbmQgYW4gaXNzdWUgdGhlcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcm9vdFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkcm9vdFBhY2thZ2UtPmdldFJlcXVpcmVzKCksICRyb290UGFja2FnZS0+Z2V0RGV2UmVxdWlyZXMoKSkgYXMgJHJvb3RSZXEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRyb290UmVxLT5nZXRUYXJnZXQoKSwgJHBrZy0+Z2V0TmFtZXMoKSkgJiYgISRyb290UmVxLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMoJGxpbmstPmdldENvbnN0cmFpbnQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcm9vdFBhY2thZ2UsICRyb290UmVxLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoJHBhY2thZ2UsICRsaW5rLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRyb290UGFja2FnZSwgbmV3IExpbmsoJHJvb3RQYWNrYWdlLT5nZXROYW1lKCksICRsaW5rLT5nZXRUYXJnZXQoKSwgbmV3IE1hdGNoQWxsQ29uc3RyYWludCwgTGluazo6VFlQRV9ET0VTX05PVF9SRVFVSVJFLCAnYnV0ICcgLiAkcGtnLT5nZXRQcmV0dHlWZXJzaW9uKCkgLiAnIGlzIGluc3RhbGxlZCcpLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vIHJvb3Qgc28gbGV0J3MganVzdCBwcmludCB3aGF0ZXZlciB3ZSBmb3VuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGtzb3J0KCRyZXN1bHRzKTsKCiAgICAgICAgcmV0dXJuICRyZXN1bHRzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdpbnN0YWxsZWQgcmVwbyAoJy5pbXBsb2RlKCcsICcsIGFycmF5X21hcChmdW5jdGlvbiAoJHJlcG8pIHsKICAgICAgICAgICAgcmV0dXJuICRyZXBvLT5nZXRSZXBvTmFtZSgpOwogICAgICAgIH0sICR0aGlzLT5nZXRSZXBvc2l0b3JpZXMoKSkpLicpJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgaWYgKAogICAgICAgICAgICAkcmVwb3NpdG9yeSBpbnN0YW5jZW9mIExvY2tBcnJheVJlcG9zaXRvcnkKICAgICAgICAgICAgfHwgJHJlcG9zaXRvcnkgaW5zdGFuY2VvZiBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlCiAgICAgICAgICAgIHx8ICRyZXBvc2l0b3J5IGluc3RhbmNlb2YgUm9vdFBhY2thZ2VSZXBvc2l0b3J5CiAgICAgICAgICAgIHx8ICRyZXBvc2l0b3J5IGluc3RhbmNlb2YgUGxhdGZvcm1SZXBvc2l0b3J5CiAgICAgICAgKSB7CiAgICAgICAgICAgIHBhcmVudDo6YWRkUmVwb3NpdG9yeSgkcmVwb3NpdG9yeSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdBbiBJbnN0YWxsZWRSZXBvc2l0b3J5IGNhbiBub3QgY29udGFpbiBhIHJlcG9zaXRvcnkgb2YgdHlwZSAnLmdldF9jbGFzcygkcmVwb3NpdG9yeSkuJyAoJy4kcmVwb3NpdG9yeS0+Z2V0UmVwb05hbWUoKS4nKScpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgovKioKICogQ29uZmlndXJhYmxlIHJlcG9zaXRvcnkgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEx1a2FzIEhvbXphIDxsdWthc2hvbXpAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIENvbmZpZ3VyYWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIG1peGVkW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9Db25maWcoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogRmlsdGVycyB3aGljaCBwYWNrYWdlcyBhcmUgc2VlbiBhcyBjYW5vbmljYWwgb24gdGhpcyByZXBvIGJ5IGxvYWRQYWNrYWdlcwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBGaWx0ZXJSZXBvc2l0b3J5IGltcGxlbWVudHMgUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcml2YXRlICRvbmx5ID0gbnVsbDsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJGV4Y2x1ZGUgPSBudWxsOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkY2Fub25pY2FsID0gdHJ1ZTsKICAgIC8qKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJHJlcG87CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl7b25seT86IGFycmF5PHN0cmluZz4sIGV4Y2x1ZGU/OiBhcnJheTxzdHJpbmc+LCBjYW5vbmljYWw/OiBib29sfSAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydvbmx5J10pKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJG9wdGlvbnNbJ29ubHknXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCcib25seSIga2V5IGZvciByZXBvc2l0b3J5ICcuJHJlcG8tPmdldFJlcG9OYW1lKCkuJyBzaG91bGQgYmUgYW4gYXJyYXknKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+b25seSA9IEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZXNUb1JlZ2V4cCgkb3B0aW9uc1snb25seSddKTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydleGNsdWRlJ10pKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJG9wdGlvbnNbJ2V4Y2x1ZGUnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCciZXhjbHVkZSIga2V5IGZvciByZXBvc2l0b3J5ICcuJHJlcG8tPmdldFJlcG9OYW1lKCkuJyBzaG91bGQgYmUgYW4gYXJyYXknKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+ZXhjbHVkZSA9IEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZXNUb1JlZ2V4cCgkb3B0aW9uc1snZXhjbHVkZSddKTsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5leGNsdWRlICYmICR0aGlzLT5vbmx5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdPbmx5IG9uZSBvZiAib25seSIgYW5kICJleGNsdWRlIiBjYW4gYmUgc3BlY2lmaWVkIGZvciByZXBvc2l0b3J5ICcuJHJlcG8tPmdldFJlcG9OYW1lKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2Nhbm9uaWNhbCddKSkgewogICAgICAgICAgICBpZiAoIWlzX2Jvb2woJG9wdGlvbnNbJ2Nhbm9uaWNhbCddKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJyJjYW5vbmljYWwiIGtleSBmb3IgcmVwb3NpdG9yeSAnLiRyZXBvLT5nZXRSZXBvTmFtZSgpLicgc2hvdWxkIGJlIGEgYm9vbGVhbicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5jYW5vbmljYWwgPSAkb3B0aW9uc1snY2Fub25pY2FsJ107CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVwbyA9ICRyZXBvOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvLT5nZXRSZXBvTmFtZSgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcnkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwbzsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZSgkbmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aXNBbGxvd2VkKCRuYW1lKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cmVwby0+ZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pc0FsbG93ZWQoJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvLT5maW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VNYXAsIGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsIGFycmF5ICRzdGFiaWxpdHlGbGFncywgYXJyYXkgJGFscmVhZHlMb2FkZWQgPSBhcnJheSgpKQogICAgewogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTWFwIGFzICRuYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmlzQWxsb3dlZCgkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlTWFwWyRuYW1lXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJHBhY2thZ2VNYXApIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCduYW1lc0ZvdW5kJyA9PiBhcnJheSgpLCAncGFja2FnZXMnID0+IGFycmF5KCkpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5yZXBvLT5sb2FkUGFja2FnZXMoJHBhY2thZ2VNYXAsICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsICRzdGFiaWxpdHlGbGFncywgJGFscmVhZHlMb2FkZWQpOwogICAgICAgIGlmICghJHRoaXMtPmNhbm9uaWNhbCkgewogICAgICAgICAgICAkcmVzdWx0WyduYW1lc0ZvdW5kJ10gPSBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCRxdWVyeSwgJG1vZGUgPSAwLCAkdHlwZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvLT5zZWFyY2goJHF1ZXJ5LCAkbW9kZSwgJHR5cGUpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNBbGxvd2VkKCRwYWNrYWdlWyduYW1lJ10pKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNBbGxvd2VkKCRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwby0+Z2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkgYXMgJG5hbWUgPT4gJHByb3ZpZGVyKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNBbGxvd2VkKCRwcm92aWRlclsnbmFtZSddKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdFskbmFtZV0gPSAkcHJvdmlkZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24gY291bnQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cmVwby0+Y291bnQoKSA+IDApIHsKICAgICAgICAgICAgcmV0dXJuIGNvdW50KCR0aGlzLT5nZXRQYWNrYWdlcygpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzQWxsb3dlZCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5vbmx5ICYmICEkdGhpcy0+ZXhjbHVkZSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+b25seSkgewogICAgICAgICAgICByZXR1cm4gUHJlZzo6aXNNYXRjaCgkdGhpcy0+b25seSwgJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICFQcmVnOjppc01hdGNoKCR0aGlzLT5leGNsdWRlLCAkbmFtZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxMb2FkZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFRhcjsKdXNlIENvbXBvc2VyXFV0aWxcWmlwOwoKLyoqCiAqIEBhdXRob3IgU2VyZ2UgU21lcnRpbiA8c2VyZy5zbWVydGluQGdtYWlsLmNvbT4KICovCmNsYXNzIEFydGlmYWN0UmVwb3NpdG9yeSBleHRlbmRzIEFycmF5UmVwb3NpdG9yeSBpbXBsZW1lbnRzIENvbmZpZ3VyYWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgTG9hZGVySW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGxvYWRlcjsKCiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkbG9va3VwOwogICAgLyoqIEB2YXIgYXJyYXl7dXJsOiBzdHJpbmd9ICovCiAgICBwcm90ZWN0ZWQgJHJlcG9Db25maWc7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl7dXJsOiBzdHJpbmd9ICRyZXBvQ29uZmlnCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcmVwb0NvbmZpZywgSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoKTsKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ3ppcCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIGFydGlmYWN0IHJlcG9zaXRvcnkgcmVxdWlyZXMgUEhQXCdzIHppcCBleHRlbnNpb24nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIoKTsKICAgICAgICAkdGhpcy0+bG9va3VwID0gJHJlcG9Db25maWdbJ3VybCddOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+cmVwb0NvbmZpZyA9ICRyZXBvQ29uZmlnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdhcnRpZmFjdCByZXBvICgnLiR0aGlzLT5sb29rdXAuJyknOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvQ29uZmlnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9Db25maWc7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgIHBhcmVudDo6aW5pdGlhbGl6ZSgpOwoKICAgICAgICAkdGhpcy0+c2NhbkRpcmVjdG9yeSgkdGhpcy0+bG9va3VwKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzY2FuRGlyZWN0b3J5KCRwYXRoKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5pbzsKCiAgICAgICAgJGRpcmVjdG9yeSA9IG5ldyBcUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJHBhdGgsIFxSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6Rk9MTE9XX1NZTUxJTktTKTsKICAgICAgICAkaXRlcmF0b3IgPSBuZXcgXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IoJGRpcmVjdG9yeSk7CiAgICAgICAgJHJlZ2V4ID0gbmV3IFxSZWdleEl0ZXJhdG9yKCRpdGVyYXRvciwgJy9eLitcLih6aXB8dGFyfGd6fHRneikkL2knKTsKICAgICAgICBmb3JlYWNoICgkcmVnZXggYXMgJGZpbGUpIHsKICAgICAgICAgICAgLyogQHZhciAkZmlsZSBcU3BsRmlsZUluZm8gKi8KICAgICAgICAgICAgaWYgKCEkZmlsZS0+aXNGaWxlKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRmaWxlKTsKICAgICAgICAgICAgaWYgKCEkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCJGaWxlIDxjb21tZW50PnskZmlsZS0+Z2V0QmFzZW5hbWUoKX08L2NvbW1lbnQ+IGRvZXNuJ3Qgc2VlbSB0byBob2xkIGEgcGFja2FnZSIsIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGVtcGxhdGUgPSAnRm91bmQgcGFja2FnZSA8aW5mbz4lczwvaW5mbz4gKDxjb21tZW50PiVzPC9jb21tZW50PikgaW4gZmlsZSA8aW5mbz4lczwvaW5mbz4nOwogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZigkdGVtcGxhdGUsICRwYWNrYWdlLT5nZXROYW1lKCksICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksICRmaWxlLT5nZXRCYXNlbmFtZSgpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gP0Jhc2VQYWNrYWdlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbihcU3BsRmlsZUluZm8gJGZpbGUpCiAgICB7CiAgICAgICAgJGpzb24gPSBudWxsOwogICAgICAgICRmaWxlVHlwZSA9IG51bGw7CiAgICAgICAgJGZpbGVFeHRlbnNpb24gPSBwYXRoaW5mbygkZmlsZS0+Z2V0UGF0aG5hbWUoKSwgUEFUSElORk9fRVhURU5TSU9OKTsKICAgICAgICBpZiAoaW5fYXJyYXkoJGZpbGVFeHRlbnNpb24sIGFycmF5KCdneicsICd0YXInLCAndGd6JyksIHRydWUpKSB7CiAgICAgICAgICAgICRmaWxlVHlwZSA9ICd0YXInOwogICAgICAgIH0gZWxzZWlmICgkZmlsZUV4dGVuc2lvbiA9PT0gJ3ppcCcpIHsKICAgICAgICAgICAgJGZpbGVUeXBlID0gJ3ppcCc7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGaWxlcyB3aXRoICInLiRmaWxlRXh0ZW5zaW9uLiciIGV4dGVuc2lvbnMgYXJlblwndCBzdXBwb3J0ZWQuIE9ubHkgWklQIGFuZCBUQVIvVEFSLkdaL1RHWiBhcmNoaXZlcyBhcmUgc3VwcG9ydGVkLicpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCRmaWxlVHlwZSA9PT0gJ3RhcicpIHsKICAgICAgICAgICAgICAgICRqc29uID0gVGFyOjpnZXRDb21wb3Nlckpzb24oJGZpbGUtPmdldFBhdGhuYW1lKCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGpzb24gPSBaaXA6OmdldENvbXBvc2VySnNvbigkZmlsZS0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRleGNlcHRpb24pIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgnRmFpbGVkIGxvYWRpbmcgcGFja2FnZSAnLiRmaWxlLT5nZXRQYXRobmFtZSgpLic6ICcuJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpLCBmYWxzZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRqc29uKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2UgPSBKc29uRmlsZTo6cGFyc2VKc29uKCRqc29uLCAkZmlsZS0+Z2V0UGF0aG5hbWUoKS4nI2NvbXBvc2VyLmpzb24nKTsKICAgICAgICAkcGFja2FnZVsnZGlzdCddID0gYXJyYXkoCiAgICAgICAgICAgICd0eXBlJyA9PiAkZmlsZVR5cGUsCiAgICAgICAgICAgICd1cmwnID0+IHN0cnRyKCRmaWxlLT5nZXRQYXRobmFtZSgpLCAnXFwnLCAnLycpLAogICAgICAgICAgICAnc2hhc3VtJyA9PiBzaGExX2ZpbGUoJGZpbGUtPmdldFJlYWxQYXRoKCkpLAogICAgICAgICk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmxvYWRlci0+bG9hZCgkcGFja2FnZSk7CiAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignRmFpbGVkIGxvYWRpbmcgcGFja2FnZSBpbiAnLiRmaWxlLic6ICcuJGUtPmdldE1lc3NhZ2UoKSwgMCwgJGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgovKioKICogRXhjZXB0aW9uIHRocm93biB3aGVuIGEgcGFja2FnZSByZXBvc2l0b3J5IGlzIHV0dGVybHkgYnJva2VuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEludmFsaWRSZXBvc2l0b3J5RXhjZXB0aW9uIGV4dGVuZHMgXEV4Y2VwdGlvbgp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwoKLyoqCiAqIFdyaXRhYmxlIGFycmF5IHJlcG9zaXRvcnkuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFdyaXRhYmxlQXJyYXlSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5IGltcGxlbWVudHMgV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmdbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGRldlBhY2thZ2VOYW1lcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2UGFja2FnZU5hbWVzKGFycmF5ICRkZXZQYWNrYWdlTmFtZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmRldlBhY2thZ2VOYW1lcyA9ICRkZXZQYWNrYWdlTmFtZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGV2UGFja2FnZU5hbWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRldlBhY2thZ2VOYW1lczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkZGV2TW9kZSwgSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlcikKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWxvYWQoKQogICAgewogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENhbm9uaWNhbFBhY2thZ2VzKCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+Z2V0UGFja2FnZXMoKTsKCiAgICAgICAgLy8gZ2V0IGF0IG1vc3Qgb25lIHBhY2thZ2Ugb2YgZWFjaCBuYW1lLCBwcmVmZXJyaW5nIG5vbi1hbGlhc2VkIG9uZXMKICAgICAgICAkcGFja2FnZXNCeU5hbWUgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCRwYWNrYWdlc0J5TmFtZVskcGFja2FnZS0+Z2V0TmFtZSgpXSkgfHwgJHBhY2thZ2VzQnlOYW1lWyRwYWNrYWdlLT5nZXROYW1lKCldIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZXNCeU5hbWVbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGNhbm9uaWNhbFBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgLy8gdW5mb2xkIGFsaWFzZWQgcGFja2FnZXMKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXNCeU5hbWUgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgd2hpbGUgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjYW5vbmljYWxQYWNrYWdlc1tdID0gJHBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNhbm9uaWNhbFBhY2thZ2VzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXI7CgovKioKICogV3JpdGFibGUgcmVwb3NpdG9yeSBpbnRlcmZhY2UuCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlIGV4dGVuZHMgUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFdyaXRlcyByZXBvc2l0b3J5IChmLmUuIHRvIHRoZSBkaXNjKS4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGV2TW9kZSBXaGV0aGVyIGRldiByZXF1aXJlbWVudHMgd2VyZSBpbmNsdWRlZCBvciBub3QgaW4gdGhpcyBpbnN0YWxsYXRpb24KICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJGRldk1vZGUsIEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIpOwoKICAgIC8qKgogICAgICogQWRkcyBwYWNrYWdlIHRvIHRoZSByZXBvc2l0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKTsKCiAgICAvKioKICAgICAqIFJlbW92ZXMgcGFja2FnZSBmcm9tIHRoZSByZXBvc2l0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKTsKCiAgICAvKioKICAgICAqIEdldCB1bmlxdWUgcGFja2FnZXMgKGF0IG1vc3Qgb25lIHBhY2thZ2Ugb2YgZWFjaCBuYW1lKSwgd2l0aCBhbGlhc2VzIHJlc29sdmVkIGFuZCByZW1vdmVkLgogICAgICoKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDYW5vbmljYWxQYWNrYWdlcygpOwoKICAgIC8qKgogICAgICogRm9yY2VzIGEgcmVsb2FkIG9mIGFsbCBwYWNrYWdlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbG9hZCgpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRkZXZQYWNrYWdlTmFtZXMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2UGFja2FnZU5hbWVzKGFycmF5ICRkZXZQYWNrYWdlTmFtZXMpOwoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXSBOYW1lcyBvZiBkZXBlbmRlbmNpZXMgaW5zdGFsbGVkIHRocm91Z2ggcmVxdWlyZS1kZXYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldlBhY2thZ2VOYW1lcygpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgppbnRlcmZhY2UgVmVyc2lvbkNhY2hlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgJHZlcnNpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIG1peGVkW118bnVsbHxmYWxzZSBQYWNrYWdlIHZlcnNpb24gZGF0YSBpZiBmb3VuZCwgZmFsc2UgdG8gaW5kaWNhdGUgdGhlIGlkZW50aWZpZXIgaXMga25vd24gYnV0IGhhcyBubyBwYWNrYWdlLCBudWxsIGZvciBhbiB1bmtub3duIGlkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcnNpb25QYWNrYWdlKCR2ZXJzaW9uLCAkaWRlbnRpZmllcik7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCi8qKgogKiBUaHJvd24gd2hlbiBhIHNlY3VyaXR5IHByb2JsZW0sIGxpa2UgYSBicm9rZW4gb3IgbWlzc2luZyBzaWduYXR1cmUKICoKICogQGF1dGhvciBFcmljIERhc3BldCA8ZWRhc3BldEBzdXJ2b2wuZnI+CiAqLwpjbGFzcyBSZXBvc2l0b3J5U2VjdXJpdHlFeGNlcHRpb24gZXh0ZW5kcyBcRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwoKLyoqCiAqIFJlcG9zaXRvcnkgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgUmVwb3NpdG9yeUludGVyZmFjZSBleHRlbmRzIFxDb3VudGFibGUKewogICAgY29uc3QgU0VBUkNIX0ZVTExURVhUID0gMDsKICAgIGNvbnN0IFNFQVJDSF9OQU1FID0gMTsKICAgIGNvbnN0IFNFQVJDSF9WRU5ET1IgPSAyOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHNwZWNpZmllZCBwYWNrYWdlIHJlZ2lzdGVyZWQgKGluc3RhbGxlZCkuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKTsKCiAgICAvKioKICAgICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3QgbWF0Y2ggb2YgYSBwYWNrYWdlIGJ5IG5hbWUgYW5kIHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICRuYW1lICAgICAgIHBhY2thZ2UgbmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50IHBhY2thZ2UgdmVyc2lvbiBvciB2ZXJzaW9uIGNvbnN0cmFpbnQgdG8gbWF0Y2ggYWdhaW5zdAogICAgICoKICAgICAqIEByZXR1cm4gQmFzZVBhY2thZ2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KTsKCiAgICAvKioKICAgICAqIFNlYXJjaGVzIGZvciBhbGwgcGFja2FnZXMgbWF0Y2hpbmcgYSBuYW1lIGFuZCBvcHRpb25hbGx5IGEgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAgJG5hbWUgICAgICAgcGFja2FnZSBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgcGFja2FnZSB2ZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBtYXRjaCBhZ2FpbnN0CiAgICAgKgogICAgICogQHJldHVybiBCYXNlUGFja2FnZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxpc3Qgb2YgcmVnaXN0ZXJlZCBwYWNrYWdlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2VzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxpc3Qgb2YgcmVnaXN0ZXJlZCBwYWNrYWdlcyB3aXRoIHRoZSBzdXBwbGllZCBuYW1lCiAgICAgKgogICAgICogLSBUaGUgcGFja2FnZXMgcmV0dXJuZWQgYXJlIHRoZSBwYWNrYWdlcyBmb3VuZCB3aGljaCBtYXRjaCB0aGUgY29uc3RyYWludHMsIGFjY2VwdGFibGUgc3RhYmlsaXR5IGFuZCBzdGFiaWxpdHkgZmxhZ3MgcHJvdmlkZWQKICAgICAqIC0gVGhlIG5hbWVzRm91bmQgcmV0dXJuZWQgYXJlIG5hbWVzIHdoaWNoIHNob3VsZCBiZSBjb25zaWRlcmVkIGFzIGNhbm9uaWNhbGx5IGZvdW5kIGluIHRoaXMgcmVwb3NpdG9yeSwgdGhhdCBzaG91bGQgbm90IGJlIGxvb2tlZCB1cCBpbiBhbnkgZnVydGhlciBsb3dlciBwcmlvcml0eSByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZVtdICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU5hbWVNYXAgICAgICAgIHBhY2thZ2UgbmFtZXMgcG9pbnRpbmcgdG8gY29uc3RyYWludHMKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4gICAgICAgICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgYXJyYXkgb2Ygc3RhYmlsaXR5ID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAgICAgICAgJHN0YWJpbGl0eUZsYWdzICAgICAgICBhbiBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+PiAkYWxyZWFkeUxvYWRlZCAgICAgICAgIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBwYWNrYWdlIHZlcnNpb24gPT4gcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSAgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlfG51bGw+ICRwYWNrYWdlTmFtZU1hcAogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5e25hbWVzRm91bmQ6IGFycmF5PHN0cmluZz4sIHBhY2thZ2VzOiBhcnJheTxCYXNlUGFja2FnZT59CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VOYW1lTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBTZWFyY2hlcyB0aGUgcmVwb3NpdG9yeSBmb3IgcGFja2FnZXMgY29udGFpbmluZyB0aGUgcXVlcnkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRxdWVyeSBzZWFyY2ggcXVlcnksIGZvciBTRUFSQ0hfTkFNRSBhbmQgU0VBUkNIX1ZFTkRPUiByZWd1bGFyIGV4cHJlc3Npb25zIG1ldGFjaGFyYWN0ZXJzIGFyZSBzdXBwb3J0ZWQgYnkgaW1wbGVtZW50YXRpb25zLCBhbmQgdXNlciBpbnB1dCBzaG91bGQgYmUgZXNjYXBlZCB0aHJvdWdoIHByZWdfcXVvdGUgYnkgY2FsbGVycwogICAgICogQHBhcmFtIGludCAgICAkbW9kZSAgYSBzZXQgb2YgU0VBUkNIXyogY29uc3RhbnRzIHRvIHNlYXJjaCBvbiwgaW1wbGVtZW50YXRpb25zIHNob3VsZCBkbyBhIGJlc3QgZWZmb3J0IG9ubHksIGRlZmF1bHQgaXMgU0VBUkNIX0ZVTExURVhUCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlICBUaGUgdHlwZSBvZiBwYWNrYWdlIHRvIHNlYXJjaCBmb3IuIERlZmF1bHRzIHRvIGFsbCB0eXBlcyBvZiBwYWNrYWdlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXlbXSBhbiBhcnJheSBvZiBhcnJheSgnbmFtZScgPT4gJy4uLicsICdkZXNjcmlwdGlvbicgPT4gJy4uLid8bnVsbCwgJ2FiYW5kb25lZCcgPT4gJ3N0cmluZyd8dHJ1ZXx1bnNldCkgRm9yIFNFQVJDSF9WRU5ET1IgdGhlIG5hbWUgd2lsbCBiZSBpbiAidmVuZG9yIiBmb3JtCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gbGlzdDxhcnJheXtuYW1lOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiA/c3RyaW5nLCBhYmFuZG9uZWQ/OiBzdHJpbmd8dHJ1ZX0+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWFyY2goJHF1ZXJ5LCAkbW9kZSA9IDAsICR0eXBlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwYWNrYWdlcyBwcm92aWRpbmcgYSBnaXZlbiBwYWNrYWdlIG5hbWUKICAgICAqCiAgICAgKiBQYWNrYWdlcyB3aGljaCBoYXZlIHRoZSBzYW1lIG5hbWUgYXMgJHBhY2thZ2VOYW1lIHNob3VsZCBub3QgYmUgcmV0dXJuZWQsIG9ubHkgdGhvc2UgdGhhdCBoYXZlIGEgInByb3ZpZGUiIG9uIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VOYW1lIHBhY2thZ2UgbmFtZSB3aGljaCBtdXN0IGJlIHByb3ZpZGVkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheVtdIGFuIGFycmF5IHdpdGggdGhlIHByb3ZpZGVyIG5hbWUgYXMga2V5IGFuZCB2YWx1ZSBvZiBhcnJheSgnbmFtZScgPT4gJy4uLicsICdkZXNjcmlwdGlvbicgPT4gJy4uLicsICd0eXBlJyA9PiAnLi4uJykKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheTxzdHJpbmcsIGFycmF5e25hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgdHlwZTogc3RyaW5nfT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3ZpZGVycygkcGFja2FnZU5hbWUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5hbWUgcmVwcmVzZW50aW5nIHRoaXMgcmVwb3NpdG9yeSB0byB0aGUgdXNlcgogICAgICoKICAgICAqIFRoaXMgaXMgYmVzdCBlZmZvcnQgYW5kIGRlZmluaXRlbHkgY2FuIG5vdCBhbHdheXMgYmUgdmVyeSBwcmVjaXNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9OYW1lKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uR3Vlc3NlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CnVzZSBDb21wb3NlclxVdGlsXEdpdCBhcyBHaXRVdGlsOwoKLyoqCiAqIFRoaXMgcmVwb3NpdG9yeSBhbGxvd3MgaW5zdGFsbGluZyBsb2NhbCBwYWNrYWdlcyB0aGF0IGFyZSBub3QgbmVjZXNzYXJpbHkgdW5kZXIgdGhlaXIgb3duIFZDUy4KICoKICogVGhlIGxvY2FsIHBhY2thZ2VzIHdpbGwgYmUgc3ltbGlua2VkIHdoZW4gcG9zc2libGUsIGVsc2UgdGhleSB3aWxsIGJlIGNvcGllZC4KICoKICogQGNvZGUKICogInJlcXVpcmUiOiB7CiAqICAgICAiPHZlbmRvcj4vPGxvY2FsLXBhY2thZ2U+IjogIioiCiAqIH0sCiAqICJyZXBvc2l0b3JpZXMiOiBbCiAqICAgICB7CiAqICAgICAgICAgInR5cGUiOiAicGF0aCIsCiAqICAgICAgICAgInVybCI6ICIuLi8uLi9yZWxhdGl2ZS9wYXRoL3RvL3BhY2thZ2UvIgogKiAgICAgfSwKICogICAgIHsKICogICAgICAgICAidHlwZSI6ICJwYXRoIiwKICogICAgICAgICAidXJsIjogIi9hYnNvbHV0ZS9wYXRoL3RvL3BhY2thZ2UvIgogKiAgICAgfSwKICogICAgIHsKICogICAgICAgICAidHlwZSI6ICJwYXRoIiwKICogICAgICAgICAidXJsIjogIi9hYnNvbHV0ZS9wYXRoL3RvL3NldmVyYWwvcGFja2FnZXMvKiIKICogICAgIH0sCiAqICAgICB7CiAqICAgICAgICAgInR5cGUiOiAicGF0aCIsCiAqICAgICAgICAgInVybCI6ICIuLi8uLi9yZWxhdGl2ZS9wYXRoL3RvL3BhY2thZ2UvIiwKICogICAgICAgICAib3B0aW9ucyI6IHsKICogICAgICAgICAgICAgInN5bWxpbmsiOiBmYWxzZQogKiAgICAgICAgIH0KICogICAgIH0sCiAqIF0KICogQGVuZGNvZGUKICoKICogQGF1dGhvciBTYW11ZWwgUm96ZSA8c2FtdWVsLnJvemVAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvaGFubiBSZWlua2UgPGpvaGFubi5yZWlua2VAZ21haWwuY29tPgogKi8KY2xhc3MgUGF0aFJlcG9zaXRvcnkgZXh0ZW5kcyBBcnJheVJlcG9zaXRvcnkgaW1wbGVtZW50cyBDb25maWd1cmFibGVSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBBcnJheUxvYWRlcgogICAgICovCiAgICBwcml2YXRlICRsb2FkZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIFZlcnNpb25HdWVzc2VyCiAgICAgKi8KICAgIHByaXZhdGUgJHZlcnNpb25HdWVzc2VyOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkdXJsOwoKICAgIC8qKgogICAgICogQHZhciBtaXhlZFtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXl7dXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBhcnJheXtzeW1saW5rPzogYm9vbCwgcmVsYXRpdmU/OiBib29sLCB2ZXJzaW9ucz86IGFycmF5PHN0cmluZywgc3RyaW5nPn19CiAgICAgKi8KICAgIHByaXZhdGUgJHJlcG9Db25maWc7CgogICAgLyoqCiAgICAgKiBAdmFyIFByb2Nlc3NFeGVjdXRvcgogICAgICovCiAgICBwcml2YXRlICRwcm9jZXNzOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheXtzeW1saW5rPzogYm9vbCwgcmVsYXRpdmU/OiBib29sLCB2ZXJzaW9ucz86IGFycmF5PHN0cmluZywgc3RyaW5nPn0KICAgICAqLwogICAgcHJpdmF0ZSAkb3B0aW9uczsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHBhdGggcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl7dXJsPzogc3RyaW5nLCBvcHRpb25zPzogYXJyYXl7c3ltbGluaz86IGJvb2wsIHJlbGF0aXZlPzogYm9vbCwgdmVyc2lvbnM/OiBhcnJheTxzdHJpbmcsIHN0cmluZz59fSAkcmVwb0NvbmZpZwogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtIENvbmZpZyAgICAgICRjb25maWcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRyZXBvQ29uZmlnLCBJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHJlcG9Db25maWdbJ3VybCddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1lvdSBtdXN0IHNwZWNpZnkgdGhlIGB1cmxgIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBwYXRoIHJlcG9zaXRvcnknKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIobnVsbCwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnVybCA9IFBsYXRmb3JtOjpleHBhbmRQYXRoKCRyZXBvQ29uZmlnWyd1cmwnXSk7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPnZlcnNpb25HdWVzc2VyID0gbmV3IFZlcnNpb25HdWVzc2VyKCRjb25maWcsICR0aGlzLT5wcm9jZXNzLCBuZXcgVmVyc2lvblBhcnNlcigpKTsKICAgICAgICAkdGhpcy0+cmVwb0NvbmZpZyA9ICRyZXBvQ29uZmlnOwogICAgICAgICR0aGlzLT5vcHRpb25zID0gaXNzZXQoJHJlcG9Db25maWdbJ29wdGlvbnMnXSkgPyAkcmVwb0NvbmZpZ1snb3B0aW9ucyddIDogYXJyYXkoKTsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5vcHRpb25zWydyZWxhdGl2ZSddKSkgewogICAgICAgICAgICAkZmlsZXN5c3RlbSA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgICAgICR0aGlzLT5vcHRpb25zWydyZWxhdGl2ZSddID0gISRmaWxlc3lzdGVtLT5pc0Fic29sdXRlUGF0aCgkdGhpcy0+dXJsKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgIHJldHVybiAncGF0aCByZXBvICgnLlVybDo6c2FuaXRpemUoJHRoaXMtPnJlcG9Db25maWdbJ3VybCddKS4nKSc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9Db25maWcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb0NvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHBhdGggcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJhc2ljYWxseSByZWFkIHRoZSBmb2xkZXIgYW5kIGFkZCB0aGUgZm91bmQgcGFja2FnZS4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgIHBhcmVudDo6aW5pdGlhbGl6ZSgpOwoKICAgICAgICAkdXJsTWF0Y2hlcyA9ICR0aGlzLT5nZXRVcmxNYXRjaGVzKCk7CgogICAgICAgIGlmIChlbXB0eSgkdXJsTWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3tbKnt9XX0nLCAkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAgICAgJHVybCA9ICR0aGlzLT51cmw7CiAgICAgICAgICAgICAgICB3aGlsZSAoUHJlZzo6aXNNYXRjaCgne1sqe31dfScsICR1cmwpKSB7CiAgICAgICAgICAgICAgICAgICAgJHVybCA9IGRpcm5hbWUoJHVybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0aGUgcGFyZW50IGRpcmVjdG9yeSBiZWZvcmUgYW55IHdpbGRjYXJkIGV4aXN0cywgc28gd2UgYXNzdW1lIGl0IGlzIGNvcnJlY3RseSBjb25maWd1cmVkIGJ1dCBzaW1wbHkgZW1wdHkKICAgICAgICAgICAgICAgIGlmIChpc19kaXIoJHVybCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIGB1cmxgIHN1cHBsaWVkIGZvciB0aGUgcGF0aCAoJyAuICR0aGlzLT51cmwgLiAnKSByZXBvc2l0b3J5IGRvZXMgbm90IGV4aXN0Jyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdXJsTWF0Y2hlcyBhcyAkdXJsKSB7CiAgICAgICAgICAgICRwYXRoID0gcmVhbHBhdGgoJHVybCkgLiBESVJFQ1RPUllfU0VQQVJBVE9SOwogICAgICAgICAgICAkY29tcG9zZXJGaWxlUGF0aCA9ICRwYXRoLidjb21wb3Nlci5qc29uJzsKCiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJGNvbXBvc2VyRmlsZVBhdGgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGpzb24gPSBmaWxlX2dldF9jb250ZW50cygkY29tcG9zZXJGaWxlUGF0aCk7CiAgICAgICAgICAgICRwYWNrYWdlID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkanNvbiwgJGNvbXBvc2VyRmlsZVBhdGgpOwogICAgICAgICAgICAkcGFja2FnZVsnZGlzdCddID0gYXJyYXkoCiAgICAgICAgICAgICAgICAndHlwZScgPT4gJ3BhdGgnLAogICAgICAgICAgICAgICAgJ3VybCcgPT4gJHVybCwKICAgICAgICAgICAgICAgICdyZWZlcmVuY2UnID0+IHNoYTEoJGpzb24gLiBzZXJpYWxpemUoJHRoaXMtPm9wdGlvbnMpKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJHBhY2thZ2VbJ3RyYW5zcG9ydC1vcHRpb25zJ10gPSAkdGhpcy0+b3B0aW9uczsKICAgICAgICAgICAgdW5zZXQoJHBhY2thZ2VbJ3RyYW5zcG9ydC1vcHRpb25zJ11bJ3ZlcnNpb25zJ10pOwoKICAgICAgICAgICAgLy8gdXNlIHRoZSB2ZXJzaW9uIHByb3ZpZGVkIGFzIG9wdGlvbiBpZiBhdmFpbGFibGUKICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlWyduYW1lJ10sICR0aGlzLT5vcHRpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlWyduYW1lJ11dKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VbJ3ZlcnNpb24nXSA9ICR0aGlzLT5vcHRpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlWyduYW1lJ11dOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjYXJyeSBvdmVyIHRoZSByb290IHBhY2thZ2UgdmVyc2lvbiBpZiB0aGlzIHBhdGggcmVwbyBpcyBpbiB0aGUgc2FtZSBnaXQgcmVwb3NpdG9yeSBhcyByb290IHBhY2thZ2UKICAgICAgICAgICAgaWYgKCFpc3NldCgkcGFja2FnZVsndmVyc2lvbiddKSAmJiAoJHJvb3RWZXJzaW9uID0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfUk9PVF9WRVJTSU9OJykpKSB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZXYtcGFyc2UgSEVBRCcsICRyZWYxLCAkcGF0aCkKICAgICAgICAgICAgICAgICAgICAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IHJldi1wYXJzZSBIRUFEJywgJHJlZjIpCiAgICAgICAgICAgICAgICAgICAgJiYgJHJlZjEgPT09ICRyZWYyCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVsndmVyc2lvbiddID0gJHJvb3RWZXJzaW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkb3V0cHV0ID0gJyc7CiAgICAgICAgICAgIGlmIChpc19kaXIoJHBhdGggLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJy5naXQnKSAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGxvZyAtbjEgLS1wcmV0dHk9JUgnLkdpdFV0aWw6OmdldE5vU2hvd1NpZ25hdHVyZUZsYWcoJHRoaXMtPnByb2Nlc3MpLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlWydkaXN0J11bJ3JlZmVyZW5jZSddID0gdHJpbSgkb3V0cHV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG5lZWRzQWxpYXMgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCFpc3NldCgkcGFja2FnZVsndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgJHZlcnNpb25EYXRhID0gJHRoaXMtPnZlcnNpb25HdWVzc2VyLT5ndWVzc1ZlcnNpb24oJHBhY2thZ2UsICRwYXRoKTsKICAgICAgICAgICAgICAgIGlmIChpc19hcnJheSgkdmVyc2lvbkRhdGEpICYmICR2ZXJzaW9uRGF0YVsncHJldHR5X3ZlcnNpb24nXSkgewogICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGEgZmVhdHVyZSBicmFuY2ggZGV0ZWN0ZWQsIHdlIGFkZCBhIHNlY29uZCBwYWNrYWdlcyB3aXRoIHRoZSBmZWF0dXJlIGJyYW5jaCB2ZXJzaW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfcHJldHR5X3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VbJ3ZlcnNpb24nXSA9ICR2ZXJzaW9uRGF0YVsnZmVhdHVyZV9wcmV0dHlfdmVyc2lvbiddOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkdGhpcy0+bG9hZGVyLT5sb2FkKCRwYWNrYWdlKSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVsndmVyc2lvbiddID0gJHZlcnNpb25EYXRhWydwcmV0dHlfdmVyc2lvbiddOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVsndmVyc2lvbiddID0gJ2Rldi1tYWluJzsKICAgICAgICAgICAgICAgICAgICAkbmVlZHNBbGlhcyA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmxvYWRlci0+bG9hZCgkcGFja2FnZSk7CiAgICAgICAgICAgIGlmICgkbmVlZHNBbGlhcyAmJiAkcGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZSkgewogICAgICAgICAgICAgICAgLy8ga2VlcCBhIGRldi1tYXN0ZXIgYWxpYXMgdG8gZGV2LW1haW4gZm9yIEJDCiAgICAgICAgICAgICAgICAkcGFja2FnZSA9IG5ldyBDb21wbGV0ZUFsaWFzUGFja2FnZSgkcGFja2FnZSwgJ2Rldi1tYXN0ZXInLCAnZGV2LW1hc3RlcicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBsaXN0IG9mIGFsbCAocG9zc2libHkgcmVsYXRpdmUpIHBhdGggbmFtZXMgbWF0Y2hpbmcgZ2l2ZW4gdXJsIChzdXBwb3J0cyBnbG9iYmluZykuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFVybE1hdGNoZXMoKQogICAgewogICAgICAgICRmbGFncyA9IEdMT0JfTUFSSyB8IEdMT0JfT05MWURJUjsKCiAgICAgICAgaWYgKGRlZmluZWQoJ0dMT0JfQlJBQ0UnKSkgewogICAgICAgICAgICAkZmxhZ3MgfD0gR0xPQl9CUkFDRTsKICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCR0aGlzLT51cmwsICd7JykgIT09IGZhbHNlIHx8IHN0cnBvcygkdGhpcy0+dXJsLCAnfScpICE9PSBmYWxzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBvcGVyYXRpbmcgc3lzdGVtIGRvZXMgbm90IHN1cHBvcnQgR0xPQl9CUkFDRSB3aGljaCBpcyByZXF1aXJlZCBmb3IgdGhlIHVybCAnLiAkdGhpcy0+dXJsKTsKICAgICAgICB9CgogICAgICAgIC8vIEVuc3VyZSBlbnZpcm9ubWVudC1zcGVjaWZpYyBwYXRoIHNlcGFyYXRvcnMgYXJlIG5vcm1hbGl6ZWQgdG8gVVJMIHNlcGFyYXRvcnMKICAgICAgICByZXR1cm4gYXJyYXlfbWFwKGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgIHJldHVybiBydHJpbShzdHJfcmVwbGFjZShESVJFQ1RPUllfU0VQQVJBVE9SLCAnLycsICR2YWwpLCAnLycpOwogICAgICAgIH0sIGdsb2IoJHRoaXMtPnVybCwgJGZsYWdzKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCi8qKgogKiBJbnN0YWxsZWQgZmlsZXN5c3RlbSByZXBvc2l0b3J5LgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBJbnN0YWxsZWRGaWxlc3lzdGVtUmVwb3NpdG9yeSBleHRlbmRzIEZpbGVzeXN0ZW1SZXBvc2l0b3J5IGltcGxlbWVudHMgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgIHJldHVybiAnaW5zdGFsbGVkICcucGFyZW50OjpnZXRSZXBvTmFtZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRnJlc2goKQogICAgewogICAgICAgIHJldHVybiAhJHRoaXMtPmZpbGUtPmV4aXN0cygpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUmVwb3NpdG9yeUZhY3RvcnkKewogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtICBDb25maWcgICAgICAkY29uZmlnCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRyZXBvc2l0b3J5CiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICRhbGxvd0ZpbGVzeXN0ZW0KICAgICAqIEByZXR1cm4gYXJyYXl8bWl4ZWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb25maWdGcm9tU3RyaW5nKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICRyZXBvc2l0b3J5LCAkYWxsb3dGaWxlc3lzdGVtID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkcmVwb3NpdG9yeSwgJ2h0dHAnKSkgewogICAgICAgICAgICAkcmVwb0NvbmZpZyA9IGFycmF5KCd0eXBlJyA9PiAnY29tcG9zZXInLCAndXJsJyA9PiAkcmVwb3NpdG9yeSk7CiAgICAgICAgfSBlbHNlaWYgKCJqc29uIiA9PT0gcGF0aGluZm8oJHJlcG9zaXRvcnksIFBBVEhJTkZPX0VYVEVOU0lPTikpIHsKICAgICAgICAgICAgJGpzb24gPSBuZXcgSnNvbkZpbGUoJHJlcG9zaXRvcnksIEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZykpOwogICAgICAgICAgICAkZGF0YSA9ICRqc29uLT5yZWFkKCk7CiAgICAgICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ3BhY2thZ2VzJ10pIHx8ICFlbXB0eSgkZGF0YVsnaW5jbHVkZXMnXSkgfHwgIWVtcHR5KCRkYXRhWydwcm92aWRlci1pbmNsdWRlcyddKSkgewogICAgICAgICAgICAgICAgJHJlcG9Db25maWcgPSBhcnJheSgndHlwZScgPT4gJ2NvbXBvc2VyJywgJ3VybCcgPT4gJ2ZpbGU6Ly8nIC4gc3RydHIocmVhbHBhdGgoJHJlcG9zaXRvcnkpLCAnXFwnLCAnLycpKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRhbGxvd0ZpbGVzeXN0ZW0pIHsKICAgICAgICAgICAgICAgICRyZXBvQ29uZmlnID0gYXJyYXkoJ3R5cGUnID0+ICdmaWxlc3lzdGVtJywgJ2pzb24nID0+ICRqc29uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHJlcG9zaXRvcnkgVVJMICgkcmVwb3NpdG9yeSkgZ2l2ZW4uIFRoaXMgZmlsZSBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQgY29tcG9zZXIgcmVwb3NpdG9yeS4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChzdHJwb3MoJHJlcG9zaXRvcnksICd7JykgPT09IDApIHsKICAgICAgICAgICAgLy8gYXNzdW1lIGl0IGlzIGEganNvbiBvYmplY3QgdGhhdCBtYWtlcyBhIHJlcG8gY29uZmlnCiAgICAgICAgICAgICRyZXBvQ29uZmlnID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVwb3NpdG9yeSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgcmVwb3NpdG9yeSB1cmwgKCRyZXBvc2l0b3J5KSBnaXZlbi4gSGFzIHRvIGJlIGEgLmpzb24gZmlsZSwgYW4gaHR0cCB1cmwgb3IgYSBKU09OIG9iamVjdC4iKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVwb0NvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgICAgICAgICAkaW8KICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgICAgICAgICAkY29uZmlnCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgJHJlcG9zaXRvcnkKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAkYWxsb3dGaWxlc3lzdGVtCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICRyZXBvc2l0b3J5LCAkYWxsb3dGaWxlc3lzdGVtID0gZmFsc2UsIFJlcG9zaXRvcnlNYW5hZ2VyICRybSA9IG51bGwpCiAgICB7CiAgICAgICAgJHJlcG9Db25maWcgPSBzdGF0aWM6OmNvbmZpZ0Zyb21TdHJpbmcoJGlvLCAkY29uZmlnLCAkcmVwb3NpdG9yeSwgJGFsbG93RmlsZXN5c3RlbSk7CgogICAgICAgIHJldHVybiBzdGF0aWM6OmNyZWF0ZVJlcG8oJGlvLCAkY29uZmlnLCAkcmVwb0NvbmZpZywgJHJtKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgICAgICAgICAkaW8KICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgICAgICAgICAkY29uZmlnCiAgICAgKiBAcGFyYW0gIGFycmF5PHN0cmluZywgbWl4ZWQ+ICRyZXBvQ29uZmlnCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVSZXBvKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIGFycmF5ICRyZXBvQ29uZmlnLCBSZXBvc2l0b3J5TWFuYWdlciAkcm0gPSBudWxsKQogICAgewogICAgICAgIGlmICghJHJtKSB7CiAgICAgICAgICAgICRybSA9IHN0YXRpYzo6bWFuYWdlcigkaW8sICRjb25maWcsIEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZykpOwogICAgICAgIH0KICAgICAgICAkcmVwb3MgPSBzZWxmOjpjcmVhdGVSZXBvcygkcm0sIGFycmF5KCRyZXBvQ29uZmlnKSk7CgogICAgICAgIHJldHVybiByZXNldCgkcmVwb3MpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZXxudWxsICAgICAgICRpbwogICAgICogQHBhcmFtICBDb25maWd8bnVsbCAgICAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSAgUmVwb3NpdG9yeU1hbmFnZXJ8bnVsbCAkcm0KICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeUludGVyZmFjZVtdCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZGVmYXVsdFJlcG9zKElPSW50ZXJmYWNlICRpbyA9IG51bGwsIENvbmZpZyAkY29uZmlnID0gbnVsbCwgUmVwb3NpdG9yeU1hbmFnZXIgJHJtID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISRjb25maWcpIHsKICAgICAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygkaW8pOwogICAgICAgIH0KICAgICAgICBpZiAoJGlvKSB7CiAgICAgICAgICAgICRpby0+bG9hZENvbmZpZ3VyYXRpb24oJGNvbmZpZyk7CiAgICAgICAgfQogICAgICAgIGlmICghJHJtKSB7CiAgICAgICAgICAgIGlmICghJGlvKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhpcyBmdW5jdGlvbiByZXF1aXJlcyBlaXRoZXIgYW4gSU9JbnRlcmZhY2Ugb3IgYSBSZXBvc2l0b3J5TWFuYWdlcicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRybSA9IHN0YXRpYzo6bWFuYWdlcigkaW8sICRjb25maWcsIEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OmNyZWF0ZVJlcG9zKCRybSwgJGNvbmZpZy0+Z2V0UmVwb3NpdG9yaWVzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZSAgICAgICAkaW8KICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgICAgICAgJGNvbmZpZwogICAgICogQHBhcmFtICBFdmVudERpc3BhdGNoZXIgICAkZXZlbnREaXNwYXRjaGVyCiAgICAgKiBAcGFyYW0gIEh0dHBEb3dubG9hZGVyICAgICRodHRwRG93bmxvYWRlcgogICAgICogQHJldHVybiBSZXBvc2l0b3J5TWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1hbmFnZXIoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciA9IG51bGwsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHJtID0gbmV3IFJlcG9zaXRvcnlNYW5hZ2VyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkZXZlbnREaXNwYXRjaGVyLCAkcHJvY2Vzcyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ2NvbXBvc2VyJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zZXJSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ3ZjcycsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygncGFja2FnZScsICdDb21wb3NlclxSZXBvc2l0b3J5XFBhY2thZ2VSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ3BlYXInLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxQZWFyUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdnaXQnLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ2JpdGJ1Y2tldCcsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnZ2l0LWJpdGJ1Y2tldCcsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnZ2l0aHViJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdnaXRsYWInLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ3N2bicsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnZm9zc2lsJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdwZXJmb3JjZScsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnaGcnLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ2FydGlmYWN0JywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcQXJ0aWZhY3RSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ3BhdGgnLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxQYXRoUmVwb3NpdG9yeScpOwoKICAgICAgICByZXR1cm4gJHJtOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PGludHxzdHJpbmcsIG1peGVkPiAkcmVwb0NvbmZpZ3MKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVSZXBvcyhSZXBvc2l0b3J5TWFuYWdlciAkcm0sIGFycmF5ICRyZXBvQ29uZmlncykKICAgIHsKICAgICAgICAkcmVwb3MgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcmVwb0NvbmZpZ3MgYXMgJGluZGV4ID0+ICRyZXBvKSB7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHJlcG8pKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignInJlcG9zaXRvcmllcyIgc2hvdWxkIGJlIGFuIGFycmF5IG9mIHJlcG9zaXRvcnkgZGVmaW5pdGlvbnMsIG9ubHkgYSBzaW5nbGUgcmVwb3NpdG9yeSB3YXMgZ2l2ZW4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRyZXBvKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1JlcG9zaXRvcnkgIicuJGluZGV4LiciICgnLmpzb25fZW5jb2RlKCRyZXBvKS4nKSBzaG91bGQgYmUgYW4gYXJyYXksICcuZ2V0dHlwZSgkcmVwbykuJyBnaXZlbicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaXNzZXQoJHJlcG9bJ3R5cGUnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdSZXBvc2l0b3J5ICInLiRpbmRleC4nIiAoJy5qc29uX2VuY29kZSgkcmVwbykuJykgbXVzdCBoYXZlIGEgdHlwZSBkZWZpbmVkJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRuYW1lID0gc2VsZjo6Z2VuZXJhdGVSZXBvc2l0b3J5TmFtZSgkaW5kZXgsICRyZXBvLCAkcmVwb3MpOwogICAgICAgICAgICBpZiAoJHJlcG9bJ3R5cGUnXSA9PT0gJ2ZpbGVzeXN0ZW0nKSB7CiAgICAgICAgICAgICAgICAkcmVwb3NbJG5hbWVdID0gbmV3IEZpbGVzeXN0ZW1SZXBvc2l0b3J5KCRyZXBvWydqc29uJ10pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJlcG9zWyRuYW1lXSA9ICRybS0+Y3JlYXRlUmVwb3NpdG9yeSgkcmVwb1sndHlwZSddLCAkcmVwbywgJGluZGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXBvczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnR8c3RyaW5nICRpbmRleAogICAgICogQHBhcmFtIGFycmF5e3VybD86IHN0cmluZ30gJHJlcG8KICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPiAkZXhpc3RpbmdSZXBvcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVSZXBvc2l0b3J5TmFtZSgkaW5kZXgsIGFycmF5ICRyZXBvLCBhcnJheSAkZXhpc3RpbmdSZXBvcykKICAgIHsKICAgICAgICAkbmFtZSA9IGlzX2ludCgkaW5kZXgpICYmIGlzc2V0KCRyZXBvWyd1cmwnXSkgPyBQcmVnOjpyZXBsYWNlKCd7Xmh0dHBzPzovL31pJywgJycsICRyZXBvWyd1cmwnXSkgOiAkaW5kZXg7CiAgICAgICAgd2hpbGUgKGlzc2V0KCRleGlzdGluZ1JlcG9zWyRuYW1lXSkpIHsKICAgICAgICAgICAgJG5hbWUgLj0gJzInOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRuYW1lOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgovKioKICogQnVpbGRzIGxpc3Qgb2YgcGFja2FnZSBmcm9tIFBFQVIgY2hhbm5lbC4KICoKICogUGFja2FnZXMgcmVhZCBmcm9tIGNoYW5uZWwgYXJlIG5hbWVkIGFzICdwZWFyLXtjaGFubmVsTmFtZX0ve3BhY2thZ2VOYW1lfScKICogYW5kIGhhcyBhbGlhc2VkIGFzICdwZWFyLXtjaGFubmVsQWxpYXN9L3twYWNrYWdlTmFtZX0nCiAqCiAqIEBhdXRob3IgQmVuamFtaW4gRWJlcmxlaSA8a29udGFrdEBiZWJlcmxlaS5kZT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAZGVwcmVjYXRlZAogKiBAcHJpdmF0ZQogKi8KY2xhc3MgUGVhclJlcG9zaXRvcnkgZXh0ZW5kcyBBcnJheVJlcG9zaXRvcnkKewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIFBFQVIgcmVwb3NpdG9yeSBoYXMgYmVlbiByZW1vdmVkIGZyb20gQ29tcG9zZXIgMi54Jyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXFZhbGlkYXRpbmdBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKCi8qKgogKiBQYWNrYWdlIHJlcG9zaXRvcnkuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBhY2thZ2VSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5CnsKICAgIC8qKiBAdmFyIG1peGVkW10gKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIGZpbGVzeXN0ZW0gcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl7cGFja2FnZTogbWl4ZWRbXX0gJGNvbmZpZyBwYWNrYWdlIGRlZmluaXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRjb25maWcpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgpOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnWydwYWNrYWdlJ107CgogICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIGFycmF5IG9mIHBhY2thZ2UgZGVmaW5pdGlvbnMKICAgICAgICBpZiAoIWlzX251bWVyaWMoa2V5KCR0aGlzLT5jb25maWcpKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uZmlnID0gYXJyYXkoJHRoaXMtPmNvbmZpZyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcmVwb3NpdG9yeSAocmVhZHMgZmlsZSwgb3IgcmVtb3RlIGFkZHJlc3MpLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgICRsb2FkZXIgPSBuZXcgVmFsaWRhdGluZ0FycmF5TG9hZGVyKG5ldyBBcnJheUxvYWRlcihudWxsLCB0cnVlKSwgdHJ1ZSk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbmZpZyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkbG9hZGVyLT5sb2FkKCRwYWNrYWdlKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRSZXBvc2l0b3J5RXhjZXB0aW9uKCdBIHJlcG9zaXRvcnkgb2YgdHlwZSAicGFja2FnZSIgY29udGFpbnMgYW4gaW52YWxpZCBwYWNrYWdlIGRlZmluaXRpb246ICcuJGUtPmdldE1lc3NhZ2UoKS4iXG5cbkludmFsaWQgcGFja2FnZSBkZWZpbml0aW9uOlxuIi5qc29uX2VuY29kZSgkcGFja2FnZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIFByZWc6OnJlcGxhY2UoJ3teYXJyYXkgfScsICdwYWNrYWdlICcsIHBhcmVudDo6Z2V0UmVwb05hbWUoKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CgovKioKICogQ29tcG9zaXRlIHJlcG9zaXRvcnkuCiAqCiAqIEBhdXRob3IgQmVhdSBTaW1lbnNlbiA8YmVhdUBkZmx5ZGV2LmNvbT4KICovCmNsYXNzIENvbXBvc2l0ZVJlcG9zaXRvcnkgaW1wbGVtZW50cyBSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogTGlzdCBvZiByZXBvc2l0b3JpZXMKICAgICAqIEB2YXIgUmVwb3NpdG9yeUludGVyZmFjZVtdCiAgICAgKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcmllczsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZVtdICRyZXBvc2l0b3JpZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRyZXBvc2l0b3JpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcmllcyBhcyAkcmVwbykgewogICAgICAgICAgICAkdGhpcy0+YWRkUmVwb3NpdG9yeSgkcmVwbyk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdjb21wb3NpdGUgcmVwbyAoJy5pbXBsb2RlKCcsICcsIGFycmF5X21hcChmdW5jdGlvbiAoJHJlcG8pIHsKICAgICAgICAgICAgcmV0dXJuICRyZXBvLT5nZXRSZXBvTmFtZSgpOwogICAgICAgIH0sICR0aGlzLT5yZXBvc2l0b3JpZXMpKS4nKSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCB0aGUgd3JhcHBlZCByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgaWYgKCRyZXBvc2l0b3J5LT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZSgkbmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgJHBhY2thZ2UgPSAkcmVwb3NpdG9yeS0+ZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQgPSBudWxsKQogICAgewogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcmVwb3NpdG9yeS0+ZmluZFBhY2thZ2VzKCRuYW1lLCAkY29uc3RyYWludCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2VzID8gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJHBhY2thZ2VzKSA6IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRuYW1lc0ZvdW5kID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkcmVzdWx0ID0gJHJlcG9zaXRvcnktPmxvYWRQYWNrYWdlcygkcGFja2FnZU1hcCwgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgJHN0YWJpbGl0eUZsYWdzLCAkYWxyZWFkeUxvYWRlZCk7CiAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHJlc3VsdFsncGFja2FnZXMnXTsKICAgICAgICAgICAgJG5hbWVzRm91bmRbXSA9ICRyZXN1bHRbJ25hbWVzRm91bmQnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3BhY2thZ2VzJyA9PiAkcGFja2FnZXMgPyBjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCAkcGFja2FnZXMpIDogYXJyYXkoKSwKICAgICAgICAgICAgJ25hbWVzRm91bmQnID0+ICRuYW1lc0ZvdW5kID8gYXJyYXlfdW5pcXVlKGNhbGxfdXNlcl9mdW5jX2FycmF5KCdhcnJheV9tZXJnZScsICRuYW1lc0ZvdW5kKSkgOiBhcnJheSgpLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCRxdWVyeSwgJG1vZGUgPSAwLCAkdHlwZSA9IG51bGwpCiAgICB7CiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgLyogQHZhciAkcmVwb3NpdG9yeSBSZXBvc2l0b3J5SW50ZXJmYWNlICovCiAgICAgICAgICAgICRtYXRjaGVzW10gPSAkcmVwb3NpdG9yeS0+c2VhcmNoKCRxdWVyeSwgJG1vZGUsICR0eXBlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWF0Y2hlcyA/IGNhbGxfdXNlcl9mdW5jX2FycmF5KCdhcnJheV9tZXJnZScsICRtYXRjaGVzKSA6IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXMgPyBjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCAkcGFja2FnZXMpIDogYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgICRyZXN1bHRzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkcmVzdWx0c1tdID0gJHJlcG9zaXRvcnktPmdldFByb3ZpZGVycygkcGFja2FnZU5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHRzID8gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJHJlc3VsdHMpIDogYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgaWYgKCRyZXBvc2l0b3J5IGluc3RhbmNlb2YgV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkcmVwb3NpdG9yeS0+cmVtb3ZlUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgJHRvdGFsID0gMDsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkdG90YWwgKz0gJHJlcG9zaXRvcnktPmNvdW50KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRvdGFsOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgcmVwb3NpdG9yeS4KICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgaWYgKCRyZXBvc2l0b3J5IGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3NpdG9yeS0+Z2V0UmVwb3NpdG9yaWVzKCkgYXMgJHJlcG8pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRSZXBvc2l0b3J5KCRyZXBvKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXNbXSA9ICRyZXBvc2l0b3J5OwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKLyoqCiAqIEluc3RhbGxhYmxlIHJlcG9zaXRvcnkgaW50ZXJmYWNlLgogKgogKiBKdXN0IHVzZWQgdG8gdGFnIGluc3RhbGxlZCByZXBvc2l0b3JpZXMgc28gdGhlIGJhc2UgY2xhc3NlcyBjYW4gYWN0IGRpZmZlcmVudGx5IG9uIEFsaWFzIHBhY2thZ2VzCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmludGVyZmFjZSBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlIGV4dGVuZHMgV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgcGFja2FnZXMgd2VyZSBuZXZlciBpbnN0YWxsZWQgaW4gdGhpcyByZXBvc2l0b3J5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0ZyZXNoKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwoKLyoqCiAqIEZpbGVzeXN0ZW0gcmVwb3NpdG9yeS4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgRmlsZXN5c3RlbVJlcG9zaXRvcnkgZXh0ZW5kcyBXcml0YWJsZUFycmF5UmVwb3NpdG9yeQp7CiAgICAvKiogQHZhciBKc29uRmlsZSAqLwogICAgcHJvdGVjdGVkICRmaWxlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkZHVtcFZlcnNpb25zOwogICAgLyoqIEB2YXIgP1Jvb3RQYWNrYWdlSW50ZXJmYWNlICovCiAgICBwcml2YXRlICRyb290UGFja2FnZTsKICAgIC8qKiBAdmFyIEZpbGVzeXN0ZW0gKi8KICAgIHByaXZhdGUgJGZpbGVzeXN0ZW07CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBmaWxlc3lzdGVtIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIEpzb25GaWxlICAgICAgICAgICAgICAkcmVwb3NpdG9yeUZpbGUgcmVwb3NpdG9yeSBqc29uIGZpbGUKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgJGR1bXBWZXJzaW9ucwogICAgICogQHBhcmFtID9Sb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UgICAgTXVzdCBiZSBwcm92aWRlZCBpZiAkZHVtcFZlcnNpb25zIGlzIHRydWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEpzb25GaWxlICRyZXBvc2l0b3J5RmlsZSwgJGR1bXBWZXJzaW9ucyA9IGZhbHNlLCBSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UgPSBudWxsLCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtID0gbnVsbCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCk7CiAgICAgICAgJHRoaXMtPmZpbGUgPSAkcmVwb3NpdG9yeUZpbGU7CiAgICAgICAgJHRoaXMtPmR1bXBWZXJzaW9ucyA9ICRkdW1wVmVyc2lvbnM7CiAgICAgICAgJHRoaXMtPnJvb3RQYWNrYWdlID0gJHJvb3RQYWNrYWdlOwogICAgICAgICR0aGlzLT5maWxlc3lzdGVtID0gJGZpbGVzeXN0ZW0gPzogbmV3IEZpbGVzeXN0ZW07CiAgICAgICAgaWYgKCRkdW1wVmVyc2lvbnMgJiYgISRyb290UGFja2FnZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignRXhwZWN0ZWQgYSByb290IHBhY2thZ2UgaW5zdGFuY2UgaWYgJGR1bXBWZXJzaW9ucyBpcyB0cnVlJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcmVwb3NpdG9yeSAocmVhZHMgZmlsZSwgb3IgcmVtb3RlIGFkZHJlc3MpLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgIGlmICghJHRoaXMtPmZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRkYXRhID0gJHRoaXMtPmZpbGUtPnJlYWQoKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydwYWNrYWdlcyddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJGRhdGFbJ3BhY2thZ2VzJ107CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZXMgPSAkZGF0YTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydkZXYtcGFja2FnZS1uYW1lcyddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnNldERldlBhY2thZ2VOYW1lcygkZGF0YVsnZGV2LXBhY2thZ2UtbmFtZXMnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHBhY2thZ2VzKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBwYXJzZSBwYWNrYWdlIGxpc3QgZnJvbSB0aGUgcmVwb3NpdG9yeScpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFJlcG9zaXRvcnlFeGNlcHRpb24oJ0ludmFsaWQgcmVwb3NpdG9yeSBkYXRhIGluICcuJHRoaXMtPmZpbGUtPmdldFBhdGgoKS4nLCBwYWNrYWdlcyBjb3VsZCBub3QgYmUgbG9hZGVkOiBbJy5nZXRfY2xhc3MoJGUpLiddICcuJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQoKICAgICAgICAkbG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKG51bGwsIHRydWUpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZURhdGEpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkbG9hZGVyLT5sb2FkKCRwYWNrYWdlRGF0YSk7CiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlbG9hZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzID0gbnVsbDsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogV3JpdGVzIHdyaXRhYmxlIHJlcG9zaXRvcnkuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkZGV2TW9kZSwgSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlcikKICAgIHsKICAgICAgICAkZGF0YSA9IGFycmF5KCdwYWNrYWdlcycgPT4gYXJyYXkoKSwgJ2RldicgPT4gJGRldk1vZGUsICdkZXYtcGFja2FnZS1uYW1lcycgPT4gYXJyYXkoKSk7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcigpOwoKICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGRpcmVjdG9yeSBpcyBjcmVhdGVkIHNvIHdlIGNhbiByZWFscGF0aCBpdAogICAgICAgIC8vIGFzIHJlYWxwYXRoKCkgZG9lcyBzb21lIGFkZGl0aW9uYWwgbm9ybWFsaXphdGlvbnMgd2l0aCBuZXR3b3JrIHBhdGhzIHRoYXQgbm9ybWFsaXplUGF0aCBkb2VzIG5vdAogICAgICAgIC8vIGFuZCB3ZSBuZWVkIHRvIGZpbmQgc2hvcnRlc3QgcGF0aCBjb3JyZWN0bHkKICAgICAgICAkcmVwb0RpciA9IGRpcm5hbWUoJHRoaXMtPmZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkcmVwb0Rpcik7CgogICAgICAgICRyZXBvRGlyID0gJHRoaXMtPmZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgocmVhbHBhdGgoJHJlcG9EaXIpKTsKICAgICAgICAkaW5zdGFsbFBhdGhzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldENhbm9uaWNhbFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHBrZ0FycmF5ID0gJGR1bXBlci0+ZHVtcCgkcGFja2FnZSk7CiAgICAgICAgICAgICRwYXRoID0gJGluc3RhbGxhdGlvbk1hbmFnZXItPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKICAgICAgICAgICAgJGluc3RhbGxQYXRoID0gbnVsbDsKICAgICAgICAgICAgaWYgKCcnICE9PSAkcGF0aCAmJiBudWxsICE9PSAkcGF0aCkgewogICAgICAgICAgICAgICAgJG5vcm1hbGl6ZWRQYXRoID0gJHRoaXMtPmZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHRoaXMtPmZpbGVzeXN0ZW0tPmlzQWJzb2x1dGVQYXRoKCRwYXRoKSA/ICRwYXRoIDogZ2V0Y3dkKCkgLiAnLycgLiAkcGF0aCk7CiAgICAgICAgICAgICAgICAkaW5zdGFsbFBhdGggPSAkdGhpcy0+ZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aCgkcmVwb0RpciwgJG5vcm1hbGl6ZWRQYXRoLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaW5zdGFsbFBhdGhzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJGluc3RhbGxQYXRoOwoKICAgICAgICAgICAgJHBrZ0FycmF5WydpbnN0YWxsLXBhdGgnXSA9ICRpbnN0YWxsUGF0aDsKICAgICAgICAgICAgJGRhdGFbJ3BhY2thZ2VzJ11bXSA9ICRwa2dBcnJheTsKCiAgICAgICAgICAgIC8vIG9ubHkgd3JpdGUgdG8gdGhlIGZpbGVzIHRoZSBuYW1lcyB3aGljaCBhcmUgcmVhbGx5IGluc3RhbGxlZCwgYXMgd2UgcmVjZWl2ZSB0aGUgZnVsbCBsaXN0CiAgICAgICAgICAgIC8vIG9mIGRldiBwYWNrYWdlIG5hbWVzIGJlZm9yZSB0aGV5IGdldCBpbnN0YWxsZWQgZHVyaW5nIGNvbXBvc2VyIGluc3RhbGwKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICR0aGlzLT5kZXZQYWNrYWdlTmFtZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnZGV2LXBhY2thZ2UtbmFtZXMnXVtdID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc29ydCgkZGF0YVsnZGV2LXBhY2thZ2UtbmFtZXMnXSk7CiAgICAgICAgdXNvcnQoJGRhdGFbJ3BhY2thZ2VzJ10sIGZ1bmN0aW9uICgkYSwgJGIpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYVsnbmFtZSddLCAkYlsnbmFtZSddKTsKICAgICAgICB9KTsKCiAgICAgICAgJHRoaXMtPmZpbGUtPndyaXRlKCRkYXRhKTsKCiAgICAgICAgaWYgKCR0aGlzLT5kdW1wVmVyc2lvbnMpIHsKICAgICAgICAgICAgJHZlcnNpb25zID0gJHRoaXMtPmdlbmVyYXRlSW5zdGFsbGVkVmVyc2lvbnMoJGluc3RhbGxhdGlvbk1hbmFnZXIsICRpbnN0YWxsUGF0aHMsICRkZXZNb2RlLCAkcmVwb0Rpcik7CgogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkcmVwb0Rpci4nL2luc3RhbGxlZC5waHAnLCAnPD9waHAgcmV0dXJuICcgLiAkdGhpcy0+ZHVtcFRvUGhwQ29kZSgkdmVyc2lvbnMpIC4gJzsnLiJcbiIpOwogICAgICAgICAgICAkaW5zdGFsbGVkVmVyc2lvbnNDbGFzcyA9IGZpbGVfZ2V0X2NvbnRlbnRzKF9fRElSX18uJy8uLi9JbnN0YWxsZWRWZXJzaW9ucy5waHAnKTsKICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHJlcG9EaXIuJy9JbnN0YWxsZWRWZXJzaW9ucy5waHAnLCAkaW5zdGFsbGVkVmVyc2lvbnNDbGFzcyk7CgogICAgICAgICAgICBcQ29tcG9zZXJcSW5zdGFsbGVkVmVyc2lvbnM6OnJlbG9hZCgkdmVyc2lvbnMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxtaXhlZD4gJGFycmF5CiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZHVtcFRvUGhwQ29kZShhcnJheSAkYXJyYXkgPSBhcnJheSgpLCAkbGV2ZWwgPSAwKQogICAgewogICAgICAgICRsaW5lcyA9ICJhcnJheShcbiI7CiAgICAgICAgJGxldmVsKys7CgogICAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAkbGluZXMgLj0gc3RyX3JlcGVhdCgnICAgICcsICRsZXZlbCk7CiAgICAgICAgICAgICRsaW5lcyAuPSBpc19pbnQoJGtleSkgPyAka2V5IC4gJyA9PiAnIDogJ1wnJyAuICRrZXkgLiAnXCcgPT4gJzsKCiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZXMgLj0gJHRoaXMtPmR1bXBUb1BocENvZGUoJHZhbHVlLCAkbGV2ZWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbGluZXMgLj0gImFycmF5KCksXG4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJGtleSA9PT0gJ2luc3RhbGxfcGF0aCcgJiYgaXNfc3RyaW5nKCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZmlsZXN5c3RlbS0+aXNBYnNvbHV0ZVBhdGgoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICRsaW5lcyAuPSB2YXJfZXhwb3J0KCR2YWx1ZSwgdHJ1ZSkgLiAiLFxuIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmVzIC49ICJfX0RJUl9fIC4gIiAuIHZhcl9leHBvcnQoJy8nIC4gJHZhbHVlLCB0cnVlKSAuICIsXG4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGxpbmVzIC49IHZhcl9leHBvcnQoJHZhbHVlLCB0cnVlKSAuICIsXG4iOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkbGluZXMgLj0gc3RyX3JlcGVhdCgnICAgICcsICRsZXZlbCAtIDEpIC4gJyknIC4gKCRsZXZlbCAtIDEgPT0gMCA/ICcnIDogIixcbiIpOwoKICAgICAgICByZXR1cm4gJGxpbmVzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkaW5zdGFsbFBhdGhzCiAgICAgKiBAcGFyYW0gYm9vbCAkZGV2TW9kZQogICAgICogQHBhcmFtIHN0cmluZyAkcmVwb0RpcgogICAgICoKICAgICAqIEByZXR1cm4gP2FycmF5PG1peGVkPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdlbmVyYXRlSW5zdGFsbGVkVmVyc2lvbnMoSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlciwgYXJyYXkgJGluc3RhbGxQYXRocywgJGRldk1vZGUsICRyZXBvRGlyKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmR1bXBWZXJzaW9ucykgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRkZXZQYWNrYWdlcyA9IGFycmF5X2ZsaXAoJHRoaXMtPmRldlBhY2thZ2VOYW1lcyk7CiAgICAgICAgJHZlcnNpb25zID0gYXJyYXkoJ3ZlcnNpb25zJyA9PiBhcnJheSgpKTsKICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+Z2V0UGFja2FnZXMoKTsKICAgICAgICAkcGFja2FnZXNbXSA9ICRyb290UGFja2FnZSA9ICR0aGlzLT5yb290UGFja2FnZTsKICAgICAgICB3aGlsZSAoJHJvb3RQYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRyb290UGFja2FnZSA9ICRyb290UGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAkcGFja2FnZXNbXSA9ICRyb290UGFja2FnZTsKICAgICAgICB9CgogICAgICAgIC8vIGFkZCByZWFsIGluc3RhbGxlZCBwYWNrYWdlcwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVmZXJlbmNlID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSkgewogICAgICAgICAgICAgICAgJHJlZmVyZW5jZSA9ICRwYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSA9PT0gJ3NvdXJjZScgPyAkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkgOiAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChudWxsID09PSAkcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICAgICAkcmVmZXJlbmNlID0gKCRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSA/OiAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKSA/OiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJHRvID0gJHRoaXMtPmZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgocmVhbHBhdGgoZ2V0Y3dkKCkpKTsKICAgICAgICAgICAgICAgICRpbnN0YWxsUGF0aCA9ICR0aGlzLT5maWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoKCRyZXBvRGlyLCAkdG8sIHRydWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGluc3RhbGxQYXRoID0gJGluc3RhbGxQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlLT5nZXROYW1lKCldID0gYXJyYXkoCiAgICAgICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAndmVyc2lvbicgPT4gJHBhY2thZ2UtPmdldFZlcnNpb24oKSwKICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0VHlwZSgpLAogICAgICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gJGluc3RhbGxQYXRoLAogICAgICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAkcmVmZXJlbmNlLAogICAgICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gaXNzZXQoJGRldlBhY2thZ2VzWyRwYWNrYWdlLT5nZXROYW1lKCldKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1sncm9vdCddID0gJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlLT5nZXROYW1lKCldOwogICAgICAgICAgICAgICAgdW5zZXQoJHZlcnNpb25zWydyb290J11bJ2Rldl9yZXF1aXJlbWVudCddKTsKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1sncm9vdCddWyduYW1lJ10gPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICAgICAgJHZlcnNpb25zWydyb290J11bJ2RldiddID0gJGRldk1vZGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGFkZCBwcm92aWRlZC9yZXBsYWNlZCBwYWNrYWdlcwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkaXNEZXZQYWNrYWdlID0gaXNzZXQoJGRldlBhY2thZ2VzWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcGxhY2VzKCkgYXMgJHJlcGxhY2UpIHsKICAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGUgcGxhdGZvcm0gcmVwbGFjZXMgYXMgd2hlbiB0aGV5IGFyZSByZWFsbHkgdGhlcmUgd2UgY2FuIG5vdCBjaGVjayBmb3IgdGhlaXIgcHJlc2VuY2UKICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRyZXBsYWNlLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRyZXBsYWNlLT5nZXRUYXJnZXQoKV1bJ2Rldl9yZXF1aXJlbWVudCddKSkgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uc1sndmVyc2lvbnMnXVskcmVwbGFjZS0+Z2V0VGFyZ2V0KCldWydkZXZfcmVxdWlyZW1lbnQnXSA9ICRpc0RldlBhY2thZ2U7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoISRpc0RldlBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHJlcGxhY2UtPmdldFRhcmdldCgpXVsnZGV2X3JlcXVpcmVtZW50J10gPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXBsYWNlZCA9ICRyZXBsYWNlLT5nZXRQcmV0dHlDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICBpZiAoJHJlcGxhY2VkID09PSAnc2VsZi52ZXJzaW9uJykgewogICAgICAgICAgICAgICAgICAgICRyZXBsYWNlZCA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR2ZXJzaW9uc1sndmVyc2lvbnMnXVskcmVwbGFjZS0+Z2V0VGFyZ2V0KCldWydyZXBsYWNlZCddKSB8fCAhaW5fYXJyYXkoJHJlcGxhY2VkLCAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHJlcGxhY2UtPmdldFRhcmdldCgpXVsncmVwbGFjZWQnXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHJlcGxhY2UtPmdldFRhcmdldCgpXVsncmVwbGFjZWQnXVtdID0gJHJlcGxhY2VkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRQcm92aWRlcygpIGFzICRwcm92aWRlKSB7CiAgICAgICAgICAgICAgICAvLyBleGNsdWRlIHBsYXRmb3JtIHByb3ZpZGVzIGFzIHdoZW4gdGhleSBhcmUgcmVhbGx5IHRoZXJlIHdlIGNhbiBub3QgY2hlY2sgZm9yIHRoZWlyIHByZXNlbmNlCiAgICAgICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcHJvdmlkZS0+Z2V0VGFyZ2V0KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR2ZXJzaW9uc1sndmVyc2lvbnMnXVskcHJvdmlkZS0+Z2V0VGFyZ2V0KCldWydkZXZfcmVxdWlyZW1lbnQnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHByb3ZpZGUtPmdldFRhcmdldCgpXVsnZGV2X3JlcXVpcmVtZW50J10gPSAkaXNEZXZQYWNrYWdlOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCEkaXNEZXZQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwcm92aWRlLT5nZXRUYXJnZXQoKV1bJ2Rldl9yZXF1aXJlbWVudCddID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcHJvdmlkZWQgPSAkcHJvdmlkZS0+Z2V0UHJldHR5Q29uc3RyYWludCgpOwogICAgICAgICAgICAgICAgaWYgKCRwcm92aWRlZCA9PT0gJ3NlbGYudmVyc2lvbicpIHsKICAgICAgICAgICAgICAgICAgICAkcHJvdmlkZWQgPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHByb3ZpZGUtPmdldFRhcmdldCgpXVsncHJvdmlkZWQnXSkgfHwgIWluX2FycmF5KCRwcm92aWRlZCwgJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwcm92aWRlLT5nZXRUYXJnZXQoKV1bJ3Byb3ZpZGVkJ10sIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwcm92aWRlLT5nZXRUYXJnZXQoKV1bJ3Byb3ZpZGVkJ11bXSA9ICRwcm92aWRlZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gYWRkIGFsaWFzZXMKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCEkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlLT5nZXROYW1lKCldWydhbGlhc2VzJ11bXSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbnNbJ3Jvb3QnXVsnYWxpYXNlcyddW10gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBrc29ydCgkdmVyc2lvbnNbJ3ZlcnNpb25zJ10pOwogICAgICAgIGtzb3J0KCR2ZXJzaW9ucyk7CgogICAgICAgIHJldHVybiAkdmVyc2lvbnM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3M7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcQ2FjaGU7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcR2l0SHViOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdpdEh1YkRyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkb3duZXI7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcmVwb3NpdG9yeTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgc3RyaW5nPiBNYXAgb2YgdGFnIG5hbWUgdG8gaWRlbnRpZmllciAqLwogICAgcHJvdGVjdGVkICR0YWdzOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiBicmFuY2ggbmFtZSB0byBpZGVudGlmaWVyICovCiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHJvb3RJZGVudGlmaWVyOwogICAgLyoqIEB2YXIgbWl4ZWRbXSAqLwogICAgcHJvdGVjdGVkICRyZXBvRGF0YTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkaGFzSXNzdWVzID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGlzUHJpdmF0ZSA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkaXNBcmNoaXZlZCA9IGZhbHNlOwogICAgLyoqIEB2YXIgYXJyYXk8aW50LCBhcnJheXt0eXBlOiBzdHJpbmcsIHVybDogc3RyaW5nfT58ZmFsc2V8bnVsbCAqLwogICAgcHJpdmF0ZSAkZnVuZGluZ0luZm87CgogICAgLyoqCiAgICAgKiBHaXQgRHJpdmVyCiAgICAgKgogICAgICogQHZhciA/R2l0RHJpdmVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZ2l0RHJpdmVyID0gbnVsbDsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBQcmVnOjptYXRjaCgnI14oPzooPzpodHRwcz98Z2l0KTovLyhbXi9dKykvfGdpdEAoW146XSspOi8/KShbXi9dKykvKC4rPykoPzpcLmdpdHwvKT8kIycsICR0aGlzLT51cmwsICRtYXRjaCk7CiAgICAgICAgJHRoaXMtPm93bmVyID0gJG1hdGNoWzNdOwogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5ID0gJG1hdGNoWzRdOwogICAgICAgICR0aGlzLT5vcmlnaW5VcmwgPSBzdHJ0b2xvd2VyKCFlbXB0eSgkbWF0Y2hbMV0pID8gJG1hdGNoWzFdIDogJG1hdGNoWzJdKTsKICAgICAgICBpZiAoJHRoaXMtPm9yaWdpblVybCA9PT0gJ3d3dy5naXRodWIuY29tJykgewogICAgICAgICAgICAkdGhpcy0+b3JpZ2luVXJsID0gJ2dpdGh1Yi5jb20nOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y2FjaGUgPSBuZXcgQ2FjaGUoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXJlcG8tZGlyJykuJy8nLiR0aGlzLT5vcmlnaW5VcmwuJy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkpOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CgogICAgICAgIGlmICgkdGhpcy0+Y29uZmlnLT5nZXQoJ3VzZS1naXRodWItYXBpJykgPT09IGZhbHNlIHx8IChpc3NldCgkdGhpcy0+cmVwb0NvbmZpZ1snbm8tYXBpJ10pICYmICR0aGlzLT5yZXBvQ29uZmlnWyduby1hcGknXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNldHVwR2l0RHJpdmVyKCR0aGlzLT51cmwpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZldGNoUm9vdElkZW50aWZpZXIoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3J5VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2h0dHBzOi8vJy4kdGhpcy0+b3JpZ2luVXJsLicvJy4kdGhpcy0+b3duZXIuJy8nLiR0aGlzLT5yZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdElkZW50aWZpZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0VXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ2h0dHBzOi8vJyAuICR0aGlzLT5vcmlnaW5VcmwgLiAnLycuJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeS4nLmdpdCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0QXBpVXJsKCkKICAgIHsKICAgICAgICBpZiAoJ2dpdGh1Yi5jb20nID09PSAkdGhpcy0+b3JpZ2luVXJsKSB7CiAgICAgICAgICAgICRhcGlVcmwgPSAnYXBpLmdpdGh1Yi5jb20nOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRhcGlVcmwgPSAkdGhpcy0+b3JpZ2luVXJsIC4gJy9hcGkvdjMnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdodHRwczovLycgLiAkYXBpVXJsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0U291cmNlKCRpZGVudGlmaWVyKTsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5pc1ByaXZhdGUpIHsKICAgICAgICAgICAgLy8gUHJpdmF0ZSBHaXRIdWIgcmVwb3NpdG9yaWVzIHNob3VsZCBiZSBhY2Nlc3NlZCB1c2luZyB0aGUKICAgICAgICAgICAgLy8gU1NIIHZlcnNpb24gb2YgdGhlIFVSTC4KICAgICAgICAgICAgJHVybCA9ICR0aGlzLT5nZW5lcmF0ZVNzaFVybCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR1cmwgPSAkdGhpcy0+Z2V0VXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICdnaXQnLCAndXJsJyA9PiAkdXJsLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAkdXJsID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy96aXBiYWxsLycuJGlkZW50aWZpZXI7CgogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ3ppcCcsICd1cmwnID0+ICR1cmwsICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyLCAnc2hhc3VtJyA9PiAnJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENhY2hlKCRpZGVudGlmaWVyKSAmJiAkcmVzID0gJHRoaXMtPmNhY2hlLT5yZWFkKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgJGNvbXBvc2VyID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRCYXNlQ29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPndyaXRlKCRpZGVudGlmaWVyLCBqc29uX2VuY29kZSgkY29tcG9zZXIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAgICAgLy8gc3BlY2lhbHMgZm9yIGdpdGh1YgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ3N1cHBvcnQnXVsnc291cmNlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGxhYmVsID0gYXJyYXlfc2VhcmNoKCRpZGVudGlmaWVyLCAkdGhpcy0+Z2V0VGFncygpKSA/OiBhcnJheV9zZWFyY2goJGlkZW50aWZpZXIsICR0aGlzLT5nZXRCcmFuY2hlcygpKSA/OiAkaWRlbnRpZmllcjsKICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ3N1cHBvcnQnXVsnc291cmNlJ10gPSBzcHJpbnRmKCdodHRwczovLyVzLyVzLyVzL3RyZWUvJXMnLCAkdGhpcy0+b3JpZ2luVXJsLCAkdGhpcy0+b3duZXIsICR0aGlzLT5yZXBvc2l0b3J5LCAkbGFiZWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ3N1cHBvcnQnXVsnaXNzdWVzJ10pICYmICR0aGlzLT5oYXNJc3N1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ3N1cHBvcnQnXVsnaXNzdWVzJ10gPSBzcHJpbnRmKCdodHRwczovLyVzLyVzLyVzL2lzc3VlcycsICR0aGlzLT5vcmlnaW5VcmwsICR0aGlzLT5vd25lciwgJHRoaXMtPnJlcG9zaXRvcnkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ2FiYW5kb25lZCddKSAmJiAkdGhpcy0+aXNBcmNoaXZlZCkgewogICAgICAgICAgICAgICAgICAgICRjb21wb3NlclsnYWJhbmRvbmVkJ10gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ2Z1bmRpbmcnXSkgJiYgJGZ1bmRpbmcgPSAkdGhpcy0+Z2V0RnVuZGluZ0luZm8oKSkgewogICAgICAgICAgICAgICAgICAgICRjb21wb3NlclsnZnVuZGluZyddID0gJGZ1bmRpbmc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gJGNvbXBvc2VyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxpbnQsIGFycmF5e3R5cGU6IHN0cmluZywgdXJsOiBzdHJpbmd9PnxmYWxzZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEZ1bmRpbmdJbmZvKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmZ1bmRpbmdJbmZvKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZnVuZGluZ0luZm87CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPm9yaWdpblVybCAhPT0gJ2dpdGh1Yi5jb20nKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZnVuZGluZ0luZm8gPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKGFycmF5KCR0aGlzLT5nZXRBcGlVcmwoKSAuICcvcmVwb3MvJy4kdGhpcy0+b3duZXIuJy8nLiR0aGlzLT5yZXBvc2l0b3J5LicvY29udGVudHMvLmdpdGh1Yi9GVU5ESU5HLnltbCcsICR0aGlzLT5nZXRBcGlVcmwoKSAuICcvcmVwb3MvJy4kdGhpcy0+b3duZXIuJy8uZ2l0aHViL2NvbnRlbnRzL0ZVTkRJTkcueW1sJykgYXMgJGZpbGUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRmaWxlLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAncmV0cnktYXV0aC1mYWlsdXJlJyA9PiBmYWxzZSwKICAgICAgICAgICAgICAgICkpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVtcHR5KCRyZXNwb25zZVsnY29udGVudCddKSB8fCAkcmVzcG9uc2VbJ2VuY29kaW5nJ10gIT09ICdiYXNlNjQnIHx8ICEoJGZ1bmRpbmcgPSBiYXNlNjRfZGVjb2RlKCRyZXNwb25zZVsnY29udGVudCddKSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJGZ1bmRpbmcpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZnVuZGluZ0luZm8gPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgICRrZXkgPSBudWxsOwogICAgICAgIGZvcmVhY2ggKFByZWc6OnNwbGl0KCd7XHI/XG59JywgJGZ1bmRpbmcpIGFzICRsaW5lKSB7CiAgICAgICAgICAgICRsaW5lID0gdHJpbSgkbGluZSk7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XihcdyspXHMqOlxzKiguKykkfScsICRsaW5lLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15cWyguKilcXSg/OlxzKiMuKik/JH0nLCAkbWF0Y2hbMl0sICRtYXRjaDIpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWFwKCd0cmltJywgUHJlZzo6c3BsaXQoJ3tbXCciXT9ccyosXHMqW1wnIl0/fScsICRtYXRjaDJbMV0pKSBhcyAkaXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBhcnJheSgndHlwZScgPT4gJG1hdGNoWzFdLCAndXJsJyA9PiB0cmltKCRpdGVtLCAnIlwnICcpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoUHJlZzo6aXNNYXRjaCgne14oW14jXS4qPykoXHMrIy4qKT8kfScsICRtYXRjaFsyXSwgJG1hdGNoMikpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBhcnJheSgndHlwZScgPT4gJG1hdGNoWzFdLCAndXJsJyA9PiB0cmltKCRtYXRjaDJbMV0sICciXCcgJykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGtleSA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZWlmIChQcmVnOjppc01hdGNoKCd7XihcdyspXHMqOlxzKiNccyokfScsICRsaW5lLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAka2V5ID0gJG1hdGNoWzFdOwogICAgICAgICAgICB9IGVsc2VpZiAoJGtleSAmJiBQcmVnOjppc01hdGNoKCd7Xi1ccyooLispKFxzKyMuKik/JH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoJ3R5cGUnID0+ICRrZXksICd1cmwnID0+IHRyaW0oJG1hdGNoWzFdLCAnIlwnICcpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdCBhcyAka2V5ID0+ICRpdGVtKSB7CiAgICAgICAgICAgIHN3aXRjaCAoJGl0ZW1bJ3R5cGUnXSkgewogICAgICAgICAgICAgICAgY2FzZSAndGlkZWxpZnQnOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vdGlkZWxpZnQuY29tL2Z1bmRpbmcvZ2l0aHViLycgLiAkaXRlbVsndXJsJ107CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdnaXRodWInOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vZ2l0aHViLmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3BhdHJlb24nOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vd3d3LnBhdHJlb24uY29tLycgLiBiYXNlbmFtZSgkaXRlbVsndXJsJ10pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnb3RlY2hpZSc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9vdGVjaGllLmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ29wZW5fY29sbGVjdGl2ZSc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9vcGVuY29sbGVjdGl2ZS5jb20vJyAuIGJhc2VuYW1lKCRpdGVtWyd1cmwnXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdsaWJlcmFwYXknOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vbGliZXJhcGF5LmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2tvX2ZpJzoKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WyRrZXldWyd1cmwnXSA9ICdodHRwczovL2tvLWZpLmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2lzc3VlaHVudCc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9pc3N1ZWh1bnQuaW8vci8nIC4gJGl0ZW1bJ3VybCddOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnY29tbXVuaXR5X2JyaWRnZSc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9mdW5kaW5nLmNvbW11bml0eWJyaWRnZS5vcmcvcHJvamVjdHMvJyAuIGJhc2VuYW1lKCRpdGVtWyd1cmwnXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZnVuZGluZ0luZm8gPSAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVDb250ZW50KCRmaWxlLCAkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXRBcGlVcmwoKSAuICcvcmVwb3MvJy4kdGhpcy0+b3duZXIuJy8nLiR0aGlzLT5yZXBvc2l0b3J5LicvY29udGVudHMvJyAuICRmaWxlIC4gJz9yZWY9Jy51cmxlbmNvZGUoJGlkZW50aWZpZXIpOwogICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVzb3VyY2UpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgaWYgKGVtcHR5KCRyZXNvdXJjZVsnY29udGVudCddKSB8fCAkcmVzb3VyY2VbJ2VuY29kaW5nJ10gIT09ICdiYXNlNjQnIHx8ICEoJGNvbnRlbnQgPSBiYXNlNjRfZGVjb2RlKCRyZXNvdXJjZVsnY29udGVudCddKSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgcmV0cmlldmUgJyAuICRmaWxlIC4gJyBmb3IgJy4kaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2hhbmdlRGF0ZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0Q2hhbmdlRGF0ZSgkaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICAkcmVzb3VyY2UgPSAkdGhpcy0+Z2V0QXBpVXJsKCkgLiAnL3JlcG9zLycuJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeS4nL2NvbW1pdHMvJy51cmxlbmNvZGUoJGlkZW50aWZpZXIpOwogICAgICAgICRjb21taXQgPSAkdGhpcy0+Z2V0Q29udGVudHMoJHJlc291cmNlKS0+ZGVjb2RlSnNvbigpOwoKICAgICAgICByZXR1cm4gbmV3IFxEYXRlVGltZSgkY29tbWl0Wydjb21taXQnXVsnY29tbWl0dGVyJ11bJ2RhdGUnXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldFRhZ3MoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0YWdzID0gYXJyYXkoKTsKICAgICAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy90YWdzP3Blcl9wYWdlPTEwMCc7CgogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+Z2V0Q29udGVudHMoJHJlc291cmNlKTsKICAgICAgICAgICAgICAgICR0YWdzRGF0YSA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRhZ3NEYXRhIGFzICR0YWcpIHsKICAgICAgICAgICAgICAgICAgICAkdGFnc1skdGFnWyduYW1lJ11dID0gJHRhZ1snY29tbWl0J11bJ3NoYSddOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXROZXh0UGFnZSgkcmVzcG9uc2UpOwogICAgICAgICAgICB9IHdoaWxlICgkcmVzb3VyY2UpOwoKICAgICAgICAgICAgJHRoaXMtPnRhZ3MgPSAkdGFnczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldEJyYW5jaGVzKCk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+YnJhbmNoZXMpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gYXJyYXkoKTsKICAgICAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy9naXQvcmVmcy9oZWFkcz9wZXJfcGFnZT0xMDAnOwoKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmdldENvbnRlbnRzKCRyZXNvdXJjZSk7CiAgICAgICAgICAgICAgICAkYnJhbmNoRGF0YSA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGJyYW5jaERhdGEgYXMgJGJyYW5jaCkgewogICAgICAgICAgICAgICAgICAgICRuYW1lID0gc3Vic3RyKCRicmFuY2hbJ3JlZiddLCAxMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRuYW1lICE9PSAnZ2gtcGFnZXMnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1skbmFtZV0gPSAkYnJhbmNoWydvYmplY3QnXVsnc2hhJ107CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXROZXh0UGFnZSgkcmVzcG9uc2UpOwogICAgICAgICAgICB9IHdoaWxlICgkcmVzb3VyY2UpOwoKICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzID0gJGJyYW5jaGVzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5icmFuY2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHMoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgJHVybCwgJGRlZXAgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJyNeKCg/Omh0dHBzP3xnaXQpOi8vKFteL10rKS98Z2l0QChbXjpdKyk6Lz8pKFteL10rKS8oLis/KSg/OlwuZ2l0fC8pPyQjJywgJHVybCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRvcmlnaW5VcmwgPSAhZW1wdHkoJG1hdGNoZXNbMl0pID8gJG1hdGNoZXNbMl0gOiAkbWF0Y2hlc1szXTsKICAgICAgICBpZiAoIWluX2FycmF5KHN0cnRvbG93ZXIoUHJlZzo6cmVwbGFjZSgne153d3dcLn1pJywgJycsICRvcmlnaW5VcmwpKSwgJGNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1NraXBwaW5nIEdpdEh1YiBkcml2ZXIgZm9yICcuJHVybC4nIGJlY2F1c2UgdGhlIE9wZW5TU0wgUEhQIGV4dGVuc2lvbiBpcyBtaXNzaW5nLicsIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZXMgYmFjayB0aGUgbG9hZGVkIDxnaXRodWItYXBpPi9yZXBvcy88b3duZXI+LzxyZXBvPiByZXN1bHQKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkW118bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb0RhdGEoKQogICAgewogICAgICAgICR0aGlzLT5mZXRjaFJvb3RJZGVudGlmaWVyKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb0RhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBTU0ggVVJMCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCkKICAgIHsKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkdGhpcy0+b3JpZ2luVXJsLCAnOicpKSB7CiAgICAgICAgICAgIHJldHVybiAnc3NoOi8vZ2l0QCcgLiAkdGhpcy0+b3JpZ2luVXJsIC4gJy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdnaXRAJyAuICR0aGlzLT5vcmlnaW5VcmwgLiAnOicuJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeS4nLmdpdCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRmZXRjaGluZ1JlcG9EYXRhCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDb250ZW50cygkdXJsLCAkZmV0Y2hpbmdSZXBvRGF0YSA9IGZhbHNlKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmdldENvbnRlbnRzKCR1cmwpOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkZ2l0SHViVXRpbCA9IG5ldyBHaXRIdWIoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHRoaXMtPmh0dHBEb3dubG9hZGVyKTsKCiAgICAgICAgICAgIHN3aXRjaCAoJGUtPmdldENvZGUoKSkgewogICAgICAgICAgICAgICAgY2FzZSA0MDE6CiAgICAgICAgICAgICAgICBjYXNlIDQwNDoKICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gYXV0aG9yaXplIG9ubHkgaWYgd2UgYXJlIGZldGNoaW5nIHRoZSBtYWluIC9yZXBvcy9mb28vYmFyIGRhdGEsIG90aGVyd2lzZSBpdCBtdXN0IGJlIGEgcmVhbCA0MDQKICAgICAgICAgICAgICAgICAgICBpZiAoISRmZXRjaGluZ1JlcG9EYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCRnaXRIdWJVdGlsLT5hdXRob3JpemVPQXV0aCgkdGhpcy0+b3JpZ2luVXJsKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmF0dGVtcHRDbG9uZUZhbGxiYWNrKCk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICdkdW1teScpLCAyMDAsIGFycmF5KCksICdudWxsJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkc2NvcGVzSXNzdWVkID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAkc2NvcGVzTmVlZGVkID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGhlYWRlcnMgPSAkZS0+Z2V0SGVhZGVycygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc2NvcGVzID0gUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaGVhZGVycywgJ1gtT0F1dGgtU2NvcGVzJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzY29wZXNJc3N1ZWQgPSBleHBsb2RlKCcgJywgJHNjb3Blcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRzY29wZXMgPSBSZXNwb25zZTo6ZmluZEhlYWRlclZhbHVlKCRoZWFkZXJzLCAnWC1BY2NlcHRlZC1PQXV0aC1TY29wZXMnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNjb3Blc05lZWRlZCA9IGV4cGxvZGUoJyAnLCAkc2NvcGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkc2NvcGVzRmFpbGVkID0gYXJyYXlfZGlmZigkc2NvcGVzTmVlZGVkLCAkc2NvcGVzSXNzdWVkKTsKICAgICAgICAgICAgICAgICAgICAvLyBub24tYXV0aGVudGljYXRlZCByZXF1ZXN0cyBnZXQgbm8gc2NvcGVzTmVlZGVkLCBzbyBhc2sgZm9yIGNyZWRlbnRpYWxzCiAgICAgICAgICAgICAgICAgICAgLy8gYXV0aGVudGljYXRlZCByZXF1ZXN0cyB3aGljaCBmYWlsZWQgc29tZSBzY29wZXMgc2hvdWxkIGFzayBmb3IgbmV3IGNyZWRlbnRpYWxzIHRvbwogICAgICAgICAgICAgICAgICAgIGlmICghJGhlYWRlcnMgfHwgIWNvdW50KCRzY29wZXNOZWVkZWQpIHx8IGNvdW50KCRzY29wZXNGYWlsZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRnaXRIdWJVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJHRoaXMtPm9yaWdpblVybCwgJ1lvdXIgR2l0SHViIGNyZWRlbnRpYWxzIGFyZSByZXF1aXJlZCB0byBmZXRjaCBwcml2YXRlIHJlcG9zaXRvcnkgbWV0YWRhdGEgKDxpbmZvPicuJHRoaXMtPnVybC4nPC9pbmZvPiknKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmdldENvbnRlbnRzKCR1cmwpOwoKICAgICAgICAgICAgICAgIGNhc2UgNDAzOgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkdGhpcy0+b3JpZ2luVXJsKSAmJiAkZ2l0SHViVXRpbC0+YXV0aG9yaXplT0F1dGgoJHRoaXMtPm9yaWdpblVybCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpICYmICRmZXRjaGluZ1JlcG9EYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hdHRlbXB0Q2xvbmVGYWxsYmFjaygpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAnZHVtbXknKSwgMjAwLCBhcnJheSgpLCAnbnVsbCcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdGVkID0gJGdpdEh1YlV0aWwtPmlzUmF0ZUxpbWl0ZWQoKGFycmF5KSAkZS0+Z2V0SGVhZGVycygpKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmhhc0F1dGhlbnRpY2F0aW9uKCR0aGlzLT5vcmlnaW5VcmwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkdpdEh1YiBBUEkgbGltaXQgZXhoYXVzdGVkLiBGYWlsZWQgdG8gZ2V0IG1ldGFkYXRhIGZvciB0aGUgJy4kdGhpcy0+dXJsLicgcmVwb3NpdG9yeSwgdHJ5IHJ1bm5pbmcgaW4gaW50ZXJhY3RpdmUgbW9kZSBzbyB0aGF0IHlvdSBjYW4gZW50ZXIgeW91ciBHaXRIdWIgY3JlZGVudGlhbHMgdG8gaW5jcmVhc2UgdGhlIEFQSSBsaW1pdDwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkdGhpcy0+b3JpZ2luVXJsLCAnQVBJIGxpbWl0IGV4aGF1c3RlZC4gRW50ZXIgeW91ciBHaXRIdWIgY3JlZGVudGlhbHMgdG8gZ2V0IGEgbGFyZ2VyIEFQSSBsaW1pdCAoPGluZm8+Jy4kdGhpcy0+dXJsLic8L2luZm8+KScpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJHJhdGVMaW1pdGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXQgPSAkZ2l0SHViVXRpbC0+Z2V0UmF0ZUxpbWl0KCRlLT5nZXRIZWFkZXJzKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+R2l0SHViIEFQSSBsaW1pdCAoJWQgY2FsbHMvaHIpIGlzIGV4aGF1c3RlZC4gWW91IGFyZSBhbHJlYWR5IGF1dGhvcml6ZWQgc28geW91IGhhdmUgdG8gd2FpdCB1bnRpbCAlcyBiZWZvcmUgZG9pbmcgbW9yZSByZXF1ZXN0czwvZXJyb3I+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXRbJ2xpbWl0J10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmF0ZUxpbWl0WydyZXNldCddCiAgICAgICAgICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEZldGNoIHJvb3QgaWRlbnRpZmllciBmcm9tIEdpdEh1YgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZldGNoUm9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cmVwb0RhdGEpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHJlcG9EYXRhVXJsID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5yZXBvRGF0YSA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVwb0RhdGFVcmwsIHRydWUpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpID09PSA0OTkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hdHRlbXB0Q2xvbmVGYWxsYmFjaygpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5yZXBvRGF0YSAmJiBudWxsICE9PSAkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vd25lciA9ICR0aGlzLT5yZXBvRGF0YVsnb3duZXInXVsnbG9naW4nXTsKICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSA9ICR0aGlzLT5yZXBvRGF0YVsnbmFtZSddOwoKICAgICAgICAkdGhpcy0+aXNQcml2YXRlID0gIWVtcHR5KCR0aGlzLT5yZXBvRGF0YVsncHJpdmF0ZSddKTsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlcG9EYXRhWydkZWZhdWx0X2JyYW5jaCddKSkgewogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAkdGhpcy0+cmVwb0RhdGFbJ2RlZmF1bHRfYnJhbmNoJ107CiAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCR0aGlzLT5yZXBvRGF0YVsnbWFzdGVyX2JyYW5jaCddKSkgewogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAkdGhpcy0+cmVwb0RhdGFbJ21hc3Rlcl9icmFuY2gnXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAnbWFzdGVyJzsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmhhc0lzc3VlcyA9ICFlbXB0eSgkdGhpcy0+cmVwb0RhdGFbJ2hhc19pc3N1ZXMnXSk7CiAgICAgICAgJHRoaXMtPmlzQXJjaGl2ZWQgPSAhZW1wdHkoJHRoaXMtPnJlcG9EYXRhWydhcmNoaXZlZCddKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwaHBzdGFuLWltcHVyZQogICAgICoKICAgICAqIEByZXR1cm4gdHJ1ZQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXR0ZW1wdENsb25lRmFsbGJhY2soKQogICAgewogICAgICAgICR0aGlzLT5pc1ByaXZhdGUgPSB0cnVlOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBJZiB0aGlzIHJlcG9zaXRvcnkgbWF5IGJlIHByaXZhdGUgKGhhcmQgdG8gc2F5IGZvciBzdXJlLAogICAgICAgICAgICAvLyBHaXRIdWIgcmV0dXJucyA0MDQgZm9yIHByaXZhdGUgcmVwb3NpdG9yaWVzKSBhbmQgd2UKICAgICAgICAgICAgLy8gY2Fubm90IGFzayBmb3IgYXV0aGVudGljYXRpb24gY3JlZGVudGlhbHMgKGJlY2F1c2Ugd2UKICAgICAgICAgICAgLy8gYXJlIG5vdCBpbnRlcmFjdGl2ZSkgdGhlbiB3ZSBmYWxsYmFjayB0byBHaXREcml2ZXIuCiAgICAgICAgICAgICR0aGlzLT5zZXR1cEdpdERyaXZlcigkdGhpcy0+Z2VuZXJhdGVTc2hVcmwoKSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkdGhpcy0+Z2l0RHJpdmVyID0gbnVsbDsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkZhaWxlZCB0byBjbG9uZSB0aGUgJy4kdGhpcy0+Z2VuZXJhdGVTc2hVcmwoKS4nIHJlcG9zaXRvcnksIHRyeSBydW5uaW5nIGluIGludGVyYWN0aXZlIG1vZGUgc28gdGhhdCB5b3UgY2FuIGVudGVyIHlvdXIgR2l0SHViIGNyZWRlbnRpYWxzPC9lcnJvcj4nKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXR1cEdpdERyaXZlcigkdXJsKQogICAgewogICAgICAgICR0aGlzLT5naXREcml2ZXIgPSBuZXcgR2l0RHJpdmVyKAogICAgICAgICAgICBhcnJheSgndXJsJyA9PiAkdXJsKSwKICAgICAgICAgICAgJHRoaXMtPmlvLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLAogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIsCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+Z2l0RHJpdmVyLT5pbml0aWFsaXplKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXROZXh0UGFnZShSZXNwb25zZSAkcmVzcG9uc2UpCiAgICB7CiAgICAgICAgJGhlYWRlciA9ICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdsaW5rJyk7CiAgICAgICAgaWYgKCEkaGVhZGVyKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGxpbmtzID0gZXhwbG9kZSgnLCcsICRoZWFkZXIpOwogICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnezwoLis/KT47ICpyZWw9Im5leHQifScsICRsaW5rLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXFBlcmZvcmNlOwoKLyoqCiAqIEBhdXRob3IgTWF0dCBXaGl0dG9tIDxNYXR0LldoaXR0b21AdmV0ZXJhbnN1bml0ZWQuY29tPgogKi8KY2xhc3MgUGVyZm9yY2VEcml2ZXIgZXh0ZW5kcyBWY3NEcml2ZXIKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJGRlcG90OwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJGJyYW5jaDsKICAgIC8qKiBAdmFyID9QZXJmb3JjZSAqLwogICAgcHJvdGVjdGVkICRwZXJmb3JjZSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlcG90ID0gJHRoaXMtPnJlcG9Db25maWdbJ2RlcG90J107CiAgICAgICAgJHRoaXMtPmJyYW5jaCA9ICcnOwogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPnJlcG9Db25maWdbJ2JyYW5jaCddKSkgewogICAgICAgICAgICAkdGhpcy0+YnJhbmNoID0gJHRoaXMtPnJlcG9Db25maWdbJ2JyYW5jaCddOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmluaXRQZXJmb3JjZSgkdGhpcy0+cmVwb0NvbmZpZyk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5wNExvZ2luKCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5jaGVja1N0cmVhbSgpOwoKICAgICAgICAkdGhpcy0+cGVyZm9yY2UtPndyaXRlUDRDbGllbnRTcGVjKCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5jb25uZWN0Q2xpZW50KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHJlcG9Db25maWcKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbml0UGVyZm9yY2UoJHJlcG9Db25maWcpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+cGVyZm9yY2UpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghQ2FjaGU6OmlzVXNhYmxlKChzdHJpbmcpICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1BlcmZvcmNlRHJpdmVyIHJlcXVpcmVzIGEgdXNhYmxlIGNhY2hlIGRpcmVjdG9yeSwgYW5kIGl0IGxvb2tzIGxpa2UgeW91IHNldCBpdCB0byBiZSBkaXNhYmxlZCcpOwogICAgICAgIH0KCiAgICAgICAgJHJlcG9EaXIgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKSAuICcvJyAuICR0aGlzLT5kZXBvdDsKICAgICAgICAkdGhpcy0+cGVyZm9yY2UgPSBQZXJmb3JjZTo6Y3JlYXRlKCRyZXBvQ29uZmlnLCAkdGhpcy0+Z2V0VXJsKCksICRyZXBvRGlyLCAkdGhpcy0+cHJvY2VzcywgJHRoaXMtPmlvKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wZXJmb3JjZS0+Z2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJyYW5jaDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wZXJmb3JjZS0+Z2V0QnJhbmNoZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBlcmZvcmNlLT5nZXRUYWdzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAndHlwZScgPT4gJ3BlcmZvcmNlJywKICAgICAgICAgICAgJ3VybCcgPT4gJHRoaXMtPnJlcG9Db25maWdbJ3VybCddLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllciwKICAgICAgICAgICAgJ3A0dXNlcicgPT4gJHRoaXMtPnBlcmZvcmNlLT5nZXRVc2VyKCksCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0NvbXBvc2VyRmlsZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAkY29tcG9zZXJJbmZvID0gJHRoaXMtPnBlcmZvcmNlLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCcvLycgLiAkdGhpcy0+ZGVwb3QgLiAnLycgLiAkaWRlbnRpZmllcik7CgogICAgICAgIHJldHVybiAhZW1wdHkoJGNvbXBvc2VySW5mbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGVudHMoJHVybCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgXEJhZE1ldGhvZENhbGxFeGNlcHRpb24oJ05vdCBpbXBsZW1lbnRlZC91c2VkIGluIFBlcmZvcmNlRHJpdmVyJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRkZWVwIHx8IFByZWc6OmlzTWF0Y2goJyNcYihwZXJmb3JjZXxwNClcYiNpJywgJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIFBlcmZvcmNlOjpjaGVja1NlcnZlckV4aXN0cygkdXJsLCBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoKQogICAgewogICAgICAgICR0aGlzLT5wZXJmb3JjZS0+Y2xlYW51cENsaWVudFNwZWMoKTsKICAgICAgICAkdGhpcy0+cGVyZm9yY2UgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlcG90KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlcG90OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5icmFuY2g7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3M7Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFVybDsKdXNlIENvbXBvc2VyXFV0aWxcR2l0IGFzIEdpdFV0aWw7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdpdERyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICAvKiogQHZhciBhcnJheTxpbnR8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiB0YWcgbmFtZSAoY2FuIGJlIHR1cm5lZCB0byBhbiBpbnQgYnkgcGhwIGlmIGl0IGlzIGEgbnVtZXJpYyBuYW1lKSB0byBpZGVudGlmaWVyICovCiAgICBwcm90ZWN0ZWQgJHRhZ3M7CiAgICAvKiogQHZhciBhcnJheTxpbnR8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiBicmFuY2ggbmFtZSAoY2FuIGJlIHR1cm5lZCB0byBhbiBpbnQgYnkgcGhwIGlmIGl0IGlzIGEgbnVtZXJpYyBuYW1lKSB0byBpZGVudGlmaWVyICovCiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHJvb3RJZGVudGlmaWVyOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHJlcG9EaXI7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzTG9jYWxQYXRoKCR0aGlzLT51cmwpKSB7CiAgICAgICAgICAgICR0aGlzLT51cmwgPSBQcmVnOjpyZXBsYWNlKCd7W1xcL11cLmdpdC8/JH0nLCAnJywgJHRoaXMtPnVybCk7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCR0aGlzLT51cmwpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byByZWFkIHBhY2thZ2UgaW5mb3JtYXRpb24gZnJvbSAnLiR0aGlzLT51cmwuJyBhcyB0aGUgcGF0aCBkb2VzIG5vdCBleGlzdCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5yZXBvRGlyID0gJHRoaXMtPnVybDsKICAgICAgICAgICAgJGNhY2hlVXJsID0gcmVhbHBhdGgoJHRoaXMtPnVybCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFDYWNoZTo6aXNVc2FibGUoKHN0cmluZykgJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0dpdERyaXZlciByZXF1aXJlcyBhIHVzYWJsZSBjYWNoZSBkaXJlY3RvcnksIGFuZCBpdCBsb29rcyBsaWtlIHlvdSBzZXQgaXQgdG8gYmUgZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnJlcG9EaXIgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKSAuICcvJyAuIFByZWc6OnJlcGxhY2UoJ3tbXmEtejAtOS5dfWknLCAnLScsICR0aGlzLT51cmwpIC4gJy8nOwoKICAgICAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgICAgICRmcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKGRpcm5hbWUoJHRoaXMtPnJlcG9EaXIpKTsKCiAgICAgICAgICAgIGlmICghaXNfd3JpdGFibGUoZGlybmFtZSgkdGhpcy0+cmVwb0RpcikpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NhbiBub3QgY2xvbmUgJy4kdGhpcy0+dXJsLicgdG8gYWNjZXNzIHBhY2thZ2UgaW5mb3JtYXRpb24uIFRoZSAiJy5kaXJuYW1lKCR0aGlzLT5yZXBvRGlyKS4nIiBkaXJlY3RvcnkgaXMgbm90IHdyaXRhYmxlIGJ5IHRoZSBjdXJyZW50IHVzZXIuJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XnNzaDovL1teQF0rQFteOl0rOlteMC05XSt9JywgJHRoaXMtPnVybCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGUgc291cmNlIFVSTCAnLiR0aGlzLT51cmwuJyBpcyBpbnZhbGlkLCBzc2ggVVJMcyBzaG91bGQgaGF2ZSBhIHBvcnQgbnVtYmVyIGFmdGVyICI6Ii4nLiJcbiIuJ1VzZSBzc2g6Ly9naXRAZXhhbXBsZS5jb206MjIvcGF0aCBvciBqdXN0IGdpdEBleGFtcGxlLmNvbTpwYXRoIGlmIHlvdSBkbyBub3Qgd2FudCB0byBwcm92aWRlIGEgcGFzc3dvcmQgb3IgY3VzdG9tIHBvcnQuJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRnaXRVdGlsID0gbmV3IEdpdFV0aWwoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJGZzKTsKICAgICAgICAgICAgaWYgKCEkZ2l0VXRpbC0+c3luY01pcnJvcigkdGhpcy0+dXJsLCAkdGhpcy0+cmVwb0RpcikpIHsKICAgICAgICAgICAgICAgIGlmICghaXNfZGlyKCR0aGlzLT5yZXBvRGlyKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGNsb25lICcuJHRoaXMtPnVybC4nIHRvIHJlYWQgcGFja2FnZSBpbmZvcm1hdGlvbiBmcm9tIGl0Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5GYWlsZWQgdG8gdXBkYXRlICcuJHRoaXMtPnVybC4nLCBwYWNrYWdlIGluZm9ybWF0aW9uIGZyb20gdGhpcyByZXBvc2l0b3J5IG1heSBiZSBvdXRkYXRlZDwvZXJyb3I+Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjYWNoZVVybCA9ICR0aGlzLT51cmw7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Z2V0VGFncygpOwogICAgICAgICR0aGlzLT5nZXRCcmFuY2hlcygpOwoKICAgICAgICAkdGhpcy0+Y2FjaGUgPSBuZXcgQ2FjaGUoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXJlcG8tZGlyJykuJy8nLlByZWc6OnJlcGxhY2UoJ3tbXmEtejAtOS5dfWknLCAnLScsIFVybDo6c2FuaXRpemUoJGNhY2hlVXJsKSkpOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cm9vdElkZW50aWZpZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gJ21hc3Rlcic7CgogICAgICAgICAgICAvLyBzZWxlY3QgY3VycmVudGx5IGNoZWNrZWQgb3V0IGJyYW5jaCBpZiBtYXN0ZXIgaXMgbm90IGF2YWlsYWJsZQogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGJyYW5jaCAtLW5vLWNvbG9yJywgJG91dHB1dCwgJHRoaXMtPnJlcG9EaXIpOwogICAgICAgICAgICAkYnJhbmNoZXMgPSAkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KTsKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgnKiBtYXN0ZXInLCAkYnJhbmNoZXMpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYnJhbmNoZXMgYXMgJGJyYW5jaCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoICYmIFByZWc6OmlzTWF0Y2goJ3teXCogKyhcUyspfScsICRicmFuY2gsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdElkZW50aWZpZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KCd0eXBlJyA9PiAnZ2l0JywgJ3VybCcgPT4gJHRoaXMtPmdldFVybCgpLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJHJlc291cmNlID0gc3ByaW50ZignJXM6JXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkaWRlbnRpZmllciksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRmaWxlKSk7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoc3ByaW50ZignZ2l0IHNob3cgJXMnLCAkcmVzb3VyY2UpLCAkY29udGVudCwgJHRoaXMtPnJlcG9EaXIpOwoKICAgICAgICBpZiAoIXRyaW0oJGNvbnRlbnQpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb250ZW50OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoc3ByaW50ZigKICAgICAgICAgICAgJ2dpdCAtYyBsb2cuc2hvd1NpZ25hdHVyZT1mYWxzZSBsb2cgLTEgLS1mb3JtYXQ9JSVhdCAlcycsCiAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRpZGVudGlmaWVyKQogICAgICAgICksICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKTsKCiAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJ0AnLnRyaW0oJG91dHB1dCksIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0aGlzLT50YWdzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgc2hvdy1yZWYgLS10YWdzIC0tZGVyZWZlcmVuY2UnLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0Rpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvdXRwdXQgPSAkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkdGFnKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRhZyAmJiBQcmVnOjppc01hdGNoKCd7XihbYS1mMC05XXs0MH0pIHJlZnMvdGFncy8oXFMrPykoXF5ce1x9KT8kfScsICR0YWcsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dGFnc1skbWF0Y2hbMl1dID0gKHN0cmluZykgJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QnJhbmNoZXMoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+YnJhbmNoZXMpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgYnJhbmNoIC0tbm8tY29sb3IgLS1uby1hYmJyZXYgLXYnLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0Rpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRicmFuY2gpIHsKICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoICYmICFQcmVnOjppc01hdGNoKCd7XiAqW14vXSsvSEVBRCB9JywgJGJyYW5jaCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne14oPzpcKiApPyAqKFxTKykgKihbYS1mMC05XSspKD86IC4qKT8kfScsICRicmFuY2gsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWyRtYXRjaFsxXV0gPSAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+YnJhbmNoZXMgPSAkYnJhbmNoZXM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmJyYW5jaGVzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdXBwb3J0cyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkdXJsLCAkZGVlcCA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcjKF5naXQ6Ly98XC5naXQvPyR8Z2l0KD86b2xpdGUpP0B8Ly9naXRcLnwvL2dpdGh1Yi5jb20vKSNpJywgJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBsb2NhbCBmaWxlc3lzdGVtCiAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzTG9jYWxQYXRoKCR1cmwpKSB7CiAgICAgICAgICAgICR1cmwgPSBGaWxlc3lzdGVtOjpnZXRQbGF0Zm9ybVBhdGgoJHVybCk7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCR1cmwpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGEgZ2l0IHJlcG8gaW4gdGhhdCBwYXRoCiAgICAgICAgICAgIGlmICgkcHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IHRhZycsICRvdXRwdXQsICR1cmwpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkZGVlcCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkZ2l0VXRpbCA9IG5ldyBHaXRVdGlsKCRpbywgJGNvbmZpZywgbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pLCBuZXcgRmlsZXN5c3RlbSgpKTsKICAgICAgICBHaXRVdGlsOjpjbGVhbkVudigpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkZ2l0VXRpbC0+cnVuQ29tbWFuZChmdW5jdGlvbiAoJHVybCkgewogICAgICAgICAgICAgICAgcmV0dXJuICdnaXQgbHMtcmVtb3RlIC0taGVhZHMgLS0gJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpOwogICAgICAgICAgICB9LCAkdXJsLCBzeXNfZ2V0X3RlbXBfZGlyKCkpOwogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CnVzZSBDb21wb3NlclxVdGlsXFN2biBhcyBTdm5VdGlsOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgVGlsbCBLbGFtcGFlY2tlbCA8dGlsbEBwaHAubmV0PgogKi8KY2xhc3MgU3ZuRHJpdmVyIGV4dGVuZHMgVmNzRHJpdmVyCnsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRiYXNlVXJsOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiB0YWcgbmFtZSB0byBpZGVudGlmaWVyICovCiAgICBwcm90ZWN0ZWQgJHRhZ3M7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gTWFwIG9mIGJyYW5jaCBuYW1lIHRvIGlkZW50aWZpZXIgKi8KICAgIHByb3RlY3RlZCAkYnJhbmNoZXM7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHJvb3RJZGVudGlmaWVyOwoKICAgIC8qKiBAdmFyIHN0cmluZ3xmYWxzZSAqLwogICAgcHJvdGVjdGVkICR0cnVua1BhdGggPSAndHJ1bmsnOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzUGF0aCA9ICdicmFuY2hlcyc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdGFnc1BhdGggPSAndGFncyc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcGFja2FnZVBhdGggPSAnJzsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkY2FjaGVDcmVkZW50aWFscyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBAdmFyIFxDb21wb3NlclxVdGlsXFN2bgogICAgICovCiAgICBwcml2YXRlICR1dGlsOwoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgICR0aGlzLT51cmwgPSAkdGhpcy0+YmFzZVVybCA9IHJ0cmltKHNlbGY6Om5vcm1hbGl6ZVVybCgkdGhpcy0+dXJsKSwgJy8nKTsKCiAgICAgICAgU3ZuVXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5yZXBvQ29uZmlnWyd0cnVuay1wYXRoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT50cnVua1BhdGggPSAkdGhpcy0+cmVwb0NvbmZpZ1sndHJ1bmstcGF0aCddOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlcG9Db25maWdbJ2JyYW5jaGVzLXBhdGgnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzUGF0aCA9ICR0aGlzLT5yZXBvQ29uZmlnWydicmFuY2hlcy1wYXRoJ107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVwb0NvbmZpZ1sndGFncy1wYXRoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT50YWdzUGF0aCA9ICR0aGlzLT5yZXBvQ29uZmlnWyd0YWdzLXBhdGgnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3N2bi1jYWNoZS1jcmVkZW50aWFscycsICR0aGlzLT5yZXBvQ29uZmlnKSkgewogICAgICAgICAgICAkdGhpcy0+Y2FjaGVDcmVkZW50aWFscyA9IChib29sKSAkdGhpcy0+cmVwb0NvbmZpZ1snc3ZuLWNhY2hlLWNyZWRlbnRpYWxzJ107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVwb0NvbmZpZ1sncGFja2FnZS1wYXRoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlUGF0aCA9ICcvJyAuIHRyaW0oJHRoaXMtPnJlcG9Db25maWdbJ3BhY2thZ2UtcGF0aCddLCAnLycpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlICE9PSAoJHBvcyA9IHN0cnJwb3MoJHRoaXMtPnVybCwgJy8nIC4gJHRoaXMtPnRydW5rUGF0aCkpKSB7CiAgICAgICAgICAgICR0aGlzLT5iYXNlVXJsID0gc3Vic3RyKCR0aGlzLT51cmwsIDAsICRwb3MpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNhY2hlID0gbmV3IENhY2hlKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZXBvLWRpcicpLicvJy5QcmVnOjpyZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCBVcmw6OnNhbml0aXplKCR0aGlzLT5iYXNlVXJsKSkpOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CgogICAgICAgICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgICAgICR0aGlzLT5nZXRUYWdzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdElkZW50aWZpZXIgPzogJHRoaXMtPnRydW5rUGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICdzdm4nLCAndXJsJyA9PiAkdGhpcy0+YmFzZVVybCwgJ3JlZmVyZW5jZScgPT4gJGlkZW50aWZpZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3QoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jYWNoZSAmJiBQcmVnOjppc01hdGNoKCd7QFxkKyR9JywgJGlkZW50aWZpZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikgJiYgJHJlcyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkaWRlbnRpZmllci4nLmpzb24nKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRCYXNlQ29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CiAgICAgICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAkZS0+Z2V0TWVzc2FnZSgpOwogICAgICAgICAgICAgICAgaWYgKHN0cmlwb3MoJG1lc3NhZ2UsICdwYXRoIG5vdCBmb3VuZCcpID09PSBmYWxzZSAmJiBzdHJpcG9zKCRtZXNzYWdlLCAnc3ZuOiB3YXJuaW5nOiBXMTYwMDEzJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyByZW1lbWJlciBhIG5vdC1leGlzdGVudCBjb21wb3Nlci5qc29uCiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+d3JpdGUoJGlkZW50aWZpZXIuJy5qc29uJywganNvbl9lbmNvZGUoJGNvbXBvc2VyKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gJGNvbXBvc2VyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgICRpZGVudGlmaWVyID0gJy8nIC4gdHJpbSgkaWRlbnRpZmllciwgJy8nKSAuICcvJzsKCiAgICAgICAgUHJlZzo6bWF0Y2goJ3teKC4rPykoQFxkKyk/LyR9JywgJGlkZW50aWZpZXIsICRtYXRjaCk7CiAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbMl0pKSB7CiAgICAgICAgICAgICRwYXRoID0gJG1hdGNoWzFdOwogICAgICAgICAgICAkcmV2ID0gJG1hdGNoWzJdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwYXRoID0gJGlkZW50aWZpZXI7CiAgICAgICAgICAgICRyZXYgPSAnJzsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRyZXNvdXJjZSA9ICRwYXRoLiRmaWxlOwogICAgICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPmV4ZWN1dGUoJ3N2biBjYXQnLCAkdGhpcy0+YmFzZVVybCAuICRyZXNvdXJjZSAuICRyZXYpOwogICAgICAgICAgICBpZiAoIXRyaW0oJG91dHB1dCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbigkZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJGlkZW50aWZpZXIgPSAnLycgLiB0cmltKCRpZGVudGlmaWVyLCAnLycpIC4gJy8nOwoKICAgICAgICBQcmVnOjptYXRjaCgne14oLis/KShAXGQrKT8vJH0nLCAkaWRlbnRpZmllciwgJG1hdGNoKTsKICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsyXSkpIHsKICAgICAgICAgICAgJHBhdGggPSAkbWF0Y2hbMV07CiAgICAgICAgICAgICRyZXYgPSAkbWF0Y2hbMl07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhdGggPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgJHJldiA9ICcnOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5leGVjdXRlKCdzdm4gaW5mbycsICR0aGlzLT5iYXNlVXJsIC4gJHBhdGggLiAkcmV2KTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkbGluZSkgewogICAgICAgICAgICBpZiAoJGxpbmUgJiYgUHJlZzo6aXNNYXRjaCgne15MYXN0IENoYW5nZWQgRGF0ZTogKFteKF0rKX0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJG1hdGNoWzFdLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnRhZ3MpIHsKICAgICAgICAgICAgJHRhZ3MgPSBhcnJheSgpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT50YWdzUGF0aCAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQgPSAkdGhpcy0+ZXhlY3V0ZSgnc3ZuIGxzIC0tdmVyYm9zZScsICR0aGlzLT5iYXNlVXJsIC4gJy8nIC4gJHRoaXMtPnRhZ3NQYXRoKTsKICAgICAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2Nlc3MtPnNwbGl0TGluZXMoJG91dHB1dCkgYXMgJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSB0cmltKCRsaW5lKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsaW5lICYmIFByZWc6OmlzTWF0Y2goJ3teXHMqKFxTKykuKj8oXFMrKVxzKiR9JywgJGxpbmUsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWF0Y2hbMV0sICRtYXRjaFsyXSkgJiYgJG1hdGNoWzJdICE9PSAnLi8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRhZ3NbcnRyaW0oJG1hdGNoWzJdLCAnLycpXSA9ICR0aGlzLT5idWlsZElkZW50aWZpZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcvJyAuICR0aGlzLT50YWdzUGF0aCAuICcvJyAuICRtYXRjaFsyXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoWzFdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnRhZ3MgPSAkdGFnczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgpOwoKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkdGhpcy0+dHJ1bmtQYXRoKSB7CiAgICAgICAgICAgICAgICAkdHJ1bmtQYXJlbnQgPSAkdGhpcy0+YmFzZVVybCAuICcvJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0cnVua1BhcmVudCA9ICR0aGlzLT5iYXNlVXJsIC4gJy8nIC4gJHRoaXMtPnRydW5rUGF0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5leGVjdXRlKCdzdm4gbHMgLS12ZXJib3NlJywgJHRydW5rUGFyZW50KTsKICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSB0cmltKCRsaW5lKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmUgJiYgUHJlZzo6aXNNYXRjaCgne15ccyooXFMrKS4qPyhcUyspXHMqJH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoWzFdLCAkbWF0Y2hbMl0pICYmICRtYXRjaFsyXSA9PT0gJy4vJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWyd0cnVuayddID0gJHRoaXMtPmJ1aWxkSWRlbnRpZmllcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLycgLiAkdGhpcy0+dHJ1bmtQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaFsxXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yb290SWRlbnRpZmllciA9ICRicmFuY2hlc1sndHJ1bmsnXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCRvdXRwdXQpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5icmFuY2hlc1BhdGggIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPmV4ZWN1dGUoJ3N2biBscyAtLXZlcmJvc2UnLCAkdGhpcy0+YmFzZVVybCAuICcvJyAuICR0aGlzLT5icmFuY2hlc1BhdGgpOwogICAgICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcyh0cmltKCRvdXRwdXQpKSBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmUgJiYgUHJlZzo6aXNNYXRjaCgne15ccyooXFMrKS4qPyhcUyspXHMqJH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaFsxXSwgJG1hdGNoWzJdKSAmJiAkbWF0Y2hbMl0gIT09ICcuLycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbcnRyaW0oJG1hdGNoWzJdLCAnLycpXSA9ICR0aGlzLT5idWlsZElkZW50aWZpZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcvJyAuICR0aGlzLT5icmFuY2hlc1BhdGggLiAnLycgLiAkbWF0Y2hbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaFsxXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9ICRicmFuY2hlczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHVybCA9IHNlbGY6Om5vcm1hbGl6ZVVybCgkdXJsKTsKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnIyhec3ZuOi8vfF5zdm5cK3NzaDovL3xzdm5cLikjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gcHJvY2VlZCB3aXRoIGRlZXAgY2hlY2sgZm9yIGxvY2FsIHVybHMgc2luY2UgdGhleSBhcmUgZmFzdCB0byBwcm9jZXNzCiAgICAgICAgaWYgKCEkZGVlcCAmJiAhRmlsZXN5c3RlbTo6aXNMb2NhbFBhdGgoJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJGV4aXQgPSAkcHJvY2Vzcy0+ZXhlY3V0ZSgKICAgICAgICAgICAgInN2biBpbmZvIC0tbm9uLWludGVyYWN0aXZlIC0tICIuUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCksCiAgICAgICAgICAgICRpZ25vcmVkT3V0cHV0CiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRleGl0ID09PSAwKSB7CiAgICAgICAgICAgIC8vIFRoaXMgaXMgZGVmaW5pdGVseSBhIFN1YnZlcnNpb24gcmVwb3NpdG9yeS4KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBTdWJ2ZXJzaW9uIGNsaWVudCAxLjcgYW5kIG9sZGVyCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJpcG9zKCRwcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpLCAnYXV0aG9yaXphdGlvbiBmYWlsZWQ6JykpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBsaWtlbHkgYSByZW1vdGUgU3VidmVyc2lvbiByZXBvc2l0b3J5IHRoYXQgcmVxdWlyZXMKICAgICAgICAgICAgLy8gYXV0aGVudGljYXRpb24uIFdlIHdpbGwgaGFuZGxlIGFjdHVhbCBhdXRoZW50aWNhdGlvbiBsYXRlci4KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBTdWJ2ZXJzaW9uIGNsaWVudCAxLjggYW5kIG5ld2VyCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJpcG9zKCRwcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpLCAnQXV0aGVudGljYXRpb24gZmFpbGVkJykpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBsaWtlbHkgYSByZW1vdGUgU3VidmVyc2lvbiBvciBuZXdlciByZXBvc2l0b3J5IHRoYXQgcmVxdWlyZXMKICAgICAgICAgICAgLy8gYXV0aGVudGljYXRpb24uIFdlIHdpbGwgaGFuZGxlIGFjdHVhbCBhdXRoZW50aWNhdGlvbiBsYXRlci4KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBBbiBhYnNvbHV0ZSBwYXRoIChsZWFkaW5nICcvJykgaXMgY29udmVydGVkIHRvIGEgZmlsZTovLyB1cmwuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBub3JtYWxpemVVcmwoJHVybCkKICAgIHsKICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgIGlmICgkZnMtPmlzQWJzb2x1dGVQYXRoKCR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiAnZmlsZTovLycgLiBzdHJ0cigkdXJsLCAnXFwnLCAnLycpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR1cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlIGFuIFNWTiBjb21tYW5kIGFuZCB0cnkgdG8gZml4IHVwIHRoZSBwcm9jZXNzIHdpdGggY3JlZGVudGlhbHMKICAgICAqIGlmIG5lY2Vzc2FyeS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRjb21tYW5kIFRoZSBzdm4gY29tbWFuZCB0byBydW4uCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICR1cmwgICAgIFRoZSBTVk4gVVJMLgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoJGNvbW1hbmQsICR1cmwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT51dGlsKSB7CiAgICAgICAgICAgICR0aGlzLT51dGlsID0gbmV3IFN2blV0aWwoJHRoaXMtPmJhc2VVcmwsICR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICAgICAkdGhpcy0+dXRpbC0+c2V0Q2FjaGVDcmVkZW50aWFscygkdGhpcy0+Y2FjaGVDcmVkZW50aWFscyk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnV0aWwtPmV4ZWN1dGUoJGNvbW1hbmQsICR1cmwpOwogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+dXRpbC0+YmluYXJ5VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBsb2FkICcuJHRoaXMtPnVybC4nLCBzdm4gd2FzIG5vdCBmb3VuZCwgY2hlY2sgdGhhdCBpdCBpcyBpbnN0YWxsZWQgYW5kIGluIHlvdXIgUEFUSCBlbnYuJyAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgJ1JlcG9zaXRvcnkgJy4kdGhpcy0+dXJsLicgY291bGQgbm90IGJlIHByb2Nlc3NlZCwgJy4kZS0+Z2V0TWVzc2FnZSgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQnVpbGQgdGhlIGlkZW50aWZpZXIgcmVzcGVjdGluZyAicGFja2FnZS1wYXRoIiBjb25maWcgb3B0aW9uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYmFzZURpciAgVGhlIHBhdGggdG8gdHJ1bmsvYnJhbmNoL3RhZwogICAgICogQHBhcmFtIGludCAgICAkcmV2aXNpb24gVGhlIHJldmlzaW9uIG1hcmsgdG8gYWRkIHRvIGlkZW50aWZpZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYnVpbGRJZGVudGlmaWVyKCRiYXNlRGlyLCAkcmV2aXNpb24pCiAgICB7CiAgICAgICAgcmV0dXJuIHJ0cmltKCRiYXNlRGlyLCAnLycpIC4gJHRoaXMtPnBhY2thZ2VQYXRoIC4gJy9AJyAuICRyZXZpc2lvbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIEEgZHJpdmVyIGltcGxlbWVudGF0aW9uIGZvciBkcml2ZXIgd2l0aCBhdXRoZW50aWNhdGlvbiBpbnRlcmFjdGlvbi4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmFic3RyYWN0IGNsYXNzIFZjc0RyaXZlciBpbXBsZW1lbnRzIFZjc0RyaXZlckludGVyZmFjZQp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdXJsOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJG9yaWdpblVybDsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgbWl4ZWQ+ICovCiAgICBwcm90ZWN0ZWQgJHJlcG9Db25maWc7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBtaXhlZD4gKi8KICAgIHByb3RlY3RlZCAkaW5mb0NhY2hlID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyID9DYWNoZSAqLwogICAgcHJvdGVjdGVkICRjYWNoZTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheXt1cmw6IHN0cmluZ30mYXJyYXk8c3RyaW5nLCBtaXhlZD4gICAgICAgICAgICRyZXBvQ29uZmlnICAgICBUaGUgcmVwb3NpdG9yeSBjb25maWd1cmF0aW9uCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgJGNvbmZpZyAgICAgICAgIFRoZSBjb21wb3NlciBjb25maWd1cmF0aW9uCiAgICAgKiBAcGFyYW0gSHR0cERvd25sb2FkZXIgICRodHRwRG93bmxvYWRlciBSZW1vdGUgRmlsZXN5c3RlbSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICogQHBhcmFtIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyAgICAgICAgUHJvY2VzcyBpbnN0YW5jZSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICovCiAgICBmaW5hbCBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJlcG9Db25maWcsIElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciwgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzKQogICAgewogICAgICAgIGlmIChGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkcmVwb0NvbmZpZ1sndXJsJ10pKSB7CiAgICAgICAgICAgICRyZXBvQ29uZmlnWyd1cmwnXSA9IEZpbGVzeXN0ZW06OmdldFBsYXRmb3JtUGF0aCgkcmVwb0NvbmZpZ1sndXJsJ10pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnVybCA9ICRyZXBvQ29uZmlnWyd1cmwnXTsKICAgICAgICAkdGhpcy0+b3JpZ2luVXJsID0gJHJlcG9Db25maWdbJ3VybCddOwogICAgICAgICR0aGlzLT5yZXBvQ29uZmlnID0gJHJlcG9Db25maWc7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gJGlkZW50aWZpZXIgc2hvdWxkIGJlIGNhY2hlZCBvciBub3QuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGlkZW50aWZpZXIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jYWNoZSAmJiBQcmVnOjppc01hdGNoKCd7XlthLWYwLTldezQwfSR9aUQnLCAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENhY2hlKCRpZGVudGlmaWVyKSAmJiAkcmVzID0gJHRoaXMtPmNhY2hlLT5yZWFkKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldEJhc2VDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPndyaXRlKCRpZGVudGlmaWVyLCBKc29uRmlsZTo6ZW5jb2RlKCRjb21wb3NlciwgMCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSA9ICRjb21wb3NlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkZW50aWZpZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgbWl4ZWQ+fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEJhc2VDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICRjb21wb3NlckZpbGVDb250ZW50ID0gJHRoaXMtPmdldEZpbGVDb250ZW50KCdjb21wb3Nlci5qc29uJywgJGlkZW50aWZpZXIpOwoKICAgICAgICBpZiAoISRjb21wb3NlckZpbGVDb250ZW50KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkY29tcG9zZXJGaWxlQ29udGVudCwgJGlkZW50aWZpZXIgLiAnOmNvbXBvc2VyLmpzb24nKTsKCiAgICAgICAgaWYgKGVtcHR5KCRjb21wb3NlclsndGltZSddKSAmJiAkY2hhbmdlRGF0ZSA9ICR0aGlzLT5nZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAkY29tcG9zZXJbJ3RpbWUnXSA9ICRjaGFuZ2VEYXRlLT5mb3JtYXQoREFURV9SRkMzMzM5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29tcG9zZXJGaWxlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAoYm9vbCkgJHRoaXMtPmdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBodHRwcyBvciBodHRwIHByb3RvY29sIGRlcGVuZGluZyBvbiBTU0wgc3VwcG9ydC4KICAgICAqCiAgICAgKiBDYWxsIHRoaXMgb25seSBpZiB5b3Uga25vdyB0aGF0IHRoZSBzZXJ2ZXIgc3VwcG9ydHMgYm90aC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgY29ycmVjdCB0eXBlIG9mIHByb3RvY29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRTY2hlbWUoKQogICAgewogICAgICAgIGlmIChleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpIHsKICAgICAgICAgICAgcmV0dXJuICdodHRwcyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ2h0dHAnOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSByZW1vdGUgY29udGVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwgVGhlIFVSTCBvZiBjb250ZW50CiAgICAgKgogICAgICogQHJldHVybiBSZXNwb25zZQogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbnRlbnRzKCR1cmwpCiAgICB7CiAgICAgICAgJG9wdGlvbnMgPSBpc3NldCgkdGhpcy0+cmVwb0NvbmZpZ1snb3B0aW9ucyddKSA/ICR0aGlzLT5yZXBvQ29uZmlnWydvcHRpb25zJ10gOiBhcnJheSgpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJHVybCwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgVmNzRHJpdmVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGRyaXZlciAoZ2l0IGNsb25lLCBzdm4gY2hlY2tvdXQsIGZldGNoIGluZm8gZXRjKQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjb21wb3Nlci5qc29uIGZpbGUgaW5mb3JtYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgJGlkZW50aWZpZXIgQW55IGlkZW50aWZpZXIgdG8gYSBzcGVjaWZpYyBicmFuY2gvdGFnL2NvbW1pdAogICAgICogQHJldHVybiBtaXhlZFtdIGNvbnRhaW5pbmcgYWxsIGluZm9zIGZyb20gdGhlIGNvbXBvc2VyLmpzb24gZmlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGNvbnRlbnQgb2YgJGZpbGUgb3IgbnVsbCBpZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdC4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRmaWxlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBjaGFuZ2VkYXRlIGZvciAkaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIFxEYXRlVGltZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcm9vdCBpZGVudGlmaWVyICh0cnVuaywgbWFzdGVyLCBkZWZhdWx0L3RpcCAuLikKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290SWRlbnRpZmllcigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGxpc3Qgb2YgYnJhbmNoZXMgaW4gdGhlIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PGludHxzdHJpbmcsIHN0cmluZz4gQnJhbmNoIG5hbWVzIGFzIGtleXMsIGlkZW50aWZpZXJzIGFzIHZhbHVlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QnJhbmNoZXMoKTsKCiAgICAvKioKICAgICAqIFJldHVybiBsaXN0IG9mIHRhZ3MgaW4gdGhlIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PGludHxzdHJpbmcsIHN0cmluZz4gVGFnIG5hbWVzIGFzIGtleXMsIGlkZW50aWZpZXJzIGFzIHZhbHVlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllciBBbnkgaWRlbnRpZmllciB0byBhIHNwZWNpZmljIGJyYW5jaC90YWcvY29tbWl0CiAgICAgKgogICAgICogQHJldHVybiBhcnJheXt0eXBlOiBzdHJpbmcsIHVybDogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgc2hhc3VtOiBzdHJpbmd9fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3QoJGlkZW50aWZpZXIpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllciBBbnkgaWRlbnRpZmllciB0byBhIHNwZWNpZmljIGJyYW5jaC90YWcvY29tbWl0CiAgICAgKgogICAgICogQHJldHVybiBhcnJheXt0eXBlOiBzdHJpbmcsIHVybDogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZ30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcik7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIFVSTCBvZiB0aGUgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSByZXBvc2l0b3J5IGhhcyBhIGNvbXBvc2VyIGZpbGUgZm9yIGEgZ2l2ZW4gaWRlbnRpZmllciwKICAgICAqIGZhbHNlIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkaWRlbnRpZmllciBBbnkgaWRlbnRpZmllciB0byBhIHNwZWNpZmljIGJyYW5jaC90YWcvY29tbWl0CiAgICAgKiBAcmV0dXJuIGJvb2wgICBXaGV0aGVyIHRoZSByZXBvc2l0b3J5IGhhcyBhIGNvbXBvc2VyIGZpbGUgZm9yIGEgZ2l2ZW4gaWRlbnRpZmllci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0NvbXBvc2VyRmlsZSgkaWRlbnRpZmllcik7CgogICAgLyoqCiAgICAgKiBQZXJmb3JtcyBhbnkgY2xlYW51cCBuZWNlc3NhcnkgYXMgdGhlIGRyaXZlciBpcyBub3QgbG9uZ2VyIG5lZWRlZAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoaXMgZHJpdmVyIGNhbiBoYW5kbGUgYSBnaXZlbiB1cmwKICAgICAqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICRpbyAgICAgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgJGNvbmZpZyBjdXJyZW50ICRjb25maWcKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHVybCAgICBVUkwgdG8gdmFsaWRhdGUvY2hlY2sKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgJGRlZXAgICB1bmxlc3MgdHJ1ZSwgb25seSBzaGFsbG93IGNoZWNrcyAodXJsIG1hdGNoaW5nIHR5cGljYWxseSkgc2hvdWxkIGJlIGRvbmUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxIZyBhcyBIZ1V0aWxzOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIFBlciBCZXJuaGFyZHQgPHBsYkB3ZWJmYWN0b3J5LmRlPgogKi8KY2xhc3MgSGdEcml2ZXIgZXh0ZW5kcyBWY3NEcml2ZXIKewogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiB0YWcgbmFtZSB0byBpZGVudGlmaWVyICovCiAgICBwcm90ZWN0ZWQgJHRhZ3M7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gTWFwIG9mIGJyYW5jaCBuYW1lIHRvIGlkZW50aWZpZXIgKi8KICAgIHByb3RlY3RlZCAkYnJhbmNoZXM7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcm9vdElkZW50aWZpZXI7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcmVwb0RpcjsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBpZiAoRmlsZXN5c3RlbTo6aXNMb2NhbFBhdGgoJHRoaXMtPnVybCkpIHsKICAgICAgICAgICAgJHRoaXMtPnJlcG9EaXIgPSAkdGhpcy0+dXJsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghQ2FjaGU6OmlzVXNhYmxlKChzdHJpbmcpICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdIZ0RyaXZlciByZXF1aXJlcyBhIHVzYWJsZSBjYWNoZSBkaXJlY3RvcnksIGFuZCBpdCBsb29rcyBsaWtlIHlvdSBzZXQgaXQgdG8gYmUgZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNhY2hlRGlyID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJyk7CiAgICAgICAgICAgICR0aGlzLT5yZXBvRGlyID0gJGNhY2hlRGlyIC4gJy8nIC4gUHJlZzo6cmVwbGFjZSgne1teYS16MC05XX1pJywgJy0nLCAkdGhpcy0+dXJsKSAuICcvJzsKCiAgICAgICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgICAgICRmcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRjYWNoZURpcik7CgogICAgICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKGRpcm5hbWUoJHRoaXMtPnJlcG9EaXIpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDYW4gbm90IGNsb25lICcuJHRoaXMtPnVybC4nIHRvIGFjY2VzcyBwYWNrYWdlIGluZm9ybWF0aW9uLiBUaGUgIicuJGNhY2hlRGlyLiciIGRpcmVjdG9yeSBpcyBub3Qgd3JpdGFibGUgYnkgdGhlIGN1cnJlbnQgdXNlci4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRW5zdXJlIHdlIGFyZSBhbGxvd2VkIHRvIHVzZSB0aGlzIFVSTCBieSBjb25maWcKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdGhpcy0+dXJsLCAkdGhpcy0+aW8pOwoKICAgICAgICAgICAgJGhnVXRpbHMgPSBuZXcgSGdVdGlscygkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgcmVwbyBpZiBpdCBpcyBhIHZhbGlkIGhnIHJlcG9zaXRvcnkKICAgICAgICAgICAgaWYgKGlzX2RpcigkdGhpcy0+cmVwb0RpcikgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIHN1bW1hcnknLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0RpcikpIHsKICAgICAgICAgICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnaGcgcHVsbCcsICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkZhaWxlZCB0byB1cGRhdGUgJy4kdGhpcy0+dXJsLicsIHBhY2thZ2UgaW5mb3JtYXRpb24gZnJvbSB0aGlzIHJlcG9zaXRvcnkgbWF5IGJlIG91dGRhdGVkICgnLiR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpLicpPC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGNsZWFuIHVwIGRpcmVjdG9yeSBhbmQgZG8gYSBmcmVzaCBjbG9uZSBpbnRvIGl0CiAgICAgICAgICAgICAgICAkZnMtPnJlbW92ZURpcmVjdG9yeSgkdGhpcy0+cmVwb0Rpcik7CgogICAgICAgICAgICAgICAgJHJlcG9EaXIgPSAkdGhpcy0+cmVwb0RpcjsKICAgICAgICAgICAgICAgICRjb21tYW5kID0gZnVuY3Rpb24gKCR1cmwpIHVzZSAoJHJlcG9EaXIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZignaGcgY2xvbmUgLS1ub3VwZGF0ZSAtLSAlcyAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVwb0RpcikpOwogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICAkaGdVdGlscy0+cnVuQ29tbWFuZCgkY29tbWFuZCwgJHRoaXMtPnVybCwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5nZXRUYWdzKCk7CiAgICAgICAgJHRoaXMtPmdldEJyYW5jaGVzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cm9vdElkZW50aWZpZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoc3ByaW50ZignaGcgdGlwIC0tdGVtcGxhdGUgIntub2RlfSInKSwgJG91dHB1dCwgJHRoaXMtPnJlcG9EaXIpOwogICAgICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPnByb2Nlc3MtPnNwbGl0TGluZXMoJG91dHB1dCk7CiAgICAgICAgICAgICR0aGlzLT5yb290SWRlbnRpZmllciA9ICRvdXRwdXRbMF07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3RJZGVudGlmaWVyOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ2hnJywgJ3VybCcgPT4gJHRoaXMtPmdldFVybCgpLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJHJlc291cmNlID0gc3ByaW50ZignaGcgY2F0IC1yICVzICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGlkZW50aWZpZXIpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkpOwogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRyZXNvdXJjZSwgJGNvbnRlbnQsICR0aGlzLT5yZXBvRGlyKTsKCiAgICAgICAgaWYgKCF0cmltKCRjb250ZW50KSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKAogICAgICAgICAgICBzcHJpbnRmKAogICAgICAgICAgICAgICAgJ2hnIGxvZyAtLXRlbXBsYXRlICJ7ZGF0ZXxyZmMzMzM5ZGF0ZX0iIC1yICVzJywKICAgICAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRpZGVudGlmaWVyKQogICAgICAgICAgICApLAogICAgICAgICAgICAkb3V0cHV0LAogICAgICAgICAgICAkdGhpcy0+cmVwb0RpcgogICAgICAgICk7CgogICAgICAgIHJldHVybiBuZXcgXERhdGVUaW1lKHRyaW0oJG91dHB1dCksIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0YWdzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdoZyB0YWdzJywgJG91dHB1dCwgJHRoaXMtPnJlcG9EaXIpOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkdGFnKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRhZyAmJiBQcmVnOjppc01hdGNoKCcoXihbXlxzXSspXHMrXGQrOiguKikkKScsICR0YWcsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGFnc1skbWF0Y2hbMV1dID0gJG1hdGNoWzJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCR0YWdzWyd0aXAnXSk7CgogICAgICAgICAgICAkdGhpcy0+dGFncyA9ICR0YWdzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50YWdzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaGVzKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmJyYW5jaGVzKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRib29rbWFya3MgPSBhcnJheSgpOwoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIGJyYW5jaGVzJywgJG91dHB1dCwgJHRoaXMtPnJlcG9EaXIpOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkYnJhbmNoKSB7CiAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaCAmJiBQcmVnOjppc01hdGNoKCcoXihbXlxzXSspXHMrXGQrOihbYS1mMC05XSspKScsICRicmFuY2gsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJG1hdGNoWzFdXSA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIGJvb2ttYXJrcycsICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2Nlc3MtPnNwbGl0TGluZXMoJG91dHB1dCkgYXMgJGJyYW5jaCkgewogICAgICAgICAgICAgICAgaWYgKCRicmFuY2ggJiYgUHJlZzo6aXNNYXRjaCgnKF4oPzpbXHMqXSopKFteXHNdKylccytcZCs6KC4qKSQpJywgJGJyYW5jaCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICRib29rbWFya3NbJG1hdGNoWzFdXSA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQnJhbmNoZXMgd2lsbCBoYXZlIHByZWZlcmVuY2Ugb3ZlciBib29rbWFya3MKICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzID0gYXJyYXlfbWVyZ2UoJGJvb2ttYXJrcywgJGJyYW5jaGVzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyMoXig/Omh0dHBzP3xzc2gpOi8vKD86W15AXStAKT9iaXRidWNrZXQub3JnfGh0dHBzOi8vKD86Lio/KVwua2lsbmhnLmNvbSkjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbG9jYWwgZmlsZXN5c3RlbQogICAgICAgIGlmIChGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkdXJsKSkgewogICAgICAgICAgICAkdXJsID0gRmlsZXN5c3RlbTo6Z2V0UGxhdGZvcm1QYXRoKCR1cmwpOwogICAgICAgICAgICBpZiAoIWlzX2RpcigkdXJsKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIGhnIHJlcG8gaW4gdGhhdCBwYXRoCiAgICAgICAgICAgIGlmICgkcHJvY2Vzcy0+ZXhlY3V0ZSgnaGcgc3VtbWFyeScsICRvdXRwdXQsICR1cmwpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkZGVlcCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkZXhpdCA9ICRwcm9jZXNzLT5leGVjdXRlKHNwcmludGYoJ2hnIGlkZW50aWZ5IC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCkpLCAkaWdub3JlZCk7CgogICAgICAgIHJldHVybiAkZXhpdCA9PT0gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcR2l0TGFiOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIERyaXZlciBmb3IgR2l0TGFiIEFQSSwgdXNlIHRoZSBHaXQgZHJpdmVyIGZvciBsb2NhbCBjaGVja291dHMuCiAqCiAqIEBhdXRob3IgSGVucmlrIEJqw7hybnNrb3YgPGhlbnJpa0BianJuc2tvdi5kaz4KICogQGF1dGhvciBKw6lyw7RtZSBUYW1hcmVsbGUgPGplcm9tZUB0YW1hcmVsbGUubmV0PgogKi8KY2xhc3MgR2l0TGFiRHJpdmVyIGV4dGVuZHMgVmNzRHJpdmVyCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBwaHBzdGFuLXZhciAnaHR0cHMnfCdodHRwJwogICAgICovCiAgICBwcml2YXRlICRzY2hlbWU7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJG5hbWVzcGFjZTsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yeTsKCiAgICAvKioKICAgICAqIEB2YXIgbWl4ZWRbXSBQcm9qZWN0IGRhdGEgcmV0dXJuZWQgYnkgR2l0TGFiIEFQSQogICAgICovCiAgICBwcml2YXRlICRwcm9qZWN0OwoKICAgIC8qKgogICAgICogQHZhciBhcnJheTxzdHJpbmd8aW50LCBtaXhlZFtdPiBLZWVwcyBjb21taXRzIHJldHVybmVkIGJ5IEdpdExhYiBBUEkgYXMgY29tbWl0IGlkID0+IGluZm8KICAgICAqLwogICAgcHJpdmF0ZSAkY29tbWl0cyA9IGFycmF5KCk7CgogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiB0YWcgbmFtZSB0byBpZGVudGlmaWVyICovCiAgICBwcml2YXRlICR0YWdzOwoKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgc3RyaW5nPiBNYXAgb2YgYnJhbmNoIG5hbWUgdG8gaWRlbnRpZmllciAqLwogICAgcHJpdmF0ZSAkYnJhbmNoZXM7CgogICAgLyoqCiAgICAgKiBHaXQgRHJpdmVyCiAgICAgKgogICAgICogQHZhciA/R2l0RHJpdmVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZ2l0RHJpdmVyID0gbnVsbDsKCiAgICAvKioKICAgICAqIFByb3RvY29sIHRvIGZvcmNlIHVzZSBvZiBmb3IgcmVwb3NpdG9yeSBVUkxzLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nIE9uZSBvZiBzc2gsIGh0dHAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm90b2NvbDsKCiAgICAvKioKICAgICAqIERlZmF1bHRzIHRvIHRydWUgdW5sZXNzIHdlIGNhbiBtYWtlIHN1cmUgaXQgaXMgcHVibGljCiAgICAgKgogICAgICogQHZhciBib29sIGRlZmluZXMgd2hldGhlciB0aGUgcmVwbyBpcyBwcml2YXRlIG9yIG5vdAogICAgICovCiAgICBwcml2YXRlICRpc1ByaXZhdGUgPSB0cnVlOwoKICAgIC8qKgogICAgICogQHZhciBib29sIHRydWUgaWYgdGhlIG9yaWdpbiBoYXMgYSBwb3J0IG51bWJlciBvciBhIHBhdGggY29tcG9uZW50IGluIGl0CiAgICAgKi8KICAgIHByaXZhdGUgJGhhc05vbnN0YW5kYXJkT3JpZ2luID0gZmFsc2U7CgogICAgY29uc3QgVVJMX1JFR0VYID0gJyNeKD86KD9QPHNjaGVtZT5odHRwcz8pOi8vKD9QPGRvbWFpbj4uKz8pKD86Oig/UDxwb3J0PlswLTldKykpPy98Z2l0QCg/UDxkb21haW4yPlteOl0rKTopKD9QPHBhcnRzPi4rKS8oP1A8cmVwbz5bXi9dKz8pKD86XC5naXR8Lyk/JCMnOwoKICAgIC8qKgogICAgICogRXh0cmFjdHMgaW5mb3JtYXRpb24gZnJvbSB0aGUgcmVwb3NpdG9yeSB1cmwuCiAgICAgKgogICAgICogU1NIIHVybHMgdXNlIGh0dHBzIGJ5IGRlZmF1bHQuIFNldCAic2VjdXJlLWh0dHAiOiBmYWxzZSBvbiB0aGUgcmVwb3NpdG9yeSBjb25maWcgdG8gdXNlIGh0dHAgaW5zdGVhZC4KICAgICAqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKHNlbGY6OlVSTF9SRUdFWCwgJHRoaXMtPnVybCwgJG1hdGNoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIFVSTCBwcm92aWRlZCBpcyBpbnZhbGlkLiBJdCBtdXN0IGJlIHRoZSBIVFRQIFVSTCBvZiBhIEdpdExhYiBwcm9qZWN0LicpOwogICAgICAgIH0KCiAgICAgICAgJGd1ZXNzZWREb21haW4gPSAhZW1wdHkoJG1hdGNoWydkb21haW4nXSkgPyAkbWF0Y2hbJ2RvbWFpbiddIDogJG1hdGNoWydkb21haW4yJ107CiAgICAgICAgJGNvbmZpZ3VyZWREb21haW5zID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpOwogICAgICAgICR1cmxQYXJ0cyA9IGV4cGxvZGUoJy8nLCAkbWF0Y2hbJ3BhcnRzJ10pOwoKICAgICAgICAkdGhpcy0+c2NoZW1lID0gIWVtcHR5KCRtYXRjaFsnc2NoZW1lJ10pCiAgICAgICAgICAgID8gJG1hdGNoWydzY2hlbWUnXQogICAgICAgICAgICA6IChpc3NldCgkdGhpcy0+cmVwb0NvbmZpZ1snc2VjdXJlLWh0dHAnXSkgJiYgJHRoaXMtPnJlcG9Db25maWdbJ3NlY3VyZS1odHRwJ10gPT09IGZhbHNlID8gJ2h0dHAnIDogJ2h0dHBzJykKICAgICAgICA7CiAgICAgICAgJHRoaXMtPm9yaWdpblVybCA9IHNlbGY6OmRldGVybWluZU9yaWdpbigkY29uZmlndXJlZERvbWFpbnMsICRndWVzc2VkRG9tYWluLCAkdXJsUGFydHMsICRtYXRjaFsncG9ydCddKTsKCiAgICAgICAgaWYgKCRwcm90b2NvbCA9ICR0aGlzLT5jb25maWctPmdldCgnZ2l0bGFiLXByb3RvY29sJykpIHsKICAgICAgICAgICAgLy8gaHR0cHMgdHJlYXRlZCBhcyBhIHN5bm9ueW0gZm9yIGh0dHAuCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHByb3RvY29sLCBhcnJheSgnZ2l0JywgJ2h0dHAnLCAnaHR0cHMnKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignZ2l0bGFiLXByb3RvY29sIG11c3QgYmUgb25lIG9mIGdpdCwgaHR0cC4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+cHJvdG9jb2wgPSAkcHJvdG9jb2wgPT09ICdnaXQnID8gJ3NzaCcgOiAnaHR0cCc7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkdGhpcy0+b3JpZ2luVXJsLCAnOicpIHx8IGZhbHNlICE9PSBzdHJwb3MoJHRoaXMtPm9yaWdpblVybCwgJy8nKSkgewogICAgICAgICAgICAkdGhpcy0+aGFzTm9uc3RhbmRhcmRPcmlnaW4gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm5hbWVzcGFjZSA9IGltcGxvZGUoJy8nLCAkdXJsUGFydHMpOwogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5ID0gUHJlZzo6cmVwbGFjZSgnIyhcLmdpdCkkIycsICcnLCAkbWF0Y2hbJ3JlcG8nXSk7CgogICAgICAgICR0aGlzLT5jYWNoZSA9IG5ldyBDYWNoZSgkdGhpcy0+aW8sICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKS4nLycuJHRoaXMtPm9yaWdpblVybC4nLycuJHRoaXMtPm5hbWVzcGFjZS4nLycuJHRoaXMtPnJlcG9zaXRvcnkpOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CgogICAgICAgICR0aGlzLT5mZXRjaFByb2plY3QoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIEh0dHBEb3dubG9hZGVyIGluc3RhbmNlLgogICAgICogTWFpbmx5IHVzZWZ1bCBmb3IgdGVzdHMuCiAgICAgKgogICAgICogQGludGVybmFsCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIdHRwRG93bmxvYWRlcihIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikgJiYgJHJlcyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHJlcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0QmFzZUNvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpOwoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNhY2hlLT53cml0ZSgkaWRlbnRpZmllciwganNvbl9lbmNvZGUoJGNvbXBvc2VyKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgIC8vIHNwZWNpYWxzIGZvciBnaXRsYWIgKHRoaXMgZGF0YSBpcyBvbmx5IGF2YWlsYWJsZSBpZiBhdXRoZW50aWNhdGlvbiBpcyBwcm92aWRlZCkKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbXBvc2VyWydzdXBwb3J0J11bJ3NvdXJjZSddKSAmJiBpc3NldCgkdGhpcy0+cHJvamVjdFsnd2ViX3VybCddKSkgewogICAgICAgICAgICAgICAgICAgICRsYWJlbCA9IGFycmF5X3NlYXJjaCgkaWRlbnRpZmllciwgJHRoaXMtPmdldFRhZ3MoKSwgdHJ1ZSkgPzogYXJyYXlfc2VhcmNoKCRpZGVudGlmaWVyLCAkdGhpcy0+Z2V0QnJhbmNoZXMoKSwgdHJ1ZSkgPzogJGlkZW50aWZpZXI7CiAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydzdXBwb3J0J11bJ3NvdXJjZSddID0gc3ByaW50ZignJXMvLS90cmVlLyVzJywgJHRoaXMtPnByb2plY3RbJ3dlYl91cmwnXSwgJGxhYmVsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbXBvc2VyWydzdXBwb3J0J11bJ2lzc3VlcyddKSAmJiAhZW1wdHkoJHRoaXMtPnByb2plY3RbJ2lzc3Vlc19lbmFibGVkJ10pICYmIGlzc2V0KCR0aGlzLT5wcm9qZWN0Wyd3ZWJfdXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydzdXBwb3J0J11bJ2lzc3VlcyddID0gc3ByaW50ZignJXMvLS9pc3N1ZXMnLCAkdGhpcy0+cHJvamVjdFsnd2ViX3VybCddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbXBvc2VyWydhYmFuZG9uZWQnXSkgJiYgIWVtcHR5KCR0aGlzLT5wcm9qZWN0WydhcmNoaXZlZCddKSkgewogICAgICAgICAgICAgICAgICAgICRjb21wb3NlclsnYWJhbmRvbmVkJ10gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSA9ICRjb21wb3NlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldEZpbGVDb250ZW50KCRmaWxlLCAkaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSByb290IGlkZW50aWZpZXIgdG8gYSBjYWNoZWFibGUgY29tbWl0IGlkCiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7W2EtZjAtOV17NDB9fWknLCAkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gJHRoaXMtPmdldEJyYW5jaGVzKCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkYnJhbmNoZXNbJGlkZW50aWZpZXJdKSkgewogICAgICAgICAgICAgICAgJGlkZW50aWZpZXIgPSAkYnJhbmNoZXNbJGlkZW50aWZpZXJdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcmVzb3VyY2UgPSAkdGhpcy0+Z2V0QXBpVXJsKCkuJy9yZXBvc2l0b3J5L2ZpbGVzLycuJHRoaXMtPnVybEVuY29kZUFsbCgkZmlsZSkuJy9yYXc/cmVmPScuJGlkZW50aWZpZXI7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRjb250ZW50ID0gJHRoaXMtPmdldENvbnRlbnRzKCRyZXNvdXJjZSktPmdldEJvZHkoKTsKICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgIT09IDQwNCkgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb250ZW50OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb21taXRzWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJHRoaXMtPmNvbW1pdHNbJGlkZW50aWZpZXJdWydjb21taXR0ZWRfZGF0ZSddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgXERhdGVUaW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yeVVybCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5wcm90b2NvbCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByb2plY3RbInskdGhpcy0+cHJvdG9jb2x9X3VybF90b19yZXBvIl07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmlzUHJpdmF0ZSA/ICR0aGlzLT5wcm9qZWN0Wydzc2hfdXJsX3RvX3JlcG8nXSA6ICR0aGlzLT5wcm9qZWN0WydodHRwX3VybF90b19yZXBvJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0VXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2plY3RbJ3dlYl91cmwnXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0KCRpZGVudGlmaWVyKQogICAgewogICAgICAgICR1cmwgPSAkdGhpcy0+Z2V0QXBpVXJsKCkuJy9yZXBvc2l0b3J5L2FyY2hpdmUuemlwP3NoYT0nLiRpZGVudGlmaWVyOwoKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICd6aXAnLCAndXJsJyA9PiAkdXJsLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllciwgJ3NoYXN1bScgPT4gJycpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0U291cmNlKCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ2dpdCcsICd1cmwnID0+ICR0aGlzLT5nZXRSZXBvc2l0b3J5VXJsKCksICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290SWRlbnRpZmllcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2plY3RbJ2RlZmF1bHRfYnJhbmNoJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QnJhbmNoZXMoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRCcmFuY2hlcygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+YnJhbmNoZXMpIHsKICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzID0gJHRoaXMtPmdldFJlZmVyZW5jZXMoJ2JyYW5jaGVzJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmJyYW5jaGVzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhZ3MoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRUYWdzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0aGlzLT50YWdzID0gJHRoaXMtPmdldFJlZmVyZW5jZXMoJ3RhZ3MnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nIEJhc2UgVVJMIGZvciBHaXRMYWIgQVBJIHYzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcGlVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2NoZW1lLic6Ly8nLiR0aGlzLT5vcmlnaW5VcmwuJy9hcGkvdjQvcHJvamVjdHMvJy4kdGhpcy0+dXJsRW5jb2RlQWxsKCR0aGlzLT5uYW1lc3BhY2UpLiclMkYnLiR0aGlzLT51cmxFbmNvZGVBbGwoJHRoaXMtPnJlcG9zaXRvcnkpOwogICAgfQoKICAgIC8qKgogICAgICogVXJsZW5jb2RlIGFsbCBub24gYWxwaGFudW1lcmljIGNoYXJhY3RlcnMuIHJhd3VybGVuY29kZSgpIGNhbiBub3QgYmUgdXNlZCBhcyBpdCBkb2VzIG5vdCBlbmNvZGUgYC5gCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHN0cmluZwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1cmxFbmNvZGVBbGwoJHN0cmluZykKICAgIHsKICAgICAgICAkZW5jb2RlZCA9ICcnOwogICAgICAgIGZvciAoJGkgPSAwOyBpc3NldCgkc3RyaW5nWyRpXSk7ICRpKyspIHsKICAgICAgICAgICAgJGNoYXJhY3RlciA9ICRzdHJpbmdbJGldOwogICAgICAgICAgICBpZiAoIWN0eXBlX2FsbnVtKCRjaGFyYWN0ZXIpICYmICFpbl9hcnJheSgkY2hhcmFjdGVyLCBhcnJheSgnLScsICdfJyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkY2hhcmFjdGVyID0gJyUnIC4gc3ByaW50ZignJTAyWCcsIG9yZCgkY2hhcmFjdGVyKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVuY29kZWQgLj0gJGNoYXJhY3RlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZW5jb2RlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIHdoZXJlIGtleXMgYXJlIG5hbWVkIHJlZmVyZW5jZXMgbGlrZSB0YWdzIG9yIGJyYW5jaGVzIGFuZCB0aGUgdmFsdWUgYSBzaGEKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFJlZmVyZW5jZXMoJHR5cGUpCiAgICB7CiAgICAgICAgJHBlclBhZ2UgPSAxMDA7CiAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpLicvcmVwb3NpdG9yeS8nLiR0eXBlLic/cGVyX3BhZ2U9Jy4kcGVyUGFnZTsKCiAgICAgICAgJHJlZmVyZW5jZXMgPSBhcnJheSgpOwogICAgICAgIGRvIHsKICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmdldENvbnRlbnRzKCRyZXNvdXJjZSk7CiAgICAgICAgICAgICRkYXRhID0gJHJlc3BvbnNlLT5kZWNvZGVKc29uKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkZGF0YSBhcyAkZGF0dW0pIHsKICAgICAgICAgICAgICAgICRyZWZlcmVuY2VzWyRkYXR1bVsnbmFtZSddXSA9ICRkYXR1bVsnY29tbWl0J11bJ2lkJ107CgogICAgICAgICAgICAgICAgLy8gS2VlcCB0aGUgbGFzdCBjb21taXQgZGF0ZSBvZiBhIHJlZmVyZW5jZSB0byBhdm9pZAogICAgICAgICAgICAgICAgLy8gdW5uZWNlc3NhcnkgQVBJIGNhbGwgd2hlbiByZXRyaWV2aW5nIHRoZSBjb21wb3NlciBmaWxlLgogICAgICAgICAgICAgICAgJHRoaXMtPmNvbW1pdHNbJGRhdHVtWydjb21taXQnXVsnaWQnXV0gPSAkZGF0dW1bJ2NvbW1pdCddOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY291bnQoJGRhdGEpID49ICRwZXJQYWdlKSB7CiAgICAgICAgICAgICAgICAkcmVzb3VyY2UgPSAkdGhpcy0+Z2V0TmV4dFBhZ2UoJHJlc3BvbnNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSB3aGlsZSAoJHJlc291cmNlKTsKCiAgICAgICAgcmV0dXJuICRyZWZlcmVuY2VzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaFByb2plY3QoKQogICAgewogICAgICAgIC8vIHdlIG5lZWQgdG8gZmV0Y2ggdGhlIGRlZmF1bHQgYnJhbmNoIGZyb20gdGhlIGFwaQogICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXRBcGlVcmwoKTsKICAgICAgICAkdGhpcy0+cHJvamVjdCA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVzb3VyY2UsIHRydWUpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wcm9qZWN0Wyd2aXNpYmlsaXR5J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5pc1ByaXZhdGUgPSAkdGhpcy0+cHJvamVjdFsndmlzaWJpbGl0eSddICE9PSAncHVibGljJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBjbGllbnQgaXMgbm90IGF1dGhlbnRpY2F0ZWQsIHRoZXJlZm9yZSByZXBvc2l0b3J5IGhhcyB0byBiZSBwdWJsaWMKICAgICAgICAgICAgJHRoaXMtPmlzUHJpdmF0ZSA9IGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwaHBzdGFuLWltcHVyZQogICAgICoKICAgICAqIEByZXR1cm4gdHJ1ZQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXR0ZW1wdENsb25lRmFsbGJhY2soKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNQcml2YXRlID09PSBmYWxzZSkgewogICAgICAgICAgICAkdXJsID0gJHRoaXMtPmdlbmVyYXRlUHVibGljVXJsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHVybCA9ICR0aGlzLT5nZW5lcmF0ZVNzaFVybCgpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gSWYgdGhpcyByZXBvc2l0b3J5IG1heSBiZSBwcml2YXRlIGFuZCB3ZQogICAgICAgICAgICAvLyBjYW5ub3QgYXNrIGZvciBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFscyAoYmVjYXVzZSB3ZQogICAgICAgICAgICAvLyBhcmUgbm90IGludGVyYWN0aXZlKSB0aGVuIHdlIGZhbGxiYWNrIHRvIEdpdERyaXZlci4KICAgICAgICAgICAgJHRoaXMtPnNldHVwR2l0RHJpdmVyKCR1cmwpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmdpdERyaXZlciA9IG51bGw7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5GYWlsZWQgdG8gY2xvbmUgdGhlICcuJHVybC4nIHJlcG9zaXRvcnksIHRyeSBydW5uaW5nIGluIGludGVyYWN0aXZlIG1vZGUgc28gdGhhdCB5b3UgY2FuIGVudGVyIHlvdXIgY3JlZGVudGlhbHM8L2Vycm9yPicpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBTU0ggVVJMCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmhhc05vbnN0YW5kYXJkT3JpZ2luKSB7CiAgICAgICAgICAgIHJldHVybiAnc3NoOi8vZ2l0QCcuJHRoaXMtPm9yaWdpblVybC4nLycuJHRoaXMtPm5hbWVzcGFjZS4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdnaXRAJyAuICR0aGlzLT5vcmlnaW5VcmwgLiAnOicuJHRoaXMtPm5hbWVzcGFjZS4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlUHVibGljVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtZSAuICc6Ly8nIC4gJHRoaXMtPm9yaWdpblVybCAuICcvJy4kdGhpcy0+bmFtZXNwYWNlLicvJy4kdGhpcy0+cmVwb3NpdG9yeS4nLmdpdCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNldHVwR2l0RHJpdmVyKCR1cmwpCiAgICB7CiAgICAgICAgJHRoaXMtPmdpdERyaXZlciA9IG5ldyBHaXREcml2ZXIoCiAgICAgICAgICAgIGFycmF5KCd1cmwnID0+ICR1cmwpLAogICAgICAgICAgICAkdGhpcy0+aW8sCiAgICAgICAgICAgICR0aGlzLT5jb25maWcsCiAgICAgICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciwKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MKICAgICAgICApOwogICAgICAgICR0aGlzLT5naXREcml2ZXItPmluaXRpYWxpemUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGZldGNoaW5nUmVwb0RhdGEKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbnRlbnRzKCR1cmwsICRmZXRjaGluZ1JlcG9EYXRhID0gZmFsc2UpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHJlc3BvbnNlID0gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKCiAgICAgICAgICAgIGlmICgkZmV0Y2hpbmdSZXBvRGF0YSkgewogICAgICAgICAgICAgICAgJGpzb24gPSAkcmVzcG9uc2UtPmRlY29kZUpzb24oKTsKCiAgICAgICAgICAgICAgICAvLyBBY2Nlc3NpbmcgdGhlIEFQSSB3aXRoIGEgdG9rZW4gd2l0aCBHdWVzdCAoMTApIGFjY2VzcyB3aWxsIHJldHVybgogICAgICAgICAgICAgICAgLy8gbW9yZSBkYXRhIHRoYW4gdW5hdXRoZW50aWNhdGVkIGFjY2VzcyBidXQgbm8gZGVmYXVsdF9icmFuY2ggZGF0YQogICAgICAgICAgICAgICAgLy8gYWNjZXNzaW5nIGZpbGVzIHZpYSB0aGUgQVBJIHdpbGwgdGhlbiBhbHNvIGZhaWwKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGpzb25bJ2RlZmF1bHRfYnJhbmNoJ10pICYmIGlzc2V0KCRqc29uWydwZXJtaXNzaW9ucyddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pc1ByaXZhdGUgPSAkanNvblsndmlzaWJpbGl0eSddICE9PSAncHVibGljJzsKCiAgICAgICAgICAgICAgICAgICAgJG1vcmVUaGFuR3Vlc3RBY2Nlc3MgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBib3RoIGFjY2VzcyBsZXZlbHMgKGUuZy4gcHJvamVjdCwgZ3JvdXApCiAgICAgICAgICAgICAgICAgICAgLy8gLSB2YWx1ZSB3aWxsIGJlIG51bGwgaWYgbm8gYWNjZXNzIGlzIHNldAogICAgICAgICAgICAgICAgICAgIC8vIC0gdmFsdWUgd2lsbCBiZSBhcnJheSB3aXRoIGtleSBhY2Nlc3NfbGV2ZWwgaWYgc2V0CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGpzb25bJ3Blcm1pc3Npb25zJ10gYXMgJHBlcm1pc3Npb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwZXJtaXNzaW9uICYmICRwZXJtaXNzaW9uWydhY2Nlc3NfbGV2ZWwnXSA+IDEwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbW9yZVRoYW5HdWVzdEFjY2VzcyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJG1vcmVUaGFuR3Vlc3RBY2Nlc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5HaXRMYWIgdG9rZW4gd2l0aCBHdWVzdCBvbmx5IGFjY2VzcyBkZXRlY3RlZDwvd2FybmluZz4nKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hdHRlbXB0Q2xvbmVGYWxsYmFjaygpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAnZHVtbXknKSwgMjAwLCBhcnJheSgpLCAnbnVsbCcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBmb3JjZSBhdXRoIGFzIHRoZSB1bmF1dGhlbnRpY2F0ZWQgdmVyc2lvbiBvZiB0aGUgQVBJIGlzIGJyb2tlbgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkanNvblsnZGVmYXVsdF9icmFuY2gnXSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBHaXRMYWIgYWxsb3dzIHlvdSB0byBkaXNhYmxlIHRoZSByZXBvc2l0b3J5IGluc2lkZSBhIHByb2plY3QgdG8gdXNlIGEgcHJvamVjdCBvbmx5IGZvciBpc3N1ZXMgYW5kIHdpa2kKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGpzb25bJ3JlcG9zaXRvcnlfYWNjZXNzX2xldmVsJ10pICYmICRqc29uWydyZXBvc2l0b3J5X2FjY2Vzc19sZXZlbCddID09PSAnZGlzYWJsZWQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1RoZSBHaXRMYWIgcmVwb3NpdG9yeSBpcyBkaXNhYmxlZCBpbiB0aGUgcHJvamVjdCcsIDQwMCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRqc29uWydpZCddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aXNQcml2YXRlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdHaXRMYWIgQVBJIHNlZW1zIHRvIG5vdCBiZSBhdXRoZW50aWNhdGVkIGFzIGl0IGRpZCBub3QgcmV0dXJuIGEgZGVmYXVsdF9icmFuY2gnLCA0MDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHJlc3BvbnNlOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkZ2l0TGFiVXRpbCA9IG5ldyBHaXRMYWIoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHRoaXMtPmh0dHBEb3dubG9hZGVyKTsKCiAgICAgICAgICAgIHN3aXRjaCAoJGUtPmdldENvZGUoKSkgewogICAgICAgICAgICAgICAgY2FzZSA0MDE6CiAgICAgICAgICAgICAgICBjYXNlIDQwNDoKICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gYXV0aG9yaXplIG9ubHkgaWYgd2UgYXJlIGZldGNoaW5nIHRoZSBtYWluIC9yZXBvcy9mb28vYmFyIGRhdGEsIG90aGVyd2lzZSBpdCBtdXN0IGJlIGEgcmVhbCA0MDQKICAgICAgICAgICAgICAgICAgICBpZiAoISRmZXRjaGluZ1JlcG9EYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aCgkdGhpcy0+b3JpZ2luVXJsKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmF0dGVtcHRDbG9uZUZhbGxiYWNrKCk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICdkdW1teScpLCAyMDAsIGFycmF5KCksICdudWxsJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+RmFpbGVkIHRvIGRvd25sb2FkICcgLiAkdGhpcy0+bmFtZXNwYWNlIC4gJy8nIC4gJHRoaXMtPnJlcG9zaXRvcnkgLiAnOicgLiAkZS0+Z2V0TWVzc2FnZSgpIC4gJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAkZ2l0TGFiVXRpbC0+YXV0aG9yaXplT0F1dGhJbnRlcmFjdGl2ZWx5KCR0aGlzLT5zY2hlbWUsICR0aGlzLT5vcmlnaW5VcmwsICdZb3VyIGNyZWRlbnRpYWxzIGFyZSByZXF1aXJlZCB0byBmZXRjaCBwcml2YXRlIHJlcG9zaXRvcnkgbWV0YWRhdGEgKDxpbmZvPicuJHRoaXMtPnVybC4nPC9pbmZvPiknKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CgogICAgICAgICAgICAgICAgY2FzZSA0MDM6CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmhhc0F1dGhlbnRpY2F0aW9uKCR0aGlzLT5vcmlnaW5VcmwpICYmICRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aCgkdGhpcy0+b3JpZ2luVXJsKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkgJiYgJGZldGNoaW5nUmVwb0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmF0dGVtcHRDbG9uZUZhbGxiYWNrKCk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICdkdW1teScpLCAyMDAsIGFycmF5KCksICdudWxsJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVXNlcyB0aGUgY29uZmlnIGBnaXRsYWItZG9tYWluc2AgdG8gc2VlIGlmIHRoZSBkcml2ZXIgc3VwcG9ydHMgdGhlIHVybCBmb3IgdGhlCiAgICAgKiByZXBvc2l0b3J5IGdpdmVuLgogICAgICoKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHMoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgJHVybCwgJGRlZXAgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goc2VsZjo6VVJMX1JFR0VYLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRzY2hlbWUgPSAhZW1wdHkoJG1hdGNoWydzY2hlbWUnXSkgPyAkbWF0Y2hbJ3NjaGVtZSddIDogbnVsbDsKICAgICAgICAkZ3Vlc3NlZERvbWFpbiA9ICFlbXB0eSgkbWF0Y2hbJ2RvbWFpbiddKSA/ICRtYXRjaFsnZG9tYWluJ10gOiAkbWF0Y2hbJ2RvbWFpbjInXTsKICAgICAgICAkdXJsUGFydHMgPSBleHBsb2RlKCcvJywgJG1hdGNoWydwYXJ0cyddKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSBzZWxmOjpkZXRlcm1pbmVPcmlnaW4oKGFycmF5KSAkY29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyksICRndWVzc2VkRG9tYWluLCAkdXJsUGFydHMsICRtYXRjaFsncG9ydCddKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ2h0dHBzJyA9PT0gJHNjaGVtZSAmJiAhZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignU2tpcHBpbmcgR2l0TGFiIGRyaXZlciBmb3IgJy4kdXJsLicgYmVjYXVzZSB0aGUgT3BlblNTTCBQSFAgZXh0ZW5zaW9uIGlzIG1pc3NpbmcuJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXROZXh0UGFnZShSZXNwb25zZSAkcmVzcG9uc2UpCiAgICB7CiAgICAgICAgJGhlYWRlciA9ICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdsaW5rJyk7CgogICAgICAgICRsaW5rcyA9IGV4cGxvZGUoJywnLCAkaGVhZGVyKTsKICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3s8KC4rPyk+OyAqcmVsPSJuZXh0In0nLCAkbGluaywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaFsxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGFycmF5PHN0cmluZz4gJGNvbmZpZ3VyZWREb21haW5zCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgJGd1ZXNzZWREb21haW4KICAgICAqIEBwYXJhbSAgYXJyYXk8c3RyaW5nPiAkdXJsUGFydHMKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAkcG9ydE51bWJlcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGRldGVybWluZU9yaWdpbihhcnJheSAkY29uZmlndXJlZERvbWFpbnMsICRndWVzc2VkRG9tYWluLCBhcnJheSAmJHVybFBhcnRzLCAkcG9ydE51bWJlcikKICAgIHsKICAgICAgICAkZ3Vlc3NlZERvbWFpbiA9IHN0cnRvbG93ZXIoJGd1ZXNzZWREb21haW4pOwoKICAgICAgICBpZiAoaW5fYXJyYXkoJGd1ZXNzZWREb21haW4sICRjb25maWd1cmVkRG9tYWlucykgfHwgKCRwb3J0TnVtYmVyICYmIGluX2FycmF5KCRndWVzc2VkRG9tYWluLic6Jy4kcG9ydE51bWJlciwgJGNvbmZpZ3VyZWREb21haW5zKSkpIHsKICAgICAgICAgICAgaWYgKCRwb3J0TnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGd1ZXNzZWREb21haW4uJzonLiRwb3J0TnVtYmVyOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGd1ZXNzZWREb21haW47CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBvcnROdW1iZXIpIHsKICAgICAgICAgICAgJGd1ZXNzZWREb21haW4gLj0gJzonLiRwb3J0TnVtYmVyOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKG51bGwgIT09ICgkcGFydCA9IGFycmF5X3NoaWZ0KCR1cmxQYXJ0cykpKSB7CiAgICAgICAgICAgICRndWVzc2VkRG9tYWluIC49ICcvJyAuICRwYXJ0OwoKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRndWVzc2VkRG9tYWluLCAkY29uZmlndXJlZERvbWFpbnMpIHx8ICgkcG9ydE51bWJlciAmJiBpbl9hcnJheShQcmVnOjpyZXBsYWNlKCd7OlxkK30nLCAnJywgJGd1ZXNzZWREb21haW4pLCAkY29uZmlndXJlZERvbWFpbnMpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRndWVzc2VkRG9tYWluOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3M7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcQml0YnVja2V0Owp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIEBhdXRob3IgUGVyIEJlcm5oYXJkdCA8cGxiQHdlYmZhY3RvcnkuZGU+CiAqLwpjbGFzcyBHaXRCaXRidWNrZXREcml2ZXIgZXh0ZW5kcyBWY3NEcml2ZXIKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJG93bmVyOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHJlcG9zaXRvcnk7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRoYXNJc3N1ZXMgPSBmYWxzZTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByaXZhdGUgJHJvb3RJZGVudGlmaWVyOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiB0YWcgbmFtZSB0byBpZGVudGlmaWVyICovCiAgICBwcml2YXRlICR0YWdzOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiBicmFuY2ggbmFtZSB0byBpZGVudGlmaWVyICovCiAgICBwcml2YXRlICRicmFuY2hlczsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkYnJhbmNoZXNVcmwgPSAnJzsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkdGFnc1VybCA9ICcnOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRob21lVXJsID0gJyc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJHdlYnNpdGUgPSAnJzsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkY2xvbmVIdHRwc1VybCA9ICcnOwoKICAgIC8qKgogICAgICogQHZhciA/VmNzRHJpdmVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZmFsbGJhY2tEcml2ZXIgPSBudWxsOwogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgaWYgc2V0IGVpdGhlciBnaXQgb3IgaGcgKi8KICAgIHByaXZhdGUgJHZjc1R5cGU7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgUHJlZzo6bWF0Y2goJyNeaHR0cHM/Oi8vYml0YnVja2V0XC5vcmcvKFteL10rKS8oW14vXSs/KShcLmdpdHwvPyk/JCNpJywgJHRoaXMtPnVybCwgJG1hdGNoKTsKICAgICAgICAkdGhpcy0+b3duZXIgPSAkbWF0Y2hbMV07CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnkgPSAkbWF0Y2hbMl07CiAgICAgICAgJHRoaXMtPm9yaWdpblVybCA9ICdiaXRidWNrZXQub3JnJzsKICAgICAgICAkdGhpcy0+Y2FjaGUgPSBuZXcgQ2FjaGUoCiAgICAgICAgICAgICR0aGlzLT5pbywKICAgICAgICAgICAgaW1wbG9kZSgnLycsIGFycmF5KAogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZXBvLWRpcicpLAogICAgICAgICAgICAgICAgJHRoaXMtPm9yaWdpblVybCwKICAgICAgICAgICAgICAgICR0aGlzLT5vd25lciwKICAgICAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICApKQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmNhY2hlLT5zZXRSZWFkT25seSgkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXJlYWQtb25seScpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZmFsbGJhY2tEcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RyaXZlci0+Z2V0VXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNsb25lSHR0cHNVcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBmZXRjaCB0aGUgcmVwb3NpdG9yeSBkYXRhIHZpYSB0aGUgQml0QnVja2V0IEFQSSBhbmQKICAgICAqIHNldHMgc29tZSBwYXJhbWV0ZXJzIHdoaWNoIGFyZSB1c2VkIGluIG90aGVyIG1ldGhvZHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqIEBwaHBzdGFuLWltcHVyZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UmVwb0RhdGEoKQogICAgewogICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICdodHRwczovL2FwaS5iaXRidWNrZXQub3JnLzIuMC9yZXBvc2l0b3JpZXMvJXMvJXM/JXMnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICBodHRwX2J1aWxkX3F1ZXJ5KAogICAgICAgICAgICAgICAgYXJyYXkoJ2ZpZWxkcycgPT4gJy1wcm9qZWN0LC1vd25lcicpLAogICAgICAgICAgICAgICAgJycsCiAgICAgICAgICAgICAgICAnJicKICAgICAgICAgICAgKQogICAgICAgICk7CgogICAgICAgICRyZXBvRGF0YSA9ICR0aGlzLT5mZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCRyZXNvdXJjZSwgdHJ1ZSktPmRlY29kZUpzb24oKTsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnBhcnNlQ2xvbmVVcmxzKCRyZXBvRGF0YVsnbGlua3MnXVsnY2xvbmUnXSk7CgogICAgICAgICR0aGlzLT5oYXNJc3N1ZXMgPSAhZW1wdHkoJHJlcG9EYXRhWydoYXNfaXNzdWVzJ10pOwogICAgICAgICR0aGlzLT5icmFuY2hlc1VybCA9ICRyZXBvRGF0YVsnbGlua3MnXVsnYnJhbmNoZXMnXVsnaHJlZiddOwogICAgICAgICR0aGlzLT50YWdzVXJsID0gJHJlcG9EYXRhWydsaW5rcyddWyd0YWdzJ11bJ2hyZWYnXTsKICAgICAgICAkdGhpcy0+aG9tZVVybCA9ICRyZXBvRGF0YVsnbGlua3MnXVsnaHRtbCddWydocmVmJ107CiAgICAgICAgJHRoaXMtPndlYnNpdGUgPSAkcmVwb0RhdGFbJ3dlYnNpdGUnXTsKICAgICAgICAkdGhpcy0+dmNzVHlwZSA9ICRyZXBvRGF0YVsnc2NtJ107CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmluZm9DYWNoZVskaWRlbnRpZmllcl0pKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpICYmICRyZXMgPSAkdGhpcy0+Y2FjaGUtPnJlYWQoJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSBKc29uRmlsZTo6cGFyc2VKc29uKCRyZXMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldEJhc2VDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKTsKCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENhY2hlKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+d3JpdGUoJGlkZW50aWZpZXIsIGpzb25fZW5jb2RlKCRjb21wb3NlcikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICAgICAvLyBzcGVjaWFscyBmb3IgYml0YnVja2V0CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRjb21wb3Nlclsnc3VwcG9ydCddWydzb3VyY2UnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkbGFiZWwgPSBhcnJheV9zZWFyY2goCiAgICAgICAgICAgICAgICAgICAgICAgICRpZGVudGlmaWVyLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Z2V0VGFncygpCiAgICAgICAgICAgICAgICAgICAgKSA/OiBhcnJheV9zZWFyY2goCiAgICAgICAgICAgICAgICAgICAgICAgICRpZGVudGlmaWVyLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Z2V0QnJhbmNoZXMoKQogICAgICAgICAgICAgICAgICAgICkgPzogJGlkZW50aWZpZXI7CgogICAgICAgICAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCRsYWJlbCwgJHRhZ3MgPSAkdGhpcy0+Z2V0VGFncygpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaGFzaCA9ICR0YWdzWyRsYWJlbF07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKGFycmF5X2tleV9leGlzdHMoJGxhYmVsLCAkYnJhbmNoZXMgPSAkdGhpcy0+Z2V0QnJhbmNoZXMoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGhhc2ggPSAkYnJhbmNoZXNbJGxhYmVsXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGhhc2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb21wb3Nlclsnc3VwcG9ydCddWydzb3VyY2UnXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly8lcy8lcy8lcy9zcmMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9yaWdpblVybCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5vd25lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5CiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydzdXBwb3J0J11bJ3NvdXJjZSddID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdodHRwczovLyVzLyVzLyVzL3NyYy8lcy8/YXQ9JXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9yaWdpblVybCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5vd25lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGhhc2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGFiZWwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRjb21wb3Nlclsnc3VwcG9ydCddWydpc3N1ZXMnXSkgJiYgJHRoaXMtPmhhc0lzc3VlcykgewogICAgICAgICAgICAgICAgICAgICRjb21wb3Nlclsnc3VwcG9ydCddWydpc3N1ZXMnXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICdodHRwczovLyVzLyVzLyVzL2lzc3VlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5vcmlnaW5VcmwsCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5vd25lciwKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ2hvbWVwYWdlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydob21lcGFnZSddID0gZW1wdHkoJHRoaXMtPndlYnNpdGUpID8gJHRoaXMtPmhvbWVVcmwgOiAkdGhpcy0+d2Vic2l0ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmluZm9DYWNoZVskaWRlbnRpZmllcl0gPSAkY29tcG9zZXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmluZm9DYWNoZVskaWRlbnRpZmllcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZmFsbGJhY2tEcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RyaXZlci0+Z2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJGlkZW50aWZpZXIsICcvJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9ICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGJyYW5jaGVzWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgICAgICRpZGVudGlmaWVyID0gJGJyYW5jaGVzWyRpZGVudGlmaWVyXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc291cmNlID0gc3ByaW50ZigKICAgICAgICAgICAgJ2h0dHBzOi8vYXBpLmJpdGJ1Y2tldC5vcmcvMi4wL3JlcG9zaXRvcmllcy8lcy8lcy9zcmMvJXMvJXMnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICAkaWRlbnRpZmllciwKICAgICAgICAgICAgJGZpbGUKICAgICAgICApOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmZldGNoV2l0aE9BdXRoQ3JlZGVudGlhbHMoJHJlc291cmNlKS0+Z2V0Qm9keSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJGlkZW50aWZpZXIsICcvJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9ICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGJyYW5jaGVzWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgICAgICRpZGVudGlmaWVyID0gJGJyYW5jaGVzWyRpZGVudGlmaWVyXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc291cmNlID0gc3ByaW50ZigKICAgICAgICAgICAgJ2h0dHBzOi8vYXBpLmJpdGJ1Y2tldC5vcmcvMi4wL3JlcG9zaXRvcmllcy8lcy8lcy9jb21taXQvJXM/ZmllbGRzPWRhdGUnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICAkaWRlbnRpZmllcgogICAgICAgICk7CiAgICAgICAgJGNvbW1pdCA9ICR0aGlzLT5mZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCRyZXNvdXJjZSktPmRlY29kZUpzb24oKTsKCiAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJGNvbW1pdFsnZGF0ZSddKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRTb3VyY2UoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCd0eXBlJyA9PiAkdGhpcy0+dmNzVHlwZSwgJ3VybCcgPT4gJHRoaXMtPmdldFVybCgpLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldERpc3QoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgJHVybCA9IHNwcmludGYoCiAgICAgICAgICAgICdodHRwczovL2JpdGJ1Y2tldC5vcmcvJXMvJXMvZ2V0LyVzLnppcCcsCiAgICAgICAgICAgICR0aGlzLT5vd25lciwKICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnksCiAgICAgICAgICAgICRpZGVudGlmaWVyCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuIGFycmF5KCd0eXBlJyA9PiAnemlwJywgJ3VybCcgPT4gJHVybCwgJ3JlZmVyZW5jZScgPT4gJGlkZW50aWZpZXIsICdzaGFzdW0nID0+ICcnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldFRhZ3MoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+dGFncykgewogICAgICAgICAgICAkdGFncyA9IGFycmF5KCk7CiAgICAgICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAnJXM/JXMnLAogICAgICAgICAgICAgICAgJHRoaXMtPnRhZ3NVcmwsCiAgICAgICAgICAgICAgICBodHRwX2J1aWxkX3F1ZXJ5KAogICAgICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAncGFnZWxlbicgPT4gMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAnZmllbGRzJyA9PiAndmFsdWVzLm5hbWUsdmFsdWVzLnRhcmdldC5oYXNoLG5leHQnLAogICAgICAgICAgICAgICAgICAgICAgICAnc29ydCcgPT4gJy10YXJnZXQuZGF0ZScsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAnJywKICAgICAgICAgICAgICAgICAgICAnJicKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJGhhc05leHQgPSB0cnVlOwogICAgICAgICAgICB3aGlsZSAoJGhhc05leHQpIHsKICAgICAgICAgICAgICAgICR0YWdzRGF0YSA9ICR0aGlzLT5mZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCRyZXNvdXJjZSktPmRlY29kZUpzb24oKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0YWdzRGF0YVsndmFsdWVzJ10gYXMgJGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAkdGFnc1skZGF0YVsnbmFtZSddXSA9ICRkYXRhWyd0YXJnZXQnXVsnaGFzaCddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGVtcHR5KCR0YWdzRGF0YVsnbmV4dCddKSkgewogICAgICAgICAgICAgICAgICAgICRoYXNOZXh0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9ICR0YWdzRGF0YVsnbmV4dCddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+dGFncyA9ICR0YWdzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50YWdzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaGVzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldEJyYW5jaGVzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmJyYW5jaGVzKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAnJXM/JXMnLAogICAgICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzVXJsLAogICAgICAgICAgICAgICAgaHR0cF9idWlsZF9xdWVyeSgKICAgICAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZ2VsZW4nID0+IDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpZWxkcycgPT4gJ3ZhbHVlcy5uYW1lLHZhbHVlcy50YXJnZXQuaGFzaCx2YWx1ZXMuaGVhZHMsbmV4dCcsCiAgICAgICAgICAgICAgICAgICAgICAgICdzb3J0JyA9PiAnLXRhcmdldC5kYXRlJywKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICcnLAogICAgICAgICAgICAgICAgICAgICcmJwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgICAgICAkaGFzTmV4dCA9IHRydWU7CiAgICAgICAgICAgIHdoaWxlICgkaGFzTmV4dCkgewogICAgICAgICAgICAgICAgJGJyYW5jaERhdGEgPSAkdGhpcy0+ZmV0Y2hXaXRoT0F1dGhDcmVkZW50aWFscygkcmVzb3VyY2UpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYnJhbmNoRGF0YVsndmFsdWVzJ10gYXMgJGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJGRhdGFbJ25hbWUnXV0gPSAkZGF0YVsndGFyZ2V0J11bJ2hhc2gnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkYnJhbmNoRGF0YVsnbmV4dCddKSkgewogICAgICAgICAgICAgICAgICAgICRoYXNOZXh0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9ICRicmFuY2hEYXRhWyduZXh0J107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9ICRicmFuY2hlczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHJlbW90ZSBjb250ZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybCAgICAgICAgICAgICAgVGhlIFVSTCBvZiBjb250ZW50CiAgICAgKiBAcGFyYW0gYm9vbCAgICRmZXRjaGluZ1JlcG9EYXRhCiAgICAgKgogICAgICogQHJldHVybiBSZXNwb25zZSBUaGUgcmVzdWx0CiAgICAgKgogICAgICogQHBocHN0YW4taW1wdXJlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCR1cmwsICRmZXRjaGluZ1JlcG9EYXRhID0gZmFsc2UpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRiaXRidWNrZXRVdGlsID0gbmV3IEJpdGJ1Y2tldCgkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzLCAkdGhpcy0+aHR0cERvd25sb2FkZXIpOwoKICAgICAgICAgICAgaWYgKDQwMyA9PT0gJGUtPmdldENvZGUoKSB8fCAoNDAxID09PSAkZS0+Z2V0Q29kZSgpICYmIHN0cnBvcygkZS0+Z2V0TWVzc2FnZSgpLCAnQ291bGQgbm90IGF1dGhlbnRpY2F0ZSBhZ2FpbnN0JykgPT09IDApKSB7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJHRoaXMtPm9yaWdpblVybCkKICAgICAgICAgICAgICAgICAgICAmJiAkYml0YnVja2V0VXRpbC0+YXV0aG9yaXplT0F1dGgoJHRoaXMtPm9yaWdpblVybCkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmdldENvbnRlbnRzKCR1cmwpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkgJiYgJGZldGNoaW5nUmVwb0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YXR0ZW1wdENsb25lRmFsbGJhY2soKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAnZHVtbXknKSwgMjAwLCBhcnJheSgpLCAnbnVsbCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBTU0ggVVJMCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2dpdEAnIC4gJHRoaXMtPm9yaWdpblVybCAuICc6JyAuICR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgfQoKICAgIC8qKgogICAgICogQHBocHN0YW4taW1wdXJlCiAgICAgKgogICAgICogQHJldHVybiB0cnVlCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhdHRlbXB0Q2xvbmVGYWxsYmFjaygpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHRoaXMtPnNldHVwRmFsbGJhY2tEcml2ZXIoJHRoaXMtPmdlbmVyYXRlU3NoVXJsKCkpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRHJpdmVyID0gbnVsbDsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgICc8ZXJyb3I+RmFpbGVkIHRvIGNsb25lIHRoZSAnIC4gJHRoaXMtPmdlbmVyYXRlU3NoVXJsKCkgLiAnIHJlcG9zaXRvcnksIHRyeSBydW5uaW5nIGluIGludGVyYWN0aXZlIG1vZGUnCiAgICAgICAgICAgICAgICAgICAgLiAnIHNvIHRoYXQgeW91IGNhbiBlbnRlciB5b3VyIEJpdGJ1Y2tldCBPQXV0aCBjb25zdW1lciBjcmVkZW50aWFsczwvZXJyb3I+JwogICAgICAgICAgICApOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdXJsCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNldHVwRmFsbGJhY2tEcml2ZXIoJHVybCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEcml2ZXIgPSBuZXcgR2l0RHJpdmVyKAogICAgICAgICAgICBhcnJheSgndXJsJyA9PiAkdXJsKSwKICAgICAgICAgICAgJHRoaXMtPmlvLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLAogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIsCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmluaXRpYWxpemUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgYXJyYXk8YXJyYXl7bmFtZTogc3RyaW5nLCBocmVmOiBzdHJpbmd9PiAkY2xvbmVMaW5rcwogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNsb25lVXJscyhhcnJheSAkY2xvbmVMaW5rcykKICAgIHsKICAgICAgICBmb3JlYWNoICgkY2xvbmVMaW5rcyBhcyAkY2xvbmVMaW5rKSB7CiAgICAgICAgICAgIGlmICgkY2xvbmVMaW5rWyduYW1lJ10gPT09ICdodHRwcycpIHsKICAgICAgICAgICAgICAgIC8vIEZvcm1hdDogaHR0cHM6Ly8odXNlckApYml0YnVja2V0Lm9yZy97dXNlcn0ve3JlcG99CiAgICAgICAgICAgICAgICAvLyBTdHJpcCB1c2VybmFtZSBmcm9tIFVSTCAob25seSBwcmVzZW50IGluIGNsb25lIFVSTCdzIGZvciBwcml2YXRlIHJlcG9zaXRvcmllcykKICAgICAgICAgICAgICAgICR0aGlzLT5jbG9uZUh0dHBzVXJsID0gUHJlZzo6cmVwbGFjZSgnL2h0dHBzOlwvXC8oW15AXStAKT8vJywgJ2h0dHBzOi8vJywgJGNsb25lTGlua1snaHJlZiddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gKGFycmF5e25hbWU6IHN0cmluZ30mbWl4ZWRbXSl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TWFpbkJyYW5jaERhdGEoKQogICAgewogICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICdodHRwczovL2FwaS5iaXRidWNrZXQub3JnLzIuMC9yZXBvc2l0b3JpZXMvJXMvJXM/ZmllbGRzPW1haW5icmFuY2gnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5CiAgICAgICAgKTsKCiAgICAgICAgJGRhdGEgPSAkdGhpcy0+ZmV0Y2hXaXRoT0F1dGhDcmVkZW50aWFscygkcmVzb3VyY2UpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydtYWluYnJhbmNoJ10pKSB7CiAgICAgICAgICAgIHJldHVybiAkZGF0YVsnbWFpbmJyYW5jaCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZmFsbGJhY2tEcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cm9vdElkZW50aWZpZXIpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+Z2V0UmVwb0RhdGEoKSkgewogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZmFsbGJhY2tEcml2ZXIpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdBIGZhbGxiYWNrIGRyaXZlciBzaG91bGQgYmUgc2V0dXAgaWYgZ2V0UmVwb0RhdGEgcmV0dXJucyBmYWxzZScpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+dmNzVHlwZSAhPT0gJ2dpdCcpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXJsLicgZG9lcyBub3QgYXBwZWFyIHRvIGJlIGEgZ2l0IHJlcG9zaXRvcnksIHVzZSAnLgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jbG9uZUh0dHBzVXJsLicgYnV0IHJlbWVtYmVyIHRoYXQgQml0YnVja2V0IG5vIGxvbmdlciBzdXBwb3J0cyB0aGUgbWVyY3VyaWFsIHJlcG9zaXRvcmllcy4gJy4KICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly9iaXRidWNrZXQub3JnL2Jsb2cvc3Vuc2V0dGluZy1tZXJjdXJpYWwtc3VwcG9ydC1pbi1iaXRidWNrZXQnCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWFpbkJyYW5jaERhdGEgPSAkdGhpcy0+Z2V0TWFpbkJyYW5jaERhdGEoKTsKICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gIWVtcHR5KCRtYWluQnJhbmNoRGF0YVsnbmFtZSddKSA/ICRtYWluQnJhbmNoRGF0YVsnbmFtZSddIDogJ21hc3Rlcic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3RJZGVudGlmaWVyOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdXBwb3J0cyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkdXJsLCAkZGVlcCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgnI15odHRwcz86Ly9iaXRidWNrZXRcLm9yZy8oW14vXSspLyhbXi9dKz8pKFwuZ2l0fC8/KT8kI2knLCAkdXJsKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1NraXBwaW5nIEJpdGJ1Y2tldCBnaXQgZHJpdmVyIGZvciAnLiR1cmwuJyBiZWNhdXNlIHRoZSBPcGVuU1NMIFBIUCBleHRlbnNpb24gaXMgbWlzc2luZy4nLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBCb2h3YVogPGh0dHA6Ly9ib2h3YXoubmV0Lz4KICovCmNsYXNzIEZvc3NpbERyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gTWFwIG9mIHRhZyBuYW1lIHRvIGlkZW50aWZpZXIgKi8KICAgIHByb3RlY3RlZCAkdGFnczsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgc3RyaW5nPiBNYXAgb2YgYnJhbmNoIG5hbWUgdG8gaWRlbnRpZmllciAqLwogICAgcHJvdGVjdGVkICRicmFuY2hlczsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcm9vdElkZW50aWZpZXIgPSBudWxsOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRyZXBvRmlsZSA9IG51bGw7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkY2hlY2tvdXREaXI7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgLy8gTWFrZSBzdXJlIGZvc3NpbCBpcyBpbnN0YWxsZWQgYW5kIHJlYWNoYWJsZS4KICAgICAgICAkdGhpcy0+Y2hlY2tGb3NzaWwoKTsKCiAgICAgICAgLy8gRW5zdXJlIHdlIGFyZSBhbGxvd2VkIHRvIHVzZSB0aGlzIFVSTCBieSBjb25maWcuCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdGhpcy0+dXJsLCAkdGhpcy0+aW8pOwoKICAgICAgICAvLyBPbmx5IGlmIHVybCBwb2ludHMgdG8gYSBsb2NhbGx5IGFjY2Vzc2libGUgZGlyZWN0b3J5LCBhc3N1bWUgaXQncyB0aGUgY2hlY2tvdXQgZGlyZWN0b3J5LgogICAgICAgIC8vIE90aGVyd2lzZSwgaXQgc2hvdWxkIGJlIHNvbWV0aGluZyBmb3NzaWwgY2FuIGNsb25lIGZyb20uCiAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzTG9jYWxQYXRoKCR0aGlzLT51cmwpICYmIGlzX2RpcigkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tvdXREaXIgPSAkdGhpcy0+dXJsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghQ2FjaGU6OmlzVXNhYmxlKChzdHJpbmcpICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKSkgfHwgIUNhY2hlOjppc1VzYWJsZSgoc3RyaW5nKSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRm9zc2lsRHJpdmVyIHJlcXVpcmVzIGEgdXNhYmxlIGNhY2hlIGRpcmVjdG9yeSwgYW5kIGl0IGxvb2tzIGxpa2UgeW91IHNldCBpdCB0byBiZSBkaXNhYmxlZCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG9jYWxOYW1lID0gUHJlZzo6cmVwbGFjZSgne1teYS16MC05XX1pJywgJy0nLCAkdGhpcy0+dXJsKTsKICAgICAgICAgICAgJHRoaXMtPnJlcG9GaWxlID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZXBvLWRpcicpIC4gJy8nIC4gJGxvY2FsTmFtZSAuICcuZm9zc2lsJzsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrb3V0RGlyID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJykgLiAnLycgLiAkbG9jYWxOYW1lIC4gJy8nOwoKICAgICAgICAgICAgJHRoaXMtPnVwZGF0ZUxvY2FsUmVwbygpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmdldFRhZ3MoKTsKICAgICAgICAkdGhpcy0+Z2V0QnJhbmNoZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHRoYXQgZm9zc2lsIGNhbiBiZSBpbnZva2VkIHZpYSBjb21tYW5kIGxpbmUuCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0Zvc3NpbCgpCiAgICB7CiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdmb3NzaWwgdmVyc2lvbicsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oImZvc3NpbCB3YXMgbm90IGZvdW5kLCBjaGVjayB0aGF0IGl0IGlzIGluc3RhbGxlZCBhbmQgaW4geW91ciBQQVRIIGVudi5cblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbG9uZSBvciB1cGRhdGUgZXhpc3RpbmcgbG9jYWwgZm9zc2lsIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVMb2NhbFJlcG8oKQogICAgewogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgJGZzLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoJHRoaXMtPmNoZWNrb3V0RGlyKTsKCiAgICAgICAgaWYgKCFpc193cml0YWJsZShkaXJuYW1lKCR0aGlzLT5jaGVja291dERpcikpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ2FuIG5vdCBjbG9uZSAnLiR0aGlzLT51cmwuJyB0byBhY2Nlc3MgcGFja2FnZSBpbmZvcm1hdGlvbi4gVGhlICInLiR0aGlzLT5jaGVja291dERpci4nIiBkaXJlY3RvcnkgaXMgbm90IHdyaXRhYmxlIGJ5IHRoZSBjdXJyZW50IHVzZXIuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyB1cGRhdGUgdGhlIHJlcG8gaWYgaXQgaXMgYSB2YWxpZCBmb3NzaWwgcmVwb3NpdG9yeQogICAgICAgIGlmIChpc19maWxlKCR0aGlzLT5yZXBvRmlsZSkgJiYgaXNfZGlyKCR0aGlzLT5jaGVja291dERpcikgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCBpbmZvJywgJG91dHB1dCwgJHRoaXMtPmNoZWNrb3V0RGlyKSkgewogICAgICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCBwdWxsJywgJG91dHB1dCwgJHRoaXMtPmNoZWNrb3V0RGlyKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+RmFpbGVkIHRvIHVwZGF0ZSAnLiR0aGlzLT51cmwuJywgcGFja2FnZSBpbmZvcm1hdGlvbiBmcm9tIHRoaXMgcmVwb3NpdG9yeSBtYXkgYmUgb3V0ZGF0ZWQgKCcuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkuJyk8L2Vycm9yPicpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gY2xlYW4gdXAgZGlyZWN0b3J5IGFuZCBkbyBhIGZyZXNoIGNsb25lIGludG8gaXQKICAgICAgICAgICAgJGZzLT5yZW1vdmVEaXJlY3RvcnkoJHRoaXMtPmNoZWNrb3V0RGlyKTsKICAgICAgICAgICAgJGZzLT5yZW1vdmUoJHRoaXMtPnJlcG9GaWxlKTsKCiAgICAgICAgICAgICRmcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0aGlzLT5jaGVja291dERpcik7CgogICAgICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoc3ByaW50ZignZm9zc2lsIGNsb25lIC0tICVzICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRoaXMtPnVybCksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0aGlzLT5yZXBvRmlsZSkpLCAkb3V0cHV0KSkgewogICAgICAgICAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGNsb25lICcuJHRoaXMtPnVybC4nIHRvIHJlcG9zaXRvcnkgJyAuICR0aGlzLT5yZXBvRmlsZSAuICJcblxuIiAuJG91dHB1dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZShzcHJpbnRmKCdmb3NzaWwgb3BlbiAtLW5lc3RlZCAtLSAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0aGlzLT5yZXBvRmlsZSkpLCAkb3V0cHV0LCAkdGhpcy0+Y2hlY2tvdXREaXIpKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gb3BlbiByZXBvc2l0b3J5ICcuJHRoaXMtPnJlcG9GaWxlLicgaW4gJyAuICR0aGlzLT5jaGVja291dERpciAuICJcblxuIiAuJG91dHB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cm9vdElkZW50aWZpZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gJ3RydW5rJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdElkZW50aWZpZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KCd0eXBlJyA9PiAnZm9zc2lsJywgJ3VybCcgPT4gJHRoaXMtPmdldFVybCgpLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdmb3NzaWwgY2F0IC1yICVzIC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGlkZW50aWZpZXIpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkpOwogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkY29udGVudCwgJHRoaXMtPmNoZWNrb3V0RGlyKTsKCiAgICAgICAgaWYgKCF0cmltKCRjb250ZW50KSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdmb3NzaWwgZmluZm8gLWIgLW4gMSBjb21wb3Nlci5qc29uJywgJG91dHB1dCwgJHRoaXMtPmNoZWNrb3V0RGlyKTsKICAgICAgICBsaXN0KCwgJGRhdGUpID0gZXhwbG9kZSgnICcsIHRyaW0oJG91dHB1dCksIDMpOwoKICAgICAgICByZXR1cm4gbmV3IFxEYXRlVGltZSgkZGF0ZSwgbmV3IFxEYXRlVGltZVpvbmUoJ1VUQycpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnRhZ3MpIHsKICAgICAgICAgICAgJHRhZ3MgPSBhcnJheSgpOwoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCB0YWcgbGlzdCcsICRvdXRwdXQsICR0aGlzLT5jaGVja291dERpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICR0YWcpIHsKICAgICAgICAgICAgICAgICR0YWdzWyR0YWddID0gJHRhZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnRhZ3MgPSAkdGFnczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgpOwoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCBicmFuY2ggbGlzdCcsICRvdXRwdXQsICR0aGlzLT5jaGVja291dERpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRicmFuY2gpIHsKICAgICAgICAgICAgICAgICRicmFuY2ggPSB0cmltKFByZWc6OnJlcGxhY2UoJy9eXCovJywgJycsIHRyaW0oJGJyYW5jaCkpKTsKICAgICAgICAgICAgICAgICRicmFuY2hlc1skYnJhbmNoXSA9ICRicmFuY2g7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9ICRicmFuY2hlczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyMoXig/Omh0dHBzP3xzc2gpOi8vKD86W15AXUApPyg/OmNoaXNlbGFwcFwuY29tfGZvc3NpbFwuKSkjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyEvZm9zc2lsL3xcLmZvc3NpbCEnLCAkdXJsKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGxvY2FsIGZpbGVzeXN0ZW0KICAgICAgICBpZiAoRmlsZXN5c3RlbTo6aXNMb2NhbFBhdGgoJHVybCkpIHsKICAgICAgICAgICAgJHVybCA9IEZpbGVzeXN0ZW06OmdldFBsYXRmb3JtUGF0aCgkdXJsKTsKICAgICAgICAgICAgaWYgKCFpc19kaXIoJHVybCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBmb3NzaWwgcmVwbyBpbiB0aGF0IHBhdGgKICAgICAgICAgICAgaWYgKCRwcm9jZXNzLT5leGVjdXRlKCdmb3NzaWwgaW5mbycsICRvdXRwdXQsICR1cmwpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnREaXNwYXRjaGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwoKLyoqCiAqIFJlcG9zaXRvcmllcyBtYW5hZ2VyLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgRnJhbsOnb2lzIFBsdWNoaW5vIDxmcmFuY29pcy5wbHVjaGlub0BvcGVuZGlzcGxheS5jb20+CiAqLwpjbGFzcyBSZXBvc2l0b3J5TWFuYWdlcgp7CiAgICAvKiogQHZhciBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICovCiAgICBwcml2YXRlICRsb2NhbFJlcG9zaXRvcnk7CiAgICAvKiogQHZhciBsaXN0PFJlcG9zaXRvcnlJbnRlcmZhY2U+ICovCiAgICBwcml2YXRlICRyZXBvc2l0b3JpZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBjbGFzcy1zdHJpbmc8UmVwb3NpdG9yeUludGVyZmFjZT4+ICovCiAgICBwcml2YXRlICRyZXBvc2l0b3J5Q2xhc3NlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcml2YXRlICRodHRwRG93bmxvYWRlcjsKICAgIC8qKiBAdmFyID9FdmVudERpc3BhdGNoZXIgKi8KICAgIHByaXZhdGUgJGV2ZW50RGlzcGF0Y2hlcjsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJpdmF0ZSAkcHJvY2VzczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciA9IG51bGwsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyID0gJGV2ZW50RGlzcGF0Y2hlcjsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNlYXJjaGVzIGZvciBhIHBhY2thZ2UgYnkgaXRzIG5hbWUgYW5kIHZlcnNpb24gaW4gbWFuYWdlZCByZXBvc2l0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8XENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgcGFja2FnZSB2ZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBtYXRjaCBhZ2FpbnN0CiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkgKi8KICAgICAgICAgICAgaWYgKCRwYWNrYWdlID0gJHJlcG9zaXRvcnktPmZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZWFyY2hlcyBmb3IgYWxsIHBhY2thZ2VzIG1hdGNoaW5nIGEgbmFtZSBhbmQgb3B0aW9uYWxseSBhIHZlcnNpb24gaW4gbWFuYWdlZCByZXBvc2l0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8XENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgcGFja2FnZSB2ZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBtYXRjaCBhZ2FpbnN0CiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFJlcG9zaXRvcmllcygpIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5X21lcmdlKCRwYWNrYWdlcywgJHJlcG9zaXRvcnktPmZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3NpdG9yeSByZXBvc2l0b3J5IGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllc1tdID0gJHJlcG9zaXRvcnk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgcmVwb3NpdG9yeSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBjaGFpbgogICAgICoKICAgICAqIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW5qZWN0aW5nIGFkZGl0aW9uYWwgcmVwb3NpdG9yaWVzIHRoYXQgc2hvdWxkIHRydW1wIFBhY2thZ2lzdCwgZS5nLiBmcm9tIGEgcGx1Z2luLgogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5IHJlcG9zaXRvcnkgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBlbmRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgYXJyYXlfdW5zaGlmdCgkdGhpcy0+cmVwb3NpdG9yaWVzLCAkcmVwb3NpdG9yeSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmV3IHJlcG9zaXRvcnkgZm9yIGEgc3BlY2lmaWMgaW5zdGFsbGF0aW9uIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICR0eXBlICAgcmVwb3NpdG9yeSB0eXBlCiAgICAgKiBAcGFyYW0gIGFycmF5PHN0cmluZywgbWl4ZWQ+ICAgICAgJGNvbmZpZyByZXBvc2l0b3J5IGNvbmZpZ3VyYXRpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkbmFtZSAgIHJlcG9zaXRvcnkgbmFtZQogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHJlcG9zaXRvcnkgZm9yIHByb3ZpZGVkIHR5cGUgaXMgbm90IHJlZ2lzdGVyZWQKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUmVwb3NpdG9yeSgkdHlwZSwgJGNvbmZpZywgJG5hbWUgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlcG9zaXRvcnlDbGFzc2VzWyR0eXBlXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1JlcG9zaXRvcnkgdHlwZSBpcyBub3QgcmVnaXN0ZXJlZDogJy4kdHlwZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1sncGFja2FnaXN0J10pICYmIGZhbHNlID09PSAkY29uZmlnWydwYWNrYWdpc3QnXSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlJlcG9zaXRvcnkgIicuJG5hbWUuJyIgKCcuanNvbl9lbmNvZGUoJGNvbmZpZykuJykgaGFzIGEgcGFja2FnaXN0IGtleSB3aGljaCBzaG91bGQgYmUgaW4gaXRzIG93biByZXBvc2l0b3J5IGRlZmluaXRpb248L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICAkY2xhc3MgPSAkdGhpcy0+cmVwb3NpdG9yeUNsYXNzZXNbJHR5cGVdOwoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snb25seSddKSB8fCBpc3NldCgkY29uZmlnWydleGNsdWRlJ10pIHx8IGlzc2V0KCRjb25maWdbJ2Nhbm9uaWNhbCddKSkgewogICAgICAgICAgICAkZmlsdGVyQ29uZmlnID0gJGNvbmZpZzsKICAgICAgICAgICAgdW5zZXQoJGNvbmZpZ1snb25seSddLCAkY29uZmlnWydleGNsdWRlJ10sICRjb25maWdbJ2Nhbm9uaWNhbCddKTsKICAgICAgICB9CgogICAgICAgICRyZXBvc2l0b3J5ID0gbmV3ICRjbGFzcygkY29uZmlnLCAkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5odHRwRG93bmxvYWRlciwgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlciwgJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICBpZiAoaXNzZXQoJGZpbHRlckNvbmZpZykpIHsKICAgICAgICAgICAgJHJlcG9zaXRvcnkgPSBuZXcgRmlsdGVyUmVwb3NpdG9yeSgkcmVwb3NpdG9yeSwgJGZpbHRlckNvbmZpZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlcG9zaXRvcnk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZXMgcmVwb3NpdG9yeSBjbGFzcyBmb3IgYSBzcGVjaWZpYyBpbnN0YWxsYXRpb24gdHlwZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlICBpbnN0YWxsYXRpb24gdHlwZQogICAgICogQHBhcmFtIGNsYXNzLXN0cmluZzxSZXBvc2l0b3J5SW50ZXJmYWNlPiAkY2xhc3MgY2xhc3MgbmFtZSBvZiB0aGUgcmVwbyBpbXBsZW1lbnRhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yeUNsYXNzKCR0eXBlLCAkY2xhc3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlDbGFzc2VzWyR0eXBlXSA9ICRjbGFzczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIHJlcG9zaXRvcmllcywgZXhjZXB0IGxvY2FsIG9uZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgbG9jYWwgcmVwb3NpdG9yeSBmb3IgdGhlIHByb2plY3QuCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkgcmVwb3NpdG9yeSBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9jYWxSZXBvc2l0b3J5KEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2FsUmVwb3NpdG9yeSA9ICRyZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBsb2NhbCByZXBvc2l0b3J5IGZvciB0aGUgcHJvamVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2FsUmVwb3NpdG9yeSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NhbFJlcG9zaXRvcnk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUG9vbE9wdGltaXplcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxQb2xpY3lJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUG9vbDsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxQb29sQnVpbGRlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZUFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludEludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxTdGFiaWxpdHlGaWx0ZXI7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJlcG9zaXRvcnlTZXQKewogICAgLyoqCiAgICAgKiBQYWNrYWdlcyBhcmUgcmV0dXJuZWQgZXZlbiB0aG91Z2ggdGhlaXIgc3RhYmlsaXR5IGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlZCBzdGFiaWxpdHkKICAgICAqLwogICAgY29uc3QgQUxMT1dfVU5BQ0NFUFRBQkxFX1NUQUJJTElUSUVTID0gMTsKICAgIC8qKgogICAgICogUGFja2FnZXMgd2lsbCBiZSBsb29rZWQgdXAgaW4gYWxsIHJlcG9zaXRvcmllcywgZXZlbiBhZnRlciB0aGV5IGhhdmUgYmVlbiBmb3VuZCBpbiBhIGhpZ2hlciBwcmlvIG9uZQogICAgICovCiAgICBjb25zdCBBTExPV19TSEFET1dFRF9SRVBPU0lUT1JJRVMgPSAyOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheVtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGFycmF5e2FsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+PgogICAgICovCiAgICBwcml2YXRlICRyb290QWxpYXNlczsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSAkcm9vdFJlZmVyZW5jZXM7CgogICAgLyoqIEB2YXIgUmVwb3NpdG9yeUludGVyZmFjZVtdICovCiAgICBwcml2YXRlICRyZXBvc2l0b3JpZXMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciBpbnRbXSBhcnJheSBvZiBzdGFiaWxpdHkgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+CiAgICAgKi8KICAgIHByaXZhdGUgJGFjY2VwdGFibGVTdGFiaWxpdGllczsKCiAgICAvKioKICAgICAqIEB2YXIgaW50W10gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPgogICAgICovCiAgICBwcml2YXRlICRzdGFiaWxpdHlGbGFnczsKCiAgICAvKioKICAgICAqIEB2YXIgQ29uc3RyYWludEludGVyZmFjZVtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlICRyb290UmVxdWlyZXM7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkbG9ja2VkID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRhbGxvd0luc3RhbGxlZFJlcG9zaXRvcmllcyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogSW4gbW9zdCBjYXNlcyBpZiB5b3UgYXJlIGxvb2tpbmcgdG8gdXNlIHRoaXMgY2xhc3MgYXMgYSB3YXkgdG8gZmluZCBwYWNrYWdlcyBmcm9tIHJlcG9zaXRvcmllcwogICAgICogcGFzc2luZyBtaW5pbXVtU3RhYmlsaXR5IGlzIGFsbCB5b3UgbmVlZCB0byB3b3JyeSBhYm91dC4gVGhlIHJlc3QgaXMgZm9yIGFkdmFuY2VkIHBvb2wgY3JlYXRpb24gaW5jbHVkaW5nCiAgICAgKiBhbGlhc2VzLCBwaW5uZWQgcmVmZXJlbmNlcyBhbmQgb3RoZXIgc3BlY2lhbCBjYXNlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtaW5pbXVtU3RhYmlsaXR5CiAgICAgKiBAcGFyYW0gaW50W10gICRzdGFiaWxpdHlGbGFncyAgIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwYXJhbSBhcnJheVtdICRyb290QWxpYXNlcwogICAgICogQHBocHN0YW4tcGFyYW0gbGlzdDxhcnJheXtwYWNrYWdlOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgYWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4gJHJvb3RBbGlhc2VzCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHJvb3RSZWZlcmVuY2VzIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBzb3VyY2UgcmVmZXJlbmNlCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJHJvb3RSZWZlcmVuY2VzCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZVtdICRyb290UmVxdWlyZXMgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IGNvbnN0cmFpbnQgZnJvbSB0aGUgcm9vdCBwYWNrYWdlCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxzdHJpbmcsIENvbnN0cmFpbnRJbnRlcmZhY2U+ICRyb290UmVxdWlyZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtaW5pbXVtU3RhYmlsaXR5ID0gJ3N0YWJsZScsIGFycmF5ICRzdGFiaWxpdHlGbGFncyA9IGFycmF5KCksIGFycmF5ICRyb290QWxpYXNlcyA9IGFycmF5KCksIGFycmF5ICRyb290UmVmZXJlbmNlcyA9IGFycmF5KCksIGFycmF5ICRyb290UmVxdWlyZXMgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5yb290QWxpYXNlcyA9IHNlbGY6OmdldFJvb3RBbGlhc2VzUGVyUGFja2FnZSgkcm9vdEFsaWFzZXMpOwogICAgICAgICR0aGlzLT5yb290UmVmZXJlbmNlcyA9ICRyb290UmVmZXJlbmNlczsKCiAgICAgICAgJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllcyBhcyAkc3RhYmlsaXR5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICBpZiAoJHZhbHVlIDw9IEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbJG1pbmltdW1TdGFiaWxpdHldKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWNjZXB0YWJsZVN0YWJpbGl0aWVzWyRzdGFiaWxpdHldID0gJHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR0aGlzLT5zdGFiaWxpdHlGbGFncyA9ICRzdGFiaWxpdHlGbGFnczsKICAgICAgICAkdGhpcy0+cm9vdFJlcXVpcmVzID0gJHJvb3RSZXF1aXJlczsKICAgICAgICBmb3JlYWNoICgkcm9vdFJlcXVpcmVzIGFzICRuYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSkgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnJvb3RSZXF1aXJlc1skbmFtZV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGFsbG93CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGxvd0luc3RhbGxlZFJlcG9zaXRvcmllcygkYWxsb3cgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5hbGxvd0luc3RhbGxlZFJlcG9zaXRvcmllcyA9ICRhbGxvdzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29uc3RyYWludEludGVyZmFjZVtdIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBjb25zdHJhaW50IGZyb20gdGhlIHJvb3QgcGFja2FnZSwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIGV4Y2x1ZGVkCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdFJlcXVpcmVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3RSZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSByZXBvc2l0b3J5IHRvIHRoaXMgcmVwb3NpdG9yeSBzZXQKICAgICAqCiAgICAgKiBUaGUgZmlyc3QgcmVwb3MgYWRkZWQgaGF2ZSBhIGhpZ2hlciBwcmlvcml0eS4gQXMgc29vbiBhcyBhIHBhY2thZ2UgaXMgZm91bmQgaW4gYW55CiAgICAgKiByZXBvc2l0b3J5IHRoZSBzZWFyY2ggZm9yIHRoYXQgcGFja2FnZSBlbmRzLCBhbmQgZm9sbG93aW5nIHJlcG9zIHdpbGwgbm90IGJlIGNvbnN1bHRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyBBIHBhY2thZ2UgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUmVwb3NpdG9yeShSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvKQogICAgewogICAgICAgIGlmICgkdGhpcy0+bG9ja2VkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiUG9vbCBoYXMgYWxyZWFkeSBiZWVuIGNyZWF0ZWQgZnJvbSB0aGlzIHJlcG9zaXRvcnkgc2V0LCBpdCBjYW5ub3QgYmUgbW9kaWZpZWQgYW55bW9yZS4iKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcmVwbyBpbnN0YW5jZW9mIENvbXBvc2l0ZVJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgJHJlcG9zID0gJHJlcG8tPmdldFJlcG9zaXRvcmllcygpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXBvcyA9IGFycmF5KCRyZXBvKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZXBvcyBhcyAkcmVwbykgewogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzW10gPSAkcmVwbzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kIHBhY2thZ2VzIHByb3ZpZGluZyBvciBtYXRjaGluZyBhIG5hbWUgYW5kIG9wdGlvbmFsbHkgbWVldGluZyBhIGNvbnN0cmFpbnQgaW4gYWxsIHJlcG9zaXRvcmllcwogICAgICoKICAgICAqIFJldHVybmVkIGluIHRoZSBvcmRlciBvZiByZXBvc2l0b3JpZXMsIG1hdGNoaW5nIHByaW9yaXR5CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgJG5hbWUKICAgICAqIEBwYXJhbSAgQ29uc3RyYWludEludGVyZmFjZXxudWxsICRjb25zdHJhaW50CiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAgICAgICAkZmxhZ3MgICAgICBhbnkgb2YgdGhlIEFMTE9XXyogY29uc3RhbnRzIGZyb20gdGhpcyBjbGFzcyB0byB0d2VhayB3aGF0IGlzIHJldHVybmVkCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCA9IG51bGwsICRmbGFncyA9IDApCiAgICB7CiAgICAgICAgJGlnbm9yZVN0YWJpbGl0eSA9ICgkZmxhZ3MgJiBzZWxmOjpBTExPV19VTkFDQ0VQVEFCTEVfU1RBQklMSVRJRVMpICE9PSAwOwogICAgICAgICRsb2FkRnJvbUFsbFJlcG9zID0gKCRmbGFncyAmIHNlbGY6OkFMTE9XX1NIQURPV0VEX1JFUE9TSVRPUklFUykgIT09IDA7CgogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRsb2FkRnJvbUFsbFJlcG9zKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHJlcG9zaXRvcnktPmZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpID86IGFycmF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHJlcG9zaXRvcnktPmxvYWRQYWNrYWdlcyhhcnJheSgkbmFtZSA9PiAkY29uc3RyYWludCksICRpZ25vcmVTdGFiaWxpdHkgPyBCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzIDogJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllcywgJGlnbm9yZVN0YWJpbGl0eSA/IGFycmF5KCkgOiAkdGhpcy0+c3RhYmlsaXR5RmxhZ3MpOwoKICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHJlc3VsdFsncGFja2FnZXMnXTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZXN1bHRbJ25hbWVzRm91bmQnXSBhcyAkbmFtZUZvdW5kKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgbG9hZGluZyB0aGUgc2FtZSBwYWNrYWdlIGFnYWluIGZyb20gb3RoZXIgcmVwb3NpdG9yaWVzIG9uY2UgaXQgaGFzIGJlZW4gZm91bmQKICAgICAgICAgICAgICAgICAgICBpZiAoJG5hbWUgPT09ICRuYW1lRm91bmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjYW5kaWRhdGVzID0gJHBhY2thZ2VzID8gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJHBhY2thZ2VzKSA6IGFycmF5KCk7CgogICAgICAgIC8vIHdoZW4gdXNpbmcgbG9hZFBhY2thZ2VzIGFib3ZlICghJGxvYWRGcm9tQWxsUmVwb3MpIHRoZSByZXBvcyBhbHJlYWR5IGZpbHRlciBmb3Igc3RhYmlsaXR5IHNvIG5vIG5lZWQgdG8gZG8gaXQgYWdhaW4KICAgICAgICBpZiAoJGlnbm9yZVN0YWJpbGl0eSB8fCAhJGxvYWRGcm9tQWxsUmVwb3MpIHsKICAgICAgICAgICAgcmV0dXJuICRjYW5kaWRhdGVzOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZXMgYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmlzUGFja2FnZUFjY2VwdGFibGUoJGNhbmRpZGF0ZS0+Z2V0TmFtZXMoKSwgJGNhbmRpZGF0ZS0+Z2V0U3RhYmlsaXR5KCkpKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkY2FuZGlkYXRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHBhY2thZ2VOYW1lCiAgICAgKgogICAgICogQHJldHVybiBhcnJheVtdIGFuIGFycmF5IHdpdGggdGhlIHByb3ZpZGVyIG5hbWUgYXMga2V5IGFuZCB2YWx1ZSBvZiBhcnJheSgnbmFtZScgPT4gJy4uLicsICdkZXNjcmlwdGlvbicgPT4gJy4uLicsICd0eXBlJyA9PiAnLi4uJykKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheTxzdHJpbmcsIGFycmF5e25hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgdHlwZTogc3RyaW5nfT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3ZpZGVycygkcGFja2FnZU5hbWUpCiAgICB7CiAgICAgICAgJHByb3ZpZGVycyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICBpZiAoJHJlcG9Qcm92aWRlcnMgPSAkcmVwb3NpdG9yeS0+Z2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkpIHsKICAgICAgICAgICAgICAgICRwcm92aWRlcnMgPSBhcnJheV9tZXJnZSgkcHJvdmlkZXJzLCAkcmVwb1Byb3ZpZGVycyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvdmlkZXJzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgZm9yIGVhY2ggZ2l2ZW4gcGFja2FnZSBuYW1lIHdoZXRoZXIgaXQgd291bGQgYmUgYWNjZXB0ZWQgYnkgdGhpcyBSZXBvc2l0b3J5U2V0IGluIHRoZSBnaXZlbiAkc3RhYmlsaXR5CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmdbXSAkbmFtZXMKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHN0YWJpbGl0eSBvbmUgb2YgJ3N0YWJsZScsICdSQycsICdiZXRhJywgJ2FscGhhJyBvciAnZGV2JwogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1BhY2thZ2VBY2NlcHRhYmxlKCRuYW1lcywgJHN0YWJpbGl0eSkKICAgIHsKICAgICAgICByZXR1cm4gU3RhYmlsaXR5RmlsdGVyOjppc1BhY2thZ2VBY2NlcHRhYmxlKCR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMsICR0aGlzLT5zdGFiaWxpdHlGbGFncywgJG5hbWVzLCAkc3RhYmlsaXR5KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHBvb2wgZm9yIGRlcGVuZGVuY3kgcmVzb2x1dGlvbiBmcm9tIHRoZSBwYWNrYWdlcyBpbiB0aGlzIHJlcG9zaXRvcnkgc2V0LgogICAgICoKICAgICAqIEByZXR1cm4gUG9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUG9vbChSZXF1ZXN0ICRyZXF1ZXN0LCBJT0ludGVyZmFjZSAkaW8sIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyID0gbnVsbCwgUG9vbE9wdGltaXplciAkcG9vbE9wdGltaXplciA9IG51bGwpCiAgICB7CiAgICAgICAgJHBvb2xCdWlsZGVyID0gbmV3IFBvb2xCdWlsZGVyKCR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMsICR0aGlzLT5zdGFiaWxpdHlGbGFncywgJHRoaXMtPnJvb3RBbGlhc2VzLCAkdGhpcy0+cm9vdFJlZmVyZW5jZXMsICRpbywgJGV2ZW50RGlzcGF0Y2hlciwgJHBvb2xPcHRpbWl6ZXIpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvKSB7CiAgICAgICAgICAgIGlmICgoJHJlcG8gaW5zdGFuY2VvZiBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlIHx8ICRyZXBvIGluc3RhbmNlb2YgSW5zdGFsbGVkUmVwb3NpdG9yeSkgJiYgISR0aGlzLT5hbGxvd0luc3RhbGxlZFJlcG9zaXRvcmllcykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignVGhlIHBvb2wgY2FuIG5vdCBhY2NlcHQgcGFja2FnZXMgZnJvbSBhbiBpbnN0YWxsZWQgcmVwb3NpdG9yeScpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9ja2VkID0gdHJ1ZTsKCiAgICAgICAgcmV0dXJuICRwb29sQnVpbGRlci0+YnVpbGRQb29sKCR0aGlzLT5yZXBvc2l0b3JpZXMsICRyZXF1ZXN0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHBvb2wgZm9yIGRlcGVuZGVuY3kgcmVzb2x1dGlvbiBmcm9tIHRoZSBwYWNrYWdlcyBpbiB0aGlzIHJlcG9zaXRvcnkgc2V0LgogICAgICoKICAgICAqIEByZXR1cm4gUG9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUG9vbFdpdGhBbGxQYWNrYWdlcygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwbykgewogICAgICAgICAgICBpZiAoKCRyZXBvIGluc3RhbmNlb2YgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSB8fCAkcmVwbyBpbnN0YW5jZW9mIEluc3RhbGxlZFJlcG9zaXRvcnkpICYmICEkdGhpcy0+YWxsb3dJbnN0YWxsZWRSZXBvc2l0b3JpZXMpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ1RoZSBwb29sIGNhbiBub3QgYWNjZXB0IHBhY2thZ2VzIGZyb20gYW4gaW5zdGFsbGVkIHJlcG9zaXRvcnknKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxvY2tlZCA9IHRydWU7CgogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcGFja2FnZTsKCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJvb3RBbGlhc2VzWyRwYWNrYWdlLT5nZXROYW1lKCldWyRwYWNrYWdlLT5nZXRWZXJzaW9uKCldKSkgewogICAgICAgICAgICAgICAgICAgICRhbGlhcyA9ICR0aGlzLT5yb290QWxpYXNlc1skcGFja2FnZS0+Z2V0TmFtZSgpXVskcGFja2FnZS0+Z2V0VmVyc2lvbigpXTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGFsaWFzUGFja2FnZSA9IG5ldyBDb21wbGV0ZUFsaWFzUGFja2FnZSgkcGFja2FnZSwgJGFsaWFzWydhbGlhc19ub3JtYWxpemVkJ10sICRhbGlhc1snYWxpYXMnXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGFsaWFzUGFja2FnZSA9IG5ldyBBbGlhc1BhY2thZ2UoJHBhY2thZ2UsICRhbGlhc1snYWxpYXNfbm9ybWFsaXplZCddLCAkYWxpYXNbJ2FsaWFzJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkYWxpYXNQYWNrYWdlLT5zZXRSb290UGFja2FnZUFsaWFzKHRydWUpOwogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJGFsaWFzUGFja2FnZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBQb29sKCRwYWNrYWdlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlTmFtZQogICAgICoKICAgICAqIEByZXR1cm4gUG9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUG9vbEZvclBhY2thZ2UoJHBhY2thZ2VOYW1lLCBMb2NrQXJyYXlSZXBvc2l0b3J5ICRsb2NrZWRSZXBvID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBUT0RPIHVuaWZ5IHRoaXMgd2l0aCBhYm92ZSBpbiBzb21lIHNpbXBsZXIgdmVyc2lvbiB3aXRob3V0ICJyZXF1ZXN0Ij8KICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWF0ZVBvb2xGb3JQYWNrYWdlcyhhcnJheSgkcGFja2FnZU5hbWUpLCAkbG9ja2VkUmVwbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHBhY2thZ2VOYW1lcwogICAgICoKICAgICAqIEByZXR1cm4gUG9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUG9vbEZvclBhY2thZ2VzKCRwYWNrYWdlTmFtZXMsIExvY2tBcnJheVJlcG9zaXRvcnkgJGxvY2tlZFJlcG8gPSBudWxsKQogICAgewogICAgICAgICRyZXF1ZXN0ID0gbmV3IFJlcXVlc3QoJGxvY2tlZFJlcG8pOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU5hbWVzIGFzICRwYWNrYWdlTmFtZSkgewogICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcGFja2FnZU5hbWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdjcmVhdGVQb29sRm9yUGFja2FnZShzKSBjYW4gbm90IGJlIHVzZWQgZm9yIHBsYXRmb3JtIHBhY2thZ2VzLCBhcyB0aGV5IGFyZSBuZXZlciBsb2FkZWQgYnkgdGhlIFBvb2xCdWlsZGVyIHdoaWNoIGV4cGVjdHMgdGhlbSB0byBiZSBmaXhlZC4gVXNlIGNyZWF0ZVBvb2xXaXRoQWxsUGFja2FnZXMgb3IgcGFzcyBpbiBhIHByb3BlciByZXF1ZXN0IHdpdGggdGhlIHBsYXRmb3JtIHBhY2thZ2VzIHlvdSBuZWVkIGZpeGVkIGluIGl0LicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVxdWVzdC0+cmVxdWlyZU5hbWUoJHBhY2thZ2VOYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Y3JlYXRlUG9vbCgkcmVxdWVzdCwgbmV3IE51bGxJTygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheVtdICRhbGlhc2VzCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBsaXN0PGFycmF5e3BhY2thZ2U6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9PiAkYWxpYXNlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGFycmF5e2FsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+PgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRSb290QWxpYXNlc1BlclBhY2thZ2UoYXJyYXkgJGFsaWFzZXMpCiAgICB7CiAgICAgICAgJG5vcm1hbGl6ZWRBbGlhc2VzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJGFsaWFzZXMgYXMgJGFsaWFzKSB7CiAgICAgICAgICAgICRub3JtYWxpemVkQWxpYXNlc1skYWxpYXNbJ3BhY2thZ2UnXV1bJGFsaWFzWyd2ZXJzaW9uJ11dID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnYWxpYXMnID0+ICRhbGlhc1snYWxpYXMnXSwKICAgICAgICAgICAgICAgICdhbGlhc19ub3JtYWxpemVkJyA9PiAkYWxpYXNbJ2FsaWFzX25vcm1hbGl6ZWQnXSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbm9ybWFsaXplZEFsaWFzZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxVcGRhdGVPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVuaW5zdGFsbE9wZXJhdGlvbjsKCi8qKgogKiBNZXRhcGFja2FnZSBpbnN0YWxsYXRpb24gbWFuYWdlci4KICoKICogQGF1dGhvciBNYXJ0aW4gSGFzb8WIIDxtYXJ0aW4uaGFzb25AZ21haWwuY29tPgogKi8KY2xhc3MgTWV0YXBhY2thZ2VJbnN0YWxsZXIgaW1wbGVtZW50cyBJbnN0YWxsZXJJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1cHBvcnRzKCRwYWNrYWdlVHlwZSkKICAgIHsKICAgICAgICByZXR1cm4gJHBhY2thZ2VUeXBlID09PSAnbWV0YXBhY2thZ2UnOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW5zdGFsbGVkKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuICRyZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gbm9vcAogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIC8vIG5vb3AKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBub29wCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIEluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkpOwoKICAgICAgICAkcmVwby0+YWRkUGFja2FnZShjbG9uZSAkcGFja2FnZSk7CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCkKICAgIHsKICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCRpbml0aWFsKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSBpcyBub3QgaW5zdGFsbGVkOiAnLiRpbml0aWFsKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBVcGRhdGVPcGVyYXRpb246OmZvcm1hdCgkaW5pdGlhbCwgJHRhcmdldCkpOwoKICAgICAgICAkcmVwby0+cmVtb3ZlUGFja2FnZSgkaW5pdGlhbCk7CiAgICAgICAgJHJlcG8tPmFkZFBhY2thZ2UoY2xvbmUgJHRhcmdldCk7CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BhY2thZ2UgaXMgbm90IGluc3RhbGxlZDogJy4kcGFja2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVW5pbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpKTsKCiAgICAgICAgJHJlcG8tPnJlbW92ZVBhY2thZ2UoJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxQYXRoKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuICcnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXERvd25sb2FkTWFuYWdlcjsKCi8qKgogKiBQYWNrYWdlIGluc3RhbGxhdGlvbiBtYW5hZ2VyLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBMaWJyYXJ5SW5zdGFsbGVyIGltcGxlbWVudHMgSW5zdGFsbGVySW50ZXJmYWNlLCBCaW5hcnlQcmVzZW5jZUludGVyZmFjZQp7CiAgICAvKiogQHZhciBDb21wb3NlciAqLwogICAgcHJvdGVjdGVkICRjb21wb3NlcjsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICR2ZW5kb3JEaXI7CiAgICAvKiogQHZhciBEb3dubG9hZE1hbmFnZXIgKi8KICAgIHByb3RlY3RlZCAkZG93bmxvYWRNYW5hZ2VyOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdHlwZTsKICAgIC8qKiBAdmFyIEZpbGVzeXN0ZW0gKi8KICAgIHByb3RlY3RlZCAkZmlsZXN5c3RlbTsKICAgIC8qKiBAdmFyIEJpbmFyeUluc3RhbGxlciAqLwogICAgcHJvdGVjdGVkICRiaW5hcnlJbnN0YWxsZXI7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBsaWJyYXJ5IGluc3RhbGxlci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbwogICAgICogQHBhcmFtIENvbXBvc2VyICAgICAgICAkY29tcG9zZXIKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAgJHR5cGUKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtICAgICAgJGZpbGVzeXN0ZW0KICAgICAqIEBwYXJhbSBCaW5hcnlJbnN0YWxsZXIgJGJpbmFyeUluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb21wb3NlciAkY29tcG9zZXIsICR0eXBlID0gJ2xpYnJhcnknLCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtID0gbnVsbCwgQmluYXJ5SW5zdGFsbGVyICRiaW5hcnlJbnN0YWxsZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyID0gJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKTsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPnR5cGUgPSAkdHlwZTsKCiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZmlsZXN5c3RlbSA/OiBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICR0aGlzLT52ZW5kb3JEaXIgPSBydHJpbSgkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3ZlbmRvci1kaXInKSwgJy8nKTsKICAgICAgICAkdGhpcy0+YmluYXJ5SW5zdGFsbGVyID0gJGJpbmFyeUluc3RhbGxlciA/OiBuZXcgQmluYXJ5SW5zdGFsbGVyKCR0aGlzLT5pbywgcnRyaW0oJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdiaW4tZGlyJyksICcvJyksICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnYmluLWNvbXBhdCcpLCAkdGhpcy0+ZmlsZXN5c3RlbSwgJHRoaXMtPnZlbmRvckRpcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJHBhY2thZ2VUeXBlKQogICAgewogICAgICAgIHJldHVybiAkcGFja2FnZVR5cGUgPT09ICR0aGlzLT50eXBlIHx8IG51bGwgPT09ICR0aGlzLT50eXBlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW5zdGFsbGVkKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGluc3RhbGxQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzUmVhZGFibGUoJGluc3RhbGxQYXRoKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoUGxhdGZvcm06OmlzV2luZG93cygpICYmICR0aGlzLT5maWxlc3lzdGVtLT5pc0p1bmN0aW9uKCRpbnN0YWxsUGF0aCkpIHx8IGlzX2xpbmsoJGluc3RhbGxQYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVWZW5kb3JEaXIoKTsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmRvd25sb2FkKCRwYWNrYWdlLCAkZG93bmxvYWRQYXRoLCAkcHJldlBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBhcmUoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZVZlbmRvckRpcigpOwogICAgICAgICRkb3dubG9hZFBhdGggPSAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+cHJlcGFyZSgkdHlwZSwgJHBhY2thZ2UsICRkb3dubG9hZFBhdGgsICRwcmV2UGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplVmVuZG9yRGlyKCk7CiAgICAgICAgJGRvd25sb2FkUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5jbGVhbnVwKCR0eXBlLCAkcGFja2FnZSwgJGRvd25sb2FkUGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVWZW5kb3JEaXIoKTsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgLy8gcmVtb3ZlIHRoZSBiaW5hcmllcyBpZiBpdCBhcHBlYXJzIHRoZSBwYWNrYWdlIGZpbGVzIGFyZSBtaXNzaW5nCiAgICAgICAgaWYgKCFGaWxlc3lzdGVtOjppc1JlYWRhYmxlKCRkb3dubG9hZFBhdGgpICYmICRyZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAkdGhpcy0+YmluYXJ5SW5zdGFsbGVyLT5yZW1vdmVCaW5hcmllcygkcGFja2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5pbnN0YWxsQ29kZSgkcGFja2FnZSk7CiAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAkYmluYXJ5SW5zdGFsbGVyID0gJHRoaXMtPmJpbmFyeUluc3RhbGxlcjsKICAgICAgICAkaW5zdGFsbFBhdGggPSAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkYmluYXJ5SW5zdGFsbGVyLCAkaW5zdGFsbFBhdGgsICRwYWNrYWdlLCAkcmVwbykgewogICAgICAgICAgICAkYmluYXJ5SW5zdGFsbGVyLT5pbnN0YWxsQmluYXJpZXMoJHBhY2thZ2UsICRpbnN0YWxsUGF0aCk7CiAgICAgICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAkcmVwby0+YWRkUGFja2FnZShjbG9uZSAkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJGluaXRpYWwpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQ6ICcuJGluaXRpYWwpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVWZW5kb3JEaXIoKTsKCiAgICAgICAgJHRoaXMtPmJpbmFyeUluc3RhbGxlci0+cmVtb3ZlQmluYXJpZXMoJGluaXRpYWwpOwogICAgICAgICRwcm9taXNlID0gJHRoaXMtPnVwZGF0ZUNvZGUoJGluaXRpYWwsICR0YXJnZXQpOwogICAgICAgIGlmICghJHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRwcm9taXNlID0gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgICAgIH0KCiAgICAgICAgJGJpbmFyeUluc3RhbGxlciA9ICR0aGlzLT5iaW5hcnlJbnN0YWxsZXI7CiAgICAgICAgJGluc3RhbGxQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCR0YXJnZXQpOwoKICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkYmluYXJ5SW5zdGFsbGVyLCAkaW5zdGFsbFBhdGgsICR0YXJnZXQsICRpbml0aWFsLCAkcmVwbykgewogICAgICAgICAgICAkYmluYXJ5SW5zdGFsbGVyLT5pbnN0YWxsQmluYXJpZXMoJHRhcmdldCwgJGluc3RhbGxQYXRoKTsKICAgICAgICAgICAgJHJlcG8tPnJlbW92ZVBhY2thZ2UoJGluaXRpYWwpOwogICAgICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCR0YXJnZXQpKSB7CiAgICAgICAgICAgICAgICAkcmVwby0+YWRkUGFja2FnZShjbG9uZSAkdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQ6ICcuJHBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+cmVtb3ZlQ29kZSgkcGFja2FnZSk7CiAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAkYmluYXJ5SW5zdGFsbGVyID0gJHRoaXMtPmJpbmFyeUluc3RhbGxlcjsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldFBhY2thZ2VCYXNlUGF0aCgkcGFja2FnZSk7CiAgICAgICAgJGZpbGVzeXN0ZW0gPSAkdGhpcy0+ZmlsZXN5c3RlbTsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJGJpbmFyeUluc3RhbGxlciwgJGZpbGVzeXN0ZW0sICRkb3dubG9hZFBhdGgsICRwYWNrYWdlLCAkcmVwbykgewogICAgICAgICAgICAkYmluYXJ5SW5zdGFsbGVyLT5yZW1vdmVCaW5hcmllcygkcGFja2FnZSk7CiAgICAgICAgICAgICRyZXBvLT5yZW1vdmVQYWNrYWdlKCRwYWNrYWdlKTsKCiAgICAgICAgICAgIGlmIChzdHJwb3MoJHBhY2thZ2UtPmdldE5hbWUoKSwgJy8nKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VWZW5kb3JEaXIgPSBkaXJuYW1lKCRkb3dubG9hZFBhdGgpOwogICAgICAgICAgICAgICAgaWYgKGlzX2RpcigkcGFja2FnZVZlbmRvckRpcikgJiYgJGZpbGVzeXN0ZW0tPmlzRGlyRW1wdHkoJHBhY2thZ2VWZW5kb3JEaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ3JtZGlyJywgJHBhY2thZ2VWZW5kb3JEaXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbFBhdGgoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZVZlbmRvckRpcigpOwoKICAgICAgICAkYmFzZVBhdGggPSAoJHRoaXMtPnZlbmRvckRpciA/ICR0aGlzLT52ZW5kb3JEaXIuJy8nIDogJycpIC4gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKICAgICAgICAkdGFyZ2V0RGlyID0gJHBhY2thZ2UtPmdldFRhcmdldERpcigpOwoKICAgICAgICByZXR1cm4gJGJhc2VQYXRoIC4gKCR0YXJnZXREaXIgPyAnLycuJHRhcmdldERpciA6ICcnKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1ha2Ugc3VyZSBiaW5hcmllcyBhcmUgaW5zdGFsbGVkIGZvciBhIGdpdmVuIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgUGFja2FnZSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5zdXJlQmluYXJpZXNQcmVzZW5jZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5iaW5hcnlJbnN0YWxsZXItPmluc3RhbGxCaW5hcmllcygkcGFja2FnZSwgJHRoaXMtPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKSwgZmFsc2UpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYmFzZSBwYXRoIG9mIHRoZSBwYWNrYWdlIHdpdGhvdXQgdGFyZ2V0LWRpciBwYXRoCiAgICAgKgogICAgICogSXQgaXMgdXNlZCBmb3IgQkMgYXMgZ2V0SW5zdGFsbFBhdGggdGVuZHMgdG8gYmUgb3ZlcnJpZGRlbiBieQogICAgICogaW5zdGFsbGVyIHBsdWdpbnMgYnV0IG5vdCBnZXRQYWNrYWdlQmFzZVBhdGgKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQYWNrYWdlQmFzZVBhdGgoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkaW5zdGFsbFBhdGggPSAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwogICAgICAgICR0YXJnZXREaXIgPSAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCk7CgogICAgICAgIGlmICgkdGFyZ2V0RGlyKSB7CiAgICAgICAgICAgIHJldHVybiBQcmVnOjpyZXBsYWNlKCd7LyonLnN0cl9yZXBsYWNlKCcvJywgJy8rJywgcHJlZ19xdW90ZSgkdGFyZ2V0RGlyKSkuJy8/JH0nLCAnJywgJGluc3RhbGxQYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaW5zdGFsbFBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbENvZGUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmluc3RhbGwoJHBhY2thZ2UsICRkb3dubG9hZFBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZUNvZGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgICRpbml0aWFsRG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRpbml0aWFsKTsKICAgICAgICAkdGFyZ2V0RG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCR0YXJnZXQpOwogICAgICAgIGlmICgkdGFyZ2V0RG93bmxvYWRQYXRoICE9PSAkaW5pdGlhbERvd25sb2FkUGF0aCkgewogICAgICAgICAgICAvLyBpZiB0aGUgdGFyZ2V0IGFuZCBpbml0aWFsIGRpcnMgaW50ZXJzZWN0LCB3ZSBmb3JjZSBhIHJlbW92ZSArIGluc3RhbGwKICAgICAgICAgICAgLy8gdG8gYXZvaWQgdGhlIHJlbmFtZSB3aXBpbmcgdGhlIHRhcmdldCBkaXIgYXMgcGFydCBvZiB0aGUgaW5pdGlhbCBkaXIgY2xlYW51cAogICAgICAgICAgICBpZiAoc3RycG9zKCRpbml0aWFsRG93bmxvYWRQYXRoLCAkdGFyZ2V0RG93bmxvYWRQYXRoKSA9PT0gMAogICAgICAgICAgICAgICAgfHwgc3RycG9zKCR0YXJnZXREb3dubG9hZFBhdGgsICRpbml0aWFsRG93bmxvYWRQYXRoKSA9PT0gMAogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRwcm9taXNlID0gJHRoaXMtPnJlbW92ZUNvZGUoJGluaXRpYWwpOwogICAgICAgICAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkc2VsZiA9ICR0aGlzOwoKICAgICAgICAgICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCRzZWxmLCAkdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgJHJlZmxNZXRob2QgPSBuZXcgXFJlZmxlY3Rpb25NZXRob2QoJHNlbGYsICdpbnN0YWxsQ29kZScpOwogICAgICAgICAgICAgICAgICAgICRyZWZsTWV0aG9kLT5zZXRBY2Nlc3NpYmxlKHRydWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBlcXVpdmFsZW50IG9mICR0aGlzLT5pbnN0YWxsQ29kZSgkdGFyZ2V0KSB3aXRoIHBocCA1LjMgc3VwcG9ydAogICAgICAgICAgICAgICAgICAgIC8vIFRPRE8gcmVtb3ZlIHRoaXMgb25jZSA1LjMgc3VwcG9ydCBpcyBkcm9wcGVkCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRyZWZsTWV0aG9kLT5pbnZva2UoJHNlbGYsICR0YXJnZXQpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW5hbWUoJGluaXRpYWxEb3dubG9hZFBhdGgsICR0YXJnZXREb3dubG9hZFBhdGgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPnVwZGF0ZSgkaW5pdGlhbCwgJHRhcmdldCwgJHRhcmdldERvd25sb2FkUGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcmVtb3ZlQ29kZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRkb3dubG9hZFBhdGggPSAkdGhpcy0+Z2V0UGFja2FnZUJhc2VQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPnJlbW92ZSgkcGFja2FnZSwgJGRvd25sb2FkUGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemVWZW5kb3JEaXIoKQogICAgewogICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoJHRoaXMtPnZlbmRvckRpcik7CiAgICAgICAgJHRoaXMtPnZlbmRvckRpciA9IHJlYWxwYXRoKCR0aGlzLT52ZW5kb3JEaXIpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBJbnN0YWxsZXIgZm9yIHBsdWdpbiBwYWNrYWdlcwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQbHVnaW5JbnN0YWxsZXIgZXh0ZW5kcyBMaWJyYXJ5SW5zdGFsbGVyCnsKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgUGx1Z2luIGluc3RhbGxlci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGNvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbXBvc2VyICRjb21wb3NlciwgRmlsZXN5c3RlbSAkZnMgPSBudWxsLCBCaW5hcnlJbnN0YWxsZXIgJGJpbmFyeUluc3RhbGxlciA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW8sICRjb21wb3NlciwgJ2NvbXBvc2VyLXBsdWdpbicsICRmcywgJGJpbmFyeUluc3RhbGxlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJHBhY2thZ2VUeXBlKQogICAgewogICAgICAgIHJldHVybiAkcGFja2FnZVR5cGUgPT09ICdjb21wb3Nlci1wbHVnaW4nIHx8ICRwYWNrYWdlVHlwZSA9PT0gJ2NvbXBvc2VyLWluc3RhbGxlcic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICRleHRyYSA9ICRwYWNrYWdlLT5nZXRFeHRyYSgpOwogICAgICAgIGlmIChlbXB0eSgkZXh0cmFbJ2NsYXNzJ10pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdFcnJvciB3aGlsZSBpbnN0YWxsaW5nICcuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nLCBjb21wb3Nlci1wbHVnaW4gcGFja2FnZXMgc2hvdWxkIGhhdmUgYSBjbGFzcyBkZWZpbmVkIGluIHRoZWlyIGV4dHJhIGtleSB0byBiZSB1c2FibGUuJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcGFyZW50Ojpkb3dubG9hZCgkcGFja2FnZSwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHByb21pc2UgPSBwYXJlbnQ6Omluc3RhbGwoJHJlcG8sICRwYWNrYWdlKTsKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgICRwbHVnaW5NYW5hZ2VyID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRQbHVnaW5NYW5hZ2VyKCk7CiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHNlbGYsICRwbHVnaW5NYW5hZ2VyLCAkcGFja2FnZSwgJHJlcG8pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIFBsYXRmb3JtOjp3b3JrYXJvdW5kRmlsZXN5c3RlbUlzc3VlcygpOwogICAgICAgICAgICAgICAgJHBsdWdpbk1hbmFnZXItPnJlZ2lzdGVyUGFja2FnZSgkcGFja2FnZSwgdHJ1ZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRzZWxmLT5yb2xsYmFja0luc3RhbGwoJGUsICRyZXBvLCAkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgICRwcm9taXNlID0gcGFyZW50Ojp1cGRhdGUoJHJlcG8sICRpbml0aWFsLCAkdGFyZ2V0KTsKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgICRwbHVnaW5NYW5hZ2VyID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRQbHVnaW5NYW5hZ2VyKCk7CiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHNlbGYsICRwbHVnaW5NYW5hZ2VyLCAkaW5pdGlhbCwgJHRhcmdldCwgJHJlcG8pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIFBsYXRmb3JtOjp3b3JrYXJvdW5kRmlsZXN5c3RlbUlzc3VlcygpOwogICAgICAgICAgICAgICAgJHBsdWdpbk1hbmFnZXItPmRlYWN0aXZhdGVQYWNrYWdlKCRpbml0aWFsKTsKICAgICAgICAgICAgICAgICRwbHVnaW5NYW5hZ2VyLT5yZWdpc3RlclBhY2thZ2UoJHRhcmdldCwgdHJ1ZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRzZWxmLT5yb2xsYmFja0luc3RhbGwoJGUsICRyZXBvLCAkdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldFBsdWdpbk1hbmFnZXIoKS0+dW5pbnN0YWxsUGFja2FnZSgkcGFja2FnZSk7CgogICAgICAgIHJldHVybiBwYXJlbnQ6OnVuaW5zdGFsbCgkcmVwbywgJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogVE9ETyB2MyBzaG91bGQgbWFrZSB0aGlzIHByaXZhdGUgb25jZSB3ZSBjYW4gZHJvcCBQSFAgNS4zIHN1cHBvcnQKICAgICAqIEBwcml2YXRlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByb2xsYmFja0luc3RhbGwoXEV4Y2VwdGlvbiAkZSwgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1BsdWdpbiBpbml0aWFsaXphdGlvbiBmYWlsZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKSwgdW5pbnN0YWxsaW5nIHBsdWdpbicpOwogICAgICAgIHBhcmVudDo6dW5pbnN0YWxsKCRyZXBvLCAkcGFja2FnZSk7CiAgICAgICAgdGhyb3cgJGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBEb2VzIG5vdCBpbnN0YWxsIGFueXRoaW5nIGJ1dCBtYXJrcyBwYWNrYWdlcyBpbnN0YWxsZWQgaW4gdGhlIHJlcG8KICoKICogVXNlZnVsIGZvciBkcnkgcnVucwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBOb29wSW5zdGFsbGVyIGltcGxlbWVudHMgSW5zdGFsbGVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1cHBvcnRzKCRwYWNrYWdlVHlwZSkKICAgIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0luc3RhbGxlZChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICRyZXBvLT5hZGRQYWNrYWdlKGNsb25lICRwYWNrYWdlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCkKICAgIHsKICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCRpbml0aWFsKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSBpcyBub3QgaW5zdGFsbGVkOiAnLiRpbml0aWFsKTsKICAgICAgICB9CgogICAgICAgICRyZXBvLT5yZW1vdmVQYWNrYWdlKCRpbml0aWFsKTsKICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCR0YXJnZXQpKSB7CiAgICAgICAgICAgICRyZXBvLT5hZGRQYWNrYWdlKGNsb25lICR0YXJnZXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSBpcyBub3QgaW5zdGFsbGVkOiAnLiRwYWNrYWdlKTsKICAgICAgICB9CiAgICAgICAgJHJlcG8tPnJlbW92ZVBhY2thZ2UoJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxQYXRoKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRhcmdldERpciA9ICRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKTsKCiAgICAgICAgcmV0dXJuICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkgLiAoJHRhcmdldERpciA/ICcvJy4kdGFyZ2V0RGlyIDogJycpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogSW50ZXJmYWNlIGZvciB0aGUgcGFja2FnZSBpbnN0YWxsYXRpb24gbWFuYWdlci4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KaW50ZXJmYWNlIEluc3RhbGxlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIERlY2lkZXMgaWYgdGhlIGluc3RhbGxlciBzdXBwb3J0cyB0aGUgZ2l2ZW4gdHlwZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYWNrYWdlVHlwZQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdXBwb3J0cygkcGFja2FnZVR5cGUpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIHRoYXQgcHJvdmlkZWQgcGFja2FnZSBpcyBpbnN0YWxsZWQuCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gICAgcmVwb3NpdG9yeSBpbiB3aGljaCB0byBjaGVjawogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgICAgICAgICAgICAgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7CgogICAgLyoqCiAgICAgKiBEb3dubG9hZHMgdGhlIGZpbGVzIG5lZWRlZCB0byBsYXRlciBpbnN0YWxsIHRoZSBnaXZlbiBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcHJldlBhY2thZ2UgcHJldmlvdXMgcGFja2FnZSBpbnN0YW5jZSBpbiBjYXNlIG9mIGFuIHVwZGF0ZQogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBEbyBhbnl0aGluZyB0aGF0IG5lZWRzIHRvIGJlIGRvbmUgYmV0d2VlbiBhbGwgZG93bmxvYWRzIGhhdmUgYmVlbiBjb21wbGV0ZWQgYW5kIHRoZSBhY3R1YWwgb3BlcmF0aW9uIGlzIGV4ZWN1dGVkCiAgICAgKgogICAgICogQWxsIHBhY2thZ2VzIGdldCBmaXJzdCBkb3dubG9hZGVkLCB0aGVuIGFsbCB0b2dldGhlciBwcmVwYXJlZCwgdGhlbiBhbGwgdG9nZXRoZXIgaW5zdGFsbGVkL3VwZGF0ZWQvdW5pbnN0YWxsZWQuIFRoZXJlZm9yZQogICAgICogZm9yIGVycm9yIHJlY292ZXJ5IGl0IGlzIGltcG9ydGFudCB0byBhdm9pZCBmYWlsaW5nIGR1cmluZyBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwgYXMgbXVjaCBhcyBwb3NzaWJsZSwgYW5kIHJpc2t5IHRoaW5ncyBvcgogICAgICogdXNlciBwcm9tcHRzIHNob3VsZCBoYXBwZW4gaW4gdGhlIHByZXBhcmUgc3RlcCByYXRoZXIuIEluIGNhc2Ugb2YgZmFpbHVyZSwgY2xlYW51cCgpIHdpbGwgYmUgY2FsbGVkIHNvIHRoYXQgY2hhbmdlcyBjYW4KICAgICAqIGJlIHVuZG9uZSBhcyBtdWNoIGFzIHBvc3NpYmxlLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICR0eXBlICAgICAgICBvbmUgb2YgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHByZXZQYWNrYWdlIHByZXZpb3VzIHBhY2thZ2UgaW5zdGFuY2UgaW4gY2FzZSBvZiBhbiB1cGRhdGUKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcmVwYXJlKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpOwoKICAgIC8qKgogICAgICogSW5zdGFsbHMgc3BlY2lmaWMgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gICAgcmVwb3NpdG9yeSBpbiB3aGljaCB0byBjaGVjawogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgICAgICAgICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpOwoKICAgIC8qKgogICAgICogVXBkYXRlcyBzcGVjaWZpYyBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAgICAgICAgJGluaXRpYWwgYWxyZWFkeSBpbnN0YWxsZWQgcGFja2FnZSB2ZXJzaW9uCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAgICAgICAgJHRhcmdldCAgdXBkYXRlZCB2ZXJzaW9uCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiAgICAgaWYgJGluaXRpYWwgcGFja2FnZSBpcyBub3QgaW5zdGFsbGVkCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCk7CgogICAgLyoqCiAgICAgKiBVbmluc3RhbGxzIHNwZWNpZmljIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICAgICAgICAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpOwoKICAgIC8qKgogICAgICogRG8gYW55dGhpbmcgdG8gY2xlYW51cCBjaGFuZ2VzIGFwcGxpZWQgaW4gdGhlIHByZXBhcmUgb3IgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsIHN0ZXBzCiAgICAgKgogICAgICogTm90ZSB0aGF0IGNsZWFudXAgd2lsbCBiZSBjYWxsZWQgZm9yIGFsbCBwYWNrYWdlcyByZWdhcmRsZXNzIGlmIHRoZXkgZmFpbGVkIGFuIG9wZXJhdGlvbiBvciBub3QsIHRvIGdpdmUKICAgICAqIGFsbCBpbnN0YWxsZXJzIGEgY2hhbmdlIHRvIGNsZWFudXAgdGhpbmdzIHRoZXkgZGlkIHByZXZpb3VzbHksIHNvIHlvdSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgY2hhbmdlcwogICAgICogYXBwbGllZCBpbiB0aGUgaW5zdGFsbGVyL2Rvd25sb2FkZXIgdGhlbXNlbHZlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAkdHlwZSAgICAgICAgb25lIG9mIGluc3RhbGwvdXBkYXRlL3VuaW5zdGFsbAogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgICAgIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwcmV2UGFja2FnZSBwcmV2aW91cyBwYWNrYWdlIGluc3RhbmNlIGluIGNhc2Ugb2YgYW4gdXBkYXRlCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGluc3RhbGxhdGlvbiBwYXRoIG9mIGEgcGFja2FnZQogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICogQHJldHVybiBzdHJpbmcgICAgICAgICAgIHBhdGggdG8gaW5zdGFsbCB0bywgd2hpY2ggTVVTVCBub3QgZW5kIHdpdGggYSBzbGFzaAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbFBhdGgoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFRyYW5zYWN0aW9uOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgpjbGFzcyBJbnN0YWxsZXJFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBDb21wb3NlcgogICAgICovCiAgICBwcml2YXRlICRjb21wb3NlcjsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkZGV2TW9kZTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcml2YXRlICRleGVjdXRlT3BlcmF0aW9uczsKCiAgICAvKioKICAgICAqIEB2YXIgVHJhbnNhY3Rpb24KICAgICAqLwogICAgcHJpdmF0ZSAkdHJhbnNhY3Rpb247CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGV2ZW50TmFtZQogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRkZXZNb2RlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGV4ZWN1dGVPcGVyYXRpb25zCiAgICAgKiBAcGFyYW0gVHJhbnNhY3Rpb24gJHRyYW5zYWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZXZlbnROYW1lLCBDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbywgJGRldk1vZGUsICRleGVjdXRlT3BlcmF0aW9ucywgVHJhbnNhY3Rpb24gJHRyYW5zYWN0aW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGV2ZW50TmFtZSk7CgogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmRldk1vZGUgPSAkZGV2TW9kZTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZU9wZXJhdGlvbnMgPSAkZXhlY3V0ZU9wZXJhdGlvbnM7CiAgICAgICAgJHRoaXMtPnRyYW5zYWN0aW9uID0gJHRyYW5zYWN0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb21wb3NlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJTygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZXZNb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRldk1vZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRXhlY3V0aW5nT3BlcmF0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leGVjdXRlT3BlcmF0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVHJhbnNhY3Rpb258bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHJhbnNhY3Rpb247CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKCi8qKgogKiBVdGlsaXR5IHRvIGhhbmRsZSBpbnN0YWxsYXRpb24gb2YgcGFja2FnZSAiYmluIi9iaW5hcmllcwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgSGVsbXV0IEh1bW1lbCA8aW5mb0BoZWxodW0uaW8+CiAqLwpjbGFzcyBCaW5hcnlJbnN0YWxsZXIKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJGJpbkRpcjsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRiaW5Db21wYXQ7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIEZpbGVzeXN0ZW0gKi8KICAgIHByb3RlY3RlZCAkZmlsZXN5c3RlbTsKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcml2YXRlICR2ZW5kb3JEaXI7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGJpbkRpcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRiaW5Db21wYXQKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtICAkZmlsZXN5c3RlbQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICR2ZW5kb3JEaXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgJGJpbkRpciwgJGJpbkNvbXBhdCwgRmlsZXN5c3RlbSAkZmlsZXN5c3RlbSA9IG51bGwsICR2ZW5kb3JEaXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5iaW5EaXIgPSAkYmluRGlyOwogICAgICAgICR0aGlzLT5iaW5Db21wYXQgPSAkYmluQ29tcGF0OwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmaWxlc3lzdGVtID86IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgJHRoaXMtPnZlbmRvckRpciA9ICR2ZW5kb3JEaXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnN0YWxsUGF0aAogICAgICogQHBhcmFtIGJvb2wgJHdhcm5Pbk92ZXJ3cml0ZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbEJpbmFyaWVzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRpbnN0YWxsUGF0aCwgJHdhcm5Pbk92ZXJ3cml0ZSA9IHRydWUpCiAgICB7CiAgICAgICAgJGJpbmFyaWVzID0gJHRoaXMtPmdldEJpbmFyaWVzKCRwYWNrYWdlKTsKICAgICAgICBpZiAoISRiaW5hcmllcykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBQbGF0Zm9ybTo6d29ya2Fyb3VuZEZpbGVzeXN0ZW1Jc3N1ZXMoKTsKCiAgICAgICAgZm9yZWFjaCAoJGJpbmFyaWVzIGFzICRiaW4pIHsKICAgICAgICAgICAgJGJpblBhdGggPSAkaW5zdGFsbFBhdGguJy8nLiRiaW47CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJGJpblBhdGgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICA8d2FybmluZz5Ta2lwcGVkIGluc3RhbGxhdGlvbiBvZiBiaW4gJy4kYmluLicgZm9yIHBhY2thZ2UgJy4kcGFja2FnZS0+Z2V0TmFtZSgpLic6IGZpbGUgbm90IGZvdW5kIGluIHBhY2thZ2U8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNfZGlyKCRiaW5QYXRoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgPHdhcm5pbmc+U2tpcHBlZCBpbnN0YWxsYXRpb24gb2YgYmluICcuJGJpbi4nIGZvciBwYWNrYWdlICcuJHBhY2thZ2UtPmdldE5hbWUoKS4nOiBmb3VuZCBhIGRpcmVjdG9yeSBhdCB0aGF0IHBhdGg8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISR0aGlzLT5maWxlc3lzdGVtLT5pc0Fic29sdXRlUGF0aCgkYmluUGF0aCkpIHsKICAgICAgICAgICAgICAgIC8vIGluIGNhc2UgYSBjdXN0b20gaW5zdGFsbGVyIHJldHVybmVkIGEgcmVsYXRpdmUgcGF0aCBmb3IgdGhlCiAgICAgICAgICAgICAgICAvLyAkcGFja2FnZSwgd2UgY2FuIG5vdyBzYWZlbHkgdHVybiBpdCBpbnRvIGEgYWJzb2x1dGUgcGF0aCAoYXMgd2UKICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgY2hlY2tlZCB0aGUgYmluYXJ5J3MgZXhpc3RlbmNlKS4gVGhlIGZvbGxvd2luZyBoZWxwZXJzCiAgICAgICAgICAgICAgICAvLyB3aWxsIHJlcXVpcmUgYWJzb2x1dGUgcGF0aHMgdG8gd29yayBwcm9wZXJseS4KICAgICAgICAgICAgICAgICRiaW5QYXRoID0gcmVhbHBhdGgoJGJpblBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplQmluRGlyKCk7CiAgICAgICAgICAgICRsaW5rID0gJHRoaXMtPmJpbkRpci4nLycuYmFzZW5hbWUoJGJpbik7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkbGluaykpIHsKICAgICAgICAgICAgICAgIGlmICghaXNfbGluaygkbGluaykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHdhcm5Pbk92ZXJ3cml0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBTa2lwcGVkIGluc3RhbGxhdGlvbiBvZiBiaW4gJy4kYmluLicgZm9yIHBhY2thZ2UgJy4kcGFja2FnZS0+Z2V0TmFtZSgpLic6IG5hbWUgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgZmlsZScpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChyZWFscGF0aCgkbGluaykgPT09IHJlYWxwYXRoKCRiaW5QYXRoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEl0IGlzIGEgbGlua2VkIGJpbmFyeSBmcm9tIGEgcHJldmlvdXMgaW5zdGFsbGF0aW9uLCB3aGljaCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBhIHByb3h5IGZpbGUKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCRsaW5rKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGJpbkNvbXBhdCA9ICR0aGlzLT5iaW5Db21wYXQ7CiAgICAgICAgICAgIGlmICgkYmluQ29tcGF0ID09PSAiYXV0byIgJiYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSB8fCBQbGF0Zm9ybTo6aXNXaW5kb3dzU3Vic3lzdGVtRm9yTGludXgoKSkpIHsKICAgICAgICAgICAgICAgICRiaW5Db21wYXQgPSAnZnVsbCc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkYmluQ29tcGF0ID09PSAiZnVsbCIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbnN0YWxsRnVsbEJpbmFyaWVzKCRiaW5QYXRoLCAkbGluaywgJGJpbiwgJHBhY2thZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmluc3RhbGxVbml4eVByb3h5QmluYXJpZXMoJGJpblBhdGgsICRsaW5rKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnY2htb2QnLCAkYmluUGF0aCwgMDc3NyAmIH51bWFzaygpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUJpbmFyaWVzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVCaW5EaXIoKTsKCiAgICAgICAgJGJpbmFyaWVzID0gJHRoaXMtPmdldEJpbmFyaWVzKCRwYWNrYWdlKTsKICAgICAgICBpZiAoISRiaW5hcmllcykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRiaW5hcmllcyBhcyAkYmluKSB7CiAgICAgICAgICAgICRsaW5rID0gJHRoaXMtPmJpbkRpci4nLycuYmFzZW5hbWUoJGJpbik7CiAgICAgICAgICAgIGlmIChpc19saW5rKCRsaW5rKSB8fCBmaWxlX2V4aXN0cygkbGluaykpIHsgLy8gc3RpbGwgY2hlY2tpbmcgZm9yIHN5bWxpbmtzIGhlcmUgZm9yIGxlZ2FjeSBzdXBwb3J0CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCRsaW5rKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNfZmlsZSgkbGluay4nLmJhdCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCRsaW5rLicuYmF0Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGF0dGVtcHQgcmVtb3ZpbmcgdGhlIGJpbiBkaXIgaW4gY2FzZSBpdCBpcyBsZWZ0IGVtcHR5CiAgICAgICAgaWYgKGlzX2RpcigkdGhpcy0+YmluRGlyKSAmJiAkdGhpcy0+ZmlsZXN5c3RlbS0+aXNEaXJFbXB0eSgkdGhpcy0+YmluRGlyKSkgewogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgncm1kaXInLCAkdGhpcy0+YmluRGlyKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiaW4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGRldGVybWluZUJpbmFyeUNhbGxlcigkYmluKQogICAgewogICAgICAgIGlmICgnLmJhdCcgPT09IHN1YnN0cigkYmluLCAtNCkgfHwgJy5leGUnID09PSBzdWJzdHIoJGJpbiwgLTQpKSB7CiAgICAgICAgICAgIHJldHVybiAnY2FsbCc7CiAgICAgICAgfQoKICAgICAgICAkaGFuZGxlID0gZm9wZW4oJGJpbiwgJ3InKTsKICAgICAgICAkbGluZSA9IGZnZXRzKCRoYW5kbGUpOwogICAgICAgIGZjbG9zZSgkaGFuZGxlKTsKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne14jIS8oPzp1c3IvYmluL2VudiApPyg/OlteL10rLykqKC4rKSR9bScsICRsaW5lLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIHJldHVybiB0cmltKCRtYXRjaFsxXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ3BocCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRCaW5hcmllcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0QmluYXJpZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJpblBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmsKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJpbgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbEZ1bGxCaW5hcmllcygkYmluUGF0aCwgJGxpbmssICRiaW4sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgLy8gYWRkIHVuaXh5IHN1cHBvcnQgZm9yIGN5Z3dpbiBhbmQgc2ltaWxhciBlbnZpcm9ubWVudHMKICAgICAgICBpZiAoJy5iYXQnICE9PSBzdWJzdHIoJGJpblBhdGgsIC00KSkgewogICAgICAgICAgICAkdGhpcy0+aW5zdGFsbFVuaXh5UHJveHlCaW5hcmllcygkYmluUGF0aCwgJGxpbmspOwogICAgICAgICAgICAkbGluayAuPSAnLmJhdCc7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkbGluaykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIFNraXBwZWQgaW5zdGFsbGF0aW9uIG9mIGJpbiAnLiRiaW4uJy5iYXQgcHJveHkgZm9yIHBhY2thZ2UgJy4kcGFja2FnZS0+Z2V0TmFtZSgpLic6IGEgLmJhdCBwcm94eSB3YXMgYWxyZWFkeSBpbnN0YWxsZWQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRsaW5rKSkgewogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkbGluaywgJHRoaXMtPmdlbmVyYXRlV2luZG93c1Byb3h5Q29kZSgkYmluUGF0aCwgJGxpbmspKTsKICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2NobW9kJywgJGxpbmssIDA3NzcgJiB+dW1hc2soKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkYmluUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkbGluawogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbFVuaXh5UHJveHlCaW5hcmllcygkYmluUGF0aCwgJGxpbmspCiAgICB7CiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGxpbmssICR0aGlzLT5nZW5lcmF0ZVVuaXh5UHJveHlDb2RlKCRiaW5QYXRoLCAkbGluaykpOwogICAgICAgIFNpbGVuY2VyOjpjYWxsKCdjaG1vZCcsICRsaW5rLCAwNzc3ICYgfnVtYXNrKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplQmluRGlyKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0aGlzLT5iaW5EaXIpOwogICAgICAgICR0aGlzLT5iaW5EaXIgPSByZWFscGF0aCgkdGhpcy0+YmluRGlyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJpbgogICAgICogQHBhcmFtIHN0cmluZyAkbGluawogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZW5lcmF0ZVdpbmRvd3NQcm94eUNvZGUoJGJpbiwgJGxpbmspCiAgICB7CiAgICAgICAgJGJpblBhdGggPSAkdGhpcy0+ZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aCgkbGluaywgJGJpbik7CiAgICAgICAgJGNhbGxlciA9IHNlbGY6OmRldGVybWluZUJpbmFyeUNhbGxlcigkYmluKTsKCiAgICAgICAgLy8gaWYgdGhlIHRhcmdldCBpcyBhIHBocCBmaWxlLCB3ZSBydW4gdGhlIHVuaXh5IHByb3h5IGZpbGUKICAgICAgICAvLyB0byBlbnN1cmUgdGhhdCBfY29tcG9zZXJfYXV0b2xvYWRfcGF0aCBnZXRzIGRlZmluZWQsIGluc3RlYWQKICAgICAgICAvLyBvZiBydW5uaW5nIHRoZSBiaW5hcnkgZGlyZWN0bHkKICAgICAgICBpZiAoJGNhbGxlciA9PT0gJ3BocCcpIHsKICAgICAgICAgICAgcmV0dXJuICJARUNITyBPRkZcclxuIi4KICAgICAgICAgICAgICAgICJzZXRsb2NhbCBESVNBQkxFREVMQVlFREVYUEFOU0lPTlxyXG4iLgogICAgICAgICAgICAgICAgIlNFVCBCSU5fVEFSR0VUPSV+ZHAwLyIudHJpbShQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShiYXNlbmFtZSgkbGluaywgJy5iYXQnKSksICciXCcnKS4iXHJcbiIuCiAgICAgICAgICAgICAgICAiU0VUIENPTVBPU0VSX0JJTl9ESVI9JX5kcDBcclxuIi4KICAgICAgICAgICAgICAgICJ7JGNhbGxlcn0gXCIlQklOX1RBUkdFVCVcIiAlKlxyXG4iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICJARUNITyBPRkZcclxuIi4KICAgICAgICAgICAgInNldGxvY2FsIERJU0FCTEVERUxBWUVERVhQQU5TSU9OXHJcbiIuCiAgICAgICAgICAgICJTRVQgQklOX1RBUkdFVD0lfmRwMC8iLnRyaW0oUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGJpblBhdGgpLCAnIlwnJykuIlxyXG4iLgogICAgICAgICAgICAiU0VUIENPTVBPU0VSX0JJTl9ESVI9JX5kcDBcclxuIi4KICAgICAgICAgICAgInskY2FsbGVyfSBcIiVCSU5fVEFSR0VUJVwiICUqXHJcbiI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiaW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmsKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2VuZXJhdGVVbml4eVByb3h5Q29kZSgkYmluLCAkbGluaykKICAgIHsKICAgICAgICAkYmluUGF0aCA9ICR0aGlzLT5maWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoKCRsaW5rLCAkYmluKTsKCiAgICAgICAgJGJpbkRpciA9IFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKGRpcm5hbWUoJGJpblBhdGgpKTsKICAgICAgICAkYmluRmlsZSA9IGJhc2VuYW1lKCRiaW5QYXRoKTsKCiAgICAgICAgJGJpbkNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoJGJpbik7CiAgICAgICAgLy8gRm9yIHBocCBmaWxlcywgd2UgZ2VuZXJhdGUgYSBQSFAgcHJveHkgaW5zdGVhZCBvZiBhIHNoZWxsIG9uZSwKICAgICAgICAvLyB3aGljaCBhbGxvd3MgY2FsbGluZyB0aGUgcHJveHkgd2l0aCBhIGN1c3RvbSBwaHAgcHJvY2VzcwogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XigjIS4qXHI/XG4pP1tcclxuXHQgXSo8XD9waHB9JywgJGJpbkNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIC8vIGNhcnJ5IG92ZXIgdGhlIGV4aXN0aW5nIHNoZWJhbmcgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIGFkZCBvdXIgb3duCiAgICAgICAgICAgICRwcm94eUNvZGUgPSBlbXB0eSgkbWF0Y2hbMV0pID8gJyMhL3Vzci9iaW4vZW52IHBocCcgOiB0cmltKCRtYXRjaFsxXSk7CiAgICAgICAgICAgICRiaW5QYXRoRXhwb3J0ZWQgPSAkdGhpcy0+ZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUoJGxpbmssICRiaW4sIGZhbHNlLCB0cnVlKTsKICAgICAgICAgICAgJHN0cmVhbVByb3h5Q29kZSA9ICRzdHJlYW1IaW50ID0gJyc7CiAgICAgICAgICAgICRnbG9iYWxzQ29kZSA9ICckR0xPQkFMU1tcJ19jb21wb3Nlcl9iaW5fZGlyXCddID0gX19ESVJfXzsnLiJcbiI7CiAgICAgICAgICAgICRwaHB1bml0SGFjazEgPSAkcGhwdW5pdEhhY2syID0gJyc7CiAgICAgICAgICAgIC8vIERvbid0IGV4cG9zZSBhdXRvbG9hZCBwYXRoIHdoZW4gdmVuZG9yIGRpciB3YXMgbm90IHNldCBpbiBjdXN0b20gaW5zdGFsbGVycwogICAgICAgICAgICBpZiAoJHRoaXMtPnZlbmRvckRpcikgewogICAgICAgICAgICAgICAgJGdsb2JhbHNDb2RlIC49ICckR0xPQkFMU1tcJ19jb21wb3Nlcl9hdXRvbG9hZF9wYXRoXCddID0gJyAuICR0aGlzLT5maWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZSgkbGluaywgJHRoaXMtPnZlbmRvckRpciAuICcvYXV0b2xvYWQucGhwJywgZmFsc2UsIHRydWUpLiI7XG4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFkZCB3b3JrYXJvdW5kIGZvciBQSFBVbml0IHByb2Nlc3MgaXNvbGF0aW9uCiAgICAgICAgICAgIGlmICgkdGhpcy0+ZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aCgkYmluKSA9PT0gJHRoaXMtPmZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHRoaXMtPnZlbmRvckRpci4nL3BocHVuaXQvcGhwdW5pdC9waHB1bml0JykpIHsKICAgICAgICAgICAgICAgIC8vIHdvcmthcm91bmQgaXNzdWUgb24gUEhQVW5pdCA2LjUrIHJ1bm5pbmcgb24gUEhQIDgrCiAgICAgICAgICAgICAgICAkZ2xvYmFsc0NvZGUgLj0gJyRHTE9CQUxTW1wnX19QSFBVTklUX0lTT0xBVElPTl9FWENMVURFX0xJU1RcJ10gPSAkR0xPQkFMU1tcJ19fUEhQVU5JVF9JU09MQVRJT05fQkxBQ0tMSVNUXCddID0gYXJyYXkocmVhbHBhdGgoJy4kYmluUGF0aEV4cG9ydGVkLicpKTsnLiJcbiI7CiAgICAgICAgICAgICAgICAvLyB3b3JrYXJvdW5kIGlzc3VlIG9uIGFsbCBQSFBVbml0IHZlcnNpb25zIHJ1bm5pbmcgb24gUEhQIDw4CiAgICAgICAgICAgICAgICAkcGhwdW5pdEhhY2sxID0gIidwaHB2ZnNjb21wb3NlcjovLycuIjsKICAgICAgICAgICAgICAgICRwaHB1bml0SGFjazIgPSAnCiAgICAgICAgICAgICAgICAkZGF0YSA9IHN0cl9yZXBsYWNlKFwnX19ESVJfX1wnLCB2YXJfZXhwb3J0KGRpcm5hbWUoJHRoaXMtPnJlYWxwYXRoKSwgdHJ1ZSksICRkYXRhKTsKICAgICAgICAgICAgICAgICRkYXRhID0gc3RyX3JlcGxhY2UoXCdfX0ZJTEVfX1wnLCB2YXJfZXhwb3J0KCR0aGlzLT5yZWFscGF0aCwgdHJ1ZSksICRkYXRhKTsnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0cmltKCRtYXRjaFswXSkgIT09ICc8P3BocCcpIHsKICAgICAgICAgICAgICAgICRzdHJlYW1IaW50ID0gJyB1c2luZyBhIHN0cmVhbSB3cmFwcGVyIHRvIHByZXZlbnQgdGhlIHNoZWJhbmcgZnJvbSBiZWluZyBvdXRwdXQgb24gUEhQPDgnLiJcbiAqIjsKICAgICAgICAgICAgICAgICRzdHJlYW1Qcm94eUNvZGUgPSA8PDxTVFJFQU1QUk9YWQppZiAoUEhQX1ZFUlNJT05fSUQgPCA4MDAwMCkgewogICAgaWYgKCFjbGFzc19leGlzdHMoJ0NvbXBvc2VyXEJpblByb3h5V3JhcHBlcicpKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQGludGVybmFsCiAgICAgICAgICovCiAgICAgICAgZmluYWwgY2xhc3MgQmluUHJveHlXcmFwcGVyCiAgICAgICAgewogICAgICAgICAgICBwcml2YXRlIFwkaGFuZGxlOwogICAgICAgICAgICBwcml2YXRlIFwkcG9zaXRpb247CiAgICAgICAgICAgIHByaXZhdGUgXCRyZWFscGF0aDsKCiAgICAgICAgICAgIHB1YmxpYyBmdW5jdGlvbiBzdHJlYW1fb3BlbihcJHBhdGgsIFwkbW9kZSwgXCRvcHRpb25zLCAmXCRvcGVuZWRfcGF0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZ2V0IHJpZCBvZiBwaHB2ZnNjb21wb3NlcjovLyBwcmVmaXggZm9yIF9fRklMRV9fICYgX19ESVJfXyByZXNvbHV0aW9uCiAgICAgICAgICAgICAgICBcJG9wZW5lZF9wYXRoID0gc3Vic3RyKFwkcGF0aCwgMTcpOwogICAgICAgICAgICAgICAgXCR0aGlzLT5yZWFscGF0aCA9IHJlYWxwYXRoKFwkb3BlbmVkX3BhdGgpID86IFwkb3BlbmVkX3BhdGg7CiAgICAgICAgICAgICAgICBcJG9wZW5lZF9wYXRoID0gJHBocHVuaXRIYWNrMVwkdGhpcy0+cmVhbHBhdGg7CiAgICAgICAgICAgICAgICBcJHRoaXMtPmhhbmRsZSA9IGZvcGVuKFwkdGhpcy0+cmVhbHBhdGgsIFwkbW9kZSk7CiAgICAgICAgICAgICAgICBcJHRoaXMtPnBvc2l0aW9uID0gMDsKCiAgICAgICAgICAgICAgICByZXR1cm4gKGJvb2wpIFwkdGhpcy0+aGFuZGxlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgZnVuY3Rpb24gc3RyZWFtX3JlYWQoXCRjb3VudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgXCRkYXRhID0gZnJlYWQoXCR0aGlzLT5oYW5kbGUsIFwkY291bnQpOwoKICAgICAgICAgICAgICAgIGlmIChcJHRoaXMtPnBvc2l0aW9uID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgXCRkYXRhID0gcHJlZ19yZXBsYWNlKCd7XiMhLipcXHI/XFxufScsICcnLCBcJGRhdGEpOwogICAgICAgICAgICAgICAgfSRwaHB1bml0SGFjazIKCiAgICAgICAgICAgICAgICBcJHRoaXMtPnBvc2l0aW9uICs9IHN0cmxlbihcJGRhdGEpOwoKICAgICAgICAgICAgICAgIHJldHVybiBcJGRhdGE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBmdW5jdGlvbiBzdHJlYW1fY2FzdChcJGNhc3RBcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFwkdGhpcy0+aGFuZGxlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgZnVuY3Rpb24gc3RyZWFtX2Nsb3NlKCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZmNsb3NlKFwkdGhpcy0+aGFuZGxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGZ1bmN0aW9uIHN0cmVhbV9sb2NrKFwkb3BlcmF0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gXCRvcGVyYXRpb24gPyBmbG9jayhcJHRoaXMtPmhhbmRsZSwgXCRvcGVyYXRpb24pIDogdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGZ1bmN0aW9uIHN0cmVhbV9zZWVrKFwkb2Zmc2V0LCBcJHdoZW5jZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKDAgPT09IGZzZWVrKFwkdGhpcy0+aGFuZGxlLCBcJG9mZnNldCwgXCR3aGVuY2UpKSB7CiAgICAgICAgICAgICAgICAgICAgXCR0aGlzLT5wb3NpdGlvbiA9IGZ0ZWxsKFwkdGhpcy0+aGFuZGxlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBmdW5jdGlvbiBzdHJlYW1fdGVsbCgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBcJHRoaXMtPnBvc2l0aW9uOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgZnVuY3Rpb24gc3RyZWFtX2VvZigpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmZW9mKFwkdGhpcy0+aGFuZGxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGZ1bmN0aW9uIHN0cmVhbV9zdGF0KCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBmdW5jdGlvbiBzdHJlYW1fc2V0X29wdGlvbihcJG9wdGlvbiwgXCRhcmcxLCBcJGFyZzIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgZnVuY3Rpb24gdXJsX3N0YXQoXCRwYXRoLCBcJGZsYWdzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBcJHBhdGggPSBzdWJzdHIoXCRwYXRoLCAxNyk7CiAgICAgICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoXCRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGF0KFwkcGF0aCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3N0cmVhbV93cmFwcGVyX3JlZ2lzdGVyJykgJiYgc3RyZWFtX3dyYXBwZXJfcmVnaXN0ZXIoJ3BocHZmc2NvbXBvc2VyJywgJ0NvbXBvc2VyXEJpblByb3h5V3JhcHBlcicpKSB7CiAgICAgICAgaW5jbHVkZSgicGhwdmZzY29tcG9zZXI6Ly8iIC4gJGJpblBhdGhFeHBvcnRlZCk7CiAgICAgICAgZXhpdCgwKTsKICAgIH0KfQoKU1RSRUFNUFJPWFk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcHJveHlDb2RlIC4gIlxuIiAuIDw8PFBST1hZCjw/cGhwCgovKioKICogUHJveHkgUEhQIGZpbGUgZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCiAqCiAqIFRoaXMgZmlsZSBpbmNsdWRlcyB0aGUgcmVmZXJlbmNlZCBiaW4gcGF0aCAoJGJpblBhdGgpCiAqJHN0cmVhbUhpbnQKICogQGdlbmVyYXRlZAogKi8KCm5hbWVzcGFjZSBDb21wb3NlcjsKCiRnbG9iYWxzQ29kZQokc3RyZWFtUHJveHlDb2RlCmluY2x1ZGUgJGJpblBhdGhFeHBvcnRlZDsKClBST1hZOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDw8PFBST1hZCiMhL3Vzci9iaW4vZW52IHNoCgojIFN1cHBvcnQgYmFzaCB0byBzdXBwb3J0IGBzb3VyY2VgIHdpdGggZmFsbGJhY2sgb24gJDAgaWYgdGhpcyBkb2VzIG5vdCBydW4gd2l0aCBiYXNoCiMgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM1MDA2NTA1LzY1MTIKc2VsZkFyZz0iXCRCQVNIX1NPVVJDRSIKaWYgWyAteiAiXCRzZWxmQXJnIiBdOyB0aGVuCiAgICBzZWxmQXJnPSJcJDAiCmZpCgpzZWxmPVwkKHJlYWxwYXRoIFwkc2VsZkFyZyAyPiAvZGV2L251bGwpCmlmIFsgLXogIlwkc2VsZiIgXTsgdGhlbgogICAgc2VsZj0iXCRzZWxmQXJnIgpmaQoKZGlyPVwkKGNkICJcJHtzZWxmJVsvXFxcXF0qfSIgPiAvZGV2L251bGw7IGNkICRiaW5EaXIgJiYgcHdkKQoKaWYgWyAtZCAvcHJvYy9jeWdkcml2ZSBdOyB0aGVuCiAgICBjYXNlIFwkKHdoaWNoIHBocCkgaW4KICAgICAgICBcJChyZWFkbGluayAtbiAvcHJvYy9jeWdkcml2ZSkvKikKICAgICAgICAgICAgIyBXZSBhcmUgaW4gQ3lnd2luIHVzaW5nIFdpbmRvd3MgcGhwLCBzbyB0aGUgcGF0aCBtdXN0IGJlIHRyYW5zbGF0ZWQKICAgICAgICAgICAgZGlyPVwkKGN5Z3BhdGggLW0gIlwkZGlyIik7CiAgICAgICAgICAgIDs7CiAgICBlc2FjCmZpCgpleHBvcnQgQ09NUE9TRVJfQklOX0RJUj1cJChjZCAiXCR7c2VsZiVbL1xcXFxdKn0iID4gL2Rldi9udWxsOyBwd2QpCgojIElmIGJhc2ggaXMgc291cmNpbmcgdGhpcyBmaWxlLCB3ZSBoYXZlIHRvIHNvdXJjZSB0aGUgdGFyZ2V0IGFzIHdlbGwKYmFzaFNvdXJjZT0iXCRCQVNIX1NPVVJDRSIKaWYgWyAtbiAiXCRiYXNoU291cmNlIiBdOyB0aGVuCiAgICBpZiBbICJcJGJhc2hTb3VyY2UiICE9ICJcJDAiIF07IHRoZW4KICAgICAgICBzb3VyY2UgIlwke2Rpcn0vJGJpbkZpbGUiICJcJEAiCiAgICAgICAgcmV0dXJuCiAgICBmaQpmaQoKIlwke2Rpcn0vJGJpbkZpbGUiICJcJEAiCgpQUk9YWTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7Cgp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cT3BlcmF0aW9uSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50OwoKLyoqCiAqIFRoZSBQYWNrYWdlIEV2ZW50LgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBQYWNrYWdlRXZlbnQgZXh0ZW5kcyBFdmVudAp7CiAgICAvKioKICAgICAqIEB2YXIgQ29tcG9zZXIKICAgICAqLwogICAgcHJpdmF0ZSAkY29tcG9zZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJGlvOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJGRldk1vZGU7CgogICAgLyoqCiAgICAgKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkbG9jYWxSZXBvOwoKICAgIC8qKgogICAgICogQHZhciBPcGVyYXRpb25JbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlICRvcGVyYXRpb25zOwoKICAgIC8qKgogICAgICogQHZhciBPcGVyYXRpb25JbnRlcmZhY2UgVGhlIG9wZXJhdGlvbiBpbnN0YW5jZSB3aGljaCBpcyBiZWluZyBleGVjdXRlZAogICAgICovCiAgICBwcml2YXRlICRvcGVyYXRpb247CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJGV2ZW50TmFtZQogICAgICogQHBhcmFtIENvbXBvc2VyICAgICAgICAgICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAgICAgICRpbwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICRkZXZNb2RlCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAgJGxvY2FsUmVwbwogICAgICogQHBhcmFtIE9wZXJhdGlvbkludGVyZmFjZVtdICRvcGVyYXRpb25zCiAgICAgKiBAcGFyYW0gT3BlcmF0aW9uSW50ZXJmYWNlICAgJG9wZXJhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGV2ZW50TmFtZSwgQ29tcG9zZXIgJGNvbXBvc2VyLCBJT0ludGVyZmFjZSAkaW8sICRkZXZNb2RlLCBSZXBvc2l0b3J5SW50ZXJmYWNlICRsb2NhbFJlcG8sIGFycmF5ICRvcGVyYXRpb25zLCBPcGVyYXRpb25JbnRlcmZhY2UgJG9wZXJhdGlvbikKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRldmVudE5hbWUpOwoKICAgICAgICAkdGhpcy0+Y29tcG9zZXIgPSAkY29tcG9zZXI7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5kZXZNb2RlID0gJGRldk1vZGU7CiAgICAgICAgJHRoaXMtPmxvY2FsUmVwbyA9ICRsb2NhbFJlcG87CiAgICAgICAgJHRoaXMtPm9wZXJhdGlvbnMgPSAkb3BlcmF0aW9uczsKICAgICAgICAkdGhpcy0+b3BlcmF0aW9uID0gJG9wZXJhdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29tcG9zZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBvc2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBJT0ludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SU8oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW87CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGV2TW9kZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXZNb2RlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSZXBvc2l0b3J5SW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbFJlcG8oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9jYWxSZXBvOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBPcGVyYXRpb25JbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE9wZXJhdGlvbkludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZXJhdGlvbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxEb3dubG9hZE1hbmFnZXI7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CgovKioKICogUHJvamVjdCBJbnN0YWxsZXIgaXMgdXNlZCB0byBpbnN0YWxsIGEgc2luZ2xlIHBhY2thZ2UgaW50byBhIGRpcmVjdG9yeSBhcwogKiByb290IHByb2plY3QuCiAqCiAqIEBhdXRob3IgQmVuamFtaW4gRWJlcmxlaSA8a29udGFrdEBiZWJlcmxlaS5kZT4KICovCmNsYXNzIFByb2plY3RJbnN0YWxsZXIgaW1wbGVtZW50cyBJbnN0YWxsZXJJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRpbnN0YWxsUGF0aDsKICAgIC8qKiBAdmFyIERvd25sb2FkTWFuYWdlciAqLwogICAgcHJpdmF0ZSAkZG93bmxvYWRNYW5hZ2VyOwogICAgLyoqIEB2YXIgRmlsZXN5c3RlbSAqLwogICAgcHJpdmF0ZSAkZmlsZXN5c3RlbTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGluc3RhbGxQYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5zdGFsbFBhdGgsIERvd25sb2FkTWFuYWdlciAkZG0sIEZpbGVzeXN0ZW0gJGZzKQogICAgewogICAgICAgICR0aGlzLT5pbnN0YWxsUGF0aCA9IHJ0cmltKHN0cnRyKCRpbnN0YWxsUGF0aCwgJ1xcJywgJy8nKSwgJy8nKS4nLyc7CiAgICAgICAgJHRoaXMtPmRvd25sb2FkTWFuYWdlciA9ICRkbTsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmczsKICAgIH0KCiAgICAvKioKICAgICAqIERlY2lkZXMgaWYgdGhlIGluc3RhbGxlciBzdXBwb3J0cyB0aGUgZ2l2ZW4gdHlwZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYWNrYWdlVHlwZQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdXBwb3J0cygkcGFja2FnZVR5cGUpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICRpbnN0YWxsUGF0aCA9ICR0aGlzLT5pbnN0YWxsUGF0aDsKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGluc3RhbGxQYXRoKSAmJiAhJHRoaXMtPmZpbGVzeXN0ZW0tPmlzRGlyRW1wdHkoJGluc3RhbGxQYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiUHJvamVjdCBkaXJlY3RvcnkgJGluc3RhbGxQYXRoIGlzIG5vdCBlbXB0eS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpc19kaXIoJGluc3RhbGxQYXRoKSkgewogICAgICAgICAgICBta2RpcigkaW5zdGFsbFBhdGgsIDA3NzcsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmRvd25sb2FkKCRwYWNrYWdlLCAkaW5zdGFsbFBhdGgsICRwcmV2UGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5wcmVwYXJlKCR0eXBlLCAkcGFja2FnZSwgJHRoaXMtPmluc3RhbGxQYXRoLCAkcHJldlBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+Y2xlYW51cCgkdHlwZSwgJHBhY2thZ2UsICR0aGlzLT5pbnN0YWxsUGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmluc3RhbGwoJHBhY2thZ2UsICR0aGlzLT5pbnN0YWxsUGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigibm90IHN1cHBvcnRlZCIpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJub3Qgc3VwcG9ydGVkIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnN0YWxsYXRpb24gcGF0aCBvZiBhIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5zdGFsbFBhdGg7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBJbnRlcmZhY2UgZm9yIHRoZSBwYWNrYWdlIGluc3RhbGxhdGlvbiBtYW5hZ2VyIHRoYXQgaGFuZGxlIGJpbmFyeSBpbnN0YWxsYXRpb24uCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmludGVyZmFjZSBCaW5hcnlQcmVzZW5jZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIE1ha2Ugc3VyZSBiaW5hcmllcyBhcmUgaW5zdGFsbGVkIGZvciBhIGdpdmVuIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5zdXJlQmluYXJpZXNQcmVzZW5jZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CgovKioKICogQWRkIHN1Z2dlc3RlZCBwYWNrYWdlcyBmcm9tIGRpZmZlcmVudCBwbGFjZXMgdG8gb3V0cHV0IHRoZW0gaW4gdGhlIGVuZC4KICoKICogQGF1dGhvciBIYXJhbGFuIERvYnJldiA8aGtkb2JyZXZAZ21haWwuY29tPgogKi8KY2xhc3MgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgp7CiAgICBjb25zdCBNT0RFX0xJU1QgPSAxOwogICAgY29uc3QgTU9ERV9CWV9QQUNLQUdFID0gMjsKICAgIGNvbnN0IE1PREVfQllfU1VHR0VTVElPTiA9IDQ7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5PGFycmF5e3NvdXJjZTogc3RyaW5nLCB0YXJnZXQ6IHN0cmluZywgcmVhc29uOiBzdHJpbmd9PgogICAgICovCiAgICBwcm90ZWN0ZWQgJHN1Z2dlc3RlZFBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbykKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5PGFycmF5e3NvdXJjZTogc3RyaW5nLCB0YXJnZXQ6IHN0cmluZywgcmVhc29uOiBzdHJpbmd9PiBTdWdnZXN0ZWQgcGFja2FnZXMgd2l0aCBzb3VyY2UsIHRhcmdldCBhbmQgcmVhc29uIGtleXMuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBzdWdnZXN0ZWQgcGFja2FnZXMgdG8gYmUgbGlzdGVkIGFmdGVyIGluc3RhbGwKICAgICAqCiAgICAgKiBDb3VsZCBiZSB1c2VkIHRvIGFkZCBzdWdnZXN0ZWQgcGFja2FnZXMgYm90aCBmcm9tIHRoZSBpbnN0YWxsZXIKICAgICAqIG9yIGZyb20gQ3JlYXRlUHJvamVjdENvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRzb3VyY2UgU291cmNlIHBhY2thZ2Ugd2hpY2ggbWFkZSB0aGUgc3VnZ2VzdGlvbgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICR0YXJnZXQgVGFyZ2V0IHBhY2thZ2UgdG8gYmUgc3VnZ2VzdGVkCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiBSZWFzb24gdGhlIHRhcmdldCBwYWNrYWdlIHRvIGJlIHN1Z2dlc3RlZAogICAgICogQHJldHVybiBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRQYWNrYWdlKCRzb3VyY2UsICR0YXJnZXQsICRyZWFzb24pCiAgICB7CiAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzW10gPSBhcnJheSgKICAgICAgICAgICAgJ3NvdXJjZScgPT4gJHNvdXJjZSwKICAgICAgICAgICAgJ3RhcmdldCcgPT4gJHRhcmdldCwKICAgICAgICAgICAgJ3JlYXNvbicgPT4gJHJlYXNvbiwKICAgICAgICApOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGQgYWxsIHN1Z2dlc3Rpb25zIGZyb20gYSBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICAgICAkcGFja2FnZQogICAgICogQHJldHVybiBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTdWdnZXN0aW9uc0Zyb21QYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHNvdXJjZSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCk7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFN1Z2dlc3RzKCkgYXMgJHRhcmdldCA9PiAkcmVhc29uKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKAogICAgICAgICAgICAgICAgJHNvdXJjZSwKICAgICAgICAgICAgICAgICR0YXJnZXQsCiAgICAgICAgICAgICAgICAkcmVhc29uCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBPdXRwdXQgc3VnZ2VzdGVkIHBhY2thZ2VzLgogICAgICoKICAgICAqIERvIG5vdCBsaXN0IHRoZSBvbmVzIGFscmVhZHkgaW5zdGFsbGVkIGlmIGluc3RhbGxlZCByZXBvc2l0b3J5IHByb3ZpZGVkLgogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgICAgICAgICAgICAgICRtb2RlICAgICAgICAgICAgIE9uZSBvZiB0aGUgTU9ERV8qIGNvbnN0YW50cyBmcm9tIHRoaXMgY2xhc3MKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeXxudWxsICRpbnN0YWxsZWRSZXBvICAgIElmIHBhc3NlZCBpbiwgc3VnZ2VzdGVkIHBhY2thZ2VzIHdoaWNoIGFyZSBpbnN0YWxsZWQgYWxyZWFkeSB3aWxsIGJlIHNraXBwZWQKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZXxudWxsICAgICRvbmx5RGVwZW5kZW50c09mIElmIHBhc3NlZCBpbiwgb25seSB0aGUgc3VnZ2VzdGlvbnMgZnJvbSBkaXJlY3QgZGVwZW5kZW50cyBvZiB0aGF0IHBhY2thZ2UsIG9yIGZyb20gdGhlIHBhY2thZ2UgaXRzZWxmLCB3aWxsIGJlIHNob3duCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG91dHB1dCgkbW9kZSwgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbyA9IG51bGwsIFBhY2thZ2VJbnRlcmZhY2UgJG9ubHlEZXBlbmRlbnRzT2YgPSBudWxsKQogICAgewogICAgICAgICRzdWdnZXN0ZWRQYWNrYWdlcyA9ICR0aGlzLT5nZXRGaWx0ZXJlZFN1Z2dlc3Rpb25zKCRpbnN0YWxsZWRSZXBvLCAkb25seURlcGVuZGVudHNPZik7CgogICAgICAgICRzdWdnZXN0ZXJzID0gYXJyYXkoKTsKICAgICAgICAkc3VnZ2VzdGVkID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVkUGFja2FnZXMgYXMgJHN1Z2dlc3Rpb24pIHsKICAgICAgICAgICAgJHN1Z2dlc3RlcnNbJHN1Z2dlc3Rpb25bJ3NvdXJjZSddXVskc3VnZ2VzdGlvblsndGFyZ2V0J11dID0gJHN1Z2dlc3Rpb25bJ3JlYXNvbiddOwogICAgICAgICAgICAkc3VnZ2VzdGVkWyRzdWdnZXN0aW9uWyd0YXJnZXQnXV1bJHN1Z2dlc3Rpb25bJ3NvdXJjZSddXSA9ICRzdWdnZXN0aW9uWydyZWFzb24nXTsKICAgICAgICB9CiAgICAgICAga3NvcnQoJHN1Z2dlc3RlcnMpOwogICAgICAgIGtzb3J0KCRzdWdnZXN0ZWQpOwoKICAgICAgICAvLyBTaW1wbGUgbW9kZQogICAgICAgIGlmICgkbW9kZSAmIHNlbGY6Ok1PREVfTElTVCkgewogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9rZXlzKCRzdWdnZXN0ZWQpIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKHNwcmludGYoJzxpbmZvPiVzPC9pbmZvPicsICRuYW1lKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIEdyb3VwZWQgYnkgcGFja2FnZQogICAgICAgIGlmICgkbW9kZSAmIHNlbGY6Ok1PREVfQllfUEFDS0FHRSkgewogICAgICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVycyBhcyAkc3VnZ2VzdGVyID0+ICRzdWdnZXN0aW9ucykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzcHJpbnRmKCc8Y29tbWVudD4lczwvY29tbWVudD4gc3VnZ2VzdHM6JywgJHN1Z2dlc3RlcikpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRzdWdnZXN0aW9ucyBhcyAkc3VnZ2VzdGlvbiA9PiAkcmVhc29uKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzcHJpbnRmKCcgLSA8aW5mbz4lczwvaW5mbz4nIC4gKCRyZWFzb24gPyAnOiAlcycgOiAnJyksICRzdWdnZXN0aW9uLCAkdGhpcy0+ZXNjYXBlT3V0cHV0KCRyZWFzb24pKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKCcnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gR3JvdXBlZCBieSBzdWdnZXN0aW9uCiAgICAgICAgaWYgKCRtb2RlICYgc2VsZjo6TU9ERV9CWV9TVUdHRVNUSU9OKSB7CiAgICAgICAgICAgIC8vIEltcHJvdmUgcmVhZGFiaWxpdHkgaW4gZnVsbCBtb2RlCiAgICAgICAgICAgIGlmICgkbW9kZSAmIHNlbGY6Ok1PREVfQllfUEFDS0FHRSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzdHJfcmVwZWF0KCctJywgNzgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVkIGFzICRzdWdnZXN0aW9uID0+ICRzdWdnZXN0ZXJzKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKHNwcmludGYoJzxjb21tZW50PiVzPC9jb21tZW50PiBpcyBzdWdnZXN0ZWQgYnk6JywgJHN1Z2dlc3Rpb24pKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVycyBhcyAkc3VnZ2VzdGVyID0+ICRyZWFzb24pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKHNwcmludGYoJyAtIDxpbmZvPiVzPC9pbmZvPicgLiAoJHJlYXNvbiA/ICc6ICVzJyA6ICcnKSwgJHN1Z2dlc3RlciwgJHRoaXMtPmVzY2FwZU91dHB1dCgkcmVhc29uKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgnJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkb25seURlcGVuZGVudHNPZikgewogICAgICAgICAgICAkYWxsU3VnZ2VzdGVkUGFja2FnZXMgPSAkdGhpcy0+Z2V0RmlsdGVyZWRTdWdnZXN0aW9ucygkaW5zdGFsbGVkUmVwbyk7CiAgICAgICAgICAgICRkaWZmID0gY291bnQoJGFsbFN1Z2dlc3RlZFBhY2thZ2VzKSAtIGNvdW50KCRzdWdnZXN0ZWRQYWNrYWdlcyk7CiAgICAgICAgICAgIGlmICgkZGlmZikgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgnPGluZm8+Jy4kZGlmZi4nIGFkZGl0aW9uYWwgc3VnZ2VzdGlvbnM8L2luZm8+IGJ5IHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIGNhbiBiZSBzaG93biB3aXRoIDxpbmZvPi0tYWxsPC9pbmZvPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogT3V0cHV0IG51bWJlciBvZiBuZXcgc3VnZ2VzdGVkIHBhY2thZ2VzIGFuZCBhIGhpbnQgdG8gdXNlIHN1Z2dlc3QgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIEluc3RhbGxlZFJlcG9zaXRvcnl8bnVsbCAkaW5zdGFsbGVkUmVwbyAgICBJZiBwYXNzZWQgaW4sIHN1Z2dlc3RlZCBwYWNrYWdlcyB3aGljaCBhcmUgaW5zdGFsbGVkIGFscmVhZHkgd2lsbCBiZSBza2lwcGVkCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAgICAkb25seURlcGVuZGVudHNPZiBJZiBwYXNzZWQgaW4sIG9ubHkgdGhlIHN1Z2dlc3Rpb25zIGZyb20gZGlyZWN0IGRlcGVuZGVudHMgb2YgdGhhdCBwYWNrYWdlLCBvciBmcm9tIHRoZSBwYWNrYWdlIGl0c2VsZiwgd2lsbCBiZSBzaG93bgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvdXRwdXRNaW5pbWFsaXN0aWMoSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbyA9IG51bGwsIFBhY2thZ2VJbnRlcmZhY2UgJG9ubHlEZXBlbmRlbnRzT2YgPSBudWxsKQogICAgewogICAgICAgICRzdWdnZXN0ZWRQYWNrYWdlcyA9ICR0aGlzLT5nZXRGaWx0ZXJlZFN1Z2dlc3Rpb25zKCRpbnN0YWxsZWRSZXBvLCAkb25seURlcGVuZGVudHNPZik7CiAgICAgICAgaWYgKCRzdWdnZXN0ZWRQYWNrYWdlcykgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPicuY291bnQoJHN1Z2dlc3RlZFBhY2thZ2VzKS4nIHBhY2thZ2Ugc3VnZ2VzdGlvbnMgd2VyZSBhZGRlZCBieSBuZXcgZGVwZW5kZW5jaWVzLCB1c2UgYGNvbXBvc2VyIHN1Z2dlc3RgIHRvIHNlZSBkZXRhaWxzLjwvaW5mbz4nKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIEluc3RhbGxlZFJlcG9zaXRvcnl8bnVsbCAkaW5zdGFsbGVkUmVwbyAgICBJZiBwYXNzZWQgaW4sIHN1Z2dlc3RlZCBwYWNrYWdlcyB3aGljaCBhcmUgaW5zdGFsbGVkIGFscmVhZHkgd2lsbCBiZSBza2lwcGVkCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAgICAkb25seURlcGVuZGVudHNPZiBJZiBwYXNzZWQgaW4sIG9ubHkgdGhlIHN1Z2dlc3Rpb25zIGZyb20gZGlyZWN0IGRlcGVuZGVudHMgb2YgdGhhdCBwYWNrYWdlLCBvciBmcm9tIHRoZSBwYWNrYWdlIGl0c2VsZiwgd2lsbCBiZSBzaG93bgogICAgICogQHJldHVybiBtaXhlZFtdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RmlsdGVyZWRTdWdnZXN0aW9ucyhJbnN0YWxsZWRSZXBvc2l0b3J5ICRpbnN0YWxsZWRSZXBvID0gbnVsbCwgUGFja2FnZUludGVyZmFjZSAkb25seURlcGVuZGVudHNPZiA9IG51bGwpCiAgICB7CiAgICAgICAgJHN1Z2dlc3RlZFBhY2thZ2VzID0gJHRoaXMtPmdldFBhY2thZ2VzKCk7CiAgICAgICAgJGluc3RhbGxlZE5hbWVzID0gYXJyYXkoKTsKICAgICAgICBpZiAobnVsbCAhPT0gJGluc3RhbGxlZFJlcG8gJiYgIWVtcHR5KCRzdWdnZXN0ZWRQYWNrYWdlcykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGluc3RhbGxlZFJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRpbnN0YWxsZWROYW1lcyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgICAgICRpbnN0YWxsZWROYW1lcywKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0TmFtZXMoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHNvdXJjZUZpbHRlciA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRvbmx5RGVwZW5kZW50c09mKSB7CiAgICAgICAgICAgICRzb3VyY2VGaWx0ZXIgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRsaW5rKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICB9LCBhcnJheV9tZXJnZSgkb25seURlcGVuZGVudHNPZi0+Z2V0UmVxdWlyZXMoKSwgJG9ubHlEZXBlbmRlbnRzT2YtPmdldERldlJlcXVpcmVzKCkpKTsKICAgICAgICAgICAgJHNvdXJjZUZpbHRlcltdID0gJG9ubHlEZXBlbmRlbnRzT2YtPmdldE5hbWUoKTsKICAgICAgICB9CgogICAgICAgICRzdWdnZXN0aW9ucyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHN1Z2dlc3RlZFBhY2thZ2VzIGFzICRzdWdnZXN0aW9uKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkc3VnZ2VzdGlvblsndGFyZ2V0J10sICRpbnN0YWxsZWROYW1lcykgfHwgKCRzb3VyY2VGaWx0ZXIgJiYgIWluX2FycmF5KCRzdWdnZXN0aW9uWydzb3VyY2UnXSwgJHNvdXJjZUZpbHRlcikpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHN1Z2dlc3Rpb25zW10gPSAkc3VnZ2VzdGlvbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3VnZ2VzdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkc3RyaW5nCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVzY2FwZU91dHB1dCgkc3RyaW5nKQogICAgewogICAgICAgIHJldHVybiBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZSgKICAgICAgICAgICAgJHRoaXMtPnJlbW92ZUNvbnRyb2xDaGFyYWN0ZXJzKCRzdHJpbmcpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzdHJpbmcKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVtb3ZlQ29udHJvbENoYXJhY3RlcnMoJHN0cmluZykKICAgIHsKICAgICAgICByZXR1cm4gUHJlZzo6cmVwbGFjZSgKICAgICAgICAgICAgJy9bWzpjbnRybDpdXS8nLAogICAgICAgICAgICAnJywKICAgICAgICAgICAgc3RyX3JlcGxhY2UoIlxuIiwgJyAnLCAkc3RyaW5nKQogICAgICAgICk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSU9cQ29uc29sZUlPOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXE9wZXJhdGlvbkludGVyZmFjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVXBkYXRlT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXE1hcmtBbGlhc0luc3RhbGxlZE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cTWFya0FsaWFzVW5pbnN0YWxsZWRPcGVyYXRpb247CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXEZpbGVEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXFV0aWxcTG9vcDsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogUGFja2FnZSBvcGVyYXRpb24gbWFuYWdlci4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgSW5zdGFsbGF0aW9uTWFuYWdlcgp7CiAgICAvKiogQHZhciBhcnJheTxJbnN0YWxsZXJJbnRlcmZhY2U+ICovCiAgICBwcml2YXRlICRpbnN0YWxsZXJzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgSW5zdGFsbGVySW50ZXJmYWNlPiAqLwogICAgcHJpdmF0ZSAkY2FjaGUgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxQYWNrYWdlSW50ZXJmYWNlPj4gKi8KICAgIHByaXZhdGUgJG5vdGlmaWFibGVQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBMb29wICovCiAgICBwcml2YXRlICRsb29wOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqIEB2YXIgP0V2ZW50RGlzcGF0Y2hlciAqLwogICAgcHJpdmF0ZSAkZXZlbnREaXNwYXRjaGVyOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkb3V0cHV0UHJvZ3Jlc3M7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KExvb3AgJGxvb3AsIElPSW50ZXJmYWNlICRpbywgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5sb29wID0gJGxvb3A7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNldCgpCiAgICB7CiAgICAgICAgJHRoaXMtPm5vdGlmaWFibGVQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgRmlsZURvd25sb2FkZXI6OiRkb3dubG9hZE1ldGFkYXRhID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgaW5zdGFsbGVyCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlckludGVyZmFjZSAkaW5zdGFsbGVyIGluc3RhbGxlciBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkSW5zdGFsbGVyKEluc3RhbGxlckludGVyZmFjZSAkaW5zdGFsbGVyKQogICAgewogICAgICAgIGFycmF5X3Vuc2hpZnQoJHRoaXMtPmluc3RhbGxlcnMsICRpbnN0YWxsZXIpOwogICAgICAgICR0aGlzLT5jYWNoZSA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGluc3RhbGxlcgogICAgICoKICAgICAqIEBwYXJhbSBJbnN0YWxsZXJJbnRlcmZhY2UgJGluc3RhbGxlciBpbnN0YWxsZXIgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUluc3RhbGxlcihJbnN0YWxsZXJJbnRlcmZhY2UgJGluc3RhbGxlcikKICAgIHsKICAgICAgICBpZiAoZmFsc2UgIT09ICgka2V5ID0gYXJyYXlfc2VhcmNoKCRpbnN0YWxsZXIsICR0aGlzLT5pbnN0YWxsZXJzLCB0cnVlKSkpIHsKICAgICAgICAgICAgYXJyYXlfc3BsaWNlKCR0aGlzLT5pbnN0YWxsZXJzLCAka2V5LCAxKTsKICAgICAgICAgICAgJHRoaXMtPmNhY2hlID0gYXJyYXkoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNhYmxlcyBwbHVnaW5zLgogICAgICoKICAgICAqIFdlIHByZXZlbnQgYW55IHBsdWdpbnMgZnJvbSBiZWluZyBpbnN0YW50aWF0ZWQgYnkgc2ltcGx5CiAgICAgKiBkZWFjdGl2YXRpbmcgdGhlIGluc3RhbGxlciBmb3IgdGhlbS4gVGhpcyBlbnN1cmUgdGhhdCBubyB0aGlyZC1wYXJ0eQogICAgICogY29kZSBpcyBldmVyIGV4ZWN1dGVkLgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZVBsdWdpbnMoKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5pbnN0YWxsZXJzIGFzICRpID0+ICRpbnN0YWxsZXIpIHsKICAgICAgICAgICAgaWYgKCEkaW5zdGFsbGVyIGluc3RhbmNlb2YgUGx1Z2luSW5zdGFsbGVyKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmluc3RhbGxlcnNbJGldKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGluc3RhbGxlciBmb3IgYSBzcGVjaWZpYyBwYWNrYWdlIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSBwYWNrYWdlIHR5cGUKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgaW5zdGFsbGVyIGZvciBwcm92aWRlZCB0eXBlIGlzIG5vdCByZWdpc3RlcmVkCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVyKCR0eXBlKQogICAgewogICAgICAgICR0eXBlID0gc3RydG9sb3dlcigkdHlwZSk7CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y2FjaGVbJHR5cGVdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNhY2hlWyR0eXBlXTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5pbnN0YWxsZXJzIGFzICRpbnN0YWxsZXIpIHsKICAgICAgICAgICAgaWYgKCRpbnN0YWxsZXItPnN1cHBvcnRzKCR0eXBlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jYWNoZVskdHlwZV0gPSAkaW5zdGFsbGVyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVW5rbm93biBpbnN0YWxsZXIgdHlwZTogJy4kdHlwZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciBwcm92aWRlZCBwYWNrYWdlIGlzIGluc3RhbGxlZCBpbiBvbmUgb2YgdGhlIHJlZ2lzdGVyZWQgaW5zdGFsbGVycy4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICAgICAgICAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1BhY2thZ2VJbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSAmJiAkdGhpcy0+aXNQYWNrYWdlSW5zdGFsbGVkKCRyZXBvLCAkcGFja2FnZS0+Z2V0QWxpYXNPZigpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SW5zdGFsbGVyKCRwYWNrYWdlLT5nZXRUeXBlKCkpLT5pc0luc3RhbGxlZCgkcmVwbywgJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogSW5zdGFsbCBiaW5hcnkgZm9yIHRoZSBnaXZlbiBwYWNrYWdlLgogICAgICogSWYgdGhlIGluc3RhbGxlciBhc3NvY2lhdGVkIHRvIHRoaXMgcGFja2FnZSBkb2Vzbid0IGhhbmRsZSB0aGF0IGZ1bmN0aW9uLCBpdCdsbCBkbyBub3RoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIFBhY2thZ2UgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuc3VyZUJpbmFyaWVzUHJlc2VuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkcGFja2FnZS0+Z2V0VHlwZSgpKTsKICAgICAgICB9IGNhdGNoIChcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIC8vIG5vIGluc3RhbGxlciBmb3VuZCBmb3IgdGhlIGN1cnJlbnQgcGFja2FnZSB0eXBlIChAc2VlIGBnZXRJbnN0YWxsZXIoKWApCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIGlmIHRoZSBnaXZlbiBpbnN0YWxsZXIgc3VwcG9ydCBpbnN0YWxsaW5nIGJpbmFyaWVzCiAgICAgICAgaWYgKCRpbnN0YWxsZXIgaW5zdGFuY2VvZiBCaW5hcnlQcmVzZW5jZUludGVyZmFjZSkgewogICAgICAgICAgICAkaW5zdGFsbGVyLT5lbnN1cmVCaW5hcmllc1ByZXNlbmNlKCRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyBzb2x2ZXIgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvICAgICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gYWRkL3JlbW92ZS91cGRhdGUgcGFja2FnZXMKICAgICAqIEBwYXJhbSBPcGVyYXRpb25JbnRlcmZhY2VbXSAgICAgICAgICRvcGVyYXRpb25zIG9wZXJhdGlvbnMgdG8gZXhlY3V0ZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgJGRldk1vZGUgICAgd2hldGhlciB0aGUgaW5zdGFsbCBpcyBiZWluZyBydW4gaW4gZGV2IG1vZGUKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICAgICRydW5TY3JpcHRzIHdoZXRoZXIgdG8gZGlzcGF0Y2ggc2NyaXB0IGV2ZW50cwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZShJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBhcnJheSAkb3BlcmF0aW9ucywgJGRldk1vZGUgPSB0cnVlLCAkcnVuU2NyaXB0cyA9IHRydWUpCiAgICB7CiAgICAgICAgLyoqIEB2YXIgUHJvbWlzZUludGVyZmFjZVtdICovCiAgICAgICAgJGNsZWFudXBQcm9taXNlcyA9IGFycmF5KCk7CgogICAgICAgICRsb29wID0gJHRoaXMtPmxvb3A7CiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICRydW5DbGVhbnVwID0gZnVuY3Rpb24gKCkgdXNlICgmJGNsZWFudXBQcm9taXNlcywgJGxvb3ApIHsKICAgICAgICAgICAgJHByb21pc2VzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICRsb29wLT5hYm9ydEpvYnMoKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRjbGVhbnVwUHJvbWlzZXMgYXMgJGNsZWFudXApIHsKICAgICAgICAgICAgICAgICRwcm9taXNlc1tdID0gbmV3IFxSZWFjdFxQcm9taXNlXFByb21pc2UoZnVuY3Rpb24gKCRyZXNvbHZlLCAkcmVqZWN0KSB1c2UgKCRjbGVhbnVwKSB7CiAgICAgICAgICAgICAgICAgICAgJHByb21pc2UgPSAkY2xlYW51cCgpOwogICAgICAgICAgICAgICAgICAgIGlmICghJHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkcmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc29sdmUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJHByb21pc2VzKSkgewogICAgICAgICAgICAgICAgJGxvb3AtPndhaXQoJHByb21pc2VzKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgICRoYW5kbGVJbnRlcnJ1cHRzVW5peCA9IGZ1bmN0aW9uX2V4aXN0cygncGNudGxfYXN5bmNfc2lnbmFscycpICYmIGZ1bmN0aW9uX2V4aXN0cygncGNudGxfc2lnbmFsJyk7CiAgICAgICAgJGhhbmRsZUludGVycnVwdHNXaW5kb3dzID0gZnVuY3Rpb25fZXhpc3RzKCdzYXBpX3dpbmRvd3Nfc2V0X2N0cmxfaGFuZGxlcicpICYmIFBIUF9TQVBJID09PSAnY2xpJzsKICAgICAgICAkcHJldkhhbmRsZXIgPSBudWxsOwogICAgICAgICR3aW5kb3dzSGFuZGxlciA9IG51bGw7CiAgICAgICAgaWYgKCRoYW5kbGVJbnRlcnJ1cHRzVW5peCkgewogICAgICAgICAgICBwY250bF9hc3luY19zaWduYWxzKHRydWUpOwogICAgICAgICAgICAkcHJldkhhbmRsZXIgPSBwY250bF9zaWduYWxfZ2V0X2hhbmRsZXIoU0lHSU5UKTsKICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR0lOVCwgZnVuY3Rpb24gKCRzaWcpIHVzZSAoJHJ1bkNsZWFudXAsICRwcmV2SGFuZGxlciwgJGlvKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1JlY2VpdmVkIFNJR0lOVCwgYWJvcnRpbmcnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAgICAgJHJ1bkNsZWFudXAoKTsKCiAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCRwcmV2SGFuZGxlciwgYXJyYXkoU0lHX0RGTCwgU0lHX0lHTiksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJHByZXZIYW5kbGVyLCAkc2lnKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBleGl0KDEzMCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBpZiAoJGhhbmRsZUludGVycnVwdHNXaW5kb3dzKSB7CiAgICAgICAgICAgICR3aW5kb3dzSGFuZGxlciA9IGZ1bmN0aW9uICgkZXZlbnQpIHVzZSAoJHJ1bkNsZWFudXAsICRpbykgewogICAgICAgICAgICAgICAgaWYgKCRldmVudCAhPT0gUEhQX1dJTkRPV1NfRVZFTlRfQ1RSTF9DKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdSZWNlaXZlZCBDVFJMK0MsIGFib3J0aW5nJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgICRydW5DbGVhbnVwKCk7CgogICAgICAgICAgICAgICAgZXhpdCgxMzApOwogICAgICAgICAgICB9OwogICAgICAgICAgICBzYXBpX3dpbmRvd3Nfc2V0X2N0cmxfaGFuZGxlcigkd2luZG93c0hhbmRsZXIpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gZXhlY3V0ZSBvcGVyYXRpb25zIGluIGJhdGNoZXMgdG8gbWFrZSBzdXJlIGRvd25sb2FkLW1vZGlmeWluZy1wbHVnaW5zIGFyZSBpbnN0YWxsZWQKICAgICAgICAgICAgLy8gYmVmb3JlIHRoZSBvdGhlciBwYWNrYWdlcyBnZXQgZG93bmxvYWRlZAogICAgICAgICAgICAkYmF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRiYXRjaCA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvcGVyYXRpb25zIGFzICRpbmRleCA9PiAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbiB8fCAkb3BlcmF0aW9uIGluc3RhbmNlb2YgSW5zdGFsbE9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbiA/ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKSA6ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFR5cGUoKSA9PT0gJ2NvbXBvc2VyLXBsdWdpbicgJiYgKCRleHRyYSA9ICRwYWNrYWdlLT5nZXRFeHRyYSgpKSAmJiBpc3NldCgkZXh0cmFbJ3BsdWdpbi1tb2RpZmllcy1kb3dubG9hZHMnXSkgJiYgJGV4dHJhWydwbHVnaW4tbW9kaWZpZXMtZG93bmxvYWRzJ10gPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRiYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJhdGNoZXNbXSA9ICRiYXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkYmF0Y2hlc1tdID0gYXJyYXkoJGluZGV4ID0+ICRvcGVyYXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAkYmF0Y2ggPSBhcnJheSgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGJhdGNoWyRpbmRleF0gPSAkb3BlcmF0aW9uOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGJhdGNoKSB7CiAgICAgICAgICAgICAgICAkYmF0Y2hlc1tdID0gJGJhdGNoOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkYmF0Y2hlcyBhcyAkYmF0Y2gpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5kb3dubG9hZEFuZEV4ZWN1dGVCYXRjaCgkcmVwbywgJGJhdGNoLCAkY2xlYW51cFByb21pc2VzLCAkZGV2TW9kZSwgJHJ1blNjcmlwdHMsICRvcGVyYXRpb25zKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHJ1bkNsZWFudXAoKTsKCiAgICAgICAgICAgIGlmICgkaGFuZGxlSW50ZXJydXB0c1VuaXgpIHsKICAgICAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsICRwcmV2SGFuZGxlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRoYW5kbGVJbnRlcnJ1cHRzV2luZG93cykgewogICAgICAgICAgICAgICAgc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXIoJHdpbmRvd3NIYW5kbGVyLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRoYW5kbGVJbnRlcnJ1cHRzVW5peCkgewogICAgICAgICAgICBwY250bF9zaWduYWwoU0lHSU5ULCAkcHJldkhhbmRsZXIpOwogICAgICAgIH0KICAgICAgICBpZiAoJGhhbmRsZUludGVycnVwdHNXaW5kb3dzKSB7CiAgICAgICAgICAgIHNhcGlfd2luZG93c19zZXRfY3RybF9oYW5kbGVyKCR3aW5kb3dzSGFuZGxlciwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gZG8gYSBsYXN0IHdyaXRlIHNvIHRoYXQgd2Ugd3JpdGUgdGhlIHJlcG9zaXRvcnkgZXZlbiBpZiBub3RoaW5nIGNoYW5nZWQKICAgICAgICAvLyBhcyB0aGF0IGNhbiB0cmlnZ2VyIGFuIHVwZGF0ZSBvZiBzb21lIGZpbGVzIGxpa2UgSW5zdGFsbGVkVmVyc2lvbnMucGhwIGlmCiAgICAgICAgLy8gcnVubmluZyBhIG5ldyBjb21wb3NlciB2ZXJzaW9uCiAgICAgICAgJHJlcG8tPndyaXRlKCRkZXZNb2RlLCAkdGhpcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gT3BlcmF0aW9uSW50ZXJmYWNlW10gJG9wZXJhdGlvbnMgICAgTGlzdCBvZiBvcGVyYXRpb25zIHRvIGV4ZWN1dGUgaW4gdGhpcyBiYXRjaAogICAgICogQHBhcmFtIFByb21pc2VJbnRlcmZhY2VbXSAkY2xlYW51cFByb21pc2VzCiAgICAgKiBAcGFyYW0gYm9vbCAkZGV2TW9kZQogICAgICogQHBhcmFtIGJvb2wgJHJ1blNjcmlwdHMKICAgICAqIEBwYXJhbSBPcGVyYXRpb25JbnRlcmZhY2VbXSAkYWxsT3BlcmF0aW9ucyBDb21wbGV0ZSBsaXN0IG9mIG9wZXJhdGlvbnMgdG8gYmUgZXhlY3V0ZWQgaW4gdGhlIGluc3RhbGwgam9iLCB1c2VkIGZvciBldmVudCBsaXN0ZW5lcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBkb3dubG9hZEFuZEV4ZWN1dGVCYXRjaChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBhcnJheSAkb3BlcmF0aW9ucywgYXJyYXkgJiRjbGVhbnVwUHJvbWlzZXMsICRkZXZNb2RlLCAkcnVuU2NyaXB0cywgYXJyYXkgJGFsbE9wZXJhdGlvbnMpCiAgICB7CiAgICAgICAgJHByb21pc2VzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJG9wZXJhdGlvbnMgYXMgJGluZGV4ID0+ICRvcGVyYXRpb24pIHsKICAgICAgICAgICAgJG9wVHlwZSA9ICRvcGVyYXRpb24tPmdldE9wZXJhdGlvblR5cGUoKTsKCiAgICAgICAgICAgIC8vIGlnbm9yaW5nIGFsaWFzIG9wcyBhcyB0aGV5IGRvbid0IG5lZWQgdG8gZXhlY3V0ZSBhbnl0aGluZyBhdCB0aGlzIHN0YWdlCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJG9wVHlwZSwgYXJyYXkoJ3VwZGF0ZScsICdpbnN0YWxsJywgJ3VuaW5zdGFsbCcpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkb3BUeXBlID09PSAndXBkYXRlJykgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgVXBkYXRlT3BlcmF0aW9uICRvcGVyYXRpb24gKi8KICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpOwogICAgICAgICAgICAgICAgJGluaXRpYWxQYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0SW5pdGlhbFBhY2thZ2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qKiBAdmFyIEluc3RhbGxPcGVyYXRpb258TWFya0FsaWFzSW5zdGFsbGVkT3BlcmF0aW9ufE1hcmtBbGlhc1VuaW5zdGFsbGVkT3BlcmF0aW9ufFVuaW5zdGFsbE9wZXJhdGlvbiAkb3BlcmF0aW9uICovCiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgICRpbml0aWFsUGFja2FnZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGluc3RhbGxlciA9ICR0aGlzLT5nZXRJbnN0YWxsZXIoJHBhY2thZ2UtPmdldFR5cGUoKSk7CgogICAgICAgICAgICAkY2xlYW51cFByb21pc2VzWyRpbmRleF0gPSBmdW5jdGlvbiAoKSB1c2UgKCRvcFR5cGUsICRpbnN0YWxsZXIsICRwYWNrYWdlLCAkaW5pdGlhbFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIC8vIGF2b2lkIGNhbGxpbmcgY2xlYW51cCBpZiB0aGUgZG93bmxvYWQgd2FzIG5vdCBldmVuIGluaXRpYWxpemVkIGZvciBhIHBhY2thZ2UKICAgICAgICAgICAgICAgIC8vIGFzIHdpdGhvdXQgaW5zdGFsbGF0aW9uIHNvdXJjZSBjb25maWd1cmVkIG5vdGhpbmcgd2lsbCB3b3JrCiAgICAgICAgICAgICAgICBpZiAoISRwYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJGluc3RhbGxlci0+Y2xlYW51cCgkb3BUeXBlLCAkcGFja2FnZSwgJGluaXRpYWxQYWNrYWdlKTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGlmICgkb3BUeXBlICE9PSAndW5pbnN0YWxsJykgewogICAgICAgICAgICAgICAgJHByb21pc2UgPSAkaW5zdGFsbGVyLT5kb3dubG9hZCgkcGFja2FnZSwgJGluaXRpYWxQYWNrYWdlKTsKICAgICAgICAgICAgICAgIGlmICgkcHJvbWlzZSkgewogICAgICAgICAgICAgICAgICAgICRwcm9taXNlc1tdID0gJHByb21pc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGV4ZWN1dGUgYWxsIGRvd25sb2FkcyBmaXJzdAogICAgICAgIGlmIChjb3VudCgkcHJvbWlzZXMpKSB7CiAgICAgICAgICAgICR0aGlzLT53YWl0T25Qcm9taXNlcygkcHJvbWlzZXMpOwogICAgICAgIH0KCiAgICAgICAgLy8gZXhlY3V0ZSBvcGVyYXRpb25zIGluIGJhdGNoZXMgdG8gbWFrZSBzdXJlIGV2ZXJ5IHBsdWdpbiBpcyBpbnN0YWxsZWQgaW4gdGhlCiAgICAgICAgLy8gcmlnaHQgb3JkZXIgYW5kIGFjdGl2YXRlZCBiZWZvcmUgdGhlIHBhY2thZ2VzIGRlcGVuZGluZyBvbiBpdCBhcmUgaW5zdGFsbGVkCiAgICAgICAgJGJhdGNoZXMgPSBhcnJheSgpOwogICAgICAgICRiYXRjaCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJG9wZXJhdGlvbnMgYXMgJGluZGV4ID0+ICRvcGVyYXRpb24pIHsKICAgICAgICAgICAgaWYgKCRvcGVyYXRpb24gaW5zdGFuY2VvZiBJbnN0YWxsT3BlcmF0aW9uIHx8ICRvcGVyYXRpb24gaW5zdGFuY2VvZiBVcGRhdGVPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbiA/ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKSA6ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItcGx1Z2luJyB8fCAkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItaW5zdGFsbGVyJykgewogICAgICAgICAgICAgICAgICAgIGlmICgkYmF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJhdGNoZXNbXSA9ICRiYXRjaDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGJhdGNoZXNbXSA9IGFycmF5KCRpbmRleCA9PiAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgICAgICAgICAkYmF0Y2ggPSBhcnJheSgpOwoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkYmF0Y2hbJGluZGV4XSA9ICRvcGVyYXRpb247CiAgICAgICAgfQoKICAgICAgICBpZiAoJGJhdGNoKSB7CiAgICAgICAgICAgICRiYXRjaGVzW10gPSAkYmF0Y2g7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkYmF0Y2hlcyBhcyAkYmF0Y2gpIHsKICAgICAgICAgICAgJHRoaXMtPmV4ZWN1dGVCYXRjaCgkcmVwbywgJGJhdGNoLCAkY2xlYW51cFByb21pc2VzLCAkZGV2TW9kZSwgJHJ1blNjcmlwdHMsICRhbGxPcGVyYXRpb25zKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gT3BlcmF0aW9uSW50ZXJmYWNlW10gJG9wZXJhdGlvbnMgICAgTGlzdCBvZiBvcGVyYXRpb25zIHRvIGV4ZWN1dGUgaW4gdGhpcyBiYXRjaAogICAgICogQHBhcmFtIFByb21pc2VJbnRlcmZhY2VbXSAkY2xlYW51cFByb21pc2VzCiAgICAgKiBAcGFyYW0gYm9vbCAkZGV2TW9kZQogICAgICogQHBhcmFtIGJvb2wgJHJ1blNjcmlwdHMKICAgICAqIEBwYXJhbSBPcGVyYXRpb25JbnRlcmZhY2VbXSAkYWxsT3BlcmF0aW9ucyBDb21wbGV0ZSBsaXN0IG9mIG9wZXJhdGlvbnMgdG8gYmUgZXhlY3V0ZWQgaW4gdGhlIGluc3RhbGwgam9iLCB1c2VkIGZvciBldmVudCBsaXN0ZW5lcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBleGVjdXRlQmF0Y2goSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgYXJyYXkgJG9wZXJhdGlvbnMsIGFycmF5ICRjbGVhbnVwUHJvbWlzZXMsICRkZXZNb2RlLCAkcnVuU2NyaXB0cywgYXJyYXkgJGFsbE9wZXJhdGlvbnMpCiAgICB7CiAgICAgICAgJHByb21pc2VzID0gYXJyYXkoKTsKICAgICAgICAkcG9zdEV4ZWNDYWxsYmFja3MgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkb3BlcmF0aW9ucyBhcyAkaW5kZXggPT4gJG9wZXJhdGlvbikgewogICAgICAgICAgICAkb3BUeXBlID0gJG9wZXJhdGlvbi0+Z2V0T3BlcmF0aW9uVHlwZSgpOwoKICAgICAgICAgICAgLy8gaWdub3JpbmcgYWxpYXMgb3BzIGFzIHRoZXkgZG9uJ3QgbmVlZCB0byBleGVjdXRlIGFueXRoaW5nCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJG9wVHlwZSwgYXJyYXkoJ3VwZGF0ZScsICdpbnN0YWxsJywgJ3VuaW5zdGFsbCcpKSkgewogICAgICAgICAgICAgICAgLy8gb3V0cHV0IGFsaWFzIG9wcyBpbiBkZWJ1ZyB2ZXJib3NpdHkgYXMgdGhleSBoYXZlIG5vIG91dHB1dCBvdGhlcndpc2UKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aW8tPmlzRGVidWcoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAtICcgLiAkb3BlcmF0aW9uLT5zaG93KGZhbHNlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+JG9wVHlwZSgkcmVwbywgJG9wZXJhdGlvbik7CgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkb3BUeXBlID09PSAndXBkYXRlJykgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgVXBkYXRlT3BlcmF0aW9uICRvcGVyYXRpb24gKi8KICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpOwogICAgICAgICAgICAgICAgJGluaXRpYWxQYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0SW5pdGlhbFBhY2thZ2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qKiBAdmFyIEluc3RhbGxPcGVyYXRpb258TWFya0FsaWFzSW5zdGFsbGVkT3BlcmF0aW9ufE1hcmtBbGlhc1VuaW5zdGFsbGVkT3BlcmF0aW9ufFVuaW5zdGFsbE9wZXJhdGlvbiAkb3BlcmF0aW9uICovCiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgICRpbml0aWFsUGFja2FnZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGluc3RhbGxlciA9ICR0aGlzLT5nZXRJbnN0YWxsZXIoJHBhY2thZ2UtPmdldFR5cGUoKSk7CgogICAgICAgICAgICAkZXZlbnQgPSAnQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudHM6OlBSRV9QQUNLQUdFXycuc3RydG91cHBlcigkb3BUeXBlKTsKICAgICAgICAgICAgaWYgKGRlZmluZWQoJGV2ZW50KSAmJiAkcnVuU2NyaXB0cyAmJiAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFBhY2thZ2VFdmVudChjb25zdGFudCgkZXZlbnQpLCAkZGV2TW9kZSwgJHJlcG8sICRhbGxPcGVyYXRpb25zLCAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRpc3BhdGNoZXIgPSAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyOwogICAgICAgICAgICAkaW5zdGFsbE1hbmFnZXIgPSAkdGhpczsKICAgICAgICAgICAgJGlvID0gJHRoaXMtPmlvOwoKICAgICAgICAgICAgJHByb21pc2UgPSAkaW5zdGFsbGVyLT5wcmVwYXJlKCRvcFR5cGUsICRwYWNrYWdlLCAkaW5pdGlhbFBhY2thZ2UpOwogICAgICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwcm9taXNlID0gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkb3BUeXBlLCAkaW5zdGFsbE1hbmFnZXIsICRyZXBvLCAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGluc3RhbGxNYW5hZ2VyLT4kb3BUeXBlKCRyZXBvLCAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgfSktPnRoZW4oJGNsZWFudXBQcm9taXNlc1skaW5kZXhdKQogICAgICAgICAgICAtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkaW5zdGFsbE1hbmFnZXIsICRkZXZNb2RlLCAkcmVwbykgewogICAgICAgICAgICAgICAgJHJlcG8tPndyaXRlKCRkZXZNb2RlLCAkaW5zdGFsbE1hbmFnZXIpOwogICAgICAgICAgICB9LCBmdW5jdGlvbiAoJGUpIHVzZSAoJG9wVHlwZSwgJHBhY2thZ2UsICRpbykgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgPGVycm9yPicgLiB1Y2ZpcnN0KCRvcFR5cGUpIC4nIG9mICcuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGZhaWxlZDwvZXJyb3I+Jyk7CgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgJHBvc3RFeGVjQ2FsbGJhY2tzW10gPSBmdW5jdGlvbiAoKSB1c2UgKCRvcFR5cGUsICRydW5TY3JpcHRzLCAkZGlzcGF0Y2hlciwgJGRldk1vZGUsICRyZXBvLCAkYWxsT3BlcmF0aW9ucywgJG9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgJGV2ZW50ID0gJ0NvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnRzOjpQT1NUX1BBQ0tBR0VfJy5zdHJ0b3VwcGVyKCRvcFR5cGUpOwogICAgICAgICAgICAgICAgaWYgKGRlZmluZWQoJGV2ZW50KSAmJiAkcnVuU2NyaXB0cyAmJiAkZGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgICAgICRkaXNwYXRjaGVyLT5kaXNwYXRjaFBhY2thZ2VFdmVudChjb25zdGFudCgkZXZlbnQpLCAkZGV2TW9kZSwgJHJlcG8sICRhbGxPcGVyYXRpb25zLCAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICRwcm9taXNlc1tdID0gJHByb21pc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBleGVjdXRlIGFsbCBwcmVwYXJlID0+IGluc3RhbGxzL3VwZGF0ZXMvcmVtb3ZlcyA9PiBjbGVhbnVwIHN0ZXBzCiAgICAgICAgaWYgKGNvdW50KCRwcm9taXNlcykpIHsKICAgICAgICAgICAgJHRoaXMtPndhaXRPblByb21pc2VzKCRwcm9taXNlcyk7CiAgICAgICAgfQoKICAgICAgICBQbGF0Zm9ybTo6d29ya2Fyb3VuZEZpbGVzeXN0ZW1Jc3N1ZXMoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBvc3RFeGVjQ2FsbGJhY2tzIGFzICRjYikgewogICAgICAgICAgICAkY2IoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUHJvbWlzZUludGVyZmFjZVtdICRwcm9taXNlcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdhaXRPblByb21pc2VzKGFycmF5ICRwcm9taXNlcykKICAgIHsKICAgICAgICAkcHJvZ3Jlc3MgPSBudWxsOwogICAgICAgIGlmICgKICAgICAgICAgICAgJHRoaXMtPm91dHB1dFByb2dyZXNzCiAgICAgICAgICAgICYmICR0aGlzLT5pbyBpbnN0YW5jZW9mIENvbnNvbGVJTwogICAgICAgICAgICAmJiAhUGxhdGZvcm06OmdldEVudignQ0knKQogICAgICAgICAgICAmJiAhJHRoaXMtPmlvLT5pc0RlYnVnKCkKICAgICAgICAgICAgJiYgY291bnQoJHByb21pc2VzKSA+IDEKICAgICAgICApIHsKICAgICAgICAgICAgJHByb2dyZXNzID0gJHRoaXMtPmlvLT5nZXRQcm9ncmVzc0JhcigpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+bG9vcC0+d2FpdCgkcHJvbWlzZXMsICRwcm9ncmVzcyk7CiAgICAgICAgaWYgKCRwcm9ncmVzcykgewogICAgICAgICAgICAkcHJvZ3Jlc3MtPmNsZWFyKCk7CiAgICAgICAgICAgIC8vIFByb2dyZXNzQmFyIGluIG5vbi1kZWNvcmF0ZWQgb3V0cHV0IGRvZXMgbm90IG91dHB1dCBhIGZpbmFsIGxpbmUtYnJlYWsgYW5kIGNsZWFyKCkgZG9lcyBub3RoaW5nCiAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0RlY29yYXRlZCgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgaW5zdGFsbCBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gICAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gSW5zdGFsbE9wZXJhdGlvbiAgICAgICAgICAgICAkb3BlcmF0aW9uIG9wZXJhdGlvbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIEluc3RhbGxPcGVyYXRpb24gJG9wZXJhdGlvbikKICAgIHsKICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkcGFja2FnZS0+Z2V0VHlwZSgpKTsKICAgICAgICAkcHJvbWlzZSA9ICRpbnN0YWxsZXItPmluc3RhbGwoJHJlcG8sICRwYWNrYWdlKTsKICAgICAgICAkdGhpcy0+bWFya0Zvck5vdGlmaWNhdGlvbigkcGFja2FnZSk7CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHVwZGF0ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gICAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gVXBkYXRlT3BlcmF0aW9uICAgICAgICAgICAgICAkb3BlcmF0aW9uIG9wZXJhdGlvbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgVXBkYXRlT3BlcmF0aW9uICRvcGVyYXRpb24pCiAgICB7CiAgICAgICAgJGluaXRpYWwgPSAkb3BlcmF0aW9uLT5nZXRJbml0aWFsUGFja2FnZSgpOwogICAgICAgICR0YXJnZXQgPSAkb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCk7CgogICAgICAgICRpbml0aWFsVHlwZSA9ICRpbml0aWFsLT5nZXRUeXBlKCk7CiAgICAgICAgJHRhcmdldFR5cGUgPSAkdGFyZ2V0LT5nZXRUeXBlKCk7CgogICAgICAgIGlmICgkaW5pdGlhbFR5cGUgPT09ICR0YXJnZXRUeXBlKSB7CiAgICAgICAgICAgICRpbnN0YWxsZXIgPSAkdGhpcy0+Z2V0SW5zdGFsbGVyKCRpbml0aWFsVHlwZSk7CiAgICAgICAgICAgICRwcm9taXNlID0gJGluc3RhbGxlci0+dXBkYXRlKCRyZXBvLCAkaW5pdGlhbCwgJHRhcmdldCk7CiAgICAgICAgICAgICR0aGlzLT5tYXJrRm9yTm90aWZpY2F0aW9uKCR0YXJnZXQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwcm9taXNlID0gJHRoaXMtPmdldEluc3RhbGxlcigkaW5pdGlhbFR5cGUpLT51bmluc3RhbGwoJHJlcG8sICRpbml0aWFsKTsKICAgICAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICRwcm9taXNlID0gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkdGFyZ2V0VHlwZSk7CiAgICAgICAgICAgICRwcm9taXNlID0gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkaW5zdGFsbGVyLCAkcmVwbywgJHRhcmdldCkgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbnN0YWxsZXItPmluc3RhbGwoJHJlcG8sICR0YXJnZXQpOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFVuaW5zdGFsbHMgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSBVbmluc3RhbGxPcGVyYXRpb24gICAgICAgICAgICRvcGVyYXRpb24gb3BlcmF0aW9uIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBVbmluc3RhbGxPcGVyYXRpb24gJG9wZXJhdGlvbikKICAgIHsKICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkcGFja2FnZS0+Z2V0VHlwZSgpKTsKCiAgICAgICAgcmV0dXJuICRpbnN0YWxsZXItPnVuaW5zdGFsbCgkcmVwbywgJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgbWFya0FsaWFzSW5zdGFsbGVkIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSBNYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb24gICRvcGVyYXRpb24gb3BlcmF0aW9uIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtYXJrQWxpYXNJbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgTWFya0FsaWFzSW5zdGFsbGVkT3BlcmF0aW9uICRvcGVyYXRpb24pCiAgICB7CiAgICAgICAgJHBhY2thZ2UgPSAkb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCk7CgogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICRyZXBvLT5hZGRQYWNrYWdlKGNsb25lICRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyBtYXJrQWxpYXMgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICAkcmVwbyAgICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSBNYXJrQWxpYXNVbmluc3RhbGxlZE9wZXJhdGlvbiAkb3BlcmF0aW9uIG9wZXJhdGlvbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFya0FsaWFzVW5pbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgTWFya0FsaWFzVW5pbnN0YWxsZWRPcGVyYXRpb24gJG9wZXJhdGlvbikKICAgIHsKICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKCiAgICAgICAgJHJlcG8tPnJlbW92ZVBhY2thZ2UoJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5zdGFsbGF0aW9uIHBhdGggb2YgYSBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgICAgcGF0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbFBhdGgoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkcGFja2FnZS0+Z2V0VHlwZSgpKTsKCiAgICAgICAgcmV0dXJuICRpbnN0YWxsZXItPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRvdXRwdXRQcm9ncmVzcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3V0cHV0UHJvZ3Jlc3MoJG91dHB1dFByb2dyZXNzKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXRQcm9ncmVzcyA9ICRvdXRwdXRQcm9ncmVzczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm90aWZ5SW5zdGFsbHMoSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgICRwcm9taXNlcyA9IGFycmF5KCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ub3RpZmlhYmxlUGFja2FnZXMgYXMgJHJlcG9VcmwgPT4gJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAvLyBub24tYmF0Y2ggQVBJLCBkZXByZWNhdGVkCiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRyZXBvVXJsLCAnJXBhY2thZ2UlJykpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHVybCA9IHN0cl9yZXBsYWNlKCclcGFja2FnZSUnLCAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLCAkcmVwb1VybCk7CgogICAgICAgICAgICAgICAgICAgICAgICAkcGFyYW1zID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmVyc2lvbicgPT4gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uX25vcm1hbGl6ZWQnID0+ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICRvcHRzID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncmV0cnktYXV0aC1mYWlsdXJlJyA9PiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdodHRwJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWV0aG9kJyA9PiAnUE9TVCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2hlYWRlcicgPT4gYXJyYXkoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbnRlbnQnID0+IGh0dHBfYnVpbGRfcXVlcnkoJHBhcmFtcywgJycsICcmJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RpbWVvdXQnID0+IDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgJHByb21pc2VzW10gPSAkdGhpcy0+bG9vcC0+Z2V0SHR0cERvd25sb2FkZXIoKS0+YWRkKCR1cmwsICRvcHRzKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRwb3N0RGF0YSA9IGFycmF5KCdkb3dubG9hZHMnID0+IGFycmF5KCkpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VOb3RpZmljYXRpb24gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcGFja2FnZS0+Z2V0VmVyc2lvbigpLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkcmVwb1VybCwgJ3BhY2thZ2lzdC5vcmcvJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldChGaWxlRG93bmxvYWRlcjo6JGRvd25sb2FkTWV0YWRhdGFbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU5vdGlmaWNhdGlvblsnZG93bmxvYWRlZCddID0gRmlsZURvd25sb2FkZXI6OiRkb3dubG9hZE1ldGFkYXRhWyRwYWNrYWdlLT5nZXROYW1lKCldOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VOb3RpZmljYXRpb25bJ2Rvd25sb2FkZWQnXSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRwb3N0RGF0YVsnZG93bmxvYWRzJ11bXSA9ICRwYWNrYWdlTm90aWZpY2F0aW9uOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRvcHRzID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ3JldHJ5LWF1dGgtZmFpbHVyZScgPT4gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgJ2h0dHAnID0+IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnbWV0aG9kJyA9PiAnUE9TVCcsCiAgICAgICAgICAgICAgICAgICAgICAgICdoZWFkZXInID0+IGFycmF5KCdDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb24nKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbnRlbnQnID0+IGpzb25fZW5jb2RlKCRwb3N0RGF0YSksCiAgICAgICAgICAgICAgICAgICAgICAgICd0aW1lb3V0JyA9PiA2LAogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRwcm9taXNlc1tdID0gJHRoaXMtPmxvb3AtPmdldEh0dHBEb3dubG9hZGVyKCktPmFkZCgkcmVwb1VybCwgJG9wdHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+bG9vcC0+d2FpdCgkcHJvbWlzZXMpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yZXNldCgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbWFya0Zvck5vdGlmaWNhdGlvbihQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0Tm90aWZpY2F0aW9uVXJsKCkpIHsKICAgICAgICAgICAgJHRoaXMtPm5vdGlmaWFibGVQYWNrYWdlc1skcGFja2FnZS0+Z2V0Tm90aWZpY2F0aW9uVXJsKCldWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCmNsYXNzIEluc3RhbGxlckV2ZW50cwp7CiAgICAvKioKICAgICAqIFRoZSBQUkVfT1BFUkFUSU9OU19FWEVDIGV2ZW50IG9jY3VycyBiZWZvcmUgdGhlIGxvY2sgZmlsZSBnZXRzCiAgICAgKiBpbnN0YWxsZWQgYW5kIG9wZXJhdGlvbnMgYXJlIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYW4gQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxlckV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9PUEVSQVRJT05TX0VYRUMgPSAncHJlLW9wZXJhdGlvbnMtZXhlYyc7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKLyoqCiAqIFBhY2thZ2UgRXZlbnRzLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBQYWNrYWdlRXZlbnRzCnsKICAgIC8qKgogICAgICogVGhlIFBSRV9QQUNLQUdFX0lOU1RBTEwgZXZlbnQgb2NjdXJzIGJlZm9yZSBhIHBhY2thZ2UgaXMgaW5zdGFsbGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9QQUNLQUdFX0lOU1RBTEwgPSAncHJlLXBhY2thZ2UtaW5zdGFsbCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9QQUNLQUdFX0lOU1RBTEwgZXZlbnQgb2NjdXJzIGFmdGVyIGEgcGFja2FnZSBpcyBpbnN0YWxsZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9QQUNLQUdFX0lOU1RBTEwgPSAncG9zdC1wYWNrYWdlLWluc3RhbGwnOwoKICAgIC8qKgogICAgICogVGhlIFBSRV9QQUNLQUdFX1VQREFURSBldmVudCBvY2N1cnMgYmVmb3JlIGEgcGFja2FnZSBpcyB1cGRhdGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9QQUNLQUdFX1VQREFURSA9ICdwcmUtcGFja2FnZS11cGRhdGUnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfUEFDS0FHRV9VUERBVEUgZXZlbnQgb2NjdXJzIGFmdGVyIGEgcGFja2FnZSBpcyB1cGRhdGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfUEFDS0FHRV9VUERBVEUgPSAncG9zdC1wYWNrYWdlLXVwZGF0ZSc7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX1BBQ0tBR0VfVU5JTlNUQUxMIGV2ZW50IG9jY3VycyBiZWZvcmUgYSBwYWNrYWdlIGhhcyBiZWVuIHVuaW5zdGFsbGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9QQUNLQUdFX1VOSU5TVEFMTCA9ICdwcmUtcGFja2FnZS11bmluc3RhbGwnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfUEFDS0FHRV9VTklOU1RBTEwgZXZlbnQgb2NjdXJzIGFmdGVyIGEgcGFja2FnZSBoYXMgYmVlbiB1bmluc3RhbGxlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX1BBQ0tBR0VfVU5JTlNUQUxMID0gJ3Bvc3QtcGFja2FnZS11bmluc3RhbGwnOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbGZVcGRhdGU7Cgp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXENvbmZpZzsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBWZXJzaW9ucwp7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHVibGljIHN0YXRpYyAkY2hhbm5lbHMgPSBhcnJheSgnc3RhYmxlJywgJ3ByZXZpZXcnLCAnc25hcHNob3QnLCAnMScsICcyJyk7CgogICAgLyoqIEB2YXIgSHR0cERvd25sb2FkZXIgKi8KICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgQ29uZmlnICovCiAgICBwcml2YXRlICRjb25maWc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNoYW5uZWw7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIGFycmF5PGludCwgYXJyYXl7cGF0aDogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIG1pbi1waHA6IGludH0+PiAqLwogICAgcHJpdmF0ZSAkdmVyc2lvbnNEYXRhOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDb25maWcgJGNvbmZpZywgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyKQogICAgewogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFubmVsKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNoYW5uZWwpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jaGFubmVsOwogICAgICAgIH0KCiAgICAgICAgJGNoYW5uZWxGaWxlID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdob21lJykuJy91cGRhdGUtY2hhbm5lbCc7CiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRjaGFubmVsRmlsZSkpIHsKICAgICAgICAgICAgJGNoYW5uZWwgPSB0cmltKGZpbGVfZ2V0X2NvbnRlbnRzKCRjaGFubmVsRmlsZSkpOwogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGNoYW5uZWwsIGFycmF5KCdzdGFibGUnLCAncHJldmlldycsICdzbmFwc2hvdCcpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jaGFubmVsID0gJGNoYW5uZWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Y2hhbm5lbCA9ICdzdGFibGUnOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkY2hhbm5lbAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2hhbm5lbCgkY2hhbm5lbCkKICAgIHsKICAgICAgICBpZiAoIWluX2FycmF5KCRjaGFubmVsLCBzZWxmOjokY2hhbm5lbHMsIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIGNoYW5uZWwgJy4kY2hhbm5lbC4nLCBtdXN0IGJlIG9uZSBvZjogJyAuIGltcGxvZGUoJywgJywgc2VsZjo6JGNoYW5uZWxzKSk7CiAgICAgICAgfQoKICAgICAgICAkY2hhbm5lbEZpbGUgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2hvbWUnKS4nL3VwZGF0ZS1jaGFubmVsJzsKICAgICAgICAkdGhpcy0+Y2hhbm5lbCA9ICRjaGFubmVsOwogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRjaGFubmVsRmlsZSwgKGlzX251bWVyaWMoJGNoYW5uZWwpID8gJ3N0YWJsZScgOiAkY2hhbm5lbCkuUEhQX0VPTCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGNoYW5uZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e3BhdGg6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBtaW4tcGhwOiBpbnR9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMYXRlc3QoJGNoYW5uZWwgPSBudWxsKQogICAgewogICAgICAgICR2ZXJzaW9ucyA9ICR0aGlzLT5nZXRWZXJzaW9uc0RhdGEoKTsKCiAgICAgICAgZm9yZWFjaCAoJHZlcnNpb25zWyRjaGFubmVsID86ICR0aGlzLT5nZXRDaGFubmVsKCldIGFzICR2ZXJzaW9uKSB7CiAgICAgICAgICAgIGlmICgkdmVyc2lvblsnbWluLXBocCddIDw9IFBIUF9WRVJTSU9OX0lEKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZlcnNpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdUaGVyZSBpcyBubyB2ZXJzaW9uIG9mIENvbXBvc2VyIGF2YWlsYWJsZSBmb3IgeW91ciBQSFAgdmVyc2lvbiAoJy5QSFBfVkVSU0lPTi4nKScpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIGFycmF5PGludCwgYXJyYXl7cGF0aDogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIG1pbi1waHA6IGludH0+PgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFZlcnNpb25zRGF0YSgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+dmVyc2lvbnNEYXRhKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+Y29uZmlnLT5nZXQoJ2Rpc2FibGUtdGxzJykgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICRwcm90b2NvbCA9ICdodHRwJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcm90b2NvbCA9ICdodHRwcyc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT52ZXJzaW9uc0RhdGEgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkcHJvdG9jb2wgLiAnOi8vZ2V0Y29tcG9zZXIub3JnL3ZlcnNpb25zJyktPmRlY29kZUpzb24oKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvbnNEYXRhOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbGZVcGRhdGU7Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEtleXMKewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmaW5nZXJwcmludCgkcGF0aCkKICAgIHsKICAgICAgICAkaGFzaCA9IHN0cnRvdXBwZXIoaGFzaCgnc2hhMjU2JywgUHJlZzo6cmVwbGFjZSgne1xzfScsICcnLCBmaWxlX2dldF9jb250ZW50cygkcGF0aCkpKSk7CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcgJywgYXJyYXkoCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgMCwgOCksCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgOCwgOCksCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgMTYsIDgpLAogICAgICAgICAgICBzdWJzdHIoJGhhc2gsIDI0LCA4KSwKICAgICAgICAgICAgJycsIC8vIEV4dHJhIHNwYWNlCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgMzIsIDgpLAogICAgICAgICAgICBzdWJzdHIoJGhhc2gsIDQwLCA4KSwKICAgICAgICAgICAgc3Vic3RyKCRoYXNoLCA0OCwgOCksCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgNTYsIDgpLAogICAgICAgICkpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNYXRjaEFsbENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNdWx0aUNvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcSW50ZXJ2YWw7CnVzZSBDb21wb3NlclxTZW12ZXJcSW50ZXJ2YWxzOwoKZmluYWwgY2xhc3MgSWdub3JlTGlzdFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIgaW1wbGVtZW50cyBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkaWdub3JlUmVnZXg7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcml2YXRlICRpZ25vcmVVcHBlckJvdW5kUmVnZXg7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHJlcUxpc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRyZXFMaXN0KQogICAgewogICAgICAgICRpZ25vcmVBbGwgPSAkaWdub3JlVXBwZXJCb3VuZCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcUxpc3QgYXMgJHJlcSkgewogICAgICAgICAgICBpZiAoc3Vic3RyKCRyZXEsIC0xKSA9PT0gJysnKSB7CiAgICAgICAgICAgICAgICAkaWdub3JlVXBwZXJCb3VuZFtdID0gc3Vic3RyKCRyZXEsIDAsIC0xKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpZ25vcmVBbGxbXSA9ICRyZXE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRoaXMtPmlnbm9yZVJlZ2V4ID0gQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lc1RvUmVnZXhwKCRpZ25vcmVBbGwpOwogICAgICAgICR0aGlzLT5pZ25vcmVVcHBlckJvdW5kUmVnZXggPSBCYXNlUGFja2FnZTo6cGFja2FnZU5hbWVzVG9SZWdleHAoJGlnbm9yZVVwcGVyQm91bmQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVxCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSWdub3JlZCgkcmVxKQogICAgewogICAgICAgIGlmICghUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcmVxKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gUHJlZzo6aXNNYXRjaCgkdGhpcy0+aWdub3JlUmVnZXgsICRyZXEpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVxCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbHRlckNvbnN0cmFpbnQoJHJlcSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBpZiAoIVBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcSkpIHsKICAgICAgICAgICAgcmV0dXJuICRjb25zdHJhaW50OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCR0aGlzLT5pZ25vcmVVcHBlckJvdW5kUmVnZXgsICRyZXEpKSB7CiAgICAgICAgICAgIHJldHVybiAkY29uc3RyYWludDsKICAgICAgICB9CgogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCR0aGlzLT5pZ25vcmVSZWdleCwgJHJlcSkpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRjaEFsbENvbnN0cmFpbnQ7CiAgICAgICAgfQoKICAgICAgICAkaW50ZXJ2YWxzID0gSW50ZXJ2YWxzOjpnZXQoJGNvbnN0cmFpbnQpOwogICAgICAgICRsYXN0ID0gZW5kKCRpbnRlcnZhbHNbJ251bWVyaWMnXSk7CiAgICAgICAgaWYgKCRsYXN0ICE9PSBmYWxzZSAmJiAoc3RyaW5nKSAkbGFzdC0+Z2V0RW5kKCkgIT09IChzdHJpbmcpIEludGVydmFsOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9IG5ldyBNdWx0aUNvbnN0cmFpbnQoYXJyYXkoJGNvbnN0cmFpbnQsIG5ldyBDb25zdHJhaW50KCc+PScsICRsYXN0LT5nZXRFbmQoKS0+Z2V0VmVyc2lvbigpKSksIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29uc3RyYWludDsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyOwoKZmluYWwgY2xhc3MgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3RvcnkKewogICAgLyoqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGJvb2xPckxpc3QKICAgICAqCiAgICAgKiBAcmV0dXJuIFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tQm9vbE9yTGlzdCgkYm9vbE9yTGlzdCkKICAgIHsKICAgICAgICBpZiAoaXNfYm9vbCgkYm9vbE9yTGlzdCkpIHsKICAgICAgICAgICAgcmV0dXJuICRib29sT3JMaXN0ID8gc2VsZjo6aWdub3JlQWxsKCkgOiBzZWxmOjppZ25vcmVOb3RoaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfYXJyYXkoJGJvb2xPckxpc3QpKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgSWdub3JlTGlzdFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoJGJvb2xPckxpc3QpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgIHNwcmludGYoCiAgICAgICAgICAgICAgICAnUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcjogVW5rbm93biAkYm9vbE9yTGlzdCBwYXJhbWV0ZXIgJXMuIFBsZWFzZSByZXBvcnQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy9uZXcuJywKICAgICAgICAgICAgICAgIGdldHR5cGUoJGJvb2xPckxpc3QpCiAgICAgICAgICAgICkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaWdub3JlQWxsKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IElnbm9yZUFsbFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlnbm9yZU5vdGhpbmcoKQogICAgewogICAgICAgIHJldHVybiBuZXcgSWdub3JlTm90aGluZ1BsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyOwoKaW50ZXJmYWNlIFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXEKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJZ25vcmVkKCRyZXEpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CgpmaW5hbCBjbGFzcyBJZ25vcmVOb3RoaW5nUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbXBsZW1lbnRzIFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXEKICAgICAqIEByZXR1cm4gZmFsc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSWdub3JlZCgkcmVxKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5OwoKZmluYWwgY2xhc3MgSWdub3JlQWxsUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbXBsZW1lbnRzIFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXEKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJZ25vcmVkKCRyZXEpCiAgICB7CiAgICAgICAgcmV0dXJuIFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFNjcmlwdEV4ZWN1dGlvbkV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXI7CgovKioKICogVGhlIGJhc2UgZXZlbnQgY2xhc3MKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcgVGhpcyBldmVudCdzIG5hbWUKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmdbXSBBcmd1bWVudHMgcGFzc2VkIGJ5IHRoZSB1c2VyLCB0aGVzZSB3aWxsIGJlIGZvcndhcmRlZCB0byBDTEkgc2NyaXB0IGhhbmRsZXJzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJnczsKCiAgICAvKioKICAgICAqIEB2YXIgbWl4ZWRbXSBGbGFncyB1c2FibGUgaW4gUEhQIHNjcmlwdCBoYW5kbGVycwogICAgICovCiAgICBwcm90ZWN0ZWQgJGZsYWdzOwoKICAgIC8qKgogICAgICogQHZhciBib29sIFdoZXRoZXIgdGhlIGV2ZW50IHNob3VsZCBub3QgYmUgcGFzc2VkIHRvIG1vcmUgbGlzdGVuZXJzCiAgICAgKi8KICAgIHByaXZhdGUgJHByb3BhZ2F0aW9uU3RvcHBlZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRuYW1lICBUaGUgZXZlbnQgbmFtZQogICAgICogQHBhcmFtIHN0cmluZ1tdICRhcmdzICBBcmd1bWVudHMgcGFzc2VkIGJ5IHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgJGZsYWdzIE9wdGlvbmFsIGZsYWdzIHRvIHBhc3MgZGF0YSBub3QgYXMgYXJndW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCBhcnJheSAkYXJncyA9IGFycmF5KCksIGFycmF5ICRmbGFncyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWUgPSAkbmFtZTsKICAgICAgICAkdGhpcy0+YXJncyA9ICRhcmdzOwogICAgICAgICR0aGlzLT5mbGFncyA9ICRmbGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV2ZW50J3MgbmFtZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZXZlbnQgbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXZlbnQncyBhcmd1bWVudHMuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXSBUaGUgZXZlbnQgYXJndW1lbnRzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJnczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV2ZW50J3MgZmxhZ3MuCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZFtdIFRoZSBldmVudCBmbGFncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmxhZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmxhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc3RvcFByb3BhZ2F0aW9uIGhhcyBiZWVuIGNhbGxlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHByb3BhZ2F0aW9uIGhhcyBiZWVuIHN0b3BwZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUHJvcGFnYXRpb25TdG9wcGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb3BhZ2F0aW9uU3RvcHBlZDsKICAgIH0KCiAgICAvKioKICAgICAqIFByZXZlbnRzIHRoZSBldmVudCBmcm9tIGJlaW5nIHBhc3NlZCB0byBmdXJ0aGVyIGxpc3RlbmVycwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXI7CgovKioKICogQW4gRXZlbnRTdWJzY3JpYmVyIGtub3dzIHdoaWNoIGV2ZW50cyBpdCBpcyBpbnRlcmVzdGVkIGluLgogKgogKiBJZiBhbiBFdmVudFN1YnNjcmliZXIgaXMgYWRkZWQgdG8gYW4gRXZlbnREaXNwYXRjaGVyLCB0aGUgbWFuYWdlciBpbnZva2VzCiAqIHtAbGluayBnZXRTdWJzY3JpYmVkRXZlbnRzfSBhbmQgcmVnaXN0ZXJzIHRoZSBzdWJzY3JpYmVyIGFzIGEgbGlzdGVuZXIgZm9yIGFsbAogKiByZXR1cm5lZCBldmVudHMuCiAqCiAqIEBhdXRob3IgR3VpbGhlcm1lIEJsYW5jbyA8Z3VpbGhlcm1lYmxhbmNvQGhvdG1haWwuY29tPgogKiBAYXV0aG9yIEpvbmF0aGFuIFdhZ2UgPGpvbndhZ2VAZ21haWwuY29tPgogKiBAYXV0aG9yIFJvbWFuIEJvcnNjaGVsIDxyb21hbkBjb2RlLWZhY3Rvcnkub3JnPgogKiBAYXV0aG9yIEJlcm5oYXJkIFNjaHVzc2VrIDxic2NodXNzZWtAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIEV2ZW50U3Vic2NyaWJlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdGhpcyBzdWJzY3JpYmVyIHdhbnRzIHRvIGxpc3RlbiB0by4KICAgICAqCiAgICAgKiBUaGUgYXJyYXkga2V5cyBhcmUgZXZlbnQgbmFtZXMgYW5kIHRoZSB2YWx1ZSBjYW4gYmU6CiAgICAgKgogICAgICogKiBUaGUgbWV0aG9kIG5hbWUgdG8gY2FsbCAocHJpb3JpdHkgZGVmYXVsdHMgdG8gMCkKICAgICAqICogQW4gYXJyYXkgY29tcG9zZWQgb2YgdGhlIG1ldGhvZCBuYW1lIHRvIGNhbGwgYW5kIHRoZSBwcmlvcml0eQogICAgICogKiBBbiBhcnJheSBvZiBhcnJheXMgY29tcG9zZWQgb2YgdGhlIG1ldGhvZCBuYW1lcyB0byBjYWxsIGFuZCByZXNwZWN0aXZlCiAgICAgKiAgIHByaW9yaXRpZXMsIG9yIDAgaWYgdW5zZXQKICAgICAqCiAgICAgKiBGb3IgaW5zdGFuY2U6CiAgICAgKgogICAgICogKiBhcnJheSgnZXZlbnROYW1lJyA9PiAnbWV0aG9kTmFtZScpCiAgICAgKiAqIGFycmF5KCdldmVudE5hbWUnID0+IGFycmF5KCdtZXRob2ROYW1lJywgJHByaW9yaXR5KSkKICAgICAqICogYXJyYXkoJ2V2ZW50TmFtZScgPT4gYXJyYXkoYXJyYXkoJ21ldGhvZE5hbWUxJywgJHByaW9yaXR5KSwgYXJyYXkoJ21ldGhvZE5hbWUyJykpCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZ3xhcnJheXswOiBzdHJpbmcsIDE/OiBpbnR9fGFycmF5PGFycmF5ezA6IHN0cmluZywgMT86IGludH0+PiBUaGUgZXZlbnQgbmFtZXMgdG8gbGlzdGVuIHRvCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0U3Vic2NyaWJlZEV2ZW50cygpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlcjsKCnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcVHJhbnNhY3Rpb247CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGVyRXZlbnQ7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cT3BlcmF0aW9uSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2NyaXB0Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudDsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxCaW5hcnlJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFNjcmlwdFxFdmVudCBhcyBTY3JpcHRFdmVudDsKdXNlIENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaHBFeGVjdXRhYmxlRmluZGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGVjdXRhYmxlRmluZGVyOwoKLyoqCiAqIFRoZSBFdmVudCBEaXNwYXRjaGVyLgogKgogKiBFeGFtcGxlIGluIGNvbW1hbmQ6CiAqICAgICAkZGlzcGF0Y2hlciA9IG5ldyBFdmVudERpc3BhdGNoZXIoJHRoaXMtPmdldENvbXBvc2VyKCksICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5nZXRJTygpKTsKICogICAgIC8vIC4uLgogKiAgICAgJGRpc3BhdGNoZXItPmRpc3BhdGNoKFNjcmlwdEV2ZW50czo6UE9TVF9JTlNUQUxMX0NNRCk7CiAqICAgICAvLyAuLi4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgRXZlbnREaXNwYXRjaGVyCnsKICAgIC8qKiBAdmFyIENvbXBvc2VyICovCiAgICBwcm90ZWN0ZWQgJGNvbXBvc2VyOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciA/Q2xhc3NMb2FkZXIgKi8KICAgIHByb3RlY3RlZCAkbG9hZGVyOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcm90ZWN0ZWQgJHByb2Nlc3M7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIGFycmF5PGludCwgYXJyYXk8Y2FsbGFibGV8c3RyaW5nPj4+ICovCiAgICBwcm90ZWN0ZWQgJGxpc3RlbmVycyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJHJ1blNjcmlwdHMgPSB0cnVlOwogICAgLyoqIEB2YXIgbGlzdDxzdHJpbmc+ICovCiAgICBwcml2YXRlICRldmVudFN0YWNrOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIENvbXBvc2VyICAgICAgICAkY29tcG9zZXIgVGhlIGNvbXBvc2VyIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICBUaGUgSU9JbnRlcmZhY2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENvbXBvc2VyICRjb21wb3NlciwgSU9JbnRlcmZhY2UgJGlvLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzcyA/OiBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPmV2ZW50U3RhY2sgPSBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHdoZXRoZXIgc2NyaXB0IGhhbmRsZXJzIGFyZSBhY3RpdmUgb3Igbm90CiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHJ1blNjcmlwdHMKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJ1blNjcmlwdHMoJHJ1blNjcmlwdHMgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5ydW5TY3JpcHRzID0gKGJvb2wpICRydW5TY3JpcHRzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwYXRjaCBhbiBldmVudAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRldmVudE5hbWUgQW4gZXZlbnQgbmFtZQogICAgICogQHBhcmFtICBFdmVudCAgJGV2ZW50CiAgICAgKiBAcmV0dXJuIGludCAgICByZXR1cm4gY29kZSBvZiB0aGUgZXhlY3V0ZWQgc2NyaXB0IGlmIGFueSwgZm9yIHBocCBzY3JpcHRzIGEgZmFsc2UgcmV0dXJuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgaXMgY2hhbmdlZCB0byAxLCBhbnl0aGluZyBlbHNlIHRvIDAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoKCRldmVudE5hbWUsIEV2ZW50ICRldmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRldmVudCkgewogICAgICAgICAgICAkZXZlbnQgPSBuZXcgRXZlbnQoJGV2ZW50TmFtZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmRvRGlzcGF0Y2goJGV2ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIERpc3BhdGNoIGEgc2NyaXB0IGV2ZW50LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgJGV2ZW50TmFtZSAgICAgIFRoZSBjb25zdGFudCBpbiBTY3JpcHRFdmVudHMKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgJGRldk1vZGUKICAgICAqIEBwYXJhbSAgYXJyYXk8aW50LCBtaXhlZD4gICAgJGFkZGl0aW9uYWxBcmdzIEFyZ3VtZW50cyBwYXNzZWQgYnkgdGhlIHVzZXIKICAgICAqIEBwYXJhbSAgYXJyYXk8c3RyaW5nLCBtaXhlZD4gJGZsYWdzICAgICAgICAgIE9wdGlvbmFsIGZsYWdzIHRvIHBhc3MgZGF0YSBub3QgYXMgYXJndW1lbnQKICAgICAqIEByZXR1cm4gaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2RlIG9mIHRoZSBleGVjdXRlZCBzY3JpcHQgaWYgYW55LCBmb3IgcGhwIHNjcmlwdHMgYSBmYWxzZSByZXR1cm4KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIGlzIGNoYW5nZWQgdG8gMSwgYW55dGhpbmcgZWxzZSB0byAwCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNwYXRjaFNjcmlwdCgkZXZlbnROYW1lLCAkZGV2TW9kZSA9IGZhbHNlLCAkYWRkaXRpb25hbEFyZ3MgPSBhcnJheSgpLCAkZmxhZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZG9EaXNwYXRjaChuZXcgU2NyaXB0XEV2ZW50KCRldmVudE5hbWUsICR0aGlzLT5jb21wb3NlciwgJHRoaXMtPmlvLCAkZGV2TW9kZSwgJGFkZGl0aW9uYWxBcmdzLCAkZmxhZ3MpKTsKICAgIH0KCiAgICAvKioKICAgICAqIERpc3BhdGNoIGEgcGFja2FnZSBldmVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJGV2ZW50TmFtZSAgVGhlIGNvbnN0YW50IGluIFBhY2thZ2VFdmVudHMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAkZGV2TW9kZSAgICBXaGV0aGVyIG9yIG5vdCB3ZSBhcmUgaW4gZGV2IG1vZGUKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICAkbG9jYWxSZXBvICBUaGUgaW5zdGFsbGVkIHJlcG9zaXRvcnkKICAgICAqIEBwYXJhbSBPcGVyYXRpb25JbnRlcmZhY2VbXSAkb3BlcmF0aW9ucyBUaGUgbGlzdCBvZiBvcGVyYXRpb25zCiAgICAgKiBAcGFyYW0gT3BlcmF0aW9uSW50ZXJmYWNlICAgJG9wZXJhdGlvbiAgVGhlIHBhY2thZ2UgYmVpbmcgaW5zdGFsbGVkL3VwZGF0ZWQvcmVtb3ZlZAogICAgICoKICAgICAqIEByZXR1cm4gaW50IHJldHVybiBjb2RlIG9mIHRoZSBleGVjdXRlZCBzY3JpcHQgaWYgYW55LCBmb3IgcGhwIHNjcmlwdHMgYSBmYWxzZSByZXR1cm4KICAgICAqICAgICAgICAgICAgIHZhbHVlIGlzIGNoYW5nZWQgdG8gMSwgYW55dGhpbmcgZWxzZSB0byAwCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNwYXRjaFBhY2thZ2VFdmVudCgkZXZlbnROYW1lLCAkZGV2TW9kZSwgUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvLCBhcnJheSAkb3BlcmF0aW9ucywgT3BlcmF0aW9uSW50ZXJmYWNlICRvcGVyYXRpb24pCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kb0Rpc3BhdGNoKG5ldyBQYWNrYWdlRXZlbnQoJGV2ZW50TmFtZSwgJHRoaXMtPmNvbXBvc2VyLCAkdGhpcy0+aW8sICRkZXZNb2RlLCAkbG9jYWxSZXBvLCAkb3BlcmF0aW9ucywgJG9wZXJhdGlvbikpOwogICAgfQoKICAgIC8qKgogICAgICogRGlzcGF0Y2ggYSBpbnN0YWxsZXIgZXZlbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRldmVudE5hbWUgICAgICAgICBUaGUgY29uc3RhbnQgaW4gSW5zdGFsbGVyRXZlbnRzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGRldk1vZGUgICAgICAgICAgIFdoZXRoZXIgb3Igbm90IHdlIGFyZSBpbiBkZXYgbW9kZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRleGVjdXRlT3BlcmF0aW9ucyBUcnVlIGlmIG9wZXJhdGlvbnMgd2lsbCBiZSBleGVjdXRlZCwgZmFsc2UgaW4gLS1kcnktcnVuCiAgICAgKiBAcGFyYW0gVHJhbnNhY3Rpb24gJHRyYW5zYWN0aW9uICAgICAgIFRoZSB0cmFuc2FjdGlvbiBjb250YWlucyB0aGUgbGlzdCBvZiBvcGVyYXRpb25zCiAgICAgKgogICAgICogQHJldHVybiBpbnQgcmV0dXJuIGNvZGUgb2YgdGhlIGV4ZWN1dGVkIHNjcmlwdCBpZiBhbnksIGZvciBwaHAgc2NyaXB0cyBhIGZhbHNlIHJldHVybgogICAgICogICAgICAgICAgICAgdmFsdWUgaXMgY2hhbmdlZCB0byAxLCBhbnl0aGluZyBlbHNlIHRvIDAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoSW5zdGFsbGVyRXZlbnQoJGV2ZW50TmFtZSwgJGRldk1vZGUsICRleGVjdXRlT3BlcmF0aW9ucywgVHJhbnNhY3Rpb24gJHRyYW5zYWN0aW9uKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZG9EaXNwYXRjaChuZXcgSW5zdGFsbGVyRXZlbnQoJGV2ZW50TmFtZSwgJHRoaXMtPmNvbXBvc2VyLCAkdGhpcy0+aW8sICRkZXZNb2RlLCAkZXhlY3V0ZU9wZXJhdGlvbnMsICR0cmFuc2FjdGlvbikpOwogICAgfQoKICAgIC8qKgogICAgICogVHJpZ2dlcnMgdGhlIGxpc3RlbmVycyBvZiBhbiBldmVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gIEV2ZW50ICAgICAgICAgICAgICAgICAgICAgICAgJGV2ZW50IFRoZSBldmVudCBvYmplY3QgdG8gcGFzcyB0byB0aGUgZXZlbnQgaGFuZGxlcnMvbGlzdGVuZXJzLgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbnxcRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvZGUgb2YgdGhlIGV4ZWN1dGVkIHNjcmlwdCBpZiBhbnksIGZvciBwaHAgc2NyaXB0cyBhIGZhbHNlIHJldHVybgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIGlzIGNoYW5nZWQgdG8gMSwgYW55dGhpbmcgZWxzZSB0byAwCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0Rpc3BhdGNoKEV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICBpZiAoUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfREVCVUdfRVZFTlRTJykpIHsKICAgICAgICAgICAgJGRldGFpbHMgPSBudWxsOwogICAgICAgICAgICBpZiAoJGV2ZW50IGluc3RhbmNlb2YgUGFja2FnZUV2ZW50KSB7CiAgICAgICAgICAgICAgICAkZGV0YWlscyA9IChzdHJpbmcpICRldmVudC0+Z2V0T3BlcmF0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdEaXNwYXRjaGluZyA8aW5mbz4nLiRldmVudC0+Z2V0TmFtZSgpLic8L2luZm8+Jy4oJGRldGFpbHMgPyAnICgnLiRkZXRhaWxzLicpJyA6ICcnKS4nIGV2ZW50Jyk7CiAgICAgICAgfQoKICAgICAgICAkbGlzdGVuZXJzID0gJHRoaXMtPmdldExpc3RlbmVycygkZXZlbnQpOwoKICAgICAgICAkdGhpcy0+cHVzaEV2ZW50KCRldmVudCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRyZXR1cm5NYXggPSAwOwogICAgICAgICAgICBmb3JlYWNoICgkbGlzdGVuZXJzIGFzICRjYWxsYWJsZSkgewogICAgICAgICAgICAgICAgJHJldHVybiA9IDA7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZW5zdXJlQmluRGlySXNJblBhdGgoKTsKCiAgICAgICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkY2FsbGFibGUpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19jYWxsYWJsZSgkY2FsbGFibGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjbGFzc05hbWUgPSBpc19vYmplY3QoJGNhbGxhYmxlWzBdKSA/IGdldF9jbGFzcygkY2FsbGFibGVbMF0pIDogJGNhbGxhYmxlWzBdOwoKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdTdWJzY3JpYmVyICcuJGNsYXNzTmFtZS4nOjonLiRjYWxsYWJsZVsxXS4nIGZvciBldmVudCAnLiRldmVudC0+Z2V0TmFtZSgpLicgaXMgbm90IGNhbGxhYmxlLCBtYWtlIHN1cmUgdGhlIGZ1bmN0aW9uIGlzIGRlZmluZWQgYW5kIHB1YmxpYycpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJGNhbGxhYmxlKSAmJiAoaXNfc3RyaW5nKCRjYWxsYWJsZVswXSkgfHwgaXNfb2JqZWN0KCRjYWxsYWJsZVswXSkpICYmIGlzX3N0cmluZygkY2FsbGFibGVbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc+ICVzOiAlcycsICRldmVudC0+Z2V0TmFtZSgpLCAoaXNfb2JqZWN0KCRjYWxsYWJsZVswXSkgPyBnZXRfY2xhc3MoJGNhbGxhYmxlWzBdKSA6ICRjYWxsYWJsZVswXSkuJy0+Jy4kY2FsbGFibGVbMV0pLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRyZXR1cm4gPSBmYWxzZSA9PT0gY2FsbF91c2VyX2Z1bmMoJGNhbGxhYmxlLCAkZXZlbnQpID8gMSA6IDA7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlzQ29tcG9zZXJTY3JpcHQoJGNhbGxhYmxlKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc+ICVzOiAlcycsICRldmVudC0+Z2V0TmFtZSgpLCAkY2FsbGFibGUpLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CgogICAgICAgICAgICAgICAgICAgICRzY3JpcHQgPSBleHBsb2RlKCcgJywgc3Vic3RyKCRjYWxsYWJsZSwgMSkpOwogICAgICAgICAgICAgICAgICAgICRzY3JpcHROYW1lID0gJHNjcmlwdFswXTsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkc2NyaXB0WzBdKTsKCiAgICAgICAgICAgICAgICAgICAgJGFyZ3MgPSBhcnJheV9tZXJnZSgkc2NyaXB0LCAkZXZlbnQtPmdldEFyZ3VtZW50cygpKTsKICAgICAgICAgICAgICAgICAgICAkZmxhZ3MgPSAkZXZlbnQtPmdldEZsYWdzKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkY2FsbGFibGUsICdAY29tcG9zZXIgJykgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGV4ZWMgPSAkdGhpcy0+Z2V0UGhwRXhlY0NvbW1hbmQoKSAuICcgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX0JJTkFSWScpKSAuICcgJyAuIGltcGxvZGUoJyAnLCAkYXJncyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwICE9PSAoJGV4aXRDb2RlID0gJHRoaXMtPmV4ZWN1dGVUdHkoJGV4ZWMpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJzxlcnJvcj5TY3JpcHQgJXMgaGFuZGxpbmcgdGhlICVzIGV2ZW50IHJldHVybmVkIHdpdGggZXJyb3IgY29kZSAnLiRleGl0Q29kZS4nPC9lcnJvcj4nLCAkY2FsbGFibGUsICRldmVudC0+Z2V0TmFtZSgpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NyaXB0RXhlY3V0aW9uRXhjZXB0aW9uKCdFcnJvciBPdXRwdXQ6ICcuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICRleGl0Q29kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRMaXN0ZW5lcnMobmV3IEV2ZW50KCRzY3JpcHROYW1lKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8d2FybmluZz5Zb3UgbWFkZSBhIHJlZmVyZW5jZSB0byBhIG5vbi1leGlzdGVudCBzY3JpcHQgJXM8L3dhcm5pbmc+JywgJGNhbGxhYmxlKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qKiBAdmFyIEluc3RhbGxlckV2ZW50ICRldmVudCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNjcmlwdEV2ZW50ID0gbmV3IFNjcmlwdFxFdmVudCgkc2NyaXB0TmFtZSwgJGV2ZW50LT5nZXRDb21wb3NlcigpLCAkZXZlbnQtPmdldElPKCksICRldmVudC0+aXNEZXZNb2RlKCksICRhcmdzLCAkZmxhZ3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNjcmlwdEV2ZW50LT5zZXRPcmlnaW5hdGluZ0V2ZW50KCRldmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmV0dXJuID0gJHRoaXMtPmRpc3BhdGNoKCRzY3JpcHROYW1lLCAkc2NyaXB0RXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTY3JpcHRFeGVjdXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+U2NyaXB0ICVzIHdhcyBjYWxsZWQgdmlhICVzPC9lcnJvcj4nLCAkY2FsbGFibGUsICRldmVudC0+Z2V0TmFtZSgpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5pc1BocFNjcmlwdCgkY2FsbGFibGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNsYXNzTmFtZSA9IHN1YnN0cigkY2FsbGFibGUsIDAsIHN0cnBvcygkY2FsbGFibGUsICc6OicpKTsKICAgICAgICAgICAgICAgICAgICAkbWV0aG9kTmFtZSA9IHN1YnN0cigkY2FsbGFibGUsIHN0cnBvcygkY2FsbGFibGUsICc6OicpICsgMik7CgogICAgICAgICAgICAgICAgICAgIGlmICghY2xhc3NfZXhpc3RzKCRjbGFzc05hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Q2xhc3MgJy4kY2xhc3NOYW1lLicgaXMgbm90IGF1dG9sb2FkYWJsZSwgY2FuIG5vdCBjYWxsICcuJGV2ZW50LT5nZXROYW1lKCkuJyBzY3JpcHQ8L3dhcm5pbmc+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghaXNfY2FsbGFibGUoJGNhbGxhYmxlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPk1ldGhvZCAnLiRjYWxsYWJsZS4nIGlzIG5vdCBjYWxsYWJsZSwgY2FuIG5vdCBjYWxsICcuJGV2ZW50LT5nZXROYW1lKCkuJyBzY3JpcHQ8L3dhcm5pbmc+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmV0dXJuID0gZmFsc2UgPT09ICR0aGlzLT5leGVjdXRlRXZlbnRQaHBTY3JpcHQoJGNsYXNzTmFtZSwgJG1ldGhvZE5hbWUsICRldmVudCkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIlNjcmlwdCAlcyBoYW5kbGluZyB0aGUgJXMgZXZlbnQgdGVybWluYXRlZCB3aXRoIGFuIGV4Y2VwdGlvbiI7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPicuc3ByaW50ZigkbWVzc2FnZSwgJGNhbGxhYmxlLCAkZXZlbnQtPmdldE5hbWUoKSkuJzwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkYXJncyA9IGltcGxvZGUoJyAnLCBhcnJheV9tYXAoYXJyYXkoJ0NvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yJywgJ2VzY2FwZScpLCAkZXZlbnQtPmdldEFyZ3VtZW50cygpKSk7CiAgICAgICAgICAgICAgICAgICAgJGV4ZWMgPSAkY2FsbGFibGUgLiAoJGFyZ3MgPT09ICcnID8gJycgOiAnICcuJGFyZ3MpOwogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aW8tPmlzVmVyYm9zZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc+ICVzOiAlcycsICRldmVudC0+Z2V0TmFtZSgpLCAkZXhlYykpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkZXZlbnQtPmdldE5hbWUoKSAhPT0gJ19fZXhlY19jb21tYW5kJykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3Qgb3V0cHV0IHRoZSBjb21tYW5kIGJlaW5nIHJ1biB3aGVuIHVzaW5nIGBjb21wb3NlciBleGVjYCBhcyBpdCBpcyBmYWlybHkgb2J2aW91cyB0aGUgdXNlciBpcyBydW5uaW5nIGl0CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc+ICVzJywgJGV4ZWMpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRwb3NzaWJsZUxvY2FsQmluYXJpZXMgPSAkdGhpcy0+Y29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0QmluYXJpZXMoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBvc3NpYmxlTG9jYWxCaW5hcmllcykgewogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG9zc2libGVMb2NhbEJpbmFyaWVzIGFzICRsb2NhbEV4ZWMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XGInLnByZWdfcXVvdGUoJGNhbGxhYmxlKS4nJH0nLCAkbG9jYWxFeGVjKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYWxsZXIgPSBCaW5hcnlJbnN0YWxsZXI6OmRldGVybWluZUJpbmFyeUNhbGxlcigkbG9jYWxFeGVjKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXhlYyA9IFByZWc6OnJlcGxhY2UoJ3teJy5wcmVnX3F1b3RlKCRjYWxsYWJsZSkuJ30nLCAkY2FsbGVyIC4gJyAnIC4gJGxvY2FsRXhlYywgJGV4ZWMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRleGVjLCAnQHB1dGVudiAnKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkZXhlYywgJz0nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgUGxhdGZvcm06OmNsZWFyRW52KHN1YnN0cigkZXhlYywgOCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgkdmFyLCAkdmFsdWUpID0gZXhwbG9kZSgnPScsIHN1YnN0cigkZXhlYywgOCksIDIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgUGxhdGZvcm06OnB1dEVudigkdmFyLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkZXhlYywgJ0BwaHAgJykgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGhBbmRBcmdzID0gc3Vic3RyKCRleGVjLCA1KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGhBbmRBcmdzID0gUHJlZzo6cmVwbGFjZUNhbGxiYWNrKCd7XlxTK30nLCBmdW5jdGlvbiAoJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJy8nLCAnXFwnLCAkcGF0aFswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAkcGF0aEFuZEFyZ3MpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hdGNoIHNvbWVuYW1lIChub3QgaW4gcXVvdGUsIGFuZCBub3QgYSBxdWFsaWZpZWQgcGF0aCkgYW5kIGlmIGl0IGlzIG5vdCBhIHZhbGlkIHBhdGggZnJvbSBDV0QgdGhlbiB0cnkgdG8gZmluZCBpdAogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiAkUEFUSC4gVGhpcyBhbGxvd3Mgc3VwcG9ydCBmb3IgYEBwaHAgZm9vYCB3aGVyZSBmb28gaXMgYSBiaW5hcnkgbmFtZSBmb3VuZCBpbiBQQVRIIGJ1dCBub3QgYW4gYWN0dWFsIHJlbGF0aXZlIHBhdGgKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoZWQgPSBQcmVnOjppc01hdGNoKCd7XlteXCciXHMvXFxcXF0rfScsICRwYXRoQW5kQXJncywgJG1hdGNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRtYXRjaGVkICYmICFmaWxlX2V4aXN0cygkbWF0Y2hbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZmluZGVyID0gbmV3IEV4ZWN1dGFibGVGaW5kZXI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBhdGhUb0V4ZWMgPSAkZmluZGVyLT5maW5kKCRtYXRjaFswXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aEFuZEFyZ3MgPSAkcGF0aFRvRXhlYyAuIHN1YnN0cigkcGF0aEFuZEFyZ3MsIHN0cmxlbigkbWF0Y2hbMF0pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkZXhlYyA9ICR0aGlzLT5nZXRQaHBFeGVjQ29tbWFuZCgpIC4gJyAnIC4gJHBhdGhBbmRBcmdzOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmaW5kZXIgPSBuZXcgUGhwRXhlY3V0YWJsZUZpbmRlcigpOwogICAgICAgICAgICAgICAgICAgICAgICAkcGhwUGF0aCA9ICRmaW5kZXItPmZpbmQoZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBocFBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBsYXRmb3JtOjpwdXRFbnYoJ1BIUF9CSU5BUlknLCAkcGhwUGF0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRleGVjID0gUHJlZzo6cmVwbGFjZUNhbGxiYWNrKCd7XlxTK30nLCBmdW5jdGlvbiAoJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJy8nLCAnXFwnLCAkcGF0aFswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAkZXhlYyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGlmIGNvbXBvc2VyIGlzIGJlaW5nIGV4ZWN1dGVkLCBtYWtlIHN1cmUgaXQgcnVucyB0aGUgZXhwZWN0ZWQgY29tcG9zZXIgZnJvbSBjdXJyZW50IHBhdGgKICAgICAgICAgICAgICAgICAgICAvLyByZXNvbHV0aW9uLCBldmVuIGlmIGJpbi1kaXIgY29udGFpbnMgY29tcG9zZXIgdG9vIGJlY2F1c2UgdGhlIHByb2plY3QgcmVxdWlyZXMgY29tcG9zZXIvY29tcG9zZXIKICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy84NzQ4CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkZXhlYywgJ2NvbXBvc2VyICcpID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRleGVjID0gJHRoaXMtPmdldFBocEV4ZWNDb21tYW5kKCkgLiAnICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9CSU5BUlknKSkgLiBzdWJzdHIoJGV4ZWMsIDgpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKDAgIT09ICgkZXhpdENvZGUgPSAkdGhpcy0+ZXhlY3V0ZVR0eSgkZXhlYykpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+U2NyaXB0ICVzIGhhbmRsaW5nIHRoZSAlcyBldmVudCByZXR1cm5lZCB3aXRoIGVycm9yIGNvZGUgJy4kZXhpdENvZGUuJzwvZXJyb3I+JywgJGNhbGxhYmxlLCAkZXZlbnQtPmdldE5hbWUoKSksIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CgogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NyaXB0RXhlY3V0aW9uRXhjZXB0aW9uKCdFcnJvciBPdXRwdXQ6ICcuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICRleGl0Q29kZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXR1cm5NYXggPSBtYXgoJHJldHVybk1heCwgJHJldHVybik7CgogICAgICAgICAgICAgICAgaWYgKCRldmVudC0+aXNQcm9wYWdhdGlvblN0b3BwZWQoKSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgeyAvLyBUT0RPIENvbXBvc2VyIDIuMiB0dXJuIGFsbCB0aGlzIGludG8gYSBmaW5hbGx5CiAgICAgICAgICAgICR0aGlzLT5wb3BFdmVudCgpOwoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZSkgewogICAgICAgICAgICAkdGhpcy0+cG9wRXZlbnQoKTsKCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnBvcEV2ZW50KCk7CgogICAgICAgIHJldHVybiAkcmV0dXJuTWF4OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZXhlYwogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlVHR5KCRleGVjKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGVUdHkoJGV4ZWMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRleGVjKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQaHBFeGVjQ29tbWFuZCgpCiAgICB7CiAgICAgICAgJGZpbmRlciA9IG5ldyBQaHBFeGVjdXRhYmxlRmluZGVyKCk7CiAgICAgICAgJHBocFBhdGggPSAkZmluZGVyLT5maW5kKGZhbHNlKTsKICAgICAgICBpZiAoISRwaHBQYXRoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGxvY2F0ZSBQSFAgYmluYXJ5IHRvIGV4ZWN1dGUgJy4kcGhwUGF0aCk7CiAgICAgICAgfQogICAgICAgICRwaHBBcmdzID0gJGZpbmRlci0+ZmluZEFyZ3VtZW50cygpOwogICAgICAgICRwaHBBcmdzID0gJHBocEFyZ3MgPyAnICcgLiBpbXBsb2RlKCcgJywgJHBocEFyZ3MpIDogJyc7CiAgICAgICAgJGFsbG93VXJsRk9wZW5GbGFnID0gJyAtZCBhbGxvd191cmxfZm9wZW49JyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKGluaV9nZXQoJ2FsbG93X3VybF9mb3BlbicpKTsKICAgICAgICAkZGlzYWJsZUZ1bmN0aW9uc0ZsYWcgPSAnIC1kIGRpc2FibGVfZnVuY3Rpb25zPScgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShpbmlfZ2V0KCdkaXNhYmxlX2Z1bmN0aW9ucycpKTsKICAgICAgICAkbWVtb3J5TGltaXRGbGFnID0gJyAtZCBtZW1vcnlfbGltaXQ9JyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKGluaV9nZXQoJ21lbW9yeV9saW1pdCcpKTsKCiAgICAgICAgcmV0dXJuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwaHBQYXRoKSAuICRwaHBBcmdzIC4gJGFsbG93VXJsRk9wZW5GbGFnIC4gJGRpc2FibGVGdW5jdGlvbnNGbGFnIC4gJG1lbW9yeUxpbWl0RmxhZzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsYXNzTmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkbWV0aG9kTmFtZQogICAgICogQHBhcmFtIEV2ZW50ICAkZXZlbnQgICAgICBFdmVudCBpbnZva2luZyB0aGUgUEhQIGNhbGxhYmxlCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZUV2ZW50UGhwU2NyaXB0KCRjbGFzc05hbWUsICRtZXRob2ROYW1lLCBFdmVudCAkZXZlbnQpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNWZXJib3NlKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJz4gJXM6ICVzOjolcycsICRldmVudC0+Z2V0TmFtZSgpLCAkY2xhc3NOYW1lLCAkbWV0aG9kTmFtZSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc+ICVzOjolcycsICRjbGFzc05hbWUsICRtZXRob2ROYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNsYXNzTmFtZTo6JG1ldGhvZE5hbWUoJGV2ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIGxpc3RlbmVyIGZvciBhIHBhcnRpY3VsYXIgZXZlbnQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSAtIHR5cGljYWxseSBhIGNvbnN0YW50CiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGxpc3RlbmVyICBBIGNhbGxhYmxlIGV4cGVjdGluZyBhbiBldmVudCBhcmd1bWVudAogICAgICogQHBhcmFtIGludCAgICAgICRwcmlvcml0eSAgQSBoaWdoZXIgdmFsdWUgcmVwcmVzZW50cyBhIGhpZ2hlciBwcmlvcml0eQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTGlzdGVuZXIoJGV2ZW50TmFtZSwgJGxpc3RlbmVyLCAkcHJpb3JpdHkgPSAwKQogICAgewogICAgICAgICR0aGlzLT5saXN0ZW5lcnNbJGV2ZW50TmFtZV1bJHByaW9yaXR5XVtdID0gJGxpc3RlbmVyOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGNhbGxhYmxlfG9iamVjdCAkbGlzdGVuZXIgQSBjYWxsYWJsZSBvciBhbiBvYmplY3QgaW5zdGFuY2UgZm9yIHdoaWNoIGFsbCBsaXN0ZW5lcnMgc2hvdWxkIGJlIHJlbW92ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKCRsaXN0ZW5lcikKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+bGlzdGVuZXJzIGFzICRldmVudE5hbWUgPT4gJHByaW9yaXRpZXMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHByaW9yaXRpZXMgYXMgJHByaW9yaXR5ID0+ICRsaXN0ZW5lcnMpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaXN0ZW5lcnMgYXMgJGluZGV4ID0+ICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpc3RlbmVyID09PSAkY2FuZGlkYXRlIHx8IChpc19hcnJheSgkY2FuZGlkYXRlKSAmJiBpc19vYmplY3QoJGxpc3RlbmVyKSAmJiAkY2FuZGlkYXRlWzBdID09PSAkbGlzdGVuZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5saXN0ZW5lcnNbJGV2ZW50TmFtZV1bJHByaW9yaXR5XVskaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIG9iamVjdCBtZXRob2RzIGFzIGxpc3RlbmVycyBmb3IgdGhlIGV2ZW50cyBpbiBnZXRTdWJzY3JpYmVkRXZlbnRzCiAgICAgKgogICAgICogQHNlZSBFdmVudFN1YnNjcmliZXJJbnRlcmZhY2UKICAgICAqCiAgICAgKiBAcGFyYW0gRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlICRzdWJzY3JpYmVyCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTdWJzY3JpYmVyKEV2ZW50U3Vic2NyaWJlckludGVyZmFjZSAkc3Vic2NyaWJlcikKICAgIHsKICAgICAgICBmb3JlYWNoICgkc3Vic2NyaWJlci0+Z2V0U3Vic2NyaWJlZEV2ZW50cygpIGFzICRldmVudE5hbWUgPT4gJHBhcmFtcykgewogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRwYXJhbXMpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlzdGVuZXIoJGV2ZW50TmFtZSwgYXJyYXkoJHN1YnNjcmliZXIsICRwYXJhbXMpKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzX3N0cmluZygkcGFyYW1zWzBdKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpc3RlbmVyKCRldmVudE5hbWUsIGFycmF5KCRzdWJzY3JpYmVyLCAkcGFyYW1zWzBdKSwgaXNzZXQoJHBhcmFtc1sxXSkgPyAkcGFyYW1zWzFdIDogMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFyYW1zIGFzICRsaXN0ZW5lcikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaXN0ZW5lcigkZXZlbnROYW1lLCBhcnJheSgkc3Vic2NyaWJlciwgJGxpc3RlbmVyWzBdKSwgaXNzZXQoJGxpc3RlbmVyWzFdKSA/ICRsaXN0ZW5lclsxXSA6IDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmVzIGFsbCBsaXN0ZW5lcnMgZm9yIGEgZ2l2ZW4gZXZlbnQKICAgICAqCiAgICAgKiBAcGFyYW0gIEV2ZW50ICRldmVudAogICAgICogQHJldHVybiBhcnJheTxjYWxsYWJsZXxzdHJpbmc+IEFsbCBsaXN0ZW5lcnM6IGNhbGxhYmxlcyBhbmQgc2NyaXB0cwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKEV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICAkc2NyaXB0TGlzdGVuZXJzID0gJHRoaXMtPnJ1blNjcmlwdHMgPyAkdGhpcy0+Z2V0U2NyaXB0TGlzdGVuZXJzKCRldmVudCkgOiBhcnJheSgpOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5saXN0ZW5lcnNbJGV2ZW50LT5nZXROYW1lKCldWzBdKSkgewogICAgICAgICAgICAkdGhpcy0+bGlzdGVuZXJzWyRldmVudC0+Z2V0TmFtZSgpXVswXSA9IGFycmF5KCk7CiAgICAgICAgfQogICAgICAgIGtyc29ydCgkdGhpcy0+bGlzdGVuZXJzWyRldmVudC0+Z2V0TmFtZSgpXSk7CgogICAgICAgICRsaXN0ZW5lcnMgPSAkdGhpcy0+bGlzdGVuZXJzOwogICAgICAgICRsaXN0ZW5lcnNbJGV2ZW50LT5nZXROYW1lKCldWzBdID0gYXJyYXlfbWVyZ2UoJGxpc3RlbmVyc1skZXZlbnQtPmdldE5hbWUoKV1bMF0sICRzY3JpcHRMaXN0ZW5lcnMpOwoKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJGxpc3RlbmVyc1skZXZlbnQtPmdldE5hbWUoKV0pOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGFuIGV2ZW50IGhhcyBsaXN0ZW5lcnMgcmVnaXN0ZXJlZAogICAgICoKICAgICAqIEBwYXJhbSAgRXZlbnQgJGV2ZW50CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0V2ZW50TGlzdGVuZXJzKEV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICAkbGlzdGVuZXJzID0gJHRoaXMtPmdldExpc3RlbmVycygkZXZlbnQpOwoKICAgICAgICByZXR1cm4gY291bnQoJGxpc3RlbmVycykgPiAwOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgYWxsIGxpc3RlbmVycyBkZWZpbmVkIGFzIHNjcmlwdHMgaW4gdGhlIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gIEV2ZW50ICRldmVudCBFdmVudCBvYmplY3QKICAgICAqIEByZXR1cm4gc3RyaW5nW10gTGlzdGVuZXJzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRTY3JpcHRMaXN0ZW5lcnMoRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgJHNjcmlwdHMgPSAkcGFja2FnZS0+Z2V0U2NyaXB0cygpOwoKICAgICAgICBpZiAoZW1wdHkoJHNjcmlwdHNbJGV2ZW50LT5nZXROYW1lKCldKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bG9hZGVyKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkZXItPnVucmVnaXN0ZXIoKTsKICAgICAgICB9CgogICAgICAgICRnZW5lcmF0b3IgPSAkdGhpcy0+Y29tcG9zZXItPmdldEF1dG9sb2FkR2VuZXJhdG9yKCk7CiAgICAgICAgaWYgKCRldmVudCBpbnN0YW5jZW9mIFNjcmlwdEV2ZW50KSB7CiAgICAgICAgICAgICRnZW5lcmF0b3ItPnNldERldk1vZGUoJGV2ZW50LT5pc0Rldk1vZGUoKSk7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+Y29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpLT5nZXRDYW5vbmljYWxQYWNrYWdlcygpOwogICAgICAgICRwYWNrYWdlTWFwID0gJGdlbmVyYXRvci0+YnVpbGRQYWNrYWdlTWFwKCR0aGlzLT5jb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLCAkcGFja2FnZSwgJHBhY2thZ2VzKTsKICAgICAgICAkbWFwID0gJGdlbmVyYXRvci0+cGFyc2VBdXRvbG9hZHMoJHBhY2thZ2VNYXAsICRwYWNrYWdlKTsKICAgICAgICAkdGhpcy0+bG9hZGVyID0gJGdlbmVyYXRvci0+Y3JlYXRlTG9hZGVyKCRtYXAsICR0aGlzLT5jb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgndmVuZG9yLWRpcicpKTsKICAgICAgICAkdGhpcy0+bG9hZGVyLT5yZWdpc3RlcihmYWxzZSk7CgogICAgICAgIHJldHVybiAkc2NyaXB0c1skZXZlbnQtPmdldE5hbWUoKV07CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc3RyaW5nIGdpdmVuIHJlZmVyZW5jZXMgYSBjbGFzcyBwYXRoIGFuZCBtZXRob2QKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkY2FsbGFibGUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNQaHBTY3JpcHQoJGNhbGxhYmxlKQogICAgewogICAgICAgIHJldHVybiBmYWxzZSA9PT0gc3RycG9zKCRjYWxsYWJsZSwgJyAnKSAmJiBmYWxzZSAhPT0gc3RycG9zKCRjYWxsYWJsZSwgJzo6Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc3RyaW5nIGdpdmVuIHJlZmVyZW5jZXMgYSBjb21wb3NlciBydW4tc2NyaXB0CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGNhbGxhYmxlCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzQ29tcG9zZXJTY3JpcHQoJGNhbGxhYmxlKQogICAgewogICAgICAgIHJldHVybiBzdHJwb3MoJGNhbGxhYmxlLCAnQCcpID09PSAwICYmIHN0cnBvcygkY2FsbGFibGUsICdAcGhwICcpICE9PSAwICYmIHN0cnBvcygkY2FsbGFibGUsICdAcHV0ZW52ICcpICE9PSAwOwogICAgfQoKICAgIC8qKgogICAgICogUHVzaCBhbiBldmVudCB0byB0aGUgc3RhY2sgb2YgYWN0aXZlIGV2ZW50CiAgICAgKgogICAgICogQHBhcmFtICBFdmVudCAgICAgICAgICAgICAkZXZlbnQKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwdXNoRXZlbnQoRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgICRldmVudE5hbWUgPSAkZXZlbnQtPmdldE5hbWUoKTsKICAgICAgICBpZiAoaW5fYXJyYXkoJGV2ZW50TmFtZSwgJHRoaXMtPmV2ZW50U3RhY2spKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCJDaXJjdWxhciBjYWxsIHRvIHNjcmlwdCBoYW5kbGVyICclcycgZGV0ZWN0ZWQiLCAkZXZlbnROYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfcHVzaCgkdGhpcy0+ZXZlbnRTdGFjaywgJGV2ZW50TmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQb3BzIHRoZSBhY3RpdmUgZXZlbnQgZnJvbSB0aGUgc3RhY2sKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwb3BFdmVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X3BvcCgkdGhpcy0+ZXZlbnRTdGFjayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBlbnN1cmVCaW5EaXJJc0luUGF0aCgpCiAgICB7CiAgICAgICAgJHBhdGhFbnYgPSAnUEFUSCc7CiAgICAgICAgaWYgKGZhbHNlID09PSBQbGF0Zm9ybTo6Z2V0RW52KCdQQVRIJykgJiYgZmFsc2UgIT09IFBsYXRmb3JtOjpnZXRFbnYoJ1BhdGgnKSkgewogICAgICAgICAgICAkcGF0aEVudiA9ICdQYXRoJzsKICAgICAgICB9CgogICAgICAgIC8vIGFkZCB0aGUgYmluIGRpciB0byB0aGUgUEFUSCB0byBtYWtlIGxvY2FsIGJpbmFyaWVzIG9mIGRlcHMgdXNhYmxlIGluIHNjcmlwdHMKICAgICAgICAkYmluRGlyID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdiaW4tZGlyJyk7CiAgICAgICAgaWYgKGlzX2RpcigkYmluRGlyKSkgewogICAgICAgICAgICAkYmluRGlyID0gcmVhbHBhdGgoJGJpbkRpcik7CiAgICAgICAgICAgICRwYXRoVmFsdWUgPSBQbGF0Zm9ybTo6Z2V0RW52KCRwYXRoRW52KTsKICAgICAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7KF58Jy5QQVRIX1NFUEFSQVRPUi4nKScucHJlZ19xdW90ZSgkYmluRGlyKS4nKCR8Jy5QQVRIX1NFUEFSQVRPUi4nKX0nLCAkcGF0aFZhbHVlKSkgewogICAgICAgICAgICAgICAgUGxhdGZvcm06OnB1dEVudigkcGF0aEVudiwgJGJpbkRpci5QQVRIX1NFUEFSQVRPUi4kcGF0aFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7CgovKioKICogVGhlIFJ1bGVXYXRjaEdyYXBoIGVmZmljaWVudGx5IHByb3BhZ2F0ZXMgZGVjaXNpb25zIHRvIG90aGVyIHJ1bGVzCiAqCiAqIEFsbCBydWxlcyBnZW5lcmF0ZWQgZm9yIHNvbHZpbmcgYSBTQVQgcHJvYmxlbSBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byB0aGUKICogZ3JhcGguIFdoZW4gYSBkZWNpc2lvbiBvbiBhIGxpdGVyYWwgaXMgbWFkZSwgdGhlIGdyYXBoIGNhbiBiZSB1c2VkIHRvCiAqIHByb3BhZ2F0ZSB0aGUgZGVjaXNpb24gdG8gYWxsIG90aGVyIHJ1bGVzIGludm9sdmluZyB0aGUgbGl0ZXJhbCwgbGVhZGluZyB0bwogKiBvdGhlciB0cml2aWFsIGRlY2lzaW9ucyByZXN1bHRpbmcgZnJvbSB1bml0IGNsYXVzZXMuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBSdWxlV2F0Y2hHcmFwaAp7CiAgICAvKiogQHZhciBhcnJheTxpbnQsIFJ1bGVXYXRjaENoYWluPiAqLwogICAgcHJvdGVjdGVkICR3YXRjaENoYWlucyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBJbnNlcnRzIGEgcnVsZSBub2RlIGludG8gdGhlIGFwcHJvcHJpYXRlIGNoYWlucyB3aXRoaW4gdGhlIGdyYXBoCiAgICAgKgogICAgICogVGhlIG5vZGUgaXMgcHJlcGVuZGVkIHRvIHRoZSB3YXRjaCBjaGFpbnMgZm9yIGVhY2ggb2YgdGhlIHR3byBsaXRlcmFscyBpdAogICAgICogd2F0Y2hlcy4KICAgICAqCiAgICAgKiBBc3NlcnRpb25zIGFyZSBza2lwcGVkIGJlY2F1c2UgdGhleSBvbmx5IGRlcGVuZCBvbiBhIHNpbmdsZSBwYWNrYWdlIGFuZAogICAgICogaGF2ZSBubyBhbHRlcm5hdGl2ZSBsaXRlcmFsIHRoYXQgY291bGQgYmUgdHJ1ZSwgc28gdGhlcmUgaXMgbm8gbmVlZCB0bwogICAgICogd2F0Y2ggY2hhbmdlcyBpbiBhbnkgbGl0ZXJhbHMuCiAgICAgKgogICAgICogQHBhcmFtIFJ1bGVXYXRjaE5vZGUgJG5vZGUgVGhlIHJ1bGUgbm9kZSB0byBiZSBpbnNlcnRlZCBpbnRvIHRoZSBncmFwaAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnNlcnQoUnVsZVdhdGNoTm9kZSAkbm9kZSkKICAgIHsKICAgICAgICBpZiAoJG5vZGUtPmdldFJ1bGUoKS0+aXNBc3NlcnRpb24oKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoISRub2RlLT5nZXRSdWxlKCkgaW5zdGFuY2VvZiBNdWx0aUNvbmZsaWN0UnVsZSkgewogICAgICAgICAgICBmb3JlYWNoIChhcnJheSgkbm9kZS0+d2F0Y2gxLCAkbm9kZS0+d2F0Y2gyKSBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+d2F0Y2hDaGFpbnNbJGxpdGVyYWxdKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXRjaENoYWluc1skbGl0ZXJhbF0gPSBuZXcgUnVsZVdhdGNoQ2hhaW47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRoaXMtPndhdGNoQ2hhaW5zWyRsaXRlcmFsXS0+dW5zaGlmdCgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3JlYWNoICgkbm9kZS0+Z2V0UnVsZSgpLT5nZXRMaXRlcmFscygpIGFzICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT53YXRjaENoYWluc1skbGl0ZXJhbF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhdGNoQ2hhaW5zWyRsaXRlcmFsXSA9IG5ldyBSdWxlV2F0Y2hDaGFpbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+d2F0Y2hDaGFpbnNbJGxpdGVyYWxdLT51bnNoaWZ0KCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByb3BhZ2F0ZXMgYSBkZWNpc2lvbiBvbiBhIGxpdGVyYWwgdG8gYWxsIHJ1bGVzIHdhdGNoaW5nIHRoZSBsaXRlcmFsCiAgICAgKgogICAgICogSWYgYSBkZWNpc2lvbiwgZS5nLiArQSBoYXMgYmVlbiBtYWRlLCB0aGVuIGFsbCBydWxlcyBjb250YWluaW5nIC1BLCBlLmcuCiAgICAgKiAoLUF8K0J8K0MpIG5vdyBuZWVkIHRvIHNhdGlzZnkgYXQgbGVhc3Qgb25lIG9mIHRoZSBvdGhlciBsaXRlcmFscywgc28KICAgICAqIHRoYXQgdGhlIHJ1bGUgYXMgYSB3aG9sZSBiZWNvbWVzIHRydWUsIHNpbmNlIHdpdGggK0EgYXBwbGllZCB0aGUgcnVsZQogICAgICogaXMgbm93IChmYWxzZXwrQnwrQykgc28gZXNzZW50aWFsbHkgKCtCfCtDKS4KICAgICAqCiAgICAgKiBUaGlzIG1lYW5zIHRoYXQgYWxsIHJ1bGVzIHdhdGNoaW5nIHRoZSBsaXRlcmFsIC1BIG5lZWQgdG8gYmUgdXBkYXRlZCB0bwogICAgICogd2F0Y2ggMiBvdGhlciBsaXRlcmFscyB3aGljaCBjYW4gc3RpbGwgYmUgc2F0aXNmaWVkIGluc3RlYWQuIFNvIGxpdGVyYWxzCiAgICAgKiB0aGF0IGNvbmZsaWN0IHdpdGggcHJldmlvdXNseSBtYWRlIGRlY2lzaW9ucyBhcmUgbm90IGFuIG9wdGlvbi4KICAgICAqCiAgICAgKiBBbHRlcm5hdGl2ZWx5IGl0IGNhbiBvY2N1ciB0aGF0IGEgdW5pdCBjbGF1c2UgcmVzdWx0czogZS5nLiBpZiBpbiB0aGUKICAgICAqIGFib3ZlIGV4YW1wbGUgdGhlIHJ1bGUgd2FzICgtQXwrQiksIHRoZW4gQSB0dXJuaW5nIHRydWUgbWVhbnMgdGhhdAogICAgICogQiBtdXN0IG5vdyBiZSBkZWNpZGVkIHRydWUgYXMgd2VsbC4KICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAkZGVjaWRlZExpdGVyYWwgVGhlIGxpdGVyYWwgd2hpY2ggd2FzIGRlY2lkZWQgKEEgaW4gb3VyIGV4YW1wbGUpCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAkbGV2ZWwgICAgICAgICAgVGhlIGxldmVsIGF0IHdoaWNoIHRoZSBkZWNpc2lvbiB0b29rIHBsYWNlIGFuZCBhdCB3aGljaAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbCByZXN1bHRpbmcgZGVjaXNpb25zIHNob3VsZCBiZSBtYWRlLgogICAgICogQHBhcmFtICBEZWNpc2lvbnMgJGRlY2lzaW9ucyAgICAgIFVzZWQgdG8gY2hlY2sgcHJldmlvdXMgZGVjaXNpb25zIGFuZCB0bwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyIGRlY2lzaW9ucyByZXN1bHRpbmcgZnJvbSBwcm9wYWdhdGlvbgogICAgICogQHJldHVybiBSdWxlfG51bGwgSWYgYSBjb25mbGljdCBpcyBmb3VuZCB0aGUgY29uZmxpY3RpbmcgcnVsZSBpcyByZXR1cm5lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvcGFnYXRlTGl0ZXJhbCgkZGVjaWRlZExpdGVyYWwsICRsZXZlbCwgRGVjaXNpb25zICRkZWNpc2lvbnMpCiAgICB7CiAgICAgICAgLy8gd2UgaW52ZXJ0IHRoZSBkZWNpZGVkIGxpdGVyYWwgaGVyZSwgZXhhbXBsZToKICAgICAgICAvLyBBIHdhcyBkZWNpZGVkID0+ICgtQXxCKSBub3cgcmVxdWlyZXMgQiB0byBiZSB0cnVlLCBzbyB3ZSBsb29rIGZvcgogICAgICAgIC8vIHJ1bGVzIHdoaWNoIGFyZSBmdWxmaWxsZWQgYnkgLUEsIHJhdGhlciB0aGFuIEEuCiAgICAgICAgJGxpdGVyYWwgPSAtJGRlY2lkZWRMaXRlcmFsOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT53YXRjaENoYWluc1skbGl0ZXJhbF0pKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGNoYWluID0gJHRoaXMtPndhdGNoQ2hhaW5zWyRsaXRlcmFsXTsKCiAgICAgICAgJGNoYWluLT5yZXdpbmQoKTsKICAgICAgICB3aGlsZSAoJGNoYWluLT52YWxpZCgpKSB7CiAgICAgICAgICAgICRub2RlID0gJGNoYWluLT5jdXJyZW50KCk7CiAgICAgICAgICAgIGlmICghJG5vZGUtPmdldFJ1bGUoKSBpbnN0YW5jZW9mIE11bHRpQ29uZmxpY3RSdWxlKSB7CiAgICAgICAgICAgICAgICAkb3RoZXJXYXRjaCA9ICRub2RlLT5nZXRPdGhlcldhdGNoKCRsaXRlcmFsKTsKCiAgICAgICAgICAgICAgICBpZiAoISRub2RlLT5nZXRSdWxlKCktPmlzRGlzYWJsZWQoKSAmJiAhJGRlY2lzaW9ucy0+c2F0aXNmeSgkb3RoZXJXYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkcnVsZUxpdGVyYWxzID0gJG5vZGUtPmdldFJ1bGUoKS0+Z2V0TGl0ZXJhbHMoKTsKCiAgICAgICAgICAgICAgICAgICAgJGFsdGVybmF0aXZlTGl0ZXJhbHMgPSBhcnJheV9maWx0ZXIoJHJ1bGVMaXRlcmFscywgZnVuY3Rpb24gKCRydWxlTGl0ZXJhbCkgdXNlICgkbGl0ZXJhbCwgJG90aGVyV2F0Y2gsICRkZWNpc2lvbnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRsaXRlcmFsICE9PSAkcnVsZUxpdGVyYWwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRvdGhlcldhdGNoICE9PSAkcnVsZUxpdGVyYWwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICEkZGVjaXNpb25zLT5jb25mbGljdCgkcnVsZUxpdGVyYWwpOwogICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJGFsdGVybmF0aXZlTGl0ZXJhbHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoJGFsdGVybmF0aXZlTGl0ZXJhbHMpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bW92ZVdhdGNoKCRsaXRlcmFsLCBjdXJyZW50KCRhbHRlcm5hdGl2ZUxpdGVyYWxzKSwgJG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkZGVjaXNpb25zLT5jb25mbGljdCgkb3RoZXJXYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRub2RlLT5nZXRSdWxlKCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb25zLT5kZWNpZGUoJG90aGVyV2F0Y2gsICRsZXZlbCwgJG5vZGUtPmdldFJ1bGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbm9kZS0+Z2V0UnVsZSgpLT5nZXRMaXRlcmFscygpIGFzICRvdGhlckxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpdGVyYWwgIT09ICRvdGhlckxpdGVyYWwgJiYgISRkZWNpc2lvbnMtPnNhdGlzZnkoJG90aGVyTGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRkZWNpc2lvbnMtPmNvbmZsaWN0KCRvdGhlckxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGUtPmdldFJ1bGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9ucy0+ZGVjaWRlKCRvdGhlckxpdGVyYWwsICRsZXZlbCwgJG5vZGUtPmdldFJ1bGUoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2hhaW4tPm5leHQoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogTW92ZXMgYSBydWxlIG5vZGUgZnJvbSBvbmUgd2F0Y2ggY2hhaW4gdG8gYW5vdGhlcgogICAgICoKICAgICAqIFRoZSBydWxlIG5vZGUncyB3YXRjaGVkIGxpdGVyYWxzIGFyZSB1cGRhdGVkIGFjY29yZGluZ2x5LgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICRmcm9tTGl0ZXJhbCBBIGxpdGVyYWwgdGhlIG5vZGUgdXNlZCB0byB3YXRjaAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgJHRvTGl0ZXJhbCAgIEEgbGl0ZXJhbCB0aGUgbm9kZSBzaG91bGQgd2F0Y2ggbm93CiAgICAgKiBAcGFyYW0gUnVsZVdhdGNoTm9kZSAkbm9kZSAgICAgICAgVGhlIHJ1bGUgbm9kZSB0byBiZSBtb3ZlZAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBtb3ZlV2F0Y2goJGZyb21MaXRlcmFsLCAkdG9MaXRlcmFsLCBSdWxlV2F0Y2hOb2RlICRub2RlKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPndhdGNoQ2hhaW5zWyR0b0xpdGVyYWxdKSkgewogICAgICAgICAgICAkdGhpcy0+d2F0Y2hDaGFpbnNbJHRvTGl0ZXJhbF0gPSBuZXcgUnVsZVdhdGNoQ2hhaW47CiAgICAgICAgfQoKICAgICAgICAkbm9kZS0+bW92ZVdhdGNoKCRmcm9tTGl0ZXJhbCwgJHRvTGl0ZXJhbCk7CiAgICAgICAgJHRoaXMtPndhdGNoQ2hhaW5zWyRmcm9tTGl0ZXJhbF0tPnJlbW92ZSgpOwogICAgICAgICR0aGlzLT53YXRjaENoYWluc1skdG9MaXRlcmFsXS0+dW5zaGlmdCgkbm9kZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBpbGluZ01hdGNoZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE11bHRpQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxJbnRlcnZhbHM7CgovKioKICogT3B0aW1pemVzIGEgZ2l2ZW4gcG9vbAogKgogKiBAYXV0aG9yIFlhbmljayBXaXRzY2hpIDx5YW5pY2sud2l0c2NoaUB0ZXJtaW5hbDQyLmNoPgogKi8KY2xhc3MgUG9vbE9wdGltaXplcgp7CiAgICAvKioKICAgICAqIEB2YXIgUG9saWN5SW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJHBvbGljeTsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8aW50LCB0cnVlPgogICAgICovCiAgICBwcml2YXRlICRpcnJlbW92YWJsZVBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIENvbnN0cmFpbnRJbnRlcmZhY2U+PgogICAgICovCiAgICBwcml2YXRlICRyZXF1aXJlQ29uc3RyYWludHNQZXJQYWNrYWdlID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIENvbnN0cmFpbnRJbnRlcmZhY2U+PgogICAgICovCiAgICBwcml2YXRlICRjb25mbGljdENvbnN0cmFpbnRzUGVyUGFja2FnZSA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5PGludCwgdHJ1ZT4KICAgICAqLwogICAgcHJpdmF0ZSAkcGFja2FnZXNUb1JlbW92ZSA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5PGludCwgQmFzZVBhY2thZ2VbXT4KICAgICAqLwogICAgcHJpdmF0ZSAkYWxpYXNlc1BlclBhY2thZ2UgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgc3RyaW5nPj4KICAgICAqLwogICAgcHJpdmF0ZSAkcmVtb3ZlZFZlcnNpb25zQnlQYWNrYWdlID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUG9saWN5SW50ZXJmYWNlICRwb2xpY3kpCiAgICB7CiAgICAgICAgJHRoaXMtPnBvbGljeSA9ICRwb2xpY3k7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFBvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG9wdGltaXplKFJlcXVlc3QgJHJlcXVlc3QsIFBvb2wgJHBvb2wpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXBhcmUoJHJlcXVlc3QsICRwb29sKTsKCiAgICAgICAgJHRoaXMtPm9wdGltaXplQnlJZGVudGljYWxEZXBlbmRlbmNpZXMoJHJlcXVlc3QsICRwb29sKTsKCiAgICAgICAgJHRoaXMtPm9wdGltaXplSW1wb3NzaWJsZVBhY2thZ2VzQXdheSgkcmVxdWVzdCwgJHBvb2wpOwoKICAgICAgICAkb3B0aW1pemVkUG9vbCA9ICR0aGlzLT5hcHBseVJlbW92YWxzVG9Qb29sKCRwb29sKTsKCiAgICAgICAgLy8gTm8gbmVlZCB0byBydW4gdGhpcyByZWN1cnNpdmVseSBhdCB0aGUgbW9tZW50CiAgICAgICAgLy8gYmVjYXVzZSB0aGUgY3VycmVudCBvcHRpbWl6YXRpb25zIGNhbm5vdCBwcm92aWRlCiAgICAgICAgLy8gZXZlbiBtb3JlIGdhaW5zIHdoZW4gcmFuIGFnYWluLiBNaWdodCBjaGFuZ2UKICAgICAgICAvLyBpbiB0aGUgZnV0dXJlIHdpdGggYWRkaXRpb25hbCBvcHRpbWl6YXRpb25zLgoKICAgICAgICAkdGhpcy0+aXJyZW1vdmFibGVQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPnJlcXVpcmVDb25zdHJhaW50c1BlclBhY2thZ2UgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5jb25mbGljdENvbnN0cmFpbnRzUGVyUGFja2FnZSA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzVG9SZW1vdmUgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5hbGlhc2VzUGVyUGFja2FnZSA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPnJlbW92ZWRWZXJzaW9uc0J5UGFja2FnZSA9IGFycmF5KCk7CgogICAgICAgIHJldHVybiAkb3B0aW1pemVkUG9vbDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHByZXBhcmUoUmVxdWVzdCAkcmVxdWVzdCwgUG9vbCAkcG9vbCkKICAgIHsKICAgICAgICAkaXJyZW1vdmFibGVQYWNrYWdlQ29uc3RyYWludEdyb3VwcyA9IGFycmF5KCk7CgogICAgICAgIC8vIE1hcmsgZml4ZWQgb3IgbG9ja2VkIHBhY2thZ2VzIGFzIGlycmVtb3ZhYmxlCiAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldEZpeGVkT3JMb2NrZWRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRpcnJlbW92YWJsZVBhY2thZ2VDb25zdHJhaW50R3JvdXBzWyRwYWNrYWdlLT5nZXROYW1lKCldW10gPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICB9CgogICAgICAgIC8vIEV4dHJhY3QgcmVxdWVzdGVkIHBhY2thZ2UgcmVxdWlyZW1lbnRzCiAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldFJlcXVpcmVzKCkgYXMgJHJlcXVpcmUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSBJbnRlcnZhbHM6OmNvbXBhY3RDb25zdHJhaW50KCRjb25zdHJhaW50KTsKICAgICAgICAgICAgJHRoaXMtPnJlcXVpcmVDb25zdHJhaW50c1BlclBhY2thZ2VbJHJlcXVpcmVdWyhzdHJpbmcpICRjb25zdHJhaW50XSA9ICRjb25zdHJhaW50OwogICAgICAgIH0KCiAgICAgICAgLy8gRmlyc3QgcGFzcyBvdmVyIGFsbCBwYWNrYWdlcyB0byBleHRyYWN0IGluZm9ybWF0aW9uIGFuZCBtYXJrIHBhY2thZ2UgY29uc3RyYWludHMgaXJyZW1vdmFibGUKICAgICAgICBmb3JlYWNoICgkcG9vbC0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAvLyBFeHRyYWN0IHBhY2thZ2UgcmVxdWlyZW1lbnRzCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9IEludGVydmFsczo6Y29tcGFjdENvbnN0cmFpbnQoJGxpbmstPmdldENvbnN0cmFpbnQoKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVxdWlyZUNvbnN0cmFpbnRzUGVyUGFja2FnZVskbGluay0+Z2V0VGFyZ2V0KCldWyhzdHJpbmcpICRjb25zdHJhaW50XSA9ICRjb25zdHJhaW50OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEV4dHJhY3QgcGFja2FnZSBjb25mbGljdHMKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldENvbmZsaWN0cygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9IEludGVydmFsczo6Y29tcGFjdENvbnN0cmFpbnQoJGxpbmstPmdldENvbnN0cmFpbnQoKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmxpY3RDb25zdHJhaW50c1BlclBhY2thZ2VbJGxpbmstPmdldFRhcmdldCgpXVsoc3RyaW5nKSAkY29uc3RyYWludF0gPSAkY29uc3RyYWludDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvZiBhbGlhcyBwYWNrYWdlcyBmb3IgZXZlcnkgcGFja2FnZSBzbyBpZiBlaXRoZXIgdGhlIGFsaWFzIG9yIGFsaWFzZWQgaXMga2VwdAogICAgICAgICAgICAvLyB3ZSBrZWVwIHRoZSBvdGhlcnMgYXMgdGhleSBhcmUgYSB1bml0IG9mIHBhY2thZ2VzIHJlYWxseQogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hbGlhc2VzUGVyUGFja2FnZVskcGFja2FnZS0+Z2V0QWxpYXNPZigpLT5pZF1bXSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkaXJyZW1vdmFibGVQYWNrYWdlQ29uc3RyYWludHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRpcnJlbW92YWJsZVBhY2thZ2VDb25zdHJhaW50R3JvdXBzIGFzICRwYWNrYWdlTmFtZSA9PiAkY29uc3RyYWludHMpIHsKICAgICAgICAgICAgJGlycmVtb3ZhYmxlUGFja2FnZUNvbnN0cmFpbnRzWyRwYWNrYWdlTmFtZV0gPSAxID09PSBcY291bnQoJGNvbnN0cmFpbnRzKSA/ICRjb25zdHJhaW50c1swXSA6IG5ldyBNdWx0aUNvbnN0cmFpbnQoJGNvbnN0cmFpbnRzLCBmYWxzZSk7CiAgICAgICAgfQogICAgICAgIHVuc2V0KCRpcnJlbW92YWJsZVBhY2thZ2VDb25zdHJhaW50R3JvdXBzKTsKCiAgICAgICAgLy8gTWFyayB0aGUgcGFja2FnZXMgYXMgaXJyZW1vdmFibGUgYmFzZWQgb24gdGhlIGNvbnN0cmFpbnRzCiAgICAgICAgZm9yZWFjaCAoJHBvb2wtPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaXJyZW1vdmFibGVQYWNrYWdlQ29uc3RyYWludHNbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbXBpbGluZ01hdGNoZXI6Om1hdGNoKCRpcnJlbW92YWJsZVBhY2thZ2VDb25zdHJhaW50c1skcGFja2FnZS0+Z2V0TmFtZSgpXSwgQ29uc3RyYWludDo6T1BfRVEsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bWFya1BhY2thZ2VJcnJlbW92YWJsZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXJrUGFja2FnZUlycmVtb3ZhYmxlKEJhc2VQYWNrYWdlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5pcnJlbW92YWJsZVBhY2thZ2VzWyRwYWNrYWdlLT5pZF0gPSB0cnVlOwogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAvLyByZWN1cnNpbmcgaGVyZSBzbyBhbGlhc2VzUGVyUGFja2FnZSBmb3IgdGhlIGFsaWFzT2YgY2FuIGJlIGNoZWNrZWQKICAgICAgICAgICAgLy8gYW5kIGFsbCBpdHMgYWxpYXNlcyBtYXJrZWQgYXMgaXJyZW1vdmFibGUgYXMgd2VsbAogICAgICAgICAgICAkdGhpcy0+bWFya1BhY2thZ2VJcnJlbW92YWJsZSgkcGFja2FnZS0+Z2V0QWxpYXNPZigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hbGlhc2VzUGVyUGFja2FnZVskcGFja2FnZS0+aWRdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWxpYXNlc1BlclBhY2thZ2VbJHBhY2thZ2UtPmlkXSBhcyAkYWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aXJyZW1vdmFibGVQYWNrYWdlc1skYWxpYXNQYWNrYWdlLT5pZF0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQb29sIE9wdGltaXplZCBwb29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwbHlSZW1vdmFsc1RvUG9vbChQb29sICRwb29sKQogICAgewogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJHJlbW92ZWRWZXJzaW9ucyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBvb2wtPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cGFja2FnZXNUb1JlbW92ZVskcGFja2FnZS0+aWRdKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZW1vdmVkVmVyc2lvbnNbJHBhY2thZ2UtPmdldE5hbWUoKV1bJHBhY2thZ2UtPmdldFZlcnNpb24oKV0gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkb3B0aW1pemVkUG9vbCA9IG5ldyBQb29sKCRwYWNrYWdlcywgJHBvb2wtPmdldFVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlcygpLCAkcmVtb3ZlZFZlcnNpb25zLCAkdGhpcy0+cmVtb3ZlZFZlcnNpb25zQnlQYWNrYWdlKTsKCiAgICAgICAgcmV0dXJuICRvcHRpbWl6ZWRQb29sOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3B0aW1pemVCeUlkZW50aWNhbERlcGVuZGVuY2llcyhSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sKQogICAgewogICAgICAgICRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2UgPSBhcnJheSgpOwogICAgICAgICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cCA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwb29sLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CgogICAgICAgICAgICAvLyBJZiB0aGF0IHBhY2thZ2Ugd2FzIGFscmVhZHkgbWFya2VkIGlycmVtb3ZhYmxlLCB3ZSBjYW4gc2tpcAogICAgICAgICAgICAvLyB0aGUgZW50aXJlIHByb2Nlc3MgZm9yIGl0CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+aXJyZW1vdmFibGVQYWNrYWdlc1skcGFja2FnZS0+aWRdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5tYXJrUGFja2FnZUZvclJlbW92YWwoJHBhY2thZ2UtPmlkKTsKCiAgICAgICAgICAgICRkZXBlbmRlbmN5SGFzaCA9ICR0aGlzLT5jYWxjdWxhdGVEZXBlbmRlbmN5SGFzaCgkcGFja2FnZSk7CgogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0TmFtZXMoZmFsc2UpIGFzICRwYWNrYWdlTmFtZSkgewoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlcXVpcmVDb25zdHJhaW50c1BlclBhY2thZ2VbJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVxdWlyZUNvbnN0cmFpbnRzUGVyUGFja2FnZVskcGFja2FnZU5hbWVdIGFzICRyZXF1aXJlQ29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICRncm91cEhhc2hQYXJ0cyA9IGFycmF5KCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChDb21waWxpbmdNYXRjaGVyOjptYXRjaCgkcmVxdWlyZUNvbnN0cmFpbnQsIENvbnN0cmFpbnQ6Ok9QX0VRLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZ3JvdXBIYXNoUGFydHNbXSA9ICdyZXF1aXJlOicgLiAoc3RyaW5nKSAkcmVxdWlyZUNvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFJlcGxhY2VzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcGxhY2VzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDb21waWxpbmdNYXRjaGVyOjptYXRjaCgkbGluay0+Z2V0Q29uc3RyYWludCgpLCBDb25zdHJhaW50OjpPUF9FUSwgJHBhY2thZ2UtPmdldFZlcnNpb24oKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgdGhlIHNhbWUgaGFzaCBwYXJ0IGFzIHRoZSByZWd1bGFyIHJlcXVpcmUgaGFzaCBiZWNhdXNlIHRoYXQncyB3aGF0IHRoZSByZXBsYWNlbWVudCBkb2VzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGdyb3VwSGFzaFBhcnRzW10gPSAncmVxdWlyZTonIC4gKHN0cmluZykgJGxpbmstPmdldENvbnN0cmFpbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25mbGljdENvbnN0cmFpbnRzUGVyUGFja2FnZVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uZmxpY3RDb25zdHJhaW50c1BlclBhY2thZ2VbJHBhY2thZ2VOYW1lXSBhcyAkY29uZmxpY3RDb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ29tcGlsaW5nTWF0Y2hlcjo6bWF0Y2goJGNvbmZsaWN0Q29uc3RyYWludCwgQ29uc3RyYWludDo6T1BfRVEsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGdyb3VwSGFzaFBhcnRzW10gPSAnY29uZmxpY3Q6JyAuIChzdHJpbmcpICRjb25mbGljdENvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJGdyb3VwSGFzaFBhcnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGdyb3VwSGFzaCA9IGltcGxvZGUoJycsICRncm91cEhhc2hQYXJ0cyk7CiAgICAgICAgICAgICAgICAgICAgJGlkZW50aWNhbERlZmluaXRpb25zUGVyUGFja2FnZVskcGFja2FnZU5hbWVdWyRncm91cEhhc2hdWyRkZXBlbmRlbmN5SGFzaF1bXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cFskcGFja2FnZS0+aWRdWyRwYWNrYWdlTmFtZV0gPSBhcnJheSgnZ3JvdXBIYXNoJyA9PiAkZ3JvdXBIYXNoLCAnZGVwZW5kZW5jeUhhc2gnID0+ICRkZXBlbmRlbmN5SGFzaCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2UgYXMgJGNvbnN0cmFpbnRHcm91cHMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnN0cmFpbnRHcm91cHMgYXMgJGNvbnN0cmFpbnRHcm91cCkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnN0cmFpbnRHcm91cCBhcyAkcGFja2FnZXMpIHsKICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IG9uZSBwYWNrYWdlIGluIHRoaXMgY29uc3RyYWludCBncm91cCBoYXMgdGhlIHNhbWUgcmVxdWlyZW1lbnRzLCB3ZSdyZSBub3QgYWxsb3dlZCB0byByZW1vdmUgdGhhdCBwYWNrYWdlCiAgICAgICAgICAgICAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5rZWVwUGFja2FnZSgkcGFja2FnZXNbMF0sICRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2UsICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIHdlIGZpbmQgb3V0IHdoaWNoIG9uZSBpcyB0aGUgcHJlZmVycmVkIHBhY2thZ2UgaW4gdGhpcyBjb25zdHJhaW50IGdyb3VwIHdoaWNoIGlzCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiBub3QgYWxsb3dlZCB0byBiZSByZW1vdmVkIGVpdGhlcgogICAgICAgICAgICAgICAgICAgICRsaXRlcmFscyA9IGFycmF5KCk7CgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGl0ZXJhbHNbXSA9ICRwYWNrYWdlLT5pZDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wb2xpY3ktPnNlbGVjdFByZWZlcnJlZFBhY2thZ2VzKCRwb29sLCAkbGl0ZXJhbHMpIGFzICRwcmVmZXJyZWRMaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5rZWVwUGFja2FnZSgkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkcHJlZmVycmVkTGl0ZXJhbCksICRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2UsICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYWxjdWxhdGVEZXBlbmRlbmN5SGFzaChCYXNlUGFja2FnZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkaGFzaCA9ICcnOwoKICAgICAgICAkaGFzaFJlbGV2YW50TGlua3MgPSBhcnJheSgKICAgICAgICAgICAgJ3JlcXVpcmVzJyA9PiAkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgJ2NvbmZsaWN0cycgPT4gJHBhY2thZ2UtPmdldENvbmZsaWN0cygpLAogICAgICAgICAgICAncmVwbGFjZXMnID0+ICRwYWNrYWdlLT5nZXRSZXBsYWNlcygpLAogICAgICAgICAgICAncHJvdmlkZXMnID0+ICRwYWNrYWdlLT5nZXRQcm92aWRlcygpCiAgICAgICAgKTsKCiAgICAgICAgZm9yZWFjaCAoJGhhc2hSZWxldmFudExpbmtzIGFzICRrZXkgPT4gJGxpbmtzKSB7CiAgICAgICAgICAgIGlmICgwID09PSBcY291bnQoJGxpbmtzKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHN0YXJ0IG5ldyBoYXNoIHNlY3Rpb24KICAgICAgICAgICAgJGhhc2ggLj0gJGtleSAuICc6JzsKCiAgICAgICAgICAgICRzdWJoYXNoID0gYXJyYXkoKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICAgICAgLy8gVG8gZ2V0IHRoZSBiZXN0IGRlcGVuZGVuY3kgaGFzaCBtYXRjaGVzIHdlIHNob3VsZCB1c2UgSW50ZXJ2YWxzOjpjb21wYWN0Q29uc3RyYWludCgpIGhlcmUuCiAgICAgICAgICAgICAgICAvLyBIb3dldmVyLCB0aGUgbWFqb3JpdHkgb2YgcHJvamVjdHMgYXJlIGdvaW5nIHRvIHNwZWNpZnkgdGhlaXIgY29uc3RyYWludHMgYWxyZWFkeSBwcmV0dHkKICAgICAgICAgICAgICAgIC8vIG11Y2ggaW4gdGhlIGJlc3QgdmFyaWFudCBwb3NzaWJsZS4gSW4gb3RoZXIgd29yZHMsIHdlJ2QgYmUgd2FzdGluZyB0aW1lIGhlcmUgYW5kIGl0IHdvdWxkIGFjdHVhbGx5IGh1cnQKICAgICAgICAgICAgICAgIC8vIHBlcmZvcm1hbmNlIG1vcmUgdGhhbiB0aGUgYWRkaXRpb25hbCBmZXcgcGFja2FnZXMgdGhhdCBjb3VsZCBiZSBmaWx0ZXJlZCBvdXQgd291bGQgYmVuZWZpdCB0aGUgcHJvY2Vzcy4KICAgICAgICAgICAgICAgICRzdWJoYXNoWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSAoc3RyaW5nKSAkbGluay0+Z2V0Q29uc3RyYWludCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBTb3J0IGZvciBiZXN0IHJlc3VsdAogICAgICAgICAgICBrc29ydCgkc3ViaGFzaCk7CgogICAgICAgICAgICBmb3JlYWNoICgkc3ViaGFzaCBhcyAkdGFyZ2V0ID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAkaGFzaCAuPSAkdGFyZ2V0IC4gJ0AnIC4gJGNvbnN0cmFpbnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkaGFzaDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJGlkCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXJrUGFja2FnZUZvclJlbW92YWwoJGlkKQogICAgewogICAgICAgIC8vIFdlIGFyZSBub3QgYWxsb3dlZCB0byByZW1vdmUgcGFja2FnZXMgaWYgdGhleSBoYXZlIGJlZW4gbWFya2VkIGFzIGlycmVtb3ZhYmxlCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5pcnJlbW92YWJsZVBhY2thZ2VzWyRpZF0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0F0dGVtcHRlZCByZW1vdmluZyBhIHBhY2thZ2Ugd2hpY2ggd2FzIHByZXZpb3VzbHkgbWFya2VkIGlycmVtb3ZhYmxlJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cGFja2FnZXNUb1JlbW92ZVskaWRdID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBsaXN0PEJhc2VQYWNrYWdlPj4+PiAkaWRlbnRpY2FsRGVmaW5pdGlvbnNQZXJQYWNrYWdlCiAgICAgKiBAcGFyYW0gYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIGFycmF5e2dyb3VwSGFzaDogc3RyaW5nLCBkZXBlbmRlbmN5SGFzaDogc3RyaW5nfT4+ICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24ga2VlcFBhY2thZ2UoQmFzZVBhY2thZ2UgJHBhY2thZ2UsICRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2UsICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cCkKICAgIHsKICAgICAgICB1bnNldCgkdGhpcy0+cGFja2FnZXNUb1JlbW92ZVskcGFja2FnZS0+aWRdKTsKCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgIC8vIHJlY3Vyc2luZyBoZXJlIHNvIGFsaWFzZXNQZXJQYWNrYWdlIGZvciB0aGUgYWxpYXNPZiBjYW4gYmUgY2hlY2tlZAogICAgICAgICAgICAvLyBhbmQgYWxsIGl0cyBhbGlhc2VzIG1hcmtlZCB0byBiZSBrZXB0IGFzIHdlbGwKICAgICAgICAgICAgJHRoaXMtPmtlZXBQYWNrYWdlKCRwYWNrYWdlLT5nZXRBbGlhc09mKCksICRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2UsICRwYWNrYWdlSWRlbnRpY2FsRGVmaW5pdGlvbkxvb2t1cCk7CiAgICAgICAgfQoKICAgICAgICAvLyByZWNvcmQgYWxsIHRoZSB2ZXJzaW9ucyBvZiB0aGUgcGFja2FnZSBncm91cCBzbyB3ZSBjYW4gbGlzdCB0aGVtIGxhdGVyIGluIFByb2JsZW0gb3V0cHV0CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldE5hbWVzKGZhbHNlKSBhcyAkbmFtZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VJZGVudGljYWxEZWZpbml0aW9uTG9va3VwWyRwYWNrYWdlLT5pZF1bJG5hbWVdKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VHcm91cFBvaW50ZXJzID0gJHBhY2thZ2VJZGVudGljYWxEZWZpbml0aW9uTG9va3VwWyRwYWNrYWdlLT5pZF1bJG5hbWVdOwogICAgICAgICAgICAgICAgJHBhY2thZ2VHcm91cCA9ICRpZGVudGljYWxEZWZpbml0aW9uc1BlclBhY2thZ2VbJG5hbWVdWyRwYWNrYWdlR3JvdXBQb2ludGVyc1snZ3JvdXBIYXNoJ11dWyRwYWNrYWdlR3JvdXBQb2ludGVyc1snZGVwZW5kZW5jeUhhc2gnXV07CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZUdyb3VwIGFzICRwa2cpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBrZyBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGtnLT5nZXRQcmV0dHlWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwa2cgPSAkcGtnLT5nZXRBbGlhc09mKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmVkVmVyc2lvbnNCeVBhY2thZ2Vbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV1bJHBrZy0+Z2V0VmVyc2lvbigpXSA9ICRwa2ctPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hbGlhc2VzUGVyUGFja2FnZVskcGFja2FnZS0+aWRdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWxpYXNlc1BlclBhY2thZ2VbJHBhY2thZ2UtPmlkXSBhcyAkYWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+cGFja2FnZXNUb1JlbW92ZVskYWxpYXNQYWNrYWdlLT5pZF0pOwoKICAgICAgICAgICAgICAgIC8vIHJlY29yZCBhbGwgdGhlIHZlcnNpb25zIG9mIHRoZSBwYWNrYWdlIGdyb3VwIHNvIHdlIGNhbiBsaXN0IHRoZW0gbGF0ZXIgaW4gUHJvYmxlbSBvdXRwdXQKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhbGlhc1BhY2thZ2UtPmdldE5hbWVzKGZhbHNlKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZUlkZW50aWNhbERlZmluaXRpb25Mb29rdXBbJGFsaWFzUGFja2FnZS0+aWRdWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VHcm91cFBvaW50ZXJzID0gJHBhY2thZ2VJZGVudGljYWxEZWZpbml0aW9uTG9va3VwWyRhbGlhc1BhY2thZ2UtPmlkXVskbmFtZV07CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlR3JvdXAgPSAkaWRlbnRpY2FsRGVmaW5pdGlvbnNQZXJQYWNrYWdlWyRuYW1lXVskcGFja2FnZUdyb3VwUG9pbnRlcnNbJ2dyb3VwSGFzaCddXVskcGFja2FnZUdyb3VwUG9pbnRlcnNbJ2RlcGVuZGVuY3lIYXNoJ11dOwogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZUdyb3VwIGFzICRwa2cpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcGtnIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICRwa2ctPmdldFByZXR0eVZlcnNpb24oKSA9PT0gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGtnID0gJHBrZy0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZWRWZXJzaW9uc0J5UGFja2FnZVtzcGxfb2JqZWN0X2hhc2goJGFsaWFzUGFja2FnZSldWyRwa2ctPmdldFZlcnNpb24oKV0gPSAkcGtnLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBVc2UgdGhlIGxpc3Qgb2YgbG9ja2VkIHBhY2thZ2VzIHRvIGNvbnN0cmFpbiB0aGUgbG9hZGVkIHBhY2thZ2VzCiAgICAgKiBUaGlzIHdpbGwgcmVkdWNlIHBhY2thZ2VzIHdpdGggc2lnbmlmaWNhbnQgbnVtYmVycyBvZiBoaXN0b3JpY2FsIHZlcnNpb25zIHRvIGEgc21hbGxlciBudW1iZXIKICAgICAqIGFuZCByZWR1Y2UgdGhlIHJlc3VsdGluZyBydWxlIHNldCB0aGF0IGlzIGdlbmVyYXRlZAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG9wdGltaXplSW1wb3NzaWJsZVBhY2thZ2VzQXdheShSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sKQogICAgewogICAgICAgIGlmIChjb3VudCgkcmVxdWVzdC0+Z2V0TG9ja2VkUGFja2FnZXMoKSkgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VJbmRleCA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwb29sLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRpZCA9ICRwYWNrYWdlLT5pZDsKCiAgICAgICAgICAgIC8vIERvIG5vdCByZW1vdmUgaXJyZW1vdmFibGUgcGFja2FnZXMKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5pcnJlbW92YWJsZVBhY2thZ2VzWyRpZF0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBEbyBub3QgcmVtb3ZlIGEgcGFja2FnZSBhbGlhc2VkIGJ5IGFub3RoZXIgcGFja2FnZSwgbm9yIGFsaWFzZXMKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hbGlhc2VzUGVyUGFja2FnZVskaWRdKSB8fCAkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gRG8gbm90IHJlbW92ZSBsb2NrZWQgcGFja2FnZXMKICAgICAgICAgICAgaWYgKCRyZXF1ZXN0LT5pc0ZpeGVkUGFja2FnZSgkcGFja2FnZSkgfHwgJHJlcXVlc3QtPmlzTG9ja2VkUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGFja2FnZUluZGV4WyRwYWNrYWdlLT5nZXROYW1lKCldWyRwYWNrYWdlLT5pZF0gPSAkcGFja2FnZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRMb2NrZWRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIC8vIElmIHRoaXMgbG9ja2VkIHBhY2thZ2UgaXMgbm8gbG9uZ2VyIHJlcXVpcmVkIGJ5IHJvb3Qgb3IgYW55dGhpbmcgaW4gdGhlIHBvb2wsIGl0IG1heSBnZXQgdW5pbnN0YWxsZWQgc28gZG8gbm90IGFwcGx5IGl0cyByZXF1aXJlbWVudHMKICAgICAgICAgICAgLy8gSW4gYSBjYXNlIHdoZXJlIGEgcmVxdWlyZW1lbnQgV0VSRSB0byBhcHBlYXIgaW4gdGhlIHBvb2wgYnkgYSBwYWNrYWdlIHRoYXQgd291bGQgbm90IGJlIHVzZWQsIGl0IHdvdWxkJ3ZlIGJlZW4gdW5sb2NrZWQgYW5kIHNvIG5vdCBmaWx0ZXJlZCBzdGlsbAogICAgICAgICAgICAkaXNVbnVzZWRQYWNrYWdlID0gdHJ1ZTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldE5hbWVzKGZhbHNlKSBhcyAkcGFja2FnZU5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVxdWlyZUNvbnN0cmFpbnRzUGVyUGFja2FnZVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICRpc1VudXNlZFBhY2thZ2UgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRpc1VudXNlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHJlcXVpcmUgPSAkbGluay0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRwYWNrYWdlSW5kZXhbJHJlcXVpcmVdKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRsaW5rQ29uc3RyYWludCA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZUluZGV4WyRyZXF1aXJlXSBhcyAkaWQgPT4gJHJlcXVpcmVkUGtnKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZhbHNlID09PSBDb21waWxpbmdNYXRjaGVyOjptYXRjaCgkbGlua0NvbnN0cmFpbnQsIENvbnN0cmFpbnQ6Ok9QX0VRLCAkcmVxdWlyZWRQa2ctPmdldFZlcnNpb24oKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlRm9yUmVtb3ZhbCgkaWQpOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkcGFja2FnZUluZGV4WyRyZXF1aXJlXVskaWRdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXElnbm9yZUxpc3RQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyOwp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBTb2x2ZXIKewogICAgY29uc3QgQlJBTkNIX0xJVEVSQUxTID0gMDsKICAgIGNvbnN0IEJSQU5DSF9MRVZFTCA9IDE7CgogICAgLyoqIEB2YXIgUG9saWN5SW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJHBvbGljeTsKICAgIC8qKiBAdmFyIFBvb2wgKi8KICAgIHByb3RlY3RlZCAkcG9vbDsKCiAgICAvKiogQHZhciBSdWxlU2V0ICovCiAgICBwcm90ZWN0ZWQgJHJ1bGVzOwoKICAgIC8qKiBAdmFyIFJ1bGVXYXRjaEdyYXBoICovCiAgICBwcm90ZWN0ZWQgJHdhdGNoR3JhcGg7CiAgICAvKiogQHZhciBEZWNpc2lvbnMgKi8KICAgIHByb3RlY3RlZCAkZGVjaXNpb25zOwogICAgLyoqIEB2YXIgQmFzZVBhY2thZ2VbXSAqLwogICAgcHJvdGVjdGVkICRmaXhlZE1hcDsKCiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByb3RlY3RlZCAkcHJvcGFnYXRlSW5kZXg7CiAgICAvKiogQHZhciBtaXhlZFtdICovCiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIFByb2JsZW1bXSAqLwogICAgcHJvdGVjdGVkICRwcm9ibGVtcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxSdWxlW10+ICovCiAgICBwcm90ZWN0ZWQgJGxlYXJuZWRQb29sID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgaW50PiAqLwogICAgcHJvdGVjdGVkICRsZWFybmVkV2h5ID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwdWJsaWMgJHRlc3RGbGFnTGVhcm5lZFBvc2l0aXZlTGl0ZXJhbCA9IGZhbHNlOwoKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQb2xpY3lJbnRlcmZhY2UgJHBvbGljeSwgUG9vbCAkcG9vbCwgSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+cG9saWN5ID0gJHBvbGljeTsKICAgICAgICAkdGhpcy0+cG9vbCA9ICRwb29sOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJ1bGVTZXRTaXplKCkKICAgIHsKICAgICAgICByZXR1cm4gXGNvdW50KCR0aGlzLT5ydWxlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFBvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBvb2woKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cG9vbDsKICAgIH0KCiAgICAvLyBha2Egc29sdmVyX21ha2VydWxlZGVjaXNpb25zCgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYWtlQXNzZXJ0aW9uUnVsZURlY2lzaW9ucygpCiAgICB7CiAgICAgICAgJGRlY2lzaW9uU3RhcnQgPSBcY291bnQoJHRoaXMtPmRlY2lzaW9ucykgLSAxOwoKICAgICAgICAkcnVsZXNDb3VudCA9IFxjb3VudCgkdGhpcy0+cnVsZXMpOwogICAgICAgIGZvciAoJHJ1bGVJbmRleCA9IDA7ICRydWxlSW5kZXggPCAkcnVsZXNDb3VudDsgJHJ1bGVJbmRleCsrKSB7CiAgICAgICAgICAgICRydWxlID0gJHRoaXMtPnJ1bGVzLT5ydWxlQnlJZFskcnVsZUluZGV4XTsKCiAgICAgICAgICAgIGlmICghJHJ1bGUtPmlzQXNzZXJ0aW9uKCkgfHwgJHJ1bGUtPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRsaXRlcmFscyA9ICRydWxlLT5nZXRMaXRlcmFscygpOwogICAgICAgICAgICAkbGl0ZXJhbCA9ICRsaXRlcmFsc1swXTsKCiAgICAgICAgICAgIGlmICghJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlZCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lkZSgkbGl0ZXJhbCwgMSwgJHJ1bGUpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVjaXNpb25zLT5zYXRpc2Z5KCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZvdW5kIGEgY29uZmxpY3QKICAgICAgICAgICAgaWYgKFJ1bGVTZXQ6OlRZUEVfTEVBUk5FRCA9PT0gJHJ1bGUtPmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgJHJ1bGUtPmRpc2FibGUoKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29uZmxpY3QgPSAkdGhpcy0+ZGVjaXNpb25zLT5kZWNpc2lvblJ1bGUoJGxpdGVyYWwpOwoKICAgICAgICAgICAgaWYgKCRjb25mbGljdCAmJiBSdWxlU2V0OjpUWVBFX1BBQ0tBR0UgPT09ICRjb25mbGljdC0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgICAgICAkcHJvYmxlbSA9IG5ldyBQcm9ibGVtKCk7CgogICAgICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUoJHJ1bGUpOwogICAgICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUoJGNvbmZsaWN0KTsKICAgICAgICAgICAgICAgICRydWxlLT5kaXNhYmxlKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvYmxlbXNbXSA9ICRwcm9ibGVtOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNvbmZsaWN0IHdpdGggYW5vdGhlciByb290IHJlcXVpcmUvZml4ZWQgcGFja2FnZQogICAgICAgICAgICAkcHJvYmxlbSA9IG5ldyBQcm9ibGVtKCk7CiAgICAgICAgICAgICRwcm9ibGVtLT5hZGRSdWxlKCRydWxlKTsKICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUoJGNvbmZsaWN0KTsKCiAgICAgICAgICAgIC8vIHB1c2ggYWxsIG9mIG91ciBydWxlcyAoY2FuIG9ubHkgYmUgcm9vdCByZXF1aXJlL2ZpeGVkIHBhY2thZ2UgcnVsZXMpCiAgICAgICAgICAgIC8vIGFzc2VydGluZyB0aGlzIGxpdGVyYWwgb24gdGhlIHByb2JsZW0gc3RhY2sKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJ1bGVzLT5nZXRJdGVyYXRvckZvcihSdWxlU2V0OjpUWVBFX1JFUVVFU1QpIGFzICRhc3NlcnRSdWxlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGFzc2VydFJ1bGUtPmlzRGlzYWJsZWQoKSB8fCAhJGFzc2VydFJ1bGUtPmlzQXNzZXJ0aW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkYXNzZXJ0UnVsZUxpdGVyYWxzID0gJGFzc2VydFJ1bGUtPmdldExpdGVyYWxzKCk7CiAgICAgICAgICAgICAgICAkYXNzZXJ0UnVsZUxpdGVyYWwgPSAkYXNzZXJ0UnVsZUxpdGVyYWxzWzBdOwoKICAgICAgICAgICAgICAgIGlmIChhYnMoJGxpdGVyYWwpICE9PSBhYnMoJGFzc2VydFJ1bGVMaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUoJGFzc2VydFJ1bGUpOwogICAgICAgICAgICAgICAgJGFzc2VydFJ1bGUtPmRpc2FibGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+cHJvYmxlbXNbXSA9ICRwcm9ibGVtOwoKICAgICAgICAgICAgJHRoaXMtPmRlY2lzaW9ucy0+cmVzZXRUb09mZnNldCgkZGVjaXNpb25TdGFydCk7CiAgICAgICAgICAgICRydWxlSW5kZXggPSAtMTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNldHVwRml4ZWRNYXAoUmVxdWVzdCAkcmVxdWVzdCkKICAgIHsKICAgICAgICAkdGhpcy0+Zml4ZWRNYXAgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRGaXhlZFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHRoaXMtPmZpeGVkTWFwWyRwYWNrYWdlLT5pZF0gPSAkcGFja2FnZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrRm9yUm9vdFJlcXVpcmVQcm9ibGVtcyhSZXF1ZXN0ICRyZXF1ZXN0LCBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRSZXF1aXJlcygpIGFzICRwYWNrYWdlTmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmlzSWdub3JlZCgkcGFja2FnZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RhbmNlb2YgSWdub3JlTGlzdFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmZpbHRlckNvbnN0cmFpbnQoJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJHRoaXMtPnBvb2wtPndoYXRQcm92aWRlcygkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgJHByb2JsZW0gPSBuZXcgUHJvYmxlbSgpOwogICAgICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUobmV3IEdlbmVyaWNSdWxlKGFycmF5KCksIFJ1bGU6OlJVTEVfUk9PVF9SRVFVSVJFLCBhcnJheSgncGFja2FnZU5hbWUnID0+ICRwYWNrYWdlTmFtZSwgJ2NvbnN0cmFpbnQnID0+ICRjb25zdHJhaW50KSkpOwogICAgICAgICAgICAgICAgJHRoaXMtPnByb2JsZW1zW10gPSAkcHJvYmxlbTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gTG9ja1RyYW5zYWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzb2x2ZShSZXF1ZXN0ICRyZXF1ZXN0LCBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciA9ICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID86IFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5OjppZ25vcmVOb3RoaW5nKCk7CgogICAgICAgICR0aGlzLT5zZXR1cEZpeGVkTWFwKCRyZXF1ZXN0KTsKCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdHZW5lcmF0aW5nIHJ1bGVzJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAkcnVsZVNldEdlbmVyYXRvciA9IG5ldyBSdWxlU2V0R2VuZXJhdG9yKCR0aGlzLT5wb2xpY3ksICR0aGlzLT5wb29sKTsKICAgICAgICAkdGhpcy0+cnVsZXMgPSAkcnVsZVNldEdlbmVyYXRvci0+Z2V0UnVsZXNGb3IoJHJlcXVlc3QsICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKTsKICAgICAgICB1bnNldCgkcnVsZVNldEdlbmVyYXRvcik7CiAgICAgICAgJHRoaXMtPmNoZWNrRm9yUm9vdFJlcXVpcmVQcm9ibGVtcygkcmVxdWVzdCwgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwogICAgICAgICR0aGlzLT5kZWNpc2lvbnMgPSBuZXcgRGVjaXNpb25zKCR0aGlzLT5wb29sKTsKICAgICAgICAkdGhpcy0+d2F0Y2hHcmFwaCA9IG5ldyBSdWxlV2F0Y2hHcmFwaDsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJ1bGVzIGFzICRydWxlKSB7CiAgICAgICAgICAgICR0aGlzLT53YXRjaEdyYXBoLT5pbnNlcnQobmV3IFJ1bGVXYXRjaE5vZGUoJHJ1bGUpKTsKICAgICAgICB9CgogICAgICAgIC8qIG1ha2UgZGVjaXNpb25zIGJhc2VkIG9uIHJvb3QgcmVxdWlyZS9maXggYXNzZXJ0aW9ucyAqLwogICAgICAgICR0aGlzLT5tYWtlQXNzZXJ0aW9uUnVsZURlY2lzaW9ucygpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1Jlc29sdmluZyBkZXBlbmRlbmNpZXMgdGhyb3VnaCBTQVQnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICRiZWZvcmUgPSBtaWNyb3RpbWUodHJ1ZSk7CiAgICAgICAgJHRoaXMtPnJ1blNhdCgpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignRGVwZW5kZW5jeSByZXNvbHV0aW9uIGNvbXBsZXRlZCBpbiAlLjNmIHNlY29uZHMnLCBtaWNyb3RpbWUodHJ1ZSkgLSAkYmVmb3JlKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICBpZiAoJHRoaXMtPnByb2JsZW1zKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTb2x2ZXJQcm9ibGVtc0V4Y2VwdGlvbigkdGhpcy0+cHJvYmxlbXMsICR0aGlzLT5sZWFybmVkUG9vbCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IExvY2tUcmFuc2FjdGlvbigkdGhpcy0+cG9vbCwgJHJlcXVlc3QtPmdldFByZXNlbnRNYXAoKSwgJHJlcXVlc3QtPmdldEZpeGVkUGFja2FnZXNNYXAoKSwgJHRoaXMtPmRlY2lzaW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIGRlY2lzaW9uIGFuZCBwcm9wYWdhdGVzIGl0IHRvIGFsbCBydWxlcy4KICAgICAqCiAgICAgKiBFdmFsdWF0ZXMgZWFjaCB0ZXJtIGFmZmVjdGVkIGJ5IHRoZSBkZWNpc2lvbiAobGlua2VkIHRocm91Z2ggd2F0Y2hlcykKICAgICAqIElmIHdlIGZpbmQgdW5pdCBydWxlcyB3ZSBtYWtlIG5ldyBkZWNpc2lvbnMgYmFzZWQgb24gdGhlbQogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICRsZXZlbAogICAgICogQHJldHVybiBSdWxlfG51bGwgQSBydWxlIG9uIGNvbmZsaWN0LCBvdGhlcndpc2UgbnVsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByb3BhZ2F0ZSgkbGV2ZWwpCiAgICB7CiAgICAgICAgd2hpbGUgKCR0aGlzLT5kZWNpc2lvbnMtPnZhbGlkT2Zmc2V0KCR0aGlzLT5wcm9wYWdhdGVJbmRleCkpIHsKICAgICAgICAgICAgJGRlY2lzaW9uID0gJHRoaXMtPmRlY2lzaW9ucy0+YXRPZmZzZXQoJHRoaXMtPnByb3BhZ2F0ZUluZGV4KTsKCiAgICAgICAgICAgICRjb25mbGljdCA9ICR0aGlzLT53YXRjaEdyYXBoLT5wcm9wYWdhdGVMaXRlcmFsKAogICAgICAgICAgICAgICAgJGRlY2lzaW9uW0RlY2lzaW9uczo6REVDSVNJT05fTElURVJBTF0sCiAgICAgICAgICAgICAgICAkbGV2ZWwsCiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVjaXNpb25zCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAkdGhpcy0+cHJvcGFnYXRlSW5kZXgrKzsKCiAgICAgICAgICAgIGlmICgkY29uZmxpY3QpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29uZmxpY3Q7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmV2ZXJ0cyBhIGRlY2lzaW9uIGF0IHRoZSBnaXZlbiBsZXZlbC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJldmVydCgkbGV2ZWwpCiAgICB7CiAgICAgICAgd2hpbGUgKCEkdGhpcy0+ZGVjaXNpb25zLT5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgJGxpdGVyYWwgPSAkdGhpcy0+ZGVjaXNpb25zLT5sYXN0TGl0ZXJhbCgpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5kZWNpc2lvbnMtPnVuZGVjaWRlZCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGVjaXNpb25MZXZlbCA9ICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lzaW9uTGV2ZWwoJGxpdGVyYWwpOwoKICAgICAgICAgICAgaWYgKCRkZWNpc2lvbkxldmVsIDw9ICRsZXZlbCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbnMtPnJldmVydExhc3QoKTsKICAgICAgICAgICAgJHRoaXMtPnByb3BhZ2F0ZUluZGV4ID0gXGNvdW50KCR0aGlzLT5kZWNpc2lvbnMpOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKCFlbXB0eSgkdGhpcy0+YnJhbmNoZXMpICYmICR0aGlzLT5icmFuY2hlc1tcY291bnQoJHRoaXMtPmJyYW5jaGVzKSAtIDFdW3NlbGY6OkJSQU5DSF9MRVZFTF0gPj0gJGxldmVsKSB7CiAgICAgICAgICAgIGFycmF5X3BvcCgkdGhpcy0+YnJhbmNoZXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHNldHByb3BhZ2F0ZWxlYXJuCiAgICAgKgogICAgICogYWRkIGZyZWUgZGVjaXNpb24gKGEgcG9zaXRpdmUgbGl0ZXJhbCkgdG8gZGVjaXNpb24gcXVldWUKICAgICAqIGluY3JlYXNlIGxldmVsIGFuZCBwcm9wYWdhdGUgZGVjaXNpb24KICAgICAqIHJldHVybiBpZiBubyBjb25mbGljdC4KICAgICAqCiAgICAgKiBpbiBjb25mbGljdCBjYXNlLCBhbmFseXplIGNvbmZsaWN0IHJ1bGUsIGFkZCByZXN1bHRpbmcKICAgICAqIHJ1bGUgdG8gbGVhcm50IHJ1bGUgc2V0LCBtYWtlIGRlY2lzaW9uIGZyb20gbGVhcm50CiAgICAgKiBydWxlIChhbHdheXMgdW5pdCkgYW5kIHJlLXByb3BhZ2F0ZS4KICAgICAqCiAgICAgKiByZXR1cm5zIHRoZSBuZXcgc29sdmVyIGxldmVsIG9yIDAgaWYgdW5zb2x2YWJsZQogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAkbGV2ZWwKICAgICAqIEBwYXJhbSAgc3RyaW5nfGludCAkbGl0ZXJhbAogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXRQcm9wYWdhdGVMZWFybigkbGV2ZWwsICRsaXRlcmFsLCBSdWxlICRydWxlKQogICAgewogICAgICAgICRsZXZlbCsrOwoKICAgICAgICAkdGhpcy0+ZGVjaXNpb25zLT5kZWNpZGUoJGxpdGVyYWwsICRsZXZlbCwgJHJ1bGUpOwoKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAkcnVsZSA9ICR0aGlzLT5wcm9wYWdhdGUoJGxldmVsKTsKCiAgICAgICAgICAgIGlmICghJHJ1bGUpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGxldmVsID09IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+YW5hbHl6ZVVuc29sdmFibGUoJHJ1bGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjb25mbGljdAogICAgICAgICAgICBsaXN0KCRsZWFybkxpdGVyYWwsICRuZXdMZXZlbCwgJG5ld1J1bGUsICR3aHkpID0gJHRoaXMtPmFuYWx5emUoJGxldmVsLCAkcnVsZSk7CgogICAgICAgICAgICBpZiAoJG5ld0xldmVsIDw9IDAgfHwgJG5ld0xldmVsID49ICRsZXZlbCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNvbHZlckJ1Z0V4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAiVHJ5aW5nIHRvIHJldmVydCB0byBpbnZhbGlkIGxldmVsICIuJG5ld0xldmVsLiIgZnJvbSBsZXZlbCAiLiRsZXZlbC4iLiIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRsZXZlbCA9ICRuZXdMZXZlbDsKCiAgICAgICAgICAgICR0aGlzLT5yZXZlcnQoJGxldmVsKTsKCiAgICAgICAgICAgICR0aGlzLT5ydWxlcy0+YWRkKCRuZXdSdWxlLCBSdWxlU2V0OjpUWVBFX0xFQVJORUQpOwoKICAgICAgICAgICAgJHRoaXMtPmxlYXJuZWRXaHlbc3BsX29iamVjdF9oYXNoKCRuZXdSdWxlKV0gPSAkd2h5OwoKICAgICAgICAgICAgJHJ1bGVOb2RlID0gbmV3IFJ1bGVXYXRjaE5vZGUoJG5ld1J1bGUpOwogICAgICAgICAgICAkcnVsZU5vZGUtPndhdGNoMk9uSGlnaGVzdCgkdGhpcy0+ZGVjaXNpb25zKTsKICAgICAgICAgICAgJHRoaXMtPndhdGNoR3JhcGgtPmluc2VydCgkcnVsZU5vZGUpOwoKICAgICAgICAgICAgJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlKCRsZWFybkxpdGVyYWwsICRsZXZlbCwgJG5ld1J1bGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRsZXZlbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgaW50ICAgJGxldmVsCiAgICAgKiBAcGFyYW0gIGludFtdICRkZWNpc2lvblF1ZXVlCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNlbGVjdEFuZEluc3RhbGwoJGxldmVsLCBhcnJheSAkZGVjaXNpb25RdWV1ZSwgUnVsZSAkcnVsZSkKICAgIHsKICAgICAgICAvLyBjaG9vc2UgYmVzdCBwYWNrYWdlIHRvIGluc3RhbGwgZnJvbSBkZWNpc2lvblF1ZXVlCiAgICAgICAgJGxpdGVyYWxzID0gJHRoaXMtPnBvbGljeS0+c2VsZWN0UHJlZmVycmVkUGFja2FnZXMoJHRoaXMtPnBvb2wsICRkZWNpc2lvblF1ZXVlLCAkcnVsZS0+Z2V0UmVxdWlyZWRQYWNrYWdlKCkpOwoKICAgICAgICAkc2VsZWN0ZWRMaXRlcmFsID0gYXJyYXlfc2hpZnQoJGxpdGVyYWxzKTsKCiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIG11bHRpcGxlIGNhbmRpZGF0ZXMsIHRoZW4gYnJhbmNoCiAgICAgICAgaWYgKFxjb3VudCgkbGl0ZXJhbHMpKSB7CiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlc1tdID0gYXJyYXkoJGxpdGVyYWxzLCAkbGV2ZWwpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRQcm9wYWdhdGVMZWFybigkbGV2ZWwsICRzZWxlY3RlZExpdGVyYWwsICRydWxlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgaW50ICAgJGxldmVsCiAgICAgKiBAcmV0dXJuIGFycmF5e2ludCwgaW50LCBHZW5lcmljUnVsZSwgaW50fQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYW5hbHl6ZSgkbGV2ZWwsIFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgJGFuYWx5emVkUnVsZSA9ICRydWxlOwogICAgICAgICRydWxlTGV2ZWwgPSAxOwogICAgICAgICRudW0gPSAwOwogICAgICAgICRsMW51bSA9IDA7CiAgICAgICAgJHNlZW4gPSBhcnJheSgpOwogICAgICAgICRsZWFybmVkTGl0ZXJhbHMgPSBhcnJheShudWxsKTsKCiAgICAgICAgJGRlY2lzaW9uSWQgPSBcY291bnQoJHRoaXMtPmRlY2lzaW9ucyk7CgogICAgICAgICR0aGlzLT5sZWFybmVkUG9vbFtdID0gYXJyYXkoKTsKCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgJHRoaXMtPmxlYXJuZWRQb29sW1xjb3VudCgkdGhpcy0+bGVhcm5lZFBvb2wpIC0gMV1bXSA9ICRydWxlOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHJ1bGUtPmdldExpdGVyYWxzKCkgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgIC8vIG11bHRpY29uZmxpY3RydWxlIGlzIHJlYWxseSBhIGJ1bmNoIG9mIHJ1bGVzIGluIG9uZSwgc28gc29tZSBtYXkgbm90IGhhdmUgZmluaXNoZWQgcHJvcGFnYXRpbmcgeWV0CiAgICAgICAgICAgICAgICBpZiAoJHJ1bGUgaW5zdGFuY2VvZiBNdWx0aUNvbmZsaWN0UnVsZSAmJiAhJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlZCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBza2lwIHRoZSBvbmUgdHJ1ZSBsaXRlcmFsCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmRlY2lzaW9ucy0+c2F0aXNmeSgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNlZW5bYWJzKCRsaXRlcmFsKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkc2VlblthYnMoJGxpdGVyYWwpXSA9IHRydWU7CgogICAgICAgICAgICAgICAgJGwgPSAkdGhpcy0+ZGVjaXNpb25zLT5kZWNpc2lvbkxldmVsKCRsaXRlcmFsKTsKCiAgICAgICAgICAgICAgICBpZiAoMSA9PT0gJGwpIHsKICAgICAgICAgICAgICAgICAgICAkbDFudW0rKzsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkbGV2ZWwgPT09ICRsKSB7CiAgICAgICAgICAgICAgICAgICAgJG51bSsrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBub3QgbGV2ZWwxIG9yIGNvbmZsaWN0IGxldmVsLCBhZGQgdG8gbmV3IHJ1bGUKICAgICAgICAgICAgICAgICAgICAkbGVhcm5lZExpdGVyYWxzW10gPSAkbGl0ZXJhbDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRsID4gJHJ1bGVMZXZlbCkgewogICAgICAgICAgICAgICAgICAgICAgICAkcnVsZUxldmVsID0gJGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCRsaXRlcmFsKTsKCiAgICAgICAgICAgICRsMXJldHJ5ID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUgKCRsMXJldHJ5KSB7CiAgICAgICAgICAgICAgICAkbDFyZXRyeSA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIGlmICgwID09PSAkbnVtICYmIDAgPT09IC0tJGwxbnVtKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYWxsIGxldmVsIDEgbGl0ZXJhbHMgZG9uZQogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGRlY2lzaW9uSWQgPD0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29sdmVyQnVnRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlYWNoZWQgaW52YWxpZCBkZWNpc2lvbiBpZCAkZGVjaXNpb25JZCB3aGlsZSBsb29raW5nIHRocm91Z2ggJHJ1bGUgZm9yIGEgbGl0ZXJhbCBwcmVzZW50IGluIHRoZSBhbmFseXplZCBydWxlICRhbmFseXplZFJ1bGUuIgogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9uSWQtLTsKCiAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9uID0gJHRoaXMtPmRlY2lzaW9ucy0+YXRPZmZzZXQoJGRlY2lzaW9uSWQpOwogICAgICAgICAgICAgICAgICAgICRsaXRlcmFsID0gJGRlY2lzaW9uW0RlY2lzaW9uczo6REVDSVNJT05fTElURVJBTF07CgogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkc2VlblthYnMoJGxpdGVyYWwpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHVuc2V0KCRzZWVuW2FicygkbGl0ZXJhbCldKTsKCiAgICAgICAgICAgICAgICBpZiAoMCAhPT0gJG51bSAmJiAwID09PSAtLSRudW0pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpdGVyYWwgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT50ZXN0RmxhZ0xlYXJuZWRQb3NpdGl2ZUxpdGVyYWwgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbGVhcm5lZExpdGVyYWxzWzBdID0gLSRsaXRlcmFsOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRsMW51bSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxlYXJuZWRMaXRlcmFscyBhcyAkaSA9PiAkbGVhcm5lZExpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpICE9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkc2VlblthYnMoJGxlYXJuZWRMaXRlcmFsKV0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgbGV2ZWwgMSBtYXJrcyBsZWZ0CiAgICAgICAgICAgICAgICAgICAgJGwxbnVtKys7CiAgICAgICAgICAgICAgICAgICAgJGwxcmV0cnkgPSB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb24gPSAkdGhpcy0+ZGVjaXNpb25zLT5hdE9mZnNldCgkZGVjaXNpb25JZCk7CiAgICAgICAgICAgICAgICAgICAgJHJ1bGUgPSAkZGVjaXNpb25bRGVjaXNpb25zOjpERUNJU0lPTl9SRUFTT05dOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJHJ1bGUgaW5zdGFuY2VvZiBNdWx0aUNvbmZsaWN0UnVsZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBvbmx5IGV2ZXIgZXhhY3RseSBvbmUgcG9zaXRpdmUgZGVjaXNpb24gaW4gYSBtdWx0aWNvbmZsaWN0IHJ1bGUKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHJ1bGUtPmdldExpdGVyYWxzKCkgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHNlZW5bYWJzKCRsaXRlcmFsKV0pICYmICR0aGlzLT5kZWNpc2lvbnMtPnNhdGlzZnkoLSRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5sZWFybmVkUG9vbFtcY291bnQoJHRoaXMtPmxlYXJuZWRQb29sKSAtIDFdW10gPSAkcnVsZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbCA9ICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lzaW9uTGV2ZWwoJGxpdGVyYWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgxID09PSAkbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbDFudW0rKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGxldmVsID09PSAkbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbnVtKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm90IGxldmVsMSBvciBjb25mbGljdCBsZXZlbCwgYWRkIHRvIG5ldyBydWxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsZWFybmVkTGl0ZXJhbHNbXSA9ICRsaXRlcmFsOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsID4gJHJ1bGVMZXZlbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJ1bGVMZXZlbCA9ICRsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzZWVuW2FicygkbGl0ZXJhbCldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGwxcmV0cnkgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRlY2lzaW9uID0gJHRoaXMtPmRlY2lzaW9ucy0+YXRPZmZzZXQoJGRlY2lzaW9uSWQpOwogICAgICAgICAgICAkcnVsZSA9ICRkZWNpc2lvbltEZWNpc2lvbnM6OkRFQ0lTSU9OX1JFQVNPTl07CiAgICAgICAgfQoKICAgICAgICAkd2h5ID0gXGNvdW50KCR0aGlzLT5sZWFybmVkUG9vbCkgLSAxOwoKICAgICAgICBpZiAoISRsZWFybmVkTGl0ZXJhbHNbMF0pIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFNvbHZlckJ1Z0V4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJEaWQgbm90IGZpbmQgYSBsZWFybmFibGUgbGl0ZXJhbCBpbiBhbmFseXplZCBydWxlICRhbmFseXplZFJ1bGUuIgogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJG5ld1J1bGUgPSBuZXcgR2VuZXJpY1J1bGUoJGxlYXJuZWRMaXRlcmFscywgUnVsZTo6UlVMRV9MRUFSTkVELCAkd2h5KTsKCiAgICAgICAgcmV0dXJuIGFycmF5KCRsZWFybmVkTGl0ZXJhbHNbMF0sICRydWxlTGV2ZWwsICRuZXdSdWxlLCAkd2h5KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHRydWU+ICRydWxlU2VlbgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYW5hbHl6ZVVuc29sdmFibGVSdWxlKFByb2JsZW0gJHByb2JsZW0sIFJ1bGUgJGNvbmZsaWN0UnVsZSwgYXJyYXkgJiRydWxlU2VlbikKICAgIHsKICAgICAgICAkd2h5ID0gc3BsX29iamVjdF9oYXNoKCRjb25mbGljdFJ1bGUpOwogICAgICAgICRydWxlU2Vlblskd2h5XSA9IHRydWU7CgogICAgICAgIGlmICgkY29uZmxpY3RSdWxlLT5nZXRUeXBlKCkgPT0gUnVsZVNldDo6VFlQRV9MRUFSTkVEKSB7CiAgICAgICAgICAgICRsZWFybmVkV2h5ID0gJHRoaXMtPmxlYXJuZWRXaHlbJHdoeV07CiAgICAgICAgICAgICRwcm9ibGVtUnVsZXMgPSAkdGhpcy0+bGVhcm5lZFBvb2xbJGxlYXJuZWRXaHldOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHByb2JsZW1SdWxlcyBhcyAkcHJvYmxlbVJ1bGUpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHJ1bGVTZWVuW3NwbF9vYmplY3RfaGFzaCgkcHJvYmxlbVJ1bGUpXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YW5hbHl6ZVVuc29sdmFibGVSdWxlKCRwcm9ibGVtLCAkcHJvYmxlbVJ1bGUsICRydWxlU2Vlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgkY29uZmxpY3RSdWxlLT5nZXRUeXBlKCkgPT0gUnVsZVNldDo6VFlQRV9QQUNLQUdFKSB7CiAgICAgICAgICAgIC8vIHBhY2thZ2UgcnVsZXMgY2Fubm90IGJlIHBhcnQgb2YgYSBwcm9ibGVtCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRwcm9ibGVtLT5uZXh0U2VjdGlvbigpOwogICAgICAgICRwcm9ibGVtLT5hZGRSdWxlKCRjb25mbGljdFJ1bGUpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhbmFseXplVW5zb2x2YWJsZShSdWxlICRjb25mbGljdFJ1bGUpCiAgICB7CiAgICAgICAgJHByb2JsZW0gPSBuZXcgUHJvYmxlbSgpOwogICAgICAgICRwcm9ibGVtLT5hZGRSdWxlKCRjb25mbGljdFJ1bGUpOwoKICAgICAgICAkcnVsZVNlZW4gPSBhcnJheSgpOwoKICAgICAgICAkdGhpcy0+YW5hbHl6ZVVuc29sdmFibGVSdWxlKCRwcm9ibGVtLCAkY29uZmxpY3RSdWxlLCAkcnVsZVNlZW4pOwoKICAgICAgICAkdGhpcy0+cHJvYmxlbXNbXSA9ICRwcm9ibGVtOwoKICAgICAgICAkc2VlbiA9IGFycmF5KCk7CiAgICAgICAgJGxpdGVyYWxzID0gJGNvbmZsaWN0UnVsZS0+Z2V0TGl0ZXJhbHMoKTsKCiAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRsaXRlcmFsKSB7CiAgICAgICAgICAgIC8vIHNraXAgdGhlIG9uZSB0cnVlIGxpdGVyYWwKICAgICAgICAgICAgaWYgKCR0aGlzLT5kZWNpc2lvbnMtPnNhdGlzZnkoJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc2VlblthYnMoJGxpdGVyYWwpXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZGVjaXNpb25zIGFzICRkZWNpc2lvbikgewogICAgICAgICAgICAkbGl0ZXJhbCA9ICRkZWNpc2lvbltEZWNpc2lvbnM6OkRFQ0lTSU9OX0xJVEVSQUxdOwoKICAgICAgICAgICAgLy8gc2tpcCBsaXRlcmFscyB0aGF0IGFyZSBub3QgaW4gdGhpcyBydWxlCiAgICAgICAgICAgIGlmICghaXNzZXQoJHNlZW5bYWJzKCRsaXRlcmFsKV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHdoeSA9ICRkZWNpc2lvbltEZWNpc2lvbnM6OkRFQ0lTSU9OX1JFQVNPTl07CgogICAgICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZSgkd2h5KTsKICAgICAgICAgICAgJHRoaXMtPmFuYWx5emVVbnNvbHZhYmxlUnVsZSgkcHJvYmxlbSwgJHdoeSwgJHJ1bGVTZWVuKTsKCiAgICAgICAgICAgICRsaXRlcmFscyA9ICR3aHktPmdldExpdGVyYWxzKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgIC8vIHNraXAgdGhlIG9uZSB0cnVlIGxpdGVyYWwKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVjaXNpb25zLT5zYXRpc2Z5KCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHNlZW5bYWJzKCRsaXRlcmFsKV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIGVuYWJsZS9kaXNhYmxlIGxlYXJudCBydWxlcwogICAgICoKICAgICAqIHdlIGhhdmUgZW5hYmxlZCBvciBkaXNhYmxlZCBzb21lIG9mIG91ciBydWxlcy4gV2Ugbm93IHJlLWVuYWJsZSBhbGwKICAgICAqIG9mIG91ciBsZWFybnQgcnVsZXMgZXhjZXB0IHRoZSBvbmVzIHRoYXQgd2VyZSBsZWFybnQgZnJvbSBydWxlcyB0aGF0CiAgICAgKiBhcmUgbm93IGRpc2FibGVkLgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVuYWJsZURpc2FibGVMZWFybmVkUnVsZXMoKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ydWxlcy0+Z2V0SXRlcmF0b3JGb3IoUnVsZVNldDo6VFlQRV9MRUFSTkVEKSBhcyAkcnVsZSkgewogICAgICAgICAgICAkd2h5ID0gJHRoaXMtPmxlYXJuZWRXaHlbc3BsX29iamVjdF9oYXNoKCRydWxlKV07CiAgICAgICAgICAgICRwcm9ibGVtUnVsZXMgPSAkdGhpcy0+bGVhcm5lZFBvb2xbJHdoeV07CgogICAgICAgICAgICAkZm91bmREaXNhYmxlZCA9IGZhbHNlOwogICAgICAgICAgICBmb3JlYWNoICgkcHJvYmxlbVJ1bGVzIGFzICRwcm9ibGVtUnVsZSkgewogICAgICAgICAgICAgICAgaWYgKCRwcm9ibGVtUnVsZS0+aXNEaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGZvdW5kRGlzYWJsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGZvdW5kRGlzYWJsZWQgJiYgJHJ1bGUtPmlzRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAkcnVsZS0+ZGlzYWJsZSgpOwogICAgICAgICAgICB9IGVsc2VpZiAoISRmb3VuZERpc2FibGVkICYmICRydWxlLT5pc0Rpc2FibGVkKCkpIHsKICAgICAgICAgICAgICAgICRydWxlLT5lbmFibGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJ1blNhdCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb3BhZ2F0ZUluZGV4ID0gMDsKCiAgICAgICAgLyoKICAgICAgICAgKiBoZXJlJ3MgdGhlIG1haW4gbG9vcDoKICAgICAgICAgKiAxKSBwcm9wYWdhdGUgbmV3IGRlY2lzaW9ucyAob25seSBuZWVkZWQgb25jZSkKICAgICAgICAgKiAyKSBmdWxmaWxsIHJvb3QgcmVxdWlyZXMvZml4ZWQgcGFja2FnZXMKICAgICAgICAgKiAzKSBmdWxmaWxsIGFsbCB1bnJlc29sdmVkIHJ1bGVzCiAgICAgICAgICogNCkgbWluaW1hbGl6ZSBzb2x1dGlvbiBpZiB3ZSBoYWQgY2hvaWNlcwogICAgICAgICAqIGlmIHdlIGVuY291bnRlciBhIHByb2JsZW0sIHdlIHJld2luZCB0byBhIHNhZmUgbGV2ZWwgYW5kIHJlc3RhcnQKICAgICAgICAgKiB3aXRoIHN0ZXAgMQogICAgICAgICAqLwoKICAgICAgICAkbGV2ZWwgPSAxOwogICAgICAgICRzeXN0ZW1MZXZlbCA9ICRsZXZlbCArIDE7CgogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGlmICgxID09PSAkbGV2ZWwpIHsKICAgICAgICAgICAgICAgICRjb25mbGljdFJ1bGUgPSAkdGhpcy0+cHJvcGFnYXRlKCRsZXZlbCk7CiAgICAgICAgICAgICAgICBpZiAobnVsbCAhPT0gJGNvbmZsaWN0UnVsZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+YW5hbHl6ZVVuc29sdmFibGUoJGNvbmZsaWN0UnVsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGhhbmRsZSByb290IHJlcXVpcmUvZml4ZWQgcGFja2FnZSBydWxlcwogICAgICAgICAgICBpZiAoJGxldmVsIDwgJHN5c3RlbUxldmVsKSB7CiAgICAgICAgICAgICAgICAkaXRlcmF0b3IgPSAkdGhpcy0+cnVsZXMtPmdldEl0ZXJhdG9yRm9yKFJ1bGVTZXQ6OlRZUEVfUkVRVUVTVCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkaXRlcmF0b3IgYXMgJHJ1bGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHJ1bGUtPmlzRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRkZWNpc2lvblF1ZXVlID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vbmVTYXRpc2ZpZWQgPSB0cnVlOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHJ1bGUtPmdldExpdGVyYWxzKCkgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVjaXNpb25zLT5zYXRpc2Z5KCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub25lU2F0aXNmaWVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpdGVyYWwgPiAwICYmICR0aGlzLT5kZWNpc2lvbnMtPnVuZGVjaWRlZCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb25RdWV1ZVtdID0gJGxpdGVyYWw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbm9uZVNhdGlzZmllZCAmJiBcY291bnQoJGRlY2lzaW9uUXVldWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBhbnkgb2YgdGhlIG9wdGlvbnMgaW4gdGhlIGRlY2lzaW9uIHF1ZXVlIGFyZSBmaXhlZCwgb25seSB1c2UgdGhvc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcnVuZWRRdWV1ZSA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGVjaXNpb25RdWV1ZSBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Zml4ZWRNYXBbYWJzKCRsaXRlcmFsKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcnVuZWRRdWV1ZVtdID0gJGxpdGVyYWw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkcHJ1bmVkUXVldWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9uUXVldWUgPSAkcHJ1bmVkUXVldWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbm9uZVNhdGlzZmllZCAmJiBcY291bnQoJGRlY2lzaW9uUXVldWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkb0xldmVsID0gJGxldmVsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxldmVsID0gJHRoaXMtPnNlbGVjdEFuZEluc3RhbGwoJGxldmVsLCAkZGVjaXNpb25RdWV1ZSwgJHJ1bGUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkbGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxldmVsIDw9ICRvTGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkc3lzdGVtTGV2ZWwgPSAkbGV2ZWwgKyAxOwoKICAgICAgICAgICAgICAgIC8vIHJvb3QgcmVxdWlyZXMvZml4ZWQgcGFja2FnZXMgbGVmdAogICAgICAgICAgICAgICAgJGl0ZXJhdG9yLT5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoJGl0ZXJhdG9yLT52YWxpZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkbGV2ZWwgPCAkc3lzdGVtTGV2ZWwpIHsKICAgICAgICAgICAgICAgICRzeXN0ZW1MZXZlbCA9ICRsZXZlbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJ1bGVzQ291bnQgPSBcY291bnQoJHRoaXMtPnJ1bGVzKTsKICAgICAgICAgICAgJHBhc3MgPSAxOwoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdMb29raW5nIGF0IGFsbCBydWxlcy4nLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICBmb3IgKCRpID0gMCwgJG4gPSAwOyAkbiA8ICRydWxlc0NvdW50OyAkaSsrLCAkbisrKSB7CiAgICAgICAgICAgICAgICBpZiAoJGkgPT0gJHJ1bGVzQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoMSA9PT0gJHBhc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJTb21ldGhpbmcncyBjaGFuZ2VkLCBsb29raW5nIGF0IGFsbCBydWxlcyBhZ2FpbiAocGFzcyAjJHBhc3MpIiwgZmFsc2UsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5vdmVyd3JpdGVFcnJvcigiU29tZXRoaW5nJ3MgY2hhbmdlZCwgbG9va2luZyBhdCBhbGwgcnVsZXMgYWdhaW4gKHBhc3MgIyRwYXNzKSIsIGZhbHNlLCBudWxsLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGkgPSAwOwogICAgICAgICAgICAgICAgICAgICRwYXNzKys7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJ1bGUgPSAkdGhpcy0+cnVsZXMtPnJ1bGVCeUlkWyRpXTsKICAgICAgICAgICAgICAgICRsaXRlcmFscyA9ICRydWxlLT5nZXRMaXRlcmFscygpOwoKICAgICAgICAgICAgICAgIGlmICgkcnVsZS0+aXNEaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGRlY2lzaW9uUXVldWUgPSBhcnJheSgpOwoKICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0CiAgICAgICAgICAgICAgICAvLyAqIGFsbCBuZWdhdGl2ZSBsaXRlcmFscyBhcmUgaW5zdGFsbGVkCiAgICAgICAgICAgICAgICAvLyAqIG5vIHBvc2l0aXZlIGxpdGVyYWwgaXMgaW5zdGFsbGVkCiAgICAgICAgICAgICAgICAvLyBpLmUuIHRoZSBydWxlIGlzIG5vdCBmdWxmaWxsZWQgYW5kIHdlCiAgICAgICAgICAgICAgICAvLyBqdXN0IG5lZWQgdG8gZGVjaWRlIG9uIHRoZSBwb3NpdGl2ZSBsaXRlcmFscwogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkbGl0ZXJhbCA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlZEluc3RhbGwoJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOyAvLyBuZXh0IHJ1bGUKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVjaXNpb25zLT5kZWNpZGVkSW5zdGFsbCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7IC8vIG5leHQgcnVsZQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVjaXNpb25zLT51bmRlY2lkZWQoJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb25RdWV1ZVtdID0gJGxpdGVyYWw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbmVlZCB0byBoYXZlIGF0IGxlYXN0IDIgaXRlbSB0byBwaWNrIGZyb20KICAgICAgICAgICAgICAgIGlmIChcY291bnQoJGRlY2lzaW9uUXVldWUpIDwgMikgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRsZXZlbCA9ICR0aGlzLT5zZWxlY3RBbmRJbnN0YWxsKCRsZXZlbCwgJGRlY2lzaW9uUXVldWUsICRydWxlKTsKCiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJGxldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHNvbWV0aGluZyBjaGFuZ2VkLCBzbyBsb29rIGF0IGFsbCBydWxlcyBhZ2FpbgogICAgICAgICAgICAgICAgJHJ1bGVzQ291bnQgPSBcY291bnQoJHRoaXMtPnJ1bGVzKTsKICAgICAgICAgICAgICAgICRuID0gLTE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkbGV2ZWwgPCAkc3lzdGVtTGV2ZWwpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBtaW5pbWl6YXRpb24gc3RlcAogICAgICAgICAgICBpZiAoXGNvdW50KCR0aGlzLT5icmFuY2hlcykpIHsKICAgICAgICAgICAgICAgICRsYXN0TGl0ZXJhbCA9IG51bGw7CiAgICAgICAgICAgICAgICAkbGFzdExldmVsID0gbnVsbDsKICAgICAgICAgICAgICAgICRsYXN0QnJhbmNoSW5kZXggPSAwOwogICAgICAgICAgICAgICAgJGxhc3RCcmFuY2hPZmZzZXQgPSAwOwoKICAgICAgICAgICAgICAgIGZvciAoJGkgPSBcY291bnQoJHRoaXMtPmJyYW5jaGVzKSAtIDE7ICRpID49IDA7ICRpLS0pIHsKICAgICAgICAgICAgICAgICAgICBsaXN0KCRsaXRlcmFscywgJGwpID0gJHRoaXMtPmJyYW5jaGVzWyRpXTsKCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRvZmZzZXQgPT4gJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsaXRlcmFsICYmICRsaXRlcmFsID4gMCAmJiAkdGhpcy0+ZGVjaXNpb25zLT5kZWNpc2lvbkxldmVsKCRsaXRlcmFsKSA+ICRsICsgMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxhc3RMaXRlcmFsID0gJGxpdGVyYWw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGFzdEJyYW5jaEluZGV4ID0gJGk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGFzdEJyYW5jaE9mZnNldCA9ICRvZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGFzdExldmVsID0gJGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRsYXN0TGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5icmFuY2hlc1skbGFzdEJyYW5jaEluZGV4XVtzZWxmOjpCUkFOQ0hfTElURVJBTFNdWyRsYXN0QnJhbmNoT2Zmc2V0XSk7CgogICAgICAgICAgICAgICAgICAgICRsZXZlbCA9ICRsYXN0TGV2ZWw7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJldmVydCgkbGV2ZWwpOwoKICAgICAgICAgICAgICAgICAgICAkd2h5ID0gJHRoaXMtPmRlY2lzaW9ucy0+bGFzdFJlYXNvbigpOwoKICAgICAgICAgICAgICAgICAgICAkbGV2ZWwgPSAkdGhpcy0+c2V0UHJvcGFnYXRlTGVhcm4oJGxldmVsLCAkbGFzdExpdGVyYWwsICR3aHkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJGxldmVsID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgUnViZW4gR29uemFsZXogPHJ1YmVucnVhQGdtYWlsLmNvbT4KICogQHBocHN0YW4tdHlwZSBSZWFzb25EYXRhIExpbmt8QmFzZVBhY2thZ2V8c3RyaW5nfGludHxhcnJheXtwYWNrYWdlTmFtZTogc3RyaW5nLCBjb25zdHJhaW50OiBDb25zdHJhaW50SW50ZXJmYWNlfXxhcnJheXtwYWNrYWdlOiBCYXNlUGFja2FnZX0KICovCmFic3RyYWN0IGNsYXNzIFJ1bGUKewogICAgLy8gcmVhc29uIGNvbnN0YW50cyBhbmQgLy8gdGhlaXIgcmVhc29uIGRhdGEgY29udGVudHMKICAgIGNvbnN0IFJVTEVfUk9PVF9SRVFVSVJFID0gMjsgLy8gYXJyYXl7cGFja2FnZU5hbWU6IHN0cmluZywgY29uc3RyYWludDogQ29uc3RyYWludEludGVyZmFjZX0KICAgIGNvbnN0IFJVTEVfRklYRUQgPSAzOyAvLyBhcnJheXtwYWNrYWdlOiBCYXNlUGFja2FnZX0KICAgIGNvbnN0IFJVTEVfUEFDS0FHRV9DT05GTElDVCA9IDY7IC8vIExpbmsKICAgIGNvbnN0IFJVTEVfUEFDS0FHRV9SRVFVSVJFUyA9IDc7IC8vIExpbmsKICAgIGNvbnN0IFJVTEVfUEFDS0FHRV9TQU1FX05BTUUgPSAxMDsgLy8gc3RyaW5nIChwYWNrYWdlIG5hbWUpCiAgICBjb25zdCBSVUxFX0xFQVJORUQgPSAxMjsgLy8gaW50IChydWxlIGlkKQogICAgY29uc3QgUlVMRV9QQUNLQUdFX0FMSUFTID0gMTM7IC8vIEJhc2VQYWNrYWdlCiAgICBjb25zdCBSVUxFX1BBQ0tBR0VfSU5WRVJTRV9BTElBUyA9IDE0OyAvLyBCYXNlUGFja2FnZQoKICAgIC8vIGJpdGZpZWxkIGRlZnMKICAgIGNvbnN0IEJJVEZJRUxEX1RZUEUgPSAwOwogICAgY29uc3QgQklURklFTERfUkVBU09OID0gODsKICAgIGNvbnN0IEJJVEZJRUxEX0RJU0FCTEVEID0gMTY7CgogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcm90ZWN0ZWQgJGJpdGZpZWxkOwogICAgLyoqIEB2YXIgUmVxdWVzdCAqLwogICAgcHJvdGVjdGVkICRyZXF1ZXN0OwogICAgLyoqCiAgICAgKiBAdmFyIExpbmt8QmFzZVBhY2thZ2V8Q29uc3RyYWludEludGVyZmFjZXxzdHJpbmcKICAgICAqIEBwaHBzdGFuLXZhciBSZWFzb25EYXRhCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVhc29uRGF0YTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzZWxmOjpSVUxFXyogJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUgcmVhc29uIGZvciBnZW5lcmF0aW5nIHRoaXMgcnVsZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAkcmVhc29uRGF0YQogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIFJlYXNvbkRhdGEgJHJlYXNvbkRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRyZWFzb24sICRyZWFzb25EYXRhKQogICAgewogICAgICAgICR0aGlzLT5yZWFzb25EYXRhID0gJHJlYXNvbkRhdGE7CgogICAgICAgICR0aGlzLT5iaXRmaWVsZCA9ICgwIDw8IHNlbGY6OkJJVEZJRUxEX0RJU0FCTEVEKSB8CiAgICAgICAgICAgICgkcmVhc29uIDw8IHNlbGY6OkJJVEZJRUxEX1JFQVNPTikgfAogICAgICAgICAgICAoMjU1IDw8IHNlbGY6OkJJVEZJRUxEX1RZUEUpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gZ2V0TGl0ZXJhbHMoKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50fHN0cmluZwogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gZ2V0SGFzaCgpOwoKICAgIGFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUnVsZSAkcnVsZQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIGFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiBlcXVhbHMoUnVsZSAkcnVsZSk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVhc29uKCkKICAgIHsKICAgICAgICByZXR1cm4gKCR0aGlzLT5iaXRmaWVsZCAmICgyNTUgPDwgc2VsZjo6QklURklFTERfUkVBU09OKSkgPj4gc2VsZjo6QklURklFTERfUkVBU09OOwogICAgfQoKICAgIC8qKgogICAgICogQHBocHN0YW4tcmV0dXJuIFJlYXNvbkRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlYXNvbkRhdGEoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVhc29uRGF0YTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcXVpcmVkUGFja2FnZSgpCiAgICB7CiAgICAgICAgJHJlYXNvbiA9ICR0aGlzLT5nZXRSZWFzb24oKTsKCiAgICAgICAgaWYgKCRyZWFzb24gPT09IHNlbGY6OlJVTEVfUk9PVF9SRVFVSVJFKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVhc29uRGF0YVsncGFja2FnZU5hbWUnXTsKICAgICAgICB9CgogICAgICAgIGlmICgkcmVhc29uID09PSBzZWxmOjpSVUxFX0ZJWEVEKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVhc29uRGF0YVsncGFja2FnZSddLT5nZXROYW1lKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlYXNvbiA9PT0gc2VsZjo6UlVMRV9QQUNLQUdFX1JFUVVJUkVTKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBSdWxlU2V0OjpUWVBFXyogJHR5cGUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHlwZSgkdHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+Yml0ZmllbGQgPSAoJHRoaXMtPmJpdGZpZWxkICYgfigyNTUgPDwgc2VsZjo6QklURklFTERfVFlQRSkpIHwgKCgyNTUgJiAkdHlwZSkgPDwgc2VsZjo6QklURklFTERfVFlQRSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICgkdGhpcy0+Yml0ZmllbGQgJiAoMjU1IDw8IHNlbGY6OkJJVEZJRUxEX1RZUEUpKSA+PiBzZWxmOjpCSVRGSUVMRF9UWVBFOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNhYmxlKCkKICAgIHsKICAgICAgICAkdGhpcy0+Yml0ZmllbGQgPSAoJHRoaXMtPmJpdGZpZWxkICYgfigyNTUgPDwgc2VsZjo6QklURklFTERfRElTQUJMRUQpKSB8ICgxIDw8IHNlbGY6OkJJVEZJRUxEX0RJU0FCTEVEKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlKCkKICAgIHsKICAgICAgICAkdGhpcy0+Yml0ZmllbGQgJj0gfigyNTUgPDwgc2VsZjo6QklURklFTERfRElTQUJMRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Rpc2FibGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpICgoJHRoaXMtPmJpdGZpZWxkICYgKDI1NSA8PCBzZWxmOjpCSVRGSUVMRF9ESVNBQkxFRCkpID4+IHNlbGY6OkJJVEZJRUxEX0RJU0FCTEVEKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNFbmFibGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gISgoJHRoaXMtPmJpdGZpZWxkICYgKDI1NSA8PCBzZWxmOjpCSVRGSUVMRF9ESVNBQkxFRCkpID4+IHNlbGY6OkJJVEZJRUxEX0RJU0FCTEVEKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gaXNBc3NlcnRpb24oKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNDYXVzZWRCeUxvY2soUmVwb3NpdG9yeVNldCAkcmVwb3NpdG9yeVNldCwgUmVxdWVzdCAkcmVxdWVzdCwgUG9vbCAkcG9vbCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdldFJlYXNvbigpID09PSBzZWxmOjpSVUxFX1BBQ0tBR0VfUkVRVUlSRVMpIHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHRoaXMtPnJlYXNvbkRhdGEtPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkcmVxdWVzdC0+Z2V0TG9ja2VkUmVwb3NpdG9yeSgpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0TG9ja2VkUmVwb3NpdG9yeSgpLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXROYW1lKCkgPT09ICR0aGlzLT5yZWFzb25EYXRhLT5nZXRUYXJnZXQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBvb2wtPmlzVW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5yZWFzb25EYXRhLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlcXVpcmVkIHBhY2thZ2Ugd2FzIGxvY2tlZCBidXQgaGFzIGJlZW4gdW5sb2NrZWQgYW5kIHN0aWxsIG1hdGNoZXMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkcmVxdWVzdC0+aXNMb2NrZWRQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmdldFJlYXNvbigpID09PSBzZWxmOjpSVUxFX1JPT1RfUkVRVUlSRSkgewogICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkdGhpcy0+cmVhc29uRGF0YVsncGFja2FnZU5hbWUnXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHJlcXVlc3QtPmdldExvY2tlZFJlcG9zaXRvcnkoKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldExvY2tlZFJlcG9zaXRvcnkoKS0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0TmFtZSgpID09PSAkdGhpcy0+cmVhc29uRGF0YVsncGFja2FnZU5hbWUnXSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBvb2wtPmlzVW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5yZWFzb25EYXRhWydjb25zdHJhaW50J10tPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VQYWNrYWdlKFBvb2wgJHBvb2wpCiAgICB7CiAgICAgICAgJGxpdGVyYWxzID0gJHRoaXMtPmdldExpdGVyYWxzKCk7CgogICAgICAgIHN3aXRjaCAoJHRoaXMtPmdldFJlYXNvbigpKSB7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6UlVMRV9QQUNLQUdFX0NPTkZMSUNUOgogICAgICAgICAgICAgICAgJHBhY2thZ2UxID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsc1swXSkpOwogICAgICAgICAgICAgICAgJHBhY2thZ2UyID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsc1sxXSkpOwoKICAgICAgICAgICAgICAgIGlmICgkcmVhc29uRGF0YSA9ICR0aGlzLT5nZXRSZWFzb25EYXRhKCkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBzd2FwIGxpdGVyYWxzIGlmIHRoZXkgYXJlIG5vdCBpbiB0aGUgcmlnaHQgb3JkZXIgd2l0aCBwYWNrYWdlMiBiZWluZyB0aGUgY29uZmxpY3RlcgogICAgICAgICAgICAgICAgICAgIGlmICgkcmVhc29uRGF0YS0+Z2V0U291cmNlKCkgPT09ICRwYWNrYWdlMS0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QoJHBhY2thZ2UyLCAkcGFja2FnZTEpID0gYXJyYXkoJHBhY2thZ2UxLCAkcGFja2FnZTIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2UyOwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1BBQ0tBR0VfUkVRVUlSRVM6CiAgICAgICAgICAgICAgICAkc291cmNlTGl0ZXJhbCA9IGFycmF5X3NoaWZ0KCRsaXRlcmFscyk7CiAgICAgICAgICAgICAgICAkc291cmNlUGFja2FnZSA9ICR0aGlzLT5kZWR1cGxpY2F0ZURlZmF1bHRCcmFuY2hBbGlhcygkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkc291cmNlTGl0ZXJhbCkpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkc291cmNlUGFja2FnZTsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdOb3QgaW1wbGVtZW50ZWQnKTsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGlzVmVyYm9zZQogICAgICogQHBhcmFtIEJhc2VQYWNrYWdlW10gJGluc3RhbGxlZE1hcAogICAgICogQHBhcmFtIGFycmF5PFJ1bGVbXT4gJGxlYXJuZWRQb29sCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKFJlcG9zaXRvcnlTZXQgJHJlcG9zaXRvcnlTZXQsIFJlcXVlc3QgJHJlcXVlc3QsIFBvb2wgJHBvb2wsICRpc1ZlcmJvc2UsIGFycmF5ICRpbnN0YWxsZWRNYXAgPSBhcnJheSgpLCBhcnJheSAkbGVhcm5lZFBvb2wgPSBhcnJheSgpKQogICAgewogICAgICAgICRsaXRlcmFscyA9ICR0aGlzLT5nZXRMaXRlcmFscygpOwoKICAgICAgICBzd2l0Y2ggKCR0aGlzLT5nZXRSZWFzb24oKSkgewogICAgICAgICAgICBjYXNlIHNlbGY6OlJVTEVfUk9PVF9SRVFVSVJFOgogICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lID0gJHRoaXMtPnJlYXNvbkRhdGFbJ3BhY2thZ2VOYW1lJ107CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICR0aGlzLT5yZWFzb25EYXRhWydjb25zdHJhaW50J107CgogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJHBvb2wtPndoYXRQcm92aWRlcygkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgICAgIGlmICghJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdObyBwYWNrYWdlIGZvdW5kIHRvIHNhdGlzZnkgcm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmUgJy4kcGFja2FnZU5hbWUuKCRjb25zdHJhaW50ID8gJyAnLiRjb25zdHJhaW50LT5nZXRQcmV0dHlTdHJpbmcoKSA6ICcnKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcGFja2FnZXNOb25BbGlhcyA9IGFycmF5X3ZhbHVlcyhhcnJheV9maWx0ZXIoJHBhY2thZ2VzLCBmdW5jdGlvbiAoJHApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gISgkcCBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSk7CiAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHBhY2thZ2VzTm9uQWxpYXMpID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZXNOb25BbGlhc1swXTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHJlcXVlc3QtPmlzTG9ja2VkUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBpcyBsb2NrZWQgdG8gdmVyc2lvbiAnLiRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkuIiBhbmQgYW4gdXBkYXRlIG9mIHRoaXMgcGFja2FnZSB3YXMgbm90IHJlcXVlc3RlZC4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJ1Jvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAnLiRwYWNrYWdlTmFtZS4oJGNvbnN0cmFpbnQgPyAnICcuJGNvbnN0cmFpbnQtPmdldFByZXR0eVN0cmluZygpIDogJycpLicgLT4gc2F0aXNmaWFibGUgYnkgJy4kdGhpcy0+Zm9ybWF0UGFja2FnZXNVbmlxdWUoJHBvb2wsICRwYWNrYWdlcywgJGlzVmVyYm9zZSwgJGNvbnN0cmFpbnQpLicuJzsKCiAgICAgICAgICAgIGNhc2Ugc2VsZjo6UlVMRV9GSVhFRDoKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlJ10pOwoKICAgICAgICAgICAgICAgIGlmICgkcmVxdWVzdC0+aXNMb2NrZWRQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLicgaXMgbG9ja2VkIHRvIHZlcnNpb24gJy4kcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLicgYW5kIGFuIHVwZGF0ZSBvZiB0aGlzIHBhY2thZ2Ugd2FzIG5vdCByZXF1ZXN0ZWQuJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGlzIHByZXNlbnQgYXQgdmVyc2lvbiAnLiRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgLiAnIGFuZCBjYW5ub3QgYmUgbW9kaWZpZWQgYnkgQ29tcG9zZXInOwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1BBQ0tBR0VfQ09ORkxJQ1Q6CiAgICAgICAgICAgICAgICAkcGFja2FnZTEgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzBdKSk7CiAgICAgICAgICAgICAgICAkcGFja2FnZTIgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzFdKSk7CgogICAgICAgICAgICAgICAgJGNvbmZsaWN0VGFyZ2V0ID0gJHBhY2thZ2UxLT5nZXRQcmV0dHlTdHJpbmcoKTsKICAgICAgICAgICAgICAgIGlmICgkcmVhc29uRGF0YSA9ICR0aGlzLT5nZXRSZWFzb25EYXRhKCkpIHsKICAgICAgICAgICAgICAgICAgICBhc3NlcnQoJHJlYXNvbkRhdGEgaW5zdGFuY2VvZiBMaW5rKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gc3dhcCBsaXRlcmFscyBpZiB0aGV5IGFyZSBub3QgaW4gdGhlIHJpZ2h0IG9yZGVyIHdpdGggcGFja2FnZTIgYmVpbmcgdGhlIGNvbmZsaWN0ZXIKICAgICAgICAgICAgICAgICAgICBpZiAoJHJlYXNvbkRhdGEtPmdldFNvdXJjZSgpID09PSAkcGFja2FnZTEtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0KCRwYWNrYWdlMiwgJHBhY2thZ2UxKSA9IGFycmF5KCRwYWNrYWdlMSwgJHBhY2thZ2UyKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbmZsaWN0VGFyZ2V0ID0gJHBhY2thZ2UxLT5nZXRQcmV0dHlOYW1lKCkuJyAnLiRyZWFzb25EYXRhLT5nZXRQcmV0dHlDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgY29uZmxpY3QgaXMgbm90IGRpcmVjdGx5IGFnYWluc3QgdGhlIHBhY2thZ2UgYnV0IHNvbWV0aGluZyBpdCBwcm92aWRlcy9yZXBsYWNlcywKICAgICAgICAgICAgICAgICAgICAvLyB3ZSB0cnkgdG8gZmluZCB0aGF0IGxpbmsgdG8gZGlzcGxheSBhIGJldHRlciBtZXNzYWdlCiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZWFzb25EYXRhLT5nZXRUYXJnZXQoKSAhPT0gJHBhY2thZ2UxLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHByb3ZpZGVUeXBlID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgJHByb3ZpZGVkID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UxLT5nZXRQcm92aWRlcygpIGFzICRwcm92aWRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHByb3ZpZGUtPmdldFRhcmdldCgpID09PSAkcmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJvdmlkZVR5cGUgPSAncHJvdmlkZXMnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcm92aWRlZCA9ICRwcm92aWRlLT5nZXRQcmV0dHlDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UxLT5nZXRSZXBsYWNlcygpIGFzICRyZXBsYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHJlcGxhY2UtPmdldFRhcmdldCgpID09PSAkcmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJvdmlkZVR5cGUgPSAncmVwbGFjZXMnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcm92aWRlZCA9ICRyZXBsYWNlLT5nZXRQcmV0dHlDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT09ICRwcm92aWRlVHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbmZsaWN0VGFyZ2V0ID0gJHJlYXNvbkRhdGEtPmdldFRhcmdldCgpLicgJy4kcmVhc29uRGF0YS0+Z2V0UHJldHR5Q29uc3RyYWludCgpLicgKCcuJHBhY2thZ2UxLT5nZXRQcmV0dHlTdHJpbmcoKS4nICcuJHByb3ZpZGVUeXBlLicgJy4kcmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCkuJyAnLiRwcm92aWRlZC4nKSc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlMi0+Z2V0UHJldHR5U3RyaW5nKCkuJyBjb25mbGljdHMgd2l0aCAnLiRjb25mbGljdFRhcmdldC4nLic7CgogICAgICAgICAgICBjYXNlIHNlbGY6OlJVTEVfUEFDS0FHRV9SRVFVSVJFUzoKICAgICAgICAgICAgICAgICRzb3VyY2VMaXRlcmFsID0gYXJyYXlfc2hpZnQoJGxpdGVyYWxzKTsKICAgICAgICAgICAgICAgICRzb3VyY2VQYWNrYWdlID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRzb3VyY2VMaXRlcmFsKSk7CiAgICAgICAgICAgICAgICAvKiogQHZhciBMaW5rICovCiAgICAgICAgICAgICAgICAkcmVhc29uRGF0YSA9ICR0aGlzLT5yZWFzb25EYXRhOwoKICAgICAgICAgICAgICAgICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZXNbXSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGV4dCA9ICRyZWFzb25EYXRhLT5nZXRQcmV0dHlTdHJpbmcoJHNvdXJjZVBhY2thZ2UpOwogICAgICAgICAgICAgICAgaWYgKCRyZXF1aXJlcykgewogICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICcgLT4gc2F0aXNmaWFibGUgYnkgJyAuICR0aGlzLT5mb3JtYXRQYWNrYWdlc1VuaXF1ZSgkcG9vbCwgJHJlcXVpcmVzLCAkaXNWZXJib3NlLCAkdGhpcy0+cmVhc29uRGF0YS0+Z2V0Q29uc3RyYWludCgpKSAuICcuJzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldE5hbWUgPSAkcmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCk7CgogICAgICAgICAgICAgICAgICAgICRyZWFzb24gPSBQcm9ibGVtOjpnZXRNaXNzaW5nUGFja2FnZVJlYXNvbigkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkdGFyZ2V0TmFtZSwgJHRoaXMtPnJlYXNvbkRhdGEtPmdldENvbnN0cmFpbnQoKSk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGV4dCAuICcgLT4gJyAuICRyZWFzb25bMV07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0ZXh0OwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1BBQ0tBR0VfU0FNRV9OQU1FOgogICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lcyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU5hbWVzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXBsYWNlZE5hbWUgPSAkdGhpcy0+cmVhc29uRGF0YTsKCiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHBhY2thZ2VOYW1lcykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VOYW1lc1skcmVwbGFjZWROYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9ICdUaGV5ICcuKGNvdW50KCRsaXRlcmFscykgPT0gMiA/ICdib3RoJyA6ICdhbGwnKS4nIHJlcGxhY2UgJy4kcmVwbGFjZWROYW1lLicgYW5kIHRodXMgY2Fubm90IGNvZXhpc3QuJzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZXJOYW1lcyA9ICRwYWNrYWdlTmFtZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRyZXBsYWNlck5hbWVzWyRyZXBsYWNlZE5hbWVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VyTmFtZXMgPSBhcnJheV9rZXlzKCRyZXBsYWNlck5hbWVzKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCgkcmVwbGFjZXJOYW1lcykgPT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9ICRyZXBsYWNlck5hbWVzWzBdIC4gJyByZXBsYWNlcyAnOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9ICdbJy5pbXBsb2RlKCcsICcsICRyZXBsYWNlck5hbWVzKS4nXSByZXBsYWNlICc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiAuPSAkcmVwbGFjZWROYW1lLicgYW5kIHRodXMgY2Fubm90IGNvZXhpc3Qgd2l0aCBpdC4nOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAkcmVtb3ZhYmxlUGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGluc3RhbGxlZE1hcFthYnMoJGxpdGVyYWwpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbnN0YWxsZWRQYWNrYWdlc1tdID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlbW92YWJsZVBhY2thZ2VzW10gPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkaW5zdGFsbGVkUGFja2FnZXMgJiYgJHJlbW92YWJsZVBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0UGFja2FnZXNVbmlxdWUoJHBvb2wsICRyZW1vdmFibGVQYWNrYWdlcywgJGlzVmVyYm9zZSwgbnVsbCwgdHJ1ZSkuJyBjYW5ub3QgYmUgaW5zdGFsbGVkIGFzIHRoYXQgd291bGQgcmVxdWlyZSByZW1vdmluZyAnLiR0aGlzLT5mb3JtYXRQYWNrYWdlc1VuaXF1ZSgkcG9vbCwgJGluc3RhbGxlZFBhY2thZ2VzLCAkaXNWZXJib3NlLCBudWxsLCB0cnVlKS4nLiAnLiRyZWFzb247CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ09ubHkgb25lIG9mIHRoZXNlIGNhbiBiZSBpbnN0YWxsZWQ6ICcuJHRoaXMtPmZvcm1hdFBhY2thZ2VzVW5pcXVlKCRwb29sLCAkbGl0ZXJhbHMsICRpc1ZlcmJvc2UsIG51bGwsIHRydWUpLicuICcuJHJlYXNvbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJ1lvdSBjYW4gb25seSBpbnN0YWxsIG9uZSB2ZXJzaW9uIG9mIGEgcGFja2FnZSwgc28gb25seSBvbmUgb2YgdGhlc2UgY2FuIGJlIGluc3RhbGxlZDogJyAuICR0aGlzLT5mb3JtYXRQYWNrYWdlc1VuaXF1ZSgkcG9vbCwgJGxpdGVyYWxzLCAkaXNWZXJib3NlLCBudWxsLCB0cnVlKSAuICcuJzsKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX0xFQVJORUQ6CiAgICAgICAgICAgICAgICAvKiogQFRPRE8gY3VycmVudGx5IHN0aWxsIGdlbmVyYXRlcyB3YXkgdG9vIG11Y2ggb3V0cHV0IHRvIGJlIGhlbHBmdWwsIGFuZCBpbiBzb21lIGNhc2VzIGNhbiBldmVuIGxlYWQgdG8gZW5kbGVzcyByZWN1cnNpb24gKi8KICAgICAgICAgICAgICAgIC8vIGlmIChpc3NldCgkbGVhcm5lZFBvb2xbJHRoaXMtPnJlYXNvbkRhdGFdKSkgewogICAgICAgICAgICAgICAgLy8gICAgIGVjaG8gJHRoaXMtPnJlYXNvbkRhdGEuIlxuIjsKICAgICAgICAgICAgICAgIC8vICAgICAkbGVhcm5lZFN0cmluZyA9ICcsIGxlYXJuZWQgcnVsZXM6JyAuIFByb2JsZW06OmZvcm1hdERlZHVwbGljYXRlZFJ1bGVzKCRsZWFybmVkUG9vbFskdGhpcy0+cmVhc29uRGF0YV0sICcgICAgICAgICcsICRyZXBvc2l0b3J5U2V0LCAkcmVxdWVzdCwgJHBvb2wsICRpc1ZlcmJvc2UsICRpbnN0YWxsZWRNYXAsICRsZWFybmVkUG9vbCk7CiAgICAgICAgICAgICAgICAvLyB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gICAgICRsZWFybmVkU3RyaW5nID0gJyAocmVhc29uaW5nIHVuYXZhaWxhYmxlKSc7CiAgICAgICAgICAgICAgICAvLyB9CiAgICAgICAgICAgICAgICAkbGVhcm5lZFN0cmluZyA9ICcgKGNvbmZsaWN0IGFuYWx5c2lzIHJlc3VsdCknOwoKICAgICAgICAgICAgICAgIGlmIChjb3VudCgkbGl0ZXJhbHMpID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0ID0gJHBvb2wtPmxpdGVyYWxUb1ByZXR0eVN0cmluZygkbGl0ZXJhbHNbMF0sICRpbnN0YWxsZWRNYXApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZ3JvdXBzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkaW5zdGFsbGVkTWFwWyRwYWNrYWdlLT5pZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZ3JvdXAgPSAkbGl0ZXJhbCA+IDAgPyAna2VlcCcgOiAncmVtb3ZlJzsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRncm91cCA9ICRsaXRlcmFsID4gMCA/ICdpbnN0YWxsJyA6ICdkb25cJ3QgaW5zdGFsbCc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRncm91cHNbJGdyb3VwXVtdID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0cyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGdyb3VwcyBhcyAkZ3JvdXAgPT4gJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRydWxlVGV4dHNbXSA9ICRncm91cCAuIChjb3VudCgkcGFja2FnZXMpID4gMSA/ICcgb25lIG9mJyA6ICcnKS4nICcgLiAkdGhpcy0+Zm9ybWF0UGFja2FnZXNVbmlxdWUoJHBvb2wsICRwYWNrYWdlcywgJGlzVmVyYm9zZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcnVsZVRleHQgPSBpbXBsb2RlKCcgfCAnLCAkcnVsZVRleHRzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJ0NvbmNsdXNpb246ICcuJHJ1bGVUZXh0LiRsZWFybmVkU3RyaW5nOwogICAgICAgICAgICBjYXNlIHNlbGY6OlJVTEVfUEFDS0FHRV9BTElBUzoKICAgICAgICAgICAgICAgICRhbGlhc1BhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbHNbMF0pOwoKICAgICAgICAgICAgICAgIC8vIGF2b2lkIHJldHVybmluZyBjb250ZW50IGxpa2UgIjk5OTk5OTktZGV2IGlzIGFuIGFsaWFzIG9mIGRldi1tYXN0ZXIiIGFzIGl0IGlzIHVzZWxlc3MKICAgICAgICAgICAgICAgIGlmICgkYWxpYXNQYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzFdKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRhbGlhc1BhY2thZ2UtPmdldFByZXR0eVN0cmluZygpIC4nIGlzIGFuIGFsaWFzIG9mICcuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLicgYW5kIHRodXMgcmVxdWlyZXMgaXQgdG8gYmUgaW5zdGFsbGVkIHRvby4nOwogICAgICAgICAgICBjYXNlIHNlbGY6OlJVTEVfUEFDS0FHRV9JTlZFUlNFX0FMSUFTOgogICAgICAgICAgICAgICAgLy8gaW52ZXJzZSBhbGlhcyBydWxlcyB3b3JrIHRoZSBvdGhlciB3YXkgYXJvdW5kIHRoYW4gYWJvdmUKICAgICAgICAgICAgICAgICRhbGlhc1BhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbHNbMV0pOwoKICAgICAgICAgICAgICAgIC8vIGF2b2lkIHJldHVybmluZyBjb250ZW50IGxpa2UgIjk5OTk5OTktZGV2IGlzIGFuIGFsaWFzIG9mIGRldi1tYXN0ZXIiIGFzIGl0IGlzIHVzZWxlc3MKICAgICAgICAgICAgICAgIGlmICgkYWxpYXNQYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzBdKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRhbGlhc1BhY2thZ2UtPmdldFByZXR0eVN0cmluZygpIC4nIGlzIGFuIGFsaWFzIG9mICcuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLicgYW5kIG11c3QgYmUgaW5zdGFsbGVkIHdpdGggaXQuJzsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICRydWxlVGV4dCA9ICcnOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRpID0+ICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0IC49ICd8JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0IC49ICRwb29sLT5saXRlcmFsVG9QcmV0dHlTdHJpbmcoJGxpdGVyYWwsICRpbnN0YWxsZWRNYXApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAnKCcuJHJ1bGVUZXh0LicpJzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8aW50fEJhc2VQYWNrYWdlPiAkcGFja2FnZXMgQW4gYXJyYXkgY29udGFpbmluZyBwYWNrYWdlcyBvciBsaXRlcmFscwogICAgICogQHBhcmFtIGJvb2wgJGlzVmVyYm9zZQogICAgICogQHBhcmFtIGJvb2wgJHVzZVJlbW92ZWRWZXJzaW9uR3JvdXAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmb3JtYXRQYWNrYWdlc1VuaXF1ZShQb29sICRwb29sLCBhcnJheSAkcGFja2FnZXMsICRpc1ZlcmJvc2UsIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgPSBudWxsLCAkdXNlUmVtb3ZlZFZlcnNpb25Hcm91cCA9IGZhbHNlKQogICAgewogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCFcaXNfb2JqZWN0KCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzWyRpbmRleF0gPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBQcm9ibGVtOjpnZXRQYWNrYWdlTGlzdCgkcGFja2FnZXMsICRpc1ZlcmJvc2UsICRwb29sLCAkY29uc3RyYWludCwgJHVzZVJlbW92ZWRWZXJzaW9uR3JvdXApOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBCYXNlUGFja2FnZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKEJhc2VQYWNrYWdlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAkcGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFV0aWxcSW5pSGVscGVyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5U2V0OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqCiAqIEBtZXRob2Qgc2VsZjo6RVJST1JfREVQRU5ERU5DWV9SRVNPTFVUSU9OX0ZBSUxFRCBnZXRDb2RlKCkKICovCmNsYXNzIFNvbHZlclByb2JsZW1zRXhjZXB0aW9uIGV4dGVuZHMgXFJ1bnRpbWVFeGNlcHRpb24KewogICAgY29uc3QgRVJST1JfREVQRU5ERU5DWV9SRVNPTFVUSU9OX0ZBSUxFRCA9IDI7CgogICAgLyoqIEB2YXIgUHJvYmxlbVtdICovCiAgICBwcm90ZWN0ZWQgJHByb2JsZW1zOwogICAgLyoqIEB2YXIgYXJyYXk8UnVsZVtdPiAqLwogICAgcHJvdGVjdGVkICRsZWFybmVkUG9vbDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBQcm9ibGVtW10gJHByb2JsZW1zCiAgICAgKiBAcGFyYW0gYXJyYXk8UnVsZVtdPiAkbGVhcm5lZFBvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRwcm9ibGVtcywgYXJyYXkgJGxlYXJuZWRQb29sKQogICAgewogICAgICAgICR0aGlzLT5wcm9ibGVtcyA9ICRwcm9ibGVtczsKICAgICAgICAkdGhpcy0+bGVhcm5lZFBvb2wgPSAkbGVhcm5lZFBvb2w7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJ0ZhaWxlZCByZXNvbHZpbmcgZGVwZW5kZW5jaWVzIHdpdGggJy5jb3VudCgkcHJvYmxlbXMpLicgcHJvYmxlbXMsIGNhbGwgZ2V0UHJldHR5U3RyaW5nIHRvIGdldCBmb3JtYXR0ZWQgZGV0YWlscycsIHNlbGY6OkVSUk9SX0RFUEVOREVOQ1lfUkVTT0xVVElPTl9GQUlMRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGlzVmVyYm9zZQogICAgICogQHBhcmFtIGJvb2wgJGlzRGV2RXh0cmFjdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVN0cmluZyhSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sLCAkaXNWZXJib3NlLCAkaXNEZXZFeHRyYWN0aW9uID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGluc3RhbGxlZE1hcCA9ICRyZXF1ZXN0LT5nZXRQcmVzZW50TWFwKHRydWUpOwogICAgICAgICRtaXNzaW5nRXh0ZW5zaW9ucyA9IGFycmF5KCk7CiAgICAgICAgJGlzQ2F1c2VkQnlMb2NrID0gZmFsc2U7CgogICAgICAgICRwcm9ibGVtcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2JsZW1zIGFzICRwcm9ibGVtKSB7CiAgICAgICAgICAgICRwcm9ibGVtc1tdID0gJHByb2JsZW0tPmdldFByZXR0eVN0cmluZygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkaW5zdGFsbGVkTWFwLCAkdGhpcy0+bGVhcm5lZFBvb2wpLiJcbiI7CgogICAgICAgICAgICAkbWlzc2luZ0V4dGVuc2lvbnMgPSBhcnJheV9tZXJnZSgkbWlzc2luZ0V4dGVuc2lvbnMsICR0aGlzLT5nZXRFeHRlbnNpb25Qcm9ibGVtcygkcHJvYmxlbS0+Z2V0UmVhc29ucygpKSk7CgogICAgICAgICAgICAkaXNDYXVzZWRCeUxvY2sgPSAkaXNDYXVzZWRCeUxvY2sgfHwgJHByb2JsZW0tPmlzQ2F1c2VkQnlMb2NrKCRyZXBvc2l0b3J5U2V0LCAkcmVxdWVzdCwgJHBvb2wpOwogICAgICAgIH0KCiAgICAgICAgJGkgPSAxOwogICAgICAgICR0ZXh0ID0gIlxuIjsKICAgICAgICBmb3JlYWNoIChhcnJheV91bmlxdWUoJHByb2JsZW1zKSBhcyAkcHJvYmxlbSkgewogICAgICAgICAgICAkdGV4dCAuPSAiICBQcm9ibGVtICIuKCRpKyspLiRwcm9ibGVtOwogICAgICAgIH0KCiAgICAgICAgJGhpbnRzID0gYXJyYXkoKTsKICAgICAgICBpZiAoISRpc0RldkV4dHJhY3Rpb24gJiYgKHN0cnBvcygkdGV4dCwgJ2NvdWxkIG5vdCBiZSBmb3VuZCcpIHx8IHN0cnBvcygkdGV4dCwgJ25vIG1hdGNoaW5nIHBhY2thZ2UgZm91bmQnKSkpIHsKICAgICAgICAgICAgJGhpbnRzW10gPSAiUG90ZW50aWFsIGNhdXNlczpcbiAtIEEgdHlwbyBpbiB0aGUgcGFja2FnZSBuYW1lXG4gLSBUaGUgcGFja2FnZSBpcyBub3QgYXZhaWxhYmxlIGluIGEgc3RhYmxlLWVub3VnaCB2ZXJzaW9uIGFjY29yZGluZyB0byB5b3VyIG1pbmltdW0tc3RhYmlsaXR5IHNldHRpbmdcbiAgIHNlZSA8aHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzA0LXNjaGVtYS5tZCNtaW5pbXVtLXN0YWJpbGl0eT4gZm9yIG1vcmUgZGV0YWlscy5cbiAtIEl0J3MgYSBwcml2YXRlIHBhY2thZ2UgYW5kIHlvdSBmb3Jnb3QgdG8gYWRkIGEgY3VzdG9tIHJlcG9zaXRvcnkgdG8gZmluZCBpdFxuXG5SZWFkIDxodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvdHJvdWJsZXNob290aW5nLm1kPiBmb3IgZnVydGhlciBjb21tb24gcHJvYmxlbXMuIjsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJG1pc3NpbmdFeHRlbnNpb25zKSkgewogICAgICAgICAgICAkaGludHNbXSA9ICR0aGlzLT5jcmVhdGVFeHRlbnNpb25IaW50KCRtaXNzaW5nRXh0ZW5zaW9ucyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlzQ2F1c2VkQnlMb2NrICYmICEkaXNEZXZFeHRyYWN0aW9uICYmICEkcmVxdWVzdC0+Z2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlUm9vdERlcGVuZGVuY2llcygpKSB7CiAgICAgICAgICAgICRoaW50c1tdID0gIlVzZSB0aGUgb3B0aW9uIC0td2l0aC1hbGwtZGVwZW5kZW5jaWVzICgtVykgdG8gYWxsb3cgdXBncmFkZXMsIGRvd25ncmFkZXMgYW5kIHJlbW92YWxzIGZvciBwYWNrYWdlcyBjdXJyZW50bHkgbG9ja2VkIHRvIHNwZWNpZmljIHZlcnNpb25zLiI7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCR0ZXh0LCAnZm91bmQgY29tcG9zZXItcGx1Z2luLWFwaVsyLjAuMF0gYnV0IGl0IGRvZXMgbm90IG1hdGNoJykgJiYgc3RycG9zKCR0ZXh0LCAnLSBvY3JhbWl1cy9wYWNrYWdlLXZlcnNpb25zJykpIHsKICAgICAgICAgICAgJGhpbnRzW10gPSAiPHdhcm5pbmc+b2NyYW1pdXMvcGFja2FnZS12ZXJzaW9ucyBvbmx5IHByb3ZpZGVzIHN1cHBvcnQgZm9yIENvbXBvc2VyIDIgaW4gMS44Kywgd2hpY2ggcmVxdWlyZXMgUEhQIDcuNC48L3dhcm5pbmc+XG5JZiB5b3UgY2FuIG5vdCB1cGdyYWRlIFBIUCB5b3UgY2FuIHJlcXVpcmUgPGluZm8+Y29tcG9zZXIvcGFja2FnZS12ZXJzaW9ucy1kZXByZWNhdGVkPC9pbmZvPiB0byByZXNvbHZlIHRoaXMgd2l0aCBQSFAgNy4wKy4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJ1BIUFVuaXRcRnJhbWV3b3JrXFRlc3RDYXNlJywgZmFsc2UpKSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJHRleHQsICdmb3VuZCBjb21wb3Nlci1wbHVnaW4tYXBpWzIuMC4wXSBidXQgaXQgZG9lcyBub3QgbWF0Y2gnKSkgewogICAgICAgICAgICAgICAgJGhpbnRzW10gPSAiWW91IGFyZSB1c2luZyBDb21wb3NlciAyLCB3aGljaCBzb21lIG9mIHlvdXIgcGx1Z2lucyBzZWVtIHRvIGJlIGluY29tcGF0aWJsZSB3aXRoLiBNYWtlIHN1cmUgeW91IHVwZGF0ZSB5b3VyIHBsdWdpbnMgb3IgcmVwb3J0IGEgcGx1Z2luLWlzc3VlIHRvIGFzayB0aGVtIHRvIHN1cHBvcnQgQ29tcG9zZXIgMi4iOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhpbnRzKSB7CiAgICAgICAgICAgICR0ZXh0IC49ICJcbiIgLiBpbXBsb2RlKCJcblxuIiwgJGhpbnRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGV4dDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUHJvYmxlbVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9ibGVtcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9ibGVtczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkbWlzc2luZ0V4dGVuc2lvbnMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY3JlYXRlRXh0ZW5zaW9uSGludChhcnJheSAkbWlzc2luZ0V4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgJHBhdGhzID0gSW5pSGVscGVyOjpnZXRBbGwoKTsKCiAgICAgICAgaWYgKGNvdW50KCRwYXRocykgPT09IDEgJiYgZW1wdHkoJHBhdGhzWzBdKSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICAkaWdub3JlRXh0ZW5zaW9uc0FyZ3VtZW50cyA9IGltcGxvZGUoIiAiLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRleHRlbnNpb24pIHsKICAgICAgICAgICAgcmV0dXJuICItLWlnbm9yZS1wbGF0Zm9ybS1yZXE9JGV4dGVuc2lvbiI7CiAgICAgICAgfSwgJG1pc3NpbmdFeHRlbnNpb25zKSk7CgogICAgICAgICR0ZXh0ID0gIlRvIGVuYWJsZSBleHRlbnNpb25zLCB2ZXJpZnkgdGhhdCB0aGV5IGFyZSBlbmFibGVkIGluIHlvdXIgLmluaSBmaWxlczpcbiAgICAtICI7CiAgICAgICAgJHRleHQgLj0gaW1wbG9kZSgiXG4gICAgLSAiLCAkcGF0aHMpOwogICAgICAgICR0ZXh0IC49ICJcbllvdSBjYW4gYWxzbyBydW4gYHBocCAtLWluaWAgaW4gYSB0ZXJtaW5hbCB0byBzZWUgd2hpY2ggZmlsZXMgYXJlIHVzZWQgYnkgUEhQIGluIENMSSBtb2RlLiI7CiAgICAgICAgJHRleHQgLj0gIlxuQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBydW4gQ29tcG9zZXIgd2l0aCBgJGlnbm9yZUV4dGVuc2lvbnNBcmd1bWVudHNgIHRvIHRlbXBvcmFyaWx5IGlnbm9yZSB0aGVzZSByZXF1aXJlZCBleHRlbnNpb25zLiI7CgogICAgICAgIHJldHVybiAkdGV4dDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBSdWxlW11bXSAkcmVhc29uU2V0cwogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEV4dGVuc2lvblByb2JsZW1zKGFycmF5ICRyZWFzb25TZXRzKQogICAgewogICAgICAgICRtaXNzaW5nRXh0ZW5zaW9ucyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlYXNvblNldHMgYXMgJHJlYXNvblNldCkgewogICAgICAgICAgICBmb3JlYWNoICgkcmVhc29uU2V0IGFzICRydWxlKSB7CiAgICAgICAgICAgICAgICAkcmVxdWlyZWQgPSAkcnVsZS0+Z2V0UmVxdWlyZWRQYWNrYWdlKCk7CiAgICAgICAgICAgICAgICBpZiAobnVsbCAhPT0gJHJlcXVpcmVkICYmIDAgPT09IHN0cnBvcygkcmVxdWlyZWQsICdleHQtJykpIHsKICAgICAgICAgICAgICAgICAgICAkbWlzc2luZ0V4dGVuc2lvbnNbJHJlcXVpcmVkXSA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheV9rZXlzKCRtaXNzaW5nRXh0ZW5zaW9ucyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBwaHBzdGFuLWltcG9ydC10eXBlIFJlYXNvbkRhdGEgZnJvbSBSdWxlCiAqLwpjbGFzcyBSdWxlMkxpdGVyYWxzIGV4dGVuZHMgUnVsZQp7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByb3RlY3RlZCAkbGl0ZXJhbDE7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByb3RlY3RlZCAkbGl0ZXJhbDI7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsMQogICAgICogQHBhcmFtIGludCAkbGl0ZXJhbDIKICAgICAqIEBwYXJhbSBSdWxlOjpSVUxFXyogJHJlYXNvbiBBIFJVTEVfKiBjb25zdGFudAogICAgICogQHBhcmFtIG1peGVkICRyZWFzb25EYXRhCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gUmVhc29uRGF0YSAkcmVhc29uRGF0YQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGxpdGVyYWwxLCAkbGl0ZXJhbDIsICRyZWFzb24sICRyZWFzb25EYXRhKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHJlYXNvbiwgJHJlYXNvbkRhdGEpOwoKICAgICAgICBpZiAoJGxpdGVyYWwxIDwgJGxpdGVyYWwyKSB7CiAgICAgICAgICAgICR0aGlzLT5saXRlcmFsMSA9ICRsaXRlcmFsMTsKICAgICAgICAgICAgJHRoaXMtPmxpdGVyYWwyID0gJGxpdGVyYWwyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5saXRlcmFsMSA9ICRsaXRlcmFsMjsKICAgICAgICAgICAgJHRoaXMtPmxpdGVyYWwyID0gJGxpdGVyYWwxOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQHJldHVybiBpbnRbXSAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExpdGVyYWxzKCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoJHRoaXMtPmxpdGVyYWwxLCAkdGhpcy0+bGl0ZXJhbDIpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhhc2goKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGl0ZXJhbDEuJywnLiR0aGlzLT5saXRlcmFsMjsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGlzIHJ1bGUgaXMgZXF1YWwgdG8gYW5vdGhlciBvbmUKICAgICAqCiAgICAgKiBJZ25vcmVzIHdoZXRoZXIgZWl0aGVyIG9mIHRoZSBydWxlcyBpcyBkaXNhYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIFJ1bGUgJHJ1bGUgVGhlIHJ1bGUgdG8gY2hlY2sgYWdhaW5zdAogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHJ1bGVzIGFyZSBlcXVhbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXF1YWxzKFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgLy8gc3BlY2lhbGl6ZWQgZmFzdC1jYXNlCiAgICAgICAgaWYgKCRydWxlIGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICBpZiAoJHRoaXMtPmxpdGVyYWwxICE9PSAkcnVsZS0+bGl0ZXJhbDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5saXRlcmFsMiAhPT0gJHJ1bGUtPmxpdGVyYWwyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJGxpdGVyYWxzID0gJHJ1bGUtPmdldExpdGVyYWxzKCk7CiAgICAgICAgaWYgKDIgIT0gXGNvdW50KCRsaXRlcmFscykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5saXRlcmFsMSAhPT0gJGxpdGVyYWxzWzBdKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGl0ZXJhbDIgIT09ICRsaXRlcmFsc1sxXSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKiogQHJldHVybiBmYWxzZSAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQXNzZXJ0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgcnVsZSBhcyBhIHN0cmluZyBvZiB0aGUgZm9ybWF0IChMaXRlcmFsMXxMaXRlcmFsMnwuLi4pCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+aXNEaXNhYmxlZCgpID8gJ2Rpc2FibGVkKCcgOiAnKCc7CgogICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPmxpdGVyYWwxIC4gJ3wnIC4gJHRoaXMtPmxpdGVyYWwyIC4gJyknOwoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7CgovKioKICogV3JhcHBlciBhcm91bmQgYSBSdWxlIHdoaWNoIGtlZXBzIHRyYWNrIG9mIHRoZSB0d28gbGl0ZXJhbHMgaXQgd2F0Y2hlcwogKgogKiBVc2VkIGJ5IFJ1bGVXYXRjaEdyYXBoIHRvIHN0b3JlIHJ1bGVzIGluIHR3byBSdWxlV2F0Y2hDaGFpbnMuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBSdWxlV2F0Y2hOb2RlCnsKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHVibGljICR3YXRjaDE7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHB1YmxpYyAkd2F0Y2gyOwoKICAgIC8qKiBAdmFyIFJ1bGUgKi8KICAgIHByb3RlY3RlZCAkcnVsZTsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgbm9kZSB3YXRjaGluZyB0aGUgZmlyc3QgYW5kIHNlY29uZCBsaXRlcmFscyBvZiB0aGUgcnVsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUnVsZSAkcnVsZSBUaGUgcnVsZSB0byB3cmFwCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSdWxlICRydWxlKQogICAgewogICAgICAgICR0aGlzLT5ydWxlID0gJHJ1bGU7CgogICAgICAgICRsaXRlcmFscyA9ICRydWxlLT5nZXRMaXRlcmFscygpOwoKICAgICAgICAkbGl0ZXJhbENvdW50ID0gXGNvdW50KCRsaXRlcmFscyk7CiAgICAgICAgJHRoaXMtPndhdGNoMSA9ICRsaXRlcmFsQ291bnQgPiAwID8gJGxpdGVyYWxzWzBdIDogMDsKICAgICAgICAkdGhpcy0+d2F0Y2gyID0gJGxpdGVyYWxDb3VudCA+IDEgPyAkbGl0ZXJhbHNbMV0gOiAwOwogICAgfQoKICAgIC8qKgogICAgICogUGxhY2VzIHRoZSBzZWNvbmQgd2F0Y2ggb24gdGhlIHJ1bGUncyBsaXRlcmFsLCBkZWNpZGVkIGF0IHRoZSBoaWdoZXN0IGxldmVsCiAgICAgKgogICAgICogVXNlZnVsIGZvciBsZWFybmVkIHJ1bGVzIHdoZXJlIHRoZSBsaXRlcmFsIGZvciB0aGUgaGlnaGVzdCBydWxlIGlzIG1vc3QKICAgICAqIGxpa2VseSB0byBxdWlja2x5IGxlYWQgdG8gZnVydGhlciBkZWNpc2lvbnMuCiAgICAgKgogICAgICogQHBhcmFtIERlY2lzaW9ucyAkZGVjaXNpb25zIFRoZSBkZWNpc2lvbnMgbWFkZSBzbyBmYXIgYnkgdGhlIHNvbHZlcgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3YXRjaDJPbkhpZ2hlc3QoRGVjaXNpb25zICRkZWNpc2lvbnMpCiAgICB7CiAgICAgICAgJGxpdGVyYWxzID0gJHRoaXMtPnJ1bGUtPmdldExpdGVyYWxzKCk7CgogICAgICAgIC8vIGlmIHRoZXJlIGFyZSBvbmx5IDIgZWxlbWVudHMsIGJvdGggYXJlIGJlaW5nIHdhdGNoZWQgYW55d2F5CiAgICAgICAgaWYgKFxjb3VudCgkbGl0ZXJhbHMpIDwgMyB8fCAkdGhpcy0+cnVsZSBpbnN0YW5jZW9mIE11bHRpQ29uZmxpY3RSdWxlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR3YXRjaExldmVsID0gMDsKCiAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRsaXRlcmFsKSB7CiAgICAgICAgICAgICRsZXZlbCA9ICRkZWNpc2lvbnMtPmRlY2lzaW9uTGV2ZWwoJGxpdGVyYWwpOwoKICAgICAgICAgICAgaWYgKCRsZXZlbCA+ICR3YXRjaExldmVsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d2F0Y2gyID0gJGxpdGVyYWw7CiAgICAgICAgICAgICAgICAkd2F0Y2hMZXZlbCA9ICRsZXZlbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJ1bGUgdGhpcyBub2RlIHdyYXBzCiAgICAgKgogICAgICogQHJldHVybiBSdWxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSdWxlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJ1bGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBvbmUgd2F0Y2hlZCBsaXRlcmFsLCB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvdGhlciB3YXRjaGVkIGxpdGVyYWwKICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAkbGl0ZXJhbCBUaGUgd2F0Y2hlZCBsaXRlcmFsIHRoYXQgc2hvdWxkIG5vdCBiZSByZXR1cm5lZAogICAgICogQHJldHVybiBpbnQgQSBsaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPdGhlcldhdGNoKCRsaXRlcmFsKQogICAgewogICAgICAgIGlmICgkdGhpcy0+d2F0Y2gxID09ICRsaXRlcmFsKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+d2F0Y2gyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT53YXRjaDE7CiAgICB9CgogICAgLyoqCiAgICAgKiBNb3ZlcyBhIHdhdGNoIGZyb20gb25lIGxpdGVyYWwgdG8gYW5vdGhlcgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGZyb20gVGhlIHByZXZpb3VzbHkgd2F0Y2hlZCBsaXRlcmFsCiAgICAgKiBAcGFyYW0gaW50ICR0byAgIFRoZSBsaXRlcmFsIHRvIGJlIHdhdGNoZWQgbm93CiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1vdmVXYXRjaCgkZnJvbSwgJHRvKQogICAgewogICAgICAgIGlmICgkdGhpcy0+d2F0Y2gxID09ICRmcm9tKSB7CiAgICAgICAgICAgICR0aGlzLT53YXRjaDEgPSAkdG87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPndhdGNoMiA9ICR0bzsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAaW1wbGVtZW50cyBcSXRlcmF0b3JBZ2dyZWdhdGU8UnVsZT4KICovCmNsYXNzIFJ1bGVTZXQgaW1wbGVtZW50cyBcSXRlcmF0b3JBZ2dyZWdhdGUsIFxDb3VudGFibGUKewogICAgLy8gaGlnaGVzdCBwcmlvcml0eSA9PiBsb3dlc3QgbnVtYmVyCiAgICBjb25zdCBUWVBFX1BBQ0tBR0UgPSAwOwogICAgY29uc3QgVFlQRV9SRVFVRVNUID0gMTsKICAgIGNvbnN0IFRZUEVfTEVBUk5FRCA9IDQ7CgogICAgLyoqCiAgICAgKiBSRUFELU9OTFk6IExvb2t1cCB0YWJsZSBmb3IgcnVsZSBpZCB0byBydWxlIG9iamVjdAogICAgICoKICAgICAqIEB2YXIgYXJyYXk8aW50LCBSdWxlPgogICAgICovCiAgICBwdWJsaWMgJHJ1bGVCeUlkID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBhcnJheTwwfDF8NCwgc3RyaW5nPiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyAkdHlwZXMgPSBhcnJheSgKICAgICAgICBzZWxmOjpUWVBFX1BBQ0tBR0UgPT4gJ1BBQ0tBR0UnLAogICAgICAgIHNlbGY6OlRZUEVfUkVRVUVTVCA9PiAnUkVRVUVTVCcsCiAgICAgICAgc2VsZjo6VFlQRV9MRUFSTkVEID0+ICdMRUFSTkVEJywKICAgICk7CgogICAgLyoqIEB2YXIgYXJyYXk8c2VsZjo6VFlQRV8qLCBSdWxlW10+ICovCiAgICBwcm90ZWN0ZWQgJHJ1bGVzOwoKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJvdGVjdGVkICRuZXh0UnVsZUlkID0gMDsKCiAgICAvKiogQHZhciBhcnJheTxpbnR8c3RyaW5nLCBSdWxlfFJ1bGVbXT4gKi8KICAgIHByb3RlY3RlZCAkcnVsZXNCeUhhc2ggPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFR5cGVzKCkgYXMgJHR5cGUpIHsKICAgICAgICAgICAgJHRoaXMtPnJ1bGVzWyR0eXBlXSA9IGFycmF5KCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHNlbGY6OlRZUEVfKiAkdHlwZQogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGQoUnVsZSAkcnVsZSwgJHR5cGUpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldChzZWxmOjokdHlwZXNbJHR5cGVdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXE91dE9mQm91bmRzRXhjZXB0aW9uKCdVbmtub3duIHJ1bGUgdHlwZTogJyAuICR0eXBlKTsKICAgICAgICB9CgogICAgICAgICRoYXNoID0gJHJ1bGUtPmdldEhhc2goKTsKCiAgICAgICAgLy8gRG8gbm90IGFkZCBpZiBydWxlIGFscmVhZHkgZXhpc3RzCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5ydWxlc0J5SGFzaFskaGFzaF0pKSB7CiAgICAgICAgICAgICRwb3RlbnRpYWxEdXBsaWNhdGVzID0gJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXTsKICAgICAgICAgICAgaWYgKFxpc19hcnJheSgkcG90ZW50aWFsRHVwbGljYXRlcykpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwb3RlbnRpYWxEdXBsaWNhdGVzIGFzICRwb3RlbnRpYWxEdXBsaWNhdGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHJ1bGUtPmVxdWFscygkcG90ZW50aWFsRHVwbGljYXRlKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCRydWxlLT5lcXVhbHMoJHBvdGVudGlhbER1cGxpY2F0ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5ydWxlc1skdHlwZV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5ydWxlc1skdHlwZV0gPSBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJ1bGVzWyR0eXBlXVtdID0gJHJ1bGU7CiAgICAgICAgJHRoaXMtPnJ1bGVCeUlkWyR0aGlzLT5uZXh0UnVsZUlkXSA9ICRydWxlOwogICAgICAgICRydWxlLT5zZXRUeXBlKCR0eXBlKTsKCiAgICAgICAgJHRoaXMtPm5leHRSdWxlSWQrKzsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cnVsZXNCeUhhc2hbJGhhc2hdKSkgewogICAgICAgICAgICAkdGhpcy0+cnVsZXNCeUhhc2hbJGhhc2hdID0gJHJ1bGU7CiAgICAgICAgfSBlbHNlaWYgKFxpc19hcnJheSgkdGhpcy0+cnVsZXNCeUhhc2hbJGhhc2hdKSkgewogICAgICAgICAgICAkdGhpcy0+cnVsZXNCeUhhc2hbJGhhc2hdW10gPSAkcnVsZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkb3JpZ2luYWxSdWxlID0gJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXTsKICAgICAgICAgICAgJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXSA9IGFycmF5KCRvcmlnaW5hbFJ1bGUsICRydWxlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uZXh0UnVsZUlkOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAkaWQKICAgICAqIEByZXR1cm4gUnVsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcnVsZUJ5SWQoJGlkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cnVsZUJ5SWRbJGlkXTsKICAgIH0KCiAgICAvKiogQHJldHVybiBhcnJheTxzZWxmOjpUWVBFXyosIFJ1bGVbXT4gKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSdWxlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUnVsZVNldEl0ZXJhdG9yCiAgICAgKi8KICAgICNbXFJldHVyblR5cGVXaWxsQ2hhbmdlXQogICAgcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFJ1bGVTZXRJdGVyYXRvcigkdGhpcy0+Z2V0UnVsZXMoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHNlbGY6OlRZUEVfKnxhcnJheTxzZWxmOjpUWVBFXyo+ICR0eXBlcwogICAgICogQHJldHVybiBSdWxlU2V0SXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yRm9yKCR0eXBlcykKICAgIHsKICAgICAgICBpZiAoIVxpc19hcnJheSgkdHlwZXMpKSB7CiAgICAgICAgICAgICR0eXBlcyA9IGFycmF5KCR0eXBlcyk7CiAgICAgICAgfQoKICAgICAgICAkYWxsUnVsZXMgPSAkdGhpcy0+Z2V0UnVsZXMoKTsKCiAgICAgICAgLyoqIEB2YXIgYXJyYXk8c2VsZjo6VFlQRV8qLCBSdWxlW10+ICRydWxlcyAqLwogICAgICAgICRydWxlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCR0eXBlcyBhcyAkdHlwZSkgewogICAgICAgICAgICAkcnVsZXNbJHR5cGVdID0gJGFsbFJ1bGVzWyR0eXBlXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUnVsZVNldEl0ZXJhdG9yKCRydWxlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c2VsZjo6VFlQRV8qPnxzZWxmOjpUWVBFXyogJHR5cGVzCiAgICAgKiBAcmV0dXJuIFJ1bGVTZXRJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3JXaXRob3V0KCR0eXBlcykKICAgIHsKICAgICAgICBpZiAoIVxpc19hcnJheSgkdHlwZXMpKSB7CiAgICAgICAgICAgICR0eXBlcyA9IGFycmF5KCR0eXBlcyk7CiAgICAgICAgfQoKICAgICAgICAkcnVsZXMgPSAkdGhpcy0+Z2V0UnVsZXMoKTsKCiAgICAgICAgZm9yZWFjaCAoJHR5cGVzIGFzICR0eXBlKSB7CiAgICAgICAgICAgIHVuc2V0KCRydWxlc1skdHlwZV0pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBSdWxlU2V0SXRlcmF0b3IoJHJ1bGVzKTsKICAgIH0KCiAgICAvKiogQHJldHVybiBhcnJheXswOiAwLCAxOiAxLCAyOiA0fSAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGVzKCkKICAgIHsKICAgICAgICAkdHlwZXMgPSBzZWxmOjokdHlwZXM7CgogICAgICAgIHJldHVybiBhcnJheV9rZXlzKCR0eXBlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkaXNWZXJib3NlCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKFJlcG9zaXRvcnlTZXQgJHJlcG9zaXRvcnlTZXQgPSBudWxsLCBSZXF1ZXN0ICRyZXF1ZXN0ID0gbnVsbCwgUG9vbCAkcG9vbCA9IG51bGwsICRpc1ZlcmJvc2UgPSBmYWxzZSkKICAgIHsKICAgICAgICAkc3RyaW5nID0gIlxuIjsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cnVsZXMgYXMgJHR5cGUgPT4gJHJ1bGVzKSB7CiAgICAgICAgICAgICRzdHJpbmcgLj0gc3RyX3BhZChzZWxmOjokdHlwZXNbJHR5cGVdLCA4LCAnICcpIC4gIjogIjsKICAgICAgICAgICAgZm9yZWFjaCAoJHJ1bGVzIGFzICRydWxlKSB7CiAgICAgICAgICAgICAgICAkc3RyaW5nIC49ICgkcmVwb3NpdG9yeVNldCAmJiAkcmVxdWVzdCAmJiAkcG9vbCA/ICRydWxlLT5nZXRQcmV0dHlTdHJpbmcoJHJlcG9zaXRvcnlTZXQsICRyZXF1ZXN0LCAkcG9vbCwgJGlzVmVyYm9zZSkgOiAkcnVsZSkuIlxuIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc3RyaW5nIC49ICJcblxuIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3RyaW5nOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZXR0eVN0cmluZygpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29tcGlsaW5nTWF0Y2hlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIEEgcGFja2FnZSBwb29sIGNvbnRhaW5zIGFsbCBwYWNrYWdlcyBmb3IgZGVwZW5kZW5jeSByZXNvbHV0aW9uCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBvb2wgaW1wbGVtZW50cyBcQ291bnRhYmxlCnsKICAgIC8qKiBAdmFyIEJhc2VQYWNrYWdlW10gKi8KICAgIHByb3RlY3RlZCAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZVtdPiAqLwogICAgcHJvdGVjdGVkICRwYWNrYWdlQnlOYW1lID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIFZlcnNpb25QYXJzZXIgKi8KICAgIHByb3RlY3RlZCAkdmVyc2lvblBhcnNlcjsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZVtdPj4gKi8KICAgIHByb3RlY3RlZCAkcHJvdmlkZXJDYWNoZSA9IGFycmF5KCk7CiAgICAvKiogQHZhciBCYXNlUGFja2FnZVtdICovCiAgICBwcm90ZWN0ZWQgJHVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlczsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBzdHJpbmc+PiBNYXAgb2YgcGFja2FnZSBuYW1lID0+IG5vcm1hbGl6ZWQgdmVyc2lvbiA9PiBwcmV0dHkgdmVyc2lvbiAqLwogICAgcHJvdGVjdGVkICRyZW1vdmVkVmVyc2lvbnMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIHN0cmluZz4+IE1hcCBvZiBwYWNrYWdlIG9iamVjdCBoYXNoID0+IHJlbW92ZWQgbm9ybWFsaXplZCB2ZXJzaW9ucyA9PiByZW1vdmVkIHByZXR0eSB2ZXJzaW9uICovCiAgICBwcm90ZWN0ZWQgJHJlbW92ZWRWZXJzaW9uc0J5UGFja2FnZSA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQmFzZVBhY2thZ2VbXSAkcGFja2FnZXMKICAgICAqIEBwYXJhbSBCYXNlUGFja2FnZVtdICR1bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgc3RyaW5nPj4gJHJlbW92ZWRWZXJzaW9ucwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBzdHJpbmc+PiAkcmVtb3ZlZFZlcnNpb25zQnlQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcGFja2FnZXMgPSBhcnJheSgpLCBhcnJheSAkdW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzID0gYXJyYXkoKSwgYXJyYXkgJHJlbW92ZWRWZXJzaW9ucyA9IGFycmF5KCksIGFycmF5ICRyZW1vdmVkVmVyc2lvbnNCeVBhY2thZ2UgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgJHRoaXMtPnNldFBhY2thZ2VzKCRwYWNrYWdlcyk7CiAgICAgICAgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlcyA9ICR1bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXM7CiAgICAgICAgJHRoaXMtPnJlbW92ZWRWZXJzaW9ucyA9ICRyZW1vdmVkVmVyc2lvbnM7CiAgICAgICAgJHRoaXMtPnJlbW92ZWRWZXJzaW9uc0J5UGFja2FnZSA9ICRyZW1vdmVkVmVyc2lvbnNCeVBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlbW92ZWRWZXJzaW9ucygkbmFtZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5yZW1vdmVkVmVyc2lvbnNbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZW1vdmVkVmVyc2lvbnNbJG5hbWVdIGFzICR2ZXJzaW9uID0+ICRwcmV0dHlWZXJzaW9uKSB7CiAgICAgICAgICAgIGlmICgkY29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkdmVyc2lvbikpKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0WyR2ZXJzaW9uXSA9ICRwcmV0dHlWZXJzaW9uOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRvYmplY3RIYXNoCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVtb3ZlZFZlcnNpb25zQnlQYWNrYWdlKCRvYmplY3RIYXNoKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlbW92ZWRWZXJzaW9uc0J5UGFja2FnZVskb2JqZWN0SGFzaF0pKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVkVmVyc2lvbnNCeVBhY2thZ2VbJG9iamVjdEhhc2hdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIEJhc2VQYWNrYWdlW10gJHBhY2thZ2VzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXRQYWNrYWdlcyhhcnJheSAkcGFja2FnZXMpCiAgICB7CiAgICAgICAgJGlkID0gMTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlc1tdID0gJHBhY2thZ2U7CgogICAgICAgICAgICAkcGFja2FnZS0+aWQgPSAkaWQrKzsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXROYW1lcygpIGFzICRwcm92aWRlZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2VCeU5hbWVbJHByb3ZpZGVkXVtdID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2VzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmVzIHRoZSBwYWNrYWdlIG9iamVjdCBmb3IgYSBnaXZlbiBwYWNrYWdlIGlkLgogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgJGlkCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYWNrYWdlQnlJZCgkaWQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYWNrYWdlc1skaWQgLSAxXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgaG93IG1hbnkgcGFja2FnZXMgaGF2ZSBiZWVuIGxvYWRlZCBpbnRvIHRoZSBwb29sCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIFxjb3VudCgkdGhpcy0+cGFja2FnZXMpOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoZXMgYWxsIHBhY2thZ2VzIHByb3ZpZGluZyB0aGUgZ2l2ZW4gcGFja2FnZSBuYW1lIGFuZCBtYXRjaCB0aGUgY29uc3RyYWludAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHBhY2thZ2UgbmFtZSB0byBiZSBzZWFyY2hlZCBmb3IKICAgICAqIEBwYXJhbSA/Q29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCBBIGNvbnN0cmFpbnQgdGhhdCBhbGwgcmV0dXJuZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlcyBtdXN0IG1hdGNoIG9yIG51bGwgdG8gcmV0dXJuIGFsbAogICAgICogQHJldHVybiBCYXNlUGFja2FnZVtdIEEgc2V0IG9mIHBhY2thZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3aGF0UHJvdmlkZXMoJG5hbWUsIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgPSBudWxsKQogICAgewogICAgICAgICRrZXkgPSAoc3RyaW5nKSAkY29uc3RyYWludDsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByb3ZpZGVyQ2FjaGVbJG5hbWVdWyRrZXldKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByb3ZpZGVyQ2FjaGVbJG5hbWVdWyRrZXldOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm92aWRlckNhY2hlWyRuYW1lXVska2V5XSA9ICR0aGlzLT5jb21wdXRlV2hhdFByb3ZpZGVzKCRuYW1lLCAkY29uc3RyYWludCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICRuYW1lICAgICAgIFRoZSBwYWNrYWdlIG5hbWUgdG8gYmUgc2VhcmNoZWQgZm9yCiAgICAgKiBAcGFyYW0gID9Db25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50IEEgY29uc3RyYWludCB0aGF0IGFsbCByZXR1cm5lZAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlcyBtdXN0IG1hdGNoIG9yIG51bGwgdG8gcmV0dXJuIGFsbAogICAgICogQHJldHVybiBCYXNlUGFja2FnZVtdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY29tcHV0ZVdoYXRQcm92aWRlcygkbmFtZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cGFja2FnZUJ5TmFtZVskbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFja2FnZUJ5TmFtZVskbmFtZV0gYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPm1hdGNoKCRjYW5kaWRhdGUsICRuYW1lLCAkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgICRtYXRjaGVzW10gPSAkY2FuZGlkYXRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsCiAgICAgKiBAcmV0dXJuIEJhc2VQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsaXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWwpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2VCeUlkKCRwYWNrYWdlSWQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAkbGl0ZXJhbAogICAgICogQHBhcmFtIGFycmF5PGludCwgQmFzZVBhY2thZ2U+ICRpbnN0YWxsZWRNYXAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsaXRlcmFsVG9QcmV0dHlTdHJpbmcoJGxpdGVyYWwsICRpbnN0YWxsZWRNYXApCiAgICB7CiAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CgogICAgICAgIGlmIChpc3NldCgkaW5zdGFsbGVkTWFwWyRwYWNrYWdlLT5pZF0pKSB7CiAgICAgICAgICAgICRwcmVmaXggPSAoJGxpdGVyYWwgPiAwID8gJ2tlZXAnIDogJ3JlbW92ZScpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwcmVmaXggPSAoJGxpdGVyYWwgPiAwID8gJ2luc3RhbGwnIDogJ2RvblwndCBpbnN0YWxsJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByZWZpeC4nICcuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBwYWNrYWdlIG1hdGNoZXMgdGhlIGdpdmVuIGNvbnN0cmFpbnQgZGlyZWN0bHkgb3IgdGhyb3VnaAogICAgICogcHJvdmlkZWQgb3IgcmVwbGFjZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgJG5hbWUgICAgICAgTmFtZSBvZiB0aGUgcGFja2FnZSB0byBiZSBtYXRjaGVkCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hdGNoKEJhc2VQYWNrYWdlICRjYW5kaWRhdGUsICRuYW1lLCBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkY2FuZGlkYXRlTmFtZSA9ICRjYW5kaWRhdGUtPmdldE5hbWUoKTsKICAgICAgICAkY2FuZGlkYXRlVmVyc2lvbiA9ICRjYW5kaWRhdGUtPmdldFZlcnNpb24oKTsKCiAgICAgICAgaWYgKCRjYW5kaWRhdGVOYW1lID09PSAkbmFtZSkgewogICAgICAgICAgICByZXR1cm4gJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgQ29tcGlsaW5nTWF0Y2hlcjo6bWF0Y2goJGNvbnN0cmFpbnQsIENvbnN0cmFpbnQ6Ok9QX0VRLCAkY2FuZGlkYXRlVmVyc2lvbik7CiAgICAgICAgfQoKICAgICAgICAkcHJvdmlkZXMgPSAkY2FuZGlkYXRlLT5nZXRQcm92aWRlcygpOwogICAgICAgICRyZXBsYWNlcyA9ICRjYW5kaWRhdGUtPmdldFJlcGxhY2VzKCk7CgogICAgICAgIC8vIGFsaWFzZXMgY3JlYXRlIG11bHRpcGxlIHJlcGxhY2VzL3Byb3ZpZGVzIGZvciBvbmUgdGFyZ2V0IHNvIHRoZXkgY2FuIG5vdCB1c2UgdGhlIHNob3J0Y3V0IGJlbG93CiAgICAgICAgaWYgKGlzc2V0KCRyZXBsYWNlc1swXSkgfHwgaXNzZXQoJHByb3ZpZGVzWzBdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkcHJvdmlkZXMgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0VGFyZ2V0KCkgPT09ICRuYW1lICYmICgkY29uc3RyYWludCA9PT0gbnVsbCB8fCAkY29uc3RyYWludC0+bWF0Y2hlcygkbGluay0+Z2V0Q29uc3RyYWludCgpKSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcGxhY2VzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFRhcmdldCgpID09PSAkbmFtZSAmJiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgJGNvbnN0cmFpbnQtPm1hdGNoZXMoJGxpbmstPmdldENvbnN0cmFpbnQoKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkcHJvdmlkZXNbJG5hbWVdKSAmJiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgJGNvbnN0cmFpbnQtPm1hdGNoZXMoJHByb3ZpZGVzWyRuYW1lXS0+Z2V0Q29uc3RyYWludCgpKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHJlcGxhY2VzWyRuYW1lXSkgJiYgKCRjb25zdHJhaW50ID09PSBudWxsIHx8ICRjb25zdHJhaW50LT5tYXRjaGVzKCRyZXBsYWNlc1skbmFtZV0tPmdldENvbnN0cmFpbnQoKSkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1VuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlKEJhc2VQYWNrYWdlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiBcaW5fYXJyYXkoJHBhY2thZ2UsICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBCYXNlUGFja2FnZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVbmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICAkc3RyID0gIlBvb2w6XG4iOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHN0ciAuPSAnLSAnLnN0cl9wYWQoKHN0cmluZykgJHBhY2thZ2UtPmlkLCA2LCAnICcsIFNUUl9QQURfTEVGVCkuJzogJy4kcGFja2FnZS0+Z2V0TmFtZSgpLiJcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHN0cjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICoKICogTXVsdGlDb25mbGljdFJ1bGUoW0EsIEIsIENdKSBhY3RzIGFzIFJ1bGUoWy1BLCAtQl0pLCBSdWxlKFstQSwgLUNdKSwgUnVsZShbLUIsIC1DXSkKICovCmNsYXNzIE11bHRpQ29uZmxpY3RSdWxlIGV4dGVuZHMgUnVsZQp7CiAgICAvKiogQHZhciBpbnRbXSAqLwogICAgcHJvdGVjdGVkICRsaXRlcmFsczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnRbXSAkbGl0ZXJhbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRsaXRlcmFscywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcmVhc29uLCAkcmVhc29uRGF0YSk7CgogICAgICAgIGlmIChcY291bnQoJGxpdGVyYWxzKSA8IDMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJtdWx0aSBjb25mbGljdCBydWxlIHJlcXVpcmVzIGF0IGxlYXN0IDMgbGl0ZXJhbHMiKTsKICAgICAgICB9CgogICAgICAgIC8vIHNvcnQgYWxsIHBhY2thZ2VzIGFzY2VuZGluZyBieSBpZAogICAgICAgIHNvcnQoJGxpdGVyYWxzKTsKCiAgICAgICAgJHRoaXMtPmxpdGVyYWxzID0gJGxpdGVyYWxzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGl0ZXJhbHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGl0ZXJhbHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGFzaCgpCiAgICB7CiAgICAgICAgJGRhdGEgPSB1bnBhY2soJ2loYXNoJywgbWQ1KCdjOicuaW1wbG9kZSgnLCcsICR0aGlzLT5saXRlcmFscyksIHRydWUpKTsKCiAgICAgICAgcmV0dXJuICRkYXRhWydoYXNoJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhpcyBydWxlIGlzIGVxdWFsIHRvIGFub3RoZXIgb25lCiAgICAgKgogICAgICogSWdub3JlcyB3aGV0aGVyIGVpdGhlciBvZiB0aGUgcnVsZXMgaXMgZGlzYWJsZWQuCiAgICAgKgogICAgICogQHBhcmFtICBSdWxlICRydWxlIFRoZSBydWxlIHRvIGNoZWNrIGFnYWluc3QKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBydWxlcyBhcmUgZXF1YWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVxdWFscyhSdWxlICRydWxlKQogICAgewogICAgICAgIGlmICgkcnVsZSBpbnN0YW5jZW9mIE11bHRpQ29uZmxpY3RSdWxlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bGl0ZXJhbHMgPT09ICRydWxlLT5nZXRMaXRlcmFscygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Fzc2VydGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBuZXZlcgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZSgpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJEaXNhYmxpbmcgbXVsdGkgY29uZmxpY3QgcnVsZXMgaXMgbm90IHBvc3NpYmxlLiBQbGVhc2UgY29udGFjdCBjb21wb3NlciBhdCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIgdG8gbGV0IHVzIGRlYnVnIHdoYXQgbGVhZCB0byB0aGlzIHNpdHVhdGlvbi4iKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBydWxlIGFzIGEgc3RyaW5nIG9mIHRoZSBmb3JtYXQgKExpdGVyYWwxfExpdGVyYWwyfC4uLikKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgLy8gVE9ETyBtdWx0aSBjb25mbGljdD8KICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmlzRGlzYWJsZWQoKSA/ICdkaXNhYmxlZChtdWx0aSgnIDogJyhtdWx0aSgnOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+bGl0ZXJhbHMgYXMgJGkgPT4gJGxpdGVyYWwpIHsKICAgICAgICAgICAgaWYgKCRpICE9IDApIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgLj0gJ3wnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXN1bHQgLj0gJGxpdGVyYWw7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0IC49ICcpKSc7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb247Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CgovKioKICogU29sdmVyIGluc3RhbGwgb3BlcmF0aW9uLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgTWFya0FsaWFzVW5pbnN0YWxsZWRPcGVyYXRpb24gZXh0ZW5kcyBTb2x2ZXJPcGVyYXRpb24gaW1wbGVtZW50cyBPcGVyYXRpb25JbnRlcmZhY2UKewogICAgY29uc3QgVFlQRSA9ICdtYXJrQWxpYXNVbmluc3RhbGxlZCc7CgogICAgLyoqCiAgICAgKiBAdmFyIEFsaWFzUGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEFsaWFzUGFja2FnZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gQWxpYXNQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hvdygkbG9jaykKICAgIHsKICAgICAgICByZXR1cm4gJ01hcmtpbmcgPGluZm8+Jy4kdGhpcy0+cGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLic8L2luZm8+ICg8Y29tbWVudD4nLiR0aGlzLT5wYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpLic8L2NvbW1lbnQ+KSBhcyB1bmluc3RhbGxlZCwgYWxpYXMgb2YgPGluZm8+Jy4kdGhpcy0+cGFja2FnZS0+Z2V0QWxpYXNPZigpLT5nZXRQcmV0dHlOYW1lKCkuJzwvaW5mbz4gKDxjb21tZW50PicuJHRoaXMtPnBhY2thZ2UtPmdldEFsaWFzT2YoKS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKS4nPC9jb21tZW50PiknOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb247CgovKioKICogQWJzdHJhY3Qgb3BlcmF0aW9uIGNsYXNzLgogKgogKiBAYXV0aG9yIEFsZWtzYW5kciBCZXpwaWF0b3YgPGFsZWtzYW5kci5iZXpwaWF0b3ZAc3ByeWtlci5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBTb2x2ZXJPcGVyYXRpb24gaW1wbGVtZW50cyBPcGVyYXRpb25JbnRlcmZhY2UKewogICAgY29uc3QgVFlQRSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIG9wZXJhdGlvbiB0eXBlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRpb25UeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gc3RhdGljOjpUWVBFOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2hvdyhmYWxzZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvbjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKCi8qKgogKiBTb2x2ZXIgdXBkYXRlIG9wZXJhdGlvbi4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmNsYXNzIFVwZGF0ZU9wZXJhdGlvbiBleHRlbmRzIFNvbHZlck9wZXJhdGlvbiBpbXBsZW1lbnRzIE9wZXJhdGlvbkludGVyZmFjZQp7CiAgICBjb25zdCBUWVBFID0gJ3VwZGF0ZSc7CgogICAgLyoqCiAgICAgKiBAdmFyIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRpbml0aWFsUGFja2FnZTsKCiAgICAvKioKICAgICAqIEB2YXIgUGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHRhcmdldFBhY2thZ2U7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCBpbml0aWFsIHBhY2thZ2UKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQgIHRhcmdldCBwYWNrYWdlICh1cGRhdGVkKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsUGFja2FnZSA9ICRpbml0aWFsOwogICAgICAgICR0aGlzLT50YXJnZXRQYWNrYWdlID0gJHRhcmdldDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgaW5pdGlhbCBwYWNrYWdlLgogICAgICoKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5pdGlhbFBhY2thZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5pdGlhbFBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRhcmdldCBwYWNrYWdlLgogICAgICoKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0UGFja2FnZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50YXJnZXRQYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3coJGxvY2spCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmZvcm1hdCgkdGhpcy0+aW5pdGlhbFBhY2thZ2UsICR0aGlzLT50YXJnZXRQYWNrYWdlLCAkbG9jayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkbG9jawogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXQoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbFBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldFBhY2thZ2UsICRsb2NrID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGZyb21WZXJzaW9uID0gJGluaXRpYWxQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpOwogICAgICAgICR0b1ZlcnNpb24gPSAkdGFyZ2V0UGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKTsKCiAgICAgICAgaWYgKCRmcm9tVmVyc2lvbiA9PT0gJHRvVmVyc2lvbiAmJiAkaW5pdGlhbFBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpICE9PSAkdGFyZ2V0UGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgJGZyb21WZXJzaW9uID0gJGluaXRpYWxQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbih0cnVlLCBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX1NPVVJDRV9SRUYpOwogICAgICAgICAgICAkdG9WZXJzaW9uID0gJHRhcmdldFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKHRydWUsIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfU09VUkNFX1JFRik7CiAgICAgICAgfSBlbHNlaWYgKCRmcm9tVmVyc2lvbiA9PT0gJHRvVmVyc2lvbiAmJiAkaW5pdGlhbFBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSAhPT0gJHRhcmdldFBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSkgewogICAgICAgICAgICAkZnJvbVZlcnNpb24gPSAkaW5pdGlhbFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKHRydWUsIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfRElTVF9SRUYpOwogICAgICAgICAgICAkdG9WZXJzaW9uID0gJHRhcmdldFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKHRydWUsIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfRElTVF9SRUYpOwogICAgICAgIH0KCiAgICAgICAgJGFjdGlvbk5hbWUgPSBWZXJzaW9uUGFyc2VyOjppc1VwZ3JhZGUoJGluaXRpYWxQYWNrYWdlLT5nZXRWZXJzaW9uKCksICR0YXJnZXRQYWNrYWdlLT5nZXRWZXJzaW9uKCkpID8gJ1VwZ3JhZGluZycgOiAnRG93bmdyYWRpbmcnOwoKICAgICAgICByZXR1cm4gJGFjdGlvbk5hbWUuJyA8aW5mbz4nLiRpbml0aWFsUGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLic8L2luZm8+ICg8Y29tbWVudD4nLiRmcm9tVmVyc2lvbi4nPC9jb21tZW50PiA9PiA8Y29tbWVudD4nLiR0b1ZlcnNpb24uJzwvY29tbWVudD4pJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKLyoqCiAqIFNvbHZlciBvcGVyYXRpb24gaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIE9wZXJhdGlvbkludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgb3BlcmF0aW9uIHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdGlvblR5cGUoKTsKCiAgICAvKioKICAgICAqIFNlcmlhbGl6ZXMgdGhlIG9wZXJhdGlvbiBpbiBhIGh1bWFuIHJlYWRhYmxlIGZvcm1hdAogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICRsb2NrIFdoZXRoZXIgdGhpcyBpcyBhbiBvcGVyYXRpb24gb24gdGhlIGxvY2sgZmlsZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3coJGxvY2spOwoKICAgIC8qKgogICAgICogU2VyaWFsaXplcyB0aGUgb3BlcmF0aW9uIGluIGEgaHVtYW4gcmVhZGFibGUgZm9ybWF0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwoKLyoqCiAqIFNvbHZlciBpbnN0YWxsIG9wZXJhdGlvbi4KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIE1hcmtBbGlhc0luc3RhbGxlZE9wZXJhdGlvbiBleHRlbmRzIFNvbHZlck9wZXJhdGlvbiBpbXBsZW1lbnRzIE9wZXJhdGlvbkludGVyZmFjZQp7CiAgICBjb25zdCBUWVBFID0gJ21hcmtBbGlhc0luc3RhbGxlZCc7CgogICAgLyoqCiAgICAgKiBAdmFyIEFsaWFzUGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEFsaWFzUGFja2FnZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gQWxpYXNQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hvdygkbG9jaykKICAgIHsKICAgICAgICByZXR1cm4gJ01hcmtpbmcgPGluZm8+Jy4kdGhpcy0+cGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLic8L2luZm8+ICg8Y29tbWVudD4nLiR0aGlzLT5wYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpLic8L2NvbW1lbnQ+KSBhcyBpbnN0YWxsZWQsIGFsaWFzIG9mIDxpbmZvPicuJHRoaXMtPnBhY2thZ2UtPmdldEFsaWFzT2YoKS0+Z2V0UHJldHR5TmFtZSgpLic8L2luZm8+ICg8Y29tbWVudD4nLiR0aGlzLT5wYWNrYWdlLT5nZXRBbGlhc09mKCktPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkuJzwvY29tbWVudD4pJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBTb2x2ZXIgdW5pbnN0YWxsIG9wZXJhdGlvbi4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmNsYXNzIFVuaW5zdGFsbE9wZXJhdGlvbiBleHRlbmRzIFNvbHZlck9wZXJhdGlvbiBpbXBsZW1lbnRzIE9wZXJhdGlvbkludGVyZmFjZQp7CiAgICBjb25zdCBUWVBFID0gJ3VuaW5zdGFsbCc7CgogICAgLyoqCiAgICAgKiBAdmFyIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRwYWNrYWdlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5wYWNrYWdlID0gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHBhY2thZ2UgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hvdygkbG9jaykKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6Zm9ybWF0KCR0aGlzLT5wYWNrYWdlLCAkbG9jayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkbG9jawogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGxvY2sgPSBmYWxzZSkKICAgIHsKICAgICAgICByZXR1cm4gJ1JlbW92aW5nIDxpbmZvPicuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nPC9pbmZvPiAoPGNvbW1lbnQ+Jy4kcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKS4nPC9jb21tZW50PiknOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb247Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIFNvbHZlciBpbnN0YWxsIG9wZXJhdGlvbi4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmNsYXNzIEluc3RhbGxPcGVyYXRpb24gZXh0ZW5kcyBTb2x2ZXJPcGVyYXRpb24gaW1wbGVtZW50cyBPcGVyYXRpb25JbnRlcmZhY2UKewogICAgY29uc3QgVFlQRSA9ICdpbnN0YWxsJzsKCiAgICAvKioKICAgICAqIEB2YXIgUGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhY2thZ2UgPSAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgcGFja2FnZSBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzaG93KCRsb2NrKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpmb3JtYXQoJHRoaXMtPnBhY2thZ2UsICRsb2NrKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRsb2NrCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkbG9jayA9IGZhbHNlKQogICAgewogICAgICAgIHJldHVybiAoJGxvY2sgPyAnTG9ja2luZyAnIDogJ0luc3RhbGxpbmcgJykuJzxpbmZvPicuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nPC9pbmZvPiAoPGNvbW1lbnQ+Jy4kcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKS4nPC9jb21tZW50PiknOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogQGludGVybmFsCiAqLwpjbGFzcyBMb2NhbFJlcG9UcmFuc2FjdGlvbiBleHRlbmRzIFRyYW5zYWN0aW9uCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZXBvc2l0b3J5SW50ZXJmYWNlICRsb2NrZWRSZXBvc2l0b3J5LCBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRsb2NhbFJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgKICAgICAgICAgICAgJGxvY2FsUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSwKICAgICAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnktPmdldFBhY2thZ2VzKCkKICAgICAgICApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2U7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogQGludGVybmFsCiAqLwpjbGFzcyBMb2NrVHJhbnNhY3Rpb24gZXh0ZW5kcyBUcmFuc2FjdGlvbgp7CiAgICAvKioKICAgICAqIHBhY2thZ2VzIGluIGN1cnJlbnQgbG9jayBmaWxlLCBwbGF0Zm9ybSByZXBvIG9yIG90aGVyd2lzZSBwcmVzZW50CiAgICAgKgogICAgICogSW5kZXhlZCBieSBzcGxfb2JqZWN0X2hhc2gKICAgICAqCiAgICAgKiBAdmFyIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U+CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJlc2VudE1hcDsKCiAgICAvKioKICAgICAqIFBhY2thZ2VzIHdoaWNoIGNhbm5vdCBiZSBtYXBwZWQsIHBsYXRmb3JtIHJlcG8sIHJvb3QgcGFja2FnZSwgb3RoZXIgZml4ZWQgcmVwb3MKICAgICAqCiAgICAgKiBJbmRleGVkIGJ5IHBhY2thZ2UgaWQKICAgICAqCiAgICAgKiBAdmFyIGFycmF5PGludCwgQmFzZVBhY2thZ2U+CiAgICAgKi8KICAgIHByb3RlY3RlZCAkdW5sb2NrYWJsZU1hcDsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXl7ZGV2OiBCYXNlUGFja2FnZVtdLCBub24tZGV2OiBCYXNlUGFja2FnZVtdLCBhbGw6IEJhc2VQYWNrYWdlW119CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVzdWx0UGFja2FnZXM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZT4gJHByZXNlbnRNYXAKICAgICAqIEBwYXJhbSBhcnJheTxpbnQsIEJhc2VQYWNrYWdlPiAkdW5sb2NrYWJsZU1hcAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUG9vbCAkcG9vbCwgYXJyYXkgJHByZXNlbnRNYXAsIGFycmF5ICR1bmxvY2thYmxlTWFwLCBEZWNpc2lvbnMgJGRlY2lzaW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+cHJlc2VudE1hcCA9ICRwcmVzZW50TWFwOwogICAgICAgICR0aGlzLT51bmxvY2thYmxlTWFwID0gJHVubG9ja2FibGVNYXA7CgogICAgICAgICR0aGlzLT5zZXRSZXN1bHRQYWNrYWdlcygkcG9vbCwgJGRlY2lzaW9ucyk7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkdGhpcy0+cHJlc2VudE1hcCwgJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydhbGwnXSk7CiAgICB9CgogICAgLy8gVE9ETyBtYWtlIHRoaXMgYSBiaXQgcHJldHRpZXIgaW5zdGVhZCBvZiB0aGUgdHdvIHRleHQgaW5kZXhlcz8KICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXN1bHRQYWNrYWdlcyhQb29sICRwb29sLCBEZWNpc2lvbnMgJGRlY2lzaW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+cmVzdWx0UGFja2FnZXMgPSBhcnJheSgnYWxsJyA9PiBhcnJheSgpLCAnbm9uLWRldicgPT4gYXJyYXkoKSwgJ2RldicgPT4gYXJyYXkoKSk7CiAgICAgICAgZm9yZWFjaCAoJGRlY2lzaW9ucyBhcyAkaSA9PiAkZGVjaXNpb24pIHsKICAgICAgICAgICAgJGxpdGVyYWwgPSAkZGVjaXNpb25bRGVjaXNpb25zOjpERUNJU0lPTl9MSVRFUkFMXTsKCiAgICAgICAgICAgIGlmICgkbGl0ZXJhbCA+IDApIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpOwoKICAgICAgICAgICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlc1snYWxsJ11bXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dW5sb2NrYWJsZU1hcFskcGFja2FnZS0+aWRdKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlc1snbm9uLWRldiddW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Tm9uRGV2UGFja2FnZXMoTG9ja1RyYW5zYWN0aW9uICRleHRyYWN0aW9uUmVzdWx0KQogICAgewogICAgICAgICRwYWNrYWdlcyA9ICRleHRyYWN0aW9uUmVzdWx0LT5nZXROZXdMb2NrUGFja2FnZXMoZmFsc2UpOwoKICAgICAgICAkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ2RldiddID0gJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydub24tZGV2J107CiAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydub24tZGV2J10gPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydkZXYnXSBhcyAkaSA9PiAkcmVzdWx0UGFja2FnZSkgewogICAgICAgICAgICAgICAgLy8gVE9ETyB0aGlzIGNvbXBhcmlzb24gaXMgcHJvYmFibHkgaW5zdWZmaWNpZW50LCBhbGlhc2VzLCB3aGF0IGFib3V0IG1vZGlmaWVkIHZlcnNpb25zPyBJIGd1ZXNzIHRoZXkgYXJlbid0IHBvc3NpYmxlPwogICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXROYW1lKCkgPT0gJHJlc3VsdFBhY2thZ2UtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlc1snbm9uLWRldiddW10gPSAkcmVzdWx0UGFja2FnZTsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ2RldiddWyRpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gVE9ETyBhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5IG5lZWRzIHRvIGJlIGxvb2tlZCBhdCBoZXJlIGFzIHdlbGw/CiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRkZXZNb2RlCiAgICAgKiBAcGFyYW0gYm9vbCAkdXBkYXRlTWlycm9ycwogICAgICogQHJldHVybiBCYXNlUGFja2FnZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROZXdMb2NrUGFja2FnZXMoJGRldk1vZGUsICR1cGRhdGVNaXJyb3JzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVzdWx0UGFja2FnZXNbJGRldk1vZGUgPyAnZGV2JyA6ICdub24tZGV2J10gYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCEkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgLy8gaWYgd2UncmUganVzdCB1cGRhdGluZyBtaXJyb3JzIHdlIG5lZWQgdG8gcmVzZXQgcmVmZXJlbmNlcyB0byB0aGUgc2FtZSBhcyBjdXJyZW50bHkgInByZXNlbnQiIHBhY2thZ2VzJyByZWZlcmVuY2VzIHRvIGtlZXAgdGhlIGxvY2sgZmlsZSBhcy1pcwogICAgICAgICAgICAgICAgLy8gd2UgZG8gbm90IHJlc2V0IHJlZmVyZW5jZXMgaWYgdGhlIGN1cnJlbnRseSBwcmVzZW50IHBhY2thZ2UgZGlkbid0IGhhdmUgYW55LCBvciBpZiB0aGUgdHlwZSBvZiBWQ1MgaGFzIGNoYW5nZWQKICAgICAgICAgICAgICAgIGlmICgkdXBkYXRlTWlycm9ycyAmJiAhaXNzZXQoJHRoaXMtPnByZXNlbnRNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByZXNlbnRNYXAgYXMgJHByZXNlbnRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0TmFtZSgpID09ICRwcmVzZW50UGFja2FnZS0+Z2V0TmFtZSgpICYmICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT0gJHByZXNlbnRQYWNrYWdlLT5nZXRWZXJzaW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcHJlc2VudFBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpICYmICRwcmVzZW50UGFja2FnZS0+Z2V0U291cmNlVHlwZSgpID09PSAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRwcmVzZW50UGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwcmVzZW50UGFja2FnZS0+Z2V0UmVsZWFzZURhdGUoKSAmJiAkcGFja2FnZSBpbnN0YW5jZW9mIFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0UmVsZWFzZURhdGUoJHByZXNlbnRQYWNrYWdlLT5nZXRSZWxlYXNlRGF0ZSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hpY2ggb2YgdGhlIGdpdmVuIGFsaWFzZXMgZnJvbSBjb21wb3Nlci5qc29uIGFyZSBhY3R1YWxseSBpbiB1c2UgZm9yIHRoZSBsb2NrIGZpbGUKICAgICAqIEBwYXJhbSBhcnJheTxhcnJheXtwYWNrYWdlOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgYWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4gJGFsaWFzZXMKICAgICAqIEByZXR1cm4gYXJyYXk8YXJyYXl7cGFja2FnZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGFsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbGlhc2VzKCRhbGlhc2VzKQogICAgewogICAgICAgICR1c2VkQWxpYXNlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXN1bHRQYWNrYWdlc1snYWxsJ10gYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYWxpYXNlcyBhcyAkaW5kZXggPT4gJGFsaWFzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRhbGlhc1sncGFja2FnZSddID09PSAkcGFja2FnZS0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR1c2VkQWxpYXNlc1tdID0gJGFsaWFzOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkYWxpYXNlc1skaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHVzb3J0KCR1c2VkQWxpYXNlcywgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhWydwYWNrYWdlJ10sICRiWydwYWNrYWdlJ10pOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gJHVzZWRBbGlhc2VzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAaW1wbGVtZW50cyBcSXRlcmF0b3I8UnVsZVNldDo6VFlQRV8qLCBSdWxlPgogKi8KY2xhc3MgUnVsZVNldEl0ZXJhdG9yIGltcGxlbWVudHMgXEl0ZXJhdG9yCnsKICAgIC8qKiBAdmFyIGFycmF5PFJ1bGVTZXQ6OlRZUEVfKiwgUnVsZVtdPiAqLwogICAgcHJvdGVjdGVkICRydWxlczsKICAgIC8qKiBAdmFyIGFycmF5PFJ1bGVTZXQ6OlRZUEVfKj4gKi8KICAgIHByb3RlY3RlZCAkdHlwZXM7CgogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcm90ZWN0ZWQgJGN1cnJlbnRPZmZzZXQ7CiAgICAvKiogQHZhciBSdWxlU2V0OjpUWVBFXyp8LTEgKi8KICAgIHByb3RlY3RlZCAkY3VycmVudFR5cGU7CiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByb3RlY3RlZCAkY3VycmVudFR5cGVPZmZzZXQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8UnVsZVNldDo6VFlQRV8qLCBSdWxlW10+ICRydWxlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJ1bGVzKQogICAgewogICAgICAgICR0aGlzLT5ydWxlcyA9ICRydWxlczsKICAgICAgICAkdGhpcy0+dHlwZXMgPSBhcnJheV9rZXlzKCRydWxlcyk7CiAgICAgICAgc29ydCgkdGhpcy0+dHlwZXMpOwoKICAgICAgICAkdGhpcy0+cmV3aW5kKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFJ1bGUKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlc1skdGhpcy0+Y3VycmVudFR5cGVdWyR0aGlzLT5jdXJyZW50T2Zmc2V0XTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUnVsZVNldDo6VFlQRV8qfC0xCiAgICAgKi8KICAgICNbXFJldHVyblR5cGVXaWxsQ2hhbmdlXQogICAgcHVibGljIGZ1bmN0aW9uIGtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jdXJyZW50VHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBuZXh0KCkKICAgIHsKICAgICAgICAkdGhpcy0+Y3VycmVudE9mZnNldCsrOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5ydWxlc1skdGhpcy0+Y3VycmVudFR5cGVdKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmN1cnJlbnRPZmZzZXQgPj0gXGNvdW50KCR0aGlzLT5ydWxlc1skdGhpcy0+Y3VycmVudFR5cGVdKSkgewogICAgICAgICAgICAkdGhpcy0+Y3VycmVudE9mZnNldCA9IDA7CgogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGVPZmZzZXQrKzsKCiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT50eXBlc1skdGhpcy0+Y3VycmVudFR5cGVPZmZzZXRdKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VHlwZSA9IC0xOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VHlwZSA9ICR0aGlzLT50eXBlc1skdGhpcy0+Y3VycmVudFR5cGVPZmZzZXRdOwogICAgICAgICAgICB9IHdoaWxlIChpc3NldCgkdGhpcy0+dHlwZXNbJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0XSkgJiYgIVxjb3VudCgkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKQogICAgewogICAgICAgICR0aGlzLT5jdXJyZW50T2Zmc2V0ID0gMDsKCiAgICAgICAgJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0ID0gLTE7CiAgICAgICAgJHRoaXMtPmN1cnJlbnRUeXBlID0gLTE7CgogICAgICAgIGRvIHsKICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0Kys7CgogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT50eXBlc1skdGhpcy0+Y3VycmVudFR5cGVPZmZzZXRdKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUeXBlID0gLTE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUeXBlID0gJHRoaXMtPnR5cGVzWyR0aGlzLT5jdXJyZW50VHlwZU9mZnNldF07CiAgICAgICAgfSB3aGlsZSAoaXNzZXQoJHRoaXMtPnR5cGVzWyR0aGlzLT5jdXJyZW50VHlwZU9mZnNldF0pICYmICFcY291bnQoJHRoaXMtPnJ1bGVzWyR0aGlzLT5jdXJyZW50VHlwZV0pKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5ydWxlc1skdGhpcy0+Y3VycmVudFR5cGVdLCAkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXVskdGhpcy0+Y3VycmVudE9mZnNldF0pOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCi8qKgogKiBBbiBleHRlbnNpb24gb2YgU3BsRG91Ymx5TGlua2VkTGlzdCB3aXRoIHNlZWsgYW5kIHJlbW92YWwgb2YgY3VycmVudCBlbGVtZW50CiAqCiAqIFNwbERvdWJseUxpbmtlZExpc3Qgb25seSBhbGxvd3MgZGVsZXRpbmcgYSBwYXJ0aWN1bGFyIG9mZnNldCBhbmQgaGFzIG5vCiAqIG1ldGhvZCB0byBzZXQgdGhlIGludGVybmFsIGl0ZXJhdG9yIHRvIGEgcGFydGljdWxhciBvZmZzZXQuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBleHRlbmRzIFxTcGxEb3VibHlMaW5rZWRMaXN0PFJ1bGVXYXRjaE5vZGU+CiAqLwpjbGFzcyBSdWxlV2F0Y2hDaGFpbiBleHRlbmRzIFxTcGxEb3VibHlMaW5rZWRMaXN0CnsKICAgIC8qKgogICAgICogTW92ZXMgdGhlIGludGVybmFsIGl0ZXJhdG9yIHRvIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CiAgICAgKgogICAgICogQHBhcmFtIGludCAkb2Zmc2V0IFRoZSBvZmZzZXQgdG8gc2VlayB0by4KICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2Vlaygkb2Zmc2V0KQogICAgewogICAgICAgICR0aGlzLT5yZXdpbmQoKTsKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkb2Zmc2V0OyAkaSsrLCAkdGhpcy0+bmV4dCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIGN1cnJlbnQgZWxlbWVudCBmcm9tIHRoZSBsaXN0CiAgICAgKgogICAgICogQXMgU3BsRG91Ymx5TGlua2VkTGlzdCBvbmx5IGFsbG93cyBkZWxldGluZyBhIHBhcnRpY3VsYXIgb2Zmc2V0IGFuZAogICAgICogaW5jb3JyZWN0bHkgc2V0cyB0aGUgaW50ZXJuYWwgaXRlcmF0b3IgaWYgeW91IGRlbGV0ZSB0aGUgY3VycmVudCB2YWx1ZQogICAgICogdGhpcyBtZXRob2Qgc2V0cyB0aGUgaW50ZXJuYWwgaXRlcmF0b3IgYmFjayB0byB0aGUgZm9sbG93aW5nIGVsZW1lbnQKICAgICAqIHVzaW5nIHRoZSBzZWVrIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZSgpCiAgICB7CiAgICAgICAgJG9mZnNldCA9ICR0aGlzLT5rZXkoKTsKICAgICAgICAkdGhpcy0+b2Zmc2V0VW5zZXQoJG9mZnNldCk7CiAgICAgICAgJHRoaXMtPnNlZWsoJG9mZnNldCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBHZW5lcmljUnVsZSBleHRlbmRzIFJ1bGUKewogICAgLyoqIEB2YXIgaW50W10gKi8KICAgIHByb3RlY3RlZCAkbGl0ZXJhbHM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50W10gJGxpdGVyYWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkbGl0ZXJhbHMsICRyZWFzb24sICRyZWFzb25EYXRhKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHJlYXNvbiwgJHJlYXNvbkRhdGEpOwoKICAgICAgICAvLyBzb3J0IGFsbCBwYWNrYWdlcyBhc2NlbmRpbmcgYnkgaWQKICAgICAgICBzb3J0KCRsaXRlcmFscyk7CgogICAgICAgICR0aGlzLT5saXRlcmFscyA9ICRsaXRlcmFsczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50W10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExpdGVyYWxzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxpdGVyYWxzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhhc2goKQogICAgewogICAgICAgICRkYXRhID0gdW5wYWNrKCdpaGFzaCcsIG1kNShpbXBsb2RlKCcsJywgJHRoaXMtPmxpdGVyYWxzKSwgdHJ1ZSkpOwoKICAgICAgICByZXR1cm4gJGRhdGFbJ2hhc2gnXTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGlzIHJ1bGUgaXMgZXF1YWwgdG8gYW5vdGhlciBvbmUKICAgICAqCiAgICAgKiBJZ25vcmVzIHdoZXRoZXIgZWl0aGVyIG9mIHRoZSBydWxlcyBpcyBkaXNhYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIFJ1bGUgJHJ1bGUgVGhlIHJ1bGUgdG8gY2hlY2sgYWdhaW5zdAogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHJ1bGVzIGFyZSBlcXVhbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXF1YWxzKFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saXRlcmFscyA9PT0gJHJ1bGUtPmdldExpdGVyYWxzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQXNzZXJ0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gMSA9PT0gXGNvdW50KCR0aGlzLT5saXRlcmFscyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgcnVsZSBhcyBhIHN0cmluZyBvZiB0aGUgZm9ybWF0IChMaXRlcmFsMXxMaXRlcmFsMnwuLi4pCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+aXNEaXNhYmxlZCgpID8gJ2Rpc2FibGVkKCcgOiAnKCc7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5saXRlcmFscyBhcyAkaSA9PiAkbGl0ZXJhbCkgewogICAgICAgICAgICBpZiAoJGkgIT0gMCkgewogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAnfCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCAuPSAkbGl0ZXJhbDsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgLj0gJyknOwoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7CgovKioKICogU3RvcmVzIGRlY2lzaW9ucyBvbiBpbnN0YWxsaW5nLCByZW1vdmluZyBvciBrZWVwaW5nIHBhY2thZ2VzCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBpbXBsZW1lbnRzIFxJdGVyYXRvcjxhcnJheXswOiBpbnQsIDE6IFJ1bGV9PgogKi8KY2xhc3MgRGVjaXNpb25zIGltcGxlbWVudHMgXEl0ZXJhdG9yLCBcQ291bnRhYmxlCnsKICAgIGNvbnN0IERFQ0lTSU9OX0xJVEVSQUwgPSAwOwogICAgY29uc3QgREVDSVNJT05fUkVBU09OID0gMTsKCiAgICAvKiogQHZhciBQb29sICovCiAgICBwcm90ZWN0ZWQgJHBvb2w7CiAgICAvKiogQHZhciBhcnJheTxpbnQsIGludD4gKi8KICAgIHByb3RlY3RlZCAkZGVjaXNpb25NYXA7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8YXJyYXl7MDogaW50LCAxOiBSdWxlfT4KICAgICAqLwogICAgcHJvdGVjdGVkICRkZWNpc2lvblF1ZXVlID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUG9vbCAkcG9vbCkKICAgIHsKICAgICAgICAkdGhpcy0+cG9vbCA9ICRwb29sOwogICAgICAgICR0aGlzLT5kZWNpc2lvbk1hcCA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWNpZGUoJGxpdGVyYWwsICRsZXZlbCwgUnVsZSAkd2h5KQogICAgewogICAgICAgICR0aGlzLT5hZGREZWNpc2lvbigkbGl0ZXJhbCwgJGxldmVsKTsKICAgICAgICAkdGhpcy0+ZGVjaXNpb25RdWV1ZVtdID0gYXJyYXkoCiAgICAgICAgICAgIHNlbGY6OkRFQ0lTSU9OX0xJVEVSQUwgPT4gJGxpdGVyYWwsCiAgICAgICAgICAgIHNlbGY6OkRFQ0lTSU9OX1JFQVNPTiA9PiAkd2h5LAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNhdGlzZnkoJGxpdGVyYWwpCiAgICB7CiAgICAgICAgJHBhY2thZ2VJZCA9IGFicygkbGl0ZXJhbCk7CgogICAgICAgIHJldHVybiAoCiAgICAgICAgICAgICRsaXRlcmFsID4gMCAmJiBpc3NldCgkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0pICYmICR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSA+IDAgfHwKICAgICAgICAgICAgJGxpdGVyYWwgPCAwICYmIGlzc2V0KCR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSkgJiYgJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdIDwgMAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbmZsaWN0KCRsaXRlcmFsKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWwpOwoKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICAoaXNzZXQoJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdKSAmJiAkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0gPiAwICYmICRsaXRlcmFsIDwgMCkgfHwKICAgICAgICAgICAgKGlzc2V0KCR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSkgJiYgJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdIDwgMCAmJiAkbGl0ZXJhbCA+IDApCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJGxpdGVyYWxPclBhY2thZ2VJZAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWNpZGVkKCRsaXRlcmFsT3JQYWNrYWdlSWQpCiAgICB7CiAgICAgICAgcmV0dXJuICFlbXB0eSgkdGhpcy0+ZGVjaXNpb25NYXBbYWJzKCRsaXRlcmFsT3JQYWNrYWdlSWQpXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsT3JQYWNrYWdlSWQKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5kZWNpZGVkKCRsaXRlcmFsT3JQYWNrYWdlSWQpCiAgICB7CiAgICAgICAgcmV0dXJuIGVtcHR5KCR0aGlzLT5kZWNpc2lvbk1hcFthYnMoJGxpdGVyYWxPclBhY2thZ2VJZCldKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJGxpdGVyYWxPclBhY2thZ2VJZAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWNpZGVkSW5zdGFsbCgkbGl0ZXJhbE9yUGFja2FnZUlkKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWxPclBhY2thZ2VJZCk7CgogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0pICYmICR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSA+IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaXRlcmFsT3JQYWNrYWdlSWQKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWNpc2lvbkxldmVsKCRsaXRlcmFsT3JQYWNrYWdlSWQpCiAgICB7CiAgICAgICAgJHBhY2thZ2VJZCA9IGFicygkbGl0ZXJhbE9yUGFja2FnZUlkKTsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdKSkgewogICAgICAgICAgICByZXR1cm4gYWJzKCR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJGxpdGVyYWxPclBhY2thZ2VJZAogICAgICogQHJldHVybiBSdWxlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlY2lzaW9uUnVsZSgkbGl0ZXJhbE9yUGFja2FnZUlkKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWxPclBhY2thZ2VJZCk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5kZWNpc2lvblF1ZXVlIGFzICRkZWNpc2lvbikgewogICAgICAgICAgICBpZiAoJHBhY2thZ2VJZCA9PT0gYWJzKCRkZWNpc2lvbltzZWxmOjpERUNJU0lPTl9MSVRFUkFMXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZGVjaXNpb25bc2VsZjo6REVDSVNJT05fUkVBU09OXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRxdWV1ZU9mZnNldAogICAgICogQHJldHVybiBhcnJheXswOiBpbnQsIDE6IFJ1bGV9IGEgbGl0ZXJhbCBhbmQgZGVjaXNpb24gcmVhc29uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdE9mZnNldCgkcXVldWVPZmZzZXQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWNpc2lvblF1ZXVlWyRxdWV1ZU9mZnNldF07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRxdWV1ZU9mZnNldAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZE9mZnNldCgkcXVldWVPZmZzZXQpCiAgICB7CiAgICAgICAgcmV0dXJuICRxdWV1ZU9mZnNldCA+PSAwICYmICRxdWV1ZU9mZnNldCA8IFxjb3VudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFJ1bGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxhc3RSZWFzb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVjaXNpb25RdWV1ZVtcY291bnQoJHRoaXMtPmRlY2lzaW9uUXVldWUpIC0gMV1bc2VsZjo6REVDSVNJT05fUkVBU09OXTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsYXN0TGl0ZXJhbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWNpc2lvblF1ZXVlW1xjb3VudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSkgLSAxXVtzZWxmOjpERUNJU0lPTl9MSVRFUkFMXTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXQoKQogICAgewogICAgICAgIHdoaWxlICgkZGVjaXNpb24gPSBhcnJheV9wb3AoJHRoaXMtPmRlY2lzaW9uUXVldWUpKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbk1hcFthYnMoJGRlY2lzaW9uW3NlbGY6OkRFQ0lTSU9OX0xJVEVSQUxdKV0gPSAwOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJG9mZnNldAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNldFRvT2Zmc2V0KCRvZmZzZXQpCiAgICB7CiAgICAgICAgd2hpbGUgKFxjb3VudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSkgPiAkb2Zmc2V0ICsgMSkgewogICAgICAgICAgICAkZGVjaXNpb24gPSBhcnJheV9wb3AoJHRoaXMtPmRlY2lzaW9uUXVldWUpOwogICAgICAgICAgICAkdGhpcy0+ZGVjaXNpb25NYXBbYWJzKCRkZWNpc2lvbltzZWxmOjpERUNJU0lPTl9MSVRFUkFMXSldID0gMDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJldmVydExhc3QoKQogICAgewogICAgICAgICR0aGlzLT5kZWNpc2lvbk1hcFthYnMoJHRoaXMtPmxhc3RMaXRlcmFsKCkpXSA9IDA7CiAgICAgICAgYXJyYXlfcG9wKCR0aGlzLT5kZWNpc2lvblF1ZXVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgICNbXFJldHVyblR5cGVXaWxsQ2hhbmdlXQogICAgcHVibGljIGZ1bmN0aW9uIGNvdW50KCkKICAgIHsKICAgICAgICByZXR1cm4gXGNvdW50KCR0aGlzLT5kZWNpc2lvblF1ZXVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKQogICAgewogICAgICAgIGVuZCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5ezA6IGludCwgMTogUnVsZX18ZmFsc2UKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGN1cnJlbnQoJHRoaXMtPmRlY2lzaW9uUXVldWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiA/aW50CiAgICAgKi8KICAgICNbXFJldHVyblR5cGVXaWxsQ2hhbmdlXQogICAgcHVibGljIGZ1bmN0aW9uIGtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGtleSgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dCgpCiAgICB7CiAgICAgICAgcHJldigkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZSAhPT0gY3VycmVudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRW1wdHkoKQogICAgewogICAgICAgIHJldHVybiBcY291bnQoJHRoaXMtPmRlY2lzaW9uUXVldWUpID09PSAwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAkbGl0ZXJhbAogICAgICogQHBhcmFtIGludCAkbGV2ZWwKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkRGVjaXNpb24oJGxpdGVyYWwsICRsZXZlbCkKICAgIHsKICAgICAgICAkcGFja2FnZUlkID0gYWJzKCRsaXRlcmFsKTsKCiAgICAgICAgJHByZXZpb3VzRGVjaXNpb24gPSBpc3NldCgkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0pID8gJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdIDogbnVsbDsKICAgICAgICBpZiAoJHByZXZpb3VzRGVjaXNpb24gIT0gMCkgewogICAgICAgICAgICAkbGl0ZXJhbFN0cmluZyA9ICR0aGlzLT5wb29sLT5saXRlcmFsVG9QcmV0dHlTdHJpbmcoJGxpdGVyYWwsIGFycmF5KCkpOwogICAgICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5wb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKICAgICAgICAgICAgdGhyb3cgbmV3IFNvbHZlckJ1Z0V4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJUcnlpbmcgdG8gZGVjaWRlICRsaXRlcmFsU3RyaW5nIG9uIGxldmVsICRsZXZlbCwgZXZlbiB0aG91Z2ggJHBhY2thZ2Ugd2FzIHByZXZpb3VzbHkgZGVjaWRlZCBhcyAiLihpbnQpICRwcmV2aW91c0RlY2lzaW9uLiIuIgogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsaXRlcmFsID4gMCkgewogICAgICAgICAgICAkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0gPSAkbGV2ZWw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdID0gLSRsZXZlbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdG9TdHJpbmcoUG9vbCAkcG9vbCA9IG51bGwpCiAgICB7CiAgICAgICAgJGRlY2lzaW9uTWFwID0gJHRoaXMtPmRlY2lzaW9uTWFwOwogICAgICAgIGtzb3J0KCRkZWNpc2lvbk1hcCk7CiAgICAgICAgJHN0ciA9ICdbJzsKICAgICAgICBmb3JlYWNoICgkZGVjaXNpb25NYXAgYXMgJHBhY2thZ2VJZCA9PiAkbGV2ZWwpIHsKICAgICAgICAgICAgJHN0ciAuPSAoKCRwb29sKSA/ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRwYWNrYWdlSWQpIDogJHBhY2thZ2VJZCkuJzonLiRsZXZlbC4nLCc7CiAgICAgICAgfQogICAgICAgICRzdHIgLj0gJ10nOwoKICAgICAgICByZXR1cm4gJHN0cjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50b1N0cmluZygpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwppbnRlcmZhY2UgUG9saWN5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBDb25zdHJhaW50OjpTVFJfT1BfKiAkb3BlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZlcnNpb25Db21wYXJlKFBhY2thZ2VJbnRlcmZhY2UgJGEsIFBhY2thZ2VJbnRlcmZhY2UgJGIsICRvcGVyYXRvcik7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludFtdICAgJGxpdGVyYWxzCiAgICAgKiBAcGFyYW0gID9zdHJpbmcgJHJlcXVpcmVkUGFja2FnZQogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VsZWN0UHJlZmVycmVkUGFja2FnZXMoUG9vbCAkcG9vbCwgYXJyYXkgJGxpdGVyYWxzLCAkcmVxdWlyZWRQYWNrYWdlID0gbnVsbCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBTb2x2ZXJCdWdFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoCiAgICAgICAgICAgICRtZXNzYWdlLiJcblRoaXMgZXhjZXB0aW9uIHdhcyBtb3N0IGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gQ29tcG9zZXIuXG4iLgogICAgICAgICAgICAiUGxlYXNlIHJlcG9ydCB0aGUgY29tbWFuZCB5b3UgcmFuLCB0aGUgZXhhY3QgZXJyb3IgeW91IHJlY2VpdmVkLCBhbmQgeW91ciBjb21wb3Nlci5qc29uIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMgLSB0aGFuayB5b3UhXG4iCiAgICAgICAgKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZUFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFN0YWJpbGl0eUZpbHRlcjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxQbHVnaW5cUHJlUG9vbENyZWF0ZUV2ZW50Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb21waWxpbmdNYXRjaGVyOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNYXRjaEFsbENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNdWx0aUNvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcSW50ZXJ2YWxzOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQb29sQnVpbGRlcgp7CiAgICAvKioKICAgICAqIEB2YXIgaW50W10KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4KICAgICAqLwogICAgcHJpdmF0ZSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzOwogICAgLyoqCiAgICAgKiBAdmFyIGludFtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+CiAgICAgKi8KICAgIHByaXZhdGUgJHN0YWJpbGl0eUZsYWdzOwogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5W10KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgYXJyYXl7YWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4+CiAgICAgKi8KICAgIHByaXZhdGUgJHJvb3RBbGlhc2VzOwogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ1tdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJHJvb3RSZWZlcmVuY2VzOwogICAgLyoqCiAgICAgKiBAdmFyID9FdmVudERpc3BhdGNoZXIKICAgICAqLwogICAgcHJpdmF0ZSAkZXZlbnREaXNwYXRjaGVyOwogICAgLyoqCiAgICAgKiBAdmFyIFBvb2xPcHRpbWl6ZXJ8bnVsbAogICAgICovCiAgICBwcml2YXRlICRwb29sT3B0aW1pemVyOwogICAgLyoqCiAgICAgKiBAdmFyIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5W10KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIEFsaWFzUGFja2FnZVtdPgogICAgICovCiAgICBwcml2YXRlICRhbGlhc01hcCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgQ29uc3RyYWludEludGVyZmFjZVtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlICRwYWNrYWdlc1RvTG9hZCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgQ29uc3RyYWludEludGVyZmFjZVtdCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlICRsb2FkZWRQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXlbXQogICAgICogQHBocHN0YW4tdmFyIGFycmF5PGludCwgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+Pj4KICAgICAqLwogICAgcHJpdmF0ZSAkbG9hZGVkUGVyUmVwbyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgQmFzZVBhY2thZ2VbXQogICAgICovCiAgICBwcml2YXRlICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgQmFzZVBhY2thZ2VbXQogICAgICovCiAgICBwcml2YXRlICR1bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByaXZhdGUgJHVwZGF0ZUFsbG93TGlzdCA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIGFycmF5PFBhY2thZ2VJbnRlcmZhY2U+PiAqLwogICAgcHJpdmF0ZSAkc2tpcHBlZExvYWQgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogS2VlcHMgYSBsaXN0IG9mIGRlcGVuZGVuY2llcyB3aGljaCBhcmUgbG9ja2VkIGJ1dCB3ZXJlIGF1dG8tdW5sb2NrZWQgYXMgdGhleSBhcmUgcGF0aCByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBUaGlzIGhhbGYtdW5sb2NrZWQgc3RhdGUgbWVhbnMgdGhlIHBhY2thZ2UgaXRzZWxmIHdpbGwgdXBkYXRlIGJ1dCB0aGUgVVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUyoKICAgICAqIGZsYWdzIHdpbGwgbm90IGFwcGx5IHVudGlsIHRoZSBwYWNrYWdlIHJlYWxseSBnZXRzIHVubG9ja2VkIGluIHNvbWUgb3RoZXIgd2F5IHRoYW4gYmVpbmcgYSBwYXRoIHJlcG8KICAgICAqCiAgICAgKiBAdmFyIGFycmF5PHN0cmluZywgdHJ1ZT4KICAgICAqLwogICAgcHJpdmF0ZSAkcGF0aFJlcG9VbmxvY2tlZCA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBLZWVwcyBhIGxpc3Qgb2YgZGVwZW5kZW5jaWVzIHdoaWNoIGFyZSByb290IHJlcXVpcmVtZW50cywgYW5kIGFzIHN1Y2gKICAgICAqIGhhdmUgYWxyZWFkeSB0aGVpciBtYXhpbXVtIHJlcXVpcmVkIHJhbmdlIGxvYWRlZCBhbmQgY2FuIG5vdCBiZQogICAgICogZXh0ZW5kZWQgYnkgbWFya1BhY2thZ2VOYW1lRm9yTG9hZGluZwogICAgICoKICAgICAqIFBhY2thZ2VzIGdldCBjbGVhcmVkIGZyb20gdGhpcyBsaXN0IGlmIHRoZXkgZ2V0IHVubG9ja2VkIGFzIGluIHRoYXQgY2FzZQogICAgICogd2UgbmVlZCB0byBhY3R1YWxseSBsb2FkIHRoZW0KICAgICAqCiAgICAgKiBAdmFyIGFycmF5PHN0cmluZywgdHJ1ZT4KICAgICAqLwogICAgcHJpdmF0ZSAkbWF4RXh0ZW5kZWRSZXFzID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHN0cmluZywgYm9vbD4KICAgICAqLwogICAgcHJpdmF0ZSAkdXBkYXRlQWxsb3dXYXJuZWQgPSBhcnJheSgpOwoKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkaW5kZXhDb3VudGVyID0gMDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnRbXSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzIGFycmF5IG9mIHN0YWJpbGl0eSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzCiAgICAgKiBAcGFyYW0gaW50W10gJHN0YWJpbGl0eUZsYWdzIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwYXJhbSBhcnJheVtdICRyb290QWxpYXNlcwogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGFycmF5e2FsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+PiAkcm9vdEFsaWFzZXMKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkcm9vdFJlZmVyZW5jZXMgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IHNvdXJjZSByZWZlcmVuY2UKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkcm9vdFJlZmVyZW5jZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsIGFycmF5ICRzdGFiaWxpdHlGbGFncywgYXJyYXkgJHJvb3RBbGlhc2VzLCBhcnJheSAkcm9vdFJlZmVyZW5jZXMsIElPSW50ZXJmYWNlICRpbywgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsLCBQb29sT3B0aW1pemVyICRwb29sT3B0aW1pemVyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YWNjZXB0YWJsZVN0YWJpbGl0aWVzID0gJGFjY2VwdGFibGVTdGFiaWxpdGllczsKICAgICAgICAkdGhpcy0+c3RhYmlsaXR5RmxhZ3MgPSAkc3RhYmlsaXR5RmxhZ3M7CiAgICAgICAgJHRoaXMtPnJvb3RBbGlhc2VzID0gJHJvb3RBbGlhc2VzOwogICAgICAgICR0aGlzLT5yb290UmVmZXJlbmNlcyA9ICRyb290UmVmZXJlbmNlczsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyID0gJGV2ZW50RGlzcGF0Y2hlcjsKICAgICAgICAkdGhpcy0+cG9vbE9wdGltaXplciA9ICRwb29sT3B0aW1pemVyOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlW10gJHJlcG9zaXRvcmllcwogICAgICogQHJldHVybiBQb29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBidWlsZFBvb2woYXJyYXkgJHJlcG9zaXRvcmllcywgUmVxdWVzdCAkcmVxdWVzdCkKICAgIHsKICAgICAgICBpZiAoJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93TGlzdCgpKSB7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVBbGxvd0xpc3QgPSAkcmVxdWVzdC0+Z2V0VXBkYXRlQWxsb3dMaXN0KCk7CiAgICAgICAgICAgICR0aGlzLT53YXJuQWJvdXROb25NYXRjaGluZ1VwZGF0ZUFsbG93TGlzdCgkcmVxdWVzdCk7CgogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0TG9ja2VkUmVwb3NpdG9yeSgpLT5nZXRQYWNrYWdlcygpIGFzICRsb2NrZWRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pc1VwZGF0ZUFsbG93ZWQoJGxvY2tlZFBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcmVtZW1iZXIgd2hpY2ggcGFja2FnZXMgd2Ugc2tpcHBlZCBsb2FkaW5nIHJlbW90ZSBjb250ZW50IGZvciBpbiB0aGlzIHBhcnRpYWwgdXBkYXRlCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNraXBwZWRMb2FkWyRsb2NrZWRQYWNrYWdlLT5nZXROYW1lKCldW10gPSAkbG9ja2VkUGFja2FnZTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2tpcHBlZExvYWRbJGxpbmstPmdldFRhcmdldCgpXVtdID0gJGxvY2tlZFBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBQYXRoIHJlcG8gcGFja2FnZXMgYXJlIG5ldmVyIGxvYWRlZCBmcm9tIGxvY2ssIHRvIGZvcmNlIHRoZW0gdG8gYWx3YXlzIHJlbWFpbiBpbiBzeW5jCiAgICAgICAgICAgICAgICAgICAgLy8gdW5sZXNzIHN5bWxpbmtpbmcgaXMgZGlzYWJsZWQgaW4gd2hpY2ggY2FzZSB3ZSBwcm9iYWJseSBzaG91bGQgcmF0aGVyIHRyZWF0IHRoZW0gbGlrZQogICAgICAgICAgICAgICAgICAgIC8vIHJlZ3VsYXIgcGFja2FnZXMuIFdlIG1hcmsgdGhlbSBzcGVjaWFsbHkgc28gdGhleSBjYW4gYmUgcmVsb2FkZWQgZnVsbHkgaW5jbHVkaW5nIHVwZGF0ZSBwcm9wYWdhdGlvbgogICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZXkgZG8gZ2V0IHVubG9ja2VkLCBidXQgYnkgZGVmYXVsdCB0aGV5IGFyZSB1bmxvY2tlZCB3aXRob3V0IHVwZGF0ZSBwcm9wYWdhdGlvbi4KICAgICAgICAgICAgICAgICAgICBpZiAoJGxvY2tlZFBhY2thZ2UtPmdldERpc3RUeXBlKCkgPT09ICdwYXRoJykgewogICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNwb3J0T3B0aW9ucyA9ICRsb2NrZWRQYWNrYWdlLT5nZXRUcmFuc3BvcnRPcHRpb25zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRyYW5zcG9ydE9wdGlvbnNbJ3N5bWxpbmsnXSkgfHwgJHRyYW5zcG9ydE9wdGlvbnNbJ3N5bWxpbmsnXSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5wYXRoUmVwb1VubG9ja2VkWyRsb2NrZWRQYWNrYWdlLT5nZXROYW1lKCldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcmVxdWVzdC0+bG9ja1BhY2thZ2UoJGxvY2tlZFBhY2thZ2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0Rml4ZWRPckxvY2tlZFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgLy8gdXNpbmcgTWF0Y2hBbGxDb25zdHJhaW50IGhlcmUgYmVjYXVzZSBmaXhlZCBwYWNrYWdlcyBkbyBub3QgbmVlZCB0byByZXRyaWdnZXIKICAgICAgICAgICAgLy8gbG9hZGluZyBhbnkgcGFja2FnZXMKICAgICAgICAgICAgJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gbmV3IE1hdGNoQWxsQ29uc3RyYWludCgpOwoKICAgICAgICAgICAgLy8gcmVwbGFjZSBtZWFucyBjb25mbGljdCwgc28gaWYgYSBmaXhlZCBwYWNrYWdlIHJlcGxhY2VzIGEgbmFtZSwgbm8gbmVlZCB0byBsb2FkIHRoYXQgb25lLCBwYWNrYWdlcyB3b3VsZCBjb25mbGljdCBhbnl3YXlzCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXBsYWNlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZGVkUGFja2FnZXNbJGxpbmstPmdldFRhcmdldCgpXSA9IG5ldyBNYXRjaEFsbENvbnN0cmFpbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVE9ETyBpbiBob3cgZmFyIGNhbiB3ZSBkbyB0aGUgYWJvdmUgZm9yIGNvbmZsaWN0cz8gSXQncyBtb3JlIHRyaWNreSBjYXVzZSBjb25mbGljdHMgY2FuIGJlIGxpbWl0ZWQgdG8KICAgICAgICAgICAgLy8gc3BlY2lmaWMgdmVyc2lvbnMgd2hpbGUgcmVwbGFjZSBpcyBhIGNvbmZsaWN0IHdpdGggYWxsIHZlcnNpb25zIG9mIHRoZSBuYW1lCgogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VSZXBvc2l0b3J5CiAgICAgICAgICAgICAgICB8fCAkcGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgUGxhdGZvcm1SZXBvc2l0b3J5CiAgICAgICAgICAgICAgICB8fCBTdGFiaWxpdHlGaWx0ZXI6OmlzUGFja2FnZUFjY2VwdGFibGUoJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllcywgJHRoaXMtPnN0YWJpbGl0eUZsYWdzLCAkcGFja2FnZS0+Z2V0TmFtZXMoKSwgJHBhY2thZ2UtPmdldFN0YWJpbGl0eSgpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICR0aGlzLT5sb2FkUGFja2FnZSgkcmVxdWVzdCwgJHJlcG9zaXRvcmllcywgJHBhY2thZ2UsIGZhbHNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXNbXSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0UmVxdWlyZXMoKSBhcyAkcGFja2FnZU5hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgLy8gZml4ZWQgYW5kIGxvY2tlZCBwYWNrYWdlcyBoYXZlIGFscmVhZHkgYmVlbiBhZGRlZCwgc28gaWYgYSByb290IHJlcXVpcmUgbmVlZHMgb25lIG9mIHRoZW0sIG5vIG5lZWQgdG8gZG8gYW55dGhpbmcKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5sb2FkZWRQYWNrYWdlc1skcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlc1RvTG9hZFskcGFja2FnZU5hbWVdID0gJGNvbnN0cmFpbnQ7CiAgICAgICAgICAgICR0aGlzLT5tYXhFeHRlbmRlZFJlcXNbJHBhY2thZ2VOYW1lXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBjbGVhbiB1cCBwYWNrYWdlc1RvTG9hZCBmb3IgYW55dGhpbmcgd2UgbWFudWFsbHkgbWFya2VkIGxvYWRlZCBhYm92ZQogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYWNrYWdlc1RvTG9hZCBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5wYWNrYWdlc1RvTG9hZFskbmFtZV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB3aGlsZSAoIWVtcHR5KCR0aGlzLT5wYWNrYWdlc1RvTG9hZCkpIHsKICAgICAgICAgICAgJHRoaXMtPmxvYWRQYWNrYWdlc01hcmtlZEZvckxvYWRpbmcoJHJlcXVlc3QsICRyZXBvc2l0b3JpZXMpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBhY2thZ2VzIGFzICRpID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgIC8vIHdlIGNoZWNrIGFsbCBhbGlhcyByZWxhdGVkIHBhY2thZ2VzIGF0IG9uY2UsIHNvIG5vIG5lZWQgdG8gY2hlY2sgaW5kaXZpZHVhbCBhbGlhc2VzCiAgICAgICAgICAgIC8vIGlzc2V0IGFsc28gY2hlY2tzIG5vbi1udWxsIHZhbHVlCiAgICAgICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz09JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAkYWxpYXNlZFBhY2thZ2VzID0gYXJyYXkoJGkgPT4gJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hbGlhc01hcFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSkpIHsKICAgICAgICAgICAgICAgICAgICAkYWxpYXNlZFBhY2thZ2VzICs9ICR0aGlzLT5hbGlhc01hcFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkZm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhbGlhc2VkUGFja2FnZXMgYXMgJHBhY2thZ2VPckFsaWFzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKENvbXBpbGluZ01hdGNoZXI6Om1hdGNoKCRjb25zdHJhaW50LCBDb25zdHJhaW50OjpPUF9FUSwgJHBhY2thZ2VPckFsaWFzLT5nZXRWZXJzaW9uKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCEkZm91bmQpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkYWxpYXNlZFBhY2thZ2VzIGFzICRpbmRleCA9PiAkcGFja2FnZU9yQWxpYXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnBhY2thZ2VzWyRpbmRleF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5ldmVudERpc3BhdGNoZXIpIHsKICAgICAgICAgICAgJHByZVBvb2xDcmVhdGVFdmVudCA9IG5ldyBQcmVQb29sQ3JlYXRlRXZlbnQoCiAgICAgICAgICAgICAgICBQbHVnaW5FdmVudHM6OlBSRV9QT09MX0NSRUFURSwKICAgICAgICAgICAgICAgICRyZXBvc2l0b3JpZXMsCiAgICAgICAgICAgICAgICAkcmVxdWVzdCwKICAgICAgICAgICAgICAgICR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMsCiAgICAgICAgICAgICAgICAkdGhpcy0+c3RhYmlsaXR5RmxhZ3MsCiAgICAgICAgICAgICAgICAkdGhpcy0+cm9vdEFsaWFzZXMsCiAgICAgICAgICAgICAgICAkdGhpcy0+cm9vdFJlZmVyZW5jZXMsCiAgICAgICAgICAgICAgICAkdGhpcy0+cGFja2FnZXMsCiAgICAgICAgICAgICAgICAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwcmVQb29sQ3JlYXRlRXZlbnQtPmdldE5hbWUoKSwgJHByZVBvb2xDcmVhdGVFdmVudCk7CiAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlcyA9ICRwcmVQb29sQ3JlYXRlRXZlbnQtPmdldFBhY2thZ2VzKCk7CiAgICAgICAgICAgICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMgPSAkcHJlUG9vbENyZWF0ZUV2ZW50LT5nZXRVbmFjY2VwdGFibGVGaXhlZFBhY2thZ2VzKCk7CiAgICAgICAgfQoKICAgICAgICAkcG9vbCA9IG5ldyBQb29sKCR0aGlzLT5wYWNrYWdlcywgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlcyk7CgogICAgICAgICR0aGlzLT5hbGlhc01hcCA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzVG9Mb2FkID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+bG9hZGVkUGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5sb2FkZWRQZXJSZXBvID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+cGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5tYXhFeHRlbmRlZFJlcXMgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5za2lwcGVkTG9hZCA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPmluZGV4Q291bnRlciA9IDA7CgogICAgICAgICRwb29sID0gJHRoaXMtPnJ1bk9wdGltaXplcigkcmVxdWVzdCwgJHBvb2wpOwoKICAgICAgICBJbnRlcnZhbHM6OmNsZWFyKCk7CgogICAgICAgIHJldHVybiAkcG9vbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoUmVxdWVzdCAkcmVxdWVzdCwgJG5hbWUsIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgLy8gU2tpcCBwbGF0Zm9ybSByZXF1aXJlcyBhdCB0aGlzIHN0YWdlCiAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFJvb3QgcmVxdWlyZSAod2hpY2ggd2FzIG5vdCB1bmxvY2tlZCkgYWxyZWFkeSBsb2FkZWQgdGhlIG1heGltdW0gcmFuZ2Ugc28gbm8KICAgICAgICAvLyBuZWVkIHRvIGNoZWNrIGFueXRoaW5nIGhlcmUKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm1heEV4dGVuZGVkUmVxc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFJvb3QgcmVxdWlyZXMgY2FuIG5vdCBiZSBvdmVycnVsZWQgYnkgZGVwZW5kZW5jaWVzIHNvIHRoZXJlIGlzIG5vIHBvaW50IGluCiAgICAgICAgLy8gZXh0ZW5kaW5nIHRoZSBsb2FkZWQgY29uc3RyYWludCBmb3IgdGhvc2UuCiAgICAgICAgLy8gVGhpcyBpcyB0cmlnZ2VyZWQgd2hlbiBsb2FkaW5nIGEgcm9vdCByZXF1aXJlIHdoaWNoIHdhcyBsb2NrZWQgYnV0IGdvdCB1bmxvY2tlZCwgdGhlbgogICAgICAgIC8vIHdlIG1ha2Ugc3VyZSB0aGF0IHdlIGxvYWQgYXQgbW9zdCB0aGUgaW50ZXJ2YWxzIGNvdmVyZWQgYnkgdGhlIHJvb3QgY29uc3RyYWludC4KICAgICAgICAkcm9vdFJlcXVpcmVzID0gJHJlcXVlc3QtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgaWYgKGlzc2V0KCRyb290UmVxdWlyZXNbJG5hbWVdKSAmJiAhSW50ZXJ2YWxzOjppc1N1YnNldE9mKCRjb25zdHJhaW50LCAkcm9vdFJlcXVpcmVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkcm9vdFJlcXVpcmVzWyRuYW1lXTsKICAgICAgICB9CgogICAgICAgIC8vIE5vdCB5ZXQgbG9hZGVkIG9yIGFscmVhZHkgbWFya2VkIGZvciBhIHJlbG9hZCwgc2V0IHRoZSBjb25zdHJhaW50IHRvIGJlIGxvYWRlZAogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRuYW1lXSkpIHsKICAgICAgICAgICAgLy8gTWF5YmUgaXQgd2FzIGFscmVhZHkgbWFya2VkIGJlZm9yZSBidXQgbm90IGxvYWRlZCB5ZXQuIEluIHRoYXQgY2FzZQogICAgICAgICAgICAvLyB3ZSBoYXZlIHRvIGV4dGVuZCB0aGUgY29uc3RyYWludCAod2UgZG9uJ3QgY2hlY2sgaWYgdGhleSBhcmUgaWRlbnRpY2FsIGJlY2F1c2UKICAgICAgICAgICAgLy8gTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoKSB3aWxsIG9wdGltaXplIGFueXdheSkKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wYWNrYWdlc1RvTG9hZFskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IG1hcmtlZCBmb3IgbG9hZGluZyBhbmQgdGhpcyBkb2VzIG5vdCBleHBhbmQgdGhlIGNvbnN0cmFpbnQgdG8gYmUgbG9hZGVkLCBub3RoaW5nIHRvIGRvCiAgICAgICAgICAgICAgICBpZiAoSW50ZXJ2YWxzOjppc1N1YnNldE9mKCRjb25zdHJhaW50LCAkdGhpcy0+cGFja2FnZXNUb0xvYWRbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBleHRlbmQgdGhlIGNvbnN0cmFpbnQgdG8gYmUgbG9hZGVkCiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9IEludGVydmFsczo6Y29tcGFjdENvbnN0cmFpbnQoTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoYXJyYXkoJHRoaXMtPnBhY2thZ2VzVG9Mb2FkWyRuYW1lXSwgJGNvbnN0cmFpbnQpLCBmYWxzZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+cGFja2FnZXNUb0xvYWRbJG5hbWVdID0gJGNvbnN0cmFpbnQ7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBObyBuZWVkIHRvIGxvYWQgdGhpcyBwYWNrYWdlIHdpdGggdGhpcyBjb25zdHJhaW50IGJlY2F1c2UgaXQgaXMKICAgICAgICAvLyBhIHN1YnNldCBvZiB0aGUgY29uc3RyYWludCB3aXRoIHdoaWNoIHdlIGhhdmUgYWxyZWFkeSBsb2FkZWQgcGFja2FnZXMKICAgICAgICBpZiAoSW50ZXJ2YWxzOjppc1N1YnNldE9mKCRjb25zdHJhaW50LCAkdGhpcy0+bG9hZGVkUGFja2FnZXNbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBXZSBoYXZlIGFscmVhZHkgbG9hZGVkIHRoYXQgcGFja2FnZSBidXQgbm90IGluIHRoZSBjb25zdHJhaW50IHRoYXQncwogICAgICAgIC8vIHJlcXVpcmVkLiBXZSBleHRlbmQgdGhlIGNvbnN0cmFpbnQgYW5kIG1hcmsgdGhhdCBwYWNrYWdlIGFzIG5vdCBiZWluZyBsb2FkZWQKICAgICAgICAvLyB5ZXQgc28gd2UgZ2V0IHRoZSByZXF1aXJlZCBwYWNrYWdlIHZlcnNpb25zCiAgICAgICAgJHRoaXMtPnBhY2thZ2VzVG9Mb2FkWyRuYW1lXSA9IEludGVydmFsczo6Y29tcGFjdENvbnN0cmFpbnQoTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoYXJyYXkoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRuYW1lXSwgJGNvbnN0cmFpbnQpLCBmYWxzZSkpOwogICAgICAgIHVuc2V0KCR0aGlzLT5sb2FkZWRQYWNrYWdlc1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2VbXSAkcmVwb3NpdG9yaWVzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkUGFja2FnZXNNYXJrZWRGb3JMb2FkaW5nKFJlcXVlc3QgJHJlcXVlc3QsIGFycmF5ICRyZXBvc2l0b3JpZXMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBhY2thZ2VzVG9Mb2FkIGFzICRuYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkZWRQYWNrYWdlc1skbmFtZV0gPSAkY29uc3RyYWludDsKICAgICAgICB9CgogICAgICAgICRwYWNrYWdlQmF0Y2ggPSAkdGhpcy0+cGFja2FnZXNUb0xvYWQ7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzVG9Mb2FkID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcmllcyBhcyAkcmVwb0luZGV4ID0+ICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkcGFja2FnZUJhdGNoKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRoZXNlIHJlcG9zIGhhdmUgdGhlaXIgcGFja2FnZXMgZml4ZWQgb3IgbG9ja2VkIGlmIHRoZXkgbmVlZCB0byBiZSBsb2FkZWQgc28gd2UKICAgICAgICAgICAgLy8gbmV2ZXIgbmVlZCB0byBsb2FkIGFueXRoaW5nIGVsc2UgZnJvbSB0aGVtCiAgICAgICAgICAgIGlmICgkcmVwb3NpdG9yeSBpbnN0YW5jZW9mIFBsYXRmb3JtUmVwb3NpdG9yeSB8fCAkcmVwb3NpdG9yeSA9PT0gJHJlcXVlc3QtPmdldExvY2tlZFJlcG9zaXRvcnkoKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCA9ICRyZXBvc2l0b3J5LT5sb2FkUGFja2FnZXMoJHBhY2thZ2VCYXRjaCwgJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllcywgJHRoaXMtPnN0YWJpbGl0eUZsYWdzLCBpc3NldCgkdGhpcy0+bG9hZGVkUGVyUmVwb1skcmVwb0luZGV4XSkgPyAkdGhpcy0+bG9hZGVkUGVyUmVwb1skcmVwb0luZGV4XSA6IGFycmF5KCkpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHJlc3VsdFsnbmFtZXNGb3VuZCddIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAvLyBhdm9pZCBsb2FkaW5nIHRoZSBzYW1lIHBhY2thZ2UgYWdhaW4gZnJvbSBvdGhlciByZXBvc2l0b3JpZXMgb25jZSBpdCBoYXMgYmVlbiBmb3VuZAogICAgICAgICAgICAgICAgdW5zZXQoJHBhY2thZ2VCYXRjaFskbmFtZV0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXN1bHRbJ3BhY2thZ2VzJ10gYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5sb2FkZWRQZXJSZXBvWyRyZXBvSW5kZXhdWyRwYWNrYWdlLT5nZXROYW1lKCldWyRwYWNrYWdlLT5nZXRWZXJzaW9uKCldID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZFBhY2thZ2UoJHJlcXVlc3QsICRyZXBvc2l0b3JpZXMsICRwYWNrYWdlLCAhaXNzZXQoJHRoaXMtPnBhdGhSZXBvVW5sb2NrZWRbJHBhY2thZ2UtPmdldE5hbWUoKV0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRwcm9wYWdhdGVVcGRhdGUKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlW10gJHJlcG9zaXRvcmllcwogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbG9hZFBhY2thZ2UoUmVxdWVzdCAkcmVxdWVzdCwgYXJyYXkgJHJlcG9zaXRvcmllcywgQmFzZVBhY2thZ2UgJHBhY2thZ2UsICRwcm9wYWdhdGVVcGRhdGUpCiAgICB7CiAgICAgICAgJGluZGV4ID0gJHRoaXMtPmluZGV4Q291bnRlcisrOwogICAgICAgICR0aGlzLT5wYWNrYWdlc1skaW5kZXhdID0gJHBhY2thZ2U7CgogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAkdGhpcy0+YWxpYXNNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlLT5nZXRBbGlhc09mKCkpXVskaW5kZXhdID0gJHBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICAkbmFtZSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CgogICAgICAgIC8vIHdlJ3JlIHNpbXBseSBzZXR0aW5nIHRoZSByb290IHJlZmVyZW5jZXMgb24gYWxsIHZlcnNpb25zIGZvciBhIG5hbWUgaGVyZSBhbmQgcmVseSBvbiB0aGUgc29sdmVyIHRvIHBpY2sgdGhlCiAgICAgICAgLy8gcmlnaHQgdmVyc2lvbi4gSXQnZCBiZSBtb3JlIHdvcmsgdG8gZmlndXJlIG91dCB3aGljaCB2ZXJzaW9ucyBhbmQgd2hpY2ggYWxpYXNlcyBvZiB0aG9zZSB2ZXJzaW9ucyB0aGlzIG1heQogICAgICAgIC8vIGFwcGx5IHRvCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5yb290UmVmZXJlbmNlc1skbmFtZV0pKSB7CiAgICAgICAgICAgIC8vIGRvIG5vdCBtb2RpZnkgdGhlIHJlZmVyZW5jZXMgb24gYWxyZWFkeSBsb2NrZWQgb3IgZml4ZWQgcGFja2FnZXMKICAgICAgICAgICAgaWYgKCEkcmVxdWVzdC0+aXNMb2NrZWRQYWNrYWdlKCRwYWNrYWdlKSAmJiAhJHJlcXVlc3QtPmlzRml4ZWRQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCR0aGlzLT5yb290UmVmZXJlbmNlc1skbmFtZV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBwcm9wYWdhdGVVcGRhdGUgaXMgZmFsc2Ugd2UgYXJlIGxvYWRpbmcgYSBmaXhlZCBvciBsb2NrZWQgcGFja2FnZSwgcm9vdCBhbGlhc2VzIGRvIG5vdCBhcHBseSBhcyB0aGV5IGFyZQogICAgICAgIC8vIG1hbnVhbGx5IGxvYWRlZCBhcyBzZXBhcmF0ZSBwYWNrYWdlcyBpbiB0aGlzIGNhc2UKICAgICAgICBpZiAoJHByb3BhZ2F0ZVVwZGF0ZSAmJiBpc3NldCgkdGhpcy0+cm9vdEFsaWFzZXNbJG5hbWVdWyRwYWNrYWdlLT5nZXRWZXJzaW9uKCldKSkgewogICAgICAgICAgICAkYWxpYXMgPSAkdGhpcy0+cm9vdEFsaWFzZXNbJG5hbWVdWyRwYWNrYWdlLT5nZXRWZXJzaW9uKCldOwogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRiYXNlUGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYmFzZVBhY2thZ2UgPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGJhc2VQYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkYWxpYXNQYWNrYWdlID0gbmV3IENvbXBsZXRlQWxpYXNQYWNrYWdlKCRiYXNlUGFja2FnZSwgJGFsaWFzWydhbGlhc19ub3JtYWxpemVkJ10sICRhbGlhc1snYWxpYXMnXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYWxpYXNQYWNrYWdlID0gbmV3IEFsaWFzUGFja2FnZSgkYmFzZVBhY2thZ2UsICRhbGlhc1snYWxpYXNfbm9ybWFsaXplZCddLCAkYWxpYXNbJ2FsaWFzJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRhbGlhc1BhY2thZ2UtPnNldFJvb3RQYWNrYWdlQWxpYXModHJ1ZSk7CgogICAgICAgICAgICAkbmV3SW5kZXggPSAkdGhpcy0+aW5kZXhDb3VudGVyKys7CiAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlc1skbmV3SW5kZXhdID0gJGFsaWFzUGFja2FnZTsKICAgICAgICAgICAgJHRoaXMtPmFsaWFzTWFwW3NwbF9vYmplY3RfaGFzaCgkYWxpYXNQYWNrYWdlLT5nZXRBbGlhc09mKCkpXVskbmV3SW5kZXhdID0gJGFsaWFzUGFja2FnZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICRyZXF1aXJlID0gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICAkbGlua0NvbnN0cmFpbnQgPSAkbGluay0+Z2V0Q29uc3RyYWludCgpOwoKICAgICAgICAgICAgLy8gaWYgdGhlIHJlcXVpcmVkIHBhY2thZ2UgaXMgbG9hZGVkIGFzIGEgbG9ja2VkIHBhY2thZ2Ugb25seSBhbmQgaGFzbid0IGhhZCBpdHMgZGVwcyBhbmFseXplZAogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnNraXBwZWRMb2FkWyRyZXF1aXJlXSkpIHsKICAgICAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGRvaW5nIGEgZnVsbCB1cGRhdGUgb3IgdGhpcyBpcyBhIHBhcnRpYWwgdXBkYXRlIHdpdGggdHJhbnNpdGl2ZSBkZXBzIGFuZCB3ZSdyZSBjdXJyZW50bHkKICAgICAgICAgICAgICAgIC8vIGxvb2tpbmcgYXQgYSBwYWNrYWdlIHdoaWNoIG5lZWRzIHRvIGJlIHVwZGF0ZWQgd2UgbmVlZCB0byB1bmxvY2sgdGhlIHBhY2thZ2Ugd2Ugbm93IGtub3cgaXMgYQogICAgICAgICAgICAgICAgLy8gZGVwZW5kZW5jeSBvZiBhbm90aGVyIHBhY2thZ2Ugd2hpY2ggd2UgYXJlIHRyeWluZyB0byB1cGRhdGUsIGFuZCB0aGVuIGF0dGVtcHQgdG8gbG9hZCBpdCBhZ2FpbgogICAgICAgICAgICAgICAgaWYgKCRwcm9wYWdhdGVVcGRhdGUgJiYgJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHNraXBwZWRSb290UmVxdWlyZXMgPSAkdGhpcy0+Z2V0U2tpcHBlZFJvb3RSZXF1aXJlcygkcmVxdWVzdCwgJHJlcXVpcmUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZVJvb3REZXBlbmRlbmNpZXMoKSB8fCAhJHNraXBwZWRSb290UmVxdWlyZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVubG9ja1BhY2thZ2UoJHJlcXVlc3QsICRyZXBvc2l0b3JpZXMsICRyZXF1aXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoJHJlcXVlc3QsICRyZXF1aXJlLCAkbGlua0NvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRza2lwcGVkUm9vdFJlcXVpcmVzIGFzICRyb290UmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dXBkYXRlQWxsb3dXYXJuZWRbJHJvb3RSZXF1aXJlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXBkYXRlQWxsb3dXYXJuZWRbJHJvb3RSZXF1aXJlXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5EZXBlbmRlbmN5ICcuJHJvb3RSZXF1aXJlLicgaXMgYWxzbyBhIHJvb3QgcmVxdWlyZW1lbnQuIFBhY2thZ2UgaGFzIG5vdCBiZWVuIGxpc3RlZCBhcyBhbiB1cGRhdGUgYXJndW1lbnQsIHNvIGtlZXBpbmcgbG9ja2VkIGF0IG9sZCB2ZXJzaW9uLiBVc2UgLS13aXRoLWFsbC1kZXBlbmRlbmNpZXMgKC1XKSB0byBpbmNsdWRlIHJvb3QgZGVwZW5kZW5jaWVzLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkdGhpcy0+cGF0aFJlcG9VbmxvY2tlZFskcmVxdWlyZV0pICYmICFpc3NldCgkdGhpcy0+bG9hZGVkUGFja2FnZXNbJHJlcXVpcmVdKSkgewogICAgICAgICAgICAgICAgICAgIC8vIGlmIGRvaW5nIGEgcGFydGlhbCB1cGRhdGUgYW5kIGEgcGFja2FnZSBkZXBlbmRzIG9uIGEgcGF0aC1yZXBvLXVubG9ja2VkIHBhY2thZ2Ugd2hpY2ggaXMgbm90IHJlZmVyZW5jZWQgYnkgdGhlIHJvb3QsIHdlIG5lZWQgdG8gZW5zdXJlIGl0IGdldHMgbG9hZGVkIGFzIGl0IHdhcyBub3QgbG9hZGVkIGJ5IHRoZSByZXF1ZXN0J3Mgcm9vdCByZXF1aXJlbWVudHMKICAgICAgICAgICAgICAgICAgICAvLyBhbmQgd291bGQgbm90IGJlIGxvYWRlZCBhYm92ZSBpZiB1cGRhdGUgcHJvcGFnYXRpb24gaXMgbm90IGFsbG93ZWQgKHdoaWNoIGhhcHBlbnMgaWYgdGhlIHJlcXVpcmVyIGlzIGl0c2VsZiBhIHBhdGgtcmVwby11bmxvY2tlZCBwYWNrYWdlKSBvciBpZiB0cmFuc2l0aXZlIGRlcHMgYXJlIG5vdCBhbGxvd2VkIHRvIGJlIHVubG9ja2VkCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoJHJlcXVlc3QsICRyZXF1aXJlLCAkbGlua0NvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoJHJlcXVlc3QsICRyZXF1aXJlLCAkbGlua0NvbnN0cmFpbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSdyZSBkb2luZyBhIHBhcnRpYWwgdXBkYXRlIHdpdGggZGVwcyB3ZSBhbHNvIG5lZWQgdG8gdW5sb2NrIHBhY2thZ2VzIHdoaWNoIGFyZSBiZWluZyByZXBsYWNlZCBpbiBjYXNlCiAgICAgICAgLy8gdGhleSBhcmUgY3VycmVudGx5IGxvY2tlZCBhbmQgdGh1cyBwcmV2ZW50IHRoaXMgdXBkYXRlYWJsZSBwYWNrYWdlIGZyb20gYmVpbmcgaW5zdGFsbGFibGUvdXBkYXRlYWJsZQogICAgICAgIGlmICgkcHJvcGFnYXRlVXBkYXRlICYmICRyZXF1ZXN0LT5nZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoKSkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHJlcGxhY2UgPSAkbGluay0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRyZXBsYWNlXSwgJHRoaXMtPnNraXBwZWRMb2FkWyRyZXBsYWNlXSkpIHsKICAgICAgICAgICAgICAgICAgICAkc2tpcHBlZFJvb3RSZXF1aXJlcyA9ICR0aGlzLT5nZXRTa2lwcGVkUm9vdFJlcXVpcmVzKCRyZXF1ZXN0LCAkcmVwbGFjZSk7CgogICAgICAgICAgICAgICAgICAgIGlmICgkcmVxdWVzdC0+Z2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlUm9vdERlcGVuZGVuY2llcygpIHx8ICEkc2tpcHBlZFJvb3RSZXF1aXJlcykgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dW5sb2NrUGFja2FnZSgkcmVxdWVzdCwgJHJlcG9zaXRvcmllcywgJHJlcGxhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bWFya1BhY2thZ2VOYW1lRm9yTG9hZGluZygkcmVxdWVzdCwgJHJlcGxhY2UsICRsaW5rLT5nZXRDb25zdHJhaW50KCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRza2lwcGVkUm9vdFJlcXVpcmVzIGFzICRyb290UmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dXBkYXRlQWxsb3dXYXJuZWRbJHJvb3RSZXF1aXJlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXBkYXRlQWxsb3dXYXJuZWRbJHJvb3RSZXF1aXJlXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5EZXBlbmRlbmN5ICcuJHJvb3RSZXF1aXJlLicgaXMgYWxzbyBhIHJvb3QgcmVxdWlyZW1lbnQuIFBhY2thZ2UgaGFzIG5vdCBiZWVuIGxpc3RlZCBhcyBhbiB1cGRhdGUgYXJndW1lbnQsIHNvIGtlZXBpbmcgbG9ja2VkIGF0IG9sZCB2ZXJzaW9uLiBVc2UgLS13aXRoLWFsbC1kZXBlbmRlbmNpZXMgKC1XKSB0byBpbmNsdWRlIHJvb3QgZGVwZW5kZW5jaWVzLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBhIHBhcnRpY3VsYXIgbmFtZSBpcyByZXF1aXJlZCBkaXJlY3RseSBpbiB0aGUgcmVxdWVzdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgcGFja2FnZU5hbWUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzUm9vdFJlcXVpcmUoUmVxdWVzdCAkcmVxdWVzdCwgJG5hbWUpCiAgICB7CiAgICAgICAgJHJvb3RSZXF1aXJlcyA9ICRyZXF1ZXN0LT5nZXRSZXF1aXJlcygpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJHJvb3RSZXF1aXJlc1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRTa2lwcGVkUm9vdFJlcXVpcmVzKFJlcXVlc3QgJHJlcXVlc3QsICRuYW1lKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnNraXBwZWRMb2FkWyRuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICAkcm9vdFJlcXVpcmVzID0gJHJlcXVlc3QtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoaXNzZXQoJHJvb3RSZXF1aXJlc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheV9tYXAoZnVuY3Rpb24gKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpIHVzZSAoJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICgkbmFtZSAhPT0gJHBhY2thZ2UtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4nICh2aWEgcmVwbGFjZSBvZiAnLiRuYW1lLicpJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgfSwgJHRoaXMtPnNraXBwZWRMb2FkWyRuYW1lXSk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+c2tpcHBlZExvYWRbJG5hbWVdIGFzICRwYWNrYWdlT3JSZXBsYWNlcikgewogICAgICAgICAgICBpZiAoaXNzZXQoJHJvb3RSZXF1aXJlc1skcGFja2FnZU9yUmVwbGFjZXItPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlc1tdID0gJHBhY2thZ2VPclJlcGxhY2VyLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VPclJlcGxhY2VyLT5nZXRSZXBsYWNlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJvb3RSZXF1aXJlc1skbGluay0+Z2V0VGFyZ2V0KCldKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkbmFtZSAhPT0gJHBhY2thZ2VPclJlcGxhY2VyLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoZXNbXSA9ICRwYWNrYWdlT3JSZXBsYWNlci0+Z2V0TmFtZSgpIC4nICh2aWEgcmVwbGFjZSBvZiAnLiRuYW1lLicpJzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tdID0gJHBhY2thZ2VPclJlcGxhY2VyLT5nZXROYW1lKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgdXBkYXRlIGFsbG93IGxpc3QgYWxsb3dzIHRoaXMgcGFja2FnZSBpbiB0aGUgbG9jayBmaWxlIHRvIGJlIHVwZGF0ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1VwZGF0ZUFsbG93ZWQoQmFzZVBhY2thZ2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCBhcyAkcGF0dGVybiA9PiAkdm9pZCkgewogICAgICAgICAgICAkcGF0dGVyblJlZ2V4cCA9IEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCRwYXR0ZXJuKTsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJHBhdHRlcm5SZWdleHAsICRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gd2FybkFib3V0Tm9uTWF0Y2hpbmdVcGRhdGVBbGxvd0xpc3QoUmVxdWVzdCAkcmVxdWVzdCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0IGFzICRwYXR0ZXJuID0+ICR2b2lkKSB7CiAgICAgICAgICAgICRwYXR0ZXJuUmVnZXhwID0gQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lVG9SZWdleHAoJHBhdHRlcm4pOwogICAgICAgICAgICAvLyB1cGRhdGUgcGF0dGVybiBtYXRjaGVzIGEgbG9ja2VkIHBhY2thZ2U/ID0+IGFsbCBnb29kCiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRMb2NrZWRSZXBvc2l0b3J5KCktPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRwYXR0ZXJuUmVnZXhwLCAkcGFja2FnZS0+Z2V0TmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gdXBkYXRlIHBhdHRlcm4gbWF0Y2hlcyBhIHJvb3QgcmVxdWlyZT8gPT4gYWxsIGdvb2QsIHByb2JhYmx5IGEgbmV3IHBhY2thZ2UKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldFJlcXVpcmVzKCkgYXMgJHBhY2thZ2VOYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgkcGF0dGVyblJlZ2V4cCwgJHBhY2thZ2VOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0cnBvcygkcGF0dGVybiwgJyonKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+UGF0dGVybiAiJyAuICRwYXR0ZXJuIC4gJyIgbGlzdGVkIGZvciB1cGRhdGUgZG9lcyBub3QgbWF0Y2ggYW55IGxvY2tlZCBwYWNrYWdlcy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlBhY2thZ2UgIicgLiAkcGF0dGVybiAuICciIGxpc3RlZCBmb3IgdXBkYXRlIGlzIG5vdCBsb2NrZWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV2ZXJ0cyB0aGUgZGVjaXNpb24gdG8gdXNlIGEgbG9ja2VkIHBhY2thZ2UgaWYgYSBwYXJ0aWFsIHVwZGF0ZSB3aXRoIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzCiAgICAgKiBmb3VuZCB0aGF0IHRoaXMgcGFja2FnZSBhY3R1YWxseSBuZWVkcyB0byBiZSB1cGRhdGVkCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2VbXSAkcmVwb3NpdG9yaWVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1bmxvY2tQYWNrYWdlKFJlcXVlc3QgJHJlcXVlc3QsIGFycmF5ICRyZXBvc2l0b3JpZXMsICRuYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5za2lwcGVkTG9hZFskbmFtZV0gYXMgJHBhY2thZ2VPclJlcGxhY2VyKSB7CiAgICAgICAgICAgIC8vIGlmIHdlIHVuZml4ZWQgYSByZXBsYWNlZCBwYWNrYWdlIG5hbWUsIHdlIGFsc28gbmVlZCB0byB1bmZpeCB0aGUgcmVwbGFjZXIgaXRzZWxmCiAgICAgICAgICAgIC8vIGFzIGxvbmcgYXMgaXQgd2FzIG5vdCB1bmZpeGVkIHlldAogICAgICAgICAgICBpZiAoJHBhY2thZ2VPclJlcGxhY2VyLT5nZXROYW1lKCkgIT09ICRuYW1lICYmIGlzc2V0KCR0aGlzLT5za2lwcGVkTG9hZFskcGFja2FnZU9yUmVwbGFjZXItPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAkcmVwbGFjZXJOYW1lID0gJHBhY2thZ2VPclJlcGxhY2VyLT5nZXROYW1lKCk7CiAgICAgICAgICAgICAgICBpZiAoJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZVJvb3REZXBlbmRlbmNpZXMoKSB8fCAoISR0aGlzLT5pc1Jvb3RSZXF1aXJlKCRyZXF1ZXN0LCAkbmFtZSkgJiYgISR0aGlzLT5pc1Jvb3RSZXF1aXJlKCRyZXF1ZXN0LCAkcmVwbGFjZXJOYW1lKSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dW5sb2NrUGFja2FnZSgkcmVxdWVzdCwgJHJlcG9zaXRvcmllcywgJHJlcGxhY2VyTmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aXNSb290UmVxdWlyZSgkcmVxdWVzdCwgJHJlcGxhY2VyTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoJHJlcXVlc3QsICRyZXBsYWNlck5hbWUsIG5ldyBNYXRjaEFsbENvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYWNrYWdlcyBhcyAkbG9hZGVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVzID0gJGxvYWRlZFBhY2thZ2UtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJlcXVpcmVzWyRyZXBsYWNlck5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5tYXJrUGFja2FnZU5hbWVGb3JMb2FkaW5nKCRyZXF1ZXN0LCAkcmVwbGFjZXJOYW1lLCAkcmVxdWlyZXNbJHJlcGxhY2VyTmFtZV0tPmdldENvbnN0cmFpbnQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cGF0aFJlcG9VbmxvY2tlZFskbmFtZV0pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYWNrYWdlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0TmFtZSgpID09PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmVMb2FkZWRQYWNrYWdlKCRyZXF1ZXN0LCAkcmVwb3NpdG9yaWVzLCAkcGFja2FnZSwgJGluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdW5zZXQoJHRoaXMtPnNraXBwZWRMb2FkWyRuYW1lXSwgJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRuYW1lXSwgJHRoaXMtPm1heEV4dGVuZGVkUmVxc1skbmFtZV0sICR0aGlzLT5wYXRoUmVwb1VubG9ja2VkWyRuYW1lXSk7CgogICAgICAgIC8vIHJlbW92ZSBsb2NrZWQgcGFja2FnZSBieSB0aGlzIG5hbWUgd2hpY2ggd2FzIGFscmVhZHkgaW5pdGlhbGl6ZWQKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0TG9ja2VkUGFja2FnZXMoKSBhcyAkbG9ja2VkUGFja2FnZSkgewogICAgICAgICAgICBpZiAoISgkbG9ja2VkUGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgJiYgJGxvY2tlZFBhY2thZ2UtPmdldE5hbWUoKSA9PT0gJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gJGluZGV4ID0gYXJyYXlfc2VhcmNoKCRsb2NrZWRQYWNrYWdlLCAkdGhpcy0+cGFja2FnZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcXVlc3QtPnVubG9ja1BhY2thZ2UoJGxvY2tlZFBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmVMb2FkZWRQYWNrYWdlKCRyZXF1ZXN0LCAkcmVwb3NpdG9yaWVzLCAkbG9ja2VkUGFja2FnZSwgJGluZGV4KTsKCiAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgYW55IHJlcXVpcmVtZW50cyBmb3IgdGhpcyBwYWNrYWdlIGJ5IG90aGVyIGxvY2tlZCBvciBmaXhlZCBwYWNrYWdlcyBhcmUgbm93CiAgICAgICAgICAgICAgICAgICAgLy8gYWxzbyBsb2FkZWQsIGFzIHRoZXkgd2VyZSBwcmV2aW91c2x5IGlnbm9yZWQgYmVjYXVzZSB0aGUgbG9ja2VkIChub3cgdW5sb2NrZWQpIHBhY2thZ2UgYWxyZWFkeQogICAgICAgICAgICAgICAgICAgIC8vIHNhdGlzZmllZCB0aGVpciByZXF1aXJlbWVudHMKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0Rml4ZWRPckxvY2tlZFBhY2thZ2VzKCkgYXMgJGZpeGVkT3JMb2NrZWRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZml4ZWRPckxvY2tlZFBhY2thZ2UgPT09ICRsb2NrZWRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5za2lwcGVkTG9hZFskZml4ZWRPckxvY2tlZFBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZXMgPSAkZml4ZWRPckxvY2tlZFBhY2thZ2UtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJlcXVpcmVzWyRsb2NrZWRQYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5tYXJrUGFja2FnZU5hbWVGb3JMb2FkaW5nKCRyZXF1ZXN0LCAkbG9ja2VkUGFja2FnZS0+Z2V0TmFtZSgpLCAkcmVxdWlyZXNbJGxvY2tlZFBhY2thZ2UtPmdldE5hbWUoKV0tPmdldENvbnN0cmFpbnQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZVtdICRyZXBvc2l0b3JpZXMKICAgICAqIEBwYXJhbSBpbnQgJGluZGV4CiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZW1vdmVMb2FkZWRQYWNrYWdlKFJlcXVlc3QgJHJlcXVlc3QsIGFycmF5ICRyZXBvc2l0b3JpZXMsIEJhc2VQYWNrYWdlICRwYWNrYWdlLCAkaW5kZXgpCiAgICB7CiAgICAgICAgJHJlcG9JbmRleCA9IGFycmF5X3NlYXJjaCgkcGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpLCAkcmVwb3NpdG9yaWVzLCB0cnVlKTsKCiAgICAgICAgdW5zZXQoJHRoaXMtPmxvYWRlZFBlclJlcG9bJHJlcG9JbmRleF1bJHBhY2thZ2UtPmdldE5hbWUoKV1bJHBhY2thZ2UtPmdldFZlcnNpb24oKV0pOwogICAgICAgIHVuc2V0KCR0aGlzLT5wYWNrYWdlc1skaW5kZXhdKTsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmFsaWFzTWFwW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWxpYXNNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0gYXMgJGFsaWFzSW5kZXggPT4gJGFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmxvYWRlZFBlclJlcG9bJHJlcG9JbmRleF1bJGFsaWFzUGFja2FnZS0+Z2V0TmFtZSgpXVskYWxpYXNQYWNrYWdlLT5nZXRWZXJzaW9uKCldKTsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5wYWNrYWdlc1skYWxpYXNJbmRleF0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5hbGlhc01hcFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQb29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcnVuT3B0aW1pemVyKFJlcXVlc3QgJHJlcXVlc3QsIFBvb2wgJHBvb2wpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5wb29sT3B0aW1pemVyKSB7CiAgICAgICAgICAgIHJldHVybiAkcG9vbDsKICAgICAgICB9CgogICAgICAgICR0b3RhbCA9IFxjb3VudCgkcG9vbC0+Z2V0UGFja2FnZXMoKSk7CgogICAgICAgICRwb29sID0gJHRoaXMtPnBvb2xPcHRpbWl6ZXItPm9wdGltaXplKCRyZXF1ZXN0LCAkcG9vbCk7CgogICAgICAgICRmaWx0ZXJlZCA9ICR0b3RhbCAtIFxjb3VudCgkcG9vbC0+Z2V0UGFja2FnZXMoKSk7CgogICAgICAgIGlmICgwID09PSAkZmlsdGVyZWQpIHsKICAgICAgICAgICAgcmV0dXJuICRwb29sOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzcHJpbnRmKAogICAgICAgICAgICAnPGluZm8+Rm91bmQgJXMgcGFja2FnZSB2ZXJzaW9ucyByZWZlcmVuY2VkIGluIHlvdXIgZGVwZW5kZW5jeSBncmFwaC4gJXMgKCVkJSUpIHdlcmUgb3B0aW1pemVkIGF3YXkuPC9pbmZvPicsCiAgICAgICAgICAgIG51bWJlcl9mb3JtYXQoJHRvdGFsKSwKICAgICAgICAgICAgbnVtYmVyX2Zvcm1hdCgkZmlsdGVyZWQpLAogICAgICAgICAgICByb3VuZCgxMDAvJHRvdGFsKiRmaWx0ZXJlZCkKICAgICAgICApLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSWV9WRVJCT1NFKTsKCiAgICAgICAgcmV0dXJuICRwb29sOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQ7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XExvY2tBcnJheVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludEludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CgovKioKICogUmVwcmVzZW50cyBhIHByb2JsZW0gZGV0ZWN0ZWQgd2hpbGUgc29sdmluZyBkZXBlbmRlbmNpZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFByb2JsZW0KewogICAgLyoqCiAgICAgKiBBIG1hcCBjb250YWluaW5nIHRoZSBpZCBvZiBlYWNoIHJ1bGUgcGFydCBvZiB0aGlzIHByb2JsZW0gYXMgYSBrZXkKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCB0cnVlPgogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlYXNvblNlZW47CgogICAgLyoqCiAgICAgKiBBIHNldCBvZiByZWFzb25zIGZvciB0aGUgcHJvYmxlbSwgZWFjaCBpcyBhIHJ1bGUgb3IgYSByb290IHJlcXVpcmUgYW5kIGEgcnVsZQogICAgICogQHZhciBhcnJheTxpbnQsIGFycmF5PGludCwgUnVsZT4+CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVhc29ucyA9IGFycmF5KCk7CgogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcm90ZWN0ZWQgJHNlY3Rpb24gPSAwOwoKICAgIC8qKgogICAgICogQWRkIGEgcnVsZSBhcyBhIHJlYXNvbgogICAgICoKICAgICAqIEBwYXJhbSBSdWxlICRydWxlIEEgcnVsZSB3aGljaCBpcyBhIHJlYXNvbiBmb3IgdGhpcyBwcm9ibGVtCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJ1bGUoUnVsZSAkcnVsZSkKICAgIHsKICAgICAgICAkdGhpcy0+YWRkUmVhc29uKHNwbF9vYmplY3RfaGFzaCgkcnVsZSksICRydWxlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlIGFsbCByZWFzb25zIGZvciB0aGlzIHByb2JsZW0KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PGludCwgYXJyYXk8aW50LCBSdWxlPj4gVGhlIHByb2JsZW0ncyByZWFzb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWFzb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlYXNvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGh1bWFuIHJlYWRhYmxlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHByb2JsZW0ncyByZWFzb25zCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGlzVmVyYm9zZQogICAgICogQHBhcmFtIGFycmF5PGludHxzdHJpbmcsIEJhc2VQYWNrYWdlPiAkaW5zdGFsbGVkTWFwIEEgbWFwIG9mIGFsbCBwcmVzZW50IHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gYXJyYXk8UnVsZVtdPiAkbGVhcm5lZFBvb2wKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoUmVwb3NpdG9yeVNldCAkcmVwb3NpdG9yeVNldCwgUmVxdWVzdCAkcmVxdWVzdCwgUG9vbCAkcG9vbCwgJGlzVmVyYm9zZSwgYXJyYXkgJGluc3RhbGxlZE1hcCA9IGFycmF5KCksIGFycmF5ICRsZWFybmVkUG9vbCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgLy8gVE9ETyBkb2Vzbid0IHRoaXMgZW50aXJlbHkgZGVmZWF0IHRoZSBwdXJwb3NlIG9mIHRoZSBwcm9ibGVtIHNlY3Rpb25zPyB3aGF0J3MgdGhlIHBvaW50IG9mIHNlY3Rpb25zPwogICAgICAgICRyZWFzb25zID0gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgYXJyYXlfcmV2ZXJzZSgkdGhpcy0+cmVhc29ucykpOwoKICAgICAgICBpZiAoY291bnQoJHJlYXNvbnMpID09PSAxKSB7CiAgICAgICAgICAgIHJlc2V0KCRyZWFzb25zKTsKICAgICAgICAgICAgJHJ1bGUgPSBjdXJyZW50KCRyZWFzb25zKTsKCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHJ1bGUtPmdldFJlYXNvbigpLCBhcnJheShSdWxlOjpSVUxFX1JPT1RfUkVRVUlSRSwgUnVsZTo6UlVMRV9GSVhFRCksIHRydWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCJTaW5nbGUgcmVhc29uIHByb2JsZW1zIG11c3QgY29udGFpbiBhIHJlcXVlc3QgcnVsZS4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlYXNvbkRhdGEgPSAkcnVsZS0+Z2V0UmVhc29uRGF0YSgpOwogICAgICAgICAgICAkcGFja2FnZU5hbWUgPSAkcmVhc29uRGF0YVsncGFja2FnZU5hbWUnXTsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkcmVhc29uRGF0YVsnY29uc3RyYWludCddOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJHBvb2wtPndoYXRQcm92aWRlcygkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbXB0eSgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIlxuICAgICIuaW1wbG9kZShzZWxmOjpnZXRNaXNzaW5nUGFja2FnZVJlYXNvbigkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjpmb3JtYXREZWR1cGxpY2F0ZWRSdWxlcygkcmVhc29ucywgJyAgICAnLCAkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkaW5zdGFsbGVkTWFwLCAkbGVhcm5lZFBvb2wpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFJ1bGVbXSAkcnVsZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGluZGVudAogICAgICogQHBhcmFtIGJvb2wgJGlzVmVyYm9zZQogICAgICogQHBhcmFtIGFycmF5PGludHxzdHJpbmcsIEJhc2VQYWNrYWdlPiAkaW5zdGFsbGVkTWFwIEEgbWFwIG9mIGFsbCBwcmVzZW50IHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gYXJyYXk8UnVsZVtdPiAkbGVhcm5lZFBvb2wKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXREZWR1cGxpY2F0ZWRSdWxlcygkcnVsZXMsICRpbmRlbnQsIFJlcG9zaXRvcnlTZXQgJHJlcG9zaXRvcnlTZXQsIFJlcXVlc3QgJHJlcXVlc3QsIFBvb2wgJHBvb2wsICRpc1ZlcmJvc2UsIGFycmF5ICRpbnN0YWxsZWRNYXAgPSBhcnJheSgpLCBhcnJheSAkbGVhcm5lZFBvb2wgPSBhcnJheSgpKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJHRlbXBsYXRlcyA9IGFycmF5KCk7CiAgICAgICAgJHBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyOwogICAgICAgICRkZWR1cGxpY2F0YWJsZVJ1bGVUeXBlcyA9IGFycmF5KFJ1bGU6OlJVTEVfUEFDS0FHRV9SRVFVSVJFUywgUnVsZTo6UlVMRV9QQUNLQUdFX0NPTkZMSUNUKTsKICAgICAgICBmb3JlYWNoICgkcnVsZXMgYXMgJHJ1bGUpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAkcnVsZS0+Z2V0UHJldHR5U3RyaW5nKCRyZXBvc2l0b3J5U2V0LCAkcmVxdWVzdCwgJHBvb2wsICRpc1ZlcmJvc2UsICRpbnN0YWxsZWRNYXAsICRsZWFybmVkUG9vbCk7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkcnVsZS0+Z2V0UmVhc29uKCksICRkZWR1cGxpY2F0YWJsZVJ1bGVUeXBlcywgdHJ1ZSkgJiYgUHJlZzo6aXNNYXRjaCgne14oP1A8cGFja2FnZT5cUyspICg/UDx2ZXJzaW9uPlxTKykgKD9QPHR5cGU+cmVxdWlyZXN8Y29uZmxpY3RzKX0nLCAkbWVzc2FnZSwgJG0pKSB7CiAgICAgICAgICAgICAgICAkdGVtcGxhdGUgPSBQcmVnOjpyZXBsYWNlKCd7XlxTKyBcUysgfScsICclcyVzICcsICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICRtZXNzYWdlc1tdID0gJHRlbXBsYXRlOwogICAgICAgICAgICAgICAgJHRlbXBsYXRlc1skdGVtcGxhdGVdWyRtWzFdXVskcGFyc2VyLT5ub3JtYWxpemUoJG1bMl0pXSA9ICRtWzJdOwogICAgICAgICAgICAgICAgJHNvdXJjZVBhY2thZ2UgPSAkcnVsZS0+Z2V0U291cmNlUGFja2FnZSgkcG9vbCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG9vbC0+Z2V0UmVtb3ZlZFZlcnNpb25zQnlQYWNrYWdlKHNwbF9vYmplY3RfaGFzaCgkc291cmNlUGFja2FnZSkpIGFzICR2ZXJzaW9uID0+ICRwcmV0dHlWZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAgICAgJHRlbXBsYXRlc1skdGVtcGxhdGVdWyRtWzFdXVskdmVyc2lvbl0gPSAkcHJldHR5VmVyc2lvbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCRtZXNzYWdlICE9PSAnJykgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSAkbWVzc2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoYXJyYXlfdW5pcXVlKCRtZXNzYWdlcykgYXMgJG1lc3NhZ2UpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZW1wbGF0ZXNbJG1lc3NhZ2VdKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRlbXBsYXRlc1skbWVzc2FnZV0gYXMgJHBhY2thZ2UgPT4gJHZlcnNpb25zKSB7CiAgICAgICAgICAgICAgICAgICAgdWtzb3J0KCR2ZXJzaW9ucywgJ3ZlcnNpb25fY29tcGFyZScpOwogICAgICAgICAgICAgICAgICAgIGlmICghJGlzVmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnMgPSBzZWxmOjpjb25kZW5zZVZlcnNpb25MaXN0KCR2ZXJzaW9ucywgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCgkdmVyc2lvbnMpID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIHMgZnJvbSByZXF1aXJlcy9jb25mbGljdHMgdG8gY29ycmVjdCBncmFtbWFyCiAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gUHJlZzo6cmVwbGFjZSgne14oJXMlcyAoPzpyZXF1aXJlfGNvbmZsaWN0KSlzfScsICckMScsICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gc3ByaW50ZigkbWVzc2FnZSwgJHBhY2thZ2UsICdbJy5pbXBsb2RlKCcsICcsICR2ZXJzaW9ucykuJ10nKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBzcHJpbnRmKCRtZXNzYWdlLCAkcGFja2FnZSwgJyAnLnJlc2V0KCR2ZXJzaW9ucykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9ICRtZXNzYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gIlxuJGluZGVudC0gIi5pbXBsb2RlKCJcbiRpbmRlbnQtICIsICRyZXN1bHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0NhdXNlZEJ5TG9jayhSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZWFzb25zIGFzICRzZWN0aW9uUnVsZXMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHNlY3Rpb25SdWxlcyBhcyAkcnVsZSkgewogICAgICAgICAgICAgICAgaWYgKCRydWxlLT5pc0NhdXNlZEJ5TG9jaygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZSBhIHJlYXNvbiBkZXNjcmlwdG9yIGJ1dCBpZ25vcmUgZHVwbGljYXRlcwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgICBBIGNhbm9uaWNhbCBpZGVudGlmaWVyIGZvciB0aGUgcmVhc29uCiAgICAgKiBAcGFyYW0gUnVsZSAgICRyZWFzb24gVGhlIHJlYXNvbiBkZXNjcmlwdG9yCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJlYXNvbigkaWQsIFJ1bGUgJHJlYXNvbikKICAgIHsKICAgICAgICAvLyBUT0RPOiBpZiBhIHJ1bGUgaXMgcGFydCBvZiBhIHByb2JsZW0gZGVzY3JpcHRpb24gaW4gdHdvIHNlY3Rpb25zLCBpc24ndCB0aGlzIGdvaW5nIHRvIHJlbW92ZSBhIG1lc3NhZ2UKICAgICAgICAvLyB0aGF0IGlzIGltcG9ydGFudCB0byB1bmRlcnN0YW5kIHRoZSBpc3N1ZT8KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cmVhc29uU2VlblskaWRdKSkgewogICAgICAgICAgICAkdGhpcy0+cmVhc29uU2VlblskaWRdID0gdHJ1ZTsKICAgICAgICAgICAgJHRoaXMtPnJlYXNvbnNbJHRoaXMtPnNlY3Rpb25dW10gPSAkcmVhc29uOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dFNlY3Rpb24oKQogICAgewogICAgICAgICR0aGlzLT5zZWN0aW9uKys7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqIEBwYXJhbSBib29sICRpc1ZlcmJvc2UKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VOYW1lCiAgICAgKiBAcmV0dXJuIGFycmF5ezA6IHN0cmluZywgMTogc3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldE1pc3NpbmdQYWNrYWdlUmVhc29uKFJlcG9zaXRvcnlTZXQgJHJlcG9zaXRvcnlTZXQsIFJlcXVlc3QgJHJlcXVlc3QsIFBvb2wgJHBvb2wsICRpc1ZlcmJvc2UsICRwYWNrYWdlTmFtZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHBhY2thZ2VOYW1lKSkgewogICAgICAgICAgICAvLyBoYW5kbGUgcGhwL3BocC0qL2hodm0KICAgICAgICAgICAgaWYgKDAgPT09IHN0cmlwb3MoJHBhY2thZ2VOYW1lLCAncGhwJykgfHwgJHBhY2thZ2VOYW1lID09PSAnaGh2bScpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gc2VsZjo6Z2V0UGxhdGZvcm1QYWNrYWdlVmVyc2lvbigkcG9vbCwgJHBhY2thZ2VOYW1lLCBwaHB2ZXJzaW9uKCkpOwoKICAgICAgICAgICAgICAgICRtc2cgPSAiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgIi4kcGFja2FnZU5hbWUuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkuJyBidXQgJzsKCiAgICAgICAgICAgICAgICBpZiAoZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykgfHwgKCRwYWNrYWdlTmFtZSA9PT0gJ2hodm0nICYmIGNvdW50KCRwb29sLT53aGF0UHJvdmlkZXMoJHBhY2thZ2VOYW1lKSkgPiAwKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkbXNnLCAneW91ciBISFZNIHZlcnNpb24gZG9lcyBub3Qgc2F0aXNmeSB0aGF0IHJlcXVpcmVtZW50LicpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZU5hbWUgPT09ICdoaHZtJykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkbXNnLCAnSEhWTSB3YXMgbm90IGRldGVjdGVkIG9uIHRoaXMgbWFjaGluZSwgbWFrZSBzdXJlIGl0IGlzIGluIHlvdXIgUEFUSC4nKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJG1zZywgJ3RoZSAnLiRwYWNrYWdlTmFtZS4nIHBhY2thZ2UgaXMgZGlzYWJsZWQgYnkgeW91ciBwbGF0Zm9ybSBjb25maWcuIEVuYWJsZSBpdCBhZ2FpbiB3aXRoICJjb21wb3NlciBjb25maWcgcGxhdGZvcm0uJy4kcGFja2FnZU5hbWUuJyAtLXVuc2V0Ii4nKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJG1zZywgJ3lvdXIgJy4kcGFja2FnZU5hbWUuJyB2ZXJzaW9uICgnLiAkdmVyc2lvbiAuJykgZG9lcyBub3Qgc2F0aXNmeSB0aGF0IHJlcXVpcmVtZW50LicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBoYW5kbGUgcGhwIGV4dGVuc2lvbnMKICAgICAgICAgICAgaWYgKDAgPT09IHN0cmlwb3MoJHBhY2thZ2VOYW1lLCAnZXh0LScpKSB7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkcGFja2FnZU5hbWUsICcgJykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJy0gJywgIlBIUCBleHRlbnNpb24gIi4kcGFja2FnZU5hbWUuJyBzaG91bGQgYmUgcmVxdWlyZWQgYXMgJy5zdHJfcmVwbGFjZSgnICcsICctJywgJHBhY2thZ2VOYW1lKS4nLicpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRleHQgPSBzdWJzdHIoJHBhY2thZ2VOYW1lLCA0KTsKICAgICAgICAgICAgICAgICRtc2cgPSAiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgUEhQIGV4dGVuc2lvbiAiLiRwYWNrYWdlTmFtZS5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KS4nIGJ1dCAnOwoKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gc2VsZjo6Z2V0UGxhdGZvcm1QYWNrYWdlVmVyc2lvbigkcG9vbCwgJHBhY2thZ2VOYW1lLCBwaHB2ZXJzaW9uKCRleHQpID86ICcwJyk7CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uX2xvYWRlZCgkZXh0KSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RoZSAnLiRwYWNrYWdlTmFtZS4nIHBhY2thZ2UgaXMgZGlzYWJsZWQgYnkgeW91ciBwbGF0Zm9ybSBjb25maWcuIEVuYWJsZSBpdCBhZ2FpbiB3aXRoICJjb21wb3NlciBjb25maWcgcGxhdGZvcm0uJy4kcGFja2FnZU5hbWUuJyAtLXVuc2V0Ii4nLAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRtc2csICdpdCBpcyBtaXNzaW5nIGZyb20geW91ciBzeXN0ZW0uIEluc3RhbGwgb3IgZW5hYmxlIFBIUFwncyAnLiRleHQuJyBleHRlbnNpb24uJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRtc2csICdpdCBoYXMgdGhlIHdyb25nIHZlcnNpb24gaW5zdGFsbGVkICgnLiR2ZXJzaW9uLicpLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBoYW5kbGUgbGlua2VkIGxpYnMKICAgICAgICAgICAgaWYgKDAgPT09IHN0cmlwb3MoJHBhY2thZ2VOYW1lLCAnbGliLScpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkcGFja2FnZU5hbWUpID09PSAnbGliLWljdScpIHsKICAgICAgICAgICAgICAgICAgICAkZXJyb3IgPSBleHRlbnNpb25fbG9hZGVkKCdpbnRsJykgPyAnaXQgaGFzIHRoZSB3cm9uZyB2ZXJzaW9uIGluc3RhbGxlZCwgdHJ5IHVwZ3JhZGluZyB0aGUgaW50bCBleHRlbnNpb24uJyA6ICdpdCBpcyBtaXNzaW5nIGZyb20geW91ciBzeXN0ZW0sIG1ha2Ugc3VyZSB0aGUgaW50bCBleHRlbnNpb24gaXMgbG9hZGVkLic7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgbGlua2VkIGxpYnJhcnkgIi4kcGFja2FnZU5hbWUuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkuJyBidXQgJywgJGVycm9yKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzIGxpbmtlZCBsaWJyYXJ5ICIuJHBhY2thZ2VOYW1lLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpLicgYnV0ICcsICdpdCBoYXMgdGhlIHdyb25nIHZlcnNpb24gaW5zdGFsbGVkIG9yIGlzIG1pc3NpbmcgZnJvbSB5b3VyIHN5c3RlbSwgbWFrZSBzdXJlIHRvIGxvYWQgdGhlIGV4dGVuc2lvbiBwcm92aWRpbmcgaXQuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRsb2NrZWRQYWNrYWdlID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0TG9ja2VkUGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldE5hbWUoKSA9PT0gJHBhY2thZ2VOYW1lKSB7CiAgICAgICAgICAgICAgICAkbG9ja2VkUGFja2FnZSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgaWYgKCRwb29sLT5pc1VuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSAiLCAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLicgaXMgZml4ZWQgdG8gJy4kcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLicgKGxvY2sgZmlsZSB2ZXJzaW9uKSBieSBhIHBhcnRpYWwgdXBkYXRlIGJ1dCB0aGF0IHZlcnNpb24gaXMgcmVqZWN0ZWQgYnkgeW91ciBtaW5pbXVtLXN0YWJpbGl0eS4gTWFrZSBzdXJlIHlvdSBsaXN0IGl0IGFzIGFuIGFyZ3VtZW50IGZvciB0aGUgdXBkYXRlIGNvbW1hbmQuJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gZmlyc3QgY2hlY2sgaWYgdGhlIGFjdHVhbCByZXF1ZXN0ZWQgcGFja2FnZSBpcyBmb3VuZCBpbiBub3JtYWwgY29uZGl0aW9ucwogICAgICAgIC8vIGlmIHNvIGl0IG11c3QgbWVhbiBpdCBpcyByZWplY3RlZCBieSBhbm90aGVyIGNvbnN0cmFpbnQgdGhhbiB0aGUgb25lIGdpdmVuIGhlcmUKICAgICAgICBpZiAoJHBhY2thZ2VzID0gJHJlcG9zaXRvcnlTZXQtPmZpbmRQYWNrYWdlcygkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KSkgewogICAgICAgICAgICAkcm9vdFJlcXMgPSAkcmVwb3NpdG9yeVNldC0+Z2V0Um9vdFJlcXVpcmVzKCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkcm9vdFJlcXNbJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICRmaWx0ZXJlZCA9IGFycmF5X2ZpbHRlcigkcGFja2FnZXMsIGZ1bmN0aW9uICgkcCkgdXNlICgkcm9vdFJlcXMsICRwYWNrYWdlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcm9vdFJlcXNbJHBhY2thZ2VOYW1lXS0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkcC0+Z2V0VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmICgwID09PSBjb3VudCgkZmlsdGVyZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpIC4gJywgJywgJ2ZvdW5kICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJHBhY2thZ2VzLCAkaXNWZXJib3NlLCAkcG9vbCwgJGNvbnN0cmFpbnQpLicgYnV0ICcuKHNlbGY6Omhhc011bHRpcGxlTmFtZXMoJHBhY2thZ2VzKSA/ICd0aGVzZSBjb25mbGljdCcgOiAnaXQgY29uZmxpY3RzJykuJyB3aXRoIHlvdXIgcm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmUgKCcuJHJvb3RSZXFzWyRwYWNrYWdlTmFtZV0tPmdldFByZXR0eVN0cmluZygpLicpLicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGxvY2tlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRmaXhlZENvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkbG9ja2VkUGFja2FnZS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgICRmaWx0ZXJlZCA9IGFycmF5X2ZpbHRlcigkcGFja2FnZXMsIGZ1bmN0aW9uICgkcCkgdXNlICgkZml4ZWRDb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmaXhlZENvbnN0cmFpbnQtPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz09JywgJHAtPmdldFZlcnNpb24oKSkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gY291bnQoJGZpbHRlcmVkKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsICcsICdmb3VuZCAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRwYWNrYWdlcywgJGlzVmVyYm9zZSwgJHBvb2wsICRjb25zdHJhaW50KS4nIGJ1dCB0aGUgcGFja2FnZSBpcyBmaXhlZCB0byAnLiRsb2NrZWRQYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkuJyAobG9jayBmaWxlIHZlcnNpb24pIGJ5IGEgcGFydGlhbCB1cGRhdGUgYW5kIHRoYXQgdmVyc2lvbiBkb2VzIG5vdCBtYXRjaC4gTWFrZSBzdXJlIHlvdSBsaXN0IGl0IGFzIGFuIGFyZ3VtZW50IGZvciB0aGUgdXBkYXRlIGNvbW1hbmQuJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRub25Mb2NrZWRQYWNrYWdlcyA9IGFycmF5X2ZpbHRlcigkcGFja2FnZXMsIGZ1bmN0aW9uICgkcCkgewogICAgICAgICAgICAgICAgcmV0dXJuICEkcC0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgTG9ja0FycmF5UmVwb3NpdG9yeTsKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBpZiAoISRub25Mb2NrZWRQYWNrYWdlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpIC4gJywgJywgJ2ZvdW5kICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJHBhY2thZ2VzLCAkaXNWZXJib3NlLCAkcG9vbCwgJGNvbnN0cmFpbnQpLicgaW4gdGhlIGxvY2sgZmlsZSBidXQgbm90IGluIHJlbW90ZSByZXBvc2l0b3JpZXMsIG1ha2Ugc3VyZSB5b3UgYXZvaWQgdXBkYXRpbmcgdGhpcyBwYWNrYWdlIHRvIGtlZXAgdGhlIG9uZSBmcm9tIHRoZSBsb2NrIGZpbGUuJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsICcsICdmb3VuZCAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRwYWNrYWdlcywgJGlzVmVyYm9zZSwgJHBvb2wsICRjb25zdHJhaW50KS4nIGJ1dCB0aGVzZSB3ZXJlIG5vdCBsb2FkZWQsIGxpa2VseSBiZWNhdXNlICcuKHNlbGY6Omhhc011bHRpcGxlTmFtZXMoJHBhY2thZ2VzKSA/ICd0aGV5IGNvbmZsaWN0JyA6ICdpdCBjb25mbGljdHMnKS4nIHdpdGggYW5vdGhlciByZXF1aXJlLicpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgaWYgdGhlIHBhY2thZ2UgaXMgZm91bmQgd2hlbiBieXBhc3Npbmcgc3RhYmlsaXR5IGNoZWNrcwogICAgICAgIGlmICgkcGFja2FnZXMgPSAkcmVwb3NpdG9yeVNldC0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQsIFJlcG9zaXRvcnlTZXQ6OkFMTE9XX1VOQUNDRVBUQUJMRV9TVEFCSUxJVElFUykpIHsKICAgICAgICAgICAgLy8gd2UgbXVzdCBmaXJzdCB2ZXJpZnkgaWYgYSB2YWxpZCBwYWNrYWdlIHdvdWxkIGJlIGZvdW5kIGluIGEgbG93ZXIgcHJpb3JpdHkgcmVwb3NpdG9yeQogICAgICAgICAgICBpZiAoJGFsbFJlcG9zUGFja2FnZXMgPSAkcmVwb3NpdG9yeVNldC0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQsIFJlcG9zaXRvcnlTZXQ6OkFMTE9XX1NIQURPV0VEX1JFUE9TSVRPUklFUykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxmOjpjb21wdXRlQ2hlY2tGb3JMb3dlclByaW9SZXBvKCRwb29sLCAkaXNWZXJib3NlLCAkcGFja2FnZU5hbWUsICRwYWNrYWdlcywgJGFsbFJlcG9zUGFja2FnZXMsICdtaW5pbXVtLXN0YWJpbGl0eScsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpIC4gJywgJywgJ2ZvdW5kICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJHBhY2thZ2VzLCAkaXNWZXJib3NlLCAkcG9vbCwgJGNvbnN0cmFpbnQpLicgYnV0ICcuKHNlbGY6Omhhc011bHRpcGxlTmFtZXMoJHBhY2thZ2VzKSA/ICd0aGVzZSBkbycgOiAnaXQgZG9lcycpLicgbm90IG1hdGNoIHlvdXIgbWluaW11bS1zdGFiaWxpdHkuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBpZiB0aGUgcGFja2FnZSBpcyBmb3VuZCB3aGVuIGJ5cGFzc2luZyB0aGUgY29uc3RyYWludCBhbmQgc3RhYmlsaXR5IGNoZWNrcwogICAgICAgIGlmICgkcGFja2FnZXMgPSAkcmVwb3NpdG9yeVNldC0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlTmFtZSwgbnVsbCwgUmVwb3NpdG9yeVNldDo6QUxMT1dfVU5BQ0NFUFRBQkxFX1NUQUJJTElUSUVTKSkgewogICAgICAgICAgICAvLyB3ZSBtdXN0IGZpcnN0IHZlcmlmeSBpZiBhIHZhbGlkIHBhY2thZ2Ugd291bGQgYmUgZm91bmQgaW4gYSBsb3dlciBwcmlvcml0eSByZXBvc2l0b3J5CiAgICAgICAgICAgIGlmICgkYWxsUmVwb3NQYWNrYWdlcyA9ICRyZXBvc2l0b3J5U2V0LT5maW5kUGFja2FnZXMoJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCwgUmVwb3NpdG9yeVNldDo6QUxMT1dfU0hBRE9XRURfUkVQT1NJVE9SSUVTKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OmNvbXB1dGVDaGVja0Zvckxvd2VyUHJpb1JlcG8oJHBvb2wsICRpc1ZlcmJvc2UsICRwYWNrYWdlTmFtZSwgJHBhY2thZ2VzLCAkYWxsUmVwb3NQYWNrYWdlcywgJ2NvbnN0cmFpbnQnLCAkY29uc3RyYWludCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzdWZmaXggPSAnJzsKICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50IGluc3RhbmNlb2YgQ29uc3RyYWludCAmJiAkY29uc3RyYWludC0+Z2V0VmVyc2lvbigpID09PSAnZGV2LW1hc3RlcicpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRjYW5kaWRhdGUtPmdldFZlcnNpb24oKSwgYXJyYXkoJ2Rldi1kZWZhdWx0JywgJ2Rldi1tYWluJyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzdWZmaXggPSAnIFBlcmhhcHMgZGV2LW1hc3RlciB3YXMgcmVuYW1lZCB0byAnLiRjYW5kaWRhdGUtPmdldFByZXR0eVZlcnNpb24oKS4nPyc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIHJvb3QgcGFja2FnZSBpcyBhIG5hbWUgbWF0Y2ggYW5kIGhpbnQgdGhlIGRlcGVuZGVuY2llcyBvbiByb290IHRyb3VibGVzaG9vdGluZyBhcnRpY2xlCiAgICAgICAgICAgICRhbGxSZXBvc1BhY2thZ2VzID0gJHBhY2thZ2VzOwogICAgICAgICAgICAkdG9wUGFja2FnZSA9IHJlc2V0KCRhbGxSZXBvc1BhY2thZ2VzKTsKICAgICAgICAgICAgaWYgKCR0b3BQYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICRzdWZmaXggPSAnIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kZXAtb24tcm9vdCBmb3IgZGV0YWlscyBhbmQgYXNzaXN0YW5jZS4nOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzICRwYWNrYWdlTmFtZSIuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkgLiAnLCAnLCAnZm91bmQgJy5zZWxmOjpnZXRQYWNrYWdlTGlzdCgkcGFja2FnZXMsICRpc1ZlcmJvc2UsICRwb29sLCAkY29uc3RyYWludCkuJyBidXQgJy4oc2VsZjo6aGFzTXVsdGlwbGVOYW1lcygkcGFja2FnZXMpID8gJ3RoZXNlIGRvJyA6ICdpdCBkb2VzJykuJyBub3QgbWF0Y2ggdGhlIGNvbnN0cmFpbnQuJyAuICRzdWZmaXgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7XltBLVphLXowLTlfLi8tXSskfScsICRwYWNrYWdlTmFtZSkpIHsKICAgICAgICAgICAgJGlsbGVnYWxDaGFycyA9IFByZWc6OnJlcGxhY2UoJ3tbQS1aYS16MC05Xy4vLV0rfScsICcnLCAkcGFja2FnZU5hbWUpOwoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUsIGl0ICIsICdjb3VsZCBub3QgYmUgZm91bmQsIGl0IGxvb2tzIGxpa2UgaXRzIG5hbWUgaXMgaW52YWxpZCwgIicuJGlsbGVnYWxDaGFycy4nIiBpcyBub3QgYWxsb3dlZCBpbiBwYWNrYWdlIG5hbWVzLicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwcm92aWRlcnMgPSAkcmVwb3NpdG9yeVNldC0+Z2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkpIHsKICAgICAgICAgICAgJG1heFByb3ZpZGVycyA9IDIwOwogICAgICAgICAgICAkcHJvdmlkZXJzU3RyID0gaW1wbG9kZShhcnJheV9tYXAoZnVuY3Rpb24gKCRwKSB7CiAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSAkcFsnZGVzY3JpcHRpb24nXSA/ICcgJy5zdWJzdHIoJHBbJ2Rlc2NyaXB0aW9uJ10sIDAsIDEwMCkgOiAnJzsKCiAgICAgICAgICAgICAgICByZXR1cm4gIiAgICAgIC0gJHtwWyduYW1lJ119Ii4kZGVzY3JpcHRpb24uIlxuIjsKICAgICAgICAgICAgfSwgY291bnQoJHByb3ZpZGVycykgPiAkbWF4UHJvdmlkZXJzICsgMSA/IGFycmF5X3NsaWNlKCRwcm92aWRlcnMsIDAsICRtYXhQcm92aWRlcnMpIDogJHByb3ZpZGVycykpOwogICAgICAgICAgICBpZiAoY291bnQoJHByb3ZpZGVycykgPiAkbWF4UHJvdmlkZXJzICsgMSkgewogICAgICAgICAgICAgICAgJHByb3ZpZGVyc1N0ciAuPSAnICAgICAgLi4uIGFuZCAnLihjb3VudCgkcHJvdmlkZXJzKSAtICRtYXhQcm92aWRlcnMpLicgbW9yZS4nLiJcbiI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KS4iLCBpdCAiLCAiY291bGQgbm90IGJlIGZvdW5kIGluIGFueSB2ZXJzaW9uLCBidXQgdGhlIGZvbGxvd2luZyBwYWNrYWdlcyBwcm92aWRlIGl0OlxuIi4kcHJvdmlkZXJzU3RyLiIgICAgICBDb25zaWRlciByZXF1aXJpbmcgb25lIG9mIHRoZXNlIHRvIHNhdGlzZnkgdGhlICRwYWNrYWdlTmFtZSByZXF1aXJlbWVudC4iKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lLCBpdCAiLCAiY291bGQgbm90IGJlIGZvdW5kIGluIGFueSB2ZXJzaW9uLCB0aGVyZSBtYXkgYmUgYSB0eXBvIGluIHRoZSBwYWNrYWdlIG5hbWUuIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlW10gJHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gYm9vbCAkaXNWZXJib3NlCiAgICAgKiBAcGFyYW0gYm9vbCAkdXNlUmVtb3ZlZFZlcnNpb25Hcm91cAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRQYWNrYWdlTGlzdChhcnJheSAkcGFja2FnZXMsICRpc1ZlcmJvc2UsIFBvb2wgJHBvb2wgPSBudWxsLCBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50ID0gbnVsbCwgJHVzZVJlbW92ZWRWZXJzaW9uR3JvdXAgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcHJlcGFyZWQgPSBhcnJheSgpOwogICAgICAgICRoYXNEZWZhdWx0QnJhbmNoID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHByZXBhcmVkWyRwYWNrYWdlLT5nZXROYW1lKCldWyduYW1lJ10gPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgICAgICAkcHJlcGFyZWRbJHBhY2thZ2UtPmdldE5hbWUoKV1bJ3ZlcnNpb25zJ11bJHBhY2thZ2UtPmdldFZlcnNpb24oKV0gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLigkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSA/ICcgKGFsaWFzIG9mICcuJHBhY2thZ2UtPmdldEFsaWFzT2YoKS0+Z2V0UHJldHR5VmVyc2lvbigpLicpJyA6ICcnKTsKICAgICAgICAgICAgaWYgKCRwb29sICYmICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG9vbC0+Z2V0UmVtb3ZlZFZlcnNpb25zKCRwYWNrYWdlLT5nZXROYW1lKCksICRjb25zdHJhaW50KSBhcyAkdmVyc2lvbiA9PiAkcHJldHR5VmVyc2lvbikgewogICAgICAgICAgICAgICAgICAgICRwcmVwYXJlZFskcGFja2FnZS0+Z2V0TmFtZSgpXVsndmVyc2lvbnMnXVskdmVyc2lvbl0gPSAkcHJldHR5VmVyc2lvbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHBvb2wgJiYgJHVzZVJlbW92ZWRWZXJzaW9uR3JvdXApIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwb29sLT5nZXRSZW1vdmVkVmVyc2lvbnNCeVBhY2thZ2Uoc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKSkgYXMgJHZlcnNpb24gPT4gJHByZXR0eVZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAkcHJlcGFyZWRbJHBhY2thZ2UtPmdldE5hbWUoKV1bJ3ZlcnNpb25zJ11bJHZlcnNpb25dID0gJHByZXR0eVZlcnNpb247CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5pc0RlZmF1bHRCcmFuY2goKSkgewogICAgICAgICAgICAgICAgJGhhc0RlZmF1bHRCcmFuY2hbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcHJlcGFyZWRTdHJpbmdzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcHJlcGFyZWQgYXMgJG5hbWUgPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBpbXBsaWNpdCBkZWZhdWx0IGJyYW5jaCBhbGlhcyB0byBhdm9pZCBjcnVmdCBpbiB0aGUgZGlzcGxheQogICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ3ZlcnNpb25zJ11bVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVNdLCAkaGFzRGVmYXVsdEJyYW5jaFskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkcGFja2FnZVsndmVyc2lvbnMnXVtWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBU10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICB1a3NvcnQoJHBhY2thZ2VbJ3ZlcnNpb25zJ10sICd2ZXJzaW9uX2NvbXBhcmUnKTsKCiAgICAgICAgICAgIGlmICghJGlzVmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VbJ3ZlcnNpb25zJ10gPSBzZWxmOjpjb25kZW5zZVZlcnNpb25MaXN0KCRwYWNrYWdlWyd2ZXJzaW9ucyddLCA0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcHJlcGFyZWRTdHJpbmdzW10gPSAkcGFja2FnZVsnbmFtZSddLidbJy5pbXBsb2RlKCcsICcsICRwYWNrYWdlWyd2ZXJzaW9ucyddKS4nXSc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaW1wbG9kZSgnLCAnLCAkcHJlcGFyZWRTdHJpbmdzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYWNrYWdlTmFtZQogICAgICogQHBhcmFtICBzdHJpbmcgJHZlcnNpb24gdGhlIGVmZmVjdGl2ZSBydW50aW1lIHZlcnNpb24gb2YgdGhlIHBsYXRmb3JtIHBhY2thZ2UKICAgICAqIEByZXR1cm4gP3N0cmluZyBhIHZlcnNpb24gc3RyaW5nIG9yIG51bGwgaWYgaXQgYXBwZWFycyB0aGUgcGFja2FnZSB3YXMgYXJ0aWZpY2lhbGx5IGRpc2FibGVkCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldFBsYXRmb3JtUGFja2FnZVZlcnNpb24oUG9vbCAkcG9vbCwgJHBhY2thZ2VOYW1lLCAkdmVyc2lvbikKICAgIHsKICAgICAgICAkYXZhaWxhYmxlID0gJHBvb2wtPndoYXRQcm92aWRlcygkcGFja2FnZU5hbWUpOwoKICAgICAgICBpZiAoY291bnQoJGF2YWlsYWJsZSkpIHsKICAgICAgICAgICAgJHNlbGVjdGVkID0gbnVsbDsKICAgICAgICAgICAgZm9yZWFjaCAoJGF2YWlsYWJsZSBhcyAkcGtnKSB7CiAgICAgICAgICAgICAgICBpZiAoJHBrZy0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgUGxhdGZvcm1SZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICAgICAgJHNlbGVjdGVkID0gJHBrZzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHNlbGVjdGVkID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkc2VsZWN0ZWQgPSByZXNldCgkYXZhaWxhYmxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gbXVzdCBiZSBhIHBhY2thZ2UgcHJvdmlkaW5nL3JlcGxhY2luZyBhbmQgbm90IGEgcmVhbCBwbGF0Zm9ybSBwYWNrYWdlCiAgICAgICAgICAgIGlmICgkc2VsZWN0ZWQtPmdldE5hbWUoKSAhPT0gJHBhY2thZ2VOYW1lKSB7CiAgICAgICAgICAgICAgICAvKiogQHZhciBMaW5rICRsaW5rICovCiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZShhcnJheV92YWx1ZXMoJHNlbGVjdGVkLT5nZXRQcm92aWRlcygpKSwgYXJyYXlfdmFsdWVzKCRzZWxlY3RlZC0+Z2V0UmVwbGFjZXMoKSkpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRsaW5rLT5nZXRUYXJnZXQoKSA9PT0gJHBhY2thZ2VOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpLicgJy5zdWJzdHIoJGxpbmstPmdldERlc2NyaXB0aW9uKCksIDAsIC0xKS4nZCBieSAnLiRzZWxlY3RlZC0+Z2V0UHJldHR5U3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdmVyc2lvbiA9ICRzZWxlY3RlZC0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAkZXh0cmEgPSAkc2VsZWN0ZWQtPmdldEV4dHJhKCk7CiAgICAgICAgICAgIGlmICgkc2VsZWN0ZWQgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJiYgaXNzZXQoJGV4dHJhWydjb25maWcucGxhdGZvcm0nXSkgJiYgJGV4dHJhWydjb25maWcucGxhdGZvcm0nXSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgJHZlcnNpb24gLj0gJzsgJyAuIHN0cl9yZXBsYWNlKCdQYWNrYWdlICcsICcnLCAkc2VsZWN0ZWQtPmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHZlcnNpb25zIGFuIGFycmF5IG9mIHByZXR0eSB2ZXJzaW9ucywgd2l0aCBub3JtYWxpemVkIHZlcnNpb25zIGFzIGtleXMKICAgICAqIEBwYXJhbSBpbnQgJG1heAogICAgICogQHBhcmFtIGludCAkbWF4RGV2CiAgICAgKiBAcmV0dXJuIGxpc3Q8c3RyaW5nPiBhIGxpc3Qgb2YgcHJldHR5IHZlcnNpb25zIGFuZCAnLi4uJyB3aGVyZSB2ZXJzaW9ucyB3ZXJlIHJlbW92ZWQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY29uZGVuc2VWZXJzaW9uTGlzdChhcnJheSAkdmVyc2lvbnMsICRtYXgsICRtYXhEZXYgPSAxNikKICAgIHsKICAgICAgICBpZiAoY291bnQoJHZlcnNpb25zKSA8PSAkbWF4KSB7CiAgICAgICAgICAgIHJldHVybiAkdmVyc2lvbnM7CiAgICAgICAgfQoKICAgICAgICAkZmlsdGVyZWQgPSBhcnJheSgpOwogICAgICAgICRieU1ham9yID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24gPT4gJHByZXR0eSkgewogICAgICAgICAgICBpZiAoMCA9PT0gc3RyaXBvcygkdmVyc2lvbiwgJ2Rldi0nKSkgewogICAgICAgICAgICAgICAgJGJ5TWFqb3JbJ2RldiddW10gPSAkcHJldHR5OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGJ5TWFqb3JbUHJlZzo6cmVwbGFjZSgne14oXGQrKVwuLip9JywgJyQxJywgJHZlcnNpb24pXVtdID0gJHByZXR0eTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkYnlNYWpvciBhcyAkbWFqb3JWZXJzaW9uID0+ICR2ZXJzaW9uc0Zvck1ham9yKSB7CiAgICAgICAgICAgICRtYXhWZXJzaW9ucyA9ICRtYWpvclZlcnNpb24gPT09ICdkZXYnID8gJG1heERldiA6ICRtYXg7CiAgICAgICAgICAgIGlmIChjb3VudCgkdmVyc2lvbnNGb3JNYWpvcikgPiAkbWF4VmVyc2lvbnMpIHsKICAgICAgICAgICAgICAgIC8vIG91dHB1dCBvbmx5IDFzdCBhbmQgbGFzdCB2ZXJzaW9ucwogICAgICAgICAgICAgICAgJGZpbHRlcmVkW10gPSAkdmVyc2lvbnNGb3JNYWpvclswXTsKICAgICAgICAgICAgICAgICRmaWx0ZXJlZFtdID0gJy4uLic7CiAgICAgICAgICAgICAgICAkZmlsdGVyZWRbXSA9ICR2ZXJzaW9uc0Zvck1ham9yW2NvdW50KCR2ZXJzaW9uc0Zvck1ham9yKSAtIDFdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGZpbHRlcmVkID0gYXJyYXlfbWVyZ2UoJGZpbHRlcmVkLCAkdmVyc2lvbnNGb3JNYWpvcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkZmlsdGVyZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdICRwYWNrYWdlcwogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGhhc011bHRpcGxlTmFtZXMoYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgICRuYW1lID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRuYW1lID09PSBudWxsIHx8ICRuYW1lID09PSAkcGFja2FnZS0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICAgICAkbmFtZSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGlzVmVyYm9zZQogICAgICogQHBhcmFtIHN0cmluZyAkcGFja2FnZU5hbWUKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlW10gJGhpZ2hlclJlcG9QYWNrYWdlcwogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2VbXSAkYWxsUmVwb3NQYWNrYWdlcwogICAgICogQHBhcmFtIHN0cmluZyAkcmVhc29uCiAgICAgKiBAcmV0dXJuIGFycmF5ezA6IHN0cmluZywgMTogc3RyaW5nfQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb21wdXRlQ2hlY2tGb3JMb3dlclByaW9SZXBvKFBvb2wgJHBvb2wsICRpc1ZlcmJvc2UsICRwYWNrYWdlTmFtZSwgYXJyYXkgJGhpZ2hlclJlcG9QYWNrYWdlcywgYXJyYXkgJGFsbFJlcG9zUGFja2FnZXMsICRyZWFzb24sIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgPSBudWxsKQogICAgewogICAgICAgICRuZXh0UmVwb1BhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkbmV4dFJlcG8gPSBudWxsOwoKICAgICAgICBmb3JlYWNoICgkYWxsUmVwb3NQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJG5leHRSZXBvID09PSBudWxsIHx8ICRuZXh0UmVwbyA9PT0gJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKSkgewogICAgICAgICAgICAgICAgJG5leHRSZXBvUGFja2FnZXNbXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgJG5leHRSZXBvID0gJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhpZ2hlclJlcG9QYWNrYWdlcykgewogICAgICAgICAgICAkdG9wUGFja2FnZSA9IHJlc2V0KCRoaWdoZXJSZXBvUGFja2FnZXMpOwogICAgICAgICAgICBpZiAoJHRvcFBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgICAgICItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpLicsIGl0IGlzICcsCiAgICAgICAgICAgICAgICAgICAgJ3NhdGlzZmlhYmxlIGJ5ICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJG5leHRSZXBvUGFja2FnZXMsICRpc1ZlcmJvc2UsICRwb29sLCAkY29uc3RyYWludCkuJyBmcm9tICcuJG5leHRSZXBvLT5nZXRSZXBvTmFtZSgpLicgYnV0ICcuJHRvcFBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGlzIHRoZSByb290IHBhY2thZ2UgYW5kIGNhbm5vdCBiZSBtb2RpZmllZC4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RlcC1vbi1yb290IGZvciBkZXRhaWxzIGFuZCBhc3Npc3RhbmNlLicsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJG5leHRSZXBvIGluc3RhbmNlb2YgTG9ja0FycmF5UmVwb3NpdG9yeSkgewogICAgICAgICAgICAkc2luZ3VsYXIgPSBjb3VudCgkaGlnaGVyUmVwb1BhY2thZ2VzKSA9PT0gMTsKCiAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsIGl0IGlzICcsCiAgICAgICAgICAgICAgICAnZm91bmQgJy5zZWxmOjpnZXRQYWNrYWdlTGlzdCgkbmV4dFJlcG9QYWNrYWdlcywgJGlzVmVyYm9zZSwgJHBvb2wsICRjb25zdHJhaW50KS4nIGluIHRoZSBsb2NrIGZpbGUgYW5kICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJGhpZ2hlclJlcG9QYWNrYWdlcywgJGlzVmVyYm9zZSwgJHBvb2wsICRjb25zdHJhaW50KS4nIGZyb20gJy5yZXNldCgkaGlnaGVyUmVwb1BhY2thZ2VzKS0+Z2V0UmVwb3NpdG9yeSgpLT5nZXRSZXBvTmFtZSgpLicgYnV0ICcgLiAoJHNpbmd1bGFyID8gJ2l0IGRvZXMnIDogJ3RoZXNlIGRvJykgLiAnIG5vdCBtYXRjaCB5b3VyICcuJHJlYXNvbi4nIGFuZCAnIC4gKCRzaW5ndWxhciA/ICdpcycgOiAnYXJlJykgLiAnIHRoZXJlZm9yZSBub3QgaW5zdGFsbGFibGUuIE1ha2Ugc3VyZSB5b3UgZWl0aGVyIGZpeCB0aGUgJy4kcmVhc29uLicgb3IgYXZvaWQgdXBkYXRpbmcgdGhpcyBwYWNrYWdlIHRvIGtlZXAgdGhlIG9uZSBmcm9tIHRoZSBsb2NrIGZpbGUuJywgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsIGl0IGlzICcsICdzYXRpc2ZpYWJsZSBieSAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRuZXh0UmVwb1BhY2thZ2VzLCAkaXNWZXJib3NlLCAkcG9vbCwgJGNvbnN0cmFpbnQpLicgZnJvbSAnLiRuZXh0UmVwby0+Z2V0UmVwb05hbWUoKS4nIGJ1dCAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRoaWdoZXJSZXBvUGFja2FnZXMsICRpc1ZlcmJvc2UsICRwb29sLCAkY29uc3RyYWludCkuJyBmcm9tICcucmVzZXQoJGhpZ2hlclJlcG9QYWNrYWdlcyktPmdldFJlcG9zaXRvcnkoKS0+Z2V0UmVwb05hbWUoKS4nIGhhcyBoaWdoZXIgcmVwb3NpdG9yeSBwcmlvcml0eS4gVGhlIHBhY2thZ2VzIGZyb20gdGhlIGhpZ2hlciBwcmlvcml0eSByZXBvc2l0b3J5IGRvIG5vdCBtYXRjaCB5b3VyICcuJHJlYXNvbi4nIGFuZCBhcmUgdGhlcmVmb3JlIG5vdCBpbnN0YWxsYWJsZS4gVGhhdCByZXBvc2l0b3J5IGlzIGNhbm9uaWNhbCBzbyB0aGUgbG93ZXIgcHJpb3JpdHkgcmVwb1wncyBwYWNrYWdlcyBhcmUgbm90IGluc3RhbGxhYmxlLiBTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvcmVwb3ByaW8gZm9yIGRldGFpbHMgYW5kIGFzc2lzdGFuY2UuJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyBhIGNvbnN0cmFpbnQgaW50byB0ZXh0IHVzYWJsZSBpbiBhIHNlbnRlbmNlIGRlc2NyaWJpbmcgYSByZXF1ZXN0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjb25zdHJhaW50VG9UZXh0KENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiAkY29uc3RyYWludCA/ICcgJy4kY29uc3RyYWludC0+Z2V0UHJldHR5U3RyaW5nKCkgOiAnJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcSWdub3JlTGlzdFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFBsYXRmb3JtUmVwb3NpdG9yeTsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAcGhwc3Rhbi1pbXBvcnQtdHlwZSBSZWFzb25EYXRhIGZyb20gUnVsZQogKi8KY2xhc3MgUnVsZVNldEdlbmVyYXRvcgp7CiAgICAvKiogQHZhciBQb2xpY3lJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkcG9saWN5OwogICAgLyoqIEB2YXIgUG9vbCAqLwogICAgcHJvdGVjdGVkICRwb29sOwogICAgLyoqIEB2YXIgUnVsZVNldCAqLwogICAgcHJvdGVjdGVkICRydWxlczsKICAgIC8qKiBAdmFyIGFycmF5PGludCwgQmFzZVBhY2thZ2U+ICovCiAgICBwcm90ZWN0ZWQgJGFkZGVkTWFwID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2VbXT4gKi8KICAgIHByb3RlY3RlZCAkYWRkZWRQYWNrYWdlc0J5TmFtZXMgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQb2xpY3lJbnRlcmZhY2UgJHBvbGljeSwgUG9vbCAkcG9vbCkKICAgIHsKICAgICAgICAkdGhpcy0+cG9saWN5ID0gJHBvbGljeTsKICAgICAgICAkdGhpcy0+cG9vbCA9ICRwb29sOwogICAgICAgICR0aGlzLT5ydWxlcyA9IG5ldyBSdWxlU2V0OwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBydWxlIGZvciB0aGUgcmVxdWlyZW1lbnRzIG9mIGEgcGFja2FnZQogICAgICoKICAgICAqIFRoaXMgcnVsZSBpcyBvZiB0aGUgZm9ybSAoLUF8QnxDKSwgd2hlcmUgQiBhbmQgQyBhcmUgdGhlIHByb3ZpZGVycyBvZgogICAgICogb25lIHJlcXVpcmVtZW50IG9mIHRoZSBwYWNrYWdlIEEuCiAgICAgKgogICAgICogQHBhcmFtICBCYXNlUGFja2FnZSAkcGFja2FnZSBUaGUgcGFja2FnZSB3aXRoIGEgcmVxdWlyZW1lbnQKICAgICAqIEBwYXJhbSAgQmFzZVBhY2thZ2VbXSAkcHJvdmlkZXJzIFRoZSBwcm92aWRlcnMgb2YgdGhlIHJlcXVpcmVtZW50CiAgICAgKiBAcGFyYW0gIFJ1bGU6OlJVTEVfKiAkcmVhc29uIEEgUlVMRV8qIGNvbnN0YW50IGRlc2NyaWJpbmcgdGhlIHJlYXNvbiBmb3IgZ2VuZXJhdGluZyB0aGlzIHJ1bGUKICAgICAqIEBwYXJhbSAgbWl4ZWQgJHJlYXNvbkRhdGEgQW55IGRhdGEsIGUuZy4gdGhlIHJlcXVpcmVtZW50IG5hbWUsIHRoYXQgZ29lcyB3aXRoIHRoZSByZWFzb24KICAgICAqIEByZXR1cm4gUnVsZXxudWxsIFRoZSBnZW5lcmF0ZWQgcnVsZSBvciBudWxsIGlmIHRhdXRvbG9naWNhbAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIFJlYXNvbkRhdGEgJHJlYXNvbkRhdGEKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZVJlcXVpcmVSdWxlKEJhc2VQYWNrYWdlICRwYWNrYWdlLCBhcnJheSAkcHJvdmlkZXJzLCAkcmVhc29uLCAkcmVhc29uRGF0YSA9IG51bGwpCiAgICB7CiAgICAgICAgJGxpdGVyYWxzID0gYXJyYXkoLSRwYWNrYWdlLT5pZCk7CgogICAgICAgIGZvcmVhY2ggKCRwcm92aWRlcnMgYXMgJHByb3ZpZGVyKSB7CiAgICAgICAgICAgIC8vIHNlbGYgZnVsZmlsbGluZyBydWxlPwogICAgICAgICAgICBpZiAoJHByb3ZpZGVyID09PSAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxpdGVyYWxzW10gPSAkcHJvdmlkZXItPmlkOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljUnVsZSgkbGl0ZXJhbHMsICRyZWFzb24sICRyZWFzb25EYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBydWxlIHRvIGluc3RhbGwgYXQgbGVhc3Qgb25lIG9mIGEgc2V0IG9mIHBhY2thZ2VzCiAgICAgKgogICAgICogVGhlIHJ1bGUgaXMgKEF8QnxDKSB3aXRoIEEsIEIgYW5kIEMgZGlmZmVyZW50IHBhY2thZ2VzLiBJZiB0aGUgZ2l2ZW4KICAgICAqIHNldCBvZiBwYWNrYWdlcyBpcyBlbXB0eSBhbiBpbXBvc3NpYmxlIHJ1bGUgaXMgZ2VuZXJhdGVkLgogICAgICoKICAgICAqIEBwYXJhbSAgQmFzZVBhY2thZ2VbXSAkcGFja2FnZXMgICBUaGUgc2V0IG9mIHBhY2thZ2VzIHRvIGNob29zZSBmcm9tCiAgICAgKiBAcGFyYW0gIFJ1bGU6OlJVTEVfKiAgJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUgcmVhc29uIGZvcgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRpbmcgdGhpcyBydWxlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgJHJlYXNvbkRhdGEgQWRkaXRpb25hbCBkYXRhIGxpa2UgdGhlIHJvb3QgcmVxdWlyZSBvciBmaXggcmVxdWVzdCBpbmZvCiAgICAgKiBAcmV0dXJuIFJ1bGUgICAgICAgICAgVGhlIGdlbmVyYXRlZCBydWxlCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gUmVhc29uRGF0YSAkcmVhc29uRGF0YQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY3JlYXRlSW5zdGFsbE9uZU9mUnVsZShhcnJheSAkcGFja2FnZXMsICRyZWFzb24sICRyZWFzb25EYXRhKQogICAgewogICAgICAgICRsaXRlcmFscyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRsaXRlcmFsc1tdID0gJHBhY2thZ2UtPmlkOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljUnVsZSgkbGl0ZXJhbHMsICRyZWFzb24sICRyZWFzb25EYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBydWxlIGZvciB0d28gY29uZmxpY3RpbmcgcGFja2FnZXMKICAgICAqCiAgICAgKiBUaGUgcnVsZSBmb3IgY29uZmxpY3RpbmcgcGFja2FnZXMgQSBhbmQgQiBpcyAoLUF8LUIpLiBBIGlzIGNhbGxlZCB0aGUgaXNzdWVyCiAgICAgKiBhbmQgQiB0aGUgcHJvdmlkZXIuCiAgICAgKgogICAgICogQHBhcmFtIEJhc2VQYWNrYWdlICRpc3N1ZXIgVGhlIHBhY2thZ2UgZGVjbGFyaW5nIHRoZSBjb25mbGljdAogICAgICogQHBhcmFtIEJhc2VQYWNrYWdlICRwcm92aWRlciBUaGUgcGFja2FnZSBjYXVzaW5nIHRoZSBjb25mbGljdAogICAgICogQHBhcmFtIFJ1bGU6OlJVTEVfKiAkcmVhc29uIEEgUlVMRV8qIGNvbnN0YW50IGRlc2NyaWJpbmcgdGhlIHJlYXNvbiBmb3IgZ2VuZXJhdGluZyB0aGlzIHJ1bGUKICAgICAqIEBwYXJhbSBtaXhlZCAkcmVhc29uRGF0YSBBbnkgZGF0YSwgZS5nLiB0aGUgcGFja2FnZSBuYW1lLCB0aGF0IGdvZXMgd2l0aCB0aGUgcmVhc29uCiAgICAgKiBAcmV0dXJuID9SdWxlIFRoZSBnZW5lcmF0ZWQgcnVsZQogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIFJlYXNvbkRhdGEgJHJlYXNvbkRhdGEKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZVJ1bGUyTGl0ZXJhbHMoQmFzZVBhY2thZ2UgJGlzc3VlciwgQmFzZVBhY2thZ2UgJHByb3ZpZGVyLCAkcmVhc29uLCAkcmVhc29uRGF0YSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gaWdub3JlIHNlbGYgY29uZmxpY3QKICAgICAgICBpZiAoJGlzc3VlciA9PT0gJHByb3ZpZGVyKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBSdWxlMkxpdGVyYWxzKC0kaXNzdWVyLT5pZCwgLSRwcm92aWRlci0+aWQsICRyZWFzb24sICRyZWFzb25EYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBCYXNlUGFja2FnZVtdICRwYWNrYWdlcwogICAgICogQHBhcmFtIFJ1bGU6OlJVTEVfKiAkcmVhc29uIEEgUlVMRV8qIGNvbnN0YW50CiAgICAgKiBAcGFyYW0gbWl4ZWQgJHJlYXNvbkRhdGEKICAgICAqIEByZXR1cm4gUnVsZQogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIFJlYXNvbkRhdGEgJHJlYXNvbkRhdGEKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZU11bHRpQ29uZmxpY3RSdWxlKGFycmF5ICRwYWNrYWdlcywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpCiAgICB7CiAgICAgICAgJGxpdGVyYWxzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGxpdGVyYWxzW10gPSAtJHBhY2thZ2UtPmlkOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxjb3VudCgkbGl0ZXJhbHMpID09IDIpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSdWxlMkxpdGVyYWxzKCRsaXRlcmFsc1swXSwgJGxpdGVyYWxzWzFdLCAkcmVhc29uLCAkcmVhc29uRGF0YSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IE11bHRpQ29uZmxpY3RSdWxlKCRsaXRlcmFscywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIHJ1bGUgdW5sZXNzIGl0IGR1cGxpY2F0ZXMgYW4gZXhpc3Rpbmcgb25lIG9mIGFueSB0eXBlCiAgICAgKgogICAgICogVG8gYmUgYWJsZSB0byBkaXJlY3RseSBwYXNzIGluIHRoZSByZXN1bHQgb2Ygb25lIG9mIHRoZSBydWxlIGNyZWF0aW9uCiAgICAgKiBtZXRob2RzIG51bGwgaXMgYWxsb3dlZCB3aGljaCB3aWxsIG5vdCBpbnNlcnQgYSBydWxlLgogICAgICoKICAgICAqIEBwYXJhbSBSdWxlU2V0OjpUWVBFXyogJHR5cGUgQSBUWVBFXyogY29uc3RhbnQgZGVmaW5pbmcgdGhlIHJ1bGUgdHlwZQogICAgICogQHBhcmFtIFJ1bGUgJG5ld1J1bGUgVGhlIHJ1bGUgYWJvdXQgdG8gYmUgYWRkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRSdWxlKCR0eXBlLCBSdWxlICRuZXdSdWxlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISRuZXdSdWxlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5ydWxlcy0+YWRkKCRuZXdSdWxlLCAkdHlwZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJ1bGVzRm9yUGFja2FnZShCYXNlUGFja2FnZSAkcGFja2FnZSwgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZSAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcikKICAgIHsKICAgICAgICAvKiogQHZhciBcU3BsUXVldWU8QmFzZVBhY2thZ2U+ICovCiAgICAgICAgJHdvcmtRdWV1ZSA9IG5ldyBcU3BsUXVldWU7CiAgICAgICAgJHdvcmtRdWV1ZS0+ZW5xdWV1ZSgkcGFja2FnZSk7CgogICAgICAgIHdoaWxlICghJHdvcmtRdWV1ZS0+aXNFbXB0eSgpKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHdvcmtRdWV1ZS0+ZGVxdWV1ZSgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmFkZGVkTWFwWyRwYWNrYWdlLT5pZF0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmFkZGVkTWFwWyRwYWNrYWdlLT5pZF0gPSAkcGFja2FnZTsKCiAgICAgICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXROYW1lcyhmYWxzZSkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkZWRQYWNrYWdlc0J5TmFtZXNbJG5hbWVdW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR3b3JrUXVldWUtPmVucXVldWUoJHBhY2thZ2UtPmdldEFsaWFzT2YoKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVSZXF1aXJlUnVsZSgkcGFja2FnZSwgYXJyYXkoJHBhY2thZ2UtPmdldEFsaWFzT2YoKSksIFJ1bGU6OlJVTEVfUEFDS0FHRV9BTElBUywgJHBhY2thZ2UpKTsKCiAgICAgICAgICAgICAgICAvLyBhbGlhc2VzIG11c3QgYmUgaW5zdGFsbGVkIHdpdGggdGhlaXIgbWFpbiBwYWNrYWdlLCBzbyBjcmVhdGUgYSBydWxlIHRoZSBvdGhlciB3YXkgYXJvdW5kIGFzIHdlbGwKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRSdWxlKFJ1bGVTZXQ6OlRZUEVfUEFDS0FHRSwgJHRoaXMtPmNyZWF0ZVJlcXVpcmVSdWxlKCRwYWNrYWdlLT5nZXRBbGlhc09mKCksIGFycmF5KCRwYWNrYWdlKSwgUnVsZTo6UlVMRV9QQUNLQUdFX0lOVkVSU0VfQUxJQVMsICRwYWNrYWdlLT5nZXRBbGlhc09mKCkpKTsKCiAgICAgICAgICAgICAgICAvLyBpZiBhbGlhcyBwYWNrYWdlIGhhcyBubyBzZWxmLnZlcnNpb24gcmVxdWlyZXMsIGl0cyByZXF1aXJlbWVudHMgZG8gbm90CiAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIGJlIGFkZGVkIGFzIHRoZSBhbGlhc2VkIHBhY2thZ2UgcHJvY2Vzc2luZyB3aWxsIHRha2UgY2FyZSBvZiBpdAogICAgICAgICAgICAgICAgaWYgKCEkcGFja2FnZS0+aGFzU2VsZlZlcnNpb25SZXF1aXJlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICBpZiAoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmlzSWdub3JlZCgkbGluay0+Z2V0VGFyZ2V0KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIgaW5zdGFuY2VvZiBJZ25vcmVMaXN0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcikgewogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmZpbHRlckNvbnN0cmFpbnQoJGxpbmstPmdldFRhcmdldCgpLCAkY29uc3RyYWludCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHBvc3NpYmxlUmVxdWlyZXMgPSAkdGhpcy0+cG9vbC0+d2hhdFByb3ZpZGVzKCRsaW5rLT5nZXRUYXJnZXQoKSwgJGNvbnN0cmFpbnQpOwoKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRSdWxlKFJ1bGVTZXQ6OlRZUEVfUEFDS0FHRSwgJHRoaXMtPmNyZWF0ZVJlcXVpcmVSdWxlKCRwYWNrYWdlLCAkcG9zc2libGVSZXF1aXJlcywgUnVsZTo6UlVMRV9QQUNLQUdFX1JFUVVJUkVTLCAkbGluaykpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwb3NzaWJsZVJlcXVpcmVzIGFzICRyZXF1aXJlKSB7CiAgICAgICAgICAgICAgICAgICAgJHdvcmtRdWV1ZS0+ZW5xdWV1ZSgkcmVxdWlyZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZENvbmZsaWN0UnVsZXMoUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZSAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcikKICAgIHsKICAgICAgICAvKiogQHZhciBCYXNlUGFja2FnZSAkcGFja2FnZSAqLwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hZGRlZE1hcCBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0Q29uZmxpY3RzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgIC8vIGV2ZW4gaWYgY29ubGljdCBlbmRzIHVwIGJlaW5nIHdpdGggYW4gYWxpYXMsIHRoZXJlIHdvdWxkIGJlIGF0IGxlYXN0IG9uZSBhY3R1YWwgcGFja2FnZSBieSB0aGlzIG5hbWUKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmFkZGVkUGFja2FnZXNCeU5hbWVzWyRsaW5rLT5nZXRUYXJnZXQoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkbGluay0+Z2V0Q29uc3RyYWludCgpOwogICAgICAgICAgICAgICAgaWYgKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLT5pc0lnbm9yZWQoJGxpbmstPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RhbmNlb2YgSWdub3JlTGlzdFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpIHsKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLT5maWx0ZXJDb25zdHJhaW50KCRsaW5rLT5nZXRUYXJnZXQoKSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRjb25mbGljdHMgPSAkdGhpcy0+cG9vbC0+d2hhdFByb3ZpZGVzKCRsaW5rLT5nZXRUYXJnZXQoKSwgJGNvbnN0cmFpbnQpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb25mbGljdHMgYXMgJGNvbmZsaWN0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZGVmaW5lIHRoZSBjb25mbGljdCBydWxlIGZvciByZWd1bGFyIHBhY2thZ2VzLCBmb3IgYWxpYXMgcGFja2FnZXMgaXQncyBvbmx5IG5lZWRlZCBpZiB0aGUgbmFtZQogICAgICAgICAgICAgICAgICAgIC8vIG1hdGNoZXMgdGhlIGNvbmZsaWN0IGV4YWN0bHksIG90aGVyd2lzZSB0aGUgbmFtZSBtYXRjaCBpcyBieSBwcm92aWRlL3JlcGxhY2Ugd2hpY2ggbWVhbnMgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gcGFja2FnZSB3aGljaCB0aGlzIGlzIGFuIGFsaWFzIG9mIHdpbGwgY29uZmxpY3QgYW55d2F5LCBzbyBubyBuZWVkIHRvIGNyZWF0ZSBhZGRpdGlvbmFsIHJ1bGVzCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkY29uZmxpY3QgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgfHwgJGNvbmZsaWN0LT5nZXROYW1lKCkgPT09ICRsaW5rLT5nZXRUYXJnZXQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVSdWxlMkxpdGVyYWxzKCRwYWNrYWdlLCAkY29uZmxpY3QsIFJ1bGU6OlJVTEVfUEFDS0FHRV9DT05GTElDVCwgJGxpbmspKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hZGRlZFBhY2thZ2VzQnlOYW1lcyBhcyAkbmFtZSA9PiAkcGFja2FnZXMpIHsKICAgICAgICAgICAgaWYgKFxjb3VudCgkcGFja2FnZXMpID4gMSkgewogICAgICAgICAgICAgICAgJHJlYXNvbiA9IFJ1bGU6OlJVTEVfUEFDS0FHRV9TQU1FX05BTUU7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVNdWx0aUNvbmZsaWN0UnVsZSgkcGFja2FnZXMsICRyZWFzb24sICRuYW1lKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJ1bGVzRm9yUmVxdWVzdChSZXF1ZXN0ICRyZXF1ZXN0LCBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRGaXhlZFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5pZCA9PSAtMSkgewogICAgICAgICAgICAgICAgLy8gZml4ZWQgcGFja2FnZSB3YXMgbm90IGFkZGVkIHRvIHRoZSBwb29sIGFzIGl0IGRpZCBub3QgcGFzcyB0aGUgc3RhYmlsaXR5IHJlcXVpcmVtZW50cywgdGhpcyBpcyBmaW5lCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnBvb2wtPmlzVW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBsb29rcyBsaWtlIGEgYnVnCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCJGaXhlZCBwYWNrYWdlICIuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLiIgd2FzIG5vdCBhZGRlZCB0byBzb2x2ZXIgcG9vbC4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmFkZFJ1bGVzRm9yUGFja2FnZSgkcGFja2FnZSwgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwoKICAgICAgICAgICAgJHJ1bGUgPSAkdGhpcy0+Y3JlYXRlSW5zdGFsbE9uZU9mUnVsZShhcnJheSgkcGFja2FnZSksIFJ1bGU6OlJVTEVfRklYRUQsIGFycmF5KAogICAgICAgICAgICAgICAgJ3BhY2thZ2UnID0+ICRwYWNrYWdlLAogICAgICAgICAgICApKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFJ1bGUoUnVsZVNldDo6VFlQRV9SRVFVRVNULCAkcnVsZSk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0UmVxdWlyZXMoKSBhcyAkcGFja2FnZU5hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLT5pc0lnbm9yZWQoJHBhY2thZ2VOYW1lKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0gZWxzZWlmICgkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbnN0YW5jZW9mIElnbm9yZUxpc3RQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLT5maWx0ZXJDb25zdHJhaW50KCRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+cG9vbC0+d2hhdFByb3ZpZGVzKCRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICBpZiAoJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZXNGb3JQYWNrYWdlKCRwYWNrYWdlLCAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJ1bGUgPSAkdGhpcy0+Y3JlYXRlSW5zdGFsbE9uZU9mUnVsZSgkcGFja2FnZXMsIFJ1bGU6OlJVTEVfUk9PVF9SRVFVSVJFLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAncGFja2FnZU5hbWUnID0+ICRwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAnY29uc3RyYWludCcgPT4gJGNvbnN0cmFpbnQsCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRSdWxlKFJ1bGVTZXQ6OlRZUEVfUkVRVUVTVCwgJHJ1bGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRSdWxlc0ZvclJvb3RBbGlhc2VzKFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2UgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBvb2wtPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgLy8gZW5zdXJlIHRoYXQgcnVsZXMgZm9yIHJvb3QgYWxpYXMgcGFja2FnZXMgYW5kIGFsaWFzZXMgb2YgcGFja2FnZXMgd2hpY2ggd2VyZSBsb2FkZWQgYXJlIGFsc28gbG9hZGVkCiAgICAgICAgICAgIC8vIGV2ZW4gaWYgdGhlIGFsaWFzIGl0c2VsZiBpc24ndCByZXF1aXJlZCwgb3RoZXJ3aXNlIGEgcGFja2FnZSBjb3VsZCBiZSBpbnN0YWxsZWQgd2l0aG91dCBpdHMgYWxpYXMgd2hpY2gKICAgICAgICAgICAgLy8gbGVhZHMgdG8gdW5leHBlY3RlZCBiZWhhdmlvcgogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5hZGRlZE1hcFskcGFja2FnZS0+aWRdKSAmJgogICAgICAgICAgICAgICAgJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgJiYKICAgICAgICAgICAgICAgICgkcGFja2FnZS0+aXNSb290UGFja2FnZUFsaWFzKCkgfHwgaXNzZXQoJHRoaXMtPmFkZGVkTWFwWyRwYWNrYWdlLT5nZXRBbGlhc09mKCktPmlkXSkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFJ1bGVzRm9yUGFja2FnZSgkcGFja2FnZSwgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSdWxlU2V0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSdWxlc0ZvcihSZXF1ZXN0ICRyZXF1ZXN0LCBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciA9ICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID86IFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5OjppZ25vcmVOb3RoaW5nKCk7CgogICAgICAgICR0aGlzLT5hZGRSdWxlc0ZvclJlcXVlc3QoJHJlcXVlc3QsICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKTsKCiAgICAgICAgJHRoaXMtPmFkZFJ1bGVzRm9yUm9vdEFsaWFzZXMoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwoKICAgICAgICAkdGhpcy0+YWRkQ29uZmxpY3RSdWxlcygkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcik7CgogICAgICAgIC8vIFJlbW92ZSByZWZlcmVuY2VzIHRvIHBhY2thZ2VzCiAgICAgICAgJHRoaXMtPmFkZGVkTWFwID0gJHRoaXMtPmFkZGVkUGFja2FnZXNCeU5hbWVzID0gYXJyYXkoKTsKCiAgICAgICAgJHJ1bGVzID0gJHRoaXMtPnJ1bGVzOwoKICAgICAgICAkdGhpcy0+cnVsZXMgPSBuZXcgUnVsZVNldDsKCiAgICAgICAgcmV0dXJuICRydWxlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFBsYXRmb3JtUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cT3BlcmF0aW9uSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgVHJhbnNhY3Rpb24KewogICAgLyoqCiAgICAgKiBAdmFyIE9wZXJhdGlvbkludGVyZmFjZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0aW9uczsKCiAgICAvKioKICAgICAqIFBhY2thZ2VzIHByZXNlbnQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdHJhbnNhY3Rpb24KICAgICAqIEB2YXIgUGFja2FnZUludGVyZmFjZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJlc2VudFBhY2thZ2VzOwoKICAgIC8qKgogICAgICogUGFja2FnZSBzZXQgcmVzdWx0aW5nIGZyb20gdGhpcyB0cmFuc2FjdGlvbgogICAgICogQHZhciBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVzdWx0UGFja2FnZU1hcDsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8c3RyaW5nLCBQYWNrYWdlSW50ZXJmYWNlW10+CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVzdWx0UGFja2FnZXNCeU5hbWUgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2VbXSAkcHJlc2VudFBhY2thZ2VzCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdICRyZXN1bHRQYWNrYWdlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHByZXNlbnRQYWNrYWdlcywgJHJlc3VsdFBhY2thZ2VzKQogICAgewogICAgICAgICR0aGlzLT5wcmVzZW50UGFja2FnZXMgPSAkcHJlc2VudFBhY2thZ2VzOwogICAgICAgICR0aGlzLT5zZXRSZXN1bHRQYWNrYWdlTWFwcygkcmVzdWx0UGFja2FnZXMpOwogICAgICAgICR0aGlzLT5vcGVyYXRpb25zID0gJHRoaXMtPmNhbGN1bGF0ZU9wZXJhdGlvbnMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gT3BlcmF0aW9uSW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlcmF0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlW10gJHJlc3VsdFBhY2thZ2VzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXRSZXN1bHRQYWNrYWdlTWFwcygkcmVzdWx0UGFja2FnZXMpCiAgICB7CiAgICAgICAgJHBhY2thZ2VTb3J0ID0gZnVuY3Rpb24gKFBhY2thZ2VJbnRlcmZhY2UgJGEsIFBhY2thZ2VJbnRlcmZhY2UgJGIpIHsKICAgICAgICAgICAgLy8gc29ydCBhbGlhcyBwYWNrYWdlcyBieSB0aGUgc2FtZSBuYW1lIGJlaGluZCB0aGVpciBub24gYWxpYXMgdmVyc2lvbgogICAgICAgICAgICBpZiAoJGEtPmdldE5hbWUoKSA9PSAkYi0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICAgICBpZiAoJGEgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgIT0gJGIgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGEgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgPyAtMSA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBpZiBuYW1lcyBhcmUgdGhlIHNhbWUsIGNvbXBhcmUgdmVyc2lvbiwgZS5nLiB0byBzb3J0IGFsaWFzZXMgcmVsaWFibHksIGFjdHVhbCBvcmRlciBkb2VzIG5vdCBtYXR0ZXIKICAgICAgICAgICAgICAgIHJldHVybiBzdHJjbXAoJGItPmdldFZlcnNpb24oKSwgJGEtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBzdHJjbXAoJGItPmdldE5hbWUoKSwgJGEtPmdldE5hbWUoKSk7CiAgICAgICAgfTsKCiAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VNYXAgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRyZXN1bHRQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkdGhpcy0+cmVzdWx0UGFja2FnZU1hcFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0TmFtZXMoKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VzQnlOYW1lWyRuYW1lXVtdID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHVhc29ydCgkdGhpcy0+cmVzdWx0UGFja2FnZU1hcCwgJHBhY2thZ2VTb3J0KTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVzdWx0UGFja2FnZXNCeU5hbWUgYXMgJG5hbWUgPT4gJHBhY2thZ2VzKSB7CiAgICAgICAgICAgIHVhc29ydCgkdGhpcy0+cmVzdWx0UGFja2FnZXNCeU5hbWVbJG5hbWVdLCAkcGFja2FnZVNvcnQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gT3BlcmF0aW9uSW50ZXJmYWNlW10KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNhbGN1bGF0ZU9wZXJhdGlvbnMoKQogICAgewogICAgICAgICRvcGVyYXRpb25zID0gYXJyYXkoKTsKCiAgICAgICAgJHByZXNlbnRQYWNrYWdlTWFwID0gYXJyYXkoKTsKICAgICAgICAkcmVtb3ZlTWFwID0gYXJyYXkoKTsKICAgICAgICAkcHJlc2VudEFsaWFzTWFwID0gYXJyYXkoKTsKICAgICAgICAkcmVtb3ZlQWxpYXNNYXAgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcmVzZW50UGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkcHJlc2VudEFsaWFzTWFwWyRwYWNrYWdlLT5nZXROYW1lKCkuJzo6Jy4kcGFja2FnZS0+Z2V0VmVyc2lvbigpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgJHJlbW92ZUFsaWFzTWFwWyRwYWNrYWdlLT5nZXROYW1lKCkuJzo6Jy4kcGFja2FnZS0+Z2V0VmVyc2lvbigpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHByZXNlbnRQYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAkcmVtb3ZlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRzdGFjayA9ICR0aGlzLT5nZXRSb290UGFja2FnZXMoKTsKCiAgICAgICAgJHZpc2l0ZWQgPSBhcnJheSgpOwogICAgICAgICRwcm9jZXNzZWQgPSBhcnJheSgpOwoKICAgICAgICB3aGlsZSAoIWVtcHR5KCRzdGFjaykpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSBhcnJheV9wb3AoJHN0YWNrKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkcHJvY2Vzc2VkW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJHZpc2l0ZWRbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pKSB7CiAgICAgICAgICAgICAgICAkdmlzaXRlZFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9IHRydWU7CgogICAgICAgICAgICAgICAgJHN0YWNrW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRzdGFja1tdID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBvc3NpYmxlUmVxdWlyZXMgPSAkdGhpcy0+Z2V0UHJvdmlkZXJzSW5SZXN1bHQoJGxpbmspOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBvc3NpYmxlUmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzdGFja1tdID0gJHJlcXVpcmU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICghaXNzZXQoJHByb2Nlc3NlZFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSkpIHsKICAgICAgICAgICAgICAgICRwcm9jZXNzZWRbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0gPSB0cnVlOwoKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRhbGlhc0tleSA9ICRwYWNrYWdlLT5nZXROYW1lKCkuJzo6Jy4kcGFja2FnZS0+Z2V0VmVyc2lvbigpOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcHJlc2VudEFsaWFzTWFwWyRhbGlhc0tleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRyZW1vdmVBbGlhc01hcFskYWxpYXNLZXldKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkb3BlcmF0aW9uc1tdID0gbmV3IE9wZXJhdGlvblxNYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb24oJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHNvdXJjZSA9ICRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIHdlIG5lZWQgdG8gdXBkYXRlPwogICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIGRpZmZlcmVudCBmb3IgbG9jaz8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRWZXJzaW9uKCkgIT0gJHByZXNlbnRQYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldLT5nZXRWZXJzaW9uKCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkgIT09ICRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0RGlzdFJlZmVyZW5jZSgpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkgIT09ICRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0U291cmNlUmVmZXJlbmNlKCkKICAgICAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkb3BlcmF0aW9uc1tdID0gbmV3IE9wZXJhdGlvblxVcGRhdGVPcGVyYXRpb24oJHNvdXJjZSwgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRyZW1vdmVNYXBbJHBhY2thZ2UtPmdldE5hbWUoKV0pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRvcGVyYXRpb25zW10gPSBuZXcgT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb24oJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkcmVtb3ZlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZW1vdmVNYXAgYXMgJG5hbWUgPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkb3BlcmF0aW9ucywgbmV3IE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb24oJHBhY2thZ2UpKTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJHJlbW92ZUFsaWFzTWFwIGFzICRuYW1lVmVyc2lvbiA9PiAkcGFja2FnZSkgewogICAgICAgICAgICAkb3BlcmF0aW9uc1tdID0gbmV3IE9wZXJhdGlvblxNYXJrQWxpYXNVbmluc3RhbGxlZE9wZXJhdGlvbigkcGFja2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkb3BlcmF0aW9ucyA9ICR0aGlzLT5tb3ZlUGx1Z2luc1RvRnJvbnQoJG9wZXJhdGlvbnMpOwogICAgICAgIC8vIFRPRE8gZml4IHRoaXM6CiAgICAgICAgLy8gd2UgaGF2ZSB0byBkbyB0aGlzIGFnYWluIGhlcmUgZXZlbiB0aG91Z2ggdGhlIGFib3ZlIHN0YWNrIGNvZGUgZGlkIGl0IGJlY2F1c2UgbW92aW5nIHBsdWdpbnMgbW92ZXMgdGhlbSBiZWZvcmUgdW5pbnN0YWxscwogICAgICAgICRvcGVyYXRpb25zID0gJHRoaXMtPm1vdmVVbmluc3RhbGxzVG9Gcm9udCgkb3BlcmF0aW9ucyk7CgogICAgICAgIC8vIFRPRE8gc2tpcCB1cGRhdGVzIHdoaWNoIGRvbid0IHVwZGF0ZT8gaXMgdGhpcyBuZWVkZWQ/IHdlIHNob3VsZG4ndCBzY2hlZHVsZSB0aGlzIHVwZGF0ZSBpbiB0aGUgZmlyc3QgcGxhY2U/CiAgICAgICAgLyoKICAgICAgICBpZiAoJ3VwZGF0ZScgPT09ICRvcFR5cGUpIHsKICAgICAgICAgICAgJHRhcmdldFBhY2thZ2UgPSAkb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCk7CiAgICAgICAgICAgIGlmICgkdGFyZ2V0UGFja2FnZS0+aXNEZXYoKSkgewogICAgICAgICAgICAgICAgJGluaXRpYWxQYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0SW5pdGlhbFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgIGlmICgkdGFyZ2V0UGFja2FnZS0+Z2V0VmVyc2lvbigpID09PSAkaW5pdGlhbFBhY2thZ2UtPmdldFZlcnNpb24oKQogICAgICAgICAgICAgICAgICAgICYmICghJHRhcmdldFBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpIHx8ICR0YXJnZXRQYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSA9PT0gJGluaXRpYWxQYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkKICAgICAgICAgICAgICAgICAgICAmJiAoISR0YXJnZXRQYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkgfHwgJHRhcmdldFBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSA9PT0gJGluaXRpYWxQYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgLSBTa2lwcGluZyB1cGRhdGUgb2YgJyAuICR0YXJnZXRQYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkgLiAnIHRvIHRoZSBzYW1lIHJlZmVyZW5jZS1sb2NrZWQgdmVyc2lvbicsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0qLwoKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZXJhdGlvbnMgPSAkb3BlcmF0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIERldGVybWluZSB3aGljaCBwYWNrYWdlcyBpbiB0aGUgcmVzdWx0IGFyZSBub3QgcmVxdWlyZWQgYnkgYW55IG90aGVyIHBhY2thZ2VzIGluIGl0LgogICAgICoKICAgICAqIFRoZXNlIHNlcnZlIGFzIGEgc3RhcnRpbmcgcG9pbnQgdG8gZW51bWVyYXRlIHBhY2thZ2VzIGluIGEgdG9wb2xvZ2ljYWwgb3JkZXIgZGVzcGl0ZSBwb3RlbnRpYWwgY3ljbGVzLgogICAgICogSWYgdGhlcmUgYXJlIHBhY2thZ2VzIHdpdGggYSBjeWNsZSBvbiB0aGUgdG9wIGxldmVsIHRoZSBwYWNrYWdlIHdpdGggdGhlIGxvd2VzdCBuYW1lIGdldHMgcGlja2VkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRSb290UGFja2FnZXMoKQogICAgewogICAgICAgICRyb290cyA9ICR0aGlzLT5yZXN1bHRQYWNrYWdlTWFwOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVzdWx0UGFja2FnZU1hcCBhcyAkcGFja2FnZUhhc2ggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkcm9vdHNbJHBhY2thZ2VIYXNoXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHBvc3NpYmxlUmVxdWlyZXMgPSAkdGhpcy0+Z2V0UHJvdmlkZXJzSW5SZXN1bHQoJGxpbmspOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwb3NzaWJsZVJlcXVpcmVzIGFzICRyZXF1aXJlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXF1aXJlICE9PSAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkcm9vdHNbc3BsX29iamVjdF9oYXNoKCRyZXF1aXJlKV0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyb290czsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQcm92aWRlcnNJblJlc3VsdChMaW5rICRsaW5rKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlc3VsdFBhY2thZ2VzQnlOYW1lWyRsaW5rLT5nZXRUYXJnZXQoKV0pKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXN1bHRQYWNrYWdlc0J5TmFtZVskbGluay0+Z2V0VGFyZ2V0KCldOwogICAgfQoKICAgIC8qKgogICAgICogV29ya2Fyb3VuZDogaWYgeW91ciBwYWNrYWdlcyBkZXBlbmQgb24gcGx1Z2lucywgd2UgbXVzdCBiZSBzdXJlCiAgICAgKiB0aGF0IHRob3NlIGFyZSBpbnN0YWxsZWQgLyB1cGRhdGVkIGZpcnN0OyBlbHNlIGl0IHdvdWxkIGxlYWQgdG8gcGFja2FnZXMKICAgICAqIGJlaW5nIGluc3RhbGxlZCBtdWx0aXBsZSB0aW1lcyBpbiBkaWZmZXJlbnQgZm9sZGVycywgd2hlbiBydW5uaW5nIENvbXBvc2VyCiAgICAgKiB0d2ljZS4KICAgICAqCiAgICAgKiBXaGlsZSB0aGlzIGRvZXMgbm90IGZpeCB0aGUgcm9vdC1jYXVzZXMgb2YgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy8xMTQ3LAogICAgICogaXQgYXQgbGVhc3QgZml4ZXMgdGhlIHN5bXB0b21zIGFuZCBtYWtlcyB1c2FnZSBvZiBjb21wb3NlciBwb3NzaWJsZSAoYWdhaW4pCiAgICAgKiBpbiBzdWNoIHNjZW5hcmlvcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIE9wZXJhdGlvbkludGVyZmFjZVtdICRvcGVyYXRpb25zCiAgICAgKiBAcmV0dXJuIE9wZXJhdGlvbkludGVyZmFjZVtdIHJlb3JkZXJlZCBvcGVyYXRpb24gbGlzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1vdmVQbHVnaW5zVG9Gcm9udChhcnJheSAkb3BlcmF0aW9ucykKICAgIHsKICAgICAgICAkZGxNb2RpZnlpbmdQbHVnaW5zTm9EZXBzID0gYXJyYXkoKTsKICAgICAgICAkZGxNb2RpZnlpbmdQbHVnaW5zV2l0aERlcHMgPSBhcnJheSgpOwogICAgICAgICRkbE1vZGlmeWluZ1BsdWdpblJlcXVpcmVzID0gYXJyYXkoKTsKICAgICAgICAkcGx1Z2luc05vRGVwcyA9IGFycmF5KCk7CiAgICAgICAgJHBsdWdpbnNXaXRoRGVwcyA9IGFycmF5KCk7CiAgICAgICAgJHBsdWdpblJlcXVpcmVzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfcmV2ZXJzZSgkb3BlcmF0aW9ucywgdHJ1ZSkgYXMgJGlkeCA9PiAkb3ApIHsKICAgICAgICAgICAgaWYgKCRvcCBpbnN0YW5jZW9mIE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRvcC0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG9wIGluc3RhbmNlb2YgT3BlcmF0aW9uXFVwZGF0ZU9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkb3AtPmdldFRhcmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaXNEb3dubG9hZHNNb2RpZnlpbmdQbHVnaW4gPSAkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItcGx1Z2luJyAmJiAoJGV4dHJhID0gJHBhY2thZ2UtPmdldEV4dHJhKCkpICYmIGlzc2V0KCRleHRyYVsncGx1Z2luLW1vZGlmaWVzLWRvd25sb2FkcyddKSAmJiAkZXh0cmFbJ3BsdWdpbi1tb2RpZmllcy1kb3dubG9hZHMnXSA9PT0gdHJ1ZTsKCiAgICAgICAgICAgIC8vIGlzIHRoaXMgYSBkb3dubG9hZHMgbW9kaWZ5aW5nIHBsdWdpbiBvciBhIGRlcGVuZGVuY3kgb2Ygb25lPwogICAgICAgICAgICBpZiAoJGlzRG93bmxvYWRzTW9kaWZ5aW5nUGx1Z2luIHx8IGNvdW50KGFycmF5X2ludGVyc2VjdCgkcGFja2FnZS0+Z2V0TmFtZXMoKSwgJGRsTW9kaWZ5aW5nUGx1Z2luUmVxdWlyZXMpKSkgewogICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBwYWNrYWdlJ3MgcmVxdWlyZXMsIGJ1dCBmaWx0ZXIgb3V0IGFueSBwbGF0Zm9ybSByZXF1aXJlbWVudHMKICAgICAgICAgICAgICAgICRyZXF1aXJlcyA9IGFycmF5X2ZpbHRlcihhcnJheV9rZXlzKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpKSwgZnVuY3Rpb24gKCRyZXEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIVBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcSk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvLyBpcyB0aGlzIGEgcGx1Z2luIHdpdGggbm8gbWVhbmluZ2Z1bCBkZXBlbmRlbmNpZXM/CiAgICAgICAgICAgICAgICBpZiAoJGlzRG93bmxvYWRzTW9kaWZ5aW5nUGx1Z2luICYmICFjb3VudCgkcmVxdWlyZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcGx1Z2lucyB3aXRoIG5vIGRlcGVuZGVuY2llcyBnbyB0byB0aGUgdmVyeSBmcm9udAogICAgICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGRsTW9kaWZ5aW5nUGx1Z2luc05vRGVwcywgJG9wKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gY2FwdHVyZSB0aGUgcmVxdWlyZW1lbnRzIGZvciB0aGlzIHBhY2thZ2Ugc28gdGhvc2UgcGFja2FnZXMgd2lsbCBiZSBtb3ZlZCB1cCBhcyB3ZWxsCiAgICAgICAgICAgICAgICAgICAgJGRsTW9kaWZ5aW5nUGx1Z2luUmVxdWlyZXMgPSBhcnJheV9tZXJnZSgkZGxNb2RpZnlpbmdQbHVnaW5SZXF1aXJlcywgJHJlcXVpcmVzKTsKICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIHRoZSBvcGVyYXRpb24gdG8gdGhlIGZyb250CiAgICAgICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkZGxNb2RpZnlpbmdQbHVnaW5zV2l0aERlcHMsICRvcCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdW5zZXQoJG9wZXJhdGlvbnNbJGlkeF0pOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlzIHRoaXMgcGFja2FnZSBhIHBsdWdpbj8KICAgICAgICAgICAgJGlzUGx1Z2luID0gJHBhY2thZ2UtPmdldFR5cGUoKSA9PT0gJ2NvbXBvc2VyLXBsdWdpbicgfHwgJHBhY2thZ2UtPmdldFR5cGUoKSA9PT0gJ2NvbXBvc2VyLWluc3RhbGxlcic7CgogICAgICAgICAgICAvLyBpcyB0aGlzIGEgcGx1Z2luIG9yIGEgZGVwZW5kZW5jeSBvZiBhIHBsdWdpbj8KICAgICAgICAgICAgaWYgKCRpc1BsdWdpbiB8fCBjb3VudChhcnJheV9pbnRlcnNlY3QoJHBhY2thZ2UtPmdldE5hbWVzKCksICRwbHVnaW5SZXF1aXJlcykpKSB7CiAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIHBhY2thZ2UncyByZXF1aXJlcywgYnV0IGZpbHRlciBvdXQgYW55IHBsYXRmb3JtIHJlcXVpcmVtZW50cwogICAgICAgICAgICAgICAgJHJlcXVpcmVzID0gYXJyYXlfZmlsdGVyKGFycmF5X2tleXMoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkpLCBmdW5jdGlvbiAoJHJlcSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAhUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcmVxKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIC8vIGlzIHRoaXMgYSBwbHVnaW4gd2l0aCBubyBtZWFuaW5nZnVsIGRlcGVuZGVuY2llcz8KICAgICAgICAgICAgICAgIGlmICgkaXNQbHVnaW4gJiYgIWNvdW50KCRyZXF1aXJlcykpIHsKICAgICAgICAgICAgICAgICAgICAvLyBwbHVnaW5zIHdpdGggbm8gZGVwZW5kZW5jaWVzIGdvIHRvIHRoZSB2ZXJ5IGZyb250CiAgICAgICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkcGx1Z2luc05vRGVwcywgJG9wKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gY2FwdHVyZSB0aGUgcmVxdWlyZW1lbnRzIGZvciB0aGlzIHBhY2thZ2Ugc28gdGhvc2UgcGFja2FnZXMgd2lsbCBiZSBtb3ZlZCB1cCBhcyB3ZWxsCiAgICAgICAgICAgICAgICAgICAgJHBsdWdpblJlcXVpcmVzID0gYXJyYXlfbWVyZ2UoJHBsdWdpblJlcXVpcmVzLCAkcmVxdWlyZXMpOwogICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgdGhlIG9wZXJhdGlvbiB0byB0aGUgZnJvbnQKICAgICAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRwbHVnaW5zV2l0aERlcHMsICRvcCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdW5zZXQoJG9wZXJhdGlvbnNbJGlkeF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfbWVyZ2UoJGRsTW9kaWZ5aW5nUGx1Z2luc05vRGVwcywgJGRsTW9kaWZ5aW5nUGx1Z2luc1dpdGhEZXBzLCAkcGx1Z2luc05vRGVwcywgJHBsdWdpbnNXaXRoRGVwcywgJG9wZXJhdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZhbHMgb2YgcGFja2FnZXMgc2hvdWxkIGJlIGV4ZWN1dGVkIGJlZm9yZSBpbnN0YWxsYXRpb25zIGluCiAgICAgKiBjYXNlIHR3byBwYWNrYWdlcyByZXNvbHZlIHRvIHRoZSBzYW1lIHBhdGggKGR1ZSB0byBjdXN0b20gaW5zdGFsbGVycykKICAgICAqCiAgICAgKiBAcGFyYW0gIE9wZXJhdGlvbkludGVyZmFjZVtdICRvcGVyYXRpb25zCiAgICAgKiBAcmV0dXJuIE9wZXJhdGlvbkludGVyZmFjZVtdIHJlb3JkZXJlZCBvcGVyYXRpb24gbGlzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1vdmVVbmluc3RhbGxzVG9Gcm9udChhcnJheSAkb3BlcmF0aW9ucykKICAgIHsKICAgICAgICAkdW5pbnN0T3BzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkb3BlcmF0aW9ucyBhcyAkaWR4ID0+ICRvcCkgewogICAgICAgICAgICBpZiAoJG9wIGluc3RhbmNlb2YgT3BlcmF0aW9uXFVuaW5zdGFsbE9wZXJhdGlvbiB8fCAkb3AgaW5zdGFuY2VvZiBPcGVyYXRpb25cTWFya0FsaWFzVW5pbnN0YWxsZWRPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICR1bmluc3RPcHNbXSA9ICRvcDsKICAgICAgICAgICAgICAgIHVuc2V0KCRvcGVyYXRpb25zWyRpZHhdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKCR1bmluc3RPcHMsICRvcGVyYXRpb25zKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcTG9ja0FycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNYXRjaEFsbENvbnN0cmFpbnQ7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJlcXVlc3QKewogICAgLyoqCiAgICAgKiBJZGVudGlmaWVzIGEgcGFydGlhbCB1cGRhdGUgZm9yIGxpc3RlZCBwYWNrYWdlcyBvbmx5LCBhbGwgZGVwZW5kZW5jaWVzIHdpbGwgcmVtYWluIGF0IGxvY2tlZCB2ZXJzaW9ucwogICAgICovCiAgICBjb25zdCBVUERBVEVfT05MWV9MSVNURUQgPSAwOwoKICAgIC8qKgogICAgICogSWRlbnRpZmllcyBhIHBhcnRpYWwgdXBkYXRlIGZvciBsaXN0ZWQgcGFja2FnZXMgYW5kIHJlY3Vyc2l2ZWx5IGFsbCB0aGVpciBkZXBlbmRlbmNpZXMsIGhvd2V2ZXIgZGVwZW5kZW5jaWVzCiAgICAgKiBhbHNvIGRpcmVjdGx5IHJlcXVpcmVkIGJ5IHRoZSByb290IGNvbXBvc2VyLmpzb24gYW5kIHRoZWlyIGRlcGVuZGVuY2llcyB3aWxsIHJlbWFpbiBhdCB0aGUgbG9ja2VkIHZlcnNpb24uCiAgICAgKi8KICAgIGNvbnN0IFVQREFURV9MSVNURURfV0lUSF9UUkFOU0lUSVZFX0RFUFNfTk9fUk9PVF9SRVFVSVJFID0gMTsKCiAgICAvKioKICAgICAqIElkZW50aWZpZXMgYSBwYXJ0aWFsIHVwZGF0ZSBmb3IgbGlzdGVkIHBhY2thZ2VzIGFuZCByZWN1cnNpdmVseSBhbGwgdGhlaXIgZGVwZW5kZW5jaWVzLCBldmVuIGRlcGVuZGVuY2llcwogICAgICogYWxzbyBkaXJlY3RseSByZXF1aXJlZCBieSB0aGUgcm9vdCBjb21wb3Nlci5qc29uIHdpbGwgYmUgdXBkYXRlZC4KICAgICAqLwogICAgY29uc3QgVVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUyA9IDI7CgogICAgLyoqIEB2YXIgP0xvY2tBcnJheVJlcG9zaXRvcnkgKi8KICAgIHByb3RlY3RlZCAkbG9ja2VkUmVwb3NpdG9yeTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgQ29uc3RyYWludEludGVyZmFjZT4gKi8KICAgIHByb3RlY3RlZCAkcmVxdWlyZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZT4gKi8KICAgIHByb3RlY3RlZCAkZml4ZWRQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlPiAqLwogICAgcHJvdGVjdGVkICRsb2NrZWRQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlPiAqLwogICAgcHJvdGVjdGVkICRmaXhlZExvY2tlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIHN0cmluZ1tdICovCiAgICBwcm90ZWN0ZWQgJHVwZGF0ZUFsbG93TGlzdCA9IGFycmF5KCk7CiAgICAvKiogQHZhciBmYWxzZXxzZWxmOjpVUERBVEVfKiAqLwogICAgcHJvdGVjdGVkICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBmYWxzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoTG9ja0FycmF5UmVwb3NpdG9yeSAkbG9ja2VkUmVwb3NpdG9yeSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2tlZFJlcG9zaXRvcnkgPSAkbG9ja2VkUmVwb3NpdG9yeTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VOYW1lCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlcXVpcmVOYW1lKCRwYWNrYWdlTmFtZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCA9IG51bGwpCiAgICB7CiAgICAgICAgJHBhY2thZ2VOYW1lID0gc3RydG9sb3dlcigkcGFja2FnZU5hbWUpOwoKICAgICAgICBpZiAoJGNvbnN0cmFpbnQgPT09IG51bGwpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSBuZXcgTWF0Y2hBbGxDb25zdHJhaW50KCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVxdWlyZXNbJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignT3ZlcndyaXRpbmcgcmVxdWlyZXMgc2VlbXMgbGlrZSBhIGJ1ZyAoJy4kcGFja2FnZU5hbWUuJyAnLiR0aGlzLT5yZXF1aXJlc1skcGFja2FnZU5hbWVdLT5nZXRQcmV0dHlTdHJpbmcoKS4nID0+ICcuJGNvbnN0cmFpbnQtPmdldFByZXR0eVN0cmluZygpLicsIGNoZWNrIHdoeSBpdCBpcyBoYXBwZW5pbmcsIG1pZ2h0IGJlIGEgcm9vdCBhbGlhcycpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+cmVxdWlyZXNbJHBhY2thZ2VOYW1lXSA9ICRjb25zdHJhaW50OwogICAgfQoKICAgIC8qKgogICAgICogTWFyayBhIHBhY2thZ2UgYXMgY3VycmVudGx5IHByZXNlbnQgYW5kIGhhdmluZyB0byByZW1haW4gaW5zdGFsbGVkCiAgICAgKgogICAgICogVGhpcyBpcyB1c2VkIGZvciBwbGF0Zm9ybSBwYWNrYWdlcyB3aGljaCBjYW5ub3QgYmUgbW9kaWZpZWQgYnkgQ29tcG9zZXIuIEEgcnVsZSBlbmZvcmNpbmcgdGhlaXIgaW5zdGFsbGF0aW9uIGlzCiAgICAgKiBnZW5lcmF0ZWQgZm9yIGRlcGVuZGVuY3kgcmVzb2x1dGlvbi4gUGFydGlhbCB1cGRhdGVzIHdpdGggZGVwZW5kZW5jaWVzIGNhbm5vdCBpbiBhbnkgd2F5IG1vZGlmeSB0aGVzZSBwYWNrYWdlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpeFBhY2thZ2UoQmFzZVBhY2thZ2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmZpeGVkUGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0gPSAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hcmsgYSBwYWNrYWdlIGFzIGxvY2tlZCB0byBhIHNwZWNpZmljIHZlcnNpb24gYnV0IHJlbW92YWJsZQogICAgICoKICAgICAqIFRoaXMgaXMgdXNlZCBmb3IgbG9jayBmaWxlIHBhY2thZ2VzIHdoaWNoIG5lZWQgdG8gYmUgdHJlYXRlZCBzaW1pbGFyIHRvIGZpeGVkIHBhY2thZ2VzIGJ5IHRoZSBwb29sIGJ1aWxkZXIgaW4KICAgICAqIHRoYXQgYnkgZGVmYXVsdCB0aGV5IHNob3VsZCByZWFsbHkgb25seSBoYXZlIHRoZSBjdXJyZW50bHkgcHJlc2VudCB2ZXJzaW9uIGxvYWRlZCBhbmQgbm8gcmVtb3RlIGFsdGVybmF0aXZlcy4KICAgICAqCiAgICAgKiBIb3dldmVyIHVubGlrZSBmaXhlZCBwYWNrYWdlcyB0aGVyZSB3aWxsIG5vdCBiZSBhIHNwZWNpYWwgcnVsZSBlbmZvcmNpbmcgdGhlaXIgaW5zdGFsbGF0aW9uIGZvciB0aGUgc29sdmVyLCBzbwogICAgICogaWYgbm90aGluZyByZXF1aXJlcyB0aGVzZSBwYWNrYWdlcyB0aGV5IHdpbGwgYmUgcmVtb3ZlZC4gQWRkaXRpb25hbGx5IGluIGEgcGFydGlhbCB1cGRhdGUgdGhlc2UgcGFja2FnZXMgY2FuIGJlCiAgICAgKiB1bmxvY2tlZCwgbWVhbmluZyBvdGhlciB2ZXJzaW9ucyBjYW4gYmUgaW5zdGFsbGVkIGlmIGV4cGxpY2l0bHkgcmVxdWVzdGVkIGFzIHBhcnQgb2YgdGhlIHVwZGF0ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvY2tQYWNrYWdlKEJhc2VQYWNrYWdlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5sb2NrZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogTWFya3MgYSBsb2NrZWQgcGFja2FnZSBmaXhlZC4gU28gaXQncyB0cmVhdGVkIGlycmVtb3ZhYmxlIGxpa2UgYSBwbGF0Zm9ybSBwYWNrYWdlLgogICAgICoKICAgICAqIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciB0aGUgY29tcG9zZXIgaW5zdGFsbCBzdGVwIHdoaWNoIHZlcmlmaWVzIHRoZSBsb2NrIGZpbGUgaW50ZWdyaXR5IGFuZCBzaG91bGQgbm90IGFsbG93CiAgICAgKiByZW1vdmFsIG9mIGFueSBwYWNrYWdlcy4gQXQgdGhlIHNhbWUgdGltZSBsb2NrIHBhY2thZ2VzIHRoZXJlIGNhbm5vdCBzaW1wbHkgYmUgbWFya2VkIGZpeGVkLCBhcyBlcnJvciByZXBvcnRpbmcKICAgICAqIHdvdWxkIHRoZW4gcmVwb3J0IHRoZW0gYXMgcGxhdGZvcm0gcGFja2FnZXMsIHNvIHRoaXMgc3RpbGwgbWFya3MgdGhlbSBhcyBsb2NrZWQgcGFja2FnZXMgYXQgdGhlIHNhbWUgdGltZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpeExvY2tlZFBhY2thZ2UoQmFzZVBhY2thZ2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmZpeGVkUGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0gPSAkcGFja2FnZTsKICAgICAgICAkdGhpcy0+Zml4ZWRMb2NrZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmxvY2tQYWNrYWdlKEJhc2VQYWNrYWdlICRwYWNrYWdlKQogICAgewogICAgICAgIHVuc2V0KCR0aGlzLT5sb2NrZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHVwZGF0ZUFsbG93TGlzdAogICAgICogQHBhcmFtIGZhbHNlfHNlbGY6OlVQREFURV8qICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXBkYXRlQWxsb3dMaXN0KCR1cGRhdGVBbGxvd0xpc3QsICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCA9ICR1cGRhdGVBbGxvd0xpc3Q7CiAgICAgICAgJHRoaXMtPnVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyA9ICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcGRhdGVBbGxvd0xpc3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXBkYXRlQWxsb3dMaXN0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzICE9PSBzZWxmOjpVUERBVEVfT05MWV9MSVNURUQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZVJvb3REZXBlbmRlbmNpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID09PSBzZWxmOjpVUERBVEVfTElTVEVEX1dJVEhfVFJBTlNJVElWRV9ERVBTOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIENvbnN0cmFpbnRJbnRlcmZhY2U+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXF1aXJlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpeGVkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zml4ZWRQYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNGaXhlZFBhY2thZ2UoQmFzZVBhY2thZ2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5maXhlZFBhY2thZ2VzW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2tlZFBhY2thZ2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvY2tlZFBhY2thZ2VzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0xvY2tlZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmxvY2tlZFBhY2thZ2VzW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldKSB8fCBpc3NldCgkdGhpcy0+Zml4ZWRMb2NrZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaXhlZE9yTG9ja2VkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9tZXJnZSgkdGhpcy0+Zml4ZWRQYWNrYWdlcywgJHRoaXMtPmxvY2tlZFBhY2thZ2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRwYWNrYWdlSWRzCiAgICAgKiBAcmV0dXJuIGFycmF5PGludHxzdHJpbmcsIEJhc2VQYWNrYWdlPgogICAgICoKICAgICAqIEBUT0RPIGxvb2sgaW50byByZW1vdmluZyB0aGUgcGFja2FnZUlkcyBvcHRpb24sIHRoZSBvbmx5IHBsYWNlIHRydWUgaXMgdXNlZAogICAgICogICAgICAgaXMgZm9yIHRoZSBpbnN0YWxsZWQgbWFwIGluIHRoZSBzb2x2ZXIgcHJvYmxlbXMuCiAgICAgKiAgICAgICBTb21lIGxvY2tlZCBwYWNrYWdlcyBtYXkgbm90IGJlIGluIHRoZSBwb29sLAogICAgICogICAgICAgc28gdGhleSBoYXZlIGEgcGFja2FnZS0+aWQgb2YgLTEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXNlbnRNYXAoJHBhY2thZ2VJZHMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcHJlc2VudE1hcCA9IGFycmF5KCk7CgogICAgICAgIGlmICgkdGhpcy0+bG9ja2VkUmVwb3NpdG9yeSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+bG9ja2VkUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJHByZXNlbnRNYXBbJHBhY2thZ2VJZHMgPyAkcGFja2FnZS0+Z2V0SWQoKSA6IHNwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5maXhlZFBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRwcmVzZW50TWFwWyRwYWNrYWdlSWRzID8gJHBhY2thZ2UtPmdldElkKCkgOiBzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwcmVzZW50TWFwOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBCYXNlUGFja2FnZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaXhlZFBhY2thZ2VzTWFwKCkKICAgIHsKICAgICAgICAkZml4ZWRQYWNrYWdlc01hcCA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5maXhlZFBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRmaXhlZFBhY2thZ2VzTWFwWyRwYWNrYWdlLT5nZXRJZCgpXSA9ICRwYWNrYWdlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaXhlZFBhY2thZ2VzTWFwOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiA/TG9ja0FycmF5UmVwb3NpdG9yeQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9ja2VkUmVwb3NpdG9yeSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NrZWRSZXBvc2l0b3J5OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIERlZmF1bHRQb2xpY3kgaW1wbGVtZW50cyBQb2xpY3lJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkcHJlZmVyU3RhYmxlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkcHJlZmVyTG93ZXN0OwoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJHByZWZlclN0YWJsZQogICAgICogQHBhcmFtIGJvb2wgJHByZWZlckxvd2VzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHByZWZlclN0YWJsZSA9IGZhbHNlLCAkcHJlZmVyTG93ZXN0ID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlclN0YWJsZSA9ICRwcmVmZXJTdGFibGU7CiAgICAgICAgJHRoaXMtPnByZWZlckxvd2VzdCA9ICRwcmVmZXJMb3dlc3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvciBPbmUgb2YgQ29uc3RyYWludDo6U1RSX09QXyoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIENvbnN0cmFpbnQ6OlNUUl9PUF8qICRvcGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmVyc2lvbkNvbXBhcmUoUGFja2FnZUludGVyZmFjZSAkYSwgUGFja2FnZUludGVyZmFjZSAkYiwgJG9wZXJhdG9yKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cHJlZmVyU3RhYmxlICYmICgkc3RhYkEgPSAkYS0+Z2V0U3RhYmlsaXR5KCkpICE9PSAoJHN0YWJCID0gJGItPmdldFN0YWJpbGl0eSgpKSkgewogICAgICAgICAgICByZXR1cm4gQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1skc3RhYkFdIDwgQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1skc3RhYkJdOwogICAgICAgIH0KCiAgICAgICAgJGNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgkb3BlcmF0b3IsICRiLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICR2ZXJzaW9uID0gbmV3IENvbnN0cmFpbnQoJz09JywgJGEtPmdldFZlcnNpb24oKSk7CgogICAgICAgIHJldHVybiAkY29uc3RyYWludC0+bWF0Y2hTcGVjaWZpYygkdmVyc2lvbiwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludFtdICAkbGl0ZXJhbHMKICAgICAqIEBwYXJhbSAgc3RyaW5nICRyZXF1aXJlZFBhY2thZ2UKICAgICAqIEByZXR1cm4gaW50W10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlbGVjdFByZWZlcnJlZFBhY2thZ2VzKFBvb2wgJHBvb2wsIGFycmF5ICRsaXRlcmFscywgJHJlcXVpcmVkUGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmdyb3VwTGl0ZXJhbHNCeU5hbWUoJHBvb2wsICRsaXRlcmFscyk7CiAgICAgICAgJHBvbGljeSA9ICR0aGlzOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJiRuYW1lTGl0ZXJhbHMpIHsKICAgICAgICAgICAgdXNvcnQoJG5hbWVMaXRlcmFscywgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkcG9saWN5LCAkcG9vbCwgJHJlcXVpcmVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRwb2xpY3ktPmNvbXBhcmVCeVByaW9yaXR5KCRwb29sLCAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkYSksICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRiKSwgJHJlcXVpcmVkUGFja2FnZSwgdHJ1ZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICYkc29ydGVkTGl0ZXJhbHMpIHsKICAgICAgICAgICAgJHNvcnRlZExpdGVyYWxzID0gJHRoaXMtPnBydW5lVG9CZXN0VmVyc2lvbigkcG9vbCwgJHNvcnRlZExpdGVyYWxzKTsKICAgICAgICAgICAgJHNvcnRlZExpdGVyYWxzID0gJHRoaXMtPnBydW5lUmVtb3RlQWxpYXNlcygkcG9vbCwgJHNvcnRlZExpdGVyYWxzKTsKICAgICAgICB9CgogICAgICAgICRzZWxlY3RlZCA9IFxjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCBhcnJheV92YWx1ZXMoJHBhY2thZ2VzKSk7CgogICAgICAgIC8vIG5vdyBzb3J0IHRoZSByZXN1bHQgYWNyb3NzIGFsbCBwYWNrYWdlcyB0byByZXNwZWN0IHJlcGxhY2VzIGFjcm9zcyBwYWNrYWdlcwogICAgICAgIHVzb3J0KCRzZWxlY3RlZCwgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkcG9saWN5LCAkcG9vbCwgJHJlcXVpcmVkUGFja2FnZSkgewogICAgICAgICAgICByZXR1cm4gJHBvbGljeS0+Y29tcGFyZUJ5UHJpb3JpdHkoJHBvb2wsICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRhKSwgJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGIpLCAkcmVxdWlyZWRQYWNrYWdlKTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRzZWxlY3RlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgaW50W10gJGxpdGVyYWxzCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgaW50W10+CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBncm91cExpdGVyYWxzQnlOYW1lKFBvb2wgJHBvb2wsICRsaXRlcmFscykKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAkcGFja2FnZU5hbWUgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCktPmdldE5hbWUoKTsKCiAgICAgICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VzWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZXNbJHBhY2thZ2VOYW1lXSA9IGFycmF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBhY2thZ2VzWyRwYWNrYWdlTmFtZV1bXSA9ICRsaXRlcmFsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwcm90ZWN0ZWQKICAgICAqIEBwYXJhbSA/c3RyaW5nICRyZXF1aXJlZFBhY2thZ2UKICAgICAqIEBwYXJhbSBib29sICRpZ25vcmVSZXBsYWNlCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGFyZUJ5UHJpb3JpdHkoUG9vbCAkcG9vbCwgQmFzZVBhY2thZ2UgJGEsIEJhc2VQYWNrYWdlICRiLCAkcmVxdWlyZWRQYWNrYWdlID0gbnVsbCwgJGlnbm9yZVJlcGxhY2UgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBwcmVmZXIgYWxpYXNlcyB0byB0aGUgb3JpZ2luYWwgcGFja2FnZQogICAgICAgIGlmICgkYS0+Z2V0TmFtZSgpID09PSAkYi0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICRhQWxpYXNlZCA9ICRhIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlOwogICAgICAgICAgICAkYkFsaWFzZWQgPSAkYiBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZTsKICAgICAgICAgICAgaWYgKCRhQWxpYXNlZCAmJiAhJGJBbGlhc2VkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7IC8vIHVzZSBhCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkYUFsaWFzZWQgJiYgJGJBbGlhc2VkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsgLy8gdXNlIGIKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaWdub3JlUmVwbGFjZSkgewogICAgICAgICAgICAvLyByZXR1cm4gb3JpZ2luYWwsIG5vdCByZXBsYWNlZAogICAgICAgICAgICBpZiAoJHRoaXMtPnJlcGxhY2VzKCRhLCAkYikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOyAvLyB1c2UgYgogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+cmVwbGFjZXMoJGIsICRhKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOyAvLyB1c2UgYQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBmb3IgcmVwbGFjZXJzIG5vdCByZXBsYWNpbmcgZWFjaCBvdGhlciwgcHV0IGEgaGlnaGVyIHByaW8gb24gcmVwbGFjaW5nCiAgICAgICAgICAgIC8vIHBhY2thZ2VzIHdpdGggdGhlIHNhbWUgdmVuZG9yIGFzIHRoZSByZXF1aXJlZCBwYWNrYWdlCiAgICAgICAgICAgIGlmICgkcmVxdWlyZWRQYWNrYWdlICYmIGZhbHNlICE9PSAoJHBvcyA9IHN0cnBvcygkcmVxdWlyZWRQYWNrYWdlLCAnLycpKSkgewogICAgICAgICAgICAgICAgJHJlcXVpcmVkVmVuZG9yID0gc3Vic3RyKCRyZXF1aXJlZFBhY2thZ2UsIDAsICRwb3MpOwoKICAgICAgICAgICAgICAgICRhSXNTYW1lVmVuZG9yID0gc3RycG9zKCRhLT5nZXROYW1lKCksICRyZXF1aXJlZFZlbmRvcikgPT09IDA7CiAgICAgICAgICAgICAgICAkYklzU2FtZVZlbmRvciA9IHN0cnBvcygkYi0+Z2V0TmFtZSgpLCAkcmVxdWlyZWRWZW5kb3IpID09PSAwOwoKICAgICAgICAgICAgICAgIGlmICgkYklzU2FtZVZlbmRvciAhPT0gJGFJc1NhbWVWZW5kb3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGFJc1NhbWVWZW5kb3IgPyAtMSA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHByaW9yaXR5IGVxdWFsLCBzb3J0IGJ5IHBhY2thZ2UgaWQgdG8gbWFrZSByZXByb2R1Y2libGUKICAgICAgICBpZiAoJGEtPmlkID09PSAkYi0+aWQpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKCRhLT5pZCA8ICRiLT5pZCkgPyAtMSA6IDE7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc291cmNlIHJlcGxhY2VzIGEgcGFja2FnZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGFyZ2V0LgogICAgICoKICAgICAqIFJlcGxhY2UgY29uc3RyYWludHMgYXJlIGlnbm9yZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yCiAgICAgKiBwcmlvcml0aXNhdGlvbiwgbm90IGZvciBhY3R1YWwgY29uc3RyYWludCB2ZXJpZmljYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZXBsYWNlcyhCYXNlUGFja2FnZSAkc291cmNlLCBCYXNlUGFja2FnZSAkdGFyZ2V0KQogICAgewogICAgICAgIGZvcmVhY2ggKCRzb3VyY2UtPmdldFJlcGxhY2VzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgaWYgKCRsaW5rLT5nZXRUYXJnZXQoKSA9PT0gJHRhcmdldC0+Z2V0TmFtZSgpCi8vICAgICAgICAgICAgICAgICYmIChudWxsID09PSAkbGluay0+Z2V0Q29uc3RyYWludCgpIHx8Ci8vICAgICAgICAgICAgICAgICRsaW5rLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz09JywgJHRhcmdldC0+Z2V0VmVyc2lvbigpKSkpKSB7CiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludFtdICRsaXRlcmFscwogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJ1bmVUb0Jlc3RWZXJzaW9uKFBvb2wgJHBvb2wsICRsaXRlcmFscykKICAgIHsKICAgICAgICAkb3BlcmF0b3IgPSAkdGhpcy0+cHJlZmVyTG93ZXN0ID8gJzwnIDogJz4nOwogICAgICAgICRiZXN0TGl0ZXJhbHMgPSBhcnJheSgkbGl0ZXJhbHNbMF0pOwogICAgICAgICRiZXN0UGFja2FnZSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsc1swXSk7CiAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRpID0+ICRsaXRlcmFsKSB7CiAgICAgICAgICAgIGlmICgwID09PSAkaSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwYWNrYWdlID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT52ZXJzaW9uQ29tcGFyZSgkcGFja2FnZSwgJGJlc3RQYWNrYWdlLCAkb3BlcmF0b3IpKSB7CiAgICAgICAgICAgICAgICAkYmVzdFBhY2thZ2UgPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgICRiZXN0TGl0ZXJhbHMgPSBhcnJheSgkbGl0ZXJhbCk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+dmVyc2lvbkNvbXBhcmUoJHBhY2thZ2UsICRiZXN0UGFja2FnZSwgJz09JykpIHsKICAgICAgICAgICAgICAgICRiZXN0TGl0ZXJhbHNbXSA9ICRsaXRlcmFsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGJlc3RMaXRlcmFsczsKICAgIH0KCiAgICAvKioKICAgICAqIEFzc3VtZXMgdGhhdCBsb2NhbGx5IGFsaWFzZWQgKGluIHJvb3QgcGFja2FnZSByZXF1aXJlcykgcGFja2FnZXMgdGFrZSBwcmlvcml0eSBvdmVyIGJyYW5jaC1hbGlhcyBvbmVzCiAgICAgKgogICAgICogSWYgbm8gcGFja2FnZSBpcyBhIGxvY2FsIGFsaWFzLCBub3RoaW5nIGhhcHBlbnMKICAgICAqCiAgICAgKiBAcGFyYW0gIGludFtdICRsaXRlcmFscwogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJ1bmVSZW1vdGVBbGlhc2VzKFBvb2wgJHBvb2wsIGFycmF5ICRsaXRlcmFscykKICAgIHsKICAgICAgICAkaGFzTG9jYWxBbGlhcyA9IGZhbHNlOwoKICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CgogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgJiYgJHBhY2thZ2UtPmlzUm9vdFBhY2thZ2VBbGlhcygpKSB7CiAgICAgICAgICAgICAgICAkaGFzTG9jYWxBbGlhcyA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaGFzTG9jYWxBbGlhcykgewogICAgICAgICAgICByZXR1cm4gJGxpdGVyYWxzOwogICAgICAgIH0KCiAgICAgICAgJHNlbGVjdGVkID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CgogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgJiYgJHBhY2thZ2UtPmlzUm9vdFBhY2thZ2VBbGlhcygpKSB7CiAgICAgICAgICAgICAgICAkc2VsZWN0ZWRbXSA9ICRsaXRlcmFsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNlbGVjdGVkOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbnNvbGU7Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVyU3R5bGU7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSHRtbE91dHB1dEZvcm1hdHRlciBleHRlbmRzIE91dHB1dEZvcm1hdHRlcgp7CiAgICAvKiogQHZhciBhcnJheTxpbnQsIHN0cmluZz4gKi8KICAgIHByaXZhdGUgc3RhdGljICRhdmFpbGFibGVGb3JlZ3JvdW5kQ29sb3JzID0gYXJyYXkoCiAgICAgICAgMzAgPT4gJ2JsYWNrJywKICAgICAgICAzMSA9PiAncmVkJywKICAgICAgICAzMiA9PiAnZ3JlZW4nLAogICAgICAgIDMzID0+ICd5ZWxsb3cnLAogICAgICAgIDM0ID0+ICdibHVlJywKICAgICAgICAzNSA9PiAnbWFnZW50YScsCiAgICAgICAgMzYgPT4gJ2N5YW4nLAogICAgICAgIDM3ID0+ICd3aGl0ZScsCiAgICApOwogICAgLyoqIEB2YXIgYXJyYXk8aW50LCBzdHJpbmc+ICovCiAgICBwcml2YXRlIHN0YXRpYyAkYXZhaWxhYmxlQmFja2dyb3VuZENvbG9ycyA9IGFycmF5KAogICAgICAgIDQwID0+ICdibGFjaycsCiAgICAgICAgNDEgPT4gJ3JlZCcsCiAgICAgICAgNDIgPT4gJ2dyZWVuJywKICAgICAgICA0MyA9PiAneWVsbG93JywKICAgICAgICA0NCA9PiAnYmx1ZScsCiAgICAgICAgNDUgPT4gJ21hZ2VudGEnLAogICAgICAgIDQ2ID0+ICdjeWFuJywKICAgICAgICA0NyA9PiAnd2hpdGUnLAogICAgKTsKICAgIC8qKiBAdmFyIGFycmF5PGludCwgc3RyaW5nPiAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGF2YWlsYWJsZU9wdGlvbnMgPSBhcnJheSgKICAgICAgICAxID0+ICdib2xkJywKICAgICAgICA0ID0+ICd1bmRlcnNjb3JlJywKICAgICAgICAvLzUgPT4gJ2JsaW5rJywKICAgICAgICAvLzcgPT4gJ3JldmVyc2UnLAogICAgICAgIC8vOCA9PiAnY29uY2VhbCcKICAgICk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBPdXRwdXRGb3JtYXR0ZXJTdHlsZT4gJHN0eWxlcyBBcnJheSBvZiAibmFtZSA9PiBGb3JtYXR0ZXJTdHlsZSIgaW5zdGFuY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkc3R5bGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KHRydWUsICRzdHlsZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtID9zdHJpbmcgJG1lc3NhZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZm9ybWF0KCRtZXNzYWdlKQogICAgewogICAgICAgICRmb3JtYXR0ZWQgPSBwYXJlbnQ6OmZvcm1hdCgkbWVzc2FnZSk7CgogICAgICAgICRjbGVhckVzY2FwZUNvZGVzID0gJyg/OjM5fDQ5fDB8MjJ8MjR8MjV8Mjd8MjgpJzsKCiAgICAgICAgLy8gVE9ETyBpbiAyLjMgcmVwbGFjZSB3aXRoIENsb3N1cmU6OmZyb21DYWxsYWJsZSBhbmQgdGhlbiB1c2UgUHJlZzo6cmVwbGFjZUNhbGxiYWNrCiAgICAgICAgcmV0dXJuIHByZWdfcmVwbGFjZV9jYWxsYmFjaygie1wwMzNcWyhbMC05O10rKW0oLio/KVwwMzNcWyg/OiIuJGNsZWFyRXNjYXBlQ29kZXMuIjspKj8iLiRjbGVhckVzY2FwZUNvZGVzLiJtfXMiLCBhcnJheSgkdGhpcywgJ2Zvcm1hdEh0bWwnKSwgJGZvcm1hdHRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJG1hdGNoZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZvcm1hdEh0bWwoJG1hdGNoZXMpCiAgICB7CiAgICAgICAgJG91dCA9ICc8c3BhbiBzdHlsZT0iJzsKICAgICAgICBmb3JlYWNoIChleHBsb2RlKCc7JywgJG1hdGNoZXNbMV0pIGFzICRjb2RlKSB7CiAgICAgICAgICAgIGlmIChpc3NldChzZWxmOjokYXZhaWxhYmxlRm9yZWdyb3VuZENvbG9yc1soaW50KSAkY29kZV0pKSB7CiAgICAgICAgICAgICAgICAkb3V0IC49ICdjb2xvcjonLnNlbGY6OiRhdmFpbGFibGVGb3JlZ3JvdW5kQ29sb3JzWyhpbnQpICRjb2RlXS4nOyc7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldChzZWxmOjokYXZhaWxhYmxlQmFja2dyb3VuZENvbG9yc1soaW50KSAkY29kZV0pKSB7CiAgICAgICAgICAgICAgICAkb3V0IC49ICdiYWNrZ3JvdW5kLWNvbG9yOicuc2VsZjo6JGF2YWlsYWJsZUJhY2tncm91bmRDb2xvcnNbKGludCkgJGNvZGVdLic7JzsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KHNlbGY6OiRhdmFpbGFibGVPcHRpb25zWyhpbnQpICRjb2RlXSkpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoc2VsZjo6JGF2YWlsYWJsZU9wdGlvbnNbKGludCkgJGNvZGVdKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYm9sZCc6CiAgICAgICAgICAgICAgICAgICAgICAgICRvdXQgLj0gJ2ZvbnQtd2VpZ2h0OmJvbGQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3VuZGVyc2NvcmUnOgogICAgICAgICAgICAgICAgICAgICAgICAkb3V0IC49ICd0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lOyc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG91dC4nIj4nLiRtYXRjaGVzWzJdLic8L3NwYW4+JzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb25zb2xlOwoKdXNlIENvbXBvc2VyXElPXE51bGxJTzsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxBcHBsaWNhdGlvbiBhcyBCYXNlQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxDb21tYW5kTm90Rm91bmRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxIZWxwZXJTZXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxRdWVzdGlvbkhlbHBlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTZWxkXEpzb25MaW50XFBhcnNpbmdFeGNlcHRpb247CnVzZSBDb21wb3NlclxDb21tYW5kOwp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xDb25zb2xlSU87CnVzZSBDb21wb3NlclxKc29uXEpzb25WYWxpZGF0aW9uRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcVXRpbFxFcnJvckhhbmRsZXI7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXFNjcmlwdEV4ZWN1dGlvbkV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXEV4Y2VwdGlvblxOb1NzbEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFhkZWJ1Z0hhbmRsZXJcWGRlYnVnSGFuZGxlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFByb2Nlc3NUaW1lZE91dEV4Y2VwdGlvbjsKCi8qKgogKiBUaGUgY29uc29sZSBhcHBsaWNhdGlvbiB0aGF0IGhhbmRsZXMgdGhlIGNvbW1hbmRzCiAqCiAqIEBhdXRob3IgUnlhbiBXZWF2ZXIgPHJ5YW5Aa25wbGFicy5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmNsYXNzIEFwcGxpY2F0aW9uIGV4dGVuZHMgQmFzZUFwcGxpY2F0aW9uCnsKICAgIC8qKgogICAgICogQHZhciA/Q29tcG9zZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21wb3NlcjsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgc3RhdGljICRsb2dvID0gJyAgIF9fX19fXwogIC8gX19fXy9fX18gIF9fX18gX19fICBfX19fICBfX19fICBfX19fX19fXyAgX19fX18KIC8gLyAgIC8gX18gXC8gX18gYF9fIFwvIF9fIFwvIF9fIFwvIF9fXy8gXyBcLyBfX18vCi8gL19fXy8gL18vIC8gLyAvIC8gLyAvIC9fLyAvIC9fLyAoX18gICkgIF9fLyAvClxfX19fL1xfX19fL18vIC9fLyAvXy8gLl9fXy9cX19fXy9fX19fL1xfX18vXy8KICAgICAgICAgICAgICAgICAgICAvXy8KJzsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRoYXNQbHVnaW5Db21tYW5kcyA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkZGlzYWJsZVBsdWdpbnNCeURlZmF1bHQgPSBmYWxzZTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGRpc2FibGVTY3JpcHRzQnlEZWZhdWx0ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZyBTdG9yZSB0aGUgaW5pdGlhbCB3b3JraW5nIGRpcmVjdG9yeSBhdCBzdGFydHVwIHRpbWUKICAgICAqLwogICAgcHJpdmF0ZSAkaW5pdGlhbFdvcmtpbmdEaXJlY3Rvcnk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgICAgICBzdGF0aWMgJHNodXRkb3duUmVnaXN0ZXJlZCA9IGZhbHNlOwoKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdpbmlfc2V0JykgJiYgZXh0ZW5zaW9uX2xvYWRlZCgneGRlYnVnJykpIHsKICAgICAgICAgICAgaW5pX3NldCgneGRlYnVnLnNob3dfZXhjZXB0aW9uX3RyYWNlJywgJzAnKTsKICAgICAgICAgICAgaW5pX3NldCgneGRlYnVnLnNjcmVhbScsICcwJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdkYXRlX2RlZmF1bHRfdGltZXpvbmVfc2V0JykgJiYgZnVuY3Rpb25fZXhpc3RzKCdkYXRlX2RlZmF1bHRfdGltZXpvbmVfZ2V0JykpIHsKICAgICAgICAgICAgZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldChTaWxlbmNlcjo6Y2FsbCgnZGF0ZV9kZWZhdWx0X3RpbWV6b25lX2dldCcpKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHNodXRkb3duUmVnaXN0ZXJlZCkgewogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwY250bF9hc3luY19zaWduYWxzJykgJiYgZnVuY3Rpb25fZXhpc3RzKCdwY250bF9zaWduYWwnKSkgewogICAgICAgICAgICAgICAgcGNudGxfYXN5bmNfc2lnbmFscyh0cnVlKTsKICAgICAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsIGZ1bmN0aW9uICgkc2lnKSB7CiAgICAgICAgICAgICAgICAgICAgZXhpdCgxMzApOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzaHV0ZG93blJlZ2lzdGVyZWQgPSB0cnVlOwoKICAgICAgICAgICAgcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgJGxhc3RFcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgogICAgICAgICAgICAgICAgaWYgKCRsYXN0RXJyb3IgJiYgJGxhc3RFcnJvclsnbWVzc2FnZSddICYmCiAgICAgICAgICAgICAgICAgICAoc3RycG9zKCRsYXN0RXJyb3JbJ21lc3NhZ2UnXSwgJ0FsbG93ZWQgbWVtb3J5JykgIT09IGZhbHNlIC8qWmVuZCBQSFAgb3V0IG9mIG1lbW9yeSBlcnJvciovIHx8CiAgICAgICAgICAgICAgICAgICAgc3RycG9zKCRsYXN0RXJyb3JbJ21lc3NhZ2UnXSwgJ2V4Y2VlZGVkIG1lbW9yeScpICE9PSBmYWxzZSAvKkhIVk0gb3V0IG9mIG1lbW9yeSBlcnJvcnMqLykpIHsKICAgICAgICAgICAgICAgICAgICBlY2hvICJcbiIuICdDaGVjayBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvdHJvdWJsZXNob290aW5nLm1kI21lbW9yeS1saW1pdC1lcnJvcnMgZm9yIG1vcmUgaW5mbyBvbiBob3cgdG8gaGFuZGxlIG91dCBvZiBtZW1vcnkgZXJyb3JzLic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvID0gbmV3IE51bGxJTygpOwoKICAgICAgICAkdGhpcy0+aW5pdGlhbFdvcmtpbmdEaXJlY3RvcnkgPSBnZXRjd2QoKTsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgnQ29tcG9zZXInLCBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBydW4oSW5wdXRJbnRlcmZhY2UgJGlucHV0ID0gbnVsbCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkb3V0cHV0KSB7CiAgICAgICAgICAgICRvdXRwdXQgPSBGYWN0b3J5OjpjcmVhdGVPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OnJ1bigkaW5wdXQsICRvdXRwdXQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRvUnVuKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmRpc2FibGVQbHVnaW5zQnlEZWZhdWx0ID0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tbm8tcGx1Z2lucycpOwogICAgICAgICR0aGlzLT5kaXNhYmxlU2NyaXB0c0J5RGVmYXVsdCA9ICRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKCctLW5vLXNjcmlwdHMnKTsKCiAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX05PX0lOVEVSQUNUSU9OJykgfHwgIVBsYXRmb3JtOjppc1R0eShkZWZpbmVkKCdTVERJTicpID8gU1RESU4gOiBmb3BlbigncGhwOi8vc3RkaW4nLCAncicpKSkgewogICAgICAgICAgICAkaW5wdXQtPnNldEludGVyYWN0aXZlKGZhbHNlKTsKICAgICAgICB9CgogICAgICAgICRpbyA9ICR0aGlzLT5pbyA9IG5ldyBDb25zb2xlSU8oJGlucHV0LCAkb3V0cHV0LCBuZXcgSGVscGVyU2V0KGFycmF5KAogICAgICAgICAgICBuZXcgUXVlc3Rpb25IZWxwZXIoKSwKICAgICAgICApKSk7CgogICAgICAgIC8vIFJlZ2lzdGVyIGVycm9yIGhhbmRsZXIgYWdhaW4gdG8gcGFzcyBpdCB0aGUgSU8gaW5zdGFuY2UKICAgICAgICBFcnJvckhhbmRsZXI6OnJlZ2lzdGVyKCRpbyk7CgogICAgICAgIGlmICgkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbignLS1uby1jYWNoZScpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignRGlzYWJsaW5nIGNhY2hlIHVzYWdlJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgUGxhdGZvcm06OnB1dEVudignQ09NUE9TRVJfQ0FDSEVfRElSJywgUGxhdGZvcm06OmlzV2luZG93cygpID8gJ251bCcgOiAnL2Rldi9udWxsJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBzd2l0Y2ggd29ya2luZyBkaXIKICAgICAgICBpZiAoJG5ld1dvcmtEaXIgPSAkdGhpcy0+Z2V0TmV3V29ya2luZ0RpcigkaW5wdXQpKSB7CiAgICAgICAgICAgICRvbGRXb3JraW5nRGlyID0gZ2V0Y3dkKCk7CiAgICAgICAgICAgIGNoZGlyKCRuZXdXb3JrRGlyKTsKICAgICAgICAgICAgJHRoaXMtPmluaXRpYWxXb3JraW5nRGlyZWN0b3J5ID0gJG5ld1dvcmtEaXI7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignQ2hhbmdlZCBDV0QgdG8gJyAuIGdldGN3ZCgpLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgIH0KCiAgICAgICAgLy8gZGV0ZXJtaW5lIGNvbW1hbmQgbmFtZSB0byBiZSBleGVjdXRlZCB3aXRob3V0IGluY2x1ZGluZyBwbHVnaW4gY29tbWFuZHMKICAgICAgICAkY29tbWFuZE5hbWUgPSAnJzsKICAgICAgICBpZiAoJG5hbWUgPSAkdGhpcy0+Z2V0Q29tbWFuZE5hbWUoJGlucHV0KSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGNvbW1hbmROYW1lID0gJHRoaXMtPmZpbmQoJG5hbWUpLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gd2UnbGwgY2hlY2sgY29tbWFuZCB2YWxpZGl0eSBhZ2FpbiBsYXRlciBhZnRlciBwbHVnaW5zIGFyZSBsb2FkZWQKICAgICAgICAgICAgICAgICRjb21tYW5kTmFtZSA9IGZhbHNlOwogICAgICAgICAgICB9IGNhdGNoIChcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHByb21wdCB1c2VyIGZvciBkaXIgY2hhbmdlIGlmIG5vIGNvbXBvc2VyLmpzb24gaXMgcHJlc2VudCBpbiBjdXJyZW50IGRpcgogICAgICAgIGlmICgkaW8tPmlzSW50ZXJhY3RpdmUoKSAmJiAhJG5ld1dvcmtEaXIgJiYgIWluX2FycmF5KCRjb21tYW5kTmFtZSwgYXJyYXkoJycsICdsaXN0JywgJ2luaXQnLCAnYWJvdXQnLCAnaGVscCcsICdkaWFnbm9zZScsICdzZWxmLXVwZGF0ZScsICdnbG9iYWwnLCAnY3JlYXRlLXByb2plY3QnLCAnb3V0ZGF0ZWQnKSwgdHJ1ZSkgJiYgIWZpbGVfZXhpc3RzKEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpKSAmJiAoJHVzZVBhcmVudERpcklmTm9Kc29uQXZhaWxhYmxlID0gJHRoaXMtPmdldFVzZVBhcmVudERpckNvbmZpZ1ZhbHVlKCkpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkZGlyID0gZGlybmFtZShnZXRjd2QoKSk7CiAgICAgICAgICAgICRob21lID0gcmVhbHBhdGgoUGxhdGZvcm06OmdldEVudignSE9NRScpID86IFBsYXRmb3JtOjpnZXRFbnYoJ1VTRVJQUk9GSUxFJykgPzogJy8nKTsKCiAgICAgICAgICAgIC8vIGFib3J0IHdoZW4gd2UgcmVhY2ggdGhlIGhvbWUgZGlyIG9yIHRvcCBvZiB0aGUgZmlsZXN5c3RlbQogICAgICAgICAgICB3aGlsZSAoZGlybmFtZSgkZGlyKSAhPT0gJGRpciAmJiAkZGlyICE9PSAkaG9tZSkgewogICAgICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRkaXIuJy8nLkZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdXNlUGFyZW50RGlySWZOb0pzb25BdmFpbGFibGUgPT09IHRydWUgfHwgJGlvLT5hc2tDb25maXJtYXRpb24oJzxpbmZvPk5vIGNvbXBvc2VyLmpzb24gaW4gY3VycmVudCBkaXJlY3RvcnksIGRvIHlvdSB3YW50IHRvIHVzZSB0aGUgb25lIGF0ICcuJGRpci4nPzwvaW5mbz4gWzxjb21tZW50PlksbjwvY29tbWVudD5dPyAnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHVzZVBhcmVudERpcklmTm9Kc29uQXZhaWxhYmxlID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPk5vIGNvbXBvc2VyLmpzb24gaW4gY3VycmVudCBkaXJlY3RvcnksIGNoYW5naW5nIHdvcmtpbmcgZGlyZWN0b3J5IHRvICcuJGRpci4nPC9pbmZvPicpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5BbHdheXMgd2FudCB0byB1c2UgdGhlIHBhcmVudCBkaXI/IFVzZSAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIHVzZS1wYXJlbnQtZGlyIHRydWUiIHRvIGNoYW5nZSB0aGUgZGVmYXVsdC48L2luZm8+Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJG9sZFdvcmtpbmdEaXIgPSBnZXRjd2QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hkaXIoJGRpcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGRpciA9IGRpcm5hbWUoJGRpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGF2b2lkIGxvYWRpbmcgcGx1Z2lucy9pbml0aWFsaXppbmcgdGhlIENvbXBvc2VyIGluc3RhbmNlIGVhcmxpZXIgdGhhbiBuZWNlc3NhcnkgaWYgbm8gcGx1Z2luIGNvbW1hbmQgaXMgbmVlZGVkCiAgICAgICAgLy8gaWYgc2hvd2luZyB0aGUgdmVyc2lvbiwgd2UgbmV2ZXIgbmVlZCBwbHVnaW4gY29tbWFuZHMKICAgICAgICAkbWF5TmVlZFBsdWdpbkNvbW1hbmQgPSBmYWxzZSA9PT0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oYXJyYXkoJy0tdmVyc2lvbicsICctVicpKQogICAgICAgICAgICAmJiAoCiAgICAgICAgICAgICAgICAvLyBub3QgYSBjb21wb3NlciBjb21tYW5kLCBzbyB0cnkgbG9hZGluZyBwbHVnaW4gb25lcwogICAgICAgICAgICAgICAgZmFsc2UgPT09ICRjb21tYW5kTmFtZQogICAgICAgICAgICAgICAgLy8gbGlzdCBjb21tYW5kIHJlcXVpcmVzIHBsdWdpbiBjb21tYW5kcyB0byBzaG93IHRoZW0KICAgICAgICAgICAgICAgIHx8IGluX2FycmF5KCRjb21tYW5kTmFtZSwgYXJyYXkoJycsICdsaXN0JywgJ2hlbHAnKSwgdHJ1ZSkKICAgICAgICAgICAgKTsKCiAgICAgICAgaWYgKCRtYXlOZWVkUGx1Z2luQ29tbWFuZCAmJiAhJHRoaXMtPmRpc2FibGVQbHVnaW5zQnlEZWZhdWx0ICYmICEkdGhpcy0+aGFzUGx1Z2luQ29tbWFuZHMpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQbHVnaW5Db21tYW5kcygpIGFzICRjb21tYW5kKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXMoJGNvbW1hbmQtPmdldE5hbWUoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5QbHVnaW4gY29tbWFuZCAnLiRjb21tYW5kLT5nZXROYW1lKCkuJyAoJy5nZXRfY2xhc3MoJGNvbW1hbmQpLicpIHdvdWxkIG92ZXJyaWRlIGEgQ29tcG9zZXIgY29tbWFuZCBhbmQgaGFzIGJlZW4gc2tpcHBlZDwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkKCRjb21tYW5kKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3NsRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyBzdXBwcmVzcyB0aGVzZSBhcyB0aGV5IGFyZSBub3QgcmVsZXZhbnQgYXQgdGhpcyBwb2ludAogICAgICAgICAgICB9IGNhdGNoIChQYXJzaW5nRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkZGV0YWlscyA9ICRlLT5nZXREZXRhaWxzKCk7CgogICAgICAgICAgICAgICAgJGZpbGUgPSByZWFscGF0aChGYWN0b3J5OjpnZXRDb21wb3NlckZpbGUoKSk7CgogICAgICAgICAgICAgICAgJGxpbmUgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCRkZXRhaWxzICYmIGlzc2V0KCRkZXRhaWxzWydsaW5lJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSAkZGV0YWlsc1snbGluZSddOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRnaGUgPSBuZXcgR2l0aHViQWN0aW9uRXJyb3IoJHRoaXMtPmlvKTsKICAgICAgICAgICAgICAgICRnaGUtPmVtaXQoJGUtPmdldE1lc3NhZ2UoKSwgJGZpbGUsICRsaW5lKTsKCiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmhhc1BsdWdpbkNvbW1hbmRzID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGRldGVybWluZSBjb21tYW5kIG5hbWUgdG8gYmUgZXhlY3V0ZWQgaW5jbCBwbHVnaW4gY29tbWFuZHMsIGFuZCBjaGVjayBpZiBpdCdzIGEgcHJveHkgY29tbWFuZAogICAgICAgICRpc1Byb3h5Q29tbWFuZCA9IGZhbHNlOwogICAgICAgIGlmICgkbmFtZSA9ICR0aGlzLT5nZXRDb21tYW5kTmFtZSgkaW5wdXQpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5maW5kKCRuYW1lKTsKICAgICAgICAgICAgICAgICRjb21tYW5kTmFtZSA9ICRjb21tYW5kLT5nZXROYW1lKCk7CiAgICAgICAgICAgICAgICAkaXNQcm94eUNvbW1hbmQgPSAoJGNvbW1hbmQgaW5zdGFuY2VvZiBDb21tYW5kXEJhc2VDb21tYW5kICYmICRjb21tYW5kLT5pc1Byb3h5Q29tbWFuZCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoISRpc1Byb3h5Q29tbWFuZCkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICdSdW5uaW5nICVzICglcykgd2l0aCAlcyBvbiAlcycsCiAgICAgICAgICAgICAgICBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpLAogICAgICAgICAgICAgICAgQ29tcG9zZXI6OlJFTEVBU0VfREFURSwKICAgICAgICAgICAgICAgIGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpID8gJ0hIVk0gJy5ISFZNX1ZFUlNJT04gOiAnUEhQICcuUEhQX1ZFUlNJT04sCiAgICAgICAgICAgICAgICBmdW5jdGlvbl9leGlzdHMoJ3BocF91bmFtZScpID8gcGhwX3VuYW1lKCdzJykgLiAnIC8gJyAuIHBocF91bmFtZSgncicpIDogJ1Vua25vd24gT1MnCiAgICAgICAgICAgICksIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CgogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDMwMikgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Db21wb3NlciBvbmx5IG9mZmljaWFsbHkgc3VwcG9ydHMgUEhQIDUuMy4yIGFuZCBhYm92ZSwgeW91IHdpbGwgbW9zdCBsaWtlbHkgZW5jb3VudGVyIHByb2JsZW1zIHdpdGggeW91ciBQSFAgJy5QSFBfVkVSU0lPTi4nLCB1cGdyYWRpbmcgaXMgc3Ryb25nbHkgcmVjb21tZW5kZWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoWGRlYnVnSGFuZGxlcjo6aXNYZGVidWdBY3RpdmUoKSAmJiAhUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfRElTQUJMRV9YREVCVUdfV0FSTicpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNvbXBvc2VyIGlzIG9wZXJhdGluZyBzbG93ZXIgdGhhbiBub3JtYWwgYmVjYXVzZSB5b3UgaGF2ZSBYZGVidWcgZW5hYmxlZC4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL3hkZWJ1Zzwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGRlZmluZWQoJ0NPTVBPU0VSX0RFVl9XQVJOSU5HX1RJTUUnKSAmJiAkY29tbWFuZE5hbWUgIT09ICdzZWxmLXVwZGF0ZScgJiYgJGNvbW1hbmROYW1lICE9PSAnc2VsZnVwZGF0ZScgJiYgdGltZSgpID4gQ09NUE9TRVJfREVWX1dBUk5JTkdfVElNRSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoJzx3YXJuaW5nPldhcm5pbmc6IFRoaXMgZGV2ZWxvcG1lbnQgYnVpbGQgb2YgQ29tcG9zZXIgaXMgb3ZlciA2MCBkYXlzIG9sZC4gSXQgaXMgcmVjb21tZW5kZWQgdG8gdXBkYXRlIGl0IGJ5IHJ1bm5pbmcgIiVzIHNlbGYtdXBkYXRlIiB0byBnZXQgdGhlIGxhdGVzdCB2ZXJzaW9uLjwvd2FybmluZz4nLCAkX1NFUlZFUlsnUEhQX1NFTEYnXSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAhUGxhdGZvcm06OmlzV2luZG93cygpCiAgICAgICAgICAgICAgICAmJiBmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKQogICAgICAgICAgICAgICAgJiYgIVBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX0FMTE9XX1NVUEVSVVNFUicpCiAgICAgICAgICAgICAgICAmJiAoaW5pX2dldCgnb3Blbl9iYXNlZGlyJykgfHwgIWZpbGVfZXhpc3RzKCcvLmRvY2tlcmVudicpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldHVpZCcpICYmIHBvc2l4X2dldHVpZCgpID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjb21tYW5kTmFtZSAhPT0gJ3NlbGYtdXBkYXRlJyAmJiAkY29tbWFuZE5hbWUgIT09ICdzZWxmdXBkYXRlJykgewogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkRvIG5vdCBydW4gQ29tcG9zZXIgYXMgcm9vdC9zdXBlciB1c2VyISBTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvcm9vdCBmb3IgZGV0YWlsczwvd2FybmluZz4nKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkaW8tPmFza0NvbmZpcm1hdGlvbignPGluZm8+Q29udGludWUgYXMgcm9vdC9zdXBlciB1c2VyPC9pbmZvPiBbPGNvbW1lbnQ+eWVzPC9jb21tZW50Pl0/ICcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCR1aWQgPSAoaW50KSBQbGF0Zm9ybTo6Z2V0RW52KCdTVURPX1VJRCcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNpbGVudGx5IGNsb2JiZXIgYW55IHN1ZG8gY3JlZGVudGlhbHMgb24gdGhlIGludm9raW5nIHVzZXIgdG8gYXZvaWQgcHJpdmlsZWdlIGVzY2FsYXRpb25zIGxhdGVyIG9uCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZi4gaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy81MTE5CiAgICAgICAgICAgICAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdleGVjJywgInN1ZG8gLXUgXFwjeyR1aWR9IHN1ZG8gLUsgPiAvZGV2L251bGwgMj4mMSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFNpbGVudGx5IGNsb2JiZXIgYW55IHJlbWFpbmluZyBzdWRvIGxlYXNlcyBvbiB0aGUgY3VycmVudCB1c2VyIGFzIHdlbGwgdG8gYXZvaWQgcHJpdmlsZWdlIGVzY2FsYXRpb25zCiAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnZXhlYycsICdzdWRvIC1LID4gL2Rldi9udWxsIDI+JjEnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgc3lzdGVtIHRlbXAgZm9sZGVyIGZvciB1c2FiaWxpdHkgYXMgaXQgY2FuIGNhdXNlIHdlaXJkIHJ1bnRpbWUgaXNzdWVzIG90aGVyd2lzZQogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbChmdW5jdGlvbiAoKSB1c2UgKCRpbykgewogICAgICAgICAgICAgICAgJHRlbXBmaWxlID0gc3lzX2dldF90ZW1wX2RpcigpIC4gJy90ZW1wLScgLiBtZDUobWljcm90aW1lKCkpOwogICAgICAgICAgICAgICAgaWYgKCEoZmlsZV9wdXRfY29udGVudHMoJHRlbXBmaWxlLCBfX0ZJTEVfXykgJiYgKGZpbGVfZ2V0X2NvbnRlbnRzKCR0ZW1wZmlsZSkgPT0gX19GSUxFX18pICYmIHVubGluaygkdGVtcGZpbGUpICYmICFmaWxlX2V4aXN0cygkdGVtcGZpbGUpKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+UEhQIHRlbXAgZGlyZWN0b3J5ICglcykgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IHdyaXRhYmxlIHRvIENvbXBvc2VyLiBTZXQgc3lzX3RlbXBfZGlyIGluIHlvdXIgcGhwLmluaTwvZXJyb3I+Jywgc3lzX2dldF90ZW1wX2RpcigpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgLy8gYWRkIG5vbi1zdGFuZGFyZCBzY3JpcHRzIGFzIG93biBjb21tYW5kcwogICAgICAgICAgICAkZmlsZSA9IEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpOwogICAgICAgICAgICBpZiAoaXNfZmlsZSgkZmlsZSkgJiYgRmlsZXN5c3RlbTo6aXNSZWFkYWJsZSgkZmlsZSkgJiYgaXNfYXJyYXkoJGNvbXBvc2VyID0ganNvbl9kZWNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpLCB0cnVlKSkpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29tcG9zZXJbJ3NjcmlwdHMnXSkgJiYgaXNfYXJyYXkoJGNvbXBvc2VyWydzY3JpcHRzJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbXBvc2VyWydzY3JpcHRzJ10gYXMgJHNjcmlwdCA9PiAkZHVtbXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkZWZpbmVkKCdDb21wb3NlclxTY3JpcHRcU2NyaXB0RXZlbnRzOjonLnN0cl9yZXBsYWNlKCctJywgJ18nLCBzdHJ0b3VwcGVyKCRzY3JpcHQpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aGFzKCRzY3JpcHQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5BIHNjcmlwdCBuYW1lZCAnLiRzY3JpcHQuJyB3b3VsZCBvdmVycmlkZSBhIENvbXBvc2VyIGNvbW1hbmQgYW5kIGhhcyBiZWVuIHNraXBwZWQ8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29tcG9zZXJbJ3NjcmlwdHMtZGVzY3JpcHRpb25zJ11bJHNjcmlwdF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiA9ICRjb21wb3Nlclsnc2NyaXB0cy1kZXNjcmlwdGlvbnMnXVskc2NyaXB0XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGQobmV3IENvbW1hbmRcU2NyaXB0QWxpYXNDb21tYW5kKCRzY3JpcHQsICRkZXNjcmlwdGlvbikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tcHJvZmlsZScpKSB7CiAgICAgICAgICAgICAgICAkc3RhcnRUaW1lID0gbWljcm90aW1lKHRydWUpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5lbmFibGVEZWJ1Z2dpbmcoJHN0YXJ0VGltZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZXN1bHQgPSBwYXJlbnQ6OmRvUnVuKCRpbnB1dCwgJG91dHB1dCk7CgogICAgICAgICAgICAvLyBjaGRpciBiYWNrIHRvICRvbGRXb3JraW5nRGlyIGlmIHNldAogICAgICAgICAgICBpZiAoaXNzZXQoJG9sZFdvcmtpbmdEaXIpKSB7CiAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnY2hkaXInLCAkb2xkV29ya2luZ0Rpcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc3NldCgkc3RhcnRUaW1lKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5NZW1vcnkgdXNhZ2U6ICcucm91bmQobWVtb3J5X2dldF91c2FnZSgpIC8gMTAyNCAvIDEwMjQsIDIpLidNaUIgKHBlYWs6ICcucm91bmQobWVtb3J5X2dldF9wZWFrX3VzYWdlKCkgLyAxMDI0IC8gMTAyNCwgMikuJ01pQiksIHRpbWU6ICcucm91bmQobWljcm90aW1lKHRydWUpIC0gJHN0YXJ0VGltZSwgMikuJ3MnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9IGNhdGNoIChTY3JpcHRFeGVjdXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgcmV0dXJuICRlLT5nZXRDb2RlKCk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkZ2hlID0gbmV3IEdpdGh1YkFjdGlvbkVycm9yKCR0aGlzLT5pbyk7CiAgICAgICAgICAgICRnaGUtPmVtaXQoJGUtPmdldE1lc3NhZ2UoKSk7CgogICAgICAgICAgICAkdGhpcy0+aGludENvbW1vbkVycm9ycygkZSk7CgogICAgICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSW5wdXRJbnRlcmZhY2UgICAgJGlucHV0CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldE5ld1dvcmtpbmdEaXIoSW5wdXRJbnRlcmZhY2UgJGlucHV0KQogICAgewogICAgICAgICR3b3JraW5nRGlyID0gJGlucHV0LT5nZXRQYXJhbWV0ZXJPcHRpb24oYXJyYXkoJy0td29ya2luZy1kaXInLCAnLWQnKSk7CiAgICAgICAgaWYgKGZhbHNlICE9PSAkd29ya2luZ0RpciAmJiAhaXNfZGlyKCR3b3JraW5nRGlyKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ludmFsaWQgd29ya2luZyBkaXJlY3Rvcnkgc3BlY2lmaWVkLCAnLiR3b3JraW5nRGlyLicgZG9lcyBub3QgZXhpc3QuJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHdvcmtpbmdEaXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBoaW50Q29tbW9uRXJyb3JzKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgU2lsZW5jZXI6OnN1cHByZXNzKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlLCB0cnVlKTsKICAgICAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CgogICAgICAgICAgICAgICAgJG1pblNwYWNlRnJlZSA9IDEwMjQgKiAxMDI0OwogICAgICAgICAgICAgICAgaWYgKCgoJGRmID0gZGlza19mcmVlX3NwYWNlKCRkaXIgPSAkY29uZmlnLT5nZXQoJ2hvbWUnKSkpICE9PSBmYWxzZSAmJiAkZGYgPCAkbWluU3BhY2VGcmVlKQogICAgICAgICAgICAgICAgICAgIHx8ICgoJGRmID0gZGlza19mcmVlX3NwYWNlKCRkaXIgPSAkY29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKSkpICE9PSBmYWxzZSAmJiAkZGYgPCAkbWluU3BhY2VGcmVlKQogICAgICAgICAgICAgICAgICAgIHx8ICgoJGRmID0gZGlza19mcmVlX3NwYWNlKCRkaXIgPSBzeXNfZ2V0X3RlbXBfZGlyKCkpKSAhPT0gZmFsc2UgJiYgJGRmIDwgJG1pblNwYWNlRnJlZSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPlRoZSBkaXNrIGhvc3RpbmcgJy4kZGlyLicgaXMgZnVsbCwgdGhpcyBtYXkgYmUgdGhlIGNhdXNlIG9mIHRoZSBmb2xsb3dpbmcgZXhjZXB0aW9uPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KICAgICAgICBTaWxlbmNlcjo6cmVzdG9yZSgpOwoKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpICYmIGZhbHNlICE9PSBzdHJwb3MoJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpLCAnVGhlIHN5c3RlbSBjYW5ub3QgZmluZCB0aGUgcGF0aCBzcGVjaWZpZWQnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5UaGUgZm9sbG93aW5nIGV4Y2VwdGlvbiBtYXkgYmUgY2F1c2VkIGJ5IGEgc3RhbGUgZW50cnkgaW4geW91ciBjbWQuZXhlIEF1dG9SdW48L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkNoZWNrIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQjLXRoZS1zeXN0ZW0tY2Fubm90LWZpbmQtdGhlLXBhdGgtc3BlY2lmaWVkLXdpbmRvd3MtIGZvciBkZXRhaWxzPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpLCAnZm9yayBmYWlsZWQgLSBDYW5ub3QgYWxsb2NhdGUgbWVtb3J5JykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+VGhlIGZvbGxvd2luZyBleGNlcHRpb24gaXMgY2F1c2VkIGJ5IGEgbGFjayBvZiBtZW1vcnkgb3Igc3dhcCwgb3Igbm90IGhhdmluZyBzd2FwIGNvbmZpZ3VyZWQ8L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkNoZWNrIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQjcHJvYy1vcGVuLWZvcmstZmFpbGVkLWVycm9ycyBmb3IgZGV0YWlsczwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZXhjZXB0aW9uIGluc3RhbmNlb2YgUHJvY2Vzc1RpbWVkT3V0RXhjZXB0aW9uKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPlRoZSBmb2xsb3dpbmcgZXhjZXB0aW9uIGlzIGNhdXNlZCBieSBhIHByb2Nlc3MgdGltZW91dDwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Q2hlY2sgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzA2LWNvbmZpZy5tZCNwcm9jZXNzLXRpbWVvdXQgZm9yIGRldGFpbHM8L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhpbnRzID0gSHR0cERvd25sb2FkZXI6OmdldEV4Y2VwdGlvbkhpbnRzKCRleGNlcHRpb24pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRoaW50cyBhcyAkaGludCkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCRoaW50LCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZWQKICAgICAqIEBwYXJhbSAgYm9vbHxudWxsICAgICAgICAgICAgICAgJGRpc2FibGVQbHVnaW5zCiAgICAgKiBAcGFyYW0gIGJvb2x8bnVsbCAgICAgICAgICAgICAgICRkaXNhYmxlU2NyaXB0cwogICAgICogQHRocm93cyBKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuID9cQ29tcG9zZXJcQ29tcG9zZXIgSWYgJHJlcXVpcmVkIGlzIHRydWUgdGhlbiB0aGUgcmV0dXJuIHZhbHVlIGlzIGd1YXJhbnRlZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VyKCRyZXF1aXJlZCA9IHRydWUsICRkaXNhYmxlUGx1Z2lucyA9IG51bGwsICRkaXNhYmxlU2NyaXB0cyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRkaXNhYmxlUGx1Z2lucykgewogICAgICAgICAgICAkZGlzYWJsZVBsdWdpbnMgPSAkdGhpcy0+ZGlzYWJsZVBsdWdpbnNCeURlZmF1bHQ7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsID09PSAkZGlzYWJsZVNjcmlwdHMpIHsKICAgICAgICAgICAgJGRpc2FibGVTY3JpcHRzID0gJHRoaXMtPmRpc2FibGVTY3JpcHRzQnlEZWZhdWx0OwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21wb3NlcikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gRmFjdG9yeTo6Y3JlYXRlKCR0aGlzLT5pbywgbnVsbCwgJGRpc2FibGVQbHVnaW5zLCAkZGlzYWJsZVNjcmlwdHMpOwogICAgICAgICAgICB9IGNhdGNoIChcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoJHJlcXVpcmVkKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgICAgIC8vIFRPRE8gY29tcG9zZXIgMi4zIHNpbXBsaWZ5IHRvICR0aGlzLT5hcmVFeGNlcHRpb25zQ2F1Z2h0KCkKICAgICAgICAgICAgICAgICAgICBpZiAoIW1ldGhvZF9leGlzdHMoJHRoaXMsICdhcmVFeGNlcHRpb25zQ2F1Z2h0JykgfHwgJHRoaXMtPmFyZUV4Y2VwdGlvbnNDYXVnaHQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoSnNvblZhbGlkYXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICgkcmVxdWlyZWQpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIGNhY2hlZCBjb21wb3NlciBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXRDb21wb3NlcigpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gbnVsbDsKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkdGhpcy0+Z2V0SU8oKSwgJ3Jlc2V0QXV0aGVudGljYXRpb25zJykpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPnJlc2V0QXV0aGVudGljYXRpb25zKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBJT0ludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SU8oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW87CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRsb2dvIC4gcGFyZW50OjpnZXRIZWxwKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBhbGwgdGhlIGNvbXBvc2VyIGNvbW1hbmRzLgogICAgICogQHJldHVybiBcU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmRbXQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0RGVmYXVsdENvbW1hbmRzKCkKICAgIHsKICAgICAgICAkY29tbWFuZHMgPSBhcnJheV9tZXJnZShwYXJlbnQ6OmdldERlZmF1bHRDb21tYW5kcygpLCBhcnJheSgKICAgICAgICAgICAgbmV3IENvbW1hbmRcQWJvdXRDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXENvbmZpZ0NvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcRGVwZW5kc0NvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcUHJvaGliaXRzQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxJbml0Q29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxJbnN0YWxsQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxDcmVhdGVQcm9qZWN0Q29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxVcGRhdGVDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFNlYXJjaENvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcVmFsaWRhdGVDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFNob3dDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFN1Z2dlc3RzQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxSZXF1aXJlQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxEdW1wQXV0b2xvYWRDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFN0YXR1c0NvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcQXJjaGl2ZUNvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcRGlhZ25vc2VDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFJ1blNjcmlwdENvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcTGljZW5zZXNDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXEdsb2JhbENvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcQ2xlYXJDYWNoZUNvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcUmVtb3ZlQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxIb21lQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxFeGVjQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxPdXRkYXRlZENvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcQ2hlY2tQbGF0Zm9ybVJlcXNDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXEZ1bmRDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFJlaW5zdGFsbENvbW1hbmQoKSwKICAgICAgICApKTsKCiAgICAgICAgaWYgKHN0cnBvcyhfX0ZJTEVfXywgJ3BoYXI6JykgPT09IDApIHsKICAgICAgICAgICAgJGNvbW1hbmRzW10gPSBuZXcgQ29tbWFuZFxTZWxmVXBkYXRlQ29tbWFuZCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21tYW5kczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb25nVmVyc2lvbigpCiAgICB7CiAgICAgICAgaWYgKENvbXBvc2VyOjpCUkFOQ0hfQUxJQVNfVkVSU0lPTiAmJiBDb21wb3Nlcjo6QlJBTkNIX0FMSUFTX1ZFUlNJT04gIT09ICdAcGFja2FnZV9icmFuY2hfYWxpYXNfdmVyc2lvbicuJ0AnKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKAogICAgICAgICAgICAgICAgJzxpbmZvPiVzPC9pbmZvPiB2ZXJzaW9uIDxjb21tZW50PiVzICglcyk8L2NvbW1lbnQ+ICVzJywKICAgICAgICAgICAgICAgICR0aGlzLT5nZXROYW1lKCksCiAgICAgICAgICAgICAgICBDb21wb3Nlcjo6QlJBTkNIX0FMSUFTX1ZFUlNJT04sCiAgICAgICAgICAgICAgICAkdGhpcy0+Z2V0VmVyc2lvbigpLAogICAgICAgICAgICAgICAgQ29tcG9zZXI6OlJFTEVBU0VfREFURQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0TG9uZ1ZlcnNpb24oKSAuICcgJyAuIENvbXBvc2VyOjpSRUxFQVNFX0RBVEU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIElucHV0RGVmaW5pdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0RGVmYXVsdElucHV0RGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgJGRlZmluaXRpb24gPSBwYXJlbnQ6OmdldERlZmF1bHRJbnB1dERlZmluaXRpb24oKTsKICAgICAgICAkZGVmaW5pdGlvbi0+YWRkT3B0aW9uKG5ldyBJbnB1dE9wdGlvbignLS1wcm9maWxlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNwbGF5IHRpbWluZyBhbmQgbWVtb3J5IHVzYWdlIGluZm9ybWF0aW9uJykpOwogICAgICAgICRkZWZpbml0aW9uLT5hZGRPcHRpb24obmV3IElucHV0T3B0aW9uKCctLW5vLXBsdWdpbnMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1doZXRoZXIgdG8gZGlzYWJsZSBwbHVnaW5zLicpKTsKICAgICAgICAkZGVmaW5pdGlvbi0+YWRkT3B0aW9uKG5ldyBJbnB1dE9wdGlvbignLS1uby1zY3JpcHRzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTa2lwcyB0aGUgZXhlY3V0aW9uIG9mIGFsbCBzY3JpcHRzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbiBmaWxlLicpKTsKICAgICAgICAkZGVmaW5pdGlvbi0+YWRkT3B0aW9uKG5ldyBJbnB1dE9wdGlvbignLS13b3JraW5nLWRpcicsICctZCcsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0lmIHNwZWNpZmllZCwgdXNlIHRoZSBnaXZlbiBkaXJlY3RvcnkgYXMgd29ya2luZyBkaXJlY3RvcnkuJykpOwogICAgICAgICRkZWZpbml0aW9uLT5hZGRPcHRpb24obmV3IElucHV0T3B0aW9uKCctLW5vLWNhY2hlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdQcmV2ZW50IHVzZSBvZiB0aGUgY2FjaGUnKSk7CgogICAgICAgIHJldHVybiAkZGVmaW5pdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29tbWFuZFxCYXNlQ29tbWFuZFtdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UGx1Z2luQ29tbWFuZHMoKQogICAgewogICAgICAgICRjb21tYW5kcyA9IGFycmF5KCk7CgogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSwgZmFsc2UpOwogICAgICAgIGlmIChudWxsID09PSAkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGNvbXBvc2VyID0gRmFjdG9yeTo6Y3JlYXRlR2xvYmFsKCR0aGlzLT5pbyk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICRwbSA9ICRjb21wb3Nlci0+Z2V0UGx1Z2luTWFuYWdlcigpOwogICAgICAgICAgICBmb3JlYWNoICgkcG0tPmdldFBsdWdpbkNhcGFiaWxpdGllcygnQ29tcG9zZXJcUGx1Z2luXENhcGFiaWxpdHlcQ29tbWFuZFByb3ZpZGVyJywgYXJyYXkoJ2NvbXBvc2VyJyA9PiAkY29tcG9zZXIsICdpbycgPT4gJHRoaXMtPmlvKSkgYXMgJGNhcGFiaWxpdHkpIHsKICAgICAgICAgICAgICAgICRuZXdDb21tYW5kcyA9ICRjYXBhYmlsaXR5LT5nZXRDb21tYW5kcygpOwogICAgICAgICAgICAgICAgaWYgKCFpc19hcnJheSgkbmV3Q29tbWFuZHMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1BsdWdpbiBjYXBhYmlsaXR5ICcuZ2V0X2NsYXNzKCRjYXBhYmlsaXR5KS4nIGZhaWxlZCB0byByZXR1cm4gYW4gYXJyYXkgZnJvbSBnZXRDb21tYW5kcycpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG5ld0NvbW1hbmRzIGFzICRjb21tYW5kKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkY29tbWFuZCBpbnN0YW5jZW9mIENvbW1hbmRcQmFzZUNvbW1hbmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1BsdWdpbiBjYXBhYmlsaXR5ICcuZ2V0X2NsYXNzKCRjYXBhYmlsaXR5KS4nIHJldHVybmVkIGFuIGludmFsaWQgdmFsdWUsIHdlIGV4cGVjdGVkIGFuIGFycmF5IG9mIENvbXBvc2VyXENvbW1hbmRcQmFzZUNvbW1hbmQgb2JqZWN0cycpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb21tYW5kcyA9IGFycmF5X21lcmdlKCRjb21tYW5kcywgJG5ld0NvbW1hbmRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21tYW5kczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgd29ya2luZyBkaXJlY3RvcnkgYXQgc3RhcnR1cCB0aW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluaXRpYWxXb3JraW5nRGlyZWN0b3J5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmluaXRpYWxXb3JraW5nRGlyZWN0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiAncHJvbXB0J3xib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0VXNlUGFyZW50RGlyQ29uZmlnVmFsdWUoKQogICAgewogICAgICAgICRjb25maWcgPSBGYWN0b3J5OjpjcmVhdGVDb25maWcoJHRoaXMtPmlvKTsKCiAgICAgICAgcmV0dXJuICRjb25maWctPmdldCgndXNlLXBhcmVudC1kaXInKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb25zb2xlOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKCmZpbmFsIGNsYXNzIEdpdGh1YkFjdGlvbkVycm9yCnsKICAgIC8qKgogICAgICogQHZhciBJT0ludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGlvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAgJGlvKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbWVzc2FnZQogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRmaWxlCiAgICAgKiBAcGFyYW0gbnVsbHxpbnQgICAgJGxpbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVtaXQoJG1lc3NhZ2UsICRmaWxlID0gbnVsbCwgJGxpbmUgPSBudWxsKQogICAgewogICAgICAgIGlmIChQbGF0Zm9ybTo6Z2V0RW52KCdHSVRIVUJfQUNUSU9OUycpICYmICFQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9URVNUU19BUkVfUlVOTklORycpKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJHRoaXMtPmVzY2FwZURhdGEoJG1lc3NhZ2UpOwoKICAgICAgICAgICAgaWYgKCRmaWxlICYmICRsaW5lKSB7CiAgICAgICAgICAgICAgICAkZmlsZSA9ICR0aGlzLT5lc2NhcGVQcm9wZXJ0eSgkZmlsZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKCI6OmVycm9yIGZpbGU9Ii4gJGZpbGUgLiIsbGluZT0iLiAkbGluZSAuIjo6Ii4gJG1lc3NhZ2UpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGZpbGUpIHsKICAgICAgICAgICAgICAgICRmaWxlID0gJHRoaXMtPmVzY2FwZVByb3BlcnR5KCRmaWxlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGUoIjo6ZXJyb3IgZmlsZT0iLiAkZmlsZSAuIjo6Ii4gJG1lc3NhZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgiOjplcnJvciA6OiIuICRtZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkYXRhCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVzY2FwZURhdGEoJGRhdGEpIHsKICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvdG9vbGtpdC9ibG9iLzRmN2ZiNjUxM2EzNTU2ODlmNjlmMDg0OWVkZWIzNjlhNGRjODE3MjkvcGFja2FnZXMvY29yZS9zcmMvY29tbWFuZC50cyNMODAtTDg1CiAgICAgICAgJGRhdGEgPSBzdHJfcmVwbGFjZSgiJSIsICclMjUnLCAkZGF0YSk7CiAgICAgICAgJGRhdGEgPSBzdHJfcmVwbGFjZSgiXHIiLCAnJTBEJywgJGRhdGEpOwogICAgICAgICRkYXRhID0gc3RyX3JlcGxhY2UoIlxuIiwgJyUwQScsICRkYXRhKTsKCiAgICAgICAgcmV0dXJuICRkYXRhOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByb3BlcnR5CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVzY2FwZVByb3BlcnR5KCRwcm9wZXJ0eSkgewogICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vYWN0aW9ucy90b29sa2l0L2Jsb2IvNGY3ZmI2NTEzYTM1NTY4OWY2OWYwODQ5ZWRlYjM2OWE0ZGM4MTcyOS9wYWNrYWdlcy9jb3JlL3NyYy9jb21tYW5kLnRzI0w4Ny1MOTQKICAgICAgICAkcHJvcGVydHkgPSBzdHJfcmVwbGFjZSgiJSIsICclMjUnLCAkcHJvcGVydHkpOwogICAgICAgICRwcm9wZXJ0eSA9IHN0cl9yZXBsYWNlKCJcciIsICclMEQnLCAkcHJvcGVydHkpOwogICAgICAgICRwcm9wZXJ0eSA9IHN0cl9yZXBsYWNlKCJcbiIsICclMEEnLCAkcHJvcGVydHkpOwogICAgICAgICRwcm9wZXJ0eSA9IHN0cl9yZXBsYWNlKCI6IiwgJyUzQScsICRwcm9wZXJ0eSk7CiAgICAgICAgJHByb3BlcnR5ID0gc3RyX3JlcGxhY2UoIiwiLCAnJTJDJywgJHByb3BlcnR5KTsKCiAgICAgICAgcmV0dXJuICRwcm9wZXJ0eTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXFNjcmlwdFxFdmVudCBhcyBTY3JpcHRFdmVudDsKdXNlIENvbXBvc2VyXFNjcmlwdFxTY3JpcHRFdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbi5wb3RlbmNpZXJAZ21haWwuY29tPgogKi8KY2xhc3MgUnVuU2NyaXB0Q29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmdbXSBBcnJheSB3aXRoIGNvbW1hbmQgZXZlbnRzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2NyaXB0RXZlbnRzID0gYXJyYXkoCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQUkVfSU5TVEFMTF9DTUQsCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQT1NUX0lOU1RBTExfQ01ELAogICAgICAgIFNjcmlwdEV2ZW50czo6UFJFX1VQREFURV9DTUQsCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQT1NUX1VQREFURV9DTUQsCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQUkVfU1RBVFVTX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfU1RBVFVTX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfUk9PVF9QQUNLQUdFX0lOU1RBTEwsCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQT1NUX0NSRUFURV9QUk9KRUNUX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBSRV9BUkNISVZFX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfQVJDSElWRV9DTUQsCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQUkVfQVVUT0xPQURfRFVNUCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfQVVUT0xPQURfRFVNUCwKICAgICk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdydW4tc2NyaXB0JykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdydW4nKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignUnVucyB0aGUgc2NyaXB0cyBkZWZpbmVkIGluIGNvbXBvc2VyLmpzb24uJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3NjcmlwdCcsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnU2NyaXB0IG5hbWUgdG8gcnVuLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2FyZ3MnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSB8IElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3RpbWVvdXQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdTZXRzIHNjcmlwdCB0aW1lb3V0IGluIHNlY29uZHMsIG9yIDAgZm9yIG5ldmVyLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NldHMgdGhlIGRldiBtb2RlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIHRoZSBkZXYgbW9kZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbGlzdCcsICdsJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IHNjcmlwdHMuJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+cnVuLXNjcmlwdDwvaW5mbz4gY29tbWFuZCBydW5zIHNjcmlwdHMgZGVmaW5lZCBpbiBjb21wb3Nlci5qc29uOgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgcnVuLXNjcmlwdCBwb3N0LXVwZGF0ZS1jbWQ8L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNydW4tc2NyaXB0CkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdsaXN0JykpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5saXN0U2NyaXB0cygkb3V0cHV0KTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkaW5wdXQtPmdldEFyZ3VtZW50KCdzY3JpcHQnKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgYXJndW1lbnQgInNjcmlwdCInKTsKICAgICAgICB9CgogICAgICAgICRzY3JpcHQgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdzY3JpcHQnKTsKICAgICAgICBpZiAoIWluX2FycmF5KCRzY3JpcHQsICR0aGlzLT5zY3JpcHRFdmVudHMpKSB7CiAgICAgICAgICAgIGlmIChkZWZpbmVkKCdDb21wb3NlclxTY3JpcHRcU2NyaXB0RXZlbnRzOjonLnN0cl9yZXBsYWNlKCctJywgJ18nLCBzdHJ0b3VwcGVyKCRzY3JpcHQpKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1NjcmlwdCAiJXMiIGNhbm5vdCBiZSBydW4gd2l0aCB0aGlzIGNvbW1hbmQnLCAkc2NyaXB0KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwogICAgICAgICRkZXZNb2RlID0gJGlucHV0LT5nZXRPcHRpb24oJ2RldicpIHx8ICEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2Jyk7CiAgICAgICAgJGV2ZW50ID0gbmV3IFNjcmlwdEV2ZW50KCRzY3JpcHQsICRjb21wb3NlciwgJHRoaXMtPmdldElPKCksICRkZXZNb2RlKTsKICAgICAgICAkaGFzTGlzdGVuZXJzID0gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+aGFzRXZlbnRMaXN0ZW5lcnMoJGV2ZW50KTsKICAgICAgICBpZiAoISRoYXNMaXN0ZW5lcnMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignU2NyaXB0ICIlcyIgaXMgbm90IGRlZmluZWQgaW4gdGhpcyBwYWNrYWdlJywgJHNjcmlwdCkpOwogICAgICAgIH0KCiAgICAgICAgJGFyZ3MgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdhcmdzJyk7CgogICAgICAgIGlmIChudWxsICE9PSAkdGltZW91dCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCd0aW1lb3V0JykpIHsKICAgICAgICAgICAgaWYgKCFjdHlwZV9kaWdpdCgkdGltZW91dCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGltZW91dCB2YWx1ZSBtdXN0IGJlIG51bWVyaWMgYW5kIHBvc2l0aXZlIGlmIGRlZmluZWQsIG9yIDAgZm9yIGZvcmV2ZXInKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBPdmVycmlkZSBnbG9iYWwgdGltZW91dCBzZXQgYmVmb3JlIGluIENvbXBvc2VyIGJ5IGVudmlyb25tZW50IG9yIGNvbmZpZwogICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OnNldFRpbWVvdXQoKGludCkgJHRpbWVvdXQpOwogICAgICAgIH0KCiAgICAgICAgUGxhdGZvcm06OnB1dEVudignQ09NUE9TRVJfREVWX01PREUnLCAkZGV2TW9kZSA/ICcxJyA6ICcwJyk7CgogICAgICAgIHJldHVybiAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaFNjcmlwdCgkc2NyaXB0LCAkZGV2TW9kZSwgJGFyZ3MpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxpc3RTY3JpcHRzKE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRzY3JpcHRzID0gJHRoaXMtPmdldENvbXBvc2VyKCktPmdldFBhY2thZ2UoKS0+Z2V0U2NyaXB0cygpOwoKICAgICAgICBpZiAoIWNvdW50KCRzY3JpcHRzKSkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+c2NyaXB0czo8L2luZm8+Jyk7CiAgICAgICAgJHRhYmxlID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkc2NyaXB0cyBhcyAkbmFtZSA9PiAkc2NyaXB0KSB7CiAgICAgICAgICAgICRkZXNjcmlwdGlvbiA9ICcnOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGNtZCA9ICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5maW5kKCRuYW1lKTsKICAgICAgICAgICAgICAgIGlmICgkY21kIGluc3RhbmNlb2YgU2NyaXB0QWxpYXNDb21tYW5kKSB7CiAgICAgICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJGNtZC0+Z2V0RGVzY3JpcHRpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gaWdub3JlIHNjcmlwdHMgdGhhdCBoYXZlIG5vIGNvbW1hbmQgYXNzb2NpYXRlZCwgbGlrZSBuYXRpdmUgQ29tcG9zZXIgc2NyaXB0IGxpc3RlbmVycwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0YWJsZVtdID0gYXJyYXkoJyAgJy4kbmFtZSwgJGRlc2NyaXB0aW9uKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yZW5kZXJUYWJsZSgkdGFibGUsICRvdXRwdXQpOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxJZ25vcmVBbGxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyOwp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25TZWxlY3RvcjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFV0aWxcU2lsZW5jZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XEFycmF5SW5wdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhlY3V0YWJsZUZpbmRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEZvcm1hdHRlckhlbHBlcjsKCi8qKgogKiBAYXV0aG9yIEp1c3RpbiBSYWluYm93IDxqdXN0aW4ucmFpbmJvd0BnbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEluaXRDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqIEB2YXIgP0NvbXBvc2l0ZVJlcG9zaXRvcnkgKi8KICAgIHByb3RlY3RlZCAkcmVwb3M7CgogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICovCiAgICBwcml2YXRlICRnaXRDb25maWc7CgogICAgLyoqIEB2YXIgUmVwb3NpdG9yeVNldFtdICovCiAgICBwcml2YXRlICRyZXBvc2l0b3J5U2V0czsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnaW5pdCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0NyZWF0ZXMgYSBiYXNpYyBjb21wb3Nlci5qc29uIGZpbGUgaW4gY3VycmVudCBkaXJlY3RvcnkuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduYW1lJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnTmFtZSBvZiB0aGUgcGFja2FnZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkZXNjcmlwdGlvbicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0Rlc2NyaXB0aW9uIG9mIHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXV0aG9yJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnQXV0aG9yIG5hbWUgb2YgcGFja2FnZScpLAogICAgICAgICAgICAgICAgLy8gbmV3IElucHV0T3B0aW9uKCd2ZXJzaW9uJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdWZXJzaW9uIG9mIHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndHlwZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9PUFRJT05BTCwgJ1R5cGUgb2YgcGFja2FnZSAoZS5nLiBsaWJyYXJ5LCBwcm9qZWN0LCBtZXRhcGFja2FnZSwgY29tcG9zZXItcGx1Z2luKScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdob21lcGFnZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0hvbWVwYWdlIG9mIHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVxdWlyZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSB8IElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1BhY2thZ2UgdG8gcmVxdWlyZSB3aXRoIGEgdmVyc2lvbiBjb25zdHJhaW50LCBlLmcuIGZvby9iYXI6MS4wLjAgb3IgZm9vL2Jhcj0xLjAuMCBvciAiZm9vL2JhciAxLjAuMCInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVxdWlyZS1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVkgfCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdQYWNrYWdlIHRvIHJlcXVpcmUgZm9yIGRldmVsb3BtZW50IHdpdGggYSB2ZXJzaW9uIGNvbnN0cmFpbnQsIGUuZy4gZm9vL2JhcjoxLjAuMCBvciBmb28vYmFyPTEuMC4wIG9yICJmb28vYmFyIDEuMC4wIicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzdGFiaWxpdHknLCAncycsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ01pbmltdW0gc3RhYmlsaXR5IChlbXB0eSBvciBvbmUgb2Y6ICcuaW1wbG9kZSgnLCAnLCBhcnJheV9rZXlzKEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMpKS4nKScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsaWNlbnNlJywgJ2wnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdMaWNlbnNlIG9mIHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVwb3NpdG9yeScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0FkZCBjdXN0b20gcmVwb3NpdG9yaWVzLCBlaXRoZXIgYnkgVVJMIG9yIHVzaW5nIEpTT04gYXJyYXlzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2F1dG9sb2FkJywgJ2EnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdBZGQgUFNSLTQgYXV0b2xvYWQgbWFwcGluZy4gTWFwcyB5b3VyIHBhY2thZ2VcJ3MgbmFtZXNwYWNlIHRvIHRoZSBwcm92aWRlZCBkaXJlY3RvcnkuIChFeHBlY3RzIGEgcmVsYXRpdmUgcGF0aCwgZS5nLiBzcmMvKScpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPmluaXQ8L2luZm8+IGNvbW1hbmQgY3JlYXRlcyBhIGJhc2ljIGNvbXBvc2VyLmpzb24gZmlsZQppbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBpbml0PC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjaW5pdApFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqIEB0aHJvd3MgXFNlbGRcSnNvbkxpbnRcUGFyc2luZ0V4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICAkYWxsb3dsaXN0ID0gYXJyYXkoJ25hbWUnLCAnZGVzY3JpcHRpb24nLCAnYXV0aG9yJywgJ3R5cGUnLCAnaG9tZXBhZ2UnLCAncmVxdWlyZScsICdyZXF1aXJlLWRldicsICdzdGFiaWxpdHknLCAnbGljZW5zZScsICdhdXRvbG9hZCcpOwogICAgICAgICRvcHRpb25zID0gYXJyYXlfZmlsdGVyKGFycmF5X2ludGVyc2VjdF9rZXkoJGlucHV0LT5nZXRPcHRpb25zKCksIGFycmF5X2ZsaXAoJGFsbG93bGlzdCkpKTsKCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWyduYW1lJ10pICYmICFQcmVnOjppc01hdGNoKCd7XlthLXowLTlfLi1dKy9bYS16MC05Xy4tXSskfUQnLCAkb3B0aW9uc1snbmFtZSddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICdUaGUgcGFja2FnZSBuYW1lICcuJG9wdGlvbnNbJ25hbWUnXS4nIGlzIGludmFsaWQsIGl0IHNob3VsZCBiZSBsb3dlcmNhc2UgYW5kIGhhdmUgYSB2ZW5kb3IgbmFtZSwgYSBmb3J3YXJkIHNsYXNoLCBhbmQgYSBwYWNrYWdlIG5hbWUsIG1hdGNoaW5nOiBbYS16MC05Xy4tXSsvW2EtejAtOV8uLV0rJwogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydhdXRob3InXSkpIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ2F1dGhvcnMnXSA9ICR0aGlzLT5mb3JtYXRBdXRob3JzKCRvcHRpb25zWydhdXRob3InXSk7CiAgICAgICAgICAgIHVuc2V0KCRvcHRpb25zWydhdXRob3InXSk7CiAgICAgICAgfQoKICAgICAgICAkcmVwb3NpdG9yaWVzID0gJGlucHV0LT5nZXRPcHRpb24oJ3JlcG9zaXRvcnknKTsKICAgICAgICBpZiAoJHJlcG9zaXRvcmllcykgewogICAgICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCRpbyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXBvc2l0b3JpZXMgYXMgJHJlcG8pIHsKICAgICAgICAgICAgICAgICRvcHRpb25zWydyZXBvc2l0b3JpZXMnXVtdID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmNvbmZpZ0Zyb21TdHJpbmcoJGlvLCAkY29uZmlnLCAkcmVwbywgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snc3RhYmlsaXR5J10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydtaW5pbXVtLXN0YWJpbGl0eSddID0gJG9wdGlvbnNbJ3N0YWJpbGl0eSddOwogICAgICAgICAgICB1bnNldCgkb3B0aW9uc1snc3RhYmlsaXR5J10pOwogICAgICAgIH0KCiAgICAgICAgJG9wdGlvbnNbJ3JlcXVpcmUnXSA9IGlzc2V0KCRvcHRpb25zWydyZXF1aXJlJ10pID8gJHRoaXMtPmZvcm1hdFJlcXVpcmVtZW50cygkb3B0aW9uc1sncmVxdWlyZSddKSA6IG5ldyBcc3RkQ2xhc3M7CiAgICAgICAgaWYgKGFycmF5KCkgPT09ICRvcHRpb25zWydyZXF1aXJlJ10pIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ3JlcXVpcmUnXSA9IG5ldyBcc3RkQ2xhc3M7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3JlcXVpcmUtZGV2J10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydyZXF1aXJlLWRldiddID0gJHRoaXMtPmZvcm1hdFJlcXVpcmVtZW50cygkb3B0aW9uc1sncmVxdWlyZS1kZXYnXSk7CiAgICAgICAgICAgIGlmIChhcnJheSgpID09PSAkb3B0aW9uc1sncmVxdWlyZS1kZXYnXSkgewogICAgICAgICAgICAgICAgJG9wdGlvbnNbJ3JlcXVpcmUtZGV2J10gPSBuZXcgXHN0ZENsYXNzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyAtLWF1dG9sb2FkIC0gY3JlYXRlIGF1dG9sb2FkIG9iamVjdAogICAgICAgICRhdXRvbG9hZFBhdGggPSBudWxsOwogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snYXV0b2xvYWQnXSkpIHsKICAgICAgICAgICAgJGF1dG9sb2FkUGF0aCA9ICRvcHRpb25zWydhdXRvbG9hZCddOwogICAgICAgICAgICAkbmFtZXNwYWNlID0gJHRoaXMtPm5hbWVzcGFjZUZyb21QYWNrYWdlTmFtZSgkaW5wdXQtPmdldE9wdGlvbignbmFtZScpKTsKICAgICAgICAgICAgJG9wdGlvbnNbJ2F1dG9sb2FkJ10gPSAob2JqZWN0KSBhcnJheSgKICAgICAgICAgICAgICAgICdwc3ItNCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJG5hbWVzcGFjZSAuICdcXCcgPT4gJGF1dG9sb2FkUGF0aCwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkZmlsZSA9IG5ldyBKc29uRmlsZShGYWN0b3J5OjpnZXRDb21wb3NlckZpbGUoKSk7CiAgICAgICAgJGpzb24gPSBKc29uRmlsZTo6ZW5jb2RlKCRvcHRpb25zKTsKCiAgICAgICAgaWYgKCRpbnB1dC0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihhcnJheSgnJywgJGpzb24sICcnKSk7CiAgICAgICAgICAgIGlmICghJGlvLT5hc2tDb25maXJtYXRpb24oJ0RvIHlvdSBjb25maXJtIGdlbmVyYXRpb24gWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Q29tbWFuZCBhYm9ydGVkPC9lcnJvcj4nKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChqc29uX2VuY29kZSgkb3B0aW9ucykgPT09ICd7InJlcXVpcmUiOnt9fScpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IGhhdmUgdG8gcnVuIHRoaXMgY29tbWFuZCBpbiBpbnRlcmFjdGl2ZSBtb2RlLCBvciBzcGVjaWZ5IGF0IGxlYXN0IHNvbWUgZGF0YSB1c2luZyAtLW5hbWUsIC0tcmVxdWlyZSwgZXRjLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1dyaXRpbmcgJy4kZmlsZS0+Z2V0UGF0aCgpKTsKICAgICAgICB9CgogICAgICAgICRmaWxlLT53cml0ZSgkb3B0aW9ucyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGZpbGUtPnZhbGlkYXRlU2NoZW1hKEpzb25GaWxlOjpMQVhfU0NIRU1BKTsKICAgICAgICB9IGNhdGNoIChKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5TY2hlbWEgdmFsaWRhdGlvbiBlcnJvciwgYWJvcnRpbmc8L2Vycm9yPicpOwogICAgICAgICAgICAkZXJyb3JzID0gJyAtICcgLiBpbXBsb2RlKFBIUF9FT0wgLiAnIC0gJywgJGUtPmdldEVycm9ycygpKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCRlLT5nZXRNZXNzYWdlKCkgLiAnOicgLiBQSFBfRU9MIC4gJGVycm9ycyk7CiAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCd1bmxpbmsnLCAkZmlsZS0+Z2V0UGF0aCgpKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgLy8gLS1hdXRvbG9hZCAtIENyZWF0ZSBzcmMgZm9sZGVyCiAgICAgICAgaWYgKCRhdXRvbG9hZFBhdGgpIHsKICAgICAgICAgICAgJGZpbGVzeXN0ZW0gPSBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRhdXRvbG9hZFBhdGgpOwoKICAgICAgICAgICAgLy8gZHVtcC1hdXRvbG9hZCBvbmx5IGZvciBwcm9qZWN0cyB3aXRob3V0IGFkZGVkIGRlcGVuZGVuY2llcy4KICAgICAgICAgICAgaWYgKCEkdGhpcy0+aGFzRGVwZW5kZW5jaWVzKCRvcHRpb25zKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJ1bkR1bXBBdXRvbG9hZENvbW1hbmQoJG91dHB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmlzSW50ZXJhY3RpdmUoKSAmJiBpc19kaXIoJy5naXQnKSkgewogICAgICAgICAgICAkaWdub3JlRmlsZSA9IHJlYWxwYXRoKCcuZ2l0aWdub3JlJyk7CgogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRpZ25vcmVGaWxlKSB7CiAgICAgICAgICAgICAgICAkaWdub3JlRmlsZSA9IHJlYWxwYXRoKCcuJykgLiAnLy5naXRpZ25vcmUnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISR0aGlzLT5oYXNWZW5kb3JJZ25vcmUoJGlnbm9yZUZpbGUpKSB7CiAgICAgICAgICAgICAgICAkcXVlc3Rpb24gPSAnV291bGQgeW91IGxpa2UgdGhlIDxpbmZvPnZlbmRvcjwvaW5mbz4gZGlyZWN0b3J5IGFkZGVkIHRvIHlvdXIgPGluZm8+LmdpdGlnbm9yZTwvaW5mbz4gWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnOwoKICAgICAgICAgICAgICAgIGlmICgkaW8tPmFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZFZlbmRvcklnbm9yZSgkaWdub3JlRmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRxdWVzdGlvbiA9ICdXb3VsZCB5b3UgbGlrZSB0byBpbnN0YWxsIGRlcGVuZGVuY2llcyBub3cgWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnOwogICAgICAgIGlmICgkaW5wdXQtPmlzSW50ZXJhY3RpdmUoKSAmJiAkdGhpcy0+aGFzRGVwZW5kZW5jaWVzKCRvcHRpb25zKSAmJiAkaW8tPmFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24pKSB7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVEZXBlbmRlbmNpZXMoJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAvLyAtLWF1dG9sb2FkIC0gU2hvdyBwb3N0LWluc3RhbGwgY29uZmlndXJhdGlvbiBpbmZvCiAgICAgICAgaWYgKCRhdXRvbG9hZFBhdGgpIHsKICAgICAgICAgICAgJG5hbWVzcGFjZSA9ICR0aGlzLT5uYW1lc3BhY2VGcm9tUGFja2FnZU5hbWUoJGlucHV0LT5nZXRPcHRpb24oJ25hbWUnKSk7CgogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1BTUi00IGF1dG9sb2FkaW5nIGNvbmZpZ3VyZWQuIFVzZSAiPGNvbW1lbnQ+bmFtZXNwYWNlICcuJG5hbWVzcGFjZS4nOzwvY29tbWVudD4iIGluICcuJGF1dG9sb2FkUGF0aCk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignSW5jbHVkZSB0aGUgQ29tcG9zZXIgYXV0b2xvYWRlciB3aXRoOiA8Y29tbWVudD5yZXF1aXJlIFwndmVuZG9yL2F1dG9sb2FkLnBocFwnOzwvY29tbWVudD4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGludGVyYWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGdpdCA9ICR0aGlzLT5nZXRHaXRDb25maWcoKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICAvKiogQHZhciBGb3JtYXR0ZXJIZWxwZXIgJGZvcm1hdHRlciAqLwogICAgICAgICRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0SGVscGVyU2V0KCktPmdldCgnZm9ybWF0dGVyJyk7CgogICAgICAgIC8vIGluaXRpYWxpemUgcmVwb3MgaWYgY29uZmlndXJlZAogICAgICAgICRyZXBvc2l0b3JpZXMgPSAkaW5wdXQtPmdldE9wdGlvbigncmVwb3NpdG9yeScpOwogICAgICAgIGlmICgkcmVwb3NpdG9yaWVzKSB7CiAgICAgICAgICAgICRjb25maWcgPSBGYWN0b3J5OjpjcmVhdGVDb25maWcoJGlvKTsKICAgICAgICAgICAgJHJlcG9zID0gYXJyYXkobmV3IFBsYXRmb3JtUmVwb3NpdG9yeSk7CiAgICAgICAgICAgICRjcmVhdGVEZWZhdWx0UGFja2FnaXN0UmVwbyA9IHRydWU7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXBvc2l0b3JpZXMgYXMgJHJlcG8pIHsKICAgICAgICAgICAgICAgICRyZXBvQ29uZmlnID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmNvbmZpZ0Zyb21TdHJpbmcoJGlvLCAkY29uZmlnLCAkcmVwbywgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKGlzc2V0KCRyZXBvQ29uZmlnWydwYWNrYWdpc3QnXSkgJiYgJHJlcG9Db25maWcgPT09IGFycmF5KCdwYWNrYWdpc3QnID0+IGZhbHNlKSkKICAgICAgICAgICAgICAgICAgICB8fCAoaXNzZXQoJHJlcG9Db25maWdbJ3BhY2thZ2lzdC5vcmcnXSkgJiYgJHJlcG9Db25maWcgPT09IGFycmF5KCdwYWNrYWdpc3Qub3JnJyA9PiBmYWxzZSkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkY3JlYXRlRGVmYXVsdFBhY2thZ2lzdFJlcG8gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXBvc1tdID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmNyZWF0ZVJlcG8oJGlvLCAkY29uZmlnLCAkcmVwb0NvbmZpZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY3JlYXRlRGVmYXVsdFBhY2thZ2lzdFJlcG8pIHsKICAgICAgICAgICAgICAgICRyZXBvc1tdID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmNyZWF0ZVJlcG8oJGlvLCAkY29uZmlnLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAndHlwZScgPT4gJ2NvbXBvc2VyJywKICAgICAgICAgICAgICAgICAgICAndXJsJyA9PiAnaHR0cHM6Ly9yZXBvLnBhY2thZ2lzdC5vcmcnLAogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5yZXBvcyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCRyZXBvcyk7CiAgICAgICAgICAgIHVuc2V0KCRyZXBvcywgJGNvbmZpZywgJHJlcG9zaXRvcmllcyk7CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoYXJyYXkoCiAgICAgICAgICAgICcnLAogICAgICAgICAgICAkZm9ybWF0dGVyLT5mb3JtYXRCbG9jaygnV2VsY29tZSB0byB0aGUgQ29tcG9zZXIgY29uZmlnIGdlbmVyYXRvcicsICdiZz1ibHVlO2ZnPXdoaXRlJywgdHJ1ZSksCiAgICAgICAgICAgICcnLAogICAgICAgICkpOwoKICAgICAgICAvLyBuYW1lc3BhY2UKICAgICAgICAkaW8tPndyaXRlRXJyb3IoYXJyYXkoCiAgICAgICAgICAgICcnLAogICAgICAgICAgICAnVGhpcyBjb21tYW5kIHdpbGwgZ3VpZGUgeW91IHRocm91Z2ggY3JlYXRpbmcgeW91ciBjb21wb3Nlci5qc29uIGNvbmZpZy4nLAogICAgICAgICAgICAnJywKICAgICAgICApKTsKCiAgICAgICAgJGN3ZCA9IHJlYWxwYXRoKCIuIik7CgogICAgICAgIGlmICghJG5hbWUgPSAkaW5wdXQtPmdldE9wdGlvbignbmFtZScpKSB7CiAgICAgICAgICAgICRuYW1lID0gYmFzZW5hbWUoJGN3ZCk7CiAgICAgICAgICAgICRuYW1lID0gUHJlZzo6cmVwbGFjZSgneyg/OihbYS16XSkoW0EtWl0pfChbQS1aXSkoW0EtWl1bYS16XSkpfScsICdcXDFcXDMtXFwyXFw0JywgJG5hbWUpOwogICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJG5hbWUpOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX1ZFTkRPUiddKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSAkX1NFUlZFUlsnQ09NUE9TRVJfREVGQVVMVF9WRU5ET1InXSAuICcvJyAuICRuYW1lOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGdpdFsnZ2l0aHViLnVzZXInXSkpIHsKICAgICAgICAgICAgICAgICRuYW1lID0gJGdpdFsnZ2l0aHViLnVzZXInXSAuICcvJyAuICRuYW1lOwogICAgICAgICAgICB9IGVsc2VpZiAoIWVtcHR5KCRfU0VSVkVSWydVU0VSTkFNRSddKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSAkX1NFUlZFUlsnVVNFUk5BTUUnXSAuICcvJyAuICRuYW1lOwogICAgICAgICAgICB9IGVsc2VpZiAoIWVtcHR5KCRfU0VSVkVSWydVU0VSJ10pKSB7CiAgICAgICAgICAgICAgICAkbmFtZSA9ICRfU0VSVkVSWydVU0VSJ10gLiAnLycgLiAkbmFtZTsKICAgICAgICAgICAgfSBlbHNlaWYgKGdldF9jdXJyZW50X3VzZXIoKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSBnZXRfY3VycmVudF91c2VyKCkgLiAnLycgLiAkbmFtZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHBhY2thZ2UgbmFtZXMgbXVzdCBiZSBpbiB0aGUgZm9ybWF0IGZvby9iYXIKICAgICAgICAgICAgICAgICRuYW1lIC49ICcvJyAuICRuYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAkbmFtZSA9ICRpby0+YXNrQW5kVmFsaWRhdGUoCiAgICAgICAgICAgICdQYWNrYWdlIG5hbWUgKDx2ZW5kb3I+LzxuYW1lPikgWzxjb21tZW50PicuJG5hbWUuJzwvY29tbWVudD5dOiAnLAogICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHVlKSB1c2UgKCRuYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRuYW1lOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgne15bYS16MC05Xy4tXSsvW2EtejAtOV8uLV0rJH1EJywgJHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAnVGhlIHBhY2thZ2UgbmFtZSAnLiR2YWx1ZS4nIGlzIGludmFsaWQsIGl0IHNob3VsZCBiZSBsb3dlcmNhc2UgYW5kIGhhdmUgYSB2ZW5kb3IgbmFtZSwgYSBmb3J3YXJkIHNsYXNoLCBhbmQgYSBwYWNrYWdlIG5hbWUsIG1hdGNoaW5nOiBbYS16MC05Xy4tXSsvW2EtejAtOV8uLV0rJwogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgJG5hbWUKICAgICAgICApOwogICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCduYW1lJywgJG5hbWUpOwoKICAgICAgICAkZGVzY3JpcHRpb24gPSAkaW5wdXQtPmdldE9wdGlvbignZGVzY3JpcHRpb24nKSA/OiBmYWxzZTsKICAgICAgICAkZGVzY3JpcHRpb24gPSAkaW8tPmFzaygKICAgICAgICAgICAgJ0Rlc2NyaXB0aW9uIFs8Y29tbWVudD4nLiRkZXNjcmlwdGlvbi4nPC9jb21tZW50Pl06ICcsCiAgICAgICAgICAgICRkZXNjcmlwdGlvbgogICAgICAgICk7CiAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ2Rlc2NyaXB0aW9uJywgJGRlc2NyaXB0aW9uKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRhdXRob3IgPSAkaW5wdXQtPmdldE9wdGlvbignYXV0aG9yJykpIHsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkX1NFUlZFUlsnQ09NUE9TRVJfREVGQVVMVF9BVVRIT1InXSkpIHsKICAgICAgICAgICAgICAgICRhdXRob3JfbmFtZSA9ICRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX0FVVEhPUiddOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGdpdFsndXNlci5uYW1lJ10pKSB7CiAgICAgICAgICAgICAgICAkYXV0aG9yX25hbWUgPSAkZ2l0Wyd1c2VyLm5hbWUnXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkX1NFUlZFUlsnQ09NUE9TRVJfREVGQVVMVF9FTUFJTCddKSkgewogICAgICAgICAgICAgICAgJGF1dGhvcl9lbWFpbCA9ICRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX0VNQUlMJ107CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkZ2l0Wyd1c2VyLmVtYWlsJ10pKSB7CiAgICAgICAgICAgICAgICAkYXV0aG9yX2VtYWlsID0gJGdpdFsndXNlci5lbWFpbCddOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJGF1dGhvcl9uYW1lLCAkYXV0aG9yX2VtYWlsKSkgewogICAgICAgICAgICAgICAgJGF1dGhvciA9IHNwcmludGYoJyVzIDwlcz4nLCAkYXV0aG9yX25hbWUsICRhdXRob3JfZW1haWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkc2VsZiA9ICR0aGlzOwogICAgICAgICRhdXRob3IgPSAkaW8tPmFza0FuZFZhbGlkYXRlKAogICAgICAgICAgICAnQXV0aG9yIFs8Y29tbWVudD4nLiRhdXRob3IuJzwvY29tbWVudD4sIG4gdG8gc2tpcF06ICcsCiAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJHNlbGYsICRhdXRob3IpIHsKICAgICAgICAgICAgICAgIGlmICgkdmFsdWUgPT09ICduJyB8fCAkdmFsdWUgPT09ICdubycpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdmFsdWUgPzogJGF1dGhvcjsKICAgICAgICAgICAgICAgICRhdXRob3IgPSAkc2VsZi0+cGFyc2VBdXRob3JTdHJpbmcoJHZhbHVlKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZignJXMgPCVzPicsICRhdXRob3JbJ25hbWUnXSwgJGF1dGhvclsnZW1haWwnXSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICRhdXRob3IKICAgICAgICApOwogICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdhdXRob3InLCAkYXV0aG9yKTsKCiAgICAgICAgJG1pbmltdW1TdGFiaWxpdHkgPSAkaW5wdXQtPmdldE9wdGlvbignc3RhYmlsaXR5JykgPzogbnVsbDsKICAgICAgICAkbWluaW11bVN0YWJpbGl0eSA9ICRpby0+YXNrQW5kVmFsaWRhdGUoCiAgICAgICAgICAgICdNaW5pbXVtIFN0YWJpbGl0eSBbPGNvbW1lbnQ+Jy4kbWluaW11bVN0YWJpbGl0eS4nPC9jb21tZW50Pl06ICcsCiAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJG1pbmltdW1TdGFiaWxpdHkpIHsKICAgICAgICAgICAgICAgIGlmIChudWxsID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJG1pbmltdW1TdGFiaWxpdHk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFpc3NldChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzWyR2YWx1ZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICdJbnZhbGlkIG1pbmltdW0gc3RhYmlsaXR5ICInLiR2YWx1ZS4nIi4gTXVzdCBiZSBlbXB0eSBvciBvbmUgb2Y6ICcuCiAgICAgICAgICAgICAgICAgICAgICAgIGltcGxvZGUoJywgJywgYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzKSkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICRtaW5pbXVtU3RhYmlsaXR5CiAgICAgICAgKTsKICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignc3RhYmlsaXR5JywgJG1pbmltdW1TdGFiaWxpdHkpOwoKICAgICAgICAkdHlwZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCd0eXBlJykgPzogZmFsc2U7CiAgICAgICAgJHR5cGUgPSAkaW8tPmFzaygKICAgICAgICAgICAgJ1BhY2thZ2UgVHlwZSAoZS5nLiBsaWJyYXJ5LCBwcm9qZWN0LCBtZXRhcGFja2FnZSwgY29tcG9zZXItcGx1Z2luKSBbPGNvbW1lbnQ+Jy4kdHlwZS4nPC9jb21tZW50Pl06ICcsCiAgICAgICAgICAgICR0eXBlCiAgICAgICAgKTsKICAgICAgICAkaW5wdXQtPnNldE9wdGlvbigndHlwZScsICR0eXBlKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRsaWNlbnNlID0gJGlucHV0LT5nZXRPcHRpb24oJ2xpY2Vuc2UnKSkgewogICAgICAgICAgICBpZiAoIWVtcHR5KCRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX0xJQ0VOU0UnXSkpIHsKICAgICAgICAgICAgICAgICRsaWNlbnNlID0gJF9TRVJWRVJbJ0NPTVBPU0VSX0RFRkFVTFRfTElDRU5TRSddOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkbGljZW5zZSA9ICRpby0+YXNrKAogICAgICAgICAgICAnTGljZW5zZSBbPGNvbW1lbnQ+Jy4kbGljZW5zZS4nPC9jb21tZW50Pl06ICcsCiAgICAgICAgICAgICRsaWNlbnNlCiAgICAgICAgKTsKICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignbGljZW5zZScsICRsaWNlbnNlKTsKCiAgICAgICAgJGlvLT53cml0ZUVycm9yKGFycmF5KCcnLCAnRGVmaW5lIHlvdXIgZGVwZW5kZW5jaWVzLicsICcnKSk7CgogICAgICAgIC8vIHByZXBhcmUgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMKICAgICAgICAkcmVwb3MgPSAkdGhpcy0+Z2V0UmVwb3MoKTsKICAgICAgICAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJG1pbmltdW1TdGFiaWxpdHkgPzogJ3N0YWJsZSc7CiAgICAgICAgJHBsYXRmb3JtUmVwbyA9IG51bGw7CiAgICAgICAgaWYgKCRyZXBvcyBpbnN0YW5jZW9mIENvbXBvc2l0ZVJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG9zLT5nZXRSZXBvc2l0b3JpZXMoKSBhcyAkY2FuZGlkYXRlUmVwbykgewogICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGVSZXBvIGluc3RhbmNlb2YgUGxhdGZvcm1SZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICAgICAgJHBsYXRmb3JtUmVwbyA9ICRjYW5kaWRhdGVSZXBvOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcXVlc3Rpb24gPSAnV291bGQgeW91IGxpa2UgdG8gZGVmaW5lIHlvdXIgZGVwZW5kZW5jaWVzIChyZXF1aXJlKSBpbnRlcmFjdGl2ZWx5IFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJzsKICAgICAgICAkcmVxdWlyZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdyZXF1aXJlJyk7CiAgICAgICAgJHJlcXVpcmVtZW50cyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRyZXF1aXJlIHx8ICRpby0+YXNrQ29uZmlybWF0aW9uKCRxdWVzdGlvbikpIHsKICAgICAgICAgICAgJHJlcXVpcmVtZW50cyA9ICR0aGlzLT5kZXRlcm1pbmVSZXF1aXJlbWVudHMoJGlucHV0LCAkb3V0cHV0LCAkcmVxdWlyZSwgJHBsYXRmb3JtUmVwbywgJHByZWZlcnJlZFN0YWJpbGl0eSk7CiAgICAgICAgfQogICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdyZXF1aXJlJywgJHJlcXVpcmVtZW50cyk7CgogICAgICAgICRxdWVzdGlvbiA9ICdXb3VsZCB5b3UgbGlrZSB0byBkZWZpbmUgeW91ciBkZXYgZGVwZW5kZW5jaWVzIChyZXF1aXJlLWRldikgaW50ZXJhY3RpdmVseSBbPGNvbW1lbnQ+eWVzPC9jb21tZW50Pl0/ICc7CiAgICAgICAgJHJlcXVpcmVEZXYgPSAkaW5wdXQtPmdldE9wdGlvbigncmVxdWlyZS1kZXYnKTsKICAgICAgICAkZGV2UmVxdWlyZW1lbnRzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJHJlcXVpcmVEZXYgfHwgJGlvLT5hc2tDb25maXJtYXRpb24oJHF1ZXN0aW9uKSkgewogICAgICAgICAgICAkZGV2UmVxdWlyZW1lbnRzID0gJHRoaXMtPmRldGVybWluZVJlcXVpcmVtZW50cygkaW5wdXQsICRvdXRwdXQsICRyZXF1aXJlRGV2LCAkcGxhdGZvcm1SZXBvLCAkcHJlZmVycmVkU3RhYmlsaXR5KTsKICAgICAgICB9CiAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ3JlcXVpcmUtZGV2JywgJGRldlJlcXVpcmVtZW50cyk7CgogICAgICAgIC8vIC0tYXV0b2xvYWQgLSBpbnB1dCBhbmQgdmFsaWRhdGlvbgogICAgICAgICRhdXRvbG9hZCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdhdXRvbG9hZCcpID86ICdzcmMvJzsKICAgICAgICAkbmFtZXNwYWNlID0gJHRoaXMtPm5hbWVzcGFjZUZyb21QYWNrYWdlTmFtZSgkaW5wdXQtPmdldE9wdGlvbignbmFtZScpKTsKICAgICAgICAkYXV0b2xvYWQgPSAkaW8tPmFza0FuZFZhbGlkYXRlKAogICAgICAgICAgICAnQWRkIFBTUi00IGF1dG9sb2FkIG1hcHBpbmc/IE1hcHMgbmFtZXNwYWNlICInLiRuYW1lc3BhY2UuJyIgdG8gdGhlIGVudGVyZWQgcmVsYXRpdmUgcGF0aC4gWzxjb21tZW50PicuJGF1dG9sb2FkLic8L2NvbW1lbnQ+LCBuIHRvIHNraXBdOiAnLAogICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHVlKSB1c2UgKCRhdXRvbG9hZCkgewogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkYXV0b2xvYWQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR2YWx1ZSA9PT0gJ24nIHx8ICR2YWx1ZSA9PT0gJ25vJykgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdmFsdWUgPzogJGF1dG9sb2FkOwoKICAgICAgICAgICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgne15bXi9dW0EtWmEtejAtOVwtXy9dKy8kfScsICR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAnVGhlIHNyYyBmb2xkZXIgbmFtZSAiJXMiIGlzIGludmFsaWQuIFBsZWFzZSBhZGQgYSByZWxhdGl2ZSBwYXRoIHdpdGggdGFpbGluZyBmb3J3YXJkIHNsYXNoLiBbQS1aYS16MC05Xy0vXSsvJywKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlCiAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgJGF1dG9sb2FkCiAgICAgICAgKTsKICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignYXV0b2xvYWQnLCAkYXV0b2xvYWQpOwogICAgfQoKICAgIC8qKgogICAgICogQHByaXZhdGUKICAgICAqIEBwYXJhbSAgc3RyaW5nICRhdXRob3IKICAgICAqIEByZXR1cm4gYXJyYXl7bmFtZTogc3RyaW5nLCBlbWFpbDogc3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VBdXRob3JTdHJpbmcoJGF1dGhvcikKICAgIHsKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL14oP1A8bmFtZT5bLSAuLFxwe0x9XHB7Tn1ccHtNbn1cJ+KAmSIoKV0rKSA8KD9QPGVtYWlsPi4rPyk+JC91JywgJGF1dGhvciwgJG1hdGNoKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmlzVmFsaWRFbWFpbCgkbWF0Y2hbJ2VtYWlsJ10pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+IHRyaW0oJG1hdGNoWyduYW1lJ10pLAogICAgICAgICAgICAgICAgICAgICdlbWFpbCcgPT4gJG1hdGNoWydlbWFpbCddLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICdJbnZhbGlkIGF1dGhvciBzdHJpbmcuICBNdXN0IGJlIGluIHRoZSBmb3JtYXQ6ICcuCiAgICAgICAgICAgICdKb2huIFNtaXRoIDxqb2huQGV4YW1wbGUuY29tPicKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb21wb3NpdGVSZXBvc2l0b3J5CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRSZXBvcygpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+cmVwb3MpIHsKICAgICAgICAgICAgJHRoaXMtPnJlcG9zID0gbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICBhcnJheShuZXcgUGxhdGZvcm1SZXBvc2l0b3J5KSwKICAgICAgICAgICAgICAgIFJlcG9zaXRvcnlGYWN0b3J5OjpkZWZhdWx0UmVwb3MoJHRoaXMtPmdldElPKCkpCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRyZXF1aXJlcwogICAgICogQHBhcmFtIFBsYXRmb3JtUmVwb3NpdG9yeXxudWxsICRwbGF0Zm9ybVJlcG8KICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZWZlcnJlZFN0YWJpbGl0eQogICAgICogQHBhcmFtIGJvb2wgJGNoZWNrUHJvdmlkZWRWZXJzaW9ucwogICAgICogQHBhcmFtIGJvb2wgJGZpeGVkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmc+CiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgZmluYWwgcHJvdGVjdGVkIGZ1bmN0aW9uIGRldGVybWluZVJlcXVpcmVtZW50cyhJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkcmVxdWlyZXMgPSBhcnJheSgpLCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbyA9IG51bGwsICRwcmVmZXJyZWRTdGFiaWxpdHkgPSAnc3RhYmxlJywgJGNoZWNrUHJvdmlkZWRWZXJzaW9ucyA9IHRydWUsICRmaXhlZCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkcmVxdWlyZXMpIHsKICAgICAgICAgICAgJHJlcXVpcmVzID0gJHRoaXMtPm5vcm1hbGl6ZVJlcXVpcmVtZW50cygkcmVxdWlyZXMpOwogICAgICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmVtZW50KSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRyZXF1aXJlbWVudFsndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgICAgIC8vIGRldGVybWluZSB0aGUgYmVzdCB2ZXJzaW9uIGF1dG9tYXRpY2FsbHkKICAgICAgICAgICAgICAgICAgICBsaXN0KCRuYW1lLCAkdmVyc2lvbikgPSAkdGhpcy0+ZmluZEJlc3RWZXJzaW9uQW5kTmFtZUZvclBhY2thZ2UoJGlucHV0LCAkcmVxdWlyZW1lbnRbJ25hbWUnXSwgJHBsYXRmb3JtUmVwbywgJHByZWZlcnJlZFN0YWJpbGl0eSwgbnVsbCwgbnVsbCwgJGZpeGVkKTsKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXSA9ICR2ZXJzaW9uOwoKICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHBhY2thZ2UgbmFtZSBmcm9tIHBhY2thZ2lzdC5vcmcKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZW1lbnRbJ25hbWUnXSA9ICRuYW1lOwoKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJ1VzaW5nIHZlcnNpb24gPGluZm8+JXM8L2luZm8+IGZvciA8aW5mbz4lczwvaW5mbz4nLAogICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXSwKICAgICAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVtZW50WyduYW1lJ10KICAgICAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB0aGUgc3BlY2lmaWVkIHZlcnNpb24vY29uc3RyYWludCBleGlzdHMgYmVmb3JlIHdlIHByb2NlZWQKICAgICAgICAgICAgICAgICAgICBsaXN0KCRuYW1lKSA9ICR0aGlzLT5maW5kQmVzdFZlcnNpb25BbmROYW1lRm9yUGFja2FnZSgkaW5wdXQsICRyZXF1aXJlbWVudFsnbmFtZSddLCAkcGxhdGZvcm1SZXBvLCAkcHJlZmVycmVkU3RhYmlsaXR5LCAkY2hlY2tQcm92aWRlZFZlcnNpb25zID8gJHJlcXVpcmVtZW50Wyd2ZXJzaW9uJ10gOiBudWxsLCAnZGV2JywgJGZpeGVkKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gcmVwbGFjZSBwYWNrYWdlIG5hbWUgZnJvbSBwYWNrYWdpc3Qub3JnCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVtZW50WyduYW1lJ10gPSAkbmFtZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkcmVxdWlyZW1lbnRbJ25hbWUnXSAuICcgJyAuICRyZXF1aXJlbWVudFsndmVyc2lvbiddOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKCiAgICAgICAgLy8gQ29sbGVjdCBleGlzdGluZyBwYWNrYWdlcwogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSk7CiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSAkY29tcG9zZXIgPyAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpIDogbnVsbDsKICAgICAgICAkZXhpc3RpbmdQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRpbnN0YWxsZWRSZXBvKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsZWRSZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkZXhpc3RpbmdQYWNrYWdlc1tdID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1bnNldCgkY29tcG9zZXIsICRpbnN0YWxsZWRSZXBvKTsKCiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgd2hpbGUgKG51bGwgIT09ICRwYWNrYWdlID0gJGlvLT5hc2soJ1NlYXJjaCBmb3IgYSBwYWNrYWdlOiAnKSkgewogICAgICAgICAgICAkbWF0Y2hlcyA9ICR0aGlzLT5nZXRSZXBvcygpLT5zZWFyY2goJHBhY2thZ2UpOwoKICAgICAgICAgICAgaWYgKGNvdW50KCRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIHBhY2thZ2VzIGZyb20gc2VhcmNoIHJlc3VsdHMuCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkcG9zaXRpb24gPT4gJGZvdW5kUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkZm91bmRQYWNrYWdlWyduYW1lJ10sICRleGlzdGluZ1BhY2thZ2VzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkbWF0Y2hlc1skcG9zaXRpb25dKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbWF0Y2hlcyA9IGFycmF5X3ZhbHVlcygkbWF0Y2hlcyk7CgogICAgICAgICAgICAgICAgJGV4YWN0TWF0Y2ggPSBudWxsOwogICAgICAgICAgICAgICAgJGNob2ljZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXMgYXMgJHBvc2l0aW9uID0+ICRmb3VuZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkYWJhbmRvbmVkID0gJyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRmb3VuZFBhY2thZ2VbJ2FiYW5kb25lZCddKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRmb3VuZFBhY2thZ2VbJ2FiYW5kb25lZCddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VtZW50ID0gc3ByaW50ZignVXNlICVzIGluc3RlYWQnLCAkZm91bmRQYWNrYWdlWydhYmFuZG9uZWQnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnQgPSAnTm8gcmVwbGFjZW1lbnQgd2FzIHN1Z2dlc3RlZCc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGFiYW5kb25lZCA9IHNwcmludGYoJzx3YXJuaW5nPkFiYW5kb25lZC4gJXMuPC93YXJuaW5nPicsICRyZXBsYWNlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkY2hvaWNlc1tdID0gc3ByaW50ZignIDxpbmZvPiU1czwvaW5mbz4gJXMgJXMnLCAiWyRwb3NpdGlvbl0iLCAkZm91bmRQYWNrYWdlWyduYW1lJ10sICRhYmFuZG9uZWQpOwogICAgICAgICAgICAgICAgICAgIGlmICgkZm91bmRQYWNrYWdlWyduYW1lJ10gPT09ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRleGFjdE1hdGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIG5vIG1hdGNoLCBwcm9tcHQgd2hpY2ggdG8gcGljawogICAgICAgICAgICAgICAgaWYgKCEkZXhhY3RNYXRjaCkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJycsCiAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoJ0ZvdW5kIDxpbmZvPiVzPC9pbmZvPiBwYWNrYWdlcyBtYXRjaGluZyA8aW5mbz4lczwvaW5mbz4nLCBjb3VudCgkbWF0Y2hlcyksICRwYWNrYWdlKSwKICAgICAgICAgICAgICAgICAgICAgICAgJycsCiAgICAgICAgICAgICAgICAgICAgKSk7CgogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigkY2hvaWNlcyk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcnKTsKCiAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRvciA9IGZ1bmN0aW9uICgkc2VsZWN0aW9uKSB1c2UgKCRtYXRjaGVzLCAkdmVyc2lvblBhcnNlcikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJycgPT09ICRzZWxlY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX251bWVyaWMoJHNlbGVjdGlvbikgJiYgaXNzZXQoJG1hdGNoZXNbKGludCkgJHNlbGVjdGlvbl0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRtYXRjaGVzWyhpbnQpICRzZWxlY3Rpb25dOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZVsnbmFtZSddOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15ccyooP1A8bmFtZT5bXFMvXSspKD86XHMrKD9QPHZlcnNpb24+XFMrKSk/XHMqJH0nLCAkc2VsZWN0aW9uLCAkcGFja2FnZU1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VNYXRjaGVzWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2luZyBgYWNtZS9leGFtcGxlIH4yLjNgCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbGlkYXRlIHZlcnNpb24gY29uc3RyYWludAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRwYWNrYWdlTWF0Y2hlc1sndmVyc2lvbiddKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlTWF0Y2hlc1snbmFtZSddLicgJy4kcGFja2FnZU1hdGNoZXNbJ3ZlcnNpb24nXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXJzaW5nIGBhY21lL2V4YW1wbGVgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2VNYXRjaGVzWyduYW1lJ107CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCdOb3QgYSB2YWxpZCBzZWxlY3Rpb24nKTsKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRpby0+YXNrQW5kVmFsaWRhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICdFbnRlciBwYWNrYWdlICMgdG8gYWRkLCBvciB0aGUgY29tcGxldGUgcGFja2FnZSBuYW1lIGlmIGl0IGlzIG5vdCBsaXN0ZWQ6ICcsCiAgICAgICAgICAgICAgICAgICAgICAgICR2YWxpZGF0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgIDMsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBubyBjb25zdHJhaW50IHlldCwgZGV0ZXJtaW5lIHRoZSBiZXN0IHZlcnNpb24gYXV0b21hdGljYWxseQogICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkcGFja2FnZSAmJiBmYWxzZSA9PT0gc3RycG9zKCRwYWNrYWdlLCAnICcpKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRvciA9IGZ1bmN0aW9uICgkaW5wdXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlucHV0ID0gdHJpbSgkaW5wdXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRpbnB1dCA/OiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICRpby0+YXNrQW5kVmFsaWRhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICdFbnRlciB0aGUgdmVyc2lvbiBjb25zdHJhaW50IHRvIHJlcXVpcmUgKG9yIGxlYXZlIGJsYW5rIHRvIHVzZSB0aGUgbGF0ZXN0IHZlcnNpb24pOiAnLAogICAgICAgICAgICAgICAgICAgICAgICAkdmFsaWRhdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAzLAogICAgICAgICAgICAgICAgICAgICAgICBmYWxzZQogICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgsICRjb25zdHJhaW50KSA9ICR0aGlzLT5maW5kQmVzdFZlcnNpb25BbmROYW1lRm9yUGFja2FnZSgkaW5wdXQsICRwYWNrYWdlLCAkcGxhdGZvcm1SZXBvLCAkcHJlZmVycmVkU3RhYmlsaXR5KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1VzaW5nIHZlcnNpb24gPGluZm8+JXM8L2luZm8+IGZvciA8aW5mbz4lczwvaW5mbz4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZQogICAgICAgICAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlIC49ICcgJy4kY29uc3RyYWludDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVzW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgICAgICAkZXhpc3RpbmdQYWNrYWdlc1tdID0gc3Vic3RyKCRwYWNrYWdlLCAwLCBzdHJwb3MoJHBhY2thZ2UsICcgJykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlcXVpcmVzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkYXV0aG9yCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxpbnQsIGFycmF5e25hbWU6IHN0cmluZywgZW1haWw6IHN0cmluZ30+CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmb3JtYXRBdXRob3JzKCRhdXRob3IpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KCR0aGlzLT5wYXJzZUF1dGhvclN0cmluZygkYXV0aG9yKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0IG5hbWVzcGFjZSBmcm9tIHBhY2thZ2UncyB2ZW5kb3IgbmFtZS4KICAgICAqCiAgICAgKiBuZXdfcHJvamVjdHMuYWNtZS1leHRyYS9wYWNrYWdlLW5hbWUgYmVjb21lcyAiTmV3UHJvamVjdHNBY21lRXh0cmFcUGFja2FnZU5hbWUiCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGFja2FnZU5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBuYW1lc3BhY2VGcm9tUGFja2FnZU5hbWUoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGlmICghJHBhY2thZ2VOYW1lIHx8IHN0cnBvcygkcGFja2FnZU5hbWUsICcvJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJG5hbWVzcGFjZSA9IGFycmF5X21hcCgKICAgICAgICAgICAgZnVuY3Rpb24gKCRwYXJ0KSB7CiAgICAgICAgICAgICAgICAkcGFydCA9IFByZWc6OnJlcGxhY2UoJy9bXmEtejAtOV0vaScsICcgJywgJHBhcnQpOwogICAgICAgICAgICAgICAgJHBhcnQgPSB1Y3dvcmRzKCRwYXJ0KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJyAnLCAnJywgJHBhcnQpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBleHBsb2RlKCcvJywgJHBhY2thZ2VOYW1lKQogICAgICAgICk7CgogICAgICAgIHJldHVybiBqb2luKCdcXCcsICRuYW1lc3BhY2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEdpdENvbmZpZygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5naXRDb25maWcpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXRDb25maWc7CiAgICAgICAgfQoKICAgICAgICAkZmluZGVyID0gbmV3IEV4ZWN1dGFibGVGaW5kZXIoKTsKICAgICAgICAkZ2l0QmluID0gJGZpbmRlci0+ZmluZCgnZ2l0Jyk7CgogICAgICAgIC8vIFRPRE8gaW4gdjIuMyBhbHdheXMgY2FsbCB3aXRoIGFuIGFycmF5CiAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJ1N5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzcycsICdmcm9tU2hlbGxDb21tYW5kbGluZScpKSB7CiAgICAgICAgICAgICRjbWQgPSBuZXcgUHJvY2VzcyhhcnJheSgkZ2l0QmluLCAnY29uZmlnJywgJy1sJykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUKICAgICAgICAgICAgJGNtZCA9IG5ldyBQcm9jZXNzKHNwcmludGYoJyVzIGNvbmZpZyAtbCcsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRnaXRCaW4pKSk7CiAgICAgICAgfQogICAgICAgICRjbWQtPnJ1bigpOwoKICAgICAgICBpZiAoJGNtZC0+aXNTdWNjZXNzZnVsKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmdpdENvbmZpZyA9IGFycmF5KCk7CiAgICAgICAgICAgIFByZWc6Om1hdGNoQWxsKCd7XihbXj1dKyk9KC4qKSR9bScsICRjbWQtPmdldE91dHB1dCgpLCAkbWF0Y2hlcyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzWzFdIGFzICRrZXkgPT4gJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Z2l0Q29uZmlnWyRtYXRjaF0gPSAkbWF0Y2hlc1syXVska2V5XTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXRDb25maWc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmdpdENvbmZpZyA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgdGhlIGxvY2FsIC5naXRpZ25vcmUgZmlsZSBmb3IgdGhlIENvbXBvc2VyIHZlbmRvciBkaXJlY3RvcnkuCiAgICAgKgogICAgICogVGVzdGVkIHBhdHRlcm5zIGluY2x1ZGU6CiAgICAgKiAgIi8kdmVuZG9yIgogICAgICogICIkdmVuZG9yIgogICAgICogICIkdmVuZG9yLyIKICAgICAqICAiLyR2ZW5kb3IvIgogICAgICogICIvJHZlbmRvci8qIgogICAgICogICIkdmVuZG9yLyoiCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWdub3JlRmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNWZW5kb3JJZ25vcmUoJGlnbm9yZUZpbGUsICR2ZW5kb3IgPSAndmVuZG9yJykKICAgIHsKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRpZ25vcmVGaWxlKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcGF0dGVybiA9IHNwcmludGYoJ3teLz8lcygvXCo/KT8kfScsIHByZWdfcXVvdGUoJHZlbmRvcikpOwoKICAgICAgICAkbGluZXMgPSBmaWxlKCRpZ25vcmVGaWxlLCBGSUxFX0lHTk9SRV9ORVdfTElORVMpOwogICAgICAgIGZvcmVhY2ggKCRsaW5lcyBhcyAkbGluZSkgewogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgkcGF0dGVybiwgJGxpbmUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkaWdub3JlRmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRWZW5kb3JJZ25vcmUoJGlnbm9yZUZpbGUsICR2ZW5kb3IgPSAnL3ZlbmRvci8nKQogICAgewogICAgICAgICRjb250ZW50cyA9ICIiOwogICAgICAgIGlmIChmaWxlX2V4aXN0cygkaWdub3JlRmlsZSkpIHsKICAgICAgICAgICAgJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoJGlnbm9yZUZpbGUpOwoKICAgICAgICAgICAgaWYgKHN0cnBvcygkY29udGVudHMsICJcbiIpICE9PSAwKSB7CiAgICAgICAgICAgICAgICAkY29udGVudHMgLj0gIlxuIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGlnbm9yZUZpbGUsICRjb250ZW50cyAuICR2ZW5kb3IuICJcbiIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZW1haWwKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzVmFsaWRFbWFpbCgkZW1haWwpCiAgICB7CiAgICAgICAgLy8gYXNzdW1lIGl0J3MgdmFsaWQgaWYgd2UgY2FuJ3QgdmFsaWRhdGUgaXQKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygnZmlsdGVyX3ZhcicpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gcGhwIDw1LjMuMyBoYXMgYSB2ZXJ5IGJyb2tlbiBlbWFpbCB2YWxpZGF0b3IsIHNvIGJ5cGFzcyBjaGVja3MKICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDMwMykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZSAhPT0gZmlsdGVyX3ZhcigkZW1haWwsIEZJTFRFUl9WQUxJREFURV9FTUFJTCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJG1pbmltdW1TdGFiaWxpdHkKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlTZXQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRSZXBvc2l0b3J5U2V0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgJG1pbmltdW1TdGFiaWxpdHkgPSBudWxsKQogICAgewogICAgICAgICRrZXkgPSAkbWluaW11bVN0YWJpbGl0eSA/OiAnZGVmYXVsdCc7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlcG9zaXRvcnlTZXRzWyRrZXldKSkgewogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeVNldHNbJGtleV0gPSAkcmVwb3NpdG9yeVNldCA9IG5ldyBSZXBvc2l0b3J5U2V0KCRtaW5pbXVtU3RhYmlsaXR5ID86ICR0aGlzLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCRpbnB1dCkpOwogICAgICAgICAgICAkcmVwb3NpdG9yeVNldC0+YWRkUmVwb3NpdG9yeSgkdGhpcy0+Z2V0UmVwb3MoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcnlTZXRzWyRrZXldOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRNaW5pbXVtU3RhYmlsaXR5KElucHV0SW50ZXJmYWNlICRpbnB1dCkKICAgIHsKICAgICAgICBpZiAoJGlucHV0LT5oYXNPcHRpb24oJ3N0YWJpbGl0eScpKSB7CiAgICAgICAgICAgIHJldHVybiBWZXJzaW9uUGFyc2VyOjpub3JtYWxpemVTdGFiaWxpdHkoJGlucHV0LT5nZXRPcHRpb24oJ3N0YWJpbGl0eScpID86ICdzdGFibGUnKTsKICAgICAgICB9CgogICAgICAgICRmaWxlID0gRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCk7CiAgICAgICAgaWYgKGlzX2ZpbGUoJGZpbGUpICYmIEZpbGVzeXN0ZW06OmlzUmVhZGFibGUoJGZpbGUpICYmIGlzX2FycmF5KCRjb21wb3NlciA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlKSwgdHJ1ZSkpKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbXBvc2VyWydtaW5pbXVtLXN0YWJpbGl0eSddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkY29tcG9zZXJbJ21pbmltdW0tc3RhYmlsaXR5J10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ3N0YWJsZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBhIHBhY2thZ2UgbmFtZSwgdGhpcyBkZXRlcm1pbmVzIHRoZSBiZXN0IHZlcnNpb24gdG8gdXNlIGluIHRoZSByZXF1aXJlIGtleS4KICAgICAqCiAgICAgKiBUaGlzIHJldHVybnMgYSB2ZXJzaW9uIHdpdGggdGhlIH4gb3BlcmF0b3IgcHJlZml4ZWQgd2hlbiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJG5hbWUKICAgICAqIEBwYXJhbSAgUGxhdGZvcm1SZXBvc2l0b3J5fG51bGwgICAkcGxhdGZvcm1SZXBvCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJHByZWZlcnJlZFN0YWJpbGl0eQogICAgICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICAgICAgICAgICAgICRyZXF1aXJlZFZlcnNpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkbWluaW11bVN0YWJpbGl0eQogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICRmaXhlZAogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGFycmF5e3N0cmluZywgc3RyaW5nfSAgICAgbmFtZSB2ZXJzaW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZEJlc3RWZXJzaW9uQW5kTmFtZUZvclBhY2thZ2UoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCAkbmFtZSwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8gPSBudWxsLCAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJ3N0YWJsZScsICRyZXF1aXJlZFZlcnNpb24gPSBudWxsLCAkbWluaW11bVN0YWJpbGl0eSA9IG51bGwsICRmaXhlZCA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gaGFuZGxlIGlnbm9yZS1wbGF0Zm9ybS1yZXFzIGZsYWcgaWYgcHJlc2VudAogICAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSBmYWxzZTsKICAgICAgICBpZiAoJGlucHV0LT5oYXNPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgJiYgJGlucHV0LT5oYXNPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnKSkgewogICAgICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwogICAgICAgIH0KICAgICAgICAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciA9IFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5Ojpmcm9tQm9vbE9yTGlzdCgkaWdub3JlUGxhdGZvcm1SZXFzKTsKCiAgICAgICAgLy8gZmluZCB0aGUgbGF0ZXN0IHZlcnNpb24gYWxsb3dlZCBpbiB0aGlzIHJlcG8gc2V0CiAgICAgICAgJHZlcnNpb25TZWxlY3RvciA9IG5ldyBWZXJzaW9uU2VsZWN0b3IoJHRoaXMtPmdldFJlcG9zaXRvcnlTZXQoJGlucHV0LCAkbWluaW11bVN0YWJpbGl0eSksICRwbGF0Zm9ybVJlcG8pOwogICAgICAgICRlZmZlY3RpdmVNaW5pbXVtU3RhYmlsaXR5ID0gJG1pbmltdW1TdGFiaWxpdHkgPzogJHRoaXMtPmdldE1pbmltdW1TdGFiaWxpdHkoJGlucHV0KTsKCiAgICAgICAgJHBhY2thZ2UgPSAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgJHJlcXVpcmVkVmVyc2lvbiwgJHByZWZlcnJlZFN0YWJpbGl0eSwgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwoKICAgICAgICBpZiAoISRwYWNrYWdlKSB7CiAgICAgICAgICAgIC8vIHBsYXRmb3JtIHBhY2thZ2VzIGNhbiBub3QgYmUgZm91bmQgaW4gdGhlIHBvb2wgaW4gdmVyc2lvbnMgb3RoZXIgdGhhbiB0aGUgbG9jYWwgcGxhdGZvcm0ncyBoYXMKICAgICAgICAgICAgLy8gc28gaWYgcGxhdGZvcm0gcmVxcyBhcmUgaWdub3JlZCB3ZSBqdXN0IHRha2UgdGhlIHVzZXIncyB3b3JkIGZvciBpdAogICAgICAgICAgICBpZiAoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmlzSWdub3JlZCgkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgJHJlcXVpcmVkVmVyc2lvbiA/OiAnKicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBwYWNrYWdlIHJlcXVpcmVtZW50cyB3ZXJlIHRoZSBwcm9ibGVtCiAgICAgICAgICAgIGlmICghKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RhbmNlb2YgSWdub3JlQWxsUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcikgJiYgKCRjYW5kaWRhdGUgPSAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgJHJlcXVpcmVkVmVyc2lvbiwgJHByZWZlcnJlZFN0YWJpbGl0eSwgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6Omlnbm9yZUFsbCgpKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ1BhY2thZ2UgJXMlcyBoYXMgcmVxdWlyZW1lbnRzIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUEhQIHZlcnNpb24sIFBIUCBleHRlbnNpb25zIGFuZCBDb21wb3NlciB2ZXJzaW9uJyAuICR0aGlzLT5nZXRQbGF0Zm9ybUV4Y2VwdGlvbkRldGFpbHMoJGNhbmRpZGF0ZSwgJHBsYXRmb3JtUmVwbyksCiAgICAgICAgICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVkVmVyc2lvbiA/ICcgYXQgdmVyc2lvbiAnLiRyZXF1aXJlZFZlcnNpb24gOiAnJwogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgbWluaW11bSBzdGFiaWxpdHkgd2FzIHRoZSBwcm9ibGVtIGJ1dCB0aGUgcGFja2FnZSBleGlzdHMKICAgICAgICAgICAgaWYgKCRwYWNrYWdlID0gJHZlcnNpb25TZWxlY3Rvci0+ZmluZEJlc3RDYW5kaWRhdGUoJG5hbWUsICRyZXF1aXJlZFZlcnNpb24sICRwcmVmZXJyZWRTdGFiaWxpdHksICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLCBSZXBvc2l0b3J5U2V0OjpBTExPV19VTkFDQ0VQVEFCTEVfU1RBQklMSVRJRVMpKSB7CiAgICAgICAgICAgICAgICAvLyB3ZSBtdXN0IGZpcnN0IHZlcmlmeSBpZiBhIHZhbGlkIHBhY2thZ2Ugd291bGQgYmUgZm91bmQgaW4gYSBsb3dlciBwcmlvcml0eSByZXBvc2l0b3J5CiAgICAgICAgICAgICAgICBpZiAoJGFsbFJlcG9zUGFja2FnZSA9ICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCAkcmVxdWlyZWRWZXJzaW9uLCAkcHJlZmVycmVkU3RhYmlsaXR5LCAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciwgUmVwb3NpdG9yeVNldDo6QUxMT1dfU0hBRE9XRURfUkVQT1NJVE9SSUVTKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAnUGFja2FnZSAnLiRuYW1lLicgZXhpc3RzIGluICcuJGFsbFJlcG9zUGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpLT5nZXRSZXBvTmFtZSgpLicgYW5kICcuJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKS0+Z2V0UmVwb05hbWUoKS4nIHdoaWNoIGhhcyBhIGhpZ2hlciByZXBvc2l0b3J5IHByaW9yaXR5LiBUaGUgcGFja2FnZXMgZnJvbSB0aGUgaGlnaGVyIHByaW9yaXR5IHJlcG9zaXRvcnkgZG8gbm90IG1hdGNoIHlvdXIgbWluaW11bS1zdGFiaWxpdHkgYW5kIGFyZSB0aGVyZWZvcmUgbm90IGluc3RhbGxhYmxlLiBUaGF0IHJlcG9zaXRvcnkgaXMgY2Fub25pY2FsIHNvIHRoZSBsb3dlciBwcmlvcml0eSByZXBvXCdzIHBhY2thZ2VzIGFyZSBub3QgaW5zdGFsbGFibGUuIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9yZXBvcHJpbyBmb3IgZGV0YWlscyBhbmQgYXNzaXN0YW5jZS4nCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdDb3VsZCBub3QgZmluZCBhIHZlcnNpb24gb2YgcGFja2FnZSAlcyBtYXRjaGluZyB5b3VyIG1pbmltdW0tc3RhYmlsaXR5ICglcykuIFJlcXVpcmUgaXQgd2l0aCBhbiBleHBsaWNpdCB2ZXJzaW9uIGNvbnN0cmFpbnQgYWxsb3dpbmcgaXRzIGRlc2lyZWQgc3RhYmlsaXR5LicsCiAgICAgICAgICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgJGVmZmVjdGl2ZU1pbmltdW1TdGFiaWxpdHkKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIHJlcXVpcmVkIHZlcnNpb24gd2FzIHRoZSBwcm9ibGVtCiAgICAgICAgICAgIGlmICgkcmVxdWlyZWRWZXJzaW9uICYmICRwYWNrYWdlID0gJHZlcnNpb25TZWxlY3Rvci0+ZmluZEJlc3RDYW5kaWRhdGUoJG5hbWUsIG51bGwsICRwcmVmZXJyZWRTdGFiaWxpdHksICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKSkgewogICAgICAgICAgICAgICAgLy8gd2UgbXVzdCBmaXJzdCB2ZXJpZnkgaWYgYSB2YWxpZCBwYWNrYWdlIHdvdWxkIGJlIGZvdW5kIGluIGEgbG93ZXIgcHJpb3JpdHkgcmVwb3NpdG9yeQogICAgICAgICAgICAgICAgaWYgKCRhbGxSZXBvc1BhY2thZ2UgPSAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgJHJlcXVpcmVkVmVyc2lvbiwgJHByZWZlcnJlZFN0YWJpbGl0eSwgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6Omlnbm9yZU5vdGhpbmcoKSwgUmVwb3NpdG9yeVNldDo6QUxMT1dfU0hBRE9XRURfUkVQT1NJVE9SSUVTKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAnUGFja2FnZSAnLiRuYW1lLicgZXhpc3RzIGluICcuJGFsbFJlcG9zUGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpLT5nZXRSZXBvTmFtZSgpLicgYW5kICcuJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKS0+Z2V0UmVwb05hbWUoKS4nIHdoaWNoIGhhcyBhIGhpZ2hlciByZXBvc2l0b3J5IHByaW9yaXR5LiBUaGUgcGFja2FnZXMgZnJvbSB0aGUgaGlnaGVyIHByaW9yaXR5IHJlcG9zaXRvcnkgZG8gbm90IG1hdGNoIHlvdXIgY29uc3RyYWludCBhbmQgYXJlIHRoZXJlZm9yZSBub3QgaW5zdGFsbGFibGUuIFRoYXQgcmVwb3NpdG9yeSBpcyBjYW5vbmljYWwgc28gdGhlIGxvd2VyIHByaW9yaXR5IHJlcG9cJ3MgcGFja2FnZXMgYXJlIG5vdCBpbnN0YWxsYWJsZS4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL3JlcG9wcmlvIGZvciBkZXRhaWxzIGFuZCBhc3Npc3RhbmNlLicKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0NvdWxkIG5vdCBmaW5kIHBhY2thZ2UgJXMgaW4gYSB2ZXJzaW9uIG1hdGNoaW5nICIlcyIgYW5kIGEgc3RhYmlsaXR5IG1hdGNoaW5nICInLiRlZmZlY3RpdmVNaW5pbXVtU3RhYmlsaXR5LiciLicsCiAgICAgICAgICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVkVmVyc2lvbgogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgUEhQIHZlcnNpb24gd2FzIHRoZSBwcm9ibGVtIGZvciBhbGwgdmVyc2lvbnMKICAgICAgICAgICAgaWYgKCEoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIgaW5zdGFuY2VvZiBJZ25vcmVBbGxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKSAmJiAoJGNhbmRpZGF0ZSA9ICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCBudWxsLCAkcHJlZmVycmVkU3RhYmlsaXR5LCBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6aWdub3JlQWxsKCksIFJlcG9zaXRvcnlTZXQ6OkFMTE9XX1VOQUNDRVBUQUJMRV9TVEFCSUxJVElFUykpKSB7CiAgICAgICAgICAgICAgICAkYWRkaXRpb25hbCA9ICcnOwogICAgICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgbnVsbCwgJHByZWZlcnJlZFN0YWJpbGl0eSwgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6Omlnbm9yZUFsbCgpKSkgewogICAgICAgICAgICAgICAgICAgICRhZGRpdGlvbmFsID0gUEhQX0VPTC5QSFBfRU9MLidBZGRpdGlvbmFsbHksIHRoZSBwYWNrYWdlIHdhcyBvbmx5IGZvdW5kIHdpdGggYSBzdGFiaWxpdHkgb2YgIicuJGNhbmRpZGF0ZS0+Z2V0U3RhYmlsaXR5KCkuJyIgd2hpbGUgeW91ciBtaW5pbXVtIHN0YWJpbGl0eSBpcyAiJy4kZWZmZWN0aXZlTWluaW11bVN0YWJpbGl0eS4nIi4nOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0NvdWxkIG5vdCBmaW5kIHBhY2thZ2UgJXMgaW4gYW55IHZlcnNpb24gbWF0Y2hpbmcgeW91ciBQSFAgdmVyc2lvbiwgUEhQIGV4dGVuc2lvbnMgYW5kIENvbXBvc2VyIHZlcnNpb24nIC4gJHRoaXMtPmdldFBsYXRmb3JtRXhjZXB0aW9uRGV0YWlscygkY2FuZGlkYXRlLCAkcGxhdGZvcm1SZXBvKSAuICclcycsCiAgICAgICAgICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgJGFkZGl0aW9uYWwKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDaGVjayBmb3Igc2ltaWxhciBuYW1lcy90eXBvcwogICAgICAgICAgICAkc2ltaWxhciA9ICR0aGlzLT5maW5kU2ltaWxhcigkbmFtZSk7CiAgICAgICAgICAgIGlmICgkc2ltaWxhcikgewogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRuYW1lLCAkc2ltaWxhciwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IGZpbmQgcGFja2FnZSAlcy4gSXQgd2FzIGhvd2V2ZXIgZm91bmQgdmlhIHJlcG9zaXRvcnkgc2VhcmNoLCB3aGljaCBpbmRpY2F0ZXMgYSBjb25zaXN0ZW5jeSBpc3N1ZSB3aXRoIHRoZSByZXBvc2l0b3J5LiIsCiAgICAgICAgICAgICAgICAgICAgICAgICRuYW1lCiAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IGZpbmQgcGFja2FnZSAlcy5cblxuRGlkIHlvdSBtZWFuICIgLiAoY291bnQoJHNpbWlsYXIpID4gMSA/ICdvbmUgb2YgdGhlc2UnIDogJ3RoaXMnKSAuICI/XG4gICAgJXMiLAogICAgICAgICAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICAgICAgICAgIGltcGxvZGUoIlxuICAgICIsICRzaW1pbGFyKQogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnQ291bGQgbm90IGZpbmQgYSBtYXRjaGluZyB2ZXJzaW9uIG9mIHBhY2thZ2UgJXMuIENoZWNrIHRoZSBwYWNrYWdlIHNwZWxsaW5nLCB5b3VyIHZlcnNpb24gY29uc3RyYWludCBhbmQgdGhhdCB0aGUgcGFja2FnZSBpcyBhdmFpbGFibGUgaW4gYSBzdGFiaWxpdHkgd2hpY2ggbWF0Y2hlcyB5b3VyIG1pbmltdW0tc3RhYmlsaXR5ICglcykuJywKICAgICAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICAgICAgJGVmZmVjdGl2ZU1pbmltdW1TdGFiaWxpdHkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICRmaXhlZCA/ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgOiAkdmVyc2lvblNlbGVjdG9yLT5maW5kUmVjb21tZW5kZWRSZXF1aXJlVmVyc2lvbigkcGFja2FnZSksCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UGxhdGZvcm1FeGNlcHRpb25EZXRhaWxzKFBhY2thZ2VJbnRlcmZhY2UgJGNhbmRpZGF0ZSwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8gPSBudWxsKQogICAgewogICAgICAgICRkZXRhaWxzID0gYXJyYXkoKTsKICAgICAgICBpZiAoISRwbGF0Zm9ybVJlcG8pIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICBpZiAoIVBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJGxpbmstPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBsYXRmb3JtUGtnID0gJHBsYXRmb3JtUmVwby0+ZmluZFBhY2thZ2UoJGxpbmstPmdldFRhcmdldCgpLCAnKicpOwogICAgICAgICAgICBpZiAoISRwbGF0Zm9ybVBrZykgewogICAgICAgICAgICAgICAgaWYgKCRwbGF0Zm9ybVJlcG8tPmlzUGxhdGZvcm1QYWNrYWdlRGlzYWJsZWQoJGxpbmstPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgICAgICRkZXRhaWxzW10gPSAkY2FuZGlkYXRlLT5nZXRQcmV0dHlOYW1lKCkuJyAnLiRjYW5kaWRhdGUtPmdldFByZXR0eVZlcnNpb24oKS4nIHJlcXVpcmVzICcuJGxpbmstPmdldFRhcmdldCgpLicgJy4kbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpLicgYnV0IGl0IGlzIGRpc2FibGVkIGJ5IHlvdXIgcGxhdGZvcm0gY29uZmlnLiBFbmFibGUgaXQgYWdhaW4gd2l0aCAiY29tcG9zZXIgY29uZmlnIHBsYXRmb3JtLicuJGxpbmstPmdldFRhcmdldCgpLicgLS11bnNldCIuJzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGRldGFpbHNbXSA9ICRjYW5kaWRhdGUtPmdldFByZXR0eU5hbWUoKS4nICcuJGNhbmRpZGF0ZS0+Z2V0UHJldHR5VmVyc2lvbigpLicgcmVxdWlyZXMgJy4kbGluay0+Z2V0VGFyZ2V0KCkuJyAnLiRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkuJyBidXQgaXQgaXMgbm90IHByZXNlbnQuJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGxpbmstPmdldENvbnN0cmFpbnQoKS0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkcGxhdGZvcm1Qa2ctPmdldFZlcnNpb24oKSkpKSB7CiAgICAgICAgICAgICAgICAkcGxhdGZvcm1Qa2dWZXJzaW9uID0gJHBsYXRmb3JtUGtnLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAkcGxhdGZvcm1FeHRyYSA9ICRwbGF0Zm9ybVBrZy0+Z2V0RXh0cmEoKTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGxhdGZvcm1FeHRyYVsnY29uZmlnLnBsYXRmb3JtJ10pICYmICRwbGF0Zm9ybVBrZyBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgICAgICRwbGF0Zm9ybVBrZ1ZlcnNpb24gLj0gJyAoJy4kcGxhdGZvcm1Qa2ctPmdldERlc2NyaXB0aW9uKCkuJyknOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGRldGFpbHNbXSA9ICRjYW5kaWRhdGUtPmdldFByZXR0eU5hbWUoKS4nICcuJGNhbmRpZGF0ZS0+Z2V0UHJldHR5VmVyc2lvbigpLicgcmVxdWlyZXMgJy4kbGluay0+Z2V0VGFyZ2V0KCkuJyAnLiRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkuJyB3aGljaCBkb2VzIG5vdCBtYXRjaCB5b3VyIGluc3RhbGxlZCB2ZXJzaW9uICcuJHBsYXRmb3JtUGtnVmVyc2lvbi4nLic7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJGRldGFpbHMpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICc6Jy5QSFBfRU9MLicgIC0gJyAuIGltcGxvZGUoUEhQX0VPTC4nICAtICcsICRkZXRhaWxzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaW5kU2ltaWxhcigkcGFja2FnZSkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcmVzdWx0cyA9ICR0aGlzLT5yZXBvcy0+c2VhcmNoKCRwYWNrYWdlKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIC8vIGlnbm9yZSBzZWFyY2ggZXJyb3JzCiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KICAgICAgICAkc2ltaWxhclBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CgogICAgICAgIGZvcmVhY2ggKCRyZXN1bHRzIGFzICRyZXN1bHQpIHsKICAgICAgICAgICAgaWYgKCRpbnN0YWxsZWRSZXBvLT5maW5kUGFja2FnZSgkcmVzdWx0WyduYW1lJ10sICcqJykpIHsKICAgICAgICAgICAgICAgIC8vIElnbm9yZSBpbnN0YWxsZWQgcGFja2FnZQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNpbWlsYXJQYWNrYWdlc1skcmVzdWx0WyduYW1lJ11dID0gbGV2ZW5zaHRlaW4oJHBhY2thZ2UsICRyZXN1bHRbJ25hbWUnXSk7CiAgICAgICAgfQogICAgICAgIGFzb3J0KCRzaW1pbGFyUGFja2FnZXMpOwoKICAgICAgICByZXR1cm4gYXJyYXlfa2V5cyhhcnJheV9zbGljZSgkc2ltaWxhclBhY2thZ2VzLCAwLCA1KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1cGRhdGVEZXBlbmRlbmNpZXMoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHVwZGF0ZUNvbW1hbmQgPSAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+ZmluZCgndXBkYXRlJyk7CiAgICAgICAgICAgICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5yZXNldENvbXBvc2VyKCk7CiAgICAgICAgICAgICR1cGRhdGVDb21tYW5kLT5ydW4obmV3IEFycmF5SW5wdXQoYXJyYXkoKSksICRvdXRwdXQpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJ0NvdWxkIG5vdCB1cGRhdGUgZGVwZW5kZW5jaWVzLiBSdW4gYGNvbXBvc2VyIHVwZGF0ZWAgdG8gc2VlIG1vcmUgaW5mb3JtYXRpb24uJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcnVuRHVtcEF1dG9sb2FkQ29tbWFuZChPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5maW5kKCdkdW1wLWF1dG9sb2FkJyk7CiAgICAgICAgICAgICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5yZXNldENvbXBvc2VyKCk7CiAgICAgICAgICAgICRjb21tYW5kLT5ydW4obmV3IEFycmF5SW5wdXQoYXJyYXkoKSksICRvdXRwdXQpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJ0NvdWxkIG5vdCBydW4gZHVtcC1hdXRvbG9hZC4nKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmd8YXJyYXk8c3RyaW5nPj4gJG9wdGlvbnMKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGhhc0RlcGVuZGVuY2llcygkb3B0aW9ucykKICAgIHsKICAgICAgICAkcmVxdWlyZXMgPSAoYXJyYXkpICRvcHRpb25zWydyZXF1aXJlJ107CiAgICAgICAgJGRldlJlcXVpcmVzID0gaXNzZXQoJG9wdGlvbnNbJ3JlcXVpcmUtZGV2J10pID8gKGFycmF5KSAkb3B0aW9uc1sncmVxdWlyZS1kZXYnXSA6IGFycmF5KCk7CgogICAgICAgIHJldHVybiAhZW1wdHkoJHJlcXVpcmVzKSB8fCAhZW1wdHkoJGRldlJlcXVpcmVzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFNjcmlwdEFsaWFzQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkc2NyaXB0OwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRkZXNjcmlwdGlvbjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNjcmlwdAogICAgICogQHBhcmFtIHN0cmluZyAkZGVzY3JpcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzY3JpcHQsICRkZXNjcmlwdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+c2NyaXB0ID0gJHNjcmlwdDsKICAgICAgICAkdGhpcy0+ZGVzY3JpcHRpb24gPSBlbXB0eSgkZGVzY3JpcHRpb24pID8gJ1J1bnMgdGhlICcuJHNjcmlwdC4nIHNjcmlwdCBhcyBkZWZpbmVkIGluIGNvbXBvc2VyLmpzb24uJyA6ICRkZXNjcmlwdGlvbjsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgkdGhpcy0+c2NyaXB0KQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCR0aGlzLT5kZXNjcmlwdGlvbikKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NldHMgdGhlIGRldiBtb2RlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIHRoZSBkZXYgbW9kZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdhcmdzJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJycpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPnJ1bi1zY3JpcHQ8L2luZm8+IGNvbW1hbmQgcnVucyBzY3JpcHRzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbjoKCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHJ1bi1zY3JpcHQgcG9zdC11cGRhdGUtY21kPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjcnVuLXNjcmlwdApFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRhcmdzID0gJGlucHV0LT5nZXRBcmd1bWVudHMoKTsKCiAgICAgICAgcmV0dXJuICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoU2NyaXB0KCR0aGlzLT5zY3JpcHQsICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSB8fCAhJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpLCAkYXJnc1snYXJncyddKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGVyRXZlbnRzOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXEpzb25cSnNvbk1hbmlwdWxhdG9yOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwoKLyoqCiAqIEBhdXRob3IgSsOpcsOpbXkgUm9tZXkgPGplcmVteUBmcmVlLWFnZW50LmZyPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBSZXF1aXJlQ29tbWFuZCBleHRlbmRzIEluaXRDb21tYW5kCnsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJG5ld2x5Q3JlYXRlZDsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGZpcnN0UmVxdWlyZTsKICAgIC8qKiBAdmFyIEpzb25GaWxlICovCiAgICBwcml2YXRlICRqc29uOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRmaWxlOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRjb21wb3NlckJhY2t1cDsKICAgIC8qKiBAdmFyIHN0cmluZyBmaWxlIG5hbWUgKi8KICAgIHByaXZhdGUgJGxvY2s7CiAgICAvKiogQHZhciA/c3RyaW5nIGNvbnRlbnRzIGJlZm9yZSBtb2RpZmljYXRpb24gaWYgdGhlIGxvY2sgZmlsZSBleGlzdHMgKi8KICAgIHByaXZhdGUgJGxvY2tCYWNrdXA7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRkZXBlbmRlbmN5UmVzb2x1dGlvbkNvbXBsZXRlZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgncmVxdWlyZScpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0FkZHMgcmVxdWlyZWQgcGFja2FnZXMgdG8geW91ciBjb21wb3Nlci5qc29uIGFuZCBpbnN0YWxscyB0aGVtLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdwYWNrYWdlcycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdPcHRpb25hbCBwYWNrYWdlIG5hbWUgY2FuIGFsc28gaW5jbHVkZSBhIHZlcnNpb24gY29uc3RyYWludCwgZS5nLiBmb28vYmFyIG9yIGZvby9iYXI6MS4wLjAgb3IgZm9vL2Jhcj0xLjAuMCBvciAiZm9vL2JhciAxLjAuMCInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBZGQgcmVxdWlyZW1lbnQgdG8gcmVxdWlyZS1kZXYuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RyeS1ydW4nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ091dHB1dHMgdGhlIG9wZXJhdGlvbnMgYnV0IHdpbGwgbm90IGV4ZWN1dGUgYW55dGhpbmcgKGltcGxpY2l0bHkgZW5hYmxlcyAtLXZlcmJvc2UpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc291cmNlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBzb3VyY2VzIHdoZW4gcG9zc2libGUsIGluY2x1ZGluZyBWQ1MgaW5mb3JtYXRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1kaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0IChkZWZhdWx0IGJlaGF2aW9yKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWluc3RhbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0fHNvdXJjZXxhdXRvIChhdXRvIGNob29zZXMgc291cmNlIGZvciBkZXYgdmVyc2lvbnMsIGRpc3QgZm9yIHRoZSByZXN0KS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZml4ZWQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1dyaXRlIGZpeGVkIHZlcnNpb24gdG8gdGhlIGNvbXBvc2VyLmpzb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXN1Z2dlc3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RFUFJFQ0FURUQ6IFRoaXMgZmxhZyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1wcm9ncmVzcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IG91dHB1dCBkb3dubG9hZCBwcm9ncmVzcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tdXBkYXRlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyB0aGUgYXV0b21hdGljIHVwZGF0ZSBvZiB0aGUgZGVwZW5kZW5jaWVzIChpbXBsaWVzIC0tbm8taW5zdGFsbCkuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWluc3RhbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXAgdGhlIGluc3RhbGwgc3RlcCBhZnRlciB1cGRhdGluZyB0aGUgY29tcG9zZXIubG9jayBmaWxlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1cGRhdGUtbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSdW4gdGhlIGRlcGVuZGVuY3kgdXBkYXRlIHdpdGggdGhlIC0tbm8tZGV2IG9wdGlvbi4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJywgJ3cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0FsbG93cyBpbmhlcml0ZWQgZGVwZW5kZW5jaWVzIHRvIGJlIHVwZGF0ZWQsIGV4Y2VwdCB0aG9zZSB0aGF0IGFyZSByb290IHJlcXVpcmVtZW50cy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndXBkYXRlLXdpdGgtYWxsLWRlcGVuZGVuY2llcycsICdXJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBbGxvd3MgYWxsIGluaGVyaXRlZCBkZXBlbmRlbmNpZXMgdG8gYmUgdXBkYXRlZCwgaW5jbHVkaW5nIHRob3NlIHRoYXQgYXJlIHJvb3QgcmVxdWlyZW1lbnRzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd3aXRoLWRlcGVuZGVuY2llcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxpYXMgZm9yIC0tdXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxpYXMgZm9yIC0tdXBkYXRlLXdpdGgtYWxsLWRlcGVuZGVuY2llcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIGEgc3BlY2lmaWMgcGxhdGZvcm0gcmVxdWlyZW1lbnQgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc3RhYmxlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdQcmVmZXIgc3RhYmxlIHZlcnNpb25zIG9mIGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWxvd2VzdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJlZmVyIGxvd2VzdCB2ZXJzaW9ucyBvZiBkZXBlbmRlbmNpZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3NvcnQtcGFja2FnZXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NvcnRzIHBhY2thZ2VzIHdoZW4gYWRkaW5nL3VwZGF0aW5nIGEgbmV3IGRlcGVuZGVuY3knKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcHRpbWl6ZSBhdXRvbG9hZGVyIGR1cmluZyBhdXRvbG9hZGVyIGR1bXAnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBdXRvbG9hZCBjbGFzc2VzIGZyb20gdGhlIGNsYXNzbWFwIG9ubHkuIEltcGxpY2l0bHkgZW5hYmxlcyBgLS1vcHRpbWl6ZS1hdXRvbG9hZGVyYC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVc2UgQVBDdSB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3Nlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1VzZSBhIGN1c3RvbSBwcmVmaXggZm9yIHRoZSBBUEN1IGF1dG9sb2FkZXIgY2FjaGUuIEltcGxpY2l0bHkgZW5hYmxlcyAtLWFwY3UtYXV0b2xvYWRlcicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIHJlcXVpcmUgY29tbWFuZCBhZGRzIHJlcXVpcmVkIHBhY2thZ2VzIHRvIHlvdXIgY29tcG9zZXIuanNvbiBhbmQgaW5zdGFsbHMgdGhlbS4KCklmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHBhY2thZ2UsIGNvbXBvc2VyIHdpbGwgcHJvbXB0IHlvdSB0byBzZWFyY2ggZm9yIGEgcGFja2FnZSwgYW5kIGdpdmVuIHJlc3VsdHMsIHByb3ZpZGUgYSBsaXN0IG9mCm1hdGNoZXMgdG8gcmVxdWlyZS4KCklmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHZlcnNpb24gY29uc3RyYWludCwgY29tcG9zZXIgd2lsbCBjaG9vc2UgYSBzdWl0YWJsZSBvbmUgYmFzZWQgb24gdGhlIGF2YWlsYWJsZSBwYWNrYWdlIHZlcnNpb25zLgoKSWYgeW91IGRvIG5vdCB3YW50IHRvIGluc3RhbGwgdGhlIG5ldyBkZXBlbmRlbmNpZXMgaW1tZWRpYXRlbHkgeW91IGNhbiBjYWxsIGl0IHdpdGggLS1uby11cGRhdGUKClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3JlcXVpcmUKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICogQHRocm93cyBcU2VsZFxKc29uTGludFxQYXJzaW5nRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygncGNudGxfYXN5bmNfc2lnbmFscycpICYmIGZ1bmN0aW9uX2V4aXN0cygncGNudGxfc2lnbmFsJykpIHsKICAgICAgICAgICAgcGNudGxfYXN5bmNfc2lnbmFscyh0cnVlKTsKICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR0lOVCwgYXJyYXkoJHRoaXMsICdyZXZlcnRDb21wb3NlckZpbGUnKSk7CiAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdURVJNLCBhcnJheSgkdGhpcywgJ3JldmVydENvbXBvc2VyRmlsZScpKTsKICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR0hVUCwgYXJyYXkoJHRoaXMsICdyZXZlcnRDb21wb3NlckZpbGUnKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZmlsZSA9IEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLXN1Z2dlc3QnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgdXNpbmcgdGhlIGRlcHJlY2F0ZWQgb3B0aW9uICItLW5vLXN1Z2dlc3QiLiBJdCBoYXMgbm8gZWZmZWN0IGFuZCB3aWxsIGJyZWFrIGluIENvbXBvc2VyIDMuPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm5ld2x5Q3JlYXRlZCA9ICFmaWxlX2V4aXN0cygkdGhpcy0+ZmlsZSk7CiAgICAgICAgaWYgKCR0aGlzLT5uZXdseUNyZWF0ZWQgJiYgIWZpbGVfcHV0X2NvbnRlbnRzKCR0aGlzLT5maWxlLCAie1xufVxuIikpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy4kdGhpcy0+ZmlsZS4nIGNvdWxkIG5vdCBiZSBjcmVhdGVkLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgaWYgKCFGaWxlc3lzdGVtOjppc1JlYWRhYmxlKCR0aGlzLT5maWxlKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj4nLiR0aGlzLT5maWxlLicgaXMgbm90IHJlYWRhYmxlLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlc2l6ZSgkdGhpcy0+ZmlsZSkgPT09IDApIHsKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPmZpbGUsICJ7XG59XG4iKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5qc29uID0gbmV3IEpzb25GaWxlKCR0aGlzLT5maWxlKTsKICAgICAgICAkdGhpcy0+bG9jayA9IEZhY3Rvcnk6OmdldExvY2tGaWxlKCR0aGlzLT5maWxlKTsKICAgICAgICAkdGhpcy0+Y29tcG9zZXJCYWNrdXAgPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+anNvbi0+Z2V0UGF0aCgpKTsKICAgICAgICAkdGhpcy0+bG9ja0JhY2t1cCA9IGZpbGVfZXhpc3RzKCR0aGlzLT5sb2NrKSA/IGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5sb2NrKSA6IG51bGw7CgogICAgICAgIC8vIGNoZWNrIGZvciB3cml0YWJpbGl0eSBieSB3cml0aW5nIHRvIHRoZSBmaWxlIGFzIGlzX3dyaXRhYmxlIGNhbiBub3QgYmUgdHJ1c3RlZCBvbiBuZXR3b3JrLW1vdW50cwogICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzgyMzEgYW5kIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9Njg5MjYKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCR0aGlzLT5maWxlKSAmJiAhU2lsZW5jZXI6OmNhbGwoJ2ZpbGVfcHV0X2NvbnRlbnRzJywgJHRoaXMtPmZpbGUsICR0aGlzLT5jb21wb3NlckJhY2t1cCkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy4kdGhpcy0+ZmlsZS4nIGlzIG5vdCB3cml0YWJsZS48L2Vycm9yPicpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2ZpeGVkJykgPT09IHRydWUpIHsKICAgICAgICAgICAgJGNvbmZpZyA9ICR0aGlzLT5qc29uLT5yZWFkKCk7CgogICAgICAgICAgICAkcGFja2FnZVR5cGUgPSBlbXB0eSgkY29uZmlnWyd0eXBlJ10pID8gJ2xpYnJhcnknIDogJGNvbmZpZ1sndHlwZSddOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvODMxMyNpc3N1ZWNvbW1lbnQtNTMyNjM3OTU1CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoJHBhY2thZ2VUeXBlICE9PSAncHJvamVjdCcpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPiItLWZpeGVkIiBvcHRpb24gaXMgYWxsb3dlZCBmb3IgInByb2plY3QiIHBhY2thZ2UgdHlwZXMgb25seSB0byBwcmV2ZW50IHBvc3NpYmxlIG1pc3VzZXMuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJGNvbmZpZ1sndHlwZSddKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPklmIHlvdXIgcGFja2FnZSBpcyBub3QgbGlicmFyeSwgeW91IHNob3VsZCBleHBsaWNpdGx5IHNwZWNpZnkgInR5cGUiIHBhcmFtZXRlciBpbiBjb21wb3Nlci5qc29uLjwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3Nlcih0cnVlLCAkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpKTsKICAgICAgICAkcmVwb3MgPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpOwoKICAgICAgICAkcGxhdGZvcm1PdmVycmlkZXMgPSAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKTsKICAgICAgICAvLyBpbml0aWFsaXplICR0aGlzLT5yZXBvcyBhcyBpdCBpcyB1c2VkIGJ5IHRoZSBwYXJlbnQgSW5pdENvbW1hbmQKICAgICAgICAkdGhpcy0+cmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheV9tZXJnZSgKICAgICAgICAgICAgYXJyYXkoJHBsYXRmb3JtUmVwbyA9IG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkoYXJyYXkoKSwgJHBsYXRmb3JtT3ZlcnJpZGVzKSksCiAgICAgICAgICAgICRyZXBvcwogICAgICAgICkpOwoKICAgICAgICBpZiAoJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldFByZWZlclN0YWJsZSgpKSB7CiAgICAgICAgICAgICRwcmVmZXJyZWRTdGFiaWxpdHkgPSAnc3RhYmxlJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRyZXF1aXJlbWVudHMgPSAkdGhpcy0+ZGV0ZXJtaW5lUmVxdWlyZW1lbnRzKAogICAgICAgICAgICAgICAgJGlucHV0LAogICAgICAgICAgICAgICAgJG91dHB1dCwKICAgICAgICAgICAgICAgICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJyksCiAgICAgICAgICAgICAgICAkcGxhdGZvcm1SZXBvLAogICAgICAgICAgICAgICAgJHByZWZlcnJlZFN0YWJpbGl0eSwKICAgICAgICAgICAgICAgICEkaW5wdXQtPmdldE9wdGlvbignbm8tdXBkYXRlJyksCiAgICAgICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignZml4ZWQnKQogICAgICAgICAgICApOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5uZXdseUNyZWF0ZWQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZXZlcnRDb21wb3NlckZpbGUoZmFsc2UpOwoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignTm8gY29tcG9zZXIuanNvbiBwcmVzZW50IGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSAoJy4kdGhpcy0+ZmlsZS4nKSwgdGhpcyBtYXkgYmUgdGhlIGNhdXNlIG9mIHRoZSBmb2xsb3dpbmcgZXhjZXB0aW9uLicsIDAsICRlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICAkcmVxdWlyZUtleSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSA/ICdyZXF1aXJlLWRldicgOiAncmVxdWlyZSc7CiAgICAgICAgJHJlbW92ZUtleSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSA/ICdyZXF1aXJlJyA6ICdyZXF1aXJlLWRldic7CiAgICAgICAgJHJlcXVpcmVtZW50cyA9ICR0aGlzLT5mb3JtYXRSZXF1aXJlbWVudHMoJHJlcXVpcmVtZW50cyk7CgogICAgICAgIC8vIHZhbGlkYXRlIHJlcXVpcmVtZW50cyBmb3JtYXQKICAgICAgICAkdmVyc2lvblBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVtZW50cyBhcyAkcGFja2FnZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkcGFja2FnZSkgPT09ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+Um9vdCBwYWNrYWdlIFwnJXNcJyBjYW5ub3QgcmVxdWlyZSBpdHNlbGYgaW4gaXRzIGNvbXBvc2VyLmpzb248L2Vycm9yPicsICRwYWNrYWdlKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgJGluY29uc2lzdGVudFJlcXVpcmVLZXlzID0gJHRoaXMtPmdldEluY29uc2lzdGVudFJlcXVpcmVLZXlzKCRyZXF1aXJlbWVudHMsICRyZXF1aXJlS2V5KTsKICAgICAgICBpZiAoY291bnQoJGluY29uc2lzdGVudFJlcXVpcmVLZXlzKSA+IDApIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGluY29uc2lzdGVudFJlcXVpcmVLZXlzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkaW8tPndhcm5pbmcoc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnJXMgaXMgY3VycmVudGx5IHByZXNlbnQgaW4gdGhlICVzIGtleSBhbmQgeW91IHJhbiB0aGUgY29tbWFuZCAlcyB0aGUgLS1kZXYgZmxhZywgd2hpY2ggd291bGQgbW92ZSBpdCB0byB0aGUgJXMga2V5LicsCiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UsCiAgICAgICAgICAgICAgICAgICAgJHJlbW92ZUtleSwKICAgICAgICAgICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignZGV2JykgPyAnd2l0aCcgOiAnd2l0aG91dCcsCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVLZXkKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgIGlmICghJGlvLT5hc2tDb25maXJtYXRpb24oc3ByaW50ZignPGluZm8+RG8geW91IHdhbnQgdG8gbW92ZSAlcz88L2luZm8+IFs8Y29tbWVudD5ubzwvY29tbWVudD5dPyAnLCBjb3VudCgkaW5jb25zaXN0ZW50UmVxdWlyZUtleXMpID4gMSA/ICd0aGVzZSByZXF1aXJlbWVudHMnIDogJ3RoaXMgcmVxdWlyZW1lbnQnKSwgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkaW8tPmFza0NvbmZpcm1hdGlvbihzcHJpbnRmKCc8aW5mbz5EbyB5b3Ugd2FudCB0byByZS1ydW4gdGhlIGNvbW1hbmQgJXMgLS1kZXY/PC9pbmZvPiBbPGNvbW1lbnQ+eWVzPC9jb21tZW50Pl0/ICcsICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSA/ICd3aXRob3V0JyA6ICd3aXRoJyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbGlzdCgkcmVxdWlyZUtleSwgJHJlbW92ZUtleSkgPSBhcnJheSgkcmVtb3ZlS2V5LCAkcmVxdWlyZUtleSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRzb3J0UGFja2FnZXMgPSAkaW5wdXQtPmdldE9wdGlvbignc29ydC1wYWNrYWdlcycpIHx8ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnc29ydC1wYWNrYWdlcycpOwoKICAgICAgICAkdGhpcy0+Zmlyc3RSZXF1aXJlID0gJHRoaXMtPm5ld2x5Q3JlYXRlZDsKICAgICAgICBpZiAoISR0aGlzLT5maXJzdFJlcXVpcmUpIHsKICAgICAgICAgICAgJGNvbXBvc2VyRGVmaW5pdGlvbiA9ICR0aGlzLT5qc29uLT5yZWFkKCk7CiAgICAgICAgICAgIGlmIChlbXB0eSgkY29tcG9zZXJEZWZpbml0aW9uWydyZXF1aXJlJ10pICYmIGVtcHR5KCRjb21wb3NlckRlZmluaXRpb25bJ3JlcXVpcmUtZGV2J10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Zmlyc3RSZXF1aXJlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaW5wdXQtPmdldE9wdGlvbignZHJ5LXJ1bicpICYmICEkdGhpcy0+dXBkYXRlRmlsZUNsZWFubHkoJHRoaXMtPmpzb24sICRyZXF1aXJlbWVudHMsICRyZXF1aXJlS2V5LCAkcmVtb3ZlS2V5LCAkc29ydFBhY2thZ2VzKSkgewogICAgICAgICAgICAkY29tcG9zZXJEZWZpbml0aW9uID0gJHRoaXMtPmpzb24tPnJlYWQoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVtZW50cyBhcyAkcGFja2FnZSA9PiAkdmVyc2lvbikgewogICAgICAgICAgICAgICAgJGNvbXBvc2VyRGVmaW5pdGlvblskcmVxdWlyZUtleV1bJHBhY2thZ2VdID0gJHZlcnNpb247CiAgICAgICAgICAgICAgICB1bnNldCgkY29tcG9zZXJEZWZpbml0aW9uWyRyZW1vdmVLZXldWyRwYWNrYWdlXSk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VyRGVmaW5pdGlvblskcmVtb3ZlS2V5XSkgJiYgY291bnQoJGNvbXBvc2VyRGVmaW5pdGlvblskcmVtb3ZlS2V5XSkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkY29tcG9zZXJEZWZpbml0aW9uWyRyZW1vdmVLZXldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+anNvbi0+d3JpdGUoJGNvbXBvc2VyRGVmaW5pdGlvbik7CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPicuJHRoaXMtPmZpbGUuJyBoYXMgYmVlbiAnLigkdGhpcy0+bmV3bHlDcmVhdGVkID8gJ2NyZWF0ZWQnIDogJ3VwZGF0ZWQnKS4nPC9pbmZvPicpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLXVwZGF0ZScpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyLT5nZXRQbHVnaW5NYW5hZ2VyKCktPmRlYWN0aXZhdGVJbnN0YWxsZWRQbHVnaW5zKCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9VcGRhdGUoJGlucHV0LCAkb3V0cHV0LCAkaW8sICRyZXF1aXJlbWVudHMsICRyZXF1aXJlS2V5LCAkcmVtb3ZlS2V5KTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmRlcGVuZGVuY3lSZXNvbHV0aW9uQ29tcGxldGVkKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmV2ZXJ0Q29tcG9zZXJGaWxlKGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICRuZXdSZXF1aXJlbWVudHMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlcXVpcmVLZXkKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbmNvbnNpc3RlbnRSZXF1aXJlS2V5cyhhcnJheSAkbmV3UmVxdWlyZW1lbnRzLCAkcmVxdWlyZUtleSkKICAgIHsKICAgICAgICAkcmVxdWlyZUtleXMgPSAkdGhpcy0+Z2V0UGFja2FnZXNCeVJlcXVpcmVLZXkoKTsKICAgICAgICAkaW5jb25zaXN0ZW50UmVxdWlyZW1lbnRzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZUtleXMgYXMgJHBhY2thZ2UgPT4gJHBhY2thZ2VSZXF1aXJlS2V5KSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJG5ld1JlcXVpcmVtZW50c1skcGFja2FnZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHJlcXVpcmVLZXkgIT09ICRwYWNrYWdlUmVxdWlyZUtleSkgewogICAgICAgICAgICAgICAgJGluY29uc2lzdGVudFJlcXVpcmVtZW50c1tdID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkaW5jb25zaXN0ZW50UmVxdWlyZW1lbnRzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRQYWNrYWdlc0J5UmVxdWlyZUtleSgpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyRGVmaW5pdGlvbiA9ICR0aGlzLT5qc29uLT5yZWFkKCk7CiAgICAgICAgJHJlcXVpcmUgPSBhcnJheSgpOwogICAgICAgICRyZXF1aXJlRGV2ID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKGlzc2V0KCRjb21wb3NlckRlZmluaXRpb25bJ3JlcXVpcmUnXSkpIHsKICAgICAgICAgICAgJHJlcXVpcmUgPSAkY29tcG9zZXJEZWZpbml0aW9uWydyZXF1aXJlJ107CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VyRGVmaW5pdGlvblsncmVxdWlyZS1kZXYnXSkpIHsKICAgICAgICAgICAgJHJlcXVpcmVEZXYgPSAkY29tcG9zZXJEZWZpbml0aW9uWydyZXF1aXJlLWRldiddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKAogICAgICAgICAgICBhcnJheV9maWxsX2tleXMoYXJyYXlfa2V5cygkcmVxdWlyZSksICdyZXF1aXJlJyksCiAgICAgICAgICAgIGFycmF5X2ZpbGxfa2V5cyhhcnJheV9rZXlzKCRyZXF1aXJlRGV2KSwgJ3JlcXVpcmUtZGV2JykKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHByaXZhdGUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFya1NvbHZlckNvbXBsZXRlKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGVwZW5kZW5jeVJlc29sdXRpb25Db21wbGV0ZWQgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkcmVxdWlyZW1lbnRzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXF1aXJlS2V5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZW1vdmVLZXkKICAgICAqIEByZXR1cm4gaW50CiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBkb1VwZGF0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBJT0ludGVyZmFjZSAkaW8sIGFycmF5ICRyZXF1aXJlbWVudHMsICRyZXF1aXJlS2V5LCAkcmVtb3ZlS2V5KQogICAgewogICAgICAgIC8vIFVwZGF0ZSBwYWNrYWdlcwogICAgICAgICR0aGlzLT5yZXNldENvbXBvc2VyKCk7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKHRydWUsICRpbnB1dC0+Z2V0T3B0aW9uKCduby1wbHVnaW5zJyksICRpbnB1dC0+Z2V0T3B0aW9uKCduby1zY3JpcHRzJykpOwoKICAgICAgICAkdGhpcy0+ZGVwZW5kZW5jeVJlc29sdXRpb25Db21wbGV0ZWQgPSBmYWxzZTsKICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5hZGRMaXN0ZW5lcihJbnN0YWxsZXJFdmVudHM6OlBSRV9PUEVSQVRJT05TX0VYRUMsIGFycmF5KCR0aGlzLCAnbWFya1NvbHZlckNvbXBsZXRlJyksIDEwMDAwKTsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdkcnktcnVuJykpIHsKICAgICAgICAgICAgJHJvb3RQYWNrYWdlID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgICAgICRsaW5rcyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ3JlcXVpcmUnID0+ICRyb290UGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgICAgICdyZXF1aXJlLWRldicgPT4gJHJvb3RQYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpLAogICAgICAgICAgICApOwogICAgICAgICAgICAkbG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKCk7CiAgICAgICAgICAgICRuZXdMaW5rcyA9ICRsb2FkZXItPnBhcnNlTGlua3MoJHJvb3RQYWNrYWdlLT5nZXROYW1lKCksICRyb290UGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLCBCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlc1skcmVxdWlyZUtleV1bJ21ldGhvZCddLCAkcmVxdWlyZW1lbnRzKTsKICAgICAgICAgICAgJGxpbmtzWyRyZXF1aXJlS2V5XSA9IGFycmF5X21lcmdlKCRsaW5rc1skcmVxdWlyZUtleV0sICRuZXdMaW5rcyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlbWVudHMgYXMgJHBhY2thZ2UgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRsaW5rc1skcmVtb3ZlS2V5XVskcGFja2FnZV0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyb290UGFja2FnZS0+c2V0UmVxdWlyZXMoJGxpbmtzWydyZXF1aXJlJ10pOwogICAgICAgICAgICAkcm9vdFBhY2thZ2UtPnNldERldlJlcXVpcmVzKCRsaW5rc1sncmVxdWlyZS1kZXYnXSk7CiAgICAgICAgfQoKICAgICAgICAkdXBkYXRlRGV2TW9kZSA9ICEkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLW5vLWRldicpOwogICAgICAgICRvcHRpbWl6ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJykgfHwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdvcHRpbWl6ZS1hdXRvbG9hZGVyJyk7CiAgICAgICAgJGF1dGhvcml0YXRpdmUgPSAkaW5wdXQtPmdldE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpIHx8ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpOwogICAgICAgICRhcGN1UHJlZml4ID0gJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnKTsKICAgICAgICAkYXBjdSA9ICRhcGN1UHJlZml4ICE9PSBudWxsIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXInKSB8fCAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2FwY3UtYXV0b2xvYWRlcicpOwoKICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX09OTFlfTElTVEVEOwogICAgICAgICRmbGFncyA9ICcnOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLXdpdGgtYWxsLWRlcGVuZGVuY2llcycpIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCd3aXRoLWFsbC1kZXBlbmRlbmNpZXMnKSkgewogICAgICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUzsKICAgICAgICAgICAgJGZsYWdzIC49ICcgLS13aXRoLWFsbC1kZXBlbmRlbmNpZXMnOwogICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtZGVwZW5kZW5jaWVzJykpIHsKICAgICAgICAgICAgJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyA9IFJlcXVlc3Q6OlVQREFURV9MSVNURURfV0lUSF9UUkFOU0lUSVZFX0RFUFNfTk9fUk9PVF9SRVFVSVJFOwogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLXdpdGgtZGVwZW5kZW5jaWVzJzsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+UnVubmluZyBjb21wb3NlciB1cGRhdGUgJy5pbXBsb2RlKCcgJywgYXJyYXlfa2V5cygkcmVxdWlyZW1lbnRzKSkuJGZsYWdzLic8L2luZm8+Jyk7CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3JlcXVpcmUnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoKCRjb21tYW5kRXZlbnQtPmdldE5hbWUoKSwgJGNvbW1hbmRFdmVudCk7CgogICAgICAgICRjb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5zZXRPdXRwdXRQcm9ncmVzcyghJGlucHV0LT5nZXRPcHRpb24oJ25vLXByb2dyZXNzJykpOwoKICAgICAgICAkaW5zdGFsbCA9IEluc3RhbGxlcjo6Y3JlYXRlKCRpbywgJGNvbXBvc2VyKTsKCiAgICAgICAgJGlnbm9yZVBsYXRmb3JtUmVxcyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycpID86ICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScpID86IGZhbHNlKTsKICAgICAgICBsaXN0KCRwcmVmZXJTb3VyY2UsICRwcmVmZXJEaXN0KSA9ICR0aGlzLT5nZXRQcmVmZXJyZWRJbnN0YWxsT3B0aW9ucygkY29tcG9zZXItPmdldENvbmZpZygpLCAkaW5wdXQpOwoKICAgICAgICAkaW5zdGFsbAogICAgICAgICAgICAtPnNldERyeVJ1bigkaW5wdXQtPmdldE9wdGlvbignZHJ5LXJ1bicpKQogICAgICAgICAgICAtPnNldFZlcmJvc2UoJGlucHV0LT5nZXRPcHRpb24oJ3ZlcmJvc2UnKSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJEaXN0KCRwcmVmZXJEaXN0KQogICAgICAgICAgICAtPnNldERldk1vZGUoJHVwZGF0ZURldk1vZGUpCiAgICAgICAgICAgIC0+c2V0T3B0aW1pemVBdXRvbG9hZGVyKCRvcHRpbWl6ZSkKICAgICAgICAgICAgLT5zZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJGF1dGhvcml0YXRpdmUpCiAgICAgICAgICAgIC0+c2V0QXBjdUF1dG9sb2FkZXIoJGFwY3UsICRhcGN1UHJlZml4KQogICAgICAgICAgICAtPnNldFVwZGF0ZSh0cnVlKQogICAgICAgICAgICAtPnNldEluc3RhbGwoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1pbnN0YWxsJykpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKCR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMpCiAgICAgICAgICAgIC0+c2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcihQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6ZnJvbUJvb2xPckxpc3QoJGlnbm9yZVBsYXRmb3JtUmVxcykpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyU3RhYmxlKCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItc3RhYmxlJykpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyTG93ZXN0KCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItbG93ZXN0JykpCiAgICAgICAgOwoKICAgICAgICAvLyBpZiBubyBsb2NrIGlzIHByZXNlbnQsIG9yIHRoZSBmaWxlIGlzIGJyYW5kIG5ldywgd2UgZG8gbm90IGRvIGEKICAgICAgICAvLyBwYXJ0aWFsIHVwZGF0ZSBhcyB0aGlzIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIEluc3RhbGxlcgogICAgICAgIGlmICghJHRoaXMtPmZpcnN0UmVxdWlyZSAmJiAkY29tcG9zZXItPmdldExvY2tlcigpLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICRpbnN0YWxsLT5zZXRVcGRhdGVBbGxvd0xpc3QoYXJyYXlfa2V5cygkcmVxdWlyZW1lbnRzKSk7CiAgICAgICAgfQoKICAgICAgICAkc3RhdHVzID0gJGluc3RhbGwtPnJ1bigpOwogICAgICAgIGlmICgkc3RhdHVzICE9PSAwKSB7CiAgICAgICAgICAgIGlmICgkc3RhdHVzID09PSBJbnN0YWxsZXI6OkVSUk9SX0RFUEVOREVOQ1lfUkVTT0xVVElPTl9GQUlMRUQpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ub3JtYWxpemVSZXF1aXJlbWVudHMoJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZXMnKSkgYXMgJHJlcSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHJlcVsndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1lvdSBjYW4gYWxzbyB0cnkgcmUtcnVubmluZyBjb21wb3NlciByZXF1aXJlIHdpdGggYW4gZXhwbGljaXQgdmVyc2lvbiBjb25zdHJhaW50LCBlLmcuICJjb21wb3NlciByZXF1aXJlICcuJHJlcVsnbmFtZSddLic6KiIgdG8gZmlndXJlIG91dCBpZiBhbnkgdmVyc2lvbiBpcyBpbnN0YWxsYWJsZSwgb3IgImNvbXBvc2VyIHJlcXVpcmUgJy4kcmVxWyduYW1lJ10uJzpeMi4xIiBpZiB5b3Uga25vdyB3aGljaCB5b3UgbmVlZC4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5yZXZlcnRDb21wb3NlckZpbGUoZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdGF0dXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICRuZXcKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlcXVpcmVLZXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlbW92ZUtleQogICAgICogQHBhcmFtIGJvb2wgJHNvcnRQYWNrYWdlcwogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdXBkYXRlRmlsZUNsZWFubHkoSnNvbkZpbGUgJGpzb24sIGFycmF5ICRuZXcsICRyZXF1aXJlS2V5LCAkcmVtb3ZlS2V5LCAkc29ydFBhY2thZ2VzKQogICAgewogICAgICAgICRjb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRqc29uLT5nZXRQYXRoKCkpOwoKICAgICAgICAkbWFuaXB1bGF0b3IgPSBuZXcgSnNvbk1hbmlwdWxhdG9yKCRjb250ZW50cyk7CgogICAgICAgIGZvcmVhY2ggKCRuZXcgYXMgJHBhY2thZ2UgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKCEkbWFuaXB1bGF0b3ItPmFkZExpbmsoJHJlcXVpcmVLZXksICRwYWNrYWdlLCAkY29uc3RyYWludCwgJHNvcnRQYWNrYWdlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRtYW5pcHVsYXRvci0+cmVtb3ZlU3ViTm9kZSgkcmVtb3ZlS2V5LCAkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG1hbmlwdWxhdG9yLT5yZW1vdmVNYWluS2V5SWZFbXB0eSgkcmVtb3ZlS2V5KTsKCiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGpzb24tPmdldFBhdGgoKSwgJG1hbmlwdWxhdG9yLT5nZXRDb250ZW50cygpKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGludGVyYWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGhhcmRFeGl0CiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJldmVydENvbXBvc2VyRmlsZSgkaGFyZEV4aXQgPSB0cnVlKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBpZiAoJHRoaXMtPm5ld2x5Q3JlYXRlZCkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoIlxuIi4nPGVycm9yPkluc3RhbGxhdGlvbiBmYWlsZWQsIGRlbGV0aW5nICcuJHRoaXMtPmZpbGUuJy48L2Vycm9yPicpOwogICAgICAgICAgICB1bmxpbmsoJHRoaXMtPmpzb24tPmdldFBhdGgoKSk7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGhpcy0+bG9jaykpIHsKICAgICAgICAgICAgICAgIHVubGluaygkdGhpcy0+bG9jayk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbXNnID0gJyB0byBpdHMgJzsKICAgICAgICAgICAgaWYgKCR0aGlzLT5sb2NrQmFja3VwKSB7CiAgICAgICAgICAgICAgICAkbXNnID0gJyBhbmQgJy4kdGhpcy0+bG9jay4nIHRvIHRoZWlyICc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCJcbiIuJzxlcnJvcj5JbnN0YWxsYXRpb24gZmFpbGVkLCByZXZlcnRpbmcgJy4kdGhpcy0+ZmlsZS4kbXNnLidvcmlnaW5hbCBjb250ZW50LjwvZXJyb3I+Jyk7CiAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCR0aGlzLT5qc29uLT5nZXRQYXRoKCksICR0aGlzLT5jb21wb3NlckJhY2t1cCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bG9ja0JhY2t1cCkgewogICAgICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPmxvY2ssICR0aGlzLT5sb2NrQmFja3VwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRoYXJkRXhpdCkgewogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwoKLyoqCiAqIEBhdXRob3IgTmllbHMgS2V1cmVudGplcyA8bmllbHMua2V1cmVudGplc0BvbWluZXMuY29tPgogKi8KY2xhc3MgRGVwZW5kc0NvbW1hbmQgZXh0ZW5kcyBCYXNlRGVwZW5kZW5jeUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBDb25maWd1cmUgY29tbWFuZCBtZXRhZGF0YS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdkZXBlbmRzJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCd3aHknKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3Mgd2hpY2ggcGFja2FnZXMgY2F1c2UgdGhlIGdpdmVuIHBhY2thZ2UgdG8gYmUgaW5zdGFsbGVkLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KHNlbGY6OkFSR1VNRU5UX1BBQ0tBR0UsIElucHV0QXJndW1lbnQ6OlJFUVVJUkVELCAnUGFja2FnZSB0byBpbnNwZWN0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oc2VsZjo6T1BUSU9OX1JFQ1VSU0lWRSwgJ3InLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JlY3Vyc2l2ZWx5IHJlc29sdmVzIHVwIHRvIHRoZSByb290IHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbihzZWxmOjpPUFRJT05fVFJFRSwgJ3QnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1ByaW50cyB0aGUgcmVzdWx0cyBhcyBhIG5lc3RlZCB0cmVlJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApEaXNwbGF5cyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCB3aGVyZSBhIHBhY2thZ2UgaXMgcmVmZXJlbmNlZC4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGRlcGVuZHMgY29tcG9zZXIvY29tcG9zZXI8L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNkZXBlbmRzLXdoeS0KRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIHJldHVybiBwYXJlbnQ6OmRvRXhlY3V0ZSgkaW5wdXQsICRvdXRwdXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXElnbm9yZUFsbFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcUHJvamVjdEluc3RhbGxlcjsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25TZWxlY3RvcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRBcnJheVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQ7CnVzZSBDb21wb3NlclxTY3JpcHRcU2NyaXB0RXZlbnRzOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEZpbmRlcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxDb25maWdcSnNvbkNvbmZpZ1NvdXJjZTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwoKLyoqCiAqIEluc3RhbGwgYSBwYWNrYWdlIGFzIG5ldyBwcm9qZWN0IGludG8gbmV3IGRpcmVjdG9yeS4KICoKICogQGF1dGhvciBCZW5qYW1pbiBFYmVybGVpIDxrb250YWt0QGJlYmVybGVpLmRlPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgVG9iaWFzIE11bmsgPHNjaG11bmtAdXNyYmluLmRlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQ3JlYXRlUHJvamVjdENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEB2YXIgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJHN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdjcmVhdGUtcHJvamVjdCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0NyZWF0ZXMgbmV3IHByb2plY3QgZnJvbSBhIHBhY2thZ2UgaW50byBnaXZlbiBkaXJlY3RvcnkuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2UnLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2UgbmFtZSB0byBiZSBpbnN0YWxsZWQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdkaXJlY3RvcnknLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ0RpcmVjdG9yeSB3aGVyZSB0aGUgZmlsZXMgc2hvdWxkIGJlIGNyZWF0ZWQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCd2ZXJzaW9uJywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdWZXJzaW9uLCB3aWxsIGRlZmF1bHQgdG8gbGF0ZXN0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3N0YWJpbGl0eScsICdzJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnTWluaW11bS1zdGFiaWxpdHkgYWxsb3dlZCAodW5sZXNzIGEgdmVyc2lvbiBpcyBzcGVjaWZpZWQpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc291cmNlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBzb3VyY2VzIHdoZW4gcG9zc2libGUsIGluY2x1ZGluZyBWQ1MgaW5mb3JtYXRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1kaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0IChkZWZhdWx0IGJlaGF2aW9yKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWluc3RhbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0fHNvdXJjZXxhdXRvIChhdXRvIGNob29zZXMgc291cmNlIGZvciBkZXYgdmVyc2lvbnMsIGRpc3QgZm9yIHRoZSByZXN0KS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVwb3NpdG9yeScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0FkZCBjdXN0b20gcmVwb3NpdG9yaWVzIHRvIGxvb2sgdGhlIHBhY2thZ2UgdXAsIGVpdGhlciBieSBVUkwgb3IgdXNpbmcgSlNPTiBhcnJheXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVwb3NpdG9yeS11cmwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdERVBSRUNBVEVEOiBVc2UgLS1yZXBvc2l0b3J5IGluc3RlYWQuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FkZC1yZXBvc2l0b3J5JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBZGQgdGhlIGN1c3RvbSByZXBvc2l0b3J5IGluIHRoZSBjb21wb3Nlci5qc29uLiBJZiBhIGxvY2sgZmlsZSBpcyBwcmVzZW50IGl0IHdpbGwgYmUgZGVsZXRlZCBhbmQgYW4gdXBkYXRlIHdpbGwgYmUgcnVuIGluc3RlYWQgb2YgaW5zdGFsbC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdFbmFibGVzIGluc3RhbGxhdGlvbiBvZiByZXF1aXJlLWRldiBwYWNrYWdlcyAoZW5hYmxlZCBieSBkZWZhdWx0LCBvbmx5IHByZXNlbnQgZm9yIEJDKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyBpbnN0YWxsYXRpb24gb2YgcmVxdWlyZS1kZXYgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWN1c3RvbS1pbnN0YWxsZXJzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdERVBSRUNBVEVEOiBVc2Ugbm8tcGx1Z2lucyBpbnN0ZWFkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zY3JpcHRzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIHByZXZlbnQgZXhlY3V0aW9uIG9mIGFsbCBkZWZpbmVkIHNjcmlwdHMgaW4gdGhlIHJvb3QgcGFja2FnZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tcHJvZ3Jlc3MnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCBvdXRwdXQgZG93bmxvYWQgcHJvZ3Jlc3MuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXNlY3VyZS1odHRwJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlIHRoZSBzZWN1cmUtaHR0cCBjb25maWcgb3B0aW9uIHRlbXBvcmFyaWx5IHdoaWxlIGluc3RhbGxpbmcgdGhlIHJvb3QgcGFja2FnZS4gVXNlIGF0IHlvdXIgb3duIHJpc2suIFVzaW5nIHRoaXMgZmxhZyBpcyBhIGJhZCBpZGVhLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdrZWVwLXZjcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnV2hldGhlciB0byBwcmV2ZW50IGRlbGV0aW5nIHRoZSB2Y3MgZm9sZGVyLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyZW1vdmUtdmNzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIGZvcmNlIGRlbGV0aW9uIG9mIHRoZSB2Y3MgZm9sZGVyIHdpdGhvdXQgcHJvbXB0aW5nLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1pbnN0YWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIHNraXAgaW5zdGFsbGF0aW9uIG9mIHRoZSBwYWNrYWdlIGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0lnbm9yZSBhbGwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXNrJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIGFzayBmb3IgcHJvamVjdCBkaXJlY3RvcnkuJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+Y3JlYXRlLXByb2plY3Q8L2luZm8+IGNvbW1hbmQgY3JlYXRlcyBhIG5ldyBwcm9qZWN0IGZyb20gYSBnaXZlbgpwYWNrYWdlIGludG8gYSBuZXcgZGlyZWN0b3J5LiBJZiBleGVjdXRlZCB3aXRob3V0IHBhcmFtcyBhbmQgaW4gYSBkaXJlY3RvcnkKd2l0aCBhIGNvbXBvc2VyLmpzb24gZmlsZSBpdCBpbnN0YWxscyB0aGUgcGFja2FnZXMgZm9yIHRoZSBjdXJyZW50IHByb2plY3QuCgpZb3UgY2FuIHVzZSB0aGlzIGNvbW1hbmQgdG8gYm9vdHN0cmFwIG5ldyBwcm9qZWN0cyBvciBzZXR1cCBhIGNsZWFuCnZlcnNpb24tY29udHJvbGxlZCBpbnN0YWxsYXRpb24gZm9yIGRldmVsb3BlcnMgb2YgeW91ciBwcm9qZWN0LgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgY3JlYXRlLXByb2plY3QgdmVuZG9yL3Byb2plY3QgdGFyZ2V0LWRpcmVjdG9yeSBbdmVyc2lvbl08L2luZm8+CgpZb3UgY2FuIGFsc28gc3BlY2lmeSB0aGUgdmVyc2lvbiB3aXRoIHRoZSBwYWNrYWdlIG5hbWUgdXNpbmcgPSBvciA6IGFzIHNlcGFyYXRvci4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGNyZWF0ZS1wcm9qZWN0IHZlbmRvci9wcm9qZWN0OnZlcnNpb24gdGFyZ2V0LWRpcmVjdG9yeTwvaW5mbz4KClRvIGluc3RhbGwgdW5zdGFibGUgcGFja2FnZXMsIGVpdGhlciBzcGVjaWZ5IHRoZSB2ZXJzaW9uIHlvdSB3YW50LCBvciB1c2UgdGhlCi0tc3RhYmlsaXR5PWRldiAod2hlcmUgZGV2IGNhbiBiZSBvbmUgb2YgUkMsIGJldGEsIGFscGhhIG9yIGRldikuCgpUbyBzZXR1cCBhIGRldmVsb3BlciB3b3JrYWJsZSB2ZXJzaW9uIHlvdSBzaG91bGQgY3JlYXRlIHRoZSBwcm9qZWN0IHVzaW5nIHRoZSBzb3VyY2UKY29udHJvbGxlZCBjb2RlIGJ5IGFwcGVuZGluZyB0aGUgPGluZm8+Jy0tcHJlZmVyLXNvdXJjZSc8L2luZm8+IGZsYWcuCgpUbyBpbnN0YWxsIGEgcGFja2FnZSBmcm9tIGFub3RoZXIgcmVwb3NpdG9yeSB0aGFuIHRoZSBkZWZhdWx0IG9uZSB5b3UKY2FuIHBhc3MgdGhlIDxpbmZvPictLXJlcG9zaXRvcnk9aHR0cHM6Ly9teXJlcG9zaXRvcnkub3JnJzwvaW5mbz4gZmxhZy4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI2NyZWF0ZS1wcm9qZWN0CkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGxpc3QoJHByZWZlclNvdXJjZSwgJHByZWZlckRpc3QpID0gJHRoaXMtPmdldFByZWZlcnJlZEluc3RhbGxPcHRpb25zKCRjb25maWcsICRpbnB1dCwgdHJ1ZSk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGV2JykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBkZXByZWNhdGVkIG9wdGlvbiAiZGV2Ii4gRGV2IHBhY2thZ2VzIGFyZSBpbnN0YWxsZWQgYnkgZGVmYXVsdCBub3cuPC93YXJuaW5nPicpOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLWN1c3RvbS1pbnN0YWxsZXJzJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBkZXByZWNhdGVkIG9wdGlvbiAibm8tY3VzdG9tLWluc3RhbGxlcnMiLiBVc2UgIm5vLXBsdWdpbnMiIGluc3RlYWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignbm8tcGx1Z2lucycsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+aXNJbnRlcmFjdGl2ZSgpICYmICRpbnB1dC0+Z2V0T3B0aW9uKCdhc2snKSkgewogICAgICAgICAgICAkcGFydHMgPSBleHBsb2RlKCIvIiwgc3RydG9sb3dlcigkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJykpLCAyKTsKICAgICAgICAgICAgJGlucHV0LT5zZXRBcmd1bWVudCgnZGlyZWN0b3J5JywgJGlvLT5hc2soJ05ldyBwcm9qZWN0IGRpcmVjdG9yeSBbPGNvbW1lbnQ+Jy5hcnJheV9wb3AoJHBhcnRzKS4nPC9jb21tZW50Pl06ICcpKTsKICAgICAgICB9CgogICAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSAkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnKSA/OiAoJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnKSA/OiBmYWxzZSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+aW5zdGFsbFByb2plY3QoCiAgICAgICAgICAgICRpbywKICAgICAgICAgICAgJGNvbmZpZywKICAgICAgICAgICAgJGlucHV0LAogICAgICAgICAgICAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0QXJndW1lbnQoJ2RpcmVjdG9yeScpLAogICAgICAgICAgICAkaW5wdXQtPmdldEFyZ3VtZW50KCd2ZXJzaW9uJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCdzdGFiaWxpdHknKSwKICAgICAgICAgICAgJHByZWZlclNvdXJjZSwKICAgICAgICAgICAgJHByZWZlckRpc3QsCiAgICAgICAgICAgICEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCdyZXBvc2l0b3J5JykgPzogJGlucHV0LT5nZXRPcHRpb24oJ3JlcG9zaXRvcnktdXJsJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCduby1wbHVnaW5zJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCduby1zY3JpcHRzJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCduby1wcm9ncmVzcycpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignbm8taW5zdGFsbCcpLAogICAgICAgICAgICBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6ZnJvbUJvb2xPckxpc3QoJGlnbm9yZVBsYXRmb3JtUmVxcyksCiAgICAgICAgICAgICEkaW5wdXQtPmdldE9wdGlvbignbm8tc2VjdXJlLWh0dHAnKSwKICAgICAgICAgICAgJGlucHV0LT5nZXRPcHRpb24oJ2FkZC1yZXBvc2l0b3J5JykKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICAgICAgICAgICAkZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICAgICAgICAgICAkcGFja2FnZVZlcnNpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRzdGFiaWxpdHkKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRwcmVmZXJTb3VyY2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRwcmVmZXJEaXN0CiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbERldlBhY2thZ2VzCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5PHN0cmluZz58bnVsbCAkcmVwb3NpdG9yaWVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAkZGlzYWJsZVBsdWdpbnMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRkaXNhYmxlU2NyaXB0cwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAgICAgJG5vUHJvZ3Jlc3MKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRub0luc3RhbGwKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRzZWN1cmVIdHRwCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAkYWRkUmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGxQcm9qZWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIElucHV0SW50ZXJmYWNlICRpbnB1dCwgJHBhY2thZ2VOYW1lID0gbnVsbCwgJGRpcmVjdG9yeSA9IG51bGwsICRwYWNrYWdlVmVyc2lvbiA9IG51bGwsICRzdGFiaWxpdHkgPSAnc3RhYmxlJywgJHByZWZlclNvdXJjZSA9IGZhbHNlLCAkcHJlZmVyRGlzdCA9IGZhbHNlLCAkaW5zdGFsbERldlBhY2thZ2VzID0gZmFsc2UsICRyZXBvc2l0b3JpZXMgPSBudWxsLCAkZGlzYWJsZVBsdWdpbnMgPSBmYWxzZSwgJGRpc2FibGVTY3JpcHRzID0gZmFsc2UsICRub1Byb2dyZXNzID0gZmFsc2UsICRub0luc3RhbGwgPSBmYWxzZSwgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZSAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciA9IG51bGwsICRzZWN1cmVIdHRwID0gdHJ1ZSwgJGFkZFJlcG9zaXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICAkb2xkQ3dkID0gZ2V0Y3dkKCk7CgogICAgICAgIGlmICgkcmVwb3NpdG9yaWVzICE9PSBudWxsICYmICFpc19hcnJheSgkcmVwb3NpdG9yaWVzKSkgewogICAgICAgICAgICAkcmVwb3NpdG9yaWVzID0gKGFycmF5KSAkcmVwb3NpdG9yaWVzOwogICAgICAgIH0KCiAgICAgICAgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIgPSAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciA/OiBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6aWdub3JlTm90aGluZygpOwoKICAgICAgICAvLyB3ZSBuZWVkIHRvIG1hbnVhbGx5IGxvYWQgdGhlIGNvbmZpZ3VyYXRpb24gdG8gcGFzcyB0aGUgYXV0aCBjcmVkZW50aWFscyB0byB0aGUgaW8gaW50ZXJmYWNlIQogICAgICAgICRpby0+bG9hZENvbmZpZ3VyYXRpb24oJGNvbmZpZyk7CgogICAgICAgICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyID0gbmV3IFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIoJGlvKTsKCiAgICAgICAgaWYgKCRwYWNrYWdlTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAkaW5zdGFsbGVkRnJvbVZjcyA9ICR0aGlzLT5pbnN0YWxsUm9vdFBhY2thZ2UoJGlvLCAkY29uZmlnLCAkcGFja2FnZU5hbWUsICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLCAkZGlyZWN0b3J5LCAkcGFja2FnZVZlcnNpb24sICRzdGFiaWxpdHksICRwcmVmZXJTb3VyY2UsICRwcmVmZXJEaXN0LCAkaW5zdGFsbERldlBhY2thZ2VzLCAkcmVwb3NpdG9yaWVzLCAkZGlzYWJsZVBsdWdpbnMsICRkaXNhYmxlU2NyaXB0cywgJG5vUHJvZ3Jlc3MsICRzZWN1cmVIdHRwKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaW5zdGFsbGVkRnJvbVZjcyA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXBvc2l0b3JpZXMgIT09IG51bGwgJiYgJGFkZFJlcG9zaXRvcnkgJiYgaXNfZmlsZSgnY29tcG9zZXIubG9jaycpKSB7CiAgICAgICAgICAgIHVubGluaygnY29tcG9zZXIubG9jaycpOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gRmFjdG9yeTo6Y3JlYXRlKCRpbywgbnVsbCwgJGRpc2FibGVQbHVnaW5zLCAkZGlzYWJsZVNjcmlwdHMpOwoKICAgICAgICAvLyBhZGQgdGhlIHJlcG9zaXRvcnkgdG8gdGhlIGNvbXBvc2VyLmpzb24gYW5kIHVzZSBpdCBmb3IgdGhlIGluc3RhbGwgcnVuIGxhdGVyCiAgICAgICAgaWYgKCRyZXBvc2l0b3JpZXMgIT09IG51bGwgJiYgJGFkZFJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcmllcyBhcyAkaW5kZXggPT4gJHJlcG8pIHsKICAgICAgICAgICAgICAgICRyZXBvQ29uZmlnID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmNvbmZpZ0Zyb21TdHJpbmcoJGlvLCAkY29tcG9zZXItPmdldENvbmZpZygpLCAkcmVwbywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAkY29tcG9zZXJKc29uUmVwb3NpdG9yaWVzQ29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0UmVwb3NpdG9yaWVzKCk7CiAgICAgICAgICAgICAgICAkbmFtZSA9IFJlcG9zaXRvcnlGYWN0b3J5OjpnZW5lcmF0ZVJlcG9zaXRvcnlOYW1lKCRpbmRleCwgJHJlcG9Db25maWcsICRjb21wb3Nlckpzb25SZXBvc2l0b3JpZXNDb25maWcpOwogICAgICAgICAgICAgICAgJGNvbmZpZ1NvdXJjZSA9IG5ldyBKc29uQ29uZmlnU291cmNlKG5ldyBKc29uRmlsZSgnY29tcG9zZXIuanNvbicpKTsKCiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKGlzc2V0KCRyZXBvQ29uZmlnWydwYWNrYWdpc3QnXSkgJiYgJHJlcG9Db25maWcgPT09IGFycmF5KCdwYWNrYWdpc3QnID0+IGZhbHNlKSkKICAgICAgICAgICAgICAgICAgICB8fCAoaXNzZXQoJHJlcG9Db25maWdbJ3BhY2thZ2lzdC5vcmcnXSkgJiYgJHJlcG9Db25maWcgPT09IGFycmF5KCdwYWNrYWdpc3Qub3JnJyA9PiBmYWxzZSkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnU291cmNlLT5hZGRSZXBvc2l0b3J5KCdwYWNrYWdpc3Qub3JnJywgZmFsc2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnU291cmNlLT5hZGRSZXBvc2l0b3J5KCRuYW1lLCAkcmVwb0NvbmZpZywgZmFsc2UpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRjb21wb3NlciA9IEZhY3Rvcnk6OmNyZWF0ZSgkaW8sIG51bGwsICRkaXNhYmxlUGx1Z2lucyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCRwcm9jZXNzKTsKCiAgICAgICAgLy8gZGlzcGF0Y2ggZXZlbnQKICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBPU1RfUk9PVF9QQUNLQUdFX0lOU1RBTEwsICRpbnN0YWxsRGV2UGFja2FnZXMpOwoKICAgICAgICAvLyB1c2UgdGhlIG5ldyBjb25maWcgaW5jbHVkaW5nIHRoZSBuZXdseSBpbnN0YWxsZWQgcHJvamVjdAogICAgICAgICRjb25maWcgPSAkY29tcG9zZXItPmdldENvbmZpZygpOwogICAgICAgIGxpc3QoJHByZWZlclNvdXJjZSwgJHByZWZlckRpc3QpID0gJHRoaXMtPmdldFByZWZlcnJlZEluc3RhbGxPcHRpb25zKCRjb25maWcsICRpbnB1dCk7CgogICAgICAgIC8vIGluc3RhbGwgZGVwZW5kZW5jaWVzIG9mIHRoZSBjcmVhdGVkIHByb2plY3QKICAgICAgICBpZiAoJG5vSW5zdGFsbCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPnNldE91dHB1dFByb2dyZXNzKCEkbm9Qcm9ncmVzcyk7CgogICAgICAgICAgICAkaW5zdGFsbGVyID0gSW5zdGFsbGVyOjpjcmVhdGUoJGlvLCAkY29tcG9zZXIpOwogICAgICAgICAgICAkaW5zdGFsbGVyLT5zZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgICAgICAgICAgICAgIC0+c2V0UHJlZmVyRGlzdCgkcHJlZmVyRGlzdCkKICAgICAgICAgICAgICAgIC0+c2V0RGV2TW9kZSgkaW5zdGFsbERldlBhY2thZ2VzKQogICAgICAgICAgICAgICAgLT5zZXRQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKQogICAgICAgICAgICAgICAgLT5zZXRTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKCR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKQogICAgICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJGNvbmZpZy0+Z2V0KCdvcHRpbWl6ZS1hdXRvbG9hZGVyJykpCiAgICAgICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkY29uZmlnLT5nZXQoJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnKSkKICAgICAgICAgICAgICAgIC0+c2V0QXBjdUF1dG9sb2FkZXIoJGNvbmZpZy0+Z2V0KCdhcGN1LWF1dG9sb2FkZXInKSk7CgogICAgICAgICAgICBpZiAoISRjb21wb3Nlci0+Z2V0TG9ja2VyKCktPmlzTG9ja2VkKCkpIHsKICAgICAgICAgICAgICAgICRpbnN0YWxsZXItPnNldFVwZGF0ZSh0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRkaXNhYmxlUGx1Z2lucykgewogICAgICAgICAgICAgICAgJGluc3RhbGxlci0+ZGlzYWJsZVBsdWdpbnMoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHN0YXR1cyA9ICRpbnN0YWxsZXItPnJ1bigpOwogICAgICAgICAgICBpZiAoMCAhPT0gJHN0YXR1cykgewogICAgICAgICAgICAgICAgcmV0dXJuICRzdGF0dXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRoYXNWY3MgPSAkaW5zdGFsbGVkRnJvbVZjczsKICAgICAgICBpZiAoCiAgICAgICAgICAgICEkaW5wdXQtPmdldE9wdGlvbigna2VlcC12Y3MnKQogICAgICAgICAgICAmJiAkaW5zdGFsbGVkRnJvbVZjcwogICAgICAgICAgICAmJiAoCiAgICAgICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbigncmVtb3ZlLXZjcycpCiAgICAgICAgICAgICAgICB8fCAhJGlvLT5pc0ludGVyYWN0aXZlKCkKICAgICAgICAgICAgICAgIHx8ICRpby0+YXNrQ29uZmlybWF0aW9uKCc8aW5mbz5EbyB5b3Ugd2FudCB0byByZW1vdmUgdGhlIGV4aXN0aW5nIFZDUyAoLmdpdCwgLnN2bi4uKSBoaXN0b3J5PzwvaW5mbz4gWzxjb21tZW50PlksbjwvY29tbWVudD5dPyAnKQogICAgICAgICAgICApCiAgICAgICAgKSB7CiAgICAgICAgICAgICRmaW5kZXIgPSBuZXcgRmluZGVyKCk7CiAgICAgICAgICAgICRmaW5kZXItPmRlcHRoKDApLT5kaXJlY3RvcmllcygpLT5pbihnZXRjd2QoKSktPmlnbm9yZVZDUyhmYWxzZSktPmlnbm9yZURvdEZpbGVzKGZhbHNlKTsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJy5zdm4nLCAnX3N2bicsICdDVlMnLCAnX2RhcmNzJywgJy5hcmNoLXBhcmFtcycsICcubW9ub3RvbmUnLCAnLmJ6cicsICcuZ2l0JywgJy5oZycsICcuZnNsY2tvdXQnLCAnX0ZPU1NJTF8nKSBhcyAkdmNzTmFtZSkgewogICAgICAgICAgICAgICAgJGZpbmRlci0+bmFtZSgkdmNzTmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkZGlycyA9IGl0ZXJhdG9yX3RvX2FycmF5KCRmaW5kZXIpOwogICAgICAgICAgICAgICAgdW5zZXQoJGZpbmRlcik7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGlycyBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkZnMtPnJlbW92ZURpcmVjdG9yeSgkZGlyKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCByZW1vdmUgJy4kZGlyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkFuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlbW92aW5nIHRoZSBWQ1MgbWV0YWRhdGE6ICcuJGUtPmdldE1lc3NhZ2UoKS4nPC9lcnJvcj4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGhhc1ZjcyA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gcmV3cml0aW5nIHNlbGYudmVyc2lvbiBkZXBlbmRlbmNpZXMgd2l0aCBleHBsaWNpdCB2ZXJzaW9uIG51bWJlcnMgaWYgdGhlIHBhY2thZ2UncyB2Y3MgbWV0YWRhdGEgaXMgZ29uZQogICAgICAgIGlmICghJGhhc1ZjcykgewogICAgICAgICAgICAkcGFja2FnZSA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICAkY29uZmlnU291cmNlID0gbmV3IEpzb25Db25maWdTb3VyY2UobmV3IEpzb25GaWxlKCdjb21wb3Nlci5qc29uJykpOwogICAgICAgICAgICBmb3JlYWNoIChCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlcyBhcyAkdHlwZSA9PiAkbWV0YSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPnsnZ2V0Jy4kbWV0YVsnbWV0aG9kJ119KCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSA9PT0gJ3NlbGYudmVyc2lvbicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1NvdXJjZS0+YWRkTGluaygkdHlwZSwgJGxpbmstPmdldFRhcmdldCgpLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGRpc3BhdGNoIGV2ZW50CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2hTY3JpcHQoU2NyaXB0RXZlbnRzOjpQT1NUX0NSRUFURV9QUk9KRUNUX0NNRCwgJGluc3RhbGxEZXZQYWNrYWdlcyk7CgogICAgICAgIGNoZGlyKCRvbGRDd2QpOwogICAgICAgICR2ZW5kb3JDb21wb3NlckRpciA9ICRjb25maWctPmdldCgndmVuZG9yLWRpcicpLicvY29tcG9zZXInOwogICAgICAgIGlmIChpc19kaXIoJHZlbmRvckNvbXBvc2VyRGlyKSAmJiAkZnMtPmlzRGlyRW1wdHkoJHZlbmRvckNvbXBvc2VyRGlyKSkgewogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgncm1kaXInLCAkdmVuZG9yQ29tcG9zZXJEaXIpOwogICAgICAgICAgICAkdmVuZG9yRGlyID0gJGNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJyk7CiAgICAgICAgICAgIGlmIChpc19kaXIoJHZlbmRvckRpcikgJiYgJGZzLT5pc0RpckVtcHR5KCR2ZW5kb3JEaXIpKSB7CiAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgncm1kaXInLCAkdmVuZG9yRGlyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAgICAgICAkZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICAgICRwYWNrYWdlVmVyc2lvbgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAgICAgICAkc3RhYmlsaXR5CiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICRwcmVmZXJTb3VyY2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgJHByZWZlckRpc3QKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgJGluc3RhbGxEZXZQYWNrYWdlcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZz58bnVsbCAkcmVwb3NpdG9yaWVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICRkaXNhYmxlUGx1Z2lucwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAkZGlzYWJsZVNjcmlwdHMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgJG5vUHJvZ3Jlc3MKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgJHNlY3VyZUh0dHAKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbFJvb3RQYWNrYWdlKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICRwYWNrYWdlTmFtZSwgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZSAkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciwgJGRpcmVjdG9yeSA9IG51bGwsICRwYWNrYWdlVmVyc2lvbiA9IG51bGwsICRzdGFiaWxpdHkgPSAnc3RhYmxlJywgJHByZWZlclNvdXJjZSA9IGZhbHNlLCAkcHJlZmVyRGlzdCA9IGZhbHNlLCAkaW5zdGFsbERldlBhY2thZ2VzID0gZmFsc2UsIGFycmF5ICRyZXBvc2l0b3JpZXMgPSBudWxsLCAkZGlzYWJsZVBsdWdpbnMgPSBmYWxzZSwgJGRpc2FibGVTY3JpcHRzID0gZmFsc2UsICRub1Byb2dyZXNzID0gZmFsc2UsICRzZWN1cmVIdHRwID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoISRzZWN1cmVIdHRwKSB7CiAgICAgICAgICAgICRjb25maWctPm1lcmdlKGFycmF5KCdjb25maWcnID0+IGFycmF5KCdzZWN1cmUtaHR0cCcgPT4gZmFsc2UpKSwgQ29uZmlnOjpTT1VSQ0VfQ09NTUFORCk7CiAgICAgICAgfQoKICAgICAgICAkcGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAkcmVxdWlyZW1lbnRzID0gJHBhcnNlci0+cGFyc2VOYW1lVmVyc2lvblBhaXJzKGFycmF5KCRwYWNrYWdlTmFtZSkpOwogICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkcmVxdWlyZW1lbnRzWzBdWyduYW1lJ10pOwogICAgICAgIGlmICghJHBhY2thZ2VWZXJzaW9uICYmIGlzc2V0KCRyZXF1aXJlbWVudHNbMF1bJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2VWZXJzaW9uID0gJHJlcXVpcmVtZW50c1swXVsndmVyc2lvbiddOwogICAgICAgIH0KCiAgICAgICAgLy8gaWYgbm8gZGlyZWN0b3J5IHdhcyBzcGVjaWZpZWQsIHVzZSB0aGUgMm5kIHBhcnQgb2YgdGhlIHBhY2thZ2UgbmFtZQogICAgICAgIGlmIChudWxsID09PSAkZGlyZWN0b3J5KSB7CiAgICAgICAgICAgICRwYXJ0cyA9IGV4cGxvZGUoIi8iLCAkbmFtZSwgMik7CiAgICAgICAgICAgICRkaXJlY3RvcnkgPSBnZXRjd2QoKSAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiBhcnJheV9wb3AoJHBhcnRzKTsKICAgICAgICB9CgogICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCRwcm9jZXNzKTsKICAgICAgICBpZiAoISRmcy0+aXNBYnNvbHV0ZVBhdGgoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgJGRpcmVjdG9yeSA9IGdldGN3ZCgpIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRkaXJlY3Rvcnk7CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPkNyZWF0aW5nIGEgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBwcm9qZWN0IGF0ICInIC4gJGZzLT5maW5kU2hvcnRlc3RQYXRoKGdldGN3ZCgpLCAkZGlyZWN0b3J5LCB0cnVlKSAuICciPC9pbmZvPicpOwoKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgaWYgKCFpc19kaXIoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdDYW5ub3QgY3JlYXRlIHByb2plY3QgZGlyZWN0b3J5IGF0ICInLiRkaXJlY3RvcnkuJyIsIGl0IGV4aXN0cyBhcyBhIGZpbGUuJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkZnMtPmlzRGlyRW1wdHkoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQcm9qZWN0IGRpcmVjdG9yeSAiJy4kZGlyZWN0b3J5LiciIGlzIG5vdCBlbXB0eS4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRzdGFiaWxpdHkpIHsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRwYWNrYWdlVmVyc2lvbikgewogICAgICAgICAgICAgICAgJHN0YWJpbGl0eSA9ICdzdGFibGUnOwogICAgICAgICAgICB9IGVsc2VpZiAoUHJlZzo6aXNNYXRjaCgne15bXixcc10qP0AoJy5pbXBsb2RlKCd8JywgYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzKSkuJykkfWknLCAkcGFja2FnZVZlcnNpb24sICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICRzdGFiaWxpdHkgPSAkbWF0Y2hbMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkc3RhYmlsaXR5ID0gVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHBhY2thZ2VWZXJzaW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHN0YWJpbGl0eSA9IFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkc3RhYmlsaXR5KTsKCiAgICAgICAgaWYgKCFpc3NldChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzWyRzdGFiaWxpdHldKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignSW52YWxpZCBzdGFiaWxpdHkgcHJvdmlkZWQgKCcuJHN0YWJpbGl0eS4nKSwgbXVzdCBiZSBvbmUgb2Y6ICcuaW1wbG9kZSgnLCAnLCBhcnJheV9rZXlzKEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMpKSk7CiAgICAgICAgfQoKICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGUoJGlvLCAkY29uZmlnLT5hbGwoKSwgJGRpc2FibGVQbHVnaW5zKTsKICAgICAgICAkY29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKTsKICAgICAgICAkcm0gPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCk7CgogICAgICAgICRyZXBvc2l0b3J5U2V0ID0gbmV3IFJlcG9zaXRvcnlTZXQoJHN0YWJpbGl0eSk7CiAgICAgICAgaWYgKG51bGwgPT09ICRyZXBvc2l0b3JpZXMpIHsKICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkobmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoUmVwb3NpdG9yeUZhY3Rvcnk6OmRlZmF1bHRSZXBvcygkaW8sICRjb25maWcsICRybSkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3NpdG9yaWVzIGFzICRyZXBvKSB7CiAgICAgICAgICAgICAgICAkcmVwb0NvbmZpZyA9IFJlcG9zaXRvcnlGYWN0b3J5Ojpjb25maWdGcm9tU3RyaW5nKCRpbywgJGNvbmZpZywgJHJlcG8sIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIChpc3NldCgkcmVwb0NvbmZpZ1sncGFja2FnaXN0J10pICYmICRyZXBvQ29uZmlnID09PSBhcnJheSgncGFja2FnaXN0JyA9PiBmYWxzZSkpCiAgICAgICAgICAgICAgICAgICAgfHwgKGlzc2V0KCRyZXBvQ29uZmlnWydwYWNrYWdpc3Qub3JnJ10pICYmICRyZXBvQ29uZmlnID09PSBhcnJheSgncGFja2FnaXN0Lm9yZycgPT4gZmFsc2UpKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcmVwb3NpdG9yeVNldC0+YWRkUmVwb3NpdG9yeShSZXBvc2l0b3J5RmFjdG9yeTo6Y3JlYXRlUmVwbygkaW8sICRjb25maWcsICRyZXBvQ29uZmlnLCAkcm0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHBsYXRmb3JtT3ZlcnJpZGVzID0gJGNvbmZpZy0+Z2V0KCdwbGF0Zm9ybScpID86IGFycmF5KCk7CiAgICAgICAgJHBsYXRmb3JtUmVwbyA9IG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkoYXJyYXkoKSwgJHBsYXRmb3JtT3ZlcnJpZGVzKTsKCiAgICAgICAgLy8gZmluZCB0aGUgbGF0ZXN0IHZlcnNpb24gaWYgdGhlcmUgYXJlIG11bHRpcGxlCiAgICAgICAgJHZlcnNpb25TZWxlY3RvciA9IG5ldyBWZXJzaW9uU2VsZWN0b3IoJHJlcG9zaXRvcnlTZXQsICRwbGF0Zm9ybVJlcG8pOwogICAgICAgICRwYWNrYWdlID0gJHZlcnNpb25TZWxlY3Rvci0+ZmluZEJlc3RDYW5kaWRhdGUoJG5hbWUsICRwYWNrYWdlVmVyc2lvbiwgJHN0YWJpbGl0eSwgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwoKICAgICAgICBpZiAoISRwYWNrYWdlKSB7CiAgICAgICAgICAgICRlcnJvck1lc3NhZ2UgPSAiQ291bGQgbm90IGZpbmQgcGFja2FnZSAkbmFtZSB3aXRoICIgLiAoJHBhY2thZ2VWZXJzaW9uID8gInZlcnNpb24gJHBhY2thZ2VWZXJzaW9uIiA6ICJzdGFiaWxpdHkgJHN0YWJpbGl0eSIpOwogICAgICAgICAgICBpZiAoISgkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbnN0YW5jZW9mIElnbm9yZUFsbFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpICYmICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCAkcGFja2FnZVZlcnNpb24sICRzdGFiaWxpdHksIFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5OjppZ25vcmVBbGwoKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCRlcnJvck1lc3NhZ2UgLicgaW4gYSB2ZXJzaW9uIGluc3RhbGxhYmxlIHVzaW5nIHlvdXIgUEhQIHZlcnNpb24sIFBIUCBleHRlbnNpb25zIGFuZCBDb21wb3NlciB2ZXJzaW9uLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigkZXJyb3JNZXNzYWdlIC4nLicpOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlciBDdHJsK0MgZm9yIHVuaXgtbGlrZSBzeXN0ZW1zCiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygncGNudGxfYXN5bmNfc2lnbmFscycpICYmIGZ1bmN0aW9uX2V4aXN0cygncGNudGxfc2lnbmFsJykpIHsKICAgICAgICAgICAgQG1rZGlyKCRkaXJlY3RvcnksIDA3NzcsIHRydWUpOwogICAgICAgICAgICBpZiAoJHJlYWxEaXIgPSByZWFscGF0aCgkZGlyZWN0b3J5KSkgewogICAgICAgICAgICAgICAgcGNudGxfYXN5bmNfc2lnbmFscyh0cnVlKTsKICAgICAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsIGZ1bmN0aW9uICgpIHVzZSAoJHJlYWxEaXIpIHsKICAgICAgICAgICAgICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICAgICAgICAgICAgICRmcy0+cmVtb3ZlRGlyZWN0b3J5KCRyZWFsRGlyKTsKICAgICAgICAgICAgICAgICAgICBleGl0KDEzMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBoYW5kbGVyIEN0cmwrQyBmb3IgV2luZG93cyBvbiBQSFAgNy40KwogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3NhcGlfd2luZG93c19zZXRfY3RybF9oYW5kbGVyJykgJiYgUEhQX1NBUEkgPT09ICdjbGknKSB7CiAgICAgICAgICAgIEBta2RpcigkZGlyZWN0b3J5LCAwNzc3LCB0cnVlKTsKICAgICAgICAgICAgaWYgKCRyZWFsRGlyID0gcmVhbHBhdGgoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgICAgIHNhcGlfd2luZG93c19zZXRfY3RybF9oYW5kbGVyKGZ1bmN0aW9uICgpIHVzZSAoJHJlYWxEaXIpIHsKICAgICAgICAgICAgICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICAgICAgICAgICAgICRmcy0+cmVtb3ZlRGlyZWN0b3J5KCRyZWFsRGlyKTsKICAgICAgICAgICAgICAgICAgICBleGl0KDEzMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gYXZvaWQgZGlzcGxheWluZyA5OTk5OTk5LWRldiBhcyB2ZXJzaW9uIGlmIGRlZmF1bHQtYnJhbmNoIHdhcyBzZWxlY3RlZAogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAkcGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPkluc3RhbGxpbmcgJyAuICRwYWNrYWdlLT5nZXROYW1lKCkgLiAnICgnIC4gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKGZhbHNlKSAuICcpPC9pbmZvPicpOwoKICAgICAgICBpZiAoJGRpc2FibGVQbHVnaW5zKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+UGx1Z2lucyBoYXZlIGJlZW4gZGlzYWJsZWQuPC9pbmZvPicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgICRkbSA9ICRjb21wb3Nlci0+Z2V0RG93bmxvYWRNYW5hZ2VyKCk7CiAgICAgICAgJGRtLT5zZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJEaXN0KCRwcmVmZXJEaXN0KTsKCiAgICAgICAgJHByb2plY3RJbnN0YWxsZXIgPSBuZXcgUHJvamVjdEluc3RhbGxlcigkZGlyZWN0b3J5LCAkZG0sICRmcyk7CiAgICAgICAgJGltID0gJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCk7CiAgICAgICAgJGltLT5zZXRPdXRwdXRQcm9ncmVzcyghJG5vUHJvZ3Jlc3MpOwogICAgICAgICRpbS0+YWRkSW5zdGFsbGVyKCRwcm9qZWN0SW5zdGFsbGVyKTsKICAgICAgICAkaW0tPmV4ZWN1dGUobmV3IEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeSgpLCBhcnJheShuZXcgSW5zdGFsbE9wZXJhdGlvbigkcGFja2FnZSkpKTsKICAgICAgICAkaW0tPm5vdGlmeUluc3RhbGxzKCRpbyk7CgogICAgICAgIC8vIGNvbGxlY3Qgc3VnZ2VzdGlvbnMKICAgICAgICAkdGhpcy0+c3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlci0+YWRkU3VnZ2VzdGlvbnNGcm9tUGFja2FnZSgkcGFja2FnZSk7CgogICAgICAgICRpbnN0YWxsZWRGcm9tVmNzID0gJ3NvdXJjZScgPT09ICRwYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKTsKCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5DcmVhdGVkIHByb2plY3QgaW4gJyAuICRkaXJlY3RvcnkgLiAnPC9pbmZvPicpOwogICAgICAgIGNoZGlyKCRkaXJlY3RvcnkpOwoKICAgICAgICBQbGF0Zm9ybTo6cHV0RW52KCdDT01QT1NFUl9ST09UX1ZFUlNJT04nLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpKTsKCiAgICAgICAgcmV0dXJuICRpbnN0YWxsZWRGcm9tVmNzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIER1bXBBdXRvbG9hZENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2R1bXAtYXV0b2xvYWQnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ2R1bXBhdXRvbG9hZCcpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdEdW1wcyB0aGUgYXV0b2xvYWRlci4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ29wdGltaXplJywgJ28nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ09wdGltaXplcyBQU1IwIGFuZCBQU1I0IHBhY2thZ2VzIHRvIGJlIGxvYWRlZCB3aXRoIGNsYXNzbWFwcyB0b28sIGdvb2QgZm9yIHByb2R1Y3Rpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnLCAnYScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQXV0b2xvYWQgY2xhc3NlcyBmcm9tIHRoZSBjbGFzc21hcCBvbmx5LiBJbXBsaWNpdGx5IGVuYWJsZXMgYC0tb3B0aW1pemVgLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhcGN1JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVc2UgQVBDdSB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3Nlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1wcmVmaXgnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdVc2UgYSBjdXN0b20gcHJlZml4IGZvciB0aGUgQVBDdSBhdXRvbG9hZGVyIGNhY2hlLiBJbXBsaWNpdGx5IGVuYWJsZXMgLS1hcGN1JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRW5hYmxlcyBhdXRvbG9hZC1kZXYgcnVsZXMuIENvbXBvc2VyIHdpbGwgYnkgZGVmYXVsdCBpbmZlciB0aGlzIGF1dG9tYXRpY2FsbHkgYWNjb3JkaW5nIHRvIHRoZSBsYXN0IGluc3RhbGwgb3IgdXBkYXRlIC0tbm8tZGV2IHN0YXRlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIGF1dG9sb2FkLWRldiBydWxlcy4gQ29tcG9zZXIgd2lsbCBieSBkZWZhdWx0IGluZmVyIHRoaXMgYXV0b21hdGljYWxseSBhY2NvcmRpbmcgdG8gdGhlIGxhc3QgaW5zdGFsbCBvciB1cGRhdGUgLS1uby1kZXYgc3RhdGUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQgfCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVksICdJZ25vcmUgYSBzcGVjaWZpYyBwbGF0Zm9ybSByZXF1aXJlbWVudCAocGhwICYgZXh0LSBwYWNrYWdlcykuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdJZ25vcmUgYWxsIHBsYXRmb3JtIHJlcXVpcmVtZW50cyAocGhwICYgZXh0LSBwYWNrYWdlcykuJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVAo8aW5mbz5waHAgY29tcG9zZXIucGhhciBkdW1wLWF1dG9sb2FkPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjZHVtcC1hdXRvbG9hZC1kdW1wYXV0b2xvYWQtCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKCiAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnZHVtcC1hdXRvbG9hZCcsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGluc3RhbGxhdGlvbk1hbmFnZXIgPSAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKTsKICAgICAgICAkbG9jYWxSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAkcGFja2FnZSA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICRjb25maWcgPSAkY29tcG9zZXItPmdldENvbmZpZygpOwoKICAgICAgICAkb3B0aW1pemUgPSAkaW5wdXQtPmdldE9wdGlvbignb3B0aW1pemUnKSB8fCAkY29uZmlnLT5nZXQoJ29wdGltaXplLWF1dG9sb2FkZXInKTsKICAgICAgICAkYXV0aG9yaXRhdGl2ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJykgfHwgJGNvbmZpZy0+Z2V0KCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyk7CiAgICAgICAgJGFwY3VQcmVmaXggPSAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1wcmVmaXgnKTsKICAgICAgICAkYXBjdSA9ICRhcGN1UHJlZml4ICE9PSBudWxsIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1JykgfHwgJGNvbmZpZy0+Z2V0KCdhcGN1LWF1dG9sb2FkZXInKTsKCiAgICAgICAgaWYgKCRhdXRob3JpdGF0aXZlKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgnPGluZm8+R2VuZXJhdGluZyBvcHRpbWl6ZWQgYXV0b2xvYWQgZmlsZXMgKGF1dGhvcml0YXRpdmUpPC9pbmZvPicpOwogICAgICAgIH0gZWxzZWlmICgkb3B0aW1pemUpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKCc8aW5mbz5HZW5lcmF0aW5nIG9wdGltaXplZCBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoJzxpbmZvPkdlbmVyYXRpbmcgYXV0b2xvYWQgZmlsZXM8L2luZm8+Jyk7CiAgICAgICAgfQoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAkZ2VuZXJhdG9yID0gJGNvbXBvc2VyLT5nZXRBdXRvbG9hZEdlbmVyYXRvcigpOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgJGdlbmVyYXRvci0+c2V0RGV2TW9kZShmYWxzZSk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGV2JykpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1lvdSBjYW4gbm90IHVzZSBib3RoIC0tbm8tZGV2IGFuZCAtLWRldiBhcyB0aGV5IGNvbmZsaWN0IHdpdGggZWFjaCBvdGhlci4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZ2VuZXJhdG9yLT5zZXREZXZNb2RlKHRydWUpOwogICAgICAgIH0KICAgICAgICAkZ2VuZXJhdG9yLT5zZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJGF1dGhvcml0YXRpdmUpOwogICAgICAgICRnZW5lcmF0b3ItPnNldFJ1blNjcmlwdHModHJ1ZSk7CiAgICAgICAgJGdlbmVyYXRvci0+c2V0QXBjdSgkYXBjdSwgJGFwY3VQcmVmaXgpOwogICAgICAgICRnZW5lcmF0b3ItPnNldFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6OmZyb21Cb29sT3JMaXN0KCRpZ25vcmVQbGF0Zm9ybVJlcXMpKTsKICAgICAgICAkbnVtYmVyT2ZDbGFzc2VzID0gJGdlbmVyYXRvci0+ZHVtcCgkY29uZmlnLCAkbG9jYWxSZXBvLCAkcGFja2FnZSwgJGluc3RhbGxhdGlvbk1hbmFnZXIsICdjb21wb3NlcicsICRvcHRpbWl6ZSk7CgogICAgICAgIGlmICgkYXV0aG9yaXRhdGl2ZSkgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoJzxpbmZvPkdlbmVyYXRlZCBvcHRpbWl6ZWQgYXV0b2xvYWQgZmlsZXMgKGF1dGhvcml0YXRpdmUpIGNvbnRhaW5pbmcgJy4gJG51bWJlck9mQ2xhc3NlcyAuJyBjbGFzc2VzPC9pbmZvPicpOwogICAgICAgIH0gZWxzZWlmICgkb3B0aW1pemUpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKCc8aW5mbz5HZW5lcmF0ZWQgb3B0aW1pemVkIGF1dG9sb2FkIGZpbGVzIGNvbnRhaW5pbmcgJy4gJG51bWJlck9mQ2xhc3NlcyAuJyBjbGFzc2VzPC9pbmZvPicpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgnPGluZm8+R2VuZXJhdGVkIGF1dG9sb2FkIGZpbGVzPC9pbmZvPicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVuaW5zdGFsbE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxUcmFuc2FjdGlvbjsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBSZWluc3RhbGxDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdyZWluc3RhbGwnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdVbmluc3RhbGxzIGFuZCByZWluc3RhbGxzIHRoZSBnaXZlbiBwYWNrYWdlIG5hbWVzJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc291cmNlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBzb3VyY2VzIHdoZW4gcG9zc2libGUsIGluY2x1ZGluZyBWQ1MgaW5mb3JtYXRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1kaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0IChkZWZhdWx0IGJlaGF2aW9yKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWluc3RhbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0fHNvdXJjZXxhdXRvIChhdXRvIGNob29zZXMgc291cmNlIGZvciBkZXYgdmVyc2lvbnMsIGRpc3QgZm9yIHRoZSByZXN0KS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tYXV0b2xvYWRlcicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2tpcHMgYXV0b2xvYWRlciBnZW5lcmF0aW9uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXByb2dyZXNzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3Qgb3V0cHV0IGRvd25sb2FkIHByb2dyZXNzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJywgJ28nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ09wdGltaXplIGF1dG9sb2FkZXIgZHVyaW5nIGF1dG9sb2FkZXIgZHVtcCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJywgJ2EnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0F1dG9sb2FkIGNsYXNzZXMgZnJvbSB0aGUgY2xhc3NtYXAgb25seS4gSW1wbGljaXRseSBlbmFibGVzIGAtLW9wdGltaXplLWF1dG9sb2FkZXJgLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1VzZSBBUEN1IHRvIGNhY2hlIGZvdW5kL25vdC1mb3VuZCBjbGFzc2VzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXItcHJlZml4JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnVXNlIGEgY3VzdG9tIHByZWZpeCBmb3IgdGhlIEFQQ3UgYXV0b2xvYWRlciBjYWNoZS4gSW1wbGljaXRseSBlbmFibGVzIC0tYXBjdS1hdXRvbG9hZGVyJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQgfCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVksICdJZ25vcmUgYSBzcGVjaWZpYyBwbGF0Zm9ybSByZXF1aXJlbWVudCAocGhwICYgZXh0LSBwYWNrYWdlcykuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdJZ25vcmUgYWxsIHBsYXRmb3JtIHJlcXVpcmVtZW50cyAocGhwICYgZXh0LSBwYWNrYWdlcykuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZXMnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSB8IElucHV0QXJndW1lbnQ6OlJFUVVJUkVELCAnTGlzdCBvZiBwYWNrYWdlIG5hbWVzIHRvIHJlaW5zdGFsbCwgY2FuIGluY2x1ZGUgYSB3aWxkY2FyZCAoKikgdG8gbWF0Y2ggYW55IHN1YnN0cmluZy4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSA8aW5mbz5yZWluc3RhbGw8L2luZm8+IGNvbW1hbmQgbG9va3MgdXAgaW5zdGFsbGVkIHBhY2thZ2VzIGJ5IG5hbWUsCnVuaW5zdGFsbHMgdGhlbSBhbmQgcmVpbnN0YWxscyB0aGVtLiBUaGlzIGxldHMgeW91IGRvIGEgY2xlYW4gaW5zdGFsbApvZiBhIHBhY2thZ2UgaWYgeW91IG1lc3NlZCB3aXRoIGl0cyBmaWxlcywgb3IgaWYgeW91IHdpc2ggdG8gY2hhbmdlCnRoZSBpbnN0YWxsYXRpb24gdHlwZSB1c2luZyAtLXByZWZlci1pbnN0YWxsLgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgcmVpbnN0YWxsIGFjbWUvZm9vICJhY21lL2Jhci0qIjwvaW5mbz4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3JlaW5zdGFsbApFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIodHJ1ZSwgJGlucHV0LT5nZXRPcHRpb24oJ25vLXBsdWdpbnMnKSwgJGlucHV0LT5nZXRPcHRpb24oJ25vLXNjcmlwdHMnKSk7CgogICAgICAgICRsb2NhbFJlcG8gPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwogICAgICAgICRwYWNrYWdlc1RvUmVpbnN0YWxsID0gYXJyYXkoKTsKICAgICAgICAkcGFja2FnZU5hbWVzVG9SZWluc3RhbGwgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJykgYXMgJHBhdHRlcm4pIHsKICAgICAgICAgICAgJHBhdHRlcm5SZWdleHAgPSBCYXNlUGFja2FnZTo6cGFja2FnZU5hbWVUb1JlZ2V4cCgkcGF0dGVybik7CiAgICAgICAgICAgICRtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG8tPmdldENhbm9uaWNhbFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRwYXR0ZXJuUmVnZXhwLCAkcGFja2FnZS0+Z2V0TmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgICRtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNUb1JlaW5zdGFsbFtdID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lc1RvUmVpbnN0YWxsW10gPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlBhdHRlcm4gIicgLiAkcGF0dGVybiAuICciIGRvZXMgbm90IG1hdGNoIGFueSBjdXJyZW50bHkgaW5zdGFsbGVkIHBhY2thZ2VzLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkcGFja2FnZXNUb1JlaW5zdGFsbCkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkZvdW5kIG5vIHBhY2thZ2VzIHRvIHJlaW5zdGFsbCwgYWJvcnRpbmcuPC93YXJuaW5nPicpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICAkdW5pbnN0YWxsT3BlcmF0aW9ucyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzVG9SZWluc3RhbGwgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHVuaW5zdGFsbE9wZXJhdGlvbnNbXSA9IG5ldyBVbmluc3RhbGxPcGVyYXRpb24oJHBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYSBsaXN0IG9mIGluc3RhbGwgb3BlcmF0aW9ucyBvcmRlcmVkIGJ5IGRlcGVuZGVuY3kvcGx1Z2lucwogICAgICAgICRwcmVzZW50UGFja2FnZXMgPSAkbG9jYWxSZXBvLT5nZXRQYWNrYWdlcygpOwogICAgICAgICRyZXN1bHRQYWNrYWdlcyA9ICRwcmVzZW50UGFja2FnZXM7CiAgICAgICAgZm9yZWFjaCAoJHByZXNlbnRQYWNrYWdlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRwYWNrYWdlTmFtZXNUb1JlaW5zdGFsbCwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRwcmVzZW50UGFja2FnZXNbJGluZGV4XSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKCRwcmVzZW50UGFja2FnZXMsICRyZXN1bHRQYWNrYWdlcyk7CiAgICAgICAgJGluc3RhbGxPcGVyYXRpb25zID0gJHRyYW5zYWN0aW9uLT5nZXRPcGVyYXRpb25zKCk7CgogICAgICAgIC8vIHJldmVyc2Utc29ydCB0aGUgdW5pbnN0YWxscyBiYXNlZCBvbiB0aGUgaW5zdGFsbCBvcmRlcgogICAgICAgICRpbnN0YWxsT3JkZXIgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsT3BlcmF0aW9ucyBhcyAkaW5kZXggPT4gJG9wKSB7CiAgICAgICAgICAgIGlmICgkb3AgaW5zdGFuY2VvZiBJbnN0YWxsT3BlcmF0aW9uICYmICEkb3AtPmdldFBhY2thZ2UoKSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgJGluc3RhbGxPcmRlclskb3AtPmdldFBhY2thZ2UoKS0+Z2V0TmFtZSgpXSA9ICRpbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1c29ydCgkdW5pbnN0YWxsT3BlcmF0aW9ucywgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkaW5zdGFsbE9yZGVyKSB7CiAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbE9yZGVyWyRiLT5nZXRQYWNrYWdlKCktPmdldE5hbWUoKV0gLSAkaW5zdGFsbE9yZGVyWyRhLT5nZXRQYWNrYWdlKCktPmdldE5hbWUoKV07CiAgICAgICAgfSk7CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3JlaW5zdGFsbCcsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CiAgICAgICAgbGlzdCgkcHJlZmVyU291cmNlLCAkcHJlZmVyRGlzdCkgPSAkdGhpcy0+Z2V0UHJlZmVycmVkSW5zdGFsbE9wdGlvbnMoJGNvbmZpZywgJGlucHV0KTsKCiAgICAgICAgJGluc3RhbGxhdGlvbk1hbmFnZXIgPSAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKTsKICAgICAgICAkZG93bmxvYWRNYW5hZ2VyID0gJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKTsKICAgICAgICAkcGFja2FnZSA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAkaW5zdGFsbGF0aW9uTWFuYWdlci0+c2V0T3V0cHV0UHJvZ3Jlc3MoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1wcm9ncmVzcycpKTsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLXBsdWdpbnMnKSkgewogICAgICAgICAgICAkaW5zdGFsbGF0aW9uTWFuYWdlci0+ZGlzYWJsZVBsdWdpbnMoKTsKICAgICAgICB9CgogICAgICAgICRkb3dubG9hZE1hbmFnZXItPnNldFByZWZlclNvdXJjZSgkcHJlZmVyU291cmNlKTsKICAgICAgICAkZG93bmxvYWRNYW5hZ2VyLT5zZXRQcmVmZXJEaXN0KCRwcmVmZXJEaXN0KTsKCiAgICAgICAgJGluc3RhbGxhdGlvbk1hbmFnZXItPmV4ZWN1dGUoJGxvY2FsUmVwbywgJHVuaW5zdGFsbE9wZXJhdGlvbnMsIHRydWUpOwogICAgICAgICRpbnN0YWxsYXRpb25NYW5hZ2VyLT5leGVjdXRlKCRsb2NhbFJlcG8sICRpbnN0YWxsT3BlcmF0aW9ucywgdHJ1ZSk7CgogICAgICAgIGlmICghJGlucHV0LT5nZXRPcHRpb24oJ25vLWF1dG9sb2FkZXInKSkgewogICAgICAgICAgICAkb3B0aW1pemUgPSAkaW5wdXQtPmdldE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicpIHx8ICRjb25maWctPmdldCgnb3B0aW1pemUtYXV0b2xvYWRlcicpOwogICAgICAgICAgICAkYXV0aG9yaXRhdGl2ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJykgfHwgJGNvbmZpZy0+Z2V0KCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyk7CiAgICAgICAgICAgICRhcGN1UHJlZml4ID0gJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnKTsKICAgICAgICAgICAgJGFwY3UgPSAkYXBjdVByZWZpeCAhPT0gbnVsbCB8fCAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJykgfHwgJGNvbmZpZy0+Z2V0KCdhcGN1LWF1dG9sb2FkZXInKTsKCiAgICAgICAgICAgICRnZW5lcmF0b3IgPSAkY29tcG9zZXItPmdldEF1dG9sb2FkR2VuZXJhdG9yKCk7CiAgICAgICAgICAgICRnZW5lcmF0b3ItPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkYXV0aG9yaXRhdGl2ZSk7CiAgICAgICAgICAgICRnZW5lcmF0b3ItPnNldEFwY3UoJGFwY3UsICRhcGN1UHJlZml4KTsKICAgICAgICAgICAgJGdlbmVyYXRvci0+c2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcihQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6ZnJvbUJvb2xPckxpc3QoJGlnbm9yZVBsYXRmb3JtUmVxcykpOwogICAgICAgICAgICAkZ2VuZXJhdG9yLT5kdW1wKCRjb25maWcsICRsb2NhbFJlcG8sICRwYWNrYWdlLCAkaW5zdGFsbGF0aW9uTWFuYWdlciwgJ2NvbXBvc2VyJywgJG9wdGltaXplKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcQ2FjaGU7CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIERhdmlkIE5laWxzZW4gPHBldGFoLnBAZ21haWwuY29tPgogKi8KY2xhc3MgQ2xlYXJDYWNoZUNvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2NsZWFyLWNhY2hlJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdjbGVhcmNhY2hlJywgJ2NjJykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0NsZWFycyBjb21wb3NlclwncyBpbnRlcm5hbCBwYWNrYWdlIGNhY2hlLicpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+Y2xlYXItY2FjaGU8L2luZm8+IGRlbGV0ZXMgYWxsIGNhY2hlZCBwYWNrYWdlcyBmcm9tIGNvbXBvc2VyJ3MKY2FjaGUgZGlyZWN0b3J5LgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjY2xlYXItY2FjaGUtY2xlYXJjYWNoZS1jYwpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICAkY2FjaGVQYXRocyA9IGFycmF5KAogICAgICAgICAgICAnY2FjaGUtdmNzLWRpcicgPT4gJGNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJyksCiAgICAgICAgICAgICdjYWNoZS1yZXBvLWRpcicgPT4gJGNvbmZpZy0+Z2V0KCdjYWNoZS1yZXBvLWRpcicpLAogICAgICAgICAgICAnY2FjaGUtZmlsZXMtZGlyJyA9PiAkY29uZmlnLT5nZXQoJ2NhY2hlLWZpbGVzLWRpcicpLAogICAgICAgICAgICAnY2FjaGUtZGlyJyA9PiAkY29uZmlnLT5nZXQoJ2NhY2hlLWRpcicpLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCRjYWNoZVBhdGhzIGFzICRrZXkgPT4gJGNhY2hlUGF0aCkgewogICAgICAgICAgICAkY2FjaGVQYXRoID0gcmVhbHBhdGgoJGNhY2hlUGF0aCk7CiAgICAgICAgICAgIGlmICghJGNhY2hlUGF0aCkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCI8aW5mbz5DYWNoZSBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3QgKCRrZXkpOiAkY2FjaGVQYXRoPC9pbmZvPiIpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjYWNoZSA9IG5ldyBDYWNoZSgkaW8sICRjYWNoZVBhdGgpOwogICAgICAgICAgICAkY2FjaGUtPnNldFJlYWRPbmx5KCRjb25maWctPmdldCgnY2FjaGUtcmVhZC1vbmx5JykpOwogICAgICAgICAgICBpZiAoISRjYWNoZS0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiPGluZm8+Q2FjaGUgaXMgbm90IGVuYWJsZWQgKCRrZXkpOiAkY2FjaGVQYXRoPC9pbmZvPiIpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoIjxpbmZvPkNsZWFyaW5nIGNhY2hlICgka2V5KTogJGNhY2hlUGF0aDwvaW5mbz4iKTsKICAgICAgICAgICAgJGNhY2hlLT5jbGVhcigpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5BbGwgY2FjaGVzIGNsZWFyZWQuPC9pbmZvPicpOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXENvbmZpZ1xKc29uQ29uZmlnU291cmNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFJlcXVlc3Q7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTsKdXNlIENvbXBvc2VyXEluc3RhbGxlcjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFBsdWdpblxDb21tYW5kRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CgovKioKICogQGF1dGhvciBQaWVycmUgZHUgUGxlc3NpcyA8cGRwbGVzQGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUmVtb3ZlQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgncmVtb3ZlJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignUmVtb3ZlcyBhIHBhY2thZ2UgZnJvbSB0aGUgcmVxdWlyZSBvciByZXF1aXJlLWRldi4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZXMnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSB8IElucHV0QXJndW1lbnQ6OlJFUVVJUkVELCAnUGFja2FnZXMgdGhhdCBzaG91bGQgYmUgcmVtb3ZlZC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZW1vdmVzIGEgcGFja2FnZSBmcm9tIHRoZSByZXF1aXJlLWRldiBzZWN0aW9uLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkcnktcnVuJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPdXRwdXRzIHRoZSBvcGVyYXRpb25zIGJ1dCB3aWxsIG5vdCBleGVjdXRlIGFueXRoaW5nIChpbXBsaWNpdGx5IGVuYWJsZXMgLS12ZXJib3NlKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tcHJvZ3Jlc3MnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCBvdXRwdXQgZG93bmxvYWQgcHJvZ3Jlc3MuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXVwZGF0ZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzYWJsZXMgdGhlIGF1dG9tYXRpYyB1cGRhdGUgb2YgdGhlIGRlcGVuZGVuY2llcyAoaW1wbGllcyAtLW5vLWluc3RhbGwpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1pbnN0YWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTa2lwIHRoZSBpbnN0YWxsIHN0ZXAgYWZ0ZXIgdXBkYXRpbmcgdGhlIGNvbXBvc2VyLmxvY2sgZmlsZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndXBkYXRlLW5vLWRldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUnVuIHRoZSBkZXBlbmRlbmN5IHVwZGF0ZSB3aXRoIHRoZSAtLW5vLWRldiBvcHRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3VwZGF0ZS13aXRoLWRlcGVuZGVuY2llcycsICd3JywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBbGxvd3MgaW5oZXJpdGVkIGRlcGVuZGVuY2llcyB0byBiZSB1cGRhdGVkIHdpdGggZXhwbGljaXQgZGVwZW5kZW5jaWVzLiAoRGVwcmVjcmF0ZWQsIGlzIG5vdyBkZWZhdWx0IGJlaGF2aW9yKScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1cGRhdGUtd2l0aC1hbGwtZGVwZW5kZW5jaWVzJywgJ1cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0FsbG93cyBhbGwgaW5oZXJpdGVkIGRlcGVuZGVuY2llcyB0byBiZSB1cGRhdGVkLCBpbmNsdWRpbmcgdGhvc2UgdGhhdCBhcmUgcm9vdCByZXF1aXJlbWVudHMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxpYXMgZm9yIC0tdXBkYXRlLXdpdGgtYWxsLWRlcGVuZGVuY2llcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby11cGRhdGUtd2l0aC1kZXBlbmRlbmNpZXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvZXMgbm90IGFsbG93IGluaGVyaXRlZCBkZXBlbmRlbmNpZXMgdG8gYmUgdXBkYXRlZCB3aXRoIGV4cGxpY2l0IGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndW51c2VkJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZW1vdmUgYWxsIHBhY2thZ2VzIHdoaWNoIGFyZSBsb2NrZWQgYnV0IG5vdCByZXF1aXJlZCBieSBhbnkgb3RoZXIgcGFja2FnZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0lnbm9yZSBhbGwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcHRpbWl6ZSBhdXRvbG9hZGVyIGR1cmluZyBhdXRvbG9hZGVyIGR1bXAnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBdXRvbG9hZCBjbGFzc2VzIGZyb20gdGhlIGNsYXNzbWFwIG9ubHkuIEltcGxpY2l0bHkgZW5hYmxlcyBgLS1vcHRpbWl6ZS1hdXRvbG9hZGVyYC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVc2UgQVBDdSB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3Nlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1VzZSBhIGN1c3RvbSBwcmVmaXggZm9yIHRoZSBBUEN1IGF1dG9sb2FkZXIgY2FjaGUuIEltcGxpY2l0bHkgZW5hYmxlcyAtLWFwY3UtYXV0b2xvYWRlcicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPnJlbW92ZTwvaW5mbz4gY29tbWFuZCByZW1vdmVzIGEgcGFja2FnZSBmcm9tIHRoZSBjdXJyZW50Cmxpc3Qgb2YgaW5zdGFsbGVkIHBhY2thZ2VzCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciByZW1vdmU8L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNyZW1vdmUKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGludGVyYWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnVzZWQnKSkgewogICAgICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKICAgICAgICAgICAgJGxvY2tlciA9ICRjb21wb3Nlci0+Z2V0TG9ja2VyKCk7CiAgICAgICAgICAgIGlmICghJGxvY2tlci0+aXNMb2NrZWQoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0EgdmFsaWQgY29tcG9zZXIubG9jayBmaWxlIGlzIHJlcXVpcmVkIHRvIHJ1biB0aGlzIGNvbW1hbmQgd2l0aCAtLXVudXNlZCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG9ja2VkUGFja2FnZXMgPSAkbG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCktPmdldFBhY2thZ2VzKCk7CgogICAgICAgICAgICAkcmVxdWlyZWQgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0UmVxdWlyZXMoKSwgJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldERldlJlcXVpcmVzKCkpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkcmVxdWlyZWRbJGxpbmstPmdldFRhcmdldCgpXSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICRmb3VuZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tlZFBhY2thZ2VzIGFzICRpbmRleCA9PiAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXROYW1lcygpIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcmVxdWlyZWRbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZWRbJGxpbmstPmdldFRhcmdldCgpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGxvY2tlZFBhY2thZ2VzWyRpbmRleF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gd2hpbGUgKCRmb3VuZCk7CgogICAgICAgICAgICAkdW51c2VkID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tlZFBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkdW51c2VkW10gPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRpbnB1dC0+c2V0QXJndW1lbnQoJ3BhY2thZ2VzJywgYXJyYXlfbWVyZ2UoJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZXMnKSwgJHVudXNlZCkpOwoKICAgICAgICAgICAgaWYgKCEkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlcycpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignPGluZm8+Tm8gdW51c2VkIHBhY2thZ2VzIHRvIHJlbW92ZTwvaW5mbz4nKTsKICAgICAgICAgICAgICAgICR0aGlzLT5zZXRDb2RlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqIEB0aHJvd3MgXFNlbGRcSnNvbkxpbnRcUGFyc2luZ0V4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRwYWNrYWdlcyA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJyk7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgJHBhY2thZ2VzKTsKCiAgICAgICAgJGZpbGUgPSBGYWN0b3J5OjpnZXRDb21wb3NlckZpbGUoKTsKCiAgICAgICAgJGpzb25GaWxlID0gbmV3IEpzb25GaWxlKCRmaWxlKTsKICAgICAgICAkY29tcG9zZXIgPSAkanNvbkZpbGUtPnJlYWQoKTsKICAgICAgICAkY29tcG9zZXJCYWNrdXAgPSBmaWxlX2dldF9jb250ZW50cygkanNvbkZpbGUtPmdldFBhdGgoKSk7CgogICAgICAgICRqc29uID0gbmV3IEpzb25Db25maWdTb3VyY2UoJGpzb25GaWxlKTsKCiAgICAgICAgJHR5cGUgPSAkaW5wdXQtPmdldE9wdGlvbignZGV2JykgPyAncmVxdWlyZS1kZXYnIDogJ3JlcXVpcmUnOwogICAgICAgICRhbHRUeXBlID0gISRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSA/ICdyZXF1aXJlLWRldicgOiAncmVxdWlyZSc7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBkZXByZWNhdGVkIG9wdGlvbiAidXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzIi4gVGhpcyBpcyBub3cgZGVmYXVsdCBiZWhhdmlvdXIuIFRoZSAtLW5vLXVwZGF0ZS13aXRoLWRlcGVuZGVuY2llcyBvcHRpb24gY2FuIGJlIHVzZWQgdG8gcmVtb3ZlIGEgcGFja2FnZSB3aXRob3V0IGl0cyBkZXBlbmRlbmNpZXMuPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgLy8gbWFrZSBzdXJlIG5hbWUgY2hlY2tzIGFyZSBkb25lIGNhc2UgaW5zZW5zaXRpdmVseQogICAgICAgIGZvcmVhY2ggKGFycmF5KCdyZXF1aXJlJywgJ3JlcXVpcmUtZGV2JykgYXMgJGxpbmtUeXBlKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29tcG9zZXJbJGxpbmtUeXBlXSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb21wb3NlclskbGlua1R5cGVdIGFzICRuYW1lID0+ICR2ZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWyRsaW5rVHlwZV1bc3RydG9sb3dlcigkbmFtZSldID0gJG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRkcnlSdW4gPSAkaW5wdXQtPmdldE9wdGlvbignZHJ5LXJ1bicpOwogICAgICAgICR0b1JlbW92ZSA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29tcG9zZXJbJHR5cGVdWyRwYWNrYWdlXSkpIHsKICAgICAgICAgICAgICAgIGlmICgkZHJ5UnVuKSB7CiAgICAgICAgICAgICAgICAgICAgJHRvUmVtb3ZlWyR0eXBlXVtdID0gJGNvbXBvc2VyWyR0eXBlXVskcGFja2FnZV07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRqc29uLT5yZW1vdmVMaW5rKCR0eXBlLCAkY29tcG9zZXJbJHR5cGVdWyRwYWNrYWdlXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkY29tcG9zZXJbJGFsdFR5cGVdWyRwYWNrYWdlXSkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+JyAuICRjb21wb3NlclskYWx0VHlwZV1bJHBhY2thZ2VdIC4gJyBjb3VsZCBub3QgYmUgZm91bmQgaW4gJyAuICR0eXBlIC4gJyBidXQgaXQgaXMgcHJlc2VudCBpbiAnIC4gJGFsdFR5cGUgLiAnPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgaWYgKCRpby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpby0+YXNrQ29uZmlybWF0aW9uKCdEbyB5b3Ugd2FudCB0byByZW1vdmUgaXQgZnJvbSAnIC4gJGFsdFR5cGUgLiAnIFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRkcnlSdW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b1JlbW92ZVskYWx0VHlwZV1bXSA9ICRjb21wb3NlclskYWx0VHlwZV1bJHBhY2thZ2VdOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGpzb24tPnJlbW92ZUxpbmsoJGFsdFR5cGUsICRjb21wb3NlclskYWx0VHlwZV1bJHBhY2thZ2VdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRjb21wb3NlclskdHlwZV0pICYmICRtYXRjaGVzID0gUHJlZzo6Z3JlcChCYXNlUGFja2FnZTo6cGFja2FnZU5hbWVUb1JlZ2V4cCgkcGFja2FnZSksIGFycmF5X2tleXMoJGNvbXBvc2VyWyR0eXBlXSkpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkbWF0Y2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGRyeVJ1bikgewogICAgICAgICAgICAgICAgICAgICAgICAkdG9SZW1vdmVbJHR5cGVdW10gPSAkbWF0Y2hlZFBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGpzb24tPnJlbW92ZUxpbmsoJHR5cGUsICRtYXRjaGVkUGFja2FnZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGNvbXBvc2VyWyRhbHRUeXBlXSkgJiYgJG1hdGNoZXMgPSBQcmVnOjpncmVwKEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCRwYWNrYWdlKSwgYXJyYXlfa2V5cygkY29tcG9zZXJbJGFsdFR5cGVdKSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzIGFzICRtYXRjaGVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+JyAuICRtYXRjaGVkUGFja2FnZSAuICcgY291bGQgbm90IGJlIGZvdW5kIGluICcgLiAkdHlwZSAuICcgYnV0IGl0IGlzIHByZXNlbnQgaW4gJyAuICRhbHRUeXBlIC4gJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpby0+YXNrQ29uZmlybWF0aW9uKCdEbyB5b3Ugd2FudCB0byByZW1vdmUgaXQgZnJvbSAnIC4gJGFsdFR5cGUgLiAnIFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZHJ5UnVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRvUmVtb3ZlWyRhbHRUeXBlXVtdID0gJG1hdGNoZWRQYWNrYWdlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkanNvbi0+cmVtb3ZlTGluaygkYWx0VHlwZSwgJG1hdGNoZWRQYWNrYWdlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Jy4kcGFja2FnZS4nIGlzIG5vdCByZXF1aXJlZCBpbiB5b3VyIGNvbXBvc2VyLmpzb24gYW5kIGhhcyBub3QgYmVlbiByZW1vdmVkPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPicuJGZpbGUuJyBoYXMgYmVlbiB1cGRhdGVkPC9pbmZvPicpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLXVwZGF0ZScpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSkpIHsKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRQbHVnaW5NYW5hZ2VyKCktPmRlYWN0aXZhdGVJbnN0YWxsZWRQbHVnaW5zKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBVcGRhdGUgcGFja2FnZXMKICAgICAgICAkdGhpcy0+cmVzZXRDb21wb3NlcigpOwogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3Nlcih0cnVlLCAkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpLCAkaW5wdXQtPmdldE9wdGlvbignbm8tc2NyaXB0cycpKTsKCiAgICAgICAgaWYgKCRkcnlSdW4pIHsKICAgICAgICAgICAgJHJvb3RQYWNrYWdlID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgICAgICRsaW5rcyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ3JlcXVpcmUnID0+ICRyb290UGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgICAgICdyZXF1aXJlLWRldicgPT4gJHJvb3RQYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpLAogICAgICAgICAgICApOwogICAgICAgICAgICBmb3JlYWNoICgkdG9SZW1vdmUgYXMgJHR5cGUgPT4gJG5hbWVzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbmFtZXMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkbGlua3NbJHR5cGVdWyRuYW1lXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJvb3RQYWNrYWdlLT5zZXRSZXF1aXJlcygkbGlua3NbJ3JlcXVpcmUnXSk7CiAgICAgICAgICAgICRyb290UGFja2FnZS0+c2V0RGV2UmVxdWlyZXMoJGxpbmtzWydyZXF1aXJlLWRldiddKTsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3JlbW92ZScsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPnNldE91dHB1dFByb2dyZXNzKCEkaW5wdXQtPmdldE9wdGlvbignbm8tcHJvZ3Jlc3MnKSk7CgogICAgICAgICRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoJGlvLCAkY29tcG9zZXIpOwoKICAgICAgICAkdXBkYXRlRGV2TW9kZSA9ICEkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLW5vLWRldicpOwogICAgICAgICRvcHRpbWl6ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJykgfHwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdvcHRpbWl6ZS1hdXRvbG9hZGVyJyk7CiAgICAgICAgJGF1dGhvcml0YXRpdmUgPSAkaW5wdXQtPmdldE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpIHx8ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpOwogICAgICAgICRhcGN1UHJlZml4ID0gJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnKTsKICAgICAgICAkYXBjdSA9ICRhcGN1UHJlZml4ICE9PSBudWxsIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXInKSB8fCAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2FwY3UtYXV0b2xvYWRlcicpOwoKICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQU19OT19ST09UX1JFUVVJUkU7CiAgICAgICAgJGZsYWdzID0gJyc7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1cGRhdGUtd2l0aC1hbGwtZGVwZW5kZW5jaWVzJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycpKSB7CiAgICAgICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBSZXF1ZXN0OjpVUERBVEVfTElTVEVEX1dJVEhfVFJBTlNJVElWRV9ERVBTOwogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLXdpdGgtYWxsLWRlcGVuZGVuY2llcyc7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby11cGRhdGUtd2l0aC1kZXBlbmRlbmNpZXMnKSkgewogICAgICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX09OTFlfTElTVEVEOwogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLXdpdGgtZGVwZW5kZW5jaWVzJzsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+UnVubmluZyBjb21wb3NlciB1cGRhdGUgJy5pbXBsb2RlKCcgJywgJHBhY2thZ2VzKS4kZmxhZ3MuJzwvaW5mbz4nKTsKCiAgICAgICAgJGlnbm9yZVBsYXRmb3JtUmVxcyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycpID86ICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScpID86IGZhbHNlKTsKCiAgICAgICAgJGluc3RhbGwKICAgICAgICAgICAgLT5zZXRWZXJib3NlKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpCiAgICAgICAgICAgIC0+c2V0RGV2TW9kZSgkdXBkYXRlRGV2TW9kZSkKICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJG9wdGltaXplKQogICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkYXV0aG9yaXRhdGl2ZSkKICAgICAgICAgICAgLT5zZXRBcGN1QXV0b2xvYWRlcigkYXBjdSwgJGFwY3VQcmVmaXgpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlKHRydWUpCiAgICAgICAgICAgIC0+c2V0SW5zdGFsbCghJGlucHV0LT5nZXRPcHRpb24oJ25vLWluc3RhbGwnKSkKICAgICAgICAgICAgLT5zZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcykKICAgICAgICAgICAgLT5zZXRQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5Ojpmcm9tQm9vbE9yTGlzdCgkaWdub3JlUGxhdGZvcm1SZXFzKSkKICAgICAgICAgICAgLT5zZXREcnlSdW4oJGRyeVJ1bikKICAgICAgICA7CgogICAgICAgIC8vIGlmIG5vIGxvY2sgaXMgcHJlc2VudCwgd2UgZG8gbm90IGRvIGEgcGFydGlhbCB1cGRhdGUgYXMKICAgICAgICAvLyB0aGlzIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIEluc3RhbGxlcgogICAgICAgIGlmICgkY29tcG9zZXItPmdldExvY2tlcigpLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICRpbnN0YWxsLT5zZXRVcGRhdGVBbGxvd0xpc3QoJHBhY2thZ2VzKTsKICAgICAgICB9CgogICAgICAgICRzdGF0dXMgPSAkaW5zdGFsbC0+cnVuKCk7CiAgICAgICAgaWYgKCRzdGF0dXMgIT09IDApIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCJcbiIuJzxlcnJvcj5SZW1vdmFsIGZhaWxlZCwgcmV2ZXJ0aW5nICcuJGZpbGUuJyB0byBpdHMgb3JpZ2luYWwgY29udGVudC48L2Vycm9yPicpOwogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkanNvbkZpbGUtPmdldFBhdGgoKSwgJGNvbXBvc2VyQmFja3VwKTsKICAgICAgICB9CgogICAgICAgIGlmICghJGRyeVJ1bikgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmICgkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpLT5maW5kUGFja2FnZXMoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+UmVtb3ZhbCBmYWlsZWQsICcuJHBhY2thZ2UuJyBpcyBzdGlsbCBwcmVzZW50LCBpdCBtYXkgYmUgcmVxdWlyZWQgYnkgYW5vdGhlciBwYWNrYWdlLiBTZWUgYGNvbXBvc2VyIHdoeSAnLiRwYWNrYWdlLidgLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHN0YXR1czsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIFJ5YW4gV2VhdmVyIDxyeWFuQGtucGxhYnMuY29tPgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgSW5zdGFsbENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2luc3RhbGwnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ2knKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignSW5zdGFsbHMgdGhlIHByb2plY3QgZGVwZW5kZW5jaWVzIGZyb20gdGhlIGNvbXBvc2VyLmxvY2sgZmlsZSBpZiBwcmVzZW50LCBvciBmYWxscyBiYWNrIG9uIHRoZSBjb21wb3Nlci5qc29uLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLXNvdXJjZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2VzIGluc3RhbGxhdGlvbiBmcm9tIHBhY2thZ2Ugc291cmNlcyB3aGVuIHBvc3NpYmxlLCBpbmNsdWRpbmcgVkNTIGluZm9ybWF0aW9uLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItZGlzdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2VzIGluc3RhbGxhdGlvbiBmcm9tIHBhY2thZ2UgZGlzdCAoZGVmYXVsdCBiZWhhdmlvcikuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1pbnN0YWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnRm9yY2VzIGluc3RhbGxhdGlvbiBmcm9tIHBhY2thZ2UgZGlzdHxzb3VyY2V8YXV0byAoYXV0byBjaG9vc2VzIHNvdXJjZSBmb3IgZGV2IHZlcnNpb25zLCBkaXN0IGZvciB0aGUgcmVzdCkuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RyeS1ydW4nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ091dHB1dHMgdGhlIG9wZXJhdGlvbnMgYnV0IHdpbGwgbm90IGV4ZWN1dGUgYW55dGhpbmcgKGltcGxpY2l0bHkgZW5hYmxlcyAtLXZlcmJvc2UpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RFUFJFQ0FURUQ6IEVuYWJsZXMgaW5zdGFsbGF0aW9uIG9mIHJlcXVpcmUtZGV2IHBhY2thZ2VzIChlbmFibGVkIGJ5IGRlZmF1bHQsIG9ubHkgcHJlc2VudCBmb3IgQkMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zdWdnZXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdERVBSRUNBVEVEOiBUaGlzIGZsYWcgZG9lcyBub3QgZXhpc3QgYW55bW9yZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyBpbnN0YWxsYXRpb24gb2YgcmVxdWlyZS1kZXYgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWF1dG9sb2FkZXInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXBzIGF1dG9sb2FkZXIgZ2VuZXJhdGlvbicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1wcm9ncmVzcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IG91dHB1dCBkb3dubG9hZCBwcm9ncmVzcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8taW5zdGFsbCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IHVzZSwgb25seSBkZWZpbmVkIGhlcmUgdG8gY2F0Y2ggbWlzdXNlIG9mIHRoZSBpbnN0YWxsIGNvbW1hbmQuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ZlcmJvc2UnLCAndnx2dnx2dnYnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3dzIG1vcmUgZGV0YWlscyBpbmNsdWRpbmcgbmV3IGNvbW1pdHMgcHVsbGVkIGluIHdoZW4gdXBkYXRpbmcgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ29wdGltaXplLWF1dG9sb2FkZXInLCAnbycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnT3B0aW1pemUgYXV0b2xvYWRlciBkdXJpbmcgYXV0b2xvYWRlciBkdW1wJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnLCAnYScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQXV0b2xvYWQgY2xhc3NlcyBmcm9tIHRoZSBjbGFzc21hcCBvbmx5LiBJbXBsaWNpdGx5IGVuYWJsZXMgYC0tb3B0aW1pemUtYXV0b2xvYWRlcmAuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlcicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnVXNlIEFQQ3UgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdVc2UgYSBjdXN0b20gcHJlZml4IGZvciB0aGUgQVBDdSBhdXRvbG9hZGVyIGNhY2hlLiBJbXBsaWNpdGx5IGVuYWJsZXMgLS1hcGN1LWF1dG9sb2FkZXInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0lnbm9yZSBhbGwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdwYWNrYWdlcycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdTaG91bGQgbm90IGJlIHByb3ZpZGVkLCB1c2UgY29tcG9zZXIgcmVxdWlyZSBpbnN0ZWFkIHRvIGFkZCBhIGdpdmVuIHBhY2thZ2UgdG8gY29tcG9zZXIuanNvbi4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSA8aW5mbz5pbnN0YWxsPC9pbmZvPiBjb21tYW5kIHJlYWRzIHRoZSBjb21wb3Nlci5sb2NrIGZpbGUgZnJvbQp0aGUgY3VycmVudCBkaXJlY3RvcnksIHByb2Nlc3NlcyBpdCwgYW5kIGRvd25sb2FkcyBhbmQgaW5zdGFsbHMgYWxsIHRoZQpsaWJyYXJpZXMgYW5kIGRlcGVuZGVuY2llcyBvdXRsaW5lZCBpbiB0aGF0IGZpbGUuIElmIHRoZSBmaWxlIGRvZXMgbm90CmV4aXN0IGl0IHdpbGwgbG9vayBmb3IgY29tcG9zZXIuanNvbiBhbmQgZG8gdGhlIHNhbWUuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBpbnN0YWxsPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjaW5zdGFsbC1pCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgdXNpbmcgdGhlIGRlcHJlY2F0ZWQgb3B0aW9uICItLWRldiIuIEl0IGhhcyBubyBlZmZlY3QgYW5kIHdpbGwgYnJlYWsgaW4gQ29tcG9zZXIgMy48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tc3VnZ2VzdCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gIi0tbm8tc3VnZ2VzdCIuIEl0IGhhcyBubyBlZmZlY3QgYW5kIHdpbGwgYnJlYWsgaW4gQ29tcG9zZXIgMy48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGFyZ3MgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlcycpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkludmFsaWQgYXJndW1lbnQgJy5pbXBsb2RlKCcgJywgJGFyZ3MpLicuIFVzZSAiY29tcG9zZXIgcmVxdWlyZSAnLmltcGxvZGUoJyAnLCAkYXJncykuJyIgaW5zdGVhZCB0byBhZGQgcGFja2FnZXMgdG8geW91ciBjb21wb3Nlci5qc29uLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8taW5zdGFsbCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkludmFsaWQgb3B0aW9uICItLW5vLWluc3RhbGwiLiBVc2UgImNvbXBvc2VyIHVwZGF0ZSAtLW5vLWluc3RhbGwiIGluc3RlYWQgaWYgeW91IGFyZSB0cnlpbmcgdG8gdXBkYXRlIHRoZSBjb21wb3Nlci5sb2NrIGZpbGUuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKHRydWUsICRpbnB1dC0+Z2V0T3B0aW9uKCduby1wbHVnaW5zJyksICRpbnB1dC0+Z2V0T3B0aW9uKCduby1zY3JpcHRzJykpOwoKICAgICAgICBpZiAoKCEkY29tcG9zZXItPmdldExvY2tlcigpIHx8ICEkY29tcG9zZXItPmdldExvY2tlcigpLT5pc0xvY2tlZCgpKSAmJiAhSHR0cERvd25sb2FkZXI6OmlzQ3VybEVuYWJsZWQoKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNvbXBvc2VyIGlzIG9wZXJhdGluZyBzaWduaWZpY2FudGx5IHNsb3dlciB0aGFuIG5vcm1hbCBiZWNhdXNlIHlvdSBkbyBub3QgaGF2ZSB0aGUgUEhQIGN1cmwgZXh0ZW5zaW9uIGVuYWJsZWQuPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnaW5zdGFsbCcsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGluc3RhbGwgPSBJbnN0YWxsZXI6OmNyZWF0ZSgkaW8sICRjb21wb3Nlcik7CgogICAgICAgICRjb25maWcgPSAkY29tcG9zZXItPmdldENvbmZpZygpOwogICAgICAgIGxpc3QoJHByZWZlclNvdXJjZSwgJHByZWZlckRpc3QpID0gJHRoaXMtPmdldFByZWZlcnJlZEluc3RhbGxPcHRpb25zKCRjb25maWcsICRpbnB1dCk7CgogICAgICAgICRvcHRpbWl6ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJykgfHwgJGNvbmZpZy0+Z2V0KCdvcHRpbWl6ZS1hdXRvbG9hZGVyJyk7CiAgICAgICAgJGF1dGhvcml0YXRpdmUgPSAkaW5wdXQtPmdldE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpIHx8ICRjb25maWctPmdldCgnY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpOwogICAgICAgICRhcGN1UHJlZml4ID0gJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnKTsKICAgICAgICAkYXBjdSA9ICRhcGN1UHJlZml4ICE9PSBudWxsIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXInKSB8fCAkY29uZmlnLT5nZXQoJ2FwY3UtYXV0b2xvYWRlcicpOwoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+c2V0T3V0cHV0UHJvZ3Jlc3MoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1wcm9ncmVzcycpKTsKCiAgICAgICAgJGluc3RhbGwKICAgICAgICAgICAgLT5zZXREcnlSdW4oJGlucHV0LT5nZXRPcHRpb24oJ2RyeS1ydW4nKSkKICAgICAgICAgICAgLT5zZXRWZXJib3NlKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyU291cmNlKCRwcmVmZXJTb3VyY2UpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyRGlzdCgkcHJlZmVyRGlzdCkKICAgICAgICAgICAgLT5zZXREZXZNb2RlKCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpCiAgICAgICAgICAgIC0+c2V0RHVtcEF1dG9sb2FkZXIoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1hdXRvbG9hZGVyJykpCiAgICAgICAgICAgIC0+c2V0T3B0aW1pemVBdXRvbG9hZGVyKCRvcHRpbWl6ZSkKICAgICAgICAgICAgLT5zZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJGF1dGhvcml0YXRpdmUpCiAgICAgICAgICAgIC0+c2V0QXBjdUF1dG9sb2FkZXIoJGFwY3UsICRhcGN1UHJlZml4KQogICAgICAgICAgICAtPnNldFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6OmZyb21Cb29sT3JMaXN0KCRpZ25vcmVQbGF0Zm9ybVJlcXMpKQogICAgICAgIDsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1wbHVnaW5zJykpIHsKICAgICAgICAgICAgJGluc3RhbGwtPmRpc2FibGVQbHVnaW5zKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGluc3RhbGwtPnJ1bigpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcQXJyYXlJbnB1dDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgT3V0ZGF0ZWRDb21tYW5kIGV4dGVuZHMgU2hvd0NvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdvdXRkYXRlZCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1Nob3dzIGEgbGlzdCBvZiBpbnN0YWxsZWQgcGFja2FnZXMgdGhhdCBoYXZlIHVwZGF0ZXMgYXZhaWxhYmxlLCBpbmNsdWRpbmcgdGhlaXIgbGF0ZXN0IHZlcnNpb24uJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2UnLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2UgdG8gaW5zcGVjdC4gT3IgYSBuYW1lIGluY2x1ZGluZyBhIHdpbGRjYXJkICgqKSB0byBmaWx0ZXIgbGlzdHMgb2YgcGFja2FnZXMgaW5zdGVhZC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignb3V0ZGF0ZWQnLCAnbycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvdyBvbmx5IHBhY2thZ2VzIHRoYXQgYXJlIG91dGRhdGVkICh0aGlzIGlzIHRoZSBkZWZhdWx0LCBidXQgcHJlc2VudCBoZXJlIGZvciBjb21wYXQgd2l0aCBgc2hvd2AnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYWxsJywgJ2EnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgYWxsIGluc3RhbGxlZCBwYWNrYWdlcyB3aXRoIHRoZWlyIGxhdGVzdCB2ZXJzaW9ucycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsb2NrZWQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3dzIHVwZGF0ZXMgZm9yIHBhY2thZ2VzIGZyb20gdGhlIGxvY2sgZmlsZSwgcmVnYXJkbGVzcyBvZiB3aGF0IGlzIGN1cnJlbnRseSBpbiB2ZW5kb3IgZGlyJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RpcmVjdCcsICdEJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93cyBvbmx5IHBhY2thZ2VzIHRoYXQgYXJlIGRpcmVjdGx5IHJlcXVpcmVkIGJ5IHRoZSByb290IHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc3RyaWN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZXR1cm4gYSBub24temVybyBleGl0IGNvZGUgd2hlbiB0aGVyZSBhcmUgb3V0ZGF0ZWQgcGFja2FnZXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbWlub3Itb25seScsICdtJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IG9ubHkgcGFja2FnZXMgdGhhdCBoYXZlIG1pbm9yIFNlbVZlci1jb21wYXRpYmxlIHVwZGF0ZXMuIFVzZSB3aXRoIHRoZSAtLW91dGRhdGVkIG9wdGlvbi4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZm9ybWF0JywgJ2YnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdGb3JtYXQgb2YgdGhlIG91dHB1dDogdGV4dCBvciBqc29uJywgJ3RleHQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIHNwZWNpZmllZCBwYWNrYWdlKHMpLiBVc2UgaXQgd2l0aCB0aGUgLS1vdXRkYXRlZCBvcHRpb24gaWYgeW91IGRvblwndCB3YW50IHRvIGJlIGluZm9ybWVkIGFib3V0IG5ldyB2ZXJzaW9ucyBvZiBzb21lIHBhY2thZ2VzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIHNlYXJjaCBpbiByZXF1aXJlLWRldiBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4gVXNlIHdpdGggdGhlIC0tb3V0ZGF0ZWQgb3B0aW9uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdJZ25vcmUgYWxsIHBsYXRmb3JtIHJlcXVpcmVtZW50cyAocGhwICYgZXh0LSBwYWNrYWdlcykuIFVzZSB3aXRoIHRoZSAtLW91dGRhdGVkIG9wdGlvbicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIG91dGRhdGVkIGNvbW1hbmQgaXMganVzdCBhIHByb3h5IGZvciBgY29tcG9zZXIgc2hvdyAtbGAKClRoZSBjb2xvciBjb2RpbmcgKG9yIHNpZ25hZ2UgaWYgeW91IGhhdmUgQU5TSSBjb2xvcnMgZGlzYWJsZWQpIGZvciBkZXBlbmRlbmN5IHZlcnNpb25zIGlzIGFzIHN1Y2g6CgotIDxpbmZvPmdyZWVuPC9pbmZvPiAoPSk6IERlcGVuZGVuY3kgaXMgaW4gdGhlIGxhdGVzdCB2ZXJzaW9uIGFuZCBpcyB1cCB0byBkYXRlLgotIDxjb21tZW50PnllbGxvdzwvY29tbWVudD4gKH4pOiBEZXBlbmRlbmN5IGhhcyBhIG5ldyB2ZXJzaW9uIGF2YWlsYWJsZSB0aGF0IGluY2x1ZGVzIGJhY2t3YXJkcwogIGNvbXBhdGliaWxpdHkgYnJlYWtzIGFjY29yZGluZyB0byBzZW12ZXIsIHNvIHVwZ3JhZGUgd2hlbiB5b3UgY2FuIGJ1dCBpdAogIG1heSBpbnZvbHZlIHdvcmsuCi0gPGhpZ2hsaWdodD5yZWQ8L2hpZ2hsaWdodD4gKCEpOiBEZXBlbmRlbmN5IGhhcyBhIG5ldyB2ZXJzaW9uIHRoYXQgaXMgc2VtdmVyLWNvbXBhdGlibGUgYW5kIHlvdSBzaG91bGQgdXBncmFkZSBpdC4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI291dGRhdGVkCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGFyZ3MgPSBhcnJheSgKICAgICAgICAgICAgJ2NvbW1hbmQnID0+ICdzaG93JywKICAgICAgICAgICAgJy0tbGF0ZXN0JyA9PiB0cnVlLAogICAgICAgICk7CiAgICAgICAgaWYgKCEkaW5wdXQtPmdldE9wdGlvbignYWxsJykpIHsKICAgICAgICAgICAgJGFyZ3NbJy0tb3V0ZGF0ZWQnXSA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGlyZWN0JykpIHsKICAgICAgICAgICAgJGFyZ3NbJy0tZGlyZWN0J10gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZScpKSB7CiAgICAgICAgICAgICRhcmdzWydwYWNrYWdlJ10gPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignc3RyaWN0JykpIHsKICAgICAgICAgICAgJGFyZ3NbJy0tc3RyaWN0J10gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ21pbm9yLW9ubHknKSkgewogICAgICAgICAgICAkYXJnc1snLS1taW5vci1vbmx5J10gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xvY2tlZCcpKSB7CiAgICAgICAgICAgICRhcmdzWyctLWxvY2tlZCddID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkgewogICAgICAgICAgICAkYXJnc1snLS1uby1kZXYnXSA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScpKSB7CiAgICAgICAgICAgICRhcmdzWyctLWlnbm9yZS1wbGF0Zm9ybS1yZXEnXSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnKSkgewogICAgICAgICAgICAkYXJnc1snLS1pZ25vcmUtcGxhdGZvcm0tcmVxcyddID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgJGFyZ3NbJy0tZm9ybWF0J10gPSAkaW5wdXQtPmdldE9wdGlvbignZm9ybWF0Jyk7CiAgICAgICAgJGFyZ3NbJy0taWdub3JlJ10gPSAkaW5wdXQtPmdldE9wdGlvbignaWdub3JlJyk7CgogICAgICAgICRpbnB1dCA9IG5ldyBBcnJheUlucHV0KCRhcmdzKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5ydW4oJGlucHV0LCAkb3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Byb3h5Q29tbWFuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXENvbmZpZ1ZhbGlkYXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcSW5pSGVscGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxTdHJlYW1Db250ZXh0RmFjdG9yeTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxTZWxmVXBkYXRlXEtleXM7CnVzZSBDb21wb3NlclxTZWxmVXBkYXRlXFZlcnNpb25zOwp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxYZGVidWdIYW5kbGVyXFhkZWJ1Z0hhbmRsZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGVjdXRhYmxlRmluZGVyOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIERpYWdub3NlQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwoKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwoKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJvdGVjdGVkICRleGl0Q29kZSA9IDA7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdkaWFnbm9zZScpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0RpYWdub3NlcyB0aGUgc3lzdGVtIHRvIGlkZW50aWZ5IGNvbW1vbiBlcnJvcnMuJykKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSA8aW5mbz5kaWFnbm9zZTwvaW5mbz4gY29tbWFuZCBjaGVja3MgY29tbW9uIGVycm9ycyB0byBoZWxwIGRlYnVnZ2luZyBwcm9ibGVtcy4KClRoZSBwcm9jZXNzIGV4aXQgY29kZSB3aWxsIGJlIDEgaW4gY2FzZSBvZiB3YXJuaW5ncyBhbmQgMiBmb3IgZXJyb3JzLgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjZGlhZ25vc2UKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnZGlhZ25vc2UnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaCgkY29tbWFuZEV2ZW50LT5nZXROYW1lKCksICRjb21tYW5kRXZlbnQpOwoKICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgY29tcG9zZXIuanNvbjogJywgZmFsc2UpOwogICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0NvbXBvc2VyU2NoZW1hKCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAkY29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCk7CiAgICAgICAgfQoKICAgICAgICAkY29uZmlnLT5tZXJnZShhcnJheSgnY29uZmlnJyA9PiBhcnJheSgnc2VjdXJlLWh0dHAnID0+IGZhbHNlKSksIENvbmZpZzo6U09VUkNFX0NPTU1BTkQpOwogICAgICAgICRjb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJ2h0dHA6Ly9yZXBvLnBhY2thZ2lzdC5vcmcnLCBuZXcgTnVsbElPKTsKCiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gRmFjdG9yeTo6Y3JlYXRlSHR0cERvd25sb2FkZXIoJGlvLCAkY29uZmlnKTsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKCiAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgcGxhdGZvcm0gc2V0dGluZ3M6ICcsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja1BsYXRmb3JtKCkpOwoKICAgICAgICAkaW8tPndyaXRlKCdDaGVja2luZyBnaXQgc2V0dGluZ3M6ICcsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0dpdCgpKTsKCiAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgaHR0cCBjb25uZWN0aXZpdHkgdG8gcGFja2FnaXN0OiAnLCBmYWxzZSk7CiAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tIdHRwKCdodHRwJywgJGNvbmZpZykpOwoKICAgICAgICAkaW8tPndyaXRlKCdDaGVja2luZyBodHRwcyBjb25uZWN0aXZpdHkgdG8gcGFja2FnaXN0OiAnLCBmYWxzZSk7CiAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tIdHRwKCdodHRwcycsICRjb25maWcpKTsKCiAgICAgICAgJG9wdHMgPSBzdHJlYW1fY29udGV4dF9nZXRfb3B0aW9ucyhTdHJlYW1Db250ZXh0RmFjdG9yeTo6Z2V0Q29udGV4dCgnaHR0cDovL2V4YW1wbGUub3JnJykpOwogICAgICAgIGlmICghZW1wdHkoJG9wdHNbJ2h0dHAnXVsncHJveHknXSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgSFRUUCBwcm94eTogJywgZmFsc2UpOwogICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0h0dHBQcm94eSgpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb2F1dGggPSAkY29uZmlnLT5nZXQoJ2dpdGh1Yi1vYXV0aCcpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvYXV0aCBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgJy4kZG9tYWluLicgb2F1dGggYWNjZXNzOiAnLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0dpdGh1Yk9hdXRoKCRkb21haW4sICR0b2tlbikpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgZ2l0aHViLmNvbSByYXRlIGxpbWl0OiAnLCBmYWxzZSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkcmF0ZSA9ICR0aGlzLT5nZXRHaXRodWJSYXRlTGltaXQoJ2dpdGh1Yi5jb20nKTsKICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHJhdGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkcmF0ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoMTAgPiAkcmF0ZVsncmVtYWluaW5nJ10pIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8d2FybmluZz5XQVJOSU5HPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJzxjb21tZW50PkdpdGh1YiBoYXMgYSByYXRlIGxpbWl0IG9uIHRoZWlyIEFQSS4gJwogICAgICAgICAgICAgICAgICAgICAgICAuICdZb3UgY3VycmVudGx5IGhhdmUgPG9wdGlvbnM9Ym9sZD4ldTwvb3B0aW9ucz1ib2xkPiAnCiAgICAgICAgICAgICAgICAgICAgICAgIC4gJ291dCBvZiA8b3B0aW9ucz1ib2xkPiV1PC9vcHRpb25zPWJvbGQ+IHJlcXVlc3RzIGxlZnQuJyAuIFBIUF9FT0wKICAgICAgICAgICAgICAgICAgICAgICAgLiAnU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLmdpdGh1Yi5jb20vdjMvI3JhdGUtbGltaXRpbmcgYW5kIGFsc28nIC4gUEhQX0VPTAogICAgICAgICAgICAgICAgICAgICAgICAuICcgICAgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jL2FydGljbGVzL3Ryb3VibGVzaG9vdGluZy5tZCNhcGktcmF0ZS1saW1pdC1hbmQtb2F1dGgtdG9rZW5zPC9jb21tZW50PicsCiAgICAgICAgICAgICAgICAgICAgICAgICRyYXRlWydyZW1haW5pbmcnXSwKICAgICAgICAgICAgICAgICAgICAgICAgJHJhdGVbJ2xpbWl0J10KICAgICAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCh0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRDb2RlKCkgPT09IDQwMSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vdXRwdXRSZXN1bHQoJzxjb21tZW50PlRoZSBvYXV0aCB0b2tlbiBmb3IgZ2l0aHViLmNvbSBzZWVtcyBpbnZhbGlkLCBydW4gImNvbXBvc2VyIGNvbmZpZyAtLWdsb2JhbCAtLXVuc2V0IGdpdGh1Yi1vYXV0aC5naXRodWIuY29tIiB0byByZW1vdmUgaXQ8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vdXRwdXRSZXN1bHQoJGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlKCdDaGVja2luZyBkaXNrIGZyZWUgc3BhY2U6ICcsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0Rpc2tTcGFjZSgkY29uZmlnKSk7CgogICAgICAgIGlmIChzdHJwb3MoX19GSUxFX18sICdwaGFyOicpID09PSAwKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJ0NoZWNraW5nIHB1YmtleXM6ICcsIGZhbHNlKTsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tQdWJLZXlzKCRjb25maWcpKTsKCiAgICAgICAgICAgICRpby0+d3JpdGUoJ0NoZWNraW5nIGNvbXBvc2VyIHZlcnNpb246ICcsIGZhbHNlKTsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tWZXJzaW9uKCRjb25maWcpKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoc3ByaW50ZignQ29tcG9zZXIgdmVyc2lvbjogPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywgQ29tcG9zZXI6OmdldFZlcnNpb24oKSkpOwoKICAgICAgICAkcGxhdGZvcm1PdmVycmlkZXMgPSAkY29uZmlnLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKTsKICAgICAgICAkcGxhdGZvcm1SZXBvID0gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkcGxhdGZvcm1PdmVycmlkZXMpOwogICAgICAgICRwaHBQa2cgPSAkcGxhdGZvcm1SZXBvLT5maW5kUGFja2FnZSgncGhwJywgJyonKTsKICAgICAgICAkcGhwVmVyc2lvbiA9ICRwaHBQa2ctPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICBpZiAoJHBocFBrZyBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAmJiBmYWxzZSAhPT0gc3RycG9zKCRwaHBQa2ctPmdldERlc2NyaXB0aW9uKCksICdvdmVycmlkZGVuJykpIHsKICAgICAgICAgICAgJHBocFZlcnNpb24gLj0gJyAtICcgLiAkcGhwUGtnLT5nZXREZXNjcmlwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZShzcHJpbnRmKCdQSFAgdmVyc2lvbjogPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywgJHBocFZlcnNpb24pKTsKCiAgICAgICAgaWYgKGRlZmluZWQoJ1BIUF9CSU5BUlknKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKHNwcmludGYoJ1BIUCBiaW5hcnkgcGF0aDogPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywgUEhQX0JJTkFSWSkpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZSgnT3BlblNTTCB2ZXJzaW9uOiAnIC4gKGRlZmluZWQoJ09QRU5TU0xfVkVSU0lPTl9URVhUJykgPyAnPGNvbW1lbnQ+Jy5PUEVOU1NMX1ZFUlNJT05fVEVYVC4nPC9jb21tZW50PicgOiAnPGVycm9yPm1pc3Npbmc8L2Vycm9yPicpKTsKICAgICAgICAkaW8tPndyaXRlKCdjVVJMIHZlcnNpb246ICcgLiAkdGhpcy0+Z2V0Q3VybFZlcnNpb24oKSk7CgogICAgICAgICRmaW5kZXIgPSBuZXcgRXhlY3V0YWJsZUZpbmRlcjsKICAgICAgICAkaGFzU3lzdGVtVW56aXAgPSAoYm9vbCkgJGZpbmRlci0+ZmluZCgndW56aXAnKTsKICAgICAgICAkYmluN3ppcCA9ICcnOwogICAgICAgIGlmICgkaGFzU3lzdGVtN3ppcCA9IChib29sKSAkZmluZGVyLT5maW5kKCc3eicsIG51bGwsIGFycmF5KCdDOlxQcm9ncmFtIEZpbGVzXDctWmlwJykpKSB7CiAgICAgICAgICAgICRiaW43emlwID0gJzd6JzsKICAgICAgICB9CiAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgISRoYXNTeXN0ZW03emlwICYmICRoYXNTeXN0ZW03emlwID0gKGJvb2wpICRmaW5kZXItPmZpbmQoJzd6eicpKSB7CiAgICAgICAgICAgICRiaW43emlwID0gJzd6eic7CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlKAogICAgICAgICAgICAnemlwOiAnIC4gKGV4dGVuc2lvbl9sb2FkZWQoJ3ppcCcpID8gJzxjb21tZW50PmV4dGVuc2lvbiBwcmVzZW50PC9jb21tZW50PicgOiAnPGNvbW1lbnQ+ZXh0ZW5zaW9uIG5vdCBsb2FkZWQ8L2NvbW1lbnQ+JykKICAgICAgICAgICAgLiAnLCAnIC4gKCRoYXNTeXN0ZW1VbnppcCA/ICc8Y29tbWVudD51bnppcCBwcmVzZW50PC9jb21tZW50PicgOiAnPGNvbW1lbnQ+dW56aXAgbm90IGF2YWlsYWJsZTwvY29tbWVudD4nKQogICAgICAgICAgICAuICcsICcgLiAoJGhhc1N5c3RlbTd6aXAgPyAnPGNvbW1lbnQ+Ny1aaXAgcHJlc2VudCAoJy4kYmluN3ppcC4nKTwvY29tbWVudD4nIDogJzxjb21tZW50PjctWmlwIG5vdCBhdmFpbGFibGU8L2NvbW1lbnQ+JykKICAgICAgICAgICAgLiAoKCRoYXNTeXN0ZW03emlwIHx8ICRoYXNTeXN0ZW1VbnppcCkgJiYgIWZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykgPyAnLCA8d2FybmluZz5wcm9jX29wZW4gaXMgZGlzYWJsZWQgb3Igbm90IHByZXNlbnQsIHVuemlwLzcteiB3aWxsIG5vdCBiZSB1c2FibGU8L3dhcm5pbmc+JyA6ICcnKQogICAgICAgICk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZXhpdENvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3x0cnVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tDb21wb3NlclNjaGVtYSgpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9IG5ldyBDb25maWdWYWxpZGF0b3IoJHRoaXMtPmdldElPKCkpOwogICAgICAgIGxpc3QoJGVycm9ycywgLCAkd2FybmluZ3MpID0gJHZhbGlkYXRvci0+dmFsaWRhdGUoRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCkpOwoKICAgICAgICBpZiAoJGVycm9ycyB8fCAkd2FybmluZ3MpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnZXJyb3InID0+ICRlcnJvcnMsCiAgICAgICAgICAgICAgICAnd2FybmluZycgPT4gJHdhcm5pbmdzLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJG91dHB1dCA9ICcnOwogICAgICAgICAgICBmb3JlYWNoICgkbWVzc2FnZXMgYXMgJHN0eWxlID0+ICRtc2dzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbXNncyBhcyAkbXNnKSB7CiAgICAgICAgICAgICAgICAgICAgJG91dHB1dCAuPSAnPCcgLiAkc3R5bGUgLiAnPicgLiAkbXNnIC4gJzwvJyAuICRzdHlsZSAuICc+JyAuIFBIUF9FT0w7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBydHJpbSgkb3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmd8dHJ1ZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrR2l0KCkKICAgIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgcmV0dXJuICc8Y29tbWVudD5wcm9jX29wZW4gaXMgbm90IGF2YWlsYWJsZSwgZ2l0IGNhbm5vdCBiZSB1c2VkPC9jb21tZW50Pic7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNvbmZpZyBjb2xvci51aScsICRvdXRwdXQpOwogICAgICAgIGlmIChzdHJ0b2xvd2VyKHRyaW0oJG91dHB1dCkpID09PSAnYWx3YXlzJykgewogICAgICAgICAgICByZXR1cm4gJzxjb21tZW50PllvdXIgZ2l0IGNvbG9yLnVpIHNldHRpbmcgaXMgc2V0IHRvIGFsd2F5cywgdGhpcyBpcyBrbm93biB0byBjcmVhdGUgaXNzdWVzLiBVc2UgImdpdCBjb25maWcgLS1nbG9iYWwgY29sb3IudWkgdHJ1ZSIgdG8gc2V0IGl0IGNvcnJlY3RseS48L2NvbW1lbnQ+JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJvdG8KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xzdHJpbmdbXXx0cnVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tIdHRwKCRwcm90bywgQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jaGVja0Nvbm5lY3Rpdml0eSgpOwogICAgICAgIGlmICgkcmVzdWx0ICE9PSB0cnVlKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRwcm90byA9PT0gJ2h0dHBzJyAmJiAkY29uZmlnLT5nZXQoJ2Rpc2FibGUtdGxzJykgPT09IHRydWUpIHsKICAgICAgICAgICAgJHRsc1dhcm5pbmcgPSAnPHdhcm5pbmc+Q29tcG9zZXIgaXMgY29uZmlndXJlZCB0byBkaXNhYmxlIFNTTC9UTFMgcHJvdGVjdGlvbi4gVGhpcyB3aWxsIGxlYXZlIHJlbW90ZSBIVFRQUyByZXF1ZXN0cyB2dWxuZXJhYmxlIHRvIE1hbi1Jbi1UaGUtTWlkZGxlIGF0dGFja3MuPC93YXJuaW5nPic7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkcHJvdG8gLiAnOi8vcmVwby5wYWNrYWdpc3Qub3JnL3BhY2thZ2VzLmpzb24nKTsKICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRoaW50cyA9IEh0dHBEb3dubG9hZGVyOjpnZXRFeGNlcHRpb25IaW50cygkZSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRoaW50cyBhcyAkaGludCkgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9ICRoaW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzdWx0W10gPSAnPGVycm9yPlsnIC4gZ2V0X2NsYXNzKCRlKSAuICddICcgLiAkZS0+Z2V0TWVzc2FnZSgpIC4gJzwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkdGxzV2FybmluZykpIHsKICAgICAgICAgICAgJHJlc3VsdFtdID0gJHRsc1dhcm5pbmc7CiAgICAgICAgfQoKICAgICAgICBpZiAoY291bnQoJHJlc3VsdCkgPiAwKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3x0cnVlfFxFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0h0dHBQcm94eSgpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jaGVja0Nvbm5lY3Rpdml0eSgpOwogICAgICAgIGlmICgkcmVzdWx0ICE9PSB0cnVlKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgJHByb3RvY29sID0gZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpID8gJ2h0dHBzJyA6ICdodHRwJzsKICAgICAgICB0cnkgewogICAgICAgICAgICAkanNvbiA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRwcm90b2NvbCAuICc6Ly9yZXBvLnBhY2thZ2lzdC5vcmcvcGFja2FnZXMuanNvbicpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgICAgICRoYXNoID0gcmVzZXQoJGpzb25bJ3Byb3ZpZGVyLWluY2x1ZGVzJ10pOwogICAgICAgICAgICAkaGFzaCA9ICRoYXNoWydzaGEyNTYnXTsKICAgICAgICAgICAgJHBhdGggPSBzdHJfcmVwbGFjZSgnJWhhc2glJywgJGhhc2gsIGtleSgkanNvblsncHJvdmlkZXItaW5jbHVkZXMnXSkpOwogICAgICAgICAgICAkcHJvdmlkZXIgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkcHJvdG9jb2wgLiAnOi8vcmVwby5wYWNrYWdpc3Qub3JnLycuJHBhdGgpLT5nZXRCb2R5KCk7CgogICAgICAgICAgICBpZiAoaGFzaCgnc2hhMjU2JywgJHByb3ZpZGVyKSAhPT0gJGhhc2gpIHsKICAgICAgICAgICAgICAgIHJldHVybiAnSXQgc2VlbXMgdGhhdCB5b3VyIHByb3h5IGlzIG1vZGlmeWluZyBodHRwIHRyYWZmaWMgb24gdGhlIGZseSc7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHJldHVybiAkZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0b2tlbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfHRydWV8XEV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrR2l0aHViT2F1dGgoJGRvbWFpbiwgJHRva2VuKQogICAgewogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y2hlY2tDb25uZWN0aXZpdHkoKTsKICAgICAgICBpZiAoJHJlc3VsdCAhPT0gdHJ1ZSkgewogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5nZXRJTygpLT5zZXRBdXRoZW50aWNhdGlvbigkZG9tYWluLCAkdG9rZW4sICd4LW9hdXRoLWJhc2ljJyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHVybCA9ICRkb21haW4gPT09ICdnaXRodWIuY29tJyA/ICdodHRwczovL2FwaS4nLiRkb21haW4uJy8nIDogJ2h0dHBzOi8vJy4kZG9tYWluLicvYXBpL3YzLyc7CgogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkdXJsLCBhcnJheSgKICAgICAgICAgICAgICAgICdyZXRyeS1hdXRoLWZhaWx1cmUnID0+IGZhbHNlLAogICAgICAgICAgICApKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRDb2RlKCkgPT09IDQwMSkgewogICAgICAgICAgICAgICAgcmV0dXJuICc8Y29tbWVudD5UaGUgb2F1dGggdG9rZW4gZm9yICcuJGRvbWFpbi4nIHNlZW1zIGludmFsaWQsIHJ1biAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tdW5zZXQgZ2l0aHViLW9hdXRoLicuJGRvbWFpbi4nIiB0byByZW1vdmUgaXQ8L2NvbW1lbnQ+JzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICRkb21haW4KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICR0b2tlbgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gbWl4ZWR8c3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0R2l0aHViUmF0ZUxpbWl0KCRkb21haW4sICR0b2tlbiA9IG51bGwpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jaGVja0Nvbm5lY3Rpdml0eSgpOwogICAgICAgIGlmICgkcmVzdWx0ICE9PSB0cnVlKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0b2tlbikgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+c2V0QXV0aGVudGljYXRpb24oJGRvbWFpbiwgJHRva2VuLCAneC1vYXV0aC1iYXNpYycpOwogICAgICAgIH0KCiAgICAgICAgJHVybCA9ICRkb21haW4gPT09ICdnaXRodWIuY29tJyA/ICdodHRwczovL2FwaS4nLiRkb21haW4uJy9yYXRlX2xpbWl0JyA6ICdodHRwczovLycuJGRvbWFpbi4nL2FwaS9yYXRlX2xpbWl0JzsKICAgICAgICAkZGF0YSA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCR1cmwsIGFycmF5KCdyZXRyeS1hdXRoLWZhaWx1cmUnID0+IGZhbHNlKSktPmRlY29kZUpzb24oKTsKCiAgICAgICAgcmV0dXJuICRkYXRhWydyZXNvdXJjZXMnXVsnY29yZSddOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmd8dHJ1ZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrRGlza1NwYWNlKENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICRtaW5TcGFjZUZyZWUgPSAxMDI0ICogMTAyNDsKICAgICAgICBpZiAoKCgkZGYgPSBAZGlza19mcmVlX3NwYWNlKCRkaXIgPSAkY29uZmlnLT5nZXQoJ2hvbWUnKSkpICE9PSBmYWxzZSAmJiAkZGYgPCAkbWluU3BhY2VGcmVlKQogICAgICAgICAgICB8fCAoKCRkZiA9IEBkaXNrX2ZyZWVfc3BhY2UoJGRpciA9ICRjb25maWctPmdldCgndmVuZG9yLWRpcicpKSkgIT09IGZhbHNlICYmICRkZiA8ICRtaW5TcGFjZUZyZWUpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiAnPGVycm9yPlRoZSBkaXNrIGhvc3RpbmcgJy4kZGlyLicgaXMgZnVsbDwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXXx0cnVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tQdWJLZXlzKENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICRob21lID0gJGNvbmZpZy0+Z2V0KCdob21lJyk7CiAgICAgICAgJGVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkaG9tZS4nL2tleXMudGFncy5wdWInKSAmJiBmaWxlX2V4aXN0cygkaG9tZS4nL2tleXMuZGV2LnB1YicpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJycpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRob21lLicva2V5cy50YWdzLnB1YicpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJ1RhZ3MgUHVibGljIEtleSBGaW5nZXJwcmludDogJyAuIEtleXM6OmZpbmdlcnByaW50KCRob21lLicva2V5cy50YWdzLnB1YicpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZXJyb3JzW10gPSAnPGVycm9yPk1pc3NpbmcgcHVia2V5IGZvciB0YWdzIHZlcmlmaWNhdGlvbjwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkaG9tZS4nL2tleXMuZGV2LnB1YicpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJ0RldiBQdWJsaWMgS2V5IEZpbmdlcnByaW50OiAnIC4gS2V5czo6ZmluZ2VycHJpbnQoJGhvbWUuJy9rZXlzLmRldi5wdWInKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGVycm9yc1tdID0gJzxlcnJvcj5NaXNzaW5nIHB1YmtleSBmb3IgZGV2IHZlcmlmaWNhdGlvbjwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgIGlmICgkZXJyb3JzKSB7CiAgICAgICAgICAgICRlcnJvcnNbXSA9ICc8ZXJyb3I+UnVuIGNvbXBvc2VyIHNlbGYtdXBkYXRlIC0tdXBkYXRlLWtleXMgdG8gc2V0IHRoZW0gdXA8L2Vycm9yPic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGVycm9ycyA/OiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmd8XEV4Y2VwdGlvbnx0cnVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tWZXJzaW9uKENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y2hlY2tDb25uZWN0aXZpdHkoKTsKICAgICAgICBpZiAoJHJlc3VsdCAhPT0gdHJ1ZSkgewogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9uc1V0aWwgPSBuZXcgVmVyc2lvbnMoJGNvbmZpZywgJHRoaXMtPmh0dHBEb3dubG9hZGVyKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkbGF0ZXN0ID0gJHZlcnNpb25zVXRpbC0+Z2V0TGF0ZXN0KCk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICByZXR1cm4gJGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoQ29tcG9zZXI6OlZFUlNJT04gIT09ICRsYXRlc3RbJ3ZlcnNpb24nXSAmJiBDb21wb3Nlcjo6VkVSU0lPTiAhPT0gJ0BwYWNrYWdlX3ZlcnNpb25AJykgewogICAgICAgICAgICByZXR1cm4gJzxjb21tZW50PllvdSBhcmUgbm90IHJ1bm5pbmcgdGhlIGxhdGVzdCAnLiR2ZXJzaW9uc1V0aWwtPmdldENoYW5uZWwoKS4nIHZlcnNpb24sIHJ1biBgY29tcG9zZXIgc2VsZi11cGRhdGVgIHRvIHVwZGF0ZSAoJy5Db21wb3Nlcjo6VkVSU0lPTi4nID0+ICcuJGxhdGVzdFsndmVyc2lvbiddLicpPC9jb21tZW50Pic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q3VybFZlcnNpb24oKQogICAgewogICAgICAgIGlmIChleHRlbnNpb25fbG9hZGVkKCdjdXJsJykpIHsKICAgICAgICAgICAgaWYgKCFIdHRwRG93bmxvYWRlcjo6aXNDdXJsRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJzxlcnJvcj5kaXNhYmxlZCB2aWEgZGlzYWJsZV9mdW5jdGlvbnMsIHVzaW5nIHBocCBzdHJlYW1zIGZhbGxiYWNrLCB3aGljaCByZWR1Y2VzIHBlcmZvcm1hbmNlPC9lcnJvcj4nOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdmVyc2lvbiA9IGN1cmxfdmVyc2lvbigpOwoKICAgICAgICAgICAgcmV0dXJuICc8Y29tbWVudD4nLiR2ZXJzaW9uWyd2ZXJzaW9uJ10uJzwvY29tbWVudD4gJy4KICAgICAgICAgICAgICAgICdsaWJ6IDxjb21tZW50PicuKCFlbXB0eSgkdmVyc2lvblsnbGliel92ZXJzaW9uJ10pID8gJHZlcnNpb25bJ2xpYnpfdmVyc2lvbiddIDogJ21pc3NpbmcnKS4nPC9jb21tZW50PiAnLgogICAgICAgICAgICAgICAgJ3NzbCA8Y29tbWVudD4nLihpc3NldCgkdmVyc2lvblsnc3NsX3ZlcnNpb24nXSkgPyAkdmVyc2lvblsnc3NsX3ZlcnNpb24nXSA6ICdtaXNzaW5nJykuJzwvY29tbWVudD4nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICc8ZXJyb3I+bWlzc2luZywgdXNpbmcgcGhwIHN0cmVhbXMgZmFsbGJhY2ssIHdoaWNoIHJlZHVjZXMgcGVyZm9ybWFuY2U8L2Vycm9yPic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbHxzdHJpbmd8c3RyaW5nW118XEV4Y2VwdGlvbiAkcmVzdWx0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3V0cHV0UmVzdWx0KCRyZXN1bHQpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKHRydWUgPT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+T0s8L2luZm8+Jyk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkaGFkRXJyb3IgPSBmYWxzZTsKICAgICAgICAkaGFkV2FybmluZyA9IGZhbHNlOwogICAgICAgIGlmICgkcmVzdWx0IGluc3RhbmNlb2YgXEV4Y2VwdGlvbikgewogICAgICAgICAgICAkcmVzdWx0ID0gJzxlcnJvcj5bJy5nZXRfY2xhc3MoJHJlc3VsdCkuJ10gJy4kcmVzdWx0LT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgIGlmICghJHJlc3VsdCkgewogICAgICAgICAgICAvLyBmYWxzZXkgcmVzdWx0cyBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBhbiBlcnJvciwgZXZlbiBpZiB0aGVyZSBpcyBub3RoaW5nIHRvIG91dHB1dAogICAgICAgICAgICAkaGFkRXJyb3IgPSB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHJlc3VsdCkpIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSBhcnJheSgkcmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkcmVzdWx0IGFzICRtZXNzYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkbWVzc2FnZSwgJzxlcnJvcj4nKSkgewogICAgICAgICAgICAgICAgICAgICRoYWRFcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoZmFsc2UgIT09IHN0cnBvcygkbWVzc2FnZSwgJzx3YXJuaW5nPicpKSB7CiAgICAgICAgICAgICAgICAgICAgJGhhZFdhcm5pbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhZEVycm9yKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJzxlcnJvcj5GQUlMPC9lcnJvcj4nKTsKICAgICAgICAgICAgJHRoaXMtPmV4aXRDb2RlID0gbWF4KCR0aGlzLT5leGl0Q29kZSwgMik7CiAgICAgICAgfSBlbHNlaWYgKCRoYWRXYXJuaW5nKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJzx3YXJuaW5nPldBUk5JTkc8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICR0aGlzLT5leGl0Q29kZSA9IG1heCgkdGhpcy0+ZXhpdENvZGUsIDEpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXN1bHQpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlc3VsdCBhcyAkbWVzc2FnZSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgkbWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3x0cnVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tQbGF0Zm9ybSgpCiAgICB7CiAgICAgICAgJG91dHB1dCA9ICcnOwogICAgICAgICRvdXQgPSBmdW5jdGlvbiAoJG1zZywgJHN0eWxlKSB1c2UgKCYkb3V0cHV0KSB7CiAgICAgICAgICAgICRvdXRwdXQgLj0gJzwnLiRzdHlsZS4nPicuJG1zZy4nPC8nLiRzdHlsZS4nPicuUEhQX0VPTDsKICAgICAgICB9OwoKICAgICAgICAvLyBjb2RlIGJlbG93IHRha2VuIGZyb20gZ2V0Y29tcG9zZXIub3JnL2luc3RhbGxlciwgYW55IGNoYW5nZXMgc2hvdWxkIGJlIG1hZGUgdGhlcmUgYW5kIHJlcGxpY2F0ZWQgaGVyZQogICAgICAgICRlcnJvcnMgPSBhcnJheSgpOwogICAgICAgICR3YXJuaW5ncyA9IGFycmF5KCk7CiAgICAgICAgJGRpc3BsYXlJbmlNZXNzYWdlID0gZmFsc2U7CgogICAgICAgICRpbmlNZXNzYWdlID0gUEhQX0VPTC5QSFBfRU9MLkluaUhlbHBlcjo6Z2V0TWVzc2FnZSgpOwogICAgICAgICRpbmlNZXNzYWdlIC49IFBIUF9FT0wuJ0lmIHlvdSBjYW4gbm90IG1vZGlmeSB0aGUgaW5pIGZpbGUsIHlvdSBjYW4gYWxzbyBydW4gYHBocCAtZCBvcHRpb249dmFsdWVgIHRvIG1vZGlmeSBpbmkgdmFsdWVzIG9uIHRoZSBmbHkuIFlvdSBjYW4gdXNlIC1kIG11bHRpcGxlIHRpbWVzLic7CgogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCdqc29uX2RlY29kZScpKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ2pzb24nXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ1BoYXInKSkgewogICAgICAgICAgICAkZXJyb3JzWydwaGFyJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdmaWx0ZXInKSkgewogICAgICAgICAgICAkZXJyb3JzWydmaWx0ZXInXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ2hhc2gnKSkgewogICAgICAgICAgICAkZXJyb3JzWydoYXNoJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdpY29udicpICYmICFleHRlbnNpb25fbG9hZGVkKCdtYnN0cmluZycpKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ2ljb252X21ic3RyaW5nJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFmaWx0ZXJfdmFyKGluaV9nZXQoJ2FsbG93X3VybF9mb3BlbicpLCBGSUxURVJfVkFMSURBVEVfQk9PTEVBTikpIHsKICAgICAgICAgICAgJGVycm9yc1snYWxsb3dfdXJsX2ZvcGVuJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ2lvbkN1YmUgTG9hZGVyJykgJiYgaW9uY3ViZV9sb2FkZXJfaXZlcnNpb24oKSA8IDQwMDA5KSB7CiAgICAgICAgICAgICRlcnJvcnNbJ2lvbmN1YmUnXSA9IGlvbmN1YmVfbG9hZGVyX3ZlcnNpb24oKTsKICAgICAgICB9CgogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA8IDUwMzAyKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ3BocCddID0gUEhQX1ZFUlNJT047CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRlcnJvcnNbJ3BocCddKSAmJiBQSFBfVkVSU0lPTl9JRCA8IDUwMzA0KSB7CiAgICAgICAgICAgICR3YXJuaW5nc1sncGhwJ10gPSBQSFBfVkVSU0lPTjsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ29wZW5zc2wnXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpICYmIE9QRU5TU0xfVkVSU0lPTl9OVU1CRVIgPCAweDEwMDAxMDBmKSB7CiAgICAgICAgICAgICR3YXJuaW5nc1snb3BlbnNzbF92ZXJzaW9uJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSAmJiAhZXh0ZW5zaW9uX2xvYWRlZCgnYXBjdScpICYmIGZpbHRlcl92YXIoaW5pX2dldCgnYXBjLmVuYWJsZV9jbGknKSwgRklMVEVSX1ZBTElEQVRFX0JPT0xFQU4pKSB7CiAgICAgICAgICAgICR3YXJuaW5nc1snYXBjX2NsaSddID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnemxpYicpKSB7CiAgICAgICAgICAgICR3YXJuaW5nc1snemxpYiddID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIG9iX3N0YXJ0KCk7CiAgICAgICAgcGhwaW5mbyhJTkZPX0dFTkVSQUwpOwogICAgICAgICRwaHBpbmZvID0gb2JfZ2V0X2NsZWFuKCk7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3tDb25maWd1cmUgQ29tbWFuZCg/OiAqPC90ZD48dGQgY2xhc3M9InYiPnwgKj0+ICopKC4qPykoPzo8L3RkPnwkKX1tJywgJHBocGluZm8sICRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbmZpZ3VyZSA9ICRtYXRjaFsxXTsKCiAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCRjb25maWd1cmUsICctLWVuYWJsZS1zaWdjaGlsZCcpKSB7CiAgICAgICAgICAgICAgICAkd2FybmluZ3NbJ3NpZ2NoaWxkJ10gPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkY29uZmlndXJlLCAnLS13aXRoLWN1cmx3cmFwcGVycycpKSB7CiAgICAgICAgICAgICAgICAkd2FybmluZ3NbJ2N1cmx3cmFwcGVycyddID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbHRlcl92YXIoaW5pX2dldCgneGRlYnVnLnByb2ZpbGVyX2VuYWJsZWQnKSwgRklMVEVSX1ZBTElEQVRFX0JPT0xFQU4pKSB7CiAgICAgICAgICAgICR3YXJuaW5nc1sneGRlYnVnX3Byb2ZpbGUnXSA9IHRydWU7CiAgICAgICAgfSBlbHNlaWYgKFhkZWJ1Z0hhbmRsZXI6OmlzWGRlYnVnQWN0aXZlKCkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWyd4ZGVidWdfbG9hZGVkJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRlZmluZWQoJ1BIUF9XSU5ET1dTX1ZFUlNJT05fQlVJTEQnKQogICAgICAgICAgICAmJiAodmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNy4yLjIzJywgJzwnKQogICAgICAgICAgICB8fCAodmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNy4zLjAnLCAnPj0nKQogICAgICAgICAgICAmJiB2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc3LjMuMTAnLCAnPCcpKSkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWydvbmVkcml2ZSddID0gUEhQX1ZFUlNJT047CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRlcnJvcnMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRlcnJvcnMgYXMgJGVycm9yID0+ICRjdXJyZW50KSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCRlcnJvcikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2pzb24nOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBqc29uIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgaXQgb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1qc29uIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3BoYXInOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBwaGFyIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgaXQgb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1waGFyIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gUEhQX0VPTC4iVGhlIGZpbHRlciBleHRlbnNpb24gaXMgbWlzc2luZy4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJJbnN0YWxsIGl0IG9yIHJlY29tcGlsZSBwaHAgd2l0aG91dCAtLWRpc2FibGUtZmlsdGVyIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2hhc2gnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBoYXNoIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgaXQgb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1oYXNoIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ljb252X21ic3RyaW5nJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSBQSFBfRU9MLiJUaGUgaWNvbnYgT1IgbWJzdHJpbmcgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkIGFuZCBib3RoIGFyZSBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgZWl0aGVyIG9mIHRoZW0gb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1pY29udiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdwaHAnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIllvdXIgUEhQICh7JGN1cnJlbnR9KSBpcyB0b28gb2xkLCB5b3UgbXVzdCB1cGdyYWRlIHRvIFBIUCA1LjMuMiBvciBoaWdoZXIuIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2FsbG93X3VybF9mb3Blbic6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gUEhQX0VPTC4iVGhlIGFsbG93X3VybF9mb3BlbiBzZXR0aW5nIGlzIGluY29ycmVjdC4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJBZGQgdGhlIGZvbGxvd2luZyB0byB0aGUgZW5kIG9mIHlvdXIgYHBocC5pbmlgOiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIiAgICBhbGxvd191cmxfZm9wZW4gPSBPbiI7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXNwbGF5SW5pTWVzc2FnZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdpb25jdWJlJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSBQSFBfRU9MLiJZb3VyIGlvbkN1YmUgTG9hZGVyIGV4dGVuc2lvbiAoJGN1cnJlbnQpIGlzIGluY29tcGF0aWJsZSB3aXRoIFBoYXIgZmlsZXMuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiVXBncmFkZSB0byBpb25DdWJlIDQuMC45IG9yIGhpZ2hlciBvciByZW1vdmUgdGhpcyBsaW5lIChwYXRoIG1heSBiZSBkaWZmZXJlbnQpIGZyb20geW91ciBgcGhwLmluaWAgdG8gZGlzYWJsZSBpdDoiLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICIgICAgemVuZF9leHRlbnNpb24gPSAvdXNyL2xpYi9waHA1LzIwMDkwNjI2K2xmcy9pb25jdWJlX2xvYWRlcl9saW5fNS4zLnNvIjsKICAgICAgICAgICAgICAgICAgICAgICAgJGRpc3BsYXlJbmlNZXNzYWdlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ29wZW5zc2wnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBvcGVuc3NsIGV4dGVuc2lvbiBpcyBtaXNzaW5nLCB3aGljaCBtZWFucyB0aGF0IHNlY3VyZSBIVFRQUyB0cmFuc2ZlcnMgYXJlIGltcG9zc2libGUuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiSWYgcG9zc2libGUgeW91IHNob3VsZCBlbmFibGUgaXQgb3IgcmVjb21waWxlIHBocCB3aXRoIC0td2l0aC1vcGVuc3NsIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoIkRpYWdub3NlQ29tbWFuZDogVW5rbm93biBlcnJvciB0eXBlIFwiJXNcIi4gUGxlYXNlIHJlcG9ydCBhdCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzL25ldy4iLCAkZXJyb3IpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRvdXQoJHRleHQsICdlcnJvcicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkb3V0cHV0IC49IFBIUF9FT0w7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR3YXJuaW5ncykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHdhcm5pbmdzIGFzICR3YXJuaW5nID0+ICRjdXJyZW50KSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCR3YXJuaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXBjX2NsaSc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlRoZSBhcGMuZW5hYmxlX2NsaSBzZXR0aW5nIGlzIGluY29ycmVjdC4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJBZGQgdGhlIGZvbGxvd2luZyB0byB0aGUgZW5kIG9mIHlvdXIgYHBocC5pbmlgOiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIiAgYXBjLmVuYWJsZV9jbGkgPSBPZmYiOwogICAgICAgICAgICAgICAgICAgICAgICAkZGlzcGxheUluaU1lc3NhZ2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnemxpYic6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gJ1RoZSB6bGliIGV4dGVuc2lvbiBpcyBub3QgbG9hZGVkLCB0aGlzIGNhbiBzbG93IGRvd24gQ29tcG9zZXIgYSBsb3QuJy5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAnSWYgcG9zc2libGUsIGVuYWJsZSBpdCBvciByZWNvbXBpbGUgcGhwIHdpdGggLS13aXRoLXpsaWInLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXNwbGF5SW5pTWVzc2FnZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdzaWdjaGlsZCc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlBIUCB3YXMgY29tcGlsZWQgd2l0aCAtLWVuYWJsZS1zaWdjaGlsZCB3aGljaCBjYW4gY2F1c2UgaXNzdWVzIG9uIHNvbWUgcGxhdGZvcm1zLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIlJlY29tcGlsZSBpdCB3aXRob3V0IHRoaXMgZmxhZyBpZiBwb3NzaWJsZSwgc2VlIGFsc286Ii5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiICBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTIyOTk5IjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2N1cmx3cmFwcGVycyc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlBIUCB3YXMgY29tcGlsZWQgd2l0aCAtLXdpdGgtY3VybHdyYXBwZXJzIHdoaWNoIHdpbGwgY2F1c2UgaXNzdWVzIHdpdGggSFRUUCBhdXRoZW50aWNhdGlvbiBhbmQgR2l0SHViLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIiBSZWNvbXBpbGUgaXQgd2l0aG91dCB0aGlzIGZsYWcgaWYgcG9zc2libGUiOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAncGhwJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSAiWW91ciBQSFAgKHskY3VycmVudH0pIGlzIHF1aXRlIG9sZCwgdXBncmFkaW5nIHRvIFBIUCA1LjMuNCBvciBoaWdoZXIgaXMgcmVjb21tZW5kZWQuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiIENvbXBvc2VyIHdvcmtzIHdpdGggNS4zLjIrIGZvciBtb3N0IHBlb3BsZSwgYnV0IHRoZXJlIG1pZ2h0IGJlIGVkZ2UgY2FzZSBpc3N1ZXMuIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ29wZW5zc2xfdmVyc2lvbic6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF0dGVtcHQgdG8gcGFyc2UgdmVyc2lvbiBudW1iZXIgb3V0LCBmYWxsYmFjayB0byB3aG9sZSBzdHJpbmcgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICRvcGVuc3NsVmVyc2lvbiA9IHN0cnN0cih0cmltKHN0cnN0cihPUEVOU1NMX1ZFUlNJT05fVEVYVCwgJyAnKSksICcgJywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRvcGVuc3NsVmVyc2lvbiA9ICRvcGVuc3NsVmVyc2lvbiA/OiBPUEVOU1NMX1ZFUlNJT05fVEVYVDsKCiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlRoZSBPcGVuU1NMIGxpYnJhcnkgKHskb3BlbnNzbFZlcnNpb259KSB1c2VkIGJ5IFBIUCBkb2VzIG5vdCBzdXBwb3J0IFRMU3YxLjIgb3IgVExTdjEuMS4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJJZiBwb3NzaWJsZSB5b3Ugc2hvdWxkIHVwZ3JhZGUgT3BlblNTTCB0byB2ZXJzaW9uIDEuMC4xIG9yIGFib3ZlLiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICd4ZGVidWdfbG9hZGVkJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSAiVGhlIHhkZWJ1ZyBleHRlbnNpb24gaXMgbG9hZGVkLCB0aGlzIGNhbiBzbG93IGRvd24gQ29tcG9zZXIgYSBsaXR0bGUuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiIERpc2FibGluZyBpdCB3aGVuIHVzaW5nIENvbXBvc2VyIGlzIHJlY29tbWVuZGVkLiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICd4ZGVidWdfcHJvZmlsZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlRoZSB4ZGVidWcucHJvZmlsZXJfZW5hYmxlZCBzZXR0aW5nIGlzIGVuYWJsZWQsIHRoaXMgY2FuIHNsb3cgZG93biBDb21wb3NlciBhIGxvdC4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJBZGQgdGhlIGZvbGxvd2luZyB0byB0aGUgZW5kIG9mIHlvdXIgYHBocC5pbmlgIHRvIGRpc2FibGUgaXQ6Ii5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiICB4ZGVidWcucHJvZmlsZXJfZW5hYmxlZCA9IDAiOwogICAgICAgICAgICAgICAgICAgICAgICAkZGlzcGxheUluaU1lc3NhZ2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnb25lZHJpdmUnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9ICJUaGUgV2luZG93cyBPbmVEcml2ZSBmb2xkZXIgaXMgbm90IHN1cHBvcnRlZCBvbiBQSFAgdmVyc2lvbnMgYmVsb3cgNy4yLjIzIGFuZCA3LjMuMTAuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiVXBncmFkZSB5b3VyIFBIUCAoeyRjdXJyZW50fSkgdG8gdXNlIHRoaXMgbG9jYXRpb24gd2l0aCBDb21wb3Nlci4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCJEaWFnbm9zZUNvbW1hbmQ6IFVua25vd24gd2FybmluZyB0eXBlIFwiJXNcIi4gUGxlYXNlIHJlcG9ydCBhdCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzL25ldy4iLCAkd2FybmluZykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG91dCgkdGV4dCwgJ2NvbW1lbnQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRkaXNwbGF5SW5pTWVzc2FnZSkgewogICAgICAgICAgICAkb3V0KCRpbmlNZXNzYWdlLCAnY29tbWVudCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICEkd2FybmluZ3MgJiYgISRlcnJvcnMgPyB0cnVlIDogJG91dHB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIGFsbG93X3VybF9mb3BlbiBpcyBPTgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfHRydWUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0Nvbm5lY3Rpdml0eSgpCiAgICB7CiAgICAgICAgaWYgKCFpbmlfZ2V0KCdhbGxvd191cmxfZm9wZW4nKSkgewogICAgICAgICAgICByZXR1cm4gJzxpbmZvPlNraXBwZWQgYmVjYXVzZSBhbGxvd191cmxfZm9wZW4gaXMgbWlzc2luZy48L2luZm8+JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CgovKioKICogQGF1dGhvciBOaWVscyBLZXVyZW50amVzIDxuaWVscy5rZXVyZW50amVzQG9taW5lcy5jb20+CiAqLwpjbGFzcyBQcm9oaWJpdHNDb21tYW5kIGV4dGVuZHMgQmFzZURlcGVuZGVuY3lDb21tYW5kCnsKICAgIC8qKgogICAgICogQ29uZmlndXJlIGNvbW1hbmQgbWV0YWRhdGEuCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgncHJvaGliaXRzJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCd3aHktbm90JykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1Nob3dzIHdoaWNoIHBhY2thZ2VzIHByZXZlbnQgdGhlIGdpdmVuIHBhY2thZ2UgZnJvbSBiZWluZyBpbnN0YWxsZWQuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoc2VsZjo6QVJHVU1FTlRfUEFDS0FHRSwgSW5wdXRBcmd1bWVudDo6UkVRVUlSRUQsICdQYWNrYWdlIHRvIGluc3BlY3QnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KHNlbGY6OkFSR1VNRU5UX0NPTlNUUkFJTlQsIElucHV0QXJndW1lbnQ6OlJFUVVJUkVELCAnVmVyc2lvbiBjb25zdHJhaW50LCB3aGljaCB2ZXJzaW9uIHlvdSBleHBlY3RlZCB0byBiZSBpbnN0YWxsZWQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbihzZWxmOjpPUFRJT05fUkVDVVJTSVZFLCAncicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUmVjdXJzaXZlbHkgcmVzb2x2ZXMgdXAgdG8gdGhlIHJvb3QgcGFja2FnZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKHNlbGY6Ok9QVElPTl9UUkVFLCAndCcsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJpbnRzIHRoZSByZXN1bHRzIGFzIGEgbmVzdGVkIHRyZWUnKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UCkRpc3BsYXlzIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHdoeSBhIHBhY2thZ2UgY2Fubm90IGJlIGluc3RhbGxlZC4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHByb2hpYml0cyBjb21wb3Nlci9jb21wb3NlcjwvaW5mbz4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3Byb2hpYml0cy13aHktbm90LQpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgcmV0dXJuIHBhcmVudDo6ZG9FeGVjdXRlKCRpbnB1dCwgJG91dHB1dCwgdHJ1ZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NpdGVSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKCi8qKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICovCmNsYXNzIFNlYXJjaENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3NlYXJjaCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1NlYXJjaGVzIGZvciBwYWNrYWdlcy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ29ubHktbmFtZScsICdOJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTZWFyY2ggb25seSBpbiBwYWNrYWdlIG5hbWVzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ29ubHktdmVuZG9yJywgJ08nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NlYXJjaCBvbmx5IGZvciB2ZW5kb3IgLyBvcmdhbml6YXRpb24gbmFtZXMsIHJldHVybnMgb25seSAidmVuZG9yIiBhcyByZXN1bHQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndHlwZScsICd0JywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnU2VhcmNoIGZvciBhIHNwZWNpZmljIHBhY2thZ2UgdHlwZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmb3JtYXQnLCAnZicsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0Zvcm1hdCBvZiB0aGUgb3V0cHV0OiB0ZXh0IG9yIGpzb24nLCAndGV4dCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3Rva2VucycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6UkVRVUlSRUQsICd0b2tlbnMgdG8gc2VhcmNoIGZvcicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIHNlYXJjaCBjb21tYW5kIHNlYXJjaGVzIGZvciBwYWNrYWdlcyBieSBpdHMgbmFtZQo8aW5mbz5waHAgY29tcG9zZXIucGhhciBzZWFyY2ggc3ltZm9ueSBjb21wb3NlcjwvaW5mbz4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3NlYXJjaApFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIC8vIGluaXQgcmVwb3MKICAgICAgICAkcGxhdGZvcm1SZXBvID0gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgJGZvcm1hdCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKTsKICAgICAgICBpZiAoIWluX2FycmF5KCRmb3JtYXQsIGFycmF5KCd0ZXh0JywgJ2pzb24nKSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoJ1Vuc3VwcG9ydGVkIGZvcm1hdCAiJXMiLiBTZWUgaGVscCBmb3Igc3VwcG9ydGVkIGZvcm1hdHMuJywgJGZvcm1hdCkpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoISgkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoZmFsc2UpKSkgewogICAgICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGUoJHRoaXMtPmdldElPKCksIGFycmF5KCksICRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKCctLW5vLXBsdWdpbnMnKSk7CiAgICAgICAgfQogICAgICAgICRsb2NhbFJlcG8gPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwogICAgICAgICRpbnN0YWxsZWRSZXBvID0gbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoYXJyYXkoJGxvY2FsUmVwbywgJHBsYXRmb3JtUmVwbykpOwogICAgICAgICRyZXBvcyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KGFycmF5X21lcmdlKGFycmF5KCRpbnN0YWxsZWRSZXBvKSwgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSkpOwoKICAgICAgICAkY29tbWFuZEV2ZW50ID0gbmV3IENvbW1hbmRFdmVudChQbHVnaW5FdmVudHM6OkNPTU1BTkQsICdzZWFyY2gnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoKCRjb21tYW5kRXZlbnQtPmdldE5hbWUoKSwgJGNvbW1hbmRFdmVudCk7CgogICAgICAgICRtb2RlID0gUmVwb3NpdG9yeUludGVyZmFjZTo6U0VBUkNIX0ZVTExURVhUOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignb25seS1uYW1lJykgPT09IHRydWUpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdvbmx5LXZlbmRvcicpID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignLS1vbmx5LW5hbWUgYW5kIC0tb25seS12ZW5kb3IgY2Fubm90IGJlIHVzZWQgdG9nZXRoZXInKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbW9kZSA9IFJlcG9zaXRvcnlJbnRlcmZhY2U6OlNFQVJDSF9OQU1FOwogICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmdldE9wdGlvbignb25seS12ZW5kb3InKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAkbW9kZSA9IFJlcG9zaXRvcnlJbnRlcmZhY2U6OlNFQVJDSF9WRU5ET1I7CiAgICAgICAgfQoKICAgICAgICAkdHlwZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCd0eXBlJyk7CgogICAgICAgICRxdWVyeSA9IGltcGxvZGUoJyAnLCAkaW5wdXQtPmdldEFyZ3VtZW50KCd0b2tlbnMnKSk7CiAgICAgICAgaWYgKCRtb2RlICE9PSBSZXBvc2l0b3J5SW50ZXJmYWNlOjpTRUFSQ0hfRlVMTFRFWFQpIHsKICAgICAgICAgICAgJHF1ZXJ5ID0gcHJlZ19xdW90ZSgkcXVlcnkpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdHMgPSAkcmVwb3MtPnNlYXJjaCgkcXVlcnksICRtb2RlLCAkdHlwZSk7CgogICAgICAgIGlmICgkcmVzdWx0cyAmJiAkZm9ybWF0ID09PSAndGV4dCcpIHsKICAgICAgICAgICAgJHdpZHRoID0gJHRoaXMtPmdldFRlcm1pbmFsV2lkdGgoKTsKCiAgICAgICAgICAgICRuYW1lTGVuZ3RoID0gMDsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICAgICAgJG5hbWVMZW5ndGggPSBtYXgoc3RybGVuKCRyZXN1bHRbJ25hbWUnXSksICRuYW1lTGVuZ3RoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbmFtZUxlbmd0aCArPSAxOwogICAgICAgICAgICBmb3JlYWNoICgkcmVzdWx0cyBhcyAkcmVzdWx0KSB7CiAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSBpc3NldCgkcmVzdWx0WydkZXNjcmlwdGlvbiddKSA/ICRyZXN1bHRbJ2Rlc2NyaXB0aW9uJ10gOiAnJzsKICAgICAgICAgICAgICAgICR3YXJuaW5nID0gIWVtcHR5KCRyZXN1bHRbJ2FiYW5kb25lZCddKSA/ICc8d2FybmluZz4hIEFiYW5kb25lZCAhPC93YXJuaW5nPiAnIDogJyc7CiAgICAgICAgICAgICAgICAkcmVtYWluaW5nID0gJHdpZHRoIC0gJG5hbWVMZW5ndGggLSBzdHJsZW4oJHdhcm5pbmcpIC0gMjsKICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oJGRlc2NyaXB0aW9uKSA+ICRyZW1haW5pbmcpIHsKICAgICAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSBzdWJzdHIoJGRlc2NyaXB0aW9uLCAwLCAkcmVtYWluaW5nIC0gMykgLiAnLi4uJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKHN0cl9wYWQoJHJlc3VsdFsnbmFtZSddLCAkbmFtZUxlbmd0aCwgJyAnKSAuICR3YXJuaW5nIC4gJGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkZm9ybWF0ID09PSAnanNvbicpIHsKICAgICAgICAgICAgJGlvLT53cml0ZShKc29uRmlsZTo6ZW5jb2RlKCRyZXN1bHRzKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDb25maWdcSnNvbkNvbmZpZ1NvdXJjZTsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxTZW12ZXJcVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CgovKioKICogQGF1dGhvciBKb3NodWEgRXN0ZXMgPEpvc2h1YS5Fc3Rlc0Bpb3N0dWRpby5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENvbmZpZ0NvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEB2YXIgQ29uZmlnCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnOwoKICAgIC8qKgogICAgICogQHZhciBKc29uRmlsZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZ0ZpbGU7CgogICAgLyoqCiAgICAgKiBAdmFyIEpzb25Db25maWdTb3VyY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRjb25maWdTb3VyY2U7CgogICAgLyoqCiAgICAgKiBAdmFyIEpzb25GaWxlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXV0aENvbmZpZ0ZpbGU7CgogICAgLyoqCiAgICAgKiBAdmFyIEpzb25Db25maWdTb3VyY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRhdXRoQ29uZmlnU291cmNlOwoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnY29uZmlnJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2V0cyBjb25maWcgb3B0aW9ucy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2dsb2JhbCcsICdnJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBcHBseSBjb21tYW5kIHRvIHRoZSBnbG9iYWwgY29uZmlnIGZpbGUnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZWRpdG9yJywgJ2UnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ09wZW4gZWRpdG9yJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2F1dGgnLCAnYScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWZmZWN0IGF1dGggY29uZmlnIGZpbGUgKG9ubHkgdXNlZCBmb3IgLS1lZGl0b3IpJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3Vuc2V0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVbnNldCB0aGUgZ2l2ZW4gc2V0dGluZy1rZXknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbGlzdCcsICdsJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZmlsZScsICdmJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnSWYgeW91IHdhbnQgdG8gY2hvb3NlIGEgZGlmZmVyZW50IGNvbXBvc2VyLmpzb24gb3IgY29uZmlnLmpzb24nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYWJzb2x1dGUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JldHVybnMgYWJzb2x1dGUgcGF0aHMgd2hlbiBmZXRjaGluZyAqLWRpciBjb25maWcgdmFsdWVzIGluc3RlYWQgb2YgcmVsYXRpdmUnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignanNvbicsICdqJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdKU09OIGRlY29kZSB0aGUgc2V0dGluZyB2YWx1ZSwgdG8gYmUgdXNlZCB3aXRoIGV4dHJhLioga2V5cycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdtZXJnZScsICdtJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdNZXJnZSB0aGUgc2V0dGluZyB2YWx1ZSB3aXRoIHRoZSBjdXJyZW50IHZhbHVlLCB0byBiZSB1c2VkIHdpdGggZXh0cmEuKiBrZXlzIGluIGNvbWJpbmF0aW9uIHdpdGggLS1qc29uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FwcGVuZCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnV2hlbiBhZGRpbmcgYSByZXBvc2l0b3J5LCBhcHBlbmQgaXQgKGxvd2VzdCBwcmlvcml0eSkgdG8gdGhlIGV4aXN0aW5nIG9uZXMgaW5zdGVhZCBvZiBwcmVwZW5kaW5nIGl0IChoaWdoZXN0IHByaW9yaXR5KScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzb3VyY2UnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc3BsYXkgd2hlcmUgdGhlIGNvbmZpZyB2YWx1ZSBpcyBsb2FkZWQgZnJvbScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3NldHRpbmcta2V5JywgbnVsbCwgJ1NldHRpbmcga2V5JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnc2V0dGluZy12YWx1ZScsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZLCAnU2V0dGluZyB2YWx1ZScpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhpcyBjb21tYW5kIGFsbG93cyB5b3UgdG8gZWRpdCBjb21wb3NlciBjb25maWcgc2V0dGluZ3MgYW5kIHJlcG9zaXRvcmllcwppbiBlaXRoZXIgdGhlIGxvY2FsIGNvbXBvc2VyLmpzb24gZmlsZSBvciB0aGUgZ2xvYmFsIGNvbmZpZy5qc29uIGZpbGUuCgpBZGRpdGlvbmFsbHkgaXQgbGV0cyB5b3UgZWRpdCBtb3N0IHByb3BlcnRpZXMgaW4gdGhlIGxvY2FsIGNvbXBvc2VyLmpzb24uCgpUbyBzZXQgYSBjb25maWcgc2V0dGluZzoKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIGJpbi1kaXIgYmluLzwvY29tbWVudD4KClRvIHJlYWQgYSBjb25maWcgc2V0dGluZzoKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIGJpbi1kaXI8L2NvbW1lbnQ+CiAgICBPdXRwdXRzOiA8aW5mbz5iaW48L2luZm8+CgpUbyBlZGl0IHRoZSBnbG9iYWwgY29uZmlnLmpzb24gZmlsZToKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIC0tZ2xvYmFsPC9jb21tZW50PgoKVG8gYWRkIGEgcmVwb3NpdG9yeToKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIHJlcG9zaXRvcmllcy5mb28gdmNzIGh0dHBzOi8vYmFyLmNvbTwvY29tbWVudD4KClRvIHJlbW92ZSBhIHJlcG9zaXRvcnkgKHJlcG8gaXMgYSBzaG9ydCBhbGlhcyBmb3IgcmVwb3NpdG9yaWVzKToKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIC0tdW5zZXQgcmVwby5mb288L2NvbW1lbnQ+CgpUbyBkaXNhYmxlIHBhY2thZ2lzdDoKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIHJlcG8ucGFja2FnaXN0IGZhbHNlPC9jb21tZW50PgoKWW91IGNhbiBhbHRlciByZXBvc2l0b3JpZXMgaW4gdGhlIGdsb2JhbCBjb25maWcuanNvbiBmaWxlIGJ5IHBhc3NpbmcgaW4gdGhlCjxpbmZvPi0tZ2xvYmFsPC9pbmZvPiBvcHRpb24uCgpUbyBhZGQgb3IgZWRpdCBzdWdnZXN0ZWQgcGFja2FnZXMgeW91IGNhbiB1c2U6CgogICAgPGNvbW1lbnQ+JWNvbW1hbmQuZnVsbF9uYW1lJSBzdWdnZXN0LnBhY2thZ2UgcmVhc29uIGZvciB0aGUgc3VnZ2VzdGlvbjwvY29tbWVudD4KClRvIGFkZCBvciBlZGl0IGV4dHJhIHByb3BlcnRpZXMgeW91IGNhbiB1c2U6CgogICAgPGNvbW1lbnQ+JWNvbW1hbmQuZnVsbF9uYW1lJSBleHRyYS5wcm9wZXJ0eSB2YWx1ZTwvY29tbWVudD4KCk9yIHRvIGFkZCBhIGNvbXBsZXggdmFsdWUgeW91IGNhbiB1c2UganNvbiB3aXRoOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgZXh0cmEucHJvcGVydHkgLS1qc29uICd7ImZvbyI6dHJ1ZSwgImJhciI6IFtdfSc8L2NvbW1lbnQ+CgpUbyBlZGl0IHRoZSBmaWxlIGluIGFuIGV4dGVybmFsIGVkaXRvcjoKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIC0tZWRpdG9yPC9jb21tZW50PgoKVG8gY2hvb3NlIHlvdXIgZWRpdG9yIHlvdSBjYW4gc2V0IHRoZSAiRURJVE9SIiBlbnYgdmFyaWFibGUuCgpUbyBnZXQgYSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gdmFsdWVzIGluIHRoZSBmaWxlOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgLS1saXN0PC9jb21tZW50PgoKWW91IGNhbiBhbHdheXMgcGFzcyBtb3JlIHRoYW4gb25lIG9wdGlvbi4gQXMgYW4gZXhhbXBsZSwgaWYgeW91IHdhbnQgdG8gZWRpdCB0aGUKZ2xvYmFsIGNvbmZpZy5qc29uIGZpbGUuCgogICAgPGNvbW1lbnQ+JWNvbW1hbmQuZnVsbF9uYW1lJSAtLWVkaXRvciAtLWdsb2JhbDwvY29tbWVudD4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI2NvbmZpZwpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCRpbnB1dCwgJG91dHB1dCk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZ2xvYmFsJykgJiYgbnVsbCAhPT0gJGlucHV0LT5nZXRPcHRpb24oJ2ZpbGUnKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJy0tZmlsZSBhbmQgLS1nbG9iYWwgY2FuIG5vdCBiZSBjb21iaW5lZCcpOwogICAgICAgIH0KCiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygkaW8pOwoKICAgICAgICAvLyBHZXQgdGhlIGxvY2FsIGNvbXBvc2VyLmpzb24sIGdsb2JhbCBjb25maWcuanNvbiwgb3IgaWYgdGhlIHVzZXIKICAgICAgICAvLyBwYXNzZWQgaW4gYSBmaWxlIHRvIHVzZQogICAgICAgICRjb25maWdGaWxlID0gJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpCiAgICAgICAgICAgID8gKCR0aGlzLT5jb25maWctPmdldCgnaG9tZScpIC4gJy9jb25maWcuanNvbicpCiAgICAgICAgICAgIDogKCRpbnB1dC0+Z2V0T3B0aW9uKCdmaWxlJykgPzogRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCkpOwoKICAgICAgICAvLyBDcmVhdGUgZ2xvYmFsIGNvbXBvc2VyLmpzb24gaWYgdGhpcyB3YXMgaW52b2tlZCB1c2luZyBgY29tcG9zZXIgZ2xvYmFsIGNvbmZpZ2AKICAgICAgICBpZiAoCiAgICAgICAgICAgICgkY29uZmlnRmlsZSA9PT0gJ2NvbXBvc2VyLmpzb24nIHx8ICRjb25maWdGaWxlID09PSAnLi9jb21wb3Nlci5qc29uJykKICAgICAgICAgICAgJiYgIWZpbGVfZXhpc3RzKCRjb25maWdGaWxlKQogICAgICAgICAgICAmJiByZWFscGF0aChnZXRjd2QoKSkgPT09IHJlYWxwYXRoKCR0aGlzLT5jb25maWctPmdldCgnaG9tZScpKQogICAgICAgICkgewogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkY29uZmlnRmlsZSwgIntcbn1cbiIpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNvbmZpZ0ZpbGUgPSBuZXcgSnNvbkZpbGUoJGNvbmZpZ0ZpbGUsIG51bGwsICRpbyk7CiAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZSA9IG5ldyBKc29uQ29uZmlnU291cmNlKCR0aGlzLT5jb25maWdGaWxlKTsKCiAgICAgICAgJGF1dGhDb25maWdGaWxlID0gJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpCiAgICAgICAgICAgID8gKCR0aGlzLT5jb25maWctPmdldCgnaG9tZScpIC4gJy9hdXRoLmpzb24nKQogICAgICAgICAgICA6IGRpcm5hbWUocmVhbHBhdGgoJGNvbmZpZ0ZpbGUpKSAuICcvYXV0aC5qc29uJzsKCiAgICAgICAgJHRoaXMtPmF1dGhDb25maWdGaWxlID0gbmV3IEpzb25GaWxlKCRhdXRoQ29uZmlnRmlsZSwgbnVsbCwgJGlvKTsKICAgICAgICAkdGhpcy0+YXV0aENvbmZpZ1NvdXJjZSA9IG5ldyBKc29uQ29uZmlnU291cmNlKCR0aGlzLT5hdXRoQ29uZmlnRmlsZSwgdHJ1ZSk7CgogICAgICAgIC8vIEluaXRpYWxpemUgdGhlIGdsb2JhbCBmaWxlIGlmIGl0J3Mgbm90IHRoZXJlLCBpZ25vcmluZyBhbnkgd2FybmluZ3Mgb3Igbm90aWNlcwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZ2xvYmFsJykgJiYgISR0aGlzLT5jb25maWdGaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICB0b3VjaCgkdGhpcy0+Y29uZmlnRmlsZS0+Z2V0UGF0aCgpKTsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ0ZpbGUtPndyaXRlKGFycmF5KCdjb25maWcnID0+IG5ldyBcQXJyYXlPYmplY3QpKTsKICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2NobW9kJywgJHRoaXMtPmNvbmZpZ0ZpbGUtPmdldFBhdGgoKSwgMDYwMCk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZ2xvYmFsJykgJiYgISR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+ZXhpc3RzKCkpIHsKICAgICAgICAgICAgdG91Y2goJHRoaXMtPmF1dGhDb25maWdGaWxlLT5nZXRQYXRoKCkpOwogICAgICAgICAgICAkdGhpcy0+YXV0aENvbmZpZ0ZpbGUtPndyaXRlKGFycmF5KCdiaXRidWNrZXQtb2F1dGgnID0+IG5ldyBcQXJyYXlPYmplY3QsICdnaXRodWItb2F1dGgnID0+IG5ldyBcQXJyYXlPYmplY3QsICdnaXRsYWItb2F1dGgnID0+IG5ldyBcQXJyYXlPYmplY3QsICdnaXRsYWItdG9rZW4nID0+IG5ldyBcQXJyYXlPYmplY3QsICdodHRwLWJhc2ljJyA9PiBuZXcgXEFycmF5T2JqZWN0LCAnYmVhcmVyJyA9PiBuZXcgXEFycmF5T2JqZWN0KSk7CiAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdjaG1vZCcsICR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+Z2V0UGF0aCgpLCAwNjAwKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmNvbmZpZ0ZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGaWxlICIlcyIgY2Fubm90IGJlIGZvdW5kIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeScsICRjb25maWdGaWxlKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqIEB0aHJvd3MgXFNlbGRcSnNvbkxpbnRcUGFyc2luZ0V4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIC8vIE9wZW4gZmlsZSBpbiBlZGl0b3IKICAgICAgICBpZiAodHJ1ZSA9PT0gJGlucHV0LT5nZXRPcHRpb24oJ2VkaXRvcicpKSB7CiAgICAgICAgICAgICRlZGl0b3IgPSBlc2NhcGVzaGVsbGNtZChQbGF0Zm9ybTo6Z2V0RW52KCdFRElUT1InKSk7CiAgICAgICAgICAgIGlmICghJGVkaXRvcikgewogICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICRlZGl0b3IgPSAnbm90ZXBhZCc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCdlZGl0b3InLCAndmltJywgJ3ZpJywgJ25hbm8nLCAncGljbycsICdlZCcpIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4ZWMoJ3doaWNoICcuJGNhbmRpZGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlZGl0b3IgPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRmaWxlID0gJGlucHV0LT5nZXRPcHRpb24oJ2F1dGgnKSA/ICR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+Z2V0UGF0aCgpIDogJHRoaXMtPmNvbmZpZ0ZpbGUtPmdldFBhdGgoKTsKICAgICAgICAgICAgc3lzdGVtKCRlZGl0b3IgLiAnICcgLiAkZmlsZSAuIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgPyAnJyA6ICcgPiBgdHR5YCcpKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlID09PSAkaW5wdXQtPmdldE9wdGlvbignZ2xvYmFsJykpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+bWVyZ2UoJHRoaXMtPmNvbmZpZ0ZpbGUtPnJlYWQoKSwgJHRoaXMtPmNvbmZpZ0ZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgICAgICR0aGlzLT5jb25maWctPm1lcmdlKGFycmF5KCdjb25maWcnID0+ICR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+ZXhpc3RzKCkgPyAkdGhpcy0+YXV0aENvbmZpZ0ZpbGUtPnJlYWQoKSA6IGFycmF5KCkpLCAkdGhpcy0+YXV0aENvbmZpZ0ZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBMaXN0IHRoZSBjb25maWd1cmF0aW9uIG9mIHRoZSBmaWxlIHNldHRpbmdzCiAgICAgICAgaWYgKHRydWUgPT09ICRpbnB1dC0+Z2V0T3B0aW9uKCdsaXN0JykpIHsKICAgICAgICAgICAgJHRoaXMtPmxpc3RDb25maWd1cmF0aW9uKCR0aGlzLT5jb25maWctPmFsbCgpLCAkdGhpcy0+Y29uZmlnLT5yYXcoKSwgJG91dHB1dCwgbnVsbCwgKGJvb2wpICRpbnB1dC0+Z2V0T3B0aW9uKCdzb3VyY2UnKSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgICRzZXR0aW5nS2V5ID0gJGlucHV0LT5nZXRBcmd1bWVudCgnc2V0dGluZy1rZXknKTsKICAgICAgICBpZiAoIWlzX3N0cmluZygkc2V0dGluZ0tleSkpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGUgdXNlciBlbnRlcnMgaW4gYSBjb25maWcgdmFyaWFibGUsIHBhcnNlIGl0IGFuZCBzYXZlIHRvIGZpbGUKICAgICAgICBpZiAoYXJyYXkoKSAhPT0gJGlucHV0LT5nZXRBcmd1bWVudCgnc2V0dGluZy12YWx1ZScpICYmICRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IGNhbiBub3QgY29tYmluZSBhIHNldHRpbmcgdmFsdWUgd2l0aCAtLXVuc2V0Jyk7CiAgICAgICAgfQoKICAgICAgICAvLyBzaG93IHRoZSB2YWx1ZSBpZiBubyB2YWx1ZSBpcyBwcm92aWRlZAogICAgICAgIGlmIChhcnJheSgpID09PSAkaW5wdXQtPmdldEFyZ3VtZW50KCdzZXR0aW5nLXZhbHVlJykgJiYgISRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICRwcm9wZXJ0aWVzID0gYXJyYXkoJ25hbWUnLCAndHlwZScsICdkZXNjcmlwdGlvbicsICdob21lcGFnZScsICd2ZXJzaW9uJywgJ21pbmltdW0tc3RhYmlsaXR5JywgJ3ByZWZlci1zdGFibGUnLCAna2V5d29yZHMnLCAnbGljZW5zZScsICdleHRyYScpOwogICAgICAgICAgICAkcmF3RGF0YSA9ICR0aGlzLT5jb25maWdGaWxlLT5yZWFkKCk7CiAgICAgICAgICAgICRkYXRhID0gJHRoaXMtPmNvbmZpZy0+YWxsKCk7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXnJlcG9zPyg/Oml0b3JpZXMpPyg/OlwuKC4rKSk/LycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJG1hdGNoZXNbMV0pIHx8ICRtYXRjaGVzWzFdID09PSAnJykgewogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IGlzc2V0KCRkYXRhWydyZXBvc2l0b3JpZXMnXSkgPyAkZGF0YVsncmVwb3NpdG9yaWVzJ10gOiBhcnJheSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWydyZXBvc2l0b3JpZXMnXVskbWF0Y2hlc1sxXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGVyZSBpcyBubyAnLiRtYXRjaGVzWzFdLicgcmVwb3NpdG9yeSBkZWZpbmVkJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAkZGF0YVsncmVwb3NpdG9yaWVzJ11bJG1hdGNoZXNbMV1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCRzZXR0aW5nS2V5LCAnLicpKSB7CiAgICAgICAgICAgICAgICAkYml0cyA9IGV4cGxvZGUoJy4nLCAkc2V0dGluZ0tleSk7CiAgICAgICAgICAgICAgICBpZiAoJGJpdHNbMF0gPT09ICdleHRyYScpIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YSA9ICRyYXdEYXRhOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YSA9ICRkYXRhWydjb25maWcnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGJpdHMgYXMgJGJpdCkgewogICAgICAgICAgICAgICAgICAgICRrZXkgPSBpc3NldCgka2V5KSA/ICRrZXkuJy4nLiRiaXQgOiAkYml0OwogICAgICAgICAgICAgICAgICAgICRtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZGF0YVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGEgPSAkZGF0YVska2V5XTsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGtleSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRzZXR0aW5nS2V5LicgaXMgbm90IGRlZmluZWQuJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHZhbHVlID0gJGRhdGE7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkZGF0YVsnY29uZmlnJ11bJHNldHRpbmdLZXldKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCRzZXR0aW5nS2V5LCAkaW5wdXQtPmdldE9wdGlvbignYWJzb2x1dGUnKSA/IDAgOiBDb25maWc6OlJFTEFUSVZFX1BBVEhTKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRyYXdEYXRhWyRzZXR0aW5nS2V5XSkgJiYgaW5fYXJyYXkoJHNldHRpbmdLZXksICRwcm9wZXJ0aWVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHJhd0RhdGFbJHNldHRpbmdLZXldOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRzZXR0aW5nS2V5LicgaXMgbm90IGRlZmluZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IGpzb25fZW5jb2RlKCR2YWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzb3VyY2VPZkNvbmZpZ1ZhbHVlID0gJyc7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignc291cmNlJykpIHsKICAgICAgICAgICAgICAgICRzb3VyY2VPZkNvbmZpZ1ZhbHVlID0gJyAoJyAuICR0aGlzLT5jb25maWctPmdldFNvdXJjZU9mVmFsdWUoJHNldHRpbmdLZXkpIC4gJyknOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoJHZhbHVlIC4gJHNvdXJjZU9mQ29uZmlnVmFsdWUsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgICR2YWx1ZXMgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdzZXR0aW5nLXZhbHVlJyk7IC8vIHdoYXQgdGhlIHVzZXIgaXMgdHJ5aW5nIHRvIGFkZC9jaGFuZ2UKCiAgICAgICAgJGJvb2xlYW5WYWxpZGF0b3IgPSBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICByZXR1cm4gaW5fYXJyYXkoJHZhbCwgYXJyYXkoJ3RydWUnLCAnZmFsc2UnLCAnMScsICcwJyksIHRydWUpOwogICAgICAgIH07CiAgICAgICAgJGJvb2xlYW5Ob3JtYWxpemVyID0gZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgcmV0dXJuICR2YWwgIT09ICdmYWxzZScgJiYgKGJvb2wpICR2YWw7CiAgICAgICAgfTsKCiAgICAgICAgLy8gaGFuZGxlIGNvbmZpZyB2YWx1ZXMKICAgICAgICAkdW5pcXVlQ29uZmlnVmFsdWVzID0gYXJyYXkoCiAgICAgICAgICAgICdwcm9jZXNzLXRpbWVvdXQnID0+IGFycmF5KCdpc19udW1lcmljJywgJ2ludHZhbCcpLAogICAgICAgICAgICAndXNlLWluY2x1ZGUtcGF0aCcgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICd1c2UtZ2l0aHViLWFwaScgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdwcmVmZXJyZWQtaW5zdGFsbCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgnYXV0bycsICdzb3VyY2UnLCAnZGlzdCcpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgJ2dpdGxhYi1wcm90b2NvbCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgnZ2l0JywgJ2h0dHAnLCAnaHR0cHMnKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdzdG9yZS1hdXRocycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgndHJ1ZScsICdmYWxzZScsICdwcm9tcHQnKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJ3Byb21wdCcgPT09ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdwcm9tcHQnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWwgIT09ICdmYWxzZScgJiYgKGJvb2wpICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnbm90aWZ5LW9uLWluc3RhbGwnID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAndmVuZG9yLWRpcicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdiaW4tZGlyJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2FyY2hpdmUtZGlyJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2FyY2hpdmUtZm9ybWF0JyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2RhdGEtZGlyJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2NhY2hlLWRpcicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdjYWNoZS1maWxlcy1kaXInID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnY2FjaGUtcmVwby1kaXInID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnY2FjaGUtdmNzLWRpcicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdjYWNoZS10dGwnID0+IGFycmF5KCdpc19udW1lcmljJywgJ2ludHZhbCcpLAogICAgICAgICAgICAnY2FjaGUtZmlsZXMtdHRsJyA9PiBhcnJheSgnaXNfbnVtZXJpYycsICdpbnR2YWwnKSwKICAgICAgICAgICAgJ2NhY2hlLWZpbGVzLW1heHNpemUnID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJlZzo6aXNNYXRjaCgnL15ccyooWzAtOS5dKylccyooPzooW2ttZ10pKD86aT9iKT8pP1xzKiQvaScsICR2YWwpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnYmluLWNvbXBhdCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgnYXV0bycsICdmdWxsJywgJ3N5bWxpbmsnKSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdkaXNjYXJkLWNoYW5nZXMnID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5fYXJyYXkoJHZhbCwgYXJyYXkoJ3N0YXNoJywgJ3RydWUnLCAnZmFsc2UnLCAnMScsICcwJyksIHRydWUpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCdzdGFzaCcgPT09ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdzdGFzaCc7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHZhbDsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdhdXRvbG9hZGVyLXN1ZmZpeCcgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCA9PT0gJ251bGwnID8gbnVsbCA6ICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnc29ydC1wYWNrYWdlcycgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdvcHRpbWl6ZS1hdXRvbG9hZGVyJyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICAgICAgJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAnYXBjdS1hdXRvbG9hZGVyJyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICAgICAgJ3ByZXBlbmQtYXV0b2xvYWRlcicgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdkaXNhYmxlLXRscycgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdzZWN1cmUtaHR0cCcgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdjYWZpbGUnID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZV9leGlzdHMoJHZhbCkgJiYgRmlsZXN5c3RlbTo6aXNSZWFkYWJsZSgkdmFsKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsID09PSAnbnVsbCcgPyBudWxsIDogJHZhbDsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdjYXBhdGgnID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNfZGlyKCR2YWwpICYmIEZpbGVzeXN0ZW06OmlzUmVhZGFibGUoJHZhbCk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCA9PT0gJ251bGwnID8gbnVsbCA6ICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnZ2l0aHViLWV4cG9zZS1ob3N0bmFtZScgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdodGFjY2Vzcy1wcm90ZWN0JyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICAgICAgJ2xvY2snID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAnYWxsb3ctcGx1Z2lucycgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdwbGF0Zm9ybS1jaGVjaycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgncGhwLW9ubHknLCAndHJ1ZScsICdmYWxzZScsICcxJywgJzAnKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJ3BocC1vbmx5JyA9PT0gJHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3BocC1vbmx5JzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsICE9PSAnZmFsc2UnICYmIChib29sKSR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAndXNlLXBhcmVudC1kaXInID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5fYXJyYXkoJHZhbCwgYXJyYXkoJ3RydWUnLCAnZmFsc2UnLCAncHJvbXB0JyksIHRydWUpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCdwcm9tcHQnID09PSAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAncHJvbXB0JzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsICE9PSAnZmFsc2UnICYmIChib29sKSAkdmFsOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICApOwogICAgICAgICRtdWx0aUNvbmZpZ1ZhbHVlcyA9IGFycmF5KAogICAgICAgICAgICAnZ2l0aHViLXByb3RvY29scycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR2YWxzKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2FycmF5IGV4cGVjdGVkJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2YWxzIGFzICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkdmFsLCBhcnJheSgnZ2l0JywgJ2h0dHBzJywgJ3NzaCcpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2YWxpZCBwcm90b2NvbHMgaW5jbHVkZTogZ2l0LCBodHRwcywgc3NoJzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWxzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWxzOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgJ2dpdGh1Yi1kb21haW5zJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHZhbHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnYXJyYXkgZXhwZWN0ZWQnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWxzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWxzOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgJ2dpdGxhYi1kb21haW5zJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHZhbHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnYXJyYXkgZXhwZWN0ZWQnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWxzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWxzOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICApOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykgJiYgKGlzc2V0KCR1bmlxdWVDb25maWdWYWx1ZXNbJHNldHRpbmdLZXldKSB8fCBpc3NldCgkbXVsdGlDb25maWdWYWx1ZXNbJHNldHRpbmdLZXldKSkpIHsKICAgICAgICAgICAgaWYgKCRzZXR0aW5nS2V5ID09PSAnZGlzYWJsZS10bHMnICYmICR0aGlzLT5jb25maWctPmdldCgnZGlzYWJsZS10bHMnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJzxpbmZvPllvdSBhcmUgbm93IHJ1bm5pbmcgQ29tcG9zZXIgd2l0aCBTU0wvVExTIHByb3RlY3Rpb24gZW5hYmxlZC48L2luZm8+Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZUNvbmZpZ1NldHRpbmcoJHNldHRpbmdLZXkpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkdW5pcXVlQ29uZmlnVmFsdWVzWyRzZXR0aW5nS2V5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPmhhbmRsZVNpbmdsZVZhbHVlKCRzZXR0aW5nS2V5LCAkdW5pcXVlQ29uZmlnVmFsdWVzWyRzZXR0aW5nS2V5XSwgJHZhbHVlcywgJ2FkZENvbmZpZ1NldHRpbmcnKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJG11bHRpQ29uZmlnVmFsdWVzWyRzZXR0aW5nS2V5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPmhhbmRsZU11bHRpVmFsdWUoJHNldHRpbmdLZXksICRtdWx0aUNvbmZpZ1ZhbHVlc1skc2V0dGluZ0tleV0sICR2YWx1ZXMsICdhZGRDb25maWdTZXR0aW5nJyk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgLy8gaGFuZGxlIHByZWZlcnJlZC1pbnN0YWxsIHBlci1wYWNrYWdlIGNvbmZpZwogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXnByZWZlcnJlZC1pbnN0YWxsXC4oLispLycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGlzdCgkdmFsaWRhdG9yKSA9ICR1bmlxdWVDb25maWdWYWx1ZXNbJ3ByZWZlcnJlZC1pbnN0YWxsJ107CiAgICAgICAgICAgIGlmICghJHZhbGlkYXRvcigkdmFsdWVzWzBdKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdJbnZhbGlkIHZhbHVlIGZvciAnLiRzZXR0aW5nS2V5LicuIFNob3VsZCBiZSBvbmUgb2Y6IGF1dG8sIHNvdXJjZSwgb3IgZGlzdCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5hZGRDb25maWdTZXR0aW5nKCRzZXR0aW5nS2V5LCAkdmFsdWVzWzBdKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIGFsbG93LXBsdWdpbnMgY29uZmlnIHNldHRpbmcgZWxlbWVudHMgdHJ1ZSBvciBmYWxzZSB0byBhZGQvcmVtb3ZlCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teYWxsb3ctcGx1Z2luc1wuKFthLXpBLVowLTkvKi1dKyl9JywgJHNldHRpbmdLZXksICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZUNvbmZpZ1NldHRpbmcoJHNldHRpbmdLZXkpOwoKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodHJ1ZSAhPT0gJGJvb2xlYW5WYWxpZGF0b3IoJHZhbHVlc1swXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICciJXMiIGlzIGFuIGludmFsaWQgdmFsdWUnLAogICAgICAgICAgICAgICAgICAgICR2YWx1ZXNbMF0KICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbm9ybWFsaXplZFZhbHVlID0gJGJvb2xlYW5Ob3JtYWxpemVyKCR2YWx1ZXNbMF0pOwoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkc2V0dGluZ0tleSwgJG5vcm1hbGl6ZWRWYWx1ZSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBwcm9wZXJ0aWVzCiAgICAgICAgJHVuaXF1ZVByb3BzID0gYXJyYXkoCiAgICAgICAgICAgICduYW1lJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ3R5cGUnID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnaG9tZXBhZ2UnID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAndmVyc2lvbicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdtaW5pbXVtLXN0YWJpbGl0eScgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc3NldChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzW1ZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkdmFsKV0pOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkdmFsKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdwcmVmZXItc3RhYmxlJyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICApOwogICAgICAgICRtdWx0aVByb3BzID0gYXJyYXkoCiAgICAgICAgICAgICdrZXl3b3JkcycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR2YWxzKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2FycmF5IGV4cGVjdGVkJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsczsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdsaWNlbnNlJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHZhbHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnYXJyYXkgZXhwZWN0ZWQnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWxzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWxzOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICApOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpICYmIChpc3NldCgkdW5pcXVlUHJvcHNbJHNldHRpbmdLZXldKSB8fCBpc3NldCgkbXVsdGlQcm9wc1skc2V0dGluZ0tleV0pIHx8IHN0cnBvcygkc2V0dGluZ0tleSwgJ2V4dHJhLicpID09PSAwKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlICcgLiAkc2V0dGluZ0tleSAuICcgcHJvcGVydHkgY2FuIG5vdCBiZSBzZXQgaW4gdGhlIGdsb2JhbCBjb25maWcuanNvbiBmaWxlLiBVc2UgYGNvbXBvc2VyIGdsb2JhbCBjb25maWdgIHRvIGFwcGx5IGNoYW5nZXMgdG8gdGhlIGdsb2JhbCBjb21wb3Nlci5qc29uJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSAmJiAoaXNzZXQoJHVuaXF1ZVByb3BzWyRzZXR0aW5nS2V5XSkgfHwgaXNzZXQoJG11bHRpUHJvcHNbJHNldHRpbmdLZXldKSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlUHJvcGVydHkoJHNldHRpbmdLZXkpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkdW5pcXVlUHJvcHNbJHNldHRpbmdLZXldKSkgewogICAgICAgICAgICAkdGhpcy0+aGFuZGxlU2luZ2xlVmFsdWUoJHNldHRpbmdLZXksICR1bmlxdWVQcm9wc1skc2V0dGluZ0tleV0sICR2YWx1ZXMsICdhZGRQcm9wZXJ0eScpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkbXVsdGlQcm9wc1skc2V0dGluZ0tleV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5oYW5kbGVNdWx0aVZhbHVlKCRzZXR0aW5nS2V5LCAkbXVsdGlQcm9wc1skc2V0dGluZ0tleV0sICR2YWx1ZXMsICdhZGRQcm9wZXJ0eScpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgcmVwb3NpdG9yaWVzCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJy9ecmVwb3M/KD86aXRvcmllcyk/XC4oLispLycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVSZXBvc2l0b3J5KCRtYXRjaGVzWzFdKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKDIgPT09IGNvdW50KCR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5hZGRSZXBvc2l0b3J5KCRtYXRjaGVzWzFdLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAndHlwZScgPT4gJHZhbHVlc1swXSwKICAgICAgICAgICAgICAgICAgICAndXJsJyA9PiAkdmFsdWVzWzFdLAogICAgICAgICAgICAgICAgKSwgJGlucHV0LT5nZXRPcHRpb24oJ2FwcGVuZCcpKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKDEgPT09IGNvdW50KCR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdHJ0b2xvd2VyKCR2YWx1ZXNbMF0pOwogICAgICAgICAgICAgICAgaWYgKHRydWUgPT09ICRib29sZWFuVmFsaWRhdG9yKCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRib29sZWFuTm9ybWFsaXplcigkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPmFkZFJlcG9zaXRvcnkoJG1hdGNoZXNbMV0sIGZhbHNlLCAkaW5wdXQtPmdldE9wdGlvbignYXBwZW5kJykpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR2YWx1ZXNbMF0pOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPmFkZFJlcG9zaXRvcnkoJG1hdGNoZXNbMV0sICR2YWx1ZSwgJGlucHV0LT5nZXRPcHRpb24oJ2FwcGVuZCcpKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IG11c3QgcGFzcyB0aGUgdHlwZSBhbmQgYSB1cmwuIEV4YW1wbGU6IHBocCBjb21wb3Nlci5waGFyIGNvbmZpZyByZXBvc2l0b3JpZXMuZm9vIHZjcyBodHRwczovL2Jhci5jb20nKTsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBleHRyYQogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXmV4dHJhXC4oLispLycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVQcm9wZXJ0eSgkc2V0dGluZ0tleSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2YWx1ZSA9ICR2YWx1ZXNbMF07CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignanNvbicpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ21lcmdlJykpIHsKICAgICAgICAgICAgICAgICAgICAkY3VycmVudFZhbHVlID0gJHRoaXMtPmNvbmZpZ0ZpbGUtPnJlYWQoKTsKICAgICAgICAgICAgICAgICAgICAkYml0cyA9IGV4cGxvZGUoJy4nLCAkc2V0dGluZ0tleSk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGJpdHMgYXMgJGJpdCkgewogICAgICAgICAgICAgICAgICAgICAgICAkY3VycmVudFZhbHVlID0gaXNzZXQoJGN1cnJlbnRWYWx1ZVskYml0XSkgPyAkY3VycmVudFZhbHVlWyRiaXRdIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCRjdXJyZW50VmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IGFycmF5X21lcmdlKCRjdXJyZW50VmFsdWUsICR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPmFkZFByb3BlcnR5KCRzZXR0aW5nS2V5LCAkdmFsdWUpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgc3VnZ2VzdAogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXnN1Z2dlc3RcLiguKykvJywgJHNldHRpbmdLZXksICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZVByb3BlcnR5KCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkUHJvcGVydHkoJHNldHRpbmdLZXksIGltcGxvZGUoJyAnLCAkdmFsdWVzKSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSB1bnNldHRpbmcgZXh0cmEvc3VnZ2VzdAogICAgICAgIGlmIChpbl9hcnJheSgkc2V0dGluZ0tleSwgYXJyYXkoJ3N1Z2dlc3QnLCAnZXh0cmEnKSwgdHJ1ZSkgJiYgJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlUHJvcGVydHkoJHNldHRpbmdLZXkpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgcGxhdGZvcm0KICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL15wbGF0Zm9ybVwuKC4rKS8nLCAkc2V0dGluZ0tleSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlQ29uZmlnU2V0dGluZygkc2V0dGluZ0tleSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPmFkZENvbmZpZ1NldHRpbmcoJHNldHRpbmdLZXksICR2YWx1ZXNbMF0gPT09ICdmYWxzZScgPyAgZmFsc2UgOiAkdmFsdWVzWzBdKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIHVuc2V0dGluZyBwbGF0Zm9ybQogICAgICAgIGlmICgkc2V0dGluZ0tleSA9PT0gJ3BsYXRmb3JtJyAmJiAkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIGF1dGgKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL14oYml0YnVja2V0LW9hdXRofGdpdGh1Yi1vYXV0aHxnaXRsYWItb2F1dGh8Z2l0bGFiLXRva2VufGh0dHAtYmFzaWN8YmVhcmVyKVwuKC4rKS8nLCAkc2V0dGluZ0tleSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmF1dGhDb25maWdTb3VyY2UtPnJlbW92ZUNvbmZpZ1NldHRpbmcoJG1hdGNoZXNbMV0uJy4nLiRtYXRjaGVzWzJdKTsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZUNvbmZpZ1NldHRpbmcoJG1hdGNoZXNbMV0uJy4nLiRtYXRjaGVzWzJdKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRtYXRjaGVzWzFdID09PSAnYml0YnVja2V0LW9hdXRoJykgewogICAgICAgICAgICAgICAgaWYgKDIgIT09IGNvdW50KCR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdFeHBlY3RlZCB0d28gYXJndW1lbnRzIChjb25zdW1lci1rZXksIGNvbnN1bWVyLXNlY3JldCksIGdvdCAnLmNvdW50KCR2YWx1ZXMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZUNvbmZpZ1NldHRpbmcoJG1hdGNoZXNbMV0uJy4nLiRtYXRjaGVzWzJdKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hdXRoQ29uZmlnU291cmNlLT5hZGRDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSwgYXJyYXkoJ2NvbnN1bWVyLWtleScgPT4gJHZhbHVlc1swXSwgJ2NvbnN1bWVyLXNlY3JldCcgPT4gJHZhbHVlc1sxXSkpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG1hdGNoZXNbMV0gPT09ICdnaXRsYWItdG9rZW4nICYmIDIgPT09IGNvdW50KCR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXV0aENvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0sIGFycmF5KCd1c2VybmFtZScgPT4gJHZhbHVlc1swXSwgJ3Rva2VuJyA9PiAkdmFsdWVzWzFdKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkbWF0Y2hlc1sxXSwgYXJyYXkoJ2dpdGh1Yi1vYXV0aCcsICdnaXRsYWItb2F1dGgnLCAnZ2l0bGFiLXRva2VuJywgJ2JlYXJlcicpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgaWYgKDEgIT09IGNvdW50KCR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUb28gbWFueSBhcmd1bWVudHMsIGV4cGVjdGVkIG9ubHkgb25lIHRva2VuJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXV0aENvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0sICR2YWx1ZXNbMF0pOwogICAgICAgICAgICB9IGVsc2VpZiAoJG1hdGNoZXNbMV0gPT09ICdodHRwLWJhc2ljJykgewogICAgICAgICAgICAgICAgaWYgKDIgIT09IGNvdW50KCR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdFeHBlY3RlZCB0d28gYXJndW1lbnRzICh1c2VybmFtZSwgcGFzc3dvcmQpLCBnb3QgJy5jb3VudCgkdmFsdWVzKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXV0aENvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0sIGFycmF5KCd1c2VybmFtZScgPT4gJHZhbHVlc1swXSwgJ3Bhc3N3b3JkJyA9PiAkdmFsdWVzWzFdKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIHNjcmlwdAogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcvXnNjcmlwdHNcLiguKykvJywgJHNldHRpbmdLZXksICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZVByb3BlcnR5KCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkUHJvcGVydHkoJHNldHRpbmdLZXksIGNvdW50KCR2YWx1ZXMpID4gMSA/ICR2YWx1ZXMgOiAkdmFsdWVzWzBdKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1NldHRpbmcgJy4kc2V0dGluZ0tleS4nIGRvZXMgbm90IGV4aXN0IG9yIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBjb21tYW5kJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRrZXkKICAgICAqIEBwYXJhbSBhcnJheXtjYWxsYWJsZSwgY2FsbGFibGV9ICRjYWxsYmFja3MgVmFsaWRhdG9yIGFuZCBub3JtYWxpemVyIGNhbGxiYWNrcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZz4gJHZhbHVlcwogICAgICogQHBhcmFtIHN0cmluZyAkbWV0aG9kCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYW5kbGVTaW5nbGVWYWx1ZSgka2V5LCBhcnJheSAkY2FsbGJhY2tzLCBhcnJheSAkdmFsdWVzLCAkbWV0aG9kKQogICAgewogICAgICAgIGxpc3QoJHZhbGlkYXRvciwgJG5vcm1hbGl6ZXIpID0gJGNhbGxiYWNrczsKICAgICAgICBpZiAoMSAhPT0gY291bnQoJHZhbHVlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdZb3UgY2FuIG9ubHkgcGFzcyBvbmUgdmFsdWUuIEV4YW1wbGU6IHBocCBjb21wb3Nlci5waGFyIGNvbmZpZyBwcm9jZXNzLXRpbWVvdXQgMzAwJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAodHJ1ZSAhPT0gJHZhbGlkYXRpb24gPSAkdmFsaWRhdG9yKCR2YWx1ZXNbMF0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJyIlcyIgaXMgYW4gaW52YWxpZCB2YWx1ZScuKCR2YWxpZGF0aW9uID8gJyAoJy4kdmFsaWRhdGlvbi4nKScgOiAnJyksCiAgICAgICAgICAgICAgICAkdmFsdWVzWzBdCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJG5vcm1hbGl6ZWRWYWx1ZSA9ICRub3JtYWxpemVyKCR2YWx1ZXNbMF0pOwoKICAgICAgICBpZiAoJGtleSA9PT0gJ2Rpc2FibGUtdGxzJykgewogICAgICAgICAgICBpZiAoISRub3JtYWxpemVkVmFsdWUgJiYgJHRoaXMtPmNvbmZpZy0+Z2V0KCdkaXNhYmxlLXRscycpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignPGluZm8+WW91IGFyZSBub3cgcnVubmluZyBDb21wb3NlciB3aXRoIFNTTC9UTFMgcHJvdGVjdGlvbiBlbmFibGVkLjwvaW5mbz4nKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRub3JtYWxpemVkVmFsdWUgJiYgISR0aGlzLT5jb25maWctPmdldCgnZGlzYWJsZS10bHMnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgbm93IHJ1bm5pbmcgQ29tcG9zZXIgd2l0aCBTU0wvVExTIHByb3RlY3Rpb24gZGlzYWJsZWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjYWxsX3VzZXJfZnVuYyhhcnJheSgkdGhpcy0+Y29uZmlnU291cmNlLCAkbWV0aG9kKSwgJGtleSwgJG5vcm1hbGl6ZWRWYWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRrZXkKICAgICAqIEBwYXJhbSBhcnJheXtjYWxsYWJsZSwgY2FsbGFibGV9ICRjYWxsYmFja3MgVmFsaWRhdG9yIGFuZCBub3JtYWxpemVyIGNhbGxiYWNrcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZz4gJHZhbHVlcwogICAgICogQHBhcmFtIHN0cmluZyAkbWV0aG9kCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYW5kbGVNdWx0aVZhbHVlKCRrZXksIGFycmF5ICRjYWxsYmFja3MsIGFycmF5ICR2YWx1ZXMsICRtZXRob2QpCiAgICB7CiAgICAgICAgbGlzdCgkdmFsaWRhdG9yLCAkbm9ybWFsaXplcikgPSAkY2FsbGJhY2tzOwogICAgICAgIGlmICh0cnVlICE9PSAkdmFsaWRhdGlvbiA9ICR2YWxpZGF0b3IoJHZhbHVlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnJXMgaXMgYW4gaW52YWxpZCB2YWx1ZScuKCR2YWxpZGF0aW9uID8gJyAoJy4kdmFsaWRhdGlvbi4nKScgOiAnJyksCiAgICAgICAgICAgICAgICBqc29uX2VuY29kZSgkdmFsdWVzKQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgIGNhbGxfdXNlcl9mdW5jKGFycmF5KCR0aGlzLT5jb25maWdTb3VyY2UsICRtZXRob2QpLCAka2V5LCAkbm9ybWFsaXplcigkdmFsdWVzKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwbGF5IHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSBpbiBhIHByZXR0eSBmb3JtYXR0ZWQgd2F5CiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PG1peGVkW118Ym9vbHxzdHJpbmc+ICRjb250ZW50cwogICAgICogQHBhcmFtIGFycmF5PG1peGVkW118c3RyaW5nPiAgICAgICRyYXdDb250ZW50cwogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAgICAgICAgICAgICAgICRrCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAgJHNob3dTb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxpc3RDb25maWd1cmF0aW9uKGFycmF5ICRjb250ZW50cywgYXJyYXkgJHJhd0NvbnRlbnRzLCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJGsgPSBudWxsLCAkc2hvd1NvdXJjZSA9IGZhbHNlKQogICAgewogICAgICAgICRvcmlnSyA9ICRrOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGZvcmVhY2ggKCRjb250ZW50cyBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICBpZiAoJGsgPT09IG51bGwgJiYgIWluX2FycmF5KCRrZXksIGFycmF5KCdjb25maWcnLCAncmVwb3NpdG9yaWVzJykpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJhd1ZhbCA9IGlzc2V0KCRyYXdDb250ZW50c1ska2V5XSkgPyAkcmF3Q29udGVudHNbJGtleV0gOiBudWxsOwoKICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWx1ZSkgJiYgKCFpc19udW1lcmljKGtleSgkdmFsdWUpKSB8fCAoJGtleSA9PT0gJ3JlcG9zaXRvcmllcycgJiYgbnVsbCA9PT0gJGspKSkgewogICAgICAgICAgICAgICAgJGsgLj0gUHJlZzo6cmVwbGFjZSgne15jb25maWdcLn0nLCAnJywgJGtleSAuICcuJyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+bGlzdENvbmZpZ3VyYXRpb24oJHZhbHVlLCAkcmF3VmFsLCAkb3V0cHV0LCAkaywgJHNob3dTb3VyY2UpOwogICAgICAgICAgICAgICAgJGsgPSAkb3JpZ0s7CgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNfYXJyYXkoJHZhbCkgPyBqc29uX2VuY29kZSgkdmFsKSA6ICR2YWw7CiAgICAgICAgICAgICAgICB9LCAkdmFsdWUpOwoKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICdbJy5pbXBsb2RlKCcsICcsICR2YWx1ZSkuJ10nOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNfYm9vbCgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSB2YXJfZXhwb3J0KCR2YWx1ZSwgdHJ1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzb3VyY2UgPSAnJzsKICAgICAgICAgICAgaWYgKCRzaG93U291cmNlKSB7CiAgICAgICAgICAgICAgICAkc291cmNlID0gJyAoJyAuICR0aGlzLT5jb25maWctPmdldFNvdXJjZU9mVmFsdWUoJGsgLiAka2V5KSAuICcpJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRyYXdWYWwpICYmICRyYXdWYWwgIT0gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdbPGNvbW1lbnQ+JyAuICRrIC4gJGtleSAuICc8L2NvbW1lbnQ+XSA8aW5mbz4nIC4gJHJhd1ZhbCAuICcgKCcgLiAkdmFsdWUgLiAnKTwvaW5mbz4nIC4gJHNvdXJjZSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJ1s8Y29tbWVudD4nIC4gJGsgLiAka2V5IC4gJzwvY29tbWVudD5dIDxpbmZvPicgLiAkdmFsdWUgLiAnPC9pbmZvPicgLiAkc291cmNlLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDb25zb2xlXEFwcGxpY2F0aW9uOwp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFByZUNvbW1hbmRSdW5FdmVudDsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxUYWJsZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFRhYmxlU2VwYXJhdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxUZXJtaW5hbDsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBDb21wb3NlciBjb21tYW5kcwogKgogKiBAbWV0aG9kIEFwcGxpY2F0aW9uIGdldEFwcGxpY2F0aW9uKCkKICoKICogQGF1dGhvciBSeWFuIFdlYXZlciA8cnlhbkBrbnBsYWJzLmNvbT4KICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIEJhc2VDb21tYW5kIGV4dGVuZHMgQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEB2YXIgQ29tcG9zZXJ8bnVsbAogICAgICovCiAgICBwcml2YXRlICRjb21wb3NlcjsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICRyZXF1aXJlZAogICAgICogQHBhcmFtICBib29sfG51bGwgICAgICAgICAkZGlzYWJsZVBsdWdpbnMKICAgICAqIEBwYXJhbSAgYm9vbHxudWxsICAgICAgICAgJGRpc2FibGVTY3JpcHRzCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VyKCRyZXF1aXJlZCA9IHRydWUsICRkaXNhYmxlUGx1Z2lucyA9IG51bGwsICRkaXNhYmxlU2NyaXB0cyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21wb3NlcikgewogICAgICAgICAgICAkYXBwbGljYXRpb24gPSAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKTsKICAgICAgICAgICAgaWYgKCRhcHBsaWNhdGlvbiBpbnN0YW5jZW9mIEFwcGxpY2F0aW9uKSB7CiAgICAgICAgICAgICAgICAvKiBAdmFyICRhcHBsaWNhdGlvbiAgICBBcHBsaWNhdGlvbiAqLwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gJGFwcGxpY2F0aW9uLT5nZXRDb21wb3NlcigkcmVxdWlyZWQsICRkaXNhYmxlUGx1Z2lucywgJGRpc2FibGVTY3JpcHRzKTsKICAgICAgICAgICAgLyoqIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUgKi8KICAgICAgICAgICAgfSBlbHNlaWYgKCRyZXF1aXJlZCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdDb3VsZCBub3QgY3JlYXRlIGEgQ29tcG9zZXJcQ29tcG9zZXIgaW5zdGFuY2UsIHlvdSBtdXN0IGluamVjdCAnLgogICAgICAgICAgICAgICAgICAgICdvbmUgaWYgdGhpcyBjb21tYW5kIGlzIG5vdCB1c2VkIHdpdGggYSBDb21wb3NlclxDb25zb2xlXEFwcGxpY2F0aW9uIGluc3RhbmNlJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tcG9zZXIoQ29tcG9zZXIgJGNvbXBvc2VyKQogICAgewogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIGNhY2hlZCBjb21wb3NlciBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXRDb21wb3NlcigpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gbnVsbDsKICAgICAgICAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+cmVzZXRDb21wb3NlcigpOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciBvciBub3QgdGhpcyBjb21tYW5kIGlzIG1lYW50IHRvIGNhbGwgYW5vdGhlciBjb21tYW5kLgogICAgICoKICAgICAqIFRoaXMgaXMgbWFpbmx5IG5lZWRlZCB0byBhdm9pZCBkdXBsaWNhdGVkIHdhcm5pbmdzIG1lc3NhZ2VzLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNQcm94eUNvbW1hbmQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElPKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmlvKSB7CiAgICAgICAgICAgICRhcHBsaWNhdGlvbiA9ICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpOwogICAgICAgICAgICBpZiAoJGFwcGxpY2F0aW9uIGluc3RhbmNlb2YgQXBwbGljYXRpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbyA9ICRhcHBsaWNhdGlvbi0+Z2V0SU8oKTsKICAgICAgICAgICAgLyoqIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUgKi8KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbyA9IG5ldyBOdWxsSU8oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SU8oSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgLy8gaW5pdGlhbGl6ZSBhIHBsdWdpbi1lbmFibGVkIENvbXBvc2VyIGluc3RhbmNlLCBlaXRoZXIgbG9jYWwgb3IgZ2xvYmFsCiAgICAgICAgJGRpc2FibGVQbHVnaW5zID0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tbm8tcGx1Z2lucycpOwogICAgICAgICRkaXNhYmxlU2NyaXB0cyA9ICRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKCctLW5vLXNjcmlwdHMnKTsKICAgICAgICBpZiAoJHRoaXMgaW5zdGFuY2VvZiBTZWxmVXBkYXRlQ29tbWFuZCkgewogICAgICAgICAgICAkZGlzYWJsZVBsdWdpbnMgPSB0cnVlOwogICAgICAgICAgICAkZGlzYWJsZVNjcmlwdHMgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlLCAkZGlzYWJsZVBsdWdpbnMsICRkaXNhYmxlU2NyaXB0cyk7CiAgICAgICAgaWYgKG51bGwgPT09ICRjb21wb3NlcikgewogICAgICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGVHbG9iYWwoJHRoaXMtPmdldElPKCksICRkaXNhYmxlUGx1Z2lucywgJGRpc2FibGVTY3JpcHRzKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAkcHJlQ29tbWFuZFJ1bkV2ZW50ID0gbmV3IFByZUNvbW1hbmRSdW5FdmVudChQbHVnaW5FdmVudHM6OlBSRV9DT01NQU5EX1JVTiwgJGlucHV0LCAkdGhpcy0+Z2V0TmFtZSgpKTsKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJHByZUNvbW1hbmRSdW5FdmVudC0+Z2V0TmFtZSgpLCAkcHJlQ29tbWFuZFJ1bkV2ZW50KTsKICAgICAgICB9CgogICAgICAgIGlmICh0cnVlID09PSAkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbihhcnJheSgnLS1uby1hbnNpJykpICYmICRpbnB1dC0+aGFzT3B0aW9uKCduby1wcm9ncmVzcycpKSB7CiAgICAgICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCduby1wcm9ncmVzcycsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRydWUgPT0gJGlucHV0LT5oYXNPcHRpb24oJ25vLWRldicpKSB7CiAgICAgICAgICAgIGlmICghJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpICYmIHRydWUgPT0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfTk9fREVWJykpIHsKICAgICAgICAgICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCduby1kZXYnLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCRpbnB1dCwgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHByZWZlclNvdXJjZSBhbmQgcHJlZmVyRGlzdCB2YWx1ZXMgYmFzZWQgb24gdGhlIGNvbmZpZ3VyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICRrZWVwVmNzUmVxdWlyZXNQcmVmZXJTb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2xbXSBBbiBhcnJheSBjb21wb3NlZCBvZiB0aGUgcHJlZmVyU291cmNlIGFuZCBwcmVmZXJEaXN0IHZhbHVlcwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UHJlZmVycmVkSW5zdGFsbE9wdGlvbnMoQ29uZmlnICRjb25maWcsIElucHV0SW50ZXJmYWNlICRpbnB1dCwgJGtlZXBWY3NSZXF1aXJlc1ByZWZlclNvdXJjZSA9IGZhbHNlKQogICAgewogICAgICAgICRwcmVmZXJTb3VyY2UgPSBmYWxzZTsKICAgICAgICAkcHJlZmVyRGlzdCA9IGZhbHNlOwoKICAgICAgICBzd2l0Y2ggKCRjb25maWctPmdldCgncHJlZmVycmVkLWluc3RhbGwnKSkgewogICAgICAgICAgICBjYXNlICdzb3VyY2UnOgogICAgICAgICAgICAgICAgJHByZWZlclNvdXJjZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnZGlzdCc6CiAgICAgICAgICAgICAgICAkcHJlZmVyRGlzdCA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnYXV0byc6CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBub29wCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmhhc09wdGlvbigncHJlZmVyLWluc3RhbGwnKSAmJiAkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLWluc3RhbGwnKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1zb3VyY2UnKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJy0tcHJlZmVyLXNvdXJjZSBjYW4gbm90IGJlIHVzZWQgdG9nZXRoZXIgd2l0aCAtLXByZWZlci1pbnN0YWxsJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItZGlzdCcpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignLS1wcmVmZXItZGlzdCBjYW4gbm90IGJlIHVzZWQgdG9nZXRoZXIgd2l0aCAtLXByZWZlci1pbnN0YWxsJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoICgkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLWluc3RhbGwnKSkgewogICAgICAgICAgICAgICAgY2FzZSAnZGlzdCc6CiAgICAgICAgICAgICAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ3ByZWZlci1kaXN0JywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgogICAgICAgICAgICAgICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdwcmVmZXItc291cmNlJywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdhdXRvJzoKICAgICAgICAgICAgICAgICAgICAkcHJlZmVyRGlzdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICRwcmVmZXJTb3VyY2UgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJy0tcHJlZmVyLWluc3RhbGwgYWNjZXB0cyBvbmUgb2YgImRpc3QiLCAic291cmNlIiBvciAiYXV0byIsIGdvdCAnLiRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItaW5zdGFsbCcpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItc291cmNlJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1kaXN0JykgfHwgKCRrZWVwVmNzUmVxdWlyZXNQcmVmZXJTb3VyY2UgJiYgJGlucHV0LT5oYXNPcHRpb24oJ2tlZXAtdmNzJykgJiYgJGlucHV0LT5nZXRPcHRpb24oJ2tlZXAtdmNzJykpKSB7CiAgICAgICAgICAgICRwcmVmZXJTb3VyY2UgPSAkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLXNvdXJjZScpIHx8ICgka2VlcFZjc1JlcXVpcmVzUHJlZmVyU291cmNlICYmICRpbnB1dC0+aGFzT3B0aW9uKCdrZWVwLXZjcycpICYmICRpbnB1dC0+Z2V0T3B0aW9uKCdrZWVwLXZjcycpKTsKICAgICAgICAgICAgJHByZWZlckRpc3QgPSAoYm9vbCkgJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1kaXN0Jyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJHByZWZlclNvdXJjZSwgJHByZWZlckRpc3QpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkcmVxdWlyZW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZvcm1hdFJlcXVpcmVtZW50cyhhcnJheSAkcmVxdWlyZW1lbnRzKQogICAgewogICAgICAgICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgJHJlcXVpcmVtZW50cyA9ICR0aGlzLT5ub3JtYWxpemVSZXF1aXJlbWVudHMoJHJlcXVpcmVtZW50cyk7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVtZW50cyBhcyAkcmVxdWlyZW1lbnQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdPcHRpb24gJy4kcmVxdWlyZW1lbnRbJ25hbWUnXSAuJyBpcyBtaXNzaW5nIGEgdmVyc2lvbiBjb25zdHJhaW50LCB1c2UgZS5nLiAnLiRyZXF1aXJlbWVudFsnbmFtZSddLic6XjEuMCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXF1aXJlc1skcmVxdWlyZW1lbnRbJ25hbWUnXV0gPSAkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVxdWlyZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkcmVxdWlyZW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiBsaXN0PGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZ30+CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBub3JtYWxpemVSZXF1aXJlbWVudHMoYXJyYXkgJHJlcXVpcmVtZW50cykKICAgIHsKICAgICAgICAkcGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKCiAgICAgICAgcmV0dXJuICRwYXJzZXItPnBhcnNlTmFtZVZlcnNpb25QYWlycygkcmVxdWlyZW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxUYWJsZVNlcGFyYXRvcnxtaXhlZFtdPiAkdGFibGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbmRlclRhYmxlKGFycmF5ICR0YWJsZSwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHJlbmRlcmVyID0gbmV3IFRhYmxlKCRvdXRwdXQpOwogICAgICAgICRyZW5kZXJlci0+c2V0U3R5bGUoJ2NvbXBhY3QnKTsKICAgICAgICAkcmVuZGVyZXJTdHlsZSA9ICRyZW5kZXJlci0+Z2V0U3R5bGUoKTsKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkcmVuZGVyZXJTdHlsZSwgJ3NldFZlcnRpY2FsQm9yZGVyQ2hhcnMnKSkgewogICAgICAgICAgICAkcmVuZGVyZXJTdHlsZS0+c2V0VmVydGljYWxCb3JkZXJDaGFycygnJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gVE9ETyByZW1vdmUgaW4gY29tcG9zZXIgMi4yCiAgICAgICAgICAgIC8vIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUKICAgICAgICAgICAgJHJlbmRlcmVyU3R5bGUtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcignJyk7CiAgICAgICAgfQogICAgICAgICRyZW5kZXJlclN0eWxlLT5zZXRDZWxsUm93Q29udGVudEZvcm1hdCgnJXMgICcpOwogICAgICAgICRyZW5kZXJlci0+c2V0Um93cygkdGFibGUpLT5yZW5kZXIoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRUZXJtaW5hbFdpZHRoKCkKICAgIHsKICAgICAgICBpZiAoY2xhc3NfZXhpc3RzKCdTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlcm1pbmFsJykpIHsKICAgICAgICAgICAgJHRlcm1pbmFsID0gbmV3IFRlcm1pbmFsKCk7CiAgICAgICAgICAgICR3aWR0aCA9ICR0ZXJtaW5hbC0+Z2V0V2lkdGgoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBGb3IgdmVyc2lvbnMgb2YgU3ltZm9ueSBjb25zb2xlIGJlZm9yZSAzLjIKICAgICAgICAgICAgLy8gVE9ETyByZW1vdmUgaW4gY29tcG9zZXIgMi4yCiAgICAgICAgICAgIC8vIEBwaHBzdGFuLWlnbm9yZS1uZXh0LWxpbmUKICAgICAgICAgICAgbGlzdCgkd2lkdGgpID0gJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPmdldFRlcm1pbmFsRGltZW5zaW9ucygpOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCA9PT0gJHdpZHRoKSB7CiAgICAgICAgICAgIC8vIEluIGNhc2UgdGhlIHdpZHRoIGlzIG5vdCBkZXRlY3RlZCwgd2UncmUgcHJvYmFibHkgcnVubmluZyB0aGUgY29tbWFuZAogICAgICAgICAgICAvLyBvdXRzaWRlIG9mIGEgcmVhbCB0ZXJtaW5hbCwgdXNlIHNwYWNlIHdpdGhvdXQgYSBsaW1pdAogICAgICAgICAgICAkd2lkdGggPSBQSFBfSU5UX01BWDsKICAgICAgICB9CiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAkd2lkdGgtLTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkd2lkdGggPSBtYXgoODAsICR3aWR0aCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHdpZHRoOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CgovKioKICogQGF1dGhvciBEYXZleSBTaGFmaWsgPG1lQGRhdmV5c2hhZmlrLmNvbT4KICovCmNsYXNzIEV4ZWNDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdleGVjJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignRXhlY3V0ZXMgYSB2ZW5kb3JlZCBiaW5hcnkvc2NyaXB0LicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbGlzdCcsICdsJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2JpbmFyeScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIGJpbmFyeSB0byBydW4sIGUuZy4gcGhwdW5pdCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2FyZ3MnLAogICAgICAgICAgICAgICAgICAgIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsCiAgICAgICAgICAgICAgICAgICAgJ0FyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBiaW5hcnkuIFVzZSA8aW5mbz4tLTwvaW5mbz4gdG8gc2VwYXJhdGUgZnJvbSBjb21wb3NlciBhcmd1bWVudHMnCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKRXhlY3V0ZXMgYSB2ZW5kb3JlZCBiaW5hcnkvc2NyaXB0LgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjZXhlYwpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CiAgICAgICAgJGJpbkRpciA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnYmluLWRpcicpOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbGlzdCcpIHx8ICEkaW5wdXQtPmdldEFyZ3VtZW50KCdiaW5hcnknKSkgewogICAgICAgICAgICAkYmlucyA9IGdsb2IoJGJpbkRpciAuICcvKicpOwogICAgICAgICAgICAkYmlucyA9IGFycmF5X21lcmdlKCRiaW5zLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiRlIChsb2NhbCkiOwogICAgICAgICAgICB9LCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0QmluYXJpZXMoKSkpOwoKICAgICAgICAgICAgaWYgKCEkYmlucykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJObyBiaW5hcmllcyBmb3VuZCBpbiBjb21wb3Nlci5qc29uIG9yIGluIGJpbi1kaXIgKCRiaW5EaXIpIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgKICAgICAgICAgICAgICAgIDw8PEVPVAo8Y29tbWVudD5BdmFpbGFibGUgYmluYXJpZXM6PC9jb21tZW50PgpFT1QKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRiaW5zIGFzICRiaW4pIHsKICAgICAgICAgICAgICAgIC8vIHNraXAgLmJhdCBjb3BpZXMKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcHJldmlvdXNCaW4pICYmICRiaW4gPT09ICRwcmV2aW91c0Jpbi4nLmJhdCcpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcHJldmlvdXNCaW4gPSAkYmluOwogICAgICAgICAgICAgICAgJGJpbiA9IGJhc2VuYW1lKCRiaW4pOwogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKAogICAgICAgICAgICAgICAgICAgIDw8PEVPVAo8aW5mbz4tICRiaW48L2luZm8+CkVPVAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAkYmluYXJ5ID0gJGlucHV0LT5nZXRBcmd1bWVudCgnYmluYXJ5Jyk7CgogICAgICAgICRkaXNwYXRjaGVyID0gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKTsKICAgICAgICAkZGlzcGF0Y2hlci0+YWRkTGlzdGVuZXIoJ19fZXhlY19jb21tYW5kJywgJGJpbmFyeSk7CgogICAgICAgIC8vIElmIHRoZSBDV0Qgd2FzIG1vZGlmaWVkLCB3ZSByZXN0b3JlIGl0IHRvIHdoYXQgaXQgd2FzIGluaXRpYWxseSwgYXMgaXQgd2FzCiAgICAgICAgLy8gbW9zdCBsaWtlbHkgbW9kaWZpZWQgYnkgdGhlIGdsb2JhbCBjb21tYW5kLCBhbmQgd2Ugd2FudCBleGVjIHRvIHJ1biBpbiB0aGUgbG9jYWwgd29ya2luZyBkaXJlY3RvcnkKICAgICAgICAvLyBub3QgdGhlIGdsb2JhbCBvbmUKICAgICAgICBpZiAoZ2V0Y3dkKCkgIT09ICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5nZXRJbml0aWFsV29ya2luZ0RpcmVjdG9yeSgpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjaGRpcigkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+Z2V0SW5pdGlhbFdvcmtpbmdEaXJlY3RvcnkoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHN3aXRjaCBiYWNrIHRvIHdvcmtpbmcgZGlyZWN0b3J5ICInLiR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5nZXRJbml0aWFsV29ya2luZ0RpcmVjdG9yeSgpLiciJywgMCwgJGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRpc3BhdGNoZXItPmRpc3BhdGNoU2NyaXB0KCdfX2V4ZWNfY29tbWFuZCcsIHRydWUsICRpbnB1dC0+Z2V0QXJndW1lbnQoJ2FyZ3MnKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUm9vdFBhY2thZ2VSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKi8KY2xhc3MgSG9tZUNvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnYnJvd3NlJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdob21lJykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ09wZW5zIHRoZSBwYWNrYWdlXCdzIHJlcG9zaXRvcnkgVVJMIG9yIGhvbWVwYWdlIGluIHlvdXIgYnJvd3Nlci4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZXMnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSwgJ1BhY2thZ2UocykgdG8gYnJvd3NlIHRvLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdob21lcGFnZScsICdIJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcGVuIHRoZSBob21lcGFnZSBpbnN0ZWFkIG9mIHRoZSByZXBvc2l0b3J5IFVSTC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc2hvdycsICdzJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPbmx5IHNob3cgdGhlIGhvbWVwYWdlIG9yIHJlcG9zaXRvcnkgVVJMLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIGhvbWUgY29tbWFuZCBvcGVucyBvciBzaG93cyBhIHBhY2thZ2UncyByZXBvc2l0b3J5IFVSTCBvcgpob21lcGFnZSBpbiB5b3VyIGRlZmF1bHQgYnJvd3Nlci4KClRvIG9wZW4gdGhlIGhvbWVwYWdlIGJ5IGRlZmF1bHQsIHVzZSAtSCBvciAtLWhvbWVwYWdlLgpUbyBzaG93IGluc3RlYWQgb2Ygb3BlbiB0aGUgcmVwb3NpdG9yeSBvciBob21lcGFnZSBVUkwsIHVzZSAtcyBvciAtLXNob3cuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNicm93c2UtaG9tZQpFT1QKICAgICAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHJlcG9zID0gJHRoaXMtPmluaXRpYWxpemVSZXBvcygpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICRyZXR1cm4gPSAwOwoKICAgICAgICAkcGFja2FnZXMgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlcycpOwogICAgICAgIGlmICghJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTm8gcGFja2FnZSBzcGVjaWZpZWQsIG9wZW5pbmcgaG9tZXBhZ2UgZm9yIHRoZSByb290IHBhY2thZ2UnKTsKICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoJHRoaXMtPmdldENvbXBvc2VyKCktPmdldFBhY2thZ2UoKS0+Z2V0TmFtZSgpKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZU5hbWUpIHsKICAgICAgICAgICAgJGhhbmRsZWQgPSBmYWxzZTsKICAgICAgICAgICAgJHBhY2thZ2VFeGlzdHMgPSBmYWxzZTsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG9zIGFzICRyZXBvKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVwby0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlTmFtZSkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZUV4aXN0cyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICR0aGlzLT5oYW5kbGVQYWNrYWdlKCRwYWNrYWdlLCAkaW5wdXQtPmdldE9wdGlvbignaG9tZXBhZ2UnKSwgJGlucHV0LT5nZXRPcHRpb24oJ3Nob3cnKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkcGFja2FnZUV4aXN0cykgewogICAgICAgICAgICAgICAgJHJldHVybiA9IDE7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlBhY2thZ2UgJy4kcGFja2FnZU5hbWUuJyBub3QgZm91bmQ8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGhhbmRsZWQpIHsKICAgICAgICAgICAgICAgICRyZXR1cm4gPSAxOwogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nLigkaW5wdXQtPmdldE9wdGlvbignaG9tZXBhZ2UnKSA/ICdJbnZhbGlkIG9yIG1pc3NpbmcgaG9tZXBhZ2UnIDogJ0ludmFsaWQgb3IgbWlzc2luZyByZXBvc2l0b3J5IFVSTCcpLicgZm9yICcuJHBhY2thZ2VOYW1lLic8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmV0dXJuOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJHNob3dIb21lcGFnZQogICAgICogQHBhcmFtIGJvb2wgJHNob3dPbmx5CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBoYW5kbGVQYWNrYWdlKENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHNob3dIb21lcGFnZSwgJHNob3dPbmx5KQogICAgewogICAgICAgICRzdXBwb3J0ID0gJHBhY2thZ2UtPmdldFN1cHBvcnQoKTsKICAgICAgICAkdXJsID0gaXNzZXQoJHN1cHBvcnRbJ3NvdXJjZSddKSA/ICRzdXBwb3J0Wydzb3VyY2UnXSA6ICRwYWNrYWdlLT5nZXRTb3VyY2VVcmwoKTsKICAgICAgICBpZiAoISR1cmwgfHwgJHNob3dIb21lcGFnZSkgewogICAgICAgICAgICAkdXJsID0gJHBhY2thZ2UtPmdldEhvbWVwYWdlKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR1cmwgfHwgIWZpbHRlcl92YXIoJHVybCwgRklMVEVSX1ZBTElEQVRFX1VSTCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRzaG93T25seSkgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoc3ByaW50ZignPGluZm8+JXM8L2luZm8+JywgJHVybCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5vcGVuQnJvd3NlcigkdXJsKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogb3BlbnMgYSB1cmwgaW4geW91ciBzeXN0ZW0gZGVmYXVsdCBicm93c2VyCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBvcGVuQnJvd3NlcigkdXJsKQogICAgewogICAgICAgICR1cmwgPSBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKTsKCiAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCR0aGlzLT5nZXRJTygpKTsKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICRwcm9jZXNzLT5leGVjdXRlKCdzdGFydCAid2ViIiBleHBsb3JlciAnIC4gJHVybCwgJG91dHB1dCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkbGludXggPSAkcHJvY2Vzcy0+ZXhlY3V0ZSgnd2hpY2ggeGRnLW9wZW4nLCAkb3V0cHV0KTsKICAgICAgICAkb3N4ID0gJHByb2Nlc3MtPmV4ZWN1dGUoJ3doaWNoIG9wZW4nLCAkb3V0cHV0KTsKCiAgICAgICAgaWYgKDAgPT09ICRsaW51eCkgewogICAgICAgICAgICAkcHJvY2Vzcy0+ZXhlY3V0ZSgneGRnLW9wZW4gJyAuICR1cmwsICRvdXRwdXQpOwogICAgICAgIH0gZWxzZWlmICgwID09PSAkb3N4KSB7CiAgICAgICAgICAgICRwcm9jZXNzLT5leGVjdXRlKCdvcGVuICcgLiAkdXJsLCAkb3V0cHV0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignTm8gc3VpdGFibGUgYnJvd3NlciBvcGVuaW5nIGNvbW1hbmQgZm91bmQsIG9wZW4geW91cnNlbGY6ICcgLiAkdXJsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlcG9zIGluIG9yZGVyIHRoZXkgc2hvdWxkIGJlIGNoZWNrZWQgaW4KICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXRpYWxpemVSZXBvcygpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlKTsKCiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICBhcnJheShuZXcgUm9vdFBhY2thZ2VSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UGFja2FnZSgpKSksIC8vIHJvb3QgcGFja2FnZQogICAgICAgICAgICAgICAgYXJyYXkoJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSksIC8vIGluc3RhbGxlZCBwYWNrYWdlcwogICAgICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSAvLyByZW1vdGVzCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gUmVwb3NpdG9yeUZhY3Rvcnk6OmRlZmF1bHRSZXBvcygkdGhpcy0+Z2V0SU8oKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk7CnVzZSBDb21wb3NlclxJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXFJvb3RQYWNrYWdlTG9hZGVyOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNdWx0aUNvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxUYWJsZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxRdWVzdGlvbjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBVcGRhdGVDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCd1cGRhdGUnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ3UnLCAndXBncmFkZScpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdVcGdyYWRlcyB5b3VyIGRlcGVuZGVuY2llcyB0byB0aGUgbGF0ZXN0IHZlcnNpb24gYWNjb3JkaW5nIHRvIGNvbXBvc2VyLmpzb24sIGFuZCB1cGRhdGVzIHRoZSBjb21wb3Nlci5sb2NrIGZpbGUuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2VzJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2VzIHRoYXQgc2hvdWxkIGJlIHVwZGF0ZWQsIGlmIG5vdCBwcm92aWRlZCBhbGwgcGFja2FnZXMgYXJlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd3aXRoJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZIHwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnVGVtcG9yYXJ5IHZlcnNpb24gY29uc3RyYWludCB0byBhZGQsIGUuZy4gZm9vL2JhcjoxLjAuMCBvciBmb28vYmFyPTEuMC4wJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1zb3VyY2UnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlcyBpbnN0YWxsYXRpb24gZnJvbSBwYWNrYWdlIHNvdXJjZXMgd2hlbiBwb3NzaWJsZSwgaW5jbHVkaW5nIFZDUyBpbmZvcm1hdGlvbi4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWRpc3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlcyBpbnN0YWxsYXRpb24gZnJvbSBwYWNrYWdlIGRpc3QgKGRlZmF1bHQgYmVoYXZpb3IpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItaW5zdGFsbCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0ZvcmNlcyBpbnN0YWxsYXRpb24gZnJvbSBwYWNrYWdlIGRpc3R8c291cmNlfGF1dG8gKGF1dG8gY2hvb3NlcyBzb3VyY2UgZm9yIGRldiB2ZXJzaW9ucywgZGlzdCBmb3IgdGhlIHJlc3QpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkcnktcnVuJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPdXRwdXRzIHRoZSBvcGVyYXRpb25zIGJ1dCB3aWxsIG5vdCBleGVjdXRlIGFueXRoaW5nIChpbXBsaWNpdGx5IGVuYWJsZXMgLS12ZXJib3NlKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdERVBSRUNBVEVEOiBFbmFibGVzIGluc3RhbGxhdGlvbiBvZiByZXF1aXJlLWRldiBwYWNrYWdlcyAoZW5hYmxlZCBieSBkZWZhdWx0LCBvbmx5IHByZXNlbnQgZm9yIEJDKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyBpbnN0YWxsYXRpb24gb2YgcmVxdWlyZS1kZXYgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2xvY2snLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ092ZXJ3cml0ZXMgdGhlIGxvY2sgZmlsZSBoYXNoIHRvIHN1cHByZXNzIHdhcm5pbmcgYWJvdXQgdGhlIGxvY2sgZmlsZSBiZWluZyBvdXQgb2YgZGF0ZSB3aXRob3V0IHVwZGF0aW5nIHBhY2thZ2UgdmVyc2lvbnMuIFBhY2thZ2UgbWV0YWRhdGEgbGlrZSBtaXJyb3JzIGFuZCBVUkxzIGFyZSB1cGRhdGVkIGlmIHRoZXkgY2hhbmdlZC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8taW5zdGFsbCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2tpcCB0aGUgaW5zdGFsbCBzdGVwIGFmdGVyIHVwZGF0aW5nIHRoZSBjb21wb3Nlci5sb2NrIGZpbGUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWF1dG9sb2FkZXInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXBzIGF1dG9sb2FkZXIgZ2VuZXJhdGlvbicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zdWdnZXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdERVBSRUNBVEVEOiBUaGlzIGZsYWcgZG9lcyBub3QgZXhpc3QgYW55bW9yZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tcHJvZ3Jlc3MnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCBvdXRwdXQgZG93bmxvYWQgcHJvZ3Jlc3MuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3dpdGgtZGVwZW5kZW5jaWVzJywgJ3cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1VwZGF0ZSBhbHNvIGRlcGVuZGVuY2llcyBvZiBwYWNrYWdlcyBpbiB0aGUgYXJndW1lbnQgbGlzdCwgZXhjZXB0IHRob3NlIHdoaWNoIGFyZSByb290IHJlcXVpcmVtZW50cy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignd2l0aC1hbGwtZGVwZW5kZW5jaWVzJywgJ1cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1VwZGF0ZSBhbHNvIGRlcGVuZGVuY2llcyBvZiBwYWNrYWdlcyBpbiB0aGUgYXJndW1lbnQgbGlzdCwgaW5jbHVkaW5nIHRob3NlIHdoaWNoIGFyZSByb290IHJlcXVpcmVtZW50cy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndmVyYm9zZScsICd2fHZ2fHZ2dicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvd3MgbW9yZSBkZXRhaWxzIGluY2x1ZGluZyBuZXcgY29tbWl0cyBwdWxsZWQgaW4gd2hlbiB1cGRhdGluZyBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcHRpbWl6ZSBhdXRvbG9hZGVyIGR1cmluZyBhdXRvbG9hZGVyIGR1bXAuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnLCAnYScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQXV0b2xvYWQgY2xhc3NlcyBmcm9tIHRoZSBjbGFzc21hcCBvbmx5LiBJbXBsaWNpdGx5IGVuYWJsZXMgYC0tb3B0aW1pemUtYXV0b2xvYWRlcmAuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlcicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnVXNlIEFQQ3UgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdVc2UgYSBjdXN0b20gcHJlZml4IGZvciB0aGUgQVBDdSBhdXRvbG9hZGVyIGNhY2hlLiBJbXBsaWNpdGx5IGVuYWJsZXMgLS1hcGN1LWF1dG9sb2FkZXInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0lnbm9yZSBhbGwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLXN0YWJsZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJlZmVyIHN0YWJsZSB2ZXJzaW9ucyBvZiBkZXBlbmRlbmNpZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1sb3dlc3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1ByZWZlciBsb3dlc3QgdmVyc2lvbnMgb2YgZGVwZW5kZW5jaWVzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpbnRlcmFjdGl2ZScsICdpJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdJbnRlcmFjdGl2ZSBpbnRlcmZhY2Ugd2l0aCBhdXRvY29tcGxldGlvbiB0byBzZWxlY3QgdGhlIHBhY2thZ2VzIHRvIHVwZGF0ZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncm9vdC1yZXFzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZXN0cmljdHMgdGhlIHVwZGF0ZSB0byB5b3VyIGZpcnN0IGRlZ3JlZSBkZXBlbmRlbmNpZXMuJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+dXBkYXRlPC9pbmZvPiBjb21tYW5kIHJlYWRzIHRoZSBjb21wb3Nlci5qc29uIGZpbGUgZnJvbSB0aGUKY3VycmVudCBkaXJlY3RvcnksIHByb2Nlc3NlcyBpdCwgYW5kIHVwZGF0ZXMsIHJlbW92ZXMgb3IgaW5zdGFsbHMgYWxsIHRoZQpkZXBlbmRlbmNpZXMuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciB1cGRhdGU8L2luZm8+CgpUbyBsaW1pdCB0aGUgdXBkYXRlIG9wZXJhdGlvbiB0byBhIGZldyBwYWNrYWdlcywgeW91IGNhbiBsaXN0IHRoZSBwYWNrYWdlKHMpCnlvdSB3YW50IHRvIHVwZGF0ZSBhcyBzdWNoOgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgdXBkYXRlIHZlbmRvci9wYWNrYWdlMSBmb28vbXlwYWNrYWdlIFsuLi5dPC9pbmZvPgoKWW91IG1heSBhbHNvIHVzZSBhbiBhc3RlcmlzayAoKikgcGF0dGVybiB0byBsaW1pdCB0aGUgdXBkYXRlIG9wZXJhdGlvbiB0byBwYWNrYWdlKHMpCmZyb20gYSBzcGVjaWZpYyB2ZW5kb3I6Cgo8aW5mbz5waHAgY29tcG9zZXIucGhhciB1cGRhdGUgdmVuZG9yL3BhY2thZ2UxIGZvby8qIFsuLi5dPC9pbmZvPgoKVG8gcnVuIGFuIHVwZGF0ZSB3aXRoIG1vcmUgcmVzdHJpY3RpdmUgY29uc3RyYWludHMgeW91IGNhbiB1c2U6Cgo8aW5mbz5waHAgY29tcG9zZXIucGhhciB1cGRhdGUgLS13aXRoIHZlbmRvci9wYWNrYWdlOjEuMC4qPC9pbmZvPgoKVG8gcnVuIGEgcGFydGlhbCB1cGRhdGUgd2l0aCBtb3JlIHJlc3RyaWN0aXZlIGNvbnN0cmFpbnRzIHlvdSBjYW4gdXNlIHRoZSBzaG9ydGhhbmQ6Cgo8aW5mbz5waHAgY29tcG9zZXIucGhhciB1cGRhdGUgdmVuZG9yL3BhY2thZ2U6MS4wLio8L2luZm8+CgpUbyBzZWxlY3QgcGFja2FnZXMgbmFtZXMgaW50ZXJhY3RpdmVseSB3aXRoIGF1dG8tY29tcGxldGlvbiB1c2UgPGluZm8+LWk8L2luZm8+LgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjdXBkYXRlLXUKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgdXNpbmcgdGhlIGRlcHJlY2F0ZWQgb3B0aW9uICItLWRldiIuIEl0IGhhcyBubyBlZmZlY3QgYW5kIHdpbGwgYnJlYWsgaW4gQ29tcG9zZXIgMy48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tc3VnZ2VzdCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gIi0tbm8tc3VnZ2VzdCIuIEl0IGhhcyBubyBlZmZlY3QgYW5kIHdpbGwgYnJlYWsgaW4gQ29tcG9zZXIgMy48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIodHJ1ZSwgJGlucHV0LT5nZXRPcHRpb24oJ25vLXBsdWdpbnMnKSwgJGlucHV0LT5nZXRPcHRpb24oJ25vLXNjcmlwdHMnKSk7CgogICAgICAgIGlmICghSHR0cERvd25sb2FkZXI6OmlzQ3VybEVuYWJsZWQoKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNvbXBvc2VyIGlzIG9wZXJhdGluZyBzaWduaWZpY2FudGx5IHNsb3dlciB0aGFuIG5vcm1hbCBiZWNhdXNlIHlvdSBkbyBub3QgaGF2ZSB0aGUgUEhQIGN1cmwgZXh0ZW5zaW9uIGVuYWJsZWQuPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VzID0gJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZXMnKTsKICAgICAgICAkcmVxcyA9ICR0aGlzLT5mb3JtYXRSZXF1aXJlbWVudHMoJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgnKSk7CgogICAgICAgIC8vIGV4dHJhY3QgLS13aXRoIHNob3J0aGFuZHMgZnJvbSB0aGUgYWxsb3dsaXN0CiAgICAgICAgaWYgKCRwYWNrYWdlcykgewogICAgICAgICAgICAkYWxsb3dsaXN0UGFja2FnZXNXaXRoUmVxdWlyZW1lbnRzID0gYXJyYXlfZmlsdGVyKCRwYWNrYWdlcywgZnVuY3Rpb24gKCRwa2cpIHsKICAgICAgICAgICAgICAgIHJldHVybiBQcmVnOjppc01hdGNoKCd7XFMrWyA9Ol1cUyt9JywgJHBrZyk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Zm9ybWF0UmVxdWlyZW1lbnRzKCRhbGxvd2xpc3RQYWNrYWdlc1dpdGhSZXF1aXJlbWVudHMpIGFzICRwYWNrYWdlID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAkcmVxc1skcGFja2FnZV0gPSAkY29uc3RyYWludDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gcmVwbGFjZSB0aGUgZm9vL2JhcjpyZXEgYnkgZm9vL2JhciBpbiB0aGUgYWxsb3dsaXN0CiAgICAgICAgICAgIGZvcmVhY2ggKCRhbGxvd2xpc3RQYWNrYWdlc1dpdGhSZXF1aXJlbWVudHMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlTmFtZSA9IFByZWc6OnJlcGxhY2UoJ3teKFteID06XSspWyA9Ol0uKiR9JywgJyQxJywgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgJGluZGV4ID0gYXJyYXlfc2VhcmNoKCRwYWNrYWdlLCAkcGFja2FnZXMpOwogICAgICAgICAgICAgICAgJHBhY2thZ2VzWyRpbmRleF0gPSAkcGFja2FnZU5hbWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRyb290UGFja2FnZSA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICRyb290UmVxdWlyZXMgPSAkcm9vdFBhY2thZ2UtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgJHJvb3REZXZSZXF1aXJlcyA9ICRyb290UGFja2FnZS0+Z2V0RGV2UmVxdWlyZXMoKTsKICAgICAgICBmb3JlYWNoICgkcmVxcyBhcyAkcGFja2FnZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHJvb3RSZXF1aXJlc1skcGFja2FnZV0pKSB7CiAgICAgICAgICAgICAgICAkcm9vdFJlcXVpcmVzWyRwYWNrYWdlXSA9ICR0aGlzLT5hcHBlbmRDb25zdHJhaW50VG9MaW5rKCRyb290UmVxdWlyZXNbJHBhY2thZ2VdLCAkY29uc3RyYWludCk7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkcm9vdERldlJlcXVpcmVzWyRwYWNrYWdlXSkpIHsKICAgICAgICAgICAgICAgICRyb290RGV2UmVxdWlyZXNbJHBhY2thZ2VdID0gJHRoaXMtPmFwcGVuZENvbnN0cmFpbnRUb0xpbmsoJHJvb3REZXZSZXF1aXJlc1skcGFja2FnZV0sICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdPbmx5IHJvb3QgcGFja2FnZSByZXF1aXJlbWVudHMgY2FuIHJlY2VpdmUgdGVtcG9yYXJ5IGNvbnN0cmFpbnRzIGFuZCAnLiRwYWNrYWdlLicgaXMgbm90IG9uZScpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRyb290UGFja2FnZS0+c2V0UmVxdWlyZXMoJHJvb3RSZXF1aXJlcyk7CiAgICAgICAgJHJvb3RQYWNrYWdlLT5zZXREZXZSZXF1aXJlcygkcm9vdERldlJlcXVpcmVzKTsKICAgICAgICAkcm9vdFBhY2thZ2UtPnNldFJlZmVyZW5jZXMoUm9vdFBhY2thZ2VMb2FkZXI6OmV4dHJhY3RSZWZlcmVuY2VzKCRyZXFzLCAkcm9vdFBhY2thZ2UtPmdldFJlZmVyZW5jZXMoKSkpOwogICAgICAgICRyb290UGFja2FnZS0+c2V0U3RhYmlsaXR5RmxhZ3MoUm9vdFBhY2thZ2VMb2FkZXI6OmV4dHJhY3RTdGFiaWxpdHlGbGFncygkcmVxcywgJHJvb3RQYWNrYWdlLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCksICRyb290UGFja2FnZS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKSkpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2ludGVyYWN0aXZlJykpIHsKICAgICAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmdldFBhY2thZ2VzSW50ZXJhY3RpdmVseSgkaW8sICRpbnB1dCwgJG91dHB1dCwgJGNvbXBvc2VyLCAkcGFja2FnZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdyb290LXJlcXMnKSkgewogICAgICAgICAgICAkcmVxdWlyZXMgPSBhcnJheV9rZXlzKCRyb290UmVxdWlyZXMpOwogICAgICAgICAgICBpZiAoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkgewogICAgICAgICAgICAgICAgJHJlcXVpcmVzID0gYXJyYXlfbWVyZ2UoJHJlcXVpcmVzLCBhcnJheV9rZXlzKCRyb290RGV2UmVxdWlyZXMpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZXMgPSBhcnJheV9pbnRlcnNlY3QoJHBhY2thZ2VzLCAkcmVxdWlyZXMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJHJlcXVpcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyB0aGUgYXJndW1lbnRzIGxvY2svbm90aGluZy9taXJyb3JzIGFyZSBub3QgcGFja2FnZSBuYW1lcyBidXQgdHJpZ2dlciBhIG1pcnJvciB1cGRhdGUgaW5zdGVhZAogICAgICAgIC8vIHRoZXkgYXJlIGZ1cnRoZXIgbXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggbGlzdGluZyBhY3R1YWwgcGFja2FnZSBuYW1lcwogICAgICAgICRmaWx0ZXJlZFBhY2thZ2VzID0gYXJyYXlfZmlsdGVyKCRwYWNrYWdlcywgZnVuY3Rpb24gKCRwYWNrYWdlKSB7CiAgICAgICAgICAgIHJldHVybiAhaW5fYXJyYXkoJHBhY2thZ2UsIGFycmF5KCdsb2NrJywgJ25vdGhpbmcnLCAnbWlycm9ycycpLCB0cnVlKTsKICAgICAgICB9KTsKICAgICAgICAkdXBkYXRlTWlycm9ycyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdsb2NrJykgfHwgY291bnQoJGZpbHRlcmVkUGFja2FnZXMpICE9IGNvdW50KCRwYWNrYWdlcyk7CiAgICAgICAgJHBhY2thZ2VzID0gJGZpbHRlcmVkUGFja2FnZXM7CgogICAgICAgIGlmICgkdXBkYXRlTWlycm9ycyAmJiAhZW1wdHkoJHBhY2thZ2VzKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5Zb3UgY2Fubm90IHNpbXVsdGFuZW91c2x5IHVwZGF0ZSBvbmx5IGEgc2VsZWN0aW9uIG9mIHBhY2thZ2VzIGFuZCByZWdlbmVyYXRlIHRoZSBsb2NrIGZpbGUgbWV0YWRhdGEuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3VwZGF0ZScsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPnNldE91dHB1dFByb2dyZXNzKCEkaW5wdXQtPmdldE9wdGlvbignbm8tcHJvZ3Jlc3MnKSk7CgogICAgICAgICRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoJGlvLCAkY29tcG9zZXIpOwoKICAgICAgICAkY29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKTsKICAgICAgICBsaXN0KCRwcmVmZXJTb3VyY2UsICRwcmVmZXJEaXN0KSA9ICR0aGlzLT5nZXRQcmVmZXJyZWRJbnN0YWxsT3B0aW9ucygkY29uZmlnLCAkaW5wdXQpOwoKICAgICAgICAkb3B0aW1pemUgPSAkaW5wdXQtPmdldE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicpIHx8ICRjb25maWctPmdldCgnb3B0aW1pemUtYXV0b2xvYWRlcicpOwogICAgICAgICRhdXRob3JpdGF0aXZlID0gJGlucHV0LT5nZXRPcHRpb24oJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnKSB8fCAkY29uZmlnLT5nZXQoJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnKTsKICAgICAgICAkYXBjdVByZWZpeCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXItcHJlZml4Jyk7CiAgICAgICAgJGFwY3UgPSAkYXBjdVByZWZpeCAhPT0gbnVsbCB8fCAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJykgfHwgJGNvbmZpZy0+Z2V0KCdhcGN1LWF1dG9sb2FkZXInKTsKCiAgICAgICAgJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyA9IFJlcXVlc3Q6OlVQREFURV9PTkxZX0xJU1RFRDsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycpKSB7CiAgICAgICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBSZXF1ZXN0OjpVUERBVEVfTElTVEVEX1dJVEhfVFJBTlNJVElWRV9ERVBTOwogICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmdldE9wdGlvbignd2l0aC1kZXBlbmRlbmNpZXMnKSkgewogICAgICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQU19OT19ST09UX1JFUVVJUkU7CiAgICAgICAgfQoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAkaW5zdGFsbAogICAgICAgICAgICAtPnNldERyeVJ1bigkaW5wdXQtPmdldE9wdGlvbignZHJ5LXJ1bicpKQogICAgICAgICAgICAtPnNldFZlcmJvc2UoJGlucHV0LT5nZXRPcHRpb24oJ3ZlcmJvc2UnKSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJEaXN0KCRwcmVmZXJEaXN0KQogICAgICAgICAgICAtPnNldERldk1vZGUoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkKICAgICAgICAgICAgLT5zZXREdW1wQXV0b2xvYWRlcighJGlucHV0LT5nZXRPcHRpb24oJ25vLWF1dG9sb2FkZXInKSkKICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJG9wdGltaXplKQogICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkYXV0aG9yaXRhdGl2ZSkKICAgICAgICAgICAgLT5zZXRBcGN1QXV0b2xvYWRlcigkYXBjdSwgJGFwY3VQcmVmaXgpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlKHRydWUpCiAgICAgICAgICAgIC0+c2V0SW5zdGFsbCghJGlucHV0LT5nZXRPcHRpb24oJ25vLWluc3RhbGwnKSkKICAgICAgICAgICAgLT5zZXRVcGRhdGVNaXJyb3JzKCR1cGRhdGVNaXJyb3JzKQogICAgICAgICAgICAtPnNldFVwZGF0ZUFsbG93TGlzdCgkcGFja2FnZXMpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKCR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMpCiAgICAgICAgICAgIC0+c2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcihQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6ZnJvbUJvb2xPckxpc3QoJGlnbm9yZVBsYXRmb3JtUmVxcykpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyU3RhYmxlKCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItc3RhYmxlJykpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyTG93ZXN0KCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItbG93ZXN0JykpCiAgICAgICAgOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLXBsdWdpbnMnKSkgewogICAgICAgICAgICAkaW5zdGFsbC0+ZGlzYWJsZVBsdWdpbnMoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaW5zdGFsbC0+cnVuKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkcGFja2FnZXMKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFBhY2thZ2VzSW50ZXJhY3RpdmVseShJT0ludGVyZmFjZSAkaW8sIElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIENvbXBvc2VyICRjb21wb3NlciwgYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgIGlmICghJGlucHV0LT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJy0taW50ZXJhY3RpdmUgY2Fubm90IGJlIHVzZWQgaW4gbm9uLWludGVyYWN0aXZlIHRlcm1pbmFscy4nKTsKICAgICAgICB9CgogICAgICAgICRyZXF1aXJlcyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldERldlJlcXVpcmVzKCkKICAgICAgICApOwogICAgICAgICRhdXRvY29tcGxldGVyVmFsdWVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgJHRhcmdldCA9ICRyZXF1aXJlLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgJGF1dG9jb21wbGV0ZXJWYWx1ZXNbc3RydG9sb3dlcigkdGFyZ2V0KV0gPSAkdGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgJGluc3RhbGxlZFBhY2thZ2VzID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKS0+Z2V0UGFja2FnZXMoKTsKICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkUGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGF1dG9jb21wbGV0ZXJWYWx1ZXNbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgIH0KCiAgICAgICAgJGhlbHBlciA9ICR0aGlzLT5nZXRIZWxwZXIoJ3F1ZXN0aW9uJyk7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IFF1ZXN0aW9uKCc8Y29tbWVudD5FbnRlciBwYWNrYWdlIG5hbWU6IDwvY29tbWVudD4nLCBudWxsKTsKCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5QcmVzcyBlbnRlciB3aXRob3V0IHZhbHVlIHRvIGVuZCBzdWJtaXNzaW9uPC9pbmZvPicpOwoKICAgICAgICBkbyB7CiAgICAgICAgICAgICRhdXRvY29tcGxldGVyVmFsdWVzID0gYXJyYXlfZGlmZigkYXV0b2NvbXBsZXRlclZhbHVlcywgJHBhY2thZ2VzKTsKICAgICAgICAgICAgJHF1ZXN0aW9uLT5zZXRBdXRvY29tcGxldGVyVmFsdWVzKCRhdXRvY29tcGxldGVyVmFsdWVzKTsKICAgICAgICAgICAgJGFkZGVkUGFja2FnZSA9ICRoZWxwZXItPmFzaygkaW5wdXQsICRvdXRwdXQsICRxdWVzdGlvbik7CgogICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkYWRkZWRQYWNrYWdlKSB8fCBlbXB0eSgkYWRkZWRQYWNrYWdlKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRhZGRlZFBhY2thZ2UgPSBzdHJ0b2xvd2VyKCRhZGRlZFBhY2thZ2UpOwogICAgICAgICAgICBpZiAoIWluX2FycmF5KCRhZGRlZFBhY2thZ2UsICRwYWNrYWdlcykpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJGFkZGVkUGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKHRydWUpOwoKICAgICAgICAkcGFja2FnZXMgPSBhcnJheV9maWx0ZXIoJHBhY2thZ2VzKTsKICAgICAgICBpZiAoISRwYWNrYWdlcykgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignWW91IG11c3QgZW50ZXIgbWluaW11bSBvbmUgcGFja2FnZS4nKTsKICAgICAgICB9CgogICAgICAgICR0YWJsZSA9IG5ldyBUYWJsZSgkb3V0cHV0KTsKICAgICAgICAkdGFibGUtPnNldEhlYWRlcnMoYXJyYXkoJ1NlbGVjdGVkIHBhY2thZ2VzJykpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkdGFibGUtPmFkZFJvdyhhcnJheSgkcGFja2FnZSkpOwogICAgICAgIH0KICAgICAgICAkdGFibGUtPnJlbmRlcigpOwoKICAgICAgICBpZiAoJGlvLT5hc2tDb25maXJtYXRpb24oc3ByaW50ZigKICAgICAgICAgICAgJ1dvdWxkIHlvdSBsaWtlIHRvIGNvbnRpbnVlIGFuZCB1cGRhdGUgdGhlIGFib3ZlIHBhY2thZ2UlcyBbPGNvbW1lbnQ+eWVzPC9jb21tZW50Pl0/ICcsCiAgICAgICAgICAgIDEgPT09IGNvdW50KCRwYWNrYWdlcykgPyAnJyA6ICdzJwogICAgICAgICkpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0luc3RhbGxhdGlvbiBhYm9ydGVkLicpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkY29uc3RyYWludAogICAgICogQHJldHVybiBMaW5rCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwZW5kQ29uc3RyYWludFRvTGluayhMaW5rICRsaW5rLCAkY29uc3RyYWludCkKICAgIHsKICAgICAgICAkcGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgJG9sZFByZXR0eVN0cmluZyA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCktPmdldFByZXR0eVN0cmluZygpOwogICAgICAgICRuZXdDb25zdHJhaW50ID0gTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoYXJyYXkoJGxpbmstPmdldENvbnN0cmFpbnQoKSwgJHBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCkpKTsKICAgICAgICAkbmV3Q29uc3RyYWludC0+c2V0UHJldHR5U3RyaW5nKCRvbGRQcmV0dHlTdHJpbmcuJywgJy4kY29uc3RyYWludCk7CgogICAgICAgIHJldHVybiBuZXcgTGluaygKICAgICAgICAgICAgJGxpbmstPmdldFNvdXJjZSgpLAogICAgICAgICAgICAkbGluay0+Z2V0VGFyZ2V0KCksCiAgICAgICAgICAgICRuZXdDb25zdHJhaW50LAogICAgICAgICAgICAvKiogQHBocHN0YW4taWdub3JlLW5leHQtbGluZSAqLwogICAgICAgICAgICAkbGluay0+Z2V0RGVzY3JpcHRpb24oKSwKICAgICAgICAgICAgJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSAuICcsICcgLiAkY29uc3RyYWludAogICAgICAgICk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxEZWZhdWx0UG9saWN5Owp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uU2VsZWN0b3I7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkQXJyYXlSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NlclJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XENvbXBvc2l0ZVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEZpbHRlclJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFBsYXRmb3JtUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUZhY3Rvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQ7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcU2VtdmVyOwp1c2UgQ29tcG9zZXJcU3BkeFxTcGR4TGljZW5zZXM7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJTdHlsZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgSsOpcsOpbXkgUm9tZXkgPGplcmVteUZyZWVBZ2VudD4KICogQGF1dGhvciBNaWhhaSBQbGFzb2lhbnUgPG1paGFpQHBsYXNvaWFudS5kZT4KICovCmNsYXNzIFNob3dDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqIEB2YXIgVmVyc2lvblBhcnNlciAqLwogICAgcHJvdGVjdGVkICR2ZXJzaW9uUGFyc2VyOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByb3RlY3RlZCAkY29sb3JzOwoKICAgIC8qKiBAdmFyID9SZXBvc2l0b3J5U2V0ICovCiAgICBwcml2YXRlICRyZXBvc2l0b3J5U2V0OwoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnc2hvdycpCiAgICAgICAgICAgIC0+c2V0QWxpYXNlcyhhcnJheSgnaW5mbycpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdTaG93cyBpbmZvcm1hdGlvbiBhYm91dCBwYWNrYWdlcy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnUGFja2FnZSB0byBpbnNwZWN0LiBPciBhIG5hbWUgaW5jbHVkaW5nIGEgd2lsZGNhcmQgKCopIHRvIGZpbHRlciBsaXN0cyBvZiBwYWNrYWdlcyBpbnN0ZWFkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3ZlcnNpb24nLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1ZlcnNpb24gb3IgdmVyc2lvbiBjb25zdHJhaW50IHRvIGluc3BlY3QnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IGFsbCBwYWNrYWdlcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsb2NrZWQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0xpc3QgYWxsIGxvY2tlZCBwYWNrYWdlcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpbnN0YWxsZWQnLCAnaScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnTGlzdCBpbnN0YWxsZWQgcGFja2FnZXMgb25seSAoZW5hYmxlZCBieSBkZWZhdWx0LCBvbmx5IHByZXNlbnQgZm9yIEJDKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncGxhdGZvcm0nLCAncCcsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnTGlzdCBwbGF0Zm9ybSBwYWNrYWdlcyBvbmx5JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2F2YWlsYWJsZScsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IGF2YWlsYWJsZSBwYWNrYWdlcyBvbmx5JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3NlbGYnLCAncycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvdyB0aGUgcm9vdCBwYWNrYWdlIGluZm9ybWF0aW9uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25hbWUtb25seScsICdOJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IHBhY2thZ2UgbmFtZXMgb25seScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwYXRoJywgJ1AnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgcGFja2FnZSBwYXRocycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd0cmVlJywgJ3QnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0xpc3QgdGhlIGRlcGVuZGVuY2llcyBhcyBhIHRyZWUnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbGF0ZXN0JywgJ2wnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgdGhlIGxhdGVzdCB2ZXJzaW9uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ291dGRhdGVkJywgJ28nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgdGhlIGxhdGVzdCB2ZXJzaW9uIGJ1dCBvbmx5IGZvciBwYWNrYWdlcyB0aGF0IGFyZSBvdXRkYXRlZCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQgfCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVksICdJZ25vcmUgc3BlY2lmaWVkIHBhY2thZ2UocykuIFVzZSBpdCB3aXRoIHRoZSAtLW91dGRhdGVkIG9wdGlvbiBpZiB5b3UgZG9uXCd0IHdhbnQgdG8gYmUgaW5mb3JtZWQgYWJvdXQgbmV3IHZlcnNpb25zIG9mIHNvbWUgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ21pbm9yLW9ubHknLCAnbScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvdyBvbmx5IHBhY2thZ2VzIHRoYXQgaGF2ZSBtaW5vciBTZW1WZXItY29tcGF0aWJsZSB1cGRhdGVzLiBVc2Ugd2l0aCB0aGUgLS1vdXRkYXRlZCBvcHRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RpcmVjdCcsICdEJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93cyBvbmx5IHBhY2thZ2VzIHRoYXQgYXJlIGRpcmVjdGx5IHJlcXVpcmVkIGJ5IHRoZSByb290IHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc3RyaWN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZXR1cm4gYSBub24temVybyBleGl0IGNvZGUgd2hlbiB0aGVyZSBhcmUgb3V0ZGF0ZWQgcGFja2FnZXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZm9ybWF0JywgJ2YnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdGb3JtYXQgb2YgdGhlIG91dHB1dDogdGV4dCBvciBqc29uJywgJ3RleHQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyBzZWFyY2ggaW4gcmVxdWlyZS1kZXYgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQgfCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVksICdJZ25vcmUgYSBzcGVjaWZpYyBwbGF0Zm9ybSByZXF1aXJlbWVudCAocGhwICYgZXh0LSBwYWNrYWdlcykuIFVzZSB3aXRoIHRoZSAtLW91dGRhdGVkIG9wdGlvbicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgKHBocCAmIGV4dC0gcGFja2FnZXMpLiBVc2Ugd2l0aCB0aGUgLS1vdXRkYXRlZCBvcHRpb24nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSBzaG93IGNvbW1hbmQgZGlzcGxheXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBwYWNrYWdlLCBvcgpsaXN0cyBhbGwgcGFja2FnZXMgYXZhaWxhYmxlLgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjc2hvdwpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd0cmVlJykpIHsKICAgICAgICAgICAgJHRoaXMtPmluaXRTdHlsZXMoJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoZmFsc2UpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2luc3RhbGxlZCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gImluc3RhbGxlZCIuIE9ubHkgaW5zdGFsbGVkIHBhY2thZ2VzIGFyZSBzaG93biBieSBkZWZhdWx0IG5vdy4gVGhlIC0tYWxsIG9wdGlvbiBjYW4gYmUgdXNlZCB0byBzaG93IGFsbCBwYWNrYWdlcy48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ291dGRhdGVkJykpIHsKICAgICAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ2xhdGVzdCcsIHRydWUpOwogICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBvcHRpb24gImlnbm9yZSIgZm9yIGFjdGlvbiBvdGhlciB0aGFuICJvdXRkYXRlZCIsIGl0IHdpbGwgYmUgaWdub3JlZC48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2RpcmVjdCcpICYmICgkaW5wdXQtPmdldE9wdGlvbignYWxsJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ2F2YWlsYWJsZScpIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdwbGF0Zm9ybScpKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1RoZSAtLWRpcmVjdCAoLUQpIG9wdGlvbiBpcyBub3QgdXNhYmxlIGluIGNvbWJpbmF0aW9uIHdpdGggLS1hbGwsIC0tcGxhdGZvcm0gKC1wKSBvciAtLWF2YWlsYWJsZSAoLWEpJyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndHJlZScpICYmICgkaW5wdXQtPmdldE9wdGlvbignYWxsJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ2F2YWlsYWJsZScpKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1RoZSAtLXRyZWUgKC10KSBvcHRpb24gaXMgbm90IHVzYWJsZSBpbiBjb21iaW5hdGlvbiB3aXRoIC0tYWxsIG9yIC0tYXZhaWxhYmxlICgtYSknKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd0cmVlJykgJiYgJGlucHV0LT5nZXRPcHRpb24oJ2xhdGVzdCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignVGhlIC0tdHJlZSAoLXQpIG9wdGlvbiBpcyBub3QgdXNhYmxlIGluIGNvbWJpbmF0aW9uIHdpdGggLS1sYXRlc3QgKC1sKScpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3RyZWUnKSAmJiAkaW5wdXQtPmdldE9wdGlvbigncGF0aCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignVGhlIC0tdHJlZSAoLXQpIG9wdGlvbiBpcyBub3QgdXNhYmxlIGluIGNvbWJpbmF0aW9uIHdpdGggLS1wYXRoICgtUCknKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgJGZvcm1hdCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKTsKICAgICAgICBpZiAoIWluX2FycmF5KCRmb3JtYXQsIGFycmF5KCd0ZXh0JywgJ2pzb24nKSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoJ1Vuc3VwcG9ydGVkIGZvcm1hdCAiJXMiLiBTZWUgaGVscCBmb3Igc3VwcG9ydGVkIGZvcm1hdHMuJywgJGZvcm1hdCkpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAvLyBpbml0IHJlcG9zCiAgICAgICAgJHBsYXRmb3JtT3ZlcnJpZGVzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICRwbGF0Zm9ybU92ZXJyaWRlcyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgncGxhdGZvcm0nKSA/OiBhcnJheSgpOwogICAgICAgIH0KICAgICAgICAkcGxhdGZvcm1SZXBvID0gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkcGxhdGZvcm1PdmVycmlkZXMpOwogICAgICAgICRsb2NrZWRSZXBvID0gbnVsbDsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdzZWxmJykpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25hbWUtb25seScpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRwYWNrYWdlLT5nZXROYW1lKCkpOwoKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXBvcyA9ICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkobmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeSgkcGFja2FnZSkpKTsKICAgICAgICB9IGVsc2VpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3BsYXRmb3JtJykpIHsKICAgICAgICAgICAgJHJlcG9zID0gJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkcGxhdGZvcm1SZXBvKSk7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdhdmFpbGFibGUnKSkgewogICAgICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRwbGF0Zm9ybVJlcG8pKTsKICAgICAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAgICAgJHJlcG9zID0gbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSk7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVkUmVwby0+YWRkUmVwb3NpdG9yeSgkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRkZWZhdWx0UmVwb3MgPSBSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKCRpbyk7CiAgICAgICAgICAgICAgICAkcmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeSgkZGVmYXVsdFJlcG9zKTsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTm8gY29tcG9zZXIuanNvbiBmb3VuZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnksIHNob3dpbmcgYXZhaWxhYmxlIHBhY2thZ2VzIGZyb20gJyAuIGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkZGVmYXVsdFJlcG9zKSkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdhbGwnKSAmJiAkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGxvY2FsUmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CiAgICAgICAgICAgICRsb2NrZXIgPSAkY29tcG9zZXItPmdldExvY2tlcigpOwogICAgICAgICAgICBpZiAoJGxvY2tlci0+aXNMb2NrZWQoKSkgewogICAgICAgICAgICAgICAgJGxvY2tlZFJlcG8gPSAkbG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KHRydWUpOwogICAgICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkbG9ja2VkUmVwbywgJGxvY2FsUmVwbywgJHBsYXRmb3JtUmVwbykpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkbG9jYWxSZXBvLCAkcGxhdGZvcm1SZXBvKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlcG9zID0gbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoYXJyYXlfbWVyZ2UoYXJyYXkobmV3IEZpbHRlclJlcG9zaXRvcnkoJGluc3RhbGxlZFJlcG8sIGFycmF5KCdjYW5vbmljYWwnID0+IGZhbHNlKSkpLCAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpKSk7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdhbGwnKSkgewogICAgICAgICAgICAkZGVmYXVsdFJlcG9zID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmRlZmF1bHRSZXBvcygkaW8pOwogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ05vIGNvbXBvc2VyLmpzb24gZm91bmQgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LCBzaG93aW5nIGF2YWlsYWJsZSBwYWNrYWdlcyBmcm9tICcgLiBpbXBsb2RlKCcsICcsIGFycmF5X2tleXMoJGRlZmF1bHRSZXBvcykpKTsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkcGxhdGZvcm1SZXBvKSk7CiAgICAgICAgICAgICRyZXBvcyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KGFycmF5X21lcmdlKGFycmF5KCRpbnN0YWxsZWRSZXBvKSwgJGRlZmF1bHRSZXBvcykpOwogICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmdldE9wdGlvbignbG9ja2VkJykpIHsKICAgICAgICAgICAgaWYgKCEkY29tcG9zZXIgfHwgISRjb21wb3Nlci0+Z2V0TG9ja2VyKCktPmlzTG9ja2VkKCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdBIHZhbGlkIGNvbXBvc2VyLmpzb24gYW5kIGNvbXBvc2VyLmxvY2sgZmlsZXMgaXMgcmVxdWlyZWQgdG8gcnVuIHRoaXMgY29tbWFuZCB3aXRoIC0tbG9ja2VkJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxvY2tlciA9ICRjb21wb3Nlci0+Z2V0TG9ja2VyKCk7CiAgICAgICAgICAgICRsb2NrZWRSZXBvID0gJGxvY2tlci0+Z2V0TG9ja2VkUmVwb3NpdG9yeSghJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpKTsKICAgICAgICAgICAgJHJlcG9zID0gJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkbG9ja2VkUmVwbykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIC0taW5zdGFsbGVkIC8gZGVmYXVsdCBjYXNlCiAgICAgICAgICAgIGlmICghJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcm9vdFBrZyA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICAkcmVwb3MgPSAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCkpKTsKCiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICR0aGlzLT5maWx0ZXJSZXF1aXJlZFBhY2thZ2VzKCRpbnN0YWxsZWRSZXBvLCAkcm9vdFBrZyk7CiAgICAgICAgICAgICAgICAkcmVwb3MgPSAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KG5ldyBJbnN0YWxsZWRBcnJheVJlcG9zaXRvcnkoYXJyYXlfbWFwKGZ1bmN0aW9uICgkcGtnKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsb25lICRwa2c7CiAgICAgICAgICAgICAgICB9LCAkcGFja2FnZXMpKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRpbnN0YWxsZWRSZXBvLT5nZXRQYWNrYWdlcygpICYmICgkcm9vdFBrZy0+Z2V0UmVxdWlyZXMoKSB8fCAkcm9vdFBrZy0+Z2V0RGV2UmVxdWlyZXMoKSkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Tm8gZGVwZW5kZW5jaWVzIGluc3RhbGxlZC4gVHJ5IHJ1bm5pbmcgY29tcG9zZXIgaW5zdGFsbCBvciB1cGRhdGUuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3Nob3cnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaCgkY29tbWFuZEV2ZW50LT5nZXROYW1lKCksICRjb21tYW5kRXZlbnQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdsYXRlc3QnKSAmJiBudWxsID09PSAkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdObyBjb21wb3Nlci5qc29uIGZvdW5kIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwgZGlzYWJsaW5nICJsYXRlc3QiIG9wdGlvbicpOwogICAgICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignbGF0ZXN0JywgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VGaWx0ZXIgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJyk7CgogICAgICAgIC8vIHNob3cgc2luZ2xlIHBhY2thZ2Ugb3Igc2luZ2xlIHZlcnNpb24KICAgICAgICBpZiAoKCRwYWNrYWdlRmlsdGVyICYmIGZhbHNlID09PSBzdHJwb3MoJHBhY2thZ2VGaWx0ZXIsICcqJykpIHx8ICFlbXB0eSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgbGlzdCgkcGFja2FnZSwgJHZlcnNpb25zKSA9ICR0aGlzLT5nZXRQYWNrYWdlKCRpbnN0YWxsZWRSZXBvLCAkcmVwb3MsICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2UnKSwgJGlucHV0LT5nZXRBcmd1bWVudCgndmVyc2lvbicpKTsKCiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgJG9wdGlvbnMgPSAkaW5wdXQtPmdldE9wdGlvbnMoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRvcHRpb25zWyd3b3JraW5nLWRpciddKSB8fCAhZmlsZV9leGlzdHMoJ2NvbXBvc2VyLmpzb24nKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJykpICYmICEkaW5wdXQtPmdldE9wdGlvbigncGxhdGZvcm0nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BhY2thZ2UgJyAuICRwYWNrYWdlRmlsdGVyIC4gJyBub3QgZm91bmQsIHRyeSB1c2luZyAtLXBsYXRmb3JtICgtcCkgdG8gc2hvdyBwbGF0Zm9ybSBwYWNrYWdlcy4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSAnIC4gJHBhY2thZ2VGaWx0ZXIgLiAnIG5vdCBmb3VuZCcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdQYWNrYWdlICcgLiAkcGFja2FnZUZpbHRlciAuICcgbm90IGZvdW5kIGluICcgLiAkb3B0aW9uc1snd29ya2luZy1kaXInXSAuICcvY29tcG9zZXIuanNvbicpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9ucyA9IGFycmF5KCRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgPT4gJHBhY2thZ2UtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRleGl0Q29kZSA9IDA7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndHJlZScpKSB7CiAgICAgICAgICAgICAgICAkYXJyYXlUcmVlID0gJHRoaXMtPmdlbmVyYXRlUGFja2FnZVRyZWUoJHBhY2thZ2UsICRpbnN0YWxsZWRSZXBvLCAkcmVwb3MpOwoKICAgICAgICAgICAgICAgIGlmICgnanNvbicgPT09ICRmb3JtYXQpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKEpzb25GaWxlOjplbmNvZGUoYXJyYXkoJ2luc3RhbGxlZCcgPT4gYXJyYXkoJGFycmF5VHJlZSkpKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kaXNwbGF5UGFja2FnZVRyZWUoYXJyYXkoJGFycmF5VHJlZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGxhdGVzdFBhY2thZ2UgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdsYXRlc3QnKSkgewogICAgICAgICAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gJHRoaXMtPmZpbmRMYXRlc3RQYWNrYWdlKCRwYWNrYWdlLCAkY29tcG9zZXIsICRwbGF0Zm9ybVJlcG8sICRpbnB1dC0+Z2V0T3B0aW9uKCdtaW5vci1vbmx5JyksICRpZ25vcmVQbGF0Zm9ybVJlcXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCdvdXRkYXRlZCcpCiAgICAgICAgICAgICAgICAgICAgJiYgJGlucHV0LT5nZXRPcHRpb24oJ3N0cmljdCcpCiAgICAgICAgICAgICAgICAgICAgJiYgJGxhdGVzdFBhY2thZ2UKICAgICAgICAgICAgICAgICAgICAmJiAkbGF0ZXN0UGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAhPT0gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkKICAgICAgICAgICAgICAgICAgICAmJiAoISRsYXRlc3RQYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlIHx8ICEkbGF0ZXN0UGFja2FnZS0+aXNBYmFuZG9uZWQoKSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICRleGl0Q29kZSA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3BhdGgnKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJHBhY2thZ2UtPmdldE5hbWUoKSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJyAnIC4gc3RydG9rKHJlYWxwYXRoKCRjb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSkpLCAiXHJcbiIpKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRleGl0Q29kZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJ2pzb24nID09PSAkZm9ybWF0KSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnByaW50UGFja2FnZUluZm9Bc0pzb24oJHBhY2thZ2UsICR2ZXJzaW9ucywgJGluc3RhbGxlZFJlcG8sICRsYXRlc3RQYWNrYWdlID86IG51bGwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cHJpbnRQYWNrYWdlSW5mbygkcGFja2FnZSwgJHZlcnNpb25zLCAkaW5zdGFsbGVkUmVwbywgJGxhdGVzdFBhY2thZ2UgPzogbnVsbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkZXhpdENvZGU7CiAgICAgICAgfQoKICAgICAgICAvLyBzaG93IHRyZWUgdmlldyBpZiByZXF1ZXN0ZWQKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3RyZWUnKSkgewogICAgICAgICAgICAkcm9vdFJlcXVpcmVzID0gJHRoaXMtPmdldFJvb3RSZXF1aXJlcygpOwogICAgICAgICAgICAkcGFja2FnZXMgPSAkaW5zdGFsbGVkUmVwby0+Z2V0UGFja2FnZXMoKTsKICAgICAgICAgICAgdXNvcnQoJHBhY2thZ2VzLCBmdW5jdGlvbiAoQmFzZVBhY2thZ2UgJGEsIEJhc2VQYWNrYWdlICRiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3RyY21wKChzdHJpbmcpICRhLCAoc3RyaW5nKSAkYik7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkYXJyYXlUcmVlID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJHJvb3RSZXF1aXJlcywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAkYXJyYXlUcmVlW10gPSAkdGhpcy0+Z2VuZXJhdGVQYWNrYWdlVHJlZSgkcGFja2FnZSwgJGluc3RhbGxlZFJlcG8sICRyZXBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgnanNvbicgPT09ICRmb3JtYXQpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoSnNvbkZpbGU6OmVuY29kZShhcnJheSgnaW5zdGFsbGVkJyA9PiAkYXJyYXlUcmVlKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXlQYWNrYWdlVHJlZSgkYXJyYXlUcmVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBsaXN0IHBhY2thZ2VzCiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkcGFja2FnZUZpbHRlclJlZ2V4ID0gbnVsbDsKICAgICAgICBpZiAobnVsbCAhPT0gJHBhY2thZ2VGaWx0ZXIpIHsKICAgICAgICAgICAgJHBhY2thZ2VGaWx0ZXJSZWdleCA9ICd7Xicuc3RyX3JlcGxhY2UoJ1xcKicsICcuKj8nLCBwcmVnX3F1b3RlKCRwYWNrYWdlRmlsdGVyKSkuJyR9aSc7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZUxpc3RGaWx0ZXIgPSBhcnJheSgpOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGlyZWN0JykpIHsKICAgICAgICAgICAgJHBhY2thZ2VMaXN0RmlsdGVyID0gJHRoaXMtPmdldFJvb3RSZXF1aXJlcygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdwYXRoJykgJiYgbnVsbCA9PT0gJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTm8gY29tcG9zZXIuanNvbiBmb3VuZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnksIGRpc2FibGluZyAicGF0aCIgb3B0aW9uJyk7CiAgICAgICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdwYXRoJywgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHJlcG9zLT5nZXRSZXBvc2l0b3JpZXMoKSBhcyAkcmVwbykgewogICAgICAgICAgICBpZiAoJHJlcG8gPT09ICRwbGF0Zm9ybVJlcG8pIHsKICAgICAgICAgICAgICAgICR0eXBlID0gJ3BsYXRmb3JtJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRsb2NrZWRSZXBvICE9PSBudWxsICYmICRyZXBvID09PSAkbG9ja2VkUmVwbykgewogICAgICAgICAgICAgICAgJHR5cGUgPSAnbG9ja2VkJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRyZXBvID09PSAkaW5zdGFsbGVkUmVwbyB8fCBpbl9hcnJheSgkcmVwbywgJGluc3RhbGxlZFJlcG8tPmdldFJlcG9zaXRvcmllcygpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJHR5cGUgPSAnaW5zdGFsbGVkJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0eXBlID0gJ2F2YWlsYWJsZSc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRyZXBvIGluc3RhbmNlb2YgQ29tcG9zZXJSZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZU5hbWVzKCRwYWNrYWdlRmlsdGVyKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1skdHlwZV1bJG5hbWVdID0gJG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VzWyR0eXBlXVskcGFja2FnZS0+Z2V0TmFtZSgpXSkKICAgICAgICAgICAgICAgICAgICAgICAgfHwgIWlzX29iamVjdCgkcGFja2FnZXNbJHR5cGVdWyRwYWNrYWdlLT5nZXROYW1lKCldKQogICAgICAgICAgICAgICAgICAgICAgICB8fCB2ZXJzaW9uX2NvbXBhcmUoJHBhY2thZ2VzWyR0eXBlXVskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0VmVyc2lvbigpLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpLCAnPCcpCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHBhY2thZ2VGaWx0ZXJSZWdleCB8fCBQcmVnOjppc01hdGNoKCRwYWNrYWdlRmlsdGVyUmVnZXgsICRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRwYWNrYWdlTGlzdEZpbHRlciB8fCBpbl9hcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcGFja2FnZUxpc3RGaWx0ZXIsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzWyR0eXBlXVskcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRyZXBvID09PSAkcGxhdGZvcm1SZXBvKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBsYXRmb3JtUmVwby0+Z2V0RGlzYWJsZWRQYWNrYWdlcygpIGFzICRuYW1lID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1skdHlwZV1bJG5hbWVdID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkc2hvd0FsbFR5cGVzID0gJGlucHV0LT5nZXRPcHRpb24oJ2FsbCcpOwogICAgICAgICRzaG93TGF0ZXN0ID0gJGlucHV0LT5nZXRPcHRpb24oJ2xhdGVzdCcpOwogICAgICAgICRzaG93TWlub3JPbmx5ID0gJGlucHV0LT5nZXRPcHRpb24oJ21pbm9yLW9ubHknKTsKICAgICAgICAkaWdub3JlZFBhY2thZ2VzID0gYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZScpKTsKICAgICAgICAkaW5kZW50ID0gJHNob3dBbGxUeXBlcyA/ICcgICcgOiAnJzsKICAgICAgICAvKiogQHZhciBQYWNrYWdlSW50ZXJmYWNlW10gJGxhdGVzdFBhY2thZ2VzICovCiAgICAgICAgJGxhdGVzdFBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkZXhpdENvZGUgPSAwOwogICAgICAgICR2aWV3RGF0YSA9IGFycmF5KCk7CiAgICAgICAgJHZpZXdNZXRhRGF0YSA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3BsYXRmb3JtJyA9PiB0cnVlLCAnbG9ja2VkJyA9PiB0cnVlLCAnYXZhaWxhYmxlJyA9PiBmYWxzZSwgJ2luc3RhbGxlZCcgPT4gdHJ1ZSkgYXMgJHR5cGUgPT4gJHNob3dWZXJzaW9uKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZXNbJHR5cGVdKSkgewogICAgICAgICAgICAgICAga3NvcnQoJHBhY2thZ2VzWyR0eXBlXSk7CgogICAgICAgICAgICAgICAgJG5hbWVMZW5ndGggPSAkdmVyc2lvbkxlbmd0aCA9ICRsYXRlc3RMZW5ndGggPSAwOwoKICAgICAgICAgICAgICAgIGlmICgkc2hvd0xhdGVzdCAmJiAkc2hvd1ZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXNbJHR5cGVdIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19vYmplY3QoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0UGFja2FnZSA9ICR0aGlzLT5maW5kTGF0ZXN0UGFja2FnZSgkcGFja2FnZSwgJGNvbXBvc2VyLCAkcGxhdGZvcm1SZXBvLCAkc2hvd01pbm9yT25seSwgJGlnbm9yZVBsYXRmb3JtUmVxcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxhdGVzdFBhY2thZ2UgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxhdGVzdFBhY2thZ2VzWyRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCldID0gJGxhdGVzdFBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHdyaXRlUGF0aCA9ICEkaW5wdXQtPmdldE9wdGlvbignbmFtZS1vbmx5JykgJiYgJGlucHV0LT5nZXRPcHRpb24oJ3BhdGgnKTsKICAgICAgICAgICAgICAgICR3cml0ZVZlcnNpb24gPSAhJGlucHV0LT5nZXRPcHRpb24oJ25hbWUtb25seScpICYmICEkaW5wdXQtPmdldE9wdGlvbigncGF0aCcpICYmICRzaG93VmVyc2lvbjsKICAgICAgICAgICAgICAgICR3cml0ZUxhdGVzdCA9ICR3cml0ZVZlcnNpb24gJiYgJHNob3dMYXRlc3Q7CiAgICAgICAgICAgICAgICAkd3JpdGVEZXNjcmlwdGlvbiA9ICEkaW5wdXQtPmdldE9wdGlvbignbmFtZS1vbmx5JykgJiYgISRpbnB1dC0+Z2V0T3B0aW9uKCdwYXRoJyk7CgogICAgICAgICAgICAgICAgJGhhc091dGRhdGVkUGFja2FnZXMgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAkdmlld0RhdGFbJHR5cGVdID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlc1skdHlwZV0gYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0UGFja2FnZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc2hvd0xhdGVzdCAmJiBpc3NldCgkbGF0ZXN0UGFja2FnZXNbJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0UGFja2FnZSA9ICRsYXRlc3RQYWNrYWdlc1skcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIGlmIENvbXBvc2VyIGlzIGNoZWNraW5nIG91dGRhdGVkIGRlcGVuZGVuY2llcyBhbmQgaWYgY3VycmVudCBwYWNrYWdlIHNob3VsZCB0cmlnZ2VyIG5vbi1kZWZhdWx0IGV4aXQgY29kZQogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZUlzVXBUb0RhdGUgPSAkbGF0ZXN0UGFja2FnZSAmJiAkbGF0ZXN0UGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSA9PT0gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkgJiYgKCEkbGF0ZXN0UGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSB8fCAhJGxhdGVzdFBhY2thZ2UtPmlzQWJhbmRvbmVkKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZUlzSWdub3JlZCA9IFxpbl9hcnJheSgkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLCAkaWdub3JlZFBhY2thZ2VzLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdvdXRkYXRlZCcpICYmICgkcGFja2FnZUlzVXBUb0RhdGUgfHwgJHBhY2thZ2VJc0lnbm9yZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdvdXRkYXRlZCcpIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdzdHJpY3QnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGhhc091dGRhdGVkUGFja2FnZXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhWyduYW1lJ10gPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAkbmFtZUxlbmd0aCA9IG1heCgkbmFtZUxlbmd0aCwgc3RybGVuKCRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR3cml0ZVZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlVmlld0RhdGFbJ3ZlcnNpb24nXSA9ICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25MZW5ndGggPSBtYXgoJHZlcnNpb25MZW5ndGgsIHN0cmxlbigkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkd3JpdGVMYXRlc3QgJiYgJGxhdGVzdFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlVmlld0RhdGFbJ2xhdGVzdCddID0gJGxhdGVzdFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhWydsYXRlc3Qtc3RhdHVzJ10gPSAkdGhpcy0+Z2V0VXBkYXRlU3RhdHVzKCRsYXRlc3RQYWNrYWdlLCAkcGFja2FnZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0TGVuZ3RoID0gbWF4KCRsYXRlc3RMZW5ndGgsIHN0cmxlbigkbGF0ZXN0UGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkd3JpdGVEZXNjcmlwdGlvbiAmJiAkcGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VWaWV3RGF0YVsnZGVzY3JpcHRpb24nXSA9ICRwYWNrYWdlLT5nZXREZXNjcmlwdGlvbigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkd3JpdGVQYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhWydwYXRoJ10gPSBzdHJ0b2socmVhbHBhdGgoJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKSksICJcclxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGF0ZXN0UGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAmJiAkbGF0ZXN0UGFja2FnZS0+aXNBYmFuZG9uZWQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VtZW50ID0gaXNfc3RyaW5nKCRsYXRlc3RQYWNrYWdlLT5nZXRSZXBsYWNlbWVudFBhY2thZ2UoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICdVc2UgJyAuICRsYXRlc3RQYWNrYWdlLT5nZXRSZXBsYWNlbWVudFBhY2thZ2UoKSAuICcgaW5zdGVhZCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdObyByZXBsYWNlbWVudCB3YXMgc3VnZ2VzdGVkJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlV2FybmluZyA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BhY2thZ2UgJXMgaXMgYWJhbmRvbmVkLCB5b3Ugc2hvdWxkIGF2b2lkIHVzaW5nIGl0LiAlcy4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VtZW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VWaWV3RGF0YVsnd2FybmluZyddID0gJHBhY2thZ2VXYXJuaW5nOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VWaWV3RGF0YVsnbmFtZSddID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgICAgICRuYW1lTGVuZ3RoID0gbWF4KCRuYW1lTGVuZ3RoLCBzdHJsZW4oJHBhY2thZ2UpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHZpZXdEYXRhWyR0eXBlXVtdID0gJHBhY2thZ2VWaWV3RGF0YTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR2aWV3TWV0YURhdGFbJHR5cGVdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ25hbWVMZW5ndGgnID0+ICRuYW1lTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uTGVuZ3RoJyA9PiAkdmVyc2lvbkxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAnbGF0ZXN0TGVuZ3RoJyA9PiAkbGF0ZXN0TGVuZ3RoLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignc3RyaWN0JykgJiYgJGhhc091dGRhdGVkUGFja2FnZXMpIHsKICAgICAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSAxOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJ2pzb24nID09PSAkZm9ybWF0KSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoSnNvbkZpbGU6OmVuY29kZSgkdmlld0RhdGEpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xhdGVzdCcpICYmIGFycmF5X2ZpbHRlcigkdmlld0RhdGEpKSB7CiAgICAgICAgICAgICAgICBpZiAoISRpby0+aXNEZWNvcmF0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTGVnZW5kOicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignISBwYXRjaCBvciBtaW5vciByZWxlYXNlIGF2YWlsYWJsZSAtIHVwZGF0ZSByZWNvbW1lbmRlZCcpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignfiBtYWpvciByZWxlYXNlIGF2YWlsYWJsZSAtIHVwZGF0ZSBwb3NzaWJsZScpOwogICAgICAgICAgICAgICAgICAgIGlmICghJGlucHV0LT5nZXRPcHRpb24oJ291dGRhdGVkJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc9IHVwIHRvIGRhdGUgdmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5Db2xvciBsZWdlbmQ6PC9pbmZvPicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignLSA8aGlnaGxpZ2h0PnBhdGNoIG9yIG1pbm9yPC9oaWdobGlnaHQ+IHJlbGVhc2UgYXZhaWxhYmxlIC0gdXBkYXRlIHJlY29tbWVuZGVkJyk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCctIDxjb21tZW50Pm1ham9yPC9jb21tZW50PiByZWxlYXNlIGF2YWlsYWJsZSAtIHVwZGF0ZSBwb3NzaWJsZScpOwogICAgICAgICAgICAgICAgICAgIGlmICghJGlucHV0LT5nZXRPcHRpb24oJ291dGRhdGVkJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCctIDxpbmZvPnVwIHRvIGRhdGU8L2luZm8+IHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR3aWR0aCA9ICR0aGlzLT5nZXRUZXJtaW5hbFdpZHRoKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkdmlld0RhdGEgYXMgJHR5cGUgPT4gJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAkbmFtZUxlbmd0aCA9ICR2aWV3TWV0YURhdGFbJHR5cGVdWyduYW1lTGVuZ3RoJ107CiAgICAgICAgICAgICAgICAkdmVyc2lvbkxlbmd0aCA9ICR2aWV3TWV0YURhdGFbJHR5cGVdWyd2ZXJzaW9uTGVuZ3RoJ107CiAgICAgICAgICAgICAgICAkbGF0ZXN0TGVuZ3RoID0gJHZpZXdNZXRhRGF0YVskdHlwZV1bJ2xhdGVzdExlbmd0aCddOwoKICAgICAgICAgICAgICAgICR3cml0ZVZlcnNpb24gPSAkbmFtZUxlbmd0aCArICR2ZXJzaW9uTGVuZ3RoICsgMyA8PSAkd2lkdGg7CiAgICAgICAgICAgICAgICAkd3JpdGVMYXRlc3QgPSAkbmFtZUxlbmd0aCArICR2ZXJzaW9uTGVuZ3RoICsgJGxhdGVzdExlbmd0aCArIDMgPD0gJHdpZHRoOwogICAgICAgICAgICAgICAgJHdyaXRlRGVzY3JpcHRpb24gPSAkbmFtZUxlbmd0aCArICR2ZXJzaW9uTGVuZ3RoICsgJGxhdGVzdExlbmd0aCArIDI0IDw9ICR3aWR0aDsKCiAgICAgICAgICAgICAgICBpZiAoJHdyaXRlTGF0ZXN0ICYmICEkaW8tPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0TGVuZ3RoICs9IDI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRzaG93QWxsVHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJ2F2YWlsYWJsZScgPT09ICR0eXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxjb21tZW50PicgLiAkdHlwZSAuICc8L2NvbW1lbnQ+OicpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxpbmZvPicgLiAkdHlwZSAuICc8L2luZm8+OicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRpbmRlbnQgLiBzdHJfcGFkKCRwYWNrYWdlWyduYW1lJ10sICRuYW1lTGVuZ3RoLCAnICcpLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlWyd2ZXJzaW9uJ10pICYmICR3cml0ZVZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnICcgLiBzdHJfcGFkKCRwYWNrYWdlWyd2ZXJzaW9uJ10sICR2ZXJzaW9uTGVuZ3RoLCAnICcpLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZVsnbGF0ZXN0J10pICYmICR3cml0ZUxhdGVzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0VmVyc2lvbiA9ICRwYWNrYWdlWydsYXRlc3QnXTsKICAgICAgICAgICAgICAgICAgICAgICAgJHVwZGF0ZVN0YXR1cyA9ICRwYWNrYWdlWydsYXRlc3Qtc3RhdHVzJ107CiAgICAgICAgICAgICAgICAgICAgICAgICRzdHlsZSA9ICR0aGlzLT51cGRhdGVTdGF0dXNUb1ZlcnNpb25TdHlsZSgkdXBkYXRlU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkaW8tPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsYXRlc3RWZXJzaW9uID0gc3RyX3JlcGxhY2UoYXJyYXkoJ3VwLXRvLWRhdGUnLCAnc2VtdmVyLXNhZmUtdXBkYXRlJywgJ3VwZGF0ZS1wb3NzaWJsZScpLCBhcnJheSgnPScsICchJywgJ34nKSwgJHVwZGF0ZVN0YXR1cykgLiAnICcgLiAkbGF0ZXN0VmVyc2lvbjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcgPCcgLiAkc3R5bGUgLiAnPicgLiBzdHJfcGFkKCRsYXRlc3RWZXJzaW9uLCAkbGF0ZXN0TGVuZ3RoLCAnICcpIC4gJzwvJyAuICRzdHlsZSAuICc+JywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ2Rlc2NyaXB0aW9uJ10pICYmICR3cml0ZURlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiA9IHN0cnRvaygkcGFja2FnZVsnZGVzY3JpcHRpb24nXSwgIlxyXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlbWFpbmluZyA9ICR3aWR0aCAtICRuYW1lTGVuZ3RoIC0gJHZlcnNpb25MZW5ndGggLSA0OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHdyaXRlTGF0ZXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVtYWluaW5nIC09ICRsYXRlc3RMZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkZGVzY3JpcHRpb24pID4gJHJlbWFpbmluZykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gc3Vic3RyKCRkZXNjcmlwdGlvbiwgMCwgJHJlbWFpbmluZyAtIDMpIC4gJy4uLic7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnICcgLiAkZGVzY3JpcHRpb24sIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlWydwYXRoJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJyAnIC4gJHBhY2thZ2VbJ3BhdGgnXSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcnKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ3dhcm5pbmcnXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPHdhcm5pbmc+JyAuICRwYWNrYWdlWyd3YXJuaW5nJ10gLiAnPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHNob3dBbGxUeXBlcykgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJycpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGV4aXRDb2RlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Um9vdFJlcXVpcmVzKCkKICAgIHsKICAgICAgICAkcm9vdFBhY2thZ2UgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0UGFja2FnZSgpOwoKICAgICAgICByZXR1cm4gYXJyYXlfbWFwKAogICAgICAgICAgICAnc3RydG9sb3dlcicsCiAgICAgICAgICAgIGFycmF5X2tleXMoYXJyYXlfbWVyZ2UoJHJvb3RQYWNrYWdlLT5nZXRSZXF1aXJlcygpLCAkcm9vdFBhY2thZ2UtPmdldERldlJlcXVpcmVzKCkpKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5fHN0cmluZ3xzdHJpbmdbXQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0VmVyc2lvblN0eWxlKFBhY2thZ2VJbnRlcmZhY2UgJGxhdGVzdFBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cGRhdGVTdGF0dXNUb1ZlcnNpb25TdHlsZSgkdGhpcy0+Z2V0VXBkYXRlU3RhdHVzKCRsYXRlc3RQYWNrYWdlLCAkcGFja2FnZSkpOwogICAgfQoKICAgIC8qKgogICAgICogZmluZHMgYSBwYWNrYWdlIGJ5IG5hbWUgYW5kIHZlcnNpb24gaWYgcHJvdmlkZWQKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICRuYW1lCiAgICAgKiBAcGFyYW0gIENvbnN0cmFpbnRJbnRlcmZhY2V8c3RyaW5nICR2ZXJzaW9uCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYXJyYXl7Q29tcGxldGVQYWNrYWdlSW50ZXJmYWNlfG51bGwsIGFycmF5PHN0cmluZywgc3RyaW5nPn0KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBhY2thZ2UoSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywgUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3MsICRuYW1lLCAkdmVyc2lvbiA9IG51bGwpCiAgICB7CiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKICAgICAgICAkY29uc3RyYWludCA9IGlzX3N0cmluZygkdmVyc2lvbikgPyAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkdmVyc2lvbikgOiAkdmVyc2lvbjsKCiAgICAgICAgJHBvbGljeSA9IG5ldyBEZWZhdWx0UG9saWN5KCk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQgPSBuZXcgUmVwb3NpdG9yeVNldCgnZGV2Jyk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFsbG93SW5zdGFsbGVkUmVwb3NpdG9yaWVzKCk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkoJHJlcG9zKTsKCiAgICAgICAgJG1hdGNoZWRQYWNrYWdlID0gbnVsbDsKICAgICAgICAkdmVyc2lvbnMgPSBhcnJheSgpOwogICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSkgewogICAgICAgICAgICAkcG9vbCA9ICRyZXBvc2l0b3J5U2V0LT5jcmVhdGVQb29sV2l0aEFsbFBhY2thZ2VzKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBvb2wgPSAkcmVwb3NpdG9yeVNldC0+Y3JlYXRlUG9vbEZvclBhY2thZ2UoJG5hbWUpOwogICAgICAgIH0KICAgICAgICAkbWF0Y2hlcyA9ICRwb29sLT53aGF0UHJvdmlkZXMoJG5hbWUsICRjb25zdHJhaW50KTsKICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgLy8gYXZvaWQgc2hvd2luZyB0aGUgOTk5OTk5OS1kZXYgYWxpYXMgaWYgdGhlIGRlZmF1bHQgYnJhbmNoIGhhcyBubyBicmFuY2gtYWxpYXMgc2V0CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+Z2V0VmVyc2lvbigpID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBzZWxlY3QgYW4gZXhhY3QgbWF0Y2ggaWYgaXQgaXMgaW4gdGhlIGluc3RhbGxlZCByZXBvIGFuZCBubyBzcGVjaWZpYyB2ZXJzaW9uIHdhcyByZXF1aXJlZAogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZlcnNpb24gJiYgJGluc3RhbGxlZFJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlZFBhY2thZ2UgPSAkcGFja2FnZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZlcnNpb25zWyRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCldID0gJHBhY2thZ2UtPmdldFZlcnNpb24oKTsKICAgICAgICAgICAgJG1hdGNoZXNbJGluZGV4XSA9ICRwYWNrYWdlLT5nZXRJZCgpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2VsZWN0IHByZWZlcnJlZCBwYWNrYWdlIGFjY29yZGluZyB0byBwb2xpY3kgcnVsZXMKICAgICAgICBpZiAoISRtYXRjaGVkUGFja2FnZSAmJiAkbWF0Y2hlcyAmJiAkcHJlZmVycmVkID0gJHBvbGljeS0+c2VsZWN0UHJlZmVycmVkUGFja2FnZXMoJHBvb2wsICRtYXRjaGVzKSkgewogICAgICAgICAgICAkbWF0Y2hlZFBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkcHJlZmVycmVkWzBdKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgkbWF0Y2hlZFBhY2thZ2UsICR2ZXJzaW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmludHMgcGFja2FnZSBpbmZvLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gICAgJHZlcnNpb25zCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZXxudWxsICAgICRsYXRlc3RQYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFBhY2thZ2VJbmZvKENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgYXJyYXkgJHZlcnNpb25zLCBJbnN0YWxsZWRSZXBvc2l0b3J5ICRpbnN0YWxsZWRSZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRsYXRlc3RQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgJHRoaXMtPnByaW50TWV0YSgkcGFja2FnZSwgJHZlcnNpb25zLCAkaW5zdGFsbGVkUmVwbywgJGxhdGVzdFBhY2thZ2UgPzogbnVsbCk7CiAgICAgICAgJHRoaXMtPnByaW50TGlua3MoJHBhY2thZ2UsIExpbms6OlRZUEVfUkVRVUlSRSk7CiAgICAgICAgJHRoaXMtPnByaW50TGlua3MoJHBhY2thZ2UsIExpbms6OlRZUEVfREVWX1JFUVVJUkUsICdyZXF1aXJlcyAoZGV2KScpOwoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFN1Z2dlc3RzKCkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgiXG48aW5mbz5zdWdnZXN0czwvaW5mbz4iKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFN1Z2dlc3RzKCkgYXMgJHN1Z2dlc3RlZCA9PiAkcmVhc29uKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRzdWdnZXN0ZWQgLiAnIDxjb21tZW50PicgLiAkcmVhc29uIC4gJzwvY29tbWVudD4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnByaW50TGlua3MoJHBhY2thZ2UsIExpbms6OlRZUEVfUFJPVklERSk7CiAgICAgICAgJHRoaXMtPnByaW50TGlua3MoJHBhY2thZ2UsIExpbms6OlRZUEVfQ09ORkxJQ1QpOwogICAgICAgICR0aGlzLT5wcmludExpbmtzKCRwYWNrYWdlLCBMaW5rOjpUWVBFX1JFUExBQ0UpOwogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIHBhY2thZ2UgbWV0YWRhdGEuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAgICAkdmVyc2lvbnMKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlfG51bGwgICAgJGxhdGVzdFBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByaW50TWV0YShDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIGFycmF5ICR2ZXJzaW9ucywgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywgUGFja2FnZUludGVyZmFjZSAkbGF0ZXN0UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+bmFtZTwvaW5mbz4gICAgIDogJyAuICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkpOwogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPmRlc2NyaXAuPC9pbmZvPiA6ICcgLiAkcGFja2FnZS0+Z2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+a2V5d29yZHM8L2luZm8+IDogJyAuIGltcGxvZGUoJywgJywgJHBhY2thZ2UtPmdldEtleXdvcmRzKCkgPzogYXJyYXkoKSkpOwogICAgICAgICR0aGlzLT5wcmludFZlcnNpb25zKCRwYWNrYWdlLCAkdmVyc2lvbnMsICRpbnN0YWxsZWRSZXBvKTsKICAgICAgICBpZiAoJGxhdGVzdFBhY2thZ2UpIHsKICAgICAgICAgICAgJHN0eWxlID0gJHRoaXMtPmdldFZlcnNpb25TdHlsZSgkbGF0ZXN0UGFja2FnZSwgJHBhY2thZ2UpOwogICAgICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz5sYXRlc3Q8L2luZm8+ICAgOiA8Jy4kc3R5bGUuJz4nIC4gJGxhdGVzdFBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSAuICc8LycuJHN0eWxlLic+Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGxhdGVzdFBhY2thZ2UgPSAkcGFja2FnZTsKICAgICAgICB9CiAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+dHlwZTwvaW5mbz4gICAgIDogJyAuICRwYWNrYWdlLT5nZXRUeXBlKCkpOwogICAgICAgICR0aGlzLT5wcmludExpY2Vuc2VzKCRwYWNrYWdlKTsKICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz5ob21lcGFnZTwvaW5mbz4gOiAnIC4gJHBhY2thZ2UtPmdldEhvbWVwYWdlKCkpOwogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPnNvdXJjZTwvaW5mbz4gICA6ICcgLiBzcHJpbnRmKCdbJXNdIDxjb21tZW50PiVzPC9jb21tZW50PiAlcycsICRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCksICRwYWNrYWdlLT5nZXRTb3VyY2VVcmwoKSwgJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSk7CiAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+ZGlzdDwvaW5mbz4gICAgIDogJyAuIHNwcmludGYoJ1slc10gPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+ICVzJywgJHBhY2thZ2UtPmdldERpc3RUeXBlKCksICRwYWNrYWdlLT5nZXREaXN0VXJsKCksICRwYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkpKTsKICAgICAgICBpZiAoJGluc3RhbGxlZFJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJzxpbmZvPnBhdGg8L2luZm8+ICAgICA6ICcgLiBzcHJpbnRmKCclcycsIHJlYWxwYXRoKCR0aGlzLT5nZXRDb21wb3NlcigpLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKSkpKTsKICAgICAgICB9CiAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+bmFtZXM8L2luZm8+ICAgIDogJyAuIGltcGxvZGUoJywgJywgJHBhY2thZ2UtPmdldE5hbWVzKCkpKTsKCiAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICRsYXRlc3RQYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICRyZXBsYWNlbWVudCA9ICgkbGF0ZXN0UGFja2FnZS0+Z2V0UmVwbGFjZW1lbnRQYWNrYWdlKCkgIT09IG51bGwpCiAgICAgICAgICAgICAgICA/ICcgVGhlIGF1dGhvciBzdWdnZXN0cyB1c2luZyB0aGUgJyAuICRsYXRlc3RQYWNrYWdlLT5nZXRSZXBsYWNlbWVudFBhY2thZ2UoKS4gJyBwYWNrYWdlIGluc3RlYWQuJwogICAgICAgICAgICAgICAgOiBudWxsOwoKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKAogICAgICAgICAgICAgICAgc3ByaW50ZignPHdhcm5pbmc+QXR0ZW50aW9uOiBUaGlzIHBhY2thZ2UgaXMgYWJhbmRvbmVkIGFuZCBubyBsb25nZXIgbWFpbnRhaW5lZC4lczwvd2FybmluZz4nLCAkcmVwbGFjZW1lbnQpCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFN1cHBvcnQoKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCJcbjxpbmZvPnN1cHBvcnQ8L2luZm8+Iik7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRTdXBwb3J0KCkgYXMgJHR5cGUgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8Y29tbWVudD4nIC4gJHR5cGUgLiAnPC9jb21tZW50PiA6ICcuJHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRBdXRvbG9hZCgpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoIlxuPGluZm8+YXV0b2xvYWQ8L2luZm8+Iik7CiAgICAgICAgICAgICRhdXRvbG9hZENvbmZpZyA9ICRwYWNrYWdlLT5nZXRBdXRvbG9hZCgpOwogICAgICAgICAgICBmb3JlYWNoICgkYXV0b2xvYWRDb25maWcgYXMgJHR5cGUgPT4gJGF1dG9sb2FkcykgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGNvbW1lbnQ+JyAuICR0eXBlIC4gJzwvY29tbWVudD4nKTsKCiAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdwc3ItMCcgfHwgJHR5cGUgPT09ICdwc3ItNCcpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkYXV0b2xvYWRzIGFzICRuYW1lID0+ICRwYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoKCRuYW1lID86ICcqJykgLiAnID0+ICcgLiAoaXNfYXJyYXkoJHBhdGgpID8gaW1wbG9kZSgnLCAnLCAkcGF0aCkgOiAoJHBhdGggPzogJy4nKSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkdHlwZSA9PT0gJ2NsYXNzbWFwJykgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoaW1wbG9kZSgnLCAnLCAkYXV0b2xvYWRDb25maWdbJHR5cGVdKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRJbmNsdWRlUGF0aHMoKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGNvbW1lbnQ+aW5jbHVkZS1wYXRoPC9jb21tZW50PicpOwogICAgICAgICAgICAgICAgJGlvLT53cml0ZShpbXBsb2RlKCcsICcsICRwYWNrYWdlLT5nZXRJbmNsdWRlUGF0aHMoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIGFsbCBhdmFpbGFibGUgdmVyc2lvbnMgb2YgdGhpcyBwYWNrYWdlIGFuZCBoaWdobGlnaHRzIHRoZSBpbnN0YWxsZWQgb25lIGlmIGFueS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICR2ZXJzaW9ucwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJpbnRWZXJzaW9ucyhDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIGFycmF5ICR2ZXJzaW9ucywgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbykKICAgIHsKICAgICAgICAkdmVyc2lvbnMgPSBhcnJheV9rZXlzKCR2ZXJzaW9ucyk7CiAgICAgICAgJHZlcnNpb25zID0gU2VtdmVyOjpyc29ydCgkdmVyc2lvbnMpOwoKICAgICAgICAvLyBoaWdobGlnaHQgaW5zdGFsbGVkIHZlcnNpb24KICAgICAgICBpZiAoJGluc3RhbGxlZFBhY2thZ2VzID0gJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlcygkcGFja2FnZS0+Z2V0TmFtZSgpKSkgewogICAgICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkUGFja2FnZXMgYXMgJGluc3RhbGxlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRpbnN0YWxsZWRWZXJzaW9uID0gJGluc3RhbGxlZFBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgICRrZXkgPSBhcnJheV9zZWFyY2goJGluc3RhbGxlZFZlcnNpb24sICR2ZXJzaW9ucyk7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRrZXkpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNbJGtleV0gPSAnPGluZm8+KiAnIC4gJGluc3RhbGxlZFZlcnNpb24gLiAnPC9pbmZvPic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR2ZXJzaW9ucyA9IGltcGxvZGUoJywgJywgJHZlcnNpb25zKTsKCiAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKCc8aW5mbz52ZXJzaW9uczwvaW5mbz4gOiAnIC4gJHZlcnNpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIHByaW50IGxpbmsgb2JqZWN0cwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgJGxpbmtUeXBlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICR0aXRsZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJpbnRMaW5rcyhDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRsaW5rVHlwZSwgJHRpdGxlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGl0bGUgPSAkdGl0bGUgPzogJGxpbmtUeXBlOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGlmICgkbGlua3MgPSAkcGFja2FnZS0+eydnZXQnLnVjZmlyc3QoJGxpbmtUeXBlKX0oKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCJcbjxpbmZvPiIgLiAkdGl0bGUgLiAiPC9pbmZvPiIpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRsaW5rLT5nZXRUYXJnZXQoKSAuICcgPGNvbW1lbnQ+JyAuICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkgLiAnPC9jb21tZW50PicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIHRoZSBsaWNlbnNlcyBvZiBhIHBhY2thZ2Ugd2l0aCBtZXRhZGF0YQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJpbnRMaWNlbnNlcyhDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHNwZHhMaWNlbnNlcyA9IG5ldyBTcGR4TGljZW5zZXMoKTsKCiAgICAgICAgJGxpY2Vuc2VzID0gJHBhY2thZ2UtPmdldExpY2Vuc2UoKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgZm9yZWFjaCAoJGxpY2Vuc2VzIGFzICRsaWNlbnNlSWQpIHsKICAgICAgICAgICAgJGxpY2Vuc2UgPSAkc3BkeExpY2Vuc2VzLT5nZXRMaWNlbnNlQnlJZGVudGlmaWVyKCRsaWNlbnNlSWQpOyAvLyBrZXlzOiAwIGZ1bGxuYW1lLCAxIG9zaSwgMiB1cmwKCiAgICAgICAgICAgIGlmICghJGxpY2Vuc2UpIHsKICAgICAgICAgICAgICAgICRvdXQgPSAkbGljZW5zZUlkOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gaXMgbGljZW5zZSBPU0kgYXBwcm92ZWQ/CiAgICAgICAgICAgICAgICBpZiAoJGxpY2Vuc2VbMV0gPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkb3V0ID0gc3ByaW50ZignJXMgKCVzKSAoT1NJIGFwcHJvdmVkKSAlcycsICRsaWNlbnNlWzBdLCAkbGljZW5zZUlkLCAkbGljZW5zZVsyXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRvdXQgPSBzcHJpbnRmKCclcyAoJXMpICVzJywgJGxpY2Vuc2VbMF0sICRsaWNlbnNlSWQsICRsaWNlbnNlWzJdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+bGljZW5zZTwvaW5mbz4gIDogJyAuICRvdXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByaW50cyBwYWNrYWdlIGluZm8gaW4gSlNPTiBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAgICAkdmVyc2lvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByaW50UGFja2FnZUluZm9Bc0pzb24oQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBhcnJheSAkdmVyc2lvbnMsIEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGxhdGVzdFBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICRqc29uID0gYXJyYXkoCiAgICAgICAgICAgICduYW1lJyA9PiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLAogICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+ICRwYWNrYWdlLT5nZXREZXNjcmlwdGlvbigpLAogICAgICAgICAgICAna2V5d29yZHMnID0+ICRwYWNrYWdlLT5nZXRLZXl3b3JkcygpID86IGFycmF5KCksCiAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0VHlwZSgpLAogICAgICAgICAgICAnaG9tZXBhZ2UnID0+ICRwYWNrYWdlLT5nZXRIb21lcGFnZSgpLAogICAgICAgICAgICAnbmFtZXMnID0+ICRwYWNrYWdlLT5nZXROYW1lcygpLAogICAgICAgICk7CgogICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZFZlcnNpb25zKCRqc29uLCAkdmVyc2lvbnMpOwogICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZExpY2Vuc2VzKCRqc29uLCAkcGFja2FnZSk7CgogICAgICAgIGlmICgkbGF0ZXN0UGFja2FnZSkgewogICAgICAgICAgICAkanNvblsnbGF0ZXN0J10gPSAkbGF0ZXN0UGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gJHBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFNvdXJjZVR5cGUoKSkgewogICAgICAgICAgICAkanNvblsnc291cmNlJ10gPSBhcnJheSgKICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpLAogICAgICAgICAgICAgICAgJ3VybCcgPT4gJHBhY2thZ2UtPmdldFNvdXJjZVVybCgpLAogICAgICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXREaXN0VHlwZSgpKSB7CiAgICAgICAgICAgICRqc29uWydkaXN0J10gPSBhcnJheSgKICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0RGlzdFR5cGUoKSwKICAgICAgICAgICAgICAgICd1cmwnID0+ICRwYWNrYWdlLT5nZXREaXN0VXJsKCksCiAgICAgICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnN0YWxsZWRSZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAkanNvblsncGF0aCddID0gcmVhbHBhdGgoJHRoaXMtPmdldENvbXBvc2VyKCktPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpKTsKICAgICAgICAgICAgaWYgKCRqc29uWydwYXRoJ10gPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkanNvblsncGF0aCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICRsYXRlc3RQYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICRqc29uWydyZXBsYWNlbWVudCddID0gJGxhdGVzdFBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRTdWdnZXN0cygpKSB7CiAgICAgICAgICAgICRqc29uWydzdWdnZXN0cyddID0gJHBhY2thZ2UtPmdldFN1Z2dlc3RzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFN1cHBvcnQoKSkgewogICAgICAgICAgICAkanNvblsnc3VwcG9ydCddID0gJHBhY2thZ2UtPmdldFN1cHBvcnQoKTsKICAgICAgICB9CgogICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZEF1dG9sb2FkKCRqc29uLCAkcGFja2FnZSk7CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0SW5jbHVkZVBhdGhzKCkpIHsKICAgICAgICAgICAgJGpzb25bJ2luY2x1ZGVfcGF0aCddID0gJHBhY2thZ2UtPmdldEluY2x1ZGVQYXRocygpOwogICAgICAgIH0KCiAgICAgICAgJGpzb24gPSAkdGhpcy0+YXBwZW5kTGlua3MoJGpzb24sICRwYWNrYWdlKTsKCiAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKEpzb25GaWxlOjplbmNvZGUoJGpzb24pKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXXxudWxsPiAkanNvbgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkdmVyc2lvbnMKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW118bnVsbD4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhcHBlbmRWZXJzaW9ucygkanNvbiwgYXJyYXkgJHZlcnNpb25zKQogICAgewogICAgICAgIHVhc29ydCgkdmVyc2lvbnMsICd2ZXJzaW9uX2NvbXBhcmUnKTsKICAgICAgICAkdmVyc2lvbnMgPSBhcnJheV9rZXlzKGFycmF5X3JldmVyc2UoJHZlcnNpb25zKSk7CiAgICAgICAgJGpzb25bJ3ZlcnNpb25zJ10gPSAkdmVyc2lvbnM7CgogICAgICAgIHJldHVybiAkanNvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXXxudWxsPiAkanNvbgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXXxudWxsPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFwcGVuZExpY2Vuc2VzKCRqc29uLCBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCRsaWNlbnNlcyA9ICRwYWNrYWdlLT5nZXRMaWNlbnNlKCkpIHsKICAgICAgICAgICAgJHNwZHhMaWNlbnNlcyA9IG5ldyBTcGR4TGljZW5zZXMoKTsKCiAgICAgICAgICAgICRqc29uWydsaWNlbnNlcyddID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkbGljZW5zZUlkKSB1c2UgKCRzcGR4TGljZW5zZXMpIHsKICAgICAgICAgICAgICAgICRsaWNlbnNlID0gJHNwZHhMaWNlbnNlcy0+Z2V0TGljZW5zZUJ5SWRlbnRpZmllcigkbGljZW5zZUlkKTsgLy8ga2V5czogMCBmdWxsbmFtZSwgMSBvc2ksIDIgdXJsCgogICAgICAgICAgICAgICAgaWYgKCEkbGljZW5zZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkbGljZW5zZUlkOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gJGxpY2Vuc2VbMF0sCiAgICAgICAgICAgICAgICAgICAgJ29zaScgPT4gJGxpY2Vuc2VJZCwKICAgICAgICAgICAgICAgICAgICAndXJsJyA9PiAkbGljZW5zZVsyXSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0sICRsaWNlbnNlcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGpzb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW118bnVsbD4gJGpzb24KICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW118bnVsbD4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhcHBlbmRBdXRvbG9hZCgkanNvbiwgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QXV0b2xvYWQoKSkgewogICAgICAgICAgICAkYXV0b2xvYWQgPSBhcnJheSgpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldEF1dG9sb2FkKCkgYXMgJHR5cGUgPT4gJGF1dG9sb2FkcykgewogICAgICAgICAgICAgICAgaWYgKCR0eXBlID09PSAncHNyLTAnIHx8ICR0eXBlID09PSAncHNyLTQnKSB7CiAgICAgICAgICAgICAgICAgICAgJHBzciA9IGFycmF5KCk7CgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHMgYXMgJG5hbWUgPT4gJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkcGF0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGggPSAnLic7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRwc3JbJG5hbWUgPzogJyonXSA9ICRwYXRoOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGF1dG9sb2FkWyR0eXBlXSA9ICRwc3I7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPT09ICdjbGFzc21hcCcpIHsKICAgICAgICAgICAgICAgICAgICAkYXV0b2xvYWRbJ2NsYXNzbWFwJ10gPSAkYXV0b2xvYWRzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkanNvblsnYXV0b2xvYWQnXSA9ICRhdXRvbG9hZDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkanNvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXXxudWxsPiAkanNvbgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXXxudWxsPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFwcGVuZExpbmtzKCRqc29uLCBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoTGluazo6JFRZUEVTIGFzICRsaW5rVHlwZSkgewogICAgICAgICAgICAkanNvbiA9ICR0aGlzLT5hcHBlbmRMaW5rKCRqc29uLCAkcGFja2FnZSwgJGxpbmtUeXBlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkanNvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXXxudWxsPiAkanNvbgogICAgICogQHBhcmFtIHN0cmluZyAkbGlua1R5cGUKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW118bnVsbD4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhcHBlbmRMaW5rKCRqc29uLCBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRsaW5rVHlwZSkKICAgIHsKICAgICAgICAkbGlua3MgPSAkcGFja2FnZS0+eydnZXQnIC4gdWNmaXJzdCgkbGlua1R5cGUpfSgpOwoKICAgICAgICBpZiAoJGxpbmtzKSB7CiAgICAgICAgICAgICRqc29uWyRsaW5rVHlwZV0gPSBhcnJheSgpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkanNvblskbGlua1R5cGVdWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGpzb247CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0IHN0eWxlcyBmb3IgdHJlZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdFN0eWxlcyhPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29sb3JzID0gYXJyYXkoCiAgICAgICAgICAgICdncmVlbicsCiAgICAgICAgICAgICd5ZWxsb3cnLAogICAgICAgICAgICAnY3lhbicsCiAgICAgICAgICAgICdtYWdlbnRhJywKICAgICAgICAgICAgJ2JsdWUnLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb2xvcnMgYXMgJGNvbG9yKSB7CiAgICAgICAgICAgICRzdHlsZSA9IG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgkY29sb3IpOwogICAgICAgICAgICAkb3V0cHV0LT5nZXRGb3JtYXR0ZXIoKS0+c2V0U3R5bGUoJGNvbG9yLCAkc3R5bGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERpc3BsYXkgdGhlIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIHN0cmluZ3xtaXhlZFtdPj4gJGFycmF5VHJlZQogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkaXNwbGF5UGFja2FnZVRyZWUoYXJyYXkgJGFycmF5VHJlZSkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICBmb3JlYWNoICgkYXJyYXlUcmVlIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoc3ByaW50ZignPGluZm8+JXM8L2luZm8+JywgJHBhY2thZ2VbJ25hbWUnXSksIGZhbHNlKTsKICAgICAgICAgICAgJGlvLT53cml0ZSgnICcgLiAkcGFja2FnZVsndmVyc2lvbiddLCBmYWxzZSk7CiAgICAgICAgICAgICRpby0+d3JpdGUoJyAnIC4gc3RydG9rKCRwYWNrYWdlWydkZXNjcmlwdGlvbiddLCAiXHJcbiIpKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZVsncmVxdWlyZXMnXSkpIHsKICAgICAgICAgICAgICAgICRyZXF1aXJlcyA9ICRwYWNrYWdlWydyZXF1aXJlcyddOwogICAgICAgICAgICAgICAgJHRyZWVCYXIgPSAn4pScJzsKICAgICAgICAgICAgICAgICRqID0gMDsKICAgICAgICAgICAgICAgICR0b3RhbCA9IGNvdW50KCRyZXF1aXJlcyk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZU5hbWUgPSAkcmVxdWlyZVsnbmFtZSddOwogICAgICAgICAgICAgICAgICAgICRqKys7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRqID09PSAkdG90YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRyZWVCYXIgPSAn4pSUJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGxldmVsID0gMTsKICAgICAgICAgICAgICAgICAgICAkY29sb3IgPSAkdGhpcy0+Y29sb3JzWyRsZXZlbF07CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAnJXPilIDilIA8JXM+JXM8LyVzPiAlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICR0cmVlQmFyLAogICAgICAgICAgICAgICAgICAgICAgICAkY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICRyZXF1aXJlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbG9yLAogICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZVsndmVyc2lvbiddCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUcmVlTGluZSgkaW5mbyk7CgogICAgICAgICAgICAgICAgICAgICR0cmVlQmFyID0gc3RyX3JlcGxhY2UoJ+KUlCcsICcgJywgJHRyZWVCYXIpOwogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZSA9IGFycmF5KCRwYWNrYWdlWyduYW1lJ10sICRyZXF1aXJlTmFtZSk7CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kaXNwbGF5VHJlZSgkcmVxdWlyZSwgJHBhY2thZ2VzSW5UcmVlLCAkdHJlZUJhciwgJGxldmVsICsgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSB0aGUgcGFja2FnZSB0cmVlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIGFycmF5PGludCwgYXJyYXk8c3RyaW5nLCBtaXhlZFtdfHN0cmluZz4+fHN0cmluZ3xudWxsPgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2VuZXJhdGVQYWNrYWdlVHJlZSgKICAgICAgICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLAogICAgICAgIEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8sCiAgICAgICAgUmVwb3NpdG9yeUludGVyZmFjZSAkcmVtb3RlUmVwb3MKICAgICkgewogICAgICAgICRyZXF1aXJlcyA9ICRwYWNrYWdlLT5nZXRSZXF1aXJlcygpOwogICAgICAgIGtzb3J0KCRyZXF1aXJlcyk7CiAgICAgICAgJGNoaWxkcmVuID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmVOYW1lID0+ICRyZXF1aXJlKSB7CiAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZSA9IGFycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRyZXF1aXJlTmFtZSk7CgogICAgICAgICAgICAkdHJlZUNoaWxkRGVzYyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ25hbWUnID0+ICRyZXF1aXJlTmFtZSwKICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcmVxdWlyZS0+Z2V0UHJldHR5Q29uc3RyYWludCgpLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJGRlZXBDaGlsZHJlbiA9ICR0aGlzLT5hZGRUcmVlKCRyZXF1aXJlTmFtZSwgJHJlcXVpcmUsICRpbnN0YWxsZWRSZXBvLCAkcmVtb3RlUmVwb3MsICRwYWNrYWdlc0luVHJlZSk7CgogICAgICAgICAgICBpZiAoJGRlZXBDaGlsZHJlbikgewogICAgICAgICAgICAgICAgJHRyZWVDaGlsZERlc2NbJ3JlcXVpcmVzJ10gPSAkZGVlcENoaWxkcmVuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2hpbGRyZW5bXSA9ICR0cmVlQ2hpbGREZXNjOwogICAgICAgIH0KICAgICAgICAkdHJlZSA9IGFycmF5KAogICAgICAgICAgICAnbmFtZScgPT4gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgPyAkcGFja2FnZS0+Z2V0RGVzY3JpcHRpb24oKSA6ICcnLAogICAgICAgICk7CgogICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgJHRyZWVbJ3JlcXVpcmVzJ10gPSAkY2hpbGRyZW47CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRyZWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwbGF5IGEgcGFja2FnZSB0cmVlCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIG1peGVkW118c3RyaW5nPj58c3RyaW5nfG51bGw+fHN0cmluZyAkcGFja2FnZQogICAgICogQHBhcmFtIGFycmF5PGludCwgc3RyaW5nfG1peGVkW10+ICRwYWNrYWdlc0luVHJlZQogICAgICogQHBhcmFtIHN0cmluZyAkcHJldmlvdXNUcmVlQmFyCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGlzcGxheVRyZWUoCiAgICAgICAgJHBhY2thZ2UsCiAgICAgICAgYXJyYXkgJHBhY2thZ2VzSW5UcmVlLAogICAgICAgICRwcmV2aW91c1RyZWVCYXIgPSAn4pScJywKICAgICAgICAkbGV2ZWwgPSAxCiAgICApIHsKICAgICAgICAkcHJldmlvdXNUcmVlQmFyID0gc3RyX3JlcGxhY2UoJ+KUnCcsICfilIInLCAkcHJldmlvdXNUcmVlQmFyKTsKICAgICAgICBpZiAoaXNfYXJyYXkoJHBhY2thZ2UpICYmIGlzc2V0KCRwYWNrYWdlWydyZXF1aXJlcyddKSkgewogICAgICAgICAgICAkcmVxdWlyZXMgPSAkcGFja2FnZVsncmVxdWlyZXMnXTsKICAgICAgICAgICAgJHRyZWVCYXIgPSAkcHJldmlvdXNUcmVlQmFyIC4gJyAg4pScJzsKICAgICAgICAgICAgJGkgPSAwOwogICAgICAgICAgICAkdG90YWwgPSBjb3VudCgkcmVxdWlyZXMpOwogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgICAgICRjdXJyZW50VHJlZSA9ICRwYWNrYWdlc0luVHJlZTsKICAgICAgICAgICAgICAgICRpKys7CiAgICAgICAgICAgICAgICBpZiAoJGkgPT09ICR0b3RhbCkgewogICAgICAgICAgICAgICAgICAgICR0cmVlQmFyID0gJHByZXZpb3VzVHJlZUJhciAuICcgIOKUlCc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29sb3JJZGVudCA9ICRsZXZlbCAlIGNvdW50KCR0aGlzLT5jb2xvcnMpOwogICAgICAgICAgICAgICAgJGNvbG9yID0gJHRoaXMtPmNvbG9yc1skY29sb3JJZGVudF07CgogICAgICAgICAgICAgICAgJGNpcmN1bGFyV2FybiA9IGluX2FycmF5KAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRUcmVlLAogICAgICAgICAgICAgICAgICAgIHRydWUKICAgICAgICAgICAgICAgICkgPyAnKGNpcmN1bGFyIGRlcGVuZGVuY3kgYWJvcnRlZCBoZXJlKScgOiAnJzsKICAgICAgICAgICAgICAgICRpbmZvID0gcnRyaW0oc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnJXPilIDilIA8JXM+JXM8LyVzPiAlcyAlcycsCiAgICAgICAgICAgICAgICAgICAgJHRyZWVCYXIsCiAgICAgICAgICAgICAgICAgICAgJGNvbG9yLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgJGNvbG9yLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyd2ZXJzaW9uJ10sCiAgICAgICAgICAgICAgICAgICAgJGNpcmN1bGFyV2FybgogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUcmVlTGluZSgkaW5mbyk7CgogICAgICAgICAgICAgICAgJHRyZWVCYXIgPSBzdHJfcmVwbGFjZSgn4pSUJywgJyAnLCAkdHJlZUJhcik7CgogICAgICAgICAgICAgICAgJGN1cnJlbnRUcmVlW10gPSAkcmVxdWlyZVsnbmFtZSddOwogICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXlUcmVlKCRyZXF1aXJlLCAkY3VycmVudFRyZWUsICR0cmVlQmFyLCAkbGV2ZWwgKyAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERpc3BsYXkgYSBwYWNrYWdlIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICRuYW1lCiAgICAgKiBAcGFyYW0gIHN0cmluZ1tdICRwYWNrYWdlc0luVHJlZQogICAgICogQHJldHVybiBhcnJheTxpbnQsIGFycmF5PHN0cmluZywgYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIHN0cmluZz4+fHN0cmluZz4+CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRUcmVlKAogICAgICAgICRuYW1lLAogICAgICAgIExpbmsgJGxpbmssCiAgICAgICAgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywKICAgICAgICBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZW1vdGVSZXBvcywKICAgICAgICBhcnJheSAkcGFja2FnZXNJblRyZWUKICAgICkgewogICAgICAgICRjaGlsZHJlbiA9IGFycmF5KCk7CiAgICAgICAgbGlzdCgkcGFja2FnZSkgPSAkdGhpcy0+Z2V0UGFja2FnZSgKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8sCiAgICAgICAgICAgICRyZW1vdGVSZXBvcywKICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkgPT09ICdzZWxmLnZlcnNpb24nID8gJGxpbmstPmdldENvbnN0cmFpbnQoKSA6ICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkKICAgICAgICApOwogICAgICAgIGlmIChpc19vYmplY3QoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICRyZXF1aXJlcyA9ICRwYWNrYWdlLT5nZXRSZXF1aXJlcygpOwogICAgICAgICAgICBrc29ydCgkcmVxdWlyZXMpOwogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmVOYW1lID0+ICRyZXF1aXJlKSB7CiAgICAgICAgICAgICAgICAkY3VycmVudFRyZWUgPSAkcGFja2FnZXNJblRyZWU7CgogICAgICAgICAgICAgICAgJHRyZWVDaGlsZERlc2MgPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gJHJlcXVpcmVOYW1lLAogICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcmVxdWlyZS0+Z2V0UHJldHR5Q29uc3RyYWludCgpLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCRyZXF1aXJlTmFtZSwgJGN1cnJlbnRUcmVlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICRjdXJyZW50VHJlZVtdID0gJHJlcXVpcmVOYW1lOwogICAgICAgICAgICAgICAgICAgICRkZWVwQ2hpbGRyZW4gPSAkdGhpcy0+YWRkVHJlZSgkcmVxdWlyZU5hbWUsICRyZXF1aXJlLCAkaW5zdGFsbGVkUmVwbywgJHJlbW90ZVJlcG9zLCAkY3VycmVudFRyZWUpOwogICAgICAgICAgICAgICAgICAgIGlmICgkZGVlcENoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0cmVlQ2hpbGREZXNjWydyZXF1aXJlcyddID0gJGRlZXBDaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGNoaWxkcmVuW10gPSAkdHJlZUNoaWxkRGVzYzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjaGlsZHJlbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVwZGF0ZVN0YXR1cwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1cGRhdGVTdGF0dXNUb1ZlcnNpb25TdHlsZSgkdXBkYXRlU3RhdHVzKQogICAgewogICAgICAgIC8vICd1cC10by1kYXRlJyBpcyBwcmludGVkIGdyZWVuCiAgICAgICAgLy8gJ3NlbXZlci1zYWZlLXVwZGF0ZScgaXMgcHJpbnRlZCByZWQKICAgICAgICAvLyAndXBkYXRlLXBvc3NpYmxlJyBpcyBwcmludGVkIHllbGxvdwogICAgICAgIHJldHVybiBzdHJfcmVwbGFjZShhcnJheSgndXAtdG8tZGF0ZScsICdzZW12ZXItc2FmZS11cGRhdGUnLCAndXBkYXRlLXBvc3NpYmxlJyksIGFycmF5KCdpbmZvJywgJ2hpZ2hsaWdodCcsICdjb21tZW50JyksICR1cGRhdGVTdGF0dXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRVcGRhdGVTdGF0dXMoUGFja2FnZUludGVyZmFjZSAkbGF0ZXN0UGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoJGxhdGVzdFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkgPT09ICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpKSB7CiAgICAgICAgICAgIHJldHVybiAndXAtdG8tZGF0ZSc7CiAgICAgICAgfQoKICAgICAgICAkY29uc3RyYWludCA9ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgaWYgKDAgIT09IHN0cnBvcygkY29uc3RyYWludCwgJ2Rldi0nKSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICdeJy4kY29uc3RyYWludDsKICAgICAgICB9CiAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlLT5nZXRWZXJzaW9uKCkgJiYgU2VtdmVyOjpzYXRpc2ZpZXMoJGxhdGVzdFBhY2thZ2UtPmdldFZlcnNpb24oKSwgJGNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgIC8vIGl0IG5lZWRzIGFuIGltbWVkaWF0ZSBzZW12ZXItY29tcGxpYW50IHVwZ3JhZGUKICAgICAgICAgICAgcmV0dXJuICdzZW12ZXItc2FmZS11cGRhdGUnOwogICAgICAgIH0KCiAgICAgICAgLy8gaXQgbmVlZHMgYW4gdXBncmFkZSBidXQgaGFzIHBvdGVudGlhbCBCQyBicmVha3Mgc28gaXMgbm90IHVyZ2VudAogICAgICAgIHJldHVybiAndXBkYXRlLXBvc3NpYmxlJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZVRyZWVMaW5lKCRsaW5lKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGlmICghJGlvLT5pc0RlY29yYXRlZCgpKSB7CiAgICAgICAgICAgICRsaW5lID0gc3RyX3JlcGxhY2UoYXJyYXkoJ+KUlCcsICfilJwnLCAn4pSA4pSAJywgJ+KUgicpLCBhcnJheSgnYC0nLCAnfC0nLCAnLScsICd8JyksICRsaW5lKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoJGxpbmUpOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZW4gYSBwYWNrYWdlLCB0aGlzIGZpbmRzIHRoZSBsYXRlc3QgcGFja2FnZSBtYXRjaGluZyBpdAogICAgICoKICAgICAqIEBwYXJhbSBib29sICRtaW5vck9ubHkKICAgICAqIEBwYXJhbSBib29sfHN0cmluZyAkaWdub3JlUGxhdGZvcm1SZXFzCiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlfGZhbHNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZExhdGVzdFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgQ29tcG9zZXIgJGNvbXBvc2VyLCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbywgJG1pbm9yT25seSA9IGZhbHNlLCAkaWdub3JlUGxhdGZvcm1SZXFzID0gZmFsc2UpCiAgICB7CiAgICAgICAgLy8gZmluZCB0aGUgbGF0ZXN0IHZlcnNpb24gYWxsb3dlZCBpbiB0aGlzIHJlcG8gc2V0CiAgICAgICAgJG5hbWUgPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICR2ZXJzaW9uU2VsZWN0b3IgPSBuZXcgVmVyc2lvblNlbGVjdG9yKCR0aGlzLT5nZXRSZXBvc2l0b3J5U2V0KCRjb21wb3NlciksICRwbGF0Zm9ybVJlcG8pOwogICAgICAgICRzdGFiaWxpdHkgPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0TWluaW11bVN0YWJpbGl0eSgpOwogICAgICAgICRmbGFncyA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRTdGFiaWxpdHlGbGFncygpOwogICAgICAgIGlmIChpc3NldCgkZmxhZ3NbJG5hbWVdKSkgewogICAgICAgICAgICAkc3RhYmlsaXR5ID0gYXJyYXlfc2VhcmNoKCRmbGFnc1skbmFtZV0sIEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgJGJlc3RTdGFiaWxpdHkgPSAkc3RhYmlsaXR5OwogICAgICAgIGlmICgkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0UHJlZmVyU3RhYmxlKCkpIHsKICAgICAgICAgICAgJGJlc3RTdGFiaWxpdHkgPSAkcGFja2FnZS0+Z2V0U3RhYmlsaXR5KCk7CiAgICAgICAgfQoKICAgICAgICAkdGFyZ2V0VmVyc2lvbiA9IG51bGw7CiAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkcGFja2FnZS0+Z2V0VmVyc2lvbigpLCAnZGV2LScpKSB7CiAgICAgICAgICAgICR0YXJnZXRWZXJzaW9uID0gJHBhY2thZ2UtPmdldFZlcnNpb24oKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGFyZ2V0VmVyc2lvbiA9PT0gbnVsbCAmJiAkbWlub3JPbmx5KSB7CiAgICAgICAgICAgICR0YXJnZXRWZXJzaW9uID0gJ14nIC4gJHBhY2thZ2UtPmdldFZlcnNpb24oKTsKICAgICAgICB9CgogICAgICAgICRjYW5kaWRhdGUgPSAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgJHRhcmdldFZlcnNpb24sICRiZXN0U3RhYmlsaXR5LCBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6ZnJvbUJvb2xPckxpc3QoJGlnbm9yZVBsYXRmb3JtUmVxcykpOwogICAgICAgIHdoaWxlICgkY2FuZGlkYXRlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRjYW5kaWRhdGUgPSAkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNhbmRpZGF0ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeVNldAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFJlcG9zaXRvcnlTZXQoQ29tcG9zZXIgJGNvbXBvc2VyKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnJlcG9zaXRvcnlTZXQpIHsKICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlTZXQgPSBuZXcgUmVwb3NpdG9yeVNldCgkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0TWluaW11bVN0YWJpbGl0eSgpLCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKSk7CiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0UmVwb3NpdG9yaWVzKCkpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb3NpdG9yeVNldDsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgcGFja2FnZSByZXF1aXJlcyBhbmQgY2hpbGQgcmVxdWlyZXMKICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5PFBhY2thZ2VJbnRlcmZhY2U+ICRidWNrZXQKICAgICAqIEByZXR1cm4gYXJyYXk8UGFja2FnZUludGVyZmFjZT4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaWx0ZXJSZXF1aXJlZFBhY2thZ2VzKFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRidWNrZXQgPSBhcnJheSgpKQogICAgewogICAgICAgICRyZXF1aXJlcyA9ICRwYWNrYWdlLT5nZXRSZXF1aXJlcygpOwoKICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjYW5kaWRhdGUtPmdldE5hbWVzKCkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcmVxdWlyZXNbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJGNhbmRpZGF0ZSwgJGJ1Y2tldCwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJ1Y2tldFtdID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGJ1Y2tldCA9ICR0aGlzLT5maWx0ZXJSZXF1aXJlZFBhY2thZ2VzKCRyZXBvLCAkY2FuZGlkYXRlLCAkYnVja2V0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkYnVja2V0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXENoYW5nZVJlcG9ydEludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcRHZjc0Rvd25sb2FkZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFZjc0NhcGFibGVEb3dubG9hZGVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxEdW1wZXJcQXJyYXlEdW1wZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvbkd1ZXNzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBsdWdpblxDb21tYW5kRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwoKLyoqCiAqIEBhdXRob3IgVGlhZ28gUmliZWlybyA8dGlhZ28ucmliZWlyb0BzZWVnbm8uY29tPgogKiBAYXV0aG9yIFJ1aSBNYXJpbmhvIDxydWkubWFyaW5ob0BzZWVnbm8uY29tPgogKi8KY2xhc3MgU3RhdHVzQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIGNvbnN0IEVYSVRfQ09ERV9FUlJPUlMgPSAxOwogICAgY29uc3QgRVhJVF9DT0RFX1VOUFVTSEVEX0NIQU5HRVMgPSAyOwogICAgY29uc3QgRVhJVF9DT0RFX1ZFUlNJT05fQ0hBTkdFUyA9IDQ7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIEB0aHJvd3MgXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3N0YXR1cycpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1Nob3dzIGEgbGlzdCBvZiBsb2NhbGx5IG1vZGlmaWVkIHBhY2thZ2VzLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndmVyYm9zZScsICd2fHZ2fHZ2dicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvdyBtb2RpZmllZCBmaWxlcyBmb3IgZWFjaCBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBjaGFuZ2VzLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIHN0YXR1cyBjb21tYW5kIGRpc3BsYXlzIGEgbGlzdCBvZiBkZXBlbmRlbmNpZXMgdGhhdCBoYXZlCmJlZW4gbW9kaWZpZWQgbG9jYWxseS4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3N0YXR1cwpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3N0YXR1cycsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgLy8gRGlzcGF0Y2ggcHJlLXN0YXR1cy1jb21tYW5kCiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2hTY3JpcHQoU2NyaXB0RXZlbnRzOjpQUkVfU1RBVFVTX0NNRCwgdHJ1ZSk7CgogICAgICAgICRleGl0Q29kZSA9ICR0aGlzLT5kb0V4ZWN1dGUoJGlucHV0KTsKCiAgICAgICAgLy8gRGlzcGF0Y2ggcG9zdC1zdGF0dXMtY29tbWFuZAogICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoU2NyaXB0KFNjcmlwdEV2ZW50czo6UE9TVF9TVEFUVVNfQ01ELCB0cnVlKTsKCiAgICAgICAgcmV0dXJuICRleGl0Q29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9FeGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCkKICAgIHsKICAgICAgICAvLyBpbml0IHJlcG9zCiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRpbnN0YWxsZWRSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKCiAgICAgICAgJGRtID0gJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKTsKICAgICAgICAkaW0gPSAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKTsKCiAgICAgICAgJGVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJHVucHVzaGVkQ2hhbmdlcyA9IGFycmF5KCk7CiAgICAgICAgJHZjc1ZlcnNpb25DaGFuZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgJHBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyOwogICAgICAgICRndWVzc2VyID0gbmV3IFZlcnNpb25HdWVzc2VyKCRjb21wb3Nlci0+Z2V0Q29uZmlnKCksIG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKSwgJHBhcnNlcik7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcjsKCiAgICAgICAgLy8gbGlzdCBwYWNrYWdlcwogICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsZWRSZXBvLT5nZXRDYW5vbmljYWxQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRkb3dubG9hZGVyID0gJGRtLT5nZXREb3dubG9hZGVyRm9yUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgICAgICR0YXJnZXREaXIgPSAkaW0tPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgICAgIGlmICgkZG93bmxvYWRlciBpbnN0YW5jZW9mIENoYW5nZVJlcG9ydEludGVyZmFjZSkgewogICAgICAgICAgICAgICAgaWYgKGlzX2xpbmsoJHRhcmdldERpcikpIHsKICAgICAgICAgICAgICAgICAgICAkZXJyb3JzWyR0YXJnZXREaXJdID0gJHRhcmdldERpciAuICcgaXMgYSBzeW1ib2xpYyBsaW5rLic7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRjaGFuZ2VzID0gJGRvd25sb2FkZXItPmdldExvY2FsQ2hhbmdlcygkcGFja2FnZSwgJHRhcmdldERpcikpIHsKICAgICAgICAgICAgICAgICAgICAkZXJyb3JzWyR0YXJnZXREaXJdID0gJGNoYW5nZXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZG93bmxvYWRlciBpbnN0YW5jZW9mIFZjc0NhcGFibGVEb3dubG9hZGVySW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGRvd25sb2FkZXItPmdldFZjc1JlZmVyZW5jZSgkcGFja2FnZSwgJHRhcmdldERpcikpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCRwYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHByZXZpb3VzUmVmID0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Rpc3QnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHByZXZpb3VzUmVmID0gJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHByZXZpb3VzUmVmID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjdXJyZW50VmVyc2lvbiA9ICRndWVzc2VyLT5ndWVzc1ZlcnNpb24oJGR1bXBlci0+ZHVtcCgkcGFja2FnZSksICR0YXJnZXREaXIpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJHByZXZpb3VzUmVmICYmICRjdXJyZW50VmVyc2lvbiAmJiAkY3VycmVudFZlcnNpb25bJ2NvbW1pdCddICE9PSAkcHJldmlvdXNSZWYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZjc1ZlcnNpb25DaGFuZ2VzWyR0YXJnZXREaXJdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncHJldmlvdXMnID0+IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZWYnID0+ICRwcmV2aW91c1JlZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY3VycmVudCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICRjdXJyZW50VmVyc2lvblsncHJldHR5X3ZlcnNpb24nXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncmVmJyA9PiAkY3VycmVudFZlcnNpb25bJ2NvbW1pdCddLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZG93bmxvYWRlciBpbnN0YW5jZW9mIER2Y3NEb3dubG9hZGVySW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICBpZiAoJHVucHVzaGVkID0gJGRvd25sb2FkZXItPmdldFVucHVzaGVkQ2hhbmdlcygkcGFja2FnZSwgJHRhcmdldERpcikpIHsKICAgICAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzWyR0YXJnZXREaXJdID0gJHVucHVzaGVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBvdXRwdXQgZXJyb3JzL3dhcm5pbmdzCiAgICAgICAgaWYgKCEkZXJyb3JzICYmICEkdW5wdXNoZWRDaGFuZ2VzICYmICEkdmNzVmVyc2lvbkNoYW5nZXMpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5ObyBsb2NhbCBjaGFuZ2VzPC9pbmZvPicpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVycm9ycykgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5Zb3UgaGF2ZSBjaGFuZ2VzIGluIHRoZSBmb2xsb3dpbmcgZGVwZW5kZW5jaWVzOjwvZXJyb3I+Jyk7CgogICAgICAgICAgICBmb3JlYWNoICgkZXJyb3JzIGFzICRwYXRoID0+ICRjaGFuZ2VzKSB7CiAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3ZlcmJvc2UnKSkgewogICAgICAgICAgICAgICAgICAgICRpbmRlbnRlZENoYW5nZXMgPSBpbXBsb2RlKCJcbiIsIGFycmF5X21hcChmdW5jdGlvbiAoJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcgICAgJyAuIGx0cmltKCRsaW5lKTsKICAgICAgICAgICAgICAgICAgICB9LCBleHBsb2RlKCJcbiIsICRjaGFuZ2VzKSkpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxpbmZvPicuJHBhdGguJzwvaW5mbz46Jyk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgkaW5kZW50ZWRDaGFuZ2VzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgkcGF0aCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdW5wdXNoZWRDaGFuZ2VzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGhhdmUgdW5wdXNoZWQgY2hhbmdlcyBvbiB0aGUgY3VycmVudCBicmFuY2ggaW4gdGhlIGZvbGxvd2luZyBkZXBlbmRlbmNpZXM6PC93YXJuaW5nPicpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHVucHVzaGVkQ2hhbmdlcyBhcyAkcGF0aCA9PiAkY2hhbmdlcykgewogICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpIHsKICAgICAgICAgICAgICAgICAgICAkaW5kZW50ZWRDaGFuZ2VzID0gaW1wbG9kZSgiXG4iLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnICAgICcgLiBsdHJpbSgkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgfSwgZXhwbG9kZSgiXG4iLCAkY2hhbmdlcykpKTsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz4nLiRwYXRoLic8L2luZm8+OicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJGluZGVudGVkQ2hhbmdlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJHBhdGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHZjc1ZlcnNpb25DaGFuZ2VzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGhhdmUgdmVyc2lvbiB2YXJpYXRpb25zIGluIHRoZSBmb2xsb3dpbmcgZGVwZW5kZW5jaWVzOjwvd2FybmluZz4nKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCR2Y3NWZXJzaW9uQ2hhbmdlcyBhcyAkcGF0aCA9PiAkY2hhbmdlcykgewogICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBkb24ndCBjYW4ndCBmaW5kIGEgdmVyc2lvbiwgdXNlIHRoZSByZWYgaW5zdGVhZC4KICAgICAgICAgICAgICAgICAgICAkY3VycmVudFZlcnNpb24gPSAkY2hhbmdlc1snY3VycmVudCddWyd2ZXJzaW9uJ10gPzogJGNoYW5nZXNbJ2N1cnJlbnQnXVsncmVmJ107CiAgICAgICAgICAgICAgICAgICAgJHByZXZpb3VzVmVyc2lvbiA9ICRjaGFuZ2VzWydwcmV2aW91cyddWyd2ZXJzaW9uJ10gPzogJGNoYW5nZXNbJ3ByZXZpb3VzJ11bJ3JlZiddOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJGlvLT5pc1ZlcnlWZXJib3NlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3V0cHV0IHRoZSByZWYgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIG9yIG5vdCBpdCdzIGJlaW5nIHVzZWQgYXMgdGhlIHZlcnNpb24KICAgICAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRWZXJzaW9uIC49IHNwcmludGYoJyAoJXMpJywgJGNoYW5nZXNbJ2N1cnJlbnQnXVsncmVmJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAkcHJldmlvdXNWZXJzaW9uIC49IHNwcmludGYoJyAoJXMpJywgJGNoYW5nZXNbJ3ByZXZpb3VzJ11bJ3JlZiddKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxpbmZvPicuJHBhdGguJzwvaW5mbz46Jyk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZShzcHJpbnRmKCcgICAgRnJvbSA8Y29tbWVudD4lczwvY29tbWVudD4gdG8gPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywgJHByZXZpb3VzVmVyc2lvbiwgJGN1cnJlbnRWZXJzaW9uKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJHBhdGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoKCRlcnJvcnMgfHwgJHVucHVzaGVkQ2hhbmdlcyB8fCAkdmNzVmVyc2lvbkNoYW5nZXMpICYmICEkaW5wdXQtPmdldE9wdGlvbigndmVyYm9zZScpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignVXNlIC0tdmVyYm9zZSAoLXYpIHRvIHNlZSBhIGxpc3Qgb2YgZmlsZXMnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoJGVycm9ycyA/IHNlbGY6OkVYSVRfQ09ERV9FUlJPUlMgOiAwKSArICgkdW5wdXNoZWRDaGFuZ2VzID8gc2VsZjo6RVhJVF9DT0RFX1VOUFVTSEVEX0NIQU5HRVMgOiAwKSArICgkdmNzVmVyc2lvbkNoYW5nZXMgPyBzZWxmOjpFWElUX0NPREVfVkVSU0lPTl9DSEFOR0VTIDogMCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFRhYmxlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFN0eWxlXFN5bWZvbnlTdHlsZTsKCi8qKgogKiBAYXV0aG9yIEJlbm/DrnQgTWVybGV0IDxiZW5vaXQubWVybGV0QGdtYWlsLmNvbT4KICovCmNsYXNzIExpY2Vuc2VzQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnbGljZW5zZXMnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdTaG93cyBpbmZvcm1hdGlvbiBhYm91dCBsaWNlbnNlcyBvZiBkZXBlbmRlbmNpZXMuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmb3JtYXQnLCAnZicsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0Zvcm1hdCBvZiB0aGUgb3V0cHV0OiB0ZXh0LCBqc29uIG9yIHN1bW1hcnknLCAndGV4dCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIHNlYXJjaCBpbiByZXF1aXJlLWRldiBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSBsaWNlbnNlIGNvbW1hbmQgZGlzcGxheXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxpY2Vuc2VzIG9mCnRoZSBpbnN0YWxsZWQgZGVwZW5kZW5jaWVzLgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjbGljZW5zZXMKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwoKICAgICAgICAkY29tbWFuZEV2ZW50ID0gbmV3IENvbW1hbmRFdmVudChQbHVnaW5FdmVudHM6OkNPTU1BTkQsICdsaWNlbnNlcycsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJHJvb3QgPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKTsKICAgICAgICAkcmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmZpbHRlclJlcXVpcmVkUGFja2FnZXMoJHJlcG8sICRyb290KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+YXBwZW5kUGFja2FnZXMoJHJlcG8tPmdldFBhY2thZ2VzKCksIGFycmF5KCkpOwogICAgICAgIH0KCiAgICAgICAga3NvcnQoJHBhY2thZ2VzKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgc3dpdGNoICgkZm9ybWF0ID0gJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpKSB7CiAgICAgICAgICAgIGNhc2UgJ3RleHQnOgogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnTmFtZTogPGNvbW1lbnQ+Jy4kcm9vdC0+Z2V0UHJldHR5TmFtZSgpLic8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdWZXJzaW9uOiA8Y29tbWVudD4nLiRyb290LT5nZXRGdWxsUHJldHR5VmVyc2lvbigpLic8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdMaWNlbnNlczogPGNvbW1lbnQ+Jy4oaW1wbG9kZSgnLCAnLCAkcm9vdC0+Z2V0TGljZW5zZSgpKSA/OiAnbm9uZScpLic8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdEZXBlbmRlbmNpZXM6Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcnKTsKCiAgICAgICAgICAgICAgICAkdGFibGUgPSBuZXcgVGFibGUoJG91dHB1dCk7CiAgICAgICAgICAgICAgICAkdGFibGUtPnNldFN0eWxlKCdjb21wYWN0Jyk7CiAgICAgICAgICAgICAgICAkdGFibGVTdHlsZSA9ICR0YWJsZS0+Z2V0U3R5bGUoKTsKICAgICAgICAgICAgICAgIGlmIChtZXRob2RfZXhpc3RzKCR0YWJsZVN0eWxlLCAnc2V0VmVydGljYWxCb3JkZXJDaGFycycpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRhYmxlU3R5bGUtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcnMoJycpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIHJlbW92ZSBpbiBjb21wb3NlciAyLjIKICAgICAgICAgICAgICAgICAgICAvLyBAcGhwc3Rhbi1pZ25vcmUtbmV4dC1saW5lCiAgICAgICAgICAgICAgICAgICAgJHRhYmxlU3R5bGUtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcignJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGFibGVTdHlsZS0+c2V0Q2VsbFJvd0NvbnRlbnRGb3JtYXQoJyVzICAnKTsKICAgICAgICAgICAgICAgICR0YWJsZS0+c2V0SGVhZGVycyhhcnJheSgnTmFtZScsICdWZXJzaW9uJywgJ0xpY2Vuc2UnKSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkdGFibGUtPmFkZFJvdyhhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGltcGxvZGUoJywgJywgJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgPyAkcGFja2FnZS0+Z2V0TGljZW5zZSgpIDogYXJyYXkoKSkgPzogJ25vbmUnLAogICAgICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRhYmxlLT5yZW5kZXIoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAnanNvbic6CiAgICAgICAgICAgICAgICAkZGVwZW5kZW5jaWVzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRkZXBlbmRlbmNpZXNbJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKV0gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAnbGljZW5zZScgPT4gJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgPyAkcGFja2FnZS0+Z2V0TGljZW5zZSgpIDogYXJyYXkoKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoSnNvbkZpbGU6OmVuY29kZShhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gJHJvb3QtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAndmVyc2lvbicgPT4gJHJvb3QtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAgICAgJ2xpY2Vuc2UnID0+ICRyb290LT5nZXRMaWNlbnNlKCksCiAgICAgICAgICAgICAgICAgICAgJ2RlcGVuZGVuY2llcycgPT4gJGRlcGVuZGVuY2llcywKICAgICAgICAgICAgICAgICkpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAnc3VtbWFyeSc6CiAgICAgICAgICAgICAgICAkdXNlZExpY2Vuc2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRsaWNlbnNlID0gJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgPyAkcGFja2FnZS0+Z2V0TGljZW5zZSgpIDogYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAkbGljZW5zZU5hbWUgPSAkbGljZW5zZVswXTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR1c2VkTGljZW5zZXNbJGxpY2Vuc2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHVzZWRMaWNlbnNlc1skbGljZW5zZU5hbWVdID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHVzZWRMaWNlbnNlc1skbGljZW5zZU5hbWVdKys7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU29ydCBsaWNlbnNlcyBzbyB0aGF0IHRoZSBtb3N0IHVzZWQgbGljZW5zZSB3aWxsIGFwcGVhciBmaXJzdAogICAgICAgICAgICAgICAgYXJzb3J0KCR1c2VkTGljZW5zZXMsIFNPUlRfTlVNRVJJQyk7CgogICAgICAgICAgICAgICAgJHJvd3MgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVzZWRMaWNlbnNlcyBhcyAkdXNlZExpY2Vuc2UgPT4gJG51bWJlck9mRGVwZW5kZW5jaWVzKSB7CiAgICAgICAgICAgICAgICAgICAgJHJvd3NbXSA9IGFycmF5KCR1c2VkTGljZW5zZSwgJG51bWJlck9mRGVwZW5kZW5jaWVzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkc3ltZm9ueUlvID0gbmV3IFN5bWZvbnlTdHlsZSgkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICAgICAgICAgJHN5bWZvbnlJby0+dGFibGUoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoJ0xpY2Vuc2UnLCAnTnVtYmVyIG9mIGRlcGVuZGVuY2llcycpLAogICAgICAgICAgICAgICAgICAgICRyb3dzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVW5zdXBwb3J0ZWQgZm9ybWF0ICIlcyIuICBTZWUgaGVscCBmb3Igc3VwcG9ydGVkIGZvcm1hdHMuJywgJGZvcm1hdCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kIHBhY2thZ2UgcmVxdWlyZXMgYW5kIGNoaWxkIHJlcXVpcmVzCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+ICRidWNrZXQKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBQYWNrYWdlSW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbHRlclJlcXVpcmVkUGFja2FnZXMoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGJ1Y2tldCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHJlcXVpcmVzID0gYXJyYXlfa2V5cygkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSk7CgogICAgICAgICRwYWNrYWdlTGlzdE5hbWVzID0gYXJyYXlfa2V5cygkYnVja2V0KTsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheV9maWx0ZXIoCiAgICAgICAgICAgICRyZXBvLT5nZXRQYWNrYWdlcygpLAogICAgICAgICAgICBmdW5jdGlvbiAoJHBhY2thZ2UpIHVzZSAoJHJlcXVpcmVzLCAkcGFja2FnZUxpc3ROYW1lcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRyZXF1aXJlcykgJiYgIWluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRwYWNrYWdlTGlzdE5hbWVzKTsKICAgICAgICAgICAgfQogICAgICAgICk7CgogICAgICAgICRidWNrZXQgPSAkdGhpcy0+YXBwZW5kUGFja2FnZXMoJHBhY2thZ2VzLCAkYnVja2V0KTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRidWNrZXQgPSAkdGhpcy0+ZmlsdGVyUmVxdWlyZWRQYWNrYWdlcygkcmVwbywgJHBhY2thZ2UsICRidWNrZXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRidWNrZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHBhY2thZ2VzIHRvIHRoZSBwYWNrYWdlIGxpc3QKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2VbXSAgICAgICAgICAgICAgJHBhY2thZ2VzIHRoZSBsaXN0IG9mIHBhY2thZ2VzIHRvIGFkZAogICAgICogQHBhcmFtICBhcnJheTxzdHJpbmcsIFBhY2thZ2VJbnRlcmZhY2U+ICRidWNrZXQgICB0aGUgbGlzdCB0byBhZGQgcGFja2FnZXMgdG8KICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBQYWNrYWdlSW50ZXJmYWNlPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzLCBhcnJheSAkYnVja2V0KQogICAgewogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkYnVja2V0WyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGJ1Y2tldDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE1hdGNoQWxsQ29uc3RyYWludDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgTmljb2xhcyBHcmVrYXMgPHBAdGNod29yay5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEZ1bmRDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldE5hbWUoJ2Z1bmQnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdEaXNjb3ZlciBob3cgdG8gaGVscCBmdW5kIHRoZSBtYWludGVuYW5jZSBvZiB5b3VyIGRlcGVuZGVuY2llcy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsICdmJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnRm9ybWF0IG9mIHRoZSBvdXRwdXQ6IHRleHQgb3IganNvbicsICd0ZXh0JyksCiAgICAgICAgICAgICkpCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKCiAgICAgICAgJHJlcG8gPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwogICAgICAgICRyZW1vdGVSZXBvcyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0UmVwb3NpdG9yaWVzKCkpOwogICAgICAgICRmdW5kaW5ncyA9IGFycmF5KCk7CgogICAgICAgICRwYWNrYWdlc1RvTG9hZCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZXNUb0xvYWRbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSBuZXcgTWF0Y2hBbGxDb25zdHJhaW50KCk7CiAgICAgICAgfQoKICAgICAgICAvLyBsb2FkIGFsbCBwYWNrYWdlcyBkZXYgdmVyc2lvbnMgaW4gcGFyYWxsZWwKICAgICAgICAkcmVzdWx0ID0gJHJlbW90ZVJlcG9zLT5sb2FkUGFja2FnZXMoJHBhY2thZ2VzVG9Mb2FkLCBhcnJheSgnZGV2JyA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZX0RFViksIGFycmF5KCkpOwoKICAgICAgICAvLyBjb2xsZWN0IGZ1bmRpbmcgZGF0YSBmcm9tIGRlZmF1bHQgYnJhbmNoZXMKICAgICAgICBmb3JlYWNoICgkcmVzdWx0WydwYWNrYWdlcyddIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICEkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZQogICAgICAgICAgICAgICAgJiYgJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UKICAgICAgICAgICAgICAgICYmICRwYWNrYWdlLT5pc0RlZmF1bHRCcmFuY2goKQogICAgICAgICAgICAgICAgJiYgJHBhY2thZ2UtPmdldEZ1bmRpbmcoKQogICAgICAgICAgICAgICAgJiYgaXNzZXQoJHBhY2thZ2VzVG9Mb2FkWyRwYWNrYWdlLT5nZXROYW1lKCldKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRmdW5kaW5ncyA9ICR0aGlzLT5pbnNlcnRGdW5kaW5nRGF0YSgkZnVuZGluZ3MsICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlc1RvTG9hZFskcGFja2FnZS0+Z2V0TmFtZSgpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGNvbGxlY3QgZnVuZGluZyBmcm9tIGluc3RhbGxlZCBwYWNrYWdlcyBpZiBub25lIHdhcyBmb3VuZCBpbiB0aGUgZGVmYXVsdCBicmFuY2ggYWJvdmUKICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgfHwgIWlzc2V0KCRwYWNrYWdlc1RvTG9hZFskcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJiYgJHBhY2thZ2UtPmdldEZ1bmRpbmcoKSkgewogICAgICAgICAgICAgICAgJGZ1bmRpbmdzID0gJHRoaXMtPmluc2VydEZ1bmRpbmdEYXRhKCRmdW5kaW5ncywgJHBhY2thZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBrc29ydCgkZnVuZGluZ3MpOwoKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgJGZvcm1hdCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKTsKICAgICAgICBpZiAoIWluX2FycmF5KCRmb3JtYXQsIGFycmF5KCd0ZXh0JywgJ2pzb24nKSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoJ1Vuc3VwcG9ydGVkIGZvcm1hdCAiJXMiLiBTZWUgaGVscCBmb3Igc3VwcG9ydGVkIGZvcm1hdHMuJywgJGZvcm1hdCkpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGZ1bmRpbmdzICYmICRmb3JtYXQgPT09ICd0ZXh0JykgewogICAgICAgICAgICAkcHJldiA9IG51bGw7CgogICAgICAgICAgICAkaW8tPndyaXRlKCdUaGUgZm9sbG93aW5nIHBhY2thZ2VzIHdlcmUgZm91bmQgaW4geW91ciBkZXBlbmRlbmNpZXMgd2hpY2ggcHVibGlzaCBmdW5kaW5nIGluZm9ybWF0aW9uOicpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGZ1bmRpbmdzIGFzICR2ZW5kb3IgPT4gJGxpbmtzKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcnKTsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoc3ByaW50ZigiPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+IiwgJHZlbmRvcikpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICR1cmwgPT4gJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSBzcHJpbnRmKCcgIDxpbmZvPiVzPC9pbmZvPicsIGltcGxvZGUoJywgJywgJHBhY2thZ2VzKSk7CgogICAgICAgICAgICAgICAgICAgIGlmICgkcHJldiAhPT0gJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwcmV2ID0gJGxpbmU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKHNwcmludGYoJyAgICAlcycsICR1cmwpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGlvLT53cml0ZSgiIik7CiAgICAgICAgICAgICRpby0+d3JpdGUoIlBsZWFzZSBjb25zaWRlciBmb2xsb3dpbmcgdGhlc2UgbGlua3MgYW5kIHNwb25zb3JpbmcgdGhlIHdvcmsgb2YgcGFja2FnZSBhdXRob3JzISIpOwogICAgICAgICAgICAkaW8tPndyaXRlKCJUaGFuayB5b3UhIik7CiAgICAgICAgfSBlbHNlaWYgKCRmb3JtYXQgPT09ICdqc29uJykgewogICAgICAgICAgICAkaW8tPndyaXRlKEpzb25GaWxlOjplbmNvZGUoJGZ1bmRpbmdzKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgiTm8gZnVuZGluZyBsaW5rcyB3ZXJlIGZvdW5kIGluIHlvdXIgcGFja2FnZSBkZXBlbmRlbmNpZXMuIFRoaXMgZG9lc24ndCBtZWFuIHRoZXkgZG9uJ3QgbmVlZCB5b3VyIHN1cHBvcnQhIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBtaXhlZFtdICRmdW5kaW5ncwogICAgICogQHJldHVybiBtaXhlZFtdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaW5zZXJ0RnVuZGluZ0RhdGEoYXJyYXkgJGZ1bmRpbmdzLCBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldEZ1bmRpbmcoKSBhcyAkZnVuZGluZ09wdGlvbikgewogICAgICAgICAgICBsaXN0KCR2ZW5kb3IsICRwYWNrYWdlTmFtZSkgPSBleHBsb2RlKCcvJywgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSk7CiAgICAgICAgICAgIC8vIGlnbm9yZSBtYWxmb3JtZWQgZnVuZGluZyBlbnRyaWVzCiAgICAgICAgICAgIGlmIChlbXB0eSgkZnVuZGluZ09wdGlvblsndXJsJ10pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdXJsID0gJGZ1bmRpbmdPcHRpb25bJ3VybCddOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRmdW5kaW5nT3B0aW9uWyd0eXBlJ10pICYmICRmdW5kaW5nT3B0aW9uWyd0eXBlJ10gPT09ICdnaXRodWInICYmIFByZWc6OmlzTWF0Y2goJ3teaHR0cHM6Ly9naXRodWIuY29tLyhbXi9dKykkfScsICR1cmwsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICR1cmwgPSAnaHR0cHM6Ly9naXRodWIuY29tL3Nwb25zb3JzLycuJG1hdGNoWzFdOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRmdW5kaW5nc1skdmVuZG9yXVskdXJsXVtdID0gJHBhY2thZ2VOYW1lOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmdW5kaW5nczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSb290UGFja2FnZVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CgpjbGFzcyBDaGVja1BsYXRmb3JtUmVxc0NvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcy0+c2V0TmFtZSgnY2hlY2stcGxhdGZvcm0tcmVxcycpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0NoZWNrIHRoYXQgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIGFyZSBzYXRpc2ZpZWQuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIGNoZWNraW5nIG9mIHJlcXVpcmUtZGV2IHBhY2thZ2VzIHJlcXVpcmVtZW50cy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbG9jaycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQ2hlY2tzIHJlcXVpcmVtZW50cyBvbmx5IGZyb20gdGhlIGxvY2sgZmlsZSwgbm90IGZyb20gaW5zdGFsbGVkIHBhY2thZ2VzLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKQ2hlY2tzIHRoYXQgeW91ciBQSFAgYW5kIGV4dGVuc2lvbnMgdmVyc2lvbnMgbWF0Y2ggdGhlIHBsYXRmb3JtIHJlcXVpcmVtZW50cyBvZiB0aGUgaW5zdGFsbGVkIHBhY2thZ2VzLgoKVW5saWtlIHVwZGF0ZS9pbnN0YWxsLCB0aGlzIGNvbW1hbmQgd2lsbCBpZ25vcmUgY29uZmlnLnBsYXRmb3JtIHNldHRpbmdzIGFuZCBjaGVjayB0aGUgcmVhbCBwbGF0Zm9ybSBwYWNrYWdlcyBzbyB5b3UgY2FuIGJlIGNlcnRhaW4geW91IGhhdmUgdGhlIHJlcXVpcmVkIHBsYXRmb3JtIGRlcGVuZGVuY2llcy4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGNoZWNrLXBsYXRmb3JtLXJlcXM8L2luZm8+CgpFT1QKICAgICAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgJHJlbW92ZVBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xvY2snKSkgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignPGluZm8+Q2hlY2tpbmcgJy4oJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpID8gJ25vbi1kZXYgJyA6ICcnKS4ncGxhdGZvcm0gcmVxdWlyZW1lbnRzIHVzaW5nIHRoZSBsb2NrIGZpbGU8L2luZm8+Jyk7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gJGNvbXBvc2VyLT5nZXRMb2NrZXIoKS0+Z2V0TG9ja2VkUmVwb3NpdG9yeSghJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaW5zdGFsbGVkUmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CiAgICAgICAgICAgIC8vIGZhbGxiYWNrIHRvIGxvY2tmaWxlIGlmIGluc3RhbGxlZCByZXBvIGlzIGVtcHR5CiAgICAgICAgICAgIGlmICghJGluc3RhbGxlZFJlcG8tPmdldFBhY2thZ2VzKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZUVycm9yKCc8d2FybmluZz5ObyB2ZW5kb3IgZGlyIHByZXNlbnQsIGNoZWNraW5nICcuKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSA/ICdub24tZGV2ICcgOiAnJykuJ3BsYXRmb3JtIHJlcXVpcmVtZW50cyBmcm9tIHRoZSBsb2NrIGZpbGU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVkUmVwbyA9ICRjb21wb3Nlci0+Z2V0TG9ja2VyKCktPmdldExvY2tlZFJlcG9zaXRvcnkoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlbW92ZVBhY2thZ2VzID0gJGluc3RhbGxlZFJlcG8tPmdldERldlBhY2thZ2VOYW1lcygpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZUVycm9yKCc8aW5mbz5DaGVja2luZyAnLigkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykgPyAnbm9uLWRldiAnIDogJycpLidwbGF0Zm9ybSByZXF1aXJlbWVudHMgZm9yIHBhY2thZ2VzIGluIHRoZSB2ZW5kb3IgZGlyPC9pbmZvPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpKSB7CiAgICAgICAgICAgICRyZXF1aXJlcyArPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0RGV2UmVxdWlyZXMoKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxdWlyZSA9PiAkbGluaykgewogICAgICAgICAgICAkcmVxdWlyZXNbJHJlcXVpcmVdID0gYXJyYXkoJGxpbmspOwogICAgICAgIH0KCiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkaW5zdGFsbGVkUmVwbywgbmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeSgkY29tcG9zZXItPmdldFBhY2thZ2UoKSkpKTsKICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkUmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJHJlbW92ZVBhY2thZ2VzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJHJlcXVpcmUgPT4gJGxpbmspIHsKICAgICAgICAgICAgICAgICRyZXF1aXJlc1skcmVxdWlyZV1bXSA9ICRsaW5rOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBrc29ydCgkcmVxdWlyZXMpOwoKICAgICAgICAkaW5zdGFsbGVkUmVwby0+YWRkUmVwb3NpdG9yeShuZXcgUGxhdGZvcm1SZXBvc2l0b3J5KGFycmF5KCksIGFycmF5KCkpKTsKCiAgICAgICAgJHJlc3VsdHMgPSBhcnJheSgpOwogICAgICAgICRleGl0Q29kZSA9IDA7CgogICAgICAgIC8qKgogICAgICAgICAqIEB2YXIgTGlua1tdICRsaW5rcwogICAgICAgICAqLwogICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxdWlyZSA9PiAkbGlua3MpIHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcXVpcmUpKSB7CiAgICAgICAgICAgICAgICAkY2FuZGlkYXRlcyA9ICRpbnN0YWxsZWRSZXBvLT5maW5kUGFja2FnZXNXaXRoUmVwbGFjZXJzQW5kUHJvdmlkZXJzKCRyZXF1aXJlKTsKICAgICAgICAgICAgICAgIGlmICgkY2FuZGlkYXRlcykgewogICAgICAgICAgICAgICAgICAgICRyZXFSZXN1bHRzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkY2FuZGlkYXRlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjYW5kaWRhdGVDb25zdHJhaW50ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGUtPmdldE5hbWUoKSA9PT0gJHJlcXVpcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYW5kaWRhdGVDb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz0nLCAkY2FuZGlkYXRlLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNhbmRpZGF0ZUNvbnN0cmFpbnQtPnNldFByZXR0eVN0cmluZygkY2FuZGlkYXRlLT5nZXRQcmV0dHlWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoJGNhbmRpZGF0ZS0+Z2V0UHJvdmlkZXMoKSwgJGNhbmRpZGF0ZS0+Z2V0UmVwbGFjZXMoKSkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFRhcmdldCgpID09PSAkcmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FuZGlkYXRlQ29uc3RyYWludCA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2FmZXR5IGNoZWNrIGZvciBwaHBzdGFuLCBidXQgaXQgc2hvdWxkIG5vdCBiZSBwb3NzaWJsZSB0byBnZXQgYSBjYW5kaWRhdGUgb3V0IG9mIGZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMgd2l0aG91dCBhIGNvbnN0cmFpbnQgbWF0Y2hpbmcgJHJlcXVpcmUKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkY2FuZGlkYXRlQ29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCRjYW5kaWRhdGVDb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXFSZXN1bHRzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNhbmRpZGF0ZS0+Z2V0TmFtZSgpID09PSAkcmVxdWlyZSA/ICRjYW5kaWRhdGUtPmdldFByZXR0eU5hbWUoKSA6ICRyZXF1aXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FuZGlkYXRlQ29uc3RyYWludC0+Z2V0UHJldHR5U3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGVycm9yPmZhaWxlZDwvZXJyb3I+Jy4oJGNhbmRpZGF0ZS0+Z2V0TmFtZSgpID09PSAkcmVxdWlyZSA/ICcnIDogJyA8Y29tbWVudD5wcm92aWRlZCBieSAnLiRjYW5kaWRhdGUtPmdldFByZXR0eU5hbWUoKS4nPC9jb21tZW50PicpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgdG8gbmV4dCBjYW5kaWRhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FuZGlkYXRlLT5nZXROYW1lKCkgPT09ICRyZXF1aXJlID8gJGNhbmRpZGF0ZS0+Z2V0UHJldHR5TmFtZSgpIDogJHJlcXVpcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FuZGlkYXRlQ29uc3RyYWludC0+Z2V0UHJldHR5U3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbmZvPnN1Y2Nlc3M8L2luZm8+Jy4oJGNhbmRpZGF0ZS0+Z2V0TmFtZSgpID09PSAkcmVxdWlyZSA/ICcnIDogJyA8Y29tbWVudD5wcm92aWRlZCBieSAnLiRjYW5kaWRhdGUtPmdldFByZXR0eU5hbWUoKS4nPC9jb21tZW50PicpLAogICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuZGlkYXRlIG1hdGNoZWQsIHNraXAgdG8gbmV4dCByZXF1aXJlbWVudAogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gc2hvdyB0aGUgZmlyc3QgZXJyb3IgZnJvbSBldmVyeSBmYWlsZWQgY2FuZGlkYXRlCiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHMgPSBhcnJheV9tZXJnZSgkcmVzdWx0cywgJHJlcVJlc3VsdHMpOwogICAgICAgICAgICAgICAgICAgICRleGl0Q29kZSA9IG1heCgkZXhpdENvZGUsIDEpOwoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmUsCiAgICAgICAgICAgICAgICAgICAgJ24vYScsCiAgICAgICAgICAgICAgICAgICAgJGxpbmtzWzBdLAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+bWlzc2luZzwvZXJyb3I+JywKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgJGV4aXRDb2RlID0gbWF4KCRleGl0Q29kZSwgMik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5wcmludFRhYmxlKCRvdXRwdXQsICRyZXN1bHRzKTsKCiAgICAgICAgcmV0dXJuICRleGl0Q29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBtaXhlZFtdICRyZXN1bHRzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFRhYmxlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkcmVzdWx0cykKICAgIHsKICAgICAgICAkcm93cyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHZhciBMaW5rfG51bGwgJGxpbmsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGxpc3QoJHBsYXRmb3JtUGFja2FnZSwgJHZlcnNpb24sICRsaW5rLCAkc3RhdHVzKSA9ICRyZXN1bHQ7CiAgICAgICAgICAgICRyb3dzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICRwbGF0Zm9ybVBhY2thZ2UsCiAgICAgICAgICAgICAgICAkdmVyc2lvbiwKICAgICAgICAgICAgICAgICRsaW5rID8gc3ByaW50ZignJXMgJXMgJXMgKCVzKScsICRsaW5rLT5nZXRTb3VyY2UoKSwgJGxpbmstPmdldERlc2NyaXB0aW9uKCksICRsaW5rLT5nZXRUYXJnZXQoKSwgJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSkgOiAnJywKICAgICAgICAgICAgICAgICRzdGF0dXMsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVuZGVyVGFibGUoJHJvd3MsICRvdXRwdXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxTdHJpbmdJbnB1dDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBHbG9iYWxDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdnbG9iYWwnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdBbGxvd3MgcnVubmluZyBjb21tYW5kcyBpbiB0aGUgZ2xvYmFsIGNvbXBvc2VyIGRpciAoJENPTVBPU0VSX0hPTUUpLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdjb21tYW5kLW5hbWUnLCBJbnB1dEFyZ3VtZW50OjpSRVFVSVJFRCwgJycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2FyZ3MnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSB8IElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApVc2UgdGhpcyBjb21tYW5kIGFzIGEgd3JhcHBlciB0byBydW4gb3RoZXIgQ29tcG9zZXIgY29tbWFuZHMKd2l0aGluIHRoZSBnbG9iYWwgY29udGV4dCBvZiBDT01QT1NFUl9IT01FLgoKWW91IGNhbiB1c2UgdGhpcyB0byBpbnN0YWxsIENMSSB1dGlsaXRpZXMgZ2xvYmFsbHksIGFsbCB5b3UgbmVlZAppcyB0byBhZGQgdGhlIENPTVBPU0VSX0hPTUUvdmVuZG9yL2JpbiBkaXIgdG8geW91ciBQQVRIIGVudiB2YXIuCgpDT01QT1NFUl9IT01FIGlzIGM6XFVzZXJzXDx1c2VyPlxBcHBEYXRhXFJvYW1pbmdcQ29tcG9zZXIgb24gV2luZG93cwphbmQgL2hvbWUvPHVzZXI+Ly5jb21wb3NlciBvbiB1bml4IHN5c3RlbXMuCgpJZiB5b3VyIHN5c3RlbSB1c2VzIGZyZWVkZXNrdG9wLm9yZyBzdGFuZGFyZHMsIHRoZW4gaXQgd2lsbCBmaXJzdCBjaGVjawpYREdfQ09ORklHX0hPTUUgb3IgZGVmYXVsdCB0byAvaG9tZS88dXNlcj4vLmNvbmZpZy9jb21wb3NlcgoKTm90ZTogVGhpcyBwYXRoIG1heSB2YXJ5IGRlcGVuZGluZyBvbiBjdXN0b21pemF0aW9ucyB0byBiaW4tZGlyIGluCmNvbXBvc2VyLmpzb24gb3IgdGhlIGVudmlyb25tZW50YWwgdmFyaWFibGUgQ09NUE9TRVJfQklOX0RJUi4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI2dsb2JhbApFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50fHZvaWQKICAgICAqIEB0aHJvd3MgXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEV4Y2VwdGlvbkludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcnVuKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgaWYgKCFtZXRob2RfZXhpc3RzKCRpbnB1dCwgJ19fdG9TdHJpbmcnKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdFeHBlY3RlZCBhbiBJbnB1dCBpbnN0YW5jZSB0aGF0IGlzIHN0cmluZ2FibGUsIGdvdCAnLmdldF9jbGFzcygkaW5wdXQpKTsKICAgICAgICB9CgogICAgICAgIC8vIGV4dHJhY3QgcmVhbCBjb21tYW5kIG5hbWUKICAgICAgICAkdG9rZW5zID0gUHJlZzo6c3BsaXQoJ3tccyt9JywgJGlucHV0LT5fX3RvU3RyaW5nKCkpOwogICAgICAgICRhcmdzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdG9rZW5zIGFzICR0b2tlbikgewogICAgICAgICAgICBpZiAoJHRva2VuICYmICR0b2tlblswXSAhPT0gJy0nKSB7CiAgICAgICAgICAgICAgICAkYXJnc1tdID0gJHRva2VuOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRhcmdzKSA+PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHNob3cgaGVscCBmb3IgdGhpcyBjb21tYW5kIGlmIG5vIGNvbW1hbmQgd2FzIGZvdW5kCiAgICAgICAgaWYgKGNvdW50KCRhcmdzKSA8IDIpIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6cnVuKCRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGUgQ09NUE9TRVIgZW52IHZhciBzaG91bGQgbm90IGFwcGx5IHRvIHRoZSBnbG9iYWwgZXhlY3V0aW9uIHNjb3BlCiAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSJykpIHsKICAgICAgICAgICAgUGxhdGZvcm06OmNsZWFyRW52KCdDT01QT1NFUicpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hhbmdlIHRvIGdsb2JhbCBkaXIKICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCk7CiAgICAgICAgJGhvbWUgPSAkY29uZmlnLT5nZXQoJ2hvbWUnKTsKCiAgICAgICAgaWYgKCFpc19kaXIoJGhvbWUpKSB7CiAgICAgICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgICAgICRmcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRob21lKTsKICAgICAgICAgICAgaWYgKCFpc19kaXIoJGhvbWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBjcmVhdGUgaG9tZSBkaXJlY3RvcnknKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgY2hkaXIoJGhvbWUpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3Qgc3dpdGNoIHRvIGhvbWUgZGlyZWN0b3J5ICInLiRob21lLiciJywgMCwgJGUpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignPGluZm8+Q2hhbmdlZCBjdXJyZW50IGRpcmVjdG9yeSB0byAnLiRob21lLic8L2luZm8+Jyk7CgogICAgICAgIC8vIGNyZWF0ZSBuZXcgaW5wdXQgd2l0aG91dCAiZ2xvYmFsIiBjb21tYW5kIHByZWZpeAogICAgICAgICRpbnB1dCA9IG5ldyBTdHJpbmdJbnB1dChQcmVnOjpyZXBsYWNlKCd7XGJnKD86bCg/Om8oPzpiKD86YSg/OmwpPyk/KT8pPyk/XGJ9JywgJycsICRpbnB1dC0+X190b1N0cmluZygpLCAxKSk7CiAgICAgICAgJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPnJlc2V0Q29tcG9zZXIoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5ydW4oJGlucHV0LCAkb3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Byb3h5Q29tbWFuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUZhY3Rvcnk7CnVzZSBDb21wb3NlclxTY3JpcHRcU2NyaXB0RXZlbnRzOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXExvb3A7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJjaGl2ZSBvZiBhIHBhY2thZ2UgZm9yIGRpc3RyaWJ1dGlvbi4KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEFyY2hpdmVDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdhcmNoaXZlJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignQ3JlYXRlcyBhbiBhcmNoaXZlIG9mIHRoaXMgY29tcG9zZXIgcGFja2FnZS4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIHBhY2thZ2UgdG8gYXJjaGl2ZSBpbnN0ZWFkIG9mIHRoZSBjdXJyZW50IHByb2plY3QnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCd2ZXJzaW9uJywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdBIHZlcnNpb24gY29uc3RyYWludCB0byBmaW5kIHRoZSBwYWNrYWdlIHRvIGFyY2hpdmUnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZm9ybWF0JywgJ2YnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdGb3JtYXQgb2YgdGhlIHJlc3VsdGluZyBhcmNoaXZlOiB0YXIsIHRhci5neiwgdGFyLmJ6MiBvciB6aXAgKGRlZmF1bHQgdGFyKScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkaXInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdXcml0ZSB0aGUgYXJjaGl2ZSB0byB0aGlzIGRpcmVjdG9yeScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmaWxlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnV3JpdGUgdGhlIGFyY2hpdmUgd2l0aCB0aGUgZ2l2ZW4gZmlsZSBuYW1lLicKICAgICAgICAgICAgICAgICAgICAuJyBOb3RlIHRoYXQgdGhlIGZvcm1hdCB3aWxsIGJlIGFwcGVuZGVkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtZmlsdGVycycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGZpbHRlcnMgd2hlbiBzYXZpbmcgcGFja2FnZScpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPmFyY2hpdmU8L2luZm8+IGNvbW1hbmQgY3JlYXRlcyBhbiBhcmNoaXZlIG9mIHRoZSBzcGVjaWZpZWQgZm9ybWF0CmNvbnRhaW5pbmcgdGhlIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBvZiB0aGUgQ29tcG9zZXIgcHJvamVjdCBvciB0aGUgc3BlY2lmaWVkCnBhY2thZ2UgaW4gdGhlIHNwZWNpZmllZCB2ZXJzaW9uIGFuZCB3cml0ZXMgaXQgdG8gdGhlIHNwZWNpZmllZCBkaXJlY3RvcnkuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBhcmNoaXZlIFstLWZvcm1hdD16aXBdIFstLWRpcj0vZm9vXSBbcGFja2FnZSBbdmVyc2lvbl1dPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjYXJjaGl2ZQpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSk7CiAgICAgICAgJGNvbmZpZyA9IG51bGw7CgogICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CiAgICAgICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ2FyY2hpdmUnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICAgICAkZXZlbnREaXNwYXRjaGVyID0gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKTsKICAgICAgICAgICAgJGV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKICAgICAgICAgICAgJGV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2hTY3JpcHQoU2NyaXB0RXZlbnRzOjpQUkVfQVJDSElWRV9DTUQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkY29uZmlnKSB7CiAgICAgICAgICAgICRjb25maWcgPSBGYWN0b3J5OjpjcmVhdGVDb25maWcoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkaW5wdXQtPmdldE9wdGlvbignZm9ybWF0JykpIHsKICAgICAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ2Zvcm1hdCcsICRjb25maWctPmdldCgnYXJjaGl2ZS1mb3JtYXQnKSk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsID09PSAkaW5wdXQtPmdldE9wdGlvbignZGlyJykpIHsKICAgICAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ2RpcicsICRjb25maWctPmdldCgnYXJjaGl2ZS1kaXInKSk7CiAgICAgICAgfQoKICAgICAgICAkcmV0dXJuQ29kZSA9ICR0aGlzLT5hcmNoaXZlKAogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKSwKICAgICAgICAgICAgJGNvbmZpZywKICAgICAgICAgICAgJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZScpLAogICAgICAgICAgICAkaW5wdXQtPmdldEFyZ3VtZW50KCd2ZXJzaW9uJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKSwKICAgICAgICAgICAgJGlucHV0LT5nZXRPcHRpb24oJ2RpcicpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignZmlsZScpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLWZpbHRlcnMnKSwKICAgICAgICAgICAgJGNvbXBvc2VyCiAgICAgICAgKTsKCiAgICAgICAgaWYgKDAgPT09ICRyZXR1cm5Db2RlICYmICRjb21wb3NlcikgewogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBPU1RfQVJDSElWRV9DTUQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXR1cm5Db2RlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRwYWNrYWdlTmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICR2ZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtYXQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlc3QKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZmlsZU5hbWUKICAgICAqIEBwYXJhbSBib29sICRpZ25vcmVGaWx0ZXJzCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXJjaGl2ZShJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkcGFja2FnZU5hbWUgPSBudWxsLCAkdmVyc2lvbiA9IG51bGwsICRmb3JtYXQgPSAndGFyJywgJGRlc3QgPSAnLicsICRmaWxlTmFtZSA9IG51bGwsICRpZ25vcmVGaWx0ZXJzID0gZmFsc2UsIENvbXBvc2VyICRjb21wb3NlciA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAkYXJjaGl2ZU1hbmFnZXIgPSAkY29tcG9zZXItPmdldEFyY2hpdmVNYW5hZ2VyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGZhY3RvcnkgPSBuZXcgRmFjdG9yeTsKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCk7CiAgICAgICAgICAgICRodHRwRG93bmxvYWRlciA9IEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZyk7CiAgICAgICAgICAgICRkb3dubG9hZE1hbmFnZXIgPSAkZmFjdG9yeS0+Y3JlYXRlRG93bmxvYWRNYW5hZ2VyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkcHJvY2Vzcyk7CiAgICAgICAgICAgICRhcmNoaXZlTWFuYWdlciA9ICRmYWN0b3J5LT5jcmVhdGVBcmNoaXZlTWFuYWdlcigkY29uZmlnLCAkZG93bmxvYWRNYW5hZ2VyLCBuZXcgTG9vcCgkaHR0cERvd25sb2FkZXIsICRwcm9jZXNzKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2VOYW1lKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPnNlbGVjdFBhY2thZ2UoJGlvLCAkcGFja2FnZU5hbWUsICR2ZXJzaW9uKTsKCiAgICAgICAgICAgIGlmICghJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0UGFja2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5DcmVhdGluZyB0aGUgYXJjaGl2ZSBpbnRvICInLiRkZXN0LiciLjwvaW5mbz4nKTsKICAgICAgICAkcGFja2FnZVBhdGggPSAkYXJjaGl2ZU1hbmFnZXItPmFyY2hpdmUoJHBhY2thZ2UsICRmb3JtYXQsICRkZXN0LCAkZmlsZU5hbWUsICRpZ25vcmVGaWx0ZXJzKTsKICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbTsKICAgICAgICAkc2hvcnRQYXRoID0gJGZzLT5maW5kU2hvcnRlc3RQYXRoKGdldGN3ZCgpLCAkcGFja2FnZVBhdGgsIHRydWUpOwoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0NyZWF0ZWQ6ICcsIGZhbHNlKTsKICAgICAgICAkaW8tPndyaXRlKHN0cmxlbigkc2hvcnRQYXRoKSA8IHN0cmxlbigkcGFja2FnZVBhdGgpID8gJHNob3J0UGF0aCA6ICRwYWNrYWdlUGF0aCk7CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICR2ZXJzaW9uCiAgICAgKgogICAgICogQHJldHVybiAoQmFzZVBhY2thZ2UmQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlKXxmYWxzZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2VsZWN0UGFja2FnZShJT0ludGVyZmFjZSAkaW8sICRwYWNrYWdlTmFtZSwgJHZlcnNpb24gPSBudWxsKQogICAgewogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+U2VhcmNoaW5nIGZvciB0aGUgc3BlY2lmaWVkIHBhY2thZ2UuPC9pbmZvPicpOwoKICAgICAgICBpZiAoJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlKSkgewogICAgICAgICAgICAkbG9jYWxSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAgICAgJHJlcG8gPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheV9tZXJnZShhcnJheSgkbG9jYWxSZXBvKSwgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRkZWZhdWx0UmVwb3MgPSBSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKCR0aGlzLT5nZXRJTygpKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdObyBjb21wb3Nlci5qc29uIGZvdW5kIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwgc2VhcmNoaW5nIHBhY2thZ2VzIGZyb20gJyAuIGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkZGVmYXVsdFJlcG9zKSkpOwogICAgICAgICAgICAkcmVwbyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCRkZWZhdWx0UmVwb3MpOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VzID0gJHJlcG8tPmZpbmRQYWNrYWdlcygkcGFja2FnZU5hbWUsICR2ZXJzaW9uKTsKCiAgICAgICAgaWYgKGNvdW50KCRwYWNrYWdlcykgPiAxKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gcmVzZXQoJHBhY2thZ2VzKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5Gb3VuZCBtdWx0aXBsZSBtYXRjaGVzLCBzZWxlY3RlZCAnLiRwYWNrYWdlLT5nZXRQcmV0dHlTdHJpbmcoKS4nLjwvaW5mbz4nKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdBbHRlcm5hdGl2ZXMgd2VyZSAnLmltcGxvZGUoJywgJywgYXJyYXlfbWFwKGZ1bmN0aW9uICgkcCkgewogICAgICAgICAgICAgICAgcmV0dXJuICRwLT5nZXRQcmV0dHlTdHJpbmcoKTsKICAgICAgICAgICAgfSwgJHBhY2thZ2VzKSkuJy4nKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8Y29tbWVudD5QbGVhc2UgdXNlIGEgbW9yZSBzcGVjaWZpYyBjb25zdHJhaW50IHRvIHBpY2sgYSBkaWZmZXJlbnQgcGFja2FnZS48L2NvbW1lbnQ+Jyk7CiAgICAgICAgfSBlbHNlaWYgKCRwYWNrYWdlcykgewogICAgICAgICAgICAkcGFja2FnZSA9IHJlc2V0KCRwYWNrYWdlcyk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+Rm91bmQgYW4gZXhhY3QgbWF0Y2ggJy4kcGFja2FnZS0+Z2V0UHJldHR5U3RyaW5nKCkuJy48L2luZm8+Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Q291bGQgbm90IGZpbmQgYSBwYWNrYWdlIG1hdGNoaW5nICcuJHBhY2thZ2VOYW1lLicuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignRXhwZWN0ZWQgYSBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgaW5zdGFuY2UgYnV0IGZvdW5kICcuZ2V0X2NsYXNzKCRwYWNrYWdlKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQWJvdXRDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdhYm91dCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1Nob3dzIGEgc2hvcnQgaW5mb3JtYXRpb24gYWJvdXQgQ29tcG9zZXIuJykKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGFib3V0PC9pbmZvPgpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlclZlcnNpb24gPSBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpOwoKICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoCiAgICAgICAgICAgIDw8PEVPVAo8aW5mbz5Db21wb3NlciAtIERlcGVuZGVuY3kgTWFuYWdlciBmb3IgUEhQIC0gdmVyc2lvbiAkY29tcG9zZXJWZXJzaW9uPC9pbmZvPgo8Y29tbWVudD5Db21wb3NlciBpcyBhIGRlcGVuZGVuY3kgbWFuYWdlciB0cmFja2luZyBsb2NhbCBkZXBlbmRlbmNpZXMgb2YgeW91ciBwcm9qZWN0cyBhbmQgbGlicmFyaWVzLgpTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvIGZvciBtb3JlIGluZm9ybWF0aW9uLjwvY29tbWVudD4KRU9UCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcU2VsZlVwZGF0ZVxLZXlzOwp1c2UgQ29tcG9zZXJcU2VsZlVwZGF0ZVxWZXJzaW9uczsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxGaWxlc3lzdGVtRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CgovKioKICogQGF1dGhvciBJZ29yIFdpZWRsZXIgPGlnb3JAd2llZGxlci5jaD4KICogQGF1dGhvciBLZXZpbiBSYW4gPGtyYW5AYWRvYmUuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBTZWxmVXBkYXRlQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIGNvbnN0IEhPTUVQQUdFID0gJ2dldGNvbXBvc2VyLm9yZyc7CiAgICBjb25zdCBPTERfSU5TVEFMTF9FWFQgPSAnLW9sZC5waGFyJzsKCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3NlbGYtdXBkYXRlJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdzZWxmdXBkYXRlJykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1VwZGF0ZXMgY29tcG9zZXIucGhhciB0byB0aGUgbGF0ZXN0IHZlcnNpb24uJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyb2xsYmFjaycsICdyJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZXZlcnQgdG8gYW4gb2xkZXIgaW5zdGFsbGF0aW9uIG9mIGNvbXBvc2VyJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2NsZWFuLWJhY2t1cHMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RlbGV0ZSBvbGQgYmFja3VwcyBkdXJpbmcgYW4gdXBkYXRlLiBUaGlzIG1ha2VzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgY29tcG9zZXIgdGhlIG9ubHkgYmFja3VwIGF2YWlsYWJsZSBhZnRlciB0aGUgdXBkYXRlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgndmVyc2lvbicsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIHZlcnNpb24gdG8gdXBkYXRlIHRvJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXByb2dyZXNzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3Qgb3V0cHV0IGRvd25sb2FkIHByb2dyZXNzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1cGRhdGUta2V5cycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJvbXB0IHVzZXIgZm9yIGEga2V5IHVwZGF0ZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzdGFibGUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlIGFuIHVwZGF0ZSB0byB0aGUgc3RhYmxlIGNoYW5uZWwnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJldmlldycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2UgYW4gdXBkYXRlIHRvIHRoZSBwcmV2aWV3IGNoYW5uZWwnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc25hcHNob3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlIGFuIHVwZGF0ZSB0byB0aGUgc25hcHNob3QgY2hhbm5lbCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCcxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZSBhbiB1cGRhdGUgdG8gdGhlIHN0YWJsZSBjaGFubmVsLCBidXQgb25seSB1c2UgMS54IHZlcnNpb25zJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJzInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlIGFuIHVwZGF0ZSB0byB0aGUgc3RhYmxlIGNoYW5uZWwsIGJ1dCBvbmx5IHVzZSAyLnggdmVyc2lvbnMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc2V0LWNoYW5uZWwtb25seScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnT25seSBzdG9yZSB0aGUgY2hhbm5lbCBhcyB0aGUgZGVmYXVsdCBvbmUgYW5kIHRoZW4gZXhpdCcpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPnNlbGYtdXBkYXRlPC9pbmZvPiBjb21tYW5kIGNoZWNrcyBnZXRjb21wb3Nlci5vcmcgZm9yIG5ld2VyCnZlcnNpb25zIG9mIGNvbXBvc2VyIGFuZCBpZiBmb3VuZCwgaW5zdGFsbHMgdGhlIGxhdGVzdC4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHNlbGYtdXBkYXRlPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjc2VsZi11cGRhdGUtc2VsZnVwZGF0ZS0KRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICogQHRocm93cyBGaWxlc3lzdGVtRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgLy8gdHJpZ2dlciBhdXRvbG9hZGluZyBvZiBhIGZldyBjbGFzc2VzIHdoaWNoIG1heSBiZSBuZWVkZWQgd2hlbiB2ZXJpZnlpbmcvc3dhcHBpbmcgdGhlIHBoYXIgZmlsZQogICAgICAgIC8vIHRvIGVuc3VyZSB3ZSBkbyBub3QgdHJ5IHRvIGxvYWQgdGhlbSBmcm9tIHRoZSBuZXcgcGhhciwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvMTAyNTIKICAgICAgICBjbGFzc19leGlzdHMoJ0NvbXBvc2VyXFV0aWxcUGxhdGZvcm0nKTsKICAgICAgICBjbGFzc19leGlzdHMoJ0NvbXBvc2VyXERvd25sb2FkZXJcRmlsZXN5c3RlbUV4Y2VwdGlvbicpOwoKICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCk7CgogICAgICAgIGlmICgkY29uZmlnLT5nZXQoJ2Rpc2FibGUtdGxzJykgPT09IHRydWUpIHsKICAgICAgICAgICAgJGJhc2VVcmwgPSAnaHR0cDovLycgLiBzZWxmOjpIT01FUEFHRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYmFzZVVybCA9ICdodHRwczovLycgLiBzZWxmOjpIT01FUEFHRTsKICAgICAgICB9CgogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICRodHRwRG93bmxvYWRlciA9IEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZyk7CgogICAgICAgICR2ZXJzaW9uc1V0aWwgPSBuZXcgVmVyc2lvbnMoJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyKTsKCiAgICAgICAgLy8gc3dpdGNoIGNoYW5uZWwgaWYgcmVxdWVzdGVkCiAgICAgICAgJHJlcXVlc3RlZENoYW5uZWwgPSBudWxsOwogICAgICAgIGZvcmVhY2ggKFZlcnNpb25zOjokY2hhbm5lbHMgYXMgJGNoYW5uZWwpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCRjaGFubmVsKSkgewogICAgICAgICAgICAgICAgJHJlcXVlc3RlZENoYW5uZWwgPSAkY2hhbm5lbDsKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1V0aWwtPnNldENoYW5uZWwoJGNoYW5uZWwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignc2V0LWNoYW5uZWwtb25seScpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJGNhY2hlRGlyID0gJGNvbmZpZy0+Z2V0KCdjYWNoZS1kaXInKTsKICAgICAgICAkcm9sbGJhY2tEaXIgPSAkY29uZmlnLT5nZXQoJ2RhdGEtZGlyJyk7CiAgICAgICAgJGhvbWUgPSAkY29uZmlnLT5nZXQoJ2hvbWUnKTsKICAgICAgICAkbG9jYWxGaWxlbmFtZSA9IHJlYWxwYXRoKCRfU0VSVkVSWydhcmd2J11bMF0pID86ICRfU0VSVkVSWydhcmd2J11bMF07CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLWtleXMnKSkgewogICAgICAgICAgICAkdGhpcy0+ZmV0Y2hLZXlzKCRpbywgJGNvbmZpZyk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGVuc3VyZSBjb21wb3Nlci5waGFyIGxvY2F0aW9uIGlzIGFjY2Vzc2libGUKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRsb2NhbEZpbGVuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXN5c3RlbUV4Y2VwdGlvbignQ29tcG9zZXIgdXBkYXRlIGZhaWxlZDogdGhlICInLiRsb2NhbEZpbGVuYW1lLiciIGlzIG5vdCBhY2Nlc3NpYmxlJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBpZiBjdXJyZW50IGRpciBpcyB3cml0YWJsZSBhbmQgaWYgbm90IHRyeSB0aGUgY2FjaGUgZGlyIGZyb20gc2V0dGluZ3MKICAgICAgICAkdG1wRGlyID0gaXNfd3JpdGFibGUoZGlybmFtZSgkbG9jYWxGaWxlbmFtZSkpID8gZGlybmFtZSgkbG9jYWxGaWxlbmFtZSkgOiAkY2FjaGVEaXI7CgogICAgICAgIC8vIGNoZWNrIGZvciBwZXJtaXNzaW9ucyBpbiBsb2NhbCBmaWxlc3lzdGVtIGJlZm9yZSBzdGFydCBjb25uZWN0aW9uIHByb2Nlc3MKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCR0bXBEaXIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlc3lzdGVtRXhjZXB0aW9uKCdDb21wb3NlciB1cGRhdGUgZmFpbGVkOiB0aGUgIicuJHRtcERpci4nIiBkaXJlY3RvcnkgdXNlZCB0byBkb3dubG9hZCB0aGUgdGVtcCBmaWxlIGNvdWxkIG5vdCBiZSB3cml0dGVuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBpZiBjb21wb3NlciBpcyBydW5uaW5nIGFzIHRoZSBzYW1lIHVzZXIgdGhhdCBvd25zIHRoZSBkaXJlY3Rvcnkgcm9vdCwgb25seSBpZiBQT1NJWCBpcyBkZWZpbmVkIGFuZCBjYWxsYWJsZQogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldHB3dWlkJykgJiYgZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRldWlkJykpIHsKICAgICAgICAgICAgJGNvbXBvc2VVc2VyID0gcG9zaXhfZ2V0cHd1aWQocG9zaXhfZ2V0ZXVpZCgpKTsKICAgICAgICAgICAgJGhvbWVPd25lciA9IHBvc2l4X2dldHB3dWlkKGZpbGVvd25lcigkaG9tZSkpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VVc2VyWyduYW1lJ10sICRob21lT3duZXJbJ25hbWUnXSkgJiYgJGNvbXBvc2VVc2VyWyduYW1lJ10gIT09ICRob21lT3duZXJbJ25hbWUnXSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHJ1bm5pbmcgQ29tcG9zZXIgYXMgIicuJGNvbXBvc2VVc2VyWyduYW1lJ10uJyIsIHdoaWxlICInLiRob21lLiciIGlzIG93bmVkIGJ5ICInLiRob21lT3duZXJbJ25hbWUnXS4nIjwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdyb2xsYmFjaycpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cm9sbGJhY2soJG91dHB1dCwgJHJvbGxiYWNrRGlyLCAkbG9jYWxGaWxlbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAkbGF0ZXN0ID0gJHZlcnNpb25zVXRpbC0+Z2V0TGF0ZXN0KCk7CiAgICAgICAgJGxhdGVzdFN0YWJsZSA9ICR2ZXJzaW9uc1V0aWwtPmdldExhdGVzdCgnc3RhYmxlJyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGxhdGVzdFByZXZpZXcgPSAkdmVyc2lvbnNVdGlsLT5nZXRMYXRlc3QoJ3ByZXZpZXcnKTsKICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRsYXRlc3RQcmV2aWV3ID0gJGxhdGVzdFN0YWJsZTsKICAgICAgICB9CiAgICAgICAgJGxhdGVzdFZlcnNpb24gPSAkbGF0ZXN0Wyd2ZXJzaW9uJ107CiAgICAgICAgJHVwZGF0ZVZlcnNpb24gPSAkaW5wdXQtPmdldEFyZ3VtZW50KCd2ZXJzaW9uJykgPzogJGxhdGVzdFZlcnNpb247CiAgICAgICAgJGN1cnJlbnRNYWpvclZlcnNpb24gPSBQcmVnOjpyZXBsYWNlKCd7XihcZCspLip9JywgJyQxJywgQ29tcG9zZXI6OmdldFZlcnNpb24oKSk7CiAgICAgICAgJHVwZGF0ZU1ham9yVmVyc2lvbiA9IFByZWc6OnJlcGxhY2UoJ3teKFxkKykuKn0nLCAnJDEnLCAkdXBkYXRlVmVyc2lvbik7CiAgICAgICAgJHByZXZpZXdNYWpvclZlcnNpb24gPSBQcmVnOjpyZXBsYWNlKCd7XihcZCspLip9JywgJyQxJywgJGxhdGVzdFByZXZpZXdbJ3ZlcnNpb24nXSk7CgogICAgICAgIGlmICgkdmVyc2lvbnNVdGlsLT5nZXRDaGFubmVsKCkgPT09ICdzdGFibGUnICYmICEkaW5wdXQtPmdldEFyZ3VtZW50KCd2ZXJzaW9uJykpIHsKICAgICAgICAgICAgLy8gaWYgcmVxdWVzdGluZyBzdGFibGUgY2hhbm5lbCBhbmQgbm8gc3BlY2lmaWMgdmVyc2lvbiwgYXZvaWQgYXV0b21hdGljYWxseSB1cGdyYWRpbmcgdG8gdGhlIG5leHQgbWFqb3IKICAgICAgICAgICAgLy8gc2ltcGx5IG91dHB1dCBhIHdhcm5pbmcgdGhhdCB0aGUgbmV4dCBtYWpvciBzdGFibGUgaXMgYXZhaWxhYmxlIGFuZCBsZXQgdXNlcnMgdXBncmFkZSB0byBpdCBtYW51YWxseQogICAgICAgICAgICBpZiAoJGN1cnJlbnRNYWpvclZlcnNpb24gPCAkdXBkYXRlTWFqb3JWZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAkc2tpcHBlZFZlcnNpb24gPSAkdXBkYXRlVmVyc2lvbjsKCiAgICAgICAgICAgICAgICAkdmVyc2lvbnNVdGlsLT5zZXRDaGFubmVsKCRjdXJyZW50TWFqb3JWZXJzaW9uKTsKCiAgICAgICAgICAgICAgICAkbGF0ZXN0ID0gJHZlcnNpb25zVXRpbC0+Z2V0TGF0ZXN0KCk7CiAgICAgICAgICAgICAgICAkbGF0ZXN0U3RhYmxlID0gJHZlcnNpb25zVXRpbC0+Z2V0TGF0ZXN0KCdzdGFibGUnKTsKICAgICAgICAgICAgICAgICRsYXRlc3RWZXJzaW9uID0gJGxhdGVzdFsndmVyc2lvbiddOwogICAgICAgICAgICAgICAgJHVwZGF0ZVZlcnNpb24gPSAkbGF0ZXN0VmVyc2lvbjsKCiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkEgbmV3IHN0YWJsZSBtYWpvciB2ZXJzaW9uIG9mIENvbXBvc2VyIGlzIGF2YWlsYWJsZSAoJy4kc2tpcHBlZFZlcnNpb24uJyksIHJ1biAiY29tcG9zZXIgc2VsZi11cGRhdGUgLS0nLiR1cGRhdGVNYWpvclZlcnNpb24uJyIgdG8gdXBkYXRlIHRvIGl0LiBTZWUgYWxzbyBodHRwczovL2dldGNvbXBvc2VyLm9yZy8nLiR1cGRhdGVNYWpvclZlcnNpb24uJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRjdXJyZW50TWFqb3JWZXJzaW9uIDwgJHByZXZpZXdNYWpvclZlcnNpb24pIHsKICAgICAgICAgICAgICAgIC8vIHByb21vdGUgbmV4dCBtYWpvciB2ZXJzaW9uIGlmIGF2YWlsYWJsZSBpbiBwcmV2aWV3CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkEgcHJldmlldyByZWxlYXNlIG9mIHRoZSBuZXh0IG1ham9yIHZlcnNpb24gb2YgQ29tcG9zZXIgaXMgYXZhaWxhYmxlICgnLiRsYXRlc3RQcmV2aWV3Wyd2ZXJzaW9uJ10uJyksIHJ1biAiY29tcG9zZXIgc2VsZi11cGRhdGUgLS1wcmV2aWV3IiB0byBnaXZlIGl0IGEgdHJ5LiBTZWUgYWxzbyBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcmVsZWFzZXMgZm9yIGNoYW5nZWxvZ3MuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlcXVlc3RlZENoYW5uZWwgJiYgaXNfbnVtZXJpYygkcmVxdWVzdGVkQ2hhbm5lbCkgJiYgc3RycG9zKCRsYXRlc3RTdGFibGVbJ3ZlcnNpb24nXSwgJHJlcXVlc3RlZENoYW5uZWwpICE9PSAwKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+V2FybmluZzogWW91IGZvcmNlZCB0aGUgaW5zdGFsbCBvZiAnLiRsYXRlc3RWZXJzaW9uLicgdmlhIC0tJy4kcmVxdWVzdGVkQ2hhbm5lbC4nLCBidXQgJy4kbGF0ZXN0U3RhYmxlWyd2ZXJzaW9uJ10uJyBpcyB0aGUgbGF0ZXN0IHN0YWJsZSB2ZXJzaW9uLiBVcGRhdGluZyB0byBpdCB2aWEgY29tcG9zZXIgc2VsZi11cGRhdGUgLS1zdGFibGUgaXMgcmVjb21tZW5kZWQuPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teWzAtOWEtZl17NDB9JH0nLCAkdXBkYXRlVmVyc2lvbikgJiYgJHVwZGF0ZVZlcnNpb24gIT09ICRsYXRlc3RWZXJzaW9uKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPllvdSBjYW4gbm90IHVwZGF0ZSB0byBhIHNwZWNpZmljIFNIQS0xIGFzIHRob3NlIHBoYXJzIGFyZSBub3QgYXZhaWxhYmxlIGZvciBkb3dubG9hZDwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgICRjaGFubmVsU3RyaW5nID0gJHZlcnNpb25zVXRpbC0+Z2V0Q2hhbm5lbCgpOwogICAgICAgIGlmIChpc19udW1lcmljKCRjaGFubmVsU3RyaW5nKSkgewogICAgICAgICAgICAkY2hhbm5lbFN0cmluZyAuPSAnLngnOwogICAgICAgIH0KCiAgICAgICAgaWYgKENvbXBvc2VyOjpWRVJTSU9OID09PSAkdXBkYXRlVmVyc2lvbikgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICc8aW5mbz5Zb3UgYXJlIGFscmVhZHkgdXNpbmcgdGhlIGxhdGVzdCBhdmFpbGFibGUgQ29tcG9zZXIgdmVyc2lvbiAlcyAoJXMgY2hhbm5lbCkuPC9pbmZvPicsCiAgICAgICAgICAgICAgICAgICAgJHVwZGF0ZVZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgJGNoYW5uZWxTdHJpbmcKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgYmFja3VwcyBleGNlcHQgZm9yIHRoZSBtb3N0IHJlY2VudCwgaWYgYW55CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignY2xlYW4tYmFja3VwcycpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2xlYW5CYWNrdXBzKCRyb2xsYmFja0RpciwgJHRoaXMtPmdldExhc3RCYWNrdXBWZXJzaW9uKCRyb2xsYmFja0RpcikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgICR0ZW1wRmlsZW5hbWUgPSAkdG1wRGlyIC4gJy8nIC4gYmFzZW5hbWUoJGxvY2FsRmlsZW5hbWUsICcucGhhcicpLictdGVtcCcucmFuZCgwLCAxMDAwMDAwMCkuJy5waGFyJzsKICAgICAgICAkYmFja3VwRmlsZSA9IHNwcmludGYoCiAgICAgICAgICAgICclcy8lcy0lcyVzJywKICAgICAgICAgICAgJHJvbGxiYWNrRGlyLAogICAgICAgICAgICBzdHJ0cihDb21wb3Nlcjo6UkVMRUFTRV9EQVRFLCAnIDonLCAnXy0nKSwKICAgICAgICAgICAgUHJlZzo6cmVwbGFjZSgne14oWzAtOWEtZl17N30pWzAtOWEtZl17MzN9JH0nLCAnJDEnLCBDb21wb3Nlcjo6VkVSU0lPTiksCiAgICAgICAgICAgIHNlbGY6Ok9MRF9JTlNUQUxMX0VYVAogICAgICAgICk7CgogICAgICAgICR1cGRhdGluZ1RvVGFnID0gIVByZWc6OmlzTWF0Y2goJ3teWzAtOWEtZl17NDB9JH0nLCAkdXBkYXRlVmVyc2lvbik7CgogICAgICAgICRpby0+d3JpdGUoc3ByaW50ZigiVXBncmFkaW5nIHRvIHZlcnNpb24gPGluZm8+JXM8L2luZm8+ICglcyBjaGFubmVsKS4iLCAkdXBkYXRlVmVyc2lvbiwgJGNoYW5uZWxTdHJpbmcpKTsKICAgICAgICAkcmVtb3RlRmlsZW5hbWUgPSAkYmFzZVVybCAuICgkdXBkYXRpbmdUb1RhZyA/ICIvZG93bmxvYWQveyR1cGRhdGVWZXJzaW9ufS9jb21wb3Nlci5waGFyIiA6ICcvY29tcG9zZXIucGhhcicpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRzaWduYXR1cmUgPSAkaHR0cERvd25sb2FkZXItPmdldCgkcmVtb3RlRmlsZW5hbWUuJy5zaWcnKS0+Z2V0Qm9keSgpOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGUtPmdldFN0YXR1c0NvZGUoKSA9PT0gNDA0KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVmVyc2lvbiAiJy4kdXBkYXRlVmVyc2lvbi4nIiBjb3VsZCBub3QgYmUgZm91bmQuJywgMCwgJGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICcsIGZhbHNlKTsKICAgICAgICAkaHR0cERvd25sb2FkZXItPmNvcHkoJHJlbW90ZUZpbGVuYW1lLCAkdGVtcEZpbGVuYW1lKTsKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJycpOwoKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCR0ZW1wRmlsZW5hbWUpIHx8ICEkc2lnbmF0dXJlKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPlRoZSBkb3dubG9hZCBvZiB0aGUgbmV3IGNvbXBvc2VyIHZlcnNpb24gZmFpbGVkIGZvciBhbiB1bmV4cGVjdGVkIHJlYXNvbjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIC8vIHZlcmlmeSBwaGFyIHNpZ25hdHVyZQogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpICYmICRjb25maWctPmdldCgnZGlzYWJsZS10bHMnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwaW5nIHBoYXIgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBhcyB5b3UgaGF2ZSBkaXNhYmxlZCBPcGVuU1NMIHZpYSBjb25maWcuZGlzYWJsZS10bHM8L3dhcm5pbmc+Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIG9wZW5zc2wgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkIGZvciBwaGFyIHNpZ25hdHVyZXMgdG8gYmUgdmVyaWZpZWQgYnV0IGl0IGlzIG5vdCBhdmFpbGFibGUuICcKICAgICAgICAgICAgICAgIC4gJ0lmIHlvdSBjYW4gbm90IGVuYWJsZSB0aGUgb3BlbnNzbCBleHRlbnNpb24sIHlvdSBjYW4gZGlzYWJsZSB0aGlzIGVycm9yLCBhdCB5b3VyIG93biByaXNrLCBieSBzZXR0aW5nIHRoZSBcJ2Rpc2FibGUtdGxzXCcgb3B0aW9uIHRvIHRydWUuJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzaWdGaWxlID0gJ2ZpbGU6Ly8nLiRob21lLicvJyAuICgkdXBkYXRpbmdUb1RhZyA/ICdrZXlzLnRhZ3MucHViJyA6ICdrZXlzLmRldi5wdWInKTsKICAgICAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkc2lnRmlsZSkpIHsKICAgICAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKAogICAgICAgICAgICAgICAgICAgICRob21lLicva2V5cy5kZXYucHViJywKICAgICAgICAgICAgICAgICAgICA8PDxERVZQVUJLRVkKLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFuQkRIalpTNmUwWk1vSzN4VEQ3ZgpGTkN6bFhqWC9BaWUyZGl0OFFYQTAzcFNyT1RiYU1ueE9OM2hVTDQ3THozZzFTQzZZSkVNVkhyMHpZcTRlbFdpCmkzZWNGRWd6TGNqK3BaTTVYNnFXdTJPeno0dld4M0pZbzEvYS9IWWRPdVc5ZTNsd1M4VnRTMEFWSkErVThYMEEKaFpuQm1HcGx0SGhPOGhQS0hna0p0a1RVeENoZVRjYnFuNHdHSGw4WjJTZWRpRGNQVEx3cWV6V0tVZnJZenUxZgpvL2ozV0Z3RnM2R3RLNHdkWXRpWHIreXNwQlpITzN5MXVkZjhlRkZHY2IyVjNFYUxPcnRmdXI2WFFWaXpqT3VrCjhsdzV6enNlMVFwL2tsSHFiRFJzalN6SjZpTDZGNGF5bkJjNkV1cXQvOGNjTkFJejByTGpMaE9yYWV5ajRlTm4KOGlva3dNS2lYcGNyUUxUS0grUkgxSkN1T1Z4UTQzNmJKd2JTc3AxVndpcWZ0UFFpZU4rdHpxeStFaUhKSm1HZgpUQkFiV2NuY2ljQ2s5cTJtZCtBbWhOYnZITzRQV2JiejlUekM3SEpiNDYwanlXZXVNRXZ3M2dOSXBFbzJqWWE5CnBNVjZjVnFuU2Erd09jMEQ3cEM5YTZibmUwYnZMY20zUyt3Nkk1aURCM2xac2IzQTlVdFJpU1A3YUdTbzdENzIKOHRDOCtjSWdaY0k3azl2anZPcUgrZDdzZE9VMnlQQ25SWTZ3Rmg2Mi9nOGJEblVwcjU2blpOMUc4OUd3TTRkNApyL1RVN0JRUUl6c1pnQWlxT0dYdlZrbElnQU1pVjBpdWNnZjNyTkJMamplTkV3TlNUVEc5RjBDdFErN0pMd2FFCndTRXVBdVJtK3BScWk4QlJuUS9HS1VjQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQpERVZQVUJLRVkKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoCiAgICAgICAgICAgICAgICAgICAgJGhvbWUuJy9rZXlzLnRhZ3MucHViJywKICAgICAgICAgICAgICAgICAgICA8PDxUQUdTUFVCS0VZCi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tCk1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBMFZpLzJLNmFwQ1ZqNzZuQ25DbDIKTVFVUGRLK0E5ZXFrWUJhY1hvMndRQllteVZsWG0yL24vWnNYNnBDTFlQUVRIeXI1alhia1F6Qnc4U0txUGRsaAp2QTdOcGJNZU5Dejd3UC9Bb2J2VVhNOHhRdVhLYk1EVFkydVo0TzdzTStQZkdicHRLUEJHTGU4WjhkMnNVblRPCmJYdFg2THJqMTN3a1J0bzdzdC93L1lwMzNSSGU5U2xxa2lpUzRNc0gxakJrY0lrRUhzUmF2ZVp6ZWRVYXhZME0KbWJhMHVQaEdVSW5wUHpFSHdyWXFCQkV0V3ZQOTd0MnZ0Zng4STVxdjI4a2gwWTZ0K2puakwxVXJpZDJpdVFaZgpub0NNRklPdTR2a3NLNUh4Snh4ck4wR09tR213VlFqT090eGt3aWtOaW90WkdQUjRLc1ZqOE5uQnJMWDdvR3VNCm5RdkdjaWl1K0tvQzJyM0hEQnJwRGVCVmRPV3hEelQ1UjRpSTBLb0x6RmgycEtxd2JZK29iTlBTMmJqKzJkZ0oKclYzVjVKanJ5NDJRT0NCTjNjODh3VTFQS2Z0T0xqMkVDcGV3WTZ2bkU0NzhJaXBpRXU3RUFkSzhad2oyTG1UcgpSS1FVU2E5azdnZ0JrWVpXQWVPLzJBZzBleTNnMmJnN2VxaytzSEVxNXluSVhkNWxodjZ0QzVQQmRIbFdpcERLCnRsMkl4aUVuZWpuT21BekdWaXZFMVlHZHVZQmpOK21qeERWeThLR0Jyam56MUpQZ0F2Z2R3SjJkWXc0UnNjL2UKVHpDRldHay9ITTZhNGYwSXpCV2JKNW90MFBJaTRhbWswN0lvdEJYRFd3cURpUVR3eXVHQ3ltNUVxV1EyQkQ5NQpSR3Y4OUJQRCsyRExuSnlzbmdzdlZhVUNBd0VBQVE9PQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0KVEFHU1BVQktFWQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHB1YmtleWlkID0gb3BlbnNzbF9wa2V5X2dldF9wdWJsaWMoJHNpZ0ZpbGUpOwogICAgICAgICAgICAkYWxnbyA9IGRlZmluZWQoJ09QRU5TU0xfQUxHT19TSEEzODQnKSA/IE9QRU5TU0xfQUxHT19TSEEzODQgOiAnU0hBMzg0JzsKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgnc2hhMzg0JywgYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgb3BlbnNzbF9nZXRfbWRfbWV0aG9kcygpKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignU0hBMzg0IGlzIG5vdCBzdXBwb3J0ZWQgYnkgeW91ciBvcGVuc3NsIGV4dGVuc2lvbiwgY291bGQgbm90IHZlcmlmeSB0aGUgcGhhciBmaWxlIGludGVncml0eScpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRzaWduYXR1cmUgPSBqc29uX2RlY29kZSgkc2lnbmF0dXJlLCB0cnVlKTsKICAgICAgICAgICAgJHNpZ25hdHVyZSA9IGJhc2U2NF9kZWNvZGUoJHNpZ25hdHVyZVsnc2hhMzg0J10pOwogICAgICAgICAgICAkdmVyaWZpZWQgPSAxID09PSBvcGVuc3NsX3ZlcmlmeShmaWxlX2dldF9jb250ZW50cygkdGVtcEZpbGVuYW1lKSwgJHNpZ25hdHVyZSwgJHB1YmtleWlkLCAkYWxnbyk7CgogICAgICAgICAgICAvLyBQSFAgOCBhdXRvbWF0aWNhbGx5IGZyZWVzIHRoZSBrZXkgaW5zdGFuY2UgYW5kIGRlcHJlY2F0ZXMgdGhlIGZ1bmN0aW9uCiAgICAgICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA8IDgwMDAwKSB7CiAgICAgICAgICAgICAgICBvcGVuc3NsX2ZyZWVfa2V5KCRwdWJrZXlpZCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJHZlcmlmaWVkKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBwaGFyIHNpZ25hdHVyZSBkaWQgbm90IG1hdGNoIHRoZSBmaWxlIHlvdSBkb3dubG9hZGVkLCB0aGlzIG1lYW5zIHlvdXIgcHVibGljIGtleXMgYXJlIG91dGRhdGVkIG9yIHRoYXQgdGhlIHBoYXIgZmlsZSBpcyBjb3JydXB0L2hhcyBiZWVuIG1vZGlmaWVkJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHJlbW92ZSBzYXZlZCBpbnN0YWxsYXRpb25zIG9mIGNvbXBvc2VyCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdjbGVhbi1iYWNrdXBzJykpIHsKICAgICAgICAgICAgJHRoaXMtPmNsZWFuQmFja3Vwcygkcm9sbGJhY2tEaXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+c2V0TG9jYWxQaGFyKCRsb2NhbEZpbGVuYW1lLCAkdGVtcEZpbGVuYW1lLCAkYmFja3VwRmlsZSkpIHsKICAgICAgICAgICAgQHVubGluaygkdGVtcEZpbGVuYW1lKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRiYWNrdXBGaWxlKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICdVc2UgPGluZm8+Y29tcG9zZXIgc2VsZi11cGRhdGUgLS1yb2xsYmFjazwvaW5mbz4gdG8gcmV0dXJuIHRvIHZlcnNpb24gPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywKICAgICAgICAgICAgICAgIENvbXBvc2VyOjpWRVJTSU9OCiAgICAgICAgICAgICkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QSBiYWNrdXAgb2YgdGhlIGN1cnJlbnQgdmVyc2lvbiBjb3VsZCBub3QgYmUgd3JpdHRlbiB0byAnLiRiYWNrdXBGaWxlLicsIG5vIHJvbGxiYWNrIHBvc3NpYmxlPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZmV0Y2hLZXlzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgaWYgKCEkaW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1B1YmxpYyBrZXlzIGNhbiBub3QgYmUgZmV0Y2hlZCBpbiBub24taW50ZXJhY3RpdmUgbW9kZSwgcGxlYXNlIHJ1biBDb21wb3NlciBpbnRlcmFjdGl2ZWx5Jyk7CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlKCdPcGVuIDxpbmZvPmh0dHBzOi8vY29tcG9zZXIuZ2l0aHViLmlvL3B1YmtleXMuaHRtbDwvaW5mbz4gdG8gZmluZCB0aGUgbGF0ZXN0IGtleXMnKTsKCiAgICAgICAgJHZhbGlkYXRvciA9IGZ1bmN0aW9uICgkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7Xi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tJH0nLCB0cmltKCR2YWx1ZSkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignSW52YWxpZCBpbnB1dCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJpbSgkdmFsdWUpLiJcbiI7CiAgICAgICAgfTsKCiAgICAgICAgJGRldktleSA9ICcnOwogICAgICAgIHdoaWxlICghUHJlZzo6aXNNYXRjaCgneygtLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLS4rPy0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSl9cycsICRkZXZLZXksICRtYXRjaCkpIHsKICAgICAgICAgICAgJGRldktleSA9ICRpby0+YXNrQW5kVmFsaWRhdGUoJ0VudGVyIERldiAvIFNuYXBzaG90IFB1YmxpYyBLZXkgKGluY2x1ZGluZyBsaW5lcyB3aXRoIC0tLS0tKTogJywgJHZhbGlkYXRvcik7CiAgICAgICAgICAgIHdoaWxlICgkbGluZSA9ICRpby0+YXNrKCcnKSkgewogICAgICAgICAgICAgICAgJGRldktleSAuPSB0cmltKCRsaW5lKS4iXG4iOwogICAgICAgICAgICAgICAgaWYgKHRyaW0oJGxpbmUpID09PSAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJykgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRrZXlQYXRoID0gJGNvbmZpZy0+Z2V0KCdob21lJykuJy9rZXlzLmRldi5wdWInLCAkbWF0Y2hbMF0pOwogICAgICAgICRpby0+d3JpdGUoJ1N0b3JlZCBrZXkgd2l0aCBmaW5nZXJwcmludDogJyAuIEtleXM6OmZpbmdlcnByaW50KCRrZXlQYXRoKSk7CgogICAgICAgICR0YWdzS2V5ID0gJyc7CiAgICAgICAgd2hpbGUgKCFQcmVnOjppc01hdGNoKCd7KC0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tLis/LS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tKX1zJywgJHRhZ3NLZXksICRtYXRjaCkpIHsKICAgICAgICAgICAgJHRhZ3NLZXkgPSAkaW8tPmFza0FuZFZhbGlkYXRlKCdFbnRlciBUYWdzIFB1YmxpYyBLZXkgKGluY2x1ZGluZyBsaW5lcyB3aXRoIC0tLS0tKTogJywgJHZhbGlkYXRvcik7CiAgICAgICAgICAgIHdoaWxlICgkbGluZSA9ICRpby0+YXNrKCcnKSkgewogICAgICAgICAgICAgICAgJHRhZ3NLZXkgLj0gdHJpbSgkbGluZSkuIlxuIjsKICAgICAgICAgICAgICAgIGlmICh0cmltKCRsaW5lKSA9PT0gJy0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLScpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmaWxlX3B1dF9jb250ZW50cygka2V5UGF0aCA9ICRjb25maWctPmdldCgnaG9tZScpLicva2V5cy50YWdzLnB1YicsICRtYXRjaFswXSk7CiAgICAgICAgJGlvLT53cml0ZSgnU3RvcmVkIGtleSB3aXRoIGZpbmdlcnByaW50OiAnIC4gS2V5czo6ZmluZ2VycHJpbnQoJGtleVBhdGgpKTsKCiAgICAgICAgJGlvLT53cml0ZSgnUHVibGljIGtleXMgc3RvcmVkIGluICcuJGNvbmZpZy0+Z2V0KCdob21lJykpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcm9sbGJhY2tEaXIKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxvY2FsRmlsZW5hbWUKICAgICAqIEByZXR1cm4gaW50CiAgICAgKiBAdGhyb3dzIEZpbGVzeXN0ZW1FeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJvbGxiYWNrKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkcm9sbGJhY2tEaXIsICRsb2NhbEZpbGVuYW1lKQogICAgewogICAgICAgICRyb2xsYmFja1ZlcnNpb24gPSAkdGhpcy0+Z2V0TGFzdEJhY2t1cFZlcnNpb24oJHJvbGxiYWNrRGlyKTsKICAgICAgICBpZiAoISRyb2xsYmFja1ZlcnNpb24pIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0NvbXBvc2VyIHJvbGxiYWNrIGZhaWxlZDogbm8gaW5zdGFsbGF0aW9uIHRvIHJvbGwgYmFjayB0byBpbiAiJy4kcm9sbGJhY2tEaXIuJyInKTsKICAgICAgICB9CgogICAgICAgICRvbGRGaWxlID0gJHJvbGxiYWNrRGlyIC4gJy8nIC4gJHJvbGxiYWNrVmVyc2lvbiAuIHNlbGY6Ok9MRF9JTlNUQUxMX0VYVDsKCiAgICAgICAgaWYgKCFpc19maWxlKCRvbGRGaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXN5c3RlbUV4Y2VwdGlvbignQ29tcG9zZXIgcm9sbGJhY2sgZmFpbGVkOiAiJy4kb2xkRmlsZS4nIiBjb3VsZCBub3QgYmUgZm91bmQnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFGaWxlc3lzdGVtOjppc1JlYWRhYmxlKCRvbGRGaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXN5c3RlbUV4Y2VwdGlvbignQ29tcG9zZXIgcm9sbGJhY2sgZmFpbGVkOiAiJy4kb2xkRmlsZS4nIiBjb3VsZCBub3QgYmUgcmVhZCcpOwogICAgICAgIH0KCiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoIlJvbGxpbmcgYmFjayB0byB2ZXJzaW9uIDxpbmZvPiVzPC9pbmZvPi4iLCAkcm9sbGJhY2tWZXJzaW9uKSk7CiAgICAgICAgaWYgKCEkdGhpcy0+c2V0TG9jYWxQaGFyKCRsb2NhbEZpbGVuYW1lLCAkb2xkRmlsZSkpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgZG93bmxvYWRlZC9yb2xsYmFjayBwaGFyIGlzIHZhbGlkIHRoZW4gbW92ZXMgaXQKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgJGxvY2FsRmlsZW5hbWUgVGhlIGNvbXBvc2VyLnBoYXIgbG9jYXRpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAkbmV3RmlsZW5hbWUgICBUaGUgZG93bmxvYWRlZCBvciBiYWNrdXAgcGhhcgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICRiYWNrdXBUYXJnZXQgIFRoZSBmaWxlbmFtZSB0byB1c2UgZm9yIHRoZSBiYWNrdXAKICAgICAqIEB0aHJvd3MgRmlsZXN5c3RlbUV4Y2VwdGlvbiBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgbW92ZWQKICAgICAqIEByZXR1cm4gYm9vbCAgICAgICAgICAgICAgICBXaGV0aGVyIHRoZSBwaGFyIGlzIHZhbGlkIGFuZCBoYXMgYmVlbiBtb3ZlZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0TG9jYWxQaGFyKCRsb2NhbEZpbGVuYW1lLCAkbmV3RmlsZW5hbWUsICRiYWNrdXBUYXJnZXQgPSBudWxsKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIEBjaG1vZCgkbmV3RmlsZW5hbWUsIGZpbGVwZXJtcygkbG9jYWxGaWxlbmFtZSkpOwoKICAgICAgICAvLyBjaGVjayBwaGFyIHZhbGlkaXR5CiAgICAgICAgaWYgKCEkdGhpcy0+dmFsaWRhdGVQaGFyKCRuZXdGaWxlbmFtZSwgJGVycm9yKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5UaGUgJy4oJGJhY2t1cFRhcmdldCA/ICd1cGRhdGUnIDogJ2JhY2t1cCcpLicgZmlsZSBpcyBjb3JydXB0ZWQgKCcuJGVycm9yLicpPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIGlmICgkYmFja3VwVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5QbGVhc2UgcmUtcnVuIHRoZSBzZWxmLXVwZGF0ZSBjb21tYW5kIHRvIHRyeSBhZ2Fpbi48L2Vycm9yPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBjb3B5IGN1cnJlbnQgZmlsZSBpbnRvIGJhY2t1cHMgZGlyCiAgICAgICAgaWYgKCRiYWNrdXBUYXJnZXQpIHsKICAgICAgICAgICAgQGNvcHkoJGxvY2FsRmlsZW5hbWUsICRiYWNrdXBUYXJnZXQpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgLy8gdXNlIGNvcHkgdG8gYXBwbHkgcGVybWlzc2lvbnMgZnJvbSB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5CiAgICAgICAgICAgICAgICAvLyBhcyByZW5hbWUgdXNlcyBzb3VyY2UgcGVybWlzc2lvbnMgYW5kIG1heSBibG9jayBvdGhlciB1c2VycwogICAgICAgICAgICAgICAgY29weSgkbmV3RmlsZW5hbWUsICRsb2NhbEZpbGVuYW1lKTsKICAgICAgICAgICAgICAgIEB1bmxpbmsoJG5ld0ZpbGVuYW1lKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlbmFtZSgkbmV3RmlsZW5hbWUsICRsb2NhbEZpbGVuYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAvLyBzZWUgaWYgd2UgY2FuIHJ1biB0aGlzIG9wZXJhdGlvbiBhcyBhbiBBZG1pbiBvbiBXaW5kb3dzCiAgICAgICAgICAgIGlmICghaXNfd3JpdGFibGUoZGlybmFtZSgkbG9jYWxGaWxlbmFtZSkpCiAgICAgICAgICAgICAgICAmJiAkaW8tPmlzSW50ZXJhY3RpdmUoKQogICAgICAgICAgICAgICAgJiYgJHRoaXMtPmlzV2luZG93c05vbkFkbWluVXNlcigpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnRyeUFzV2luZG93c0FkbWluKCRsb2NhbEZpbGVuYW1lLCAkbmV3RmlsZW5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAdW5saW5rKCRuZXdGaWxlbmFtZSk7CiAgICAgICAgICAgICRhY3Rpb24gPSAnQ29tcG9zZXIgJy4oJGJhY2t1cFRhcmdldCA/ICd1cGRhdGUnIDogJ3JvbGxiYWNrJyk7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlc3lzdGVtRXhjZXB0aW9uKCRhY3Rpb24uJyBmYWlsZWQ6ICInLiRsb2NhbEZpbGVuYW1lLiciIGNvdWxkIG5vdCBiZSB3cml0dGVuLicuUEhQX0VPTC4kZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyb2xsYmFja0RpcgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRleGNlcHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNsZWFuQmFja3Vwcygkcm9sbGJhY2tEaXIsICRleGNlcHQgPSBudWxsKQogICAgewogICAgICAgICRmaW5kZXIgPSAkdGhpcy0+Z2V0T2xkSW5zdGFsbGF0aW9uRmluZGVyKCRyb2xsYmFja0Rpcik7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW07CgogICAgICAgIGZvcmVhY2ggKCRmaW5kZXIgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKCRleGNlcHQgJiYgJGZpbGUtPmdldEJhc2VuYW1lKHNlbGY6Ok9MRF9JTlNUQUxMX0VYVCkgPT09ICRleGNlcHQpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRmaWxlID0gKHN0cmluZykgJGZpbGU7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+UmVtb3Zpbmc6ICcuJGZpbGUuJzwvaW5mbz4nKTsKICAgICAgICAgICAgJGZzLT5yZW1vdmUoJGZpbGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJvbGxiYWNrRGlyCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TGFzdEJhY2t1cFZlcnNpb24oJHJvbGxiYWNrRGlyKQogICAgewogICAgICAgICRmaW5kZXIgPSAkdGhpcy0+Z2V0T2xkSW5zdGFsbGF0aW9uRmluZGVyKCRyb2xsYmFja0Rpcik7CiAgICAgICAgJGZpbmRlci0+c29ydEJ5TmFtZSgpOwogICAgICAgICRmaWxlcyA9IGl0ZXJhdG9yX3RvX2FycmF5KCRmaW5kZXIpOwoKICAgICAgICBpZiAoY291bnQoJGZpbGVzKSkgewogICAgICAgICAgICByZXR1cm4gYmFzZW5hbWUoZW5kKCRmaWxlcyksIHNlbGY6Ok9MRF9JTlNUQUxMX0VYVCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyb2xsYmFja0RpcgogICAgICogQHJldHVybiBGaW5kZXIKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldE9sZEluc3RhbGxhdGlvbkZpbmRlcigkcm9sbGJhY2tEaXIpCiAgICB7CiAgICAgICAgcmV0dXJuIEZpbmRlcjo6Y3JlYXRlKCkKICAgICAgICAgICAgLT5kZXB0aCgwKQogICAgICAgICAgICAtPmZpbGVzKCkKICAgICAgICAgICAgLT5uYW1lKCcqJyAuIHNlbGY6Ok9MRF9JTlNUQUxMX0VYVCkKICAgICAgICAgICAgLT5pbigkcm9sbGJhY2tEaXIpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBkb3dubG9hZGVkL2JhY2t1cCBwaGFyIGZpbGUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHBoYXJGaWxlIFRoZSBkb3dubG9hZGVkIG9yIGJhY2t1cCBwaGFyCiAgICAgKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGVycm9yICAgIFNldCBieSBtZXRob2Qgb24gZmFpbHVyZQogICAgICoKICAgICAqIENvZGUgdGFrZW4gZnJvbSBnZXRjb21wb3Nlci5vcmcvaW5zdGFsbGVyLiBBbnkgY2hhbmdlcyBzaG91bGQgYmUgbWFkZQogICAgICogdGhlcmUgYW5kIHJlcGxpY2F0ZWQgaGVyZQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sICAgICAgIElmIHRoZSBvcGVyYXRpb24gc3VjY2VlZGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZVBoYXIoJHBoYXJGaWxlLCAmJGVycm9yKQogICAgewogICAgICAgIGlmIChpbmlfZ2V0KCdwaGFyLnJlYWRvbmx5JykpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBUZXN0IHRoZSBwaGFyIHZhbGlkaXR5CiAgICAgICAgICAgICRwaGFyID0gbmV3IFxQaGFyKCRwaGFyRmlsZSk7CiAgICAgICAgICAgIC8vIEZyZWUgdGhlIHZhcmlhYmxlIHRvIHVubG9jayB0aGUgZmlsZQogICAgICAgICAgICB1bnNldCgkcGhhcik7CiAgICAgICAgICAgICRyZXN1bHQgPSB0cnVlOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkZSBpbnN0YW5jZW9mIFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gJiYgISRlIGluc3RhbmNlb2YgXFBoYXJFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRlcnJvciA9ICRlLT5nZXRNZXNzYWdlKCk7CiAgICAgICAgICAgICRyZXN1bHQgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBub24tYWRtaW4gV2luZG93cyB1c2VyIGFjY291bnQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzV2luZG93c05vbkFkbWluVXNlcigpCiAgICB7CiAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gZmx0bWMuZXhlIG1hbmFnZXMgZmlsdGVyIGRyaXZlcnMgYW5kIGVycm9ycyB3aXRob3V0IGFkbWluIHByaXZpbGVnZXMKICAgICAgICBleGVjKCdmbHRtYy5leGUgZmlsdGVycycsICRvdXRwdXQsICRleGl0Q29kZSk7CgogICAgICAgIHJldHVybiAkZXhpdENvZGUgIT09IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnZva2VzIGEgVUFDIHByb21wdCB0byB1cGRhdGUgY29tcG9zZXIucGhhciBhcyBhbiBhZG1pbgogICAgICoKICAgICAqIFVzZXMgYSAudmJzIHNjcmlwdCB0byBlbGV2YXRlIGFuZCBydW4gdGhlIGNtZC5leGUgY29weSBjb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRsb2NhbEZpbGVuYW1lIFRoZSBjb21wb3Nlci5waGFyIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmV3RmlsZW5hbWUgICBUaGUgZG93bmxvYWRlZCBvciBiYWNrdXAgcGhhcgogICAgICogQHJldHVybiBib29sICAgV2hldGhlciBjb21wb3Nlci5waGFyIGhhcyBiZWVuIHVwZGF0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHRyeUFzV2luZG93c0FkbWluKCRsb2NhbEZpbGVuYW1lLCAkbmV3RmlsZW5hbWUpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPlVuYWJsZSB0byB3cml0ZSAiJy4kbG9jYWxGaWxlbmFtZS4nIi4gQWNjZXNzIGlzIGRlbmllZC48L2Vycm9yPicpOwogICAgICAgICRoZWxwTWVzc2FnZSA9ICdQbGVhc2UgcnVuIHRoZSBzZWxmLXVwZGF0ZSBjb21tYW5kIGFzIGFuIEFkbWluaXN0cmF0b3IuJzsKICAgICAgICAkcXVlc3Rpb24gPSAnQ29tcGxldGUgdGhpcyBvcGVyYXRpb24gd2l0aCBBZG1pbmlzdHJhdG9yIHByaXZpbGVnZXMgWzxjb21tZW50PlksbjwvY29tbWVudD5dPyAnOwoKICAgICAgICBpZiAoISRpby0+YXNrQ29uZmlybWF0aW9uKCRxdWVzdGlvbiwgZmFsc2UpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+T3BlcmF0aW9uIGNhbmNlbGxlZC4gJy4kaGVscE1lc3NhZ2UuJzwvd2FybmluZz4nKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICR0bXBGaWxlID0gdGVtcG5hbShzeXNfZ2V0X3RlbXBfZGlyKCksICcnKTsKICAgICAgICAkc2NyaXB0ID0gJHRtcEZpbGUuJy52YnMnOwogICAgICAgIHJlbmFtZSgkdG1wRmlsZSwgJHNjcmlwdCk7CgogICAgICAgICRjaGVja3N1bSA9IGhhc2hfZmlsZSgnc2hhMjU2JywgJG5ld0ZpbGVuYW1lKTsKCiAgICAgICAgLy8gY21kJ3MgaW50ZXJuYWwgY29weSBpcyBmdXNzeSBhYm91dCBiYWNrc2xhc2hlcwogICAgICAgICRzb3VyY2UgPSBzdHJfcmVwbGFjZSgnLycsICdcXCcsICRuZXdGaWxlbmFtZSk7CiAgICAgICAgJGRlc3RpbmF0aW9uID0gc3RyX3JlcGxhY2UoJy8nLCAnXFwnLCAkbG9jYWxGaWxlbmFtZSk7CgogICAgICAgICR2YnMgPSA8PDxFT1QKU2V0IFVBQyA9IENyZWF0ZU9iamVjdCgiU2hlbGwuQXBwbGljYXRpb24iKQpVQUMuU2hlbGxFeGVjdXRlICJjbWQuZXhlIiwgIi9jIGNvcHkgL2IgL3kgIiIkc291cmNlIiIgIiIkZGVzdGluYXRpb24iIiIsICIiLCAicnVuYXMiLCAwCldzY3JpcHQuU2xlZXAoMzAwKQpFT1Q7CgogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRzY3JpcHQsICR2YnMpOwogICAgICAgIGV4ZWMoJyInLiRzY3JpcHQuJyInKTsKICAgICAgICBAdW5saW5rKCRzY3JpcHQpOwoKICAgICAgICAvLyBzZWUgaWYgdGhlIGZpbGUgd2FzIGNvcGllZCBhbmQgaXMgc3RpbGwgYWNjZXNzaWJsZQogICAgICAgIGlmICgkcmVzdWx0ID0gRmlsZXN5c3RlbTo6aXNSZWFkYWJsZSgkbG9jYWxGaWxlbmFtZSkgJiYgKGhhc2hfZmlsZSgnc2hhMjU2JywgJGxvY2FsRmlsZW5hbWUpID09PSAkY2hlY2tzdW0pKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+T3BlcmF0aW9uIHN1Y2NlZWRlZC48L2luZm8+Jyk7CiAgICAgICAgICAgIEB1bmxpbmsoJG5ld0ZpbGVuYW1lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5PcGVyYXRpb24gZmFpbGVkLicuJGhlbHBNZXNzYWdlLic8L2Vycm9yPicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUm9vdFBhY2thZ2VSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJTdHlsZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBCYXNlIGltcGxlbWVudGF0aW9uIGZvciBjb21tYW5kcyBtYXBwaW5nIGRlcGVuZGVuY3kgcmVsYXRpb25zaGlwcy4KICoKICogQGF1dGhvciBOaWVscyBLZXVyZW50amVzIDxuaWVscy5rZXVyZW50amVzQG9taW5lcy5jb20+CiAqLwpjbGFzcyBCYXNlRGVwZW5kZW5jeUNvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBjb25zdCBBUkdVTUVOVF9QQUNLQUdFID0gJ3BhY2thZ2UnOwogICAgY29uc3QgQVJHVU1FTlRfQ09OU1RSQUlOVCA9ICd2ZXJzaW9uJzsKICAgIGNvbnN0IE9QVElPTl9SRUNVUlNJVkUgPSAncmVjdXJzaXZlJzsKICAgIGNvbnN0IE9QVElPTl9UUkVFID0gJ3RyZWUnOwoKICAgIC8qKiBAdmFyID9zdHJpbmdbXSAqLwogICAgcHJvdGVjdGVkICRjb2xvcnM7CgogICAgLyoqCiAgICAgKiBFeGVjdXRlIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICRpbnZlcnRlZCBXaGV0aGVyIHRvIGludmVydCBtYXRjaGluZyBwcm9jZXNzICh3aHktbm90IHZzIHdoeSBiZWhhdmlvdXIpCiAgICAgKiBAcmV0dXJuIGludCAgICAgICAgICAgICBFeGl0IGNvZGUgb2YgdGhlIG9wZXJhdGlvbi4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkaW52ZXJ0ZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBFbWl0IGNvbW1hbmQgZXZlbnQgb24gc3RhcnR1cAogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJHRoaXMtPmdldE5hbWUoKSwgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaCgkY29tbWFuZEV2ZW50LT5nZXROYW1lKCksICRjb21tYW5kRXZlbnQpOwoKICAgICAgICAkcGxhdGZvcm1PdmVycmlkZXMgPSAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKTsKICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KAogICAgICAgICAgICBuZXcgUm9vdFBhY2thZ2VSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UGFja2FnZSgpKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSwKICAgICAgICAgICAgbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkcGxhdGZvcm1PdmVycmlkZXMpLAogICAgICAgICkpOwoKICAgICAgICAvLyBQYXJzZSBwYWNrYWdlIG5hbWUgYW5kIGNvbnN0cmFpbnQKICAgICAgICBsaXN0KCRuZWVkbGUsICR0ZXh0Q29uc3RyYWludCkgPSBhcnJheV9wYWQoCiAgICAgICAgICAgIGV4cGxvZGUoJzonLCAkaW5wdXQtPmdldEFyZ3VtZW50KHNlbGY6OkFSR1VNRU5UX1BBQ0tBR0UpKSwKICAgICAgICAgICAgMiwKICAgICAgICAgICAgJGlucHV0LT5oYXNBcmd1bWVudChzZWxmOjpBUkdVTUVOVF9DT05TVFJBSU5UKSA/ICRpbnB1dC0+Z2V0QXJndW1lbnQoc2VsZjo6QVJHVU1FTlRfQ09OU1RSQUlOVCkgOiAnKicKICAgICAgICApOwoKICAgICAgICAvLyBGaW5kIHBhY2thZ2VzIHRoYXQgYXJlIG9yIHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBwYWNrYWdlIGZpcnN0CiAgICAgICAgJHBhY2thZ2VzID0gJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMoJG5lZWRsZSk7CiAgICAgICAgaWYgKGVtcHR5KCRwYWNrYWdlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQ291bGQgbm90IGZpbmQgcGFja2FnZSAiJXMiIGluIHlvdXIgcHJvamVjdCcsICRuZWVkbGUpKTsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZSB2ZXJzaW9uIHdlIGFzayBmb3IgaXMgbm90IGluc3RhbGxlZCB0aGVuIHdlIG5lZWQgdG8gbG9jYXRlIGl0IGluIHJlbW90ZSByZXBvcyBhbmQgYWRkIGl0LgogICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGZvciB3aHktbm90IHRvIHJlc29sdmUgY29uZmxpY3RzIGZyb20gYW4gdW5pbnN0YWxsZWQgdmVyc2lvbiBhZ2FpbnN0IGluc3RhbGxlZCBwYWNrYWdlcy4KICAgICAgICBpZiAoISRpbnN0YWxsZWRSZXBvLT5maW5kUGFja2FnZSgkbmVlZGxlLCAkdGV4dENvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICRkZWZhdWx0UmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKCR0aGlzLT5nZXRJTygpKSk7CiAgICAgICAgICAgIGlmICgkbWF0Y2ggPSAkZGVmYXVsdFJlcG9zLT5maW5kUGFja2FnZSgkbmVlZGxlLCAkdGV4dENvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVkUmVwby0+YWRkUmVwb3NpdG9yeShuZXcgSW5zdGFsbGVkQXJyYXlSZXBvc2l0b3J5KGFycmF5KGNsb25lICRtYXRjaCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSW5jbHVkZSByZXBsYWNlZCBwYWNrYWdlcyBmb3IgaW52ZXJ0ZWQgbG9va3VwcyBhcyB0aGV5IGFyZSB0aGVuIHRoZSBhY3R1YWwgc3RhcnRpbmcgcG9pbnQgdG8gY29uc2lkZXIKICAgICAgICAkbmVlZGxlcyA9IGFycmF5KCRuZWVkbGUpOwogICAgICAgIGlmICgkaW52ZXJ0ZWQpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkbmVlZGxlcyA9IGFycmF5X21lcmdlKCRuZWVkbGVzLCBhcnJheV9tYXAoZnVuY3Rpb24gKExpbmsgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICAgICAgfSwgJHBhY2thZ2UtPmdldFJlcGxhY2VzKCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUGFyc2UgY29uc3RyYWludCBpZiBvbmUgd2FzIHN1cHBsaWVkCiAgICAgICAgaWYgKCcqJyAhPT0gJHRleHRDb25zdHJhaW50KSB7CiAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkdGV4dENvbnN0cmFpbnQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb25zdHJhaW50ID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIFBhcnNlIHJlbmRlcmluZyBvcHRpb25zCiAgICAgICAgJHJlbmRlclRyZWUgPSAkaW5wdXQtPmdldE9wdGlvbihzZWxmOjpPUFRJT05fVFJFRSk7CiAgICAgICAgJHJlY3Vyc2l2ZSA9ICRyZW5kZXJUcmVlIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKHNlbGY6Ok9QVElPTl9SRUNVUlNJVkUpOwoKICAgICAgICAvLyBSZXNvbHZlIGRlcGVuZGVuY2llcwogICAgICAgICRyZXN1bHRzID0gJGluc3RhbGxlZFJlcG8tPmdldERlcGVuZGVudHMoJG5lZWRsZXMsICRjb25zdHJhaW50LCAkaW52ZXJ0ZWQsICRyZWN1cnNpdmUpOwogICAgICAgIGlmIChlbXB0eSgkcmVzdWx0cykpIHsKICAgICAgICAgICAgJGV4dHJhID0gKG51bGwgIT09ICRjb25zdHJhaW50KSA/IHNwcmludGYoJyBpbiB2ZXJzaW9ucyAlc21hdGNoaW5nICVzJywgJGludmVydGVkID8gJ25vdCAnIDogJycsICR0ZXh0Q29uc3RyYWludCkgOiAnJzsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICc8aW5mbz5UaGVyZSBpcyBubyBpbnN0YWxsZWQgcGFja2FnZSBkZXBlbmRpbmcgb24gIiVzIiVzPC9pbmZvPicsCiAgICAgICAgICAgICAgICAkbmVlZGxlLAogICAgICAgICAgICAgICAgJGV4dHJhCiAgICAgICAgICAgICkpOwogICAgICAgIH0gZWxzZWlmICgkcmVuZGVyVHJlZSkgewogICAgICAgICAgICAkdGhpcy0+aW5pdFN0eWxlcygkb3V0cHV0KTsKICAgICAgICAgICAgJHJvb3QgPSAkcGFja2FnZXNbMF07CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZShzcHJpbnRmKCc8aW5mbz4lczwvaW5mbz4gJXMgJXMnLCAkcm9vdC0+Z2V0UHJldHR5TmFtZSgpLCAkcm9vdC0+Z2V0UHJldHR5VmVyc2lvbigpLCAkcm9vdCBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSA/ICRyb290LT5nZXREZXNjcmlwdGlvbigpIDogJycpKTsKICAgICAgICAgICAgJHRoaXMtPnByaW50VHJlZSgkcmVzdWx0cyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnByaW50VGFibGUoJG91dHB1dCwgJHJlc3VsdHMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBBc3NlbWJsZXMgYW5kIHByaW50cyBhIGJvdHRvbS11cCB0YWJsZSBvZiB0aGUgZGVwZW5kZW5jaWVzLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheXtQYWNrYWdlSW50ZXJmYWNlLCBMaW5rLCBtaXhlZH1bXSAkcmVzdWx0cwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJpbnRUYWJsZShPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJHJlc3VsdHMpCiAgICB7CiAgICAgICAgJHRhYmxlID0gYXJyYXkoKTsKICAgICAgICAkZG91YmxlcyA9IGFycmF5KCk7CiAgICAgICAgZG8gewogICAgICAgICAgICAkcXVldWUgPSBhcnJheSgpOwogICAgICAgICAgICAkcm93cyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXN1bHRzIGFzICRyZXN1bHQpIHsKICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogQHZhciBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgICAgICAgICAgICAgKiBAdmFyIExpbmsgICAgICAgICAgICAgJGxpbmsKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbGlzdCgkcGFja2FnZSwgJGxpbmssICRjaGlsZHJlbikgPSAkcmVzdWx0OwogICAgICAgICAgICAgICAgJHVuaXF1ZSA9IChzdHJpbmcpICRsaW5rOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRkb3VibGVzWyR1bmlxdWVdKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGRvdWJsZXNbJHVuaXF1ZV0gPSB0cnVlOwogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpID09PSBSb290UGFja2FnZTo6REVGQVVMVF9QUkVUVFlfVkVSU0lPTiA/ICctJyA6ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAkcm93c1tdID0gYXJyYXkoJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJHZlcnNpb24sICRsaW5rLT5nZXREZXNjcmlwdGlvbigpLCBzcHJpbnRmKCclcyAoJXMpJywgJGxpbmstPmdldFRhcmdldCgpLCAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpKSk7CiAgICAgICAgICAgICAgICBpZiAoJGNoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICAgICAgJHF1ZXVlID0gYXJyYXlfbWVyZ2UoJHF1ZXVlLCAkY2hpbGRyZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXN1bHRzID0gJHF1ZXVlOwogICAgICAgICAgICAkdGFibGUgPSBhcnJheV9tZXJnZSgkcm93cywgJHRhYmxlKTsKICAgICAgICB9IHdoaWxlICghZW1wdHkoJHJlc3VsdHMpKTsKCiAgICAgICAgJHRoaXMtPnJlbmRlclRhYmxlKCR0YWJsZSwgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0IHN0eWxlcyBmb3IgdHJlZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdFN0eWxlcyhPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29sb3JzID0gYXJyYXkoCiAgICAgICAgICAgICdncmVlbicsCiAgICAgICAgICAgICd5ZWxsb3cnLAogICAgICAgICAgICAnY3lhbicsCiAgICAgICAgICAgICdtYWdlbnRhJywKICAgICAgICAgICAgJ2JsdWUnLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb2xvcnMgYXMgJGNvbG9yKSB7CiAgICAgICAgICAgICRzdHlsZSA9IG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgkY29sb3IpOwogICAgICAgICAgICAkb3V0cHV0LT5nZXRGb3JtYXR0ZXIoKS0+c2V0U3R5bGUoJGNvbG9yLCAkc3R5bGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlY3Vyc2l2ZWx5IHByaW50cyBhIHRyZWUgb2YgdGhlIHNlbGVjdGVkIHJlc3VsdHMuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5e1BhY2thZ2VJbnRlcmZhY2UsIExpbmssIG1peGVkW118Ym9vbH1bXSAkcmVzdWx0cyBSZXN1bHRzIHRvIGJlIHByaW50ZWQgYXQgdGhpcyBsZXZlbC4KICAgICAqIEBwYXJhbSBzdHJpbmcgICRwcmVmaXggIFByZWZpeCBvZiB0aGUgY3VycmVudCB0cmVlIGxldmVsLgogICAgICogQHBhcmFtIGludCAgICAgJGxldmVsICAgQ3VycmVudCBsZXZlbCBvZiByZWN1cnNpb24uCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFRyZWUoJHJlc3VsdHMsICRwcmVmaXggPSAnJywgJGxldmVsID0gMSkKICAgIHsKICAgICAgICAkY291bnQgPSBjb3VudCgkcmVzdWx0cyk7CiAgICAgICAgJGlkeCA9IDA7CiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICBsaXN0KCRwYWNrYWdlLCAkbGluaywgJGNoaWxkcmVuKSA9ICRyZXN1bHQ7CgogICAgICAgICAgICAkY29sb3IgPSAkdGhpcy0+Y29sb3JzWyRsZXZlbCAlIGNvdW50KCR0aGlzLT5jb2xvcnMpXTsKICAgICAgICAgICAgJHByZXZDb2xvciA9ICR0aGlzLT5jb2xvcnNbKCRsZXZlbCAtIDEpICUgY291bnQoJHRoaXMtPmNvbG9ycyldOwogICAgICAgICAgICAkaXNMYXN0ID0gKCsrJGlkeCA9PSAkY291bnQpOwogICAgICAgICAgICAkdmVyc2lvblRleHQgPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpID09PSBSb290UGFja2FnZTo6REVGQVVMVF9QUkVUVFlfVkVSU0lPTiA/ICcnIDogJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgJHBhY2thZ2VUZXh0ID0gcnRyaW0oc3ByaW50ZignPCVzPiVzPC8lMSRzPiAlcycsICRjb2xvciwgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJHZlcnNpb25UZXh0KSk7CiAgICAgICAgICAgICRsaW5rVGV4dCA9IHNwcmludGYoJyVzIDwlcz4lczwvJTIkcz4gJXMnLCAkbGluay0+Z2V0RGVzY3JpcHRpb24oKSwgJHByZXZDb2xvciwgJGxpbmstPmdldFRhcmdldCgpLCAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpKTsKICAgICAgICAgICAgJGNpcmN1bGFyV2FybiA9ICRjaGlsZHJlbiA9PT0gZmFsc2UgPyAnKGNpcmN1bGFyIGRlcGVuZGVuY3kgYWJvcnRlZCBoZXJlKScgOiAnJzsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVHJlZUxpbmUocnRyaW0oc3ByaW50ZigiJXMlcyVzICglcykgJXMiLCAkcHJlZml4LCAkaXNMYXN0ID8gJ+KUlOKUgOKUgCcgOiAn4pSc4pSA4pSAJywgJHBhY2thZ2VUZXh0LCAkbGlua1RleHQsICRjaXJjdWxhcldhcm4pKSk7CiAgICAgICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcmludFRyZWUoJGNoaWxkcmVuLCAkcHJlZml4IC4gKCRpc0xhc3QgPyAnICAgJyA6ICfilIIgICcpLCAkbGV2ZWwgKyAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZVRyZWVMaW5lKCRsaW5lKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGlmICghJGlvLT5pc0RlY29yYXRlZCgpKSB7CiAgICAgICAgICAgICRsaW5lID0gc3RyX3JlcGxhY2UoYXJyYXkoJ+KUlCcsICfilJwnLCAn4pSA4pSAJywgJ+KUgicpLCBhcnJheSgnYC0nLCAnfC0nLCAnLScsICd8JyksICRsaW5lKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoJGxpbmUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgpjbGFzcyBTdWdnZXN0c0NvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3N1Z2dlc3RzJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3MgcGFja2FnZSBzdWdnZXN0aW9ucy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2J5LXBhY2thZ2UnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0dyb3VwcyBvdXRwdXQgYnkgc3VnZ2VzdGluZyBwYWNrYWdlIChkZWZhdWx0KScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdieS1zdWdnZXN0aW9uJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdHcm91cHMgb3V0cHV0IGJ5IHN1Z2dlc3RlZCBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FsbCcsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IHN1Z2dlc3Rpb25zIGZyb20gYWxsIGRlcGVuZGVuY2llcywgaW5jbHVkaW5nIHRyYW5zaXRpdmUgb25lcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IG9ubHkgbGlzdCBvZiBzdWdnZXN0ZWQgcGFja2FnZSBuYW1lcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0V4Y2x1ZGUgc3VnZ2VzdGlvbnMgZnJvbSByZXF1aXJlLWRldiBwYWNrYWdlcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2VzJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2VzIHRoYXQgeW91IHdhbnQgdG8gbGlzdCBzdWdnZXN0aW9ucyBmcm9tLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKClRoZSA8aW5mbz4lY29tbWFuZC5uYW1lJTwvaW5mbz4gY29tbWFuZCBzaG93cyBhIHNvcnRlZCBsaXN0IG9mIHN1Z2dlc3RlZCBwYWNrYWdlcy4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3N1Z2dlc3RzCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKCiAgICAgICAgJGluc3RhbGxlZFJlcG9zID0gYXJyYXkoCiAgICAgICAgICAgIG5ldyBSb290UGFja2FnZVJlcG9zaXRvcnkoY2xvbmUgJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCkpLAogICAgICAgICk7CgogICAgICAgICRsb2NrZXIgPSAkY29tcG9zZXItPmdldExvY2tlcigpOwogICAgICAgIGlmICgkbG9ja2VyLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvc1tdID0gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkbG9ja2VyLT5nZXRQbGF0Zm9ybU92ZXJyaWRlcygpKTsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG9zW10gPSAkbG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvc1tdID0gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKSk7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvc1tdID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICB9CgogICAgICAgICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoJGluc3RhbGxlZFJlcG9zKTsKICAgICAgICAkcmVwb3J0ZXIgPSBuZXcgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcigkdGhpcy0+Z2V0SU8oKSk7CgogICAgICAgICRmaWx0ZXIgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlcycpOwogICAgICAgICRwYWNrYWdlcyA9ICRpbnN0YWxsZWRSZXBvLT5nZXRQYWNrYWdlcygpOwogICAgICAgICRwYWNrYWdlc1tdID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJGZpbHRlcikgJiYgIWluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRmaWx0ZXIpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlcG9ydGVyLT5hZGRTdWdnZXN0aW9uc0Zyb21QYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICB9CgogICAgICAgIC8vIERldGVybWluZSBvdXRwdXQgbW9kZSwgZGVmYXVsdCBpcyBieS1wYWNrYWdlCiAgICAgICAgJG1vZGUgPSBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOjpNT0RFX0JZX1BBQ0tBR0U7CgogICAgICAgIC8vIGlmIGJ5LXN1Z2dlc3Rpb24gaXMgZ2l2ZW4gd2Ugb3ZlcnJpZGUgdGhlIGRlZmF1bHQKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2J5LXN1Z2dlc3Rpb24nKSkgewogICAgICAgICAgICAkbW9kZSA9IFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI6Ok1PREVfQllfU1VHR0VTVElPTjsKICAgICAgICB9CiAgICAgICAgLy8gdW5sZXNzIGJ5LXBhY2thZ2UgaXMgYWxzbyBwcmVzZW50IHRoZW4gd2UgZW5hYmxlIGJvdGgKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2J5LXBhY2thZ2UnKSkgewogICAgICAgICAgICAkbW9kZSB8PSBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOjpNT0RFX0JZX1BBQ0tBR0U7CiAgICAgICAgfQogICAgICAgIC8vIGxpc3QgaXMgZXhjbHVzaXZlIGFuZCBvdmVycmlkZXMgZXZlcnl0aGluZyBlbHNlCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdsaXN0JykpIHsKICAgICAgICAgICAgJG1vZGUgPSBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOjpNT0RFX0xJU1Q7CiAgICAgICAgfQoKICAgICAgICAkcmVwb3J0ZXItPm91dHB1dCgkbW9kZSwgJGluc3RhbGxlZFJlcG8sIGVtcHR5KCRmaWx0ZXIpICYmICEkaW5wdXQtPmdldE9wdGlvbignYWxsJykgPyAkY29tcG9zZXItPmdldFBhY2thZ2UoKSA6IG51bGwpOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXFZhbGlkYXRpbmdBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBsdWdpblxDb21tYW5kRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxVdGlsXENvbmZpZ1ZhbGlkYXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIFZhbGlkYXRlQ29tbWFuZAogKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVmFsaWRhdGVDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBjb25maWd1cmUKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3ZhbGlkYXRlJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignVmFsaWRhdGVzIGEgY29tcG9zZXIuanNvbiBhbmQgY29tcG9zZXIubG9jay4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWNoZWNrLWFsbCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IHZhbGlkYXRlIHJlcXVpcmVzIGZvciBvdmVybHkgc3RyaWN0L2xvb3NlIGNvbnN0cmFpbnRzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWNoZWNrLWxvY2snLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCBjaGVjayBpZiBsb2NrIGZpbGUgaXMgdXAgdG8gZGF0ZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1jaGVjay1wdWJsaXNoJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3QgY2hlY2sgZm9yIHB1Ymxpc2ggZXJyb3JzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWNoZWNrLXZlcnNpb24nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCByZXBvcnQgYSB3YXJuaW5nIGlmIHRoZSB2ZXJzaW9uIGZpZWxkIGlzIHByZXNlbnQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignd2l0aC1kZXBlbmRlbmNpZXMnLCAnQScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxzbyB2YWxpZGF0ZSB0aGUgY29tcG9zZXIuanNvbiBvZiBhbGwgaW5zdGFsbGVkIGRlcGVuZGVuY2llcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzdHJpY3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JldHVybiBhIG5vbi16ZXJvIGV4aXQgY29kZSBmb3Igd2FybmluZ3MgYXMgd2VsbCBhcyBlcnJvcnMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdmaWxlJywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdwYXRoIHRvIGNvbXBvc2VyLmpzb24gZmlsZScpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIHZhbGlkYXRlIGNvbW1hbmQgdmFsaWRhdGVzIGEgZ2l2ZW4gY29tcG9zZXIuanNvbiBhbmQgY29tcG9zZXIubG9jawoKRXhpdCBjb2RlcyBpbiBjYXNlIG9mIGVycm9ycyBhcmU6CjEgdmFsaWRhdGlvbiB3YXJuaW5nKHMpLCBvbmx5IHdoZW4gLS1zdHJpY3QgaXMgZ2l2ZW4KMiB2YWxpZGF0aW9uIGVycm9yKHMpCjMgZmlsZSB1bnJlYWRhYmxlIG9yIG1pc3NpbmcKClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3ZhbGlkYXRlCkVPVAogICAgICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkZmlsZSA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ2ZpbGUnKSA/OiBGYWN0b3J5OjpnZXRDb21wb3NlckZpbGUoKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkZmlsZSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+JyAuICRmaWxlIC4gJyBub3QgZm91bmQuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiAzOwogICAgICAgIH0KICAgICAgICBpZiAoIUZpbGVzeXN0ZW06OmlzUmVhZGFibGUoJGZpbGUpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPicgLiAkZmlsZSAuICcgaXMgbm90IHJlYWRhYmxlLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMzsKICAgICAgICB9CgogICAgICAgICR2YWxpZGF0b3IgPSBuZXcgQ29uZmlnVmFsaWRhdG9yKCRpbyk7CiAgICAgICAgJGNoZWNrQWxsID0gJGlucHV0LT5nZXRPcHRpb24oJ25vLWNoZWNrLWFsbCcpID8gMCA6IFZhbGlkYXRpbmdBcnJheUxvYWRlcjo6Q0hFQ0tfQUxMOwogICAgICAgICRjaGVja1B1Ymxpc2ggPSAhJGlucHV0LT5nZXRPcHRpb24oJ25vLWNoZWNrLXB1Ymxpc2gnKTsKICAgICAgICAkY2hlY2tMb2NrID0gISRpbnB1dC0+Z2V0T3B0aW9uKCduby1jaGVjay1sb2NrJyk7CiAgICAgICAgJGNoZWNrVmVyc2lvbiA9ICRpbnB1dC0+Z2V0T3B0aW9uKCduby1jaGVjay12ZXJzaW9uJykgPyAwIDogQ29uZmlnVmFsaWRhdG9yOjpDSEVDS19WRVJTSU9OOwogICAgICAgICRpc1N0cmljdCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdzdHJpY3QnKTsKICAgICAgICBsaXN0KCRlcnJvcnMsICRwdWJsaXNoRXJyb3JzLCAkd2FybmluZ3MpID0gJHZhbGlkYXRvci0+dmFsaWRhdGUoJGZpbGUsICRjaGVja0FsbCwgJGNoZWNrVmVyc2lvbik7CgogICAgICAgICRsb2NrRXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGUoJGlvLCAkZmlsZSwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tbm8tcGx1Z2lucycpKTsKICAgICAgICAkbG9ja2VyID0gJGNvbXBvc2VyLT5nZXRMb2NrZXIoKTsKICAgICAgICBpZiAoJGxvY2tlci0+aXNMb2NrZWQoKSAmJiAhJGxvY2tlci0+aXNGcmVzaCgpKSB7CiAgICAgICAgICAgICRsb2NrRXJyb3JzW10gPSAnLSBUaGUgbG9jayBmaWxlIGlzIG5vdCB1cCB0byBkYXRlIHdpdGggdGhlIGxhdGVzdCBjaGFuZ2VzIGluIGNvbXBvc2VyLmpzb24sIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgeW91IHJ1biBgY29tcG9zZXIgdXBkYXRlYCBvciBgY29tcG9zZXIgdXBkYXRlIDxwYWNrYWdlIG5hbWU+YC4nOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsb2NrZXItPmlzTG9ja2VkKCkpIHsKICAgICAgICAgICAgJG1pc3NpbmdSZXF1aXJlbWVudHMgPSBmYWxzZTsKICAgICAgICAgICAgJHNldHMgPSBhcnJheSgKICAgICAgICAgICAgICAgIGFycmF5KCdyZXBvJyA9PiAkbG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KGZhbHNlKSwgJ21ldGhvZCcgPT4gJ2dldFJlcXVpcmVzJywgJ2Rlc2NyaXB0aW9uJyA9PiAnUmVxdWlyZWQnKSwKICAgICAgICAgICAgICAgIGFycmF5KCdyZXBvJyA9PiAkbG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KHRydWUpLCAnbWV0aG9kJyA9PiAnZ2V0RGV2UmVxdWlyZXMnLCAnZGVzY3JpcHRpb24nID0+ICdSZXF1aXJlZCAoaW4gcmVxdWlyZS1kZXYpJyksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRzZXRzIGFzICRzZXQpIHsKICAgICAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkoJHNldFsncmVwbyddKSk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoY2FsbF91c2VyX2Z1bmMoYXJyYXkoJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCksICRzZXRbJ21ldGhvZCddKSkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkbGluay0+Z2V0VGFyZ2V0KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoISRpbnN0YWxsZWRSZXBvLT5maW5kUGFja2FnZXNXaXRoUmVwbGFjZXJzQW5kUHJvdmlkZXJzKCRsaW5rLT5nZXRUYXJnZXQoKSwgJGxpbmstPmdldENvbnN0cmFpbnQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXN1bHRzID0gJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMoJGxpbmstPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHByb3ZpZGVyID0gcmVzZXQoJHJlc3VsdHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxvY2tFcnJvcnNbXSA9ICctICcgLiAkc2V0WydkZXNjcmlwdGlvbiddLicgcGFja2FnZSAiJyAuICRsaW5rLT5nZXRUYXJnZXQoKSAuICciIGlzIGluIHRoZSBsb2NrIGZpbGUgYXMgIicuJHByb3ZpZGVyLT5nZXRQcmV0dHlWZXJzaW9uKCkuJyIgYnV0IHRoYXQgZG9lcyBub3Qgc2F0aXNmeSB5b3VyIGNvbnN0cmFpbnQgIicuJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKS4nIi4nOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxvY2tFcnJvcnNbXSA9ICctICcgLiAkc2V0WydkZXNjcmlwdGlvbiddLicgcGFja2FnZSAiJyAuICRsaW5rLT5nZXRUYXJnZXQoKSAuICciIGlzIG5vdCBwcmVzZW50IGluIHRoZSBsb2NrIGZpbGUuJzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkbWlzc2luZ1JlcXVpcmVtZW50cyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG1pc3NpbmdSZXF1aXJlbWVudHMpIHsKICAgICAgICAgICAgICAgICRsb2NrRXJyb3JzW10gPSAnVGhpcyB1c3VhbGx5IGhhcHBlbnMgd2hlbiBjb21wb3NlciBmaWxlcyBhcmUgaW5jb3JyZWN0bHkgbWVyZ2VkIG9yIHRoZSBjb21wb3Nlci5qc29uIGZpbGUgaXMgbWFudWFsbHkgZWRpdGVkLic7CiAgICAgICAgICAgICAgICAkbG9ja0Vycm9yc1tdID0gJ1JlYWQgbW9yZSBhYm91dCBjb3JyZWN0bHkgcmVzb2x2aW5nIG1lcmdlIGNvbmZsaWN0cyBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvcmVzb2x2aW5nLW1lcmdlLWNvbmZsaWN0cy5tZCc7CiAgICAgICAgICAgICAgICAkbG9ja0Vycm9yc1tdID0gJ2FuZCBwcmVmZXIgdXNpbmcgdGhlICJyZXF1aXJlIiBjb21tYW5kIG92ZXIgZWRpdGluZyB0aGUgY29tcG9zZXIuanNvbiBmaWxlIGRpcmVjdGx5IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjcmVxdWlyZSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXRSZXN1bHQoJGlvLCAkZmlsZSwgJGVycm9ycywgJHdhcm5pbmdzLCAkY2hlY2tQdWJsaXNoLCAkcHVibGlzaEVycm9ycywgJGNoZWNrTG9jaywgJGxvY2tFcnJvcnMsIHRydWUpOwoKICAgICAgICAvLyAkZXJyb3JzIGluY2x1ZGUgcHVibGlzaCBhbmQgbG9jayBlcnJvcnMgd2hlbiBleGlzdHMKICAgICAgICAkZXhpdENvZGUgPSAkZXJyb3JzID8gMiA6ICgkaXNTdHJpY3QgJiYgJHdhcm5pbmdzID8gMSA6IDApOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtZGVwZW5kZW5jaWVzJykpIHsKICAgICAgICAgICAgJGxvY2FsUmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRwYXRoID0gJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICRmaWxlID0gJHBhdGggLiAnL2NvbXBvc2VyLmpzb24nOwogICAgICAgICAgICAgICAgaWYgKGlzX2RpcigkcGF0aCkgJiYgZmlsZV9leGlzdHMoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkZXJyb3JzLCAkcHVibGlzaEVycm9ycywgJHdhcm5pbmdzKSA9ICR2YWxpZGF0b3ItPnZhbGlkYXRlKCRmaWxlLCAkY2hlY2tBbGwsICRjaGVja1ZlcnNpb24pOwoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCRpbywgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJGVycm9ycywgJHdhcm5pbmdzLCAkY2hlY2tQdWJsaXNoLCAkcHVibGlzaEVycm9ycyk7CgogICAgICAgICAgICAgICAgICAgIC8vICRlcnJvcnMgaW5jbHVkZSBwdWJsaXNoIGVycm9ycyB3aGVuIGV4aXN0cwogICAgICAgICAgICAgICAgICAgICRkZXBDb2RlID0gJGVycm9ycyA/IDIgOiAoJGlzU3RyaWN0ICYmICR3YXJuaW5ncyA/IDEgOiAwKTsKICAgICAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSBtYXgoJGRlcENvZGUsICRleGl0Q29kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3ZhbGlkYXRlJywgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICAkZXZlbnRDb2RlID0gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgcmV0dXJuIG1heCgkZXZlbnRDb2RlLCAkZXhpdENvZGUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZ1tdICRlcnJvcnMKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkd2FybmluZ3MKICAgICAqIEBwYXJhbSBib29sICRjaGVja1B1Ymxpc2gKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkcHVibGlzaEVycm9ycwogICAgICogQHBhcmFtIGJvb2wgJGNoZWNrTG9jawogICAgICogQHBhcmFtIHN0cmluZ1tdICRsb2NrRXJyb3JzCiAgICAgKiBAcGFyYW0gYm9vbCAkcHJpbnRTY2hlbWFVcmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBvdXRwdXRSZXN1bHQoSU9JbnRlcmZhY2UgJGlvLCAkbmFtZSwgJiRlcnJvcnMsICYkd2FybmluZ3MsICRjaGVja1B1Ymxpc2ggPSBmYWxzZSwgJHB1Ymxpc2hFcnJvcnMgPSBhcnJheSgpLCAkY2hlY2tMb2NrID0gZmFsc2UsICRsb2NrRXJyb3JzID0gYXJyYXkoKSwgJHByaW50U2NoZW1hVXJsID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGRvUHJpbnRTY2hlbWFVcmwgPSBmYWxzZTsKCiAgICAgICAgaWYgKCRlcnJvcnMpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+JyAuICRuYW1lIC4gJyBpcyBpbnZhbGlkLCB0aGUgZm9sbG93aW5nIGVycm9ycy93YXJuaW5ncyB3ZXJlIGZvdW5kOjwvZXJyb3I+Jyk7CiAgICAgICAgfSBlbHNlaWYgKCRwdWJsaXNoRXJyb3JzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+JyAuICRuYW1lIC4gJyBpcyB2YWxpZCBmb3Igc2ltcGxlIHVzYWdlIHdpdGggQ29tcG9zZXIgYnV0IGhhczwvaW5mbz4nKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5zdHJpY3QgZXJyb3JzIHRoYXQgbWFrZSBpdCB1bmFibGUgdG8gYmUgcHVibGlzaGVkIGFzIGEgcGFja2FnZTwvaW5mbz4nKTsKICAgICAgICAgICAgJGRvUHJpbnRTY2hlbWFVcmwgPSAkcHJpbnRTY2hlbWFVcmw7CiAgICAgICAgfSBlbHNlaWYgKCR3YXJuaW5ncykgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPicgLiAkbmFtZSAuICcgaXMgdmFsaWQsIGJ1dCB3aXRoIGEgZmV3IHdhcm5pbmdzPC9pbmZvPicpOwogICAgICAgICAgICAkZG9QcmludFNjaGVtYVVybCA9ICRwcmludFNjaGVtYVVybDsKICAgICAgICB9IGVsc2VpZiAoJGxvY2tFcnJvcnMpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+JyAuICRuYW1lIC4gJyBpcyB2YWxpZCBidXQgeW91ciBjb21wb3Nlci5sb2NrIGhhcyBzb21lICcuKCRjaGVja0xvY2sgPyAnZXJyb3JzJyA6ICd3YXJuaW5ncycpLic8L2luZm8+Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+JyAuICRuYW1lIC4gJyBpcyB2YWxpZDwvaW5mbz4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZG9QcmludFNjaGVtYVVybCkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDQtc2NoZW1hLm1kIGZvciBkZXRhaWxzIG9uIHRoZSBzY2hlbWE8L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVycm9ycykgewogICAgICAgICAgICAkZXJyb3JzID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkZXJyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJy0gJyAuICRlcnI7CiAgICAgICAgICAgIH0sICRlcnJvcnMpOwogICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRlcnJvcnMsICcjIEdlbmVyYWwgZXJyb3JzJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkd2FybmluZ3MpIHsKICAgICAgICAgICAgJHdhcm5pbmdzID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkZXJyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJy0gJyAuICRlcnI7CiAgICAgICAgICAgIH0sICR3YXJuaW5ncyk7CiAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJHdhcm5pbmdzLCAnIyBHZW5lcmFsIHdhcm5pbmdzJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBBdm9pZCBzZXR0aW5nIHRoZSBleGl0IGNvZGUgdG8gMSBpbiBjYXNlIC0tc3RyaWN0IGFuZCAtLW5vLWNoZWNrLXB1Ymxpc2gvLS1uby1jaGVjay1sb2NrIGFyZSBjb21iaW5lZAogICAgICAgICRleHRyYVdhcm5pbmdzID0gYXJyYXkoKTsKCiAgICAgICAgLy8gSWYgY2hlY2tpbmcgcHVibGlzaCBlcnJvcnMsIGRpc3BsYXkgdGhlbSBhcyBlcnJvcnMsIG90aGVyd2lzZSBqdXN0IHNob3cgdGhlbSBhcyB3YXJuaW5ncwogICAgICAgIGlmICgkcHVibGlzaEVycm9ycykgewogICAgICAgICAgICAkcHVibGlzaEVycm9ycyA9IGFycmF5X21hcChmdW5jdGlvbiAoJGVycikgewogICAgICAgICAgICAgICAgcmV0dXJuICctICcgLiAkZXJyOwogICAgICAgICAgICB9LCAkcHVibGlzaEVycm9ycyk7CgogICAgICAgICAgICBpZiAoJGNoZWNrUHVibGlzaCkgewogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkcHVibGlzaEVycm9ycywgJyMgUHVibGlzaCBlcnJvcnMnKTsKICAgICAgICAgICAgICAgICRlcnJvcnMgPSBhcnJheV9tZXJnZSgkZXJyb3JzLCAkcHVibGlzaEVycm9ycyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRwdWJsaXNoRXJyb3JzLCAnIyBQdWJsaXNoIHdhcm5pbmdzJyk7CiAgICAgICAgICAgICAgICAkZXh0cmFXYXJuaW5ncyA9IGFycmF5X21lcmdlKCRleHRyYVdhcm5pbmdzLCAkcHVibGlzaEVycm9ycyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIElmIGNoZWNraW5nIGxvY2sgZXJyb3JzLCBkaXNwbGF5IHRoZW0gYXMgZXJyb3JzLCBvdGhlcndpc2UganVzdCBzaG93IHRoZW0gYXMgd2FybmluZ3MKICAgICAgICBpZiAoJGxvY2tFcnJvcnMpIHsKICAgICAgICAgICAgaWYgKCRjaGVja0xvY2spIHsKICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGxvY2tFcnJvcnMsICcjIExvY2sgZmlsZSBlcnJvcnMnKTsKICAgICAgICAgICAgICAgICRlcnJvcnMgPSBhcnJheV9tZXJnZSgkZXJyb3JzLCAkbG9ja0Vycm9ycyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRsb2NrRXJyb3JzLCAnIyBMb2NrIGZpbGUgd2FybmluZ3MnKTsKICAgICAgICAgICAgICAgICRleHRyYVdhcm5pbmdzID0gYXJyYXlfbWVyZ2UoJGV4dHJhV2FybmluZ3MsICRsb2NrRXJyb3JzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG1lc3NhZ2VzID0gYXJyYXkoCiAgICAgICAgICAgICdlcnJvcicgPT4gJGVycm9ycywKICAgICAgICAgICAgJ3dhcm5pbmcnID0+IGFycmF5X21lcmdlKCR3YXJuaW5ncywgJGV4dHJhV2FybmluZ3MpLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAkc3R5bGUgPT4gJG1zZ3MpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJG1zZ3MgYXMgJG1zZykgewogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkbXNnLCAnIycpID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8JyAuICRzdHlsZSAuICc+JyAuICRtc2cgLiAnPC8nIC4gJHN0eWxlIC4gJz4nKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCRtc2cpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyOwoKdXNlIENvbXBvc2VyXENvbmZpZ1xKc29uQ29uZmlnU291cmNlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBcmNoaXZlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uR3Vlc3NlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CnVzZSBDb21wb3NlclxVdGlsXExvb3A7CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudDsKdXNlIFNlbGRcSnNvbkxpbnRcRHVwbGljYXRlS2V5RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVyU3R5bGU7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxDb25zb2xlT3V0cHV0Owp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXEF1dG9sb2FkXEF1dG9sb2FkR2VuZXJhdG9yOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXEpzb25cSnNvblZhbGlkYXRpb25FeGNlcHRpb247CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBTZWxkXEpzb25MaW50XEpzb25QYXJzZXI7CgovKioKICogQ3JlYXRlcyBhIGNvbmZpZ3VyZWQgaW5zdGFuY2Ugb2YgY29tcG9zZXIuCiAqCiAqIEBhdXRob3IgUnlhbiBXZWF2ZXIgPHJ5YW5Aa25wbGFicy5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBJZ29yIFdpZWRsZXIgPGlnb3JAd2llZGxlci5jaD4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEZhY3RvcnkKewogICAgLyoqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldEhvbWVEaXIoKQogICAgewogICAgICAgICRob21lID0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfSE9NRScpOwogICAgICAgIGlmICgkaG9tZSkgewogICAgICAgICAgICByZXR1cm4gJGhvbWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgIGlmICghUGxhdGZvcm06OmdldEVudignQVBQREFUQScpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBBUFBEQVRBIG9yIENPTVBPU0VSX0hPTUUgZW52aXJvbm1lbnQgdmFyaWFibGUgbXVzdCBiZSBzZXQgZm9yIGNvbXBvc2VyIHRvIHJ1biBjb3JyZWN0bHknKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJ0cmltKHN0cnRyKFBsYXRmb3JtOjpnZXRFbnYoJ0FQUERBVEEnKSwgJ1xcJywgJy8nKSwgJy8nKSAuICcvQ29tcG9zZXInOwogICAgICAgIH0KCiAgICAgICAgJHVzZXJEaXIgPSBzZWxmOjpnZXRVc2VyRGlyKCk7CiAgICAgICAgJGRpcnMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoc2VsZjo6dXNlWGRnKCkpIHsKICAgICAgICAgICAgLy8gWERHIEJhc2UgRGlyZWN0b3J5IFNwZWNpZmljYXRpb25zCiAgICAgICAgICAgICR4ZGdDb25maWcgPSBQbGF0Zm9ybTo6Z2V0RW52KCdYREdfQ09ORklHX0hPTUUnKTsKICAgICAgICAgICAgaWYgKCEkeGRnQ29uZmlnKSB7CiAgICAgICAgICAgICAgICAkeGRnQ29uZmlnID0gJHVzZXJEaXIgLiAnLy5jb25maWcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGlyc1tdID0gJHhkZ0NvbmZpZyAuICcvY29tcG9zZXInOwogICAgICAgIH0KCiAgICAgICAgJGRpcnNbXSA9ICR1c2VyRGlyIC4gJy8uY29tcG9zZXInOwoKICAgICAgICAvLyBzZWxlY3QgZmlyc3QgZGlyIHdoaWNoIGV4aXN0cyBvZjogJFhER19DT05GSUdfSE9NRS9jb21wb3NlciBvciB+Ly5jb21wb3NlcgogICAgICAgIGZvcmVhY2ggKCRkaXJzIGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKFNpbGVuY2VyOjpjYWxsKCdpc19kaXInLCAkZGlyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkaXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGlmIG5vbmUgZXhpc3RzLCB3ZSBkZWZhdWx0IHRvIGZpcnN0IGRlZmluZWQgb25lIChYREcgb25lIGlmIHN5c3RlbSB1c2VzIGl0LCBvciB+Ly5jb21wb3NlciBvdGhlcndpc2UpCiAgICAgICAgcmV0dXJuICRkaXJzWzBdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJGhvbWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0Q2FjaGVEaXIoJGhvbWUpCiAgICB7CiAgICAgICAgJGNhY2hlRGlyID0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfQ0FDSEVfRElSJyk7CiAgICAgICAgaWYgKCRjYWNoZURpcikgewogICAgICAgICAgICByZXR1cm4gJGNhY2hlRGlyOwogICAgICAgIH0KCiAgICAgICAgJGhvbWVFbnYgPSBQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9IT01FJyk7CiAgICAgICAgaWYgKCRob21lRW52KSB7CiAgICAgICAgICAgIHJldHVybiAkaG9tZUVudiAuICcvY2FjaGUnOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICBpZiAoJGNhY2hlRGlyID0gUGxhdGZvcm06OmdldEVudignTE9DQUxBUFBEQVRBJykpIHsKICAgICAgICAgICAgICAgICRjYWNoZURpciAuPSAnL0NvbXBvc2VyJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjYWNoZURpciA9ICRob21lIC4gJy9jYWNoZSc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBydHJpbShzdHJ0cigkY2FjaGVEaXIsICdcXCcsICcvJyksICcvJyk7CiAgICAgICAgfQoKICAgICAgICAkdXNlckRpciA9IHNlbGY6OmdldFVzZXJEaXIoKTsKICAgICAgICBpZiAoUEhQX09TID09PSAnRGFyd2luJykgewogICAgICAgICAgICAvLyBNaWdyYXRlIGV4aXN0aW5nIGNhY2hlIGRpciBpbiBvbGQgbG9jYXRpb24gaWYgcHJlc2VudAogICAgICAgICAgICBpZiAoaXNfZGlyKCRob21lIC4gJy9jYWNoZScpICYmICFpc19kaXIoJHVzZXJEaXIgLiAnL0xpYnJhcnkvQ2FjaGVzL2NvbXBvc2VyJykpIHsKICAgICAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdyZW5hbWUnLCAkaG9tZSAuICcvY2FjaGUnLCAkdXNlckRpciAuICcvTGlicmFyeS9DYWNoZXMvY29tcG9zZXInKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR1c2VyRGlyIC4gJy9MaWJyYXJ5L0NhY2hlcy9jb21wb3Nlcic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhvbWUgPT09ICR1c2VyRGlyIC4gJy8uY29tcG9zZXInICYmIGlzX2RpcigkaG9tZSAuICcvY2FjaGUnKSkgewogICAgICAgICAgICByZXR1cm4gJGhvbWUgLiAnL2NhY2hlJzsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjp1c2VYZGcoKSkgewogICAgICAgICAgICAkeGRnQ2FjaGUgPSBQbGF0Zm9ybTo6Z2V0RW52KCdYREdfQ0FDSEVfSE9NRScpID86ICR1c2VyRGlyIC4gJy8uY2FjaGUnOwoKICAgICAgICAgICAgcmV0dXJuICR4ZGdDYWNoZSAuICcvY29tcG9zZXInOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRob21lIC4gJy9jYWNoZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkaG9tZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXREYXRhRGlyKCRob21lKQogICAgewogICAgICAgICRob21lRW52ID0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfSE9NRScpOwogICAgICAgIGlmICgkaG9tZUVudikgewogICAgICAgICAgICByZXR1cm4gJGhvbWVFbnY7CiAgICAgICAgfQoKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJ0cigkaG9tZSwgJ1xcJywgJy8nKTsKICAgICAgICB9CgogICAgICAgICR1c2VyRGlyID0gc2VsZjo6Z2V0VXNlckRpcigpOwogICAgICAgIGlmICgkaG9tZSAhPT0gJHVzZXJEaXIgLiAnLy5jb21wb3NlcicgJiYgc2VsZjo6dXNlWGRnKCkpIHsKICAgICAgICAgICAgJHhkZ0RhdGEgPSBQbGF0Zm9ybTo6Z2V0RW52KCdYREdfREFUQV9IT01FJykgPzogJHVzZXJEaXIgLiAnLy5sb2NhbC9zaGFyZSc7CgogICAgICAgICAgICByZXR1cm4gJHhkZ0RhdGEgLiAnL2NvbXBvc2VyJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaG9tZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY3dkCiAgICAgKgogICAgICogQHJldHVybiBDb25maWcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVDb25maWcoSU9JbnRlcmZhY2UgJGlvID0gbnVsbCwgJGN3ZCA9IG51bGwpCiAgICB7CiAgICAgICAgJGN3ZCA9ICRjd2QgPzogKHN0cmluZykgZ2V0Y3dkKCk7CgogICAgICAgICRjb25maWcgPSBuZXcgQ29uZmlnKHRydWUsICRjd2QpOwoKICAgICAgICAvLyBkZXRlcm1pbmUgYW5kIGFkZCBtYWluIGRpcnMgdG8gdGhlIGNvbmZpZwogICAgICAgICRob21lID0gc2VsZjo6Z2V0SG9tZURpcigpOwogICAgICAgICRjb25maWctPm1lcmdlKGFycmF5KCdjb25maWcnID0+IGFycmF5KAogICAgICAgICAgICAnaG9tZScgPT4gJGhvbWUsCiAgICAgICAgICAgICdjYWNoZS1kaXInID0+IHNlbGY6OmdldENhY2hlRGlyKCRob21lKSwKICAgICAgICAgICAgJ2RhdGEtZGlyJyA9PiBzZWxmOjpnZXREYXRhRGlyKCRob21lKSwKICAgICAgICApKSwgQ29uZmlnOjpTT1VSQ0VfREVGQVVMVCk7CgogICAgICAgIC8vIGxvYWQgZ2xvYmFsIGNvbmZpZwogICAgICAgICRmaWxlID0gbmV3IEpzb25GaWxlKCRjb25maWctPmdldCgnaG9tZScpLicvY29uZmlnLmpzb24nKTsKICAgICAgICBpZiAoJGZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIGlmICgkaW8gJiYgJGlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTG9hZGluZyBjb25maWcgZmlsZSAnIC4gJGZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNvbmZpZy0+bWVyZ2UoJGZpbGUtPnJlYWQoKSwgJGZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgfQogICAgICAgICRjb25maWctPnNldENvbmZpZ1NvdXJjZShuZXcgSnNvbkNvbmZpZ1NvdXJjZSgkZmlsZSkpOwoKICAgICAgICAkaHRhY2Nlc3NQcm90ZWN0ID0gKGJvb2wpICRjb25maWctPmdldCgnaHRhY2Nlc3MtcHJvdGVjdCcpOwogICAgICAgIGlmICgkaHRhY2Nlc3NQcm90ZWN0KSB7CiAgICAgICAgICAgIC8vIFByb3RlY3QgZGlyZWN0b3J5IGFnYWluc3Qgd2ViIGFjY2Vzcy4gU2luY2UgSE9NRSBjb3VsZCBiZQogICAgICAgICAgICAvLyB0aGUgd3d3LWRhdGEncyB1c2VyIGhvbWUgYW5kIGJlIHdlYi1hY2Nlc3NpYmxlIGl0IGlzIGEKICAgICAgICAgICAgLy8gcG90ZW50aWFsIHNlY3VyaXR5IHJpc2sKICAgICAgICAgICAgJGRpcnMgPSBhcnJheSgkY29uZmlnLT5nZXQoJ2hvbWUnKSwgJGNvbmZpZy0+Z2V0KCdjYWNoZS1kaXInKSwgJGNvbmZpZy0+Z2V0KCdkYXRhLWRpcicpKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRpcnMgYXMgJGRpcikgewogICAgICAgICAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkZGlyIC4gJy8uaHRhY2Nlc3MnKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNfZGlyKCRkaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdta2RpcicsICRkaXIsIDA3NzcsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnZmlsZV9wdXRfY29udGVudHMnLCAkZGlyIC4gJy8uaHRhY2Nlc3MnLCAnRGVueSBmcm9tIGFsbCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBsb2FkIGdsb2JhbCBhdXRoIGZpbGUKICAgICAgICAkZmlsZSA9IG5ldyBKc29uRmlsZSgkY29uZmlnLT5nZXQoJ2hvbWUnKS4nL2F1dGguanNvbicpOwogICAgICAgIGlmICgkZmlsZS0+ZXhpc3RzKCkpIHsKICAgICAgICAgICAgaWYgKCRpbyAmJiAkaW8tPmlzRGVidWcoKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdMb2FkaW5nIGNvbmZpZyBmaWxlICcgLiAkZmlsZS0+Z2V0UGF0aCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY29uZmlnLT5tZXJnZShhcnJheSgnY29uZmlnJyA9PiAkZmlsZS0+cmVhZCgpKSwgJGZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgfQogICAgICAgICRjb25maWctPnNldEF1dGhDb25maWdTb3VyY2UobmV3IEpzb25Db25maWdTb3VyY2UoJGZpbGUsIHRydWUpKTsKCiAgICAgICAgLy8gbG9hZCBDT01QT1NFUl9BVVRIIGVudmlyb25tZW50IHZhcmlhYmxlIGlmIHNldAogICAgICAgIGlmICgkY29tcG9zZXJBdXRoRW52ID0gUGxhdGZvcm06OmdldEVudignQ09NUE9TRVJfQVVUSCcpKSB7CiAgICAgICAgICAgICRhdXRoRGF0YSA9IGpzb25fZGVjb2RlKCRjb21wb3NlckF1dGhFbnYsIHRydWUpOwoKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRhdXRoRGF0YSkgewogICAgICAgICAgICAgICAgaWYgKCRpbykgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkNPTVBPU0VSX0FVVEggZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgbWFsZm9ybWVkLCBzaG91bGQgYmUgYSB2YWxpZCBKU09OIG9iamVjdDwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJGlvICYmICRpby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdMb2FkaW5nIGF1dGggY29uZmlnIGZyb20gQ09NUE9TRVJfQVVUSCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvbmZpZy0+bWVyZ2UoYXJyYXkoJ2NvbmZpZycgPT4gJGF1dGhEYXRhKSwgJ0NPTVBPU0VSX0FVVEgnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb25maWc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbXBvc2VyRmlsZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRyaW0oUGxhdGZvcm06OmdldEVudignQ09NUE9TRVInKSkgPzogJy4vY29tcG9zZXIuanNvbic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21wb3NlckZpbGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldExvY2tGaWxlKCRjb21wb3NlckZpbGUpCiAgICB7CiAgICAgICAgcmV0dXJuICJqc29uIiA9PT0gcGF0aGluZm8oJGNvbXBvc2VyRmlsZSwgUEFUSElORk9fRVhURU5TSU9OKQogICAgICAgICAgICAgICAgPyBzdWJzdHIoJGNvbXBvc2VyRmlsZSwgMCwgLTQpLidsb2NrJwogICAgICAgICAgICAgICAgOiAkY29tcG9zZXJGaWxlIC4gJy5sb2NrJzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXl7aGlnaGxpZ2h0OiBPdXRwdXRGb3JtYXR0ZXJTdHlsZSwgd2FybmluZzogT3V0cHV0Rm9ybWF0dGVyU3R5bGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlQWRkaXRpb25hbFN0eWxlcygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAnaGlnaGxpZ2h0JyA9PiBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoJ3JlZCcpLAogICAgICAgICAgICAnd2FybmluZycgPT4gbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCdibGFjaycsICd5ZWxsb3cnKSwKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIENvbnNvbGVPdXRwdXQgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnNvbGVPdXRwdXQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVPdXRwdXQoKQogICAgewogICAgICAgICRzdHlsZXMgPSBzZWxmOjpjcmVhdGVBZGRpdGlvbmFsU3R5bGVzKCk7CiAgICAgICAgJGZvcm1hdHRlciA9IG5ldyBPdXRwdXRGb3JtYXR0ZXIoZmFsc2UsICRzdHlsZXMpOwoKICAgICAgICByZXR1cm4gbmV3IENvbnNvbGVPdXRwdXQoQ29uc29sZU91dHB1dDo6VkVSQk9TSVRZX05PUk1BTCwgbnVsbCwgJGZvcm1hdHRlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgQ29tcG9zZXIgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICAgICAgICAgICAgICAgICAgICAgICAkaW8gICAgICAgICAgICAgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgYXJyYXk8c3RyaW5nLCBtaXhlZD58c3RyaW5nfG51bGwgICRsb2NhbENvbmZpZyAgICBlaXRoZXIgYSBjb25maWd1cmF0aW9uIGFycmF5IG9yIGEgZmlsZW5hbWUgdG8gcmVhZCBmcm9tLCBpZiBudWxsIGl0IHdpbGwKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkIGZyb20gdGhlIGRlZmF1bHQgZmlsZW5hbWUKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkaXNhYmxlUGx1Z2lucyBXaGV0aGVyIHBsdWdpbnMgc2hvdWxkIG5vdCBiZSBsb2FkZWQKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkaXNhYmxlU2NyaXB0cyBXaGV0aGVyIHNjcmlwdHMgc2hvdWxkIG5vdCBiZSBydW4KICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgICAgICAgICAgICAgICAgICAgICAgICRjd2QKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmdWxsTG9hZCAgICAgICBXaGV0aGVyIHRvIGluaXRpYWxpemUgZXZlcnl0aGluZyBvciBvbmx5IG1haW4gcHJvamVjdCBzdHVmZiAodXNlZCB3aGVuIGxvYWRpbmcgdGhlIGdsb2JhbCBjb21wb3NlcikKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVDb21wb3NlcihJT0ludGVyZmFjZSAkaW8sICRsb2NhbENvbmZpZyA9IG51bGwsICRkaXNhYmxlUGx1Z2lucyA9IGZhbHNlLCAkY3dkID0gbnVsbCwgJGZ1bGxMb2FkID0gdHJ1ZSwgJGRpc2FibGVTY3JpcHRzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGN3ZCA9ICRjd2QgPzogKHN0cmluZykgZ2V0Y3dkKCk7CgogICAgICAgIC8vIGxvYWQgQ29tcG9zZXIgY29uZmlndXJhdGlvbgogICAgICAgIGlmIChudWxsID09PSAkbG9jYWxDb25maWcpIHsKICAgICAgICAgICAgJGxvY2FsQ29uZmlnID0gc3RhdGljOjpnZXRDb21wb3NlckZpbGUoKTsKICAgICAgICB9CgogICAgICAgICRsb2NhbENvbmZpZ1NvdXJjZSA9IENvbmZpZzo6U09VUkNFX1VOS05PV047CiAgICAgICAgaWYgKGlzX3N0cmluZygkbG9jYWxDb25maWcpKSB7CiAgICAgICAgICAgICRjb21wb3NlckZpbGUgPSAkbG9jYWxDb25maWc7CgogICAgICAgICAgICAkZmlsZSA9IG5ldyBKc29uRmlsZSgkbG9jYWxDb25maWcsIG51bGwsICRpbyk7CgogICAgICAgICAgICBpZiAoISRmaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgaWYgKCRsb2NhbENvbmZpZyA9PT0gJy4vY29tcG9zZXIuanNvbicgfHwgJGxvY2FsQ29uZmlnID09PSAnY29tcG9zZXIuanNvbicpIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDb21wb3NlciBjb3VsZCBub3QgZmluZCBhIGNvbXBvc2VyLmpzb24gZmlsZSBpbiAnLiRjd2Q7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0NvbXBvc2VyIGNvdWxkIG5vdCBmaW5kIHRoZSBjb25maWcgZmlsZTogJy4kbG9jYWxDb25maWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkaW5zdHJ1Y3Rpb25zID0gJGZ1bGxMb2FkID8gJ1RvIGluaXRpYWxpemUgYSBwcm9qZWN0LCBwbGVhc2UgY3JlYXRlIGEgY29tcG9zZXIuanNvbiBmaWxlLiBTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvYmFzaWMtdXNhZ2UnIDogJyc7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigkbWVzc2FnZS5QSFBfRU9MLiRpbnN0cnVjdGlvbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGZpbGUtPnZhbGlkYXRlU2NoZW1hKEpzb25GaWxlOjpMQVhfU0NIRU1BKTsKICAgICAgICAgICAgfSBjYXRjaCAoSnNvblZhbGlkYXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRlcnJvcnMgPSAnIC0gJyAuIGltcGxvZGUoUEhQX0VPTCAuICcgLSAnLCAkZS0+Z2V0RXJyb3JzKCkpOwogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAkZS0+Z2V0TWVzc2FnZSgpIC4gJzonIC4gUEhQX0VPTCAuICRlcnJvcnM7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSnNvblZhbGlkYXRpb25FeGNlcHRpb24oJG1lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRqc29uUGFyc2VyID0gbmV3IEpzb25QYXJzZXI7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkanNvblBhcnNlci0+cGFyc2UoZmlsZV9nZXRfY29udGVudHMoJGxvY2FsQ29uZmlnKSwgSnNvblBhcnNlcjo6REVURUNUX0tFWV9DT05GTElDVFMpOwogICAgICAgICAgICB9IGNhdGNoIChEdXBsaWNhdGVLZXlFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRkZXRhaWxzID0gJGUtPmdldERldGFpbHMoKTsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+S2V5ICcuJGRldGFpbHNbJ2tleSddLicgaXMgYSBkdXBsaWNhdGUgaW4gJy4kbG9jYWxDb25maWcuJyBhdCBsaW5lICcuJGRldGFpbHNbJ2xpbmUnXS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG9jYWxDb25maWcgPSAkZmlsZS0+cmVhZCgpOwogICAgICAgICAgICAkbG9jYWxDb25maWdTb3VyY2UgPSAkZmlsZS0+Z2V0UGF0aCgpOwogICAgICAgIH0KCiAgICAgICAgLy8gTG9hZCBjb25maWcgYW5kIG92ZXJyaWRlIHdpdGggbG9jYWwgY29uZmlnL2F1dGggY29uZmlnCiAgICAgICAgJGNvbmZpZyA9IHN0YXRpYzo6Y3JlYXRlQ29uZmlnKCRpbywgJGN3ZCk7CiAgICAgICAgJGNvbmZpZy0+bWVyZ2UoJGxvY2FsQ29uZmlnLCAkbG9jYWxDb25maWdTb3VyY2UpOwogICAgICAgIGlmIChpc3NldCgkY29tcG9zZXJGaWxlKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0xvYWRpbmcgY29uZmlnIGZpbGUgJyAuICRjb21wb3NlckZpbGUgLicgKCcucmVhbHBhdGgoJGNvbXBvc2VyRmlsZSkuJyknLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAkY29uZmlnLT5zZXRDb25maWdTb3VyY2UobmV3IEpzb25Db25maWdTb3VyY2UobmV3IEpzb25GaWxlKHJlYWxwYXRoKCRjb21wb3NlckZpbGUpLCBudWxsLCAkaW8pKSk7CgogICAgICAgICAgICAkbG9jYWxBdXRoRmlsZSA9IG5ldyBKc29uRmlsZShkaXJuYW1lKHJlYWxwYXRoKCRjb21wb3NlckZpbGUpKSAuICcvYXV0aC5qc29uJywgbnVsbCwgJGlvKTsKICAgICAgICAgICAgaWYgKCRsb2NhbEF1dGhGaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdMb2FkaW5nIGNvbmZpZyBmaWxlICcgLiAkbG9jYWxBdXRoRmlsZS0+Z2V0UGF0aCgpLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAgICAgJGNvbmZpZy0+bWVyZ2UoYXJyYXkoJ2NvbmZpZycgPT4gJGxvY2FsQXV0aEZpbGUtPnJlYWQoKSksICRsb2NhbEF1dGhGaWxlLT5nZXRQYXRoKCkpOwogICAgICAgICAgICAgICAgJGNvbmZpZy0+c2V0QXV0aENvbmZpZ1NvdXJjZShuZXcgSnNvbkNvbmZpZ1NvdXJjZSgkbG9jYWxBdXRoRmlsZSwgdHJ1ZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdmVuZG9yRGlyID0gJGNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJyk7CgogICAgICAgIC8vIGluaXRpYWxpemUgY29tcG9zZXIKICAgICAgICAkY29tcG9zZXIgPSBuZXcgQ29tcG9zZXIoKTsKICAgICAgICAkY29tcG9zZXItPnNldENvbmZpZygkY29uZmlnKTsKCiAgICAgICAgaWYgKCRmdWxsTG9hZCkgewogICAgICAgICAgICAvLyBsb2FkIGF1dGggY29uZmlncyBpbnRvIHRoZSBJTyBpbnN0YW5jZQogICAgICAgICAgICAkaW8tPmxvYWRDb25maWd1cmF0aW9uKCRjb25maWcpOwoKICAgICAgICAgICAgLy8gbG9hZCBleGlzdGluZyBDb21wb3NlclxJbnN0YWxsZWRWZXJzaW9ucyBpbnN0YW5jZSBpZiBhdmFpbGFibGUKICAgICAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJ0NvbXBvc2VyXEluc3RhbGxlZFZlcnNpb25zJywgZmFsc2UpICYmIGZpbGVfZXhpc3RzKCRpbnN0YWxsZWRWZXJzaW9uc1BhdGggPSAkY29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKS4nL2NvbXBvc2VyL0luc3RhbGxlZFZlcnNpb25zLnBocCcpKSB7CiAgICAgICAgICAgICAgICBpbmNsdWRlICRpbnN0YWxsZWRWZXJzaW9uc1BhdGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRodHRwRG93bmxvYWRlciA9IHNlbGY6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZyk7CiAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJGxvb3AgPSBuZXcgTG9vcCgkaHR0cERvd25sb2FkZXIsICRwcm9jZXNzKTsKICAgICAgICAkY29tcG9zZXItPnNldExvb3AoJGxvb3ApOwoKICAgICAgICAvLyBpbml0aWFsaXplIGV2ZW50IGRpc3BhdGNoZXIKICAgICAgICAkZGlzcGF0Y2hlciA9IG5ldyBFdmVudERpc3BhdGNoZXIoJGNvbXBvc2VyLCAkaW8sICRwcm9jZXNzKTsKICAgICAgICAkZGlzcGF0Y2hlci0+c2V0UnVuU2NyaXB0cyghJGRpc2FibGVTY3JpcHRzKTsKICAgICAgICAkY29tcG9zZXItPnNldEV2ZW50RGlzcGF0Y2hlcigkZGlzcGF0Y2hlcik7CgogICAgICAgIC8vIGluaXRpYWxpemUgcmVwb3NpdG9yeSBtYW5hZ2VyCiAgICAgICAgJHJtID0gUmVwb3NpdG9yeUZhY3Rvcnk6Om1hbmFnZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRkaXNwYXRjaGVyLCAkcHJvY2Vzcyk7CiAgICAgICAgJGNvbXBvc2VyLT5zZXRSZXBvc2l0b3J5TWFuYWdlcigkcm0pOwoKICAgICAgICAvLyBmb3JjZS1zZXQgdGhlIHZlcnNpb24gb2YgdGhlIGdsb2JhbCBwYWNrYWdlIGlmIG5vdCBkZWZpbmVkIGFzCiAgICAgICAgLy8gZ3Vlc3NpbmcgaXQgYWRkcyBubyB2YWx1ZSBhbmQgb25seSB0YWtlcyB0aW1lCiAgICAgICAgaWYgKCEkZnVsbExvYWQgJiYgIWlzc2V0KCRsb2NhbENvbmZpZ1sndmVyc2lvbiddKSkgewogICAgICAgICAgICAkbG9jYWxDb25maWdbJ3ZlcnNpb24nXSA9ICcxLjAuMCc7CiAgICAgICAgfQoKICAgICAgICAvLyBsb2FkIHBhY2thZ2UKICAgICAgICAkcGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgJGd1ZXNzZXIgPSBuZXcgVmVyc2lvbkd1ZXNzZXIoJGNvbmZpZywgJHByb2Nlc3MsICRwYXJzZXIpOwogICAgICAgICRsb2FkZXIgPSAkdGhpcy0+bG9hZFJvb3RQYWNrYWdlKCRybSwgJGNvbmZpZywgJHBhcnNlciwgJGd1ZXNzZXIsICRpbyk7CiAgICAgICAgJHBhY2thZ2UgPSAkbG9hZGVyLT5sb2FkKCRsb2NhbENvbmZpZywgJ0NvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2UnLCAkY3dkKTsKICAgICAgICAkY29tcG9zZXItPnNldFBhY2thZ2UoJHBhY2thZ2UpOwoKICAgICAgICAvLyBsb2FkIGxvY2FsIHJlcG9zaXRvcnkKICAgICAgICAkdGhpcy0+YWRkTG9jYWxSZXBvc2l0b3J5KCRpbywgJHJtLCAkdmVuZG9yRGlyLCAkcGFja2FnZSwgJHByb2Nlc3MpOwoKICAgICAgICAvLyBpbml0aWFsaXplIGluc3RhbGxhdGlvbiBtYW5hZ2VyCiAgICAgICAgJGltID0gJHRoaXMtPmNyZWF0ZUluc3RhbGxhdGlvbk1hbmFnZXIoJGxvb3AsICRpbywgJGRpc3BhdGNoZXIpOwogICAgICAgICRjb21wb3Nlci0+c2V0SW5zdGFsbGF0aW9uTWFuYWdlcigkaW0pOwoKICAgICAgICBpZiAoJGZ1bGxMb2FkKSB7CiAgICAgICAgICAgIC8vIGluaXRpYWxpemUgZG93bmxvYWQgbWFuYWdlcgogICAgICAgICAgICAkZG0gPSAkdGhpcy0+Y3JlYXRlRG93bmxvYWRNYW5hZ2VyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkcHJvY2VzcywgJGRpc3BhdGNoZXIpOwogICAgICAgICAgICAkY29tcG9zZXItPnNldERvd25sb2FkTWFuYWdlcigkZG0pOwoKICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSBhdXRvbG9hZCBnZW5lcmF0b3IKICAgICAgICAgICAgJGdlbmVyYXRvciA9IG5ldyBBdXRvbG9hZEdlbmVyYXRvcigkZGlzcGF0Y2hlciwgJGlvKTsKICAgICAgICAgICAgJGNvbXBvc2VyLT5zZXRBdXRvbG9hZEdlbmVyYXRvcigkZ2VuZXJhdG9yKTsKCiAgICAgICAgICAgIC8vIGluaXRpYWxpemUgYXJjaGl2ZSBtYW5hZ2VyCiAgICAgICAgICAgICRhbSA9ICR0aGlzLT5jcmVhdGVBcmNoaXZlTWFuYWdlcigkY29uZmlnLCAkZG0sICRsb29wKTsKICAgICAgICAgICAgJGNvbXBvc2VyLT5zZXRBcmNoaXZlTWFuYWdlcigkYW0pOwogICAgICAgIH0KCiAgICAgICAgLy8gYWRkIGluc3RhbGxlcnMgdG8gdGhlIG1hbmFnZXIgKG11c3QgaGFwcGVuIGFmdGVyIGRvd25sb2FkIG1hbmFnZXIgaXMgY3JlYXRlZCBzaW5jZSB0aGV5IHJlYWQgaXQgb3V0IG9mICRjb21wb3NlcikKICAgICAgICAkdGhpcy0+Y3JlYXRlRGVmYXVsdEluc3RhbGxlcnMoJGltLCAkY29tcG9zZXIsICRpbywgJHByb2Nlc3MpOwoKICAgICAgICBpZiAoJGZ1bGxMb2FkKSB7CiAgICAgICAgICAgICRnbG9iYWxDb21wb3NlciA9IG51bGw7CiAgICAgICAgICAgIGlmIChyZWFscGF0aCgkY29uZmlnLT5nZXQoJ2hvbWUnKSkgIT09ICRjd2QpIHsKICAgICAgICAgICAgICAgICRnbG9iYWxDb21wb3NlciA9ICR0aGlzLT5jcmVhdGVHbG9iYWxDb21wb3NlcigkaW8sICRjb25maWcsICRkaXNhYmxlUGx1Z2lucywgJGRpc2FibGVTY3JpcHRzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBtID0gJHRoaXMtPmNyZWF0ZVBsdWdpbk1hbmFnZXIoJGlvLCAkY29tcG9zZXIsICRnbG9iYWxDb21wb3NlciwgJGRpc2FibGVQbHVnaW5zKTsKICAgICAgICAgICAgJGNvbXBvc2VyLT5zZXRQbHVnaW5NYW5hZ2VyKCRwbSk7CgogICAgICAgICAgICAkcG0tPmxvYWRJbnN0YWxsZWRQbHVnaW5zKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBpbml0IGxvY2tlciBpZiBwb3NzaWJsZQogICAgICAgIGlmICgkZnVsbExvYWQgJiYgaXNzZXQoJGNvbXBvc2VyRmlsZSkpIHsKICAgICAgICAgICAgJGxvY2tGaWxlID0gc2VsZjo6Z2V0TG9ja0ZpbGUoJGNvbXBvc2VyRmlsZSk7CgogICAgICAgICAgICAkbG9ja2VyID0gbmV3IFBhY2thZ2VcTG9ja2VyKCRpbywgbmV3IEpzb25GaWxlKCRsb2NrRmlsZSwgbnVsbCwgJGlvKSwgJGltLCBmaWxlX2dldF9jb250ZW50cygkY29tcG9zZXJGaWxlKSwgJHByb2Nlc3MpOwogICAgICAgICAgICAkY29tcG9zZXItPnNldExvY2tlcigkbG9ja2VyKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZnVsbExvYWQpIHsKICAgICAgICAgICAgJGluaXRFdmVudCA9IG5ldyBFdmVudChQbHVnaW5FdmVudHM6OklOSVQpOwogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaCgkaW5pdEV2ZW50LT5nZXROYW1lKCksICRpbml0RXZlbnQpOwoKICAgICAgICAgICAgLy8gb25jZSBldmVyeXRoaW5nIGlzIGluaXRpYWxpemVkIHdlIGNhbgogICAgICAgICAgICAvLyBwdXJnZSBwYWNrYWdlcyBmcm9tIGxvY2FsIHJlcG9zIGlmIHRoZXkgaGF2ZSBiZWVuIGRlbGV0ZWQgb24gdGhlIGZpbGVzeXN0ZW0KICAgICAgICAgICAgJHRoaXMtPnB1cmdlUGFja2FnZXMoJHJtLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSwgJGltKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICAgJGlvICAgICAgICAgICAgIElPIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgJGRpc2FibGVQbHVnaW5zIFdoZXRoZXIgcGx1Z2lucyBzaG91bGQgbm90IGJlIGxvYWRlZAogICAgICogQHBhcmFtICBib29sICAgICAgICAgICRkaXNhYmxlU2NyaXB0cyBXaGV0aGVyIHNjcmlwdHMgc2hvdWxkIG5vdCBiZSBleGVjdXRlZAogICAgICogQHJldHVybiBDb21wb3NlcnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlR2xvYmFsKElPSW50ZXJmYWNlICRpbywgJGRpc2FibGVQbHVnaW5zID0gZmFsc2UsICRkaXNhYmxlU2NyaXB0cyA9IGZhbHNlKQogICAgewogICAgICAgICRmYWN0b3J5ID0gbmV3IHN0YXRpYygpOwoKICAgICAgICByZXR1cm4gJGZhY3RvcnktPmNyZWF0ZUdsb2JhbENvbXBvc2VyKCRpbywgc3RhdGljOjpjcmVhdGVDb25maWcoJGlvKSwgJGRpc2FibGVQbHVnaW5zLCAkZGlzYWJsZVNjcmlwdHMsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlcUmVwb3NpdG9yeU1hbmFnZXIgJHJtCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAkdmVuZG9yRGlyCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRMb2NhbFJlcG9zaXRvcnkoSU9JbnRlcmZhY2UgJGlvLCBSZXBvc2l0b3J5TWFuYWdlciAkcm0sICR2ZW5kb3JEaXIsIFJvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZSwgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCkKICAgIHsKICAgICAgICAkZnMgPSBudWxsOwogICAgICAgIGlmICgkcHJvY2VzcykgewogICAgICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgkcHJvY2Vzcyk7CiAgICAgICAgfQoKICAgICAgICAkcm0tPnNldExvY2FsUmVwb3NpdG9yeShuZXcgUmVwb3NpdG9yeVxJbnN0YWxsZWRGaWxlc3lzdGVtUmVwb3NpdG9yeShuZXcgSnNvbkZpbGUoJHZlbmRvckRpci4nL2NvbXBvc2VyL2luc3RhbGxlZC5qc29uJywgbnVsbCwgJGlvKSwgdHJ1ZSwgJHJvb3RQYWNrYWdlLCAkZnMpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRkaXNhYmxlUGx1Z2lucwogICAgICogQHBhcmFtIGJvb2wgJGRpc2FibGVTY3JpcHRzCiAgICAgKiBAcGFyYW0gYm9vbCAkZnVsbExvYWQKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZUdsb2JhbENvbXBvc2VyKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICRkaXNhYmxlUGx1Z2lucywgJGRpc2FibGVTY3JpcHRzLCAkZnVsbExvYWQgPSBmYWxzZSkKICAgIHsKICAgICAgICAkY29tcG9zZXIgPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5jcmVhdGVDb21wb3NlcigkaW8sICRjb25maWctPmdldCgnaG9tZScpIC4gJy9jb21wb3Nlci5qc29uJywgJGRpc2FibGVQbHVnaW5zLCAkY29uZmlnLT5nZXQoJ2hvbWUnKSwgJGZ1bGxMb2FkLCAkZGlzYWJsZVNjcmlwdHMpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdGYWlsZWQgdG8gaW5pdGlhbGl6ZSBnbG9iYWwgY29tcG9zZXI6ICcuJGUtPmdldE1lc3NhZ2UoKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPXElPSW50ZXJmYWNlICAgICAgICAgICAgICRpbwogICAgICogQHBhcmFtICBDb25maWcgICAgICAgICAgICAgICAgICAgICAkY29uZmlnCiAgICAgKiBAcGFyYW0gIEV2ZW50RGlzcGF0Y2hlciAgICAgICAgICAgICRldmVudERpc3BhdGNoZXIKICAgICAqIEByZXR1cm4gRG93bmxvYWRlclxEb3dubG9hZE1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyZWF0ZURvd25sb2FkTWFuYWdlcihJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcywgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsKQogICAgewogICAgICAgICRjYWNoZSA9IG51bGw7CiAgICAgICAgaWYgKCRjb25maWctPmdldCgnY2FjaGUtZmlsZXMtdHRsJykgPiAwKSB7CiAgICAgICAgICAgICRjYWNoZSA9IG5ldyBDYWNoZSgkaW8sICRjb25maWctPmdldCgnY2FjaGUtZmlsZXMtZGlyJyksICdhLXowLTlfLi8nKTsKICAgICAgICAgICAgJGNhY2hlLT5zZXRSZWFkT25seSgkY29uZmlnLT5nZXQoJ2NhY2hlLXJlYWQtb25seScpKTsKICAgICAgICB9CgogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCRwcm9jZXNzKTsKCiAgICAgICAgJGRtID0gbmV3IERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyKCRpbywgZmFsc2UsICRmcyk7CiAgICAgICAgc3dpdGNoICgkcHJlZmVycmVkID0gJGNvbmZpZy0+Z2V0KCdwcmVmZXJyZWQtaW5zdGFsbCcpKSB7CiAgICAgICAgICAgIGNhc2UgJ2Rpc3QnOgogICAgICAgICAgICAgICAgJGRtLT5zZXRQcmVmZXJEaXN0KHRydWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6CiAgICAgICAgICAgICAgICAkZG0tPnNldFByZWZlclNvdXJjZSh0cnVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdhdXRvJzoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIG5vb3AKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX2FycmF5KCRwcmVmZXJyZWQpKSB7CiAgICAgICAgICAgICRkbS0+c2V0UHJlZmVyZW5jZXMoJHByZWZlcnJlZCk7CiAgICAgICAgfQoKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ2dpdCcsIG5ldyBEb3dubG9hZGVyXEdpdERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkcHJvY2VzcywgJGZzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCdzdm4nLCBuZXcgRG93bmxvYWRlclxTdm5Eb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJHByb2Nlc3MsICRmcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcignZm9zc2lsJywgbmV3IERvd25sb2FkZXJcRm9zc2lsRG93bmxvYWRlcigkaW8sICRjb25maWcsICRwcm9jZXNzLCAkZnMpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ2hnJywgbmV3IERvd25sb2FkZXJcSGdEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJHByb2Nlc3MsICRmcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcigncGVyZm9yY2UnLCBuZXcgRG93bmxvYWRlclxQZXJmb3JjZURvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkcHJvY2VzcywgJGZzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCd6aXAnLCBuZXcgRG93bmxvYWRlclxaaXBEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkZXZlbnREaXNwYXRjaGVyLCAkY2FjaGUsICRmcywgJHByb2Nlc3MpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ3JhcicsIG5ldyBEb3dubG9hZGVyXFJhckRvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRldmVudERpc3BhdGNoZXIsICRjYWNoZSwgJGZzLCAkcHJvY2VzcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcigndGFyJywgbmV3IERvd25sb2FkZXJcVGFyRG93bmxvYWRlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJGNhY2hlLCAkZnMsICRwcm9jZXNzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCdnemlwJywgbmV3IERvd25sb2FkZXJcR3ppcERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRldmVudERpc3BhdGNoZXIsICRjYWNoZSwgJGZzLCAkcHJvY2VzcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcigneHonLCBuZXcgRG93bmxvYWRlclxYekRvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRldmVudERpc3BhdGNoZXIsICRjYWNoZSwgJGZzLCAkcHJvY2VzcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcigncGhhcicsIG5ldyBEb3dubG9hZGVyXFBoYXJEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkZXZlbnREaXNwYXRjaGVyLCAkY2FjaGUsICRmcywgJHByb2Nlc3MpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ2ZpbGUnLCBuZXcgRG93bmxvYWRlclxGaWxlRG93bmxvYWRlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJGNhY2hlLCAkZnMsICRwcm9jZXNzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCdwYXRoJywgbmV3IERvd25sb2FkZXJcUGF0aERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRldmVudERpc3BhdGNoZXIsICRjYWNoZSwgJGZzLCAkcHJvY2VzcykpOwoKICAgICAgICByZXR1cm4gJGRtOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBDb25maWcgICAgICAgICAgICAgICAgICAgICAkY29uZmlnIFRoZSBjb25maWd1cmF0aW9uCiAgICAgKiBAcGFyYW0gIERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyICRkbSAgICAgTWFuYWdlciB1c2UgdG8gZG93bmxvYWQgc291cmNlcwogICAgICogQHJldHVybiBBcmNoaXZlclxBcmNoaXZlTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlQXJjaGl2ZU1hbmFnZXIoQ29uZmlnICRjb25maWcsIERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyICRkbSwgTG9vcCAkbG9vcCkKICAgIHsKICAgICAgICAkYW0gPSBuZXcgQXJjaGl2ZXJcQXJjaGl2ZU1hbmFnZXIoJGRtLCAkbG9vcCk7CiAgICAgICAgJGFtLT5hZGRBcmNoaXZlcihuZXcgQXJjaGl2ZXJcWmlwQXJjaGl2ZXIpOwogICAgICAgICRhbS0+YWRkQXJjaGl2ZXIobmV3IEFyY2hpdmVyXFBoYXJBcmNoaXZlcik7CgogICAgICAgIHJldHVybiAkYW07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICAgICAgICAgICRpbwogICAgICogQHBhcmFtICBDb21wb3NlciAgICAgICAgICAgICAkY29tcG9zZXIKICAgICAqIEBwYXJhbSAgQ29tcG9zZXIgICAgICAgICAgICAgJGdsb2JhbENvbXBvc2VyCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICRkaXNhYmxlUGx1Z2lucwogICAgICogQHJldHVybiBQbHVnaW5cUGx1Z2luTWFuYWdlcgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY3JlYXRlUGx1Z2luTWFuYWdlcihJT0ludGVyZmFjZSAkaW8sIENvbXBvc2VyICRjb21wb3NlciwgQ29tcG9zZXIgJGdsb2JhbENvbXBvc2VyID0gbnVsbCwgJGRpc2FibGVQbHVnaW5zID0gZmFsc2UpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBQbHVnaW5cUGx1Z2luTWFuYWdlcigkaW8sICRjb21wb3NlciwgJGdsb2JhbENvbXBvc2VyLCAkZGlzYWJsZVBsdWdpbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlSW5zdGFsbGF0aW9uTWFuYWdlcihMb29wICRsb29wLCBJT0ludGVyZmFjZSAkaW8sIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyKCRsb29wLCAkaW8sICRldmVudERpc3BhdGNoZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0SW5zdGFsbGVycyhJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlciAkaW0sIENvbXBvc2VyICRjb21wb3NlciwgSU9JbnRlcmZhY2UgJGlvLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCRwcm9jZXNzKTsKICAgICAgICAkYmluYXJ5SW5zdGFsbGVyID0gbmV3IEluc3RhbGxlclxCaW5hcnlJbnN0YWxsZXIoJGlvLCBydHJpbSgkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2Jpbi1kaXInKSwgJy8nKSwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdiaW4tY29tcGF0JyksICRmcywgcnRyaW0oJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCd2ZW5kb3ItZGlyJyksICcvJykpOwoKICAgICAgICAkaW0tPmFkZEluc3RhbGxlcihuZXcgSW5zdGFsbGVyXExpYnJhcnlJbnN0YWxsZXIoJGlvLCAkY29tcG9zZXIsIG51bGwsICRmcywgJGJpbmFyeUluc3RhbGxlcikpOwogICAgICAgICRpbS0+YWRkSW5zdGFsbGVyKG5ldyBJbnN0YWxsZXJcUGx1Z2luSW5zdGFsbGVyKCRpbywgJGNvbXBvc2VyLCAkZnMsICRiaW5hcnlJbnN0YWxsZXIpKTsKICAgICAgICAkaW0tPmFkZEluc3RhbGxlcihuZXcgSW5zdGFsbGVyXE1ldGFwYWNrYWdlSW5zdGFsbGVyKCRpbykpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgICAkcmVwbyByZXBvc2l0b3J5IHRvIHB1cmdlIHBhY2thZ2VzIGZyb20KICAgICAqIEBwYXJhbSBJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlciAgJGltICAgbWFuYWdlciB0byBjaGVjayB3aGV0aGVyIHBhY2thZ2VzIGFyZSBzdGlsbCBpbnN0YWxsZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHB1cmdlUGFja2FnZXMoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXIgJGltKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghJGltLT5pc1BhY2thZ2VJbnN0YWxsZWQoJHJlcG8sICRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgJHJlcG8tPnJlbW92ZVBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQYWNrYWdlXExvYWRlclxSb290UGFja2FnZUxvYWRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gbG9hZFJvb3RQYWNrYWdlKFJlcG9zaXRvcnlNYW5hZ2VyICRybSwgQ29uZmlnICRjb25maWcsIFZlcnNpb25QYXJzZXIgJHBhcnNlciwgVmVyc2lvbkd1ZXNzZXIgJGd1ZXNzZXIsIElPSW50ZXJmYWNlICRpbykKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFBhY2thZ2VcTG9hZGVyXFJvb3RQYWNrYWdlTG9hZGVyKCRybSwgJGNvbmZpZywgJHBhcnNlciwgJGd1ZXNzZXIsICRpbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICRpbyAgICAgICAgICAgICBJTyBpbnN0YW5jZQogICAgICogQHBhcmFtICBtaXhlZCAgICAgICAkY29uZmlnICAgICAgICAgZWl0aGVyIGEgY29uZmlndXJhdGlvbiBhcnJheSBvciBhIGZpbGVuYW1lIHRvIHJlYWQgZnJvbSwgaWYgbnVsbCBpdCB3aWxsIHJlYWQgZnJvbQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGRlZmF1bHQgZmlsZW5hbWUKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgJGRpc2FibGVQbHVnaW5zIFdoZXRoZXIgcGx1Z2lucyBzaG91bGQgbm90IGJlIGxvYWRlZAogICAgICogQHBhcmFtICBib29sICAgICAgICAkZGlzYWJsZVNjcmlwdHMgV2hldGhlciBzY3JpcHRzIHNob3VsZCBub3QgYmUgcnVuCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKElPSW50ZXJmYWNlICRpbywgJGNvbmZpZyA9IG51bGwsICRkaXNhYmxlUGx1Z2lucyA9IGZhbHNlLCAkZGlzYWJsZVNjcmlwdHMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkZmFjdG9yeSA9IG5ldyBzdGF0aWMoKTsKCiAgICAgICAgcmV0dXJuICRmYWN0b3J5LT5jcmVhdGVDb21wb3NlcigkaW8sICRjb25maWcsICRkaXNhYmxlUGx1Z2lucywgbnVsbCwgdHJ1ZSwgJGRpc2FibGVTY3JpcHRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIElmIHlvdSBhcmUgY2FsbGluZyB0aGlzIGluIGEgcGx1Z2luLCB5b3UgcHJvYmFibHkgc2hvdWxkIGluc3RlYWQgdXNlICRjb21wb3Nlci0+Z2V0TG9vcCgpLT5nZXRIdHRwRG93bmxvYWRlcigpCiAgICAgKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZSAgICAkaW8gICAgICBJTyBpbnN0YW5jZQogICAgICogQHBhcmFtICBDb25maWcgICAgICAgICAkY29uZmlnICBDb25maWcgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgbWl4ZWRbXSAgICAgICAgJG9wdGlvbnMgQXJyYXkgb2Ygb3B0aW9ucyBwYXNzZWQgZGlyZWN0bHkgdG8gSHR0cERvd25sb2FkZXIgY29uc3RydWN0b3IKICAgICAqIEByZXR1cm4gSHR0cERvd25sb2FkZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVIdHRwRG93bmxvYWRlcihJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgc3RhdGljICR3YXJuZWQgPSBmYWxzZTsKICAgICAgICAkZGlzYWJsZVRscyA9IGZhbHNlOwogICAgICAgIC8vIGFsbG93IHJ1bm5pbmcgdGhlIGNvbmZpZyBjb21tYW5kIGlmIGRpc2FibGUtdGxzIGlzIGluIHRoZSBhcmcgbGlzdCwgZXZlbiBpZiBvcGVuc3NsIGlzIG1pc3NpbmcsIHRvIGFsbG93IGRpc2FibGluZyBpdCB2aWEgdGhlIGNvbmZpZyBjb21tYW5kCiAgICAgICAgaWYgKGlzc2V0KCRfU0VSVkVSWydhcmd2J10pICYmIGluX2FycmF5KCdkaXNhYmxlLXRscycsICRfU0VSVkVSWydhcmd2J10pICYmIChpbl9hcnJheSgnY29uZicsICRfU0VSVkVSWydhcmd2J10pIHx8IGluX2FycmF5KCdjb25maWcnLCAkX1NFUlZFUlsnYXJndiddKSkpIHsKICAgICAgICAgICAgJHdhcm5lZCA9IHRydWU7CiAgICAgICAgICAgICRkaXNhYmxlVGxzID0gIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKTsKICAgICAgICB9IGVsc2VpZiAoJGNvbmZpZy0+Z2V0KCdkaXNhYmxlLXRscycpID09PSB0cnVlKSB7CiAgICAgICAgICAgIGlmICghJHdhcm5lZCkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHJ1bm5pbmcgQ29tcG9zZXIgd2l0aCBTU0wvVExTIHByb3RlY3Rpb24gZGlzYWJsZWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR3YXJuZWQgPSB0cnVlOwogICAgICAgICAgICAkZGlzYWJsZVRscyA9IHRydWU7CiAgICAgICAgfSBlbHNlaWYgKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvblxOb1NzbEV4Y2VwdGlvbignVGhlIG9wZW5zc2wgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkIGZvciBTU0wvVExTIHByb3RlY3Rpb24gYnV0IGlzIG5vdCBhdmFpbGFibGUuICcKICAgICAgICAgICAgICAgIC4gJ0lmIHlvdSBjYW4gbm90IGVuYWJsZSB0aGUgb3BlbnNzbCBleHRlbnNpb24sIHlvdSBjYW4gZGlzYWJsZSB0aGlzIGVycm9yLCBhdCB5b3VyIG93biByaXNrLCBieSBzZXR0aW5nIHRoZSBcJ2Rpc2FibGUtdGxzXCcgb3B0aW9uIHRvIHRydWUuJyk7CiAgICAgICAgfQogICAgICAgICRodHRwRG93bmxvYWRlck9wdGlvbnMgPSBhcnJheSgpOwogICAgICAgIGlmICgkZGlzYWJsZVRscyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgaWYgKCRjb25maWctPmdldCgnY2FmaWxlJykpIHsKICAgICAgICAgICAgICAgICRodHRwRG93bmxvYWRlck9wdGlvbnNbJ3NzbCddWydjYWZpbGUnXSA9ICRjb25maWctPmdldCgnY2FmaWxlJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRjb25maWctPmdldCgnY2FwYXRoJykpIHsKICAgICAgICAgICAgICAgICRodHRwRG93bmxvYWRlck9wdGlvbnNbJ3NzbCddWydjYXBhdGgnXSA9ICRjb25maWctPmdldCgnY2FwYXRoJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGh0dHBEb3dubG9hZGVyT3B0aW9ucyA9IGFycmF5X3JlcGxhY2VfcmVjdXJzaXZlKCRodHRwRG93bmxvYWRlck9wdGlvbnMsICRvcHRpb25zKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGh0dHBEb3dubG9hZGVyID0gbmV3IEh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyT3B0aW9ucywgJGRpc2FibGVUbHMpOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkZS0+Z2V0TWVzc2FnZSgpLCAnY2FmaWxlJykpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxlcnJvcj5VbmFibGUgdG8gbG9jYXRlIGEgdmFsaWQgQ0EgY2VydGlmaWNhdGUgZmlsZS4gWW91IG11c3Qgc2V0IGEgdmFsaWQgXCdjYWZpbGVcJyBvcHRpb24uPC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxlcnJvcj5BIHZhbGlkIENBIGNlcnRpZmljYXRlIGZpbGUgaXMgcmVxdWlyZWQgZm9yIFNTTC9UTFMgcHJvdGVjdGlvbi48L2Vycm9yPicpOwogICAgICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNTA2MDApIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8ZXJyb3I+SXQgaXMgcmVjb21tZW5kZWQgeW91IHVwZ3JhZGUgdG8gUEhQIDUuNisgd2hpY2ggY2FuIGRldGVjdCB5b3VyIHN5c3RlbSBDQSBmaWxlIGF1dG9tYXRpY2FsbHkuPC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxlcnJvcj5Zb3UgY2FuIGRpc2FibGUgdGhpcyBlcnJvciwgYXQgeW91ciBvd24gcmlzaywgYnkgc2V0dGluZyB0aGUgXCdkaXNhYmxlLXRsc1wnIG9wdGlvbiB0byB0cnVlLjwvZXJyb3I+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGh0dHBEb3dubG9hZGVyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHVzZVhkZygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cygkX1NFUlZFUikgYXMgJGtleSkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRrZXksICdYREdfJykgPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoU2lsZW5jZXI6OmNhbGwoJ2lzX2RpcicsICcvZXRjL3hkZycpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0VXNlckRpcigpCiAgICB7CiAgICAgICAgJGhvbWUgPSBQbGF0Zm9ybTo6Z2V0RW52KCdIT01FJyk7CiAgICAgICAgaWYgKCEkaG9tZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBIT01FIG9yIENPTVBPU0VSX0hPTUUgZW52aXJvbm1lbnQgdmFyaWFibGUgbXVzdCBiZSBzZXQgZm9yIGNvbXBvc2VyIHRvIHJ1biBjb3JyZWN0bHknKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBydHJpbShzdHJ0cigkaG9tZSwgJ1xcJywgJy8nKSwgJy8nKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlcjsKCnVzZSBDb21wb3NlclxBdXRvbG9hZFxBdXRvbG9hZEdlbmVyYXRvcjsKdXNlIENvbXBvc2VyXENvbnNvbGVcR2l0aHViQWN0aW9uRXJyb3I7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcRGVmYXVsdFBvbGljeTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxMb2NhbFJlcG9UcmFuc2FjdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxMb2NrVHJhbnNhY3Rpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVwZGF0ZU9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVW5pbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFBvb2xPcHRpbWl6ZXI7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUG9vbDsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFNvbHZlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxTb2x2ZXJQcm9ibGVtc0V4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxQb2xpY3lJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXERvd25sb2FkTWFuYWdlcjsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlclxJZ25vcmVMaXN0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcjsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5Owp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxlckV2ZW50czsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxBcnJheVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQ7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XENvbXBvc2l0ZVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2NrZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRBcnJheVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5TWFuYWdlcjsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcTG9ja0FycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNjcmlwdFxTY3JpcHRFdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBCZWF1IFNpbWVuc2VuIDxiZWF1QGRmbHlkZXYuY29tPgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgSW5zdGFsbGVyCnsKICAgIGNvbnN0IEVSUk9SX05PTkUgPSAwOyAvLyBubyBlcnJvci9zdWNjZXNzIHN0YXRlCiAgICBjb25zdCBFUlJPUl9HRU5FUklDX0ZBSUxVUkUgPSAxOwogICAgY29uc3QgRVJST1JfTk9fTE9DS19GSUxFX0ZPUl9QQVJUSUFMX1VQREFURSA9IDM7CiAgICBjb25zdCBFUlJPUl9MT0NLX0ZJTEVfSU5WQUxJRCA9IDQ7CiAgICAvLyB1c2VkL2RlY2xhcmVkIGluIFNvbHZlclByb2JsZW1zRXhjZXB0aW9uLCBjYXJyaWVkIG92ZXIgaGVyZSBmb3IgY29tcGxldGVuZXNzCiAgICBjb25zdCBFUlJPUl9ERVBFTkRFTkNZX1JFU09MVVRJT05fRkFJTEVEID0gMjsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKioKICAgICAqIEB2YXIgQ29uZmlnCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnOwoKICAgIC8qKgogICAgICogQHZhciBSb290UGFja2FnZUludGVyZmFjZSZCYXNlUGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgLy8gVE9ETyBjYW4gd2UgZ2V0IHJpZCBvZiB0aGUgYmVsb3cgYW5kIGp1c3QgdXNlIHRoZSBwYWNrYWdlIGl0c2VsZj8KICAgIC8qKgogICAgICogQHZhciBSb290UGFja2FnZUludGVyZmFjZSZCYXNlUGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGZpeGVkUm9vdFBhY2thZ2U7CgogICAgLyoqCiAgICAgKiBAdmFyIERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGRvd25sb2FkTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgUmVwb3NpdG9yeU1hbmFnZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRyZXBvc2l0b3J5TWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgTG9ja2VyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbG9ja2VyOwoKICAgIC8qKgogICAgICogQHZhciBJbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5zdGFsbGF0aW9uTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgRXZlbnREaXNwYXRjaGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXZlbnREaXNwYXRjaGVyOwoKICAgIC8qKgogICAgICogQHZhciBBdXRvbG9hZEdlbmVyYXRvcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGF1dG9sb2FkR2VuZXJhdG9yOwoKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkcHJlZmVyU291cmNlID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJHByZWZlckRpc3QgPSBmYWxzZTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkb3B0aW1pemVBdXRvbG9hZGVyID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZSA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRhcGN1QXV0b2xvYWRlciA9IGZhbHNlOwogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByb3RlY3RlZCAkYXBjdUF1dG9sb2FkZXJQcmVmaXggPSBudWxsOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRkZXZNb2RlID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGRyeVJ1biA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICR2ZXJib3NlID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJHVwZGF0ZSA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRpbnN0YWxsID0gdHJ1ZTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkZHVtcEF1dG9sb2FkZXIgPSB0cnVlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRydW5TY3JpcHRzID0gdHJ1ZTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkcHJlZmVyU3RhYmxlID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJHByZWZlckxvd2VzdCA9IGZhbHNlOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICR3cml0ZUxvY2s7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGV4ZWN1dGVPcGVyYXRpb25zID0gdHJ1ZTsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJHVwZGF0ZU1pcnJvcnMgPSBmYWxzZTsKICAgIC8qKgogICAgICogQXJyYXkgb2YgcGFja2FnZSBuYW1lcy9nbG9icyBmbGFnZ2VkIGZvciB1cGRhdGUKICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ1tdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkICR1cGRhdGVBbGxvd0xpc3QgPSBudWxsOwogICAgLyoqIEB2YXIgUmVxdWVzdDo6VVBEQVRFXyogKi8KICAgIHByb3RlY3RlZCAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX09OTFlfTElTVEVEOwoKICAgIC8qKgogICAgICogQHZhciBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcjsKCiAgICAvKioKICAgICAqIEB2YXIgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CgogICAgLyoqCiAgICAgKiBAdmFyID9SZXBvc2l0b3J5SW50ZXJmYWNlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAgICAgICRpbwogICAgICogQHBhcmFtIENvbmZpZyAgICAgICAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSBSb290UGFja2FnZUludGVyZmFjZSZCYXNlUGFja2FnZSAkcGFja2FnZQogICAgICogQHBhcmFtIERvd25sb2FkTWFuYWdlciAgICAgICRkb3dubG9hZE1hbmFnZXIKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5TWFuYWdlciAgICAkcmVwb3NpdG9yeU1hbmFnZXIKICAgICAqIEBwYXJhbSBMb2NrZXIgICAgICAgICAgICAgICAkbG9ja2VyCiAgICAgKiBAcGFyYW0gSW5zdGFsbGF0aW9uTWFuYWdlciAgJGluc3RhbGxhdGlvbk1hbmFnZXIKICAgICAqIEBwYXJhbSBFdmVudERpc3BhdGNoZXIgICAgICAkZXZlbnREaXNwYXRjaGVyCiAgICAgKiBAcGFyYW0gQXV0b2xvYWRHZW5lcmF0b3IgICAgJGF1dG9sb2FkR2VuZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBSb290UGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgRG93bmxvYWRNYW5hZ2VyICRkb3dubG9hZE1hbmFnZXIsIFJlcG9zaXRvcnlNYW5hZ2VyICRyZXBvc2l0b3J5TWFuYWdlciwgTG9ja2VyICRsb2NrZXIsIEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIsIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyLCBBdXRvbG9hZEdlbmVyYXRvciAkYXV0b2xvYWRHZW5lcmF0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5wYWNrYWdlID0gJHBhY2thZ2U7CiAgICAgICAgJHRoaXMtPmRvd25sb2FkTWFuYWdlciA9ICRkb3dubG9hZE1hbmFnZXI7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlNYW5hZ2VyID0gJHJlcG9zaXRvcnlNYW5hZ2VyOwogICAgICAgICR0aGlzLT5sb2NrZXIgPSAkbG9ja2VyOwogICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyID0gJGluc3RhbGxhdGlvbk1hbmFnZXI7CiAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlciA9ICRldmVudERpc3BhdGNoZXI7CiAgICAgICAgJHRoaXMtPmF1dG9sb2FkR2VuZXJhdG9yID0gJGF1dG9sb2FkR2VuZXJhdG9yOwogICAgICAgICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyID0gbmV3IFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIoJHRoaXMtPmlvKTsKICAgICAgICAkdGhpcy0+cGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciA9IFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5OjppZ25vcmVOb3RoaW5nKCk7CgogICAgICAgICR0aGlzLT53cml0ZUxvY2sgPSAkY29uZmlnLT5nZXQoJ2xvY2snKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1biBpbnN0YWxsYXRpb24gKG9yIHVwZGF0ZSkKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqIEByZXR1cm4gaW50ICAgICAgICAwIG9uIHN1Y2Nlc3Mgb3IgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUKICAgICAqIEBwaHBzdGFuLXJldHVybiBzZWxmOjpFUlJPUl8qCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBydW4oKQogICAgewogICAgICAgIC8vIERpc2FibGUgR0MgdG8gc2F2ZSBDUFUgY3ljbGVzLCBhcyB0aGUgZGVwZW5kZW5jeSBzb2x2ZXIgY2FuIGNyZWF0ZSBodW5kcmVkcyBvZiB0aG91c2FuZHMKICAgICAgICAvLyBvZiBQSFAgb2JqZWN0cywgdGhlIEdDIGNhbiBzcGVuZCBxdWl0ZSBzb21lIHRpbWUgd2Fsa2luZyB0aGUgdHJlZSBvZiByZWZlcmVuY2VzIGxvb2tpbmcKICAgICAgICAvLyBmb3Igc3R1ZmYgdG8gY29sbGVjdCB3aGlsZSB0aGVyZSBpcyBub3RoaW5nIHRvIGNvbGxlY3QuIFRoaXMgc2xvd3MgdGhpbmdzIGRvd24gZHJhbWF0aWNhbGx5CiAgICAgICAgLy8gYW5kIHR1cm5pbmcgaXQgb2ZmIHJlc3VsdHMgaW4gbXVjaCBiZXR0ZXIgcGVyZm9ybWFuY2UuIERvIG5vdCB0cnkgdGhpcyBhdCBob21lIGhvd2V2ZXIuCiAgICAgICAgZ2NfY29sbGVjdF9jeWNsZXMoKTsKICAgICAgICBnY19kaXNhYmxlKCk7CgogICAgICAgIGlmICgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0ICYmICR0aGlzLT51cGRhdGVNaXJyb3JzKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiVGhlIGluc3RhbGxlciBvcHRpb25zIHVwZGF0ZU1pcnJvcnMgYW5kIHVwZGF0ZUFsbG93TGlzdCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiIpOwogICAgICAgIH0KCiAgICAgICAgJGlzRnJlc2hJbnN0YWxsID0gJHRoaXMtPnJlcG9zaXRvcnlNYW5hZ2VyLT5nZXRMb2NhbFJlcG9zaXRvcnkoKS0+aXNGcmVzaCgpOwoKICAgICAgICAvLyBGb3JjZSB1cGRhdGUgaWYgdGhlcmUgaXMgbm8gbG9jayBmaWxlIHByZXNlbnQKICAgICAgICBpZiAoISR0aGlzLT51cGRhdGUgJiYgISR0aGlzLT5sb2NrZXItPmlzTG9ja2VkKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5ObyBjb21wb3Nlci5sb2NrIGZpbGUgcHJlc2VudC4gVXBkYXRpbmcgZGVwZW5kZW5jaWVzIHRvIGxhdGVzdCBpbnN0ZWFkIG9mIGluc3RhbGxpbmcgZnJvbSBsb2NrIGZpbGUuIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9pbnN0YWxsIGZvciBtb3JlIGluZm9ybWF0aW9uLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgJHRoaXMtPnVwZGF0ZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmRyeVJ1bikgewogICAgICAgICAgICAkdGhpcy0+dmVyYm9zZSA9IHRydWU7CiAgICAgICAgICAgICR0aGlzLT5ydW5TY3JpcHRzID0gZmFsc2U7CiAgICAgICAgICAgICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucyA9IGZhbHNlOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVMb2NrID0gZmFsc2U7CiAgICAgICAgICAgICR0aGlzLT5kdW1wQXV0b2xvYWRlciA9IGZhbHNlOwogICAgICAgICAgICAkdGhpcy0+bW9ja0xvY2FsUmVwb3NpdG9yaWVzKCR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnVwZGF0ZSAmJiAhJHRoaXMtPmluc3RhbGwpIHsKICAgICAgICAgICAgJHRoaXMtPmR1bXBBdXRvbG9hZGVyID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnJ1blNjcmlwdHMpIHsKICAgICAgICAgICAgUGxhdGZvcm06OnB1dEVudignQ09NUE9TRVJfREVWX01PREUnLCAkdGhpcy0+ZGV2TW9kZSA/ICcxJyA6ICcwJyk7CgogICAgICAgICAgICAvLyBkaXNwYXRjaCBwcmUgZXZlbnQKICAgICAgICAgICAgLy8gc2hvdWxkIHdlIHRyZWF0IHRoaXMgbW9yZSBzdHJpY3RseSBhcyBydW5uaW5nIGFuIHVwZGF0ZSBhbmQgdGhlbiBydW5uaW5nIGFuIGluc3RhbGwsIHRyaWdnZXJpbmcgZXZlbnRzIG11bHRpcGxlIHRpbWVzPwogICAgICAgICAgICAkZXZlbnROYW1lID0gJHRoaXMtPnVwZGF0ZSA/IFNjcmlwdEV2ZW50czo6UFJFX1VQREFURV9DTUQgOiBTY3JpcHRFdmVudHM6OlBSRV9JTlNUQUxMX0NNRDsKICAgICAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2hTY3JpcHQoJGV2ZW50TmFtZSwgJHRoaXMtPmRldk1vZGUpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+c2V0UHJlZmVyU291cmNlKCR0aGlzLT5wcmVmZXJTb3VyY2UpOwogICAgICAgICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPnNldFByZWZlckRpc3QoJHRoaXMtPnByZWZlckRpc3QpOwoKICAgICAgICAkbG9jYWxSZXBvID0gJHRoaXMtPnJlcG9zaXRvcnlNYW5hZ2VyLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCR0aGlzLT51cGRhdGUpIHsKICAgICAgICAgICAgICAgICRyZXMgPSAkdGhpcy0+ZG9VcGRhdGUoJGxvY2FsUmVwbywgJHRoaXMtPmluc3RhbGwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJlcyA9ICR0aGlzLT5kb0luc3RhbGwoJGxvY2FsUmVwbyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRyZXMgIT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zICYmICR0aGlzLT5pbnN0YWxsICYmICR0aGlzLT5jb25maWctPmdldCgnbm90aWZ5LW9uLWluc3RhbGwnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmluc3RhbGxhdGlvbk1hbmFnZXItPm5vdGlmeUluc3RhbGxzKCR0aGlzLT5pbyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zICYmICR0aGlzLT5pbnN0YWxsICYmICR0aGlzLT5jb25maWctPmdldCgnbm90aWZ5LW9uLWluc3RhbGwnKSkgewogICAgICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlci0+bm90aWZ5SW5zdGFsbHMoJHRoaXMtPmlvKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dXBkYXRlKSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkoCiAgICAgICAgICAgICAgICAkdGhpcy0+bG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCR0aGlzLT5kZXZNb2RlKSwKICAgICAgICAgICAgICAgICR0aGlzLT5jcmVhdGVQbGF0Zm9ybVJlcG8oZmFsc2UpLAogICAgICAgICAgICAgICAgbmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeShjbG9uZSAkdGhpcy0+cGFja2FnZSksCiAgICAgICAgICAgICkpOwogICAgICAgICAgICBpZiAoJGlzRnJlc2hJbnN0YWxsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlci0+YWRkU3VnZ2VzdGlvbnNGcm9tUGFja2FnZSgkdGhpcy0+cGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXItPm91dHB1dE1pbmltYWxpc3RpYygkaW5zdGFsbGVkUmVwbyk7CiAgICAgICAgfQoKICAgICAgICAvLyBGaW5kIGFiYW5kb25lZCBwYWNrYWdlcyBhbmQgd2FybiB1c2VyCiAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnkgPSAkdGhpcy0+bG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KHRydWUpOwogICAgICAgIGZvcmVhY2ggKCRsb2NrZWRSZXBvc2l0b3J5LT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2UgfHwgISRwYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlcGxhY2VtZW50ID0gaXNfc3RyaW5nKCRwYWNrYWdlLT5nZXRSZXBsYWNlbWVudFBhY2thZ2UoKSkKICAgICAgICAgICAgICAgID8gJ1VzZSAnIC4gJHBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpIC4gJyBpbnN0ZWFkJwogICAgICAgICAgICAgICAgOiAnTm8gcmVwbGFjZW1lbnQgd2FzIHN1Z2dlc3RlZCc7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICI8d2FybmluZz5QYWNrYWdlICVzIGlzIGFiYW5kb25lZCwgeW91IHNob3VsZCBhdm9pZCB1c2luZyBpdC4gJXMuPC93YXJuaW5nPiIsCiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnQKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+ZHVtcEF1dG9sb2FkZXIpIHsKICAgICAgICAgICAgLy8gd3JpdGUgYXV0b2xvYWRlcgogICAgICAgICAgICBpZiAoJHRoaXMtPm9wdGltaXplQXV0b2xvYWRlcikgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5HZW5lcmF0aW5nIG9wdGltaXplZCBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGluZm8+R2VuZXJhdGluZyBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmF1dG9sb2FkR2VuZXJhdG9yLT5zZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+c2V0QXBjdSgkdGhpcy0+YXBjdUF1dG9sb2FkZXIsICR0aGlzLT5hcGN1QXV0b2xvYWRlclByZWZpeCk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+c2V0UnVuU2NyaXB0cygkdGhpcy0+cnVuU2NyaXB0cyk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+c2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcigkdGhpcy0+cGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcik7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+ZHVtcCgkdGhpcy0+Y29uZmlnLCAkbG9jYWxSZXBvLCAkdGhpcy0+cGFja2FnZSwgJHRoaXMtPmluc3RhbGxhdGlvbk1hbmFnZXIsICdjb21wb3NlcicsICR0aGlzLT5vcHRpbWl6ZUF1dG9sb2FkZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5pbnN0YWxsICYmICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucykgewogICAgICAgICAgICAvLyBmb3JjZSBiaW5hcmllcyByZS1nZW5lcmF0aW9uIGluIGNhc2UgdGhleSBhcmUgbWlzc2luZwogICAgICAgICAgICBmb3JlYWNoICgkbG9jYWxSZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlci0+ZW5zdXJlQmluYXJpZXNQcmVzZW5jZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRmdW5kaW5nQ291bnQgPSAwOwogICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICEkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+Z2V0RnVuZGluZygpKSB7CiAgICAgICAgICAgICAgICAkZnVuZGluZ0NvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCRmdW5kaW5nQ291bnQgPiAwKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheSgKICAgICAgICAgICAgICAgIHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgIjxpbmZvPiVkIHBhY2thZ2UlcyB5b3UgYXJlIHVzaW5nICVzIGxvb2tpbmcgZm9yIGZ1bmRpbmcuPC9pbmZvPiIsCiAgICAgICAgICAgICAgICAgICAgJGZ1bmRpbmdDb3VudCwKICAgICAgICAgICAgICAgICAgICAxID09PSAkZnVuZGluZ0NvdW50ID8gJycgOiAncycsCiAgICAgICAgICAgICAgICAgICAgMSA9PT0gJGZ1bmRpbmdDb3VudCA/ICdpcycgOiAnYXJlJwogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICc8aW5mbz5Vc2UgdGhlIGBjb21wb3NlciBmdW5kYCBjb21tYW5kIHRvIGZpbmQgb3V0IG1vcmUhPC9pbmZvPicsCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5ydW5TY3JpcHRzKSB7CiAgICAgICAgICAgIC8vIGRpc3BhdGNoIHBvc3QgZXZlbnQKICAgICAgICAgICAgJGV2ZW50TmFtZSA9ICR0aGlzLT51cGRhdGUgPyBTY3JpcHRFdmVudHM6OlBPU1RfVVBEQVRFX0NNRCA6IFNjcmlwdEV2ZW50czo6UE9TVF9JTlNUQUxMX0NNRDsKICAgICAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2hTY3JpcHQoJGV2ZW50TmFtZSwgJHRoaXMtPmRldk1vZGUpOwogICAgICAgIH0KCiAgICAgICAgLy8gcmUtZW5hYmxlIEdDIGV4Y2VwdCBvbiBISFZNIHdoaWNoIHRyaWdnZXJzIGEgd2FybmluZyBoZXJlCiAgICAgICAgaWYgKCFkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICBnY19lbmFibGUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGRvSW5zdGFsbAogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gc2VsZjo6RVJST1JfKgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9VcGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvLCAkZG9JbnN0YWxsKQogICAgewogICAgICAgICRwbGF0Zm9ybVJlcG8gPSAkdGhpcy0+Y3JlYXRlUGxhdGZvcm1SZXBvKHRydWUpOwogICAgICAgICRhbGlhc2VzID0gJHRoaXMtPmdldFJvb3RBbGlhc2VzKHRydWUpOwoKICAgICAgICAkbG9ja2VkUmVwb3NpdG9yeSA9IG51bGw7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bG9ja2VyLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICAgICAkbG9ja2VkUmVwb3NpdG9yeSA9ICR0aGlzLT5sb2NrZXItPmdldExvY2tlZFJlcG9zaXRvcnkodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcU2VsZFxKc29uTGludFxQYXJzaW5nRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0IHx8ICR0aGlzLT51cGRhdGVNaXJyb3JzKSB7CiAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIHdlIGFyZSBkb2luZyBhIHBhcnRpYWwgdXBkYXRlIG9yIHVwZGF0aW5nIG1pcnJvcnMsIHRoZSBsb2NrIGZpbGUgaXMgbmVlZGVkIHNvIHdlIGVycm9yCiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBvdGhlcndpc2UsIGlnbm9yaW5nIHBhcnNlIGVycm9ycyBhcyB0aGUgbG9jayBmaWxlIHdpbGwgYmUgcmVnZW5lcmF0ZWQgZnJvbSBzY3JhdGNoIHdoZW4KICAgICAgICAgICAgLy8gZG9pbmcgYSBmdWxsIHVwZGF0ZQogICAgICAgIH0KCiAgICAgICAgaWYgKCgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0IHx8ICR0aGlzLT51cGRhdGVNaXJyb3JzKSAmJiAhJGxvY2tlZFJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Q2Fubm90IHVwZGF0ZSAnIC4gKCR0aGlzLT51cGRhdGVNaXJyb3JzID8gJ2xvY2sgZmlsZSBpbmZvcm1hdGlvbicgOiAnb25seSBhIHBhcnRpYWwgc2V0IG9mIHBhY2thZ2VzJykgLiAnIHdpdGhvdXQgYSBsb2NrIGZpbGUgcHJlc2VudC4gUnVuIGBjb21wb3NlciB1cGRhdGVgIHRvIGdlbmVyYXRlIGEgbG9jayBmaWxlLjwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKCiAgICAgICAgICAgIHJldHVybiBzZWxmOjpFUlJPUl9OT19MT0NLX0ZJTEVfRk9SX1BBUlRJQUxfVVBEQVRFOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5Mb2FkaW5nIGNvbXBvc2VyIHJlcG9zaXRvcmllcyB3aXRoIHBhY2thZ2UgaW5mb3JtYXRpb248L2luZm8+Jyk7CgogICAgICAgIC8vIGNyZWF0aW5nIHJlcG9zaXRvcnkgc2V0CiAgICAgICAgJHBvbGljeSA9ICR0aGlzLT5jcmVhdGVQb2xpY3kodHJ1ZSk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQgPSAkdGhpcy0+Y3JlYXRlUmVwb3NpdG9yeVNldCh0cnVlLCAkcGxhdGZvcm1SZXBvLCAkYWxpYXNlcyk7CiAgICAgICAgJHJlcG9zaXRvcmllcyA9ICR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlci0+Z2V0UmVwb3NpdG9yaWVzKCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAkcmVwb3NpdG9yeVNldC0+YWRkUmVwb3NpdG9yeSgkcmVwb3NpdG9yeSk7CiAgICAgICAgfQogICAgICAgIGlmICgkbG9ja2VkUmVwb3NpdG9yeSkgewogICAgICAgICAgICAkcmVwb3NpdG9yeVNldC0+YWRkUmVwb3NpdG9yeSgkbG9ja2VkUmVwb3NpdG9yeSk7CiAgICAgICAgfQoKICAgICAgICAkcmVxdWVzdCA9ICR0aGlzLT5jcmVhdGVSZXF1ZXN0KCR0aGlzLT5maXhlZFJvb3RQYWNrYWdlLCAkcGxhdGZvcm1SZXBvLCAkbG9ja2VkUmVwb3NpdG9yeSk7CiAgICAgICAgJHRoaXMtPnJlcXVpcmVQYWNrYWdlc0ZvclVwZGF0ZSgkcmVxdWVzdCwgJGxvY2tlZFJlcG9zaXRvcnksIHRydWUpOwoKICAgICAgICAvLyBwYXNzIHRoZSBhbGxvdyBsaXN0IGludG8gdGhlIHJlcXVlc3QsIHNvIHRoZSBwb29sIGJ1aWxkZXIgY2FuIGFwcGx5IGl0CiAgICAgICAgaWYgKCR0aGlzLT51cGRhdGVBbGxvd0xpc3QpIHsKICAgICAgICAgICAgJHJlcXVlc3QtPnNldFVwZGF0ZUFsbG93TGlzdCgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0LCAkdGhpcy0+dXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKTsKICAgICAgICB9CgogICAgICAgICRwb29sID0gJHJlcG9zaXRvcnlTZXQtPmNyZWF0ZVBvb2woJHJlcXVlc3QsICR0aGlzLT5pbywgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlciwgJHRoaXMtPmNyZWF0ZVBvb2xPcHRpbWl6ZXIoJHBvbGljeSkpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPlVwZGF0aW5nIGRlcGVuZGVuY2llczwvaW5mbz4nKTsKCiAgICAgICAgLy8gc29sdmUgZGVwZW5kZW5jaWVzCiAgICAgICAgJHNvbHZlciA9IG5ldyBTb2x2ZXIoJHBvbGljeSwgJHBvb2wsICR0aGlzLT5pbyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGxvY2tUcmFuc2FjdGlvbiA9ICRzb2x2ZXItPnNvbHZlKCRyZXF1ZXN0LCAkdGhpcy0+cGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcik7CiAgICAgICAgICAgICRydWxlU2V0U2l6ZSA9ICRzb2x2ZXItPmdldFJ1bGVTZXRTaXplKCk7CiAgICAgICAgICAgICRzb2x2ZXIgPSBudWxsOwogICAgICAgIH0gY2F0Y2ggKFNvbHZlclByb2JsZW1zRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRlcnIgPSAnWW91ciByZXF1aXJlbWVudHMgY291bGQgbm90IGJlIHJlc29sdmVkIHRvIGFuIGluc3RhbGxhYmxlIHNldCBvZiBwYWNrYWdlcy4nOwogICAgICAgICAgICAkcHJldHR5UHJvYmxlbSA9ICRlLT5nZXRQcmV0dHlTdHJpbmcoJHJlcG9zaXRvcnlTZXQsICRyZXF1ZXN0LCAkcG9vbCwgJHRoaXMtPmlvLT5pc1ZlcmJvc2UoKSk7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj4nLiAkZXJyIC4nPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJHByZXR0eVByb2JsZW0pOwogICAgICAgICAgICBpZiAoISR0aGlzLT5kZXZNb2RlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlJ1bm5pbmcgdXBkYXRlIHdpdGggLS1uby1kZXYgZG9lcyBub3QgbWVhbiByZXF1aXJlLWRldiBpcyBpZ25vcmVkLCBpdCBqdXN0IG1lYW5zIHRoZSBwYWNrYWdlcyB3aWxsIG5vdCBiZSBpbnN0YWxsZWQuIElmIGRldiByZXF1aXJlbWVudHMgYXJlIGJsb2NraW5nIHRoZSB1cGRhdGUgeW91IGhhdmUgdG8gcmVzb2x2ZSB0aG9zZSBwcm9ibGVtcy48L3dhcm5pbmc+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGdoZSA9IG5ldyBHaXRodWJBY3Rpb25FcnJvcigkdGhpcy0+aW8pOwogICAgICAgICAgICAkZ2hlLT5lbWl0KCRlcnIuIlxuIi4kcHJldHR5UHJvYmxlbSk7CgogICAgICAgICAgICByZXR1cm4gbWF4KHNlbGY6OkVSUk9SX0dFTkVSSUNfRkFJTFVSRSwgJGUtPmdldENvZGUoKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIkFuYWx5emVkICIuY291bnQoJHBvb2wpLiIgcGFja2FnZXMgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMiLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJBbmFseXplZCAiLiRydWxlU2V0U2l6ZS4iIHJ1bGVzIHRvIHJlc29sdmUgZGVwZW5kZW5jaWVzIiwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICAkcG9vbCA9IG51bGw7CgogICAgICAgIGlmICghJGxvY2tUcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignTm90aGluZyB0byBtb2RpZnkgaW4gbG9jayBmaWxlJyk7CiAgICAgICAgfQoKICAgICAgICAkZXhpdENvZGUgPSAkdGhpcy0+ZXh0cmFjdERldlBhY2thZ2VzKCRsb2NrVHJhbnNhY3Rpb24sICRwbGF0Zm9ybVJlcG8sICRhbGlhc2VzLCAkcG9saWN5LCAkbG9ja2VkUmVwb3NpdG9yeSk7CiAgICAgICAgaWYgKCRleGl0Q29kZSAhPT0gMCkgewogICAgICAgICAgICByZXR1cm4gJGV4aXRDb2RlOwogICAgICAgIH0KCiAgICAgICAgLy8gd3JpdGUgbG9jawogICAgICAgICRwbGF0Zm9ybVJlcXMgPSAkdGhpcy0+ZXh0cmFjdFBsYXRmb3JtUmVxdWlyZW1lbnRzKCR0aGlzLT5wYWNrYWdlLT5nZXRSZXF1aXJlcygpKTsKICAgICAgICAkcGxhdGZvcm1EZXZSZXFzID0gJHRoaXMtPmV4dHJhY3RQbGF0Zm9ybVJlcXVpcmVtZW50cygkdGhpcy0+cGFja2FnZS0+Z2V0RGV2UmVxdWlyZXMoKSk7CgogICAgICAgICRpbnN0YWxsc1VwZGF0ZXMgPSAkdW5pbnN0YWxscyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRsb2NrVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSkgewogICAgICAgICAgICAkaW5zdGFsbE5hbWVzID0gJHVwZGF0ZU5hbWVzID0gJHVuaW5zdGFsbE5hbWVzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tUcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpIGFzICRvcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgIGlmICgkb3BlcmF0aW9uIGluc3RhbmNlb2YgSW5zdGFsbE9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgICAgICRpbnN0YWxsc1VwZGF0ZXNbXSA9ICRvcGVyYXRpb247CiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxOYW1lc1tdID0gJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpLT5nZXRQcmV0dHlOYW1lKCkuJzonLiRvcGVyYXRpb24tPmdldFBhY2thZ2UoKS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkb3BlcmF0aW9uIGluc3RhbmNlb2YgVXBkYXRlT3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gd2hlbiBtaXJyb3JzL21ldGFkYXRhIGZyb20gYSBwYWNrYWdlIGdldHMgdXBkYXRlZCB3ZSBkbyBub3Qgd2FudCB0byBsaXN0IGl0IGFzIGFuCiAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlIGluIHRoZSBvdXRwdXQgYXMgaXQgaXMgb25seSBhbiBpbnRlcm5hbCBsb2NrIGZpbGUgbWV0YWRhdGEgdXBkYXRlCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT51cGRhdGVNaXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICYmICRvcGVyYXRpb24tPmdldEluaXRpYWxQYWNrYWdlKCktPmdldE5hbWUoKSA9PSAkb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCktPmdldE5hbWUoKQogICAgICAgICAgICAgICAgICAgICAgICAmJiAkb3BlcmF0aW9uLT5nZXRJbml0aWFsUGFja2FnZSgpLT5nZXRWZXJzaW9uKCkgPT0gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpLT5nZXRWZXJzaW9uKCkKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbHNVcGRhdGVzW10gPSAkb3BlcmF0aW9uOwogICAgICAgICAgICAgICAgICAgICR1cGRhdGVOYW1lc1tdID0gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpLT5nZXRQcmV0dHlOYW1lKCkuJzonLiRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkb3BlcmF0aW9uIGluc3RhbmNlb2YgVW5pbnN0YWxsT3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgJHVuaW5zdGFsbHNbXSA9ICRvcGVyYXRpb247CiAgICAgICAgICAgICAgICAgICAgJHVuaW5zdGFsbE5hbWVzW10gPSAkb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCktPmdldFByZXR0eU5hbWUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoCiAgICAgICAgICAgICAgICAiPGluZm8+TG9jayBmaWxlIG9wZXJhdGlvbnM6ICVkIGluc3RhbGwlcywgJWQgdXBkYXRlJXMsICVkIHJlbW92YWwlczwvaW5mbz4iLAogICAgICAgICAgICAgICAgY291bnQoJGluc3RhbGxOYW1lcyksCiAgICAgICAgICAgICAgICAxID09PSBjb3VudCgkaW5zdGFsbE5hbWVzKSA/ICcnIDogJ3MnLAogICAgICAgICAgICAgICAgY291bnQoJHVwZGF0ZU5hbWVzKSwKICAgICAgICAgICAgICAgIDEgPT09IGNvdW50KCR1cGRhdGVOYW1lcykgPyAnJyA6ICdzJywKICAgICAgICAgICAgICAgIGNvdW50KCR1bmluc3RhbGxzKSwKICAgICAgICAgICAgICAgIDEgPT09IGNvdW50KCR1bmluc3RhbGxzKSA/ICcnIDogJ3MnCiAgICAgICAgICAgICkpOwogICAgICAgICAgICBpZiAoJGluc3RhbGxOYW1lcykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJJbnN0YWxsczogIi5pbXBsb2RlKCcsICcsICRpbnN0YWxsTmFtZXMpLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR1cGRhdGVOYW1lcykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJVcGRhdGVzOiAiLmltcGxvZGUoJywgJywgJHVwZGF0ZU5hbWVzKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdW5pbnN0YWxscykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJSZW1vdmFsczogIi5pbXBsb2RlKCcsICcsICR1bmluc3RhbGxOYW1lcyksIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHNvcnRCeU5hbWUgPSBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgIGlmICgkYSBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgJGEgPSAkYS0+Z2V0VGFyZ2V0UGFja2FnZSgpLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYSA9ICRhLT5nZXRQYWNrYWdlKCktPmdldE5hbWUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGIgaW5zdGFuY2VvZiBVcGRhdGVPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICRiID0gJGItPmdldFRhcmdldFBhY2thZ2UoKS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGIgPSAkYi0+Z2V0UGFja2FnZSgpLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBzdHJjbXAoJGEsICRiKTsKICAgICAgICB9OwogICAgICAgIHVzb3J0KCR1bmluc3RhbGxzLCAkc29ydEJ5TmFtZSk7CiAgICAgICAgdXNvcnQoJGluc3RhbGxzVXBkYXRlcywgJHNvcnRCeU5hbWUpOwoKICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkdW5pbnN0YWxscywgJGluc3RhbGxzVXBkYXRlcykgYXMgJG9wZXJhdGlvbikgewogICAgICAgICAgICAvLyBjb2xsZWN0IHN1Z2dlc3Rpb25zCiAgICAgICAgICAgIGlmICgkb3BlcmF0aW9uIGluc3RhbmNlb2YgSW5zdGFsbE9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXItPmFkZFN1Z2dlc3Rpb25zRnJvbVBhY2thZ2UoJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gb3V0cHV0IG9wLCBidXQgYWxpYXMgb3Agb25seSBpbiBkZWJ1ZyB2ZXJib3NpdHkKICAgICAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJG9wZXJhdGlvbi0+Z2V0T3BlcmF0aW9uVHlwZSgpLCAnQWxpYXMnKSB8fCAkdGhpcy0+aW8tPmlzRGVidWcoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgIC0gJyAuICRvcGVyYXRpb24tPnNob3codHJ1ZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdXBkYXRlZExvY2sgPSAkdGhpcy0+bG9ja2VyLT5zZXRMb2NrRGF0YSgKICAgICAgICAgICAgJGxvY2tUcmFuc2FjdGlvbi0+Z2V0TmV3TG9ja1BhY2thZ2VzKGZhbHNlLCAkdGhpcy0+dXBkYXRlTWlycm9ycyksCiAgICAgICAgICAgICRsb2NrVHJhbnNhY3Rpb24tPmdldE5ld0xvY2tQYWNrYWdlcyh0cnVlLCAkdGhpcy0+dXBkYXRlTWlycm9ycyksCiAgICAgICAgICAgICRwbGF0Zm9ybVJlcXMsCiAgICAgICAgICAgICRwbGF0Zm9ybURldlJlcXMsCiAgICAgICAgICAgICRsb2NrVHJhbnNhY3Rpb24tPmdldEFsaWFzZXMoJGFsaWFzZXMpLAogICAgICAgICAgICAkdGhpcy0+cGFja2FnZS0+Z2V0TWluaW11bVN0YWJpbGl0eSgpLAogICAgICAgICAgICAkdGhpcy0+cGFja2FnZS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKSwKICAgICAgICAgICAgJHRoaXMtPnByZWZlclN0YWJsZSB8fCAkdGhpcy0+cGFja2FnZS0+Z2V0UHJlZmVyU3RhYmxlKCksCiAgICAgICAgICAgICR0aGlzLT5wcmVmZXJMb3dlc3QsCiAgICAgICAgICAgICR0aGlzLT5jb25maWctPmdldCgncGxhdGZvcm0nKSA/OiBhcnJheSgpLAogICAgICAgICAgICAkdGhpcy0+d3JpdGVMb2NrICYmICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucwogICAgICAgICk7CiAgICAgICAgaWYgKCR1cGRhdGVkTG9jayAmJiAkdGhpcy0+d3JpdGVMb2NrICYmICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucykgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPldyaXRpbmcgbG9jayBmaWxlPC9pbmZvPicpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvMjc2NAogICAgICAgIGlmICgkdGhpcy0+ZXhlY3V0ZU9wZXJhdGlvbnMgJiYgY291bnQoJGxvY2tUcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpKSA+IDApIHsKICAgICAgICAgICAgJHZlbmRvckRpciA9ICR0aGlzLT5jb25maWctPmdldCgndmVuZG9yLWRpcicpOwogICAgICAgICAgICBpZiAoaXNfZGlyKCR2ZW5kb3JEaXIpKSB7CiAgICAgICAgICAgICAgICAvLyBzdXBwcmVzcyBlcnJvcnMgYXMgdGhpcyBmYWlscyBzb21ldGltZXMgb24gT1NYIGZvciBubyBhcHBhcmVudCByZWFzb24KICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzQwNzAjaXNzdWVjb21tZW50LTEyOTc5Mjc0OAogICAgICAgICAgICAgICAgQHRvdWNoKCR2ZW5kb3JEaXIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRvSW5zdGFsbCkgewogICAgICAgICAgICAvLyBUT0RPIGVuc3VyZSBsb2NrIGlzIHVzZWQgZnJvbSBsb2NrZXIgYXMtaXMsIHNpbmNlIGl0IG1heSBub3QgaGF2ZSBiZWVuIHdyaXR0ZW4gdG8gZGlzayBpbiBjYXNlIG9mIGV4ZWN1dGVPcGVyYXRpb25zID09IGZhbHNlCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9JbnN0YWxsKCRsb2NhbFJlcG8sIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW4gdGhlIHNvbHZlciBhIHNlY29uZCB0aW1lIG9uIHRvcCBvZiB0aGUgZXhpc3RpbmcgdXBkYXRlIHJlc3VsdCB3aXRoIG9ubHkgdGhlIGN1cnJlbnQgcmVzdWx0IHNldCBpbiB0aGUgcG9vbAogICAgICogYW5kIHNlZSB3aGF0IHBhY2thZ2VzIHdvdWxkIGdldCByZW1vdmVkIGlmIHdlIG9ubHkgaGFkIHRoZSBub24tZGV2IHBhY2thZ2VzIGluIHRoZSBzb2x2ZXIgcmVxdWVzdAogICAgICoKICAgICAqIEBwYXJhbSBhcnJheTxpbnQsIGFycmF5PHN0cmluZywgc3RyaW5nPj4gJGFsaWFzZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIGxpc3Q8YXJyYXl7cGFja2FnZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGFsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+ICRhbGlhc2VzCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gc2VsZjo6RVJST1JfKgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXh0cmFjdERldlBhY2thZ2VzKExvY2tUcmFuc2FjdGlvbiAkbG9ja1RyYW5zYWN0aW9uLCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbywgYXJyYXkgJGFsaWFzZXMsIFBvbGljeUludGVyZmFjZSAkcG9saWN5LCBMb2NrQXJyYXlSZXBvc2l0b3J5ICRsb2NrZWRSZXBvc2l0b3J5ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5wYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdFJlcG8gPSBuZXcgQXJyYXlSZXBvc2l0b3J5KGFycmF5KCkpOwogICAgICAgICRsb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIobnVsbCwgdHJ1ZSk7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcigpOwogICAgICAgIGZvcmVhY2ggKCRsb2NrVHJhbnNhY3Rpb24tPmdldE5ld0xvY2tQYWNrYWdlcyhmYWxzZSkgYXMgJHBrZykgewogICAgICAgICAgICAkcmVzdWx0UmVwby0+YWRkUGFja2FnZSgkbG9hZGVyLT5sb2FkKCRkdW1wZXItPmR1bXAoJHBrZykpKTsKICAgICAgICB9CgogICAgICAgICRyZXBvc2l0b3J5U2V0ID0gJHRoaXMtPmNyZWF0ZVJlcG9zaXRvcnlTZXQodHJ1ZSwgJHBsYXRmb3JtUmVwbywgJGFsaWFzZXMpOwogICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KCRyZXN1bHRSZXBvKTsKCiAgICAgICAgJHJlcXVlc3QgPSAkdGhpcy0+Y3JlYXRlUmVxdWVzdCgkdGhpcy0+Zml4ZWRSb290UGFja2FnZSwgJHBsYXRmb3JtUmVwbyk7CiAgICAgICAgJHRoaXMtPnJlcXVpcmVQYWNrYWdlc0ZvclVwZGF0ZSgkcmVxdWVzdCwgJGxvY2tlZFJlcG9zaXRvcnksIGZhbHNlKTsKCiAgICAgICAgJHBvb2wgPSAkcmVwb3NpdG9yeVNldC0+Y3JlYXRlUG9vbFdpdGhBbGxQYWNrYWdlcygpOwoKICAgICAgICAkc29sdmVyID0gbmV3IFNvbHZlcigkcG9saWN5LCAkcG9vbCwgJHRoaXMtPmlvKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkbm9uRGV2TG9ja1RyYW5zYWN0aW9uID0gJHNvbHZlci0+c29sdmUoJHJlcXVlc3QsICR0aGlzLT5wbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKTsKICAgICAgICAgICAgJHNvbHZlciA9IG51bGw7CiAgICAgICAgfSBjYXRjaCAoU29sdmVyUHJvYmxlbXNFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGVyciA9ICdVbmFibGUgdG8gZmluZCBhIGNvbXBhdGlibGUgc2V0IG9mIHBhY2thZ2VzIGJhc2VkIG9uIHlvdXIgbm9uLWRldiByZXF1aXJlbWVudHMgYWxvbmUuJzsKICAgICAgICAgICAgJHByZXR0eVByb2JsZW0gPSAkZS0+Z2V0UHJldHR5U3RyaW5nKCRyZXBvc2l0b3J5U2V0LCAkcmVxdWVzdCwgJHBvb2wsICR0aGlzLT5pby0+aXNWZXJib3NlKCksIHRydWUpOwoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy4gJGVyciAuJzwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdZb3VyIHJlcXVpcmVtZW50cyBjYW4gYmUgcmVzb2x2ZWQgc3VjY2Vzc2Z1bGx5IHdoZW4gcmVxdWlyZS1kZXYgcGFja2FnZXMgYXJlIHByZXNlbnQuJyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IG1heSBuZWVkIHRvIG1vdmUgcGFja2FnZXMgZnJvbSByZXF1aXJlLWRldiBvciBzb21lIG9mIHRoZWlyIGRlcGVuZGVuY2llcyB0byByZXF1aXJlLicpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJHByZXR0eVByb2JsZW0pOwoKICAgICAgICAgICAgJGdoZSA9IG5ldyBHaXRodWJBY3Rpb25FcnJvcigkdGhpcy0+aW8pOwogICAgICAgICAgICAkZ2hlLT5lbWl0KCRlcnIuIlxuIi4kcHJldHR5UHJvYmxlbSk7CgogICAgICAgICAgICByZXR1cm4gJGUtPmdldENvZGUoKTsKICAgICAgICB9CgogICAgICAgICRsb2NrVHJhbnNhY3Rpb24tPnNldE5vbkRldlBhY2thZ2VzKCRub25EZXZMb2NrVHJhbnNhY3Rpb24pOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgJGFscmVhZHlTb2x2ZWQgV2hldGhlciB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIGFzIHBhcnQgb2YgYW4gdXBkYXRlIGNvbW1hbmQgb3IgaW5kZXBlbmRlbnRseQogICAgICogQHJldHVybiBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXQgY29kZQogICAgICogQHBocHN0YW4tcmV0dXJuIHNlbGY6OkVSUk9SXyoKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvSW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRsb2NhbFJlcG8sICRhbHJlYWR5U29sdmVkID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5JbnN0YWxsaW5nIGRlcGVuZGVuY2llcyBmcm9tIGxvY2sgZmlsZScuKCR0aGlzLT5kZXZNb2RlID8gJyAoaW5jbHVkaW5nIHJlcXVpcmUtZGV2KScgOiAnJykuJzwvaW5mbz4nKTsKCiAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnkgPSAkdGhpcy0+bG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCR0aGlzLT5kZXZNb2RlKTsKCiAgICAgICAgLy8gdmVyaWZ5IHRoYXQgdGhlIGxvY2sgZmlsZSB3b3JrcyB3aXRoIHRoZSBjdXJyZW50IHBsYXRmb3JtIHJlcG9zaXRvcnkKICAgICAgICAvLyB3ZSBjYW4gc2tpcCB0aGlzIHBhcnQgaWYgd2UncmUgZG9pbmcgdGhpcyBhcyB0aGUgc2Vjb25kIHN0ZXAgYWZ0ZXIgYW4gdXBkYXRlCiAgICAgICAgaWYgKCEkYWxyZWFkeVNvbHZlZCkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPlZlcmlmeWluZyBsb2NrIGZpbGUgY29udGVudHMgY2FuIGJlIGluc3RhbGxlZCBvbiBjdXJyZW50IHBsYXRmb3JtLjwvaW5mbz4nKTsKCiAgICAgICAgICAgICRwbGF0Zm9ybVJlcG8gPSAkdGhpcy0+Y3JlYXRlUGxhdGZvcm1SZXBvKGZhbHNlKTsKICAgICAgICAgICAgLy8gY3JlYXRpbmcgcmVwb3NpdG9yeSBzZXQKICAgICAgICAgICAgJHBvbGljeSA9ICR0aGlzLT5jcmVhdGVQb2xpY3koZmFsc2UpOwogICAgICAgICAgICAvLyB1c2UgYWxpYXNlcyBmcm9tIGxvY2sgZmlsZSBvbmx5LCBzbyBlbXB0eSByb290IGFsaWFzZXMgaGVyZQogICAgICAgICAgICAkcmVwb3NpdG9yeVNldCA9ICR0aGlzLT5jcmVhdGVSZXBvc2l0b3J5U2V0KGZhbHNlLCAkcGxhdGZvcm1SZXBvLCBhcnJheSgpLCAkbG9ja2VkUmVwb3NpdG9yeSk7CiAgICAgICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KCRsb2NrZWRSZXBvc2l0b3J5KTsKCiAgICAgICAgICAgIC8vIGNyZWF0aW5nIHJlcXVpcmVtZW50cyByZXF1ZXN0CiAgICAgICAgICAgICRyZXF1ZXN0ID0gJHRoaXMtPmNyZWF0ZVJlcXVlc3QoJHRoaXMtPmZpeGVkUm9vdFBhY2thZ2UsICRwbGF0Zm9ybVJlcG8sICRsb2NrZWRSZXBvc2l0b3J5KTsKCiAgICAgICAgICAgIGlmICghJHRoaXMtPmxvY2tlci0+aXNGcmVzaCgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPldhcm5pbmc6IFRoZSBsb2NrIGZpbGUgaXMgbm90IHVwIHRvIGRhdGUgd2l0aCB0aGUgbGF0ZXN0IGNoYW5nZXMgaW4gY29tcG9zZXIuanNvbi4gWW91IG1heSBiZSBnZXR0aW5nIG91dGRhdGVkIGRlcGVuZGVuY2llcy4gSXQgaXMgcmVjb21tZW5kZWQgdGhhdCB5b3UgcnVuIGBjb21wb3NlciB1cGRhdGVgIG9yIGBjb21wb3NlciB1cGRhdGUgPHBhY2thZ2UgbmFtZT5gLjwvd2FybmluZz4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJHJlcXVlc3QtPmZpeExvY2tlZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+bG9ja2VyLT5nZXRQbGF0Zm9ybVJlcXVpcmVtZW50cygkdGhpcy0+ZGV2TW9kZSkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICRyZXF1ZXN0LT5yZXF1aXJlTmFtZSgkbGluay0+Z2V0VGFyZ2V0KCksICRsaW5rLT5nZXRDb25zdHJhaW50KCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcG9vbCA9ICRyZXBvc2l0b3J5U2V0LT5jcmVhdGVQb29sKCRyZXF1ZXN0LCAkdGhpcy0+aW8sICR0aGlzLT5ldmVudERpc3BhdGNoZXIpOwoKICAgICAgICAgICAgLy8gc29sdmUgZGVwZW5kZW5jaWVzCiAgICAgICAgICAgICRzb2x2ZXIgPSBuZXcgU29sdmVyKCRwb2xpY3ksICRwb29sLCAkdGhpcy0+aW8pOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGxvY2tUcmFuc2FjdGlvbiA9ICRzb2x2ZXItPnNvbHZlKCRyZXF1ZXN0LCAkdGhpcy0+cGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcik7CiAgICAgICAgICAgICAgICAkc29sdmVyID0gbnVsbDsKCiAgICAgICAgICAgICAgICAvLyBpbnN0YWxsaW5nIHRoZSBsb2NrZWQgcGFja2FnZXMgb24gdGhpcyBwbGF0Zm9ybSByZXN1bHRlZCBpbiBsb2NrIG1vZGlmeWluZyBvcGVyYXRpb25zLCB0aGVyZSB3YXNuJ3QgYSBjb25mbGljdCwgYnV0IHRoZSBsb2NrIGZpbGUgYXMtaXMgc2VlbXMgdG8gbm90IHdvcmsgb24gdGhpcyBzeXN0ZW0KICAgICAgICAgICAgICAgIGlmICgwICE9PSBjb3VudCgkbG9ja1RyYW5zYWN0aW9uLT5nZXRPcGVyYXRpb25zKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+WW91ciBsb2NrIGZpbGUgY2Fubm90IGJlIGluc3RhbGxlZCBvbiB0aGlzIHN5c3RlbSB3aXRob3V0IGNoYW5nZXMuIFBsZWFzZSBydW4gY29tcG9zZXIgdXBkYXRlLjwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OkVSUk9SX0xPQ0tfRklMRV9JTlZBTElEOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChTb2x2ZXJQcm9ibGVtc0V4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJGVyciA9ICdZb3VyIGxvY2sgZmlsZSBkb2VzIG5vdCBjb250YWluIGEgY29tcGF0aWJsZSBzZXQgb2YgcGFja2FnZXMuIFBsZWFzZSBydW4gY29tcG9zZXIgdXBkYXRlLic7CiAgICAgICAgICAgICAgICAkcHJldHR5UHJvYmxlbSA9ICRlLT5nZXRQcmV0dHlTdHJpbmcoJHJlcG9zaXRvcnlTZXQsICRyZXF1ZXN0LCAkcG9vbCwgJHRoaXMtPmlvLT5pc1ZlcmJvc2UoKSk7CgogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy4gJGVyciAuJzwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkcHJldHR5UHJvYmxlbSk7CgogICAgICAgICAgICAgICAgJGdoZSA9IG5ldyBHaXRodWJBY3Rpb25FcnJvcigkdGhpcy0+aW8pOwogICAgICAgICAgICAgICAgJGdoZS0+ZW1pdCgkZXJyLiJcbiIuJHByZXR0eVByb2JsZW0pOwoKICAgICAgICAgICAgICAgIHJldHVybiBtYXgoc2VsZjo6RVJST1JfR0VORVJJQ19GQUlMVVJFLCAkZS0+Z2V0Q29kZSgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETyBpbiBob3cgZmFyIGRvIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgaGVyZSB0byBlbnN1cmUgZGV2IHBhY2thZ2VzIGJlaW5nIHVwZGF0ZWQgdG8gbGF0ZXN0IGluIGxvY2sgd2l0aG91dCB2ZXJzaW9uIGNoYW5nZSBhcmUgdHJlYXRlZCBjb3JyZWN0bHk/CiAgICAgICAgJGxvY2FsUmVwb1RyYW5zYWN0aW9uID0gbmV3IExvY2FsUmVwb1RyYW5zYWN0aW9uKCRsb2NrZWRSZXBvc2l0b3J5LCAkbG9jYWxSZXBvKTsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaEluc3RhbGxlckV2ZW50KEluc3RhbGxlckV2ZW50czo6UFJFX09QRVJBVElPTlNfRVhFQywgJHRoaXMtPmRldk1vZGUsICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucywgJGxvY2FsUmVwb1RyYW5zYWN0aW9uKTsKCiAgICAgICAgaWYgKCEkbG9jYWxSZXBvVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ05vdGhpbmcgdG8gaW5zdGFsbCwgdXBkYXRlIG9yIHJlbW92ZScpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsb2NhbFJlcG9UcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpKSB7CiAgICAgICAgICAgICRpbnN0YWxscyA9ICR1cGRhdGVzID0gJHVuaW5zdGFsbHMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbG9jYWxSZXBvVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSBhcyAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIEluc3RhbGxPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbHNbXSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKS0+Z2V0UHJldHR5TmFtZSgpLic6Jy4kb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCktPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgICAgICR1cGRhdGVzW10gPSAkb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCktPmdldFByZXR0eU5hbWUoKS4nOicuJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRvcGVyYXRpb24gaW5zdGFuY2VvZiBVbmluc3RhbGxPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAkdW5pbnN0YWxsc1tdID0gJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpLT5nZXRQcmV0dHlOYW1lKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgIjxpbmZvPlBhY2thZ2Ugb3BlcmF0aW9uczogJWQgaW5zdGFsbCVzLCAlZCB1cGRhdGUlcywgJWQgcmVtb3ZhbCVzPC9pbmZvPiIsCiAgICAgICAgICAgICAgICBjb3VudCgkaW5zdGFsbHMpLAogICAgICAgICAgICAgICAgMSA9PT0gY291bnQoJGluc3RhbGxzKSA/ICcnIDogJ3MnLAogICAgICAgICAgICAgICAgY291bnQoJHVwZGF0ZXMpLAogICAgICAgICAgICAgICAgMSA9PT0gY291bnQoJHVwZGF0ZXMpID8gJycgOiAncycsCiAgICAgICAgICAgICAgICBjb3VudCgkdW5pbnN0YWxscyksCiAgICAgICAgICAgICAgICAxID09PSBjb3VudCgkdW5pbnN0YWxscykgPyAnJyA6ICdzJwogICAgICAgICAgICApKTsKICAgICAgICAgICAgaWYgKCRpbnN0YWxscykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJJbnN0YWxsczogIi5pbXBsb2RlKCcsICcsICRpbnN0YWxscyksIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHVwZGF0ZXMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiVXBkYXRlczogIi5pbXBsb2RlKCcsICcsICR1cGRhdGVzKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdW5pbnN0YWxscykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJSZW1vdmFsczogIi5pbXBsb2RlKCcsICcsICR1bmluc3RhbGxzKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zKSB7CiAgICAgICAgICAgICRsb2NhbFJlcG8tPnNldERldlBhY2thZ2VOYW1lcygkdGhpcy0+bG9ja2VyLT5nZXREZXZQYWNrYWdlTmFtZXMoKSk7CiAgICAgICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyLT5leGVjdXRlKCRsb2NhbFJlcG8sICRsb2NhbFJlcG9UcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpLCAkdGhpcy0+ZGV2TW9kZSwgJHRoaXMtPnJ1blNjcmlwdHMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG9UcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpIGFzICRvcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgIC8vIG91dHB1dCBvcCwgYnV0IGFsaWFzIG9wIG9ubHkgaW4gZGVidWcgdmVyYm9zaXR5CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkb3BlcmF0aW9uLT5nZXRPcGVyYXRpb25UeXBlKCksICdBbGlhcycpIHx8ICR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgIC0gJyAuICRvcGVyYXRpb24tPnNob3coZmFsc2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkZm9yVXBkYXRlCiAgICAgKgogICAgICogQHJldHVybiBQbGF0Zm9ybVJlcG9zaXRvcnkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZVBsYXRmb3JtUmVwbygkZm9yVXBkYXRlKQogICAgewogICAgICAgIGlmICgkZm9yVXBkYXRlKSB7CiAgICAgICAgICAgICRwbGF0Zm9ybU92ZXJyaWRlcyA9ICR0aGlzLT5jb25maWctPmdldCgncGxhdGZvcm0nKSA/OiBhcnJheSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwbGF0Zm9ybU92ZXJyaWRlcyA9ICR0aGlzLT5sb2NrZXItPmdldFBsYXRmb3JtT3ZlcnJpZGVzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkcGxhdGZvcm1PdmVycmlkZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZvclVwZGF0ZQogICAgICogQHBhcmFtICBhcnJheTxpbnQsIGFycmF5PHN0cmluZywgc3RyaW5nPj4gJHJvb3RBbGlhc2VzCiAgICAgKiBAcGFyYW0gIFJlcG9zaXRvcnlJbnRlcmZhY2V8bnVsbCAgICAgICAgICAkbG9ja2VkUmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeVNldAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIGxpc3Q8YXJyYXl7cGFja2FnZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGFsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+ICRyb290QWxpYXNlcwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVJlcG9zaXRvcnlTZXQoJGZvclVwZGF0ZSwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8sIGFycmF5ICRyb290QWxpYXNlcyA9IGFycmF5KCksICRsb2NrZWRSZXBvc2l0b3J5ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGZvclVwZGF0ZSkgewogICAgICAgICAgICAkbWluaW11bVN0YWJpbGl0eSA9ICR0aGlzLT5wYWNrYWdlLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCk7CiAgICAgICAgICAgICRzdGFiaWxpdHlGbGFncyA9ICR0aGlzLT5wYWNrYWdlLT5nZXRTdGFiaWxpdHlGbGFncygpOwoKICAgICAgICAgICAgJHJlcXVpcmVzID0gYXJyYXlfbWVyZ2UoJHRoaXMtPnBhY2thZ2UtPmdldFJlcXVpcmVzKCksICR0aGlzLT5wYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbWluaW11bVN0YWJpbGl0eSA9ICR0aGlzLT5sb2NrZXItPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICAgICAgJHN0YWJpbGl0eUZsYWdzID0gJHRoaXMtPmxvY2tlci0+Z2V0U3RhYmlsaXR5RmxhZ3MoKTsKCiAgICAgICAgICAgICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NrZWRSZXBvc2l0b3J5LT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludC0+c2V0UHJldHR5U3RyaW5nKCRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgJHJlcXVpcmVzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJGNvbnN0cmFpbnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRyb290UmVxdWlyZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmICgkY29uc3RyYWludCBpbnN0YW5jZW9mIExpbmspIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJGNvbnN0cmFpbnQtPmdldENvbnN0cmFpbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBza2lwIHBsYXRmb3JtIHJlcXVpcmVtZW50cyBmcm9tIHRoZSByb290IHBhY2thZ2UgdG8gYXZvaWQgZmlsdGVyaW5nIG91dCBleGlzdGluZyBwbGF0Zm9ybSBwYWNrYWdlcwogICAgICAgICAgICBpZiAoJHRoaXMtPnBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmlzSWdub3JlZCgkcmVxKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+cGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbnN0YW5jZW9mIElnbm9yZUxpc3RQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICR0aGlzLT5wbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyLT5maWx0ZXJDb25zdHJhaW50KCRyZXEsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcm9vdFJlcXVpcmVzWyRyZXFdID0gJGNvbnN0cmFpbnQ7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Zml4ZWRSb290UGFja2FnZSA9IGNsb25lICR0aGlzLT5wYWNrYWdlOwogICAgICAgICR0aGlzLT5maXhlZFJvb3RQYWNrYWdlLT5zZXRSZXF1aXJlcyhhcnJheSgpKTsKICAgICAgICAkdGhpcy0+Zml4ZWRSb290UGFja2FnZS0+c2V0RGV2UmVxdWlyZXMoYXJyYXkoKSk7CgogICAgICAgICRzdGFiaWxpdHlGbGFnc1skdGhpcy0+cGFja2FnZS0+Z2V0TmFtZSgpXSA9IEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHRoaXMtPnBhY2thZ2UtPmdldFZlcnNpb24oKSldOwoKICAgICAgICAkcmVwb3NpdG9yeVNldCA9IG5ldyBSZXBvc2l0b3J5U2V0KCRtaW5pbXVtU3RhYmlsaXR5LCAkc3RhYmlsaXR5RmxhZ3MsICRyb290QWxpYXNlcywgJHRoaXMtPnBhY2thZ2UtPmdldFJlZmVyZW5jZXMoKSwgJHJvb3RSZXF1aXJlcyk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkobmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeSgkdGhpcy0+Zml4ZWRSb290UGFja2FnZSkpOwogICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KCRwbGF0Zm9ybVJlcG8pOwogICAgICAgIGlmICgkdGhpcy0+YWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeSkgewogICAgICAgICAgICAvLyBhbGxvdyB1c2luZyBpbnN0YWxsZWQgcmVwb3MgaWYgbmVlZGVkIHRvIGF2b2lkIHdhcm5pbmdzIGFib3V0IGluc3RhbGxlZCByZXBvc2l0b3JpZXMgYmVpbmcgdXNlZCBpbiB0aGUgUmVwb3NpdG9yeVNldAogICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvOTU3NAogICAgICAgICAgICAkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yaWVzID0gJHRoaXMtPmFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnk7CiAgICAgICAgICAgIGlmICgkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yaWVzIGluc3RhbmNlb2YgQ29tcG9zaXRlUmVwb3NpdG9yeSkgewogICAgICAgICAgICAgICAgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcmllcyA9ICRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3JpZXMtPmdldFJlcG9zaXRvcmllcygpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcmllcyA9IGFycmF5KCRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3JpZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3JpZXMgYXMgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgICAgIGlmICgkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeSBpbnN0YW5jZW9mIEluc3RhbGxlZFJlcG9zaXRvcnkgfHwgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkgaW5zdGFuY2VvZiBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFsbG93SW5zdGFsbGVkUmVwb3NpdG9yaWVzKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KCR0aGlzLT5hZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVwb3NpdG9yeVNldDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRmb3JVcGRhdGUKICAgICAqCiAgICAgKiBAcmV0dXJuIERlZmF1bHRQb2xpY3kKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVQb2xpY3koJGZvclVwZGF0ZSkKICAgIHsKICAgICAgICAkcHJlZmVyU3RhYmxlID0gbnVsbDsKICAgICAgICAkcHJlZmVyTG93ZXN0ID0gbnVsbDsKICAgICAgICBpZiAoISRmb3JVcGRhdGUpIHsKICAgICAgICAgICAgJHByZWZlclN0YWJsZSA9ICR0aGlzLT5sb2NrZXItPmdldFByZWZlclN0YWJsZSgpOwogICAgICAgICAgICAkcHJlZmVyTG93ZXN0ID0gJHRoaXMtPmxvY2tlci0+Z2V0UHJlZmVyTG93ZXN0KCk7CiAgICAgICAgfQogICAgICAgIC8vIG9sZCBsb2NrIGZpbGUgd2l0aG91dCBwcmVmZXIgc3RhYmxlL2xvd2VzdCB3aWxsIHJldHVybiBudWxsCiAgICAgICAgLy8gc28gaW4gdGhpcyBjYXNlIHdlIHVzZSB0aGUgY29tcG9zZXIuanNvbiBpbmZvCiAgICAgICAgaWYgKG51bGwgPT09ICRwcmVmZXJTdGFibGUpIHsKICAgICAgICAgICAgJHByZWZlclN0YWJsZSA9ICR0aGlzLT5wcmVmZXJTdGFibGUgfHwgJHRoaXMtPnBhY2thZ2UtPmdldFByZWZlclN0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCA9PT0gJHByZWZlckxvd2VzdCkgewogICAgICAgICAgICAkcHJlZmVyTG93ZXN0ID0gJHRoaXMtPnByZWZlckxvd2VzdDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgRGVmYXVsdFBvbGljeSgkcHJlZmVyU3RhYmxlLCAkcHJlZmVyTG93ZXN0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBSb290UGFja2FnZUludGVyZmFjZSZCYXNlUGFja2FnZSAkcm9vdFBhY2thZ2UKICAgICAqIEByZXR1cm4gUmVxdWVzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVJlcXVlc3QoUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHJvb3RQYWNrYWdlLCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbywgTG9ja0FycmF5UmVwb3NpdG9yeSAkbG9ja2VkUmVwb3NpdG9yeSA9IG51bGwpCiAgICB7CiAgICAgICAgJHJlcXVlc3QgPSBuZXcgUmVxdWVzdCgkbG9ja2VkUmVwb3NpdG9yeSk7CgogICAgICAgICRyZXF1ZXN0LT5maXhQYWNrYWdlKCRyb290UGFja2FnZSk7CiAgICAgICAgaWYgKCRyb290UGFja2FnZSBpbnN0YW5jZW9mIFJvb3RBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgJHJlcXVlc3QtPmZpeFBhY2thZ2UoJHJvb3RQYWNrYWdlLT5nZXRBbGlhc09mKCkpOwogICAgICAgIH0KCiAgICAgICAgJGZpeGVkUGFja2FnZXMgPSAkcGxhdGZvcm1SZXBvLT5nZXRQYWNrYWdlcygpOwogICAgICAgIGlmICgkdGhpcy0+YWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeSkgewogICAgICAgICAgICAkZml4ZWRQYWNrYWdlcyA9IGFycmF5X21lcmdlKCRmaXhlZFBhY2thZ2VzLCAkdGhpcy0+YWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBmaXggdGhlIHZlcnNpb24gb2YgYWxsIHBsYXRmb3JtIHBhY2thZ2VzICsgYWRkaXRpb25hbGx5IGluc3RhbGxlZCBwYWNrYWdlcwogICAgICAgIC8vIHRvIHByZXZlbnQgdGhlIHNvbHZlciB0cnlpbmcgdG8gcmVtb3ZlIG9yIHVwZGF0ZSB0aG9zZQogICAgICAgIC8vIFRPRE8gd2h5IG5vdCByZXBsYWNlcz8KICAgICAgICAkcHJvdmlkZWQgPSAkcm9vdFBhY2thZ2UtPmdldFByb3ZpZGVzKCk7CiAgICAgICAgZm9yZWFjaCAoJGZpeGVkUGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgLy8gc2tpcCBwbGF0Zm9ybSBwYWNrYWdlcyB0aGF0IGFyZSBwcm92aWRlZCBieSB0aGUgcm9vdCBwYWNrYWdlCiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpICE9PSAkcGxhdGZvcm1SZXBvCiAgICAgICAgICAgICAgICB8fCAhaXNzZXQoJHByb3ZpZGVkWyRwYWNrYWdlLT5nZXROYW1lKCldKQogICAgICAgICAgICAgICAgfHwgISRwcm92aWRlZFskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKG5ldyBDb25zdHJhaW50KCc9JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJHJlcXVlc3QtPmZpeFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlcXVlc3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gTG9ja0FycmF5UmVwb3NpdG9yeXxudWxsICRsb2NrZWRSZXBvc2l0b3J5CiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICRpbmNsdWRlRGV2UmVxdWlyZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXF1aXJlUGFja2FnZXNGb3JVcGRhdGUoUmVxdWVzdCAkcmVxdWVzdCwgTG9ja0FycmF5UmVwb3NpdG9yeSAkbG9ja2VkUmVwb3NpdG9yeSA9IG51bGwsICRpbmNsdWRlRGV2UmVxdWlyZXMgPSB0cnVlKQogICAgewogICAgICAgIC8vIGlmIHdlJ3JlIHVwZGF0aW5nIG1pcnJvcnMgd2Ugd2FudCB0byBrZWVwIGV4YWN0bHkgdGhlIHNhbWUgdmVyc2lvbnMgaW5zdGFsbGVkIHdoaWNoIGFyZSBpbiB0aGUgbG9jayBmaWxlLCBidXQgd2Ugd2FudCBjdXJyZW50IHJlbW90ZSBtZXRhZGF0YQogICAgICAgIGlmICgkdGhpcy0+dXBkYXRlTWlycm9ycykgewogICAgICAgICAgICAkZXhjbHVkZWRQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGlmICghJGluY2x1ZGVEZXZSZXF1aXJlcykgewogICAgICAgICAgICAgICAgJGV4Y2x1ZGVkUGFja2FnZXMgPSBhcnJheV9mbGlwKCR0aGlzLT5sb2NrZXItPmdldERldlBhY2thZ2VOYW1lcygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tlZFJlcG9zaXRvcnktPmdldFBhY2thZ2VzKCkgYXMgJGxvY2tlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGUgYWxpYXMgcGFja2FnZXMgaGVyZSBhcyBmb3Igcm9vdCBhbGlhc2VzLCBib3RoIGFsaWFzIGFuZCBhbGlhc2VkIGFyZQogICAgICAgICAgICAgICAgLy8gcHJlc2VudCBpbiB0aGUgbG9jayByZXBvIGFuZCB3ZSBvbmx5IHdhbnQgdG8gcmVxdWlyZSB0aGUgYWxpYXNlZCB2ZXJzaW9uCiAgICAgICAgICAgICAgICBpZiAoISRsb2NrZWRQYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICFpc3NldCgkZXhjbHVkZWRQYWNrYWdlc1skbG9ja2VkUGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVxdWVzdC0+cmVxdWlyZU5hbWUoJGxvY2tlZFBhY2thZ2UtPmdldE5hbWUoKSwgbmV3IENvbnN0cmFpbnQoJz09JywgJGxvY2tlZFBhY2thZ2UtPmdldFZlcnNpb24oKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGxpbmtzID0gJHRoaXMtPnBhY2thZ2UtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgICAgIGlmICgkaW5jbHVkZURldlJlcXVpcmVzKSB7CiAgICAgICAgICAgICAgICAkbGlua3MgPSBhcnJheV9tZXJnZSgkbGlua3MsICR0aGlzLT5wYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICRyZXF1ZXN0LT5yZXF1aXJlTmFtZSgkbGluay0+Z2V0VGFyZ2V0KCksICRsaW5rLT5nZXRDb25zdHJhaW50KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGZvclVwZGF0ZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIHN0cmluZz4+CiAgICAgKgogICAgICogQHBocHN0YW4tcmV0dXJuIGxpc3Q8YXJyYXl7cGFja2FnZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGFsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Um9vdEFsaWFzZXMoJGZvclVwZGF0ZSkKICAgIHsKICAgICAgICBpZiAoJGZvclVwZGF0ZSkgewogICAgICAgICAgICAkYWxpYXNlcyA9ICR0aGlzLT5wYWNrYWdlLT5nZXRBbGlhc2VzKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGFsaWFzZXMgPSAkdGhpcy0+bG9ja2VyLT5nZXRBbGlhc2VzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGFsaWFzZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gTGlua1tdICRsaW5rcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXh0cmFjdFBsYXRmb3JtUmVxdWlyZW1lbnRzKGFycmF5ICRsaW5rcykKICAgIHsKICAgICAgICAkcGxhdGZvcm1SZXFzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJGxpbmstPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgJHBsYXRmb3JtUmVxc1skbGluay0+Z2V0VGFyZ2V0KCldID0gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwbGF0Zm9ybVJlcXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBsYWNlIGxvY2FsIHJlcG9zaXRvcmllcyB3aXRoIEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeSBpbnN0YW5jZXMKICAgICAqCiAgICAgKiBUaGlzIGlzIHRvIHByZXZlbnQgYW55IGFjY2lkZW50YWwgbW9kaWZpY2F0aW9uIG9mIHRoZSBleGlzdGluZyByZXBvcyBvbiBkaXNrCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbW9ja0xvY2FsUmVwb3NpdG9yaWVzKFJlcG9zaXRvcnlNYW5hZ2VyICRybSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRybS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCktPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHBhY2thZ2VzWyhzdHJpbmcpICRwYWNrYWdlXSA9IGNsb25lICRwYWNrYWdlOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJGtleSA9PiAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRhbGlhcyA9IChzdHJpbmcpICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgICAgICAgICAkY2xhc3NOYW1lID0gZ2V0X2NsYXNzKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1ska2V5XSA9IG5ldyAkY2xhc3NOYW1lKCRwYWNrYWdlc1skYWxpYXNdLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkcm0tPnNldExvY2FsUmVwb3NpdG9yeSgKICAgICAgICAgICAgbmV3IEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeSgkcGFja2FnZXMpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUG9vbE9wdGltaXplcnxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY3JlYXRlUG9vbE9wdGltaXplcihQb2xpY3lJbnRlcmZhY2UgJHBvbGljeSkKICAgIHsKICAgICAgICAvLyBOb3QgdGhlIGJlc3QgYXJjaGl0ZWN0dXJhbCBkZWNpc2lvbiBoZXJlLCB3b3VsZCBuZWVkIHRvIGJlIGFibGUKICAgICAgICAvLyB0byBjb25maWd1cmUgZnJvbSB0aGUgb3V0c2lkZSBvZiBJbnN0YWxsZXIgYnV0IHRoaXMgaXMgb25seQogICAgICAgIC8vIGEgZGVidWdnaW5nIHRvb2wgYW5kIHNob3VsZCBuZXZlciBiZSByZXF1aXJlZCBpbiBhbnkgb3RoZXIgdXNlIGNhc2UKICAgICAgICBpZiAoJzAnID09PSBQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9QT09MX09QVElNSVpFUicpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGUoJ1Bvb2wgT3B0aW1pemVyIHdhcyBkaXNhYmxlZCBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLicsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUG9vbE9wdGltaXplcigkcG9saWN5KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBJbnN0YWxsZXIKICAgICAqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtICBDb21wb3NlciAgICAkY29tcG9zZXIKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKElPSW50ZXJmYWNlICRpbywgQ29tcG9zZXIgJGNvbXBvc2VyKQogICAgewogICAgICAgIHJldHVybiBuZXcgc3RhdGljKAogICAgICAgICAgICAkaW8sCiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0Q29uZmlnKCksCiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldERvd25sb2FkTWFuYWdlcigpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCksCiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0TG9ja2VyKCksCiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldEF1dG9sb2FkR2VuZXJhdG9yKCkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBSZXBvc2l0b3J5SW50ZXJmYWNlICRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5CiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkgPSAkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciB0byBydW4gaW4gZHJ5bW9kZSBvciBub3QKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkZHJ5UnVuCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RHJ5UnVuKCRkcnlSdW4gPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5kcnlSdW4gPSAoYm9vbCkgJGRyeVJ1bjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzLCBpZiB0aGlzIGlzIGEgZHJ5IHJ1biAoc2ltdWxhdGlvbiBtb2RlKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRHJ5UnVuKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRyeVJ1bjsKICAgIH0KCiAgICAvKioKICAgICAqIHByZWZlciBzb3VyY2UgaW5zdGFsbGF0aW9uCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJHByZWZlclNvdXJjZQogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZlclNvdXJjZSgkcHJlZmVyU291cmNlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJlZmVyU291cmNlID0gKGJvb2wpICRwcmVmZXJTb3VyY2U7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHByZWZlciBkaXN0IGluc3RhbGxhdGlvbgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRwcmVmZXJEaXN0CiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZmVyRGlzdCgkcHJlZmVyRGlzdCA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlckRpc3QgPSAoYm9vbCkgJHByZWZlckRpc3Q7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFdoZXRoZXIgb3Igbm90IGdlbmVyYXRlZCBhdXRvbG9hZGVyIGFyZSBvcHRpbWl6ZWQKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkb3B0aW1pemVBdXRvbG9hZGVyCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW1pemVBdXRvbG9hZGVyKCRvcHRpbWl6ZUF1dG9sb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wdGltaXplQXV0b2xvYWRlciA9IChib29sKSAkb3B0aW1pemVBdXRvbG9hZGVyOwogICAgICAgIGlmICghJHRoaXMtPm9wdGltaXplQXV0b2xvYWRlcikgewogICAgICAgICAgICAvLyBGb3JjZSBjbGFzc01hcEF1dGhvcml0YXRpdmUgb2ZmIHdoZW4gbm90IG9wdGltaXppbmcgdGhlCiAgICAgICAgICAgIC8vIGF1dG9sb2FkZXIKICAgICAgICAgICAgJHRoaXMtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZShmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIG9yIG5vdCBnZW5lcmF0ZWQgYXV0b2xvYWRlciBjb25zaWRlcnMgdGhlIGNsYXNzIG1hcAogICAgICogYXV0aG9yaXRhdGl2ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkY2xhc3NNYXBBdXRob3JpdGF0aXZlCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2xhc3NNYXBBdXRob3JpdGF0aXZlKCRjbGFzc01hcEF1dGhvcml0YXRpdmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSA9IChib29sKSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlOwogICAgICAgIGlmICgkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlKSB7CiAgICAgICAgICAgIC8vIEZvcmNlIG9wdGltaXplQXV0b2xvYWRlciB3aGVuIGNsYXNzbWFwIGlzIGF1dGhvcml0YXRpdmUKICAgICAgICAgICAgJHRoaXMtPnNldE9wdGltaXplQXV0b2xvYWRlcih0cnVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFdoZXRoZXIgb3Igbm90IGdlbmVyYXRlZCBhdXRvbG9hZGVyIGNvbnNpZGVycyBBUEN1IGNhY2hpbmcuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgICAkYXBjdUF1dG9sb2FkZXIKICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgJGFwY3VBdXRvbG9hZGVyUHJlZml4CiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXBjdUF1dG9sb2FkZXIoJGFwY3VBdXRvbG9hZGVyLCAkYXBjdUF1dG9sb2FkZXJQcmVmaXggPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5hcGN1QXV0b2xvYWRlciA9ICRhcGN1QXV0b2xvYWRlcjsKICAgICAgICAkdGhpcy0+YXBjdUF1dG9sb2FkZXJQcmVmaXggPSAkYXBjdUF1dG9sb2FkZXJQcmVmaXg7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHVwZGF0ZSBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICR1cGRhdGUKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVcGRhdGUoJHVwZGF0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dXBkYXRlID0gKGJvb2wpICR1cGRhdGU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFsbG93cyBkaXNhYmxpbmcgdGhlIGluc3RhbGwgc3RlcCBhZnRlciBhbiB1cGRhdGUKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkaW5zdGFsbAogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEluc3RhbGwoJGluc3RhbGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmluc3RhbGwgPSAoYm9vbCkgJGluc3RhbGw7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIGVuYWJsZXMgZGV2IHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJGRldk1vZGUKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXZNb2RlKCRkZXZNb2RlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGV2TW9kZSA9IChib29sKSAkZGV2TW9kZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogc2V0IHdoZXRoZXIgdG8gcnVuIGF1dG9sb2FkZXIgb3Igbm90CiAgICAgKgogICAgICogVGhpcyBpcyBkaXNhYmxlZCBpbXBsaWNpdGx5IHdoZW4gZW5hYmxpbmcgZHJ5UnVuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJGR1bXBBdXRvbG9hZGVyCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RHVtcEF1dG9sb2FkZXIoJGR1bXBBdXRvbG9hZGVyID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZHVtcEF1dG9sb2FkZXIgPSAoYm9vbCkgJGR1bXBBdXRvbG9hZGVyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBzZXQgd2hldGhlciB0byBydW4gc2NyaXB0cyBvciBub3QKICAgICAqCiAgICAgKiBUaGlzIGlzIGRpc2FibGVkIGltcGxpY2l0bHkgd2hlbiBlbmFibGluZyBkcnlSdW4KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkcnVuU2NyaXB0cwogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqIEBkZXByZWNhdGVkIFVzZSBzZXRSdW5TY3JpcHRzKGZhbHNlKSBvbiB0aGUgRXZlbnREaXNwYXRjaGVyIGluc3RhbmNlIGJlaW5nIGluamVjdGVkIGluc3RlYWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJ1blNjcmlwdHMoJHJ1blNjcmlwdHMgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5ydW5TY3JpcHRzID0gKGJvb2wpICRydW5TY3JpcHRzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBzZXQgdGhlIGNvbmZpZyBpbnN0YW5jZQogICAgICoKICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICRjb25maWcKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25maWcoQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHJ1biBpbiB2ZXJib3NlIG1vZGUKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkdmVyYm9zZQogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZlcmJvc2UoJHZlcmJvc2UgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT52ZXJib3NlID0gKGJvb2wpICR2ZXJib3NlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MsIGlmIHJ1bm5pbmcgaW4gdmVyYm9zZSBtb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJib3NlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcmJvc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBzZXQgaWdub3JlIFBsYXRmb3JtIFBhY2thZ2UgcmVxdWlyZW1lbnRzCiAgICAgKgogICAgICogSWYgdGhpcyBpcyBzZXQgdG8gdHJ1ZSwgYWxsIHBsYXRmb3JtIHJlcXVpcmVtZW50cyBhcmUgaWdub3JlZAogICAgICogSWYgdGhpcyBpcyBzZXQgdG8gZmFsc2UsIG5vIHBsYXRmb3JtIHJlcXVpcmVtZW50cyBhcmUgaWdub3JlZAogICAgICogSWYgdGhpcyBpcyBzZXQgdG8gc3RyaW5nW10sIHRob3NlIHBhY2thZ2VzIHdpbGwgYmUgaWdub3JlZAogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbHxzdHJpbmdbXSAkaWdub3JlUGxhdGZvcm1SZXFzCiAgICAgKgogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCB1c2Ugc2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbnN0ZWFkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZ25vcmVQbGF0Zm9ybVJlcXVpcmVtZW50cygkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgewogICAgICAgIHRyaWdnZXJfZXJyb3IoJ0luc3RhbGxlcjo6c2V0SWdub3JlUGxhdGZvcm1SZXF1aXJlbWVudHMgaXMgZGVwcmVjYXRlZCBzaW5jZSBDb21wb3NlciAyLjIsIHVzZSBzZXRQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RlYWQuJywgRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnNldFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIoUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckZhY3Rvcnk6OmZyb21Cb29sT3JMaXN0KCRpZ25vcmVQbGF0Zm9ybVJlcXMpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcihQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyKQogICAgewogICAgICAgICR0aGlzLT5wbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID0gJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXI7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFVwZGF0ZSB0aGUgbG9jayBmaWxlIHRvIHRoZSBleGFjdCBzYW1lIHZlcnNpb25zIGFuZCByZWZlcmVuY2VzIGJ1dCB1c2UgY3VycmVudCByZW1vdGUgbWV0YWRhdGEgbGlrZSBVUkxzIGFuZCBtaXJyb3IgaW5mbwogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICR1cGRhdGVNaXJyb3JzCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXBkYXRlTWlycm9ycygkdXBkYXRlTWlycm9ycykKICAgIHsKICAgICAgICAkdGhpcy0+dXBkYXRlTWlycm9ycyA9ICR1cGRhdGVNaXJyb3JzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiByZXN0cmljdCB0aGUgdXBkYXRlIG9wZXJhdGlvbiB0byBhIGZldyBwYWNrYWdlcywgYWxsIG90aGVyIHBhY2thZ2VzCiAgICAgKiB0aGF0IGFyZSBhbHJlYWR5IGluc3RhbGxlZCB3aWxsIGJlIGtlcHQgYXQgdGhlaXIgY3VycmVudCB2ZXJzaW9uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRwYWNrYWdlcwogICAgICoKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVcGRhdGVBbGxvd0xpc3QoYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgICR0aGlzLT51cGRhdGVBbGxvd0xpc3QgPSBhcnJheV9mbGlwKGFycmF5X21hcCgnc3RydG9sb3dlcicsICRwYWNrYWdlcykpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaG91bGQgZGVwZW5kZW5jaWVzIG9mIHBhY2thZ2VzIG1hcmtlZCBmb3IgdXBkYXRlIGJlIHVwZGF0ZWQ/CiAgICAgKgogICAgICogRGVwZW5kaW5nIG9uIHRoZSBjaG9zZW4gY29uc3RhbnQgdGhpcyB3aWxsIGVpdGhlciBvbmx5IHVwZGF0ZSB0aGUgZGlyZWN0bHkgbmFtZWQgcGFja2FnZXMsIGFsbCB0cmFuc2l0aXZlCiAgICAgKiBkZXBlbmRlbmNpZXMgd2hpY2ggYXJlIG5vdCByb290IHJlcXVpcmVtZW50IG9yIGFsbCB0cmFuc2l0aXZlIGRlcGVuZGVuY2llcyBpbmNsdWRpbmcgcm9vdCByZXF1aXJlbWVudHMKICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzIE9uZSBvZiB0aGUgVVBEQVRFXyBjb25zdGFudHMgb24gdGhlIFJlcXVlc3QgY2xhc3MKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcykKICAgIHsKICAgICAgICBpZiAoIWluX2FycmF5KCR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMsIGFycmF5KFJlcXVlc3Q6OlVQREFURV9PTkxZX0xJU1RFRCwgUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQU19OT19ST09UX1JFUVVJUkUsIFJlcXVlc3Q6OlVQREFURV9MSVNURURfV0lUSF9UUkFOU0lUSVZFX0RFUFMpLCB0cnVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIkludmFsaWQgdmFsdWUgZm9yIHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyBzdXBwbGllZCIpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyA9ICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNob3VsZCBwYWNrYWdlcyBiZSBwcmVmZXJyZWQgaW4gYSBzdGFibGUgdmVyc2lvbiB3aGVuIHVwZGF0aW5nPwogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRwcmVmZXJTdGFibGUKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmZXJTdGFibGUoJHByZWZlclN0YWJsZSA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlclN0YWJsZSA9IChib29sKSAkcHJlZmVyU3RhYmxlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaG91bGQgcGFja2FnZXMgYmUgcHJlZmVycmVkIGluIGEgbG93ZXN0IHZlcnNpb24gd2hlbiB1cGRhdGluZz8KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkcHJlZmVyTG93ZXN0CiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZmVyTG93ZXN0KCRwcmVmZXJMb3dlc3QgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5wcmVmZXJMb3dlc3QgPSAoYm9vbCkgJHByZWZlckxvd2VzdDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2hvdWxkIHRoZSBsb2NrIGZpbGUgYmUgdXBkYXRlZCB3aGVuIHVwZGF0aW5nPwogICAgICoKICAgICAqIFRoaXMgaXMgZGlzYWJsZWQgaW1wbGljaXRseSB3aGVuIGVuYWJsaW5nIGRyeVJ1bgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICR3cml0ZUxvY2sKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRXcml0ZUxvY2soJHdyaXRlTG9jayA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlTG9jayA9IChib29sKSAkd3JpdGVMb2NrOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaG91bGQgdGhlIG9wZXJhdGlvbnMgKHBhY2thZ2UgaW5zdGFsbCwgdXBkYXRlIGFuZCByZW1vdmFsKSBiZSBleGVjdXRlZCBvbiBkaXNrPwogICAgICoKICAgICAqIFRoaXMgaXMgZGlzYWJsZWQgaW1wbGljaXRseSB3aGVuIGVuYWJsaW5nIGRyeVJ1bgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRleGVjdXRlT3BlcmF0aW9ucwogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEV4ZWN1dGVPcGVyYXRpb25zKCRleGVjdXRlT3BlcmF0aW9ucyA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zID0gKGJvb2wpICRleGVjdXRlT3BlcmF0aW9uczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRGlzYWJsZXMgcGx1Z2lucy4KICAgICAqCiAgICAgKiBDYWxsIHRoaXMgaWYgeW91IHdhbnQgdG8gZW5zdXJlIHRoYXQgdGhpcmQtcGFydHkgY29kZSBuZXZlciBnZXRzCiAgICAgKiBleGVjdXRlZC4gVGhlIGRlZmF1bHQgaXMgdG8gYXV0b21hdGljYWxseSBpbnN0YWxsLCBhbmQgZXhlY3V0ZQogICAgICogY3VzdG9tIHRoaXJkLXBhcnR5IGluc3RhbGxlcnMuCiAgICAgKgogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc2FibGVQbHVnaW5zKCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlci0+ZGlzYWJsZVBsdWdpbnMoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyICRzdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcihTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyICRzdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKQogICAgewogICAgICAgICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyID0gJHN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJTzsKCnVzZSBDb21wb3NlclxRdWVzdGlvblxTdHJpY3RDb25maXJtYXRpb25RdWVzdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlclNldDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFByb2dyZXNzQmFyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXENob2ljZVF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxRdWVzdGlvbjsKCi8qKgogKiBUaGUgSW5wdXQvT3V0cHV0IGhlbHBlci4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ29uc29sZUlPIGV4dGVuZHMgQmFzZUlPCnsKICAgIC8qKiBAdmFyIElucHV0SW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlucHV0OwogICAgLyoqIEB2YXIgT3V0cHV0SW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJG91dHB1dDsKICAgIC8qKiBAdmFyIEhlbHBlclNldCAqLwogICAgcHJvdGVjdGVkICRoZWxwZXJTZXQ7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkbGFzdE1lc3NhZ2UgPSAnJzsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRsYXN0TWVzc2FnZUVyciA9ICcnOwoKICAgIC8qKiBAdmFyIGZsb2F0ICovCiAgICBwcml2YXRlICRzdGFydFRpbWU7CiAgICAvKiogQHZhciBhcnJheTxpbnQsIGludD4gKi8KICAgIHByaXZhdGUgJHZlcmJvc2l0eU1hcDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBJbnB1dEludGVyZmFjZSAgJGlucHV0ICAgICBUaGUgaW5wdXQgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCAgICBUaGUgb3V0cHV0IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gSGVscGVyU2V0ICAgICAgICRoZWxwZXJTZXQgVGhlIGhlbHBlclNldCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgSGVscGVyU2V0ICRoZWxwZXJTZXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwogICAgICAgICR0aGlzLT5oZWxwZXJTZXQgPSAkaGVscGVyU2V0OwogICAgICAgICR0aGlzLT52ZXJib3NpdHlNYXAgPSBhcnJheSgKICAgICAgICAgICAgc2VsZjo6UVVJRVQgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfUVVJRVQsCiAgICAgICAgICAgIHNlbGY6Ok5PUk1BTCA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9OT1JNQUwsCiAgICAgICAgICAgIHNlbGY6OlZFUkJPU0UgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSQk9TRSwKICAgICAgICAgICAgc2VsZjo6VkVSWV9WRVJCT1NFID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSwKICAgICAgICAgICAgc2VsZjo6REVCVUcgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfREVCVUcsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBmbG9hdCAkc3RhcnRUaW1lCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVEZWJ1Z2dpbmcoJHN0YXJ0VGltZSkKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnRUaW1lID0gJHN0YXJ0VGltZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0ludGVyYWN0aXZlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlucHV0LT5pc0ludGVyYWN0aXZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5pc0RlY29yYXRlZCgpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldFZlcmJvc2l0eSgpID49IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUkJPU0U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldFZlcmJvc2l0eSgpID49IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlYnVnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkgPj0gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfREVCVUc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvV3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgZmFsc2UsICR2ZXJib3NpdHkpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlRXJyb3IoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvV3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgdHJ1ZSwgJHZlcmJvc2l0eSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVSYXcoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvV3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgZmFsc2UsICR2ZXJib3NpdHksIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlRXJyb3JSYXcoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvV3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgdHJ1ZSwgJHZlcmJvc2l0eSwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW118c3RyaW5nICRtZXNzYWdlcwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICRuZXdsaW5lCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgJHN0ZGVycgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAkcmF3CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9Xcml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lLCAkc3RkZXJyLCAkdmVyYm9zaXR5LCAkcmF3ID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHNmVmVyYm9zaXR5ID0gJHRoaXMtPnZlcmJvc2l0eU1hcFskdmVyYm9zaXR5XTsKICAgICAgICBpZiAoJHNmVmVyYm9zaXR5ID4gJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyYXcpIHsKICAgICAgICAgICAgaWYgKCRzZlZlcmJvc2l0eSA9PT0gT3V0cHV0SW50ZXJmYWNlOjpPVVRQVVRfTk9STUFMKSB7CiAgICAgICAgICAgICAgICAkc2ZWZXJib3NpdHkgPSBPdXRwdXRJbnRlcmZhY2U6Ok9VVFBVVF9SQVc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkc2ZWZXJib3NpdHkgfD0gT3V0cHV0SW50ZXJmYWNlOjpPVVRQVVRfUkFXOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPnN0YXJ0VGltZSkgewogICAgICAgICAgICAkbWVtb3J5VXNhZ2UgPSBtZW1vcnlfZ2V0X3VzYWdlKCkgLyAxMDI0IC8gMTAyNDsKICAgICAgICAgICAgJHRpbWVTcGVudCA9IG1pY3JvdGltZSh0cnVlKSAtICR0aGlzLT5zdGFydFRpbWU7CiAgICAgICAgICAgICRtZXNzYWdlcyA9IGFycmF5X21hcChmdW5jdGlvbiAoJG1lc3NhZ2UpIHVzZSAoJG1lbW9yeVVzYWdlLCAkdGltZVNwZW50KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZignWyUuMWZNaUIvJS4yZnNdICVzJywgJG1lbW9yeVVzYWdlLCAkdGltZVNwZW50LCAkbWVzc2FnZSk7CiAgICAgICAgICAgIH0sIChhcnJheSkgJG1lc3NhZ2VzKTsKICAgICAgICB9CgogICAgICAgIGlmICh0cnVlID09PSAkc3RkZXJyICYmICR0aGlzLT5vdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQtPmdldEVycm9yT3V0cHV0KCktPndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICRzZlZlcmJvc2l0eSk7CiAgICAgICAgICAgICR0aGlzLT5sYXN0TWVzc2FnZUVyciA9IGltcGxvZGUoJG5ld2xpbmUgPyAiXG4iIDogJycsIChhcnJheSkgJG1lc3NhZ2VzKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXQtPndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICRzZlZlcmJvc2l0eSk7CiAgICAgICAgJHRoaXMtPmxhc3RNZXNzYWdlID0gaW1wbG9kZSgkbmV3bGluZSA/ICJcbiIgOiAnJywgKGFycmF5KSAkbWVzc2FnZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHNpemUgPSBudWxsLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgICAgICR0aGlzLT5kb092ZXJ3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lLCAkc2l6ZSwgZmFsc2UsICR2ZXJib3NpdHkpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZUVycm9yKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkc2l6ZSA9IG51bGwsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvT3ZlcndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICRzaXplLCB0cnVlLCAkdmVyYm9zaXR5KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmdbXXxzdHJpbmcgJG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRuZXdsaW5lCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICRzaXplCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRzdGRlcnIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgJHZlcmJvc2l0eQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRvT3ZlcndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICRzaXplLCAkc3RkZXJyLCAkdmVyYm9zaXR5KQogICAgewogICAgICAgIC8vIG1lc3NhZ2VzIGNhbiBiZSBhbiBhcnJheSwgbGV0J3MgY29udmVydCBpdCB0byBzdHJpbmcgYW55d2F5CiAgICAgICAgJG1lc3NhZ2VzID0gaW1wbG9kZSgkbmV3bGluZSA/ICJcbiIgOiAnJywgKGFycmF5KSAkbWVzc2FnZXMpOwoKICAgICAgICAvLyBzaW5jZSBvdmVyd3JpdGUgaXMgc3VwcG9zZWQgdG8gb3ZlcndyaXRlIGxhc3QgbWVzc2FnZS4uLgogICAgICAgIGlmICghaXNzZXQoJHNpemUpKSB7CiAgICAgICAgICAgIC8vIHJlbW92aW5nIHBvc3NpYmxlIGZvcm1hdHRpbmcgb2YgbGFzdE1lc3NhZ2Ugd2l0aCBzdHJpcF90YWdzCiAgICAgICAgICAgICRzaXplID0gc3RybGVuKHN0cmlwX3RhZ3MoJHN0ZGVyciA/ICR0aGlzLT5sYXN0TWVzc2FnZUVyciA6ICR0aGlzLT5sYXN0TWVzc2FnZSkpOwogICAgICAgIH0KICAgICAgICAvLyAuLi5sZXQncyBmaWxsIGl0cyBsZW5ndGggd2l0aCBiYWNrc3BhY2VzCiAgICAgICAgJHRoaXMtPmRvV3JpdGUoc3RyX3JlcGVhdCgiXHgwOCIsICRzaXplKSwgZmFsc2UsICRzdGRlcnIsICR2ZXJib3NpdHkpOwoKICAgICAgICAvLyB3cml0ZSB0aGUgbmV3IG1lc3NhZ2UKICAgICAgICAkdGhpcy0+ZG9Xcml0ZSgkbWVzc2FnZXMsIGZhbHNlLCAkc3RkZXJyLCAkdmVyYm9zaXR5KTsKCiAgICAgICAgLy8gSW4gY21kLmV4ZSBvbiBXaW44LjEgKHBvc3NpYmx5IDEwPyksIHRoZSBsaW5lIGNhbiBub3QgYmUgY2xlYXJlZCwgc28gd2UgbmVlZCB0bwogICAgICAgIC8vIHRyYWNrIHRoZSBsZW5ndGggb2YgcHJldmlvdXMgb3V0cHV0IGFuZCBmaWxsIGl0IHdpdGggc3BhY2VzIHRvIG1ha2Ugc3VyZSB0aGUgbGluZSBpcyBjbGVhcmVkLgogICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC81ODM2IGZvciBtb3JlIGRldGFpbHMKICAgICAgICAkZmlsbCA9ICRzaXplIC0gc3RybGVuKHN0cmlwX3RhZ3MoJG1lc3NhZ2VzKSk7CiAgICAgICAgaWYgKCRmaWxsID4gMCkgewogICAgICAgICAgICAvLyB3aGl0ZXNwYWNlIHdoYXRldmVyIGhhcyBsZWZ0CiAgICAgICAgICAgICR0aGlzLT5kb1dyaXRlKHN0cl9yZXBlYXQoJyAnLCAkZmlsbCksIGZhbHNlLCAkc3RkZXJyLCAkdmVyYm9zaXR5KTsKICAgICAgICAgICAgLy8gbW92ZSB0aGUgY3Vyc29yIGJhY2sKICAgICAgICAgICAgJHRoaXMtPmRvV3JpdGUoc3RyX3JlcGVhdCgiXHgwOCIsICRmaWxsKSwgZmFsc2UsICRzdGRlcnIsICR2ZXJib3NpdHkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRuZXdsaW5lKSB7CiAgICAgICAgICAgICR0aGlzLT5kb1dyaXRlKCcnLCB0cnVlLCAkc3RkZXJyLCAkdmVyYm9zaXR5KTsKICAgICAgICB9CgogICAgICAgIGlmICgkc3RkZXJyKSB7CiAgICAgICAgICAgICR0aGlzLT5sYXN0TWVzc2FnZUVyciA9ICRtZXNzYWdlczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+bGFzdE1lc3NhZ2UgPSAkbWVzc2FnZXM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgICAgICAgICAkbWF4CiAgICAgKiBAcmV0dXJuIFByb2dyZXNzQmFyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9ncmVzc0JhcigkbWF4ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFByb2dyZXNzQmFyKCR0aGlzLT5nZXRFcnJvck91dHB1dCgpLCAkbWF4KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2soJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgLyoqIEB2YXIgXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyICRoZWxwZXIgKi8KICAgICAgICAkaGVscGVyID0gJHRoaXMtPmhlbHBlclNldC0+Z2V0KCdxdWVzdGlvbicpOwogICAgICAgICRxdWVzdGlvbiA9IG5ldyBRdWVzdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0KTsKCiAgICAgICAgcmV0dXJuICRoZWxwZXItPmFzaygkdGhpcy0+aW5wdXQsICR0aGlzLT5nZXRFcnJvck91dHB1dCgpLCAkcXVlc3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0ID0gdHJ1ZSkKICAgIHsKICAgICAgICAvKiogQHZhciBcU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUXVlc3Rpb25IZWxwZXIgJGhlbHBlciAqLwogICAgICAgICRoZWxwZXIgPSAkdGhpcy0+aGVscGVyU2V0LT5nZXQoJ3F1ZXN0aW9uJyk7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IFN0cmljdENvbmZpcm1hdGlvblF1ZXN0aW9uKCRxdWVzdGlvbiwgJGRlZmF1bHQpOwoKICAgICAgICByZXR1cm4gJGhlbHBlci0+YXNrKCR0aGlzLT5pbnB1dCwgJHRoaXMtPmdldEVycm9yT3V0cHV0KCksICRxdWVzdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQW5kVmFsaWRhdGUoJHF1ZXN0aW9uLCAkdmFsaWRhdG9yLCAkYXR0ZW1wdHMgPSBudWxsLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgLyoqIEB2YXIgXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyICRoZWxwZXIgKi8KICAgICAgICAkaGVscGVyID0gJHRoaXMtPmhlbHBlclNldC0+Z2V0KCdxdWVzdGlvbicpOwogICAgICAgICRxdWVzdGlvbiA9IG5ldyBRdWVzdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0KTsKICAgICAgICAkcXVlc3Rpb24tPnNldFZhbGlkYXRvcigkdmFsaWRhdG9yKTsKICAgICAgICAkcXVlc3Rpb24tPnNldE1heEF0dGVtcHRzKCRhdHRlbXB0cyk7CgogICAgICAgIHJldHVybiAkaGVscGVyLT5hc2soJHRoaXMtPmlucHV0LCAkdGhpcy0+Z2V0RXJyb3JPdXRwdXQoKSwgJHF1ZXN0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2tBbmRIaWRlQW5zd2VyKCRxdWVzdGlvbikKICAgIHsKICAgICAgICAvKiogQHZhciBcU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUXVlc3Rpb25IZWxwZXIgJGhlbHBlciAqLwogICAgICAgICRoZWxwZXIgPSAkdGhpcy0+aGVscGVyU2V0LT5nZXQoJ3F1ZXN0aW9uJyk7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IFF1ZXN0aW9uKCRxdWVzdGlvbik7CiAgICAgICAgJHF1ZXN0aW9uLT5zZXRIaWRkZW4odHJ1ZSk7CgogICAgICAgIHJldHVybiAkaGVscGVyLT5hc2soJHRoaXMtPmlucHV0LCAkdGhpcy0+Z2V0RXJyb3JPdXRwdXQoKSwgJHF1ZXN0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWxlY3QoJHF1ZXN0aW9uLCAkY2hvaWNlcywgJGRlZmF1bHQsICRhdHRlbXB0cyA9IGZhbHNlLCAkZXJyb3JNZXNzYWdlID0gJ1ZhbHVlICIlcyIgaXMgaW52YWxpZCcsICRtdWx0aXNlbGVjdCA9IGZhbHNlKQogICAgewogICAgICAgIC8qKiBAdmFyIFxTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxRdWVzdGlvbkhlbHBlciAkaGVscGVyICovCiAgICAgICAgJGhlbHBlciA9ICR0aGlzLT5oZWxwZXJTZXQtPmdldCgncXVlc3Rpb24nKTsKICAgICAgICAkcXVlc3Rpb24gPSBuZXcgQ2hvaWNlUXVlc3Rpb24oJHF1ZXN0aW9uLCAkY2hvaWNlcywgJGRlZmF1bHQpOwogICAgICAgICRxdWVzdGlvbi0+c2V0TWF4QXR0ZW1wdHMoJGF0dGVtcHRzID86IG51bGwpOyAvLyBJT0ludGVyZmFjZSByZXF1aXJlcyBmYWxzZSwgYW5kIFF1ZXN0aW9uIHJlcXVpcmVzIG51bGwgb3IgaW50CiAgICAgICAgJHF1ZXN0aW9uLT5zZXRFcnJvck1lc3NhZ2UoJGVycm9yTWVzc2FnZSk7CiAgICAgICAgJHF1ZXN0aW9uLT5zZXRNdWx0aXNlbGVjdCgkbXVsdGlzZWxlY3QpOwoKICAgICAgICAkcmVzdWx0ID0gJGhlbHBlci0+YXNrKCR0aGlzLT5pbnB1dCwgJHRoaXMtPmdldEVycm9yT3V0cHV0KCksICRxdWVzdGlvbik7CgogICAgICAgIGlmICghaXNfYXJyYXkoJHJlc3VsdCkpIHsKICAgICAgICAgICAgcmV0dXJuIChzdHJpbmcpIGFycmF5X3NlYXJjaCgkcmVzdWx0LCAkY2hvaWNlcywgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0cyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGNob2ljZXMgYXMgJGluZGV4ID0+ICRjaG9pY2UpIHsKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRjaG9pY2UsICRyZXN1bHQsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gKHN0cmluZykgJGluZGV4OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEVycm9yT3V0cHV0KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPm91dHB1dCBpbnN0YW5jZW9mIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPm91dHB1dDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJTzsKCi8qKgogKiBJT0ludGVyZmFjZSB0aGF0IGlzIG5vdCBpbnRlcmFjdGl2ZSBhbmQgbmV2ZXIgd3JpdGVzIHRoZSBvdXRwdXQKICoKICogQGF1dGhvciBDaHJpc3RvcGhlIENvZXZvZXQgPHN0b2ZAbm90ay5vcmc+CiAqLwpjbGFzcyBOdWxsSU8gZXh0ZW5kcyBCYXNlSU8KewogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJbnRlcmFjdGl2ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyeVZlcmJvc2UoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlYnVnKCkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZUVycm9yKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHNpemUgPSA4MCwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvdmVyd3JpdGVFcnJvcigkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHNpemUgPSA4MCwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2soJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0ID0gdHJ1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQW5kVmFsaWRhdGUoJHF1ZXN0aW9uLCAkdmFsaWRhdG9yLCAkYXR0ZW1wdHMgPSBudWxsLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFza0FuZEhpZGVBbnN3ZXIoJHF1ZXN0aW9uKQogICAgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlbGVjdCgkcXVlc3Rpb24sICRjaG9pY2VzLCAkZGVmYXVsdCwgJGF0dGVtcHRzID0gZmFsc2UsICRlcnJvck1lc3NhZ2UgPSAnVmFsdWUgIiVzIiBpcyBpbnZhbGlkJywgJG11bHRpc2VsZWN0ID0gZmFsc2UpCiAgICB7CiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXElPOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgUHNyXExvZ1xMb2dMZXZlbDsKCmFic3RyYWN0IGNsYXNzIEJhc2VJTyBpbXBsZW1lbnRzIElPSW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgYXJyYXl7dXNlcm5hbWU6IHN0cmluZ3xudWxsLCBwYXNzd29yZDogc3RyaW5nfG51bGx9PiAqLwogICAgcHJvdGVjdGVkICRhdXRoZW50aWNhdGlvbnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dGhlbnRpY2F0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hdXRoZW50aWNhdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc2V0QXV0aGVudGljYXRpb25zKCkKICAgIHsKICAgICAgICAkdGhpcy0+YXV0aGVudGljYXRpb25zID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5hdXRoZW50aWNhdGlvbnNbJHJlcG9zaXRvcnlOYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0aGVudGljYXRpb24oJHJlcG9zaXRvcnlOYW1lKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+YXV0aGVudGljYXRpb25zWyRyZXBvc2l0b3J5TmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+YXV0aGVudGljYXRpb25zWyRyZXBvc2l0b3J5TmFtZV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJ3VzZXJuYW1lJyA9PiBudWxsLCAncGFzc3dvcmQnID0+IG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSwgJHVzZXJuYW1lLCAkcGFzc3dvcmQgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5hdXRoZW50aWNhdGlvbnNbJHJlcG9zaXRvcnlOYW1lXSA9IGFycmF5KCd1c2VybmFtZScgPT4gJHVzZXJuYW1lLCAncGFzc3dvcmQnID0+ICRwYXNzd29yZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVSYXcoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICR2ZXJib3NpdHkpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlRXJyb3JSYXcoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRXJyb3IoJG1lc3NhZ2VzLCAkbmV3bGluZSwgJHZlcmJvc2l0eSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBmb3Igb3ZlcndyaXRlIGFuZCBzZXQgdGhlIGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uIGZvciB0aGUgcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXBvc2l0b3J5TmFtZSBUaGUgdW5pcXVlIG5hbWUgb2YgcmVwb3NpdG9yeQogICAgICogQHBhcmFtIHN0cmluZyAkdXNlcm5hbWUgICAgICAgVGhlIHVzZXJuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXNzd29yZCAgICAgICBUaGUgcGFzc3dvcmQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrQW5kU2V0QXV0aGVudGljYXRpb24oJHJlcG9zaXRvcnlOYW1lLCAkdXNlcm5hbWUsICRwYXNzd29yZCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5oYXNBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUpKSB7CiAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmdldEF1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSk7CiAgICAgICAgICAgIGlmICgkYXV0aFsndXNlcm5hbWUnXSA9PT0gJHVzZXJuYW1lICYmICRhdXRoWydwYXNzd29yZCddID09PSAkcGFzc3dvcmQpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICI8d2FybmluZz5XYXJuaW5nOiBZb3Ugc2hvdWxkIGF2b2lkIG92ZXJ3cml0aW5nIGFscmVhZHkgZGVmaW5lZCBhdXRoIHNldHRpbmdzIGZvciAlcy48L3dhcm5pbmc+IiwKICAgICAgICAgICAgICAgICAgICAkcmVwb3NpdG9yeU5hbWUKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnNldEF1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSwgJHVzZXJuYW1lLCAkcGFzc3dvcmQpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRDb25maWd1cmF0aW9uKENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICRiaXRidWNrZXRPYXV0aCA9ICRjb25maWctPmdldCgnYml0YnVja2V0LW9hdXRoJykgPzogYXJyYXkoKTsKICAgICAgICAkZ2l0aHViT2F1dGggPSAkY29uZmlnLT5nZXQoJ2dpdGh1Yi1vYXV0aCcpID86IGFycmF5KCk7CiAgICAgICAgJGdpdGxhYk9hdXRoID0gJGNvbmZpZy0+Z2V0KCdnaXRsYWItb2F1dGgnKSA/OiBhcnJheSgpOwogICAgICAgICRnaXRsYWJUb2tlbiA9ICRjb25maWctPmdldCgnZ2l0bGFiLXRva2VuJykgPzogYXJyYXkoKTsKICAgICAgICAkaHR0cEJhc2ljID0gJGNvbmZpZy0+Z2V0KCdodHRwLWJhc2ljJykgPzogYXJyYXkoKTsKICAgICAgICAkYmVhcmVyVG9rZW4gPSAkY29uZmlnLT5nZXQoJ2JlYXJlcicpID86IGFycmF5KCk7CgogICAgICAgIC8vIHJlbG9hZCBvYXV0aCB0b2tlbnMgZnJvbSBjb25maWcgaWYgYXZhaWxhYmxlCgogICAgICAgIGZvcmVhY2ggKCRiaXRidWNrZXRPYXV0aCBhcyAkZG9tYWluID0+ICRjcmVkKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICRjcmVkWydjb25zdW1lci1rZXknXSwgJGNyZWRbJ2NvbnN1bWVyLXNlY3JldCddKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRnaXRodWJPYXV0aCBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAvLyBhbGxvd2VkIGNoYXJzIGZvciBHSCB0b2tlbnMgYXJlIGZyb20gaHR0cHM6Ly9naXRodWIuYmxvZy9jaGFuZ2Vsb2cvMjAyMS0wMy0wNC1hdXRoZW50aWNhdGlvbi10b2tlbi1mb3JtYXQtdXBkYXRlcy8KICAgICAgICAgICAgLy8gcGx1cyBkb3RzIHdoaWNoIHdlcmUgYXQgc29tZSBwb2ludCB1c2VkIGZvciBHSCBhcHAgaW50ZWdyYXRpb24gdG9rZW5zCiAgICAgICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgne15bLkEtWmEtejAtOV9dKyR9JywgJHRva2VuKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1lvdXIgZ2l0aHViIG9hdXRoIHRva2VuIGZvciAnLiRkb21haW4uJyBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnM6ICInLiR0b2tlbi4nIicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR0b2tlbiwgJ3gtb2F1dGgtYmFzaWMnKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRnaXRsYWJPYXV0aCBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tBbmRTZXRBdXRoZW50aWNhdGlvbigkZG9tYWluLCAkdG9rZW4sICdvYXV0aDInKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRnaXRsYWJUb2tlbiBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAkdXNlcm5hbWUgPSBpc19hcnJheSgkdG9rZW4pICYmIGFycmF5X2tleV9leGlzdHMoInVzZXJuYW1lIiwgJHRva2VuKSA/ICR0b2tlblsidXNlcm5hbWUiXSA6ICR0b2tlbjsKICAgICAgICAgICAgJHBhc3N3b3JkID0gaXNfYXJyYXkoJHRva2VuKSAmJiBhcnJheV9rZXlfZXhpc3RzKCJ0b2tlbiIsICR0b2tlbikgPyAkdG9rZW5bInRva2VuIl0gOiAncHJpdmF0ZS10b2tlbic7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR1c2VybmFtZSwgJHBhc3N3b3JkKTsKICAgICAgICB9CgogICAgICAgIC8vIHJlbG9hZCBodHRwIGJhc2ljIGNyZWRlbnRpYWxzIGZyb20gY29uZmlnIGlmIGF2YWlsYWJsZQogICAgICAgIGZvcmVhY2ggKCRodHRwQmFzaWMgYXMgJGRvbWFpbiA9PiAkY3JlZCkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tBbmRTZXRBdXRoZW50aWNhdGlvbigkZG9tYWluLCAkY3JlZFsndXNlcm5hbWUnXSwgJGNyZWRbJ3Bhc3N3b3JkJ10pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGJlYXJlclRva2VuIGFzICRkb21haW4gPT4gJHRva2VuKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR0b2tlbiwgJ2JlYXJlcicpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2V0dXAgcHJvY2VzcyB0aW1lb3V0CiAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjpzZXRUaW1lb3V0KChpbnQpICRjb25maWctPmdldCgncHJvY2Vzcy10aW1lb3V0JykpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbWVyZ2VuY3koJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpFTUVSR0VOQ1ksICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFsZXJ0KCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6QUxFUlQsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyaXRpY2FsKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6Q1JJVElDQUwsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVycm9yKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6RVJST1IsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpXQVJOSU5HLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpOT1RJQ0UsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluZm8oJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpJTkZPLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWJ1ZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkRFQlVHLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmIChpbl9hcnJheSgkbGV2ZWwsIGFycmF5KExvZ0xldmVsOjpFTUVSR0VOQ1ksIExvZ0xldmVsOjpBTEVSVCwgTG9nTGV2ZWw6OkNSSVRJQ0FMLCBMb2dMZXZlbDo6RVJST1IpKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVFcnJvcignPGVycm9yPicuJG1lc3NhZ2UuJzwvZXJyb3I+Jyk7CiAgICAgICAgfSBlbHNlaWYgKCRsZXZlbCA9PT0gTG9nTGV2ZWw6OldBUk5JTkcpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJG1lc3NhZ2UuJzwvd2FybmluZz4nKTsKICAgICAgICB9IGVsc2VpZiAoJGxldmVsID09PSBMb2dMZXZlbDo6Tk9USUNFKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZUVycm9yKCc8aW5mbz4nLiRtZXNzYWdlLic8L2luZm8+JywgdHJ1ZSwgc2VsZjo6VkVSQk9TRSk7CiAgICAgICAgfSBlbHNlaWYgKCRsZXZlbCA9PT0gTG9nTGV2ZWw6OklORk8pIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlRXJyb3IoJzxpbmZvPicuJG1lc3NhZ2UuJzwvaW5mbz4nLCB0cnVlLCBzZWxmOjpWRVJZX1ZFUkJPU0UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZUVycm9yKCRtZXNzYWdlLCB0cnVlLCBzZWxmOjpERUJVRyk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXElPOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlOwoKLyoqCiAqIFRoZSBJbnB1dC9PdXRwdXQgaGVscGVyIGludGVyZmFjZS4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmludGVyZmFjZSBJT0ludGVyZmFjZSBleHRlbmRzIExvZ2dlckludGVyZmFjZQp7CiAgICBjb25zdCBRVUlFVCA9IDE7CiAgICBjb25zdCBOT1JNQUwgPSAyOwogICAgY29uc3QgVkVSQk9TRSA9IDQ7CiAgICBjb25zdCBWRVJZX1ZFUkJPU0UgPSA4OwogICAgY29uc3QgREVCVUcgPSAxNjsKCiAgICAvKioKICAgICAqIElzIHRoaXMgaW5wdXQgbWVhbnMgaW50ZXJhY3RpdmU/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0ludGVyYWN0aXZlKCk7CgogICAgLyoqCiAgICAgKiBJcyB0aGlzIG91dHB1dCB2ZXJib3NlPwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJib3NlKCk7CgogICAgLyoqCiAgICAgKiBJcyB0aGUgb3V0cHV0IHZlcnkgdmVyYm9zZT8KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyeVZlcmJvc2UoKTsKCiAgICAvKioKICAgICAqIElzIHRoZSBvdXRwdXQgaW4gZGVidWcgdmVyYm9zaXR5PwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWJ1ZygpOwoKICAgIC8qKgogICAgICogSXMgdGhpcyBvdXRwdXQgZGVjb3JhdGVkPwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKTsKCiAgICAvKioKICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdICRtZXNzYWdlcyAgVGhlIG1lc3NhZ2UgYXMgYW4gYXJyYXkgb2YgbGluZXMgb3IgYSBzaW5nbGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRuZXdsaW5lICAgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkdmVyYm9zaXR5IFZlcmJvc2l0eSBsZXZlbCBmcm9tIHRoZSBWRVJCT1NJVFlfKiBjb25zdGFudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKTsKCiAgICAvKioKICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGVycm9yIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdICRtZXNzYWdlcyAgVGhlIG1lc3NhZ2UgYXMgYW4gYXJyYXkgb2YgbGluZXMgb3IgYSBzaW5nbGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRuZXdsaW5lICAgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkdmVyYm9zaXR5IFZlcmJvc2l0eSBsZXZlbCBmcm9tIHRoZSBWRVJCT1NJVFlfKiBjb25zdGFudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlRXJyb3IoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpOwoKICAgIC8qKgogICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgb3V0cHV0LCB3aXRob3V0IGZvcm1hdHRpbmcgaXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkbWVzc2FnZXMgIFRoZSBtZXNzYWdlIGFzIGFuIGFycmF5IG9mIGxpbmVzIG9yIGEgc2luZ2xlIHN0cmluZwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAkbmV3bGluZSAgIFdoZXRoZXIgdG8gYWRkIGEgbmV3bGluZSBvciBub3QKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJHZlcmJvc2l0eSBWZXJib3NpdHkgbGV2ZWwgZnJvbSB0aGUgVkVSQk9TSVRZXyogY29uc3RhbnRzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZVJhdygkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCk7CgogICAgLyoqCiAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBlcnJvciBvdXRwdXQsIHdpdGhvdXQgZm9ybWF0dGluZyBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdICRtZXNzYWdlcyAgVGhlIG1lc3NhZ2UgYXMgYW4gYXJyYXkgb2YgbGluZXMgb3IgYSBzaW5nbGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRuZXdsaW5lICAgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkdmVyYm9zaXR5IFZlcmJvc2l0eSBsZXZlbCBmcm9tIHRoZSBWRVJCT1NJVFlfKiBjb25zdGFudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlRXJyb3JSYXcoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpOwoKICAgIC8qKgogICAgICogT3ZlcndyaXRlcyBhIHByZXZpb3VzIG1lc3NhZ2UgdG8gdGhlIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdICRtZXNzYWdlcyAgVGhlIG1lc3NhZ2UgYXMgYW4gYXJyYXkgb2YgbGluZXMgb3IgYSBzaW5nbGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRuZXdsaW5lICAgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkc2l6ZSAgICAgIFRoZSBzaXplIG9mIGxpbmUKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJHZlcmJvc2l0eSBWZXJib3NpdHkgbGV2ZWwgZnJvbSB0aGUgVkVSQk9TSVRZXyogY29uc3RhbnRzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvdmVyd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICRzaXplID0gbnVsbCwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCk7CgogICAgLyoqCiAgICAgKiBPdmVyd3JpdGVzIGEgcHJldmlvdXMgbWVzc2FnZSB0byB0aGUgZXJyb3Igb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8c3RyaW5nW10gJG1lc3NhZ2VzICBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBsaW5lcyBvciBhIHNpbmdsZSBzdHJpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgJG5ld2xpbmUgICBXaGV0aGVyIHRvIGFkZCBhIG5ld2xpbmUgb3Igbm90CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRzaXplICAgICAgVGhlIHNpemUgb2YgbGluZQogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkdmVyYm9zaXR5IFZlcmJvc2l0eSBsZXZlbCBmcm9tIHRoZSBWRVJCT1NJVFlfKiBjb25zdGFudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZUVycm9yKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkc2l6ZSA9IG51bGwsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpOwoKICAgIC8qKgogICAgICogQXNrcyBhIHF1ZXN0aW9uIHRvIHRoZSB1c2VyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uIFRoZSBxdWVzdGlvbiB0byBhc2sKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlZmF1bHQgIFRoZSBkZWZhdWx0IGFuc3dlciBpZiBub25lIGlzIGdpdmVuIGJ5IHRoZSB1c2VyCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBJZiB0aGVyZSBpcyBubyBkYXRhIHRvIHJlYWQgaW4gdGhlIGlucHV0IHN0cmVhbQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCAgICAgICBUaGUgdXNlciBhbnN3ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFzaygkcXVlc3Rpb24sICRkZWZhdWx0ID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBBc2tzIGEgY29uZmlybWF0aW9uIHRvIHRoZSB1c2VyLgogICAgICoKICAgICAqIFRoZSBxdWVzdGlvbiB3aWxsIGJlIGFza2VkIHVudGlsIHRoZSB1c2VyIGFuc3dlcnMgYnkgbm90aGluZywgeWVzLCBvciBuby4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRxdWVzdGlvbiBUaGUgcXVlc3Rpb24gdG8gYXNrCiAgICAgKiBAcGFyYW0gYm9vbCAgICRkZWZhdWx0ICBUaGUgZGVmYXVsdCBhbnN3ZXIgaWYgdGhlIHVzZXIgZW50ZXJzIG5vdGhpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdXNlciBoYXMgY29uZmlybWVkLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0ID0gdHJ1ZSk7CgogICAgLyoqCiAgICAgKiBBc2tzIGZvciBhIHZhbHVlIGFuZCB2YWxpZGF0ZXMgdGhlIHJlc3BvbnNlLgogICAgICoKICAgICAqIFRoZSB2YWxpZGF0b3IgcmVjZWl2ZXMgdGhlIGRhdGEgdG8gdmFsaWRhdGUuIEl0IG11c3QgcmV0dXJuIHRoZQogICAgICogdmFsaWRhdGVkIGRhdGEgd2hlbiB0aGUgZGF0YSBpcyB2YWxpZCBhbmQgdGhyb3cgYW4gZXhjZXB0aW9uCiAgICAgKiBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRxdWVzdGlvbiAgVGhlIHF1ZXN0aW9uIHRvIGFzawogICAgICogQHBhcmFtIGNhbGxhYmxlICR2YWxpZGF0b3IgQSBQSFAgY2FsbGJhY2sKICAgICAqIEBwYXJhbSBudWxsfGludCAkYXR0ZW1wdHMgIE1heCBudW1iZXIgb2YgdGltZXMgdG8gYXNrIGJlZm9yZSBnaXZpbmcgdXAgKGRlZmF1bHQgb2YgbnVsbCBtZWFucyBpbmZpbml0ZSkKICAgICAqIEBwYXJhbSBtaXhlZCAgICAkZGVmYXVsdCAgIFRoZSBkZWZhdWx0IGFuc3dlciBpZiBub25lIGlzIGdpdmVuIGJ5IHRoZSB1c2VyCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uIFdoZW4gYW55IG9mIHRoZSB2YWxpZGF0b3JzIHJldHVybiBhbiBlcnJvcgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQW5kVmFsaWRhdGUoJHF1ZXN0aW9uLCAkdmFsaWRhdG9yLCAkYXR0ZW1wdHMgPSBudWxsLCAkZGVmYXVsdCA9IG51bGwpOwoKICAgIC8qKgogICAgICogQXNrcyBhIHF1ZXN0aW9uIHRvIHRoZSB1c2VyIGFuZCBoaWRlIHRoZSBhbnN3ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24gVGhlIHF1ZXN0aW9uIHRvIGFzawogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIGFuc3dlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQW5kSGlkZUFuc3dlcigkcXVlc3Rpb24pOwoKICAgIC8qKgogICAgICogQXNrcyB0aGUgdXNlciB0byBzZWxlY3QgYSB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHF1ZXN0aW9uICAgICBUaGUgcXVlc3Rpb24gdG8gYXNrCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgJGNob2ljZXMgICAgICBMaXN0IG9mIGNob2ljZXMgdG8gcGljayBmcm9tCiAgICAgKiBAcGFyYW0gYm9vbHxzdHJpbmcgJGRlZmF1bHQgICAgICBUaGUgZGVmYXVsdCBhbnN3ZXIgaWYgdGhlIHVzZXIgZW50ZXJzIG5vdGhpbmcKICAgICAqIEBwYXJhbSBib29sfGludCAgICAkYXR0ZW1wdHMgICAgIE1heCBudW1iZXIgb2YgdGltZXMgdG8gYXNrIGJlZm9yZSBnaXZpbmcgdXAgKGZhbHNlIGJ5IGRlZmF1bHQsIHdoaWNoIG1lYW5zIGluZmluaXRlKQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRlcnJvck1lc3NhZ2UgTWVzc2FnZSB3aGljaCB3aWxsIGJlIHNob3duIGlmIGludmFsaWQgdmFsdWUgZnJvbSBjaG9pY2UgbGlzdCB3b3VsZCBiZSBwaWNrZWQKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkbXVsdGlzZWxlY3QgIFNlbGVjdCBtb3JlIHRoYW4gb25lIHZhbHVlIHNlcGFyYXRlZCBieSBjb21tYQogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHJldHVybiBpbnR8c3RyaW5nfHN0cmluZ1tdfGJvb2wgICAgIFRoZSBzZWxlY3RlZCB2YWx1ZSBvciB2YWx1ZXMgKHRoZSBrZXkgb2YgdGhlIGNob2ljZXMgYXJyYXkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWxlY3QoJHF1ZXN0aW9uLCAkY2hvaWNlcywgJGRlZmF1bHQsICRhdHRlbXB0cyA9IGZhbHNlLCAkZXJyb3JNZXNzYWdlID0gJ1ZhbHVlICIlcyIgaXMgaW52YWxpZCcsICRtdWx0aXNlbGVjdCA9IGZhbHNlKTsKCiAgICAvKioKICAgICAqIEdldCBhbGwgYXV0aGVudGljYXRpb24gaW5mb3JtYXRpb24gZW50ZXJlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgYXJyYXl7dXNlcm5hbWU6IHN0cmluZ3xudWxsLCBwYXNzd29yZDogc3RyaW5nfG51bGx9PiBUaGUgbWFwIG9mIGF1dGhlbnRpY2F0aW9uIGRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dGhlbnRpY2F0aW9ucygpOwoKICAgIC8qKgogICAgICogVmVyaWZ5IGlmIHRoZSByZXBvc2l0b3J5IGhhcyBhIGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlcG9zaXRvcnlOYW1lIFRoZSB1bmlxdWUgbmFtZSBvZiByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSB1c2VybmFtZSBhbmQgcGFzc3dvcmQgb2YgcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXBvc2l0b3J5TmFtZSBUaGUgdW5pcXVlIG5hbWUgb2YgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7dXNlcm5hbWU6IHN0cmluZ3xudWxsLCBwYXNzd29yZDogc3RyaW5nfG51bGx9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiBmb3IgdGhlIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJHJlcG9zaXRvcnlOYW1lIFRoZSB1bmlxdWUgbmFtZSBvZiByZXBvc2l0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nICAkdXNlcm5hbWUgICAgICAgVGhlIHVzZXJuYW1lCiAgICAgKiBAcGFyYW0gP3N0cmluZyAkcGFzc3dvcmQgICAgICAgVGhlIHBhc3N3b3JkCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUsICR1c2VybmFtZSwgJHBhc3N3b3JkID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBMb2FkcyBhdXRoZW50aWNhdGlvbnMgZnJvbSBhIGNvbmZpZyBpbnN0YW5jZQogICAgICoKICAgICAqIEBwYXJhbSBDb25maWcgJGNvbmZpZwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZENvbmZpZ3VyYXRpb24oQ29uZmlnICRjb25maWcpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXElPOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcU3RyZWFtT3V0cHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XFN0cmluZ0lucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcSGVscGVyU2V0OwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEJ1ZmZlcklPIGV4dGVuZHMgQ29uc29sZUlPCnsKICAgIC8qKiBAdmFyIFN0cmluZ0lucHV0ICovCiAgICBwcm90ZWN0ZWQgJGlucHV0OwogICAgLyoqIEB2YXIgU3RyZWFtT3V0cHV0ICovCiAgICBwcm90ZWN0ZWQgJG91dHB1dDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkaW5wdXQKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyYm9zaXR5CiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlfG51bGwgJGZvcm1hdHRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGlucHV0ID0gJycsICR2ZXJib3NpdHkgPSBTdHJlYW1PdXRwdXQ6OlZFUkJPU0lUWV9OT1JNQUwsIE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkaW5wdXQgPSBuZXcgU3RyaW5nSW5wdXQoJGlucHV0KTsKICAgICAgICAkaW5wdXQtPnNldEludGVyYWN0aXZlKGZhbHNlKTsKCiAgICAgICAgJG91dHB1dCA9IG5ldyBTdHJlYW1PdXRwdXQoZm9wZW4oJ3BocDovL21lbW9yeScsICdydycpLCAkdmVyYm9zaXR5LCAkZm9ybWF0dGVyID8gJGZvcm1hdHRlci0+aXNEZWNvcmF0ZWQoKSA6IGZhbHNlLCAkZm9ybWF0dGVyKTsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW5wdXQsICRvdXRwdXQsIG5ldyBIZWxwZXJTZXQoYXJyYXkoCiAgICAgICAgICAgIG5ldyBRdWVzdGlvbkhlbHBlcigpLAogICAgICAgICkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nIG91dHB1dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3V0cHV0KCkKICAgIHsKICAgICAgICBmc2VlaygkdGhpcy0+b3V0cHV0LT5nZXRTdHJlYW0oKSwgMCk7CgogICAgICAgICRvdXRwdXQgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5vdXRwdXQtPmdldFN0cmVhbSgpKTsKCiAgICAgICAgJG91dHB1dCA9IFByZWc6OnJlcGxhY2VDYWxsYmFjaygieyg/PD1efFxufFx4MDgpKC4rPykoXHgwOCspfSIsIGZ1bmN0aW9uICgkbWF0Y2hlcykgewogICAgICAgICAgICAkcHJlID0gc3RyaXBfdGFncygkbWF0Y2hlc1sxXSk7CgogICAgICAgICAgICBpZiAoc3RybGVuKCRwcmUpID09PSBzdHJsZW4oJG1hdGNoZXNbMl0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRPRE8gcmV2ZXJzZSBwYXJzZSB0aGUgc3RyaW5nLCBza2lwcGluZyBzcGFuIHRhZ3MgYW5kIFwwMzNcWyhbMC05O10rKW0oLio/KVwwMzNcWzBtIHN0eWxlIGJsb2JzCiAgICAgICAgICAgIHJldHVybiBydHJpbSgkbWF0Y2hlc1sxXSkuIlxuIjsKICAgICAgICB9LCAkb3V0cHV0KTsKCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGlucHV0cwogICAgICoKICAgICAqIEBzZWUgY3JlYXRlU3RyZWFtCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVc2VySW5wdXRzKGFycmF5ICRpbnB1dHMpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aW5wdXQgaW5zdGFuY2VvZiBTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdTZXR0aW5nIHRoZSB1c2VyIGlucHV0cyByZXF1aXJlcyBhdCBsZWFzdCB0aGUgdmVyc2lvbiAzLjIgb2YgdGhlIHN5bWZvbnkvY29uc29sZSBjb21wb25lbnQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW5wdXQtPnNldFN0cmVhbSgkdGhpcy0+Y3JlYXRlU3RyZWFtKCRpbnB1dHMpKTsKICAgICAgICAkdGhpcy0+aW5wdXQtPnNldEludGVyYWN0aXZlKHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRpbnB1dHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGZhbHNlfHJlc291cmNlIHN0cmVhbQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVN0cmVhbShhcnJheSAkaW5wdXRzKQogICAgewogICAgICAgICRzdHJlYW0gPSBmb3BlbigncGhwOi8vbWVtb3J5JywgJ3IrJyk7CgogICAgICAgIGZvcmVhY2ggKCRpbnB1dHMgYXMgJGlucHV0KSB7CiAgICAgICAgICAgIGZ3cml0ZSgkc3RyZWFtLCAkaW5wdXQuUEhQX0VPTCk7CiAgICAgICAgfQoKICAgICAgICByZXdpbmQoJHN0cmVhbSk7CgogICAgICAgIHJldHVybiAkc3RyZWFtOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwoKLyoqCiAqIERlZmluZXMgdGhlIGVzc2VudGlhbCBpbmZvcm1hdGlvbiBhIHBhY2thZ2UgaGFzIHRoYXQgaXMgdXNlZCBkdXJpbmcgc29sdmluZy9pbnN0YWxsYXRpb24KICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KaW50ZXJmYWNlIFBhY2thZ2VJbnRlcmZhY2UKewogICAgY29uc3QgRElTUExBWV9TT1VSQ0VfUkVGX0lGX0RFViA9IDA7CiAgICBjb25zdCBESVNQTEFZX1NPVVJDRV9SRUYgPSAxOwogICAgY29uc3QgRElTUExBWV9ESVNUX1JFRiA9IDI7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlJ3MgbmFtZSB3aXRob3V0IHZlcnNpb24gaW5mbywgdGh1cyBub3QgYSB1bmlxdWUgaWRlbnRpZmllcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHBhY2thZ2UgbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSdzIHByZXR0eSAoaS5lLiB3aXRoIHByb3BlciBjYXNlKSBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcGFja2FnZSBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlOYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIG5hbWVzIHRoYXQgY291bGQgcmVmZXIgdG8gdGhpcyBwYWNrYWdlCiAgICAgKgogICAgICogTm8gdmVyc2lvbiBvciByZWxlYXNlIHR5cGUgaW5mb3JtYXRpb24gc2hvdWxkIGJlIGluY2x1ZGVkIGluIGFueSBvZiB0aGUKICAgICAqIG5hbWVzLiBQcm92aWRlZCBvciByZXBsYWNlZCBwYWNrYWdlIG5hbWVzIG5lZWQgdG8gYmUgcmV0dXJuZWQgYXMgd2VsbC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkcHJvdmlkZXMgV2hldGhlciBwcm92aWRlZCBuYW1lcyBzaG91bGQgYmUgaW5jbHVkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIEFuIGFycmF5IG9mIHN0cmluZ3MgcmVmZXJyaW5nIHRvIHRoaXMgcGFja2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXMoJHByb3ZpZGVzID0gdHJ1ZSk7CgogICAgLyoqCiAgICAgKiBBbGxvd3MgdGhlIHNvbHZlciB0byBzZXQgYW4gaWQgZm9yIHRoaXMgcGFja2FnZSB0byByZWZlciB0byBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRpZAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SWQoJGlkKTsKCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUgcGFja2FnZSdzIGlkIHNldCB0aHJvdWdoIHNldElkCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIHByZXZpb3VzbHkgc2V0IHBhY2thZ2UgaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElkKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHBhY2thZ2UgaXMgYSBkZXZlbG9wbWVudCB2aXJ0dWFsIHBhY2thZ2Ugb3IgYSBjb25jcmV0ZSBvbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGV2KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlIHR5cGUsIGUuZy4gbGlicmFyeQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBwYWNrYWdlIHR5cGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgdGFyZ2V0RGlyIHByb3BlcnR5CiAgICAgKgogICAgICogQHJldHVybiA/c3RyaW5nIFRoZSBwYWNrYWdlIHRhcmdldERpcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0RGlyKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlIGV4dHJhIGRhdGEKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkW10gVGhlIHBhY2thZ2UgZXh0cmEgZGF0YQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXh0cmEoKTsKCiAgICAvKioKICAgICAqIFNldHMgc291cmNlIGZyb20gd2hpY2ggdGhpcyBwYWNrYWdlIHdhcyBpbnN0YWxsZWQgKHNvdXJjZS9kaXN0KS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIHNvdXJjZS9kaXN0CiAgICAgKiBAcGhwc3Rhbi1wYXJhbSAnc291cmNlJ3wnZGlzdCd8bnVsbCAkdHlwZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5zdGFsbGF0aW9uU291cmNlKCR0eXBlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgc291cmNlIGZyb20gd2hpY2ggdGhpcyBwYWNrYWdlIHdhcyBpbnN0YWxsZWQgKHNvdXJjZS9kaXN0KS4KICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcgc291cmNlL2Rpc3QKICAgICAqIEBwaHBzdGFuLXJldHVybiAnc291cmNlJ3wnZGlzdCd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGF0aW9uU291cmNlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZXBvc2l0b3J5IHR5cGUgb2YgdGhpcyBwYWNrYWdlLCBlLmcuIGdpdCwgc3ZuCiAgICAgKgogICAgICogQHJldHVybiA/c3RyaW5nIFRoZSByZXBvc2l0b3J5IHR5cGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlcG9zaXRvcnkgdXJsIG9mIHRoaXMgcGFja2FnZSwgZS5nLiBnaXQ6Ly9naXRodWIuY29tL25hZGVybWFuL2NvbXBvc2VyLmdpdAogICAgICoKICAgICAqIEByZXR1cm4gP3N0cmluZyBUaGUgcmVwb3NpdG9yeSB1cmwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVVybCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVwb3NpdG9yeSB1cmxzIG9mIHRoaXMgcGFja2FnZSBpbmNsdWRpbmcgbWlycm9ycywgZS5nLiBnaXQ6Ly9naXRodWIuY29tL25hZGVybWFuL2NvbXBvc2VyLmdpdAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVVybHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlcG9zaXRvcnkgcmVmZXJlbmNlIG9mIHRoaXMgcGFja2FnZSwgZS5nLiBtYXN0ZXIsIDEuMC4wIG9yIGEgY29tbWl0IGhhc2ggZm9yIGdpdAogICAgICoKICAgICAqIEByZXR1cm4gP3N0cmluZyBUaGUgcmVwb3NpdG9yeSByZWZlcmVuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVJlZmVyZW5jZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc291cmNlIG1pcnJvcnMgb2YgdGhpcyBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiA/YXJyYXk8aW50LCBhcnJheXt1cmw6IHN0cmluZywgcHJlZmVycmVkOiBib29sfT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZU1pcnJvcnMoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSAgP2FycmF5PGludCwgYXJyYXl7dXJsOiBzdHJpbmcsIHByZWZlcnJlZDogYm9vbH0+ICRtaXJyb3JzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZU1pcnJvcnMoJG1pcnJvcnMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgZGlzdHJpYnV0aW9uIGFyY2hpdmUgb2YgdGhpcyB2ZXJzaW9uLCBlLmcuIHppcCwgdGFyYmFsbAogICAgICoKICAgICAqIEByZXR1cm4gP3N0cmluZyBUaGUgcmVwb3NpdG9yeSB0eXBlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdXJsIG9mIHRoZSBkaXN0cmlidXRpb24gYXJjaGl2ZSBvZiB0aGlzIHZlcnNpb24KICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RVcmwoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHVybHMgb2YgdGhlIGRpc3RyaWJ1dGlvbiBhcmNoaXZlIG9mIHRoaXMgdmVyc2lvbiwgaW5jbHVkaW5nIG1pcnJvcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VXJscygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIG9mIHRoZSBkaXN0cmlidXRpb24gYXJjaGl2ZSBvZiB0aGlzIHZlcnNpb24sIGUuZy4gbWFzdGVyLCAxLjAuMCBvciBhIGNvbW1pdCBoYXNoIGZvciBnaXQKICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RSZWZlcmVuY2UoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNoYTEgY2hlY2tzdW0gZm9yIHRoZSBkaXN0cmlidXRpb24gYXJjaGl2ZSBvZiB0aGlzIHZlcnNpb24KICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RTaGExQ2hlY2tzdW0oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRpc3QgbWlycm9ycyBvZiB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuID9hcnJheTxpbnQsIGFycmF5e3VybDogc3RyaW5nLCBwcmVmZXJyZWQ6IGJvb2x9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdE1pcnJvcnMoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSAgP2FycmF5PGludCwgYXJyYXl7dXJsOiBzdHJpbmcsIHByZWZlcnJlZDogYm9vbH0+ICRtaXJyb3JzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RNaXJyb3JzKCRtaXJyb3JzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgdGhpcyBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgdmVyc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJldHR5IChpLmUuIG5vbi1ub3JtYWxpemVkKSB2ZXJzaW9uIHN0cmluZyBvZiB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlWZXJzaW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcmV0dHkgdmVyc2lvbiBzdHJpbmcgcGx1cyBhIGdpdCBvciBoZyBjb21taXQgaGFzaCBvZiB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAc2VlIGdldFByZXR0eVZlcnNpb24KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAkdHJ1bmNhdGUgICAgSWYgdGhlIHNvdXJjZSByZWZlcmVuY2UgaXMgYSBzaGExIGhhc2gsIHRydW5jYXRlIGl0CiAgICAgKiBAcGFyYW0gIGludCAgICAkZGlzcGxheU1vZGUgT25lIG9mIHRoZSBESVNQTEFZXyBjb25zdGFudHMgb24gdGhpcyBpbnRlcmZhY2UgZGV0ZXJtaW5pbmcgZGlzcGxheSBvZiByZWZlcmVuY2VzCiAgICAgKiBAcmV0dXJuIHN0cmluZyB2ZXJzaW9uCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gc2VsZjo6RElTUExBWV9TT1VSQ0VfUkVGX0lGX0RFVnxzZWxmOjpESVNQTEFZX1NPVVJDRV9SRUZ8c2VsZjo6RElTUExBWV9ESVNUX1JFRiAkZGlzcGxheU1vZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZ1bGxQcmV0dHlWZXJzaW9uKCR0cnVuY2F0ZSA9IHRydWUsICRkaXNwbGF5TW9kZSA9IHNlbGY6OkRJU1BMQVlfU09VUkNFX1JFRl9JRl9ERVYpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVsZWFzZSBkYXRlIG9mIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiA/XERhdGVUaW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWxlYXNlRGF0ZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3RhYmlsaXR5IG9mIHRoaXMgcGFja2FnZTogb25lIG9mIChkZXYsIGFscGhhLCBiZXRhLCBSQywgc3RhYmxlKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKgogICAgICogQHBocHN0YW4tcmV0dXJuICdzdGFibGUnfCdSQyd8J2JldGEnfCdhbHBoYSd8J2RldicKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBsaW5rcyB0byBwYWNrYWdlcyB3aGljaCBuZWVkIHRvIGJlIGluc3RhbGxlZCBiZWZvcmUKICAgICAqIHRoaXMgcGFja2FnZSBjYW4gYmUgaW5zdGFsbGVkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIExpbms+IEEgbWFwIG9mIHBhY2thZ2UgbGlua3MgZGVmaW5pbmcgcmVxdWlyZWQgcGFja2FnZXMsIGluZGV4ZWQgYnkgdGhlIHJlcXVpcmUgcGFja2FnZSdzIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcXVpcmVzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIGxpbmtzIHRvIHBhY2thZ2VzIHdoaWNoIG11c3Qgbm90IGJlIGluc3RhbGxlZCBhdCB0aGUKICAgICAqIHNhbWUgdGltZSBhcyB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIExpbmtbXSBBbiBhcnJheSBvZiBwYWNrYWdlIGxpbmtzIGRlZmluaW5nIGNvbmZsaWN0aW5nIHBhY2thZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25mbGljdHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgbGlua3MgdG8gdmlydHVhbCBwYWNrYWdlcyB0aGF0IGFyZSBwcm92aWRlZCB0aHJvdWdoCiAgICAgKiB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIExpbmtbXSBBbiBhcnJheSBvZiBwYWNrYWdlIGxpbmtzIGRlZmluaW5nIHByb3ZpZGVkIHBhY2thZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBsaW5rcyB0byBwYWNrYWdlcyB3aGljaCBjYW4gYWx0ZXJuYXRpdmVseSBiZQogICAgICogc2F0aXNmaWVkIGJ5IGluc3RhbGxpbmcgdGhpcyBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiBMaW5rW10gQW4gYXJyYXkgb2YgcGFja2FnZSBsaW5rcyBkZWZpbmluZyByZXBsYWNlZCBwYWNrYWdlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZXMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgbGlua3MgdG8gcGFja2FnZXMgd2hpY2ggYXJlIHJlcXVpcmVkIHRvIGRldmVsb3AKICAgICAqIHRoaXMgcGFja2FnZS4gVGhlc2UgYXJlIGluc3RhbGxlZCBpZiBpbiBkZXYgbW9kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgTGluaz4gQSBtYXAgb2YgcGFja2FnZSBsaW5rcyBkZWZpbmluZyBwYWNrYWdlcyByZXF1aXJlZCBmb3IgZGV2ZWxvcG1lbnQsIGluZGV4ZWQgYnkgdGhlIHJlcXVpcmUgcGFja2FnZSdzIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldlJlcXVpcmVzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHBhY2thZ2UgbmFtZXMgYW5kIHJlYXNvbnMgd2h5IHRoZXkgYXJlIHVzZWZ1bCBpbgogICAgICogY29tYmluYXRpb24gd2l0aCB0aGlzIHBhY2thZ2UuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBBbiBhcnJheSBvZiBwYWNrYWdlIHN1Z2dlc3Rpb25zIHdpdGggZGVzY3JpcHRpb25zCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdWdnZXN0cygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhc3NvY2lhdGl2ZSBhcnJheSBvZiBhdXRvbG9hZGluZyBydWxlcwogICAgICoKICAgICAqIHsiPHR5cGU+IjogeyI8bmFtZXNwYWNlIjogIjxkaXJlY3Rvcnk+In19CiAgICAgKgogICAgICogVHlwZSBpcyBlaXRoZXIgInBzci00IiwgInBzci0wIiwgImNsYXNzbWFwIiBvciAiZmlsZXMiLiBOYW1lc3BhY2VzIGFyZSBtYXBwZWQgdG8KICAgICAqIGRpcmVjdG9yaWVzIGZvciBhdXRvbG9hZGluZyB1c2luZyB0aGUgdHlwZSBzcGVjaWZpZWQuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBNYXBwaW5nIG9mIGF1dG9sb2FkaW5nIHJ1bGVzCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXl7cHNyLTA/OiBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXT4sIHBzci00PzogYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW10+LCBjbGFzc21hcD86IGxpc3Q8c3RyaW5nPiwgZmlsZXM/OiBsaXN0PHN0cmluZz59CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvbG9hZCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhc3NvY2lhdGl2ZSBhcnJheSBvZiBkZXYgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqCiAgICAgKiB7Ijx0eXBlPiI6IHsiPG5hbWVzcGFjZSI6ICI8ZGlyZWN0b3J5PiJ9fQogICAgICoKICAgICAqIFR5cGUgaXMgZWl0aGVyICJwc3ItNCIsICJwc3ItMCIsICJjbGFzc21hcCIgb3IgImZpbGVzIi4gTmFtZXNwYWNlcyBhcmUgbWFwcGVkIHRvCiAgICAgKiBkaXJlY3RvcmllcyBmb3IgYXV0b2xvYWRpbmcgdXNpbmcgdGhlIHR5cGUgc3BlY2lmaWVkLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgTWFwcGluZyBvZiBkZXYgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheXtwc3ItMD86IGFycmF5PHN0cmluZywgc3RyaW5nfHN0cmluZ1tdPiwgcHNyLTQ/OiBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXT4sIGNsYXNzbWFwPzogbGlzdDxzdHJpbmc+LCBmaWxlcz86IGxpc3Q8c3RyaW5nPn0KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldkF1dG9sb2FkKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBkaXJlY3RvcmllcyB3aGljaCBzaG91bGQgZ2V0IGFkZGVkIHRvIFBIUCdzCiAgICAgKiBpbmNsdWRlIHBhdGguCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5jbHVkZVBhdGhzKCk7CgogICAgLyoqCiAgICAgKiBTdG9yZXMgYSByZWZlcmVuY2UgdG8gdGhlIHJlcG9zaXRvcnkgdGhhdCBvd25zIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcG9zaXRvcnkoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3NpdG9yeSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSByZXBvc2l0b3J5IHRoYXQgb3ducyB0aGUgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gP1JlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcnkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgYmluYXJpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCaW5hcmllcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIHVuaXF1ZSBuYW1lLCBjb25zdHJ1Y3RlZCBmcm9tIG5hbWUgYW5kIHZlcnNpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVuaXF1ZU5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2Ugbm90aWZpY2F0aW9uIHVybAogICAgICoKICAgICAqIEByZXR1cm4gP3N0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Tm90aWZpY2F0aW9uVXJsKCk7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyB0aGUgcGFja2FnZSBpbnRvIGEgcmVhZGFibGUgYW5kIHVuaXF1ZSBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpOwoKICAgIC8qKgogICAgICogQ29udmVydHMgdGhlIHBhY2thZ2UgaW50byBhIHByZXR0eSByZWFkYWJsZSBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKCk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVmYXVsdEJyYW5jaCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2Ygb3B0aW9ucyB0byBkb3dubG9hZCBwYWNrYWdlIGRpc3QgZmlsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRyYW5zcG9ydE9wdGlvbnMoKTsKCiAgICAvKioKICAgICAqIENvbmZpZ3VyZXMgdGhlIGxpc3Qgb2Ygb3B0aW9ucyB0byBkb3dubG9hZCBwYWNrYWdlIGRpc3QgZmlsZXMKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhbnNwb3J0T3B0aW9ucyhhcnJheSAkb3B0aW9ucyk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWZlcmVuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZVJlZmVyZW5jZSgkcmVmZXJlbmNlKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFVybCgkdXJsKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RUeXBlKCR0eXBlKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFJlZmVyZW5jZSgkcmVmZXJlbmNlKTsKCiAgICAvKioKICAgICAqIFNldCBkaXN0IGFuZCBzb3VyY2UgcmVmZXJlbmNlcyBhbmQgdXBkYXRlIGRpc3QgVVJMIGZvciBvbmVzIHRoYXQgY29udGFpbiBhIHJlZmVyZW5jZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlRGlzdFJlZmVyZW5jZXMoJHJlZmVyZW5jZSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCi8qKgogKiBQYWNrYWdlIGNvbnRhaW5pbmcgYWRkaXRpb25hbCBtZXRhZGF0YSB0aGF0IGlzIG5vdCB1c2VkIGJ5IHRoZSBzb2x2ZXIKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIENvbXBsZXRlUGFja2FnZSBleHRlbmRzIFBhY2thZ2UgaW1wbGVtZW50cyBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgbWl4ZWRbXSAqLwogICAgcHJvdGVjdGVkICRyZXBvc2l0b3JpZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByb3RlY3RlZCAkbGljZW5zZSA9IGFycmF5KCk7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJvdGVjdGVkICRrZXl3b3JkcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxhcnJheXtuYW1lPzogc3RyaW5nLCBob21lcGFnZT86IHN0cmluZywgZW1haWw/OiBzdHJpbmcsIHJvbGU/OiBzdHJpbmd9PiAqLwogICAgcHJvdGVjdGVkICRhdXRob3JzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkZGVzY3JpcHRpb24gPSBudWxsOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRob21lcGFnZSA9IG51bGw7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZ1tdPiBNYXAgb2Ygc2NyaXB0IG5hbWUgdG8gYXJyYXkgb2YgaGFuZGxlcnMgKi8KICAgIHByb3RlY3RlZCAkc2NyaXB0cyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheXtpc3N1ZXM/OiBzdHJpbmcsIGZvcnVtPzogc3RyaW5nLCB3aWtpPzogc3RyaW5nLCBzb3VyY2U/OiBzdHJpbmcsIGVtYWlsPzogc3RyaW5nLCBpcmM/OiBzdHJpbmcsIGRvY3M/OiBzdHJpbmcsIHJzcz86IHN0cmluZywgY2hhdD86IHN0cmluZ30gKi8KICAgIHByb3RlY3RlZCAkc3VwcG9ydCA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxhcnJheXt1cmw/OiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9PiAqLwogICAgcHJvdGVjdGVkICRmdW5kaW5nID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGJvb2x8c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJGFiYW5kb25lZCA9IGZhbHNlOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRhcmNoaXZlTmFtZSA9IG51bGw7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJvdGVjdGVkICRhcmNoaXZlRXhjbHVkZXMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNjcmlwdHMoYXJyYXkgJHNjcmlwdHMpCiAgICB7CiAgICAgICAgJHRoaXMtPnNjcmlwdHMgPSAkc2NyaXB0czsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY3JpcHRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNjcmlwdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yaWVzKGFycmF5ICRyZXBvc2l0b3JpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllcyA9ICRyZXBvc2l0b3JpZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMaWNlbnNlKGFycmF5ICRsaWNlbnNlKQogICAgewogICAgICAgICR0aGlzLT5saWNlbnNlID0gJGxpY2Vuc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGljZW5zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saWNlbnNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEtleXdvcmRzKGFycmF5ICRrZXl3b3JkcykKICAgIHsKICAgICAgICAkdGhpcy0+a2V5d29yZHMgPSAka2V5d29yZHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2V5d29yZHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+a2V5d29yZHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0aG9ycyhhcnJheSAkYXV0aG9ycykKICAgIHsKICAgICAgICAkdGhpcy0+YXV0aG9ycyA9ICRhdXRob3JzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dGhvcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXV0aG9yczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXNjcmlwdGlvbigkZGVzY3JpcHRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmRlc2NyaXB0aW9uID0gJGRlc2NyaXB0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlc2NyaXB0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhvbWVwYWdlKCRob21lcGFnZSkKICAgIHsKICAgICAgICAkdGhpcy0+aG9tZXBhZ2UgPSAkaG9tZXBhZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SG9tZXBhZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aG9tZXBhZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3VwcG9ydChhcnJheSAkc3VwcG9ydCkKICAgIHsKICAgICAgICAkdGhpcy0+c3VwcG9ydCA9ICRzdXBwb3J0OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1cHBvcnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3VwcG9ydDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGdW5kaW5nKGFycmF5ICRmdW5kaW5nKQogICAgewogICAgICAgICR0aGlzLT5mdW5kaW5nID0gJGZ1bmRpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RnVuZGluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mdW5kaW5nOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQWJhbmRvbmVkKCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpICR0aGlzLT5hYmFuZG9uZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWJhbmRvbmVkKCRhYmFuZG9uZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFiYW5kb25lZCA9ICRhYmFuZG9uZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZW1lbnRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGhpcy0+YWJhbmRvbmVkKSA/ICR0aGlzLT5hYmFuZG9uZWQgOiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVOYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5hcmNoaXZlTmFtZSA9ICRuYW1lOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyY2hpdmVOYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyY2hpdmVOYW1lOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVFeGNsdWRlcyhhcnJheSAkZXhjbHVkZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyY2hpdmVFeGNsdWRlcyA9ICRleGNsdWRlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmNoaXZlRXhjbHVkZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJjaGl2ZUV4Y2x1ZGVzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290QWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZTsKCi8qKgogKiBEZWZpbmVzIGEgbG9hZGVyIHRoYXQgdGFrZXMgYW4gYXJyYXkgdG8gY3JlYXRlIHBhY2thZ2UgaW5zdGFuY2VzCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmludGVyZmFjZSBMb2FkZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHBhY2thZ2UgZnJvbSBhbiBhcnJheSB0byBhIHJlYWwgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAdGVtcGxhdGUgUGFja2FnZUNsYXNzIG9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZQogICAgICoKICAgICAqIEBwYXJhbSAgbWl4ZWRbXSAkY29uZmlnIHBhY2thZ2UgZGF0YQogICAgICogQHBhcmFtICBzdHJpbmcgICRjbGFzcyAgRlFDTiB0byBiZSBpbnN0YW50aWF0ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbXBsZXRlUGFja2FnZXxDb21wbGV0ZUFsaWFzUGFja2FnZXxSb290UGFja2FnZXxSb290QWxpYXNQYWNrYWdlCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gY2xhc3Mtc3RyaW5nPFBhY2thZ2VDbGFzcz4gJGNsYXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKGFycmF5ICRjb25maWcsICRjbGFzcyA9ICdDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZScpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEludmFsaWRQYWNrYWdlRXhjZXB0aW9uIGV4dGVuZHMgXEV4Y2VwdGlvbgp7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJpdmF0ZSAkZXJyb3JzOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByaXZhdGUgJHdhcm5pbmdzOwogICAgLyoqIEB2YXIgbWl4ZWRbXSBwYWNrYWdlIGNvbmZpZyAqLwogICAgcHJpdmF0ZSAkZGF0YTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkZXJyb3JzCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHdhcm5pbmdzCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgJGRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRlcnJvcnMsIGFycmF5ICR3YXJuaW5ncywgYXJyYXkgJGRhdGEpCiAgICB7CiAgICAgICAgJHRoaXMtPmVycm9ycyA9ICRlcnJvcnM7CiAgICAgICAgJHRoaXMtPndhcm5pbmdzID0gJHdhcm5pbmdzOwogICAgICAgICR0aGlzLT5kYXRhID0gJGRhdGE7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgiSW52YWxpZCBwYWNrYWdlIGluZm9ybWF0aW9uOiBcbiIuaW1wbG9kZSgiXG4iLCBhcnJheV9tZXJnZSgkZXJyb3JzLCAkd2FybmluZ3MpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIG1peGVkW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERhdGEoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGF0YTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRXYXJuaW5ncygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT53YXJuaW5nczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlQWxpYXNQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaGl2IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBKc29uTG9hZGVyCnsKICAgIC8qKiBAdmFyIExvYWRlckludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkbG9hZGVyOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChMb2FkZXJJbnRlcmZhY2UgJGxvYWRlcikKICAgIHsKICAgICAgICAkdGhpcy0+bG9hZGVyID0gJGxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nfEpzb25GaWxlICAgICAgICAgICAgICAgICAgICAgICRqc29uIEEgZmlsZW5hbWUsIGpzb24gc3RyaW5nIG9yIEpzb25GaWxlIGluc3RhbmNlIHRvIGxvYWQgdGhlIHBhY2thZ2UgZnJvbQogICAgICogQHJldHVybiBDb21wbGV0ZVBhY2thZ2V8Q29tcGxldGVBbGlhc1BhY2thZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJGpzb24pCiAgICB7CiAgICAgICAgaWYgKCRqc29uIGluc3RhbmNlb2YgSnNvbkZpbGUpIHsKICAgICAgICAgICAgJGNvbmZpZyA9ICRqc29uLT5yZWFkKCk7CiAgICAgICAgfSBlbHNlaWYgKGZpbGVfZXhpc3RzKCRqc29uKSkgewogICAgICAgICAgICAkY29uZmlnID0gSnNvbkZpbGU6OnBhcnNlSnNvbihmaWxlX2dldF9jb250ZW50cygkanNvbiksICRqc29uKTsKICAgICAgICB9IGVsc2VpZiAoaXNfc3RyaW5nKCRqc29uKSkgewogICAgICAgICAgICAkY29uZmlnID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkanNvbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICJKc29uTG9hZGVyOiBVbmtub3duIFwkanNvbiBwYXJhbWV0ZXIgJXMuIFBsZWFzZSByZXBvcnQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy9uZXcuIiwKICAgICAgICAgICAgICAgIGdldHR5cGUoJGpzb24pCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkZXItPmxvYWQoJGNvbmZpZyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcU3BkeFxTcGR4TGljZW5zZXM7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVmFsaWRhdGluZ0FycmF5TG9hZGVyIGltcGxlbWVudHMgTG9hZGVySW50ZXJmYWNlCnsKICAgIGNvbnN0IENIRUNLX0FMTCA9IDM7CiAgICBjb25zdCBDSEVDS19VTkJPVU5EX0NPTlNUUkFJTlRTID0gMTsKICAgIGNvbnN0IENIRUNLX1NUUklDVF9DT05TVFJBSU5UUyA9IDI7CgogICAgLyoqIEB2YXIgTG9hZGVySW50ZXJmYWNlICovCiAgICBwcml2YXRlICRsb2FkZXI7CiAgICAvKiogQHZhciBWZXJzaW9uUGFyc2VyICovCiAgICBwcml2YXRlICR2ZXJzaW9uUGFyc2VyOwogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByaXZhdGUgJGVycm9yczsKICAgIC8qKiBAdmFyIHN0cmluZ1tdICovCiAgICBwcml2YXRlICR3YXJuaW5nczsKICAgIC8qKiBAdmFyIG1peGVkW10gKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKICAgIC8qKiBAdmFyIGludCBPbmUgb3IgbW9yZSBvZiBzZWxmOjpDSEVDS18qIGNvbnN0YW50cyAqLwogICAgcHJpdmF0ZSAkZmxhZ3M7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdHJ1ZSAkc3RyaWN0TmFtZQogICAgICogQHBhcmFtIGludCAgJGZsYWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChMb2FkZXJJbnRlcmZhY2UgJGxvYWRlciwgJHN0cmljdE5hbWUgPSB0cnVlLCBWZXJzaW9uUGFyc2VyICRwYXJzZXIgPSBudWxsLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgICR0aGlzLT5sb2FkZXIgPSAkbG9hZGVyOwogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gJHBhcnNlciA/OiBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICR0aGlzLT5mbGFncyA9ICRmbGFnczsKCiAgICAgICAgaWYgKCRzdHJpY3ROYW1lICE9PSB0cnVlKSB7IC8vIEBwaHBzdGFuLWlnbm9yZS1saW5lCiAgICAgICAgICAgIHRyaWdnZXJfZXJyb3IoJyRzdHJpY3ROYW1lIG11c3QgYmUgc2V0IHRvIHRydWUgaW4gVmFsaWRhdGluZ0FycmF5TG9hZGVyXCdzIGNvbnN0cnVjdG9yIGFzIG9mIDIuMiwgYW5kIGl0IHdpbGwgYmUgcmVtb3ZlZCBpbiAzLjAnLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoYXJyYXkgJGNvbmZpZywgJGNsYXNzID0gJ0NvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlJykKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+d2FybmluZ3MgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwoKICAgICAgICAkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ25hbWUnLCB0cnVlKTsKICAgICAgICBpZiAoJGVyciA9IHNlbGY6Omhhc1BhY2thZ2VOYW1pbmdFcnJvcigkY29uZmlnWyduYW1lJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICduYW1lIDogJy4kZXJyOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+Y29uZmlnWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgIGlmICghaXNfc2NhbGFyKCR0aGlzLT5jb25maWdbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZVN0cmluZygndmVyc2lvbicpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFpc19zdHJpbmcoJHRoaXMtPmNvbmZpZ1sndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdbJ3ZlcnNpb24nXSA9IChzdHJpbmcpICR0aGlzLT5jb25maWdbJ3ZlcnNpb24nXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkdGhpcy0+Y29uZmlnWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICd2ZXJzaW9uIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWyd2ZXJzaW9uJ10uJyk6ICcuJGUtPmdldE1lc3NhZ2UoKTsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5jb25maWdbJ2NvbmZpZyddWydwbGF0Zm9ybSddKSkgewogICAgICAgICAgICBmb3JlYWNoICgoYXJyYXkpICR0aGlzLT5jb25maWdbJ2NvbmZpZyddWydwbGF0Zm9ybSddIGFzICRrZXkgPT4gJHBsYXRmb3JtKSB7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRwbGF0Zm9ybSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc19zdHJpbmcoJHBsYXRmb3JtKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdjb25maWcucGxhdGZvcm0uJyAuICRrZXkgLiAnIDogaW52YWxpZCB2YWx1ZSAoJy5nZXR0eXBlKCRwbGF0Zm9ybSkuJyAnLnZhcl9leHBvcnQoJHBsYXRmb3JtLCB0cnVlKS4nKTogZXhwZWN0ZWQgc3RyaW5nIG9yIGZhbHNlJzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcGxhdGZvcm0pOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdjb25maWcucGxhdGZvcm0uJyAuICRrZXkgLiAnIDogaW52YWxpZCB2YWx1ZSAoJy4kcGxhdGZvcm0uJyk6ICcuJGUtPmdldE1lc3NhZ2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnZhbGlkYXRlUmVnZXgoJ3R5cGUnLCAnW0EtWmEtejAtOS1dKycpOwogICAgICAgICR0aGlzLT52YWxpZGF0ZVN0cmluZygndGFyZ2V0LWRpcicpOwogICAgICAgICR0aGlzLT52YWxpZGF0ZUFycmF5KCdleHRyYScpOwoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1snYmluJ10pKSB7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHRoaXMtPmNvbmZpZ1snYmluJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ2JpbicpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlRmxhdEFycmF5KCdiaW4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnZhbGlkYXRlQXJyYXkoJ3NjcmlwdHMnKTsgLy8gVE9ETyB2YWxpZGF0ZSBldmVudCBuYW1lcyAmIGxpc3RlbmVyIHN5bnRheAogICAgICAgICR0aGlzLT52YWxpZGF0ZVN0cmluZygnZGVzY3JpcHRpb24nKTsKICAgICAgICAkdGhpcy0+dmFsaWRhdGVVcmwoJ2hvbWVwYWdlJyk7CiAgICAgICAgJHRoaXMtPnZhbGlkYXRlRmxhdEFycmF5KCdrZXl3b3JkcycsICdbXHB7Tn1ccHtMfSAuXy1dKycpOwoKICAgICAgICAkcmVsZWFzZURhdGUgPSBudWxsOwogICAgICAgICR0aGlzLT52YWxpZGF0ZVN0cmluZygndGltZScpOwogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmNvbmZpZ1sndGltZSddKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHJlbGVhc2VEYXRlID0gbmV3IFxEYXRlVGltZSgkdGhpcy0+Y29uZmlnWyd0aW1lJ10sIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICd0aW1lIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWyd0aW1lJ10uJyk6ICcuJGUtPmdldE1lc3NhZ2UoKTsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3RpbWUnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBsaWNlbnNlIHZhbGlkaXR5IG9uIG5ld2x5IHVwZGF0ZWQgYnJhbmNoZXMKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1snbGljZW5zZSddKSAmJiAoISRyZWxlYXNlRGF0ZSB8fCAkcmVsZWFzZURhdGUtPmdldFRpbWVzdGFtcCgpID49IHN0cnRvdGltZSgnLThkYXlzJykpKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdGhpcy0+Y29uZmlnWydsaWNlbnNlJ10pIHx8IGlzX3N0cmluZygkdGhpcy0+Y29uZmlnWydsaWNlbnNlJ10pKSB7CiAgICAgICAgICAgICAgICAkbGljZW5zZXMgPSAoYXJyYXkpICR0aGlzLT5jb25maWdbJ2xpY2Vuc2UnXTsKCiAgICAgICAgICAgICAgICAkbGljZW5zZVZhbGlkYXRvciA9IG5ldyBTcGR4TGljZW5zZXMoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaWNlbnNlcyBhcyAkbGljZW5zZSkgewogICAgICAgICAgICAgICAgICAgIC8vIHJlcGxhY2UgcHJvcHJpZXRhcnkgYnkgTUlUIGZvciB2YWxpZGF0aW9uIHB1cnBvc2VzIHNpbmNlIGl0J3Mgbm90IGEgdmFsaWQgU1BEWCBpZGVudGlmaWVyLCBidXQgaXMgYWNjZXB0ZWQgYnkgY29tcG9zZXIKICAgICAgICAgICAgICAgICAgICBpZiAoJ3Byb3ByaWV0YXJ5JyA9PT0gJGxpY2Vuc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRsaWNlbnNlVG9WYWxpZGF0ZSA9IHN0cl9yZXBsYWNlKCdwcm9wcmlldGFyeScsICdNSVQnLCAkbGljZW5zZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkbGljZW5zZVZhbGlkYXRvci0+dmFsaWRhdGUoJGxpY2Vuc2VUb1ZhbGlkYXRlKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpY2Vuc2VWYWxpZGF0b3ItPnZhbGlkYXRlKHRyaW0oJGxpY2Vuc2VUb1ZhbGlkYXRlKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTGljZW5zZSAlcyBtdXN0IG5vdCBjb250YWluIGV4dHJhIHNwYWNlcywgbWFrZSBzdXJlIHRvIHRyaW0gaXQuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uX2VuY29kZSgkbGljZW5zZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0xpY2Vuc2UgJXMgaXMgbm90IGEgdmFsaWQgU1BEWCBsaWNlbnNlIGlkZW50aWZpZXIsIHNlZSBodHRwczovL3NwZHgub3JnL2xpY2Vuc2VzLyBpZiB5b3UgdXNlIGFuIG9wZW4gbGljZW5zZS4nIC4gUEhQX0VPTCAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lmIHRoZSBzb2Z0d2FyZSBpcyBjbG9zZWQtc291cmNlLCB5b3UgbWF5IHVzZSAicHJvcHJpZXRhcnkiIGFzIGxpY2Vuc2UuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uX2VuY29kZSgkbGljZW5zZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnYXV0aG9ycycpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydhdXRob3JzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJ2F1dGhvcnMnXSBhcyAka2V5ID0+ICRhdXRob3IpIHsKICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJGF1dGhvcikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnYXV0aG9ycy4nLiRrZXkuJyA6IHNob3VsZCBiZSBhbiBhcnJheSwgJy5nZXR0eXBlKCRhdXRob3IpLicgZ2l2ZW4nOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2F1dGhvcnMnXVska2V5XSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheSgnaG9tZXBhZ2UnLCAnZW1haWwnLCAnbmFtZScsICdyb2xlJykgYXMgJGF1dGhvckRhdGEpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGF1dGhvclskYXV0aG9yRGF0YV0pICYmICFpc19zdHJpbmcoJGF1dGhvclskYXV0aG9yRGF0YV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdhdXRob3JzLicuJGtleS4nLicuJGF1dGhvckRhdGEuJyA6IGludmFsaWQgdmFsdWUsIG11c3QgYmUgYSBzdHJpbmcnOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydhdXRob3JzJ11bJGtleV1bJGF1dGhvckRhdGFdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGF1dGhvclsnaG9tZXBhZ2UnXSkgJiYgISR0aGlzLT5maWx0ZXJVcmwoJGF1dGhvclsnaG9tZXBhZ2UnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdhdXRob3JzLicuJGtleS4nLmhvbWVwYWdlIDogaW52YWxpZCB2YWx1ZSAoJy4kYXV0aG9yWydob21lcGFnZSddLicpLCBtdXN0IGJlIGFuIGh0dHAvaHR0cHMgVVJMJzsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydhdXRob3JzJ11bJGtleV1bJ2hvbWVwYWdlJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhdXRob3JbJ2VtYWlsJ10pICYmICFmaWx0ZXJfdmFyKCRhdXRob3JbJ2VtYWlsJ10sIEZJTFRFUl9WQUxJREFURV9FTUFJTCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdhdXRob3JzLicuJGtleS4nLmVtYWlsIDogaW52YWxpZCB2YWx1ZSAoJy4kYXV0aG9yWydlbWFpbCddLicpLCBtdXN0IGJlIGEgdmFsaWQgZW1haWwgYWRkcmVzcyc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddWyRrZXldWydlbWFpbCddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkdGhpcy0+Y29uZmlnWydhdXRob3JzJ11bJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddWyRrZXldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddKSkgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT52YWxpZGF0ZUFycmF5KCdzdXBwb3J0JykgJiYgIWVtcHR5KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ2lzc3VlcycsICdmb3J1bScsICd3aWtpJywgJ3NvdXJjZScsICdlbWFpbCcsICdpcmMnLCAnZG9jcycsICdyc3MnLCAnY2hhdCcpIGFzICRrZXkpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJGtleV0pICYmICFpc19zdHJpbmcoJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdzdXBwb3J0LicuJGtleS4nIDogaW52YWxpZCB2YWx1ZSwgbXVzdCBiZSBhIHN0cmluZyc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWyRrZXldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVsnZW1haWwnXSkgJiYgIWZpbHRlcl92YXIoJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWydlbWFpbCddLCBGSUxURVJfVkFMSURBVEVfRU1BSUwpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdzdXBwb3J0LmVtYWlsIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJ2VtYWlsJ10uJyksIG11c3QgYmUgYSB2YWxpZCBlbWFpbCBhZGRyZXNzJzsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVsnZW1haWwnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJ2lyYyddKSAmJiAhJHRoaXMtPmZpbHRlclVybCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJ2lyYyddLCBhcnJheSgnaXJjJywgJ2lyY3MnKSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJ3N1cHBvcnQuaXJjIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJ2lyYyddLicpLCBtdXN0IGJlIGEgaXJjOi8vPHNlcnZlcj4vPGNoYW5uZWw+IG9yIGlyY3M6Ly8gVVJMJzsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVsnaXJjJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoIChhcnJheSgnaXNzdWVzJywgJ2ZvcnVtJywgJ3dpa2knLCAnc291cmNlJywgJ2RvY3MnLCAnY2hhdCcpIGFzICRrZXkpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJGtleV0pICYmICEkdGhpcy0+ZmlsdGVyVXJsKCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdzdXBwb3J0LicuJGtleS4nIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJGtleV0uJyksIG11c3QgYmUgYW4gaHR0cC9odHRwcyBVUkwnOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnZnVuZGluZycpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydmdW5kaW5nJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXSBhcyAka2V5ID0+ICRmdW5kaW5nT3B0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRmdW5kaW5nT3B0aW9uKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdmdW5kaW5nLicuJGtleS4nIDogc2hvdWxkIGJlIGFuIGFycmF5LCAnLmdldHR5cGUoJGZ1bmRpbmdPcHRpb24pLicgZ2l2ZW4nOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXVska2V5XSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheSgndHlwZScsICd1cmwnKSBhcyAkZnVuZGluZ0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGZ1bmRpbmdPcHRpb25bJGZ1bmRpbmdEYXRhXSkgJiYgIWlzX3N0cmluZygkZnVuZGluZ09wdGlvblskZnVuZGluZ0RhdGFdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnZnVuZGluZy4nLiRrZXkuJy4nLiRmdW5kaW5nRGF0YS4nIDogaW52YWxpZCB2YWx1ZSwgbXVzdCBiZSBhIHN0cmluZyc7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXVska2V5XVskZnVuZGluZ0RhdGFdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGZ1bmRpbmdPcHRpb25bJ3VybCddKSAmJiAhJHRoaXMtPmZpbHRlclVybCgkZnVuZGluZ09wdGlvblsndXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnZnVuZGluZy4nLiRrZXkuJy51cmwgOiBpbnZhbGlkIHZhbHVlICgnLiRmdW5kaW5nT3B0aW9uWyd1cmwnXS4nKSwgbXVzdCBiZSBhbiBodHRwL2h0dHBzIFVSTCc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snZnVuZGluZyddWyRrZXldWyd1cmwnXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNvbmZpZ1snZnVuZGluZyddWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR1bmJvdW5kQ29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9JywgJzEwMDAwMDAwLWRldicpOwogICAgICAgICRzdGFibGVDb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz0nLCAnMS4wLjAnKTsKCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlcykgYXMgJGxpbmtUeXBlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgkbGlua1R5cGUpICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJGxpbmtUeXBlXSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJGxpbmtUeXBlXSBhcyAkcGFja2FnZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSBzdHJjYXNlY21wKCRwYWNrYWdlLCAkdGhpcy0+Y29uZmlnWyduYW1lJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRsaW5rVHlwZS4nLicuJHBhY2thZ2UuJyA6IGEgcGFja2FnZSBjYW5ub3Qgc2V0IGEgJy4kbGlua1R5cGUuJyBvbiBpdHNlbGYnOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRsaW5rVHlwZV1bJHBhY2thZ2VdKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkZXJyID0gc2VsZjo6aGFzUGFja2FnZU5hbWluZ0Vycm9yKCRwYWNrYWdlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkbGlua1R5cGUuJy4nLiRlcnI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCFQcmVnOjppc01hdGNoKCd7XltBLVphLXowLTlfLi8tXSskfScsICRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICRsaW5rVHlwZS4nLicuJHBhY2thZ2UuJyA6IGludmFsaWQga2V5LCBwYWNrYWdlIG5hbWVzIG11c3QgYmUgc3RyaW5ncyBjb250YWluaW5nIG9ubHkgW0EtWmEtejAtOV8uLy1dJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19zdHJpbmcoJGNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRsaW5rVHlwZS4nLicuJHBhY2thZ2UuJyA6IGludmFsaWQgdmFsdWUsIG11c3QgYmUgYSBzdHJpbmcgY29udGFpbmluZyBhIHZlcnNpb24gY29uc3RyYWludCc7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJGxpbmtUeXBlXVskcGFja2FnZV0pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgnc2VsZi52ZXJzaW9uJyAhPT0gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaW5rQ29uc3RyYWludCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJGxpbmtUeXBlLicuJy4kcGFja2FnZS4nIDogaW52YWxpZCB2ZXJzaW9uIGNvbnN0cmFpbnQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKSc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRsaW5rVHlwZV1bJHBhY2thZ2VdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayByZXF1aXJlcyBmb3IgdW5ib3VuZCBjb25zdHJhaW50cyBvbiBub24tcGxhdGZvcm0gcGFja2FnZXMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKCR0aGlzLT5mbGFncyAmIHNlbGY6OkNIRUNLX1VOQk9VTkRfQ09OU1RSQUlOVFMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAncmVxdWlyZScgPT09ICRsaW5rVHlwZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgJGxpbmtDb25zdHJhaW50LT5tYXRjaGVzKCR1bmJvdW5kQ29uc3RyYWludCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICFQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRwYWNrYWdlKQogICAgICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJGxpbmtUeXBlLicuJy4kcGFja2FnZS4nIDogdW5ib3VuZCB2ZXJzaW9uIGNvbnN0cmFpbnRzICgnLiRjb25zdHJhaW50LicpIHNob3VsZCBiZSBhdm9pZGVkJzsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgcmVxdWlyZXMgZm9yIGV4YWN0IGNvbnN0cmFpbnRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJHRoaXMtPmZsYWdzICYgc2VsZjo6Q0hFQ0tfU1RSSUNUX0NPTlNUUkFJTlRTKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgJ3JlcXVpcmUnID09PSAkbGlua1R5cGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHN0cnBvcygkbGlua0NvbnN0cmFpbnQsICc9JykgPT09IDAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICRzdGFibGVDb25zdHJhaW50LT52ZXJzaW9uQ29tcGFyZSgkc3RhYmxlQ29uc3RyYWludCwgJGxpbmtDb25zdHJhaW50LCAnPD0nKQogICAgICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJGxpbmtUeXBlLicuJy4kcGFja2FnZS4nIDogZXhhY3QgdmVyc2lvbiBjb25zdHJhaW50cyAoJy4kY29uc3RyYWludC4nKSBzaG91bGQgYmUgYXZvaWRlZCBpZiB0aGUgcGFja2FnZSBmb2xsb3dzIHNlbWFudGljIHZlcnNpb25pbmcnOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmtUeXBlID09PSAnY29uZmxpY3QnICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJ3JlcGxhY2UnXSkgJiYgJGtleXMgPSBhcnJheV9pbnRlcnNlY3Rfa2V5KCR0aGlzLT5jb25maWdbJ3JlcGxhY2UnXSwgJHRoaXMtPmNvbmZpZ1snY29uZmxpY3QnXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJGxpbmtUeXBlLicuJy4kcGFja2FnZS4nIDogeW91IGNhbm5vdCBjb25mbGljdCB3aXRoIGEgcGFja2FnZSB0aGF0IGlzIGFsc28gcmVwbGFjZWQsIGFzIHJlcGxhY2UgYWxyZWFkeSBjcmVhdGVzIGFuIGltcGxpY2l0IGNvbmZsaWN0IHJ1bGUnOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRsaW5rVHlwZV1bJHBhY2thZ2VdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnc3VnZ2VzdCcpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydzdWdnZXN0J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJ3N1Z2dlc3QnXSBhcyAkcGFja2FnZSA9PiAkZGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCRkZXNjcmlwdGlvbikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnc3VnZ2VzdC4nLiRwYWNrYWdlLicgOiBpbnZhbGlkIHZhbHVlLCBtdXN0IGJlIGEgc3RyaW5nIGRlc2NyaWJpbmcgd2h5IHRoZSBwYWNrYWdlIGlzIHN1Z2dlc3RlZCc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snc3VnZ2VzdCddWyRwYWNrYWdlXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ21pbmltdW0tc3RhYmlsaXR5JykgJiYgIWVtcHR5KCR0aGlzLT5jb25maWdbJ21pbmltdW0tc3RhYmlsaXR5J10pKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1tzdHJ0b2xvd2VyKCR0aGlzLT5jb25maWdbJ21pbmltdW0tc3RhYmlsaXR5J10pXSkgJiYgJHRoaXMtPmNvbmZpZ1snbWluaW11bS1zdGFiaWxpdHknXSAhPT0gJ1JDJykgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJ21pbmltdW0tc3RhYmlsaXR5IDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWydtaW5pbXVtLXN0YWJpbGl0eSddLicpLCBtdXN0IGJlIG9uZSBvZiAnLmltcGxvZGUoJywgJywgYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzKSk7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydtaW5pbXVtLXN0YWJpbGl0eSddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT52YWxpZGF0ZUFycmF5KCdhdXRvbG9hZCcpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydhdXRvbG9hZCddKSkgewogICAgICAgICAgICAkdHlwZXMgPSBhcnJheSgncHNyLTAnLCAncHNyLTQnLCAnY2xhc3NtYXAnLCAnZmlsZXMnLCAnZXhjbHVkZS1mcm9tLWNsYXNzbWFwJyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJ2F1dG9sb2FkJ10gYXMgJHR5cGUgPT4gJHR5cGVDb25maWcpIHsKICAgICAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHR5cGUsICR0eXBlcykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnYXV0b2xvYWQgOiBpbnZhbGlkIHZhbHVlICgnLiR0eXBlLicpLCBtdXN0IGJlIG9uZSBvZiAnLmltcGxvZGUoJywgJywgJHR5cGVzKTsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydhdXRvbG9hZCddWyR0eXBlXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdwc3ItNCcpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdHlwZUNvbmZpZyBhcyAkbmFtZXNwYWNlID0+ICRkaXJzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbmFtZXNwYWNlICE9PSAnJyAmJiAnXFwnICE9PSBzdWJzdHIoJG5hbWVzcGFjZSwgLTEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnYXV0b2xvYWQucHNyLTQgOiBpbnZhbGlkIHZhbHVlICgnLiRuYW1lc3BhY2UuJyksIG5hbWVzcGFjZXMgbXVzdCBlbmQgd2l0aCBhIG5hbWVzcGFjZSBzZXBhcmF0b3IsIHNob3VsZCBiZSAnLiRuYW1lc3BhY2UuJ1xcXFwnOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5jb25maWdbJ2F1dG9sb2FkJ11bJ3Bzci00J10pICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWyd0YXJnZXQtZGlyJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICd0YXJnZXQtZGlyIDogdGhpcyBjYW4gbm90IGJlIHVzZWQgdG9nZXRoZXIgd2l0aCB0aGUgYXV0b2xvYWQucHNyLTQgc2V0dGluZywgcmVtb3ZlIHRhcmdldC1kaXIgdG8gdXBncmFkZSB0byBwc3ItNCc7CiAgICAgICAgICAgIC8vIFVuc2V0IHRoZSBwc3ItNCBzZXR0aW5nLCBzaW5jZSB1bnNldHRpbmcgdGFyZ2V0LWRpciBtaWdodAogICAgICAgICAgICAvLyBpbnRlcmZlcmUgd2l0aCBvdGhlciBzZXR0aW5ncy4KICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0b2xvYWQnXVsncHNyLTQnXSk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoIChhcnJheSgnc291cmNlJywgJ2Rpc3QnKSBhcyAkc3JjVHlwZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPnZhbGlkYXRlQXJyYXkoJHNyY1R5cGUpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWyRzcmNUeXBlXSkpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbmZpZ1skc3JjVHlwZV1bJ3R5cGUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkc3JjVHlwZSAuICcudHlwZSA6IG11c3QgYmUgcHJlc2VudCc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5jb25maWdbJHNyY1R5cGVdWyd1cmwnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkc3JjVHlwZSAuICcudXJsIDogbXVzdCBiZSBwcmVzZW50JzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkc3JjVHlwZSA9PT0gJ3NvdXJjZScgJiYgIWlzc2V0KCR0aGlzLT5jb25maWdbJHNyY1R5cGVdWydyZWZlcmVuY2UnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkc3JjVHlwZSAuICcucmVmZXJlbmNlIDogbXVzdCBiZSBwcmVzZW50JzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCR0aGlzLT5jb25maWdbJHNyY1R5cGVdWyd0eXBlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJHNyY1R5cGUgLiAnLnR5cGUgOiBzaG91bGQgYmUgYSBzdHJpbmcsICcuZ2V0dHlwZSgkdGhpcy0+Y29uZmlnWyRzcmNUeXBlXVsndHlwZSddKS4nIGdpdmVuJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCR0aGlzLT5jb25maWdbJHNyY1R5cGVdWyd1cmwnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkc3JjVHlwZSAuICcudXJsIDogc2hvdWxkIGJlIGEgc3RyaW5nLCAnLmdldHR5cGUoJHRoaXMtPmNvbmZpZ1skc3JjVHlwZV1bJ3VybCddKS4nIGdpdmVuJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWyRzcmNUeXBlXVsncmVmZXJlbmNlJ10pICYmICFpc19zdHJpbmcoJHRoaXMtPmNvbmZpZ1skc3JjVHlwZV1bJ3JlZmVyZW5jZSddKSAmJiAhaXNfaW50KCR0aGlzLT5jb25maWdbJHNyY1R5cGVdWydyZWZlcmVuY2UnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkc3JjVHlwZSAuICcucmVmZXJlbmNlIDogc2hvdWxkIGJlIGEgc3RyaW5nIG9yIGludCwgJy5nZXR0eXBlKCR0aGlzLT5jb25maWdbJHNyY1R5cGVdWydyZWZlcmVuY2UnXSkuJyBnaXZlbic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1skc3JjVHlwZV1bJ3JlZmVyZW5jZSddKSAmJiBQcmVnOjppc01hdGNoKCd7XlxzKi19JywgKHN0cmluZykgJHRoaXMtPmNvbmZpZ1skc3JjVHlwZV1bJ3JlZmVyZW5jZSddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRzcmNUeXBlIC4gJy5yZWZlcmVuY2UgOiBtdXN0IG5vdCBzdGFydCB3aXRoIGEgIi0iLCAiJy4kdGhpcy0+Y29uZmlnWyRzcmNUeXBlXVsncmVmZXJlbmNlJ10uJyIgZ2l2ZW4nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3teXHMqLX0nLCAkdGhpcy0+Y29uZmlnWyRzcmNUeXBlXVsndXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJHNyY1R5cGUgLiAnLnVybCA6IG11c3Qgbm90IHN0YXJ0IHdpdGggYSAiLSIsICInLiR0aGlzLT5jb25maWdbJHNyY1R5cGVdWyd1cmwnXS4nIiBnaXZlbic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFRPRE8gdmFsaWRhdGUgcmVwb3NpdG9yaWVzCiAgICAgICAgLy8gVE9ETyB2YWxpZGF0ZSBwYWNrYWdlIHJlcG9zaXRvcmllcycgcGFja2FnZXMgdXNpbmcgdGhpcyByZWN1cnNpdmVseQoKICAgICAgICAkdGhpcy0+dmFsaWRhdGVGbGF0QXJyYXkoJ2luY2x1ZGUtcGF0aCcpOwogICAgICAgICR0aGlzLT52YWxpZGF0ZUFycmF5KCd0cmFuc3BvcnQtb3B0aW9ucycpOwoKICAgICAgICAvLyBicmFuY2ggYWxpYXMgdmFsaWRhdGlvbgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXSkpIHsKICAgICAgICAgICAgaWYgKCFpc19hcnJheSgkdGhpcy0+Y29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdleHRyYS5icmFuY2gtYWxpYXMgOiBtdXN0IGJlIGFuIGFycmF5IG9mIHZlcnNpb25zID0+IGFsaWFzZXMnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ10gYXMgJHNvdXJjZUJyYW5jaCA9PiAkdGFyZ2V0QnJhbmNoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19zdHJpbmcoJHRhcmdldEJyYW5jaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnZXh0cmEuYnJhbmNoLWFsaWFzLicuJHNvdXJjZUJyYW5jaC4nIDogdGhlIHRhcmdldCBicmFuY2ggKCcuanNvbl9lbmNvZGUoJHRhcmdldEJyYW5jaCkuJykgbXVzdCBiZSBhIHN0cmluZywgIicuZ2V0dHlwZSgkdGFyZ2V0QnJhbmNoKS4nIiByZWNlaXZlZC4nOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXVskc291cmNlQnJhbmNoXSk7CgogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGVuc3VyZSBpdCBpcyBhbiBhbGlhcyB0byBhIC1kZXYgcGFja2FnZQogICAgICAgICAgICAgICAgICAgIGlmICgnLWRldicgIT09IHN1YnN0cigkdGFyZ2V0QnJhbmNoLCAtNCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnZXh0cmEuYnJhbmNoLWFsaWFzLicuJHNvdXJjZUJyYW5jaC4nIDogdGhlIHRhcmdldCBicmFuY2ggKCcuJHRhcmdldEJyYW5jaC4nKSBtdXN0IGVuZCBpbiAtZGV2JzsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ11bJHNvdXJjZUJyYW5jaF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBub3JtYWxpemUgd2l0aG91dCAtZGV2IGFuZCBlbnN1cmUgaXQncyBhIG51bWVyaWMgYnJhbmNoIHRoYXQgaXMgcGFyc2VhYmxlCiAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRlZFRhcmdldEJyYW5jaCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemVCcmFuY2goc3Vic3RyKCR0YXJnZXRCcmFuY2gsIDAsIC00KSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCctZGV2JyAhPT0gc3Vic3RyKCR2YWxpZGF0ZWRUYXJnZXRCcmFuY2gsIC00KSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdleHRyYS5icmFuY2gtYWxpYXMuJy4kc291cmNlQnJhbmNoLicgOiB0aGUgdGFyZ2V0IGJyYW5jaCAoJy4kdGFyZ2V0QnJhbmNoLicpIG11c3QgYmUgYSBwYXJzZWFibGUgbnVtYmVyIGxpa2UgMi4wLWRldic7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddWyRzb3VyY2VCcmFuY2hdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdXNpbmcgbnVtZXJpYyBhbGlhc2VzIGVuc3VyZSB0aGUgYWxpYXMgaXMgYSB2YWxpZCBzdWJ2ZXJzaW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKCgkc291cmNlUHJlZml4ID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPnBhcnNlTnVtZXJpY0FsaWFzUHJlZml4KCRzb3VyY2VCcmFuY2gpKQogICAgICAgICAgICAgICAgICAgICAgICAmJiAoJHRhcmdldFByZWZpeCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZU51bWVyaWNBbGlhc1ByZWZpeCgkdGFyZ2V0QnJhbmNoKSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHN0cmlwb3MoJHRhcmdldFByZWZpeCwgJHNvdXJjZVByZWZpeCkgIT09IDApCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJ2V4dHJhLmJyYW5jaC1hbGlhcy4nLiRzb3VyY2VCcmFuY2guJyA6IHRoZSB0YXJnZXQgYnJhbmNoICgnLiR0YXJnZXRCcmFuY2guJykgaXMgbm90IGEgdmFsaWQgbnVtZXJpYyBhbGlhcyBmb3IgdGhpcyB2ZXJzaW9uJzsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ11bJHNvdXJjZUJyYW5jaF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5lcnJvcnMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYWNrYWdlRXhjZXB0aW9uKCR0aGlzLT5lcnJvcnMsICR0aGlzLT53YXJuaW5ncywgJGNvbmZpZyk7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5sb2FkZXItPmxvYWQoJHRoaXMtPmNvbmZpZywgJGNsYXNzKTsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gYXJyYXkoKTsKCiAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0V2FybmluZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+d2FybmluZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFcnJvcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3JzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAkaXNMaW5rCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGhhc1BhY2thZ2VOYW1pbmdFcnJvcigkbmFtZSwgJGlzTGluayA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgne15bYS16MC05XSg/OltfLi1dP1thLXowLTldKykqL1thLXowLTldKD86KD86W18uXT98LXswLDJ9KVthLXowLTldKykqJH1pRCcsICRuYW1lKSkgewogICAgICAgICAgICByZXR1cm4gJG5hbWUuJyBpcyBpbnZhbGlkLCBpdCBzaG91bGQgaGF2ZSBhIHZlbmRvciBuYW1lLCBhIGZvcndhcmQgc2xhc2gsIGFuZCBhIHBhY2thZ2UgbmFtZS4gVGhlIHZlbmRvciBhbmQgcGFja2FnZSBuYW1lIGNhbiBiZSB3b3JkcyBzZXBhcmF0ZWQgYnkgLSwgLiBvciBfLiBUaGUgY29tcGxldGUgbmFtZSBzaG91bGQgbWF0Y2ggIl5bYS16MC05XShbXy4tXT9bYS16MC05XSspKi9bYS16MC05XSgoW18uXT98LXswLDJ9KVthLXowLTldKykqJCIuJzsKICAgICAgICB9CgogICAgICAgICRyZXNlcnZlZE5hbWVzID0gYXJyYXkoJ251bCcsICdjb24nLCAncHJuJywgJ2F1eCcsICdjb20xJywgJ2NvbTInLCAnY29tMycsICdjb200JywgJ2NvbTUnLCAnY29tNicsICdjb203JywgJ2NvbTgnLCAnY29tOScsICdscHQxJywgJ2xwdDInLCAnbHB0MycsICdscHQ0JywgJ2xwdDUnLCAnbHB0NicsICdscHQ3JywgJ2xwdDgnLCAnbHB0OScpOwogICAgICAgICRiaXRzID0gZXhwbG9kZSgnLycsIHN0cnRvbG93ZXIoJG5hbWUpKTsKICAgICAgICBpZiAoaW5fYXJyYXkoJGJpdHNbMF0sICRyZXNlcnZlZE5hbWVzLCB0cnVlKSB8fCBpbl9hcnJheSgkYml0c1sxXSwgJHJlc2VydmVkTmFtZXMsIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkbmFtZS4nIGlzIHJlc2VydmVkLCBwYWNrYWdlIGFuZCB2ZW5kb3IgbmFtZXMgY2FuIG5vdCBtYXRjaCBhbnkgb2Y6ICcuaW1wbG9kZSgnLCAnLCAkcmVzZXJ2ZWROYW1lcykuJy4nOwogICAgICAgIH0KCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3tcLmpzb24kfScsICRuYW1lKSkgewogICAgICAgICAgICByZXR1cm4gJG5hbWUuJyBpcyBpbnZhbGlkLCBwYWNrYWdlIG5hbWVzIGNhbiBub3QgZW5kIGluIC5qc29uLCBjb25zaWRlciByZW5hbWluZyBpdCBvciBwZXJoYXBzIHVzaW5nIGEgLWpzb24gc3VmZml4IGluc3RlYWQuJzsKICAgICAgICB9CgogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7W0EtWl19JywgJG5hbWUpKSB7CiAgICAgICAgICAgIGlmICgkaXNMaW5rKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG5hbWUuJyBpcyBpbnZhbGlkLCBpdCBzaG91bGQgbm90IGNvbnRhaW4gdXBwZXJjYXNlIGNoYXJhY3RlcnMuIFBsZWFzZSB1c2UgJy5zdHJ0b2xvd2VyKCRuYW1lKS4nIGluc3RlYWQuJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHN1Z2dlc3ROYW1lID0gUHJlZzo6cmVwbGFjZSgneyg/OihbYS16XSkoW0EtWl0pfChbQS1aXSkoW0EtWl1bYS16XSkpfScsICdcXDFcXDMtXFwyXFw0JywgJG5hbWUpOwogICAgICAgICAgICAkc3VnZ2VzdE5hbWUgPSBzdHJ0b2xvd2VyKCRzdWdnZXN0TmFtZSk7CgogICAgICAgICAgICByZXR1cm4gJG5hbWUuJyBpcyBpbnZhbGlkLCBpdCBzaG91bGQgbm90IGNvbnRhaW4gdXBwZXJjYXNlIGNoYXJhY3RlcnMuIFdlIHN1Z2dlc3QgdXNpbmcgJy4kc3VnZ2VzdE5hbWUuJyBpbnN0ZWFkLic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByb3BlcnR5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWdleAogICAgICogQHBhcmFtIGJvb2wgICAkbWFuZGF0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkcHJvcGVydHkKICAgICAqIEBwaHBzdGFuLXBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgJHJlZ2V4CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVSZWdleCgkcHJvcGVydHksICRyZWdleCwgJG1hbmRhdG9yeSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlU3RyaW5nKCRwcm9wZXJ0eSwgJG1hbmRhdG9yeSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCd7XicuJHJlZ2V4LickfXUnLCAkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJHByb3BlcnR5LicgOiBpbnZhbGlkIHZhbHVlICgnLiR0aGlzLT5jb25maWdbJHByb3BlcnR5XS4nKSwgbXVzdCBtYXRjaCAnLiRyZWdleDsKICAgICAgICAgICAgaWYgKCRtYW5kYXRvcnkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRtZXNzYWdlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAkbWVzc2FnZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcm9wZXJ0eQogICAgICogQHBhcmFtIGJvb2wgICAkbWFuZGF0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkcHJvcGVydHkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZVN0cmluZygkcHJvcGVydHksICRtYW5kYXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSAmJiAhaXNfc3RyaW5nKCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJHByb3BlcnR5LicgOiBzaG91bGQgYmUgYSBzdHJpbmcsICcuZ2V0dHlwZSgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pLicgZ2l2ZW4nOwogICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pIHx8IHRyaW0oJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSA9PT0gJycpIHsKICAgICAgICAgICAgaWYgKCRtYW5kYXRvcnkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRwcm9wZXJ0eS4nIDogbXVzdCBiZSBwcmVzZW50JzsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcm9wZXJ0eQogICAgICogQHBhcmFtIGJvb2wgICAkbWFuZGF0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkcHJvcGVydHkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZUFycmF5KCRwcm9wZXJ0eSwgJG1hbmRhdG9yeSA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pICYmICFpc19hcnJheSgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRwcm9wZXJ0eS4nIDogc2hvdWxkIGJlIGFuIGFycmF5LCAnLmdldHR5cGUoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKS4nIGdpdmVuJzsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSB8fCAhY291bnQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSkgewogICAgICAgICAgICBpZiAoJG1hbmRhdG9yeSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJHByb3BlcnR5LicgOiBtdXN0IGJlIHByZXNlbnQgYW5kIGNvbnRhaW4gYXQgbGVhc3Qgb25lIGVsZW1lbnQnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkcHJvcGVydHkKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcmVnZXgKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkbWFuZGF0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAgICAgICRwcm9wZXJ0eQogICAgICogQHBocHN0YW4tcGFyYW0gbm9uLWVtcHR5LXN0cmluZ3xudWxsICRyZWdleAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlRmxhdEFycmF5KCRwcm9wZXJ0eSwgJHJlZ2V4ID0gbnVsbCwgJG1hbmRhdG9yeSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlQXJyYXkoJHByb3BlcnR5LCAkbWFuZGF0b3J5KSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcGFzcyA9IHRydWU7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCR2YWx1ZSkgJiYgIWlzX251bWVyaWMoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJHByb3BlcnR5LicuJy4ka2V5LicgOiBtdXN0IGJlIGEgc3RyaW5nIG9yIGludCwgJy5nZXR0eXBlKCR2YWx1ZSkuJyBnaXZlbic7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV1bJGtleV0pOwogICAgICAgICAgICAgICAgJHBhc3MgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRyZWdleCAmJiAhUHJlZzo6aXNNYXRjaCgne14nLiRyZWdleC4nJH11JywgJHZhbHVlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAkcHJvcGVydHkuJy4nLiRrZXkuJyA6IGludmFsaWQgdmFsdWUgKCcuJHZhbHVlLicpLCBtdXN0IG1hdGNoICcuJHJlZ2V4OwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldWyRrZXldKTsKICAgICAgICAgICAgICAgICRwYXNzID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFzczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByb3BlcnR5CiAgICAgKiBAcGFyYW0gYm9vbCAkbWFuZGF0b3J5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkcHJvcGVydHkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZVVybCgkcHJvcGVydHksICRtYW5kYXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZVN0cmluZygkcHJvcGVydHksICRtYW5kYXRvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmZpbHRlclVybCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pKSB7CiAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJHByb3BlcnR5LicgOiBpbnZhbGlkIHZhbHVlICgnLiR0aGlzLT5jb25maWdbJHByb3BlcnR5XS4nKSwgbXVzdCBiZSBhbiBodHRwL2h0dHBzIFVSTCc7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBtaXhlZCAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkc2NoZW1lcwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbHRlclVybCgkdmFsdWUsIGFycmF5ICRzY2hlbWVzID0gYXJyYXkoJ2h0dHAnLCAnaHR0cHMnKSkKICAgIHsKICAgICAgICBpZiAoJHZhbHVlID09PSAnJykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRiaXRzID0gcGFyc2VfdXJsKCR2YWx1ZSk7CiAgICAgICAgaWYgKGVtcHR5KCRiaXRzWydzY2hlbWUnXSkgfHwgZW1wdHkoJGJpdHNbJ2hvc3QnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpbl9hcnJheSgkYml0c1snc2NoZW1lJ10sICRzY2hlbWVzLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZUFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290QWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNoaXYgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQXJyYXlMb2FkZXIgaW1wbGVtZW50cyBMb2FkZXJJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgVmVyc2lvblBhcnNlciAqLwogICAgcHJvdGVjdGVkICR2ZXJzaW9uUGFyc2VyOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRsb2FkT3B0aW9uczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRsb2FkT3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoVmVyc2lvblBhcnNlciAkcGFyc2VyID0gbnVsbCwgJGxvYWRPcHRpb25zID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcGFyc2VyKSB7CiAgICAgICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSAkcGFyc2VyOwogICAgICAgICR0aGlzLT5sb2FkT3B0aW9ucyA9ICRsb2FkT3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKGFycmF5ICRjb25maWcsICRjbGFzcyA9ICdDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZScpCiAgICB7CiAgICAgICAgaWYgKCRjbGFzcyAhPT0gJ0NvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlJyAmJiAkY2xhc3MgIT09ICdDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlJykgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdUaGUgJGNsYXNzIGFyZyBpcyBkZXByZWNhdGVkLCBwbGVhc2UgcmVhY2ggb3V0IHRvIENvbXBvc2VyIG1haW50YWluZXJzIEFTQVAgaWYgeW91IHN0aWxsIG5lZWQgdGhpcy4nLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5jcmVhdGVPYmplY3QoJGNvbmZpZywgJGNsYXNzKTsKCiAgICAgICAgZm9yZWFjaCAoQmFzZVBhY2thZ2U6OiRzdXBwb3J0ZWRMaW5rVHlwZXMgYXMgJHR5cGUgPT4gJG9wdHMpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJHR5cGVdKSkgewogICAgICAgICAgICAgICAgJG1ldGhvZCA9ICdzZXQnLnVjZmlyc3QoJG9wdHNbJ21ldGhvZCddKTsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT57JG1ldGhvZH0oCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlTGlua3MoCiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXROYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAgICAgICAgICRvcHRzWydtZXRob2QnXSwKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1skdHlwZV0KICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5jb25maWd1cmVPYmplY3QoJHBhY2thZ2UsICRjb25maWcpOwoKICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbGlzdDxhcnJheTxtaXhlZD4+ICR2ZXJzaW9ucwogICAgICoKICAgICAqIEByZXR1cm4gbGlzdDxDb21wbGV0ZVBhY2thZ2V8Q29tcGxldGVBbGlhc1BhY2thZ2U+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkUGFja2FnZXMoYXJyYXkgJHZlcnNpb25zKQogICAgewogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJGxpbmtDYWNoZSA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9ucyBhcyAkdmVyc2lvbikgewogICAgICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5jcmVhdGVPYmplY3QoJHZlcnNpb24sICdDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZScpOwoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ3VyZUNhY2hlZExpbmtzKCRsaW5rQ2FjaGUsICRwYWNrYWdlLCAkdmVyc2lvbik7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmNvbmZpZ3VyZU9iamVjdCgkcGFja2FnZSwgJHZlcnNpb24pOwoKICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGVtcGxhdGUgUGFja2FnZUNsYXNzIG9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb25maWcgcGFja2FnZSBkYXRhCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkY2xhc3MgIEZRQ04gdG8gYmUgaW5zdGFudGlhdGVkCiAgICAgKgogICAgICogQHJldHVybiBDb21wbGV0ZVBhY2thZ2V8Um9vdFBhY2thZ2UKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBjbGFzcy1zdHJpbmc8UGFja2FnZUNsYXNzPiAkY2xhc3MKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVPYmplY3QoYXJyYXkgJGNvbmZpZywgJGNsYXNzKQogICAgewogICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1snbmFtZSddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignVW5rbm93biBwYWNrYWdlIGhhcyBubyBuYW1lIGRlZmluZWQgKCcuanNvbl9lbmNvZGUoJGNvbmZpZykuJykuJyk7CiAgICAgICAgfQogICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1sndmVyc2lvbiddKSB8fCAhaXNfc2NhbGFyKCRjb25maWdbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1BhY2thZ2UgJy4kY29uZmlnWyduYW1lJ10uJyBoYXMgbm8gdmVyc2lvbiBkZWZpbmVkLicpOwogICAgICAgIH0KICAgICAgICBpZiAoIWlzX3N0cmluZygkY29uZmlnWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICRjb25maWdbJ3ZlcnNpb24nXSA9IChzdHJpbmcpICRjb25maWdbJ3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBhbHJlYWR5IG5vcm1hbGl6ZWQgdmVyc2lvbnMKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1sndmVyc2lvbl9ub3JtYWxpemVkJ10pICYmIGlzX3N0cmluZygkY29uZmlnWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSkpIHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkY29uZmlnWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXTsKCiAgICAgICAgICAgIC8vIGhhbmRsaW5nIG9mIGV4aXN0aW5nIHJlcG9zIHdoaWNoIG5lZWQgdG8gcmVtYWluIGNvbXBvc2VyIHYxIGNvbXBhdGlibGUsIGluIGNhc2UgdGhlIHZlcnNpb25fbm9ybWFsaXplZCBjb250YWluZWQgVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVMsIHdlIHJlbm9ybWFsaXplIGl0CiAgICAgICAgICAgIGlmICgkdmVyc2lvbiA9PT0gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVMpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkY29uZmlnWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRjb25maWdbJ3ZlcnNpb24nXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3ICRjbGFzcygkY29uZmlnWyduYW1lJ10sICR2ZXJzaW9uLCAkY29uZmlnWyd2ZXJzaW9uJ10pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIENvbXBsZXRlUGFja2FnZSAkcGFja2FnZQogICAgICogQHBhcmFtIG1peGVkW10gICAgICAgICAkY29uZmlnIHBhY2thZ2UgZGF0YQogICAgICoKICAgICAqIEByZXR1cm4gUm9vdFBhY2thZ2V8Um9vdEFsaWFzUGFja2FnZXxDb21wbGV0ZVBhY2thZ2V8Q29tcGxldGVBbGlhc1BhY2thZ2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjb25maWd1cmVPYmplY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgYXJyYXkgJGNvbmZpZykKICAgIHsKICAgICAgICBpZiAoISRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0FycmF5TG9hZGVyIGV4cGVjdHMgaW5zdGFuY2VzIG9mIHRoZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZSBjbGFzcyB0byBmdW5jdGlvbiBjb3JyZWN0bHknKTsKICAgICAgICB9CgogICAgICAgICRwYWNrYWdlLT5zZXRUeXBlKGlzc2V0KCRjb25maWdbJ3R5cGUnXSkgPyBzdHJ0b2xvd2VyKCRjb25maWdbJ3R5cGUnXSkgOiAnbGlicmFyeScpOwoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1sndGFyZ2V0LWRpciddKSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0VGFyZ2V0RGlyKCRjb25maWdbJ3RhcmdldC1kaXInXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snZXh0cmEnXSkgJiYgXGlzX2FycmF5KCRjb25maWdbJ2V4dHJhJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRFeHRyYSgkY29uZmlnWydleHRyYSddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydiaW4nXSkpIHsKICAgICAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGNvbmZpZ1snYmluJ10pKSB7CiAgICAgICAgICAgICAgICAkY29uZmlnWydiaW4nXSA9IGFycmF5KCRjb25maWdbJ2JpbiddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkY29uZmlnWydiaW4nXSBhcyAka2V5ID0+ICRiaW4pIHsKICAgICAgICAgICAgICAgICRjb25maWdbJ2JpbiddWyRrZXldID0gbHRyaW0oJGJpbiwgJy8nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZS0+c2V0QmluYXJpZXMoJGNvbmZpZ1snYmluJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2luc3RhbGxhdGlvbi1zb3VyY2UnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldEluc3RhbGxhdGlvblNvdXJjZSgkY29uZmlnWydpbnN0YWxsYXRpb24tc291cmNlJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2RlZmF1bHQtYnJhbmNoJ10pICYmICRjb25maWdbJ2RlZmF1bHQtYnJhbmNoJ10gPT09IHRydWUpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldElzRGVmYXVsdEJyYW5jaCh0cnVlKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydzb3VyY2UnXSkpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkY29uZmlnWydzb3VyY2UnXVsndHlwZSddLCAkY29uZmlnWydzb3VyY2UnXVsndXJsJ10sICRjb25maWdbJ3NvdXJjZSddWydyZWZlcmVuY2UnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgIlBhY2thZ2UgJXMncyBzb3VyY2Uga2V5IHNob3VsZCBiZSBzcGVjaWZpZWQgYXMge1widHlwZVwiOiAuLi4sIFwidXJsXCI6IC4uLiwgXCJyZWZlcmVuY2VcIjogLi4ufSxcbiVzIGdpdmVuLiIsCiAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1snbmFtZSddLAogICAgICAgICAgICAgICAgICAgIGpzb25fZW5jb2RlKCRjb25maWdbJ3NvdXJjZSddKQogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZVR5cGUoJGNvbmZpZ1snc291cmNlJ11bJ3R5cGUnXSk7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRTb3VyY2VVcmwoJGNvbmZpZ1snc291cmNlJ11bJ3VybCddKTsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZVJlZmVyZW5jZShpc3NldCgkY29uZmlnWydzb3VyY2UnXVsncmVmZXJlbmNlJ10pID8gJGNvbmZpZ1snc291cmNlJ11bJ3JlZmVyZW5jZSddIDogbnVsbCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWydzb3VyY2UnXVsnbWlycm9ycyddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZU1pcnJvcnMoJGNvbmZpZ1snc291cmNlJ11bJ21pcnJvcnMnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydkaXN0J10pKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1snZGlzdCddWyd0eXBlJ10sICRjb25maWdbJ2Rpc3QnXVsndXJsJ10pKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICJQYWNrYWdlICVzJ3MgZGlzdCBrZXkgc2hvdWxkIGJlIHNwZWNpZmllZCBhcyAiLgogICAgICAgICAgICAgICAgICAgICJ7XCJ0eXBlXCI6IC4uLiwgXCJ1cmxcIjogLi4uLCBcInJlZmVyZW5jZVwiOiAuLi4sIFwic2hhc3VtXCI6IC4uLn0sXG4lcyBnaXZlbi4iLAogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ25hbWUnXSwKICAgICAgICAgICAgICAgICAgICBqc29uX2VuY29kZSgkY29uZmlnWydkaXN0J10pCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZS0+c2V0RGlzdFR5cGUoJGNvbmZpZ1snZGlzdCddWyd0eXBlJ10pOwogICAgICAgICAgICAkcGFja2FnZS0+c2V0RGlzdFVybCgkY29uZmlnWydkaXN0J11bJ3VybCddKTsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldERpc3RSZWZlcmVuY2UoaXNzZXQoJGNvbmZpZ1snZGlzdCddWydyZWZlcmVuY2UnXSkgPyAkY29uZmlnWydkaXN0J11bJ3JlZmVyZW5jZSddIDogbnVsbCk7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXREaXN0U2hhMUNoZWNrc3VtKGlzc2V0KCRjb25maWdbJ2Rpc3QnXVsnc2hhc3VtJ10pID8gJGNvbmZpZ1snZGlzdCddWydzaGFzdW0nXSA6IG51bGwpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snZGlzdCddWydtaXJyb3JzJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0RGlzdE1pcnJvcnMoJGNvbmZpZ1snZGlzdCddWydtaXJyb3JzJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snc3VnZ2VzdCddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snc3VnZ2VzdCddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkY29uZmlnWydzdWdnZXN0J10gYXMgJHRhcmdldCA9PiAkcmVhc29uKSB7CiAgICAgICAgICAgICAgICBpZiAoJ3NlbGYudmVyc2lvbicgPT09IHRyaW0oJHJlYXNvbikpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydzdWdnZXN0J11bJHRhcmdldF0gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRTdWdnZXN0cygkY29uZmlnWydzdWdnZXN0J10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2F1dG9sb2FkJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRBdXRvbG9hZCgkY29uZmlnWydhdXRvbG9hZCddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydhdXRvbG9hZC1kZXYnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldERldkF1dG9sb2FkKCRjb25maWdbJ2F1dG9sb2FkLWRldiddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydpbmNsdWRlLXBhdGgnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldEluY2x1ZGVQYXRocygkY29uZmlnWydpbmNsdWRlLXBhdGgnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRjb25maWdbJ3RpbWUnXSkpIHsKICAgICAgICAgICAgJHRpbWUgPSBQcmVnOjppc01hdGNoKCcvXlxkKyskL0QnLCAkY29uZmlnWyd0aW1lJ10pID8gJ0AnLiRjb25maWdbJ3RpbWUnXSA6ICRjb25maWdbJ3RpbWUnXTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkZGF0ZSA9IG5ldyBcRGF0ZVRpbWUoJHRpbWUsIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0UmVsZWFzZURhdGUoJGRhdGUpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snbm90aWZpY2F0aW9uLXVybCddKSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0Tm90aWZpY2F0aW9uVXJsKCRjb25maWdbJ25vdGlmaWNhdGlvbi11cmwnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydhcmNoaXZlJ11bJ25hbWUnXSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRBcmNoaXZlTmFtZSgkY29uZmlnWydhcmNoaXZlJ11bJ25hbWUnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydhcmNoaXZlJ11bJ2V4Y2x1ZGUnXSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRBcmNoaXZlRXhjbHVkZXMoJGNvbmZpZ1snYXJjaGl2ZSddWydleGNsdWRlJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snc2NyaXB0cyddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snc2NyaXB0cyddKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZ1snc2NyaXB0cyddIGFzICRldmVudCA9PiAkbGlzdGVuZXJzKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1snc2NyaXB0cyddWyRldmVudF0gPSAoYXJyYXkpICRsaXN0ZW5lcnM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheSgnY29tcG9zZXInLCAncGhwJywgJ3B1dGVudicpIGFzICRyZXNlcnZlZCkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWydzY3JpcHRzJ11bJHJlc2VydmVkXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignVGhlIGAnLiRyZXNlcnZlZC4nYCBzY3JpcHQgbmFtZSBpcyByZXNlcnZlZCBmb3IgaW50ZXJuYWwgdXNlLCBwbGVhc2UgYXZvaWQgZGVmaW5pbmcgaXQnLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNjcmlwdHMoJGNvbmZpZ1snc2NyaXB0cyddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydkZXNjcmlwdGlvbiddKSAmJiBcaXNfc3RyaW5nKCRjb25maWdbJ2Rlc2NyaXB0aW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0RGVzY3JpcHRpb24oJGNvbmZpZ1snZGVzY3JpcHRpb24nXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snaG9tZXBhZ2UnXSkgJiYgXGlzX3N0cmluZygkY29uZmlnWydob21lcGFnZSddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldEhvbWVwYWdlKCRjb25maWdbJ2hvbWVwYWdlJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRjb25maWdbJ2tleXdvcmRzJ10pICYmIFxpc19hcnJheSgkY29uZmlnWydrZXl3b3JkcyddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldEtleXdvcmRzKCRjb25maWdbJ2tleXdvcmRzJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRjb25maWdbJ2xpY2Vuc2UnXSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRMaWNlbnNlKFxpc19hcnJheSgkY29uZmlnWydsaWNlbnNlJ10pID8gJGNvbmZpZ1snbGljZW5zZSddIDogYXJyYXkoJGNvbmZpZ1snbGljZW5zZSddKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snYXV0aG9ycyddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snYXV0aG9ycyddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldEF1dGhvcnMoJGNvbmZpZ1snYXV0aG9ycyddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3N1cHBvcnQnXSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRTdXBwb3J0KCRjb25maWdbJ3N1cHBvcnQnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snZnVuZGluZyddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snZnVuZGluZyddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldEZ1bmRpbmcoJGNvbmZpZ1snZnVuZGluZyddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2FiYW5kb25lZCddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldEFiYW5kb25lZCgkY29uZmlnWydhYmFuZG9uZWQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bG9hZE9wdGlvbnMgJiYgaXNzZXQoJGNvbmZpZ1sndHJhbnNwb3J0LW9wdGlvbnMnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldFRyYW5zcG9ydE9wdGlvbnMoJGNvbmZpZ1sndHJhbnNwb3J0LW9wdGlvbnMnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGFsaWFzTm9ybWFsaXplZCA9ICR0aGlzLT5nZXRCcmFuY2hBbGlhcygkY29uZmlnKSkgewogICAgICAgICAgICAkcHJldHR5QWxpYXMgPSBQcmVnOjpyZXBsYWNlKCd7KFwuOXs3fSkrfScsICcueCcsICRhbGlhc05vcm1hbGl6ZWQpOwoKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUm9vdEFsaWFzUGFja2FnZSgkcGFja2FnZSwgJGFsaWFzTm9ybWFsaXplZCwgJHByZXR0eUFsaWFzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV0ZUFsaWFzUGFja2FnZSgkcGFja2FnZSwgJGFsaWFzTm9ybWFsaXplZCwgJHByZXR0eUFsaWFzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGFycmF5e3N0cmluZywgTGlua30+Pj4+ICRsaW5rQ2FjaGUKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29uZmlnCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY29uZmlndXJlQ2FjaGVkTGlua3MoJiRsaW5rQ2FjaGUsICRwYWNrYWdlLCBhcnJheSAkY29uZmlnKQogICAgewogICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CgogICAgICAgIGZvcmVhY2ggKEJhc2VQYWNrYWdlOjokc3VwcG9ydGVkTGlua1R5cGVzIGFzICR0eXBlID0+ICRvcHRzKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWyR0eXBlXSkpIHsKICAgICAgICAgICAgICAgICRtZXRob2QgPSAnc2V0Jy51Y2ZpcnN0KCRvcHRzWydtZXRob2QnXSk7CgogICAgICAgICAgICAgICAgJGxpbmtzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJHR5cGVdIGFzICRwcmV0dHlUYXJnZXQgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ID0gc3RydG9sb3dlcigkcHJldHR5VGFyZ2V0KTsKCiAgICAgICAgICAgICAgICAgICAgLy8gcmVjdXJzaXZlIGxpbmtzIGFyZSBub3Qgc3VwcG9ydGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0YXJnZXQgPT09ICRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50ID09PSAnc2VsZi52ZXJzaW9uJykgewogICAgICAgICAgICAgICAgICAgICAgICAkbGlua3NbJHRhcmdldF0gPSAkdGhpcy0+Y3JlYXRlTGluaygkbmFtZSwgJHByZXR0eVZlcnNpb24sICRvcHRzWydtZXRob2QnXSwgJHRhcmdldCwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGxpbmtDYWNoZVskbmFtZV1bJHR5cGVdWyR0YXJnZXRdWyRjb25zdHJhaW50XSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaW5rQ2FjaGVbJG5hbWVdWyR0eXBlXVskdGFyZ2V0XVskY29uc3RyYWludF0gPSBhcnJheSgkdGFyZ2V0LCAkdGhpcy0+Y3JlYXRlTGluaygkbmFtZSwgJHByZXR0eVZlcnNpb24sICRvcHRzWydtZXRob2QnXSwgJHRhcmdldCwgJGNvbnN0cmFpbnQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgkdGFyZ2V0LCAkbGluaykgPSAkbGlua0NhY2hlWyRuYW1lXVskdHlwZV1bJHRhcmdldF1bJGNvbnN0cmFpbnRdOwogICAgICAgICAgICAgICAgICAgICAgICAkbGlua3NbJHRhcmdldF0gPSAkbGluazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnskbWV0aG9kfSgkbGlua3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHNvdXJjZSAgICAgICAgc291cmNlIHBhY2thZ2UgbmFtZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHNvdXJjZVZlcnNpb24gc291cmNlIHBhY2thZ2UgdmVyc2lvbiAocHJldHR5IHZlcnNpb24gaWRlYWxseSkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiAgIGxpbmsgZGVzY3JpcHRpb24gKGUuZy4gcmVxdWlyZXMsIHJlcGxhY2VzLCAuLikKICAgICAqIEBwYXJhbSAgYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICRsaW5rcyAgICAgICAgIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBjb25zdHJhaW50IG1hcHBpbmdzCiAgICAgKgogICAgICogQHJldHVybiBMaW5rW10KICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBMaW5rOjpUWVBFXyogJGRlc2NyaXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUxpbmtzKCRzb3VyY2UsICRzb3VyY2VWZXJzaW9uLCAkZGVzY3JpcHRpb24sICRsaW5rcykKICAgIHsKICAgICAgICAkcmVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJHRhcmdldCA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAkdGFyZ2V0ID0gc3RydG9sb3dlcigkdGFyZ2V0KTsKICAgICAgICAgICAgJHJlc1skdGFyZ2V0XSA9ICR0aGlzLT5jcmVhdGVMaW5rKCRzb3VyY2UsICRzb3VyY2VWZXJzaW9uLCAkZGVzY3JpcHRpb24sICR0YXJnZXQsICRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgJHNvdXJjZSAgICAgICAgICAgc291cmNlIHBhY2thZ2UgbmFtZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgJHNvdXJjZVZlcnNpb24gICAgc291cmNlIHBhY2thZ2UgdmVyc2lvbiAocHJldHR5IHZlcnNpb24gaWRlYWxseSkKICAgICAqIEBwYXJhbSAgTGluazo6VFlQRV8qICRkZXNjcmlwdGlvbiAgICAgIGxpbmsgZGVzY3JpcHRpb24gKGUuZy4gcmVxdWlyZXMsIHJlcGxhY2VzLCAuLikKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICR0YXJnZXQgICAgICAgICAgIHRhcmdldCBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRwcmV0dHlDb25zdHJhaW50IGNvbnN0cmFpbnQgc3RyaW5nCiAgICAgKiBAcmV0dXJuIExpbmsKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVMaW5rKCRzb3VyY2UsICRzb3VyY2VWZXJzaW9uLCAkZGVzY3JpcHRpb24sICR0YXJnZXQsICRwcmV0dHlDb25zdHJhaW50KQogICAgewogICAgICAgIGlmICghXGlzX3N0cmluZygkcHJldHR5Q29uc3RyYWludCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0xpbmsgY29uc3RyYWludCBpbiAnLiRzb3VyY2UuJyAnLiRkZXNjcmlwdGlvbi4nID4gJy4kdGFyZ2V0Licgc2hvdWxkIGJlIGEgc3RyaW5nLCBnb3QgJy5cZ2V0dHlwZSgkcHJldHR5Q29uc3RyYWludCkgLiAnICgnIC4gdmFyX2V4cG9ydCgkcHJldHR5Q29uc3RyYWludCwgdHJ1ZSkgLiAnKScpOwogICAgICAgIH0KICAgICAgICBpZiAoJ3NlbGYudmVyc2lvbicgPT09ICRwcmV0dHlDb25zdHJhaW50KSB7CiAgICAgICAgICAgICRwYXJzZWRDb25zdHJhaW50ID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJHNvdXJjZVZlcnNpb24pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwYXJzZWRDb25zdHJhaW50ID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJHByZXR0eUNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBMaW5rKCRzb3VyY2UsICR0YXJnZXQsICRwYXJzZWRDb25zdHJhaW50LCAkZGVzY3JpcHRpb24sICRwcmV0dHlDb25zdHJhaW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyBhIGJyYW5jaCBhbGlhcyAoZGV2LW1hc3RlciA9PiAxLjAueC1kZXYgZm9yIGV4YW1wbGUpIGlmIGl0IGV4aXN0cwogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb25maWcgdGhlIGVudGlyZSBwYWNrYWdlIGNvbmZpZwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBicmFuY2ggYWxpYXMgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hBbGlhcyhhcnJheSAkY29uZmlnKQogICAgewogICAgICAgIGlmIChzdHJwb3MoJGNvbmZpZ1sndmVyc2lvbiddLCAnZGV2LScpICE9PSAwICYmICctZGV2JyAhPT0gc3Vic3RyKCRjb25maWdbJ3ZlcnNpb24nXSwgLTQpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddIGFzICRzb3VyY2VCcmFuY2ggPT4gJHRhcmdldEJyYW5jaCkgewogICAgICAgICAgICAgICAgLy8gZW5zdXJlIGl0IGlzIGFuIGFsaWFzIHRvIGEgLWRldiBwYWNrYWdlCiAgICAgICAgICAgICAgICBpZiAoJy1kZXYnICE9PSBzdWJzdHIoJHRhcmdldEJyYW5jaCwgLTQpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbm9ybWFsaXplIHdpdGhvdXQgLWRldiBhbmQgZW5zdXJlIGl0J3MgYSBudW1lcmljIGJyYW5jaCB0aGF0IGlzIHBhcnNlYWJsZQogICAgICAgICAgICAgICAgaWYgKCR0YXJnZXRCcmFuY2ggPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRlZFRhcmdldEJyYW5jaCA9IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdmFsaWRhdGVkVGFyZ2V0QnJhbmNoID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZUJyYW5jaChzdWJzdHIoJHRhcmdldEJyYW5jaCwgMCwgLTQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgnLWRldicgIT09IHN1YnN0cigkdmFsaWRhdGVkVGFyZ2V0QnJhbmNoLCAtNCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBlbnN1cmUgdGhhdCBpdCBpcyB0aGUgY3VycmVudCBicmFuY2ggYWxpYXNpbmcgaXRzZWxmCiAgICAgICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkY29uZmlnWyd2ZXJzaW9uJ10pICE9PSBzdHJ0b2xvd2VyKCRzb3VyY2VCcmFuY2gpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSWYgdXNpbmcgbnVtZXJpYyBhbGlhc2VzIGVuc3VyZSB0aGUgYWxpYXMgaXMgYSB2YWxpZCBzdWJ2ZXJzaW9uCiAgICAgICAgICAgICAgICBpZiAoKCRzb3VyY2VQcmVmaXggPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJHNvdXJjZUJyYW5jaCkpCiAgICAgICAgICAgICAgICAgICAgJiYgKCR0YXJnZXRQcmVmaXggPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJHRhcmdldEJyYW5jaCkpCiAgICAgICAgICAgICAgICAgICAgJiYgKHN0cmlwb3MoJHRhcmdldFByZWZpeCwgJHNvdXJjZVByZWZpeCkgIT09IDApCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbGlkYXRlZFRhcmdldEJyYW5jaDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKAogICAgICAgICAgICBpc3NldCgkY29uZmlnWydkZWZhdWx0LWJyYW5jaCddKQogICAgICAgICAgICAmJiAkY29uZmlnWydkZWZhdWx0LWJyYW5jaCddID09PSB0cnVlCiAgICAgICAgICAgICYmIGZhbHNlID09PSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJGNvbmZpZ1sndmVyc2lvbiddKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25HdWVzc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5TWFuYWdlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKCi8qKgogKiBBcnJheUxvYWRlciBidWlsdCBmb3IgdGhlIHNvbGUgcHVycG9zZSBvZiBsb2FkaW5nIHRoZSByb290IHBhY2thZ2UKICoKICogU2V0cyBhZGRpdGlvbmFsIGRlZmF1bHRzIGFuZCBsb2FkcyByZXBvc2l0b3JpZXMKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUm9vdFBhY2thZ2VMb2FkZXIgZXh0ZW5kcyBBcnJheUxvYWRlcgp7CiAgICAvKioKICAgICAqIEB2YXIgUmVwb3NpdG9yeU1hbmFnZXIKICAgICAqLwogICAgcHJpdmF0ZSAkbWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgQ29uZmlnCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEB2YXIgVmVyc2lvbkd1ZXNzZXIKICAgICAqLwogICAgcHJpdmF0ZSAkdmVyc2lvbkd1ZXNzZXI7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFJlcG9zaXRvcnlNYW5hZ2VyICRtYW5hZ2VyLCBDb25maWcgJGNvbmZpZywgVmVyc2lvblBhcnNlciAkcGFyc2VyID0gbnVsbCwgVmVyc2lvbkd1ZXNzZXIgJHZlcnNpb25HdWVzc2VyID0gbnVsbCwgSU9JbnRlcmZhY2UgJGlvID0gbnVsbCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRwYXJzZXIpOwoKICAgICAgICAkdGhpcy0+bWFuYWdlciA9ICRtYW5hZ2VyOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT52ZXJzaW9uR3Vlc3NlciA9ICR2ZXJzaW9uR3Vlc3NlciA/OiBuZXcgVmVyc2lvbkd1ZXNzZXIoJGNvbmZpZywgbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pLCAkdGhpcy0+dmVyc2lvblBhcnNlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICoKICAgICAqIEB0ZW1wbGF0ZSBQYWNrYWdlQ2xhc3Mgb2YgUm9vdFBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGN3ZAogICAgICoKICAgICAqIEByZXR1cm4gUm9vdFBhY2thZ2V8Um9vdEFsaWFzUGFja2FnZQogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIGNsYXNzLXN0cmluZzxQYWNrYWdlQ2xhc3M+ICRjbGFzcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZChhcnJheSAkY29uZmlnLCAkY2xhc3MgPSAnQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZScsICRjd2QgPSBudWxsKQogICAgewogICAgICAgIGlmICgkY2xhc3MgIT09ICdDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlJykgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdUaGUgJGNsYXNzIGFyZyBpcyBkZXByZWNhdGVkLCBwbGVhc2UgcmVhY2ggb3V0IHRvIENvbXBvc2VyIG1haW50YWluZXJzIEFTQVAgaWYgeW91IHN0aWxsIG5lZWQgdGhpcy4nLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRjb25maWdbJ25hbWUnXSkpIHsKICAgICAgICAgICAgJGNvbmZpZ1snbmFtZSddID0gJ19fcm9vdF9fJzsKICAgICAgICB9IGVsc2VpZiAoJGVyciA9IFZhbGlkYXRpbmdBcnJheUxvYWRlcjo6aGFzUGFja2FnZU5hbWluZ0Vycm9yKCRjb25maWdbJ25hbWUnXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdZb3VyIHBhY2thZ2UgbmFtZSAnLiRlcnIpOwogICAgICAgIH0KICAgICAgICAkYXV0b1ZlcnNpb25lZCA9IGZhbHNlOwogICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1sndmVyc2lvbiddKSkgewogICAgICAgICAgICAkY29tbWl0ID0gbnVsbDsKCiAgICAgICAgICAgIC8vIG92ZXJyaWRlIHdpdGggZW52IHZhciBpZiBhdmFpbGFibGUKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjpnZXRFbnYoJ0NPTVBPU0VSX1JPT1RfVkVSU0lPTicpKSB7CiAgICAgICAgICAgICAgICAkY29uZmlnWyd2ZXJzaW9uJ10gPSBQbGF0Zm9ybTo6Z2V0RW52KCdDT01QT1NFUl9ST09UX1ZFUlNJT04nKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uRGF0YSA9ICR0aGlzLT52ZXJzaW9uR3Vlc3Nlci0+Z3Vlc3NWZXJzaW9uKCRjb25maWcsICRjd2QgPzogZ2V0Y3dkKCkpOwogICAgICAgICAgICAgICAgaWYgKCR2ZXJzaW9uRGF0YSkgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ3ZlcnNpb24nXSA9ICR2ZXJzaW9uRGF0YVsncHJldHR5X3ZlcnNpb24nXTsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICR2ZXJzaW9uRGF0YVsndmVyc2lvbiddOwogICAgICAgICAgICAgICAgICAgICRjb21taXQgPSAkdmVyc2lvbkRhdGFbJ2NvbW1pdCddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRjb25maWdbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgICRjb25maWdbJ3ZlcnNpb24nXSA9ICcxLjAuMCc7CiAgICAgICAgICAgICAgICAkYXV0b1ZlcnNpb25lZCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY29tbWl0KSB7CiAgICAgICAgICAgICAgICAkY29uZmlnWydzb3VyY2UnXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICd0eXBlJyA9PiAnJywKICAgICAgICAgICAgICAgICAgICAndXJsJyA9PiAnJywKICAgICAgICAgICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAkY29tbWl0LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRjb25maWdbJ2Rpc3QnXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICd0eXBlJyA9PiAnJywKICAgICAgICAgICAgICAgICAgICAndXJsJyA9PiAnJywKICAgICAgICAgICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAkY29tbWl0LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIEB2YXIgUm9vdFBhY2thZ2V8Um9vdEFsaWFzUGFja2FnZSAkcGFja2FnZSAqLwogICAgICAgICRwYWNrYWdlID0gcGFyZW50Ojpsb2FkKCRjb25maWcsICRjbGFzcyk7CiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAkcmVhbFBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZWFsUGFja2FnZSA9ICRwYWNrYWdlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkcmVhbFBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdFeHBlY3RpbmcgYSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlIGF0IHRoaXMgcG9pbnQnKTsKICAgICAgICB9CgogICAgICAgIGlmICgkYXV0b1ZlcnNpb25lZCkgewogICAgICAgICAgICAkcmVhbFBhY2thZ2UtPnJlcGxhY2VWZXJzaW9uKCRyZWFsUGFja2FnZS0+Z2V0VmVyc2lvbigpLCBSb290UGFja2FnZTo6REVGQVVMVF9QUkVUVFlfVkVSU0lPTik7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snbWluaW11bS1zdGFiaWxpdHknXSkpIHsKICAgICAgICAgICAgJHJlYWxQYWNrYWdlLT5zZXRNaW5pbXVtU3RhYmlsaXR5KFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkY29uZmlnWydtaW5pbXVtLXN0YWJpbGl0eSddKSk7CiAgICAgICAgfQoKICAgICAgICAkYWxpYXNlcyA9IGFycmF5KCk7CiAgICAgICAgJHN0YWJpbGl0eUZsYWdzID0gYXJyYXkoKTsKICAgICAgICAkcmVmZXJlbmNlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3JlcXVpcmUnLCAncmVxdWlyZS1kZXYnKSBhcyAkbGlua1R5cGUpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJGxpbmtUeXBlXSkpIHsKICAgICAgICAgICAgICAgICRsaW5rSW5mbyA9IEJhc2VQYWNrYWdlOjokc3VwcG9ydGVkTGlua1R5cGVzWyRsaW5rVHlwZV07CiAgICAgICAgICAgICAgICAkbWV0aG9kID0gJ2dldCcudWNmaXJzdCgkbGlua0luZm9bJ21ldGhvZCddKTsKICAgICAgICAgICAgICAgICRsaW5rcyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVhbFBhY2thZ2UtPiRtZXRob2QoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICRsaW5rc1skbGluay0+Z2V0VGFyZ2V0KCldID0gJGxpbmstPmdldENvbnN0cmFpbnQoKS0+Z2V0UHJldHR5U3RyaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkYWxpYXNlcyA9ICR0aGlzLT5leHRyYWN0QWxpYXNlcygkbGlua3MsICRhbGlhc2VzKTsKICAgICAgICAgICAgICAgICRzdGFiaWxpdHlGbGFncyA9IHNlbGY6OmV4dHJhY3RTdGFiaWxpdHlGbGFncygkbGlua3MsICRyZWFsUGFja2FnZS0+Z2V0TWluaW11bVN0YWJpbGl0eSgpLCAkc3RhYmlsaXR5RmxhZ3MpOwogICAgICAgICAgICAgICAgJHJlZmVyZW5jZXMgPSBzZWxmOjpleHRyYWN0UmVmZXJlbmNlcygkbGlua3MsICRyZWZlcmVuY2VzKTsKCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGxpbmtzWyRjb25maWdbJ25hbWUnXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1Jvb3QgcGFja2FnZSBcJyVzXCcgY2Fubm90IHJlcXVpcmUgaXRzZWxmIGluIGl0cyBjb21wb3Nlci5qc29uJyAuIFBIUF9FT0wgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEaWQgeW91IGFjY2lkZW50YWxseSBuYW1lIHlvdXIgcm9vdCBwYWNrYWdlIGFmdGVyIGFuIGV4dGVybmFsIHBhY2thZ2U/JywgJGNvbmZpZ1snbmFtZSddKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKGFycmF5X2tleXMoQmFzZVBhY2thZ2U6OiRzdXBwb3J0ZWRMaW5rVHlwZXMpIGFzICRsaW5rVHlwZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1skbGlua1R5cGVdKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZ1skbGlua1R5cGVdIGFzICRsaW5rTmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkZXJyID0gVmFsaWRhdGluZ0FycmF5TG9hZGVyOjpoYXNQYWNrYWdlTmFtaW5nRXJyb3IoJGxpbmtOYW1lLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGxpbmtUeXBlLicuJy4kZXJyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRyZWFsUGFja2FnZS0+c2V0QWxpYXNlcygkYWxpYXNlcyk7CiAgICAgICAgJHJlYWxQYWNrYWdlLT5zZXRTdGFiaWxpdHlGbGFncygkc3RhYmlsaXR5RmxhZ3MpOwogICAgICAgICRyZWFsUGFja2FnZS0+c2V0UmVmZXJlbmNlcygkcmVmZXJlbmNlcyk7CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydwcmVmZXItc3RhYmxlJ10pKSB7CiAgICAgICAgICAgICRyZWFsUGFja2FnZS0+c2V0UHJlZmVyU3RhYmxlKChib29sKSAkY29uZmlnWydwcmVmZXItc3RhYmxlJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2NvbmZpZyddKSkgewogICAgICAgICAgICAkcmVhbFBhY2thZ2UtPnNldENvbmZpZygkY29uZmlnWydjb25maWcnXSk7CiAgICAgICAgfQoKICAgICAgICAkcmVwb3MgPSBSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKG51bGwsICR0aGlzLT5jb25maWcsICR0aGlzLT5tYW5hZ2VyKTsKICAgICAgICBmb3JlYWNoICgkcmVwb3MgYXMgJHJlcG8pIHsKICAgICAgICAgICAgJHRoaXMtPm1hbmFnZXItPmFkZFJlcG9zaXRvcnkoJHJlcG8pOwogICAgICAgIH0KICAgICAgICAkcmVhbFBhY2thZ2UtPnNldFJlcG9zaXRvcmllcygkdGhpcy0+Y29uZmlnLT5nZXRSZXBvc2l0b3JpZXMoKSk7CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZXMKICAgICAqIEBwYXJhbSBsaXN0PGFycmF5e3BhY2thZ2U6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9PiAkYWxpYXNlcwogICAgICoKICAgICAqIEByZXR1cm4gbGlzdDxhcnJheXtwYWNrYWdlOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgYWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBleHRyYWN0QWxpYXNlcyhhcnJheSAkcmVxdWlyZXMsIGFycmF5ICRhbGlhc2VzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxTmFtZSA9PiAkcmVxVmVyc2lvbikgewogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne14oW14sXHMjXSspKD86I1teIF0rKT8gK2FzICsoW14sXHNdKykkfScsICRyZXFWZXJzaW9uLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAkYWxpYXNlc1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ3BhY2thZ2UnID0+IHN0cnRvbG93ZXIoJHJlcU5hbWUpLAogICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRtYXRjaFsxXSwgJHJlcVZlcnNpb24pLAogICAgICAgICAgICAgICAgICAgICdhbGlhcycgPT4gJG1hdGNoWzJdLAogICAgICAgICAgICAgICAgICAgICdhbGlhc19ub3JtYWxpemVkJyA9PiAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRtYXRjaFsyXSwgJHJlcVZlcnNpb24pLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlaWYgKHN0cnBvcygkcmVxVmVyc2lvbiwgJyBhcyAnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdJbnZhbGlkIGFsaWFzIGRlZmluaXRpb24gaW4gIicuJHJlcU5hbWUuJyI6ICInLiRyZXFWZXJzaW9uLiciLiBBbGlhc2VzIHNob3VsZCBiZSBpbiB0aGUgZm9ybSAiZXhhY3QtdmVyc2lvbiBhcyBvdGhlci1leGFjdC12ZXJzaW9uIi4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhbGlhc2VzOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkcmVxdWlyZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgJG1pbmltdW1TdGFiaWxpdHkKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGludD4gICAgJHN0YWJpbGl0eUZsYWdzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIGludD4KICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4gJHN0YWJpbGl0eUZsYWdzCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdFN0YWJpbGl0eUZsYWdzKGFycmF5ICRyZXF1aXJlcywgJG1pbmltdW1TdGFiaWxpdHksIGFycmF5ICRzdGFiaWxpdHlGbGFncykKICAgIHsKICAgICAgICAkc3RhYmlsaXRpZXMgPSBCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzOwogICAgICAgIC8qKiBAdmFyIGludCAkbWluaW11bVN0YWJpbGl0eSAqLwogICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJHN0YWJpbGl0aWVzWyRtaW5pbXVtU3RhYmlsaXR5XTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcU5hbWUgPT4gJHJlcVZlcnNpb24pIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnRzID0gYXJyYXkoKTsKCiAgICAgICAgICAgIC8vIGV4dHJhY3QgYWxsIHN1Yi1jb25zdHJhaW50cyBpbiBjYXNlIGl0IGlzIGFuIE9SL0FORCBtdWx0aS1jb25zdHJhaW50CiAgICAgICAgICAgICRvclNwbGl0ID0gUHJlZzo6c3BsaXQoJ3tccypcfFx8P1xzKn0nLCB0cmltKCRyZXFWZXJzaW9uKSk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvclNwbGl0IGFzICRvckNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICRhbmRTcGxpdCA9IFByZWc6OnNwbGl0KCd7KD88IV58YXN8Wz0+PCAsXSkgKig/PCEtKVssIF0oPyEtKSAqKD8hLHxhc3wkKX0nLCAkb3JDb25zdHJhaW50KTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhbmRTcGxpdCBhcyAkYW5kQ29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJGFuZENvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHBhcnNlIGV4cGxpY2l0IHN0YWJpbGl0eSBmbGFncyB0byB0aGUgbW9zdCB1bnN0YWJsZQogICAgICAgICAgICAkbWF0Y2ggPSBmYWxzZTsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnN0cmFpbnRzIGFzICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15bXkBdKj9AKCcuaW1wbG9kZSgnfCcsIGFycmF5X2tleXMoJHN0YWJpbGl0aWVzKSkuJykkfWknLCAkY29uc3RyYWludCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkcmVxTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgJHN0YWJpbGl0eSA9ICRzdGFiaWxpdGllc1tWZXJzaW9uUGFyc2VyOjpub3JtYWxpemVTdGFiaWxpdHkoJG1hdGNoWzFdKV07CgogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkc3RhYmlsaXR5RmxhZ3NbJG5hbWVdKSAmJiAkc3RhYmlsaXR5RmxhZ3NbJG5hbWVdID4gJHN0YWJpbGl0eSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSA9ICRzdGFiaWxpdHk7CiAgICAgICAgICAgICAgICAgICAgJG1hdGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRtYXRjaCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgLy8gaW5mZXIgZmxhZ3MgZm9yIHJlcXVpcmVtZW50cyB0aGF0IGhhdmUgYW4gZXhwbGljaXQgLWRldiBvciAtYmV0YSB2ZXJzaW9uIHNwZWNpZmllZCBidXQgb25seQogICAgICAgICAgICAgICAgLy8gZm9yIHRob3NlIHRoYXQgYXJlIG1vcmUgdW5zdGFibGUgdGhhbiB0aGUgbWluaW11bVN0YWJpbGl0eSBvciBleGlzdGluZyBmbGFncwogICAgICAgICAgICAgICAgJHJlcVZlcnNpb24gPSBQcmVnOjpyZXBsYWNlKCd7XihbXixcc0BdKykgYXMgLiskfScsICckMScsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XlteLFxzQF0rJH0nLCAkcmVxVmVyc2lvbikgJiYgJ3N0YWJsZScgIT09ICgkc3RhYmlsaXR5TmFtZSA9IFZlcnNpb25QYXJzZXI6OnBhcnNlU3RhYmlsaXR5KCRyZXFWZXJzaW9uKSkpIHsKICAgICAgICAgICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJHJlcU5hbWUpOwogICAgICAgICAgICAgICAgICAgICRzdGFiaWxpdHkgPSAkc3RhYmlsaXRpZXNbJHN0YWJpbGl0eU5hbWVdOwogICAgICAgICAgICAgICAgICAgIGlmICgoaXNzZXQoJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSkgJiYgJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSA+ICRzdGFiaWxpdHkpIHx8ICgkbWluaW11bVN0YWJpbGl0eSA+ICRzdGFiaWxpdHkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkc3RhYmlsaXR5RmxhZ3NbJG5hbWVdID0gJHN0YWJpbGl0eTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdGFiaWxpdHlGbGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICoKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJHJlcXVpcmVzCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICRyZWZlcmVuY2VzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0UmVmZXJlbmNlcyhhcnJheSAkcmVxdWlyZXMsIGFycmF5ICRyZWZlcmVuY2VzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxTmFtZSA9PiAkcmVxVmVyc2lvbikgewogICAgICAgICAgICAkcmVxVmVyc2lvbiA9IFByZWc6OnJlcGxhY2UoJ3teKFteLFxzQF0rKSBhcyAuKyR9JywgJyQxJywgJHJlcVZlcnNpb24pOwogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgne15bXixcc0BdKz8jKFthLWYwLTldKykkfScsICRyZXFWZXJzaW9uLCAkbWF0Y2gpICYmICdkZXYnID09PSBWZXJzaW9uUGFyc2VyOjpwYXJzZVN0YWJpbGl0eSgkcmVxVmVyc2lvbikpIHsKICAgICAgICAgICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkcmVxTmFtZSk7CiAgICAgICAgICAgICAgICAkcmVmZXJlbmNlc1skbmFtZV0gPSAkbWF0Y2hbMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVmZXJlbmNlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBBbGlhc1BhY2thZ2UgZXh0ZW5kcyBCYXNlUGFja2FnZQp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdmVyc2lvbjsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlWZXJzaW9uOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRkZXY7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJHJvb3RQYWNrYWdlQWxpYXMgPSBmYWxzZTsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBwaHBzdGFuLXZhciAnc3RhYmxlJ3wnUkMnfCdiZXRhJ3wnYWxwaGEnfCdkZXYnCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3RhYmlsaXR5OwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRoYXNTZWxmVmVyc2lvblJlcXVpcmVzID0gZmFsc2U7CgogICAgLyoqIEB2YXIgQmFzZVBhY2thZ2UgKi8KICAgIHByb3RlY3RlZCAkYWxpYXNPZjsKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRyZXF1aXJlczsKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRkZXZSZXF1aXJlczsKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRjb25mbGljdHM7CiAgICAvKiogQHZhciBMaW5rW10gKi8KICAgIHByb3RlY3RlZCAkcHJvdmlkZXM7CiAgICAvKiogQHZhciBMaW5rW10gKi8KICAgIHByb3RlY3RlZCAkcmVwbGFjZXM7CgogICAgLyoqCiAgICAgKiBBbGwgZGVzY2VuZGFudHMnIGNvbnN0cnVjdG9ycyBzaG91bGQgY2FsbCB0aGlzIHBhcmVudCBjb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBCYXNlUGFja2FnZSAkYWxpYXNPZiAgICAgICBUaGUgcGFja2FnZSB0aGlzIHBhY2thZ2UgaXMgYW4gYWxpYXMgb2YKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdmVyc2lvbiAgICAgICBUaGUgdmVyc2lvbiB0aGUgYWxpYXMgbXVzdCByZXBvcnQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkcHJldHR5VmVyc2lvbiBUaGUgYWxpYXMncyBub24tbm9ybWFsaXplZCB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChCYXNlUGFja2FnZSAkYWxpYXNPZiwgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGFsaWFzT2YtPmdldE5hbWUoKSk7CgogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgJHRoaXMtPnByZXR0eVZlcnNpb24gPSAkcHJldHR5VmVyc2lvbjsKICAgICAgICAkdGhpcy0+YWxpYXNPZiA9ICRhbGlhc09mOwogICAgICAgICR0aGlzLT5zdGFiaWxpdHkgPSBWZXJzaW9uUGFyc2VyOjpwYXJzZVN0YWJpbGl0eSgkdmVyc2lvbik7CiAgICAgICAgJHRoaXMtPmRldiA9ICR0aGlzLT5zdGFiaWxpdHkgPT09ICdkZXYnOwoKICAgICAgICBmb3JlYWNoIChMaW5rOjokVFlQRVMgYXMgJHR5cGUpIHsKICAgICAgICAgICAgJGxpbmtzID0gJGFsaWFzT2YtPnsnZ2V0JyAuIHVjZmlyc3QoJHR5cGUpfSgpOwogICAgICAgICAgICAkdGhpcy0+JHR5cGUgPSAkdGhpcy0+cmVwbGFjZVNlbGZWZXJzaW9uRGVwZW5kZW5jaWVzKCRsaW5rcywgJHR5cGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQmFzZVBhY2thZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsaWFzT2YoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZjsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YWJpbGl0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZXYoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcXVpcmVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcXVpcmVzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nfGludCwgTGluaz4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZsaWN0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25mbGljdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICogQHJldHVybiBhcnJheTxzdHJpbmd8aW50LCBMaW5rPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvdmlkZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvdmlkZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICogQHJldHVybiBhcnJheTxzdHJpbmd8aW50LCBMaW5rPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwbGFjZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGV2UmVxdWlyZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2UmVxdWlyZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZXMgd2hldGhlciB0aGlzIGlzIGFuIGFsaWFzIGNyZWF0ZWQgYnkgYW4gYWxpYXNpbmcgaW4gdGhlIHJlcXVpcmVtZW50cyBvZiB0aGUgcm9vdCBwYWNrYWdlIG9yIG5vdAogICAgICoKICAgICAqIFVzZSBieSB0aGUgcG9saWN5IGZvciBzb3J0aW5nIG1hbnVhbGx5IGFsaWFzZWQgcGFja2FnZXMgZmlyc3QsIHNlZSAjNTc2CiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Um9vdFBhY2thZ2VBbGlhcygkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290UGFja2FnZUFsaWFzID0gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBzZXRSb290UGFja2FnZUFsaWFzCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUm9vdFBhY2thZ2VBbGlhcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290UGFja2FnZUFsaWFzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIExpbmtbXSAgICAgICAkbGlua3MKICAgICAqIEBwYXJhbSBMaW5rOjpUWVBFXyogJGxpbmtUeXBlCiAgICAgKgogICAgICogQHJldHVybiBMaW5rW10KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcyhhcnJheSAkbGlua3MsICRsaW5rVHlwZSkKICAgIHsKICAgICAgICAvLyBmb3Igc2VsZi52ZXJzaW9uIHJlcXVpcmVtZW50cywgd2UgdXNlIHRoZSBvcmlnaW5hbCBwYWNrYWdlJ3MgYnJhbmNoIG5hbWUgaW5zdGVhZCwgdG8gYXZvaWQgbGVha2luZyB0aGUgbWFnaWMgZGV2LW1hc3Rlci1hbGlhcyB0byB1c2VycwogICAgICAgICRwcmV0dHlWZXJzaW9uID0gJHRoaXMtPnByZXR0eVZlcnNpb247CiAgICAgICAgaWYgKCRwcmV0dHlWZXJzaW9uID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICR0aGlzLT5hbGlhc09mLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGluX2FycmF5KCRsaW5rVHlwZSwgYXJyYXkoTGluazo6VFlQRV9DT05GTElDVCwgTGluazo6VFlQRV9QUk9WSURFLCBMaW5rOjpUWVBFX1JFUExBQ0UpLCB0cnVlKSkgewogICAgICAgICAgICAkbmV3TGlua3MgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgIC8vIGxpbmsgaXMgc2VsZi52ZXJzaW9uLCBidXQgbXVzdCBiZSByZXBsYWNpbmcgYWxzbyB0aGUgcmVwbGFjZWQgdmVyc2lvbgogICAgICAgICAgICAgICAgaWYgKCdzZWxmLnZlcnNpb24nID09PSAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJG5ld0xpbmtzW10gPSBuZXcgTGluaygkbGluay0+Z2V0U291cmNlKCksICRsaW5rLT5nZXRUYXJnZXQoKSwgJGNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgnPScsICR0aGlzLT52ZXJzaW9uKSwgJGxpbmtUeXBlLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQtPnNldFByZXR0eVN0cmluZygkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxpbmtzID0gYXJyYXlfbWVyZ2UoJGxpbmtzLCAkbmV3TGlua3MpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkaW5kZXggPT4gJGxpbmspIHsKICAgICAgICAgICAgICAgIGlmICgnc2VsZi52ZXJzaW9uJyA9PT0gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkbGlua1R5cGUgPT09IExpbms6OlRZUEVfUkVRVUlSRSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aGFzU2VsZlZlcnNpb25SZXF1aXJlcyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRsaW5rc1skaW5kZXhdID0gbmV3IExpbmsoJGxpbmstPmdldFNvdXJjZSgpLCAkbGluay0+Z2V0VGFyZ2V0KCksICRjb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz0nLCAkdGhpcy0+dmVyc2lvbiksICRsaW5rVHlwZSwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50LT5zZXRQcmV0dHlTdHJpbmcoJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxpbmtzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNTZWxmVmVyc2lvblJlcXVpcmVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc1NlbGZWZXJzaW9uUmVxdWlyZXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiBwYXJlbnQ6Ol9fdG9TdHJpbmcoKS4nICgnLigkdGhpcy0+cm9vdFBhY2thZ2VBbGlhcyA/ICdyb290ICcgOiAnJykuICdhbGlhcyBvZiAnLiR0aGlzLT5hbGlhc09mLT5nZXRWZXJzaW9uKCkuJyknOwogICAgfQoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIFdyYXBwZXJzIGFyb3VuZCB0aGUgYWxpYXNlZCBwYWNrYWdlICoKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0VHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYXJnZXREaXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0VGFyZ2V0RGlyKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4dHJhKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldEV4dHJhKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEluc3RhbGxhdGlvblNvdXJjZSgkdHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0SW5zdGFsbGF0aW9uU291cmNlKCR0eXBlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGF0aW9uU291cmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldEluc3RhbGxhdGlvblNvdXJjZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFNvdXJjZVR5cGUoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFNvdXJjZVVybCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VVcmxzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFNvdXJjZVVybHMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlUmVmZXJlbmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFNvdXJjZVJlZmVyZW5jZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VSZWZlcmVuY2UoJHJlZmVyZW5jZSkKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0U291cmNlUmVmZXJlbmNlKCRyZWZlcmVuY2UpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VNaXJyb3JzKCRtaXJyb3JzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRTb3VyY2VNaXJyb3JzKCRtaXJyb3JzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlTWlycm9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRTb3VyY2VNaXJyb3JzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldERpc3RUeXBlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0RGlzdFVybCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VXJscygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXREaXN0VXJscygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0UmVmZXJlbmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldERpc3RSZWZlcmVuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFJlZmVyZW5jZSgkcmVmZXJlbmNlKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXREaXN0UmVmZXJlbmNlKCRyZWZlcmVuY2UpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0U2hhMUNoZWNrc3VtKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldERpc3RTaGExQ2hlY2tzdW0oKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhbnNwb3J0T3B0aW9ucyhhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0VHJhbnNwb3J0T3B0aW9ucygkb3B0aW9ucyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFRyYW5zcG9ydE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXN0TWlycm9ycygkbWlycm9ycykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0RGlzdE1pcnJvcnMoJG1pcnJvcnMpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0TWlycm9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXREaXN0TWlycm9ycygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvbG9hZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBdXRvbG9hZCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXZBdXRvbG9hZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXREZXZBdXRvbG9hZCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbmNsdWRlUGF0aHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0SW5jbHVkZVBhdGhzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlbGVhc2VEYXRlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFJlbGVhc2VEYXRlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEJpbmFyaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldEJpbmFyaWVzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1Z2dlc3RzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFN1Z2dlc3RzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldE5vdGlmaWNhdGlvblVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXROb3RpZmljYXRpb25VcmwoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWZhdWx0QnJhbmNoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmlzRGVmYXVsdEJyYW5jaCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXN0VXJsKCR1cmwpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldERpc3RVcmwoJHVybCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RUeXBlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXREaXN0VHlwZSgkdHlwZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRyZWZlcmVuY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRyZWZlcmVuY2UpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxMb2NrQXJyYXlSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXEFycmF5TG9hZGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxHaXQgYXMgR2l0VXRpbDsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgU2VsZFxKc29uTGludFxQYXJzaW5nRXhjZXB0aW9uOwoKLyoqCiAqIFJlYWRzL3dyaXRlcyBwcm9qZWN0IGxvY2tmaWxlIChjb21wb3Nlci5sb2NrKS4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNoaXYgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgTG9ja2VyCnsKICAgIC8qKiBAdmFyIEpzb25GaWxlICovCiAgICBwcml2YXRlICRsb2NrRmlsZTsKICAgIC8qKiBAdmFyIEluc3RhbGxhdGlvbk1hbmFnZXIgKi8KICAgIHByaXZhdGUgJGluc3RhbGxhdGlvbk1hbmFnZXI7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGhhc2g7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNvbnRlbnRIYXNoOwogICAgLyoqIEB2YXIgQXJyYXlMb2FkZXIgKi8KICAgIHByaXZhdGUgJGxvYWRlcjsKICAgIC8qKiBAdmFyIEFycmF5RHVtcGVyICovCiAgICBwcml2YXRlICRkdW1wZXI7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByaXZhdGUgJHByb2Nlc3M7CiAgICAvKiogQHZhciBtaXhlZFtdfG51bGwgKi8KICAgIHByaXZhdGUgJGxvY2tEYXRhQ2FjaGUgPSBudWxsOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkdmlydHVhbEZpbGVXcml0dGVuID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBwYWNrYWdlcyBsb2NrZXIuCiAgICAgKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gSnNvbkZpbGUgICAgICAgICAgICAkbG9ja0ZpbGUgICAgICAgICAgICAgbG9ja2ZpbGUgbG9hZGVyCiAgICAgKiBAcGFyYW0gSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlciAgaW5zdGFsbGF0aW9uIG1hbmFnZXIgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICRjb21wb3NlckZpbGVDb250ZW50cyBUaGUgY29udGVudHMgb2YgdGhlIGNvbXBvc2VyIGZpbGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgSnNvbkZpbGUgJGxvY2tGaWxlLCBJbnN0YWxsYXRpb25NYW5hZ2VyICRpbnN0YWxsYXRpb25NYW5hZ2VyLCAkY29tcG9zZXJGaWxlQ29udGVudHMsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2tGaWxlID0gJGxvY2tGaWxlOwogICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyID0gJGluc3RhbGxhdGlvbk1hbmFnZXI7CiAgICAgICAgJHRoaXMtPmhhc2ggPSBtZDUoJGNvbXBvc2VyRmlsZUNvbnRlbnRzKTsKICAgICAgICAkdGhpcy0+Y29udGVudEhhc2ggPSBzZWxmOjpnZXRDb250ZW50SGFzaCgkY29tcG9zZXJGaWxlQ29udGVudHMpOwogICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIobnVsbCwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmR1bXBlciA9IG5ldyBBcnJheUR1bXBlcigpOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWQ1IGhhc2ggb2YgdGhlIHNvcnRlZCBjb250ZW50IG9mIHRoZSBjb21wb3NlciBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbXBvc2VyRmlsZUNvbnRlbnRzIFRoZSBjb250ZW50cyBvZiB0aGUgY29tcG9zZXIgZmlsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbnRlbnRIYXNoKCRjb21wb3NlckZpbGVDb250ZW50cykKICAgIHsKICAgICAgICAkY29udGVudCA9IGpzb25fZGVjb2RlKCRjb21wb3NlckZpbGVDb250ZW50cywgdHJ1ZSk7CgogICAgICAgICRyZWxldmFudEtleXMgPSBhcnJheSgKICAgICAgICAgICAgJ25hbWUnLAogICAgICAgICAgICAndmVyc2lvbicsCiAgICAgICAgICAgICdyZXF1aXJlJywKICAgICAgICAgICAgJ3JlcXVpcmUtZGV2JywKICAgICAgICAgICAgJ2NvbmZsaWN0JywKICAgICAgICAgICAgJ3JlcGxhY2UnLAogICAgICAgICAgICAncHJvdmlkZScsCiAgICAgICAgICAgICdtaW5pbXVtLXN0YWJpbGl0eScsCiAgICAgICAgICAgICdwcmVmZXItc3RhYmxlJywKICAgICAgICAgICAgJ3JlcG9zaXRvcmllcycsCiAgICAgICAgICAgICdleHRyYScsCiAgICAgICAgKTsKCiAgICAgICAgJHJlbGV2YW50Q29udGVudCA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKGFycmF5X2ludGVyc2VjdCgkcmVsZXZhbnRLZXlzLCBhcnJheV9rZXlzKCRjb250ZW50KSkgYXMgJGtleSkgewogICAgICAgICAgICAkcmVsZXZhbnRDb250ZW50WyRrZXldID0gJGNvbnRlbnRbJGtleV07CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkY29udGVudFsnY29uZmlnJ11bJ3BsYXRmb3JtJ10pKSB7CiAgICAgICAgICAgICRyZWxldmFudENvbnRlbnRbJ2NvbmZpZyddWydwbGF0Zm9ybSddID0gJGNvbnRlbnRbJ2NvbmZpZyddWydwbGF0Zm9ybSddOwogICAgICAgIH0KCiAgICAgICAga3NvcnQoJHJlbGV2YW50Q29udGVudCk7CgogICAgICAgIHJldHVybiBtZDUoanNvbl9lbmNvZGUoJHJlbGV2YW50Q29udGVudCkpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgbG9ja2VyIGhhcyBiZWVuIGxvY2tlZCAobG9ja2ZpbGUgZm91bmQpLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNMb2NrZWQoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnZpcnR1YWxGaWxlV3JpdHRlbiAmJiAhJHRoaXMtPmxvY2tGaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkZGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJGRhdGFbJ3BhY2thZ2VzJ10pOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGxvY2sgZmlsZSBpcyBzdGlsbCB1cCB0byBkYXRlIHdpdGggdGhlIGN1cnJlbnQgaGFzaAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNGcmVzaCgpCiAgICB7CiAgICAgICAgJGxvY2sgPSAkdGhpcy0+bG9ja0ZpbGUtPnJlYWQoKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkbG9ja1snY29udGVudC1oYXNoJ10pKSB7CiAgICAgICAgICAgIC8vIFRoZXJlIGlzIGEgY29udGVudCBoYXNoIGtleSwgdXNlIHRoYXQgaW5zdGVhZCBvZiB0aGUgZmlsZSBoYXNoCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29udGVudEhhc2ggPT09ICRsb2NrWydjb250ZW50LWhhc2gnXTsKICAgICAgICB9CgogICAgICAgIC8vIEJDIHN1cHBvcnQgZm9yIG9sZCBsb2NrIGZpbGVzIHdpdGhvdXQgY29udGVudC1oYXNoCiAgICAgICAgaWYgKCFlbXB0eSgkbG9ja1snaGFzaCddKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmhhc2ggPT09ICRsb2NrWydoYXNoJ107CiAgICAgICAgfQoKICAgICAgICAvLyBzaG91bGQgbm90IGJlIHJlYWNoZWQgdW5sZXNzIHRoZSBsb2NrIGZpbGUgaXMgY29ycnVwdGVkLCBzbyBhc3N1bWUgaXQncyBvdXQgb2YgZGF0ZQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNlYXJjaGVzIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGxvY2tlZCBwYWNrYWdlcywgcmV0cmlldmVkIGZyb20gcmVnaXN0ZXJlZCByZXBvc2l0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR3aXRoRGV2UmVxcyB0cnVlIHRvIHJldHJpZXZlIHRoZSBsb2NrZWQgZGV2IHBhY2thZ2VzCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIFxDb21wb3NlclxSZXBvc2l0b3J5XExvY2tBcnJheVJlcG9zaXRvcnkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2tlZFJlcG9zaXRvcnkoJHdpdGhEZXZSZXFzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGxvY2tEYXRhID0gJHRoaXMtPmdldExvY2tEYXRhKCk7CiAgICAgICAgJHBhY2thZ2VzID0gbmV3IExvY2tBcnJheVJlcG9zaXRvcnkoKTsKCiAgICAgICAgJGxvY2tlZFBhY2thZ2VzID0gJGxvY2tEYXRhWydwYWNrYWdlcyddOwogICAgICAgIGlmICgkd2l0aERldlJlcXMpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRsb2NrRGF0YVsncGFja2FnZXMtZGV2J10pKSB7CiAgICAgICAgICAgICAgICAkbG9ja2VkUGFja2FnZXMgPSBhcnJheV9tZXJnZSgkbG9ja2VkUGFja2FnZXMsICRsb2NrRGF0YVsncGFja2FnZXMtZGV2J10pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgbG9jayBmaWxlIGRvZXMgbm90IGNvbnRhaW4gcmVxdWlyZS1kZXYgaW5mb3JtYXRpb24sIHJ1biBpbnN0YWxsIHdpdGggdGhlIC0tbm8tZGV2IG9wdGlvbiBvciBkZWxldGUgaXQgYW5kIHJ1biBjb21wb3NlciB1cGRhdGUgdG8gZ2VuZXJhdGUgYSBuZXcgbG9jayBmaWxlLicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZW1wdHkoJGxvY2tlZFBhY2thZ2VzKSkgewogICAgICAgICAgICByZXR1cm4gJHBhY2thZ2VzOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRsb2NrZWRQYWNrYWdlc1swXVsnbmFtZSddKSkgewogICAgICAgICAgICAkcGFja2FnZUJ5TmFtZSA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NrZWRQYWNrYWdlcyBhcyAkaW5mbykgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+bG9hZGVyLT5sb2FkKCRpbmZvKTsKICAgICAgICAgICAgICAgICRwYWNrYWdlcy0+YWRkUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgICAgICAgICAkcGFja2FnZUJ5TmFtZVskcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRwYWNrYWdlOwoKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlQnlOYW1lWyRwYWNrYWdlLT5nZXRBbGlhc09mKCktPmdldE5hbWUoKV0gPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJGxvY2tEYXRhWydhbGlhc2VzJ10pKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbG9ja0RhdGFbJ2FsaWFzZXMnXSBhcyAkYWxpYXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VCeU5hbWVbJGFsaWFzWydwYWNrYWdlJ11dKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYWxpYXNQa2cgPSBuZXcgQ29tcGxldGVBbGlhc1BhY2thZ2UoJHBhY2thZ2VCeU5hbWVbJGFsaWFzWydwYWNrYWdlJ11dLCAkYWxpYXNbJ2FsaWFzX25vcm1hbGl6ZWQnXSwgJGFsaWFzWydhbGlhcyddKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGFsaWFzUGtnLT5zZXRSb290UGFja2FnZUFsaWFzKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXMtPmFkZFBhY2thZ2UoJGFsaWFzUGtnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1lvdXIgY29tcG9zZXIubG9jayBpcyBpbnZhbGlkLiBSdW4gImNvbXBvc2VyIHVwZGF0ZSIgdG8gZ2VuZXJhdGUgYSBuZXcgb25lLicpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXSBOYW1lcyBvZiBkZXBlbmRlbmNpZXMgaW5zdGFsbGVkIHRocm91Z2ggcmVxdWlyZS1kZXYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldlBhY2thZ2VOYW1lcygpCiAgICB7CiAgICAgICAgJG5hbWVzID0gYXJyYXkoKTsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKICAgICAgICBpZiAoaXNzZXQoJGxvY2tEYXRhWydwYWNrYWdlcy1kZXYnXSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tEYXRhWydwYWNrYWdlcy1kZXYnXSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJG5hbWVzW10gPSBzdHJ0b2xvd2VyKCRwYWNrYWdlWyduYW1lJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5hbWVzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIHN0b3JlZCBpbiB0aGUgbG9jayBmaWxlCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgJHdpdGhEZXZSZXFzIGlmIHRydWUsIHRoZSBwbGF0Zm9ybSByZXF1aXJlbWVudHMgZnJvbSB0aGUgcmVxdWlyZS1kZXYgYmxvY2sgYXJlIGFsc28gcmV0dXJuZWQKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXFBhY2thZ2VcTGlua1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQbGF0Zm9ybVJlcXVpcmVtZW50cygkd2l0aERldlJlcXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKICAgICAgICAkcmVxdWlyZW1lbnRzID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkbG9ja0RhdGFbJ3BsYXRmb3JtJ10pKSB7CiAgICAgICAgICAgICRyZXF1aXJlbWVudHMgPSAkdGhpcy0+bG9hZGVyLT5wYXJzZUxpbmtzKAogICAgICAgICAgICAgICAgJ19fcm9vdF9fJywKICAgICAgICAgICAgICAgICcxLjAuMCcsCiAgICAgICAgICAgICAgICBMaW5rOjpUWVBFX1JFUVVJUkUsCiAgICAgICAgICAgICAgICBpc3NldCgkbG9ja0RhdGFbJ3BsYXRmb3JtJ10pID8gJGxvY2tEYXRhWydwbGF0Zm9ybSddIDogYXJyYXkoKQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR3aXRoRGV2UmVxcyAmJiAhZW1wdHkoJGxvY2tEYXRhWydwbGF0Zm9ybS1kZXYnXSkpIHsKICAgICAgICAgICAgJGRldlJlcXVpcmVtZW50cyA9ICR0aGlzLT5sb2FkZXItPnBhcnNlTGlua3MoCiAgICAgICAgICAgICAgICAnX19yb290X18nLAogICAgICAgICAgICAgICAgJzEuMC4wJywKICAgICAgICAgICAgICAgIExpbms6OlRZUEVfUkVRVUlSRSwKICAgICAgICAgICAgICAgIGlzc2V0KCRsb2NrRGF0YVsncGxhdGZvcm0tZGV2J10pID8gJGxvY2tEYXRhWydwbGF0Zm9ybS1kZXYnXSA6IGFycmF5KCkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRyZXF1aXJlbWVudHMgPSBhcnJheV9tZXJnZSgkcmVxdWlyZW1lbnRzLCAkZGV2UmVxdWlyZW1lbnRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVxdWlyZW1lbnRzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1pbmltdW1TdGFiaWxpdHkoKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJGxvY2tEYXRhWydtaW5pbXVtLXN0YWJpbGl0eSddKSA/ICRsb2NrRGF0YVsnbWluaW11bS1zdGFiaWxpdHknXSA6ICdzdGFibGUnOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eUZsYWdzKCkKICAgIHsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKCiAgICAgICAgcmV0dXJuIGlzc2V0KCRsb2NrRGF0YVsnc3RhYmlsaXR5LWZsYWdzJ10pID8gJGxvY2tEYXRhWydzdGFiaWxpdHktZmxhZ3MnXSA6IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2x8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZmVyU3RhYmxlKCkKICAgIHsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKCiAgICAgICAgLy8gcmV0dXJuIG51bGwgaWYgbm90IHNldCB0byBhbGxvdyBjYWxsZXIgbG9naWMgdG8gY2hvb3NlIHRoZQogICAgICAgIC8vIHJpZ2h0IGJlaGF2aW9yIHNpbmNlIG9sZCBsb2NrIGZpbGVzIGhhdmUgbm8gcHJlZmVyLXN0YWJsZQogICAgICAgIHJldHVybiBpc3NldCgkbG9ja0RhdGFbJ3ByZWZlci1zdGFibGUnXSkgPyAkbG9ja0RhdGFbJ3ByZWZlci1zdGFibGUnXSA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2x8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZmVyTG93ZXN0KCkKICAgIHsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKCiAgICAgICAgLy8gcmV0dXJuIG51bGwgaWYgbm90IHNldCB0byBhbGxvdyBjYWxsZXIgbG9naWMgdG8gY2hvb3NlIHRoZQogICAgICAgIC8vIHJpZ2h0IGJlaGF2aW9yIHNpbmNlIG9sZCBsb2NrIGZpbGVzIGhhdmUgbm8gcHJlZmVyLWxvd2VzdAogICAgICAgIHJldHVybiBpc3NldCgkbG9ja0RhdGFbJ3ByZWZlci1sb3dlc3QnXSkgPyAkbG9ja0RhdGFbJ3ByZWZlci1sb3dlc3QnXSA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGxhdGZvcm1PdmVycmlkZXMoKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJGxvY2tEYXRhWydwbGF0Zm9ybS1vdmVycmlkZXMnXSkgPyAkbG9ja0RhdGFbJ3BsYXRmb3JtLW92ZXJyaWRlcyddIDogYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nW11bXQogICAgICoKICAgICAqIEBwaHBzdGFuLXJldHVybiBsaXN0PGFycmF5e3BhY2thZ2U6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNlcygpCiAgICB7CiAgICAgICAgJGxvY2tEYXRhID0gJHRoaXMtPmdldExvY2tEYXRhKCk7CgogICAgICAgIHJldHVybiBpc3NldCgkbG9ja0RhdGFbJ2FsaWFzZXMnXSkgPyAkbG9ja0RhdGFbJ2FsaWFzZXMnXSA6IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgbWl4ZWQ+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NrRGF0YSgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5sb2NrRGF0YUNhY2hlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bG9ja0RhdGFDYWNoZTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmxvY2tGaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdObyBsb2NrZmlsZSBmb3VuZC4gVW5hYmxlIHRvIHJlYWQgbG9ja2VkIHBhY2thZ2VzJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmxvY2tEYXRhQ2FjaGUgPSAkdGhpcy0+bG9ja0ZpbGUtPnJlYWQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvY2tzIHByb3ZpZGVkIGRhdGEgaW50byBsb2NrZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdICAgICAgJHBhY2thZ2VzICAgICAgICAgIGFycmF5IG9mIHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdfG51bGwgJGRldlBhY2thZ2VzICAgICAgIGFycmF5IG9mIGRldiBwYWNrYWdlcyBvciBudWxsIGlmIGluc3RhbGxlZCB3aXRob3V0IC0tZGV2CiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICAgJHBsYXRmb3JtUmVxcyAgICAgIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBjb25zdHJhaW50IGZvciByZXF1aXJlZCBwbGF0Zm9ybSBwYWNrYWdlcwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAgICRwbGF0Zm9ybURldlJlcXMgICBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gY29uc3RyYWludCBmb3IgZGV2LXJlcXVpcmVkIHBsYXRmb3JtIHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gc3RyaW5nW11bXSAgICAgICAgICAgICAgJGFsaWFzZXMgICAgICAgICAgIGFycmF5IG9mIGFsaWFzZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAkbWluaW11bVN0YWJpbGl0eQogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgaW50PiAgICAgICRzdGFiaWxpdHlGbGFncwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAgICRwcmVmZXJTdGFibGUKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAkcHJlZmVyTG93ZXN0CiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICAgJHBsYXRmb3JtT3ZlcnJpZGVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgJHdyaXRlICAgICAgICAgICAgIFdoZXRoZXIgdG8gYWN0dWFsbHkgd3JpdGUgZGF0YSB0byBkaXNrLCB1c2VmdWwgaW4gdGVzdHMgYW5kIGZvciAtLWRyeS1ydW4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBsaXN0PGFycmF5e3BhY2thZ2U6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9PiAkYWxpYXNlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9ja0RhdGEoYXJyYXkgJHBhY2thZ2VzLCAkZGV2UGFja2FnZXMsIGFycmF5ICRwbGF0Zm9ybVJlcXMsICRwbGF0Zm9ybURldlJlcXMsIGFycmF5ICRhbGlhc2VzLCAkbWluaW11bVN0YWJpbGl0eSwgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCAkcHJlZmVyU3RhYmxlLCAkcHJlZmVyTG93ZXN0LCBhcnJheSAkcGxhdGZvcm1PdmVycmlkZXMsICR3cml0ZSA9IHRydWUpCiAgICB7CiAgICAgICAgLy8ga2VlcCBvbGQgZGVmYXVsdCBicmFuY2ggbmFtZXMgbm9ybWFsaXplZCB0byBERUZBVUxUX0JSQU5DSF9BTElBUyBmb3IgQkMgYXMgdGhhdCBpcyBob3cgQ29tcG9zZXIgMSBvdXRwdXRzIHRoZSBsb2NrIGZpbGUKICAgICAgICAvLyB3aGVuIGxvYWRpbmcgdGhlIGxvY2sgZmlsZSB0aGUgdmVyc2lvbiBpcyBhbnl3YXkgaWdub3JlZCBpbiBDb21wb3NlciAyLCBzbyBpdCBoYXMgbm8gYWR2ZXJzZSBlZmZlY3QKICAgICAgICAkYWxpYXNlcyA9IGFycmF5X21hcChmdW5jdGlvbiAoJGFsaWFzKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkYWxpYXNbJ3ZlcnNpb24nXSwgYXJyYXkoJ2Rldi1tYXN0ZXInLCAnZGV2LXRydW5rJywgJ2Rldi1kZWZhdWx0JyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkYWxpYXNbJ3ZlcnNpb24nXSA9IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGFsaWFzOwogICAgICAgIH0sICRhbGlhc2VzKTsKCiAgICAgICAgJGxvY2sgPSBhcnJheSgKICAgICAgICAgICAgJ19yZWFkbWUnID0+IGFycmF5KCdUaGlzIGZpbGUgbG9ja3MgdGhlIGRlcGVuZGVuY2llcyBvZiB5b3VyIHByb2plY3QgdG8gYSBrbm93biBzdGF0ZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUmVhZCBtb3JlIGFib3V0IGl0IGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMS1iYXNpYy11c2FnZS5tZCNpbnN0YWxsaW5nLWRlcGVuZGVuY2llcycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhpcyBmaWxlIGlzIEBnZW5lcicuJ2F0ZWQgYXV0b21hdGljYWxseScsICksCiAgICAgICAgICAgICdjb250ZW50LWhhc2gnID0+ICR0aGlzLT5jb250ZW50SGFzaCwKICAgICAgICAgICAgJ3BhY2thZ2VzJyA9PiBudWxsLAogICAgICAgICAgICAncGFja2FnZXMtZGV2JyA9PiBudWxsLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gJGFsaWFzZXMsCiAgICAgICAgICAgICdtaW5pbXVtLXN0YWJpbGl0eScgPT4gJG1pbmltdW1TdGFiaWxpdHksCiAgICAgICAgICAgICdzdGFiaWxpdHktZmxhZ3MnID0+ICRzdGFiaWxpdHlGbGFncywKICAgICAgICAgICAgJ3ByZWZlci1zdGFibGUnID0+ICRwcmVmZXJTdGFibGUsCiAgICAgICAgICAgICdwcmVmZXItbG93ZXN0JyA9PiAkcHJlZmVyTG93ZXN0LAogICAgICAgICk7CgogICAgICAgICRsb2NrWydwYWNrYWdlcyddID0gJHRoaXMtPmxvY2tQYWNrYWdlcygkcGFja2FnZXMpOwogICAgICAgIGlmIChudWxsICE9PSAkZGV2UGFja2FnZXMpIHsKICAgICAgICAgICAgJGxvY2tbJ3BhY2thZ2VzLWRldiddID0gJHRoaXMtPmxvY2tQYWNrYWdlcygkZGV2UGFja2FnZXMpOwogICAgICAgIH0KCiAgICAgICAgJGxvY2tbJ3BsYXRmb3JtJ10gPSAkcGxhdGZvcm1SZXFzOwogICAgICAgICRsb2NrWydwbGF0Zm9ybS1kZXYnXSA9ICRwbGF0Zm9ybURldlJlcXM7CiAgICAgICAgaWYgKCRwbGF0Zm9ybU92ZXJyaWRlcykgewogICAgICAgICAgICAkbG9ja1sncGxhdGZvcm0tb3ZlcnJpZGVzJ10gPSAkcGxhdGZvcm1PdmVycmlkZXM7CiAgICAgICAgfQogICAgICAgICRsb2NrWydwbHVnaW4tYXBpLXZlcnNpb24nXSA9IFBsdWdpbkludGVyZmFjZTo6UExVR0lOX0FQSV9WRVJTSU9OOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkaXNMb2NrZWQgPSAkdGhpcy0+aXNMb2NrZWQoKTsKICAgICAgICB9IGNhdGNoIChQYXJzaW5nRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRpc0xvY2tlZCA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoISRpc0xvY2tlZCB8fCAkbG9jayAhPT0gJHRoaXMtPmdldExvY2tEYXRhKCkpIHsKICAgICAgICAgICAgaWYgKCR3cml0ZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmxvY2tGaWxlLT53cml0ZSgkbG9jayk7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9ja0RhdGFDYWNoZSA9IG51bGw7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmlydHVhbEZpbGVXcml0dGVuID0gZmFsc2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmlydHVhbEZpbGVXcml0dGVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5sb2NrRGF0YUNhY2hlID0gSnNvbkZpbGU6OnBhcnNlSnNvbihKc29uRmlsZTo6ZW5jb2RlKCRsb2NrLCA0NDggJiBKc29uRmlsZTo6SlNPTl9QUkVUVFlfUFJJTlQpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdICRwYWNrYWdlcwogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWRbXVtdCiAgICAgKgogICAgICogQHBocHN0YW4tcmV0dXJuIGxpc3Q8YXJyYXk8c3RyaW5nLCBtaXhlZD4+CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbG9ja1BhY2thZ2VzKGFycmF5ICRwYWNrYWdlcykKICAgIHsKICAgICAgICAkbG9ja2VkID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKICAgICAgICAgICAgJHZlcnNpb24gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwoKICAgICAgICAgICAgaWYgKCEkbmFtZSB8fCAhJHZlcnNpb24pIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnUGFja2FnZSAiJXMiIGhhcyBubyB2ZXJzaW9uIG9yIG5hbWUgYW5kIGNhbiBub3QgYmUgbG9ja2VkJywKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZQogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzcGVjID0gJHRoaXMtPmR1bXBlci0+ZHVtcCgkcGFja2FnZSk7CiAgICAgICAgICAgIHVuc2V0KCRzcGVjWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSk7CgogICAgICAgICAgICAvLyBhbHdheXMgbW92ZSB0aW1lIHRvIHRoZSBlbmQgb2YgdGhlIHBhY2thZ2UgZGVmaW5pdGlvbgogICAgICAgICAgICAkdGltZSA9IGlzc2V0KCRzcGVjWyd0aW1lJ10pID8gJHNwZWNbJ3RpbWUnXSA6IG51bGw7CiAgICAgICAgICAgIHVuc2V0KCRzcGVjWyd0aW1lJ10pOwogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmlzRGV2KCkgJiYgJHBhY2thZ2UtPmdldEluc3RhbGxhdGlvblNvdXJjZSgpID09PSAnc291cmNlJykgewogICAgICAgICAgICAgICAgLy8gdXNlIHRoZSBleGFjdCBjb21taXQgdGltZSBvZiB0aGUgY3VycmVudCByZWZlcmVuY2UgaWYgaXQncyBhIGRldiBwYWNrYWdlCiAgICAgICAgICAgICAgICAkdGltZSA9ICR0aGlzLT5nZXRQYWNrYWdlVGltZSgkcGFja2FnZSkgPzogJHRpbWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bGwgIT09ICR0aW1lKSB7CiAgICAgICAgICAgICAgICAkc3BlY1sndGltZSddID0gJHRpbWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVuc2V0KCRzcGVjWydpbnN0YWxsYXRpb24tc291cmNlJ10pOwoKICAgICAgICAgICAgJGxvY2tlZFtdID0gJHNwZWM7CiAgICAgICAgfQoKICAgICAgICB1c29ydCgkbG9ja2VkLCBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgICRjb21wYXJpc29uID0gc3RyY21wKCRhWyduYW1lJ10sICRiWyduYW1lJ10pOwoKICAgICAgICAgICAgaWYgKDAgIT09ICRjb21wYXJpc29uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGNvbXBhcmlzb247CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIGl0IGlzIHRoZSBzYW1lIHBhY2thZ2UsIGNvbXBhcmUgdGhlIHZlcnNpb25zIHRvIG1ha2UgdGhlIG9yZGVyIGRldGVybWluaXN0aWMKICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYVsndmVyc2lvbiddLCAkYlsndmVyc2lvbiddKTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRsb2NrZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlcydzIGRhdGV0aW1lIGZvciBpdHMgc291cmNlIHJlZmVyZW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgVGhlIHBhY2thZ2UgdG8gc2Nhbi4KICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgICAgICBUaGUgZm9ybWF0dGVkIGRhdGV0aW1lIG9yIG51bGwgaWYgbm9uZSB3YXMgZm91bmQuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UGFja2FnZVRpbWUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkcGF0aCA9IHJlYWxwYXRoKCR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSkpOwogICAgICAgICRzb3VyY2VUeXBlID0gJHBhY2thZ2UtPmdldFNvdXJjZVR5cGUoKTsKICAgICAgICAkZGF0ZXRpbWUgPSBudWxsOwoKICAgICAgICBpZiAoJHBhdGggJiYgaW5fYXJyYXkoJHNvdXJjZVR5cGUsIGFycmF5KCdnaXQnLCAnaGcnKSkpIHsKICAgICAgICAgICAgJHNvdXJjZVJlZiA9ICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSA/OiAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpOwogICAgICAgICAgICBzd2l0Y2ggKCRzb3VyY2VUeXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlICdnaXQnOgogICAgICAgICAgICAgICAgICAgIEdpdFV0aWw6OmNsZWFuRW52KCk7CgogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGxvZyAtbjEgLS1wcmV0dHk9JWN0ICcuUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHNvdXJjZVJlZikuR2l0VXRpbDo6Z2V0Tm9TaG93U2lnbmF0dXJlRmxhZygkdGhpcy0+cHJvY2VzcyksICRvdXRwdXQsICRwYXRoKSAmJiBQcmVnOjppc01hdGNoKCd7XlxzKlxkK1xzKiR9JywgJG91dHB1dCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGV0aW1lID0gbmV3IFxEYXRlVGltZSgnQCcudHJpbSgkb3V0cHV0KSwgbmV3IFxEYXRlVGltZVpvbmUoJ1VUQycpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnaGcnOgogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnaGcgbG9nIC0tdGVtcGxhdGUgIntkYXRlfGhnZGF0ZX0iIC1yICcuUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHNvdXJjZVJlZiksICRvdXRwdXQsICRwYXRoKSAmJiBQcmVnOjppc01hdGNoKCd7XlxzKihcZCspXHMqfScsICRvdXRwdXQsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGV0aW1lID0gbmV3IFxEYXRlVGltZSgnQCcuJG1hdGNoWzFdLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkYXRldGltZSA/ICRkYXRldGltZS0+Zm9ybWF0KERBVEVfUkZDMzMzOSkgOiBudWxsOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxVdGlsXENvbXBvc2VyTWlycm9yOwoKLyoqCiAqIENvcmUgcGFja2FnZSBkZWZpbml0aW9ucyB0aGF0IGFyZSBuZWVkZWQgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMgYW5kIGluc3RhbGwgcGFja2FnZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFBhY2thZ2UgZXh0ZW5kcyBCYXNlUGFja2FnZQp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdHlwZTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdGFyZ2V0RGlyOwogICAgLyoqIEB2YXIgJ3NvdXJjZSd8J2Rpc3QnfG51bGwgKi8KICAgIHByb3RlY3RlZCAkaW5zdGFsbGF0aW9uU291cmNlOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRzb3VyY2VUeXBlOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRzb3VyY2VVcmw7CiAgICAvKiogQHZhciA/c3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHNvdXJjZVJlZmVyZW5jZTsKICAgIC8qKiBAdmFyID9hcnJheTxpbnQsIGFycmF5e3VybDogc3RyaW5nLCBwcmVmZXJyZWQ6IGJvb2x9PiAqLwogICAgcHJvdGVjdGVkICRzb3VyY2VNaXJyb3JzOwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRkaXN0VHlwZTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkZGlzdFVybDsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkZGlzdFJlZmVyZW5jZTsKICAgIC8qKiBAdmFyID9zdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkZGlzdFNoYTFDaGVja3N1bTsKICAgIC8qKiBAdmFyID9hcnJheTxpbnQsIGFycmF5e3VybDogc3RyaW5nLCBwcmVmZXJyZWQ6IGJvb2x9PiAqLwogICAgcHJvdGVjdGVkICRkaXN0TWlycm9yczsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICR2ZXJzaW9uOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHByZXR0eVZlcnNpb247CiAgICAvKiogQHZhciA/XERhdGVUaW1lICovCiAgICBwcm90ZWN0ZWQgJHJlbGVhc2VEYXRlOwogICAgLyoqIEB2YXIgbWl4ZWRbXSAqLwogICAgcHJvdGVjdGVkICRleHRyYSA9IGFycmF5KCk7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJvdGVjdGVkICRiaW5hcmllcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcm90ZWN0ZWQgJGRldjsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBwaHBzdGFuLXZhciAnc3RhYmxlJ3wnUkMnfCdiZXRhJ3wnYWxwaGEnfCdkZXYnCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3RhYmlsaXR5OwogICAgLyoqIEB2YXIgP3N0cmluZyAqLwogICAgcHJvdGVjdGVkICRub3RpZmljYXRpb25Vcmw7CgogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBMaW5rPiAqLwogICAgcHJvdGVjdGVkICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIExpbms+ICovCiAgICBwcm90ZWN0ZWQgJGNvbmZsaWN0cyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIExpbms+ICovCiAgICBwcm90ZWN0ZWQgJHByb3ZpZGVzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgTGluaz4gKi8KICAgIHByb3RlY3RlZCAkcmVwbGFjZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBMaW5rPiAqLwogICAgcHJvdGVjdGVkICRkZXZSZXF1aXJlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gKi8KICAgIHByb3RlY3RlZCAkc3VnZ2VzdHMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXl7cHNyLTA/OiBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXT4sIHBzci00PzogYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW10+LCBjbGFzc21hcD86IGxpc3Q8c3RyaW5nPiwgZmlsZXM/OiBsaXN0PHN0cmluZz59ICovCiAgICBwcm90ZWN0ZWQgJGF1dG9sb2FkID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5e3Bzci0wPzogYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW10+LCBwc3ItND86IGFycmF5PHN0cmluZywgc3RyaW5nfHN0cmluZ1tdPiwgY2xhc3NtYXA/OiBsaXN0PHN0cmluZz4sIGZpbGVzPzogbGlzdDxzdHJpbmc+fSAqLwogICAgcHJvdGVjdGVkICRkZXZBdXRvbG9hZCA9IGFycmF5KCk7CiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJvdGVjdGVkICRpbmNsdWRlUGF0aHMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRpc0RlZmF1bHRCcmFuY2ggPSBmYWxzZTsKICAgIC8qKiBAdmFyIG1peGVkW10gKi8KICAgIHByb3RlY3RlZCAkdHJhbnNwb3J0T3B0aW9ucyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IGluIG1lbW9yeSBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgICAgICAgICAgVGhlIHBhY2thZ2UncyBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uICAgICAgIFRoZSBwYWNrYWdlJ3MgdmVyc2lvbgogICAgICogQHBhcmFtIHN0cmluZyAkcHJldHR5VmVyc2lvbiBUaGUgcGFja2FnZSdzIG5vbi1ub3JtYWxpemVkIHZlcnNpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbmFtZSk7CgogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgJHRoaXMtPnByZXR0eVZlcnNpb24gPSAkcHJldHR5VmVyc2lvbjsKCiAgICAgICAgJHRoaXMtPnN0YWJpbGl0eSA9IFZlcnNpb25QYXJzZXI6OnBhcnNlU3RhYmlsaXR5KCR2ZXJzaW9uKTsKICAgICAgICAkdGhpcy0+ZGV2ID0gJHRoaXMtPnN0YWJpbGl0eSA9PT0gJ2Rldic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZXYoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHlwZSgkdHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+dHlwZSA9ICR0eXBlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHlwZSA/OiAnbGlicmFyeSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YWJpbGl0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldERpcgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGFyZ2V0RGlyKCR0YXJnZXREaXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnRhcmdldERpciA9ICR0YXJnZXREaXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0RGlyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnRhcmdldERpcikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBsdHJpbShQcmVnOjpyZXBsYWNlKCd7ICg/Ol58W1xcXFwvXSspIFwuXC4/ICg/OltcXFxcL10rfCQpICg/OlwuXC4/ICg/OltcXFxcL10rfCQpICkqfXgnLCAnLycsICR0aGlzLT50YXJnZXREaXIpLCAnLycpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG1peGVkW10gJGV4dHJhCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHRyYShhcnJheSAkZXh0cmEpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4dHJhID0gJGV4dHJhOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4dHJhKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4dHJhOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRiaW5hcmllcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QmluYXJpZXMoYXJyYXkgJGJpbmFyaWVzKQogICAgewogICAgICAgICR0aGlzLT5iaW5hcmllcyA9ICRiaW5hcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCaW5hcmllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5iaW5hcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnN0YWxsYXRpb25Tb3VyY2UoJHR5cGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmluc3RhbGxhdGlvblNvdXJjZSA9ICR0eXBlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxhdGlvblNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnN0YWxsYXRpb25Tb3VyY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VUeXBlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5zb3VyY2VUeXBlID0gJHR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlVHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2VUeXBlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VVcmwoJHVybCkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlVXJsID0gJHVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlVXJsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVmZXJlbmNlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VSZWZlcmVuY2UoJHJlZmVyZW5jZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlUmVmZXJlbmNlID0gJHJlZmVyZW5jZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VSZWZlcmVuY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlUmVmZXJlbmNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZU1pcnJvcnMoJG1pcnJvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPnNvdXJjZU1pcnJvcnMgPSAkbWlycm9yczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VNaXJyb3JzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNvdXJjZU1pcnJvcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlVXJscygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRVcmxzKCR0aGlzLT5zb3VyY2VVcmwsICR0aGlzLT5zb3VyY2VNaXJyb3JzLCAkdGhpcy0+c291cmNlUmVmZXJlbmNlLCAkdGhpcy0+c291cmNlVHlwZSwgJ3NvdXJjZScpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFR5cGUoJHR5cGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmRpc3RUeXBlID0gJHR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGlzdFR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RVcmwoJHVybCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzdFVybCA9ICR1cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kaXN0VXJsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVmZXJlbmNlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXN0UmVmZXJlbmNlKCRyZWZlcmVuY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmRpc3RSZWZlcmVuY2UgPSAkcmVmZXJlbmNlOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RSZWZlcmVuY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGlzdFJlZmVyZW5jZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNoYTFjaGVja3N1bQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFNoYTFDaGVja3N1bSgkc2hhMWNoZWNrc3VtKQogICAgewogICAgICAgICR0aGlzLT5kaXN0U2hhMUNoZWNrc3VtID0gJHNoYTFjaGVja3N1bTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0U2hhMUNoZWNrc3VtKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRpc3RTaGExQ2hlY2tzdW07CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdE1pcnJvcnMoJG1pcnJvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmRpc3RNaXJyb3JzID0gJG1pcnJvcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdE1pcnJvcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGlzdE1pcnJvcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFVybHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VXJscygkdGhpcy0+ZGlzdFVybCwgJHRoaXMtPmRpc3RNaXJyb3JzLCAkdGhpcy0+ZGlzdFJlZmVyZW5jZSwgJHRoaXMtPmRpc3RUeXBlLCAnZGlzdCcpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRyYW5zcG9ydE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHJhbnNwb3J0T3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFuc3BvcnRPcHRpb25zKGFycmF5ICRvcHRpb25zKQogICAgewogICAgICAgICR0aGlzLT50cmFuc3BvcnRPcHRpb25zID0gJG9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52ZXJzaW9uOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJldHR5VmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVsZWFzZURhdGUKICAgICAqCiAgICAgKiBAcGFyYW0gXERhdGVUaW1lICRyZWxlYXNlRGF0ZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVsZWFzZURhdGUoXERhdGVUaW1lICRyZWxlYXNlRGF0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+cmVsZWFzZURhdGUgPSAkcmVsZWFzZURhdGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVsZWFzZURhdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVsZWFzZURhdGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlcXVpcmVkIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgTGluaz4gJHJlcXVpcmVzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcXVpcmVzKGFycmF5ICRyZXF1aXJlcykKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHJlcXVpcmVzWzBdKSkgeyAvLyBAcGhwc3Rhbi1pZ25vcmUtbGluZQogICAgICAgICAgICAkcmVxdWlyZXMgPSAkdGhpcy0+Y29udmVydExpbmtzVG9NYXAoJHJlcXVpcmVzLCAnc2V0UmVxdWlyZXMnKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yZXF1aXJlcyA9ICRyZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXF1aXJlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgY29uZmxpY3RpbmcgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBMaW5rPiAkY29uZmxpY3RzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbmZsaWN0cyhhcnJheSAkY29uZmxpY3RzKQogICAgewogICAgICAgIGlmIChpc3NldCgkY29uZmxpY3RzWzBdKSkgeyAvLyBAcGhwc3Rhbi1pZ25vcmUtbGluZQogICAgICAgICAgICAkY29uZmxpY3RzID0gJHRoaXMtPmNvbnZlcnRMaW5rc1RvTWFwKCRjb25mbGljdHMsICdzZXRDb25mbGljdHMnKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb25mbGljdHMgPSAkY29uZmxpY3RzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBMaW5rPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmxpY3RzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmZsaWN0czsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcHJvdmlkZWQgdmlydHVhbCBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIExpbms+ICRwcm92aWRlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm92aWRlcyhhcnJheSAkcHJvdmlkZXMpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRwcm92aWRlc1swXSkpIHsgLy8gQHBocHN0YW4taWdub3JlLWxpbmUKICAgICAgICAgICAgJHByb3ZpZGVzID0gJHRoaXMtPmNvbnZlcnRMaW5rc1RvTWFwKCRwcm92aWRlcywgJ3NldFByb3ZpZGVzJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cHJvdmlkZXMgPSAkcHJvdmlkZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIExpbms+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm92aWRlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcGFja2FnZXMgdGhpcyBvbmUgcmVwbGFjZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBMaW5rPiAkcmVwbGFjZXMgQSBzZXQgb2YgcGFja2FnZSBsaW5rcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwbGFjZXMoYXJyYXkgJHJlcGxhY2VzKQogICAgewogICAgICAgIGlmIChpc3NldCgkcmVwbGFjZXNbMF0pKSB7IC8vIEBwaHBzdGFuLWlnbm9yZS1saW5lCiAgICAgICAgICAgICRyZXBsYWNlcyA9ICR0aGlzLT5jb252ZXJ0TGlua3NUb01hcCgkcmVwbGFjZXMsICdzZXRSZXBsYWNlcycpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJlcGxhY2VzID0gJHJlcGxhY2VzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBMaW5rPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwbGFjZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlY29tbWVuZGVkIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgTGluaz4gJGRldlJlcXVpcmVzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERldlJlcXVpcmVzKGFycmF5ICRkZXZSZXF1aXJlcykKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJGRldlJlcXVpcmVzWzBdKSkgeyAvLyBAcGhwc3Rhbi1pZ25vcmUtbGluZQogICAgICAgICAgICAkZGV2UmVxdWlyZXMgPSAkdGhpcy0+Y29udmVydExpbmtzVG9NYXAoJGRldlJlcXVpcmVzLCAnc2V0RGV2UmVxdWlyZXMnKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5kZXZSZXF1aXJlcyA9ICRkZXZSZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXZSZXF1aXJlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXZSZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgc3VnZ2VzdGVkIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkc3VnZ2VzdHMgQSBzZXQgb2YgcGFja2FnZSBuYW1lcy9jb21tZW50cwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3VnZ2VzdHMoYXJyYXkgJHN1Z2dlc3RzKQogICAgewogICAgICAgICR0aGlzLT5zdWdnZXN0cyA9ICRzdWdnZXN0czsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdWdnZXN0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdWdnZXN0czsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgYXV0b2xvYWQgbWFwcGluZwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkYXV0b2xvYWQgTWFwcGluZyBvZiBhdXRvbG9hZGluZyBydWxlcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5e3Bzci0wPzogYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW10+LCBwc3ItND86IGFycmF5PHN0cmluZywgc3RyaW5nfHN0cmluZ1tdPiwgY2xhc3NtYXA/OiBsaXN0PHN0cmluZz4sIGZpbGVzPzogbGlzdDxzdHJpbmc+fSAkYXV0b2xvYWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dG9sb2FkKGFycmF5ICRhdXRvbG9hZCkKICAgIHsKICAgICAgICAkdGhpcy0+YXV0b2xvYWQgPSAkYXV0b2xvYWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0b2xvYWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXV0b2xvYWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGRldiBhdXRvbG9hZCBtYXBwaW5nCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRkZXZBdXRvbG9hZCBNYXBwaW5nIG9mIGRldiBhdXRvbG9hZGluZyBydWxlcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5e3Bzci0wPzogYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW10+LCBwc3ItND86IGFycmF5PHN0cmluZywgc3RyaW5nfHN0cmluZ1tdPiwgY2xhc3NtYXA/OiBsaXN0PHN0cmluZz4sIGZpbGVzPzogbGlzdDxzdHJpbmc+fSAkZGV2QXV0b2xvYWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERldkF1dG9sb2FkKGFycmF5ICRkZXZBdXRvbG9hZCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGV2QXV0b2xvYWQgPSAkZGV2QXV0b2xvYWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGV2QXV0b2xvYWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2QXV0b2xvYWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsaXN0IG9mIHBhdGhzIGFkZGVkIHRvIFBIUCdzIGluY2x1ZGUgcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGluY2x1ZGVQYXRocyBMaXN0IG9mIGRpcmVjdG9yaWVzLgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5jbHVkZVBhdGhzKGFycmF5ICRpbmNsdWRlUGF0aHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmluY2x1ZGVQYXRocyA9ICRpbmNsdWRlUGF0aHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5jbHVkZVBhdGhzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmluY2x1ZGVQYXRoczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIG5vdGlmaWNhdGlvbiBVUkwKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRub3RpZmljYXRpb25VcmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5vdGlmaWNhdGlvblVybCgkbm90aWZpY2F0aW9uVXJsKQogICAgewogICAgICAgICR0aGlzLT5ub3RpZmljYXRpb25VcmwgPSAkbm90aWZpY2F0aW9uVXJsOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5vdGlmaWNhdGlvblVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ub3RpZmljYXRpb25Vcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGVmYXVsdEJyYW5jaAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SXNEZWZhdWx0QnJhbmNoKCRkZWZhdWx0QnJhbmNoKQogICAgewogICAgICAgICR0aGlzLT5pc0RlZmF1bHRCcmFuY2ggPSAkZGVmYXVsdEJyYW5jaDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlZmF1bHRCcmFuY2goKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aXNEZWZhdWx0QnJhbmNoOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRyZWZlcmVuY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldFNvdXJjZVJlZmVyZW5jZSgkcmVmZXJlbmNlKTsKCiAgICAgICAgLy8gb25seSBiaXRidWNrZXQsIGdpdGh1YiBhbmQgZ2l0bGFiIGhhdmUgYXV0byBnZW5lcmF0ZWQgZGlzdCBVUkxzIHRoYXQgZWFzaWx5IGFsbG93IHJlcGxhY2luZyB0aGUgcmVmZXJlbmNlIGluIHRoZSBkaXN0IFVSTAogICAgICAgIC8vIFRPRE8gZ2VuZXJhbGl6ZSB0aGlzIGEgYml0IGZvciBzZWxmLW1hbmFnZWQvb24tcHJlbSB2ZXJzaW9ucz8gU29tZSBraW5kIG9mIHJlcGxhY2UgdG9rZW4gaW4gZGlzdCB1cmxzIHdoaWNoIGFsbG93IHRoaXM/CiAgICAgICAgaWYgKAogICAgICAgICAgICAkdGhpcy0+Z2V0RGlzdFVybCgpICE9PSBudWxsCiAgICAgICAgICAgICYmIFByZWc6OmlzTWF0Y2goJ3teaHR0cHM/Oi8vKD86KD86d3d3XC4pP2JpdGJ1Y2tldFwub3JnfChhcGlcLik/Z2l0aHViXC5jb218KD86d3d3XC4pP2dpdGxhYlwuY29tKS99aScsICR0aGlzLT5nZXREaXN0VXJsKCkpCiAgICAgICAgKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREaXN0UmVmZXJlbmNlKCRyZWZlcmVuY2UpOwogICAgICAgICAgICAkdGhpcy0+c2V0RGlzdFVybChQcmVnOjpyZXBsYWNlKCd7KD88PS98c2hhPSlbYS1mMC05XXs0MH0oPz0vfCQpfWknLCAkcmVmZXJlbmNlLCAkdGhpcy0+Z2V0RGlzdFVybCgpKSk7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5nZXREaXN0UmVmZXJlbmNlKCkpIHsgLy8gdXBkYXRlIHRoZSBkaXN0IHJlZmVyZW5jZSBpZiB0aGVyZSB3YXMgb25lLCBidXQgaWYgbm9uZSB3YXMgcHJvdmlkZWQgaWdub3JlIGl0CiAgICAgICAgICAgICR0aGlzLT5zZXREaXN0UmVmZXJlbmNlKCRyZWZlcmVuY2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlcGxhY2VzIGN1cnJlbnQgdmVyc2lvbiBhbmQgcHJldHR5IHZlcnNpb24gd2l0aCBwYXNzZWQgdmFsdWVzLgogICAgICogSXQgYWxzbyBzZXRzIHN0YWJpbGl0eS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uICAgICAgIFRoZSBwYWNrYWdlJ3Mgbm9ybWFsaXplZCB2ZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcmV0dHlWZXJzaW9uIFRoZSBwYWNrYWdlJ3Mgbm9uLW5vcm1hbGl6ZWQgdmVyc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVwbGFjZVZlcnNpb24oJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKQogICAgewogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgJHRoaXMtPnByZXR0eVZlcnNpb24gPSAkcHJldHR5VmVyc2lvbjsKCiAgICAgICAgJHRoaXMtPnN0YWJpbGl0eSA9IFZlcnNpb25QYXJzZXI6OnBhcnNlU3RhYmlsaXR5KCR2ZXJzaW9uKTsKICAgICAgICAkdGhpcy0+ZGV2ID0gJHRoaXMtPnN0YWJpbGl0eSA9PT0gJ2Rldic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICR1cmwKICAgICAqIEBwYXJhbSBtaXhlZFtdfG51bGwgJG1pcnJvcnMKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgJHJlZgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAkdHlwZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkdXJsVHlwZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBsaXN0PGFycmF5e3VybDogc3RyaW5nLCBwcmVmZXJyZWQ6IGJvb2x9PnxudWxsICRtaXJyb3JzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRVcmxzKCR1cmwsICRtaXJyb3JzLCAkcmVmLCAkdHlwZSwgJHVybFR5cGUpCiAgICB7CiAgICAgICAgaWYgKCEkdXJsKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR1cmxUeXBlID09PSAnZGlzdCcgJiYgZmFsc2UgIT09IHN0cnBvcygkdXJsLCAnJScpKSB7CiAgICAgICAgICAgICR1cmwgPSBDb21wb3Nlck1pcnJvcjo6cHJvY2Vzc1VybCgkdXJsLCAkdGhpcy0+bmFtZSwgJHRoaXMtPnZlcnNpb24sICRyZWYsICR0eXBlLCAkdGhpcy0+cHJldHR5VmVyc2lvbik7CiAgICAgICAgfQoKICAgICAgICAkdXJscyA9IGFycmF5KCR1cmwpOwogICAgICAgIGlmICgkbWlycm9ycykgewogICAgICAgICAgICBmb3JlYWNoICgkbWlycm9ycyBhcyAkbWlycm9yKSB7CiAgICAgICAgICAgICAgICBpZiAoJHVybFR5cGUgPT09ICdkaXN0JykgewogICAgICAgICAgICAgICAgICAgICRtaXJyb3JVcmwgPSBDb21wb3Nlck1pcnJvcjo6cHJvY2Vzc1VybCgkbWlycm9yWyd1cmwnXSwgJHRoaXMtPm5hbWUsICR0aGlzLT52ZXJzaW9uLCAkcmVmLCAkdHlwZSwgJHRoaXMtPnByZXR0eVZlcnNpb24pOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR1cmxUeXBlID09PSAnc291cmNlJyAmJiAkdHlwZSA9PT0gJ2dpdCcpIHsKICAgICAgICAgICAgICAgICAgICAkbWlycm9yVXJsID0gQ29tcG9zZXJNaXJyb3I6OnByb2Nlc3NHaXRVcmwoJG1pcnJvclsndXJsJ10sICR0aGlzLT5uYW1lLCAkdXJsLCAkdHlwZSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHVybFR5cGUgPT09ICdzb3VyY2UnICYmICR0eXBlID09PSAnaGcnKSB7CiAgICAgICAgICAgICAgICAgICAgJG1pcnJvclVybCA9IENvbXBvc2VyTWlycm9yOjpwcm9jZXNzSGdVcmwoJG1pcnJvclsndXJsJ10sICR0aGlzLT5uYW1lLCAkdXJsLCAkdHlwZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFcaW5fYXJyYXkoJG1pcnJvclVybCwgJHVybHMpKSB7CiAgICAgICAgICAgICAgICAgICAgJGZ1bmMgPSAkbWlycm9yWydwcmVmZXJyZWQnXSA/ICdhcnJheV91bnNoaWZ0JyA6ICdhcnJheV9wdXNoJzsKICAgICAgICAgICAgICAgICAgICAkZnVuYygkdXJscywgJG1pcnJvclVybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJsczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgYXJyYXk8aW50LCBMaW5rPiAkbGlua3MKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzb3VyY2UKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBMaW5rPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNvbnZlcnRMaW5rc1RvTWFwKGFycmF5ICRsaW5rcywgJHNvdXJjZSkKICAgIHsKICAgICAgICB0cmlnZ2VyX2Vycm9yKCdQYWNrYWdlOjonLiRzb3VyY2UuJyBtdXN0IGJlIGNhbGxlZCB3aXRoIGEgbWFwIG9mIGxvd2VyY2FzZWQgcGFja2FnZSBuYW1lID0+IExpbmsgb2JqZWN0LCBnb3QgYSBpbmRleGVkIGFycmF5LCB0aGlzIGlzIGRlcHJlY2F0ZWQgYW5kIHlvdSBzaG91bGQgZml4IHlvdXIgdXNhZ2UuJyk7CiAgICAgICAgJG5ld0xpbmtzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgJG5ld0xpbmtzWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSAkbGluazsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbmV3TGlua3M7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDb21wbGV0ZUFsaWFzUGFja2FnZSBleHRlbmRzIEFsaWFzUGFja2FnZSBpbXBsZW1lbnRzIENvbXBsZXRlUGFja2FnZUludGVyZmFjZQp7CiAgICAvKiogQHZhciBDb21wbGV0ZVBhY2thZ2UgKi8KICAgIHByb3RlY3RlZCAkYWxpYXNPZjsKCiAgICAvKioKICAgICAqIEFsbCBkZXNjZW5kYW50cycgY29uc3RydWN0b3JzIHNob3VsZCBjYWxsIHRoaXMgcGFyZW50IGNvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIENvbXBsZXRlUGFja2FnZSAkYWxpYXNPZiAgICAgICBUaGUgcGFja2FnZSB0aGlzIHBhY2thZ2UgaXMgYW4gYWxpYXMgb2YKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJHZlcnNpb24gICAgICAgVGhlIHZlcnNpb24gdGhlIGFsaWFzIG11c3QgcmVwb3J0CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRwcmV0dHlWZXJzaW9uIFRoZSBhbGlhcydzIG5vbi1ub3JtYWxpemVkIHZlcnNpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENvbXBsZXRlUGFja2FnZSAkYWxpYXNPZiwgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGFsaWFzT2YsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbXBsZXRlUGFja2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNPZigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY3JpcHRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFNjcmlwdHMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U2NyaXB0cyhhcnJheSAkc2NyaXB0cykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0U2NyaXB0cygkc2NyaXB0cyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcmllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRSZXBvc2l0b3JpZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yaWVzKGFycmF5ICRyZXBvc2l0b3JpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldFJlcG9zaXRvcmllcygkcmVwb3NpdG9yaWVzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGljZW5zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRMaWNlbnNlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldExpY2Vuc2UoYXJyYXkgJGxpY2Vuc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldExpY2Vuc2UoJGxpY2Vuc2UpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXl3b3JkcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRLZXl3b3JkcygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLZXl3b3JkcyhhcnJheSAka2V5d29yZHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldEtleXdvcmRzKCRrZXl3b3Jkcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldERlc2NyaXB0aW9uKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldERlc2NyaXB0aW9uKCRkZXNjcmlwdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0RGVzY3JpcHRpb24oJGRlc2NyaXB0aW9uKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SG9tZXBhZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0SG9tZXBhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SG9tZXBhZ2UoJGhvbWVwYWdlKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRIb21lcGFnZSgkaG9tZXBhZ2UpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRob3JzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldEF1dGhvcnMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0aG9ycyhhcnJheSAkYXV0aG9ycykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0QXV0aG9ycygkYXV0aG9ycyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1cHBvcnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U3VwcG9ydCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdXBwb3J0KGFycmF5ICRzdXBwb3J0KQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRTdXBwb3J0KCRzdXBwb3J0KTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RnVuZGluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRGdW5kaW5nKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEZ1bmRpbmcoYXJyYXkgJGZ1bmRpbmcpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldEZ1bmRpbmcoJGZ1bmRpbmcpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0FiYW5kb25lZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5pc0FiYW5kb25lZCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBsYWNlbWVudFBhY2thZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0UmVwbGFjZW1lbnRQYWNrYWdlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEFiYW5kb25lZCgkYWJhbmRvbmVkKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRBYmFuZG9uZWQoJGFiYW5kb25lZCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyY2hpdmVOYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldEFyY2hpdmVOYW1lKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVOYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRBcmNoaXZlTmFtZSgkbmFtZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyY2hpdmVFeGNsdWRlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBcmNoaXZlRXhjbHVkZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJjaGl2ZUV4Y2x1ZGVzKGFycmF5ICRleGNsdWRlcykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0QXJjaGl2ZUV4Y2x1ZGVzKCRleGNsdWRlcyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxDb21wYXJlcjsKCi8qKgogKiBjbGFzcyBDb21wYXJlcgogKgogKiBAYXV0aG9yIEhlY3RvciBQcmF0cyA8aGVjdG9ycHJhdHNvcnRlZ2FAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tcGFyZXIKewogICAgLyoqIEB2YXIgc3RyaW5nIFNvdXJjZSBkaXJlY3RvcnkgKi8KICAgIHByaXZhdGUgJHNvdXJjZTsKICAgIC8qKiBAdmFyIHN0cmluZyBUYXJnZXQgZGlyZWN0b3J5ICovCiAgICBwcml2YXRlICR1cGRhdGU7CiAgICAvKiogQHZhciBhcnJheXtjaGFuZ2VkPzogc3RyaW5nW10sIHJlbW92ZWQ/OiBzdHJpbmdbXSwgYWRkZWQ/OiBzdHJpbmdbXX0gKi8KICAgIHByaXZhdGUgJGNoYW5nZWQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZSgkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5zb3VyY2UgPSAkc291cmNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXBkYXRlCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVcGRhdGUoJHVwZGF0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dXBkYXRlID0gJHVwZGF0ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICR0b1N0cmluZwogICAgICogQHBhcmFtIGJvb2wgJGV4cGxpY2F0ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e2NoYW5nZWQ/OiBzdHJpbmdbXSwgcmVtb3ZlZD86IHN0cmluZ1tdLCBhZGRlZD86IHN0cmluZ1tdfXxzdHJpbmd8ZmFsc2UgZmFsc2UgaWYgbm8gY2hhbmdlLCBzdHJpbmcgb25seSBpZiAkdG9TdHJpbmcgaXMgdHJ1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2hhbmdlZCgkdG9TdHJpbmcgPSBmYWxzZSwgJGV4cGxpY2F0ZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICAkY2hhbmdlZCA9ICR0aGlzLT5jaGFuZ2VkOwogICAgICAgIGlmICghY291bnQoJGNoYW5nZWQpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRleHBsaWNhdGVkKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjaGFuZ2VkIGFzICRzZWN0aW9uS2V5ID0+ICRpdGVtU2VjdGlvbikgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGl0ZW1TZWN0aW9uIGFzICRpdGVtS2V5ID0+ICRpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgJGNoYW5nZWRbJHNlY3Rpb25LZXldWyRpdGVtS2V5XSA9ICRpdGVtLicgKCcuJHNlY3Rpb25LZXkuJyknOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRvU3RyaW5nKSB7CiAgICAgICAgICAgICRzdHJpbmdzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGNoYW5nZWQgYXMgJHNlY3Rpb25LZXkgPT4gJGl0ZW1TZWN0aW9uKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkaXRlbVNlY3Rpb24gYXMgJGl0ZW1LZXkgPT4gJGl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAkc3RyaW5nc1tdID0gJGl0ZW0uIlxyXG4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRjaGFuZ2VkID0gaW1wbG9kZSgiXHJcbiIsICRzdHJpbmdzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2hhbmdlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG9Db21wYXJlKCkKICAgIHsKICAgICAgICAkc291cmNlID0gYXJyYXkoKTsKICAgICAgICAkZGVzdGluYXRpb24gPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5jaGFuZ2VkID0gYXJyYXkoKTsKICAgICAgICAkY3VycmVudERpcmVjdG9yeSA9IGdldGN3ZCgpOwogICAgICAgIGNoZGlyKCR0aGlzLT5zb3VyY2UpOwogICAgICAgICRzb3VyY2UgPSAkdGhpcy0+ZG9UcmVlKCcuJywgJHNvdXJjZSk7CiAgICAgICAgaWYgKCFpc19hcnJheSgkc291cmNlKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNoZGlyKCRjdXJyZW50RGlyZWN0b3J5KTsKICAgICAgICBjaGRpcigkdGhpcy0+dXBkYXRlKTsKICAgICAgICAkZGVzdGluYXRpb24gPSAkdGhpcy0+ZG9UcmVlKCcuJywgJGRlc3RpbmF0aW9uKTsKICAgICAgICBpZiAoIWlzX2FycmF5KCRkZXN0aW5hdGlvbikpIHsKICAgICAgICAgICAgZXhpdDsKICAgICAgICB9CiAgICAgICAgY2hkaXIoJGN1cnJlbnREaXJlY3RvcnkpOwogICAgICAgIGZvcmVhY2ggKCRzb3VyY2UgYXMgJGRpciA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlIGFzICRmaWxlID0+ICRoYXNoKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGRlc3RpbmF0aW9uWyRkaXJdWyRmaWxlXSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGhhc2ggIT09ICRkZXN0aW5hdGlvblskZGlyXVskZmlsZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoYW5nZWRbJ2NoYW5nZWQnXVtdID0gJGRpci4nLycuJGZpbGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hhbmdlZFsncmVtb3ZlZCddW10gPSAkZGlyLicvJy4kZmlsZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkZGVzdGluYXRpb24gYXMgJGRpciA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlIGFzICRmaWxlID0+ICRoYXNoKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRzb3VyY2VbJGRpcl1bJGZpbGVdKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGFuZ2VkWydhZGRlZCddW10gPSAkZGlyLicvJy4kZmlsZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpcgogICAgICogQHBhcmFtIG1peGVkICRhcnJheQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIHN0cmluZ3xmYWxzZT4+fGZhbHNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9UcmVlKCRkaXIsICYkYXJyYXkpCiAgICB7CiAgICAgICAgaWYgKCRkaCA9IG9wZW5kaXIoJGRpcikpIHsKICAgICAgICAgICAgd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7CiAgICAgICAgICAgICAgICBpZiAoJGZpbGUgIT09ICcuJyAmJiAkZmlsZSAhPT0gJy4uJykgewogICAgICAgICAgICAgICAgICAgIGlmIChpc19saW5rKCRkaXIuJy8nLiRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYXJyYXlbJGRpcl1bJGZpbGVdID0gcmVhZGxpbmsoJGRpci4nLycuJGZpbGUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc19kaXIoJGRpci4nLycuJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY291bnQoJGFycmF5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGFycmF5WzBdID0gJ1RlbXAnOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmRvVHJlZSgkZGlyLicvJy4kZmlsZSwgJGFycmF5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2ZpbGUoJGRpci4nLycuJGZpbGUpICYmIGZpbGVzaXplKCRkaXIuJy8nLiRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYXJyYXlbJGRpcl1bJGZpbGVdID0gbWQ1X2ZpbGUoJGRpci4nLycuJGZpbGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY291bnQoJGFycmF5KSA+IDEgJiYgaXNzZXQoJGFycmF5WycwJ10pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkYXJyYXlbJzAnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkYXJyYXk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCi8qKgogKiBUaGUgcm9vdCBwYWNrYWdlIHJlcHJlc2VudHMgdGhlIHByb2plY3QncyBjb21wb3Nlci5qc29uIGFuZCBjb250YWlucyBhZGRpdGlvbmFsIG1ldGFkYXRhCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFJvb3RQYWNrYWdlIGV4dGVuZHMgQ29tcGxldGVQYWNrYWdlIGltcGxlbWVudHMgUm9vdFBhY2thZ2VJbnRlcmZhY2UKewogICAgY29uc3QgREVGQVVMVF9QUkVUVFlfVkVSU0lPTiA9ICcxLjAuMCtuby12ZXJzaW9uLXNldCc7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJG1pbmltdW1TdGFiaWxpdHkgPSAnc3RhYmxlJzsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkcHJlZmVyU3RhYmxlID0gZmFsc2U7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4gTWFwIG9mIHBhY2thZ2UgbmFtZSB0byBzdGFiaWxpdHkgY29uc3RhbnQgKi8KICAgIHByb3RlY3RlZCAkc3RhYmlsaXR5RmxhZ3MgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgbWl4ZWRbXSAqLwogICAgcHJvdGVjdGVkICRjb25maWcgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+IE1hcCBvZiBwYWNrYWdlIG5hbWUgdG8gcmVmZXJlbmNlL2NvbW1pdCBoYXNoICovCiAgICBwcm90ZWN0ZWQgJHJlZmVyZW5jZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8YXJyYXl7cGFja2FnZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGFsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+ICovCiAgICBwcm90ZWN0ZWQgJGFsaWFzZXMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICoge0BpbmVyaGl0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TWluaW11bVN0YWJpbGl0eSgkbWluaW11bVN0YWJpbGl0eSkKICAgIHsKICAgICAgICAkdGhpcy0+bWluaW11bVN0YWJpbGl0eSA9ICRtaW5pbXVtU3RhYmlsaXR5OwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1pbmltdW1TdGFiaWxpdHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWluaW11bVN0YWJpbGl0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGFiaWxpdHlGbGFncyhhcnJheSAkc3RhYmlsaXR5RmxhZ3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YWJpbGl0eUZsYWdzID0gJHN0YWJpbGl0eUZsYWdzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eUZsYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YWJpbGl0eUZsYWdzOwogICAgfQoKICAgIC8qKgogICAgICoge0BpbmVyaGl0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZmVyU3RhYmxlKCRwcmVmZXJTdGFibGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlclN0YWJsZSA9ICRwcmVmZXJTdGFibGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZmVyU3RhYmxlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZWZlclN0YWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5lcmhpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbmZpZyhhcnJheSAkY29uZmlnKQogICAgewogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZpZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25maWc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluZXJoaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZWZlcmVuY2VzKGFycmF5ICRyZWZlcmVuY2VzKQogICAgewogICAgICAgICR0aGlzLT5yZWZlcmVuY2VzID0gJHJlZmVyZW5jZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZWZlcmVuY2VzOwogICAgfQoKICAgIC8qKgogICAgICoge0BpbmVyaGl0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWxpYXNlcyhhcnJheSAkYWxpYXNlcykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNlcyA9ICRhbGlhc2VzOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsaWFzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFJvb3RBbGlhc1BhY2thZ2UgZXh0ZW5kcyBDb21wbGV0ZUFsaWFzUGFja2FnZSBpbXBsZW1lbnRzIFJvb3RQYWNrYWdlSW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIFJvb3RQYWNrYWdlICovCiAgICBwcm90ZWN0ZWQgJGFsaWFzT2Y7CgogICAgLyoqCiAgICAgKiBBbGwgZGVzY2VuZGFudHMnIGNvbnN0cnVjdG9ycyBzaG91bGQgY2FsbCB0aGlzIHBhcmVudCBjb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBSb290UGFja2FnZSAkYWxpYXNPZiAgICAgICBUaGUgcGFja2FnZSB0aGlzIHBhY2thZ2UgaXMgYW4gYWxpYXMgb2YKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdmVyc2lvbiAgICAgICBUaGUgdmVyc2lvbiB0aGUgYWxpYXMgbXVzdCByZXBvcnQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkcHJldHR5VmVyc2lvbiBUaGUgYWxpYXMncyBub24tbm9ybWFsaXplZCB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSb290UGFja2FnZSAkYWxpYXNPZiwgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGFsaWFzT2YsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFJvb3RQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbGlhc09mKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2Y7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBbGlhc2VzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TWluaW11bVN0YWJpbGl0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5RmxhZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U3RhYmlsaXR5RmxhZ3MoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWZlcmVuY2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFJlZmVyZW5jZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmZXJTdGFibGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0UHJlZmVyU3RhYmxlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmlnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldENvbmZpZygpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcXVpcmVzKGFycmF5ICRyZXF1aXJlKQogICAgewogICAgICAgICR0aGlzLT5yZXF1aXJlcyA9ICR0aGlzLT5yZXBsYWNlU2VsZlZlcnNpb25EZXBlbmRlbmNpZXMoJHJlcXVpcmUsIExpbms6OlRZUEVfUkVRVUlSRSk7CgogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRSZXF1aXJlcygkcmVxdWlyZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2UmVxdWlyZXMoYXJyYXkgJGRldlJlcXVpcmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmRldlJlcXVpcmVzID0gJHRoaXMtPnJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcygkZGV2UmVxdWlyZSwgTGluazo6VFlQRV9ERVZfUkVRVUlSRSk7CgogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXREZXZSZXF1aXJlcygkZGV2UmVxdWlyZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uZmxpY3RzKGFycmF5ICRjb25mbGljdHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbmZsaWN0cyA9ICR0aGlzLT5yZXBsYWNlU2VsZlZlcnNpb25EZXBlbmRlbmNpZXMoJGNvbmZsaWN0cywgTGluazo6VFlQRV9DT05GTElDVCk7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldENvbmZsaWN0cygkY29uZmxpY3RzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm92aWRlcyhhcnJheSAkcHJvdmlkZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb3ZpZGVzID0gJHRoaXMtPnJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcygkcHJvdmlkZXMsIExpbms6OlRZUEVfUFJPVklERSk7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldFByb3ZpZGVzKCRwcm92aWRlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwbGFjZXMoYXJyYXkgJHJlcGxhY2VzKQogICAgewogICAgICAgICR0aGlzLT5yZXBsYWNlcyA9ICR0aGlzLT5yZXBsYWNlU2VsZlZlcnNpb25EZXBlbmRlbmNpZXMoJHJlcGxhY2VzLCBMaW5rOjpUWVBFX1JFUExBQ0UpOwogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRSZXBsYWNlcygkcmVwbGFjZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dG9sb2FkKGFycmF5ICRhdXRvbG9hZCkKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0QXV0b2xvYWQoJGF1dG9sb2FkKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXZBdXRvbG9hZChhcnJheSAkZGV2QXV0b2xvYWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldERldkF1dG9sb2FkKCRkZXZBdXRvbG9hZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3RhYmlsaXR5RmxhZ3MoYXJyYXkgJHN0YWJpbGl0eUZsYWdzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRTdGFiaWxpdHlGbGFncygkc3RhYmlsaXR5RmxhZ3MpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1pbmltdW1TdGFiaWxpdHkoJG1pbmltdW1TdGFiaWxpdHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldE1pbmltdW1TdGFiaWxpdHkoJG1pbmltdW1TdGFiaWxpdHkpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZlclN0YWJsZSgkcHJlZmVyU3RhYmxlKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRQcmVmZXJTdGFibGUoJHByZWZlclN0YWJsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uZmlnKGFycmF5ICRjb25maWcpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldENvbmZpZygkY29uZmlnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZWZlcmVuY2VzKGFycmF5ICRyZWZlcmVuY2VzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRSZWZlcmVuY2VzKCRyZWZlcmVuY2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBbGlhc2VzKGFycmF5ICRhbGlhc2VzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRBbGlhc2VzKCRhbGlhc2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdWdnZXN0cyhhcnJheSAkc3VnZ2VzdHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldFN1Z2dlc3RzKCRzdWdnZXN0cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXh0cmEoYXJyYXkgJGV4dHJhKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRFeHRyYSgkZXh0cmEpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2Nsb25lKCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY2xvbmUoKTsKICAgICAgICAkdGhpcy0+YWxpYXNPZiA9IGNsb25lICR0aGlzLT5hbGlhc09mOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7CgovKioKICogRGVmaW5lcyBhZGRpdGlvbmFsIGZpZWxkcyB0aGF0IGFyZSBvbmx5IG5lZWRlZCBmb3IgdGhlIHJvb3QgcGFja2FnZQogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgUm9vdFBhY2thZ2VJbnRlcmZhY2UgZXh0ZW5kcyBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHBhY2thZ2UgbmFtZXMgYW5kIHRoZWlyIGFsaWFzZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PGFycmF5e3BhY2thZ2U6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWluaW11bSBzdGFiaWxpdHkgb2YgdGhlIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TWluaW11bVN0YWJpbGl0eSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3RhYmlsaXR5IGZsYWdzIHRvIGFwcGx5IHRvIGRlcGVuZGVuY2llcwogICAgICoKICAgICAqIGFycmF5KCdmb28vYmFyJyA9PiAnZGV2JykKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5RmxhZ3MoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgcGFja2FnZSBuYW1lcyBhbmQgc291cmNlIHJlZmVyZW5jZXMgdGhhdCBtdXN0IGJlIGVuZm9yY2VkIG9uIHRoZW0KICAgICAqCiAgICAgKiBhcnJheSgnZm9vL2JhcicgPT4gJ2FiY2QxMjM0JykKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSByb290IHBhY2thZ2UgcHJlZmVycyBwaWNraW5nIHN0YWJsZSBwYWNrYWdlcyBvdmVyIHVuc3RhYmxlIG9uZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZWZlclN0YWJsZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcm9vdCBwYWNrYWdlJ3MgY29uZmlndXJhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmlnKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlcXVpcmVkIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIExpbmtbXSAkcmVxdWlyZXMgQSBzZXQgb2YgcGFja2FnZSBsaW5rcwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVxdWlyZXMoYXJyYXkgJHJlcXVpcmVzKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVjb21tZW5kZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTGlua1tdICRkZXZSZXF1aXJlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXZSZXF1aXJlcyhhcnJheSAkZGV2UmVxdWlyZXMpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBjb25mbGljdGluZyBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSBMaW5rW10gJGNvbmZsaWN0cyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25mbGljdHMoYXJyYXkgJGNvbmZsaWN0cyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHByb3ZpZGVkIHZpcnR1YWwgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTGlua1tdICRwcm92aWRlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm92aWRlcyhhcnJheSAkcHJvdmlkZXMpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBwYWNrYWdlcyB0aGlzIG9uZSByZXBsYWNlcwogICAgICoKICAgICAqIEBwYXJhbSBMaW5rW10gJHJlcGxhY2VzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcGxhY2VzKGFycmF5ICRyZXBsYWNlcyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlcG9zaXRvcmllcwogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZFtdICRyZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcG9zaXRvcmllcyhhcnJheSAkcmVwb3NpdG9yaWVzKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgYXV0b2xvYWQgbWFwcGluZwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheXtwc3ItMD86IGFycmF5PHN0cmluZywgc3RyaW5nfHN0cmluZ1tdPiwgcHNyLTQ/OiBhcnJheTxzdHJpbmcsIHN0cmluZ3xzdHJpbmdbXT4sIGNsYXNzbWFwPzogbGlzdDxzdHJpbmc+LCBmaWxlcz86IGxpc3Q8c3RyaW5nPn0gJGF1dG9sb2FkIE1hcHBpbmcgb2YgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dG9sb2FkKGFycmF5ICRhdXRvbG9hZCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGRldiBhdXRvbG9hZCBtYXBwaW5nCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5e3Bzci0wPzogYXJyYXk8c3RyaW5nLCBzdHJpbmd8c3RyaW5nW10+LCBwc3ItND86IGFycmF5PHN0cmluZywgc3RyaW5nfHN0cmluZ1tdPiwgY2xhc3NtYXA/OiBsaXN0PHN0cmluZz4sIGZpbGVzPzogbGlzdDxzdHJpbmc+fSAkZGV2QXV0b2xvYWQgTWFwcGluZyBvZiBkZXYgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERldkF1dG9sb2FkKGFycmF5ICRkZXZBdXRvbG9hZCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHN0YWJpbGl0eUZsYWdzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkc3RhYmlsaXR5RmxhZ3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0YWJpbGl0eUZsYWdzKGFycmF5ICRzdGFiaWxpdHlGbGFncyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIG1pbmltdW1TdGFiaWxpdHkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtaW5pbXVtU3RhYmlsaXR5CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNaW5pbXVtU3RhYmlsaXR5KCRtaW5pbXVtU3RhYmlsaXR5KTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgcHJlZmVyU3RhYmxlCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHByZWZlclN0YWJsZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZmVyU3RhYmxlKCRwcmVmZXJTdGFibGUpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBjb25maWcKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29uZmlnCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25maWcoYXJyYXkgJGNvbmZpZyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlZmVyZW5jZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICRyZWZlcmVuY2VzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZWZlcmVuY2VzKGFycmF5ICRyZWZlcmVuY2VzKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgYWxpYXNlcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheTxhcnJheXtwYWNrYWdlOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgYWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4gJGFsaWFzZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFsaWFzZXMoYXJyYXkgJGFsaWFzZXMpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBzdWdnZXN0ZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBzdHJpbmc+ICRzdWdnZXN0cyBBIHNldCBvZiBwYWNrYWdlIG5hbWVzL2NvbW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdWdnZXN0cyhhcnJheSAkc3VnZ2VzdHMpOwoKICAgIC8qKgogICAgICogQHBhcmFtIG1peGVkW10gJGV4dHJhCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHRyYShhcnJheSAkZXh0cmEpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7CgovKioKICogQGF1dGhvciBUaWxsIEtsYW1wYWVja2VsIDx0aWxsQHBocC5uZXQ+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgTWF0dGhpZXUgTW9xdWV0IDxtYXR0aGlldUBtb3F1ZXQubmV0PgogKi8KY2xhc3MgUGhhckFyY2hpdmVyIGltcGxlbWVudHMgQXJjaGl2ZXJJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBpbnQ+ICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRmb3JtYXRzID0gYXJyYXkoCiAgICAgICAgJ3ppcCcgPT4gXFBoYXI6OlpJUCwKICAgICAgICAndGFyJyA9PiBcUGhhcjo6VEFSLAogICAgICAgICd0YXIuZ3onID0+IFxQaGFyOjpUQVIsCiAgICAgICAgJ3Rhci5iejInID0+IFxQaGFyOjpUQVIsCiAgICApOwoKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgaW50PiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyAkY29tcHJlc3NGb3JtYXRzID0gYXJyYXkoCiAgICAgICAgJ3Rhci5neicgPT4gXFBoYXI6OkdaLAogICAgICAgICd0YXIuYnoyJyA9PiBcUGhhcjo6QloyLAogICAgKTsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmNoaXZlKCRzb3VyY2VzLCAkdGFyZ2V0LCAkZm9ybWF0LCBhcnJheSAkZXhjbHVkZXMgPSBhcnJheSgpLCAkaWdub3JlRmlsdGVycyA9IGZhbHNlKQogICAgewogICAgICAgICRzb3VyY2VzID0gcmVhbHBhdGgoJHNvdXJjZXMpOwoKICAgICAgICAvLyBQaGFyIHdvdWxkIG90aGVyd2lzZSBsb2FkIHRoZSBmaWxlIHdoaWNoIHdlIGRvbid0IHdhbnQKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRhcmdldCkpIHsKICAgICAgICAgICAgdW5saW5rKCR0YXJnZXQpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGZpbGVuYW1lID0gc3Vic3RyKCR0YXJnZXQsIDAsIHN0cnJwb3MoJHRhcmdldCwgJGZvcm1hdCkgLSAxKTsKCiAgICAgICAgICAgIC8vIENoZWNrIGlmIGNvbXByZXNzIGZvcm1hdAogICAgICAgICAgICBpZiAoaXNzZXQoc3RhdGljOjokY29tcHJlc3NGb3JtYXRzWyRmb3JtYXRdKSkgewogICAgICAgICAgICAgICAgLy8gQ3VycmVudCBjb21wcmVzcyBmb3JtYXQgc3VwcG9ydGVkIGJhc2Ugb24gdGFyCiAgICAgICAgICAgICAgICAkdGFyZ2V0ID0gJGZpbGVuYW1lIC4gJy50YXInOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGhhciA9IG5ldyBcUGhhckRhdGEoCiAgICAgICAgICAgICAgICAkdGFyZ2V0LAogICAgICAgICAgICAgICAgXEZpbGVzeXN0ZW1JdGVyYXRvcjo6S0VZX0FTX1BBVEhOQU1FIHwgXEZpbGVzeXN0ZW1JdGVyYXRvcjo6Q1VSUkVOVF9BU19GSUxFSU5GTywKICAgICAgICAgICAgICAgICcnLAogICAgICAgICAgICAgICAgc3RhdGljOjokZm9ybWF0c1skZm9ybWF0XQogICAgICAgICAgICApOwogICAgICAgICAgICAkZmlsZXMgPSBuZXcgQXJjaGl2YWJsZUZpbGVzRmluZGVyKCRzb3VyY2VzLCAkZXhjbHVkZXMsICRpZ25vcmVGaWx0ZXJzKTsKICAgICAgICAgICAgJGZpbGVzT25seSA9IG5ldyBBcmNoaXZhYmxlRmlsZXNGaWx0ZXIoJGZpbGVzKTsKICAgICAgICAgICAgJHBoYXItPmJ1aWxkRnJvbUl0ZXJhdG9yKCRmaWxlc09ubHksICRzb3VyY2VzKTsKICAgICAgICAgICAgJGZpbGVzT25seS0+YWRkRW1wdHlEaXIoJHBoYXIsICRzb3VyY2VzKTsKCiAgICAgICAgICAgIGlmIChpc3NldChzdGF0aWM6OiRjb21wcmVzc0Zvcm1hdHNbJGZvcm1hdF0pKSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBjYW4gYmUgY29tcHJlc3NlZD8KICAgICAgICAgICAgICAgIGlmICghJHBoYXItPmNhbkNvbXByZXNzKHN0YXRpYzo6JGNvbXByZXNzRm9ybWF0c1skZm9ybWF0XSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignQ2FuIG5vdCBjb21wcmVzcyB0byAlcyBmb3JtYXQnLCAkZm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gRGVsZXRlIG9sZCB0YXIKICAgICAgICAgICAgICAgIHVubGluaygkdGFyZ2V0KTsKCiAgICAgICAgICAgICAgICAvLyBDb21wcmVzcyB0aGUgbmV3IHRhcgogICAgICAgICAgICAgICAgJHBoYXItPmNvbXByZXNzKHN0YXRpYzo6JGNvbXByZXNzRm9ybWF0c1skZm9ybWF0XSk7CgogICAgICAgICAgICAgICAgLy8gTWFrZSB0aGUgY29ycmVjdCBmaWxlbmFtZQogICAgICAgICAgICAgICAgJHRhcmdldCA9ICRmaWxlbmFtZSAuICcuJyAuICRmb3JtYXQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkdGFyZ2V0OwogICAgICAgIH0gY2F0Y2ggKFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBjcmVhdGUgYXJjaGl2ZSAnJXMnIGZyb20gJyVzJzogJXMiLAogICAgICAgICAgICAgICAgJHRhcmdldCwKICAgICAgICAgICAgICAgICRzb3VyY2VzLAogICAgICAgICAgICAgICAgJGUtPmdldE1lc3NhZ2UoKQogICAgICAgICAgICApOwoKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRtZXNzYWdlLCAkZS0+Z2V0Q29kZSgpLCAkZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1cHBvcnRzKCRmb3JtYXQsICRzb3VyY2VUeXBlKQogICAgewogICAgICAgIHJldHVybiBpc3NldChzdGF0aWM6OiRmb3JtYXRzWyRmb3JtYXRdKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIEZpbGVzeXN0ZW1JdGVyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcU3BsRmlsZUluZm87CgovKioKICogQSBTeW1mb255IEZpbmRlciB3cmFwcGVyIHdoaWNoIGxvY2F0ZXMgZmlsZXMgdGhhdCBzaG91bGQgZ28gaW50byBhcmNoaXZlcwogKgogKiBIYW5kbGVzIC5naXRpZ25vcmUsIC5naXRhdHRyaWJ1dGVzIGFuZCAuaGdpZ25vcmUgZmlsZXMgYXMgd2VsbCBhcyBjb21wb3NlcidzCiAqIG93biBleGNsdWRlIHJ1bGVzIGZyb20gY29tcG9zZXIuanNvbgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQXJjaGl2YWJsZUZpbGVzRmluZGVyIGV4dGVuZHMgXEZpbHRlckl0ZXJhdG9yCnsKICAgIC8qKgogICAgICogQHZhciBGaW5kZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRmaW5kZXI7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgaW50ZXJuYWwgU3ltZm9ueSBGaW5kZXIgd2l0aCBhcHByb3ByaWF0ZSBmaWx0ZXJzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlcyBQYXRoIHRvIHNvdXJjZSBmaWxlcyB0byBiZSBhcmNoaXZlZAogICAgICogQHBhcmFtIHN0cmluZ1tdICRleGNsdWRlcyBDb21wb3NlcidzIG93biBleGNsdWRlIHJ1bGVzIGZyb20gY29tcG9zZXIuanNvbgogICAgICogQHBhcmFtIGJvb2wgJGlnbm9yZUZpbHRlcnMgSWdub3JlIGZpbHRlcnMgd2hlbiBsb29raW5nIGZvciBmaWxlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNvdXJjZXMsIGFycmF5ICRleGNsdWRlcywgJGlnbm9yZUZpbHRlcnMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgpOwoKICAgICAgICAkc291cmNlcyA9ICRmcy0+bm9ybWFsaXplUGF0aChyZWFscGF0aCgkc291cmNlcykpOwoKICAgICAgICBpZiAoJGlnbm9yZUZpbHRlcnMpIHsKICAgICAgICAgICAgJGZpbHRlcnMgPSBhcnJheSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRmaWx0ZXJzID0gYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgR2l0RXhjbHVkZUZpbHRlcigkc291cmNlcyksCiAgICAgICAgICAgICAgICBuZXcgQ29tcG9zZXJFeGNsdWRlRmlsdGVyKCRzb3VyY2VzLCAkZXhjbHVkZXMpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZpbmRlciA9IG5ldyBGaW5kZXIoKTsKCiAgICAgICAgJGZpbHRlciA9IGZ1bmN0aW9uIChcU3BsRmlsZUluZm8gJGZpbGUpIHVzZSAoJHNvdXJjZXMsICRmaWx0ZXJzLCAkZnMpIHsKICAgICAgICAgICAgaWYgKCRmaWxlLT5pc0xpbmsoKSAmJiBzdHJwb3MoJGZpbGUtPmdldFJlYWxQYXRoKCksICRzb3VyY2VzKSAhPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVsYXRpdmVQYXRoID0gUHJlZzo6cmVwbGFjZSgKICAgICAgICAgICAgICAgICcjXicucHJlZ19xdW90ZSgkc291cmNlcywgJyMnKS4nIycsCiAgICAgICAgICAgICAgICAnJywKICAgICAgICAgICAgICAgICRmcy0+bm9ybWFsaXplUGF0aCgkZmlsZS0+Z2V0UmVhbFBhdGgoKSkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRleGNsdWRlID0gZmFsc2U7CiAgICAgICAgICAgIGZvcmVhY2ggKCRmaWx0ZXJzIGFzICRmaWx0ZXIpIHsKICAgICAgICAgICAgICAgICRleGNsdWRlID0gJGZpbHRlci0+ZmlsdGVyKCRyZWxhdGl2ZVBhdGgsICRleGNsdWRlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICEkZXhjbHVkZTsKICAgICAgICB9OwoKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkZmlsdGVyLCAnYmluZFRvJykpIHsKICAgICAgICAgICAgJGZpbHRlciA9ICRmaWx0ZXItPmJpbmRUbyhudWxsKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maW5kZXIKICAgICAgICAgICAgLT5pbigkc291cmNlcykKICAgICAgICAgICAgLT5maWx0ZXIoJGZpbHRlcikKICAgICAgICAgICAgLT5pZ25vcmVWQ1ModHJ1ZSkKICAgICAgICAgICAgLT5pZ25vcmVEb3RGaWxlcyhmYWxzZSkKICAgICAgICAgICAgLT5zb3J0QnlOYW1lKCk7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHRoaXMtPmZpbmRlci0+Z2V0SXRlcmF0b3IoKSk7CiAgICB9CgogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICAvKiogQHZhciBTcGxGaWxlSW5mbyAkY3VycmVudCAqLwogICAgICAgICRjdXJyZW50ID0gJHRoaXMtPmdldElubmVySXRlcmF0b3IoKS0+Y3VycmVudCgpOwoKICAgICAgICBpZiAoISRjdXJyZW50LT5pc0RpcigpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJGl0ZXJhdG9yID0gbmV3IEZpbGVzeXN0ZW1JdGVyYXRvcigkY3VycmVudCwgRmlsZXN5c3RlbUl0ZXJhdG9yOjpTS0lQX0RPVFMpOwoKICAgICAgICByZXR1cm4gISRpdGVyYXRvci0+dmFsaWQoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlcjsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KYWJzdHJhY3QgY2xhc3MgQmFzZUV4Y2x1ZGVGaWx0ZXIKewogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJHNvdXJjZVBhdGg7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5PGFycmF5ezA6IHN0cmluZywgMTogYm9vbCwgMjogYm9vbH0+IGFycmF5IG9mIFskcGF0dGVybiwgJG5lZ2F0ZSwgJHN0cmlwTGVhZGluZ1NsYXNoXSBhcnJheXMKICAgICAqLwogICAgcHJvdGVjdGVkICRleGNsdWRlUGF0dGVybnM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2VQYXRoIERpcmVjdG9yeSBjb250YWluaW5nIHNvdXJjZXMgdG8gYmUgZmlsdGVyZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzb3VyY2VQYXRoKQogICAgewogICAgICAgICR0aGlzLT5zb3VyY2VQYXRoID0gJHNvdXJjZVBhdGg7CiAgICAgICAgJHRoaXMtPmV4Y2x1ZGVQYXR0ZXJucyA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgdGhlIGdpdmVuIHBhdGggYWdhaW5zdCBhbGwgZXhjbHVkZSBwYXR0ZXJucyBpbiB0aGlzIGZpbHRlcgogICAgICoKICAgICAqIE5lZ2F0ZWQgcGF0dGVybnMgb3ZlcndyaXRlIGV4Y2x1ZGUgZGVjaXNpb25zIG9mIHByZXZpb3VzIGZpbHRlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVsYXRpdmVQYXRoIFRoZSBmaWxlJ3MgcGF0aCByZWxhdGl2ZSB0byB0aGUgc291cmNlUGF0aAogICAgICogQHBhcmFtIGJvb2wgJGV4Y2x1ZGUgV2hldGhlciBhIHByZXZpb3VzIGZpbHRlciB3YW50cyB0byBleGNsdWRlIHRoaXMgZmlsZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBmaWxlIHNob3VsZCBiZSBleGNsdWRlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmlsdGVyKCRyZWxhdGl2ZVBhdGgsICRleGNsdWRlKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5leGNsdWRlUGF0dGVybnMgYXMgJHBhdHRlcm5EYXRhKSB7CiAgICAgICAgICAgIGxpc3QoJHBhdHRlcm4sICRuZWdhdGUsICRzdHJpcExlYWRpbmdTbGFzaCkgPSAkcGF0dGVybkRhdGE7CgogICAgICAgICAgICBpZiAoJHN0cmlwTGVhZGluZ1NsYXNoKSB7CiAgICAgICAgICAgICAgICAkcGF0aCA9IHN1YnN0cigkcmVsYXRpdmVQYXRoLCAxKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYXRoID0gJHJlbGF0aXZlUGF0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRwYXR0ZXJuLCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICAkZXhjbHVkZSA9ICEkbmVnYXRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gc3VwcHJlc3NlZAogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGV4Y2x1ZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzZXMgYSBmaWxlIGNvbnRhaW5pbmcgZXhjbHVkZSBydWxlcyBvZiBkaWZmZXJlbnQgZm9ybWF0cyBwZXIgbGluZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkbGluZXMgQSBzZXQgb2YgbGluZXMgdG8gYmUgcGFyc2VkCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGxpbmVQYXJzZXIgVGhlIHBhcnNlciB0byBiZSB1c2VkIG9uIGVhY2ggbGluZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8YXJyYXl7MDogc3RyaW5nLCAxOiBib29sLCAyOiBib29sfT4gRXhjbHVkZSBwYXR0ZXJucyB0byBiZSB1c2VkIGluIGZpbHRlcigpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxpbmVzKGFycmF5ICRsaW5lcywgJGxpbmVQYXJzZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2ZpbHRlcigKICAgICAgICAgICAgYXJyYXlfbWFwKAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCRsaW5lKSB1c2UgKCRsaW5lUGFyc2VyKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSB0cmltKCRsaW5lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkbGluZSB8fCAwID09PSBzdHJwb3MoJGxpbmUsICcjJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmMoJGxpbmVQYXJzZXIsICRsaW5lKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAkbGluZXMKICAgICAgICAgICAgKSwKICAgICAgICAgICAgZnVuY3Rpb24gKCRwYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHBhdHRlcm4gIT09IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGEgc2V0IG9mIGV4Y2x1ZGUgcGF0dGVybnMgZm9yIGZpbHRlcigpIGZyb20gZ2l0aWdub3JlIHJ1bGVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRydWxlcyBBIGxpc3Qgb2YgZXhjbHVkZSBydWxlcyBpbiBnaXRpZ25vcmUgc3ludGF4CiAgICAgKgogICAgICogQHJldHVybiBhcnJheTxpbnQsIGFycmF5ezA6IHN0cmluZywgMTogYm9vbCwgMjogYm9vbH0+IEV4Y2x1ZGUgcGF0dGVybnMKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlUGF0dGVybnMoJHJ1bGVzKQogICAgewogICAgICAgICRwYXR0ZXJucyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJ1bGVzIGFzICRydWxlKSB7CiAgICAgICAgICAgICRwYXR0ZXJuc1tdID0gJHRoaXMtPmdlbmVyYXRlUGF0dGVybigkcnVsZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhdHRlcm5zOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGFuIGV4Y2x1ZGUgcGF0dGVybiBmb3IgZmlsdGVyKCkgZnJvbSBhIGdpdGlnbm9yZSBydWxlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcnVsZSBBbiBleGNsdWRlIHJ1bGUgaW4gZ2l0aWdub3JlIHN5bnRheAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7MDogc3RyaW5nLCAxOiBib29sLCAyOiBib29sfSBBbiBleGNsdWRlIHBhdHRlcm4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlUGF0dGVybigkcnVsZSkKICAgIHsKICAgICAgICAkbmVnYXRlID0gZmFsc2U7CiAgICAgICAgJHBhdHRlcm4gPSAnJzsKCiAgICAgICAgaWYgKCRydWxlICE9PSAnJyAmJiAkcnVsZVswXSA9PT0gJyEnKSB7CiAgICAgICAgICAgICRuZWdhdGUgPSB0cnVlOwogICAgICAgICAgICAkcnVsZSA9IGx0cmltKCRydWxlLCAnIScpOwogICAgICAgIH0KCiAgICAgICAgJGZpcnN0U2xhc2hQb3NpdGlvbiA9IHN0cnBvcygkcnVsZSwgJy8nKTsKICAgICAgICBpZiAoMCA9PT0gJGZpcnN0U2xhc2hQb3NpdGlvbikgewogICAgICAgICAgICAkcGF0dGVybiA9ICdeLyc7CiAgICAgICAgfSBlbHNlaWYgKGZhbHNlID09PSAkZmlyc3RTbGFzaFBvc2l0aW9uIHx8IHN0cmxlbigkcnVsZSkgLSAxID09PSAkZmlyc3RTbGFzaFBvc2l0aW9uKSB7CiAgICAgICAgICAgICRwYXR0ZXJuID0gJy8nOwogICAgICAgIH0KCiAgICAgICAgJHJ1bGUgPSB0cmltKCRydWxlLCAnLycpOwoKICAgICAgICAvLyByZW1vdmUgZGVsaW1pdGVycyBhcyB3ZWxsIGFzIGNhcmV0ICheKSBhbmQgZG9sbGFyIHNpZ24gKCQpIGZyb20gdGhlIHJlZ2V4CiAgICAgICAgJHJ1bGUgPSBzdWJzdHIoRmluZGVyXEdsb2I6OnRvUmVnZXgoJHJ1bGUpLCAyLCAtMik7CgogICAgICAgIHJldHVybiBhcnJheSgneycuJHBhdHRlcm4uJHJ1bGUuJyg/PSR8Lyl9JywgJG5lZ2F0ZSwgZmFsc2UpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7Cgp1c2UgWmlwQXJjaGl2ZTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKCi8qKgogKiBAYXV0aG9yIEphbiBQcmllc2VyIDxqYW5AcHJpZXNlci5uZXQ+CiAqLwpjbGFzcyBaaXBBcmNoaXZlciBpbXBsZW1lbnRzIEFyY2hpdmVySW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgYm9vbD4gKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgJGZvcm1hdHMgPSBhcnJheSgKICAgICAgICAnemlwJyA9PiB0cnVlLAogICAgKTsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmNoaXZlKCRzb3VyY2VzLCAkdGFyZ2V0LCAkZm9ybWF0LCBhcnJheSAkZXhjbHVkZXMgPSBhcnJheSgpLCAkaWdub3JlRmlsdGVycyA9IGZhbHNlKQogICAgewogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgJHNvdXJjZXMgPSAkZnMtPm5vcm1hbGl6ZVBhdGgoJHNvdXJjZXMpOwoKICAgICAgICAkemlwID0gbmV3IFppcEFyY2hpdmUoKTsKICAgICAgICAkcmVzID0gJHppcC0+b3BlbigkdGFyZ2V0LCBaaXBBcmNoaXZlOjpDUkVBVEUpOwogICAgICAgIGlmICgkcmVzID09PSB0cnVlKSB7CiAgICAgICAgICAgICRmaWxlcyA9IG5ldyBBcmNoaXZhYmxlRmlsZXNGaW5kZXIoJHNvdXJjZXMsICRleGNsdWRlcywgJGlnbm9yZUZpbHRlcnMpOwogICAgICAgICAgICBmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGUpIHsKICAgICAgICAgICAgICAgIC8qKiBAdmFyIFxTcGxGaWxlSW5mbyAkZmlsZSAqLwogICAgICAgICAgICAgICAgJGZpbGVwYXRoID0gc3RydHIoJGZpbGUtPmdldFBhdGgoKS4iLyIuJGZpbGUtPmdldEZpbGVuYW1lKCksICdcXCcsICcvJyk7CiAgICAgICAgICAgICAgICAkbG9jYWxuYW1lID0gJGZpbGVwYXRoOwogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkbG9jYWxuYW1lLCAkc291cmNlcyAuICcvJykgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkbG9jYWxuYW1lID0gc3Vic3RyKCRsb2NhbG5hbWUsIHN0cmxlbigkc291cmNlcyAuICcvJykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRmaWxlLT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICAgICAgJHppcC0+YWRkRW1wdHlEaXIoJGxvY2FsbmFtZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR6aXAtPmFkZEZpbGUoJGZpbGVwYXRoLCAkbG9jYWxuYW1lKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAqIFppcEFyY2hpdmU6OnNldEV4dGVybmFsQXR0cmlidXRlc05hbWUgaXMgYXZhaWxhYmxlIGZyb20gPj0gUEhQIDUuNgogICAgICAgICAgICAgICAgICogc2V0RXh0ZXJuYWxBdHRyaWJ1dGVzTmFtZSgpIGlzIG9ubHkgYXZhaWxhYmxlIHdpdGggbGliemlwIDAuMTEuMiBvciBhYm92ZQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDAgJiYgbWV0aG9kX2V4aXN0cygkemlwLCAnc2V0RXh0ZXJuYWxBdHRyaWJ1dGVzTmFtZScpKSB7CiAgICAgICAgICAgICAgICAgICAgJHBlcm1zID0gZmlsZXBlcm1zKCRmaWxlcGF0aCk7CgogICAgICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICAgICAqIEVuc3VyZSB0byBwcmVzZXJ2ZSB0aGUgcGVybWlzc2lvbiB1bWFza3MgZm9yIHRoZSBmaWxlcGF0aCBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAkemlwLT5zZXRFeHRlcm5hbEF0dHJpYnV0ZXNOYW1lKCRsb2NhbG5hbWUsIFppcEFyY2hpdmU6Ok9QU1lTX1VOSVgsICRwZXJtcyA8PCAxNik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR6aXAtPmNsb3NlKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGFyZ2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRtZXNzYWdlID0gc3ByaW50ZigKICAgICAgICAgICAgIkNvdWxkIG5vdCBjcmVhdGUgYXJjaGl2ZSAnJXMnIGZyb20gJyVzJzogJXMiLAogICAgICAgICAgICAkdGFyZ2V0LAogICAgICAgICAgICAkc291cmNlcywKICAgICAgICAgICAgJHppcC0+Z2V0U3RhdHVzU3RyaW5nKCkKICAgICAgICApOwogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkbWVzc2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJGZvcm1hdCwgJHNvdXJjZVR5cGUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KHN0YXRpYzo6JGZvcm1hdHNbJGZvcm1hdF0pICYmICR0aGlzLT5jb21wcmVzc2lvbkF2YWlsYWJsZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY29tcHJlc3Npb25BdmFpbGFibGUoKQogICAgewogICAgICAgIHJldHVybiBjbGFzc19leGlzdHMoJ1ppcEFyY2hpdmUnKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKLyoqCiAqIEBhdXRob3IgVGlsbCBLbGFtcGFlY2tlbCA8dGlsbEBwaHAubmV0PgogKiBAYXV0aG9yIE1hdHRoaWV1IE1vcXVldCA8bWF0dGhpZXVAbW9xdWV0Lm5ldD4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmludGVyZmFjZSBBcmNoaXZlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBhcmNoaXZlIGZyb20gdGhlIHNvdXJjZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRzb3VyY2VzICAgICAgIFRoZSBzb3VyY2VzIGRpcmVjdG9yeQogICAgICogQHBhcmFtIHN0cmluZyAgICR0YXJnZXQgICAgICAgIFRoZSB0YXJnZXQgZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAgICRmb3JtYXQgICAgICAgIFRoZSBmb3JtYXQgdXNlZCBmb3IgYXJjaGl2ZQogICAgICogQHBhcmFtIHN0cmluZ1tdICRleGNsdWRlcyAgICAgIEEgbGlzdCBvZiBwYXR0ZXJucyBmb3IgZmlsZXMgdG8gZXhjbHVkZQogICAgICogQHBhcmFtIGJvb2wgICAgICRpZ25vcmVGaWx0ZXJzIFdoZXRoZXIgdG8gaWdub3JlIGZpbHRlcnMgd2hlbiBsb29raW5nIGZvciBmaWxlcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBwYXRoIHRvIHRoZSB3cml0dGVuIGFyY2hpdmUgZmlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXJjaGl2ZSgkc291cmNlcywgJHRhcmdldCwgJGZvcm1hdCwgYXJyYXkgJGV4Y2x1ZGVzID0gYXJyYXkoKSwgJGlnbm9yZUZpbHRlcnMgPSBmYWxzZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXQgc3VwcG9ydGVkIGJ5IHRoZSBhcmNoaXZlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtYXQgICAgIFRoZSBhcmNoaXZlIGZvcm1hdAogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlVHlwZSBUaGUgc291cmNlIHR5cGUgKGdpdCwgc3ZuLCBoZywgZXRjLikKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgZm9ybWF0IGlzIHN1cHBvcnRlZCBieSB0aGUgYXJjaGl2ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1cHBvcnRzKCRmb3JtYXQsICRzb3VyY2VUeXBlKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcTG9vcDsKdXNlIENvbXBvc2VyXFV0aWxcU3luY0hlbHBlcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIE1hdHRoaWV1IE1vcXVldCA8bWF0dGhpZXVAbW9xdWV0Lm5ldD4KICogQGF1dGhvciBUaWxsIEtsYW1wYWVja2VsIDx0aWxsQHBocC5uZXQ+CiAqLwpjbGFzcyBBcmNoaXZlTWFuYWdlcgp7CiAgICAvKiogQHZhciBEb3dubG9hZE1hbmFnZXIgKi8KICAgIHByb3RlY3RlZCAkZG93bmxvYWRNYW5hZ2VyOwogICAgLyoqIEB2YXIgTG9vcCAqLwogICAgcHJvdGVjdGVkICRsb29wOwoKICAgIC8qKgogICAgICogQHZhciBBcmNoaXZlckludGVyZmFjZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJjaGl2ZXJzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJG92ZXJ3cml0ZUZpbGVzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBEb3dubG9hZE1hbmFnZXIgJGRvd25sb2FkTWFuYWdlciBBIG1hbmFnZXIgdXNlZCB0byBkb3dubG9hZCBwYWNrYWdlIHNvdXJjZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KERvd25sb2FkTWFuYWdlciAkZG93bmxvYWRNYW5hZ2VyLCBMb29wICRsb29wKQogICAgewogICAgICAgICR0aGlzLT5kb3dubG9hZE1hbmFnZXIgPSAkZG93bmxvYWRNYW5hZ2VyOwogICAgICAgICR0aGlzLT5sb29wID0gJGxvb3A7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQXJjaGl2ZXJJbnRlcmZhY2UgJGFyY2hpdmVyCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRBcmNoaXZlcihBcmNoaXZlckludGVyZmFjZSAkYXJjaGl2ZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyY2hpdmVyc1tdID0gJGFyY2hpdmVyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHdoZXRoZXIgZXhpc3RpbmcgYXJjaGl2ZXMgc2hvdWxkIGJlIG92ZXJ3cml0dGVuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG92ZXJ3cml0ZUZpbGVzIE5ldyBzZXR0aW5nCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3ZlcndyaXRlRmlsZXMoJG92ZXJ3cml0ZUZpbGVzKQogICAgewogICAgICAgICR0aGlzLT5vdmVyd3JpdGVGaWxlcyA9ICRvdmVyd3JpdGVGaWxlczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGUgYSBkaXN0aW5jdCBmaWxlbmFtZSBmb3IgYSBwYXJ0aWN1bGFyIHZlcnNpb24gb2YgYSBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgVGhlIHBhY2thZ2UgdG8gZ2V0IGEgbmFtZSBmb3IKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIGZpbGVuYW1lIHdpdGhvdXQgYW4gZXh0ZW5zaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlRmlsZW5hbWUoQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QXJjaGl2ZU5hbWUoKSkgewogICAgICAgICAgICAkYmFzZU5hbWUgPSAkcGFja2FnZS0+Z2V0QXJjaGl2ZU5hbWUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYmFzZU5hbWUgPSBQcmVnOjpyZXBsYWNlKCcjW15hLXowLTktX10jaScsICctJywgJHBhY2thZ2UtPmdldE5hbWUoKSk7CiAgICAgICAgfQogICAgICAgICRuYW1lUGFydHMgPSBhcnJheSgkYmFzZU5hbWUpOwoKICAgICAgICBpZiAobnVsbCAhPT0gJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSAmJiBQcmVnOjppc01hdGNoKCd7XlthLWYwLTldezQwfSR9JywgJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSkpIHsKICAgICAgICAgICAgYXJyYXlfcHVzaCgkbmFtZVBhcnRzLCAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpLCAkcGFja2FnZS0+Z2V0RGlzdFR5cGUoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYXJyYXlfcHVzaCgkbmFtZVBhcnRzLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLCAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgJG5hbWVQYXJ0c1tdID0gc3Vic3RyKHNoYTEoJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSwgMCwgNik7CiAgICAgICAgfQoKICAgICAgICAkbmFtZSA9IGltcGxvZGUoJy0nLCBhcnJheV9maWx0ZXIoJG5hbWVQYXJ0cywgZnVuY3Rpb24gKCRwKSB7CiAgICAgICAgICAgIHJldHVybiAhZW1wdHkoJHApOwogICAgICAgIH0pKTsKCiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKCcvJywgJy0nLCAkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gYXJjaGl2ZSBvZiB0aGUgc3BlY2lmaWVkIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgICRwYWNrYWdlICAgICAgIFRoZSBwYWNrYWdlIHRvIGFyY2hpdmUKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkZm9ybWF0ICAgICAgICBUaGUgZm9ybWF0IG9mIHRoZSBhcmNoaXZlICh6aXAsIHRhciwgLi4uKQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICR0YXJnZXREaXIgICAgIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gYnVpbGQgdGhlIGFyY2hpdmUKICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgICAgICAgICAgICAgICAkZmlsZU5hbWUgICAgICBUaGUgcmVsYXRpdmUgZmlsZSBuYW1lIHRvIHVzZSBmb3IgdGhlIGFyY2hpdmUsIG9yIG51bGwgdG8gZ2VuZXJhdGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgcGFja2FnZSBuYW1lLiBOb3RlIHRoYXQgdGhlIGZvcm1hdCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoaXMgbmFtZQogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICRpZ25vcmVGaWx0ZXJzIElnbm9yZSBmaWx0ZXJzIHdoZW4gbG9va2luZyBmb3IgZmlsZXMgaW4gdGhlIHBhY2thZ2UKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcgICAgICAgICAgICAgICAgICAgIFRoZSBwYXRoIG9mIHRoZSBjcmVhdGVkIGFyY2hpdmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyY2hpdmUoQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZm9ybWF0LCAkdGFyZ2V0RGlyLCAkZmlsZU5hbWUgPSBudWxsLCAkaWdub3JlRmlsdGVycyA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChlbXB0eSgkZm9ybWF0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignRm9ybWF0IG11c3QgYmUgc3BlY2lmaWVkJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBTZWFyY2ggZm9yIHRoZSBtb3N0IGFwcHJvcHJpYXRlIGFyY2hpdmVyCiAgICAgICAgJHVzYWJsZUFyY2hpdmVyID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXJjaGl2ZXJzIGFzICRhcmNoaXZlcikgewogICAgICAgICAgICBpZiAoJGFyY2hpdmVyLT5zdXBwb3J0cygkZm9ybWF0LCAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpKSkgewogICAgICAgICAgICAgICAgJHVzYWJsZUFyY2hpdmVyID0gJGFyY2hpdmVyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIENoZWNrcyB0aGUgZm9ybWF0L3NvdXJjZSB0eXBlIGFyZSBzdXBwb3J0ZWQgYmVmb3JlIGRvd25sb2FkaW5nIHRoZSBwYWNrYWdlCiAgICAgICAgaWYgKG51bGwgPT09ICR1c2FibGVBcmNoaXZlcikgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignTm8gYXJjaGl2ZXIgZm91bmQgdG8gc3VwcG9ydCAlcyBmb3JtYXQnLCAkZm9ybWF0KSk7CiAgICAgICAgfQoKICAgICAgICAkZmlsZXN5c3RlbSA9IG5ldyBGaWxlc3lzdGVtKCk7CgogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRzb3VyY2VQYXRoID0gcmVhbHBhdGgoJy4nKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBEaXJlY3RvcnkgdXNlZCB0byBkb3dubG9hZCB0aGUgc291cmNlcwogICAgICAgICAgICAkc291cmNlUGF0aCA9IHN5c19nZXRfdGVtcF9kaXIoKS4nL2NvbXBvc2VyX2FyY2hpdmUnLnVuaXFpZCgpOwogICAgICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRzb3VyY2VQYXRoKTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBEb3dubG9hZCBzb3VyY2VzCiAgICAgICAgICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmRvd25sb2FkKCRwYWNrYWdlLCAkc291cmNlUGF0aCk7CiAgICAgICAgICAgICAgICBTeW5jSGVscGVyOjphd2FpdCgkdGhpcy0+bG9vcCwgJHByb21pc2UpOwogICAgICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5pbnN0YWxsKCRwYWNrYWdlLCAkc291cmNlUGF0aCk7CiAgICAgICAgICAgICAgICBTeW5jSGVscGVyOjphd2FpdCgkdGhpcy0+bG9vcCwgJHByb21pc2UpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCRzb3VyY2VQYXRoKTsKICAgICAgICAgICAgICAgIHRocm93ICAkZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgZXhjbHVkZSBmcm9tIGRvd25sb2FkZWQgY29tcG9zZXIuanNvbgogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGNvbXBvc2VySnNvblBhdGggPSAkc291cmNlUGF0aC4nL2NvbXBvc2VyLmpzb24nKSkgewogICAgICAgICAgICAgICAgJGpzb25GaWxlID0gbmV3IEpzb25GaWxlKCRjb21wb3Nlckpzb25QYXRoKTsKICAgICAgICAgICAgICAgICRqc29uRGF0YSA9ICRqc29uRmlsZS0+cmVhZCgpOwogICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkanNvbkRhdGFbJ2FyY2hpdmUnXVsnbmFtZSddKSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRBcmNoaXZlTmFtZSgkanNvbkRhdGFbJ2FyY2hpdmUnXVsnbmFtZSddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJGpzb25EYXRhWydhcmNoaXZlJ11bJ2V4Y2x1ZGUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0QXJjaGl2ZUV4Y2x1ZGVzKCRqc29uRGF0YVsnYXJjaGl2ZSddWydleGNsdWRlJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGZpbGVOYW1lKSB7CiAgICAgICAgICAgICRwYWNrYWdlTmFtZSA9ICR0aGlzLT5nZXRQYWNrYWdlRmlsZW5hbWUoJHBhY2thZ2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwYWNrYWdlTmFtZSA9ICRmaWxlTmFtZTsKICAgICAgICB9CgogICAgICAgIC8vIEFyY2hpdmUgZmlsZW5hbWUKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0YXJnZXREaXIpOwogICAgICAgICR0YXJnZXQgPSByZWFscGF0aCgkdGFyZ2V0RGlyKS4nLycuJHBhY2thZ2VOYW1lLicuJy4kZm9ybWF0OwogICAgICAgICRmaWxlc3lzdGVtLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoZGlybmFtZSgkdGFyZ2V0KSk7CgogICAgICAgIGlmICghJHRoaXMtPm92ZXJ3cml0ZUZpbGVzICYmIGZpbGVfZXhpc3RzKCR0YXJnZXQpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgLy8gQ3JlYXRlIHRoZSBhcmNoaXZlCiAgICAgICAgJHRlbXBUYXJnZXQgPSBzeXNfZ2V0X3RlbXBfZGlyKCkuJy9jb21wb3Nlcl9hcmNoaXZlJy51bmlxaWQoKS4nLicuJGZvcm1hdDsKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKGRpcm5hbWUoJHRlbXBUYXJnZXQpKTsKCiAgICAgICAgJGFyY2hpdmVQYXRoID0gJHVzYWJsZUFyY2hpdmVyLT5hcmNoaXZlKCRzb3VyY2VQYXRoLCAkdGVtcFRhcmdldCwgJGZvcm1hdCwgJHBhY2thZ2UtPmdldEFyY2hpdmVFeGNsdWRlcygpLCAkaWdub3JlRmlsdGVycyk7CiAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbmFtZSgkYXJjaGl2ZVBhdGgsICR0YXJnZXQpOwoKICAgICAgICAvLyBjbGVhbnVwIHRlbXBvcmFyeSBkb3dubG9hZAogICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAkZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCRzb3VyY2VQYXRoKTsKICAgICAgICB9CiAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZSgkdGVtcFRhcmdldCk7CgogICAgICAgIHJldHVybiAkdGFyZ2V0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7CgovKioKICogQW4gZXhjbHVkZSBmaWx0ZXIgd2hpY2ggcHJvY2Vzc2VzIGNvbXBvc2VyJ3Mgb3duIGV4Y2x1ZGUgcnVsZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIENvbXBvc2VyRXhjbHVkZUZpbHRlciBleHRlbmRzIEJhc2VFeGNsdWRlRmlsdGVyCnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlUGF0aCBEaXJlY3RvcnkgY29udGFpbmluZyBzb3VyY2VzIHRvIGJlIGZpbHRlcmVkCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGV4Y2x1ZGVSdWxlcyBBbiBhcnJheSBvZiBleGNsdWRlIHJ1bGVzIGZyb20gY29tcG9zZXIuanNvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNvdXJjZVBhdGgsIGFycmF5ICRleGNsdWRlUnVsZXMpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkc291cmNlUGF0aCk7CiAgICAgICAgJHRoaXMtPmV4Y2x1ZGVQYXR0ZXJucyA9ICR0aGlzLT5nZW5lcmF0ZVBhdHRlcm5zKCRleGNsdWRlUnVsZXMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7Cgp1c2UgRmlsdGVySXRlcmF0b3I7CnVzZSBQaGFyRGF0YTsKCmNsYXNzIEFyY2hpdmFibGVGaWxlc0ZpbHRlciBleHRlbmRzIEZpbHRlckl0ZXJhdG9yCnsKICAgIC8qKiBAdmFyIHN0cmluZ1tdICovCiAgICBwcml2YXRlICRkaXJzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgYWNjZXB0YWJsZSwgb3RoZXJ3aXNlIGZhbHNlLgogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHQoKQogICAgewogICAgICAgICRmaWxlID0gJHRoaXMtPmdldElubmVySXRlcmF0b3IoKS0+Y3VycmVudCgpOwogICAgICAgIGlmICgkZmlsZS0+aXNEaXIoKSkgewogICAgICAgICAgICAkdGhpcy0+ZGlyc1tdID0gKHN0cmluZykgJGZpbGU7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEVtcHR5RGlyKFBoYXJEYXRhICRwaGFyLCAkc291cmNlcykKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZGlycyBhcyAkZmlsZXBhdGgpIHsKICAgICAgICAgICAgJGxvY2FsbmFtZSA9IHN0cl9yZXBsYWNlKCRzb3VyY2VzIC4gIi8iLCAnJywgJGZpbGVwYXRoKTsKICAgICAgICAgICAgJHBoYXItPmFkZEVtcHR5RGlyKCRsb2NhbG5hbWUpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKCi8qKgogKiBBbiBleGNsdWRlIGZpbHRlciB0aGF0IHByb2Nlc3NlcyBnaXRhdHRyaWJ1dGVzCiAqCiAqIEl0IHJlc3BlY3RzIGV4cG9ydC1pZ25vcmUgZ2l0IGF0dHJpYnV0ZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEdpdEV4Y2x1ZGVGaWx0ZXIgZXh0ZW5kcyBCYXNlRXhjbHVkZUZpbHRlcgp7CiAgICAvKioKICAgICAqIFBhcnNlcyAuZ2l0YXR0cmlidXRlcyBpZiBpdCBleGlzdHMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2VQYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc291cmNlUGF0aCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRzb3VyY2VQYXRoKTsKCiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRzb3VyY2VQYXRoLicvLmdpdGF0dHJpYnV0ZXMnKSkgewogICAgICAgICAgICAkdGhpcy0+ZXhjbHVkZVBhdHRlcm5zID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXhjbHVkZVBhdHRlcm5zLAogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlTGluZXMoCiAgICAgICAgICAgICAgICAgICAgZmlsZSgkc291cmNlUGF0aC4nLy5naXRhdHRyaWJ1dGVzJyksCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoJHRoaXMsICdwYXJzZUdpdEF0dHJpYnV0ZXNMaW5lJykKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxsYmFjayBwYXJzZXIgd2hpY2ggZmluZHMgZXhwb3J0LWlnbm9yZSBydWxlcyBpbiBnaXQgYXR0cmlidXRlIGxpbmVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGluZSBBIGxpbmUgZnJvbSAuZ2l0YXR0cmlidXRlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7MDogc3RyaW5nLCAxOiBib29sLCAyOiBib29sfXxudWxsIEFuIGV4Y2x1ZGUgcGF0dGVybiBmb3IgZmlsdGVyKCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlR2l0QXR0cmlidXRlc0xpbmUoJGxpbmUpCiAgICB7CiAgICAgICAgJHBhcnRzID0gUHJlZzo6c3BsaXQoJyNccysjJywgJGxpbmUpOwoKICAgICAgICBpZiAoY291bnQoJHBhcnRzKSA9PSAyICYmICRwYXJ0c1sxXSA9PT0gJ2V4cG9ydC1pZ25vcmUnKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2VuZXJhdGVQYXR0ZXJuKCRwYXJ0c1swXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoY291bnQoJHBhcnRzKSA9PSAyICYmICRwYXJ0c1sxXSA9PT0gJy1leHBvcnQtaWdub3JlJykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdlbmVyYXRlUGF0dGVybignIScuJHBhcnRzWzBdKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7CgovKioKICogRGVmaW5lcyBwYWNrYWdlIG1ldGFkYXRhIHRoYXQgaXMgbm90IG5lY2Vzc2FyaWx5IG5lZWRlZCBmb3Igc29sdmluZyBhbmQgaW5zdGFsbGluZyBwYWNrYWdlcwogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KaW50ZXJmYWNlIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSBleHRlbmRzIFBhY2thZ2VJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzY3JpcHRzIG9mIHRoaXMgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmdbXT4gTWFwIG9mIHNjcmlwdCBuYW1lIHRvIGFycmF5IG9mIGhhbmRsZXJzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY3JpcHRzKCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGFycmF5PHN0cmluZywgc3RyaW5nW10+ICRzY3JpcHRzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNjcmlwdHMoYXJyYXkgJHNjcmlwdHMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkW10gUmVwb3NpdG9yaWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3JpZXMoKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVwb3NpdG9yaWVzCiAgICAgKgogICAgICogQHBhcmFtICBtaXhlZFtdICRyZXBvc2l0b3JpZXMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yaWVzKGFycmF5ICRyZXBvc2l0b3JpZXMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBsaWNlbnNlLCBlLmcuIE1JVCwgQlNELCBHUEwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIFRoZSBwYWNrYWdlIGxpY2Vuc2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMaWNlbnNlKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGxpY2Vuc2UKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZ1tdICRsaWNlbnNlCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExpY2Vuc2UoYXJyYXkgJGxpY2Vuc2UpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBrZXl3b3JkcyByZWxhdGluZyB0byB0aGUgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEtleXdvcmRzKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGtleXdvcmRzCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmdbXSAka2V5d29yZHMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0S2V5d29yZHMoYXJyYXkgJGtleXdvcmRzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgZGVzY3JpcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuID9zdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGRlc2NyaXB0aW9uCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGRlc2NyaXB0aW9uCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlc2NyaXB0aW9uKCRkZXNjcmlwdGlvbik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlIGhvbWVwYWdlCiAgICAgKgogICAgICogQHJldHVybiA/c3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIb21lcGFnZSgpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBob21lcGFnZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRob21lcGFnZQogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIb21lcGFnZSgkaG9tZXBhZ2UpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBhdXRob3JzIG9mIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogRWFjaCBpdGVtIGNhbiBjb250YWluIG5hbWUvaG9tZXBhZ2UvZW1haWwga2V5cwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8YXJyYXl7bmFtZT86IHN0cmluZywgaG9tZXBhZ2U/OiBzdHJpbmcsIGVtYWlsPzogc3RyaW5nLCByb2xlPzogc3RyaW5nfT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dGhvcnMoKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgYXV0aG9ycwogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXk8YXJyYXl7bmFtZT86IHN0cmluZywgaG9tZXBhZ2U/OiBzdHJpbmcsIGVtYWlsPzogc3RyaW5nLCByb2xlPzogc3RyaW5nfT4gJGF1dGhvcnMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0aG9ycyhhcnJheSAkYXV0aG9ycyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdXBwb3J0IGluZm9ybWF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXtpc3N1ZXM/OiBzdHJpbmcsIGZvcnVtPzogc3RyaW5nLCB3aWtpPzogc3RyaW5nLCBzb3VyY2U/OiBzdHJpbmcsIGVtYWlsPzogc3RyaW5nLCBpcmM/OiBzdHJpbmcsIGRvY3M/OiBzdHJpbmcsIHJzcz86IHN0cmluZywgY2hhdD86IHN0cmluZ30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1cHBvcnQoKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgc3VwcG9ydCBpbmZvcm1hdGlvbgogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXl7aXNzdWVzPzogc3RyaW5nLCBmb3J1bT86IHN0cmluZywgd2lraT86IHN0cmluZywgc291cmNlPzogc3RyaW5nLCBlbWFpbD86IHN0cmluZywgaXJjPzogc3RyaW5nLCBkb2NzPzogc3RyaW5nLCByc3M/OiBzdHJpbmcsIGNoYXQ/OiBzdHJpbmd9ICRzdXBwb3J0CiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN1cHBvcnQoYXJyYXkgJHN1cHBvcnQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBmdW5kaW5nIG9wdGlvbnMgZm9yIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogRWFjaCBpdGVtIHdpbGwgY29udGFpbiB0eXBlIGFuZCB1cmwga2V5cwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXk8YXJyYXl7dHlwZT86IHN0cmluZywgdXJsPzogc3RyaW5nfT4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZ1bmRpbmcoKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgZnVuZGluZwogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXk8YXJyYXl7dHlwZT86IHN0cmluZywgdXJsPzogc3RyaW5nfT4gJGZ1bmRpbmcKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RnVuZGluZyhhcnJheSAkZnVuZGluZyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGlmIHRoZSBwYWNrYWdlIGlzIGFiYW5kb25lZCBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQWJhbmRvbmVkKCk7CgogICAgLyoqCiAgICAgKiBJZiB0aGUgcGFja2FnZSBpcyBhYmFuZG9uZWQgYW5kIGhhcyBhIHN1Z2dlc3RlZCByZXBsYWNlbWVudCwgdGhpcyBtZXRob2QgcmV0dXJucyBpdAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcGxhY2VtZW50UGFja2FnZSgpOwoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sfHN0cmluZyAkYWJhbmRvbmVkCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFiYW5kb25lZCgkYWJhbmRvbmVkKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgZGVmYXVsdCBiYXNlIGZpbGVuYW1lIGZvciBhcmNoaXZlCiAgICAgKgogICAgICogQHJldHVybiA/c3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmNoaXZlTmFtZSgpOwoKICAgIC8qKgogICAgICogU2V0cyBkZWZhdWx0IGJhc2UgZmlsZW5hbWUgZm9yIGFyY2hpdmUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmNoaXZlTmFtZSgkbmFtZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwYXR0ZXJucyB0byBleGNsdWRlIGZyb20gcGFja2FnZSBhcmNoaXZlcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyY2hpdmVFeGNsdWRlcygpOwoKICAgIC8qKgogICAgICogU2V0cyBhIGxpc3Qgb2YgcGF0dGVybnMgdG8gYmUgZXhjbHVkZWQgZnJvbSBhcmNoaXZlcwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nW10gJGV4Y2x1ZGVzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVFeGNsdWRlcyhhcnJheSAkZXhjbHVkZXMpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludEludGVyZmFjZTsKCi8qKgogKiBSZXByZXNlbnRzIGEgbGluayBiZXR3ZWVuIHR3byBwYWNrYWdlcywgcmVwcmVzZW50ZWQgYnkgdGhlaXIgbmFtZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIExpbmsKewogICAgY29uc3QgVFlQRV9SRVFVSVJFID0gJ3JlcXVpcmVzJzsKICAgIGNvbnN0IFRZUEVfREVWX1JFUVVJUkUgPSAnZGV2UmVxdWlyZXMnOwogICAgY29uc3QgVFlQRV9QUk9WSURFID0gJ3Byb3ZpZGVzJzsKICAgIGNvbnN0IFRZUEVfQ09ORkxJQ1QgPSAnY29uZmxpY3RzJzsKICAgIGNvbnN0IFRZUEVfUkVQTEFDRSA9ICdyZXBsYWNlcyc7CgogICAgLyoqCiAgICAgKiBTcGVjaWFsIHR5cGUKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBjb25zdCBUWVBFX0RPRVNfTk9UX1JFUVVJUkUgPSAnZG9lcyBub3QgcmVxdWlyZSc7CiAgICAvKioKICAgICAqIFRPRE8gc2hvdWxkIGJlIG1hcmtlZCBwcml2YXRlIG9uY2UgNS4zIGlzIGRyb3BwZWQKICAgICAqIEBwcml2YXRlCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfVU5LTk9XTiA9ICdyZWxhdGVzIHRvJzsKCiAgICAvKioKICAgICAqIFdpbGwgYmUgY29udmVydGVkIGludG8gYSBjb25zdGFudCBvbmNlIHRoZSBtaW4gUEhQIHZlcnNpb24gYWxsb3dzIHRoaXMKICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzZWxmOjpUWVBFX1JFUVVJUkV8c2VsZjo6VFlQRV9ERVZfUkVRVUlSRXxzZWxmOjpUWVBFX1BST1ZJREV8c2VsZjo6VFlQRV9DT05GTElDVHxzZWxmOjpUWVBFX1JFUExBQ0U+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgJFRZUEVTID0gYXJyYXkoCiAgICAgICAgc2VsZjo6VFlQRV9SRVFVSVJFLAogICAgICAgIHNlbGY6OlRZUEVfREVWX1JFUVVJUkUsCiAgICAgICAgc2VsZjo6VFlQRV9QUk9WSURFLAogICAgICAgIHNlbGY6OlRZUEVfQ09ORkxJQ1QsCiAgICAgICAgc2VsZjo6VFlQRV9SRVBMQUNFLAogICAgKTsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICR0YXJnZXQ7CgogICAgLyoqCiAgICAgKiBAdmFyIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRjb25zdHJhaW50OwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBwaHBzdGFuLXZhciBzdHJpbmcgJGRlc2NyaXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZGVzY3JpcHRpb247CgogICAgLyoqCiAgICAgKiBAdmFyID9zdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlDb25zdHJhaW50OwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBwYWNrYWdlIGxpbmsuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgJHNvdXJjZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgJHRhcmdldAogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgICAgICAgQ29uc3RyYWludCBhcHBseWluZyB0byB0aGUgdGFyZ2V0IG9mIHRoaXMgbGluawogICAgICogQHBhcmFtIHNlbGY6OlRZUEVfKiAgICAgICAgJGRlc2NyaXB0aW9uICAgICAgVXNlZCB0byBjcmVhdGUgYSBkZXNjcmlwdGl2ZSBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAgICAgICRwcmV0dHlDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgKICAgICAgICAkc291cmNlLAogICAgICAgICR0YXJnZXQsCiAgICAgICAgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCwKICAgICAgICAkZGVzY3JpcHRpb24gPSBzZWxmOjpUWVBFX1VOS05PV04sCiAgICAgICAgJHByZXR0eUNvbnN0cmFpbnQgPSBudWxsCiAgICApIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gc3RydG9sb3dlcigkc291cmNlKTsKICAgICAgICAkdGhpcy0+dGFyZ2V0ID0gc3RydG9sb3dlcigkdGFyZ2V0KTsKICAgICAgICAkdGhpcy0+Y29uc3RyYWludCA9ICRjb25zdHJhaW50OwogICAgICAgICR0aGlzLT5kZXNjcmlwdGlvbiA9IHNlbGY6OlRZUEVfREVWX1JFUVVJUkUgPT09ICRkZXNjcmlwdGlvbiA/ICdyZXF1aXJlcyAoZm9yIGRldmVsb3BtZW50KScgOiAkZGVzY3JpcHRpb247CiAgICAgICAgJHRoaXMtPnByZXR0eUNvbnN0cmFpbnQgPSAkcHJldHR5Q29uc3RyYWludDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhcmdldCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50YXJnZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnN0cmFpbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uc3RyYWludDsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiBJZiBubyBwcmV0dHkgY29uc3RyYWludCB3YXMgcHJvdmlkZWQKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlDb25zdHJhaW50KCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnByZXR0eUNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oc3ByaW50ZignTGluayAlcyBoYXMgYmVlbiBtaXNjb25maWd1cmVkIGFuZCBoYWQgbm8gcHJldHR5Q29uc3RyYWludCBnaXZlbi4nLCAkdGhpcykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcmV0dHlDb25zdHJhaW50OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlLicgJy4kdGhpcy0+ZGVzY3JpcHRpb24uJyAnLiR0aGlzLT50YXJnZXQuJyAoJy4kdGhpcy0+Y29uc3RyYWludC4nKSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHNvdXJjZVBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoUGFja2FnZUludGVyZmFjZSAkc291cmNlUGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gJHNvdXJjZVBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLicgJy4kdGhpcy0+ZGVzY3JpcHRpb24uJyAnLiR0aGlzLT50YXJnZXQuJyAnLiR0aGlzLT5jb25zdHJhaW50LT5nZXRQcmV0dHlTdHJpbmcoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb247Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxTZW12ZXJcVmVyc2lvblBhcnNlciBhcyBTZW12ZXJWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcU2VtdmVyXFNlbXZlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CgpjbGFzcyBWZXJzaW9uUGFyc2VyIGV4dGVuZHMgU2VtdmVyVmVyc2lvblBhcnNlcgp7CiAgICBjb25zdCBERUZBVUxUX0JSQU5DSF9BTElBUyA9ICc5OTk5OTk5LWRldic7CgogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPiBDb25zdHJhaW50IHBhcnNpbmcgY2FjaGUgKi8KICAgIHByaXZhdGUgc3RhdGljICRjb25zdHJhaW50cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludHMpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldChzZWxmOjokY29uc3RyYWludHNbJGNvbnN0cmFpbnRzXSkpIHsKICAgICAgICAgICAgc2VsZjo6JGNvbnN0cmFpbnRzWyRjb25zdHJhaW50c10gPSBwYXJlbnQ6OnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokY29uc3RyYWludHNbJGNvbnN0cmFpbnRzXTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBhcnJheSBvZiBzdHJpbmdzIHJlcHJlc2VudGluZyBwYWNrYWdlL3ZlcnNpb24gcGFpcnMuCiAgICAgKgogICAgICogVGhlIHBhcnNpbmcgcmVzdWx0cyBpbiBhbiBhcnJheSBvZiBhcnJheXMsIGVhY2ggb2Ygd2hpY2gKICAgICAqIGNvbnRhaW4gYSAnbmFtZScga2V5IHdpdGggdmFsdWUgYW5kIG9wdGlvbmFsbHkgYSAndmVyc2lvbicga2V5IHdpdGggdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRwYWlycyBhIHNldCBvZiBwYWNrYWdlL3ZlcnNpb24gcGFpcnMgc2VwYXJhdGVkIGJ5ICI6IiwgIj0iIG9yICIgIgogICAgICoKICAgICAqIEByZXR1cm4gbGlzdDxhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmd9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VOYW1lVmVyc2lvblBhaXJzKGFycmF5ICRwYWlycykKICAgIHsKICAgICAgICAkcGFpcnMgPSBhcnJheV92YWx1ZXMoJHBhaXJzKTsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKCiAgICAgICAgZm9yICgkaSA9IDAsICRjb3VudCA9IGNvdW50KCRwYWlycyk7ICRpIDwgJGNvdW50OyAkaSsrKSB7CiAgICAgICAgICAgICRwYWlyID0gUHJlZzo6cmVwbGFjZSgne14oW149OiBdKylbPTogXSguKikkfScsICckMSAkMicsIHRyaW0oJHBhaXJzWyRpXSkpOwogICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkcGFpciwgJyAnKSAmJiBpc3NldCgkcGFpcnNbJGkgKyAxXSkgJiYgZmFsc2UgPT09IHN0cnBvcygkcGFpcnNbJGkgKyAxXSwgJy8nKSAmJiAhUHJlZzo6aXNNYXRjaCgneyg/PD1bYS16MC05Xy8tXSlcKnxcKig/PVthLXowLTlfLy1dKX1pJywgJHBhaXJzWyRpICsgMV0pICYmICFQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRwYWlyc1skaSArIDFdKSkgewogICAgICAgICAgICAgICAgJHBhaXIgLj0gJyAnLiRwYWlyc1skaSArIDFdOwogICAgICAgICAgICAgICAgJGkrKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHN0cnBvcygkcGFpciwgJyAnKSkgewogICAgICAgICAgICAgICAgbGlzdCgkbmFtZSwgJHZlcnNpb24pID0gZXhwbG9kZSgnICcsICRwYWlyLCAyKTsKICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9IGFycmF5KCduYW1lJyA9PiAkbmFtZSwgJ3ZlcnNpb24nID0+ICR2ZXJzaW9uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9IGFycmF5KCduYW1lJyA9PiAkcGFpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbm9ybWFsaXplZEZyb20KICAgICAqIEBwYXJhbSBzdHJpbmcgJG5vcm1hbGl6ZWRUbwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzVXBncmFkZSgkbm9ybWFsaXplZEZyb20sICRub3JtYWxpemVkVG8pCiAgICB7CiAgICAgICAgaWYgKCRub3JtYWxpemVkRnJvbSA9PT0gJG5vcm1hbGl6ZWRUbykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChpbl9hcnJheSgkbm9ybWFsaXplZEZyb20sIGFycmF5KCdkZXYtbWFzdGVyJywgJ2Rldi10cnVuaycsICdkZXYtZGVmYXVsdCcpLCB0cnVlKSkgewogICAgICAgICAgICAkbm9ybWFsaXplZEZyb20gPSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUzsKICAgICAgICB9CiAgICAgICAgaWYgKGluX2FycmF5KCRub3JtYWxpemVkVG8sIGFycmF5KCdkZXYtbWFzdGVyJywgJ2Rldi10cnVuaycsICdkZXYtZGVmYXVsdCcpLCB0cnVlKSkgewogICAgICAgICAgICAkbm9ybWFsaXplZFRvID0gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVM7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCRub3JtYWxpemVkRnJvbSwgJ2Rldi0nKSA9PT0gMCB8fCBzdHJwb3MoJG5vcm1hbGl6ZWRUbywgJ2Rldi0nKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRzb3J0ZWQgPSBTZW12ZXI6OnNvcnQoYXJyYXkoJG5vcm1hbGl6ZWRUbywgJG5vcm1hbGl6ZWRGcm9tKSk7CgogICAgICAgIHJldHVybiAkc29ydGVkWzBdID09PSAkbm9ybWFsaXplZEZyb207CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEhnRHJpdmVyOwp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgQ29tcG9zZXJcU2VtdmVyXFZlcnNpb25QYXJzZXIgYXMgU2VtdmVyVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFV0aWxcR2l0IGFzIEdpdFV0aWw7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXFN2biBhcyBTdm5VdGlsOwoKLyoqCiAqIFRyeSB0byBndWVzcyB0aGUgY3VycmVudCB2ZXJzaW9uIG51bWJlciBiYXNlZCBvbiBkaWZmZXJlbnQgVkNTIGNvbmZpZ3VyYXRpb24uCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBTYW11ZWwgUm96ZSA8c2FtdWVsLnJvemVAZ21haWwuY29tPgogKgogKiBAcGhwc3Rhbi10eXBlIFZlcnNpb24gYXJyYXl7dmVyc2lvbjogc3RyaW5nLCBjb21taXQ6IHN0cmluZ3xudWxsLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nfG51bGwsIGZlYXR1cmVfdmVyc2lvbj86IHN0cmluZ3xudWxsLCBmZWF0dXJlX3ByZXR0eV92ZXJzaW9uPzogc3RyaW5nfG51bGx9CiAqLwpjbGFzcyBWZXJzaW9uR3Vlc3Nlcgp7CiAgICAvKioKICAgICAqIEB2YXIgQ29uZmlnCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yCiAgICAgKi8KICAgIHByaXZhdGUgJHByb2Nlc3M7CgogICAgLyoqCiAgICAgKiBAdmFyIFNlbXZlclZlcnNpb25QYXJzZXIKICAgICAqLwogICAgcHJpdmF0ZSAkdmVyc2lvblBhcnNlcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSBQcm9jZXNzRXhlY3V0b3IgICAgICRwcm9jZXNzCiAgICAgKiBAcGFyYW0gU2VtdmVyVmVyc2lvblBhcnNlciAkdmVyc2lvblBhcnNlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29uZmlnICRjb25maWcsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcywgU2VtdmVyVmVyc2lvblBhcnNlciAkdmVyc2lvblBhcnNlcikKICAgIHsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gJHZlcnNpb25QYXJzZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHBhY2thZ2VDb25maWcKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAkcGF0aCBQYXRoIHRvIGd1ZXNzIGludG8KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqIEBwaHBzdGFuLXJldHVybiBWZXJzaW9ufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGd1ZXNzVmVyc2lvbihhcnJheSAkcGFja2FnZUNvbmZpZywgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3Byb2Nfb3BlbicpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25EYXRhID0gJHRoaXMtPmd1ZXNzR2l0VmVyc2lvbigkcGFja2FnZUNvbmZpZywgJHBhdGgpOwogICAgICAgIGlmIChudWxsICE9PSAkdmVyc2lvbkRhdGEgJiYgbnVsbCAhPT0gJHZlcnNpb25EYXRhWyd2ZXJzaW9uJ10pIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wb3N0cHJvY2VzcygkdmVyc2lvbkRhdGEpOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25EYXRhID0gJHRoaXMtPmd1ZXNzSGdWZXJzaW9uKCRwYWNrYWdlQ29uZmlnLCAkcGF0aCk7CiAgICAgICAgaWYgKG51bGwgIT09ICR2ZXJzaW9uRGF0YSAmJiBudWxsICE9PSAkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnBvc3Rwcm9jZXNzKCR2ZXJzaW9uRGF0YSk7CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvbkRhdGEgPSAkdGhpcy0+Z3Vlc3NGb3NzaWxWZXJzaW9uKCRwYXRoKTsKICAgICAgICBpZiAobnVsbCAhPT0gJHZlcnNpb25EYXRhICYmIG51bGwgIT09ICR2ZXJzaW9uRGF0YVsndmVyc2lvbiddKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cG9zdHByb2Nlc3MoJHZlcnNpb25EYXRhKTsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9uRGF0YSA9ICR0aGlzLT5ndWVzc1N2blZlcnNpb24oJHBhY2thZ2VDb25maWcsICRwYXRoKTsKICAgICAgICBpZiAobnVsbCAhPT0gJHZlcnNpb25EYXRhICYmIG51bGwgIT09ICR2ZXJzaW9uRGF0YVsndmVyc2lvbiddKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cG9zdHByb2Nlc3MoJHZlcnNpb25EYXRhKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICR2ZXJzaW9uRGF0YQogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIFZlcnNpb24gJHZlcnNpb25EYXRhCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBocHN0YW4tcmV0dXJuIFZlcnNpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwb3N0cHJvY2VzcyhhcnJheSAkdmVyc2lvbkRhdGEpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddKSAmJiAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddID09PSAkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSAmJiAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfcHJldHR5X3ZlcnNpb24nXSA9PT0gJHZlcnNpb25EYXRhWydwcmV0dHlfdmVyc2lvbiddKSB7CiAgICAgICAgICAgIHVuc2V0KCR2ZXJzaW9uRGF0YVsnZmVhdHVyZV92ZXJzaW9uJ10sICR2ZXJzaW9uRGF0YVsnZmVhdHVyZV9wcmV0dHlfdmVyc2lvbiddKTsKICAgICAgICB9CgogICAgICAgIGlmICgnLWRldicgPT09IHN1YnN0cigkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSwgLTQpICYmIFByZWc6OmlzTWF0Y2goJ3tcLjl7N319JywgJHZlcnNpb25EYXRhWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICR2ZXJzaW9uRGF0YVsncHJldHR5X3ZlcnNpb24nXSA9IFByZWc6OnJlcGxhY2UoJ3soXC45ezd9KSt9JywgJy54JywgJHZlcnNpb25EYXRhWyd2ZXJzaW9uJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddKSAmJiAnLWRldicgPT09IHN1YnN0cigkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddLCAtNCkgJiYgUHJlZzo6aXNNYXRjaCgne1wuOXs3fX0nLCAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddKSkgewogICAgICAgICAgICAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfcHJldHR5X3ZlcnNpb24nXSA9IFByZWc6OnJlcGxhY2UoJ3soXC45ezd9KSt9JywgJy54JywgJHZlcnNpb25EYXRhWydmZWF0dXJlX3ZlcnNpb24nXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZlcnNpb25EYXRhOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+ICRwYWNrYWdlQ29uZmlnCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e3ZlcnNpb246IHN0cmluZ3xudWxsLCBjb21taXQ6IHN0cmluZ3xudWxsLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nfG51bGwsIGZlYXR1cmVfdmVyc2lvbj86IHN0cmluZ3xudWxsLCBmZWF0dXJlX3ByZXR0eV92ZXJzaW9uPzogc3RyaW5nfG51bGx9CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ3Vlc3NHaXRWZXJzaW9uKGFycmF5ICRwYWNrYWdlQ29uZmlnLCAkcGF0aCkKICAgIHsKICAgICAgICBHaXRVdGlsOjpjbGVhbkVudigpOwogICAgICAgICRjb21taXQgPSBudWxsOwogICAgICAgICR2ZXJzaW9uID0gbnVsbDsKICAgICAgICAkcHJldHR5VmVyc2lvbiA9IG51bGw7CiAgICAgICAgJGZlYXR1cmVWZXJzaW9uID0gbnVsbDsKICAgICAgICAkZmVhdHVyZVByZXR0eVZlcnNpb24gPSBudWxsOwogICAgICAgICRpc0RldGFjaGVkID0gZmFsc2U7CgogICAgICAgIC8vIHRyeSB0byBmZXRjaCBjdXJyZW50IHZlcnNpb24gZnJvbSBnaXQgYnJhbmNoCiAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgYnJhbmNoIC1hIC0tbm8tY29sb3IgLS1uby1hYmJyZXYgLXYnLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gYXJyYXkoKTsKICAgICAgICAgICAgJGlzRmVhdHVyZUJyYW5jaCA9IGZhbHNlOwoKICAgICAgICAgICAgLy8gZmluZCBjdXJyZW50IGJyYW5jaCBhbmQgY29sbGVjdCBhbGwgYnJhbmNoIG5hbWVzCiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRicmFuY2gpIHsKICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoICYmIFByZWc6OmlzTWF0Y2goJ3teKD86XCogKSAqKFwobm8gYnJhbmNoXCl8XChkZXRhY2hlZCBmcm9tIFxTK1wpfFwoSEVBRCBkZXRhY2hlZCBhdCBcUytcKXxcUyspICooW2EtZjAtOV0rKSAuKiR9JywgJGJyYW5jaCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoWzFdID09PSAnKG5vIGJyYW5jaCknCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IHN0cnBvcygkbWF0Y2hbMV0sICcoZGV0YWNoZWQgJykgPT09IDAKICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3RycG9zKCRtYXRjaFsxXSwgJyhIRUFEIGRldGFjaGVkIGF0JykgPT09IDAKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAnZGV2LScgLiAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgICAgICAgICAgICAgICAgICRpc0ZlYXR1cmVCcmFuY2ggPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAkaXNEZXRhY2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRtYXRjaFsxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gJ2Rldi0nIC4gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgICAgICAgICAkaXNGZWF0dXJlQnJhbmNoID0gJHRoaXMtPmlzRmVhdHVyZUJyYW5jaCgkcGFja2FnZUNvbmZpZywgJG1hdGNoWzFdKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkbWF0Y2hbMl0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbW1pdCA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRicmFuY2ggJiYgIVByZWc6OmlzTWF0Y2goJ3teICouKy9IRUFEIH0nLCAkYnJhbmNoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7Xig/OlwqICk/ICooKD86cmVtb3Rlcy8oPzpvcmlnaW58dXBzdHJlYW0pLyk/W15ccy9dKykgKihbYS1mMC05XSspIC4qJH0nLCAkYnJhbmNoLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1tdID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRpc0ZlYXR1cmVCcmFuY2gpIHsKICAgICAgICAgICAgICAgICRmZWF0dXJlVmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgJGZlYXR1cmVQcmV0dHlWZXJzaW9uID0gJHByZXR0eVZlcnNpb247CgogICAgICAgICAgICAgICAgLy8gdHJ5IHRvIGZpbmQgdGhlIGJlc3QgKG5lYXJlc3QpIHZlcnNpb24gYnJhbmNoIHRvIGFzc3VtZSB0aGlzIGZlYXR1cmUncyB2ZXJzaW9uCiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmd1ZXNzRmVhdHVyZVZlcnNpb24oJHBhY2thZ2VDb25maWcsICR2ZXJzaW9uLCAkYnJhbmNoZXMsICdnaXQgcmV2LWxpc3QgJWNhbmRpZGF0ZSUuLiVicmFuY2glJywgJHBhdGgpOwogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkcmVzdWx0Wyd2ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICRyZXN1bHRbJ3ByZXR0eV92ZXJzaW9uJ107CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJHZlcnNpb24gfHwgJGlzRGV0YWNoZWQpIHsKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT52ZXJzaW9uRnJvbUdpdFRhZ3MoJHBhdGgpOwogICAgICAgICAgICBpZiAoJHJlc3VsdCkgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkcmVzdWx0Wyd2ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICRyZXN1bHRbJ3ByZXR0eV92ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAkZmVhdHVyZVZlcnNpb24gPSBudWxsOwogICAgICAgICAgICAgICAgJGZlYXR1cmVQcmV0dHlWZXJzaW9uID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkY29tbWl0KSB7CiAgICAgICAgICAgICRjb21tYW5kID0gJ2dpdCBsb2cgLS1wcmV0dHk9IiVIIiAtbjEgSEVBRCcuR2l0VXRpbDo6Z2V0Tm9TaG93U2lnbmF0dXJlRmxhZygkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAkY29tbWl0ID0gdHJpbSgkb3V0cHV0KSA/OiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGZlYXR1cmVWZXJzaW9uKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgndmVyc2lvbicgPT4gJHZlcnNpb24sICdjb21taXQnID0+ICRjb21taXQsICdwcmV0dHlfdmVyc2lvbicgPT4gJHByZXR0eVZlcnNpb24sICdmZWF0dXJlX3ZlcnNpb24nID0+ICRmZWF0dXJlVmVyc2lvbiwgJ2ZlYXR1cmVfcHJldHR5X3ZlcnNpb24nID0+ICRmZWF0dXJlUHJldHR5VmVyc2lvbik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAnY29tbWl0JyA9PiAkY29tbWl0LCAncHJldHR5X3ZlcnNpb24nID0+ICRwcmV0dHlWZXJzaW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e3ZlcnNpb246IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZ318bnVsbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHZlcnNpb25Gcm9tR2l0VGFncygkcGF0aCkKICAgIHsKICAgICAgICAvLyB0cnkgdG8gZmV0Y2ggY3VycmVudCB2ZXJzaW9uIGZyb20gZ2l0IHRhZ3MKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBkZXNjcmliZSAtLWV4YWN0LW1hdGNoIC0tdGFncycsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKHRyaW0oJG91dHB1dCkpOwoKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgndmVyc2lvbicgPT4gJHZlcnNpb24sICdwcmV0dHlfdmVyc2lvbicgPT4gdHJpbSgkb3V0cHV0KSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHBhY2thZ2VDb25maWcKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7dmVyc2lvbjogc3RyaW5nfG51bGwsIGNvbW1pdDogJyd8bnVsbCwgcHJldHR5X3ZlcnNpb246IHN0cmluZ3xudWxsLCBmZWF0dXJlX3ZlcnNpb24/OiBzdHJpbmd8bnVsbCwgZmVhdHVyZV9wcmV0dHlfdmVyc2lvbj86IHN0cmluZ3xudWxsfXxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ3Vlc3NIZ1ZlcnNpb24oYXJyYXkgJHBhY2thZ2VDb25maWcsICRwYXRoKQogICAgewogICAgICAgIC8vIHRyeSB0byBmZXRjaCBjdXJyZW50IHZlcnNpb24gZnJvbSBoZyBicmFuY2gKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIGJyYW5jaCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAkYnJhbmNoID0gdHJpbSgkb3V0cHV0KTsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRicmFuY2gpOwogICAgICAgICAgICAkaXNGZWF0dXJlQnJhbmNoID0gMCA9PT0gc3RycG9zKCR2ZXJzaW9uLCAnZGV2LScpOwoKICAgICAgICAgICAgaWYgKFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTID09PSAkdmVyc2lvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gbnVsbCwgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnZGV2LScuJGJyYW5jaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGlzRmVhdHVyZUJyYW5jaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gbnVsbCwgJ3ByZXR0eV92ZXJzaW9uJyA9PiAkdmVyc2lvbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlLXVzZSB0aGUgSGdEcml2ZXIgdG8gZmV0Y2ggYnJhbmNoZXMgKHRoaXMgcHJvcGVybHkgaW5jbHVkZXMgYm9va21hcmtzKQogICAgICAgICAgICAkaW8gPSBuZXcgTnVsbElPKCk7CiAgICAgICAgICAgICRkcml2ZXIgPSBuZXcgSGdEcml2ZXIoYXJyYXkoJ3VybCcgPT4gJHBhdGgpLCAkaW8sICR0aGlzLT5jb25maWcsIG5ldyBIdHRwRG93bmxvYWRlcigkaW8sICR0aGlzLT5jb25maWcpLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgICAgICRicmFuY2hlcyA9IGFycmF5X21hcCgnc3RydmFsJywgYXJyYXlfa2V5cygkZHJpdmVyLT5nZXRCcmFuY2hlcygpKSk7CgogICAgICAgICAgICAvLyB0cnkgdG8gZmluZCB0aGUgYmVzdCAobmVhcmVzdCkgdmVyc2lvbiBicmFuY2ggdG8gYXNzdW1lIHRoaXMgZmVhdHVyZSdzIHZlcnNpb24KICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5ndWVzc0ZlYXR1cmVWZXJzaW9uKCRwYWNrYWdlQ29uZmlnLCAkdmVyc2lvbiwgJGJyYW5jaGVzLCAnaGcgbG9nIC1yICJub3QgYW5jZXN0b3JzKFwnJWNhbmRpZGF0ZSVcJykgYW5kIGFuY2VzdG9ycyhcJyVicmFuY2glXCcpIiAtLXRlbXBsYXRlICJ7bm9kZX1cXG4iJywgJHBhdGgpOwogICAgICAgICAgICAkcmVzdWx0Wydjb21taXQnXSA9ICcnOwogICAgICAgICAgICAkcmVzdWx0WydmZWF0dXJlX3ZlcnNpb24nXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAkcmVzdWx0WydmZWF0dXJlX3ByZXR0eV92ZXJzaW9uJ10gPSAkdmVyc2lvbjsKCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gICAgICRwYWNrYWdlQ29uZmlnCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICAgICAgICAgICR2ZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgICAgICAgICAgICAgICRicmFuY2hlcwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAkc2NtQ21kbGluZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAkcGF0aAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgJHNjbUNtZGxpbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e3ZlcnNpb246IHN0cmluZ3xudWxsLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nfG51bGx9CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ3Vlc3NGZWF0dXJlVmVyc2lvbihhcnJheSAkcGFja2FnZUNvbmZpZywgJHZlcnNpb24sIGFycmF5ICRicmFuY2hlcywgJHNjbUNtZGxpbmUsICRwYXRoKQogICAgewogICAgICAgICRwcmV0dHlWZXJzaW9uID0gJHZlcnNpb247CgogICAgICAgIC8vIGlnbm9yZSBmZWF0dXJlIGJyYW5jaGVzIGlmIHRoZXkgaGF2ZSBubyBicmFuY2gtYWxpYXMgb3Igc2VsZi52ZXJzaW9uIGlzIHVzZWQKICAgICAgICAvLyBhbmQgZmluZCB0aGUgYnJhbmNoIHRoZXkgY2FtZSBmcm9tIHRvIHVzZSBhcyBhIHZlcnNpb24gaW5zdGVhZAogICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VDb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddWyR2ZXJzaW9uXSkKICAgICAgICAgICAgfHwgc3RycG9zKGpzb25fZW5jb2RlKCRwYWNrYWdlQ29uZmlnKSwgJyJzZWxmLnZlcnNpb24iJykKICAgICAgICApIHsKICAgICAgICAgICAgJGJyYW5jaCA9IFByZWc6OnJlcGxhY2UoJ3teZGV2LX0nLCAnJywgJHZlcnNpb24pOwogICAgICAgICAgICAkbGVuZ3RoID0gUEhQX0lOVF9NQVg7CgogICAgICAgICAgICAvLyByZXR1cm4gZGlyZWN0bHksIGlmIGJyYW5jaCBpcyBjb25maWd1cmVkIHRvIGJlIG5vbi1mZWF0dXJlIGJyYW5jaAogICAgICAgICAgICBpZiAoISR0aGlzLT5pc0ZlYXR1cmVCcmFuY2goJHBhY2thZ2VDb25maWcsICRicmFuY2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAncHJldHR5X3ZlcnNpb24nID0+ICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc29ydCBsb2NhbCBicmFuY2hlcyBmaXJzdCB0aGVuIHJlbW90ZSBvbmVzCiAgICAgICAgICAgIC8vIGFuZCBzb3J0IG51bWVyaWMgYnJhbmNoZXMgYmVsb3cgbmFtZWQgb25lcywgdG8gbWFrZSBzdXJlIGlmIHRoZSBicmFuY2ggaGFzIHRoZSBzYW1lIGRpc3RhbmNlIGZyb20gbWFpbiBhbmQgMS4xMCBhbmQgMS45IGZvciBleGFtcGxlLCBtYWluIGlzIHBpY2tlZAogICAgICAgICAgICAvLyBhbmQgc29ydCB1c2luZyBuYXR1cmFsIHNvcnQgc28gdGhhdCAxLjEwIHdpbGwgYXBwZWFyIGJlZm9yZSAxLjkKICAgICAgICAgICAgdXNvcnQoJGJyYW5jaGVzLCBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgICAgICAkYVJlbW90ZSA9IDAgPT09IHN0cnBvcygkYSwgJ3JlbW90ZXMvJyk7CiAgICAgICAgICAgICAgICAkYlJlbW90ZSA9IDAgPT09IHN0cnBvcygkYiwgJ3JlbW90ZXMvJyk7CgogICAgICAgICAgICAgICAgaWYgKCRhUmVtb3RlICE9PSAkYlJlbW90ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkYVJlbW90ZSA/IDEgOiAtMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gc3RybmF0Y2FzZWNtcCgkYiwgJGEpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRicmFuY2hlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAkY2FuZGlkYXRlVmVyc2lvbiA9IFByZWc6OnJlcGxhY2UoJ3tecmVtb3Rlcy9cUysvfScsICcnLCAkY2FuZGlkYXRlKTsKCiAgICAgICAgICAgICAgICAvLyBkbyBub3QgY29tcGFyZSBhZ2FpbnN0IGl0c2VsZiBvciBvdGhlciBmZWF0dXJlIGJyYW5jaGVzCiAgICAgICAgICAgICAgICBpZiAoJGNhbmRpZGF0ZSA9PT0gJGJyYW5jaCB8fCAkdGhpcy0+aXNGZWF0dXJlQnJhbmNoKCRwYWNrYWdlQ29uZmlnLCAkY2FuZGlkYXRlVmVyc2lvbikpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkY21kTGluZSA9IHN0cl9yZXBsYWNlKGFycmF5KCclY2FuZGlkYXRlJScsICclYnJhbmNoJScpLCBhcnJheSgkY2FuZGlkYXRlLCAkYnJhbmNoKSwgJHNjbUNtZGxpbmUpOwogICAgICAgICAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjbWRMaW5lLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRvdXRwdXQpIDwgJGxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICRsZW5ndGggPSBzdHJsZW4oJG91dHB1dCk7CiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRjYW5kaWRhdGVWZXJzaW9uKTsKICAgICAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICdkZXYtJyAuICRjYW5kaWRhdGVWZXJzaW9uOwogICAgICAgICAgICAgICAgICAgIGlmICgkbGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ3ByZXR0eV92ZXJzaW9uJyA9PiAkcHJldHR5VmVyc2lvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHBhY2thZ2VDb25maWcKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAgICAgICAkYnJhbmNoTmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzRmVhdHVyZUJyYW5jaChhcnJheSAkcGFja2FnZUNvbmZpZywgJGJyYW5jaE5hbWUpCiAgICB7CiAgICAgICAgJG5vbkZlYXR1cmVCcmFuY2hlcyA9ICcnOwogICAgICAgIGlmICghZW1wdHkoJHBhY2thZ2VDb25maWdbJ25vbi1mZWF0dXJlLWJyYW5jaGVzJ10pKSB7CiAgICAgICAgICAgICRub25GZWF0dXJlQnJhbmNoZXMgPSBpbXBsb2RlKCd8JywgJHBhY2thZ2VDb25maWdbJ25vbi1mZWF0dXJlLWJyYW5jaGVzJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICFQcmVnOjppc01hdGNoKCd7XignIC4gJG5vbkZlYXR1cmVCcmFuY2hlcyAuICd8bWFzdGVyfG1haW58bGF0ZXN0fG5leHR8Y3VycmVudHxzdXBwb3J0fHRpcHx0cnVua3xkZWZhdWx0fGRldmVsb3B8XGQrXC4uKykkfScsICRicmFuY2hOYW1lLCAkbWF0Y2gpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7dmVyc2lvbjogc3RyaW5nfG51bGwsIGNvbW1pdDogJycsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmd8bnVsbH0KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBndWVzc0Zvc3NpbFZlcnNpb24oJHBhdGgpCiAgICB7CiAgICAgICAgJHZlcnNpb24gPSBudWxsOwogICAgICAgICRwcmV0dHlWZXJzaW9uID0gbnVsbDsKCiAgICAgICAgLy8gdHJ5IHRvIGZldGNoIGN1cnJlbnQgdmVyc2lvbiBmcm9tIGZvc3NpbAogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZm9zc2lsIGJyYW5jaCBsaXN0JywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgICRicmFuY2ggPSB0cmltKCRvdXRwdXQpOwogICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemVCcmFuY2goJGJyYW5jaCk7CiAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gJ2Rldi0nIC4gJGJyYW5jaDsKICAgICAgICB9CgogICAgICAgIC8vIHRyeSB0byBmZXRjaCBjdXJyZW50IHZlcnNpb24gZnJvbSBmb3NzaWwgdGFncwogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZm9zc2lsIHRhZyBsaXN0JywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUodHJpbSgkb3V0cHV0KSk7CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9IHRyaW0oJG91dHB1dCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gJycsICdwcmV0dHlfdmVyc2lvbicgPT4gJHByZXR0eVZlcnNpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+ICRwYWNrYWdlQ29uZmlnCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5e3ZlcnNpb246IHN0cmluZywgY29tbWl0OiAnJywgcHJldHR5X3ZlcnNpb246IHN0cmluZ318bnVsbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGd1ZXNzU3ZuVmVyc2lvbihhcnJheSAkcGFja2FnZUNvbmZpZywgJHBhdGgpCiAgICB7CiAgICAgICAgU3ZuVXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgLy8gdHJ5IHRvIGZldGNoIGN1cnJlbnQgdmVyc2lvbiBmcm9tIHN2bgogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnc3ZuIGluZm8gLS14bWwnLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgJHRydW5rUGF0aCA9IGlzc2V0KCRwYWNrYWdlQ29uZmlnWyd0cnVuay1wYXRoJ10pID8gcHJlZ19xdW90ZSgkcGFja2FnZUNvbmZpZ1sndHJ1bmstcGF0aCddLCAnIycpIDogJ3RydW5rJzsKICAgICAgICAgICAgJGJyYW5jaGVzUGF0aCA9IGlzc2V0KCRwYWNrYWdlQ29uZmlnWydicmFuY2hlcy1wYXRoJ10pID8gcHJlZ19xdW90ZSgkcGFja2FnZUNvbmZpZ1snYnJhbmNoZXMtcGF0aCddLCAnIycpIDogJ2JyYW5jaGVzJzsKICAgICAgICAgICAgJHRhZ3NQYXRoID0gaXNzZXQoJHBhY2thZ2VDb25maWdbJ3RhZ3MtcGF0aCddKSA/IHByZWdfcXVvdGUoJHBhY2thZ2VDb25maWdbJ3RhZ3MtcGF0aCddLCAnIycpIDogJ3RhZ3MnOwoKICAgICAgICAgICAgJHVybFBhdHRlcm4gPSAnIzx1cmw+LiovKCcgLiAkdHJ1bmtQYXRoIC4gJ3woJyAuICRicmFuY2hlc1BhdGggLiAnfCcgLiAkdGFnc1BhdGggLiAnKS8oLiopKTwvdXJsPiMnOwoKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJHVybFBhdHRlcm4sICRvdXRwdXQsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWzJdKSAmJiAoJGJyYW5jaGVzUGF0aCA9PT0gJG1hdGNoZXNbMl0gfHwgJHRhZ3NQYXRoID09PSAkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gYSBicmFuY2hlcyBwYXRoCiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRtYXRjaGVzWzNdKTsKICAgICAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICdkZXYtJyAuICRtYXRjaGVzWzNdOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAnY29tbWl0JyA9PiAnJywgJ3ByZXR0eV92ZXJzaW9uJyA9PiAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSB0cmltKCRtYXRjaGVzWzFdKTsKICAgICAgICAgICAgICAgIGlmICgkcHJldHR5VmVyc2lvbiA9PT0gJ3RydW5rJykgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJ2Rldi10cnVuayc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gJycsICdwcmV0dHlfdmVyc2lvbicgPT4gJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb247Cgp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcSWdub3JlQWxsUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlcjsKdXNlIENvbXBvc2VyXEZpbHRlclxQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJGYWN0b3J5Owp1c2UgQ29tcG9zZXJcRmlsdGVyXFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXJcUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CgovKioKICogU2VsZWN0cyB0aGUgYmVzdCBwb3NzaWJsZSB2ZXJzaW9uIGZvciBhIHBhY2thZ2UKICoKICogQGF1dGhvciBSeWFuIFdlYXZlciA8cnlhbkBrbnB1bml2ZXJzaXR5LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVmVyc2lvblNlbGVjdG9yCnsKICAgIC8qKiBAdmFyIFJlcG9zaXRvcnlTZXQgKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcnlTZXQ7CgogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlW10+ICovCiAgICBwcml2YXRlICRwbGF0Zm9ybUNvbnN0cmFpbnRzID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBWZXJzaW9uUGFyc2VyICovCiAgICBwcml2YXRlICRwYXJzZXI7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8gSWYgcGFzc2VkIGluLCB0aGUgdmVyc2lvbnMgZm91bmQgd2lsbCBiZSBmaWx0ZXJlZCBhZ2FpbnN0IHRoZWlyIHJlcXVpcmVtZW50cyB0byBlbGltaW5hdGUgYW55IG5vdCBtYXRjaGluZyB0aGUgY3VycmVudCBwbGF0Zm9ybSBwYWNrYWdlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVwb3NpdG9yeVNldCAkcmVwb3NpdG9yeVNldCwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8gPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5U2V0ID0gJHJlcG9zaXRvcnlTZXQ7CiAgICAgICAgaWYgKCRwbGF0Zm9ybVJlcG8pIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBsYXRmb3JtUmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnBsYXRmb3JtQ29uc3RyYWludHNbJHBhY2thZ2UtPmdldE5hbWUoKV1bXSA9IG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogR2l2ZW4gYSBwYWNrYWdlIG5hbWUgYW5kIG9wdGlvbmFsIHZlcnNpb24sIHJldHVybnMgdGhlIGxhdGVzdCBQYWNrYWdlSW50ZXJmYWNlCiAgICAgKiB0aGF0IG1hdGNoZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRhcmdldFBhY2thZ2VWZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcmVmZXJyZWRTdGFiaWxpdHkKICAgICAqIEBwYXJhbSBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVySW50ZXJmYWNlfGJvb2x8c3RyaW5nW10gJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcG9TZXRGbGFncyoKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZXxmYWxzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZEJlc3RDYW5kaWRhdGUoJHBhY2thZ2VOYW1lLCAkdGFyZ2V0UGFja2FnZVZlcnNpb24gPSBudWxsLCAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJ3N0YWJsZScsICRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyID0gbnVsbCwgJHJlcG9TZXRGbGFncyA9IDApCiAgICB7CiAgICAgICAgaWYgKCFpc3NldChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzWyRwcmVmZXJyZWRTdGFiaWxpdHldKSkgewogICAgICAgICAgICAvLyBJZiB5b3UgZ2V0IHRoaXMsIG1heWJlIHlvdSBhcmUgc3RpbGwgcmVseWluZyBvbiB0aGUgQ29tcG9zZXIgMS54IHNpZ25hdHVyZSB3aGVyZSB0aGUgM3JkIGFyZyB3YXMgdGhlIHBocCB2ZXJzaW9uCiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdFeHBlY3RlZCBhIHZhbGlkIHN0YWJpbGl0eSBuYW1lIGFzIDNyZCBhcmd1bWVudCwgZ290ICcuJHByZWZlcnJlZFN0YWJpbGl0eSk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpIHsKICAgICAgICAgICAgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIgPSBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6aWdub3JlTm90aGluZygpOwogICAgICAgIH0gZWxzZWlmICghKCRwbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyIGluc3RhbmNlb2YgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZSkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignVmVyc2lvblNlbGVjdG9yOjpmaW5kQmVzdENhbmRpZGF0ZSB3aXRoIGlnbm9yZWQgcGxhdGZvcm0gcmVxcyBhcyBib29sfGFycmF5IGlzIGRlcHJlY2F0ZWQgc2luY2UgQ29tcG9zZXIgMi4yLCB1c2UgYW4gaW5zdGFuY2Ugb2YgUGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlckludGVyZmFjZSBpbnN0ZWFkLicsIEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICAgICAgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIgPSBQbGF0Zm9ybVJlcXVpcmVtZW50RmlsdGVyRmFjdG9yeTo6ZnJvbUJvb2xPckxpc3QoJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpOwogICAgICAgIH0KCiAgICAgICAgJGNvbnN0cmFpbnQgPSAkdGFyZ2V0UGFja2FnZVZlcnNpb24gPyAkdGhpcy0+Z2V0UGFyc2VyKCktPnBhcnNlQ29uc3RyYWludHMoJHRhcmdldFBhY2thZ2VWZXJzaW9uKSA6IG51bGw7CiAgICAgICAgJGNhbmRpZGF0ZXMgPSAkdGhpcy0+cmVwb3NpdG9yeVNldC0+ZmluZFBhY2thZ2VzKHN0cnRvbG93ZXIoJHBhY2thZ2VOYW1lKSwgJGNvbnN0cmFpbnQsICRyZXBvU2V0RmxhZ3MpOwoKICAgICAgICBpZiAoJHRoaXMtPnBsYXRmb3JtQ29uc3RyYWludHMgJiYgISgkcGxhdGZvcm1SZXF1aXJlbWVudEZpbHRlciBpbnN0YW5jZW9mIElnbm9yZUFsbFBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpKSB7CiAgICAgICAgICAgICRwbGF0Zm9ybUNvbnN0cmFpbnRzID0gJHRoaXMtPnBsYXRmb3JtQ29uc3RyYWludHM7CiAgICAgICAgICAgICRjYW5kaWRhdGVzID0gYXJyYXlfZmlsdGVyKCRjYW5kaWRhdGVzLCBmdW5jdGlvbiAoJHBrZykgdXNlICgkcGxhdGZvcm1Db25zdHJhaW50cywgJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXIpIHsKICAgICAgICAgICAgICAgICRyZXFzID0gJHBrZy0+Z2V0UmVxdWlyZXMoKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVxcyBhcyAkbmFtZSA9PiAkbGluaykgewogICAgICAgICAgICAgICAgICAgIGlmICghJHBsYXRmb3JtUmVxdWlyZW1lbnRGaWx0ZXItPmlzSWdub3JlZCgkbmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwbGF0Zm9ybUNvbnN0cmFpbnRzWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwbGF0Zm9ybUNvbnN0cmFpbnRzWyRuYW1lXSBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCRjb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFja2FnZSByZXF1aXJlcyBhIHBsYXRmb3JtIHBhY2thZ2UgdGhhdCBpcyB1bmtub3duIG9uIGN1cnJlbnQgcGxhdGZvcm0uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJdCBtZWFucyB0aGF0IGN1cnJlbnQgcGxhdGZvcm0gY2Fubm90IHZhbGlkYXRlIHRoaXMgY29uc3RyYWludCBhbmQgc28gcGFja2FnZSBpcyBub3QgaW5zdGFsbGFibGUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkY2FuZGlkYXRlcykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBzZWxlY3QgaGlnaGVzdCB2ZXJzaW9uIGlmIHdlIGhhdmUgbWFueQogICAgICAgICRwYWNrYWdlID0gcmVzZXQoJGNhbmRpZGF0ZXMpOwogICAgICAgICRtaW5Qcmlvcml0eSA9IEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbJHByZWZlcnJlZFN0YWJpbGl0eV07CiAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZXMgYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICAkY2FuZGlkYXRlUHJpb3JpdHkgPSAkY2FuZGlkYXRlLT5nZXRTdGFiaWxpdHlQcmlvcml0eSgpOwogICAgICAgICAgICAkY3VycmVudFByaW9yaXR5ID0gJHBhY2thZ2UtPmdldFN0YWJpbGl0eVByaW9yaXR5KCk7CgogICAgICAgICAgICAvLyBjYW5kaWRhdGUgaXMgbGVzcyBzdGFibGUgdGhhbiBvdXIgcHJlZmVycmVkIHN0YWJpbGl0eSwKICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgcGFja2FnZSBpcyBtb3JlIHN0YWJsZSB0aGFuIGNhbmRpZGF0ZSwgc2tpcCBpdAogICAgICAgICAgICBpZiAoJG1pblByaW9yaXR5IDwgJGNhbmRpZGF0ZVByaW9yaXR5ICYmICRjdXJyZW50UHJpb3JpdHkgPCAkY2FuZGlkYXRlUHJpb3JpdHkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjYW5kaWRhdGUgaXMgbGVzcyBzdGFibGUgdGhhbiBvdXIgcHJlZmVycmVkIHN0YWJpbGl0eSwKICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgcGFja2FnZSBpcyBsZXNzIHN0YWJsZSB0aGFuIGNhbmRpZGF0ZSwgc2VsZWN0IGNhbmRpZGF0ZQogICAgICAgICAgICBpZiAoJG1pblByaW9yaXR5IDwgJGNhbmRpZGF0ZVByaW9yaXR5ICYmICRjYW5kaWRhdGVQcmlvcml0eSA8ICRjdXJyZW50UHJpb3JpdHkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjYW5kaWRhdGUgaXMgbW9yZSBzdGFibGUgdGhhbiBvdXIgcHJlZmVycmVkIHN0YWJpbGl0eSwKICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgcGFja2FnZSBpcyBsZXNzIHN0YWJsZSB0aGFuIHByZWZlcnJlZCBzdGFiaWxpdHksIHNlbGVjdCBjYW5kaWRhdGUKICAgICAgICAgICAgaWYgKCRtaW5Qcmlvcml0eSA+PSAkY2FuZGlkYXRlUHJpb3JpdHkgJiYgJG1pblByaW9yaXR5IDwgJGN1cnJlbnRQcmlvcml0eSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNlbGVjdCBoaWdoZXN0IHZlcnNpb24gb2YgdGhlIHR3bwogICAgICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKCRwYWNrYWdlLT5nZXRWZXJzaW9uKCksICRjYW5kaWRhdGUtPmdldFZlcnNpb24oKSwgJzwnKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkY2FuZGlkYXRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSBlbmQgdXAgd2l0aCA5OTk5OTk5LWRldiBhcyBzZWxlY3RlZCBwYWNrYWdlLCBtYWtlIHN1cmUgd2UgdXNlIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIGluc3RlYWQgb2YgdGhlIGFsaWFzCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdpdmVuIGEgY29uY3JldGUgdmVyc2lvbiwgdGhpcyByZXR1cm5zIGEgXiBjb25zdHJhaW50ICh3aGVuIHBvc3NpYmxlKQogICAgICogdGhhdCBzaG91bGQgYmUgdXNlZCwgZm9yIGV4YW1wbGUsIGluIGNvbXBvc2VyLmpzb24uCiAgICAgKgogICAgICogRm9yIGV4YW1wbGU6CiAgICAgKiAgKiAxLjIuMSAgICAgICAgIC0+IF4xLjIKICAgICAqICAqIDEuMiAgICAgICAgICAgLT4gXjEuMgogICAgICogICogdjMuMi4xICAgICAgICAtPiBeMy4yCiAgICAgKiAgKiAyLjAtYmV0YS4xICAgIC0+IF4yLjBAYmV0YQogICAgICogICogZGV2LW1hc3RlciAgICAtPiBeMi4xQGRldiAgICAgIChkZXYgdmVyc2lvbiB3aXRoIGFsaWFzKQogICAgICogICogZGV2LW1hc3RlciAgICAtPiBkZXYtbWFzdGVyICAgIChkZXYgdmVyc2lvbnMgYXJlIHVudG91Y2hlZCkKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUmVjb21tZW5kZWRSZXF1aXJlVmVyc2lvbihQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIC8vIEV4dGVuc2lvbnMgd2hpY2ggYXJlIHZlcnNpb25lZCBpbiBzeW5jIHdpdGggUEhQIHNob3VsZCByYXRoZXIgYmUgcmVxdWlyZWQgYXMgIioiIHRvIHNpbXBsaWZ5CiAgICAgICAgLy8gdGhlIHJlcXVpcmVzIGFuZCBoYXZlIG9ubHkgb25lIHJlcXVpcmVkIHZlcnNpb24gdG8gY2hhbmdlIHdoZW4gYnVtcGluZyB0aGUgcGhwIHJlcXVpcmVtZW50CiAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkcGFja2FnZS0+Z2V0TmFtZSgpLCAnZXh0LScpKSB7CiAgICAgICAgICAgICRwaHBWZXJzaW9uID0gUEhQX01BSk9SX1ZFUlNJT04gLiAnLicgLiBQSFBfTUlOT1JfVkVSU0lPTiAuICcuJyAuIFBIUF9SRUxFQVNFX1ZFUlNJT047CiAgICAgICAgICAgICRleHRWZXJzaW9uID0gaW1wbG9kZSgnLicsIGFycmF5X3NsaWNlKGV4cGxvZGUoJy4nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSwgMCwgMykpOwogICAgICAgICAgICBpZiAoJHBocFZlcnNpb24gPT09ICRleHRWZXJzaW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJyonOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgaWYgKCEkcGFja2FnZS0+aXNEZXYoKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnRyYW5zZm9ybVZlcnNpb24oJHZlcnNpb24sICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksICRwYWNrYWdlLT5nZXRTdGFiaWxpdHkoKSk7CiAgICAgICAgfQoKICAgICAgICAkbG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKCR0aGlzLT5nZXRQYXJzZXIoKSk7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcigpOwogICAgICAgICRleHRyYSA9ICRsb2FkZXItPmdldEJyYW5jaEFsaWFzKCRkdW1wZXItPmR1bXAoJHBhY2thZ2UpKTsKICAgICAgICBpZiAoJGV4dHJhICYmICRleHRyYSAhPT0gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVMpIHsKICAgICAgICAgICAgJGV4dHJhID0gUHJlZzo6cmVwbGFjZSgne14oXGQrXC5cZCtcLlxkKykoXC45OTk5OTk5KS1kZXYkfScsICckMS4wJywgJGV4dHJhLCAtMSwgJGNvdW50KTsKICAgICAgICAgICAgaWYgKCRjb3VudCkgewogICAgICAgICAgICAgICAgJGV4dHJhID0gc3RyX3JlcGxhY2UoJy45OTk5OTk5JywgJy4wJywgJGV4dHJhKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnRyYW5zZm9ybVZlcnNpb24oJGV4dHJhLCAkZXh0cmEsICdkZXYnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcmV0dHlWZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGFiaWxpdHkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHRyYW5zZm9ybVZlcnNpb24oJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uLCAkc3RhYmlsaXR5KQogICAgewogICAgICAgIC8vIGF0dGVtcHQgdG8gdHJhbnNmb3JtIDIuMS4xIHRvIDIuMQogICAgICAgIC8vIHRoaXMgYWxsb3dzIHlvdSB0byB1cGdyYWRlIHRocm91Z2ggbWlub3IgdmVyc2lvbnMKICAgICAgICAkc2VtYW50aWNWZXJzaW9uUGFydHMgPSBleHBsb2RlKCcuJywgJHZlcnNpb24pOwoKICAgICAgICAvLyBjaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIHNlbXZlci1sb29raW5nIHZlcnNpb24KICAgICAgICBpZiAoY291bnQoJHNlbWFudGljVmVyc2lvblBhcnRzKSA9PSA0ICYmIFByZWc6OmlzTWF0Y2goJ3teMFxEP30nLCAkc2VtYW50aWNWZXJzaW9uUGFydHNbM10pKSB7CiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbGFzdCBwYXJ0cyAoaS5lLiB0aGUgcGF0Y2ggdmVyc2lvbiBudW1iZXIgYW5kIGFueSBleHRyYSkKICAgICAgICAgICAgaWYgKCRzZW1hbnRpY1ZlcnNpb25QYXJ0c1swXSA9PT0gJzAnKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkc2VtYW50aWNWZXJzaW9uUGFydHNbM10pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdW5zZXQoJHNlbWFudGljVmVyc2lvblBhcnRzWzJdLCAkc2VtYW50aWNWZXJzaW9uUGFydHNbM10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR2ZXJzaW9uID0gaW1wbG9kZSgnLicsICRzZW1hbnRpY1ZlcnNpb25QYXJ0cyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICRwcmV0dHlWZXJzaW9uOwogICAgICAgIH0KCiAgICAgICAgLy8gYXBwZW5kIHN0YWJpbGl0eSBmbGFnIGlmIG5vdCBkZWZhdWx0CiAgICAgICAgaWYgKCRzdGFiaWxpdHkgIT0gJ3N0YWJsZScpIHsKICAgICAgICAgICAgJHZlcnNpb24gLj0gJ0AnLiRzdGFiaWxpdHk7CiAgICAgICAgfQoKICAgICAgICAvLyAyLjEgLT4gXjIuMQogICAgICAgIHJldHVybiAnXicgLiAkdmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVmVyc2lvblBhcnNlcgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFBhcnNlcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5wYXJzZXIgPT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnBhcnNlcjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb247Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBTdGFiaWxpdHlGaWx0ZXIKewogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYW55IG9mIHRoZSBwcm92aWRlZCBwYWNrYWdlIG5hbWVzIGluIHRoZSBnaXZlbiBzdGFiaWxpdHkgbWF0Y2ggdGhlIGNvbmZpZ3VyZWQgYWNjZXB0YWJsZSBzdGFiaWxpdHkgYW5kIGZsYWdzCiAgICAgKgogICAgICogQHBhcmFtIGludFtdICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgYXJyYXkgb2Ygc3RhYmlsaXR5ID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMKICAgICAqIEBwYXJhbSBpbnRbXSAkc3RhYmlsaXR5RmxhZ3MgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+ICRzdGFiaWxpdHlGbGFncwogICAgICogQHBhcmFtICBzdHJpbmdbXSAkbmFtZXMgICAgIFRoZSBwYWNrYWdlIG5hbWUocykgdG8gY2hlY2sgZm9yIHN0YWJpbGl0eSBmbGFncwogICAgICogQHBhcmFtICBzdHJpbmcgICAkc3RhYmlsaXR5IG9uZSBvZiAnc3RhYmxlJywgJ1JDJywgJ2JldGEnLCAnYWxwaGEnIG9yICdkZXYnCiAgICAgKiBAcmV0dXJuIGJvb2wgICAgIHRydWUgaWYgYW55IHBhY2thZ2UgbmFtZSBpcyBhY2NlcHRhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNQYWNrYWdlQWNjZXB0YWJsZShhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRuYW1lcywgJHN0YWJpbGl0eSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkbmFtZXMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgLy8gYWxsb3cgaWYgcGFja2FnZSBtYXRjaGVzIHRoZSBwYWNrYWdlLXNwZWNpZmljIHN0YWJpbGl0eSBmbGFnCiAgICAgICAgICAgIGlmIChpc3NldCgkc3RhYmlsaXR5RmxhZ3NbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgaWYgKEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbJHN0YWJpbGl0eV0gPD0gJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGFjY2VwdGFibGVTdGFiaWxpdGllc1skc3RhYmlsaXR5XSkpIHsKICAgICAgICAgICAgICAgIC8vIGFsbG93IGlmIHBhY2thZ2UgbWF0Y2hlcyB0aGUgZ2xvYmFsIHN0YWJpbGl0eSByZXF1aXJlbWVudCBhbmQgaGFzIG5vIGV4Y2VwdGlvbgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXER1bXBlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaGl2IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEFycmF5RHVtcGVyCnsKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheTxzdHJpbmcsIG1peGVkPgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZHVtcChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRrZXlzID0gYXJyYXkoCiAgICAgICAgICAgICdiaW5hcmllcycgPT4gJ2JpbicsCiAgICAgICAgICAgICd0eXBlJywKICAgICAgICAgICAgJ2V4dHJhJywKICAgICAgICAgICAgJ2luc3RhbGxhdGlvblNvdXJjZScgPT4gJ2luc3RhbGxhdGlvbi1zb3VyY2UnLAogICAgICAgICAgICAnYXV0b2xvYWQnLAogICAgICAgICAgICAnZGV2QXV0b2xvYWQnID0+ICdhdXRvbG9hZC1kZXYnLAogICAgICAgICAgICAnbm90aWZpY2F0aW9uVXJsJyA9PiAnbm90aWZpY2F0aW9uLXVybCcsCiAgICAgICAgICAgICdpbmNsdWRlUGF0aHMnID0+ICdpbmNsdWRlLXBhdGgnLAogICAgICAgICk7CgogICAgICAgICRkYXRhID0gYXJyYXkoKTsKICAgICAgICAkZGF0YVsnbmFtZSddID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKICAgICAgICAkZGF0YVsndmVyc2lvbiddID0gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAkZGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10gPSAkcGFja2FnZS0+Z2V0VmVyc2lvbigpOwoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFRhcmdldERpcigpKSB7CiAgICAgICAgICAgICRkYXRhWyd0YXJnZXQtZGlyJ10gPSAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFNvdXJjZVR5cGUoKSkgewogICAgICAgICAgICAkZGF0YVsnc291cmNlJ11bJ3R5cGUnXSA9ICRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCk7CiAgICAgICAgICAgICRkYXRhWydzb3VyY2UnXVsndXJsJ10gPSAkcGFja2FnZS0+Z2V0U291cmNlVXJsKCk7CiAgICAgICAgICAgIGlmIChudWxsICE9PSAoJHZhbHVlID0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ3NvdXJjZSddWydyZWZlcmVuY2UnXSA9ICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJG1pcnJvcnMgPSAkcGFja2FnZS0+Z2V0U291cmNlTWlycm9ycygpKSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnc291cmNlJ11bJ21pcnJvcnMnXSA9ICRtaXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldERpc3RUeXBlKCkpIHsKICAgICAgICAgICAgJGRhdGFbJ2Rpc3QnXVsndHlwZSddID0gJHBhY2thZ2UtPmdldERpc3RUeXBlKCk7CiAgICAgICAgICAgICRkYXRhWydkaXN0J11bJ3VybCddID0gJHBhY2thZ2UtPmdldERpc3RVcmwoKTsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICgkdmFsdWUgPSAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2Rpc3QnXVsncmVmZXJlbmNlJ10gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bGwgIT09ICgkdmFsdWUgPSAkcGFja2FnZS0+Z2V0RGlzdFNoYTFDaGVja3N1bSgpKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2Rpc3QnXVsnc2hhc3VtJ10gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRtaXJyb3JzID0gJHBhY2thZ2UtPmdldERpc3RNaXJyb3JzKCkpIHsKICAgICAgICAgICAgICAgICRkYXRhWydkaXN0J11bJ21pcnJvcnMnXSA9ICRtaXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoIChCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlcyBhcyAkdHlwZSA9PiAkb3B0cykgewogICAgICAgICAgICBpZiAoJGxpbmtzID0gJHBhY2thZ2UtPnsnZ2V0Jy51Y2ZpcnN0KCRvcHRzWydtZXRob2QnXSl9KCkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICRkYXRhWyR0eXBlXVskbGluay0+Z2V0VGFyZ2V0KCldID0gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGtzb3J0KCRkYXRhWyR0eXBlXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZXMgPSAkcGFja2FnZS0+Z2V0U3VnZ2VzdHMoKSkgewogICAgICAgICAgICBrc29ydCgkcGFja2FnZXMpOwogICAgICAgICAgICAkZGF0YVsnc3VnZ2VzdCddID0gJHBhY2thZ2VzOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRSZWxlYXNlRGF0ZSgpKSB7CiAgICAgICAgICAgICRkYXRhWyd0aW1lJ10gPSAkcGFja2FnZS0+Z2V0UmVsZWFzZURhdGUoKS0+Zm9ybWF0KERBVEVfUkZDMzMzOSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmlzRGVmYXVsdEJyYW5jaCgpKSB7CiAgICAgICAgICAgICRkYXRhWydkZWZhdWx0LWJyYW5jaCddID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRkYXRhID0gJHRoaXMtPmR1bXBWYWx1ZXMoJHBhY2thZ2UsICRrZXlzLCAkZGF0YSk7CgogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldEFyY2hpdmVOYW1lKCkpIHsKICAgICAgICAgICAgICAgICRkYXRhWydhcmNoaXZlJ11bJ25hbWUnXSA9ICRwYWNrYWdlLT5nZXRBcmNoaXZlTmFtZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QXJjaGl2ZUV4Y2x1ZGVzKCkpIHsKICAgICAgICAgICAgICAgICRkYXRhWydhcmNoaXZlJ11bJ2V4Y2x1ZGUnXSA9ICRwYWNrYWdlLT5nZXRBcmNoaXZlRXhjbHVkZXMoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGtleXMgPSBhcnJheSgKICAgICAgICAgICAgICAgICdzY3JpcHRzJywKICAgICAgICAgICAgICAgICdsaWNlbnNlJywKICAgICAgICAgICAgICAgICdhdXRob3JzJywKICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbicsCiAgICAgICAgICAgICAgICAnaG9tZXBhZ2UnLAogICAgICAgICAgICAgICAgJ2tleXdvcmRzJywKICAgICAgICAgICAgICAgICdyZXBvc2l0b3JpZXMnLAogICAgICAgICAgICAgICAgJ3N1cHBvcnQnLAogICAgICAgICAgICAgICAgJ2Z1bmRpbmcnLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJGRhdGEgPSAkdGhpcy0+ZHVtcFZhbHVlcygkcGFja2FnZSwgJGtleXMsICRkYXRhKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkZGF0YVsna2V5d29yZHMnXSkgJiYgXGlzX2FycmF5KCRkYXRhWydrZXl3b3JkcyddKSkgewogICAgICAgICAgICAgICAgc29ydCgkZGF0YVsna2V5d29yZHMnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+aXNBYmFuZG9uZWQoKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2FiYW5kb25lZCddID0gJHBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpID86IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJHBhY2thZ2UtPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICAgICAgaWYgKCRtaW5pbXVtU3RhYmlsaXR5KSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnbWluaW11bS1zdGFiaWxpdHknXSA9ICRtaW5pbXVtU3RhYmlsaXR5OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRwYWNrYWdlLT5nZXRUcmFuc3BvcnRPcHRpb25zKCkpID4gMCkgewogICAgICAgICAgICAkZGF0YVsndHJhbnNwb3J0LW9wdGlvbnMnXSA9ICRwYWNrYWdlLT5nZXRUcmFuc3BvcnRPcHRpb25zKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXk8aW50fHN0cmluZywgc3RyaW5nPiAka2V5cwogICAgICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+ICAgICAgJGRhdGEKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5PHN0cmluZywgbWl4ZWQ+CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZHVtcFZhbHVlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBhcnJheSAka2V5cywgYXJyYXkgJGRhdGEpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGtleXMgYXMgJG1ldGhvZCA9PiAka2V5KSB7CiAgICAgICAgICAgIGlmIChpc19udW1lcmljKCRtZXRob2QpKSB7CiAgICAgICAgICAgICAgICAkbWV0aG9kID0gJGtleTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGdldHRlciA9ICdnZXQnLnVjZmlyc3QoJG1ldGhvZCk7CiAgICAgICAgICAgICR2YWx1ZSA9ICRwYWNrYWdlLT4kZ2V0dGVyKCk7CgogICAgICAgICAgICBpZiAobnVsbCAhPT0gJHZhbHVlICYmICEoXGlzX2FycmF5KCR2YWx1ZSkgJiYgMCA9PT0gXGNvdW50KCR2YWx1ZSkpKSB7CiAgICAgICAgICAgICAgICAkZGF0YVska2V5XSA9ICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkYXRhOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CgovKioKICogQmFzZSBjbGFzcyBmb3IgcGFja2FnZXMgcHJvdmlkaW5nIG5hbWUgc3RvcmFnZSBhbmQgZGVmYXVsdCBtYXRjaCBpbXBsZW1lbnRhdGlvbgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KYWJzdHJhY3QgY2xhc3MgQmFzZVBhY2thZ2UgaW1wbGVtZW50cyBQYWNrYWdlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHBocHN0YW4tdmFyIGFycmF5PG5vbi1lbXB0eS1zdHJpbmcsIGFycmF5e2Rlc2NyaXB0aW9uOiBzdHJpbmcsIG1ldGhvZDogTGluazo6VFlQRV8qfT4KICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljICRzdXBwb3J0ZWRMaW5rVHlwZXMgPSBhcnJheSgKICAgICAgICAncmVxdWlyZScgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAncmVxdWlyZXMnLCAnbWV0aG9kJyA9PiBMaW5rOjpUWVBFX1JFUVVJUkUpLAogICAgICAgICdjb25mbGljdCcgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAnY29uZmxpY3RzJywgJ21ldGhvZCcgPT4gTGluazo6VFlQRV9DT05GTElDVCksCiAgICAgICAgJ3Byb3ZpZGUnID0+IGFycmF5KCdkZXNjcmlwdGlvbicgPT4gJ3Byb3ZpZGVzJywgJ21ldGhvZCcgPT4gTGluazo6VFlQRV9QUk9WSURFKSwKICAgICAgICAncmVwbGFjZScgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAncmVwbGFjZXMnLCAnbWV0aG9kJyA9PiBMaW5rOjpUWVBFX1JFUExBQ0UpLAogICAgICAgICdyZXF1aXJlLWRldicgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAncmVxdWlyZXMgKGZvciBkZXZlbG9wbWVudCknLCAnbWV0aG9kJyA9PiBMaW5rOjpUWVBFX0RFVl9SRVFVSVJFKSwKICAgICk7CgogICAgY29uc3QgU1RBQklMSVRZX1NUQUJMRSA9IDA7CiAgICBjb25zdCBTVEFCSUxJVFlfUkMgPSA1OwogICAgY29uc3QgU1RBQklMSVRZX0JFVEEgPSAxMDsKICAgIGNvbnN0IFNUQUJJTElUWV9BTFBIQSA9IDE1OwogICAgY29uc3QgU1RBQklMSVRZX0RFViA9IDIwOwoKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgc2VsZjo6U1RBQklMSVRZXyo+ICovCiAgICBwdWJsaWMgc3RhdGljICRzdGFiaWxpdGllcyA9IGFycmF5KAogICAgICAgICdzdGFibGUnID0+IHNlbGY6OlNUQUJJTElUWV9TVEFCTEUsCiAgICAgICAgJ1JDJyA9PiBzZWxmOjpTVEFCSUxJVFlfUkMsCiAgICAgICAgJ2JldGEnID0+IHNlbGY6OlNUQUJJTElUWV9CRVRBLAogICAgICAgICdhbHBoYScgPT4gc2VsZjo6U1RBQklMSVRZX0FMUEhBLAogICAgICAgICdkZXYnID0+IHNlbGY6OlNUQUJJTElUWV9ERVYsCiAgICApOwoKICAgIC8qKgogICAgICogUkVBRC1PTkxZOiBUaGUgcGFja2FnZSBpZCwgcHVibGljIGZvciBmYXN0IGFjY2VzcyBpbiBkZXBlbmRlbmN5IHNvbHZlcgogICAgICogQHZhciBpbnQKICAgICAqIEBpbnRlcm5hbAogICAgICogQHJlYWRvbmx5CiAgICAgKi8KICAgIHB1YmxpYyAkaWQ7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkbmFtZTsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlOYW1lOwogICAgLyoqIEB2YXIgP1JlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkcmVwb3NpdG9yeSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBBbGwgZGVzY2VuZGFudHMnIGNvbnN0cnVjdG9ycyBzaG91bGQgY2FsbCB0aGlzIHBhcmVudCBjb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHBhY2thZ2UncyBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJldHR5TmFtZSA9ICRuYW1lOwogICAgICAgICR0aGlzLT5uYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CiAgICAgICAgJHRoaXMtPmlkID0gLTE7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eU5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJldHR5TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lcygkcHJvdmlkZXMgPSB0cnVlKQogICAgewogICAgICAgICRuYW1lcyA9IGFycmF5KAogICAgICAgICAgICAkdGhpcy0+Z2V0TmFtZSgpID0+IHRydWUsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRwcm92aWRlcykgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UHJvdmlkZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJG5hbWVzWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAkbmFtZXNbJGxpbmstPmdldFRhcmdldCgpXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfa2V5cygkbmFtZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElkKCRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yeShSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5KQogICAgewogICAgICAgIGlmICgkdGhpcy0+cmVwb3NpdG9yeSAmJiAkcmVwb3NpdG9yeSAhPT0gJHRoaXMtPnJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignQSBwYWNrYWdlIGNhbiBvbmx5IGJlIGFkZGVkIHRvIG9uZSByZXBvc2l0b3J5Jyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5ID0gJHJlcG9zaXRvcnk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yeSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogY2hlY2tzIGlmIHRoaXMgcGFja2FnZSBpcyBhIHBsYXRmb3JtIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUGxhdGZvcm0oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgUGxhdGZvcm1SZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIHVuaXF1ZSBuYW1lLCBjb25zdHJ1Y3RlZCBmcm9tIG5hbWUsIHZlcnNpb24gYW5kIHJlbGVhc2UgdHlwZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VW5pcXVlTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXROYW1lKCkuJy0nLiR0aGlzLT5nZXRWZXJzaW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVxdWFscyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRzZWxmID0gJHRoaXM7CiAgICAgICAgaWYgKCR0aGlzIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRzZWxmID0gJHRoaXMtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZSA9PT0gJHNlbGY7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyB0aGUgcGFja2FnZSBpbnRvIGEgcmVhZGFibGUgYW5kIHVuaXF1ZSBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRVbmlxdWVOYW1lKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVN0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRQcmV0dHlOYW1lKCkuJyAnLiR0aGlzLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RnVsbFByZXR0eVZlcnNpb24oJHRydW5jYXRlID0gdHJ1ZSwgJGRpc3BsYXlNb2RlID0gUGFja2FnZUludGVyZmFjZTo6RElTUExBWV9TT1VSQ0VfUkVGX0lGX0RFVikKICAgIHsKICAgICAgICBpZiAoJGRpc3BsYXlNb2RlID09PSBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX1NPVVJDRV9SRUZfSUZfREVWICYmCiAgICAgICAgICAgICghJHRoaXMtPmlzRGV2KCkgfHwgIVxpbl9hcnJheSgkdGhpcy0+Z2V0U291cmNlVHlwZSgpLCBhcnJheSgnaGcnLCAnZ2l0JykpKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoJGRpc3BsYXlNb2RlKSB7CiAgICAgICAgICAgIGNhc2UgUGFja2FnZUludGVyZmFjZTo6RElTUExBWV9TT1VSQ0VfUkVGX0lGX0RFVjoKICAgICAgICAgICAgY2FzZSBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX1NPVVJDRV9SRUY6CiAgICAgICAgICAgICAgICAkcmVmZXJlbmNlID0gJHRoaXMtPmdldFNvdXJjZVJlZmVyZW5jZSgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUGFja2FnZUludGVyZmFjZTo6RElTUExBWV9ESVNUX1JFRjoKICAgICAgICAgICAgICAgICRyZWZlcmVuY2UgPSAkdGhpcy0+Z2V0RGlzdFJlZmVyZW5jZSgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignRGlzcGxheSBtb2RlICcuJGRpc3BsYXlNb2RlLicgaXMgbm90IHN1cHBvcnRlZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRyZWZlcmVuY2UpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBzb3VyY2UgcmVmZXJlbmNlIGlzIGEgc2hhMSBoYXNoIC0tIHRydW5jYXRlCiAgICAgICAgaWYgKCR0cnVuY2F0ZSAmJiBcc3RybGVuKCRyZWZlcmVuY2UpID09PSA0MCAmJiAkdGhpcy0+Z2V0U291cmNlVHlwZSgpICE9PSAnc3ZuJykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZXR0eVZlcnNpb24oKSAuICcgJyAuIHN1YnN0cigkcmVmZXJlbmNlLCAwLCA3KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UHJldHR5VmVyc2lvbigpIC4gJyAnIC4gJHJlZmVyZW5jZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50CiAgICAgKgogICAgICogQHBocHN0YW4tcmV0dXJuIHNlbGY6OlNUQUJJTElUWV8qCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGFiaWxpdHlQcmlvcml0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRzdGFiaWxpdGllc1skdGhpcy0+Z2V0U3RhYmlsaXR5KCldOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2Nsb25lKCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSA9IG51bGw7CiAgICAgICAgJHRoaXMtPmlkID0gLTE7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZCBhIHJlZ2V4cCBmcm9tIGEgcGFja2FnZSBuYW1lLCBleHBhbmRpbmcgKiBnbG9icyBhcyByZXF1aXJlZAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRhbGxvd1BhdHRlcm4KICAgICAqIEBwYXJhbSAgc3RyaW5nICR3cmFwICAgICAgICAgV3JhcCB0aGUgY2xlYW5lZCBzdHJpbmcgYnkgdGhlIGdpdmVuIHN0cmluZwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYWNrYWdlTmFtZVRvUmVnZXhwKCRhbGxvd1BhdHRlcm4sICR3cmFwID0gJ3teJXMkfWknKQogICAgewogICAgICAgICRjbGVhbmVkQWxsb3dQYXR0ZXJuID0gc3RyX3JlcGxhY2UoJ1xcKicsICcuKicsIHByZWdfcXVvdGUoJGFsbG93UGF0dGVybikpOwoKICAgICAgICByZXR1cm4gc3ByaW50Zigkd3JhcCwgJGNsZWFuZWRBbGxvd1BhdHRlcm4pOwogICAgfQoKICAgIC8qKgogICAgICogQnVpbGQgYSByZWdleHAgZnJvbSBwYWNrYWdlIG5hbWVzLCBleHBhbmRpbmcgKiBnbG9icyBhcyByZXF1aXJlZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkcGFja2FnZU5hbWVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICR3cmFwCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhY2thZ2VOYW1lc1RvUmVnZXhwKGFycmF5ICRwYWNrYWdlTmFtZXMsICR3cmFwID0gJ3teKD86JXMpJH1pRCcpCiAgICB7CiAgICAgICAgJHBhY2thZ2VOYW1lcyA9IGFycmF5X21hcCgKICAgICAgICAgICAgZnVuY3Rpb24gKCRwYWNrYWdlTmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCRwYWNrYWdlTmFtZSwgJyVzJyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICRwYWNrYWdlTmFtZXMKICAgICAgICApOwoKICAgICAgICByZXR1cm4gc3ByaW50Zigkd3JhcCwgaW1wbG9kZSgnfCcsICRwYWNrYWdlTmFtZXMpKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2NrZXI7CnVzZSBDb21wb3NlclxQY3JlXFByZWc7CnVzZSBDb21wb3NlclxVdGlsXExvb3A7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luTWFuYWdlcjsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXEF1dG9sb2FkXEF1dG9sb2FkR2VuZXJhdG9yOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBcmNoaXZlclxBcmNoaXZlTWFuYWdlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaGl2IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBDb21wb3Nlcgp7CiAgICAvKgogICAgICogRXhhbXBsZXMgb2YgdGhlIGZvbGxvd2luZyBjb25zdGFudHMgaW4gdGhlIHZhcmlvdXMgY29uZmlndXJhdGlvbnMgdGhleSBjYW4gYmUgaW4KICAgICAqCiAgICAgKiByZWxlYXNlcyAocGhhcik6CiAgICAgKiBjb25zdCBWRVJTSU9OID0gJzEuOC4yJzsKICAgICAqIGNvbnN0IEJSQU5DSF9BTElBU19WRVJTSU9OID0gJyc7CiAgICAgKiBjb25zdCBSRUxFQVNFX0RBVEUgPSAnMjAxOS0wMS0yOSAxNTowMDo1Myc7CiAgICAgKiBjb25zdCBTT1VSQ0VfVkVSU0lPTiA9ICcnOwogICAgICoKICAgICAqIHNuYXBzaG90IGJ1aWxkcyAocGhhcik6CiAgICAgKiBjb25zdCBWRVJTSU9OID0gJ2QzODczYTA1NjUwZTE2ODI1MTA2N2Q5NjQ4ODQ1YzIyMGM1MGUyZDcnOwogICAgICogY29uc3QgQlJBTkNIX0FMSUFTX1ZFUlNJT04gPSAnMS45LWRldic7CiAgICAgKiBjb25zdCBSRUxFQVNFX0RBVEUgPSAnMjAxOS0wMi0yMCAwNzo0Mzo1Nic7CiAgICAgKiBjb25zdCBTT1VSQ0VfVkVSU0lPTiA9ICcnOwogICAgICoKICAgICAqIHNvdXJjZSAoZ2l0IGNsb25lKToKICAgICAqIGNvbnN0IFZFUlNJT04gPSAnQHBhY2thZ2VfdmVyc2lvbkAnOwogICAgICogY29uc3QgQlJBTkNIX0FMSUFTX1ZFUlNJT04gPSAnQHBhY2thZ2VfYnJhbmNoX2FsaWFzX3ZlcnNpb25AJzsKICAgICAqIGNvbnN0IFJFTEVBU0VfREFURSA9ICdAcmVsZWFzZV9kYXRlQCc7CiAgICAgKiBjb25zdCBTT1VSQ0VfVkVSU0lPTiA9ICcxLjgtZGV2K3NvdXJjZSc7CiAgICAgKi8KICAgIGNvbnN0IFZFUlNJT04gPSAnMi4yLjUnOwogICAgY29uc3QgQlJBTkNIX0FMSUFTX1ZFUlNJT04gPSAnJzsKICAgIGNvbnN0IFJFTEVBU0VfREFURSA9ICcyMDIyLTAxLTIxIDE3OjI1OjUyJzsKICAgIGNvbnN0IFNPVVJDRV9WRVJTSU9OID0gJyc7CgogICAgLyoqCiAgICAgKiBWZXJzaW9uIG51bWJlciBvZiB0aGUgaW50ZXJuYWwgY29tcG9zZXItcnVudGltZS1hcGkgcGFja2FnZQogICAgICoKICAgICAqIFRoaXMgaXMgdXNlZCB0byB2ZXJzaW9uIGZlYXR1cmVzIGF2YWlsYWJsZSB0byBwcm9qZWN0cyBhdCBydW50aW1lCiAgICAgKiBsaWtlIHRoZSBwbGF0Zm9ybS1jaGVjayBmaWxlLCB0aGUgQ29tcG9zZXJcSW5zdGFsbGVkVmVyc2lvbnMgY2xhc3MKICAgICAqIGFuZCBwb3NzaWJseSBvdGhlcnMgaW4gdGhlIGZ1dHVyZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBSVU5USU1FX0FQSV9WRVJTSU9OID0gJzIuMi4yJzsKCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigpCiAgICB7CiAgICAgICAgLy8gbm8gcmVwbGFjZW1lbnQgZG9uZSwgdGhpcyBtdXN0IGJlIGEgc291cmNlIGNoZWNrb3V0CiAgICAgICAgaWYgKHNlbGY6OlZFUlNJT04gPT09ICdAcGFja2FnZV92ZXJzaW9uJy4nQCcpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OlNPVVJDRV9WRVJTSU9OOwogICAgICAgIH0KCiAgICAgICAgLy8gd2UgaGF2ZSBhIGJyYW5jaCBhbGlhcyBhbmQgdmVyc2lvbiBpcyBhIGNvbW1pdCBpZCwgdGhpcyBtdXN0IGJlIGEgc25hcHNob3QgYnVpbGQKICAgICAgICBpZiAoc2VsZjo6QlJBTkNIX0FMSUFTX1ZFUlNJT04gIT09ICcnICYmIFByZWc6OmlzTWF0Y2goJ3teW2EtZjAtOV17NDB9JH0nLCBzZWxmOjpWRVJTSU9OKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6QlJBTkNIX0FMSUFTX1ZFUlNJT04uJysnLnNlbGY6OlZFUlNJT047CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6VkVSU0lPTjsKICAgIH0KCiAgICAvKioKICAgICAqIEB2YXIgUm9vdFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkcGFja2FnZTsKCiAgICAvKioKICAgICAqIEB2YXIgP0xvY2tlcgogICAgICovCiAgICBwcml2YXRlICRsb2NrZXIgPSBudWxsOwoKICAgIC8qKgogICAgICogQHZhciBMb29wCiAgICAgKi8KICAgIHByaXZhdGUgJGxvb3A7CgogICAgLyoqCiAgICAgKiBAdmFyIFJlcG9zaXRvcnlcUmVwb3NpdG9yeU1hbmFnZXIKICAgICAqLwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yeU1hbmFnZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyCiAgICAgKi8KICAgIHByaXZhdGUgJGRvd25sb2FkTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXIKICAgICAqLwogICAgcHJpdmF0ZSAkaW5zdGFsbGF0aW9uTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgUGx1Z2luXFBsdWdpbk1hbmFnZXIKICAgICAqLwogICAgcHJpdmF0ZSAkcGx1Z2luTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgQ29uZmlnCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEB2YXIgRXZlbnREaXNwYXRjaGVyCiAgICAgKi8KICAgIHByaXZhdGUgJGV2ZW50RGlzcGF0Y2hlcjsKCiAgICAvKioKICAgICAqIEB2YXIgQXV0b2xvYWRcQXV0b2xvYWRHZW5lcmF0b3IKICAgICAqLwogICAgcHJpdmF0ZSAkYXV0b2xvYWRHZW5lcmF0b3I7CgogICAgLyoqCiAgICAgKiBAdmFyIEFyY2hpdmVNYW5hZ2VyCiAgICAgKi8KICAgIHByaXZhdGUgJGFyY2hpdmVNYW5hZ2VyOwoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQYWNrYWdlKFJvb3RQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5wYWNrYWdlID0gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFJvb3RQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbmZpZyhDb25maWcgJGNvbmZpZykKICAgIHsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29uZmlnCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25maWcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2NrZXIoTG9ja2VyICRsb2NrZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2tlciA9ICRsb2NrZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuID9Mb2NrZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2tlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NrZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvb3AoTG9vcCAkbG9vcCkKICAgIHsKICAgICAgICAkdGhpcy0+bG9vcCA9ICRsb29wOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBMb29wCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb29wKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvb3A7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcG9zaXRvcnlNYW5hZ2VyKFJlcG9zaXRvcnlNYW5hZ2VyICRtYW5hZ2VyKQogICAgewogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSZXBvc2l0b3J5TWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yeU1hbmFnZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb3NpdG9yeU1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERvd25sb2FkTWFuYWdlcihEb3dubG9hZE1hbmFnZXIgJG1hbmFnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvd25sb2FkTWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBEb3dubG9hZE1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERvd25sb2FkTWFuYWdlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVNYW5hZ2VyKEFyY2hpdmVNYW5hZ2VyICRtYW5hZ2VyKQogICAgewogICAgICAgICR0aGlzLT5hcmNoaXZlTWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBBcmNoaXZlTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJjaGl2ZU1hbmFnZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJjaGl2ZU1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEluc3RhbGxhdGlvbk1hbmFnZXIoSW5zdGFsbGF0aW9uTWFuYWdlciAkbWFuYWdlcikKICAgIHsKICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBJbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmluc3RhbGxhdGlvbk1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBsdWdpbk1hbmFnZXIoUGx1Z2luTWFuYWdlciAkbWFuYWdlcikKICAgIHsKICAgICAgICAkdGhpcy0+cGx1Z2luTWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQbHVnaW5NYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQbHVnaW5NYW5hZ2VyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBsdWdpbk1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEV2ZW50RGlzcGF0Y2hlcihFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlcikKICAgIHsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyID0gJGV2ZW50RGlzcGF0Y2hlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gRXZlbnREaXNwYXRjaGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFdmVudERpc3BhdGNoZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBdXRvbG9hZEdlbmVyYXRvcihBdXRvbG9hZEdlbmVyYXRvciAkYXV0b2xvYWRHZW5lcmF0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPmF1dG9sb2FkR2VuZXJhdG9yID0gJGF1dG9sb2FkR2VuZXJhdG9yOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBBdXRvbG9hZEdlbmVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0b2xvYWRHZW5lcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXV0b2xvYWRHZW5lcmF0b3I7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSnNvbjsKCnVzZSBFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSnNvblZhbGlkYXRpb25FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24KewogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ1tdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXJyb3JzOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGVycm9ycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsICRlcnJvcnMgPSBhcnJheSgpLCBFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JzID0gJGVycm9yczsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KChzdHJpbmcpICRtZXNzYWdlLCAwLCAkcHJldmlvdXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxKc29uOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5OwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEpzb25NYW5pcHVsYXRvcgp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgc3RhdGljICRERUZJTkVTID0gJyg/KERFRklORSkKICAgICAgICg/PG51bWJlcj4gICAgLT8gKD89IFsxLTldfDAoPyFcZCkgKSBcZCsrIChcLlxkKyspPyAoW2VFXSBbKy1dPysgXGQrKyk/ICkKICAgICAgICg/PGJvb2xlYW4+ICAgdHJ1ZSB8IGZhbHNlIHwgbnVsbCApCiAgICAgICAoPzxzdHJpbmc+ICAgICIgKFteIlxcXFxdKisgfCBcXFxcIFsiXFxcXGJmbnJ0XC9dIHwgXFxcXCB1IFswLTlBLUZhLWZdezR9ICkqICIgKQogICAgICAgKD88YXJyYXk+ICAgICBcWyAgKD86ICAoPyZqc29uKSBccyorICg/OiAsICg/Jmpzb24pIFxzKisgKSorICApPysgIFxzKisgXF0gKQogICAgICAgKD88cGFpcj4gICAgICBccyorICg/JnN0cmluZykgXHMqKyA6ICg/Jmpzb24pIFxzKisgKQogICAgICAgKD88b2JqZWN0PiAgICBceyAgKD86ICAoPyZwYWlyKSAgKD86ICwgKD8mcGFpcikgICkqKyAgKT8rICBccyorIFx9ICkKICAgICAgICg/PGpzb24+ICAgICAgXHMqKyAoPzogKD8mbnVtYmVyKSB8ICg/JmJvb2xlYW4pIHwgKD8mc3RyaW5nKSB8ICg/JmFycmF5KSB8ICg/Jm9iamVjdCkgKSApCiAgICApJzsKCiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNvbnRlbnRzOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRuZXdsaW5lOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRpbmRlbnQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvbnRlbnRzKQogICAgewogICAgICAgICRjb250ZW50cyA9IHRyaW0oJGNvbnRlbnRzKTsKICAgICAgICBpZiAoJGNvbnRlbnRzID09PSAnJykgewogICAgICAgICAgICAkY29udGVudHMgPSAne30nOwogICAgICAgIH0KICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJyNeXHsoLiopXH0kI3MnLCAkY29udGVudHMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGUganNvbiBmaWxlIG11c3QgYmUgYW4gb2JqZWN0ICh7fSknKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPm5ld2xpbmUgPSBmYWxzZSAhPT0gc3RycG9zKCRjb250ZW50cywgIlxyXG4iKSA/ICJcclxuIiA6ICJcbiI7CiAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gJGNvbnRlbnRzID09PSAne30nID8gJ3snIC4gJHRoaXMtPm5ld2xpbmUgLiAnfScgOiAkY29udGVudHM7CiAgICAgICAgJHRoaXMtPmRldGVjdEluZGVudGluZygpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRlbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRlbnRzIC4gJHRoaXMtPm5ld2xpbmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25zdHJhaW50CiAgICAgKiBAcGFyYW0gYm9vbCAgICRzb3J0UGFja2FnZXMKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTGluaygkdHlwZSwgJHBhY2thZ2UsICRjb25zdHJhaW50LCAkc29ydFBhY2thZ2VzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CgogICAgICAgIC8vIG5vIGxpbmsgb2YgdGhhdCB0eXBlIHlldAogICAgICAgIGlmICghaXNzZXQoJGRlY29kZWRbJHR5cGVdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE1haW5LZXkoJHR5cGUsIGFycmF5KCRwYWNrYWdlID0+ICRjb25zdHJhaW50KSk7CiAgICAgICAgfQoKICAgICAgICAkcmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+XHMqXHtccyooPzooPyZzdHJpbmcpXHMqOlxzKig/Jmpzb24pXHMqLFxzKikqPyknLgogICAgICAgICAgICAnKD9QPHByb3BlcnR5PicucHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCR0eXBlKSkuJ1xzKjpccyopKD9QPHZhbHVlPig/Jmpzb24pKSg/UDxlbmQ+LiopfXN4JzsKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJHJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkbGlua3MgPSAkbWF0Y2hlc1sndmFsdWUnXTsKCiAgICAgICAgLy8gdHJ5IHRvIGZpbmQgZXhpc3RpbmcgbGluawogICAgICAgICRwYWNrYWdlUmVnZXggPSBzdHJfcmVwbGFjZSgnLycsICdcXFxcPy8nLCBwcmVnX3F1b3RlKCRwYWNrYWdlKSk7CiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLiciKD9QPHBhY2thZ2U+Jy4kcGFja2FnZVJlZ2V4LicpIihccyo6XHMqKSg/JnN0cmluZyl9aXgnOwogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRyZWdleCwgJGxpbmtzLCAkcGFja2FnZU1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBleGlzdGluZyBsaW5rCiAgICAgICAgICAgICRleGlzdGluZ1BhY2thZ2UgPSAkcGFja2FnZU1hdGNoZXNbJ3BhY2thZ2UnXTsKICAgICAgICAgICAgJHBhY2thZ2VSZWdleCA9IHN0cl9yZXBsYWNlKCcvJywgJ1xcXFw/LycsIHByZWdfcXVvdGUoJGV4aXN0aW5nUGFja2FnZSkpOwogICAgICAgICAgICAkbGlua3MgPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJ3snLnNlbGY6OiRERUZJTkVTLiciJy4kcGFja2FnZVJlZ2V4LiciKD9QPHNlcGFyYXRvcj5ccyo6XHMqKSg/JnN0cmluZyl9aXgnLCBmdW5jdGlvbiAoJG0pIHVzZSAoJGV4aXN0aW5nUGFja2FnZSwgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBKc29uRmlsZTo6ZW5jb2RlKHN0cl9yZXBsYWNlKCdcXC8nLCAnLycsICRleGlzdGluZ1BhY2thZ2UpKSAuICRtWydzZXBhcmF0b3InXSAuICciJyAuICRjb25zdHJhaW50IC4gJyInOwogICAgICAgICAgICB9LCAkbGlua3MpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoKCcjXlxzKlx7XHMqXFMrLio/KFxzKlx9XHMqKSQjcycsICRsaW5rcywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgLy8gbGluayBtaXNzaW5nIGJ1dCBub24gZW1wdHkgbGlua3MKICAgICAgICAgICAgICAgICRsaW5rcyA9IFByZWc6OnJlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgJ3snLnByZWdfcXVvdGUoJG1hdGNoWzFdKS4nJH0nLAogICAgICAgICAgICAgICAgICAgIC8vIGFkZGNzbGFzaGVzIGlzIHVzZWQgdG8gZG91YmxlIHVwIGJhY2tzbGFzaGVzLyQgc2luY2UgcHJlZ19yZXBsYWNlIHJlc29sdmVzIHRoZW0gYXMgYmFjayByZWZlcmVuY2VzIG90aGVyd2lzZSwgc2VlICMxNTg4CiAgICAgICAgICAgICAgICAgICAgYWRkY3NsYXNoZXMoJywnIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJHBhY2thZ2UpLic6ICcuSnNvbkZpbGU6OmVuY29kZSgkY29uc3RyYWludCkgLiAkbWF0Y2hbMV0sICdcXCQnKSwKICAgICAgICAgICAgICAgICAgICAkbGlua3MKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBsaW5rcyBlbXB0eQogICAgICAgICAgICAgICAgJGxpbmtzID0gJ3snIC4gJHRoaXMtPm5ld2xpbmUgLgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRlbnQgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgkcGFja2FnZSkuJzogJy5Kc29uRmlsZTo6ZW5jb2RlKCRjb25zdHJhaW50KSAuICR0aGlzLT5uZXdsaW5lIC4KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZW50IC4gJ30nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAodHJ1ZSA9PT0gJHNvcnRQYWNrYWdlcykgewogICAgICAgICAgICAkcmVxdWlyZW1lbnRzID0ganNvbl9kZWNvZGUoJGxpbmtzLCB0cnVlKTsKICAgICAgICAgICAgJHRoaXMtPnNvcnRQYWNrYWdlcygkcmVxdWlyZW1lbnRzKTsKICAgICAgICAgICAgJGxpbmtzID0gJHRoaXMtPmZvcm1hdCgkcmVxdWlyZW1lbnRzKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb250ZW50cyA9ICRtYXRjaGVzWydzdGFydCddIC4gJG1hdGNoZXNbJ3Byb3BlcnR5J10gLiAkbGlua3MgLiAkbWF0Y2hlc1snZW5kJ107CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogU29ydHMgcGFja2FnZXMgYnkgaW1wb3J0YW5jZSAocGxhdGZvcm0gcGFja2FnZXMgZmlyc3QsIHRoZW4gUEhQIGRlcGVuZGVuY2llcykgYW5kIGFscGhhYmV0aWNhbGx5LgogICAgICoKICAgICAqIEBsaW5rIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMi1saWJyYXJpZXMubWQjcGxhdGZvcm0tcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkcGFja2FnZXMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNvcnRQYWNrYWdlcyhhcnJheSAmJHBhY2thZ2VzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcHJlZml4ID0gZnVuY3Rpb24gKCRyZXF1aXJlbWVudCkgewogICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcmVxdWlyZW1lbnQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gUHJlZzo6cmVwbGFjZSgKICAgICAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJy9ecGhwLycsCiAgICAgICAgICAgICAgICAgICAgICAgICcvXmhodm0vJywKICAgICAgICAgICAgICAgICAgICAgICAgJy9eZXh0LycsCiAgICAgICAgICAgICAgICAgICAgICAgICcvXmxpYi8nLAogICAgICAgICAgICAgICAgICAgICAgICAnL15cRC8nLAogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICcwLSQwJywKICAgICAgICAgICAgICAgICAgICAgICAgJzEtJDAnLAogICAgICAgICAgICAgICAgICAgICAgICAnMi0kMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICczLSQwJywKICAgICAgICAgICAgICAgICAgICAgICAgJzQtJDAnLAogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVtZW50CiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJzUtJy4kcmVxdWlyZW1lbnQ7CiAgICAgICAgfTsKCiAgICAgICAgdWtzb3J0KCRwYWNrYWdlcywgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkcHJlZml4KSB7CiAgICAgICAgICAgIHJldHVybiBzdHJuYXRjbXAoJHByZWZpeCgkYSksICRwcmVmaXgoJGIpKTsKICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgJG5hbWUKICAgICAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPiAgJGNvbmZpZwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAkYXBwZW5kCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoJG5hbWUsICRjb25maWcsICRhcHBlbmQgPSB0cnVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgncmVwb3NpdG9yaWVzJywgJG5hbWUsICRjb25maWcsICRhcHBlbmQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVSZXBvc2l0b3J5KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgncmVwb3NpdG9yaWVzJywgJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIG1peGVkICAkdmFsdWUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQ29uZmlnU2V0dGluZygkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgnY29uZmlnJywgJG5hbWUsICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUNvbmZpZ1NldHRpbmcoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVTdWJOb2RlKCdjb25maWcnLCAkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFByb3BlcnR5KCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ3N1Z2dlc3QuJykgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRTdWJOb2RlKCdzdWdnZXN0Jywgc3Vic3RyKCRuYW1lLCA4KSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICdleHRyYS4nKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmFkZFN1Yk5vZGUoJ2V4dHJhJywgc3Vic3RyKCRuYW1lLCA2KSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICdzY3JpcHRzLicpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgnc2NyaXB0cycsIHN1YnN0cigkbmFtZSwgOCksICR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE1haW5LZXkoJG5hbWUsICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KCRuYW1lKQogICAgewogICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICdzdWdnZXN0LicpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgnc3VnZ2VzdCcsIHN1YnN0cigkbmFtZSwgOCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ2V4dHJhLicpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgnZXh0cmEnLCBzdWJzdHIoJG5hbWUsIDYpKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICdzY3JpcHRzLicpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgnc2NyaXB0cycsIHN1YnN0cigkbmFtZSwgOCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVNYWluS2V5KCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1haW5Ob2RlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gbWl4ZWQgICR2YWx1ZQogICAgICogQHBhcmFtIGJvb2wgICAkYXBwZW5kCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFN1Yk5vZGUoJG1haW5Ob2RlLCAkbmFtZSwgJHZhbHVlLCAkYXBwZW5kID0gdHJ1ZSkKICAgIHsKICAgICAgICAkZGVjb2RlZCA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgJHN1Yk5hbWUgPSBudWxsOwogICAgICAgIGlmIChpbl9hcnJheSgkbWFpbk5vZGUsIGFycmF5KCdjb25maWcnLCAnZXh0cmEnLCAnc2NyaXB0cycpKSAmJiBmYWxzZSAhPT0gc3RycG9zKCRuYW1lLCAnLicpKSB7CiAgICAgICAgICAgIGxpc3QoJG5hbWUsICRzdWJOYW1lKSA9IGV4cGxvZGUoJy4nLCAkbmFtZSwgMik7CiAgICAgICAgfQoKICAgICAgICAvLyBubyBtYWluIG5vZGUgeWV0CiAgICAgICAgaWYgKCFpc3NldCgkZGVjb2RlZFskbWFpbk5vZGVdKSkgewogICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRNYWluS2V5KCRtYWluTm9kZSwgYXJyYXkoJG5hbWUgPT4gYXJyYXkoJHN1Yk5hbWUgPT4gJHZhbHVlKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZE1haW5LZXkoJG1haW5Ob2RlLCBhcnJheSgkbmFtZSA9PiAkdmFsdWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBtYWluIG5vZGUgY29udGVudCBub3QgbWF0Y2gtYWJsZQogICAgICAgICRub2RlUmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+IFxzKiBceyBccyogKD86ICg/JnN0cmluZykgXHMqIDogKD8manNvbikgXHMqICwgXHMqICkqPycuCiAgICAgICAgICAgIHByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkbWFpbk5vZGUpKS4nXHMqOlxzKikoP1A8Y29udGVudD4oPyZvYmplY3QpKSg/UDxlbmQ+LiopfXN4JzsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCFQcmVnOjppc01hdGNoKCRub2RlUmVnZXgsICR0aGlzLT5jb250ZW50cywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgPT09IFBSRUdfQkFDS1RSQUNLX0xJTUlUX0VSUk9SKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICAkY2hpbGRyZW4gPSAkbWF0Y2hbJ2NvbnRlbnQnXTsKICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgkY2hpbGRyZW4pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICR0aGF0ID0gJHRoaXM7CgogICAgICAgIC8vIGNoaWxkIGV4aXN0cwogICAgICAgICRjaGlsZFJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLicoP1A8c3RhcnQ+IicucHJlZ19xdW90ZSgkbmFtZSkuJyJccyo6XHMqKSg/UDxjb250ZW50Pig/Jmpzb24pKSg/UDxlbmQ+LD8pfXgnOwogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCRjaGlsZFJlZ2V4LCAkY2hpbGRyZW4sICRtYXRjaGVzKSkgewogICAgICAgICAgICAkY2hpbGRyZW4gPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJGNoaWxkUmVnZXgsIGZ1bmN0aW9uICgkbWF0Y2hlcykgdXNlICgkc3ViTmFtZSwgJHZhbHVlLCAkdGhhdCkgewogICAgICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJGN1clZhbCA9IGpzb25fZGVjb2RlKCRtYXRjaGVzWydjb250ZW50J10sIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJGN1clZhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGN1clZhbCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRjdXJWYWxbJHN1Yk5hbWVdID0gJHZhbHVlOwogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRjdXJWYWw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWydzdGFydCddIC4gJHRoYXQtPmZvcm1hdCgkdmFsdWUsIDEpIC4gJG1hdGNoZXNbJ2VuZCddOwogICAgICAgICAgICB9LCAkY2hpbGRyZW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFByZWc6Om1hdGNoKCcjXnsgKD9QPGxlYWRpbmdzcGFjZT5ccyo/KSAoP1A8Y29udGVudD5cUysuKj8pPyAoP1A8dHJhaWxpbmdzcGFjZT5ccyopIH0kI3N4JywgJGNoaWxkcmVuLCAkbWF0Y2gpOwoKICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSAnJzsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbJ3RyYWlsaW5nc3BhY2UnXSkpIHsKICAgICAgICAgICAgICAgICR3aGl0ZXNwYWNlID0gJG1hdGNoWyd0cmFpbGluZ3NwYWNlJ107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoWydjb250ZW50J10pKSB7CiAgICAgICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBhcnJheSgkc3ViTmFtZSA9PiAkdmFsdWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNoaWxkIG1pc3NpbmcgYnV0IG5vbiBlbXB0eSBjaGlsZHJlbgogICAgICAgICAgICAgICAgaWYgKCRhcHBlbmQpIHsKICAgICAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSBQcmVnOjpyZXBsYWNlKAogICAgICAgICAgICAgICAgICAgICAgICAnIycuJHdoaXRlc3BhY2UuJ30kIycsCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZGNzbGFzaGVzKCcsJyAuICR0aGlzLT5uZXdsaW5lIC4gJHRoaXMtPmluZGVudCAuICR0aGlzLT5pbmRlbnQgLiBKc29uRmlsZTo6ZW5jb2RlKCRuYW1lKS4nOiAnLiR0aGlzLT5mb3JtYXQoJHZhbHVlLCAxKSAuICR3aGl0ZXNwYWNlIC4gJ30nLCAnXFwkJyksCiAgICAgICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR3aGl0ZXNwYWNlID0gJyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbJ2xlYWRpbmdzcGFjZSddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkd2hpdGVzcGFjZSA9ICRtYXRjaFsnbGVhZGluZ3NwYWNlJ107CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSBQcmVnOjpyZXBsYWNlKAogICAgICAgICAgICAgICAgICAgICAgICAnI157Jy4kd2hpdGVzcGFjZS4nIycsCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZGNzbGFzaGVzKCd7JyAuICR3aGl0ZXNwYWNlIC4gSnNvbkZpbGU6OmVuY29kZSgkbmFtZSkuJzogJy4kdGhpcy0+Zm9ybWF0KCR2YWx1ZSwgMSkgLiAnLCcgLiAkdGhpcy0+bmV3bGluZSAuICR0aGlzLT5pbmRlbnQgLiAkdGhpcy0+aW5kZW50LCAnXFwkJyksCiAgICAgICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBhcnJheSgkc3ViTmFtZSA9PiAkdmFsdWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNoaWxkcmVuIHByZXNlbnQgYnV0IGVtcHR5CiAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSAneycgLiAkdGhpcy0+bmV3bGluZSAuICR0aGlzLT5pbmRlbnQgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgkbmFtZSkuJzogJy4kdGhpcy0+Zm9ybWF0KCR2YWx1ZSwgMSkgLiAkd2hpdGVzcGFjZSAuICd9JzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gUHJlZzo6cmVwbGFjZUNhbGxiYWNrKCRub2RlUmVnZXgsIGZ1bmN0aW9uICgkbSkgdXNlICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgcmV0dXJuICRtWydzdGFydCddIC4gJGNoaWxkcmVuIC4gJG1bJ2VuZCddOwogICAgICAgIH0sICR0aGlzLT5jb250ZW50cyk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbWFpbk5vZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lKQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAvLyBubyBub2RlIG9yIGVtcHR5IG5vZGUKICAgICAgICBpZiAoZW1wdHkoJGRlY29kZWRbJG1haW5Ob2RlXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBubyBub2RlIGNvbnRlbnQgbWF0Y2gtYWJsZQogICAgICAgICRub2RlUmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+IFxzKiBceyBccyogKD86ICg/JnN0cmluZykgXHMqIDogKD8manNvbikgXHMqICwgXHMqICkqPycuCiAgICAgICAgICAgIHByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkbWFpbk5vZGUpKS4nXHMqOlxzKikoP1A8Y29udGVudD4oPyZvYmplY3QpKSg/UDxlbmQ+LiopfXN4JzsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJG5vZGVSZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGUtPmdldENvZGUoKSA9PT0gUFJFR19CQUNLVFJBQ0tfTElNSVRfRVJST1IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgICRjaGlsZHJlbiA9ICRtYXRjaFsnY29udGVudCddOwoKICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgkY2hpbGRyZW4sIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRzdWJOYW1lID0gbnVsbDsKICAgICAgICBpZiAoaW5fYXJyYXkoJG1haW5Ob2RlLCBhcnJheSgnY29uZmlnJywgJ2V4dHJhJywgJ3NjcmlwdHMnKSkgJiYgZmFsc2UgIT09IHN0cnBvcygkbmFtZSwgJy4nKSkgewogICAgICAgICAgICBsaXN0KCRuYW1lLCAkc3ViTmFtZSkgPSBleHBsb2RlKCcuJywgJG5hbWUsIDIpOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gbm9kZSB0byByZW1vdmUKICAgICAgICBpZiAoIWlzc2V0KCRkZWNvZGVkWyRtYWluTm9kZV1bJG5hbWVdKSB8fCAoJHN1Yk5hbWUgJiYgIWlzc2V0KCRkZWNvZGVkWyRtYWluTm9kZV1bJG5hbWVdWyRzdWJOYW1lXSkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gdHJ5IGFuZCBmaW5kIGEgbWF0Y2ggZm9yIHRoZSBzdWJrZXkKICAgICAgICAka2V5UmVnZXggPSBzdHJfcmVwbGFjZSgnLycsICdcXFxcPy8nLCBwcmVnX3F1b3RlKCRuYW1lKSk7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJ3siJy4ka2V5UmVnZXguJyJccyo6fWknLCAkY2hpbGRyZW4pKSB7CiAgICAgICAgICAgIC8vIGZpbmQgYmVzdCBtYXRjaCBmb3IgdGhlIHZhbHVlIG9mICJuYW1lIgogICAgICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaEFsbCgneycuc2VsZjo6JERFRklORVMuJyInLiRrZXlSZWdleC4nIlxzKjpccyooPzooPyZqc29uKSl9eCcsICRjaGlsZHJlbiwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAkYmVzdE1hdGNoID0gJyc7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlc1swXSBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRiZXN0TWF0Y2gpIDwgc3RybGVuKCRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJlc3RNYXRjaCA9ICRtYXRjaDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY2hpbGRyZW5DbGVhbiA9IFByZWc6OnJlcGxhY2UoJ3ssXHMqJy5wcmVnX3F1b3RlKCRiZXN0TWF0Y2gpLid9aScsICcnLCAkY2hpbGRyZW4sIC0xLCAkY291bnQpOwogICAgICAgICAgICAgICAgaWYgKDEgIT09ICRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gUHJlZzo6cmVwbGFjZSgneycucHJlZ19xdW90ZSgkYmVzdE1hdGNoKS4nXHMqLD9ccyp9aScsICcnLCAkY2hpbGRyZW5DbGVhbiwgLTEsICRjb3VudCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKDEgIT09ICRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNoaWxkcmVuQ2xlYW4gPSAkY2hpbGRyZW47CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRjaGlsZHJlbkNsZWFuKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiSnNvbk1hbmlwdWxhdG9yOiBcJGNoaWxkcmVuQ2xlYW4gaXMgbm90IGRlZmluZWQuIFBsZWFzZSByZXBvcnQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy9uZXcuIik7CiAgICAgICAgfQoKICAgICAgICAvLyBubyBjaGlsZCBkYXRhIGxlZnQsICRuYW1lIHdhcyB0aGUgb25seSBrZXkgaW4KICAgICAgICBQcmVnOjptYXRjaCgnI157IFxzKj8gKD9QPGNvbnRlbnQ+XFMrLio/KT8gKD9QPHRyYWlsaW5nc3BhY2U+XHMqKSB9JCNzeCcsICRjaGlsZHJlbkNsZWFuLCAkbWF0Y2gpOwogICAgICAgIGlmIChlbXB0eSgkbWF0Y2hbJ2NvbnRlbnQnXSkpIHsKICAgICAgICAgICAgJG5ld2xpbmUgPSAkdGhpcy0+bmV3bGluZTsKICAgICAgICAgICAgJGluZGVudCA9ICR0aGlzLT5pbmRlbnQ7CgogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJG5vZGVSZWdleCwgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCRpbmRlbnQsICRuZXdsaW5lKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ3N0YXJ0J10gLiAneycgLiAkbmV3bGluZSAuICRpbmRlbnQgLiAnfScgLiAkbWF0Y2hlc1snZW5kJ107CiAgICAgICAgICAgIH0sICR0aGlzLT5jb250ZW50cyk7CgogICAgICAgICAgICAvLyB3ZSBoYXZlIGEgc3VibmFtZSwgc28gd2UgcmVzdG9yZSB0aGUgcmVzdCBvZiAkbmFtZQogICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICRjdXJWYWwgPSBqc29uX2RlY29kZSgkY2hpbGRyZW4sIHRydWUpOwogICAgICAgICAgICAgICAgdW5zZXQoJGN1clZhbFskbmFtZV1bJHN1Yk5hbWVdKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRTdWJOb2RlKCRtYWluTm9kZSwgJG5hbWUsICRjdXJWYWxbJG5hbWVdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkdGhhdCA9ICR0aGlzOwogICAgICAgICR0aGlzLT5jb250ZW50cyA9IFByZWc6OnJlcGxhY2VDYWxsYmFjaygkbm9kZVJlZ2V4LCBmdW5jdGlvbiAoJG1hdGNoZXMpIHVzZSAoJHRoYXQsICRuYW1lLCAkc3ViTmFtZSwgJGNoaWxkcmVuQ2xlYW4pIHsKICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkY3VyVmFsID0ganNvbl9kZWNvZGUoJG1hdGNoZXNbJ2NvbnRlbnQnXSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB1bnNldCgkY3VyVmFsWyRuYW1lXVskc3ViTmFtZV0pOwogICAgICAgICAgICAgICAgJGNoaWxkcmVuQ2xlYW4gPSAkdGhhdC0+Zm9ybWF0KCRjdXJWYWwpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ3N0YXJ0J10gLiAkY2hpbGRyZW5DbGVhbiAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICB9LCAkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHBhcmFtIG1peGVkICAkY29udGVudAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRNYWluS2V5KCRrZXksICRjb250ZW50KQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwogICAgICAgICRjb250ZW50ID0gJHRoaXMtPmZvcm1hdCgkY29udGVudCk7CgogICAgICAgIC8vIGtleSBleGlzdHMgYWxyZWFkeQogICAgICAgICRyZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nXig/UDxzdGFydD5ccypce1xzKig/Oig/JnN0cmluZylccyo6XHMqKD8manNvbilccyosXHMqKSo/KScuCiAgICAgICAgICAgICcoP1A8a2V5PicucHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCRrZXkpKS4nXHMqOlxzKig/Jmpzb24pKSg/UDxlbmQ+LiopfXN4JzsKICAgICAgICBpZiAoaXNzZXQoJGRlY29kZWRbJGtleV0pICYmIFByZWc6OmlzTWF0Y2goJHJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaGVzKSkgewogICAgICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICAgICAgaWYgKCFAanNvbl9kZWNvZGUoJ3snLiRtYXRjaGVzWydrZXknXS4nfScpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5jb250ZW50cyA9ICRtYXRjaGVzWydzdGFydCddIC4gSnNvbkZpbGU6OmVuY29kZSgka2V5KS4nOiAnLiRjb250ZW50IC4gJG1hdGNoZXNbJ2VuZCddOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBhcHBlbmQgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZSBhbmQga2VlcCB3aGl0ZXNwYWNlCiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyNbXntcc10oXHMqKVx9JCMnLCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gUHJlZzo6cmVwbGFjZSgKICAgICAgICAgICAgICAgICcjJy4kbWF0Y2hbMV0uJ1x9JCMnLAogICAgICAgICAgICAgICAgYWRkY3NsYXNoZXMoJywnIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgka2V5KS4gJzogJy4gJGNvbnRlbnQgLiAkdGhpcy0+bmV3bGluZSAuICd9JywgJ1xcJCcpLAogICAgICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzCiAgICAgICAgICAgICk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGVuZCBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlCiAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gUHJlZzo6cmVwbGFjZSgKICAgICAgICAgICAgJyNcfSQjJywKICAgICAgICAgICAgYWRkY3NsYXNoZXMoJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuICc6ICcuJGNvbnRlbnQgLiAkdGhpcy0+bmV3bGluZSAuICd9JywgJ1xcJCcpLAogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMKICAgICAgICApOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVNYWluS2V5KCRrZXkpCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CgogICAgICAgIGlmICghYXJyYXlfa2V5X2V4aXN0cygka2V5LCAkZGVjb2RlZCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBrZXkgZXhpc3RzIGFscmVhZHkKICAgICAgICAkcmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+XHMqXHtccyooPzooPyZzdHJpbmcpXHMqOlxzKig/Jmpzb24pXHMqLFxzKikqPyknLgogICAgICAgICAgICAnKD9QPHJlbW92YWw+Jy5wcmVnX3F1b3RlKEpzb25GaWxlOjplbmNvZGUoJGtleSkpLidccyo6XHMqKD8manNvbikpXHMqLD9ccyooP1A8ZW5kPi4qKX1zeCc7CiAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJHJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaGVzKSkgewogICAgICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICAgICAgaWYgKCFAanNvbl9kZWNvZGUoJ3snLiRtYXRjaGVzWydyZW1vdmFsJ10uJ30nKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjaGVjayB0aGF0IHdlIGFyZSBub3QgbGVhdmluZyBhIGRhbmdsaW5nIGNvbW1hIG9uIHRoZSBwcmV2aW91cyBsaW5lIGlmIHRoZSBsYXN0IGxpbmUgd2FzIHJlbW92ZWQKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyMsXHMqJCMnLCAkbWF0Y2hlc1snc3RhcnQnXSkgJiYgUHJlZzo6aXNNYXRjaCgnI15cfSQjJywgJG1hdGNoZXNbJ2VuZCddKSkgewogICAgICAgICAgICAgICAgJG1hdGNoZXNbJ3N0YXJ0J10gPSBydHJpbShQcmVnOjpyZXBsYWNlKCcjLChccyopJCMnLCAnJDEnLCAkbWF0Y2hlc1snc3RhcnQnXSksICR0aGlzLT5pbmRlbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkbWF0Y2hlc1snc3RhcnQnXSAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICAgICAgaWYgKFByZWc6OmlzTWF0Y2goJyNeXHtccypcfVxzKiQjJywgJHRoaXMtPmNvbnRlbnRzKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gIntcbn0iOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVNYWluS2V5SWZFbXB0eSgka2V5KQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoJGtleSwgJGRlY29kZWQpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX2FycmF5KCRkZWNvZGVkWyRrZXldKSAmJiBjb3VudCgkZGVjb2RlZFska2V5XSkgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVNYWluS2V5KCRrZXkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGRhdGEKICAgICAqIEBwYXJhbSBpbnQgICAkZGVwdGgKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmb3JtYXQoJGRhdGEsICRkZXB0aCA9IDApCiAgICB7CiAgICAgICAgaWYgKGlzX2FycmF5KCRkYXRhKSkgewogICAgICAgICAgICByZXNldCgkZGF0YSk7CgogICAgICAgICAgICBpZiAoaXNfbnVtZXJpYyhrZXkoJGRhdGEpKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRhdGEgYXMgJGtleSA9PiAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJGtleV0gPSAkdGhpcy0+Zm9ybWF0KCR2YWwsICRkZXB0aCArIDEpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAnWycuaW1wbG9kZSgnLCAnLCAkZGF0YSkuJ10nOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkb3V0ID0gJ3snIC4gJHRoaXMtPm5ld2xpbmU7CiAgICAgICAgICAgICRlbGVtcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYXRhIGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICAgICAgJGVsZW1zW10gPSBzdHJfcmVwZWF0KCR0aGlzLT5pbmRlbnQsICRkZXB0aCArIDIpIC4gSnNvbkZpbGU6OmVuY29kZSgka2V5KS4gJzogJy4kdGhpcy0+Zm9ybWF0KCR2YWwsICRkZXB0aCArIDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG91dCAuIGltcGxvZGUoJywnLiR0aGlzLT5uZXdsaW5lLCAkZWxlbXMpIC4gJHRoaXMtPm5ld2xpbmUgLiBzdHJfcmVwZWF0KCR0aGlzLT5pbmRlbnQsICRkZXB0aCArIDEpIC4gJ30nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEpzb25GaWxlOjplbmNvZGUoJGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXRlY3RJbmRlbnRpbmcoKQogICAgewogICAgICAgIGlmIChQcmVnOjppc01hdGNoKCd7XihbIFx0XSspIn1tJywgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRlbnQgPSAkbWF0Y2hbMV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmluZGVudCA9ICcgICAgJzsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSnNvbjsKCnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogRm9ybWF0cyBqc29uIHN0cmluZ3MgdXNlZCBmb3IgcGhwIDwgNS40IGJlY2F1c2UgdGhlIGpzb25fZW5jb2RlIGRvZXNuJ3QKICogc3VwcG9ydHMgdGhlIGZsYWdzIEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBKU09OX1BSRVRUWV9QUklOVCB8IEpTT05fVU5FU0NBUEVEX1VOSUNPREUKICogaW4gdGhlc2UgdmVyc2lvbnMKICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNoaXYgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSnNvbkZvcm1hdHRlcgp7CiAgICAvKioKICAgICAqIFRoaXMgY29kZSBpcyBiYXNlZCBvbiB0aGUgZnVuY3Rpb24gZm91bmQgYXQ6CiAgICAgKiAgaHR0cDovL3JlY3Vyc2l2ZS1kZXNpZ24uY29tL2Jsb2cvMjAwOC8wMy8xMS9mb3JtYXQtanNvbi13aXRoLXBocC8KICAgICAqCiAgICAgKiBPcmlnaW5hbGx5IGxpY2Vuc2VkIHVuZGVyIE1JVCBieSBEYXZlIFBlcnJldHQgPG1haWxAcmVjdXJzaXZlLWRlc2lnbi5jb20+CiAgICAgKgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRqc29uCiAgICAgKiBAcGFyYW0gIGJvb2wgICAkdW5lc2NhcGVVbmljb2RlIFVuIGVzY2FwZSB1bmljb2RlCiAgICAgKiBAcGFyYW0gIGJvb2wgICAkdW5lc2NhcGVTbGFzaGVzIFVuIGVzY2FwZSBzbGFzaGVzCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdCgkanNvbiwgJHVuZXNjYXBlVW5pY29kZSwgJHVuZXNjYXBlU2xhc2hlcykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJyc7CiAgICAgICAgJHBvcyA9IDA7CiAgICAgICAgJHN0ckxlbiA9IHN0cmxlbigkanNvbik7CiAgICAgICAgJGluZGVudFN0ciA9ICcgICAgJzsKICAgICAgICAkbmV3TGluZSA9ICJcbiI7CiAgICAgICAgJG91dE9mUXVvdGVzID0gdHJ1ZTsKICAgICAgICAkYnVmZmVyID0gJyc7CiAgICAgICAgJG5vZXNjYXBlID0gdHJ1ZTsKCiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJHN0ckxlbjsgJGkrKykgewogICAgICAgICAgICAvLyBHcmFiIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCiAgICAgICAgICAgICRjaGFyID0gc3Vic3RyKCRqc29uLCAkaSwgMSk7CgogICAgICAgICAgICAvLyBBcmUgd2UgaW5zaWRlIGEgcXVvdGVkIHN0cmluZz8KICAgICAgICAgICAgaWYgKCciJyA9PT0gJGNoYXIgJiYgJG5vZXNjYXBlKSB7CiAgICAgICAgICAgICAgICAkb3V0T2ZRdW90ZXMgPSAhJG91dE9mUXVvdGVzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRvdXRPZlF1b3RlcykgewogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICRub2VzY2FwZSA9ICdcXCcgPT09ICRjaGFyID8gISRub2VzY2FwZSA6IHRydWU7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJycgIT09ICRidWZmZXIpIHsKICAgICAgICAgICAgICAgIGlmICgkdW5lc2NhcGVTbGFzaGVzKSB7CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9IHN0cl9yZXBsYWNlKCdcXC8nLCAnLycsICRidWZmZXIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkdW5lc2NhcGVVbmljb2RlICYmIGZ1bmN0aW9uX2V4aXN0cygnbWJfY29udmVydF9lbmNvZGluZycpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjkzNDU2My9ob3ctdG8tZGVjb2RlLXVuaWNvZGUtZXNjYXBlLXNlcXVlbmNlcy1saWtlLXUwMGVkLXRvLXByb3Blci11dGYtOC1lbmNvZGVkLWNoYQogICAgICAgICAgICAgICAgICAgICRidWZmZXIgPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJy8oXFxcXCspdShbMC05YS1mXXs0fSkvaScsIGZ1bmN0aW9uICgkbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGwgPSBzdHJsZW4oJG1hdGNoWzFdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbCAlIDIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlID0gaGV4ZGVjKCRtYXRjaFsyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAweEQ4MDAuLjB4REZGRiBkZW5vdGVzIFVURi0xNiBzdXJyb2dhdGUgcGFpciB3aGljaCB3b24ndCBiZSB1bmVzY2FwZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzc1MTAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgweEQ4MDAgPD0gJGNvZGUgJiYgMHhERkZGID49ICRjb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGVhdCgnXFwnLCAkbCAtIDEpIC4gbWJfY29udmVydF9lbmNvZGluZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrKCdIKicsICRtYXRjaFsyXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1VURi04JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVUNTLTJCRScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkbWF0Y2hbMF07CiAgICAgICAgICAgICAgICAgICAgfSwgJGJ1ZmZlcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkYnVmZmVyLiRjaGFyOwogICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICcnOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgnOicgPT09ICRjaGFyKSB7CiAgICAgICAgICAgICAgICAvLyBBZGQgYSBzcGFjZSBhZnRlciB0aGUgOiBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgICRjaGFyIC49ICcgJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCd9JyA9PT0gJGNoYXIgfHwgJ10nID09PSAkY2hhcikgewogICAgICAgICAgICAgICAgJHBvcy0tOwogICAgICAgICAgICAgICAgJHByZXZDaGFyID0gc3Vic3RyKCRqc29uLCAkaSAtIDEsIDEpOwoKICAgICAgICAgICAgICAgIGlmICgneycgIT09ICRwcmV2Q2hhciAmJiAnWycgIT09ICRwcmV2Q2hhcikgewogICAgICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgY2hhcmFjdGVyIGlzIHRoZSBlbmQgb2YgYW4gZWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAvLyBvdXRwdXQgYSBuZXcgbGluZSBhbmQgaW5kZW50IHRoZSBuZXh0IGxpbmUKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICRuZXdMaW5lOwogICAgICAgICAgICAgICAgICAgIGZvciAoJGogPSAwOyAkaiA8ICRwb3M7ICRqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkaW5kZW50U3RyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29sbGFwc2UgZW1wdHkge30gYW5kIFtdCiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCA9IHJ0cmltKCRyZXN1bHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzdWx0IC49ICRjaGFyOwoKICAgICAgICAgICAgLy8gSWYgdGhlIGxhc3QgY2hhcmFjdGVyIHdhcyB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQsCiAgICAgICAgICAgIC8vIG91dHB1dCBhIG5ldyBsaW5lIGFuZCBpbmRlbnQgdGhlIG5leHQgbGluZQogICAgICAgICAgICBpZiAoJywnID09PSAkY2hhciB8fCAneycgPT09ICRjaGFyIHx8ICdbJyA9PT0gJGNoYXIpIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgLj0gJG5ld0xpbmU7CgogICAgICAgICAgICAgICAgaWYgKCd7JyA9PT0gJGNoYXIgfHwgJ1snID09PSAkY2hhcikgewogICAgICAgICAgICAgICAgICAgICRwb3MrKzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKCRqID0gMDsgJGogPCAkcG9zOyAkaisrKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkaW5kZW50U3RyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxKc29uOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIEpzb25TY2hlbWFcVmFsaWRhdG9yOwp1c2UgU2VsZFxKc29uTGludFxKc29uUGFyc2VyOwp1c2UgU2VsZFxKc29uTGludFxQYXJzaW5nRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CgovKioKICogUmVhZHMvd3JpdGVzIGpzb24gZmlsZXMuCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaGl2IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEpzb25GaWxlCnsKICAgIGNvbnN0IExBWF9TQ0hFTUEgPSAxOwogICAgY29uc3QgU1RSSUNUX1NDSEVNQSA9IDI7CgogICAgY29uc3QgSlNPTl9VTkVTQ0FQRURfU0xBU0hFUyA9IDY0OwogICAgY29uc3QgSlNPTl9QUkVUVFlfUFJJTlQgPSAxMjg7CiAgICBjb25zdCBKU09OX1VORVNDQVBFRF9VTklDT0RFID0gMjU2OwoKICAgIGNvbnN0IENPTVBPU0VSX1NDSEVNQV9QQVRIID0gJy8uLi8uLi8uLi9yZXMvY29tcG9zZXItc2NoZW1hLmpzb24nOwoKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkcGF0aDsKICAgIC8qKiBAdmFyID9IdHRwRG93bmxvYWRlciAqLwogICAgcHJpdmF0ZSAkaHR0cERvd25sb2FkZXI7CiAgICAvKiogQHZhciA/SU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMganNvbiBmaWxlIHJlYWRlci9wYXJzZXIuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRwYXRoICAgICAgICAgICBwYXRoIHRvIGEgbG9ja2ZpbGUKICAgICAqIEBwYXJhbSAgP0h0dHBEb3dubG9hZGVyICAgICAgICAgICAkaHR0cERvd25sb2FkZXIgcmVxdWlyZWQgZm9yIGxvYWRpbmcgaHR0cC9odHRwcyBqc29uIGZpbGVzCiAgICAgKiBAcGFyYW0gID9JT0ludGVyZmFjZSAgICAgICAgICAgICAgJGlvCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRwYXRoLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIgPSBudWxsLCBJT0ludGVyZmFjZSAkaW8gPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5wYXRoID0gJHBhdGg7CgogICAgICAgIGlmIChudWxsID09PSAkaHR0cERvd25sb2FkZXIgJiYgUHJlZzo6aXNNYXRjaCgne15odHRwcz86Ly99aScsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignaHR0cCB1cmxzIHJlcXVpcmUgYSBIdHRwRG93bmxvYWRlciBpbnN0YW5jZSB0byBiZSBwYXNzZWQnKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciBqc29uIGZpbGUgZXhpc3RzLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhpc3RzKCkKICAgIHsKICAgICAgICByZXR1cm4gaXNfZmlsZSgkdGhpcy0+cGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkcyBqc29uIGZpbGUuCiAgICAgKgogICAgICogQHRocm93cyBQYXJzaW5nRXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWFkKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmh0dHBEb3dubG9hZGVyKSB7CiAgICAgICAgICAgICAgICAkanNvbiA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCR0aGlzLT5wYXRoKS0+Z2V0Qm9keSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pbyAmJiAkdGhpcy0+aW8tPmlzRGVidWcoKSkgewogICAgICAgICAgICAgICAgICAgICRyZWFscGF0aEluZm8gPSAnJzsKICAgICAgICAgICAgICAgICAgICAkcmVhbHBhdGggPSByZWFscGF0aCgkdGhpcy0+cGF0aCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkcmVhbHBhdGggJiYgJHJlYWxwYXRoICE9PSAkdGhpcy0+cGF0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVhbHBhdGhJbmZvID0gJyAoJyAuICRyZWFscGF0aCAuICcpJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdSZWFkaW5nICcgLiAkdGhpcy0+cGF0aCAuICRyZWFscGF0aEluZm8pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGpzb24gPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+cGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCksIDAsICRlKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHJlYWQgJy4kdGhpcy0+cGF0aC4iXG5cbiIuJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RhdGljOjpwYXJzZUpzb24oJGpzb24sICR0aGlzLT5wYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyBqc29uIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtICBtaXhlZFtdICAgICAgICAgICAgICAgICAgICAgICAgICAkaGFzaCAgICB3cml0ZXMgaGFzaCBpbnRvIGpzb24gZmlsZQogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG9wdGlvbnMganNvbl9lbmNvZGUgb3B0aW9ucyAoZGVmYXVsdHMgdG8gSlNPTl9VTkVTQ0FQRURfU0xBU0hFUyB8IEpTT05fUFJFVFRZX1BSSU5UIHwgSlNPTl9VTkVTQ0FQRURfVU5JQ09ERSkKICAgICAqIEB0aHJvd3MgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbnxcRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKGFycmF5ICRoYXNoLCAkb3B0aW9ucyA9IDQ0OCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnBhdGggPT09ICdwaHA6Ly9tZW1vcnknKSB7CiAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCR0aGlzLT5wYXRoLCBzdGF0aWM6OmVuY29kZSgkaGFzaCwgJG9wdGlvbnMpKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRkaXIgPSBkaXJuYW1lKCR0aGlzLT5wYXRoKTsKICAgICAgICBpZiAoIWlzX2RpcigkZGlyKSkgewogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGRpcikpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIHJlYWxwYXRoKCRkaXIpLicgZXhpc3RzIGFuZCBpcyBub3QgYSBkaXJlY3RvcnkuJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIUBta2RpcigkZGlyLCAwNzc3LCB0cnVlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJGRpci4nIGRvZXMgbm90IGV4aXN0IGFuZCBjb3VsZCBub3QgYmUgY3JlYXRlZC4nCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcmV0cmllcyA9IDM7CiAgICAgICAgd2hpbGUgKCRyZXRyaWVzLS0pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICR0aGlzLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR0aGlzLT5wYXRoLCBzdGF0aWM6OmVuY29kZSgkaGFzaCwgJG9wdGlvbnMpLiAoJG9wdGlvbnMgJiBzZWxmOjpKU09OX1BSRVRUWV9QUklOVCA/ICJcbiIgOiAnJykpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICgkcmV0cmllcyA+IDApIHsKICAgICAgICAgICAgICAgICAgICB1c2xlZXAoNTAwMDAwKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1vZGlmeSBmaWxlIHByb3BlcnRpZXMgb25seSBpZiBjb250ZW50IG1vZGlmaWVkCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudAogICAgICogQHJldHVybiBpbnR8ZmFsc2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCRwYXRoLCAkY29udGVudCkKICAgIHsKICAgICAgICAkY3VycmVudENvbnRlbnQgPSBAZmlsZV9nZXRfY29udGVudHMoJHBhdGgpOwogICAgICAgIGlmICghJGN1cnJlbnRDb250ZW50IHx8ICgkY3VycmVudENvbnRlbnQgIT0gJGNvbnRlbnQpKSB7CiAgICAgICAgICAgIHJldHVybiBmaWxlX3B1dF9jb250ZW50cygkcGF0aCwgJGNvbnRlbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIHNjaGVtYSBvZiB0aGUgY3VycmVudCBqc29uIGZpbGUgYWNjb3JkaW5nIHRvIGNvbXBvc2VyLXNjaGVtYS5qc29uIHJ1bGVzCiAgICAgKgogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICAgICAgICAkc2NoZW1hICAgICBhIEpzb25GaWxlOjoqX1NDSEVNQSBjb25zdGFudAogICAgICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICAgICAgICAgICAkc2NoZW1hRmlsZSBhIHBhdGggdG8gdGhlIHNjaGVtYSBmaWxlCiAgICAgKiBAdGhyb3dzIEpzb25WYWxpZGF0aW9uRXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbCAgICAgICAgICAgICAgICAgICAgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZVNjaGVtYSgkc2NoZW1hID0gc2VsZjo6U1RSSUNUX1NDSEVNQSwgJHNjaGVtYUZpbGUgPSBudWxsKQogICAgewogICAgICAgICRjb250ZW50ID0gZmlsZV9nZXRfY29udGVudHMoJHRoaXMtPnBhdGgpOwogICAgICAgICRkYXRhID0ganNvbl9kZWNvZGUoJGNvbnRlbnQpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJGRhdGEgJiYgJ251bGwnICE9PSAkY29udGVudCkgewogICAgICAgICAgICBzZWxmOjp2YWxpZGF0ZVN5bnRheCgkY29udGVudCwgJHRoaXMtPnBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJGlzQ29tcG9zZXJTY2hlbWFGaWxlID0gZmFsc2U7CiAgICAgICAgaWYgKG51bGwgPT09ICRzY2hlbWFGaWxlKSB7CiAgICAgICAgICAgICRpc0NvbXBvc2VyU2NoZW1hRmlsZSA9IHRydWU7CiAgICAgICAgICAgICRzY2hlbWFGaWxlID0gX19ESVJfXyAuIHNlbGY6OkNPTVBPU0VSX1NDSEVNQV9QQVRIOwogICAgICAgIH0KCiAgICAgICAgLy8gUHJlcGVuZCB3aXRoIGZpbGU6Ly8gb25seSB3aGVuIG5vdCB1c2luZyBhIHNwZWNpYWwgc2NoZW1hIGFscmVhZHkgKGUuZy4gaW4gdGhlIHBoYXIpCiAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJHNjaGVtYUZpbGUsICc6Ly8nKSkgewogICAgICAgICAgICAkc2NoZW1hRmlsZSA9ICdmaWxlOi8vJyAuICRzY2hlbWFGaWxlOwogICAgICAgIH0KCiAgICAgICAgJHNjaGVtYURhdGEgPSAob2JqZWN0KSBhcnJheSgnJHJlZicgPT4gJHNjaGVtYUZpbGUpOwoKICAgICAgICBpZiAoJHNjaGVtYSA9PT0gc2VsZjo6TEFYX1NDSEVNQSkgewogICAgICAgICAgICAkc2NoZW1hRGF0YS0+YWRkaXRpb25hbFByb3BlcnRpZXMgPSB0cnVlOwogICAgICAgICAgICAkc2NoZW1hRGF0YS0+cmVxdWlyZWQgPSBhcnJheSgpOwogICAgICAgIH0gZWxzZWlmICgkc2NoZW1hID09PSBzZWxmOjpTVFJJQ1RfU0NIRU1BICYmICRpc0NvbXBvc2VyU2NoZW1hRmlsZSkgewogICAgICAgICAgICAkc2NoZW1hRGF0YS0+YWRkaXRpb25hbFByb3BlcnRpZXMgPSBmYWxzZTsKICAgICAgICAgICAgJHNjaGVtYURhdGEtPnJlcXVpcmVkID0gYXJyYXkoJ25hbWUnLCAnZGVzY3JpcHRpb24nKTsKICAgICAgICB9CgogICAgICAgICR2YWxpZGF0b3IgPSBuZXcgVmFsaWRhdG9yKCk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJGRhdGEsICRzY2hlbWFEYXRhKTsKCiAgICAgICAgaWYgKCEkdmFsaWRhdG9yLT5pc1ZhbGlkKCkpIHsKICAgICAgICAgICAgJGVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKChhcnJheSkgJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkgYXMgJGVycm9yKSB7CiAgICAgICAgICAgICAgICAkZXJyb3JzW10gPSAoJGVycm9yWydwcm9wZXJ0eSddID8gJGVycm9yWydwcm9wZXJ0eSddLicgOiAnIDogJycpLiRlcnJvclsnbWVzc2FnZSddOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbignIicuJHRoaXMtPnBhdGguJyIgZG9lcyBub3QgbWF0Y2ggdGhlIGV4cGVjdGVkIEpTT04gc2NoZW1hJywgJGVycm9ycyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuY29kZXMgYW4gYXJyYXkgaW50byAob3B0aW9uYWxseSBwcmV0dHktcHJpbnRlZCkgSlNPTgogICAgICoKICAgICAqIEBwYXJhbSAgbWl4ZWQgICRkYXRhICAgIERhdGEgdG8gZW5jb2RlIGludG8gYSBmb3JtYXR0ZWQgSlNPTiBzdHJpbmcKICAgICAqIEBwYXJhbSAgaW50ICAgICRvcHRpb25zIGpzb25fZW5jb2RlIG9wdGlvbnMgKGRlZmF1bHRzIHRvIEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBKU09OX1BSRVRUWV9QUklOVCB8IEpTT05fVU5FU0NBUEVEX1VOSUNPREUpCiAgICAgKiBAcmV0dXJuIHN0cmluZyBFbmNvZGVkIGpzb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlbmNvZGUoJGRhdGEsICRvcHRpb25zID0gNDQ4KQogICAgewogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA1MDQwMCkgewogICAgICAgICAgICAkanNvbiA9IGpzb25fZW5jb2RlKCRkYXRhLCAkb3B0aW9ucyk7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGpzb24pIHsKICAgICAgICAgICAgICAgIHNlbGY6OnRocm93RW5jb2RlRXJyb3IoanNvbl9sYXN0X2Vycm9yKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAgY29tcGFjdCBicmFja2V0cyB0byBmb2xsb3cgcmVjZW50IHBocCB2ZXJzaW9ucwogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDQyOCB8fCAoUEhQX1ZFUlNJT05fSUQgPj0gNTA1MDAgJiYgUEhQX1ZFUlNJT05fSUQgPCA1MDUxMikgfHwgKGRlZmluZWQoJ0pTT05fQ19WRVJTSU9OJykgJiYgdmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oJ2pzb24nKSwgJzEuMy42JywgJzwnKSkpIHsKICAgICAgICAgICAgICAgICRqc29uID0gUHJlZzo6cmVwbGFjZSgnL1xbXHMrXF0vJywgJ1tdJywgJGpzb24pOwogICAgICAgICAgICAgICAgJGpzb24gPSBQcmVnOjpyZXBsYWNlKCcvXHtccytcfS8nLCAne30nLCAkanNvbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkanNvbjsKICAgICAgICB9CgogICAgICAgICRqc29uID0ganNvbl9lbmNvZGUoJGRhdGEpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJGpzb24pIHsKICAgICAgICAgICAgc2VsZjo6dGhyb3dFbmNvZGVFcnJvcihqc29uX2xhc3RfZXJyb3IoKSk7CiAgICAgICAgfQoKICAgICAgICAkcHJldHR5UHJpbnQgPSAoYm9vbCkgKCRvcHRpb25zICYgc2VsZjo6SlNPTl9QUkVUVFlfUFJJTlQpOwogICAgICAgICR1bmVzY2FwZVVuaWNvZGUgPSAoYm9vbCkgKCRvcHRpb25zICYgc2VsZjo6SlNPTl9VTkVTQ0FQRURfVU5JQ09ERSk7CiAgICAgICAgJHVuZXNjYXBlU2xhc2hlcyA9IChib29sKSAoJG9wdGlvbnMgJiBzZWxmOjpKU09OX1VORVNDQVBFRF9TTEFTSEVTKTsKCiAgICAgICAgaWYgKCEkcHJldHR5UHJpbnQgJiYgISR1bmVzY2FwZVVuaWNvZGUgJiYgISR1bmVzY2FwZVNsYXNoZXMpIHsKICAgICAgICAgICAgcmV0dXJuICRqc29uOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEpzb25Gb3JtYXR0ZXI6OmZvcm1hdCgkanNvbiwgJHVuZXNjYXBlVW5pY29kZSwgJHVuZXNjYXBlU2xhc2hlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaHJvd3MgYW4gZXhjZXB0aW9uIGFjY29yZGluZyB0byBhIGdpdmVuIGNvZGUgd2l0aCBhIGN1c3RvbWl6ZWQgbWVzc2FnZQogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgICAgICAgJGNvZGUgcmV0dXJuIGNvZGUgb2YganNvbl9sYXN0X2Vycm9yIGZ1bmN0aW9uCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdGhyb3dFbmNvZGVFcnJvcigkY29kZSkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRjb2RlKSB7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9ERVBUSDoKICAgICAgICAgICAgICAgICRtc2cgPSAnTWF4aW11bSBzdGFjayBkZXB0aCBleGNlZWRlZCc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBKU09OX0VSUk9SX1NUQVRFX01JU01BVENIOgogICAgICAgICAgICAgICAgJG1zZyA9ICdVbmRlcmZsb3cgb3IgdGhlIG1vZGVzIG1pc21hdGNoJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfQ1RSTF9DSEFSOgogICAgICAgICAgICAgICAgJG1zZyA9ICdVbmV4cGVjdGVkIGNvbnRyb2wgY2hhcmFjdGVyIGZvdW5kJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfVVRGODoKICAgICAgICAgICAgICAgICRtc2cgPSAnTWFsZm9ybWVkIFVURi04IGNoYXJhY3RlcnMsIHBvc3NpYmx5IGluY29ycmVjdGx5IGVuY29kZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAkbXNnID0gJ1Vua25vd24gZXJyb3InOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdKU09OIGVuY29kaW5nIGZhaWxlZDogJy4kbXNnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBqc29uIHN0cmluZyBhbmQgcmV0dXJucyBoYXNoLgogICAgICoKICAgICAqIEBwYXJhbSA/c3RyaW5nICRqc29uIGpzb24gc3RyaW5nCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlIHRoZSBqc29uIGZpbGUKICAgICAqCiAgICAgKiBAdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24KICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZUpzb24oJGpzb24sICRmaWxlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGpzb24pIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICRkYXRhID0ganNvbl9kZWNvZGUoJGpzb24sIHRydWUpOwogICAgICAgIGlmIChudWxsID09PSAkZGF0YSAmJiBKU09OX0VSUk9SX05PTkUgIT09IGpzb25fbGFzdF9lcnJvcigpKSB7CiAgICAgICAgICAgIHNlbGY6OnZhbGlkYXRlU3ludGF4KCRqc29uLCAkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIHN5bnRheCBvZiBhIEpTT04gc3RyaW5nCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRqc29uCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJGZpbGUKICAgICAqIEB0aHJvd3MgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgogICAgICogQHRocm93cyBQYXJzaW5nRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2wgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdmFsaWRhdGVTeW50YXgoJGpzb24sICRmaWxlID0gbnVsbCkKICAgIHsKICAgICAgICAkcGFyc2VyID0gbmV3IEpzb25QYXJzZXIoKTsKICAgICAgICAkcmVzdWx0ID0gJHBhcnNlci0+bGludCgkanNvbik7CiAgICAgICAgaWYgKG51bGwgPT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgaWYgKGRlZmluZWQoJ0pTT05fRVJST1JfVVRGOCcpICYmIEpTT05fRVJST1JfVVRGOCA9PT0ganNvbl9sYXN0X2Vycm9yKCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCciJy4kZmlsZS4nIiBpcyBub3QgVVRGLTgsIGNvdWxkIG5vdCBwYXJzZSBhcyBKU09OJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oJyInLiRmaWxlLiciIGRvZXMgbm90IGNvbnRhaW4gdmFsaWQgSlNPTicuIlxuIi4kcmVzdWx0LT5nZXRNZXNzYWdlKCksICRyZXN1bHQtPmdldERldGFpbHMoKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGxhdGZvcm07Cgp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGVjdXRhYmxlRmluZGVyOwoKY2xhc3MgSGh2bURldGVjdG9yCnsKICAgIC8qKiBAdmFyIHN0cmluZ3xmYWxzZXxudWxsICovCiAgICBwcml2YXRlIHN0YXRpYyAkaGh2bVZlcnNpb24gPSBudWxsOwogICAgLyoqIEB2YXIgP0V4ZWN1dGFibGVGaW5kZXIgKi8KICAgIHByaXZhdGUgJGV4ZWN1dGFibGVGaW5kZXI7CiAgICAvKiogQHZhciA/UHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcml2YXRlICRwcm9jZXNzRXhlY3V0b3I7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEV4ZWN1dGFibGVGaW5kZXIgJGV4ZWN1dGFibGVGaW5kZXIgPSBudWxsLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3NFeGVjdXRvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGFibGVGaW5kZXIgPSAkZXhlY3V0YWJsZUZpbmRlcjsKICAgICAgICAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yID0gJHByb2Nlc3NFeGVjdXRvcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXQoKQogICAgewogICAgICAgIHNlbGY6OiRoaHZtVmVyc2lvbiA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJzaW9uKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gc2VsZjo6JGhodm1WZXJzaW9uKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokaGh2bVZlcnNpb24gPzogbnVsbDsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRoaHZtVmVyc2lvbiA9IGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpID8gSEhWTV9WRVJTSU9OIDogbnVsbDsKICAgICAgICBpZiAoc2VsZjo6JGhodm1WZXJzaW9uID09PSBudWxsICYmICFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgc2VsZjo6JGhodm1WZXJzaW9uID0gZmFsc2U7CiAgICAgICAgICAgICR0aGlzLT5leGVjdXRhYmxlRmluZGVyID0gJHRoaXMtPmV4ZWN1dGFibGVGaW5kZXIgPzogbmV3IEV4ZWN1dGFibGVGaW5kZXIoKTsKICAgICAgICAgICAgJGhodm1QYXRoID0gJHRoaXMtPmV4ZWN1dGFibGVGaW5kZXItPmZpbmQoJ2hodm0nKTsKICAgICAgICAgICAgaWYgKCRoaHZtUGF0aCAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3NFeGVjdXRvciA9ICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigpOwogICAgICAgICAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPnByb2Nlc3NFeGVjdXRvci0+ZXhlY3V0ZSgKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkaGh2bVBhdGgpLgogICAgICAgICAgICAgICAgICAgICcgLS1waHAgLWQgaGh2bS5qaXQ9MCAtciAiZWNobyBISFZNX1ZFUlNJT047IiAyPi9kZXYvbnVsbCcsCiAgICAgICAgICAgICAgICAgICAgc2VsZjo6JGhodm1WZXJzaW9uCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCRleGl0Q29kZSAhPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHNlbGY6OiRoaHZtVmVyc2lvbiA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGhodm1WZXJzaW9uID86IG51bGw7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGxhdGZvcm07Cgp1c2UgQ29tcG9zZXJcUGNyZVxQcmVnOwoKLyoqCiAqIEBhdXRob3IgTGFycyBTdHJvam55IDxsYXJzQHN0cm9qbnkubmV0PgogKi8KY2xhc3MgVmVyc2lvbgp7CiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJG9wZW5zc2xWZXJzaW9uCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICRpc0ZpcHMKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZU9wZW5zc2woJG9wZW5zc2xWZXJzaW9uLCAmJGlzRmlwcykKICAgIHsKICAgICAgICAkaXNGaXBzID0gZmFsc2U7CgogICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgnL14oPzx2ZXJzaW9uPlswLTkuXSspKD88cGF0Y2g+W2Etel17MCwyfSk/KD88c3VmZml4Pig/Oi0/KD86ZGV2fHByZXxhbHBoYXxiZXRhfHJjfGZpcHMpW1xkXSopKik/KD88Z2FyYmFnZT4tXHcrKT8kLycsICRvcGVuc3NsVmVyc2lvbiwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGlzRmlwcyA9IHN0cnBvcygkbWF0Y2hlc1snc3VmZml4J10sICdmaXBzJykgIT09IGZhbHNlOwogICAgICAgICRzdWZmaXggPSBzdHJ0cignLScubHRyaW0oJG1hdGNoZXNbJ3N1ZmZpeCddLCAnLScpLCBhcnJheSgnLWZpcHMnID0+ICcnLCAnLXByZScgPT4gJy1hbHBoYScpKTsKICAgICAgICAkcGF0Y2ggPSBzZWxmOjpjb252ZXJ0QWxwaGFWZXJzaW9uVG9JbnRWZXJzaW9uKCRtYXRjaGVzWydwYXRjaCddKTsKCiAgICAgICAgcmV0dXJuIHJ0cmltKCRtYXRjaGVzWyd2ZXJzaW9uJ10uJy4nLiRwYXRjaC4kc3VmZml4LCAnLScpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkbGlianBlZ1ZlcnNpb24KICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZUxpYmpwZWcoJGxpYmpwZWdWZXJzaW9uKQogICAgewogICAgICAgIGlmICghUHJlZzo6aXNNYXRjaCgnL14oPzxtYWpvcj5cZCspKD88bWlub3I+W2Etel0qKSQvJywgJGxpYmpwZWdWZXJzaW9uLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ21ham9yJ10uJy4nLnNlbGY6OmNvbnZlcnRBbHBoYVZlcnNpb25Ub0ludFZlcnNpb24oJG1hdGNoZXNbJ21pbm9yJ10pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkem9uZWluZm9WZXJzaW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGFyc2Vab25laW5mb1ZlcnNpb24oJHpvbmVpbmZvVmVyc2lvbikKICAgIHsKICAgICAgICBpZiAoIVByZWc6OmlzTWF0Y2goJy9eKD88eWVhcj5cZHs0fSkoPzxyZXZpc2lvbj5bYS16XSopJC8nLCAkem9uZWluZm9WZXJzaW9uLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ3llYXInXS4nLicuc2VsZjo6Y29udmVydEFscGhhVmVyc2lvblRvSW50VmVyc2lvbigkbWF0Y2hlc1sncmV2aXNpb24nXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiAiIiA9PiAwLCAiYSIgPT4gMSwgInpnIiA9PiAzMwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRhbHBoYQogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY29udmVydEFscGhhVmVyc2lvblRvSW50VmVyc2lvbigkYWxwaGEpCiAgICB7CiAgICAgICAgcmV0dXJuIHN0cmxlbigkYWxwaGEpICogKC1vcmQoJ2EnKSArIDEpICsgYXJyYXlfc3VtKGFycmF5X21hcCgnb3JkJywgc3RyX3NwbGl0KCRhbHBoYSkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgaW50ICAgICR2ZXJzaW9uSWQKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29udmVydExpYnhwbVZlcnNpb25JZCgkdmVyc2lvbklkKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb252ZXJ0VmVyc2lvbklkKCR2ZXJzaW9uSWQsIDEwMCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludCAgICAkdmVyc2lvbklkCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbnZlcnRPcGVubGRhcFZlcnNpb25JZCgkdmVyc2lvbklkKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb252ZXJ0VmVyc2lvbklkKCR2ZXJzaW9uSWQsIDEwMCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICR2ZXJzaW9uSWQKICAgICAqIEBwYXJhbSBpbnQgJGJhc2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0VmVyc2lvbklkKCR2ZXJzaW9uSWQsICRiYXNlKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKAogICAgICAgICAgICAnJWQuJWQuJWQnLAogICAgICAgICAgICAkdmVyc2lvbklkIC8gKCRiYXNlICogJGJhc2UpLAogICAgICAgICAgICAoaW50KSAoJHZlcnNpb25JZCAvICRiYXNlKSAlICRiYXNlLAogICAgICAgICAgICAkdmVyc2lvbklkICUgJGJhc2UKICAgICAgICApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsYXRmb3JtOwoKY2xhc3MgUnVudGltZQp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN0YW50CiAgICAgKiBAcGFyYW0gY2xhc3Mtc3RyaW5nICRjbGFzcwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29uc3RhbnQoJGNvbnN0YW50LCAkY2xhc3MgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBkZWZpbmVkKGx0cmltKCRjbGFzcy4nOjonLiRjb25zdGFudCwgJzonKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25zdGFudAogICAgICogQHBhcmFtIGNsYXNzLXN0cmluZyAkY2xhc3MKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25zdGFudCgkY29uc3RhbnQsICRjbGFzcyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnN0YW50KGx0cmltKCRjbGFzcy4nOjonLiRjb25zdGFudCwgJzonKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmbgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzRnVuY3Rpb24oJGZuKQogICAgewogICAgICAgIHJldHVybiBmdW5jdGlvbl9leGlzdHMoJGZuKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkY2FsbGFibGUKICAgICAqIEBwYXJhbSBtaXhlZFtdICRhcmd1bWVudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnZva2UoJGNhbGxhYmxlLCBhcnJheSAkYXJndW1lbnRzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJGNhbGxhYmxlLCAkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBjbGFzcy1zdHJpbmcgJGNsYXNzCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNDbGFzcygkY2xhc3MpCiAgICB7CiAgICAgICAgcmV0dXJuIGNsYXNzX2V4aXN0cygkY2xhc3MsIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBjbGFzcy1zdHJpbmcgJGNsYXNzCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkYXJndW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QKICAgICAqIEB0aHJvd3MgXFJlZmxlY3Rpb25FeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbnN0cnVjdCgkY2xhc3MsIGFycmF5ICRhcmd1bWVudHMgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmIChlbXB0eSgkYXJndW1lbnRzKSkgewogICAgICAgICAgICByZXR1cm4gbmV3ICRjbGFzczsKICAgICAgICB9CgogICAgICAgICRyZWZsID0gbmV3IFxSZWZsZWN0aW9uQ2xhc3MoJGNsYXNzKTsKCiAgICAgICAgcmV0dXJuICRyZWZsLT5uZXdJbnN0YW5jZUFyZ3MoJGFyZ3VtZW50cyk7CiAgICB9CgogICAgLyoqIEByZXR1cm4gc3RyaW5nW10gKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHRlbnNpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gZ2V0X2xvYWRlZF9leHRlbnNpb25zKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRleHRlbnNpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uVmVyc2lvbigkZXh0ZW5zaW9uKQogICAgewogICAgICAgIHJldHVybiBwaHB2ZXJzaW9uKCRleHRlbnNpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZXh0ZW5zaW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEB0aHJvd3MgXFJlZmxlY3Rpb25FeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4dGVuc2lvbkluZm8oJGV4dGVuc2lvbikKICAgIHsKICAgICAgICAkcmVmbGVjdG9yID0gbmV3IFxSZWZsZWN0aW9uRXh0ZW5zaW9uKCRleHRlbnNpb24pOwoKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgICRyZWZsZWN0b3ItPmluZm8oKTsKCiAgICAgICAgcmV0dXJuIG9iX2dldF9jbGVhbigpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEBwYXJhbSBzdHJpbmcgJGZpbGUKICogQHJldHVybiA/XENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyCiAqLwpmdW5jdGlvbiBpbmNsdWRlSWZFeGlzdHMoJGZpbGUpCnsKICAgIHJldHVybiBmaWxlX2V4aXN0cygkZmlsZSkgPyBpbmNsdWRlICRmaWxlIDogbnVsbDsKfQoKaWYgKCghJGxvYWRlciA9IGluY2x1ZGVJZkV4aXN0cyhfX0RJUl9fLicvLi4vdmVuZG9yL2F1dG9sb2FkLnBocCcpKSAmJiAoISRsb2FkZXIgPSBpbmNsdWRlSWZFeGlzdHMoX19ESVJfXy4nLy4uLy4uLy4uL2F1dG9sb2FkLnBocCcpKSkgewogICAgZWNobyAnWW91IG11c3Qgc2V0IHVwIHRoZSBwcm9qZWN0IGRlcGVuZGVuY2llcyB1c2luZyBgY29tcG9zZXIgaW5zdGFsbGAnLlBIUF9FT0wuCiAgICAgICAgJ1NlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb3dubG9hZC8gZm9yIGluc3RydWN0aW9ucyBvbiBpbnN0YWxsaW5nIENvbXBvc2VyJy5QSFBfRU9MOwogICAgZXhpdCgxKTsKfQoKcmV0dXJuICRsb2FkZXI7Cjw/cGhwCgovLyBhdXRvbG9hZF9yZWFsLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpjbGFzcyBDb21wb3NlckF1dG9sb2FkZXJJbml0MDQxMTQxMTBhZjg3ZjU2MjRiMzU4MGViYTQzYjg3NzAKewogICAgcHJpdmF0ZSBzdGF0aWMgJGxvYWRlcjsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvYWRDbGFzc0xvYWRlcigkY2xhc3MpCiAgICB7CiAgICAgICAgaWYgKCdDb21wb3NlclxBdXRvbG9hZFxDbGFzc0xvYWRlcicgPT09ICRjbGFzcykgewogICAgICAgICAgICByZXF1aXJlIF9fRElSX18gLiAnL0NsYXNzTG9hZGVyLnBocCc7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBcQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRMb2FkZXIoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSBzZWxmOjokbG9hZGVyKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokbG9hZGVyOwogICAgICAgIH0KCiAgICAgICAgcmVxdWlyZSBfX0RJUl9fIC4gJy9wbGF0Zm9ybV9jaGVjay5waHAnOwoKICAgICAgICBzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJ0NvbXBvc2VyQXV0b2xvYWRlckluaXQwNDExNDExMGFmODdmNTYyNGIzNTgwZWJhNDNiODc3MCcsICdsb2FkQ2xhc3NMb2FkZXInKSwgdHJ1ZSwgdHJ1ZSk7CiAgICAgICAgc2VsZjo6JGxvYWRlciA9ICRsb2FkZXIgPSBuZXcgXENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyKFxkaXJuYW1lKFxkaXJuYW1lKF9fRklMRV9fKSkpOwogICAgICAgIHNwbF9hdXRvbG9hZF91bnJlZ2lzdGVyKGFycmF5KCdDb21wb3NlckF1dG9sb2FkZXJJbml0MDQxMTQxMTBhZjg3ZjU2MjRiMzU4MGViYTQzYjg3NzAnLCAnbG9hZENsYXNzTG9hZGVyJykpOwoKICAgICAgICAkdXNlU3RhdGljTG9hZGVyID0gUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDAgJiYgIWRlZmluZWQoJ0hIVk1fVkVSU0lPTicpICYmICghZnVuY3Rpb25fZXhpc3RzKCd6ZW5kX2xvYWRlcl9maWxlX2VuY29kZWQnKSB8fCAhemVuZF9sb2FkZXJfZmlsZV9lbmNvZGVkKCkpOwogICAgICAgIGlmICgkdXNlU3RhdGljTG9hZGVyKSB7CiAgICAgICAgICAgIHJlcXVpcmUgX19ESVJfXyAuICcvYXV0b2xvYWRfc3RhdGljLnBocCc7CgogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYyhcQ29tcG9zZXJcQXV0b2xvYWRcQ29tcG9zZXJTdGF0aWNJbml0MDQxMTQxMTBhZjg3ZjU2MjRiMzU4MGViYTQzYjg3NzA6OmdldEluaXRpYWxpemVyKCRsb2FkZXIpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbWFwID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9hdXRvbG9hZF9uYW1lc3BhY2VzLnBocCc7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtYXAgYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+c2V0KCRuYW1lc3BhY2UsICRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG1hcCA9IHJlcXVpcmUgX19ESVJfXyAuICcvYXV0b2xvYWRfcHNyNC5waHAnOwogICAgICAgICAgICBmb3JlYWNoICgkbWFwIGFzICRuYW1lc3BhY2UgPT4gJHBhdGgpIHsKICAgICAgICAgICAgICAgICRsb2FkZXItPnNldFBzcjQoJG5hbWVzcGFjZSwgJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2xhc3NNYXAgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX2NsYXNzbWFwLnBocCc7CiAgICAgICAgICAgIGlmICgkY2xhc3NNYXApIHsKICAgICAgICAgICAgICAgICRsb2FkZXItPmFkZENsYXNzTWFwKCRjbGFzc01hcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRsb2FkZXItPnJlZ2lzdGVyKHRydWUpOwoKICAgICAgICBpZiAoJHVzZVN0YXRpY0xvYWRlcikgewogICAgICAgICAgICAkaW5jbHVkZUZpbGVzID0gQ29tcG9zZXJcQXV0b2xvYWRcQ29tcG9zZXJTdGF0aWNJbml0MDQxMTQxMTBhZjg3ZjU2MjRiMzU4MGViYTQzYjg3NzA6OiRmaWxlczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaW5jbHVkZUZpbGVzID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9hdXRvbG9hZF9maWxlcy5waHAnOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkaW5jbHVkZUZpbGVzIGFzICRmaWxlSWRlbnRpZmllciA9PiAkZmlsZSkgewogICAgICAgICAgICBjb21wb3NlclJlcXVpcmUwNDExNDExMGFmODdmNTYyNGIzNTgwZWJhNDNiODc3MCgkZmlsZUlkZW50aWZpZXIsICRmaWxlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbG9hZGVyOwogICAgfQp9CgovKioKICogQHBhcmFtIHN0cmluZyAkZmlsZUlkZW50aWZpZXIKICogQHBhcmFtIHN0cmluZyAkZmlsZQogKiBAcmV0dXJuIHZvaWQKICovCmZ1bmN0aW9uIGNvbXBvc2VyUmVxdWlyZTA0MTE0MTEwYWY4N2Y1NjI0YjM1ODBlYmE0M2I4NzcwKCRmaWxlSWRlbnRpZmllciwgJGZpbGUpCnsKICAgIGlmIChlbXB0eSgkR0xPQkFMU1snX19jb21wb3Nlcl9hdXRvbG9hZF9maWxlcyddWyRmaWxlSWRlbnRpZmllcl0pKSB7CiAgICAgICAgJEdMT0JBTFNbJ19fY29tcG9zZXJfYXV0b2xvYWRfZmlsZXMnXVskZmlsZUlkZW50aWZpZXJdID0gdHJ1ZTsKCiAgICAgICAgcmVxdWlyZSAkZmlsZTsKICAgIH0KfQo8P3BocAoKLy8gYXV0b2xvYWRfY2xhc3NtYXAucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKCiR2ZW5kb3JEaXIgPSBkaXJuYW1lKGRpcm5hbWUoX19GSUxFX18pKTsKJGJhc2VEaXIgPSBkaXJuYW1lKCR2ZW5kb3JEaXIpOwoKcmV0dXJuIGFycmF5KAogICAgJ0NvbXBvc2VyXFxJbnN0YWxsZWRWZXJzaW9ucycgPT4gJHZlbmRvckRpciAuICcvY29tcG9zZXIvSW5zdGFsbGVkVmVyc2lvbnMucGhwJywKICAgICdXUF9DTEknID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS93cC1jbGkvcGhwL2NsYXNzLXdwLWNsaS5waHAnLAogICAgJ1dQX0NMSV9Db21tYW5kJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvd3AtY2xpL3BocC9jbGFzcy13cC1jbGktY29tbWFuZC5waHAnLAopOwo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc3BkeC1saWNlbnNlcy4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxTcGR4OwoKY2xhc3MgU3BkeExpY2Vuc2VzCnsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgY29uc3QgTElDRU5TRVNfRklMRSA9ICdzcGR4LWxpY2Vuc2VzLmpzb24nOwoKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgY29uc3QgRVhDRVBUSU9OU19GSUxFID0gJ3NwZHgtZXhjZXB0aW9ucy5qc29uJzsKCiAgICAvKioKICAgICAqIENvbnRhaW5zIGFsbCB0aGUgbGljZW5zZXMuCiAgICAgKgogICAgICogVGhlIGFycmF5IGlzIGluZGV4ZWQgYnkgbGljZW5zZSBpZGVudGlmaWVycywgd2hpY2ggY29udGFpbgogICAgICogYSBudW1lcmljYWxseSBpbmRleGVkIGFycmF5IHdpdGggbGljZW5zZSBkZXRhaWxzLgogICAgICoKICAgICAqICBbIGxvd2VyY2FzZWQgbGljZW5zZSBpZGVudGlmaWVyID0+CiAgICAgKiAgICAgIFsgMCA9PiBpZGVudGlmaWVyIChzdHJpbmcpLCAxID0+IGZ1bGwgbmFtZSAoc3RyaW5nKSwgMiA9PiBvc2kgY2VydGlmaWVkIChib29sKSwgMyA9PiBkZXByZWNhdGVkIChib29sKSBdCiAgICAgKiAgICAsIC4uLgogICAgICogIF0KICAgICAqCiAgICAgKiBAdmFyIGFycmF5PHN0cmluZywgYXJyYXl7MDogc3RyaW5nLCAxOiBzdHJpbmcsIDI6IGJvb2wsIDM6IGJvb2x9PgogICAgICovCiAgICBwcml2YXRlICRsaWNlbnNlczsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJGxpY2Vuc2VzRXhwcmVzc2lvbjsKCiAgICAvKioKICAgICAqIENvbnRhaW5zIGFsbCB0aGUgbGljZW5zZSBleGNlcHRpb25zLgogICAgICoKICAgICAqIFRoZSBhcnJheSBpcyBpbmRleGVkIGJ5IGxpY2Vuc2UgZXhjZXB0aW9uIGlkZW50aWZpZXJzLCB3aGljaCBjb250YWluCiAgICAgKiBhIG51bWVyaWNhbGx5IGluZGV4ZWQgYXJyYXkgd2l0aCBsaWNlbnNlIGV4Y2VwdGlvbiBkZXRhaWxzLgogICAgICoKICAgICAqICBbIGxvd2VyY2FzZWQgZXhjZXB0aW9uIGlkZW50aWZpZXIgPT4KICAgICAqICAgICAgWyAwID0+IGV4Y2VwdGlvbiBpZGVudGlmaWVyIChzdHJpbmcpLCAxID0+IGZ1bGwgbmFtZSAoc3RyaW5nKSBdCiAgICAgKiAgICAsIC4uLgogICAgICogIF0KICAgICAqCiAgICAgKiBAdmFyIGFycmF5PHN0cmluZywgYXJyYXl7MDogc3RyaW5nLCAxOiBzdHJpbmd9PgogICAgICovCiAgICBwcml2YXRlICRleGNlcHRpb25zOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkZXhjZXB0aW9uc0V4cHJlc3Npb247CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+bG9hZExpY2Vuc2VzKCk7CiAgICAgICAgJHRoaXMtPmxvYWRFeGNlcHRpb25zKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxpY2Vuc2UgbWV0YWRhdGEgYnkgbGljZW5zZSBpZGVudGlmaWVyLgogICAgICoKICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBhIGxpbmsgdG8gdGhlIGZ1bGwgbGljZW5zZSB0ZXh0IHRvIHRoZSBsaWNlbnNlIG1ldGFkYXRhLgogICAgICogVGhlIGFycmF5IHJldHVybmVkIGlzIGluIHRoZSBmb3JtIG9mOgogICAgICoKICAgICAqICBbIDAgPT4gZnVsbCBuYW1lIChzdHJpbmcpLCAxID0+IG9zaSBjZXJ0aWZpZWQsIDIgPT4gbGluayB0byBsaWNlbnNlIHRleHQgKHN0cmluZyksIDMgPT4gZGVwcmVjYXRpb24gc3RhdHVzIChib29sKSBdCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllcgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7MDogc3RyaW5nLCAxOiBib29sLCAyOiBzdHJpbmcsIDM6IGJvb2x9fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExpY2Vuc2VCeUlkZW50aWZpZXIoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJGtleSA9IHN0cnRvbG93ZXIoJGlkZW50aWZpZXIpOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5saWNlbnNlc1ska2V5XSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBsaXN0KCRpZGVudGlmaWVyLCAkbmFtZSwgJGlzT3NpQXBwcm92ZWQsICRpc0RlcHJlY2F0ZWRMaWNlbnNlSWQpID0gJHRoaXMtPmxpY2Vuc2VzWyRrZXldOwoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICAkaXNPc2lBcHByb3ZlZCwKICAgICAgICAgICAgJ2h0dHBzOi8vc3BkeC5vcmcvbGljZW5zZXMvJyAuICRpZGVudGlmaWVyIC4gJy5odG1sI2xpY2Vuc2VUZXh0JywKICAgICAgICAgICAgJGlzRGVwcmVjYXRlZExpY2Vuc2VJZCwKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgbGljZW5zZXMgaW5mb3JtYXRpb24sIGtleWVkIGJ5IHRoZSBsb3dlcmNhc2VkIGxpY2Vuc2UgaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5ezA6IHN0cmluZywgMTogc3RyaW5nLCAyOiBib29sLCAzOiBib29sfVtdIEVhY2ggaXRlbSBpcyBbIDAgPT4gaWRlbnRpZmllciAoc3RyaW5nKSwgMSA9PiBmdWxsIG5hbWUgKHN0cmluZyksIDIgPT4gb3NpIGNlcnRpZmllZCAoYm9vbCksIDMgPT4gZGVwcmVjYXRlZCAoYm9vbCkgXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGljZW5zZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGljZW5zZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxpY2Vuc2UgZXhjZXB0aW9uIG1ldGFkYXRhIGJ5IGxpY2Vuc2UgZXhjZXB0aW9uIGlkZW50aWZpZXIuCiAgICAgKgogICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGEgbGluayB0byB0aGUgZnVsbCBsaWNlbnNlIGV4Y2VwdGlvbiB0ZXh0IHRvIHRoZSBsaWNlbnNlIGV4Y2VwdGlvbiBtZXRhZGF0YS4KICAgICAqIFRoZSBhcnJheSByZXR1cm5lZCBpcyBpbiB0aGUgZm9ybSBvZjoKICAgICAqCiAgICAgKiAgWyAwID0+IGZ1bGwgbmFtZSAoc3RyaW5nKSwgMSA9PiBsaW5rIHRvIGxpY2Vuc2UgdGV4dCAoc3RyaW5nKSBdCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllcgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl7MDogc3RyaW5nLCAxOiBzdHJpbmd9fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4Y2VwdGlvbkJ5SWRlbnRpZmllcigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAka2V5ID0gc3RydG9sb3dlcigkaWRlbnRpZmllcik7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmV4Y2VwdGlvbnNbJGtleV0pKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgbGlzdCgkaWRlbnRpZmllciwgJG5hbWUpID0gJHRoaXMtPmV4Y2VwdGlvbnNbJGtleV07CgogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICdodHRwczovL3NwZHgub3JnL2xpY2Vuc2VzLycgLiAkaWRlbnRpZmllciAuICcuaHRtbCNsaWNlbnNlRXhjZXB0aW9uVGV4dCcsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNob3J0IGlkZW50aWZpZXIgb2YgYSBsaWNlbnNlIChvciBsaWNlbnNlIGV4Y2VwdGlvbikgYnkgZnVsbCBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJZGVudGlmaWVyQnlOYW1lKCRuYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5saWNlbnNlcyBhcyAkbGljZW5zZURhdGEpIHsKICAgICAgICAgICAgaWYgKCRsaWNlbnNlRGF0YVsxXSA9PT0gJG5hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbGljZW5zZURhdGFbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5leGNlcHRpb25zIGFzICRsaWNlbnNlRGF0YSkgewogICAgICAgICAgICBpZiAoJGxpY2Vuc2VEYXRhWzFdID09PSAkbmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRsaWNlbnNlRGF0YVswXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBPU0kgQXBwcm92ZWQgc3RhdHVzIGZvciBhIGxpY2Vuc2UgYnkgaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc09zaUFwcHJvdmVkQnlJZGVudGlmaWVyKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGljZW5zZXNbc3RydG9sb3dlcigkaWRlbnRpZmllcildWzJdOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVwcmVjYXRpb24gc3RhdHVzIGZvciBhIGxpY2Vuc2UgYnkgaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlcHJlY2F0ZWRCeUlkZW50aWZpZXIoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saWNlbnNlc1tzdHJ0b2xvd2VyKCRpZGVudGlmaWVyKV1bM107CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW118c3RyaW5nICRsaWNlbnNlCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZSgkbGljZW5zZSkKICAgIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJGxpY2Vuc2UpKSB7CiAgICAgICAgICAgICRjb3VudCA9IGNvdW50KCRsaWNlbnNlKTsKICAgICAgICAgICAgaWYgKCRjb3VudCAhPT0gY291bnQoYXJyYXlfZmlsdGVyKCRsaWNlbnNlLCAnaXNfc3RyaW5nJykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignQXJyYXkgb2Ygc3RyaW5ncyBleHBlY3RlZC4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGljZW5zZSA9ICRjb3VudCA+IDEgID8gJygnIC4gaW1wbG9kZSgnIE9SICcsICRsaWNlbnNlKSAuICcpJyA6IChzdHJpbmcpIHJlc2V0KCRsaWNlbnNlKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNfc3RyaW5nKCRsaWNlbnNlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ0FycmF5IG9yIFN0cmluZyBleHBlY3RlZCwgJXMgZ2l2ZW4uJywKICAgICAgICAgICAgICAgIGdldHR5cGUoJGxpY2Vuc2UpCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1ZhbGlkTGljZW5zZVN0cmluZygkbGljZW5zZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFJlc291cmNlc0RpcigpCiAgICB7CiAgICAgICAgcmV0dXJuIGRpcm5hbWUoX19ESVJfXykgLiAnL3Jlcyc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkTGljZW5zZXMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+bGljZW5zZXMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGpzb24gPSBmaWxlX2dldF9jb250ZW50cyhzZWxmOjpnZXRSZXNvdXJjZXNEaXIoKSAuICcvJyAuIHNlbGY6OkxJQ0VOU0VTX0ZJTEUpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJGpzb24pIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdNaXNzaW5nIGxpY2Vuc2UgZmlsZSBpbiAnIC4gc2VsZjo6Z2V0UmVzb3VyY2VzRGlyKCkgLiAnLycgLiBzZWxmOjpMSUNFTlNFU19GSUxFKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmxpY2Vuc2VzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoanNvbl9kZWNvZGUoJGpzb24sIHRydWUpIGFzICRpZGVudGlmaWVyID0+ICRsaWNlbnNlKSB7CiAgICAgICAgICAgICR0aGlzLT5saWNlbnNlc1tzdHJ0b2xvd2VyKCRpZGVudGlmaWVyKV0gPSBhcnJheSgkaWRlbnRpZmllciwgJGxpY2Vuc2VbMF0sICRsaWNlbnNlWzFdLCAkbGljZW5zZVsyXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbG9hZEV4Y2VwdGlvbnMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+ZXhjZXB0aW9ucykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkanNvbiA9IGZpbGVfZ2V0X2NvbnRlbnRzKHNlbGY6OmdldFJlc291cmNlc0RpcigpIC4gJy8nIC4gc2VsZjo6RVhDRVBUSU9OU19GSUxFKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRqc29uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignTWlzc2luZyBleGNlcHRpb25zIGZpbGUgaW4gJyAuIHNlbGY6OmdldFJlc291cmNlc0RpcigpIC4gJy8nIC4gc2VsZjo6RVhDRVBUSU9OU19GSUxFKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmV4Y2VwdGlvbnMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoIChqc29uX2RlY29kZSgkanNvbiwgdHJ1ZSkgYXMgJGlkZW50aWZpZXIgPT4gJGV4Y2VwdGlvbikgewogICAgICAgICAgICAkdGhpcy0+ZXhjZXB0aW9uc1tzdHJ0b2xvd2VyKCRpZGVudGlmaWVyKV0gPSBhcnJheSgkaWRlbnRpZmllciwgJGV4Y2VwdGlvblswXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRMaWNlbnNlc0V4cHJlc3Npb24oKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+bGljZW5zZXNFeHByZXNzaW9uKSB7CiAgICAgICAgICAgICRsaWNlbnNlcyA9IGFycmF5X21hcCgncHJlZ19xdW90ZScsIGFycmF5X2tleXMoJHRoaXMtPmxpY2Vuc2VzKSk7CiAgICAgICAgICAgIHJzb3J0KCRsaWNlbnNlcyk7CiAgICAgICAgICAgICRsaWNlbnNlcyA9IGltcGxvZGUoJ3wnLCAkbGljZW5zZXMpOwogICAgICAgICAgICAkdGhpcy0+bGljZW5zZXNFeHByZXNzaW9uID0gJGxpY2Vuc2VzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5saWNlbnNlc0V4cHJlc3Npb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEV4Y2VwdGlvbnNFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmV4Y2VwdGlvbnNFeHByZXNzaW9uKSB7CiAgICAgICAgICAgICRleGNlcHRpb25zID0gYXJyYXlfbWFwKCdwcmVnX3F1b3RlJywgYXJyYXlfa2V5cygkdGhpcy0+ZXhjZXB0aW9ucykpOwogICAgICAgICAgICByc29ydCgkZXhjZXB0aW9ucyk7CiAgICAgICAgICAgICRleGNlcHRpb25zID0gaW1wbG9kZSgnfCcsICRleGNlcHRpb25zKTsKICAgICAgICAgICAgJHRoaXMtPmV4Y2VwdGlvbnNFeHByZXNzaW9uID0gJGV4Y2VwdGlvbnM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4Y2VwdGlvbnNFeHByZXNzaW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbGljZW5zZQogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1ZhbGlkTGljZW5zZVN0cmluZygkbGljZW5zZSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxpY2Vuc2VzW3N0cnRvbG93ZXIoJGxpY2Vuc2UpXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkbGljZW5zZXMgPSAkdGhpcy0+Z2V0TGljZW5zZXNFeHByZXNzaW9uKCk7CiAgICAgICAgJGV4Y2VwdGlvbnMgPSAkdGhpcy0+Z2V0RXhjZXB0aW9uc0V4cHJlc3Npb24oKTsKCiAgICAgICAgJHJlZ2V4ID0gPDw8UkVHRVgKewooPyhERUZJTkUpCiAgICAjIGlkc3RyaW5nOiAxKiggQUxQSEEgLyBESUdJVCAvIC0gLyAuICkKICAgICg/PGlkc3RyaW5nPltccExccE4uLV17MSx9KQoKICAgICMgbGljZW5zZS1pZDogdGFrZW4gZnJvbSBsaXN0CiAgICAoPzxsaWNlbnNlaWQ+JHtsaWNlbnNlc30pCgogICAgIyBsaWNlbnNlLWV4Y2VwdGlvbi1pZDogdGFrZW4gZnJvbSBsaXN0CiAgICAoPzxsaWNlbnNlZXhjZXB0aW9uaWQ+JHtleGNlcHRpb25zfSkKCiAgICAjIGxpY2Vuc2UtcmVmOiBbRG9jdW1lbnRSZWYtMSooaWRzdHJpbmcpOl1MaWNlbnNlUmVmLTEqKGlkc3RyaW5nKQogICAgKD88bGljZW5zZXJlZj4oPzpEb2N1bWVudFJlZi0oPyZpZHN0cmluZyk6KT9MaWNlbnNlUmVmLSg/Jmlkc3RyaW5nKSkKCiAgICAjIHNpbXBsZS1leHByZXNzc2lvbjogbGljZW5zZS1pZCAvIGxpY2Vuc2UtaWQrIC8gbGljZW5zZS1yZWYKICAgICg/PHNpbXBsZV9leHByZXNzaW9uPig/JmxpY2Vuc2VpZClcKz8gfCAoPyZsaWNlbnNlaWQpIHwgKD8mbGljZW5zZXJlZikpCgogICAgIyBjb21wb3VuZC1leHByZXNzaW9uOiAxKigKICAgICMgICBzaW1wbGUtZXhwcmVzc2lvbiAvCiAgICAjICAgc2ltcGxlLWV4cHJlc3Npb24gV0lUSCBsaWNlbnNlLWV4Y2VwdGlvbi1pZCAvCiAgICAjICAgY29tcG91bmQtZXhwcmVzc2lvbiBBTkQgY29tcG91bmQtZXhwcmVzc2lvbiAvCiAgICAjICAgY29tcG91bmQtZXhwcmVzc2lvbiBPUiBjb21wb3VuZC1leHByZXNzaW9uCiAgICAjICkgLyAoIGNvbXBvdW5kLWV4cHJlc3Npb24gKSApCiAgICAoPzxjb21wb3VuZF9oZWFkPgogICAgICAgICg/JnNpbXBsZV9leHByZXNzaW9uKSAoIFxzKyBXSVRIIFxzKyAoPyZsaWNlbnNlZXhjZXB0aW9uaWQpKT8KICAgICAgICAgICAgfCBcKCBccyogKD8mY29tcG91bmRfZXhwcmVzc2lvbikgXHMqIFwpCiAgICApCiAgICAoPzxjb21wb3VuZF9leHByZXNzaW9uPgogICAgICAgICg/JmNvbXBvdW5kX2hlYWQpICg/OiBccysgKD86QU5EfE9SKSBccysgKD8mY29tcG91bmRfZXhwcmVzc2lvbikpPwogICAgKQoKICAgICMgbGljZW5zZS1leHByZXNzaW9uOiAxKjEoc2ltcGxlLWV4cHJlc3Npb24gLyBjb21wb3VuZC1leHByZXNzaW9uKQogICAgKD88bGljZW5zZV9leHByZXNzaW9uPig/JmNvbXBvdW5kX2V4cHJlc3Npb24pIHwgKD8mc2ltcGxlX2V4cHJlc3Npb24pKQopICMgZW5kIG9mIGRlZmluZQoKXihOT05FIHwgTk9BU1NFUlRJT04gfCAoPyZsaWNlbnNlX2V4cHJlc3Npb24pKSQKfXhpClJFR0VYOwoKICAgICAgICAkbWF0Y2ggPSBwcmVnX21hdGNoKCRyZWdleCwgJGxpY2Vuc2UpOwoKICAgICAgICBpZiAoMCA9PT0gJG1hdGNoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJG1hdGNoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignUmVnZXggZmFpbGVkIHRvIGNvbXBpbGUvcnVuLicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL2NhLWJ1bmRsZS4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDYUJ1bmRsZTsKCnVzZSBQc3JcTG9nXExvZ2dlckludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUGhwUHJvY2VzczsKCi8qKgogKiBAYXV0aG9yIENocmlzIFNtaXRoIDxjaHJpc0BjczI3OC5vcmc+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENhQnVuZGxlCnsKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcml2YXRlIHN0YXRpYyAkY2FQYXRoOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBib29sPiAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGNhRmlsZVZhbGlkaXR5ID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGJvb2x8bnVsbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHVzZU9wZW5zc2xQYXJzZTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN5c3RlbSBDQSBidW5kbGUgcGF0aCwgb3IgYSBwYXRoIHRvIHRoZSBidW5kbGVkIG9uZQogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIHdhcyBhZGFwdGVkIGZyb20gU3NsdXJwLgogICAgICogaHR0cHM6Ly9naXRodWIuY29tL0V2YW5Eb3RQcm8vU3NsdXJwCiAgICAgKgogICAgICogKGMpIEV2YW4gQ291cnkgPG1lQGV2YW5jb3VyeS5jb20+CiAgICAgKgogICAgICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHNlZSBiZWxvdzoKICAgICAqCiAgICAgKiBDb3B5cmlnaHQgKGMpIDIwMTMsIEV2YW4gQ291cnkKICAgICAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAgICAgKgogICAgICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwKICAgICAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICAqCiAgICAgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCiAgICAgKiAgICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICoKICAgICAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICAgICAqICAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24KICAgICAqICAgICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogICAgICoKICAgICAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIiBBTkQKICAgICAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVECiAgICAgKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAgICAgKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SCiAgICAgKiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKICAgICAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsKICAgICAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTgogICAgICogQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKICAgICAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTCiAgICAgKiBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KICAgICAqCiAgICAgKiBAcGFyYW0gIExvZ2dlckludGVyZmFjZSAkbG9nZ2VyIG9wdGlvbmFsIGxvZ2dlciBmb3IgaW5mb3JtYXRpb24gYWJvdXQgd2hpY2ggQ0EgZmlsZXMgd2VyZSBsb2FkZWQKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgIHBhdGggdG8gYSBDQSBidW5kbGUgZmlsZSBvciBkaXJlY3RvcnkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTeXN0ZW1DYVJvb3RCdW5kbGVQYXRoKExvZ2dlckludGVyZmFjZSAkbG9nZ2VyID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6JGNhUGF0aCAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JGNhUGF0aDsKICAgICAgICB9CiAgICAgICAgJGNhQnVuZGxlUGF0aHMgPSBhcnJheSgpOwoKICAgICAgICAvLyBJZiBTU0xfQ0VSVF9GSUxFIGVudiB2YXJpYWJsZSBwb2ludHMgdG8gYSB2YWxpZCBjZXJ0aWZpY2F0ZS9idW5kbGUsIHVzZSB0aGF0LgogICAgICAgIC8vIFRoaXMgbWltaWNzIGhvdyBPcGVuU1NMIHVzZXMgdGhlIFNTTF9DRVJUX0ZJTEUgZW52IHZhcmlhYmxlLgogICAgICAgICRjYUJ1bmRsZVBhdGhzW10gPSBzZWxmOjpnZXRFbnZWYXJpYWJsZSgnU1NMX0NFUlRfRklMRScpOwoKICAgICAgICAvLyBJZiBTU0xfQ0VSVF9ESVIgZW52IHZhcmlhYmxlIHBvaW50cyB0byBhIHZhbGlkIGNlcnRpZmljYXRlL2J1bmRsZSwgdXNlIHRoYXQuCiAgICAgICAgLy8gVGhpcyBtaW1pY3MgaG93IE9wZW5TU0wgdXNlcyB0aGUgU1NMX0NFUlRfRklMRSBlbnYgdmFyaWFibGUuCiAgICAgICAgJGNhQnVuZGxlUGF0aHNbXSA9IHNlbGY6OmdldEVudlZhcmlhYmxlKCdTU0xfQ0VSVF9ESVInKTsKCiAgICAgICAgJGNhQnVuZGxlUGF0aHNbXSA9IGluaV9nZXQoJ29wZW5zc2wuY2FmaWxlJyk7CiAgICAgICAgJGNhQnVuZGxlUGF0aHNbXSA9IGluaV9nZXQoJ29wZW5zc2wuY2FwYXRoJyk7CgogICAgICAgICRvdGhlckxvY2F0aW9ucyA9IGFycmF5KAogICAgICAgICAgICAnL2V0Yy9wa2kvdGxzL2NlcnRzL2NhLWJ1bmRsZS5jcnQnLCAvLyBGZWRvcmEsIFJIRUwsIENlbnRPUyAoY2EtY2VydGlmaWNhdGVzIHBhY2thZ2UpCiAgICAgICAgICAgICcvZXRjL3NzbC9jZXJ0cy9jYS1jZXJ0aWZpY2F0ZXMuY3J0JywgLy8gRGViaWFuLCBVYnVudHUsIEdlbnRvbywgQXJjaCBMaW51eCAoY2EtY2VydGlmaWNhdGVzIHBhY2thZ2UpCiAgICAgICAgICAgICcvZXRjL3NzbC9jYS1idW5kbGUucGVtJywgLy8gU1VTRSwgb3BlblNVU0UgKGNhLWNlcnRpZmljYXRlcyBwYWNrYWdlKQogICAgICAgICAgICAnL3Vzci9sb2NhbC9zaGFyZS9jZXJ0cy9jYS1yb290LW5zcy5jcnQnLCAvLyBGcmVlQlNEIChjYV9yb290X25zc19wYWNrYWdlKQogICAgICAgICAgICAnL3Vzci9zc2wvY2VydHMvY2EtYnVuZGxlLmNydCcsIC8vIEN5Z3dpbgogICAgICAgICAgICAnL29wdC9sb2NhbC9zaGFyZS9jdXJsL2N1cmwtY2EtYnVuZGxlLmNydCcsIC8vIE9TIFggbWFjcG9ydHMsIGN1cmwtY2EtYnVuZGxlIHBhY2thZ2UKICAgICAgICAgICAgJy91c3IvbG9jYWwvc2hhcmUvY3VybC9jdXJsLWNhLWJ1bmRsZS5jcnQnLCAvLyBEZWZhdWx0IGNVUkwgQ0EgYnVuZGUgcGF0aCAod2l0aG91dCAtLXdpdGgtY2EtYnVuZGxlIG9wdGlvbikKICAgICAgICAgICAgJy91c3Ivc2hhcmUvc3NsL2NlcnRzL2NhLWJ1bmRsZS5jcnQnLCAvLyBSZWFsbHkgb2xkIFJlZEhhdD8KICAgICAgICAgICAgJy9ldGMvc3NsL2NlcnQucGVtJywgLy8gT3BlbkJTRAogICAgICAgICAgICAnL3Vzci9sb2NhbC9ldGMvc3NsL2NlcnQucGVtJywgLy8gRnJlZUJTRCAxMC54CiAgICAgICAgICAgICcvdXNyL2xvY2FsL2V0Yy9vcGVuc3NsL2NlcnQucGVtJywgLy8gT1MgWCBob21lYnJldywgb3BlbnNzbCBwYWNrYWdlCiAgICAgICAgICAgICcvdXNyL2xvY2FsL2V0Yy9vcGVuc3NsQDEuMS9jZXJ0LnBlbScsIC8vIE9TIFggaG9tZWJyZXcsIG9wZW5zc2xAMS4xIHBhY2thZ2UKICAgICAgICApOwoKICAgICAgICBmb3JlYWNoKCRvdGhlckxvY2F0aW9ucyBhcyAkbG9jYXRpb24pIHsKICAgICAgICAgICAgJG90aGVyTG9jYXRpb25zW10gPSBkaXJuYW1lKCRsb2NhdGlvbik7CiAgICAgICAgfQoKICAgICAgICAkY2FCdW5kbGVQYXRocyA9IGFycmF5X21lcmdlKCRjYUJ1bmRsZVBhdGhzLCAkb3RoZXJMb2NhdGlvbnMpOwoKICAgICAgICBmb3JlYWNoICgkY2FCdW5kbGVQYXRocyBhcyAkY2FCdW5kbGUpIHsKICAgICAgICAgICAgaWYgKCRjYUJ1bmRsZSAmJiBzZWxmOjpjYUZpbGVVc2FibGUoJGNhQnVuZGxlLCAkbG9nZ2VyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRjYVBhdGggPSAkY2FCdW5kbGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY2FCdW5kbGUgJiYgc2VsZjo6Y2FEaXJVc2FibGUoJGNhQnVuZGxlLCAkbG9nZ2VyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRjYVBhdGggPSAkY2FCdW5kbGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokY2FQYXRoID0gc3RhdGljOjpnZXRCdW5kbGVkQ2FCdW5kbGVQYXRoKCk7IC8vIEJ1bmRsZWQgQ0EgZmlsZSwgbGFzdCByZXNvcnQKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhdGggdG8gdGhlIGJ1bmRsZWQgQ0EgZmlsZQogICAgICoKICAgICAqIEluIGNhc2UgeW91IGRvbid0IHdhbnQgdG8gdHJ1c3QgdGhlIHVzZXIgb3IgdGhlIHN5c3RlbSwgeW91IGNhbiB1c2UgdGhpcyBkaXJlY3RseQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHBhdGggdG8gYSBDQSBidW5kbGUgZmlsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEJ1bmRsZWRDYUJ1bmRsZVBhdGgoKQogICAgewogICAgICAgICRjYUJ1bmRsZUZpbGUgPSBfX0RJUl9fLicvLi4vcmVzL2NhY2VydC5wZW0nOwoKICAgICAgICAvLyBjVVJMIGRvZXMgbm90IHVuZGVyc3RhbmQgJ3BoYXI6Ly8nIHBhdGhzCiAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jYS1idW5kbGUvaXNzdWVzLzEwCiAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkY2FCdW5kbGVGaWxlLCAncGhhcjovLycpKSB7CiAgICAgICAgICAgICR0ZW1wQ2FCdW5kbGVGaWxlID0gdGVtcG5hbShzeXNfZ2V0X3RlbXBfZGlyKCksICdvcGVuc3NsLWNhLWJ1bmRsZS0nKTsKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkdGVtcENhQnVuZGxlRmlsZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgY3JlYXRlIGEgdGVtcG9yYXJ5IGZpbGUgdG8gc3RvcmUgdGhlIGJ1bmRsZWQgQ0EgZmlsZScpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygKICAgICAgICAgICAgICAgICR0ZW1wQ2FCdW5kbGVGaWxlLAogICAgICAgICAgICAgICAgZmlsZV9nZXRfY29udGVudHMoJGNhQnVuZGxlRmlsZSkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKGZ1bmN0aW9uKCkgdXNlICgkdGVtcENhQnVuZGxlRmlsZSkgewogICAgICAgICAgICAgICAgQHVubGluaygkdGVtcENhQnVuZGxlRmlsZSk7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgJGNhQnVuZGxlRmlsZSA9ICR0ZW1wQ2FCdW5kbGVGaWxlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjYUJ1bmRsZUZpbGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgYSBDQSBmaWxlIHVzaW5nIG9wZW5zbF94NTA5X3BhcnNlIG9ubHkgaWYgaXQgaXMgc2FmZSB0byB1c2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRmaWxlbmFtZQogICAgICogQHBhcmFtIExvZ2dlckludGVyZmFjZSAkbG9nZ2VyICAgb3B0aW9uYWwgbG9nZ2VyIGZvciBpbmZvcm1hdGlvbiBhYm91dCB3aGljaCBDQSBmaWxlcyB3ZXJlIGxvYWRlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhbGlkYXRlQ2FGaWxlKCRmaWxlbmFtZSwgTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgIHN0YXRpYyAkd2FybmVkID0gZmFsc2U7CgogICAgICAgIGlmIChpc3NldChzZWxmOjokY2FGaWxlVmFsaWRpdHlbJGZpbGVuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRjYUZpbGVWYWxpZGl0eVskZmlsZW5hbWVdOwogICAgICAgIH0KCiAgICAgICAgJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoJGZpbGVuYW1lKTsKCiAgICAgICAgLy8gYXNzdW1lIHRoZSBDQSBpcyB2YWxpZCBpZiBwaHAgaXMgdnVsbmVyYWJsZSB0bwogICAgICAgIC8vIGh0dHBzOi8vd3d3LnNla3Rpb25laW5zLmRlL2Fkdmlzb3JpZXMvYWR2aXNvcnktMDEyMDEzLXBocC1vcGVuc3NsX3g1MDlfcGFyc2UtbWVtb3J5LWNvcnJ1cHRpb24tdnVsbmVyYWJpbGl0eS5odG1sCiAgICAgICAgaWYgKCFzdGF0aWM6OmlzT3BlbnNzbFBhcnNlU2FmZSgpKSB7CiAgICAgICAgICAgIGlmICghJHdhcm5lZCAmJiAkbG9nZ2VyKSB7CiAgICAgICAgICAgICAgICAkbG9nZ2VyLT53YXJuaW5nKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ1lvdXIgdmVyc2lvbiBvZiBQSFAsICVzLCBpcyBhZmZlY3RlZCBieSBDVkUtMjAxMy02NDIwIGFuZCBjYW5ub3Qgc2FmZWx5IHBlcmZvcm0gY2VydGlmaWNhdGUgdmFsaWRhdGlvbiwgd2Ugc3Ryb25nbHkgc3VnZ2VzdCB5b3UgdXBncmFkZS4nLAogICAgICAgICAgICAgICAgICAgIFBIUF9WRVJTSU9OCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgICR3YXJuZWQgPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaXNWYWxpZCA9ICFlbXB0eSgkY29udGVudHMpOwogICAgICAgIH0gZWxzZWlmIChpc19zdHJpbmcoJGNvbnRlbnRzKSAmJiBzdHJsZW4oJGNvbnRlbnRzKSA+IDApIHsKICAgICAgICAgICAgJGNvbnRlbnRzID0gcHJlZ19yZXBsYWNlKCIvXihcXC0rKD86QkVHSU58RU5EKSlcXHMrVFJVU1RFRFxccysoQ0VSVElGSUNBVEVcXC0rKVwkL20iLCAnJDEgJDInLCAkY29udGVudHMpOwogICAgICAgICAgICBpZiAobnVsbCA9PT0gJGNvbnRlbnRzKSB7CiAgICAgICAgICAgICAgICAvLyByZWdleCBleHRyYWN0aW9uIGZhaWxlZAogICAgICAgICAgICAgICAgJGlzVmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpc1ZhbGlkID0gKGJvb2wpIG9wZW5zc2xfeDUwOV9wYXJzZSgkY29udGVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlzVmFsaWQgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkbG9nZ2VyKSB7CiAgICAgICAgICAgICRsb2dnZXItPmRlYnVnKCdDaGVja2VkIENBIGZpbGUgJy5yZWFscGF0aCgkZmlsZW5hbWUpLic6ICcuKCRpc1ZhbGlkID8gJ3ZhbGlkJyA6ICdpbnZhbGlkJykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRjYUZpbGVWYWxpZGl0eVskZmlsZW5hbWVdID0gJGlzVmFsaWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBUZXN0IGlmIGl0IGlzIHNhZmUgdG8gdXNlIHRoZSBQSFAgZnVuY3Rpb24gb3BlbnNzbF94NTA5X3BhcnNlKCkuCiAgICAgKgogICAgICogVGhpcyBjaGVja3MgaWYgT3BlblNTTCBleHRlbnNpb25zIGlzIHZ1bG5lcmFibGUgdG8gcmVtb3RlIGNvZGUgZXhlY3V0aW9uCiAgICAgKiB2aWEgdGhlIGV4cGxvaXQgZG9jdW1lbnRlZCBhcyBDVkUtMjAxMy02NDIwLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzT3BlbnNzbFBhcnNlU2FmZSgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09IHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDApIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gVnVsbmVyYWJsZToKICAgICAgICAvLyBQSFAgNS4zLjAgLSBQSFAgNS4zLjI3CiAgICAgICAgLy8gUEhQIDUuNC4wIC0gUEhQIDUuNC4yMgogICAgICAgIC8vIFBIUCA1LjUuMCAtIFBIUCA1LjUuNgogICAgICAgIGlmICgKICAgICAgICAgICAgICAgKFBIUF9WRVJTSU9OX0lEIDwgNTA0MDAgJiYgUEhQX1ZFUlNJT05fSUQgPj0gNTAzMjgpCiAgICAgICAgICAgIHx8IChQSFBfVkVSU0lPTl9JRCA8IDUwNTAwICYmIFBIUF9WRVJTSU9OX0lEID49IDUwNDIzKQogICAgICAgICAgICB8fCBQSFBfVkVSU0lPTl9JRCA+PSA1MDUwNwogICAgICAgICkgewogICAgICAgICAgICAvLyBUaGlzIHZlcnNpb24gb2YgUEhQIGhhcyB0aGUgZml4IGZvciBDVkUtMjAxMy02NDIwIGFwcGxpZWQuCiAgICAgICAgICAgIHJldHVybiBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChkZWZpbmVkKCdQSFBfV0lORE9XU19WRVJTSU9OX0JVSUxEJykpIHsKICAgICAgICAgICAgLy8gV2luZG93cyBpcyBwcm9iYWJseSBpbnNlY3VyZSBpbiB0aGlzIGNhc2UuCiAgICAgICAgICAgIHJldHVybiBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkY29tcGFyZURpc3Ryb1ZlcnNpb25QcmVmaXggPSBmdW5jdGlvbiAoJHByZWZpeCwgJGZpeGVkVmVyc2lvbikgewogICAgICAgICAgICAkcmVnZXggPSAne14nLnByZWdfcXVvdGUoJHByZWZpeCkuJyhbMC05XSspJH0nOwoKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHJlZ2V4LCBQSFBfVkVSU0lPTiwgJG0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKChpbnQpICRtWzFdKSA+PSAkZml4ZWRWZXJzaW9uOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAgICAgLy8gSGFyZCBjb2RlZCBsaXN0IG9mIFBIUCBkaXN0cmlidXRpb25zIHdpdGggdGhlIGZpeCBiYWNrcG9ydGVkLgogICAgICAgIGlmICgKICAgICAgICAgICAgJGNvbXBhcmVEaXN0cm9WZXJzaW9uUHJlZml4KCc1LjMuMy03K3NxdWVlemUnLCAxOCkgLy8gRGViaWFuIDYgKFNxdWVlemUpCiAgICAgICAgICAgIHx8ICRjb21wYXJlRGlzdHJvVmVyc2lvblByZWZpeCgnNS40LjQtMTQrZGViN3UnLCA3KSAvLyBEZWJpYW4gNyAoV2hlZXp5KQogICAgICAgICAgICB8fCAkY29tcGFyZURpc3Ryb1ZlcnNpb25QcmVmaXgoJzUuMy4xMC0xdWJ1bnR1My4nLCA5KSAvLyBVYnVudHUgMTIuMDQgKFByZWNpc2UpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIFN5bWZvbnkgUHJvY2VzcyBjb21wb25lbnQgaXMgbWlzc2luZyBzbyB3ZSBhc3N1bWUgaXQgaXMgdW5zYWZlIGF0IHRoaXMgcG9pbnQKICAgICAgICBpZiAoIWNsYXNzX2V4aXN0cygnU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaHBQcm9jZXNzJykpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIFRoaXMgaXMgd2hlcmUgdGhpbmdzIGdldCBjcmF6eSwgYmVjYXVzZSBkaXN0cm9zIGJhY2twb3J0IHNlY3VyaXR5CiAgICAgICAgLy8gZml4ZXMgdGhlIGNoYW5jZXMgYXJlIG9uIE5JWCBzeXN0ZW1zIHRoZSBmaXggaGFzIGJlZW4gYXBwbGllZCBidXQKICAgICAgICAvLyBpdCdzIG5vdCBwb3NzaWJsZSB0byB2ZXJpZnkgdGhhdCBmcm9tIHRoZSBQSFAgdmVyc2lvbi4KICAgICAgICAvLwogICAgICAgIC8vIFRvIHZlcmlmeSBleGVjIGEgbmV3IFBIUCBwcm9jZXNzIGFuZCBydW4gdGhlIGlzc3VlIHRlc3RjYXNlIHdpdGgKICAgICAgICAvLyBrbm93biBzYWZlIGlucHV0IHRoYXQgcmVwbGljYXRlcyB0aGUgYnVnLgoKICAgICAgICAvLyBCYXNlZCBvbiB0ZXN0Y2FzZSBpbiBodHRwczovL2dpdGh1Yi5jb20vcGhwL3BocC1zcmMvY29tbWl0L2MxMjI0NTczYzc3M2I2ODQ1ZTgzNTA1ZjcxN2ZiZjgyMGZjMTg0MTUKICAgICAgICAvLyBjaGFuZ2VzIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9waHAvcGhwLXNyYy9jb21taXQvNzZhN2ZkODkzYjdkNjEwMTMwMGNjNjU2MDU4NzA0YTczMjU0ZDU5MwogICAgICAgICRjZXJ0ID0gJ0xTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVZ3UkVORFFUUjVaMEYzU1VKQlowbEtRVXA2ZFRoeU5uVTJaVUpqVFVFd1IwTlRjVWRUU1dJelJGRkZRa0pSVlVGTlNVaEVUVkZ6ZDBOUldVUUtWbEZSUjBWM1NrVlNWRVZqVFVKdlIwRXhWVVZEUVhkVVZHMDVlVnBJU205YVYyeDFURlprYkdNelVtMVpWM2hzWW1wRlVVMUJORWRCTVZWRlFuZDNTQXBUT0U5RWQzSmFjMkpxUlZWTlFrbEhRVEZWUlVObmQweFZNbFp5WkVkc2RtSnJWbkJpYmsxNFNIcEJaRUpuVGxaQ1FYTk5SbXN4YUdKSGJHcGhWemt4Q21ONVFrUmFXRW93U1VaT2JGa3pVbkJpTWpSNFNWUkJaa0puVGxaQ1FVMU5SMGN4YUdKSGJHcGhWemt4WTNrMWVscFhkREJoVnpsMVdsZHNkV041TldzS1dsUkZjVTFEWjBkRFUzRkhVMGxpTTBSUlJVcEJVbGxpWXpOU2JGcHRSblZNYlZaNll6SldlVkZJVG14aE0xSndZakkxYkdGWE5YcE1iVkpzVFVoVldRcGFSRVUxVG5wQmQwMVVRWGhOUkVGM1RVUkJkMWRuUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJDa0ZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUVLUVVGQlFVRkJRVmhFVkVVd1RWUkZlVTlFUlhoTmVtdDZUbFp2ZDJkalRYaERla0ZLUW1kT1ZrSkJXVlJCYTFKR1RWSjNkMGRuV1VSV1VWRkpSRUpPVHdwaU0wcHJZMjFvYkdGWE5IUldNbFo2WkVkYWFHSkhWblZOVWtGM1JHZFpSRlpSVVVoRVFXUk1kelJRUTNSdGVIVk5VbEYzUldkWlJGWlJVVXRFUVhSVUNscFhkREJoVnpsMVVsZHNkV042UldaTlFqQkhRVEZWUlVOM2QxZFVWMFp6WVZkT2NHSXpWbnBKUlU1c1kyNVJaMVV5Vm1wa1IyeDJZbXBGYUUxQ09FY0tRVEZWUlVGM2QxbGlWMFp6WVZkT2NHSXpWbnBNYms1c1lUTlNjR0l5Tld4aFZ6VjZURzFTYkUxVGIzZExRVmxLUzI5YVNXaDJZMDVCVVd0Q1JtaDBlZ3BrUjFadFdWYzBkVnBZVG5wYVdFcEJZekpXY21SSGJIWmliVlp3WW01TmRWcEhWWGRuWjBWcFRVRXdSME5UY1VkVFNXSXpSRkZGUWtGUlZVRkJORWxDQ2tSM1FYZG5aMFZMUVc5SlFrRlJSRVJCWmpOb2JEZEtXVEJZWTBadWFYbEZTbkJUVTBSeGJqQlBjVUp5TmxGUU5qVjFjMHBRVW5Rdk9GQmhSRzl4UW5VS2QwVlpWQzlPWVNzMlpuTm5VR3BETUhWTE9VUmFaMWRuTW5SSVYxZHZZVzVUWW14QlRXOTZOVkJJTmxvclV6UlRTRkphTjJVeVpFUkphbEJxWkdocWFBb3diVXhuTWxWTlR6VjVjREJXTnprM1IyZHpPV3hPZERaS1VtWklPREZOVGpKdllsaFhjelJPZEhwMFRFMTFSRFpsWjNGd2NqaGtSR0p5TXpSaFQzTTRDbkJyWkhWcE5WVmhkMVJhYTNONU5YQk1VRWh4TldOTmFFWkhiVEEyZGpZMVEweHZNRll5VUdRNUswdEJiMnRRY2xCalRqVkxURXRsWW5vM2JVeHdhellLVTAxbFJWaFBTMUEwYVdSRmNYaDVVVGRQTjJaQ2RVaE5aV1J6VVdoMUszQnlXVE56YVROQ1ZYbExabEYwVURWRFdtNVlNbUp3TUhkTFNIaFlNVEpFV0FveGJtWkdTWFE1UkdKSGRraFVZM2xQZFU0cmJscE1VRUp0TTNaWGVHNTBlVWxKZGxaQlowMUNRVUZIYWxGcVFrRk5RV3RIUVRGVlpFVjNVVU5OUVVGM0NrVlJXVXBaU1ZwSlFWbGlORkZuUlVKQ1FWRkVRV2RsUVUxQmMwZEJNVlZrUkhkUlJVRjNTVVp2UkVGVVFtZE9Wa2hUVlVWRVJFRkxRbWRuY2tKblJVWUtRbEZqUkVGcVFVNUNaMnR4YUd0cFJ6bDNNRUpCVVZWR1FVRlBRMEZSUlVGSE1HWmFXVmxEVkdKa2FqRllXV01yTVZOdWIyRlFVaXQyU1RoRE9FTmhSQW80S3pCVldXaGtibmxWTkdkbllUQkNRV05FY2xrNVpUazBaVVZCZFRaYWNYbGpSalpHYWt4eFdGaGtRV0p2Y0hCWGIyTnlObFEyUjBReGVETXpRMnRzQ2xaQmNucEhMMHQ0VVc5b1IwUXlTbVZ4YTJoSlRXeEViMjE0U0U4M2EyRXpPU3RQWVRocE1uWlhURlo1YWxVNFFWcDJWMDFCY25WSVlUUkZSVTU1UnpjS2JGY3lRV0ZuWVVaTFJrTnlPVlJ1V0ZSbWNtUjRSMVpGWW5ZM1MxWlJObUprYUdjMWNEVlRhbkJYU0RFclRYRXdNM1ZTTTFwWVVFSlpaSGxXT0RNeE9RcHZNR3hXYWpGTFJra3lSRU5NTDJ4cFYybHpTbEp2YjJZck1XTlNNelZEZEdRd2QxbENZM0JDTmxSYWMyeE5ZMDlRYkRjMlpIZExkMHBuWlVwdk1sRm5DbHB6Wm0xak1uWkRNUzl4VDJ4T2RVNXhMekJVZW5wclZrZDJPRVZVVkRORFoyRlZLMVZZWlRSWVQxWjJhMk5qWldKS2JqSmtaejA5Q2kwdExTMHRSVTVFSUVORlVsUkpSa2xEUVZSRkxTMHRMUzBLJzsKICAgICAgICAkc2NyaXB0ID0gPDw8J0VPVCcKCmVycm9yX3JlcG9ydGluZygtMSk7CiRpbmZvID0gb3BlbnNzbF94NTA5X3BhcnNlKGJhc2U2NF9kZWNvZGUoJyVzJykpOwp2YXJfZHVtcChQSFBfVkVSU0lPTiwgJGluZm9bJ2lzc3VlciddWydlbWFpbEFkZHJlc3MnXSwgJGluZm9bJ3ZhbGlkRnJvbV90aW1lX3QnXSk7CgpFT1Q7CiAgICAgICAgJHNjcmlwdCA9ICc8Jy4iP3BocFxuIi5zcHJpbnRmKCRzY3JpcHQsICRjZXJ0KTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUGhwUHJvY2Vzcygkc2NyaXB0KTsKICAgICAgICAgICAgJHByb2Nlc3MtPm11c3RSdW4oKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIC8vIEluIHRoZSBjYXNlIG9mIGFueSBleGNlcHRpb25zIGp1c3QgYWNjZXB0IGl0IGlzIG5vdCBwb3NzaWJsZSB0bwogICAgICAgICAgICAvLyBkZXRlcm1pbmUgdGhlIHNhZmV0eSBvZiBvcGVuc3NsX3g1MDlfcGFyc2UgYW5kIGJhaWwgb3V0LgogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZSA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dCA9IHByZWdfc3BsaXQoJ3tccj9cbn0nLCB0cmltKCRwcm9jZXNzLT5nZXRPdXRwdXQoKSkpOwogICAgICAgICRlcnJvck91dHB1dCA9IHRyaW0oJHByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwoKICAgICAgICBpZiAoCiAgICAgICAgICAgIGlzX2FycmF5KCRvdXRwdXQpCiAgICAgICAgICAgICYmIGNvdW50KCRvdXRwdXQpID09PSAzCiAgICAgICAgICAgICYmICRvdXRwdXRbMF0gPT09IHNwcmludGYoJ3N0cmluZyglZCkgIiVzIicsIHN0cmxlbihQSFBfVkVSU0lPTiksIFBIUF9WRVJTSU9OKQogICAgICAgICAgICAmJiAkb3V0cHV0WzFdID09PSAnc3RyaW5nKDI3KSAic3RlZmFuLmVzc2VyQHNla3Rpb25laW5zLmRlIicKICAgICAgICAgICAgJiYgJG91dHB1dFsyXSA9PT0gJ2ludCgtMSknCiAgICAgICAgICAgICYmIHByZWdfbWF0Y2goJ3tvcGVuc3NsX3g1MDlfcGFyc2VcKFwpOiBpbGxlZ2FsICg/OkFTTjEgZGF0YSB0eXBlIGZvcnxsZW5ndGggaW4pIHRpbWVzdGFtcCBpbiAtIG9uIGxpbmUgXGQrfScsICRlcnJvck91dHB1dCkKICAgICAgICApIHsKICAgICAgICAgICAgLy8gVGhpcyBQSFAgaGFzIHRoZSBmaXggYmFja3BvcnRlZCBwcm9iYWJseSBieSBhIGRpc3RybyBzZWN1cml0eSB0ZWFtLgogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZSA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogUmVzZXRzIHRoZSBzdGF0aWMgY2FjaGVzCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXNldCgpCiAgICB7CiAgICAgICAgc2VsZjo6JGNhRmlsZVZhbGlkaXR5ID0gYXJyYXkoKTsKICAgICAgICBzZWxmOjokY2FQYXRoID0gbnVsbDsKICAgICAgICBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRuYW1lCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRFbnZWYXJpYWJsZSgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJF9TRVJWRVJbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJF9TRVJWRVJbJG5hbWVdOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBIUF9TQVBJID09PSAnY2xpJyAmJiAoJHZhbHVlID0gZ2V0ZW52KCRuYW1lKSkgIT09IGZhbHNlICYmICR2YWx1ZSAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmd8ZmFsc2UgJGNlcnRGaWxlCiAgICAgKiBAcGFyYW0gIExvZ2dlckludGVyZmFjZXxudWxsICRsb2dnZXIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjYUZpbGVVc2FibGUoJGNlcnRGaWxlLCBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlciA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICRjZXJ0RmlsZQogICAgICAgICAgICAmJiBzdGF0aWM6OmlzRmlsZSgkY2VydEZpbGUsICRsb2dnZXIpCiAgICAgICAgICAgICYmIHN0YXRpYzo6aXNSZWFkYWJsZSgkY2VydEZpbGUsICRsb2dnZXIpCiAgICAgICAgICAgICYmIHN0YXRpYzo6dmFsaWRhdGVDYUZpbGUoJGNlcnRGaWxlLCAkbG9nZ2VyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nfGZhbHNlICRjZXJ0RGlyCiAgICAgKiBAcGFyYW0gIExvZ2dlckludGVyZmFjZXxudWxsICRsb2dnZXIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjYURpclVzYWJsZSgkY2VydERpciwgTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiAkY2VydERpcgogICAgICAgICAgICAmJiBzdGF0aWM6OmlzRGlyKCRjZXJ0RGlyLCAkbG9nZ2VyKQogICAgICAgICAgICAmJiBzdGF0aWM6OmlzUmVhZGFibGUoJGNlcnREaXIsICRsb2dnZXIpCiAgICAgICAgICAgICYmIHN0YXRpYzo6Z2xvYigkY2VydERpciAuICcvKicsICRsb2dnZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJGNlcnRGaWxlCiAgICAgKiBAcGFyYW0gIExvZ2dlckludGVyZmFjZXxudWxsICRsb2dnZXIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc0ZpbGUoJGNlcnRGaWxlLCBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlciA9IG51bGwpCiAgICB7CiAgICAgICAgJGlzRmlsZSA9IEBpc19maWxlKCRjZXJ0RmlsZSk7CiAgICAgICAgaWYgKCEkaXNGaWxlICYmICRsb2dnZXIpIHsKICAgICAgICAgICAgJGxvZ2dlci0+ZGVidWcoc3ByaW50ZignQ2hlY2tlZCBDQSBmaWxlICVzIGRvZXMgbm90IGV4aXN0IG9yIGl0IGlzIG5vdCBhIGZpbGUuJywgJGNlcnRGaWxlKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGlzRmlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRjZXJ0RGlyCiAgICAgKiBAcGFyYW0gIExvZ2dlckludGVyZmFjZXxudWxsICRsb2dnZXIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc0RpcigkY2VydERpciwgTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgICRpc0RpciA9IEBpc19kaXIoJGNlcnREaXIpOwogICAgICAgIGlmICghJGlzRGlyICYmICRsb2dnZXIpIHsKICAgICAgICAgICAgJGxvZ2dlci0+ZGVidWcoc3ByaW50ZignQ2hlY2tlZCBkaXJlY3RvcnkgJXMgZG9lcyBub3QgZXhpc3Qgb3IgaXQgaXMgbm90IGEgZGlyZWN0b3J5LicsICRjZXJ0RGlyKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGlzRGlyOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJGNlcnRGaWxlT3JEaXIKICAgICAqIEBwYXJhbSAgTG9nZ2VySW50ZXJmYWNlfG51bGwgJGxvZ2dlcgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzUmVhZGFibGUoJGNlcnRGaWxlT3JEaXIsIExvZ2dlckludGVyZmFjZSAkbG9nZ2VyID0gbnVsbCkKICAgIHsKICAgICAgICAkaXNSZWFkYWJsZSA9IEBpc19yZWFkYWJsZSgkY2VydEZpbGVPckRpcik7CiAgICAgICAgaWYgKCEkaXNSZWFkYWJsZSAmJiAkbG9nZ2VyKSB7CiAgICAgICAgICAgICRsb2dnZXItPmRlYnVnKHNwcmludGYoJ0NoZWNrZWQgZmlsZSBvciBkaXJlY3RvcnkgJXMgaXMgbm90IHJlYWRhYmxlLicsICRjZXJ0RmlsZU9yRGlyKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGlzUmVhZGFibGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0dGVybgogICAgICogQHBhcmFtICBMb2dnZXJJbnRlcmZhY2V8bnVsbCAkbG9nZ2VyCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2xvYigkcGF0dGVybiwgTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgICRjZXJ0cyA9IGdsb2IoJHBhdHRlcm4pOwogICAgICAgIGlmICgkY2VydHMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIGlmICgkbG9nZ2VyKSB7CiAgICAgICAgICAgICAgICAkbG9nZ2VyLT5kZWJ1ZyhzcHJpbnRmKCJBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gZmluZCBjZXJ0aWZpY2F0ZXMgZm9yIHBhdHRlcm46ICVzIiwgJHBhdHRlcm4pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoY291bnQoJGNlcnRzKSA9PT0gMCkgewogICAgICAgICAgICBpZiAoJGxvZ2dlcikgewogICAgICAgICAgICAgICAgJGxvZ2dlci0+ZGVidWcoc3ByaW50ZigiTm8gQ0EgZmlsZXMgZm91bmQgZm9yIHBhdHRlcm46ICVzIiwgJHBhdHRlcm4pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocCByZXR1cm4gYXJyYXkoCiAgICAncm9vdCcgPT4gYXJyYXkoCiAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnZGV2LXJlbGVhc2UtMi02LTAnLAogICAgICAgICd2ZXJzaW9uJyA9PiAnZGV2LXJlbGVhc2UtMi02LTAnLAogICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vLi4vJywKICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAncmVmZXJlbmNlJyA9PiAnMTk3MTJmMWE1ZTIwNjEyYTc1NTEyZDJmNDE4Y2RlNDU1YWRjNTEyNScsCiAgICAgICAgJ25hbWUnID0+ICd3cC1jbGkvd3AtY2xpLWJ1bmRsZScsCiAgICAgICAgJ2RldicgPT4gZmFsc2UsCiAgICApLAogICAgJ3ZlcnNpb25zJyA9PiBhcnJheSgKICAgICAgICAnY29tcG9zZXIvY2EtYnVuZGxlJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS4zLjEnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzEuMy4xLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uL2NhLWJ1bmRsZScsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnNGM2NzkxODZmMmFjYTRhYjZhMGYxYjBiOWNmOTI1MmRlY2I0NGQwYicsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ2NvbXBvc2VyL2NvbXBvc2VyJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMi4yLjUnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMi41LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uL2NvbXBvc2VyJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICcyMmM0MWVmMjc1YzdiYjY0ZmEyOGZiMmMwODcxYTM5NjY2ODMyY2I5JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXInID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcxLjAuMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMS4wLjAuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4vbWV0YWRhdGEtbWluaWZpZXInLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2M1NDlkMjM4Mjk1MzZmMGQwZTk4NGFhYWJiZjAyYWY5MWY0NDMyMDcnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdjb21wb3Nlci9wY3JlJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS4wLjEnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzEuMC4xLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uL3BjcmUnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzY3YTMyZDdkNmY5ZjU2MGI3MjZhYjI1YTA2MWIzOGZmM2E4MGM1NjAnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdjb21wb3Nlci9zZW12ZXInID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICczLjIuNycsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMy4yLjcuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4vc2VtdmVyJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdkZWFjMjcwNTZiNTdlNDZmYWYxMzZmYWU3YjQ0OWVlYWE3MTY2MWVlJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnY29tcG9zZXIvc3BkeC1saWNlbnNlcycgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuNS42JywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcxLjUuNi4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi9zcGR4LWxpY2Vuc2VzJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdhMzBkNDg3MTY5ZDc5OTc0NWNhNzI4MGJjOTBmZGZhNjkzNTM2OTAxJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnY29tcG9zZXIveGRlYnVnLWhhbmRsZXInID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcyLjAuNCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjQuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4veGRlYnVnLWhhbmRsZXInLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzBjMWEzOTI1ZWM1OGE0ZWM5OGU5OTJiOWM3ZDE3MWU5ZTE4NGJlMGEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdnZXR0ZXh0L2dldHRleHQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2NC44LjYnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzQuOC42LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9nZXR0ZXh0L2dldHRleHQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2JiZWI4ZjRkMzA3NzY2MzczOWFlY2I0NTUxYjIyZTcyMGMwZTllZmUnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdnZXR0ZXh0L2xhbmd1YWdlcycgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzIuOS4wJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjkuMC4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vZ2V0dGV4dC9sYW5ndWFnZXMnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2VkNTZkZDJjN2Y0MDI0Y2M5NTNlZDE4MGQyNWYwMmYyNjQwZTNmZmEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdqdXN0aW5yYWluYm93L2pzb24tc2NoZW1hJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnNS4yLjExJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICc1LjIuMTEuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzJhYjY3NDRiNzI5NmRlZDgwZjhjYzRmOTUwOWFiYmZmMzkzMzk5YWEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdtY2s4OS9wZWFzdCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YxLjEzLjExJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcxLjEzLjExLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9tY2s4OS9wZWFzdCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnNzhjNTc5NjZmM2RhNWYyMjM2MzZlYTA0MTdkNzFhYzZmZjYxZTQ3ZicsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ211c3RhY2hlL211c3RhY2hlJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMTQuMScsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4xNC4xLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9tdXN0YWNoZS9tdXN0YWNoZScsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnNTc5ZmZhNWM5NmUxZDI5MmMwNjBiM2RkNjI4MTFmZjAxYWQ4YzI0ZScsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ25iL294eW1lbCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YwLjEuMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMC4xLjAuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL25iL294eW1lbCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnY2JlNjI2ZWY1NWQ1YzRjYzliNWU2ZTM5MDRiMzk1ODYxZWE3NmUzYycsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3Bzci9sb2cnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcxLjEuNCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMS4xLjQuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3Bzci9sb2cnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2Q0OTY5NWI5MDljM2I3NjI4YjYyODlkYjU0NzlhMWMyMDQ2MDFmMTEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdwc3IvbG9nLWltcGxlbWVudGF0aW9uJyA9PiBhcnJheSgKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgICAgICdwcm92aWRlZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAwID0+ICcxLjAnLAogICAgICAgICAgICApLAogICAgICAgICksCiAgICAgICAgJ3JlYWN0L3Byb21pc2UnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi44LjAnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuOC4wLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9yZWFjdC9wcm9taXNlJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdmM2NmZjk2YTE5NzM2NzE0NTI0Y2EwZGQxZDQxMzBkZTczZGJiYmM0JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAncm1jY3VlL3JlcXVlc3RzJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjEuOC4xJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcxLjguMS4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vcm1jY3VlL3JlcXVlc3RzJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc4MmU2OTM2MzY2ZWFjM2FmNGQ4MzZjMThiOWQ4YzMxMDI4ZmU0Y2Q1JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnc2VsZC9qc29ubGludCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuOC4zJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcxLjguMy4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vc2VsZC9qc29ubGludCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnOWFkNmNlNzljMzQyZmJkNDRkZjEwZWE5NTUxMWExYjI0ZGVlNWI1NycsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3NlbGQvcGhhci11dGlscycgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuMi4wJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcxLjIuMC4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vc2VsZC9waGFyLXV0aWxzJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc5ZjM0NTJjOTNmZjQyMzQ2OWMwZDU2NDUwNDMxNTYyY2E0MjNkY2VlJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnc3ltZm9ueS9jb25zb2xlJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9zeW1mb255L2NvbnNvbGUnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2ExMGIxZGE2ZmM5MzA4MGMxODBiYmE3MjE5YjVmZjViNzUxOGZlODEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdzeW1mb255L2RlYnVnJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9zeW1mb255L2RlYnVnJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdhYjQyODg5ZGU1N2ZkZmNmY2MwNzU5YWIxMDJlMmZkNGVhNzJkY2FlJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnc3ltZm9ueS9maWxlc3lzdGVtJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9zeW1mb255L2ZpbGVzeXN0ZW0nLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U1OGQ3ODQxY2RkZmVkNmU4NDY4MjkwNDBkY2EyY2NhMGViYmJiYjMnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdzeW1mb255L2ZpbmRlcicgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vc3ltZm9ueS9maW5kZXInLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2I2YjZhZDNkYjNlZGIxYjRiMWMxODk2YjE5NzVmYjY4NDk5NGRlNmUnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICdzeW1mb255L3BvbHlmaWxsLWN0eXBlJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjEuMTkuMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMS4xOS4wLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi9zeW1mb255L3BvbHlmaWxsLWN0eXBlJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdhZWQ1OTY5MTNiNzBmYWU1N2JlNTNkODZmYWEyZTllZjg1YTIyOTdiJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZycgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YxLjE5LjAnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzEuMTkuMC4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZycsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnYjVmN2I5MzJlZTZmYTgwMmZjNzkyZWFiZDc3YzRjODgwODQ1MTdjZScsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3N5bWZvbnkvcHJvY2VzcycgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vc3ltZm9ueS9wcm9jZXNzJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdiODY0OGNmMWQ1YWYxMmE0NGE1MWQwN2VmOWJmOTgwOTIxZjE1ZmNhJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL2NhY2hlLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjknLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMC45LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL2NhY2hlLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzA1Mzc4NDQwZDhjNmQ0ZDJhMWE1ZTVjYmMxYmE5MmE1ZTRiZjFjNDAnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvY2hlY2tzdW0tY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjEuMicsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4xLjIuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvY2hlY2tzdW0tY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnZWM1OWEyNGFmMmNhOTdiNzcwYTQ3MDliMGExYzI0MWVlYjRiNGNmZicsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9jb25maWctY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjEuMycsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4xLjMuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvY29uZmlnLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2NkYWJiYzQ3ZGFlNDY0YTkzYjEwMzYxYjlhMThlODRjZjRlNzJmZTInLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvY29yZS1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4xJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMS4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICd3cC1jbGktcGFja2FnZScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS9jb3JlLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2E3NWQwNTJlYTAwMGI0ZjBlYzE0MTA2YzExMDgzNmIzNzZlOTVhNGYnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvY3Jvbi1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICd3cC1jbGktcGFja2FnZScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS9jcm9uLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2JiOWZkOTY0NWU5YTUyNzZkMDI0YTU5YWZmZWRhM2U2YWE4NTMwYmUnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvZGItY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuMjAnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMC4yMC4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICd3cC1jbGktcGFja2FnZScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS9kYi1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc3MDlmNThjMzBkMTc4YWZjZGVjYWY1NjA2OGNhOWY1ZTk4NWVkNmI5JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL2VtYmVkLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjExJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuMTEuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvZW1iZWQtY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnMDBhOTAxYTY2YWVjYjRkYTk0YThkYWNlNjEwZWIxMTM1ZmM4MjM4NicsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9lbnRpdHktY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjIuMScsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4yLjEuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvZW50aXR5LWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2Q3ZDA4YjA1YzY3NjUxYWJkZTVkNTcwODUxZTQ2NDk4YTE2NGNiMzQnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvZXZhbC1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4yJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMi4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICd3cC1jbGktcGFja2FnZScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS9ldmFsLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzUyMTMwNDBlYzIxNjdiMjc0OGYyNjg5ZmY2ZmUyNGI5MmEwNjRhOTAnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvZXhwb3J0LWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjExJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuMTEuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvZXhwb3J0LWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzhkZDEzN2UwYzczOWE1OWJiM2QzZGU2ODRhMjE5ZGJiMzQ0NzNlMTEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4xLjQnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMS40LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc2NDAxZDdlYTUxMDg0ZmFjNDAwMTBjMmZiMzA1YmU2NDA2NzVmMzg1JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL2kxOG4tY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjIuMTMnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMi4xMy4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICd3cC1jbGktcGFja2FnZScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS9pMThuLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzc3ZWNlOWUyYzkxNGJiNTZlYTcyYjllZTlmMDA1NTZkZWNlMDdiM2YnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvaW1wb3J0LWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjgnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMC44LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL2ltcG9ydC1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdhMDkyZTNhYmNjYTg0M2YxZmFiZjJlOWI3MDZhOTEyYWUwNzUzNTVmJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjEyJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuMTIuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvbGFuZ3VhZ2UtY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnYmJkYmE2OTE3OWZjOGRmNTk3OTI4NTg3MTExNTAwYzhhZGU0MGEzOCcsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjgnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMC44LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnZTY1NTA1Yzk3M2VhOTM0OTI1N2E0ZjMzYWM5ZWRjNzhkYjBiMTg5YScsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9tZWRpYS1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xMicsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEyLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL21lZGlhLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzdjYmYzMmM3ZmE2ODYzMTYxOWY4NWE5YmVhMGZiODBmY2ExMTliYTYnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMC42LjMnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzAuNi4zLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc2YWEwYjRkYTY5Y2U5ZTlhMmM4NDAyZGFiOGQ0M2NmMzJjNTgxY2M3JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL3BhY2thZ2UtY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjIuMicsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4yLjIuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvcGFja2FnZS1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICczNmFmZGVlMjFkMDIyZTYyNzA4NjdhYTBjYmZlZjZmNDUzMDQxODE0JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL3BocC1jbGktdG9vbHMnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MC4xMS4xMycsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMC4xMS4xMy4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICdsaWJyYXJ5JywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3BocC1jbGktdG9vbHMnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2EyODY2ODU1YWMxYWJjNTMwMDVjMTAyZTkwMTU1M2FkNTc3MmRjMDQnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvcmV3cml0ZS1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEwLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3Jld3JpdGUtY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnNTYyYTBhNWEwZDUxYmUwMDBkZTg3ZDdhOGE4NzBkZTEzMzgzZWNkNicsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9yb2xlLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjknLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMC45LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3JvbGUtY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnOWFiZDkzOTUyNTY1OTM1MDg0MTYwYmMzYmU0OWRmYjI0ODNiYjBiNicsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xNicsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjE2LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJzZkOTJmYjM2M2I4ZWQ3NDczYWY3ZjEyY2YzNDJhYWY5ZDJjOTZlODEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuMTYnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMC4xNi4wJywKICAgICAgICAgICAgJ3R5cGUnID0+ICd3cC1jbGktcGFja2FnZScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS9zZWFyY2gtcmVwbGFjZS1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICdkYmYyMTU2MGZkOTE3MTBiMjkwMGY1NjMxNDQ4NjU3ZDI4ZjJiMzgwJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL3NlcnZlci1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEwLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3NlcnZlci1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc1MGM4MWY0NWYxY2YwOWJjMGE1MmUzNTgyYjNlNTZkMjdjYTNjMzNjJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL3NoZWxsLWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjExJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuMTEuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnd3AtY2xpLXBhY2thZ2UnLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvc2hlbGwtY29tbWFuZCcsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnMjhhN2RlMzEzNGM5ZjA1OTkwMGQ4ZmE0YWVhMWQ3ZDYxODQ4MTQ1NCcsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kJyA9PiBhcnJheSgKICAgICAgICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEwLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3N1cGVyLWFkbWluLWNvbW1hbmQnLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U2NzA3ZjNhY2ZmZjA4OWQxOWM1YzU1YmJhMGZkNjZjZDdkNmMyZmEnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvd2lkZ2V0LWNvbW1hbmQnID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4xLjcnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzIuMS43LjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ3dwLWNsaS1wYWNrYWdlJywKICAgICAgICAgICAgJ2luc3RhbGxfcGF0aCcgPT4gX19ESVJfXyAuICcvLi4vd3AtY2xpL3dpZGdldC1jb21tYW5kJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICc2YWVkYWI3N2YxY2QyYTBmNTExYjYyMTEwYzI0NGMzMmI4NGRkNDI5JywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICAgICAnd3AtY2xpL3dwLWNsaScgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjYuMCcsCiAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAnMi42LjAuMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uL3dwLWNsaS93cC1jbGknLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gYXJyYXkoKSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJ2RlZTEzYzJiYWY2YmY5NzI0ODRhNjNmOGI4ZGFiNDhmNzIyMGYwOTUnLAogICAgICAgICAgICAnZGV2X3JlcXVpcmVtZW50JyA9PiBmYWxzZSwKICAgICAgICApLAogICAgICAgICd3cC1jbGkvd3AtY2xpLWJ1bmRsZScgPT4gYXJyYXkoCiAgICAgICAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ2Rldi1yZWxlYXNlLTItNi0wJywKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICdkZXYtcmVsZWFzZS0yLTYtMCcsCiAgICAgICAgICAgICd0eXBlJyA9PiAnbGlicmFyeScsCiAgICAgICAgICAgICdpbnN0YWxsX3BhdGgnID0+IF9fRElSX18gLiAnLy4uLy4uLycsCiAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAnMTk3MTJmMWE1ZTIwNjEyYTc1NTEyZDJmNDE4Y2RlNDU1YWRjNTEyNScsCiAgICAgICAgICAgICdkZXZfcmVxdWlyZW1lbnQnID0+IGZhbHNlLAogICAgICAgICksCiAgICAgICAgJ3dwLWNsaS93cC1jb25maWctdHJhbnNmb3JtZXInID0+IGFycmF5KAogICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS4zLjAnLAogICAgICAgICAgICAndmVyc2lvbicgPT4gJzEuMy4wLjAnLAogICAgICAgICAgICAndHlwZScgPT4gJ2xpYnJhcnknLAogICAgICAgICAgICAnaW5zdGFsbF9wYXRoJyA9PiBfX0RJUl9fIC4gJy8uLi93cC1jbGkvd3AtY29uZmlnLXRyYW5zZm9ybWVyJywKICAgICAgICAgICAgJ2FsaWFzZXMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdyZWZlcmVuY2UnID0+ICcyZTkwZWVmYzZiOGY1MTY2ZjUzYWE1NDE0ZmQ4ZjFhNTcyMTY0ZWYxJywKICAgICAgICAgICAgJ2Rldl9yZXF1aXJlbWVudCcgPT4gZmFsc2UsCiAgICAgICAgKSwKICAgICksCik7Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci94ZGVidWctaGFuZGxlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxYZGVidWdIYW5kbGVyOwoKdXNlIFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlOwp1c2UgUHNyXExvZ1xMb2dMZXZlbDsKCi8qKgogKiBAYXV0aG9yIEpvaG4gU3RldmVuc29uIDxqb2huLXN0ZXZlbnNvbkBibHVleW9uZGVyLmNvLnVrPgogKiBAaW50ZXJuYWwKICovCmNsYXNzIFN0YXR1cwp7CiAgICBjb25zdCBFTlZfUkVTVEFSVCA9ICdYREVCVUdfSEFORExFUl9SRVNUQVJUJzsKICAgIGNvbnN0IENIRUNLID0gJ0NoZWNrJzsKICAgIGNvbnN0IEVSUk9SID0gJ0Vycm9yJzsKICAgIGNvbnN0IElORk8gPSAnSW5mbyc7CiAgICBjb25zdCBOT1JFU1RBUlQgPSAnTm9SZXN0YXJ0JzsKICAgIGNvbnN0IFJFU1RBUlQgPSAnUmVzdGFydCc7CiAgICBjb25zdCBSRVNUQVJUSU5HID0gJ1Jlc3RhcnRpbmcnOwogICAgY29uc3QgUkVTVEFSVEVEID0gJ1Jlc3RhcnRlZCc7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkZGVidWc7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRlbnZBbGxvd1hkZWJ1ZzsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJpdmF0ZSAkbG9hZGVkOwoKICAgIC8qKiBAdmFyIExvZ2dlckludGVyZmFjZXxudWxsICovCiAgICBwcml2YXRlICRsb2dnZXI7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkbW9kZU9mZjsKCiAgICAgLyoqIEB2YXIgZmxvYXQgKi8KICAgIHByaXZhdGUgJHRpbWU7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGVudkFsbG93WGRlYnVnIFByZWZpeGVkIF9BTExPV19YREVCVUcgbmFtZQogICAgICogQHBhcmFtIGJvb2wgJGRlYnVnIFdoZXRoZXIgZGVidWcgb3V0cHV0IGlzIHJlcXVpcmVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZW52QWxsb3dYZGVidWcsICRkZWJ1ZykKICAgIHsKICAgICAgICAkc3RhcnQgPSBnZXRlbnYoc2VsZjo6RU5WX1JFU1RBUlQpOwogICAgICAgIFByb2Nlc3M6OnNldEVudihzZWxmOjpFTlZfUkVTVEFSVCk7CiAgICAgICAgJHRoaXMtPnRpbWUgPSBpc19udW1lcmljKCRzdGFydCkgPyByb3VuZCgobWljcm90aW1lKHRydWUpIC0gJHN0YXJ0KSAqIDEwMDApIDogMDsKCiAgICAgICAgJHRoaXMtPmVudkFsbG93WGRlYnVnID0gJGVudkFsbG93WGRlYnVnOwogICAgICAgICR0aGlzLT5kZWJ1ZyA9ICRkZWJ1ZyAmJiBkZWZpbmVkKCdTVERFUlInKTsKICAgICAgICAkdGhpcy0+bW9kZU9mZiA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIExvZ2dlckludGVyZmFjZSAkbG9nZ2VyCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2dnZXIoTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZ2dlciA9ICRsb2dnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxscyBhIGhhbmRsZXIgbWV0aG9kIHRvIHJlcG9ydCBhIG1lc3NhZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcCBUaGUgaGFuZGxlciBjb25zdGFudAogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRkYXRhIERhdGEgcmVxdWlyZWQgYnkgdGhlIGhhbmRsZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiAkb3AgaXMgbm90IGtub3duCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXBvcnQoJG9wLCAkZGF0YSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmxvZ2dlciAhPT0gbnVsbCB8fCAkdGhpcy0+ZGVidWcpIHsKICAgICAgICAgICAgJGNhbGxhYmxlID0gYXJyYXkoJHRoaXMsICdyZXBvcnQnLiRvcCk7CgogICAgICAgICAgICBpZiAoIWlzX2NhbGxhYmxlKCRjYWxsYWJsZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdVbmtub3duIG9wIGhhbmRsZXI6ICcuJG9wKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBhcmFtcyA9ICRkYXRhICE9PSBudWxsID8gJGRhdGEgOiBhcnJheSgpOwogICAgICAgICAgICBjYWxsX3VzZXJfZnVuY19hcnJheSgkY2FsbGFibGUsIGFycmF5KCRwYXJhbXMpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBPdXRwdXRzIGEgc3RhdHVzIG1lc3NhZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG91dHB1dCgkdGV4dCwgJGxldmVsID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmxvZ2dlciAhPT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+bG9nZ2VyLT5sb2coJGxldmVsICE9PSBudWxsID8gJGxldmVsOiBMb2dMZXZlbDo6REVCVUcsICR0ZXh0KTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+ZGVidWcpIHsKICAgICAgICAgICAgZndyaXRlKFNUREVSUiwgc3ByaW50ZigneGRlYnVnLWhhbmRsZXJbJWRdICVzJywgZ2V0bXlwaWQoKSwgJHRleHQuUEhQX0VPTCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxvYWRlZAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcG9ydENoZWNrKCRsb2FkZWQpCiAgICB7CiAgICAgICAgbGlzdCgkdmVyc2lvbiwgJG1vZGUpID0gZXhwbG9kZSgnfCcsICRsb2FkZWQpOwoKICAgICAgICBpZiAoJHZlcnNpb24gIT09ICcnKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkZWQgPSAnKCcuJHZlcnNpb24uJyknLigkbW9kZSAhPT0gJycgPyAnIG1vZGU9Jy4kbW9kZSA6ICcnKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPm1vZGVPZmYgPSAkbW9kZSA9PT0gJ29mZic7CiAgICAgICAgJHRoaXMtPm91dHB1dCgnQ2hlY2tpbmcgJy4kdGhpcy0+ZW52QWxsb3dYZGVidWcpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZXJyb3IKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXBvcnRFcnJvcigkZXJyb3IpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dChzcHJpbnRmKCdObyByZXN0YXJ0ICglcyknLCAkZXJyb3IpLCBMb2dMZXZlbDo6V0FSTklORyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbmZvCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVwb3J0SW5mbygkaW5mbykKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0KCRpbmZvKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcG9ydE5vUmVzdGFydCgpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dCgkdGhpcy0+Z2V0TG9hZGVkTWVzc2FnZSgpKTsKCiAgICAgICAgaWYgKCR0aGlzLT5sb2FkZWQgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRleHQgPSBzcHJpbnRmKCdObyByZXN0YXJ0ICglcyknLCAkdGhpcy0+Z2V0RW52QWxsb3coKSk7CiAgICAgICAgICAgIGlmICghKChib29sKSBnZXRlbnYoJHRoaXMtPmVudkFsbG93WGRlYnVnKSkpIHsKICAgICAgICAgICAgICAgICR0ZXh0IC49ICcgQWxsb3dlZCBieSAnLigkdGhpcy0+bW9kZU9mZiA/ICdtb2RlJyA6ICdhcHBsaWNhdGlvbicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQoJHRleHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcG9ydFJlc3RhcnQoKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQoJHRoaXMtPmdldExvYWRlZE1lc3NhZ2UoKSk7CiAgICAgICAgUHJvY2Vzczo6c2V0RW52KHNlbGY6OkVOVl9SRVNUQVJULCAoc3RyaW5nKSBtaWNyb3RpbWUodHJ1ZSkpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVwb3J0UmVzdGFydGVkKCkKICAgIHsKICAgICAgICAkbG9hZGVkID0gJHRoaXMtPmdldExvYWRlZE1lc3NhZ2UoKTsKICAgICAgICAkdGV4dCA9IHNwcmludGYoJ1Jlc3RhcnRlZCAoJWQgbXMpLiAlcycsICR0aGlzLT50aW1lLCAkbG9hZGVkKTsKICAgICAgICAkbGV2ZWwgPSAkdGhpcy0+bG9hZGVkICE9PSBudWxsID8gTG9nTGV2ZWw6OldBUk5JTkcgOiBudWxsOwogICAgICAgICR0aGlzLT5vdXRwdXQoJHRleHQsICRsZXZlbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tYW5kCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVwb3J0UmVzdGFydGluZygkY29tbWFuZCkKICAgIHsKICAgICAgICAkdGV4dCA9IHNwcmludGYoJ1Byb2Nlc3MgcmVzdGFydGluZyAoJXMpJywgJHRoaXMtPmdldEVudkFsbG93KCkpOwogICAgICAgICR0aGlzLT5vdXRwdXQoJHRleHQpOwogICAgICAgICR0ZXh0ID0gJ1J1bm5pbmcgJy4kY29tbWFuZDsKICAgICAgICAkdGhpcy0+b3V0cHV0KCR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIF9BTExPV19YREVCVUcgZW52aXJvbm1lbnQgdmFyaWFibGUgYXMgbmFtZT12YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RW52QWxsb3coKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZW52QWxsb3dYZGVidWcuJz0nLmdldGVudigkdGhpcy0+ZW52QWxsb3dYZGVidWcpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgWGRlYnVnIHN0YXR1cyBhbmQgdmVyc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0TG9hZGVkTWVzc2FnZSgpCiAgICB7CiAgICAgICAgJGxvYWRlZCA9ICR0aGlzLT5sb2FkZWQgIT09IG51bGwgPyBzcHJpbnRmKCdsb2FkZWQgJXMnLCAkdGhpcy0+bG9hZGVkKSA6ICdub3QgbG9hZGVkJzsKICAgICAgICByZXR1cm4gJ1RoZSBYZGVidWcgZXh0ZW5zaW9uIGlzICcuJGxvYWRlZDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIveGRlYnVnLWhhbmRsZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcWGRlYnVnSGFuZGxlcjsKCi8qKgogKiBAYXV0aG9yIEpvaG4gU3RldmVuc29uIDxqb2huLXN0ZXZlbnNvbkBibHVleW9uZGVyLmNvLnVrPgogKgogKiBAcGhwc3Rhbi10eXBlIHJlc3RhcnREYXRhIGFycmF5e3RtcEluaTogc3RyaW5nLCBzY2FubmVkSW5pczogYm9vbCwgc2NhbkRpcjogZmFsc2V8c3RyaW5nLCBwaHByYzogZmFsc2V8c3RyaW5nLCBpbmlzOiBzdHJpbmdbXSwgc2tpcHBlZDogc3RyaW5nfQogKi8KY2xhc3MgUGhwQ29uZmlnCnsKICAgIC8qKgogICAgICogVXNlIHRoZSBvcmlnaW5hbCBQSFAgY29uZmlndXJhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10gRW1wdHkgYXJyYXkgb2YgUEhQIGNsaSBvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1c2VPcmlnaW5hbCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmdldERhdGFBbmRSZXNldCgpOwogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogVXNlIHN0YW5kYXJkIHJlc3RhcnQgc2V0dGluZ3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIFBIUCBjbGkgb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXNlU3RhbmRhcmQoKQogICAgewogICAgICAgICRkYXRhID0gJHRoaXMtPmdldERhdGFBbmRSZXNldCgpOwogICAgICAgIGlmICgkZGF0YSAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJy1uJywgJy1jJywgJGRhdGFbJ3RtcEluaSddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogVXNlIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBwZXJzaXN0IHNldHRpbmdzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXSBFbXB0eSBhcnJheSBvZiBQSFAgY2xpIG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVzZVBlcnNpc3RlbnQoKQogICAgewogICAgICAgICRkYXRhID0gJHRoaXMtPmdldERhdGFBbmRSZXNldCgpOwogICAgICAgIGlmICgkZGF0YSAhPT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+dXBkYXRlRW52KCdQSFBSQycsICRkYXRhWyd0bXBJbmknXSk7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVFbnYoJ1BIUF9JTklfU0NBTl9ESVInLCAnJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgcmVzdGFydCBkYXRhIGlmIGF2YWlsYWJsZSBhbmQgcmVzZXRzIHRoZSBlbnZpcm9ubWVudAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICogQHBocHN0YW4tcmV0dXJuIHJlc3RhcnREYXRhfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXREYXRhQW5kUmVzZXQoKQogICAgewogICAgICAgICRkYXRhID0gWGRlYnVnSGFuZGxlcjo6Z2V0UmVzdGFydFNldHRpbmdzKCk7CiAgICAgICAgaWYgKCRkYXRhICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVFbnYoJ1BIUFJDJywgJGRhdGFbJ3BocHJjJ10pOwogICAgICAgICAgICAkdGhpcy0+dXBkYXRlRW52KCdQSFBfSU5JX1NDQU5fRElSJywgJGRhdGFbJ3NjYW5EaXInXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBVcGRhdGVzIGEgcmVzdGFydCBzZXR0aW5ncyB2YWx1ZSBpbiB0aGUgZW52aXJvbm1lbnQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfGZhbHNlICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVwZGF0ZUVudigkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIFByb2Nlc3M6OnNldEVudigkbmFtZSwgZmFsc2UgIT09ICR2YWx1ZSA/ICR2YWx1ZSA6IG51bGwpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci94ZGVidWctaGFuZGxlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxYZGVidWdIYW5kbGVyOwoKdXNlIENvbXBvc2VyXFBjcmVcUHJlZzsKdXNlIFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqCiAqIEBwaHBzdGFuLWltcG9ydC10eXBlIHJlc3RhcnREYXRhIGZyb20gUGhwQ29uZmlnCiAqLwpjbGFzcyBYZGVidWdIYW5kbGVyCnsKICAgIGNvbnN0IFNVRkZJWF9BTExPVyA9ICdfQUxMT1dfWERFQlVHJzsKICAgIGNvbnN0IFNVRkZJWF9JTklTID0gJ19PUklHSU5BTF9JTklTJzsKICAgIGNvbnN0IFJFU1RBUlRfSUQgPSAnaW50ZXJuYWwnOwogICAgY29uc3QgUkVTVEFSVF9TRVRUSU5HUyA9ICdYREVCVUdfSEFORExFUl9TRVRUSU5HUyc7CiAgICBjb25zdCBERUJVRyA9ICdYREVCVUdfSEFORExFUl9ERUJVRyc7CgogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByb3RlY3RlZCAkdG1wSW5pOwoKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgc3RhdGljICRpblJlc3RhcnQ7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlIHN0YXRpYyAkbmFtZTsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHNraXBwZWQ7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHhkZWJ1Z0FjdGl2ZTsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHhkZWJ1Z01vZGU7CgogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByaXZhdGUgc3RhdGljICR4ZGVidWdWZXJzaW9uOwoKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGNsaTsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJpdmF0ZSAkZGVidWc7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRlbnZBbGxvd1hkZWJ1ZzsKCiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGVudk9yaWdpbmFsSW5pczsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRwZXJzaXN0ZW50OwoKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcml2YXRlICRzY3JpcHQ7CgogICAgLyoqIEB2YXIgU3RhdHVzICovCiAgICBwcml2YXRlICRzdGF0dXNXcml0ZXI7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvcgogICAgICoKICAgICAqIFRoZSAkZW52UHJlZml4IGlzIHVzZWQgdG8gY3JlYXRlIGRpc3RpbmN0IGVudmlyb25tZW50IHZhcmlhYmxlcy4gSXQgaXMKICAgICAqIHVwcGVyY2FzZWQgYW5kIHByZXBlbmRlZCB0byB0aGUgZGVmYXVsdCBiYXNlIHZhbHVlcy4gRm9yIGV4YW1wbGUgJ215YXBwJwogICAgICogd291bGQgcmVzdWx0IGluIE1ZQVBQX0FMTE9XX1hERUJVRyBhbmQgTVlBUFBfT1JJR0lOQUxfSU5JUy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlbnZQcmVmaXggVmFsdWUgdXNlZCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHBhcmFtZXRlciBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZW52UHJlZml4KQogICAgewogICAgICAgIGlmICghaXNfc3RyaW5nKCRlbnZQcmVmaXgpIHx8ICRlbnZQcmVmaXggPT09ICcnKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignSW52YWxpZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXInKTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRuYW1lID0gc3RydG91cHBlcigkZW52UHJlZml4KTsKICAgICAgICAkdGhpcy0+ZW52QWxsb3dYZGVidWcgPSBzZWxmOjokbmFtZS5zZWxmOjpTVUZGSVhfQUxMT1c7CiAgICAgICAgJHRoaXMtPmVudk9yaWdpbmFsSW5pcyA9IHNlbGY6OiRuYW1lLnNlbGY6OlNVRkZJWF9JTklTOwoKICAgICAgICBzZWxmOjpzZXRYZGVidWdEZXRhaWxzKCk7CiAgICAgICAgc2VsZjo6JGluUmVzdGFydCA9IGZhbHNlOwoKICAgICAgICBpZiAoJHRoaXMtPmNsaSA9IFBIUF9TQVBJID09PSAnY2xpJykgewogICAgICAgICAgICAkdGhpcy0+ZGVidWcgPSAoc3RyaW5nKSBnZXRlbnYoc2VsZjo6REVCVUcpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0YXR1c1dyaXRlciA9IG5ldyBTdGF0dXMoJHRoaXMtPmVudkFsbG93WGRlYnVnLCAoYm9vbCkgJHRoaXMtPmRlYnVnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFjdGl2YXRlcyBzdGF0dXMgbWVzc2FnZSBvdXRwdXQgdG8gYSBQU1IzIGxvZ2dlcgogICAgICoKICAgICAqIEBwYXJhbSBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvZ2dlcihMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcikKICAgIHsKICAgICAgICAkdGhpcy0+c3RhdHVzV3JpdGVyLT5zZXRMb2dnZXIoJGxvZ2dlcik7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgbWFpbiBzY3JpcHQgbG9jYXRpb24gaWYgaXQgY2Fubm90IGJlIGNhbGxlZCBmcm9tIGFyZ3YKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzY3JpcHQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNYWluU2NyaXB0KCRzY3JpcHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnNjcmlwdCA9ICRzY3JpcHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUGVyc2lzdCB0aGUgc2V0dGluZ3MgdG8ga2VlcCBYZGVidWcgb3V0IG9mIHN1Yi1wcm9jZXNzZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQZXJzaXN0ZW50KCkKICAgIHsKICAgICAgICAkdGhpcy0+cGVyc2lzdGVudCA9IHRydWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIFhkZWJ1ZyBpcyBsb2FkZWQgYW5kIHRoZSBwcm9jZXNzIG5lZWRzIHRvIGJlIHJlc3RhcnRlZAogICAgICoKICAgICAqIFRoaXMgYmVoYXZpb3VyIGNhbiBiZSBkaXNhYmxlZCBieSBzZXR0aW5nIHRoZSBNWUFQUF9BTExPV19YREVCVUcKICAgICAqIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIDEuIFRoaXMgdmFyaWFibGUgaXMgdXNlZCBpbnRlcm5hbGx5IHNvIHRoYXQKICAgICAqIHRoZSByZXN0YXJ0ZWQgcHJvY2VzcyBpcyBjcmVhdGVkIG9ubHkgb25jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCkKICAgIHsKICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6Q0hFQ0ssIHNlbGY6OiR4ZGVidWdWZXJzaW9uLid8Jy5zZWxmOjokeGRlYnVnTW9kZSk7CiAgICAgICAgJGVudkFyZ3MgPSBleHBsb2RlKCd8JywgKHN0cmluZykgZ2V0ZW52KCR0aGlzLT5lbnZBbGxvd1hkZWJ1ZykpOwoKICAgICAgICBpZiAoISgoYm9vbCkgJGVudkFyZ3NbMF0pICYmICR0aGlzLT5yZXF1aXJlc1Jlc3RhcnQoc2VsZjo6JHhkZWJ1Z0FjdGl2ZSkpIHsKICAgICAgICAgICAgLy8gUmVzdGFydCByZXF1aXJlZAogICAgICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6UkVTVEFSVCk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPnByZXBhcmVSZXN0YXJ0KCkpIHsKICAgICAgICAgICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdldENvbW1hbmQoKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZXN0YXJ0KCRjb21tYW5kKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZjo6UkVTVEFSVF9JRCA9PT0gJGVudkFyZ3NbMF0gJiYgY291bnQoJGVudkFyZ3MpID09PSA1KSB7CiAgICAgICAgICAgIC8vIFJlc3RhcnRlZCwgc28gdW5zZXQgZW52aXJvbm1lbnQgdmFyaWFibGUgYW5kIHVzZSBzYXZlZCB2YWx1ZXMKICAgICAgICAgICAgJHRoaXMtPm5vdGlmeShTdGF0dXM6OlJFU1RBUlRFRCk7CgogICAgICAgICAgICBQcm9jZXNzOjpzZXRFbnYoJHRoaXMtPmVudkFsbG93WGRlYnVnKTsKICAgICAgICAgICAgc2VsZjo6JGluUmVzdGFydCA9IHRydWU7CgogICAgICAgICAgICBpZiAoc2VsZjo6JHhkZWJ1Z1ZlcnNpb24gPT09IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIFNraXBwZWQgdmVyc2lvbiBpcyBvbmx5IHNldCBpZiBYZGVidWcgaXMgbm90IGxvYWRlZAogICAgICAgICAgICAgICAgc2VsZjo6JHNraXBwZWQgPSAkZW52QXJnc1sxXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnRyeUVuYWJsZVNpZ25hbHMoKTsKCiAgICAgICAgICAgIC8vIFB1dCByZXN0YXJ0IHNldHRpbmdzIGluIHRoZSBlbnZpcm9ubWVudAogICAgICAgICAgICAkdGhpcy0+c2V0RW52UmVzdGFydFNldHRpbmdzKCRlbnZBcmdzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm5vdGlmeShTdGF0dXM6Ok5PUkVTVEFSVCk7CiAgICAgICAgJHNldHRpbmdzID0gc2VsZjo6Z2V0UmVzdGFydFNldHRpbmdzKCk7CgogICAgICAgIGlmICgkc2V0dGluZ3MgIT09IG51bGwpIHsKICAgICAgICAgICAgLy8gQ2FsbGVkIHdpdGggZXhpc3Rpbmcgc2V0dGluZ3MsIHNvIHN5bmMgb3VyIHNldHRpbmdzCiAgICAgICAgICAgICR0aGlzLT5zeW5jU2V0dGluZ3MoJHNldHRpbmdzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHBocC5pbmkgbG9jYXRpb25zIHdpdGggYXQgbGVhc3Qgb25lIGVudHJ5CiAgICAgKgogICAgICogVGhlIGVxdWl2YWxlbnQgb2YgY2FsbGluZyBwaHBfaW5pX2xvYWRlZF9maWxlIHRoZW4gcGhwX2luaV9zY2FubmVkX2ZpbGVzLgogICAgICogVGhlIGxvYWRlZCBpbmkgbG9jYXRpb24gaXMgdGhlIGZpcnN0IGVudHJ5IGFuZCBtYXkgYmUgZW1wdHkuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEFsbEluaUZpbGVzKCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6JG5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgJGVudiA9IGdldGVudihzZWxmOjokbmFtZS5zZWxmOjpTVUZGSVhfSU5JUyk7CgogICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRlbnYpIHsKICAgICAgICAgICAgICAgIHJldHVybiBleHBsb2RlKFBBVEhfU0VQQVJBVE9SLCAkZW52KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHBhdGhzID0gYXJyYXkoKHN0cmluZykgcGhwX2luaV9sb2FkZWRfZmlsZSgpKTsKICAgICAgICAkc2Nhbm5lZCA9IHBocF9pbmlfc2Nhbm5lZF9maWxlcygpOwoKICAgICAgICBpZiAoJHNjYW5uZWQgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRwYXRocyA9IGFycmF5X21lcmdlKCRwYXRocywgYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnLCcsICRzY2FubmVkKSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYXRoczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgcmVzdGFydCBzZXR0aW5ncyBvciBudWxsCiAgICAgKgogICAgICogU2V0dGluZ3Mgd2lsbCBiZSBhdmFpbGFibGUgaWYgdGhlIGN1cnJlbnQgcHJvY2VzcyB3YXMgcmVzdGFydGVkLCBvcgogICAgICogY2FsbGVkIHdpdGggdGhlIHNldHRpbmdzIGZyb20gYW4gZXhpc3RpbmcgcmVzdGFydC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqIEBwaHBzdGFuLXJldHVybiByZXN0YXJ0RGF0YXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UmVzdGFydFNldHRpbmdzKCkKICAgIHsKICAgICAgICAkZW52QXJncyA9IGV4cGxvZGUoJ3wnLCAoc3RyaW5nKSBnZXRlbnYoc2VsZjo6UkVTVEFSVF9TRVRUSU5HUykpOwoKICAgICAgICBpZiAoY291bnQoJGVudkFyZ3MpICE9PSA2CiAgICAgICAgICAgIHx8ICghc2VsZjo6JGluUmVzdGFydCAmJiBwaHBfaW5pX2xvYWRlZF9maWxlKCkgIT09ICRlbnZBcmdzWzBdKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3RtcEluaScgPT4gJGVudkFyZ3NbMF0sCiAgICAgICAgICAgICdzY2FubmVkSW5pcycgPT4gKGJvb2wpICRlbnZBcmdzWzFdLAogICAgICAgICAgICAnc2NhbkRpcicgPT4gJyonID09PSAkZW52QXJnc1syXSA/IGZhbHNlIDogJGVudkFyZ3NbMl0sCiAgICAgICAgICAgICdwaHByYycgPT4gJyonID09PSAkZW52QXJnc1szXSA/IGZhbHNlIDogJGVudkFyZ3NbM10sCiAgICAgICAgICAgICdpbmlzJyA9PiBleHBsb2RlKFBBVEhfU0VQQVJBVE9SLCAkZW52QXJnc1s0XSksCiAgICAgICAgICAgICdza2lwcGVkJyA9PiAkZW52QXJnc1s1XSwKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgWGRlYnVnIHZlcnNpb24gdGhhdCB0cmlnZ2VyZWQgYSBzdWNjZXNzZnVsIHJlc3RhcnQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFNraXBwZWRWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gKHN0cmluZykgc2VsZjo6JHNraXBwZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgWGRlYnVnIGlzIGxvYWRlZCBhbmQgYWN0aXZlCiAgICAgKgogICAgICogdHJ1ZTogaWYgWGRlYnVnIGlzIGxvYWRlZCBhbmQgaXMgcnVubmluZyBpbiBhbiBhY3RpdmUgbW9kZS4KICAgICAqIGZhbHNlOiBpZiBYZGVidWcgaXMgbm90IGxvYWRlZCwgb3IgaXQgaXMgcnVubmluZyB3aXRoIHhkZWJ1Zy5tb2RlPW9mZi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1hkZWJ1Z0FjdGl2ZSgpCiAgICB7CiAgICAgICAgc2VsZjo6c2V0WGRlYnVnRGV0YWlscygpOwogICAgICAgIHJldHVybiBzZWxmOjokeGRlYnVnQWN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogQWxsb3dzIGFuIGV4dGVuZGluZyBjbGFzcyB0byBkZWNpZGUgaWYgdGhlcmUgc2hvdWxkIGJlIGEgcmVzdGFydAogICAgICoKICAgICAqIFRoZSBkZWZhdWx0IGlzIHRvIHJlc3RhcnQgaWYgWGRlYnVnIGlzIGxvYWRlZCBhbmQgaXRzIG1vZGUgaXMgbm90ICJvZmYiLgogICAgICogRG8gbm90IHR5cGVoaW50IGZvciAxLnggY29tcGF0aWJpbGl0eS4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGVmYXVsdCBUaGUgZGVmYXVsdCBiZWhhdmlvdXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgcHJvY2VzcyBzaG91bGQgcmVzdGFydAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcmVxdWlyZXNSZXN0YXJ0KCRkZWZhdWx0KQogICAgewogICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEFsbG93cyBhbiBleHRlbmRpbmcgY2xhc3MgdG8gYWNjZXNzIHRoZSB0bXBJbmkKICAgICAqCiAgICAgKiBEbyBub3QgdHlwZWhpbnQgZm9yIDEueCBjb21wYXRpYmlsaXR5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRjb21tYW5kCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZXN0YXJ0KCRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT5kb1Jlc3RhcnQoJGNvbW1hbmQpOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIHJlc3RhcnRlZCBjb21tYW5kIHRoZW4gZGVsZXRlcyB0aGUgdG1wIGluaQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkY29tbWFuZAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICogQHBocHN0YW4tcmV0dXJuIG5ldmVyCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9SZXN0YXJ0KGFycmF5ICRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT50cnlFbmFibGVTaWduYWxzKCk7CiAgICAgICAgJHRoaXMtPm5vdGlmeShTdGF0dXM6OlJFU1RBUlRJTkcsIGltcGxvZGUoJyAnLCAkY29tbWFuZCkpOwoKICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gNzA0MDApIHsKICAgICAgICAgICAgJGNtZCA9ICRjb21tYW5kOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjbWQgPSBQcm9jZXNzOjplc2NhcGVTaGVsbENvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICAgICBpZiAoZGVmaW5lZCgnUEhQX1dJTkRPV1NfVkVSU0lPTl9CVUlMRCcpKSB7CiAgICAgICAgICAgICAgICAvLyBPdXRlciBxdW90ZXMgcmVxdWlyZWQgb24gY21kIHN0cmluZyBiZWxvdyBQSFAgOAogICAgICAgICAgICAgICAgJGNtZCA9ICciJy4kY21kLiciJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHByb2Nlc3MgPSBwcm9jX29wZW4oJGNtZCwgYXJyYXkoKSwgJHBpcGVzKTsKICAgICAgICBpZiAoaXNfcmVzb3VyY2UoJHByb2Nlc3MpKSB7CiAgICAgICAgICAgICRleGl0Q29kZSA9IHByb2NfY2xvc2UoJHByb2Nlc3MpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkZXhpdENvZGUpKSB7CiAgICAgICAgICAgIC8vIFVubGlrZWx5IHRoYXQgcGhwIG9yIHRoZSBkZWZhdWx0IHNoZWxsIGNhbm5vdCBiZSBpbnZva2VkCiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpFUlJPUiwgJ1VuYWJsZSB0byByZXN0YXJ0IHByb2Nlc3MnKTsKICAgICAgICAgICAgJGV4aXRDb2RlID0gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPm5vdGlmeShTdGF0dXM6OklORk8sICdSZXN0YXJ0ZWQgcHJvY2VzcyBleGl0ZWQgJy4kZXhpdENvZGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5kZWJ1ZyA9PT0gJzInKSB7CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpJTkZPLCAnVGVtcCBpbmkgc2F2ZWQ6ICcuJHRoaXMtPnRtcEluaSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgQHVubGluaygoc3RyaW5nKSAkdGhpcy0+dG1wSW5pKTsKICAgICAgICB9CgogICAgICAgIGV4aXQoJGV4aXRDb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBldmVyeXRoaW5nIHdhcyB3cml0dGVuIGZvciB0aGUgcmVzdGFydAogICAgICoKICAgICAqIElmIGFueSBvZiB0aGUgZm9sbG93aW5nIGZhaWxzIChob3dldmVyIHVubGlrZWx5KSB3ZSBtdXN0IHJldHVybiBmYWxzZSB0bwogICAgICogc3RvcCBwb3RlbnRpYWwgcmVjdXJzaW9uOgogICAgICogICAtIHRtcCBpbmkgZmlsZSBjcmVhdGlvbgogICAgICogICAtIGVudmlyb25tZW50IHZhcmlhYmxlIGNyZWF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcHJlcGFyZVJlc3RhcnQoKQogICAgewogICAgICAgICRlcnJvciA9IG51bGw7CiAgICAgICAgJGluaUZpbGVzID0gc2VsZjo6Z2V0QWxsSW5pRmlsZXMoKTsKICAgICAgICAkc2Nhbm5lZEluaXMgPSBjb3VudCgkaW5pRmlsZXMpID4gMTsKICAgICAgICAkdG1wRGlyID0gc3lzX2dldF90ZW1wX2RpcigpOwoKICAgICAgICBpZiAoISR0aGlzLT5jbGkpIHsKICAgICAgICAgICAgJGVycm9yID0gJ1Vuc3VwcG9ydGVkIFNBUEk6ICcuUEhQX1NBUEk7CiAgICAgICAgfSBlbHNlaWYgKCFkZWZpbmVkKCdQSFBfQklOQVJZJykpIHsKICAgICAgICAgICAgJGVycm9yID0gJ1BIUCB2ZXJzaW9uIGlzIHRvbyBvbGQ6ICcuUEhQX1ZFUlNJT047CiAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+Y2hlY2tDb25maWd1cmF0aW9uKCRpbmZvKSkgewogICAgICAgICAgICAkZXJyb3IgPSAkaW5mbzsKICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5jaGVja1NjYW5EaXJDb25maWcoKSkgewogICAgICAgICAgICAkZXJyb3IgPSAnUEhQIHZlcnNpb24gZG9lcyBub3QgcmVwb3J0IHNjYW5uZWQgaW5pczogJy5QSFBfVkVSU0lPTjsKICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5jaGVja01haW5TY3JpcHQoKSkgewogICAgICAgICAgICAkZXJyb3IgPSAnVW5hYmxlIHRvIGFjY2VzcyBtYWluIHNjcmlwdDogJy4kdGhpcy0+c2NyaXB0OwogICAgICAgIH0gZWxzZWlmICghJHRoaXMtPndyaXRlVG1wSW5pKCRpbmlGaWxlcywgJHRtcERpciwgJGVycm9yKSkgewogICAgICAgICAgICAkZXJyb3IgPSAkZXJyb3IgIT09IG51bGwgPyAkZXJyb3IgOiAnVW5hYmxlIHRvIGNyZWF0ZSB0ZW1wIGluaSBmaWxlIGF0OiAnLiR0bXBEaXI7CiAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+c2V0RW52aXJvbm1lbnQoJHNjYW5uZWRJbmlzLCAkaW5pRmlsZXMpKSB7CiAgICAgICAgICAgICRlcnJvciA9ICdVbmFibGUgdG8gc2V0IGVudmlyb25tZW50IHZhcmlhYmxlcyc7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVycm9yICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpFUlJPUiwgJGVycm9yKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZXJyb3IgPT09IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHRtcCBpbmkgZmlsZSB3YXMgd3JpdHRlbgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkaW5pRmlsZXMgQWxsIGluaSBmaWxlcyB1c2VkIGluIHRoZSBjdXJyZW50IHByb2Nlc3MKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRtcERpciBUaGUgc3lzdGVtIHRlbXBvcmFyeSBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkZXJyb3IgU2V0IGJ5IG1ldGhvZCBpZiBpbmkgZmlsZSBjYW5ub3QgYmUgcmVhZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdyaXRlVG1wSW5pKGFycmF5ICRpbmlGaWxlcywgJHRtcERpciwgJiRlcnJvcikKICAgIHsKICAgICAgICBpZiAoKCR0bXBmaWxlID0gQHRlbXBuYW0oJHRtcERpciwgJycpKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnRtcEluaSA9ICR0bXBmaWxlOwoKICAgICAgICAvLyAkaW5pRmlsZXMgaGFzIGF0IGxlYXN0IG9uZSBpdGVtIGFuZCBpdCBtYXkgYmUgZW1wdHkKICAgICAgICBpZiAoJGluaUZpbGVzWzBdID09PSAnJykgewogICAgICAgICAgICBhcnJheV9zaGlmdCgkaW5pRmlsZXMpOwogICAgICAgIH0KCiAgICAgICAgJGNvbnRlbnQgPSAnJzsKICAgICAgICAkc2VjdGlvblJlZ2V4ID0gJy9eXHMqXFsoPzpQQVRIfEhPU1QpXHMqPS9taSc7CiAgICAgICAgJHhkZWJ1Z1JlZ2V4ID0gJy9eXHMqKHplbmRfZXh0ZW5zaW9uXHMqPS4qeGRlYnVnLiopJC9taSc7CgogICAgICAgIGZvcmVhY2ggKCRpbmlGaWxlcyBhcyAkZmlsZSkgewogICAgICAgICAgICAvLyBDaGVjayBmb3IgaW5hY2Nlc3NpYmxlIGluaSBmaWxlcwogICAgICAgICAgICBpZiAoKCRkYXRhID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlKSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkZXJyb3IgPSAnVW5hYmxlIHRvIHJlYWQgaW5pOiAnLiRmaWxlOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENoZWNrIGFuZCByZW1vdmUgZGlyZWN0aXZlcyBhZnRlciBIT1NUIGFuZCBQQVRIIHNlY3Rpb25zCiAgICAgICAgICAgIGlmIChQcmVnOjppc01hdGNoV2l0aE9mZnNldHMoJHNlY3Rpb25SZWdleCwgJGRhdGEsICRtYXRjaGVzLCBQUkVHX09GRlNFVF9DQVBUVVJFKSkgewogICAgICAgICAgICAgICAgJGRhdGEgPSBzdWJzdHIoJGRhdGEsIDAsICRtYXRjaGVzWzBdWzFdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY29udGVudCAuPSBQcmVnOjpyZXBsYWNlKCR4ZGVidWdSZWdleCwgJzskMScsICRkYXRhKS5QSFBfRU9MOwogICAgICAgIH0KCiAgICAgICAgLy8gTWVyZ2UgbG9hZGVkIHNldHRpbmdzIGludG8gb3VyIGluaSBjb250ZW50LCBpZiBpdCBpcyB2YWxpZAogICAgICAgICRjb25maWcgPSBwYXJzZV9pbmlfc3RyaW5nKCRjb250ZW50KTsKICAgICAgICAkbG9hZGVkID0gaW5pX2dldF9hbGwobnVsbCwgZmFsc2UpOwoKICAgICAgICBpZiAoZmFsc2UgPT09ICRjb25maWcgfHwgZmFsc2UgPT09ICRsb2FkZWQpIHsKICAgICAgICAgICAgJGVycm9yID0gJ1VuYWJsZSB0byBwYXJzZSBpbmkgZGF0YSc7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjb250ZW50IC49ICR0aGlzLT5tZXJnZUxvYWRlZENvbmZpZygkbG9hZGVkLCAkY29uZmlnKTsKCiAgICAgICAgLy8gV29yay1hcm91bmQgZm9yIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NzU5MzIKICAgICAgICAkY29udGVudCAuPSAnb3BjYWNoZS5lbmFibGVfY2xpPTAnLlBIUF9FT0w7CgogICAgICAgIHJldHVybiAoYm9vbCkgQGZpbGVfcHV0X2NvbnRlbnRzKCR0aGlzLT50bXBJbmksICRjb250ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgZm9yIHRoZSByZXN0YXJ0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENvbW1hbmQoKQogICAgewogICAgICAgICRwaHAgPSBhcnJheShQSFBfQklOQVJZKTsKICAgICAgICAkYXJncyA9IGFycmF5X3NsaWNlKCRfU0VSVkVSWydhcmd2J10sIDEpOwoKICAgICAgICBpZiAoISR0aGlzLT5wZXJzaXN0ZW50KSB7CiAgICAgICAgICAgIC8vIFVzZSBjb21tYW5kLWxpbmUgb3B0aW9ucwogICAgICAgICAgICBhcnJheV9wdXNoKCRwaHAsICctbicsICctYycsICR0aGlzLT50bXBJbmkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKCRwaHAsIGFycmF5KCR0aGlzLT5zY3JpcHQpLCAkYXJncyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlc3RhcnQgZW52aXJvbm1lbnQgdmFyaWFibGVzIHdlcmUgc2V0CiAgICAgKgogICAgICogTm8gbmVlZCB0byB1cGRhdGUgJF9TRVJWRVIgc2luY2UgdGhpcyBpcyBzZXQgaW4gdGhlIHJlc3RhcnRlZCBwcm9jZXNzLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRzY2FubmVkSW5pcyBXaGV0aGVyIHRoZXJlIHdlcmUgc2Nhbm5lZCBpbmkgZmlsZXMKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkaW5pRmlsZXMgQWxsIGluaSBmaWxlcyB1c2VkIGluIHRoZSBjdXJyZW50IHByb2Nlc3MKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXRFbnZpcm9ubWVudCgkc2Nhbm5lZEluaXMsIGFycmF5ICRpbmlGaWxlcykKICAgIHsKICAgICAgICAkc2NhbkRpciA9IGdldGVudignUEhQX0lOSV9TQ0FOX0RJUicpOwogICAgICAgICRwaHByYyA9IGdldGVudignUEhQUkMnKTsKCiAgICAgICAgLy8gTWFrZSBvcmlnaW5hbCBpbmlzIGF2YWlsYWJsZSB0byByZXN0YXJ0ZWQgcHJvY2VzcwogICAgICAgIGlmICghcHV0ZW52KCR0aGlzLT5lbnZPcmlnaW5hbEluaXMuJz0nLmltcGxvZGUoUEFUSF9TRVBBUkFUT1IsICRpbmlGaWxlcykpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cGVyc2lzdGVudCkgewogICAgICAgICAgICAvLyBVc2UgdGhlIGVudmlyb25tZW50IHRvIHBlcnNpc3QgdGhlIHNldHRpbmdzCiAgICAgICAgICAgIGlmICghcHV0ZW52KCdQSFBfSU5JX1NDQU5fRElSPScpIHx8ICFwdXRlbnYoJ1BIUFJDPScuJHRoaXMtPnRtcEluaSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gRmxhZyByZXN0YXJ0ZWQgcHJvY2VzcyBhbmQgc2F2ZSB2YWx1ZXMgZm9yIGl0IHRvIHVzZQogICAgICAgICRlbnZBcmdzID0gYXJyYXkoCiAgICAgICAgICAgIHNlbGY6OlJFU1RBUlRfSUQsCiAgICAgICAgICAgIHNlbGY6OiR4ZGVidWdWZXJzaW9uLAogICAgICAgICAgICAoaW50KSAkc2Nhbm5lZEluaXMsCiAgICAgICAgICAgIGZhbHNlID09PSAkc2NhbkRpciA/ICcqJyA6ICRzY2FuRGlyLAogICAgICAgICAgICBmYWxzZSA9PT0gJHBocHJjID8gJyonIDogJHBocHJjLAogICAgICAgICk7CgogICAgICAgIHJldHVybiBwdXRlbnYoJHRoaXMtPmVudkFsbG93WGRlYnVnLic9Jy5pbXBsb2RlKCd8JywgJGVudkFyZ3MpKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvZ3Mgc3RhdHVzIG1lc3NhZ2VzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3AgU3RhdHVzIGhhbmRsZXIgY29uc3RhbnQKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkZGF0YSBPcHRpb25hbCBkYXRhCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbm90aWZ5KCRvcCwgJGRhdGEgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5zdGF0dXNXcml0ZXItPnJlcG9ydCgkb3AsICRkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgZGVmYXVsdCwgY2hhbmdlZCBhbmQgY29tbWFuZC1saW5lIGluaSBzZXR0aW5ncwogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZFtdICRsb2FkZWRDb25maWcgQWxsIGN1cnJlbnQgaW5pIHNldHRpbmdzCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkaW5pQ29uZmlnIFNldHRpbmdzIGZyb20gdXNlciBpbmkgZmlsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1lcmdlTG9hZGVkQ29uZmlnKGFycmF5ICRsb2FkZWRDb25maWcsIGFycmF5ICRpbmlDb25maWcpCiAgICB7CiAgICAgICAgJGNvbnRlbnQgPSAnJzsKCiAgICAgICAgZm9yZWFjaCAoJGxvYWRlZENvbmZpZyBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgLy8gVmFsdWUgd2lsbCBlaXRoZXIgYmUgbnVsbCwgc3RyaW5nIG9yIGFycmF5IChISFZNIG9ubHkpCiAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCR2YWx1ZSkKICAgICAgICAgICAgICAgIHx8IHN0cnBvcygkbmFtZSwgJ3hkZWJ1ZycpID09PSAwCiAgICAgICAgICAgICAgICB8fCAkbmFtZSA9PT0gJ2FwYy5tbWFwX2ZpbGVfbWFzaycpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRpbmlDb25maWdbJG5hbWVdKSB8fCAkaW5pQ29uZmlnWyRuYW1lXSAhPT0gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAvLyBEb3VibGUtcXVvdGUgZXNjYXBlIGVhY2ggdmFsdWUKICAgICAgICAgICAgICAgICRjb250ZW50IC49ICRuYW1lLic9IicuYWRkY3NsYXNoZXMoJHZhbHVlLCAnXFwiJykuJyInLlBIUF9FT0w7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2NyaXB0IG5hbWUgY2FuIGJlIHVzZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja01haW5TY3JpcHQoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+c2NyaXB0KSB7CiAgICAgICAgICAgIC8vIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHNldCAtLSBmb3Igc3RhbmRhcmQgaW5wdXQKICAgICAgICAgICAgcmV0dXJuIGZpbGVfZXhpc3RzKCR0aGlzLT5zY3JpcHQpIHx8ICctLScgPT09ICR0aGlzLT5zY3JpcHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPnNjcmlwdCA9ICRfU0VSVkVSWydhcmd2J11bMF0pKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gVXNlIGEgYmFja3RyYWNlIHRvIHJlc29sdmUgUGhhciBhbmQgY2hkaXIgaXNzdWVzLgogICAgICAgICR0cmFjZSA9IGRlYnVnX2JhY2t0cmFjZShERUJVR19CQUNLVFJBQ0VfSUdOT1JFX0FSR1MpOwogICAgICAgICRtYWluID0gZW5kKCR0cmFjZSk7CgogICAgICAgIGlmICgkbWFpbiAhPT0gZmFsc2UgJiYgaXNzZXQoJG1haW5bJ2ZpbGUnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbGVfZXhpc3RzKCR0aGlzLT5zY3JpcHQgPSAkbWFpblsnZmlsZSddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgcmVzdGFydCBzZXR0aW5ncyB0byB0aGUgZW52aXJvbm1lbnQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGVudkFyZ3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXRFbnZSZXN0YXJ0U2V0dGluZ3MoJGVudkFyZ3MpCiAgICB7CiAgICAgICAgJHNldHRpbmdzID0gYXJyYXkoCiAgICAgICAgICAgIHBocF9pbmlfbG9hZGVkX2ZpbGUoKSwKICAgICAgICAgICAgJGVudkFyZ3NbMl0sCiAgICAgICAgICAgICRlbnZBcmdzWzNdLAogICAgICAgICAgICAkZW52QXJnc1s0XSwKICAgICAgICAgICAgZ2V0ZW52KCR0aGlzLT5lbnZPcmlnaW5hbEluaXMpLAogICAgICAgICAgICBzZWxmOjokc2tpcHBlZCwKICAgICAgICApOwoKICAgICAgICBQcm9jZXNzOjpzZXRFbnYoc2VsZjo6UkVTVEFSVF9TRVRUSU5HUywgaW1wbG9kZSgnfCcsICRzZXR0aW5ncykpOwogICAgfQoKICAgIC8qKgogICAgICogU3luY3Mgc2V0dGluZ3MgYW5kIHRoZSBlbnZpcm9ubWVudCBpZiBjYWxsZWQgd2l0aCBleGlzdGluZyBzZXR0aW5ncwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkc2V0dGluZ3MKICAgICAqIEBwaHBzdGFuLXBhcmFtIHJlc3RhcnREYXRhICRzZXR0aW5ncwogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN5bmNTZXR0aW5ncyhhcnJheSAkc2V0dGluZ3MpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSBnZXRlbnYoJHRoaXMtPmVudk9yaWdpbmFsSW5pcykpIHsKICAgICAgICAgICAgLy8gQ2FsbGVkIGJ5IGFub3RoZXIgYXBwLCBzbyBtYWtlIG9yaWdpbmFsIGluaXMgYXZhaWxhYmxlCiAgICAgICAgICAgIFByb2Nlc3M6OnNldEVudigkdGhpcy0+ZW52T3JpZ2luYWxJbmlzLCBpbXBsb2RlKFBBVEhfU0VQQVJBVE9SLCAkc2V0dGluZ3NbJ2luaXMnXSkpOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JHNraXBwZWQgPSAkc2V0dGluZ3NbJ3NraXBwZWQnXTsKICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6SU5GTywgJ1Byb2Nlc3MgY2FsbGVkIHdpdGggZXhpc3RpbmcgcmVzdGFydCBzZXR0aW5ncycpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBzY2FubmVkIGluaXMgYW5kIFBIUCBpcyBhYmxlIHRvIHJlcG9ydCB0aGVtCiAgICAgKgogICAgICogcGhwX2luaV9zY2FubmVkX2ZpbGVzIHdpbGwgZmFpbCB3aGVuIFBIUF9DT05GSUdfRklMRV9TQ0FOX0RJUiBpcyBlbXB0eS4KICAgICAqIEZpeGVkIGluIDcuMS4xMyBhbmQgNy4yLjEKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja1NjYW5EaXJDb25maWcoKQogICAgewogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA3MDExMyAmJiBQSFBfVkVSU0lPTl9JRCAhPT0gNzAyMDApIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKChzdHJpbmcpIGdldGVudignUEhQX0lOSV9TQ0FOX0RJUicpID09PSAnJykKICAgICAgICAgICAgfHwgUEhQX0NPTkZJR19GSUxFX1NDQU5fRElSICE9PSAnJzsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBhcmUgbm8ga25vd24gY29uZmlndXJhdGlvbiBpc3N1ZXMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbmZvIFNldCBieSBtZXRob2QKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrQ29uZmlndXJhdGlvbigmJGluZm8pCiAgICB7CiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3Byb2Nfb3BlbicpKSB7CiAgICAgICAgICAgICRpbmZvID0gJ3Byb2Nfb3BlbiBmdW5jdGlvbiBpcyBkaXNhYmxlZCc7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChleHRlbnNpb25fbG9hZGVkKCd1b3B6JykgJiYgISgoYm9vbCkgaW5pX2dldCgndW9wei5kaXNhYmxlJykpKSB7CiAgICAgICAgICAgIC8vIHVvcHogd29ya3MgYXQgb3Bjb2RlIGxldmVsIGFuZCBkaXNhYmxlcyBleGl0IGNhbGxzCiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3VvcHpfYWxsb3dfZXhpdCcpKSB7CiAgICAgICAgICAgICAgICBAdW9wel9hbGxvd19leGl0KHRydWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGluZm8gPSAndW9weiBleHRlbnNpb24gaXMgbm90IGNvbXBhdGlibGUnOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayBVTkMgcGF0aHMgd2hlbiB1c2luZyBjbWQuZXhlCiAgICAgICAgaWYgKGRlZmluZWQoJ1BIUF9XSU5ET1dTX1ZFUlNJT05fQlVJTEQnKSAmJiBQSFBfVkVSU0lPTl9JRCA8IDcwNDAwKSB7CiAgICAgICAgICAgICR3b3JraW5nRGlyID0gZ2V0Y3dkKCk7CgogICAgICAgICAgICBpZiAoJHdvcmtpbmdEaXIgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkaW5mbyA9ICd1bmFibGUgdG8gZGV0ZXJtaW5lIHdvcmtpbmcgZGlyZWN0b3J5JzsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkd29ya2luZ0RpciwgJ1xcXFwnKSkgewogICAgICAgICAgICAgICAgJGluZm8gPSAnY21kLmV4ZSBkb2VzIG5vdCBzdXBwb3J0IFVOQyBwYXRoczogJy4kd29ya2luZ0RpcjsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmFibGVzIGFzeW5jIHNpZ25hbHMgYW5kIGNvbnRyb2wgaW50ZXJydXB0cyBpbiB0aGUgcmVzdGFydGVkIHByb2Nlc3MKICAgICAqCiAgICAgKiBBdmFpbGFibGUgb24gVW5peCBQSFAgNy4xKyB3aXRoIHRoZSBwY250bCBleHRlbnNpb24gYW5kIFdpbmRvd3MgUEhQIDcuNCsuCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdHJ5RW5hYmxlU2lnbmFscygpCiAgICB7CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygncGNudGxfYXN5bmNfc2lnbmFscycpICYmIGZ1bmN0aW9uX2V4aXN0cygncGNudGxfc2lnbmFsJykpIHsKICAgICAgICAgICAgcGNudGxfYXN5bmNfc2lnbmFscyh0cnVlKTsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAnQXN5bmMgc2lnbmFscyBlbmFibGVkJzsKCiAgICAgICAgICAgIGlmICghc2VsZjo6JGluUmVzdGFydCkgewogICAgICAgICAgICAgICAgLy8gUmVzdGFydGluZywgc28gaWdub3JlIFNJR0lOVCBpbiBwYXJlbnQKICAgICAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsIFNJR19JR04pOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNfaW50KHBjbnRsX3NpZ25hbF9nZXRfaGFuZGxlcihTSUdJTlQpKSkgewogICAgICAgICAgICAgICAgLy8gUmVzdGFydGVkLCBubyBoYW5kbGVyIHNldCBzbyBmb3JjZSBkZWZhdWx0IGFjdGlvbgogICAgICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR0lOVCwgU0lHX0RGTCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghc2VsZjo6JGluUmVzdGFydCAmJiBmdW5jdGlvbl9leGlzdHMoJ3NhcGlfd2luZG93c19zZXRfY3RybF9oYW5kbGVyJykpIHsKICAgICAgICAgICAgLy8gUmVzdGFydGluZywgc28gc2V0IGEgaGFuZGxlciB0byBpZ25vcmUgQ1RSTCBldmVudHMgaW4gdGhlIHBhcmVudC4KICAgICAgICAgICAgLy8gVGhpcyBlbnN1cmVzIHRoYXQgQ1RSTCtDIGV2ZW50cyB3aWxsIGJlIGF2YWlsYWJsZSBpbiB0aGUgY2hpbGQKICAgICAgICAgICAgLy8gcHJvY2VzcyB3aXRob3V0IGhhdmluZyB0byBlbmFibGUgdGhlbSB0aGVyZSwgd2hpY2ggaXMgdW5yZWxpYWJsZS4KICAgICAgICAgICAgc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXIoZnVuY3Rpb24gKCRldnQpIHt9KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHN0YXRpYyBwcm9wZXJ0aWVzICR4ZGVidWdBY3RpdmUsICR4ZGVidWdWZXJzaW9uIGFuZCAkeGRlYnVnTW9kZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzZXRYZGVidWdEZXRhaWxzKCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6JHhkZWJ1Z0FjdGl2ZSAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzZWxmOjokeGRlYnVnQWN0aXZlID0gZmFsc2U7CiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCd4ZGVidWcnKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvbiA9IHBocHZlcnNpb24oJ3hkZWJ1ZycpOwogICAgICAgIHNlbGY6OiR4ZGVidWdWZXJzaW9uID0gJHZlcnNpb24gIT09IGZhbHNlID8gJHZlcnNpb24gOiAndW5rbm93bic7CgogICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoc2VsZjo6JHhkZWJ1Z1ZlcnNpb24sICczLjEnLCAnPj0nKSkgewogICAgICAgICAgICAkbW9kZXMgPSB4ZGVidWdfaW5mbygnbW9kZScpOwogICAgICAgICAgICBzZWxmOjokeGRlYnVnTW9kZSA9IGNvdW50KCRtb2RlcykgPT09IDAgPyAnb2ZmJyA6IGltcGxvZGUoJywnLCAkbW9kZXMpOwogICAgICAgICAgICBzZWxmOjokeGRlYnVnQWN0aXZlID0gc2VsZjo6JHhkZWJ1Z01vZGUgIT09ICdvZmYnOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBTZWUgaWYgeGRlYnVnLm1vZGUgaXMgc3VwcG9ydGVkIGluIHRoaXMgdmVyc2lvbgogICAgICAgICRpbmlNb2RlID0gaW5pX2dldCgneGRlYnVnLm1vZGUnKTsKICAgICAgICBpZiAoJGluaU1vZGUgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIEVudmlyb25tZW50IHZhbHVlIHdpbnMgYnV0IGNhbm5vdCBiZSBlbXB0eQogICAgICAgICRlbnZNb2RlID0gKHN0cmluZykgZ2V0ZW52KCdYREVCVUdfTU9ERScpOwogICAgICAgIGlmICgkZW52TW9kZSAhPT0gJycpIHsKICAgICAgICAgICAgc2VsZjo6JHhkZWJ1Z01vZGUgPSAkZW52TW9kZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWxmOjokeGRlYnVnTW9kZSA9ICRpbmlNb2RlICE9PSAnJyA/ICRpbmlNb2RlIDogJ29mZic7CiAgICAgICAgfQoKICAgICAgICAvLyBBbiBlbXB0eSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBpcyB0cmVhdGVkIGFzIG1vZGUgJ29mZicKICAgICAgICBpZiAoUHJlZzo6aXNNYXRjaCgnL14sKyQvJywgc3RyX3JlcGxhY2UoJyAnLCAnJywgc2VsZjo6JHhkZWJ1Z01vZGUpKSkgewogICAgICAgICAgICBzZWxmOjokeGRlYnVnTW9kZSA9ICdvZmYnOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JHhkZWJ1Z0FjdGl2ZSA9IHNlbGY6OiR4ZGVidWdNb2RlICE9PSAnb2ZmJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIveGRlYnVnLWhhbmRsZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcWGRlYnVnSGFuZGxlcjsKCnVzZSBDb21wb3NlclxQY3JlXFByZWc7CgovKioKICogUHJvY2VzcyB1dGlsaXR5IGZ1bmN0aW9ucwogKgogKiBAYXV0aG9yIEpvaG4gU3RldmVuc29uIDxqb2huLXN0ZXZlbnNvbkBibHVleW9uZGVyLmNvLnVrPgogKi8KY2xhc3MgUHJvY2Vzcwp7CiAgICAvKioKICAgICAqIEVzY2FwZXMgYSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIHNoZWxsIGFyZ3VtZW50LgogICAgICoKICAgICAqIEZyb20gaHR0cHM6Ly9naXRodWIuY29tL2pvaG5zdGV2ZW5zb24vd2luYm94LWFyZ3MKICAgICAqIE1JVCBMaWNlbnNlZCAoYykgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYXJnICBUaGUgYXJndW1lbnQgdG8gYmUgZXNjYXBlZAogICAgICogQHBhcmFtIGJvb2wgICAkbWV0YSBBZGRpdGlvbmFsbHkgZXNjYXBlIGNtZC5leGUgbWV0YSBjaGFyYWN0ZXJzCiAgICAgKiBAcGFyYW0gYm9vbCAkbW9kdWxlIFRoZSBhcmd1bWVudCBpcyB0aGUgbW9kdWxlIHRvIGludm9rZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBlc2NhcGVkIGFyZ3VtZW50CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXNjYXBlKCRhcmcsICRtZXRhID0gdHJ1ZSwgJG1vZHVsZSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghZGVmaW5lZCgnUEhQX1dJTkRPV1NfVkVSU0lPTl9CVUlMRCcpKSB7CiAgICAgICAgICAgIHJldHVybiAiJyIuc3RyX3JlcGxhY2UoIiciLCAiJ1xcJyciLCAkYXJnKS4iJyI7CiAgICAgICAgfQoKICAgICAgICAkcXVvdGUgPSBzdHJwYnJrKCRhcmcsICIgXHQiKSAhPT0gZmFsc2UgfHwgJGFyZyA9PT0gJyc7CgogICAgICAgICRhcmcgPSBQcmVnOjpyZXBsYWNlKCcvKFxcXFwqKSIvJywgJyQxJDFcXCInLCAkYXJnLCAtMSwgJGRxdW90ZXMpOwoKICAgICAgICBpZiAoJG1ldGEpIHsKICAgICAgICAgICAgJG1ldGEgPSAkZHF1b3RlcyB8fCBQcmVnOjppc01hdGNoKCcvJVteJV0rJS8nLCAkYXJnKTsKCiAgICAgICAgICAgIGlmICghJG1ldGEpIHsKICAgICAgICAgICAgICAgICRxdW90ZSA9ICRxdW90ZSB8fCBzdHJwYnJrKCRhcmcsICdeJnw8PigpJykgIT09IGZhbHNlOwogICAgICAgICAgICB9IGVsc2VpZiAoJG1vZHVsZSAmJiAhJGRxdW90ZXMgJiYgJHF1b3RlKSB7CiAgICAgICAgICAgICAgICAkbWV0YSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHF1b3RlKSB7CiAgICAgICAgICAgICRhcmcgPSAnIicuKFByZWc6OnJlcGxhY2UoJy8oXFxcXCopJC8nLCAnJDEkMScsICRhcmcpKS4nIic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1ldGEpIHsKICAgICAgICAgICAgJGFyZyA9IFByZWc6OnJlcGxhY2UoJy8oWyJeJnw8PigpJV0pLycsICdeJDEnLCAkYXJnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYXJnOwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhbiBhcnJheSBvZiBhcmd1bWVudHMgdGhhdCBtYWtlIHVwIGEgc2hlbGwgY29tbWFuZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkYXJncyBBcmd1bWVudCBsaXN0LCB3aXRoIHRoZSBtb2R1bGUgbmFtZSBmaXJzdAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBlc2NhcGVkIGNvbW1hbmQgbGluZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVzY2FwZVNoZWxsQ29tbWFuZChhcnJheSAkYXJncykKICAgIHsKICAgICAgICAkY29tbWFuZCA9ICcnOwogICAgICAgICRtb2R1bGUgPSBhcnJheV9zaGlmdCgkYXJncyk7CgogICAgICAgIGlmICgkbW9kdWxlICE9PSBudWxsKSB7CiAgICAgICAgICAgICRjb21tYW5kID0gc2VsZjo6ZXNjYXBlKCRtb2R1bGUsIHRydWUsIHRydWUpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGFyZ3MgYXMgJGFyZykgewogICAgICAgICAgICAgICAgJGNvbW1hbmQgLj0gJyAnLnNlbGY6OmVzY2FwZSgkYXJnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogTWFrZXMgcHV0ZW52IGVudmlyb25tZW50IGNoYW5nZXMgYXZhaWxhYmxlIGluICRfU0VSVkVSIGFuZCAkX0VOVgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkdmFsdWUgQSBudWxsIHZhbHVlIHVuc2V0cyB0aGUgdmFyaWFibGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgd2FzIHNldAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldEVudigkbmFtZSwgJHZhbHVlID0gbnVsbCkKICAgIHsKICAgICAgICAkdW5zZXQgPSBudWxsID09PSAkdmFsdWU7CgogICAgICAgIGlmICghcHV0ZW52KCR1bnNldCA/ICRuYW1lIDogJG5hbWUuJz0nLiR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR1bnNldCkgewogICAgICAgICAgICB1bnNldCgkX1NFUlZFUlskbmFtZV0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRfU0VSVkVSWyRuYW1lXSA9ICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgIC8vIFVwZGF0ZSAkX0VOViBpZiBpdCBpcyBiZWluZyB1c2VkCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJpcG9zKChzdHJpbmcpIGluaV9nZXQoJ3ZhcmlhYmxlc19vcmRlcicpLCAnRScpKSB7CiAgICAgICAgICAgIGlmICgkdW5zZXQpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRfRU5WWyRuYW1lXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkX0VOVlskbmFtZV0gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovLyBhdXRvbG9hZF9zdGF0aWMucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKCm5hbWVzcGFjZSBDb21wb3NlclxBdXRvbG9hZDsKCmNsYXNzIENvbXBvc2VyU3RhdGljSW5pdDA0MTE0MTEwYWY4N2Y1NjI0YjM1ODBlYmE0M2I4NzcwCnsKICAgIHB1YmxpYyBzdGF0aWMgJGZpbGVzID0gYXJyYXkgKAogICAgICAgICczMjBjZGUyMmY2NmRkNGY1ZDNmZDYyMWQzZTg4Yjk4ZicgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L3BvbHlmaWxsLWN0eXBlL2Jvb3RzdHJhcC5waHAnLAogICAgICAgICcwZTZkN2JmNGE1ODExYmZhNWNmNDBjNWNjZDZmYWU2YScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nL2Jvb3RzdHJhcC5waHAnLAogICAgICAgICdhZDE1NWY4ZjFjZjBkNDE4ZmU0OWUyNDhkYjhjNjYxYicgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9yZWFjdC9wcm9taXNlL3NyYy9mdW5jdGlvbnNfaW5jbHVkZS5waHAnLAogICAgICAgICdiZTAxYjliMTY5MjVkY2IyMjE2NWM0MGI0NjY4MWFjNicgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL2NsaS5waHAnLAogICAgICAgICczOTM3ODA2MTA1Y2M4ZTIyMWI4ZmE4ZGI1YjcwZDJmMicgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljL2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAnLAogICAgICAgICdiYTM2NmY5NmY0ZmRkYmRlZjYxYWQ3YTg2MmI0NGY2MScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcGFja2FnZS1jb21tYW5kL3BhY2thZ2UtY29tbWFuZC5waHAnLAogICAgICAgICc4YTBhZDAyZGY2YTUwODdmMmMzODBmOGZkNTJkYjI3MycgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY2FjaGUtY29tbWFuZC9jYWNoZS1jb21tYW5kLnBocCcsCiAgICAgICAgJ2YzZjAxOTlhM2VjZDlmNTAxZDBhM2IzNjFiZDJmNjFjJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9lbnRpdHktY29tbWFuZC9lbnRpdHktY29tbWFuZC5waHAnLAogICAgICAgICczZjIwMTAzM2Q1YWNlYjIyOTMzMTQyNzNiZTg4ZjdjNicgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvZXh0ZW5zaW9uLWNvbW1hbmQucGhwJywKICAgICAgICAnYzY1Zjc1MzM3NWZhZWUzNDliN2FkYzQ4YzJlZTdjYzInID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2RiLWNvbW1hbmQvZGItY29tbWFuZC5waHAnLAogICAgICAgICc1ZTA5OWQzY2FjNjc3ZGQyYmVjMTAwM2VhNzcwNzc0NScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvbWVkaWEtY29tbWFuZC9tZWRpYS1jb21tYW5kLnBocCcsCiAgICAgICAgJ2Q5NzljMTFmZTgwYmE5NmFlMzAzN2I0MzQyOWZlNTQ2JyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3NjYWZmb2xkLWNvbW1hbmQucGhwJywKICAgICAgICAnNWM2ZWM1Y2ZmOGY5ZDYyNTc3MmM4ZWQxNDdmNmI4OTQnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2V4cG9ydC1jb21tYW5kL2V4cG9ydC1jb21tYW5kLnBocCcsCiAgICAgICAgJ2FjOTQ5Y2U0MGE5ODE4MTliYTEzMjQ3MzUxOGE5YTMxJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS93cC1jb25maWctdHJhbnNmb3JtZXIvc3JjL1dQQ29uZmlnVHJhbnNmb3JtZXIucGhwJywKICAgICAgICAnYjY2ZDI5NzU3ZmNiMmZiN2E5NjA4ZDA2OGUzNzE2YjAnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQvY2hlY2tzdW0tY29tbWFuZC5waHAnLAogICAgICAgICczMGNiYjZlNDEyMmRjOTg4ZTQ5NGM2YjljMDQzODIzMycgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvaW1wb3J0LWNvbW1hbmQvaW1wb3J0LWNvbW1hbmQucGhwJywKICAgICAgICAnOWYwNGRkMGFhNWQ2N2VjNzVhNzVjODhjMzQ1YTA3OWUnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NlcnZlci1jb21tYW5kL3NlcnZlci1jb21tYW5kLnBocCcsCiAgICAgICAgJzg1MTk3NzliYmI2NWVlYjg0MmFmMmY2MjljZTdiNmY4JyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kL3N1cGVyLWFkbWluLWNvbW1hbmQucGhwJywKICAgICAgICAnNWRlYWY2Y2U5YzhiYmRmYjY1MTA0YzdlOTM4ZDU4NzUnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2NvbmZpZy1jb21tYW5kL2NvbmZpZy1jb21tYW5kLnBocCcsCiAgICAgICAgJzY4YzM5Yjg4MjE1YjZjZjdhMGRhMTY0MTY2NjcwZWY5JyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jb3JlLWNvbW1hbmQvY29yZS1jb21tYW5kLnBocCcsCiAgICAgICAgJzc2NTRlMDBiZjBlNjMyNTgwNzY0NDAwYmQ4MjkzYTljJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jcm9uLWNvbW1hbmQvY3Jvbi1jb21tYW5kLnBocCcsCiAgICAgICAgJzAyMWQzYTEzNDcxNTU2ZjBiNTcwMzhkNjc5ZjdmOGVhJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9lbWJlZC1jb21tYW5kL2VtYmVkLWNvbW1hbmQucGhwJywKICAgICAgICAnZjk1OGRjYTNmNDEyZmQ3OTc1ZGExNzAwOTEyYTkzMjEnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2V2YWwtY29tbWFuZC9ldmFsLWNvbW1hbmQucGhwJywKICAgICAgICAnZmZiNDY1YTQ5NGMzMTAxMjE4YzQ0MTcxODBjMmM5YTInID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2kxOG4tY29tbWFuZC9pMThuLWNvbW1hbmQucGhwJywKICAgICAgICAnMWM4OGMxZWZmMDUyMTdhOGNhYzgwYzY0YzlhYzIwODAnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZC9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQucGhwJywKICAgICAgICAnYWNlMGQyMDVkYjdmNDEzNWVjMzIxMzJhMDA3NmQ1NTUnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvbGFuZ3VhZ2UtY29tbWFuZC5waHAnLAogICAgICAgICdmMzk5YzFjOGQwYzc4N2Q1Yzk0YzA5ODg0Y2RkOTc2MicgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcmV3cml0ZS1jb21tYW5kL3Jld3JpdGUtY29tbWFuZC5waHAnLAogICAgICAgICcwODBmYWRkNjY3MTk1ZDA1NWM1YTIzMzg2ZjI3MDI2MScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcm9sZS1jb21tYW5kL3JvbGUtY29tbWFuZC5waHAnLAogICAgICAgICc4ZWNiMTNmOGJiYzIyYjFiMzRkMTJiMTRlYzAxMDc3YScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC9zZWFyY2gtcmVwbGFjZS1jb21tYW5kLnBocCcsCiAgICAgICAgJzEyOWQ1OGZhODE1MTM3NGFjZWI4NTcxYmNhYTk3NTA0JyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zaGVsbC1jb21tYW5kL3NoZWxsLWNvbW1hbmQucGhwJywKICAgICAgICAnMWYwNTM3MmFmY2M3ZDBjNTFhMzA1Y2VmMWQ1NmRkMDEnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3dpZGdldC1jb21tYW5kL3dpZGdldC1jb21tYW5kLnBocCcsCiAgICApOwoKICAgIHB1YmxpYyBzdGF0aWMgJHByZWZpeExlbmd0aHNQc3I0ID0gYXJyYXkgKAogICAgICAgICdXJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdXUF9DTElcXE1haW50ZW5hbmNlTW9kZVxcJyA9PiAyMywKICAgICAgICAgICAgJ1dQX0NMSVxcSTE4blxcJyA9PiAxMiwKICAgICAgICAgICAgJ1dQX0NMSVxcRW1iZWRzXFwnID0+IDE0LAogICAgICAgICAgICAnV1BfQ0xJXFwnID0+IDcsCiAgICAgICAgKSwKICAgICAgICAnUycgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnU3ltZm9ueVxcUG9seWZpbGxcXE1ic3RyaW5nXFwnID0+IDI2LAogICAgICAgICAgICAnU3ltZm9ueVxcUG9seWZpbGxcXEN0eXBlXFwnID0+IDIzLAogICAgICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxQcm9jZXNzXFwnID0+IDI2LAogICAgICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxGaW5kZXJcXCcgPT4gMjUsCiAgICAgICAgICAgICdTeW1mb255XFxDb21wb25lbnRcXEZpbGVzeXN0ZW1cXCcgPT4gMjksCiAgICAgICAgICAgICdTeW1mb255XFxDb21wb25lbnRcXERlYnVnXFwnID0+IDI0LAogICAgICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxDb25zb2xlXFwnID0+IDI2LAogICAgICAgICAgICAnU2VsZFxcUGhhclV0aWxzXFwnID0+IDE1LAogICAgICAgICAgICAnU2VsZFxcSnNvbkxpbnRcXCcgPT4gMTQsCiAgICAgICAgKSwKICAgICAgICAnUicgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnUmVhY3RcXFByb21pc2VcXCcgPT4gMTQsCiAgICAgICAgKSwKICAgICAgICAnUCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnUHNyXFxMb2dcXCcgPT4gOCwKICAgICAgICAgICAgJ1BlYXN0XFx0ZXN0XFwnID0+IDExLAogICAgICAgICAgICAnUGVhc3RcXCcgPT4gNiwKICAgICAgICApLAogICAgICAgICdNJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdNdXN0YW5nb3N0YW5nXFwnID0+IDE0LAogICAgICAgICksCiAgICAgICAgJ0onID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ0pzb25TY2hlbWFcXCcgPT4gMTEsCiAgICAgICAgKSwKICAgICAgICAnRycgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnR2V0dGV4dFxcTGFuZ3VhZ2VzXFwnID0+IDE4LAogICAgICAgICAgICAnR2V0dGV4dFxcJyA9PiA4LAogICAgICAgICksCiAgICAgICAgJ0MnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ0NvbXBvc2VyXFxYZGVidWdIYW5kbGVyXFwnID0+IDIzLAogICAgICAgICAgICAnQ29tcG9zZXJcXFNwZHhcXCcgPT4gMTQsCiAgICAgICAgICAgICdDb21wb3NlclxcU2VtdmVyXFwnID0+IDE2LAogICAgICAgICAgICAnQ29tcG9zZXJcXFBjcmVcXCcgPT4gMTQsCiAgICAgICAgICAgICdDb21wb3NlclxcTWV0YWRhdGFNaW5pZmllclxcJyA9PiAyNiwKICAgICAgICAgICAgJ0NvbXBvc2VyXFxDYUJ1bmRsZVxcJyA9PiAxOCwKICAgICAgICAgICAgJ0NvbXBvc2VyXFwnID0+IDksCiAgICAgICAgKSwKICAgICk7CgogICAgcHVibGljIHN0YXRpYyAkcHJlZml4RGlyc1BzcjQgPSBhcnJheSAoCiAgICAgICAgJ1dQX0NMSVxcTWFpbnRlbmFuY2VNb2RlXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQvc3JjJywKICAgICAgICApLAogICAgICAgICdXUF9DTElcXEkxOG5cXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMnLAogICAgICAgICksCiAgICAgICAgJ1dQX0NMSVxcRW1iZWRzXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9lbWJlZC1jb21tYW5kL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnV1BfQ0xJXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvV1BfQ0xJJywKICAgICAgICAgICAgMSA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zaGVsbC1jb21tYW5kL3NyYy9XUF9DTEknLAogICAgICAgICksCiAgICAgICAgJ1N5bWZvbnlcXFBvbHlmaWxsXFxNYnN0cmluZ1xcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nJywKICAgICAgICApLAogICAgICAgICdTeW1mb255XFxQb2x5ZmlsbFxcQ3R5cGVcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZScsCiAgICAgICAgKSwKICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxQcm9jZXNzXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3N5bWZvbnkvcHJvY2VzcycsCiAgICAgICAgKSwKICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxGaW5kZXJcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvc3ltZm9ueS9maW5kZXInLAogICAgICAgICksCiAgICAgICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcRmlsZXN5c3RlbVxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L2ZpbGVzeXN0ZW0nLAogICAgICAgICksCiAgICAgICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcRGVidWdcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICksCiAgICAgICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcQ29uc29sZVxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L2NvbnNvbGUnLAogICAgICAgICksCiAgICAgICAgJ1NlbGRcXFBoYXJVdGlsc1xcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zZWxkL3BoYXItdXRpbHMvc3JjJywKICAgICAgICApLAogICAgICAgICdTZWxkXFxKc29uTGludFxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zZWxkL2pzb25saW50L3NyYy9TZWxkL0pzb25MaW50JywKICAgICAgICApLAogICAgICAgICdSZWFjdFxcUHJvbWlzZVxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9yZWFjdC9wcm9taXNlL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnUHNyXFxMb2dcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvcHNyL2xvZy9Qc3IvTG9nJywKICAgICAgICApLAogICAgICAgICdQZWFzdFxcdGVzdFxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9tY2s4OS9wZWFzdC90ZXN0L1BlYXN0JywKICAgICAgICApLAogICAgICAgICdQZWFzdFxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9tY2s4OS9wZWFzdC9saWIvUGVhc3QnLAogICAgICAgICksCiAgICAgICAgJ011c3Rhbmdvc3RhbmdcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9zcmMnLAogICAgICAgICksCiAgICAgICAgJ0pzb25TY2hlbWFcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYScsCiAgICAgICAgKSwKICAgICAgICAnR2V0dGV4dFxcTGFuZ3VhZ2VzXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL2dldHRleHQvbGFuZ3VhZ2VzL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnR2V0dGV4dFxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9nZXR0ZXh0L2dldHRleHQvc3JjJywKICAgICAgICApLAogICAgICAgICdDb21wb3NlclxcWGRlYnVnSGFuZGxlclxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9jb21wb3Nlci94ZGVidWctaGFuZGxlci9zcmMnLAogICAgICAgICksCiAgICAgICAgJ0NvbXBvc2VyXFxTcGR4XFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICApLAogICAgICAgICdDb21wb3NlclxcU2VtdmVyXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL2NvbXBvc2VyL3NlbXZlci9zcmMnLAogICAgICAgICksCiAgICAgICAgJ0NvbXBvc2VyXFxQY3JlXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL2NvbXBvc2VyL3BjcmUvc3JjJywKICAgICAgICApLAogICAgICAgICdDb21wb3NlclxcTWV0YWRhdGFNaW5pZmllclxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9jb21wb3Nlci9tZXRhZGF0YS1taW5pZmllci9zcmMnLAogICAgICAgICksCiAgICAgICAgJ0NvbXBvc2VyXFxDYUJ1bmRsZVxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9jb21wb3Nlci9jYS1idW5kbGUvc3JjJywKICAgICAgICApLAogICAgICAgICdDb21wb3NlclxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXInLAogICAgICAgICksCiAgICApOwoKICAgIHB1YmxpYyBzdGF0aWMgJGZhbGxiYWNrRGlyc1BzcjQgPSBhcnJheSAoCiAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jYWNoZS1jb21tYW5kL3NyYycsCiAgICAgICAgMSA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jb25maWctY29tbWFuZC9zcmMnLAogICAgICAgIDIgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY29yZS1jb21tYW5kL3NyYycsCiAgICAgICAgMyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL3NyYycsCiAgICAgICAgNCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jcm9uLWNvbW1hbmQvc3JjJywKICAgICAgICA1ID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2RiLWNvbW1hbmQvc3JjJywKICAgICAgICA2ID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2V2YWwtY29tbWFuZC9zcmMnLAogICAgICAgIDcgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjJywKICAgICAgICA4ID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYycsCiAgICAgICAgOSA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMnLAogICAgICAgIDEwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2ltcG9ydC1jb21tYW5kL3NyYycsCiAgICAgICAgMTEgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvbGFuZ3VhZ2UtY29tbWFuZC9zcmMnLAogICAgICAgIDEyID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL21lZGlhLWNvbW1hbmQvc3JjJywKICAgICAgICAxMyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9wYWNrYWdlLWNvbW1hbmQvc3JjJywKICAgICAgICAxNCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9yZXdyaXRlLWNvbW1hbmQvc3JjJywKICAgICAgICAxNSA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9yb2xlLWNvbW1hbmQvc3JjJywKICAgICAgICAxNiA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zZWFyY2gtcmVwbGFjZS1jb21tYW5kL3NyYycsCiAgICAgICAgMTcgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvc2VydmVyLWNvbW1hbmQvc3JjJywKICAgICAgICAxOCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3NyYycsCiAgICAgICAgMTkgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvc2hlbGwtY29tbWFuZC9zcmMnLAogICAgICAgIDIwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3N1cGVyLWFkbWluLWNvbW1hbmQvc3JjJywKICAgICAgICAyMSA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS93aWRnZXQtY29tbWFuZC9zcmMnLAogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljICRwcmVmaXhlc1BzcjAgPSBhcnJheSAoCiAgICAgICAgJ2MnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ2NsaScgPT4gCiAgICAgICAgICAgIGFycmF5ICgKICAgICAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcGhwLWNsaS10b29scy9saWInLAogICAgICAgICAgICApLAogICAgICAgICksCiAgICAgICAgJ1cnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ1dQX0NMSVxcJyA9PiAKICAgICAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS93cC1jbGkvcGhwJywKICAgICAgICAgICAgKSwKICAgICAgICApLAogICAgICAgICdSJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdSZXF1ZXN0cycgPT4gCiAgICAgICAgICAgIGFycmF5ICgKICAgICAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeScsCiAgICAgICAgICAgICksCiAgICAgICAgKSwKICAgICAgICAnTycgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnT3h5bWVsJyA9PiAKICAgICAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL25iL294eW1lbCcsCiAgICAgICAgICAgICksCiAgICAgICAgKSwKICAgICAgICAnTScgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnTXVzdGFjaGUnID0+IAogICAgICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvbXVzdGFjaGUvbXVzdGFjaGUvc3JjJywKICAgICAgICAgICAgKSwKICAgICAgICApLAogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljICRjbGFzc01hcCA9IGFycmF5ICgKICAgICAgICAnQ29tcG9zZXJcXEluc3RhbGxlZFZlcnNpb25zJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL2NvbXBvc2VyL0luc3RhbGxlZFZlcnNpb25zLnBocCcsCiAgICAgICAgJ1dQX0NMSScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvd3AtY2xpL3BocC9jbGFzcy13cC1jbGkucGhwJywKICAgICAgICAnV1BfQ0xJX0NvbW1hbmQnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3dwLWNsaS9waHAvY2xhc3Mtd3AtY2xpLWNvbW1hbmQucGhwJywKICAgICk7CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRJbml0aWFsaXplcihDbGFzc0xvYWRlciAkbG9hZGVyKQogICAgewogICAgICAgIHJldHVybiBcQ2xvc3VyZTo6YmluZChmdW5jdGlvbiAoKSB1c2UgKCRsb2FkZXIpIHsKICAgICAgICAgICAgJGxvYWRlci0+cHJlZml4TGVuZ3Roc1BzcjQgPSBDb21wb3NlclN0YXRpY0luaXQwNDExNDExMGFmODdmNTYyNGIzNTgwZWJhNDNiODc3MDo6JHByZWZpeExlbmd0aHNQc3I0OwogICAgICAgICAgICAkbG9hZGVyLT5wcmVmaXhEaXJzUHNyNCA9IENvbXBvc2VyU3RhdGljSW5pdDA0MTE0MTEwYWY4N2Y1NjI0YjM1ODBlYmE0M2I4NzcwOjokcHJlZml4RGlyc1BzcjQ7CiAgICAgICAgICAgICRsb2FkZXItPmZhbGxiYWNrRGlyc1BzcjQgPSBDb21wb3NlclN0YXRpY0luaXQwNDExNDExMGFmODdmNTYyNGIzNTgwZWJhNDNiODc3MDo6JGZhbGxiYWNrRGlyc1BzcjQ7CiAgICAgICAgICAgICRsb2FkZXItPnByZWZpeGVzUHNyMCA9IENvbXBvc2VyU3RhdGljSW5pdDA0MTE0MTEwYWY4N2Y1NjI0YjM1ODBlYmE0M2I4NzcwOjokcHJlZml4ZXNQc3IwOwogICAgICAgICAgICAkbG9hZGVyLT5jbGFzc01hcCA9IENvbXBvc2VyU3RhdGljSW5pdDA0MTE0MTEwYWY4N2Y1NjI0YjM1ODBlYmE0M2I4NzcwOjokY2xhc3NNYXA7CgogICAgICAgIH0sIG51bGwsIENsYXNzTG9hZGVyOjpjbGFzcyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3BjcmUuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGNyZTsKCmNsYXNzIFBjcmVFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbgp7CiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRmdW5jdGlvbgogICAgICogQHBhcmFtICBzdHJpbmd8c3RyaW5nW10gJHBhdHRlcm4KICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GdW5jdGlvbigkZnVuY3Rpb24sICRwYXR0ZXJuKQogICAgewogICAgICAgICRjb2RlID0gcHJlZ19sYXN0X2Vycm9yKCk7CgogICAgICAgIGlmIChpc19hcnJheSgkcGF0dGVybikpIHsKICAgICAgICAgICAgJHBhdHRlcm4gPSBpbXBsb2RlKCcsICcsICRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUGNyZUV4Y2VwdGlvbigkZnVuY3Rpb24uJygpOiBmYWlsZWQgZXhlY3V0aW5nICInLiRwYXR0ZXJuLiciOiAnLnNlbGY6OnBjcmVMYXN0RXJyb3JNZXNzYWdlKCRjb2RlKSwgJGNvZGUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgJGNvZGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHBjcmVMYXN0RXJyb3JNZXNzYWdlKCRjb2RlKQogICAgewogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA4MDAwMCkgewogICAgICAgICAgICByZXR1cm4gcHJlZ19sYXN0X2Vycm9yX21zZygpOwogICAgICAgIH0KCiAgICAgICAgLy8gb2xkZXIgcGhwIHZlcnNpb25zIGRpZCBub3Qgc2V0IHRoZSBjb2RlIHByb3Blcmx5IGluIGFsbCBjYXNlcwogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA8IDcwMjAxICYmICRjb2RlID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAnVU5ERUZJTkVEX0VSUk9SJzsKICAgICAgICB9CgogICAgICAgICRjb25zdGFudHMgPSBnZXRfZGVmaW5lZF9jb25zdGFudHModHJ1ZSk7CiAgICAgICAgaWYgKCFpc3NldCgkY29uc3RhbnRzWydwY3JlJ10pKSB7CiAgICAgICAgICAgIHJldHVybiAnVU5ERUZJTkVEX0VSUk9SJzsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRjb25zdGFudHNbJ3BjcmUnXSBhcyAkY29uc3QgPT4gJHZhbCkgewogICAgICAgICAgICBpZiAoJHZhbCA9PT0gJGNvZGUgJiYgc3Vic3RyKCRjb25zdCwgLTYpID09PSAnX0VSUk9SJykgewogICAgICAgICAgICAgICAgcmV0dXJuICRjb25zdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdVTkRFRklORURfRVJST1InOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9wY3JlLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBjcmU7CgpmaW5hbCBjbGFzcyBNYXRjaEFsbFdpdGhPZmZzZXRzUmVzdWx0CnsKICAgIC8qKgogICAgICogQW4gYXJyYXkgb2YgbWF0Y2ggZ3JvdXAgPT4gbGlzdCBvZiBtYXRjaGVzLCBldmVyeSBtYXRjaCBiZWluZyBhIHBhaXIgb2Ygc3RyaW5nIG1hdGNoZWQgKyBvZmZzZXQgaW4gYnl0ZXMgKG9yIC0xIGlmIG5vIG1hdGNoKQogICAgICoKICAgICAqIEByZWFkb25seQogICAgICogQHZhciBhcnJheTxpbnR8c3RyaW5nLCBsaXN0PGFycmF5e3N0cmluZ3xudWxsLCBpbnR9Pj4KICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxpbnR8c3RyaW5nLCBsaXN0PGFycmF5e3N0cmluZ3xudWxsLCBpbnQ8LTEsIG1heD59Pj4KICAgICAqLwogICAgcHVibGljICRtYXRjaGVzOwoKICAgIC8qKgogICAgICogQHJlYWRvbmx5CiAgICAgKiBAdmFyIDB8cG9zaXRpdmUtaW50CiAgICAgKi8KICAgIHB1YmxpYyAkY291bnQ7CgogICAgLyoqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJG1hdGNoZWQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gMHxwb3NpdGl2ZS1pbnQgJGNvdW50CiAgICAgKiBAcGFyYW0gYXJyYXk8aW50fHN0cmluZywgbGlzdDxhcnJheXtzdHJpbmd8bnVsbCwgaW50fT4+ICRtYXRjaGVzCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxpbnR8c3RyaW5nLCBsaXN0PGFycmF5e3N0cmluZ3xudWxsLCBpbnQ8LTEsIG1heD59Pj4gJG1hdGNoZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb3VudCwgYXJyYXkgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSAkbWF0Y2hlczsKICAgICAgICAkdGhpcy0+bWF0Y2hlZCA9IChib29sKSAkY291bnQ7CiAgICAgICAgJHRoaXMtPmNvdW50ID0gJGNvdW50OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9wY3JlLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBjcmU7CgpjbGFzcyBSZWdleAp7CiAgICAvKioKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICRwYXR0ZXJuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdWJqZWN0CiAgICAgKiBAcGFyYW0gaW50ICAgICRvZmZzZXQKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzTWF0Y2goJHBhdHRlcm4sICRzdWJqZWN0LCAkb2Zmc2V0ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpIFByZWc6Om1hdGNoKCRwYXR0ZXJuLCAkc3ViamVjdCwgJG1hdGNoZXMsIDAsICRvZmZzZXQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgJHBhdHRlcm4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1YmplY3QKICAgICAqIEBwYXJhbSBpbnQgICAgJGZsYWdzIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjIrCiAgICAgKiBAcGFyYW0gaW50ICAgICRvZmZzZXQKICAgICAqIEByZXR1cm4gTWF0Y2hSZXN1bHQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYXRjaCgkcGF0dGVybiwgJHN1YmplY3QsICRmbGFncyA9IDAsICRvZmZzZXQgPSAwKQogICAgewogICAgICAgIGlmICgoJGZsYWdzICYgUFJFR19PRkZTRVRfQ0FQVFVSRSkgIT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BSRUdfT0ZGU0VUX0NBUFRVUkUgaXMgbm90IHN1cHBvcnRlZCBhcyBpdCBjaGFuZ2VzIHRoZSByZXR1cm4gdHlwZSwgdXNlIG1hdGNoV2l0aE9mZnNldHMoKSBpbnN0ZWFkJyk7CiAgICAgICAgfQoKICAgICAgICAkY291bnQgPSBQcmVnOjptYXRjaCgkcGF0dGVybiwgJHN1YmplY3QsICRtYXRjaGVzLCAkZmxhZ3MsICRvZmZzZXQpOwoKICAgICAgICByZXR1cm4gbmV3IE1hdGNoUmVzdWx0KCRjb3VudCwgJG1hdGNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyBwcmVnX21hdGNoIHdpdGggUFJFR19PRkZTRVRfQ0FQVFVSRQogICAgICoKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICRwYXR0ZXJuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdWJqZWN0CiAgICAgKiBAcGFyYW0gaW50ICAgICRmbGFncyBQUkVHX1VOTUFUQ0hFRF9BU19OVUxMLCBvbmx5IGF2YWlsYWJsZSBvbiBQSFAgNy4yKwogICAgICogQHBhcmFtIGludCAgICAkb2Zmc2V0CiAgICAgKiBAcmV0dXJuIE1hdGNoV2l0aE9mZnNldHNSZXN1bHQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYXRjaFdpdGhPZmZzZXRzKCRwYXR0ZXJuLCAkc3ViamVjdCwgJGZsYWdzID0gMCwgJG9mZnNldCA9IDApCiAgICB7CiAgICAgICAgJGNvdW50ID0gUHJlZzo6bWF0Y2hXaXRoT2Zmc2V0cygkcGF0dGVybiwgJHN1YmplY3QsICRtYXRjaGVzLCAkZmxhZ3MsICRvZmZzZXQpOwoKICAgICAgICByZXR1cm4gbmV3IE1hdGNoV2l0aE9mZnNldHNSZXN1bHQoJGNvdW50LCAkbWF0Y2hlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAkc3ViamVjdAogICAgICogQHBhcmFtIGludCAgICAkZmxhZ3MgUFJFR19VTk1BVENIRURfQVNfTlVMTCwgb25seSBhdmFpbGFibGUgb24gUEhQIDcuMisKICAgICAqIEBwYXJhbSBpbnQgICAgJG9mZnNldAogICAgICogQHJldHVybiBNYXRjaEFsbFJlc3VsdAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1hdGNoQWxsKCRwYXR0ZXJuLCAkc3ViamVjdCwgJGZsYWdzID0gMCwgJG9mZnNldCA9IDApCiAgICB7CiAgICAgICAgaWYgKCgkZmxhZ3MgJiBQUkVHX09GRlNFVF9DQVBUVVJFKSAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUFJFR19PRkZTRVRfQ0FQVFVSRSBpcyBub3Qgc3VwcG9ydGVkIGFzIGl0IGNoYW5nZXMgdGhlIHJldHVybiB0eXBlLCB1c2UgbWF0Y2hBbGxXaXRoT2Zmc2V0cygpIGluc3RlYWQnKTsKICAgICAgICB9CgogICAgICAgIGlmICgoJGZsYWdzICYgUFJFR19TRVRfT1JERVIpICE9PSAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQUkVHX1NFVF9PUkRFUiBpcyBub3Qgc3VwcG9ydGVkIGFzIGl0IGNoYW5nZXMgdGhlIHJldHVybiB0eXBlJyk7CiAgICAgICAgfQoKICAgICAgICAkY291bnQgPSBQcmVnOjptYXRjaEFsbCgkcGF0dGVybiwgJHN1YmplY3QsICRtYXRjaGVzLCAkZmxhZ3MsICRvZmZzZXQpOwoKICAgICAgICByZXR1cm4gbmV3IE1hdGNoQWxsUmVzdWx0KCRjb3VudCwgJG1hdGNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyBwcmVnX21hdGNoX2FsbCB3aXRoIFBSRUdfT0ZGU0VUX0NBUFRVUkUKICAgICAqCiAgICAgKiBAcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAkc3ViamVjdAogICAgICogQHBhcmFtIGludCAgICAkZmxhZ3MgUFJFR19VTk1BVENIRURfQVNfTlVMTCwgb25seSBhdmFpbGFibGUgb24gUEhQIDcuMisKICAgICAqIEBwYXJhbSBpbnQgICAgJG9mZnNldAogICAgICogQHJldHVybiBNYXRjaEFsbFdpdGhPZmZzZXRzUmVzdWx0CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWF0Y2hBbGxXaXRoT2Zmc2V0cygkcGF0dGVybiwgJHN1YmplY3QsICRmbGFncyA9IDAsICRvZmZzZXQgPSAwKQogICAgewogICAgICAgICRjb3VudCA9IFByZWc6Om1hdGNoQWxsV2l0aE9mZnNldHMoJHBhdHRlcm4sICRzdWJqZWN0LCAkbWF0Y2hlcywgJGZsYWdzLCAkb2Zmc2V0KTsKCiAgICAgICAgcmV0dXJuIG5ldyBNYXRjaEFsbFdpdGhPZmZzZXRzUmVzdWx0KCRjb3VudCwgJG1hdGNoZXMpOwogICAgfQogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdICRwYXR0ZXJuCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdICRyZXBsYWNlbWVudAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAkc3ViamVjdAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkbGltaXQKICAgICAqIEByZXR1cm4gUmVwbGFjZVJlc3VsdAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlcGxhY2UoJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCA9IC0xKQogICAgewogICAgICAgICRyZXN1bHQgPSBQcmVnOjpyZXBsYWNlKCRwYXR0ZXJuLCAkcmVwbGFjZW1lbnQsICRzdWJqZWN0LCAkbGltaXQsICRjb3VudCk7CgogICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVJlc3VsdCgkY291bnQsICRyZXN1bHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkcGF0dGVybgogICAgICogQHBhcmFtIGNhbGxhYmxlICAgICAgICAkcmVwbGFjZW1lbnQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJHN1YmplY3QKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJGxpbWl0CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRmbGFncyBQUkVHX09GRlNFVF9DQVBUVVJFIG9yIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjQrCiAgICAgKiBAcmV0dXJuIFJlcGxhY2VSZXN1bHQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXBsYWNlQ2FsbGJhY2soJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCA9IC0xLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgICRyZXN1bHQgPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2soJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCwgJGNvdW50LCAkZmxhZ3MpOwoKICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VSZXN1bHQoJGNvdW50LCAkcmVzdWx0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEF2YWlsYWJsZSBmcm9tIFBIUCA3LjAKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBjYWxsYWJsZT4gJHBhdHRlcm4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1YmplY3QKICAgICAqIEBwYXJhbSBpbnQgICAgJGxpbWl0CiAgICAgKiBAcGFyYW0gaW50ICAgICRmbGFncyBQUkVHX09GRlNFVF9DQVBUVVJFIG9yIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjQrCiAgICAgKiBAcmV0dXJuIFJlcGxhY2VSZXN1bHQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXBsYWNlQ2FsbGJhY2tBcnJheSgkcGF0dGVybiwgJHN1YmplY3QsICRsaW1pdCA9IC0xLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgICRyZXN1bHQgPSBQcmVnOjpyZXBsYWNlQ2FsbGJhY2tBcnJheSgkcGF0dGVybiwgJHN1YmplY3QsICRsaW1pdCwgJGNvdW50LCAkZmxhZ3MpOwoKICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VSZXN1bHQoJGNvdW50LCAkcmVzdWx0KTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvcGNyZS4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQY3JlOwoKY2xhc3MgUHJlZwp7CiAgICBjb25zdCBBUlJBWV9NU0cgPSAnJHN1YmplY3QgYXMgYW4gYXJyYXkgaXMgbm90IHN1cHBvcnRlZC4gWW91IGNhbiB1c2UgXCdmb3JlYWNoXCcgaW5zdGVhZC4nOwoKICAgIC8qKgogICAgICogQHBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgICAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAgICRzdWJqZWN0CiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nfG51bGw+ICRtYXRjaGVzIFNldCBieSBtZXRob2QKICAgICAqIEBwYXJhbSBpbnQgICAgICAkZmxhZ3MgUFJFR19VTk1BVENIRURfQVNfTlVMTCwgb25seSBhdmFpbGFibGUgb24gUEhQIDcuMisKICAgICAqIEBwYXJhbSBpbnQgICAgICAkb2Zmc2V0CiAgICAgKiBAcmV0dXJuIDB8MQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1hdGNoKCRwYXR0ZXJuLCAkc3ViamVjdCwgJiRtYXRjaGVzID0gbnVsbCwgJGZsYWdzID0gMCwgJG9mZnNldCA9IDApCiAgICB7CiAgICAgICAgaWYgKCgkZmxhZ3MgJiBQUkVHX09GRlNFVF9DQVBUVVJFKSAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUFJFR19PRkZTRVRfQ0FQVFVSRSBpcyBub3Qgc3VwcG9ydGVkIGFzIGl0IGNoYW5nZXMgdGhlIHR5cGUgb2YgJG1hdGNoZXMsIHVzZSBtYXRjaFdpdGhPZmZzZXRzKCkgaW5zdGVhZCcpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IHByZWdfbWF0Y2goJHBhdHRlcm4sICRzdWJqZWN0LCAkbWF0Y2hlcywgJGZsYWdzLCAkb2Zmc2V0KTsKICAgICAgICBpZiAoJHJlc3VsdCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgUGNyZUV4Y2VwdGlvbjo6ZnJvbUZ1bmN0aW9uKCdwcmVnX21hdGNoJywgJHBhdHRlcm4pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHByZWdfbWF0Y2ggd2l0aCBQUkVHX09GRlNFVF9DQVBUVVJFCiAgICAgKgogICAgICogQHBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgICAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAgICRzdWJqZWN0CiAgICAgKiBAcGFyYW0gYXJyYXk8aW50fHN0cmluZywgYXJyYXl7c3RyaW5nfG51bGwsIGludH0+ICRtYXRjaGVzIFNldCBieSBtZXRob2QKICAgICAqIEBwYXJhbSBpbnQgICAgICAkZmxhZ3MgUFJFR19VTk1BVENIRURfQVNfTlVMTCwgb25seSBhdmFpbGFibGUgb24gUEhQIDcuMisKICAgICAqIEBwYXJhbSBpbnQgICAgICAkb2Zmc2V0CiAgICAgKiBAcmV0dXJuIDB8MQogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PGludHxzdHJpbmcsIGFycmF5e3N0cmluZ3xudWxsLCBpbnQ8LTEsIG1heD59PiAkbWF0Y2hlcwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1hdGNoV2l0aE9mZnNldHMoJHBhdHRlcm4sICRzdWJqZWN0LCAmJG1hdGNoZXMsICRmbGFncyA9IDAsICRvZmZzZXQgPSAwKQogICAgewogICAgICAgICRyZXN1bHQgPSBwcmVnX21hdGNoKCRwYXR0ZXJuLCAkc3ViamVjdCwgJG1hdGNoZXMsICRmbGFncyB8IFBSRUdfT0ZGU0VUX0NBUFRVUkUsICRvZmZzZXQpOwogICAgICAgIGlmICgkcmVzdWx0ID09PSBmYWxzZSkgewogICAgICAgICAgICB0aHJvdyBQY3JlRXhjZXB0aW9uOjpmcm9tRnVuY3Rpb24oJ3ByZWdfbWF0Y2gnLCAkcGF0dGVybik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICAgJHBhdHRlcm4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAkc3ViamVjdAogICAgICogQHBhcmFtIGFycmF5PGludHxzdHJpbmcsIGxpc3Q8c3RyaW5nfG51bGw+PiAkbWF0Y2hlcyBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGZsYWdzIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjIrCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJG9mZnNldAogICAgICogQHJldHVybiAwfHBvc2l0aXZlLWludAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1hdGNoQWxsKCRwYXR0ZXJuLCAkc3ViamVjdCwgJiRtYXRjaGVzID0gbnVsbCwgJGZsYWdzID0gMCwgJG9mZnNldCA9IDApCiAgICB7CiAgICAgICAgaWYgKCgkZmxhZ3MgJiBQUkVHX09GRlNFVF9DQVBUVVJFKSAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUFJFR19PRkZTRVRfQ0FQVFVSRSBpcyBub3Qgc3VwcG9ydGVkIGFzIGl0IGNoYW5nZXMgdGhlIHR5cGUgb2YgJG1hdGNoZXMsIHVzZSBtYXRjaEFsbFdpdGhPZmZzZXRzKCkgaW5zdGVhZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCgkZmxhZ3MgJiBQUkVHX1NFVF9PUkRFUikgIT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BSRUdfU0VUX09SREVSIGlzIG5vdCBzdXBwb3J0ZWQgYXMgaXQgY2hhbmdlcyB0aGUgdHlwZSBvZiAkbWF0Y2hlcycpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IHByZWdfbWF0Y2hfYWxsKCRwYXR0ZXJuLCAkc3ViamVjdCwgJG1hdGNoZXMsICRmbGFncywgJG9mZnNldCk7CiAgICAgICAgaWYgKCRyZXN1bHQgPT09IGZhbHNlIHx8ICRyZXN1bHQgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgUGNyZUV4Y2VwdGlvbjo6ZnJvbUZ1bmN0aW9uKCdwcmVnX21hdGNoX2FsbCcsICRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUnVucyBwcmVnX21hdGNoX2FsbCB3aXRoIFBSRUdfT0ZGU0VUX0NBUFRVUkUKICAgICAqCiAgICAgKiBAcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAgICRwYXR0ZXJuCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHN1YmplY3QKICAgICAqIEBwYXJhbSBhcnJheTxpbnR8c3RyaW5nLCBsaXN0PGFycmF5e3N0cmluZ3xudWxsLCBpbnR9Pj4gJG1hdGNoZXMgU2V0IGJ5IG1ldGhvZAogICAgICogQHBhcmFtIGludCAgICAgICRmbGFncyBQUkVHX1VOTUFUQ0hFRF9BU19OVUxMLCBvbmx5IGF2YWlsYWJsZSBvbiBQSFAgNy4yKwogICAgICogQHBhcmFtIGludCAgICAgICRvZmZzZXQKICAgICAqIEByZXR1cm4gMHxwb3NpdGl2ZS1pbnQKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxpbnR8c3RyaW5nLCBsaXN0PGFycmF5e3N0cmluZ3xudWxsLCBpbnQ8LTEsIG1heD59Pj4gJG1hdGNoZXMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYXRjaEFsbFdpdGhPZmZzZXRzKCRwYXR0ZXJuLCAkc3ViamVjdCwgJiRtYXRjaGVzLCAkZmxhZ3MgPSAwLCAkb2Zmc2V0ID0gMCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gcHJlZ19tYXRjaF9hbGwoJHBhdHRlcm4sICRzdWJqZWN0LCAkbWF0Y2hlcywgJGZsYWdzIHwgUFJFR19PRkZTRVRfQ0FQVFVSRSwgJG9mZnNldCk7CiAgICAgICAgaWYgKCRyZXN1bHQgPT09IGZhbHNlIHx8ICRyZXN1bHQgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgUGNyZUV4Y2VwdGlvbjo6ZnJvbUZ1bmN0aW9uKCdwcmVnX21hdGNoX2FsbCcsICRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkcmVwbGFjZW1lbnQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJHN1YmplY3QKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJGxpbWl0CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRjb3VudCBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlcGxhY2UoJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCA9IC0xLCAmJGNvdW50ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJHN1YmplY3QpKSB7IC8vIEBwaHBzdGFuLWlnbm9yZS1saW5lCiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHN0YXRpYzo6QVJSQVlfTVNHKTsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgPSBwcmVnX3JlcGxhY2UoJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCwgJGNvdW50KTsKICAgICAgICBpZiAoJHJlc3VsdCA9PT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBQY3JlRXhjZXB0aW9uOjpmcm9tRnVuY3Rpb24oJ3ByZWdfcmVwbGFjZScsICRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkcGF0dGVybgogICAgICogQHBhcmFtIGNhbGxhYmxlICAgICAgICAkcmVwbGFjZW1lbnQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJHN1YmplY3QKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJGxpbWl0CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRjb3VudCBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRmbGFncyBQUkVHX09GRlNFVF9DQVBUVVJFIG9yIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjQrCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlcGxhY2VDYWxsYmFjaygkcGF0dGVybiwgJHJlcGxhY2VtZW50LCAkc3ViamVjdCwgJGxpbWl0ID0gLTEsICYkY291bnQgPSBudWxsLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgIGlmIChpc19hcnJheSgkc3ViamVjdCkpIHsgLy8gQHBocHN0YW4taWdub3JlLWxpbmUKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3RhdGljOjpBUlJBWV9NU0cpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDcwNDAwKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCwgJGNvdW50LCAkZmxhZ3MpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHBhdHRlcm4sICRyZXBsYWNlbWVudCwgJHN1YmplY3QsICRsaW1pdCwgJGNvdW50KTsKICAgICAgICB9CiAgICAgICAgaWYgKCRyZXN1bHQgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgUGNyZUV4Y2VwdGlvbjo6ZnJvbUZ1bmN0aW9uKCdwcmVnX3JlcGxhY2VfY2FsbGJhY2snLCAkcGF0dGVybik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEF2YWlsYWJsZSBmcm9tIFBIUCA3LjAKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBjYWxsYWJsZT4gJHBhdHRlcm4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1YmplY3QKICAgICAqIEBwYXJhbSBpbnQgICAgJGxpbWl0CiAgICAgKiBAcGFyYW0gaW50ICAgICRjb3VudCBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcGFyYW0gaW50ICAgICRmbGFncyBQUkVHX09GRlNFVF9DQVBUVVJFIG9yIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjQrCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlcGxhY2VDYWxsYmFja0FycmF5KGFycmF5ICRwYXR0ZXJuLCAkc3ViamVjdCwgJGxpbWl0ID0gLTEsICYkY291bnQgPSBudWxsLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgIGlmIChpc19hcnJheSgkc3ViamVjdCkpIHsgLy8gQHBocHN0YW4taWdub3JlLWxpbmUKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3RhdGljOjpBUlJBWV9NU0cpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDcwNDAwKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2tfYXJyYXkoJHBhdHRlcm4sICRzdWJqZWN0LCAkbGltaXQsICRjb3VudCwgJGZsYWdzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcmVzdWx0ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrX2FycmF5KCRwYXR0ZXJuLCAkc3ViamVjdCwgJGxpbWl0LCAkY291bnQpOwogICAgICAgIH0KICAgICAgICBpZiAoJHJlc3VsdCA9PT0gbnVsbCkgewogICAgICAgICAgICAkcGF0dGVybiA9IGFycmF5X2tleXMoJHBhdHRlcm4pOwogICAgICAgICAgICB0aHJvdyBQY3JlRXhjZXB0aW9uOjpmcm9tRnVuY3Rpb24oJ3ByZWdfcmVwbGFjZV9jYWxsYmFja19hcnJheScsICRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAkc3ViamVjdAogICAgICogQHBhcmFtIGludCAgICAkbGltaXQKICAgICAqIEBwYXJhbSBpbnQgICAgJGZsYWdzIFBSRUdfU1BMSVRfTk9fRU1QVFkgb3IgUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFCiAgICAgKiBAcmV0dXJuIGxpc3Q8c3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNwbGl0KCRwYXR0ZXJuLCAkc3ViamVjdCwgJGxpbWl0ID0gLTEsICRmbGFncyA9IDApCiAgICB7CiAgICAgICAgaWYgKCgkZmxhZ3MgJiBQUkVHX1NQTElUX09GRlNFVF9DQVBUVVJFKSAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUFJFR19TUExJVF9PRkZTRVRfQ0FQVFVSRSBpcyBub3Qgc3VwcG9ydGVkIGFzIGl0IGNoYW5nZXMgdGhlIHR5cGUgb2YgJG1hdGNoZXMsIHVzZSBzcGxpdFdpdGhPZmZzZXRzKCkgaW5zdGVhZCcpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IHByZWdfc3BsaXQoJHBhdHRlcm4sICRzdWJqZWN0LCAkbGltaXQsICRmbGFncyk7CiAgICAgICAgaWYgKCRyZXN1bHQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IFBjcmVFeGNlcHRpb246OmZyb21GdW5jdGlvbigncHJlZ19zcGxpdCcsICRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAkc3ViamVjdAogICAgICogQHBhcmFtIGludCAgICAkbGltaXQKICAgICAqIEBwYXJhbSBpbnQgICAgJGZsYWdzIFBSRUdfU1BMSVRfTk9fRU1QVFkgb3IgUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFCiAgICAgKiBAcmV0dXJuIGxpc3Q8YXJyYXl7c3RyaW5nLCBpbnR9PgogICAgICogQHBocHN0YW4tcmV0dXJuIGxpc3Q8YXJyYXl7c3RyaW5nLCBpbnQ8MCwgbWF4Pn0+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3BsaXRXaXRoT2Zmc2V0cygkcGF0dGVybiwgJHN1YmplY3QsICRsaW1pdCA9IC0xLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgICRyZXN1bHQgPSBwcmVnX3NwbGl0KCRwYXR0ZXJuLCAkc3ViamVjdCwgJGxpbWl0LCAkZmxhZ3MgfCBQUkVHX1NQTElUX09GRlNFVF9DQVBUVVJFKTsKICAgICAgICBpZiAoJHJlc3VsdCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgUGNyZUV4Y2VwdGlvbjo6ZnJvbUZ1bmN0aW9uKCdwcmVnX3NwbGl0JywgJHBhdHRlcm4pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGVtcGxhdGUgVCBvZiBzdHJpbmd8XFN0cmluZ2FibGUKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkcGF0dGVybgogICAgICogQHBhcmFtIGFycmF5PFQ+ICRhcnJheQogICAgICogQHBhcmFtIGludCAgICAgICRmbGFncyBQUkVHX0dSRVBfSU5WRVJUCiAgICAgKiBAcmV0dXJuIGFycmF5PFQ+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ3JlcCgkcGF0dGVybiwgYXJyYXkgJGFycmF5LCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgICRyZXN1bHQgPSBwcmVnX2dyZXAoJHBhdHRlcm4sICRhcnJheSwgJGZsYWdzKTsKICAgICAgICBpZiAoJHJlc3VsdCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgUGNyZUV4Y2VwdGlvbjo6ZnJvbUZ1bmN0aW9uKCdwcmVnX2dyZXAnLCAkcGF0dGVybik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICAgJHBhdHRlcm4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAkc3ViamVjdAogICAgICogQHBhcmFtIGFycmF5PHN0cmluZ3xudWxsPiAkbWF0Y2hlcyBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGZsYWdzIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjIrCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJG9mZnNldAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNNYXRjaCgkcGF0dGVybiwgJHN1YmplY3QsICYkbWF0Y2hlcyA9IG51bGwsICRmbGFncyA9IDAsICRvZmZzZXQgPSAwKQogICAgewogICAgICAgIHJldHVybiAoYm9vbCkgc3RhdGljOjptYXRjaCgkcGF0dGVybiwgJHN1YmplY3QsICRtYXRjaGVzLCAkZmxhZ3MsICRvZmZzZXQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgICAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAgICRzdWJqZWN0CiAgICAgKiBAcGFyYW0gYXJyYXk8aW50fHN0cmluZywgbGlzdDxzdHJpbmd8bnVsbD4+ICRtYXRjaGVzIFNldCBieSBtZXRob2QKICAgICAqIEBwYXJhbSBpbnQgICAgICAkZmxhZ3MgUFJFR19VTk1BVENIRURfQVNfTlVMTCwgb25seSBhdmFpbGFibGUgb24gUEhQIDcuMisKICAgICAqIEBwYXJhbSBpbnQgICAgICAkb2Zmc2V0CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc01hdGNoQWxsKCRwYXR0ZXJuLCAkc3ViamVjdCwgJiRtYXRjaGVzID0gbnVsbCwgJGZsYWdzID0gMCwgJG9mZnNldCA9IDApCiAgICB7CiAgICAgICAgcmV0dXJuIChib29sKSBzdGF0aWM6Om1hdGNoQWxsKCRwYXR0ZXJuLCAkc3ViamVjdCwgJG1hdGNoZXMsICRmbGFncywgJG9mZnNldCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHByZWdfbWF0Y2ggd2l0aCBQUkVHX09GRlNFVF9DQVBUVVJFCiAgICAgKgogICAgICogQHBhcmFtIG5vbi1lbXB0eS1zdHJpbmcgICAkcGF0dGVybgogICAgICogQHBhcmFtIHN0cmluZyAgICRzdWJqZWN0CiAgICAgKiBAcGFyYW0gYXJyYXk8aW50fHN0cmluZywgYXJyYXl7c3RyaW5nfG51bGwsIGludH0+ICRtYXRjaGVzIFNldCBieSBtZXRob2QKICAgICAqIEBwYXJhbSBpbnQgICAgICAkZmxhZ3MgUFJFR19VTk1BVENIRURfQVNfTlVMTCwgb25seSBhdmFpbGFibGUgb24gUEhQIDcuMisKICAgICAqIEBwYXJhbSBpbnQgICAgICAkb2Zmc2V0CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheTxpbnR8c3RyaW5nLCBhcnJheXtzdHJpbmd8bnVsbCwgaW50PC0xLCBtYXg+fT4gJG1hdGNoZXMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc01hdGNoV2l0aE9mZnNldHMoJHBhdHRlcm4sICRzdWJqZWN0LCAmJG1hdGNoZXMsICRmbGFncyA9IDAsICRvZmZzZXQgPSAwKQogICAgewogICAgICAgIHJldHVybiAoYm9vbCkgc3RhdGljOjptYXRjaFdpdGhPZmZzZXRzKCRwYXR0ZXJuLCAkc3ViamVjdCwgJG1hdGNoZXMsICRmbGFncywgJG9mZnNldCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHByZWdfbWF0Y2hfYWxsIHdpdGggUFJFR19PRkZTRVRfQ0FQVFVSRQogICAgICoKICAgICAqIEBwYXJhbSBub24tZW1wdHktc3RyaW5nICAgJHBhdHRlcm4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAkc3ViamVjdAogICAgICogQHBhcmFtIGFycmF5PGludHxzdHJpbmcsIGxpc3Q8YXJyYXl7c3RyaW5nfG51bGwsIGludH0+PiAkbWF0Y2hlcyBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGZsYWdzIFBSRUdfVU5NQVRDSEVEX0FTX05VTEwsIG9ubHkgYXZhaWxhYmxlIG9uIFBIUCA3LjIrCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJG9mZnNldAogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXk8aW50fHN0cmluZywgbGlzdDxhcnJheXtzdHJpbmd8bnVsbCwgaW50PC0xLCBtYXg+fT4+ICRtYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNNYXRjaEFsbFdpdGhPZmZzZXRzKCRwYXR0ZXJuLCAkc3ViamVjdCwgJiRtYXRjaGVzLCAkZmxhZ3MgPSAwLCAkb2Zmc2V0ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpIHN0YXRpYzo6bWF0Y2hBbGxXaXRoT2Zmc2V0cygkcGF0dGVybiwgJHN1YmplY3QsICRtYXRjaGVzLCAkZmxhZ3MsICRvZmZzZXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9wY3JlLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBjcmU7CgpmaW5hbCBjbGFzcyBNYXRjaFJlc3VsdAp7CiAgICAvKioKICAgICAqIEFuIGFycmF5IG9mIG1hdGNoIGdyb3VwID0+IHN0cmluZyBtYXRjaGVkCiAgICAgKgogICAgICogQHJlYWRvbmx5CiAgICAgKiBAdmFyIGFycmF5PGludHxzdHJpbmcsIHN0cmluZ3xudWxsPgogICAgICovCiAgICBwdWJsaWMgJG1hdGNoZXM7CgogICAgLyoqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJG1hdGNoZWQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gMHxwb3NpdGl2ZS1pbnQgJGNvdW50CiAgICAgKiBAcGFyYW0gYXJyYXk8c3RyaW5nfG51bGw+ICRtYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY291bnQsIGFycmF5ICRtYXRjaGVzKQogICAgewogICAgICAgICR0aGlzLT5tYXRjaGVzID0gJG1hdGNoZXM7CiAgICAgICAgJHRoaXMtPm1hdGNoZWQgPSAoYm9vbCkgJGNvdW50OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9wY3JlLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBjcmU7CgpmaW5hbCBjbGFzcyBNYXRjaEFsbFJlc3VsdAp7CiAgICAvKioKICAgICAqIEFuIGFycmF5IG9mIG1hdGNoIGdyb3VwID0+IGxpc3Qgb2YgbWF0Y2hlZCBzdHJpbmdzCiAgICAgKgogICAgICogQHJlYWRvbmx5CiAgICAgKiBAdmFyIGFycmF5PGludHxzdHJpbmcsIGxpc3Q8c3RyaW5nfG51bGw+PgogICAgICovCiAgICBwdWJsaWMgJG1hdGNoZXM7CgogICAgLyoqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgMHxwb3NpdGl2ZS1pbnQKICAgICAqLwogICAgcHVibGljICRjb3VudDsKCiAgICAvKioKICAgICAqIEByZWFkb25seQogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkbWF0Y2hlZDsKCiAgICAvKioKICAgICAqIEBwYXJhbSAwfHBvc2l0aXZlLWludCAkY291bnQKICAgICAqIEBwYXJhbSBhcnJheTxhcnJheTxzdHJpbmd8bnVsbD4+ICRtYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY291bnQsIGFycmF5ICRtYXRjaGVzKQogICAgewogICAgICAgICR0aGlzLT5tYXRjaGVzID0gJG1hdGNoZXM7CiAgICAgICAgJHRoaXMtPm1hdGNoZWQgPSAoYm9vbCkgJGNvdW50OwogICAgICAgICR0aGlzLT5jb3VudCA9ICRjb3VudDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvcGNyZS4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQY3JlOwoKZmluYWwgY2xhc3MgUmVwbGFjZVJlc3VsdAp7CiAgICAvKioKICAgICAqIEByZWFkb25seQogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRyZXN1bHQ7CgogICAgLyoqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgMHxwb3NpdGl2ZS1pbnQKICAgICAqLwogICAgcHVibGljICRjb3VudDsKCiAgICAvKioKICAgICAqIEByZWFkb25seQogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkbWF0Y2hlZDsKCiAgICAvKioKICAgICAqIEBwYXJhbSAwfHBvc2l0aXZlLWludCAkY291bnQKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlc3VsdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvdW50LCAkcmVzdWx0KQogICAgewogICAgICAgICR0aGlzLT5jb3VudCA9ICRjb3VudDsKICAgICAgICAkdGhpcy0+bWF0Y2hlZCA9IChib29sKSAkY291bnQ7CiAgICAgICAgJHRoaXMtPnJlc3VsdCA9ICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3BjcmUuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGNyZTsKCmZpbmFsIGNsYXNzIE1hdGNoV2l0aE9mZnNldHNSZXN1bHQKewogICAgLyoqCiAgICAgKiBBbiBhcnJheSBvZiBtYXRjaCBncm91cCA9PiBwYWlyIG9mIHN0cmluZyBtYXRjaGVkICsgb2Zmc2V0IGluIGJ5dGVzIChvciAtMSBpZiBubyBtYXRjaCkKICAgICAqCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB2YXIgYXJyYXk8aW50fHN0cmluZywgYXJyYXl7c3RyaW5nfG51bGwsIGludH0+CiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8aW50fHN0cmluZywgYXJyYXl7c3RyaW5nfG51bGwsIGludDwtMSwgbWF4Pn0+CiAgICAgKi8KICAgIHB1YmxpYyAkbWF0Y2hlczsKCiAgICAvKioKICAgICAqIEByZWFkb25seQogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkbWF0Y2hlZDsKCiAgICAvKioKICAgICAqIEBwYXJhbSAwfHBvc2l0aXZlLWludCAkY291bnQKICAgICAqIEBwYXJhbSBhcnJheTxhcnJheXtzdHJpbmd8bnVsbCwgaW50fT4gJG1hdGNoZXMKICAgICAqIEBwaHBzdGFuLXBhcmFtIGFycmF5PGludHxzdHJpbmcsIGFycmF5e3N0cmluZ3xudWxsLCBpbnQ8LTEsIG1heD59PiAkbWF0Y2hlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvdW50LCBhcnJheSAkbWF0Y2hlcykKICAgIHsKICAgICAgICAkdGhpcy0+bWF0Y2hlcyA9ICRtYXRjaGVzOwogICAgICAgICR0aGlzLT5tYXRjaGVkID0gKGJvb2wpICRjb3VudDsKICAgIH0KfQo8P3BocAoKLy8gYXV0b2xvYWRfbmFtZXNwYWNlcy5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKJHZlbmRvckRpciA9IGRpcm5hbWUoZGlybmFtZShfX0ZJTEVfXykpOwokYmFzZURpciA9IGRpcm5hbWUoJHZlbmRvckRpcik7CgpyZXR1cm4gYXJyYXkoCiAgICAnY2xpJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy93cC1jbGkvcGhwLWNsaS10b29scy9saWInKSwKICAgICdXUF9DTElcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvd3AtY2xpL3dwLWNsaS9waHAnKSwKICAgICdSZXF1ZXN0cycgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnknKSwKICAgICdPeHltZWwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL25iL294eW1lbCcpLAogICAgJ011c3RhY2hlJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9tdXN0YWNoZS9tdXN0YWNoZS9zcmMnKSwKKTsKPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXI7Cgp1c2UgQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcVmVyc2lvblBhcnNlcjsKCi8qKgogKiBUaGlzIGNsYXNzIGlzIGNvcGllZCBpbiBldmVyeSBDb21wb3NlciBpbnN0YWxsZWQgcHJvamVjdCBhbmQgYXZhaWxhYmxlIHRvIGFsbAogKgogKiBTZWUgYWxzbyBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDctcnVudGltZS5tZCNpbnN0YWxsZWQtdmVyc2lvbnMKICoKICogVG8gcmVxdWlyZSBpdHMgcHJlc2VuY2UsIHlvdSBjYW4gcmVxdWlyZSBgY29tcG9zZXItcnVudGltZS1hcGkgXjIuMGAKICovCmNsYXNzIEluc3RhbGxlZFZlcnNpb25zCnsKICAgIC8qKgogICAgICogQHZhciBtaXhlZFtdfG51bGwKICAgICAqIEBwc2FsbS12YXIgYXJyYXl7cm9vdDogYXJyYXl7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nLCBhbGlhc2VzOiBzdHJpbmdbXSwgZGV2OiBib29sLCBpbnN0YWxsX3BhdGg6IHN0cmluZywgdHlwZTogc3RyaW5nfSwgdmVyc2lvbnM6IGFycmF5PHN0cmluZywgYXJyYXl7ZGV2X3JlcXVpcmVtZW50OiBib29sLCBwcmV0dHlfdmVyc2lvbj86IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgYWxpYXNlcz86IHN0cmluZ1tdLCByZWZlcmVuY2U/OiBzdHJpbmcsIHJlcGxhY2VkPzogc3RyaW5nW10sIHByb3ZpZGVkPzogc3RyaW5nW10sIGluc3RhbGxfcGF0aD86IHN0cmluZywgdHlwZT86IHN0cmluZ30+fXxhcnJheXt9fG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGluc3RhbGxlZDsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbHxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRjYW5HZXRWZW5kb3JzOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheVtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYXJyYXl7cm9vdDogYXJyYXl7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nLCBhbGlhc2VzOiBzdHJpbmdbXSwgZGV2OiBib29sLCBpbnN0YWxsX3BhdGg6IHN0cmluZywgdHlwZTogc3RyaW5nfSwgdmVyc2lvbnM6IGFycmF5PHN0cmluZywgYXJyYXl7ZGV2X3JlcXVpcmVtZW50OiBib29sLCBwcmV0dHlfdmVyc2lvbj86IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgYWxpYXNlcz86IHN0cmluZ1tdLCByZWZlcmVuY2U/OiBzdHJpbmcsIHJlcGxhY2VkPzogc3RyaW5nW10sIHByb3ZpZGVkPzogc3RyaW5nW10sIGluc3RhbGxfcGF0aD86IHN0cmluZywgdHlwZT86IHN0cmluZ30+fT4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGluc3RhbGxlZEJ5VmVuZG9yID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCBwYWNrYWdlIG5hbWVzIHdoaWNoIGFyZSBwcmVzZW50LCBlaXRoZXIgYnkgYmVpbmcgaW5zdGFsbGVkLCByZXBsYWNlZCBvciBwcm92aWRlZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqIEBwc2FsbS1yZXR1cm4gbGlzdDxzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVkUGFja2FnZXMoKQogICAgewogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewogICAgICAgICAgICAkcGFja2FnZXNbXSA9IGFycmF5X2tleXMoJGluc3RhbGxlZFsndmVyc2lvbnMnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoMSA9PT0gXGNvdW50KCRwYWNrYWdlcykpIHsKICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlc1swXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheV9rZXlzKGFycmF5X2ZsaXAoXGNhbGxfdXNlcl9mdW5jX2FycmF5KCdhcnJheV9tZXJnZScsICRwYWNrYWdlcykpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCBwYWNrYWdlIG5hbWVzIHdpdGggYSBzcGVjaWZpYyB0eXBlIGUuZy4gJ2xpYnJhcnknCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAkdHlwZQogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICogQHBzYWxtLXJldHVybiBsaXN0PHN0cmluZz4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRJbnN0YWxsZWRQYWNrYWdlc0J5VHlwZSgkdHlwZSkKICAgIHsKICAgICAgICAkcGFja2FnZXNCeVR5cGUgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoIChzZWxmOjpnZXRJbnN0YWxsZWQoKSBhcyAkaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ10gYXMgJG5hbWUgPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZVsndHlwZSddKSAmJiAkcGFja2FnZVsndHlwZSddID09PSAkdHlwZSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc0J5VHlwZVtdID0gJG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXNCeVR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcGFja2FnZSBpcyBpbnN0YWxsZWQKICAgICAqCiAgICAgKiBUaGlzIGFsc28gcmV0dXJucyB0cnVlIGlmIHRoZSBwYWNrYWdlIG5hbWUgaXMgcHJvdmlkZWQgb3IgcmVwbGFjZWQgYnkgYW5vdGhlciBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhY2thZ2VOYW1lCiAgICAgKiBAcGFyYW0gIGJvb2wgICAkaW5jbHVkZURldlJlcXVpcmVtZW50cwogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNJbnN0YWxsZWQoJHBhY2thZ2VOYW1lLCAkaW5jbHVkZURldlJlcXVpcmVtZW50cyA9IHRydWUpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbmNsdWRlRGV2UmVxdWlyZW1lbnRzIHx8IGVtcHR5KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsnZGV2X3JlcXVpcmVtZW50J10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcGFja2FnZSBzYXRpc2ZpZXMgYSB2ZXJzaW9uIGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBlLmcuIElmIHlvdSB3YW50IHRvIGtub3cgd2hldGhlciB2ZXJzaW9uIDIuMysgb2YgcGFja2FnZSBmb28vYmFyIGlzIGluc3RhbGxlZCwgeW91IHdvdWxkIGNhbGw6CiAgICAgKgogICAgICogICBDb21wb3NlclxJbnN0YWxsZWRWZXJzaW9uczo6c2F0aXNmaWVzKG5ldyBWZXJzaW9uUGFyc2VyLCAnZm9vL2JhcicsICdeMi4zJykKICAgICAqCiAgICAgKiBAcGFyYW0gIFZlcnNpb25QYXJzZXIgJHBhcnNlciAgICAgIEluc3RhbGwgY29tcG9zZXIvc2VtdmVyIHRvIGhhdmUgYWNjZXNzIHRvIHRoaXMgY2xhc3MgYW5kIGZ1bmN0aW9uYWxpdHkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkcGFja2FnZU5hbWUKICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgICAkY29uc3RyYWludCAgQSB2ZXJzaW9uIGNvbnN0cmFpbnQgdG8gY2hlY2sgZm9yLCBpZiB5b3UgcGFzcyBvbmUgeW91IGhhdmUgdG8gbWFrZSBzdXJlIGNvbXBvc2VyL3NlbXZlciBpcyByZXF1aXJlZCBieSB5b3VyIHBhY2thZ2UKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhdGlzZmllcyhWZXJzaW9uUGFyc2VyICRwYXJzZXIsICRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJGNvbnN0cmFpbnQgPSAkcGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICAkcHJvdmlkZWQgPSAkcGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKHNlbGY6OmdldFZlcnNpb25SYW5nZXMoJHBhY2thZ2VOYW1lKSk7CgogICAgICAgIHJldHVybiAkcHJvdmlkZWQtPm1hdGNoZXMoJGNvbnN0cmFpbnQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHZlcnNpb24gY29uc3RyYWludCByZXByZXNlbnRpbmcgYWxsIHRoZSByYW5nZShzKSB3aGljaCBhcmUgaW5zdGFsbGVkIGZvciBhIGdpdmVuIHBhY2thZ2UKICAgICAqCiAgICAgKiBJdCBpcyBlYXNpZXIgdG8gdXNlIHRoaXMgdmlhIGlzSW5zdGFsbGVkKCkgd2l0aCB0aGUgJGNvbnN0cmFpbnQgYXJndW1lbnQgaWYgeW91IG5lZWQgdG8gY2hlY2sKICAgICAqIHdoZXRoZXIgYSBnaXZlbiB2ZXJzaW9uIG9mIGEgcGFja2FnZSBpcyBpbnN0YWxsZWQsIGFuZCBub3QganVzdCB3aGV0aGVyIGl0IGV4aXN0cwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmcgVmVyc2lvbiBjb25zdHJhaW50IHVzYWJsZSB3aXRoIGNvbXBvc2VyL3NlbXZlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFZlcnNpb25SYW5nZXMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJhbmdlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkcmFuZ2VzW10gPSAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ2FsaWFzZXMnLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkcmFuZ2VzID0gYXJyYXlfbWVyZ2UoJHJhbmdlcywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydhbGlhc2VzJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdyZXBsYWNlZCcsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICRyYW5nZXMgPSBhcnJheV9tZXJnZSgkcmFuZ2VzLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlcGxhY2VkJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdwcm92aWRlZCcsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICRyYW5nZXMgPSBhcnJheV9tZXJnZSgkcmFuZ2VzLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3Byb3ZpZGVkJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaW1wbG9kZSgnIHx8ICcsICRyYW5nZXMpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignUGFja2FnZSAiJyAuICRwYWNrYWdlTmFtZSAuICciIGlzIG5vdCBpbnN0YWxsZWQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIElmIHRoZSBwYWNrYWdlIGlzIGJlaW5nIHJlcGxhY2VkIG9yIHByb3ZpZGVkIGJ1dCBpcyBub3QgcmVhbGx5IGluc3RhbGxlZCwgbnVsbCB3aWxsIGJlIHJldHVybmVkIGFzIHZlcnNpb24sIHVzZSBzYXRpc2ZpZXMgb3IgZ2V0VmVyc2lvblJhbmdlcyBpZiB5b3UgbmVlZCB0byBrbm93IGlmIGEgZ2l2ZW4gdmVyc2lvbiBpcyBwcmVzZW50CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigkcGFja2FnZU5hbWUpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBJZiB0aGUgcGFja2FnZSBpcyBiZWluZyByZXBsYWNlZCBvciBwcm92aWRlZCBidXQgaXMgbm90IHJlYWxseSBpbnN0YWxsZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZCBhcyB2ZXJzaW9uLCB1c2Ugc2F0aXNmaWVzIG9yIGdldFZlcnNpb25SYW5nZXMgaWYgeW91IG5lZWQgdG8ga25vdyBpZiBhIGdpdmVuIHZlcnNpb24gaXMgcHJlc2VudAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFByZXR0eVZlcnNpb24oJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsncHJldHR5X3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBJZiB0aGUgcGFja2FnZSBpcyBiZWluZyByZXBsYWNlZCBvciBwcm92aWRlZCBidXQgaXMgbm90IHJlYWxseSBpbnN0YWxsZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZCBhcyByZWZlcmVuY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSZWZlcmVuY2UoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlZmVyZW5jZSddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlZmVyZW5jZSddOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignUGFja2FnZSAiJyAuICRwYWNrYWdlTmFtZSAuICciIGlzIG5vdCBpbnN0YWxsZWQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIElmIHRoZSBwYWNrYWdlIGlzIGJlaW5nIHJlcGxhY2VkIG9yIHByb3ZpZGVkIGJ1dCBpcyBub3QgcmVhbGx5IGluc3RhbGxlZCwgbnVsbCB3aWxsIGJlIHJldHVybmVkIGFzIGluc3RhbGwgcGF0aC4gUGFja2FnZXMgb2YgdHlwZSBtZXRhcGFja2FnZXMgYWxzbyBoYXZlIGEgbnVsbCBpbnN0YWxsIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5zdGFsbFBhdGgoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsnaW5zdGFsbF9wYXRoJ10pID8gJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydpbnN0YWxsX3BhdGgnXSA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXE91dE9mQm91bmRzRXhjZXB0aW9uKCdQYWNrYWdlICInIC4gJHBhY2thZ2VOYW1lIC4gJyIgaXMgbm90IGluc3RhbGxlZCcpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBzYWxtLXJldHVybiBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmcsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmcsIGFsaWFzZXM6IHN0cmluZ1tdLCBkZXY6IGJvb2wsIGluc3RhbGxfcGF0aDogc3RyaW5nLCB0eXBlOiBzdHJpbmd9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Um9vdFBhY2thZ2UoKQogICAgewogICAgICAgICRpbnN0YWxsZWQgPSBzZWxmOjpnZXRJbnN0YWxsZWQoKTsKCiAgICAgICAgcmV0dXJuICRpbnN0YWxsZWRbMF1bJ3Jvb3QnXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJhdyBpbnN0YWxsZWQucGhwIGRhdGEgZm9yIGN1c3RvbSBpbXBsZW1lbnRhdGlvbnMKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgZ2V0QWxsUmF3RGF0YSgpIGluc3RlYWQgd2hpY2ggcmV0dXJucyBhbGwgZGF0YXNldHMgZm9yIGFsbCBhdXRvbG9hZGVycyBwcmVzZW50IGluIHRoZSBwcm9jZXNzLiBnZXRSYXdEYXRhIG9ubHkgcmV0dXJucyB0aGUgZmlyc3QgZGF0YXNldCBsb2FkZWQsIHdoaWNoIG1heSBub3QgYmUgd2hhdCB5b3UgZXhwZWN0LgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5e3Jvb3Q6IGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZywgYWxpYXNlczogc3RyaW5nW10sIGRldjogYm9vbCwgaW5zdGFsbF9wYXRoOiBzdHJpbmcsIHR5cGU6IHN0cmluZ30sIHZlcnNpb25zOiBhcnJheTxzdHJpbmcsIGFycmF5e2Rldl9yZXF1aXJlbWVudDogYm9vbCwgcHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdLCBpbnN0YWxsX3BhdGg/OiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9Pn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSYXdEYXRhKCkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcignZ2V0UmF3RGF0YSBvbmx5IHJldHVybnMgdGhlIGZpcnN0IGRhdGFzZXQgbG9hZGVkLCB3aGljaCBtYXkgbm90IGJlIHdoYXQgeW91IGV4cGVjdC4gVXNlIGdldEFsbFJhd0RhdGEoKSBpbnN0ZWFkIHdoaWNoIHJldHVybnMgYWxsIGRhdGFzZXRzIGZvciBhbGwgYXV0b2xvYWRlcnMgcHJlc2VudCBpbiB0aGUgcHJvY2Vzcy4nLCBFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaW5zdGFsbGVkKSB7CiAgICAgICAgICAgIC8vIG9ubHkgcmVxdWlyZSB0aGUgaW5zdGFsbGVkLnBocCBmaWxlIGlmIHRoaXMgZmlsZSBpcyBsb2FkZWQgZnJvbSBpdHMgZHVtcGVkIGxvY2F0aW9uLAogICAgICAgICAgICAvLyBhbmQgbm90IGZyb20gaXRzIHNvdXJjZSBsb2NhdGlvbiBpbiB0aGUgY29tcG9zZXIvY29tcG9zZXIgcGFja2FnZSwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvOTkzNwogICAgICAgICAgICBpZiAoc3Vic3RyKF9fRElSX18sIC04LCAxKSAhPT0gJ0MnKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokaW5zdGFsbGVkID0gaW5jbHVkZSBfX0RJUl9fIC4gJy9pbnN0YWxsZWQucGhwJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbGY6OiRpbnN0YWxsZWQgPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGluc3RhbGxlZDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJhdyBkYXRhIG9mIGFsbCBpbnN0YWxsZWQucGhwIHdoaWNoIGFyZSBjdXJyZW50bHkgbG9hZGVkIGZvciBjdXN0b20gaW1wbGVtZW50YXRpb25zCiAgICAgKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGxpc3Q8YXJyYXl7cm9vdDogYXJyYXl7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nLCBhbGlhc2VzOiBzdHJpbmdbXSwgZGV2OiBib29sLCBpbnN0YWxsX3BhdGg6IHN0cmluZywgdHlwZTogc3RyaW5nfSwgdmVyc2lvbnM6IGFycmF5PHN0cmluZywgYXJyYXl7ZGV2X3JlcXVpcmVtZW50OiBib29sLCBwcmV0dHlfdmVyc2lvbj86IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgYWxpYXNlcz86IHN0cmluZ1tdLCByZWZlcmVuY2U/OiBzdHJpbmcsIHJlcGxhY2VkPzogc3RyaW5nW10sIHByb3ZpZGVkPzogc3RyaW5nW10sIGluc3RhbGxfcGF0aD86IHN0cmluZywgdHlwZT86IHN0cmluZ30+fT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRBbGxSYXdEYXRhKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0SW5zdGFsbGVkKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBMZXRzIHlvdSByZWxvYWQgdGhlIHN0YXRpYyBhcnJheSBmcm9tIGFub3RoZXIgZmlsZQogICAgICoKICAgICAqIFRoaXMgaXMgb25seSB1c2VmdWwgZm9yIGNvbXBsZXggaW50ZWdyYXRpb25zIGluIHdoaWNoIGEgcHJvamVjdCBuZWVkcyB0byB1c2UKICAgICAqIHRoaXMgY2xhc3MgYnV0IHRoZW4gYWxzbyBuZWVkcyB0byBleGVjdXRlIGFub3RoZXIgcHJvamVjdCdzIGF1dG9sb2FkZXIgaW4gcHJvY2VzcywKICAgICAqIGFuZCB3YW50cyB0byBlbnN1cmUgYm90aCBwcm9qZWN0cyBoYXZlIGFjY2VzcyB0byB0aGVpciB2ZXJzaW9uIG9mIGluc3RhbGxlZC5waHAuCiAgICAgKgogICAgICogQSB0eXBpY2FsIGNhc2Ugd291bGQgYmUgUEhQVW5pdCwgd2hlcmUgaXQgd291bGQgbmVlZCB0byBtYWtlIHN1cmUgaXQgcmVhZHMgYWxsCiAgICAgKiB0aGUgZGF0YSBpdCBuZWVkcyBmcm9tIHRoaXMgY2xhc3MsIHRoZW4gY2FsbCByZWxvYWQoKSB3aXRoCiAgICAgKiBgcmVxdWlyZSAkQ1dEL3ZlbmRvci9jb21wb3Nlci9pbnN0YWxsZWQucGhwYCAob3Igc2ltaWxhcikgYXMgaW5wdXQgdG8gbWFrZSBzdXJlCiAgICAgKiB0aGUgcHJvamVjdCBpbiB3aGljaCBpdCBydW5zIGNhbiB0aGVuIGFsc28gdXNlIHRoaXMgY2xhc3Mgc2FmZWx5LCB3aXRob3V0CiAgICAgKiBpbnRlcmZlcmVuY2UgYmV0d2VlbiBQSFBVbml0J3MgZGVwZW5kZW5jaWVzIGFuZCB0aGUgcHJvamVjdCdzIGRlcGVuZGVuY2llcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5W10gJGRhdGEgQSB2ZW5kb3IvY29tcG9zZXIvaW5zdGFsbGVkLnBocCBkYXRhIHNldAogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHBzYWxtLXBhcmFtIGFycmF5e3Jvb3Q6IGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZywgYWxpYXNlczogc3RyaW5nW10sIGRldjogYm9vbCwgaW5zdGFsbF9wYXRoOiBzdHJpbmcsIHR5cGU6IHN0cmluZ30sIHZlcnNpb25zOiBhcnJheTxzdHJpbmcsIGFycmF5e2Rldl9yZXF1aXJlbWVudDogYm9vbCwgcHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdLCBpbnN0YWxsX3BhdGg/OiBzdHJpbmcsIHR5cGU/OiBzdHJpbmd9Pn0gJGRhdGEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZWxvYWQoJGRhdGEpCiAgICB7CiAgICAgICAgc2VsZjo6JGluc3RhbGxlZCA9ICRkYXRhOwogICAgICAgIHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvciA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5W10KICAgICAqIEBwc2FsbS1yZXR1cm4gbGlzdDxhcnJheXtyb290OiBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmcsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmcsIGFsaWFzZXM6IHN0cmluZ1tdLCBkZXY6IGJvb2wsIGluc3RhbGxfcGF0aDogc3RyaW5nLCB0eXBlOiBzdHJpbmd9LCB2ZXJzaW9uczogYXJyYXk8c3RyaW5nLCBhcnJheXtkZXZfcmVxdWlyZW1lbnQ6IGJvb2wsIHByZXR0eV92ZXJzaW9uPzogc3RyaW5nLCB2ZXJzaW9uPzogc3RyaW5nLCBhbGlhc2VzPzogc3RyaW5nW10sIHJlZmVyZW5jZT86IHN0cmluZywgcmVwbGFjZWQ/OiBzdHJpbmdbXSwgcHJvdmlkZWQ/OiBzdHJpbmdbXSwgaW5zdGFsbF9wYXRoPzogc3RyaW5nLCB0eXBlPzogc3RyaW5nfT59PgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRJbnN0YWxsZWQoKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokY2FuR2V0VmVuZG9ycykgewogICAgICAgICAgICBzZWxmOjokY2FuR2V0VmVuZG9ycyA9IG1ldGhvZF9leGlzdHMoJ0NvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyJywgJ2dldFJlZ2lzdGVyZWRMb2FkZXJzJyk7CiAgICAgICAgfQoKICAgICAgICAkaW5zdGFsbGVkID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKHNlbGY6OiRjYW5HZXRWZW5kb3JzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKENsYXNzTG9hZGVyOjpnZXRSZWdpc3RlcmVkTG9hZGVycygpIGFzICR2ZW5kb3JEaXIgPT4gJGxvYWRlcikgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvclskdmVuZG9yRGlyXSkpIHsKICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbGVkW10gPSBzZWxmOjokaW5zdGFsbGVkQnlWZW5kb3JbJHZlbmRvckRpcl07CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNfZmlsZSgkdmVuZG9yRGlyLicvY29tcG9zZXIvaW5zdGFsbGVkLnBocCcpKSB7CiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxlZFtdID0gc2VsZjo6JGluc3RhbGxlZEJ5VmVuZG9yWyR2ZW5kb3JEaXJdID0gcmVxdWlyZSAkdmVuZG9yRGlyLicvY29tcG9zZXIvaW5zdGFsbGVkLnBocCc7CiAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiRpbnN0YWxsZWQgJiYgc3RydHIoJHZlbmRvckRpci4nL2NvbXBvc2VyJywgJ1xcJywgJy8nKSA9PT0gc3RydHIoX19ESVJfXywgJ1xcJywgJy8nKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmOjokaW5zdGFsbGVkID0gJGluc3RhbGxlZFtjb3VudCgkaW5zdGFsbGVkKSAtIDFdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgLy8gb25seSByZXF1aXJlIHRoZSBpbnN0YWxsZWQucGhwIGZpbGUgaWYgdGhpcyBmaWxlIGlzIGxvYWRlZCBmcm9tIGl0cyBkdW1wZWQgbG9jYXRpb24sCiAgICAgICAgICAgIC8vIGFuZCBub3QgZnJvbSBpdHMgc291cmNlIGxvY2F0aW9uIGluIHRoZSBjb21wb3Nlci9jb21wb3NlciBwYWNrYWdlLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy85OTM3CiAgICAgICAgICAgIGlmIChzdWJzdHIoX19ESVJfXywgLTgsIDEpICE9PSAnQycpIHsKICAgICAgICAgICAgICAgIHNlbGY6OiRpbnN0YWxsZWQgPSByZXF1aXJlIF9fRElSX18gLiAnL2luc3RhbGxlZC5waHAnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsZjo6JGluc3RhbGxlZCA9IGFycmF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGluc3RhbGxlZFtdID0gc2VsZjo6JGluc3RhbGxlZDsKCiAgICAgICAgcmV0dXJuICRpbnN0YWxsZWQ7CiAgICB9Cn0KPD9waHAKCi8vIGF1dG9sb2FkX2ZpbGVzLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokdmVuZG9yRGlyID0gZGlybmFtZShkaXJuYW1lKF9fRklMRV9fKSk7CiRiYXNlRGlyID0gZGlybmFtZSgkdmVuZG9yRGlyKTsKCnJldHVybiBhcnJheSgKICAgICczMjBjZGUyMmY2NmRkNGY1ZDNmZDYyMWQzZTg4Yjk4ZicgPT4gJHZlbmRvckRpciAuICcvc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZS9ib290c3RyYXAucGhwJywKICAgICcwZTZkN2JmNGE1ODExYmZhNWNmNDBjNWNjZDZmYWU2YScgPT4gJHZlbmRvckRpciAuICcvc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9ib290c3RyYXAucGhwJywKICAgICdhZDE1NWY4ZjFjZjBkNDE4ZmU0OWUyNDhkYjhjNjYxYicgPT4gJHZlbmRvckRpciAuICcvcmVhY3QvcHJvbWlzZS9zcmMvZnVuY3Rpb25zX2luY2x1ZGUucGhwJywKICAgICdiZTAxYjliMTY5MjVkY2IyMjE2NWM0MGI0NjY4MWFjNicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9jbGkucGhwJywKICAgICczOTM3ODA2MTA1Y2M4ZTIyMWI4ZmE4ZGI1YjcwZDJmMicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9pbmNsdWRlcy9mdW5jdGlvbnMucGhwJywKICAgICdiYTM2NmY5NmY0ZmRkYmRlZjYxYWQ3YTg2MmI0NGY2MScgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3BhY2thZ2UtY29tbWFuZC9wYWNrYWdlLWNvbW1hbmQucGhwJywKICAgICc4YTBhZDAyZGY2YTUwODdmMmMzODBmOGZkNTJkYjI3MycgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL2NhY2hlLWNvbW1hbmQvY2FjaGUtY29tbWFuZC5waHAnLAogICAgJ2YzZjAxOTlhM2VjZDlmNTAxZDBhM2IzNjFiZDJmNjFjJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvZW50aXR5LWNvbW1hbmQvZW50aXR5LWNvbW1hbmQucGhwJywKICAgICczZjIwMTAzM2Q1YWNlYjIyOTMzMTQyNzNiZTg4ZjdjNicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL2V4dGVuc2lvbi1jb21tYW5kLnBocCcsCiAgICAnYzY1Zjc1MzM3NWZhZWUzNDliN2FkYzQ4YzJlZTdjYzInID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9kYi1jb21tYW5kL2RiLWNvbW1hbmQucGhwJywKICAgICc1ZTA5OWQzY2FjNjc3ZGQyYmVjMTAwM2VhNzcwNzc0NScgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL21lZGlhLWNvbW1hbmQvbWVkaWEtY29tbWFuZC5waHAnLAogICAgJ2Q5NzljMTFmZTgwYmE5NmFlMzAzN2I0MzQyOWZlNTQ2JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC9zY2FmZm9sZC1jb21tYW5kLnBocCcsCiAgICAnNWM2ZWM1Y2ZmOGY5ZDYyNTc3MmM4ZWQxNDdmNmI4OTQnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9leHBvcnQtY29tbWFuZC9leHBvcnQtY29tbWFuZC5waHAnLAogICAgJ2FjOTQ5Y2U0MGE5ODE4MTliYTEzMjQ3MzUxOGE5YTMxJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvd3AtY29uZmlnLXRyYW5zZm9ybWVyL3NyYy9XUENvbmZpZ1RyYW5zZm9ybWVyLnBocCcsCiAgICAnYjY2ZDI5NzU3ZmNiMmZiN2E5NjA4ZDA2OGUzNzE2YjAnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL2NoZWNrc3VtLWNvbW1hbmQucGhwJywKICAgICczMGNiYjZlNDEyMmRjOTg4ZTQ5NGM2YjljMDQzODIzMycgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL2ltcG9ydC1jb21tYW5kL2ltcG9ydC1jb21tYW5kLnBocCcsCiAgICAnOWYwNGRkMGFhNWQ2N2VjNzVhNzVjODhjMzQ1YTA3OWUnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zZXJ2ZXItY29tbWFuZC9zZXJ2ZXItY29tbWFuZC5waHAnLAogICAgJzg1MTk3NzliYmI2NWVlYjg0MmFmMmY2MjljZTdiNmY4JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvc3VwZXItYWRtaW4tY29tbWFuZC9zdXBlci1hZG1pbi1jb21tYW5kLnBocCcsCiAgICAnNWRlYWY2Y2U5YzhiYmRmYjY1MTA0YzdlOTM4ZDU4NzUnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jb25maWctY29tbWFuZC9jb25maWctY29tbWFuZC5waHAnLAogICAgJzY4YzM5Yjg4MjE1YjZjZjdhMGRhMTY0MTY2NjcwZWY5JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvY29yZS1jb21tYW5kL2NvcmUtY29tbWFuZC5waHAnLAogICAgJzc2NTRlMDBiZjBlNjMyNTgwNzY0NDAwYmQ4MjkzYTljJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvY3Jvbi1jb21tYW5kL2Nyb24tY29tbWFuZC5waHAnLAogICAgJzAyMWQzYTEzNDcxNTU2ZjBiNTcwMzhkNjc5ZjdmOGVhJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvZW1iZWQtY29tbWFuZC9lbWJlZC1jb21tYW5kLnBocCcsCiAgICAnZjk1OGRjYTNmNDEyZmQ3OTc1ZGExNzAwOTEyYTkzMjEnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9ldmFsLWNvbW1hbmQvZXZhbC1jb21tYW5kLnBocCcsCiAgICAnZmZiNDY1YTQ5NGMzMTAxMjE4YzQ0MTcxODBjMmM5YTInID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9pMThuLWNvbW1hbmQvaTE4bi1jb21tYW5kLnBocCcsCiAgICAnMWM4OGMxZWZmMDUyMTdhOGNhYzgwYzY0YzlhYzIwODAnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQvbWFpbnRlbmFuY2UtbW9kZS1jb21tYW5kLnBocCcsCiAgICAnYWNlMGQyMDVkYjdmNDEzNWVjMzIxMzJhMDA3NmQ1NTUnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL2xhbmd1YWdlLWNvbW1hbmQucGhwJywKICAgICdmMzk5YzFjOGQwYzc4N2Q1Yzk0YzA5ODg0Y2RkOTc2MicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3Jld3JpdGUtY29tbWFuZC9yZXdyaXRlLWNvbW1hbmQucGhwJywKICAgICcwODBmYWRkNjY3MTk1ZDA1NWM1YTIzMzg2ZjI3MDI2MScgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3JvbGUtY29tbWFuZC9yb2xlLWNvbW1hbmQucGhwJywKICAgICc4ZWNiMTNmOGJiYzIyYjFiMzRkMTJiMTRlYzAxMDc3YScgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC5waHAnLAogICAgJzEyOWQ1OGZhODE1MTM3NGFjZWI4NTcxYmNhYTk3NTA0JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvc2hlbGwtY29tbWFuZC9zaGVsbC1jb21tYW5kLnBocCcsCiAgICAnMWYwNTM3MmFmY2M3ZDBjNTFhMzA1Y2VmMWQ1NmRkMDEnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS93aWRnZXQtY29tbWFuZC93aWRnZXQtY29tbWFuZC5waHAnLAopOwo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlcjsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTXVsdGlDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKCi8qKgogKiBWZXJzaW9uIHBhcnNlci4KICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVmVyc2lvblBhcnNlcgp7CiAgICAvKioKICAgICAqIFJlZ2V4IHRvIG1hdGNoIHByZS1yZWxlYXNlIGRhdGEgKHNvcnQgb2YpLgogICAgICoKICAgICAqIER1ZSB0byBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eToKICAgICAqICAgLSBJbnN0ZWFkIG9mIGVuZm9yY2luZyBoeXBoZW4sIGFuIHVuZGVyc2NvcmUsIGRvdCBvciBub3RoaW5nIGF0IGFsbCBhcmUgYWxzbyBhY2NlcHRlZC4KICAgICAqICAgLSBPbmx5IHN0YWJpbGl0aWVzIGFzIHJlY29nbml6ZWQgYnkgQ29tcG9zZXIgYXJlIGFsbG93ZWQgdG8gcHJlY2VkZSBhIG51bWVyaWNhbCBpZGVudGlmaWVyLgogICAgICogICAtIE51bWVyaWNhbC1vbmx5IHByZS1yZWxlYXNlIGlkZW50aWZpZXJzIGFyZSBub3Qgc3VwcG9ydGVkLCBzZWUgdGVzdHMuCiAgICAgKgogICAgICogICAgICAgICAgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS18CiAgICAgKiBbbWFqb3JdLlttaW5vcl0uW3BhdGNoXSAtW3ByZS1yZWxlYXNlXSArW2J1aWxkLW1ldGFkYXRhXQogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRtb2RpZmllclJlZ2V4ID0gJ1suXy1dPyg/OihzdGFibGV8YmV0YXxifFJDfGFscGhhfGF8cGF0Y2h8cGx8cCkoKD86Wy4tXT9cZCspKispPyk/KFsuLV0/ZGV2KT8nOwoKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHN0YWJpbGl0aWVzUmVnZXggPSAnc3RhYmxlfFJDfGJldGF8YWxwaGF8ZGV2JzsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YWJpbGl0eSBvZiBhIHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gJ3N0YWJsZSd8J1JDJ3wnYmV0YSd8J2FscGhhJ3wnZGV2JwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhcnNlU3RhYmlsaXR5KCR2ZXJzaW9uKQogICAgewogICAgICAgICR2ZXJzaW9uID0gKHN0cmluZykgcHJlZ19yZXBsYWNlKCd7Iy4rJH0nLCAnJywgJHZlcnNpb24pOwoKICAgICAgICBpZiAoc3RycG9zKCR2ZXJzaW9uLCAnZGV2LScpID09PSAwIHx8ICctZGV2JyA9PT0gc3Vic3RyKCR2ZXJzaW9uLCAtNCkpIHsKICAgICAgICAgICAgcmV0dXJuICdkZXYnOwogICAgICAgIH0KCiAgICAgICAgcHJlZ19tYXRjaCgneycgLiBzZWxmOjokbW9kaWZpZXJSZWdleCAuICcoPzpcKy4qKT8kfWknLCBzdHJ0b2xvd2VyKCR2ZXJzaW9uKSwgJG1hdGNoKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbM10pKSB7CiAgICAgICAgICAgIHJldHVybiAnZGV2JzsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJG1hdGNoWzFdKSkgewogICAgICAgICAgICBpZiAoJ2JldGEnID09PSAkbWF0Y2hbMV0gfHwgJ2InID09PSAkbWF0Y2hbMV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAnYmV0YSc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCdhbHBoYScgPT09ICRtYXRjaFsxXSB8fCAnYScgPT09ICRtYXRjaFsxXSkgewogICAgICAgICAgICAgICAgcmV0dXJuICdhbHBoYSc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCdyYycgPT09ICRtYXRjaFsxXSkgewogICAgICAgICAgICAgICAgcmV0dXJuICdSQyc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAnc3RhYmxlJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0YWJpbGl0eQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbm9ybWFsaXplU3RhYmlsaXR5KCRzdGFiaWxpdHkpCiAgICB7CiAgICAgICAgJHN0YWJpbGl0eSA9IHN0cnRvbG93ZXIoJHN0YWJpbGl0eSk7CgogICAgICAgIHJldHVybiAkc3RhYmlsaXR5ID09PSAncmMnID8gJ1JDJyA6ICRzdGFiaWxpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWxpemVzIGEgdmVyc2lvbiBzdHJpbmcgdG8gYmUgYWJsZSB0byBwZXJmb3JtIGNvbXBhcmlzb25zIG9uIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJGZ1bGxWZXJzaW9uIG9wdGlvbmFsIGNvbXBsZXRlIHZlcnNpb24gc3RyaW5nIHRvIGdpdmUgbW9yZSBjb250ZXh0CiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vcm1hbGl6ZSgkdmVyc2lvbiwgJGZ1bGxWZXJzaW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkdmVyc2lvbiA9IHRyaW0oJHZlcnNpb24pOwogICAgICAgICRvcmlnVmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgIGlmIChudWxsID09PSAkZnVsbFZlcnNpb24pIHsKICAgICAgICAgICAgJGZ1bGxWZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgfQoKICAgICAgICAvLyBzdHJpcCBvZmYgYWxpYXNpbmcKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oW14sXHNdKyspICsrYXMgKysoW14sXHNdKyspJH0nLCAkdmVyc2lvbiwgJG1hdGNoKSkgewogICAgICAgICAgICAkdmVyc2lvbiA9ICRtYXRjaFsxXTsKICAgICAgICB9CgogICAgICAgIC8vIHN0cmlwIG9mZiBzdGFiaWxpdHkgZmxhZwogICAgICAgIGlmIChwcmVnX21hdGNoKCd7QCg/OicgLiBzZWxmOjokc3RhYmlsaXRpZXNSZWdleCAuICcpJH1pJywgJHZlcnNpb24sICRtYXRjaCkpIHsKICAgICAgICAgICAgJHZlcnNpb24gPSBzdWJzdHIoJHZlcnNpb24sIDAsIHN0cmxlbigkdmVyc2lvbikgLSBzdHJsZW4oJG1hdGNoWzBdKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBub3JtYWxpemUgbWFzdGVyL3RydW5rL2RlZmF1bHQgYnJhbmNoZXMgdG8gZGV2LW5hbWUgZm9yIEJDIHdpdGggMS54IGFzIHRoZXNlIHVzZWQgdG8gYmUgdmFsaWQgY29uc3RyYWludHMKICAgICAgICBpZiAoXGluX2FycmF5KCR2ZXJzaW9uLCBhcnJheSgnbWFzdGVyJywgJ3RydW5rJywgJ2RlZmF1bHQnKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgJHZlcnNpb24gPSAnZGV2LScgLiAkdmVyc2lvbjsKICAgICAgICB9CgogICAgICAgIC8vIGlmIHJlcXVpcmVtZW50IGlzIGJyYW5jaC1saWtlLCB1c2UgZnVsbCBuYW1lCiAgICAgICAgaWYgKHN0cmlwb3MoJHZlcnNpb24sICdkZXYtJykgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICdkZXYtJyAuIHN1YnN0cigkdmVyc2lvbiwgNCk7CiAgICAgICAgfQoKICAgICAgICAvLyBzdHJpcCBvZmYgYnVpbGQgbWV0YWRhdGEKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oW14sXHMrXSsrKVwrW15cc10rKyR9JywgJHZlcnNpb24sICRtYXRjaCkpIHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkbWF0Y2hbMV07CiAgICAgICAgfQoKICAgICAgICAvLyBtYXRjaCBjbGFzc2ljYWwgdmVyc2lvbmluZwogICAgICAgIGlmIChwcmVnX21hdGNoKCd7XnY/KFxkezEsNX0pKFwuXGQrKyk/KFwuXGQrKyk/KFwuXGQrKyk/JyAuIHNlbGY6OiRtb2RpZmllclJlZ2V4IC4gJyR9aScsICR2ZXJzaW9uLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkbWF0Y2hlc1sxXQogICAgICAgICAgICAgICAgLiAoIWVtcHR5KCRtYXRjaGVzWzJdKSA/ICRtYXRjaGVzWzJdIDogJy4wJykKICAgICAgICAgICAgICAgIC4gKCFlbXB0eSgkbWF0Y2hlc1szXSkgPyAkbWF0Y2hlc1szXSA6ICcuMCcpCiAgICAgICAgICAgICAgICAuICghZW1wdHkoJG1hdGNoZXNbNF0pID8gJG1hdGNoZXNbNF0gOiAnLjAnKTsKICAgICAgICAgICAgJGluZGV4ID0gNTsKICAgICAgICAvLyBtYXRjaCBkYXRlKHRpbWUpIGJhc2VkIHZlcnNpb25pbmcKICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgne152PyhcZHs0fSg/OlsuOi1dP1xkezJ9KXsxLDZ9KD86Wy46LV0/XGR7MSwzfSk/KScgLiBzZWxmOjokbW9kaWZpZXJSZWdleCAuICckfWknLCAkdmVyc2lvbiwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gcHJlZ19yZXBsYWNlKCd7XER9JywgJy4nLCAkbWF0Y2hlc1sxXSk7CiAgICAgICAgICAgICRpbmRleCA9IDI7CiAgICAgICAgfQoKICAgICAgICAvLyBhZGQgdmVyc2lvbiBtb2RpZmllcnMgaWYgYSB2ZXJzaW9uIHdhcyBtYXRjaGVkCiAgICAgICAgaWYgKGlzc2V0KCRpbmRleCkpIHsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hlc1skaW5kZXhdKSkgewogICAgICAgICAgICAgICAgaWYgKCdzdGFibGUnID09PSAkbWF0Y2hlc1skaW5kZXhdKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHZlcnNpb24gLj0gJy0nIC4gJHRoaXMtPmV4cGFuZFN0YWJpbGl0eSgkbWF0Y2hlc1skaW5kZXhdKSAuIChpc3NldCgkbWF0Y2hlc1skaW5kZXggKyAxXSkgJiYgJycgIT09ICRtYXRjaGVzWyRpbmRleCArIDFdID8gbHRyaW0oJG1hdGNoZXNbJGluZGV4ICsgMV0sICcuLScpIDogJycpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaGVzWyRpbmRleCArIDJdKSkgewogICAgICAgICAgICAgICAgJHZlcnNpb24gLj0gJy1kZXYnOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHZlcnNpb247CiAgICAgICAgfQoKICAgICAgICAvLyBtYXRjaCBkZXYgYnJhbmNoZXMKICAgICAgICBpZiAocHJlZ19tYXRjaCgneyguKj8pWy4tXT9kZXYkfWknLCAkdmVyc2lvbiwgJG1hdGNoKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJG5vcm1hbGl6ZWQgPSAkdGhpcy0+bm9ybWFsaXplQnJhbmNoKCRtYXRjaFsxXSk7CiAgICAgICAgICAgICAgICAvLyBhIGJyYW5jaCBlbmRpbmcgd2l0aCAtZGV2IGlzIG9ubHkgdmFsaWQgaWYgaXQgaXMgbnVtZXJpYwogICAgICAgICAgICAgICAgLy8gaWYgaXQgZ2V0cyBwcmVmaXhlZCB3aXRoIGRldi0gaXQgbWVhbnMgdGhlIGJyYW5jaCBuYW1lIHNob3VsZAogICAgICAgICAgICAgICAgLy8gaGF2ZSBoYWQgYSBkZXYtIHByZWZpeCBhbHJlYWR5IHdoZW4gcGFzc2VkIHRvIG5vcm1hbGl6ZQogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkbm9ybWFsaXplZCwgJ2Rldi0nKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJG5vcm1hbGl6ZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGV4dHJhTWVzc2FnZSA9ICcnOwogICAgICAgIGlmIChwcmVnX21hdGNoKCd7ICthcyArJyAuIHByZWdfcXVvdGUoJHZlcnNpb24pIC4gJyg/OkAoPzonLnNlbGY6OiRzdGFiaWxpdGllc1JlZ2V4LicpKT8kfScsICRmdWxsVmVyc2lvbikpIHsKICAgICAgICAgICAgJGV4dHJhTWVzc2FnZSA9ICcgaW4gIicgLiAkZnVsbFZlcnNpb24gLiAnIiwgdGhlIGFsaWFzIG11c3QgYmUgYW4gZXhhY3QgdmVyc2lvbic7CiAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJ3teJyAuIHByZWdfcXVvdGUoJHZlcnNpb24pIC4gJyg/OkAoPzonLnNlbGY6OiRzdGFiaWxpdGllc1JlZ2V4LicpKT8gK2FzICt9JywgJGZ1bGxWZXJzaW9uKSkgewogICAgICAgICAgICAkZXh0cmFNZXNzYWdlID0gJyBpbiAiJyAuICRmdWxsVmVyc2lvbiAuICciLCB0aGUgYWxpYXMgc291cmNlIG11c3QgYmUgYW4gZXhhY3QgdmVyc2lvbiwgaWYgaXQgaXMgYSBicmFuY2ggbmFtZSB5b3Ugc2hvdWxkIHByZWZpeCBpdCB3aXRoIGRldi0nOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0ludmFsaWQgdmVyc2lvbiBzdHJpbmcgIicgLiAkb3JpZ1ZlcnNpb24gLiAnIicgLiAkZXh0cmFNZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgbnVtZXJpYyBwcmVmaXggZnJvbSBhbGlhcywgaWYgaXQgaXMgaW4gbnVtZXJpYyBmb3JtYXQsIHN1aXRhYmxlIGZvciB2ZXJzaW9uIGNvbXBhcmlzb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYnJhbmNoIEJyYW5jaCBuYW1lIChlLmcuIDIuMS54LWRldikKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBOdW1lcmljIHByZWZpeCBpZiBwcmVzZW50IChlLmcuIDIuMS4pIG9yIGZhbHNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZU51bWVyaWNBbGlhc1ByZWZpeCgkYnJhbmNoKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xig/UDx2ZXJzaW9uPihcZCsrXFwuKSpcZCsrKSg/OlwueCk/LWRldiR9aScsICRicmFuY2gsICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ3ZlcnNpb24nXSAuICcuJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZXMgYSBicmFuY2ggbmFtZSB0byBiZSBhYmxlIHRvIHBlcmZvcm0gY29tcGFyaXNvbnMgb24gaXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemVCcmFuY2goJG5hbWUpCiAgICB7CiAgICAgICAgJG5hbWUgPSB0cmltKCRuYW1lKTsKCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3tedj8oXGQrKykoXC4oPzpcZCsrfFt4WCpdKSk/KFwuKD86XGQrK3xbeFgqXSkpPyhcLig/OlxkKyt8W3hYKl0pKT8kfWknLCAkbmFtZSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gJyc7CiAgICAgICAgICAgIGZvciAoJGkgPSAxOyAkaSA8IDU7ICsrJGkpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uIC49IGlzc2V0KCRtYXRjaGVzWyRpXSkgPyBzdHJfcmVwbGFjZShhcnJheSgnKicsICdYJyksICd4JywgJG1hdGNoZXNbJGldKSA6ICcueCc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgneCcsICc5OTk5OTk5JywgJHZlcnNpb24pIC4gJy1kZXYnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdkZXYtJyAuICRuYW1lOwogICAgfQoKICAgIC8qKgogICAgICogTm9ybWFsaXplcyBhIGRlZmF1bHQgYnJhbmNoIG5hbWUgKGkuZS4gbWFzdGVyIG9uIGdpdCkgdG8gOTk5OTk5OS1kZXYuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemVEZWZhdWx0QnJhbmNoKCRuYW1lKQogICAgewogICAgICAgIGlmICgkbmFtZSA9PT0gJ2Rldi1tYXN0ZXInIHx8ICRuYW1lID09PSAnZGV2LWRlZmF1bHQnIHx8ICRuYW1lID09PSAnZGV2LXRydW5rJykgewogICAgICAgICAgICByZXR1cm4gJzk5OTk5OTktZGV2JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGNvbnN0cmFpbnQgc3RyaW5nIGludG8gTXVsdGlDb25zdHJhaW50IGFuZC9vciBDb25zdHJhaW50IG9iamVjdHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29uc3RyYWludHMKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnRzKQogICAgewogICAgICAgICRwcmV0dHlDb25zdHJhaW50ID0gJGNvbnN0cmFpbnRzOwoKICAgICAgICAkb3JDb25zdHJhaW50cyA9IHByZWdfc3BsaXQoJ3tccypcfFx8P1xzKn0nLCB0cmltKCRjb25zdHJhaW50cykpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJG9yQ29uc3RyYWludHMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gcHJlZ19zcGxpdCBzdHJpbmc6ICcuJGNvbnN0cmFpbnRzKTsKICAgICAgICB9CiAgICAgICAgJG9yR3JvdXBzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJG9yQ29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnRzKSB7CiAgICAgICAgICAgICRhbmRDb25zdHJhaW50cyA9IHByZWdfc3BsaXQoJ3soPzwhXnxhc3xbPT48ICxdKSAqKD88IS0pWywgXSg/IS0pICooPyEsfGFzfCQpfScsICRjb25zdHJhaW50cyk7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGFuZENvbnN0cmFpbnRzKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBwcmVnX3NwbGl0IHN0cmluZzogJy4kY29uc3RyYWludHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChcY291bnQoJGFuZENvbnN0cmFpbnRzKSA+IDEpIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50T2JqZWN0cyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYW5kQ29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFyc2VDb25zdHJhaW50KCRjb25zdHJhaW50KSBhcyAkcGFyc2VkQ29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludE9iamVjdHNbXSA9ICRwYXJzZWRDb25zdHJhaW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50T2JqZWN0cyA9ICR0aGlzLT5wYXJzZUNvbnN0cmFpbnQoJGFuZENvbnN0cmFpbnRzWzBdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkY29uc3RyYWludE9iamVjdHMpKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9ICRjb25zdHJhaW50T2JqZWN0c1swXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gbmV3IE11bHRpQ29uc3RyYWludCgkY29uc3RyYWludE9iamVjdHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkb3JHcm91cHNbXSA9ICRjb25zdHJhaW50OwogICAgICAgIH0KCiAgICAgICAgJGNvbnN0cmFpbnQgPSBNdWx0aUNvbnN0cmFpbnQ6OmNyZWF0ZSgkb3JHcm91cHMsIGZhbHNlKTsKCiAgICAgICAgJGNvbnN0cmFpbnQtPnNldFByZXR0eVN0cmluZygkcHJldHR5Q29uc3RyYWludCk7CgogICAgICAgIHJldHVybiAkY29uc3RyYWludDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKgogICAgICogQHBocHN0YW4tcmV0dXJuIG5vbi1lbXB0eS1hcnJheTxDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnNlQ29uc3RyYWludCgkY29uc3RyYWludCkKICAgIHsKICAgICAgICAvLyBzdHJpcCBvZmYgYWxpYXNpbmcKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oW14sXHNdKyspICsrYXMgKysoW14sXHNdKyspJH0nLCAkY29uc3RyYWludCwgJG1hdGNoKSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICRtYXRjaFsxXTsKICAgICAgICB9CgogICAgICAgIC8vIHN0cmlwIEBzdGFiaWxpdHkgZmxhZ3MsIGFuZCBrZWVwIGl0IGZvciBsYXRlciB1c2UKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oW14sXHNdKj8pQCgnIC4gc2VsZjo6JHN0YWJpbGl0aWVzUmVnZXggLiAnKSR9aScsICRjb25zdHJhaW50LCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICRjb25zdHJhaW50ID0gJycgIT09ICRtYXRjaFsxXSA/ICRtYXRjaFsxXSA6ICcqJzsKICAgICAgICAgICAgaWYgKCRtYXRjaFsyXSAhPT0gJ3N0YWJsZScpIHsKICAgICAgICAgICAgICAgICRzdGFiaWxpdHlNb2RpZmllciA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gZ2V0IHJpZCBvZiAjcmVmcyBhcyB0aG9zZSBhcmUgdXNlZCBieSBjb21wb3NlciBvbmx5CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKGRldi1bXixcc0BdKz98W14sXHNAXSs/XC54LWRldikjLiskfWknLCAkY29uc3RyYWludCwgJG1hdGNoKSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICRtYXRjaFsxXTsKICAgICAgICB9CgogICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xih2KT9beFgqXShcLlt4WCpdKSokfWknLCAkY29uc3RyYWludCwgJG1hdGNoKSkgewogICAgICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsxXSkgfHwgIWVtcHR5KCRtYXRjaFsyXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheShuZXcgQ29uc3RyYWludCgnPj0nLCAnMC4wLjAuMC1kZXYnKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheShuZXcgTWF0Y2hBbGxDb25zdHJhaW50KCkpOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25SZWdleCA9ICd2PyhcZCsrKSg/OlwuKFxkKyspKT8oPzpcLihcZCsrKSk/KD86XC4oXGQrKykpPyg/OicgLiBzZWxmOjokbW9kaWZpZXJSZWdleCAuICd8XC4oW3hYKl1bLi1dP2RldikpKD86XCtbXlxzXSspPyc7CgogICAgICAgIC8vIFRpbGRlIFJhbmdlCiAgICAgICAgLy8KICAgICAgICAvLyBMaWtlIHdpbGRjYXJkIGNvbnN0cmFpbnRzLCB1bnN1ZmZpeGVkIHRpbGRlIGNvbnN0cmFpbnRzIHNheSB0aGF0IHRoZXkgbXVzdCBiZSBncmVhdGVyIHRoYW4gdGhlIHByZXZpb3VzCiAgICAgICAgLy8gdmVyc2lvbiwgdG8gZW5zdXJlIHRoYXQgdW5zdGFibGUgaW5zdGFuY2VzIG9mIHRoZSBjdXJyZW50IHZlcnNpb24gYXJlIGFsbG93ZWQuIEhvd2V2ZXIsIGlmIGEgc3RhYmlsaXR5CiAgICAgICAgLy8gc3VmZml4IGlzIGFkZGVkIHRvIHRoZSBjb25zdHJhaW50LCB0aGVuIGEgPj0gbWF0Y2ggb24gdGhlIGN1cnJlbnQgdmVyc2lvbiBpcyB1c2VkIGluc3RlYWQuCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3tefj4/JyAuICR2ZXJzaW9uUmVnZXggLiAnJH1pJywgJGNvbnN0cmFpbnQsICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRjb25zdHJhaW50LCAnfj4nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJ0NvdWxkIG5vdCBwYXJzZSB2ZXJzaW9uIGNvbnN0cmFpbnQgJyAuICRjb25zdHJhaW50IC4gJzogJyAuCiAgICAgICAgICAgICAgICAgICAgJ0ludmFsaWQgb3BlcmF0b3IgIn4+IiwgeW91IHByb2JhYmx5IG1lYW50IHRvIHVzZSB0aGUgIn4iIG9wZXJhdG9yJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gV29yayBvdXQgd2hpY2ggcG9zaXRpb24gaW4gdGhlIHZlcnNpb24gd2UgYXJlIG9wZXJhdGluZyBhdAogICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbNF0pICYmICcnICE9PSAkbWF0Y2hlc1s0XSAmJiBudWxsICE9PSAkbWF0Y2hlc1s0XSkgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gNDsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRtYXRjaGVzWzNdKSAmJiAnJyAhPT0gJG1hdGNoZXNbM10gJiYgbnVsbCAhPT0gJG1hdGNoZXNbM10pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IDM7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkbWF0Y2hlc1syXSkgJiYgJycgIT09ICRtYXRjaGVzWzJdICYmIG51bGwgIT09ICRtYXRjaGVzWzJdKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gd2hlbiBtYXRjaGluZyAyLngtZGV2IG9yIDMuMC54LWRldiB3ZSBoYXZlIHRvIHNoaWZ0IHRoZSBzZWNvbmQgb3IgdGhpcmQgbnVtYmVyLCBkZXNwaXRlIG5vIHNlY29uZC90aGlyZCBudW1iZXIgbWF0Y2hpbmcgYWJvdmUKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hlc1s4XSkpIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbisrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIHN0YWJpbGl0eSBzdWZmaXgKICAgICAgICAgICAgJHN0YWJpbGl0eVN1ZmZpeCA9ICcnOwogICAgICAgICAgICBpZiAoZW1wdHkoJG1hdGNoZXNbNV0pICYmIGVtcHR5KCRtYXRjaGVzWzddKSAmJiBlbXB0eSgkbWF0Y2hlc1s4XSkpIHsKICAgICAgICAgICAgICAgICRzdGFiaWxpdHlTdWZmaXggLj0gJy1kZXYnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG93VmVyc2lvbiA9ICR0aGlzLT5ub3JtYWxpemUoc3Vic3RyKCRjb25zdHJhaW50IC4gJHN0YWJpbGl0eVN1ZmZpeCwgMSkpOwogICAgICAgICAgICAkbG93ZXJCb3VuZCA9IG5ldyBDb25zdHJhaW50KCc+PScsICRsb3dWZXJzaW9uKTsKCiAgICAgICAgICAgIC8vIEZvciB1cHBlciBib3VuZCwgd2UgaW5jcmVtZW50IHRoZSBwb3NpdGlvbiBvZiBvbmUgbW9yZSBzaWduaWZpY2FuY2UsCiAgICAgICAgICAgIC8vIGJ1dCBoaWdoUG9zaXRpb24gPSAwIHdvdWxkIGJlIGlsbGVnYWwKICAgICAgICAgICAgJGhpZ2hQb3NpdGlvbiA9IG1heCgxLCAkcG9zaXRpb24gLSAxKTsKICAgICAgICAgICAgJGhpZ2hWZXJzaW9uID0gJHRoaXMtPm1hbmlwdWxhdGVWZXJzaW9uU3RyaW5nKCRtYXRjaGVzLCAkaGlnaFBvc2l0aW9uLCAxKSAuICctZGV2JzsKICAgICAgICAgICAgJHVwcGVyQm91bmQgPSBuZXcgQ29uc3RyYWludCgnPCcsICRoaWdoVmVyc2lvbik7CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICAgICAkbG93ZXJCb3VuZCwKICAgICAgICAgICAgICAgICR1cHBlckJvdW5kLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gQ2FyZXQgUmFuZ2UKICAgICAgICAvLwogICAgICAgIC8vIEFsbG93cyBjaGFuZ2VzIHRoYXQgZG8gbm90IG1vZGlmeSB0aGUgbGVmdC1tb3N0IG5vbi16ZXJvIGRpZ2l0IGluIHRoZSBbbWFqb3IsIG1pbm9yLCBwYXRjaF0gdHVwbGUuCiAgICAgICAgLy8gSW4gb3RoZXIgd29yZHMsIHRoaXMgYWxsb3dzIHBhdGNoIGFuZCBtaW5vciB1cGRhdGVzIGZvciB2ZXJzaW9ucyAxLjAuMCBhbmQgYWJvdmUsIHBhdGNoIHVwZGF0ZXMgZm9yCiAgICAgICAgLy8gdmVyc2lvbnMgMC5YID49MC4xLjAsIGFuZCBubyB1cGRhdGVzIGZvciB2ZXJzaW9ucyAwLjAuWAogICAgICAgIGlmIChwcmVnX21hdGNoKCd7XlxeJyAuICR2ZXJzaW9uUmVnZXggLiAnKCQpfWknLCAkY29uc3RyYWludCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIFdvcmsgb3V0IHdoaWNoIHBvc2l0aW9uIGluIHRoZSB2ZXJzaW9uIHdlIGFyZSBvcGVyYXRpbmcgYXQKICAgICAgICAgICAgaWYgKCcwJyAhPT0gJG1hdGNoZXNbMV0gfHwgJycgPT09ICRtYXRjaGVzWzJdIHx8IG51bGwgPT09ICRtYXRjaGVzWzJdKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAxOwogICAgICAgICAgICB9IGVsc2VpZiAoJzAnICE9PSAkbWF0Y2hlc1syXSB8fCAnJyA9PT0gJG1hdGNoZXNbM10gfHwgbnVsbCA9PT0gJG1hdGNoZXNbM10pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IDI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIHN0YWJpbGl0eSBzdWZmaXgKICAgICAgICAgICAgJHN0YWJpbGl0eVN1ZmZpeCA9ICcnOwogICAgICAgICAgICBpZiAoZW1wdHkoJG1hdGNoZXNbNV0pICYmIGVtcHR5KCRtYXRjaGVzWzddKSAmJiBlbXB0eSgkbWF0Y2hlc1s4XSkpIHsKICAgICAgICAgICAgICAgICRzdGFiaWxpdHlTdWZmaXggLj0gJy1kZXYnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG93VmVyc2lvbiA9ICR0aGlzLT5ub3JtYWxpemUoc3Vic3RyKCRjb25zdHJhaW50IC4gJHN0YWJpbGl0eVN1ZmZpeCwgMSkpOwogICAgICAgICAgICAkbG93ZXJCb3VuZCA9IG5ldyBDb25zdHJhaW50KCc+PScsICRsb3dWZXJzaW9uKTsKCiAgICAgICAgICAgIC8vIEZvciB1cHBlciBib3VuZCwgd2UgaW5jcmVtZW50IHRoZSBwb3NpdGlvbiBvZiBvbmUgbW9yZSBzaWduaWZpY2FuY2UsCiAgICAgICAgICAgIC8vIGJ1dCBoaWdoUG9zaXRpb24gPSAwIHdvdWxkIGJlIGlsbGVnYWwKICAgICAgICAgICAgJGhpZ2hWZXJzaW9uID0gJHRoaXMtPm1hbmlwdWxhdGVWZXJzaW9uU3RyaW5nKCRtYXRjaGVzLCAkcG9zaXRpb24sIDEpIC4gJy1kZXYnOwogICAgICAgICAgICAkdXBwZXJCb3VuZCA9IG5ldyBDb25zdHJhaW50KCc8JywgJGhpZ2hWZXJzaW9uKTsKCiAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICRsb3dlckJvdW5kLAogICAgICAgICAgICAgICAgJHVwcGVyQm91bmQsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLyBYIFJhbmdlCiAgICAgICAgLy8KICAgICAgICAvLyBBbnkgb2YgWCwgeCwgb3IgKiBtYXkgYmUgdXNlZCB0byAic3RhbmQgaW4iIGZvciBvbmUgb2YgdGhlIG51bWVyaWMgdmFsdWVzIGluIHRoZSBbbWFqb3IsIG1pbm9yLCBwYXRjaF0gdHVwbGUuCiAgICAgICAgLy8gQSBwYXJ0aWFsIHZlcnNpb24gcmFuZ2UgaXMgdHJlYXRlZCBhcyBhbiBYLVJhbmdlLCBzbyB0aGUgc3BlY2lhbCBjaGFyYWN0ZXIgaXMgaW4gZmFjdCBvcHRpb25hbC4KICAgICAgICBpZiAocHJlZ19tYXRjaCgne152PyhcZCsrKSg/OlwuKFxkKyspKT8oPzpcLihcZCsrKSk/KD86XC5beFgqXSkrKyR9JywgJGNvbnN0cmFpbnQsICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbM10pICYmICcnICE9PSAkbWF0Y2hlc1szXSAmJiBudWxsICE9PSAkbWF0Y2hlc1szXSkgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gMzsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRtYXRjaGVzWzJdKSAmJiAnJyAhPT0gJG1hdGNoZXNbMl0gJiYgbnVsbCAhPT0gJG1hdGNoZXNbMl0pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IDI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG93VmVyc2lvbiA9ICR0aGlzLT5tYW5pcHVsYXRlVmVyc2lvblN0cmluZygkbWF0Y2hlcywgJHBvc2l0aW9uKSAuICctZGV2JzsKICAgICAgICAgICAgJGhpZ2hWZXJzaW9uID0gJHRoaXMtPm1hbmlwdWxhdGVWZXJzaW9uU3RyaW5nKCRtYXRjaGVzLCAkcG9zaXRpb24sIDEpIC4gJy1kZXYnOwoKICAgICAgICAgICAgaWYgKCRsb3dWZXJzaW9uID09PSAnMC4wLjAuMC1kZXYnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkobmV3IENvbnN0cmFpbnQoJzwnLCAkaGlnaFZlcnNpb24pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgbmV3IENvbnN0cmFpbnQoJz49JywgJGxvd1ZlcnNpb24pLAogICAgICAgICAgICAgICAgbmV3IENvbnN0cmFpbnQoJzwnLCAkaGlnaFZlcnNpb24pLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gSHlwaGVuIFJhbmdlCiAgICAgICAgLy8KICAgICAgICAvLyBTcGVjaWZpZXMgYW4gaW5jbHVzaXZlIHNldC4gSWYgYSBwYXJ0aWFsIHZlcnNpb24gaXMgcHJvdmlkZWQgYXMgdGhlIGZpcnN0IHZlcnNpb24gaW4gdGhlIGluY2x1c2l2ZSByYW5nZSwKICAgICAgICAvLyB0aGVuIHRoZSBtaXNzaW5nIHBpZWNlcyBhcmUgcmVwbGFjZWQgd2l0aCB6ZXJvZXMuIElmIGEgcGFydGlhbCB2ZXJzaW9uIGlzIHByb3ZpZGVkIGFzIHRoZSBzZWNvbmQgdmVyc2lvbiBpbgogICAgICAgIC8vIHRoZSBpbmNsdXNpdmUgcmFuZ2UsIHRoZW4gYWxsIHZlcnNpb25zIHRoYXQgc3RhcnQgd2l0aCB0aGUgc3VwcGxpZWQgcGFydHMgb2YgdGhlIHR1cGxlIGFyZSBhY2NlcHRlZCwgYnV0CiAgICAgICAgLy8gbm90aGluZyB0aGF0IHdvdWxkIGJlIGdyZWF0ZXIgdGhhbiB0aGUgcHJvdmlkZWQgdHVwbGUgcGFydHMuCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD9QPGZyb20+JyAuICR2ZXJzaW9uUmVnZXggLiAnKSArLSArKD9QPHRvPicgLiAkdmVyc2lvblJlZ2V4IC4gJykoJCl9aScsICRjb25zdHJhaW50LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBzdGFiaWxpdHkgc3VmZml4CiAgICAgICAgICAgICRsb3dTdGFiaWxpdHlTdWZmaXggPSAnJzsKICAgICAgICAgICAgaWYgKGVtcHR5KCRtYXRjaGVzWzZdKSAmJiBlbXB0eSgkbWF0Y2hlc1s4XSkgJiYgZW1wdHkoJG1hdGNoZXNbOV0pKSB7CiAgICAgICAgICAgICAgICAkbG93U3RhYmlsaXR5U3VmZml4ID0gJy1kZXYnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG93VmVyc2lvbiA9ICR0aGlzLT5ub3JtYWxpemUoJG1hdGNoZXNbJ2Zyb20nXSk7CiAgICAgICAgICAgICRsb3dlckJvdW5kID0gbmV3IENvbnN0cmFpbnQoJz49JywgJGxvd1ZlcnNpb24gLiAkbG93U3RhYmlsaXR5U3VmZml4KTsKCiAgICAgICAgICAgICRlbXB0eSA9IGZ1bmN0aW9uICgkeCkgewogICAgICAgICAgICAgICAgcmV0dXJuICgkeCA9PT0gMCB8fCAkeCA9PT0gJzAnKSA/IGZhbHNlIDogZW1wdHkoJHgpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaWYgKCghJGVtcHR5KCRtYXRjaGVzWzEyXSkgJiYgISRlbXB0eSgkbWF0Y2hlc1sxM10pKSB8fCAhZW1wdHkoJG1hdGNoZXNbMTVdKSB8fCAhZW1wdHkoJG1hdGNoZXNbMTddKSB8fCAhZW1wdHkoJG1hdGNoZXNbMThdKSkgewogICAgICAgICAgICAgICAgJGhpZ2hWZXJzaW9uID0gJHRoaXMtPm5vcm1hbGl6ZSgkbWF0Y2hlc1sndG8nXSk7CiAgICAgICAgICAgICAgICAkdXBwZXJCb3VuZCA9IG5ldyBDb25zdHJhaW50KCc8PScsICRoaWdoVmVyc2lvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkaGlnaE1hdGNoID0gYXJyYXkoJycsICRtYXRjaGVzWzExXSwgJG1hdGNoZXNbMTJdLCAkbWF0Y2hlc1sxM10sICRtYXRjaGVzWzE0XSk7CgogICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUgdG8gdmVyc2lvbgogICAgICAgICAgICAgICAgJHRoaXMtPm5vcm1hbGl6ZSgkbWF0Y2hlc1sndG8nXSk7CgogICAgICAgICAgICAgICAgJGhpZ2hWZXJzaW9uID0gJHRoaXMtPm1hbmlwdWxhdGVWZXJzaW9uU3RyaW5nKCRoaWdoTWF0Y2gsICRlbXB0eSgkbWF0Y2hlc1sxMl0pID8gMSA6IDIsIDEpIC4gJy1kZXYnOwogICAgICAgICAgICAgICAgJHVwcGVyQm91bmQgPSBuZXcgQ29uc3RyYWludCgnPCcsICRoaWdoVmVyc2lvbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICRsb3dlckJvdW5kLAogICAgICAgICAgICAgICAgJHVwcGVyQm91bmQsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLyBCYXNpYyBDb21wYXJhdG9ycwogICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xig8PnwhPXw+PT98PD0/fD09Pyk/XHMqKC4qKX0nLCAkY29uc3RyYWludCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPm5vcm1hbGl6ZSgkbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcmVjb3ZlciBmcm9tIGFuIGludmFsaWQgY29uc3RyYWludCBsaWtlIGZvb2Jhci1kZXYgd2hpY2ggc2hvdWxkIGJlIGRldi1mb29iYXIKICAgICAgICAgICAgICAgICAgICAvLyBleGNlcHQgaWYgdGhlIGNvbnN0cmFpbnQgdXNlcyBhIGtub3duIG9wZXJhdG9yLCBpbiB3aGljaCBjYXNlIGl0IG11c3QgYmUgYSBwYXJzZSBlcnJvcgogICAgICAgICAgICAgICAgICAgIGlmIChzdWJzdHIoJG1hdGNoZXNbMl0sIC00KSA9PT0gJy1kZXYnICYmIHByZWdfbWF0Y2goJ3teWzAtOWEtekEtWi0uL10rJH0nLCAkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+bm9ybWFsaXplKCdkZXYtJy5zdWJzdHIoJG1hdGNoZXNbMl0sIDAsIC00KSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRvcCA9ICRtYXRjaGVzWzFdID86ICc9JzsKCiAgICAgICAgICAgICAgICBpZiAoJG9wICE9PSAnPT0nICYmICRvcCAhPT0gJz0nICYmICFlbXB0eSgkc3RhYmlsaXR5TW9kaWZpZXIpICYmIHNlbGY6OnBhcnNlU3RhYmlsaXR5KCR2ZXJzaW9uKSA9PT0gJ3N0YWJsZScpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiAuPSAnLScgLiAkc3RhYmlsaXR5TW9kaWZpZXI7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJzwnID09PSAkb3AgfHwgJz49JyA9PT0gJG9wKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvLScgLiBzZWxmOjokbW9kaWZpZXJSZWdleCAuICckLycsIHN0cnRvbG93ZXIoJG1hdGNoZXNbMl0pKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRtYXRjaGVzWzJdLCAnZGV2LScpICE9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiAuPSAnLWRldic7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KG5ldyBDb25zdHJhaW50KCRtYXRjaGVzWzFdID86ICc9JywgJHZlcnNpb24pKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkbWVzc2FnZSA9ICdDb3VsZCBub3QgcGFyc2UgdmVyc2lvbiBjb25zdHJhaW50ICcgLiAkY29uc3RyYWludDsKICAgICAgICBpZiAoaXNzZXQoJGUpKSB7CiAgICAgICAgICAgICRtZXNzYWdlIC49ICc6ICcgLiAkZS0+Z2V0TWVzc2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogSW5jcmVtZW50LCBkZWNyZW1lbnQsIG9yIHNpbXBseSBwYWQgYSB2ZXJzaW9uIG51bWJlci4KICAgICAqCiAgICAgKiBTdXBwb3J0IGZ1bmN0aW9uIGZvciB7QGxpbmsgcGFyc2VDb25zdHJhaW50KCl9CiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkbWF0Y2hlcyAgIEFycmF5IHdpdGggdmVyc2lvbiBwYXJ0cyBpbiBhcnJheSBpbmRleGVzIDEsMiwzLDQKICAgICAqIEBwYXJhbSBpbnQgICAgJHBvc2l0aW9uICAxLDIsMyw0IC0gd2hpY2ggc2VnbWVudCBvZiB0aGUgdmVyc2lvbiB0byBpbmNyZW1lbnQvZGVjcmVtZW50CiAgICAgKiBAcGFyYW0gaW50ICAgICRpbmNyZW1lbnQKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhZCAgICAgICBUaGUgc3RyaW5nIHRvIHBhZCB2ZXJzaW9uIHBhcnRzIGFmdGVyICRwb3NpdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIG5ldyB2ZXJzaW9uCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gc3RyaW5nW10gJG1hdGNoZXMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYW5pcHVsYXRlVmVyc2lvblN0cmluZyhhcnJheSAkbWF0Y2hlcywgJHBvc2l0aW9uLCAkaW5jcmVtZW50ID0gMCwgJHBhZCA9ICcwJykKICAgIHsKICAgICAgICBmb3IgKCRpID0gNDsgJGkgPiAwOyAtLSRpKSB7CiAgICAgICAgICAgIGlmICgkaSA+ICRwb3NpdGlvbikgewogICAgICAgICAgICAgICAgJG1hdGNoZXNbJGldID0gJHBhZDsKICAgICAgICAgICAgfSBlbHNlaWYgKCRpID09PSAkcG9zaXRpb24gJiYgJGluY3JlbWVudCkgewogICAgICAgICAgICAgICAgJG1hdGNoZXNbJGldICs9ICRpbmNyZW1lbnQ7CiAgICAgICAgICAgICAgICAvLyBJZiAkbWF0Y2hlc1skaV0gd2FzIDAsIGNhcnJ5IHRoZSBkZWNyZW1lbnQKICAgICAgICAgICAgICAgIGlmICgkbWF0Y2hlc1skaV0gPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgJG1hdGNoZXNbJGldID0gJHBhZDsKICAgICAgICAgICAgICAgICAgICAtLSRwb3NpdGlvbjsKCiAgICAgICAgICAgICAgICAgICAgLy8gUmV0dXJuIG51bGwgb24gYSBjYXJyeSBvdmVyZmxvdwogICAgICAgICAgICAgICAgICAgIGlmICgkaSA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWF0Y2hlc1sxXSAuICcuJyAuICRtYXRjaGVzWzJdIC4gJy4nIC4gJG1hdGNoZXNbM10gLiAnLicgLiAkbWF0Y2hlc1s0XTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4cGFuZCBzaG9ydGhhbmQgc3RhYmlsaXR5IHN0cmluZyB0byBsb25nIHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RhYmlsaXR5CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBleHBhbmRTdGFiaWxpdHkoJHN0YWJpbGl0eSkKICAgIHsKICAgICAgICAkc3RhYmlsaXR5ID0gc3RydG9sb3dlcigkc3RhYmlsaXR5KTsKCiAgICAgICAgc3dpdGNoICgkc3RhYmlsaXR5KSB7CiAgICAgICAgICAgIGNhc2UgJ2EnOgogICAgICAgICAgICAgICAgcmV0dXJuICdhbHBoYSc7CiAgICAgICAgICAgIGNhc2UgJ2InOgogICAgICAgICAgICAgICAgcmV0dXJuICdiZXRhJzsKICAgICAgICAgICAgY2FzZSAncCc6CiAgICAgICAgICAgIGNhc2UgJ3BsJzoKICAgICAgICAgICAgICAgIHJldHVybiAncGF0Y2gnOwogICAgICAgICAgICBjYXNlICdyYyc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ1JDJzsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiAkc3RhYmlsaXR5OwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlcjsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKY2xhc3MgSW50ZXJ2YWwKewogICAgLyoqIEB2YXIgQ29uc3RyYWludCAqLwogICAgcHJpdmF0ZSAkc3RhcnQ7CiAgICAvKiogQHZhciBDb25zdHJhaW50ICovCiAgICBwcml2YXRlICRlbmQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENvbnN0cmFpbnQgJHN0YXJ0LCBDb25zdHJhaW50ICRlbmQpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXJ0ID0gJHN0YXJ0OwogICAgICAgICR0aGlzLT5lbmQgPSAkZW5kOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGFydCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGFydDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29uc3RyYWludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVuZDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29uc3RyYWludAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21aZXJvKCkKICAgIHsKICAgICAgICBzdGF0aWMgJHplcm87CgogICAgICAgIGlmIChudWxsID09PSAkemVybykgewogICAgICAgICAgICAkemVybyA9IG5ldyBDb25zdHJhaW50KCc+PScsICcwLjAuMC4wLWRldicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR6ZXJvOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdW50aWxQb3NpdGl2ZUluZmluaXR5KCkKICAgIHsKICAgICAgICBzdGF0aWMgJHBvc2l0aXZlSW5maW5pdHk7CgogICAgICAgIGlmIChudWxsID09PSAkcG9zaXRpdmVJbmZpbml0eSkgewogICAgICAgICAgICAkcG9zaXRpdmVJbmZpbml0eSA9IG5ldyBDb25zdHJhaW50KCc8JywgUEhQX0lOVF9NQVguJy4wLjAuMCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwb3NpdGl2ZUluZmluaXR5OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYW55KCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IHNlbGYoc2VsZjo6ZnJvbVplcm8oKSwgc2VsZjo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheXsnbmFtZXMnOiBzdHJpbmdbXSwgJ2V4Y2x1ZGUnOiBib29sfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFueURldigpCiAgICB7CiAgICAgICAgLy8gYW55ID09IGV4Y2x1ZGUgbm90aGluZwogICAgICAgIHJldHVybiBhcnJheSgnbmFtZXMnID0+IGFycmF5KCksICdleGNsdWRlJyA9PiB0cnVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXl7J25hbWVzJzogc3RyaW5nW10sICdleGNsdWRlJzogYm9vbH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBub0RldigpCiAgICB7CiAgICAgICAgLy8gbm90aGluZyA9PSBubyBuYW1lcyBpbmNsdWRlZAogICAgICAgIHJldHVybiBhcnJheSgnbmFtZXMnID0+IGFycmF5KCksICdleGNsdWRlJyA9PiBmYWxzZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3NlbXZlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludDsKCi8qKgogKiBEZWZpbmVzIGEgY29uc3RyYWludC4KICovCmNsYXNzIENvbnN0cmFpbnQgaW1wbGVtZW50cyBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIC8qIG9wZXJhdG9yIGludGVnZXIgdmFsdWVzICovCiAgICBjb25zdCBPUF9FUSA9IDA7CiAgICBjb25zdCBPUF9MVCA9IDE7CiAgICBjb25zdCBPUF9MRSA9IDI7CiAgICBjb25zdCBPUF9HVCA9IDM7CiAgICBjb25zdCBPUF9HRSA9IDQ7CiAgICBjb25zdCBPUF9ORSA9IDU7CgogICAgLyogb3BlcmF0b3Igc3RyaW5nIHZhbHVlcyAqLwogICAgY29uc3QgU1RSX09QX0VRID0gJz09JzsKICAgIGNvbnN0IFNUUl9PUF9FUV9BTFQgPSAnPSc7CiAgICBjb25zdCBTVFJfT1BfTFQgPSAnPCc7CiAgICBjb25zdCBTVFJfT1BfTEUgPSAnPD0nOwogICAgY29uc3QgU1RSX09QX0dUID0gJz4nOwogICAgY29uc3QgU1RSX09QX0dFID0gJz49JzsKICAgIGNvbnN0IFNUUl9PUF9ORSA9ICchPSc7CiAgICBjb25zdCBTVFJfT1BfTkVfQUxUID0gJzw+JzsKCiAgICAvKioKICAgICAqIE9wZXJhdG9yIHRvIGludGVnZXIgdHJhbnNsYXRpb24gdGFibGUuCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHNlbGY6OlNUUl9PUF8qLCBzZWxmOjpPUF8qPgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkdHJhbnNPcFN0ciA9IGFycmF5KAogICAgICAgICc9JyA9PiBzZWxmOjpPUF9FUSwKICAgICAgICAnPT0nID0+IHNlbGY6Ok9QX0VRLAogICAgICAgICc8JyA9PiBzZWxmOjpPUF9MVCwKICAgICAgICAnPD0nID0+IHNlbGY6Ok9QX0xFLAogICAgICAgICc+JyA9PiBzZWxmOjpPUF9HVCwKICAgICAgICAnPj0nID0+IHNlbGY6Ok9QX0dFLAogICAgICAgICc8PicgPT4gc2VsZjo6T1BfTkUsCiAgICAgICAgJyE9JyA9PiBzZWxmOjpPUF9ORSwKICAgICk7CgogICAgLyoqCiAgICAgKiBJbnRlZ2VyIHRvIG9wZXJhdG9yIHRyYW5zbGF0aW9uIHRhYmxlLgogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzZWxmOjpPUF8qLCBzZWxmOjpTVFJfT1BfKj4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHRyYW5zT3BJbnQgPSBhcnJheSgKICAgICAgICBzZWxmOjpPUF9FUSA9PiAnPT0nLAogICAgICAgIHNlbGY6Ok9QX0xUID0+ICc8JywKICAgICAgICBzZWxmOjpPUF9MRSA9PiAnPD0nLAogICAgICAgIHNlbGY6Ok9QX0dUID0+ICc+JywKICAgICAgICBzZWxmOjpPUF9HRSA9PiAnPj0nLAogICAgICAgIHNlbGY6Ok9QX05FID0+ICchPScsCiAgICApOwoKICAgIC8qKgogICAgICogQHZhciBpbnQKICAgICAqIEBwaHBzdGFuLXZhciBzZWxmOjpPUF8qCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0b3I7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHZlcnNpb247CgogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByb3RlY3RlZCAkcHJldHR5U3RyaW5nOwoKICAgIC8qKiBAdmFyIEJvdW5kICovCiAgICBwcm90ZWN0ZWQgJGxvd2VyQm91bmQ7CgogICAgLyoqIEB2YXIgQm91bmQgKi8KICAgIHByb3RlY3RlZCAkdXBwZXJCb3VuZDsKCiAgICAvKioKICAgICAqIFNldHMgb3BlcmF0b3IgYW5kIHZlcnNpb24gdG8gY29tcGFyZSB3aXRoLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGludmFsaWQgb3BlcmF0b3IgaXMgZ2l2ZW4uCiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gc2VsZjo6U1RSX09QXyogJG9wZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkb3BlcmF0b3IsICR2ZXJzaW9uKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JHRyYW5zT3BTdHJbJG9wZXJhdG9yXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICdJbnZhbGlkIG9wZXJhdG9yICIlcyIgZ2l2ZW4sIGV4cGVjdGVkIG9uZSBvZjogJXMnLAogICAgICAgICAgICAgICAgJG9wZXJhdG9yLAogICAgICAgICAgICAgICAgaW1wbG9kZSgnLCAnLCBzZWxmOjpnZXRTdXBwb3J0ZWRPcGVyYXRvcnMoKSkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSBzZWxmOjokdHJhbnNPcFN0clskb3BlcmF0b3JdOwogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52ZXJzaW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gc2VsZjo6U1RSX09QXyoKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6JHRyYW5zT3BJbnRbJHRoaXMtPm9wZXJhdG9yXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hlcyhDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcikKICAgIHsKICAgICAgICBpZiAoJHByb3ZpZGVyIGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPm1hdGNoU3BlY2lmaWMoJHByb3ZpZGVyKTsKICAgICAgICB9CgogICAgICAgIC8vIHR1cm4gbWF0Y2hpbmcgYXJvdW5kIHRvIGZpbmQgYSBtYXRjaAogICAgICAgIHJldHVybiAkcHJvdmlkZXItPm1hdGNoZXMoJHRoaXMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJldHR5U3RyaW5nKCRwcmV0dHlTdHJpbmcpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXR0eVN0cmluZyA9ICRwcmV0dHlTdHJpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cHJldHR5U3RyaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJldHR5U3RyaW5nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5fX3RvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYWxsIHN1cHBvcnRlZCBjb21wYXJpc29uIG9wZXJhdG9ycy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKgogICAgICogQHBocHN0YW4tcmV0dXJuIGxpc3Q8c2VsZjo6U1RSX09QXyo+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0U3VwcG9ydGVkT3BlcmF0b3JzKCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXlfa2V5cyhzZWxmOjokdHJhbnNPcFN0cik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkb3BlcmF0b3IKICAgICAqIEByZXR1cm4gaW50CiAgICAgKgogICAgICogQHBocHN0YW4tcGFyYW0gIHNlbGY6OlNUUl9PUF8qICRvcGVyYXRvcgogICAgICogQHBocHN0YW4tcmV0dXJuIHNlbGY6Ok9QXyoKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRPcGVyYXRvckNvbnN0YW50KCRvcGVyYXRvcikKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6JHRyYW5zT3BTdHJbJG9wZXJhdG9yXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGEKICAgICAqIEBwYXJhbSBzdHJpbmcgJGIKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcGFyYW0gYm9vbCAgICRjb21wYXJlQnJhbmNoZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgaW52YWxpZCBvcGVyYXRvciBpcyBnaXZlbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBzZWxmOjpTVFJfT1BfKiAkb3BlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZlcnNpb25Db21wYXJlKCRhLCAkYiwgJG9wZXJhdG9yLCAkY29tcGFyZUJyYW5jaGVzID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldChzZWxmOjokdHJhbnNPcFN0clskb3BlcmF0b3JdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ0ludmFsaWQgb3BlcmF0b3IgIiVzIiBnaXZlbiwgZXhwZWN0ZWQgb25lIG9mOiAlcycsCiAgICAgICAgICAgICAgICAkb3BlcmF0b3IsCiAgICAgICAgICAgICAgICBpbXBsb2RlKCcsICcsIHNlbGY6OmdldFN1cHBvcnRlZE9wZXJhdG9ycygpKQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgICRhSXNCcmFuY2ggPSBzdHJwb3MoJGEsICdkZXYtJykgPT09IDA7CiAgICAgICAgJGJJc0JyYW5jaCA9IHN0cnBvcygkYiwgJ2Rldi0nKSA9PT0gMDsKCiAgICAgICAgaWYgKCRvcGVyYXRvciA9PT0gJyE9JyAmJiAoJGFJc0JyYW5jaCB8fCAkYklzQnJhbmNoKSkgewogICAgICAgICAgICByZXR1cm4gJGEgIT09ICRiOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRhSXNCcmFuY2ggJiYgJGJJc0JyYW5jaCkgewogICAgICAgICAgICByZXR1cm4gJG9wZXJhdG9yID09PSAnPT0nICYmICRhID09PSAkYjsKICAgICAgICB9CgogICAgICAgIC8vIHdoZW4gYnJhbmNoZXMgYXJlIG5vdCBjb21wYXJhYmxlLCB3ZSBtYWtlIHN1cmUgZGV2IGJyYW5jaGVzIG5ldmVyIG1hdGNoIGFueXRoaW5nCiAgICAgICAgaWYgKCEkY29tcGFyZUJyYW5jaGVzICYmICgkYUlzQnJhbmNoIHx8ICRiSXNCcmFuY2gpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcdmVyc2lvbl9jb21wYXJlKCRhLCAkYiwgJG9wZXJhdG9yKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbXBpbGUoJG90aGVyT3BlcmF0b3IpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkdGhpcy0+dmVyc2lvbiwgJ2Rldi0nKSA9PT0gMCkgewogICAgICAgICAgICBpZiAoc2VsZjo6T1BfRVEgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX0VRID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCckYiAmJiAkdiA9PT0gJXMnLCBcdmFyX2V4cG9ydCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX05FID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCchJGIgfHwgJHYgIT09ICVzJywgXHZhcl9leHBvcnQoJHRoaXMtPnZlcnNpb24sIHRydWUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAnZmFsc2UnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2VsZjo6T1BfTkUgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX0VRID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCchJGIgfHwgJHYgIT09ICVzJywgXHZhcl9leHBvcnQoJHRoaXMtPnZlcnNpb24sIHRydWUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzZWxmOjpPUF9ORSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3RydWUnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJ2ZhbHNlJzsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjpPUF9FUSA9PT0gJHRoaXMtPm9wZXJhdG9yKSB7CiAgICAgICAgICAgIGlmIChzZWxmOjpPUF9FUSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCc9PVwnKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX05FID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyRiIHx8IFx2ZXJzaW9uX2NvbXBhcmUoJHYsICVzLCBcJyE9XCcpJywgXHZhcl9leHBvcnQoJHRoaXMtPnZlcnNpb24sIHRydWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyEkYiAmJiBcdmVyc2lvbl9jb21wYXJlKCVzLCAkdiwgXCclc1wnKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSwgc2VsZjo6JHRyYW5zT3BJbnRbJG90aGVyT3BlcmF0b3JdKTsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjpPUF9ORSA9PT0gJHRoaXMtPm9wZXJhdG9yKSB7CiAgICAgICAgICAgIGlmIChzZWxmOjpPUF9FUSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCckYiB8fCAoISRiICYmIFx2ZXJzaW9uX2NvbXBhcmUoJHYsICVzLCBcJyE9XCcpKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzZWxmOjpPUF9ORSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiAndHJ1ZSc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6Ok9QX0xUID09PSAkdGhpcy0+b3BlcmF0b3IgfHwgc2VsZjo6T1BfTEUgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBpZiAoc2VsZjo6T1BfTFQgPT09ICRvdGhlck9wZXJhdG9yIHx8IHNlbGY6Ok9QX0xFID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsgLy8gJHRoaXMtPm9wZXJhdG9yIG11c3QgYmUgc2VsZjo6T1BfR1QgfHwgc2VsZjo6T1BfR0UgaGVyZQogICAgICAgICAgICBpZiAoc2VsZjo6T1BfR1QgPT09ICRvdGhlck9wZXJhdG9yIHx8IHNlbGY6Ok9QX0dFID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZjo6T1BfTkUgPT09ICRvdGhlck9wZXJhdG9yKSB7CiAgICAgICAgICAgIHJldHVybiAndHJ1ZSc7CiAgICAgICAgfQoKICAgICAgICAkY29kZUNvbXBhcmlzb24gPSBzcHJpbnRmKCdcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCclc1wnKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSwgc2VsZjo6JHRyYW5zT3BJbnRbJHRoaXMtPm9wZXJhdG9yXSk7CiAgICAgICAgaWYgKCR0aGlzLT5vcGVyYXRvciA9PT0gc2VsZjo6T1BfTEUpIHsKICAgICAgICAgICAgaWYgKCRvdGhlck9wZXJhdG9yID09PSBzZWxmOjpPUF9HVCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyEkYiAmJiBcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCchPVwnKSAmJiAnLCBcdmFyX2V4cG9ydCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSkpIC4gJGNvZGVDb21wYXJpc29uOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5vcGVyYXRvciA9PT0gc2VsZjo6T1BfR0UpIHsKICAgICAgICAgICAgaWYgKCRvdGhlck9wZXJhdG9yID09PSBzZWxmOjpPUF9MVCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyEkYiAmJiBcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCchPVwnKSAmJiAnLCBcdmFyX2V4cG9ydCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSkpIC4gJGNvZGVDb21wYXJpc29uOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZignISRiICYmICVzJywgJGNvZGVDb21wYXJpc29uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50ICRwcm92aWRlcgogICAgICogQHBhcmFtIGJvb2wgICAgICAgJGNvbXBhcmVCcmFuY2hlcwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hTcGVjaWZpYyhDb25zdHJhaW50ICRwcm92aWRlciwgJGNvbXBhcmVCcmFuY2hlcyA9IGZhbHNlKQogICAgewogICAgICAgICRub0VxdWFsT3AgPSBzdHJfcmVwbGFjZSgnPScsICcnLCBzZWxmOjokdHJhbnNPcEludFskdGhpcy0+b3BlcmF0b3JdKTsKICAgICAgICAkcHJvdmlkZXJOb0VxdWFsT3AgPSBzdHJfcmVwbGFjZSgnPScsICcnLCBzZWxmOjokdHJhbnNPcEludFskcHJvdmlkZXItPm9wZXJhdG9yXSk7CgogICAgICAgICRpc0VxdWFsT3AgPSBzZWxmOjpPUF9FUSA9PT0gJHRoaXMtPm9wZXJhdG9yOwogICAgICAgICRpc05vbkVxdWFsT3AgPSBzZWxmOjpPUF9ORSA9PT0gJHRoaXMtPm9wZXJhdG9yOwogICAgICAgICRpc1Byb3ZpZGVyRXF1YWxPcCA9IHNlbGY6Ok9QX0VRID09PSAkcHJvdmlkZXItPm9wZXJhdG9yOwogICAgICAgICRpc1Byb3ZpZGVyTm9uRXF1YWxPcCA9IHNlbGY6Ok9QX05FID09PSAkcHJvdmlkZXItPm9wZXJhdG9yOwoKICAgICAgICAvLyAnIT0nIG9wZXJhdG9yIGlzIG1hdGNoIHdoZW4gb3RoZXIgb3BlcmF0b3IgaXMgbm90ICc9PScgb3BlcmF0b3Igb3IgdmVyc2lvbiBpcyBub3QgbWF0Y2gKICAgICAgICAvLyB0aGVzZSBraW5kcyBvZiBjb21wYXJpc29ucyBhbHdheXMgaGF2ZSBhIHNvbHV0aW9uCiAgICAgICAgaWYgKCRpc05vbkVxdWFsT3AgfHwgJGlzUHJvdmlkZXJOb25FcXVhbE9wKSB7CiAgICAgICAgICAgIGlmICgkaXNOb25FcXVhbE9wICYmICEkaXNQcm92aWRlck5vbkVxdWFsT3AgJiYgISRpc1Byb3ZpZGVyRXF1YWxPcCAmJiBzdHJwb3MoJHByb3ZpZGVyLT52ZXJzaW9uLCAnZGV2LScpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkaXNQcm92aWRlck5vbkVxdWFsT3AgJiYgISRpc05vbkVxdWFsT3AgJiYgISRpc0VxdWFsT3AgJiYgc3RycG9zKCR0aGlzLT52ZXJzaW9uLCAnZGV2LScpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGlzRXF1YWxPcCAmJiAhJGlzUHJvdmlkZXJFcXVhbE9wKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb25Db21wYXJlKCRwcm92aWRlci0+dmVyc2lvbiwgJHRoaXMtPnZlcnNpb24sICchPScsICRjb21wYXJlQnJhbmNoZXMpOwogICAgICAgIH0KCiAgICAgICAgLy8gYW4gZXhhbXBsZSBmb3IgdGhlIGNvbmRpdGlvbiBpcyA8PSAyLjAgJiA8IDEuMAogICAgICAgIC8vIHRoZXNlIGtpbmRzIG9mIGNvbXBhcmlzb25zIGFsd2F5cyBoYXZlIGEgc29sdXRpb24KICAgICAgICBpZiAoJHRoaXMtPm9wZXJhdG9yICE9PSBzZWxmOjpPUF9FUSAmJiAkbm9FcXVhbE9wID09PSAkcHJvdmlkZXJOb0VxdWFsT3ApIHsKICAgICAgICAgICAgcmV0dXJuICEoc3RycG9zKCR0aGlzLT52ZXJzaW9uLCAnZGV2LScpID09PSAwIHx8IHN0cnBvcygkcHJvdmlkZXItPnZlcnNpb24sICdkZXYtJykgPT09IDApOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb24xID0gJGlzRXF1YWxPcCA/ICR0aGlzLT52ZXJzaW9uIDogJHByb3ZpZGVyLT52ZXJzaW9uOwogICAgICAgICR2ZXJzaW9uMiA9ICRpc0VxdWFsT3AgPyAkcHJvdmlkZXItPnZlcnNpb24gOiAkdGhpcy0+dmVyc2lvbjsKICAgICAgICAkb3BlcmF0b3IgPSAkaXNFcXVhbE9wID8gJHByb3ZpZGVyLT5vcGVyYXRvciA6ICR0aGlzLT5vcGVyYXRvcjsKCiAgICAgICAgaWYgKCR0aGlzLT52ZXJzaW9uQ29tcGFyZSgkdmVyc2lvbjEsICR2ZXJzaW9uMiwgc2VsZjo6JHRyYW5zT3BJbnRbJG9wZXJhdG9yXSwgJGNvbXBhcmVCcmFuY2hlcykpIHsKICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlLCBlLmcuIHJlcXVpcmUgPj0gMS4wIGFuZCBwcm92aWRlIDwgMS4wCiAgICAgICAgICAgIC8vIDEuMCA+PSAxLjAgYnV0IDEuMCBpcyBvdXRzaWRlIG9mIHRoZSBwcm92aWRlZCBpbnRlcnZhbAoKICAgICAgICAgICAgcmV0dXJuICEoc2VsZjo6JHRyYW5zT3BJbnRbJHByb3ZpZGVyLT5vcGVyYXRvcl0gPT09ICRwcm92aWRlck5vRXF1YWxPcAogICAgICAgICAgICAgICAgJiYgc2VsZjo6JHRyYW5zT3BJbnRbJHRoaXMtPm9wZXJhdG9yXSAhPT0gJG5vRXF1YWxPcAogICAgICAgICAgICAgICAgJiYgXHZlcnNpb25fY29tcGFyZSgkcHJvdmlkZXItPnZlcnNpb24sICR0aGlzLT52ZXJzaW9uLCAnPT0nKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiR0cmFuc09wSW50WyR0aGlzLT5vcGVyYXRvcl0gLiAnICcgLiAkdGhpcy0+dmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvd2VyQm91bmQoKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Qm91bmRzKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+bG93ZXJCb3VuZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVwcGVyQm91bmQoKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Qm91bmRzKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+dXBwZXJCb3VuZDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RCb3VuZHMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+bG93ZXJCb3VuZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBCcmFuY2hlcwogICAgICAgIGlmIChzdHJwb3MoJHRoaXMtPnZlcnNpb24sICdkZXYtJykgPT09IDApIHsKICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSBCb3VuZDo6emVybygpOwogICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IEJvdW5kOjpwb3NpdGl2ZUluZmluaXR5KCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2ggKCR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBjYXNlIHNlbGY6Ok9QX0VROgogICAgICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSBuZXcgQm91bmQoJHRoaXMtPnZlcnNpb24sIHRydWUpOwogICAgICAgICAgICAgICAgJHRoaXMtPnVwcGVyQm91bmQgPSBuZXcgQm91bmQoJHRoaXMtPnZlcnNpb24sIHRydWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6T1BfTFQ6CiAgICAgICAgICAgICAgICAkdGhpcy0+bG93ZXJCb3VuZCA9IEJvdW5kOjp6ZXJvKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IG5ldyBCb3VuZCgkdGhpcy0+dmVyc2lvbiwgZmFsc2UpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6T1BfTEU6CiAgICAgICAgICAgICAgICAkdGhpcy0+bG93ZXJCb3VuZCA9IEJvdW5kOjp6ZXJvKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IG5ldyBCb3VuZCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBzZWxmOjpPUF9HVDoKICAgICAgICAgICAgICAgICR0aGlzLT5sb3dlckJvdW5kID0gbmV3IEJvdW5kKCR0aGlzLT52ZXJzaW9uLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IEJvdW5kOjpwb3NpdGl2ZUluZmluaXR5KCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBzZWxmOjpPUF9HRToKICAgICAgICAgICAgICAgICR0aGlzLT5sb3dlckJvdW5kID0gbmV3IEJvdW5kKCR0aGlzLT52ZXJzaW9uLCB0cnVlKTsKICAgICAgICAgICAgICAgICR0aGlzLT51cHBlckJvdW5kID0gQm91bmQ6OnBvc2l0aXZlSW5maW5pdHkoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHNlbGY6Ok9QX05FOgogICAgICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSBCb3VuZDo6emVybygpOwogICAgICAgICAgICAgICAgJHRoaXMtPnVwcGVyQm91bmQgPSBCb3VuZDo6cG9zaXRpdmVJbmZpbml0eSgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnQ7CgovKioKICogRGVmaW5lcyBhIGNvbmp1bmN0aXZlIG9yIGRpc2p1bmN0aXZlIHNldCBvZiBjb25zdHJhaW50cy4KICovCmNsYXNzIE11bHRpQ29uc3RyYWludCBpbXBsZW1lbnRzIENvbnN0cmFpbnRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAdmFyIENvbnN0cmFpbnRJbnRlcmZhY2VbXQogICAgICogQHBocHN0YW4tdmFyIG5vbi1lbXB0eS1hcnJheTxDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnN0cmFpbnRzOwoKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcm90ZWN0ZWQgJHByZXR0eVN0cmluZzsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJvdGVjdGVkICRzdHJpbmc7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJvdGVjdGVkICRjb25qdW5jdGl2ZTsKCiAgICAvKiogQHZhciBCb3VuZHxudWxsICovCiAgICBwcm90ZWN0ZWQgJGxvd2VyQm91bmQ7CgogICAgLyoqIEB2YXIgQm91bmR8bnVsbCAqLwogICAgcHJvdGVjdGVkICR1cHBlckJvdW5kOwoKICAgIC8qKgogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2VbXSAkY29uc3RyYWludHMgQSBzZXQgb2YgY29uc3RyYWludHMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgJGNvbmp1bmN0aXZlIFdoZXRoZXIgdGhlIGNvbnN0cmFpbnRzIHNob3VsZCBiZSB0cmVhdGVkIGFzIGNvbmp1bmN0aXZlIG9yIGRpc2p1bmN0aXZlCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIElmIGxlc3MgdGhhbiAyIGNvbnN0cmFpbnRzIGFyZSBwYXNzZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRjb25zdHJhaW50cywgJGNvbmp1bmN0aXZlID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPCAyKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgJ011c3QgcHJvdmlkZSBhdCBsZWFzdCB0d28gY29uc3RyYWludHMgZm9yIGEgTXVsdGlDb25zdHJhaW50LiBVc2UgJy4KICAgICAgICAgICAgICAgICd0aGUgcmVndWxhciBDb25zdHJhaW50IGNsYXNzIGZvciBvbmUgY29uc3RyYWludCBvbmx5IG9yIE1hdGNoQWxsQ29uc3RyYWludCBmb3Igbm9uZS4gWW91IG1heSB1c2UgJy4KICAgICAgICAgICAgICAgICdNdWx0aUNvbnN0cmFpbnQ6OmNyZWF0ZSgpIHdoaWNoIG9wdGltaXplcyBhbmQgaGFuZGxlcyB0aG9zZSBjYXNlcyBhdXRvbWF0aWNhbGx5LicKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb25zdHJhaW50cyA9ICRjb25zdHJhaW50czsKICAgICAgICAkdGhpcy0+Y29uanVuY3RpdmUgPSAkY29uanVuY3RpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uc3RyYWludHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uc3RyYWludHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQ29uanVuY3RpdmUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uanVuY3RpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGlzanVuY3RpdmUoKQogICAgewogICAgICAgIHJldHVybiAhJHRoaXMtPmNvbmp1bmN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGlsZSgkb3RoZXJPcGVyYXRvcikKICAgIHsKICAgICAgICAkcGFydHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICAkY29kZSA9ICRjb25zdHJhaW50LT5jb21waWxlKCRvdGhlck9wZXJhdG9yKTsKICAgICAgICAgICAgaWYgKCRjb2RlID09PSAndHJ1ZScpIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmNvbmp1bmN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd0cnVlJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCRjb2RlID09PSAnZmFsc2UnKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbmp1bmN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdmYWxzZSc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcGFydHNbXSA9ICcoJy4kY29kZS4nKSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJHBhcnRzKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29uanVuY3RpdmUgPyAndHJ1ZScgOiAnZmFsc2UnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25qdW5jdGl2ZSA/IGltcGxvZGUoJyYmJywgJHBhcnRzKSA6IGltcGxvZGUoJ3x8JywgJHBhcnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hlcyhDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcikKICAgIHsKICAgICAgICBpZiAoZmFsc2UgPT09ICR0aGlzLT5jb25qdW5jdGl2ZSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgIGlmICgkcHJvdmlkZXItPm1hdGNoZXMoJGNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIHdoZW4gbWF0Y2hpbmcgYSBjb25qdW5jdGl2ZSBhbmQgYSBkaXNqdW5jdGl2ZSBtdWx0aSBjb25zdHJhaW50IHdlIGhhdmUgdG8gaXRlcmF0ZSBvdmVyIHRoZSBkaXNqdW5jdGl2ZSBvbmUKICAgICAgICAvLyBvdGhlcndpc2Ugd2UnZCByZXR1cm4gdHJ1ZSBpZiBkaWZmZXJlbnQgcGFydHMgb2YgdGhlIGRpc2p1bmN0aXZlIGNvbnN0cmFpbnQgbWF0Y2ggdGhlIGNvbmp1bmN0aXZlIG9uZQogICAgICAgIC8vIHdoaWNoIHdvdWxkIGxlYWQgdG8gaW5jb3JyZWN0IHJlc3VsdHMsIGUuZy4gWz4xIGFuZCA8Ml0gd291bGQgbWF0Y2ggWzwxIG9yID4yXSBhbHRob3VnaCB0aGV5IGRvIG5vdCBpbnRlcnNlY3QKICAgICAgICBpZiAoJHByb3ZpZGVyIGluc3RhbmNlb2YgTXVsdGlDb25zdHJhaW50ICYmICRwcm92aWRlci0+aXNEaXNqdW5jdGl2ZSgpKSB7CiAgICAgICAgICAgIHJldHVybiAkcHJvdmlkZXItPm1hdGNoZXMoJHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbnN0cmFpbnRzIGFzICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmICghJHByb3ZpZGVyLT5tYXRjaGVzKCRjb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZXR0eVN0cmluZygkcHJldHR5U3RyaW5nKQogICAgewogICAgICAgICR0aGlzLT5wcmV0dHlTdHJpbmcgPSAkcHJldHR5U3RyaW5nOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnByZXR0eVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVN0cmluZzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoc3RyaW5nKSAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c3RyaW5nICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+c3RyaW5nOwogICAgICAgIH0KCiAgICAgICAgJGNvbnN0cmFpbnRzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnRzW10gPSAoc3RyaW5nKSAkY29uc3RyYWludDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+c3RyaW5nID0gJ1snIC4gaW1wbG9kZSgkdGhpcy0+Y29uanVuY3RpdmUgPyAnICcgOiAnIHx8ICcsICRjb25zdHJhaW50cykgLiAnXSc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb3dlckJvdW5kKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXh0cmFjdEJvdW5kcygpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmxvd2VyQm91bmQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignZXh0cmFjdEJvdW5kcyBzaG91bGQgaGF2ZSBwb3B1bGF0ZWQgdGhlIGxvd2VyQm91bmQgcHJvcGVydHknKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+bG93ZXJCb3VuZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVwcGVyQm91bmQoKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Qm91bmRzKCk7CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+dXBwZXJCb3VuZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdleHRyYWN0Qm91bmRzIHNob3VsZCBoYXZlIHBvcHVsYXRlZCB0aGUgdXBwZXJCb3VuZCBwcm9wZXJ0eScpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT51cHBlckJvdW5kOwogICAgfQoKICAgIC8qKgogICAgICogVHJpZXMgdG8gb3B0aW1pemUgdGhlIGNvbnN0cmFpbnRzIGFzIG11Y2ggYXMgcG9zc2libGUsIG1lYW5pbmcKICAgICAqIHJlZHVjaW5nL2NvbGxhcHNpbmcgY29uZ3J1ZW50IGNvbnN0cmFpbnRzIGV0Yy4KICAgICAqIERvZXMgbm90IG5lY2Vzc2FyaWx5IHJldHVybiBhIE11bHRpQ29uc3RyYWludCBpbnN0YW5jZSBpZgogICAgICogdGhpbmdzIGNhbiBiZSByZWR1Y2VkIHRvIGEgc2ltcGxlIGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZVtdICRjb25zdHJhaW50cyBBIHNldCBvZiBjb25zdHJhaW50cwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAkY29uanVuY3RpdmUgV2hldGhlciB0aGUgY29uc3RyYWludHMgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgY29uanVuY3RpdmUgb3IgZGlzanVuY3RpdmUKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGUoYXJyYXkgJGNvbnN0cmFpbnRzLCAkY29uanVuY3RpdmUgPSB0cnVlKQogICAgewogICAgICAgIGlmICgwID09PSBcY291bnQoJGNvbnN0cmFpbnRzKSkgewogICAgICAgICAgICByZXR1cm4gbmV3IE1hdGNoQWxsQ29uc3RyYWludCgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkY29uc3RyYWludHMpKSB7CiAgICAgICAgICAgIHJldHVybiAkY29uc3RyYWludHNbMF07CiAgICAgICAgfQoKICAgICAgICAkb3B0aW1pemVkID0gc2VsZjo6b3B0aW1pemVDb25zdHJhaW50cygkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSk7CiAgICAgICAgaWYgKCRvcHRpbWl6ZWQgIT09IG51bGwpIHsKICAgICAgICAgICAgbGlzdCgkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSkgPSAkb3B0aW1pemVkOwogICAgICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPT09IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29uc3RyYWludHNbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgc2VsZigkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIENvbnN0cmFpbnRJbnRlcmZhY2VbXSAkY29uc3RyYWludHMKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICRjb25qdW5jdGl2ZQogICAgICogQHJldHVybiA/YXJyYXkKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXl7MDogbGlzdDxDb25zdHJhaW50SW50ZXJmYWNlPiwgMTogYm9vbH18bnVsbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBvcHRpbWl6ZUNvbnN0cmFpbnRzKGFycmF5ICRjb25zdHJhaW50cywgJGNvbmp1bmN0aXZlKQogICAgewogICAgICAgIC8vIHBhcnNlIHRoZSB0d28gT1IgZ3JvdXBzIGFuZCBpZiB0aGV5IGFyZSBjb250aWd1b3VzIHdlIGNvbGxhcHNlCiAgICAgICAgLy8gdGhlbSBpbnRvIG9uZSBjb25zdHJhaW50CiAgICAgICAgLy8gWz49IDEgPCAyXSB8fCBbPj0gMiA8IDNdIHx8IFs+PSAzIDwgNF0gPT4gWz49IDEgPCA0XQogICAgICAgIGlmICghJGNvbmp1bmN0aXZlKSB7CiAgICAgICAgICAgICRsZWZ0ID0gJGNvbnN0cmFpbnRzWzBdOwogICAgICAgICAgICAkbWVyZ2VkQ29uc3RyYWludHMgPSBhcnJheSgpOwogICAgICAgICAgICAkb3B0aW1pemVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoJGkgPSAxLCAkbCA9IFxjb3VudCgkY29uc3RyYWludHMpOyAkaSA8ICRsOyAkaSsrKSB7CiAgICAgICAgICAgICAgICAkcmlnaHQgPSAkY29uc3RyYWludHNbJGldOwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICRsZWZ0IGluc3RhbmNlb2Ygc2VsZgogICAgICAgICAgICAgICAgICAgICYmICRsZWZ0LT5jb25qdW5jdGl2ZQogICAgICAgICAgICAgICAgICAgICYmICRyaWdodCBpbnN0YW5jZW9mIHNlbGYKICAgICAgICAgICAgICAgICAgICAmJiAkcmlnaHQtPmNvbmp1bmN0aXZlCiAgICAgICAgICAgICAgICAgICAgJiYgXGNvdW50KCRsZWZ0LT5jb25zdHJhaW50cykgPT09IDIKICAgICAgICAgICAgICAgICAgICAmJiBcY291bnQoJHJpZ2h0LT5jb25zdHJhaW50cykgPT09IDIKICAgICAgICAgICAgICAgICAgICAmJiAoJGxlZnQwID0gKHN0cmluZykgJGxlZnQtPmNvbnN0cmFpbnRzWzBdKQogICAgICAgICAgICAgICAgICAgICYmICRsZWZ0MFswXSA9PT0gJz4nICYmICRsZWZ0MFsxXSA9PT0gJz0nCiAgICAgICAgICAgICAgICAgICAgJiYgKCRsZWZ0MSA9IChzdHJpbmcpICRsZWZ0LT5jb25zdHJhaW50c1sxXSkKICAgICAgICAgICAgICAgICAgICAmJiAkbGVmdDFbMF0gPT09ICc8JwogICAgICAgICAgICAgICAgICAgICYmICgkcmlnaHQwID0gKHN0cmluZykgJHJpZ2h0LT5jb25zdHJhaW50c1swXSkKICAgICAgICAgICAgICAgICAgICAmJiAkcmlnaHQwWzBdID09PSAnPicgJiYgJHJpZ2h0MFsxXSA9PT0gJz0nCiAgICAgICAgICAgICAgICAgICAgJiYgKCRyaWdodDEgPSAoc3RyaW5nKSAkcmlnaHQtPmNvbnN0cmFpbnRzWzFdKQogICAgICAgICAgICAgICAgICAgICYmICRyaWdodDFbMF0gPT09ICc8JwogICAgICAgICAgICAgICAgICAgICYmIHN1YnN0cigkbGVmdDEsIDIpID09PSBzdWJzdHIoJHJpZ2h0MCwgMykKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICRvcHRpbWl6ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICRsZWZ0ID0gbmV3IE11bHRpQ29uc3RyYWludCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGVmdC0+Y29uc3RyYWludHNbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmlnaHQtPmNvbnN0cmFpbnRzWzFdLAogICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG1lcmdlZENvbnN0cmFpbnRzW10gPSAkbGVmdDsKICAgICAgICAgICAgICAgICAgICAkbGVmdCA9ICRyaWdodDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJG9wdGltaXplZCkgewogICAgICAgICAgICAgICAgJG1lcmdlZENvbnN0cmFpbnRzW10gPSAkbGVmdDsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkbWVyZ2VkQ29uc3RyYWludHMsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETzogSGVyZSdzIHRoZSBwbGFjZSB0byBwdXQgbW9yZSBvcHRpbWl6YXRpb25zCgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXh0cmFjdEJvdW5kcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5sb3dlckJvdW5kKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmxvd2VyQm91bmQgfHwgbnVsbCA9PT0gJHRoaXMtPnVwcGVyQm91bmQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5sb3dlckJvdW5kID0gJGNvbnN0cmFpbnQtPmdldExvd2VyQm91bmQoKTsKICAgICAgICAgICAgICAgICR0aGlzLT51cHBlckJvdW5kID0gJGNvbnN0cmFpbnQtPmdldFVwcGVyQm91bmQoKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQtPmdldExvd2VyQm91bmQoKS0+Y29tcGFyZVRvKCR0aGlzLT5sb3dlckJvdW5kLCAkdGhpcy0+aXNDb25qdW5jdGl2ZSgpID8gJz4nIDogJzwnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSAkY29uc3RyYWludC0+Z2V0TG93ZXJCb3VuZCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQtPmdldFVwcGVyQm91bmQoKS0+Y29tcGFyZVRvKCR0aGlzLT51cHBlckJvdW5kLCAkdGhpcy0+aXNDb25qdW5jdGl2ZSgpID8gJzwnIDogJz4nKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnVwcGVyQm91bmQgPSAkY29uc3RyYWludC0+Z2V0VXBwZXJCb3VuZCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnQ7CgovKioKICogRE8gTk9UIElNUExFTUVOVCB0aGlzIGludGVyZmFjZS4gSXQgaXMgb25seSBtZWFudCBmb3IgdXNhZ2UgYXMgYSB0eXBlIGhpbnQKICogaW4gbGlicmFyaWVzIHJlbHlpbmcgb24gY29tcG9zZXIvc2VtdmVyIGJ1dCBjcmVhdGluZyB5b3VyIG93biBjb25zdHJhaW50IGNsYXNzCiAqIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBpcyBub3QgYSBzdXBwb3J0ZWQgdXNlIGNhc2UgYW5kIHdpbGwgY2F1c2UgdGhlCiAqIGNvbXBvc2VyL3NlbXZlciBjb21wb25lbnRzIHRvIHJldHVybiB1bmV4cGVjdGVkIHJlc3VsdHMuCiAqLwppbnRlcmZhY2UgQ29uc3RyYWludEludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBjb25zdHJhaW50IGludGVyc2VjdHMgaW4gYW55IHdheSB3aXRoIHRoaXMgY29uc3RyYWludAogICAgICoKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hlcyhDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcik7CgogICAgLyoqCiAgICAgKiBQcm92aWRlcyBhIGNvbXBpbGVkIHZlcnNpb24gb2YgdGhlIGNvbnN0cmFpbnQgZm9yIHRoZSBnaXZlbiBvcGVyYXRvcgogICAgICogVGhlIGNvbXBpbGVkIHZlcnNpb24gbXVzdCBiZSBhIFBIUCBleHByZXNzaW9uLgogICAgICogRXhlY3V0b3Igb2YgY29tcGlsZSB2ZXJzaW9uIG11c3QgcHJvdmlkZSAyIHZhcmlhYmxlczoKICAgICAqIC0gJHYgPSB0aGUgc3RyaW5nIHZlcnNpb24gdG8gY29tcGFyZSB3aXRoCiAgICAgKiAtICRiID0gd2hldGhlciBvciBub3QgdGhlIHZlcnNpb24gaXMgYSBub24tY29tcGFyYWJsZSBicmFuY2ggKHN0YXJ0cyB3aXRoICJkZXYtIikKICAgICAqCiAgICAgKiBAc2VlIENvbnN0cmFpbnQ6Ok9QXyogZm9yIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBvcGVyYXRvcnMuCiAgICAgKiBAZXhhbXBsZSByZXR1cm4gJyEkYiAmJiB2ZXJzaW9uX2NvbXBhcmUoJHYsICcxLjAnLCAnPicpJzsKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRvdGhlck9wZXJhdG9yIG9uZSBDb25zdHJhaW50OjpPUF8qCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBDb25zdHJhaW50OjpPUF8qICRvdGhlck9wZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21waWxlKCRvdGhlck9wZXJhdG9yKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gQm91bmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVwcGVyQm91bmQoKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gQm91bmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvd2VyQm91bmQoKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcHJldHR5U3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmV0dHlTdHJpbmcoJHByZXR0eVN0cmluZyk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnQ7CgpjbGFzcyBCb3VuZAp7CiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJHZlcnNpb247CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkaXNJbmNsdXNpdmU7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKiBAcGFyYW0gYm9vbCAgICRpc0luY2x1c2l2ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHZlcnNpb24sICRpc0luY2x1c2l2ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgICR0aGlzLT5pc0luY2x1c2l2ZSA9ICRpc0luY2x1c2l2ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW5jbHVzaXZlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzSW5jbHVzaXZlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1plcm8oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VmVyc2lvbigpID09PSAnMC4wLjAuMC1kZXYnICYmICR0aGlzLT5pc0luY2x1c2l2ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Bvc2l0aXZlSW5maW5pdHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VmVyc2lvbigpID09PSBQSFBfSU5UX01BWC4nLjAuMC4wJyAmJiAhJHRoaXMtPmlzSW5jbHVzaXZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21wYXJlcyBhIGJvdW5kIHRvIGFub3RoZXIgd2l0aCBhIGdpdmVuIG9wZXJhdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBCb3VuZCAgJG90aGVyCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGFyZVRvKEJvdW5kICRvdGhlciwgJG9wZXJhdG9yKQogICAgewogICAgICAgIGlmICghXGluX2FycmF5KCRvcGVyYXRvciwgYXJyYXkoJzwnLCAnPicpLCB0cnVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignRG9lcyBub3Qgc3VwcG9ydCBhbnkgb3RoZXIgb3BlcmF0b3Igb3RoZXIgdGhhbiA+IG9yIDwuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGV5IGFyZSB0aGUgc2FtZSBpdCBkb2Vzbid0IG1hdHRlcgogICAgICAgIGlmICgkdGhpcyA9PSAkb3RoZXIpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBhcmVSZXN1bHQgPSB2ZXJzaW9uX2NvbXBhcmUoJHRoaXMtPmdldFZlcnNpb24oKSwgJG90aGVyLT5nZXRWZXJzaW9uKCkpOwoKICAgICAgICAvLyBOb3QgdGhlIHNhbWUgdmVyc2lvbiBtZWFucyB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIGlmIHRoZSBib3VuZHMgYXJlIGluY2x1c2l2ZSBvciBub3QKICAgICAgICBpZiAoMCAhPT0gJGNvbXBhcmVSZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuICgoJz4nID09PSAkb3BlcmF0b3IpID8gMSA6IC0xKSA9PT0gJGNvbXBhcmVSZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICAvLyBRdWVzdGlvbiB3ZSdyZSBhbnN3ZXJpbmcgaGVyZSBpcyAiYW0gSSBoaWdoZXIgdGhhbiAkb3RoZXI/IgogICAgICAgIHJldHVybiAnPicgPT09ICRvcGVyYXRvciA/ICRvdGhlci0+aXNJbmNsdXNpdmUoKSA6ICEkb3RoZXItPmlzSW5jbHVzaXZlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKAogICAgICAgICAgICAnJXMgWyVzXScsCiAgICAgICAgICAgICR0aGlzLT5nZXRWZXJzaW9uKCksCiAgICAgICAgICAgICR0aGlzLT5pc0luY2x1c2l2ZSgpID8gJ2luY2x1c2l2ZScgOiAnZXhjbHVzaXZlJwogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB6ZXJvKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IEJvdW5kKCcwLjAuMC4wLWRldicsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcG9zaXRpdmVJbmZpbml0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBCb3VuZChQSFBfSU5UX01BWC4nLjAuMC4wJywgZmFsc2UpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnQ7CgovKioKICogQmxhY2tob2xlIG9mIGNvbnN0cmFpbnRzLCBub3RoaW5nIGVzY2FwZXMgaXQKICovCmNsYXNzIE1hdGNoTm9uZUNvbnN0cmFpbnQgaW1wbGVtZW50cyBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcm90ZWN0ZWQgJHByZXR0eVN0cmluZzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hlcyhDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcikKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21waWxlKCRvdGhlck9wZXJhdG9yKQogICAgewogICAgICAgIHJldHVybiAnZmFsc2UnOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJldHR5U3RyaW5nKCRwcmV0dHlTdHJpbmcpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXR0eVN0cmluZyA9ICRwcmV0dHlTdHJpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cHJldHR5U3RyaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJldHR5U3RyaW5nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIChzdHJpbmcpICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICdbXSc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcHBlckJvdW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IEJvdW5kKCcwLjAuMC4wLWRldicsIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvd2VyQm91bmQoKQogICAgewogICAgICAgIHJldHVybiBuZXcgQm91bmQoJzAuMC4wLjAtZGV2JywgZmFsc2UpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnQ7CgovKioKICogRGVmaW5lcyB0aGUgYWJzZW5jZSBvZiBhIGNvbnN0cmFpbnQuCiAqCiAqIFRoaXMgY29uc3RyYWludCBtYXRjaGVzIGV2ZXJ5dGhpbmcuCiAqLwpjbGFzcyBNYXRjaEFsbENvbnN0cmFpbnQgaW1wbGVtZW50cyBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcm90ZWN0ZWQgJHByZXR0eVN0cmluZzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hlcyhDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcikKICAgIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbXBpbGUoJG90aGVyT3BlcmF0b3IpCiAgICB7CiAgICAgICAgcmV0dXJuICd0cnVlJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZXR0eVN0cmluZygkcHJldHR5U3RyaW5nKQogICAgewogICAgICAgICR0aGlzLT5wcmV0dHlTdHJpbmcgPSAkcHJldHR5U3RyaW5nOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnByZXR0eVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVN0cmluZzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoc3RyaW5nKSAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAnKic7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcHBlckJvdW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gQm91bmQ6OnBvc2l0aXZlSW5maW5pdHkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvd2VyQm91bmQoKQogICAgewogICAgICAgIHJldHVybiBCb3VuZDo6emVybygpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hOb25lQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE11bHRpQ29uc3RyYWludDsKCi8qKgogKiBIZWxwZXIgY2xhc3MgZ2VuZXJhdGluZyBpbnRlcnZhbHMgZnJvbSBjb25zdHJhaW50cwogKgogKiBUaGlzIGNvbnRhaW5zIHV0aWxpdGllcyBmb3I6CiAqCiAqICAtIGNvbXBhY3RpbmcgYW4gZXhpc3RpbmcgY29uc3RyYWludCB3aGljaCBjYW4gYmUgdXNlZCB0byBjb21iaW5lIHNldmVyYWwgaW50byBvbmUKICogYnkgY3JlYXRpbmcgYSBNdWx0aUNvbnN0cmFpbnQgb3V0IG9mIHRoZSBtYW55IGNvbnN0cmFpbnRzIHlvdSBoYXZlLgogKgogKiAgLSBjaGVja2luZyB3aGV0aGVyIG9uZSBzdWJzZXQgaXMgYSBzdWJzZXQgb2YgYW5vdGhlci4KICoKICogTm90ZTogWW91IHNob3VsZCBjYWxsIGNsZWFyIHRvIGZyZWUgbWVtb2l6YXRpb24gbWVtb3J5ICB1c2FnZSB3aGVuIHlvdSBhcmUgZG9uZSB1c2luZyB0aGlzIGNsYXNzCiAqLwpjbGFzcyBJbnRlcnZhbHMKewogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBhcnJheXsnbnVtZXJpYyc6IEludGVydmFsW10sICdicmFuY2hlcyc6IGFycmF5eyduYW1lcyc6IHN0cmluZ1tdLCAnZXhjbHVkZSc6IGJvb2x9fT4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGludGVydmFsc0NhY2hlID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIGludD4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJG9wU29ydE9yZGVyID0gYXJyYXkoCiAgICAgICAgJz49JyA9PiAtMywKICAgICAgICAnPCcgPT4gLTIsCiAgICAgICAgJz4nID0+IDIsCiAgICAgICAgJzw9JyA9PiAzLAogICAgKTsKCiAgICAvKioKICAgICAqIENsZWFycyB0aGUgbWVtb2l6YXRpb24gY2FjaGUgb25jZSB5b3UgYXJlIGRvbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjbGVhcigpCiAgICB7CiAgICAgICAgc2VsZjo6JGludGVydmFsc0NhY2hlID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyICRjYW5kaWRhdGUgaXMgYSBzdWJzZXQgb2YgJGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1N1YnNldE9mKENvbnN0cmFpbnRJbnRlcmZhY2UgJGNhbmRpZGF0ZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBpZiAoJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBNYXRjaEFsbENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhbmRpZGF0ZSBpbnN0YW5jZW9mIE1hdGNoTm9uZUNvbnN0cmFpbnQgfHwgJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBNYXRjaE5vbmVDb25zdHJhaW50KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRpbnRlcnNlY3Rpb25JbnRlcnZhbHMgPSBzZWxmOjpnZXQobmV3IE11bHRpQ29uc3RyYWludChhcnJheSgkY2FuZGlkYXRlLCAkY29uc3RyYWludCksIHRydWUpKTsKICAgICAgICAkY2FuZGlkYXRlSW50ZXJ2YWxzID0gc2VsZjo6Z2V0KCRjYW5kaWRhdGUpOwogICAgICAgIGlmIChcY291bnQoJGludGVyc2VjdGlvbkludGVydmFsc1snbnVtZXJpYyddKSAhPT0gXGNvdW50KCRjYW5kaWRhdGVJbnRlcnZhbHNbJ251bWVyaWMnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGludGVyc2VjdGlvbkludGVydmFsc1snbnVtZXJpYyddIGFzICRpbmRleCA9PiAkaW50ZXJ2YWwpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkY2FuZGlkYXRlSW50ZXJ2YWxzWydudW1lcmljJ11bJGluZGV4XSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKChzdHJpbmcpICRjYW5kaWRhdGVJbnRlcnZhbHNbJ251bWVyaWMnXVskaW5kZXhdLT5nZXRTdGFydCgpICE9PSAoc3RyaW5nKSAkaW50ZXJ2YWwtPmdldFN0YXJ0KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKChzdHJpbmcpICRjYW5kaWRhdGVJbnRlcnZhbHNbJ251bWVyaWMnXVskaW5kZXhdLT5nZXRFbmQoKSAhPT0gKHN0cmluZykgJGludGVydmFsLT5nZXRFbmQoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGludGVyc2VjdGlvbkludGVydmFsc1snYnJhbmNoZXMnXVsnZXhjbHVkZSddICE9PSAkY2FuZGlkYXRlSW50ZXJ2YWxzWydicmFuY2hlcyddWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoXGNvdW50KCRpbnRlcnNlY3Rpb25JbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ10pICE9PSBcY291bnQoJGNhbmRpZGF0ZUludGVydmFsc1snYnJhbmNoZXMnXVsnbmFtZXMnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkaW50ZXJzZWN0aW9uSW50ZXJ2YWxzWydicmFuY2hlcyddWyduYW1lcyddIGFzICRpbmRleCA9PiAkbmFtZSkgewogICAgICAgICAgICBpZiAoJG5hbWUgIT09ICRjYW5kaWRhdGVJbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ11bJGluZGV4XSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyICRhIGFuZCAkYiBoYXZlIGFueSBpbnRlcnNlY3Rpb24sIGVxdWl2YWxlbnQgdG8gJGEtPm1hdGNoZXMoJGIpCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaGF2ZUludGVyc2VjdGlvbnMoQ29uc3RyYWludEludGVyZmFjZSAkYSwgQ29uc3RyYWludEludGVyZmFjZSAkYikKICAgIHsKICAgICAgICBpZiAoJGEgaW5zdGFuY2VvZiBNYXRjaEFsbENvbnN0cmFpbnQgfHwgJGIgaW5zdGFuY2VvZiBNYXRjaEFsbENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGEgaW5zdGFuY2VvZiBNYXRjaE5vbmVDb25zdHJhaW50IHx8ICRiIGluc3RhbmNlb2YgTWF0Y2hOb25lQ29uc3RyYWludCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkaW50ZXJzZWN0aW9uSW50ZXJ2YWxzID0gc2VsZjo6Z2VuZXJhdGVJbnRlcnZhbHMobmV3IE11bHRpQ29uc3RyYWludChhcnJheSgkYSwgJGIpLCB0cnVlKSwgdHJ1ZSk7CgogICAgICAgIHJldHVybiBcY291bnQoJGludGVyc2VjdGlvbkludGVydmFsc1snbnVtZXJpYyddKSA+IDAgfHwgJGludGVyc2VjdGlvbkludGVydmFsc1snYnJhbmNoZXMnXVsnZXhjbHVkZSddIHx8IFxjb3VudCgkaW50ZXJzZWN0aW9uSW50ZXJ2YWxzWydicmFuY2hlcyddWyduYW1lcyddKSA+IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBvcHRpbWl6ZSBhIE11bHRpQ29uc3RyYWludAogICAgICoKICAgICAqIFdoZW4gbWVyZ2luZyBNdWx0aUNvbnN0cmFpbnRzIHRvZ2V0aGVyIHRoZXkgY2FuIGdldCB2ZXJ5IGxhcmdlLCB0aGlzIHdpbGwKICAgICAqIGNvbXBhY3QgaXQgYnkgbG9va2luZyBhdCB0aGUgcmVhbCBpbnRlcnZhbHMgY292ZXJlZCBieSBhbGwgdGhlIGNvbnN0cmFpbnRzCiAgICAgKiBhbmQgdGhlbiBjcmVhdGVzIGEgbmV3IGNvbnN0cmFpbnQgY29udGFpbmluZyBvbmx5IHRoZSBzbWFsbGVzdCBhbW91bnQgb2YgcnVsZXMKICAgICAqIHRvIG1hdGNoIHRoZSBzYW1lIGludGVydmFscy4KICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb21wYWN0Q29uc3RyYWludChDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50KQogICAgewogICAgICAgIGlmICghJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBNdWx0aUNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuICRjb25zdHJhaW50OwogICAgICAgIH0KCiAgICAgICAgJGludGVydmFscyA9IHNlbGY6OmdlbmVyYXRlSW50ZXJ2YWxzKCRjb25zdHJhaW50KTsKICAgICAgICAkY29uc3RyYWludHMgPSBhcnJheSgpOwogICAgICAgICRoYXNOdW1lcmljTWF0Y2hBbGwgPSBmYWxzZTsKCiAgICAgICAgaWYgKFxjb3VudCgkaW50ZXJ2YWxzWydudW1lcmljJ10pID09PSAxICYmIChzdHJpbmcpICRpbnRlcnZhbHNbJ251bWVyaWMnXVswXS0+Z2V0U3RhcnQoKSA9PT0gKHN0cmluZykgSW50ZXJ2YWw6OmZyb21aZXJvKCkgJiYgKHN0cmluZykgJGludGVydmFsc1snbnVtZXJpYyddWzBdLT5nZXRFbmQoKSA9PT0gKHN0cmluZykgSW50ZXJ2YWw6OnVudGlsUG9zaXRpdmVJbmZpbml0eSgpKSB7CiAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJGludGVydmFsc1snbnVtZXJpYyddWzBdLT5nZXRTdGFydCgpOwogICAgICAgICAgICAkaGFzTnVtZXJpY01hdGNoQWxsID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdW5FcXVhbENvbnN0cmFpbnRzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yICgkaSA9IDAsICRjb3VudCA9IFxjb3VudCgkaW50ZXJ2YWxzWydudW1lcmljJ10pOyAkaSA8ICRjb3VudDsgJGkrKykgewogICAgICAgICAgICAgICAgJGludGVydmFsID0gJGludGVydmFsc1snbnVtZXJpYyddWyRpXTsKCiAgICAgICAgICAgICAgICAvLyBpZiBjdXJyZW50IGludGVydmFsIGVuZHMgd2l0aCA8IE4gYW5kIG5leHQgaW50ZXJ2YWwgYmVnaW5zIHdpdGggPiBOIHdlIGNhbiBzd2FwIHRoaXMgb3V0IGZvciAhPSBOCiAgICAgICAgICAgICAgICAvLyBidXQgdGhpcyBuZWVkcyB0byBoYXBwZW4gYXMgYSBjb25qdW5jdGl2ZSBleHByZXNzaW9uIHRvZ2V0aGVyIHdpdGggdGhlIHN0YXJ0IG9mIHRoZSBjdXJyZW50IGludGVydmFsCiAgICAgICAgICAgICAgICAvLyBhbmQgZW5kIG9mIG5leHQgaW50ZXJ2YWwsIHNvIFs+PU0sIDxOXSB8fCBbPk4sIDxQXSA9PiBbPj1NLCAhPU4sIDxQXSBidXQgTS9QIGNhbiBiZSBza2lwcGVkIGlmCiAgICAgICAgICAgICAgICAvLyB0aGV5IGFyZSB6ZXJvLytpbmYKICAgICAgICAgICAgICAgIGlmICgkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRPcGVyYXRvcigpID09PSAnPCcgJiYgJGkrMSA8ICRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICRuZXh0SW50ZXJ2YWwgPSAkaW50ZXJ2YWxzWydudW1lcmljJ11bJGkrMV07CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpbnRlcnZhbC0+Z2V0RW5kKCktPmdldFZlcnNpb24oKSA9PT0gJG5leHRJbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpICYmICRuZXh0SW50ZXJ2YWwtPmdldFN0YXJ0KCktPmdldE9wZXJhdG9yKCkgPT09ICc+JykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IGFkZCBhIHN0YXJ0IGlmIHdlIGRpZG4ndCBhbHJlYWR5IGRvIHNvLCBjYW4gYmUgc2tpcHBlZCBpZiB3ZSdyZSBsb29raW5nIGF0IHNlY29uZAogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRlcnZhbCBpbiBbPj1NLCA8Tl0gfHwgWz5OLCA8UF0gfHwgWz5QLCA8UV0gd2hlcmUgdW5FcXVhbENvbnN0cmFpbnRzIGN1cnJlbnRseSBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAvLyBbPj1NLCAhPU5dIGFscmVhZHkgYW5kIHdlIG9ubHkgd2FudCB0byBhZGQgIT1QIHJpZ2h0IG5vdwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCR1bkVxdWFsQ29uc3RyYWludHMpID09PSAwICYmIChzdHJpbmcpICRpbnRlcnZhbC0+Z2V0U3RhcnQoKSAhPT0gKHN0cmluZykgSW50ZXJ2YWw6OmZyb21aZXJvKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR1bkVxdWFsQ29uc3RyYWludHNbXSA9ICRpbnRlcnZhbC0+Z2V0U3RhcnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkdW5FcXVhbENvbnN0cmFpbnRzW10gPSBuZXcgQ29uc3RyYWludCgnIT0nLCAkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKFxjb3VudCgkdW5FcXVhbENvbnN0cmFpbnRzKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHdoZXJlIHRoZSBlbmQgb2YgdGhlIGZvbGxvd2luZyBpbnRlcnZhbCBvZiBhICE9IGNvbnN0cmFpbnQgaXMgYWRkZWQgYXMgZXhwbGFpbmVkIGFib3ZlCiAgICAgICAgICAgICAgICAgICAgaWYgKChzdHJpbmcpICRpbnRlcnZhbC0+Z2V0RW5kKCkgIT09IChzdHJpbmcpIEludGVydmFsOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdW5FcXVhbENvbnN0cmFpbnRzW10gPSAkaW50ZXJ2YWwtPmdldEVuZCgpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gY291bnQgaXMgMSBpZiBlbnRpcmUgY29uc3RyYWludCBpcyBqdXN0IG9uZSAhPSBleHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKFxjb3VudCgkdW5FcXVhbENvbnN0cmFpbnRzKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnRzW10gPSBuZXcgTXVsdGlDb25zdHJhaW50KCR1bkVxdWFsQ29uc3RyYWludHMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJHVuRXF1YWxDb25zdHJhaW50c1swXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR1bkVxdWFsQ29uc3RyYWludHMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgYmFjayA+PSB4IC0gPD0geCBpbnRlcnZhbHMgdG8gPT0geAogICAgICAgICAgICAgICAgaWYgKCRpbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpID09PSAkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRWZXJzaW9uKCkgJiYgJGludGVydmFsLT5nZXRTdGFydCgpLT5nZXRPcGVyYXRvcigpID09PSAnPj0nICYmICRpbnRlcnZhbC0+Z2V0RW5kKCktPmdldE9wZXJhdG9yKCkgPT09ICc8PScpIHsKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludHNbXSA9IG5ldyBDb25zdHJhaW50KCc9PScsICRpbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoKHN0cmluZykgJGludGVydmFsLT5nZXRTdGFydCgpID09PSAoc3RyaW5nKSBJbnRlcnZhbDo6ZnJvbVplcm8oKSkgewogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJGludGVydmFsLT5nZXRFbmQoKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgoc3RyaW5nKSAkaW50ZXJ2YWwtPmdldEVuZCgpID09PSAoc3RyaW5nKSBJbnRlcnZhbDo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludHNbXSA9ICRpbnRlcnZhbC0+Z2V0U3RhcnQoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnRzW10gPSBuZXcgTXVsdGlDb25zdHJhaW50KGFycmF5KCRpbnRlcnZhbC0+Z2V0U3RhcnQoKSwgJGludGVydmFsLT5nZXRFbmQoKSksIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkZGV2Q29uc3RyYWludHMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoMCA9PT0gXGNvdW50KCRpbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ10pKSB7CiAgICAgICAgICAgIGlmICgkaW50ZXJ2YWxzWydicmFuY2hlcyddWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgIGlmICgkaGFzTnVtZXJpY01hdGNoQWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRjaEFsbENvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgY29uc3RyYWludCBzaG91bGQgY29udGFpbiBhICE9IG9wZXJhdG9yIGFuZCBhbHJlYWR5IGNvdmVyIHRoaXMKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ10gYXMgJGJyYW5jaE5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICgkaW50ZXJ2YWxzWydicmFuY2hlcyddWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICAkZGV2Q29uc3RyYWludHNbXSA9IG5ldyBDb25zdHJhaW50KCchPScsICRicmFuY2hOYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGRldkNvbnN0cmFpbnRzW10gPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkYnJhbmNoTmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGV4Y2x1ZGVkIGJyYW5jaGVzLCBlLmcuICE9IGRldi1mb28gYXJlIGNvbmp1bmN0aXZlIHdpdGggdGhlIGludGVydmFsLCBzbwogICAgICAgICAgICAvLyA+IDIuMCAhPSBkZXYtZm9vIG11c3QgcmV0dXJuIGEgY29uanVuY3RpdmUgY29uc3RyYWludAogICAgICAgICAgICBpZiAoJGludGVydmFsc1snYnJhbmNoZXMnXVsnZXhjbHVkZSddKSB7CiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aUNvbnN0cmFpbnQoYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KG5ldyBNdWx0aUNvbnN0cmFpbnQoJGNvbnN0cmFpbnRzLCBmYWxzZSkpLAogICAgICAgICAgICAgICAgICAgICAgICAkZGV2Q29uc3RyYWludHMKICAgICAgICAgICAgICAgICAgICApLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPT09IDEgJiYgKHN0cmluZykkY29uc3RyYWludHNbMF0gPT09IChzdHJpbmcpSW50ZXJ2YWw6OmZyb21aZXJvKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRkZXZDb25zdHJhaW50cykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTXVsdGlDb25zdHJhaW50KCRkZXZDb25zdHJhaW50cywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZGV2Q29uc3RyYWludHNbMF07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aUNvbnN0cmFpbnQoYXJyYXlfbWVyZ2UoJGNvbnN0cmFpbnRzLCAkZGV2Q29uc3RyYWludHMpLCB0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGRldkNvbnN0cmFpbnRzIGNvbnRhaW5zIGEgbGlzdCBvZiA9PSBvcGVyYXRvcnMgZm9yIGJyYW5jaGVzIHdoaWNoIGFyZSBkaXNqdW5jdGl2ZSB3aXRoIHRoZQogICAgICAgICAgICAvLyByZXN0IG9mIHRoZSBjb25zdHJhaW50CiAgICAgICAgICAgICRjb25zdHJhaW50cyA9IGFycmF5X21lcmdlKCRjb25zdHJhaW50cywgJGRldkNvbnN0cmFpbnRzKTsKICAgICAgICB9CgogICAgICAgIGlmIChcY291bnQoJGNvbnN0cmFpbnRzKSA+IDEpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aUNvbnN0cmFpbnQoJGNvbnN0cmFpbnRzLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPT09IDEpIHsKICAgICAgICAgICAgcmV0dXJuICRjb25zdHJhaW50c1swXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgTWF0Y2hOb25lQ29uc3RyYWludDsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtZXJpYyBpbnRlcnZhbHMgYW5kIGJyYW5jaCBjb25zdHJhaW50cyByZXByZXNlbnRpbmcgYSBnaXZlbiBjb25zdHJhaW50CiAgICAgKgogICAgICogaWYgdGhlIHJldHVybmVkIG51bWVyaWMgYXJyYXkgaXMgZW1wdHkgaXQgbWVhbnMgdGhlIGNvbnN0cmFpbnQgbWF0Y2hlcyBub3RoaW5nIGluIHRoZSBudW1lcmljIHJhbmdlICgwIC0gK2luZikKICAgICAqIGlmIHRoZSByZXR1cm5lZCBicmFuY2hlcyBhcnJheSBpcyBlbXB0eSBpdCBtZWFucyBubyBkZXYtKiB2ZXJzaW9ucyBhcmUgbWF0Y2hlZAogICAgICogaWYgYSBjb25zdHJhaW50IG1hdGNoZXMgYWxsIHBvc3NpYmxlIGRldi0qIHZlcnNpb25zLCBicmFuY2hlcyB3aWxsIGNvbnRhaW4gSW50ZXJ2YWw6OmFueURldigpCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5eydudW1lcmljJzogSW50ZXJ2YWxbXSwgJ2JyYW5jaGVzJzogYXJyYXl7J25hbWVzJzogc3RyaW5nW10sICdleGNsdWRlJzogYm9vbH19CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0KENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJGtleSA9IChzdHJpbmcpICRjb25zdHJhaW50OwoKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRpbnRlcnZhbHNDYWNoZVska2V5XSkpIHsKICAgICAgICAgICAgc2VsZjo6JGludGVydmFsc0NhY2hlWyRrZXldID0gc2VsZjo6Z2VuZXJhdGVJbnRlcnZhbHMoJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRpbnRlcnZhbHNDYWNoZVska2V5XTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRzdG9wT25GaXJzdFZhbGlkSW50ZXJ2YWwKICAgICAqCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXl7J251bWVyaWMnOiBJbnRlcnZhbFtdLCAnYnJhbmNoZXMnOiBhcnJheXsnbmFtZXMnOiBzdHJpbmdbXSwgJ2V4Y2x1ZGUnOiBib29sfX0KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVJbnRlcnZhbHMoQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCwgJHN0b3BPbkZpcnN0VmFsaWRJbnRlcnZhbCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkY29uc3RyYWludCBpbnN0YW5jZW9mIE1hdGNoQWxsQ29uc3RyYWludCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJ251bWVyaWMnID0+IGFycmF5KG5ldyBJbnRlcnZhbChJbnRlcnZhbDo6ZnJvbVplcm8oKSwgSW50ZXJ2YWw6OnVudGlsUG9zaXRpdmVJbmZpbml0eSgpKSksICdicmFuY2hlcycgPT4gSW50ZXJ2YWw6OmFueURldigpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkY29uc3RyYWludCBpbnN0YW5jZW9mIE1hdGNoTm9uZUNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCdudW1lcmljJyA9PiBhcnJheSgpLCAnYnJhbmNoZXMnID0+IGFycmF5KCduYW1lcycgPT4gYXJyYXkoKSwgJ2V4Y2x1ZGUnID0+IGZhbHNlKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBDb25zdHJhaW50KSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjpnZW5lcmF0ZVNpbmdsZUNvbnN0cmFpbnRJbnRlcnZhbHMoJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkY29uc3RyYWludCBpbnN0YW5jZW9mIE11bHRpQ29uc3RyYWludCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignVGhlIGNvbnN0cmFpbnQgcGFzc2VkIGluIHNob3VsZCBiZSBhbiBNYXRjaEFsbENvbnN0cmFpbnQsIENvbnN0cmFpbnQgb3IgTXVsdGlDb25zdHJhaW50IGluc3RhbmNlLCBnb3QgJy5cZ2V0X2NsYXNzKCRjb25zdHJhaW50KS4nLicpOwogICAgICAgIH0KCiAgICAgICAgJGNvbnN0cmFpbnRzID0gJGNvbnN0cmFpbnQtPmdldENvbnN0cmFpbnRzKCk7CgogICAgICAgICRudW1lcmljR3JvdXBzID0gYXJyYXkoKTsKICAgICAgICAkY29uc3RyYWludEJyYW5jaGVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkY29uc3RyYWludHMgYXMgJGMpIHsKICAgICAgICAgICAgJHJlcyA9IHNlbGY6OmdldCgkYyk7CiAgICAgICAgICAgICRudW1lcmljR3JvdXBzW10gPSAkcmVzWydudW1lcmljJ107CiAgICAgICAgICAgICRjb25zdHJhaW50QnJhbmNoZXNbXSA9ICRyZXNbJ2JyYW5jaGVzJ107CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNvbnN0cmFpbnQtPmlzRGlzanVuY3RpdmUoKSkgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBJbnRlcnZhbDo6bm9EZXYoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnN0cmFpbnRCcmFuY2hlcyBhcyAkYikgewogICAgICAgICAgICAgICAgaWYgKCRiWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaGVzWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzanVuY3RpdmUgY29uc3RyYWludCwgc28gb25seSBleGNsdWRlIHdoYXQncyBleGNsdWRlZCBpbiBhbGwgY29uc3RyYWludHMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIT1hLCE9YiB8fCAhPWIsIT1jID0+ICE9YgogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV9pbnRlcnNlY3QoJGJyYW5jaGVzWyduYW1lcyddLCAkYlsnbmFtZXMnXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzanVuY3RpdmUgY29uc3RyYWludCBzbyBleGNsdWRlIGFsbCBuYW1lcyB3aGljaCBhcmUgbm90IGV4cGxpY2l0bHkgaW5jbHVkZWQgaW4gdGhlIGFsdGVybmF0aXZlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICg9PWIgfHwgPT1jKSB8fCAhPWEsIT1iID0+ICE9YQogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ2V4Y2x1ZGUnXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X2RpZmYoJGJbJ25hbWVzJ10sICRicmFuY2hlc1snbmFtZXMnXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaGVzWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzanVuY3RpdmUgY29uc3RyYWludCBzbyBleGNsdWRlIGFsbCBuYW1lcyB3aGljaCBhcmUgbm90IGV4cGxpY2l0bHkgaW5jbHVkZWQgaW4gdGhlIGFsdGVybmF0aXZlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICE9YSwhPWIgfHwgKD09YiB8fCA9PWMpID0+ICE9YQogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV9kaWZmKCRicmFuY2hlc1snbmFtZXMnXSwgJGJbJ25hbWVzJ10pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc2p1bmN0aXZlIGNvbnN0cmFpbnQsIHNvIGp1c3QgYWRkIGFsbCB0aGUgb3RoZXIgYnJhbmNoZXMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gKD09YSB8fCA9PWIpIHx8ID09YyA9PiA9PWEgfHwgPT1iIHx8ID09YwogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV9tZXJnZSgkYnJhbmNoZXNbJ25hbWVzJ10sICRiWyduYW1lcyddKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBJbnRlcnZhbDo6YW55RGV2KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25zdHJhaW50QnJhbmNoZXMgYXMgJGIpIHsKICAgICAgICAgICAgICAgIGlmICgkYlsnZXhjbHVkZSddKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRicmFuY2hlc1snZXhjbHVkZSddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmp1bmN0aXZlLCBzbyBqdXN0IGFkZCBhbGwgYnJhbmNoIG5hbWVzIHRvIGJlIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICE9YSAmJiAhPWIgPT4gIT1hLCE9YgogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV9tZXJnZSgkYnJhbmNoZXNbJ25hbWVzJ10sICRiWyduYW1lcyddKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25qdW5jdGl2ZSwgc28gb25seSBrZWVwIGluY2x1ZGVkIG5hbWVzIHdoaWNoIGFyZSBub3QgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gKD09YXx8PT1jKSAmJiAhPWEsIT1iID0+ID09YwogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV9kaWZmKCRicmFuY2hlc1snbmFtZXMnXSwgJGJbJ25hbWVzJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRicmFuY2hlc1snZXhjbHVkZSddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmp1bmN0aXZlLCBzbyBvbmx5IGtlZXAgaW5jbHVkZWQgbmFtZXMgd2hpY2ggYXJlIG5vdCBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgICAgICAvLyAhPWEsIT1iICYmICg9PWF8fD09YykgPT4gPT1jCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X2RpZmYoJGJbJ25hbWVzJ10sICRicmFuY2hlc1snbmFtZXMnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snZXhjbHVkZSddID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uanVuY3RpdmUsIHNvIG9ubHkga2VlcCBuYW1lcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiBib3RoCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICg9PWF8fD09YikgJiYgKD09YXx8PT1jKSA9PiA9PWEKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWyduYW1lcyddID0gYXJyYXlfaW50ZXJzZWN0KCRicmFuY2hlc1snbmFtZXMnXSwgJGJbJ25hbWVzJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGJyYW5jaGVzWyduYW1lcyddID0gYXJyYXlfdW5pcXVlKCRicmFuY2hlc1snbmFtZXMnXSk7CgogICAgICAgIGlmIChcY291bnQoJG51bWVyaWNHcm91cHMpID09PSAxKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgnbnVtZXJpYycgPT4gJG51bWVyaWNHcm91cHNbMF0sICdicmFuY2hlcycgPT4gJGJyYW5jaGVzKTsKICAgICAgICB9CgogICAgICAgICRib3JkZXJzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbnVtZXJpY0dyb3VwcyBhcyAkZ3JvdXApIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGdyb3VwIGFzICRpbnRlcnZhbCkgewogICAgICAgICAgICAgICAgJGJvcmRlcnNbXSA9IGFycmF5KCd2ZXJzaW9uJyA9PiAkaW50ZXJ2YWwtPmdldFN0YXJ0KCktPmdldFZlcnNpb24oKSwgJ29wZXJhdG9yJyA9PiAkaW50ZXJ2YWwtPmdldFN0YXJ0KCktPmdldE9wZXJhdG9yKCksICdzaWRlJyA9PiAnc3RhcnQnKTsKICAgICAgICAgICAgICAgICRib3JkZXJzW10gPSBhcnJheSgndmVyc2lvbicgPT4gJGludGVydmFsLT5nZXRFbmQoKS0+Z2V0VmVyc2lvbigpLCAnb3BlcmF0b3InID0+ICRpbnRlcnZhbC0+Z2V0RW5kKCktPmdldE9wZXJhdG9yKCksICdzaWRlJyA9PiAnZW5kJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRvcFNvcnRPcmRlciA9IHNlbGY6OiRvcFNvcnRPcmRlcjsKICAgICAgICB1c29ydCgkYm9yZGVycywgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkb3BTb3J0T3JkZXIpIHsKICAgICAgICAgICAgJG9yZGVyID0gdmVyc2lvbl9jb21wYXJlKCRhWyd2ZXJzaW9uJ10sICRiWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICBpZiAoJG9yZGVyID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG9wU29ydE9yZGVyWyRhWydvcGVyYXRvciddXSAtICRvcFNvcnRPcmRlclskYlsnb3BlcmF0b3InXV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkb3JkZXI7CiAgICAgICAgfSk7CgogICAgICAgICRhY3RpdmVJbnRlcnZhbHMgPSAwOwogICAgICAgICRpbnRlcnZhbHMgPSBhcnJheSgpOwogICAgICAgICRpbmRleCA9IDA7CiAgICAgICAgJGFjdGl2YXRpb25UaHJlc2hvbGQgPSAkY29uc3RyYWludC0+aXNDb25qdW5jdGl2ZSgpID8gXGNvdW50KCRudW1lcmljR3JvdXBzKSA6IDE7CiAgICAgICAgJHN0YXJ0ID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkYm9yZGVycyBhcyAkYm9yZGVyKSB7CiAgICAgICAgICAgIGlmICgkYm9yZGVyWydzaWRlJ10gPT09ICdzdGFydCcpIHsKICAgICAgICAgICAgICAgICRhY3RpdmVJbnRlcnZhbHMrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRhY3RpdmVJbnRlcnZhbHMtLTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRzdGFydCAmJiAkYWN0aXZlSW50ZXJ2YWxzID49ICRhY3RpdmF0aW9uVGhyZXNob2xkKSB7CiAgICAgICAgICAgICAgICAkc3RhcnQgPSBuZXcgQ29uc3RyYWludCgkYm9yZGVyWydvcGVyYXRvciddLCAkYm9yZGVyWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXJ0ICYmICRhY3RpdmVJbnRlcnZhbHMgPCAkYWN0aXZhdGlvblRocmVzaG9sZCkgewogICAgICAgICAgICAgICAgLy8gZmlsdGVyIG91dCBpbnZhbGlkIGludGVydmFscyBsaWtlID4geCAtIDw9IHgsIG9yID49IHggLSA8IHgKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uX2NvbXBhcmUoJHN0YXJ0LT5nZXRWZXJzaW9uKCksICRib3JkZXJbJ3ZlcnNpb24nXSwgJz0nKQogICAgICAgICAgICAgICAgICAgICYmICgKICAgICAgICAgICAgICAgICAgICAgICAgKCRzdGFydC0+Z2V0T3BlcmF0b3IoKSA9PT0gJz4nICYmICRib3JkZXJbJ29wZXJhdG9yJ10gPT09ICc8PScpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8ICgkc3RhcnQtPmdldE9wZXJhdG9yKCkgPT09ICc+PScgJiYgJGJvcmRlclsnb3BlcmF0b3InXSA9PT0gJzwnKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRpbnRlcnZhbHNbJGluZGV4XSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpbnRlcnZhbHNbJGluZGV4XSA9IG5ldyBJbnRlcnZhbCgkc3RhcnQsIG5ldyBDb25zdHJhaW50KCRib3JkZXJbJ29wZXJhdG9yJ10sICRib3JkZXJbJ3ZlcnNpb24nXSkpOwogICAgICAgICAgICAgICAgICAgICRpbmRleCsrOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJHN0b3BPbkZpcnN0VmFsaWRJbnRlcnZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHN0YXJ0ID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCdudW1lcmljJyA9PiAkaW50ZXJ2YWxzLCAnYnJhbmNoZXMnID0+ICRicmFuY2hlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi1yZXR1cm4gYXJyYXl7J251bWVyaWMnOiBJbnRlcnZhbFtdLCAnYnJhbmNoZXMnOiBhcnJheXsnbmFtZXMnOiBzdHJpbmdbXSwgJ2V4Y2x1ZGUnOiBib29sfX0KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVTaW5nbGVDb25zdHJhaW50SW50ZXJ2YWxzKENvbnN0cmFpbnQgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJG9wID0gJGNvbnN0cmFpbnQtPmdldE9wZXJhdG9yKCk7CgogICAgICAgIC8vIGhhbmRsZSBicmFuY2ggY29uc3RyYWludHMgZmlyc3QKICAgICAgICBpZiAoc3RycG9zKCRjb25zdHJhaW50LT5nZXRWZXJzaW9uKCksICdkZXYtJykgPT09IDApIHsKICAgICAgICAgICAgJGludGVydmFscyA9IGFycmF5KCk7CiAgICAgICAgICAgICRicmFuY2hlcyA9IGFycmF5KCduYW1lcycgPT4gYXJyYXkoKSwgJ2V4Y2x1ZGUnID0+IGZhbHNlKTsKCiAgICAgICAgICAgIC8vICE9IGRldi1mb28gbWVhbnMgYW55IG51bWVyaWMgdmVyc2lvbiBtYXkgbWF0Y2gsIHdlIHRyZWF0ID4vPCBsaWtlICE9IHRoZXkgYXJlIG5vdCByZWFsbHkgZGVmaW5lZCBmb3IgYnJhbmNoZXMKICAgICAgICAgICAgaWYgKCRvcCA9PT0gJyE9JykgewogICAgICAgICAgICAgICAgJGludGVydmFsc1tdID0gbmV3IEludGVydmFsKEludGVydmFsOjpmcm9tWmVybygpLCBJbnRlcnZhbDo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpOwogICAgICAgICAgICAgICAgJGJyYW5jaGVzID0gYXJyYXkoJ25hbWVzJyA9PiBhcnJheSgkY29uc3RyYWludC0+Z2V0VmVyc2lvbigpKSwgJ2V4Y2x1ZGUnID0+IHRydWUpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG9wID09PSAnPT0nKSB7CiAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ11bXSA9ICRjb25zdHJhaW50LT5nZXRWZXJzaW9uKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICdudW1lcmljJyA9PiAkaW50ZXJ2YWxzLAogICAgICAgICAgICAgICAgJ2JyYW5jaGVzJyA9PiAkYnJhbmNoZXMsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG9wWzBdID09PSAnPicpIHsgLy8gPiAmID49CiAgICAgICAgICAgIHJldHVybiBhcnJheSgnbnVtZXJpYycgPT4gYXJyYXkobmV3IEludGVydmFsKCRjb25zdHJhaW50LCBJbnRlcnZhbDo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpKSwgJ2JyYW5jaGVzJyA9PiBJbnRlcnZhbDo6bm9EZXYoKSk7CiAgICAgICAgfQogICAgICAgIGlmICgkb3BbMF0gPT09ICc8JykgeyAvLyA8ICYgPD0KICAgICAgICAgICAgcmV0dXJuIGFycmF5KCdudW1lcmljJyA9PiBhcnJheShuZXcgSW50ZXJ2YWwoSW50ZXJ2YWw6OmZyb21aZXJvKCksICRjb25zdHJhaW50KSksICdicmFuY2hlcycgPT4gSW50ZXJ2YWw6Om5vRGV2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAoJG9wID09PSAnIT0nKSB7CiAgICAgICAgICAgIC8vIGNvbnZlcnQgIT14IHRvIGludGVydmFscyBvZiAwIC0gPHggJiYgPnggLSAraW5mICsgZGV2KgogICAgICAgICAgICByZXR1cm4gYXJyYXkoJ251bWVyaWMnID0+IGFycmF5KAogICAgICAgICAgICAgICAgbmV3IEludGVydmFsKEludGVydmFsOjpmcm9tWmVybygpLCBuZXcgQ29uc3RyYWludCgnPCcsICRjb25zdHJhaW50LT5nZXRWZXJzaW9uKCkpKSwKICAgICAgICAgICAgICAgIG5ldyBJbnRlcnZhbChuZXcgQ29uc3RyYWludCgnPicsICRjb25zdHJhaW50LT5nZXRWZXJzaW9uKCkpLCBJbnRlcnZhbDo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpLAogICAgICAgICAgICApLCAnYnJhbmNoZXMnID0+IEludGVydmFsOjphbnlEZXYoKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBjb252ZXJ0ID09eCB0byBhbiBpbnRlcnZhbCBvZiA+PXggLSA8PXgKICAgICAgICByZXR1cm4gYXJyYXkoJ251bWVyaWMnID0+IGFycmF5KAogICAgICAgICAgICBuZXcgSW50ZXJ2YWwobmV3IENvbnN0cmFpbnQoJz49JywgJGNvbnN0cmFpbnQtPmdldFZlcnNpb24oKSksIG5ldyBDb25zdHJhaW50KCc8PScsICRjb25zdHJhaW50LT5nZXRWZXJzaW9uKCkpKSwKICAgICAgICApLCAnYnJhbmNoZXMnID0+IEludGVydmFsOjpub0RldigpKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlcjsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKY2xhc3MgQ29tcGFyYXRvcgp7CiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xID4gJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdyZWF0ZXJUaGFuKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJz4nLCAkdmVyc2lvbjIpOwogICAgfQoKICAgIC8qKgogICAgICogRXZhbHVhdGVzIHRoZSBleHByZXNzaW9uOiAkdmVyc2lvbjEgPj0gJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdyZWF0ZXJUaGFuT3JFcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJz49JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xIDwgJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxlc3NUaGFuKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJzwnLCAkdmVyc2lvbjIpOwogICAgfQoKICAgIC8qKgogICAgICogRXZhbHVhdGVzIHRoZSBleHByZXNzaW9uOiAkdmVyc2lvbjEgPD0gJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxlc3NUaGFuT3JFcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJzw9JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xID09ICR2ZXJzaW9uMi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMQogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbjIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJz09JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xICE9ICR2ZXJzaW9uMi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMQogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbjIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBub3RFcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJyE9JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xICRvcGVyYXRvciAkdmVyc2lvbjIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbjEKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBwaHBzdGFuLXBhcmFtIENvbnN0cmFpbnQ6OlNUUl9PUF8qICAkb3BlcmF0b3IKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb21wYXJlKCR2ZXJzaW9uMSwgJG9wZXJhdG9yLCAkdmVyc2lvbjIpCiAgICB7CiAgICAgICAgJGNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgkb3BlcmF0b3IsICR2ZXJzaW9uMik7CgogICAgICAgIHJldHVybiAkY29uc3RyYWludC0+bWF0Y2hTcGVjaWZpYyhuZXcgQ29uc3RyYWludCgnPT0nLCAkdmVyc2lvbjEpLCB0cnVlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlcjsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludEludGVyZmFjZTsKCi8qKgogKiBIZWxwZXIgY2xhc3MgdG8gZXZhbHVhdGUgY29uc3RyYWludCBieSBjb21waWxpbmcgYW5kIHJldXNpbmcgdGhlIGNvZGUgdG8gZXZhbHVhdGUKICovCmNsYXNzIENvbXBpbGluZ01hdGNoZXIKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBjYWxsYWJsZT4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGNvbXBpbGVkQ2hlY2tlckNhY2hlID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgc3RhdGljICRlbmFibGVkOwoKICAgIC8qKgogICAgICogQHBocHN0YW4tdmFyIGFycmF5PENvbnN0cmFpbnQ6Ok9QXyosIENvbnN0cmFpbnQ6OlNUUl9PUF8qPgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkdHJhbnNPcEludCA9IGFycmF5KAogICAgICAgIENvbnN0cmFpbnQ6Ok9QX0VRID0+IENvbnN0cmFpbnQ6OlNUUl9PUF9FUSwKICAgICAgICBDb25zdHJhaW50OjpPUF9MVCA9PiBDb25zdHJhaW50OjpTVFJfT1BfTFQsCiAgICAgICAgQ29uc3RyYWludDo6T1BfTEUgPT4gQ29uc3RyYWludDo6U1RSX09QX0xFLAogICAgICAgIENvbnN0cmFpbnQ6Ok9QX0dUID0+IENvbnN0cmFpbnQ6OlNUUl9PUF9HVCwKICAgICAgICBDb25zdHJhaW50OjpPUF9HRSA9PiBDb25zdHJhaW50OjpTVFJfT1BfR0UsCiAgICAgICAgQ29uc3RyYWludDo6T1BfTkUgPT4gQ29uc3RyYWludDo6U1RSX09QX05FLAogICAgKTsKCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJGNvbnN0cmFpbnQgbWF0Y2ggJG9wZXJhdG9yICR2ZXJzaW9uCiAgICAgKgogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICRvcGVyYXRvcgogICAgICogQHBocHN0YW4tcGFyYW0gQ29uc3RyYWludDo6T1BfKiAgJG9wZXJhdG9yCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAkdmVyc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYXRjaChDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50LCAkb3BlcmF0b3IsICR2ZXJzaW9uKQogICAgewogICAgICAgIGlmIChzZWxmOjokZW5hYmxlZCA9PT0gbnVsbCkgewogICAgICAgICAgICBzZWxmOjokZW5hYmxlZCA9ICFcaW5fYXJyYXkoJ2V2YWwnLCBleHBsb2RlKCcsJywgKHN0cmluZykgaW5pX2dldCgnZGlzYWJsZV9mdW5jdGlvbnMnKSksIHRydWUpOwogICAgICAgIH0KICAgICAgICBpZiAoIXNlbGY6OiRlbmFibGVkKSB7CiAgICAgICAgICAgIHJldHVybiAkY29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludChzZWxmOjokdHJhbnNPcEludFskb3BlcmF0b3JdLCAkdmVyc2lvbikpOwogICAgICAgIH0KCiAgICAgICAgJGNhY2hlS2V5ID0gJG9wZXJhdG9yLiRjb25zdHJhaW50OwogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGNvbXBpbGVkQ2hlY2tlckNhY2hlWyRjYWNoZUtleV0pKSB7CiAgICAgICAgICAgICRjb2RlID0gJGNvbnN0cmFpbnQtPmNvbXBpbGUoJG9wZXJhdG9yKTsKICAgICAgICAgICAgc2VsZjo6JGNvbXBpbGVkQ2hlY2tlckNhY2hlWyRjYWNoZUtleV0gPSAkZnVuY3Rpb24gPSBldmFsKCdyZXR1cm4gZnVuY3Rpb24oJHYsICRiKXtyZXR1cm4gJy4kY29kZS4nO307Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGZ1bmN0aW9uID0gc2VsZjo6JGNvbXBpbGVkQ2hlY2tlckNhY2hlWyRjYWNoZUtleV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZ1bmN0aW9uKCR2ZXJzaW9uLCBzdHJwb3MoJHZlcnNpb24sICdkZXYtJykgPT09IDApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CgpjbGFzcyBTZW12ZXIKewogICAgY29uc3QgU09SVF9BU0MgPSAxOwogICAgY29uc3QgU09SVF9ERVNDID0gLTE7CgogICAgLyoqIEB2YXIgVmVyc2lvblBhcnNlciAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHZlcnNpb25QYXJzZXI7CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgaWYgZ2l2ZW4gdmVyc2lvbiBzYXRpc2ZpZXMgZ2l2ZW4gY29uc3RyYWludHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbgogICAgICogQHBhcmFtIHN0cmluZyAkY29uc3RyYWludHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYXRpc2ZpZXMoJHZlcnNpb24sICRjb25zdHJhaW50cykKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gc2VsZjo6JHZlcnNpb25QYXJzZXIpIHsKICAgICAgICAgICAgc2VsZjo6JHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBzZWxmOjokdmVyc2lvblBhcnNlcjsKICAgICAgICAkcHJvdmlkZXIgPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkdmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCR2ZXJzaW9uKSk7CiAgICAgICAgJHBhcnNlZENvbnN0cmFpbnRzID0gJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnRzKTsKCiAgICAgICAgcmV0dXJuICRwYXJzZWRDb25zdHJhaW50cy0+bWF0Y2hlcygkcHJvdmlkZXIpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGFsbCB2ZXJzaW9ucyB0aGF0IHNhdGlzZnkgZ2l2ZW4gY29uc3RyYWludHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICR2ZXJzaW9ucwogICAgICogQHBhcmFtIHN0cmluZyAgICRjb25zdHJhaW50cwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYXRpc2ZpZWRCeShhcnJheSAkdmVyc2lvbnMsICRjb25zdHJhaW50cykKICAgIHsKICAgICAgICAkdmVyc2lvbnMgPSBhcnJheV9maWx0ZXIoJHZlcnNpb25zLCBmdW5jdGlvbiAoJHZlcnNpb24pIHVzZSAoJGNvbnN0cmFpbnRzKSB7CiAgICAgICAgICAgIHJldHVybiBTZW12ZXI6OnNhdGlzZmllcygkdmVyc2lvbiwgJGNvbnN0cmFpbnRzKTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIGFycmF5X3ZhbHVlcygkdmVyc2lvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogU29ydCBnaXZlbiBhcnJheSBvZiB2ZXJzaW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHZlcnNpb25zCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNvcnQoYXJyYXkgJHZlcnNpb25zKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjp1c29ydCgkdmVyc2lvbnMsIHNlbGY6OlNPUlRfQVNDKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNvcnQgZ2l2ZW4gYXJyYXkgb2YgdmVyc2lvbnMgaW4gcmV2ZXJzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJHZlcnNpb25zCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJzb3J0KGFycmF5ICR2ZXJzaW9ucykKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6dXNvcnQoJHZlcnNpb25zLCBzZWxmOjpTT1JUX0RFU0MpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICR2ZXJzaW9ucwogICAgICogQHBhcmFtIGludCAgICAgICRkaXJlY3Rpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHVzb3J0KGFycmF5ICR2ZXJzaW9ucywgJGRpcmVjdGlvbikKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gc2VsZjo6JHZlcnNpb25QYXJzZXIpIHsKICAgICAgICAgICAgc2VsZjo6JHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBzZWxmOjokdmVyc2lvblBhcnNlcjsKICAgICAgICAkbm9ybWFsaXplZCA9IGFycmF5KCk7CgogICAgICAgIC8vIE5vcm1hbGl6ZSBvdXRzaWRlIG9mIHVzb3J0KCkgc2NvcGUgZm9yIG1pbm9yIHBlcmZvcm1hbmNlIGluY3JlYXNlLgogICAgICAgIC8vIENyZWF0ZXMgYW4gYXJyYXkgb2YgYXJyYXlzOiBbW25vcm1hbGl6ZWQsIGtleV0sIC4uLl0KICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJGtleSA9PiAkdmVyc2lvbikgewogICAgICAgICAgICAkbm9ybWFsaXplZFZlcnNpb24gPSAkdmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCR2ZXJzaW9uKTsKICAgICAgICAgICAgJG5vcm1hbGl6ZWRWZXJzaW9uID0gJHZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZURlZmF1bHRCcmFuY2goJG5vcm1hbGl6ZWRWZXJzaW9uKTsKICAgICAgICAgICAgJG5vcm1hbGl6ZWRbXSA9IGFycmF5KCRub3JtYWxpemVkVmVyc2lvbiwgJGtleSk7CiAgICAgICAgfQoKICAgICAgICB1c29ydCgkbm9ybWFsaXplZCwgZnVuY3Rpb24gKGFycmF5ICRsZWZ0LCBhcnJheSAkcmlnaHQpIHVzZSAoJGRpcmVjdGlvbikgewogICAgICAgICAgICBpZiAoJGxlZnRbMF0gPT09ICRyaWdodFswXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb21wYXJhdG9yOjpsZXNzVGhhbigkbGVmdFswXSwgJHJpZ2h0WzBdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0kZGlyZWN0aW9uOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGRpcmVjdGlvbjsKICAgICAgICB9KTsKCiAgICAgICAgLy8gUmVjcmVhdGUgaW5wdXQgYXJyYXksIHVzaW5nIHRoZSBvcmlnaW5hbCBpbmRleGVzIHdoaWNoIGFyZSBub3cgaW4gc29ydGVkIG9yZGVyLgogICAgICAgICRzb3J0ZWQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRub3JtYWxpemVkIGFzICRpdGVtKSB7CiAgICAgICAgICAgICRzb3J0ZWRbXSA9ICR2ZXJzaW9uc1skaXRlbVsxXV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNvcnRlZDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllcjsKCmNsYXNzIE1ldGFkYXRhTWluaWZpZXIKewogICAgLyoqCiAgICAgKiBFeHBhbmRzIGFuIGFycmF5IG9mIG1pbmlmaWVkIHZlcnNpb25zIGJhY2sgdG8gdGhlaXIgb3JpZ2luYWwgZm9ybWF0CiAgICAgKgogICAgICogQHBhcmFtIGFycmF5W10gJHZlcnNpb25zIEEgbGlzdCBvZiBtaW5pZmllZCB2ZXJzaW9uIGFycmF5cwogICAgICogQHJldHVybiBhcnJheVtdIEEgbGlzdCBvZiB2ZXJzaW9uIGFycmF5cwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4cGFuZChhcnJheSAkdmVyc2lvbnMpCiAgICB7CiAgICAgICAgJGV4cGFuZGVkID0gYXJyYXkoKTsKICAgICAgICAkZXhwYW5kZWRWZXJzaW9uID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb25EYXRhKSB7CiAgICAgICAgICAgIGlmICghJGV4cGFuZGVkVmVyc2lvbikgewogICAgICAgICAgICAgICAgJGV4cGFuZGVkVmVyc2lvbiA9ICR2ZXJzaW9uRGF0YTsKICAgICAgICAgICAgICAgICRleHBhbmRlZFtdID0gJGV4cGFuZGVkVmVyc2lvbjsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBhZGQgYW55IGNoYW5nZXMgZnJvbSB0aGUgcHJldmlvdXMgdmVyc2lvbiB0byB0aGUgZXhwYW5kZWQgb25lCiAgICAgICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9uRGF0YSBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgIGlmICgkdmFsID09PSAnX191bnNldCcpIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkZXhwYW5kZWRWZXJzaW9uWyRrZXldKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGV4cGFuZGVkVmVyc2lvblska2V5XSA9ICR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRleHBhbmRlZFtdID0gJGV4cGFuZGVkVmVyc2lvbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZXhwYW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBNaW5pZmllcyBhbiBhcnJheSBvZiB2ZXJzaW9ucyBpbnRvIGEgc2V0IG9mIHZlcnNpb24gZGlmZnMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXlbXSAkdmVyc2lvbnMgQSBsaXN0IG9mIHZlcnNpb24gYXJyYXlzCiAgICAgKiBAcmV0dXJuIGFycmF5W10gQSBsaXN0IG9mIHZlcnNpb25zIG1pbmlmaWVkIHdpdGggZWFjaCBhcnJheSBvbmx5IGNvbnRhaW5pbmcgdGhlIGRpZmZlcmVuY2VzIHRvIHRoZSBwcmV2aW91cyBvbmUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtaW5pZnkoYXJyYXkgJHZlcnNpb25zKQogICAgewogICAgICAgICRtaW5pZmllZFZlcnNpb25zID0gYXJyYXkoKTsKCiAgICAgICAgJGxhc3RLbm93blZlcnNpb25EYXRhID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24pIHsKICAgICAgICAgICAgaWYgKCEkbGFzdEtub3duVmVyc2lvbkRhdGEpIHsKICAgICAgICAgICAgICAgICRsYXN0S25vd25WZXJzaW9uRGF0YSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgJG1pbmlmaWVkVmVyc2lvbnNbXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtaW5pZmllZFZlcnNpb24gPSBhcnJheSgpOwoKICAgICAgICAgICAgLy8gYWRkIGFueSBjaGFuZ2VzIGZyb20gdGhlIHByZXZpb3VzIHZlcnNpb24KICAgICAgICAgICAgZm9yZWFjaCAoJHZlcnNpb24gYXMgJGtleSA9PiAkdmFsKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRsYXN0S25vd25WZXJzaW9uRGF0YVska2V5XSkgfHwgJGxhc3RLbm93blZlcnNpb25EYXRhWyRrZXldICE9PSAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgJG1pbmlmaWVkVmVyc2lvblska2V5XSA9ICR2YWw7CiAgICAgICAgICAgICAgICAgICAgJGxhc3RLbm93blZlcnNpb25EYXRhWyRrZXldID0gJHZhbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3RvcmUgYW55IGRlbGV0aW9ucyBmcm9tIHRoZSBwcmV2aW91cyB2ZXJzaW9uIGZvciBrZXlzIG1pc3NpbmcgaW4gY3VycmVudCBvbmUKICAgICAgICAgICAgZm9yZWFjaCAoJGxhc3RLbm93blZlcnNpb25EYXRhIGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvblska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkbWluaWZpZWRWZXJzaW9uWyRrZXldID0gIl9fdW5zZXQiOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRsYXN0S25vd25WZXJzaW9uRGF0YVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtaW5pZmllZFZlcnNpb25zW10gPSAkbWluaWZpZWRWZXJzaW9uOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtaW5pZmllZFZlcnNpb25zOwogICAgfQp9Cjw/cGhwCgovLyBhdXRvbG9hZF9wc3I0LnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokdmVuZG9yRGlyID0gZGlybmFtZShkaXJuYW1lKF9fRklMRV9fKSk7CiRiYXNlRGlyID0gZGlybmFtZSgkdmVuZG9yRGlyKTsKCnJldHVybiBhcnJheSgKICAgICdXUF9DTElcXE1haW50ZW5hbmNlTW9kZVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy93cC1jbGkvbWFpbnRlbmFuY2UtbW9kZS1jb21tYW5kL3NyYycpLAogICAgJ1dQX0NMSVxcSTE4blxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy93cC1jbGkvaTE4bi1jb21tYW5kL3NyYycpLAogICAgJ1dQX0NMSVxcRW1iZWRzXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9lbWJlZC1jb21tYW5kL3NyYycpLAogICAgJ1dQX0NMSVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSScsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zaGVsbC1jb21tYW5kL3NyYy9XUF9DTEknKSwKICAgICdTeW1mb255XFxQb2x5ZmlsbFxcTWJzdHJpbmdcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZycpLAogICAgJ1N5bWZvbnlcXFBvbHlmaWxsXFxDdHlwZVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9zeW1mb255L3BvbHlmaWxsLWN0eXBlJyksCiAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxQcm9jZXNzXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3N5bWZvbnkvcHJvY2VzcycpLAogICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcRmluZGVyXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3N5bWZvbnkvZmluZGVyJyksCiAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxGaWxlc3lzdGVtXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3N5bWZvbnkvZmlsZXN5c3RlbScpLAogICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcQ29uc29sZVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9zeW1mb255L2NvbnNvbGUnKSwKICAgICdTZWxkXFxQaGFyVXRpbHNcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvc2VsZC9waGFyLXV0aWxzL3NyYycpLAogICAgJ1NlbGRcXEpzb25MaW50XFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3NlbGQvanNvbmxpbnQvc3JjL1NlbGQvSnNvbkxpbnQnKSwKICAgICdSZWFjdFxcUHJvbWlzZVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9yZWFjdC9wcm9taXNlL3NyYycpLAogICAgJ1BzclxcTG9nXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3Bzci9sb2cvUHNyL0xvZycpLAogICAgJ1BlYXN0XFx0ZXN0XFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL21jazg5L3BlYXN0L3Rlc3QvUGVhc3QnKSwKICAgICdQZWFzdFxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9tY2s4OS9wZWFzdC9saWIvUGVhc3QnKSwKICAgICdNdXN0YW5nb3N0YW5nXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMvc3JjJyksCiAgICAnSnNvblNjaGVtYVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hJyksCiAgICAnR2V0dGV4dFxcTGFuZ3VhZ2VzXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL2dldHRleHQvbGFuZ3VhZ2VzL3NyYycpLAogICAgJ0dldHRleHRcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvZ2V0dGV4dC9nZXR0ZXh0L3NyYycpLAogICAgJ0NvbXBvc2VyXFxYZGVidWdIYW5kbGVyXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL3hkZWJ1Zy1oYW5kbGVyL3NyYycpLAogICAgJ0NvbXBvc2VyXFxTZW12ZXJcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvY29tcG9zZXIvc2VtdmVyL3NyYycpLAogICAgJ0NvbXBvc2VyXFxQY3JlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL3BjcmUvc3JjJyksCiAgICAnQ29tcG9zZXJcXE1ldGFkYXRhTWluaWZpZXJcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIvc3JjJyksCiAgICAnQ29tcG9zZXJcXENhQnVuZGxlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL2NhLWJ1bmRsZS9zcmMnKSwKICAgICdDb21wb3NlclxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXInKSwKICAgICcnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jYWNoZS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jb25maWctY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvY29yZS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jcm9uLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2RiLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2V2YWwtY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvaW1wb3J0LWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL21lZGlhLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3BhY2thZ2UtY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvcmV3cml0ZS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9yb2xlLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3NlcnZlci1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zaGVsbC1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS93aWRnZXQtY29tbWFuZC9zcmMnKSwKKTsKPD9waHAKCi8vIHBsYXRmb3JtX2NoZWNrLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokaXNzdWVzID0gYXJyYXkoKTsKCmlmICghKFBIUF9WRVJTSU9OX0lEID49IDUwNjAwKSkgewogICAgJGlzc3Vlc1tdID0gJ1lvdXIgQ29tcG9zZXIgZGVwZW5kZW5jaWVzIHJlcXVpcmUgYSBQSFAgdmVyc2lvbiAiPj0gNS42LjAiLiBZb3UgYXJlIHJ1bm5pbmcgJyAuIFBIUF9WRVJTSU9OIC4gJy4nOwp9CgppZiAoJGlzc3VlcykgewogICAgaWYgKCFoZWFkZXJzX3NlbnQoKSkgewogICAgICAgIGhlYWRlcignSFRUUC8xLjEgNTAwIEludGVybmFsIFNlcnZlciBFcnJvcicpOwogICAgfQogICAgaWYgKCFpbmlfZ2V0KCdkaXNwbGF5X2Vycm9ycycpKSB7CiAgICAgICAgaWYgKFBIUF9TQVBJID09PSAnY2xpJyB8fCBQSFBfU0FQSSA9PT0gJ3BocGRiZycpIHsKICAgICAgICAgICAgZndyaXRlKFNUREVSUiwgJ0NvbXBvc2VyIGRldGVjdGVkIGlzc3VlcyBpbiB5b3VyIHBsYXRmb3JtOicgLiBQSFBfRU9MLlBIUF9FT0wgLiBpbXBsb2RlKFBIUF9FT0wsICRpc3N1ZXMpIC4gUEhQX0VPTC5QSFBfRU9MKTsKICAgICAgICB9IGVsc2VpZiAoIWhlYWRlcnNfc2VudCgpKSB7CiAgICAgICAgICAgIGVjaG8gJ0NvbXBvc2VyIGRldGVjdGVkIGlzc3VlcyBpbiB5b3VyIHBsYXRmb3JtOicgLiBQSFBfRU9MLlBIUF9FT0wgLiBzdHJfcmVwbGFjZSgnWW91IGFyZSBydW5uaW5nICcuUEhQX1ZFUlNJT04uJy4nLCAnJywgaW1wbG9kZShQSFBfRU9MLCAkaXNzdWVzKSkgLiBQSFBfRU9MLlBIUF9FT0w7CiAgICAgICAgfQogICAgfQogICAgdHJpZ2dlcl9lcnJvcigKICAgICAgICAnQ29tcG9zZXIgZGV0ZWN0ZWQgaXNzdWVzIGluIHlvdXIgcGxhdGZvcm06ICcgLiBpbXBsb2RlKCcgJywgJGlzc3VlcyksCiAgICAgICAgRV9VU0VSX0VSUk9SCiAgICApOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxQb2x5ZmlsbFxDdHlwZTsKCi8qKgogKiBDdHlwZSBpbXBsZW1lbnRhdGlvbiB0aHJvdWdoIHJlZ2V4LgogKgogKiBAaW50ZXJuYWwKICoKICogQGF1dGhvciBHZXJ0IGRlIFBhZ3RlciA8QmFja0VuZFRlYUBnbWFpbC5jb20+CiAqLwpmaW5hbCBjbGFzcyBDdHlwZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBpcyBlaXRoZXIgYSBsZXR0ZXIgb3IgYSBkaWdpdCwgRkFMU0Ugb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEBzZWUgaHR0cHM6Ly9waHAubmV0L2N0eXBlLWFsbnVtCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjdHlwZV9hbG51bSgkdGV4dCkKICAgIHsKICAgICAgICAkdGV4dCA9IHNlbGY6OmNvbnZlcnRfaW50X3RvX2NoYXJfZm9yX2N0eXBlKCR0ZXh0KTsKCiAgICAgICAgcmV0dXJuIFxpc19zdHJpbmcoJHRleHQpICYmICcnICE9PSAkdGV4dCAmJiAhcHJlZ19tYXRjaCgnL1teQS1aYS16MC05XS8nLCAkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRleHQgaXMgYSBsZXR0ZXIsIEZBTFNFIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1hbHBoYQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfYWxwaGEoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXkEtWmEtel0vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBUUlVFIGlmIGV2ZXJ5IGNoYXJhY3RlciBpbiB0ZXh0IGlzIGEgY29udHJvbCBjaGFyYWN0ZXIgZnJvbSB0aGUgY3VycmVudCBsb2NhbGUsIEZBTFNFIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1jbnRybAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfY250cmwoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXlx4MDAtXHgxZlx4N2ZdLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyB0ZXh0IGlzIGEgZGVjaW1hbCBkaWdpdCwgRkFMU0Ugb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEBzZWUgaHR0cHM6Ly9waHAubmV0L2N0eXBlLWRpZ2l0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjdHlwZV9kaWdpdCgkdGV4dCkKICAgIHsKICAgICAgICAkdGV4dCA9IHNlbGY6OmNvbnZlcnRfaW50X3RvX2NoYXJfZm9yX2N0eXBlKCR0ZXh0KTsKCiAgICAgICAgcmV0dXJuIFxpc19zdHJpbmcoJHRleHQpICYmICcnICE9PSAkdGV4dCAmJiAhcHJlZ19tYXRjaCgnL1teMC05XS8nLCAkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRleHQgaXMgcHJpbnRhYmxlIGFuZCBhY3R1YWxseSBjcmVhdGVzIHZpc2libGUgb3V0cHV0IChubyB3aGl0ZSBzcGFjZSksIEZBTFNFIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1ncmFwaAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfZ3JhcGgoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXiEtfl0vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBUUlVFIGlmIGV2ZXJ5IGNoYXJhY3RlciBpbiB0ZXh0IGlzIGEgbG93ZXJjYXNlIGxldHRlci4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1sb3dlcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfbG93ZXIoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXmEtel0vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBUUlVFIGlmIGV2ZXJ5IGNoYXJhY3RlciBpbiB0ZXh0IHdpbGwgYWN0dWFsbHkgY3JlYXRlIG91dHB1dCAoaW5jbHVkaW5nIGJsYW5rcykuIFJldHVybnMgRkFMU0UgaWYgdGV4dCBjb250YWlucyBjb250cm9sIGNoYXJhY3RlcnMgb3IgY2hhcmFjdGVycyB0aGF0IGRvIG5vdCBoYXZlIGFueSBvdXRwdXQgb3IgY29udHJvbCBmdW5jdGlvbiBhdCBhbGwuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtcHJpbnQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX3ByaW50KCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW14gLX5dLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBpcyBwcmludGFibGUsIGJ1dCBuZWl0aGVyIGxldHRlciwgZGlnaXQgb3IgYmxhbmssIEZBTFNFIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1wdW5jdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfcHVuY3QoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXiEtXC9cOi1AXFstYFx7LX5dLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBjcmVhdGVzIHNvbWUgc29ydCBvZiB3aGl0ZSBzcGFjZSwgRkFMU0Ugb3RoZXJ3aXNlLiBCZXNpZGVzIHRoZSBibGFuayBjaGFyYWN0ZXIgdGhpcyBhbHNvIGluY2x1ZGVzIHRhYiwgdmVydGljYWwgdGFiLCBsaW5lIGZlZWQsIGNhcnJpYWdlIHJldHVybiBhbmQgZm9ybSBmZWVkIGNoYXJhY3RlcnMuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtc3BhY2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX3NwYWNlKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW15cc10vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBUUlVFIGlmIGV2ZXJ5IGNoYXJhY3RlciBpbiB0ZXh0IGlzIGFuIHVwcGVyY2FzZSBsZXR0ZXIuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtdXBwZXIKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX3VwcGVyKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW15BLVpdLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBpcyBhIGhleGFkZWNpbWFsICdkaWdpdCcsIHRoYXQgaXMgYSBkZWNpbWFsIGRpZ2l0IG9yIGEgY2hhcmFjdGVyIGZyb20gW0EtRmEtZl0gLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUteGRpZ2l0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjdHlwZV94ZGlnaXQoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXkEtRmEtZjAtOV0vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydHMgaW50ZWdlcnMgdG8gdGhlaXIgY2hhciB2ZXJzaW9ucyBhY2NvcmRpbmcgdG8gbm9ybWFsIGN0eXBlIGJlaGF2aW91ciwgaWYgbmVlZGVkLgogICAgICoKICAgICAqIElmIGFuIGludGVnZXIgYmV0d2VlbiAtMTI4IGFuZCAyNTUgaW5jbHVzaXZlIGlzIHByb3ZpZGVkLAogICAgICogaXQgaXMgaW50ZXJwcmV0ZWQgYXMgdGhlIEFTQ0lJIHZhbHVlIG9mIGEgc2luZ2xlIGNoYXJhY3RlcgogICAgICogKG5lZ2F0aXZlIHZhbHVlcyBoYXZlIDI1NiBhZGRlZCBpbiBvcmRlciB0byBhbGxvdyBjaGFyYWN0ZXJzIGluIHRoZSBFeHRlbmRlZCBBU0NJSSByYW5nZSkuCiAgICAgKiBBbnkgb3RoZXIgaW50ZWdlciBpcyBpbnRlcnByZXRlZCBhcyBhIHN0cmluZyBjb250YWluaW5nIHRoZSBkZWNpbWFsIGRpZ2l0cyBvZiB0aGUgaW50ZWdlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkaW50CiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkaW50KQogICAgewogICAgICAgIGlmICghXGlzX2ludCgkaW50KSkgewogICAgICAgICAgICByZXR1cm4gJGludDsKICAgICAgICB9CgogICAgICAgIGlmICgkaW50IDwgLTEyOCB8fCAkaW50ID4gMjU1KSB7CiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSAkaW50OwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnQgPCAwKSB7CiAgICAgICAgICAgICRpbnQgKz0gMjU2OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxjaHIoJGludCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCnVzZSBTeW1mb255XFBvbHlmaWxsXEN0eXBlIGFzIHA7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfYWxudW0nKSkgewogICAgZnVuY3Rpb24gY3R5cGVfYWxudW0oJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV9hbG51bSgkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX2FscGhhJykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX2FscGhhKCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfYWxwaGEoJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV9jbnRybCcpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV9jbnRybCgkaW5wdXQpIHsgcmV0dXJuIHBcQ3R5cGU6OmN0eXBlX2NudHJsKCRpbnB1dCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfZGlnaXQnKSkgewogICAgZnVuY3Rpb24gY3R5cGVfZGlnaXQoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV9kaWdpdCgkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX2dyYXBoJykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX2dyYXBoKCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfZ3JhcGgoJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV9sb3dlcicpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV9sb3dlcigkaW5wdXQpIHsgcmV0dXJuIHBcQ3R5cGU6OmN0eXBlX2xvd2VyKCRpbnB1dCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfcHJpbnQnKSkgewogICAgZnVuY3Rpb24gY3R5cGVfcHJpbnQoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV9wcmludCgkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX3B1bmN0JykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX3B1bmN0KCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfcHVuY3QoJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV9zcGFjZScpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV9zcGFjZSgkaW5wdXQpIHsgcmV0dXJuIHBcQ3R5cGU6OmN0eXBlX3NwYWNlKCRpbnB1dCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfdXBwZXInKSkgewogICAgZnVuY3Rpb24gY3R5cGVfdXBwZXIoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV91cHBlcigkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX3hkaWdpdCcpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV94ZGlnaXQoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV94ZGlnaXQoJGlucHV0KTsgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbTsKCnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvblxJT0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcRmxvY2tTdG9yZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcU2VtYXBob3JlU3RvcmU7CgpAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMgY2xhc3MgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuNCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gVXNlICVzIG9yICVzIGluc3RlYWQuJywgTG9ja0hhbmRsZXI6OmNsYXNzLCBTZW1hcGhvcmVTdG9yZTo6Y2xhc3MsIEZsb2NrU3RvcmU6OmNsYXNzKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCi8qKgogKiBMb2NrSGFuZGxlciBjbGFzcyBwcm92aWRlcyBhIHNpbXBsZSBhYnN0cmFjdGlvbiB0byBsb2NrIGFueXRoaW5nIGJ5IG1lYW5zIG9mCiAqIGEgZmlsZSBsb2NrLgogKgogKiBBIGxvY2tlZCBmaWxlIGlzIGNyZWF0ZWQgYmFzZWQgb24gdGhlIGxvY2sgbmFtZSB3aGVuIGNhbGxpbmcgbG9jaygpLiBPdGhlcgogKiBsb2NrIGhhbmRsZXJzIHdpbGwgbm90IGJlIGFibGUgdG8gbG9jayB0aGUgc2FtZSBuYW1lIHVudGlsIGl0IGlzIHJlbGVhc2VkCiAqIChleHBsaWNpdGx5IGJ5IGNhbGxpbmcgcmVsZWFzZSgpIG9yIGltcGxpY2l0bHkgd2hlbiB0aGUgaW5zdGFuY2UgaG9sZGluZyB0aGUKICogbG9jayBpcyBkZXN0cm95ZWQpLgogKgogKiBAYXV0aG9yIEdyw6lnb2lyZSBQaW5lYXUgPGx5cml4eEBseXJpeHguaW5mbz4KICogQGF1dGhvciBSb21haW4gTmV1dHJvbiA8aW1wcmVjQGdtYWlsLmNvbT4KICogQGF1dGhvciBOaWNvbGFzIEdyZWthcyA8cEB0Y2h3b3JrLmNvbT4KICoKICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjQsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgU3ltZm9ueVxDb21wb25lbnRcTG9ja1xTdG9yZVxTZW1hcGhvcmVTdG9yZSBvciBTeW1mb255XENvbXBvbmVudFxMb2NrXFN0b3JlXEZsb2NrU3RvcmUgaW5zdGVhZC4KICovCmNsYXNzIExvY2tIYW5kbGVyCnsKICAgIHByaXZhdGUgJGZpbGU7CiAgICBwcml2YXRlICRoYW5kbGU7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJG5hbWUgICAgIFRoZSBsb2NrIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkbG9ja1BhdGggVGhlIGRpcmVjdG9yeSB0byBzdG9yZSB0aGUgbG9jay4gRGVmYXVsdCB2YWx1ZXMgd2lsbCB1c2UgdGVtcG9yYXJ5IGRpcmVjdG9yeQogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgdGhlIGxvY2sgZGlyZWN0b3J5IGNvdWxkIG5vdCBiZSBjcmVhdGVkIG9yIGlzIG5vdCB3cml0YWJsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsICRsb2NrUGF0aCA9IG51bGwpCiAgICB7CiAgICAgICAgJGxvY2tQYXRoID0gJGxvY2tQYXRoID86IHN5c19nZXRfdGVtcF9kaXIoKTsKCiAgICAgICAgaWYgKCFpc19kaXIoJGxvY2tQYXRoKSkgewogICAgICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICAgICAkZnMtPm1rZGlyKCRsb2NrUGF0aCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCRsb2NrUGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ1RoZSBkaXJlY3RvcnkgIiVzIiBpcyBub3Qgd3JpdGFibGUuJywgJGxvY2tQYXRoKSwgMCwgbnVsbCwgJGxvY2tQYXRoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maWxlID0gc3ByaW50ZignJXMvc2YuJXMuJXMubG9jaycsICRsb2NrUGF0aCwgcHJlZ19yZXBsYWNlKCcvW15hLXowLTlcLl8tXSsvaScsICctJywgJG5hbWUpLCBoYXNoKCdzaGEyNTYnLCAkbmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogTG9jayB0aGUgcmVzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGJsb2NraW5nIFdhaXQgdW50aWwgdGhlIGxvY2sgaXMgcmVsZWFzZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgUmV0dXJucyB0cnVlIGlmIHRoZSBsb2NrIHdhcyBhY3F1aXJlZCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiB0aGUgbG9jayBmaWxlIGNvdWxkIG5vdCBiZSBjcmVhdGVkIG9yIG9wZW5lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9jaygkYmxvY2tpbmcgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmhhbmRsZSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRlcnJvciA9IG51bGw7CgogICAgICAgIC8vIFNpbGVuY2UgZXJyb3IgcmVwb3J0aW5nCiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoZnVuY3Rpb24gKCRlcnJubywgJG1zZykgdXNlICgmJGVycm9yKSB7CiAgICAgICAgICAgICRlcnJvciA9ICRtc2c7CiAgICAgICAgfSk7CgogICAgICAgIGlmICghJHRoaXMtPmhhbmRsZSA9IGZvcGVuKCR0aGlzLT5maWxlLCAncisnKSA/OiBmb3BlbigkdGhpcy0+ZmlsZSwgJ3InKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmhhbmRsZSA9IGZvcGVuKCR0aGlzLT5maWxlLCAneCcpKSB7CiAgICAgICAgICAgICAgICBjaG1vZCgkdGhpcy0+ZmlsZSwgMDY2Nik7CiAgICAgICAgICAgIH0gZWxzZWlmICghJHRoaXMtPmhhbmRsZSA9IGZvcGVuKCR0aGlzLT5maWxlLCAncisnKSA/OiBmb3BlbigkdGhpcy0+ZmlsZSwgJ3InKSkgewogICAgICAgICAgICAgICAgdXNsZWVwKDEwMCk7IC8vIEdpdmUgc29tZSB0aW1lIGZvciBjaG1vZCgpIHRvIGNvbXBsZXRlCiAgICAgICAgICAgICAgICAkdGhpcy0+aGFuZGxlID0gZm9wZW4oJHRoaXMtPmZpbGUsICdyKycpID86IGZvcGVuKCR0aGlzLT5maWxlLCAncicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKICAgICAgICBpZiAoISR0aGlzLT5oYW5kbGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCRlcnJvciwgMCwgbnVsbCwgJHRoaXMtPmZpbGUpOwogICAgICAgIH0KCiAgICAgICAgLy8gT24gV2luZG93cywgZXZlbiBpZiBQSFAgZG9jIHNheXMgdGhlIGNvbnRyYXJ5LCBMT0NLX05CIHdvcmtzLCBzZWUKICAgICAgICAvLyBodHRwczovL2J1Z3MucGhwLm5ldC81NDEyOQogICAgICAgIGlmICghZmxvY2soJHRoaXMtPmhhbmRsZSwgXExPQ0tfRVggfCAoJGJsb2NraW5nID8gMCA6IFxMT0NLX05CKSkpIHsKICAgICAgICAgICAgZmNsb3NlKCR0aGlzLT5oYW5kbGUpOwogICAgICAgICAgICAkdGhpcy0+aGFuZGxlID0gbnVsbDsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmVsZWFzZSB0aGUgcmVzb3VyY2UuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWxlYXNlKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmhhbmRsZSkgewogICAgICAgICAgICBmbG9jaygkdGhpcy0+aGFuZGxlLCBcTE9DS19VTiB8IFxMT0NLX05CKTsKICAgICAgICAgICAgZmNsb3NlKCR0aGlzLT5oYW5kbGUpOwogICAgICAgICAgICAkdGhpcy0+aGFuZGxlID0gbnVsbDsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvbjsKCi8qKgogKiBJT0V4Y2VwdGlvbiBpbnRlcmZhY2UgZm9yIGZpbGUgYW5kIGlucHV0L291dHB1dCBzdHJlYW0gcmVsYXRlZCBleGNlcHRpb25zIHRocm93biBieSB0aGUgY29tcG9uZW50LgogKgogKiBAYXV0aG9yIENocmlzdGlhbiBHw6RydG5lciA8Y2hyaXN0aWFuZ2FlcnRuZXIuZmlsbUBnb29nbGVtYWlsLmNvbT4KICovCmludGVyZmFjZSBJT0V4Y2VwdGlvbkludGVyZmFjZSBleHRlbmRzIEV4Y2VwdGlvbkludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFzc29jaWF0ZWQgcGF0aCBmb3IgdGhlIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXRoKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvbjsKCi8qKgogKiBFeGNlcHRpb24gY2xhc3MgdGhyb3duIHdoZW4gYSBmaWxlc3lzdGVtIG9wZXJhdGlvbiBmYWlsdXJlIGhhcHBlbnMuCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqIEBhdXRob3IgQ2hyaXN0aWFuIEfDpHJ0bmVyIDxjaHJpc3RpYW5nYWVydG5lci5maWxtQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIElPRXhjZXB0aW9uIGV4dGVuZHMgXFJ1bnRpbWVFeGNlcHRpb24gaW1wbGVtZW50cyBJT0V4Y2VwdGlvbkludGVyZmFjZQp7CiAgICBwcml2YXRlICRwYXRoOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJGNvZGUgPSAwLCBcRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwsICRwYXRoID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+cGF0aCA9ICRwYXRoOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkY29kZSwgJHByZXZpb3VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhdGgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGF0aDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbGVzeXN0ZW1cRXhjZXB0aW9uOwoKLyoqCiAqIEV4Y2VwdGlvbiBpbnRlcmZhY2UgZm9yIGFsbCBleGNlcHRpb25zIHRocm93biBieSB0aGUgY29tcG9uZW50LgogKgogKiBAYXV0aG9yIFJvbWFpbiBOZXV0cm9uIDxpbXByZWNAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvbjsKCi8qKgogKiBFeGNlcHRpb24gY2xhc3MgdGhyb3duIHdoZW4gYSBmaWxlIGNvdWxkbid0IGJlIGZvdW5kLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBDaHJpc3RpYW4gR8OkcnRuZXIgPGNocmlzdGlhbmdhZXJ0bmVyLmZpbG1AZ29vZ2xlbWFpbC5jb20+CiAqLwpjbGFzcyBGaWxlTm90Rm91bmRFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbgp7CiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UgPSBudWxsLCAkY29kZSA9IDAsIFxFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCwgJHBhdGggPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkbWVzc2FnZSkgewogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHBhdGgpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0ZpbGUgY291bGQgbm90IGJlIGZvdW5kLic7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoJ0ZpbGUgIiVzIiBjb3VsZCBub3QgYmUgZm91bmQuJywgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkY29kZSwgJHByZXZpb3VzLCAkcGF0aCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbGVzeXN0ZW1cRXhjZXB0aW9uXEZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbGVzeXN0ZW1cRXhjZXB0aW9uXElPRXhjZXB0aW9uOwoKLyoqCiAqIFByb3ZpZGVzIGJhc2ljIHV0aWxpdHkgdG8gbWFuaXB1bGF0ZSB0aGUgZmlsZSBzeXN0ZW0uCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRmlsZXN5c3RlbQp7CiAgICBwcml2YXRlIHN0YXRpYyAkbGFzdEVycm9yOwoKICAgIC8qKgogICAgICogQ29waWVzIGEgZmlsZS4KICAgICAqCiAgICAgKiBJZiB0aGUgdGFyZ2V0IGZpbGUgaXMgb2xkZXIgdGhhbiB0aGUgb3JpZ2luIGZpbGUsIGl0J3MgYWx3YXlzIG92ZXJ3cml0dGVuLgogICAgICogSWYgdGhlIHRhcmdldCBmaWxlIGlzIG5ld2VyLCBpdCBpcyBvdmVyd3JpdHRlbiBvbmx5IHdoZW4gdGhlCiAgICAgKiAkb3ZlcndyaXRlTmV3ZXJGaWxlcyBvcHRpb24gaXMgc2V0IHRvIHRydWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luRmlsZSAgICAgICAgICBUaGUgb3JpZ2luYWwgZmlsZW5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldEZpbGUgICAgICAgICAgVGhlIHRhcmdldCBmaWxlbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAkb3ZlcndyaXRlTmV3ZXJGaWxlcyBJZiB0cnVlLCB0YXJnZXQgZmlsZXMgbmV3ZXIgdGhhbiBvcmlnaW4gZmlsZXMgYXJlIG92ZXJ3cml0dGVuCiAgICAgKgogICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gV2hlbiBvcmlnaW5GaWxlIGRvZXNuJ3QgZXhpc3QKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gICAgICAgICAgIFdoZW4gY29weSBmYWlscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29weSgkb3JpZ2luRmlsZSwgJHRhcmdldEZpbGUsICRvdmVyd3JpdGVOZXdlckZpbGVzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJG9yaWdpbklzTG9jYWwgPSBzdHJlYW1faXNfbG9jYWwoJG9yaWdpbkZpbGUpIHx8IDAgPT09IHN0cmlwb3MoJG9yaWdpbkZpbGUsICdmaWxlOi8vJyk7CiAgICAgICAgaWYgKCRvcmlnaW5Jc0xvY2FsICYmICFpc19maWxlKCRvcmlnaW5GaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjb3B5ICIlcyIgYmVjYXVzZSBmaWxlIGRvZXMgbm90IGV4aXN0LicsICRvcmlnaW5GaWxlKSwgMCwgbnVsbCwgJG9yaWdpbkZpbGUpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm1rZGlyKFxkaXJuYW1lKCR0YXJnZXRGaWxlKSk7CgogICAgICAgICRkb0NvcHkgPSB0cnVlOwogICAgICAgIGlmICghJG92ZXJ3cml0ZU5ld2VyRmlsZXMgJiYgbnVsbCA9PT0gcGFyc2VfdXJsKCRvcmlnaW5GaWxlLCBcUEhQX1VSTF9IT1NUKSAmJiBpc19maWxlKCR0YXJnZXRGaWxlKSkgewogICAgICAgICAgICAkZG9Db3B5ID0gZmlsZW10aW1lKCRvcmlnaW5GaWxlKSA+IGZpbGVtdGltZSgkdGFyZ2V0RmlsZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRvQ29weSkgewogICAgICAgICAgICAvLyBodHRwczovL2J1Z3MucGhwLm5ldC82NDYzNAogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRzb3VyY2UgPSBAZm9wZW4oJG9yaWdpbkZpbGUsICdyJykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY29weSAiJXMiIHRvICIlcyIgYmVjYXVzZSBzb3VyY2UgZmlsZSBjb3VsZCBub3QgYmUgb3BlbmVkIGZvciByZWFkaW5nLicsICRvcmlnaW5GaWxlLCAkdGFyZ2V0RmlsZSksIDAsIG51bGwsICRvcmlnaW5GaWxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gU3RyZWFtIGNvbnRleHQgY3JlYXRlZCB0byBhbGxvdyBmaWxlcyBvdmVyd3JpdGUgd2hlbiB1c2luZyBGVFAgc3RyZWFtIHdyYXBwZXIgLSBkaXNhYmxlZCBieSBkZWZhdWx0CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHRhcmdldCA9IEBmb3BlbigkdGFyZ2V0RmlsZSwgJ3cnLCBudWxsLCBzdHJlYW1fY29udGV4dF9jcmVhdGUoWydmdHAnID0+IFsnb3ZlcndyaXRlJyA9PiB0cnVlXV0pKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjb3B5ICIlcyIgdG8gIiVzIiBiZWNhdXNlIHRhcmdldCBmaWxlIGNvdWxkIG5vdCBiZSBvcGVuZWQgZm9yIHdyaXRpbmcuJywgJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlKSwgMCwgbnVsbCwgJG9yaWdpbkZpbGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkYnl0ZXNDb3BpZWQgPSBzdHJlYW1fY29weV90b19zdHJlYW0oJHNvdXJjZSwgJHRhcmdldCk7CiAgICAgICAgICAgIGZjbG9zZSgkc291cmNlKTsKICAgICAgICAgICAgZmNsb3NlKCR0YXJnZXQpOwogICAgICAgICAgICB1bnNldCgkc291cmNlLCAkdGFyZ2V0KTsKCiAgICAgICAgICAgIGlmICghaXNfZmlsZSgkdGFyZ2V0RmlsZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY29weSAiJXMiIHRvICIlcyIuJywgJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlKSwgMCwgbnVsbCwgJG9yaWdpbkZpbGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG9yaWdpbklzTG9jYWwpIHsKICAgICAgICAgICAgICAgIC8vIExpa2UgYGNwYCwgcHJlc2VydmUgZXhlY3V0YWJsZSBwZXJtaXNzaW9uIGJpdHMKICAgICAgICAgICAgICAgIEBjaG1vZCgkdGFyZ2V0RmlsZSwgZmlsZXBlcm1zKCR0YXJnZXRGaWxlKSB8IChmaWxlcGVybXMoJG9yaWdpbkZpbGUpICYgMDExMSkpOwoKICAgICAgICAgICAgICAgIGlmICgkYnl0ZXNDb3BpZWQgIT09ICRieXRlc09yaWdpbiA9IGZpbGVzaXplKCRvcmlnaW5GaWxlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY29weSB0aGUgd2hvbGUgY29udGVudCBvZiAiJXMiIHRvICIlcyIgKCVnIG9mICVnIGJ5dGVzIGNvcGllZCkuJywgJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlLCAkYnl0ZXNDb3BpZWQsICRieXRlc09yaWdpbiksIDAsIG51bGwsICRvcmlnaW5GaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBkaXJlY3RvcnkgcmVjdXJzaXZlbHkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpdGVyYWJsZSAkZGlycyBUaGUgZGlyZWN0b3J5IHBhdGgKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJG1vZGUgVGhlIGRpcmVjdG9yeSBtb2RlCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBPbiBhbnkgZGlyZWN0b3J5IGNyZWF0aW9uIGZhaWx1cmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1rZGlyKCRkaXJzLCAkbW9kZSA9IDA3NzcpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvSXRlcmFibGUoJGRpcnMpIGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKGlzX2RpcigkZGlyKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghc2VsZjo6Ym94KCdta2RpcicsICRkaXIsICRtb2RlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJGRpcikpIHsKICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZGlyZWN0b3J5IHdhcyBub3QgY3JlYXRlZCBieSBhIGNvbmN1cnJlbnQgcHJvY2Vzcy4gTGV0J3MgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggYSBkZXZlbG9wZXIgZnJpZW5kbHkgZXJyb3IgbWVzc2FnZSBpZiB3ZSBoYXZlIG9uZQogICAgICAgICAgICAgICAgICAgIGlmIChzZWxmOjokbGFzdEVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY3JlYXRlICIlcyI6ICcsICRkaXIpLnNlbGY6OiRsYXN0RXJyb3IsIDAsIG51bGwsICRkaXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNyZWF0ZSAiJXMiLicsICRkaXIpLCAwLCBudWxsLCAkZGlyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB0aGUgZXhpc3RlbmNlIG9mIGZpbGVzIG9yIGRpcmVjdG9yaWVzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aXRlcmFibGUgJGZpbGVzIEEgZmlsZW5hbWUsIGFuIGFycmF5IG9mIGZpbGVzLCBvciBhIFxUcmF2ZXJzYWJsZSBpbnN0YW5jZSB0byBjaGVjawogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBmaWxlIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGlzdHMoJGZpbGVzKQogICAgewogICAgICAgICRtYXhQYXRoTGVuZ3RoID0gXFBIUF9NQVhQQVRITEVOIC0gMjsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvSXRlcmFibGUoJGZpbGVzKSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoXHN0cmxlbigkZmlsZSkgPiAkbWF4UGF0aExlbmd0aCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0NvdWxkIG5vdCBjaGVjayBpZiBmaWxlIGV4aXN0IGJlY2F1c2UgcGF0aCBsZW5ndGggZXhjZWVkcyAlZCBjaGFyYWN0ZXJzLicsICRtYXhQYXRoTGVuZ3RoKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRmaWxlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYWNjZXNzIGFuZCBtb2RpZmljYXRpb24gdGltZSBvZiBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aXRlcmFibGUgJGZpbGVzIEEgZmlsZW5hbWUsIGFuIGFycmF5IG9mIGZpbGVzLCBvciBhIFxUcmF2ZXJzYWJsZSBpbnN0YW5jZSB0byBjcmVhdGUKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAgICAgICAgJHRpbWUgIFRoZSB0b3VjaCB0aW1lIGFzIGEgVW5peCB0aW1lc3RhbXAsIGlmIG5vdCBzdXBwbGllZCB0aGUgY3VycmVudCBzeXN0ZW0gdGltZSBpcyB1c2VkCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICAgICRhdGltZSBUaGUgYWNjZXNzIHRpbWUgYXMgYSBVbml4IHRpbWVzdGFtcCwgaWYgbm90IHN1cHBsaWVkIHRoZSBjdXJyZW50IHN5c3RlbSB0aW1lIGlzIHVzZWQKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gdG91Y2ggZmFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRvdWNoKCRmaWxlcywgJHRpbWUgPSBudWxsLCAkYXRpbWUgPSBudWxsKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b0l0ZXJhYmxlKCRmaWxlcykgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJHRvdWNoID0gJHRpbWUgPyBAdG91Y2goJGZpbGUsICR0aW1lLCAkYXRpbWUpIDogQHRvdWNoKCRmaWxlKTsKICAgICAgICAgICAgaWYgKHRydWUgIT09ICR0b3VjaCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byB0b3VjaCAiJXMiLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBmaWxlcyBvciBkaXJlY3Rvcmllcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGl0ZXJhYmxlICRmaWxlcyBBIGZpbGVuYW1lLCBhbiBhcnJheSBvZiBmaWxlcywgb3IgYSBcVHJhdmVyc2FibGUgaW5zdGFuY2UgdG8gcmVtb3ZlCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIHJlbW92YWwgZmFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZSgkZmlsZXMpCiAgICB7CiAgICAgICAgaWYgKCRmaWxlcyBpbnN0YW5jZW9mIFxUcmF2ZXJzYWJsZSkgewogICAgICAgICAgICAkZmlsZXMgPSBpdGVyYXRvcl90b19hcnJheSgkZmlsZXMsIGZhbHNlKTsKICAgICAgICB9IGVsc2VpZiAoIVxpc19hcnJheSgkZmlsZXMpKSB7CiAgICAgICAgICAgICRmaWxlcyA9IFskZmlsZXNdOwogICAgICAgIH0KICAgICAgICAkZmlsZXMgPSBhcnJheV9yZXZlcnNlKCRmaWxlcyk7CiAgICAgICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlKSB7CiAgICAgICAgICAgIGlmIChpc19saW5rKCRmaWxlKSkgewogICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzUyMTc2CiAgICAgICAgICAgICAgICBpZiAoIShzZWxmOjpib3goJ3VubGluaycsICRmaWxlKSB8fCAnXFwnICE9PSBcRElSRUNUT1JZX1NFUEFSQVRPUiB8fCBzZWxmOjpib3goJ3JtZGlyJywgJGZpbGUpKSAmJiBmaWxlX2V4aXN0cygkZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHJlbW92ZSBzeW1saW5rICIlcyI6ICcsICRmaWxlKS5zZWxmOjokbGFzdEVycm9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2RpcigkZmlsZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmUobmV3IFxGaWxlc3lzdGVtSXRlcmF0b3IoJGZpbGUsIFxGaWxlc3lzdGVtSXRlcmF0b3I6OkNVUlJFTlRfQVNfUEFUSE5BTUUgfCBcRmlsZXN5c3RlbUl0ZXJhdG9yOjpTS0lQX0RPVFMpKTsKCiAgICAgICAgICAgICAgICBpZiAoIXNlbGY6OmJveCgncm1kaXInLCAkZmlsZSkgJiYgZmlsZV9leGlzdHMoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byByZW1vdmUgZGlyZWN0b3J5ICIlcyI6ICcsICRmaWxlKS5zZWxmOjokbGFzdEVycm9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCFzZWxmOjpib3goJ3VubGluaycsICRmaWxlKSAmJiAoZmFsc2UgIT09IHN0cnBvcyhzZWxmOjokbGFzdEVycm9yLCAnUGVybWlzc2lvbiBkZW5pZWQnKSB8fCBmaWxlX2V4aXN0cygkZmlsZSkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHJlbW92ZSBmaWxlICIlcyI6ICcsICRmaWxlKS5zZWxmOjokbGFzdEVycm9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoYW5nZSBtb2RlIGZvciBhbiBhcnJheSBvZiBmaWxlcyBvciBkaXJlY3Rvcmllcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGl0ZXJhYmxlICRmaWxlcyAgICAgQSBmaWxlbmFtZSwgYW4gYXJyYXkgb2YgZmlsZXMsIG9yIGEgXFRyYXZlcnNhYmxlIGluc3RhbmNlIHRvIGNoYW5nZSBtb2RlCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRtb2RlICAgICAgVGhlIG5ldyBtb2RlIChvY3RhbCkKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJHVtYXNrICAgICBUaGUgbW9kZSBtYXNrIChvY3RhbCkKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgJHJlY3Vyc2l2ZSBXaGV0aGVyIGNoYW5nZSB0aGUgbW9kIHJlY3Vyc2l2ZWx5IG9yIG5vdAogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiB0aGUgY2hhbmdlIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaG1vZCgkZmlsZXMsICRtb2RlLCAkdW1hc2sgPSAwMDAwLCAkcmVjdXJzaXZlID0gZmFsc2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvSXRlcmFibGUoJGZpbGVzKSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoKFxQSFBfVkVSU0lPTl9JRCA8IDgwMDAwIHx8IFxpc19pbnQoJG1vZGUpKSAmJiB0cnVlICE9PSBAY2htb2QoJGZpbGUsICRtb2RlICYgfiR1bWFzaykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY2htb2QgZmlsZSAiJXMiLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkcmVjdXJzaXZlICYmIGlzX2RpcigkZmlsZSkgJiYgIWlzX2xpbmsoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2htb2QobmV3IFxGaWxlc3lzdGVtSXRlcmF0b3IoJGZpbGUpLCAkbW9kZSwgJHVtYXNrLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoYW5nZSB0aGUgb3duZXIgb2YgYW4gYXJyYXkgb2YgZmlsZXMgb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpdGVyYWJsZSAkZmlsZXMgICAgIEEgZmlsZW5hbWUsIGFuIGFycmF5IG9mIGZpbGVzLCBvciBhIFxUcmF2ZXJzYWJsZSBpbnN0YW5jZSB0byBjaGFuZ2Ugb3duZXIKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICAgICAgJHVzZXIgICAgICBBIHVzZXIgbmFtZSBvciBudW1iZXIKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgJHJlY3Vyc2l2ZSBXaGV0aGVyIGNoYW5nZSB0aGUgb3duZXIgcmVjdXJzaXZlbHkgb3Igbm90CiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIHRoZSBjaGFuZ2UgZmFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNob3duKCRmaWxlcywgJHVzZXIsICRyZWN1cnNpdmUgPSBmYWxzZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dG9JdGVyYWJsZSgkZmlsZXMpIGFzICRmaWxlKSB7CiAgICAgICAgICAgIGlmICgkcmVjdXJzaXZlICYmIGlzX2RpcigkZmlsZSkgJiYgIWlzX2xpbmsoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hvd24obmV3IFxGaWxlc3lzdGVtSXRlcmF0b3IoJGZpbGUpLCAkdXNlciwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX2xpbmsoJGZpbGUpICYmIFxmdW5jdGlvbl9leGlzdHMoJ2xjaG93bicpKSB7CiAgICAgICAgICAgICAgICBpZiAodHJ1ZSAhPT0gQGxjaG93bigkZmlsZSwgJHVzZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjaG93biBmaWxlICIlcyIuJywgJGZpbGUpLCAwLCBudWxsLCAkZmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAodHJ1ZSAhPT0gQGNob3duKCRmaWxlLCAkdXNlcikpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNob3duIGZpbGUgIiVzIi4nLCAkZmlsZSksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoYW5nZSB0aGUgZ3JvdXAgb2YgYW4gYXJyYXkgb2YgZmlsZXMgb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpdGVyYWJsZSAkZmlsZXMgICAgIEEgZmlsZW5hbWUsIGFuIGFycmF5IG9mIGZpbGVzLCBvciBhIFxUcmF2ZXJzYWJsZSBpbnN0YW5jZSB0byBjaGFuZ2UgZ3JvdXAKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICAgICAgJGdyb3VwICAgICBBIGdyb3VwIG5hbWUgb3IgbnVtYmVyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRyZWN1cnNpdmUgV2hldGhlciBjaGFuZ2UgdGhlIGdyb3VwIHJlY3Vyc2l2ZWx5IG9yIG5vdAogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiB0aGUgY2hhbmdlIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGdycCgkZmlsZXMsICRncm91cCwgJHJlY3Vyc2l2ZSA9IGZhbHNlKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b0l0ZXJhYmxlKCRmaWxlcykgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKCRyZWN1cnNpdmUgJiYgaXNfZGlyKCRmaWxlKSAmJiAhaXNfbGluaygkZmlsZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jaGdycChuZXcgXEZpbGVzeXN0ZW1JdGVyYXRvcigkZmlsZSksICRncm91cCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX2xpbmsoJGZpbGUpICYmIFxmdW5jdGlvbl9leGlzdHMoJ2xjaGdycCcpKSB7CiAgICAgICAgICAgICAgICBpZiAodHJ1ZSAhPT0gQGxjaGdycCgkZmlsZSwgJGdyb3VwKSB8fCAoXGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpICYmICFwb3NpeF9nZXRncm5hbSgkZ3JvdXApKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY2hncnAgZmlsZSAiJXMiLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHRydWUgIT09IEBjaGdycCgkZmlsZSwgJGdyb3VwKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY2hncnAgZmlsZSAiJXMiLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVuYW1lcyBhIGZpbGUgb3IgYSBkaXJlY3RvcnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luICAgIFRoZSBvcmlnaW4gZmlsZW5hbWUgb3IgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQgICAgVGhlIG5ldyBmaWxlbmFtZSBvciBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBib29sICAgJG92ZXJ3cml0ZSBXaGV0aGVyIHRvIG92ZXJ3cml0ZSB0aGUgdGFyZ2V0IGlmIGl0IGFscmVhZHkgZXhpc3RzCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIHRhcmdldCBmaWxlIG9yIGRpcmVjdG9yeSBhbHJlYWR5IGV4aXN0cwogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIG9yaWdpbiBjYW5ub3QgYmUgcmVuYW1lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuYW1lKCRvcmlnaW4sICR0YXJnZXQsICRvdmVyd3JpdGUgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyB3ZSBjaGVjayB0aGF0IHRhcmdldCBkb2VzIG5vdCBleGlzdAogICAgICAgIGlmICghJG92ZXJ3cml0ZSAmJiAkdGhpcy0+aXNSZWFkYWJsZSgkdGFyZ2V0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignQ2Fubm90IHJlbmFtZSBiZWNhdXNlIHRoZSB0YXJnZXQgIiVzIiBhbHJlYWR5IGV4aXN0cy4nLCAkdGFyZ2V0KSwgMCwgbnVsbCwgJHRhcmdldCk7CiAgICAgICAgfQoKICAgICAgICBpZiAodHJ1ZSAhPT0gQHJlbmFtZSgkb3JpZ2luLCAkdGFyZ2V0KSkgewogICAgICAgICAgICBpZiAoaXNfZGlyKCRvcmlnaW4pKSB7CiAgICAgICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvNTQwOTcgJiBodHRwczovL3BocC5uZXQvcmVuYW1lIzExMzk0MwogICAgICAgICAgICAgICAgJHRoaXMtPm1pcnJvcigkb3JpZ2luLCAkdGFyZ2V0LCBudWxsLCBbJ292ZXJyaWRlJyA9PiAkb3ZlcndyaXRlLCAnZGVsZXRlJyA9PiAkb3ZlcndyaXRlXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVtb3ZlKCRvcmlnaW4pOwoKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignQ2Fubm90IHJlbmFtZSAiJXMiIHRvICIlcyIuJywgJG9yaWdpbiwgJHRhcmdldCksIDAsIG51bGwsICR0YXJnZXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRlbGxzIHdoZXRoZXIgYSBmaWxlIGV4aXN0cyBhbmQgaXMgcmVhZGFibGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZW5hbWUgUGF0aCB0byB0aGUgZmlsZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiB3aW5kb3dzIHBhdGggaXMgbG9uZ2VyIHRoYW4gMjU4IGNoYXJhY3RlcnMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1JlYWRhYmxlKCRmaWxlbmFtZSkKICAgIHsKICAgICAgICAkbWF4UGF0aExlbmd0aCA9IFxQSFBfTUFYUEFUSExFTiAtIDI7CgogICAgICAgIGlmIChcc3RybGVuKCRmaWxlbmFtZSkgPiAkbWF4UGF0aExlbmd0aCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignQ291bGQgbm90IGNoZWNrIGlmIGZpbGUgaXMgcmVhZGFibGUgYmVjYXVzZSBwYXRoIGxlbmd0aCBleGNlZWRzICVkIGNoYXJhY3RlcnMuJywgJG1heFBhdGhMZW5ndGgpLCAwLCBudWxsLCAkZmlsZW5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzX3JlYWRhYmxlKCRmaWxlbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgc3ltYm9saWMgbGluayBvciBjb3B5IGEgZGlyZWN0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbkRpciAgICAgVGhlIG9yaWdpbiBkaXJlY3RvcnkgcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0RGlyICAgICBUaGUgc3ltYm9saWMgbGluayBuYW1lCiAgICAgKiBAcGFyYW0gYm9vbCAgICRjb3B5T25XaW5kb3dzIFdoZXRoZXIgdG8gY29weSBmaWxlcyBpZiBvbiBXaW5kb3dzCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIHN5bWxpbmsgZmFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN5bWxpbmsoJG9yaWdpbkRpciwgJHRhcmdldERpciwgJGNvcHlPbldpbmRvd3MgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgJG9yaWdpbkRpciA9IHN0cnRyKCRvcmlnaW5EaXIsICcvJywgJ1xcJyk7CiAgICAgICAgICAgICR0YXJnZXREaXIgPSBzdHJ0cigkdGFyZ2V0RGlyLCAnLycsICdcXCcpOwoKICAgICAgICAgICAgaWYgKCRjb3B5T25XaW5kb3dzKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bWlycm9yKCRvcmlnaW5EaXIsICR0YXJnZXREaXIpOwoKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm1rZGlyKFxkaXJuYW1lKCR0YXJnZXREaXIpKTsKCiAgICAgICAgaWYgKGlzX2xpbmsoJHRhcmdldERpcikpIHsKICAgICAgICAgICAgaWYgKHJlYWRsaW5rKCR0YXJnZXREaXIpID09PSAkb3JpZ2luRGlyKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgkdGFyZ2V0RGlyKTsKICAgICAgICB9CgogICAgICAgIGlmICghc2VsZjo6Ym94KCdzeW1saW5rJywgJG9yaWdpbkRpciwgJHRhcmdldERpcikpIHsKICAgICAgICAgICAgJHRoaXMtPmxpbmtFeGNlcHRpb24oJG9yaWdpbkRpciwgJHRhcmdldERpciwgJ3N5bWJvbGljJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIGhhcmQgbGluaywgb3Igc2V2ZXJhbCBoYXJkIGxpbmtzIHRvIGEgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRvcmlnaW5GaWxlICBUaGUgb3JpZ2luYWwgZmlsZQogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkdGFyZ2V0RmlsZXMgVGhlIHRhcmdldCBmaWxlKHMpCiAgICAgKgogICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gV2hlbiBvcmlnaW5hbCBmaWxlIGlzIG1pc3Npbmcgb3Igbm90IGEgZmlsZQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgICAgICAgICAgV2hlbiBsaW5rIGZhaWxzLCBpbmNsdWRpbmcgaWYgbGluayBhbHJlYWR5IGV4aXN0cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFyZGxpbmsoJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlcykKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5leGlzdHMoJG9yaWdpbkZpbGUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24obnVsbCwgMCwgbnVsbCwgJG9yaWdpbkZpbGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc19maWxlKCRvcmlnaW5GaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKHNwcmludGYoJ09yaWdpbiBmaWxlICIlcyIgaXMgbm90IGEgZmlsZS4nLCAkb3JpZ2luRmlsZSkpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvSXRlcmFibGUoJHRhcmdldEZpbGVzKSBhcyAkdGFyZ2V0RmlsZSkgewogICAgICAgICAgICBpZiAoaXNfZmlsZSgkdGFyZ2V0RmlsZSkpIHsKICAgICAgICAgICAgICAgIGlmIChmaWxlaW5vZGUoJG9yaWdpbkZpbGUpID09PSBmaWxlaW5vZGUoJHRhcmdldEZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVtb3ZlKCR0YXJnZXRGaWxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFzZWxmOjpib3goJ2xpbmsnLCAkb3JpZ2luRmlsZSwgJHRhcmdldEZpbGUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bGlua0V4Y2VwdGlvbigkb3JpZ2luRmlsZSwgJHRhcmdldEZpbGUsICdoYXJkJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldAogICAgICogQHBhcmFtIHN0cmluZyAkbGlua1R5cGUgTmFtZSBvZiB0aGUgbGluayB0eXBlLCB0eXBpY2FsbHkgJ3N5bWJvbGljJyBvciAnaGFyZCcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBsaW5rRXhjZXB0aW9uKCRvcmlnaW4sICR0YXJnZXQsICRsaW5rVHlwZSkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6JGxhc3RFcnJvcikgewogICAgICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgJiYgZmFsc2UgIT09IHN0cnBvcyhzZWxmOjokbGFzdEVycm9yLCAnZXJyb3IgY29kZSgxMzE0KScpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignVW5hYmxlIHRvIGNyZWF0ZSAiJXMiIGxpbmsgZHVlIHRvIGVycm9yIGNvZGUgMTMxNDogXCdBIHJlcXVpcmVkIHByaXZpbGVnZSBpcyBub3QgaGVsZCBieSB0aGUgY2xpZW50XCcuIERvIHlvdSBoYXZlIHRoZSByZXF1aXJlZCBBZG1pbmlzdHJhdG9yLXJpZ2h0cz8nLCAkbGlua1R5cGUpLCAwLCBudWxsLCAkdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNyZWF0ZSAiJXMiIGxpbmsgZnJvbSAiJXMiIHRvICIlcyIuJywgJGxpbmtUeXBlLCAkb3JpZ2luLCAkdGFyZ2V0KSwgMCwgbnVsbCwgJHRhcmdldCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXNvbHZlcyBsaW5rcyBpbiBwYXRocy4KICAgICAqCiAgICAgKiBXaXRoICRjYW5vbmljYWxpemUgPSBmYWxzZSAoZGVmYXVsdCkKICAgICAqICAgICAgLSBpZiAkcGF0aCBkb2VzIG5vdCBleGlzdCBvciBpcyBub3QgYSBsaW5rLCByZXR1cm5zIG51bGwKICAgICAqICAgICAgLSBpZiAkcGF0aCBpcyBhIGxpbmssIHJldHVybnMgdGhlIG5leHQgZGlyZWN0IHRhcmdldCBvZiB0aGUgbGluayB3aXRob3V0IGNvbnNpZGVyaW5nIHRoZSBleGlzdGVuY2Ugb2YgdGhlIHRhcmdldAogICAgICoKICAgICAqIFdpdGggJGNhbm9uaWNhbGl6ZSA9IHRydWUKICAgICAqICAgICAgLSBpZiAkcGF0aCBkb2VzIG5vdCBleGlzdCwgcmV0dXJucyBudWxsCiAgICAgKiAgICAgIC0gaWYgJHBhdGggZXhpc3RzLCByZXR1cm5zIGl0cyBhYnNvbHV0ZSBmdWxseSByZXNvbHZlZCBmaW5hbCB2ZXJzaW9uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aCAgICAgICAgIEEgZmlsZXN5c3RlbSBwYXRoCiAgICAgKiBAcGFyYW0gYm9vbCAgICRjYW5vbmljYWxpemUgV2hldGhlciBvciBub3QgdG8gcmV0dXJuIGEgY2Fub25pY2FsaXplZCBwYXRoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZGxpbmsoJHBhdGgsICRjYW5vbmljYWxpemUgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISRjYW5vbmljYWxpemUgJiYgIWlzX2xpbmsoJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRjYW5vbmljYWxpemUpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICAgICAgJHBhdGggPSByZWFkbGluaygkcGF0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiByZWFscGF0aCgkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgcmV0dXJuIHJlYWxwYXRoKCRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZWFkbGluaygkcGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBhbiBleGlzdGluZyBwYXRoLCBjb252ZXJ0IGl0IHRvIGEgcGF0aCByZWxhdGl2ZSB0byBhIGdpdmVuIHN0YXJ0aW5nIHBhdGguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZW5kUGF0aCAgIEFic29sdXRlIHBhdGggb2YgdGFyZ2V0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGFydFBhdGggQWJzb2x1dGUgcGF0aCB3aGVyZSB0cmF2ZXJzYWwgYmVnaW5zCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUGF0aCBvZiB0YXJnZXQgcmVsYXRpdmUgdG8gc3RhcnRpbmcgcGF0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFrZVBhdGhSZWxhdGl2ZSgkZW5kUGF0aCwgJHN0YXJ0UGF0aCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pc0Fic29sdXRlUGF0aCgkZW5kUGF0aCkgfHwgISR0aGlzLT5pc0Fic29sdXRlUGF0aCgkc3RhcnRQYXRoKSkgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdTdXBwb3J0IGZvciBwYXNzaW5nIHJlbGF0aXZlIHBhdGhzIHRvICVzKCkgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuNCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICB9CgogICAgICAgIC8vIE5vcm1hbGl6ZSBzZXBhcmF0b3JzIG9uIFdpbmRvd3MKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgJGVuZFBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRlbmRQYXRoKTsKICAgICAgICAgICAgJHN0YXJ0UGF0aCA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJHN0YXJ0UGF0aCk7CiAgICAgICAgfQoKICAgICAgICAkc3BsaXREcml2ZUxldHRlciA9IGZ1bmN0aW9uICgkcGF0aCkgewogICAgICAgICAgICByZXR1cm4gKFxzdHJsZW4oJHBhdGgpID4gMiAmJiAnOicgPT09ICRwYXRoWzFdICYmICcvJyA9PT0gJHBhdGhbMl0gJiYgY3R5cGVfYWxwaGEoJHBhdGhbMF0pKQogICAgICAgICAgICAgICAgPyBbc3Vic3RyKCRwYXRoLCAyKSwgc3RydG91cHBlcigkcGF0aFswXSldCiAgICAgICAgICAgICAgICA6IFskcGF0aCwgbnVsbF07CiAgICAgICAgfTsKCiAgICAgICAgJHNwbGl0UGF0aCA9IGZ1bmN0aW9uICgkcGF0aCwgJGFic29sdXRlKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBbXTsKCiAgICAgICAgICAgIGZvcmVhY2ggKGV4cGxvZGUoJy8nLCB0cmltKCRwYXRoLCAnLycpKSBhcyAkc2VnbWVudCkgewogICAgICAgICAgICAgICAgaWYgKCcuLicgPT09ICRzZWdtZW50ICYmICgkYWJzb2x1dGUgfHwgXGNvdW50KCRyZXN1bHQpKSkgewogICAgICAgICAgICAgICAgICAgIGFycmF5X3BvcCgkcmVzdWx0KTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgnLicgIT09ICRzZWdtZW50ICYmICcnICE9PSAkc2VnbWVudCkgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9ICRzZWdtZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9OwoKICAgICAgICBsaXN0KCRlbmRQYXRoLCAkZW5kRHJpdmVMZXR0ZXIpID0gJHNwbGl0RHJpdmVMZXR0ZXIoJGVuZFBhdGgpOwogICAgICAgIGxpc3QoJHN0YXJ0UGF0aCwgJHN0YXJ0RHJpdmVMZXR0ZXIpID0gJHNwbGl0RHJpdmVMZXR0ZXIoJHN0YXJ0UGF0aCk7CgogICAgICAgICRzdGFydFBhdGhBcnIgPSAkc3BsaXRQYXRoKCRzdGFydFBhdGgsIHN0YXRpYzo6aXNBYnNvbHV0ZVBhdGgoJHN0YXJ0UGF0aCkpOwogICAgICAgICRlbmRQYXRoQXJyID0gJHNwbGl0UGF0aCgkZW5kUGF0aCwgc3RhdGljOjppc0Fic29sdXRlUGF0aCgkZW5kUGF0aCkpOwoKICAgICAgICBpZiAoJGVuZERyaXZlTGV0dGVyICYmICRzdGFydERyaXZlTGV0dGVyICYmICRlbmREcml2ZUxldHRlciAhPSAkc3RhcnREcml2ZUxldHRlcikgewogICAgICAgICAgICAvLyBFbmQgcGF0aCBpcyBvbiBhbm90aGVyIGRyaXZlLCBzbyBubyByZWxhdGl2ZSBwYXRoIGV4aXN0cwogICAgICAgICAgICByZXR1cm4gJGVuZERyaXZlTGV0dGVyLic6LycuKCRlbmRQYXRoQXJyID8gaW1wbG9kZSgnLycsICRlbmRQYXRoQXJyKS4nLycgOiAnJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBGaW5kIGZvciB3aGljaCBkaXJlY3RvcnkgdGhlIGNvbW1vbiBwYXRoIHN0b3BzCiAgICAgICAgJGluZGV4ID0gMDsKICAgICAgICB3aGlsZSAoaXNzZXQoJHN0YXJ0UGF0aEFyclskaW5kZXhdKSAmJiBpc3NldCgkZW5kUGF0aEFyclskaW5kZXhdKSAmJiAkc3RhcnRQYXRoQXJyWyRpbmRleF0gPT09ICRlbmRQYXRoQXJyWyRpbmRleF0pIHsKICAgICAgICAgICAgKyskaW5kZXg7CiAgICAgICAgfQoKICAgICAgICAvLyBEZXRlcm1pbmUgaG93IGRlZXAgdGhlIHN0YXJ0IHBhdGggaXMgcmVsYXRpdmUgdG8gdGhlIGNvbW1vbiBwYXRoIChpZSwgIndlYi9idW5kbGVzIiA9IDIgbGV2ZWxzKQogICAgICAgIGlmICgxID09PSBcY291bnQoJHN0YXJ0UGF0aEFycikgJiYgJycgPT09ICRzdGFydFBhdGhBcnJbMF0pIHsKICAgICAgICAgICAgJGRlcHRoID0gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZGVwdGggPSBcY291bnQoJHN0YXJ0UGF0aEFycikgLSAkaW5kZXg7CiAgICAgICAgfQoKICAgICAgICAvLyBSZXBlYXRlZCAiLi4vIiBmb3IgZWFjaCBsZXZlbCBuZWVkIHRvIHJlYWNoIHRoZSBjb21tb24gcGF0aAogICAgICAgICR0cmF2ZXJzZXIgPSBzdHJfcmVwZWF0KCcuLi8nLCAkZGVwdGgpOwoKICAgICAgICAkZW5kUGF0aFJlbWFpbmRlciA9IGltcGxvZGUoJy8nLCBcYXJyYXlfc2xpY2UoJGVuZFBhdGhBcnIsICRpbmRleCkpOwoKICAgICAgICAvLyBDb25zdHJ1Y3QgJGVuZFBhdGggZnJvbSB0cmF2ZXJzaW5nIHRvIHRoZSBjb21tb24gcGF0aCwgdGhlbiB0byB0aGUgcmVtYWluaW5nICRlbmRQYXRoCiAgICAgICAgJHJlbGF0aXZlUGF0aCA9ICR0cmF2ZXJzZXIuKCcnICE9PSAkZW5kUGF0aFJlbWFpbmRlciA/ICRlbmRQYXRoUmVtYWluZGVyLicvJyA6ICcnKTsKCiAgICAgICAgcmV0dXJuICcnID09PSAkcmVsYXRpdmVQYXRoID8gJy4vJyA6ICRyZWxhdGl2ZVBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBNaXJyb3JzIGEgZGlyZWN0b3J5IHRvIGFub3RoZXIuCiAgICAgKgogICAgICogQ29waWVzIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBmcm9tIHRoZSBvcmlnaW4gZGlyZWN0b3J5IGludG8gdGhlIHRhcmdldCBkaXJlY3RvcnkuIEJ5IGRlZmF1bHQ6CiAgICAgKgogICAgICogIC0gZXhpc3RpbmcgZmlsZXMgaW4gdGhlIHRhcmdldCBkaXJlY3Rvcnkgd2lsbCBiZSBvdmVyd3JpdHRlbiwgZXhjZXB0IGlmIHRoZXkgYXJlIG5ld2VyIChzZWUgdGhlIGBvdmVycmlkZWAgb3B0aW9uKQogICAgICogIC0gZmlsZXMgaW4gdGhlIHRhcmdldCBkaXJlY3RvcnkgdGhhdCBkbyBub3QgZXhpc3QgaW4gdGhlIHNvdXJjZSBkaXJlY3Rvcnkgd2lsbCBub3QgYmUgZGVsZXRlZCAoc2VlIHRoZSBgZGVsZXRlYCBvcHRpb24pCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICRvcmlnaW5EaXIgVGhlIG9yaWdpbiBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAkdGFyZ2V0RGlyIFRoZSB0YXJnZXQgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gXFRyYXZlcnNhYmxlfG51bGwgJGl0ZXJhdG9yICBJdGVyYXRvciB0aGF0IGZpbHRlcnMgd2hpY2ggZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHRvIGNvcHksIGlmIG51bGwgYSByZWN1cnNpdmUgaXRlcmF0b3IgaXMgY3JlYXRlZAogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgICRvcHRpb25zICAgQW4gYXJyYXkgb2YgYm9vbGVhbiBvcHRpb25zCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWxpZCBvcHRpb25zIGFyZToKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gJG9wdGlvbnNbJ292ZXJyaWRlJ10gSWYgdHJ1ZSwgdGFyZ2V0IGZpbGVzIG5ld2VyIHRoYW4gb3JpZ2luIGZpbGVzIGFyZSBvdmVyd3JpdHRlbiAoc2VlIGNvcHkoKSwgZGVmYXVsdHMgdG8gZmFsc2UpCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtICRvcHRpb25zWydjb3B5X29uX3dpbmRvd3MnXSBXaGV0aGVyIHRvIGNvcHkgZmlsZXMgaW5zdGVhZCBvZiBsaW5rcyBvbiBXaW5kb3dzIChzZWUgc3ltbGluaygpLCBkZWZhdWx0cyB0byBmYWxzZSkKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gJG9wdGlvbnNbJ2RlbGV0ZSddIFdoZXRoZXIgdG8gZGVsZXRlIGZpbGVzIHRoYXQgYXJlIG5vdCBpbiB0aGUgc291cmNlIGRpcmVjdG9yeSAoZGVmYXVsdHMgdG8gZmFsc2UpCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIGZpbGUgdHlwZSBpcyB1bmtub3duCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtaXJyb3IoJG9yaWdpbkRpciwgJHRhcmdldERpciwgXFRyYXZlcnNhYmxlICRpdGVyYXRvciA9IG51bGwsICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRhcmdldERpciA9IHJ0cmltKCR0YXJnZXREaXIsICcvXFwnKTsKICAgICAgICAkb3JpZ2luRGlyID0gcnRyaW0oJG9yaWdpbkRpciwgJy9cXCcpOwogICAgICAgICRvcmlnaW5EaXJMZW4gPSBcc3RybGVuKCRvcmlnaW5EaXIpOwoKICAgICAgICAvLyBJdGVyYXRlIGluIGRlc3RpbmF0aW9uIGZvbGRlciB0byByZW1vdmUgb2Jzb2xldGUgZW50cmllcwogICAgICAgIGlmICgkdGhpcy0+ZXhpc3RzKCR0YXJnZXREaXIpICYmIGlzc2V0KCRvcHRpb25zWydkZWxldGUnXSkgJiYgJG9wdGlvbnNbJ2RlbGV0ZSddKSB7CiAgICAgICAgICAgICRkZWxldGVJdGVyYXRvciA9ICRpdGVyYXRvcjsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRkZWxldGVJdGVyYXRvcikgewogICAgICAgICAgICAgICAgJGZsYWdzID0gXEZpbGVzeXN0ZW1JdGVyYXRvcjo6U0tJUF9ET1RTOwogICAgICAgICAgICAgICAgJGRlbGV0ZUl0ZXJhdG9yID0gbmV3IFxSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKG5ldyBcUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJHRhcmdldERpciwgJGZsYWdzKSwgXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OkNISUxEX0ZJUlNUKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGFyZ2V0RGlyTGVuID0gXHN0cmxlbigkdGFyZ2V0RGlyKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRlbGV0ZUl0ZXJhdG9yIGFzICRmaWxlKSB7CiAgICAgICAgICAgICAgICAkb3JpZ2luID0gJG9yaWdpbkRpci5zdWJzdHIoJGZpbGUtPmdldFBhdGhuYW1lKCksICR0YXJnZXREaXJMZW4pOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZXhpc3RzKCRvcmlnaW4pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgkZmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb3B5T25XaW5kb3dzID0gZmFsc2U7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydjb3B5X29uX3dpbmRvd3MnXSkpIHsKICAgICAgICAgICAgJGNvcHlPbldpbmRvd3MgPSAkb3B0aW9uc1snY29weV9vbl93aW5kb3dzJ107CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGl0ZXJhdG9yKSB7CiAgICAgICAgICAgICRmbGFncyA9ICRjb3B5T25XaW5kb3dzID8gXEZpbGVzeXN0ZW1JdGVyYXRvcjo6U0tJUF9ET1RTIHwgXEZpbGVzeXN0ZW1JdGVyYXRvcjo6Rk9MTE9XX1NZTUxJTktTIDogXEZpbGVzeXN0ZW1JdGVyYXRvcjo6U0tJUF9ET1RTOwogICAgICAgICAgICAkaXRlcmF0b3IgPSBuZXcgXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IobmV3IFxSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigkb3JpZ2luRGlyLCAkZmxhZ3MpLCBcUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjo6U0VMRl9GSVJTVCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmV4aXN0cygkb3JpZ2luRGlyKSkgewogICAgICAgICAgICAkdGhpcy0+bWtkaXIoJHRhcmdldERpcik7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkaXRlcmF0b3IgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJHRhcmdldCA9ICR0YXJnZXREaXIuc3Vic3RyKCRmaWxlLT5nZXRQYXRobmFtZSgpLCAkb3JpZ2luRGlyTGVuKTsKCiAgICAgICAgICAgIGlmICgkY29weU9uV2luZG93cykgewogICAgICAgICAgICAgICAgaWYgKGlzX2ZpbGUoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvcHkoJGZpbGUsICR0YXJnZXQsIGlzc2V0KCRvcHRpb25zWydvdmVycmlkZSddKSA/ICRvcHRpb25zWydvdmVycmlkZSddIDogZmFsc2UpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2RpcigkZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bWtkaXIoJHRhcmdldCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdVbmFibGUgdG8gZ3Vlc3MgIiVzIiBmaWxlIHR5cGUuJywgJGZpbGUpLCAwLCBudWxsLCAkZmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoaXNfbGluaygkZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c3ltbGluaygkZmlsZS0+Z2V0TGlua1RhcmdldCgpLCAkdGFyZ2V0KTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc19kaXIoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1rZGlyKCR0YXJnZXQpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2ZpbGUoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvcHkoJGZpbGUsICR0YXJnZXQsIGlzc2V0KCRvcHRpb25zWydvdmVycmlkZSddKSA/ICRvcHRpb25zWydvdmVycmlkZSddIDogZmFsc2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignVW5hYmxlIHRvIGd1ZXNzICIlcyIgZmlsZSB0eXBlLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBmaWxlIHBhdGggaXMgYW4gYWJzb2x1dGUgcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlIEEgZmlsZSBwYXRoCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Fic29sdXRlUGF0aCgkZmlsZSkKICAgIHsKICAgICAgICByZXR1cm4gJycgIT09IChzdHJpbmcpICRmaWxlICYmIChzdHJzcG4oJGZpbGUsICcvXFwnLCAwLCAxKQogICAgICAgICAgICB8fCAoXHN0cmxlbigkZmlsZSkgPiAzICYmIGN0eXBlX2FscGhhKCRmaWxlWzBdKQogICAgICAgICAgICAgICAgJiYgJzonID09PSAkZmlsZVsxXQogICAgICAgICAgICAgICAgJiYgc3Ryc3BuKCRmaWxlLCAnL1xcJywgMiwgMSkKICAgICAgICAgICAgKQogICAgICAgICAgICB8fCBudWxsICE9PSBwYXJzZV91cmwoJGZpbGUsIFxQSFBfVVJMX1NDSEVNRSkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHRlbXBvcmFyeSBmaWxlIHdpdGggc3VwcG9ydCBmb3IgY3VzdG9tIHN0cmVhbSB3cmFwcGVycy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXIgICAgVGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgdGVtcG9yYXJ5IGZpbGVuYW1lIHdpbGwgYmUgY3JlYXRlZAogICAgICogQHBhcmFtIHN0cmluZyAkcHJlZml4IFRoZSBwcmVmaXggb2YgdGhlIGdlbmVyYXRlZCB0ZW1wb3JhcnkgZmlsZW5hbWUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICBOb3RlOiBXaW5kb3dzIHVzZXMgb25seSB0aGUgZmlyc3QgdGhyZWUgY2hhcmFjdGVycyBvZiBwcmVmaXgKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgbmV3IHRlbXBvcmFyeSBmaWxlbmFtZSAod2l0aCBwYXRoKSwgb3IgdGhyb3cgYW4gZXhjZXB0aW9uIG9uIGZhaWx1cmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRlbXBuYW0oJGRpciwgJHByZWZpeCkKICAgIHsKICAgICAgICBsaXN0KCRzY2hlbWUsICRoaWVyYXJjaHkpID0gJHRoaXMtPmdldFNjaGVtZUFuZEhpZXJhcmNoeSgkZGlyKTsKCiAgICAgICAgLy8gSWYgbm8gc2NoZW1lIG9yIHNjaGVtZSBpcyAiZmlsZSIgb3IgImdzIiAoR29vZ2xlIENsb3VkKSBjcmVhdGUgdGVtcCBmaWxlIGluIGxvY2FsIGZpbGVzeXN0ZW0KICAgICAgICBpZiAobnVsbCA9PT0gJHNjaGVtZSB8fCAnZmlsZScgPT09ICRzY2hlbWUgfHwgJ2dzJyA9PT0gJHNjaGVtZSkgewogICAgICAgICAgICAkdG1wRmlsZSA9IEB0ZW1wbmFtKCRoaWVyYXJjaHksICRwcmVmaXgpOwoKICAgICAgICAgICAgLy8gSWYgdGVtcG5hbSBmYWlsZWQgb3Igbm8gc2NoZW1lIHJldHVybiB0aGUgZmlsZW5hbWUgb3RoZXJ3aXNlIHByZXBlbmQgdGhlIHNjaGVtZQogICAgICAgICAgICBpZiAoZmFsc2UgIT09ICR0bXBGaWxlKSB7CiAgICAgICAgICAgICAgICBpZiAobnVsbCAhPT0gJHNjaGVtZSAmJiAnZ3MnICE9PSAkc2NoZW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRzY2hlbWUuJzovLycuJHRtcEZpbGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0bXBGaWxlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oJ0EgdGVtcG9yYXJ5IGZpbGUgY291bGQgbm90IGJlIGNyZWF0ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBMb29wIHVudGlsIHdlIGNyZWF0ZSBhIHZhbGlkIHRlbXAgZmlsZSBvciBoYXZlIHJlYWNoZWQgMTAgYXR0ZW1wdHMKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAxMDsgKyskaSkgewogICAgICAgICAgICAvLyBDcmVhdGUgYSB1bmlxdWUgZmlsZW5hbWUKICAgICAgICAgICAgJHRtcEZpbGUgPSAkZGlyLicvJy4kcHJlZml4LnVuaXFpZChtdF9yYW5kKCksIHRydWUpOwoKICAgICAgICAgICAgLy8gVXNlIGZvcGVuIGluc3RlYWQgb2YgZmlsZV9leGlzdHMgYXMgc29tZSBzdHJlYW1zIGRvIG5vdCBzdXBwb3J0IHN0YXQKICAgICAgICAgICAgLy8gVXNlIG1vZGUgJ3grJyB0byBhdG9taWNhbGx5IGNoZWNrIGV4aXN0ZW5jZSBhbmQgY3JlYXRlIHRvIGF2b2lkIGEgVE9DVE9VIHZ1bG5lcmFiaWxpdHkKICAgICAgICAgICAgJGhhbmRsZSA9IEBmb3BlbigkdG1wRmlsZSwgJ3grJyk7CgogICAgICAgICAgICAvLyBJZiB1bnN1Y2Nlc3NmdWwgcmVzdGFydCB0aGUgbG9vcAogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRoYW5kbGUpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDbG9zZSB0aGUgZmlsZSBpZiBpdCB3YXMgc3VjY2Vzc2Z1bGx5IG9wZW5lZAogICAgICAgICAgICBAZmNsb3NlKCRoYW5kbGUpOwoKICAgICAgICAgICAgcmV0dXJuICR0bXBGaWxlOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCdBIHRlbXBvcmFyeSBmaWxlIGNvdWxkIG5vdCBiZSBjcmVhdGVkLicpOwogICAgfQoKICAgIC8qKgogICAgICogQXRvbWljYWxseSBkdW1wcyBjb250ZW50IGludG8gYSBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVuYW1lIFRoZSBmaWxlIHRvIGJlIHdyaXR0ZW4gdG8KICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnQgIFRoZSBkYXRhIHRvIHdyaXRlIGludG8gdGhlIGZpbGUKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBmaWxlIGNhbm5vdCBiZSB3cml0dGVuIHRvCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkdW1wRmlsZSgkZmlsZW5hbWUsICRjb250ZW50KQogICAgewogICAgICAgICRkaXIgPSBcZGlybmFtZSgkZmlsZW5hbWUpOwoKICAgICAgICBpZiAoIWlzX2RpcigkZGlyKSkgewogICAgICAgICAgICAkdGhpcy0+bWtkaXIoJGRpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCRkaXIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdVbmFibGUgdG8gd3JpdGUgdG8gdGhlICIlcyIgZGlyZWN0b3J5LicsICRkaXIpLCAwLCBudWxsLCAkZGlyKTsKICAgICAgICB9CgogICAgICAgIC8vIFdpbGwgY3JlYXRlIGEgdGVtcCBmaWxlIHdpdGggMDYwMCBhY2Nlc3MgcmlnaHRzCiAgICAgICAgLy8gd2hlbiB0aGUgZmlsZXN5c3RlbSBzdXBwb3J0cyBjaG1vZC4KICAgICAgICAkdG1wRmlsZSA9ICR0aGlzLT50ZW1wbmFtKCRkaXIsIGJhc2VuYW1lKCRmaWxlbmFtZSkpOwoKICAgICAgICBpZiAoZmFsc2UgPT09IEBmaWxlX3B1dF9jb250ZW50cygkdG1wRmlsZSwgJGNvbnRlbnQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gd3JpdGUgZmlsZSAiJXMiLicsICRmaWxlbmFtZSksIDAsIG51bGwsICRmaWxlbmFtZSk7CiAgICAgICAgfQoKICAgICAgICBAY2htb2QoJHRtcEZpbGUsIGZpbGVfZXhpc3RzKCRmaWxlbmFtZSkgPyBmaWxlcGVybXMoJGZpbGVuYW1lKSA6IDA2NjYgJiB+dW1hc2soKSk7CgogICAgICAgICR0aGlzLT5yZW5hbWUoJHRtcEZpbGUsICRmaWxlbmFtZSwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBcHBlbmRzIGNvbnRlbnQgdG8gYW4gZXhpc3RpbmcgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlbmFtZSBUaGUgZmlsZSB0byB3aGljaCB0byBhcHBlbmQgY29udGVudAogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudCAgVGhlIGNvbnRlbnQgdG8gYXBwZW5kCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiB0aGUgZmlsZSBpcyBub3Qgd3JpdGFibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZFRvRmlsZSgkZmlsZW5hbWUsICRjb250ZW50KQogICAgewogICAgICAgICRkaXIgPSBcZGlybmFtZSgkZmlsZW5hbWUpOwoKICAgICAgICBpZiAoIWlzX2RpcigkZGlyKSkgewogICAgICAgICAgICAkdGhpcy0+bWtkaXIoJGRpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCRkaXIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdVbmFibGUgdG8gd3JpdGUgdG8gdGhlICIlcyIgZGlyZWN0b3J5LicsICRkaXIpLCAwLCBudWxsLCAkZGlyKTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gQGZpbGVfcHV0X2NvbnRlbnRzKCRmaWxlbmFtZSwgJGNvbnRlbnQsIFxGSUxFX0FQUEVORCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byB3cml0ZSBmaWxlICIlcyIuJywgJGZpbGVuYW1lKSwgMCwgbnVsbCwgJGZpbGVuYW1lKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGZpbGVzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxcVHJhdmVyc2FibGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB0b0l0ZXJhYmxlKCRmaWxlcykKICAgIHsKICAgICAgICByZXR1cm4gXGlzX2FycmF5KCRmaWxlcykgfHwgJGZpbGVzIGluc3RhbmNlb2YgXFRyYXZlcnNhYmxlID8gJGZpbGVzIDogWyRmaWxlc107CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGEgMi10dXBsZSBvZiBzY2hlbWUgKG1heSBiZSBudWxsKSBhbmQgaGllcmFyY2hpY2FsIHBhcnQgb2YgYSBmaWxlbmFtZSAoZS5nLiBmaWxlOi8vL3RtcCAtPiBbZmlsZSwgdG1wXSkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZW5hbWUgVGhlIGZpbGVuYW1lIHRvIGJlIHBhcnNlZAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVGhlIGZpbGVuYW1lIHNjaGVtZSBhbmQgaGllcmFyY2hpY2FsIHBhcnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRTY2hlbWVBbmRIaWVyYXJjaHkoJGZpbGVuYW1lKQogICAgewogICAgICAgICRjb21wb25lbnRzID0gZXhwbG9kZSgnOi8vJywgJGZpbGVuYW1lLCAyKTsKCiAgICAgICAgcmV0dXJuIDIgPT09IFxjb3VudCgkY29tcG9uZW50cykgPyBbJGNvbXBvbmVudHNbMF0sICRjb21wb25lbnRzWzFdXSA6IFtudWxsLCAkY29tcG9uZW50c1swXV07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGZ1bmMKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGJveCgkZnVuYykKICAgIHsKICAgICAgICBzZWxmOjokbGFzdEVycm9yID0gbnVsbDsKICAgICAgICBzZXRfZXJyb3JfaGFuZGxlcihfX0NMQVNTX18uJzo6aGFuZGxlRXJyb3InKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcmVzdWx0ID0gXGNhbGxfdXNlcl9mdW5jX2FycmF5KCRmdW5jLCBcYXJyYXlfc2xpY2UoXGZ1bmNfZ2V0X2FyZ3MoKSwgMSkpOwogICAgICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGUpIHsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgfQogICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKICAgICAgICB0aHJvdyAkZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGhhbmRsZUVycm9yKCR0eXBlLCAkbXNnKQogICAgewogICAgICAgIHNlbGY6OiRsYXN0RXJyb3IgPSAkbXNnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXBlbmRlbmN5SW5qZWN0aW9uOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kTG9hZGVyXENvbnRhaW5lckNvbW1hbmRMb2FkZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxEZXBlbmRlbmN5SW5qZWN0aW9uXENvbXBpbGVyXENvbXBpbGVyUGFzc0ludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XERlcGVuZGVuY3lJbmplY3Rpb25cQ29tcGlsZXJcU2VydmljZUxvY2F0b3JUYWdQYXNzOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRGVwZW5kZW5jeUluamVjdGlvblxDb250YWluZXJCdWlsZGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRGVwZW5kZW5jeUluamVjdGlvblxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRGVwZW5kZW5jeUluamVjdGlvblxUeXBlZFJlZmVyZW5jZTsKCi8qKgogKiBSZWdpc3RlcnMgY29uc29sZSBjb21tYW5kcy4KICoKICogQGF1dGhvciBHcsOpZ29pcmUgUGluZWF1IDxseXJpeHhAbHlyaXh4LmluZm8+CiAqLwpjbGFzcyBBZGRDb25zb2xlQ29tbWFuZFBhc3MgaW1wbGVtZW50cyBDb21waWxlclBhc3NJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkY29tbWFuZExvYWRlclNlcnZpY2VJZDsKICAgIHByaXZhdGUgJGNvbW1hbmRUYWc7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb21tYW5kTG9hZGVyU2VydmljZUlkID0gJ2NvbnNvbGUuY29tbWFuZF9sb2FkZXInLCAkY29tbWFuZFRhZyA9ICdjb25zb2xlLmNvbW1hbmQnKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kTG9hZGVyU2VydmljZUlkID0gJGNvbW1hbmRMb2FkZXJTZXJ2aWNlSWQ7CiAgICAgICAgJHRoaXMtPmNvbW1hbmRUYWcgPSAkY29tbWFuZFRhZzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyhDb250YWluZXJCdWlsZGVyICRjb250YWluZXIpCiAgICB7CiAgICAgICAgJGNvbW1hbmRTZXJ2aWNlcyA9ICRjb250YWluZXItPmZpbmRUYWdnZWRTZXJ2aWNlSWRzKCR0aGlzLT5jb21tYW5kVGFnLCB0cnVlKTsKICAgICAgICAkbGF6eUNvbW1hbmRNYXAgPSBbXTsKICAgICAgICAkbGF6eUNvbW1hbmRSZWZzID0gW107CiAgICAgICAgJHNlcnZpY2VJZHMgPSBbXTsKICAgICAgICAkbGF6eVNlcnZpY2VJZHMgPSBbXTsKCiAgICAgICAgZm9yZWFjaCAoJGNvbW1hbmRTZXJ2aWNlcyBhcyAkaWQgPT4gJHRhZ3MpIHsKICAgICAgICAgICAgJGRlZmluaXRpb24gPSAkY29udGFpbmVyLT5nZXREZWZpbml0aW9uKCRpZCk7CiAgICAgICAgICAgICRjbGFzcyA9ICRjb250YWluZXItPmdldFBhcmFtZXRlckJhZygpLT5yZXNvbHZlVmFsdWUoJGRlZmluaXRpb24tPmdldENsYXNzKCkpOwoKICAgICAgICAgICAgJGNvbW1hbmRJZCA9ICdjb25zb2xlLmNvbW1hbmQuJy5zdHJ0b2xvd2VyKHN0cl9yZXBsYWNlKCdcXCcsICdfJywgJGNsYXNzKSk7CgogICAgICAgICAgICBpZiAoaXNzZXQoJHRhZ3NbMF1bJ2NvbW1hbmQnXSkpIHsKICAgICAgICAgICAgICAgICRjb21tYW5kTmFtZSA9ICR0YWdzWzBdWydjb21tYW5kJ107CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoISRyID0gJGNvbnRhaW5lci0+Z2V0UmVmbGVjdGlvbkNsYXNzKCRjbGFzcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0NsYXNzICIlcyIgdXNlZCBmb3Igc2VydmljZSAiJXMiIGNhbm5vdCBiZSBmb3VuZC4nLCAkY2xhc3MsICRpZCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCEkci0+aXNTdWJjbGFzc09mKENvbW1hbmQ6OmNsYXNzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIHNlcnZpY2UgIiVzIiB0YWdnZWQgIiVzIiBtdXN0IGJlIGEgc3ViY2xhc3Mgb2YgIiVzIi4nLCAkaWQsICR0aGlzLT5jb21tYW5kVGFnLCBDb21tYW5kOjpjbGFzcykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvbW1hbmROYW1lID0gJGNsYXNzOjpnZXREZWZhdWx0TmFtZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobnVsbCA9PT0gJGNvbW1hbmROYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNlcnZpY2VJZHNbJGNvbW1hbmRJZF0pIHx8ICRjb250YWluZXItPmhhc0FsaWFzKCRjb21tYW5kSWQpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmRJZCA9ICRjb21tYW5kSWQuJ18nLiRpZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghJGRlZmluaXRpb24tPmlzUHVibGljKCkgfHwgJGRlZmluaXRpb24tPmlzUHJpdmF0ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbnRhaW5lci0+c2V0QWxpYXMoJGNvbW1hbmRJZCwgJGlkKS0+c2V0UHVibGljKHRydWUpOwogICAgICAgICAgICAgICAgICAgICRpZCA9ICRjb21tYW5kSWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkc2VydmljZUlkc1skY29tbWFuZElkXSA9ICRpZDsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHNlcnZpY2VJZHNbJGNvbW1hbmRJZF0gPSAkaWQ7CiAgICAgICAgICAgICRsYXp5U2VydmljZUlkc1skaWRdID0gdHJ1ZTsKICAgICAgICAgICAgdW5zZXQoJHRhZ3NbMF0pOwogICAgICAgICAgICAkbGF6eUNvbW1hbmRNYXBbJGNvbW1hbmROYW1lXSA9ICRpZDsKICAgICAgICAgICAgJGxhenlDb21tYW5kUmVmc1skaWRdID0gbmV3IFR5cGVkUmVmZXJlbmNlKCRpZCwgJGNsYXNzKTsKICAgICAgICAgICAgJGFsaWFzZXMgPSBbXTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCR0YWdzIGFzICR0YWcpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGFnWydjb21tYW5kJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGFsaWFzZXNbXSA9ICR0YWdbJ2NvbW1hbmQnXTsKICAgICAgICAgICAgICAgICAgICAkbGF6eUNvbW1hbmRNYXBbJHRhZ1snY29tbWFuZCddXSA9ICRpZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRlZmluaXRpb24tPmFkZE1ldGhvZENhbGwoJ3NldE5hbWUnLCBbJGNvbW1hbmROYW1lXSk7CgogICAgICAgICAgICBpZiAoJGFsaWFzZXMpIHsKICAgICAgICAgICAgICAgICRkZWZpbml0aW9uLT5hZGRNZXRob2RDYWxsKCdzZXRBbGlhc2VzJywgWyRhbGlhc2VzXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb250YWluZXIKICAgICAgICAgICAgLT5yZWdpc3RlcigkdGhpcy0+Y29tbWFuZExvYWRlclNlcnZpY2VJZCwgQ29udGFpbmVyQ29tbWFuZExvYWRlcjo6Y2xhc3MpCiAgICAgICAgICAgIC0+c2V0UHVibGljKHRydWUpCiAgICAgICAgICAgIC0+c2V0QXJndW1lbnRzKFtTZXJ2aWNlTG9jYXRvclRhZ1Bhc3M6OnJlZ2lzdGVyKCRjb250YWluZXIsICRsYXp5Q29tbWFuZFJlZnMpLCAkbGF6eUNvbW1hbmRNYXBdKTsKCiAgICAgICAgJGNvbnRhaW5lci0+c2V0UGFyYW1ldGVyKCdjb25zb2xlLmNvbW1hbmQuaWRzJywgJHNlcnZpY2VJZHMpOwogICAgICAgICRjb250YWluZXItPnNldFBhcmFtZXRlcignY29uc29sZS5sYXp5X2NvbW1hbmQuaWRzJywgJGxhenlTZXJ2aWNlSWRzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CgovKioKICogQSBJbnB1dERlZmluaXRpb24gcmVwcmVzZW50cyBhIHNldCBvZiB2YWxpZCBjb21tYW5kIGxpbmUgYXJndW1lbnRzIGFuZCBvcHRpb25zLgogKgogKiBVc2FnZToKICoKICogICAgICRkZWZpbml0aW9uID0gbmV3IElucHV0RGVmaW5pdGlvbihbCiAqICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ25hbWUnLCBJbnB1dEFyZ3VtZW50OjpSRVFVSVJFRCksCiAqICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmb28nLCAnZicsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCksCiAqICAgICBdKTsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBJbnB1dERlZmluaXRpb24KewogICAgcHJpdmF0ZSAkYXJndW1lbnRzOwogICAgcHJpdmF0ZSAkcmVxdWlyZWRDb3VudDsKICAgIHByaXZhdGUgJGhhc0FuQXJyYXlBcmd1bWVudCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkaGFzT3B0aW9uYWw7CiAgICBwcml2YXRlICRvcHRpb25zOwogICAgcHJpdmF0ZSAkc2hvcnRjdXRzOwoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICRkZWZpbml0aW9uIEFuIGFycmF5IG9mIElucHV0QXJndW1lbnQgYW5kIElucHV0T3B0aW9uIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZGVmaW5pdGlvbiA9IFtdKQogICAgewogICAgICAgICR0aGlzLT5zZXREZWZpbml0aW9uKCRkZWZpbml0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlZmluaXRpb24gb2YgdGhlIGlucHV0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVmaW5pdGlvbihhcnJheSAkZGVmaW5pdGlvbikKICAgIHsKICAgICAgICAkYXJndW1lbnRzID0gW107CiAgICAgICAgJG9wdGlvbnMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbiBhcyAkaXRlbSkgewogICAgICAgICAgICBpZiAoJGl0ZW0gaW5zdGFuY2VvZiBJbnB1dE9wdGlvbikgewogICAgICAgICAgICAgICAgJG9wdGlvbnNbXSA9ICRpdGVtOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGFyZ3VtZW50c1tdID0gJGl0ZW07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXRBcmd1bWVudHMoJGFyZ3VtZW50cyk7CiAgICAgICAgJHRoaXMtPnNldE9wdGlvbnMoJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgSW5wdXRBcmd1bWVudCBvYmplY3RzLgogICAgICoKICAgICAqIEBwYXJhbSBJbnB1dEFyZ3VtZW50W10gJGFyZ3VtZW50cyBBbiBhcnJheSBvZiBJbnB1dEFyZ3VtZW50IG9iamVjdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyZ3VtZW50cygkYXJndW1lbnRzID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50cyA9IFtdOwogICAgICAgICR0aGlzLT5yZXF1aXJlZENvdW50ID0gMDsKICAgICAgICAkdGhpcy0+aGFzT3B0aW9uYWwgPSBmYWxzZTsKICAgICAgICAkdGhpcy0+aGFzQW5BcnJheUFyZ3VtZW50ID0gZmFsc2U7CiAgICAgICAgJHRoaXMtPmFkZEFyZ3VtZW50cygkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYW4gYXJyYXkgb2YgSW5wdXRBcmd1bWVudCBvYmplY3RzLgogICAgICoKICAgICAqIEBwYXJhbSBJbnB1dEFyZ3VtZW50W10gJGFyZ3VtZW50cyBBbiBhcnJheSBvZiBJbnB1dEFyZ3VtZW50IG9iamVjdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEFyZ3VtZW50cygkYXJndW1lbnRzID0gW10pCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRhcmd1bWVudHMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGFyZ3VtZW50cyBhcyAkYXJndW1lbnQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRBcmd1bWVudCgkYXJndW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBXaGVuIGluY29ycmVjdCBhcmd1bWVudCBpcyBnaXZlbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQXJndW1lbnQoSW5wdXRBcmd1bWVudCAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hcmd1bWVudHNbJGFyZ3VtZW50LT5nZXROYW1lKCldKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oc3ByaW50ZignQW4gYXJndW1lbnQgd2l0aCBuYW1lICIlcyIgYWxyZWFkeSBleGlzdHMuJywgJGFyZ3VtZW50LT5nZXROYW1lKCkpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aGFzQW5BcnJheUFyZ3VtZW50KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQ2Fubm90IGFkZCBhbiBhcmd1bWVudCBhZnRlciBhbiBhcnJheSBhcmd1bWVudC4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkYXJndW1lbnQtPmlzUmVxdWlyZWQoKSAmJiAkdGhpcy0+aGFzT3B0aW9uYWwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdDYW5ub3QgYWRkIGEgcmVxdWlyZWQgYXJndW1lbnQgYWZ0ZXIgYW4gb3B0aW9uYWwgb25lLicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRhcmd1bWVudC0+aXNBcnJheSgpKSB7CiAgICAgICAgICAgICR0aGlzLT5oYXNBbkFycmF5QXJndW1lbnQgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRhcmd1bWVudC0+aXNSZXF1aXJlZCgpKSB7CiAgICAgICAgICAgICsrJHRoaXMtPnJlcXVpcmVkQ291bnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmhhc09wdGlvbmFsID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hcmd1bWVudHNbJGFyZ3VtZW50LT5nZXROYW1lKCldID0gJGFyZ3VtZW50OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBJbnB1dEFyZ3VtZW50IGJ5IG5hbWUgb3IgYnkgcG9zaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJG5hbWUgVGhlIElucHV0QXJndW1lbnQgbmFtZSBvciBwb3NpdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXRBcmd1bWVudCBBbiBJbnB1dEFyZ3VtZW50IG9iamVjdAogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gYXJndW1lbnQgZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzQXJndW1lbnQoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlICIlcyIgYXJndW1lbnQgZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICRhcmd1bWVudHMgPSBcaXNfaW50KCRuYW1lKSA/IGFycmF5X3ZhbHVlcygkdGhpcy0+YXJndW1lbnRzKSA6ICR0aGlzLT5hcmd1bWVudHM7CgogICAgICAgIHJldHVybiAkYXJndW1lbnRzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhbiBJbnB1dEFyZ3VtZW50IG9iamVjdCBleGlzdHMgYnkgbmFtZSBvciBwb3NpdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkbmFtZSBUaGUgSW5wdXRBcmd1bWVudCBuYW1lIG9yIHBvc2l0aW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIElucHV0QXJndW1lbnQgb2JqZWN0IGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNBcmd1bWVudCgkbmFtZSkKICAgIHsKICAgICAgICAkYXJndW1lbnRzID0gXGlzX2ludCgkbmFtZSkgPyBhcnJheV92YWx1ZXMoJHRoaXMtPmFyZ3VtZW50cykgOiAkdGhpcy0+YXJndW1lbnRzOwoKICAgICAgICByZXR1cm4gaXNzZXQoJGFyZ3VtZW50c1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgYXJyYXkgb2YgSW5wdXRBcmd1bWVudCBvYmplY3RzLgogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXRBcmd1bWVudFtdIEFuIGFycmF5IG9mIElucHV0QXJndW1lbnQgb2JqZWN0cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50czsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBJbnB1dEFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgbnVtYmVyIG9mIElucHV0QXJndW1lbnRzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudENvdW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc0FuQXJyYXlBcmd1bWVudCA/IFxQSFBfSU5UX01BWCA6IFxjb3VudCgkdGhpcy0+YXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiByZXF1aXJlZCBJbnB1dEFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgbnVtYmVyIG9mIHJlcXVpcmVkIElucHV0QXJndW1lbnRzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudFJlcXVpcmVkQ291bnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVxdWlyZWRDb3VudDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gYXJyYXkgb2YgZGVmYXVsdCB2YWx1ZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50RGVmYXVsdHMoKQogICAgewogICAgICAgICR2YWx1ZXMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXJndW1lbnRzIGFzICRhcmd1bWVudCkgewogICAgICAgICAgICAkdmFsdWVzWyRhcmd1bWVudC0+Z2V0TmFtZSgpXSA9ICRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWx1ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBJbnB1dE9wdGlvbiBvYmplY3RzLgogICAgICoKICAgICAqIEBwYXJhbSBJbnB1dE9wdGlvbltdICRvcHRpb25zIEFuIGFycmF5IG9mIElucHV0T3B0aW9uIG9iamVjdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbnMoJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+b3B0aW9ucyA9IFtdOwogICAgICAgICR0aGlzLT5zaG9ydGN1dHMgPSBbXTsKICAgICAgICAkdGhpcy0+YWRkT3B0aW9ucygkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGFuIGFycmF5IG9mIElucHV0T3B0aW9uIG9iamVjdHMuCiAgICAgKgogICAgICogQHBhcmFtIElucHV0T3B0aW9uW10gJG9wdGlvbnMgQW4gYXJyYXkgb2YgSW5wdXRPcHRpb24gb2JqZWN0cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkT3B0aW9ucygkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGZvcmVhY2ggKCRvcHRpb25zIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgJHRoaXMtPmFkZE9wdGlvbigkb3B0aW9uKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIFdoZW4gb3B0aW9uIGdpdmVuIGFscmVhZHkgZXhpc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+b3B0aW9uc1skb3B0aW9uLT5nZXROYW1lKCldKSAmJiAhJG9wdGlvbi0+ZXF1YWxzKCR0aGlzLT5vcHRpb25zWyRvcHRpb24tPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdBbiBvcHRpb24gbmFtZWQgIiVzIiBhbHJlYWR5IGV4aXN0cy4nLCAkb3B0aW9uLT5nZXROYW1lKCkpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKGV4cGxvZGUoJ3wnLCAkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSBhcyAkc2hvcnRjdXQpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+c2hvcnRjdXRzWyRzaG9ydGN1dF0pICYmICEkb3B0aW9uLT5lcXVhbHMoJHRoaXMtPm9wdGlvbnNbJHRoaXMtPnNob3J0Y3V0c1skc2hvcnRjdXRdXSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oc3ByaW50ZignQW4gb3B0aW9uIHdpdGggc2hvcnRjdXQgIiVzIiBhbHJlYWR5IGV4aXN0cy4nLCAkc2hvcnRjdXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wdGlvbnNbJG9wdGlvbi0+Z2V0TmFtZSgpXSA9ICRvcHRpb247CiAgICAgICAgaWYgKCRvcHRpb24tPmdldFNob3J0Y3V0KCkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnfCcsICRvcHRpb24tPmdldFNob3J0Y3V0KCkpIGFzICRzaG9ydGN1dCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnNob3J0Y3V0c1skc2hvcnRjdXRdID0gJG9wdGlvbi0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBJbnB1dE9wdGlvbiBieSBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIElucHV0T3B0aW9uIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0T3B0aW9uIEEgSW5wdXRPcHRpb24gb2JqZWN0CiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9uKCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc09wdGlvbigkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0tJXMiIG9wdGlvbiBkb2VzIG5vdCBleGlzdC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5vcHRpb25zWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhbiBJbnB1dE9wdGlvbiBvYmplY3QgZXhpc3RzIGJ5IG5hbWUuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgY2FuJ3QgYmUgdXNlZCB0byBjaGVjayBpZiB0aGUgdXNlciBpbmNsdWRlZCB0aGUgb3B0aW9uIHdoZW4KICAgICAqIGV4ZWN1dGluZyB0aGUgY29tbWFuZCAodXNlIGdldE9wdGlvbigpIGluc3RlYWQpLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIElucHV0T3B0aW9uIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNPcHRpb24oJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5vcHRpb25zWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBJbnB1dE9wdGlvbiBvYmplY3RzLgogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXRPcHRpb25bXSBBbiBhcnJheSBvZiBJbnB1dE9wdGlvbiBvYmplY3RzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cyBieSBzaG9ydGN1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBJbnB1dE9wdGlvbiBzaG9ydGN1dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBJbnB1dE9wdGlvbiBvYmplY3QgZXhpc3RzLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1Nob3J0Y3V0KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+c2hvcnRjdXRzWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGFuIElucHV0T3B0aW9uIGJ5IHNob3J0Y3V0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNob3J0Y3V0IFRoZSBTaG9ydGN1dCBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBJbnB1dE9wdGlvbiBBbiBJbnB1dE9wdGlvbiBvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbkZvclNob3J0Y3V0KCRzaG9ydGN1dCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldE9wdGlvbigkdGhpcy0+c2hvcnRjdXRUb05hbWUoJHNob3J0Y3V0KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGFuIGFycmF5IG9mIGRlZmF1bHQgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gYXJyYXkgb2YgYWxsIGRlZmF1bHQgdmFsdWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb25EZWZhdWx0cygpCiAgICB7CiAgICAgICAgJHZhbHVlcyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5vcHRpb25zIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgJHZhbHVlc1skb3B0aW9uLT5nZXROYW1lKCldID0gJG9wdGlvbi0+Z2V0RGVmYXVsdCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWx1ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBJbnB1dE9wdGlvbiBuYW1lIGdpdmVuIGEgc2hvcnRjdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc2hvcnRjdXQgVGhlIHNob3J0Y3V0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIElucHV0T3B0aW9uIG5hbWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2VzIG5vdCBleGlzdAogICAgICoKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hvcnRjdXRUb05hbWUoJHNob3J0Y3V0KQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnNob3J0Y3V0c1skc2hvcnRjdXRdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJHNob3J0Y3V0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnNob3J0Y3V0c1skc2hvcnRjdXRdOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgc3lub3BzaXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHNob3J0IFdoZXRoZXIgdG8gcmV0dXJuIHRoZSBzaG9ydCB2ZXJzaW9uICh3aXRoIG9wdGlvbnMgZm9sZGVkKSBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgc3lub3BzaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN5bm9wc2lzKCRzaG9ydCA9IGZhbHNlKQogICAgewogICAgICAgICRlbGVtZW50cyA9IFtdOwoKICAgICAgICBpZiAoJHNob3J0ICYmICR0aGlzLT5nZXRPcHRpb25zKCkpIHsKICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAnW29wdGlvbnNdJzsKICAgICAgICB9IGVsc2VpZiAoISRzaG9ydCkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0T3B0aW9ucygpIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICcnOwogICAgICAgICAgICAgICAgaWYgKCRvcHRpb24tPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAnICVzJXMlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICRvcHRpb24tPmlzVmFsdWVPcHRpb25hbCgpID8gJ1snIDogJycsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cnRvdXBwZXIoJG9wdGlvbi0+Z2V0TmFtZSgpKSwKICAgICAgICAgICAgICAgICAgICAgICAgJG9wdGlvbi0+aXNWYWx1ZU9wdGlvbmFsKCkgPyAnXScgOiAnJwogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHNob3J0Y3V0ID0gJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSA/IHNwcmludGYoJy0lc3wnLCAkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSA6ICcnOwogICAgICAgICAgICAgICAgJGVsZW1lbnRzW10gPSBzcHJpbnRmKCdbJXMtLSVzJXNdJywgJHNob3J0Y3V0LCAkb3B0aW9uLT5nZXROYW1lKCksICR2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChcY291bnQoJGVsZW1lbnRzKSAmJiAkdGhpcy0+Z2V0QXJndW1lbnRzKCkpIHsKICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAnWy0tXSc7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICRlbGVtZW50ID0gJzwnLiRhcmd1bWVudC0+Z2V0TmFtZSgpLic+JzsKICAgICAgICAgICAgaWYgKCEkYXJndW1lbnQtPmlzUmVxdWlyZWQoKSkgewogICAgICAgICAgICAgICAgJGVsZW1lbnQgPSAnWycuJGVsZW1lbnQuJ10nOwogICAgICAgICAgICB9IGVsc2VpZiAoJGFyZ3VtZW50LT5pc0FycmF5KCkpIHsKICAgICAgICAgICAgICAgICRlbGVtZW50IC49ICcgKCcuJGVsZW1lbnQuJyknOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGFyZ3VtZW50LT5pc0FycmF5KCkpIHsKICAgICAgICAgICAgICAgICRlbGVtZW50IC49ICcuLi4nOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZWxlbWVudHNbXSA9ICRlbGVtZW50OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGltcGxvZGUoJyAnLCAkZWxlbWVudHMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogU3RyaW5nSW5wdXQgcmVwcmVzZW50cyBhbiBpbnB1dCBwcm92aWRlZCBhcyBhIHN0cmluZy4KICoKICogVXNhZ2U6CiAqCiAqICAgICAkaW5wdXQgPSBuZXcgU3RyaW5nSW5wdXQoJ2ZvbyAtLWJhcj0iZm9vYmFyIicpOwogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIFN0cmluZ0lucHV0IGV4dGVuZHMgQXJndklucHV0CnsKICAgIGNvbnN0IFJFR0VYX1NUUklORyA9ICcoW15cc10rPykoPzpcc3woPzwhXFxcXCkifCg/PCFcXFxcKVwnfCQpJzsKICAgIGNvbnN0IFJFR0VYX1FVT1RFRF9TVFJJTkcgPSAnKD86IihbXiJcXFxcXSooPzpcXFxcLlteIlxcXFxdKikqKSJ8XCcoW15cJ1xcXFxdKig/OlxcXFwuW15cJ1xcXFxdKikqKVwnKSc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnB1dCBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHBhcmFtZXRlcnMgZnJvbSB0aGUgQ0xJCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5wdXQpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChbXSk7CgogICAgICAgICR0aGlzLT5zZXRUb2tlbnMoJHRoaXMtPnRva2VuaXplKCRpbnB1dCkpOwogICAgfQoKICAgIC8qKgogICAgICogVG9rZW5pemVzIGEgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFRoZSBpbnB1dCB0byB0b2tlbml6ZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gYXJyYXkgb2YgdG9rZW5zCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiB1bmFibGUgdG8gcGFyc2UgaW5wdXQgKHNob3VsZCBuZXZlciBoYXBwZW4pCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdG9rZW5pemUoJGlucHV0KQogICAgewogICAgICAgICR0b2tlbnMgPSBbXTsKICAgICAgICAkbGVuZ3RoID0gXHN0cmxlbigkaW5wdXQpOwogICAgICAgICRjdXJzb3IgPSAwOwogICAgICAgIHdoaWxlICgkY3Vyc29yIDwgJGxlbmd0aCkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL1xzKy9BJywgJGlucHV0LCAkbWF0Y2gsIG51bGwsICRjdXJzb3IpKSB7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvKFtePSJcJ1xzXSs/KSg9PykoJy5zZWxmOjpSRUdFWF9RVU9URURfU1RSSU5HLicrKS9BJywgJGlucHV0LCAkbWF0Y2gsIG51bGwsICRjdXJzb3IpKSB7CiAgICAgICAgICAgICAgICAkdG9rZW5zW10gPSAkbWF0Y2hbMV0uJG1hdGNoWzJdLnN0cmlwY3NsYXNoZXMoc3RyX3JlcGxhY2UoWyciXCcnLCAnXCciJywgJ1wnXCcnLCAnIiInXSwgJycsIHN1YnN0cigkbWF0Y2hbM10sIDEsIFxzdHJsZW4oJG1hdGNoWzNdKSAtIDIpKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvJy5zZWxmOjpSRUdFWF9RVU9URURfU1RSSU5HLicvQScsICRpbnB1dCwgJG1hdGNoLCBudWxsLCAkY3Vyc29yKSkgewogICAgICAgICAgICAgICAgJHRva2Vuc1tdID0gc3RyaXBjc2xhc2hlcyhzdWJzdHIoJG1hdGNoWzBdLCAxLCBcc3RybGVuKCRtYXRjaFswXSkgLSAyKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvJy5zZWxmOjpSRUdFWF9TVFJJTkcuJy9BJywgJGlucHV0LCAkbWF0Y2gsIG51bGwsICRjdXJzb3IpKSB7CiAgICAgICAgICAgICAgICAkdG9rZW5zW10gPSBzdHJpcGNzbGFzaGVzKCRtYXRjaFsxXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1VuYWJsZSB0byBwYXJzZSBpbnB1dCBuZWFyICIuLi4gJXMgLi4uIi4nLCBzdWJzdHIoJGlucHV0LCAkY3Vyc29yLCAxMCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGN1cnNvciArPSBcc3RybGVuKCRtYXRjaFswXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRva2VuczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhIGNvbW1hbmQgbGluZSBhcmd1bWVudC4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBJbnB1dEFyZ3VtZW50CnsKICAgIGNvbnN0IFJFUVVJUkVEID0gMTsKICAgIGNvbnN0IE9QVElPTkFMID0gMjsKICAgIGNvbnN0IElTX0FSUkFZID0gNDsKCiAgICBwcml2YXRlICRuYW1lOwogICAgcHJpdmF0ZSAkbW9kZTsKICAgIHByaXZhdGUgJGRlZmF1bHQ7CiAgICBwcml2YXRlICRkZXNjcmlwdGlvbjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAkbmFtZSAgICAgICAgVGhlIGFyZ3VtZW50IG5hbWUKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAgICAgICAgICAgICAkbW9kZSAgICAgICAgVGhlIGFyZ3VtZW50IG1vZGU6IHNlbGY6OlJFUVVJUkVEIG9yIHNlbGY6Ok9QVElPTkFMCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uIEEgZGVzY3JpcHRpb24gdGV4dAogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXXxudWxsICRkZWZhdWx0ICAgICBUaGUgZGVmYXVsdCB2YWx1ZSAoZm9yIHNlbGY6Ok9QVElPTkFMIG1vZGUgb25seSkKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGFyZ3VtZW50IG1vZGUgaXMgbm90IHZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJG1vZGUgPSBudWxsLCAkZGVzY3JpcHRpb24gPSAnJywgJGRlZmF1bHQgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkbW9kZSkgewogICAgICAgICAgICAkbW9kZSA9IHNlbGY6Ok9QVElPTkFMOwogICAgICAgIH0gZWxzZWlmICghXGlzX2ludCgkbW9kZSkgfHwgJG1vZGUgPiA3IHx8ICRtb2RlIDwgMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0FyZ3VtZW50IG1vZGUgIiVzIiBpcyBub3QgdmFsaWQuJywgJG1vZGUpKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgJHRoaXMtPm1vZGUgPSAkbW9kZTsKICAgICAgICAkdGhpcy0+ZGVzY3JpcHRpb24gPSAkZGVzY3JpcHRpb247CgogICAgICAgICR0aGlzLT5zZXREZWZhdWx0KCRkZWZhdWx0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFyZ3VtZW50IG5hbWUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGFyZ3VtZW50IG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXJndW1lbnQgaXMgcmVxdWlyZWQuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgcGFyYW1ldGVyIG1vZGUgaXMgc2VsZjo6UkVRVUlSRUQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNSZXF1aXJlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OlJFUVVJUkVEID09PSAoc2VsZjo6UkVRVUlSRUQgJiAkdGhpcy0+bW9kZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGFyZ3VtZW50IGNhbiB0YWtlIG11bHRpcGxlIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiBtb2RlIGlzIHNlbGY6OklTX0FSUkFZLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQXJyYXkoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpJU19BUlJBWSA9PT0gKHNlbGY6OklTX0FSUkFZICYgJHRoaXMtPm1vZGUpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdfG51bGwgJGRlZmF1bHQgVGhlIGRlZmF1bHQgdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIFdoZW4gaW5jb3JyZWN0IGRlZmF1bHQgdmFsdWUgaXMgZ2l2ZW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlZmF1bHQoJGRlZmF1bHQgPSBudWxsKQogICAgewogICAgICAgIGlmIChzZWxmOjpSRVFVSVJFRCA9PT0gJHRoaXMtPm1vZGUgJiYgbnVsbCAhPT0gJGRlZmF1bHQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdDYW5ub3Qgc2V0IGEgZGVmYXVsdCB2YWx1ZSBleGNlcHQgZm9yIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMIG1vZGUuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmlzQXJyYXkoKSkgewogICAgICAgICAgICBpZiAobnVsbCA9PT0gJGRlZmF1bHQpIHsKICAgICAgICAgICAgICAgICRkZWZhdWx0ID0gW107CiAgICAgICAgICAgIH0gZWxzZWlmICghXGlzX2FycmF5KCRkZWZhdWx0KSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdBIGRlZmF1bHQgdmFsdWUgZm9yIGFuIGFycmF5IGFyZ3VtZW50IG11c3QgYmUgYW4gYXJyYXkuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5kZWZhdWx0ID0gJGRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfHN0cmluZ1tdfG51bGwgVGhlIGRlZmF1bHQgdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlZmF1bHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVmYXVsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uIHRleHQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGRlc2NyaXB0aW9uIHRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlc2NyaXB0aW9uOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxSdW50aW1lRXhjZXB0aW9uOwoKLyoqCiAqIElucHV0IGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgY29uY3JldGUgSW5wdXQgY2xhc3Nlcy4KICoKICogVGhyZWUgY29uY3JldGUgY2xhc3NlcyBhcmUgcHJvdmlkZWQgYnkgZGVmYXVsdDoKICoKICogICogYEFyZ3ZJbnB1dGA6IFRoZSBpbnB1dCBjb21lcyBmcm9tIHRoZSBDTEkgYXJndW1lbnRzIChhcmd2KQogKiAgKiBgU3RyaW5nSW5wdXRgOiBUaGUgaW5wdXQgaXMgcHJvdmlkZWQgYXMgYSBzdHJpbmcKICogICogYEFycmF5SW5wdXRgOiBUaGUgaW5wdXQgaXMgcHJvdmlkZWQgYXMgYW4gYXJyYXkKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBJbnB1dCBpbXBsZW1lbnRzIElucHV0SW50ZXJmYWNlLCBTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2UKewogICAgcHJvdGVjdGVkICRkZWZpbml0aW9uOwogICAgcHJvdGVjdGVkICRzdHJlYW07CiAgICBwcm90ZWN0ZWQgJG9wdGlvbnMgPSBbXTsKICAgIHByb3RlY3RlZCAkYXJndW1lbnRzID0gW107CiAgICBwcm90ZWN0ZWQgJGludGVyYWN0aXZlID0gdHJ1ZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGRlZmluaXRpb24pIHsKICAgICAgICAgICAgJHRoaXMtPmRlZmluaXRpb24gPSBuZXcgSW5wdXREZWZpbml0aW9uKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmJpbmQoJGRlZmluaXRpb24pOwogICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGUoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBiaW5kKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+YXJndW1lbnRzID0gW107CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBbXTsKICAgICAgICAkdGhpcy0+ZGVmaW5pdGlvbiA9ICRkZWZpbml0aW9uOwoKICAgICAgICAkdGhpcy0+cGFyc2UoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb2Nlc3NlcyBjb21tYW5kIGxpbmUgYXJndW1lbnRzLgogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2UoKTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkYXRlKCkKICAgIHsKICAgICAgICAkZGVmaW5pdGlvbiA9ICR0aGlzLT5kZWZpbml0aW9uOwogICAgICAgICRnaXZlbkFyZ3VtZW50cyA9ICR0aGlzLT5hcmd1bWVudHM7CgogICAgICAgICRtaXNzaW5nQXJndW1lbnRzID0gYXJyYXlfZmlsdGVyKGFycmF5X2tleXMoJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpKSwgZnVuY3Rpb24gKCRhcmd1bWVudCkgdXNlICgkZGVmaW5pdGlvbiwgJGdpdmVuQXJndW1lbnRzKSB7CiAgICAgICAgICAgIHJldHVybiAhXGFycmF5X2tleV9leGlzdHMoJGFyZ3VtZW50LCAkZ2l2ZW5Bcmd1bWVudHMpICYmICRkZWZpbml0aW9uLT5nZXRBcmd1bWVudCgkYXJndW1lbnQpLT5pc1JlcXVpcmVkKCk7CiAgICAgICAgfSk7CgogICAgICAgIGlmIChcY291bnQoJG1pc3NpbmdBcmd1bWVudHMpID4gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdOb3QgZW5vdWdoIGFyZ3VtZW50cyAobWlzc2luZzogIiVzIikuJywgaW1wbG9kZSgnLCAnLCAkbWlzc2luZ0FyZ3VtZW50cykpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0ludGVyYWN0aXZlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmludGVyYWN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW50ZXJhY3RpdmUoJGludGVyYWN0aXZlKQogICAgewogICAgICAgICR0aGlzLT5pbnRlcmFjdGl2ZSA9IChib29sKSAkaW50ZXJhY3RpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudHMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9tZXJnZSgkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnREZWZhdWx0cygpLCAkdGhpcy0+YXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc0FyZ3VtZW50KCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiJXMiIGFyZ3VtZW50IGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmFyZ3VtZW50c1skbmFtZV0pID8gJHRoaXMtPmFyZ3VtZW50c1skbmFtZV0gOiAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnQoJG5hbWUpLT5nZXREZWZhdWx0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudCgkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc0FyZ3VtZW50KCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiJXMiIGFyZ3VtZW50IGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YXJndW1lbnRzWyRuYW1lXSA9ICR2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0FyZ3VtZW50KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzQXJndW1lbnQoJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKCR0aGlzLT5kZWZpbml0aW9uLT5nZXRPcHRpb25EZWZhdWx0cygpLCAkdGhpcy0+b3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb24oJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzT3B0aW9uKCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiJXMiIG9wdGlvbiBkb2VzIG5vdCBleGlzdC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxhcnJheV9rZXlfZXhpc3RzKCRuYW1lLCAkdGhpcy0+b3B0aW9ucykgPyAkdGhpcy0+b3B0aW9uc1skbmFtZV0gOiAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uKCRuYW1lKS0+Z2V0RGVmYXVsdCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzT3B0aW9uKCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiJXMiIG9wdGlvbiBkb2VzIG5vdCBleGlzdC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wdGlvbnNbJG5hbWVdID0gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzT3B0aW9uKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzT3B0aW9uKCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVzY2FwZXMgYSB0b2tlbiB0aHJvdWdoIGVzY2FwZXNoZWxsYXJnIGlmIGl0IGNvbnRhaW5zIHVuc2FmZSBjaGFycy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0b2tlbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlc2NhcGVUb2tlbigkdG9rZW4pCiAgICB7CiAgICAgICAgcmV0dXJuIHByZWdfbWF0Y2goJ3teW1x3LV0rJH0nLCAkdG9rZW4pID8gJHRva2VuIDogZXNjYXBlc2hlbGxhcmcoJHRva2VuKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0cmVhbSgkc3RyZWFtKQogICAgewogICAgICAgICR0aGlzLT5zdHJlYW0gPSAkc3RyZWFtOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RyZWFtKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0cmVhbTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7CgovKioKICogU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlIGlzIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgYWxsIGlucHV0IGNsYXNzZXMKICogdGhhdCBoYXZlIGFuIGlucHV0IHN0cmVhbS4KICoKICogQGF1dGhvciBSb2JpbiBDaGFsYXMgPHJvYmluLmNoYWxhc0BnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlIGV4dGVuZHMgSW5wdXRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tIHdoZW4gaW50ZXJhY3Rpbmcgd2l0aCB0aGUgdXNlci4KICAgICAqCiAgICAgKiBUaGlzIGlzIG1haW5seSB1c2VmdWwgZm9yIHRlc3RpbmcgcHVycG9zZS4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJHN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHJlYW0oJHN0cmVhbSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnB1dCBzdHJlYW0uCiAgICAgKgogICAgICogQHJldHVybiByZXNvdXJjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdHJlYW0oKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKCi8qKgogKiBJbnB1dEludGVyZmFjZSBpcyB0aGUgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IGFsbCBpbnB1dCBjbGFzc2VzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmludGVyZmFjZSBJbnB1dEludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGZyb20gdGhlIHJhdyBwYXJhbWV0ZXJzIChub3QgcGFyc2VkKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgYXJndW1lbnQgb3IgbnVsbCBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpcnN0QXJndW1lbnQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmF3IHBhcmFtZXRlcnMgKG5vdCBwYXJzZWQpIGNvbnRhaW4gYSB2YWx1ZS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0byBiZSB1c2VkIHRvIGludHJvc3BlY3QgdGhlIGlucHV0IHBhcmFtZXRlcnMKICAgICAqIGJlZm9yZSB0aGV5IGhhdmUgYmVlbiB2YWxpZGF0ZWQuIEl0IG11c3QgYmUgdXNlZCBjYXJlZnVsbHkuCiAgICAgKiBEb2VzIG5vdCBuZWNlc3NhcmlseSByZXR1cm4gdGhlIGNvcnJlY3QgcmVzdWx0IGZvciBzaG9ydCBvcHRpb25zCiAgICAgKiB3aGVuIG11bHRpcGxlIGZsYWdzIGFyZSBjb21iaW5lZCBpbiB0aGUgc2FtZSBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkdmFsdWVzICAgICBUaGUgdmFsdWVzIHRvIGxvb2sgZm9yIGluIHRoZSByYXcgcGFyYW1ldGVycyAoY2FuIGJlIGFuIGFycmF5KQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkb25seVBhcmFtcyBPbmx5IGNoZWNrIHJlYWwgcGFyYW1ldGVycywgc2tpcCB0aG9zZSBmb2xsb3dpbmcgYW4gZW5kIG9mIG9wdGlvbnMgKC0tKSBzaWduYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgaXMgY29udGFpbmVkIGluIHRoZSByYXcgcGFyYW1ldGVycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGFyYW1ldGVyT3B0aW9uKCR2YWx1ZXMsICRvbmx5UGFyYW1zID0gZmFsc2UpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSByYXcgb3B0aW9uIChub3QgcGFyc2VkKS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0byBiZSB1c2VkIHRvIGludHJvc3BlY3QgdGhlIGlucHV0IHBhcmFtZXRlcnMKICAgICAqIGJlZm9yZSB0aGV5IGhhdmUgYmVlbiB2YWxpZGF0ZWQuIEl0IG11c3QgYmUgdXNlZCBjYXJlZnVsbHkuCiAgICAgKiBEb2VzIG5vdCBuZWNlc3NhcmlseSByZXR1cm4gdGhlIGNvcnJlY3QgcmVzdWx0IGZvciBzaG9ydCBvcHRpb25zCiAgICAgKiB3aGVuIG11bHRpcGxlIGZsYWdzIGFyZSBjb21iaW5lZCBpbiB0aGUgc2FtZSBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkdmFsdWVzICAgICBUaGUgdmFsdWUocykgdG8gbG9vayBmb3IgaW4gdGhlIHJhdyBwYXJhbWV0ZXJzIChjYW4gYmUgYW4gYXJyYXkpCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICRkZWZhdWx0ICAgIFRoZSBkZWZhdWx0IHZhbHVlIHRvIHJldHVybiBpZiBubyByZXN1bHQgaXMgZm91bmQKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG9ubHlQYXJhbXMgT25seSBjaGVjayByZWFsIHBhcmFtZXRlcnMsIHNraXAgdGhvc2UgZm9sbG93aW5nIGFuIGVuZCBvZiBvcHRpb25zICgtLSkgc2lnbmFsCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBUaGUgb3B0aW9uIHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJhbWV0ZXJPcHRpb24oJHZhbHVlcywgJGRlZmF1bHQgPSBmYWxzZSwgJG9ubHlQYXJhbXMgPSBmYWxzZSk7CgogICAgLyoqCiAgICAgKiBCaW5kcyB0aGUgY3VycmVudCBJbnB1dCBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMgYW5kIG9wdGlvbnMuCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBiaW5kKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbik7CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGlucHV0LgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIG5vdCBlbm91Z2ggYXJndW1lbnRzIGFyZSBnaXZlbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIHRoZSBnaXZlbiBhcmd1bWVudHMgbWVyZ2VkIHdpdGggdGhlIGRlZmF1bHQgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50cygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYXJndW1lbnQgdmFsdWUgZm9yIGEgZ2l2ZW4gYXJndW1lbnQgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8c3RyaW5nW118bnVsbCBUaGUgYXJndW1lbnQgdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGFyZ3VtZW50IGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCRuYW1lKTsKCiAgICAvKioKICAgICAqIFNldHMgYW4gYXJndW1lbnQgdmFsdWUgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJG5hbWUgIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdfG51bGwgJHZhbHVlIFRoZSBhcmd1bWVudCB2YWx1ZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gYXJndW1lbnQgZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRBcmd1bWVudCBvYmplY3QgZXhpc3RzIGJ5IG5hbWUgb3IgcG9zaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJG5hbWUgVGhlIElucHV0QXJndW1lbnQgbmFtZSBvciBwb3NpdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBJbnB1dEFyZ3VtZW50IG9iamVjdCBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQXJndW1lbnQoJG5hbWUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgdGhlIGdpdmVuIG9wdGlvbnMgbWVyZ2VkIHdpdGggdGhlIGRlZmF1bHQgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wdGlvbiB2YWx1ZSBmb3IgYSBnaXZlbiBvcHRpb24gbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBvcHRpb24gbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfHN0cmluZ1tdfGJvb2x8bnVsbCBUaGUgb3B0aW9uIHZhbHVlCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9uKCRuYW1lKTsKCiAgICAvKioKICAgICAqIFNldHMgYW4gb3B0aW9uIHZhbHVlIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJG5hbWUgIFRoZSBvcHRpb24gbmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXXxib29sfG51bGwgJHZhbHVlIFRoZSBvcHRpb24gdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2Vzbid0IGV4aXN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb24oJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cyBieSBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIElucHV0T3B0aW9uIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNPcHRpb24oJG5hbWUpOwoKICAgIC8qKgogICAgICogSXMgdGhpcyBpbnB1dCBtZWFucyBpbnRlcmFjdGl2ZT8KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW50ZXJhY3RpdmUoKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlucHV0IGludGVyYWN0aXZpdHkuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGludGVyYWN0aXZlIElmIHRoZSBpbnB1dCBzaG91bGQgYmUgaW50ZXJhY3RpdmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEludGVyYWN0aXZlKCRpbnRlcmFjdGl2ZSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0OwoKLyoqCiAqIElucHV0QXdhcmVJbnRlcmZhY2Ugc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IGNsYXNzZXMgdGhhdCBkZXBlbmRzIG9uIHRoZQogKiBDb25zb2xlIElucHV0LgogKgogKiBAYXV0aG9yIFdvdXRlciBKIDx3YWxkaW8ud2ViZGVzaWduQGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBJbnB1dEF3YXJlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU2V0cyB0aGUgQ29uc29sZSBJbnB1dC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElucHV0KElucHV0SW50ZXJmYWNlICRpbnB1dCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRPcHRpb25FeGNlcHRpb247CgovKioKICogQXJyYXlJbnB1dCByZXByZXNlbnRzIGFuIGlucHV0IHByb3ZpZGVkIGFzIGFuIGFycmF5LgogKgogKiBVc2FnZToKICoKICogICAgICRpbnB1dCA9IG5ldyBBcnJheUlucHV0KFsnY29tbWFuZCcgPT4gJ2ZvbzpiYXInLCAnZm9vJyA9PiAnYmFyJywgJy0tYmFyJyA9PiAnZm9vYmFyJ10pOwogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEFycmF5SW5wdXQgZXh0ZW5kcyBJbnB1dAp7CiAgICBwcml2YXRlICRwYXJhbWV0ZXJzOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcGFyYW1ldGVycywgSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+cGFyYW1ldGVycyA9ICRwYXJhbWV0ZXJzOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRkZWZpbml0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpcnN0QXJndW1lbnQoKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYXJhbWV0ZXJzIGFzICRwYXJhbSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCRwYXJhbSAmJiBcaXNfc3RyaW5nKCRwYXJhbSkgJiYgJy0nID09PSAkcGFyYW1bMF0pIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNQYXJhbWV0ZXJPcHRpb24oJHZhbHVlcywgJG9ubHlQYXJhbXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdmFsdWVzID0gKGFycmF5KSAkdmFsdWVzOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFyYW1ldGVycyBhcyAkayA9PiAkdikgewogICAgICAgICAgICBpZiAoIVxpc19pbnQoJGspKSB7CiAgICAgICAgICAgICAgICAkdiA9ICRrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG9ubHlQYXJhbXMgJiYgJy0tJyA9PT0gJHYpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFxpbl9hcnJheSgkdiwgJHZhbHVlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJhbWV0ZXJPcHRpb24oJHZhbHVlcywgJGRlZmF1bHQgPSBmYWxzZSwgJG9ubHlQYXJhbXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdmFsdWVzID0gKGFycmF5KSAkdmFsdWVzOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFyYW1ldGVycyBhcyAkayA9PiAkdikgewogICAgICAgICAgICBpZiAoJG9ubHlQYXJhbXMgJiYgKCctLScgPT09ICRrIHx8IChcaXNfaW50KCRrKSAmJiAnLS0nID09PSAkdikpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChcaXNfaW50KCRrKSkgewogICAgICAgICAgICAgICAgaWYgKFxpbl9hcnJheSgkdiwgJHZhbHVlcykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKFxpbl9hcnJheSgkaywgJHZhbHVlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZ2lmaWVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcmdzIHBhc3NlZCB0byB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgJHBhcmFtcyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYXJhbWV0ZXJzIGFzICRwYXJhbSA9PiAkdmFsKSB7CiAgICAgICAgICAgIGlmICgkcGFyYW0gJiYgXGlzX3N0cmluZygkcGFyYW0pICYmICctJyA9PT0gJHBhcmFtWzBdKSB7CiAgICAgICAgICAgICAgICBpZiAoXGlzX2FycmF5KCR2YWwpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHZhbCBhcyAkdikgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFyYW1zW10gPSAkcGFyYW0uKCcnICE9ICR2ID8gJz0nLiR0aGlzLT5lc2NhcGVUb2tlbigkdikgOiAnJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcGFyYW1zW10gPSAkcGFyYW0uKCcnICE9ICR2YWwgPyAnPScuJHRoaXMtPmVzY2FwZVRva2VuKCR2YWwpIDogJycpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBhcmFtc1tdID0gXGlzX2FycmF5KCR2YWwpID8gaW1wbG9kZSgnICcsIGFycmF5X21hcChbJHRoaXMsICdlc2NhcGVUb2tlbiddLCAkdmFsKSkgOiAkdGhpcy0+ZXNjYXBlVG9rZW4oJHZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcgJywgJHBhcmFtcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZSgpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBhcmFtZXRlcnMgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCctLScgPT09ICRrZXkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRrZXksICctLScpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTG9uZ09wdGlvbihzdWJzdHIoJGtleSwgMiksICR2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgwID09PSBzdHJwb3MoJGtleSwgJy0nKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFNob3J0T3B0aW9uKHN1YnN0cigka2V5LCAxKSwgJHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRBcmd1bWVudCgka2V5LCAkdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIHNob3J0IG9wdGlvbiB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzaG9ydGN1dCBUaGUgc2hvcnQgb3B0aW9uIGtleQogICAgICogQHBhcmFtIG1peGVkICAkdmFsdWUgICAgVGhlIHZhbHVlIGZvciB0aGUgb3B0aW9uCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkT3B0aW9uRXhjZXB0aW9uIFdoZW4gb3B0aW9uIGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRTaG9ydE9wdGlvbigkc2hvcnRjdXQsICR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5kZWZpbml0aW9uLT5oYXNTaG9ydGN1dCgkc2hvcnRjdXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3B0aW9uRXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJHNob3J0Y3V0KSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YWRkTG9uZ09wdGlvbigkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uRm9yU2hvcnRjdXQoJHNob3J0Y3V0KS0+Z2V0TmFtZSgpLCAkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIGxvbmcgb3B0aW9uIHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIFRoZSBsb25nIG9wdGlvbiBrZXkKICAgICAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlIFRoZSB2YWx1ZSBmb3IgdGhlIG9wdGlvbgogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZE9wdGlvbkV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2Vzbid0IGV4aXN0CiAgICAgKiBAdGhyb3dzIEludmFsaWRPcHRpb25FeGNlcHRpb24gV2hlbiBhIHJlcXVpcmVkIHZhbHVlIGlzIG1pc3NpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRMb25nT3B0aW9uKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzT3B0aW9uKCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wdGlvbkV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0tJXMiIG9wdGlvbiBkb2VzIG5vdCBleGlzdC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgJG9wdGlvbiA9ICR0aGlzLT5kZWZpbml0aW9uLT5nZXRPcHRpb24oJG5hbWUpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmICgkb3B0aW9uLT5pc1ZhbHVlUmVxdWlyZWQoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcHRpb25FeGNlcHRpb24oc3ByaW50ZignVGhlICItLSVzIiBvcHRpb24gcmVxdWlyZXMgYSB2YWx1ZS4nLCAkbmFtZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRvcHRpb24tPmlzVmFsdWVPcHRpb25hbCgpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3B0aW9uc1skbmFtZV0gPSAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGFuIGFyZ3VtZW50IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKiBAcGFyYW0gbWl4ZWQgICR2YWx1ZSBUaGUgdmFsdWUgZm9yIHRoZSBhcmd1bWVudAogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gYXJndW1lbnQgZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFkZEFyZ3VtZW50KCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzQXJndW1lbnQoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlICIlcyIgYXJndW1lbnQgZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hcmd1bWVudHNbJG5hbWVdID0gJHZhbHVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxSdW50aW1lRXhjZXB0aW9uOwoKLyoqCiAqIEFyZ3ZJbnB1dCByZXByZXNlbnRzIGFuIGlucHV0IGNvbWluZyBmcm9tIHRoZSBDTEkgYXJndW1lbnRzLgogKgogKiBVc2FnZToKICoKICogICAgICRpbnB1dCA9IG5ldyBBcmd2SW5wdXQoKTsKICoKICogQnkgZGVmYXVsdCwgdGhlIGAkX1NFUlZFUlsnYXJndiddYCBhcnJheSBpcyB1c2VkIGZvciB0aGUgaW5wdXQgdmFsdWVzLgogKgogKiBUaGlzIGNhbiBiZSBvdmVycmlkZGVuIGJ5IGV4cGxpY2l0bHkgcGFzc2luZyB0aGUgaW5wdXQgdmFsdWVzIGluIHRoZSBjb25zdHJ1Y3RvcjoKICoKICogICAgICRpbnB1dCA9IG5ldyBBcmd2SW5wdXQoJF9TRVJWRVJbJ2FyZ3YnXSk7CiAqCiAqIElmIHlvdSBwYXNzIGl0IHlvdXJzZWxmLCBkb24ndCBmb3JnZXQgdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGUgYXJyYXkKICogaXMgdGhlIG5hbWUgb2YgdGhlIHJ1bm5pbmcgYXBwbGljYXRpb24uCiAqCiAqIFdoZW4gcGFzc2luZyBhbiBhcmd1bWVudCB0byB0aGUgY29uc3RydWN0b3IsIGJlIHN1cmUgdGhhdCBpdCByZXNwZWN0cwogKiB0aGUgc2FtZSBydWxlcyBhcyB0aGUgYXJndiBvbmUuIEl0J3MgYWxtb3N0IGFsd2F5cyBiZXR0ZXIgdG8gdXNlIHRoZQogKiBgU3RyaW5nSW5wdXRgIHdoZW4geW91IHdhbnQgdG8gcHJvdmlkZSB5b3VyIG93biBpbnB1dC4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEBzZWUgaHR0cDovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2xpYmMvbWFudWFsL2h0bWxfbm9kZS9Bcmd1bWVudC1TeW50YXguaHRtbAogKiBAc2VlIGh0dHA6Ly93d3cub3Blbmdyb3VwLm9yZy9vbmxpbmVwdWJzLzAwOTY5NTM5OS9iYXNlZGVmcy94YmRfY2hhcDEyLmh0bWwjdGFnXzEyXzAyCiAqLwpjbGFzcyBBcmd2SW5wdXQgZXh0ZW5kcyBJbnB1dAp7CiAgICBwcml2YXRlICR0b2tlbnM7CiAgICBwcml2YXRlICRwYXJzZWQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAgICAgICAgICAgJGFyZ3YgICAgICAgQW4gYXJyYXkgb2YgcGFyYW1ldGVycyBmcm9tIHRoZSBDTEkgKGluIHRoZSBhcmd2IGZvcm1hdCkKICAgICAqIEBwYXJhbSBJbnB1dERlZmluaXRpb258bnVsbCAkZGVmaW5pdGlvbiBBIElucHV0RGVmaW5pdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGFyZ3YgPSBudWxsLCBJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24gPSBudWxsKQogICAgewogICAgICAgICRhcmd2ID0gbnVsbCAhPT0gJGFyZ3YgPyAkYXJndiA6IChpc3NldCgkX1NFUlZFUlsnYXJndiddKSA/ICRfU0VSVkVSWydhcmd2J10gOiBbXSk7CgogICAgICAgIC8vIHN0cmlwIHRoZSBhcHBsaWNhdGlvbiBuYW1lCiAgICAgICAgYXJyYXlfc2hpZnQoJGFyZ3YpOwoKICAgICAgICAkdGhpcy0+dG9rZW5zID0gJGFyZ3Y7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGRlZmluaXRpb24pOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXRUb2tlbnMoYXJyYXkgJHRva2VucykKICAgIHsKICAgICAgICAkdGhpcy0+dG9rZW5zID0gJHRva2VuczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlKCkKICAgIHsKICAgICAgICAkcGFyc2VPcHRpb25zID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+cGFyc2VkID0gJHRoaXMtPnRva2VuczsKICAgICAgICB3aGlsZSAobnVsbCAhPT0gJHRva2VuID0gYXJyYXlfc2hpZnQoJHRoaXMtPnBhcnNlZCkpIHsKICAgICAgICAgICAgaWYgKCRwYXJzZU9wdGlvbnMgJiYgJycgPT0gJHRva2VuKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGFyc2VBcmd1bWVudCgkdG9rZW4pOwogICAgICAgICAgICB9IGVsc2VpZiAoJHBhcnNlT3B0aW9ucyAmJiAnLS0nID09ICR0b2tlbikgewogICAgICAgICAgICAgICAgJHBhcnNlT3B0aW9ucyA9IGZhbHNlOwogICAgICAgICAgICB9IGVsc2VpZiAoJHBhcnNlT3B0aW9ucyAmJiAwID09PSBzdHJwb3MoJHRva2VuLCAnLS0nKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlTG9uZ09wdGlvbigkdG9rZW4pOwogICAgICAgICAgICB9IGVsc2VpZiAoJHBhcnNlT3B0aW9ucyAmJiAnLScgPT09ICR0b2tlblswXSAmJiAnLScgIT09ICR0b2tlbikgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlU2hvcnRPcHRpb24oJHRva2VuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUFyZ3VtZW50KCR0b2tlbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzaG9ydCBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdG9rZW4gVGhlIGN1cnJlbnQgdG9rZW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZVNob3J0T3B0aW9uKCR0b2tlbikKICAgIHsKICAgICAgICAkbmFtZSA9IHN1YnN0cigkdG9rZW4sIDEpOwoKICAgICAgICBpZiAoXHN0cmxlbigkbmFtZSkgPiAxKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzU2hvcnRjdXQoJG5hbWVbMF0pICYmICR0aGlzLT5kZWZpbml0aW9uLT5nZXRPcHRpb25Gb3JTaG9ydGN1dCgkbmFtZVswXSktPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgICAgIC8vIGFuIG9wdGlvbiB3aXRoIGEgdmFsdWUgKHdpdGggbm8gc3BhY2UpCiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkU2hvcnRPcHRpb24oJG5hbWVbMF0sIHN1YnN0cigkbmFtZSwgMSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlU2hvcnRPcHRpb25TZXQoJG5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmFkZFNob3J0T3B0aW9uKCRuYW1lLCBudWxsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzaG9ydCBvcHRpb24gc2V0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGN1cnJlbnQgdG9rZW4KICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnNlU2hvcnRPcHRpb25TZXQoJG5hbWUpCiAgICB7CiAgICAgICAgJGxlbiA9IFxzdHJsZW4oJG5hbWUpOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRsZW47ICsrJGkpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzU2hvcnRjdXQoJG5hbWVbJGldKSkgewogICAgICAgICAgICAgICAgJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCRuYW1lLCBudWxsLCB0cnVlKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgZmFsc2UgPT09ICRlbmNvZGluZyA/ICRuYW1lWyRpXSA6IG1iX3N1YnN0cigkbmFtZSwgJGksIDEsICRlbmNvZGluZykpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG9wdGlvbiA9ICR0aGlzLT5kZWZpbml0aW9uLT5nZXRPcHRpb25Gb3JTaG9ydGN1dCgkbmFtZVskaV0pOwogICAgICAgICAgICBpZiAoJG9wdGlvbi0+YWNjZXB0VmFsdWUoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZExvbmdPcHRpb24oJG9wdGlvbi0+Z2V0TmFtZSgpLCAkaSA9PT0gJGxlbiAtIDEgPyBudWxsIDogc3Vic3RyKCRuYW1lLCAkaSArIDEpKTsKCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMb25nT3B0aW9uKCRvcHRpb24tPmdldE5hbWUoKSwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsb25nIG9wdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0b2tlbiBUaGUgY3VycmVudCB0b2tlbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnNlTG9uZ09wdGlvbigkdG9rZW4pCiAgICB7CiAgICAgICAgJG5hbWUgPSBzdWJzdHIoJHRva2VuLCAyKTsKCiAgICAgICAgaWYgKGZhbHNlICE9PSAkcG9zID0gc3RycG9zKCRuYW1lLCAnPScpKSB7CiAgICAgICAgICAgIGlmICgwID09PSBcc3RybGVuKCR2YWx1ZSA9IHN1YnN0cigkbmFtZSwgJHBvcyArIDEpKSkgewogICAgICAgICAgICAgICAgLy8gaWYgbm8gdmFsdWUgYWZ0ZXIgIj0iIHRoZW4gc3Vic3RyKCkgcmV0dXJucyAiIiBzaW5jZSBwaHA3IG9ubHksIGZhbHNlIGJlZm9yZQogICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vcGhwLm5ldC9taWdyYXRpb243MC5pbmNvbXBhdGlibGUucGhwIzExOTE1MQogICAgICAgICAgICAgICAgaWYgKFxQSFBfVkVSU0lPTl9JRCA8IDcwMDAwICYmIGZhbHNlID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAnJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJHRoaXMtPnBhcnNlZCwgJHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+YWRkTG9uZ09wdGlvbihzdWJzdHIoJG5hbWUsIDAsICRwb3MpLCAkdmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRMb25nT3B0aW9uKCRuYW1lLCBudWxsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdG9rZW4gVGhlIGN1cnJlbnQgdG9rZW4KICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiB0b28gbWFueSBhcmd1bWVudHMgYXJlIGdpdmVuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcGFyc2VBcmd1bWVudCgkdG9rZW4pCiAgICB7CiAgICAgICAgJGMgPSBcY291bnQoJHRoaXMtPmFyZ3VtZW50cyk7CgogICAgICAgIC8vIGlmIGlucHV0IGlzIGV4cGVjdGluZyBhbm90aGVyIGFyZ3VtZW50LCBhZGQgaXQKICAgICAgICBpZiAoJHRoaXMtPmRlZmluaXRpb24tPmhhc0FyZ3VtZW50KCRjKSkgewogICAgICAgICAgICAkYXJnID0gJHRoaXMtPmRlZmluaXRpb24tPmdldEFyZ3VtZW50KCRjKTsKICAgICAgICAgICAgJHRoaXMtPmFyZ3VtZW50c1skYXJnLT5nZXROYW1lKCldID0gJGFyZy0+aXNBcnJheSgpID8gWyR0b2tlbl0gOiAkdG9rZW47CgogICAgICAgIC8vIGlmIGxhc3QgYXJndW1lbnQgaXNBcnJheSgpLCBhcHBlbmQgdG9rZW4gdG8gbGFzdCBhcmd1bWVudAogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzQXJndW1lbnQoJGMgLSAxKSAmJiAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnQoJGMgLSAxKS0+aXNBcnJheSgpKSB7CiAgICAgICAgICAgICRhcmcgPSAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnQoJGMgLSAxKTsKICAgICAgICAgICAgJHRoaXMtPmFyZ3VtZW50c1skYXJnLT5nZXROYW1lKCldW10gPSAkdG9rZW47CgogICAgICAgIC8vIHVuZXhwZWN0ZWQgYXJndW1lbnQKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYWxsID0gJHRoaXMtPmRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpOwogICAgICAgICAgICBpZiAoXGNvdW50KCRhbGwpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUb28gbWFueSBhcmd1bWVudHMsIGV4cGVjdGVkIGFyZ3VtZW50cyAiJXMiLicsIGltcGxvZGUoJyIgIicsIGFycmF5X2tleXMoJGFsbCkpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ05vIGFyZ3VtZW50cyBleHBlY3RlZCwgZ290ICIlcyIuJywgJHRva2VuKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIHNob3J0IG9wdGlvbiB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzaG9ydGN1dCBUaGUgc2hvcnQgb3B0aW9uIGtleQogICAgICogQHBhcmFtIG1peGVkICAkdmFsdWUgICAgVGhlIHZhbHVlIGZvciB0aGUgb3B0aW9uCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gb3B0aW9uIGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRTaG9ydE9wdGlvbigkc2hvcnRjdXQsICR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5kZWZpbml0aW9uLT5oYXNTaG9ydGN1dCgkc2hvcnRjdXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJHNob3J0Y3V0KSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YWRkTG9uZ09wdGlvbigkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uRm9yU2hvcnRjdXQoJHNob3J0Y3V0KS0+Z2V0TmFtZSgpLCAkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIGxvbmcgb3B0aW9uIHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIFRoZSBsb25nIG9wdGlvbiBrZXkKICAgICAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlIFRoZSB2YWx1ZSBmb3IgdGhlIG9wdGlvbgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2Vzbid0IGV4aXN0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkTG9uZ09wdGlvbigkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc09wdGlvbigkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVGhlICItLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb24gPSAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uKCRuYW1lKTsKCiAgICAgICAgaWYgKG51bGwgIT09ICR2YWx1ZSAmJiAhJG9wdGlvbi0+YWNjZXB0VmFsdWUoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0tJXMiIG9wdGlvbiBkb2VzIG5vdCBhY2NlcHQgYSB2YWx1ZS4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxpbl9hcnJheSgkdmFsdWUsIFsnJywgbnVsbF0sIHRydWUpICYmICRvcHRpb24tPmFjY2VwdFZhbHVlKCkgJiYgXGNvdW50KCR0aGlzLT5wYXJzZWQpKSB7CiAgICAgICAgICAgIC8vIGlmIG9wdGlvbiBhY2NlcHRzIGFuIG9wdGlvbmFsIG9yIG1hbmRhdG9yeSBhcmd1bWVudAogICAgICAgICAgICAvLyBsZXQncyBzZWUgaWYgdGhlcmUgaXMgb25lIHByb3ZpZGVkCiAgICAgICAgICAgICRuZXh0ID0gYXJyYXlfc2hpZnQoJHRoaXMtPnBhcnNlZCk7CiAgICAgICAgICAgIGlmICgoaXNzZXQoJG5leHRbMF0pICYmICctJyAhPT0gJG5leHRbMF0pIHx8IFxpbl9hcnJheSgkbmV4dCwgWycnLCBudWxsXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRuZXh0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkdGhpcy0+cGFyc2VkLCAkbmV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCRvcHRpb24tPmlzVmFsdWVSZXF1aXJlZCgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0tJXMiIG9wdGlvbiByZXF1aXJlcyBhIHZhbHVlLicsICRuYW1lKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJG9wdGlvbi0+aXNBcnJheSgpICYmICEkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRvcHRpb24tPmlzQXJyYXkoKSkgewogICAgICAgICAgICAkdGhpcy0+b3B0aW9uc1skbmFtZV1bXSA9ICR2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+b3B0aW9uc1skbmFtZV0gPSAkdmFsdWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Rmlyc3RBcmd1bWVudCgpCiAgICB7CiAgICAgICAgJGlzT3B0aW9uID0gZmFsc2U7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRva2VucyBhcyAkaSA9PiAkdG9rZW4pIHsKICAgICAgICAgICAgaWYgKCR0b2tlbiAmJiAnLScgPT09ICR0b2tlblswXSkgewogICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJHRva2VuLCAnPScpIHx8ICFpc3NldCgkdGhpcy0+dG9rZW5zWyRpICsgMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSWYgaXQncyBhIGxvbmcgb3B0aW9uLCBjb25zaWRlciB0aGF0IGV2ZXJ5dGhpbmcgYWZ0ZXIgIi0tIiBpcyB0aGUgb3B0aW9uIG5hbWUuCiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIHVzZSB0aGUgbGFzdCBjaGFyIChpZiBpdCdzIGEgc2hvcnQgb3B0aW9uIHNldCwgb25seSB0aGUgbGFzdCBvbmUgY2FuIHRha2UgYSB2YWx1ZSB3aXRoIHNwYWNlIHNlcGFyYXRvcikKICAgICAgICAgICAgICAgICRuYW1lID0gJy0nID09PSAkdG9rZW5bMV0gPyBzdWJzdHIoJHRva2VuLCAyKSA6IHN1YnN0cigkdG9rZW4sIC0xKTsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPm9wdGlvbnNbJG5hbWVdKSAmJiAhJHRoaXMtPmRlZmluaXRpb24tPmhhc1Nob3J0Y3V0KCRuYW1lKSkgewogICAgICAgICAgICAgICAgICAgIC8vIG5vb3AKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgoaXNzZXQoJHRoaXMtPm9wdGlvbnNbJG5hbWVdKSB8fCBpc3NldCgkdGhpcy0+b3B0aW9uc1skbmFtZSA9ICR0aGlzLT5kZWZpbml0aW9uLT5zaG9ydGN1dFRvTmFtZSgkbmFtZSldKSkgJiYgJHRoaXMtPnRva2Vuc1skaSArIDFdID09PSAkdGhpcy0+b3B0aW9uc1skbmFtZV0pIHsKICAgICAgICAgICAgICAgICAgICAkaXNPcHRpb24gPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGlzT3B0aW9uKSB7CiAgICAgICAgICAgICAgICAkaXNPcHRpb24gPSBmYWxzZTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRva2VuOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNQYXJhbWV0ZXJPcHRpb24oJHZhbHVlcywgJG9ubHlQYXJhbXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdmFsdWVzID0gKGFycmF5KSAkdmFsdWVzOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dG9rZW5zIGFzICR0b2tlbikgewogICAgICAgICAgICBpZiAoJG9ubHlQYXJhbXMgJiYgJy0tJyA9PT0gJHRva2VuKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlcyBhcyAkdmFsdWUpIHsKICAgICAgICAgICAgICAgIC8vIE9wdGlvbnMgd2l0aCB2YWx1ZXM6CiAgICAgICAgICAgICAgICAvLyAgIEZvciBsb25nIG9wdGlvbnMsIHRlc3QgZm9yICctLW9wdGlvbj0nIGF0IGJlZ2lubmluZwogICAgICAgICAgICAgICAgLy8gICBGb3Igc2hvcnQgb3B0aW9ucywgdGVzdCBmb3IgJy1vJyBhdCBiZWdpbm5pbmcKICAgICAgICAgICAgICAgICRsZWFkaW5nID0gMCA9PT0gc3RycG9zKCR2YWx1ZSwgJy0tJykgPyAkdmFsdWUuJz0nIDogJHZhbHVlOwogICAgICAgICAgICAgICAgaWYgKCR0b2tlbiA9PT0gJHZhbHVlIHx8ICcnICE9PSAkbGVhZGluZyAmJiAwID09PSBzdHJwb3MoJHRva2VuLCAkbGVhZGluZykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFyYW1ldGVyT3B0aW9uKCR2YWx1ZXMsICRkZWZhdWx0ID0gZmFsc2UsICRvbmx5UGFyYW1zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHZhbHVlcyA9IChhcnJheSkgJHZhbHVlczsKICAgICAgICAkdG9rZW5zID0gJHRoaXMtPnRva2VuczsKCiAgICAgICAgd2hpbGUgKDAgPCBcY291bnQoJHRva2VucykpIHsKICAgICAgICAgICAgJHRva2VuID0gYXJyYXlfc2hpZnQoJHRva2Vucyk7CiAgICAgICAgICAgIGlmICgkb25seVBhcmFtcyAmJiAnLS0nID09PSAkdG9rZW4pIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlcyBhcyAkdmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICgkdG9rZW4gPT09ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheV9zaGlmdCgkdG9rZW5zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIE9wdGlvbnMgd2l0aCB2YWx1ZXM6CiAgICAgICAgICAgICAgICAvLyAgIEZvciBsb25nIG9wdGlvbnMsIHRlc3QgZm9yICctLW9wdGlvbj0nIGF0IGJlZ2lubmluZwogICAgICAgICAgICAgICAgLy8gICBGb3Igc2hvcnQgb3B0aW9ucywgdGVzdCBmb3IgJy1vJyBhdCBiZWdpbm5pbmcKICAgICAgICAgICAgICAgICRsZWFkaW5nID0gMCA9PT0gc3RycG9zKCR2YWx1ZSwgJy0tJykgPyAkdmFsdWUuJz0nIDogJHZhbHVlOwogICAgICAgICAgICAgICAgaWYgKCcnICE9PSAkbGVhZGluZyAmJiAwID09PSBzdHJwb3MoJHRva2VuLCAkbGVhZGluZykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3Vic3RyKCR0b2tlbiwgXHN0cmxlbigkbGVhZGluZykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFyZ3MgcGFzc2VkIHRvIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICAkdG9rZW5zID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkdG9rZW4pIHsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKC1bXj1dKz0pKC4rKX0nLCAkdG9rZW4sICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbWF0Y2hbMV0uJHRoaXMtPmVzY2FwZVRva2VuKCRtYXRjaFsyXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdG9rZW4gJiYgJy0nICE9PSAkdG9rZW5bMF0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXNjYXBlVG9rZW4oJHRva2VuKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0b2tlbjsKICAgICAgICB9LCAkdGhpcy0+dG9rZW5zKTsKCiAgICAgICAgcmV0dXJuIGltcGxvZGUoJyAnLCAkdG9rZW5zKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhIGNvbW1hbmQgbGluZSBvcHRpb24uCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgSW5wdXRPcHRpb24KewogICAgY29uc3QgVkFMVUVfTk9ORSA9IDE7CiAgICBjb25zdCBWQUxVRV9SRVFVSVJFRCA9IDI7CiAgICBjb25zdCBWQUxVRV9PUFRJT05BTCA9IDQ7CiAgICBjb25zdCBWQUxVRV9JU19BUlJBWSA9IDg7CgogICAgcHJpdmF0ZSAkbmFtZTsKICAgIHByaXZhdGUgJHNob3J0Y3V0OwogICAgcHJpdmF0ZSAkbW9kZTsKICAgIHByaXZhdGUgJGRlZmF1bHQ7CiAgICBwcml2YXRlICRkZXNjcmlwdGlvbjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICAgVGhlIG9wdGlvbiBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5fG51bGwgICAgICAgICAgICAgJHNob3J0Y3V0ICAgIFRoZSBzaG9ydGN1dHMsIGNhbiBiZSBudWxsLCBhIHN0cmluZyBvZiBzaG9ydGN1dHMgZGVsaW1pdGVkIGJ5IHwgb3IgYW4gYXJyYXkgb2Ygc2hvcnRjdXRzCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICAgICAgICAgICAgICAgICAgJG1vZGUgICAgICAgIFRoZSBvcHRpb24gbW9kZTogT25lIG9mIHRoZSBWQUxVRV8qIGNvbnN0YW50cwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIHRleHQKICAgICAqIEBwYXJhbSBzdHJpbmd8c3RyaW5nW118aW50fGJvb2x8bnVsbCAkZGVmYXVsdCAgICAgVGhlIGRlZmF1bHQgdmFsdWUgKG11c3QgYmUgbnVsbCBmb3Igc2VsZjo6VkFMVUVfTk9ORSkKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiBvcHRpb24gbW9kZSBpcyBpbnZhbGlkIG9yIGluY29tcGF0aWJsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsICRzaG9ydGN1dCA9IG51bGwsICRtb2RlID0gbnVsbCwgJGRlc2NyaXB0aW9uID0gJycsICRkZWZhdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRuYW1lLCAnLS0nKSkgewogICAgICAgICAgICAkbmFtZSA9IHN1YnN0cigkbmFtZSwgMik7CiAgICAgICAgfQoKICAgICAgICBpZiAoZW1wdHkoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0FuIG9wdGlvbiBuYW1lIGNhbm5vdCBiZSBlbXB0eS4nKTsKICAgICAgICB9CgogICAgICAgIGlmIChlbXB0eSgkc2hvcnRjdXQpKSB7CiAgICAgICAgICAgICRzaG9ydGN1dCA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJHNob3J0Y3V0KSB7CiAgICAgICAgICAgIGlmIChcaXNfYXJyYXkoJHNob3J0Y3V0KSkgewogICAgICAgICAgICAgICAgJHNob3J0Y3V0ID0gaW1wbG9kZSgnfCcsICRzaG9ydGN1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNob3J0Y3V0cyA9IHByZWdfc3BsaXQoJ3soXHwpLT99JywgbHRyaW0oJHNob3J0Y3V0LCAnLScpKTsKICAgICAgICAgICAgJHNob3J0Y3V0cyA9IGFycmF5X2ZpbHRlcigkc2hvcnRjdXRzKTsKICAgICAgICAgICAgJHNob3J0Y3V0ID0gaW1wbG9kZSgnfCcsICRzaG9ydGN1dHMpOwoKICAgICAgICAgICAgaWYgKGVtcHR5KCRzaG9ydGN1dCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0FuIG9wdGlvbiBzaG9ydGN1dCBjYW5ub3QgYmUgZW1wdHkuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkbW9kZSkgewogICAgICAgICAgICAkbW9kZSA9IHNlbGY6OlZBTFVFX05PTkU7CiAgICAgICAgfSBlbHNlaWYgKCFcaXNfaW50KCRtb2RlKSB8fCAkbW9kZSA+IDE1IHx8ICRtb2RlIDwgMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ09wdGlvbiBtb2RlICIlcyIgaXMgbm90IHZhbGlkLicsICRtb2RlKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgICR0aGlzLT5zaG9ydGN1dCA9ICRzaG9ydGN1dDsKICAgICAgICAkdGhpcy0+bW9kZSA9ICRtb2RlOwogICAgICAgICR0aGlzLT5kZXNjcmlwdGlvbiA9ICRkZXNjcmlwdGlvbjsKCiAgICAgICAgaWYgKCR0aGlzLT5pc0FycmF5KCkgJiYgISR0aGlzLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0ltcG9zc2libGUgdG8gaGF2ZSBhbiBvcHRpb24gbW9kZSBWQUxVRV9JU19BUlJBWSBpZiB0aGUgb3B0aW9uIGRvZXMgbm90IGFjY2VwdCBhIHZhbHVlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNldERlZmF1bHQoJGRlZmF1bHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgb3B0aW9uIHNob3J0Y3V0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIHNob3J0Y3V0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTaG9ydGN1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zaG9ydGN1dDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wdGlvbiBuYW1lLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG9wdGlvbiBhY2NlcHRzIGEgdmFsdWUuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdmFsdWUgbW9kZSBpcyBub3Qgc2VsZjo6VkFMVUVfTk9ORSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1ZhbHVlUmVxdWlyZWQoKSB8fCAkdGhpcy0+aXNWYWx1ZU9wdGlvbmFsKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG9wdGlvbiByZXF1aXJlcyBhIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHZhbHVlIG1vZGUgaXMgc2VsZjo6VkFMVUVfUkVRVUlSRUQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWYWx1ZVJlcXVpcmVkKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6VkFMVUVfUkVRVUlSRUQgPT09IChzZWxmOjpWQUxVRV9SRVFVSVJFRCAmICR0aGlzLT5tb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgb3B0aW9uIHRha2VzIGFuIG9wdGlvbmFsIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHZhbHVlIG1vZGUgaXMgc2VsZjo6VkFMVUVfT1BUSU9OQUwsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWYWx1ZU9wdGlvbmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6VkFMVUVfT1BUSU9OQUwgPT09IChzZWxmOjpWQUxVRV9PUFRJT05BTCAmICR0aGlzLT5tb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgb3B0aW9uIGNhbiB0YWtlIG11bHRpcGxlIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiBtb2RlIGlzIHNlbGY6OlZBTFVFX0lTX0FSUkFZLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQXJyYXkoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWQUxVRV9JU19BUlJBWSA9PT0gKHNlbGY6OlZBTFVFX0lTX0FSUkFZICYgJHRoaXMtPm1vZGUpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdfGludHxib29sfG51bGwgJGRlZmF1bHQgVGhlIGRlZmF1bHQgdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIFdoZW4gaW5jb3JyZWN0IGRlZmF1bHQgdmFsdWUgaXMgZ2l2ZW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlZmF1bHQoJGRlZmF1bHQgPSBudWxsKQogICAgewogICAgICAgIGlmIChzZWxmOjpWQUxVRV9OT05FID09PSAoc2VsZjo6VkFMVUVfTk9ORSAmICR0aGlzLT5tb2RlKSAmJiBudWxsICE9PSAkZGVmYXVsdCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0Nhbm5vdCBzZXQgYSBkZWZhdWx0IHZhbHVlIHdoZW4gdXNpbmcgSW5wdXRPcHRpb246OlZBTFVFX05PTkUgbW9kZS4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aXNBcnJheSgpKSB7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkZGVmYXVsdCkgewogICAgICAgICAgICAgICAgJGRlZmF1bHQgPSBbXTsKICAgICAgICAgICAgfSBlbHNlaWYgKCFcaXNfYXJyYXkoJGRlZmF1bHQpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0EgZGVmYXVsdCB2YWx1ZSBmb3IgYW4gYXJyYXkgb3B0aW9uIG11c3QgYmUgYW4gYXJyYXkuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5kZWZhdWx0ID0gJHRoaXMtPmFjY2VwdFZhbHVlKCkgPyAkZGVmYXVsdCA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xzdHJpbmdbXXxpbnR8Ym9vbHxudWxsIFRoZSBkZWZhdWx0IHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWZhdWx0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiB0ZXh0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBkZXNjcmlwdGlvbiB0ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBvcHRpb24gZXF1YWxzIHRoaXMgb25lLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXF1YWxzKHNlbGYgJG9wdGlvbikKICAgIHsKICAgICAgICByZXR1cm4gJG9wdGlvbi0+Z2V0TmFtZSgpID09PSAkdGhpcy0+Z2V0TmFtZSgpCiAgICAgICAgICAgICYmICRvcHRpb24tPmdldFNob3J0Y3V0KCkgPT09ICR0aGlzLT5nZXRTaG9ydGN1dCgpCiAgICAgICAgICAgICYmICRvcHRpb24tPmdldERlZmF1bHQoKSA9PT0gJHRoaXMtPmdldERlZmF1bHQoKQogICAgICAgICAgICAmJiAkb3B0aW9uLT5pc0FycmF5KCkgPT09ICR0aGlzLT5pc0FycmF5KCkKICAgICAgICAgICAgJiYgJG9wdGlvbi0+aXNWYWx1ZVJlcXVpcmVkKCkgPT09ICR0aGlzLT5pc1ZhbHVlUmVxdWlyZWQoKQogICAgICAgICAgICAmJiAkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSA9PT0gJHRoaXMtPmlzVmFsdWVPcHRpb25hbCgpCiAgICAgICAgOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvbjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKCi8qKgogKiBSZXByZXNlbnRzIGEgUXVlc3Rpb24uCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgUXVlc3Rpb24KewogICAgcHJpdmF0ZSAkcXVlc3Rpb247CiAgICBwcml2YXRlICRhdHRlbXB0czsKICAgIHByaXZhdGUgJGhpZGRlbiA9IGZhbHNlOwogICAgcHJpdmF0ZSAkaGlkZGVuRmFsbGJhY2sgPSB0cnVlOwogICAgcHJpdmF0ZSAkYXV0b2NvbXBsZXRlclZhbHVlczsKICAgIHByaXZhdGUgJHZhbGlkYXRvcjsKICAgIHByaXZhdGUgJGRlZmF1bHQ7CiAgICBwcml2YXRlICRub3JtYWxpemVyOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24gVGhlIHF1ZXN0aW9uIHRvIGFzayB0byB0aGUgdXNlcgogICAgICogQHBhcmFtIG1peGVkICAkZGVmYXVsdCAgVGhlIGRlZmF1bHQgYW5zd2VyIHRvIHJldHVybiBpZiB0aGUgdXNlciBlbnRlcnMgbm90aGluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnF1ZXN0aW9uID0gJHF1ZXN0aW9uOwogICAgICAgICR0aGlzLT5kZWZhdWx0ID0gJGRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UXVlc3Rpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cXVlc3Rpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWZhdWx0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHVzZXIgcmVzcG9uc2UgbXVzdCBiZSBoaWRkZW4uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0hpZGRlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oaWRkZW47CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIHVzZXIgcmVzcG9uc2UgbXVzdCBiZSBoaWRkZW4gb3Igbm90LgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRoaWRkZW4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBhdXRvY29tcGxldGVyIGlzIGFsc28gdXNlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGlkZGVuKCRoaWRkZW4pCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5hdXRvY29tcGxldGVyVmFsdWVzKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQSBoaWRkZW4gcXVlc3Rpb24gY2Fubm90IHVzZSB0aGUgYXV0b2NvbXBsZXRlci4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5oaWRkZW4gPSAoYm9vbCkgJGhpZGRlbjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogSW4gY2FzZSB0aGUgcmVzcG9uc2UgY2FuIG5vdCBiZSBoaWRkZW4sIHdoZXRoZXIgdG8gZmFsbGJhY2sgb24gbm9uLWhpZGRlbiBxdWVzdGlvbiBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0hpZGRlbkZhbGxiYWNrKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhpZGRlbkZhbGxiYWNrOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB3aGV0aGVyIHRvIGZhbGxiYWNrIG9uIG5vbi1oaWRkZW4gcXVlc3Rpb24gaWYgdGhlIHJlc3BvbnNlIGNhbiBub3QgYmUgaGlkZGVuLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRmYWxsYmFjawogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhpZGRlbkZhbGxiYWNrKCRmYWxsYmFjaykKICAgIHsKICAgICAgICAkdGhpcy0+aGlkZGVuRmFsbGJhY2sgPSAoYm9vbCkgJGZhbGxiYWNrOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHZhbHVlcyBmb3IgdGhlIGF1dG9jb21wbGV0ZXIuCiAgICAgKgogICAgICogQHJldHVybiBpdGVyYWJsZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvY29tcGxldGVyVmFsdWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF1dG9jb21wbGV0ZXJWYWx1ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHZhbHVlcyBmb3IgdGhlIGF1dG9jb21wbGV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGl0ZXJhYmxlfG51bGwgJHZhbHVlcwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0b2NvbXBsZXRlclZhbHVlcygkdmFsdWVzKQogICAgewogICAgICAgIGlmIChcaXNfYXJyYXkoJHZhbHVlcykpIHsKICAgICAgICAgICAgJHZhbHVlcyA9ICR0aGlzLT5pc0Fzc29jKCR2YWx1ZXMpID8gYXJyYXlfbWVyZ2UoYXJyYXlfa2V5cygkdmFsdWVzKSwgYXJyYXlfdmFsdWVzKCR2YWx1ZXMpKSA6IGFycmF5X3ZhbHVlcygkdmFsdWVzKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdmFsdWVzICYmICFcaXNfYXJyYXkoJHZhbHVlcykgJiYgISR2YWx1ZXMgaW5zdGFuY2VvZiBcVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignQXV0b2NvbXBsZXRlciB2YWx1ZXMgY2FuIGJlIGVpdGhlciBhbiBhcnJheSwgYG51bGxgIG9yIGEgYFRyYXZlcnNhYmxlYCBvYmplY3QuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmhpZGRlbikgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0EgaGlkZGVuIHF1ZXN0aW9uIGNhbm5vdCB1c2UgdGhlIGF1dG9jb21wbGV0ZXIuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YXV0b2NvbXBsZXRlclZhbHVlcyA9ICR2YWx1ZXM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSB2YWxpZGF0b3IgZm9yIHRoZSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWxpZGF0b3IoY2FsbGFibGUgJHZhbGlkYXRvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbGlkYXRvciA9ICR2YWxpZGF0b3I7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHZhbGlkYXRvciBmb3IgdGhlIHF1ZXN0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGV8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbGlkYXRvcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLgogICAgICoKICAgICAqIE51bGwgbWVhbnMgYW4gdW5saW1pdGVkIG51bWJlciBvZiBhdHRlbXB0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50fG51bGwgJGF0dGVtcHRzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGluIGNhc2UgdGhlIG51bWJlciBvZiBhdHRlbXB0cyBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNYXhBdHRlbXB0cygkYXR0ZW1wdHMpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRhdHRlbXB0cykgewogICAgICAgICAgICAkYXR0ZW1wdHMgPSAoaW50KSAkYXR0ZW1wdHM7CiAgICAgICAgICAgIGlmICgkYXR0ZW1wdHMgPCAxKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdNYXhpbXVtIG51bWJlciBvZiBhdHRlbXB0cyBtdXN0IGJlIGEgcG9zaXRpdmUgdmFsdWUuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5hdHRlbXB0cyA9ICRhdHRlbXB0czsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYXR0ZW1wdHMuCiAgICAgKgogICAgICogTnVsbCBtZWFucyBhbiB1bmxpbWl0ZWQgbnVtYmVyIG9mIGF0dGVtcHRzLgogICAgICoKICAgICAqIEByZXR1cm4gaW50fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1heEF0dGVtcHRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF0dGVtcHRzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIG5vcm1hbGl6ZXIgZm9yIHRoZSByZXNwb25zZS4KICAgICAqCiAgICAgKiBUaGUgbm9ybWFsaXplciBjYW4gYmUgYSBjYWxsYWJsZSAoYSBzdHJpbmcpLCBhIGNsb3N1cmUgb3IgYSBjbGFzcyBpbXBsZW1lbnRpbmcgX19pbnZva2UuCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Tm9ybWFsaXplcihjYWxsYWJsZSAkbm9ybWFsaXplcikKICAgIHsKICAgICAgICAkdGhpcy0+bm9ybWFsaXplciA9ICRub3JtYWxpemVyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBub3JtYWxpemVyIGZvciB0aGUgcmVzcG9uc2UuCiAgICAgKgogICAgICogVGhlIG5vcm1hbGl6ZXIgY2FuIGJhIGEgY2FsbGFibGUgKGEgc3RyaW5nKSwgYSBjbG9zdXJlIG9yIGEgY2xhc3MgaW1wbGVtZW50aW5nIF9faW52b2tlLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGV8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Tm9ybWFsaXplcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ub3JtYWxpemVyOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc0Fzc29jKCRhcnJheSkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpIFxjb3VudChhcnJheV9maWx0ZXIoYXJyYXlfa2V5cygkYXJyYXkpLCAnaXNfc3RyaW5nJykpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvbjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhIGNob2ljZSBxdWVzdGlvbi4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBDaG9pY2VRdWVzdGlvbiBleHRlbmRzIFF1ZXN0aW9uCnsKICAgIHByaXZhdGUgJGNob2ljZXM7CiAgICBwcml2YXRlICRtdWx0aXNlbGVjdCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkcHJvbXB0ID0gJyA+ICc7CiAgICBwcml2YXRlICRlcnJvck1lc3NhZ2UgPSAnVmFsdWUgIiVzIiBpcyBpbnZhbGlkJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uIFRoZSBxdWVzdGlvbiB0byBhc2sgdG8gdGhlIHVzZXIKICAgICAqIEBwYXJhbSBhcnJheSAgJGNob2ljZXMgIFRoZSBsaXN0IG9mIGF2YWlsYWJsZSBjaG9pY2VzCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRkZWZhdWx0ICBUaGUgZGVmYXVsdCBhbnN3ZXIgdG8gcmV0dXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcXVlc3Rpb24sIGFycmF5ICRjaG9pY2VzLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCEkY2hvaWNlcykgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdDaG9pY2UgcXVlc3Rpb24gbXVzdCBoYXZlIGF0IGxlYXN0IDEgY2hvaWNlIGF2YWlsYWJsZS4nKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAkZGVmYXVsdCk7CgogICAgICAgICR0aGlzLT5jaG9pY2VzID0gJGNob2ljZXM7CiAgICAgICAgJHRoaXMtPnNldFZhbGlkYXRvcigkdGhpcy0+Z2V0RGVmYXVsdFZhbGlkYXRvcigpKTsKICAgICAgICAkdGhpcy0+c2V0QXV0b2NvbXBsZXRlclZhbHVlcygkY2hvaWNlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGF2YWlsYWJsZSBjaG9pY2VzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENob2ljZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hvaWNlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgbXVsdGlzZWxlY3Qgb3B0aW9uLgogICAgICoKICAgICAqIFdoZW4gbXVsdGlzZWxlY3QgaXMgc2V0IHRvIHRydWUsIG11bHRpcGxlIGNob2ljZXMgY2FuIGJlIGFuc3dlcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRtdWx0aXNlbGVjdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE11bHRpc2VsZWN0KCRtdWx0aXNlbGVjdCkKICAgIHsKICAgICAgICAkdGhpcy0+bXVsdGlzZWxlY3QgPSAkbXVsdGlzZWxlY3Q7CiAgICAgICAgJHRoaXMtPnNldFZhbGlkYXRvcigkdGhpcy0+Z2V0RGVmYXVsdFZhbGlkYXRvcigpKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjaG9pY2VzIGFyZSBtdWx0aXNlbGVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzTXVsdGlzZWxlY3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bXVsdGlzZWxlY3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9tcHQgZm9yIGNob2ljZXMuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb21wdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9tcHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9tcHQgZm9yIGNob2ljZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJvbXB0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvbXB0KCRwcm9tcHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb21wdCA9ICRwcm9tcHQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGVycm9yIG1lc3NhZ2UgZm9yIGludmFsaWQgdmFsdWVzLgogICAgICoKICAgICAqIFRoZSBlcnJvciBtZXNzYWdlIGhhcyBhIHN0cmluZyBwbGFjZWhvbGRlciAoJXMpIGZvciB0aGUgaW52YWxpZCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlcnJvck1lc3NhZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFcnJvck1lc3NhZ2UoJGVycm9yTWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JNZXNzYWdlID0gJGVycm9yTWVzc2FnZTsKICAgICAgICAkdGhpcy0+c2V0VmFsaWRhdG9yKCR0aGlzLT5nZXREZWZhdWx0VmFsaWRhdG9yKCkpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlciB2YWxpZGF0b3IuCiAgICAgKgogICAgICogQHJldHVybiBjYWxsYWJsZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERlZmF1bHRWYWxpZGF0b3IoKQogICAgewogICAgICAgICRjaG9pY2VzID0gJHRoaXMtPmNob2ljZXM7CiAgICAgICAgJGVycm9yTWVzc2FnZSA9ICR0aGlzLT5lcnJvck1lc3NhZ2U7CiAgICAgICAgJG11bHRpc2VsZWN0ID0gJHRoaXMtPm11bHRpc2VsZWN0OwogICAgICAgICRpc0Fzc29jID0gJHRoaXMtPmlzQXNzb2MoJGNob2ljZXMpOwoKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCRzZWxlY3RlZCkgdXNlICgkY2hvaWNlcywgJGVycm9yTWVzc2FnZSwgJG11bHRpc2VsZWN0LCAkaXNBc3NvYykgewogICAgICAgICAgICBpZiAoJG11bHRpc2VsZWN0KSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgYSBzZXBhcmF0ZWQgY29tbWEgdmFsdWVzCiAgICAgICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9eW14sXSsoPzosW14sXSspKiQvJywgJHNlbGVjdGVkLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJGVycm9yTWVzc2FnZSwgJHNlbGVjdGVkKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHNlbGVjdGVkQ2hvaWNlcyA9IGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJywnLCAkc2VsZWN0ZWQpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRzZWxlY3RlZENob2ljZXMgPSBbdHJpbSgkc2VsZWN0ZWQpXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG11bHRpc2VsZWN0Q2hvaWNlcyA9IFtdOwogICAgICAgICAgICBmb3JlYWNoICgkc2VsZWN0ZWRDaG9pY2VzIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgJHJlc3VsdHMgPSBbXTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjaG9pY2VzIGFzICRrZXkgPT4gJGNob2ljZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkY2hvaWNlID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9ICRrZXk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChcY291bnQoJHJlc3VsdHMpID4gMSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIHByb3ZpZGVkIGFuc3dlciBpcyBhbWJpZ3VvdXMuIFZhbHVlIHNob3VsZCBiZSBvbmUgb2YgIiVzIi4nLCBpbXBsb2RlKCciIG9yICInLCAkcmVzdWx0cykpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gYXJyYXlfc2VhcmNoKCR2YWx1ZSwgJGNob2ljZXMpOwoKICAgICAgICAgICAgICAgIGlmICghJGlzQXNzb2MpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCA9ICRjaG9pY2VzWyRyZXN1bHRdOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkY2hvaWNlc1skdmFsdWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJGNob2ljZXNbJHZhbHVlXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoZmFsc2UgPT09ICRyZXN1bHQgJiYgaXNzZXQoJGNob2ljZXNbJHZhbHVlXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigkZXJyb3JNZXNzYWdlLCAkdmFsdWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbXVsdGlzZWxlY3RDaG9pY2VzW10gPSAoc3RyaW5nKSAkcmVzdWx0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG11bHRpc2VsZWN0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG11bHRpc2VsZWN0Q2hvaWNlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQoJG11bHRpc2VsZWN0Q2hvaWNlcyk7CiAgICAgICAgfTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb247CgovKioKICogUmVwcmVzZW50cyBhIHllcy9ubyBxdWVzdGlvbi4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBDb25maXJtYXRpb25RdWVzdGlvbiBleHRlbmRzIFF1ZXN0aW9uCnsKICAgIHByaXZhdGUgJHRydWVBbnN3ZXJSZWdleDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uICAgICAgICBUaGUgcXVlc3Rpb24gdG8gYXNrIHRvIHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gYm9vbCAgICRkZWZhdWx0ICAgICAgICAgVGhlIGRlZmF1bHQgYW5zd2VyIHRvIHJldHVybiwgdHJ1ZSBvciBmYWxzZQogICAgICogQHBhcmFtIHN0cmluZyAkdHJ1ZUFuc3dlclJlZ2V4IEEgcmVnZXggdG8gbWF0Y2ggdGhlICJ5ZXMiIGFuc3dlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IHRydWUsICR0cnVlQW5zd2VyUmVnZXggPSAnL155L2knKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAoYm9vbCkgJGRlZmF1bHQpOwoKICAgICAgICAkdGhpcy0+dHJ1ZUFuc3dlclJlZ2V4ID0gJHRydWVBbnN3ZXJSZWdleDsKICAgICAgICAkdGhpcy0+c2V0Tm9ybWFsaXplcigkdGhpcy0+Z2V0RGVmYXVsdE5vcm1hbGl6ZXIoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlciBub3JtYWxpemVyLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXREZWZhdWx0Tm9ybWFsaXplcigpCiAgICB7CiAgICAgICAgJGRlZmF1bHQgPSAkdGhpcy0+Z2V0RGVmYXVsdCgpOwogICAgICAgICRyZWdleCA9ICR0aGlzLT50cnVlQW5zd2VyUmVnZXg7CgogICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGFuc3dlcikgdXNlICgkZGVmYXVsdCwgJHJlZ2V4KSB7CiAgICAgICAgICAgIGlmIChcaXNfYm9vbCgkYW5zd2VyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRhbnN3ZXI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRhbnN3ZXJJc1RydWUgPSAoYm9vbCkgcHJlZ19tYXRjaCgkcmVnZXgsICRhbnN3ZXIpOwogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRkZWZhdWx0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGFuc3dlciAmJiAkYW5zd2VySXNUcnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJycgPT09ICRhbnN3ZXIgfHwgJGFuc3dlcklzVHJ1ZTsKICAgICAgICB9OwogICAgfQp9Cjw/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+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlc3RlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcQXJyYXlJbnB1dDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxTdHJlYW1PdXRwdXQ7CgovKioKICogRWFzZXMgdGhlIHRlc3Rpbmcgb2YgY29uc29sZSBjb21tYW5kcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgUm9iaW4gQ2hhbGFzIDxyb2Jpbi5jaGFsYXNAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tbWFuZFRlc3Rlcgp7CiAgICBwcml2YXRlICRjb21tYW5kOwogICAgcHJpdmF0ZSAkaW5wdXQ7CiAgICBwcml2YXRlICRvdXRwdXQ7CiAgICBwcml2YXRlICRpbnB1dHMgPSBbXTsKICAgIHByaXZhdGUgJHN0YXR1c0NvZGU7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENvbW1hbmQgJGNvbW1hbmQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbW1hbmQgPSAkY29tbWFuZDsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEF2YWlsYWJsZSBleGVjdXRpb24gb3B0aW9uczoKICAgICAqCiAgICAgKiAgKiBpbnRlcmFjdGl2ZTogU2V0cyB0aGUgaW5wdXQgaW50ZXJhY3RpdmUgZmxhZwogICAgICogICogZGVjb3JhdGVkOiAgIFNldHMgdGhlIG91dHB1dCBkZWNvcmF0ZWQgZmxhZwogICAgICogICogdmVyYm9zaXR5OiAgIFNldHMgdGhlIG91dHB1dCB2ZXJib3NpdHkgZmxhZwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkaW5wdXQgICBBbiBhcnJheSBvZiBjb21tYW5kIGFyZ3VtZW50cyBhbmQgb3B0aW9ucwogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zIEFuIGFycmF5IG9mIGV4ZWN1dGlvbiBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIGNvbW1hbmQgZXhpdCBjb2RlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlKGFycmF5ICRpbnB1dCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAvLyBzZXQgdGhlIGNvbW1hbmQgbmFtZSBhdXRvbWF0aWNhbGx5IGlmIHRoZSBhcHBsaWNhdGlvbiByZXF1aXJlcwogICAgICAgIC8vIHRoaXMgYXJndW1lbnQgYW5kIG5vIGNvbW1hbmQgbmFtZSB3YXMgcGFzc2VkCiAgICAgICAgaWYgKCFpc3NldCgkaW5wdXRbJ2NvbW1hbmQnXSkKICAgICAgICAgICAgJiYgKG51bGwgIT09ICRhcHBsaWNhdGlvbiA9ICR0aGlzLT5jb21tYW5kLT5nZXRBcHBsaWNhdGlvbigpKQogICAgICAgICAgICAmJiAkYXBwbGljYXRpb24tPmdldERlZmluaXRpb24oKS0+aGFzQXJndW1lbnQoJ2NvbW1hbmQnKQogICAgICAgICkgewogICAgICAgICAgICAkaW5wdXQgPSBhcnJheV9tZXJnZShbJ2NvbW1hbmQnID0+ICR0aGlzLT5jb21tYW5kLT5nZXROYW1lKCldLCAkaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlucHV0ID0gbmV3IEFycmF5SW5wdXQoJGlucHV0KTsKICAgICAgICAvLyBVc2UgYW4gaW4tbWVtb3J5IGlucHV0IHN0cmVhbSBldmVuIGlmIG5vIGlucHV0cyBhcmUgc2V0IHNvIHRoYXQgUXVlc3Rpb25IZWxwZXI6OmFzaygpIGRvZXMgbm90IHJlbHkgb24gdGhlIGJsb2NraW5nIFNURElOLgogICAgICAgICR0aGlzLT5pbnB1dC0+c2V0U3RyZWFtKHNlbGY6OmNyZWF0ZVN0cmVhbSgkdGhpcy0+aW5wdXRzKSk7CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaW50ZXJhY3RpdmUnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0LT5zZXRJbnRlcmFjdGl2ZSgkb3B0aW9uc1snaW50ZXJhY3RpdmUnXSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3V0cHV0ID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vbWVtb3J5JywgJ3cnLCBmYWxzZSkpOwogICAgICAgICR0aGlzLT5vdXRwdXQtPnNldERlY29yYXRlZChpc3NldCgkb3B0aW9uc1snZGVjb3JhdGVkJ10pID8gJG9wdGlvbnNbJ2RlY29yYXRlZCddIDogZmFsc2UpOwogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1sndmVyYm9zaXR5J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQtPnNldFZlcmJvc2l0eSgkb3B0aW9uc1sndmVyYm9zaXR5J10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0dXNDb2RlID0gJHRoaXMtPmNvbW1hbmQtPnJ1bigkdGhpcy0+aW5wdXQsICR0aGlzLT5vdXRwdXQpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZGlzcGxheSByZXR1cm5lZCBieSB0aGUgbGFzdCBleGVjdXRpb24gb2YgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG5vcm1hbGl6ZSBXaGV0aGVyIHRvIG5vcm1hbGl6ZSBlbmQgb2YgbGluZXMgdG8gXG4gb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGRpc3BsYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3BsYXkoJG5vcm1hbGl6ZSA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+b3V0cHV0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignT3V0cHV0IG5vdCBpbml0aWFsaXplZCwgZGlkIHlvdSBleGVjdXRlIHRoZSBjb21tYW5kIGJlZm9yZSByZXF1ZXN0aW5nIHRoZSBkaXNwbGF5PycpOwogICAgICAgIH0KCiAgICAgICAgcmV3aW5kKCR0aGlzLT5vdXRwdXQtPmdldFN0cmVhbSgpKTsKCiAgICAgICAgJGRpc3BsYXkgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5vdXRwdXQtPmdldFN0cmVhbSgpKTsKCiAgICAgICAgaWYgKCRub3JtYWxpemUpIHsKICAgICAgICAgICAgJGRpc3BsYXkgPSBzdHJfcmVwbGFjZShcUEhQX0VPTCwgIlxuIiwgJGRpc3BsYXkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkaXNwbGF5OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgaW5wdXQgaW5zdGFuY2UgdXNlZCBieSB0aGUgbGFzdCBleGVjdXRpb24gb2YgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHJldHVybiBJbnB1dEludGVyZmFjZSBUaGUgY3VycmVudCBpbnB1dCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5wdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5wdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBvdXRwdXQgaW5zdGFuY2UgdXNlZCBieSB0aGUgbGFzdCBleGVjdXRpb24gb2YgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHJldHVybiBPdXRwdXRJbnRlcmZhY2UgVGhlIGN1cnJlbnQgb3V0cHV0IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgc3RhdHVzIGNvZGUgcmV0dXJuZWQgYnkgdGhlIGxhc3QgZXhlY3V0aW9uIG9mIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgc3RhdHVzIGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c0NvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RhdHVzQ29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHVzZXIgaW5wdXRzLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkaW5wdXRzIEFuIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIGVhY2ggaW5wdXQKICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBhc3NlZCB0byB0aGUgY29tbWFuZCBpbnB1dCBzdHJlYW0KICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1hbmRUZXN0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElucHV0cyhhcnJheSAkaW5wdXRzKQogICAgewogICAgICAgICR0aGlzLT5pbnB1dHMgPSAkaW5wdXRzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlU3RyZWFtKGFycmF5ICRpbnB1dHMpCiAgICB7CiAgICAgICAgJHN0cmVhbSA9IGZvcGVuKCdwaHA6Ly9tZW1vcnknLCAncisnLCBmYWxzZSk7CgogICAgICAgIGZvcmVhY2ggKCRpbnB1dHMgYXMgJGlucHV0KSB7CiAgICAgICAgICAgIGZ3cml0ZSgkc3RyZWFtLCAkaW5wdXQuXFBIUF9FT0wpOwogICAgICAgIH0KCiAgICAgICAgcmV3aW5kKCRzdHJlYW0pOwoKICAgICAgICByZXR1cm4gJHN0cmVhbTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcVGVzdGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XEFycmF5SW5wdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcQ29uc29sZU91dHB1dDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XFN0cmVhbU91dHB1dDsKCi8qKgogKiBFYXNlcyB0aGUgdGVzdGluZyBvZiBjb25zb2xlIGFwcGxpY2F0aW9ucy4KICoKICogV2hlbiB0ZXN0aW5nIGFuIGFwcGxpY2F0aW9uLCBkb24ndCBmb3JnZXQgdG8gZGlzYWJsZSB0aGUgYXV0byBleGl0IGZsYWc6CiAqCiAqICAgICAkYXBwbGljYXRpb24gPSBuZXcgQXBwbGljYXRpb24oKTsKICogICAgICRhcHBsaWNhdGlvbi0+c2V0QXV0b0V4aXQoZmFsc2UpOwogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEFwcGxpY2F0aW9uVGVzdGVyCnsKICAgIHByaXZhdGUgJGFwcGxpY2F0aW9uOwogICAgcHJpdmF0ZSAkaW5wdXQ7CiAgICBwcml2YXRlICRzdGF0dXNDb2RlOwogICAgLyoqCiAgICAgKiBAdmFyIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRvdXRwdXQ7CiAgICBwcml2YXRlICRjYXB0dXJlU3RyZWFtc0luZGVwZW5kZW50bHkgPSBmYWxzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uKQogICAgewogICAgICAgICR0aGlzLT5hcHBsaWNhdGlvbiA9ICRhcHBsaWNhdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBBdmFpbGFibGUgb3B0aW9uczoKICAgICAqCiAgICAgKiAgKiBpbnRlcmFjdGl2ZTogICAgICAgICAgICAgICBTZXRzIHRoZSBpbnB1dCBpbnRlcmFjdGl2ZSBmbGFnCiAgICAgKiAgKiBkZWNvcmF0ZWQ6ICAgICAgICAgICAgICAgICBTZXRzIHRoZSBvdXRwdXQgZGVjb3JhdGVkIGZsYWcKICAgICAqICAqIHZlcmJvc2l0eTogICAgICAgICAgICAgICAgIFNldHMgdGhlIG91dHB1dCB2ZXJib3NpdHkgZmxhZwogICAgICogICogY2FwdHVyZV9zdGRlcnJfc2VwYXJhdGVseTogTWFrZSBvdXRwdXQgb2Ygc3RkT3V0IGFuZCBzdGRFcnIgc2VwYXJhdGVseSBhdmFpbGFibGUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGlucHV0ICAgQW4gYXJyYXkgb2YgYXJndW1lbnRzIGFuZCBvcHRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgQW4gYXJyYXkgb2Ygb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBjb21tYW5kIGV4aXQgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcnVuKGFycmF5ICRpbnB1dCwgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+aW5wdXQgPSBuZXcgQXJyYXlJbnB1dCgkaW5wdXQpOwogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaW50ZXJhY3RpdmUnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0LT5zZXRJbnRlcmFjdGl2ZSgkb3B0aW9uc1snaW50ZXJhY3RpdmUnXSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y2FwdHVyZVN0cmVhbXNJbmRlcGVuZGVudGx5ID0gXGFycmF5X2tleV9leGlzdHMoJ2NhcHR1cmVfc3RkZXJyX3NlcGFyYXRlbHknLCAkb3B0aW9ucykgJiYgJG9wdGlvbnNbJ2NhcHR1cmVfc3RkZXJyX3NlcGFyYXRlbHknXTsKICAgICAgICBpZiAoISR0aGlzLT5jYXB0dXJlU3RyZWFtc0luZGVwZW5kZW50bHkpIHsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dCA9IG5ldyBTdHJlYW1PdXRwdXQoZm9wZW4oJ3BocDovL21lbW9yeScsICd3JywgZmFsc2UpKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydkZWNvcmF0ZWQnXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5vdXRwdXQtPnNldERlY29yYXRlZCgkb3B0aW9uc1snZGVjb3JhdGVkJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1sndmVyYm9zaXR5J10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0LT5zZXRWZXJib3NpdHkoJG9wdGlvbnNbJ3ZlcmJvc2l0eSddKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQgPSBuZXcgQ29uc29sZU91dHB1dCgKICAgICAgICAgICAgICAgIGlzc2V0KCRvcHRpb25zWyd2ZXJib3NpdHknXSkgPyAkb3B0aW9uc1sndmVyYm9zaXR5J10gOiBDb25zb2xlT3V0cHV0OjpWRVJCT1NJVFlfTk9STUFMLAogICAgICAgICAgICAgICAgaXNzZXQoJG9wdGlvbnNbJ2RlY29yYXRlZCddKSA/ICRvcHRpb25zWydkZWNvcmF0ZWQnXSA6IG51bGwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRlcnJvck91dHB1dCA9IG5ldyBTdHJlYW1PdXRwdXQoZm9wZW4oJ3BocDovL21lbW9yeScsICd3JywgZmFsc2UpKTsKICAgICAgICAgICAgJGVycm9yT3V0cHV0LT5zZXRGb3JtYXR0ZXIoJHRoaXMtPm91dHB1dC0+Z2V0Rm9ybWF0dGVyKCkpOwogICAgICAgICAgICAkZXJyb3JPdXRwdXQtPnNldFZlcmJvc2l0eSgkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSk7CiAgICAgICAgICAgICRlcnJvck91dHB1dC0+c2V0RGVjb3JhdGVkKCR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCkpOwoKICAgICAgICAgICAgJHJlZmxlY3RlZE91dHB1dCA9IG5ldyBcUmVmbGVjdGlvbk9iamVjdCgkdGhpcy0+b3V0cHV0KTsKICAgICAgICAgICAgJHN0ckVyclByb3BlcnR5ID0gJHJlZmxlY3RlZE91dHB1dC0+Z2V0UHJvcGVydHkoJ3N0ZGVycicpOwogICAgICAgICAgICAkc3RyRXJyUHJvcGVydHktPnNldEFjY2Vzc2libGUodHJ1ZSk7CiAgICAgICAgICAgICRzdHJFcnJQcm9wZXJ0eS0+c2V0VmFsdWUoJHRoaXMtPm91dHB1dCwgJGVycm9yT3V0cHV0KTsKCiAgICAgICAgICAgICRyZWZsZWN0ZWRQYXJlbnQgPSAkcmVmbGVjdGVkT3V0cHV0LT5nZXRQYXJlbnRDbGFzcygpOwogICAgICAgICAgICAkc3RyZWFtUHJvcGVydHkgPSAkcmVmbGVjdGVkUGFyZW50LT5nZXRQcm9wZXJ0eSgnc3RyZWFtJyk7CiAgICAgICAgICAgICRzdHJlYW1Qcm9wZXJ0eS0+c2V0QWNjZXNzaWJsZSh0cnVlKTsKICAgICAgICAgICAgJHN0cmVhbVByb3BlcnR5LT5zZXRWYWx1ZSgkdGhpcy0+b3V0cHV0LCBmb3BlbigncGhwOi8vbWVtb3J5JywgJ3cnLCBmYWxzZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0dXNDb2RlID0gJHRoaXMtPmFwcGxpY2F0aW9uLT5ydW4oJHRoaXMtPmlucHV0LCAkdGhpcy0+b3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRpc3BsYXkgcmV0dXJuZWQgYnkgdGhlIGxhc3QgZXhlY3V0aW9uIG9mIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkbm9ybWFsaXplIFdoZXRoZXIgdG8gbm9ybWFsaXplIGVuZCBvZiBsaW5lcyB0byBcbiBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZGlzcGxheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzcGxheSgkbm9ybWFsaXplID0gZmFsc2UpCiAgICB7CiAgICAgICAgcmV3aW5kKCR0aGlzLT5vdXRwdXQtPmdldFN0cmVhbSgpKTsKCiAgICAgICAgJGRpc3BsYXkgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5vdXRwdXQtPmdldFN0cmVhbSgpKTsKCiAgICAgICAgaWYgKCRub3JtYWxpemUpIHsKICAgICAgICAgICAgJGRpc3BsYXkgPSBzdHJfcmVwbGFjZShcUEhQX0VPTCwgIlxuIiwgJGRpc3BsYXkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkaXNwbGF5OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3V0cHV0IHdyaXR0ZW4gdG8gU1RERVJSIGJ5IHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkbm9ybWFsaXplIFdoZXRoZXIgdG8gbm9ybWFsaXplIGVuZCBvZiBsaW5lcyB0byBcbiBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoJG5vcm1hbGl6ZSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmNhcHR1cmVTdHJlYW1zSW5kZXBlbmRlbnRseSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdUaGUgZXJyb3Igb3V0cHV0IGlzIG5vdCBhdmFpbGFibGUgd2hlbiB0aGUgdGVzdGVyIGlzIHJ1biB3aXRob3V0ICJjYXB0dXJlX3N0ZGVycl9zZXBhcmF0ZWx5IiBvcHRpb24gc2V0LicpOwogICAgICAgIH0KCiAgICAgICAgcmV3aW5kKCR0aGlzLT5vdXRwdXQtPmdldEVycm9yT3V0cHV0KCktPmdldFN0cmVhbSgpKTsKCiAgICAgICAgJGRpc3BsYXkgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5vdXRwdXQtPmdldEVycm9yT3V0cHV0KCktPmdldFN0cmVhbSgpKTsKCiAgICAgICAgaWYgKCRub3JtYWxpemUpIHsKICAgICAgICAgICAgJGRpc3BsYXkgPSBzdHJfcmVwbGFjZShcUEhQX0VPTCwgIlxuIiwgJGRpc3BsYXkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkaXNwbGF5OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgaW5wdXQgaW5zdGFuY2UgdXNlZCBieSB0aGUgbGFzdCBleGVjdXRpb24gb2YgdGhlIGFwcGxpY2F0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXRJbnRlcmZhY2UgVGhlIGN1cnJlbnQgaW5wdXQgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElucHV0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlucHV0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3V0cHV0IGluc3RhbmNlIHVzZWQgYnkgdGhlIGxhc3QgZXhlY3V0aW9uIG9mIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZSBUaGUgY3VycmVudCBvdXRwdXQgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE91dHB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBzdGF0dXMgY29kZSByZXR1cm5lZCBieSB0aGUgbGFzdCBleGVjdXRpb24gb2YgdGhlIGFwcGxpY2F0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBzdGF0dXMgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhdHVzQ29kZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0dXNDb2RlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKw6lyw7RtZSBUYW1hcmVsbGUgPGplcm9tZUB0YW1hcmVsbGUubmV0PgogKi8KY2xhc3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGV4dGVuZHMgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvbjsKCi8qKgogKiBSZXByZXNlbnRzIGFuIGluY29ycmVjdCBjb21tYW5kIG5hbWUgdHlwZWQgaW4gdGhlIGNvbnNvbGUuCiAqCiAqIEBhdXRob3IgSsOpcsO0bWUgVGFtYXJlbGxlIDxqZXJvbWVAdGFtYXJlbGxlLm5ldD4KICovCmNsYXNzIENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbiBleHRlbmRzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaW1wbGVtZW50cyBFeGNlcHRpb25JbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkYWx0ZXJuYXRpdmVzOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJG1lc3NhZ2UgICAgICBFeGNlcHRpb24gbWVzc2FnZSB0byB0aHJvdwogICAgICogQHBhcmFtIGFycmF5ICAgICAgJGFsdGVybmF0aXZlcyBMaXN0IG9mIHNpbWlsYXIgZGVmaW5lZCBuYW1lcwogICAgICogQHBhcmFtIGludCAgICAgICAgJGNvZGUgICAgICAgICBFeGNlcHRpb24gY29kZQogICAgICogQHBhcmFtIFxFeGNlcHRpb24gJHByZXZpb3VzICAgICBQcmV2aW91cyBleGNlcHRpb24gdXNlZCBmb3IgdGhlIGV4Y2VwdGlvbiBjaGFpbmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsIGFycmF5ICRhbHRlcm5hdGl2ZXMgPSBbXSwgJGNvZGUgPSAwLCBcRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJGNvZGUsICRwcmV2aW91cyk7CgogICAgICAgICR0aGlzLT5hbHRlcm5hdGl2ZXMgPSAkYWx0ZXJuYXRpdmVzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheSBBIGxpc3Qgb2Ygc2ltaWxhciBkZWZpbmVkIG5hbWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbHRlcm5hdGl2ZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWx0ZXJuYXRpdmVzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKw6lyw7RtZSBUYW1hcmVsbGUgPGplcm9tZUB0YW1hcmVsbGUubmV0PgogKi8KY2xhc3MgTG9naWNFeGNlcHRpb24gZXh0ZW5kcyBcTG9naWNFeGNlcHRpb24gaW1wbGVtZW50cyBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb247CgovKioKICogRXhjZXB0aW9uSW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIErDqXLDtG1lIFRhbWFyZWxsZSA8amVyb21lQHRhbWFyZWxsZS5uZXQ+CiAqLwppbnRlcmZhY2UgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uOwoKLyoqCiAqIFJlcHJlc2VudHMgYW4gaW5jb3JyZWN0IG9wdGlvbiBuYW1lIHR5cGVkIGluIHRoZSBjb25zb2xlLgogKgogKiBAYXV0aG9yIErDqXLDtG1lIFRhbWFyZWxsZSA8amVyb21lQHRhbWFyZWxsZS5uZXQ+CiAqLwpjbGFzcyBJbnZhbGlkT3B0aW9uRXhjZXB0aW9uIGV4dGVuZHMgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIErDqXLDtG1lIFRhbWFyZWxsZSA8amVyb21lQHRhbWFyZWxsZS5uZXQ+CiAqLwpjbGFzcyBSdW50aW1lRXhjZXB0aW9uIGV4dGVuZHMgXFJ1bnRpbWVFeGNlcHRpb24gaW1wbGVtZW50cyBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBNYXJrZG93biBkZXNjcmlwdG9yLgogKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqCiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgTWFya2Rvd25EZXNjcmlwdG9yIGV4dGVuZHMgRGVzY3JpcHRvcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlc2NyaWJlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkb2JqZWN0LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRkZWNvcmF0ZWQgPSAkb3V0cHV0LT5pc0RlY29yYXRlZCgpOwogICAgICAgICRvdXRwdXQtPnNldERlY29yYXRlZChmYWxzZSk7CgogICAgICAgIHBhcmVudDo6ZGVzY3JpYmUoJG91dHB1dCwgJG9iamVjdCwgJG9wdGlvbnMpOwoKICAgICAgICAkb3V0cHV0LT5zZXREZWNvcmF0ZWQoJGRlY29yYXRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSgkY29udGVudCwgJGRlY29yYXRlZCA9IHRydWUpCiAgICB7CiAgICAgICAgcGFyZW50Ojp3cml0ZSgkY29udGVudCwgJGRlY29yYXRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0QXJndW1lbnQoSW5wdXRBcmd1bWVudCAkYXJndW1lbnQsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlKAogICAgICAgICAgICAnIyMjIyBgJy4oJGFyZ3VtZW50LT5nZXROYW1lKCkgPzogJzxub25lPicpLiJgXG5cbiIKICAgICAgICAgICAgLigkYXJndW1lbnQtPmdldERlc2NyaXB0aW9uKCkgPyBwcmVnX3JlcGxhY2UoJy9ccypbXHJcbl1ccyovJywgIlxuIiwgJGFyZ3VtZW50LT5nZXREZXNjcmlwdGlvbigpKS4iXG5cbiIgOiAnJykKICAgICAgICAgICAgLicqIElzIHJlcXVpcmVkOiAnLigkYXJndW1lbnQtPmlzUmVxdWlyZWQoKSA/ICd5ZXMnIDogJ25vJykuIlxuIgogICAgICAgICAgICAuJyogSXMgYXJyYXk6ICcuKCRhcmd1bWVudC0+aXNBcnJheSgpID8gJ3llcycgOiAnbm8nKS4iXG4iCiAgICAgICAgICAgIC4nKiBEZWZhdWx0OiBgJy5zdHJfcmVwbGFjZSgiXG4iLCAnJywgdmFyX2V4cG9ydCgkYXJndW1lbnQtPmdldERlZmF1bHQoKSwgdHJ1ZSkpLidgJwogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0T3B0aW9uKElucHV0T3B0aW9uICRvcHRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG5hbWUgPSAnLS0nLiRvcHRpb24tPmdldE5hbWUoKTsKICAgICAgICBpZiAoJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkgewogICAgICAgICAgICAkbmFtZSAuPSAnfC0nLnN0cl9yZXBsYWNlKCd8JywgJ3wtJywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkuJyc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+d3JpdGUoCiAgICAgICAgICAgICcjIyMjIGAnLiRuYW1lLidgJy4iXG5cbiIKICAgICAgICAgICAgLigkb3B0aW9uLT5nZXREZXNjcmlwdGlvbigpID8gcHJlZ19yZXBsYWNlKCcvXHMqW1xyXG5dXHMqLycsICJcbiIsICRvcHRpb24tPmdldERlc2NyaXB0aW9uKCkpLiJcblxuIiA6ICcnKQogICAgICAgICAgICAuJyogQWNjZXB0IHZhbHVlOiAnLigkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpID8gJ3llcycgOiAnbm8nKS4iXG4iCiAgICAgICAgICAgIC4nKiBJcyB2YWx1ZSByZXF1aXJlZDogJy4oJG9wdGlvbi0+aXNWYWx1ZVJlcXVpcmVkKCkgPyAneWVzJyA6ICdubycpLiJcbiIKICAgICAgICAgICAgLicqIElzIG11bHRpcGxlOiAnLigkb3B0aW9uLT5pc0FycmF5KCkgPyAneWVzJyA6ICdubycpLiJcbiIKICAgICAgICAgICAgLicqIERlZmF1bHQ6IGAnLnN0cl9yZXBsYWNlKCJcbiIsICcnLCB2YXJfZXhwb3J0KCRvcHRpb24tPmdldERlZmF1bHQoKSwgdHJ1ZSkpLidgJwogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0RGVmaW5pdGlvbihJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgaWYgKCRzaG93QXJndW1lbnRzID0gXGNvdW50KCRkZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKSkgPiAwKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZSgnIyMjIEFyZ3VtZW50cycpOwogICAgICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuXG4iKTsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZSgkdGhpcy0+ZGVzY3JpYmVJbnB1dEFyZ3VtZW50KCRhcmd1bWVudCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkpID4gMCkgewogICAgICAgICAgICBpZiAoJHNob3dBcmd1bWVudHMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZSgiXG5cbiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+d3JpdGUoJyMjIyBPcHRpb25zJyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkgYXMgJG9wdGlvbikgewogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlKCJcblxuIik7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoJHRoaXMtPmRlc2NyaWJlSW5wdXRPcHRpb24oJG9wdGlvbikpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVDb21tYW5kKENvbW1hbmQgJGNvbW1hbmQsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJGNvbW1hbmQtPmdldFN5bm9wc2lzKCk7CiAgICAgICAgJGNvbW1hbmQtPm1lcmdlQXBwbGljYXRpb25EZWZpbml0aW9uKGZhbHNlKTsKCiAgICAgICAgJHRoaXMtPndyaXRlKAogICAgICAgICAgICAnYCcuJGNvbW1hbmQtPmdldE5hbWUoKS4iYFxuIgogICAgICAgICAgICAuc3RyX3JlcGVhdCgnLScsIEhlbHBlcjo6c3RybGVuKCRjb21tYW5kLT5nZXROYW1lKCkpICsgMikuIlxuXG4iCiAgICAgICAgICAgIC4oJGNvbW1hbmQtPmdldERlc2NyaXB0aW9uKCkgPyAkY29tbWFuZC0+Z2V0RGVzY3JpcHRpb24oKS4iXG5cbiIgOiAnJykKICAgICAgICAgICAgLicjIyMgVXNhZ2UnLiJcblxuIgogICAgICAgICAgICAuYXJyYXlfcmVkdWNlKGFycmF5X21lcmdlKFskY29tbWFuZC0+Z2V0U3lub3BzaXMoKV0sICRjb21tYW5kLT5nZXRBbGlhc2VzKCksICRjb21tYW5kLT5nZXRVc2FnZXMoKSksIGZ1bmN0aW9uICgkY2FycnksICR1c2FnZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRjYXJyeS4nKiBgJy4kdXNhZ2UuJ2AnLiJcbiI7CiAgICAgICAgICAgIH0pCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRoZWxwID0gJGNvbW1hbmQtPmdldFByb2Nlc3NlZEhlbHAoKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuIik7CiAgICAgICAgICAgICR0aGlzLT53cml0ZSgkaGVscCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNvbW1hbmQtPmdldE5hdGl2ZURlZmluaXRpb24oKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuXG4iKTsKICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXREZWZpbml0aW9uKCRjb21tYW5kLT5nZXROYXRpdmVEZWZpbml0aW9uKCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRkZXNjcmliZWROYW1lc3BhY2UgPSBpc3NldCgkb3B0aW9uc1snbmFtZXNwYWNlJ10pID8gJG9wdGlvbnNbJ25hbWVzcGFjZSddIDogbnVsbDsKICAgICAgICAkZGVzY3JpcHRpb24gPSBuZXcgQXBwbGljYXRpb25EZXNjcmlwdGlvbigkYXBwbGljYXRpb24sICRkZXNjcmliZWROYW1lc3BhY2UpOwogICAgICAgICR0aXRsZSA9ICR0aGlzLT5nZXRBcHBsaWNhdGlvblRpdGxlKCRhcHBsaWNhdGlvbik7CgogICAgICAgICR0aGlzLT53cml0ZSgkdGl0bGUuIlxuIi5zdHJfcmVwZWF0KCc9JywgSGVscGVyOjpzdHJsZW4oJHRpdGxlKSkpOwoKICAgICAgICBmb3JlYWNoICgkZGVzY3JpcHRpb24tPmdldE5hbWVzcGFjZXMoKSBhcyAkbmFtZXNwYWNlKSB7CiAgICAgICAgICAgIGlmIChBcHBsaWNhdGlvbkRlc2NyaXB0aW9uOjpHTE9CQUxfTkFNRVNQQUNFICE9PSAkbmFtZXNwYWNlWydpZCddKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuXG4iKTsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZSgnKionLiRuYW1lc3BhY2VbJ2lkJ10uJzoqKicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuXG4iKTsKICAgICAgICAgICAgJHRoaXMtPndyaXRlKGltcGxvZGUoIlxuIiwgYXJyYXlfbWFwKGZ1bmN0aW9uICgkY29tbWFuZE5hbWUpIHVzZSAoJGRlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZignKiBbYCVzYF0oIyVzKScsICRjb21tYW5kTmFtZSwgc3RyX3JlcGxhY2UoJzonLCAnJywgJGRlc2NyaXB0aW9uLT5nZXRDb21tYW5kKCRjb21tYW5kTmFtZSktPmdldE5hbWUoKSkpOwogICAgICAgICAgICB9LCAkbmFtZXNwYWNlWydjb21tYW5kcyddKSkpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGRlc2NyaXB0aW9uLT5nZXRDb21tYW5kcygpIGFzICRjb21tYW5kKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZSgiXG5cbiIpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGUoJHRoaXMtPmRlc2NyaWJlQ29tbWFuZCgkY29tbWFuZCkpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEFwcGxpY2F0aW9uVGl0bGUoQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uKQogICAgewogICAgICAgIGlmICgnVU5LTk9XTicgIT09ICRhcHBsaWNhdGlvbi0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgIGlmICgnVU5LTk9XTicgIT09ICRhcHBsaWNhdGlvbi0+Z2V0VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZignJXMgJXMnLCAkYXBwbGljYXRpb24tPmdldE5hbWUoKSwgJGFwcGxpY2F0aW9uLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGFwcGxpY2F0aW9uLT5nZXROYW1lKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ0NvbnNvbGUgVG9vbCc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXERlc2NyaXB0b3I7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxBcHBsaWNhdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dERlZmluaXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwoKLyoqCiAqIFhNTCBkZXNjcmlwdG9yLgogKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqCiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgWG1sRGVzY3JpcHRvciBleHRlbmRzIERlc2NyaXB0b3IKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIFxET01Eb2N1bWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5wdXREZWZpbml0aW9uRG9jdW1lbnQoSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uKQogICAgewogICAgICAgICRkb20gPSBuZXcgXERPTURvY3VtZW50KCcxLjAnLCAnVVRGLTgnKTsKICAgICAgICAkZG9tLT5hcHBlbmRDaGlsZCgkZGVmaW5pdGlvblhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2RlZmluaXRpb24nKSk7CgogICAgICAgICRkZWZpbml0aW9uWE1MLT5hcHBlbmRDaGlsZCgkYXJndW1lbnRzWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnYXJndW1lbnRzJykpOwogICAgICAgIGZvcmVhY2ggKCRkZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKSBhcyAkYXJndW1lbnQpIHsKICAgICAgICAgICAgJHRoaXMtPmFwcGVuZERvY3VtZW50KCRhcmd1bWVudHNYTUwsICR0aGlzLT5nZXRJbnB1dEFyZ3VtZW50RG9jdW1lbnQoJGFyZ3VtZW50KSk7CiAgICAgICAgfQoKICAgICAgICAkZGVmaW5pdGlvblhNTC0+YXBwZW5kQ2hpbGQoJG9wdGlvbnNYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdvcHRpb25zJykpOwogICAgICAgIGZvcmVhY2ggKCRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkgYXMgJG9wdGlvbikgewogICAgICAgICAgICAkdGhpcy0+YXBwZW5kRG9jdW1lbnQoJG9wdGlvbnNYTUwsICR0aGlzLT5nZXRJbnB1dE9wdGlvbkRvY3VtZW50KCRvcHRpb24pKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZG9tOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBcRE9NRG9jdW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbW1hbmREb2N1bWVudChDb21tYW5kICRjb21tYW5kKQogICAgewogICAgICAgICRkb20gPSBuZXcgXERPTURvY3VtZW50KCcxLjAnLCAnVVRGLTgnKTsKICAgICAgICAkZG9tLT5hcHBlbmRDaGlsZCgkY29tbWFuZFhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2NvbW1hbmQnKSk7CgogICAgICAgICRjb21tYW5kLT5nZXRTeW5vcHNpcygpOwogICAgICAgICRjb21tYW5kLT5tZXJnZUFwcGxpY2F0aW9uRGVmaW5pdGlvbihmYWxzZSk7CgogICAgICAgICRjb21tYW5kWE1MLT5zZXRBdHRyaWJ1dGUoJ2lkJywgJGNvbW1hbmQtPmdldE5hbWUoKSk7CiAgICAgICAgJGNvbW1hbmRYTUwtPnNldEF0dHJpYnV0ZSgnbmFtZScsICRjb21tYW5kLT5nZXROYW1lKCkpOwogICAgICAgICRjb21tYW5kWE1MLT5zZXRBdHRyaWJ1dGUoJ2hpZGRlbicsICRjb21tYW5kLT5pc0hpZGRlbigpID8gMSA6IDApOwoKICAgICAgICAkY29tbWFuZFhNTC0+YXBwZW5kQ2hpbGQoJHVzYWdlc1hNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ3VzYWdlcycpKTsKCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoWyRjb21tYW5kLT5nZXRTeW5vcHNpcygpXSwgJGNvbW1hbmQtPmdldEFsaWFzZXMoKSwgJGNvbW1hbmQtPmdldFVzYWdlcygpKSBhcyAkdXNhZ2UpIHsKICAgICAgICAgICAgJHVzYWdlc1hNTC0+YXBwZW5kQ2hpbGQoJGRvbS0+Y3JlYXRlRWxlbWVudCgndXNhZ2UnLCAkdXNhZ2UpKTsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kWE1MLT5hcHBlbmRDaGlsZCgkZGVzY3JpcHRpb25YTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdkZXNjcmlwdGlvbicpKTsKICAgICAgICAkZGVzY3JpcHRpb25YTUwtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZVRleHROb2RlKHN0cl9yZXBsYWNlKCJcbiIsICJcbiAiLCAkY29tbWFuZC0+Z2V0RGVzY3JpcHRpb24oKSkpKTsKCiAgICAgICAgJGNvbW1hbmRYTUwtPmFwcGVuZENoaWxkKCRoZWxwWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnaGVscCcpKTsKICAgICAgICAkaGVscFhNTC0+YXBwZW5kQ2hpbGQoJGRvbS0+Y3JlYXRlVGV4dE5vZGUoc3RyX3JlcGxhY2UoIlxuIiwgIlxuICIsICRjb21tYW5kLT5nZXRQcm9jZXNzZWRIZWxwKCkpKSk7CgogICAgICAgICRkZWZpbml0aW9uWE1MID0gJHRoaXMtPmdldElucHV0RGVmaW5pdGlvbkRvY3VtZW50KCRjb21tYW5kLT5nZXROYXRpdmVEZWZpbml0aW9uKCkpOwogICAgICAgICR0aGlzLT5hcHBlbmREb2N1bWVudCgkY29tbWFuZFhNTCwgJGRlZmluaXRpb25YTUwtPmdldEVsZW1lbnRzQnlUYWdOYW1lKCdkZWZpbml0aW9uJyktPml0ZW0oMCkpOwoKICAgICAgICByZXR1cm4gJGRvbTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkbmFtZXNwYWNlCiAgICAgKgogICAgICogQHJldHVybiBcRE9NRG9jdW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFwcGxpY2F0aW9uRG9jdW1lbnQoQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCAkbmFtZXNwYWNlID0gbnVsbCkKICAgIHsKICAgICAgICAkZG9tID0gbmV3IFxET01Eb2N1bWVudCgnMS4wJywgJ1VURi04Jyk7CiAgICAgICAgJGRvbS0+YXBwZW5kQ2hpbGQoJHJvb3RYbWwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdzeW1mb255JykpOwoKICAgICAgICBpZiAoJ1VOS05PV04nICE9PSAkYXBwbGljYXRpb24tPmdldE5hbWUoKSkgewogICAgICAgICAgICAkcm9vdFhtbC0+c2V0QXR0cmlidXRlKCduYW1lJywgJGFwcGxpY2F0aW9uLT5nZXROYW1lKCkpOwogICAgICAgICAgICBpZiAoJ1VOS05PV04nICE9PSAkYXBwbGljYXRpb24tPmdldFZlcnNpb24oKSkgewogICAgICAgICAgICAgICAgJHJvb3RYbWwtPnNldEF0dHJpYnV0ZSgndmVyc2lvbicsICRhcHBsaWNhdGlvbi0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJvb3RYbWwtPmFwcGVuZENoaWxkKCRjb21tYW5kc1hNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2NvbW1hbmRzJykpOwoKICAgICAgICAkZGVzY3JpcHRpb24gPSBuZXcgQXBwbGljYXRpb25EZXNjcmlwdGlvbigkYXBwbGljYXRpb24sICRuYW1lc3BhY2UsIHRydWUpOwoKICAgICAgICBpZiAoJG5hbWVzcGFjZSkgewogICAgICAgICAgICAkY29tbWFuZHNYTUwtPnNldEF0dHJpYnV0ZSgnbmFtZXNwYWNlJywgJG5hbWVzcGFjZSk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkZGVzY3JpcHRpb24tPmdldENvbW1hbmRzKCkgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgJHRoaXMtPmFwcGVuZERvY3VtZW50KCRjb21tYW5kc1hNTCwgJHRoaXMtPmdldENvbW1hbmREb2N1bWVudCgkY29tbWFuZCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkbmFtZXNwYWNlKSB7CiAgICAgICAgICAgICRyb290WG1sLT5hcHBlbmRDaGlsZCgkbmFtZXNwYWNlc1hNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ25hbWVzcGFjZXMnKSk7CgogICAgICAgICAgICBmb3JlYWNoICgkZGVzY3JpcHRpb24tPmdldE5hbWVzcGFjZXMoKSBhcyAkbmFtZXNwYWNlRGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VzWE1MLT5hcHBlbmRDaGlsZCgkbmFtZXNwYWNlQXJyYXlYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCduYW1lc3BhY2UnKSk7CiAgICAgICAgICAgICAgICAkbmFtZXNwYWNlQXJyYXlYTUwtPnNldEF0dHJpYnV0ZSgnaWQnLCAkbmFtZXNwYWNlRGVzY3JpcHRpb25bJ2lkJ10pOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRuYW1lc3BhY2VEZXNjcmlwdGlvblsnY29tbWFuZHMnXSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICRuYW1lc3BhY2VBcnJheVhNTC0+YXBwZW5kQ2hpbGQoJGNvbW1hbmRYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdjb21tYW5kJykpOwogICAgICAgICAgICAgICAgICAgICRjb21tYW5kWE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVUZXh0Tm9kZSgkbmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRvbTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlSW5wdXRBcmd1bWVudChJbnB1dEFyZ3VtZW50ICRhcmd1bWVudCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGVEb2N1bWVudCgkdGhpcy0+Z2V0SW5wdXRBcmd1bWVudERvY3VtZW50KCRhcmd1bWVudCkpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURvY3VtZW50KCR0aGlzLT5nZXRJbnB1dE9wdGlvbkRvY3VtZW50KCRvcHRpb24pKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlSW5wdXREZWZpbml0aW9uKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbiwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGVEb2N1bWVudCgkdGhpcy0+Z2V0SW5wdXREZWZpbml0aW9uRG9jdW1lbnQoJGRlZmluaXRpb24pKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQ29tbWFuZChDb21tYW5kICRjb21tYW5kLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURvY3VtZW50KCR0aGlzLT5nZXRDb21tYW5kRG9jdW1lbnQoJGNvbW1hbmQpKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURvY3VtZW50KCR0aGlzLT5nZXRBcHBsaWNhdGlvbkRvY3VtZW50KCRhcHBsaWNhdGlvbiwgaXNzZXQoJG9wdGlvbnNbJ25hbWVzcGFjZSddKSA/ICRvcHRpb25zWyduYW1lc3BhY2UnXSA6IG51bGwpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGVuZHMgZG9jdW1lbnQgY2hpbGRyZW4gdG8gcGFyZW50IG5vZGUuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwZW5kRG9jdW1lbnQoXERPTU5vZGUgJHBhcmVudE5vZGUsIFxET01Ob2RlICRpbXBvcnRlZFBhcmVudCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkaW1wb3J0ZWRQYXJlbnQtPmNoaWxkTm9kZXMgYXMgJGNoaWxkTm9kZSkgewogICAgICAgICAgICAkcGFyZW50Tm9kZS0+YXBwZW5kQ2hpbGQoJHBhcmVudE5vZGUtPm93bmVyRG9jdW1lbnQtPmltcG9ydE5vZGUoJGNoaWxkTm9kZSwgdHJ1ZSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyBET00gZG9jdW1lbnQuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gd3JpdGVEb2N1bWVudChcRE9NRG9jdW1lbnQgJGRvbSkKICAgIHsKICAgICAgICAkZG9tLT5mb3JtYXRPdXRwdXQgPSB0cnVlOwogICAgICAgICR0aGlzLT53cml0ZSgkZG9tLT5zYXZlWE1MKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBcRE9NRG9jdW1lbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbnB1dEFyZ3VtZW50RG9jdW1lbnQoSW5wdXRBcmd1bWVudCAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJGRvbSA9IG5ldyBcRE9NRG9jdW1lbnQoJzEuMCcsICdVVEYtOCcpOwoKICAgICAgICAkZG9tLT5hcHBlbmRDaGlsZCgkb2JqZWN0WE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnYXJndW1lbnQnKSk7CiAgICAgICAgJG9iamVjdFhNTC0+c2V0QXR0cmlidXRlKCduYW1lJywgJGFyZ3VtZW50LT5nZXROYW1lKCkpOwogICAgICAgICRvYmplY3RYTUwtPnNldEF0dHJpYnV0ZSgnaXNfcmVxdWlyZWQnLCAkYXJndW1lbnQtPmlzUmVxdWlyZWQoKSA/IDEgOiAwKTsKICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ2lzX2FycmF5JywgJGFyZ3VtZW50LT5pc0FycmF5KCkgPyAxIDogMCk7CiAgICAgICAgJG9iamVjdFhNTC0+YXBwZW5kQ2hpbGQoJGRlc2NyaXB0aW9uWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVzY3JpcHRpb24nKSk7CiAgICAgICAgJGRlc2NyaXB0aW9uWE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVUZXh0Tm9kZSgkYXJndW1lbnQtPmdldERlc2NyaXB0aW9uKCkpKTsKCiAgICAgICAgJG9iamVjdFhNTC0+YXBwZW5kQ2hpbGQoJGRlZmF1bHRzWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVmYXVsdHMnKSk7CiAgICAgICAgJGRlZmF1bHRzID0gXGlzX2FycmF5KCRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpKSA/ICRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpIDogKFxpc19ib29sKCRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpKSA/IFt2YXJfZXhwb3J0KCRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpLCB0cnVlKV0gOiAoJGFyZ3VtZW50LT5nZXREZWZhdWx0KCkgPyBbJGFyZ3VtZW50LT5nZXREZWZhdWx0KCldIDogW10pKTsKICAgICAgICBmb3JlYWNoICgkZGVmYXVsdHMgYXMgJGRlZmF1bHQpIHsKICAgICAgICAgICAgJGRlZmF1bHRzWE1MLT5hcHBlbmRDaGlsZCgkZGVmYXVsdFhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2RlZmF1bHQnKSk7CiAgICAgICAgICAgICRkZWZhdWx0WE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVUZXh0Tm9kZSgkZGVmYXVsdCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkb207CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFxET01Eb2N1bWVudAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldElucHV0T3B0aW9uRG9jdW1lbnQoSW5wdXRPcHRpb24gJG9wdGlvbikKICAgIHsKICAgICAgICAkZG9tID0gbmV3IFxET01Eb2N1bWVudCgnMS4wJywgJ1VURi04Jyk7CgogICAgICAgICRkb20tPmFwcGVuZENoaWxkKCRvYmplY3RYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdvcHRpb24nKSk7CiAgICAgICAgJG9iamVjdFhNTC0+c2V0QXR0cmlidXRlKCduYW1lJywgJy0tJy4kb3B0aW9uLT5nZXROYW1lKCkpOwogICAgICAgICRwb3MgPSBzdHJwb3MoJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSwgJ3wnKTsKICAgICAgICBpZiAoZmFsc2UgIT09ICRwb3MpIHsKICAgICAgICAgICAgJG9iamVjdFhNTC0+c2V0QXR0cmlidXRlKCdzaG9ydGN1dCcsICctJy5zdWJzdHIoJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSwgMCwgJHBvcykpOwogICAgICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ3Nob3J0Y3V0cycsICctJy5zdHJfcmVwbGFjZSgnfCcsICd8LScsICRvcHRpb24tPmdldFNob3J0Y3V0KCkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ3Nob3J0Y3V0JywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSA/ICctJy4kb3B0aW9uLT5nZXRTaG9ydGN1dCgpIDogJycpOwogICAgICAgIH0KICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ2FjY2VwdF92YWx1ZScsICRvcHRpb24tPmFjY2VwdFZhbHVlKCkgPyAxIDogMCk7CiAgICAgICAgJG9iamVjdFhNTC0+c2V0QXR0cmlidXRlKCdpc192YWx1ZV9yZXF1aXJlZCcsICRvcHRpb24tPmlzVmFsdWVSZXF1aXJlZCgpID8gMSA6IDApOwogICAgICAgICRvYmplY3RYTUwtPnNldEF0dHJpYnV0ZSgnaXNfbXVsdGlwbGUnLCAkb3B0aW9uLT5pc0FycmF5KCkgPyAxIDogMCk7CiAgICAgICAgJG9iamVjdFhNTC0+YXBwZW5kQ2hpbGQoJGRlc2NyaXB0aW9uWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVzY3JpcHRpb24nKSk7CiAgICAgICAgJGRlc2NyaXB0aW9uWE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVUZXh0Tm9kZSgkb3B0aW9uLT5nZXREZXNjcmlwdGlvbigpKSk7CgogICAgICAgIGlmICgkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgICRkZWZhdWx0cyA9IFxpc19hcnJheSgkb3B0aW9uLT5nZXREZWZhdWx0KCkpID8gJG9wdGlvbi0+Z2V0RGVmYXVsdCgpIDogKFxpc19ib29sKCRvcHRpb24tPmdldERlZmF1bHQoKSkgPyBbdmFyX2V4cG9ydCgkb3B0aW9uLT5nZXREZWZhdWx0KCksIHRydWUpXSA6ICgkb3B0aW9uLT5nZXREZWZhdWx0KCkgPyBbJG9wdGlvbi0+Z2V0RGVmYXVsdCgpXSA6IFtdKSk7CiAgICAgICAgICAgICRvYmplY3RYTUwtPmFwcGVuZENoaWxkKCRkZWZhdWx0c1hNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2RlZmF1bHRzJykpOwoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkZGVmYXVsdHMpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGVmYXVsdHMgYXMgJGRlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICAkZGVmYXVsdHNYTUwtPmFwcGVuZENoaWxkKCRkZWZhdWx0WE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVmYXVsdCcpKTsKICAgICAgICAgICAgICAgICAgICAkZGVmYXVsdFhNTC0+YXBwZW5kQ2hpbGQoJGRvbS0+Y3JlYXRlVGV4dE5vZGUoJGRlZmF1bHQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkb207CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXERlc2NyaXB0b3I7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIERlc2NyaXB0b3IgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqLwppbnRlcmZhY2UgRGVzY3JpcHRvckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBvYmplY3QgaWYgc3VwcG9ydGVkLgogICAgICoKICAgICAqIEBwYXJhbSBvYmplY3QgJG9iamVjdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVzY3JpYmUoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRvYmplY3QsIGFycmF5ICRvcHRpb25zID0gW10pOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKCi8qKgogKiBKU09OIGRlc2NyaXB0b3IuCiAqCiAqIEBhdXRob3IgSmVhbi1GcmFuw6dvaXMgU2ltb24gPGNvbnRhY3RAamZzaW1vbi5mcj4KICoKICogQGludGVybmFsCiAqLwpjbGFzcyBKc29uRGVzY3JpcHRvciBleHRlbmRzIERlc2NyaXB0b3IKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0QXJndW1lbnQoSW5wdXRBcmd1bWVudCAkYXJndW1lbnQsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRGF0YSgkdGhpcy0+Z2V0SW5wdXRBcmd1bWVudERhdGEoJGFyZ3VtZW50KSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURhdGEoJHRoaXMtPmdldElucHV0T3B0aW9uRGF0YSgkb3B0aW9uKSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dERlZmluaXRpb24oSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURhdGEoJHRoaXMtPmdldElucHV0RGVmaW5pdGlvbkRhdGEoJGRlZmluaXRpb24pLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUNvbW1hbmQoQ29tbWFuZCAkY29tbWFuZCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGVEYXRhKCR0aGlzLT5nZXRDb21tYW5kRGF0YSgkY29tbWFuZCksICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRkZXNjcmliZWROYW1lc3BhY2UgPSBpc3NldCgkb3B0aW9uc1snbmFtZXNwYWNlJ10pID8gJG9wdGlvbnNbJ25hbWVzcGFjZSddIDogbnVsbDsKICAgICAgICAkZGVzY3JpcHRpb24gPSBuZXcgQXBwbGljYXRpb25EZXNjcmlwdGlvbigkYXBwbGljYXRpb24sICRkZXNjcmliZWROYW1lc3BhY2UsIHRydWUpOwogICAgICAgICRjb21tYW5kcyA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkZGVzY3JpcHRpb24tPmdldENvbW1hbmRzKCkgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgJGNvbW1hbmRzW10gPSAkdGhpcy0+Z2V0Q29tbWFuZERhdGEoJGNvbW1hbmQpOwogICAgICAgIH0KCiAgICAgICAgJGRhdGEgPSBbXTsKICAgICAgICBpZiAoJ1VOS05PV04nICE9PSAkYXBwbGljYXRpb24tPmdldE5hbWUoKSkgewogICAgICAgICAgICAkZGF0YVsnYXBwbGljYXRpb24nXVsnbmFtZSddID0gJGFwcGxpY2F0aW9uLT5nZXROYW1lKCk7CiAgICAgICAgICAgIGlmICgnVU5LTk9XTicgIT09ICRhcHBsaWNhdGlvbi0+Z2V0VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnYXBwbGljYXRpb24nXVsndmVyc2lvbiddID0gJGFwcGxpY2F0aW9uLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRkYXRhWydjb21tYW5kcyddID0gJGNvbW1hbmRzOwoKICAgICAgICBpZiAoJGRlc2NyaWJlZE5hbWVzcGFjZSkgewogICAgICAgICAgICAkZGF0YVsnbmFtZXNwYWNlJ10gPSAkZGVzY3JpYmVkTmFtZXNwYWNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRkYXRhWyduYW1lc3BhY2VzJ10gPSBhcnJheV92YWx1ZXMoJGRlc2NyaXB0aW9uLT5nZXROYW1lc3BhY2VzKCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPndyaXRlRGF0YSgkZGF0YSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogV3JpdGVzIGRhdGEgYXMganNvbi4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZURhdGEoYXJyYXkgJGRhdGEsIGFycmF5ICRvcHRpb25zKQogICAgewogICAgICAgICRmbGFncyA9IGlzc2V0KCRvcHRpb25zWydqc29uX2VuY29kaW5nJ10pID8gJG9wdGlvbnNbJ2pzb25fZW5jb2RpbmcnXSA6IDA7CgogICAgICAgICR0aGlzLT53cml0ZShqc29uX2VuY29kZSgkZGF0YSwgJGZsYWdzKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0SW5wdXRBcmd1bWVudERhdGEoSW5wdXRBcmd1bWVudCAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgJ25hbWUnID0+ICRhcmd1bWVudC0+Z2V0TmFtZSgpLAogICAgICAgICAgICAnaXNfcmVxdWlyZWQnID0+ICRhcmd1bWVudC0+aXNSZXF1aXJlZCgpLAogICAgICAgICAgICAnaXNfYXJyYXknID0+ICRhcmd1bWVudC0+aXNBcnJheSgpLAogICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+IHByZWdfcmVwbGFjZSgnL1xzKltcclxuXVxzKi8nLCAnICcsICRhcmd1bWVudC0+Z2V0RGVzY3JpcHRpb24oKSksCiAgICAgICAgICAgICdkZWZhdWx0JyA9PiBcSU5GID09PSAkYXJndW1lbnQtPmdldERlZmF1bHQoKSA/ICdJTkYnIDogJGFyZ3VtZW50LT5nZXREZWZhdWx0KCksCiAgICAgICAgXTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbnB1dE9wdGlvbkRhdGEoSW5wdXRPcHRpb24gJG9wdGlvbikKICAgIHsKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAnbmFtZScgPT4gJy0tJy4kb3B0aW9uLT5nZXROYW1lKCksCiAgICAgICAgICAgICdzaG9ydGN1dCcgPT4gJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSA/ICctJy5zdHJfcmVwbGFjZSgnfCcsICd8LScsICRvcHRpb24tPmdldFNob3J0Y3V0KCkpIDogJycsCiAgICAgICAgICAgICdhY2NlcHRfdmFsdWUnID0+ICRvcHRpb24tPmFjY2VwdFZhbHVlKCksCiAgICAgICAgICAgICdpc192YWx1ZV9yZXF1aXJlZCcgPT4gJG9wdGlvbi0+aXNWYWx1ZVJlcXVpcmVkKCksCiAgICAgICAgICAgICdpc19tdWx0aXBsZScgPT4gJG9wdGlvbi0+aXNBcnJheSgpLAogICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+IHByZWdfcmVwbGFjZSgnL1xzKltcclxuXVxzKi8nLCAnICcsICRvcHRpb24tPmdldERlc2NyaXB0aW9uKCkpLAogICAgICAgICAgICAnZGVmYXVsdCcgPT4gXElORiA9PT0gJG9wdGlvbi0+Z2V0RGVmYXVsdCgpID8gJ0lORicgOiAkb3B0aW9uLT5nZXREZWZhdWx0KCksCiAgICAgICAgXTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbnB1dERlZmluaXRpb25EYXRhKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbikKICAgIHsKICAgICAgICAkaW5wdXRBcmd1bWVudHMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkgYXMgJG5hbWUgPT4gJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICRpbnB1dEFyZ3VtZW50c1skbmFtZV0gPSAkdGhpcy0+Z2V0SW5wdXRBcmd1bWVudERhdGEoJGFyZ3VtZW50KTsKICAgICAgICB9CgogICAgICAgICRpbnB1dE9wdGlvbnMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbi0+Z2V0T3B0aW9ucygpIGFzICRuYW1lID0+ICRvcHRpb24pIHsKICAgICAgICAgICAgJGlucHV0T3B0aW9uc1skbmFtZV0gPSAkdGhpcy0+Z2V0SW5wdXRPcHRpb25EYXRhKCRvcHRpb24pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFsnYXJndW1lbnRzJyA9PiAkaW5wdXRBcmd1bWVudHMsICdvcHRpb25zJyA9PiAkaW5wdXRPcHRpb25zXTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb21tYW5kRGF0YShDb21tYW5kICRjb21tYW5kKQogICAgewogICAgICAgICRjb21tYW5kLT5nZXRTeW5vcHNpcygpOwogICAgICAgICRjb21tYW5kLT5tZXJnZUFwcGxpY2F0aW9uRGVmaW5pdGlvbihmYWxzZSk7CgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICduYW1lJyA9PiAkY29tbWFuZC0+Z2V0TmFtZSgpLAogICAgICAgICAgICAndXNhZ2UnID0+IGFycmF5X21lcmdlKFskY29tbWFuZC0+Z2V0U3lub3BzaXMoKV0sICRjb21tYW5kLT5nZXRVc2FnZXMoKSwgJGNvbW1hbmQtPmdldEFsaWFzZXMoKSksCiAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gJGNvbW1hbmQtPmdldERlc2NyaXB0aW9uKCksCiAgICAgICAgICAgICdoZWxwJyA9PiAkY29tbWFuZC0+Z2V0UHJvY2Vzc2VkSGVscCgpLAogICAgICAgICAgICAnZGVmaW5pdGlvbicgPT4gJHRoaXMtPmdldElucHV0RGVmaW5pdGlvbkRhdGEoJGNvbW1hbmQtPmdldE5hdGl2ZURlZmluaXRpb24oKSksCiAgICAgICAgICAgICdoaWRkZW4nID0+ICRjb21tYW5kLT5pc0hpZGRlbigpLAogICAgICAgIF07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXERlc2NyaXB0b3I7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxBcHBsaWNhdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgSmVhbi1GcmFuw6dvaXMgU2ltb24gPGplYW5mcmFuY29pcy5zaW1vbkBzZW5zaW9sYWJzLmNvbT4KICoKICogQGludGVybmFsCiAqLwpjbGFzcyBBcHBsaWNhdGlvbkRlc2NyaXB0aW9uCnsKICAgIGNvbnN0IEdMT0JBTF9OQU1FU1BBQ0UgPSAnX2dsb2JhbCc7CgogICAgcHJpdmF0ZSAkYXBwbGljYXRpb247CiAgICBwcml2YXRlICRuYW1lc3BhY2U7CiAgICBwcml2YXRlICRzaG93SGlkZGVuOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRuYW1lc3BhY2VzOwoKICAgIC8qKgogICAgICogQHZhciBDb21tYW5kW10KICAgICAqLwogICAgcHJpdmF0ZSAkY29tbWFuZHM7CgogICAgLyoqCiAgICAgKiBAdmFyIENvbW1hbmRbXQogICAgICovCiAgICBwcml2YXRlICRhbGlhc2VzOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRuYW1lc3BhY2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkc2hvd0hpZGRlbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCAkbmFtZXNwYWNlID0gbnVsbCwgJHNob3dIaWRkZW4gPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+YXBwbGljYXRpb24gPSAkYXBwbGljYXRpb247CiAgICAgICAgJHRoaXMtPm5hbWVzcGFjZSA9ICRuYW1lc3BhY2U7CiAgICAgICAgJHRoaXMtPnNob3dIaWRkZW4gPSAkc2hvd0hpZGRlbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWVzcGFjZXMoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+bmFtZXNwYWNlcykgewogICAgICAgICAgICAkdGhpcy0+aW5zcGVjdEFwcGxpY2F0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWVzcGFjZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbW1hbmRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZHMoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+Y29tbWFuZHMpIHsKICAgICAgICAgICAgJHRoaXMtPmluc3BlY3RBcHBsaWNhdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21tYW5kczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1hbmQKICAgICAqCiAgICAgKiBAdGhyb3dzIENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5jb21tYW5kc1skbmFtZV0pICYmICFpc3NldCgkdGhpcy0+YWxpYXNlc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDb21tYW5kTm90Rm91bmRFeGNlcHRpb24oc3ByaW50ZignQ29tbWFuZCAiJXMiIGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmNvbW1hbmRzWyRuYW1lXSkgPyAkdGhpcy0+Y29tbWFuZHNbJG5hbWVdIDogJHRoaXMtPmFsaWFzZXNbJG5hbWVdOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaW5zcGVjdEFwcGxpY2F0aW9uKCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWFuZHMgPSBbXTsKICAgICAgICAkdGhpcy0+bmFtZXNwYWNlcyA9IFtdOwoKICAgICAgICAkYWxsID0gJHRoaXMtPmFwcGxpY2F0aW9uLT5hbGwoJHRoaXMtPm5hbWVzcGFjZSA/ICR0aGlzLT5hcHBsaWNhdGlvbi0+ZmluZE5hbWVzcGFjZSgkdGhpcy0+bmFtZXNwYWNlKSA6IG51bGwpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5zb3J0Q29tbWFuZHMoJGFsbCkgYXMgJG5hbWVzcGFjZSA9PiAkY29tbWFuZHMpIHsKICAgICAgICAgICAgJG5hbWVzID0gW107CgogICAgICAgICAgICAvKiogQHZhciBDb21tYW5kICRjb21tYW5kICovCiAgICAgICAgICAgIGZvcmVhY2ggKCRjb21tYW5kcyBhcyAkbmFtZSA9PiAkY29tbWFuZCkgewogICAgICAgICAgICAgICAgaWYgKCEkY29tbWFuZC0+Z2V0TmFtZSgpIHx8ICghJHRoaXMtPnNob3dIaWRkZW4gJiYgJGNvbW1hbmQtPmlzSGlkZGVuKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRjb21tYW5kLT5nZXROYW1lKCkgPT09ICRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbW1hbmRzWyRuYW1lXSA9ICRjb21tYW5kOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWxpYXNlc1skbmFtZV0gPSAkY29tbWFuZDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbmFtZXNbXSA9ICRuYW1lOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+bmFtZXNwYWNlc1skbmFtZXNwYWNlXSA9IFsnaWQnID0+ICRuYW1lc3BhY2UsICdjb21tYW5kcycgPT4gJG5hbWVzXTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc29ydENvbW1hbmRzKGFycmF5ICRjb21tYW5kcykKICAgIHsKICAgICAgICAkbmFtZXNwYWNlZENvbW1hbmRzID0gW107CiAgICAgICAgJGdsb2JhbENvbW1hbmRzID0gW107CiAgICAgICAgJHNvcnRlZENvbW1hbmRzID0gW107CiAgICAgICAgZm9yZWFjaCAoJGNvbW1hbmRzIGFzICRuYW1lID0+ICRjb21tYW5kKSB7CiAgICAgICAgICAgICRrZXkgPSAkdGhpcy0+YXBwbGljYXRpb24tPmV4dHJhY3ROYW1lc3BhY2UoJG5hbWUsIDEpOwogICAgICAgICAgICBpZiAoXGluX2FycmF5KCRrZXksIFsnJywgc2VsZjo6R0xPQkFMX05BTUVTUEFDRV0sIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkZ2xvYmFsQ29tbWFuZHNbJG5hbWVdID0gJGNvbW1hbmQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbmFtZXNwYWNlZENvbW1hbmRzWyRrZXldWyRuYW1lXSA9ICRjb21tYW5kOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGdsb2JhbENvbW1hbmRzKSB7CiAgICAgICAgICAgIGtzb3J0KCRnbG9iYWxDb21tYW5kcyk7CiAgICAgICAgICAgICRzb3J0ZWRDb21tYW5kc1tzZWxmOjpHTE9CQUxfTkFNRVNQQUNFXSA9ICRnbG9iYWxDb21tYW5kczsKICAgICAgICB9CgogICAgICAgIGlmICgkbmFtZXNwYWNlZENvbW1hbmRzKSB7CiAgICAgICAgICAgIGtzb3J0KCRuYW1lc3BhY2VkQ29tbWFuZHMpOwogICAgICAgICAgICBmb3JlYWNoICgkbmFtZXNwYWNlZENvbW1hbmRzIGFzICRrZXkgPT4gJGNvbW1hbmRzU2V0KSB7CiAgICAgICAgICAgICAgICBrc29ydCgkY29tbWFuZHNTZXQpOwogICAgICAgICAgICAgICAgJHNvcnRlZENvbW1hbmRzWyRrZXldID0gJGNvbW1hbmRzU2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNvcnRlZENvbW1hbmRzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxqZWFuZnJhbmNvaXMuc2ltb25Ac2Vuc2lvbGFicy5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KYWJzdHJhY3QgY2xhc3MgRGVzY3JpcHRvciBpbXBsZW1lbnRzIERlc2NyaXB0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAdmFyIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJG91dHB1dDsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlc2NyaWJlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkb2JqZWN0LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwoKICAgICAgICBzd2l0Y2ggKHRydWUpIHsKICAgICAgICAgICAgY2FzZSAkb2JqZWN0IGluc3RhbmNlb2YgSW5wdXRBcmd1bWVudDoKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0QXJndW1lbnQoJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJG9iamVjdCBpbnN0YW5jZW9mIElucHV0T3B0aW9uOgogICAgICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXRPcHRpb24oJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJG9iamVjdCBpbnN0YW5jZW9mIElucHV0RGVmaW5pdGlvbjoKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0RGVmaW5pdGlvbigkb2JqZWN0LCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAkb2JqZWN0IGluc3RhbmNlb2YgQ29tbWFuZDoKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUNvbW1hbmQoJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJG9iamVjdCBpbnN0YW5jZW9mIEFwcGxpY2F0aW9uOgogICAgICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlQXBwbGljYXRpb24oJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ09iamVjdCBvZiB0eXBlICIlcyIgaXMgbm90IGRlc2NyaWJhYmxlLicsIFxnZXRfY2xhc3MoJG9iamVjdCkpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZXMgY29udGVudCB0byBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudAogICAgICogQHBhcmFtIGJvb2wgICAkZGVjb3JhdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSgkY29udGVudCwgJGRlY29yYXRlZCA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQtPndyaXRlKCRjb250ZW50LCBmYWxzZSwgJGRlY29yYXRlZCA/IE91dHB1dEludGVyZmFjZTo6T1VUUFVUX05PUk1BTCA6IE91dHB1dEludGVyZmFjZTo6T1VUUFVUX1JBVyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYW4gSW5wdXRBcmd1bWVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xtaXhlZAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dEFyZ3VtZW50KElucHV0QXJndW1lbnQgJGFyZ3VtZW50LCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKCiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBJbnB1dE9wdGlvbiBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xtaXhlZAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKCiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBJbnB1dERlZmluaXRpb24gaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bWl4ZWQKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlSW5wdXREZWZpbml0aW9uKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbiwgYXJyYXkgJG9wdGlvbnMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYSBDb21tYW5kIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG1peGVkCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUNvbW1hbmQoQ29tbWFuZCAkY29tbWFuZCwgYXJyYXkgJG9wdGlvbnMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYW4gQXBwbGljYXRpb24gaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bWl4ZWQKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEFwcGxpY2F0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxIZWxwZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0RGVmaW5pdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CgovKioKICogVGV4dCBkZXNjcmlwdG9yLgogKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqCiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgVGV4dERlc2NyaXB0b3IgZXh0ZW5kcyBEZXNjcmlwdG9yCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dEFyZ3VtZW50KElucHV0QXJndW1lbnQgJGFyZ3VtZW50LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkYXJndW1lbnQtPmdldERlZmF1bHQoKSAmJiAoIVxpc19hcnJheSgkYXJndW1lbnQtPmdldERlZmF1bHQoKSkgfHwgXGNvdW50KCRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpKSkpIHsKICAgICAgICAgICAgJGRlZmF1bHQgPSBzcHJpbnRmKCc8Y29tbWVudD4gW2RlZmF1bHQ6ICVzXTwvY29tbWVudD4nLCAkdGhpcy0+Zm9ybWF0RGVmYXVsdFZhbHVlKCRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGRlZmF1bHQgPSAnJzsKICAgICAgICB9CgogICAgICAgICR0b3RhbFdpZHRoID0gaXNzZXQoJG9wdGlvbnNbJ3RvdGFsX3dpZHRoJ10pID8gJG9wdGlvbnNbJ3RvdGFsX3dpZHRoJ10gOiBIZWxwZXI6OnN0cmxlbigkYXJndW1lbnQtPmdldE5hbWUoKSk7CiAgICAgICAgJHNwYWNpbmdXaWR0aCA9ICR0b3RhbFdpZHRoIC0gXHN0cmxlbigkYXJndW1lbnQtPmdldE5hbWUoKSk7CgogICAgICAgICR0aGlzLT53cml0ZVRleHQoc3ByaW50ZignICA8aW5mbz4lczwvaW5mbz4gICVzJXMlcycsCiAgICAgICAgICAgICRhcmd1bWVudC0+Z2V0TmFtZSgpLAogICAgICAgICAgICBzdHJfcmVwZWF0KCcgJywgJHNwYWNpbmdXaWR0aCksCiAgICAgICAgICAgIC8vICsgNCA9IDIgc3BhY2VzIGJlZm9yZSA8aW5mbz4sIDIgc3BhY2VzIGFmdGVyIDwvaW5mbz4KICAgICAgICAgICAgcHJlZ19yZXBsYWNlKCcvXHMqW1xyXG5dXHMqLycsICJcbiIuc3RyX3JlcGVhdCgnICcsICR0b3RhbFdpZHRoICsgNCksICRhcmd1bWVudC0+Z2V0RGVzY3JpcHRpb24oKSksCiAgICAgICAgICAgICRkZWZhdWx0CiAgICAgICAgKSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGlmICgkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpICYmIG51bGwgIT09ICRvcHRpb24tPmdldERlZmF1bHQoKSAmJiAoIVxpc19hcnJheSgkb3B0aW9uLT5nZXREZWZhdWx0KCkpIHx8IFxjb3VudCgkb3B0aW9uLT5nZXREZWZhdWx0KCkpKSkgewogICAgICAgICAgICAkZGVmYXVsdCA9IHNwcmludGYoJzxjb21tZW50PiBbZGVmYXVsdDogJXNdPC9jb21tZW50PicsICR0aGlzLT5mb3JtYXREZWZhdWx0VmFsdWUoJG9wdGlvbi0+Z2V0RGVmYXVsdCgpKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGRlZmF1bHQgPSAnJzsKICAgICAgICB9CgogICAgICAgICR2YWx1ZSA9ICcnOwogICAgICAgIGlmICgkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICc9Jy5zdHJ0b3VwcGVyKCRvcHRpb24tPmdldE5hbWUoKSk7CgogICAgICAgICAgICBpZiAoJG9wdGlvbi0+aXNWYWx1ZU9wdGlvbmFsKCkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICdbJy4kdmFsdWUuJ10nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdG90YWxXaWR0aCA9IGlzc2V0KCRvcHRpb25zWyd0b3RhbF93aWR0aCddKSA/ICRvcHRpb25zWyd0b3RhbF93aWR0aCddIDogJHRoaXMtPmNhbGN1bGF0ZVRvdGFsV2lkdGhGb3JPcHRpb25zKFskb3B0aW9uXSk7CiAgICAgICAgJHN5bm9wc2lzID0gc3ByaW50ZignJXMlcycsCiAgICAgICAgICAgICRvcHRpb24tPmdldFNob3J0Y3V0KCkgPyBzcHJpbnRmKCctJXMsICcsICRvcHRpb24tPmdldFNob3J0Y3V0KCkpIDogJyAgICAnLAogICAgICAgICAgICBzcHJpbnRmKCctLSVzJXMnLCAkb3B0aW9uLT5nZXROYW1lKCksICR2YWx1ZSkKICAgICAgICApOwoKICAgICAgICAkc3BhY2luZ1dpZHRoID0gJHRvdGFsV2lkdGggLSBIZWxwZXI6OnN0cmxlbigkc3lub3BzaXMpOwoKICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KHNwcmludGYoJyAgPGluZm8+JXM8L2luZm8+ICAlcyVzJXMlcycsCiAgICAgICAgICAgICRzeW5vcHNpcywKICAgICAgICAgICAgc3RyX3JlcGVhdCgnICcsICRzcGFjaW5nV2lkdGgpLAogICAgICAgICAgICAvLyArIDQgPSAyIHNwYWNlcyBiZWZvcmUgPGluZm8+LCAyIHNwYWNlcyBhZnRlciA8L2luZm8+CiAgICAgICAgICAgIHByZWdfcmVwbGFjZSgnL1xzKltcclxuXVxzKi8nLCAiXG4iLnN0cl9yZXBlYXQoJyAnLCAkdG90YWxXaWR0aCArIDQpLCAkb3B0aW9uLT5nZXREZXNjcmlwdGlvbigpKSwKICAgICAgICAgICAgJGRlZmF1bHQsCiAgICAgICAgICAgICRvcHRpb24tPmlzQXJyYXkoKSA/ICc8Y29tbWVudD4gKG11bHRpcGxlIHZhbHVlcyBhbGxvd2VkKTwvY29tbWVudD4nIDogJycKICAgICAgICApLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0RGVmaW5pdGlvbihJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRvdGFsV2lkdGggPSAkdGhpcy0+Y2FsY3VsYXRlVG90YWxXaWR0aEZvck9wdGlvbnMoJGRlZmluaXRpb24tPmdldE9wdGlvbnMoKSk7CiAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpIGFzICRhcmd1bWVudCkgewogICAgICAgICAgICAkdG90YWxXaWR0aCA9IG1heCgkdG90YWxXaWR0aCwgSGVscGVyOjpzdHJsZW4oJGFyZ3VtZW50LT5nZXROYW1lKCkpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgnPGNvbW1lbnQ+QXJndW1lbnRzOjwvY29tbWVudD4nLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKSBhcyAkYXJndW1lbnQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0QXJndW1lbnQoJGFyZ3VtZW50LCBhcnJheV9tZXJnZSgkb3B0aW9ucywgWyd0b3RhbF93aWR0aCcgPT4gJHRvdGFsV2lkdGhdKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpICYmICRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZGVmaW5pdGlvbi0+Z2V0T3B0aW9ucygpKSB7CiAgICAgICAgICAgICRsYXRlck9wdGlvbnMgPSBbXTsKCiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoJzxjb21tZW50Pk9wdGlvbnM6PC9jb21tZW50PicsICRvcHRpb25zKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24tPmdldE9wdGlvbnMoKSBhcyAkb3B0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoXHN0cmxlbigkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAkbGF0ZXJPcHRpb25zW10gPSAkb3B0aW9uOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0T3B0aW9uKCRvcHRpb24sIGFycmF5X21lcmdlKCRvcHRpb25zLCBbJ3RvdGFsX3dpZHRoJyA9PiAkdG90YWxXaWR0aF0pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkbGF0ZXJPcHRpb25zIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVzY3JpYmVJbnB1dE9wdGlvbigkb3B0aW9uLCBhcnJheV9tZXJnZSgkb3B0aW9ucywgWyd0b3RhbF93aWR0aCcgPT4gJHRvdGFsV2lkdGhdKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUNvbW1hbmQoQ29tbWFuZCAkY29tbWFuZCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkY29tbWFuZC0+Z2V0U3lub3BzaXModHJ1ZSk7CiAgICAgICAgJGNvbW1hbmQtPmdldFN5bm9wc2lzKGZhbHNlKTsKICAgICAgICAkY29tbWFuZC0+bWVyZ2VBcHBsaWNhdGlvbkRlZmluaXRpb24oZmFsc2UpOwoKICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCc8Y29tbWVudD5Vc2FnZTo8L2NvbW1lbnQ+JywgJG9wdGlvbnMpOwogICAgICAgIGZvcmVhY2ggKGFycmF5X21lcmdlKFskY29tbWFuZC0+Z2V0U3lub3BzaXModHJ1ZSldLCAkY29tbWFuZC0+Z2V0QWxpYXNlcygpLCAkY29tbWFuZC0+Z2V0VXNhZ2VzKCkpIGFzICR1c2FnZSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCcgICcuT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoJHVzYWdlKSwgJG9wdGlvbnMpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwoKICAgICAgICAkZGVmaW5pdGlvbiA9ICRjb21tYW5kLT5nZXROYXRpdmVEZWZpbml0aW9uKCk7CiAgICAgICAgaWYgKCRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkgfHwgJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0RGVmaW5pdGlvbigkZGVmaW5pdGlvbiwgJG9wdGlvbnMpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRoZWxwID0gJGNvbW1hbmQtPmdldFByb2Nlc3NlZEhlbHAoKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCc8Y29tbWVudD5IZWxwOjwvY29tbWVudD4nLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoJyAgJy5zdHJfcmVwbGFjZSgiXG4iLCAiXG4gICIsICRoZWxwKSwgJG9wdGlvbnMpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRkZXNjcmliZWROYW1lc3BhY2UgPSBpc3NldCgkb3B0aW9uc1snbmFtZXNwYWNlJ10pID8gJG9wdGlvbnNbJ25hbWVzcGFjZSddIDogbnVsbDsKICAgICAgICAkZGVzY3JpcHRpb24gPSBuZXcgQXBwbGljYXRpb25EZXNjcmlwdGlvbigkYXBwbGljYXRpb24sICRkZXNjcmliZWROYW1lc3BhY2UpOwoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3Jhd190ZXh0J10pICYmICRvcHRpb25zWydyYXdfdGV4dCddKSB7CiAgICAgICAgICAgICR3aWR0aCA9ICR0aGlzLT5nZXRDb2x1bW5XaWR0aCgkZGVzY3JpcHRpb24tPmdldENvbW1hbmRzKCkpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGRlc2NyaXB0aW9uLT5nZXRDb21tYW5kcygpIGFzICRjb21tYW5kKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KHNwcmludGYoIiUteyR3aWR0aH1zICVzIiwgJGNvbW1hbmQtPmdldE5hbWUoKSwgJGNvbW1hbmQtPmdldERlc2NyaXB0aW9uKCkpLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCcnICE9ICRoZWxwID0gJGFwcGxpY2F0aW9uLT5nZXRIZWxwKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIiRoZWxwXG5cbiIsICRvcHRpb25zKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiPGNvbW1lbnQ+VXNhZ2U6PC9jb21tZW50PlxuIiwgJG9wdGlvbnMpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCIgIGNvbW1hbmQgW29wdGlvbnNdIFthcmd1bWVudHNdXG5cbiIsICRvcHRpb25zKTsKCiAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0RGVmaW5pdGlvbihuZXcgSW5wdXREZWZpbml0aW9uKCRhcHBsaWNhdGlvbi0+Z2V0RGVmaW5pdGlvbigpLT5nZXRPcHRpb25zKCkpLCAkb3B0aW9ucyk7CgogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwoKICAgICAgICAgICAgJGNvbW1hbmRzID0gJGRlc2NyaXB0aW9uLT5nZXRDb21tYW5kcygpOwogICAgICAgICAgICAkbmFtZXNwYWNlcyA9ICRkZXNjcmlwdGlvbi0+Z2V0TmFtZXNwYWNlcygpOwogICAgICAgICAgICBpZiAoJGRlc2NyaWJlZE5hbWVzcGFjZSAmJiAkbmFtZXNwYWNlcykgewogICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGFsbCBhbGlhcyBjb21tYW5kcyBhcmUgaW5jbHVkZWQgd2hlbiBkZXNjcmliaW5nIGEgc3BlY2lmaWMgbmFtZXNwYWNlCiAgICAgICAgICAgICAgICAkZGVzY3JpYmVkTmFtZXNwYWNlSW5mbyA9IHJlc2V0KCRuYW1lc3BhY2VzKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRkZXNjcmliZWROYW1lc3BhY2VJbmZvWydjb21tYW5kcyddIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmRzWyRuYW1lXSA9ICRkZXNjcmlwdGlvbi0+Z2V0Q29tbWFuZCgkbmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBtYXguIHdpZHRoIGJhc2VkIG9uIGF2YWlsYWJsZSBjb21tYW5kcyBwZXIgbmFtZXNwYWNlCiAgICAgICAgICAgICR3aWR0aCA9ICR0aGlzLT5nZXRDb2x1bW5XaWR0aChcY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgYXJyYXlfbWFwKGZ1bmN0aW9uICgkbmFtZXNwYWNlKSB1c2UgKCRjb21tYW5kcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X2ludGVyc2VjdCgkbmFtZXNwYWNlWydjb21tYW5kcyddLCBhcnJheV9rZXlzKCRjb21tYW5kcykpOwogICAgICAgICAgICB9LCBhcnJheV92YWx1ZXMoJG5hbWVzcGFjZXMpKSkpOwoKICAgICAgICAgICAgaWYgKCRkZXNjcmliZWROYW1lc3BhY2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoc3ByaW50ZignPGNvbW1lbnQ+QXZhaWxhYmxlIGNvbW1hbmRzIGZvciB0aGUgIiVzIiBuYW1lc3BhY2U6PC9jb21tZW50PicsICRkZXNjcmliZWROYW1lc3BhY2UpLCAkb3B0aW9ucyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCc8Y29tbWVudD5BdmFpbGFibGUgY29tbWFuZHM6PC9jb21tZW50PicsICRvcHRpb25zKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJG5hbWVzcGFjZXMgYXMgJG5hbWVzcGFjZSkgewogICAgICAgICAgICAgICAgJG5hbWVzcGFjZVsnY29tbWFuZHMnXSA9IGFycmF5X2ZpbHRlcigkbmFtZXNwYWNlWydjb21tYW5kcyddLCBmdW5jdGlvbiAoJG5hbWUpIHVzZSAoJGNvbW1hbmRzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzc2V0KCRjb21tYW5kc1skbmFtZV0pOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgaWYgKCEkbmFtZXNwYWNlWydjb21tYW5kcyddKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEkZGVzY3JpYmVkTmFtZXNwYWNlICYmIEFwcGxpY2F0aW9uRGVzY3JpcHRpb246OkdMT0JBTF9OQU1FU1BBQ0UgIT09ICRuYW1lc3BhY2VbJ2lkJ10pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoJyA8Y29tbWVudD4nLiRuYW1lc3BhY2VbJ2lkJ10uJzwvY29tbWVudD4nLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG5hbWVzcGFjZVsnY29tbWFuZHMnXSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgJHNwYWNpbmdXaWR0aCA9ICR3aWR0aCAtIEhlbHBlcjo6c3RybGVuKCRuYW1lKTsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZCA9ICRjb21tYW5kc1skbmFtZV07CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmRBbGlhc2VzID0gJG5hbWUgPT09ICRjb21tYW5kLT5nZXROYW1lKCkgPyAkdGhpcy0+Z2V0Q29tbWFuZEFsaWFzZXNUZXh0KCRjb21tYW5kKSA6ICcnOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoc3ByaW50ZignICA8aW5mbz4lczwvaW5mbz4lcyVzJywgJG5hbWUsIHN0cl9yZXBlYXQoJyAnLCAkc3BhY2luZ1dpZHRoKSwgJGNvbW1hbmRBbGlhc2VzLiRjb21tYW5kLT5nZXREZXNjcmlwdGlvbigpKSwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZVRleHQoJGNvbnRlbnQsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlKAogICAgICAgICAgICBpc3NldCgkb3B0aW9uc1sncmF3X3RleHQnXSkgJiYgJG9wdGlvbnNbJ3Jhd190ZXh0J10gPyBzdHJpcF90YWdzKCRjb250ZW50KSA6ICRjb250ZW50LAogICAgICAgICAgICBpc3NldCgkb3B0aW9uc1sncmF3X291dHB1dCddKSA/ICEkb3B0aW9uc1sncmF3X291dHB1dCddIDogdHJ1ZQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGNvbW1hbmQgYWxpYXNlcyB0byBzaG93IHRoZW0gaW4gdGhlIGNvbW1hbmQgZGVzY3JpcHRpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb21tYW5kQWxpYXNlc1RleHQoQ29tbWFuZCAkY29tbWFuZCkKICAgIHsKICAgICAgICAkdGV4dCA9ICcnOwogICAgICAgICRhbGlhc2VzID0gJGNvbW1hbmQtPmdldEFsaWFzZXMoKTsKCiAgICAgICAgaWYgKCRhbGlhc2VzKSB7CiAgICAgICAgICAgICR0ZXh0ID0gJ1snLmltcGxvZGUoJ3wnLCAkYWxpYXNlcykuJ10gJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGV4dDsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgaW5wdXQgb3B0aW9uL2FyZ3VtZW50IGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICRkZWZhdWx0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmb3JtYXREZWZhdWx0VmFsdWUoJGRlZmF1bHQpCiAgICB7CiAgICAgICAgaWYgKFxJTkYgPT09ICRkZWZhdWx0KSB7CiAgICAgICAgICAgIHJldHVybiAnSU5GJzsKICAgICAgICB9CgogICAgICAgIGlmIChcaXNfc3RyaW5nKCRkZWZhdWx0KSkgewogICAgICAgICAgICAkZGVmYXVsdCA9IE91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlKCRkZWZhdWx0KTsKICAgICAgICB9IGVsc2VpZiAoXGlzX2FycmF5KCRkZWZhdWx0KSkgewogICAgICAgICAgICBmb3JlYWNoICgkZGVmYXVsdCBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKFxpc19zdHJpbmcoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICRkZWZhdWx0WyRrZXldID0gT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKCdcXFxcJywgJ1xcJywganNvbl9lbmNvZGUoJGRlZmF1bHQsIFxKU09OX1VORVNDQVBFRF9TTEFTSEVTIHwgXEpTT05fVU5FU0NBUEVEX1VOSUNPREUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAoQ29tbWFuZHxzdHJpbmcpW10gJGNvbW1hbmRzCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb2x1bW5XaWR0aChhcnJheSAkY29tbWFuZHMpCiAgICB7CiAgICAgICAgJHdpZHRocyA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkY29tbWFuZHMgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgaWYgKCRjb21tYW5kIGluc3RhbmNlb2YgQ29tbWFuZCkgewogICAgICAgICAgICAgICAgJHdpZHRoc1tdID0gSGVscGVyOjpzdHJsZW4oJGNvbW1hbmQtPmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkY29tbWFuZC0+Z2V0QWxpYXNlcygpIGFzICRhbGlhcykgewogICAgICAgICAgICAgICAgICAgICR3aWR0aHNbXSA9IEhlbHBlcjo6c3RybGVuKCRhbGlhcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkd2lkdGhzW10gPSBIZWxwZXI6OnN0cmxlbigkY29tbWFuZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkd2lkdGhzID8gbWF4KCR3aWR0aHMpICsgMiA6IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSW5wdXRPcHRpb25bXSAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2FsY3VsYXRlVG90YWxXaWR0aEZvck9wdGlvbnMoYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRvdGFsV2lkdGggPSAwOwogICAgICAgIGZvcmVhY2ggKCRvcHRpb25zIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgLy8gIi0iICsgc2hvcnRjdXQgKyAiLCAtLSIgKyBuYW1lCiAgICAgICAgICAgICRuYW1lTGVuZ3RoID0gMSArIG1heChIZWxwZXI6OnN0cmxlbigkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSwgMSkgKyA0ICsgSGVscGVyOjpzdHJsZW4oJG9wdGlvbi0+Z2V0TmFtZSgpKTsKCiAgICAgICAgICAgIGlmICgkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWVMZW5ndGggPSAxICsgSGVscGVyOjpzdHJsZW4oJG9wdGlvbi0+Z2V0TmFtZSgpKTsgLy8gPSArIHZhbHVlCiAgICAgICAgICAgICAgICAkdmFsdWVMZW5ndGggKz0gJG9wdGlvbi0+aXNWYWx1ZU9wdGlvbmFsKCkgPyAyIDogMDsgLy8gWyArIF0KCiAgICAgICAgICAgICAgICAkbmFtZUxlbmd0aCArPSAkdmFsdWVMZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRvdGFsV2lkdGggPSBtYXgoJHRvdGFsV2lkdGgsICRuYW1lTGVuZ3RoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdG90YWxXaWR0aDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRMaXN0ZW5lcjsKCnVzZSBQc3JcTG9nXExvZ2dlckludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29uc29sZUV2ZW50czsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZUVycm9yRXZlbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50XENvbnNvbGVFdmVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZVRlcm1pbmF0ZUV2ZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcRXZlbnREaXNwYXRjaGVyXEV2ZW50U3Vic2NyaWJlckludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEphbWVzIEhhbHNhbGwgPGphbWVzLnQuaGFsc2FsbEBnb29nbGVtYWlsLmNvbT4KICogQGF1dGhvciBSb2JpbiBDaGFsYXMgPHJvYmluLmNoYWxhc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBFcnJvckxpc3RlbmVyIGltcGxlbWVudHMgRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGxvZ2dlcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5sb2dnZXIgPSAkbG9nZ2VyOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBvbkNvbnNvbGVFcnJvcihDb25zb2xlRXJyb3JFdmVudCAkZXZlbnQpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5sb2dnZXIpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGVycm9yID0gJGV2ZW50LT5nZXRFcnJvcigpOwoKICAgICAgICBpZiAoISRpbnB1dFN0cmluZyA9ICR0aGlzLT5nZXRJbnB1dFN0cmluZygkZXZlbnQpKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2dnZXItPmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB1c2luZyB0aGUgY29uc29sZS4gTWVzc2FnZTogInttZXNzYWdlfSInLCBbJ2V4Y2VwdGlvbicgPT4gJGVycm9yLCAnbWVzc2FnZScgPT4gJGVycm9yLT5nZXRNZXNzYWdlKCldKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2dnZXItPmVycm9yKCdFcnJvciB0aHJvd24gd2hpbGUgcnVubmluZyBjb21tYW5kICJ7Y29tbWFuZH0iLiBNZXNzYWdlOiAie21lc3NhZ2V9IicsIFsnZXhjZXB0aW9uJyA9PiAkZXJyb3IsICdjb21tYW5kJyA9PiAkaW5wdXRTdHJpbmcsICdtZXNzYWdlJyA9PiAkZXJyb3ItPmdldE1lc3NhZ2UoKV0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBvbkNvbnNvbGVUZXJtaW5hdGUoQ29uc29sZVRlcm1pbmF0ZUV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmxvZ2dlcikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkZXhpdENvZGUgPSAkZXZlbnQtPmdldEV4aXRDb2RlKCk7CgogICAgICAgIGlmICgwID09PSAkZXhpdENvZGUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaW5wdXRTdHJpbmcgPSAkdGhpcy0+Z2V0SW5wdXRTdHJpbmcoJGV2ZW50KSkgewogICAgICAgICAgICAkdGhpcy0+bG9nZ2VyLT5kZWJ1ZygnVGhlIGNvbnNvbGUgZXhpdGVkIHdpdGggY29kZSAie2NvZGV9IicsIFsnY29kZScgPT4gJGV4aXRDb2RlXSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9nZ2VyLT5kZWJ1ZygnQ29tbWFuZCAie2NvbW1hbmR9IiBleGl0ZWQgd2l0aCBjb2RlICJ7Y29kZX0iJywgWydjb21tYW5kJyA9PiAkaW5wdXRTdHJpbmcsICdjb2RlJyA9PiAkZXhpdENvZGVdKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFN1YnNjcmliZWRFdmVudHMoKQogICAgewogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgIENvbnNvbGVFdmVudHM6OkVSUk9SID0+IFsnb25Db25zb2xlRXJyb3InLCAtMTI4XSwKICAgICAgICAgICAgQ29uc29sZUV2ZW50czo6VEVSTUlOQVRFID0+IFsnb25Db25zb2xlVGVybWluYXRlJywgLTEyOF0sCiAgICAgICAgXTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRJbnB1dFN0cmluZyhDb25zb2xlRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgICRjb21tYW5kTmFtZSA9ICRldmVudC0+Z2V0Q29tbWFuZCgpID8gJGV2ZW50LT5nZXRDb21tYW5kKCktPmdldE5hbWUoKSA6IG51bGw7CiAgICAgICAgJGlucHV0ID0gJGV2ZW50LT5nZXRJbnB1dCgpOwoKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkaW5wdXQsICdfX3RvU3RyaW5nJykpIHsKICAgICAgICAgICAgaWYgKCRjb21tYW5kTmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKFsiJyRjb21tYW5kTmFtZSciLCAiXCIkY29tbWFuZE5hbWVcIiJdLCAkY29tbWFuZE5hbWUsIChzdHJpbmcpICRpbnB1dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSAkaW5wdXQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbW1hbmROYW1lOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7CgovKioKICogSGVscHMgb3V0cHV0dGluZyBkZWJ1ZyBpbmZvcm1hdGlvbiB3aGVuIHJ1bm5pbmcgYW4gZXh0ZXJuYWwgcHJvZ3JhbSBmcm9tIGEgY29tbWFuZC4KICoKICogQW4gZXh0ZXJuYWwgcHJvZ3JhbSBjYW4gYmUgYSBQcm9jZXNzLCBhbiBIVFRQIHJlcXVlc3QsIG9yIGFueXRoaW5nIGVsc2UuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRGVidWdGb3JtYXR0ZXJIZWxwZXIgZXh0ZW5kcyBIZWxwZXIKewogICAgcHJpdmF0ZSAkY29sb3JzID0gWydibGFjaycsICdyZWQnLCAnZ3JlZW4nLCAneWVsbG93JywgJ2JsdWUnLCAnbWFnZW50YScsICdjeWFuJywgJ3doaXRlJywgJ2RlZmF1bHQnXTsKICAgIHByaXZhdGUgJHN0YXJ0ZWQgPSBbXTsKICAgIHByaXZhdGUgJGNvdW50ID0gLTE7CgogICAgLyoqCiAgICAgKiBTdGFydHMgYSBkZWJ1ZyBmb3JtYXR0aW5nIHNlc3Npb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgICAgICBUaGUgaWQgb2YgdGhlIGZvcm1hdHRpbmcgc2Vzc2lvbgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBkaXNwbGF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcmVmaXggIFRoZSBwcmVmaXggdG8gdXNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0YXJ0KCRpZCwgJG1lc3NhZ2UsICRwcmVmaXggPSAnUlVOJykKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnRlZFskaWRdID0gWydib3JkZXInID0+ICsrJHRoaXMtPmNvdW50ICUgXGNvdW50KCR0aGlzLT5jb2xvcnMpXTsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoIiVzPGJnPWJsdWU7Zmc9d2hpdGU+ICVzIDwvPiA8Zmc9Ymx1ZT4lczwvPlxuIiwgJHRoaXMtPmdldEJvcmRlcigkaWQpLCAkcHJlZml4LCAkbWVzc2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHByb2dyZXNzIHRvIGEgZm9ybWF0dGluZyBzZXNzaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgICAgICAgIFRoZSBpZCBvZiB0aGUgZm9ybWF0dGluZyBzZXNzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRidWZmZXIgICAgICBUaGUgbWVzc2FnZSB0byBkaXNwbGF5CiAgICAgKiBAcGFyYW0gYm9vbCAgICRlcnJvciAgICAgICBXaGV0aGVyIHRvIGNvbnNpZGVyIHRoZSBidWZmZXIgYXMgZXJyb3IKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZWZpeCAgICAgIFRoZSBwcmVmaXggZm9yIG91dHB1dAogICAgICogQHBhcmFtIHN0cmluZyAkZXJyb3JQcmVmaXggVGhlIHByZWZpeCBmb3IgZXJyb3Igb3V0cHV0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzKCRpZCwgJGJ1ZmZlciwgJGVycm9yID0gZmFsc2UsICRwcmVmaXggPSAnT1VUJywgJGVycm9yUHJlZml4ID0gJ0VSUicpCiAgICB7CiAgICAgICAgJG1lc3NhZ2UgPSAnJzsKCiAgICAgICAgaWYgKCRlcnJvcikgewogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnb3V0J10pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiXG4iOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnb3V0J10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnZXJyJ10pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSBzcHJpbnRmKCclczxiZz1yZWQ7Zmc9d2hpdGU+ICVzIDwvPiAnLCAkdGhpcy0+Z2V0Qm9yZGVyKCRpZCksICRlcnJvclByZWZpeCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3RhcnRlZFskaWRdWydlcnInXSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlIC49IHN0cl9yZXBsYWNlKCJcbiIsIHNwcmludGYoIlxuJXM8Ymc9cmVkO2ZnPXdoaXRlPiAlcyA8Lz4gIiwgJHRoaXMtPmdldEJvcmRlcigkaWQpLCAkZXJyb3JQcmVmaXgpLCAkYnVmZmVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnZXJyJ10pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiXG4iOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnZXJyJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnb3V0J10pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSBzcHJpbnRmKCclczxiZz1ncmVlbjtmZz13aGl0ZT4gJXMgPC8+ICcsICR0aGlzLT5nZXRCb3JkZXIoJGlkKSwgJHByZWZpeCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3RhcnRlZFskaWRdWydvdXQnXSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlIC49IHN0cl9yZXBsYWNlKCJcbiIsIHNwcmludGYoIlxuJXM8Ymc9Z3JlZW47Zmc9d2hpdGU+ICVzIDwvPiAiLCAkdGhpcy0+Z2V0Qm9yZGVyKCRpZCksICRwcmVmaXgpLCAkYnVmZmVyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWVzc2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIFN0b3BzIGEgZm9ybWF0dGluZyBzZXNzaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgICAgICAgVGhlIGlkIG9mIHRoZSBmb3JtYXR0aW5nIHNlc3Npb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgICAgVGhlIG1lc3NhZ2UgdG8gZGlzcGxheQogICAgICogQHBhcmFtIGJvb2wgICAkc3VjY2Vzc2Z1bCBXaGV0aGVyIHRvIGNvbnNpZGVyIHRoZSByZXN1bHQgYXMgc3VjY2VzcwogICAgICogQHBhcmFtIHN0cmluZyAkcHJlZml4ICAgICBUaGUgcHJlZml4IGZvciB0aGUgZW5kIG91dHB1dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdG9wKCRpZCwgJG1lc3NhZ2UsICRzdWNjZXNzZnVsLCAkcHJlZml4ID0gJ1JFUycpCiAgICB7CiAgICAgICAgJHRyYWlsaW5nRU9MID0gaXNzZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnb3V0J10pIHx8IGlzc2V0KCR0aGlzLT5zdGFydGVkWyRpZF1bJ2VyciddKSA/ICJcbiIgOiAnJzsKCiAgICAgICAgaWYgKCRzdWNjZXNzZnVsKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCIlcyVzPGJnPWdyZWVuO2ZnPXdoaXRlPiAlcyA8Lz4gPGZnPWdyZWVuPiVzPC8+XG4iLCAkdHJhaWxpbmdFT0wsICR0aGlzLT5nZXRCb3JkZXIoJGlkKSwgJHByZWZpeCwgJG1lc3NhZ2UpOwogICAgICAgIH0KCiAgICAgICAgJG1lc3NhZ2UgPSBzcHJpbnRmKCIlcyVzPGJnPXJlZDtmZz13aGl0ZT4gJXMgPC8+IDxmZz1yZWQ+JXM8Lz5cbiIsICR0cmFpbGluZ0VPTCwgJHRoaXMtPmdldEJvcmRlcigkaWQpLCAkcHJlZml4LCAkbWVzc2FnZSk7CgogICAgICAgIHVuc2V0KCR0aGlzLT5zdGFydGVkWyRpZF1bJ291dCddLCAkdGhpcy0+c3RhcnRlZFskaWRdWydlcnInXSk7CgogICAgICAgIHJldHVybiAkbWVzc2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkIFRoZSBpZCBvZiB0aGUgZm9ybWF0dGluZyBzZXNzaW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRCb3JkZXIoJGlkKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKCc8Ymc9JXM+IDwvPicsICR0aGlzLT5jb2xvcnNbJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnYm9yZGVyJ11dKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAnZGVidWdfZm9ybWF0dGVyJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlckludGVyZmFjZTsKCi8qKgogKiBIZWxwZXIgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBoZWxwZXIgY2xhc3Nlcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBIZWxwZXIgaW1wbGVtZW50cyBIZWxwZXJJbnRlcmZhY2UKewogICAgcHJvdGVjdGVkICRoZWxwZXJTZXQgPSBudWxsOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVscGVyU2V0KEhlbHBlclNldCAkaGVscGVyU2V0ID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVscGVyU2V0ID0gJGhlbHBlclNldDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlbHBlclNldCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oZWxwZXJTZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgYSBzdHJpbmcsIHVzaW5nIG1iX3N0cndpZHRoIGlmIGl0IGlzIGF2YWlsYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgVGhlIHN0cmluZyB0byBjaGVjayBpdHMgbGVuZ3RoCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3RybGVuKCRzdHJpbmcpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSAkZW5jb2RpbmcgPSBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0cmluZywgbnVsbCwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIFxzdHJsZW4oJHN0cmluZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbWJfc3Ryd2lkdGgoJHN0cmluZywgJGVuY29kaW5nKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN1YnNldCBvZiBhIHN0cmluZywgdXNpbmcgbWJfc3Vic3RyIGlmIGl0IGlzIGF2YWlsYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHN0cmluZyBTdHJpbmcgdG8gc3Vic2V0CiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGZyb20gICBTdGFydCBvZmZzZXQKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAkbGVuZ3RoIExlbmd0aCB0byByZWFkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHN0cmluZyBzdWJzZXQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdWJzdHIoJHN0cmluZywgJGZyb20sICRsZW5ndGggPSBudWxsKQogICAgewogICAgICAgIGlmIChmYWxzZSA9PT0gJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCRzdHJpbmcsIG51bGwsIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHN0cmluZywgJGZyb20sICRsZW5ndGgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG1iX3N1YnN0cigkc3RyaW5nLCAkZnJvbSwgJGxlbmd0aCwgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdFRpbWUoJHNlY3MpCiAgICB7CiAgICAgICAgc3RhdGljICR0aW1lRm9ybWF0cyA9IFsKICAgICAgICAgICAgWzAsICc8IDEgc2VjJ10sCiAgICAgICAgICAgIFsxLCAnMSBzZWMnXSwKICAgICAgICAgICAgWzIsICdzZWNzJywgMV0sCiAgICAgICAgICAgIFs2MCwgJzEgbWluJ10sCiAgICAgICAgICAgIFsxMjAsICdtaW5zJywgNjBdLAogICAgICAgICAgICBbMzYwMCwgJzEgaHInXSwKICAgICAgICAgICAgWzcyMDAsICdocnMnLCAzNjAwXSwKICAgICAgICAgICAgWzg2NDAwLCAnMSBkYXknXSwKICAgICAgICAgICAgWzE3MjgwMCwgJ2RheXMnLCA4NjQwMF0sCiAgICAgICAgXTsKCiAgICAgICAgZm9yZWFjaCAoJHRpbWVGb3JtYXRzIGFzICRpbmRleCA9PiAkZm9ybWF0KSB7CiAgICAgICAgICAgIGlmICgkc2VjcyA+PSAkZm9ybWF0WzBdKSB7CiAgICAgICAgICAgICAgICBpZiAoKGlzc2V0KCR0aW1lRm9ybWF0c1skaW5kZXggKyAxXSkgJiYgJHNlY3MgPCAkdGltZUZvcm1hdHNbJGluZGV4ICsgMV1bMF0pCiAgICAgICAgICAgICAgICAgICAgfHwgJGluZGV4ID09IFxjb3VudCgkdGltZUZvcm1hdHMpIC0gMQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKDIgPT0gXGNvdW50KCRmb3JtYXQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZm9ybWF0WzFdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZsb29yKCRzZWNzIC8gJGZvcm1hdFsyXSkuJyAnLiRmb3JtYXRbMV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXRNZW1vcnkoJG1lbW9yeSkKICAgIHsKICAgICAgICBpZiAoJG1lbW9yeSA+PSAxMDI0ICogMTAyNCAqIDEwMjQpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyUuMWYgR2lCJywgJG1lbW9yeSAvIDEwMjQgLyAxMDI0IC8gMTAyNCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1lbW9yeSA+PSAxMDI0ICogMTAyNCkgewogICAgICAgICAgICByZXR1cm4gc3ByaW50ZignJS4xZiBNaUInLCAkbWVtb3J5IC8gMTAyNCAvIDEwMjQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRtZW1vcnkgPj0gMTAyNCkgewogICAgICAgICAgICByZXR1cm4gc3ByaW50ZignJWQgS2lCJywgJG1lbW9yeSAvIDEwMjQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNwcmludGYoJyVkIEInLCAkbWVtb3J5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN0cmxlbldpdGhvdXREZWNvcmF0aW9uKE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyLCAkc3RyaW5nKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpzdHJsZW4oc2VsZjo6cmVtb3ZlRGVjb3JhdGlvbigkZm9ybWF0dGVyLCAkc3RyaW5nKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZW1vdmVEZWNvcmF0aW9uKE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyLCAkc3RyaW5nKQogICAgewogICAgICAgICRpc0RlY29yYXRlZCA9ICRmb3JtYXR0ZXItPmlzRGVjb3JhdGVkKCk7CiAgICAgICAgJGZvcm1hdHRlci0+c2V0RGVjb3JhdGVkKGZhbHNlKTsKICAgICAgICAvLyByZW1vdmUgPC4uLj4gZm9ybWF0dGluZwogICAgICAgICRzdHJpbmcgPSAkZm9ybWF0dGVyLT5mb3JtYXQoJHN0cmluZyk7CiAgICAgICAgLy8gcmVtb3ZlIGFscmVhZHkgZm9ybWF0dGVkIGNoYXJhY3RlcnMKICAgICAgICAkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCIvXDAzM1xbW15tXSptLyIsICcnLCAkc3RyaW5nKTsKICAgICAgICAkZm9ybWF0dGVyLT5zZXREZWNvcmF0ZWQoJGlzRGVjb3JhdGVkKTsKCiAgICAgICAgcmV0dXJuICRzdHJpbmc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlcm1pbmFsOwoKLyoqCiAqIFRoZSBQcm9ncmVzc0JhciBwcm92aWRlcyBoZWxwZXJzIHRvIGRpc3BsYXkgcHJvZ3Jlc3Mgb3V0cHV0LgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBDaHJpcyBKb25lcyA8bGVla2VkQGdtYWlsLmNvbT4KICovCmZpbmFsIGNsYXNzIFByb2dyZXNzQmFyCnsKICAgIHByaXZhdGUgJGJhcldpZHRoID0gMjg7CiAgICBwcml2YXRlICRiYXJDaGFyOwogICAgcHJpdmF0ZSAkZW1wdHlCYXJDaGFyID0gJy0nOwogICAgcHJpdmF0ZSAkcHJvZ3Jlc3NDaGFyID0gJz4nOwogICAgcHJpdmF0ZSAkZm9ybWF0OwogICAgcHJpdmF0ZSAkaW50ZXJuYWxGb3JtYXQ7CiAgICBwcml2YXRlICRyZWRyYXdGcmVxID0gMTsKICAgIHByaXZhdGUgJG91dHB1dDsKICAgIHByaXZhdGUgJHN0ZXAgPSAwOwogICAgcHJpdmF0ZSAkbWF4OwogICAgcHJpdmF0ZSAkc3RhcnRUaW1lOwogICAgcHJpdmF0ZSAkc3RlcFdpZHRoOwogICAgcHJpdmF0ZSAkcGVyY2VudCA9IDAuMDsKICAgIHByaXZhdGUgJGZvcm1hdExpbmVDb3VudDsKICAgIHByaXZhdGUgJG1lc3NhZ2VzID0gW107CiAgICBwcml2YXRlICRvdmVyd3JpdGUgPSB0cnVlOwogICAgcHJpdmF0ZSAkdGVybWluYWw7CiAgICBwcml2YXRlICRmaXJzdFJ1biA9IHRydWU7CgogICAgcHJpdmF0ZSBzdGF0aWMgJGZvcm1hdHRlcnM7CiAgICBwcml2YXRlIHN0YXRpYyAkZm9ybWF0czsKCiAgICAvKioKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCBBbiBPdXRwdXRJbnRlcmZhY2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgJG1heCAgICBNYXhpbXVtIHN0ZXBzICgwIGlmIHVua25vd24pCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJG1heCA9IDApCiAgICB7CiAgICAgICAgaWYgKCRvdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRvdXRwdXQgPSAkb3V0cHV0LT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm91dHB1dCA9ICRvdXRwdXQ7CiAgICAgICAgJHRoaXMtPnNldE1heFN0ZXBzKCRtYXgpOwogICAgICAgICR0aGlzLT50ZXJtaW5hbCA9IG5ldyBUZXJtaW5hbCgpOwoKICAgICAgICBpZiAoISR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgLy8gZGlzYWJsZSBvdmVyd3JpdGUgd2hlbiBvdXRwdXQgZG9lcyBub3Qgc3VwcG9ydCBBTlNJIGNvZGVzLgogICAgICAgICAgICAkdGhpcy0+b3ZlcndyaXRlID0gZmFsc2U7CgogICAgICAgICAgICAvLyBzZXQgYSByZWFzb25hYmxlIHJlZHJhdyBmcmVxdWVuY3kgc28gb3V0cHV0IGlzbid0IGZsb29kZWQKICAgICAgICAgICAgJHRoaXMtPnNldFJlZHJhd0ZyZXF1ZW5jeSgkbWF4IC8gMTApOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0YXJ0VGltZSA9IHRpbWUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBwbGFjZWhvbGRlciBmb3JtYXR0ZXIgZm9yIGEgZ2l2ZW4gbmFtZS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBhbHNvIGFsbG93IHlvdSB0byBvdmVycmlkZSBhbiBleGlzdGluZyBwbGFjZWhvbGRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJG5hbWUgICAgIFRoZSBwbGFjZWhvbGRlciBuYW1lIChpbmNsdWRpbmcgdGhlIGRlbGltaXRlciBjaGFyIGxpa2UgJSkKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkY2FsbGFibGUgQSBQSFAgY2FsbGFibGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRQbGFjZWhvbGRlckZvcm1hdHRlckRlZmluaXRpb24oJG5hbWUsIGNhbGxhYmxlICRjYWxsYWJsZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRmb3JtYXR0ZXJzKSB7CiAgICAgICAgICAgIHNlbGY6OiRmb3JtYXR0ZXJzID0gc2VsZjo6aW5pdFBsYWNlaG9sZGVyRm9ybWF0dGVycygpOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JGZvcm1hdHRlcnNbJG5hbWVdID0gJGNhbGxhYmxlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcGxhY2Vob2xkZXIgZm9ybWF0dGVyIGZvciBhIGdpdmVuIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgcGxhY2Vob2xkZXIgbmFtZSAoaW5jbHVkaW5nIHRoZSBkZWxpbWl0ZXIgY2hhciBsaWtlICUpCiAgICAgKgogICAgICogQHJldHVybiBjYWxsYWJsZXxudWxsIEEgUEhQIGNhbGxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UGxhY2Vob2xkZXJGb3JtYXR0ZXJEZWZpbml0aW9uKCRuYW1lKQogICAgewogICAgICAgIGlmICghc2VsZjo6JGZvcm1hdHRlcnMpIHsKICAgICAgICAgICAgc2VsZjo6JGZvcm1hdHRlcnMgPSBzZWxmOjppbml0UGxhY2Vob2xkZXJGb3JtYXR0ZXJzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoc2VsZjo6JGZvcm1hdHRlcnNbJG5hbWVdKSA/IHNlbGY6OiRmb3JtYXR0ZXJzWyRuYW1lXSA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGEgZm9ybWF0IGZvciBhIGdpdmVuIG5hbWUuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgYWxzbyBhbGxvdyB5b3UgdG8gb3ZlcnJpZGUgYW4gZXhpc3RpbmcgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgICBUaGUgZm9ybWF0IG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm1hdCBBIGZvcm1hdCBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRGb3JtYXREZWZpbml0aW9uKCRuYW1lLCAkZm9ybWF0KQogICAgewogICAgICAgIGlmICghc2VsZjo6JGZvcm1hdHMpIHsKICAgICAgICAgICAgc2VsZjo6JGZvcm1hdHMgPSBzZWxmOjppbml0Rm9ybWF0cygpOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JGZvcm1hdHNbJG5hbWVdID0gJGZvcm1hdDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGZvcm1hdCBmb3IgYSBnaXZlbiBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGZvcm1hdCBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBBIGZvcm1hdCBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRGb3JtYXREZWZpbml0aW9uKCRuYW1lKQogICAgewogICAgICAgIGlmICghc2VsZjo6JGZvcm1hdHMpIHsKICAgICAgICAgICAgc2VsZjo6JGZvcm1hdHMgPSBzZWxmOjppbml0Rm9ybWF0cygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzc2V0KHNlbGY6OiRmb3JtYXRzWyRuYW1lXSkgPyBzZWxmOjokZm9ybWF0c1skbmFtZV0gOiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQXNzb2NpYXRlcyBhIHRleHQgd2l0aCBhIG5hbWVkIHBsYWNlaG9sZGVyLgogICAgICoKICAgICAqIFRoZSB0ZXh0IGlzIGRpc3BsYXllZCB3aGVuIHRoZSBwcm9ncmVzcyBiYXIgaXMgcmVuZGVyZWQgYnV0IG9ubHkKICAgICAqIHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgcGxhY2Vob2xkZXIgaXMgcGFydCBvZiB0aGUgY3VzdG9tIGZvcm1hdCBsaW5lCiAgICAgKiAoYnkgd3JhcHBpbmcgdGhlIG5hbWUgd2l0aCAlKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSB0ZXh0IHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBwbGFjZWhvbGRlcgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSAgICBUaGUgbmFtZSBvZiB0aGUgcGxhY2Vob2xkZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1lc3NhZ2UoJG1lc3NhZ2UsICRuYW1lID0gJ21lc3NhZ2UnKQogICAgewogICAgICAgICR0aGlzLT5tZXNzYWdlc1skbmFtZV0gPSAkbWVzc2FnZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TWVzc2FnZSgkbmFtZSA9ICdtZXNzYWdlJykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm1lc3NhZ2VzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByb2dyZXNzIGJhciBzdGFydCB0aW1lLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBwcm9ncmVzcyBiYXIgc3RhcnQgdGltZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhcnRUaW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXJ0VGltZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByb2dyZXNzIGJhciBtYXhpbWFsIHN0ZXBzLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBwcm9ncmVzcyBiYXIgbWF4IHN0ZXBzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNYXhTdGVwcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXg7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHN0ZXAgcG9zaXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIHByb2dyZXNzIGJhciBzdGVwCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9ncmVzcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGVwOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcHJvZ3Jlc3MgYmFyIHN0ZXAgd2lkdGguCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIHByb2dyZXNzIGJhciBzdGVwIHdpZHRoCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0U3RlcFdpZHRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0ZXBXaWR0aDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGN1cnJlbnQgcHJvZ3Jlc3MgYmFyIHBlcmNlbnQuCiAgICAgKgogICAgICogQHJldHVybiBmbG9hdCBUaGUgY3VycmVudCBwcm9ncmVzcyBiYXIgcGVyY2VudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvZ3Jlc3NQZXJjZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBlcmNlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9ncmVzcyBiYXIgd2lkdGguCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc2l6ZSBUaGUgcHJvZ3Jlc3MgYmFyIHNpemUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJhcldpZHRoKCRzaXplKQogICAgewogICAgICAgICR0aGlzLT5iYXJXaWR0aCA9IG1heCgxLCAoaW50KSAkc2l6ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9ncmVzcyBiYXIgd2lkdGguCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIHByb2dyZXNzIGJhciBzaXplCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCYXJXaWR0aCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5iYXJXaWR0aDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGJhciBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2hhciBBIGNoYXJhY3RlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QmFyQ2hhcmFjdGVyKCRjaGFyKQogICAgewogICAgICAgICR0aGlzLT5iYXJDaGFyID0gJGNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBiYXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEEgY2hhcmFjdGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCYXJDaGFyYWN0ZXIoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+YmFyQ2hhcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPm1heCA/ICc9JyA6ICR0aGlzLT5lbXB0eUJhckNoYXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmJhckNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBlbXB0eSBiYXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNoYXIgQSBjaGFyYWN0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVtcHR5QmFyQ2hhcmFjdGVyKCRjaGFyKQogICAgewogICAgICAgICR0aGlzLT5lbXB0eUJhckNoYXIgPSAkY2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGVtcHR5IGJhciBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgQSBjaGFyYWN0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVtcHR5QmFyQ2hhcmFjdGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVtcHR5QmFyQ2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2dyZXNzIGJhciBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2hhciBBIGNoYXJhY3RlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvZ3Jlc3NDaGFyYWN0ZXIoJGNoYXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb2dyZXNzQ2hhciA9ICRjaGFyOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcHJvZ3Jlc3MgYmFyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIGNoYXJhY3RlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvZ3Jlc3NDaGFyYWN0ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvZ3Jlc3NDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvZ3Jlc3MgYmFyIGZvcm1hdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtYXQgVGhlIGZvcm1hdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0KCRmb3JtYXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdCA9IG51bGw7CiAgICAgICAgJHRoaXMtPmludGVybmFsRm9ybWF0ID0gJGZvcm1hdDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHJlZHJhdyBmcmVxdWVuY3kuCiAgICAgKgogICAgICogQHBhcmFtIGludHxmbG9hdCAkZnJlcSBUaGUgZnJlcXVlbmN5IGluIHN0ZXBzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZWRyYXdGcmVxdWVuY3koJGZyZXEpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlZHJhd0ZyZXEgPSBtYXgoKGludCkgJGZyZXEsIDEpOwogICAgfQoKICAgIC8qKgogICAgICogU3RhcnRzIHRoZSBwcm9ncmVzcyBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIGludHxudWxsICRtYXggTnVtYmVyIG9mIHN0ZXBzIHRvIGNvbXBsZXRlIHRoZSBiYXIgKDAgaWYgaW5kZXRlcm1pbmF0ZSksIG51bGwgdG8gbGVhdmUgdW5jaGFuZ2VkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdGFydCgkbWF4ID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnRUaW1lID0gdGltZSgpOwogICAgICAgICR0aGlzLT5zdGVwID0gMDsKICAgICAgICAkdGhpcy0+cGVyY2VudCA9IDAuMDsKCiAgICAgICAgaWYgKG51bGwgIT09ICRtYXgpIHsKICAgICAgICAgICAgJHRoaXMtPnNldE1heFN0ZXBzKCRtYXgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmRpc3BsYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkdmFuY2VzIHRoZSBwcm9ncmVzcyBvdXRwdXQgWCBzdGVwcy4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRzdGVwIE51bWJlciBvZiBzdGVwcyB0byBhZHZhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZHZhbmNlKCRzdGVwID0gMSkKICAgIHsKICAgICAgICAkdGhpcy0+c2V0UHJvZ3Jlc3MoJHRoaXMtPnN0ZXAgKyAkc3RlcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgdG8gb3ZlcndyaXRlIHRoZSBwcm9ncmVzc2JhciwgZmFsc2UgZm9yIG5ldyBsaW5lLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRvdmVyd3JpdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE92ZXJ3cml0ZSgkb3ZlcndyaXRlKQogICAgewogICAgICAgICR0aGlzLT5vdmVyd3JpdGUgPSAoYm9vbCkgJG92ZXJ3cml0ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGN1cnJlbnQgcHJvZ3Jlc3MuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc3RlcCBUaGUgY3VycmVudCBwcm9ncmVzcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvZ3Jlc3MoJHN0ZXApCiAgICB7CiAgICAgICAgJHN0ZXAgPSAoaW50KSAkc3RlcDsKCiAgICAgICAgaWYgKCR0aGlzLT5tYXggJiYgJHN0ZXAgPiAkdGhpcy0+bWF4KSB7CiAgICAgICAgICAgICR0aGlzLT5tYXggPSAkc3RlcDsKICAgICAgICB9IGVsc2VpZiAoJHN0ZXAgPCAwKSB7CiAgICAgICAgICAgICRzdGVwID0gMDsKICAgICAgICB9CgogICAgICAgICRwcmV2UGVyaW9kID0gKGludCkgKCR0aGlzLT5zdGVwIC8gJHRoaXMtPnJlZHJhd0ZyZXEpOwogICAgICAgICRjdXJyUGVyaW9kID0gKGludCkgKCRzdGVwIC8gJHRoaXMtPnJlZHJhd0ZyZXEpOwogICAgICAgICR0aGlzLT5zdGVwID0gJHN0ZXA7CiAgICAgICAgJHRoaXMtPnBlcmNlbnQgPSAkdGhpcy0+bWF4ID8gKGZsb2F0KSAkdGhpcy0+c3RlcCAvICR0aGlzLT5tYXggOiAwOwogICAgICAgIGlmICgkcHJldlBlcmlvZCAhPT0gJGN1cnJQZXJpb2QgfHwgJHRoaXMtPm1heCA9PT0gJHN0ZXApIHsKICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXkoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5pc2hlcyB0aGUgcHJvZ3Jlc3Mgb3V0cHV0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluaXNoKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5tYXgpIHsKICAgICAgICAgICAgJHRoaXMtPm1heCA9ICR0aGlzLT5zdGVwOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5zdGVwID09PSAkdGhpcy0+bWF4ICYmICEkdGhpcy0+b3ZlcndyaXRlKSB7CiAgICAgICAgICAgIC8vIHByZXZlbnQgZG91YmxlIDEwMCUgb3V0cHV0CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXRQcm9ncmVzcygkdGhpcy0+bWF4KTsKICAgIH0KCiAgICAvKioKICAgICAqIE91dHB1dHMgdGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgc3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzcGxheSgpCiAgICB7CiAgICAgICAgaWYgKE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1FVSUVUID09PSAkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmZvcm1hdCkgewogICAgICAgICAgICAkdGhpcy0+c2V0UmVhbEZvcm1hdCgkdGhpcy0+aW50ZXJuYWxGb3JtYXQgPzogJHRoaXMtPmRldGVybWluZUJlc3RGb3JtYXQoKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3ZlcndyaXRlKCR0aGlzLT5idWlsZExpbmUoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHRoZSBwcm9ncmVzcyBiYXIgZnJvbSB0aGUgY3VycmVudCBsaW5lLgogICAgICoKICAgICAqIFRoaXMgaXMgdXNlZnVsIGlmIHlvdSB3aXNoIHRvIHdyaXRlIHNvbWUgb3V0cHV0CiAgICAgKiB3aGlsZSBhIHByb2dyZXNzIGJhciBpcyBydW5uaW5nLgogICAgICogQ2FsbCBkaXNwbGF5KCkgdG8gc2hvdyB0aGUgcHJvZ3Jlc3MgYmFyIGFnYWluLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYXIoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPm92ZXJ3cml0ZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmZvcm1hdCkgewogICAgICAgICAgICAkdGhpcy0+c2V0UmVhbEZvcm1hdCgkdGhpcy0+aW50ZXJuYWxGb3JtYXQgPzogJHRoaXMtPmRldGVybWluZUJlc3RGb3JtYXQoKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3ZlcndyaXRlKCcnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2dyZXNzIGJhciBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybWF0IFRoZSBmb3JtYXQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXRSZWFsRm9ybWF0KCRmb3JtYXQpCiAgICB7CiAgICAgICAgLy8gdHJ5IHRvIHVzZSB0aGUgX25vbWF4IHZhcmlhbnQgaWYgYXZhaWxhYmxlCiAgICAgICAgaWYgKCEkdGhpcy0+bWF4ICYmIG51bGwgIT09IHNlbGY6OmdldEZvcm1hdERlZmluaXRpb24oJGZvcm1hdC4nX25vbWF4JykpIHsKICAgICAgICAgICAgJHRoaXMtPmZvcm1hdCA9IHNlbGY6OmdldEZvcm1hdERlZmluaXRpb24oJGZvcm1hdC4nX25vbWF4Jyk7CiAgICAgICAgfSBlbHNlaWYgKG51bGwgIT09IHNlbGY6OmdldEZvcm1hdERlZmluaXRpb24oJGZvcm1hdCkpIHsKICAgICAgICAgICAgJHRoaXMtPmZvcm1hdCA9IHNlbGY6OmdldEZvcm1hdERlZmluaXRpb24oJGZvcm1hdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmZvcm1hdCA9ICRmb3JtYXQ7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Zm9ybWF0TGluZUNvdW50ID0gc3Vic3RyX2NvdW50KCR0aGlzLT5mb3JtYXQsICJcbiIpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvZ3Jlc3MgYmFyIG1heGltYWwgc3RlcHMuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkbWF4IFRoZSBwcm9ncmVzcyBiYXIgbWF4IHN0ZXBzCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0TWF4U3RlcHMoJG1heCkKICAgIHsKICAgICAgICAkdGhpcy0+bWF4ID0gbWF4KDAsIChpbnQpICRtYXgpOwogICAgICAgICR0aGlzLT5zdGVwV2lkdGggPSAkdGhpcy0+bWF4ID8gSGVscGVyOjpzdHJsZW4oJHRoaXMtPm1heCkgOiA0OwogICAgfQoKICAgIC8qKgogICAgICogT3ZlcndyaXRlcyBhIHByZXZpb3VzIG1lc3NhZ2UgdG8gdGhlIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBtZXNzYWdlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3ZlcndyaXRlKCRtZXNzYWdlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+b3ZlcndyaXRlKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmZpcnN0UnVuKSB7CiAgICAgICAgICAgICAgICAvLyBFcmFzZSBwcmV2aW91cyBsaW5lcwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5mb3JtYXRMaW5lQ291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSBzdHJfcmVwZWF0KCJceDFCWzFBXHgxQlsySyIsICR0aGlzLT5mb3JtYXRMaW5lQ291bnQpLiRtZXNzYWdlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE1vdmUgdGhlIGN1cnNvciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaW5lIGFuZCBlcmFzZSB0aGUgbGluZQogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiXHgwRFx4MUJbMkskbWVzc2FnZSI7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPnN0ZXAgPiAwKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gXFBIUF9FT0wuJG1lc3NhZ2U7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Zmlyc3RSdW4gPSBmYWxzZTsKCiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGUoJG1lc3NhZ2UpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZGV0ZXJtaW5lQmVzdEZvcm1hdCgpCiAgICB7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSkgewogICAgICAgICAgICAvLyBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVDogZGlzcGxheSBpcyBkaXNhYmxlZCBhbnl3YXkKICAgICAgICAgICAgY2FzZSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tYXggPyAndmVyYm9zZScgOiAndmVyYm9zZV9ub21heCc7CiAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSWV9WRVJCT1NFOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tYXggPyAndmVyeV92ZXJib3NlJyA6ICd2ZXJ5X3ZlcmJvc2Vfbm9tYXgnOwogICAgICAgICAgICBjYXNlIE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX0RFQlVHOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tYXggPyAnZGVidWcnIDogJ2RlYnVnX25vbWF4JzsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bWF4ID8gJ25vcm1hbCcgOiAnbm9ybWFsX25vbWF4JzsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5pdFBsYWNlaG9sZGVyRm9ybWF0dGVycygpCiAgICB7CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgJ2JhcicgPT4gZnVuY3Rpb24gKHNlbGYgJGJhciwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICRjb21wbGV0ZUJhcnMgPSBmbG9vcigkYmFyLT5nZXRNYXhTdGVwcygpID4gMCA/ICRiYXItPmdldFByb2dyZXNzUGVyY2VudCgpICogJGJhci0+Z2V0QmFyV2lkdGgoKSA6ICRiYXItPmdldFByb2dyZXNzKCkgJSAkYmFyLT5nZXRCYXJXaWR0aCgpKTsKICAgICAgICAgICAgICAgICRkaXNwbGF5ID0gc3RyX3JlcGVhdCgkYmFyLT5nZXRCYXJDaGFyYWN0ZXIoKSwgJGNvbXBsZXRlQmFycyk7CiAgICAgICAgICAgICAgICBpZiAoJGNvbXBsZXRlQmFycyA8ICRiYXItPmdldEJhcldpZHRoKCkpIHsKICAgICAgICAgICAgICAgICAgICAkZW1wdHlCYXJzID0gJGJhci0+Z2V0QmFyV2lkdGgoKSAtICRjb21wbGV0ZUJhcnMgLSBIZWxwZXI6OnN0cmxlbldpdGhvdXREZWNvcmF0aW9uKCRvdXRwdXQtPmdldEZvcm1hdHRlcigpLCAkYmFyLT5nZXRQcm9ncmVzc0NoYXJhY3RlcigpKTsKICAgICAgICAgICAgICAgICAgICAkZGlzcGxheSAuPSAkYmFyLT5nZXRQcm9ncmVzc0NoYXJhY3RlcigpLnN0cl9yZXBlYXQoJGJhci0+Z2V0RW1wdHlCYXJDaGFyYWN0ZXIoKSwgJGVtcHR5QmFycyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRkaXNwbGF5OwogICAgICAgICAgICB9LAogICAgICAgICAgICAnZWxhcHNlZCcgPT4gZnVuY3Rpb24gKHNlbGYgJGJhcikgewogICAgICAgICAgICAgICAgcmV0dXJuIEhlbHBlcjo6Zm9ybWF0VGltZSh0aW1lKCkgLSAkYmFyLT5nZXRTdGFydFRpbWUoKSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdyZW1haW5pbmcnID0+IGZ1bmN0aW9uIChzZWxmICRiYXIpIHsKICAgICAgICAgICAgICAgIGlmICghJGJhci0+Z2V0TWF4U3RlcHMoKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignVW5hYmxlIHRvIGRpc3BsYXkgdGhlIHJlbWFpbmluZyB0aW1lIGlmIHRoZSBtYXhpbXVtIG51bWJlciBvZiBzdGVwcyBpcyBub3Qgc2V0LicpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghJGJhci0+Z2V0UHJvZ3Jlc3MoKSkgewogICAgICAgICAgICAgICAgICAgICRyZW1haW5pbmcgPSAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcmVtYWluaW5nID0gcm91bmQoKHRpbWUoKSAtICRiYXItPmdldFN0YXJ0VGltZSgpKSAvICRiYXItPmdldFByb2dyZXNzKCkgKiAoJGJhci0+Z2V0TWF4U3RlcHMoKSAtICRiYXItPmdldFByb2dyZXNzKCkpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gSGVscGVyOjpmb3JtYXRUaW1lKCRyZW1haW5pbmcpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAnZXN0aW1hdGVkJyA9PiBmdW5jdGlvbiAoc2VsZiAkYmFyKSB7CiAgICAgICAgICAgICAgICBpZiAoISRiYXItPmdldE1heFN0ZXBzKCkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1VuYWJsZSB0byBkaXNwbGF5IHRoZSBlc3RpbWF0ZWQgdGltZSBpZiB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc3RlcHMgaXMgbm90IHNldC4nKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoISRiYXItPmdldFByb2dyZXNzKCkpIHsKICAgICAgICAgICAgICAgICAgICAkZXN0aW1hdGVkID0gMDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGVzdGltYXRlZCA9IHJvdW5kKCh0aW1lKCkgLSAkYmFyLT5nZXRTdGFydFRpbWUoKSkgLyAkYmFyLT5nZXRQcm9ncmVzcygpICogJGJhci0+Z2V0TWF4U3RlcHMoKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIEhlbHBlcjo6Zm9ybWF0VGltZSgkZXN0aW1hdGVkKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ21lbW9yeScgPT4gZnVuY3Rpb24gKHNlbGYgJGJhcikgewogICAgICAgICAgICAgICAgcmV0dXJuIEhlbHBlcjo6Zm9ybWF0TWVtb3J5KG1lbW9yeV9nZXRfdXNhZ2UodHJ1ZSkpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAnY3VycmVudCcgPT4gZnVuY3Rpb24gKHNlbGYgJGJhcikgewogICAgICAgICAgICAgICAgcmV0dXJuIHN0cl9wYWQoJGJhci0+Z2V0UHJvZ3Jlc3MoKSwgJGJhci0+Z2V0U3RlcFdpZHRoKCksICcgJywgXFNUUl9QQURfTEVGVCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdtYXgnID0+IGZ1bmN0aW9uIChzZWxmICRiYXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYmFyLT5nZXRNYXhTdGVwcygpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAncGVyY2VudCcgPT4gZnVuY3Rpb24gKHNlbGYgJGJhcikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZsb29yKCRiYXItPmdldFByb2dyZXNzUGVyY2VudCgpICogMTAwKTsKICAgICAgICAgICAgfSwKICAgICAgICBdOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluaXRGb3JtYXRzKCkKICAgIHsKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAnbm9ybWFsJyA9PiAnICVjdXJyZW50JS8lbWF4JSBbJWJhciVdICVwZXJjZW50OjNzJSUnLAogICAgICAgICAgICAnbm9ybWFsX25vbWF4JyA9PiAnICVjdXJyZW50JSBbJWJhciVdJywKCiAgICAgICAgICAgICd2ZXJib3NlJyA9PiAnICVjdXJyZW50JS8lbWF4JSBbJWJhciVdICVwZXJjZW50OjNzJSUgJWVsYXBzZWQ6NnMlJywKICAgICAgICAgICAgJ3ZlcmJvc2Vfbm9tYXgnID0+ICcgJWN1cnJlbnQlIFslYmFyJV0gJWVsYXBzZWQ6NnMlJywKCiAgICAgICAgICAgICd2ZXJ5X3ZlcmJvc2UnID0+ICcgJWN1cnJlbnQlLyVtYXglIFslYmFyJV0gJXBlcmNlbnQ6M3MlJSAlZWxhcHNlZDo2cyUvJWVzdGltYXRlZDotNnMlJywKICAgICAgICAgICAgJ3ZlcnlfdmVyYm9zZV9ub21heCcgPT4gJyAlY3VycmVudCUgWyViYXIlXSAlZWxhcHNlZDo2cyUnLAoKICAgICAgICAgICAgJ2RlYnVnJyA9PiAnICVjdXJyZW50JS8lbWF4JSBbJWJhciVdICVwZXJjZW50OjNzJSUgJWVsYXBzZWQ6NnMlLyVlc3RpbWF0ZWQ6LTZzJSAlbWVtb3J5OjZzJScsCiAgICAgICAgICAgICdkZWJ1Z19ub21heCcgPT4gJyAlY3VycmVudCUgWyViYXIlXSAlZWxhcHNlZDo2cyUgJW1lbW9yeTo2cyUnLAogICAgICAgIF07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGJ1aWxkTGluZSgpCiAgICB7CiAgICAgICAgJHJlZ2V4ID0gInslKFthLXpcLV9dKykoPzpcOihbXiVdKykpPyV9aSI7CiAgICAgICAgJGNhbGxiYWNrID0gZnVuY3Rpb24gKCRtYXRjaGVzKSB7CiAgICAgICAgICAgIGlmICgkZm9ybWF0dGVyID0gJHRoaXM6OmdldFBsYWNlaG9sZGVyRm9ybWF0dGVyRGVmaW5pdGlvbigkbWF0Y2hlc1sxXSkpIHsKICAgICAgICAgICAgICAgICR0ZXh0ID0gXGNhbGxfdXNlcl9mdW5jKCRmb3JtYXR0ZXIsICR0aGlzLCAkdGhpcy0+b3V0cHV0KTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCR0aGlzLT5tZXNzYWdlc1skbWF0Y2hlc1sxXV0pKSB7CiAgICAgICAgICAgICAgICAkdGV4dCA9ICR0aGlzLT5tZXNzYWdlc1skbWF0Y2hlc1sxXV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbMF07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc3NldCgkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgICR0ZXh0ID0gc3ByaW50ZignJScuJG1hdGNoZXNbMl0sICR0ZXh0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgICAgIH07CiAgICAgICAgJGxpbmUgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHJlZ2V4LCAkY2FsbGJhY2ssICR0aGlzLT5mb3JtYXQpOwoKICAgICAgICAvLyBnZXRzIHN0cmluZyBsZW5ndGggZm9yIGVhY2ggc3ViIGxpbmUgd2l0aCBtdWx0aWxpbmUgZm9ybWF0CiAgICAgICAgJGxpbmVzTGVuZ3RoID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkc3ViTGluZSkgewogICAgICAgICAgICByZXR1cm4gSGVscGVyOjpzdHJsZW5XaXRob3V0RGVjb3JhdGlvbigkdGhpcy0+b3V0cHV0LT5nZXRGb3JtYXR0ZXIoKSwgcnRyaW0oJHN1YkxpbmUsICJcciIpKTsKICAgICAgICB9LCBleHBsb2RlKCJcbiIsICRsaW5lKSk7CgogICAgICAgICRsaW5lc1dpZHRoID0gbWF4KCRsaW5lc0xlbmd0aCk7CgogICAgICAgICR0ZXJtaW5hbFdpZHRoID0gJHRoaXMtPnRlcm1pbmFsLT5nZXRXaWR0aCgpOwogICAgICAgIGlmICgkbGluZXNXaWR0aCA8PSAkdGVybWluYWxXaWR0aCkgewogICAgICAgICAgICByZXR1cm4gJGxpbmU7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0QmFyV2lkdGgoJHRoaXMtPmJhcldpZHRoIC0gJGxpbmVzV2lkdGggKyAkdGVybWluYWxXaWR0aCk7CgogICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHJlZ2V4LCAkY2FsbGJhY2ssICR0aGlzLT5mb3JtYXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7CgovKioKICogSGVscGVySW50ZXJmYWNlIGlzIHRoZSBpbnRlcmZhY2UgYWxsIGhlbHBlcnMgbXVzdCBpbXBsZW1lbnQuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KaW50ZXJmYWNlIEhlbHBlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFNldHMgdGhlIGhlbHBlciBzZXQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGVscGVyLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVscGVyU2V0KEhlbHBlclNldCAkaGVscGVyU2V0ID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBoZWxwZXIgc2V0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhlbHBlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIEhlbHBlclNldCBBIEhlbHBlclNldCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVyU2V0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYW5vbmljYWwgbmFtZSBvZiB0aGlzIGhlbHBlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgY2Fub25pY2FsIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwoKLyoqCiAqIERlZmluZXMgdGhlIHN0eWxlcyBmb3IgYSBUYWJsZS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3Ig0KHQsNGI0LAg0KHRgtCw0LzQtdC90LrQvtCy0LjRmyA8dW1waXJza3lAZ21haWwuY29tPgogKi8KY2xhc3MgVGFibGVTdHlsZQp7CiAgICBwcml2YXRlICRwYWRkaW5nQ2hhciA9ICcgJzsKICAgIHByaXZhdGUgJGhvcml6b250YWxCb3JkZXJDaGFyID0gJy0nOwogICAgcHJpdmF0ZSAkdmVydGljYWxCb3JkZXJDaGFyID0gJ3wnOwogICAgcHJpdmF0ZSAkY3Jvc3NpbmdDaGFyID0gJysnOwogICAgcHJpdmF0ZSAkY2VsbEhlYWRlckZvcm1hdCA9ICc8aW5mbz4lczwvaW5mbz4nOwogICAgcHJpdmF0ZSAkY2VsbFJvd0Zvcm1hdCA9ICclcyc7CiAgICBwcml2YXRlICRjZWxsUm93Q29udGVudEZvcm1hdCA9ICcgJXMgJzsKICAgIHByaXZhdGUgJGJvcmRlckZvcm1hdCA9ICclcyc7CiAgICBwcml2YXRlICRwYWRUeXBlID0gXFNUUl9QQURfUklHSFQ7CgogICAgLyoqCiAgICAgKiBTZXRzIHBhZGRpbmcgY2hhcmFjdGVyLCB1c2VkIGZvciBjZWxsIHBhZGRpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGFkZGluZ0NoYXIKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQYWRkaW5nQ2hhcigkcGFkZGluZ0NoYXIpCiAgICB7CiAgICAgICAgaWYgKCEkcGFkZGluZ0NoYXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdUaGUgcGFkZGluZyBjaGFyIG11c3Qgbm90IGJlIGVtcHR5LicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnBhZGRpbmdDaGFyID0gJHBhZGRpbmdDaGFyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHBhZGRpbmcgY2hhcmFjdGVyLCB1c2VkIGZvciBjZWxsIHBhZGRpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhZGRpbmdDaGFyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhZGRpbmdDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBob3Jpem9udGFsIGJvcmRlciBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaG9yaXpvbnRhbEJvcmRlckNoYXIKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIb3Jpem9udGFsQm9yZGVyQ2hhcigkaG9yaXpvbnRhbEJvcmRlckNoYXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmhvcml6b250YWxCb3JkZXJDaGFyID0gJGhvcml6b250YWxCb3JkZXJDaGFyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGhvcml6b250YWwgYm9yZGVyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SG9yaXpvbnRhbEJvcmRlckNoYXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aG9yaXpvbnRhbEJvcmRlckNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHZlcnRpY2FsIGJvcmRlciBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmVydGljYWxCb3JkZXJDaGFyCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVydGljYWxCb3JkZXJDaGFyKCR2ZXJ0aWNhbEJvcmRlckNoYXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnZlcnRpY2FsQm9yZGVyQ2hhciA9ICR2ZXJ0aWNhbEJvcmRlckNoYXI7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdmVydGljYWwgYm9yZGVyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVydGljYWxCb3JkZXJDaGFyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnRpY2FsQm9yZGVyQ2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgY3Jvc3NpbmcgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNyb3NzaW5nQ2hhcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENyb3NzaW5nQ2hhcigkY3Jvc3NpbmdDaGFyKQogICAgewogICAgICAgICR0aGlzLT5jcm9zc2luZ0NoYXIgPSAkY3Jvc3NpbmdDaGFyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGNyb3NzaW5nIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q3Jvc3NpbmdDaGFyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNyb3NzaW5nQ2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgaGVhZGVyIGNlbGwgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNlbGxIZWFkZXJGb3JtYXQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDZWxsSGVhZGVyRm9ybWF0KCRjZWxsSGVhZGVyRm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5jZWxsSGVhZGVyRm9ybWF0ID0gJGNlbGxIZWFkZXJGb3JtYXQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgaGVhZGVyIGNlbGwgZm9ybWF0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDZWxsSGVhZGVyRm9ybWF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNlbGxIZWFkZXJGb3JtYXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHJvdyBjZWxsIGZvcm1hdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjZWxsUm93Rm9ybWF0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2VsbFJvd0Zvcm1hdCgkY2VsbFJvd0Zvcm1hdCkKICAgIHsKICAgICAgICAkdGhpcy0+Y2VsbFJvd0Zvcm1hdCA9ICRjZWxsUm93Rm9ybWF0OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHJvdyBjZWxsIGZvcm1hdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2VsbFJvd0Zvcm1hdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jZWxsUm93Rm9ybWF0OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyByb3cgY2VsbCBjb250ZW50IGZvcm1hdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjZWxsUm93Q29udGVudEZvcm1hdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENlbGxSb3dDb250ZW50Rm9ybWF0KCRjZWxsUm93Q29udGVudEZvcm1hdCkKICAgIHsKICAgICAgICAkdGhpcy0+Y2VsbFJvd0NvbnRlbnRGb3JtYXQgPSAkY2VsbFJvd0NvbnRlbnRGb3JtYXQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgcm93IGNlbGwgY29udGVudCBmb3JtYXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENlbGxSb3dDb250ZW50Rm9ybWF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNlbGxSb3dDb250ZW50Rm9ybWF0OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0YWJsZSBib3JkZXIgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJvcmRlckZvcm1hdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvcmRlckZvcm1hdCgkYm9yZGVyRm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5ib3JkZXJGb3JtYXQgPSAkYm9yZGVyRm9ybWF0OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRhYmxlIGJvcmRlciBmb3JtYXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvcmRlckZvcm1hdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib3JkZXJGb3JtYXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGNlbGwgcGFkZGluZyB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJHBhZFR5cGUgU1RSX1BBRF8qCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGFkVHlwZSgkcGFkVHlwZSkKICAgIHsKICAgICAgICBpZiAoIVxpbl9hcnJheSgkcGFkVHlwZSwgW1xTVFJfUEFEX0xFRlQsIFxTVFJfUEFEX1JJR0hULCBcU1RSX1BBRF9CT1RIXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignSW52YWxpZCBwYWRkaW5nIHR5cGUuIEV4cGVjdGVkIG9uZSBvZiAoU1RSX1BBRF9MRUZULCBTVFJfUEFEX1JJR0hULCBTVFJfUEFEX0JPVEgpLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnBhZFR5cGUgPSAkcGFkVHlwZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBjZWxsIHBhZGRpbmcgdHlwZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFkVHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYWRUeXBlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlclN0eWxlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcQ29uc29sZU91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cQ2hvaWNlUXVlc3Rpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXFF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxUZXJtaW5hbDsKCi8qKgogKiBUaGUgUXVlc3Rpb25IZWxwZXIgY2xhc3MgcHJvdmlkZXMgaGVscGVycyB0byBpbnRlcmFjdCB3aXRoIHRoZSB1c2VyLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIFF1ZXN0aW9uSGVscGVyIGV4dGVuZHMgSGVscGVyCnsKICAgIHByaXZhdGUgJGlucHV0U3RyZWFtOwogICAgcHJpdmF0ZSBzdGF0aWMgJHNoZWxsOwogICAgcHJpdmF0ZSBzdGF0aWMgJHN0dHkgPSB0cnVlOwoKICAgIC8qKgogICAgICogQXNrcyBhIHF1ZXN0aW9uIHRvIHRoZSB1c2VyLgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgVGhlIHVzZXIgYW5zd2VyCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZXJlIGlzIG5vIGRhdGEgdG8gcmVhZCBpbiB0aGUgaW5wdXQgc3RyZWFtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2soSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgUXVlc3Rpb24gJHF1ZXN0aW9uKQogICAgewogICAgICAgIGlmICgkb3V0cHV0IGluc3RhbmNlb2YgQ29uc29sZU91dHB1dEludGVyZmFjZSkgewogICAgICAgICAgICAkb3V0cHV0ID0gJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgIGlmICghJGlucHV0LT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgJGRlZmF1bHQgPSAkcXVlc3Rpb24tPmdldERlZmF1bHQoKTsKCiAgICAgICAgICAgIGlmIChudWxsID09PSAkZGVmYXVsdCkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHZhbGlkYXRvciA9ICRxdWVzdGlvbi0+Z2V0VmFsaWRhdG9yKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBcY2FsbF91c2VyX2Z1bmMoJHF1ZXN0aW9uLT5nZXRWYWxpZGF0b3IoKSwgJGRlZmF1bHQpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHF1ZXN0aW9uIGluc3RhbmNlb2YgQ2hvaWNlUXVlc3Rpb24pIHsKICAgICAgICAgICAgICAgICRjaG9pY2VzID0gJHF1ZXN0aW9uLT5nZXRDaG9pY2VzKCk7CgogICAgICAgICAgICAgICAgaWYgKCEkcXVlc3Rpb24tPmlzTXVsdGlzZWxlY3QoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc3NldCgkY2hvaWNlc1skZGVmYXVsdF0pID8gJGNob2ljZXNbJGRlZmF1bHRdIDogJGRlZmF1bHQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGRlZmF1bHQgPSBleHBsb2RlKCcsJywgJGRlZmF1bHQpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRlZmF1bHQgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgICAgICAgICAkdiA9IHRyaW0oJHYpOwogICAgICAgICAgICAgICAgICAgICRkZWZhdWx0WyRrXSA9IGlzc2V0KCRjaG9pY2VzWyR2XSkgPyAkY2hvaWNlc1skdl0gOiAkdjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dCBpbnN0YW5jZW9mIFN0cmVhbWFibGVJbnB1dEludGVyZmFjZSAmJiAkc3RyZWFtID0gJGlucHV0LT5nZXRTdHJlYW0oKSkgewogICAgICAgICAgICAkdGhpcy0+aW5wdXRTdHJlYW0gPSAkc3RyZWFtOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkcXVlc3Rpb24tPmdldFZhbGlkYXRvcigpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9Bc2soJG91dHB1dCwgJHF1ZXN0aW9uKTsKICAgICAgICB9CgogICAgICAgICRpbnRlcnZpZXdlciA9IGZ1bmN0aW9uICgpIHVzZSAoJG91dHB1dCwgJHF1ZXN0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9Bc2soJG91dHB1dCwgJHF1ZXN0aW9uKTsKICAgICAgICB9OwoKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbGlkYXRlQXR0ZW1wdHMoJGludGVydmlld2VyLCAkb3V0cHV0LCAkcXVlc3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW5wdXQgc3RyZWFtIHRvIHJlYWQgZnJvbSB3aGVuIGludGVyYWN0aW5nIHdpdGggdGhlIHVzZXIuCiAgICAgKgogICAgICogVGhpcyBpcyBtYWlubHkgdXNlZnVsIGZvciB0ZXN0aW5nIHB1cnBvc2UuCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjIsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UKICAgICAqICAgICAgICAgICAgIFN0cmVhbWFibGVJbnB1dEludGVyZmFjZTo6c2V0U3RyZWFtKCkgaW5zdGVhZC4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJHN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSW4gY2FzZSB0aGUgc3RyZWFtIGlzIG5vdCBhIHJlc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnB1dFN0cmVhbSgkc3RyZWFtKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4yIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgJXM6OnNldFN0cmVhbSgpIGluc3RlYWQuJywgX19NRVRIT0RfXywgU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlOjpjbGFzcyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIGlmICghXGlzX3Jlc291cmNlKCRzdHJlYW0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0lucHV0IHN0cmVhbSBtdXN0IGJlIGEgdmFsaWQgcmVzb3VyY2UuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW5wdXRTdHJlYW0gPSAkc3RyZWFtOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaGVscGVyJ3MgaW5wdXQgc3RyZWFtLgogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4yLCB0byBiZSByZW1vdmVkIGluIDQuMC4gVXNlCiAgICAgKiAgICAgICAgICAgICBTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2U6OmdldFN0cmVhbSgpIGluc3RlYWQuCiAgICAgKgogICAgICogQHJldHVybiByZXNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5wdXRTdHJlYW0oKQogICAgewogICAgICAgIGlmICgwID09PSBcZnVuY19udW1fYXJncygpIHx8IGZ1bmNfZ2V0X2FyZygwKSkgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMiBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gVXNlICVzOjpnZXRTdHJlYW0oKSBpbnN0ZWFkLicsIF9fTUVUSE9EX18sIFN0cmVhbWFibGVJbnB1dEludGVyZmFjZTo6Y2xhc3MpLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dFN0cmVhbTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAncXVlc3Rpb24nOwogICAgfQoKICAgIC8qKgogICAgICogUHJldmVudHMgdXNhZ2Ugb2Ygc3R0eS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkaXNhYmxlU3R0eSgpCiAgICB7CiAgICAgICAgc2VsZjo6JHN0dHkgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEFza3MgdGhlIHF1ZXN0aW9uIHRvIHRoZSB1c2VyLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbHxtaXhlZHxzdHJpbmd8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIHRoZSBmYWxsYmFjayBpcyBkZWFjdGl2YXRlZCBhbmQgdGhlIHJlc3BvbnNlIGNhbm5vdCBiZSBoaWRkZW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBkb0FzayhPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgUXVlc3Rpb24gJHF1ZXN0aW9uKQogICAgewogICAgICAgICR0aGlzLT53cml0ZVByb21wdCgkb3V0cHV0LCAkcXVlc3Rpb24pOwoKICAgICAgICAkaW5wdXRTdHJlYW0gPSAkdGhpcy0+aW5wdXRTdHJlYW0gPzogXFNURElOOwogICAgICAgICRhdXRvY29tcGxldGUgPSAkcXVlc3Rpb24tPmdldEF1dG9jb21wbGV0ZXJWYWx1ZXMoKTsKCiAgICAgICAgaWYgKFxmdW5jdGlvbl9leGlzdHMoJ3NhcGlfd2luZG93c19jcF9zZXQnKSkgewogICAgICAgICAgICAvLyBDb2RlcGFnZSB1c2VkIGJ5IGNtZC5leGUgb24gV2luZG93cyB0byBhbGxvdyBzcGVjaWFsIGNoYXJhY3RlcnMgKMOpw6DDvMOxKS4KICAgICAgICAgICAgQHNhcGlfd2luZG93c19jcF9zZXQoMTI1Mik7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGF1dG9jb21wbGV0ZSB8fCAhc2VsZjo6JHN0dHkgfHwgIVRlcm1pbmFsOjpoYXNTdHR5QXZhaWxhYmxlKCkpIHsKICAgICAgICAgICAgJHJldCA9IGZhbHNlOwogICAgICAgICAgICBpZiAoJHF1ZXN0aW9uLT5pc0hpZGRlbigpKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRyZXQgPSB0cmltKCR0aGlzLT5nZXRIaWRkZW5SZXNwb25zZSgkb3V0cHV0LCAkaW5wdXRTdHJlYW0pKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISRxdWVzdGlvbi0+aXNIaWRkZW5GYWxsYmFjaygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkcmV0KSB7CiAgICAgICAgICAgICAgICAkcmV0ID0gZmdldHMoJGlucHV0U3RyZWFtLCA0MDk2KTsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHJldCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdBYm9ydGVkLicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJldCA9IHRyaW0oJHJldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcmV0ID0gdHJpbSgkdGhpcy0+YXV0b2NvbXBsZXRlKCRvdXRwdXQsICRxdWVzdGlvbiwgJGlucHV0U3RyZWFtLCBcaXNfYXJyYXkoJGF1dG9jb21wbGV0ZSkgPyAkYXV0b2NvbXBsZXRlIDogaXRlcmF0b3JfdG9fYXJyYXkoJGF1dG9jb21wbGV0ZSwgZmFsc2UpKSk7CiAgICAgICAgfQoKICAgICAgICAkcmV0ID0gXHN0cmxlbigkcmV0KSA+IDAgPyAkcmV0IDogJHF1ZXN0aW9uLT5nZXREZWZhdWx0KCk7CgogICAgICAgIGlmICgkbm9ybWFsaXplciA9ICRxdWVzdGlvbi0+Z2V0Tm9ybWFsaXplcigpKSB7CiAgICAgICAgICAgIHJldHVybiAkbm9ybWFsaXplcigkcmV0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmV0OwogICAgfQoKICAgIC8qKgogICAgICogT3V0cHV0cyB0aGUgcXVlc3Rpb24gcHJvbXB0LgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGVQcm9tcHQoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbikKICAgIHsKICAgICAgICAkbWVzc2FnZSA9ICRxdWVzdGlvbi0+Z2V0UXVlc3Rpb24oKTsKCiAgICAgICAgaWYgKCRxdWVzdGlvbiBpbnN0YW5jZW9mIENob2ljZVF1ZXN0aW9uKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oYXJyYXlfbWVyZ2UoWwogICAgICAgICAgICAgICAgJHF1ZXN0aW9uLT5nZXRRdWVzdGlvbigpLAogICAgICAgICAgICBdLCAkdGhpcy0+Zm9ybWF0Q2hvaWNlUXVlc3Rpb25DaG9pY2VzKCRxdWVzdGlvbiwgJ2luZm8nKSkpOwoKICAgICAgICAgICAgJG1lc3NhZ2UgPSAkcXVlc3Rpb24tPmdldFByb21wdCgpOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dC0+d3JpdGUoJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdGFnCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZm9ybWF0Q2hvaWNlUXVlc3Rpb25DaG9pY2VzKENob2ljZVF1ZXN0aW9uICRxdWVzdGlvbiwgJHRhZykKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBbXTsKCiAgICAgICAgJG1heFdpZHRoID0gbWF4KGFycmF5X21hcCgnc2VsZjo6c3RybGVuJywgYXJyYXlfa2V5cygkY2hvaWNlcyA9ICRxdWVzdGlvbi0+Z2V0Q2hvaWNlcygpKSkpOwoKICAgICAgICBmb3JlYWNoICgkY2hvaWNlcyBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAkcGFkZGluZyA9IHN0cl9yZXBlYXQoJyAnLCAkbWF4V2lkdGggLSBzZWxmOjpzdHJsZW4oJGtleSkpOwoKICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSBzcHJpbnRmKCIgIFs8JHRhZz4lcyRwYWRkaW5nPC8kdGFnPl0gJXMiLCAka2V5LCAkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtZXNzYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIE91dHB1dHMgYW4gZXJyb3IgbWVzc2FnZS4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlRXJyb3IoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFxFeGNlcHRpb24gJGVycm9yKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+Z2V0SGVscGVyU2V0KCkgJiYgJHRoaXMtPmdldEhlbHBlclNldCgpLT5oYXMoJ2Zvcm1hdHRlcicpKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJHRoaXMtPmdldEhlbHBlclNldCgpLT5nZXQoJ2Zvcm1hdHRlcicpLT5mb3JtYXRCbG9jaygkZXJyb3ItPmdldE1lc3NhZ2UoKSwgJ2Vycm9yJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAnPGVycm9yPicuJGVycm9yLT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgICRvdXRwdXQtPndyaXRlbG4oJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQXV0b2NvbXBsZXRlcyBhIHF1ZXN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSAkaW5wdXRTdHJlYW0KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGF1dG9jb21wbGV0ZShPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgUXVlc3Rpb24gJHF1ZXN0aW9uLCAkaW5wdXRTdHJlYW0sIGFycmF5ICRhdXRvY29tcGxldGUpCiAgICB7CiAgICAgICAgJGZ1bGxDaG9pY2UgPSAnJzsKICAgICAgICAkcmV0ID0gJyc7CgogICAgICAgICRpID0gMDsKICAgICAgICAkb2ZzID0gLTE7CiAgICAgICAgJG1hdGNoZXMgPSAkYXV0b2NvbXBsZXRlOwogICAgICAgICRudW1NYXRjaGVzID0gXGNvdW50KCRtYXRjaGVzKTsKCiAgICAgICAgJHN0dHlNb2RlID0gc2hlbGxfZXhlYygnc3R0eSAtZycpOwoKICAgICAgICAvLyBEaXNhYmxlIGljYW5vbiAoc28gd2UgY2FuIGZyZWFkIGVhY2gga2V5cHJlc3MpIGFuZCBlY2hvICh3ZSdsbCBkbyBlY2hvaW5nIGhlcmUgaW5zdGVhZCkKICAgICAgICBzaGVsbF9leGVjKCdzdHR5IC1pY2Fub24gLWVjaG8nKTsKCiAgICAgICAgLy8gQWRkIGhpZ2hsaWdodGVkIHRleHQgc3R5bGUKICAgICAgICAkb3V0cHV0LT5nZXRGb3JtYXR0ZXIoKS0+c2V0U3R5bGUoJ2hsJywgbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCdibGFjaycsICd3aGl0ZScpKTsKCiAgICAgICAgLy8gUmVhZCBhIGtleXByZXNzCiAgICAgICAgd2hpbGUgKCFmZW9mKCRpbnB1dFN0cmVhbSkpIHsKICAgICAgICAgICAgJGMgPSBmcmVhZCgkaW5wdXRTdHJlYW0sIDEpOwoKICAgICAgICAgICAgLy8gYXMgb3Bwb3NlZCB0byBmZ2V0cygpLCBmcmVhZCgpIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nIHdoZW4gdGhlIHN0cmVhbSBjb250ZW50IGlzIGVtcHR5LCBub3QgZmFsc2UuCiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGMgfHwgKCcnID09PSAkcmV0ICYmICcnID09PSAkYyAmJiBudWxsID09PSAkcXVlc3Rpb24tPmdldERlZmF1bHQoKSkpIHsKICAgICAgICAgICAgICAgIHNoZWxsX2V4ZWMoc3ByaW50Zignc3R0eSAlcycsICRzdHR5TW9kZSkpOwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ0Fib3J0ZWQuJyk7CiAgICAgICAgICAgIH0gZWxzZWlmICgiXDE3NyIgPT09ICRjKSB7IC8vIEJhY2tzcGFjZSBDaGFyYWN0ZXIKICAgICAgICAgICAgICAgIGlmICgwID09PSAkbnVtTWF0Y2hlcyAmJiAwICE9PSAkaSkgewogICAgICAgICAgICAgICAgICAgIC0tJGk7CiAgICAgICAgICAgICAgICAgICAgJGZ1bGxDaG9pY2UgPSBzZWxmOjpzdWJzdHIoJGZ1bGxDaG9pY2UsIDAsICRpKTsKICAgICAgICAgICAgICAgICAgICAvLyBNb3ZlIGN1cnNvciBiYWNrd2FyZHMKICAgICAgICAgICAgICAgICAgICAkb3V0cHV0LT53cml0ZSgiXDAzM1sxRCIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgwID09PSAkaSkgewogICAgICAgICAgICAgICAgICAgICRvZnMgPSAtMTsKICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlcyA9ICRhdXRvY29tcGxldGU7CiAgICAgICAgICAgICAgICAgICAgJG51bU1hdGNoZXMgPSBcY291bnQoJG1hdGNoZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbnVtTWF0Y2hlcyA9IDA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUG9wIHRoZSBsYXN0IGNoYXJhY3RlciBvZmYgdGhlIGVuZCBvZiBvdXIgc3RyaW5nCiAgICAgICAgICAgICAgICAkcmV0ID0gc2VsZjo6c3Vic3RyKCRyZXQsIDAsICRpKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCJcMDMzIiA9PT0gJGMpIHsKICAgICAgICAgICAgICAgIC8vIERpZCB3ZSByZWFkIGFuIGVzY2FwZSBzZXF1ZW5jZT8KICAgICAgICAgICAgICAgICRjIC49IGZyZWFkKCRpbnB1dFN0cmVhbSwgMik7CgogICAgICAgICAgICAgICAgLy8gQSA9IFVwIEFycm93LiBCID0gRG93biBBcnJvdwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRjWzJdKSAmJiAoJ0EnID09PSAkY1syXSB8fCAnQicgPT09ICRjWzJdKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgnQScgPT09ICRjWzJdICYmIC0xID09PSAkb2ZzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRvZnMgPSAwOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09ICRudW1NYXRjaGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJG9mcyArPSAoJ0EnID09PSAkY1syXSkgPyAtMSA6IDE7CiAgICAgICAgICAgICAgICAgICAgJG9mcyA9ICgkbnVtTWF0Y2hlcyArICRvZnMpICUgJG51bU1hdGNoZXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmIChcb3JkKCRjKSA8IDMyKSB7CiAgICAgICAgICAgICAgICBpZiAoIlx0IiA9PT0gJGMgfHwgIlxuIiA9PT0gJGMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJG51bU1hdGNoZXMgPiAwICYmIC0xICE9PSAkb2ZzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXQgPSAkbWF0Y2hlc1skb2ZzXTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRWNobyBvdXQgcmVtYWluaW5nIGNoYXJzIGZvciBjdXJyZW50IG1hdGNoCiAgICAgICAgICAgICAgICAgICAgICAgICRyZW1haW5pbmdDaGFyYWN0ZXJzID0gc3Vic3RyKCRyZXQsIFxzdHJsZW4odHJpbSgkdGhpcy0+bW9zdFJlY2VudGx5RW50ZXJlZFZhbHVlKCRmdWxsQ2hvaWNlKSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoJHJlbWFpbmluZ0NoYXJhY3RlcnMpOwogICAgICAgICAgICAgICAgICAgICAgICAkZnVsbENob2ljZSAuPSAkcmVtYWluaW5nQ2hhcmFjdGVyczsKICAgICAgICAgICAgICAgICAgICAgICAgJGkgPSBzZWxmOjpzdHJsZW4oJGZ1bGxDaG9pY2UpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCJcbiIgPT09ICRjKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRjKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkbnVtTWF0Y2hlcyA9IDA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoIlx4ODAiIDw9ICRjKSB7CiAgICAgICAgICAgICAgICAgICAgJGMgLj0gZnJlYWQoJGlucHV0U3RyZWFtLCBbIlx4QzAiID0+IDEsICJceEQwIiA9PiAxLCAiXHhFMCIgPT4gMiwgIlx4RjAiID0+IDNdWyRjICYgIlx4RjAiXSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoJGMpOwogICAgICAgICAgICAgICAgJHJldCAuPSAkYzsKICAgICAgICAgICAgICAgICRmdWxsQ2hvaWNlIC49ICRjOwogICAgICAgICAgICAgICAgKyskaTsKCiAgICAgICAgICAgICAgICAkdGVtcFJldCA9ICRyZXQ7CgogICAgICAgICAgICAgICAgaWYgKCRxdWVzdGlvbiBpbnN0YW5jZW9mIENob2ljZVF1ZXN0aW9uICYmICRxdWVzdGlvbi0+aXNNdWx0aXNlbGVjdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRlbXBSZXQgPSAkdGhpcy0+bW9zdFJlY2VudGx5RW50ZXJlZFZhbHVlKCRmdWxsQ2hvaWNlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbnVtTWF0Y2hlcyA9IDA7CiAgICAgICAgICAgICAgICAkb2ZzID0gMDsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYXV0b2NvbXBsZXRlIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIC8vIElmIHR5cGVkIGNoYXJhY3RlcnMgbWF0Y2ggdGhlIGJlZ2lubmluZyBjaHVuayBvZiB2YWx1ZSAoZS5nLiBbQWNtZURlXW1vQnVuZGxlKQogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSBzdHJwb3MoJHZhbHVlLCAkdGVtcFJldCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoZXNbJG51bU1hdGNoZXMrK10gPSAkdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBFcmFzZSBjaGFyYWN0ZXJzIGZyb20gY3Vyc29yIHRvIGVuZCBvZiBsaW5lCiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCJcMDMzW0siKTsKCiAgICAgICAgICAgIGlmICgkbnVtTWF0Y2hlcyA+IDAgJiYgLTEgIT09ICRvZnMpIHsKICAgICAgICAgICAgICAgIC8vIFNhdmUgY3Vyc29yIHBvc2l0aW9uCiAgICAgICAgICAgICAgICAkb3V0cHV0LT53cml0ZSgiXDAzMzciKTsKICAgICAgICAgICAgICAgIC8vIFdyaXRlIGhpZ2hsaWdodGVkIHRleHQsIGNvbXBsZXRlIHRoZSBwYXJ0aWFsbHkgZW50ZXJlZCByZXNwb25zZQogICAgICAgICAgICAgICAgJGNoYXJhY3RlcnNFbnRlcmVkID0gXHN0cmxlbih0cmltKCR0aGlzLT5tb3N0UmVjZW50bHlFbnRlcmVkVmFsdWUoJGZ1bGxDaG9pY2UpKSk7CiAgICAgICAgICAgICAgICAkb3V0cHV0LT53cml0ZSgnPGhsPicuT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGVUcmFpbGluZ0JhY2tzbGFzaChzdWJzdHIoJG1hdGNoZXNbJG9mc10sICRjaGFyYWN0ZXJzRW50ZXJlZCkpLic8L2hsPicpOwogICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBjdXJzb3IgcG9zaXRpb24KICAgICAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCJcMDMzOCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNldCBzdHR5IHNvIGl0IGJlaGF2ZXMgbm9ybWFsbHkgYWdhaW4KICAgICAgICBzaGVsbF9leGVjKHNwcmludGYoJ3N0dHkgJXMnLCAkc3R0eU1vZGUpKTsKCiAgICAgICAgcmV0dXJuICRmdWxsQ2hvaWNlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gbW9zdFJlY2VudGx5RW50ZXJlZFZhbHVlKCRlbnRlcmVkKQogICAgewogICAgICAgIC8vIERldGVybWluZSB0aGUgbW9zdCByZWNlbnQgdmFsdWUgdGhhdCB0aGUgdXNlciBlbnRlcmVkCiAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJGVudGVyZWQsICcsJykpIHsKICAgICAgICAgICAgcmV0dXJuICRlbnRlcmVkOwogICAgICAgIH0KCiAgICAgICAgJGNob2ljZXMgPSBleHBsb2RlKCcsJywgJGVudGVyZWQpOwogICAgICAgIGlmIChcc3RybGVuKCRsYXN0Q2hvaWNlID0gdHJpbSgkY2hvaWNlc1tcY291bnQoJGNob2ljZXMpIC0gMV0pKSA+IDApIHsKICAgICAgICAgICAgcmV0dXJuICRsYXN0Q2hvaWNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRlbnRlcmVkOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhIGhpZGRlbiByZXNwb25zZSBmcm9tIHVzZXIuCiAgICAgKgogICAgICogQHBhcmFtIE91dHB1dEludGVyZmFjZSAkb3V0cHV0ICAgICAgQW4gT3V0cHV0IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgICAgICAgICRpbnB1dFN0cmVhbSBUaGUgaGFuZGxlciByZXNvdXJjZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBhbnN3ZXIKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSB0aGUgZmFsbGJhY2sgaXMgZGVhY3RpdmF0ZWQgYW5kIHRoZSByZXNwb25zZSBjYW5ub3QgYmUgaGlkZGVuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0SGlkZGVuUmVzcG9uc2UoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRpbnB1dFN0cmVhbSkKICAgIHsKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgJGV4ZSA9IF9fRElSX18uJy8uLi9SZXNvdXJjZXMvYmluL2hpZGRlbmlucHV0LmV4ZSc7CgogICAgICAgICAgICAvLyBoYW5kbGUgY29kZSBydW5uaW5nIGZyb20gYSBwaGFyCiAgICAgICAgICAgIGlmICgncGhhcjonID09PSBzdWJzdHIoX19GSUxFX18sIDAsIDUpKSB7CiAgICAgICAgICAgICAgICAkdG1wRXhlID0gc3lzX2dldF90ZW1wX2RpcigpLicvaGlkZGVuaW5wdXQuZXhlJzsKICAgICAgICAgICAgICAgIGNvcHkoJGV4ZSwgJHRtcEV4ZSk7CiAgICAgICAgICAgICAgICAkZXhlID0gJHRtcEV4ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZhbHVlID0gcnRyaW0oc2hlbGxfZXhlYygkZXhlKSk7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oJycpOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCR0bXBFeGUpKSB7CiAgICAgICAgICAgICAgICB1bmxpbmsoJHRtcEV4ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZjo6JHN0dHkgJiYgVGVybWluYWw6Omhhc1N0dHlBdmFpbGFibGUoKSkgewogICAgICAgICAgICAkc3R0eU1vZGUgPSBzaGVsbF9leGVjKCdzdHR5IC1nJyk7CgogICAgICAgICAgICBzaGVsbF9leGVjKCdzdHR5IC1lY2hvJyk7CiAgICAgICAgICAgICR2YWx1ZSA9IGZnZXRzKCRpbnB1dFN0cmVhbSwgNDA5Nik7CiAgICAgICAgICAgIHNoZWxsX2V4ZWMoc3ByaW50Zignc3R0eSAlcycsICRzdHR5TW9kZSkpOwoKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdBYm9ydGVkLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdmFsdWUgPSB0cmltKCR2YWx1ZSk7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oJycpOwoKICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSAhPT0gJHNoZWxsID0gJHRoaXMtPmdldFNoZWxsKCkpIHsKICAgICAgICAgICAgJHJlYWRDbWQgPSAnY3NoJyA9PT0gJHNoZWxsID8gJ3NldCBteXBhc3N3b3JkID0gJDwnIDogJ3JlYWQgLXIgbXlwYXNzd29yZCc7CiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50ZigiL3Vzci9iaW4vZW52ICVzIC1jICdzdHR5IC1lY2hvOyAlczsgc3R0eSBlY2hvOyBlY2hvIFwkbXlwYXNzd29yZCciLCAkc2hlbGwsICRyZWFkQ21kKTsKICAgICAgICAgICAgJHZhbHVlID0gcnRyaW0oc2hlbGxfZXhlYygkY29tbWFuZCkpOwogICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCcnKTsKCiAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVW5hYmxlIHRvIGhpZGUgdGhlIHJlc3BvbnNlLicpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIGFuIGF0dGVtcHQuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICAgICAgICAkaW50ZXJ2aWV3ZXIgQSBjYWxsYWJsZSB0aGF0IHdpbGwgYXNrIGZvciBhIHF1ZXN0aW9uIGFuZCByZXR1cm4gdGhlIHJlc3VsdAogICAgICogQHBhcmFtIE91dHB1dEludGVyZmFjZSAkb3V0cHV0ICAgICAgQW4gT3V0cHV0IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gUXVlc3Rpb24gICAgICAgICRxdWVzdGlvbiAgICBBIFF1ZXN0aW9uIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBUaGUgdmFsaWRhdGVkIHJlc3BvbnNlCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uIEluIGNhc2UgdGhlIG1heCBudW1iZXIgb2YgYXR0ZW1wdHMgaGFzIGJlZW4gcmVhY2hlZCBhbmQgbm8gdmFsaWQgcmVzcG9uc2UgaGFzIGJlZW4gZ2l2ZW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZUF0dGVtcHRzKGNhbGxhYmxlICRpbnRlcnZpZXdlciwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbikKICAgIHsKICAgICAgICAkZXJyb3IgPSBudWxsOwogICAgICAgICRhdHRlbXB0cyA9ICRxdWVzdGlvbi0+Z2V0TWF4QXR0ZW1wdHMoKTsKICAgICAgICB3aGlsZSAobnVsbCA9PT0gJGF0dGVtcHRzIHx8ICRhdHRlbXB0cy0tKSB7CiAgICAgICAgICAgIGlmIChudWxsICE9PSAkZXJyb3IpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZUVycm9yKCRvdXRwdXQsICRlcnJvcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXGNhbGxfdXNlcl9mdW5jKCRxdWVzdGlvbi0+Z2V0VmFsaWRhdG9yKCksICRpbnRlcnZpZXdlcigpKTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGVycm9yKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRocm93ICRlcnJvcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSB2YWxpZCB1bml4IHNoZWxsLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGJvb2wgVGhlIHZhbGlkIHNoZWxsIG5hbWUsIGZhbHNlIGluIGNhc2Ugbm8gdmFsaWQgc2hlbGwgaXMgZm91bmQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRTaGVsbCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09IHNlbGY6OiRzaGVsbCkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHNoZWxsOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JHNoZWxsID0gZmFsc2U7CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygnL3Vzci9iaW4vZW52JykpIHsKICAgICAgICAgICAgLy8gaGFuZGxlIG90aGVyIE9TcyB3aXRoIGJhc2gvenNoL2tzaC9jc2ggaWYgYXZhaWxhYmxlIHRvIGhpZGUgdGhlIGFuc3dlcgogICAgICAgICAgICAkdGVzdCA9ICIvdXNyL2Jpbi9lbnYgJXMgLWMgJ2VjaG8gT0snIDI+IC9kZXYvbnVsbCI7CiAgICAgICAgICAgIGZvcmVhY2ggKFsnYmFzaCcsICd6c2gnLCAna3NoJywgJ2NzaCddIGFzICRzaCkgewogICAgICAgICAgICAgICAgaWYgKCdPSycgPT09IHJ0cmltKHNoZWxsX2V4ZWMoc3ByaW50ZigkdGVzdCwgJHNoKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgc2VsZjo6JHNoZWxsID0gJHNoOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JHNoZWxsOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIFByb3ZpZGVzIGhlbHBlcnMgdG8gZGlzcGxheSBhIHRhYmxlLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciDQodCw0YjQsCDQodGC0LDQvNC10L3QutC+0LLQuNGbIDx1bXBpcnNreUBnbWFpbC5jb20+CiAqIEBhdXRob3IgQWJkZWxsYXRpZiBBaXQgYm91ZGFkIDxhLmFpdGJvdWRhZEBnbWFpbC5jb20+CiAqIEBhdXRob3IgTWF4IEdyaWdvcmlhbiA8bWF4YWthd2l6YXJkQGdtYWlsLmNvbT4KICovCmNsYXNzIFRhYmxlCnsKICAgIC8qKgogICAgICogVGFibGUgaGVhZGVycy4KICAgICAqLwogICAgcHJpdmF0ZSAkaGVhZGVycyA9IFtdOwoKICAgIC8qKgogICAgICogVGFibGUgcm93cy4KICAgICAqLwogICAgcHJpdmF0ZSAkcm93cyA9IFtdOwoKICAgIC8qKgogICAgICogQ29sdW1uIHdpZHRocyBjYWNoZS4KICAgICAqLwogICAgcHJpdmF0ZSAkZWZmZWN0aXZlQ29sdW1uV2lkdGhzID0gW107CgogICAgLyoqCiAgICAgKiBOdW1iZXIgb2YgY29sdW1ucyBjYWNoZS4KICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcml2YXRlICRudW1iZXJPZkNvbHVtbnM7CgogICAgLyoqCiAgICAgKiBAdmFyIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRvdXRwdXQ7CgogICAgLyoqCiAgICAgKiBAdmFyIFRhYmxlU3R5bGUKICAgICAqLwogICAgcHJpdmF0ZSAkc3R5bGU7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJGNvbHVtblN0eWxlcyA9IFtdOwoKICAgIC8qKgogICAgICogVXNlciBzZXQgY29sdW1uIHdpZHRocy4KICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJGNvbHVtbldpZHRocyA9IFtdOwoKICAgIHByaXZhdGUgc3RhdGljICRzdHlsZXM7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwoKICAgICAgICBpZiAoIXNlbGY6OiRzdHlsZXMpIHsKICAgICAgICAgICAgc2VsZjo6JHN0eWxlcyA9IHNlbGY6OmluaXRTdHlsZXMoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXRTdHlsZSgnZGVmYXVsdCcpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIHN0eWxlIGRlZmluaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJG5hbWUgIFRoZSBzdHlsZSBuYW1lCiAgICAgKiBAcGFyYW0gVGFibGVTdHlsZSAkc3R5bGUgQSBUYWJsZVN0eWxlIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0U3R5bGVEZWZpbml0aW9uKCRuYW1lLCBUYWJsZVN0eWxlICRzdHlsZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRzdHlsZXMpIHsKICAgICAgICAgICAgc2VsZjo6JHN0eWxlcyA9IHNlbGY6OmluaXRTdHlsZXMoKTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRzdHlsZXNbJG5hbWVdID0gJHN0eWxlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhIHN0eWxlIGRlZmluaXRpb24gYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBzdHlsZSBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBUYWJsZVN0eWxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0U3R5bGVEZWZpbml0aW9uKCRuYW1lKQogICAgewogICAgICAgIGlmICghc2VsZjo6JHN0eWxlcykgewogICAgICAgICAgICBzZWxmOjokc3R5bGVzID0gc2VsZjo6aW5pdFN0eWxlcygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRzdHlsZXNbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHN0eWxlc1skbmFtZV07CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1N0eWxlICIlcyIgaXMgbm90IGRlZmluZWQuJywgJG5hbWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGFibGUgc3R5bGUuCiAgICAgKgogICAgICogQHBhcmFtIFRhYmxlU3R5bGV8c3RyaW5nICRuYW1lIFRoZSBzdHlsZSBuYW1lIG9yIGEgVGFibGVTdHlsZSBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0eWxlKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5zdHlsZSA9ICR0aGlzLT5yZXNvbHZlU3R5bGUoJG5hbWUpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHRhYmxlIHN0eWxlLgogICAgICoKICAgICAqIEByZXR1cm4gVGFibGVTdHlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3R5bGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3R5bGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRhYmxlIGNvbHVtbiBzdHlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgJGNvbHVtbkluZGV4IENvbHVtbiBpbmRleAogICAgICogQHBhcmFtIFRhYmxlU3R5bGV8c3RyaW5nICRuYW1lICAgICAgICBUaGUgc3R5bGUgbmFtZSBvciBhIFRhYmxlU3R5bGUgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb2x1bW5TdHlsZSgkY29sdW1uSW5kZXgsICRuYW1lKQogICAgewogICAgICAgICRjb2x1bW5JbmRleCA9IChpbnQpICRjb2x1bW5JbmRleDsKCiAgICAgICAgJHRoaXMtPmNvbHVtblN0eWxlc1skY29sdW1uSW5kZXhdID0gJHRoaXMtPnJlc29sdmVTdHlsZSgkbmFtZSk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGN1cnJlbnQgc3R5bGUgZm9yIGEgY29sdW1uLgogICAgICoKICAgICAqIElmIHN0eWxlIHdhcyBub3Qgc2V0LCBpdCByZXR1cm5zIHRoZSBnbG9iYWwgdGFibGUgc3R5bGUuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkY29sdW1uSW5kZXggQ29sdW1uIGluZGV4CiAgICAgKgogICAgICogQHJldHVybiBUYWJsZVN0eWxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb2x1bW5TdHlsZSgkY29sdW1uSW5kZXgpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb2x1bW5TdHlsZXNbJGNvbHVtbkluZGV4XSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb2x1bW5TdHlsZXNbJGNvbHVtbkluZGV4XTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0U3R5bGUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1pbmltdW0gd2lkdGggb2YgYSBjb2x1bW4uCiAgICAgKgogICAgICogQHBhcmFtIGludCAkY29sdW1uSW5kZXggQ29sdW1uIGluZGV4CiAgICAgKiBAcGFyYW0gaW50ICR3aWR0aCAgICAgICBNaW5pbXVtIGNvbHVtbiB3aWR0aCBpbiBjaGFyYWN0ZXJzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29sdW1uV2lkdGgoJGNvbHVtbkluZGV4LCAkd2lkdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbHVtbldpZHRoc1soaW50KSAkY29sdW1uSW5kZXhdID0gKGludCkgJHdpZHRoOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBtaW5pbXVtIHdpZHRoIG9mIGFsbCBjb2x1bW5zLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbHVtbldpZHRocyhhcnJheSAkd2lkdGhzKQogICAgewogICAgICAgICR0aGlzLT5jb2x1bW5XaWR0aHMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkd2lkdGhzIGFzICRpbmRleCA9PiAkd2lkdGgpIHsKICAgICAgICAgICAgJHRoaXMtPnNldENvbHVtbldpZHRoKCRpbmRleCwgJHdpZHRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVhZGVycyhhcnJheSAkaGVhZGVycykKICAgIHsKICAgICAgICAkaGVhZGVycyA9IGFycmF5X3ZhbHVlcygkaGVhZGVycyk7CiAgICAgICAgaWYgKCFlbXB0eSgkaGVhZGVycykgJiYgIVxpc19hcnJheSgkaGVhZGVyc1swXSkpIHsKICAgICAgICAgICAgJGhlYWRlcnMgPSBbJGhlYWRlcnNdOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmhlYWRlcnMgPSAkaGVhZGVyczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSb3dzKGFycmF5ICRyb3dzKQogICAgewogICAgICAgICR0aGlzLT5yb3dzID0gW107CgogICAgICAgIHJldHVybiAkdGhpcy0+YWRkUm93cygkcm93cyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJvd3MoYXJyYXkgJHJvd3MpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHJvd3MgYXMgJHJvdykgewogICAgICAgICAgICAkdGhpcy0+YWRkUm93KCRyb3cpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSb3coJHJvdykKICAgIHsKICAgICAgICBpZiAoJHJvdyBpbnN0YW5jZW9mIFRhYmxlU2VwYXJhdG9yKSB7CiAgICAgICAgICAgICR0aGlzLT5yb3dzW10gPSAkcm93OwoKICAgICAgICAgICAgcmV0dXJuICR0aGlzOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcaXNfYXJyYXkoJHJvdykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignQSByb3cgbXVzdCBiZSBhbiBhcnJheSBvciBhIFRhYmxlU2VwYXJhdG9yIGluc3RhbmNlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJvd3NbXSA9IGFycmF5X3ZhbHVlcygkcm93KTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSb3coJGNvbHVtbiwgYXJyYXkgJHJvdykKICAgIHsKICAgICAgICAkdGhpcy0+cm93c1skY29sdW1uXSA9ICRyb3c7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlcnMgdGFibGUgdG8gb3V0cHV0LgogICAgICoKICAgICAqIEV4YW1wbGU6CiAgICAgKgogICAgICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICogICAgIHwgSVNCTiAgICAgICAgICB8IFRpdGxlICAgICAgICAgICAgICAgICB8IEF1dGhvciAgICAgICAgICAgfAogICAgICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICogICAgIHwgOTk5MjEtNTgtMTAtNyB8IERpdmluZSBDb21lZHkgICAgICAgICB8IERhbnRlIEFsaWdoaWVyaSAgfAogICAgICogICAgIHwgOTk3MS01LTAyMTAtMCB8IEEgVGFsZSBvZiBUd28gQ2l0aWVzICB8IENoYXJsZXMgRGlja2VucyAgfAogICAgICogICAgIHwgOTYwLTQyNS0wNTktMCB8IFRoZSBMb3JkIG9mIHRoZSBSaW5ncyB8IEouIFIuIFIuIFRvbGtpZW4gfAogICAgICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVyKCkKICAgIHsKICAgICAgICAkdGhpcy0+Y2FsY3VsYXRlTnVtYmVyT2ZDb2x1bW5zKCk7CiAgICAgICAgJHJvd3MgPSAkdGhpcy0+YnVpbGRUYWJsZVJvd3MoJHRoaXMtPnJvd3MpOwogICAgICAgICRoZWFkZXJzID0gJHRoaXMtPmJ1aWxkVGFibGVSb3dzKCR0aGlzLT5oZWFkZXJzKTsKCiAgICAgICAgJHRoaXMtPmNhbGN1bGF0ZUNvbHVtbnNXaWR0aChhcnJheV9tZXJnZSgkaGVhZGVycywgJHJvd3MpKTsKCiAgICAgICAgJHRoaXMtPnJlbmRlclJvd1NlcGFyYXRvcigpOwogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcnMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJSb3coJGhlYWRlciwgJHRoaXMtPnN0eWxlLT5nZXRDZWxsSGVhZGVyRm9ybWF0KCkpOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclJvd1NlcGFyYXRvcigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRyb3dzIGFzICRyb3cpIHsKICAgICAgICAgICAgaWYgKCRyb3cgaW5zdGFuY2VvZiBUYWJsZVNlcGFyYXRvcikgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclJvd1NlcGFyYXRvcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclJvdygkcm93LCAkdGhpcy0+c3R5bGUtPmdldENlbGxSb3dGb3JtYXQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFlbXB0eSgkcm93cykpIHsKICAgICAgICAgICAgJHRoaXMtPnJlbmRlclJvd1NlcGFyYXRvcigpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNsZWFudXAoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlcnMgaG9yaXpvbnRhbCBoZWFkZXIgc2VwYXJhdG9yLgogICAgICoKICAgICAqIEV4YW1wbGU6CiAgICAgKgogICAgICogICAgICstLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tKwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbmRlclJvd1NlcGFyYXRvcigpCiAgICB7CiAgICAgICAgaWYgKDAgPT09ICRjb3VudCA9ICR0aGlzLT5udW1iZXJPZkNvbHVtbnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+c3R5bGUtPmdldEhvcml6b250YWxCb3JkZXJDaGFyKCkgJiYgISR0aGlzLT5zdHlsZS0+Z2V0Q3Jvc3NpbmdDaGFyKCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJG1hcmt1cCA9ICR0aGlzLT5zdHlsZS0+Z2V0Q3Jvc3NpbmdDaGFyKCk7CiAgICAgICAgZm9yICgkY29sdW1uID0gMDsgJGNvbHVtbiA8ICRjb3VudDsgKyskY29sdW1uKSB7CiAgICAgICAgICAgICRtYXJrdXAgLj0gc3RyX3JlcGVhdCgkdGhpcy0+c3R5bGUtPmdldEhvcml6b250YWxCb3JkZXJDaGFyKCksICR0aGlzLT5lZmZlY3RpdmVDb2x1bW5XaWR0aHNbJGNvbHVtbl0pLiR0aGlzLT5zdHlsZS0+Z2V0Q3Jvc3NpbmdDaGFyKCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3V0cHV0LT53cml0ZWxuKHNwcmludGYoJHRoaXMtPnN0eWxlLT5nZXRCb3JkZXJGb3JtYXQoKSwgJG1hcmt1cCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVycyB2ZXJ0aWNhbCBjb2x1bW4gc2VwYXJhdG9yLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbmRlckNvbHVtblNlcGFyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnN0eWxlLT5nZXRCb3JkZXJGb3JtYXQoKSwgJHRoaXMtPnN0eWxlLT5nZXRWZXJ0aWNhbEJvcmRlckNoYXIoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXJzIHRhYmxlIHJvdy4KICAgICAqCiAgICAgKiBFeGFtcGxlOgogICAgICoKICAgICAqICAgICB8IDk5NzEtNS0wMjEwLTAgfCBBIFRhbGUgb2YgVHdvIENpdGllcyAgfCBDaGFybGVzIERpY2tlbnMgIHwKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjZWxsRm9ybWF0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVuZGVyUm93KGFycmF5ICRyb3csICRjZWxsRm9ybWF0KQogICAgewogICAgICAgIGlmIChlbXB0eSgkcm93KSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkcm93Q29udGVudCA9ICR0aGlzLT5yZW5kZXJDb2x1bW5TZXBhcmF0b3IoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0Um93Q29sdW1ucygkcm93KSBhcyAkY29sdW1uKSB7CiAgICAgICAgICAgICRyb3dDb250ZW50IC49ICR0aGlzLT5yZW5kZXJDZWxsKCRyb3csICRjb2x1bW4sICRjZWxsRm9ybWF0KTsKICAgICAgICAgICAgJHJvd0NvbnRlbnQgLj0gJHRoaXMtPnJlbmRlckNvbHVtblNlcGFyYXRvcigpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+b3V0cHV0LT53cml0ZWxuKCRyb3dDb250ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlcnMgdGFibGUgY2VsbCB3aXRoIHBhZGRpbmcuCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAkY29sdW1uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjZWxsRm9ybWF0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVuZGVyQ2VsbChhcnJheSAkcm93LCAkY29sdW1uLCAkY2VsbEZvcm1hdCkKICAgIHsKICAgICAgICAkY2VsbCA9IGlzc2V0KCRyb3dbJGNvbHVtbl0pID8gJHJvd1skY29sdW1uXSA6ICcnOwogICAgICAgICR3aWR0aCA9ICR0aGlzLT5lZmZlY3RpdmVDb2x1bW5XaWR0aHNbJGNvbHVtbl07CiAgICAgICAgaWYgKCRjZWxsIGluc3RhbmNlb2YgVGFibGVDZWxsICYmICRjZWxsLT5nZXRDb2xzcGFuKCkgPiAxKSB7CiAgICAgICAgICAgIC8vIGFkZCB0aGUgd2lkdGggb2YgdGhlIGZvbGxvd2luZyBjb2x1bW5zKG51bWJlcnMgb2YgY29sc3BhbikuCiAgICAgICAgICAgIGZvcmVhY2ggKHJhbmdlKCRjb2x1bW4gKyAxLCAkY29sdW1uICsgJGNlbGwtPmdldENvbHNwYW4oKSAtIDEpIGFzICRuZXh0Q29sdW1uKSB7CiAgICAgICAgICAgICAgICAkd2lkdGggKz0gJHRoaXMtPmdldENvbHVtblNlcGFyYXRvcldpZHRoKCkgKyAkdGhpcy0+ZWZmZWN0aXZlQ29sdW1uV2lkdGhzWyRuZXh0Q29sdW1uXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gc3RyX3BhZCB3b24ndCB3b3JrIHByb3Blcmx5IHdpdGggbXVsdGktYnl0ZSBzdHJpbmdzLCB3ZSBuZWVkIHRvIGZpeCB0aGUgcGFkZGluZwogICAgICAgIGlmIChmYWxzZSAhPT0gJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCRjZWxsLCBudWxsLCB0cnVlKSkgewogICAgICAgICAgICAkd2lkdGggKz0gXHN0cmxlbigkY2VsbCkgLSBtYl9zdHJ3aWR0aCgkY2VsbCwgJGVuY29kaW5nKTsKICAgICAgICB9CgogICAgICAgICRzdHlsZSA9ICR0aGlzLT5nZXRDb2x1bW5TdHlsZSgkY29sdW1uKTsKCiAgICAgICAgaWYgKCRjZWxsIGluc3RhbmNlb2YgVGFibGVTZXBhcmF0b3IpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJHN0eWxlLT5nZXRCb3JkZXJGb3JtYXQoKSwgc3RyX3JlcGVhdCgkc3R5bGUtPmdldEhvcml6b250YWxCb3JkZXJDaGFyKCksICR3aWR0aCkpOwogICAgICAgIH0KCiAgICAgICAgJHdpZHRoICs9IEhlbHBlcjo6c3RybGVuKCRjZWxsKSAtIEhlbHBlcjo6c3RybGVuV2l0aG91dERlY29yYXRpb24oJHRoaXMtPm91dHB1dC0+Z2V0Rm9ybWF0dGVyKCksICRjZWxsKTsKICAgICAgICAkY29udGVudCA9IHNwcmludGYoJHN0eWxlLT5nZXRDZWxsUm93Q29udGVudEZvcm1hdCgpLCAkY2VsbCk7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCRjZWxsRm9ybWF0LCBzdHJfcGFkKCRjb250ZW50LCAkd2lkdGgsICRzdHlsZS0+Z2V0UGFkZGluZ0NoYXIoKSwgJHN0eWxlLT5nZXRQYWRUeXBlKCkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENhbGN1bGF0ZSBudW1iZXIgb2YgY29sdW1ucyBmb3IgdGhpcyB0YWJsZS4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYWxjdWxhdGVOdW1iZXJPZkNvbHVtbnMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+bnVtYmVyT2ZDb2x1bW5zKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRjb2x1bW5zID0gWzBdOwogICAgICAgIGZvcmVhY2ggKGFycmF5X21lcmdlKCR0aGlzLT5oZWFkZXJzLCAkdGhpcy0+cm93cykgYXMgJHJvdykgewogICAgICAgICAgICBpZiAoJHJvdyBpbnN0YW5jZW9mIFRhYmxlU2VwYXJhdG9yKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbHVtbnNbXSA9ICR0aGlzLT5nZXROdW1iZXJPZkNvbHVtbnMoJHJvdyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bnVtYmVyT2ZDb2x1bW5zID0gbWF4KCRjb2x1bW5zKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGJ1aWxkVGFibGVSb3dzKCRyb3dzKQogICAgewogICAgICAgICR1bm1lcmdlZFJvd3MgPSBbXTsKICAgICAgICBmb3IgKCRyb3dLZXkgPSAwOyAkcm93S2V5IDwgXGNvdW50KCRyb3dzKTsgKyskcm93S2V5KSB7CiAgICAgICAgICAgICRyb3dzID0gJHRoaXMtPmZpbGxOZXh0Um93cygkcm93cywgJHJvd0tleSk7CgogICAgICAgICAgICAvLyBSZW1vdmUgYW55IG5ldyBsaW5lIGJyZWFrcyBhbmQgcmVwbGFjZSBpdCB3aXRoIGEgbmV3IGxpbmUKICAgICAgICAgICAgZm9yZWFjaCAoJHJvd3NbJHJvd0tleV0gYXMgJGNvbHVtbiA9PiAkY2VsbCkgewogICAgICAgICAgICAgICAgaWYgKCFzdHJzdHIoJGNlbGwsICJcbiIpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbGluZXMgPSBleHBsb2RlKCJcbiIsIHN0cl9yZXBsYWNlKCJcbiIsICI8Zmc9ZGVmYXVsdDtiZz1kZWZhdWx0PlxuPC8+IiwgJGNlbGwpKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5lcyBhcyAkbGluZUtleSA9PiAkbGluZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkY2VsbCBpbnN0YW5jZW9mIFRhYmxlQ2VsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IG5ldyBUYWJsZUNlbGwoJGxpbmUsIFsnY29sc3BhbicgPT4gJGNlbGwtPmdldENvbHNwYW4oKV0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJGxpbmVLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJvd3NbJHJvd0tleV1bJGNvbHVtbl0gPSAkbGluZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdW5tZXJnZWRSb3dzWyRyb3dLZXldWyRsaW5lS2V5XVskY29sdW1uXSA9ICRsaW5lOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRhYmxlUm93cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRyb3dzIGFzICRyb3dLZXkgPT4gJHJvdykgewogICAgICAgICAgICAkdGFibGVSb3dzW10gPSAkdGhpcy0+ZmlsbENlbGxzKCRyb3cpOwogICAgICAgICAgICBpZiAoaXNzZXQoJHVubWVyZ2VkUm93c1skcm93S2V5XSkpIHsKICAgICAgICAgICAgICAgICR0YWJsZVJvd3MgPSBhcnJheV9tZXJnZSgkdGFibGVSb3dzLCAkdW5tZXJnZWRSb3dzWyRyb3dLZXldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0YWJsZVJvd3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBmaWxsIHJvd3MgdGhhdCBjb250YWlucyByb3dzcGFuID4gMS4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmlsbE5leHRSb3dzKGFycmF5ICRyb3dzLCAkbGluZSkKICAgIHsKICAgICAgICAkdW5tZXJnZWRSb3dzID0gW107CiAgICAgICAgZm9yZWFjaCAoJHJvd3NbJGxpbmVdIGFzICRjb2x1bW4gPT4gJGNlbGwpIHsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICRjZWxsICYmICEkY2VsbCBpbnN0YW5jZW9mIFRhYmxlQ2VsbCAmJiAhaXNfc2NhbGFyKCRjZWxsKSAmJiAhKFxpc19vYmplY3QoJGNlbGwpICYmIG1ldGhvZF9leGlzdHMoJGNlbGwsICdfX3RvU3RyaW5nJykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0EgY2VsbCBtdXN0IGJlIGEgVGFibGVDZWxsLCBhIHNjYWxhciBvciBhbiBvYmplY3QgaW1wbGVtZW50aW5nICJfX3RvU3RyaW5nKCkiLCAiJXMiIGdpdmVuLicsIFxnZXR0eXBlKCRjZWxsKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkY2VsbCBpbnN0YW5jZW9mIFRhYmxlQ2VsbCAmJiAkY2VsbC0+Z2V0Um93c3BhbigpID4gMSkgewogICAgICAgICAgICAgICAgJG5iTGluZXMgPSAkY2VsbC0+Z2V0Um93c3BhbigpIC0gMTsKICAgICAgICAgICAgICAgICRsaW5lcyA9IFskY2VsbF07CiAgICAgICAgICAgICAgICBpZiAoc3Ryc3RyKCRjZWxsLCAiXG4iKSkgewogICAgICAgICAgICAgICAgICAgICRsaW5lcyA9IGV4cGxvZGUoIlxuIiwgc3RyX3JlcGxhY2UoIlxuIiwgIjxmZz1kZWZhdWx0O2JnPWRlZmF1bHQ+XG48Lz4iLCAkY2VsbCkpOwogICAgICAgICAgICAgICAgICAgICRuYkxpbmVzID0gXGNvdW50KCRsaW5lcykgPiAkbmJMaW5lcyA/IHN1YnN0cl9jb3VudCgkY2VsbCwgIlxuIikgOiAkbmJMaW5lczsKCiAgICAgICAgICAgICAgICAgICAgJHJvd3NbJGxpbmVdWyRjb2x1bW5dID0gbmV3IFRhYmxlQ2VsbCgkbGluZXNbMF0sIFsnY29sc3BhbicgPT4gJGNlbGwtPmdldENvbHNwYW4oKV0pOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRsaW5lc1swXSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gY3JlYXRlIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IChyb3dzcGFuIHggY29sc3BhbikKICAgICAgICAgICAgICAgICR1bm1lcmdlZFJvd3MgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZShhcnJheV9maWxsKCRsaW5lICsgMSwgJG5iTGluZXMsIFtdKSwgJHVubWVyZ2VkUm93cyk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdW5tZXJnZWRSb3dzIGFzICR1bm1lcmdlZFJvd0tleSA9PiAkdW5tZXJnZWRSb3cpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBpc3NldCgkbGluZXNbJHVubWVyZ2VkUm93S2V5IC0gJGxpbmVdKSA/ICRsaW5lc1skdW5tZXJnZWRSb3dLZXkgLSAkbGluZV0gOiAnJzsKICAgICAgICAgICAgICAgICAgICAkdW5tZXJnZWRSb3dzWyR1bm1lcmdlZFJvd0tleV1bJGNvbHVtbl0gPSBuZXcgVGFibGVDZWxsKCR2YWx1ZSwgWydjb2xzcGFuJyA9PiAkY2VsbC0+Z2V0Q29sc3BhbigpXSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRuYkxpbmVzID09PSAkdW5tZXJnZWRSb3dLZXkgLSAkbGluZSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR1bm1lcmdlZFJvd3MgYXMgJHVubWVyZ2VkUm93S2V5ID0+ICR1bm1lcmdlZFJvdykgewogICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGtub3cgaWYgJHVubWVyZ2VkUm93IHdpbGwgYmUgbWVyZ2VkIG9yIGluc2VydGVkIGludG8gJHJvd3MKICAgICAgICAgICAgaWYgKGlzc2V0KCRyb3dzWyR1bm1lcmdlZFJvd0tleV0pICYmIFxpc19hcnJheSgkcm93c1skdW5tZXJnZWRSb3dLZXldKSAmJiAoJHRoaXMtPmdldE51bWJlck9mQ29sdW1ucygkcm93c1skdW5tZXJnZWRSb3dLZXldKSArICR0aGlzLT5nZXROdW1iZXJPZkNvbHVtbnMoJHVubWVyZ2VkUm93c1skdW5tZXJnZWRSb3dLZXldKSA8PSAkdGhpcy0+bnVtYmVyT2ZDb2x1bW5zKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVubWVyZ2VkUm93IGFzICRjZWxsS2V5ID0+ICRjZWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gaW5zZXJ0IGNlbGwgaW50byByb3cgYXQgY2VsbEtleSBwb3NpdGlvbgogICAgICAgICAgICAgICAgICAgIGFycmF5X3NwbGljZSgkcm93c1skdW5tZXJnZWRSb3dLZXldLCAkY2VsbEtleSwgMCwgWyRjZWxsXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcm93ID0gJHRoaXMtPmNvcHlSb3coJHJvd3MsICR1bm1lcmdlZFJvd0tleSAtIDEpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVubWVyZ2VkUm93IGFzICRjb2x1bW4gPT4gJGNlbGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRjZWxsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcm93WyRjb2x1bW5dID0gJHVubWVyZ2VkUm93WyRjb2x1bW5dOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFycmF5X3NwbGljZSgkcm93cywgJHVubWVyZ2VkUm93S2V5LCAwLCBbJHJvd10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJvd3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBmaWxsIGNlbGxzIGZvciBhIHJvdyB0aGF0IGNvbnRhaW5zIGNvbHNwYW4gPiAxLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaWxsQ2VsbHMoJHJvdykKICAgIHsKICAgICAgICAkbmV3Um93ID0gW107CiAgICAgICAgZm9yZWFjaCAoJHJvdyBhcyAkY29sdW1uID0+ICRjZWxsKSB7CiAgICAgICAgICAgICRuZXdSb3dbXSA9ICRjZWxsOwogICAgICAgICAgICBpZiAoJGNlbGwgaW5zdGFuY2VvZiBUYWJsZUNlbGwgJiYgJGNlbGwtPmdldENvbHNwYW4oKSA+IDEpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHJhbmdlKCRjb2x1bW4gKyAxLCAkY29sdW1uICsgJGNlbGwtPmdldENvbHNwYW4oKSAtIDEpIGFzICRwb3NpdGlvbikgewogICAgICAgICAgICAgICAgICAgIC8vIGluc2VydCBlbXB0eSB2YWx1ZSBhdCBjb2x1bW4gcG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAkbmV3Um93W10gPSAnJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRuZXdSb3cgPzogJHJvdzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJGxpbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY29weVJvdyhhcnJheSAkcm93cywgJGxpbmUpCiAgICB7CiAgICAgICAgJHJvdyA9ICRyb3dzWyRsaW5lXTsKICAgICAgICBmb3JlYWNoICgkcm93IGFzICRjZWxsS2V5ID0+ICRjZWxsVmFsdWUpIHsKICAgICAgICAgICAgJHJvd1skY2VsbEtleV0gPSAnJzsKICAgICAgICAgICAgaWYgKCRjZWxsVmFsdWUgaW5zdGFuY2VvZiBUYWJsZUNlbGwpIHsKICAgICAgICAgICAgICAgICRyb3dbJGNlbGxLZXldID0gbmV3IFRhYmxlQ2VsbCgnJywgWydjb2xzcGFuJyA9PiAkY2VsbFZhbHVlLT5nZXRDb2xzcGFuKCldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyb3c7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIG51bWJlciBvZiBjb2x1bW5zIGJ5IHJvdy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldE51bWJlck9mQ29sdW1ucyhhcnJheSAkcm93KQogICAgewogICAgICAgICRjb2x1bW5zID0gXGNvdW50KCRyb3cpOwogICAgICAgIGZvcmVhY2ggKCRyb3cgYXMgJGNvbHVtbikgewogICAgICAgICAgICAkY29sdW1ucyArPSAkY29sdW1uIGluc3RhbmNlb2YgVGFibGVDZWxsID8gKCRjb2x1bW4tPmdldENvbHNwYW4oKSAtIDEpIDogMDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29sdW1uczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgbGlzdCBvZiBjb2x1bW5zIGZvciB0aGUgZ2l2ZW4gcm93LgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRSb3dDb2x1bW5zKGFycmF5ICRyb3cpCiAgICB7CiAgICAgICAgJGNvbHVtbnMgPSByYW5nZSgwLCAkdGhpcy0+bnVtYmVyT2ZDb2x1bW5zIC0gMSk7CiAgICAgICAgZm9yZWFjaCAoJHJvdyBhcyAkY2VsbEtleSA9PiAkY2VsbCkgewogICAgICAgICAgICBpZiAoJGNlbGwgaW5zdGFuY2VvZiBUYWJsZUNlbGwgJiYgJGNlbGwtPmdldENvbHNwYW4oKSA+IDEpIHsKICAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGUgZ3JvdXBlZCBjb2x1bW5zLgogICAgICAgICAgICAgICAgJGNvbHVtbnMgPSBhcnJheV9kaWZmKCRjb2x1bW5zLCByYW5nZSgkY2VsbEtleSArIDEsICRjZWxsS2V5ICsgJGNlbGwtPmdldENvbHNwYW4oKSAtIDEpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb2x1bW5zOwogICAgfQoKICAgIC8qKgogICAgICogQ2FsY3VsYXRlcyBjb2x1bW5zIHdpZHRocy4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYWxjdWxhdGVDb2x1bW5zV2lkdGgoYXJyYXkgJHJvd3MpCiAgICB7CiAgICAgICAgZm9yICgkY29sdW1uID0gMDsgJGNvbHVtbiA8ICR0aGlzLT5udW1iZXJPZkNvbHVtbnM7ICsrJGNvbHVtbikgewogICAgICAgICAgICAkbGVuZ3RocyA9IFtdOwogICAgICAgICAgICBmb3JlYWNoICgkcm93cyBhcyAkcm93KSB7CiAgICAgICAgICAgICAgICBpZiAoJHJvdyBpbnN0YW5jZW9mIFRhYmxlU2VwYXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHJvdyBhcyAkaSA9PiAkY2VsbCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkY2VsbCBpbnN0YW5jZW9mIFRhYmxlQ2VsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dENvbnRlbnQgPSBIZWxwZXI6OnJlbW92ZURlY29yYXRpb24oJHRoaXMtPm91dHB1dC0+Z2V0Rm9ybWF0dGVyKCksICRjZWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHRMZW5ndGggPSBIZWxwZXI6OnN0cmxlbigkdGV4dENvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRleHRMZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudENvbHVtbnMgPSBzdHJfc3BsaXQoJHRleHRDb250ZW50LCBjZWlsKCR0ZXh0TGVuZ3RoIC8gJGNlbGwtPmdldENvbHNwYW4oKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnRlbnRDb2x1bW5zIGFzICRwb3NpdGlvbiA9PiAkY29udGVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyb3dbJGkgKyAkcG9zaXRpb25dID0gJGNvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGxlbmd0aHNbXSA9ICR0aGlzLT5nZXRDZWxsV2lkdGgoJHJvdywgJGNvbHVtbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5lZmZlY3RpdmVDb2x1bW5XaWR0aHNbJGNvbHVtbl0gPSBtYXgoJGxlbmd0aHMpICsgSGVscGVyOjpzdHJsZW4oJHRoaXMtPnN0eWxlLT5nZXRDZWxsUm93Q29udGVudEZvcm1hdCgpKSAtIDI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBjb2x1bW4gd2lkdGguCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb2x1bW5TZXBhcmF0b3JXaWR0aCgpCiAgICB7CiAgICAgICAgcmV0dXJuIEhlbHBlcjo6c3RybGVuKHNwcmludGYoJHRoaXMtPnN0eWxlLT5nZXRCb3JkZXJGb3JtYXQoKSwgJHRoaXMtPnN0eWxlLT5nZXRWZXJ0aWNhbEJvcmRlckNoYXIoKSkpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBjZWxsIHdpZHRoLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGNvbHVtbgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q2VsbFdpZHRoKGFycmF5ICRyb3csICRjb2x1bW4pCiAgICB7CiAgICAgICAgJGNlbGxXaWR0aCA9IDA7CgogICAgICAgIGlmIChpc3NldCgkcm93WyRjb2x1bW5dKSkgewogICAgICAgICAgICAkY2VsbCA9ICRyb3dbJGNvbHVtbl07CiAgICAgICAgICAgICRjZWxsV2lkdGggPSBIZWxwZXI6OnN0cmxlbldpdGhvdXREZWNvcmF0aW9uKCR0aGlzLT5vdXRwdXQtPmdldEZvcm1hdHRlcigpLCAkY2VsbCk7CiAgICAgICAgfQoKICAgICAgICAkY29sdW1uV2lkdGggPSBpc3NldCgkdGhpcy0+Y29sdW1uV2lkdGhzWyRjb2x1bW5dKSA/ICR0aGlzLT5jb2x1bW5XaWR0aHNbJGNvbHVtbl0gOiAwOwoKICAgICAgICByZXR1cm4gbWF4KCRjZWxsV2lkdGgsICRjb2x1bW5XaWR0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxsZWQgYWZ0ZXIgcmVuZGVyaW5nIHRvIGNsZWFudXAgY2FjaGUgZGF0YS4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjbGVhbnVwKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZWZmZWN0aXZlQ29sdW1uV2lkdGhzID0gW107CiAgICAgICAgJHRoaXMtPm51bWJlck9mQ29sdW1ucyA9IG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5pdFN0eWxlcygpCiAgICB7CiAgICAgICAgJGJvcmRlcmxlc3MgPSBuZXcgVGFibGVTdHlsZSgpOwogICAgICAgICRib3JkZXJsZXNzCiAgICAgICAgICAgIC0+c2V0SG9yaXpvbnRhbEJvcmRlckNoYXIoJz0nKQogICAgICAgICAgICAtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcignICcpCiAgICAgICAgICAgIC0+c2V0Q3Jvc3NpbmdDaGFyKCcgJykKICAgICAgICA7CgogICAgICAgICRjb21wYWN0ID0gbmV3IFRhYmxlU3R5bGUoKTsKICAgICAgICAkY29tcGFjdAogICAgICAgICAgICAtPnNldEhvcml6b250YWxCb3JkZXJDaGFyKCcnKQogICAgICAgICAgICAtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcignICcpCiAgICAgICAgICAgIC0+c2V0Q3Jvc3NpbmdDaGFyKCcnKQogICAgICAgICAgICAtPnNldENlbGxSb3dDb250ZW50Rm9ybWF0KCclcycpCiAgICAgICAgOwoKICAgICAgICAkc3R5bGVHdWlkZSA9IG5ldyBUYWJsZVN0eWxlKCk7CiAgICAgICAgJHN0eWxlR3VpZGUKICAgICAgICAgICAgLT5zZXRIb3Jpem9udGFsQm9yZGVyQ2hhcignLScpCiAgICAgICAgICAgIC0+c2V0VmVydGljYWxCb3JkZXJDaGFyKCcgJykKICAgICAgICAgICAgLT5zZXRDcm9zc2luZ0NoYXIoJyAnKQogICAgICAgICAgICAtPnNldENlbGxIZWFkZXJGb3JtYXQoJyVzJykKICAgICAgICA7CgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICdkZWZhdWx0JyA9PiBuZXcgVGFibGVTdHlsZSgpLAogICAgICAgICAgICAnYm9yZGVybGVzcycgPT4gJGJvcmRlcmxlc3MsCiAgICAgICAgICAgICdjb21wYWN0JyA9PiAkY29tcGFjdCwKICAgICAgICAgICAgJ3N5bWZvbnktc3R5bGUtZ3VpZGUnID0+ICRzdHlsZUd1aWRlLAogICAgICAgIF07CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXNvbHZlU3R5bGUoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCRuYW1lIGluc3RhbmNlb2YgVGFibGVTdHlsZSkgewogICAgICAgICAgICByZXR1cm4gJG5hbWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoc2VsZjo6JHN0eWxlc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokc3R5bGVzWyRuYW1lXTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignU3R5bGUgIiVzIiBpcyBub3QgZGVmaW5lZC4nLCAkbmFtZSkpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEF3YXJlSW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKCi8qKgogKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBJbnB1dEF3YXJlSW50ZXJmYWNlIGZvciBIZWxwZXJzLgogKgogKiBAYXV0aG9yIFdvdXRlciBKIDx3YWxkaW8ud2ViZGVzaWduQGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIElucHV0QXdhcmVIZWxwZXIgZXh0ZW5kcyBIZWxwZXIgaW1wbGVtZW50cyBJbnB1dEF3YXJlSW50ZXJmYWNlCnsKICAgIHByb3RlY3RlZCAkaW5wdXQ7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnB1dChJbnB1dEludGVyZmFjZSAkaW5wdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7CgovKioKICogTWFya3MgYSByb3cgYXMgYmVpbmcgYSBzZXBhcmF0b3IuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgVGFibGVTZXBhcmF0b3IgZXh0ZW5kcyBUYWJsZUNlbGwKewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgnJywgJG9wdGlvbnMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBLZXZpbiBCb25kIDxrZXZpbmJvbmRAZ21haWwuY29tPgogKi8KY2xhc3MgUHJvZ3Jlc3NJbmRpY2F0b3IKewogICAgcHJpdmF0ZSAkb3V0cHV0OwogICAgcHJpdmF0ZSAkc3RhcnRUaW1lOwogICAgcHJpdmF0ZSAkZm9ybWF0OwogICAgcHJpdmF0ZSAkbWVzc2FnZTsKICAgIHByaXZhdGUgJGluZGljYXRvclZhbHVlczsKICAgIHByaXZhdGUgJGluZGljYXRvckN1cnJlbnQ7CiAgICBwcml2YXRlICRpbmRpY2F0b3JDaGFuZ2VJbnRlcnZhbDsKICAgIHByaXZhdGUgJGluZGljYXRvclVwZGF0ZVRpbWU7CiAgICBwcml2YXRlICRzdGFydGVkID0gZmFsc2U7CgogICAgcHJpdmF0ZSBzdGF0aWMgJGZvcm1hdHRlcnM7CiAgICBwcml2YXRlIHN0YXRpYyAkZm9ybWF0czsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZm9ybWF0ICAgICAgICAgICAgICAgICAgSW5kaWNhdG9yIGZvcm1hdAogICAgICogQHBhcmFtIGludCAgICAgICAgICRpbmRpY2F0b3JDaGFuZ2VJbnRlcnZhbCBDaGFuZ2UgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAgJGluZGljYXRvclZhbHVlcyAgICAgICAgIEFuaW1hdGVkIGluZGljYXRvciBjaGFyYWN0ZXJzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJGZvcm1hdCA9IG51bGwsICRpbmRpY2F0b3JDaGFuZ2VJbnRlcnZhbCA9IDEwMCwgJGluZGljYXRvclZhbHVlcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dCA9ICRvdXRwdXQ7CgogICAgICAgIGlmIChudWxsID09PSAkZm9ybWF0KSB7CiAgICAgICAgICAgICRmb3JtYXQgPSAkdGhpcy0+ZGV0ZXJtaW5lQmVzdEZvcm1hdCgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRpbmRpY2F0b3JWYWx1ZXMpIHsKICAgICAgICAgICAgJGluZGljYXRvclZhbHVlcyA9IFsnLScsICdcXCcsICd8JywgJy8nXTsKICAgICAgICB9CgogICAgICAgICRpbmRpY2F0b3JWYWx1ZXMgPSBhcnJheV92YWx1ZXMoJGluZGljYXRvclZhbHVlcyk7CgogICAgICAgIGlmICgyID4gXGNvdW50KCRpbmRpY2F0b3JWYWx1ZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ011c3QgaGF2ZSBhdCBsZWFzdCAyIGluZGljYXRvciB2YWx1ZSBjaGFyYWN0ZXJzLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZvcm1hdCA9IHNlbGY6OmdldEZvcm1hdERlZmluaXRpb24oJGZvcm1hdCk7CiAgICAgICAgJHRoaXMtPmluZGljYXRvckNoYW5nZUludGVydmFsID0gJGluZGljYXRvckNoYW5nZUludGVydmFsOwogICAgICAgICR0aGlzLT5pbmRpY2F0b3JWYWx1ZXMgPSAkaW5kaWNhdG9yVmFsdWVzOwogICAgICAgICR0aGlzLT5zdGFydFRpbWUgPSB0aW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IGluZGljYXRvciBtZXNzYWdlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TWVzc2FnZSgkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWVzc2FnZSA9ICRtZXNzYWdlOwoKICAgICAgICAkdGhpcy0+ZGlzcGxheSgpOwogICAgfQoKICAgIC8qKgogICAgICogU3RhcnRzIHRoZSBpbmRpY2F0b3Igb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RhcnQoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zdGFydGVkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignUHJvZ3Jlc3MgaW5kaWNhdG9yIGFscmVhZHkgc3RhcnRlZC4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5tZXNzYWdlID0gJG1lc3NhZ2U7CiAgICAgICAgJHRoaXMtPnN0YXJ0ZWQgPSB0cnVlOwogICAgICAgICR0aGlzLT5zdGFydFRpbWUgPSB0aW1lKCk7CiAgICAgICAgJHRoaXMtPmluZGljYXRvclVwZGF0ZVRpbWUgPSAkdGhpcy0+Z2V0Q3VycmVudFRpbWVJbk1pbGxpc2Vjb25kcygpICsgJHRoaXMtPmluZGljYXRvckNoYW5nZUludGVydmFsOwogICAgICAgICR0aGlzLT5pbmRpY2F0b3JDdXJyZW50ID0gMDsKCiAgICAgICAgJHRoaXMtPmRpc3BsYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkdmFuY2VzIHRoZSBpbmRpY2F0b3IuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZHZhbmNlKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5zdGFydGVkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignUHJvZ3Jlc3MgaW5kaWNhdG9yIGhhcyBub3QgeWV0IGJlZW4gc3RhcnRlZC4nKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPm91dHB1dC0+aXNEZWNvcmF0ZWQoKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkY3VycmVudFRpbWUgPSAkdGhpcy0+Z2V0Q3VycmVudFRpbWVJbk1pbGxpc2Vjb25kcygpOwoKICAgICAgICBpZiAoJGN1cnJlbnRUaW1lIDwgJHRoaXMtPmluZGljYXRvclVwZGF0ZVRpbWUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmluZGljYXRvclVwZGF0ZVRpbWUgPSAkY3VycmVudFRpbWUgKyAkdGhpcy0+aW5kaWNhdG9yQ2hhbmdlSW50ZXJ2YWw7CiAgICAgICAgKyskdGhpcy0+aW5kaWNhdG9yQ3VycmVudDsKCiAgICAgICAgJHRoaXMtPmRpc3BsYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmlzaCB0aGUgaW5kaWNhdG9yIHdpdGggbWVzc2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmlzaCgkbWVzc2FnZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5zdGFydGVkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignUHJvZ3Jlc3MgaW5kaWNhdG9yIGhhcyBub3QgeWV0IGJlZW4gc3RhcnRlZC4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5tZXNzYWdlID0gJG1lc3NhZ2U7CiAgICAgICAgJHRoaXMtPmRpc3BsYXkoKTsKICAgICAgICAkdGhpcy0+b3V0cHV0LT53cml0ZWxuKCcnKTsKICAgICAgICAkdGhpcy0+c3RhcnRlZCA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZm9ybWF0IGZvciBhIGdpdmVuIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgZm9ybWF0IG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIEEgZm9ybWF0IHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEZvcm1hdERlZmluaXRpb24oJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokZm9ybWF0cykgewogICAgICAgICAgICBzZWxmOjokZm9ybWF0cyA9IHNlbGY6OmluaXRGb3JtYXRzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoc2VsZjo6JGZvcm1hdHNbJG5hbWVdKSA/IHNlbGY6OiRmb3JtYXRzWyRuYW1lXSA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGEgcGxhY2Vob2xkZXIgZm9ybWF0dGVyIGZvciBhIGdpdmVuIG5hbWUuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgYWxzbyBhbGxvdyB5b3UgdG8gb3ZlcnJpZGUgYW4gZXhpc3RpbmcgcGxhY2Vob2xkZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRuYW1lICAgICBUaGUgcGxhY2Vob2xkZXIgbmFtZSAoaW5jbHVkaW5nIHRoZSBkZWxpbWl0ZXIgY2hhciBsaWtlICUpCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGNhbGxhYmxlIEEgUEhQIGNhbGxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0UGxhY2Vob2xkZXJGb3JtYXR0ZXJEZWZpbml0aW9uKCRuYW1lLCAkY2FsbGFibGUpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokZm9ybWF0dGVycykgewogICAgICAgICAgICBzZWxmOjokZm9ybWF0dGVycyA9IHNlbGY6OmluaXRQbGFjZWhvbGRlckZvcm1hdHRlcnMoKTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRmb3JtYXR0ZXJzWyRuYW1lXSA9ICRjYWxsYWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHBsYWNlaG9sZGVyIGZvcm1hdHRlciBmb3IgYSBnaXZlbiBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHBsYWNlaG9sZGVyIG5hbWUgKGluY2x1ZGluZyB0aGUgZGVsaW1pdGVyIGNoYXIgbGlrZSAlKQogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGV8bnVsbCBBIFBIUCBjYWxsYWJsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBsYWNlaG9sZGVyRm9ybWF0dGVyRGVmaW5pdGlvbigkbmFtZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRmb3JtYXR0ZXJzKSB7CiAgICAgICAgICAgIHNlbGY6OiRmb3JtYXR0ZXJzID0gc2VsZjo6aW5pdFBsYWNlaG9sZGVyRm9ybWF0dGVycygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzc2V0KHNlbGY6OiRmb3JtYXR0ZXJzWyRuYW1lXSkgPyBzZWxmOjokZm9ybWF0dGVyc1skbmFtZV0gOiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZGlzcGxheSgpCiAgICB7CiAgICAgICAgaWYgKE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1FVSUVUID09PSAkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkc2VsZiA9ICR0aGlzOwoKICAgICAgICAkdGhpcy0+b3ZlcndyaXRlKHByZWdfcmVwbGFjZV9jYWxsYmFjaygieyUoW2EtelwtX10rKSg/Olw6KFteJV0rKSk/JX1pIiwgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCRzZWxmKSB7CiAgICAgICAgICAgIGlmICgkZm9ybWF0dGVyID0gJHNlbGY6OmdldFBsYWNlaG9sZGVyRm9ybWF0dGVyRGVmaW5pdGlvbigkbWF0Y2hlc1sxXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBcY2FsbF91c2VyX2Z1bmMoJGZvcm1hdHRlciwgJHNlbGYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbMF07CiAgICAgICAgfSwgJHRoaXMtPmZvcm1hdCkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZGV0ZXJtaW5lQmVzdEZvcm1hdCgpCiAgICB7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSkgewogICAgICAgICAgICAvLyBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVDogZGlzcGxheSBpcyBkaXNhYmxlZCBhbnl3YXkKICAgICAgICAgICAgY2FzZSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCkgPyAndmVyYm9zZScgOiAndmVyYm9zZV9ub19hbnNpJzsKICAgICAgICAgICAgY2FzZSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJZX1ZFUkJPU0U6CiAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfREVCVUc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPm91dHB1dC0+aXNEZWNvcmF0ZWQoKSA/ICd2ZXJ5X3ZlcmJvc2UnIDogJ3ZlcnlfdmVyYm9zZV9ub19hbnNpJzsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5pc0RlY29yYXRlZCgpID8gJ25vcm1hbCcgOiAnbm9ybWFsX25vX2Fuc2knOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE92ZXJ3cml0ZXMgYSBwcmV2aW91cyBtZXNzYWdlIHRvIHRoZSBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbWVzc2FnZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG92ZXJ3cml0ZSgkbWVzc2FnZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPm91dHB1dC0+aXNEZWNvcmF0ZWQoKSkgewogICAgICAgICAgICAkdGhpcy0+b3V0cHV0LT53cml0ZSgiXHgwRFx4MUJbMksiKTsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGUoJG1lc3NhZ2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQtPndyaXRlbG4oJG1lc3NhZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEN1cnJlbnRUaW1lSW5NaWxsaXNlY29uZHMoKQogICAgewogICAgICAgIHJldHVybiByb3VuZChtaWNyb3RpbWUodHJ1ZSkgKiAxMDAwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpbml0UGxhY2Vob2xkZXJGb3JtYXR0ZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAnaW5kaWNhdG9yJyA9PiBmdW5jdGlvbiAoc2VsZiAkaW5kaWNhdG9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGluZGljYXRvci0+aW5kaWNhdG9yVmFsdWVzWyRpbmRpY2F0b3ItPmluZGljYXRvckN1cnJlbnQgJSBcY291bnQoJGluZGljYXRvci0+aW5kaWNhdG9yVmFsdWVzKV07CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdtZXNzYWdlJyA9PiBmdW5jdGlvbiAoc2VsZiAkaW5kaWNhdG9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGluZGljYXRvci0+bWVzc2FnZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ2VsYXBzZWQnID0+IGZ1bmN0aW9uIChzZWxmICRpbmRpY2F0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBIZWxwZXI6OmZvcm1hdFRpbWUodGltZSgpIC0gJGluZGljYXRvci0+c3RhcnRUaW1lKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ21lbW9yeScgPT4gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEhlbHBlcjo6Zm9ybWF0TWVtb3J5KG1lbW9yeV9nZXRfdXNhZ2UodHJ1ZSkpOwogICAgICAgICAgICB9LAogICAgICAgIF07CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5pdEZvcm1hdHMoKQogICAgewogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICdub3JtYWwnID0+ICcgJWluZGljYXRvciUgJW1lc3NhZ2UlJywKICAgICAgICAgICAgJ25vcm1hbF9ub19hbnNpJyA9PiAnICVtZXNzYWdlJScsCgogICAgICAgICAgICAndmVyYm9zZScgPT4gJyAlaW5kaWNhdG9yJSAlbWVzc2FnZSUgKCVlbGFwc2VkOjZzJSknLAogICAgICAgICAgICAndmVyYm9zZV9ub19hbnNpJyA9PiAnICVtZXNzYWdlJSAoJWVsYXBzZWQ6NnMlKScsCgogICAgICAgICAgICAndmVyeV92ZXJib3NlJyA9PiAnICVpbmRpY2F0b3IlICVtZXNzYWdlJSAoJWVsYXBzZWQ6NnMlLCAlbWVtb3J5OjZzJSknLAogICAgICAgICAgICAndmVyeV92ZXJib3NlX25vX2Fuc2knID0+ICcgJW1lc3NhZ2UlICglZWxhcHNlZDo2cyUsICVtZW1vcnk6NnMlKScsCiAgICAgICAgXTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEFiZGVsbGF0aWYgQWl0IGJvdWRhZCA8YS5haXRib3VkYWRAZ21haWwuY29tPgogKi8KY2xhc3MgVGFibGVDZWxsCnsKICAgIHByaXZhdGUgJHZhbHVlOwogICAgcHJpdmF0ZSAkb3B0aW9ucyA9IFsKICAgICAgICAncm93c3BhbicgPT4gMSwKICAgICAgICAnY29sc3BhbicgPT4gMSwKICAgIF07CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHZhbHVlID0gJycsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSAmJiAhXGlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgICAgICR2YWx1ZSA9IChzdHJpbmcpICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKCiAgICAgICAgLy8gY2hlY2sgb3B0aW9uIG5hbWVzCiAgICAgICAgaWYgKCRkaWZmID0gYXJyYXlfZGlmZihhcnJheV9rZXlzKCRvcHRpb25zKSwgYXJyYXlfa2V5cygkdGhpcy0+b3B0aW9ucykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIFRhYmxlQ2VsbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBmb2xsb3dpbmcgb3B0aW9uczogXCclc1wnLicsIGltcGxvZGUoJ1wnLCBcJycsICRkaWZmKSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBhcnJheV9tZXJnZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2VsbCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgbnVtYmVyIG9mIGNvbHNwYW4uCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbHNwYW4oKQogICAgewogICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+b3B0aW9uc1snY29sc3BhbiddOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBudW1iZXIgb2Ygcm93c3Bhbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um93c3BhbigpCiAgICB7CiAgICAgICAgcmV0dXJuIChpbnQpICR0aGlzLT5vcHRpb25zWydyb3dzcGFuJ107CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CgovKioKICogVGhlIEZvcm1hdHRlciBjbGFzcyBwcm92aWRlcyBoZWxwZXJzIHRvIGZvcm1hdCBtZXNzYWdlcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBGb3JtYXR0ZXJIZWxwZXIgZXh0ZW5kcyBIZWxwZXIKewogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgbWVzc2FnZSB3aXRoaW4gYSBzZWN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNlY3Rpb24gVGhlIHNlY3Rpb24gbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbWVzc2FnZQogICAgICogQHBhcmFtIHN0cmluZyAkc3R5bGUgICBUaGUgc3R5bGUgdG8gYXBwbHkgdG8gdGhlIHNlY3Rpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZm9ybWF0IHNlY3Rpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZvcm1hdFNlY3Rpb24oJHNlY3Rpb24sICRtZXNzYWdlLCAkc3R5bGUgPSAnaW5mbycpCiAgICB7CiAgICAgICAgcmV0dXJuIHNwcmludGYoJzwlcz5bJXNdPC8lcz4gJXMnLCAkc3R5bGUsICRzZWN0aW9uLCAkc3R5bGUsICRtZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIGFzIGEgYmxvY2sgb2YgdGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlcyBUaGUgbWVzc2FnZSB0byB3cml0ZSBpbiB0aGUgYmxvY2sKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHN0eWxlICAgIFRoZSBzdHlsZSB0byBhcHBseSB0byB0aGUgd2hvbGUgYmxvY2sKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJGxhcmdlICAgIFdoZXRoZXIgdG8gcmV0dXJuIGEgbGFyZ2UgYmxvY2sKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZm9ybWF0dGVyIG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZvcm1hdEJsb2NrKCRtZXNzYWdlcywgJHN0eWxlLCAkbGFyZ2UgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIVxpc19hcnJheSgkbWVzc2FnZXMpKSB7CiAgICAgICAgICAgICRtZXNzYWdlcyA9IFskbWVzc2FnZXNdOwogICAgICAgIH0KCiAgICAgICAgJGxlbiA9IDA7CiAgICAgICAgJGxpbmVzID0gW107CiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzIGFzICRtZXNzYWdlKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoJG1lc3NhZ2UpOwogICAgICAgICAgICAkbGluZXNbXSA9IHNwcmludGYoJGxhcmdlID8gJyAgJXMgICcgOiAnICVzICcsICRtZXNzYWdlKTsKICAgICAgICAgICAgJGxlbiA9IG1heChzZWxmOjpzdHJsZW4oJG1lc3NhZ2UpICsgKCRsYXJnZSA/IDQgOiAyKSwgJGxlbik7CiAgICAgICAgfQoKICAgICAgICAkbWVzc2FnZXMgPSAkbGFyZ2UgPyBbc3RyX3JlcGVhdCgnICcsICRsZW4pXSA6IFtdOwogICAgICAgIGZvciAoJGkgPSAwOyBpc3NldCgkbGluZXNbJGldKTsgKyskaSkgewogICAgICAgICAgICAkbWVzc2FnZXNbXSA9ICRsaW5lc1skaV0uc3RyX3JlcGVhdCgnICcsICRsZW4gLSBzZWxmOjpzdHJsZW4oJGxpbmVzWyRpXSkpOwogICAgICAgIH0KICAgICAgICBpZiAoJGxhcmdlKSB7CiAgICAgICAgICAgICRtZXNzYWdlc1tdID0gc3RyX3JlcGVhdCgnICcsICRsZW4pOwogICAgICAgIH0KCiAgICAgICAgZm9yICgkaSA9IDA7IGlzc2V0KCRtZXNzYWdlc1skaV0pOyArKyRpKSB7CiAgICAgICAgICAgICRtZXNzYWdlc1skaV0gPSBzcHJpbnRmKCc8JXM+JXM8LyVzPicsICRzdHlsZSwgJG1lc3NhZ2VzWyRpXSwgJHN0eWxlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpbXBsb2RlKCJcbiIsICRtZXNzYWdlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUcnVuY2F0ZXMgYSBtZXNzYWdlIHRvIHRoZSBnaXZlbiBsZW5ndGguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGludCAgICAkbGVuZ3RoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdWZmaXgKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdHJ1bmNhdGUoJG1lc3NhZ2UsICRsZW5ndGgsICRzdWZmaXggPSAnLi4uJykKICAgIHsKICAgICAgICAkY29tcHV0ZWRMZW5ndGggPSAkbGVuZ3RoIC0gc2VsZjo6c3RybGVuKCRzdWZmaXgpOwoKICAgICAgICBpZiAoJGNvbXB1dGVkTGVuZ3RoID4gc2VsZjo6c3RybGVuKCRtZXNzYWdlKSkgewogICAgICAgICAgICByZXR1cm4gJG1lc3NhZ2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6c3Vic3RyKCRtZXNzYWdlLCAwLCAkbGVuZ3RoKS4kc3VmZml4OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdmb3JtYXR0ZXInOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogSGVscGVyU2V0IHJlcHJlc2VudHMgYSBzZXQgb2YgaGVscGVycyB0byBiZSB1c2VkIHdpdGggYSBjb21tYW5kLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEhlbHBlclNldCBpbXBsZW1lbnRzIFxJdGVyYXRvckFnZ3JlZ2F0ZQp7CiAgICAvKioKICAgICAqIEB2YXIgSGVscGVyW10KICAgICAqLwogICAgcHJpdmF0ZSAkaGVscGVycyA9IFtdOwogICAgcHJpdmF0ZSAkY29tbWFuZDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBIZWxwZXJbXSAkaGVscGVycyBBbiBhcnJheSBvZiBoZWxwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRoZWxwZXJzID0gW10pCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGhlbHBlcnMgYXMgJGFsaWFzID0+ICRoZWxwZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnNldCgkaGVscGVyLCBcaXNfaW50KCRhbGlhcykgPyBudWxsIDogJGFsaWFzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGEgaGVscGVyLgogICAgICoKICAgICAqIEBwYXJhbSBIZWxwZXJJbnRlcmZhY2UgJGhlbHBlciBUaGUgaGVscGVyIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRhbGlhcyAgQW4gYWxpYXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldChIZWxwZXJJbnRlcmZhY2UgJGhlbHBlciwgJGFsaWFzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVscGVyc1skaGVscGVyLT5nZXROYW1lKCldID0gJGhlbHBlcjsKICAgICAgICBpZiAobnVsbCAhPT0gJGFsaWFzKSB7CiAgICAgICAgICAgICR0aGlzLT5oZWxwZXJzWyRhbGlhc10gPSAkaGVscGVyOwogICAgICAgIH0KCiAgICAgICAgJGhlbHBlci0+c2V0SGVscGVyU2V0KCR0aGlzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgaGVscGVyIGlmIGRlZmluZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgaGVscGVyIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgaGVscGVyIGlzIGRlZmluZWQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+aGVscGVyc1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhIGhlbHBlciB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBoZWxwZXIgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gSGVscGVySW50ZXJmYWNlIFRoZSBoZWxwZXIgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaGVscGVyIGlzIG5vdCBkZWZpbmVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzKCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSBoZWxwZXIgIiVzIiBpcyBub3QgZGVmaW5lZC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5oZWxwZXJzWyRuYW1lXTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tbWFuZChDb21tYW5kICRjb21tYW5kID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWFuZCA9ICRjb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY29tbWFuZCBhc3NvY2lhdGVkIHdpdGggdGhpcyBoZWxwZXIgc2V0LgogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZCBBIENvbW1hbmQgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbW1hbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWFuZDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gSGVscGVyW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFxBcnJheUl0ZXJhdG9yKCR0aGlzLT5oZWxwZXJzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvclxEZXNjcmlwdG9ySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yXEpzb25EZXNjcmlwdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yXE1hcmtkb3duRGVzY3JpcHRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvclxUZXh0RGVzY3JpcHRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvclxYbWxEZXNjcmlwdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIFRoaXMgY2xhc3MgYWRkcyBoZWxwZXIgbWV0aG9kIHRvIGRlc2NyaWJlIG9iamVjdHMgaW4gdmFyaW91cyBmb3JtYXRzLgogKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqLwpjbGFzcyBEZXNjcmlwdG9ySGVscGVyIGV4dGVuZHMgSGVscGVyCnsKICAgIC8qKgogICAgICogQHZhciBEZXNjcmlwdG9ySW50ZXJmYWNlW10KICAgICAqLwogICAgcHJpdmF0ZSAkZGVzY3JpcHRvcnMgPSBbXTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+cmVnaXN0ZXIoJ3R4dCcsIG5ldyBUZXh0RGVzY3JpcHRvcigpKQogICAgICAgICAgICAtPnJlZ2lzdGVyKCd4bWwnLCBuZXcgWG1sRGVzY3JpcHRvcigpKQogICAgICAgICAgICAtPnJlZ2lzdGVyKCdqc29uJywgbmV3IEpzb25EZXNjcmlwdG9yKCkpCiAgICAgICAgICAgIC0+cmVnaXN0ZXIoJ21kJywgbmV3IE1hcmtkb3duRGVzY3JpcHRvcigpKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBvYmplY3QgaWYgc3VwcG9ydGVkLgogICAgICoKICAgICAqIEF2YWlsYWJsZSBvcHRpb25zIGFyZToKICAgICAqICogZm9ybWF0OiBzdHJpbmcsIHRoZSBvdXRwdXQgZm9ybWF0IG5hbWUKICAgICAqICogcmF3X3RleHQ6IGJvb2xlYW4sIHNldHMgb3V0cHV0IHR5cGUgYXMgcmF3CiAgICAgKgogICAgICogQHBhcmFtIG9iamVjdCAkb2JqZWN0CiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gd2hlbiB0aGUgZ2l2ZW4gZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlc2NyaWJlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkb2JqZWN0LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zID0gYXJyYXlfbWVyZ2UoWwogICAgICAgICAgICAncmF3X3RleHQnID0+IGZhbHNlLAogICAgICAgICAgICAnZm9ybWF0JyA9PiAndHh0JywKICAgICAgICBdLCAkb3B0aW9ucyk7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmRlc2NyaXB0b3JzWyRvcHRpb25zWydmb3JtYXQnXV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5zdXBwb3J0ZWQgZm9ybWF0ICIlcyIuJywgJG9wdGlvbnNbJ2Zvcm1hdCddKSk7CiAgICAgICAgfQoKICAgICAgICAkZGVzY3JpcHRvciA9ICR0aGlzLT5kZXNjcmlwdG9yc1skb3B0aW9uc1snZm9ybWF0J11dOwogICAgICAgICRkZXNjcmlwdG9yLT5kZXNjcmliZSgkb3V0cHV0LCAkb2JqZWN0LCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBkZXNjcmlwdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm1hdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRmb3JtYXQsIERlc2NyaXB0b3JJbnRlcmZhY2UgJGRlc2NyaXB0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlc2NyaXB0b3JzWyRmb3JtYXRdID0gJGRlc2NyaXB0b3I7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAnZGVzY3JpcHRvcic7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXENob2ljZVF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxDb25maXJtYXRpb25RdWVzdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cUXVlc3Rpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFN0eWxlXFN5bWZvbnlTdHlsZTsKCi8qKgogKiBTeW1mb255IFN0eWxlIEd1aWRlIGNvbXBsaWFudCBxdWVzdGlvbiBoZWxwZXIuCiAqCiAqIEBhdXRob3IgS2V2aW4gQm9uZCA8a2V2aW5ib25kQGdtYWlsLmNvbT4KICovCmNsYXNzIFN5bWZvbnlRdWVzdGlvbkhlbHBlciBleHRlbmRzIFF1ZXN0aW9uSGVscGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIFRvIGJlIHJlbW92ZWQgaW4gNC4wCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2soSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgUXVlc3Rpb24gJHF1ZXN0aW9uKQogICAgewogICAgICAgICR2YWxpZGF0b3IgPSAkcXVlc3Rpb24tPmdldFZhbGlkYXRvcigpOwogICAgICAgICRxdWVzdGlvbi0+c2V0VmFsaWRhdG9yKGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJHZhbGlkYXRvcikgewogICAgICAgICAgICBpZiAobnVsbCAhPT0gJHZhbGlkYXRvcikgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHZhbGlkYXRvcigkdmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gbWFrZSByZXF1aXJlZAogICAgICAgICAgICAgICAgaWYgKCFcaXNfYXJyYXkoJHZhbHVlKSAmJiAhXGlzX2Jvb2woJHZhbHVlKSAmJiAwID09PSBcc3RybGVuKCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcignVGhlIGRlZmF1bHQgcXVlc3Rpb24gdmFsaWRhdG9yIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgbm90IGJlIHVzZWQgYW55bW9yZSBpbiB2ZXJzaW9uIDQuMC4gU2V0IGEgY3VzdG9tIHF1ZXN0aW9uIHZhbGlkYXRvciBpZiBuZWVkZWQuJywgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdBIHZhbHVlIGlzIHJlcXVpcmVkLicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gcGFyZW50Ojphc2soJGlucHV0LCAkb3V0cHV0LCAkcXVlc3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGVQcm9tcHQoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbikKICAgIHsKICAgICAgICAkdGV4dCA9IE91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlVHJhaWxpbmdCYWNrc2xhc2goJHF1ZXN0aW9uLT5nZXRRdWVzdGlvbigpKTsKICAgICAgICAkZGVmYXVsdCA9ICRxdWVzdGlvbi0+Z2V0RGVmYXVsdCgpOwoKICAgICAgICBzd2l0Y2ggKHRydWUpIHsKICAgICAgICAgICAgY2FzZSBudWxsID09PSAkZGVmYXVsdDoKICAgICAgICAgICAgICAgICR0ZXh0ID0gc3ByaW50ZignIDxpbmZvPiVzPC9pbmZvPjonLCAkdGV4dCk7CgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICRxdWVzdGlvbiBpbnN0YW5jZW9mIENvbmZpcm1hdGlvblF1ZXN0aW9uOgogICAgICAgICAgICAgICAgJHRleHQgPSBzcHJpbnRmKCcgPGluZm8+JXMgKHllcy9ubyk8L2luZm8+IFs8Y29tbWVudD4lczwvY29tbWVudD5dOicsICR0ZXh0LCAkZGVmYXVsdCA/ICd5ZXMnIDogJ25vJyk7CgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICRxdWVzdGlvbiBpbnN0YW5jZW9mIENob2ljZVF1ZXN0aW9uICYmICRxdWVzdGlvbi0+aXNNdWx0aXNlbGVjdCgpOgogICAgICAgICAgICAgICAgJGNob2ljZXMgPSAkcXVlc3Rpb24tPmdldENob2ljZXMoKTsKICAgICAgICAgICAgICAgICRkZWZhdWx0ID0gZXhwbG9kZSgnLCcsICRkZWZhdWx0KTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGVmYXVsdCBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICRkZWZhdWx0WyRrZXldID0gJGNob2ljZXNbdHJpbSgkdmFsdWUpXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGV4dCA9IHNwcmludGYoJyA8aW5mbz4lczwvaW5mbz4gWzxjb21tZW50PiVzPC9jb21tZW50Pl06JywgJHRleHQsIE91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlKGltcGxvZGUoJywgJywgJGRlZmF1bHQpKSk7CgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICRxdWVzdGlvbiBpbnN0YW5jZW9mIENob2ljZVF1ZXN0aW9uOgogICAgICAgICAgICAgICAgJGNob2ljZXMgPSAkcXVlc3Rpb24tPmdldENob2ljZXMoKTsKICAgICAgICAgICAgICAgICR0ZXh0ID0gc3ByaW50ZignIDxpbmZvPiVzPC9pbmZvPiBbPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+XTonLCAkdGV4dCwgT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoaXNzZXQoJGNob2ljZXNbJGRlZmF1bHRdKSA/ICRjaG9pY2VzWyRkZWZhdWx0XSA6ICRkZWZhdWx0KSk7CgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgJHRleHQgPSBzcHJpbnRmKCcgPGluZm8+JXM8L2luZm8+IFs8Y29tbWVudD4lczwvY29tbWVudD5dOicsICR0ZXh0LCBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZSgkZGVmYXVsdCkpOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dC0+d3JpdGVsbigkdGV4dCk7CgogICAgICAgICRwcm9tcHQgPSAnID4gJzsKCiAgICAgICAgaWYgKCRxdWVzdGlvbiBpbnN0YW5jZW9mIENob2ljZVF1ZXN0aW9uKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oJHRoaXMtPmZvcm1hdENob2ljZVF1ZXN0aW9uQ2hvaWNlcygkcXVlc3Rpb24sICdjb21tZW50JykpOwoKICAgICAgICAgICAgJHByb21wdCA9ICRxdWVzdGlvbi0+Z2V0UHJvbXB0KCk7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0LT53cml0ZSgkcHJvbXB0KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlRXJyb3IoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFxFeGNlcHRpb24gJGVycm9yKQogICAgewogICAgICAgIGlmICgkb3V0cHV0IGluc3RhbmNlb2YgU3ltZm9ueVN0eWxlKSB7CiAgICAgICAgICAgICRvdXRwdXQtPm5ld0xpbmUoKTsKICAgICAgICAgICAgJG91dHB1dC0+ZXJyb3IoJGVycm9yLT5nZXRNZXNzYWdlKCkpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50Ojp3cml0ZUVycm9yKCRvdXRwdXQsICRlcnJvcik7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxDb25zb2xlT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cUHJvY2Vzc0ZhaWxlZEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBUaGUgUHJvY2Vzc0hlbHBlciBjbGFzcyBwcm92aWRlcyBoZWxwZXJzIHRvIHJ1biBleHRlcm5hbCBwcm9jZXNzZXMuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgUHJvY2Vzc0hlbHBlciBleHRlbmRzIEhlbHBlcgp7CiAgICAvKioKICAgICAqIFJ1bnMgYW4gZXh0ZXJuYWwgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICAgICAgJG91dHB1dCAgICBBbiBPdXRwdXRJbnRlcmZhY2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXl8UHJvY2VzcyAkY21kICAgICAgIEFuIGluc3RhbmNlIG9mIFByb2Nlc3Mgb3IgYW4gYXJyYXkgb2YgYXJndW1lbnRzIHRvIGVzY2FwZSBhbmQgcnVuIG9yIGEgY29tbWFuZCB0byBydW4KICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAgICAgICAkZXJyb3IgICAgIEFuIGVycm9yIG1lc3NhZ2UgdGhhdCBtdXN0IGJlIGRpc3BsYXllZCBpZiBzb21ldGhpbmcgd2VudCB3cm9uZwogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgICAgICAgICRjYWxsYmFjayAgQSBQSFAgY2FsbGJhY2sgdG8gcnVuIHdoZW5ldmVyIHRoZXJlIGlzIHNvbWUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCBhdmFpbGFibGUgb24gU1RET1VUIG9yIFNUREVSUgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkgVGhlIHRocmVzaG9sZCBmb3IgdmVyYm9zaXR5CiAgICAgKgogICAgICogQHJldHVybiBQcm9jZXNzIFRoZSBwcm9jZXNzIHRoYXQgcmFuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBydW4oT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRjbWQsICRlcnJvciA9IG51bGwsIGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwsICR2ZXJib3NpdHkgPSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJZX1ZFUkJPU0UpCiAgICB7CiAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoUHJvY2Vzczo6Y2xhc3MpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ1RoZSBQcm9jZXNzSGVscGVyIGNhbm5vdCBiZSBydW4gYXMgdGhlIFByb2Nlc3MgY29tcG9uZW50IGlzIG5vdCBpbnN0YWxsZWQuIFRyeSBydW5uaW5nICJjb21wb3NlIHJlcXVpcmUgc3ltZm9ueS9wcm9jZXNzIi4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb3V0cHV0IGluc3RhbmNlb2YgQ29uc29sZU91dHB1dEludGVyZmFjZSkgewogICAgICAgICAgICAkb3V0cHV0ID0gJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgICRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0SGVscGVyU2V0KCktPmdldCgnZGVidWdfZm9ybWF0dGVyJyk7CgogICAgICAgIGlmICgkY21kIGluc3RhbmNlb2YgUHJvY2VzcykgewogICAgICAgICAgICAkcHJvY2VzcyA9ICRjbWQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcygkY21kKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdmVyYm9zaXR5IDw9ICRvdXRwdXQtPmdldFZlcmJvc2l0eSgpKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRmb3JtYXR0ZXItPnN0YXJ0KHNwbF9vYmplY3RfaGFzaCgkcHJvY2VzcyksICR0aGlzLT5lc2NhcGVTdHJpbmcoJHByb2Nlc3MtPmdldENvbW1hbmRMaW5lKCkpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG91dHB1dC0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICRjYWxsYmFjayA9ICR0aGlzLT53cmFwQ2FsbGJhY2soJG91dHB1dCwgJHByb2Nlc3MsICRjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2Vzcy0+cnVuKCRjYWxsYmFjayk7CgogICAgICAgIGlmICgkdmVyYm9zaXR5IDw9ICRvdXRwdXQtPmdldFZlcmJvc2l0eSgpKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpID8gJ0NvbW1hbmQgcmFuIHN1Y2Nlc3NmdWxseScgOiBzcHJpbnRmKCclcyBDb21tYW5kIGRpZCBub3QgcnVuIHN1Y2Nlc3NmdWxseScsICRwcm9jZXNzLT5nZXRFeGl0Q29kZSgpKTsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoJGZvcm1hdHRlci0+c3RvcChzcGxfb2JqZWN0X2hhc2goJHByb2Nlc3MpLCAkbWVzc2FnZSwgJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRwcm9jZXNzLT5pc1N1Y2Nlc3NmdWwoKSAmJiBudWxsICE9PSAkZXJyb3IpIHsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbihzcHJpbnRmKCc8ZXJyb3I+JXM8L2Vycm9yPicsICR0aGlzLT5lc2NhcGVTdHJpbmcoJGVycm9yKSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwcm9jZXNzOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBUaGlzIGlzIGlkZW50aWNhbCB0byBydW4oKSBleGNlcHQgdGhhdCBhbiBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZSBwcm9jZXNzCiAgICAgKiBleGl0cyB3aXRoIGEgbm9uLXplcm8gZXhpdCBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCAgIEFuIE91dHB1dEludGVyZmFjZSBpbnN0YW5jZQogICAgICogQHBhcmFtIHN0cmluZ3xQcm9jZXNzICAkY21kICAgICAgQW4gaW5zdGFuY2Ugb2YgUHJvY2VzcyBvciBhIGNvbW1hbmQgdG8gcnVuCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICRlcnJvciAgICBBbiBlcnJvciBtZXNzYWdlIHRoYXQgbXVzdCBiZSBkaXNwbGF5ZWQgaWYgc29tZXRoaW5nIHdlbnQgd3JvbmcKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICAgJGNhbGxiYWNrIEEgUEhQIGNhbGxiYWNrIHRvIHJ1biB3aGVuZXZlciB0aGVyZSBpcyBzb21lCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgYXZhaWxhYmxlIG9uIFNURE9VVCBvciBTVERFUlIKICAgICAqCiAgICAgKiBAcmV0dXJuIFByb2Nlc3MgVGhlIHByb2Nlc3MgdGhhdCByYW4KICAgICAqCiAgICAgKiBAdGhyb3dzIFByb2Nlc3NGYWlsZWRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAc2VlIHJ1bigpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtdXN0UnVuKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkY21kLCAkZXJyb3IgPSBudWxsLCBjYWxsYWJsZSAkY2FsbGJhY2sgPSBudWxsKQogICAgewogICAgICAgICRwcm9jZXNzID0gJHRoaXMtPnJ1bigkb3V0cHV0LCAkY21kLCAkZXJyb3IsICRjYWxsYmFjayk7CgogICAgICAgIGlmICghJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBQcm9jZXNzRmFpbGVkRXhjZXB0aW9uKCRwcm9jZXNzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvY2VzczsKICAgIH0KCiAgICAvKioKICAgICAqIFdyYXBzIGEgUHJvY2VzcyBjYWxsYmFjayB0byBhZGQgZGVidWdnaW5nIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQgICBBbiBPdXRwdXRJbnRlcmZhY2UgaW50ZXJmYWNlCiAgICAgKiBAcGFyYW0gUHJvY2VzcyAgICAgICAgICRwcm9jZXNzICBUaGUgUHJvY2VzcwogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgICAkY2FsbGJhY2sgQSBQSFAgY2FsbGFibGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGNhbGxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cmFwQ2FsbGJhY2soT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFByb2Nlc3MgJHByb2Nlc3MsIGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRvdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRvdXRwdXQgPSAkb3V0cHV0LT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRIZWxwZXJTZXQoKS0+Z2V0KCdkZWJ1Z19mb3JtYXR0ZXInKTsKCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkdHlwZSwgJGJ1ZmZlcikgdXNlICgkb3V0cHV0LCAkcHJvY2VzcywgJGNhbGxiYWNrLCAkZm9ybWF0dGVyKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRmb3JtYXR0ZXItPnByb2dyZXNzKHNwbF9vYmplY3RfaGFzaCgkcHJvY2VzcyksICR0aGlzLT5lc2NhcGVTdHJpbmcoJGJ1ZmZlciksIFByb2Nlc3M6OkVSUiA9PT0gJHR5cGUpKTsKCiAgICAgICAgICAgIGlmIChudWxsICE9PSAkY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIFxjYWxsX3VzZXJfZnVuYygkY2FsbGJhY2ssICR0eXBlLCAkYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBlc2NhcGVTdHJpbmcoJHN0cikKICAgIHsKICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJzwnLCAnXFw8JywgJHN0cik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3Byb2Nlc3MnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kTG9hZGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgUm9iaW4gQ2hhbGFzIDxyb2Jpbi5jaGFsYXNAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIENvbW1hbmRMb2FkZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBMb2FkcyBhIGNvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZAogICAgICoKICAgICAqIEB0aHJvd3MgQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJG5hbWUpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGEgY29tbWFuZCBleGlzdHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRuYW1lKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nW10gQWxsIHJlZ2lzdGVyZWQgY29tbWFuZCBuYW1lcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXMoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZExvYWRlcjsKCnVzZSBQc3JcQ29udGFpbmVyXENvbnRhaW5lckludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbjsKCi8qKgogKiBMb2FkcyBjb21tYW5kcyBmcm9tIGEgUFNSLTExIGNvbnRhaW5lci4KICoKICogQGF1dGhvciBSb2JpbiBDaGFsYXMgPHJvYmluLmNoYWxhc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBDb250YWluZXJDb21tYW5kTG9hZGVyIGltcGxlbWVudHMgQ29tbWFuZExvYWRlckludGVyZmFjZQp7CiAgICBwcml2YXRlICRjb250YWluZXI7CiAgICBwcml2YXRlICRjb21tYW5kTWFwOwoKICAgIC8qKgogICAgICogQHBhcmFtIENvbnRhaW5lckludGVyZmFjZSAkY29udGFpbmVyICBBIGNvbnRhaW5lciBmcm9tIHdoaWNoIHRvIGxvYWQgY29tbWFuZCBzZXJ2aWNlcwogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgICAkY29tbWFuZE1hcCBBbiBhcnJheSB3aXRoIGNvbW1hbmQgbmFtZXMgYXMga2V5cyBhbmQgc2VydmljZSBpZHMgYXMgdmFsdWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDb250YWluZXJJbnRlcmZhY2UgJGNvbnRhaW5lciwgYXJyYXkgJGNvbW1hbmRNYXApCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbnRhaW5lciA9ICRjb250YWluZXI7CiAgICAgICAgJHRoaXMtPmNvbW1hbmRNYXAgPSAkY29tbWFuZE1hcDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXMoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDb21tYW5kTm90Rm91bmRFeGNlcHRpb24oc3ByaW50ZignQ29tbWFuZCAiJXMiIGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRhaW5lci0+Z2V0KCR0aGlzLT5jb21tYW5kTWFwWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXMoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5jb21tYW5kTWFwWyRuYW1lXSkgJiYgJHRoaXMtPmNvbnRhaW5lci0+aGFzKCR0aGlzLT5jb21tYW5kTWFwWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lcygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoJHRoaXMtPmNvbW1hbmRNYXApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kTG9hZGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbjsKCi8qKgogKiBBIHNpbXBsZSBjb21tYW5kIGxvYWRlciB1c2luZyBmYWN0b3JpZXMgdG8gaW5zdGFudGlhdGUgY29tbWFuZHMgbGF6aWx5LgogKgogKiBAYXV0aG9yIE1heGltZSBTdGVpbmhhdXNzZXIgPG1heGltZS5zdGVpbmhhdXNzZXJAZ21haWwuY29tPgogKi8KY2xhc3MgRmFjdG9yeUNvbW1hbmRMb2FkZXIgaW1wbGVtZW50cyBDb21tYW5kTG9hZGVySW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGZhY3RvcmllczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBjYWxsYWJsZVtdICRmYWN0b3JpZXMgSW5kZXhlZCBieSBjb21tYW5kIG5hbWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZmFjdG9yaWVzKQogICAgewogICAgICAgICR0aGlzLT5mYWN0b3JpZXMgPSAkZmFjdG9yaWVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZmFjdG9yaWVzWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+ZmFjdG9yaWVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdDb21tYW5kICIlcyIgZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICRmYWN0b3J5ID0gJHRoaXMtPmZhY3Rvcmllc1skbmFtZV07CgogICAgICAgIHJldHVybiAkZmFjdG9yeSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9rZXlzKCR0aGlzLT5mYWN0b3JpZXMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxMb2dnZXI7Cgp1c2UgUHNyXExvZ1xBYnN0cmFjdExvZ2dlcjsKdXNlIFBzclxMb2dcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgUHNyXExvZ1xMb2dMZXZlbDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogUFNSLTMgY29tcGxpYW50IGNvbnNvbGUgbG9nZ2VyLgogKgogKiBAYXV0aG9yIEvDqXZpbiBEdW5nbGFzIDxkdW5nbGFzQGdtYWlsLmNvbT4KICoKICogQHNlZSBodHRwczovL3d3dy5waHAtZmlnLm9yZy9wc3IvcHNyLTMvCiAqLwpjbGFzcyBDb25zb2xlTG9nZ2VyIGV4dGVuZHMgQWJzdHJhY3RMb2dnZXIKewogICAgY29uc3QgSU5GTyA9ICdpbmZvJzsKICAgIGNvbnN0IEVSUk9SID0gJ2Vycm9yJzsKCiAgICBwcml2YXRlICRvdXRwdXQ7CiAgICBwcml2YXRlICR2ZXJib3NpdHlMZXZlbE1hcCA9IFsKICAgICAgICBMb2dMZXZlbDo6RU1FUkdFTkNZID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX05PUk1BTCwKICAgICAgICBMb2dMZXZlbDo6QUxFUlQgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfTk9STUFMLAogICAgICAgIExvZ0xldmVsOjpDUklUSUNBTCA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9OT1JNQUwsCiAgICAgICAgTG9nTGV2ZWw6OkVSUk9SID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX05PUk1BTCwKICAgICAgICBMb2dMZXZlbDo6V0FSTklORyA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9OT1JNQUwsCiAgICAgICAgTG9nTGV2ZWw6Ok5PVElDRSA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFLAogICAgICAgIExvZ0xldmVsOjpJTkZPID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSwKICAgICAgICBMb2dMZXZlbDo6REVCVUcgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfREVCVUcsCiAgICBdOwogICAgcHJpdmF0ZSAkZm9ybWF0TGV2ZWxNYXAgPSBbCiAgICAgICAgTG9nTGV2ZWw6OkVNRVJHRU5DWSA9PiBzZWxmOjpFUlJPUiwKICAgICAgICBMb2dMZXZlbDo6QUxFUlQgPT4gc2VsZjo6RVJST1IsCiAgICAgICAgTG9nTGV2ZWw6OkNSSVRJQ0FMID0+IHNlbGY6OkVSUk9SLAogICAgICAgIExvZ0xldmVsOjpFUlJPUiA9PiBzZWxmOjpFUlJPUiwKICAgICAgICBMb2dMZXZlbDo6V0FSTklORyA9PiBzZWxmOjpJTkZPLAogICAgICAgIExvZ0xldmVsOjpOT1RJQ0UgPT4gc2VsZjo6SU5GTywKICAgICAgICBMb2dMZXZlbDo6SU5GTyA9PiBzZWxmOjpJTkZPLAogICAgICAgIExvZ0xldmVsOjpERUJVRyA9PiBzZWxmOjpJTkZPLAogICAgXTsKICAgIHByaXZhdGUgJGVycm9yZWQgPSBmYWxzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIGFycmF5ICR2ZXJib3NpdHlMZXZlbE1hcCA9IFtdLCBhcnJheSAkZm9ybWF0TGV2ZWxNYXAgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0ID0gJG91dHB1dDsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5TGV2ZWxNYXAgPSAkdmVyYm9zaXR5TGV2ZWxNYXAgKyAkdGhpcy0+dmVyYm9zaXR5TGV2ZWxNYXA7CiAgICAgICAgJHRoaXMtPmZvcm1hdExldmVsTWFwID0gJGZvcm1hdExldmVsTWFwICsgJHRoaXMtPmZvcm1hdExldmVsTWFwOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9nKCRsZXZlbCwgJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gW10pCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dmVyYm9zaXR5TGV2ZWxNYXBbJGxldmVsXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgbG9nIGxldmVsICIlcyIgZG9lcyBub3QgZXhpc3QuJywgJGxldmVsKSk7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPm91dHB1dDsKCiAgICAgICAgLy8gV3JpdGUgdG8gdGhlIGVycm9yIG91dHB1dCBpZiBuZWNlc3NhcnkgYW5kIGF2YWlsYWJsZQogICAgICAgIGlmIChzZWxmOjpFUlJPUiA9PT0gJHRoaXMtPmZvcm1hdExldmVsTWFwWyRsZXZlbF0pIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+ZXJyb3JlZCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyB0aGUgaWYgY29uZGl0aW9uIGNoZWNrIGlzbid0IG5lY2Vzc2FyeSAtLSBpdCdzIHRoZSBzYW1lIG9uZSB0aGF0ICRvdXRwdXQgd2lsbCBkbyBpbnRlcm5hbGx5IGFueXdheS4KICAgICAgICAvLyBXZSBvbmx5IGRvIGl0IGZvciBlZmZpY2llbmN5IGhlcmUgYXMgdGhlIG1lc3NhZ2UgZm9ybWF0dGluZyBpcyByZWxhdGl2ZWx5IGV4cGVuc2l2ZS4KICAgICAgICBpZiAoJG91dHB1dC0+Z2V0VmVyYm9zaXR5KCkgPj0gJHRoaXMtPnZlcmJvc2l0eUxldmVsTWFwWyRsZXZlbF0pIHsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbihzcHJpbnRmKCc8JTEkcz5bJTIkc10gJTMkczwvJTEkcz4nLCAkdGhpcy0+Zm9ybWF0TGV2ZWxNYXBbJGxldmVsXSwgJGxldmVsLCAkdGhpcy0+aW50ZXJwb2xhdGUoJG1lc3NhZ2UsICRjb250ZXh0KSksICR0aGlzLT52ZXJib3NpdHlMZXZlbE1hcFskbGV2ZWxdKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgd2hlbiBhbnkgbWVzc2FnZXMgaGF2ZSBiZWVuIGxvZ2dlZCBhdCBlcnJvciBsZXZlbHMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNFcnJvcmVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcnBvbGF0ZXMgY29udGV4dCB2YWx1ZXMgaW50byB0aGUgbWVzc2FnZSBwbGFjZWhvbGRlcnMuCiAgICAgKgogICAgICogQGF1dGhvciBQSFAgRnJhbWV3b3JrIEludGVyb3BlcmFiaWxpdHkgR3JvdXAKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbnRlcnBvbGF0ZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJG1lc3NhZ2UsICd7JykpIHsKICAgICAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgICAgIH0KCiAgICAgICAgJHJlcGxhY2VtZW50cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRjb250ZXh0IGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZhbCB8fCBpc19zY2FsYXIoJHZhbCkgfHwgKFxpc19vYmplY3QoJHZhbCkgJiYgbWV0aG9kX2V4aXN0cygkdmFsLCAnX190b1N0cmluZycpKSkgewogICAgICAgICAgICAgICAgJHJlcGxhY2VtZW50c1sie3ska2V5fX0iXSA9ICR2YWw7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdmFsIGluc3RhbmNlb2YgXERhdGVUaW1lSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnRzWyJ7eyRrZXl9fSJdID0gJHZhbC0+Zm9ybWF0KFxEYXRlVGltZTo6UkZDMzMzOSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChcaXNfb2JqZWN0KCR2YWwpKSB7CiAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnRzWyJ7eyRrZXl9fSJdID0gJ1tvYmplY3QgJy5cZ2V0X2NsYXNzKCR2YWwpLiddJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXBsYWNlbWVudHNbInt7JGtleX19Il0gPSAnWycuXGdldHR5cGUoJHZhbCkuJ10nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RydHIoJG1lc3NhZ2UsICRyZXBsYWNlbWVudHMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwoKLyoqCiAqIENvbnNvbGVPdXRwdXQgaXMgdGhlIGRlZmF1bHQgY2xhc3MgZm9yIGFsbCBDTEkgb3V0cHV0LiBJdCB1c2VzIFNURE9VVCBhbmQgU1RERVJSLgogKgogKiBUaGlzIGNsYXNzIGlzIGEgY29udmVuaWVudCB3cmFwcGVyIGFyb3VuZCBgU3RyZWFtT3V0cHV0YCBmb3IgYm90aCBTVERPVVQgYW5kIFNUREVSUi4KICoKICogICAgICRvdXRwdXQgPSBuZXcgQ29uc29sZU91dHB1dCgpOwogKgogKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG86CiAqCiAqICAgICAkb3V0cHV0ID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKSk7CiAqICAgICAkc3RkRXJyID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vc3RkZXJyJywgJ3cnKSk7CiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgQ29uc29sZU91dHB1dCBleHRlbmRzIFN0cmVhbU91dHB1dCBpbXBsZW1lbnRzIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkc3RkZXJyOwoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkgVGhlIHZlcmJvc2l0eSBsZXZlbCAob25lIG9mIHRoZSBWRVJCT1NJVFkgY29uc3RhbnRzIGluIE91dHB1dEludGVyZmFjZSkKICAgICAqIEBwYXJhbSBib29sfG51bGwgICAgICAgICAgICAgICAgICAgICAkZGVjb3JhdGVkIFdoZXRoZXIgdG8gZGVjb3JhdGUgbWVzc2FnZXMgKG51bGwgZm9yIGF1dG8tZ3Vlc3NpbmcpCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlfG51bGwgJGZvcm1hdHRlciBPdXRwdXQgZm9ybWF0dGVyIGluc3RhbmNlIChudWxsIHRvIHVzZSBkZWZhdWx0IE91dHB1dEZvcm1hdHRlcikKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2ZXJib3NpdHkgPSBzZWxmOjpWRVJCT1NJVFlfTk9STUFMLCAkZGVjb3JhdGVkID0gbnVsbCwgT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHRoaXMtPm9wZW5PdXRwdXRTdHJlYW0oKSwgJHZlcmJvc2l0eSwgJGRlY29yYXRlZCwgJGZvcm1hdHRlcik7CgogICAgICAgICRhY3R1YWxEZWNvcmF0ZWQgPSAkdGhpcy0+aXNEZWNvcmF0ZWQoKTsKICAgICAgICAkdGhpcy0+c3RkZXJyID0gbmV3IFN0cmVhbU91dHB1dCgkdGhpcy0+b3BlbkVycm9yU3RyZWFtKCksICR2ZXJib3NpdHksICRkZWNvcmF0ZWQsICR0aGlzLT5nZXRGb3JtYXR0ZXIoKSk7CgogICAgICAgIGlmIChudWxsID09PSAkZGVjb3JhdGVkKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREZWNvcmF0ZWQoJGFjdHVhbERlY29yYXRlZCAmJiAkdGhpcy0+c3RkZXJyLT5pc0RlY29yYXRlZCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZWNvcmF0ZWQoJGRlY29yYXRlZCkKICAgIHsKICAgICAgICBwYXJlbnQ6OnNldERlY29yYXRlZCgkZGVjb3JhdGVkKTsKICAgICAgICAkdGhpcy0+c3RkZXJyLT5zZXREZWNvcmF0ZWQoJGRlY29yYXRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGb3JtYXR0ZXIoT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIpCiAgICB7CiAgICAgICAgcGFyZW50OjpzZXRGb3JtYXR0ZXIoJGZvcm1hdHRlcik7CiAgICAgICAgJHRoaXMtPnN0ZGVyci0+c2V0Rm9ybWF0dGVyKCRmb3JtYXR0ZXIpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCkKICAgIHsKICAgICAgICBwYXJlbnQ6OnNldFZlcmJvc2l0eSgkbGV2ZWwpOwogICAgICAgICR0aGlzLT5zdGRlcnItPnNldFZlcmJvc2l0eSgkbGV2ZWwpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RkZXJyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXJyb3JPdXRwdXQoT3V0cHV0SW50ZXJmYWNlICRlcnJvcikKICAgIHsKICAgICAgICAkdGhpcy0+c3RkZXJyID0gJGVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGN1cnJlbnQgZW52aXJvbm1lbnQgc3VwcG9ydHMgd3JpdGluZyBjb25zb2xlIG91dHB1dCB0bwogICAgICogU1RET1VULgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaGFzU3Rkb3V0U3VwcG9ydCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlID09PSAkdGhpcy0+aXNSdW5uaW5nT1M0MDAoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBjdXJyZW50IGVudmlyb25tZW50IHN1cHBvcnRzIHdyaXRpbmcgY29uc29sZSBvdXRwdXQgdG8KICAgICAqIFNUREVSUi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc1N0ZGVyclN1cHBvcnQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZSA9PT0gJHRoaXMtPmlzUnVubmluZ09TNDAwKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgY3VycmVudCBleGVjdXRpbmcgZW52aXJvbm1lbnQgaXMgSUJNIGlTZXJpZXMgKE9TNDAwKSwgd2hpY2gKICAgICAqIGRvZXNuJ3QgcHJvcGVybHkgY29udmVydCBjaGFyYWN0ZXItZW5jb2RpbmdzIGJldHdlZW4gQVNDSUkgdG8gRUJDRElDLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzUnVubmluZ09TNDAwKCkKICAgIHsKICAgICAgICAkY2hlY2tzID0gWwogICAgICAgICAgICBcZnVuY3Rpb25fZXhpc3RzKCdwaHBfdW5hbWUnKSA/IHBocF91bmFtZSgncycpIDogJycsCiAgICAgICAgICAgIGdldGVudignT1NUWVBFJyksCiAgICAgICAgICAgIFxQSFBfT1MsCiAgICAgICAgXTsKCiAgICAgICAgcmV0dXJuIGZhbHNlICE9PSBzdHJpcG9zKGltcGxvZGUoJzsnLCAkY2hlY2tzKSwgJ09TNDAwJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHJlc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3Blbk91dHB1dFN0cmVhbSgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzU3Rkb3V0U3VwcG9ydCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmb3BlbigncGhwOi8vb3V0cHV0JywgJ3cnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBAZm9wZW4oJ3BocDovL3N0ZG91dCcsICd3JykgPzogZm9wZW4oJ3BocDovL291dHB1dCcsICd3Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHJlc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3BlbkVycm9yU3RyZWFtKCkKICAgIHsKICAgICAgICByZXR1cm4gZm9wZW4oJHRoaXMtPmhhc1N0ZGVyclN1cHBvcnQoKSA/ICdwaHA6Ly9zdGRlcnInIDogJ3BocDovL291dHB1dCcsICd3Jyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2U7CgovKioKICogT3V0cHV0SW50ZXJmYWNlIGlzIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgYWxsIE91dHB1dCBjbGFzc2VzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmludGVyZmFjZSBPdXRwdXRJbnRlcmZhY2UKewogICAgY29uc3QgVkVSQk9TSVRZX1FVSUVUID0gMTY7CiAgICBjb25zdCBWRVJCT1NJVFlfTk9STUFMID0gMzI7CiAgICBjb25zdCBWRVJCT1NJVFlfVkVSQk9TRSA9IDY0OwogICAgY29uc3QgVkVSQk9TSVRZX1ZFUllfVkVSQk9TRSA9IDEyODsKICAgIGNvbnN0IFZFUkJPU0lUWV9ERUJVRyA9IDI1NjsKCiAgICBjb25zdCBPVVRQVVRfTk9STUFMID0gMTsKICAgIGNvbnN0IE9VVFBVVF9SQVcgPSAyOwogICAgY29uc3QgT1VUUFVUX1BMQUlOID0gNDsKCiAgICAvKioKICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlcyBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBzdHJpbmdzIG9yIGEgc2luZ2xlIHN0cmluZwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkbmV3bGluZSAgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICRvcHRpb25zICBBIGJpdG1hc2sgb2Ygb3B0aW9ucyAob25lIG9mIHRoZSBPVVRQVVQgb3IgVkVSQk9TSVRZIGNvbnN0YW50cyksIDAgaXMgY29uc2lkZXJlZCB0aGUgc2FtZSBhcyBzZWxmOjpPVVRQVVRfTk9STUFMIHwgc2VsZjo6VkVSQk9TSVRZX05PUk1BTAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IGZhbHNlLCAkb3B0aW9ucyA9IDApOwoKICAgIC8qKgogICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgb3V0cHV0IGFuZCBhZGRzIGEgbmV3bGluZSBhdCB0aGUgZW5kLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2VzIFRoZSBtZXNzYWdlIGFzIGFuIGFycmF5IG9mIHN0cmluZ3Mgb3IgYSBzaW5nbGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICRvcHRpb25zICBBIGJpdG1hc2sgb2Ygb3B0aW9ucyAob25lIG9mIHRoZSBPVVRQVVQgb3IgVkVSQk9TSVRZIGNvbnN0YW50cyksIDAgaXMgY29uc2lkZXJlZCB0aGUgc2FtZSBhcyBzZWxmOjpPVVRQVVRfTk9STUFMIHwgc2VsZjo6VkVSQk9TSVRZX05PUk1BTAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVsbigkbWVzc2FnZXMsICRvcHRpb25zID0gMCk7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB2ZXJib3NpdHkgb2YgdGhlIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbCBUaGUgbGV2ZWwgb2YgdmVyYm9zaXR5IChvbmUgb2YgdGhlIFZFUkJPU0lUWSBjb25zdGFudHMpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWZXJib3NpdHkoJGxldmVsKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IG9mIHRoZSBvdXRwdXQuCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIGN1cnJlbnQgbGV2ZWwgb2YgdmVyYm9zaXR5IChvbmUgb2YgdGhlIFZFUkJPU0lUWSBjb25zdGFudHMpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJib3NpdHkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB2ZXJib3NpdHkgaXMgcXVpZXQgKC1xKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB2ZXJib3NpdHkgaXMgc2V0IHRvIFZFUkJPU0lUWV9RVUlFVCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1F1aWV0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdmVyYm9zaXR5IGlzIHZlcmJvc2UgKC12KS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB2ZXJib3NpdHkgaXMgc2V0IHRvIFZFUkJPU0lUWV9WRVJCT1NFLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHZlcmJvc2l0eSBpcyB2ZXJ5IHZlcmJvc2UgKC12dikuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdmVyYm9zaXR5IGlzIHNldCB0byBWRVJCT1NJVFlfVkVSWV9WRVJCT1NFLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyeVZlcmJvc2UoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB2ZXJib3NpdHkgaXMgZGVidWcgKC12dnYpLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHZlcmJvc2l0eSBpcyBzZXQgdG8gVkVSQk9TSVRZX0RFQlVHLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVidWcoKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlY29yYXRlZCBmbGFnLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRkZWNvcmF0ZWQgV2hldGhlciB0byBkZWNvcmF0ZSB0aGUgbWVzc2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlY29yYXRlZCgkZGVjb3JhdGVkKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRlY29yYXRlZCBmbGFnLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBvdXRwdXQgd2lsbCBkZWNvcmF0ZSBtZXNzYWdlcywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlY29yYXRlZCgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGb3JtYXR0ZXIoT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBjdXJyZW50IG91dHB1dCBmb3JtYXR0ZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdHRlcigpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7CgovKioKICogQGF1dGhvciBKZWFuLUZyYW7Dp29pcyBTaW1vbiA8Y29udGFjdEBqZnNpbW9uLmZyPgogKi8KY2xhc3MgQnVmZmVyZWRPdXRwdXQgZXh0ZW5kcyBPdXRwdXQKewogICAgcHJpdmF0ZSAkYnVmZmVyID0gJyc7CgogICAgLyoqCiAgICAgKiBFbXB0aWVzIGJ1ZmZlciBhbmQgcmV0dXJucyBpdHMgY29udGVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmV0Y2goKQogICAgewogICAgICAgICRjb250ZW50ID0gJHRoaXMtPmJ1ZmZlcjsKICAgICAgICAkdGhpcy0+YnVmZmVyID0gJyc7CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvV3JpdGUoJG1lc3NhZ2UsICRuZXdsaW5lKQogICAgewogICAgICAgICR0aGlzLT5idWZmZXIgLj0gJG1lc3NhZ2U7CgogICAgICAgIGlmICgkbmV3bGluZSkgewogICAgICAgICAgICAkdGhpcy0+YnVmZmVyIC49IFxQSFBfRU9MOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlckludGVyZmFjZTsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBvdXRwdXQgY2xhc3Nlcy4KICoKICogVGhlcmUgYXJlIGZpdmUgbGV2ZWxzIG9mIHZlcmJvc2l0eToKICoKICogICogbm9ybWFsOiBubyBvcHRpb24gcGFzc2VkIChub3JtYWwgb3V0cHV0KQogKiAgKiB2ZXJib3NlOiAtdiAobW9yZSBvdXRwdXQpCiAqICAqIHZlcnkgdmVyYm9zZTogLXZ2IChoaWdobHkgZXh0ZW5kZWQgb3V0cHV0KQogKiAgKiBkZWJ1ZzogLXZ2diAoYWxsIGRlYnVnIG91dHB1dCkKICogICogcXVpZXQ6IC1xIChubyBvdXRwdXQpCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgT3V0cHV0IGltcGxlbWVudHMgT3V0cHV0SW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJHZlcmJvc2l0eTsKICAgIHByaXZhdGUgJGZvcm1hdHRlcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyYm9zaXR5IFRoZSB2ZXJib3NpdHkgbGV2ZWwgKG9uZSBvZiB0aGUgVkVSQk9TSVRZIGNvbnN0YW50cyBpbiBPdXRwdXRJbnRlcmZhY2UpCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlY29yYXRlZCBXaGV0aGVyIHRvIGRlY29yYXRlIG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlfG51bGwgJGZvcm1hdHRlciBPdXRwdXQgZm9ybWF0dGVyIGluc3RhbmNlIChudWxsIHRvIHVzZSBkZWZhdWx0IE91dHB1dEZvcm1hdHRlcikKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2ZXJib3NpdHkgPSBzZWxmOjpWRVJCT1NJVFlfTk9STUFMLCAkZGVjb3JhdGVkID0gZmFsc2UsIE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5ID0gbnVsbCA9PT0gJHZlcmJvc2l0eSA/IHNlbGY6OlZFUkJPU0lUWV9OT1JNQUwgOiAkdmVyYm9zaXR5OwogICAgICAgICR0aGlzLT5mb3JtYXR0ZXIgPSAkZm9ybWF0dGVyID86IG5ldyBPdXRwdXRGb3JtYXR0ZXIoKTsKICAgICAgICAkdGhpcy0+Zm9ybWF0dGVyLT5zZXREZWNvcmF0ZWQoJGRlY29yYXRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGb3JtYXR0ZXIoT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdHRlciA9ICRmb3JtYXR0ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXR0ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0dGVyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdHRlci0+c2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0dGVyLT5pc0RlY29yYXRlZCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCkKICAgIHsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5ID0gKGludCkgJGxldmVsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyYm9zaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUXVpZXQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfUVVJRVQgPT09ICR0aGlzLT52ZXJib3NpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfVkVSQk9TRSA8PSAkdGhpcy0+dmVyYm9zaXR5OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OlZFUkJPU0lUWV9WRVJZX1ZFUkJPU0UgPD0gJHRoaXMtPnZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVidWcoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfREVCVUcgPD0gJHRoaXMtPnZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlbG4oJG1lc3NhZ2VzLCAkb3B0aW9ucyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlKCRtZXNzYWdlcywgdHJ1ZSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IGZhbHNlLCAkb3B0aW9ucyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgJG1lc3NhZ2VzID0gKGFycmF5KSAkbWVzc2FnZXM7CgogICAgICAgICR0eXBlcyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwgfCBzZWxmOjpPVVRQVVRfUkFXIHwgc2VsZjo6T1VUUFVUX1BMQUlOOwogICAgICAgICR0eXBlID0gJHR5cGVzICYgJG9wdGlvbnMgPzogc2VsZjo6T1VUUFVUX05PUk1BTDsKCiAgICAgICAgJHZlcmJvc2l0aWVzID0gc2VsZjo6VkVSQk9TSVRZX1FVSUVUIHwgc2VsZjo6VkVSQk9TSVRZX05PUk1BTCB8IHNlbGY6OlZFUkJPU0lUWV9WRVJCT1NFIHwgc2VsZjo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSB8IHNlbGY6OlZFUkJPU0lUWV9ERUJVRzsKICAgICAgICAkdmVyYm9zaXR5ID0gJHZlcmJvc2l0aWVzICYgJG9wdGlvbnMgPzogc2VsZjo6VkVSQk9TSVRZX05PUk1BTDsKCiAgICAgICAgaWYgKCR2ZXJib3NpdHkgPiAkdGhpcy0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzIGFzICRtZXNzYWdlKSB7CiAgICAgICAgICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpPVVRQVVRfTk9STUFMOgogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJHRoaXMtPmZvcm1hdHRlci0+Zm9ybWF0KCRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpPVVRQVVRfUkFXOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBPdXRwdXRJbnRlcmZhY2U6Ok9VVFBVVF9QTEFJTjoKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IHN0cmlwX3RhZ3MoJHRoaXMtPmZvcm1hdHRlci0+Zm9ybWF0KCRtZXNzYWdlKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5kb1dyaXRlKCRtZXNzYWdlLCAkbmV3bGluZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgQSBtZXNzYWdlIHRvIHdyaXRlIHRvIHRoZSBvdXRwdXQKICAgICAqIEBwYXJhbSBib29sICAgJG5ld2xpbmUgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Xcml0ZSgkbWVzc2FnZSwgJG5ld2xpbmUpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7CgovKioKICogQ29uc29sZU91dHB1dEludGVyZmFjZSBpcyB0aGUgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IENvbnNvbGVPdXRwdXQgY2xhc3MuCiAqIFRoaXMgYWRkcyBpbmZvcm1hdGlvbiBhYm91dCBzdGRlcnIgb3V0cHV0IHN0cmVhbS4KICoKICogQGF1dGhvciBEYXJpdXN6IEfDs3JlY2tpIDxkYXJlay5rcmtAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UgZXh0ZW5kcyBPdXRwdXRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBPdXRwdXRJbnRlcmZhY2UgZm9yIGVycm9ycy4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXJyb3JPdXRwdXQoT3V0cHV0SW50ZXJmYWNlICRlcnJvcik7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2U7CgovKioKICogU3RyZWFtT3V0cHV0IHdyaXRlcyB0aGUgb3V0cHV0IHRvIGEgZ2l2ZW4gc3RyZWFtLgogKgogKiBVc2FnZToKICoKICogICAgICRvdXRwdXQgPSBuZXcgU3RyZWFtT3V0cHV0KGZvcGVuKCdwaHA6Ly9zdGRvdXQnLCAndycpKTsKICoKICogQXMgYFN0cmVhbU91dHB1dGAgY2FuIHVzZSBhbnkgc3RyZWFtLCB5b3UgY2FuIGFsc28gdXNlIGEgZmlsZToKICoKICogICAgICRvdXRwdXQgPSBuZXcgU3RyZWFtT3V0cHV0KGZvcGVuKCcvcGF0aC90by9vdXRwdXQubG9nJywgJ2EnLCBmYWxzZSkpOwogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIFN0cmVhbU91dHB1dCBleHRlbmRzIE91dHB1dAp7CiAgICBwcml2YXRlICRzdHJlYW07CgogICAgLyoqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgICAgICAgICAgICAgICAgICAgICAgJHN0cmVhbSAgICBBIHN0cmVhbSByZXNvdXJjZQogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkgVGhlIHZlcmJvc2l0eSBsZXZlbCAob25lIG9mIHRoZSBWRVJCT1NJVFkgY29uc3RhbnRzIGluIE91dHB1dEludGVyZmFjZSkKICAgICAqIEBwYXJhbSBib29sfG51bGwgICAgICAgICAgICAgICAgICAgICAkZGVjb3JhdGVkIFdoZXRoZXIgdG8gZGVjb3JhdGUgbWVzc2FnZXMgKG51bGwgZm9yIGF1dG8tZ3Vlc3NpbmcpCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlfG51bGwgJGZvcm1hdHRlciBPdXRwdXQgZm9ybWF0dGVyIGluc3RhbmNlIChudWxsIHRvIHVzZSBkZWZhdWx0IE91dHB1dEZvcm1hdHRlcikKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGZpcnN0IGFyZ3VtZW50IGlzIG5vdCBhIHJlYWwgc3RyZWFtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc3RyZWFtLCAkdmVyYm9zaXR5ID0gc2VsZjo6VkVSQk9TSVRZX05PUk1BTCwgJGRlY29yYXRlZCA9IG51bGwsIE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoIVxpc19yZXNvdXJjZSgkc3RyZWFtKSB8fCAnc3RyZWFtJyAhPT0gZ2V0X3Jlc291cmNlX3R5cGUoJHN0cmVhbSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIFN0cmVhbU91dHB1dCBjbGFzcyBuZWVkcyBhIHN0cmVhbSBhcyBpdHMgZmlyc3QgYXJndW1lbnQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c3RyZWFtID0gJHN0cmVhbTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRkZWNvcmF0ZWQpIHsKICAgICAgICAgICAgJGRlY29yYXRlZCA9ICR0aGlzLT5oYXNDb2xvclN1cHBvcnQoKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHZlcmJvc2l0eSwgJGRlY29yYXRlZCwgJGZvcm1hdHRlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBzdHJlYW0gYXR0YWNoZWQgdG8gdGhpcyBTdHJlYW1PdXRwdXQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiByZXNvdXJjZSBBIHN0cmVhbSByZXNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RyZWFtKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0cmVhbTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvV3JpdGUoJG1lc3NhZ2UsICRuZXdsaW5lKQogICAgewogICAgICAgIGlmICgkbmV3bGluZSkgewogICAgICAgICAgICAkbWVzc2FnZSAuPSBcUEhQX0VPTDsKICAgICAgICB9CgogICAgICAgIEBmd3JpdGUoJHRoaXMtPnN0cmVhbSwgJG1lc3NhZ2UpOwoKICAgICAgICBmZmx1c2goJHRoaXMtPnN0cmVhbSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmVhbSBzdXBwb3J0cyBjb2xvcml6YXRpb24uCiAgICAgKgogICAgICogQ29sb3JpemF0aW9uIGlzIGRpc2FibGVkIGlmIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHN0cmVhbToKICAgICAqCiAgICAgKiBUaGlzIGlzIHRyaWNreSBvbiBXaW5kb3dzLCBiZWNhdXNlIEN5Z3dpbiwgTXN5czIgZXRjIGVtdWxhdGUgcHNldWRvCiAgICAgKiB0ZXJtaW5hbHMgdmlhIG5hbWVkIHBpcGVzLCBzbyB3ZSBjYW4gb25seSBjaGVjayB0aGUgZW52aXJvbm1lbnQuCiAgICAgKgogICAgICogUmVmZXJlbmNlOiBDb21wb3NlclxYZGVidWdIYW5kbGVyXFByb2Nlc3M6OnN1cHBvcnRzQ29sb3IKICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci94ZGVidWctaGFuZGxlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBzdHJlYW0gc3VwcG9ydHMgY29sb3JpemF0aW9uLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc0NvbG9yU3VwcG9ydCgpCiAgICB7CiAgICAgICAgaWYgKCdIeXBlcicgPT09IGdldGVudignVEVSTV9QUk9HUkFNJykpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoXERJUkVDVE9SWV9TRVBBUkFUT1IgPT09ICdcXCcpIHsKICAgICAgICAgICAgcmV0dXJuIChcZnVuY3Rpb25fZXhpc3RzKCdzYXBpX3dpbmRvd3NfdnQxMDBfc3VwcG9ydCcpCiAgICAgICAgICAgICAgICAmJiBAc2FwaV93aW5kb3dzX3Z0MTAwX3N1cHBvcnQoJHRoaXMtPnN0cmVhbSkpCiAgICAgICAgICAgICAgICB8fCBmYWxzZSAhPT0gZ2V0ZW52KCdBTlNJQ09OJykKICAgICAgICAgICAgICAgIHx8ICdPTicgPT09IGdldGVudignQ29uRW11QU5TSScpCiAgICAgICAgICAgICAgICB8fCAneHRlcm0nID09PSBnZXRlbnYoJ1RFUk0nKTsKICAgICAgICB9CgogICAgICAgIGlmIChcZnVuY3Rpb25fZXhpc3RzKCdzdHJlYW1faXNhdHR5JykpIHsKICAgICAgICAgICAgcmV0dXJuIEBzdHJlYW1faXNhdHR5KCR0aGlzLT5zdHJlYW0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2lzYXR0eScpKSB7CiAgICAgICAgICAgIHJldHVybiBAcG9zaXhfaXNhdHR5KCR0aGlzLT5zdHJlYW0pOwogICAgICAgIH0KCiAgICAgICAgJHN0YXQgPSBAZnN0YXQoJHRoaXMtPnN0cmVhbSk7CiAgICAgICAgLy8gQ2hlY2sgaWYgZm9ybWF0dGVkIG1vZGUgaXMgU19JRkNIUgogICAgICAgIHJldHVybiAkc3RhdCA/IDAwMjAwMDAgPT09ICgkc3RhdFsnbW9kZSddICYgMDE3MDAwMCkgOiBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlckludGVyZmFjZTsKCi8qKgogKiBOdWxsT3V0cHV0IHN1cHByZXNzZXMgYWxsIG91dHB1dC4KICoKICogICAgICRvdXRwdXQgPSBuZXcgTnVsbE91dHB1dCgpOwogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBUb2JpYXMgU2NodWx0emUgPGh0dHA6Ly90b2Jpb24uZGU+CiAqLwpjbGFzcyBOdWxsT3V0cHV0IGltcGxlbWVudHMgT3V0cHV0SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0dGVyKE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyKQogICAgewogICAgICAgIC8vIGRvIG5vdGhpbmcKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdHRlcigpCiAgICB7CiAgICAgICAgLy8gdG8gY29tcGx5IHdpdGggdGhlIGludGVyZmFjZSB3ZSBtdXN0IHJldHVybiBhIE91dHB1dEZvcm1hdHRlckludGVyZmFjZQogICAgICAgIHJldHVybiBuZXcgT3V0cHV0Rm9ybWF0dGVyKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZWNvcmF0ZWQoJGRlY29yYXRlZCkKICAgIHsKICAgICAgICAvLyBkbyBub3RoaW5nCiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlY29yYXRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCkKICAgIHsKICAgICAgICAvLyBkbyBub3RoaW5nCiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJib3NpdHkoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfUVVJRVQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1F1aWV0KCkKICAgIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWJ1ZygpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVsbigkbWVzc2FnZXMsICRvcHRpb25zID0gc2VsZjo6T1VUUFVUX05PUk1BTCkKICAgIHsKICAgICAgICAvLyBkbyBub3RoaW5nCiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gZmFsc2UsICRvcHRpb25zID0gc2VsZjo6T1VUUFVUX05PUk1BTCkKICAgIHsKICAgICAgICAvLyBkbyBub3RoaW5nCiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlOwoKY2xhc3MgVGVybWluYWwKewogICAgcHJpdmF0ZSBzdGF0aWMgJHdpZHRoOwogICAgcHJpdmF0ZSBzdGF0aWMgJGhlaWdodDsKICAgIHByaXZhdGUgc3RhdGljICRzdHR5OwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGVybWluYWwgd2lkdGguCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFdpZHRoKCkKICAgIHsKICAgICAgICAkd2lkdGggPSBnZXRlbnYoJ0NPTFVNTlMnKTsKICAgICAgICBpZiAoZmFsc2UgIT09ICR3aWR0aCkgewogICAgICAgICAgICByZXR1cm4gKGludCkgdHJpbSgkd2lkdGgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiR3aWR0aCkgewogICAgICAgICAgICBzZWxmOjppbml0RGltZW5zaW9ucygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiR3aWR0aCA/OiA4MDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHRlcm1pbmFsIGhlaWdodC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVpZ2h0KCkKICAgIHsKICAgICAgICAkaGVpZ2h0ID0gZ2V0ZW52KCdMSU5FUycpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJGhlaWdodCkgewogICAgICAgICAgICByZXR1cm4gKGludCkgdHJpbSgkaGVpZ2h0KTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaGVpZ2h0KSB7CiAgICAgICAgICAgIHNlbGY6OmluaXREaW1lbnNpb25zKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGhlaWdodCA/OiA1MDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGhhc1N0dHlBdmFpbGFibGUoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSBzZWxmOjokc3R0eSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHN0dHk7CiAgICAgICAgfQoKICAgICAgICAvLyBza2lwIGNoZWNrIGlmIGV4ZWMgZnVuY3Rpb24gaXMgZGlzYWJsZWQKICAgICAgICBpZiAoIVxmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBleGVjKCdzdHR5IDI+JjEnLCAkb3V0cHV0LCAkZXhpdGNvZGUpOwoKICAgICAgICByZXR1cm4gc2VsZjo6JHN0dHkgPSAwID09PSAkZXhpdGNvZGU7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5pdERpbWVuc2lvbnMoKQogICAgewogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oXGQrKXgoXGQrKSg/OiBcKChcZCspeChcZCspXCkpPyQvJywgdHJpbShnZXRlbnYoJ0FOU0lDT04nKSksICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgLy8gZXh0cmFjdCBbdywgSF0gZnJvbSAid3hoIChXeEgpIgogICAgICAgICAgICAgICAgLy8gb3IgW3csIGhdIGZyb20gInd4aCIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRtYXRjaGVzWzFdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IGlzc2V0KCRtYXRjaGVzWzRdKSA/IChpbnQpICRtYXRjaGVzWzRdIDogKGludCkgJG1hdGNoZXNbMl07CiAgICAgICAgICAgIH0gZWxzZWlmICghc2VsZjo6aGFzVnQxMDBTdXBwb3J0KCkgJiYgc2VsZjo6aGFzU3R0eUF2YWlsYWJsZSgpKSB7CiAgICAgICAgICAgICAgICAvLyBvbmx5IHVzZSBzdHR5IG9uIFdpbmRvd3MgaWYgdGhlIHRlcm1pbmFsIGRvZXMgbm90IHN1cHBvcnQgdnQxMDAgKGUuZy4gV2luZG93cyA3ICsgZ2l0LWJhc2gpCiAgICAgICAgICAgICAgICAvLyB0ZXN0aW5nIGZvciBzdHR5IGluIGEgV2luZG93cyAxMCB2dDEwMC1lbmFibGVkIGNvbnNvbGUgd2lsbCBpbXBsaWNpdGx5IGRpc2FibGUgdnQxMDAgc3VwcG9ydCBvbiBTVERPVVQKICAgICAgICAgICAgICAgIHNlbGY6OmluaXREaW1lbnNpb25zVXNpbmdTdHR5KCk7CiAgICAgICAgICAgIH0gZWxzZWlmIChudWxsICE9PSAkZGltZW5zaW9ucyA9IHNlbGY6OmdldENvbnNvbGVNb2RlKCkpIHsKICAgICAgICAgICAgICAgIC8vIGV4dHJhY3QgW3csIGhdIGZyb20gInd4aCIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRkaW1lbnNpb25zWzBdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IChpbnQpICRkaW1lbnNpb25zWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsZjo6aW5pdERpbWVuc2lvbnNVc2luZ1N0dHkoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgU1RET1VUIGhhcyB2dDEwMCBzdXBwb3J0IChzb21lIFdpbmRvd3MgMTArIGNvbmZpZ3VyYXRpb25zKS4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaGFzVnQxMDBTdXBwb3J0KCkKICAgIHsKICAgICAgICByZXR1cm4gXGZ1bmN0aW9uX2V4aXN0cygnc2FwaV93aW5kb3dzX3Z0MTAwX3N1cHBvcnQnKSAmJiBzYXBpX3dpbmRvd3NfdnQxMDBfc3VwcG9ydChmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBkaW1lbnNpb25zIHVzaW5nIHRoZSBvdXRwdXQgb2YgYW4gc3R0eSBjb2x1bW5zIGxpbmUuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluaXREaW1lbnNpb25zVXNpbmdTdHR5KCkKICAgIHsKICAgICAgICBpZiAoJHN0dHlTdHJpbmcgPSBzZWxmOjpnZXRTdHR5Q29sdW1ucygpKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvcm93cy4oXGQrKTsuY29sdW1ucy4oXGQrKTsvaScsICRzdHR5U3RyaW5nLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgIC8vIGV4dHJhY3QgW3csIGhdIGZyb20gInJvd3MgaDsgY29sdW1ucyB3OyIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRtYXRjaGVzWzJdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IChpbnQpICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgnLzsuKFxkKykucm93czsuKFxkKykuY29sdW1ucy9pJywgJHN0dHlTdHJpbmcsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgLy8gZXh0cmFjdCBbdywgaF0gZnJvbSAiOyBoIHJvd3M7IHcgY29sdW1ucyIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRtYXRjaGVzWzJdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IChpbnQpICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUnVucyBhbmQgcGFyc2VzIG1vZGUgQ09OIGlmIGl0J3MgYXZhaWxhYmxlLCBzdXBwcmVzc2luZyBhbnkgZXJyb3Igb3V0cHV0LgogICAgICoKICAgICAqIEByZXR1cm4gaW50W118bnVsbCBBbiBhcnJheSBjb21wb3NlZCBvZiB0aGUgd2lkdGggYW5kIHRoZSBoZWlnaHQgb3IgbnVsbCBpZiBpdCBjb3VsZCBub3QgYmUgcGFyc2VkCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldENvbnNvbGVNb2RlKCkKICAgIHsKICAgICAgICAkaW5mbyA9IHNlbGY6OnJlYWRGcm9tUHJvY2VzcygnbW9kZSBDT04nKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRpbmZvIHx8ICFwcmVnX21hdGNoKCcvLS0tLS0tLS0rXHI/XG4uKz8oXGQrKVxyP1xuLis/KFxkKylccj9cbi8nLCAkaW5mbywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFsoaW50KSAkbWF0Y2hlc1syXSwgKGludCkgJG1hdGNoZXNbMV1dOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyBhbmQgcGFyc2VzIHN0dHkgLWEgaWYgaXQncyBhdmFpbGFibGUsIHN1cHByZXNzaW5nIGFueSBlcnJvciBvdXRwdXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRTdHR5Q29sdW1ucygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OnJlYWRGcm9tUHJvY2Vzcygnc3R0eSAtYSB8IGdyZXAgY29sdW1ucycpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkY29tbWFuZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcmVhZEZyb21Qcm9jZXNzKCRjb21tYW5kKQogICAgewogICAgICAgIGlmICghXGZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkZGVzY3JpcHRvcnNwZWMgPSBbCiAgICAgICAgICAgIDEgPT4gWydwaXBlJywgJ3cnXSwKICAgICAgICAgICAgMiA9PiBbJ3BpcGUnLCAndyddLAogICAgICAgIF07CgogICAgICAgICRwcm9jZXNzID0gcHJvY19vcGVuKCRjb21tYW5kLCAkZGVzY3JpcHRvcnNwZWMsICRwaXBlcywgbnVsbCwgbnVsbCwgWydzdXBwcmVzc19lcnJvcnMnID0+IHRydWVdKTsKICAgICAgICBpZiAoIVxpc19yZXNvdXJjZSgkcHJvY2VzcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkaW5mbyA9IHN0cmVhbV9nZXRfY29udGVudHMoJHBpcGVzWzFdKTsKICAgICAgICBmY2xvc2UoJHBpcGVzWzFdKTsKICAgICAgICBmY2xvc2UoJHBpcGVzWzJdKTsKICAgICAgICBwcm9jX2Nsb3NlKCRwcm9jZXNzKTsKCiAgICAgICAgcmV0dXJuICRpbmZvOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXERlc2NyaXB0b3JIZWxwZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBIZWxwQ29tbWFuZCBkaXNwbGF5cyB0aGUgaGVscCBmb3IgYSBnaXZlbiBjb21tYW5kLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEhlbHBDb21tYW5kIGV4dGVuZHMgQ29tbWFuZAp7CiAgICBwcml2YXRlICRjb21tYW5kOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcy0+aWdub3JlVmFsaWRhdGlvbkVycm9ycygpOwoKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2hlbHAnKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oWwogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2NvbW1hbmRfbmFtZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIGNvbW1hbmQgbmFtZScsICdoZWxwJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1RoZSBvdXRwdXQgZm9ybWF0ICh0eHQsIHhtbCwganNvbiwgb3IgbWQpJywgJ3R4dCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyYXcnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1RvIG91dHB1dCByYXcgY29tbWFuZCBoZWxwJyksCiAgICAgICAgICAgIF0pCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0Rpc3BsYXlzIGhlbHAgZm9yIGEgY29tbWFuZCcpCiAgICAgICAgICAgIC0+c2V0SGVscCg8PDwnRU9GJwpUaGUgPGluZm8+JWNvbW1hbmQubmFtZSU8L2luZm8+IGNvbW1hbmQgZGlzcGxheXMgaGVscCBmb3IgYSBnaXZlbiBjb21tYW5kOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJSBsaXN0PC9pbmZvPgoKWW91IGNhbiBhbHNvIG91dHB1dCB0aGUgaGVscCBpbiBvdGhlciBmb3JtYXRzIGJ5IHVzaW5nIHRoZSA8Y29tbWVudD4tLWZvcm1hdDwvY29tbWVudD4gb3B0aW9uOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJSAtLWZvcm1hdD14bWwgbGlzdDwvaW5mbz4KClRvIGRpc3BsYXkgdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIGNvbW1hbmRzLCBwbGVhc2UgdXNlIHRoZSA8aW5mbz5saXN0PC9pbmZvPiBjb21tYW5kLgpFT0YKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tbWFuZChDb21tYW5kICRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kID0gJGNvbW1hbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21tYW5kKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21tYW5kID0gJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPmZpbmQoJGlucHV0LT5nZXRBcmd1bWVudCgnY29tbWFuZF9uYW1lJykpOwogICAgICAgIH0KCiAgICAgICAgJGhlbHBlciA9IG5ldyBEZXNjcmlwdG9ySGVscGVyKCk7CiAgICAgICAgJGhlbHBlci0+ZGVzY3JpYmUoJG91dHB1dCwgJHRoaXMtPmNvbW1hbmQsIFsKICAgICAgICAgICAgJ2Zvcm1hdCcgPT4gJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpLAogICAgICAgICAgICAncmF3X3RleHQnID0+ICRpbnB1dC0+Z2V0T3B0aW9uKCdyYXcnKSwKICAgICAgICBdKTsKCiAgICAgICAgJHRoaXMtPmNvbW1hbmQgPSBudWxsOwogICAgfQp9Cjw/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/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcRmFjdG9yeTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcTG9jazsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcRmxvY2tTdG9yZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcU2VtYXBob3JlU3RvcmU7CgovKioKICogQmFzaWMgbG9jayBmZWF0dXJlIGZvciBjb21tYW5kcy4KICoKICogQGF1dGhvciBHZW9mZnJleSBCcmllciA8Z2VvZmZyZXkuYnJpZXJAZ21haWwuY29tPgogKi8KdHJhaXQgTG9ja2FibGVUcmFpdAp7CiAgICAvKiogQHZhciBMb2NrICovCiAgICBwcml2YXRlICRsb2NrOwoKICAgIC8qKgogICAgICogTG9ja3MgYSBjb21tYW5kLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvY2soJG5hbWUgPSBudWxsLCAkYmxvY2tpbmcgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIWNsYXNzX2V4aXN0cyhTZW1hcGhvcmVTdG9yZTo6Y2xhc3MpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdUbyBlbmFibGUgdGhlIGxvY2tpbmcgZmVhdHVyZSB5b3UgbXVzdCBpbnN0YWxsIHRoZSBzeW1mb255L2xvY2sgY29tcG9uZW50LicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5sb2NrKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQSBsb2NrIGlzIGFscmVhZHkgaW4gcGxhY2UuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoU2VtYXBob3JlU3RvcmU6OmlzU3VwcG9ydGVkKCRibG9ja2luZykpIHsKICAgICAgICAgICAgJHN0b3JlID0gbmV3IFNlbWFwaG9yZVN0b3JlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHN0b3JlID0gbmV3IEZsb2NrU3RvcmUoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2NrID0gKG5ldyBGYWN0b3J5KCRzdG9yZSkpLT5jcmVhdGVMb2NrKCRuYW1lID86ICR0aGlzLT5nZXROYW1lKCkpOwogICAgICAgIGlmICghJHRoaXMtPmxvY2stPmFjcXVpcmUoJGJsb2NraW5nKSkgewogICAgICAgICAgICAkdGhpcy0+bG9jayA9IG51bGw7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbGVhc2VzIHRoZSBjb21tYW5kIGxvY2sgaWYgdGhlcmUgaXMgb25lLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbGVhc2UoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+bG9jaykgewogICAgICAgICAgICAkdGhpcy0+bG9jay0+cmVsZWFzZSgpOwogICAgICAgICAgICAkdGhpcy0+bG9jayA9IG51bGw7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXERlc2NyaXB0b3JIZWxwZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0RGVmaW5pdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIExpc3RDb21tYW5kIGRpc3BsYXlzIHRoZSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY29tbWFuZHMgZm9yIHRoZSBhcHBsaWNhdGlvbi4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBMaXN0Q29tbWFuZCBleHRlbmRzIENvbW1hbmQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnbGlzdCcpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbigkdGhpcy0+Y3JlYXRlRGVmaW5pdGlvbigpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdMaXN0cyBjb21tYW5kcycpCiAgICAgICAgICAgIC0+c2V0SGVscCg8PDwnRU9GJwpUaGUgPGluZm8+JWNvbW1hbmQubmFtZSU8L2luZm8+IGNvbW1hbmQgbGlzdHMgYWxsIGNvbW1hbmRzOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJTwvaW5mbz4KCllvdSBjYW4gYWxzbyBkaXNwbGF5IHRoZSBjb21tYW5kcyBmb3IgYSBzcGVjaWZpYyBuYW1lc3BhY2U6CgogIDxpbmZvPnBocCAlY29tbWFuZC5mdWxsX25hbWUlIHRlc3Q8L2luZm8+CgpZb3UgY2FuIGFsc28gb3V0cHV0IHRoZSBpbmZvcm1hdGlvbiBpbiBvdGhlciBmb3JtYXRzIGJ5IHVzaW5nIHRoZSA8Y29tbWVudD4tLWZvcm1hdDwvY29tbWVudD4gb3B0aW9uOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJSAtLWZvcm1hdD14bWw8L2luZm8+CgpJdCdzIGFsc28gcG9zc2libGUgdG8gZ2V0IHJhdyBsaXN0IG9mIGNvbW1hbmRzICh1c2VmdWwgZm9yIGVtYmVkZGluZyBjb21tYW5kIHJ1bm5lcik6CgogIDxpbmZvPnBocCAlY29tbWFuZC5mdWxsX25hbWUlIC0tcmF3PC9pbmZvPgpFT0YKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hdGl2ZURlZmluaXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y3JlYXRlRGVmaW5pdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRoZWxwZXIgPSBuZXcgRGVzY3JpcHRvckhlbHBlcigpOwogICAgICAgICRoZWxwZXItPmRlc2NyaWJlKCRvdXRwdXQsICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLCBbCiAgICAgICAgICAgICdmb3JtYXQnID0+ICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKSwKICAgICAgICAgICAgJ3Jhd190ZXh0JyA9PiAkaW5wdXQtPmdldE9wdGlvbigncmF3JyksCiAgICAgICAgICAgICduYW1lc3BhY2UnID0+ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ25hbWVzcGFjZScpLAogICAgICAgIF0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZURlZmluaXRpb24oKQogICAgewogICAgICAgIHJldHVybiBuZXcgSW5wdXREZWZpbml0aW9uKFsKICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ25hbWVzcGFjZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIG5hbWVzcGFjZSBuYW1lJyksCiAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmF3JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdUbyBvdXRwdXQgcmF3IGNvbW1hbmQgbGlzdCcpLAogICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1RoZSBvdXRwdXQgZm9ybWF0ICh0eHQsIHhtbCwganNvbiwgb3IgbWQpJywgJ3R4dCcpLAogICAgICAgIF0pOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxTdHlsZTsKCi8qKgogKiBPdXRwdXQgc3R5bGUgaGVscGVycy4KICoKICogQGF1dGhvciBLZXZpbiBCb25kIDxrZXZpbmJvbmRAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIFN0eWxlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGNvbW1hbmQgdGl0bGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdGl0bGUoJG1lc3NhZ2UpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIHNlY3Rpb24gdGl0bGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VjdGlvbigkbWVzc2FnZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgbGlzdC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxpc3RpbmcoYXJyYXkgJGVsZW1lbnRzKTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgaW5mb3JtYXRpb25hbCB0ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRleHQoJG1lc3NhZ2UpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIHN1Y2Nlc3MgcmVzdWx0IGJhci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdWNjZXNzKCRtZXNzYWdlKTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYW4gZXJyb3IgcmVzdWx0IGJhci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGFuIHdhcm5pbmcgcmVzdWx0IGJhci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3YXJuaW5nKCRtZXNzYWdlKTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBub3RlIGFkbW9uaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm90ZSgkbWVzc2FnZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgY2F1dGlvbiBhZG1vbml0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNhdXRpb24oJG1lc3NhZ2UpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIHRhYmxlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdGFibGUoYXJyYXkgJGhlYWRlcnMsIGFycmF5ICRyb3dzKTsKCiAgICAvKioKICAgICAqIEFza3MgYSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAkcXVlc3Rpb24KICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICRkZWZhdWx0CiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkdmFsaWRhdG9yCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrKCRxdWVzdGlvbiwgJGRlZmF1bHQgPSBudWxsLCAkdmFsaWRhdG9yID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBBc2tzIGEgcXVlc3Rpb24gd2l0aCB0aGUgdXNlciBpbnB1dCBoaWRkZW4uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgJHF1ZXN0aW9uCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkdmFsaWRhdG9yCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrSGlkZGVuKCRxdWVzdGlvbiwgJHZhbGlkYXRvciA9IG51bGwpOwoKICAgIC8qKgogICAgICogQXNrcyBmb3IgY29uZmlybWF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uCiAgICAgKiBAcGFyYW0gYm9vbCAgICRkZWZhdWx0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb25maXJtKCRxdWVzdGlvbiwgJGRlZmF1bHQgPSB0cnVlKTsKCiAgICAvKioKICAgICAqIEFza3MgYSBjaG9pY2UgcXVlc3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAkcXVlc3Rpb24KICAgICAqIEBwYXJhbSBzdHJpbmd8aW50fG51bGwgJGRlZmF1bHQKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaG9pY2UoJHF1ZXN0aW9uLCBhcnJheSAkY2hvaWNlcywgJGRlZmF1bHQgPSBudWxsKTsKCiAgICAvKioKICAgICAqIEFkZCBuZXdsaW5lKHMpLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGNvdW50IFRoZSBudW1iZXIgb2YgbmV3bGluZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5ld0xpbmUoJGNvdW50ID0gMSk7CgogICAgLyoqCiAgICAgKiBTdGFydHMgdGhlIHByb2dyZXNzIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRtYXggTWF4aW11bSBzdGVwcyAoMCBpZiB1bmtub3duKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3NTdGFydCgkbWF4ID0gMCk7CgogICAgLyoqCiAgICAgKiBBZHZhbmNlcyB0aGUgcHJvZ3Jlc3Mgb3V0cHV0IFggc3RlcHMuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc3RlcCBOdW1iZXIgb2Ygc3RlcHMgdG8gYWR2YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3NBZHZhbmNlKCRzdGVwID0gMSk7CgogICAgLyoqCiAgICAgKiBGaW5pc2hlcyB0aGUgcHJvZ3Jlc3Mgb3V0cHV0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3NGaW5pc2goKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcU3R5bGU7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFByb2dyZXNzQmFyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcU3ltZm9ueVF1ZXN0aW9uSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcVGFibGU7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcQnVmZmVyZWRPdXRwdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXENob2ljZVF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxDb25maXJtYXRpb25RdWVzdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cUXVlc3Rpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlcm1pbmFsOwoKLyoqCiAqIE91dHB1dCBkZWNvcmF0b3IgaGVscGVycyBmb3IgdGhlIFN5bWZvbnkgU3R5bGUgR3VpZGUuCiAqCiAqIEBhdXRob3IgS2V2aW4gQm9uZCA8a2V2aW5ib25kQGdtYWlsLmNvbT4KICovCmNsYXNzIFN5bWZvbnlTdHlsZSBleHRlbmRzIE91dHB1dFN0eWxlCnsKICAgIGNvbnN0IE1BWF9MSU5FX0xFTkdUSCA9IDEyMDsKCiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJHF1ZXN0aW9uSGVscGVyOwogICAgcHJpdmF0ZSAkcHJvZ3Jlc3NCYXI7CiAgICBwcml2YXRlICRsaW5lTGVuZ3RoOwogICAgcHJpdmF0ZSAkYnVmZmVyZWRPdXRwdXQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgICAgICR0aGlzLT5idWZmZXJlZE91dHB1dCA9IG5ldyBCdWZmZXJlZE91dHB1dCgkb3V0cHV0LT5nZXRWZXJib3NpdHkoKSwgZmFsc2UsIGNsb25lICRvdXRwdXQtPmdldEZvcm1hdHRlcigpKTsKICAgICAgICAvLyBXaW5kb3dzIGNtZCB3cmFwcyBsaW5lcyBhcyBzb29uIGFzIHRoZSB0ZXJtaW5hbCB3aWR0aCBpcyByZWFjaGVkLCB3aGV0aGVyIHRoZXJlIGFyZSBmb2xsb3dpbmcgY2hhcnMgb3Igbm90LgogICAgICAgICR3aWR0aCA9IChuZXcgVGVybWluYWwoKSktPmdldFdpZHRoKCkgPzogc2VsZjo6TUFYX0xJTkVfTEVOR1RIOwogICAgICAgICR0aGlzLT5saW5lTGVuZ3RoID0gbWluKCR3aWR0aCAtIChpbnQpIChcRElSRUNUT1JZX1NFUEFSQVRPUiA9PT0gJ1xcJyksIHNlbGY6Ok1BWF9MSU5FX0xFTkdUSCk7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgbWVzc2FnZSBhcyBhIGJsb2NrIG9mIHRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZXMgVGhlIG1lc3NhZ2UgdG8gd3JpdGUgaW4gdGhlIGJsb2NrCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICR0eXBlICAgICBUaGUgYmxvY2sgdHlwZSAoYWRkZWQgaW4gW10gb24gZmlyc3QgbGluZSkKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgJHN0eWxlICAgIFRoZSBzdHlsZSB0byBhcHBseSB0byB0aGUgd2hvbGUgYmxvY2sKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHByZWZpeCAgIFRoZSBwcmVmaXggZm9yIHRoZSBibG9jawogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkcGFkZGluZyAgV2hldGhlciB0byBhZGQgdmVydGljYWwgcGFkZGluZwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkZXNjYXBlICAgV2hldGhlciB0byBlc2NhcGUgdGhlIG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGJsb2NrKCRtZXNzYWdlcywgJHR5cGUgPSBudWxsLCAkc3R5bGUgPSBudWxsLCAkcHJlZml4ID0gJyAnLCAkcGFkZGluZyA9IGZhbHNlLCAkZXNjYXBlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBcaXNfYXJyYXkoJG1lc3NhZ2VzKSA/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+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+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlcjsKCi8qKgogKiBGb3JtYXR0ZXIgc3R5bGUgaW50ZXJmYWNlIGZvciBkZWZpbmluZyBzdHlsZXMuCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBTZXRzIHN0eWxlIGZvcmVncm91bmQgY29sb3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjb2xvciBUaGUgY29sb3IgbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9yZWdyb3VuZCgkY29sb3IgPSBudWxsKTsKCiAgICAvKioKICAgICAqIFNldHMgc3R5bGUgYmFja2dyb3VuZCBjb2xvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb2xvciBUaGUgY29sb3IgbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QmFja2dyb3VuZCgkY29sb3IgPSBudWxsKTsKCiAgICAvKioKICAgICAqIFNldHMgc29tZSBzcGVjaWZpYyBzdHlsZSBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3B0aW9uIFRoZSBvcHRpb24gbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRvcHRpb24pOwoKICAgIC8qKgogICAgICogVW5zZXRzIHNvbWUgc3BlY2lmaWMgc3R5bGUgb3B0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wdGlvbiBUaGUgb3B0aW9uIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuc2V0T3B0aW9uKCRvcHRpb24pOwoKICAgIC8qKgogICAgICogU2V0cyBtdWx0aXBsZSBzdHlsZSBvcHRpb25zIGF0IG9uY2UuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb25zKGFycmF5ICRvcHRpb25zKTsKCiAgICAvKioKICAgICAqIEFwcGxpZXMgdGhlIHN0eWxlIHRvIGEgZ2l2ZW4gdGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0IFRoZSB0ZXh0IHRvIHN0eWxlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFwcGx5KCR0ZXh0KTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKCi8qKgogKiBGb3JtYXR0ZXIgY2xhc3MgZm9yIGNvbnNvbGUgb3V0cHV0LgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKi8KY2xhc3MgT3V0cHV0Rm9ybWF0dGVyIGltcGxlbWVudHMgT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGRlY29yYXRlZDsKICAgIHByaXZhdGUgJHN0eWxlcyA9IFtdOwogICAgcHJpdmF0ZSAkc3R5bGVTdGFjazsKCiAgICAvKioKICAgICAqIEVzY2FwZXMgIjwiIHNwZWNpYWwgY2hhciBpbiBnaXZlbiB0ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQgVGV4dCB0byBlc2NhcGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBFc2NhcGVkIHRleHQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGUoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBwcmVnX3JlcGxhY2UoJy8oW15cXFxcXT8pPC8nLCAnJDFcXDwnLCAkdGV4dCk7CgogICAgICAgIHJldHVybiBzZWxmOjplc2NhcGVUcmFpbGluZ0JhY2tzbGFzaCgkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFc2NhcGVzIHRyYWlsaW5nICJcIiBpbiBnaXZlbiB0ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQgVGV4dCB0byBlc2NhcGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBFc2NhcGVkIHRleHQKICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGVUcmFpbGluZ0JhY2tzbGFzaCgkdGV4dCkKICAgIHsKICAgICAgICBpZiAoJ1xcJyA9PT0gc3Vic3RyKCR0ZXh0LCAtMSkpIHsKICAgICAgICAgICAgJGxlbiA9IFxzdHJsZW4oJHRleHQpOwogICAgICAgICAgICAkdGV4dCA9IHJ0cmltKCR0ZXh0LCAnXFwnKTsKICAgICAgICAgICAgJHRleHQgPSBzdHJfcmVwbGFjZSgiXDAiLCAnJywgJHRleHQpOwogICAgICAgICAgICAkdGV4dCAuPSBzdHJfcmVwZWF0KCJcMCIsICRsZW4gLSBcc3RybGVuKCR0ZXh0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBjb25zb2xlIG91dHB1dCBmb3JtYXR0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlY29yYXRlZCBXaGV0aGVyIHRoaXMgZm9ybWF0dGVyIHNob3VsZCBhY3R1YWxseSBkZWNvcmF0ZSBzdHJpbmdzCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2VbXSAkc3R5bGVzICAgIEFycmF5IG9mICJuYW1lID0+IEZvcm1hdHRlclN0eWxlIiBpbnN0YW5jZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRkZWNvcmF0ZWQgPSBmYWxzZSwgYXJyYXkgJHN0eWxlcyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT5kZWNvcmF0ZWQgPSAoYm9vbCkgJGRlY29yYXRlZDsKCiAgICAgICAgJHRoaXMtPnNldFN0eWxlKCdlcnJvcicsIG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgnd2hpdGUnLCAncmVkJykpOwogICAgICAgICR0aGlzLT5zZXRTdHlsZSgnaW5mbycsIG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgnZ3JlZW4nKSk7CiAgICAgICAgJHRoaXMtPnNldFN0eWxlKCdjb21tZW50JywgbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCd5ZWxsb3cnKSk7CiAgICAgICAgJHRoaXMtPnNldFN0eWxlKCdxdWVzdGlvbicsIG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgnYmxhY2snLCAnY3lhbicpKTsKCiAgICAgICAgZm9yZWFjaCAoJHN0eWxlcyBhcyAkbmFtZSA9PiAkc3R5bGUpIHsKICAgICAgICAgICAgJHRoaXMtPnNldFN0eWxlKCRuYW1lLCAkc3R5bGUpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0eWxlU3RhY2sgPSBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGVTdGFjaygpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlY29yYXRlZCA9IChib29sKSAkZGVjb3JhdGVkOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVjb3JhdGVkOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3R5bGUoJG5hbWUsIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlICRzdHlsZSkKICAgIHsKICAgICAgICAkdGhpcy0+c3R5bGVzW3N0cnRvbG93ZXIoJG5hbWUpXSA9ICRzdHlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1N0eWxlKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+c3R5bGVzW3N0cnRvbG93ZXIoJG5hbWUpXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdHlsZSgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXNTdHlsZSgkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdVbmRlZmluZWQgc3R5bGU6ICIlcyIuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+c3R5bGVzW3N0cnRvbG93ZXIoJG5hbWUpXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZvcm1hdCgkbWVzc2FnZSkKICAgIHsKICAgICAgICAkbWVzc2FnZSA9IChzdHJpbmcpICRtZXNzYWdlOwogICAgICAgICRvZmZzZXQgPSAwOwogICAgICAgICRvdXRwdXQgPSAnJzsKICAgICAgICAkdGFnUmVnZXggPSAnW2Etel1bYS16MC05LF89Oy1dKisnOwogICAgICAgIHByZWdfbWF0Y2hfYWxsKCIjPCgoJHRhZ1JlZ2V4KSB8IC8oJHRhZ1JlZ2V4KT8pPiNpeCIsICRtZXNzYWdlLCAkbWF0Y2hlcywgXFBSRUdfT0ZGU0VUX0NBUFRVUkUpOwogICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzWzBdIGFzICRpID0+ICRtYXRjaCkgewogICAgICAgICAgICAkcG9zID0gJG1hdGNoWzFdOwogICAgICAgICAgICAkdGV4dCA9ICRtYXRjaFswXTsKCiAgICAgICAgICAgIGlmICgwICE9ICRwb3MgJiYgJ1xcJyA9PSAkbWVzc2FnZVskcG9zIC0gMV0pIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBhZGQgdGhlIHRleHQgdXAgdG8gdGhlIG5leHQgdGFnCiAgICAgICAgICAgICRvdXRwdXQgLj0gJHRoaXMtPmFwcGx5Q3VycmVudFN0eWxlKHN1YnN0cigkbWVzc2FnZSwgJG9mZnNldCwgJHBvcyAtICRvZmZzZXQpKTsKICAgICAgICAgICAgJG9mZnNldCA9ICRwb3MgKyBcc3RybGVuKCR0ZXh0KTsKCiAgICAgICAgICAgIC8vIG9wZW5pbmcgdGFnPwogICAgICAgICAgICBpZiAoJG9wZW4gPSAnLycgIT0gJHRleHRbMV0pIHsKICAgICAgICAgICAgICAgICR0YWcgPSAkbWF0Y2hlc1sxXVskaV1bMF07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGFnID0gaXNzZXQoJG1hdGNoZXNbM11bJGldWzBdKSA/ICRtYXRjaGVzWzNdWyRpXVswXSA6ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRvcGVuICYmICEkdGFnKSB7CiAgICAgICAgICAgICAgICAvLyA8Lz4KICAgICAgICAgICAgICAgICR0aGlzLT5zdHlsZVN0YWNrLT5wb3AoKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGZhbHNlID09PSAkc3R5bGUgPSAkdGhpcy0+Y3JlYXRlU3R5bGVGcm9tU3RyaW5nKCR0YWcpKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR0aGlzLT5hcHBseUN1cnJlbnRTdHlsZSgkdGV4dCk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkb3BlbikgewogICAgICAgICAgICAgICAgJHRoaXMtPnN0eWxlU3RhY2stPnB1c2goJHN0eWxlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdHlsZVN0YWNrLT5wb3AoJHN0eWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG91dHB1dCAuPSAkdGhpcy0+YXBwbHlDdXJyZW50U3R5bGUoc3Vic3RyKCRtZXNzYWdlLCAkb2Zmc2V0KSk7CgogICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCRvdXRwdXQsICJcMCIpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJ0cigkb3V0cHV0LCBbIlwwIiA9PiAnXFwnLCAnXFw8JyA9PiAnPCddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgnXFw8JywgJzwnLCAkb3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gT3V0cHV0Rm9ybWF0dGVyU3R5bGVTdGFjawogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3R5bGVTdGFjaygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdHlsZVN0YWNrOwogICAgfQoKICAgIC8qKgogICAgICogVHJpZXMgdG8gY3JlYXRlIG5ldyBzdHlsZSBpbnN0YW5jZSBmcm9tIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEZvcm1hdHRlclN0eWxlfGZhbHNlIGZhbHNlIGlmIHN0cmluZyBpcyBub3QgZm9ybWF0IHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVN0eWxlRnJvbVN0cmluZygkc3RyaW5nKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+c3R5bGVzWyRzdHJpbmddKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0eWxlc1skc3RyaW5nXTsKICAgICAgICB9CgogICAgICAgIGlmICghcHJlZ19tYXRjaF9hbGwoJy8oW149XSspPShbXjtdKykoO3wkKS8nLCAkc3RyaW5nLCAkbWF0Y2hlcywgXFBSRUdfU0VUX09SREVSKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkc3R5bGUgPSBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoKTsKICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgYXJyYXlfc2hpZnQoJG1hdGNoKTsKICAgICAgICAgICAgJG1hdGNoWzBdID0gc3RydG9sb3dlcigkbWF0Y2hbMF0pOwoKICAgICAgICAgICAgaWYgKCdmZycgPT0gJG1hdGNoWzBdKSB7CiAgICAgICAgICAgICAgICAkc3R5bGUtPnNldEZvcmVncm91bmQoc3RydG9sb3dlcigkbWF0Y2hbMV0pKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCdiZycgPT0gJG1hdGNoWzBdKSB7CiAgICAgICAgICAgICAgICAkc3R5bGUtPnNldEJhY2tncm91bmQoc3RydG9sb3dlcigkbWF0Y2hbMV0pKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCdvcHRpb25zJyA9PT0gJG1hdGNoWzBdKSB7CiAgICAgICAgICAgICAgICBwcmVnX21hdGNoX2FsbCgnKFteLDtdKyknLCBzdHJ0b2xvd2VyKCRtYXRjaFsxXSksICRvcHRpb25zKTsKICAgICAgICAgICAgICAgICRvcHRpb25zID0gYXJyYXlfc2hpZnQoJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG9wdGlvbnMgYXMgJG9wdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzdHlsZS0+c2V0T3B0aW9uKCRvcHRpb24pOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVW5rbm93biBzdHlsZSBvcHRpb25zIGFyZSBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4yIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBFeGNlcHRpb24gIiVzIi4nLCAkZS0+Z2V0TWVzc2FnZSgpKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3R5bGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBcHBsaWVzIGN1cnJlbnQgc3R5bGUgZnJvbSBzdGFjayB0byB0ZXh0LCBpZiBtdXN0IGJlIGFwcGxpZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGV4dCBJbnB1dCB0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgU3R5bGVkIHRleHQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhcHBseUN1cnJlbnRTdHlsZSgkdGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzRGVjb3JhdGVkKCkgJiYgXHN0cmxlbigkdGV4dCkgPiAwID8gJHRoaXMtPnN0eWxlU3RhY2stPmdldEN1cnJlbnQoKS0+YXBwbHkoJHRleHQpIDogJHRleHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKZWFuLUZyYW7Dp29pcyBTaW1vbiA8Y29udGFjdEBqZnNpbW9uLmZyPgogKi8KY2xhc3MgT3V0cHV0Rm9ybWF0dGVyU3R5bGVTdGFjawp7CiAgICAvKioKICAgICAqIEB2YXIgT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlICRzdHlsZXM7CgogICAgcHJpdmF0ZSAkZW1wdHlTdHlsZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UgJGVtcHR5U3R5bGUgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5lbXB0eVN0eWxlID0gJGVtcHR5U3R5bGUgPzogbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCk7CiAgICAgICAgJHRoaXMtPnJlc2V0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXNldHMgc3RhY2sgKGllLiBlbXB0eSBpbnRlcm5hbCBhcnJheXMpLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXQoKQogICAgewogICAgICAgICR0aGlzLT5zdHlsZXMgPSBbXTsKICAgIH0KCiAgICAvKioKICAgICAqIFB1c2hlcyBhIHN0eWxlIGluIHRoZSBzdGFjay4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHB1c2goT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UgJHN0eWxlKQogICAgewogICAgICAgICR0aGlzLT5zdHlsZXNbXSA9ICRzdHlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFBvcHMgYSBzdHlsZSBmcm9tIHRoZSBzdGFjay4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBzdHlsZSB0YWdzIGluY29ycmVjdGx5IG5lc3RlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcG9wKE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlICRzdHlsZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5zdHlsZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZW1wdHlTdHlsZTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkc3R5bGUpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5X3BvcCgkdGhpcy0+c3R5bGVzKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKGFycmF5X3JldmVyc2UoJHRoaXMtPnN0eWxlcywgdHJ1ZSkgYXMgJGluZGV4ID0+ICRzdGFja2VkU3R5bGUpIHsKICAgICAgICAgICAgaWYgKCRzdHlsZS0+YXBwbHkoJycpID09PSAkc3RhY2tlZFN0eWxlLT5hcHBseSgnJykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdHlsZXMgPSBcYXJyYXlfc2xpY2UoJHRoaXMtPnN0eWxlcywgMCwgJGluZGV4KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHN0YWNrZWRTdHlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignSW5jb3JyZWN0bHkgbmVzdGVkIHN0eWxlIHRhZyBmb3VuZC4nKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbXB1dGVzIGN1cnJlbnQgc3R5bGUgd2l0aCBzdGFja3MgdG9wIGNvZGVzLgogICAgICoKICAgICAqIEByZXR1cm4gT3V0cHV0Rm9ybWF0dGVyU3R5bGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEN1cnJlbnQoKQogICAgewogICAgICAgIGlmIChlbXB0eSgkdGhpcy0+c3R5bGVzKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVtcHR5U3R5bGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnN0eWxlc1tcY291bnQoJHRoaXMtPnN0eWxlcykgLSAxXTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVtcHR5U3R5bGUoT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UgJGVtcHR5U3R5bGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmVtcHR5U3R5bGUgPSAkZW1wdHlTdHlsZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RW1wdHlTdHlsZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lbXB0eVN0eWxlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXI7CgovKioKICogRm9ybWF0dGVyIGludGVyZmFjZSBmb3IgY29uc29sZSBvdXRwdXQuCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVjb3JhdGVkIGZsYWcuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGRlY29yYXRlZCBXaGV0aGVyIHRvIGRlY29yYXRlIHRoZSBtZXNzYWdlcyBvciBub3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlY29yYXRlZCgkZGVjb3JhdGVkKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRlY29yYXRlZCBmbGFnLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBvdXRwdXQgd2lsbCBkZWNvcmF0ZSBtZXNzYWdlcywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlY29yYXRlZCgpOwoKICAgIC8qKgogICAgICogU2V0cyBhIG5ldyBzdHlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgJG5hbWUgIFRoZSBzdHlsZSBuYW1lCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UgJHN0eWxlIFRoZSBzdHlsZSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3R5bGUoJG5hbWUsIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlICRzdHlsZSk7CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgb3V0cHV0IGZvcm1hdHRlciBoYXMgc3R5bGUgd2l0aCBzcGVjaWZpZWQgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNTdHlsZSgkbmFtZSk7CgogICAgLyoqCiAgICAgKiBHZXRzIHN0eWxlIG9wdGlvbnMgZnJvbSBzdHlsZSB3aXRoIHNwZWNpZmllZCBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gc3R5bGUgaXNuJ3QgZGVmaW5lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3R5bGUoJG5hbWUpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIG1lc3NhZ2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBzdHlsZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBzdHlsZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBzdHlsZWQgbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZm9ybWF0KCRtZXNzYWdlKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEFsbG93cyB0byBtYW5pcHVsYXRlIHRoZSBleGl0IGNvZGUgb2YgYSBjb21tYW5kIGFmdGVyIGl0cyBleGVjdXRpb24uCiAqCiAqIEBhdXRob3IgRnJhbmNlc2NvIExldm9yYXRvIDxnaXRAZmxldm91ci5uZXQ+CiAqLwpjbGFzcyBDb25zb2xlVGVybWluYXRlRXZlbnQgZXh0ZW5kcyBDb25zb2xlRXZlbnQKewogICAgLyoqCiAgICAgKiBUaGUgZXhpdCBjb2RlIG9mIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByaXZhdGUgJGV4aXRDb2RlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDb21tYW5kICRjb21tYW5kLCBJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkZXhpdENvZGUpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkY29tbWFuZCwgJGlucHV0LCAkb3V0cHV0KTsKCiAgICAgICAgJHRoaXMtPnNldEV4aXRDb2RlKCRleGl0Q29kZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleGl0IGNvZGUuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkZXhpdENvZGUgVGhlIGNvbW1hbmQgZXhpdCBjb2RlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeGl0Q29kZSgkZXhpdENvZGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4aXRDb2RlID0gKGludCkgJGV4aXRDb2RlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZXhpdCBjb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBjb21tYW5kIGV4aXQgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhpdENvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXhpdENvZGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEV2ZW50RGlzcGF0Y2hlclxFdmVudDsKCi8qKgogKiBBbGxvd3MgdG8gaW5zcGVjdCBpbnB1dCBhbmQgb3V0cHV0IG9mIGEgY29tbWFuZC4KICoKICogQGF1dGhvciBGcmFuY2VzY28gTGV2b3JhdG8gPGdpdEBmbGV2b3VyLm5ldD4KICovCmNsYXNzIENvbnNvbGVFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIHByb3RlY3RlZCAkY29tbWFuZDsKCiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJG91dHB1dDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29tbWFuZCAkY29tbWFuZCA9IG51bGwsIElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbW1hbmQgPSAkY29tbWFuZDsKICAgICAgICAkdGhpcy0+aW5wdXQgPSAkaW5wdXQ7CiAgICAgICAgJHRoaXMtPm91dHB1dCA9ICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb21tYW5kIHRoYXQgaXMgZXhlY3V0ZWQuCiAgICAgKgogICAgICogQHJldHVybiBDb21tYW5kfG51bGwgQSBDb21tYW5kIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBpbnB1dCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0SW50ZXJmYWNlIEFuIElucHV0SW50ZXJmYWNlIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG91dHB1dCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZSBBbiBPdXRwdXRJbnRlcmZhY2UgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE91dHB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50OwoKQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICIlcyIgY2xhc3MgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gVXNlIHRoZSBDb25zb2xlRXJyb3JFdmVudCBpbnN0ZWFkLicsIENvbnNvbGVFeGNlcHRpb25FdmVudDo6Y2xhc3MpLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBBbGxvd3MgdG8gaGFuZGxlIGV4Y2VwdGlvbiB0aHJvd24gaW4gYSBjb21tYW5kLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjMsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgQ29uc29sZUVycm9yRXZlbnQgaW5zdGVhZC4KICovCmNsYXNzIENvbnNvbGVFeGNlcHRpb25FdmVudCBleHRlbmRzIENvbnNvbGVFdmVudAp7CiAgICBwcml2YXRlICRleGNlcHRpb247CiAgICBwcml2YXRlICRleGl0Q29kZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29tbWFuZCAkY29tbWFuZCwgSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgXEV4Y2VwdGlvbiAkZXhjZXB0aW9uLCAkZXhpdENvZGUpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkY29tbWFuZCwgJGlucHV0LCAkb3V0cHV0KTsKCiAgICAgICAgJHRoaXMtPnNldEV4Y2VwdGlvbigkZXhjZXB0aW9uKTsKICAgICAgICAkdGhpcy0+ZXhpdENvZGUgPSAoaW50KSAkZXhpdENvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0aHJvd24gZXhjZXB0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gXEV4Y2VwdGlvbiBUaGUgdGhyb3duIGV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhjZXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4Y2VwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcGxhY2VzIHRoZSB0aHJvd24gZXhjZXB0aW9uLgogICAgICoKICAgICAqIFRoaXMgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIGlmIG5vIHJlc3BvbnNlIGlzIHNldCBpbiB0aGUgZXZlbnQuCiAgICAgKgogICAgICogQHBhcmFtIFxFeGNlcHRpb24gJGV4Y2VwdGlvbiBUaGUgdGhyb3duIGV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhjZXB0aW9uKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+ZXhjZXB0aW9uID0gJGV4Y2VwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGV4aXQgY29kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgY29tbWFuZCBleGl0IGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4aXRDb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4aXRDb2RlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQWxsb3dzIHRvIGhhbmRsZSB0aHJvd2FibGVzIHRocm93biB3aGlsZSBydW5uaW5nIGEgY29tbWFuZC4KICoKICogQGF1dGhvciBXb3V0ZXIgZGUgSm9uZyA8d291dGVyQHdvdXRlcmoubmw+CiAqLwpmaW5hbCBjbGFzcyBDb25zb2xlRXJyb3JFdmVudCBleHRlbmRzIENvbnNvbGVFdmVudAp7CiAgICBwcml2YXRlICRlcnJvcjsKICAgIHByaXZhdGUgJGV4aXRDb2RlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkZXJyb3IsIENvbW1hbmQgJGNvbW1hbmQgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGNvbW1hbmQsICRpbnB1dCwgJG91dHB1dCk7CgogICAgICAgICR0aGlzLT5zZXRFcnJvcigkZXJyb3IpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGhyb3duIGVycm9yL2V4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIFxUaHJvd2FibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgdGhlIHRocm93biBlcnJvci9leGNlcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIFxUaHJvd2FibGUgJGVycm9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFcnJvcigkZXJyb3IpCiAgICB7CiAgICAgICAgaWYgKCEkZXJyb3IgaW5zdGFuY2VvZiBcVGhyb3dhYmxlICYmICEkZXJyb3IgaW5zdGFuY2VvZiBcRXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIGVycm9yIHBhc3NlZCB0byBDb25zb2xlRXJyb3JFdmVudCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIFxUaHJvd2FibGUgb3IgXEV4Y2VwdGlvbiwgIiVzIiB3YXMgcGFzc2VkIGluc3RlYWQuJywgXGlzX29iamVjdCgkZXJyb3IpID8gXGdldF9jbGFzcygkZXJyb3IpIDogXGdldHR5cGUoJGVycm9yKSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmVycm9yID0gJGVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhpdCBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGV4aXRDb2RlIFRoZSBjb21tYW5kIGV4aXQgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhpdENvZGUoJGV4aXRDb2RlKQogICAgewogICAgICAgICR0aGlzLT5leGl0Q29kZSA9IChpbnQpICRleGl0Q29kZTsKCiAgICAgICAgJHIgPSBuZXcgXFJlZmxlY3Rpb25Qcm9wZXJ0eSgkdGhpcy0+ZXJyb3IsICdjb2RlJyk7CiAgICAgICAgJHItPnNldEFjY2Vzc2libGUodHJ1ZSk7CiAgICAgICAgJHItPnNldFZhbHVlKCR0aGlzLT5lcnJvciwgJHRoaXMtPmV4aXRDb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGV4aXQgY29kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgY29tbWFuZCBleGl0IGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4aXRDb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gbnVsbCAhPT0gJHRoaXMtPmV4aXRDb2RlID8gJHRoaXMtPmV4aXRDb2RlIDogKFxpc19pbnQoJHRoaXMtPmVycm9yLT5nZXRDb2RlKCkpICYmIDAgIT09ICR0aGlzLT5lcnJvci0+Z2V0Q29kZSgpID8gJHRoaXMtPmVycm9yLT5nZXRDb2RlKCkgOiAxKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnQ7CgovKioKICogQWxsb3dzIHRvIGRvIHRoaW5ncyBiZWZvcmUgdGhlIGNvbW1hbmQgaXMgZXhlY3V0ZWQsIGxpa2Ugc2tpcHBpbmcgdGhlIGNvbW1hbmQgb3IgY2hhbmdpbmcgdGhlIGlucHV0LgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIENvbnNvbGVDb21tYW5kRXZlbnQgZXh0ZW5kcyBDb25zb2xlRXZlbnQKewogICAgLyoqCiAgICAgKiBUaGUgcmV0dXJuIGNvZGUgZm9yIHNraXBwZWQgY29tbWFuZHMsIHRoaXMgd2lsbCBhbHNvIGJlIHBhc3NlZCBpbnRvIHRoZSB0ZXJtaW5hdGUgZXZlbnQuCiAgICAgKi8KICAgIGNvbnN0IFJFVFVSTl9DT0RFX0RJU0FCTEVEID0gMTEzOwoKICAgIC8qKgogICAgICogSW5kaWNhdGVzIGlmIHRoZSBjb21tYW5kIHNob3VsZCBiZSBydW4gb3Igc2tpcHBlZC4KICAgICAqLwogICAgcHJpdmF0ZSAkY29tbWFuZFNob3VsZFJ1biA9IHRydWU7CgogICAgLyoqCiAgICAgKiBEaXNhYmxlcyB0aGUgY29tbWFuZCwgc28gaXQgd29uJ3QgYmUgcnVuLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZUNvbW1hbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWFuZFNob3VsZFJ1biA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlcyB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZUNvbW1hbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWFuZFNob3VsZFJ1biA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNvbW1hbmQgaXMgcnVubmFibGUsIGZhbHNlIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbW1hbmRTaG91bGRSdW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWFuZFNob3VsZFJ1bjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGU7CgovKioKICogQ29udGFpbnMgYWxsIGV2ZW50cyBkaXNwYXRjaGVkIGJ5IGFuIEFwcGxpY2F0aW9uLgogKgogKiBAYXV0aG9yIEZyYW5jZXNjbyBMZXZvcmF0byA8Z2l0QGZsZXZvdXIubmV0PgogKi8KZmluYWwgY2xhc3MgQ29uc29sZUV2ZW50cwp7CiAgICAvKioKICAgICAqIFRoZSBDT01NQU5EIGV2ZW50IGFsbG93cyB5b3UgdG8gYXR0YWNoIGxpc3RlbmVycyBiZWZvcmUgYW55IGNvbW1hbmQgaXMKICAgICAqIGV4ZWN1dGVkIGJ5IHRoZSBjb25zb2xlLiBJdCBhbHNvIGFsbG93cyB5b3UgdG8gbW9kaWZ5IHRoZSBjb21tYW5kLCBpbnB1dCBhbmQgb3V0cHV0CiAgICAgKiBiZWZvcmUgdGhleSBhcmUgaGFuZGxlZCB0byB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBARXZlbnQoIlN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZUNvbW1hbmRFdmVudCIpCiAgICAgKi8KICAgIGNvbnN0IENPTU1BTkQgPSAnY29uc29sZS5jb21tYW5kJzsKCiAgICAvKioKICAgICAqIFRoZSBURVJNSU5BVEUgZXZlbnQgYWxsb3dzIHlvdSB0byBhdHRhY2ggbGlzdGVuZXJzIGFmdGVyIGEgY29tbWFuZCBpcwogICAgICogZXhlY3V0ZWQgYnkgdGhlIGNvbnNvbGUuCiAgICAgKgogICAgICogQEV2ZW50KCJTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50XENvbnNvbGVUZXJtaW5hdGVFdmVudCIpCiAgICAgKi8KICAgIGNvbnN0IFRFUk1JTkFURSA9ICdjb25zb2xlLnRlcm1pbmF0ZSc7CgogICAgLyoqCiAgICAgKiBUaGUgRVhDRVBUSU9OIGV2ZW50IG9jY3VycyB3aGVuIGFuIHVuY2F1Z2h0IGV4Y2VwdGlvbiBhcHBlYXJzCiAgICAgKiB3aGlsZSBleGVjdXRpbmcgQ29tbWFuZCNydW4oKS4KICAgICAqCiAgICAgKiBUaGlzIGV2ZW50IGFsbG93cyB5b3UgdG8gZGVhbCB3aXRoIHRoZSBleGNlcHRpb24gb3IKICAgICAqIHRvIG1vZGlmeSB0aGUgdGhyb3duIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBARXZlbnQoIlN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZUV4Y2VwdGlvbkV2ZW50IikKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBUaGUgY29uc29sZS5leGNlcHRpb24gZXZlbnQgaXMgZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gVXNlIHRoZSBjb25zb2xlLmVycm9yIGV2ZW50IGluc3RlYWQuCiAgICAgKi8KICAgIGNvbnN0IEVYQ0VQVElPTiA9ICdjb25zb2xlLmV4Y2VwdGlvbic7CgogICAgLyoqCiAgICAgKiBUaGUgRVJST1IgZXZlbnQgb2NjdXJzIHdoZW4gYW4gdW5jYXVnaHQgZXhjZXB0aW9uIG9yIGVycm9yIGFwcGVhcnMuCiAgICAgKgogICAgICogVGhpcyBldmVudCBhbGxvd3MgeW91IHRvIGRlYWwgd2l0aCB0aGUgZXhjZXB0aW9uL2Vycm9yIG9yCiAgICAgKiB0byBtb2RpZnkgdGhlIHRocm93biBleGNlcHRpb24uCiAgICAgKgogICAgICogQEV2ZW50KCJTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50XENvbnNvbGVFcnJvckV2ZW50IikKICAgICAqLwogICAgY29uc3QgRVJST1IgPSAnY29uc29sZS5lcnJvcic7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXI7CgovKioKICogRXh0ZW5kcyBcU3BsRmlsZUluZm8gdG8gc3VwcG9ydCByZWxhdGl2ZSBwYXRocy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBTcGxGaWxlSW5mbyBleHRlbmRzIFxTcGxGaWxlSW5mbwp7CiAgICBwcml2YXRlICRyZWxhdGl2ZVBhdGg7CiAgICBwcml2YXRlICRyZWxhdGl2ZVBhdGhuYW1lOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSAgICAgICAgICAgICBUaGUgZmlsZSBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWxhdGl2ZVBhdGggICAgIFRoZSByZWxhdGl2ZSBwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWxhdGl2ZVBhdGhuYW1lIFRoZSByZWxhdGl2ZSBwYXRoIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRmaWxlLCAkcmVsYXRpdmVQYXRoLCAkcmVsYXRpdmVQYXRobmFtZSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRmaWxlKTsKICAgICAgICAkdGhpcy0+cmVsYXRpdmVQYXRoID0gJHJlbGF0aXZlUGF0aDsKICAgICAgICAkdGhpcy0+cmVsYXRpdmVQYXRobmFtZSA9ICRyZWxhdGl2ZVBhdGhuYW1lOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVsYXRpdmUgcGF0aC4KICAgICAqCiAgICAgKiBUaGlzIHBhdGggZG9lcyBub3QgY29udGFpbiB0aGUgZmlsZSBuYW1lLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHRoZSByZWxhdGl2ZSBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWxhdGl2ZVBhdGgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVsYXRpdmVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVsYXRpdmUgcGF0aCBuYW1lLgogICAgICoKICAgICAqIFRoaXMgcGF0aCBjb250YWlucyB0aGUgZmlsZSBuYW1lLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHRoZSByZWxhdGl2ZSBwYXRoIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlbGF0aXZlUGF0aG5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVsYXRpdmVQYXRobmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWxlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZQogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRlbnRzKCkKICAgIHsKICAgICAgICBzZXRfZXJyb3JfaGFuZGxlcihmdW5jdGlvbiAoJHR5cGUsICRtc2cpIHVzZSAoJiRlcnJvcikgeyAkZXJyb3IgPSAkbXNnOyB9KTsKICAgICAgICAkY29udGVudCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5nZXRQYXRobmFtZSgpKTsKICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRjb250ZW50KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkZXJyb3IpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb250ZW50OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqCiAqIEBkZXByZWNhdGVkIHNpbmNlIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuCiAqLwppbnRlcmZhY2UgRXhjZXB0aW9uSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHJldHVybiBcU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEFkYXB0ZXJcQWRhcHRlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWRhcHRlcigpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxqZWFuZnJhbmNvaXMuc2ltb25Ac2Vuc2lvbGFicy5jb20+CiAqLwpjbGFzcyBBY2Nlc3NEZW5pZWRFeGNlcHRpb24gZXh0ZW5kcyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxDb21wYXJhdG9yOwoKLyoqCiAqIERhdGVDb21wYXJlIGNvbXBpbGVzIGRhdGUgY29tcGFyaXNvbnMuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRGF0ZUNvbXBhcmF0b3IgZXh0ZW5kcyBDb21wYXJhdG9yCnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdGVzdCBBIGNvbXBhcmlzb24gc3RyaW5nCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB0ZXN0IGlzIG5vdCB1bmRlcnN0b29kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdGVzdCkKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJyNeXHMqKD09fCE9fFs8Pl09P3xhZnRlcnxzaW5jZXxiZWZvcmV8dW50aWwpP1xzKiguKz8pXHMqJCNpJywgJHRlc3QsICRtYXRjaGVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdEb25cJ3QgdW5kZXJzdGFuZCAiJXMiIGFzIGEgZGF0ZSB0ZXN0LicsICR0ZXN0KSk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICAkZGF0ZSA9IG5ldyBcRGF0ZVRpbWUoJG1hdGNoZXNbMl0pOwogICAgICAgICAgICAkdGFyZ2V0ID0gJGRhdGUtPmZvcm1hdCgnVScpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignIiVzIiBpcyBub3QgYSB2YWxpZCBkYXRlLicsICRtYXRjaGVzWzJdKSk7CiAgICAgICAgfQoKICAgICAgICAkb3BlcmF0b3IgPSBpc3NldCgkbWF0Y2hlc1sxXSkgPyAkbWF0Y2hlc1sxXSA6ICc9PSc7CiAgICAgICAgaWYgKCdzaW5jZScgPT09ICRvcGVyYXRvciB8fCAnYWZ0ZXInID09PSAkb3BlcmF0b3IpIHsKICAgICAgICAgICAgJG9wZXJhdG9yID0gJz4nOwogICAgICAgIH0KCiAgICAgICAgaWYgKCd1bnRpbCcgPT09ICRvcGVyYXRvciB8fCAnYmVmb3JlJyA9PT0gJG9wZXJhdG9yKSB7CiAgICAgICAgICAgICRvcGVyYXRvciA9ICc8JzsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXRPcGVyYXRvcigkb3BlcmF0b3IpOwogICAgICAgICR0aGlzLT5zZXRUYXJnZXQoJHRhcmdldCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcQ29tcGFyYXRvcjsKCi8qKgogKiBDb21wYXJhdG9yLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIENvbXBhcmF0b3IKewogICAgcHJpdmF0ZSAkdGFyZ2V0OwogICAgcHJpdmF0ZSAkb3BlcmF0b3IgPSAnPT0nOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGFyZ2V0IHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSB0YXJnZXQgdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhcmdldCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50YXJnZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0YXJnZXQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0IFRoZSB0YXJnZXQgdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRhcmdldCgkdGFyZ2V0KQogICAgewogICAgICAgICR0aGlzLT50YXJnZXQgPSAkdGFyZ2V0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY29tcGFyaXNvbiBvcGVyYXRvci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgb3BlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZXJhdG9yOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29tcGFyaXNvbiBvcGVyYXRvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvciBBIHZhbGlkIG9wZXJhdG9yCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcGVyYXRvcigkb3BlcmF0b3IpCiAgICB7CiAgICAgICAgaWYgKCEkb3BlcmF0b3IpIHsKICAgICAgICAgICAgJG9wZXJhdG9yID0gJz09JzsKICAgICAgICB9CgogICAgICAgIGlmICghXGluX2FycmF5KCRvcGVyYXRvciwgWyc+JywgJzwnLCAnPj0nLCAnPD0nLCAnPT0nLCAnIT0nXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignSW52YWxpZCBvcGVyYXRvciAiJXMiLicsICRvcGVyYXRvcikpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wZXJhdG9yID0gJG9wZXJhdG9yOwogICAgfQoKICAgIC8qKgogICAgICogVGVzdHMgYWdhaW5zdCB0aGUgdGFyZ2V0LgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdGVzdCBBIHRlc3QgdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRlc3QoJHRlc3QpCiAgICB7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+b3BlcmF0b3IpIHsKICAgICAgICAgICAgY2FzZSAnPic6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRlc3QgPiAkdGhpcy0+dGFyZ2V0OwogICAgICAgICAgICBjYXNlICc+PSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRlc3QgPj0gJHRoaXMtPnRhcmdldDsKICAgICAgICAgICAgY2FzZSAnPCc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRlc3QgPCAkdGhpcy0+dGFyZ2V0OwogICAgICAgICAgICBjYXNlICc8PSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRlc3QgPD0gJHRoaXMtPnRhcmdldDsKICAgICAgICAgICAgY2FzZSAnIT0nOgogICAgICAgICAgICAgICAgcmV0dXJuICR0ZXN0ICE9ICR0aGlzLT50YXJnZXQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRlc3QgPT0gJHRoaXMtPnRhcmdldDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxDb21wYXJhdG9yOwoKLyoqCiAqIE51bWJlckNvbXBhcmF0b3IgY29tcGlsZXMgYSBzaW1wbGUgY29tcGFyaXNvbiB0byBhbiBhbm9ueW1vdXMKICogc3Vicm91dGluZSwgd2hpY2ggeW91IGNhbiBjYWxsIHdpdGggYSB2YWx1ZSB0byBiZSB0ZXN0ZWQgYWdhaW4uCiAqCiAqIE5vdyB0aGlzIHdvdWxkIGJlIHZlcnkgcG9pbnRsZXNzLCBpZiBOdW1iZXJDb21wYXJlIGRpZG4ndCB1bmRlcnN0YW5kCiAqIG1hZ25pdHVkZXMuCiAqCiAqIFRoZSB0YXJnZXQgdmFsdWUgbWF5IHVzZSBtYWduaXR1ZGVzIG9mIGtpbG9ieXRlcyAoaywga2kpLAogKiBtZWdhYnl0ZXMgKG0sIG1pKSwgb3IgZ2lnYWJ5dGVzIChnLCBnaSkuICBUaG9zZSBzdWZmaXhlZAogKiB3aXRoIGFuIGkgdXNlIHRoZSBhcHByb3ByaWF0ZSAyKipuIHZlcnNpb24gaW4gYWNjb3JkYW5jZSB3aXRoIHRoZQogKiBJRUMgc3RhbmRhcmQ6IGh0dHA6Ly9waHlzaWNzLm5pc3QuZ292L2N1dS9Vbml0cy9iaW5hcnkuaHRtbAogKgogKiBCYXNlZCBvbiB0aGUgUGVybCBOdW1iZXI6OkNvbXBhcmUgbW9kdWxlLgogKgogKiBAYXV0aG9yICAgIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4gUEhQIHBvcnQKICogQGF1dGhvciAgICBSaWNoYXJkIENsYW1wIDxyaWNoYXJkY0B1bml4YmVhcmQubmV0PiBQZXJsIHZlcnNpb24KICogQGNvcHlyaWdodCAyMDA0LTIwMDUgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAY29weXJpZ2h0IDIwMDIgUmljaGFyZCBDbGFtcCA8cmljaGFyZGNAdW5peGJlYXJkLm5ldD4KICoKICogQHNlZSBodHRwOi8vcGh5c2ljcy5uaXN0Lmdvdi9jdXUvVW5pdHMvYmluYXJ5Lmh0bWwKICovCmNsYXNzIE51bWJlckNvbXBhcmF0b3IgZXh0ZW5kcyBDb21wYXJhdG9yCnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRlc3QgQSBjb21wYXJpc29uIHN0cmluZyBvciBhbiBpbnRlZ2VyCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB0ZXN0IGlzIG5vdCB1bmRlcnN0b29kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdGVzdCkKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJyNeXHMqKD09fCE9fFs8Pl09Pyk/XHMqKFswLTlcLl0rKVxzKihba21nXWk/KT9ccyokI2knLCAkdGVzdCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0RvblwndCB1bmRlcnN0YW5kICIlcyIgYXMgYSBudW1iZXIgdGVzdC4nLCAkdGVzdCkpOwogICAgICAgIH0KCiAgICAgICAgJHRhcmdldCA9ICRtYXRjaGVzWzJdOwogICAgICAgIGlmICghaXNfbnVtZXJpYygkdGFyZ2V0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdJbnZhbGlkIG51bWJlciAiJXMiLicsICR0YXJnZXQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWzNdKSkgewogICAgICAgICAgICAvLyBtYWduaXR1ZGUKICAgICAgICAgICAgc3dpdGNoIChzdHJ0b2xvd2VyKCRtYXRjaGVzWzNdKSkgewogICAgICAgICAgICAgICAgY2FzZSAnayc6CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldCAqPSAxMDAwOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAna2knOgogICAgICAgICAgICAgICAgICAgICR0YXJnZXQgKj0gMTAyNDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ20nOgogICAgICAgICAgICAgICAgICAgICR0YXJnZXQgKj0gMTAwMDAwMDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ21pJzoKICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ICo9IDEwMjQgKiAxMDI0OwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnZyc6CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldCAqPSAxMDAwMDAwMDAwOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnZ2knOgogICAgICAgICAgICAgICAgICAgICR0YXJnZXQgKj0gMTAyNCAqIDEwMjQgKiAxMDI0OwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0VGFyZ2V0KCR0YXJnZXQpOwogICAgICAgICR0aGlzLT5zZXRPcGVyYXRvcihpc3NldCgkbWF0Y2hlc1sxXSkgPyAkbWF0Y2hlc1sxXSA6ICc9PScpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxDb21wYXJhdG9yXERhdGVDb21wYXJhdG9yOwoKLyoqCiAqIERhdGVSYW5nZUZpbHRlckl0ZXJhdG9yIGZpbHRlcnMgb3V0IGZpbGVzIHRoYXQgYXJlIG5vdCBpbiB0aGUgZ2l2ZW4gZGF0ZSByYW5nZSAobGFzdCBtb2RpZmllZCBkYXRlcykuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRGF0ZVJhbmdlRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBGaWx0ZXJJdGVyYXRvcgp7CiAgICBwcml2YXRlICRjb21wYXJhdG9ycyA9IFtdOwoKICAgIC8qKgogICAgICogQHBhcmFtIFxJdGVyYXRvciAgICAgICAgJGl0ZXJhdG9yICAgIFRoZSBJdGVyYXRvciB0byBmaWx0ZXIKICAgICAqIEBwYXJhbSBEYXRlQ29tcGFyYXRvcltdICRjb21wYXJhdG9ycyBBbiBhcnJheSBvZiBEYXRlQ29tcGFyYXRvciBpbnN0YW5jZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFxJdGVyYXRvciAkaXRlcmF0b3IsIGFycmF5ICRjb21wYXJhdG9ycykKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcGFyYXRvcnMgPSAkY29tcGFyYXRvcnM7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGl0ZXJhdG9yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICAkZmlsZWluZm8gPSAkdGhpcy0+Y3VycmVudCgpOwoKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRmaWxlaW5mby0+Z2V0UGF0aG5hbWUoKSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGZpbGVkYXRlID0gJGZpbGVpbmZvLT5nZXRNVGltZSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb21wYXJhdG9ycyBhcyAkY29tcGFyZSkgewogICAgICAgICAgICBpZiAoISRjb21wYXJlLT50ZXN0KCRmaWxlZGF0ZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3I7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEV4Y2VwdGlvblxBY2Nlc3NEZW5pZWRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcU3BsRmlsZUluZm87CgovKioKICogRXh0ZW5kcyB0aGUgXFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yIHRvIHN1cHBvcnQgcmVsYXRpdmUgcGF0aHMuCiAqCiAqIEBhdXRob3IgVmljdG9yIEJlcmNoZXQgPHZpY3RvckBzdXVtaXQuY29tPgogKi8KY2xhc3MgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IgZXh0ZW5kcyBcUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IKewogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkaWdub3JlVW5yZWFkYWJsZURpcnM7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkcmV3aW5kYWJsZTsKCiAgICAvLyB0aGVzZSAzIHByb3BlcnRpZXMgdGFrZSBwYXJ0IG9mIHRoZSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gdG8gYXZvaWQgcmVkb2luZyB0aGUgc2FtZSB3b3JrIGluIGFsbCBpdGVyYXRpb25zCiAgICBwcml2YXRlICRyb290UGF0aDsKICAgIHByaXZhdGUgJHN1YlBhdGg7CiAgICBwcml2YXRlICRkaXJlY3RvcnlTZXBhcmF0b3IgPSAnLyc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKiBAcGFyYW0gaW50ICAgICRmbGFncwogICAgICogQHBhcmFtIGJvb2wgICAkaWdub3JlVW5yZWFkYWJsZURpcnMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcGF0aCwgJGZsYWdzLCAkaWdub3JlVW5yZWFkYWJsZURpcnMgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJGZsYWdzICYgKHNlbGY6OkNVUlJFTlRfQVNfUEFUSE5BTUUgfCBzZWxmOjpDVVJSRU5UX0FTX1NFTEYpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhpcyBpdGVyYXRvciBvbmx5IHN1cHBvcnQgcmV0dXJuaW5nIGN1cnJlbnQgYXMgZmlsZWluZm8uJyk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRwYXRoLCAkZmxhZ3MpOwogICAgICAgICR0aGlzLT5pZ25vcmVVbnJlYWRhYmxlRGlycyA9ICRpZ25vcmVVbnJlYWRhYmxlRGlyczsKICAgICAgICAkdGhpcy0+cm9vdFBhdGggPSAkcGF0aDsKICAgICAgICBpZiAoJy8nICE9PSBcRElSRUNUT1JZX1NFUEFSQVRPUiAmJiAhKCRmbGFncyAmIHNlbGY6OlVOSVhfUEFUSFMpKSB7CiAgICAgICAgICAgICR0aGlzLT5kaXJlY3RvcnlTZXBhcmF0b3IgPSBcRElSRUNUT1JZX1NFUEFSQVRPUjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYW4gaW5zdGFuY2Ugb2YgU3BsRmlsZUluZm8gd2l0aCBzdXBwb3J0IGZvciByZWxhdGl2ZSBwYXRocy4KICAgICAqCiAgICAgKiBAcmV0dXJuIFNwbEZpbGVJbmZvIEZpbGUgaW5mb3JtYXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKQogICAgewogICAgICAgIC8vIHRoZSBsb2dpYyBoZXJlIGF2b2lkcyByZWRvaW5nIHRoZSBzYW1lIHdvcmsgaW4gYWxsIGl0ZXJhdGlvbnMKCiAgICAgICAgaWYgKG51bGwgPT09ICRzdWJQYXRobmFtZSA9ICR0aGlzLT5zdWJQYXRoKSB7CiAgICAgICAgICAgICRzdWJQYXRobmFtZSA9ICR0aGlzLT5zdWJQYXRoID0gKHN0cmluZykgJHRoaXMtPmdldFN1YlBhdGgoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCcnICE9PSAkc3ViUGF0aG5hbWUpIHsKICAgICAgICAgICAgJHN1YlBhdGhuYW1lIC49ICR0aGlzLT5kaXJlY3RvcnlTZXBhcmF0b3I7CiAgICAgICAgfQogICAgICAgICRzdWJQYXRobmFtZSAuPSAkdGhpcy0+Z2V0RmlsZW5hbWUoKTsKCiAgICAgICAgaWYgKCcvJyAhPT0gJGJhc2VQYXRoID0gJHRoaXMtPnJvb3RQYXRoKSB7CiAgICAgICAgICAgICRiYXNlUGF0aCAuPSAkdGhpcy0+ZGlyZWN0b3J5U2VwYXJhdG9yOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBTcGxGaWxlSW5mbygkYmFzZVBhdGguJHN1YlBhdGhuYW1lLCAkdGhpcy0+c3ViUGF0aCwgJHN1YlBhdGhuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gXFJlY3Vyc2l2ZUl0ZXJhdG9yCiAgICAgKgogICAgICogQHRocm93cyBBY2Nlc3NEZW5pZWRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoaWxkcmVuKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkY2hpbGRyZW4gPSBwYXJlbnQ6OmdldENoaWxkcmVuKCk7CgogICAgICAgICAgICBpZiAoJGNoaWxkcmVuIGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICAgICAgLy8gcGFyZW50IG1ldGhvZCB3aWxsIGNhbGwgdGhlIGNvbnN0cnVjdG9yIHdpdGggZGVmYXVsdCBhcmd1bWVudHMsIHNvIHVucmVhZGFibGUgZGlycyB3b24ndCBiZSBpZ25vcmVkIGFueW1vcmUKICAgICAgICAgICAgICAgICRjaGlsZHJlbi0+aWdub3JlVW5yZWFkYWJsZURpcnMgPSAkdGhpcy0+aWdub3JlVW5yZWFkYWJsZURpcnM7CgogICAgICAgICAgICAgICAgLy8gcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIHRvIGF2b2lkIHJlZG9pbmcgdGhlIHNhbWUgd29yayBpbiBhbGwgY2hpbGRyZW4KICAgICAgICAgICAgICAgICRjaGlsZHJlbi0+cmV3aW5kYWJsZSA9ICYkdGhpcy0+cmV3aW5kYWJsZTsKICAgICAgICAgICAgICAgICRjaGlsZHJlbi0+cm9vdFBhdGggPSAkdGhpcy0+cm9vdFBhdGg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkY2hpbGRyZW47CiAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmlnbm9yZVVucmVhZGFibGVEaXJzKSB7CiAgICAgICAgICAgICAgICAvLyBJZiBkaXJlY3RvcnkgaXMgdW5yZWFkYWJsZSBhbmQgZmluZGVyIGlzIHNldCB0byBpZ25vcmUgaXQsIGEgZmFrZSBlbXB0eSBjb250ZW50IGlzIHJldHVybmVkLgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBcUmVjdXJzaXZlQXJyYXlJdGVyYXRvcihbXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWNjZXNzRGVuaWVkRXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCksICRlLT5nZXRDb2RlKCksICRlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERvIG5vdGhpbmcgZm9yIG5vbiByZXdpbmRhYmxlIHN0cmVhbS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJld2luZCgpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSAkdGhpcy0+aXNSZXdpbmRhYmxlKCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gQHNlZSBodHRwczovL2J1Z3MucGhwLm5ldC82ODU1NwogICAgICAgIGlmIChcUEhQX1ZFUlNJT05fSUQgPCA1MDUyMyB8fCBcUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDAgJiYgXFBIUF9WRVJTSU9OX0lEIDwgNTA2MDcpIHsKICAgICAgICAgICAgcGFyZW50OjpuZXh0KCk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6OnJld2luZCgpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBzdHJlYW0gaXMgcmV3aW5kYWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSB3aGVuIHRoZSBzdHJlYW0gaXMgcmV3aW5kYWJsZSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Jld2luZGFibGUoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+cmV3aW5kYWJsZSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJld2luZGFibGU7CiAgICAgICAgfQoKICAgICAgICAvLyB3b3JrYXJvdW5kIGZvciBhbiBISFZNIGJ1Zywgc2hvdWxkIGJlIHJlbW92ZWQgd2hlbiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svaGh2bS9pc3N1ZXMvNzI4MSBpcyBmaXhlZAogICAgICAgIGlmICgnJyA9PT0gJHRoaXMtPmdldFBhdGgoKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJld2luZGFibGUgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSAhPT0gJHN0cmVhbSA9IEBvcGVuZGlyKCR0aGlzLT5nZXRQYXRoKCkpKSB7CiAgICAgICAgICAgICRpbmZvcyA9IHN0cmVhbV9nZXRfbWV0YV9kYXRhKCRzdHJlYW0pOwogICAgICAgICAgICBjbG9zZWRpcigkc3RyZWFtKTsKCiAgICAgICAgICAgIGlmICgkaW5mb3NbJ3NlZWthYmxlJ10pIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmV3aW5kYWJsZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cmV3aW5kYWJsZSA9IGZhbHNlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxHbG9iOwoKLyoqCiAqIEZpbGVuYW1lRmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyBieSBwYXR0ZXJucyAoYSByZWdleHAsIGEgZ2xvYiwgb3IgYSBzdHJpbmcpLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEZpbGVuYW1lRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBNdWx0aXBsZVBjcmVGaWx0ZXJJdGVyYXRvcgp7CiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzQWNjZXB0ZWQoJHRoaXMtPmN1cnJlbnQoKS0+Z2V0RmlsZW5hbWUoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBnbG9iIHRvIHJlZ2V4cC4KICAgICAqCiAgICAgKiBQQ1JFIHBhdHRlcm5zIGFyZSBsZWZ0IHVuY2hhbmdlZC4KICAgICAqIEdsb2Igc3RyaW5ncyBhcmUgdHJhbnNmb3JtZWQgd2l0aCBHbG9iOjp0b1JlZ2V4KCkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyIFBhdHRlcm46IGdsb2Igb3IgcmVnZXhwCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVnZXhwIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBnbG9iIG9yIHJlZ2V4cAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdG9SZWdleCgkc3RyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aXNSZWdleCgkc3RyKSA/ICRzdHIgOiBHbG9iOjp0b1JlZ2V4KCRzdHIpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxDb21wYXJhdG9yXE51bWJlckNvbXBhcmF0b3I7CgovKioKICogU2l6ZVJhbmdlRmlsdGVySXRlcmF0b3IgZmlsdGVycyBvdXQgZmlsZXMgdGhhdCBhcmUgbm90IGluIHRoZSBnaXZlbiBzaXplIHJhbmdlLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIFNpemVSYW5nZUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgcHJpdmF0ZSAkY29tcGFyYXRvcnMgPSBbXTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBcSXRlcmF0b3IgICAgICAgICAgJGl0ZXJhdG9yICAgIFRoZSBJdGVyYXRvciB0byBmaWx0ZXIKICAgICAqIEBwYXJhbSBOdW1iZXJDb21wYXJhdG9yW10gJGNvbXBhcmF0b3JzIEFuIGFycmF5IG9mIE51bWJlckNvbXBhcmF0b3IgaW5zdGFuY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCBhcnJheSAkY29tcGFyYXRvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXBhcmF0b3JzID0gJGNvbXBhcmF0b3JzOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpdGVyYXRvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgJGZpbGVpbmZvID0gJHRoaXMtPmN1cnJlbnQoKTsKICAgICAgICBpZiAoISRmaWxlaW5mby0+aXNGaWxlKCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkZmlsZXNpemUgPSAkZmlsZWluZm8tPmdldFNpemUoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29tcGFyYXRvcnMgYXMgJGNvbXBhcmUpIHsKICAgICAgICAgICAgaWYgKCEkY29tcGFyZS0+dGVzdCgkZmlsZXNpemUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIEN1c3RvbUZpbHRlckl0ZXJhdG9yIGZpbHRlcnMgZmlsZXMgYnkgYXBwbHlpbmcgYW5vbnltb3VzIGZ1bmN0aW9ucy4KICoKICogVGhlIGFub255bW91cyBmdW5jdGlvbiByZWNlaXZlcyBhIFxTcGxGaWxlSW5mbyBhbmQgbXVzdCByZXR1cm4gZmFsc2UKICogdG8gcmVtb3ZlIGZpbGVzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEN1c3RvbUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgcHJpdmF0ZSAkZmlsdGVycyA9IFtdOwoKICAgIC8qKgogICAgICogQHBhcmFtIFxJdGVyYXRvciAgJGl0ZXJhdG9yIFRoZSBJdGVyYXRvciB0byBmaWx0ZXIKICAgICAqIEBwYXJhbSBjYWxsYWJsZVtdICRmaWx0ZXJzICBBbiBhcnJheSBvZiBQSFAgY2FsbGJhY2tzCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCBhcnJheSAkZmlsdGVycykKICAgIHsKICAgICAgICBmb3JlYWNoICgkZmlsdGVycyBhcyAkZmlsdGVyKSB7CiAgICAgICAgICAgIGlmICghXGlzX2NhbGxhYmxlKCRmaWx0ZXIpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignSW52YWxpZCBQSFAgY2FsbGJhY2suJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRoaXMtPmZpbHRlcnMgPSAkZmlsdGVyczsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaXRlcmF0b3IpOwogICAgfQoKICAgIC8qKgogICAgICogRmlsdGVycyB0aGUgaXRlcmF0b3IgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUga2VwdCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHQoKQogICAgewogICAgICAgICRmaWxlaW5mbyA9ICR0aGlzLT5jdXJyZW50KCk7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5maWx0ZXJzIGFzICRmaWx0ZXIpIHsKICAgICAgICAgICAgaWYgKGZhbHNlID09PSBcY2FsbF91c2VyX2Z1bmMoJGZpbHRlciwgJGZpbGVpbmZvKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCi8qKgogKiBTb3J0YWJsZUl0ZXJhdG9yIGFwcGxpZXMgYSBzb3J0IG9uIGEgZ2l2ZW4gSXRlcmF0b3IuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgU29ydGFibGVJdGVyYXRvciBpbXBsZW1lbnRzIFxJdGVyYXRvckFnZ3JlZ2F0ZQp7CiAgICBjb25zdCBTT1JUX0JZX05BTUUgPSAxOwogICAgY29uc3QgU09SVF9CWV9UWVBFID0gMjsKICAgIGNvbnN0IFNPUlRfQllfQUNDRVNTRURfVElNRSA9IDM7CiAgICBjb25zdCBTT1JUX0JZX0NIQU5HRURfVElNRSA9IDQ7CiAgICBjb25zdCBTT1JUX0JZX01PRElGSUVEX1RJTUUgPSA1OwoKICAgIHByaXZhdGUgJGl0ZXJhdG9yOwogICAgcHJpdmF0ZSAkc29ydDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBcVHJhdmVyc2FibGUgJGl0ZXJhdG9yIFRoZSBJdGVyYXRvciB0byBmaWx0ZXIKICAgICAqIEBwYXJhbSBpbnR8Y2FsbGFibGUgJHNvcnQgICAgIFRoZSBzb3J0IHR5cGUgKFNPUlRfQllfTkFNRSwgU09SVF9CWV9UWVBFLCBvciBhIFBIUCBjYWxsYmFjaykKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFxUcmF2ZXJzYWJsZSAkaXRlcmF0b3IsICRzb3J0KQogICAgewogICAgICAgICR0aGlzLT5pdGVyYXRvciA9ICRpdGVyYXRvcjsKCiAgICAgICAgaWYgKHNlbGY6OlNPUlRfQllfTkFNRSA9PT0gJHNvcnQpIHsKICAgICAgICAgICAgJHRoaXMtPnNvcnQgPSBzdGF0aWMgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYS0+Z2V0UmVhbFBhdGgoKSA/OiAkYS0+Z2V0UGF0aG5hbWUoKSwgJGItPmdldFJlYWxQYXRoKCkgPzogJGItPmdldFBhdGhuYW1lKCkpOwogICAgICAgICAgICB9OwogICAgICAgIH0gZWxzZWlmIChzZWxmOjpTT1JUX0JZX1RZUEUgPT09ICRzb3J0KSB7CiAgICAgICAgICAgICR0aGlzLT5zb3J0ID0gc3RhdGljIGZ1bmN0aW9uICgkYSwgJGIpIHsKICAgICAgICAgICAgICAgIGlmICgkYS0+aXNEaXIoKSAmJiAkYi0+aXNGaWxlKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGEtPmlzRmlsZSgpICYmICRiLT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYS0+Z2V0UmVhbFBhdGgoKSA/OiAkYS0+Z2V0UGF0aG5hbWUoKSwgJGItPmdldFJlYWxQYXRoKCkgPzogJGItPmdldFBhdGhuYW1lKCkpOwogICAgICAgICAgICB9OwogICAgICAgIH0gZWxzZWlmIChzZWxmOjpTT1JUX0JZX0FDQ0VTU0VEX1RJTUUgPT09ICRzb3J0KSB7CiAgICAgICAgICAgICR0aGlzLT5zb3J0ID0gc3RhdGljIGZ1bmN0aW9uICgkYSwgJGIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYS0+Z2V0QVRpbWUoKSAtICRiLT5nZXRBVGltZSgpOwogICAgICAgICAgICB9OwogICAgICAgIH0gZWxzZWlmIChzZWxmOjpTT1JUX0JZX0NIQU5HRURfVElNRSA9PT0gJHNvcnQpIHsKICAgICAgICAgICAgJHRoaXMtPnNvcnQgPSBzdGF0aWMgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICAgICAgcmV0dXJuICRhLT5nZXRDVGltZSgpIC0gJGItPmdldENUaW1lKCk7CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlaWYgKHNlbGY6OlNPUlRfQllfTU9ESUZJRURfVElNRSA9PT0gJHNvcnQpIHsKICAgICAgICAgICAgJHRoaXMtPnNvcnQgPSBzdGF0aWMgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICAgICAgcmV0dXJuICRhLT5nZXRNVGltZSgpIC0gJGItPmdldE1UaW1lKCk7CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlaWYgKFxpc19jYWxsYWJsZSgkc29ydCkpIHsKICAgICAgICAgICAgJHRoaXMtPnNvcnQgPSAkc29ydDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIFNvcnRhYmxlSXRlcmF0b3IgdGFrZXMgYSBQSFAgY2FsbGFibGUgb3IgYSB2YWxpZCBidWlsdC1pbiBzb3J0IGFsZ29yaXRobSBhcyBhbiBhcmd1bWVudC4nKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCkKICAgIHsKICAgICAgICAkYXJyYXkgPSBpdGVyYXRvcl90b19hcnJheSgkdGhpcy0+aXRlcmF0b3IsIHRydWUpOwogICAgICAgIHVhc29ydCgkYXJyYXksICR0aGlzLT5zb3J0KTsKCiAgICAgICAgcmV0dXJuIG5ldyBcQXJyYXlJdGVyYXRvcigkYXJyYXkpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIEZpbGVjb250ZW50RmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyBieSB0aGVpciBjb250ZW50cyB1c2luZyBwYXR0ZXJucyAocmVnZXhwcyBvciBzdHJpbmdzKS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyICA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIFfFgm9kemltaWVyeiBHYWpkYSA8Z2FqZGF3QGdhamRhdy5wbD4KICovCmNsYXNzIEZpbGVjb250ZW50RmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBNdWx0aXBsZVBjcmVGaWx0ZXJJdGVyYXRvcgp7CiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5tYXRjaFJlZ2V4cHMgJiYgISR0aGlzLT5ub01hdGNoUmVnZXhwcykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRmaWxlaW5mbyA9ICR0aGlzLT5jdXJyZW50KCk7CgogICAgICAgIGlmICgkZmlsZWluZm8tPmlzRGlyKCkgfHwgISRmaWxlaW5mby0+aXNSZWFkYWJsZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjb250ZW50ID0gJGZpbGVpbmZvLT5nZXRDb250ZW50cygpOwogICAgICAgIGlmICghJGNvbnRlbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pc0FjY2VwdGVkKCRjb250ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnRzIHN0cmluZyB0byByZWdleHAgaWYgbmVjZXNzYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBQYXR0ZXJuOiBzdHJpbmcgb3IgcmVnZXhwCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVnZXhwIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBzdHJpbmcgb3IgcmVnZXhwCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB0b1JlZ2V4KCRzdHIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1JlZ2V4KCRzdHIpID8gJHN0ciA6ICcvJy5wcmVnX3F1b3RlKCRzdHIsICcvJykuJy8nOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIFRoaXMgaXRlcmF0b3IganVzdCBvdmVycmlkZXMgdGhlIHJld2luZCBtZXRob2QgaW4gb3JkZXIgdG8gY29ycmVjdCBhIFBIUCBidWcsCiAqIHdoaWNoIGV4aXN0ZWQgYmVmb3JlIHZlcnNpb24gNS41LjIzLzUuNi43LgogKgogKiBAc2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzY4NTU3CiAqCiAqIEBhdXRob3IgQWxleCBCb2dvbWF6b3YKICoKICogQGRlcHJlY2F0ZWQgc2luY2UgMy40LCB0byBiZSByZW1vdmVkIGluIDQuMC4KICovCmFic3RyYWN0IGNsYXNzIEZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgXEZpbHRlckl0ZXJhdG9yCnsKICAgIC8qKgogICAgICogVGhpcyBpcyBhIHdvcmthcm91bmQgZm9yIHRoZSBwcm9ibGVtIHdpdGggXEZpbHRlckl0ZXJhdG9yIGxlYXZpbmcgaW5uZXIgXEZpbGVzeXN0ZW1JdGVyYXRvciBpbiB3cm9uZyBzdGF0ZSBhZnRlcgogICAgICogcmV3aW5kIGluIHNvbWUgY2FzZXMuCiAgICAgKgogICAgICogQHNlZSBGaWx0ZXJJdGVyYXRvcjo6cmV3aW5kKCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJld2luZCgpCiAgICB7CiAgICAgICAgaWYgKFxQSFBfVkVSU0lPTl9JRCA+IDUwNjA3IHx8IChcUEhQX1ZFUlNJT05fSUQgPiA1MDUyMyAmJiBcUEhQX1ZFUlNJT05fSUQgPCA1MDYwMCkpIHsKICAgICAgICAgICAgcGFyZW50OjpyZXdpbmQoKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRpdGVyYXRvciA9ICR0aGlzOwogICAgICAgIHdoaWxlICgkaXRlcmF0b3IgaW5zdGFuY2VvZiBcT3V0ZXJJdGVyYXRvcikgewogICAgICAgICAgICAkaW5uZXJJdGVyYXRvciA9ICRpdGVyYXRvci0+Z2V0SW5uZXJJdGVyYXRvcigpOwoKICAgICAgICAgICAgaWYgKCRpbm5lckl0ZXJhdG9yIGluc3RhbmNlb2YgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IpIHsKICAgICAgICAgICAgICAgIC8vIHRoaXMgY29uZGl0aW9uIGlzIG5lY2Vzc2FyeSBmb3IgaXRlcmF0b3JzIHRvIHdvcmsgcHJvcGVybHkgd2l0aCBub24tbG9jYWwgZmlsZXN5c3RlbXMgbGlrZSBmdHAKICAgICAgICAgICAgICAgIGlmICgkaW5uZXJJdGVyYXRvci0+aXNSZXdpbmRhYmxlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkaW5uZXJJdGVyYXRvci0+bmV4dCgpOwogICAgICAgICAgICAgICAgICAgICRpbm5lckl0ZXJhdG9yLT5yZXdpbmQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCRpbm5lckl0ZXJhdG9yIGluc3RhbmNlb2YgXEZpbGVzeXN0ZW1JdGVyYXRvcikgewogICAgICAgICAgICAgICAgJGlubmVySXRlcmF0b3ItPm5leHQoKTsKICAgICAgICAgICAgICAgICRpbm5lckl0ZXJhdG9yLT5yZXdpbmQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGl0ZXJhdG9yID0gJGlubmVySXRlcmF0b3I7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6OnJld2luZCgpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIEV4Y2x1ZGVEaXJlY3RvcnlGaWx0ZXJJdGVyYXRvciBmaWx0ZXJzIG91dCBkaXJlY3Rvcmllcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBFeGNsdWRlRGlyZWN0b3J5RmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBGaWx0ZXJJdGVyYXRvciBpbXBsZW1lbnRzIFxSZWN1cnNpdmVJdGVyYXRvcgp7CiAgICBwcml2YXRlICRpdGVyYXRvcjsKICAgIHByaXZhdGUgJGlzUmVjdXJzaXZlOwogICAgcHJpdmF0ZSAkZXhjbHVkZWREaXJzID0gW107CiAgICBwcml2YXRlICRleGNsdWRlZFBhdHRlcm47CgogICAgLyoqCiAgICAgKiBAcGFyYW0gXEl0ZXJhdG9yICRpdGVyYXRvciAgICBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICRkaXJlY3RvcmllcyBBbiBhcnJheSBvZiBkaXJlY3RvcmllcyB0byBleGNsdWRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCBhcnJheSAkZGlyZWN0b3JpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPml0ZXJhdG9yID0gJGl0ZXJhdG9yOwogICAgICAgICR0aGlzLT5pc1JlY3Vyc2l2ZSA9ICRpdGVyYXRvciBpbnN0YW5jZW9mIFxSZWN1cnNpdmVJdGVyYXRvcjsKICAgICAgICAkcGF0dGVybnMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkZGlyZWN0b3JpZXMgYXMgJGRpcmVjdG9yeSkgewogICAgICAgICAgICAkZGlyZWN0b3J5ID0gcnRyaW0oJGRpcmVjdG9yeSwgJy8nKTsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+aXNSZWN1cnNpdmUgfHwgZmFsc2UgIT09IHN0cnBvcygkZGlyZWN0b3J5LCAnLycpKSB7CiAgICAgICAgICAgICAgICAkcGF0dGVybnNbXSA9IHByZWdfcXVvdGUoJGRpcmVjdG9yeSwgJyMnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5leGNsdWRlZERpcnNbJGRpcmVjdG9yeV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkcGF0dGVybnMpIHsKICAgICAgICAgICAgJHRoaXMtPmV4Y2x1ZGVkUGF0dGVybiA9ICcjKD86XnwvKSg/OicuaW1wbG9kZSgnfCcsICRwYXR0ZXJucykuJykoPzovfCQpIyc7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpdGVyYXRvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc1JlY3Vyc2l2ZSAmJiBpc3NldCgkdGhpcy0+ZXhjbHVkZWREaXJzWyR0aGlzLT5nZXRGaWxlbmFtZSgpXSkgJiYgJHRoaXMtPmlzRGlyKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5leGNsdWRlZFBhdHRlcm4pIHsKICAgICAgICAgICAgJHBhdGggPSAkdGhpcy0+aXNEaXIoKSA/ICR0aGlzLT5jdXJyZW50KCktPmdldFJlbGF0aXZlUGF0aG5hbWUoKSA6ICR0aGlzLT5jdXJyZW50KCktPmdldFJlbGF0aXZlUGF0aCgpOwogICAgICAgICAgICAkcGF0aCA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJHBhdGgpOwoKICAgICAgICAgICAgcmV0dXJuICFwcmVnX21hdGNoKCR0aGlzLT5leGNsdWRlZFBhdHRlcm4sICRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNDaGlsZHJlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1JlY3Vyc2l2ZSAmJiAkdGhpcy0+aXRlcmF0b3ItPmhhc0NoaWxkcmVuKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENoaWxkcmVuKCkKICAgIHsKICAgICAgICAkY2hpbGRyZW4gPSBuZXcgc2VsZigkdGhpcy0+aXRlcmF0b3ItPmdldENoaWxkcmVuKCksIFtdKTsKICAgICAgICAkY2hpbGRyZW4tPmV4Y2x1ZGVkRGlycyA9ICR0aGlzLT5leGNsdWRlZERpcnM7CiAgICAgICAgJGNoaWxkcmVuLT5leGNsdWRlZFBhdHRlcm4gPSAkdGhpcy0+ZXhjbHVkZWRQYXR0ZXJuOwoKICAgICAgICByZXR1cm4gJGNoaWxkcmVuOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIE11bHRpcGxlUGNyZUZpbHRlckl0ZXJhdG9yIGZpbHRlcnMgZmlsZXMgdXNpbmcgcGF0dGVybnMgKHJlZ2V4cHMsIGdsb2JzIG9yIHN0cmluZ3MpLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmFic3RyYWN0IGNsYXNzIE11bHRpcGxlUGNyZUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgcHJvdGVjdGVkICRtYXRjaFJlZ2V4cHMgPSBbXTsKICAgIHByb3RlY3RlZCAkbm9NYXRjaFJlZ2V4cHMgPSBbXTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBcSXRlcmF0b3IgJGl0ZXJhdG9yICAgICAgICBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICRtYXRjaFBhdHRlcm5zICAgQW4gYXJyYXkgb2YgcGF0dGVybnMgdGhhdCBuZWVkIHRvIG1hdGNoCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICRub01hdGNoUGF0dGVybnMgQW4gYXJyYXkgb2YgcGF0dGVybnMgdGhhdCBuZWVkIHRvIG5vdCBtYXRjaAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoXEl0ZXJhdG9yICRpdGVyYXRvciwgYXJyYXkgJG1hdGNoUGF0dGVybnMsIGFycmF5ICRub01hdGNoUGF0dGVybnMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJG1hdGNoUGF0dGVybnMgYXMgJHBhdHRlcm4pIHsKICAgICAgICAgICAgJHRoaXMtPm1hdGNoUmVnZXhwc1tdID0gJHRoaXMtPnRvUmVnZXgoJHBhdHRlcm4pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJG5vTWF0Y2hQYXR0ZXJucyBhcyAkcGF0dGVybikgewogICAgICAgICAgICAkdGhpcy0+bm9NYXRjaFJlZ2V4cHNbXSA9ICR0aGlzLT50b1JlZ2V4KCRwYXR0ZXJuKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGl0ZXJhdG9yKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBzdHJpbmcgaXMgYWNjZXB0ZWQgYnkgdGhlIHJlZ2V4IGZpbHRlcnMuCiAgICAgKgogICAgICogSWYgdGhlcmUgaXMgbm8gcmVnZXhwcyBkZWZpbmVkIGluIHRoZSBjbGFzcywgdGhpcyBtZXRob2Qgd2lsbCBhY2NlcHQgdGhlIHN0cmluZy4KICAgICAqIFN1Y2ggY2FzZSBjYW4gYmUgaGFuZGxlZCBieSBjaGlsZCBjbGFzc2VzIGJlZm9yZSBjYWxsaW5nIHRoZSBtZXRob2QgaWYgdGhleSB3YW50IHRvCiAgICAgKiBhcHBseSBhIGRpZmZlcmVudCBiZWhhdmlvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgVGhlIHN0cmluZyB0byBiZSBtYXRjaGVkIGFnYWluc3QgZmlsdGVycwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNBY2NlcHRlZCgkc3RyaW5nKQogICAgewogICAgICAgIC8vIHNob3VsZCBhdCBsZWFzdCBub3QgbWF0Y2ggb25lIHJ1bGUgdG8gZXhjbHVkZQogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ub01hdGNoUmVnZXhwcyBhcyAkcmVnZXgpIHsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHJlZ2V4LCAkc3RyaW5nKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBzaG91bGQgYXQgbGVhc3QgbWF0Y2ggb25lIHJ1bGUKICAgICAgICBpZiAoJHRoaXMtPm1hdGNoUmVnZXhwcykgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+bWF0Y2hSZWdleHBzIGFzICRyZWdleCkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHJlZ2V4LCAkc3RyaW5nKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBtYXRjaCBydWxlcywgdGhlIGZpbGUgaXMgYWNjZXB0ZWQKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBzdHJpbmcgaXMgYSByZWdleC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgZ2l2ZW4gc3RyaW5nIGlzIGEgcmVnZXgKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzUmVnZXgoJHN0cikKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oLnszLH0/KVtpbXN4dUFEVV0qJC8nLCAkc3RyLCAkbSkpIHsKICAgICAgICAgICAgJHN0YXJ0ID0gc3Vic3RyKCRtWzFdLCAwLCAxKTsKICAgICAgICAgICAgJGVuZCA9IHN1YnN0cigkbVsxXSwgLTEpOwoKICAgICAgICAgICAgaWYgKCRzdGFydCA9PT0gJGVuZCkgewogICAgICAgICAgICAgICAgcmV0dXJuICFwcmVnX21hdGNoKCcvWyo/WzphbG51bTpdIFxcXFxdLycsICRzdGFydCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKFtbJ3snLCAnfSddLCBbJygnLCAnKSddLCBbJ1snLCAnXSddLCBbJzwnLCAnPiddXSBhcyAkZGVsaW1pdGVycykgewogICAgICAgICAgICAgICAgaWYgKCRzdGFydCA9PT0gJGRlbGltaXRlcnNbMF0gJiYgJGVuZCA9PT0gJGRlbGltaXRlcnNbMV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydHMgc3RyaW5nIGludG8gcmVnZXhwLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBQYXR0ZXJuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVnZXhwIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBzdHJpbmcKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIHRvUmVnZXgoJHN0cik7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3I7CgovKioKICogUGF0aEZpbHRlckl0ZXJhdG9yIGZpbHRlcnMgZmlsZXMgYnkgcGF0aCBwYXR0ZXJucyAoZS5nLiBzb21lL3NwZWNpYWwvZGlyKS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyICA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIFfFgm9kemltaWVyeiBHYWpkYSA8Z2FqZGF3QGdhamRhdy5wbD4KICovCmNsYXNzIFBhdGhGaWx0ZXJJdGVyYXRvciBleHRlbmRzIE11bHRpcGxlUGNyZUZpbHRlckl0ZXJhdG9yCnsKICAgIC8qKgogICAgICogRmlsdGVycyB0aGUgaXRlcmF0b3IgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUga2VwdCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHQoKQogICAgewogICAgICAgICRmaWxlbmFtZSA9ICR0aGlzLT5jdXJyZW50KCktPmdldFJlbGF0aXZlUGF0aG5hbWUoKTsKCiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRmaWxlbmFtZSA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJGZpbGVuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aXNBY2NlcHRlZCgkZmlsZW5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydHMgc3RyaW5ncyB0byByZWdleHAuCiAgICAgKgogICAgICogUENSRSBwYXR0ZXJucyBhcmUgbGVmdCB1bmNoYW5nZWQuCiAgICAgKgogICAgICogRGVmYXVsdCBjb252ZXJzaW9uOgogICAgICogICAgICdsb3JlbS9pcHN1bS9kb2xvcicgPT0+ICAnbG9yZW1cL2lwc3VtXC9kb2xvci8nCiAgICAgKgogICAgICogVXNlIG9ubHkgLyBhcyBkaXJlY3Rvcnkgc2VwYXJhdG9yIChvbiBXaW5kb3dzIGFsc28pLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBQYXR0ZXJuOiByZWdleHAgb3IgZGlybmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHJlZ2V4cCBjb3JyZXNwb25kaW5nIHRvIGEgZ2l2ZW4gc3RyaW5nIG9yIHJlZ2V4cAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdG9SZWdleCgkc3RyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aXNSZWdleCgkc3RyKSA/ICRzdHIgOiAnLycucHJlZ19xdW90ZSgkc3RyLCAnLycpLicvJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCi8qKgogKiBEZXB0aFJhbmdlRmlsdGVySXRlcmF0b3IgbGltaXRzIHRoZSBkaXJlY3RvcnkgZGVwdGguCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRGVwdGhSYW5nZUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgcHJpdmF0ZSAkbWluRGVwdGggPSAwOwoKICAgIC8qKgogICAgICogQHBhcmFtIFxSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yICRpdGVyYXRvciBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICAgICAgICAgJG1pbkRlcHRoIFRoZSBtaW4gZGVwdGgKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAkbWF4RGVwdGggVGhlIG1heCBkZXB0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IgJGl0ZXJhdG9yLCAkbWluRGVwdGggPSAwLCAkbWF4RGVwdGggPSBcUEhQX0lOVF9NQVgpCiAgICB7CiAgICAgICAgJHRoaXMtPm1pbkRlcHRoID0gJG1pbkRlcHRoOwogICAgICAgICRpdGVyYXRvci0+c2V0TWF4RGVwdGgoXFBIUF9JTlRfTUFYID09PSAkbWF4RGVwdGggPyAtMSA6ICRtYXhEZXB0aCk7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGl0ZXJhdG9yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldElubmVySXRlcmF0b3IoKS0+Z2V0RGVwdGgoKSA+PSAkdGhpcy0+bWluRGVwdGg7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3I7CgovKioKICogRmlsZVR5cGVGaWx0ZXJJdGVyYXRvciBvbmx5IGtlZXBzIGZpbGVzLCBkaXJlY3Rvcmllcywgb3IgYm90aC4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBGaWxlVHlwZUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgY29uc3QgT05MWV9GSUxFUyA9IDE7CiAgICBjb25zdCBPTkxZX0RJUkVDVE9SSUVTID0gMjsKCiAgICBwcml2YXRlICRtb2RlOwoKICAgIC8qKgogICAgICogQHBhcmFtIFxJdGVyYXRvciAkaXRlcmF0b3IgVGhlIEl0ZXJhdG9yIHRvIGZpbHRlcgogICAgICogQHBhcmFtIGludCAgICAgICAkbW9kZSAgICAgVGhlIG1vZGUgKHNlbGY6Ok9OTFlfRklMRVMgb3Igc2VsZjo6T05MWV9ESVJFQ1RPUklFUykKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFxJdGVyYXRvciAkaXRlcmF0b3IsICRtb2RlKQogICAgewogICAgICAgICR0aGlzLT5tb2RlID0gJG1vZGU7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGl0ZXJhdG9yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICAkZmlsZWluZm8gPSAkdGhpcy0+Y3VycmVudCgpOwogICAgICAgIGlmIChzZWxmOjpPTkxZX0RJUkVDVE9SSUVTID09PSAoc2VsZjo6T05MWV9ESVJFQ1RPUklFUyAmICR0aGlzLT5tb2RlKSAmJiAkZmlsZWluZm8tPmlzRmlsZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2VpZiAoc2VsZjo6T05MWV9GSUxFUyA9PT0gKHNlbGY6Ok9OTFlfRklMRVMgJiAkdGhpcy0+bW9kZSkgJiYgJGZpbGVpbmZvLT5pc0RpcigpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/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/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyOwoKLyoqCiAqIEdsb2IgbWF0Y2hlcyBnbG9iYmluZyBwYXR0ZXJucyBhZ2FpbnN0IHRleHQuCiAqCiAqICAgICBpZiBtYXRjaF9nbG9iKCJmb28uKiIsICJmb28uYmFyIikgZWNobyAibWF0Y2hlZFxuIjsKICoKICogICAgIC8vIHByaW50cyBmb28uYmFyIGFuZCBmb28uYmF6CiAqICAgICAkcmVnZXggPSBnbG9iX3RvX3JlZ2V4KCJmb28uKiIpOwogKiAgICAgZm9yIChbJ2Zvby5iYXInLCAnZm9vLmJheicsICdmb28nLCAnYmFyJ10gYXMgJHQpCiAqICAgICB7CiAqICAgICAgICAgaWYgKC8kcmVnZXgvKSBlY2hvICJtYXRjaGVkOiAkY2FyXG4iOwogKiAgICAgfQogKgogKiBHbG9iIGltcGxlbWVudHMgZ2xvYigzKSBzdHlsZSBtYXRjaGluZyB0aGF0IGNhbiBiZSB1c2VkIHRvIG1hdGNoCiAqIGFnYWluc3QgdGV4dCwgcmF0aGVyIHRoYW4gZmV0Y2hpbmcgbmFtZXMgZnJvbSBhIGZpbGVzeXN0ZW0uCiAqCiAqIEJhc2VkIG9uIHRoZSBQZXJsIFRleHQ6Okdsb2IgbW9kdWxlLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4gUEhQIHBvcnQKICogQGF1dGhvciAgICAgUmljaGFyZCBDbGFtcCA8cmljaGFyZGNAdW5peGJlYXJkLm5ldD4gUGVybCB2ZXJzaW9uCiAqIEBjb3B5cmlnaHQgIDIwMDQtMjAwNSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBjb3B5cmlnaHQgIDIwMDIgUmljaGFyZCBDbGFtcCA8cmljaGFyZGNAdW5peGJlYXJkLm5ldD4KICovCmNsYXNzIEdsb2IKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcmVnZXhwIHdoaWNoIGlzIHRoZSBlcXVpdmFsZW50IG9mIHRoZSBnbG9iIHBhdHRlcm4uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZ2xvYiAgICAgICAgICAgICAgICBUaGUgZ2xvYiBwYXR0ZXJuCiAgICAgKiBAcGFyYW0gYm9vbCAgICRzdHJpY3RMZWFkaW5nRG90CiAgICAgKiBAcGFyYW0gYm9vbCAgICRzdHJpY3RXaWxkY2FyZFNsYXNoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkZWxpbWl0ZXIgICAgICAgICAgIE9wdGlvbmFsIGRlbGltaXRlcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHJlZ2V4IFRoZSByZWdleHAKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1JlZ2V4KCRnbG9iLCAkc3RyaWN0TGVhZGluZ0RvdCA9IHRydWUsICRzdHJpY3RXaWxkY2FyZFNsYXNoID0gdHJ1ZSwgJGRlbGltaXRlciA9ICcjJykKICAgIHsKICAgICAgICAkZmlyc3RCeXRlID0gdHJ1ZTsKICAgICAgICAkZXNjYXBpbmcgPSBmYWxzZTsKICAgICAgICAkaW5DdXJsaWVzID0gMDsKICAgICAgICAkcmVnZXggPSAnJzsKICAgICAgICAkc2l6ZUdsb2IgPSBcc3RybGVuKCRnbG9iKTsKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkc2l6ZUdsb2I7ICsrJGkpIHsKICAgICAgICAgICAgJGNhciA9ICRnbG9iWyRpXTsKICAgICAgICAgICAgaWYgKCRmaXJzdEJ5dGUgJiYgJHN0cmljdExlYWRpbmdEb3QgJiYgJy4nICE9PSAkY2FyKSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJyg/PVteXC5dKSc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRmaXJzdEJ5dGUgPSAnLycgPT09ICRjYXI7CgogICAgICAgICAgICBpZiAoJGZpcnN0Qnl0ZSAmJiAkc3RyaWN0V2lsZGNhcmRTbGFzaCAmJiBpc3NldCgkZ2xvYlskaSArIDJdKSAmJiAnKionID09PSAkZ2xvYlskaSArIDFdLiRnbG9iWyRpICsgMl0gJiYgKCFpc3NldCgkZ2xvYlskaSArIDNdKSB8fCAnLycgPT09ICRnbG9iWyRpICsgM10pKSB7CiAgICAgICAgICAgICAgICAkY2FyID0gJ1teL10rKy8nOwogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkZ2xvYlskaSArIDNdKSkgewogICAgICAgICAgICAgICAgICAgICRjYXIgLj0gJz8nOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkc3RyaWN0TGVhZGluZ0RvdCkgewogICAgICAgICAgICAgICAgICAgICRjYXIgPSAnKD89W15cLl0pJy4kY2FyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRjYXIgPSAnLyg/OicuJGNhci4nKSonOwogICAgICAgICAgICAgICAgJGkgKz0gMiArIGlzc2V0KCRnbG9iWyRpICsgM10pOwoKICAgICAgICAgICAgICAgIGlmICgnLycgPT09ICRkZWxpbWl0ZXIpIHsKICAgICAgICAgICAgICAgICAgICAkY2FyID0gc3RyX3JlcGxhY2UoJy8nLCAnXFwvJywgJGNhcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZGVsaW1pdGVyID09PSAkY2FyIHx8ICcuJyA9PT0gJGNhciB8fCAnKCcgPT09ICRjYXIgfHwgJyknID09PSAkY2FyIHx8ICd8JyA9PT0gJGNhciB8fCAnKycgPT09ICRjYXIgfHwgJ14nID09PSAkY2FyIHx8ICckJyA9PT0gJGNhcikgewogICAgICAgICAgICAgICAgJHJlZ2V4IC49ICJcXCRjYXIiOwogICAgICAgICAgICB9IGVsc2VpZiAoJyonID09PSAkY2FyKSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJGVzY2FwaW5nID8gJ1xcKicgOiAoJHN0cmljdFdpbGRjYXJkU2xhc2ggPyAnW14vXSonIDogJy4qJyk7CiAgICAgICAgICAgIH0gZWxzZWlmICgnPycgPT09ICRjYXIpIHsKICAgICAgICAgICAgICAgICRyZWdleCAuPSAkZXNjYXBpbmcgPyAnXFw/JyA6ICgkc3RyaWN0V2lsZGNhcmRTbGFzaCA/ICdbXi9dJyA6ICcuJyk7CiAgICAgICAgICAgIH0gZWxzZWlmICgneycgPT09ICRjYXIpIHsKICAgICAgICAgICAgICAgICRyZWdleCAuPSAkZXNjYXBpbmcgPyAnXFx7JyA6ICcoJzsKICAgICAgICAgICAgICAgIGlmICghJGVzY2FwaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgKyskaW5DdXJsaWVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJ30nID09PSAkY2FyICYmICRpbkN1cmxpZXMpIHsKICAgICAgICAgICAgICAgICRyZWdleCAuPSAkZXNjYXBpbmcgPyAnfScgOiAnKSc7CiAgICAgICAgICAgICAgICBpZiAoISRlc2NhcGluZykgewogICAgICAgICAgICAgICAgICAgIC0tJGluQ3VybGllczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCcsJyA9PT0gJGNhciAmJiAkaW5DdXJsaWVzKSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJGVzY2FwaW5nID8gJywnIDogJ3wnOwogICAgICAgICAgICB9IGVsc2VpZiAoJ1xcJyA9PT0gJGNhcikgewogICAgICAgICAgICAgICAgaWYgKCRlc2NhcGluZykgewogICAgICAgICAgICAgICAgICAgICRyZWdleCAuPSAnXFxcXCc7CiAgICAgICAgICAgICAgICAgICAgJGVzY2FwaW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRlc2NhcGluZyA9IHRydWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJGNhcjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZXNjYXBpbmcgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZGVsaW1pdGVyLideJy4kcmVnZXguJyQnLiRkZWxpbWl0ZXI7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCnVzZSBTeW1mb255XFBvbHlmaWxsXE1ic3RyaW5nIGFzIHA7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfY29udmVydF92YXJpYWJsZXMnKSkgewogICAgLyoqCiAgICAgKiBDb252ZXJ0IGNoYXJhY3RlciBjb2RlIGluIHZhcmlhYmxlKHMpCiAgICAgKi8KICAgIGZ1bmN0aW9uIG1iX2NvbnZlcnRfdmFyaWFibGVzKCR0b19lbmNvZGluZywgJGZyb21fZW5jb2RpbmcsICYkdmFyLCAmLi4uJHZhcnMpCiAgICB7CiAgICAgICAgJHZhcnMgPSBbJiR2YXIsIC4uLiR2YXJzXTsKCiAgICAgICAgJG9rID0gdHJ1ZTsKICAgICAgICBhcnJheV93YWxrX3JlY3Vyc2l2ZSgkdmFycywgZnVuY3Rpb24gKCYkdikgdXNlICgmJG9rLCAkdG9fZW5jb2RpbmcsICRmcm9tX2VuY29kaW5nKSB7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHYgPSBwXE1ic3RyaW5nOjptYl9jb252ZXJ0X2VuY29kaW5nKCR2LCAkdG9fZW5jb2RpbmcsICRmcm9tX2VuY29kaW5nKSkgewogICAgICAgICAgICAgICAgJG9rID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRvayA/ICRmcm9tX2VuY29kaW5nIDogZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8vIGZyb20gQ2FzZV9JZ25vcmFibGUgaW4gaHR0cHM6Ly91bmljb2RlLm9yZy9QdWJsaWMvVU5JREFUQS9EZXJpdmVkQ29yZVByb3BlcnRpZXMudHh0CgpyZXR1cm4gJy8oPzwhW1x4ezAwMjd9XHh7MDAyRX1ceHswMDNBfVx4ezAwNUV9XHh7MDA2MH1ceHswMEE4fVx4ezAwQUR9XHh7MDBBRn1ceHswMEI0fVx4ezAwQjd9XHh7MDBCOH1ceHswMkIwfS1ceHswMkMxfVx4ezAyQzJ9LVx4ezAyQzV9XHh7MDJDNn0tXHh7MDJEMX1ceHswMkQyfS1ceHswMkRGfVx4ezAyRTB9LVx4ezAyRTR9XHh7MDJFNX0tXHh7MDJFQn1ceHswMkVDfVx4ezAyRUR9XHh7MDJFRX1ceHswMkVGfS1ceHswMkZGfVx4ezAzMDB9LVx4ezAzNkZ9XHh7MDM3NH1ceHswMzc1fVx4ezAzN0F9XHh7MDM4NH0tXHh7MDM4NX1ceHswMzg3fVx4ezA0ODN9LVx4ezA0ODd9XHh7MDQ4OH0tXHh7MDQ4OX1ceHswNTU5fVx4ezA1OTF9LVx4ezA1QkR9XHh7MDVCRn1ceHswNUMxfS1ceHswNUMyfVx4ezA1QzR9LVx4ezA1QzV9XHh7MDVDN31ceHswNUY0fVx4ezA2MDB9LVx4ezA2MDV9XHh7MDYxMH0tXHh7MDYxQX1ceHswNjFDfVx4ezA2NDB9XHh7MDY0Qn0tXHh7MDY1Rn1ceHswNjcwfVx4ezA2RDZ9LVx4ezA2REN9XHh7MDZERH1ceHswNkRGfS1ceHswNkU0fVx4ezA2RTV9LVx4ezA2RTZ9XHh7MDZFN30tXHh7MDZFOH1ceHswNkVBfS1ceHswNkVEfVx4ezA3MEZ9XHh7MDcxMX1ceHswNzMwfS1ceHswNzRBfVx4ezA3QTZ9LVx4ezA3QjB9XHh7MDdFQn0tXHh7MDdGM31ceHswN0Y0fS1ceHswN0Y1fVx4ezA3RkF9XHh7MDdGRH1ceHswODE2fS1ceHswODE5fVx4ezA4MUF9XHh7MDgxQn0tXHh7MDgyM31ceHswODI0fVx4ezA4MjV9LVx4ezA4Mjd9XHh7MDgyOH1ceHswODI5fS1ceHswODJEfVx4ezA4NTl9LVx4ezA4NUJ9XHh7MDhEM30tXHh7MDhFMX1ceHswOEUyfVx4ezA4RTN9LVx4ezA5MDJ9XHh7MDkzQX1ceHswOTNDfVx4ezA5NDF9LVx4ezA5NDh9XHh7MDk0RH1ceHswOTUxfS1ceHswOTU3fVx4ezA5NjJ9LVx4ezA5NjN9XHh7MDk3MX1ceHswOTgxfVx4ezA5QkN9XHh7MDlDMX0tXHh7MDlDNH1ceHswOUNEfVx4ezA5RTJ9LVx4ezA5RTN9XHh7MDlGRX1ceHswQTAxfS1ceHswQTAyfVx4ezBBM0N9XHh7MEE0MX0tXHh7MEE0Mn1ceHswQTQ3fS1ceHswQTQ4fVx4ezBBNEJ9LVx4ezBBNER9XHh7MEE1MX1ceHswQTcwfS1ceHswQTcxfVx4ezBBNzV9XHh7MEE4MX0tXHh7MEE4Mn1ceHswQUJDfVx4ezBBQzF9LVx4ezBBQzV9XHh7MEFDN30tXHh7MEFDOH1ceHswQUNEfVx4ezBBRTJ9LVx4ezBBRTN9XHh7MEFGQX0tXHh7MEFGRn1ceHswQjAxfVx4ezBCM0N9XHh7MEIzRn1ceHswQjQxfS1ceHswQjQ0fVx4ezBCNER9XHh7MEI1Nn1ceHswQjYyfS1ceHswQjYzfVx4ezBCODJ9XHh7MEJDMH1ceHswQkNEfVx4ezBDMDB9XHh7MEMwNH1ceHswQzNFfS1ceHswQzQwfVx4ezBDNDZ9LVx4ezBDNDh9XHh7MEM0QX0tXHh7MEM0RH1ceHswQzU1fS1ceHswQzU2fVx4ezBDNjJ9LVx4ezBDNjN9XHh7MEM4MX1ceHswQ0JDfVx4ezBDQkZ9XHh7MENDNn1ceHswQ0NDfS1ceHswQ0NEfVx4ezBDRTJ9LVx4ezBDRTN9XHh7MEQwMH0tXHh7MEQwMX1ceHswRDNCfS1ceHswRDNDfVx4ezBENDF9LVx4ezBENDR9XHh7MEQ0RH1ceHswRDYyfS1ceHswRDYzfVx4ezBEQ0F9XHh7MEREMn0tXHh7MERENH1ceHswREQ2fVx4ezBFMzF9XHh7MEUzNH0tXHh7MEUzQX1ceHswRTQ2fVx4ezBFNDd9LVx4ezBFNEV9XHh7MEVCMX1ceHswRUI0fS1ceHswRUI5fVx4ezBFQkJ9LVx4ezBFQkN9XHh7MEVDNn1ceHswRUM4fS1ceHswRUNEfVx4ezBGMTh9LVx4ezBGMTl9XHh7MEYzNX1ceHswRjM3fVx4ezBGMzl9XHh7MEY3MX0tXHh7MEY3RX1ceHswRjgwfS1ceHswRjg0fVx4ezBGODZ9LVx4ezBGODd9XHh7MEY4RH0tXHh7MEY5N31ceHswRjk5fS1ceHswRkJDfVx4ezBGQzZ9XHh7MTAyRH0tXHh7MTAzMH1ceHsxMDMyfS1ceHsxMDM3fVx4ezEwMzl9LVx4ezEwM0F9XHh7MTAzRH0tXHh7MTAzRX1ceHsxMDU4fS1ceHsxMDU5fVx4ezEwNUV9LVx4ezEwNjB9XHh7MTA3MX0tXHh7MTA3NH1ceHsxMDgyfVx4ezEwODV9LVx4ezEwODZ9XHh7MTA4RH1ceHsxMDlEfVx4ezEwRkN9XHh7MTM1RH0tXHh7MTM1Rn1ceHsxNzEyfS1ceHsxNzE0fVx4ezE3MzJ9LVx4ezE3MzR9XHh7MTc1Mn0tXHh7MTc1M31ceHsxNzcyfS1ceHsxNzczfVx4ezE3QjR9LVx4ezE3QjV9XHh7MTdCN30tXHh7MTdCRH1ceHsxN0M2fVx4ezE3Qzl9LVx4ezE3RDN9XHh7MTdEN31ceHsxN0REfVx4ezE4MEJ9LVx4ezE4MER9XHh7MTgwRX1ceHsxODQzfVx4ezE4ODV9LVx4ezE4ODZ9XHh7MThBOX1ceHsxOTIwfS1ceHsxOTIyfVx4ezE5Mjd9LVx4ezE5Mjh9XHh7MTkzMn1ceHsxOTM5fS1ceHsxOTNCfVx4ezFBMTd9LVx4ezFBMTh9XHh7MUExQn1ceHsxQTU2fVx4ezFBNTh9LVx4ezFBNUV9XHh7MUE2MH1ceHsxQTYyfVx4ezFBNjV9LVx4ezFBNkN9XHh7MUE3M30tXHh7MUE3Q31ceHsxQTdGfVx4ezFBQTd9XHh7MUFCMH0tXHh7MUFCRH1ceHsxQUJFfVx4ezFCMDB9LVx4ezFCMDN9XHh7MUIzNH1ceHsxQjM2fS1ceHsxQjNBfVx4ezFCM0N9XHh7MUI0Mn1ceHsxQjZCfS1ceHsxQjczfVx4ezFCODB9LVx4ezFCODF9XHh7MUJBMn0tXHh7MUJBNX1ceHsxQkE4fS1ceHsxQkE5fVx4ezFCQUJ9LVx4ezFCQUR9XHh7MUJFNn1ceHsxQkU4fS1ceHsxQkU5fVx4ezFCRUR9XHh7MUJFRn0tXHh7MUJGMX1ceHsxQzJDfS1ceHsxQzMzfVx4ezFDMzZ9LVx4ezFDMzd9XHh7MUM3OH0tXHh7MUM3RH1ceHsxQ0QwfS1ceHsxQ0QyfVx4ezFDRDR9LVx4ezFDRTB9XHh7MUNFMn0tXHh7MUNFOH1ceHsxQ0VEfVx4ezFDRjR9XHh7MUNGOH0tXHh7MUNGOX1ceHsxRDJDfS1ceHsxRDZBfVx4ezFENzh9XHh7MUQ5Qn0tXHh7MURCRn1ceHsxREMwfS1ceHsxREY5fVx4ezFERkJ9LVx4ezFERkZ9XHh7MUZCRH1ceHsxRkJGfS1ceHsxRkMxfVx4ezFGQ0R9LVx4ezFGQ0Z9XHh7MUZERH0tXHh7MUZERn1ceHsxRkVEfS1ceHsxRkVGfVx4ezFGRkR9LVx4ezFGRkV9XHh7MjAwQn0tXHh7MjAwRn1ceHsyMDE4fVx4ezIwMTl9XHh7MjAyNH1ceHsyMDI3fVx4ezIwMkF9LVx4ezIwMkV9XHh7MjA2MH0tXHh7MjA2NH1ceHsyMDY2fS1ceHsyMDZGfVx4ezIwNzF9XHh7MjA3Rn1ceHsyMDkwfS1ceHsyMDlDfVx4ezIwRDB9LVx4ezIwREN9XHh7MjBERH0tXHh7MjBFMH1ceHsyMEUxfVx4ezIwRTJ9LVx4ezIwRTR9XHh7MjBFNX0tXHh7MjBGMH1ceHsyQzdDfS1ceHsyQzdEfVx4ezJDRUZ9LVx4ezJDRjF9XHh7MkQ2Rn1ceHsyRDdGfVx4ezJERTB9LVx4ezJERkZ9XHh7MkUyRn1ceHszMDA1fVx4ezMwMkF9LVx4ezMwMkR9XHh7MzAzMX0tXHh7MzAzNX1ceHszMDNCfVx4ezMwOTl9LVx4ezMwOUF9XHh7MzA5Qn0tXHh7MzA5Q31ceHszMDlEfS1ceHszMDlFfVx4ezMwRkN9LVx4ezMwRkV9XHh7QTAxNX1ceHtBNEY4fS1ceHtBNEZEfVx4e0E2MEN9XHh7QTY2Rn1ceHtBNjcwfS1ceHtBNjcyfVx4e0E2NzR9LVx4e0E2N0R9XHh7QTY3Rn1ceHtBNjlDfS1ceHtBNjlEfVx4e0E2OUV9LVx4e0E2OUZ9XHh7QTZGMH0tXHh7QTZGMX1ceHtBNzAwfS1ceHtBNzE2fVx4e0E3MTd9LVx4e0E3MUZ9XHh7QTcyMH0tXHh7QTcyMX1ceHtBNzcwfVx4e0E3ODh9XHh7QTc4OX0tXHh7QTc4QX1ceHtBN0Y4fS1ceHtBN0Y5fVx4e0E4MDJ9XHh7QTgwNn1ceHtBODBCfVx4e0E4MjV9LVx4e0E4MjZ9XHh7QThDNH0tXHh7QThDNX1ceHtBOEUwfS1ceHtBOEYxfVx4e0E4RkZ9XHh7QTkyNn0tXHh7QTkyRH1ceHtBOTQ3fS1ceHtBOTUxfVx4e0E5ODB9LVx4e0E5ODJ9XHh7QTlCM31ceHtBOUI2fS1ceHtBOUI5fVx4e0E5QkN9XHh7QTlDRn1ceHtBOUU1fVx4e0E5RTZ9XHh7QUEyOX0tXHh7QUEyRX1ceHtBQTMxfS1ceHtBQTMyfVx4e0FBMzV9LVx4e0FBMzZ9XHh7QUE0M31ceHtBQTRDfVx4e0FBNzB9XHh7QUE3Q31ceHtBQUIwfVx4e0FBQjJ9LVx4e0FBQjR9XHh7QUFCN30tXHh7QUFCOH1ceHtBQUJFfS1ceHtBQUJGfVx4e0FBQzF9XHh7QUFERH1ceHtBQUVDfS1ceHtBQUVEfVx4e0FBRjN9LVx4e0FBRjR9XHh7QUFGNn1ceHtBQjVCfVx4e0FCNUN9LVx4e0FCNUZ9XHh7QUJFNX1ceHtBQkU4fVx4e0FCRUR9XHh7RkIxRX1ceHtGQkIyfS1ceHtGQkMxfVx4e0ZFMDB9LVx4e0ZFMEZ9XHh7RkUxM31ceHtGRTIwfS1ceHtGRTJGfVx4e0ZFNTJ9XHh7RkU1NX1ceHtGRUZGfVx4e0ZGMDd9XHh7RkYwRX1ceHtGRjFBfVx4e0ZGM0V9XHh7RkY0MH1ceHtGRjcwfVx4e0ZGOUV9LVx4e0ZGOUZ9XHh7RkZFM31ceHtGRkY5fS1ceHtGRkZCfVx4ezEwMUZEfVx4ezEwMkUwfVx4ezEwMzc2fS1ceHsxMDM3QX1ceHsxMEEwMX0tXHh7MTBBMDN9XHh7MTBBMDV9LVx4ezEwQTA2fVx4ezEwQTBDfS1ceHsxMEEwRn1ceHsxMEEzOH0tXHh7MTBBM0F9XHh7MTBBM0Z9XHh7MTBBRTV9LVx4ezEwQUU2fVx4ezEwRDI0fS1ceHsxMEQyN31ceHsxMEY0Nn0tXHh7MTBGNTB9XHh7MTEwMDF9XHh7MTEwMzh9LVx4ezExMDQ2fVx4ezExMDdGfS1ceHsxMTA4MX1ceHsxMTBCM30tXHh7MTEwQjZ9XHh7MTEwQjl9LVx4ezExMEJBfVx4ezExMEJEfVx4ezExMENEfVx4ezExMTAwfS1ceHsxMTEwMn1ceHsxMTEyN30tXHh7MTExMkJ9XHh7MTExMkR9LVx4ezExMTM0fVx4ezExMTczfVx4ezExMTgwfS1ceHsxMTE4MX1ceHsxMTFCNn0tXHh7MTExQkV9XHh7MTExQzl9LVx4ezExMUNDfVx4ezExMjJGfS1ceHsxMTIzMX1ceHsxMTIzNH1ceHsxMTIzNn0tXHh7MTEyMzd9XHh7MTEyM0V9XHh7MTEyREZ9XHh7MTEyRTN9LVx4ezExMkVBfVx4ezExMzAwfS1ceHsxMTMwMX1ceHsxMTMzQn0tXHh7MTEzM0N9XHh7MTEzNDB9XHh7MTEzNjZ9LVx4ezExMzZDfVx4ezExMzcwfS1ceHsxMTM3NH1ceHsxMTQzOH0tXHh7MTE0M0Z9XHh7MTE0NDJ9LVx4ezExNDQ0fVx4ezExNDQ2fVx4ezExNDVFfVx4ezExNEIzfS1ceHsxMTRCOH1ceHsxMTRCQX1ceHsxMTRCRn0tXHh7MTE0QzB9XHh7MTE0QzJ9LVx4ezExNEMzfVx4ezExNUIyfS1ceHsxMTVCNX1ceHsxMTVCQ30tXHh7MTE1QkR9XHh7MTE1QkZ9LVx4ezExNUMwfVx4ezExNURDfS1ceHsxMTVERH1ceHsxMTYzM30tXHh7MTE2M0F9XHh7MTE2M0R9XHh7MTE2M0Z9LVx4ezExNjQwfVx4ezExNkFCfVx4ezExNkFEfVx4ezExNkIwfS1ceHsxMTZCNX1ceHsxMTZCN31ceHsxMTcxRH0tXHh7MTE3MUZ9XHh7MTE3MjJ9LVx4ezExNzI1fVx4ezExNzI3fS1ceHsxMTcyQn1ceHsxMTgyRn0tXHh7MTE4Mzd9XHh7MTE4Mzl9LVx4ezExODNBfVx4ezExQTAxfS1ceHsxMUEwQX1ceHsxMUEzM30tXHh7MTFBMzh9XHh7MTFBM0J9LVx4ezExQTNFfVx4ezExQTQ3fVx4ezExQTUxfS1ceHsxMUE1Nn1ceHsxMUE1OX0tXHh7MTFBNUJ9XHh7MTFBOEF9LVx4ezExQTk2fVx4ezExQTk4fS1ceHsxMUE5OX1ceHsxMUMzMH0tXHh7MTFDMzZ9XHh7MTFDMzh9LVx4ezExQzNEfVx4ezExQzNGfVx4ezExQzkyfS1ceHsxMUNBN31ceHsxMUNBQX0tXHh7MTFDQjB9XHh7MTFDQjJ9LVx4ezExQ0IzfVx4ezExQ0I1fS1ceHsxMUNCNn1ceHsxMUQzMX0tXHh7MTFEMzZ9XHh7MTFEM0F9XHh7MTFEM0N9LVx4ezExRDNEfVx4ezExRDNGfS1ceHsxMUQ0NX1ceHsxMUQ0N31ceHsxMUQ5MH0tXHh7MTFEOTF9XHh7MTFEOTV9XHh7MTFEOTd9XHh7MTFFRjN9LVx4ezExRUY0fVx4ezE2QUYwfS1ceHsxNkFGNH1ceHsxNkIzMH0tXHh7MTZCMzZ9XHh7MTZCNDB9LVx4ezE2QjQzfVx4ezE2RjhGfS1ceHsxNkY5Mn1ceHsxNkY5M30tXHh7MTZGOUZ9XHh7MTZGRTB9LVx4ezE2RkUxfVx4ezFCQzlEfS1ceHsxQkM5RX1ceHsxQkNBMH0tXHh7MUJDQTN9XHh7MUQxNjd9LVx4ezFEMTY5fVx4ezFEMTczfS1ceHsxRDE3QX1ceHsxRDE3Qn0tXHh7MUQxODJ9XHh7MUQxODV9LVx4ezFEMThCfVx4ezFEMUFBfS1ceHsxRDFBRH1ceHsxRDI0Mn0tXHh7MUQyNDR9XHh7MURBMDB9LVx4ezFEQTM2fVx4ezFEQTNCfS1ceHsxREE2Q31ceHsxREE3NX1ceHsxREE4NH1ceHsxREE5Qn0tXHh7MURBOUZ9XHh7MURBQTF9LVx4ezFEQUFGfVx4ezFFMDAwfS1ceHsxRTAwNn1ceHsxRTAwOH0tXHh7MUUwMTh9XHh7MUUwMUJ9LVx4ezFFMDIxfVx4ezFFMDIzfS1ceHsxRTAyNH1ceHsxRTAyNn0tXHh7MUUwMkF9XHh7MUU4RDB9LVx4ezFFOEQ2fVx4ezFFOTQ0fS1ceHsxRTk0QX1ceHsxRjNGQn0tXHh7MUYzRkZ9XHh7RTAwMDF9XHh7RTAwMjB9LVx4e0UwMDdGfVx4e0UwMTAwfS1ceHtFMDFFRn1dKShccEwpKFxwTCorKS91JzsKPD9waHAKCnJldHVybiBhcnJheSAoCiAgJ2EnID0+ICdBJywKICAnYicgPT4gJ0InLAogICdjJyA9PiAnQycsCiAgJ2QnID0+ICdEJywKICAnZScgPT4gJ0UnLAogICdmJyA9PiAnRicsCiAgJ2cnID0+ICdHJywKICAnaCcgPT4gJ0gnLAogICdpJyA9PiAnSScsCiAgJ2onID0+ICdKJywKICAnaycgPT4gJ0snLAogICdsJyA9PiAnTCcsCiAgJ20nID0+ICdNJywKICAnbicgPT4gJ04nLAogICdvJyA9PiAnTycsCiAgJ3AnID0+ICdQJywKICAncScgPT4gJ1EnLAogICdyJyA9PiAnUicsCiAgJ3MnID0+ICdTJywKICAndCcgPT4gJ1QnLAogICd1JyA9PiAnVScsCiAgJ3YnID0+ICdWJywKICAndycgPT4gJ1cnLAogICd4JyA9PiAnWCcsCiAgJ3knID0+ICdZJywKICAneicgPT4gJ1onLAogICfCtScgPT4gJ86cJywKICAnw6AnID0+ICfDgCcsCiAgJ8OhJyA9PiAnw4EnLAogICfDoicgPT4gJ8OCJywKICAnw6MnID0+ICfDgycsCiAgJ8OkJyA9PiAnw4QnLAogICfDpScgPT4gJ8OFJywKICAnw6YnID0+ICfDhicsCiAgJ8OnJyA9PiAnw4cnLAogICfDqCcgPT4gJ8OIJywKICAnw6knID0+ICfDiScsCiAgJ8OqJyA9PiAnw4onLAogICfDqycgPT4gJ8OLJywKICAnw6wnID0+ICfDjCcsCiAgJ8OtJyA9PiAnw40nLAogICfDricgPT4gJ8OOJywKICAnw68nID0+ICfDjycsCiAgJ8OwJyA9PiAnw5AnLAogICfDsScgPT4gJ8ORJywKICAnw7InID0+ICfDkicsCiAgJ8OzJyA9PiAnw5MnLAogICfDtCcgPT4gJ8OUJywKICAnw7UnID0+ICfDlScsCiAgJ8O2JyA9PiAnw5YnLAogICfDuCcgPT4gJ8OYJywKICAnw7knID0+ICfDmScsCiAgJ8O6JyA9PiAnw5onLAogICfDuycgPT4gJ8ObJywKICAnw7wnID0+ICfDnCcsCiAgJ8O9JyA9PiAnw50nLAogICfDvicgPT4gJ8OeJywKICAnw78nID0+ICfFuCcsCiAgJ8SBJyA9PiAnxIAnLAogICfEgycgPT4gJ8SCJywKICAnxIUnID0+ICfEhCcsCiAgJ8SHJyA9PiAnxIYnLAogICfEiScgPT4gJ8SIJywKICAnxIsnID0+ICfEiicsCiAgJ8SNJyA9PiAnxIwnLAogICfEjycgPT4gJ8SOJywKICAnxJEnID0+ICfEkCcsCiAgJ8STJyA9PiAnxJInLAogICfElScgPT4gJ8SUJywKICAnxJcnID0+ICfElicsCiAgJ8SZJyA9PiAnxJgnLAogICfEmycgPT4gJ8SaJywKICAnxJ0nID0+ICfEnCcsCiAgJ8SfJyA9PiAnxJ4nLAogICfEoScgPT4gJ8SgJywKICAnxKMnID0+ICfEoicsCiAgJ8SlJyA9PiAnxKQnLAogICfEpycgPT4gJ8SmJywKICAnxKknID0+ICfEqCcsCiAgJ8SrJyA9PiAnxKonLAogICfErScgPT4gJ8SsJywKICAnxK8nID0+ICfEricsCiAgJ8SxJyA9PiAnSScsCiAgJ8SzJyA9PiAnxLInLAogICfEtScgPT4gJ8S0JywKICAnxLcnID0+ICfEticsCiAgJ8S6JyA9PiAnxLknLAogICfEvCcgPT4gJ8S7JywKICAnxL4nID0+ICfEvScsCiAgJ8WAJyA9PiAnxL8nLAogICfFgicgPT4gJ8WBJywKICAnxYQnID0+ICfFgycsCiAgJ8WGJyA9PiAnxYUnLAogICfFiCcgPT4gJ8WHJywKICAnxYsnID0+ICfFiicsCiAgJ8WNJyA9PiAnxYwnLAogICfFjycgPT4gJ8WOJywKICAnxZEnID0+ICfFkCcsCiAgJ8WTJyA9PiAnxZInLAogICfFlScgPT4gJ8WUJywKICAnxZcnID0+ICfFlicsCiAgJ8WZJyA9PiAnxZgnLAogICfFmycgPT4gJ8WaJywKICAnxZ0nID0+ICfFnCcsCiAgJ8WfJyA9PiAnxZ4nLAogICfFoScgPT4gJ8WgJywKICAnxaMnID0+ICfFoicsCiAgJ8WlJyA9PiAnxaQnLAogICfFpycgPT4gJ8WmJywKICAnxaknID0+ICfFqCcsCiAgJ8WrJyA9PiAnxaonLAogICfFrScgPT4gJ8WsJywKICAnxa8nID0+ICfFricsCiAgJ8WxJyA9PiAnxbAnLAogICfFsycgPT4gJ8WyJywKICAnxbUnID0+ICfFtCcsCiAgJ8W3JyA9PiAnxbYnLAogICfFuicgPT4gJ8W5JywKICAnxbwnID0+ICfFuycsCiAgJ8W+JyA9PiAnxb0nLAogICfFvycgPT4gJ1MnLAogICfGgCcgPT4gJ8mDJywKICAnxoMnID0+ICfGgicsCiAgJ8aFJyA9PiAnxoQnLAogICfGiCcgPT4gJ8aHJywKICAnxownID0+ICfGiycsCiAgJ8aSJyA9PiAnxpEnLAogICfGlScgPT4gJ8e2JywKICAnxpknID0+ICfGmCcsCiAgJ8aaJyA9PiAnyL0nLAogICfGnicgPT4gJ8igJywKICAnxqEnID0+ICfGoCcsCiAgJ8ajJyA9PiAnxqInLAogICfGpScgPT4gJ8akJywKICAnxqgnID0+ICfGpycsCiAgJ8atJyA9PiAnxqwnLAogICfGsCcgPT4gJ8avJywKICAnxrQnID0+ICfGsycsCiAgJ8a2JyA9PiAnxrUnLAogICfGuScgPT4gJ8a4JywKICAnxr0nID0+ICfGvCcsCiAgJ8a/JyA9PiAnx7cnLAogICfHhScgPT4gJ8eEJywKICAnx4YnID0+ICfHhCcsCiAgJ8eIJyA9PiAnx4cnLAogICfHiScgPT4gJ8eHJywKICAnx4snID0+ICfHiicsCiAgJ8eMJyA9PiAnx4onLAogICfHjicgPT4gJ8eNJywKICAnx5AnID0+ICfHjycsCiAgJ8eSJyA9PiAnx5EnLAogICfHlCcgPT4gJ8eTJywKICAnx5YnID0+ICfHlScsCiAgJ8eYJyA9PiAnx5cnLAogICfHmicgPT4gJ8eZJywKICAnx5wnID0+ICfHmycsCiAgJ8edJyA9PiAnxo4nLAogICfHnycgPT4gJ8eeJywKICAnx6EnID0+ICfHoCcsCiAgJ8ejJyA9PiAnx6InLAogICfHpScgPT4gJ8ekJywKICAnx6cnID0+ICfHpicsCiAgJ8epJyA9PiAnx6gnLAogICfHqycgPT4gJ8eqJywKICAnx60nID0+ICfHrCcsCiAgJ8evJyA9PiAnx64nLAogICfHsicgPT4gJ8exJywKICAnx7MnID0+ICfHsScsCiAgJ8e1JyA9PiAnx7QnLAogICfHuScgPT4gJ8e4JywKICAnx7snID0+ICfHuicsCiAgJ8e9JyA9PiAnx7wnLAogICfHvycgPT4gJ8e+JywKICAnyIEnID0+ICfIgCcsCiAgJ8iDJyA9PiAnyIInLAogICfIhScgPT4gJ8iEJywKICAnyIcnID0+ICfIhicsCiAgJ8iJJyA9PiAnyIgnLAogICfIiycgPT4gJ8iKJywKICAnyI0nID0+ICfIjCcsCiAgJ8iPJyA9PiAnyI4nLAogICfIkScgPT4gJ8iQJywKICAnyJMnID0+ICfIkicsCiAgJ8iVJyA9PiAnyJQnLAogICfIlycgPT4gJ8iWJywKICAnyJknID0+ICfImCcsCiAgJ8ibJyA9PiAnyJonLAogICfInScgPT4gJ8icJywKICAnyJ8nID0+ICfInicsCiAgJ8ijJyA9PiAnyKInLAogICfIpScgPT4gJ8ikJywKICAnyKcnID0+ICfIpicsCiAgJ8ipJyA9PiAnyKgnLAogICfIqycgPT4gJ8iqJywKICAnyK0nID0+ICfIrCcsCiAgJ8ivJyA9PiAnyK4nLAogICfIsScgPT4gJ8iwJywKICAnyLMnID0+ICfIsicsCiAgJ8i8JyA9PiAnyLsnLAogICfIvycgPT4gJ+KxvicsCiAgJ8mAJyA9PiAn4rG/JywKICAnyYInID0+ICfJgScsCiAgJ8mHJyA9PiAnyYYnLAogICfJiScgPT4gJ8mIJywKICAnyYsnID0+ICfJiicsCiAgJ8mNJyA9PiAnyYwnLAogICfJjycgPT4gJ8mOJywKICAnyZAnID0+ICfisa8nLAogICfJkScgPT4gJ+KxrScsCiAgJ8mSJyA9PiAn4rGwJywKICAnyZMnID0+ICfGgScsCiAgJ8mUJyA9PiAnxoYnLAogICfJlicgPT4gJ8aJJywKICAnyZcnID0+ICfGiicsCiAgJ8mZJyA9PiAnxo8nLAogICfJmycgPT4gJ8aQJywKICAnyZwnID0+ICfqnqsnLAogICfJoCcgPT4gJ8aTJywKICAnyaEnID0+ICfqnqwnLAogICfJoycgPT4gJ8aUJywKICAnyaUnID0+ICfqno0nLAogICfJpicgPT4gJ+qeqicsCiAgJ8moJyA9PiAnxpcnLAogICfJqScgPT4gJ8aWJywKICAnyaonID0+ICfqnq4nLAogICfJqycgPT4gJ+KxoicsCiAgJ8msJyA9PiAn6p6tJywKICAnya8nID0+ICfGnCcsCiAgJ8mxJyA9PiAn4rGuJywKICAnybInID0+ICfGnScsCiAgJ8m1JyA9PiAnxp8nLAogICfJvScgPT4gJ+KxpCcsCiAgJ8qAJyA9PiAnxqYnLAogICfKgicgPT4gJ+qfhScsCiAgJ8qDJyA9PiAnxqknLAogICfKhycgPT4gJ+qesScsCiAgJ8qIJyA9PiAnxq4nLAogICfKiScgPT4gJ8mEJywKICAnyoonID0+ICfGsScsCiAgJ8qLJyA9PiAnxrInLAogICfKjCcgPT4gJ8mFJywKICAnypInID0+ICfGtycsCiAgJ8qdJyA9PiAn6p6yJywKICAnyp4nID0+ICfqnrAnLAogICfNhScgPT4gJ86ZJywKICAnzbEnID0+ICfNsCcsCiAgJ82zJyA9PiAnzbInLAogICfNtycgPT4gJ822JywKICAnzbsnID0+ICfPvScsCiAgJ828JyA9PiAnz74nLAogICfNvScgPT4gJ8+/JywKICAnzqwnID0+ICfOhicsCiAgJ86tJyA9PiAnzognLAogICfOricgPT4gJ86JJywKICAnzq8nID0+ICfOiicsCiAgJ86xJyA9PiAnzpEnLAogICfOsicgPT4gJ86SJywKICAnzrMnID0+ICfOkycsCiAgJ860JyA9PiAnzpQnLAogICfOtScgPT4gJ86VJywKICAnzrYnID0+ICfOlicsCiAgJ863JyA9PiAnzpcnLAogICfOuCcgPT4gJ86YJywKICAnzrknID0+ICfOmScsCiAgJ866JyA9PiAnzponLAogICfOuycgPT4gJ86bJywKICAnzrwnID0+ICfOnCcsCiAgJ869JyA9PiAnzp0nLAogICfOvicgPT4gJ86eJywKICAnzr8nID0+ICfOnycsCiAgJ8+AJyA9PiAnzqAnLAogICfPgScgPT4gJ86hJywKICAnz4InID0+ICfOoycsCiAgJ8+DJyA9PiAnzqMnLAogICfPhCcgPT4gJ86kJywKICAnz4UnID0+ICfOpScsCiAgJ8+GJyA9PiAnzqYnLAogICfPhycgPT4gJ86nJywKICAnz4gnID0+ICfOqCcsCiAgJ8+JJyA9PiAnzqknLAogICfPiicgPT4gJ86qJywKICAnz4snID0+ICfOqycsCiAgJ8+MJyA9PiAnzownLAogICfPjScgPT4gJ86OJywKICAnz44nID0+ICfOjycsCiAgJ8+QJyA9PiAnzpInLAogICfPkScgPT4gJ86YJywKICAnz5UnID0+ICfOpicsCiAgJ8+WJyA9PiAnzqAnLAogICfPlycgPT4gJ8+PJywKICAnz5knID0+ICfPmCcsCiAgJ8+bJyA9PiAnz5onLAogICfPnScgPT4gJ8+cJywKICAnz58nID0+ICfPnicsCiAgJ8+hJyA9PiAnz6AnLAogICfPoycgPT4gJ8+iJywKICAnz6UnID0+ICfPpCcsCiAgJ8+nJyA9PiAnz6YnLAogICfPqScgPT4gJ8+oJywKICAnz6snID0+ICfPqicsCiAgJ8+tJyA9PiAnz6wnLAogICfPrycgPT4gJ8+uJywKICAnz7AnID0+ICfOmicsCiAgJ8+xJyA9PiAnzqEnLAogICfPsicgPT4gJ8+5JywKICAnz7MnID0+ICfNvycsCiAgJ8+1JyA9PiAnzpUnLAogICfPuCcgPT4gJ8+3JywKICAnz7snID0+ICfPuicsCiAgJ9CwJyA9PiAn0JAnLAogICfQsScgPT4gJ9CRJywKICAn0LInID0+ICfQkicsCiAgJ9CzJyA9PiAn0JMnLAogICfQtCcgPT4gJ9CUJywKICAn0LUnID0+ICfQlScsCiAgJ9C2JyA9PiAn0JYnLAogICfQtycgPT4gJ9CXJywKICAn0LgnID0+ICfQmCcsCiAgJ9C5JyA9PiAn0JknLAogICfQuicgPT4gJ9CaJywKICAn0LsnID0+ICfQmycsCiAgJ9C8JyA9PiAn0JwnLAogICfQvScgPT4gJ9CdJywKICAn0L4nID0+ICfQnicsCiAgJ9C/JyA9PiAn0J8nLAogICfRgCcgPT4gJ9CgJywKICAn0YEnID0+ICfQoScsCiAgJ9GCJyA9PiAn0KInLAogICfRgycgPT4gJ9CjJywKICAn0YQnID0+ICfQpCcsCiAgJ9GFJyA9PiAn0KUnLAogICfRhicgPT4gJ9CmJywKICAn0YcnID0+ICfQpycsCiAgJ9GIJyA9PiAn0KgnLAogICfRiScgPT4gJ9CpJywKICAn0YonID0+ICfQqicsCiAgJ9GLJyA9PiAn0KsnLAogICfRjCcgPT4gJ9CsJywKICAn0Y0nID0+ICfQrScsCiAgJ9GOJyA9PiAn0K4nLAogICfRjycgPT4gJ9CvJywKICAn0ZAnID0+ICfQgCcsCiAgJ9GRJyA9PiAn0IEnLAogICfRkicgPT4gJ9CCJywKICAn0ZMnID0+ICfQgycsCiAgJ9GUJyA9PiAn0IQnLAogICfRlScgPT4gJ9CFJywKICAn0ZYnID0+ICfQhicsCiAgJ9GXJyA9PiAn0IcnLAogICfRmCcgPT4gJ9CIJywKICAn0ZknID0+ICfQiScsCiAgJ9GaJyA9PiAn0IonLAogICfRmycgPT4gJ9CLJywKICAn0ZwnID0+ICfQjCcsCiAgJ9GdJyA9PiAn0I0nLAogICfRnicgPT4gJ9COJywKICAn0Z8nID0+ICfQjycsCiAgJ9GhJyA9PiAn0aAnLAogICfRoycgPT4gJ9GiJywKICAn0aUnID0+ICfRpCcsCiAgJ9GnJyA9PiAn0aYnLAogICfRqScgPT4gJ9GoJywKICAn0asnID0+ICfRqicsCiAgJ9GtJyA9PiAn0awnLAogICfRrycgPT4gJ9GuJywKICAn0bEnID0+ICfRsCcsCiAgJ9GzJyA9PiAn0bInLAogICfRtScgPT4gJ9G0JywKICAn0bcnID0+ICfRticsCiAgJ9G5JyA9PiAn0bgnLAogICfRuycgPT4gJ9G6JywKICAn0b0nID0+ICfRvCcsCiAgJ9G/JyA9PiAn0b4nLAogICfSgScgPT4gJ9KAJywKICAn0osnID0+ICfSiicsCiAgJ9KNJyA9PiAn0ownLAogICfSjycgPT4gJ9KOJywKICAn0pEnID0+ICfSkCcsCiAgJ9KTJyA9PiAn0pInLAogICfSlScgPT4gJ9KUJywKICAn0pcnID0+ICfSlicsCiAgJ9KZJyA9PiAn0pgnLAogICfSmycgPT4gJ9KaJywKICAn0p0nID0+ICfSnCcsCiAgJ9KfJyA9PiAn0p4nLAogICfSoScgPT4gJ9KgJywKICAn0qMnID0+ICfSoicsCiAgJ9KlJyA9PiAn0qQnLAogICfSpycgPT4gJ9KmJywKICAn0qknID0+ICfSqCcsCiAgJ9KrJyA9PiAn0qonLAogICfSrScgPT4gJ9KsJywKICAn0q8nID0+ICfSricsCiAgJ9KxJyA9PiAn0rAnLAogICfSsycgPT4gJ9KyJywKICAn0rUnID0+ICfStCcsCiAgJ9K3JyA9PiAn0rYnLAogICfSuScgPT4gJ9K4JywKICAn0rsnID0+ICfSuicsCiAgJ9K9JyA9PiAn0rwnLAogICfSvycgPT4gJ9K+JywKICAn04InID0+ICfTgScsCiAgJ9OEJyA9PiAn04MnLAogICfThicgPT4gJ9OFJywKICAn04gnID0+ICfThycsCiAgJ9OKJyA9PiAn04knLAogICfTjCcgPT4gJ9OLJywKICAn044nID0+ICfTjScsCiAgJ9OPJyA9PiAn04AnLAogICfTkScgPT4gJ9OQJywKICAn05MnID0+ICfTkicsCiAgJ9OVJyA9PiAn05QnLAogICfTlycgPT4gJ9OWJywKICAn05knID0+ICfTmCcsCiAgJ9ObJyA9PiAn05onLAogICfTnScgPT4gJ9OcJywKICAn058nID0+ICfTnicsCiAgJ9OhJyA9PiAn06AnLAogICfToycgPT4gJ9OiJywKICAn06UnID0+ICfTpCcsCiAgJ9OnJyA9PiAn06YnLAogICfTqScgPT4gJ9OoJywKICAn06snID0+ICfTqicsCiAgJ9OtJyA9PiAn06wnLAogICfTrycgPT4gJ9OuJywKICAn07EnID0+ICfTsCcsCiAgJ9OzJyA9PiAn07InLAogICfTtScgPT4gJ9O0JywKICAn07cnID0+ICfTticsCiAgJ9O5JyA9PiAn07gnLAogICfTuycgPT4gJ9O6JywKICAn070nID0+ICfTvCcsCiAgJ9O/JyA9PiAn074nLAogICfUgScgPT4gJ9SAJywKICAn1IMnID0+ICfUgicsCiAgJ9SFJyA9PiAn1IQnLAogICfUhycgPT4gJ9SGJywKICAn1IknID0+ICfUiCcsCiAgJ9SLJyA9PiAn1IonLAogICfUjScgPT4gJ9SMJywKICAn1I8nID0+ICfUjicsCiAgJ9SRJyA9PiAn1JAnLAogICfUkycgPT4gJ9SSJywKICAn1JUnID0+ICfUlCcsCiAgJ9SXJyA9PiAn1JYnLAogICfUmScgPT4gJ9SYJywKICAn1JsnID0+ICfUmicsCiAgJ9SdJyA9PiAn1JwnLAogICfUnycgPT4gJ9SeJywKICAn1KEnID0+ICfUoCcsCiAgJ9SjJyA9PiAn1KInLAogICfUpScgPT4gJ9SkJywKICAn1KcnID0+ICfUpicsCiAgJ9SpJyA9PiAn1KgnLAogICfUqycgPT4gJ9SqJywKICAn1K0nID0+ICfUrCcsCiAgJ9SvJyA9PiAn1K4nLAogICfVoScgPT4gJ9SxJywKICAn1aInID0+ICfUsicsCiAgJ9WjJyA9PiAn1LMnLAogICfVpCcgPT4gJ9S0JywKICAn1aUnID0+ICfUtScsCiAgJ9WmJyA9PiAn1LYnLAogICfVpycgPT4gJ9S3JywKICAn1agnID0+ICfUuCcsCiAgJ9WpJyA9PiAn1LknLAogICfVqicgPT4gJ9S6JywKICAn1asnID0+ICfUuycsCiAgJ9WsJyA9PiAn1LwnLAogICfVrScgPT4gJ9S9JywKICAn1a4nID0+ICfUvicsCiAgJ9WvJyA9PiAn1L8nLAogICfVsCcgPT4gJ9WAJywKICAn1bEnID0+ICfVgScsCiAgJ9WyJyA9PiAn1YInLAogICfVsycgPT4gJ9WDJywKICAn1bQnID0+ICfVhCcsCiAgJ9W1JyA9PiAn1YUnLAogICfVticgPT4gJ9WGJywKICAn1bcnID0+ICfVhycsCiAgJ9W4JyA9PiAn1YgnLAogICfVuScgPT4gJ9WJJywKICAn1bonID0+ICfViicsCiAgJ9W7JyA9PiAn1YsnLAogICfVvCcgPT4gJ9WMJywKICAn1b0nID0+ICfVjScsCiAgJ9W+JyA9PiAn1Y4nLAogICfVvycgPT4gJ9WPJywKICAn1oAnID0+ICfVkCcsCiAgJ9aBJyA9PiAn1ZEnLAogICfWgicgPT4gJ9WSJywKICAn1oMnID0+ICfVkycsCiAgJ9aEJyA9PiAn1ZQnLAogICfWhScgPT4gJ9WVJywKICAn1oYnID0+ICfVlicsCiAgJ+GDkCcgPT4gJ+GykCcsCiAgJ+GDkScgPT4gJ+GykScsCiAgJ+GDkicgPT4gJ+GykicsCiAgJ+GDkycgPT4gJ+GykycsCiAgJ+GDlCcgPT4gJ+GylCcsCiAgJ+GDlScgPT4gJ+GylScsCiAgJ+GDlicgPT4gJ+GylicsCiAgJ+GDlycgPT4gJ+GylycsCiAgJ+GDmCcgPT4gJ+GymCcsCiAgJ+GDmScgPT4gJ+GymScsCiAgJ+GDmicgPT4gJ+GymicsCiAgJ+GDmycgPT4gJ+GymycsCiAgJ+GDnCcgPT4gJ+GynCcsCiAgJ+GDnScgPT4gJ+GynScsCiAgJ+GDnicgPT4gJ+GynicsCiAgJ+GDnycgPT4gJ+GynycsCiAgJ+GDoCcgPT4gJ+GyoCcsCiAgJ+GDoScgPT4gJ+GyoScsCiAgJ+GDoicgPT4gJ+GyoicsCiAgJ+GDoycgPT4gJ+GyoycsCiAgJ+GDpCcgPT4gJ+GypCcsCiAgJ+GDpScgPT4gJ+GypScsCiAgJ+GDpicgPT4gJ+GypicsCiAgJ+GDpycgPT4gJ+GypycsCiAgJ+GDqCcgPT4gJ+GyqCcsCiAgJ+GDqScgPT4gJ+GyqScsCiAgJ+GDqicgPT4gJ+GyqicsCiAgJ+GDqycgPT4gJ+GyqycsCiAgJ+GDrCcgPT4gJ+GyrCcsCiAgJ+GDrScgPT4gJ+GyrScsCiAgJ+GDricgPT4gJ+GyricsCiAgJ+GDrycgPT4gJ+GyrycsCiAgJ+GDsCcgPT4gJ+GysCcsCiAgJ+GDsScgPT4gJ+GysScsCiAgJ+GDsicgPT4gJ+GysicsCiAgJ+GDsycgPT4gJ+GysycsCiAgJ+GDtCcgPT4gJ+GytCcsCiAgJ+GDtScgPT4gJ+GytScsCiAgJ+GDticgPT4gJ+GyticsCiAgJ+GDtycgPT4gJ+GytycsCiAgJ+GDuCcgPT4gJ+GyuCcsCiAgJ+GDuScgPT4gJ+GyuScsCiAgJ+GDuicgPT4gJ+GyuicsCiAgJ+GDvScgPT4gJ+GyvScsCiAgJ+GDvicgPT4gJ+GyvicsCiAgJ+GDvycgPT4gJ+GyvycsCiAgJ+GPuCcgPT4gJ+GPsCcsCiAgJ+GPuScgPT4gJ+GPsScsCiAgJ+GPuicgPT4gJ+GPsicsCiAgJ+GPuycgPT4gJ+GPsycsCiAgJ+GPvCcgPT4gJ+GPtCcsCiAgJ+GPvScgPT4gJ+GPtScsCiAgJ+GygCcgPT4gJ9CSJywKICAn4bKBJyA9PiAn0JQnLAogICfhsoInID0+ICfQnicsCiAgJ+GygycgPT4gJ9ChJywKICAn4bKEJyA9PiAn0KInLAogICfhsoUnID0+ICfQoicsCiAgJ+GyhicgPT4gJ9CqJywKICAn4bKHJyA9PiAn0aInLAogICfhsognID0+ICfqmYonLAogICfhtbknID0+ICfqnb0nLAogICfhtb0nID0+ICfisaMnLAogICfhto4nID0+ICfqn4YnLAogICfhuIEnID0+ICfhuIAnLAogICfhuIMnID0+ICfhuIInLAogICfhuIUnID0+ICfhuIQnLAogICfhuIcnID0+ICfhuIYnLAogICfhuIknID0+ICfhuIgnLAogICfhuIsnID0+ICfhuIonLAogICfhuI0nID0+ICfhuIwnLAogICfhuI8nID0+ICfhuI4nLAogICfhuJEnID0+ICfhuJAnLAogICfhuJMnID0+ICfhuJInLAogICfhuJUnID0+ICfhuJQnLAogICfhuJcnID0+ICfhuJYnLAogICfhuJknID0+ICfhuJgnLAogICfhuJsnID0+ICfhuJonLAogICfhuJ0nID0+ICfhuJwnLAogICfhuJ8nID0+ICfhuJ4nLAogICfhuKEnID0+ICfhuKAnLAogICfhuKMnID0+ICfhuKInLAogICfhuKUnID0+ICfhuKQnLAogICfhuKcnID0+ICfhuKYnLAogICfhuKknID0+ICfhuKgnLAogICfhuKsnID0+ICfhuKonLAogICfhuK0nID0+ICfhuKwnLAogICfhuK8nID0+ICfhuK4nLAogICfhuLEnID0+ICfhuLAnLAogICfhuLMnID0+ICfhuLInLAogICfhuLUnID0+ICfhuLQnLAogICfhuLcnID0+ICfhuLYnLAogICfhuLknID0+ICfhuLgnLAogICfhuLsnID0+ICfhuLonLAogICfhuL0nID0+ICfhuLwnLAogICfhuL8nID0+ICfhuL4nLAogICfhuYEnID0+ICfhuYAnLAogICfhuYMnID0+ICfhuYInLAogICfhuYUnID0+ICfhuYQnLAogICfhuYcnID0+ICfhuYYnLAogICfhuYknID0+ICfhuYgnLAogICfhuYsnID0+ICfhuYonLAogICfhuY0nID0+ICfhuYwnLAogICfhuY8nID0+ICfhuY4nLAogICfhuZEnID0+ICfhuZAnLAogICfhuZMnID0+ICfhuZInLAogICfhuZUnID0+ICfhuZQnLAogICfhuZcnID0+ICfhuZYnLAogICfhuZknID0+ICfhuZgnLAogICfhuZsnID0+ICfhuZonLAogICfhuZ0nID0+ICfhuZwnLAogICfhuZ8nID0+ICfhuZ4nLAogICfhuaEnID0+ICfhuaAnLAogICfhuaMnID0+ICfhuaInLAogICfhuaUnID0+ICfhuaQnLAogICfhuacnID0+ICfhuaYnLAogICfhuaknID0+ICfhuagnLAogICfhuasnID0+ICfhuaonLAogICfhua0nID0+ICfhuawnLAogICfhua8nID0+ICfhua4nLAogICfhubEnID0+ICfhubAnLAogICfhubMnID0+ICfhubInLAogICfhubUnID0+ICfhubQnLAogICfhubcnID0+ICfhubYnLAogICfhubknID0+ICfhubgnLAogICfhubsnID0+ICfhubonLAogICfhub0nID0+ICfhubwnLAogICfhub8nID0+ICfhub4nLAogICfhuoEnID0+ICfhuoAnLAogICfhuoMnID0+ICfhuoInLAogICfhuoUnID0+ICfhuoQnLAogICfhuocnID0+ICfhuoYnLAogICfhuoknID0+ICfhuognLAogICfhuosnID0+ICfhuoonLAogICfhuo0nID0+ICfhuownLAogICfhuo8nID0+ICfhuo4nLAogICfhupEnID0+ICfhupAnLAogICfhupMnID0+ICfhupInLAogICfhupUnID0+ICfhupQnLAogICfhupsnID0+ICfhuaAnLAogICfhuqEnID0+ICfhuqAnLAogICfhuqMnID0+ICfhuqInLAogICfhuqUnID0+ICfhuqQnLAogICfhuqcnID0+ICfhuqYnLAogICfhuqknID0+ICfhuqgnLAogICfhuqsnID0+ICfhuqonLAogICfhuq0nID0+ICfhuqwnLAogICfhuq8nID0+ICfhuq4nLAogICfhurEnID0+ICfhurAnLAogICfhurMnID0+ICfhurInLAogICfhurUnID0+ICfhurQnLAogICfhurcnID0+ICfhurYnLAogICfhurknID0+ICfhurgnLAogICfhursnID0+ICfhuronLAogICfhur0nID0+ICfhurwnLAogICfhur8nID0+ICfhur4nLAogICfhu4EnID0+ICfhu4AnLAogICfhu4MnID0+ICfhu4InLAogICfhu4UnID0+ICfhu4QnLAogICfhu4cnID0+ICfhu4YnLAogICfhu4knID0+ICfhu4gnLAogICfhu4snID0+ICfhu4onLAogICfhu40nID0+ICfhu4wnLAogICfhu48nID0+ICfhu44nLAogICfhu5EnID0+ICfhu5AnLAogICfhu5MnID0+ICfhu5InLAogICfhu5UnID0+ICfhu5QnLAogICfhu5cnID0+ICfhu5YnLAogICfhu5knID0+ICfhu5gnLAogICfhu5snID0+ICfhu5onLAogICfhu50nID0+ICfhu5wnLAogICfhu58nID0+ICfhu54nLAogICfhu6EnID0+ICfhu6AnLAogICfhu6MnID0+ICfhu6InLAogICfhu6UnID0+ICfhu6QnLAogICfhu6cnID0+ICfhu6YnLAogICfhu6knID0+ICfhu6gnLAogICfhu6snID0+ICfhu6onLAogICfhu60nID0+ICfhu6wnLAogICfhu68nID0+ICfhu64nLAogICfhu7EnID0+ICfhu7AnLAogICfhu7MnID0+ICfhu7InLAogICfhu7UnID0+ICfhu7QnLAogICfhu7cnID0+ICfhu7YnLAogICfhu7knID0+ICfhu7gnLAogICfhu7snID0+ICfhu7onLAogICfhu70nID0+ICfhu7wnLAogICfhu78nID0+ICfhu74nLAogICfhvIAnID0+ICfhvIgnLAogICfhvIEnID0+ICfhvIknLAogICfhvIInID0+ICfhvIonLAogICfhvIMnID0+ICfhvIsnLAogICfhvIQnID0+ICfhvIwnLAogICfhvIUnID0+ICfhvI0nLAogICfhvIYnID0+ICfhvI4nLAogICfhvIcnID0+ICfhvI8nLAogICfhvJAnID0+ICfhvJgnLAogICfhvJEnID0+ICfhvJknLAogICfhvJInID0+ICfhvJonLAogICfhvJMnID0+ICfhvJsnLAogICfhvJQnID0+ICfhvJwnLAogICfhvJUnID0+ICfhvJ0nLAogICfhvKAnID0+ICfhvKgnLAogICfhvKEnID0+ICfhvKknLAogICfhvKInID0+ICfhvKonLAogICfhvKMnID0+ICfhvKsnLAogICfhvKQnID0+ICfhvKwnLAogICfhvKUnID0+ICfhvK0nLAogICfhvKYnID0+ICfhvK4nLAogICfhvKcnID0+ICfhvK8nLAogICfhvLAnID0+ICfhvLgnLAogICfhvLEnID0+ICfhvLknLAogICfhvLInID0+ICfhvLonLAogICfhvLMnID0+ICfhvLsnLAogICfhvLQnID0+ICfhvLwnLAogICfhvLUnID0+ICfhvL0nLAogICfhvLYnID0+ICfhvL4nLAogICfhvLcnID0+ICfhvL8nLAogICfhvYAnID0+ICfhvYgnLAogICfhvYEnID0+ICfhvYknLAogICfhvYInID0+ICfhvYonLAogICfhvYMnID0+ICfhvYsnLAogICfhvYQnID0+ICfhvYwnLAogICfhvYUnID0+ICfhvY0nLAogICfhvZEnID0+ICfhvZknLAogICfhvZMnID0+ICfhvZsnLAogICfhvZUnID0+ICfhvZ0nLAogICfhvZcnID0+ICfhvZ8nLAogICfhvaAnID0+ICfhvagnLAogICfhvaEnID0+ICfhvaknLAogICfhvaInID0+ICfhvaonLAogICfhvaMnID0+ICfhvasnLAogICfhvaQnID0+ICfhvawnLAogICfhvaUnID0+ICfhva0nLAogICfhvaYnID0+ICfhva4nLAogICfhvacnID0+ICfhva8nLAogICfhvbAnID0+ICfhvronLAogICfhvbEnID0+ICfhvrsnLAogICfhvbInID0+ICfhv4gnLAogICfhvbMnID0+ICfhv4knLAogICfhvbQnID0+ICfhv4onLAogICfhvbUnID0+ICfhv4snLAogICfhvbYnID0+ICfhv5onLAogICfhvbcnID0+ICfhv5snLAogICfhvbgnID0+ICfhv7gnLAogICfhvbknID0+ICfhv7knLAogICfhvbonID0+ICfhv6onLAogICfhvbsnID0+ICfhv6snLAogICfhvbwnID0+ICfhv7onLAogICfhvb0nID0+ICfhv7snLAogICfhvoAnID0+ICfhvognLAogICfhvoEnID0+ICfhvoknLAogICfhvoInID0+ICfhvoonLAogICfhvoMnID0+ICfhvosnLAogICfhvoQnID0+ICfhvownLAogICfhvoUnID0+ICfhvo0nLAogICfhvoYnID0+ICfhvo4nLAogICfhvocnID0+ICfhvo8nLAogICfhvpAnID0+ICfhvpgnLAogICfhvpEnID0+ICfhvpknLAogICfhvpInID0+ICfhvponLAogICfhvpMnID0+ICfhvpsnLAogICfhvpQnID0+ICfhvpwnLAogICfhvpUnID0+ICfhvp0nLAogICfhvpYnID0+ICfhvp4nLAogICfhvpcnID0+ICfhvp8nLAogICfhvqAnID0+ICfhvqgnLAogICfhvqEnID0+ICfhvqknLAogICfhvqInID0+ICfhvqonLAogICfhvqMnID0+ICfhvqsnLAogICfhvqQnID0+ICfhvqwnLAogICfhvqUnID0+ICfhvq0nLAogICfhvqYnID0+ICfhvq4nLAogICfhvqcnID0+ICfhvq8nLAogICfhvrAnID0+ICfhvrgnLAogICfhvrEnID0+ICfhvrknLAogICfhvrMnID0+ICfhvrwnLAogICfhvr4nID0+ICfOmScsCiAgJ+G/gycgPT4gJ+G/jCcsCiAgJ+G/kCcgPT4gJ+G/mCcsCiAgJ+G/kScgPT4gJ+G/mScsCiAgJ+G/oCcgPT4gJ+G/qCcsCiAgJ+G/oScgPT4gJ+G/qScsCiAgJ+G/pScgPT4gJ+G/rCcsCiAgJ+G/sycgPT4gJ+G/vCcsCiAgJ+KFjicgPT4gJ+KEsicsCiAgJ+KFsCcgPT4gJ+KFoCcsCiAgJ+KFsScgPT4gJ+KFoScsCiAgJ+KFsicgPT4gJ+KFoicsCiAgJ+KFsycgPT4gJ+KFoycsCiAgJ+KFtCcgPT4gJ+KFpCcsCiAgJ+KFtScgPT4gJ+KFpScsCiAgJ+KFticgPT4gJ+KFpicsCiAgJ+KFtycgPT4gJ+KFpycsCiAgJ+KFuCcgPT4gJ+KFqCcsCiAgJ+KFuScgPT4gJ+KFqScsCiAgJ+KFuicgPT4gJ+KFqicsCiAgJ+KFuycgPT4gJ+KFqycsCiAgJ+KFvCcgPT4gJ+KFrCcsCiAgJ+KFvScgPT4gJ+KFrScsCiAgJ+KFvicgPT4gJ+KFricsCiAgJ+KFvycgPT4gJ+KFrycsCiAgJ+KGhCcgPT4gJ+KGgycsCiAgJ+KTkCcgPT4gJ+KSticsCiAgJ+KTkScgPT4gJ+KStycsCiAgJ+KTkicgPT4gJ+KSuCcsCiAgJ+KTkycgPT4gJ+KSuScsCiAgJ+KTlCcgPT4gJ+KSuicsCiAgJ+KTlScgPT4gJ+KSuycsCiAgJ+KTlicgPT4gJ+KSvCcsCiAgJ+KTlycgPT4gJ+KSvScsCiAgJ+KTmCcgPT4gJ+KSvicsCiAgJ+KTmScgPT4gJ+KSvycsCiAgJ+KTmicgPT4gJ+KTgCcsCiAgJ+KTmycgPT4gJ+KTgScsCiAgJ+KTnCcgPT4gJ+KTgicsCiAgJ+KTnScgPT4gJ+KTgycsCiAgJ+KTnicgPT4gJ+KThCcsCiAgJ+KTnycgPT4gJ+KThScsCiAgJ+KToCcgPT4gJ+KThicsCiAgJ+KToScgPT4gJ+KThycsCiAgJ+KToicgPT4gJ+KTiCcsCiAgJ+KToycgPT4gJ+KTiScsCiAgJ+KTpCcgPT4gJ+KTiicsCiAgJ+KTpScgPT4gJ+KTiycsCiAgJ+KTpicgPT4gJ+KTjCcsCiAgJ+KTpycgPT4gJ+KTjScsCiAgJ+KTqCcgPT4gJ+KTjicsCiAgJ+KTqScgPT4gJ+KTjycsCiAgJ+KwsCcgPT4gJ+KwgCcsCiAgJ+KwsScgPT4gJ+KwgScsCiAgJ+KwsicgPT4gJ+KwgicsCiAgJ+KwsycgPT4gJ+KwgycsCiAgJ+KwtCcgPT4gJ+KwhCcsCiAgJ+KwtScgPT4gJ+KwhScsCiAgJ+KwticgPT4gJ+KwhicsCiAgJ+KwtycgPT4gJ+KwhycsCiAgJ+KwuCcgPT4gJ+KwiCcsCiAgJ+KwuScgPT4gJ+KwiScsCiAgJ+KwuicgPT4gJ+KwiicsCiAgJ+KwuycgPT4gJ+KwiycsCiAgJ+KwvCcgPT4gJ+KwjCcsCiAgJ+KwvScgPT4gJ+KwjScsCiAgJ+KwvicgPT4gJ+KwjicsCiAgJ+KwvycgPT4gJ+KwjycsCiAgJ+KxgCcgPT4gJ+KwkCcsCiAgJ+KxgScgPT4gJ+KwkScsCiAgJ+KxgicgPT4gJ+KwkicsCiAgJ+KxgycgPT4gJ+KwkycsCiAgJ+KxhCcgPT4gJ+KwlCcsCiAgJ+KxhScgPT4gJ+KwlScsCiAgJ+KxhicgPT4gJ+KwlicsCiAgJ+KxhycgPT4gJ+KwlycsCiAgJ+KxiCcgPT4gJ+KwmCcsCiAgJ+KxiScgPT4gJ+KwmScsCiAgJ+KxiicgPT4gJ+KwmicsCiAgJ+KxiycgPT4gJ+KwmycsCiAgJ+KxjCcgPT4gJ+KwnCcsCiAgJ+KxjScgPT4gJ+KwnScsCiAgJ+KxjicgPT4gJ+KwnicsCiAgJ+KxjycgPT4gJ+KwnycsCiAgJ+KxkCcgPT4gJ+KwoCcsCiAgJ+KxkScgPT4gJ+KwoScsCiAgJ+KxkicgPT4gJ+KwoicsCiAgJ+KxkycgPT4gJ+KwoycsCiAgJ+KxlCcgPT4gJ+KwpCcsCiAgJ+KxlScgPT4gJ+KwpScsCiAgJ+KxlicgPT4gJ+KwpicsCiAgJ+KxlycgPT4gJ+KwpycsCiAgJ+KxmCcgPT4gJ+KwqCcsCiAgJ+KxmScgPT4gJ+KwqScsCiAgJ+KxmicgPT4gJ+KwqicsCiAgJ+KxmycgPT4gJ+KwqycsCiAgJ+KxnCcgPT4gJ+KwrCcsCiAgJ+KxnScgPT4gJ+KwrScsCiAgJ+KxnicgPT4gJ+KwricsCiAgJ+KxoScgPT4gJ+KxoCcsCiAgJ+KxpScgPT4gJ8i6JywKICAn4rGmJyA9PiAnyL4nLAogICfisagnID0+ICfisacnLAogICfisaonID0+ICfisaknLAogICfisawnID0+ICfisasnLAogICfisbMnID0+ICfisbInLAogICfisbYnID0+ICfisbUnLAogICfisoEnID0+ICfisoAnLAogICfisoMnID0+ICfisoInLAogICfisoUnID0+ICfisoQnLAogICfisocnID0+ICfisoYnLAogICfisoknID0+ICfisognLAogICfisosnID0+ICfisoonLAogICfiso0nID0+ICfisownLAogICfiso8nID0+ICfiso4nLAogICfispEnID0+ICfispAnLAogICfispMnID0+ICfispInLAogICfispUnID0+ICfispQnLAogICfispcnID0+ICfispYnLAogICfispknID0+ICfispgnLAogICfispsnID0+ICfisponLAogICfisp0nID0+ICfispwnLAogICfisp8nID0+ICfisp4nLAogICfisqEnID0+ICfisqAnLAogICfisqMnID0+ICfisqInLAogICfisqUnID0+ICfisqQnLAogICfisqcnID0+ICfisqYnLAogICfisqknID0+ICfisqgnLAogICfisqsnID0+ICfisqonLAogICfisq0nID0+ICfisqwnLAogICfisq8nID0+ICfisq4nLAogICfisrEnID0+ICfisrAnLAogICfisrMnID0+ICfisrInLAogICfisrUnID0+ICfisrQnLAogICfisrcnID0+ICfisrYnLAogICfisrknID0+ICfisrgnLAogICfisrsnID0+ICfisronLAogICfisr0nID0+ICfisrwnLAogICfisr8nID0+ICfisr4nLAogICfis4EnID0+ICfis4AnLAogICfis4MnID0+ICfis4InLAogICfis4UnID0+ICfis4QnLAogICfis4cnID0+ICfis4YnLAogICfis4knID0+ICfis4gnLAogICfis4snID0+ICfis4onLAogICfis40nID0+ICfis4wnLAogICfis48nID0+ICfis44nLAogICfis5EnID0+ICfis5AnLAogICfis5MnID0+ICfis5InLAogICfis5UnID0+ICfis5QnLAogICfis5cnID0+ICfis5YnLAogICfis5knID0+ICfis5gnLAogICfis5snID0+ICfis5onLAogICfis50nID0+ICfis5wnLAogICfis58nID0+ICfis54nLAogICfis6EnID0+ICfis6AnLAogICfis6MnID0+ICfis6InLAogICfis6wnID0+ICfis6snLAogICfis64nID0+ICfis60nLAogICfis7MnID0+ICfis7InLAogICfitIAnID0+ICfhgqAnLAogICfitIEnID0+ICfhgqEnLAogICfitIInID0+ICfhgqInLAogICfitIMnID0+ICfhgqMnLAogICfitIQnID0+ICfhgqQnLAogICfitIUnID0+ICfhgqUnLAogICfitIYnID0+ICfhgqYnLAogICfitIcnID0+ICfhgqcnLAogICfitIgnID0+ICfhgqgnLAogICfitIknID0+ICfhgqknLAogICfitIonID0+ICfhgqonLAogICfitIsnID0+ICfhgqsnLAogICfitIwnID0+ICfhgqwnLAogICfitI0nID0+ICfhgq0nLAogICfitI4nID0+ICfhgq4nLAogICfitI8nID0+ICfhgq8nLAogICfitJAnID0+ICfhgrAnLAogICfitJEnID0+ICfhgrEnLAogICfitJInID0+ICfhgrInLAogICfitJMnID0+ICfhgrMnLAogICfitJQnID0+ICfhgrQnLAogICfitJUnID0+ICfhgrUnLAogICfitJYnID0+ICfhgrYnLAogICfitJcnID0+ICfhgrcnLAogICfitJgnID0+ICfhgrgnLAogICfitJknID0+ICfhgrknLAogICfitJonID0+ICfhgronLAogICfitJsnID0+ICfhgrsnLAogICfitJwnID0+ICfhgrwnLAogICfitJ0nID0+ICfhgr0nLAogICfitJ4nID0+ICfhgr4nLAogICfitJ8nID0+ICfhgr8nLAogICfitKAnID0+ICfhg4AnLAogICfitKEnID0+ICfhg4EnLAogICfitKInID0+ICfhg4InLAogICfitKMnID0+ICfhg4MnLAogICfitKQnID0+ICfhg4QnLAogICfitKUnID0+ICfhg4UnLAogICfitKcnID0+ICfhg4cnLAogICfitK0nID0+ICfhg40nLAogICfqmYEnID0+ICfqmYAnLAogICfqmYMnID0+ICfqmYInLAogICfqmYUnID0+ICfqmYQnLAogICfqmYcnID0+ICfqmYYnLAogICfqmYknID0+ICfqmYgnLAogICfqmYsnID0+ICfqmYonLAogICfqmY0nID0+ICfqmYwnLAogICfqmY8nID0+ICfqmY4nLAogICfqmZEnID0+ICfqmZAnLAogICfqmZMnID0+ICfqmZInLAogICfqmZUnID0+ICfqmZQnLAogICfqmZcnID0+ICfqmZYnLAogICfqmZknID0+ICfqmZgnLAogICfqmZsnID0+ICfqmZonLAogICfqmZ0nID0+ICfqmZwnLAogICfqmZ8nID0+ICfqmZ4nLAogICfqmaEnID0+ICfqmaAnLAogICfqmaMnID0+ICfqmaInLAogICfqmaUnID0+ICfqmaQnLAogICfqmacnID0+ICfqmaYnLAogICfqmaknID0+ICfqmagnLAogICfqmasnID0+ICfqmaonLAogICfqma0nID0+ICfqmawnLAogICfqmoEnID0+ICfqmoAnLAogICfqmoMnID0+ICfqmoInLAogICfqmoUnID0+ICfqmoQnLAogICfqmocnID0+ICfqmoYnLAogICfqmoknID0+ICfqmognLAogICfqmosnID0+ICfqmoonLAogICfqmo0nID0+ICfqmownLAogICfqmo8nID0+ICfqmo4nLAogICfqmpEnID0+ICfqmpAnLAogICfqmpMnID0+ICfqmpInLAogICfqmpUnID0+ICfqmpQnLAogICfqmpcnID0+ICfqmpYnLAogICfqmpknID0+ICfqmpgnLAogICfqmpsnID0+ICfqmponLAogICfqnKMnID0+ICfqnKInLAogICfqnKUnID0+ICfqnKQnLAogICfqnKcnID0+ICfqnKYnLAogICfqnKknID0+ICfqnKgnLAogICfqnKsnID0+ICfqnKonLAogICfqnK0nID0+ICfqnKwnLAogICfqnK8nID0+ICfqnK4nLAogICfqnLMnID0+ICfqnLInLAogICfqnLUnID0+ICfqnLQnLAogICfqnLcnID0+ICfqnLYnLAogICfqnLknID0+ICfqnLgnLAogICfqnLsnID0+ICfqnLonLAogICfqnL0nID0+ICfqnLwnLAogICfqnL8nID0+ICfqnL4nLAogICfqnYEnID0+ICfqnYAnLAogICfqnYMnID0+ICfqnYInLAogICfqnYUnID0+ICfqnYQnLAogICfqnYcnID0+ICfqnYYnLAogICfqnYknID0+ICfqnYgnLAogICfqnYsnID0+ICfqnYonLAogICfqnY0nID0+ICfqnYwnLAogICfqnY8nID0+ICfqnY4nLAogICfqnZEnID0+ICfqnZAnLAogICfqnZMnID0+ICfqnZInLAogICfqnZUnID0+ICfqnZQnLAogICfqnZcnID0+ICfqnZYnLAogICfqnZknID0+ICfqnZgnLAogICfqnZsnID0+ICfqnZonLAogICfqnZ0nID0+ICfqnZwnLAogICfqnZ8nID0+ICfqnZ4nLAogICfqnaEnID0+ICfqnaAnLAogICfqnaMnID0+ICfqnaInLAogICfqnaUnID0+ICfqnaQnLAogICfqnacnID0+ICfqnaYnLAogICfqnaknID0+ICfqnagnLAogICfqnasnID0+ICfqnaonLAogICfqna0nID0+ICfqnawnLAogICfqna8nID0+ICfqna4nLAogICfqnbonID0+ICfqnbknLAogICfqnbwnID0+ICfqnbsnLAogICfqnb8nID0+ICfqnb4nLAogICfqnoEnID0+ICfqnoAnLAogICfqnoMnID0+ICfqnoInLAogICfqnoUnID0+ICfqnoQnLAogICfqnocnID0+ICfqnoYnLAogICfqnownID0+ICfqnosnLAogICfqnpEnID0+ICfqnpAnLAogICfqnpMnID0+ICfqnpInLAogICfqnpQnID0+ICfqn4QnLAogICfqnpcnID0+ICfqnpYnLAogICfqnpknID0+ICfqnpgnLAogICfqnpsnID0+ICfqnponLAogICfqnp0nID0+ICfqnpwnLAogICfqnp8nID0+ICfqnp4nLAogICfqnqEnID0+ICfqnqAnLAogICfqnqMnID0+ICfqnqInLAogICfqnqUnID0+ICfqnqQnLAogICfqnqcnID0+ICfqnqYnLAogICfqnqknID0+ICfqnqgnLAogICfqnrUnID0+ICfqnrQnLAogICfqnrcnID0+ICfqnrYnLAogICfqnrknID0+ICfqnrgnLAogICfqnrsnID0+ICfqnronLAogICfqnr0nID0+ICfqnrwnLAogICfqnr8nID0+ICfqnr4nLAogICfqn4MnID0+ICfqn4InLAogICfqn4gnID0+ICfqn4cnLAogICfqn4onID0+ICfqn4knLAogICfqn7YnID0+ICfqn7UnLAogICfqrZMnID0+ICfqnrMnLAogICfqrbAnID0+ICfhjqAnLAogICfqrbEnID0+ICfhjqEnLAogICfqrbInID0+ICfhjqInLAogICfqrbMnID0+ICfhjqMnLAogICfqrbQnID0+ICfhjqQnLAogICfqrbUnID0+ICfhjqUnLAogICfqrbYnID0+ICfhjqYnLAogICfqrbcnID0+ICfhjqcnLAogICfqrbgnID0+ICfhjqgnLAogICfqrbknID0+ICfhjqknLAogICfqrbonID0+ICfhjqonLAogICfqrbsnID0+ICfhjqsnLAogICfqrbwnID0+ICfhjqwnLAogICfqrb0nID0+ICfhjq0nLAogICfqrb4nID0+ICfhjq4nLAogICfqrb8nID0+ICfhjq8nLAogICfqroAnID0+ICfhjrAnLAogICfqroEnID0+ICfhjrEnLAogICfqroInID0+ICfhjrInLAogICfqroMnID0+ICfhjrMnLAogICfqroQnID0+ICfhjrQnLAogICfqroUnID0+ICfhjrUnLAogICfqroYnID0+ICfhjrYnLAogICfqrocnID0+ICfhjrcnLAogICfqrognID0+ICfhjrgnLAogICfqroknID0+ICfhjrknLAogICfqroonID0+ICfhjronLAogICfqrosnID0+ICfhjrsnLAogICfqrownID0+ICfhjrwnLAogICfqro0nID0+ICfhjr0nLAogICfqro4nID0+ICfhjr4nLAogICfqro8nID0+ICfhjr8nLAogICfqrpAnID0+ICfhj4AnLAogICfqrpEnID0+ICfhj4EnLAogICfqrpInID0+ICfhj4InLAogICfqrpMnID0+ICfhj4MnLAogICfqrpQnID0+ICfhj4QnLAogICfqrpUnID0+ICfhj4UnLAogICfqrpYnID0+ICfhj4YnLAogICfqrpcnID0+ICfhj4cnLAogICfqrpgnID0+ICfhj4gnLAogICfqrpknID0+ICfhj4knLAogICfqrponID0+ICfhj4onLAogICfqrpsnID0+ICfhj4snLAogICfqrpwnID0+ICfhj4wnLAogICfqrp0nID0+ICfhj40nLAogICfqrp4nID0+ICfhj44nLAogICfqrp8nID0+ICfhj48nLAogICfqrqAnID0+ICfhj5AnLAogICfqrqEnID0+ICfhj5EnLAogICfqrqInID0+ICfhj5InLAogICfqrqMnID0+ICfhj5MnLAogICfqrqQnID0+ICfhj5QnLAogICfqrqUnID0+ICfhj5UnLAogICfqrqYnID0+ICfhj5YnLAogICfqrqcnID0+ICfhj5cnLAogICfqrqgnID0+ICfhj5gnLAogICfqrqknID0+ICfhj5knLAogICfqrqonID0+ICfhj5onLAogICfqrqsnID0+ICfhj5snLAogICfqrqwnID0+ICfhj5wnLAogICfqrq0nID0+ICfhj50nLAogICfqrq4nID0+ICfhj54nLAogICfqrq8nID0+ICfhj58nLAogICfqrrAnID0+ICfhj6AnLAogICfqrrEnID0+ICfhj6EnLAogICfqrrInID0+ICfhj6InLAogICfqrrMnID0+ICfhj6MnLAogICfqrrQnID0+ICfhj6QnLAogICfqrrUnID0+ICfhj6UnLAogICfqrrYnID0+ICfhj6YnLAogICfqrrcnID0+ICfhj6cnLAogICfqrrgnID0+ICfhj6gnLAogICfqrrknID0+ICfhj6knLAogICfqrronID0+ICfhj6onLAogICfqrrsnID0+ICfhj6snLAogICfqrrwnID0+ICfhj6wnLAogICfqrr0nID0+ICfhj60nLAogICfqrr4nID0+ICfhj64nLAogICfqrr8nID0+ICfhj68nLAogICfvvYEnID0+ICfvvKEnLAogICfvvYInID0+ICfvvKInLAogICfvvYMnID0+ICfvvKMnLAogICfvvYQnID0+ICfvvKQnLAogICfvvYUnID0+ICfvvKUnLAogICfvvYYnID0+ICfvvKYnLAogICfvvYcnID0+ICfvvKcnLAogICfvvYgnID0+ICfvvKgnLAogICfvvYknID0+ICfvvKknLAogICfvvYonID0+ICfvvKonLAogICfvvYsnID0+ICfvvKsnLAogICfvvYwnID0+ICfvvKwnLAogICfvvY0nID0+ICfvvK0nLAogICfvvY4nID0+ICfvvK4nLAogICfvvY8nID0+ICfvvK8nLAogICfvvZAnID0+ICfvvLAnLAogICfvvZEnID0+ICfvvLEnLAogICfvvZInID0+ICfvvLInLAogICfvvZMnID0+ICfvvLMnLAogICfvvZQnID0+ICfvvLQnLAogICfvvZUnID0+ICfvvLUnLAogICfvvZYnID0+ICfvvLYnLAogICfvvZcnID0+ICfvvLcnLAogICfvvZgnID0+ICfvvLgnLAogICfvvZknID0+ICfvvLknLAogICfvvZonID0+ICfvvLonLAogICfwkJCoJyA9PiAn8JCQgCcsCiAgJ/CQkKknID0+ICfwkJCBJywKICAn8JCQqicgPT4gJ/CQkIInLAogICfwkJCrJyA9PiAn8JCQgycsCiAgJ/CQkKwnID0+ICfwkJCEJywKICAn8JCQrScgPT4gJ/CQkIUnLAogICfwkJCuJyA9PiAn8JCQhicsCiAgJ/CQkK8nID0+ICfwkJCHJywKICAn8JCQsCcgPT4gJ/CQkIgnLAogICfwkJCxJyA9PiAn8JCQiScsCiAgJ/CQkLInID0+ICfwkJCKJywKICAn8JCQsycgPT4gJ/CQkIsnLAogICfwkJC0JyA9PiAn8JCQjCcsCiAgJ/CQkLUnID0+ICfwkJCNJywKICAn8JCQticgPT4gJ/CQkI4nLAogICfwkJC3JyA9PiAn8JCQjycsCiAgJ/CQkLgnID0+ICfwkJCQJywKICAn8JCQuScgPT4gJ/CQkJEnLAogICfwkJC6JyA9PiAn8JCQkicsCiAgJ/CQkLsnID0+ICfwkJCTJywKICAn8JCQvCcgPT4gJ/CQkJQnLAogICfwkJC9JyA9PiAn8JCQlScsCiAgJ/CQkL4nID0+ICfwkJCWJywKICAn8JCQvycgPT4gJ/CQkJcnLAogICfwkJGAJyA9PiAn8JCQmCcsCiAgJ/CQkYEnID0+ICfwkJCZJywKICAn8JCRgicgPT4gJ/CQkJonLAogICfwkJGDJyA9PiAn8JCQmycsCiAgJ/CQkYQnID0+ICfwkJCcJywKICAn8JCRhScgPT4gJ/CQkJ0nLAogICfwkJGGJyA9PiAn8JCQnicsCiAgJ/CQkYcnID0+ICfwkJCfJywKICAn8JCRiCcgPT4gJ/CQkKAnLAogICfwkJGJJyA9PiAn8JCQoScsCiAgJ/CQkYonID0+ICfwkJCiJywKICAn8JCRiycgPT4gJ/CQkKMnLAogICfwkJGMJyA9PiAn8JCQpCcsCiAgJ/CQkY0nID0+ICfwkJClJywKICAn8JCRjicgPT4gJ/CQkKYnLAogICfwkJGPJyA9PiAn8JCQpycsCiAgJ/CQk5gnID0+ICfwkJKwJywKICAn8JCTmScgPT4gJ/CQkrEnLAogICfwkJOaJyA9PiAn8JCSsicsCiAgJ/CQk5snID0+ICfwkJKzJywKICAn8JCTnCcgPT4gJ/CQkrQnLAogICfwkJOdJyA9PiAn8JCStScsCiAgJ/CQk54nID0+ICfwkJK2JywKICAn8JCTnycgPT4gJ/CQkrcnLAogICfwkJOgJyA9PiAn8JCSuCcsCiAgJ/CQk6EnID0+ICfwkJK5JywKICAn8JCToicgPT4gJ/CQkronLAogICfwkJOjJyA9PiAn8JCSuycsCiAgJ/CQk6QnID0+ICfwkJK8JywKICAn8JCTpScgPT4gJ/CQkr0nLAogICfwkJOmJyA9PiAn8JCSvicsCiAgJ/CQk6cnID0+ICfwkJK/JywKICAn8JCTqCcgPT4gJ/CQk4AnLAogICfwkJOpJyA9PiAn8JCTgScsCiAgJ/CQk6onID0+ICfwkJOCJywKICAn8JCTqycgPT4gJ/CQk4MnLAogICfwkJOsJyA9PiAn8JCThCcsCiAgJ/CQk60nID0+ICfwkJOFJywKICAn8JCTricgPT4gJ/CQk4YnLAogICfwkJOvJyA9PiAn8JCThycsCiAgJ/CQk7AnID0+ICfwkJOIJywKICAn8JCTsScgPT4gJ/CQk4knLAogICfwkJOyJyA9PiAn8JCTiicsCiAgJ/CQk7MnID0+ICfwkJOLJywKICAn8JCTtCcgPT4gJ/CQk4wnLAogICfwkJO1JyA9PiAn8JCTjScsCiAgJ/CQk7YnID0+ICfwkJOOJywKICAn8JCTtycgPT4gJ/CQk48nLAogICfwkJO4JyA9PiAn8JCTkCcsCiAgJ/CQk7knID0+ICfwkJORJywKICAn8JCTuicgPT4gJ/CQk5InLAogICfwkJO7JyA9PiAn8JCTkycsCiAgJ/CQs4AnID0+ICfwkLKAJywKICAn8JCzgScgPT4gJ/CQsoEnLAogICfwkLOCJyA9PiAn8JCygicsCiAgJ/CQs4MnID0+ICfwkLKDJywKICAn8JCzhCcgPT4gJ/CQsoQnLAogICfwkLOFJyA9PiAn8JCyhScsCiAgJ/CQs4YnID0+ICfwkLKGJywKICAn8JCzhycgPT4gJ/CQsocnLAogICfwkLOIJyA9PiAn8JCyiCcsCiAgJ/CQs4knID0+ICfwkLKJJywKICAn8JCziicgPT4gJ/CQsoonLAogICfwkLOLJyA9PiAn8JCyiycsCiAgJ/CQs4wnID0+ICfwkLKMJywKICAn8JCzjScgPT4gJ/CQso0nLAogICfwkLOOJyA9PiAn8JCyjicsCiAgJ/CQs48nID0+ICfwkLKPJywKICAn8JCzkCcgPT4gJ/CQspAnLAogICfwkLORJyA9PiAn8JCykScsCiAgJ/CQs5InID0+ICfwkLKSJywKICAn8JCzkycgPT4gJ/CQspMnLAogICfwkLOUJyA9PiAn8JCylCcsCiAgJ/CQs5UnID0+ICfwkLKVJywKICAn8JCzlicgPT4gJ/CQspYnLAogICfwkLOXJyA9PiAn8JCylycsCiAgJ/CQs5gnID0+ICfwkLKYJywKICAn8JCzmScgPT4gJ/CQspknLAogICfwkLOaJyA9PiAn8JCymicsCiAgJ/CQs5snID0+ICfwkLKbJywKICAn8JCznCcgPT4gJ/CQspwnLAogICfwkLOdJyA9PiAn8JCynScsCiAgJ/CQs54nID0+ICfwkLKeJywKICAn8JCznycgPT4gJ/CQsp8nLAogICfwkLOgJyA9PiAn8JCyoCcsCiAgJ/CQs6EnID0+ICfwkLKhJywKICAn8JCzoicgPT4gJ/CQsqInLAogICfwkLOjJyA9PiAn8JCyoycsCiAgJ/CQs6QnID0+ICfwkLKkJywKICAn8JCzpScgPT4gJ/CQsqUnLAogICfwkLOmJyA9PiAn8JCypicsCiAgJ/CQs6cnID0+ICfwkLKnJywKICAn8JCzqCcgPT4gJ/CQsqgnLAogICfwkLOpJyA9PiAn8JCyqScsCiAgJ/CQs6onID0+ICfwkLKqJywKICAn8JCzqycgPT4gJ/CQsqsnLAogICfwkLOsJyA9PiAn8JCyrCcsCiAgJ/CQs60nID0+ICfwkLKtJywKICAn8JCzricgPT4gJ/CQsq4nLAogICfwkLOvJyA9PiAn8JCyrycsCiAgJ/CQs7AnID0+ICfwkLKwJywKICAn8JCzsScgPT4gJ/CQsrEnLAogICfwkLOyJyA9PiAn8JCysicsCiAgJ/CRo4AnID0+ICfwkaKgJywKICAn8JGjgScgPT4gJ/CRoqEnLAogICfwkaOCJyA9PiAn8JGioicsCiAgJ/CRo4MnID0+ICfwkaKjJywKICAn8JGjhCcgPT4gJ/CRoqQnLAogICfwkaOFJyA9PiAn8JGipScsCiAgJ/CRo4YnID0+ICfwkaKmJywKICAn8JGjhycgPT4gJ/CRoqcnLAogICfwkaOIJyA9PiAn8JGiqCcsCiAgJ/CRo4knID0+ICfwkaKpJywKICAn8JGjiicgPT4gJ/CRoqonLAogICfwkaOLJyA9PiAn8JGiqycsCiAgJ/CRo4wnID0+ICfwkaKsJywKICAn8JGjjScgPT4gJ/CRoq0nLAogICfwkaOOJyA9PiAn8JGiricsCiAgJ/CRo48nID0+ICfwkaKvJywKICAn8JGjkCcgPT4gJ/CRorAnLAogICfwkaORJyA9PiAn8JGisScsCiAgJ/CRo5InID0+ICfwkaKyJywKICAn8JGjkycgPT4gJ/CRorMnLAogICfwkaOUJyA9PiAn8JGitCcsCiAgJ/CRo5UnID0+ICfwkaK1JywKICAn8JGjlicgPT4gJ/CRorYnLAogICfwkaOXJyA9PiAn8JGitycsCiAgJ/CRo5gnID0+ICfwkaK4JywKICAn8JGjmScgPT4gJ/CRorknLAogICfwkaOaJyA9PiAn8JGiuicsCiAgJ/CRo5snID0+ICfwkaK7JywKICAn8JGjnCcgPT4gJ/CRorwnLAogICfwkaOdJyA9PiAn8JGivScsCiAgJ/CRo54nID0+ICfwkaK+JywKICAn8JGjnycgPT4gJ/CRor8nLAogICfwlrmgJyA9PiAn8Ja5gCcsCiAgJ/CWuaEnID0+ICfwlrmBJywKICAn8Ja5oicgPT4gJ/CWuYInLAogICfwlrmjJyA9PiAn8Ja5gycsCiAgJ/CWuaQnID0+ICfwlrmEJywKICAn8Ja5pScgPT4gJ/CWuYUnLAogICfwlrmmJyA9PiAn8Ja5hicsCiAgJ/CWuacnID0+ICfwlrmHJywKICAn8Ja5qCcgPT4gJ/CWuYgnLAogICfwlrmpJyA9PiAn8Ja5iScsCiAgJ/CWuaonID0+ICfwlrmKJywKICAn8Ja5qycgPT4gJ/CWuYsnLAogICfwlrmsJyA9PiAn8Ja5jCcsCiAgJ/CWua0nID0+ICfwlrmNJywKICAn8Ja5ricgPT4gJ/CWuY4nLAogICfwlrmvJyA9PiAn8Ja5jycsCiAgJ/CWubAnID0+ICfwlrmQJywKICAn8Ja5sScgPT4gJ/CWuZEnLAogICfwlrmyJyA9PiAn8Ja5kicsCiAgJ/CWubMnID0+ICfwlrmTJywKICAn8Ja5tCcgPT4gJ/CWuZQnLAogICfwlrm1JyA9PiAn8Ja5lScsCiAgJ/CWubYnID0+ICfwlrmWJywKICAn8Ja5tycgPT4gJ/CWuZcnLAogICfwlrm4JyA9PiAn8Ja5mCcsCiAgJ/CWubknID0+ICfwlrmZJywKICAn8Ja5uicgPT4gJ/CWuZonLAogICfwlrm7JyA9PiAn8Ja5mycsCiAgJ/CWubwnID0+ICfwlrmcJywKICAn8Ja5vScgPT4gJ/CWuZ0nLAogICfwlrm+JyA9PiAn8Ja5nicsCiAgJ/CWub8nID0+ICfwlrmfJywKICAn8J6koicgPT4gJ/CepIAnLAogICfwnqSjJyA9PiAn8J6kgScsCiAgJ/CepKQnID0+ICfwnqSCJywKICAn8J6kpScgPT4gJ/CepIMnLAogICfwnqSmJyA9PiAn8J6khCcsCiAgJ/CepKcnID0+ICfwnqSFJywKICAn8J6kqCcgPT4gJ/CepIYnLAogICfwnqSpJyA9PiAn8J6khycsCiAgJ/CepKonID0+ICfwnqSIJywKICAn8J6kqycgPT4gJ/CepIknLAogICfwnqSsJyA9PiAn8J6kiicsCiAgJ/CepK0nID0+ICfwnqSLJywKICAn8J6kricgPT4gJ/CepIwnLAogICfwnqSvJyA9PiAn8J6kjScsCiAgJ/CepLAnID0+ICfwnqSOJywKICAn8J6ksScgPT4gJ/CepI8nLAogICfwnqSyJyA9PiAn8J6kkCcsCiAgJ/CepLMnID0+ICfwnqSRJywKICAn8J6ktCcgPT4gJ/CepJInLAogICfwnqS1JyA9PiAn8J6kkycsCiAgJ/CepLYnID0+ICfwnqSUJywKICAn8J6ktycgPT4gJ/CepJUnLAogICfwnqS4JyA9PiAn8J6klicsCiAgJ/CepLknID0+ICfwnqSXJywKICAn8J6kuicgPT4gJ/CepJgnLAogICfwnqS7JyA9PiAn8J6kmScsCiAgJ/CepLwnID0+ICfwnqSaJywKICAn8J6kvScgPT4gJ/CepJsnLAogICfwnqS+JyA9PiAn8J6knCcsCiAgJ/CepL8nID0+ICfwnqSdJywKICAn8J6lgCcgPT4gJ/CepJ4nLAogICfwnqWBJyA9PiAn8J6knycsCiAgJ/CepYInID0+ICfwnqSgJywKICAn8J6lgycgPT4gJ/CepKEnLAopOwo8P3BocAoKcmV0dXJuIGFycmF5ICgKICAnQScgPT4gJ2EnLAogICdCJyA9PiAnYicsCiAgJ0MnID0+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/CepYMnLAopOwo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKdXNlIFN5bWZvbnlcUG9seWZpbGxcTWJzdHJpbmcgYXMgcDsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9jb252ZXJ0X2VuY29kaW5nJykpIHsKICAgIGZ1bmN0aW9uIG1iX2NvbnZlcnRfZW5jb2RpbmcoJHN0cmluZywgJHRvX2VuY29kaW5nLCAkZnJvbV9lbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2NvbnZlcnRfZW5jb2RpbmcoJHN0cmluZywgJHRvX2VuY29kaW5nLCAkZnJvbV9lbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfZGVjb2RlX21pbWVoZWFkZXInKSkgewogICAgZnVuY3Rpb24gbWJfZGVjb2RlX21pbWVoZWFkZXIoJHN0cmluZykgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZGVjb2RlX21pbWVoZWFkZXIoJHN0cmluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfZW5jb2RlX21pbWVoZWFkZXInKSkgewogICAgZnVuY3Rpb24gbWJfZW5jb2RlX21pbWVoZWFkZXIoJHN0cmluZywgJGNoYXJzZXQgPSBudWxsLCAkdHJhbnNmZXJfZW5jb2RpbmcgPSBudWxsLCAkbmV3bGluZSA9IG51bGwsICRpbmRlbnQgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9lbmNvZGVfbWltZWhlYWRlcigkc3RyaW5nLCAkY2hhcnNldCwgJHRyYW5zZmVyX2VuY29kaW5nLCAkbmV3bGluZSwgJGluZGVudCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfZGVjb2RlX251bWVyaWNlbnRpdHknKSkgewogICAgZnVuY3Rpb24gbWJfZGVjb2RlX251bWVyaWNlbnRpdHkoJHN0cmluZywgJG1hcCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZGVjb2RlX251bWVyaWNlbnRpdHkoJHN0cmluZywgJG1hcCwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9lbmNvZGVfbnVtZXJpY2VudGl0eScpKSB7CiAgICBmdW5jdGlvbiBtYl9lbmNvZGVfbnVtZXJpY2VudGl0eSgkc3RyaW5nLCAkbWFwLCAkZW5jb2RpbmcgPSBudWxsLCAkaGV4ID0gZmFsc2UpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2VuY29kZV9udW1lcmljZW50aXR5KCRzdHJpbmcsICRtYXAsICRlbmNvZGluZywgJGhleCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfY29udmVydF9jYXNlJykpIHsKICAgIGZ1bmN0aW9uIG1iX2NvbnZlcnRfY2FzZSgkc3RyaW5nLCAkbW9kZSwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfY29udmVydF9jYXNlKCRzdHJpbmcsICRtb2RlLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2ludGVybmFsX2VuY29kaW5nJykpIHsKICAgIGZ1bmN0aW9uIG1iX2ludGVybmFsX2VuY29kaW5nKCRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2ludGVybmFsX2VuY29kaW5nKCRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfbGFuZ3VhZ2UnKSkgewogICAgZnVuY3Rpb24gbWJfbGFuZ3VhZ2UoJGxhbmd1YWdlID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfbGFuZ3VhZ2UoJGxhbmd1YWdlKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9saXN0X2VuY29kaW5ncycpKSB7CiAgICBmdW5jdGlvbiBtYl9saXN0X2VuY29kaW5ncygpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2xpc3RfZW5jb2RpbmdzKCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfZW5jb2RpbmdfYWxpYXNlcycpKSB7CiAgICBmdW5jdGlvbiBtYl9lbmNvZGluZ19hbGlhc2VzKCRlbmNvZGluZykgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZW5jb2RpbmdfYWxpYXNlcygkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2NoZWNrX2VuY29kaW5nJykpIHsKICAgIGZ1bmN0aW9uIG1iX2NoZWNrX2VuY29kaW5nKCR2YWx1ZSA9IG51bGwsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2NoZWNrX2VuY29kaW5nKCR2YWx1ZSwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9kZXRlY3RfZW5jb2RpbmcnKSkgewogICAgZnVuY3Rpb24gbWJfZGV0ZWN0X2VuY29kaW5nKCRzdHJpbmcsICRlbmNvZGluZ3MgPSBudWxsLCAkc3RyaWN0ID0gZmFsc2UpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2RldGVjdF9lbmNvZGluZygkc3RyaW5nLCAkZW5jb2RpbmdzLCAkc3RyaWN0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9kZXRlY3Rfb3JkZXInKSkgewogICAgZnVuY3Rpb24gbWJfZGV0ZWN0X29yZGVyKCRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2RldGVjdF9vcmRlcigkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3BhcnNlX3N0cicpKSB7CiAgICBmdW5jdGlvbiBtYl9wYXJzZV9zdHIoJHN0cmluZywgJiRyZXN1bHQgPSBhcnJheSgpKSB7IHBhcnNlX3N0cigkc3RyaW5nLCAkcmVzdWx0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJsZW4nKSkgewogICAgZnVuY3Rpb24gbWJfc3RybGVuKCRzdHJpbmcsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cmxlbigkc3RyaW5nLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cnBvcycpKSB7CiAgICBmdW5jdGlvbiBtYl9zdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJ0b2xvd2VyJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cnRvbG93ZXIoJHN0cmluZywgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RydG9sb3dlcigkc3RyaW5nLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cnRvdXBwZXInKSkgewogICAgZnVuY3Rpb24gbWJfc3RydG91cHBlcigkc3RyaW5nLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJ0b3VwcGVyKCRzdHJpbmcsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3Vic3RpdHV0ZV9jaGFyYWN0ZXInKSkgewogICAgZnVuY3Rpb24gbWJfc3Vic3RpdHV0ZV9jaGFyYWN0ZXIoJHN1YnN0aXR1dGVfY2hhcmFjdGVyID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3Vic3RpdHV0ZV9jaGFyYWN0ZXIoJHN1YnN0aXR1dGVfY2hhcmFjdGVyKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdWJzdHInKSkgewogICAgZnVuY3Rpb24gbWJfc3Vic3RyKCRzdHJpbmcsICRzdGFydCwgJGxlbmd0aCA9IDIxNDc0ODM2NDcsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N1YnN0cigkc3RyaW5nLCAkc3RhcnQsICRsZW5ndGgsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3RyaXBvcycpKSB7CiAgICBmdW5jdGlvbiBtYl9zdHJpcG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCA9IDAsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0LCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cmlzdHInKSkgewogICAgZnVuY3Rpb24gbWJfc3RyaXN0cigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cmlzdHIoJGhheXN0YWNrLCAkbmVlZGxlLCAkYmVmb3JlX25lZWRsZSwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJyY2hyJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cnJjaHIoJGhheXN0YWNrLCAkbmVlZGxlLCAkYmVmb3JlX25lZWRsZSA9IGZhbHNlLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJyY2hyKCRoYXlzdGFjaywgJG5lZWRsZSwgJGJlZm9yZV9uZWVkbGUsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3RycmljaHInKSkgewogICAgZnVuY3Rpb24gbWJfc3RycmljaHIoJGhheXN0YWNrLCAkbmVlZGxlLCAkYmVmb3JlX25lZWRsZSA9IGZhbHNlLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJyaWNocigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cnJpcG9zJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cnJpcG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCA9IDAsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cnJpcG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJycG9zJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cnJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3Ryc3RyJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cnN0cigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cnN0cigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2dldF9pbmZvJykpIHsKICAgIGZ1bmN0aW9uIG1iX2dldF9pbmZvKCR0eXBlID0gJ2FsbCcpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2dldF9pbmZvKCR0eXBlKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9odHRwX291dHB1dCcpKSB7CiAgICBmdW5jdGlvbiBtYl9odHRwX291dHB1dCgkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9odHRwX291dHB1dCgkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cndpZHRoJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cndpZHRoKCRzdHJpbmcsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cndpZHRoKCRzdHJpbmcsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3Vic3RyX2NvdW50JykpIHsKICAgIGZ1bmN0aW9uIG1iX3N1YnN0cl9jb3VudCgkaGF5c3RhY2ssICRuZWVkbGUsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N1YnN0cl9jb3VudCgkaGF5c3RhY2ssICRuZWVkbGUsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfb3V0cHV0X2hhbmRsZXInKSkgewogICAgZnVuY3Rpb24gbWJfb3V0cHV0X2hhbmRsZXIoJHN0cmluZywgJHN0YXR1cykgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfb3V0cHV0X2hhbmRsZXIoJHN0cmluZywgJHN0YXR1cyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfaHR0cF9pbnB1dCcpKSB7CiAgICBmdW5jdGlvbiBtYl9odHRwX2lucHV0KCR0eXBlID0gJycpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2h0dHBfaW5wdXQoJHR5cGUpOyB9Cn0KCmlmIChQSFBfVkVSU0lPTl9JRCA+PSA4MDAwMCkgewogICAgcmVxdWlyZV9vbmNlIF9fRElSX18uJy9SZXNvdXJjZXMvbWJfY29udmVydF92YXJpYWJsZXMucGhwOCc7Cn0gZWxzZWlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9jb252ZXJ0X3ZhcmlhYmxlcycpKSB7CiAgICBmdW5jdGlvbiBtYl9jb252ZXJ0X3ZhcmlhYmxlcygkdG9FbmNvZGluZywgJGZyb21FbmNvZGluZywgJiRhID0gbnVsbCwgJiRiID0gbnVsbCwgJiRjID0gbnVsbCwgJiRkID0gbnVsbCwgJiRlID0gbnVsbCwgJiRmID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfY29udmVydF92YXJpYWJsZXMoJHRvRW5jb2RpbmcsICRmcm9tRW5jb2RpbmcsICRhLCAkYiwgJGMsICRkLCAkZSwgJGYpOyB9Cn0KCmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9vcmQnKSkgewogICAgZnVuY3Rpb24gbWJfb3JkKCRzdHJpbmcsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX29yZCgkc3RyaW5nLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2NocicpKSB7CiAgICBmdW5jdGlvbiBtYl9jaHIoJGNvZGVwb2ludCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfY2hyKCRjb2RlcG9pbnQsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc2NydWInKSkgewogICAgZnVuY3Rpb24gbWJfc2NydWIoJHN0cmluZywgJGVuY29kaW5nID0gbnVsbCkgeyAkZW5jb2RpbmcgPSBudWxsID09PSAkZW5jb2RpbmcgPyBtYl9pbnRlcm5hbF9lbmNvZGluZygpIDogJGVuY29kaW5nOyByZXR1cm4gbWJfY29udmVydF9lbmNvZGluZygkc3RyaW5nLCAkZW5jb2RpbmcsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3RyX3NwbGl0JykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cl9zcGxpdCgkc3RyaW5nLCAkbGVuZ3RoID0gMSwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RyX3NwbGl0KCRzdHJpbmcsICRsZW5ndGgsICRlbmNvZGluZyk7IH0KfQoKaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ21ic3RyaW5nJykpIHsKICAgIHJldHVybjsKfQoKaWYgKCFkZWZpbmVkKCdNQl9DQVNFX1VQUEVSJykpIHsKICAgIGRlZmluZSgnTUJfQ0FTRV9VUFBFUicsIDApOwp9CmlmICghZGVmaW5lZCgnTUJfQ0FTRV9MT1dFUicpKSB7CiAgICBkZWZpbmUoJ01CX0NBU0VfTE9XRVInLCAxKTsKfQppZiAoIWRlZmluZWQoJ01CX0NBU0VfVElUTEUnKSkgewogICAgZGVmaW5lKCdNQl9DQVNFX1RJVExFJywgMik7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XFBvbHlmaWxsXE1ic3RyaW5nOwoKLyoqCiAqIFBhcnRpYWwgbWJzdHJpbmcgaW1wbGVtZW50YXRpb24gaW4gUEhQLCBpY29udiBiYXNlZCwgVVRGLTggY2VudHJpYy4KICoKICogSW1wbGVtZW50ZWQ6CiAqIC0gbWJfY2hyICAgICAgICAgICAgICAgICAgLSBSZXR1cm5zIGEgc3BlY2lmaWMgY2hhcmFjdGVyIGZyb20gaXRzIFVuaWNvZGUgY29kZSBwb2ludAogKiAtIG1iX2NvbnZlcnRfZW5jb2RpbmcgICAgIC0gQ29udmVydCBjaGFyYWN0ZXIgZW5jb2RpbmcKICogLSBtYl9jb252ZXJ0X3ZhcmlhYmxlcyAgICAtIENvbnZlcnQgY2hhcmFjdGVyIGNvZGUgaW4gdmFyaWFibGUocykKICogLSBtYl9kZWNvZGVfbWltZWhlYWRlciAgICAtIERlY29kZSBzdHJpbmcgaW4gTUlNRSBoZWFkZXIgZmllbGQKICogLSBtYl9lbmNvZGVfbWltZWhlYWRlciAgICAtIEVuY29kZSBzdHJpbmcgZm9yIE1JTUUgaGVhZGVyIFhYWCBOQVRJVkUgSU1QTEVNRU5UQVRJT04gSVMgUkVBTExZIEJVR0dFRAogKiAtIG1iX2RlY29kZV9udW1lcmljZW50aXR5IC0gRGVjb2RlIEhUTUwgbnVtZXJpYyBzdHJpbmcgcmVmZXJlbmNlIHRvIGNoYXJhY3RlcgogKiAtIG1iX2VuY29kZV9udW1lcmljZW50aXR5IC0gRW5jb2RlIGNoYXJhY3RlciB0byBIVE1MIG51bWVyaWMgc3RyaW5nIHJlZmVyZW5jZQogKiAtIG1iX2NvbnZlcnRfY2FzZSAgICAgICAgIC0gUGVyZm9ybSBjYXNlIGZvbGRpbmcgb24gYSBzdHJpbmcKICogLSBtYl9kZXRlY3RfZW5jb2RpbmcgICAgICAtIERldGVjdCBjaGFyYWN0ZXIgZW5jb2RpbmcKICogLSBtYl9nZXRfaW5mbyAgICAgICAgICAgICAtIEdldCBpbnRlcm5hbCBzZXR0aW5ncyBvZiBtYnN0cmluZwogKiAtIG1iX2h0dHBfaW5wdXQgICAgICAgICAgIC0gRGV0ZWN0IEhUVFAgaW5wdXQgY2hhcmFjdGVyIGVuY29kaW5nCiAqIC0gbWJfaHR0cF9vdXRwdXQgICAgICAgICAgLSBTZXQvR2V0IEhUVFAgb3V0cHV0IGNoYXJhY3RlciBlbmNvZGluZwogKiAtIG1iX2ludGVybmFsX2VuY29kaW5nICAgIC0gU2V0L0dldCBpbnRlcm5hbCBjaGFyYWN0ZXIgZW5jb2RpbmcKICogLSBtYl9saXN0X2VuY29kaW5ncyAgICAgICAtIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIHN1cHBvcnRlZCBlbmNvZGluZ3MKICogLSBtYl9vcmQgICAgICAgICAgICAgICAgICAtIFJldHVybnMgdGhlIFVuaWNvZGUgY29kZSBwb2ludCBvZiBhIGNoYXJhY3RlcgogKiAtIG1iX291dHB1dF9oYW5kbGVyICAgICAgIC0gQ2FsbGJhY2sgZnVuY3Rpb24gY29udmVydHMgY2hhcmFjdGVyIGVuY29kaW5nIGluIG91dHB1dCBidWZmZXIKICogLSBtYl9zY3J1YiAgICAgICAgICAgICAgICAtIFJlcGxhY2VzIGlsbC1mb3JtZWQgYnl0ZSBzZXF1ZW5jZXMgd2l0aCBzdWJzdGl0dXRlIGNoYXJhY3RlcnMKICogLSBtYl9zdHJsZW4gICAgICAgICAgICAgICAtIEdldCBzdHJpbmcgbGVuZ3RoCiAqIC0gbWJfc3RycG9zICAgICAgICAgICAgICAgLSBGaW5kIHBvc2l0aW9uIG9mIGZpcnN0IG9jY3VycmVuY2Ugb2Ygc3RyaW5nIGluIGEgc3RyaW5nCiAqIC0gbWJfc3RycnBvcyAgICAgICAgICAgICAgLSBGaW5kIHBvc2l0aW9uIG9mIGxhc3Qgb2NjdXJyZW5jZSBvZiBhIHN0cmluZyBpbiBhIHN0cmluZwogKiAtIG1iX3N0cl9zcGxpdCAgICAgICAgICAgIC0gQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheQogKiAtIG1iX3N0cnRvbG93ZXIgICAgICAgICAgIC0gTWFrZSBhIHN0cmluZyBsb3dlcmNhc2UKICogLSBtYl9zdHJ0b3VwcGVyICAgICAgICAgICAtIE1ha2UgYSBzdHJpbmcgdXBwZXJjYXNlCiAqIC0gbWJfc3Vic3RpdHV0ZV9jaGFyYWN0ZXIgLSBTZXQvR2V0IHN1YnN0aXR1dGlvbiBjaGFyYWN0ZXIKICogLSBtYl9zdWJzdHIgICAgICAgICAgICAgICAtIEdldCBwYXJ0IG9mIHN0cmluZwogKiAtIG1iX3N0cmlwb3MgICAgICAgICAgICAgIC0gRmluZHMgcG9zaXRpb24gb2YgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIHN0cmluZyB3aXRoaW4gYW5vdGhlciwgY2FzZSBpbnNlbnNpdGl2ZQogKiAtIG1iX3N0cmlzdHIgICAgICAgICAgICAgIC0gRmluZHMgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIHN0cmluZyB3aXRoaW4gYW5vdGhlciwgY2FzZSBpbnNlbnNpdGl2ZQogKiAtIG1iX3N0cnJjaHIgICAgICAgICAgICAgIC0gRmluZHMgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiBhIGNoYXJhY3RlciBpbiBhIHN0cmluZyB3aXRoaW4gYW5vdGhlcgogKiAtIG1iX3N0cnJpY2hyICAgICAgICAgICAgIC0gRmluZHMgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiBhIGNoYXJhY3RlciBpbiBhIHN0cmluZyB3aXRoaW4gYW5vdGhlciwgY2FzZSBpbnNlbnNpdGl2ZQogKiAtIG1iX3N0cnJpcG9zICAgICAgICAgICAgIC0gRmluZHMgcG9zaXRpb24gb2YgbGFzdCBvY2N1cnJlbmNlIG9mIGEgc3RyaW5nIHdpdGhpbiBhbm90aGVyLCBjYXNlIGluc2Vuc2l0aXZlCiAqIC0gbWJfc3Ryc3RyICAgICAgICAgICAgICAgLSBGaW5kcyBmaXJzdCBvY2N1cnJlbmNlIG9mIGEgc3RyaW5nIHdpdGhpbiBhbm90aGVyCiAqIC0gbWJfc3Ryd2lkdGggICAgICAgICAgICAgLSBSZXR1cm4gd2lkdGggb2Ygc3RyaW5nCiAqIC0gbWJfc3Vic3RyX2NvdW50ICAgICAgICAgLSBDb3VudCB0aGUgbnVtYmVyIG9mIHN1YnN0cmluZyBvY2N1cnJlbmNlcwogKgogKiBOb3QgaW1wbGVtZW50ZWQ6CiAqIC0gbWJfY29udmVydF9rYW5hICAgICAgICAgLSBDb252ZXJ0ICJrYW5hIiBvbmUgZnJvbSBhbm90aGVyICgiemVuLWtha3UiLCAiaGFuLWtha3UiIGFuZCBtb3JlKQogKiAtIG1iX2VyZWdfKiAgICAgICAgICAgICAgIC0gUmVndWxhciBleHByZXNzaW9uIHdpdGggbXVsdGlieXRlIHN1cHBvcnQKICogLSBtYl9wYXJzZV9zdHIgICAgICAgICAgICAtIFBhcnNlIEdFVC9QT1NUL0NPT0tJRSBkYXRhIGFuZCBzZXQgZ2xvYmFsIHZhcmlhYmxlCiAqIC0gbWJfcHJlZmVycmVkX21pbWVfbmFtZSAgLSBHZXQgTUlNRSBjaGFyc2V0IHN0cmluZwogKiAtIG1iX3JlZ2V4X2VuY29kaW5nICAgICAgIC0gUmV0dXJucyBjdXJyZW50IGVuY29kaW5nIGZvciBtdWx0aWJ5dGUgcmVnZXggYXMgc3RyaW5nCiAqIC0gbWJfcmVnZXhfc2V0X29wdGlvbnMgICAgLSBTZXQvR2V0IHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIG1icmVnZXggZnVuY3Rpb25zCiAqIC0gbWJfc2VuZF9tYWlsICAgICAgICAgICAgLSBTZW5kIGVuY29kZWQgbWFpbAogKiAtIG1iX3NwbGl0ICAgICAgICAgICAgICAgIC0gU3BsaXQgbXVsdGlieXRlIHN0cmluZyB1c2luZyByZWd1bGFyIGV4cHJlc3Npb24KICogLSBtYl9zdHJjdXQgICAgICAgICAgICAgICAtIEdldCBwYXJ0IG9mIHN0cmluZwogKiAtIG1iX3N0cmltd2lkdGggICAgICAgICAgIC0gR2V0IHRydW5jYXRlZCBzdHJpbmcgd2l0aCBzcGVjaWZpZWQgd2lkdGgKICoKICogQGF1dGhvciBOaWNvbGFzIEdyZWthcyA8cEB0Y2h3b3JrLmNvbT4KICoKICogQGludGVybmFsCiAqLwpmaW5hbCBjbGFzcyBNYnN0cmluZwp7CiAgICBjb25zdCBNQl9DQVNFX0ZPTEQgPSBQSFBfSU5UX01BWDsKCiAgICBwcml2YXRlIHN0YXRpYyAkZW5jb2RpbmdMaXN0ID0gYXJyYXkoJ0FTQ0lJJywgJ1VURi04Jyk7CiAgICBwcml2YXRlIHN0YXRpYyAkbGFuZ3VhZ2UgPSAnbmV1dHJhbCc7CiAgICBwcml2YXRlIHN0YXRpYyAkaW50ZXJuYWxFbmNvZGluZyA9ICdVVEYtOCc7CiAgICBwcml2YXRlIHN0YXRpYyAkY2FzZUZvbGQgPSBhcnJheSgKICAgICAgICBhcnJheSgnwrUnLCAnxb8nLCAiXHhDRFx4ODUiLCAnz4InLCAiXHhDRlx4OTAiLCAiXHhDRlx4OTEiLCAiXHhDRlx4OTUiLCAiXHhDRlx4OTYiLCAiXHhDRlx4QjAiLCAiXHhDRlx4QjEiLCAiXHhDRlx4QjUiLCAiXHhFMVx4QkFceDlCIiwgIlx4RTFceEJFXHhCRSIpLAogICAgICAgIGFycmF5KCfOvCcsICdzJywgJ865JywgICAgICAgICfPgycsICfOsicsICAgICAgICAnzrgnLCAgICAgICAgJ8+GJywgICAgICAgICfPgCcsICAgICAgICAnzronLCAgICAgICAgJ8+BJywgICAgICAgICfOtScsICAgICAgICAiXHhFMVx4QjlceEExIiwgJ865JyksCiAgICApOwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfY29udmVydF9lbmNvZGluZygkcywgJHRvRW5jb2RpbmcsICRmcm9tRW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmIChcaXNfYXJyYXkoJGZyb21FbmNvZGluZykgfHwgZmFsc2UgIT09IHN0cnBvcygkZnJvbUVuY29kaW5nLCAnLCcpKSB7CiAgICAgICAgICAgICRmcm9tRW5jb2RpbmcgPSBzZWxmOjptYl9kZXRlY3RfZW5jb2RpbmcoJHMsICRmcm9tRW5jb2RpbmcpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRmcm9tRW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZnJvbUVuY29kaW5nKTsKICAgICAgICB9CgogICAgICAgICR0b0VuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJHRvRW5jb2RpbmcpOwoKICAgICAgICBpZiAoJ0JBU0U2NCcgPT09ICRmcm9tRW5jb2RpbmcpIHsKICAgICAgICAgICAgJHMgPSBiYXNlNjRfZGVjb2RlKCRzKTsKICAgICAgICAgICAgJGZyb21FbmNvZGluZyA9ICR0b0VuY29kaW5nOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdCQVNFNjQnID09PSAkdG9FbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gYmFzZTY0X2VuY29kZSgkcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ0hUTUwtRU5USVRJRVMnID09PSAkdG9FbmNvZGluZyB8fCAnSFRNTCcgPT09ICR0b0VuY29kaW5nKSB7CiAgICAgICAgICAgIGlmICgnSFRNTC1FTlRJVElFUycgPT09ICRmcm9tRW5jb2RpbmcgfHwgJ0hUTUwnID09PSAkZnJvbUVuY29kaW5nKSB7CiAgICAgICAgICAgICAgICAkZnJvbUVuY29kaW5nID0gJ1dpbmRvd3MtMTI1Mic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCdVVEYtOCcgIT09ICRmcm9tRW5jb2RpbmcpIHsKICAgICAgICAgICAgICAgICRzID0gaWNvbnYoJGZyb21FbmNvZGluZywgJ1VURi04Ly9JR05PUkUnLCAkcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJy9bXHg4MC1ceEZGXSsvJywgYXJyYXkoX19DTEFTU19fLCAnaHRtbF9lbmNvZGluZ19jYWxsYmFjaycpLCAkcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ0hUTUwtRU5USVRJRVMnID09PSAkZnJvbUVuY29kaW5nKSB7CiAgICAgICAgICAgICRzID0gaHRtbF9lbnRpdHlfZGVjb2RlKCRzLCBFTlRfQ09NUEFULCAnVVRGLTgnKTsKICAgICAgICAgICAgJGZyb21FbmNvZGluZyA9ICdVVEYtOCc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaWNvbnYoJGZyb21FbmNvZGluZywgJHRvRW5jb2RpbmcuJy8vSUdOT1JFJywgJHMpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfY29udmVydF92YXJpYWJsZXMoJHRvRW5jb2RpbmcsICRmcm9tRW5jb2RpbmcsICYkYSA9IG51bGwsICYkYiA9IG51bGwsICYkYyA9IG51bGwsICYkZCA9IG51bGwsICYkZSA9IG51bGwsICYkZiA9IG51bGwpCiAgICB7CiAgICAgICAgJHZhcnMgPSBhcnJheSgmJGEsICYkYiwgJiRjLCAmJGQsICYkZSwgJiRmKTsKCiAgICAgICAgJG9rID0gdHJ1ZTsKICAgICAgICBhcnJheV93YWxrX3JlY3Vyc2l2ZSgkdmFycywgZnVuY3Rpb24gKCYkdikgdXNlICgmJG9rLCAkdG9FbmNvZGluZywgJGZyb21FbmNvZGluZykgewogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICR2ID0gTWJzdHJpbmc6Om1iX2NvbnZlcnRfZW5jb2RpbmcoJHYsICR0b0VuY29kaW5nLCAkZnJvbUVuY29kaW5nKSkgewogICAgICAgICAgICAgICAgJG9rID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRvayA/ICRmcm9tRW5jb2RpbmcgOiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2RlY29kZV9taW1laGVhZGVyKCRzKQogICAgewogICAgICAgIHJldHVybiBpY29udl9taW1lX2RlY29kZSgkcywgMiwgc2VsZjo6JGludGVybmFsRW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfZW5jb2RlX21pbWVoZWFkZXIoJHMsICRjaGFyc2V0ID0gbnVsbCwgJHRyYW5zZmVyRW5jb2RpbmcgPSBudWxsLCAkbGluZWZlZWQgPSBudWxsLCAkaW5kZW50ID0gbnVsbCkKICAgIHsKICAgICAgICB0cmlnZ2VyX2Vycm9yKCdtYl9lbmNvZGVfbWltZWhlYWRlcigpIGlzIGJ1Z2dlZC4gUGxlYXNlIHVzZSBpY29udl9taW1lX2VuY29kZSgpIGluc3RlYWQnLCBFX1VTRVJfV0FSTklORyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9kZWNvZGVfbnVtZXJpY2VudGl0eSgkcywgJGNvbnZtYXAsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRzICYmICFcaXNfc2NhbGFyKCRzKSAmJiAhKFxpc19vYmplY3QoJHMpICYmIFxtZXRob2RfZXhpc3RzKCRzLCAnX190b1N0cmluZycpKSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdtYl9kZWNvZGVfbnVtZXJpY2VudGl0eSgpIGV4cGVjdHMgcGFyYW1ldGVyIDEgdG8gYmUgc3RyaW5nLCAnLlxnZXR0eXBlKCRzKS4nIGdpdmVuJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVxpc19hcnJheSgkY29udm1hcCkgfHwgISRjb252bWFwKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkZW5jb2RpbmcgJiYgIVxpc19zY2FsYXIoJGVuY29kaW5nKSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdtYl9kZWNvZGVfbnVtZXJpY2VudGl0eSgpIGV4cGVjdHMgcGFyYW1ldGVyIDMgdG8gYmUgc3RyaW5nLCAnLlxnZXR0eXBlKCRzKS4nIGdpdmVuJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuICcnOyAgLy8gSW5zdGVhZCBvZiBudWxsIChjZi4gbWJfZW5jb2RlX251bWVyaWNlbnRpdHkpLgogICAgICAgIH0KCiAgICAgICAgJHMgPSAoc3RyaW5nKSAkczsKICAgICAgICBpZiAoJycgPT09ICRzKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZyk7CgogICAgICAgIGlmICgnVVRGLTgnID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgJGVuY29kaW5nID0gbnVsbDsKICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvL3UnLCAkcykpIHsKICAgICAgICAgICAgICAgICRzID0gQGljb252KCdVVEYtOCcsICdVVEYtOC8vSUdOT1JFJywgJHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHMgPSBpY29udigkZW5jb2RpbmcsICdVVEYtOC8vSUdOT1JFJywgJHMpOwogICAgICAgIH0KCiAgICAgICAgJGNudCA9IGZsb29yKFxjb3VudCgkY29udm1hcCkgLyA0KSAqIDQ7CgogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRjbnQ7ICRpICs9IDQpIHsKICAgICAgICAgICAgLy8gY29sbGVjdG9yX2RlY29kZV9odG1sbnVtZXJpY2VudGl0eSBpZ25vcmVzICRjb252bWFwWyRpICsgM10KICAgICAgICAgICAgJGNvbnZtYXBbJGldICs9ICRjb252bWFwWyRpICsgMl07CiAgICAgICAgICAgICRjb252bWFwWyRpICsgMV0gKz0gJGNvbnZtYXBbJGkgKyAyXTsKICAgICAgICB9CgogICAgICAgICRzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCcvJiMoPzowKihbMC05XSspfHgwKihbMC05YS1mQS1GXSspKSg/ISYpOz8vJywgZnVuY3Rpb24gKGFycmF5ICRtKSB1c2UgKCRjbnQsICRjb252bWFwKSB7CiAgICAgICAgICAgICRjID0gaXNzZXQoJG1bMl0pID8gKGludCkgaGV4ZGVjKCRtWzJdKSA6ICRtWzFdOwogICAgICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkY250OyAkaSArPSA0KSB7CiAgICAgICAgICAgICAgICBpZiAoJGMgPj0gJGNvbnZtYXBbJGldICYmICRjIDw9ICRjb252bWFwWyRpICsgMV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWJzdHJpbmc6Om1iX2NocigkYyAtICRjb252bWFwWyRpICsgMl0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG1bMF07CiAgICAgICAgfSwgJHMpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAkczsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpY29udignVVRGLTgnLCAkZW5jb2RpbmcuJy8vSUdOT1JFJywgJHMpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfZW5jb2RlX251bWVyaWNlbnRpdHkoJHMsICRjb252bWFwLCAkZW5jb2RpbmcgPSBudWxsLCAkaXNfaGV4ID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRzICYmICFcaXNfc2NhbGFyKCRzKSAmJiAhKFxpc19vYmplY3QoJHMpICYmIFxtZXRob2RfZXhpc3RzKCRzLCAnX190b1N0cmluZycpKSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdtYl9lbmNvZGVfbnVtZXJpY2VudGl0eSgpIGV4cGVjdHMgcGFyYW1ldGVyIDEgdG8gYmUgc3RyaW5nLCAnLlxnZXR0eXBlKCRzKS4nIGdpdmVuJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVxpc19hcnJheSgkY29udm1hcCkgfHwgISRjb252bWFwKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkZW5jb2RpbmcgJiYgIVxpc19zY2FsYXIoJGVuY29kaW5nKSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdtYl9lbmNvZGVfbnVtZXJpY2VudGl0eSgpIGV4cGVjdHMgcGFyYW1ldGVyIDMgdG8gYmUgc3RyaW5nLCAnLlxnZXR0eXBlKCRzKS4nIGdpdmVuJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7ICAvLyBJbnN0ZWFkIG9mICcnIChjZi4gbWJfZGVjb2RlX251bWVyaWNlbnRpdHkpLgogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgIT09ICRpc19oZXggJiYgIVxpc19zY2FsYXIoJGlzX2hleCkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfZW5jb2RlX251bWVyaWNlbnRpdHkoKSBleHBlY3RzIHBhcmFtZXRlciA0IHRvIGJlIGJvb2xlYW4sICcuXGdldHR5cGUoJHMpLicgZ2l2ZW4nLCBFX1VTRVJfV0FSTklORyk7CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRzID0gKHN0cmluZykgJHM7CiAgICAgICAgaWYgKCcnID09PSAkcykgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwoKICAgICAgICBpZiAoJ1VURi04JyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRlbmNvZGluZyA9IG51bGw7CiAgICAgICAgICAgIGlmICghcHJlZ19tYXRjaCgnLy91JywgJHMpKSB7CiAgICAgICAgICAgICAgICAkcyA9IEBpY29udignVVRGLTgnLCAnVVRGLTgvL0lHTk9SRScsICRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRzID0gaWNvbnYoJGVuY29kaW5nLCAnVVRGLTgvL0lHTk9SRScsICRzKTsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyAkdWxlbk1hc2sgPSBhcnJheSgiXHhDMCIgPT4gMiwgIlx4RDAiID0+IDIsICJceEUwIiA9PiAzLCAiXHhGMCIgPT4gNCk7CgogICAgICAgICRjbnQgPSBmbG9vcihcY291bnQoJGNvbnZtYXApIC8gNCkgKiA0OwogICAgICAgICRpID0gMDsKICAgICAgICAkbGVuID0gXHN0cmxlbigkcyk7CiAgICAgICAgJHJlc3VsdCA9ICcnOwoKICAgICAgICB3aGlsZSAoJGkgPCAkbGVuKSB7CiAgICAgICAgICAgICR1bGVuID0gJHNbJGldIDwgIlx4ODAiID8gMSA6ICR1bGVuTWFza1skc1skaV0gJiAiXHhGMCJdOwogICAgICAgICAgICAkdWNociA9IHN1YnN0cigkcywgJGksICR1bGVuKTsKICAgICAgICAgICAgJGkgKz0gJHVsZW47CiAgICAgICAgICAgICRjID0gc2VsZjo6bWJfb3JkKCR1Y2hyKTsKCiAgICAgICAgICAgIGZvciAoJGogPSAwOyAkaiA8ICRjbnQ7ICRqICs9IDQpIHsKICAgICAgICAgICAgICAgIGlmICgkYyA+PSAkY29udm1hcFskal0gJiYgJGMgPD0gJGNvbnZtYXBbJGogKyAxXSkgewogICAgICAgICAgICAgICAgICAgICRjT2Zmc2V0ID0gKCRjICsgJGNvbnZtYXBbJGogKyAyXSkgJiAkY29udm1hcFskaiArIDNdOwogICAgICAgICAgICAgICAgICAgICRyZXN1bHQgLj0gJGlzX2hleCA/IHNwcmludGYoJyYjeCVYOycsICRjT2Zmc2V0KSA6ICcmIycuJGNPZmZzZXQuJzsnOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCAuPSAkdWNocjsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaWNvbnYoJ1VURi04JywgJGVuY29kaW5nLicvL0lHTk9SRScsICRyZXN1bHQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfY29udmVydF9jYXNlKCRzLCAkbW9kZSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkcyA9IChzdHJpbmcpICRzOwogICAgICAgIGlmICgnJyA9PT0gJHMpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKTsKCiAgICAgICAgaWYgKCdVVEYtOCcgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICAkZW5jb2RpbmcgPSBudWxsOwogICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy8vdScsICRzKSkgewogICAgICAgICAgICAgICAgJHMgPSBAaWNvbnYoJ1VURi04JywgJ1VURi04Ly9JR05PUkUnLCAkcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcyA9IGljb252KCRlbmNvZGluZywgJ1VURi04Ly9JR05PUkUnLCAkcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoTUJfQ0FTRV9USVRMRSA9PSAkbW9kZSkgewogICAgICAgICAgICBzdGF0aWMgJHRpdGxlUmVnZXhwID0gbnVsbDsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICR0aXRsZVJlZ2V4cCkgewogICAgICAgICAgICAgICAgJHRpdGxlUmVnZXhwID0gc2VsZjo6Z2V0RGF0YSgndGl0bGVDYXNlUmVnZXhwJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHRpdGxlUmVnZXhwLCBhcnJheShfX0NMQVNTX18sICd0aXRsZV9jYXNlJyksICRzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoTUJfQ0FTRV9VUFBFUiA9PSAkbW9kZSkgewogICAgICAgICAgICAgICAgc3RhdGljICR1cHBlciA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJHVwcGVyKSB7CiAgICAgICAgICAgICAgICAgICAgJHVwcGVyID0gc2VsZjo6Z2V0RGF0YSgndXBwZXJDYXNlJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbWFwID0gJHVwcGVyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok1CX0NBU0VfRk9MRCA9PT0gJG1vZGUpIHsKICAgICAgICAgICAgICAgICAgICAkcyA9IHN0cl9yZXBsYWNlKHNlbGY6OiRjYXNlRm9sZFswXSwgc2VsZjo6JGNhc2VGb2xkWzFdLCAkcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgc3RhdGljICRsb3dlciA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJGxvd2VyKSB7CiAgICAgICAgICAgICAgICAgICAgJGxvd2VyID0gc2VsZjo6Z2V0RGF0YSgnbG93ZXJDYXNlJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbWFwID0gJGxvd2VyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdGF0aWMgJHVsZW5NYXNrID0gYXJyYXkoIlx4QzAiID0+IDIsICJceEQwIiA9PiAyLCAiXHhFMCIgPT4gMywgIlx4RjAiID0+IDQpOwoKICAgICAgICAgICAgJGkgPSAwOwogICAgICAgICAgICAkbGVuID0gXHN0cmxlbigkcyk7CgogICAgICAgICAgICB3aGlsZSAoJGkgPCAkbGVuKSB7CiAgICAgICAgICAgICAgICAkdWxlbiA9ICRzWyRpXSA8ICJceDgwIiA/IDEgOiAkdWxlbk1hc2tbJHNbJGldICYgIlx4RjAiXTsKICAgICAgICAgICAgICAgICR1Y2hyID0gc3Vic3RyKCRzLCAkaSwgJHVsZW4pOwogICAgICAgICAgICAgICAgJGkgKz0gJHVsZW47CgogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXBbJHVjaHJdKSkgewogICAgICAgICAgICAgICAgICAgICR1Y2hyID0gJG1hcFskdWNocl07CiAgICAgICAgICAgICAgICAgICAgJG5sZW4gPSBcc3RybGVuKCR1Y2hyKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRubGVuID09ICR1bGVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRubGVuID0gJGk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzWy0tJG5sZW5dID0gJHVjaHJbLS0kdWxlbl07CiAgICAgICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKCR1bGVuKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkcyA9IHN1YnN0cl9yZXBsYWNlKCRzLCAkdWNociwgJGkgLSAkdWxlbiwgJHVsZW4pOwogICAgICAgICAgICAgICAgICAgICAgICAkbGVuICs9ICRubGVuIC0gJHVsZW47CiAgICAgICAgICAgICAgICAgICAgICAgICRpICs9ICRubGVuIC0gJHVsZW47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAkczsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpY29udignVVRGLTgnLCAkZW5jb2RpbmcuJy8vSUdOT1JFJywgJHMpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfaW50ZXJuYWxfZW5jb2RpbmcoJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokaW50ZXJuYWxFbmNvZGluZzsKICAgICAgICB9CgogICAgICAgICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZyk7CgogICAgICAgIGlmICgnVVRGLTgnID09PSAkZW5jb2RpbmcgfHwgZmFsc2UgIT09IEBpY29udigkZW5jb2RpbmcsICRlbmNvZGluZywgJyAnKSkgewogICAgICAgICAgICBzZWxmOjokaW50ZXJuYWxFbmNvZGluZyA9ICRlbmNvZGluZzsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfbGFuZ3VhZ2UoJGxhbmcgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkbGFuZykgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JGxhbmd1YWdlOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoICgkbGFuZyA9IHN0cnRvbG93ZXIoJGxhbmcpKSB7CiAgICAgICAgICAgIGNhc2UgJ3VuaSc6CiAgICAgICAgICAgIGNhc2UgJ25ldXRyYWwnOgogICAgICAgICAgICAgICAgc2VsZjo6JGxhbmd1YWdlID0gJGxhbmc7CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9saXN0X2VuY29kaW5ncygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KCdVVEYtOCcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfZW5jb2RpbmdfYWxpYXNlcygkZW5jb2RpbmcpCiAgICB7CiAgICAgICAgc3dpdGNoIChzdHJ0b3VwcGVyKCRlbmNvZGluZykpIHsKICAgICAgICAgICAgY2FzZSAnVVRGOCc6CiAgICAgICAgICAgIGNhc2UgJ1VURi04JzoKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgndXRmOCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfY2hlY2tfZW5jb2RpbmcoJHZhciA9IG51bGwsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZhcikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRlbmNvZGluZyA9IHNlbGY6OiRpbnRlcm5hbEVuY29kaW5nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6Om1iX2RldGVjdF9lbmNvZGluZygkdmFyLCBhcnJheSgkZW5jb2RpbmcpKSB8fCBmYWxzZSAhPT0gQGljb252KCRlbmNvZGluZywgJGVuY29kaW5nLCAkdmFyKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2RldGVjdF9lbmNvZGluZygkc3RyLCAkZW5jb2RpbmdMaXN0ID0gbnVsbCwgJHN0cmljdCA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkZW5jb2RpbmdMaXN0KSB7CiAgICAgICAgICAgICRlbmNvZGluZ0xpc3QgPSBzZWxmOjokZW5jb2RpbmdMaXN0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghXGlzX2FycmF5KCRlbmNvZGluZ0xpc3QpKSB7CiAgICAgICAgICAgICAgICAkZW5jb2RpbmdMaXN0ID0gYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnLCcsICRlbmNvZGluZ0xpc3QpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZW5jb2RpbmdMaXN0ID0gYXJyYXlfbWFwKCdzdHJ0b3VwcGVyJywgJGVuY29kaW5nTGlzdCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkZW5jb2RpbmdMaXN0IGFzICRlbmMpIHsKICAgICAgICAgICAgc3dpdGNoICgkZW5jKSB7CiAgICAgICAgICAgICAgICBjYXNlICdBU0NJSSc6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvW1x4ODAtXHhGRl0vJywgJHN0cikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRlbmM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ1VURjgnOgogICAgICAgICAgICAgICAgY2FzZSAnVVRGLTgnOgogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvL3UnLCAkc3RyKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ1VURi04JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gc3RybmNtcCgkZW5jLCAnSVNPLTg4NTktJywgOSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRlbmM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9kZXRlY3Rfb3JkZXIoJGVuY29kaW5nTGlzdCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZ0xpc3QpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRlbmNvZGluZ0xpc3Q7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVxpc19hcnJheSgkZW5jb2RpbmdMaXN0KSkgewogICAgICAgICAgICAkZW5jb2RpbmdMaXN0ID0gYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnLCcsICRlbmNvZGluZ0xpc3QpKTsKICAgICAgICB9CiAgICAgICAgJGVuY29kaW5nTGlzdCA9IGFycmF5X21hcCgnc3RydG91cHBlcicsICRlbmNvZGluZ0xpc3QpOwoKICAgICAgICBmb3JlYWNoICgkZW5jb2RpbmdMaXN0IGFzICRlbmMpIHsKICAgICAgICAgICAgc3dpdGNoICgkZW5jKSB7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGlmIChzdHJuY21wKCRlbmMsICdJU08tODg1OS0nLCA5KSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIG5vIGJyZWFrCiAgICAgICAgICAgICAgICBjYXNlICdBU0NJSSc6CiAgICAgICAgICAgICAgICBjYXNlICdVVEY4JzoKICAgICAgICAgICAgICAgIGNhc2UgJ1VURi04JzoKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JGVuY29kaW5nTGlzdCA9ICRlbmNvZGluZ0xpc3Q7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RybGVuKCRzLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZyk7CiAgICAgICAgaWYgKCdDUDg1MCcgPT09ICRlbmNvZGluZyB8fCAnQVNDSUknID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuIFxzdHJsZW4oJHMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEBpY29udl9zdHJsZW4oJHMsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwogICAgICAgIGlmICgnQ1A4NTAnID09PSAkZW5jb2RpbmcgfHwgJ0FTQ0lJJyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0KTsKICAgICAgICB9CgogICAgICAgICRuZWVkbGUgPSAoc3RyaW5nKSAkbmVlZGxlOwogICAgICAgIGlmICgnJyA9PT0gJG5lZWRsZSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKF9fTUVUSE9EX18uJzogRW1wdHkgZGVsaW1pdGVyJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGljb252X3N0cnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCA9IDAsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKTsKICAgICAgICBpZiAoJ0NQODUwJyA9PT0gJGVuY29kaW5nIHx8ICdBU0NJSScgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRvZmZzZXQgIT0gKGludCkgJG9mZnNldCkgewogICAgICAgICAgICAkb2Zmc2V0ID0gMDsKICAgICAgICB9IGVsc2VpZiAoJG9mZnNldCA9IChpbnQpICRvZmZzZXQpIHsKICAgICAgICAgICAgaWYgKCRvZmZzZXQgPCAwKSB7CiAgICAgICAgICAgICAgICBpZiAoMCA+ICRvZmZzZXQgKz0gc2VsZjo6bWJfc3RybGVuKCRuZWVkbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJGhheXN0YWNrID0gc2VsZjo6bWJfc3Vic3RyKCRoYXlzdGFjaywgMCwgJG9mZnNldCwgJGVuY29kaW5nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRvZmZzZXQgPSAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGhheXN0YWNrID0gc2VsZjo6bWJfc3Vic3RyKCRoYXlzdGFjaywgJG9mZnNldCwgMjE0NzQ4MzY0NywgJGVuY29kaW5nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHBvcyA9IGljb252X3N0cnJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkZW5jb2RpbmcpOwoKICAgICAgICByZXR1cm4gZmFsc2UgIT09ICRwb3MgPyAkb2Zmc2V0ICsgJHBvcyA6IGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RyX3NwbGl0KCRzdHJpbmcsICRzcGxpdF9sZW5ndGggPSAxLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkc3RyaW5nICYmICFcaXNfc2NhbGFyKCRzdHJpbmcpICYmICEoXGlzX29iamVjdCgkc3RyaW5nKSAmJiBcbWV0aG9kX2V4aXN0cygkc3RyaW5nLCAnX190b1N0cmluZycpKSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdtYl9zdHJfc3BsaXQoKSBleHBlY3RzIHBhcmFtZXRlciAxIHRvIGJlIHN0cmluZywgJy5cZ2V0dHlwZSgkc3RyaW5nKS4nIGdpdmVuJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoMSA+ICRzcGxpdF9sZW5ndGggPSAoaW50KSAkc3BsaXRfbGVuZ3RoKSB7CiAgICAgICAgICAgIHRyaWdnZXJfZXJyb3IoJ1RoZSBsZW5ndGggb2YgZWFjaCBzZWdtZW50IG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm8nLCBFX1VTRVJfV0FSTklORyk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRlbmNvZGluZyA9IG1iX2ludGVybmFsX2VuY29kaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ1VURi04JyA9PT0gJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKSkgewogICAgICAgICAgICAkcnggPSAnLygnOwogICAgICAgICAgICB3aGlsZSAoNjU1MzUgPCAkc3BsaXRfbGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAkcnggLj0gJy57NjU1MzV9JzsKICAgICAgICAgICAgICAgICRzcGxpdF9sZW5ndGggLT0gNjU1MzU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJ4IC49ICcueycuJHNwbGl0X2xlbmd0aC4nfSkvdXMnOwoKICAgICAgICAgICAgcmV0dXJuIHByZWdfc3BsaXQoJHJ4LCAkc3RyaW5nLCBudWxsLCBQUkVHX1NQTElUX0RFTElNX0NBUFRVUkUgfCBQUkVHX1NQTElUX05PX0VNUFRZKTsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgICRsZW5ndGggPSBtYl9zdHJsZW4oJHN0cmluZywgJGVuY29kaW5nKTsKCiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGxlbmd0aDsgJGkgKz0gJHNwbGl0X2xlbmd0aCkgewogICAgICAgICAgICAkcmVzdWx0W10gPSBtYl9zdWJzdHIoJHN0cmluZywgJGksICRzcGxpdF9sZW5ndGgsICRlbmNvZGluZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cnRvbG93ZXIoJHMsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6Om1iX2NvbnZlcnRfY2FzZSgkcywgTUJfQ0FTRV9MT1dFUiwgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cnRvdXBwZXIoJHMsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6Om1iX2NvbnZlcnRfY2FzZSgkcywgTUJfQ0FTRV9VUFBFUiwgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N1YnN0aXR1dGVfY2hhcmFjdGVyKCRjID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoMCA9PT0gc3RyY2FzZWNtcCgkYywgJ25vbmUnKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsICE9PSAkYyA/IGZhbHNlIDogJ25vbmUnOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3Vic3RyKCRzLCAkc3RhcnQsICRsZW5ndGggPSBudWxsLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZyk7CiAgICAgICAgaWYgKCdDUDg1MCcgPT09ICRlbmNvZGluZyB8fCAnQVNDSUknID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuIChzdHJpbmcpIHN1YnN0cigkcywgJHN0YXJ0LCBudWxsID09PSAkbGVuZ3RoID8gMjE0NzQ4MzY0NyA6ICRsZW5ndGgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRzdGFydCA8IDApIHsKICAgICAgICAgICAgJHN0YXJ0ID0gaWNvbnZfc3RybGVuKCRzLCAkZW5jb2RpbmcpICsgJHN0YXJ0OwogICAgICAgICAgICBpZiAoJHN0YXJ0IDwgMCkgewogICAgICAgICAgICAgICAgJHN0YXJ0ID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRsZW5ndGgpIHsKICAgICAgICAgICAgJGxlbmd0aCA9IDIxNDc0ODM2NDc7CiAgICAgICAgfSBlbHNlaWYgKCRsZW5ndGggPCAwKSB7CiAgICAgICAgICAgICRsZW5ndGggPSBpY29udl9zdHJsZW4oJHMsICRlbmNvZGluZykgKyAkbGVuZ3RoIC0gJHN0YXJ0OwogICAgICAgICAgICBpZiAoJGxlbmd0aCA8IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIChzdHJpbmcpIGljb252X3N1YnN0cigkcywgJHN0YXJ0LCAkbGVuZ3RoLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RyaXBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQgPSAwLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgICRoYXlzdGFjayA9IHNlbGY6Om1iX2NvbnZlcnRfY2FzZSgkaGF5c3RhY2ssIHNlbGY6Ok1CX0NBU0VfRk9MRCwgJGVuY29kaW5nKTsKICAgICAgICAkbmVlZGxlID0gc2VsZjo6bWJfY29udmVydF9jYXNlKCRuZWVkbGUsIHNlbGY6Ok1CX0NBU0VfRk9MRCwgJGVuY29kaW5nKTsKCiAgICAgICAgcmV0dXJuIHNlbGY6Om1iX3N0cnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJpc3RyKCRoYXlzdGFjaywgJG5lZWRsZSwgJHBhcnQgPSBmYWxzZSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkcG9zID0gc2VsZjo6bWJfc3RyaXBvcygkaGF5c3RhY2ssICRuZWVkbGUsIDAsICRlbmNvZGluZyk7CgogICAgICAgIHJldHVybiBzZWxmOjpnZXRTdWJwYXJ0KCRwb3MsICRwYXJ0LCAkaGF5c3RhY2ssICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJyY2hyKCRoYXlzdGFjaywgJG5lZWRsZSwgJHBhcnQgPSBmYWxzZSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwogICAgICAgIGlmICgnQ1A4NTAnID09PSAkZW5jb2RpbmcgfHwgJ0FTQ0lJJyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRwb3MgPSBzdHJycG9zKCRoYXlzdGFjaywgJG5lZWRsZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJG5lZWRsZSA9IHNlbGY6Om1iX3N1YnN0cigkbmVlZGxlLCAwLCAxLCAkZW5jb2RpbmcpOwogICAgICAgICAgICAkcG9zID0gaWNvbnZfc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRlbmNvZGluZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0U3VicGFydCgkcG9zLCAkcGFydCwgJGhheXN0YWNrLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RycmljaHIoJGhheXN0YWNrLCAkbmVlZGxlLCAkcGFydCA9IGZhbHNlLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgICRuZWVkbGUgPSBzZWxmOjptYl9zdWJzdHIoJG5lZWRsZSwgMCwgMSwgJGVuY29kaW5nKTsKICAgICAgICAkcG9zID0gc2VsZjo6bWJfc3Rycmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkZW5jb2RpbmcpOwoKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0U3VicGFydCgkcG9zLCAkcGFydCwgJGhheXN0YWNrLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3Rycmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkaGF5c3RhY2sgPSBzZWxmOjptYl9jb252ZXJ0X2Nhc2UoJGhheXN0YWNrLCBzZWxmOjpNQl9DQVNFX0ZPTEQsICRlbmNvZGluZyk7CiAgICAgICAgJG5lZWRsZSA9IHNlbGY6Om1iX2NvbnZlcnRfY2FzZSgkbmVlZGxlLCBzZWxmOjpNQl9DQVNFX0ZPTEQsICRlbmNvZGluZyk7CgogICAgICAgIHJldHVybiBzZWxmOjptYl9zdHJycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCwgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cnN0cigkaGF5c3RhY2ssICRuZWVkbGUsICRwYXJ0ID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJHBvcyA9IHN0cnBvcygkaGF5c3RhY2ssICRuZWVkbGUpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJHBvcykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICgkcGFydCkgewogICAgICAgICAgICByZXR1cm4gc3Vic3RyKCRoYXlzdGFjaywgMCwgJHBvcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3Vic3RyKCRoYXlzdGFjaywgJHBvcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9nZXRfaW5mbygkdHlwZSA9ICdhbGwnKQogICAgewogICAgICAgICRpbmZvID0gYXJyYXkoCiAgICAgICAgICAgICdpbnRlcm5hbF9lbmNvZGluZycgPT4gc2VsZjo6JGludGVybmFsRW5jb2RpbmcsCiAgICAgICAgICAgICdodHRwX291dHB1dCcgPT4gJ3Bhc3MnLAogICAgICAgICAgICAnaHR0cF9vdXRwdXRfY29udl9taW1ldHlwZXMnID0+ICdeKHRleHQvfGFwcGxpY2F0aW9uL3hodG1sXCt4bWwpJywKICAgICAgICAgICAgJ2Z1bmNfb3ZlcmxvYWQnID0+IDAsCiAgICAgICAgICAgICdmdW5jX292ZXJsb2FkX2xpc3QnID0+ICdubyBvdmVybG9hZCcsCiAgICAgICAgICAgICdtYWlsX2NoYXJzZXQnID0+ICdVVEYtOCcsCiAgICAgICAgICAgICdtYWlsX2hlYWRlcl9lbmNvZGluZycgPT4gJ0JBU0U2NCcsCiAgICAgICAgICAgICdtYWlsX2JvZHlfZW5jb2RpbmcnID0+ICdCQVNFNjQnLAogICAgICAgICAgICAnaWxsZWdhbF9jaGFycycgPT4gMCwKICAgICAgICAgICAgJ2VuY29kaW5nX3RyYW5zbGF0aW9uJyA9PiAnT2ZmJywKICAgICAgICAgICAgJ2xhbmd1YWdlJyA9PiBzZWxmOjokbGFuZ3VhZ2UsCiAgICAgICAgICAgICdkZXRlY3Rfb3JkZXInID0+IHNlbGY6OiRlbmNvZGluZ0xpc3QsCiAgICAgICAgICAgICdzdWJzdGl0dXRlX2NoYXJhY3RlcicgPT4gJ25vbmUnLAogICAgICAgICAgICAnc3RyaWN0X2RldGVjdGlvbicgPT4gJ09mZicsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCdhbGwnID09PSAkdHlwZSkgewogICAgICAgICAgICByZXR1cm4gJGluZm87CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkaW5mb1skdHlwZV0pKSB7CiAgICAgICAgICAgIHJldHVybiAkaW5mb1skdHlwZV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9odHRwX2lucHV0KCR0eXBlID0gJycpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfaHR0cF9vdXRwdXQoJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gbnVsbCAhPT0gJGVuY29kaW5nID8gJ3Bhc3MnID09PSAkZW5jb2RpbmcgOiAncGFzcyc7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJ3aWR0aCgkcywgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwoKICAgICAgICBpZiAoJ1VURi04JyAhPT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRzID0gaWNvbnYoJGVuY29kaW5nLCAnVVRGLTgvL0lHTk9SRScsICRzKTsKICAgICAgICB9CgogICAgICAgICRzID0gcHJlZ19yZXBsYWNlKCcvW1x4ezExMDB9LVx4ezExNUZ9XHh7MjMyOX1ceHsyMzJBfVx4ezJFODB9LVx4ezMwM0V9XHh7MzA0MH0tXHh7QTRDRn1ceHtBQzAwfS1ceHtEN0EzfVx4e0Y5MDB9LVx4e0ZBRkZ9XHh7RkUxMH0tXHh7RkUxOX1ceHtGRTMwfS1ceHtGRTZGfVx4e0ZGMDB9LVx4e0ZGNjB9XHh7RkZFMH0tXHh7RkZFNn1ceHsyMDAwMH0tXHh7MkZGRkR9XHh7MzAwMDB9LVx4ezNGRkZEfV0vdScsICcnLCAkcywgLTEsICR3aWRlKTsKCiAgICAgICAgcmV0dXJuICgkd2lkZSA8PCAxKSArIGljb252X3N0cmxlbigkcywgJ1VURi04Jyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdWJzdHJfY291bnQoJGhheXN0YWNrLCAkbmVlZGxlLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBzdWJzdHJfY291bnQoJGhheXN0YWNrLCAkbmVlZGxlKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX291dHB1dF9oYW5kbGVyKCRjb250ZW50cywgJHN0YXR1cykKICAgIHsKICAgICAgICByZXR1cm4gJGNvbnRlbnRzOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfY2hyKCRjb2RlLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmICgweDgwID4gJGNvZGUgJT0gMHgyMDAwMDApIHsKICAgICAgICAgICAgJHMgPSBcY2hyKCRjb2RlKTsKICAgICAgICB9IGVsc2VpZiAoMHg4MDAgPiAkY29kZSkgewogICAgICAgICAgICAkcyA9IFxjaHIoMHhDMCB8ICRjb2RlID4+IDYpLlxjaHIoMHg4MCB8ICRjb2RlICYgMHgzRik7CiAgICAgICAgfSBlbHNlaWYgKDB4MTAwMDAgPiAkY29kZSkgewogICAgICAgICAgICAkcyA9IFxjaHIoMHhFMCB8ICRjb2RlID4+IDEyKS5cY2hyKDB4ODAgfCAkY29kZSA+PiA2ICYgMHgzRikuXGNocigweDgwIHwgJGNvZGUgJiAweDNGKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcyA9IFxjaHIoMHhGMCB8ICRjb2RlID4+IDE4KS5cY2hyKDB4ODAgfCAkY29kZSA+PiAxMiAmIDB4M0YpLlxjaHIoMHg4MCB8ICRjb2RlID4+IDYgJiAweDNGKS5cY2hyKDB4ODAgfCAkY29kZSAmIDB4M0YpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdVVEYtOCcgIT09ICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZykpIHsKICAgICAgICAgICAgJHMgPSBtYl9jb252ZXJ0X2VuY29kaW5nKCRzLCAkZW5jb2RpbmcsICdVVEYtOCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfb3JkKCRzLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmICgnVVRGLTgnICE9PSAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpKSB7CiAgICAgICAgICAgICRzID0gbWJfY29udmVydF9lbmNvZGluZygkcywgJ1VURi04JywgJGVuY29kaW5nKTsKICAgICAgICB9CgogICAgICAgIGlmICgxID09PSBcc3RybGVuKCRzKSkgewogICAgICAgICAgICByZXR1cm4gXG9yZCgkcyk7CiAgICAgICAgfQoKICAgICAgICAkY29kZSA9ICgkcyA9IHVucGFjaygnQyonLCBzdWJzdHIoJHMsIDAsIDQpKSkgPyAkc1sxXSA6IDA7CiAgICAgICAgaWYgKDB4RjAgPD0gJGNvZGUpIHsKICAgICAgICAgICAgcmV0dXJuICgoJGNvZGUgLSAweEYwKSA8PCAxOCkgKyAoKCRzWzJdIC0gMHg4MCkgPDwgMTIpICsgKCgkc1szXSAtIDB4ODApIDw8IDYpICsgJHNbNF0gLSAweDgwOwogICAgICAgIH0KICAgICAgICBpZiAoMHhFMCA8PSAkY29kZSkgewogICAgICAgICAgICByZXR1cm4gKCgkY29kZSAtIDB4RTApIDw8IDEyKSArICgoJHNbMl0gLSAweDgwKSA8PCA2KSArICRzWzNdIC0gMHg4MDsKICAgICAgICB9CiAgICAgICAgaWYgKDB4QzAgPD0gJGNvZGUpIHsKICAgICAgICAgICAgcmV0dXJuICgoJGNvZGUgLSAweEMwKSA8PCA2KSArICRzWzJdIC0gMHg4MDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29kZTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRTdWJwYXJ0KCRwb3MsICRwYXJ0LCAkaGF5c3RhY2ssICRlbmNvZGluZykKICAgIHsKICAgICAgICBpZiAoZmFsc2UgPT09ICRwb3MpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoJHBhcnQpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6Om1iX3N1YnN0cigkaGF5c3RhY2ssIDAsICRwb3MsICRlbmNvZGluZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6bWJfc3Vic3RyKCRoYXlzdGFjaywgJHBvcywgbnVsbCwgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBodG1sX2VuY29kaW5nX2NhbGxiYWNrKGFycmF5ICRtKQogICAgewogICAgICAgICRpID0gMTsKICAgICAgICAkZW50aXRpZXMgPSAnJzsKICAgICAgICAkbSA9IHVucGFjaygnQyonLCBodG1sZW50aXRpZXMoJG1bMF0sIEVOVF9DT01QQVQsICdVVEYtOCcpKTsKCiAgICAgICAgd2hpbGUgKGlzc2V0KCRtWyRpXSkpIHsKICAgICAgICAgICAgaWYgKDB4ODAgPiAkbVskaV0pIHsKICAgICAgICAgICAgICAgICRlbnRpdGllcyAuPSBcY2hyKCRtWyRpKytdKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgweEYwIDw9ICRtWyRpXSkgewogICAgICAgICAgICAgICAgJGMgPSAoKCRtWyRpKytdIC0gMHhGMCkgPDwgMTgpICsgKCgkbVskaSsrXSAtIDB4ODApIDw8IDEyKSArICgoJG1bJGkrK10gLSAweDgwKSA8PCA2KSArICRtWyRpKytdIC0gMHg4MDsKICAgICAgICAgICAgfSBlbHNlaWYgKDB4RTAgPD0gJG1bJGldKSB7CiAgICAgICAgICAgICAgICAkYyA9ICgoJG1bJGkrK10gLSAweEUwKSA8PCAxMikgKyAoKCRtWyRpKytdIC0gMHg4MCkgPDwgNikgKyAkbVskaSsrXSAtIDB4ODA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYyA9ICgoJG1bJGkrK10gLSAweEMwKSA8PCA2KSArICRtWyRpKytdIC0gMHg4MDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVudGl0aWVzIC49ICcmIycuJGMuJzsnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRlbnRpdGllczsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB0aXRsZV9jYXNlKGFycmF5ICRzKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjptYl9jb252ZXJ0X2Nhc2UoJHNbMV0sIE1CX0NBU0VfVVBQRVIsICdVVEYtOCcpLnNlbGY6Om1iX2NvbnZlcnRfY2FzZSgkc1syXSwgTUJfQ0FTRV9MT1dFUiwgJ1VURi04Jyk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0RGF0YSgkZmlsZSkKICAgIHsKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUgPSBfX0RJUl9fLicvUmVzb3VyY2VzL3VuaWRhdGEvJy4kZmlsZS4nLnBocCcpKSB7CiAgICAgICAgICAgIHJldHVybiByZXF1aXJlICRmaWxlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldEVuY29kaW5nKCRlbmNvZGluZykKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokaW50ZXJuYWxFbmNvZGluZzsKICAgICAgICB9CgogICAgICAgIGlmICgnVVRGLTgnID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuICdVVEYtOCc7CiAgICAgICAgfQoKICAgICAgICAkZW5jb2RpbmcgPSBzdHJ0b3VwcGVyKCRlbmNvZGluZyk7CgogICAgICAgIGlmICgnOEJJVCcgPT09ICRlbmNvZGluZyB8fCAnQklOQVJZJyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAnQ1A4NTAnOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdVVEY4JyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAnVVRGLTgnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRlbmNvZGluZzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3M7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKCi8qKgogKiBQaHBQcm9jZXNzIHJ1bnMgYSBQSFAgc2NyaXB0IGluIGFuIGluZGVwZW5kZW50IHByb2Nlc3MuCiAqCiAqICAgICAkcCA9IG5ldyBQaHBQcm9jZXNzKCc8P3BocCBlY2hvICJmb28iOyA/PicpOwogKiAgICAgJHAtPnJ1bigpOwogKiAgICAgcHJpbnQgJHAtPmdldE91dHB1dCgpLiJcbiI7CiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgUGhwUHJvY2VzcyBleHRlbmRzIFByb2Nlc3MKewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJHNjcmlwdCAgVGhlIFBIUCBzY3JpcHQgdG8gcnVuIChhcyBhIHN0cmluZykKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY3dkICAgICBUaGUgd29ya2luZyBkaXJlY3Rvcnkgb3IgbnVsbCB0byB1c2UgdGhlIHdvcmtpbmcgZGlyIG9mIHRoZSBjdXJyZW50IFBIUCBwcm9jZXNzCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAgJGVudiAgICAgVGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyBvciBudWxsIHRvIHVzZSB0aGUgc2FtZSBlbnZpcm9ubWVudCBhcyB0aGUgY3VycmVudCBQSFAgcHJvY2VzcwogICAgICogQHBhcmFtIGludCAgICAgICAgICR0aW1lb3V0IFRoZSB0aW1lb3V0IGluIHNlY29uZHMKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAkb3B0aW9ucyBBbiBhcnJheSBvZiBvcHRpb25zIGZvciBwcm9jX29wZW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzY3JpcHQsICRjd2QgPSBudWxsLCBhcnJheSAkZW52ID0gbnVsbCwgJHRpbWVvdXQgPSA2MCwgYXJyYXkgJG9wdGlvbnMgPSBudWxsKQogICAgewogICAgICAgICRleGVjdXRhYmxlRmluZGVyID0gbmV3IFBocEV4ZWN1dGFibGVGaW5kZXIoKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRwaHAgPSAkZXhlY3V0YWJsZUZpbmRlci0+ZmluZChmYWxzZSkpIHsKICAgICAgICAgICAgJHBocCA9IG51bGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBocCA9IGFycmF5X21lcmdlKFskcGhwXSwgJGV4ZWN1dGFibGVGaW5kZXItPmZpbmRBcmd1bWVudHMoKSk7CiAgICAgICAgfQogICAgICAgIGlmICgncGhwZGJnJyA9PT0gXFBIUF9TQVBJKSB7CiAgICAgICAgICAgICRmaWxlID0gdGVtcG5hbShzeXNfZ2V0X3RlbXBfZGlyKCksICdkYmcnKTsKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGZpbGUsICRzY3JpcHQpOwogICAgICAgICAgICByZWdpc3Rlcl9zaHV0ZG93bl9mdW5jdGlvbigndW5saW5rJywgJGZpbGUpOwogICAgICAgICAgICAkcGhwW10gPSAkZmlsZTsKICAgICAgICAgICAgJHNjcmlwdCA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkb3B0aW9ucykgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJG9wdGlvbnMgcGFyYW1ldGVyIG9mIHRoZSAlcyBjb25zdHJ1Y3RvciBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLicsIF9fQ0xBU1NfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRwaHAsICRjd2QsICRlbnYsICRzY3JpcHQsICR0aW1lb3V0LCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwYXRoIHRvIHRoZSBQSFAgYmluYXJ5IHRvIHVzZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBocEJpbmFyeSgkcGhwKQogICAgewogICAgICAgICR0aGlzLT5zZXRDb21tYW5kTGluZSgkcGhwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0YXJ0KGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwvKiwgYXJyYXkgJGVudiA9IFtdKi8pCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5nZXRDb21tYW5kTGluZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdVbmFibGUgdG8gZmluZCB0aGUgUEhQIGV4ZWN1dGFibGUuJyk7CiAgICAgICAgfQogICAgICAgICRlbnYgPSAxIDwgXGZ1bmNfbnVtX2FyZ3MoKSA/IGZ1bmNfZ2V0X2FyZygxKSA6IG51bGw7CgogICAgICAgIHBhcmVudDo6c3RhcnQoJGNhbGxiYWNrLCAkZW52KTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3M7CgpAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMgY2xhc3MgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuNCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gVXNlIHRoZSBQcm9jZXNzIGNsYXNzIGluc3RlYWQuJywgUHJvY2Vzc0J1aWxkZXI6OmNsYXNzKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEtyaXMgV2FsbHNtaXRoIDxrcmlzQHN5bWZvbnkuY29tPgogKgogKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuNCwgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZSB0aGUgUHJvY2VzcyBjbGFzcyBpbnN0ZWFkLgogKi8KY2xhc3MgUHJvY2Vzc0J1aWxkZXIKewogICAgcHJpdmF0ZSAkYXJndW1lbnRzOwogICAgcHJpdmF0ZSAkY3dkOwogICAgcHJpdmF0ZSAkZW52ID0gW107CiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJHRpbWVvdXQgPSA2MDsKICAgIHByaXZhdGUgJG9wdGlvbnM7CiAgICBwcml2YXRlICRpbmhlcml0RW52ID0gdHJ1ZTsKICAgIHByaXZhdGUgJHByZWZpeCA9IFtdOwogICAgcHJpdmF0ZSAkb3V0cHV0RGlzYWJsZWQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkYXJndW1lbnRzIEFuIGFycmF5IG9mIGFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGFyZ3VtZW50cyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudHMgPSAkYXJndW1lbnRzOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHByb2Nlc3MgYnVpbGRlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGFyZ3VtZW50cyBBbiBhcnJheSBvZiBhcmd1bWVudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0YXRpYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZShhcnJheSAkYXJndW1lbnRzID0gW10pCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBzdGF0aWMoJGFyZ3VtZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGFuIHVuZXNjYXBlZCBhcmd1bWVudCB0byB0aGUgY29tbWFuZCBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYXJndW1lbnQgQSBjb21tYW5kIGFyZ3VtZW50CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkKCRhcmd1bWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXJndW1lbnRzW10gPSAkYXJndW1lbnQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBwcmVmaXggdG8gdGhlIGNvbW1hbmQgc3RyaW5nLgogICAgICoKICAgICAqIFRoZSBwcmVmaXggaXMgcHJlc2VydmVkIHdoZW4gcmVzZXR0aW5nIGFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRwcmVmaXggQSBjb21tYW5kIHByZWZpeCBvciBhbiBhcnJheSBvZiBjb21tYW5kIHByZWZpeGVzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZml4KCRwcmVmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZpeCA9IFxpc19hcnJheSgkcHJlZml4KSA/ICRwcmVmaXggOiBbJHByZWZpeF07CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFyZ3VtZW50cyBvZiB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBBcmd1bWVudHMgbXVzdCBub3QgYmUgZXNjYXBlZC4KICAgICAqIFByZXZpb3VzIGFyZ3VtZW50cyBhcmUgcmVtb3ZlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGFyZ3VtZW50cwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyZ3VtZW50cyhhcnJheSAkYXJndW1lbnRzKQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudHMgPSAkYXJndW1lbnRzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB3b3JraW5nIGRpcmVjdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGN3ZCBUaGUgd29ya2luZyBkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRXb3JraW5nRGlyZWN0b3J5KCRjd2QpCiAgICB7CiAgICAgICAgJHRoaXMtPmN3ZCA9ICRjd2Q7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgd2hldGhlciBlbnZpcm9ubWVudCB2YXJpYWJsZXMgd2lsbCBiZSBpbmhlcml0ZWQgb3Igbm90LgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpbmhlcml0RW52CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5oZXJpdEVudmlyb25tZW50VmFyaWFibGVzKCRpbmhlcml0RW52ID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW5oZXJpdEVudiA9ICRpbmhlcml0RW52OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGFuIGVudmlyb25tZW50IHZhcmlhYmxlLgogICAgICoKICAgICAqIFNldHRpbmcgYSB2YXJpYWJsZSBvdmVycmlkZXMgaXRzIHByZXZpb3VzIHZhbHVlLiBVc2UgYG51bGxgIHRvIHVuc2V0IGEKICAgICAqIGRlZmluZWQgZW52aXJvbm1lbnQgdmFyaWFibGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRuYW1lICBUaGUgdmFyaWFibGUgbmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICR2YWx1ZSBUaGUgdmFyaWFibGUgdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbnYoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZW52WyRuYW1lXSA9ICR2YWx1ZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIHNldCBvZiBlbnZpcm9ubWVudCB2YXJpYWJsZXMuCiAgICAgKgogICAgICogQWxyZWFkeSBleGlzdGluZyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgd2l0aCB0aGUgc2FtZSBuYW1lIHdpbGwgYmUKICAgICAqIG92ZXJyaWRkZW4gYnkgdGhlIG5ldyB2YWx1ZXMgcGFzc2VkIHRvIHRoaXMgbWV0aG9kLiBQYXNzIGBudWxsYCB0byB1bnNldAogICAgICogYSB2YXJpYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHZhcmlhYmxlcyBUaGUgdmFyaWFibGVzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRW52aXJvbm1lbnRWYXJpYWJsZXMoYXJyYXkgJHZhcmlhYmxlcykKICAgIHsKICAgICAgICAkdGhpcy0+ZW52ID0gYXJyYXlfcmVwbGFjZSgkdGhpcy0+ZW52LCAkdmFyaWFibGVzKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW5wdXQgb2YgdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlfHN0cmluZ3xpbnR8ZmxvYXR8Ym9vbHxcVHJhdmVyc2FibGV8bnVsbCAkaW5wdXQgVGhlIGlucHV0IGNvbnRlbnQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSW4gY2FzZSB0aGUgYXJndW1lbnQgaXMgaW52YWxpZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5wdXQoJGlucHV0KQogICAgewogICAgICAgICR0aGlzLT5pbnB1dCA9IFByb2Nlc3NVdGlsczo6dmFsaWRhdGVJbnB1dChfX01FVEhPRF9fLCAkaW5wdXQpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9jZXNzIHRpbWVvdXQuCiAgICAgKgogICAgICogVG8gZGlzYWJsZSB0aGUgdGltZW91dCwgc2V0IHRoaXMgdmFsdWUgdG8gbnVsbC4KICAgICAqCiAgICAgKiBAcGFyYW0gZmxvYXR8bnVsbCAkdGltZW91dAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGltZW91dCgkdGltZW91dCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRpbWVvdXQpIHsKICAgICAgICAgICAgJHRoaXMtPnRpbWVvdXQgPSBudWxsOwoKICAgICAgICAgICAgcmV0dXJuICR0aGlzOwogICAgICAgIH0KCiAgICAgICAgJHRpbWVvdXQgPSAoZmxvYXQpICR0aW1lb3V0OwoKICAgICAgICBpZiAoJHRpbWVvdXQgPCAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSB0aW1lb3V0IHZhbHVlIG11c3QgYmUgYSB2YWxpZCBwb3NpdGl2ZSBpbnRlZ2VyIG9yIGZsb2F0IG51bWJlci4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT50aW1lb3V0ID0gJHRpbWVvdXQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBwcm9jX29wZW4gb3B0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIFRoZSBvcHRpb24gbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUgVGhlIG9wdGlvbiB2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbigkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT5vcHRpb25zWyRuYW1lXSA9ICR2YWx1ZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRGlzYWJsZXMgZmV0Y2hpbmcgb3V0cHV0IGFuZCBlcnJvciBvdXRwdXQgZnJvbSB0aGUgdW5kZXJseWluZyBwcm9jZXNzLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc2FibGVPdXRwdXQoKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXREaXNhYmxlZCA9IHRydWU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZXMgZmV0Y2hpbmcgb3V0cHV0IGFuZCBlcnJvciBvdXRwdXQgZnJvbSB0aGUgdW5kZXJseWluZyBwcm9jZXNzLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZU91dHB1dCgpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dERpc2FibGVkID0gZmFsc2U7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBQcm9jZXNzIGluc3RhbmNlIGFuZCByZXR1cm5zIGl0LgogICAgICoKICAgICAqIEByZXR1cm4gUHJvY2VzcwogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gSW4gY2FzZSBubyBhcmd1bWVudHMgaGF2ZSBiZWVuIHByb3ZpZGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9jZXNzKCkKICAgIHsKICAgICAgICBpZiAoMCA9PT0gXGNvdW50KCR0aGlzLT5wcmVmaXgpICYmIDAgPT09IFxjb3VudCgkdGhpcy0+YXJndW1lbnRzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1lvdSBtdXN0IGFkZCgpIGNvbW1hbmQgYXJndW1lbnRzIGJlZm9yZSBjYWxsaW5nIGdldFByb2Nlc3MoKS4nKTsKICAgICAgICB9CgogICAgICAgICRhcmd1bWVudHMgPSBhcnJheV9tZXJnZSgkdGhpcy0+cHJlZml4LCAkdGhpcy0+YXJndW1lbnRzKTsKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzKCRhcmd1bWVudHMsICR0aGlzLT5jd2QsICR0aGlzLT5lbnYsICR0aGlzLT5pbnB1dCwgJHRoaXMtPnRpbWVvdXQsICR0aGlzLT5vcHRpb25zKTsKICAgICAgICAvLyB0byBwcmVzZXJ2ZSB0aGUgQkMgd2l0aCBzeW1mb255IDwzLjMsIHdlIGNvbnZlcnQgdGhlIGFycmF5IHN0cnVjdHVyZQogICAgICAgIC8vIHRvIGEgc3RyaW5nIHN0cnVjdHVyZSB0byBhdm9pZCB0aGUgcHJlZml4aW5nIHdpdGggdGhlIGV4ZWMgY29tbWFuZAogICAgICAgICRwcm9jZXNzLT5zZXRDb21tYW5kTGluZSgkcHJvY2Vzcy0+Z2V0Q29tbWFuZExpbmUoKSk7CgogICAgICAgIGlmICgkdGhpcy0+aW5oZXJpdEVudikgewogICAgICAgICAgICAkcHJvY2Vzcy0+aW5oZXJpdEVudmlyb25tZW50VmFyaWFibGVzKCk7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+b3V0cHV0RGlzYWJsZWQpIHsKICAgICAgICAgICAgJHByb2Nlc3MtPmRpc2FibGVPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvY2VzczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3M7CgovKioKICogQW4gZXhlY3V0YWJsZSBmaW5kZXIgc3BlY2lmaWNhbGx5IGRlc2lnbmVkIGZvciB0aGUgUEhQIGV4ZWN1dGFibGUuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgUGhwRXhlY3V0YWJsZUZpbmRlcgp7CiAgICBwcml2YXRlICRleGVjdXRhYmxlRmluZGVyOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGFibGVGaW5kZXIgPSBuZXcgRXhlY3V0YWJsZUZpbmRlcigpOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgVGhlIFBIUCBleGVjdXRhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpbmNsdWRlQXJncyBXaGV0aGVyIG9yIG5vdCBpbmNsdWRlIGNvbW1hbmQgYXJndW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UgVGhlIFBIUCBleGVjdXRhYmxlIHBhdGggb3IgZmFsc2UgaWYgaXQgY2Fubm90IGJlIGZvdW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kKCRpbmNsdWRlQXJncyA9IHRydWUpCiAgICB7CiAgICAgICAgJGFyZ3MgPSAkdGhpcy0+ZmluZEFyZ3VtZW50cygpOwogICAgICAgICRhcmdzID0gJGluY2x1ZGVBcmdzICYmICRhcmdzID8gJyAnLmltcGxvZGUoJyAnLCAkYXJncykgOiAnJzsKCiAgICAgICAgLy8gSEhWTSBzdXBwb3J0CiAgICAgICAgaWYgKFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICByZXR1cm4gKGdldGVudignUEhQX0JJTkFSWScpID86IFxQSFBfQklOQVJZKS4kYXJnczsKICAgICAgICB9CgogICAgICAgIC8vIFBIUF9CSU5BUlkgcmV0dXJuIHRoZSBjdXJyZW50IHNhcGkgZXhlY3V0YWJsZQogICAgICAgIGlmIChcUEhQX0JJTkFSWSAmJiBcaW5fYXJyYXkoXFBIUF9TQVBJLCBbJ2NsaScsICdjbGktc2VydmVyJywgJ3BocGRiZyddLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gXFBIUF9CSU5BUlkuJGFyZ3M7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBocCA9IGdldGVudignUEhQX1BBVEgnKSkgewogICAgICAgICAgICBpZiAoIUBpc19leGVjdXRhYmxlKCRwaHApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcGhwOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwaHAgPSBnZXRlbnYoJ1BIUF9QRUFSX1BIUF9CSU4nKSkgewogICAgICAgICAgICBpZiAoQGlzX2V4ZWN1dGFibGUoJHBocCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcGhwOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoQGlzX2V4ZWN1dGFibGUoJHBocCA9IFxQSFBfQklORElSLignXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUiA/ICdcXHBocC5leGUnIDogJy9waHAnKSkpIHsKICAgICAgICAgICAgcmV0dXJuICRwaHA7CiAgICAgICAgfQoKICAgICAgICAkZGlycyA9IFtcUEhQX0JJTkRJUl07CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRkaXJzW10gPSAnQzpceGFtcHBccGhwXFwnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5leGVjdXRhYmxlRmluZGVyLT5maW5kKCdwaHAnLCBmYWxzZSwgJGRpcnMpOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgdGhlIFBIUCBleGVjdXRhYmxlIGFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBQSFAgZXhlY3V0YWJsZSBhcmd1bWVudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRBcmd1bWVudHMoKQogICAgewogICAgICAgICRhcmd1bWVudHMgPSBbXTsKCiAgICAgICAgaWYgKFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICAkYXJndW1lbnRzW10gPSAnLS1waHAnOwogICAgICAgIH0gZWxzZWlmICgncGhwZGJnJyA9PT0gXFBIUF9TQVBJKSB7CiAgICAgICAgICAgICRhcmd1bWVudHNbXSA9ICctcXJyJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYXJndW1lbnRzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb247CgovKioKICogSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGZvciB0aGUgUHJvY2VzcyBDb21wb25lbnQuCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqLwpjbGFzcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uOwoKLyoqCiAqIExvZ2ljRXhjZXB0aW9uIGZvciB0aGUgUHJvY2VzcyBDb21wb25lbnQuCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqLwpjbGFzcyBMb2dpY0V4Y2VwdGlvbiBleHRlbmRzIFxMb2dpY0V4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvbjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3M7CgovKioKICogRXhjZXB0aW9uIGZvciBmYWlsZWQgcHJvY2Vzc2VzLgogKgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgUHJvY2Vzc0ZhaWxlZEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KewogICAgcHJpdmF0ZSAkcHJvY2VzczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUHJvY2VzcyAkcHJvY2VzcykKICAgIHsKICAgICAgICBpZiAoJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0V4cGVjdGVkIGEgZmFpbGVkIHByb2Nlc3MsIGJ1dCB0aGUgZ2l2ZW4gcHJvY2VzcyB3YXMgc3VjY2Vzc2Z1bC4nKTsKICAgICAgICB9CgogICAgICAgICRlcnJvciA9IHNwcmludGYoJ1RoZSBjb21tYW5kICIlcyIgZmFpbGVkLicuIlxuXG5FeGl0IENvZGU6ICVzKCVzKVxuXG5Xb3JraW5nIGRpcmVjdG9yeTogJXMiLAogICAgICAgICAgICAkcHJvY2Vzcy0+Z2V0Q29tbWFuZExpbmUoKSwKICAgICAgICAgICAgJHByb2Nlc3MtPmdldEV4aXRDb2RlKCksCiAgICAgICAgICAgICRwcm9jZXNzLT5nZXRFeGl0Q29kZVRleHQoKSwKICAgICAgICAgICAgJHByb2Nlc3MtPmdldFdvcmtpbmdEaXJlY3RvcnkoKQogICAgICAgICk7CgogICAgICAgIGlmICghJHByb2Nlc3MtPmlzT3V0cHV0RGlzYWJsZWQoKSkgewogICAgICAgICAgICAkZXJyb3IgLj0gc3ByaW50ZigiXG5cbk91dHB1dDpcbj09PT09PT09PT09PT09PT1cbiVzXG5cbkVycm9yIE91dHB1dDpcbj09PT09PT09PT09PT09PT1cbiVzIiwKICAgICAgICAgICAgICAgICRwcm9jZXNzLT5nZXRPdXRwdXQoKSwKICAgICAgICAgICAgICAgICRwcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRlcnJvcik7CgogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb2Nlc3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2VzczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uOwoKLyoqCiAqIE1hcmtlciBJbnRlcmZhY2UgZm9yIHRoZSBQcm9jZXNzIENvbXBvbmVudC4KICoKICogQGF1dGhvciBKb2hhbm5lcyBNLiBTY2htaXR0IDxzY2htaXR0am9oQGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb247Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzOwoKLyoqCiAqIEV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGEgcHJvY2VzcyB0aW1lcyBvdXQuCiAqCiAqIEBhdXRob3IgSm9oYW5uZXMgTS4gU2NobWl0dCA8c2NobWl0dGpvaEBnbWFpbC5jb20+CiAqLwpjbGFzcyBQcm9jZXNzVGltZWRPdXRFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uCnsKICAgIGNvbnN0IFRZUEVfR0VORVJBTCA9IDE7CiAgICBjb25zdCBUWVBFX0lETEUgPSAyOwoKICAgIHByaXZhdGUgJHByb2Nlc3M7CiAgICBwcml2YXRlICR0aW1lb3V0VHlwZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUHJvY2VzcyAkcHJvY2VzcywgJHRpbWVvdXRUeXBlKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3M7CiAgICAgICAgJHRoaXMtPnRpbWVvdXRUeXBlID0gJHRpbWVvdXRUeXBlOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KHNwcmludGYoCiAgICAgICAgICAgICdUaGUgcHJvY2VzcyAiJXMiIGV4Y2VlZGVkIHRoZSB0aW1lb3V0IG9mICVzIHNlY29uZHMuJywKICAgICAgICAgICAgJHByb2Nlc3MtPmdldENvbW1hbmRMaW5lKCksCiAgICAgICAgICAgICR0aGlzLT5nZXRFeGNlZWRlZFRpbWVvdXQoKQogICAgICAgICkpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9jZXNzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzR2VuZXJhbFRpbWVvdXQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpUWVBFX0dFTkVSQUwgPT09ICR0aGlzLT50aW1lb3V0VHlwZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJZGxlVGltZW91dCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OlRZUEVfSURMRSA9PT0gJHRoaXMtPnRpbWVvdXRUeXBlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeGNlZWRlZFRpbWVvdXQoKQogICAgewogICAgICAgIHN3aXRjaCAoJHRoaXMtPnRpbWVvdXRUeXBlKSB7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6VFlQRV9HRU5FUkFMOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzLT5nZXRUaW1lb3V0KCk7CgogICAgICAgICAgICBjYXNlIHNlbGY6OlRZUEVfSURMRToKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzcy0+Z2V0SWRsZVRpbWVvdXQoKTsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKHNwcmludGYoJ1Vua25vd24gdGltZW91dCB0eXBlICIlZCIuJywgJHRoaXMtPnRpbWVvdXRUeXBlKSk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb247CgovKioKICogUnVudGltZUV4Y2VwdGlvbiBmb3IgdGhlIFByb2Nlc3MgQ29tcG9uZW50LgogKgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgUnVudGltZUV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUGlwZXM7CgovKioKICogUGlwZXNJbnRlcmZhY2UgbWFuYWdlcyBkZXNjcmlwdG9ycyBhbmQgcGlwZXMgZm9yIHRoZSB1c2Ugb2YgcHJvY19vcGVuLgogKgogKiBAYXV0aG9yIFJvbWFpbiBOZXV0cm9uIDxpbXByZWNAZ21haWwuY29tPgogKgogKiBAaW50ZXJuYWwKICovCmludGVyZmFjZSBQaXBlc0ludGVyZmFjZQp7CiAgICBjb25zdCBDSFVOS19TSVpFID0gMTYzODQ7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGRlc2NyaXB0b3JzIGZvciB0aGUgdXNlIG9mIHByb2Nfb3Blbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdG9ycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBmaWxlbmFtZXMgaW5kZXhlZCBieSB0aGVpciByZWxhdGVkIHN0cmVhbSBpbiBjYXNlIHRoZXNlIHBpcGVzIHVzZSB0ZW1wb3JhcnkgZmlsZXMuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZXMoKTsKCiAgICAvKioKICAgICAqIFJlYWRzIGRhdGEgaW4gZmlsZSBoYW5kbGVzIGFuZCBwaXBlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkYmxvY2tpbmcgV2hldGhlciB0byB1c2UgYmxvY2tpbmcgY2FsbHMgb3Igbm90CiAgICAgKiBAcGFyYW0gYm9vbCAkY2xvc2UgICAgV2hldGhlciB0byBjbG9zZSBwaXBlcyBpZiB0aGV5J3ZlIHJlYWNoZWQgRU9GCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXSBBbiBhcnJheSBvZiByZWFkIGRhdGEgaW5kZXhlZCBieSB0aGVpciBmZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZEFuZFdyaXRlKCRibG9ja2luZywgJGNsb3NlID0gZmFsc2UpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBpZiB0aGUgY3VycmVudCBzdGF0ZSBoYXMgb3BlbiBmaWxlIGhhbmRsZXMgb3IgcGlwZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmVPcGVuKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGlmIHBpcGVzIGFyZSBhYmxlIHRvIHJlYWQgb3V0cHV0LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGF2ZVJlYWRTdXBwb3J0KCk7CgogICAgLyoqCiAgICAgKiBDbG9zZXMgZmlsZSBoYW5kbGVzIGFuZCBwaXBlcy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsb3NlKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFBpcGVzOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBVbml4UGlwZXMgaW1wbGVtZW50YXRpb24gdXNlcyB1bml4IHBpcGVzIGFzIGhhbmRsZXMuCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgVW5peFBpcGVzIGV4dGVuZHMgQWJzdHJhY3RQaXBlcwp7CiAgICBwcml2YXRlICR0dHlNb2RlOwogICAgcHJpdmF0ZSAkcHR5TW9kZTsKICAgIHByaXZhdGUgJGhhdmVSZWFkU3VwcG9ydDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHR0eU1vZGUsICRwdHlNb2RlLCAkaW5wdXQsICRoYXZlUmVhZFN1cHBvcnQpCiAgICB7CiAgICAgICAgJHRoaXMtPnR0eU1vZGUgPSAoYm9vbCkgJHR0eU1vZGU7CiAgICAgICAgJHRoaXMtPnB0eU1vZGUgPSAoYm9vbCkgJHB0eU1vZGU7CiAgICAgICAgJHRoaXMtPmhhdmVSZWFkU3VwcG9ydCA9IChib29sKSAkaGF2ZVJlYWRTdXBwb3J0OwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpbnB1dCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fZGVzdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzLT5jbG9zZSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRvcnMoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhdmVSZWFkU3VwcG9ydCkgewogICAgICAgICAgICAkbnVsbHN0cmVhbSA9IGZvcGVuKCcvZGV2L251bGwnLCAnYycpOwoKICAgICAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgICAgIFsncGlwZScsICdyJ10sCiAgICAgICAgICAgICAgICAkbnVsbHN0cmVhbSwKICAgICAgICAgICAgICAgICRudWxsc3RyZWFtLAogICAgICAgICAgICBdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT50dHlNb2RlKSB7CiAgICAgICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICAgICBbJ2ZpbGUnLCAnL2Rldi90dHknLCAnciddLAogICAgICAgICAgICAgICAgWydmaWxlJywgJy9kZXYvdHR5JywgJ3cnXSwKICAgICAgICAgICAgICAgIFsnZmlsZScsICcvZGV2L3R0eScsICd3J10sCiAgICAgICAgICAgIF07CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnB0eU1vZGUgJiYgUHJvY2Vzczo6aXNQdHlTdXBwb3J0ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAgICAgWydwdHknXSwKICAgICAgICAgICAgICAgIFsncHR5J10sCiAgICAgICAgICAgICAgICBbJ3B0eSddLAogICAgICAgICAgICBdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgWydwaXBlJywgJ3InXSwKICAgICAgICAgICAgWydwaXBlJywgJ3cnXSwgLy8gc3Rkb3V0CiAgICAgICAgICAgIFsncGlwZScsICd3J10sIC8vIHN0ZGVycgogICAgICAgIF07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlcygpCiAgICB7CiAgICAgICAgcmV0dXJuIFtdOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZEFuZFdyaXRlKCRibG9ja2luZywgJGNsb3NlID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnVuYmxvY2soKTsKICAgICAgICAkdyA9ICR0aGlzLT53cml0ZSgpOwoKICAgICAgICAkcmVhZCA9ICRlID0gW107CiAgICAgICAgJHIgPSAkdGhpcy0+cGlwZXM7CiAgICAgICAgdW5zZXQoJHJbMF0pOwoKICAgICAgICAvLyBsZXQncyBoYXZlIGEgbG9vayBpZiBzb21ldGhpbmcgY2hhbmdlZCBpbiBzdHJlYW1zCiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoWyR0aGlzLCAnaGFuZGxlRXJyb3InXSk7CiAgICAgICAgaWYgKCgkciB8fCAkdykgJiYgZmFsc2UgPT09IHN0cmVhbV9zZWxlY3QoJHIsICR3LCAkZSwgMCwgJGJsb2NraW5nID8gUHJvY2Vzczo6VElNRU9VVF9QUkVDSVNJT04gKiAxRTYgOiAwKSkgewogICAgICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKICAgICAgICAgICAgLy8gaWYgYSBzeXN0ZW0gY2FsbCBoYXMgYmVlbiBpbnRlcnJ1cHRlZCwgZm9yZ2V0IGFib3V0IGl0LCBsZXQncyB0cnkgYWdhaW4KICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBhbiBlcnJvciBvY2N1cnJlZCwgbGV0J3MgcmVzZXQgcGlwZXMKICAgICAgICAgICAgaWYgKCEkdGhpcy0+aGFzU3lzdGVtQ2FsbEJlZW5JbnRlcnJ1cHRlZCgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGlwZXMgPSBbXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZWFkOwogICAgICAgIH0KICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKCiAgICAgICAgZm9yZWFjaCAoJHIgYXMgJHBpcGUpIHsKICAgICAgICAgICAgLy8gcHJpb3IgUEhQIDUuNCB0aGUgYXJyYXkgcGFzc2VkIHRvIHN0cmVhbV9zZWxlY3QgaXMgbW9kaWZpZWQgYW5kCiAgICAgICAgICAgIC8vIGxvc2Uga2V5IGFzc29jaWF0aW9uLCB3ZSBoYXZlIHRvIGZpbmQgYmFjayB0aGUga2V5CiAgICAgICAgICAgICRyZWFkWyR0eXBlID0gYXJyYXlfc2VhcmNoKCRwaXBlLCAkdGhpcy0+cGlwZXMsIHRydWUpXSA9ICcnOwoKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgJGRhdGEgPSBAZnJlYWQoJHBpcGUsIHNlbGY6OkNIVU5LX1NJWkUpOwogICAgICAgICAgICAgICAgJHJlYWRbJHR5cGVdIC49ICRkYXRhOwogICAgICAgICAgICB9IHdoaWxlIChpc3NldCgkZGF0YVswXSkgJiYgKCRjbG9zZSB8fCBpc3NldCgkZGF0YVtzZWxmOjpDSFVOS19TSVpFIC0gMV0pKSk7CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRyZWFkWyR0eXBlXVswXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRyZWFkWyR0eXBlXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY2xvc2UgJiYgZmVvZigkcGlwZSkpIHsKICAgICAgICAgICAgICAgIGZjbG9zZSgkcGlwZSk7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+cGlwZXNbJHR5cGVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZWFkOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGF2ZVJlYWRTdXBwb3J0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhhdmVSZWFkU3VwcG9ydDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyZU9wZW4oKQogICAgewogICAgICAgIHJldHVybiAoYm9vbCkgJHRoaXMtPnBpcGVzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaXBlczsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxSdW50aW1lRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzOwoKLyoqCiAqIFdpbmRvd3NQaXBlcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRlbXBvcmFyeSBmaWxlcyBhcyBoYW5kbGVzLgogKgogKiBAc2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzUxODAwCiAqIEBzZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvNjU2NTAKICoKICogQGF1dGhvciBSb21haW4gTmV1dHJvbiA8aW1wcmVjQGdtYWlsLmNvbT4KICoKICogQGludGVybmFsCiAqLwpjbGFzcyBXaW5kb3dzUGlwZXMgZXh0ZW5kcyBBYnN0cmFjdFBpcGVzCnsKICAgIHByaXZhdGUgJGZpbGVzID0gW107CiAgICBwcml2YXRlICRmaWxlSGFuZGxlcyA9IFtdOwogICAgcHJpdmF0ZSAkbG9ja0hhbmRsZXMgPSBbXTsKICAgIHByaXZhdGUgJHJlYWRCeXRlcyA9IFsKICAgICAgICBQcm9jZXNzOjpTVERPVVQgPT4gMCwKICAgICAgICBQcm9jZXNzOjpTVERFUlIgPT4gMCwKICAgIF07CiAgICBwcml2YXRlICRoYXZlUmVhZFN1cHBvcnQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRpbnB1dCwgJGhhdmVSZWFkU3VwcG9ydCkKICAgIHsKICAgICAgICAkdGhpcy0+aGF2ZVJlYWRTdXBwb3J0ID0gKGJvb2wpICRoYXZlUmVhZFN1cHBvcnQ7CgogICAgICAgIGlmICgkdGhpcy0+aGF2ZVJlYWRTdXBwb3J0KSB7CiAgICAgICAgICAgIC8vIEZpeCBmb3IgUEhQIGJ1ZyAjNTE4MDA6IHJlYWRpbmcgZnJvbSBTVERPVVQgcGlwZSBoYW5ncyBmb3JldmVyIG9uIFdpbmRvd3MgaWYgdGhlIG91dHB1dCBpcyB0b28gYmlnLgogICAgICAgICAgICAvLyBXb3JrYXJvdW5kIGZvciB0aGlzIHByb2JsZW0gaXMgdG8gdXNlIHRlbXBvcmFyeSBmaWxlcyBpbnN0ZWFkIG9mIHBpcGVzIG9uIFdpbmRvd3MgcGxhdGZvcm0uCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIEBzZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvNTE4MDAKICAgICAgICAgICAgJHBpcGVzID0gWwogICAgICAgICAgICAgICAgUHJvY2Vzczo6U1RET1VUID0+IFByb2Nlc3M6Ok9VVCwKICAgICAgICAgICAgICAgIFByb2Nlc3M6OlNUREVSUiA9PiBQcm9jZXNzOjpFUlIsCiAgICAgICAgICAgIF07CiAgICAgICAgICAgICR0bXBEaXIgPSBzeXNfZ2V0X3RlbXBfZGlyKCk7CiAgICAgICAgICAgICRsYXN0RXJyb3IgPSAndW5rbm93biByZWFzb24nOwogICAgICAgICAgICBzZXRfZXJyb3JfaGFuZGxlcihmdW5jdGlvbiAoJHR5cGUsICRtc2cpIHVzZSAoJiRsYXN0RXJyb3IpIHsgJGxhc3RFcnJvciA9ICRtc2c7IH0pOwogICAgICAgICAgICBmb3IgKCRpID0gMDs7ICsrJGkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwaXBlcyBhcyAkcGlwZSA9PiAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICRmaWxlID0gc3ByaW50ZignJXNcXHNmX3Byb2NfJTAyWC4lcycsICR0bXBEaXIsICRpLCAkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmICghJGggPSBmb3BlbigkZmlsZS4nLmxvY2snLCAndycpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZS4nLmxvY2snKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ0EgdGVtcG9yYXJ5IGZpbGUgY291bGQgbm90IGJlIG9wZW5lZCB0byB3cml0ZSB0aGUgcHJvY2VzcyBvdXRwdXQ6ICcuJGxhc3RFcnJvcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghZmxvY2soJGgsIFxMT0NLX0VYIHwgXExPQ0tfTkIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+bG9ja0hhbmRsZXNbJHBpcGVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmbG9jaygkdGhpcy0+bG9ja0hhbmRsZXNbJHBpcGVdLCBcTE9DS19VTik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+bG9ja0hhbmRsZXNbJHBpcGVdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmxvY2tIYW5kbGVzWyRwaXBlXSA9ICRoOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIWZjbG9zZShmb3BlbigkZmlsZSwgJ3cnKSkgfHwgISRoID0gZm9wZW4oJGZpbGUsICdyJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmxvY2soJHRoaXMtPmxvY2tIYW5kbGVzWyRwaXBlXSwgXExPQ0tfVU4pOwogICAgICAgICAgICAgICAgICAgICAgICBmY2xvc2UoJHRoaXMtPmxvY2tIYW5kbGVzWyRwaXBlXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5sb2NrSGFuZGxlc1skcGlwZV0pOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZUhhbmRsZXNbJHBpcGVdID0gJGg7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzWyRwaXBlXSA9ICRmaWxlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpbnB1dCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fZGVzdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzLT5jbG9zZSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRvcnMoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhdmVSZWFkU3VwcG9ydCkgewogICAgICAgICAgICAkbnVsbHN0cmVhbSA9IGZvcGVuKCdOVUwnLCAnYycpOwoKICAgICAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgICAgIFsncGlwZScsICdyJ10sCiAgICAgICAgICAgICAgICAkbnVsbHN0cmVhbSwKICAgICAgICAgICAgICAgICRudWxsc3RyZWFtLAogICAgICAgICAgICBdOwogICAgICAgIH0KCiAgICAgICAgLy8gV2UncmUgbm90IHVzaW5nIHBpcGUgb24gV2luZG93cyBwbGF0Zm9ybSBhcyBpdCBoYW5ncyAoaHR0cHM6Ly9idWdzLnBocC5uZXQvNTE4MDApCiAgICAgICAgLy8gV2UncmUgbm90IHVzaW5nIGZpbGUgaGFuZGxlcyBhcyBpdCBjYW4gcHJvZHVjZSBjb3JydXB0ZWQgb3V0cHV0IGh0dHBzOi8vYnVncy5waHAubmV0LzY1NjUwCiAgICAgICAgLy8gU28gd2UgcmVkaXJlY3Qgb3V0cHV0IHdpdGhpbiB0aGUgY29tbWFuZGxpbmUgYW5kIHBhc3MgdGhlIG51bCBkZXZpY2UgdG8gdGhlIHByb2Nlc3MKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICBbJ3BpcGUnLCAnciddLAogICAgICAgICAgICBbJ2ZpbGUnLCAnTlVMJywgJ3cnXSwKICAgICAgICAgICAgWydmaWxlJywgJ05VTCcsICd3J10sCiAgICAgICAgXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZpbGVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZEFuZFdyaXRlKCRibG9ja2luZywgJGNsb3NlID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnVuYmxvY2soKTsKICAgICAgICAkdyA9ICR0aGlzLT53cml0ZSgpOwogICAgICAgICRyZWFkID0gJHIgPSAkZSA9IFtdOwoKICAgICAgICBpZiAoJGJsb2NraW5nKSB7CiAgICAgICAgICAgIGlmICgkdykgewogICAgICAgICAgICAgICAgQHN0cmVhbV9zZWxlY3QoJHIsICR3LCAkZSwgMCwgUHJvY2Vzczo6VElNRU9VVF9QUkVDSVNJT04gKiAxRTYpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmZpbGVIYW5kbGVzKSB7CiAgICAgICAgICAgICAgICB1c2xlZXAoUHJvY2Vzczo6VElNRU9VVF9QUkVDSVNJT04gKiAxRTYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5maWxlSGFuZGxlcyBhcyAkdHlwZSA9PiAkZmlsZUhhbmRsZSkgewogICAgICAgICAgICAkZGF0YSA9IHN0cmVhbV9nZXRfY29udGVudHMoJGZpbGVIYW5kbGUsIC0xLCAkdGhpcy0+cmVhZEJ5dGVzWyR0eXBlXSk7CgogICAgICAgICAgICBpZiAoaXNzZXQoJGRhdGFbMF0pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVhZEJ5dGVzWyR0eXBlXSArPSBcc3RybGVuKCRkYXRhKTsKICAgICAgICAgICAgICAgICRyZWFkWyR0eXBlXSA9ICRkYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkY2xvc2UpIHsKICAgICAgICAgICAgICAgIGZ0cnVuY2F0ZSgkZmlsZUhhbmRsZSwgMCk7CiAgICAgICAgICAgICAgICBmY2xvc2UoJGZpbGVIYW5kbGUpOwogICAgICAgICAgICAgICAgZmxvY2soJHRoaXMtPmxvY2tIYW5kbGVzWyR0eXBlXSwgXExPQ0tfVU4pOwogICAgICAgICAgICAgICAgZmNsb3NlKCR0aGlzLT5sb2NrSGFuZGxlc1skdHlwZV0pOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmZpbGVIYW5kbGVzWyR0eXBlXSwgJHRoaXMtPmxvY2tIYW5kbGVzWyR0eXBlXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVhZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhdmVSZWFkU3VwcG9ydCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXZlUmVhZFN1cHBvcnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmVPcGVuKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBpcGVzICYmICR0aGlzLT5maWxlSGFuZGxlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsb3NlKCkKICAgIHsKICAgICAgICBwYXJlbnQ6OmNsb3NlKCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbGVIYW5kbGVzIGFzICR0eXBlID0+ICRoYW5kbGUpIHsKICAgICAgICAgICAgZnRydW5jYXRlKCRoYW5kbGUsIDApOwogICAgICAgICAgICBmY2xvc2UoJGhhbmRsZSk7CiAgICAgICAgICAgIGZsb2NrKCR0aGlzLT5sb2NrSGFuZGxlc1skdHlwZV0sIFxMT0NLX1VOKTsKICAgICAgICAgICAgZmNsb3NlKCR0aGlzLT5sb2NrSGFuZGxlc1skdHlwZV0pOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZmlsZUhhbmRsZXMgPSAkdGhpcy0+bG9ja0hhbmRsZXMgPSBbXTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUGlwZXM7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RQaXBlcyBpbXBsZW1lbnRzIFBpcGVzSW50ZXJmYWNlCnsKICAgIHB1YmxpYyAkcGlwZXMgPSBbXTsKCiAgICBwcml2YXRlICRpbnB1dEJ1ZmZlciA9ICcnOwogICAgcHJpdmF0ZSAkaW5wdXQ7CiAgICBwcml2YXRlICRibG9ja2VkID0gdHJ1ZTsKICAgIHByaXZhdGUgJGxhc3RFcnJvcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSByZXNvdXJjZXxzdHJpbmd8aW50fGZsb2F0fGJvb2x8XEl0ZXJhdG9yfG51bGwgJGlucHV0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5wdXQpCiAgICB7CiAgICAgICAgaWYgKFxpc19yZXNvdXJjZSgkaW5wdXQpIHx8ICRpbnB1dCBpbnN0YW5jZW9mIFxJdGVyYXRvcikgewogICAgICAgICAgICAkdGhpcy0+aW5wdXQgPSAkaW5wdXQ7CiAgICAgICAgfSBlbHNlaWYgKFxpc19zdHJpbmcoJGlucHV0KSkgewogICAgICAgICAgICAkdGhpcy0+aW5wdXRCdWZmZXIgPSAkaW5wdXQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0QnVmZmVyID0gKHN0cmluZykgJGlucHV0OwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsb3NlKCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGlwZXMgYXMgJHBpcGUpIHsKICAgICAgICAgICAgZmNsb3NlKCRwaXBlKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnBpcGVzID0gW107CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBzeXN0ZW0gY2FsbCBoYXMgYmVlbiBpbnRlcnJ1cHRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc1N5c3RlbUNhbGxCZWVuSW50ZXJydXB0ZWQoKQogICAgewogICAgICAgICRsYXN0RXJyb3IgPSAkdGhpcy0+bGFzdEVycm9yOwogICAgICAgICR0aGlzLT5sYXN0RXJyb3IgPSBudWxsOwoKICAgICAgICAvLyBzdHJlYW1fc2VsZWN0IHJldHVybnMgZmFsc2Ugd2hlbiB0aGUgYHNlbGVjdGAgc3lzdGVtIGNhbGwgaXMgaW50ZXJydXB0ZWQgYnkgYW4gaW5jb21pbmcgc2lnbmFsCiAgICAgICAgcmV0dXJuIG51bGwgIT09ICRsYXN0RXJyb3IgJiYgZmFsc2UgIT09IHN0cmlwb3MoJGxhc3RFcnJvciwgJ2ludGVycnVwdGVkIHN5c3RlbSBjYWxsJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBVbmJsb2NrcyBzdHJlYW1zLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdW5ibG9jaygpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+YmxvY2tlZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGlwZXMgYXMgJHBpcGUpIHsKICAgICAgICAgICAgc3RyZWFtX3NldF9ibG9ja2luZygkcGlwZSwgMCk7CiAgICAgICAgfQogICAgICAgIGlmIChcaXNfcmVzb3VyY2UoJHRoaXMtPmlucHV0KSkgewogICAgICAgICAgICBzdHJlYW1fc2V0X2Jsb2NraW5nKCR0aGlzLT5pbnB1dCwgMCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YmxvY2tlZCA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogV3JpdGVzIGlucHV0IHRvIHN0ZGluLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gYW4gaW5wdXQgaXRlcmF0b3IgeWllbGRzIGEgbm9uIHN1cHBvcnRlZCB2YWx1ZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnBpcGVzWzBdKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJGlucHV0ID0gJHRoaXMtPmlucHV0OwoKICAgICAgICBpZiAoJGlucHV0IGluc3RhbmNlb2YgXEl0ZXJhdG9yKSB7CiAgICAgICAgICAgIGlmICghJGlucHV0LT52YWxpZCgpKSB7CiAgICAgICAgICAgICAgICAkaW5wdXQgPSBudWxsOwogICAgICAgICAgICB9IGVsc2VpZiAoXGlzX3Jlc291cmNlKCRpbnB1dCA9ICRpbnB1dC0+Y3VycmVudCgpKSkgewogICAgICAgICAgICAgICAgc3RyZWFtX3NldF9ibG9ja2luZygkaW5wdXQsIDApOwogICAgICAgICAgICB9IGVsc2VpZiAoIWlzc2V0KCR0aGlzLT5pbnB1dEJ1ZmZlclswXSkpIHsKICAgICAgICAgICAgICAgIGlmICghXGlzX3N0cmluZygkaW5wdXQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19zY2FsYXIoJGlucHV0KSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJyIlcyIgeWllbGRlZCBhIHZhbHVlIG9mIHR5cGUgIiVzIiwgYnV0IG9ubHkgc2NhbGFycyBhbmQgc3RyZWFtIHJlc291cmNlcyBhcmUgc3VwcG9ydGVkLicsIFxnZXRfY2xhc3MoJHRoaXMtPmlucHV0KSwgXGdldHR5cGUoJGlucHV0KSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkaW5wdXQgPSAoc3RyaW5nKSAkaW5wdXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5wdXRCdWZmZXIgPSAkaW5wdXQ7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5wdXQtPm5leHQoKTsKICAgICAgICAgICAgICAgICRpbnB1dCA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkaW5wdXQgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkciA9ICRlID0gW107CiAgICAgICAgJHcgPSBbJHRoaXMtPnBpcGVzWzBdXTsKCiAgICAgICAgLy8gbGV0J3MgaGF2ZSBhIGxvb2sgaWYgc29tZXRoaW5nIGNoYW5nZWQgaW4gc3RyZWFtcwogICAgICAgIGlmIChmYWxzZSA9PT0gQHN0cmVhbV9zZWxlY3QoJHIsICR3LCAkZSwgMCwgMCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdyBhcyAkc3RkaW4pIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5pbnB1dEJ1ZmZlclswXSkpIHsKICAgICAgICAgICAgICAgICR3cml0dGVuID0gZndyaXRlKCRzdGRpbiwgJHRoaXMtPmlucHV0QnVmZmVyKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pbnB1dEJ1ZmZlciA9IHN1YnN0cigkdGhpcy0+aW5wdXRCdWZmZXIsICR3cml0dGVuKTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+aW5wdXRCdWZmZXJbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFskdGhpcy0+cGlwZXNbMF1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGlucHV0KSB7CiAgICAgICAgICAgICAgICBmb3IgKDs7KSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGEgPSBmcmVhZCgkaW5wdXQsIHNlbGY6OkNIVU5LX1NJWkUpOwogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGRhdGFbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkd3JpdHRlbiA9IGZ3cml0ZSgkc3RkaW4sICRkYXRhKTsKICAgICAgICAgICAgICAgICAgICAkZGF0YSA9IHN1YnN0cigkZGF0YSwgJHdyaXR0ZW4pOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZGF0YVswXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlucHV0QnVmZmVyID0gJGRhdGE7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWyR0aGlzLT5waXBlc1swXV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGZlb2YoJGlucHV0KSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aW5wdXQgaW5zdGFuY2VvZiBcSXRlcmF0b3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlucHV0LT5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlucHV0ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIG5vIGlucHV0IHRvIHJlYWQgb24gcmVzb3VyY2UsIGJ1ZmZlciBpcyBlbXB0eQogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmlucHV0QnVmZmVyWzBdKSAmJiAhKCR0aGlzLT5pbnB1dCBpbnN0YW5jZW9mIFxJdGVyYXRvciA/ICR0aGlzLT5pbnB1dC0+dmFsaWQoKSA6ICR0aGlzLT5pbnB1dCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0ID0gbnVsbDsKICAgICAgICAgICAgZmNsb3NlKCR0aGlzLT5waXBlc1swXSk7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5waXBlc1swXSk7CiAgICAgICAgfSBlbHNlaWYgKCEkdykgewogICAgICAgICAgICByZXR1cm4gWyR0aGlzLT5waXBlc1swXV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFuZGxlRXJyb3IoJHR5cGUsICRtc2cpCiAgICB7CiAgICAgICAgJHRoaXMtPmxhc3RFcnJvciA9ICRtc2c7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFJ1bnRpbWVFeGNlcHRpb247CgovKioKICogUHJvdmlkZXMgYSB3YXkgdG8gY29udGludW91c2x5IHdyaXRlIHRvIHRoZSBpbnB1dCBvZiBhIFByb2Nlc3MgdW50aWwgdGhlIElucHV0U3RyZWFtIGlzIGNsb3NlZC4KICoKICogQGF1dGhvciBOaWNvbGFzIEdyZWthcyA8cEB0Y2h3b3JrLmNvbT4KICovCmNsYXNzIElucHV0U3RyZWFtIGltcGxlbWVudHMgXEl0ZXJhdG9yQWdncmVnYXRlCnsKICAgIC8qKiBAdmFyIGNhbGxhYmxlfG51bGwgKi8KICAgIHByaXZhdGUgJG9uRW1wdHkgPSBudWxsOwogICAgcHJpdmF0ZSAkaW5wdXQgPSBbXTsKICAgIHByaXZhdGUgJG9wZW4gPSB0cnVlOwoKICAgIC8qKgogICAgICogU2V0cyBhIGNhbGxiYWNrIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIHdyaXRlIGJ1ZmZlciBiZWNvbWVzIGVtcHR5LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25FbXB0eShjYWxsYWJsZSAkb25FbXB0eSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm9uRW1wdHkgPSAkb25FbXB0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGVuZHMgYW4gaW5wdXQgdG8gdGhlIHdyaXRlIGJ1ZmZlci4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8c3RyaW5nfGludHxmbG9hdHxib29sfFxUcmF2ZXJzYWJsZXxudWxsICRpbnB1dCBUaGUgaW5wdXQgdG8gYXBwZW5kIGFzIHNjYWxhciwKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbSByZXNvdXJjZSBvciBcVHJhdmVyc2FibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRpbnB1dCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGlucHV0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5pc0Nsb3NlZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJyIlcyIgaXMgY2xvc2VkLicsIHN0YXRpYzo6Y2xhc3MpKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmlucHV0W10gPSBQcm9jZXNzVXRpbHM6OnZhbGlkYXRlSW5wdXQoX19NRVRIT0RfXywgJGlucHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENsb3NlcyB0aGUgd3JpdGUgYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xvc2UoKQogICAgewogICAgICAgICR0aGlzLT5vcGVuID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBUZWxscyB3aGV0aGVyIHRoZSB3cml0ZSBidWZmZXIgaXMgY2xvc2VkIG9yIG5vdC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQ2xvc2VkKCkKICAgIHsKICAgICAgICByZXR1cm4gISR0aGlzLT5vcGVuOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJdGVyYXRvcigpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wZW4gPSB0cnVlOwoKICAgICAgICB3aGlsZSAoJHRoaXMtPm9wZW4gfHwgJHRoaXMtPmlucHV0KSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmlucHV0KSB7CiAgICAgICAgICAgICAgICB5aWVsZCAnJzsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjdXJyZW50ID0gYXJyYXlfc2hpZnQoJHRoaXMtPmlucHV0KTsKCiAgICAgICAgICAgIGlmICgkY3VycmVudCBpbnN0YW5jZW9mIFxJdGVyYXRvcikgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGN1cnJlbnQgYXMgJGN1cikgewogICAgICAgICAgICAgICAgICAgIHlpZWxkICRjdXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB5aWVsZCAkY3VycmVudDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISR0aGlzLT5pbnB1dCAmJiAkdGhpcy0+b3BlbiAmJiBudWxsICE9PSAkb25FbXB0eSA9ICR0aGlzLT5vbkVtcHR5KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoJG9uRW1wdHkoJHRoaXMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3M7CgovKioKICogR2VuZXJpYyBleGVjdXRhYmxlIGZpbmRlci4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgSm9oYW5uZXMgTS4gU2NobWl0dCA8c2NobWl0dGpvaEBnbWFpbC5jb20+CiAqLwpjbGFzcyBFeGVjdXRhYmxlRmluZGVyCnsKICAgIHByaXZhdGUgJHN1ZmZpeGVzID0gWycuZXhlJywgJy5iYXQnLCAnLmNtZCcsICcuY29tJ107CgogICAgLyoqCiAgICAgKiBSZXBsYWNlcyBkZWZhdWx0IHN1ZmZpeGVzIG9mIGV4ZWN1dGFibGUuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdWZmaXhlcyhhcnJheSAkc3VmZml4ZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnN1ZmZpeGVzID0gJHN1ZmZpeGVzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBuZXcgcG9zc2libGUgc3VmZml4IHRvIGNoZWNrIGZvciBleGVjdXRhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1ZmZpeAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkU3VmZml4KCRzdWZmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPnN1ZmZpeGVzW10gPSAkc3VmZml4OwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgYW4gZXhlY3V0YWJsZSBieSBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbmFtZSAgICAgIFRoZSBleGVjdXRhYmxlIG5hbWUgKHdpdGhvdXQgdGhlIGV4dGVuc2lvbikKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZGVmYXVsdCAgIFRoZSBkZWZhdWx0IHRvIHJldHVybiBpZiBubyBleGVjdXRhYmxlIGlzIGZvdW5kCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgJGV4dHJhRGlycyBBZGRpdGlvbmFsIGRpcnMgdG8gY2hlY2sgaW50bwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIGV4ZWN1dGFibGUgcGF0aCBvciBkZWZhdWx0IHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kKCRuYW1lLCAkZGVmYXVsdCA9IG51bGwsIGFycmF5ICRleHRyYURpcnMgPSBbXSkKICAgIHsKICAgICAgICBpZiAoaW5pX2dldCgnb3Blbl9iYXNlZGlyJykpIHsKICAgICAgICAgICAgJHNlYXJjaFBhdGggPSBhcnJheV9tZXJnZShleHBsb2RlKFxQQVRIX1NFUEFSQVRPUiwgaW5pX2dldCgnb3Blbl9iYXNlZGlyJykpLCAkZXh0cmFEaXJzKTsKICAgICAgICAgICAgJGRpcnMgPSBbXTsKICAgICAgICAgICAgZm9yZWFjaCAoJHNlYXJjaFBhdGggYXMgJHBhdGgpIHsKICAgICAgICAgICAgICAgIC8vIFNpbGVuY2luZyBhZ2FpbnN0IGh0dHBzOi8vYnVncy5waHAubmV0LzY5MjQwCiAgICAgICAgICAgICAgICBpZiAoQGlzX2RpcigkcGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICAkZGlyc1tdID0gJHBhdGg7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChiYXNlbmFtZSgkcGF0aCkgPT0gJG5hbWUgJiYgQGlzX2V4ZWN1dGFibGUoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGF0aDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZGlycyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgZXhwbG9kZShcUEFUSF9TRVBBUkFUT1IsIGdldGVudignUEFUSCcpID86IGdldGVudignUGF0aCcpKSwKICAgICAgICAgICAgICAgICRleHRyYURpcnMKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRzdWZmaXhlcyA9IFsnJ107CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRwYXRoRXh0ID0gZ2V0ZW52KCdQQVRIRVhUJyk7CiAgICAgICAgICAgICRzdWZmaXhlcyA9IGFycmF5X21lcmdlKCRwYXRoRXh0ID8gZXhwbG9kZShcUEFUSF9TRVBBUkFUT1IsICRwYXRoRXh0KSA6ICR0aGlzLT5zdWZmaXhlcywgJHN1ZmZpeGVzKTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJHN1ZmZpeGVzIGFzICRzdWZmaXgpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGRpcnMgYXMgJGRpcikgewogICAgICAgICAgICAgICAgaWYgKEBpc19maWxlKCRmaWxlID0gJGRpci5cRElSRUNUT1JZX1NFUEFSQVRPUi4kbmFtZS4kc3VmZml4KSAmJiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgfHwgQGlzX2V4ZWN1dGFibGUoJGZpbGUpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2VzczsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogUHJvY2Vzc1V0aWxzIGlzIGEgYnVuY2ggb2YgdXRpbGl0eSBtZXRob2RzLgogKgogKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHN0YXRpYyBtZXRob2RzIG9ubHkgYW5kIGlzIG5vdCBtZWFudCB0byBiZSBpbnN0YW50aWF0ZWQuCiAqCiAqIEBhdXRob3IgTWFydGluIEhhc2/FiCA8bWFydGluLmhhc29uQGdtYWlsLmNvbT4KICovCmNsYXNzIFByb2Nlc3NVdGlscwp7CiAgICAvKioKICAgICAqIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgc2hlbGwgYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYXJndW1lbnQgVGhlIGFyZ3VtZW50IHRoYXQgd2lsbCBiZSBlc2NhcGVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGVzY2FwZWQgYXJndW1lbnQKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZSBhIGNvbW1hbmQgbGluZSBhcnJheSBvciBnaXZlIGVudiB2YXJzIHRvIHRoZSBgUHJvY2Vzczo6c3RhcnQvcnVuKClgIG1ldGhvZCBpbnN0ZWFkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVzY2FwZUFyZ3VtZW50KCRhcmd1bWVudCkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcignVGhlICcuX19NRVRIT0RfXy4nKCkgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZSBhIGNvbW1hbmQgbGluZSBhcnJheSBvciBnaXZlIGVudiB2YXJzIHRvIHRoZSBQcm9jZXNzOjpzdGFydC9ydW4oKSBtZXRob2QgaW5zdGVhZC4nLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICAvL0ZpeCBmb3IgUEhQIGJ1ZyAjNDM3ODQgZXNjYXBlc2hlbGxhcmcgcmVtb3ZlcyAlIGZyb20gZ2l2ZW4gc3RyaW5nCiAgICAgICAgLy9GaXggZm9yIFBIUCBidWcgIzQ5NDQ2IGVzY2FwZXNoZWxsYXJnIGRvZXNuJ3Qgd29yayBvbiBXaW5kb3dzCiAgICAgICAgLy9Ac2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzQzNzg0CiAgICAgICAgLy9Ac2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzQ5NDQ2CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgIGlmICgnJyA9PT0gJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZXNjYXBlc2hlbGxhcmcoJGFyZ3VtZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCA9ICcnOwogICAgICAgICAgICAkcXVvdGUgPSBmYWxzZTsKICAgICAgICAgICAgZm9yZWFjaCAocHJlZ19zcGxpdCgnLygiKS8nLCAkYXJndW1lbnQsIC0xLCBcUFJFR19TUExJVF9OT19FTVBUWSB8IFxQUkVHX1NQTElUX0RFTElNX0NBUFRVUkUpIGFzICRwYXJ0KSB7CiAgICAgICAgICAgICAgICBpZiAoJyInID09PSAkcGFydCkgewogICAgICAgICAgICAgICAgICAgICRlc2NhcGVkQXJndW1lbnQgLj0gJ1xcIic7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoc2VsZjo6aXNTdXJyb3VuZGVkQnkoJHBhcnQsICclJykpIHsKICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBlbnZpcm9ubWVudCB2YXJpYWJsZSBleHBhbnNpb24KICAgICAgICAgICAgICAgICAgICAkZXNjYXBlZEFyZ3VtZW50IC49ICdeJSInLnN1YnN0cigkcGFydCwgMSwgLTEpLiciXiUnOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgdHJhaWxpbmcgYmFja3NsYXNoCiAgICAgICAgICAgICAgICAgICAgaWYgKCdcXCcgPT09IHN1YnN0cigkcGFydCwgLTEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0IC49ICdcXCc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRxdW90ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCAuPSAkcGFydDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHF1b3RlKSB7CiAgICAgICAgICAgICAgICAkZXNjYXBlZEFyZ3VtZW50ID0gJyInLiRlc2NhcGVkQXJndW1lbnQuJyInOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGVzY2FwZWRBcmd1bWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAiJyIuc3RyX3JlcGxhY2UoIiciLCAiJ1xcJyciLCAkYXJndW1lbnQpLiInIjsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyBhbmQgbm9ybWFsaXplcyBhIFByb2Nlc3MgaW5wdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2FsbGVyIFRoZSBuYW1lIG9mIG1ldGhvZCBjYWxsIHRoYXQgdmFsaWRhdGVzIHRoZSBpbnB1dAogICAgICogQHBhcmFtIG1peGVkICAkaW5wdXQgIFRoZSBpbnB1dCB0byB2YWxpZGF0ZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgVGhlIHZhbGlkYXRlZCBpbnB1dAogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIEluIGNhc2UgdGhlIGlucHV0IGlzIG5vdCB2YWxpZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhbGlkYXRlSW5wdXQoJGNhbGxlciwgJGlucHV0KQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkaW5wdXQpIHsKICAgICAgICAgICAgaWYgKFxpc19yZXNvdXJjZSgkaW5wdXQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGlucHV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChcaXNfc3RyaW5nKCRpbnB1dCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkaW5wdXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX3NjYWxhcigkaW5wdXQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJGlucHV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkaW5wdXQgaW5zdGFuY2VvZiBQcm9jZXNzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGlucHV0LT5nZXRJdGVyYXRvcigkaW5wdXQ6OklURVJfU0tJUF9FUlIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkaW5wdXQgaW5zdGFuY2VvZiBcSXRlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkaW5wdXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRpbnB1dCBpbnN0YW5jZW9mIFxUcmF2ZXJzYWJsZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBcSXRlcmF0b3JJdGVyYXRvcigkaW5wdXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJyIlcyIgb25seSBhY2NlcHRzIHN0cmluZ3MsIFRyYXZlcnNhYmxlIG9iamVjdHMgb3Igc3RyZWFtIHJlc291cmNlcy4nLCAkY2FsbGVyKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGlucHV0OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzU3Vycm91bmRlZEJ5KCRhcmcsICRjaGFyKQogICAgewogICAgICAgIHJldHVybiAyIDwgXHN0cmxlbigkYXJnKSAmJiAkY2hhciA9PT0gJGFyZ1swXSAmJiAkY2hhciA9PT0gJGFyZ1tcc3RybGVuKCRhcmcpIC0gMV07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cUHJvY2Vzc0ZhaWxlZEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFByb2Nlc3NUaW1lZE91dEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFJ1bnRpbWVFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFBpcGVzXFBpcGVzSW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaXBlc1xVbml4UGlwZXM7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFBpcGVzXFdpbmRvd3NQaXBlczsKCi8qKgogKiBQcm9jZXNzIGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBwcm9jXyogZnVuY3Rpb25zIHRvIGVhc2lseQogKiBzdGFydCBpbmRlcGVuZGVudCBQSFAgcHJvY2Vzc2VzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBSb21haW4gTmV1dHJvbiA8aW1wcmVjQGdtYWlsLmNvbT4KICovCmNsYXNzIFByb2Nlc3MgaW1wbGVtZW50cyBcSXRlcmF0b3JBZ2dyZWdhdGUKewogICAgY29uc3QgRVJSID0gJ2Vycic7CiAgICBjb25zdCBPVVQgPSAnb3V0JzsKCiAgICBjb25zdCBTVEFUVVNfUkVBRFkgPSAncmVhZHknOwogICAgY29uc3QgU1RBVFVTX1NUQVJURUQgPSAnc3RhcnRlZCc7CiAgICBjb25zdCBTVEFUVVNfVEVSTUlOQVRFRCA9ICd0ZXJtaW5hdGVkJzsKCiAgICBjb25zdCBTVERJTiA9IDA7CiAgICBjb25zdCBTVERPVVQgPSAxOwogICAgY29uc3QgU1RERVJSID0gMjsKCiAgICAvLyBUaW1lb3V0IFByZWNpc2lvbiBpbiBzZWNvbmRzLgogICAgY29uc3QgVElNRU9VVF9QUkVDSVNJT04gPSAwLjI7CgogICAgY29uc3QgSVRFUl9OT05fQkxPQ0tJTkcgPSAxOyAvLyBCeSBkZWZhdWx0LCBpdGVyYXRpbmcgb3ZlciBvdXRwdXRzIGlzIGEgYmxvY2tpbmcgY2FsbCwgdXNlIHRoaXMgZmxhZyB0byBtYWtlIGl0IG5vbi1ibG9ja2luZwogICAgY29uc3QgSVRFUl9LRUVQX09VVFBVVCA9IDI7ICAvLyBCeSBkZWZhdWx0LCBvdXRwdXRzIGFyZSBjbGVhcmVkIHdoaWxlIGl0ZXJhdGluZywgdXNlIHRoaXMgZmxhZyB0byBrZWVwIHRoZW0gaW4gbWVtb3J5CiAgICBjb25zdCBJVEVSX1NLSVBfT1VUID0gNDsgICAgIC8vIFVzZSB0aGlzIGZsYWcgdG8gc2tpcCBTVERPVVQgd2hpbGUgaXRlcmF0aW5nCiAgICBjb25zdCBJVEVSX1NLSVBfRVJSID0gODsgICAgIC8vIFVzZSB0aGlzIGZsYWcgdG8gc2tpcCBTVERFUlIgd2hpbGUgaXRlcmF0aW5nCgogICAgcHJpdmF0ZSAkY2FsbGJhY2s7CiAgICBwcml2YXRlICRoYXNDYWxsYmFjayA9IGZhbHNlOwogICAgcHJpdmF0ZSAkY29tbWFuZGxpbmU7CiAgICBwcml2YXRlICRjd2Q7CiAgICBwcml2YXRlICRlbnY7CiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJHN0YXJ0dGltZTsKICAgIHByaXZhdGUgJGxhc3RPdXRwdXRUaW1lOwogICAgcHJpdmF0ZSAkdGltZW91dDsKICAgIHByaXZhdGUgJGlkbGVUaW1lb3V0OwogICAgcHJpdmF0ZSAkb3B0aW9ucyA9IFsnc3VwcHJlc3NfZXJyb3JzJyA9PiB0cnVlXTsKICAgIHByaXZhdGUgJGV4aXRjb2RlOwogICAgcHJpdmF0ZSAkZmFsbGJhY2tTdGF0dXMgPSBbXTsKICAgIHByaXZhdGUgJHByb2Nlc3NJbmZvcm1hdGlvbjsKICAgIHByaXZhdGUgJG91dHB1dERpc2FibGVkID0gZmFsc2U7CiAgICBwcml2YXRlICRzdGRvdXQ7CiAgICBwcml2YXRlICRzdGRlcnI7CiAgICBwcml2YXRlICRlbmhhbmNlV2luZG93c0NvbXBhdGliaWxpdHkgPSB0cnVlOwogICAgcHJpdmF0ZSAkZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eTsKICAgIHByaXZhdGUgJHByb2Nlc3M7CiAgICBwcml2YXRlICRzdGF0dXMgPSBzZWxmOjpTVEFUVVNfUkVBRFk7CiAgICBwcml2YXRlICRpbmNyZW1lbnRhbE91dHB1dE9mZnNldCA9IDA7CiAgICBwcml2YXRlICRpbmNyZW1lbnRhbEVycm9yT3V0cHV0T2Zmc2V0ID0gMDsKICAgIHByaXZhdGUgJHR0eSA9IGZhbHNlOwogICAgcHJpdmF0ZSAkcHR5OwogICAgcHJpdmF0ZSAkaW5oZXJpdEVudiA9IGZhbHNlOwoKICAgIHByaXZhdGUgJHVzZUZpbGVIYW5kbGVzID0gZmFsc2U7CiAgICAvKiogQHZhciBQaXBlc0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkcHJvY2Vzc1BpcGVzOwoKICAgIHByaXZhdGUgJGxhdGVzdFNpZ25hbDsKCiAgICBwcml2YXRlIHN0YXRpYyAkc2lnY2hpbGQ7CgogICAgLyoqCiAgICAgKiBFeGl0IGNvZGVzIHRyYW5zbGF0aW9uIHRhYmxlLgogICAgICoKICAgICAqIFVzZXItZGVmaW5lZCBlcnJvcnMgbXVzdCB1c2UgZXhpdCBjb2RlcyBpbiB0aGUgNjQtMTEzIHJhbmdlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljICRleGl0Q29kZXMgPSBbCiAgICAgICAgMCA9PiAnT0snLAogICAgICAgIDEgPT4gJ0dlbmVyYWwgZXJyb3InLAogICAgICAgIDIgPT4gJ01pc3VzZSBvZiBzaGVsbCBidWlsdGlucycsCgogICAgICAgIDEyNiA9PiAnSW52b2tlZCBjb21tYW5kIGNhbm5vdCBleGVjdXRlJywKICAgICAgICAxMjcgPT4gJ0NvbW1hbmQgbm90IGZvdW5kJywKICAgICAgICAxMjggPT4gJ0ludmFsaWQgZXhpdCBhcmd1bWVudCcsCgogICAgICAgIC8vIHNpZ25hbHMKICAgICAgICAxMjkgPT4gJ0hhbmd1cCcsCiAgICAgICAgMTMwID0+ICdJbnRlcnJ1cHQnLAogICAgICAgIDEzMSA9PiAnUXVpdCBhbmQgZHVtcCBjb3JlJywKICAgICAgICAxMzIgPT4gJ0lsbGVnYWwgaW5zdHJ1Y3Rpb24nLAogICAgICAgIDEzMyA9PiAnVHJhY2UvYnJlYWtwb2ludCB0cmFwJywKICAgICAgICAxMzQgPT4gJ1Byb2Nlc3MgYWJvcnRlZCcsCiAgICAgICAgMTM1ID0+ICdCdXMgZXJyb3I6ICJhY2Nlc3MgdG8gdW5kZWZpbmVkIHBvcnRpb24gb2YgbWVtb3J5IG9iamVjdCInLAogICAgICAgIDEzNiA9PiAnRmxvYXRpbmcgcG9pbnQgZXhjZXB0aW9uOiAiZXJyb25lb3VzIGFyaXRobWV0aWMgb3BlcmF0aW9uIicsCiAgICAgICAgMTM3ID0+ICdLaWxsICh0ZXJtaW5hdGUgaW1tZWRpYXRlbHkpJywKICAgICAgICAxMzggPT4gJ1VzZXItZGVmaW5lZCAxJywKICAgICAgICAxMzkgPT4gJ1NlZ21lbnRhdGlvbiB2aW9sYXRpb24nLAogICAgICAgIDE0MCA9PiAnVXNlci1kZWZpbmVkIDInLAogICAgICAgIDE0MSA9PiAnV3JpdGUgdG8gcGlwZSB3aXRoIG5vIG9uZSByZWFkaW5nJywKICAgICAgICAxNDIgPT4gJ1NpZ25hbCByYWlzZWQgYnkgYWxhcm0nLAogICAgICAgIDE0MyA9PiAnVGVybWluYXRpb24gKHJlcXVlc3QgdG8gdGVybWluYXRlKScsCiAgICAgICAgLy8gMTQ0IC0gbm90IGRlZmluZWQKICAgICAgICAxNDUgPT4gJ0NoaWxkIHByb2Nlc3MgdGVybWluYXRlZCwgc3RvcHBlZCAob3IgY29udGludWVkKiknLAogICAgICAgIDE0NiA9PiAnQ29udGludWUgaWYgc3RvcHBlZCcsCiAgICAgICAgMTQ3ID0+ICdTdG9wIGV4ZWN1dGluZyB0ZW1wb3JhcmlseScsCiAgICAgICAgMTQ4ID0+ICdUZXJtaW5hbCBzdG9wIHNpZ25hbCcsCiAgICAgICAgMTQ5ID0+ICdCYWNrZ3JvdW5kIHByb2Nlc3MgYXR0ZW1wdGluZyB0byByZWFkIGZyb20gdHR5ICgiaW4iKScsCiAgICAgICAgMTUwID0+ICdCYWNrZ3JvdW5kIHByb2Nlc3MgYXR0ZW1wdGluZyB0byB3cml0ZSB0byB0dHkgKCJvdXQiKScsCiAgICAgICAgMTUxID0+ICdVcmdlbnQgZGF0YSBhdmFpbGFibGUgb24gc29ja2V0JywKICAgICAgICAxNTIgPT4gJ0NQVSB0aW1lIGxpbWl0IGV4Y2VlZGVkJywKICAgICAgICAxNTMgPT4gJ0ZpbGUgc2l6ZSBsaW1pdCBleGNlZWRlZCcsCiAgICAgICAgMTU0ID0+ICdTaWduYWwgcmFpc2VkIGJ5IHRpbWVyIGNvdW50aW5nIHZpcnR1YWwgdGltZTogInZpcnR1YWwgdGltZXIgZXhwaXJlZCInLAogICAgICAgIDE1NSA9PiAnUHJvZmlsaW5nIHRpbWVyIGV4cGlyZWQnLAogICAgICAgIC8vIDE1NiAtIG5vdCBkZWZpbmVkCiAgICAgICAgMTU3ID0+ICdQb2xsYWJsZSBldmVudCcsCiAgICAgICAgLy8gMTU4IC0gbm90IGRlZmluZWQKICAgICAgICAxNTkgPT4gJ0JhZCBzeXNjYWxsJywKICAgIF07CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICAgJGNvbW1hbmRsaW5lIFRoZSBjb21tYW5kIGxpbmUgdG8gcnVuCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgJGN3ZCAgICAgICAgIFRoZSB3b3JraW5nIGRpcmVjdG9yeSBvciBudWxsIHRvIHVzZSB0aGUgd29ya2luZyBkaXIgb2YgdGhlIGN1cnJlbnQgUEhQIHByb2Nlc3MKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICAgICAkZW52ICAgICAgICAgVGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyBvciBudWxsIHRvIHVzZSB0aGUgc2FtZSBlbnZpcm9ubWVudCBhcyB0aGUgY3VycmVudCBQSFAgcHJvY2VzcwogICAgICogQHBhcmFtIG1peGVkfG51bGwgICAgICRpbnB1dCAgICAgICBUaGUgaW5wdXQgYXMgc3RyZWFtIHJlc291cmNlLCBzY2FsYXIgb3IgXFRyYXZlcnNhYmxlLCBvciBudWxsIGZvciBubyBpbnB1dAogICAgICogQHBhcmFtIGludHxmbG9hdHxudWxsICR0aW1lb3V0ICAgICBUaGUgdGltZW91dCBpbiBzZWNvbmRzIG9yIG51bGwgdG8gZGlzYWJsZQogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICRvcHRpb25zICAgICBBbiBhcnJheSBvZiBvcHRpb25zIGZvciBwcm9jX29wZW4KICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jX29wZW4gaXMgbm90IGluc3RhbGxlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvbW1hbmRsaW5lLCAkY3dkID0gbnVsbCwgYXJyYXkgJGVudiA9IG51bGwsICRpbnB1dCA9IG51bGwsICR0aW1lb3V0ID0gNjAsIGFycmF5ICRvcHRpb25zID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoIVxmdW5jdGlvbl9leGlzdHMoJ3Byb2Nfb3BlbicpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdUaGUgUHJvY2VzcyBjbGFzcyByZWxpZXMgb24gcHJvY19vcGVuLCB3aGljaCBpcyBub3QgYXZhaWxhYmxlIG9uIHlvdXIgUEhQIGluc3RhbGxhdGlvbi4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb21tYW5kbGluZSA9ICRjb21tYW5kbGluZTsKICAgICAgICAkdGhpcy0+Y3dkID0gJGN3ZDsKCiAgICAgICAgLy8gb24gV2luZG93cywgaWYgdGhlIGN3ZCBjaGFuZ2VkIHZpYSBjaGRpcigpLCBwcm9jX29wZW4gZGVmYXVsdHMgdG8gdGhlIGRpciB3aGVyZSBQSFAgd2FzIHN0YXJ0ZWQKICAgICAgICAvLyBvbiBHbnUvTGludXgsIFBIUCBidWlsZHMgd2l0aCAtLWVuYWJsZS1tYWludGFpbmVyLXp0cyBhcmUgYWxzbyBhZmZlY3RlZAogICAgICAgIC8vIEBzZWUgOiBodHRwczovL2J1Z3MucGhwLm5ldC81MTgwMAogICAgICAgIC8vIEBzZWUgOiBodHRwczovL2J1Z3MucGhwLm5ldC81MDUyNAogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+Y3dkICYmIChcZGVmaW5lZCgnWkVORF9USFJFQURfU0FGRScpIHx8ICdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSkgewogICAgICAgICAgICAkdGhpcy0+Y3dkID0gZ2V0Y3dkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkZW52KSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRFbnYoJGVudik7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0SW5wdXQoJGlucHV0KTsKICAgICAgICAkdGhpcy0+c2V0VGltZW91dCgkdGltZW91dCk7CiAgICAgICAgJHRoaXMtPnVzZUZpbGVIYW5kbGVzID0gJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1I7CiAgICAgICAgJHRoaXMtPnB0eSA9IGZhbHNlOwogICAgICAgICR0aGlzLT5lbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5ID0gJ1xcJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgJiYgJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCk7CiAgICAgICAgaWYgKG51bGwgIT09ICRvcHRpb25zKSB7CiAgICAgICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAkb3B0aW9ucyBwYXJhbWV0ZXIgb2YgdGhlICVzIGNvbnN0cnVjdG9yIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuJywgX19DTEFTU19fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBhcnJheV9yZXBsYWNlKCR0aGlzLT5vcHRpb25zLCAkb3B0aW9ucyk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2Rlc3RydWN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+c3RvcCgwKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jbG9uZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlc2V0UHJvY2Vzc0RhdGEoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1bnMgdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogVGhlIGNhbGxiYWNrIHJlY2VpdmVzIHRoZSB0eXBlIG9mIG91dHB1dCAob3V0IG9yIGVycikgYW5kCiAgICAgKiBzb21lIGJ5dGVzIGZyb20gdGhlIG91dHB1dCBpbiByZWFsLXRpbWUuIEl0IGFsbG93cyB0byBoYXZlIGZlZWRiYWNrCiAgICAgKiBmcm9tIHRoZSBpbmRlcGVuZGVudCBwcm9jZXNzIGR1cmluZyBleGVjdXRpb24uCiAgICAgKgogICAgICogVGhlIFNURE9VVCBhbmQgU1RERVJSIGFyZSBhbHNvIGF2YWlsYWJsZSBhZnRlciB0aGUgcHJvY2VzcyBpcyBmaW5pc2hlZAogICAgICogdmlhIHRoZSBnZXRPdXRwdXQoKSBhbmQgZ2V0RXJyb3JPdXRwdXQoKSBtZXRob2RzLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRjYWxsYmFjayBBIFBIUCBjYWxsYmFjayB0byBydW4gd2hlbmV2ZXIgdGhlcmUgaXMgc29tZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCBhdmFpbGFibGUgb24gU1RET1VUIG9yIFNUREVSUgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBleGl0IHN0YXR1cyBjb2RlCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gcHJvY2VzcyBjYW4ndCBiZSBsYXVuY2hlZAogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gcHJvY2VzcyBzdG9wcGVkIGFmdGVyIHJlY2VpdmluZyBzaWduYWwKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICBJbiBjYXNlIGEgY2FsbGJhY2sgaXMgcHJvdmlkZWQgYW5kIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZAogICAgICoKICAgICAqIEBmaW5hbCBzaW5jZSB2ZXJzaW9uIDMuMwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcnVuKCRjYWxsYmFjayA9IG51bGwvKiwgYXJyYXkgJGVudiA9IFtdKi8pCiAgICB7CiAgICAgICAgJGVudiA9IDEgPCBcZnVuY19udW1fYXJncygpID8gZnVuY19nZXRfYXJnKDEpIDogbnVsbDsKICAgICAgICAkdGhpcy0+c3RhcnQoJGNhbGxiYWNrLCAkZW52KTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT53YWl0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHRoZSBwcm9jZXNzLgogICAgICoKICAgICAqIFRoaXMgaXMgaWRlbnRpY2FsIHRvIHJ1bigpIGV4Y2VwdCB0aGF0IGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlIHByb2Nlc3MKICAgICAqIGV4aXRzIHdpdGggYSBub24temVybyBleGl0IGNvZGUuCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiAgICAgICBpZiBQSFAgd2FzIGNvbXBpbGVkIHdpdGggLS1lbmFibGUtc2lnY2hpbGQgYW5kIHRoZSBlbmhhbmNlZCBzaWdjaGlsZCBjb21wYXRpYmlsaXR5IG1vZGUgaXMgbm90IGVuYWJsZWQKICAgICAqIEB0aHJvd3MgUHJvY2Vzc0ZhaWxlZEV4Y2VwdGlvbiBpZiB0aGUgcHJvY2VzcyBkaWRuJ3QgdGVybWluYXRlIHN1Y2Nlc3NmdWxseQogICAgICoKICAgICAqIEBmaW5hbCBzaW5jZSB2ZXJzaW9uIDMuMwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbXVzdFJ1bihjYWxsYWJsZSAkY2FsbGJhY2sgPSBudWxsLyosIGFycmF5ICRlbnYgPSBbXSovKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgJiYgJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1RoaXMgUEhQIGhhcyBiZWVuIGNvbXBpbGVkIHdpdGggLS1lbmFibGUtc2lnY2hpbGQuIFlvdSBtdXN0IHVzZSBzZXRFbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5KCkgdG8gdXNlIHRoaXMgbWV0aG9kLicpOwogICAgICAgIH0KICAgICAgICAkZW52ID0gMSA8IFxmdW5jX251bV9hcmdzKCkgPyBmdW5jX2dldF9hcmcoMSkgOiBudWxsOwoKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnJ1bigkY2FsbGJhY2ssICRlbnYpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBQcm9jZXNzRmFpbGVkRXhjZXB0aW9uKCR0aGlzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFN0YXJ0cyB0aGUgcHJvY2VzcyBhbmQgcmV0dXJucyBhZnRlciB3cml0aW5nIHRoZSBpbnB1dCB0byBTVERJTi4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBibG9ja3MgdW50aWwgYWxsIFNURElOIGRhdGEgaXMgc2VudCB0byB0aGUgcHJvY2VzcyB0aGVuIGl0CiAgICAgKiByZXR1cm5zIHdoaWxlIHRoZSBwcm9jZXNzIHJ1bnMgaW4gdGhlIGJhY2tncm91bmQuCiAgICAgKgogICAgICogVGhlIHRlcm1pbmF0aW9uIG9mIHRoZSBwcm9jZXNzIGNhbiBiZSBhd2FpdGVkIHdpdGggd2FpdCgpLgogICAgICoKICAgICAqIFRoZSBjYWxsYmFjayByZWNlaXZlcyB0aGUgdHlwZSBvZiBvdXRwdXQgKG91dCBvciBlcnIpIGFuZCBzb21lIGJ5dGVzIGZyb20KICAgICAqIHRoZSBvdXRwdXQgaW4gcmVhbC10aW1lIHdoaWxlIHdyaXRpbmcgdGhlIHN0YW5kYXJkIGlucHV0IHRvIHRoZSBwcm9jZXNzLgogICAgICogSXQgYWxsb3dzIHRvIGhhdmUgZmVlZGJhY2sgZnJvbSB0aGUgaW5kZXBlbmRlbnQgcHJvY2VzcyBkdXJpbmcgZXhlY3V0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRjYWxsYmFjayBBIFBIUCBjYWxsYmFjayB0byBydW4gd2hlbmV2ZXIgdGhlcmUgaXMgc29tZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCBhdmFpbGFibGUgb24gU1RET1VUIG9yIFNUREVSUgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIHByb2Nlc3MgY2FuJ3QgYmUgbGF1bmNoZWQKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIHByb2Nlc3MgaXMgYWxyZWFkeSBydW5uaW5nCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgSW4gY2FzZSBhIGNhbGxiYWNrIGlzIHByb3ZpZGVkIGFuZCBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0YXJ0KGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwvKiwgYXJyYXkgJGVudiA9IFsqLykKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdQcm9jZXNzIGlzIGFscmVhZHkgcnVubmluZy4nKTsKICAgICAgICB9CiAgICAgICAgaWYgKDIgPD0gXGZ1bmNfbnVtX2FyZ3MoKSkgewogICAgICAgICAgICAkZW52ID0gZnVuY19nZXRfYXJnKDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChfX0NMQVNTX18gIT09IHN0YXRpYzo6Y2xhc3MpIHsKICAgICAgICAgICAgICAgICRyID0gbmV3IFxSZWZsZWN0aW9uTWV0aG9kKCR0aGlzLCBfX0ZVTkNUSU9OX18pOwogICAgICAgICAgICAgICAgaWYgKF9fQ0xBU1NfXyAhPT0gJHItPmdldERlY2xhcmluZ0NsYXNzKCktPmdldE5hbWUoKSAmJiAoMiA+ICRyLT5nZXROdW1iZXJPZlBhcmFtZXRlcnMoKSB8fCAnZW52JyAhPT0gJHItPmdldFBhcmFtZXRlcnMoKVsxXS0+bmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXM6OnN0YXJ0KCkgbWV0aG9kIGV4cGVjdHMgYSBzZWNvbmQgIiRlbnYiIGFyZ3VtZW50IHNpbmNlIFN5bWZvbnkgMy4zLiBJdCB3aWxsIGJlIG1hZGUgbWFuZGF0b3J5IGluIDQuMC4nLCBzdGF0aWM6OmNsYXNzKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkZW52ID0gbnVsbDsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yZXNldFByb2Nlc3NEYXRhKCk7CiAgICAgICAgJHRoaXMtPnN0YXJ0dGltZSA9ICR0aGlzLT5sYXN0T3V0cHV0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKICAgICAgICAkdGhpcy0+Y2FsbGJhY2sgPSAkdGhpcy0+YnVpbGRDYWxsYmFjaygkY2FsbGJhY2spOwogICAgICAgICR0aGlzLT5oYXNDYWxsYmFjayA9IG51bGwgIT09ICRjYWxsYmFjazsKICAgICAgICAkZGVzY3JpcHRvcnMgPSAkdGhpcy0+Z2V0RGVzY3JpcHRvcnMoKTsKICAgICAgICAkaW5oZXJpdEVudiA9ICR0aGlzLT5pbmhlcml0RW52OwoKICAgICAgICBpZiAoXGlzX2FycmF5KCRjb21tYW5kbGluZSA9ICR0aGlzLT5jb21tYW5kbGluZSkpIHsKICAgICAgICAgICAgJGNvbW1hbmRsaW5lID0gaW1wbG9kZSgnICcsIGFycmF5X21hcChbJHRoaXMsICdlc2NhcGVBcmd1bWVudCddLCAkY29tbWFuZGxpbmUpKTsKCiAgICAgICAgICAgIGlmICgnXFwnICE9PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICAgICAgLy8gZXhlYyBpcyBtYW5kYXRvcnkgdG8gZGVhbCB3aXRoIHNlbmRpbmcgYSBzaWduYWwgdG8gdGhlIHByb2Nlc3MKICAgICAgICAgICAgICAgICRjb21tYW5kbGluZSA9ICdleGVjICcuJGNvbW1hbmRsaW5lOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGVudikgewogICAgICAgICAgICAkZW52ID0gJHRoaXMtPmVudjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoJHRoaXMtPmVudikgewogICAgICAgICAgICAgICAgJGVudiArPSAkdGhpcy0+ZW52OwogICAgICAgICAgICB9CiAgICAgICAgICAgICRpbmhlcml0RW52ID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkZW52ICYmICRpbmhlcml0RW52KSB7CiAgICAgICAgICAgICRlbnYgKz0gJHRoaXMtPmdldERlZmF1bHRFbnYoKTsKICAgICAgICB9IGVsc2VpZiAobnVsbCAhPT0gJGVudikgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcignTm90IGluaGVyaXRpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYWx3YXlzIGhhcHBlbiBpbiA0LjAuIFNldCAiUHJvY2Vzczo6aW5oZXJpdEVudmlyb25tZW50VmFyaWFibGVzKCkiIHRvIHRydWUgaW5zdGVhZC4nLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRlbnYgPSAkdGhpcy0+Z2V0RGVmYXVsdEVudigpOwogICAgICAgIH0KICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgJiYgJHRoaXMtPmVuaGFuY2VXaW5kb3dzQ29tcGF0aWJpbGl0eSkgewogICAgICAgICAgICAkdGhpcy0+b3B0aW9uc1snYnlwYXNzX3NoZWxsJ10gPSB0cnVlOwogICAgICAgICAgICAkY29tbWFuZGxpbmUgPSAkdGhpcy0+cHJlcGFyZVdpbmRvd3NDb21tYW5kTGluZSgkY29tbWFuZGxpbmUsICRlbnYpOwogICAgICAgIH0gZWxzZWlmICghJHRoaXMtPnVzZUZpbGVIYW5kbGVzICYmICR0aGlzLT5lbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5ICYmICR0aGlzLT5pc1NpZ2NoaWxkRW5hYmxlZCgpKSB7CiAgICAgICAgICAgIC8vIGxhc3QgZXhpdCBjb2RlIGlzIG91dHB1dCBvbiB0aGUgZm91cnRoIHBpcGUgYW5kIGNhdWdodCB0byB3b3JrIGFyb3VuZCAtLWVuYWJsZS1zaWdjaGlsZAogICAgICAgICAgICAkZGVzY3JpcHRvcnNbM10gPSBbJ3BpcGUnLCAndyddOwoKICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vdW5peC5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvNzEyMDUvYmFja2dyb3VuZC1wcm9jZXNzLXBpcGUtaW5wdXQKICAgICAgICAgICAgJGNvbW1hbmRsaW5lID0gJ3sgKCcuJGNvbW1hbmRsaW5lLicpIDwmMyAzPCYtIDM+L2Rldi9udWxsICYgfSAzPCYwOyc7CiAgICAgICAgICAgICRjb21tYW5kbGluZSAuPSAncGlkPSQhOyBlY2hvICRwaWQgPiYzOyB3YWl0ICRwaWQ7IGNvZGU9JD87IGVjaG8gJGNvZGUgPiYzOyBleGl0ICRjb2RlJzsKCiAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIHRoZSBidWcsIHdoZW4gUFRTIGZ1bmN0aW9uYWxpdHkgaXMgZW5hYmxlZC4KICAgICAgICAgICAgLy8gQHNlZSA6IGh0dHBzOi8vYnVncy5waHAubmV0LzY5NDQyCiAgICAgICAgICAgICRwdHNXb3JrYXJvdW5kID0gZm9wZW4oX19GSUxFX18sICdyJyk7CiAgICAgICAgfQogICAgICAgIGlmIChcZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgJGVudlBhaXJzID0gJGVudjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZW52UGFpcnMgPSBbXTsKICAgICAgICAgICAgZm9yZWFjaCAoJGVudiBhcyAkayA9PiAkdikgewogICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkdikgewogICAgICAgICAgICAgICAgICAgICRlbnZQYWlyc1tdID0gJGsuJz0nLiR2OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX2RpcigkdGhpcy0+Y3dkKSkgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcignVGhlIHByb3ZpZGVkIGN3ZCBkb2VzIG5vdCBleGlzdC4gQ29tbWFuZCBpcyBjdXJyZW50bHkgcmFuIGFnYWluc3QgZ2V0Y3dkKCkuIFRoaXMgYmVoYXZpb3IgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuNCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4nLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSBAcHJvY19vcGVuKCRjb21tYW5kbGluZSwgJGRlc2NyaXB0b3JzLCAkdGhpcy0+cHJvY2Vzc1BpcGVzLT5waXBlcywgJHRoaXMtPmN3ZCwgJGVudlBhaXJzLCAkdGhpcy0+b3B0aW9ucyk7CgogICAgICAgIGlmICghXGlzX3Jlc291cmNlKCR0aGlzLT5wcm9jZXNzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVW5hYmxlIHRvIGxhdW5jaCBhIG5ldyBwcm9jZXNzLicpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c3RhdHVzID0gc2VsZjo6U1RBVFVTX1NUQVJURUQ7CgogICAgICAgIGlmIChpc3NldCgkZGVzY3JpcHRvcnNbM10pKSB7CiAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja1N0YXR1c1sncGlkJ10gPSAoaW50KSBmZ2V0cygkdGhpcy0+cHJvY2Vzc1BpcGVzLT5waXBlc1szXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnR0eSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dXBkYXRlU3RhdHVzKGZhbHNlKTsKICAgICAgICAkdGhpcy0+Y2hlY2tUaW1lb3V0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXN0YXJ0cyB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBCZSB3YXJuZWQgdGhhdCB0aGUgcHJvY2VzcyBpcyBjbG9uZWQgYmVmb3JlIGJlaW5nIHN0YXJ0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJGNhbGxiYWNrIEEgUEhQIGNhbGxiYWNrIHRvIHJ1biB3aGVuZXZlciB0aGVyZSBpcyBzb21lCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0IGF2YWlsYWJsZSBvbiBTVERPVVQgb3IgU1RERVJSCiAgICAgKgogICAgICogQHJldHVybiBzdGF0aWMKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jZXNzIGNhbid0IGJlIGxhdW5jaGVkCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jZXNzIGlzIGFscmVhZHkgcnVubmluZwogICAgICoKICAgICAqIEBzZWUgc3RhcnQoKQogICAgICoKICAgICAqIEBmaW5hbCBzaW5jZSB2ZXJzaW9uIDMuMwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzdGFydChjYWxsYWJsZSAkY2FsbGJhY2sgPSBudWxsLyosIGFycmF5ICRlbnYgPSBbXSovKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1Byb2Nlc3MgaXMgYWxyZWFkeSBydW5uaW5nLicpOwogICAgICAgIH0KICAgICAgICAkZW52ID0gMSA8IFxmdW5jX251bV9hcmdzKCkgPyBmdW5jX2dldF9hcmcoMSkgOiBudWxsOwoKICAgICAgICAkcHJvY2VzcyA9IGNsb25lICR0aGlzOwogICAgICAgICRwcm9jZXNzLT5zdGFydCgkY2FsbGJhY2ssICRlbnYpOwoKICAgICAgICByZXR1cm4gJHByb2Nlc3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBXYWl0cyBmb3IgdGhlIHByb2Nlc3MgdG8gdGVybWluYXRlLgogICAgICoKICAgICAqIFRoZSBjYWxsYmFjayByZWNlaXZlcyB0aGUgdHlwZSBvZiBvdXRwdXQgKG91dCBvciBlcnIpIGFuZCBzb21lIGJ5dGVzCiAgICAgKiBmcm9tIHRoZSBvdXRwdXQgaW4gcmVhbC10aW1lIHdoaWxlIHdyaXRpbmcgdGhlIHN0YW5kYXJkIGlucHV0IHRvIHRoZSBwcm9jZXNzLgogICAgICogSXQgYWxsb3dzIHRvIGhhdmUgZmVlZGJhY2sgZnJvbSB0aGUgaW5kZXBlbmRlbnQgcHJvY2VzcyBkdXJpbmcgZXhlY3V0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRjYWxsYmFjayBBIHZhbGlkIFBIUCBjYWxsYmFjawogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBleGl0Y29kZSBvZiB0aGUgcHJvY2VzcwogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIHByb2Nlc3MgdGltZWQgb3V0CiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jZXNzIHN0b3BwZWQgYWZ0ZXIgcmVjZWl2aW5nIHNpZ25hbAogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiAgIFdoZW4gcHJvY2VzcyBpcyBub3QgeWV0IHN0YXJ0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhaXQoY2FsbGFibGUgJGNhbGxiYWNrID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVxdWlyZVByb2Nlc3NJc1N0YXJ0ZWQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgJHRoaXMtPnVwZGF0ZVN0YXR1cyhmYWxzZSk7CgogICAgICAgIGlmIChudWxsICE9PSAkY2FsbGJhY2spIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+cHJvY2Vzc1BpcGVzLT5oYXZlUmVhZFN1cHBvcnQoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnN0b3AoMCk7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdQYXNzIHRoZSBjYWxsYmFjayB0byB0aGUgUHJvY2Vzczo6c3RhcnQgbWV0aG9kIG9yIGVuYWJsZU91dHB1dCB0byB1c2UgYSBjYWxsYmFjayB3aXRoIFByb2Nlc3M6OndhaXQuJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmNhbGxiYWNrID0gJHRoaXMtPmJ1aWxkQ2FsbGJhY2soJGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIGRvIHsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVGltZW91dCgpOwogICAgICAgICAgICAkcnVubmluZyA9ICdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SID8gJHRoaXMtPmlzUnVubmluZygpIDogJHRoaXMtPnByb2Nlc3NQaXBlcy0+YXJlT3BlbigpOwogICAgICAgICAgICAkdGhpcy0+cmVhZFBpcGVzKCRydW5uaW5nLCAnXFwnICE9PSBcRElSRUNUT1JZX1NFUEFSQVRPUiB8fCAhJHJ1bm5pbmcpOwogICAgICAgIH0gd2hpbGUgKCRydW5uaW5nKTsKCiAgICAgICAgd2hpbGUgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tUaW1lb3V0KCk7CiAgICAgICAgICAgIHVzbGVlcCgxMDAwKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWydzaWduYWxlZCddICYmICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3Rlcm1zaWcnXSAhPT0gJHRoaXMtPmxhdGVzdFNpZ25hbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgcHJvY2VzcyBoYXMgYmVlbiBzaWduYWxlZCB3aXRoIHNpZ25hbCAiJXMiLicsICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3Rlcm1zaWcnXSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5leGl0Y29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFBpZCAocHJvY2VzcyBpZGVudGlmaWVyKSwgaWYgYXBwbGljYWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludHxudWxsIFRoZSBwcm9jZXNzIGlkIGlmIHJ1bm5pbmcsIG51bGwgb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQaWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aXNSdW5uaW5nKCkgPyAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWydwaWQnXSA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZW5kcyBhIFBPU0lYIHNpZ25hbCB0byB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRzaWduYWwgQSB2YWxpZCBQT1NJWCBzaWduYWwgKHNlZSBodHRwczovL3BocC5uZXQvcGNudGwuY29uc3RhbnRzKQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBub3QgcnVubmluZwogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgLS1lbmFibGUtc2lnY2hpbGQgaXMgYWN0aXZhdGVkIGFuZCB0aGUgcHJvY2VzcyBjYW4ndCBiZSBraWxsZWQKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIG9mIGZhaWx1cmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNpZ25hbCgkc2lnbmFsKQogICAgewogICAgICAgICR0aGlzLT5kb1NpZ25hbCgkc2lnbmFsLCB0cnVlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRGlzYWJsZXMgZmV0Y2hpbmcgb3V0cHV0IGFuZCBlcnJvciBvdXRwdXQgZnJvbSB0aGUgdW5kZXJseWluZyBwcm9jZXNzLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBhbHJlYWR5IHJ1bm5pbmcKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICBpZiBhbiBpZGxlIHRpbWVvdXQgaXMgc2V0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNhYmxlT3V0cHV0KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdEaXNhYmxpbmcgb3V0cHV0IHdoaWxlIHRoZSBwcm9jZXNzIGlzIHJ1bm5pbmcgaXMgbm90IHBvc3NpYmxlLicpOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmlkbGVUaW1lb3V0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignT3V0cHV0IGNhbiBub3QgYmUgZGlzYWJsZWQgd2hpbGUgYW4gaWRsZSB0aW1lb3V0IGlzIHNldC4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXREaXNhYmxlZCA9IHRydWU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZXMgZmV0Y2hpbmcgb3V0cHV0IGFuZCBlcnJvciBvdXRwdXQgZnJvbSB0aGUgdW5kZXJseWluZyBwcm9jZXNzLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBhbHJlYWR5IHJ1bm5pbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZU91dHB1dCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignRW5hYmxpbmcgb3V0cHV0IHdoaWxlIHRoZSBwcm9jZXNzIGlzIHJ1bm5pbmcgaXMgbm90IHBvc3NpYmxlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm91dHB1dERpc2FibGVkID0gZmFsc2U7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpbiBjYXNlIHRoZSBvdXRwdXQgaXMgZGlzYWJsZWQsIGZhbHNlIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzT3V0cHV0RGlzYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0RGlzYWJsZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG91dHB1dCBvZiB0aGUgcHJvY2VzcyAoU1RET1VUKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgcHJvY2VzcyBvdXRwdXQKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIGluIGNhc2UgdGhlIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZAogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCBzdGFydGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPdXRwdXQoKQogICAgewogICAgICAgICR0aGlzLT5yZWFkUGlwZXNGb3JPdXRwdXQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmV0ID0gc3RyZWFtX2dldF9jb250ZW50cygkdGhpcy0+c3Rkb3V0LCAtMSwgMCkpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBvdXRwdXQgaW5jcmVtZW50YWxseS4KICAgICAqCiAgICAgKiBJbiBjb21wYXJpc29uIHdpdGggdGhlIGdldE91dHB1dCBtZXRob2Qgd2hpY2ggYWx3YXlzIHJldHVybiB0aGUgd2hvbGUKICAgICAqIG91dHB1dCwgdGhpcyBvbmUgcmV0dXJucyB0aGUgbmV3IG91dHB1dCBzaW5jZSB0aGUgbGFzdCBjYWxsLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBwcm9jZXNzIG91dHB1dCBzaW5jZSB0aGUgbGFzdCBjYWxsCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBub3Qgc3RhcnRlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5jcmVtZW50YWxPdXRwdXQoKQogICAgewogICAgICAgICR0aGlzLT5yZWFkUGlwZXNGb3JPdXRwdXQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgJGxhdGVzdCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHRoaXMtPnN0ZG91dCwgLTEsICR0aGlzLT5pbmNyZW1lbnRhbE91dHB1dE9mZnNldCk7CiAgICAgICAgJHRoaXMtPmluY3JlbWVudGFsT3V0cHV0T2Zmc2V0ID0gZnRlbGwoJHRoaXMtPnN0ZG91dCk7CgogICAgICAgIGlmIChmYWxzZSA9PT0gJGxhdGVzdCkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxhdGVzdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3IgdG8gdGhlIG91dHB1dCBvZiB0aGUgcHJvY2Vzcywgd2l0aCB0aGUgb3V0cHV0IHR5cGUgYXMga2V5cyAoUHJvY2Vzczo6T1VUL0VSUikuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkZmxhZ3MgQSBiaXQgZmllbGQgb2YgUHJvY2Vzczo6SVRFUl8qIGZsYWdzCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBub3Qgc3RhcnRlZAogICAgICoKICAgICAqIEByZXR1cm4gXEdlbmVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoJGZsYWdzID0gMCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVhZFBpcGVzRm9yT3V0cHV0KF9fRlVOQ1RJT05fXywgZmFsc2UpOwoKICAgICAgICAkY2xlYXJPdXRwdXQgPSAhKHNlbGY6OklURVJfS0VFUF9PVVRQVVQgJiAkZmxhZ3MpOwogICAgICAgICRibG9ja2luZyA9ICEoc2VsZjo6SVRFUl9OT05fQkxPQ0tJTkcgJiAkZmxhZ3MpOwogICAgICAgICR5aWVsZE91dCA9ICEoc2VsZjo6SVRFUl9TS0lQX09VVCAmICRmbGFncyk7CiAgICAgICAgJHlpZWxkRXJyID0gIShzZWxmOjpJVEVSX1NLSVBfRVJSICYgJGZsYWdzKTsKCiAgICAgICAgd2hpbGUgKG51bGwgIT09ICR0aGlzLT5jYWxsYmFjayB8fCAoJHlpZWxkT3V0ICYmICFmZW9mKCR0aGlzLT5zdGRvdXQpKSB8fCAoJHlpZWxkRXJyICYmICFmZW9mKCR0aGlzLT5zdGRlcnIpKSkgewogICAgICAgICAgICBpZiAoJHlpZWxkT3V0KSB7CiAgICAgICAgICAgICAgICAkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cygkdGhpcy0+c3Rkb3V0LCAtMSwgJHRoaXMtPmluY3JlbWVudGFsT3V0cHV0T2Zmc2V0KTsKCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJG91dFswXSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNsZWFyT3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jbGVhck91dHB1dCgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmNyZW1lbnRhbE91dHB1dE9mZnNldCA9IGZ0ZWxsKCR0aGlzLT5zdGRvdXQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeWllbGQgc2VsZjo6T1VUID0+ICRvdXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkeWllbGRFcnIpIHsKICAgICAgICAgICAgICAgICRlcnIgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5zdGRlcnIsIC0xLCAkdGhpcy0+aW5jcmVtZW50YWxFcnJvck91dHB1dE9mZnNldCk7CgogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRlcnJbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjbGVhck91dHB1dCkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xlYXJFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmNyZW1lbnRhbEVycm9yT3V0cHV0T2Zmc2V0ID0gZnRlbGwoJHRoaXMtPnN0ZGVycik7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB5aWVsZCBzZWxmOjpFUlIgPT4gJGVycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkYmxvY2tpbmcgJiYgIWlzc2V0KCRvdXRbMF0pICYmICFpc3NldCgkZXJyWzBdKSkgewogICAgICAgICAgICAgICAgeWllbGQgc2VsZjo6T1VUID0+ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y2hlY2tUaW1lb3V0KCk7CiAgICAgICAgICAgICR0aGlzLT5yZWFkUGlwZXNGb3JPdXRwdXQoX19GVU5DVElPTl9fLCAkYmxvY2tpbmcpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsZWFycyB0aGUgcHJvY2VzcyBvdXRwdXQuCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYXJPdXRwdXQoKQogICAgewogICAgICAgIGZ0cnVuY2F0ZSgkdGhpcy0+c3Rkb3V0LCAwKTsKICAgICAgICBmc2VlaygkdGhpcy0+c3Rkb3V0LCAwKTsKICAgICAgICAkdGhpcy0+aW5jcmVtZW50YWxPdXRwdXRPZmZzZXQgPSAwOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGVycm9yIG91dHB1dCBvZiB0aGUgcHJvY2VzcyAoU1RERVJSKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgcHJvY2VzcyBlcnJvciBvdXRwdXQKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIGluIGNhc2UgdGhlIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZAogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCBzdGFydGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFcnJvck91dHB1dCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlYWRQaXBlc0Zvck91dHB1dChfX0ZVTkNUSU9OX18pOwoKICAgICAgICBpZiAoZmFsc2UgPT09ICRyZXQgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5zdGRlcnIsIC0xLCAwKSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJldDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVycm9yT3V0cHV0IGluY3JlbWVudGFsbHkuCiAgICAgKgogICAgICogSW4gY29tcGFyaXNvbiB3aXRoIHRoZSBnZXRFcnJvck91dHB1dCBtZXRob2Qgd2hpY2ggYWx3YXlzIHJldHVybiB0aGUKICAgICAqIHdob2xlIGVycm9yIG91dHB1dCwgdGhpcyBvbmUgcmV0dXJucyB0aGUgbmV3IGVycm9yIG91dHB1dCBzaW5jZSB0aGUgbGFzdAogICAgICogY2FsbC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgcHJvY2VzcyBlcnJvciBvdXRwdXQgc2luY2UgdGhlIGxhc3QgY2FsbAogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gaW4gY2FzZSB0aGUgb3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHN0YXJ0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluY3JlbWVudGFsRXJyb3JPdXRwdXQoKQogICAgewogICAgICAgICR0aGlzLT5yZWFkUGlwZXNGb3JPdXRwdXQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgJGxhdGVzdCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHRoaXMtPnN0ZGVyciwgLTEsICR0aGlzLT5pbmNyZW1lbnRhbEVycm9yT3V0cHV0T2Zmc2V0KTsKICAgICAgICAkdGhpcy0+aW5jcmVtZW50YWxFcnJvck91dHB1dE9mZnNldCA9IGZ0ZWxsKCR0aGlzLT5zdGRlcnIpOwoKICAgICAgICBpZiAoZmFsc2UgPT09ICRsYXRlc3QpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRsYXRlc3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhcnMgdGhlIHByb2Nlc3Mgb3V0cHV0LgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyRXJyb3JPdXRwdXQoKQogICAgewogICAgICAgIGZ0cnVuY2F0ZSgkdGhpcy0+c3RkZXJyLCAwKTsKICAgICAgICBmc2VlaygkdGhpcy0+c3RkZXJyLCAwKTsKICAgICAgICAkdGhpcy0+aW5jcmVtZW50YWxFcnJvck91dHB1dE9mZnNldCA9IDA7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4aXQgY29kZSByZXR1cm5lZCBieSB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludHxudWxsIFRoZSBleGl0IHN0YXR1cyBjb2RlLCBudWxsIGlmIHRoZSBQcm9jZXNzIGlzIG5vdCB0ZXJtaW5hdGVkCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgLS1lbmFibGUtc2lnY2hpbGQgaXMgYWN0aXZhdGVkIGFuZCB0aGUgc2lnY2hpbGQgY29tcGF0aWJpbGl0eSBtb2RlIGlzIGRpc2FibGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeGl0Q29kZSgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSAmJiAkdGhpcy0+aXNTaWdjaGlsZEVuYWJsZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVGhpcyBQSFAgaGFzIGJlZW4gY29tcGlsZWQgd2l0aCAtLWVuYWJsZS1zaWdjaGlsZC4gWW91IG11c3QgdXNlIHNldEVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkoKSB0byB1c2UgdGhpcyBtZXRob2QuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dXBkYXRlU3RhdHVzKGZhbHNlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5leGl0Y29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIHRoZSBleGl0IGNvZGUgcmV0dXJuZWQgYnkgdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgcmVsaWVzIG9uIHRoZSBVbml4IGV4aXQgY29kZSBzdGF0dXMgc3RhbmRhcmRpemF0aW9uCiAgICAgKiBhbmQgbWlnaHQgbm90IGJlIHJlbGV2YW50IGZvciBvdGhlciBvcGVyYXRpbmcgc3lzdGVtcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIEEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGZvciB0aGUgZXhpdCBzdGF0dXMgY29kZSwgbnVsbCBpZiB0aGUgUHJvY2VzcyBpcyBub3QgdGVybWluYXRlZAogICAgICoKICAgICAqIEBzZWUgaHR0cDovL3RsZHAub3JnL0xEUC9hYnMvaHRtbC9leGl0Y29kZXMuaHRtbAogICAgICogQHNlZSBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VuaXhfc2lnbmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeGl0Q29kZVRleHQoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkZXhpdGNvZGUgPSAkdGhpcy0+Z2V0RXhpdENvZGUoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc3NldChzZWxmOjokZXhpdENvZGVzWyRleGl0Y29kZV0pID8gc2VsZjo6JGV4aXRDb2Rlc1skZXhpdGNvZGVdIDogJ1Vua25vd24gZXJyb3InOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBwcm9jZXNzIGVuZGVkIHN1Y2Nlc3NmdWxseS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgcHJvY2VzcyBlbmRlZCBzdWNjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNTdWNjZXNzZnVsKCkKICAgIHsKICAgICAgICByZXR1cm4gMCA9PT0gJHRoaXMtPmdldEV4aXRDb2RlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNoaWxkIHByb2Nlc3MgaGFzIGJlZW4gdGVybWluYXRlZCBieSBhbiB1bmNhdWdodCBzaWduYWwuCiAgICAgKgogICAgICogSXQgYWx3YXlzIHJldHVybnMgZmFsc2Ugb24gV2luZG93cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSAtLWVuYWJsZS1zaWdjaGlsZCBpcyBhY3RpdmF0ZWQKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCB0ZXJtaW5hdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNCZWVuU2lnbmFsZWQoKQogICAgewogICAgICAgICR0aGlzLT5yZXF1aXJlUHJvY2Vzc0lzVGVybWluYXRlZChfX0ZVTkNUSU9OX18pOwoKICAgICAgICBpZiAoISR0aGlzLT5lbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5ICYmICR0aGlzLT5pc1NpZ2NoaWxkRW5hYmxlZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdUaGlzIFBIUCBoYXMgYmVlbiBjb21waWxlZCB3aXRoIC0tZW5hYmxlLXNpZ2NoaWxkLiBUZXJtIHNpZ25hbCBjYW4gbm90IGJlIHJldHJpZXZlZC4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWydzaWduYWxlZCddOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRoZSBzaWduYWwgdGhhdCBjYXVzZWQgdGhlIGNoaWxkIHByb2Nlc3MgdG8gdGVybWluYXRlIGl0cyBleGVjdXRpb24uCiAgICAgKgogICAgICogSXQgaXMgb25seSBtZWFuaW5nZnVsIGlmIGhhc0JlZW5TaWduYWxlZCgpIHJldHVybnMgdHJ1ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIC0tZW5hYmxlLXNpZ2NoaWxkIGlzIGFjdGl2YXRlZAogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiAgIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHRlcm1pbmF0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRlcm1TaWduYWwoKQogICAgewogICAgICAgICR0aGlzLT5yZXF1aXJlUHJvY2Vzc0lzVGVybWluYXRlZChfX0ZVTkNUSU9OX18pOwoKICAgICAgICBpZiAoJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCkgJiYgKCEkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSB8fCAtMSA9PT0gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsndGVybXNpZyddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVGhpcyBQSFAgaGFzIGJlZW4gY29tcGlsZWQgd2l0aCAtLWVuYWJsZS1zaWdjaGlsZC4gVGVybSBzaWduYWwgY2FuIG5vdCBiZSByZXRyaWV2ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsndGVybXNpZyddOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjaGlsZCBwcm9jZXNzIGhhcyBiZWVuIHN0b3BwZWQgYnkgYSBzaWduYWwuCiAgICAgKgogICAgICogSXQgYWx3YXlzIHJldHVybnMgZmFsc2Ugb24gV2luZG93cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHRlcm1pbmF0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0JlZW5TdG9wcGVkKCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVxdWlyZVByb2Nlc3NJc1Rlcm1pbmF0ZWQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3N0b3BwZWQnXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgc2lnbmFsIHRoYXQgY2F1c2VkIHRoZSBjaGlsZCBwcm9jZXNzIHRvIHN0b3AgaXRzIGV4ZWN1dGlvbi4KICAgICAqCiAgICAgKiBJdCBpcyBvbmx5IG1lYW5pbmdmdWwgaWYgaGFzQmVlblN0b3BwZWQoKSByZXR1cm5zIHRydWUuCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHRlcm1pbmF0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0b3BTaWduYWwoKQogICAgewogICAgICAgICR0aGlzLT5yZXF1aXJlUHJvY2Vzc0lzVGVybWluYXRlZChfX0ZVTkNUSU9OX18pOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsnc3RvcHNpZyddOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBwcm9jZXNzIGlzIGN1cnJlbnRseSBydW5uaW5nLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBwcm9jZXNzIGlzIGN1cnJlbnRseSBydW5uaW5nLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUnVubmluZygpCiAgICB7CiAgICAgICAgaWYgKHNlbGY6OlNUQVRVU19TVEFSVEVEICE9PSAkdGhpcy0+c3RhdHVzKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT51cGRhdGVTdGF0dXMoZmFsc2UpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsncnVubmluZyddOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBwcm9jZXNzIGhhcyBiZWVuIHN0YXJ0ZWQgd2l0aCBubyByZWdhcmQgdG8gdGhlIGN1cnJlbnQgc3RhdGUuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgc3RhdHVzIGlzIHJlYWR5LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU3RhcnRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OlNUQVRVU19SRUFEWSAhPSAkdGhpcy0+c3RhdHVzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBwcm9jZXNzIGlzIHRlcm1pbmF0ZWQuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgcHJvY2VzcyBpcyB0ZXJtaW5hdGVkLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVGVybWluYXRlZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnVwZGF0ZVN0YXR1cyhmYWxzZSk7CgogICAgICAgIHJldHVybiBzZWxmOjpTVEFUVVNfVEVSTUlOQVRFRCA9PSAkdGhpcy0+c3RhdHVzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcHJvY2VzcyBzdGF0dXMuCiAgICAgKgogICAgICogVGhlIHN0YXR1cyBpcyBvbmUgb2Y6IHJlYWR5LCBzdGFydGVkLCB0ZXJtaW5hdGVkLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBjdXJyZW50IHByb2Nlc3Mgc3RhdHVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGF0dXMoKQogICAgewogICAgICAgICR0aGlzLT51cGRhdGVTdGF0dXMoZmFsc2UpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXR1czsKICAgIH0KCiAgICAvKioKICAgICAqIFN0b3BzIHRoZSBwcm9jZXNzLgogICAgICoKICAgICAqIEBwYXJhbSBpbnR8ZmxvYXQgJHRpbWVvdXQgVGhlIHRpbWVvdXQgaW4gc2Vjb25kcwogICAgICogQHBhcmFtIGludCAgICAgICAkc2lnbmFsICBBIFBPU0lYIHNpZ25hbCB0byBzZW5kIGluIGNhc2UgdGhlIHByb2Nlc3MgaGFzIG5vdCBzdG9wIGF0IHRpbWVvdXQsIGRlZmF1bHQgaXMgU0lHS0lMTCAoOSkKICAgICAqCiAgICAgKiBAcmV0dXJuIGludHxudWxsIFRoZSBleGl0LWNvZGUgb2YgdGhlIHByb2Nlc3Mgb3IgbnVsbCBpZiBpdCdzIG5vdCBydW5uaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdG9wKCR0aW1lb3V0ID0gMTAsICRzaWduYWwgPSBudWxsKQogICAgewogICAgICAgICR0aW1lb3V0TWljcm8gPSBtaWNyb3RpbWUodHJ1ZSkgKyAkdGltZW91dDsKICAgICAgICBpZiAoJHRoaXMtPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgIC8vIGdpdmVuIGBTSUdURVJNYCBtYXkgbm90IGJlIGRlZmluZWQgYW5kIHRoYXQgYHByb2NfdGVybWluYXRlYCB1c2VzIHRoZSBjb25zdGFudCB2YWx1ZSBhbmQgbm90IHRoZSBjb25zdGFudCBpdHNlbGYsIHdlIHVzZSB0aGUgc2FtZSBoZXJlCiAgICAgICAgICAgICR0aGlzLT5kb1NpZ25hbCgxNSwgZmFsc2UpOwogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICB1c2xlZXAoMTAwMCk7CiAgICAgICAgICAgIH0gd2hpbGUgKCR0aGlzLT5pc1J1bm5pbmcoKSAmJiBtaWNyb3RpbWUodHJ1ZSkgPCAkdGltZW91dE1pY3JvKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgICAgIC8vIEF2b2lkIGV4Y2VwdGlvbiBoZXJlOiBwcm9jZXNzIGlzIHN1cHBvc2VkIHRvIGJlIHJ1bm5pbmcsIGJ1dCBpdCBtaWdodCBoYXZlIHN0b3BwZWQganVzdAogICAgICAgICAgICAgICAgLy8gYWZ0ZXIgdGhpcyBsaW5lLiBJbiBhbnkgY2FzZSwgbGV0J3Mgc2lsZW50bHkgZGlzY2FyZCB0aGUgZXJyb3IsIHdlIGNhbm5vdCBkbyBhbnl0aGluZy4KICAgICAgICAgICAgICAgICR0aGlzLT5kb1NpZ25hbCgkc2lnbmFsID86IDksIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmZhbGxiYWNrU3RhdHVzWydwaWQnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5mYWxsYmFja1N0YXR1c1sncGlkJ10pOwoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+c3RvcCgwLCAkc2lnbmFsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+Y2xvc2UoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZXhpdGNvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbGluZSB0byB0aGUgU1RET1VUIHN0cmVhbS4KICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIFRoZSBsaW5lIHRvIGFwcGVuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkT3V0cHV0KCRsaW5lKQogICAgewogICAgICAgICR0aGlzLT5sYXN0T3V0cHV0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKCiAgICAgICAgZnNlZWsoJHRoaXMtPnN0ZG91dCwgMCwgXFNFRUtfRU5EKTsKICAgICAgICBmd3JpdGUoJHRoaXMtPnN0ZG91dCwgJGxpbmUpOwogICAgICAgIGZzZWVrKCR0aGlzLT5zdGRvdXQsICR0aGlzLT5pbmNyZW1lbnRhbE91dHB1dE9mZnNldCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbGluZSB0byB0aGUgU1RERVJSIHN0cmVhbS4KICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIFRoZSBsaW5lIHRvIGFwcGVuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRXJyb3JPdXRwdXQoJGxpbmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmxhc3RPdXRwdXRUaW1lID0gbWljcm90aW1lKHRydWUpOwoKICAgICAgICBmc2VlaygkdGhpcy0+c3RkZXJyLCAwLCBcU0VFS19FTkQpOwogICAgICAgIGZ3cml0ZSgkdGhpcy0+c3RkZXJyLCAkbGluZSk7CiAgICAgICAgZnNlZWsoJHRoaXMtPnN0ZGVyciwgJHRoaXMtPmluY3JlbWVudGFsRXJyb3JPdXRwdXRPZmZzZXQpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY29tbWFuZCBsaW5lIHRvIGJlIGV4ZWN1dGVkLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBjb21tYW5kIHRvIGV4ZWN1dGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbW1hbmRMaW5lKCkKICAgIHsKICAgICAgICByZXR1cm4gXGlzX2FycmF5KCR0aGlzLT5jb21tYW5kbGluZSkgPyBpbXBsb2RlKCcgJywgYXJyYXlfbWFwKFskdGhpcywgJ2VzY2FwZUFyZ3VtZW50J10sICR0aGlzLT5jb21tYW5kbGluZSkpIDogJHRoaXMtPmNvbW1hbmRsaW5lOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29tbWFuZCBsaW5lIHRvIGJlIGV4ZWN1dGVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGNvbW1hbmRsaW5lIFRoZSBjb21tYW5kIHRvIGV4ZWN1dGUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb21tYW5kTGluZSgkY29tbWFuZGxpbmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbW1hbmRsaW5lID0gJGNvbW1hbmRsaW5lOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9jZXNzIHRpbWVvdXQgKG1heC4gcnVudGltZSkuCiAgICAgKgogICAgICogQHJldHVybiBmbG9hdHxudWxsIFRoZSB0aW1lb3V0IGluIHNlY29uZHMgb3IgbnVsbCBpZiBpdCdzIGRpc2FibGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUaW1lb3V0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRpbWVvdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9jZXNzIGlkbGUgdGltZW91dCAobWF4LiB0aW1lIHNpbmNlIGxhc3Qgb3V0cHV0KS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGZsb2F0fG51bGwgVGhlIHRpbWVvdXQgaW4gc2Vjb25kcyBvciBudWxsIGlmIGl0J3MgZGlzYWJsZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElkbGVUaW1lb3V0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlkbGVUaW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvY2VzcyB0aW1lb3V0IChtYXguIHJ1bnRpbWUpIGluIHNlY29uZHMuCiAgICAgKgogICAgICogVG8gZGlzYWJsZSB0aGUgdGltZW91dCwgc2V0IHRoaXMgdmFsdWUgdG8gbnVsbC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50fGZsb2F0fG51bGwgJHRpbWVvdXQgVGhlIHRpbWVvdXQgaW4gc2Vjb25kcwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdGltZW91dCBpcyBuZWdhdGl2ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGltZW91dCgkdGltZW91dCkKICAgIHsKICAgICAgICAkdGhpcy0+dGltZW91dCA9ICR0aGlzLT52YWxpZGF0ZVRpbWVvdXQoJHRpbWVvdXQpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9jZXNzIGlkbGUgdGltZW91dCAobWF4LiB0aW1lIHNpbmNlIGxhc3Qgb3V0cHV0KS4KICAgICAqCiAgICAgKiBUbyBkaXNhYmxlIHRoZSB0aW1lb3V0LCBzZXQgdGhpcyB2YWx1ZSB0byBudWxsLgogICAgICoKICAgICAqIEBwYXJhbSBpbnR8ZmxvYXR8bnVsbCAkdGltZW91dCBUaGUgdGltZW91dCBpbiBzZWNvbmRzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICAgICAgICAgIGlmIHRoZSBvdXRwdXQgaXMgZGlzYWJsZWQKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSB0aW1lb3V0IGlzIG5lZ2F0aXZlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZGxlVGltZW91dCgkdGltZW91dCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRpbWVvdXQgJiYgJHRoaXMtPm91dHB1dERpc2FibGVkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignSWRsZSB0aW1lb3V0IGNhbiBub3QgYmUgc2V0IHdoaWxlIHRoZSBvdXRwdXQgaXMgZGlzYWJsZWQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aWRsZVRpbWVvdXQgPSAkdGhpcy0+dmFsaWRhdGVUaW1lb3V0KCR0aW1lb3V0KTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyB0aGUgVFRZIG1vZGUuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHR0eSBUcnVlIHRvIGVuYWJsZWQgYW5kIGZhbHNlIHRvIGRpc2FibGUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgdGhlIFRUWSBtb2RlIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFR0eSgkdHR5KQogICAgewogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUiAmJiAkdHR5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdUVFkgbW9kZSBpcyBub3Qgc3VwcG9ydGVkIG9uIFdpbmRvd3MgcGxhdGZvcm0uJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkdHR5KSB7CiAgICAgICAgICAgIHN0YXRpYyAkaXNUdHlTdXBwb3J0ZWQ7CgogICAgICAgICAgICBpZiAobnVsbCA9PT0gJGlzVHR5U3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAkaXNUdHlTdXBwb3J0ZWQgPSAoYm9vbCkgQHByb2Nfb3BlbignZWNobyAxID4vZGV2L251bGwnLCBbWydmaWxlJywgJy9kZXYvdHR5JywgJ3InXSwgWydmaWxlJywgJy9kZXYvdHR5JywgJ3cnXSwgWydmaWxlJywgJy9kZXYvdHR5JywgJ3cnXV0sICRwaXBlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGlzVHR5U3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVFRZIG1vZGUgcmVxdWlyZXMgL2Rldi90dHkgdG8gYmUgcmVhZC93cml0YWJsZS4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnR0eSA9IChib29sKSAkdHR5OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIFRUWSBtb2RlIGlzIGVuYWJsZWQuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIFRUWSBtb2RlIGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNUdHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHR5OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBQVFkgbW9kZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkYm9vbAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFB0eSgkYm9vbCkKICAgIHsKICAgICAgICAkdGhpcy0+cHR5ID0gKGJvb2wpICRib29sOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFBUWSBzdGF0ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUHR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnB0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3Rvcnkgb3IgbnVsbCBvbiBmYWlsdXJlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRXb3JraW5nRGlyZWN0b3J5KCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmN3ZCkgewogICAgICAgICAgICAvLyBnZXRjd2QoKSB3aWxsIHJldHVybiBmYWxzZSBpZiBhbnkgb25lIG9mIHRoZSBwYXJlbnQgZGlyZWN0b3JpZXMgZG9lcyBub3QgaGF2ZQogICAgICAgICAgICAvLyB0aGUgcmVhZGFibGUgb3Igc2VhcmNoIG1vZGUgc2V0LCBldmVuIGlmIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBkb2VzCiAgICAgICAgICAgIHJldHVybiBnZXRjd2QoKSA/OiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jd2Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGN3ZCBUaGUgbmV3IHdvcmtpbmcgZGlyZWN0b3J5CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0V29ya2luZ0RpcmVjdG9yeSgkY3dkKQogICAgewogICAgICAgICR0aGlzLT5jd2QgPSAkY3dkOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBUaGUgY3VycmVudCBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVudigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lbnY7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuCiAgICAgKgogICAgICogRWFjaCBlbnZpcm9ubWVudCB2YXJpYWJsZSB2YWx1ZSBzaG91bGQgYmUgYSBzdHJpbmcuCiAgICAgKiBJZiBpdCBpcyBhbiBhcnJheSwgdGhlIHZhcmlhYmxlIGlzIGlnbm9yZWQuCiAgICAgKiBJZiBpdCBpcyBmYWxzZSBvciBudWxsLCBpdCB3aWxsIGJlIHJlbW92ZWQgd2hlbgogICAgICogZW52IHZhcnMgYXJlIG90aGVyd2lzZSBpbmhlcml0ZWQuCiAgICAgKgogICAgICogVGhhdCBoYXBwZW5zIGluIFBIUCB3aGVuICdhcmd2JyBpcyByZWdpc3RlcmVkIGludG8KICAgICAqIHRoZSAkX0VOViBhcnJheSBmb3IgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRlbnYgVGhlIG5ldyBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbnYoYXJyYXkgJGVudikKICAgIHsKICAgICAgICAvLyBQcm9jZXNzIGNhbiBub3QgaGFuZGxlIGVudiB2YWx1ZXMgdGhhdCBhcmUgYXJyYXlzCiAgICAgICAgJGVudiA9IGFycmF5X2ZpbHRlcigkZW52LCBmdW5jdGlvbiAoJHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiAhXGlzX2FycmF5KCR2YWx1ZSk7CiAgICAgICAgfSk7CgogICAgICAgICR0aGlzLT5lbnYgPSAkZW52OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBQcm9jZXNzIGlucHV0LgogICAgICoKICAgICAqIEByZXR1cm4gcmVzb3VyY2V8c3RyaW5nfFxJdGVyYXRvcnxudWxsIFRoZSBQcm9jZXNzIGlucHV0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlucHV0LgogICAgICoKICAgICAqIFRoaXMgY29udGVudCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgdW5kZXJseWluZyBwcm9jZXNzIHN0YW5kYXJkIGlucHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50fGZsb2F0fGJvb2x8cmVzb3VyY2V8XFRyYXZlcnNhYmxlfG51bGwgJGlucHV0IFRoZSBjb250ZW50CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBydW5uaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnB1dCgkaW5wdXQpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0lucHV0IGNhbiBub3QgYmUgc2V0IHdoaWxlIHRoZSBwcm9jZXNzIGlzIHJ1bm5pbmcuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW5wdXQgPSBQcm9jZXNzVXRpbHM6OnZhbGlkYXRlSW5wdXQoX19NRVRIT0RfXywgJGlucHV0KTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3B0aW9ucyBmb3IgcHJvY19vcGVuLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVGhlIGN1cnJlbnQgb3B0aW9ucwogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zLCB0byBiZSByZW1vdmVkIGluIDQuMC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLicsIF9fTUVUSE9EX18pLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPm9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBvcHRpb25zIGZvciBwcm9jX29wZW4uCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zIFRoZSBuZXcgb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb25zKGFycmF5ICRvcHRpb25zKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLicsIF9fTUVUSE9EX18pLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICAkdGhpcy0+b3B0aW9ucyA9ICRvcHRpb25zOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHdoZXRoZXIgb3Igbm90IFdpbmRvd3MgY29tcGF0aWJpbGl0eSBpcyBlbmFibGVkLgogICAgICoKICAgICAqIFRoaXMgaXMgdHJ1ZSBieSBkZWZhdWx0LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zLCB0byBiZSByZW1vdmVkIGluIDQuMC4gRW5oYW5jZWQgV2luZG93cyBjb21wYXRpYmlsaXR5IHdpbGwgYWx3YXlzIGJlIGVuYWJsZWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbmhhbmNlV2luZG93c0NvbXBhdGliaWxpdHkoKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBFbmhhbmNlZCBXaW5kb3dzIGNvbXBhdGliaWxpdHkgd2lsbCBhbHdheXMgYmUgZW5hYmxlZC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5lbmhhbmNlV2luZG93c0NvbXBhdGliaWxpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgb3Igbm90IFdpbmRvd3MgY29tcGF0aWJpbGl0eSBpcyBlbmFibGVkLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRlbmhhbmNlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zLCB0byBiZSByZW1vdmVkIGluIDQuMC4gRW5oYW5jZWQgV2luZG93cyBjb21wYXRpYmlsaXR5IHdpbGwgYWx3YXlzIGJlIGVuYWJsZWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbmhhbmNlV2luZG93c0NvbXBhdGliaWxpdHkoJGVuaGFuY2UpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICVzKCkgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIEVuaGFuY2VkIFdpbmRvd3MgY29tcGF0aWJpbGl0eSB3aWxsIGFsd2F5cyBiZSBlbmFibGVkLicsIF9fTUVUSE9EX18pLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICAkdGhpcy0+ZW5oYW5jZVdpbmRvd3NDb21wYXRpYmlsaXR5ID0gKGJvb2wpICRlbmhhbmNlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgc2lnY2hpbGQgY29tcGF0aWJpbGl0eSBtb2RlIGlzIGFjdGl2YXRlZCBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjMsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBTaWdjaGlsZCBjb21wYXRpYmlsaXR5IHdpbGwgYWx3YXlzIGJlIGVuYWJsZWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5KCkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gU2lnY2hpbGQgY29tcGF0aWJpbGl0eSB3aWxsIGFsd2F5cyBiZSBlbmFibGVkLicsIF9fTUVUSE9EX18pLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBY3RpdmF0ZXMgc2lnY2hpbGQgY29tcGF0aWJpbGl0eSBtb2RlLgogICAgICoKICAgICAqIFNpZ2NoaWxkIGNvbXBhdGliaWxpdHkgbW9kZSBpcyByZXF1aXJlZCB0byBnZXQgdGhlIGV4aXQgY29kZSBhbmQKICAgICAqIGRldGVybWluZSB0aGUgc3VjY2VzcyBvZiBhIHByb2Nlc3Mgd2hlbiBQSFAgaGFzIGJlZW4gY29tcGlsZWQgd2l0aAogICAgICogdGhlIC0tZW5hYmxlLXNpZ2NoaWxkIG9wdGlvbgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRlbmhhbmNlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zLCB0byBiZSByZW1vdmVkIGluIDQuMC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkoJGVuaGFuY2UpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICVzKCkgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIFNpZ2NoaWxkIGNvbXBhdGliaWxpdHkgd2lsbCBhbHdheXMgYmUgZW5hYmxlZC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgPSAoYm9vbCkgJGVuaGFuY2U7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgd2hldGhlciBlbnZpcm9ubWVudCB2YXJpYWJsZXMgd2lsbCBiZSBpbmhlcml0ZWQgb3Igbm90LgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpbmhlcml0RW52CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5oZXJpdEVudmlyb25tZW50VmFyaWFibGVzKCRpbmhlcml0RW52ID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoISRpbmhlcml0RW52KSB7CiAgICAgICAgICAgIEB0cmlnZ2VyX2Vycm9yKCdOb3QgaW5oZXJpdGluZyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBhbHdheXMgaGFwcGVuIGluIDQuMC4gU2V0ICJQcm9jZXNzOjppbmhlcml0RW52aXJvbm1lbnRWYXJpYWJsZXMoKSIgdG8gdHJ1ZSBpbnN0ZWFkLicsIFxFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW5oZXJpdEVudiA9IChib29sKSAkaW5oZXJpdEVudjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIGVudmlyb25tZW50IHZhcmlhYmxlcyB3aWxsIGJlIGluaGVyaXRlZCBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjMsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgd2lsbCBhbHdheXMgYmUgaW5oZXJpdGVkLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXJlRW52aXJvbm1lbnRWYXJpYWJsZXNJbmhlcml0ZWQoKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgd2lsbCBhbHdheXMgYmUgaW5oZXJpdGVkLicsIF9fTUVUSE9EX18pLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmluaGVyaXRFbnY7CiAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtcyBhIGNoZWNrIGJldHdlZW4gdGhlIHRpbWVvdXQgZGVmaW5pdGlvbiBhbmQgdGhlIHRpbWUgdGhlIHByb2Nlc3Mgc3RhcnRlZC4KICAgICAqCiAgICAgKiBJbiBjYXNlIHlvdSBydW4gYSBiYWNrZ3JvdW5kIHByb2Nlc3MgKHdpdGggdGhlIHN0YXJ0IG1ldGhvZCksIHlvdSBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhpcyBtZXRob2QgcmVndWxhcmx5IHRvIGVuc3VyZSB0aGUgcHJvY2VzcyB0aW1lb3V0CiAgICAgKgogICAgICogQHRocm93cyBQcm9jZXNzVGltZWRPdXRFeGNlcHRpb24gSW4gY2FzZSB0aGUgdGltZW91dCB3YXMgcmVhY2hlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2tUaW1lb3V0KCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6U1RBVFVTX1NUQVJURUQgIT09ICR0aGlzLT5zdGF0dXMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT50aW1lb3V0ICYmICR0aGlzLT50aW1lb3V0IDwgbWljcm90aW1lKHRydWUpIC0gJHRoaXMtPnN0YXJ0dGltZSkgewogICAgICAgICAgICAkdGhpcy0+c3RvcCgwKTsKCiAgICAgICAgICAgIHRocm93IG5ldyBQcm9jZXNzVGltZWRPdXRFeGNlcHRpb24oJHRoaXMsIFByb2Nlc3NUaW1lZE91dEV4Y2VwdGlvbjo6VFlQRV9HRU5FUkFMKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+aWRsZVRpbWVvdXQgJiYgJHRoaXMtPmlkbGVUaW1lb3V0IDwgbWljcm90aW1lKHRydWUpIC0gJHRoaXMtPmxhc3RPdXRwdXRUaW1lKSB7CiAgICAgICAgICAgICR0aGlzLT5zdG9wKDApOwoKICAgICAgICAgICAgdGhyb3cgbmV3IFByb2Nlc3NUaW1lZE91dEV4Y2VwdGlvbigkdGhpcywgUHJvY2Vzc1RpbWVkT3V0RXhjZXB0aW9uOjpUWVBFX0lETEUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBQVFkgaXMgc3VwcG9ydGVkIG9uIHRoZSBjdXJyZW50IG9wZXJhdGluZyBzeXN0ZW0uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNQdHlTdXBwb3J0ZWQoKQogICAgewogICAgICAgIHN0YXRpYyAkcmVzdWx0OwoKICAgICAgICBpZiAobnVsbCAhPT0gJHJlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICByZXR1cm4gJHJlc3VsdCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQgPSAoYm9vbCkgQHByb2Nfb3BlbignZWNobyAxID4vZGV2L251bGwnLCBbWydwdHknXSwgWydwdHknXSwgWydwdHknXV0sICRwaXBlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIHRoZSBkZXNjcmlwdG9ycyBuZWVkZWQgYnkgdGhlIHByb2Nfb3Blbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RGVzY3JpcHRvcnMoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aW5wdXQgaW5zdGFuY2VvZiBcSXRlcmF0b3IpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0LT5yZXdpbmQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzUGlwZXMgPSBuZXcgV2luZG93c1BpcGVzKCR0aGlzLT5pbnB1dCwgISR0aGlzLT5vdXRwdXREaXNhYmxlZCB8fCAkdGhpcy0+aGFzQ2FsbGJhY2spOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzUGlwZXMgPSBuZXcgVW5peFBpcGVzKCR0aGlzLT5pc1R0eSgpLCAkdGhpcy0+aXNQdHkoKSwgJHRoaXMtPmlucHV0LCAhJHRoaXMtPm91dHB1dERpc2FibGVkIHx8ICR0aGlzLT5oYXNDYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NQaXBlcy0+Z2V0RGVzY3JpcHRvcnMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEJ1aWxkcyB1cCB0aGUgY2FsbGJhY2sgdXNlZCBieSB3YWl0KCkuCiAgICAgKgogICAgICogVGhlIGNhbGxiYWNrcyBhZGRzIGFsbCBvY2N1cnJlZCBvdXRwdXQgdG8gdGhlIHNwZWNpZmljIGJ1ZmZlciBhbmQgY2FsbHMKICAgICAqIHRoZSB1c2VyIGNhbGxiYWNrIChpZiBwcmVzZW50KSB3aXRoIHRoZSByZWNlaXZlZCBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJGNhbGxiYWNrIFRoZSB1c2VyIGRlZmluZWQgUEhQIGNhbGxiYWNrCiAgICAgKgogICAgICogQHJldHVybiBcQ2xvc3VyZSBBIFBIUCBjbG9zdXJlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBidWlsZENhbGxiYWNrKGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXREaXNhYmxlZCkgewogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCR0eXBlLCAkZGF0YSkgdXNlICgkY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIGlmIChudWxsICE9PSAkY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgICAgICBcY2FsbF91c2VyX2Z1bmMoJGNhbGxiYWNrLCAkdHlwZSwgJGRhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgJG91dCA9IHNlbGY6Ok9VVDsKCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkdHlwZSwgJGRhdGEpIHVzZSAoJGNhbGxiYWNrLCAkb3V0KSB7CiAgICAgICAgICAgIGlmICgkb3V0ID09ICR0eXBlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkT3V0cHV0KCRkYXRhKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvck91dHB1dCgkZGF0YSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChudWxsICE9PSAkY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIFxjYWxsX3VzZXJfZnVuYygkY2FsbGJhY2ssICR0eXBlLCAkZGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIC8qKgogICAgICogVXBkYXRlcyB0aGUgc3RhdHVzIG9mIHRoZSBwcm9jZXNzLCByZWFkcyBwaXBlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkYmxvY2tpbmcgV2hldGhlciB0byB1c2UgYSBibG9ja2luZyByZWFkIGNhbGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZVN0YXR1cygkYmxvY2tpbmcpCiAgICB7CiAgICAgICAgaWYgKHNlbGY6OlNUQVRVU19TVEFSVEVEICE9PSAkdGhpcy0+c3RhdHVzKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb24gPSBwcm9jX2dldF9zdGF0dXMoJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICRydW5uaW5nID0gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsncnVubmluZyddOwoKICAgICAgICAkdGhpcy0+cmVhZFBpcGVzKCRydW5uaW5nICYmICRibG9ja2luZywgJ1xcJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgfHwgISRydW5uaW5nKTsKCiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja1N0YXR1cyAmJiAkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSAmJiAkdGhpcy0+aXNTaWdjaGlsZEVuYWJsZWQoKSkgewogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uID0gJHRoaXMtPmZhbGxiYWNrU3RhdHVzICsgJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvbjsKICAgICAgICB9CgogICAgICAgIGlmICghJHJ1bm5pbmcpIHsKICAgICAgICAgICAgJHRoaXMtPmNsb3NlKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIFBIUCBoYXMgYmVlbiBjb21waWxlZCB3aXRoIHRoZSAnLS1lbmFibGUtc2lnY2hpbGQnIG9wdGlvbiBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc1NpZ2NoaWxkRW5hYmxlZCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09IHNlbGY6OiRzaWdjaGlsZCkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHNpZ2NoaWxkOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcZnVuY3Rpb25fZXhpc3RzKCdwaHBpbmZvJykgfHwgXGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokc2lnY2hpbGQgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIG9iX3N0YXJ0KCk7CiAgICAgICAgcGhwaW5mbyhcSU5GT19HRU5FUkFMKTsKCiAgICAgICAgcmV0dXJuIHNlbGY6OiRzaWdjaGlsZCA9IGZhbHNlICE9PSBzdHJwb3Mob2JfZ2V0X2NsZWFuKCksICctLWVuYWJsZS1zaWdjaGlsZCcpOwogICAgfQoKICAgIC8qKgogICAgICogUmVhZHMgcGlwZXMgZm9yIHRoZSBmcmVzaGVzdCBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2FsbGVyICAgVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0aGF0IG5lZWRzIGZyZXNoIG91dHB1dHMKICAgICAqIEBwYXJhbSBib29sICAgJGJsb2NraW5nIFdoZXRoZXIgdG8gdXNlIGJsb2NraW5nIGNhbGxzIG9yIG5vdAogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gaW4gY2FzZSBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQgb3IgcHJvY2VzcyBpcyBub3Qgc3RhcnRlZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlYWRQaXBlc0Zvck91dHB1dCgkY2FsbGVyLCAkYmxvY2tpbmcgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPm91dHB1dERpc2FibGVkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignT3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJlcXVpcmVQcm9jZXNzSXNTdGFydGVkKCRjYWxsZXIpOwoKICAgICAgICAkdGhpcy0+dXBkYXRlU3RhdHVzKCRibG9ja2luZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgYW5kIHJldHVybnMgdGhlIGZpbHRlcmVkIHRpbWVvdXQuCiAgICAgKgogICAgICogQHBhcmFtIGludHxmbG9hdHxudWxsICR0aW1lb3V0CiAgICAgKgogICAgICogQHJldHVybiBmbG9hdHxudWxsCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIHRpbWVvdXQgaXMgYSBuZWdhdGl2ZSBudW1iZXIKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZVRpbWVvdXQoJHRpbWVvdXQpCiAgICB7CiAgICAgICAgJHRpbWVvdXQgPSAoZmxvYXQpICR0aW1lb3V0OwoKICAgICAgICBpZiAoMC4wID09PSAkdGltZW91dCkgewogICAgICAgICAgICAkdGltZW91dCA9IG51bGw7CiAgICAgICAgfSBlbHNlaWYgKCR0aW1lb3V0IDwgMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGUgdGltZW91dCB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgcG9zaXRpdmUgaW50ZWdlciBvciBmbG9hdCBudW1iZXIuJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRpbWVvdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkcyBwaXBlcywgZXhlY3V0ZXMgY2FsbGJhY2suCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGJsb2NraW5nIFdoZXRoZXIgdG8gdXNlIGJsb2NraW5nIGNhbGxzIG9yIG5vdAogICAgICogQHBhcmFtIGJvb2wgJGNsb3NlICAgIFdoZXRoZXIgdG8gY2xvc2UgZmlsZSBoYW5kbGVzIG9yIG5vdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlYWRQaXBlcygkYmxvY2tpbmcsICRjbG9zZSkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPnByb2Nlc3NQaXBlcy0+cmVhZEFuZFdyaXRlKCRibG9ja2luZywgJGNsb3NlKTsKCiAgICAgICAgJGNhbGxiYWNrID0gJHRoaXMtPmNhbGxiYWNrOwogICAgICAgIGZvcmVhY2ggKCRyZXN1bHQgYXMgJHR5cGUgPT4gJGRhdGEpIHsKICAgICAgICAgICAgaWYgKDMgIT09ICR0eXBlKSB7CiAgICAgICAgICAgICAgICAkY2FsbGJhY2soc2VsZjo6U1RET1VUID09PSAkdHlwZSA/IHNlbGY6Ok9VVCA6IHNlbGY6OkVSUiwgJGRhdGEpOwogICAgICAgICAgICB9IGVsc2VpZiAoIWlzc2V0KCR0aGlzLT5mYWxsYmFja1N0YXR1c1snc2lnbmFsZWQnXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja1N0YXR1c1snZXhpdGNvZGUnXSA9IChpbnQpICRkYXRhOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2xvc2VzIHByb2Nlc3MgcmVzb3VyY2UsIGNsb3NlcyBmaWxlIGhhbmRsZXMsIHNldHMgdGhlIGV4aXRjb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBleGl0Y29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNsb3NlKCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvY2Vzc1BpcGVzLT5jbG9zZSgpOwogICAgICAgIGlmIChcaXNfcmVzb3VyY2UoJHRoaXMtPnByb2Nlc3MpKSB7CiAgICAgICAgICAgIHByb2NfY2xvc2UoJHRoaXMtPnByb2Nlc3MpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZXhpdGNvZGUgPSAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWydleGl0Y29kZSddOwogICAgICAgICR0aGlzLT5zdGF0dXMgPSBzZWxmOjpTVEFUVVNfVEVSTUlOQVRFRDsKCiAgICAgICAgaWYgKC0xID09PSAkdGhpcy0+ZXhpdGNvZGUpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3NpZ25hbGVkJ10gJiYgMCA8ICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3Rlcm1zaWcnXSkgewogICAgICAgICAgICAgICAgLy8gaWYgcHJvY2VzcyBoYXMgYmVlbiBzaWduYWxlZCwgbm8gZXhpdGNvZGUgYnV0IGEgdmFsaWQgdGVybXNpZywgYXBwbHkgVW5peCBjb252ZW50aW9uCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXhpdGNvZGUgPSAxMjggKyAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWyd0ZXJtc2lnJ107CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSAmJiAkdGhpcy0+aXNTaWdjaGlsZEVuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsnc2lnbmFsZWQnXSA9IHRydWU7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWyd0ZXJtc2lnJ10gPSAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gRnJlZSBtZW1vcnkgZnJvbSBzZWxmLXJlZmVyZW5jZSBjYWxsYmFjayBjcmVhdGVkIGJ5IGJ1aWxkQ2FsbGJhY2sKICAgICAgICAvLyBEb2luZyBzbyBpbiBvdGhlciBjb250ZXh0cyBsaWtlIF9fZGVzdHJ1Y3Qgb3IgYnkgZ2FyYmFnZSBjb2xsZWN0b3IgaXMgaW5lZmZlY3RpdmUKICAgICAgICAvLyBOb3cgcGlwZXMgYXJlIGNsb3NlZCwgc28gdGhlIGNhbGxiYWNrIGlzIG5vIGxvbmdlciBuZWNlc3NhcnkKICAgICAgICAkdGhpcy0+Y2FsbGJhY2sgPSBudWxsOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4aXRjb2RlOwogICAgfQoKICAgIC8qKgogICAgICogUmVzZXRzIGRhdGEgcmVsYXRlZCB0byB0aGUgbGF0ZXN0IHJ1biBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXNldFByb2Nlc3NEYXRhKCkKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnR0aW1lID0gbnVsbDsKICAgICAgICAkdGhpcy0+Y2FsbGJhY2sgPSBudWxsOwogICAgICAgICR0aGlzLT5leGl0Y29kZSA9IG51bGw7CiAgICAgICAgJHRoaXMtPmZhbGxiYWNrU3RhdHVzID0gW107CiAgICAgICAgJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvbiA9IG51bGw7CiAgICAgICAgJHRoaXMtPnN0ZG91dCA9IGZvcGVuKCdwaHA6Ly90ZW1wL21heG1lbW9yeTonLigxMDI0ICogMTAyNCksICd3K2InKTsKICAgICAgICAkdGhpcy0+c3RkZXJyID0gZm9wZW4oJ3BocDovL3RlbXAvbWF4bWVtb3J5OicuKDEwMjQgKiAxMDI0KSwgJ3crYicpOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gbnVsbDsKICAgICAgICAkdGhpcy0+bGF0ZXN0U2lnbmFsID0gbnVsbDsKICAgICAgICAkdGhpcy0+c3RhdHVzID0gc2VsZjo6U1RBVFVTX1JFQURZOwogICAgICAgICR0aGlzLT5pbmNyZW1lbnRhbE91dHB1dE9mZnNldCA9IDA7CiAgICAgICAgJHRoaXMtPmluY3JlbWVudGFsRXJyb3JPdXRwdXRPZmZzZXQgPSAwOwogICAgfQoKICAgIC8qKgogICAgICogU2VuZHMgYSBQT1NJWCBzaWduYWwgdG8gdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogQHBhcmFtIGludCAgJHNpZ25hbCAgICAgICAgIEEgdmFsaWQgUE9TSVggc2lnbmFsIChzZWUgaHR0cHM6Ly9waHAubmV0L3BjbnRsLmNvbnN0YW50cykKICAgICAqIEBwYXJhbSBib29sICR0aHJvd0V4Y2VwdGlvbiBXaGV0aGVyIHRvIHRocm93IGV4Y2VwdGlvbiBpbiBjYXNlIHNpZ25hbCBmYWlsZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB0aGUgc2lnbmFsIHdhcyBzZW50IHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiAgIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHJ1bm5pbmcKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIC0tZW5hYmxlLXNpZ2NoaWxkIGlzIGFjdGl2YXRlZCBhbmQgdGhlIHByb2Nlc3MgY2FuJ3QgYmUga2lsbGVkCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSBvZiBmYWlsdXJlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9TaWduYWwoJHNpZ25hbCwgJHRocm93RXhjZXB0aW9uKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkcGlkID0gJHRoaXMtPmdldFBpZCgpKSB7CiAgICAgICAgICAgIGlmICgkdGhyb3dFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQ2FuIG5vdCBzZW5kIHNpZ25hbCBvbiBhIG5vbiBydW5uaW5nIHByb2Nlc3MuJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICBleGVjKHNwcmludGYoJ3Rhc2traWxsIC9GIC9UIC9QSUQgJWQgMj4mMScsICRwaWQpLCAkb3V0cHV0LCAkZXhpdENvZGUpOwogICAgICAgICAgICBpZiAoJGV4aXRDb2RlICYmICR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICAgICAgaWYgKCR0aHJvd0V4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1VuYWJsZSB0byBraWxsIHRoZSBwcm9jZXNzICglcykuJywgaW1wbG9kZSgnICcsICRvdXRwdXQpKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSB8fCAhJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCkpIHsKICAgICAgICAgICAgICAgICRvayA9IEBwcm9jX3Rlcm1pbmF0ZSgkdGhpcy0+cHJvY2VzcywgJHNpZ25hbCk7CiAgICAgICAgICAgIH0gZWxzZWlmIChcZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9raWxsJykpIHsKICAgICAgICAgICAgICAgICRvayA9IEBwb3NpeF9raWxsKCRwaWQsICRzaWduYWwpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG9rID0gcHJvY19vcGVuKHNwcmludGYoJ2tpbGwgLSVkICVkJywgJHNpZ25hbCwgJHBpZCksIFsyID0+IFsncGlwZScsICd3J11dLCAkcGlwZXMpKSB7CiAgICAgICAgICAgICAgICAkb2sgPSBmYWxzZSA9PT0gZmdldHMoJHBpcGVzWzJdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRvaykgewogICAgICAgICAgICAgICAgaWYgKCR0aHJvd0V4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ0Vycm9yIHdoaWxlIHNlbmRpbmcgc2lnbmFsIGAlc2AuJywgJHNpZ25hbCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxhdGVzdFNpZ25hbCA9IChpbnQpICRzaWduYWw7CiAgICAgICAgJHRoaXMtPmZhbGxiYWNrU3RhdHVzWydzaWduYWxlZCddID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+ZmFsbGJhY2tTdGF0dXNbJ2V4aXRjb2RlJ10gPSAtMTsKICAgICAgICAkdGhpcy0+ZmFsbGJhY2tTdGF0dXNbJ3Rlcm1zaWcnXSA9ICR0aGlzLT5sYXRlc3RTaWduYWw7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcHJlcGFyZVdpbmRvd3NDb21tYW5kTGluZSgkY21kLCBhcnJheSAmJGVudikKICAgIHsKICAgICAgICAkdWlkID0gdW5pcWlkKCcnLCB0cnVlKTsKICAgICAgICAkdmFyQ291bnQgPSAwOwogICAgICAgICR2YXJDYWNoZSA9IFtdOwogICAgICAgICRjbWQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCiAgICAgICAgICAgICcvIig/OigKICAgICAgICAgICAgICAgIFteIiUhXl0qKwogICAgICAgICAgICAgICAgKD86CiAgICAgICAgICAgICAgICAgICAgKD86ICFMRiEgfCAiKD86XF5bJSFeXSk/KyIgKQogICAgICAgICAgICAgICAgICAgIFteIiUhXl0qKwogICAgICAgICAgICAgICAgKSsrCiAgICAgICAgICAgICkgfCBbXiJdKisgKSIveCcsCiAgICAgICAgICAgIGZ1bmN0aW9uICgkbSkgdXNlICgmJGVudiwgJiR2YXJDYWNoZSwgJiR2YXJDb3VudCwgJHVpZCkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkbVsxXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJG1bMF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHZhckNhY2hlWyRtWzBdXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhckNhY2hlWyRtWzBdXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCR2YWx1ZSA9ICRtWzFdLCAiXDAiKSkgewogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IHN0cl9yZXBsYWNlKCJcMCIsICc/JywgJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gc3RycGJyaygkdmFsdWUsICJcIiUhXG4iKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAnIicuJHZhbHVlLiciJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdHJfcmVwbGFjZShbJyFMRiEnLCAnIl4hIicsICciXiUiJywgJyJeXiInLCAnIiInXSwgWyJcbiIsICchJywgJyUnLCAnXicsICciJ10sICR2YWx1ZSk7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAnIicucHJlZ19yZXBsYWNlKCcvKFxcXFwqKSIvJywgJyQxJDFcXCInLCAkdmFsdWUpLiciJzsKICAgICAgICAgICAgICAgICR2YXIgPSAkdWlkLisrJHZhckNvdW50OwoKICAgICAgICAgICAgICAgICRlbnZbJHZhcl0gPSAkdmFsdWU7CgogICAgICAgICAgICAgICAgcmV0dXJuICR2YXJDYWNoZVskbVswXV0gPSAnIScuJHZhci4nISc7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICRjbWQKICAgICAgICApOwoKICAgICAgICAkY21kID0gJ2NtZCAvVjpPTiAvRTpPTiAvRCAvQyAoJy5zdHJfcmVwbGFjZSgiXG4iLCAnICcsICRjbWQpLicpJzsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzc1BpcGVzLT5nZXRGaWxlcygpIGFzICRvZmZzZXQgPT4gJGZpbGVuYW1lKSB7CiAgICAgICAgICAgICRjbWQgLj0gJyAnLiRvZmZzZXQuJz4iJy4kZmlsZW5hbWUuJyInOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjbWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbnN1cmVzIHRoZSBwcm9jZXNzIGlzIHJ1bm5pbmcgb3IgdGVybWluYXRlZCwgdGhyb3dzIGEgTG9naWNFeGNlcHRpb24gaWYgdGhlIHByb2Nlc3MgaGFzIGEgbm90IHN0YXJ0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZnVuY3Rpb25OYW1lIFRoZSBmdW5jdGlvbiBuYW1lIHRoYXQgd2FzIGNhbGxlZAogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gaWYgdGhlIHByb2Nlc3MgaGFzIG5vdCBydW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXF1aXJlUHJvY2Vzc0lzU3RhcnRlZCgkZnVuY3Rpb25OYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlzU3RhcnRlZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdQcm9jZXNzIG11c3QgYmUgc3RhcnRlZCBiZWZvcmUgY2FsbGluZyAiJXMoKSIuJywgJGZ1bmN0aW9uTmFtZSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEVuc3VyZXMgdGhlIHByb2Nlc3MgaXMgdGVybWluYXRlZCwgdGhyb3dzIGEgTG9naWNFeGNlcHRpb24gaWYgdGhlIHByb2Nlc3MgaGFzIGEgc3RhdHVzIGRpZmZlcmVudCB0aGFuIGB0ZXJtaW5hdGVkYC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmdW5jdGlvbk5hbWUgVGhlIGZ1bmN0aW9uIG5hbWUgdGhhdCB3YXMgY2FsbGVkCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBpZiB0aGUgcHJvY2VzcyBpcyBub3QgeWV0IHRlcm1pbmF0ZWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXF1aXJlUHJvY2Vzc0lzVGVybWluYXRlZCgkZnVuY3Rpb25OYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlzVGVybWluYXRlZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdQcm9jZXNzIG11c3QgYmUgdGVybWluYXRlZCBiZWZvcmUgY2FsbGluZyAiJXMoKSIuJywgJGZ1bmN0aW9uTmFtZSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEVzY2FwZXMgYSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIHNoZWxsIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFyZ3VtZW50IFRoZSBhcmd1bWVudCB0aGF0IHdpbGwgYmUgZXNjYXBlZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBlc2NhcGVkIGFyZ3VtZW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXNjYXBlQXJndW1lbnQoJGFyZ3VtZW50KQogICAgewogICAgICAgIGlmICgnXFwnICE9PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICByZXR1cm4gIiciLnN0cl9yZXBsYWNlKCInIiwgIidcXCcnIiwgJGFyZ3VtZW50KS4iJyI7CiAgICAgICAgfQogICAgICAgIGlmICgnJyA9PT0gJGFyZ3VtZW50ID0gKHN0cmluZykgJGFyZ3VtZW50KSB7CiAgICAgICAgICAgIHJldHVybiAnIiInOwogICAgICAgIH0KICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkYXJndW1lbnQsICJcMCIpKSB7CiAgICAgICAgICAgICRhcmd1bWVudCA9IHN0cl9yZXBsYWNlKCJcMCIsICc/JywgJGFyZ3VtZW50KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvW1wvKCklIV4iPD4mfFxzXS8nLCAkYXJndW1lbnQpKSB7CiAgICAgICAgICAgIHJldHVybiAkYXJndW1lbnQ7CiAgICAgICAgfQogICAgICAgICRhcmd1bWVudCA9IHByZWdfcmVwbGFjZSgnLyhcXFxcKykkLycsICckMSQxJywgJGFyZ3VtZW50KTsKCiAgICAgICAgcmV0dXJuICciJy5zdHJfcmVwbGFjZShbJyInLCAnXicsICclJywgJyEnLCAiXG4iXSwgWyciIicsICciXl4iJywgJyJeJSInLCAnIl4hIicsICchTEYhJ10sICRhcmd1bWVudCkuJyInOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RGVmYXVsdEVudigpCiAgICB7CiAgICAgICAgJGVudiA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkX1NFUlZFUiBhcyAkayA9PiAkdikgewogICAgICAgICAgICBpZiAoXGlzX3N0cmluZygkdikgJiYgZmFsc2UgIT09ICR2ID0gZ2V0ZW52KCRrKSkgewogICAgICAgICAgICAgICAgJGVudlska10gPSAkdjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJF9FTlYgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgaWYgKFxpc19zdHJpbmcoJHYpKSB7CiAgICAgICAgICAgICAgICAkZW52WyRrXSA9ICR2OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGVudjsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgovKioKICogQGRlcHJlY2F0ZWQgMi44LjAgRXh0ZXJuYWwgdXNhZ2Ugb2YgUmVqZWN0ZWRQcm9taXNlIGlzIGRlcHJlY2F0ZWQsIHVzZSBgcmVqZWN0KClgIGluc3RlYWQuCiAqLwpjbGFzcyBSZWplY3RlZFByb21pc2UgaW1wbGVtZW50cyBFeHRlbmRlZFByb21pc2VJbnRlcmZhY2UsIENhbmNlbGxhYmxlUHJvbWlzZUludGVyZmFjZQp7CiAgICBwcml2YXRlICRyZWFzb247CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRyZWFzb24gPSBudWxsKQogICAgewogICAgICAgIGlmICgkcmVhc29uIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignWW91IGNhbm5vdCBjcmVhdGUgUmVhY3RcUHJvbWlzZVxSZWplY3RlZFByb21pc2Ugd2l0aCBhIHByb21pc2UuIFVzZSBSZWFjdFxQcm9taXNlXHJlamVjdCgkcHJvbWlzZU9yVmFsdWUpIGluc3RlYWQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVhc29uID0gJHJlYXNvbjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdGhlbihjYWxsYWJsZSAkb25GdWxmaWxsZWQgPSBudWxsLCBjYWxsYWJsZSAkb25SZWplY3RlZCA9IG51bGwsIGNhbGxhYmxlICRvblByb2dyZXNzID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJG9uUmVqZWN0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoJG9uUmVqZWN0ZWQoJHRoaXMtPnJlYXNvbikpOwogICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGV4Y2VwdGlvbikgewogICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkZXhjZXB0aW9uKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRleGNlcHRpb24pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWplY3RlZFByb21pc2UoJGV4Y2VwdGlvbik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBkb25lKGNhbGxhYmxlICRvbkZ1bGZpbGxlZCA9IG51bGwsIGNhbGxhYmxlICRvblJlamVjdGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUHJvZ3Jlc3MgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkb25SZWplY3RlZCkgewogICAgICAgICAgICB0aHJvdyBVbmhhbmRsZWRSZWplY3Rpb25FeGNlcHRpb246OnJlc29sdmUoJHRoaXMtPnJlYXNvbik7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gJG9uUmVqZWN0ZWQoJHRoaXMtPnJlYXNvbik7CgogICAgICAgIGlmICgkcmVzdWx0IGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICB0aHJvdyBVbmhhbmRsZWRSZWplY3Rpb25FeGNlcHRpb246OnJlc29sdmUoJHJlc3VsdC0+cmVhc29uKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcmVzdWx0IGluc3RhbmNlb2YgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRyZXN1bHQtPmRvbmUoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG90aGVyd2lzZShjYWxsYWJsZSAkb25SZWplY3RlZCkKICAgIHsKICAgICAgICBpZiAoIV9jaGVja1R5cGVoaW50KCRvblJlamVjdGVkLCAkdGhpcy0+cmVhc29uKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4obnVsbCwgJG9uUmVqZWN0ZWQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhbHdheXMoY2FsbGFibGUgJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4obnVsbCwgZnVuY3Rpb24gKCRyZWFzb24pIHVzZSAoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWRPclJlamVjdGVkKCkpLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHJlYXNvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWplY3RlZFByb21pc2UoJHJlYXNvbik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzcyhjYWxsYWJsZSAkb25Qcm9ncmVzcykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNhbmNlbCgpCiAgICB7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBSZWFjdFxQcm9taXNlOwoKY2xhc3MgRGVmZXJyZWQgaW1wbGVtZW50cyBQcm9taXNvckludGVyZmFjZQp7CiAgICBwcml2YXRlICRwcm9taXNlOwogICAgcHJpdmF0ZSAkcmVzb2x2ZUNhbGxiYWNrOwogICAgcHJpdmF0ZSAkcmVqZWN0Q2FsbGJhY2s7CiAgICBwcml2YXRlICRub3RpZnlDYWxsYmFjazsKICAgIHByaXZhdGUgJGNhbmNlbGxlcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoY2FsbGFibGUgJGNhbmNlbGxlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9ICRjYW5jZWxsZXI7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHByb21pc2UoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cHJvbWlzZSkgewogICAgICAgICAgICAkdGhpcy0+cHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlc29sdmVDYWxsYmFjayA9ICRyZXNvbHZlOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlamVjdENhbGxiYWNrICA9ICRyZWplY3Q7CiAgICAgICAgICAgICAgICAkdGhpcy0+bm90aWZ5Q2FsbGJhY2sgID0gJG5vdGlmeTsKICAgICAgICAgICAgfSwgJHRoaXMtPmNhbmNlbGxlcik7CiAgICAgICAgICAgICR0aGlzLT5jYW5jZWxsZXIgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9taXNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZXNvbHZlKCR2YWx1ZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb21pc2UoKTsKCiAgICAgICAgXGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5yZXNvbHZlQ2FsbGJhY2ssICR2YWx1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlamVjdCgkcmVhc29uID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvbWlzZSgpOwoKICAgICAgICBcY2FsbF91c2VyX2Z1bmMoJHRoaXMtPnJlamVjdENhbGxiYWNrLCAkcmVhc29uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXByZWNhdGVkIDIuNi4wIFByb2dyZXNzIHN1cHBvcnQgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGFueW1vcmUuCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHVwZGF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm90aWZ5KCR1cGRhdGUgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5wcm9taXNlKCk7CgogICAgICAgIFxjYWxsX3VzZXJfZnVuYygkdGhpcy0+bm90aWZ5Q2FsbGJhY2ssICR1cGRhdGUpOwogICAgfQoKICAgIC8qKgogICAgICogQGRlcHJlY2F0ZWQgMi4yLjAKICAgICAqIEBzZWUgRGVmZXJyZWQ6Om5vdGlmeSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzcygkdXBkYXRlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+bm90aWZ5KCR1cGRhdGUpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCi8qKgogKiBDcmVhdGVzIGEgcHJvbWlzZSBmb3IgdGhlIHN1cHBsaWVkIGAkcHJvbWlzZU9yVmFsdWVgLgogKgogKiBJZiBgJHByb21pc2VPclZhbHVlYCBpcyBhIHZhbHVlLCBpdCB3aWxsIGJlIHRoZSByZXNvbHV0aW9uIHZhbHVlIG9mIHRoZQogKiByZXR1cm5lZCBwcm9taXNlLgogKgogKiBJZiBgJHByb21pc2VPclZhbHVlYCBpcyBhIHRoZW5hYmxlIChhbnkgb2JqZWN0IHRoYXQgcHJvdmlkZXMgYSBgdGhlbigpYCBtZXRob2QpLAogKiBhIHRydXN0ZWQgcHJvbWlzZSB0aGF0IGZvbGxvd3MgdGhlIHN0YXRlIG9mIHRoZSB0aGVuYWJsZSBpcyByZXR1cm5lZC4KICoKICogSWYgYCRwcm9taXNlT3JWYWx1ZWAgaXMgYSBwcm9taXNlLCBpdCB3aWxsIGJlIHJldHVybmVkIGFzIGlzLgogKgogKiBAcGFyYW0gbWl4ZWQgJHByb21pc2VPclZhbHVlCiAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogKi8KZnVuY3Rpb24gcmVzb2x2ZSgkcHJvbWlzZU9yVmFsdWUgPSBudWxsKQp7CiAgICBpZiAoJHByb21pc2VPclZhbHVlIGluc3RhbmNlb2YgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgcmV0dXJuICRwcm9taXNlT3JWYWx1ZTsKICAgIH0KCiAgICAvLyBDaGVjayBpc19vYmplY3QoKSBmaXJzdCB0byBhdm9pZCBtZXRob2RfZXhpc3RzKCkgdHJpZ2dlcmluZwogICAgLy8gY2xhc3MgYXV0b2xvYWRlcnMgaWYgJHByb21pc2VPclZhbHVlIGlzIGEgc3RyaW5nLgogICAgaWYgKFxpc19vYmplY3QoJHByb21pc2VPclZhbHVlKSAmJiBcbWV0aG9kX2V4aXN0cygkcHJvbWlzZU9yVmFsdWUsICd0aGVuJykpIHsKICAgICAgICAkY2FuY2VsbGVyID0gbnVsbDsKCiAgICAgICAgaWYgKFxtZXRob2RfZXhpc3RzKCRwcm9taXNlT3JWYWx1ZSwgJ2NhbmNlbCcpKSB7CiAgICAgICAgICAgICRjYW5jZWxsZXIgPSBbJHByb21pc2VPclZhbHVlLCAnY2FuY2VsJ107CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKCRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KSB1c2UgKCRwcm9taXNlT3JWYWx1ZSkgewogICAgICAgICAgICAkcHJvbWlzZU9yVmFsdWUtPnRoZW4oJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpOwogICAgICAgIH0sICRjYW5jZWxsZXIpOwogICAgfQoKICAgIHJldHVybiBuZXcgRnVsZmlsbGVkUHJvbWlzZSgkcHJvbWlzZU9yVmFsdWUpOwp9CgovKioKICogQ3JlYXRlcyBhIHJlamVjdGVkIHByb21pc2UgZm9yIHRoZSBzdXBwbGllZCBgJHByb21pc2VPclZhbHVlYC4KICoKICogSWYgYCRwcm9taXNlT3JWYWx1ZWAgaXMgYSB2YWx1ZSwgaXQgd2lsbCBiZSB0aGUgcmVqZWN0aW9uIHZhbHVlIG9mIHRoZQogKiByZXR1cm5lZCBwcm9taXNlLgogKgogKiBJZiBgJHByb21pc2VPclZhbHVlYCBpcyBhIHByb21pc2UsIGl0cyBjb21wbGV0aW9uIHZhbHVlIHdpbGwgYmUgdGhlIHJlamVjdGVkCiAqIHZhbHVlIG9mIHRoZSByZXR1cm5lZCBwcm9taXNlLgogKgogKiBUaGlzIGNhbiBiZSB1c2VmdWwgaW4gc2l0dWF0aW9ucyB3aGVyZSB5b3UgbmVlZCB0byByZWplY3QgYSBwcm9taXNlIHdpdGhvdXQKICogdGhyb3dpbmcgYW4gZXhjZXB0aW9uLiBGb3IgZXhhbXBsZSwgaXQgYWxsb3dzIHlvdSB0byBwcm9wYWdhdGUgYSByZWplY3Rpb24gd2l0aAogKiB0aGUgdmFsdWUgb2YgYW5vdGhlciBwcm9taXNlLgogKgogKiBAcGFyYW0gbWl4ZWQgJHByb21pc2VPclZhbHVlCiAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogKi8KZnVuY3Rpb24gcmVqZWN0KCRwcm9taXNlT3JWYWx1ZSA9IG51bGwpCnsKICAgIGlmICgkcHJvbWlzZU9yVmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgcmV0dXJuIHJlc29sdmUoJHByb21pc2VPclZhbHVlKS0+dGhlbihmdW5jdGlvbiAoJHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVqZWN0ZWRQcm9taXNlKCR2YWx1ZSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcmV0dXJuIG5ldyBSZWplY3RlZFByb21pc2UoJHByb21pc2VPclZhbHVlKTsKfQoKLyoqCiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIG9ubHkgb25jZSBhbGwgdGhlIGl0ZW1zIGluCiAqIGAkcHJvbWlzZXNPclZhbHVlc2AgaGF2ZSByZXNvbHZlZC4gVGhlIHJlc29sdXRpb24gdmFsdWUgb2YgdGhlIHJldHVybmVkIHByb21pc2UKICogd2lsbCBiZSBhbiBhcnJheSBjb250YWluaW5nIHRoZSByZXNvbHV0aW9uIHZhbHVlcyBvZiBlYWNoIG9mIHRoZSBpdGVtcyBpbgogKiBgJHByb21pc2VzT3JWYWx1ZXNgLgogKgogKiBAcGFyYW0gYXJyYXkgJHByb21pc2VzT3JWYWx1ZXMKICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAqLwpmdW5jdGlvbiBhbGwoJHByb21pc2VzT3JWYWx1ZXMpCnsKICAgIHJldHVybiBtYXAoJHByb21pc2VzT3JWYWx1ZXMsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgcmV0dXJuICR2YWw7CiAgICB9KTsKfQoKLyoqCiAqIEluaXRpYXRlcyBhIGNvbXBldGl0aXZlIHJhY2UgdGhhdCBhbGxvd3Mgb25lIHdpbm5lci4gUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggaXMKICogcmVzb2x2ZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSBmaXJzdCBzZXR0bGVkIHByb21pc2UgcmVzb2x2ZXMuCiAqCiAqIFRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmVjb21lICoqaW5maW5pdGVseSBwZW5kaW5nKiogaWYgIGAkcHJvbWlzZXNPclZhbHVlc2AKICogY29udGFpbnMgMCBpdGVtcy4KICoKICogQHBhcmFtIGFycmF5ICRwcm9taXNlc09yVmFsdWVzCiAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogKi8KZnVuY3Rpb24gcmFjZSgkcHJvbWlzZXNPclZhbHVlcykKewogICAgJGNhbmNlbGxhdGlvblF1ZXVlID0gbmV3IENhbmNlbGxhdGlvblF1ZXVlKCk7CiAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VzT3JWYWx1ZXMpOwoKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHVzZSAoJHByb21pc2VzT3JWYWx1ZXMsICRjYW5jZWxsYXRpb25RdWV1ZSkgewogICAgICAgIHJlc29sdmUoJHByb21pc2VzT3JWYWx1ZXMpCiAgICAgICAgICAgIC0+ZG9uZShmdW5jdGlvbiAoJGFycmF5KSB1c2UgKCRjYW5jZWxsYXRpb25RdWV1ZSwgJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHsKICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJGFycmF5KSB8fCAhJGFycmF5KSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc29sdmUoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGFycmF5IGFzICRwcm9taXNlT3JWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICRjYW5jZWxsYXRpb25RdWV1ZS0+ZW5xdWV1ZSgkcHJvbWlzZU9yVmFsdWUpOwoKICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCRwcm9taXNlT3JWYWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgLT5kb25lKCRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgJHJlamVjdCwgJG5vdGlmeSk7CiAgICB9LCAkY2FuY2VsbGF0aW9uUXVldWUpOwp9CgovKioKICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIHJlc29sdmUgd2hlbiBhbnkgb25lIG9mIHRoZSBpdGVtcyBpbgogKiBgJHByb21pc2VzT3JWYWx1ZXNgIHJlc29sdmVzLiBUaGUgcmVzb2x1dGlvbiB2YWx1ZSBvZiB0aGUgcmV0dXJuZWQgcHJvbWlzZQogKiB3aWxsIGJlIHRoZSByZXNvbHV0aW9uIHZhbHVlIG9mIHRoZSB0cmlnZ2VyaW5nIGl0ZW0uCiAqCiAqIFRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgb25seSByZWplY3QgaWYgKmFsbCogaXRlbXMgaW4gYCRwcm9taXNlc09yVmFsdWVzYCBhcmUKICogcmVqZWN0ZWQuIFRoZSByZWplY3Rpb24gdmFsdWUgd2lsbCBiZSBhbiBhcnJheSBvZiBhbGwgcmVqZWN0aW9uIHJlYXNvbnMuCiAqCiAqIFRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYWxzbyByZWplY3Qgd2l0aCBhIGBSZWFjdFxQcm9taXNlXEV4Y2VwdGlvblxMZW5ndGhFeGNlcHRpb25gCiAqIGlmIGAkcHJvbWlzZXNPclZhbHVlc2AgY29udGFpbnMgMCBpdGVtcy4KICoKICogQHBhcmFtIGFycmF5ICRwcm9taXNlc09yVmFsdWVzCiAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogKi8KZnVuY3Rpb24gYW55KCRwcm9taXNlc09yVmFsdWVzKQp7CiAgICByZXR1cm4gc29tZSgkcHJvbWlzZXNPclZhbHVlcywgMSkKICAgICAgICAtPnRoZW4oZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgcmV0dXJuIFxhcnJheV9zaGlmdCgkdmFsKTsKICAgICAgICB9KTsKfQoKLyoqCiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdoZW4gYCRob3dNYW55YCBvZiB0aGUgc3VwcGxpZWQgaXRlbXMgaW4KICogYCRwcm9taXNlc09yVmFsdWVzYCByZXNvbHZlLiBUaGUgcmVzb2x1dGlvbiB2YWx1ZSBvZiB0aGUgcmV0dXJuZWQgcHJvbWlzZQogKiB3aWxsIGJlIGFuIGFycmF5IG9mIGxlbmd0aCBgJGhvd01hbnlgIGNvbnRhaW5pbmcgdGhlIHJlc29sdXRpb24gdmFsdWVzIG9mIHRoZQogKiB0cmlnZ2VyaW5nIGl0ZW1zLgogKgogKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIHJlamVjdCBpZiBpdCBiZWNvbWVzIGltcG9zc2libGUgZm9yIGAkaG93TWFueWAgaXRlbXMKICogdG8gcmVzb2x2ZSAodGhhdCBpcywgd2hlbiBgKGNvdW50KCRwcm9taXNlc09yVmFsdWVzKSAtICRob3dNYW55KSArIDFgIGl0ZW1zCiAqIHJlamVjdCkuIFRoZSByZWplY3Rpb24gdmFsdWUgd2lsbCBiZSBhbiBhcnJheSBvZgogKiBgKGNvdW50KCRwcm9taXNlc09yVmFsdWVzKSAtICRob3dNYW55KSArIDFgIHJlamVjdGlvbiByZWFzb25zLgogKgogKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGFsc28gcmVqZWN0IHdpdGggYSBgUmVhY3RcUHJvbWlzZVxFeGNlcHRpb25cTGVuZ3RoRXhjZXB0aW9uYAogKiBpZiBgJHByb21pc2VzT3JWYWx1ZXNgIGNvbnRhaW5zIGxlc3MgaXRlbXMgdGhhbiBgJGhvd01hbnlgLgogKgogKiBAcGFyYW0gYXJyYXkgJHByb21pc2VzT3JWYWx1ZXMKICogQHBhcmFtIGludCAkaG93TWFueQogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIHNvbWUoJHByb21pc2VzT3JWYWx1ZXMsICRob3dNYW55KQp7CiAgICAkY2FuY2VsbGF0aW9uUXVldWUgPSBuZXcgQ2FuY2VsbGF0aW9uUXVldWUoKTsKICAgICRjYW5jZWxsYXRpb25RdWV1ZS0+ZW5xdWV1ZSgkcHJvbWlzZXNPclZhbHVlcyk7CgogICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgdXNlICgkcHJvbWlzZXNPclZhbHVlcywgJGhvd01hbnksICRjYW5jZWxsYXRpb25RdWV1ZSkgewogICAgICAgIHJlc29sdmUoJHByb21pc2VzT3JWYWx1ZXMpCiAgICAgICAgICAgIC0+ZG9uZShmdW5jdGlvbiAoJGFycmF5KSB1c2UgKCRob3dNYW55LCAkY2FuY2VsbGF0aW9uUXVldWUsICRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KSB7CiAgICAgICAgICAgICAgICBpZiAoIVxpc19hcnJheSgkYXJyYXkpIHx8ICRob3dNYW55IDwgMSkgewogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKFtdKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGxlbiA9IFxjb3VudCgkYXJyYXkpOwoKICAgICAgICAgICAgICAgIGlmICgkbGVuIDwgJGhvd01hbnkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uXExlbmd0aEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgXHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSW5wdXQgYXJyYXkgbXVzdCBjb250YWluIGF0IGxlYXN0ICVkIGl0ZW0lcyBidXQgY29udGFpbnMgb25seSAlcyBpdGVtJXMuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRob3dNYW55LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMSA9PT0gJGhvd01hbnkgPyAnJyA6ICdzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAxID09PSAkbGVuID8gJycgOiAncycKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRvUmVzb2x2ZSA9ICRob3dNYW55OwogICAgICAgICAgICAgICAgJHRvUmVqZWN0ICA9ICgkbGVuIC0gJHRvUmVzb2x2ZSkgKyAxOwogICAgICAgICAgICAgICAgJHZhbHVlcyAgICA9IFtdOwogICAgICAgICAgICAgICAgJHJlYXNvbnMgICA9IFtdOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAkaSA9PiAkcHJvbWlzZU9yVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkZnVsZmlsbGVyID0gZnVuY3Rpb24gKCR2YWwpIHVzZSAoJGksICYkdmFsdWVzLCAmJHRvUmVzb2x2ZSwgJHRvUmVqZWN0LCAkcmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRvUmVzb2x2ZSA8IDEgfHwgJHRvUmVqZWN0IDwgMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkdmFsdWVzWyRpXSA9ICR2YWw7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gLS0kdG9SZXNvbHZlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVzb2x2ZSgkdmFsdWVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgICAgICRyZWplY3RlciA9IGZ1bmN0aW9uICgkcmVhc29uKSB1c2UgKCRpLCAmJHJlYXNvbnMsICYkdG9SZWplY3QsICR0b1Jlc29sdmUsICRyZWplY3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0b1Jlc29sdmUgPCAxIHx8ICR0b1JlamVjdCA8IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbnNbJGldID0gJHJlYXNvbjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAtLSR0b1JlamVjdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlamVjdCgkcmVhc29ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VPclZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgkcHJvbWlzZU9yVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIC0+ZG9uZSgkZnVsZmlsbGVyLCAkcmVqZWN0ZXIsICRub3RpZnkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCAkcmVqZWN0LCAkbm90aWZ5KTsKICAgIH0sICRjYW5jZWxsYXRpb25RdWV1ZSk7Cn0KCi8qKgogKiBUcmFkaXRpb25hbCBtYXAgZnVuY3Rpb24sIHNpbWlsYXIgdG8gYGFycmF5X21hcCgpYCwgYnV0IGFsbG93cyBpbnB1dCB0byBjb250YWluCiAqIHByb21pc2VzIGFuZC9vciB2YWx1ZXMsIGFuZCBgJG1hcEZ1bmNgIG1heSByZXR1cm4gZWl0aGVyIGEgdmFsdWUgb3IgYSBwcm9taXNlLgogKgogKiBUaGUgbWFwIGZ1bmN0aW9uIHJlY2VpdmVzIGVhY2ggaXRlbSBhcyBhcmd1bWVudCwgd2hlcmUgaXRlbSBpcyBhIGZ1bGx5IHJlc29sdmVkCiAqIHZhbHVlIG9mIGEgcHJvbWlzZSBvciB2YWx1ZSBpbiBgJHByb21pc2VzT3JWYWx1ZXNgLgogKgogKiBAcGFyYW0gYXJyYXkgJHByb21pc2VzT3JWYWx1ZXMKICogQHBhcmFtIGNhbGxhYmxlICRtYXBGdW5jCiAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogKi8KZnVuY3Rpb24gbWFwKCRwcm9taXNlc09yVmFsdWVzLCBjYWxsYWJsZSAkbWFwRnVuYykKewogICAgJGNhbmNlbGxhdGlvblF1ZXVlID0gbmV3IENhbmNlbGxhdGlvblF1ZXVlKCk7CiAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VzT3JWYWx1ZXMpOwoKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHVzZSAoJHByb21pc2VzT3JWYWx1ZXMsICRtYXBGdW5jLCAkY2FuY2VsbGF0aW9uUXVldWUpIHsKICAgICAgICByZXNvbHZlKCRwcm9taXNlc09yVmFsdWVzKQogICAgICAgICAgICAtPmRvbmUoZnVuY3Rpb24gKCRhcnJheSkgdXNlICgkbWFwRnVuYywgJGNhbmNlbGxhdGlvblF1ZXVlLCAkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgewogICAgICAgICAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGFycmF5KSB8fCAhJGFycmF5KSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc29sdmUoW10pOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdG9SZXNvbHZlID0gXGNvdW50KCRhcnJheSk7CiAgICAgICAgICAgICAgICAkdmFsdWVzICAgID0gW107CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGFycmF5IGFzICRpID0+ICRwcm9taXNlT3JWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICRjYW5jZWxsYXRpb25RdWV1ZS0+ZW5xdWV1ZSgkcHJvbWlzZU9yVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICR2YWx1ZXNbJGldID0gbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgkcHJvbWlzZU9yVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIC0+dGhlbigkbWFwRnVuYykKICAgICAgICAgICAgICAgICAgICAgICAgLT5kb25lKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCRtYXBwZWQpIHVzZSAoJGksICYkdmFsdWVzLCAmJHRvUmVzb2x2ZSwgJHJlc29sdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmFsdWVzWyRpXSA9ICRtYXBwZWQ7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAtLSR0b1Jlc29sdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc29sdmUoJHZhbHVlcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZWplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm90aWZ5CiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sICRyZWplY3QsICRub3RpZnkpOwogICAgfSwgJGNhbmNlbGxhdGlvblF1ZXVlKTsKfQoKLyoqCiAqIFRyYWRpdGlvbmFsIHJlZHVjZSBmdW5jdGlvbiwgc2ltaWxhciB0byBgYXJyYXlfcmVkdWNlKClgLCBidXQgaW5wdXQgbWF5IGNvbnRhaW4KICogcHJvbWlzZXMgYW5kL29yIHZhbHVlcywgYW5kIGAkcmVkdWNlRnVuY2AgbWF5IHJldHVybiBlaXRoZXIgYSB2YWx1ZSBvciBhCiAqIHByb21pc2UsICphbmQqIGAkaW5pdGlhbFZhbHVlYCBtYXkgYmUgYSBwcm9taXNlIG9yIGEgdmFsdWUgZm9yIHRoZSBzdGFydGluZwogKiB2YWx1ZS4KICoKICogQHBhcmFtIGFycmF5ICRwcm9taXNlc09yVmFsdWVzCiAqIEBwYXJhbSBjYWxsYWJsZSAkcmVkdWNlRnVuYwogKiBAcGFyYW0gbWl4ZWQgJGluaXRpYWxWYWx1ZQogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIHJlZHVjZSgkcHJvbWlzZXNPclZhbHVlcywgY2FsbGFibGUgJHJlZHVjZUZ1bmMsICRpbml0aWFsVmFsdWUgPSBudWxsKQp7CiAgICAkY2FuY2VsbGF0aW9uUXVldWUgPSBuZXcgQ2FuY2VsbGF0aW9uUXVldWUoKTsKICAgICRjYW5jZWxsYXRpb25RdWV1ZS0+ZW5xdWV1ZSgkcHJvbWlzZXNPclZhbHVlcyk7CgogICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgdXNlICgkcHJvbWlzZXNPclZhbHVlcywgJHJlZHVjZUZ1bmMsICRpbml0aWFsVmFsdWUsICRjYW5jZWxsYXRpb25RdWV1ZSkgewogICAgICAgIHJlc29sdmUoJHByb21pc2VzT3JWYWx1ZXMpCiAgICAgICAgICAgIC0+ZG9uZShmdW5jdGlvbiAoJGFycmF5KSB1c2UgKCRyZWR1Y2VGdW5jLCAkaW5pdGlhbFZhbHVlLCAkY2FuY2VsbGF0aW9uUXVldWUsICRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KSB7CiAgICAgICAgICAgICAgICBpZiAoIVxpc19hcnJheSgkYXJyYXkpKSB7CiAgICAgICAgICAgICAgICAgICAgJGFycmF5ID0gW107CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRvdGFsID0gXGNvdW50KCRhcnJheSk7CiAgICAgICAgICAgICAgICAkaSA9IDA7CgogICAgICAgICAgICAgICAgLy8gV3JhcCB0aGUgc3VwcGxpZWQgJHJlZHVjZUZ1bmMgd2l0aCBvbmUgdGhhdCBoYW5kbGVzIHByb21pc2VzIGFuZCB0aGVuCiAgICAgICAgICAgICAgICAvLyBkZWxlZ2F0ZXMgdG8gdGhlIHN1cHBsaWVkLgogICAgICAgICAgICAgICAgJHdyYXBwZWRSZWR1Y2VGdW5jID0gZnVuY3Rpb24gKCRjdXJyZW50LCAkdmFsKSB1c2UgKCRyZWR1Y2VGdW5jLCAkY2FuY2VsbGF0aW9uUXVldWUsICR0b3RhbCwgJiRpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNhbmNlbGxhdGlvblF1ZXVlLT5lbnF1ZXVlKCR2YWwpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGN1cnJlbnQKICAgICAgICAgICAgICAgICAgICAgICAgLT50aGVuKGZ1bmN0aW9uICgkYykgdXNlICgkcmVkdWNlRnVuYywgJHRvdGFsLCAmJGksICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCR2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT50aGVuKGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJHJlZHVjZUZ1bmMsICR0b3RhbCwgJiRpLCAkYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHJlZHVjZUZ1bmMoJGMsICR2YWx1ZSwgJGkrKywgJHRvdGFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICRjYW5jZWxsYXRpb25RdWV1ZS0+ZW5xdWV1ZSgkaW5pdGlhbFZhbHVlKTsKCiAgICAgICAgICAgICAgICBcYXJyYXlfcmVkdWNlKCRhcnJheSwgJHdyYXBwZWRSZWR1Y2VGdW5jLCByZXNvbHZlKCRpbml0aWFsVmFsdWUpKQogICAgICAgICAgICAgICAgICAgIC0+ZG9uZSgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSk7CiAgICAgICAgICAgIH0sICRyZWplY3QsICRub3RpZnkpOwogICAgfSwgJGNhbmNlbGxhdGlvblF1ZXVlKTsKfQoKLyoqCiAqIEBpbnRlcm5hbAogKi8KZnVuY3Rpb24gX2NoZWNrVHlwZWhpbnQoY2FsbGFibGUgJGNhbGxiYWNrLCAkb2JqZWN0KQp7CiAgICBpZiAoIVxpc19vYmplY3QoJG9iamVjdCkpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBpZiAoXGlzX2FycmF5KCRjYWxsYmFjaykpIHsKICAgICAgICAkY2FsbGJhY2tSZWZsZWN0aW9uID0gbmV3IFxSZWZsZWN0aW9uTWV0aG9kKCRjYWxsYmFja1swXSwgJGNhbGxiYWNrWzFdKTsKICAgIH0gZWxzZWlmIChcaXNfb2JqZWN0KCRjYWxsYmFjaykgJiYgISRjYWxsYmFjayBpbnN0YW5jZW9mIFxDbG9zdXJlKSB7CiAgICAgICAgJGNhbGxiYWNrUmVmbGVjdGlvbiA9IG5ldyBcUmVmbGVjdGlvbk1ldGhvZCgkY2FsbGJhY2ssICdfX2ludm9rZScpOwogICAgfSBlbHNlIHsKICAgICAgICAkY2FsbGJhY2tSZWZsZWN0aW9uID0gbmV3IFxSZWZsZWN0aW9uRnVuY3Rpb24oJGNhbGxiYWNrKTsKICAgIH0KCiAgICAkcGFyYW1ldGVycyA9ICRjYWxsYmFja1JlZmxlY3Rpb24tPmdldFBhcmFtZXRlcnMoKTsKCiAgICBpZiAoIWlzc2V0KCRwYXJhbWV0ZXJzWzBdKSkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgICRleHBlY3RlZEV4Y2VwdGlvbiA9ICRwYXJhbWV0ZXJzWzBdOwoKICAgIGlmICghJGV4cGVjdGVkRXhjZXB0aW9uLT5nZXRDbGFzcygpKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcmV0dXJuICRleHBlY3RlZEV4Y2VwdGlvbi0+Z2V0Q2xhc3MoKS0+aXNJbnN0YW5jZSgkb2JqZWN0KTsKfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgppbnRlcmZhY2UgQ2FuY2VsbGFibGVQcm9taXNlSW50ZXJmYWNlIGV4dGVuZHMgUHJvbWlzZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFRoZSBgY2FuY2VsKClgIG1ldGhvZCBub3RpZmllcyB0aGUgY3JlYXRvciBvZiB0aGUgcHJvbWlzZSB0aGF0IHRoZXJlIGlzIG5vCiAgICAgKiBmdXJ0aGVyIGludGVyZXN0IGluIHRoZSByZXN1bHRzIG9mIHRoZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogT25jZSBhIHByb21pc2UgaXMgc2V0dGxlZCAoZWl0aGVyIGZ1bGZpbGxlZCBvciByZWplY3RlZCksIGNhbGxpbmcgYGNhbmNlbCgpYCBvbgogICAgICogYSBwcm9taXNlIGhhcyBubyBlZmZlY3QuCiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjYW5jZWwoKTsKfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgppbnRlcmZhY2UgUHJvbWlzb3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9taXNlIG9mIHRoZSBkZWZlcnJlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByb21pc2UoKTsKfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgppbnRlcmZhY2UgUHJvbWlzZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFRyYW5zZm9ybXMgYSBwcm9taXNlJ3MgdmFsdWUgYnkgYXBwbHlpbmcgYSBmdW5jdGlvbiB0byB0aGUgcHJvbWlzZSdzIGZ1bGZpbGxtZW50CiAgICAgKiBvciByZWplY3Rpb24gdmFsdWUuIFJldHVybnMgYSBuZXcgcHJvbWlzZSBmb3IgdGhlIHRyYW5zZm9ybWVkIHJlc3VsdC4KICAgICAqCiAgICAgKiBUaGUgYHRoZW4oKWAgbWV0aG9kIHJlZ2lzdGVycyBuZXcgZnVsZmlsbGVkIGFuZCByZWplY3Rpb24gaGFuZGxlcnMgd2l0aCBhIHByb21pc2UKICAgICAqIChhbGwgcGFyYW1ldGVycyBhcmUgb3B0aW9uYWwpOgogICAgICoKICAgICAqICAqIGAkb25GdWxmaWxsZWRgIHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZSBwcm9taXNlIGlzIGZ1bGZpbGxlZCBhbmQgcGFzc2VkCiAgICAgKiAgICAgdGhlIHJlc3VsdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQuCiAgICAgKiAgKiBgJG9uUmVqZWN0ZWRgIHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkIGFuZCBwYXNzZWQgdGhlCiAgICAgKiAgICAgcmVhc29uIGFzIHRoZSBmaXJzdCBhcmd1bWVudC4KICAgICAqICAqIGAkb25Qcm9ncmVzc2AgKGRlcHJlY2F0ZWQpIHdpbGwgYmUgaW52b2tlZCB3aGVuZXZlciB0aGUgcHJvZHVjZXIgb2YgdGhlIHByb21pc2UKICAgICAqICAgICB0cmlnZ2VycyBwcm9ncmVzcyBub3RpZmljYXRpb25zIGFuZCBwYXNzZWQgYSBzaW5nbGUgYXJndW1lbnQgKHdoYXRldmVyIGl0CiAgICAgKiAgICAgd2FudHMpIHRvIGluZGljYXRlIHByb2dyZXNzLgogICAgICoKICAgICAqIEl0IHJldHVybnMgYSBuZXcgcHJvbWlzZSB0aGF0IHdpbGwgZnVsZmlsbCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgZWl0aGVyCiAgICAgKiBgJG9uRnVsZmlsbGVkYCBvciBgJG9uUmVqZWN0ZWRgLCB3aGljaGV2ZXIgaXMgY2FsbGVkLCBvciB3aWxsIHJlamVjdCB3aXRoCiAgICAgKiB0aGUgdGhyb3duIGV4Y2VwdGlvbiBpZiBlaXRoZXIgdGhyb3dzLgogICAgICoKICAgICAqIEEgcHJvbWlzZSBtYWtlcyB0aGUgZm9sbG93aW5nIGd1YXJhbnRlZXMgYWJvdXQgaGFuZGxlcnMgcmVnaXN0ZXJlZCBpbgogICAgICogdGhlIHNhbWUgY2FsbCB0byBgdGhlbigpYDoKICAgICAqCiAgICAgKiAgMS4gT25seSBvbmUgb2YgYCRvbkZ1bGZpbGxlZGAgb3IgYCRvblJlamVjdGVkYCB3aWxsIGJlIGNhbGxlZCwKICAgICAqICAgICAgbmV2ZXIgYm90aC4KICAgICAqICAyLiBgJG9uRnVsZmlsbGVkYCBhbmQgYCRvblJlamVjdGVkYCB3aWxsIG5ldmVyIGJlIGNhbGxlZCBtb3JlCiAgICAgKiAgICAgIHRoYW4gb25jZS4KICAgICAqICAzLiBgJG9uUHJvZ3Jlc3NgIChkZXByZWNhdGVkKSBtYXkgYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRvbkZ1bGZpbGxlZAogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJG9uUmVqZWN0ZWQKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRvblByb2dyZXNzIFRoaXMgYXJndW1lbnQgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGFueW1vcmUuCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRoZW4oY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZVxFeGNlcHRpb247CgpjbGFzcyBMZW5ndGhFeGNlcHRpb24gZXh0ZW5kcyBcTGVuZ3RoRXhjZXB0aW9uCnsKfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgpjbGFzcyBQcm9taXNlIGltcGxlbWVudHMgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlLCBDYW5jZWxsYWJsZVByb21pc2VJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkY2FuY2VsbGVyOwogICAgcHJpdmF0ZSAkcmVzdWx0OwoKICAgIHByaXZhdGUgJGhhbmRsZXJzID0gW107CiAgICBwcml2YXRlICRwcm9ncmVzc0hhbmRsZXJzID0gW107CgogICAgcHJpdmF0ZSAkcmVxdWlyZWRDYW5jZWxSZXF1ZXN0cyA9IDA7CiAgICBwcml2YXRlICRjYW5jZWxSZXF1ZXN0cyA9IDA7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGNhbGxhYmxlICRyZXNvbHZlciwgY2FsbGFibGUgJGNhbmNlbGxlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9ICRjYW5jZWxsZXI7CgogICAgICAgIC8vIEV4cGxpY2l0bHkgb3ZlcndyaXRlIGFyZ3VtZW50cyB3aXRoIG51bGwgdmFsdWVzIGJlZm9yZSBpbnZva2luZwogICAgICAgIC8vIHJlc29sdmVyIGZ1bmN0aW9uLiBUaGlzIGVuc3VyZSB0aGF0IHRoZXNlIGFyZ3VtZW50cyBkbyBub3Qgc2hvdyB1cAogICAgICAgIC8vIGluIHRoZSBzdGFjayB0cmFjZSBpbiBQSFAgNysgb25seS4KICAgICAgICAkY2IgPSAkcmVzb2x2ZXI7CiAgICAgICAgJHJlc29sdmVyID0gJGNhbmNlbGxlciA9IG51bGw7CiAgICAgICAgJHRoaXMtPmNhbGwoJGNiKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdGhlbihjYWxsYWJsZSAkb25GdWxmaWxsZWQgPSBudWxsLCBjYWxsYWJsZSAkb25SZWplY3RlZCA9IG51bGwsIGNhbGxhYmxlICRvblByb2dyZXNzID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPnJlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlc3VsdC0+dGhlbigkb25GdWxmaWxsZWQsICRvblJlamVjdGVkLCAkb25Qcm9ncmVzcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmNhbmNlbGxlcikgewogICAgICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygkdGhpcy0+cmVzb2x2ZXIoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCwgJG9uUHJvZ3Jlc3MpKTsKICAgICAgICB9CgogICAgICAgIC8vIFRoaXMgcHJvbWlzZSBoYXMgYSBjYW5jZWxsZXIsIHNvIHdlIGNyZWF0ZSBhIG5ldyBjaGlsZCBwcm9taXNlIHdoaWNoCiAgICAgICAgLy8gaGFzIGEgY2FuY2VsbGVyIHRoYXQgaW52b2tlcyB0aGUgcGFyZW50IGNhbmNlbGxlciBpZiBhbGwgb3RoZXIKICAgICAgICAvLyBmb2xsb3dlcnMgYXJlIGFsc28gY2FuY2VsbGVkLiBXZSBrZWVwIGEgcmVmZXJlbmNlIHRvIHRoaXMgcHJvbWlzZQogICAgICAgIC8vIGluc3RhbmNlIGZvciB0aGUgc3RhdGljIGNhbmNlbGxlciBmdW5jdGlvbiBhbmQgY2xlYXIgdGhpcyB0byBhdm9pZAogICAgICAgIC8vIGtlZXBpbmcgYSBjeWNsaWMgcmVmZXJlbmNlIGJldHdlZW4gcGFyZW50IGFuZCBmb2xsb3dlci4KICAgICAgICAkcGFyZW50ID0gJHRoaXM7CiAgICAgICAgKyskcGFyZW50LT5yZXF1aXJlZENhbmNlbFJlcXVlc3RzOwoKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygKICAgICAgICAgICAgJHRoaXMtPnJlc29sdmVyKCRvbkZ1bGZpbGxlZCwgJG9uUmVqZWN0ZWQsICRvblByb2dyZXNzKSwKICAgICAgICAgICAgc3RhdGljIGZ1bmN0aW9uICgpIHVzZSAoJiRwYXJlbnQpIHsKICAgICAgICAgICAgICAgIGlmICgrKyRwYXJlbnQtPmNhbmNlbFJlcXVlc3RzID49ICRwYXJlbnQtPnJlcXVpcmVkQ2FuY2VsUmVxdWVzdHMpIHsKICAgICAgICAgICAgICAgICAgICAkcGFyZW50LT5jYW5jZWwoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5yZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXN1bHQtPmRvbmUoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCwgJG9uUHJvZ3Jlc3MpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmhhbmRsZXJzW10gPSBzdGF0aWMgZnVuY3Rpb24gKEV4dGVuZGVkUHJvbWlzZUludGVyZmFjZSAkcHJvbWlzZSkgdXNlICgkb25GdWxmaWxsZWQsICRvblJlamVjdGVkKSB7CiAgICAgICAgICAgICRwcm9taXNlCiAgICAgICAgICAgICAgICAtPmRvbmUoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCk7CiAgICAgICAgfTsKCiAgICAgICAgaWYgKCRvblByb2dyZXNzKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9ncmVzc0hhbmRsZXJzW10gPSAkb25Qcm9ncmVzczsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG90aGVyd2lzZShjYWxsYWJsZSAkb25SZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4obnVsbCwgc3RhdGljIGZ1bmN0aW9uICgkcmVhc29uKSB1c2UgKCRvblJlamVjdGVkKSB7CiAgICAgICAgICAgIGlmICghX2NoZWNrVHlwZWhpbnQoJG9uUmVqZWN0ZWQsICRyZWFzb24pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkcmVhc29uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRvblJlamVjdGVkKCRyZWFzb24pOwogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhbHdheXMoY2FsbGFibGUgJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4oc3RhdGljIGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWRPclJlamVjdGVkKCkpLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgICAgICB9KTsKICAgICAgICB9LCBzdGF0aWMgZnVuY3Rpb24gKCRyZWFzb24pIHVzZSAoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWRPclJlamVjdGVkKCkpLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHJlYXNvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWplY3RlZFByb21pc2UoJHJlYXNvbik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzcyhjYWxsYWJsZSAkb25Qcm9ncmVzcykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4obnVsbCwgbnVsbCwgJG9uUHJvZ3Jlc3MpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjYW5jZWwoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+Y2FuY2VsbGVyIHx8IG51bGwgIT09ICR0aGlzLT5yZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGNhbmNlbGxlciA9ICR0aGlzLT5jYW5jZWxsZXI7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9IG51bGw7CgogICAgICAgICR0aGlzLT5jYWxsKCRjYW5jZWxsZXIpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVzb2x2ZXIoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgdXNlICgkb25GdWxmaWxsZWQsICRvblJlamVjdGVkLCAkb25Qcm9ncmVzcykgewogICAgICAgICAgICBpZiAoJG9uUHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICRwcm9ncmVzc0hhbmRsZXIgPSBzdGF0aWMgZnVuY3Rpb24gKCR1cGRhdGUpIHVzZSAoJG5vdGlmeSwgJG9uUHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAkbm90aWZ5KCRvblByb2dyZXNzKCR1cGRhdGUpKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRub3RpZnkoJGUpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vdGlmeSgkZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcm9ncmVzc0hhbmRsZXIgPSAkbm90aWZ5OwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aGFuZGxlcnNbXSA9IHN0YXRpYyBmdW5jdGlvbiAoRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlICRwcm9taXNlKSB1c2UgKCRvbkZ1bGZpbGxlZCwgJG9uUmVqZWN0ZWQsICRyZXNvbHZlLCAkcmVqZWN0LCAkcHJvZ3Jlc3NIYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAkcHJvbWlzZQogICAgICAgICAgICAgICAgICAgIC0+dGhlbigkb25GdWxmaWxsZWQsICRvblJlamVjdGVkKQogICAgICAgICAgICAgICAgICAgIC0+ZG9uZSgkcmVzb2x2ZSwgJHJlamVjdCwgJHByb2dyZXNzSGFuZGxlcik7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAkdGhpcy0+cHJvZ3Jlc3NIYW5kbGVyc1tdID0gJHByb2dyZXNzSGFuZGxlcjsKICAgICAgICB9OwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVqZWN0KCRyZWFzb24gPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+cmVzdWx0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXR0bGUocmVqZWN0KCRyZWFzb24pKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldHRsZShFeHRlbmRlZFByb21pc2VJbnRlcmZhY2UgJHByb21pc2UpCiAgICB7CiAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+dW53cmFwKCRwcm9taXNlKTsKCiAgICAgICAgaWYgKCRwcm9taXNlID09PSAkdGhpcykgewogICAgICAgICAgICAkcHJvbWlzZSA9IG5ldyBSZWplY3RlZFByb21pc2UoCiAgICAgICAgICAgICAgICBuZXcgXExvZ2ljRXhjZXB0aW9uKCdDYW5ub3QgcmVzb2x2ZSBhIHByb21pc2Ugd2l0aCBpdHNlbGYuJykKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRoYW5kbGVycyA9ICR0aGlzLT5oYW5kbGVyczsKCiAgICAgICAgJHRoaXMtPnByb2dyZXNzSGFuZGxlcnMgPSAkdGhpcy0+aGFuZGxlcnMgPSBbXTsKICAgICAgICAkdGhpcy0+cmVzdWx0ID0gJHByb21pc2U7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9IG51bGw7CgogICAgICAgIGZvcmVhY2ggKCRoYW5kbGVycyBhcyAkaGFuZGxlcikgewogICAgICAgICAgICAkaGFuZGxlcigkcHJvbWlzZSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdW53cmFwKCRwcm9taXNlKQogICAgewogICAgICAgICRwcm9taXNlID0gJHRoaXMtPmV4dHJhY3QoJHByb21pc2UpOwoKICAgICAgICB3aGlsZSAoJHByb21pc2UgaW5zdGFuY2VvZiBzZWxmICYmIG51bGwgIT09ICRwcm9taXNlLT5yZXN1bHQpIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+ZXh0cmFjdCgkcHJvbWlzZS0+cmVzdWx0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3QoJHByb21pc2UpCiAgICB7CiAgICAgICAgaWYgKCRwcm9taXNlIGluc3RhbmNlb2YgTGF6eVByb21pc2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkcHJvbWlzZS0+cHJvbWlzZSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwcm9taXNlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2FsbChjYWxsYWJsZSAkY2IpCiAgICB7CiAgICAgICAgLy8gRXhwbGljaXRseSBvdmVyd3JpdGUgYXJndW1lbnQgd2l0aCBudWxsIHZhbHVlLiBUaGlzIGVuc3VyZSB0aGF0IHRoaXMKICAgICAgICAvLyBhcmd1bWVudCBkb2VzIG5vdCBzaG93IHVwIGluIHRoZSBzdGFjayB0cmFjZSBpbiBQSFAgNysgb25seS4KICAgICAgICAkY2FsbGJhY2sgPSAkY2I7CiAgICAgICAgJGNiID0gbnVsbDsKCiAgICAgICAgLy8gVXNlIHJlZmxlY3Rpb24gdG8gaW5zcGVjdCBudW1iZXIgb2YgYXJndW1lbnRzIGV4cGVjdGVkIGJ5IHRoaXMgY2FsbGJhY2suCiAgICAgICAgLy8gV2UgZGlkIHNvbWUgY2FyZWZ1bCBiZW5jaG1hcmtpbmcgaGVyZTogVXNpbmcgcmVmbGVjdGlvbiB0byBhdm9pZCB1bm5lZWRlZAogICAgICAgIC8vIGZ1bmN0aW9uIGFyZ3VtZW50cyBpcyBhY3R1YWxseSBmYXN0ZXIgdGhhbiBibGluZGx5IHBhc3NpbmcgdGhlbS4KICAgICAgICAvLyBBbHNvLCB0aGlzIGhlbHBzIGF2b2lkaW5nIHVubmVjZXNzYXJ5IGZ1bmN0aW9uIGFyZ3VtZW50cyBpbiB0aGUgY2FsbCBzdGFjawogICAgICAgIC8vIGlmIHRoZSBjYWxsYmFjayBjcmVhdGVzIGFuIEV4Y2VwdGlvbiAoY3JlYXRpbmcgZ2FyYmFnZSBjeWNsZXMpLgogICAgICAgIGlmIChcaXNfYXJyYXkoJGNhbGxiYWNrKSkgewogICAgICAgICAgICAkcmVmID0gbmV3IFxSZWZsZWN0aW9uTWV0aG9kKCRjYWxsYmFja1swXSwgJGNhbGxiYWNrWzFdKTsKICAgICAgICB9IGVsc2VpZiAoXGlzX29iamVjdCgkY2FsbGJhY2spICYmICEkY2FsbGJhY2sgaW5zdGFuY2VvZiBcQ2xvc3VyZSkgewogICAgICAgICAgICAkcmVmID0gbmV3IFxSZWZsZWN0aW9uTWV0aG9kKCRjYWxsYmFjaywgJ19faW52b2tlJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHJlZiA9IG5ldyBcUmVmbGVjdGlvbkZ1bmN0aW9uKCRjYWxsYmFjayk7CiAgICAgICAgfQogICAgICAgICRhcmdzID0gJHJlZi0+Z2V0TnVtYmVyT2ZQYXJhbWV0ZXJzKCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgkYXJncyA9PT0gMCkgewogICAgICAgICAgICAgICAgJGNhbGxiYWNrKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBLZWVwIHJlZmVyZW5jZXMgdG8gdGhpcyBwcm9taXNlIGluc3RhbmNlIGZvciB0aGUgc3RhdGljIHJlc29sdmUvcmVqZWN0IGZ1bmN0aW9ucy4KICAgICAgICAgICAgICAgIC8vIEJ5IHVzaW5nIHN0YXRpYyBjYWxsYmFja3MgdGhhdCBhcmUgbm90IGJvdW5kIHRvIHRoaXMgaW5zdGFuY2UKICAgICAgICAgICAgICAgIC8vIGFuZCBwYXNzaW5nIHRoZSB0YXJnZXQgcHJvbWlzZSBpbnN0YW5jZSBieSByZWZlcmVuY2UsIHdlIGNhbgogICAgICAgICAgICAgICAgLy8gc3RpbGwgZXhlY3V0ZSBpdHMgcmVzb2x2aW5nIGxvZ2ljIGFuZCBzdGlsbCBjbGVhciB0aGlzCiAgICAgICAgICAgICAgICAvLyByZWZlcmVuY2Ugd2hlbiBzZXR0bGluZyB0aGUgcHJvbWlzZS4gVGhpcyBoZWxwcyBhdm9pZGluZwogICAgICAgICAgICAgICAgLy8gZ2FyYmFnZSBjeWNsZXMgaWYgYW55IGNhbGxiYWNrIGNyZWF0ZXMgYW4gRXhjZXB0aW9uLgogICAgICAgICAgICAgICAgLy8gVGhlc2UgYXNzdW1wdGlvbnMgYXJlIGNvdmVyZWQgYnkgdGhlIHRlc3Qgc3VpdGUsIHNvIGlmIHlvdSBldmVyIGZlZWwgbGlrZQogICAgICAgICAgICAgICAgLy8gcmVmYWN0b3JpbmcgdGhpcywgZ28gYWhlYWQsIGFueSBhbHRlcm5hdGl2ZSBzdWdnZXN0aW9ucyBhcmUgd2VsY29tZSEKICAgICAgICAgICAgICAgICR0YXJnZXQgPSYgJHRoaXM7CiAgICAgICAgICAgICAgICAkcHJvZ3Jlc3NIYW5kbGVycyA9JiAkdGhpcy0+cHJvZ3Jlc3NIYW5kbGVyczsKCiAgICAgICAgICAgICAgICAkY2FsbGJhY2soCiAgICAgICAgICAgICAgICAgICAgc3RhdGljIGZ1bmN0aW9uICgkdmFsdWUgPSBudWxsKSB1c2UgKCYkdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGFyZ2V0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0LT5zZXR0bGUocmVzb2x2ZSgkdmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0YXJnZXQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZnVuY3Rpb24gKCRyZWFzb24gPSBudWxsKSB1c2UgKCYkdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGFyZ2V0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0LT5yZWplY3QoJHJlYXNvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgc3RhdGljIGZ1bmN0aW9uICgkdXBkYXRlID0gbnVsbCkgdXNlICgmJHByb2dyZXNzSGFuZGxlcnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHByb2dyZXNzSGFuZGxlcnMgYXMgJGhhbmRsZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRoYW5kbGVyKCR1cGRhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGUpIHsKICAgICAgICAgICAgJHRhcmdldCA9IG51bGw7CiAgICAgICAgICAgICR0aGlzLT5yZWplY3QoJGUpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRhcmdldCA9IG51bGw7CiAgICAgICAgICAgICR0aGlzLT5yZWplY3QoJGUpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgppbnRlcmZhY2UgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlIGV4dGVuZHMgUHJvbWlzZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBwcm9taXNlJ3MgdWx0aW1hdGUgdmFsdWUgaWYgdGhlIHByb21pc2UgZnVsZmlsbHMsIG9yIGhhbmRsZXMgdGhlCiAgICAgKiB1bHRpbWF0ZSBlcnJvci4KICAgICAqCiAgICAgKiBJdCB3aWxsIGNhdXNlIGEgZmF0YWwgZXJyb3IgaWYgZWl0aGVyIGAkb25GdWxmaWxsZWRgIG9yCiAgICAgKiBgJG9uUmVqZWN0ZWRgIHRocm93IG9yIHJldHVybiBhIHJlamVjdGVkIHByb21pc2UuCiAgICAgKgogICAgICogU2luY2UgdGhlIHB1cnBvc2Ugb2YgYGRvbmUoKWAgaXMgY29uc3VtcHRpb24gcmF0aGVyIHRoYW4gdHJhbnNmb3JtYXRpb24sCiAgICAgKiBgZG9uZSgpYCBhbHdheXMgcmV0dXJucyBgbnVsbGAuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJG9uRnVsZmlsbGVkCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkb25SZWplY3RlZAogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJG9uUHJvZ3Jlc3MgVGhpcyBhcmd1bWVudCBpcyBkZXByZWNhdGVkIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYW55bW9yZS4KICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG9uZShjYWxsYWJsZSAkb25GdWxmaWxsZWQgPSBudWxsLCBjYWxsYWJsZSAkb25SZWplY3RlZCA9IG51bGwsIGNhbGxhYmxlICRvblByb2dyZXNzID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSByZWplY3Rpb24gaGFuZGxlciBmb3IgcHJvbWlzZS4gSXQgaXMgYSBzaG9ydGN1dCBmb3I6CiAgICAgKgogICAgICogYGBgcGhwCiAgICAgKiAkcHJvbWlzZS0+dGhlbihudWxsLCAkb25SZWplY3RlZCk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiBBZGRpdGlvbmFsbHksIHlvdSBjYW4gdHlwZSBoaW50IHRoZSBgJHJlYXNvbmAgYXJndW1lbnQgb2YgYCRvblJlamVjdGVkYCB0byBjYXRjaAogICAgICogb25seSBzcGVjaWZpYyBlcnJvcnMuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRvblJlamVjdGVkCiAgICAgKiBAcmV0dXJuIEV4dGVuZGVkUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb3RoZXJ3aXNlKGNhbGxhYmxlICRvblJlamVjdGVkKTsKCiAgICAvKioKICAgICAqIEFsbG93cyB5b3UgdG8gZXhlY3V0ZSAiY2xlYW51cCIgdHlwZSB0YXNrcyBpbiBhIHByb21pc2UgY2hhaW4uCiAgICAgKgogICAgICogSXQgYXJyYW5nZXMgZm9yIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCB0byBiZSBjYWxsZWQsIHdpdGggbm8gYXJndW1lbnRzLAogICAgICogd2hlbiB0aGUgcHJvbWlzZSBpcyBlaXRoZXIgZnVsZmlsbGVkIG9yIHJlamVjdGVkLgogICAgICoKICAgICAqICogSWYgYCRwcm9taXNlYCBmdWxmaWxscywgYW5kIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCByZXR1cm5zIHN1Y2Nlc3NmdWxseSwKICAgICAqICAgIGAkbmV3UHJvbWlzZWAgd2lsbCBmdWxmaWxsIHdpdGggdGhlIHNhbWUgdmFsdWUgYXMgYCRwcm9taXNlYC4KICAgICAqICogSWYgYCRwcm9taXNlYCBmdWxmaWxscywgYW5kIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCB0aHJvd3Mgb3IgcmV0dXJucyBhCiAgICAgKiAgICByZWplY3RlZCBwcm9taXNlLCBgJG5ld1Byb21pc2VgIHdpbGwgcmVqZWN0IHdpdGggdGhlIHRocm93biBleGNlcHRpb24gb3IKICAgICAqICAgIHJlamVjdGVkIHByb21pc2UncyByZWFzb24uCiAgICAgKiAqIElmIGAkcHJvbWlzZWAgcmVqZWN0cywgYW5kIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCByZXR1cm5zIHN1Y2Nlc3NmdWxseSwKICAgICAqICAgIGAkbmV3UHJvbWlzZWAgd2lsbCByZWplY3Qgd2l0aCB0aGUgc2FtZSByZWFzb24gYXMgYCRwcm9taXNlYC4KICAgICAqICogSWYgYCRwcm9taXNlYCByZWplY3RzLCBhbmQgYCRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWRgIHRocm93cyBvciByZXR1cm5zIGEKICAgICAqICAgIHJlamVjdGVkIHByb21pc2UsIGAkbmV3UHJvbWlzZWAgd2lsbCByZWplY3Qgd2l0aCB0aGUgdGhyb3duIGV4Y2VwdGlvbiBvcgogICAgICogICAgcmVqZWN0ZWQgcHJvbWlzZSdzIHJlYXNvbi4KICAgICAqCiAgICAgKiBgYWx3YXlzKClgIGJlaGF2ZXMgc2ltaWxhcmx5IHRvIHRoZSBzeW5jaHJvbm91cyBmaW5hbGx5IHN0YXRlbWVudC4gV2hlbiBjb21iaW5lZAogICAgICogd2l0aCBgb3RoZXJ3aXNlKClgLCBgYWx3YXlzKClgIGFsbG93cyB5b3UgdG8gd3JpdGUgY29kZSB0aGF0IGlzIHNpbWlsYXIgdG8gdGhlIGZhbWlsaWFyCiAgICAgKiBzeW5jaHJvbm91cyBjYXRjaC9maW5hbGx5IHBhaXIuCiAgICAgKgogICAgICogQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBzeW5jaHJvbm91cyBjb2RlOgogICAgICoKICAgICAqIGBgYHBocAogICAgICogdHJ5IHsKICAgICAqICAgICByZXR1cm4gZG9Tb21ldGhpbmcoKTsKICAgICAqIH0gY2F0Y2goXEV4Y2VwdGlvbiAkZSkgewogICAgICogICAgIHJldHVybiBoYW5kbGVFcnJvcigkZSk7CiAgICAgKiB9IGZpbmFsbHkgewogICAgICogICAgIGNsZWFudXAoKTsKICAgICAqIH0KICAgICAqIGBgYAogICAgICoKICAgICAqIFNpbWlsYXIgYXN5bmNocm9ub3VzIGNvZGUgKHdpdGggYGRvU29tZXRoaW5nKClgIHRoYXQgcmV0dXJucyBhIHByb21pc2UpIGNhbiBiZQogICAgICogd3JpdHRlbjoKICAgICAqCiAgICAgKiBgYGBwaHAKICAgICAqIHJldHVybiBkb1NvbWV0aGluZygpCiAgICAgKiAgICAgLT5vdGhlcndpc2UoJ2hhbmRsZUVycm9yJykKICAgICAqICAgICAtPmFsd2F5cygnY2xlYW51cCcpOwogICAgICogYGBgCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWQKICAgICAqIEByZXR1cm4gRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbHdheXMoY2FsbGFibGUgJG9uRnVsZmlsbGVkT3JSZWplY3RlZCk7CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBoYW5kbGVyIGZvciBwcm9ncmVzcyB1cGRhdGVzIGZyb20gcHJvbWlzZS4gSXQgaXMgYSBzaG9ydGN1dCBmb3I6CiAgICAgKgogICAgICogYGBgcGhwCiAgICAgKiAkcHJvbWlzZS0+dGhlbihudWxsLCBudWxsLCAkb25Qcm9ncmVzcyk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJG9uUHJvZ3Jlc3MKICAgICAqIEByZXR1cm4gRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlCiAgICAgKiBAZGVwcmVjYXRlZCAyLjYuMCBQcm9ncmVzcyBzdXBwb3J0IGlzIGRlcHJlY2F0ZWQgYW5kIHNob3VsZCBub3QgYmUgdXNlZCBhbnltb3JlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3MoY2FsbGFibGUgJG9uUHJvZ3Jlc3MpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCi8qKgogKiBAZGVwcmVjYXRlZCAyLjguMCBMYXp5UHJvbWlzZSBpcyBkZXByZWNhdGVkIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYW55bW9yZS4KICovCmNsYXNzIExhenlQcm9taXNlIGltcGxlbWVudHMgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlLCBDYW5jZWxsYWJsZVByb21pc2VJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkZmFjdG9yeTsKICAgIHByaXZhdGUgJHByb21pc2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGNhbGxhYmxlICRmYWN0b3J5KQogICAgewogICAgICAgICR0aGlzLT5mYWN0b3J5ID0gJGZhY3Rvcnk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRoZW4oY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9taXNlKCktPnRoZW4oJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCwgJG9uUHJvZ3Jlc3MpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBkb25lKGNhbGxhYmxlICRvbkZ1bGZpbGxlZCA9IG51bGwsIGNhbGxhYmxlICRvblJlamVjdGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUHJvZ3Jlc3MgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvbWlzZSgpLT5kb25lKCRvbkZ1bGZpbGxlZCwgJG9uUmVqZWN0ZWQsICRvblByb2dyZXNzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gb3RoZXJ3aXNlKGNhbGxhYmxlICRvblJlamVjdGVkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvbWlzZSgpLT5vdGhlcndpc2UoJG9uUmVqZWN0ZWQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhbHdheXMoY2FsbGFibGUgJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb21pc2UoKS0+YWx3YXlzKCRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzcyhjYWxsYWJsZSAkb25Qcm9ncmVzcykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb21pc2UoKS0+cHJvZ3Jlc3MoJG9uUHJvZ3Jlc3MpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjYW5jZWwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvbWlzZSgpLT5jYW5jZWwoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICogQHNlZSBQcm9taXNlOjpzZXR0bGUoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvbWlzZSgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5wcm9taXNlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvbWlzZSA9IHJlc29sdmUoXGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5mYWN0b3J5KSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgJHRoaXMtPnByb21pc2UgPSBuZXcgUmVqZWN0ZWRQcm9taXNlKCRleGNlcHRpb24pOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9taXNlID0gbmV3IFJlamVjdGVkUHJvbWlzZSgkZXhjZXB0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9taXNlOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCmNsYXNzIFVuaGFuZGxlZFJlamVjdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uCnsKICAgIHByaXZhdGUgJHJlYXNvbjsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlc29sdmUoJHJlYXNvbikKICAgIHsKICAgICAgICBpZiAoJHJlYXNvbiBpbnN0YW5jZW9mIFxFeGNlcHRpb24gfHwgJHJlYXNvbiBpbnN0YW5jZW9mIFxUaHJvd2FibGUpIHsKICAgICAgICAgICAgcmV0dXJuICRyZWFzb247CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygkcmVhc29uKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlYXNvbikKICAgIHsKICAgICAgICAkdGhpcy0+cmVhc29uID0gJHJlYXNvbjsKCiAgICAgICAgJG1lc3NhZ2UgPSBcc3ByaW50ZignVW5oYW5kbGVkIFJlamVjdGlvbjogJXMnLCBcanNvbl9lbmNvZGUoJHJlYXNvbikpOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAwKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVhc29uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlYXNvbjsKICAgIH0KfQo8P3BocAoKaWYgKCFcZnVuY3Rpb25fZXhpc3RzKCdSZWFjdFxQcm9taXNlXHJlc29sdmUnKSkgewogICAgcmVxdWlyZSBfX0RJUl9fLicvZnVuY3Rpb25zLnBocCc7Cn0KPD9waHAKCm5hbWVzcGFjZSBSZWFjdFxQcm9taXNlOwoKLyoqCiAqIEBkZXByZWNhdGVkIDIuOC4wIEV4dGVybmFsIHVzYWdlIG9mIEZ1bGZpbGxlZFByb21pc2UgaXMgZGVwcmVjYXRlZCwgdXNlIGByZXNvbHZlKClgIGluc3RlYWQuCiAqLwpjbGFzcyBGdWxmaWxsZWRQcm9taXNlIGltcGxlbWVudHMgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlLCBDYW5jZWxsYWJsZVByb21pc2VJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkdmFsdWU7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2YWx1ZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCR2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1lvdSBjYW5ub3QgY3JlYXRlIFJlYWN0XFByb21pc2VcRnVsZmlsbGVkUHJvbWlzZSB3aXRoIGEgcHJvbWlzZS4gVXNlIFJlYWN0XFByb21pc2VccmVzb2x2ZSgkcHJvbWlzZU9yVmFsdWUpIGluc3RlYWQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dmFsdWUgPSAkdmFsdWU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRoZW4oY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRvbkZ1bGZpbGxlZCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXM7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWQoJHRoaXMtPnZhbHVlKSk7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVqZWN0ZWRQcm9taXNlKCRleGNlcHRpb24pOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkZXhjZXB0aW9uKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRvbkZ1bGZpbGxlZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gJG9uRnVsZmlsbGVkKCR0aGlzLT52YWx1ZSk7CgogICAgICAgIGlmICgkcmVzdWx0IGluc3RhbmNlb2YgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRyZXN1bHQtPmRvbmUoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG90aGVyd2lzZShjYWxsYWJsZSAkb25SZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFsd2F5cyhjYWxsYWJsZSAkb25GdWxmaWxsZWRPclJlamVjdGVkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGhlbihmdW5jdGlvbiAoJHZhbHVlKSB1c2UgKCRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCgpKS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCR2YWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzKGNhbGxhYmxlICRvblByb2dyZXNzKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY2FuY2VsKCkKICAgIHsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgpjbGFzcyBDYW5jZWxsYXRpb25RdWV1ZQp7CiAgICBwcml2YXRlICRzdGFydGVkID0gZmFsc2U7CiAgICBwcml2YXRlICRxdWV1ZSA9IFtdOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zdGFydGVkKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zdGFydGVkID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+ZHJhaW4oKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5xdWV1ZSgkY2FuY2VsbGFibGUpCiAgICB7CiAgICAgICAgaWYgKCFcaXNfb2JqZWN0KCRjYW5jZWxsYWJsZSkgfHwgIVxtZXRob2RfZXhpc3RzKCRjYW5jZWxsYWJsZSwgJ3RoZW4nKSB8fCAhXG1ldGhvZF9leGlzdHMoJGNhbmNlbGxhYmxlLCAnY2FuY2VsJykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGxlbmd0aCA9IFxhcnJheV9wdXNoKCR0aGlzLT5xdWV1ZSwgJGNhbmNlbGxhYmxlKTsKCiAgICAgICAgaWYgKCR0aGlzLT5zdGFydGVkICYmIDEgPT09ICRsZW5ndGgpIHsKICAgICAgICAgICAgJHRoaXMtPmRyYWluKCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZHJhaW4oKQogICAgewogICAgICAgIGZvciAoJGkgPSBrZXkoJHRoaXMtPnF1ZXVlKTsgaXNzZXQoJHRoaXMtPnF1ZXVlWyRpXSk7ICRpKyspIHsKICAgICAgICAgICAgJGNhbmNlbGxhYmxlID0gJHRoaXMtPnF1ZXVlWyRpXTsKCiAgICAgICAgICAgICRleGNlcHRpb24gPSBudWxsOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRjYW5jZWxsYWJsZS0+Y2FuY2VsKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGV4Y2VwdGlvbikgewogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRleGNlcHRpb24pIHsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnF1ZXVlWyRpXSk7CgogICAgICAgICAgICBpZiAoJGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgdGhyb3cgJGV4Y2VwdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnF1ZXVlID0gW107CiAgICB9Cn0KPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIExpc3QsIGFkZCwgYW5kIGRlbGV0ZSBpdGVtcyBhc3NvY2lhdGVkIHdpdGggYSBtZW51LgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBBZGQgYW4gZXhpc3RpbmcgcG9zdCB0byBhbiBleGlzdGluZyBtZW51CiAqICAgICAkIHdwIG1lbnUgaXRlbSBhZGQtcG9zdCBzaWRlYmFyLW1lbnUgMzMgLS10aXRsZT0iQ3VzdG9tIFRlc3QgUG9zdCIKICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KICoKICogICAgICMgQ3JlYXRlIGEgbmV3IG1lbnUgbGluayBpdGVtCiAqICAgICAkIHdwIG1lbnUgaXRlbSBhZGQtY3VzdG9tIHNpZGViYXItbWVudSBBcHBsZSBodHRwOi8vYXBwbGUuY29tCiAqICAgICBTdWNjZXNzOiBNZW51IGl0ZW0gYWRkZWQuCiAqCiAqICAgICAjIERlbGV0ZSBtZW51IGl0ZW0KICogICAgICQgd3AgbWVudSBpdGVtIGRlbGV0ZSA0NQogKiAgICAgU3VjY2VzczogMSBtZW51IGl0ZW0gZGVsZXRlZC4KICovCmNsYXNzIE1lbnVfSXRlbV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IFsKCQknZGJfaWQnLAoJCSd0eXBlJywKCQkndGl0bGUnLAoJCSdsaW5rJywKCQkncG9zaXRpb24nLAoJXTsKCgkvKioKCSAqIEdldHMgYSBsaXN0IG9mIGl0ZW1zIGFzc29jaWF0ZWQgd2l0aCBhIG1lbnUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxtZW51PgoJICogOiBUaGUgbmFtZSwgc2x1Zywgb3IgdGVybSBJRCBmb3IgdGhlIG1lbnUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0gaWRzCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIG1lbnUgaXRlbToKCSAqCgkgKiAqIGRiX2lkCgkgKiAqIHR5cGUKCSAqICogdGl0bGUKCSAqICogbGluawoJICogKiBwb3NpdGlvbgoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBtZW51X2l0ZW1fcGFyZW50CgkgKiAqIG9iamVjdF9pZAoJICogKiBvYmplY3QKCSAqICogdHlwZQoJICogKiB0eXBlX2xhYmVsCgkgKiAqIHRhcmdldAoJICogKiBhdHRyX3RpdGxlCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIGNsYXNzZXMKCSAqICogeGZuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGl0ZW0gbGlzdCBtYWluLW1lbnUKCSAqICAgICArLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgZGJfaWQgfCB0eXBlICAgICAgfCB0aXRsZSAgICAgICB8IGxpbmsgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBwb3NpdGlvbiB8CgkgKiAgICAgKy0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IDUgICAgIHwgY3VzdG9tICAgIHwgSG9tZSAgICAgICAgfCBodHRwOi8vZXhhbXBsZS5jb20gICAgICAgICAgICAgIHwgMSAgICAgICAgfAoJICogICAgIHwgNiAgICAgfCBwb3N0X3R5cGUgfCBTYW1wbGUgUGFnZSB8IGh0dHA6Ly9leGFtcGxlLmNvbS9zYW1wbGUtcGFnZS8gfCAyICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkaXRlbXMgPSB3cF9nZXRfbmF2X21lbnVfaXRlbXMoICRhcmdzWzBdICk7CgkJaWYgKCBmYWxzZSA9PT0gJGl0ZW1zIHx8IGlzX3dwX2Vycm9yKCAkaXRlbXMgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgbWVudS4nICk7CgkJfQoKCQkvLyBDb3JyZWN0IHBvc2l0aW9uIGluY29uc2lzdGVuY3kgYW5kCgkJLy8gcHJvdGVjdGVkIGB1cmxgIHBhcmFtIGluIFdQLUNMSQoJCSRpdGVtcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRpdGVtICkgewoJCQkJCSRpdGVtLT5wb3NpdGlvbiA9ICRpdGVtLT5tZW51X29yZGVyOwoJCQkJCSRpdGVtLT5saW5rICAgICA9ICRpdGVtLT51cmw7CgkJCQkJcmV0dXJuICRpdGVtOwoJCQl9LAoJCQkkaXRlbXMKCQkpOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICYmICdpZHMnID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCSRpdGVtcyA9IGFycmF5X21hcCgKCQkJCWZ1bmN0aW9uKCAkaXRlbSApIHsKCQkJCQkJcmV0dXJuICRpdGVtLT5kYl9pZDsKCQkJCX0sCgkJCQkkaXRlbXMKCQkJKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaXRlbXMgKTsKCgl9CgoJLyoqCgkgKiBBZGRzIGEgcG9zdCBhcyBhIG1lbnUgaXRlbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnU+CgkgKiA6IFRoZSBuYW1lLCBzbHVnLCBvciB0ZXJtIElEIGZvciB0aGUgbWVudS4KCSAqCgkgKiA8cG9zdC1pZD4KCSAqIDogUG9zdCBJRCB0byBhZGQgdG8gdGhlIG1lbnUuCgkgKgoJICogWy0tdGl0bGU9PHRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWxpbms9PGxpbms+XQoJICogOiBTZXQgYSBjdXN0b20gdXJsIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWRlc2NyaXB0aW9uPTxkZXNjcmlwdGlvbj5dCgkgKiA6IFNldCBhIGN1c3RvbSBkZXNjcmlwdGlvbiBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1hdHRyLXRpdGxlPTxhdHRyLXRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGF0dHJpYnV0ZSBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS10YXJnZXQ9PHRhcmdldD5dCgkgKiA6IFNldCBhIGN1c3RvbSBsaW5rIHRhcmdldCBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1jbGFzc2VzPTxjbGFzc2VzPl0KCSAqIDogU2V0IGEgY3VzdG9tIGxpbmsgY2xhc3NlcyBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3NpdGlvbj08cG9zaXRpb24+XQoJICogOiBTcGVjaWZ5IHRoZSBwb3NpdGlvbiBvZiB0aGlzIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wYXJlbnQtaWQ9PHBhcmVudC1pZD5dCgkgKiA6IE1ha2UgdGhpcyBtZW51IGl0ZW0gYSBjaGlsZCBvZiBhbm90aGVyIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgbWVudSBpdGVtIGlkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBpdGVtIGFkZC1wb3N0IHNpZGViYXItbWVudSAzMyAtLXRpdGxlPSJDdXN0b20gVGVzdCBQb3N0IgoJICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtcG9zdAoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX3Bvc3QoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddID0gJGFyZ3NbMV07CgkJdW5zZXQoICRhcmdzWzFdICk7CgkJJHBvc3QgPSBnZXRfcG9zdCggJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddICk7CgkJaWYgKCAhICRwb3N0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBwb3N0LicgKTsKCQl9CgkJJGFzc29jX2FyZ3NbJ29iamVjdCddID0gJHBvc3QtPnBvc3RfdHlwZTsKCgkJJHRoaXMtPmFkZF9vcl91cGRhdGVfaXRlbSggJ2FkZCcsICdwb3N0X3R5cGUnLCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEFkZHMgYSB0YXhvbm9teSB0ZXJtIGFzIGEgbWVudSBpdGVtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bWVudT4KCSAqIDogVGhlIG5hbWUsIHNsdWcsIG9yIHRlcm0gSUQgZm9yIHRoZSBtZW51LgoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGF4b25vbXkgb2YgdGhlIHRlcm0gdG8gYmUgYWRkZWQuCgkgKgoJICogPHRlcm0taWQ+CgkgKiA6IFRlcm0gSUQgb2YgdGhlIHRlcm0gdG8gYmUgYWRkZWQuCgkgKgoJICogWy0tdGl0bGU9PHRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWxpbms9PGxpbms+XQoJICogOiBTZXQgYSBjdXN0b20gdXJsIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWRlc2NyaXB0aW9uPTxkZXNjcmlwdGlvbj5dCgkgKiA6IFNldCBhIGN1c3RvbSBkZXNjcmlwdGlvbiBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1hdHRyLXRpdGxlPTxhdHRyLXRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGF0dHJpYnV0ZSBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS10YXJnZXQ9PHRhcmdldD5dCgkgKiA6IFNldCBhIGN1c3RvbSBsaW5rIHRhcmdldCBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1jbGFzc2VzPTxjbGFzc2VzPl0KCSAqIDogU2V0IGEgY3VzdG9tIGxpbmsgY2xhc3NlcyBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3NpdGlvbj08cG9zaXRpb24+XQoJICogOiBTcGVjaWZ5IHRoZSBwb3NpdGlvbiBvZiB0aGlzIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wYXJlbnQtaWQ9PHBhcmVudC1pZD5dCgkgKiA6IE1ha2UgdGhpcyBtZW51IGl0ZW0gYSBjaGlsZCBvZiBhbm90aGVyIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgbWVudSBpdGVtIGlkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBpdGVtIGFkZC10ZXJtIHNpZGViYXItbWVudSBwb3N0X3RhZyAyNAoJICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtdGVybQoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX3Rlcm0oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGFzc29jX2FyZ3NbJ29iamVjdCddID0gJGFyZ3NbMV07CgkJdW5zZXQoICRhcmdzWzFdICk7CgkJJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddID0gJGFyZ3NbMl07CgkJdW5zZXQoICRhcmdzWzJdICk7CgoJCWlmICggISBnZXRfdGVybV9ieSggJ2lkJywgJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddLCAkYXNzb2NfYXJnc1snb2JqZWN0J10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgdGVybS4nICk7CgkJfQoKCQkkdGhpcy0+YWRkX29yX3VwZGF0ZV9pdGVtKCAnYWRkJywgJ3RheG9ub215JywgJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgY3VzdG9tIG1lbnUgaXRlbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnU+CgkgKiA6IFRoZSBuYW1lLCBzbHVnLCBvciB0ZXJtIElEIGZvciB0aGUgbWVudS4KCSAqCgkgKiA8dGl0bGU+CgkgKiA6IFRpdGxlIGZvciB0aGUgbGluay4KCSAqCgkgKiA8bGluaz4KCSAqIDogVGFyZ2V0IFVSTCBmb3IgdGhlIGxpbmsuCgkgKgoJICogWy0tZGVzY3JpcHRpb249PGRlc2NyaXB0aW9uPl0KCSAqIDogU2V0IGEgY3VzdG9tIGRlc2NyaXB0aW9uIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWF0dHItdGl0bGU9PGF0dHItdGl0bGU+XQoJICogOiBTZXQgYSBjdXN0b20gdGl0bGUgYXR0cmlidXRlIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLXRhcmdldD08dGFyZ2V0Pl0KCSAqIDogU2V0IGEgY3VzdG9tIGxpbmsgdGFyZ2V0IGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWNsYXNzZXM9PGNsYXNzZXM+XQoJICogOiBTZXQgYSBjdXN0b20gbGluayBjbGFzc2VzIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLXBvc2l0aW9uPTxwb3NpdGlvbj5dCgkgKiA6IFNwZWNpZnkgdGhlIHBvc2l0aW9uIG9mIHRoaXMgbWVudSBpdGVtLgoJICoKCSAqIFstLXBhcmVudC1pZD08cGFyZW50LWlkPl0KCSAqIDogTWFrZSB0aGlzIG1lbnUgaXRlbSBhIGNoaWxkIG9mIGFub3RoZXIgbWVudSBpdGVtLgoJICoKCSAqIFstLXBvcmNlbGFpbl0KCSAqIDogT3V0cHV0IGp1c3QgdGhlIG5ldyBtZW51IGl0ZW0gaWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGl0ZW0gYWRkLWN1c3RvbSBzaWRlYmFyLW1lbnUgQXBwbGUgaHR0cDovL2FwcGxlLmNvbQoJICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtY3VzdG9tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfY3VzdG9tKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRhc3NvY19hcmdzWyd0aXRsZSddID0gJGFyZ3NbMV07CgkJdW5zZXQoICRhcmdzWzFdICk7CgkJJGFzc29jX2FyZ3NbJ2xpbmsnXSA9ICRhcmdzWzJdOwoJCXVuc2V0KCAkYXJnc1syXSApOwoJCSR0aGlzLT5hZGRfb3JfdXBkYXRlX2l0ZW0oICdhZGQnLCAnY3VzdG9tJywgJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIGEgbWVudSBpdGVtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8ZGItaWQ+CgkgKiA6IERhdGFiYXNlIElEIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLXRpdGxlPTx0aXRsZT5dCgkgKiA6IFNldCBhIGN1c3RvbSB0aXRsZSBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1saW5rPTxsaW5rPl0KCSAqIDogU2V0IGEgY3VzdG9tIHVybCBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBTZXQgYSBjdXN0b20gZGVzY3JpcHRpb24gZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tYXR0ci10aXRsZT08YXR0ci10aXRsZT5dCgkgKiA6IFNldCBhIGN1c3RvbSB0aXRsZSBhdHRyaWJ1dGUgZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tdGFyZ2V0PTx0YXJnZXQ+XQoJICogOiBTZXQgYSBjdXN0b20gbGluayB0YXJnZXQgZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tY2xhc3Nlcz08Y2xhc3Nlcz5dCgkgKiA6IFNldCBhIGN1c3RvbSBsaW5rIGNsYXNzZXMgZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tcG9zaXRpb249PHBvc2l0aW9uPl0KCSAqIDogU3BlY2lmeSB0aGUgcG9zaXRpb24gb2YgdGhpcyBtZW51IGl0ZW0uCgkgKgoJICogWy0tcGFyZW50LWlkPTxwYXJlbnQtaWQ+XQoJICogOiBNYWtlIHRoaXMgbWVudSBpdGVtIGEgY2hpbGQgb2YgYW5vdGhlciBtZW51IGl0ZW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGl0ZW0gdXBkYXRlIDQ1IC0tdGl0bGU9V29yZFByZXNzIC0tbGluaz0naHR0cDovL3dvcmRwcmVzcy5vcmcnIC0tdGFyZ2V0PV9ibGFuayAtLXBvc2l0aW9uPTIKCSAqICAgICBTdWNjZXNzOiBNZW51IGl0ZW0gdXBkYXRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCB1cGRhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkvLyBTaHVmZmxlIHRoZSBwb3NpdGlvbiBvZiB0aGVzZS4KCQkkYXJnc1sxXSA9ICRhcmdzWzBdOwoJCSR0ZXJtcyAgID0gZ2V0X3RoZV90ZXJtcyggJGFyZ3NbMV0sICduYXZfbWVudScgKTsKCQlpZiAoICR0ZXJtcyAmJiAhIGlzX3dwX2Vycm9yKCAkdGVybXMgKSApIHsKCQkJJGFyZ3NbMF0gPSAoaW50KSAkdGVybXNbMF0tPnRlcm1faWQ7CgkJfSBlbHNlIHsKCQkJJGFyZ3NbMF0gPSAwOwoJCX0KCQkkdHlwZSA9IGdldF9wb3N0X21ldGEoICRhcmdzWzFdLCAnX21lbnVfaXRlbV90eXBlJywgdHJ1ZSApOwoJCSR0aGlzLT5hZGRfb3JfdXBkYXRlX2l0ZW0oICd1cGRhdGUnLCAkdHlwZSwgJGFyZ3MsICRhc3NvY19hcmdzICk7CgoJfQoKCS8qKgoJICogRGVsZXRlcyBvbmUgb3IgbW9yZSBpdGVtcyBmcm9tIGEgbWVudS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGRiLWlkPi4uLgoJICogOiBEYXRhYmFzZSBJRCBmb3IgdGhlIG1lbnUgaXRlbShzKS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1lbnUgaXRlbSBkZWxldGUgNDUKCSAqICAgICBTdWNjZXNzOiAxIG1lbnUgaXRlbSBkZWxldGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGRlbGV0ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkY291bnQgID0gMDsKCQkkZXJyb3JzID0gMDsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgoJCQkkcG9zdCAgICAgICAgICAgPSBnZXRfcG9zdCggJGFyZyApOwoJCQkkbWVudV90ZXJtICAgICAgPSBnZXRfdGhlX3Rlcm1zKCAkYXJnLCAnbmF2X21lbnUnICk7CgkJCSRwYXJlbnRfbWVudV9pZCA9IChpbnQpIGdldF9wb3N0X21ldGEoICRhcmcsICdfbWVudV9pdGVtX21lbnVfaXRlbV9wYXJlbnQnLCB0cnVlICk7CgkJCSRyZXN1bHQgICAgICAgICA9IHdwX2RlbGV0ZV9wb3N0KCAkYXJnLCB0cnVlICk7CgkJCWlmICggISAkcmVzdWx0ICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGRuJ3QgZGVsZXRlIG1lbnUgaXRlbSB7JGFyZ30uIiApOwoJCQkJJGVycm9ycysrOwoJCQl9IGVsc2UgewoKCQkJCWlmICggaXNfYXJyYXkoICRtZW51X3Rlcm0gKSAmJiAhIGVtcHR5KCAkbWVudV90ZXJtICkgJiYgJHBvc3QgKSB7CgkJCQkJJHRoaXMtPnJlb3JkZXJfbWVudV9pdGVtcyggJG1lbnVfdGVybVswXS0+dGVybV9pZCwgJHBvc3QtPm1lbnVfb3JkZXIsIC0xLCAwICk7CgkJCQl9CgoJCQkJaWYgKCAkcGFyZW50X21lbnVfaWQgKSB7CgkJCQkJJGNoaWxkcmVuID0gJHdwZGItPmdldF9yZXN1bHRzKCAkd3BkYi0+cHJlcGFyZSggIlNFTEVDVCBwb3N0X2lkIEZST00gJHdwZGItPnBvc3RtZXRhIFdIRVJFIG1ldGFfa2V5PSdfbWVudV9pdGVtX21lbnVfaXRlbV9wYXJlbnQnIEFORCBtZXRhX3ZhbHVlPSVzIiwgKGludCkgJGFyZyApICk7CgkJCQkJaWYgKCAkY2hpbGRyZW4gKSB7CgkJCQkJCSRjaGlsZHJlbl9xdWVyeSA9ICR3cGRiLT5wcmVwYXJlKCAiVVBEQVRFICR3cGRiLT5wb3N0bWV0YSBTRVQgbWV0YV92YWx1ZSA9ICVkIFdIRVJFIG1ldGFfa2V5ID0gJ19tZW51X2l0ZW1fbWVudV9pdGVtX3BhcmVudCcgQU5EIG1ldGFfdmFsdWU9JXMiLCAkcGFyZW50X21lbnVfaWQsIChpbnQpICRhcmcgKTsKCQkJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5Ob3RQcmVwYXJlZCAtLSAkY2hpbGRyZW5fcXVlcnkgaXMgYWxyZWFkeSBwcmVwYXJlZCBhYm92ZS4KCQkJCQkJJHdwZGItPnF1ZXJ5KCAkY2hpbGRyZW5fcXVlcnkgKTsKCQkJCQkJZm9yZWFjaCAoICRjaGlsZHJlbiBhcyAkY2hpbGQgKSB7CgkJCQkJCQljbGVhbl9wb3N0X2NhY2hlKCAkY2hpbGQgKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuU3RyaWN0Q29tcGFyaXNvbnMuTG9vc2VDb21wYXJpc29uIC0tIFdpbGwgaW5jcmVhc2UgY291bnQgZm9yIG5vbiBleGlzdGVudCBtZW51LgoJCQlpZiAoIGZhbHNlICE9ICRyZXN1bHQgKSB7CgkJCQkkY291bnQrKzsKCQkJfQoJCX0KCgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnbWVudSBpdGVtJywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIFdvcmtlciBtZXRob2QgdG8gY3JlYXRlIG5ldyBpdGVtcyBvciB1cGRhdGUgZXhpc3Rpbmcgb25lcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBhZGRfb3JfdXBkYXRlX2l0ZW0oICRtZXRob2QsICR0eXBlLCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRtZW51ICAgICAgICAgICAgPSAkYXJnc1swXTsKCQkkbWVudV9pdGVtX2RiX2lkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAxLCAwICk7CgoJCSRtZW51ID0gd3BfZ2V0X25hdl9tZW51X29iamVjdCggJG1lbnUgKTsKCQlpZiAoICEgJG1lbnUgfHwgaXNfd3BfZXJyb3IoICRtZW51ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIG1lbnUuJyApOwoJCX0KCgkJLy8gYHVybGAgaXMgcHJvdGVjdGVkIGluIFdQLUNMSSwgc28gd2UgdXNlIGBsaW5rYCBpbnN0ZWFkCgkJJGFzc29jX2FyZ3NbJ3VybCddID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbGluaycgKTsKCgkJLy8gTmVlZCB0byBwZXJzaXN0IHRoZSBtZW51IGl0ZW0gZGF0YS4gU2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzI4MTM4CgkJaWYgKCAndXBkYXRlJyA9PT0gJG1ldGhvZCApIHsKCgkJCSRtZW51X2l0ZW1fb2JqID0gZ2V0X3Bvc3QoICRtZW51X2l0ZW1fZGJfaWQgKTsKCQkJJG1lbnVfaXRlbV9vYmogPSB3cF9zZXR1cF9uYXZfbWVudV9pdGVtKCAkbWVudV9pdGVtX29iaiApOwoKCQkJLy8gQ29ycmVjdCB0aGUgbWVudSBwb3NpdGlvbiBpZiB0aGlzIHdhcyB0aGUgZmlyc3QgaXRlbS4gU2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzI4MTQwCgkJCSRwb3NpdGlvbiA9ICggMCA9PT0gJG1lbnVfaXRlbV9vYmotPm1lbnVfb3JkZXIgKSA/IDEgOiAkbWVudV9pdGVtX29iai0+bWVudV9vcmRlcjsKCgkJCSRkZWZhdWx0X2FyZ3MgPSBbCgkJCQkncG9zaXRpb24nICAgID0+ICRwb3NpdGlvbiwKCQkJCSd0aXRsZScgICAgICAgPT4gJG1lbnVfaXRlbV9vYmotPnRpdGxlLAoJCQkJJ3VybCcgICAgICAgICA9PiAkbWVudV9pdGVtX29iai0+dXJsLAoJCQkJJ2Rlc2NyaXB0aW9uJyA9PiAkbWVudV9pdGVtX29iai0+ZGVzY3JpcHRpb24sCgkJCQknb2JqZWN0JyAgICAgID0+ICRtZW51X2l0ZW1fb2JqLT5vYmplY3QsCgkJCQknb2JqZWN0LWlkJyAgID0+ICRtZW51X2l0ZW1fb2JqLT5vYmplY3RfaWQsCgkJCQkncGFyZW50LWlkJyAgID0+ICRtZW51X2l0ZW1fb2JqLT5tZW51X2l0ZW1fcGFyZW50LAoJCQkJJ2F0dHItdGl0bGUnICA9PiAkbWVudV9pdGVtX29iai0+YXR0cl90aXRsZSwKCQkJCSd0YXJnZXQnICAgICAgPT4gJG1lbnVfaXRlbV9vYmotPnRhcmdldCwKCQkJCSdjbGFzc2VzJyAgICAgPT4gaW1wbG9kZSggJyAnLCAkbWVudV9pdGVtX29iai0+Y2xhc3NlcyApLCAvLyBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlIGFzIGFycmF5CgkJCQkneGZuJyAgICAgICAgID0+ICRtZW51X2l0ZW1fb2JqLT54Zm4sCgkJCQknc3RhdHVzJyAgICAgID0+ICRtZW51X2l0ZW1fb2JqLT5wb3N0X3N0YXR1cywKCQkJXTsKCgkJfSBlbHNlIHsKCgkJCSRkZWZhdWx0X2FyZ3MgPSBbCgkJCQkncG9zaXRpb24nICAgID0+IDAsCgkJCQkndGl0bGUnICAgICAgID0+ICcnLAoJCQkJJ3VybCcgICAgICAgICA9PiAnJywKCQkJCSdkZXNjcmlwdGlvbicgPT4gJycsCgkJCQknb2JqZWN0JyAgICAgID0+ICcnLAoJCQkJJ29iamVjdC1pZCcgICA9PiAwLAoJCQkJJ3BhcmVudC1pZCcgICA9PiAwLAoJCQkJJ2F0dHItdGl0bGUnICA9PiAnJywKCQkJCSd0YXJnZXQnICAgICAgPT4gJycsCgkJCQknY2xhc3NlcycgICAgID0+ICcnLAoJCQkJJ3hmbicgICAgICAgICA9PiAnJywKCQkJCS8vIENvcmUgb2RkbHkgZGVmYXVsdHMgdG8gJ2RyYWZ0JyBmb3IgY3JlYXRlLAoJCQkJLy8gYW5kICdwdWJsaXNoJyBmb3IgdXBkYXRlCgkJCQkvLyBFYXNpZXN0IHRvIGFsd2F5cyB3b3JrIHdpdGggcHVibGlzaAoJCQkJJ3N0YXR1cycgICAgICA9PiAncHVibGlzaCcsCgkJCV07CgoJCX0KCgkJJG1lbnVfaXRlbV9hcmdzID0gW107CgkJZm9yZWFjaCAoICRkZWZhdWx0X2FyZ3MgYXMgJGtleSA9PiAkZGVmYXVsdF92YWx1ZSApIHsKCQkJLy8gd3BfdXBkYXRlX25hdl9tZW51X2l0ZW0oKSBoYXMgYSB3ZWlyZCBhcmd1bWVudCBwcmVmaXgKCQkJJG5ld19rZXkgICAgICAgICAgICAgICAgICAgID0gJ21lbnUtaXRlbS0nIC4gJGtleTsKCQkJJG1lbnVfaXRlbV9hcmdzWyAkbmV3X2tleSBdID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAka2V5LCAkZGVmYXVsdF92YWx1ZSApOwoJCX0KCgkJJG1lbnVfaXRlbV9hcmdzWydtZW51LWl0ZW0tdHlwZSddID0gJHR5cGU7CgkJJHJlc3VsdCAgICAgICAgICAgICAgICAgICAgICAgICAgID0gd3BfdXBkYXRlX25hdl9tZW51X2l0ZW0oICRtZW51LT50ZXJtX2lkLCAkbWVudV9pdGVtX2RiX2lkLCAkbWVudV9pdGVtX2FyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJfSBlbHNlaWYgKCAhICRyZXN1bHQgKSB7CgkJCWlmICggJ2FkZCcgPT09ICRtZXRob2QgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgYWRkIG1lbnUgaXRlbS4iICk7CgkJCX0gZWxzZWlmICggJ3VwZGF0ZScgPT09ICRtZXRob2QgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgdXBkYXRlIG1lbnUgaXRlbS4iICk7CgkJCX0KCQl9IGVsc2UgewoKCQkJaWYgKCAoICdhZGQnID09PSAkbWV0aG9kICkgJiYgJG1lbnVfaXRlbV9hcmdzWydtZW51LWl0ZW0tcG9zaXRpb24nXSApIHsKCQkJCSR0aGlzLT5yZW9yZGVyX21lbnVfaXRlbXMoICRtZW51LT50ZXJtX2lkLCAkbWVudV9pdGVtX2FyZ3NbJ21lbnUtaXRlbS1wb3NpdGlvbiddLCArMSwgJHJlc3VsdCApOwoJCQl9CgoJCQkvKioKCQkJICogU2V0IHRoZSBtZW51CgkJCSAqCgkJCSAqIHdwX3VwZGF0ZV9uYXZfbWVudV9pdGVtKCkgKnNob3VsZCogdGFrZSBjYXJlIG9mIHRoaXMsIGJ1dAoJCQkgKiBkZXBlbmRzIG9uIHdwX2luc2VydF9wb3N0KCkncyAidGF4X2lucHV0IiBhcmd1bWVudCwgd2hpY2gKCQkJICogaXMgaWdub3JlZCBpZiB0aGUgdXNlciBjYW4ndCBlZGl0IHRoZSB0YXhvbm9teQoJCQkgKgoJCQkgKiBAc2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzI3MTEzCgkJCSAqLwoJCQlpZiAoICEgaXNfb2JqZWN0X2luX3Rlcm0oICRyZXN1bHQsICduYXZfbWVudScsIChpbnQpICRtZW51LT50ZXJtX2lkICkgKSB7CgkJCQl3cF9zZXRfb2JqZWN0X3Rlcm1zKCAkcmVzdWx0LCBbIChpbnQpICRtZW51LT50ZXJtX2lkIF0sICduYXZfbWVudScgKTsKCQkJfQoKCQkJaWYgKCAnYWRkJyA9PT0gJG1ldGhvZCAmJiAhIGVtcHR5KCAkYXNzb2NfYXJnc1sncG9yY2VsYWluJ10gKSApIHsKCQkJCVdQX0NMSTo6bGluZSggJHJlc3VsdCApOwoJCQl9IGVsc2UgewoJCQkJaWYgKCAnYWRkJyA9PT0gJG1ldGhvZCApIHsKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdNZW51IGl0ZW0gYWRkZWQuJyApOwoJCQkJfSBlbHNlaWYgKCAndXBkYXRlJyA9PT0gJG1ldGhvZCApIHsKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdNZW51IGl0ZW0gdXBkYXRlZC4nICk7CgkJCQl9CgkJCX0KCQl9CgoJfQoKCS8qKgoJICogTW92ZSBibG9jayBvZiBpdGVtcyBpbiBvbmUgbmF2X21lbnUgdXAgb3IgZG93biBieSBpbmNyZW1lbnRpbmcvZGVjcmVtZW50aW5nIHRoZWlyIG1lbnVfb3JkZXIgZmllbGQuCgkgKiBFeHBlY3RzIHRoZSBtZW51IGl0ZW1zIHRvIGhhdmUgcHJvcGVyIG1lbnVfb3JkZXJzIChpLmUuIGRvZXNuJ3QgZml4IGVycm9ycyBmcm9tIHByZXZpb3VzIGluY29ycmVjdCBvcGVyYXRpb25zKS4KCSAqCgkgKiBAcGFyYW0gaW50ICRtZW51X2lkIElEIG9mIHRoZSBuYXZfbWVudQoJICogQHBhcmFtIGludCAkbWluX3Bvc2l0aW9uIG1pbmltYWwgbWVudV9vcmRlciB0byB0b3VjaAoJICogQHBhcmFtIGludCAkaW5jcmVtZW50IGhvdyBtdWNoIHRvIGNoYW5nZSBtZW51X29yZGVyOiArMSB0byBtb3ZlIGRvd24sIC0xIHRvIG1vdmUgdXAKCSAqIEBwYXJhbSBpbnQgJGlnbm9yZV9pdGVtX2lkIG1lbnUgaXRlbSB0aGF0IHNob3VsZCBiZSBpZ25vcmVkIGJ5IHRoZSBjaGFuZ2UgKGUuZy4gbmV3bHkgY3JlYXRlZCBtZW51IGl0ZW0pCgkgKiBAcmV0dXJuIGludCBudW1iZXIgb2Ygcm93cyBhZmZlY3RlZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlb3JkZXJfbWVudV9pdGVtcyggJG1lbnVfaWQsICRtaW5fcG9zaXRpb24sICRpbmNyZW1lbnQsICRpZ25vcmVfaXRlbV9pZCA9IDAgKSB7CgkJZ2xvYmFsICR3cGRiOwoJCXJldHVybiAkd3BkYi0+cXVlcnkoICR3cGRiLT5wcmVwYXJlKCAiVVBEQVRFICR3cGRiLT5wb3N0cyBTRVQgYG1lbnVfb3JkZXJgPWBtZW51X29yZGVyYCsoJWQpIFdIRVJFIGBtZW51X29yZGVyYD49JWQgQU5EIElEIElOIChTRUxFQ1Qgb2JqZWN0X2lkIEZST00gJHdwZGItPnRlcm1fcmVsYXRpb25zaGlwcyBXSEVSRSB0ZXJtX3RheG9ub215X2lkPSVkKSBBTkQgSUQ8PiVkIiwgKGludCkgJGluY3JlbWVudCwgKGludCkgJG1pbl9wb3NpdGlvbiwgKGludCkgJG1lbnVfaWQsIChpbnQpICRpZ25vcmVfaXRlbV9pZCApICk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5vYmpfZmllbGRzICk7Cgl9Cgp9Cjw/cGhwCgp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZTsKCi8qKgogKiBQZXJmb3JtIG5ldHdvcmstd2lkZSBvcGVyYXRpb25zLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBHZXQgYSBsaXN0IG9mIHN1cGVyLWFkbWlucwogKiAgICAgJCB3cCBuZXR3b3JrIG1ldGEgZ2V0IDEgc2l0ZV9hZG1pbnMKICogICAgIGFycmF5ICgKICogICAgICAgMCA9PiAnc3VwZXJ2aXNvcicsCiAqICAgICApCiAqLwpjbGFzcyBOZXR3b3JrX05hbWVzcGFjZSBleHRlbmRzIENvbW1hbmROYW1lc3BhY2UgewoKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElfQ29tbWFuZDsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0Vycm9yOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIFdQLUNMSSBjb21tYW5kcyB0aGF0IGRlYWwgd2l0aCBkYXRhYmFzZSBvYmplY3RzLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmFic3RyYWN0IGNsYXNzIENvbW1hbmRXaXRoREJPYmplY3QgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBAdmFyIHN0cmluZyAkb2JqZWN0X3R5cGUgV29yZFByZXNzJyBleHBlY3RlZCBuYW1lIGZvciB0aGUgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgJG9ial90eXBlOwoKCS8qKgoJICogQHZhciBzdHJpbmcgJG9ial9pZF9rZXkgS2V5IHJlcHJlc2VudGluZyBvYmplY3QncyBQSyBmaWVsZCBpbiBkYi4KCSAqLwoJcHJvdGVjdGVkICRvYmpfaWRfa2V5ID0gJ0lEJzsKCgkvKioKCSAqIEB2YXIgYXJyYXkgJG9ial9maWVsZHMgRGVmYXVsdCBmaWVsZHMgdG8gZGlzcGxheSBmb3IgZWFjaCBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCAkb2JqX2ZpZWxkczsKCgkvKioKCSAqIENyZWF0ZSBhIGdpdmVuIGRhdGFiYXNlIG9iamVjdC4KCSAqIEV4aXRzIHdpdGggc3RhdHVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBBcmd1bWVudHMgcGFzc2VkIHRvIGNvbW1hbmQuIEdlbmVyYWxseSB1bnVzZWQuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZCB0byBiZSBwYXNzZWQgdG8gY2FsbGJhY2suCgkgKiBAcGFyYW0gc3RyaW5nICRjYWxsYmFjayBGdW5jdGlvbiB1c2VkIHRvIGNyZWF0ZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBfY3JlYXRlKCAkYXJncywgJGFzc29jX2FyZ3MsICRjYWxsYmFjayApIHsKCQl1bnNldCggJGFzc29jX2FyZ3NbICR0aGlzLT5vYmpfaWRfa2V5IF0gKTsKCgkJJG9ial9pZCA9ICRjYWxsYmFjayggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJG9ial9pZCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkb2JqX2lkICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKSApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkb2JqX2lkICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQ3JlYXRlZCB7JHRoaXMtPm9ial90eXBlfSB7JG9ial9pZH0uIiApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZSBhIGdpdmVuIGRhdGFiYXNlIG9iamVjdC4KCSAqIEV4aXRzIHdpdGggc3RhdHVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBDb2xsZWN0aW9uIG9mIG9uZSBvciBtb3JlIG9iamVjdCBpZHMgdG8gdXBkYXRlLgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEZpZWxkcyA9PiB2YWx1ZXMgdG8gdXBkYXRlIG9uIGVhY2ggb2JqZWN0LgoJICogQHBhcmFtIHN0cmluZyAkY2FsbGJhY2sgRnVuY3Rpb24gdXNlZCB0byB1cGRhdGUgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gX3VwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzLCAkY2FsbGJhY2sgKSB7CgkJJHN0YXR1cyA9IDA7CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdOZWVkIHNvbWUgZmllbGRzIHRvIHVwZGF0ZS4nICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RlZmVyLXRlcm0tY291bnRpbmcnICkgKSB7CgkJCXdwX2RlZmVyX3Rlcm1fY291bnRpbmcoIHRydWUgKTsKCQl9CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkb2JqX2lkICkgewoJCQkkcGFyYW1zID0gYXJyYXlfbWVyZ2UoICRhc3NvY19hcmdzLCBbICR0aGlzLT5vYmpfaWRfa2V5ID0+ICRvYmpfaWQgXSApOwoKCQkJJHN0YXR1cyA9ICR0aGlzLT5zdWNjZXNzX29yX2ZhaWx1cmUoCgkJCQkkdGhpcy0+d3BfZXJyb3JfdG9fcmVzcCgKCQkJCQkkY2FsbGJhY2soICRwYXJhbXMgKSwKCQkJCQkiVXBkYXRlZCB7JHRoaXMtPm9ial90eXBlfSB7JG9ial9pZH0uIgoJCQkJKQoJCQkpOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkZWZlci10ZXJtLWNvdW50aW5nJyApICkgewoJCQl3cF9kZWZlcl90ZXJtX2NvdW50aW5nKCBmYWxzZSApOwoJCX0KCgkJZXhpdCggJHN0YXR1cyApOwoJfQoKCS8qKgoJICogVHJhbnNmb3JtcyBhcmd1bWVudHMgd2l0aCAnX18nIGZyb20gQ1NWIGludG8gZXhwZWN0ZWQgYXJyYXlzCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcHJvY2Vzc19jc3ZfYXJndW1lbnRzX3RvX2FycmF5cyggJGFzc29jX2FyZ3MgKSB7CgkJZm9yZWFjaCAoICRhc3NvY19hcmdzIGFzICRrID0+ICR2ICkgewoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICRrLCAnX18nICkgKSB7CgkJCQkkYXNzb2NfYXJnc1sgJGsgXSA9IGV4cGxvZGUoICcsJywgJHYgKTsKCQkJfQoJCX0KCQlyZXR1cm4gJGFzc29jX2FyZ3M7Cgl9CgoJLyoqCgkgKiBEZWxldGUgYSBnaXZlbiBkYXRhYmFzZSBvYmplY3QuCgkgKiBFeGl0cyB3aXRoIHN0YXR1cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgQ29sbGVjdGlvbiBvZiBvbmUgb3IgbW9yZSBvYmplY3QgaWRzIHRvIGRlbGV0ZS4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBbnkgYXJndW1lbnRzIG5lZWRlZCBmb3IgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLgoJICogQHBhcmFtIGNhbGxhYmxlICRjYWxsYmFjayBGdW5jdGlvbiB1c2VkIHRvIGRlbGV0ZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBfZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MsICRjYWxsYmFjayApIHsKCQkkc3RhdHVzID0gMDsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkZWZlci10ZXJtLWNvdW50aW5nJyApICkgewoJCQl3cF9kZWZlcl90ZXJtX2NvdW50aW5nKCB0cnVlICk7CgkJfQoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJG9ial9pZCApIHsKCQkJJHJlc3VsdCA9ICRjYWxsYmFjayggJG9ial9pZCwgJGFzc29jX2FyZ3MgKTsKCQkJJHN0YXR1cyA9ICR0aGlzLT5zdWNjZXNzX29yX2ZhaWx1cmUoICRyZXN1bHQgKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGVmZXItdGVybS1jb3VudGluZycgKSApIHsKCQkJd3BfZGVmZXJfdGVybV9jb3VudGluZyggZmFsc2UgKTsKCQl9CgoJCWV4aXQoICRzdGF0dXMgKTsKCX0KCgkvKioKCSAqIEZvcm1hdCBjYWxsYmFjayByZXNwb25zZSB0byBjb25zaXN0ZW50IGZvcm1hdC4KCSAqCgkgKiBAcGFyYW0gV1BfRXJyb3J8dHJ1ZSAkcmVzcG9uc2UgUmVzcG9uc2UgZnJvbSBDUlVEIGNhbGxiYWNrLgoJICogQHBhcmFtIHN0cmluZyAgICAgICAgJHN1Y2Nlc3NfbXNnCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB3cF9lcnJvcl90b19yZXNwKCAkcmVzcG9uc2UsICRzdWNjZXNzX21zZyApIHsKCQlyZXR1cm4gaXNfd3BfZXJyb3IoICRyZXNwb25zZSApCgkJCT8gWyAnZXJyb3InLCAkcmVzcG9uc2UtPmdldF9lcnJvcl9tZXNzYWdlKCkgXQoJCQk6IFsgJ3N1Y2Nlc3MnLCAkc3VjY2Vzc19tc2cgXTsKCX0KCgkvKioKCSAqIERpc3BsYXkgc3VjY2VzcyBvciB3YXJuaW5nIGJhc2VkIG9uIHJlc3BvbnNlOyByZXR1cm4gcHJvcGVyIGV4aXQgY29kZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlc3BvbnNlIEZvcm1hdHRlZCBmcm9tIGEgQ1JVRCBjYWxsYmFjay4KCSAqIEByZXR1cm4gaW50ICRzdGF0dXMKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHN1Y2Nlc3Nfb3JfZmFpbHVyZSggJHJlc3BvbnNlICkgewoJCWxpc3QoICR0eXBlLCAkbXNnICkgPSAkcmVzcG9uc2U7CgoJCWlmICggJ3N1Y2Nlc3MnID09PSAkdHlwZSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAkbXNnICk7CgkJCSRzdGF0dXMgPSAwOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6d2FybmluZyggJG1zZyApOwoJCQkkc3RhdHVzID0gMTsKCQl9CgoJCXJldHVybiAkc3RhdHVzOwoJfQoKCS8qKgoJICogR2V0IEZvcm1hdHRlciBvYmplY3QgYmFzZWQgb24gc3VwcGxpZWQgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZC4gRGV0ZXJtaW5lcyBmb3JtYXR0aW5nLgoJICogQHJldHVybiBGb3JtYXR0ZXIKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJaWYgKCBpc19zdHJpbmcoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkJJGZpZWxkcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJCX0gZWxzZSB7CgkJCQkkZmllbGRzID0gJGFzc29jX2FyZ3NbJ2ZpZWxkcyddOwoJCQl9CgkJfSBlbHNlIHsKCQkJJGZpZWxkcyA9ICR0aGlzLT5vYmpfZmllbGRzOwoJCX0KCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICRmaWVsZHMsICR0aGlzLT5vYmpfdHlwZSApOwoJfQoKCS8qKgoJICogR2l2ZW4gYSBjYWxsYmFjaywgZGlzcGxheSB0aGUgVVJMIGZvciBvbmUgb3IgbW9yZSBvYmplY3RzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBPbmUgb3IgbW9yZSBvYmplY3QgcmVmZXJlbmNlcy4KCSAqIEBwYXJhbSBzdHJpbmcgJGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGdldCBVUkwgZm9yIHRoZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBfdXJsKCAkYXJncywgJGNhbGxiYWNrICkgewoJCWZvcmVhY2ggKCAkYXJncyBhcyAkb2JqX2lkICkgewoJCQkkb2JqZWN0ID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJG9ial9pZCApOwoJCQlXUF9DTEk6OmxpbmUoICRjYWxsYmFjayggJG9iamVjdC0+eyR0aGlzLT5vYmpfaWRfa2V5fSApICk7CgkJfQoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVudGl0eTsKCnVzZSBPdXRPZkJvdW5kc0V4Y2VwdGlvbjsKCmNsYXNzIE5vbkV4aXN0ZW50S2V5RXhjZXB0aW9uIGV4dGVuZHMgT3V0T2ZCb3VuZHNFeGNlcHRpb24gewoJLyoqIEB2YXIgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciAqLwoJcHJvdGVjdGVkICR0cmF2ZXJzZXI7CgoJLyoqCgkgKiBAcGFyYW0gUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciAkdHJhdmVyc2VyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfdHJhdmVyc2VyKCAkdHJhdmVyc2VyICkgewoJCSR0aGlzLT50cmF2ZXJzZXIgPSAkdHJhdmVyc2VyOwoJfQoKCS8qKgoJICogQHJldHVybiBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfdHJhdmVyc2VyKCkgewoJCXJldHVybiAkdGhpcy0+dHJhdmVyc2VyOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVudGl0eTsKCnVzZSBVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb247CgpjbGFzcyBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyIHsKCgkvKioKCSAqIEB2YXIgbWl4ZWQgVGhlIGRhdGEgdG8gdHJhdmVyc2Ugc2V0IGJ5IHJlZmVyZW5jZS4KCSAqLwoJcHJvdGVjdGVkICRkYXRhOwoKCS8qKgoJICogQHZhciBudWxsfHN0cmluZyBUaGUga2V5IHRoZSBkYXRhIGJlbG9uZ3MgdG8gaW4gdGhlIHBhcmVudCdzIGRhdGEuCgkgKi8KCXByb3RlY3RlZCAka2V5OwoKCS8qKgoJICogQHZhciBudWxsfHN0YXRpYyBUaGUgcGFyZW50IGluc3RhbmNlIG9mIHRoZSB0cmF2ZXJzZXIuCgkgKi8KCXByb3RlY3RlZCAkcGFyZW50OwoKCS8qKgoJICogUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciBjb25zdHJ1Y3Rvci4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJGRhdGEgVGhlIGRhdGEgdG8gcmVhZC9tYW5pcHVsYXRlIGJ5IHJlZmVyZW5jZS4KCSAqIEBwYXJhbSBzdHJpbmd8aW50ICRrZXkgVGhlIGtleS9wcm9wZXJ0eSB0aGUgZGF0YSBiZWxvbmdzIHRvLgoJICogQHBhcmFtIHN0YXRpYyAkcGFyZW50CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJiRkYXRhLCAka2V5ID0gbnVsbCwgJHBhcmVudCA9IG51bGwgKSB7CgkJJHRoaXMtPmRhdGEgICA9JiAkZGF0YTsKCQkkdGhpcy0+a2V5ICAgID0gJGtleTsKCQkkdGhpcy0+cGFyZW50ID0gJHBhcmVudDsKCX0KCgkvKioKCSAqIEdldCB0aGUgbmVzdGVkIHZhbHVlIGF0IHRoZSBnaXZlbiBrZXkgcGF0aC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGludHxhcnJheSAka2V5X3BhdGgKCSAqCgkgKiBAcmV0dXJuIHN0YXRpYwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAka2V5X3BhdGggKSB7CgkJcmV0dXJuICR0aGlzLT50cmF2ZXJzZV90byggKGFycmF5KSAka2V5X3BhdGggKS0+dmFsdWUoKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY3VycmVudCBkYXRhLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHZhbHVlKCkgewoJCXJldHVybiAkdGhpcy0+ZGF0YTsKCX0KCgkvKioKCSAqIFVwZGF0ZSBhIG5lc3RlZCB2YWx1ZSBhdCB0aGUgZ2l2ZW4ga2V5IHBhdGguCgkgKgoJICogQHBhcmFtIHN0cmluZ3xpbnR8YXJyYXkgJGtleV9wYXRoCgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRrZXlfcGF0aCwgJHZhbHVlICkgewoJCSR0aGlzLT50cmF2ZXJzZV90byggKGFycmF5KSAka2V5X3BhdGggKS0+c2V0X3ZhbHVlKCAkdmFsdWUgKTsKCX0KCgkvKioKCSAqIFVwZGF0ZSB0aGUgY3VycmVudCBkYXRhIHdpdGggdGhlIGdpdmVuIHZhbHVlLgoJICoKCSAqIFRoaXMgd2lsbCBtdXRhdGUgdGhlIHZhcmlhYmxlIHdoaWNoIHdhcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IKCSAqIGFzIHRoZSBkYXRhIGlzIHNldCBhbmQgdHJhdmVyc2VkIGJ5IHJlZmVyZW5jZS4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfdmFsdWUoICR2YWx1ZSApIHsKCQkkdGhpcy0+ZGF0YSA9ICR2YWx1ZTsKCX0KCgkvKioKCSAqIFVuc2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4ga2V5IHBhdGguCgkgKgoJICogQHBhcmFtICRrZXlfcGF0aAoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAka2V5X3BhdGggKSB7CgkJJHRoaXMtPnRyYXZlcnNlX3RvKCAoYXJyYXkpICRrZXlfcGF0aCApLT51bnNldF9vbl9wYXJlbnQoKTsKCX0KCgkvKioKCSAqIERlZmluZSBhIG5lc3RlZCB2YWx1ZSB3aGlsZSBjcmVhdGluZyBrZXlzIGlmIHRoZXkgZG8gbm90IGV4aXN0LgoJICoKCSAqIEBwYXJhbSBhcnJheSAka2V5X3BhdGgKCSAqIEBwYXJhbSBtaXhlZCAkdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc2VydCggJGtleV9wYXRoLCAkdmFsdWUgKSB7CgkJdHJ5IHsKCQkJJHRoaXMtPnVwZGF0ZSggJGtleV9wYXRoLCAkdmFsdWUgKTsKCQl9IGNhdGNoICggTm9uRXhpc3RlbnRLZXlFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJJGV4Y2VwdGlvbi0+Z2V0X3RyYXZlcnNlcigpLT5jcmVhdGVfa2V5KCk7CgkJCSR0aGlzLT5pbnNlcnQoICRrZXlfcGF0aCwgJHZhbHVlICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlIHRoZSBrZXkgb24gdGhlIHBhcmVudCdzIGRhdGEgdGhhdCByZWZlcmVuY2VzIHRoaXMgZGF0YS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuc2V0X29uX3BhcmVudCgpIHsKCQkkdGhpcy0+cGFyZW50LT5kZWxldGVfYnlfa2V5KCAkdGhpcy0+a2V5ICk7Cgl9CgoJLyoqCgkgKiBEZWxldGUgdGhlIGdpdmVuIGtleSBmcm9tIHRoZSBkYXRhLgoJICoKCSAqIEBwYXJhbSAka2V5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGVfYnlfa2V5KCAka2V5ICkgewoJCWlmICggaXNfYXJyYXkoICR0aGlzLT5kYXRhICkgKSB7CgkJCXVuc2V0KCAkdGhpcy0+ZGF0YVsgJGtleSBdICk7CgkJfSBlbHNlIHsKCQkJdW5zZXQoICR0aGlzLT5kYXRhLT4ka2V5ICk7CgkJfQoJfQoKCS8qKgoJICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSB0cmF2ZXJzZXIgZm9yIHRoZSBnaXZlbiBoaWVyYXJjaGljYWwga2V5LgoJICoKCSAqIEBwYXJhbSBhcnJheSAka2V5X3BhdGggSGllcmFyY2hpY2FsIGtleSBwYXRoIHdpdGhpbiB0aGUgY3VycmVudCBkYXRhIHRvIHRyYXZlcnNlIHRvLgoJICoKCSAqIEB0aHJvd3MgTm9uRXhpc3RlbnRLZXlFeGNlcHRpb24KCSAqCgkgKiBAcmV0dXJuIHN0YXRpYwoJICovCglwdWJsaWMgZnVuY3Rpb24gdHJhdmVyc2VfdG8oIGFycmF5ICRrZXlfcGF0aCApIHsKCQkkY3VycmVudCA9IGFycmF5X3NoaWZ0KCAka2V5X3BhdGggKTsKCgkJaWYgKCBudWxsID09PSAkY3VycmVudCApIHsKCQkJcmV0dXJuICR0aGlzOwoJCX0KCgkJaWYgKCAhICR0aGlzLT5leGlzdHMoICRjdXJyZW50ICkgKSB7CgkJCSRleGNlcHRpb24gPSBuZXcgTm9uRXhpc3RlbnRLZXlFeGNlcHRpb24oICJObyBkYXRhIGV4aXN0cyBmb3Iga2V5IFwieyRjdXJyZW50fVwiIiApOwoJCQkkZXhjZXB0aW9uLT5zZXRfdHJhdmVyc2VyKCBuZXcgc3RhdGljKCAkdGhpcy0+ZGF0YSwgJGN1cnJlbnQsICR0aGlzLT5wYXJlbnQgKSApOwoJCQl0aHJvdyAkZXhjZXB0aW9uOwoJCX0KCgkJZm9yZWFjaCAoICR0aGlzLT5kYXRhIGFzICRrZXkgPT4gJiRrZXlfZGF0YSApIHsKCQkJaWYgKCAka2V5ID09PSAkY3VycmVudCApIHsKCQkJCSR0cmF2ZXJzZXIgPSBuZXcgc3RhdGljKCAka2V5X2RhdGEsICRrZXksICR0aGlzICk7CgkJCQlyZXR1cm4gJHRyYXZlcnNlci0+dHJhdmVyc2VfdG8oICRrZXlfcGF0aCApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogQ3JlYXRlIHRoZSBrZXkgb24gdGhlIGN1cnJlbnQgZGF0YS4KCSAqCgkgKiBAdGhyb3dzIFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gY3JlYXRlX2tleSgpIHsKCQlpZiAoIGlzX2FycmF5KCAkdGhpcy0+ZGF0YSApICkgewoJCQkkdGhpcy0+ZGF0YVsgJHRoaXMtPmtleSBdID0gbnVsbDsKCQl9IGVsc2VpZiAoIGlzX29iamVjdCggJHRoaXMtPmRhdGEgKSApIHsKCQkJJHRoaXMtPmRhdGEtPnskdGhpcy0+a2V5fSA9IG51bGw7CgkJfSBlbHNlIHsKCQkJJHR5cGUgPSBnZXR0eXBlKCAkdGhpcy0+ZGF0YSApOwoJCQl0aHJvdyBuZXcgVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKAoJCQkJIkNhbm5vdCBjcmVhdGUga2V5IFwieyR0aGlzLT5rZXl9XCIgb24gZGF0YSB0eXBlIHskdHlwZX0iCgkJCSk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIGdpdmVuIGtleSBleGlzdHMgb24gdGhlIGN1cnJlbnQgZGF0YS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4aXN0cyggJGtleSApIHsKCQlyZXR1cm4gKCBpc19hcnJheSggJHRoaXMtPmRhdGEgKSAmJiBhcnJheV9rZXlfZXhpc3RzKCAka2V5LCAkdGhpcy0+ZGF0YSApICkgfHwKCQkJKCBpc19vYmplY3QoICR0aGlzLT5kYXRhICkgJiYgcHJvcGVydHlfZXhpc3RzKCAkdGhpcy0+ZGF0YSwgJGtleSApICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRW50aXR5OwoKY2xhc3MgVXRpbHMgewoKCS8qKgoJICogQ2hlY2sgd2hldGhlciBhbnkgaW5wdXQgaXMgcGFzc2VkIHRvIFNURElOLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGhhc19zdGRpbigpIHsKCQkkaGFuZGxlICA9IGZvcGVuKCAncGhwOi8vc3RkaW4nLCAncicgKTsKCQkkcmVhZCAgICA9IGFycmF5KCAkaGFuZGxlICk7CgkJJHdyaXRlICAgPSBudWxsOwoJCSRleGNlcHQgID0gbnVsbDsKCQkkc3RyZWFtcyA9IHN0cmVhbV9zZWxlY3QoICRyZWFkLCAkd3JpdGUsICRleGNlcHQsIDAgKTsKCQlmY2xvc2UoICRoYW5kbGUgKTsKCgkJcmV0dXJuIDEgPT09ICRzdHJlYW1zOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIFdQLUNMSSBjb21tYW5kcyB0aGF0IGRlYWwgd2l0aCB0ZXJtcwogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmFic3RyYWN0IGNsYXNzIENvbW1hbmRXaXRoVGVybXMgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBAdmFyIHN0cmluZyAkb2JqZWN0X3R5cGUgV29yZFByZXNzJyBleHBlY3RlZCBuYW1lIGZvciB0aGUgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgJG9ial90eXBlOwoKCS8qKgoJICogQHZhciBzdHJpbmcgJG9iamVjdF9pZCBXb3JkUHJlc3MnIG9iamVjdCBpZC4KCSAqLwoJcHJvdGVjdGVkICRvYmpfaWQ7CgoJLyoqCgkgKiBAdmFyIGFycmF5ICRvYmpfZmllbGRzIERlZmF1bHQgZmllbGRzIHRvIGRpc3BsYXkgZm9yIGVhY2ggb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBbCgkJJ3Rlcm1faWQnLAoJCSduYW1lJywKCQknc2x1ZycsCgkJJ3RheG9ub215JywKCV07CgoJLyoqCgkgKiBMaXN0IGFsbCB0ZXJtcyBhc3NvY2lhdGVkIHdpdGggYW4gb2JqZWN0LgoJICoKCSAqIDxpZD4KCSAqIDogSUQgZm9yIHRoZSBvYmplY3QuCgkgKgoJICogPHRheG9ub215Pi4uLgoJICogOiBPbmUgb3IgbW9yZSB0YXhvbm9taWVzIHRvIGxpc3QuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCB0ZXJtLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyByb3cgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAgIC0gY291bnQKCSAqICAgLSBpZHMKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCB0ZXJtOgoJICoKCSAqICogdGVybV9pZAoJICogKiBuYW1lCgkgKiAqIHNsdWcKCSAqICogdGF4b25vbXkKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogdGVybV90YXhvbm9teV9pZAoJICogKiBkZXNjcmlwdGlvbgoJICogKiB0ZXJtX2dyb3VwCgkgKiAqIHBhcmVudAoJICogKiBjb3VudAoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknZm9ybWF0JyA9PiAndGFibGUnLAoJCV07CgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoKCQkkb2JqZWN0X2lkICAgICAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkdGF4b25vbXlfbmFtZXMgPSAkYXJnczsKCQkkdGF4b25vbXlfYXJncyAgPSBbXTsKCgkJJHRoaXMtPnNldF9vYmpfaWQoICRvYmplY3RfaWQgKTsKCgkJZm9yZWFjaCAoICR0YXhvbm9teV9uYW1lcyBhcyAkdGF4b25vbXkgKSB7CgkJCSR0aGlzLT50YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApOwoJCX0KCgkJaWYgKCAnaWRzJyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkkdGF4b25vbXlfYXJnc1snZmllbGRzJ10gPSAnaWRzJzsKCQl9CgoJCSRpdGVtcyA9IHdwX2dldF9vYmplY3RfdGVybXMoICRvYmplY3RfaWQsICR0YXhvbm9teV9uYW1lcywgJHRheG9ub215X2FyZ3MgKTsKCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpdGVtcyApOwoKCX0KCgoJLyoqCgkgKiBSZW1vdmUgYSB0ZXJtIGZyb20gYW4gb2JqZWN0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgb2JqZWN0LgoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIHRlcm0ncyB0YXhvbm9teS4KCSAqCgkgKiBbPHRlcm0+Li4uXQoJICogOiBUaGUgbmFtZSBvZiB0aGUgdGVybSBvciB0ZXJtcyB0byBiZSByZW1vdmVkIGZyb20gdGhlIG9iamVjdC4KCSAqCgkgKiBbLS1ieT08ZmllbGQ+XQoJICogOiBFeHBsaWNpdGx5IGhhbmRsZSB0aGUgdGVybSB2YWx1ZSBhcyBhIHNsdWcgb3IgaWQuCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0gc2x1ZwoJICogICAtIGlkCgkgKiAtLS0KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IFJlbW92ZSBhbGwgdGVybXMgZnJvbSB0aGUgb2JqZWN0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJG9iamVjdF9pZCA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSR0YXhvbm9teSAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkdGVybXMgICAgID0gJGFyZ3M7CgoJCSR0aGlzLT5zZXRfb2JqX2lkKCAkb2JqZWN0X2lkICk7CgoJCSR0aGlzLT50YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApOwoKCQkkZmllbGQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdieScgKTsKCQlpZiAoICRmaWVsZCApIHsKCQkJJHRlcm1zID0gJHRoaXMtPnByZXBhcmVfdGVybXMoICRmaWVsZCwgJHRlcm1zLCAkdGF4b25vbXkgKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoKCQkJLy8gTm8gbmVlZCB0byBzcGVjaWZ5IHRlcm1zIHdoaWxlIHJlbW92aW5nIGFsbCB0ZXJtcy4KCQkJaWYgKCAkdGVybXMgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnTm8gbmVlZCB0byBzcGVjaWZ5IHRlcm1zIHdoaWxlIHJlbW92aW5nIGFsbCB0ZXJtcy4nICk7CgkJCX0KCgkJCS8vIFJlbW92ZSBhbGwgc2V0IGNhdGVnb3JpZXMgZnJvbSBwb3N0LgoJCQkkcmVzdWx0ID0gd3BfZGVsZXRlX29iamVjdF90ZXJtX3JlbGF0aW9uc2hpcHMoICRvYmplY3RfaWQsICR0YXhvbm9teSApOwoKCQkJJG1lc3NhZ2UgPSAnUmVtb3ZlZCBhbGwgdGVybXMuJzsKCQkJaWYgKCAnY2F0ZWdvcnknID09PSAkdGF4b25vbXkgKSB7CgoJCQkJLy8gU2V0IGRlZmF1bHQgY2F0ZWdvcnkgdG8gcG9zdC4KCQkJCSRkZWZhdWx0X2NhdGVnb3J5ID0gKGludCkgZ2V0X29wdGlvbiggJ2RlZmF1bHRfY2F0ZWdvcnknICk7CgkJCQkkZGVmYXVsdF9jYXRlZ29yeSA9ICggISBlbXB0eSggJGRlZmF1bHRfY2F0ZWdvcnkgKSApID8gJGRlZmF1bHRfY2F0ZWdvcnkgOiAxOwoJCQkJJGRlZmF1bHRfY2F0ZWdvcnkgPSB3cF9zZXRfb2JqZWN0X3Rlcm1zKCAkb2JqZWN0X2lkLCBbICRkZWZhdWx0X2NhdGVnb3J5IF0sICR0YXhvbm9teSwgdHJ1ZSApOwoKCQkJCWlmICggaXNfd3BfZXJyb3IoICRkZWZhdWx0X2NhdGVnb3J5ICkgKSB7CgkJCQkJV1BfQ0xJOjplcnJvciggJ0ZhaWxlZCB0byBzZXQgZGVmYXVsdCB0ZXJtLicgKTsKCQkJCX0KCgkJCQkkbWVzc2FnZSA9ICdSZW1vdmVkIGFsbCB0ZXJtcyBhbmQgc2V0IGRlZmF1bHQgdGVybS4nOwoJCQl9CgoJCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnRmFpbGVkIHRvIHJlbW92ZSBhbGwgdGVybXMuJyApOwoJCQl9CgoJCQlXUF9DTEk6OnN1Y2Nlc3MoICRtZXNzYWdlICk7CgoJCQlyZXR1cm47CgkJfQoKCQkvLyBBYm9ydCBpZiBubyB0ZXJtcyBhcmUgc3BlY2lmaWVkLgoJCWlmICggISAkdGVybXMgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSB0ZXJtcywgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCS8vIFJlbW92ZSB0ZXJtIGZyb20gcG9zdC4KCQkkcmVzdWx0ID0gd3BfcmVtb3ZlX29iamVjdF90ZXJtcyggJG9iamVjdF9pZCwgJHRlcm1zLCAkdGF4b25vbXkgKTsKCgkJJGxhYmVsID0gY291bnQoICR0ZXJtcyApID4gMSA/ICd0ZXJtcycgOiAndGVybSc7CgoJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkZhaWxlZCB0byByZW1vdmUgeyRsYWJlbH0uIiApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiUmVtb3ZlZCB7JGxhYmVsfS4iICk7Cgl9CgoJLyoqCgkgKiBBZGQgYSB0ZXJtIHRvIGFuIG9iamVjdC4KCSAqCgkgKiBBcHBlbmQgdGhlIHRlcm0gdG8gdGhlIGV4aXN0aW5nIHNldCBvZiB0ZXJtcyBvbiB0aGUgb2JqZWN0LgoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPHRheG9ub215PgoJICogOiBUaGUgbmFtZSBvZiB0aGUgdGF4b25vbXkgdHlwZSB0byBiZSBhZGRlZC4KCSAqCgkgKiA8dGVybT4uLi4KCSAqIDogVGhlIHNsdWcgb2YgdGhlIHRlcm0gb3IgdGVybXMgdG8gYmUgYWRkZWQuCgkgKgoJICogWy0tYnk9PGZpZWxkPl0KCSAqIDogRXhwbGljaXRseSBoYW5kbGUgdGhlIHRlcm0gdmFsdWUgYXMgYSBzbHVnIG9yIGlkLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIHNsdWcKCSAqICAgLSBpZAoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkb2JqZWN0X2lkID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJHRheG9ub215ICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSR0ZXJtcyAgICAgPSAkYXJnczsKCgkJJHRoaXMtPnNldF9vYmpfaWQoICRvYmplY3RfaWQgKTsKCgkJJHRoaXMtPnRheG9ub215X2V4aXN0cyggJHRheG9ub215ICk7CgoJCSRmaWVsZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2J5JyApOwoJCWlmICggJGZpZWxkICkgewoJCQkkdGVybXMgPSAkdGhpcy0+cHJlcGFyZV90ZXJtcyggJGZpZWxkLCAkdGVybXMsICR0YXhvbm9teSApOwoJCX0KCQkkcmVzdWx0ID0gd3Bfc2V0X29iamVjdF90ZXJtcyggJG9iamVjdF9pZCwgJHRlcm1zLCAkdGF4b25vbXksIHRydWUgKTsKCgkJJGxhYmVsID0gY291bnQoICR0ZXJtcyApID4gMSA/ICd0ZXJtcycgOiAndGVybSc7CgkJaWYgKCAhIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkIHskbGFiZWx9LiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAiRmFpbGVkIHRvIGFkZCB7JGxhYmVsfS4iICk7CgkJfQoJfQoKCS8qKgoJICogU2V0IG9iamVjdCB0ZXJtcy4KCSAqCgkgKiBSZXBsYWNlcyBleGlzdGluZyB0ZXJtcyBvbiB0aGUgb2JqZWN0LgoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPHRheG9ub215PgoJICogOiBUaGUgbmFtZSBvZiB0aGUgdGF4b25vbXkgdHlwZSB0byBiZSB1cGRhdGVkLgoJICoKCSAqIDx0ZXJtPi4uLgoJICogOiBUaGUgc2x1ZyBvZiB0aGUgdGVybSBvciB0ZXJtcyB0byBiZSB1cGRhdGVkLgoJICoKCSAqIFstLWJ5PTxmaWVsZD5dCgkgKiA6IEV4cGxpY2l0bHkgaGFuZGxlIHRoZSB0ZXJtIHZhbHVlIGFzIGEgc2x1ZyBvciBpZC4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBzbHVnCgkgKiAgIC0gaWQKCSAqIC0tLQoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJG9iamVjdF9pZCA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSR0YXhvbm9teSAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkdGVybXMgICAgID0gJGFyZ3M7CgoJCSR0aGlzLT5zZXRfb2JqX2lkKCAkb2JqZWN0X2lkICk7CgoJCSR0aGlzLT50YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApOwoKCQkkZmllbGQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdieScgKTsKCQlpZiAoICRmaWVsZCApIHsKCQkJJHRlcm1zID0gJHRoaXMtPnByZXBhcmVfdGVybXMoICRmaWVsZCwgJHRlcm1zLCAkdGF4b25vbXkgKTsKCQl9CgkJJHJlc3VsdCA9IHdwX3NldF9vYmplY3RfdGVybXMoICRvYmplY3RfaWQsICR0ZXJtcywgJHRheG9ub215LCBmYWxzZSApOwoKCQkkbGFiZWwgPSBjb3VudCggJHRlcm1zICkgPiAxID8gJ3Rlcm1zJyA6ICd0ZXJtJzsKCQlpZiAoICEgaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiU2V0IHskbGFiZWx9LiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAiRmFpbGVkIHRvIHNldCB7JGxhYmVsfS4iICk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGF4b25vbXkgZXhpc3RzCgkgKgoJICogQHBhcmFtICR0YXhvbm9teQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdGF4b25vbXlfZXhpc3RzKCAkdGF4b25vbXkgKSB7CgoJCSR0YXhvbm9teV9uYW1lcyA9IGdldF9vYmplY3RfdGF4b25vbWllcyggJHRoaXMtPmdldF9vYmplY3RfdHlwZSgpICk7CgoJCWlmICggISBpbl9hcnJheSggJHRheG9ub215LCAkdGF4b25vbXlfbmFtZXMsIHRydWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgdGF4b25vbXkgeyR0YXhvbm9teX0uIiApOwoJCX0KCX0KCgkvKioKCSAqIFByZXBhcmUgdGVybXMgaWYgYC0tYnk9PGZpZWxkPmAgZmxhZyBpcyB1c2VkCgkgKgoJICogQHBhcmFtIGFycmF5ICR0ZXJtcwoJICogQHBhcmFtIHN0cmluZyAkZmllbGQKCSAqIEBwYXJhbSBzdHJpbmcgJHRheG9ub215CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBwcmVwYXJlX3Rlcm1zKCAkZmllbGQsICR0ZXJtcywgJHRheG9ub215ICkgewoJCWlmICggJ2lkJyA9PT0gJGZpZWxkICkgewoJCQkkbmV3X3Rlcm1zID0gW107CgkJCWZvcmVhY2ggKCAkdGVybXMgYXMgJHRlcm1faWQgKSB7CgkJCQkkdGVybSA9IGdldF90ZXJtX2J5KCAndGVybV9pZCcsICR0ZXJtX2lkLCAkdGF4b25vbXkgKTsKCQkJCWlmICggJHRlcm0gKSB7CgkJCQkJJG5ld190ZXJtc1tdID0gJHRlcm0tPnNsdWc7CgkJCQl9CgkJCX0KCQkJJHRlcm1zID0gJG5ld190ZXJtczsKCQl9CgkJcmV0dXJuICR0ZXJtczsKCX0KCgkvKioKCSAqIFNldCBvYmpfaWQgQ2xhc3MgdmFyaWFibGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRvYmpfaWQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9vYmpfaWQoICRvYmpfaWQgKSB7CgkJJHRoaXMtPm9ial9pZCA9ICRvYmpfaWQ7Cgl9CgoJLyoqCgkgKiBHZXQgb2JqX2lkIENsYXNzIHZhcmlhYmxlCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9vYmpfaWQoKSB7CgkJcmV0dXJuICR0aGlzLT5vYmpfaWQ7Cgl9CgoKCS8qKgoJICogR2V0IG9ial90eXBlIENsYXNzIHZhcmlhYmxlCgkgKgoJICogQHJldHVybiBzdHJpbmcgJG9ial90eXBlCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfb2JqZWN0X3R5cGUoKSB7CgkJcmV0dXJuICR0aGlzLT5vYmpfdHlwZTsKCX0KCgkvKioKCSAqIEdldCBGb3JtYXR0ZXIgb2JqZWN0IGJhc2VkIG9uIHN1cHBsaWVkIHBhcmFtZXRlcnMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFBhcmFtZXRlcnMgcGFzc2VkIHRvIGNvbW1hbmQuIERldGVybWluZXMgZm9ybWF0dGluZy4KCSAqCgkgKiBAcmV0dXJuIFdQX0NMSVxGb3JtYXR0ZXIKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5vYmpfZmllbGRzLCAkdGhpcy0+b2JqX3R5cGUgKTsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgRXhjZXB0aW9uOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJX0NvbW1hbmQ7CnVzZSBXUF9DTElcRW50aXR5XFJlY3Vyc2l2ZURhdGFTdHJ1Y3R1cmVUcmF2ZXJzZXI7CnVzZSBXUF9DTElcRW50aXR5XFV0aWxzIGFzIEVudGl0eVV0aWxzOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIFdQLUNMSSBjb21tYW5kcyB0aGF0IGRlYWwgd2l0aCBtZXRhZGF0YQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmFic3RyYWN0IGNsYXNzIENvbW1hbmRXaXRoTWV0YSBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcm90ZWN0ZWQgJG1ldGFfdHlwZTsKCgkvKioKCSAqIExpc3QgYWxsIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCBhbiBvYmplY3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogSUQgZm9yIHRoZSBvYmplY3QuCgkgKgoJICogWy0ta2V5cz08a2V5cz5dCgkgKiA6IExpbWl0IG91dHB1dCB0byBtZXRhZGF0YSBvZiBzcGVjaWZpYyBrZXlzLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyByb3cgZmllbGRzLiBEZWZhdWx0cyB0byBpZCxtZXRhX2tleSxtZXRhX3ZhbHVlLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAgIC0gY291bnQKCSAqIC0tLQoJICoKCSAqIFstLW9yZGVyYnk9PGZpZWxkcz5dCgkgKiA6IFNldCBvcmRlcmJ5IHdoaWNoIGZpZWxkLgoJICogLS0tCgkgKiBkZWZhdWx0OiBpZAoJICogb3B0aW9uczoKCSAqICAtIGlkCgkgKiAgLSBtZXRhX2tleQoJICogIC0gbWV0YV92YWx1ZQoJICogLS0tCgkgKgoJICogWy0tb3JkZXI9PG9yZGVyPl0KCSAqIDogU2V0IGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIG9yZGVyLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhc2MKCSAqIG9wdGlvbnM6CgkgKiAgLSBhc2MKCSAqICAtIGRlc2MKCSAqIC0tLQoJICoKCSAqIFstLXVuc2VyaWFsaXplXQoJICogOiBVbnNlcmlhbGl6ZSBtZXRhX3ZhbHVlIG91dHB1dC4KCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkb2JqZWN0X2lkICkgPSAkYXJnczsKCgkJJGtleXMgPSAhIGVtcHR5KCAkYXNzb2NfYXJnc1sna2V5cyddICkgPyBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydrZXlzJ10gKSA6IFtdOwoKCQkkb2JqZWN0X2lkID0gJHRoaXMtPmNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApOwoKCQkkbWV0YWRhdGEgPSAkdGhpcy0+Z2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkICk7CgkJaWYgKCAhICRtZXRhZGF0YSApIHsKCQkJJG1ldGFkYXRhID0gW107CgkJfQoKCQkkaXRlbXMgPSBbXTsKCQlmb3JlYWNoICggJG1ldGFkYXRhIGFzICRrZXkgPT4gJHZhbHVlcyApIHsKCgkJCS8vIFNraXAgaWYgbm90IHJlcXVlc3RlZAoJCQlpZiAoICEgZW1wdHkoICRrZXlzICkgJiYgISBpbl9hcnJheSggJGtleSwgJGtleXMsIHRydWUgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlmb3JlYWNoICggJHZhbHVlcyBhcyAkaXRlbV92YWx1ZSApIHsKCgkJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3Vuc2VyaWFsaXplJyApICkgewoJCQkJCSRpdGVtX3ZhbHVlID0gbWF5YmVfdW5zZXJpYWxpemUoICRpdGVtX3ZhbHVlICk7CgkJCQl9CgoJCQkJJGl0ZW1zW10gPSAob2JqZWN0KSBbCgkJCQkJInskdGhpcy0+bWV0YV90eXBlfV9pZCIgPT4gJG9iamVjdF9pZCwKCQkJCQknbWV0YV9rZXknICAgICAgICAgICAgICA9PiAka2V5LAoJCQkJCSdtZXRhX3ZhbHVlJyAgICAgICAgICAgID0+ICRpdGVtX3ZhbHVlLAoJCQkJXTsKCQkJfQoJCX0KCgkJJG9yZGVyICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdvcmRlcicgKTsKCQkkb3JkZXJieSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ29yZGVyYnknICk7CgoJCWlmICggJ2lkJyAhPT0gJG9yZGVyYnkgKSB7CgoJCQl1c29ydCgKCQkJCSRpdGVtcywKCQkJCWZ1bmN0aW9uICggJGEsICRiICkgdXNlICggJG9yZGVyYnksICRvcmRlciApIHsKCQkJCQkvLyBTb3J0IGFycmF5LgoJCQkJCXJldHVybiAnYXNjJyA9PT0gJG9yZGVyCgkJCQkJCT8gJGEtPiRvcmRlcmJ5ID4gJGItPiRvcmRlcmJ5CgkJCQkJCTogJGEtPiRvcmRlcmJ5IDwgJGItPiRvcmRlcmJ5OwoJCQkJfQoJCQkpOwoKCQl9IGVsc2VpZiAoICdpZCcgPT09ICRvcmRlcmJ5ICYmICdkZXNjJyA9PT0gJG9yZGVyICkgeyAvLyBTb3J0IGJ5IGRlZmF1bHQgZGVzY2VuZGluZy4KCQkJa3Jzb3J0KCAkaXRlbXMgKTsKCQl9CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRmaWVsZHMgPSBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydmaWVsZHMnXSApOwoJCX0gZWxzZSB7CgkJCSRmaWVsZHMgPSAkdGhpcy0+Z2V0X2ZpZWxkcygpOwoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkZmllbGRzLCAkdGhpcy0+bWV0YV90eXBlICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGl0ZW1zICk7CgoJfQoKCS8qKgoJICogR2V0IG1ldGEgZmllbGQgdmFsdWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIG1ldGEgZmllbGQgdG8gZ2V0LgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogR2V0IHZhbHVlIGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHZhcl9leHBvcnQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdmFyX2V4cG9ydAoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRvYmplY3RfaWQsICRtZXRhX2tleSApID0gJGFyZ3M7CgoJCSRvYmplY3RfaWQgPSAkdGhpcy0+Y2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICk7CgoJCSR2YWx1ZSA9ICR0aGlzLT5nZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgdHJ1ZSApOwoKCQlpZiAoICcnID09PSAkdmFsdWUgKSB7CgkJCWRpZSggMSApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogRGVsZXRlIGEgbWV0YSBmaWVsZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPgoJICogOiBUaGUgSUQgb2YgdGhlIG9iamVjdC4KCSAqCgkgKiBbPGtleT5dCgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBtZXRhIGZpZWxkIHRvIGRlbGV0ZS4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIHZhbHVlIHRvIGRlbGV0ZS4gSWYgb21pdHRlZCwgYWxsIHJvd3Mgd2l0aCBrZXkgd2lsbCBkZWxldGVkLgoJICoKCSAqIFstLWFsbF0KCSAqIDogRGVsZXRlIGFsbCBtZXRhIGZvciB0aGUgb2JqZWN0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJG9iamVjdF9pZCApID0gJGFyZ3M7CgoJCSRtZXRhX2tleSAgID0gISBlbXB0eSggJGFyZ3NbMV0gKSA/ICRhcmdzWzFdIDogJyc7CgkJJG1ldGFfdmFsdWUgPSAhIGVtcHR5KCAkYXJnc1syXSApID8gJGFyZ3NbMl0gOiAnJzsKCgkJaWYgKCBlbXB0eSggJG1ldGFfa2V5ICkgJiYgISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSBhIG1ldGEga2V5LCBvciB1c2UgdGhlIC0tYWxsIGZsYWcuJyApOwoJCX0KCgkJJG9iamVjdF9pZCA9ICR0aGlzLT5jaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgKSB7CgkJCSRlcnJvcnMgPSBmYWxzZTsKCQkJZm9yZWFjaCAoICR0aGlzLT5nZXRfbWV0YWRhdGEoICRvYmplY3RfaWQgKSBhcyAkbWV0YV9rZXkgPT4gJHZhbHVlcyApIHsKCQkJCSRzdWNjZXNzID0gJHRoaXMtPmRlbGV0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5ICk7CgkJCQlpZiAoICRzdWNjZXNzICkgewoJCQkJCVdQX0NMSTo6bG9nKCAiRGVsZXRlZCAneyRtZXRhX2tleX0nIGN1c3RvbSBmaWVsZC4iICk7CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIkZhaWxlZCB0byBkZWxldGUgJ3skbWV0YV9rZXl9JyBjdXN0b20gZmllbGQuIiApOwoJCQkJCSRlcnJvcnMgPSB0cnVlOwoJCQkJfQoJCQl9CgkJCWlmICggJGVycm9ycyApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdGYWlsZWQgdG8gZGVsZXRlIGFsbCBjdXN0b20gZmllbGRzLicgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ0RlbGV0ZWQgYWxsIGN1c3RvbSBmaWVsZHMuJyApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHN1Y2Nlc3MgPSAkdGhpcy0+ZGVsZXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlICk7CgkJCWlmICggJHN1Y2Nlc3MgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdEZWxldGVkIGN1c3RvbSBmaWVsZC4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnRmFpbGVkIHRvIGRlbGV0ZSBjdXN0b20gZmllbGQuJyApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogQWRkIGEgbWV0YSBmaWVsZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPgoJICogOiBUaGUgSUQgb2YgdGhlIG9iamVjdC4KCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgbmFtZSBvZiB0aGUgbWV0YSBmaWVsZCB0byBjcmVhdGUuCgkgKgoJICogWzx2YWx1ZT5dCgkgKiA6IFRoZSB2YWx1ZSBvZiB0aGUgbWV0YSBmaWVsZC4gSWYgb21pdHRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkb2JqZWN0X2lkLCAkbWV0YV9rZXkgKSA9ICRhcmdzOwoKCQkkbWV0YV92YWx1ZSA9IFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgMiApOwoJCSRtZXRhX3ZhbHVlID0gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkbWV0YV92YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCgkJJG9iamVjdF9pZCA9ICR0aGlzLT5jaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKTsKCgkJJG1ldGFfdmFsdWUgPSB3cF9zbGFzaCggJG1ldGFfdmFsdWUgKTsKCQkkc3VjY2VzcyAgICA9ICR0aGlzLT5hZGRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgKTsKCgkJaWYgKCAkc3VjY2VzcyApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnQWRkZWQgY3VzdG9tIGZpZWxkLicgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAnRmFpbGVkIHRvIGFkZCBjdXN0b20gZmllbGQuJyApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZSBhIG1ldGEgZmllbGQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIG1ldGEgZmllbGQgdG8gdXBkYXRlLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgbmV3IHZhbHVlLiBJZiBvbWl0dGVkLCB0aGUgdmFsdWUgaXMgcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiBAYWxpYXMgc2V0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkb2JqZWN0X2lkLCAkbWV0YV9rZXkgKSA9ICRhcmdzOwoKCQkkbWV0YV92YWx1ZSA9IFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgMiApOwoJCSRtZXRhX3ZhbHVlID0gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkbWV0YV92YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCgkJJG9iamVjdF9pZCA9ICR0aGlzLT5jaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKTsKCgkJJG1ldGFfdmFsdWUgPSBzYW5pdGl6ZV9tZXRhKCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdGhpcy0+bWV0YV90eXBlICk7CgkJJG9sZF92YWx1ZSAgPSBzYW5pdGl6ZV9tZXRhKCAkbWV0YV9rZXksICR0aGlzLT5nZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgdHJ1ZSApLCAkdGhpcy0+bWV0YV90eXBlICk7CgoJCWlmICggJG1ldGFfdmFsdWUgPT09ICRvbGRfdmFsdWUgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlZhbHVlIHBhc3NlZCBmb3IgY3VzdG9tIGZpZWxkICd7JG1ldGFfa2V5fScgaXMgdW5jaGFuZ2VkLiIgKTsKCQl9IGVsc2UgewoJCQkkbWV0YV92YWx1ZSA9IHdwX3NsYXNoKCAkbWV0YV92YWx1ZSApOwoJCQkkc3VjY2VzcyAgICA9ICR0aGlzLT51cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgKTsKCgkJCWlmICggJHN1Y2Nlc3MgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJVcGRhdGVkIGN1c3RvbSBmaWVsZCAneyRtZXRhX2tleX0nLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gdXBkYXRlIGN1c3RvbSBmaWVsZCAneyRtZXRhX2tleX0nLiIgKTsKCQkJfQoJCX0KCgl9CgoJLyoqCgkgKiBHZXQgYSBuZXN0ZWQgdmFsdWUgZnJvbSBhIG1ldGEgZmllbGQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIG1ldGEgZmllbGQgdG8gZ2V0LgoJICoKCSAqIDxrZXktcGF0aD4uLi4KCSAqIDogVGhlIG5hbWUocykgb2YgdGhlIGtleXMgd2l0aGluIHRoZSB2YWx1ZSB0byBsb2NhdGUgdGhlIHZhbHVlIHRvIHBsdWNrLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIG91dHB1dCBmb3JtYXQgb2YgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBsdWNrKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJG9iamVjdF9pZCwgJG1ldGFfa2V5ICkgPSAkYXJnczsKCQkkb2JqZWN0X2lkICAgICAgICAgICAgICAgICAgICA9ICR0aGlzLT5jaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKTsKCQkka2V5X3BhdGggICAgICAgICAgICAgICAgICAgICA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24gKCAka2V5ICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAka2V5ICkgJiYgKCAoc3RyaW5nKSBpbnR2YWwoICRrZXkgKSA9PT0gJGtleSApICkgewoJCQkJCXJldHVybiAoaW50KSAka2V5OwoJCQkJfQoJCQkJcmV0dXJuICRrZXk7CgkJCX0sCgkJCWFycmF5X3NsaWNlKCAkYXJncywgMiApCgkJKTsKCgkJJHZhbHVlID0gJHRoaXMtPmdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCB0cnVlICk7CgoJCSR0cmF2ZXJzZXIgPSBuZXcgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciggJHZhbHVlICk7CgoJCXRyeSB7CgkJCSR2YWx1ZSA9ICR0cmF2ZXJzZXItPmdldCggJGtleV9wYXRoICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlkaWUoIDEgKTsKCQl9CgoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIFVwZGF0ZSBhIG5lc3RlZCB2YWx1ZSBmb3IgYSBtZXRhIGZpZWxkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8YWN0aW9uPgoJICogOiBQYXRjaCBhY3Rpb24gdG8gcGVyZm9ybS4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBpbnNlcnQKCSAqICAgLSB1cGRhdGUKCSAqICAgLSBkZWxldGUKCSAqIC0tLQoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIG1ldGEgZmllbGQgdG8gdXBkYXRlLgoJICoKCSAqIDxrZXktcGF0aD4uLi4KCSAqIDogVGhlIG5hbWUocykgb2YgdGhlIGtleXMgd2l0aGluIHRoZSB2YWx1ZSB0byBsb2NhdGUgdGhlIHZhbHVlIHRvIHBhdGNoLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgbmV3IHZhbHVlLiBJZiBvbWl0dGVkLCB0aGUgdmFsdWUgaXMgcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGFjdGlvbiwgJG9iamVjdF9pZCwgJG1ldGFfa2V5ICkgPSAkYXJnczsKCQkkb2JqZWN0X2lkICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICR0aGlzLT5jaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKTsKCQkka2V5X3BhdGggICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRrZXkgKSB7CgkJCQlpZiAoIGlzX251bWVyaWMoICRrZXkgKSAmJiAoIChzdHJpbmcpIGludHZhbCggJGtleSApID09PSAka2V5ICkgKSB7CgkJCQkJcmV0dXJuIChpbnQpICRrZXk7CgkJCQl9CgkJCQkJcmV0dXJuICRrZXk7CgkJCX0sCgkJCWFycmF5X3NsaWNlKCAkYXJncywgMyApCgkJKTsKCgkJaWYgKCAnZGVsZXRlJyA9PT0gJGFjdGlvbiApIHsKCQkJJHBhdGNoX3ZhbHVlID0gbnVsbDsKCQl9IGVsc2UgewoJCQkkc3RkaW5fdmFsdWUgPSBFbnRpdHlVdGlsczo6aGFzX3N0ZGluKCkKCQkJCT8gdHJpbSggV1BfQ0xJOjpnZXRfdmFsdWVfZnJvbV9hcmdfb3Jfc3RkaW4oICRhcmdzLCAtMSApICkKCQkJCTogbnVsbDsKCQkJJHBhdGNoX3ZhbHVlID0gISBlbXB0eSggJHN0ZGluX3ZhbHVlICkKCQkJCT8gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkc3RkaW5fdmFsdWUsICRhc3NvY19hcmdzICkKCQkJCTogV1BfQ0xJOjpyZWFkX3ZhbHVlKCBhcnJheV9wb3AoICRrZXlfcGF0aCApLCAkYXNzb2NfYXJncyApOwoJCX0KCgkJLyogTmVlZCB0byBtYWtlIGEgY29weSBvZiAkY3VycmVudF9tZXRhX3ZhbHVlIGhlcmUgYXMgaXQgaXMgbW9kaWZpZWQgYnkgcmVmZXJlbmNlICovCgkJJGN1cnJlbnRfbWV0YV92YWx1ZSA9IHNhbml0aXplX21ldGEoICRtZXRhX2tleSwgJHRoaXMtPmdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCB0cnVlICksICR0aGlzLT5tZXRhX3R5cGUgKTsKCQkkb2xkX21ldGFfdmFsdWUgICAgID0gJGN1cnJlbnRfbWV0YV92YWx1ZTsKCQlpZiAoIGlzX29iamVjdCggJGN1cnJlbnRfbWV0YV92YWx1ZSApICkgewoJCQkkb2xkX21ldGFfdmFsdWUgPSBjbG9uZSAkY3VycmVudF9tZXRhX3ZhbHVlOwoJCX0KCgkJJHRyYXZlcnNlciA9IG5ldyBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyKCAkY3VycmVudF9tZXRhX3ZhbHVlICk7CgoJCXRyeSB7CgkJCSR0cmF2ZXJzZXItPiRhY3Rpb24oICRrZXlfcGF0aCwgJHBhdGNoX3ZhbHVlICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgoJCSRwYXRjaGVkX21ldGFfdmFsdWUgPSBzYW5pdGl6ZV9tZXRhKCAkbWV0YV9rZXksICR0cmF2ZXJzZXItPnZhbHVlKCksICR0aGlzLT5tZXRhX3R5cGUgKTsKCgkJaWYgKCAkcGF0Y2hlZF9tZXRhX3ZhbHVlID09PSAkb2xkX21ldGFfdmFsdWUgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlZhbHVlIHBhc3NlZCBmb3IgY3VzdG9tIGZpZWxkICd7JG1ldGFfa2V5fScgaXMgdW5jaGFuZ2VkLiIgKTsKCQl9IGVsc2UgewoJCQkkc2xhc2hlZCA9IHdwX3NsYXNoKCAkcGF0Y2hlZF9tZXRhX3ZhbHVlICk7CgkJCSRzdWNjZXNzID0gJHRoaXMtPnVwZGF0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkc2xhc2hlZCApOwoKCQkJaWYgKCAkc3VjY2VzcyApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIlVwZGF0ZWQgY3VzdG9tIGZpZWxkICd7JG1ldGFfa2V5fScuIiApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjplcnJvciggIkZhaWxlZCB0byB1cGRhdGUgY3VzdG9tIGZpZWxkICd7JG1ldGFfa2V5fScuIiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGFkZF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBib29sICAgJHVuaXF1ZSAgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIFdoZXRoZXIgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBtZXRhZGF0YSBrZXkgc2hvdWxkIGJlIHVuaXF1ZSBmb3IgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC4gSWYgdHJ1ZSwgYW5kIHRoZSBvYmplY3QgYWxyZWFkeSBoYXMgYQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRhZGF0YSBrZXksIG5vIGNoYW5nZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIG1hZGUuCgkgKgoJICogQHJldHVybiBpbnR8ZmFsc2UgVGhlIG1ldGEgSUQgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSA9IGZhbHNlICkgewoJCXJldHVybiBhZGRfbWV0YWRhdGEoICR0aGlzLT5tZXRhX3R5cGUsICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciB1cGRhdGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gbWl4ZWQgICRwcmV2X3ZhbHVlIE9wdGlvbmFsLiBJZiBzcGVjaWZpZWQsIG9ubHkgdXBkYXRlIGV4aXN0aW5nCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBPdGhlcndpc2UsIHVwZGF0ZSBhbGwgZW50cmllcy4KCSAqCgkgKiBAcmV0dXJuIGludHxib29sIE1ldGEgSUQgaWYgdGhlIGtleSBkaWRuJ3QgZXhpc3QsIHRydWUgb24gc3VjY2Vzc2Z1bAoJICogICAgICAgICAgICAgICAgICB1cGRhdGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIHVwZGF0ZV9tZXRhZGF0YSggJHRoaXMtPm1ldGFfdHlwZSwgJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHByZXZfdmFsdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBnZXRfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgIE9wdGlvbmFsLiBNZXRhZGF0YSBrZXkuIElmIG5vdCBzcGVjaWZpZWQsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0cmlldmUgYWxsIG1ldGFkYXRhIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdC4KCSAqIEBwYXJhbSBib29sICAgJHNpbmdsZSAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gSWYgdHJ1ZSwgcmV0dXJuIG9ubHkKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZmlyc3QgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBtZXRhX2tleS4gVGhpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IGlmIG1ldGFfa2V5IGlzIG5vdAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZC4KCSAqCgkgKiBAcmV0dXJuIG1peGVkIFNpbmdsZSBtZXRhZGF0YSB2YWx1ZSwgb3IgYXJyYXkgb2YgdmFsdWVzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXkgPSAnJywgJHNpbmdsZSA9IGZhbHNlICkgewoJCXJldHVybiBnZXRfbWV0YWRhdGEoICR0aGlzLT5tZXRhX3R5cGUsICRvYmplY3RfaWQsICRtZXRhX2tleSwgJHNpbmdsZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGRlbGV0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCBtZXRhZGF0YSBpcyBmb3IKCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJG1ldGFfdmFsdWUgIE9wdGlvbmFsLiBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm9uLXNjYWxhci4gSWYgc3BlY2lmaWVkLCBvbmx5IGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhpcyB2YWx1ZS4gT3RoZXJ3aXNlLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWxsIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzIGBudWxsLCBgZmFsc2VgLCBvciBhbiBlbXB0eSBzdHJpbmcgdG8gc2tpcAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGNoZWNrLiBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaXQgaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90IHBvc3NpYmxlIHRvIHBhc3MgYW4gZW1wdHkgc3RyaW5nIHRvIGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aG9zZSBlbnRyaWVzIHdpdGggYW4gZW1wdHkgc3RyaW5nIGZvciBhIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBUcnVlIG9uIHN1Y2Nlc3NmdWwgZGVsZXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVsZXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIGRlbGV0ZV9tZXRhZGF0YSggJHRoaXMtPm1ldGFfdHlwZSwgJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgZmFsc2UgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgZmllbGRzIGZvciB0aGlzIG9iamVjdCdzIG1ldGEKCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2ZpZWxkcygpIHsKCQlyZXR1cm4gWwoJCQkieyR0aGlzLT5tZXRhX3R5cGV9X2lkIiwKCQkJJ21ldGFfa2V5JywKCQkJJ21ldGFfdmFsdWUnLAoJCV07Cgl9CgoJLyoqCgkgKiBDaGVjayB0aGF0IHRoZSBvYmplY3QgSUQgZXhpc3RzCgkgKgoJICogQHBhcmFtIGludAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICkgewoJCS8vIE5lZWRzIHRvIGJlIHNldCBpbiBzdWJjbGFzcwoJCXJldHVybiAkb2JqZWN0X2lkOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aE1ldGE7CnVzZSBXUF9DTElcRmV0Y2hlcnNcUG9zdCBhcyBQb3N0RmV0Y2hlcjsKCi8qKgogKiBBZGRzLCB1cGRhdGVzLCBkZWxldGVzLCBhbmQgbGlzdHMgcG9zdCBjdXN0b20gZmllbGRzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBTZXQgcG9zdCBtZXRhCiAqICAgICAkIHdwIHBvc3QgbWV0YSBzZXQgMTIzIF93cF9wYWdlX3RlbXBsYXRlIGFib3V0LnBocAogKiAgICAgU3VjY2VzczogVXBkYXRlZCBjdXN0b20gZmllbGQgJ193cF9wYWdlX3RlbXBsYXRlJy4KICoKICogICAgICMgR2V0IHBvc3QgbWV0YQogKiAgICAgJCB3cCBwb3N0IG1ldGEgZ2V0IDEyMyBfd3BfcGFnZV90ZW1wbGF0ZQogKiAgICAgYWJvdXQucGhwCiAqCiAqICAgICAjIFVwZGF0ZSBwb3N0IG1ldGEKICogICAgICQgd3AgcG9zdCBtZXRhIHVwZGF0ZSAxMjMgX3dwX3BhZ2VfdGVtcGxhdGUgY29udGFjdC5waHAKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY3VzdG9tIGZpZWxkICdfd3BfcGFnZV90ZW1wbGF0ZScuCiAqCiAqICAgICAjIERlbGV0ZSBwb3N0IG1ldGEKICogICAgICQgd3AgcG9zdCBtZXRhIGRlbGV0ZSAxMjMgX3dwX3BhZ2VfdGVtcGxhdGUKICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY3VzdG9tIGZpZWxkLgogKi8KY2xhc3MgUG9zdF9NZXRhX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aE1ldGEgewoJcHJvdGVjdGVkICRtZXRhX3R5cGUgPSAncG9zdCc7CgoJLyoqCgkgKiBDaGVjayB0aGF0IHRoZSBwb3N0IElEIGV4aXN0cwoJICoKCSAqIEBwYXJhbSBpbnQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApIHsKCQkkZmV0Y2hlciA9IG5ldyBQb3N0RmV0Y2hlcigpOwoJCSRwb3N0ICAgID0gJGZldGNoZXItPmdldF9jaGVjayggJG9iamVjdF9pZCApOwoJCXJldHVybiAkcG9zdC0+SUQ7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgYWRkX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIGJvb2wgICAkdW5pcXVlICAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gV2hldGhlciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSBzaG91bGQgYmUgdW5pcXVlIGZvciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LiBJZiB0cnVlLCBhbmQgdGhlIG9iamVjdCBhbHJlYWR5IGhhcyBhCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSwgbm8gY2hhbmdlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgbWFkZS4KCSAqCgkgKiBAcmV0dXJuIGludHxmYWxzZSBUaGUgbWV0YSBJRCBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGFkZF9wb3N0X21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciB1cGRhdGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gbWl4ZWQgICRwcmV2X3ZhbHVlIE9wdGlvbmFsLiBJZiBzcGVjaWZpZWQsIG9ubHkgdXBkYXRlIGV4aXN0aW5nCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBPdGhlcndpc2UsIHVwZGF0ZSBhbGwgZW50cmllcy4KCSAqCgkgKiBAcmV0dXJuIGludHxib29sIE1ldGEgSUQgaWYgdGhlIGtleSBkaWRuJ3QgZXhpc3QsIHRydWUgb24gc3VjY2Vzc2Z1bAoJICogICAgICAgICAgICAgICAgICB1cGRhdGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIHVwZGF0ZV9wb3N0X21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZ2V0X21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICBPcHRpb25hbC4gTWV0YWRhdGEga2V5LiBJZiBub3Qgc3BlY2lmaWVkLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHJldHJpZXZlIGFsbCBtZXRhZGF0YSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCgkgKiBAcGFyYW0gYm9vbCAgICRzaW5nbGUgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIElmIHRydWUsIHJldHVybiBvbmx5CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZpcnN0IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuIFRoaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBpZiBtZXRhX2tleSBpcyBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQuCgkgKgoJICogQHJldHVybiBtaXhlZCBTaW5nbGUgbWV0YWRhdGEgdmFsdWUsIG9yIGFycmF5IG9mIHZhbHVlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5ID0gJycsICRzaW5nbGUgPSBmYWxzZSApIHsKCQlyZXR1cm4gZ2V0X3Bvc3RfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkc2luZ2xlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZGVsZXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IG1ldGFkYXRhIGlzIGZvcgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkKCSAqIEBwYXJhbSBtaXhlZCAkbWV0YV92YWx1ZSAgT3B0aW9uYWwuIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBub24tc2NhbGFyLiBJZiBzcGVjaWZpZWQsIG9ubHkgZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGlzIHZhbHVlLiBPdGhlcndpc2UsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhbGwgZW50cmllcyB3aXRoIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhc3MgYG51bGwsIGBmYWxzZWAsIG9yIGFuIGVtcHR5IHN0cmluZyB0byBza2lwCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgY2hlY2suIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBpdCBpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub3QgcG9zc2libGUgdG8gcGFzcyBhbiBlbXB0eSBzdHJpbmcgdG8gZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRob3NlIGVudHJpZXMgd2l0aCBhbiBlbXB0eSBzdHJpbmcgZm9yIGEgdmFsdWUuCgkgKgoJICogQHJldHVybiBib29sIFRydWUgb24gc3VjY2Vzc2Z1bCBkZWxldGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBkZWxldGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgPSAnJyApIHsKCQlyZXR1cm4gZGVsZXRlX3Bvc3RfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSApOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoREJPYmplY3Q7CnVzZSBXUF9DTElcRW50aXR5XFV0aWxzIGFzIEVudGl0eVV0aWxzOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFNpdGUgYXMgU2l0ZUZldGNoZXI7CnVzZSBXUF9DTElcRmV0Y2hlcnNcVXNlciBhcyBVc2VyRmV0Y2hlcjsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcSXRlcmF0b3JzXENTViBhcyBDc3ZJdGVyYXRvcjsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBNYW5hZ2VzIHVzZXJzLCBhbG9uZyB3aXRoIHRoZWlyIHJvbGVzLCBjYXBhYmlsaXRpZXMsIGFuZCBtZXRhLgogKgogKiBTZWUgcmVmZXJlbmNlcyBmb3IgW1JvbGVzIGFuZCBDYXBhYmlsaXRpZXNdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9Sb2xlc19hbmRfQ2FwYWJpbGl0aWVzKSBhbmQgW1dQIFVzZXIgY2xhc3NdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DbGFzc19SZWZlcmVuY2UvV1BfVXNlcikuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgdXNlciBJRHMKICogICAgICQgd3AgdXNlciBsaXN0IC0tZmllbGQ9SUQKICogICAgIDEKICoKICogICAgICMgQ3JlYXRlIGEgbmV3IHVzZXIuCiAqICAgICAkIHdwIHVzZXIgY3JlYXRlIGJvYiBib2JAZXhhbXBsZS5jb20gLS1yb2xlPWF1dGhvcgogKiAgICAgU3VjY2VzczogQ3JlYXRlZCB1c2VyIDMuCiAqICAgICBQYXNzd29yZDogazkqKiZJNHZOSCgmCiAqCiAqICAgICAjIFVwZGF0ZSBhbiBleGlzdGluZyB1c2VyLgogKiAgICAgJCB3cCB1c2VyIHVwZGF0ZSAxMjMgLS1kaXNwbGF5X25hbWU9TWFyeSAtLXVzZXJfcGFzcz1tYXJ5cGFzcwogKiAgICAgU3VjY2VzczogVXBkYXRlZCB1c2VyIDEyMy4KICoKICogICAgICMgRGVsZXRlIHVzZXIgMTIzIGFuZCByZWFzc2lnbiBwb3N0cyB0byB1c2VyIDU2NwogKiAgICAgJCB3cCB1c2VyIGRlbGV0ZSAxMjMgLS1yZWFzc2lnbj01NjcKICogICAgIFN1Y2Nlc3M6IFJlbW92ZWQgdXNlciAxMjMgZnJvbSBodHRwOi8vZXhhbXBsZS5jb20KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBVc2VyX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aERCT2JqZWN0IHsKCglwcm90ZWN0ZWQgJG9ial90eXBlICAgPSAndXNlcic7Cglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBbCgkJJ0lEJywKCQkndXNlcl9sb2dpbicsCgkJJ2Rpc3BsYXlfbmFtZScsCgkJJ3VzZXJfZW1haWwnLAoJCSd1c2VyX3JlZ2lzdGVyZWQnLAoJCSdyb2xlcycsCgldOwoKCXByaXZhdGUgJGNhcF9maWVsZHMgPSBbCgkJJ25hbWUnLAoJXTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgICAgID0gbmV3IFVzZXJGZXRjaGVyKCk7CgkJJHRoaXMtPnNpdGVmZXRjaGVyID0gbmV3IFNpdGVGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBMaXN0cyB1c2Vycy4KCSAqCgkgKiBEaXNwbGF5IFdvcmRQcmVzcyB1c2VycyBiYXNlZCBvbiBhbGwgYXJndW1lbnRzIHN1cHBvcnRlZCBieQoJICogW1dQX1VzZXJfUXVlcnkoKV0oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9yZWZlcmVuY2UvY2xhc3Nlcy93cF91c2VyX3F1ZXJ5L3ByZXBhcmVfcXVlcnkvKS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tcm9sZT08cm9sZT5dCgkgKiA6IE9ubHkgZGlzcGxheSB1c2VycyB3aXRoIGEgY2VydGFpbiByb2xlLgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogQ29udHJvbCBvdXRwdXQgYnkgb25lIG9yIG1vcmUgYXJndW1lbnRzIG9mIFdQX1VzZXJfUXVlcnkoKS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBMaXN0IGFsbCB1c2VycyBpbiB0aGUgbmV0d29yayBmb3IgbXVsdGlzaXRlLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggdXNlci4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggdXNlcjoKCSAqCgkgKiAqIElECgkgKiAqIHVzZXJfbG9naW4KCSAqICogZGlzcGxheV9uYW1lCgkgKiAqIHVzZXJfZW1haWwKCSAqICogdXNlcl9yZWdpc3RlcmVkCgkgKiAqIHJvbGVzCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHVzZXJfcGFzcwoJICogKiB1c2VyX25pY2VuYW1lCgkgKiAqIHVzZXJfdXJsCgkgKiAqIHVzZXJfYWN0aXZhdGlvbl9rZXkKCSAqICogdXNlcl9zdGF0dXMKCSAqICogc3BhbQoJICogKiBkZWxldGVkCgkgKiAqIGNhcHMKCSAqICogY2FwX2tleQoJICogKiBhbGxjYXBzCgkgKiAqIGZpbHRlcgoJICogKiB1cmwKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdXNlciBJRHMKCSAqICAgICAkIHdwIHVzZXIgbGlzdCAtLWZpZWxkPUlECgkgKiAgICAgMQoJICoKCSAqICAgICAjIExpc3QgdXNlcnMgd2l0aCBhZG1pbmlzdHJhdG9yIHJvbGUKCSAqICAgICAkIHdwIHVzZXIgbGlzdCAtLXJvbGU9YWRtaW5pc3RyYXRvciAtLWZvcm1hdD1jc3YKCSAqICAgICBJRCx1c2VyX2xvZ2luLGRpc3BsYXlfbmFtZSx1c2VyX2VtYWlsLHVzZXJfcmVnaXN0ZXJlZCxyb2xlcwoJICogICAgIDEsc3VwZXJ2aXNvcixzdXBlcnZpc29yLHN1cGVydmlzb3JAZ21haWwuY29tLCIyMDE2LTA2LTAzIDA0OjM3OjAwIixhZG1pbmlzdHJhdG9yCgkgKgoJICogICAgICMgTGlzdCB1c2VycyB3aXRoIG9ubHkgZ2l2ZW4gZmllbGRzCgkgKiAgICAgJCB3cCB1c2VyIGxpc3QgLS1maWVsZHM9ZGlzcGxheV9uYW1lLHVzZXJfZW1haWwgLS1mb3JtYXQ9anNvbgoJICogICAgIFt7ImRpc3BsYXlfbmFtZSI6InN1cGVydmlzb3IiLCJ1c2VyX2VtYWlsIjoic3VwZXJ2aXNvckBnbWFpbC5jb20ifV0KCSAqCgkgKiAgICAgIyBMaXN0IHVzZXJzIG9yZGVyZWQgYnkgdGhlICdsYXN0X2FjdGl2aXR5JyBtZXRhIHZhbHVlLgoJICogICAgICQgd3AgdXNlciBsaXN0IC0tbWV0YV9rZXk9bGFzdF9hY3Rpdml0eSAtLW9yZGVyYnk9bWV0YV92YWx1ZV9udW0KCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICkgKSB7CgkJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCQl9CgkJCSRhc3NvY19hcmdzWydibG9nX2lkJ10gPSAwOwoJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJCSRmaWVsZHMgICAgICAgICAgICAgICA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJCQkkYXNzb2NfYXJnc1snZmllbGRzJ10gPSBhcnJheV9kaWZmKCAkZmllbGRzLCBbICdyb2xlcycgXSApOwoJCQl9IGVsc2UgewoJCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gYXJyYXlfZGlmZiggJHRoaXMtPm9ial9maWVsZHMsIFsgJ3JvbGVzJyBdICk7CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBpbl9hcnJheSggJGZvcm1hdHRlci0+Zm9ybWF0LCBbICdpZHMnLCAnY291bnQnIF0sIHRydWUgKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJ2lkcyc7CgkJfSBlbHNlIHsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJ2FsbF93aXRoX21ldGEnOwoJCX0KCgkJJGFzc29jX2FyZ3NbJ2NvdW50X3RvdGFsJ10gPSBmYWxzZTsKCQkkYXNzb2NfYXJncyAgICAgICAgICAgICAgICA9IHNlbGY6OnByb2Nlc3NfY3N2X2FyZ3VtZW50c190b19hcnJheXMoICRhc3NvY19hcmdzICk7CgkJJHVzZXJzICAgICAgICAgICAgICAgICAgICAgPSBnZXRfdXNlcnMoICRhc3NvY19hcmdzICk7CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJZWNobyBpbXBsb2RlKCAnICcsICR1c2VycyApOwoJCX0gZWxzZWlmICggJ2NvdW50JyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdXNlcnMgKTsKCQl9IGVsc2UgewoJCQkkaXRlcmF0b3IgPSBVdGlsc1xpdGVyYXRvcl9tYXAoCgkJCQkkdXNlcnMsCgkJCQlmdW5jdGlvbiAoICR1c2VyICkgewoJCQkJCWlmICggISBpc19vYmplY3QoICR1c2VyICkgKSB7CgkJCQkJCXJldHVybiAkdXNlcjsKCQkJCQl9CgoJCQkJCSR1c2VyLT5yb2xlcyA9IGltcGxvZGUoICcsJywgJHVzZXItPnJvbGVzICk7CgkJCQkJJHVzZXItPnVybCAgID0gZ2V0X2F1dGhvcl9wb3N0c191cmwoICR1c2VyLT5JRCwgJHVzZXItPnVzZXJfbmljZW5hbWUgKTsKCQkJCQlyZXR1cm4gJHVzZXI7CgkJCQl9CgkJCSk7CgoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaXRlcmF0b3IgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIGRldGFpbHMgYWJvdXQgYSB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVXNlciBJRCwgdXNlciBlbWFpbCwgb3IgdXNlciBsb2dpbi4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBJbnN0ZWFkIG9mIHJldHVybmluZyB0aGUgd2hvbGUgdXNlciwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBHZXQgYSBzcGVjaWZpYyBzdWJzZXQgb2YgdGhlIHVzZXIncyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHVzZXIKCSAqICAgICAkIHdwIHVzZXIgZ2V0IDEyIC0tZmllbGQ9bG9naW4KCSAqICAgICBzdXBlcnZpc29yCgkgKgoJICogICAgICMgR2V0IHVzZXIgYW5kIGV4cG9ydCB0byBKU09OIGZpbGUKCSAqICAgICAkIHdwIHVzZXIgZ2V0IGJvYiAtLWZvcm1hdD1qc29uID4gYm9iLmpzb24KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyICAgICAgICAgICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSR1c2VyX2RhdGEgICAgICAgICAgPSAkdXNlci0+dG9fYXJyYXkoKTsKCQkkdXNlcl9kYXRhWydyb2xlcyddID0gaW1wbG9kZSggJywgJywgJHVzZXItPnJvbGVzICk7CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICR1c2VyX2RhdGEgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgb25lIG9yIG1vcmUgdXNlcnMgZnJvbSB0aGUgY3VycmVudCBzaXRlLgoJICoKCSAqIE9uIG11bHRpc2l0ZSwgYHdwIHVzZXIgZGVsZXRlYCBvbmx5IHJlbW92ZXMgdGhlIHVzZXIgZnJvbSB0aGUgY3VycmVudAoJICogc2l0ZS4gSW5jbHVkZSBgLS1uZXR3b3JrYCB0byBhbHNvIHJlbW92ZSB0aGUgdXNlciBmcm9tIHRoZSBkYXRhYmFzZSwgYnV0CgkgKiBtYWtlIHN1cmUgdG8gcmVhc3NpZ24gdGhlaXIgcG9zdHMgcHJpb3IgdG8gZGVsZXRpbmcgdGhlIHVzZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPi4uLgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlcihzKSB0byBkZWxldGUuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogT24gbXVsdGlzaXRlLCBkZWxldGUgdGhlIHVzZXIgZnJvbSB0aGUgZW50aXJlIG5ldHdvcmsuCgkgKgoJICogWy0tcmVhc3NpZ249PHVzZXItaWQ+XQoJICogOiBVc2VyIElEIHRvIHJlYXNzaWduIHRoZSBwb3N0cyB0by4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IEFuc3dlciB5ZXMgdG8gYW55IGNvbmZpcm1hdGlvbiBwcm9tcHRzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHVzZXIgMTIzIGFuZCByZWFzc2lnbiBwb3N0cyB0byB1c2VyIDU2NwoJICogICAgICQgd3AgdXNlciBkZWxldGUgMTIzIC0tcmVhc3NpZ249NTY3CgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCB1c2VyIDEyMyBmcm9tIGh0dHA6Ly9leGFtcGxlLmNvbQoJICoKCSAqICAgICAjIERlbGV0ZSBhbGwgY29udHJpYnV0b3JzIGFuZCByZWFzc2lnbiB0aGVpciBwb3N0cyB0byB1c2VyIDIKCSAqICAgICAkIHdwIHVzZXIgZGVsZXRlICQod3AgdXNlciBsaXN0IC0tcm9sZT1jb250cmlidXRvciAtLWZpZWxkPUlEKSAtLXJlYXNzaWduPTIKCSAqICAgICBTdWNjZXNzOiBSZW1vdmVkIHVzZXIgODEzIGZyb20gaHR0cDovL2V4YW1wbGUuY29tCgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCB1c2VyIDU3OCBmcm9tIGh0dHA6Ly9leGFtcGxlLmNvbQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJG5ldHdvcmsgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKSAmJiBpc19tdWx0aXNpdGUoKTsKCQkkcmVhc3NpZ24gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWFzc2lnbicgKTsKCgkJaWYgKCAkbmV0d29yayAmJiAkcmVhc3NpZ24gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdSZWFzc2lnbmluZyBjb250ZW50IHRvIGEgZGlmZmVyZW50IHVzZXIgaXMgbm90IHN1cHBvcnRlZCBvbiBtdWx0aXNpdGUuJyApOwoJCX0KCgkJaWYgKCAhICRyZWFzc2lnbiApIHsKCQkJV1BfQ0xJOjpjb25maXJtKCAnLS1yZWFzc2lnbiBwYXJhbWV0ZXIgbm90IHBhc3NlZC4gQWxsIGFzc29jaWF0ZWQgcG9zdHMgd2lsbCBiZSBkZWxldGVkLiBQcm9jZWVkPycsICRhc3NvY19hcmdzICk7CgkJfQoKCQkkdXNlcnMgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgoJCXBhcmVudDo6X2RlbGV0ZSgKCQkJJHVzZXJzLAoJCQkkYXNzb2NfYXJncywKCQkJZnVuY3Rpb24gKCAkdXNlciApIHVzZSAoICRuZXR3b3JrLCAkcmVhc3NpZ24gKSB7CgkJCQkkdXNlcl9pZCA9ICR1c2VyLT5JRDsKCgkJCQlpZiAoICRuZXR3b3JrICkgewoJCQkJCSRyZXN1bHQgID0gd3BtdV9kZWxldGVfdXNlciggJHVzZXJfaWQgKTsKCQkJCQkkbWVzc2FnZSA9ICJEZWxldGVkIHVzZXIgeyR1c2VyX2lkfS4iOwoJCQkJfSBlbHNlIHsKCQkJCQkkcmVzdWx0ICA9IHdwX2RlbGV0ZV91c2VyKCAkdXNlcl9pZCwgJHJlYXNzaWduICk7CgkJCQkJJG1lc3NhZ2UgPSAiUmVtb3ZlZCB1c2VyIHskdXNlcl9pZH0gZnJvbSAiIC4gaG9tZV91cmwoKSAuICcuJzsKCQkJCX0KCgkJCQlpZiAoICEgJHJlc3VsdCApIHsKCQkJCQkkbWVzc2FnZSA9ICJGYWlsZWQgZGVsZXRpbmcgdXNlciB7JHVzZXJfaWR9LiI7CgoJCQkJCWlmICggaXNfbXVsdGlzaXRlKCkgJiYgaXNfc3VwZXJfYWRtaW4oICR1c2VyX2lkICkgKSB7CgkJCQkJCSRtZXNzYWdlIC49ICcgVGhlIHVzZXIgaXMgYSBzdXBlciBhZG1pbi4nOwoJCQkJCX0KCgkJCQkJcmV0dXJuIFsgJ2Vycm9yJywgJG1lc3NhZ2UgXTsKCQkJCX0KCgkJCQlyZXR1cm4gWyAnc3VjY2VzcycsICRtZXNzYWdlIF07CgkJCX0KCQkpOwoJfQoKCS8qKgoJICogQ3JlYXRlcyBhIG5ldyB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlci1sb2dpbj4KCSAqIDogVGhlIGxvZ2luIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZS4KCSAqCgkgKiA8dXNlci1lbWFpbD4KCSAqIDogVGhlIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIHVzZXIgdG8gY3JlYXRlLgoJICoKCSAqIFstLXJvbGU9PHJvbGU+XQoJICogOiBUaGUgcm9sZSBvZiB0aGUgdXNlciB0byBjcmVhdGUuIERlZmF1bHQ6IGRlZmF1bHQgcm9sZS4gUG9zc2libGUgdmFsdWVzCgkgKiBpbmNsdWRlICdhZG1pbmlzdHJhdG9yJywgJ2VkaXRvcicsICdhdXRob3InLCAnY29udHJpYnV0b3InLCAnc3Vic2NyaWJlcicuCgkgKgoJICogWy0tdXNlcl9wYXNzPTxwYXNzd29yZD5dCgkgKiA6IFRoZSB1c2VyIHBhc3N3b3JkLiBEZWZhdWx0OiByYW5kb21seSBnZW5lcmF0ZWQuCgkgKgoJICogWy0tdXNlcl9yZWdpc3RlcmVkPTx5eXl5LW1tLWRkLWhoLWlpLXNzPl0KCSAqIDogVGhlIGRhdGUgdGhlIHVzZXIgcmVnaXN0ZXJlZC4gRGVmYXVsdDogY3VycmVudCBkYXRlLgoJICoKCSAqIFstLWRpc3BsYXlfbmFtZT08bmFtZT5dCgkgKiA6IFRoZSBkaXNwbGF5IG5hbWUuCgkgKgoJICogWy0tdXNlcl9uaWNlbmFtZT08bmljZV9uYW1lPl0KCSAqIDogQSBzdHJpbmcgdGhhdCBjb250YWlucyBhIFVSTC1mcmllbmRseSBuYW1lIGZvciB0aGUgdXNlci4gVGhlIGRlZmF1bHQgaXMgdGhlIHVzZXIncyB1c2VybmFtZS4KCSAqCgkgKiBbLS11c2VyX3VybD08dXJsPl0KCSAqIDogQSBzdHJpbmcgY29udGFpbmluZyB0aGUgdXNlcidzIFVSTCBmb3IgdGhlIHVzZXIncyB3ZWIgc2l0ZS4KCSAqCgkgKiBbLS1uaWNrbmFtZT08bmlja25hbWU+XQoJICogOiBUaGUgdXNlcidzIG5pY2tuYW1lLCBkZWZhdWx0cyB0byB0aGUgdXNlcidzIHVzZXJuYW1lLgoJICoKCSAqIFstLWZpcnN0X25hbWU9PGZpcnN0X25hbWU+XQoJICogOiBUaGUgdXNlcidzIGZpcnN0IG5hbWUuCgkgKgoJICogWy0tbGFzdF9uYW1lPTxsYXN0X25hbWU+XQoJICogOiBUaGUgdXNlcidzIGxhc3QgbmFtZS4KCSAqCgkgKiBbLS1kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBBIHN0cmluZyBjb250YWluaW5nIGNvbnRlbnQgYWJvdXQgdGhlIHVzZXIuCgkgKgoJICogWy0tcmljaF9lZGl0aW5nPTxyaWNoX2VkaXRpbmc+XQoJICogOiBBIHN0cmluZyBmb3Igd2hldGhlciB0byBlbmFibGUgdGhlIHJpY2ggZWRpdG9yIG9yIG5vdC4gRmFsc2UgaWYgbm90IGVtcHR5LgoJICoKCSAqIFstLXNlbmQtZW1haWxdCgkgKiA6IFNlbmQgYW4gZW1haWwgdG8gdGhlIHVzZXIgd2l0aCB0aGVpciBuZXcgYWNjb3VudCBkZXRhaWxzLgoJICoKCSAqIFstLXBvcmNlbGFpbl0KCSAqIDogT3V0cHV0IGp1c3QgdGhlIG5ldyB1c2VyIGlkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIHVzZXIKCSAqICAgICAkIHdwIHVzZXIgY3JlYXRlIGJvYiBib2JAZXhhbXBsZS5jb20gLS1yb2xlPWF1dGhvcgoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgdXNlciAzLgoJICogICAgIFBhc3N3b3JkOiBrOSoqJkk0dk5IKCYKCSAqCgkgKiAgICAgIyBDcmVhdGUgdXNlciB3aXRob3V0IHNob3dpbmcgcGFzc3dvcmQgdXBvbiBzdWNjZXNzCgkgKiAgICAgJCB3cCB1c2VyIGNyZWF0ZSBhbm4gYW5uQGV4YW1wbGUuY29tIC0tcG9yY2VsYWluCgkgKiAgICAgNAoJICovCglwdWJsaWMgZnVuY3Rpb24gY3JlYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHVzZXIgPSBuZXcgc3RkQ2xhc3MoKTsKCgkJbGlzdCggJHVzZXItPnVzZXJfbG9naW4sICR1c2VyLT51c2VyX2VtYWlsICkgPSAkYXJnczsKCgkJJGFzc29jX2FyZ3MgPSB3cF9zbGFzaCggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCB1c2VybmFtZV9leGlzdHMoICR1c2VyLT51c2VyX2xvZ2luICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgJ3skdXNlci0+dXNlcl9sb2dpbn0nIHVzZXJuYW1lIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC4iICk7CgkJfQoKCQlpZiAoICEgaXNfZW1haWwoICR1c2VyLT51c2VyX2VtYWlsICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgJ3skdXNlci0+dXNlcl9lbWFpbH0nIGVtYWlsIGFkZHJlc3MgaXMgaW52YWxpZC4iICk7CgkJfQoKCQkkdXNlci0+dXNlcl9yZWdpc3RlcmVkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoCgkJCSRhc3NvY19hcmdzLAoJCQkndXNlcl9yZWdpc3RlcmVkJywKCQkJZGF0ZV9mb3JtYXQoIGRhdGVfY3JlYXRlKCksICclRiAlVCcgKQoJCSk7CgoJCSR1c2VyLT5kaXNwbGF5X25hbWUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXNwbGF5X25hbWUnLCBmYWxzZSApOwoKCQkkdXNlci0+Zmlyc3RfbmFtZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZpcnN0X25hbWUnLCBmYWxzZSApOwoKCQkkdXNlci0+bGFzdF9uYW1lID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbGFzdF9uYW1lJywgZmFsc2UgKTsKCgkJJHVzZXItPmRlc2NyaXB0aW9uID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGVzY3JpcHRpb24nLCBmYWxzZSApOwoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndXNlcl9wYXNzJ10gKSApIHsKCQkJJHVzZXItPnVzZXJfcGFzcyA9ICRhc3NvY19hcmdzWyd1c2VyX3Bhc3MnXTsKCQl9IGVsc2UgewoJCQkkdXNlci0+dXNlcl9wYXNzID0gd3BfZ2VuZXJhdGVfcGFzc3dvcmQoIDI0ICk7CgkJCSRnZW5lcmF0ZWRfcGFzcyAgPSB0cnVlOwoJCX0KCgkJJHVzZXItPnJvbGUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyb2xlJywgZ2V0X29wdGlvbiggJ2RlZmF1bHRfcm9sZScgKSApOwoJCXNlbGY6OnZhbGlkYXRlX3JvbGUoICR1c2VyLT5yb2xlICk7CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzZW5kLWVtYWlsJyApICkgewoJCQlhZGRfZmlsdGVyKCAnc2VuZF9wYXNzd29yZF9jaGFuZ2VfZW1haWwnLCAnX19yZXR1cm5fZmFsc2UnICk7CgkJCWFkZF9maWx0ZXIoICdzZW5kX2VtYWlsX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQl9CgoJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRyZXN1bHQgPSB3cG11X3ZhbGlkYXRlX3VzZXJfc2lnbnVwKCAkdXNlci0+dXNlcl9sb2dpbiwgJHVzZXItPnVzZXJfZW1haWwgKTsKCQkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdFsnZXJyb3JzJ10gKSAmJiAhIGVtcHR5KCAkcmVzdWx0WydlcnJvcnMnXS0+ZXJyb3JzICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0WydlcnJvcnMnXSApOwoJCQl9CgkJCSR1c2VyX2lkID0gd3BtdV9jcmVhdGVfdXNlciggJHVzZXItPnVzZXJfbG9naW4sICR1c2VyLT51c2VyX3Bhc3MsICR1c2VyLT51c2VyX2VtYWlsICk7CgkJCWlmICggISAkdXNlcl9pZCApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdVbmtub3duIGVycm9yIGNyZWF0aW5nIG5ldyB1c2VyLicgKTsKCQkJfQoJCQkkdXNlci0+SUQgPSAkdXNlcl9pZDsKCQkJJHVzZXJfaWQgID0gd3BfdXBkYXRlX3VzZXIoICR1c2VyICk7CgkJCWlmICggaXNfd3BfZXJyb3IoICR1c2VyX2lkICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAkdXNlcl9pZCApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHVzZXJfaWQgPSB3cF9pbnNlcnRfdXNlciggJHVzZXIgKTsKCQl9CgoJCWlmICggISAkdXNlcl9pZCB8fCBpc193cF9lcnJvciggJHVzZXJfaWQgKSApIHsKCQkJaWYgKCAhICR1c2VyX2lkICkgewoJCQkJJHVzZXJfaWQgPSAnVW5rbm93biBlcnJvciBjcmVhdGluZyBuZXcgdXNlci4nOwoJCQl9CgkJCVdQX0NMSTo6ZXJyb3IoICR1c2VyX2lkICk7CgkJfSBlbHNlIHsKCQkJaWYgKCBmYWxzZSA9PT0gJHVzZXItPnJvbGUgKSB7CgkJCQlkZWxldGVfdXNlcl9vcHRpb24oICR1c2VyX2lkLCAnY2FwYWJpbGl0aWVzJyApOwoJCQkJZGVsZXRlX3VzZXJfb3B0aW9uKCAkdXNlcl9pZCwgJ3VzZXJfbGV2ZWwnICk7CgkJCX0KCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2VuZC1lbWFpbCcgKSApIHsKCQkJc2VsZjo6d3BfbmV3X3VzZXJfbm90aWZpY2F0aW9uKCAkdXNlcl9pZCwgJHVzZXItPnVzZXJfcGFzcyApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCVdQX0NMSTo6bGluZSggJHVzZXJfaWQgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDcmVhdGVkIHVzZXIgeyR1c2VyX2lkfS4iICk7CgkJCWlmICggaXNzZXQoICRnZW5lcmF0ZWRfcGFzcyApICkgewoJCQkJV1BfQ0xJOjpsaW5lKCAiUGFzc3dvcmQ6IHskdXNlci0+dXNlcl9wYXNzfSIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgYW4gZXhpc3RpbmcgdXNlci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+Li4uCgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIocykgdG8gdXBkYXRlLgoJICoKCSAqIFstLXVzZXJfcGFzcz08cGFzc3dvcmQ+XQoJICogOiBBIHN0cmluZyB0aGF0IGNvbnRhaW5zIHRoZSBwbGFpbiB0ZXh0IHBhc3N3b3JkIGZvciB0aGUgdXNlci4KCSAqCgkgKiBbLS11c2VyX25pY2VuYW1lPTxuaWNlX25hbWU+XQoJICogOiBBIHN0cmluZyB0aGF0IGNvbnRhaW5zIGEgVVJMLWZyaWVuZGx5IG5hbWUgZm9yIHRoZSB1c2VyLiBUaGUgZGVmYXVsdCBpcyB0aGUgdXNlcidzIHVzZXJuYW1lLgoJICoKCSAqIFstLXVzZXJfdXJsPTx1cmw+XQoJICogOiBBIHN0cmluZyBjb250YWluaW5nIHRoZSB1c2VyJ3MgVVJMIGZvciB0aGUgdXNlcidzIHdlYiBzaXRlLgoJICoKCSAqIFstLXVzZXJfZW1haWw9PGVtYWlsPl0KCSAqIDogQSBzdHJpbmcgY29udGFpbmluZyB0aGUgdXNlcidzIGVtYWlsIGFkZHJlc3MuCgkgKgoJICogWy0tZGlzcGxheV9uYW1lPTxkaXNwbGF5X25hbWU+XQoJICogOiBBIHN0cmluZyB0aGF0IHdpbGwgYmUgc2hvd24gb24gdGhlIHNpdGUuIERlZmF1bHRzIHRvIHVzZXIncyB1c2VybmFtZS4KCSAqCgkgKiBbLS1uaWNrbmFtZT08bmlja25hbWU+XQoJICogOiBUaGUgdXNlcidzIG5pY2tuYW1lLCBkZWZhdWx0cyB0byB0aGUgdXNlcidzIHVzZXJuYW1lLgoJICoKCSAqIFstLWZpcnN0X25hbWU9PGZpcnN0X25hbWU+XQoJICogOiBUaGUgdXNlcidzIGZpcnN0IG5hbWUuCgkgKgoJICogWy0tbGFzdF9uYW1lPTxsYXN0X25hbWU+XQoJICogOiBUaGUgdXNlcidzIGxhc3QgbmFtZS4KCSAqCgkgKiBbLS1kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBBIHN0cmluZyBjb250YWluaW5nIGNvbnRlbnQgYWJvdXQgdGhlIHVzZXIuCgkgKgoJICogWy0tcmljaF9lZGl0aW5nPTxyaWNoX2VkaXRpbmc+XQoJICogOiBBIHN0cmluZyBmb3Igd2hldGhlciB0byBlbmFibGUgdGhlIHJpY2ggZWRpdG9yIG9yIG5vdC4gRmFsc2UgaWYgbm90IGVtcHR5LgoJICoKCSAqIFstLXVzZXJfcmVnaXN0ZXJlZD08eXl5eS1tbS1kZC1oaC1paS1zcz5dCgkgKiA6IFRoZSBkYXRlIHRoZSB1c2VyIHJlZ2lzdGVyZWQuCgkgKgoJICogWy0tcm9sZT08cm9sZT5dCgkgKiA6IEEgc3RyaW5nIHVzZWQgdG8gc2V0IHRoZSB1c2VyJ3Mgcm9sZS4KCSAqCgkgKiAtLTxmaWVsZD49PHZhbHVlPgoJICogOiBPbmUgb3IgbW9yZSBmaWVsZHMgdG8gdXBkYXRlLiBGb3IgYWNjZXB0ZWQgZmllbGRzLCBzZWUgd3BfdXBkYXRlX3VzZXIoKS4KCSAqCgkgKiBbLS1za2lwLWVtYWlsXQoJICogOiBEb24ndCBzZW5kIGFuIGVtYWlsIG5vdGlmaWNhdGlvbiB0byB0aGUgdXNlci4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSB1c2VyCgkgKiAgICAgJCB3cCB1c2VyIHVwZGF0ZSAxMjMgLS1kaXNwbGF5X25hbWU9TWFyeSAtLXVzZXJfcGFzcz1tYXJ5cGFzcwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgdXNlciAxMjMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndXNlcl9sb2dpbiddICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggIlVzZXIgbG9naW5zIGNhbid0IGJlIGNoYW5nZWQuIiApOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ3VzZXJfbG9naW4nXSApOwoJCX0KCgkJJHVzZXJfaWRzID0gW107CgkJZm9yZWFjaCAoICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKSBhcyAkdXNlciApIHsKCQkJJHVzZXJfaWRzW10gPSAkdXNlci0+SUQ7CgkJfQoKCQkkc2tpcF9lbWFpbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtZW1haWwnICk7CgkJaWYgKCAkc2tpcF9lbWFpbCApIHsKCQkJYWRkX2ZpbHRlciggJ3NlbmRfZW1haWxfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCQlhZGRfZmlsdGVyKCAnc2VuZF9wYXNzd29yZF9jaGFuZ2VfZW1haWwnLCAnX19yZXR1cm5fZmFsc2UnICk7CgkJfQoKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCXBhcmVudDo6X3VwZGF0ZSggJHVzZXJfaWRzLCAkYXNzb2NfYXJncywgJ3dwX3VwZGF0ZV91c2VyJyApOwoKCQlpZiAoICRza2lwX2VtYWlsICkgewoJCQlyZW1vdmVfZmlsdGVyKCAnc2VuZF9lbWFpbF9jaGFuZ2VfZW1haWwnLCAnX19yZXR1cm5fZmFsc2UnICk7CgkJCXJlbW92ZV9maWx0ZXIoICdzZW5kX3Bhc3N3b3JkX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgc29tZSB1c2Vycy4KCSAqCgkgKiBDcmVhdGVzIGEgc3BlY2lmaWVkIG51bWJlciBvZiBuZXcgdXNlcnMgd2l0aCBkdW1teSBkYXRhLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1jb3VudD08bnVtYmVyPl0KCSAqIDogSG93IG1hbnkgdXNlcnMgdG8gZ2VuZXJhdGU/CgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDEwMAoJICogLS0tCgkgKgoJICogWy0tcm9sZT08cm9sZT5dCgkgKiA6IFRoZSByb2xlIG9mIHRoZSBnZW5lcmF0ZWQgdXNlcnMuIERlZmF1bHQ6IGRlZmF1bHQgcm9sZSBmcm9tIFdQCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHByb2dyZXNzCgkgKiBvcHRpb25zOgoJICogICAtIHByb2dyZXNzCgkgKiAgIC0gaWRzCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFkZCBtZXRhIHRvIGV2ZXJ5IGdlbmVyYXRlZCB1c2Vycy4KCSAqICAgICAkIHdwIHVzZXIgZ2VuZXJhdGUgLS1mb3JtYXQ9aWRzIC0tY291bnQ9MyB8IHhhcmdzIC1kICcgJyAtSSAlIHdwIHVzZXIgbWV0YSBhZGQgJSBmb28gYmFyCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkYmxvZ19pZDsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdjb3VudCcgPT4gMTAwLAoJCQkncm9sZScgID0+IGdldF9vcHRpb24oICdkZWZhdWx0X3JvbGUnICksCgkJXTsKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSRyb2xlID0gJGFzc29jX2FyZ3NbJ3JvbGUnXTsKCgkJaWYgKCAhIGVtcHR5KCAkcm9sZSApICkgewoJCQlzZWxmOjp2YWxpZGF0ZV9yb2xlKCAkcm9sZSApOwoJCX0KCgkJJHVzZXJfY291bnQgPSBjb3VudF91c2VycygpOwoJCSR0b3RhbCAgICAgID0gJHVzZXJfY291bnRbJ3RvdGFsX3VzZXJzJ107CgkJJGxpbWl0ICAgICAgPSAkYXNzb2NfYXJnc1snY291bnQnXSArICR0b3RhbDsKCgkJJGZvcm1hdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcsICdwcm9ncmVzcycgKTsKCgkJJG5vdGlmeSA9IGZhbHNlOwoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeSA9IFV0aWxzXG1ha2VfcHJvZ3Jlc3NfYmFyKCAnR2VuZXJhdGluZyB1c2VycycsICRhc3NvY19hcmdzWydjb3VudCddICk7CgkJfQoKCQlmb3IgKCAkaW5kZXggPSAkdG90YWw7ICRpbmRleCA8ICRsaW1pdDsgJGluZGV4KysgKSB7CgkJCSRsb2dpbiA9ICJ1c2VyX3skYmxvZ19pZH1feyRpbmRleH0iOwoJCQkkbmFtZSAgPSAiVXNlciB7JGluZGV4fSI7CgoJCQkkdXNlcl9pZCA9IHdwX2luc2VydF91c2VyKAoJCQkJWwoJCQkJCSd1c2VyX2xvZ2luJyAgID0+ICRsb2dpbiwKCQkJCQkndXNlcl9wYXNzJyAgICA9PiAkbG9naW4sCgkJCQkJJ25pY2tuYW1lJyAgICAgPT4gJG5hbWUsCgkJCQkJJ2Rpc3BsYXlfbmFtZScgPT4gJG5hbWUsCgkJCQkJJ3JvbGUnICAgICAgICAgPT4gJHJvbGUsCgkJCQldCgkJCSk7CgoJCQlpZiAoIGZhbHNlID09PSAkcm9sZSApIHsKCQkJCWRlbGV0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICdjYXBhYmlsaXRpZXMnICk7CgkJCQlkZWxldGVfdXNlcl9vcHRpb24oICR1c2VyX2lkLCAndXNlcl9sZXZlbCcgKTsKCQkJfQoKCQkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkJJG5vdGlmeS0+dGljaygpOwoJCQl9IGVsc2VpZiAoICdpZHMnID09PSAkZm9ybWF0ICkgewoJCQkJZWNobyAkdXNlcl9pZDsKCQkJCWlmICggJGluZGV4IDwgJGxpbWl0IC0gMSApIHsKCQkJCQllY2hvICcgJzsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkkbm90aWZ5LT5maW5pc2goKTsKCQl9Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSB1c2VyIHJvbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBVc2VyIElELCB1c2VyIGVtYWlsLCBvciB1c2VyIGxvZ2luLgoJICoKCSAqIFs8cm9sZT5dCgkgKiA6IE1ha2UgdGhlIHVzZXIgaGF2ZSB0aGUgc3BlY2lmaWVkIHJvbGUuIElmIG5vdCBwYXNzZWQsIHRoZSBkZWZhdWx0IHJvbGUgaXMKCSAqIHVzZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB1c2VyIHNldC1yb2xlIDEyIGF1dGhvcgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGpvaG5kb2UgKDEyKSB0byBodHRwOi8vZXhhbXBsZS5jb20gYXMgYXV0aG9yLgoJICoKCSAqIEBzdWJjb21tYW5kIHNldC1yb2xlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfcm9sZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJJHJvbGUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFyZ3MsIDEsIGdldF9vcHRpb24oICdkZWZhdWx0X3JvbGUnICkgKTsKCgkJc2VsZjo6dmFsaWRhdGVfcm9sZSggJHJvbGUgKTsKCgkJLy8gTXVsdGlzaXRlCgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdhZGRfdXNlcl90b19ibG9nJyApICkgewoJCQlhZGRfdXNlcl90b19ibG9nKCBnZXRfY3VycmVudF9ibG9nX2lkKCksICR1c2VyLT5JRCwgJHJvbGUgKTsKCQl9IGVsc2UgewoJCQkkdXNlci0+c2V0X3JvbGUoICRyb2xlICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJBZGRlZCB7JHVzZXItPnVzZXJfbG9naW59ICh7JHVzZXItPklEfSkgdG8gIiAuIHNpdGVfdXJsKCkgLiAiIGFzIHskcm9sZX0uIiApOwoJfQoKCS8qKgoJICogQWRkcyBhIHJvbGUgZm9yIGEgdXNlci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFVzZXIgSUQsIHVzZXIgZW1haWwsIG9yIHVzZXIgbG9naW4uCgkgKgoJICogPHJvbGU+CgkgKiA6IEFkZCB0aGUgc3BlY2lmaWVkIHJvbGUgdG8gdGhlIHVzZXIuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB1c2VyIGFkZC1yb2xlIDEyIGF1dGhvcgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkICdhdXRob3InIHJvbGUgZm9yIGpvaG5kb2UgKDEyKS4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtcm9sZQoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX3JvbGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdXNlciA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgoJCSRyb2xlID0gJGFyZ3NbMV07CgoJCXNlbGY6OnZhbGlkYXRlX3JvbGUoICRyb2xlICk7CgoJCSR1c2VyLT5hZGRfcm9sZSggJHJvbGUgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAiQWRkZWQgJ3skcm9sZX0nIHJvbGUgZm9yIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KS4iICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgdXNlcidzIHJvbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBVc2VyIElELCB1c2VyIGVtYWlsLCBvciB1c2VyIGxvZ2luLgoJICoKCSAqIFs8cm9sZT5dCgkgKiA6IEEgc3BlY2lmaWMgcm9sZSB0byByZW1vdmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB1c2VyIHJlbW92ZS1yb2xlIDEyIGF1dGhvcgoJICogICAgIFN1Y2Nlc3M6IFJlbW92ZWQgJ2F1dGhvcicgcm9sZSBmb3Igam9obmRvZSAoMTIpLgoJICoKCSAqIEBzdWJjb21tYW5kIHJlbW92ZS1yb2xlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW1vdmVfcm9sZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJaWYgKCBpc3NldCggJGFyZ3NbMV0gKSApIHsKCQkJJHJvbGUgPSAkYXJnc1sxXTsKCgkJCXNlbGY6OnZhbGlkYXRlX3JvbGUoICRyb2xlICk7CgoJCQkkdXNlci0+cmVtb3ZlX3JvbGUoICRyb2xlICk7CgoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJSZW1vdmVkICd7JHJvbGV9JyByb2xlIGZvciB7JHVzZXItPnVzZXJfbG9naW59ICh7JHVzZXItPklEfSkuIiApOwoJCX0gZWxzZSB7CgkJCS8vIE11bHRpc2l0ZQoJCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ3JlbW92ZV91c2VyX2Zyb21fYmxvZycgKSApIHsKCQkJCXJlbW92ZV91c2VyX2Zyb21fYmxvZyggJHVzZXItPklELCBnZXRfY3VycmVudF9ibG9nX2lkKCkgKTsKCQkJfSBlbHNlIHsKCQkJCSR1c2VyLT5yZW1vdmVfYWxsX2NhcHMoKTsKCQkJfQoKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiUmVtb3ZlZCB7JHVzZXItPnVzZXJfbG9naW59ICh7JHVzZXItPklEfSkgZnJvbSAiIC4gc2l0ZV91cmwoKSAuICcuJyApOwoJCX0KCX0KCgkvKioKCSAqIEFkZHMgYSBjYXBhYmlsaXR5IHRvIGEgdXNlci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFVzZXIgSUQsIHVzZXIgZW1haWwsIG9yIHVzZXIgbG9naW4uCgkgKgoJICogPGNhcD4KCSAqIDogVGhlIGNhcGFiaWxpdHkgdG8gYWRkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQWRkIGEgY2FwYWJpbGl0eSBmb3IgYSB1c2VyCgkgKiAgICAgJCB3cCB1c2VyIGFkZC1jYXAgam9obiBjcmVhdGVfcHJlbWl1bV9pdGVtCgkgKiAgICAgU3VjY2VzczogQWRkZWQgJ2NyZWF0ZV9wcmVtaXVtX2l0ZW0nIGNhcGFiaWxpdHkgZm9yIGpvaG4gKDE2KS4KCSAqCgkgKiAgICAgIyBBZGQgYSBjYXBhYmlsaXR5IGZvciBhIHVzZXIKCSAqICAgICAkIHdwIHVzZXIgYWRkLWNhcCAxNSBlZGl0X3Byb2R1Y3QKCSAqICAgICBTdWNjZXNzOiBBZGRlZCAnZWRpdF9wcm9kdWN0JyBjYXBhYmlsaXR5IGZvciBqb2huZG9lICgxNSkuCgkgKgoJICogQHN1YmNvbW1hbmQgYWRkLWNhcAoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX2NhcCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQlpZiAoICR1c2VyICkgewoJCQkkY2FwID0gJGFyZ3NbMV07CgkJCSR1c2VyLT5hZGRfY2FwKCAkY2FwICk7CgoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJBZGRlZCAneyRjYXB9JyBjYXBhYmlsaXR5IGZvciB7JHVzZXItPnVzZXJfbG9naW59ICh7JHVzZXItPklEfSkuIiApOwoJCX0KCX0KCgkvKioKCSAqIFJlbW92ZXMgYSB1c2VyJ3MgY2FwYWJpbGl0eS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFVzZXIgSUQsIHVzZXIgZW1haWwsIG9yIHVzZXIgbG9naW4uCgkgKgoJICogPGNhcD4KCSAqIDogVGhlIGNhcGFiaWxpdHkgdG8gYmUgcmVtb3ZlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHVzZXIgcmVtb3ZlLWNhcCAxMSBwdWJsaXNoX25ld3NsZXR0ZXJzCgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCAncHVibGlzaF9uZXdzbGV0dGVycycgY2FwIGZvciBzdXBlcnZpc29yICgxMSkuCgkgKgoJICogICAgICQgd3AgdXNlciByZW1vdmUtY2FwIDExIHB1Ymxpc2hfcG9zdHMKCSAqICAgICBFcnJvcjogVGhlICdwdWJsaXNoX3Bvc3RzJyBjYXAgZm9yIHN1cGVydmlzb3IgKDExKSBpcyBpbmhlcml0ZWQgZnJvbSBhIHJvbGUuCgkgKgoJICogICAgICQgd3AgdXNlciByZW1vdmUtY2FwIDExIG5vbmV4aXN0ZW50X2NhcAoJICogICAgIEVycm9yOiBObyBzdWNoICdub25leGlzdGVudF9jYXAnIGNhcCBmb3Igc3VwZXJ2aXNvciAoMTEpLgoJICoKCSAqIEBzdWJjb21tYW5kIHJlbW92ZS1jYXAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlbW92ZV9jYXAoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdXNlciA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgkJaWYgKCAkdXNlciApIHsKCQkJJGNhcCA9ICRhcmdzWzFdOwoJCQlpZiAoICEgaXNzZXQoICR1c2VyLT5jYXBzWyAkY2FwIF0gKSApIHsKCQkJCWlmICggaXNzZXQoICR1c2VyLT5hbGxjYXBzWyAkY2FwIF0gKSApIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAiVGhlICd7JGNhcH0nIGNhcCBmb3IgeyR1c2VyLT51c2VyX2xvZ2lufSAoeyR1c2VyLT5JRH0pIGlzIGluaGVyaXRlZCBmcm9tIGEgcm9sZS4iICk7CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCAiTm8gc3VjaCAneyRjYXB9JyBjYXAgZm9yIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KS4iICk7CgkJCX0KCQkJJHVzZXItPnJlbW92ZV9jYXAoICRjYXAgKTsKCgkJCVdQX0NMSTo6c3VjY2VzcyggIlJlbW92ZWQgJ3skY2FwfScgY2FwIGZvciB7JHVzZXItPnVzZXJfbG9naW59ICh7JHVzZXItPklEfSkuIiApOwoJCX0KCX0KCgkvKioKCSAqIExpc3RzIGFsbCBjYXBhYmlsaXRpZXMgZm9yIGEgdXNlci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFVzZXIgSUQsIHVzZXIgZW1haWwsIG9yIGxvZ2luLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiBsaXN0CgkgKiBvcHRpb25zOgoJICogICAtIGxpc3QKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdXNlciBsaXN0LWNhcHMgMjEKCSAqICAgICBlZGl0X3Byb2R1Y3QKCSAqICAgICBjcmVhdGVfcHJlbWl1bV9pdGVtCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdC1jYXBzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0X2NhcHMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdXNlciA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgoJCWlmICggJHVzZXIgKSB7CgkJCSR1c2VyLT5nZXRfcm9sZV9jYXBzKCk7CgoJCQkkdXNlcl9jYXBzX2xpc3QgPSAkdXNlci0+YWxsY2FwczsKCgkJCSRhY3RpdmVfdXNlcl9jYXBfbGlzdCA9IFtdOwoKCQkJZm9yZWFjaCAoICR1c2VyX2NhcHNfbGlzdCBhcyAkY2FwID0+ICRhY3RpdmUgKSB7CgkJCQlpZiAoICRhY3RpdmUgKSB7CgkJCQkJJGFjdGl2ZV91c2VyX2NhcF9saXN0W10gPSAkY2FwOwoJCQkJfQoJCQl9CgoJCQlpZiAoICdsaXN0JyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkJZm9yZWFjaCAoICRhY3RpdmVfdXNlcl9jYXBfbGlzdCBhcyAkY2FwICkgewoJCQkJCVdQX0NMSTo6bGluZSggJGNhcCApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJG91dHB1dF9jYXBzID0gW107CgkJCQlmb3JlYWNoICggJGFjdGl2ZV91c2VyX2NhcF9saXN0IGFzICRjYXAgKSB7CgkJCQkJJG91dHB1dF9jYXAgPSBuZXcgc3RkQ2xhc3MoKTsKCgkJCQkJJG91dHB1dF9jYXAtPm5hbWUgPSAkY2FwOwoKCQkJCQkkb3V0cHV0X2NhcHNbXSA9ICRvdXRwdXRfY2FwOwoJCQkJfQoJCQkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+Y2FwX2ZpZWxkcyApOwoJCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJG91dHB1dF9jYXBzICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBJbXBvcnRzIHVzZXJzIGZyb20gYSBDU1YgZmlsZS4KCSAqCgkgKiBJZiB0aGUgdXNlciBhbHJlYWR5IGV4aXN0cyAobWF0Y2hpbmcgdGhlIGVtYWlsIGFkZHJlc3Mgb3IgbG9naW4pLCB0aGVuCgkgKiB0aGUgdXNlciBpcyB1cGRhdGVkIHVubGVzcyB0aGUgYC0tc2tpcC11cGRhdGVgIGZsYWcgaXMgdXNlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGZpbGU+CgkgKiA6IFRoZSBsb2NhbCBvciByZW1vdGUgQ1NWIGZpbGUgb2YgdXNlcnMgdG8gaW1wb3J0LiBJZiAnLScsIHRoZW4gcmVhZHMgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1zZW5kLWVtYWlsXQoJICogOiBTZW5kIGFuIGVtYWlsIHRvIG5ldyB1c2VycyB3aXRoIHRoZWlyIGFjY291bnQgZGV0YWlscy4KCSAqCgkgKiBbLS1za2lwLXVwZGF0ZV0KCSAqIDogRG9uJ3QgdXBkYXRlIHVzZXJzIHRoYXQgYWxyZWFkeSBleGlzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEltcG9ydCB1c2VycyBmcm9tIGxvY2FsIENTViBmaWxlCgkgKiAgICAgJCB3cCB1c2VyIGltcG9ydC1jc3YgL3BhdGgvdG8vdXNlcnMuY3N2CgkgKiAgICAgU3VjY2VzczogYm9iam9uZXMgY3JlYXRlZAoJICogICAgIFN1Y2Nlc3M6IG5ld3VzZXIxIGNyZWF0ZWQKCSAqICAgICBTdWNjZXNzOiBleGlzdGluZ3VzZXIgY3JlYXRlZAoJICoKCSAqICAgICAjIEltcG9ydCB1c2VycyBmcm9tIHJlbW90ZSBDU1YgZmlsZQoJICogICAgICQgd3AgdXNlciBpbXBvcnQtY3N2IGh0dHA6Ly9leGFtcGxlLmNvbS91c2Vycy5jc3YKCSAqCgkgKiAgICAgU2FtcGxlIHVzZXJzLmNzdiBmaWxlOgoJICoKCSAqICAgICB1c2VyX2xvZ2luLHVzZXJfZW1haWwsZGlzcGxheV9uYW1lLHJvbGUKCSAqICAgICBib2Jqb25lcyxib2Jqb25lc0BleGFtcGxlLmNvbSxCb2IgSm9uZXMsY29udHJpYnV0b3IKCSAqICAgICBuZXd1c2VyMSxuZXd1c2VyMUBleGFtcGxlLmNvbSxOZXcgVXNlcixhdXRob3IKCSAqICAgICBleGlzdGluZ3VzZXIsZXhpc3Rpbmd1c2VyQGV4YW1wbGUuY29tLEV4aXN0aW5nIFVzZXIsYWRtaW5pc3RyYXRvcgoJICoKCSAqIEBzdWJjb21tYW5kIGltcG9ydC1jc3YKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGltcG9ydF9jc3YoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGJsb2dfdXNlcnMgPSBnZXRfdXNlcnMoKTsKCgkJJGZpbGVuYW1lID0gJGFyZ3NbMF07CgoJCWlmICggMCA9PT0gc3RyaXBvcyggJGZpbGVuYW1lLCAnaHR0cDovLycgKSB8fCAwID09PSBzdHJpcG9zKCAkZmlsZW5hbWUsICdodHRwczovLycgKSApIHsKCQkJJHJlc3BvbnNlICAgICAgPSB3cF9yZW1vdGVfaGVhZCggJGZpbGVuYW1lICk7CgkJCSRyZXNwb25zZV9jb2RlID0gKHN0cmluZykgd3BfcmVtb3RlX3JldHJpZXZlX3Jlc3BvbnNlX2NvZGUoICRyZXNwb25zZSApOwoJCQlpZiAoIGluX2FycmF5KCAoaW50KSAkcmVzcG9uc2VfY29kZVswXSwgWyA0LCA1IF0sIHRydWUgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBhY2Nlc3MgcmVtb3RlIENTViBmaWxlIChIVFRQIHskcmVzcG9uc2VfY29kZX0gcmVzcG9uc2UpLiIgKTsKCQkJfQoJCX0gZWxzZWlmICggJy0nID09PSAkZmlsZW5hbWUgKSB7CgkJCWlmICggISBFbnRpdHlVdGlsczo6aGFzX3N0ZGluKCkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVW5hYmxlIHRvIHJlYWQgY29udGVudCBmcm9tIFNURElOLicgKTsKCQkJfQoJCX0gZWxzZWlmICggISBmaWxlX2V4aXN0cyggJGZpbGVuYW1lICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJNaXNzaW5nIGZpbGU6IHskZmlsZW5hbWV9IiApOwoJCX0KCgkJLy8gRG9uJ3Qgc2VuZCBjb3JlJ3MgZW1haWxzIGR1cmluZyB0aGUgY3JlYXRpb24gLyB1cGRhdGUgcHJvY2VzcwoJCWFkZF9maWx0ZXIoICdzZW5kX3Bhc3N3b3JkX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQlhZGRfZmlsdGVyKCAnc2VuZF9lbWFpbF9jaGFuZ2VfZW1haWwnLCAnX19yZXR1cm5fZmFsc2UnICk7CgoJCWlmICggJy0nID09PSAkZmlsZW5hbWUgKSB7CgkJCSRmaWxlX29iamVjdCA9IG5ldyBOb1Jld2luZEl0ZXJhdG9yKCBuZXcgU3BsRmlsZU9iamVjdCggJ3BocDovL3N0ZGluJyApICk7CgkJCSRmaWxlX29iamVjdC0+c2V0RmxhZ3MoIFNwbEZpbGVPYmplY3Q6OlJFQURfQ1NWICk7CgkJCSRjc3ZfZGF0YSA9IFtdOwoJCQkkaW5kZXhlcyAgPSBbXTsKCQkJZm9yZWFjaCAoICRmaWxlX29iamVjdCBhcyAkbGluZSApIHsKCQkJCWlmICggZW1wdHkoICRsaW5lWzBdICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaWYgKCBlbXB0eSggJGluZGV4ZXMgKSApIHsKCQkJCQkkaW5kZXhlcyA9ICRsaW5lOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWZvcmVhY2ggKCAkaW5kZXhlcyBhcyAkbiA9PiAka2V5ICkgewoJCQkJCSRkYXRhWyAka2V5IF0gPSAkbGluZVsgJG4gXTsKCQkJCX0KCgkJCQkkY3N2X2RhdGFbXSA9ICRkYXRhOwoJCQl9CgkJfSBlbHNlIHsKCQkJJGNzdl9kYXRhID0gbmV3IENzdkl0ZXJhdG9yKCAkZmlsZW5hbWUgKTsKCQl9CgoJCWZvcmVhY2ggKCAkY3N2X2RhdGEgYXMgJG5ld191c2VyICkgewoJCQkkZGVmYXVsdHMgPSBbCgkJCQkncm9sZScgICAgICAgICAgICA9PiBnZXRfb3B0aW9uKCAnZGVmYXVsdF9yb2xlJyApLAoJCQkJJ3VzZXJfcGFzcycgICAgICAgPT4gd3BfZ2VuZXJhdGVfcGFzc3dvcmQoKSwKCQkJCSd1c2VyX3JlZ2lzdGVyZWQnID0+IGRhdGVfZm9ybWF0KCBkYXRlX2NyZWF0ZSgpLCAnJUYgJVQnICksCgkJCQknZGlzcGxheV9uYW1lJyAgICA9PiBmYWxzZSwKCQkJXTsKCQkJJG5ld191c2VyID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJG5ld191c2VyICk7CgoJCQkkc2Vjb25kYXJ5X3JvbGVzID0gW107CgkJCWlmICggISBlbXB0eSggJG5ld191c2VyWydyb2xlcyddICkgKSB7CgkJCQkkcm9sZXMgICAgICAgID0gYXJyYXlfbWFwKCAndHJpbScsIGV4cGxvZGUoICcsJywgJG5ld191c2VyWydyb2xlcyddICkgKTsKCQkJCSRpbnZhbGlkX3JvbGUgPSBmYWxzZTsKCQkJCWZvcmVhY2ggKCAkcm9sZXMgYXMgJHJvbGUgKSB7CgkJCQkJaWYgKCBudWxsID09PSBnZXRfcm9sZSggJHJvbGUgKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRuZXdfdXNlclsndXNlcl9sb2dpbiddfSBoYXMgYW4gaW52YWxpZCByb2xlLiIgKTsKCQkJCQkJJGludmFsaWRfcm9sZSA9IHRydWU7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCWlmICggJGludmFsaWRfcm9sZSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCSRuZXdfdXNlclsncm9sZSddID0gYXJyYXlfc2hpZnQoICRyb2xlcyApOwoJCQkJJHNlY29uZGFyeV9yb2xlcyAgPSAkcm9sZXM7CgkJCX0gZWxzZWlmICggJ25vbmUnID09PSAkbmV3X3VzZXJbJ3JvbGUnXSApIHsKCQkJCSRuZXdfdXNlclsncm9sZSddID0gZmFsc2U7CgkJCX0gZWxzZWlmICggbnVsbCA9PT0gZ2V0X3JvbGUoICRuZXdfdXNlclsncm9sZSddICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJ7JG5ld191c2VyWyd1c2VyX2xvZ2luJ119IGhhcyBhbiBpbnZhbGlkIHJvbGUuIiApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCS8vIFVzZXIgYWxyZWFkeSBleGlzdHMgYW5kIHdlIGp1c3QgbmVlZCB0byBhZGQgdGhlbSB0byB0aGUgc2l0ZSBpZiB0aGV5IGFyZW4ndCBhbHJlYWR5IHRoZXJlCgkJCSRleGlzdGluZ191c2VyID0gZ2V0X3VzZXJfYnkoICdlbWFpbCcsICRuZXdfdXNlclsndXNlcl9lbWFpbCddICk7CgoJCQlpZiAoICEgJGV4aXN0aW5nX3VzZXIgKSB7CgkJCQkkZXhpc3RpbmdfdXNlciA9IGdldF91c2VyX2J5KCAnbG9naW4nLCAkbmV3X3VzZXJbJ3VzZXJfbG9naW4nXSApOwoJCQl9CgoJCQlpZiAoICRleGlzdGluZ191c2VyICYmIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtdXBkYXRlJyApICkgewoKCQkJCVdQX0NMSTo6bG9nKCAieyRleGlzdGluZ191c2VyLT51c2VyX2xvZ2lufSBleGlzdHMgYW5kIGhhcyBiZWVuIHNraXBwZWQuIiApOwoJCQkJY29udGludWU7CgoJCQl9CgoJCQlpZiAoICRleGlzdGluZ191c2VyICkgewoJCQkJJG5ld191c2VyWydJRCddID0gJGV4aXN0aW5nX3VzZXItPklEOwoJCQkJJHVzZXJfaWQgICAgICAgID0gd3BfdXBkYXRlX3VzZXIoICRuZXdfdXNlciApOwoKCQkJCWlmICggISBpbl9hcnJheSggJGV4aXN0aW5nX3VzZXItPnVzZXJfbG9naW4sIHdwX2xpc3RfcGx1Y2soICRibG9nX3VzZXJzLCAndXNlcl9sb2dpbicgKSwgdHJ1ZSApICYmIGlzX211bHRpc2l0ZSgpICYmICRuZXdfdXNlclsncm9sZSddICkgewoJCQkJCWFkZF91c2VyX3RvX2Jsb2coIGdldF9jdXJyZW50X2Jsb2dfaWQoKSwgJGV4aXN0aW5nX3VzZXItPklELCAkbmV3X3VzZXJbJ3JvbGUnXSApOwoJCQkJCVdQX0NMSTo6bG9nKCAieyRleGlzdGluZ191c2VyLT51c2VyX2xvZ2lufSBhZGRlZCBhcyB7JG5ld191c2VyWydyb2xlJ119LiIgKTsKCQkJCX0KCgkJCQkvLyBDcmVhdGUgdGhlIHVzZXIKCQkJfSBlbHNlIHsKCQkJCXVuc2V0KCAkbmV3X3VzZXJbJ0lEJ10gKTsgLy8gVW5zZXQgZWxzZSBpdCB3aWxsIGp1c3QgcmV0dXJuIHRoZSBJRAoKCQkJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQkJJHJlc3VsdCA9IHdwbXVfdmFsaWRhdGVfdXNlcl9zaWdudXAoICRuZXdfdXNlclsndXNlcl9sb2dpbiddLCAkbmV3X3VzZXJbJ3VzZXJfZW1haWwnXSApOwoJCQkJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHRbJ2Vycm9ycyddICkgJiYgISBlbXB0eSggJHJlc3VsdFsnZXJyb3JzJ10tPmVycm9ycyApICkgewoJCQkJCQlXUF9DTEk6Ondhcm5pbmcoICRyZXN1bHRbJ2Vycm9ycyddICk7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCQkJCQkkdXNlcl9pZCA9IHdwbXVfY3JlYXRlX3VzZXIoICRuZXdfdXNlclsndXNlcl9sb2dpbiddLCAkbmV3X3VzZXJbJ3VzZXJfcGFzcyddLCAkbmV3X3VzZXJbJ3VzZXJfZW1haWwnXSApOwoJCQkJCWlmICggISAkdXNlcl9pZCApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAnVW5rbm93biBlcnJvciBjcmVhdGluZyBuZXcgdXNlci4nICk7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCQkJCQkkbmV3X3VzZXJbJ0lEJ10gPSAkdXNlcl9pZDsKCQkJCQkkdXNlcl9pZCAgICAgICAgPSB3cF91cGRhdGVfdXNlciggJG5ld191c2VyICk7CgkJCQkJaWYgKCBpc193cF9lcnJvciggJHVzZXJfaWQgKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkdXNlcl9pZCApOwoJCQkJCQljb250aW51ZTsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCSR1c2VyX2lkID0gd3BfaW5zZXJ0X3VzZXIoICRuZXdfdXNlciApOwoJCQkJfQoKCQkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2VuZC1lbWFpbCcgKSApIHsKCQkJCQlzZWxmOjp3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAkbmV3X3VzZXJbJ3VzZXJfcGFzcyddICk7CgkJCQl9CgkJCX0KCgkJCWlmICggaXNfd3BfZXJyb3IoICR1c2VyX2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICR1c2VyX2lkICk7CgkJCQljb250aW51ZTsKCgkJCX0KCgkJCWlmICggZmFsc2UgPT09ICRuZXdfdXNlclsncm9sZSddICkgewoJCQkJZGVsZXRlX3VzZXJfb3B0aW9uKCAkdXNlcl9pZCwgJ2NhcGFiaWxpdGllcycgKTsKCQkJCWRlbGV0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICd1c2VyX2xldmVsJyApOwoJCQl9CgoJCQkkdXNlciA9IGdldF91c2VyX2J5KCAnaWQnLCAkdXNlcl9pZCApOwoJCQlmb3JlYWNoICggJHNlY29uZGFyeV9yb2xlcyBhcyAkc2Vjb25kYXJ5X3JvbGUgKSB7CgkJCQkkdXNlci0+YWRkX3JvbGUoICRzZWNvbmRhcnlfcm9sZSApOwoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRleGlzdGluZ191c2VyICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICRuZXdfdXNlclsndXNlcl9sb2dpbiddIC4gJyB1cGRhdGVkLicgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJG5ld191c2VyWyd1c2VyX2xvZ2luJ10gLiAnIGNyZWF0ZWQuJyApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogUmVzZXRzIHRoZSBwYXNzd29yZCBmb3Igb25lIG9yIG1vcmUgdXNlcnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPi4uLgoJICogOiBvbmUgb3IgbW9yZSB1c2VyIGxvZ2lucyBvciBJRHMuCgkgKgoJICogWy0tc2tpcC1lbWFpbF0KCSAqIDogRG9uJ3Qgc2VuZCBhbiBlbWFpbCBub3RpZmljYXRpb24gdG8gdGhlIGFmZmVjdGVkIHVzZXIocykuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZXNldCB0aGUgcGFzc3dvcmQgZm9yIHR3byB1c2VycyBhbmQgc2VuZCB0aGVtIHRoZSBjaGFuZ2UgZW1haWwuCgkgKiAgICAgJCB3cCB1c2VyIHJlc2V0LXBhc3N3b3JkIGFkbWluIGVkaXRvcgoJICogICAgIFJlc2V0IHBhc3N3b3JkIGZvciBhZG1pbi4KCSAqICAgICBSZXNldCBwYXNzd29yZCBmb3IgZWRpdG9yLgoJICogICAgIFN1Y2Nlc3M6IFBhc3N3b3JkcyByZXNldCBmb3IgMiB1c2Vycy4KCSAqCgkgKiBAc3ViY29tbWFuZCByZXNldC1wYXNzd29yZAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVzZXRfcGFzc3dvcmQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkc2tpcF9lbWFpbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtZW1haWwnICk7CgkJaWYgKCAkc2tpcF9lbWFpbCApIHsKCQkJYWRkX2ZpbHRlciggJ3NlbmRfcGFzc3dvcmRfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCX0KCQkkZmV0Y2hlciA9IG5ldyBVc2VyRmV0Y2hlcigpOwoJCSR1c2VycyAgID0gJGZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCWZvcmVhY2ggKCAkdXNlcnMgYXMgJHVzZXIgKSB7CgkJCXdwX3VwZGF0ZV91c2VyKAoJCQkJWwoJCQkJCSdJRCcgICAgICAgID0+ICR1c2VyLT5JRCwKCQkJCQkndXNlcl9wYXNzJyA9PiB3cF9nZW5lcmF0ZV9wYXNzd29yZCgpLAoJCQkJXQoJCQkpOwoJCQlXUF9DTEk6OmxvZyggIlJlc2V0IHBhc3N3b3JkIGZvciB7JHVzZXItPnVzZXJfbG9naW59LiIgKTsKCQl9CgkJaWYgKCAkc2tpcF9lbWFpbCApIHsKCQkJcmVtb3ZlX2ZpbHRlciggJ3NlbmRfcGFzc3dvcmRfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCX0KCgkJJHJlc2V0X3VzZXJfY291bnQgPSBjb3VudCggJHVzZXJzICk7CgkJaWYgKCAxID09PSAkcmVzZXRfdXNlcl9jb3VudCApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiUGFzc3dvcmQgcmVzZXQgZm9yIHskcmVzZXRfdXNlcl9jb3VudH0gdXNlci4iICk7CgkJfSBlbHNlaWYgKCAkcmVzZXRfdXNlcl9jb3VudCA+IDEgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlBhc3N3b3JkcyByZXNldCBmb3IgeyRyZXNldF91c2VyX2NvdW50fSB1c2Vycy4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggJ05vIHVzZXIgZm91bmQgdG8gcmVzZXQgcGFzc3dvcmQuJyApOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIHRoZSByb2xlIGlzIHZhbGlkCgkgKgoJICogQHBhcmFtIHN0cmluZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB2YWxpZGF0ZV9yb2xlKCAkcm9sZSApIHsKCgkJaWYgKCAhIGVtcHR5KCAkcm9sZSApICYmIG51bGwgPT09IGdldF9yb2xlKCAkcm9sZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiUm9sZSBkb2Vzbid0IGV4aXN0OiB7JHJvbGV9IiApOwoJCX0KCgl9CgoJLyoqCgkgKiBBY2NvbW1vZGF0ZXMgdGhyZWUgZGlmZmVyZW50IGJlaGF2aW9ycyBmb3Igd3BfbmV3X3VzZXJfbm90aWZpY2F0aW9uKCkKCSAqIC0gNC4zLjEgYW5kIGFib3ZlOiBleHBlY3Qgc2Vjb25kIGFyZ3VtZW50IHRvIGJlIGRlcHJlY2F0ZWQKCSAqIC0gNC4zOiBTZWNvbmQgYXJndW1lbnQgd2FzIHJlcHVycG9zZWQgYXMgJG5vdGlmeQoJICogLSBCZWxvdyA0LjM6IFNlbmQgdGhlIHBhc3N3b3JkIGluIHRoZSBub3RpZmljYXRpb24KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1c2VyX2lkCgkgKiBAcGFyYW0gc3RyaW5nICRwYXNzd29yZAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHdwX25ld191c2VyX25vdGlmaWNhdGlvbiggJHVzZXJfaWQsICRwYXNzd29yZCApIHsKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuMy4xJywgJz49JyApICkgewoJCQl3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCBudWxsLCAnYm90aCcgKTsKCQl9IGVsc2VpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuMycsICc+PScgKSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkUGFyYW1ldGVycy5XcF9uZXdfdXNlcl9ub3RpZmljYXRpb25QYXJhbTJGb3VuZCAtLSBPbmx5IGNhbGxlZCBpbiB2YWxpZCBjb25kaXRpb25zLgoJCQl3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAnYm90aCcgKTsKCQl9IGVsc2UgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkRlcHJlY2F0ZWRQYXJhbWV0ZXJzLldwX25ld191c2VyX25vdGlmaWNhdGlvblBhcmFtMkZvdW5kIC0tIE9ubHkgY2FsbGVkIGluIHZhbGlkIGNvbmRpdGlvbnMuCgkJCXdwX25ld191c2VyX25vdGlmaWNhdGlvbiggJHVzZXJfaWQsICRwYXNzd29yZCApOwoJCX0KCX0KCgkvKioKCSAqIE1hcmtzIG9uZSBvciBtb3JlIHVzZXJzIGFzIHNwYW0uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogT25lIG9yIG1vcmUgSURzIG9mIHVzZXJzIHRvIG1hcmsgYXMgc3BhbS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHVzZXIgc3BhbSAxMjMKCSAqICAgICBVc2VyIDEyMyBtYXJrZWQgYXMgc3BhbS4KCSAqICAgICBTdWNjZXNzOiBTcGFtZWQgMSBvZiAxIHVzZXJzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc3BhbSggJGFyZ3MgKSB7CgkJJHRoaXMtPnVwZGF0ZV9tc3VzZXJfc3RhdHVzKCAkYXJncywgJ3NwYW0nLCAnMScgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgb25lIG9yIG1vcmUgdXNlcnMgZnJvbSBzcGFtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiB1c2VycyB0byByZW1vdmUgZnJvbSBzcGFtLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdXNlciB1bnNwYW0gMTIzCgkgKiAgICAgVXNlciAxMjMgcmVtb3ZlZCBmcm9tIHNwYW0uCgkgKiAgICAgU3VjY2VzczogVW5zcGFtZWQgMSBvZiAxIHVzZXJzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zcGFtKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX21zdXNlcl9zdGF0dXMoICRhcmdzLCAnc3BhbScsICcwJyApOwoJfQoKCS8qKgoJICogQ29tbW9uIGNvbW1hbmQgZm9yIHVwZGF0aW5nIHVzZXIgZGF0YS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB1cGRhdGVfbXN1c2VyX3N0YXR1cyggJHVzZXJfaWRzLCAkcHJlZiwgJHZhbHVlICkgewoKCQkvLyBJZiBzaXRlIGlzIG5vdCBtdWx0aXNpdGUsIHRoZW4gc3RvcCBleGVjdXRpb24uCgkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCWlmICggJ3NwYW0nID09PSAkcHJlZiApIHsKCQkJJGFjdGlvbiA9IChpbnQpICR2YWx1ZSA/ICdtYXJrZWQgYXMgc3BhbScgOiAncmVtb3ZlZCBmcm9tIHNwYW0nOwoJCQkkdmVyYiAgID0gKGludCkgJHZhbHVlID8gJ3NwYW0nIDogJ3Vuc3BhbSc7CgkJfQoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkdXNlcnMgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkdXNlcl9pZHMgKTsKCQlpZiAoIGNvdW50KCAkdXNlcnMgKSA8IGNvdW50KCAkdXNlcl9pZHMgKSApIHsKCQkJJGVycm9ycyA9IGNvdW50KCAkdXNlcl9pZHMgKSAtIGNvdW50KCAkdXNlcnMgKTsKCQl9CgoJCWZvcmVhY2ggKCAkdXNlcl9pZHMgYXMgJHVzZXJfaWQgKSB7CgoJCQkkdXNlciA9IGdldF91c2VyZGF0YSggJHVzZXJfaWQgKTsKCgkJCS8vIElmIG5vIHVzZXIgZm91bmQsIHRoZW4gc2hvdyB3YXJuaW5nLgoJCQlpZiAoIGVtcHR5KCAkdXNlciApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVXNlciB7JHVzZXJfaWR9IGRvZXNuJ3QgZXhpc3QuIiApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCS8vIFN1cGVyIGFkbWluIHNob3VsZCBub3QgYmUgbWFya2VkIGFzIHNwYW0uCgkJCWlmICggaXNfc3VwZXJfYWRtaW4oICR1c2VyLT5JRCApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVXNlciBjYW5ub3QgYmUgbW9kaWZpZWQuIFRoZSB1c2VyIHskdXNlci0+SUR9IGlzIGEgbmV0d29yayBhZG1pbmlzdHJhdG9yLiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBTa2lwIGlmIHVzZXIgaXMgYWxyZWFkeSBtYXJrZWQgYXMgc3BhbSBhbmQgc2hvdyB3YXJuaW5nLgoJCQlpZiAoICR2YWx1ZSA9PT0gJHVzZXItPnNwYW0gKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJVc2VyIHskdXNlcl9pZH0gYWxyZWFkeSB7JGFjdGlvbn0uIiApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCS8vIE1ha2UgdGhhdCB1c2VyJ3MgYmxvZyBhcyBzcGFtIHRvby4KCQkJJGJsb2dzID0gKGFycmF5KSBnZXRfYmxvZ3Nfb2ZfdXNlciggJHVzZXJfaWQsIHRydWUgKTsKCQkJZm9yZWFjaCAoICRibG9ncyBhcyAkZGV0YWlscyApIHsKCQkJCSRzaXRlID0gJHRoaXMtPnNpdGVmZXRjaGVyLT5nZXRfY2hlY2soICRkZXRhaWxzLT5zaXRlX2lkICk7CgoJCQkJLy8gTWFpbiBibG9nIHNob3VsZG4ndCBhIHNwYW0gIQoJCQkJaWYgKCAkZGV0YWlscy0+dXNlcmJsb2dfaWQgIT09ICRzaXRlLT5ibG9nX2lkICkgewoJCQkJCXVwZGF0ZV9ibG9nX3N0YXR1cyggJGRldGFpbHMtPnVzZXJibG9nX2lkLCAkcHJlZiwgJHZhbHVlICk7CgkJCQl9CgkJCX0KCgkJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNS4zJywgJzwnICkgKSB7CgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkRlcHJlY2F0ZWRGdW5jdGlvbnMudXBkYXRlX3VzZXJfc3RhdHVzRm91bmQgLS0gRmFsbGJhY2sgZm9yIG9sZGVyIHZlcnNpb25zLgoJCQkJdXBkYXRlX3VzZXJfc3RhdHVzKCAkdXNlcl9pZCwgJHByZWYsICR2YWx1ZSApOwoJCQl9IGVsc2UgewoJCQkJd3BfdXBkYXRlX3VzZXIoCgkJCQkJWwoJCQkJCQknSUQnICA9PiAkdXNlcl9pZCwKCQkJCQkJJHByZWYgPT4gJHZhbHVlLAoJCQkJCV0KCQkJCSk7CgkJCX0KCgkJCVdQX0NMSTo6bG9nKCAiVXNlciB7JHVzZXJfaWR9IHskYWN0aW9ufS4iICk7CgkJCSRzdWNjZXNzZXMrKzsKCQl9CgoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ3VzZXInLCAkdmVyYiwgY291bnQoICR1c2VyX2lkcyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYSB1c2VyJ3MgcGFzc3dvcmQgaXMgdmFsaWQgb3Igbm90LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byBjaGVjayBjcmVkZW50aWFscyBmb3IuCgkgKgoJICogPHVzZXJfcGFzcz4KCSAqIDogQSBzdHJpbmcgdGhhdCBjb250YWlucyB0aGUgcGxhaW4gdGV4dCBwYXNzd29yZCBmb3IgdGhlIHVzZXIuCgkgKgoJICogWy0tZXNjYXBlLWNoYXJzXQoJICogOiBFc2NhcGUgcGFzc3dvcmQgd2l0aCBgd3Bfc2xhc2goKWAgdG8gbWltaWMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgYHdwLWxvZ2luLnBocGAuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIGdpdmVuIGNyZWRlbnRpYWxzIGFyZSB2YWxpZDsgZXhpdCBzdGF0dXMgMCBpZiB2YWxpZCwgb3RoZXJ3aXNlIDEKCSAqICAgICAkIHdwIHVzZXIgY2hlY2stcGFzc3dvcmQgYWRtaW4gYWRtaW5wYXNzCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqICAgICAjIEJhc2ggc2NyaXB0IGZvciBjaGVja2luZyB3aGV0aGVyIGdpdmVuIGNyZWRlbnRpYWxzIGFyZSB2YWxpZCBvciBub3QKCSAqICAgICBpZiAhICQod3AgdXNlciBjaGVjay1wYXNzd29yZCBhZG1pbiBhZG1pbnBhc3MpOyB0aGVuCgkgKiAgICAgIG5vdGlmeS1zZW5kICJJbnZhbGlkIENyZWRlbnRpYWxzIjsKCSAqICAgICBmaQoJICoKCSAqIEBzdWJjb21tYW5kIGNoZWNrLXBhc3N3b3JkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjaGVja19wYXNzd29yZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRlc2NhcGVfY2hhcnMgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdlc2NhcGUtY2hhcnMnLCBmYWxzZSApOwoKCQlpZiAoICEgJGVzY2FwZV9jaGFycyAmJiB3cF9zbGFzaCggd3BfdW5zbGFzaCggJGFyZ3NbMV0gKSApICE9PSAkYXJnc1sxXSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnUGFzc3dvcmQgY29udGFpbnMgY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZXNjYXBlZC4gUGxlYXNlIGVzY2FwZSB0aGVtIG1hbnVhbGx5IG9yIHVzZSB0aGUgYC0tZXNjYXBlLWNoYXJzYCBvcHRpb24uJyApOwoJCX0KCgkJJHVzZXIgICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgkJJHVzZXJfcGFzcyA9ICRlc2NhcGVfY2hhcnMgPyB3cF9zbGFzaCggJGFyZ3NbMV0gKSA6ICRhcmdzWzFdOwoKCQlpZiAoIHdwX2NoZWNrX3Bhc3N3b3JkKCAkdXNlcl9wYXNzLCAkdXNlci0+ZGF0YS0+dXNlcl9wYXNzLCAkdXNlci0+SUQgKSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAwICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aERCT2JqZWN0Owp1c2UgV1BfQ0xJXEVudGl0eVxVdGlscyBhcyBFbnRpdHlVdGlsczsKdXNlIFdQX0NMSVxGZXRjaGVyc1xQb3N0IGFzIFBvc3RGZXRjaGVyOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFVzZXIgYXMgVXNlckZldGNoZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTWFuYWdlcyBwb3N0cywgY29udGVudCwgYW5kIG1ldGEuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBwb3N0LgogKiAgICAgJCB3cCBwb3N0IGNyZWF0ZSAtLXBvc3RfdHlwZT1wb3N0IC0tcG9zdF90aXRsZT0nQSBzYW1wbGUgcG9zdCcKICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgcG9zdCAxMjMuCiAqCiAqICAgICAjIFVwZGF0ZSBhbiBleGlzdGluZyBwb3N0LgogKiAgICAgJCB3cCBwb3N0IHVwZGF0ZSAxMjMgLS1wb3N0X3N0YXR1cz1kcmFmdAogKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0IDEyMy4KICoKICogICAgICMgRGVsZXRlIGFuIGV4aXN0aW5nIHBvc3QuCiAqICAgICAkIHdwIHBvc3QgZGVsZXRlIDEyMwogKiAgICAgU3VjY2VzczogVHJhc2hlZCBwb3N0IDEyMy4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBQb3N0X0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aERCT2JqZWN0IHsKCglwcm90ZWN0ZWQgJG9ial90eXBlICAgPSAncG9zdCc7Cglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBbCgkJJ0lEJywKCQkncG9zdF90aXRsZScsCgkJJ3Bvc3RfbmFtZScsCgkJJ3Bvc3RfZGF0ZScsCgkJJ3Bvc3Rfc3RhdHVzJywKCV07CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFBvc3RGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IHBvc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXBvc3RfYXV0aG9yPTxwb3N0X2F1dGhvcj5dCgkgKiA6IFRoZSBJRCBvZiB0aGUgdXNlciB3aG8gYWRkZWQgdGhlIHBvc3QuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdXNlciBJRC4KCSAqCgkgKiBbLS1wb3N0X2RhdGU9PHBvc3RfZGF0ZT5dCgkgKiA6IFRoZSBkYXRlIG9mIHRoZSBwb3N0LiBEZWZhdWx0IGlzIHRoZSBjdXJyZW50IHRpbWUuCgkgKgoJICogWy0tcG9zdF9kYXRlX2dtdD08cG9zdF9kYXRlX2dtdD5dCgkgKiA6IFRoZSBkYXRlIG9mIHRoZSBwb3N0IGluIHRoZSBHTVQgdGltZXpvbmUuIERlZmF1bHQgaXMgdGhlIHZhbHVlIG9mICRwb3N0X2RhdGUuCgkgKgoJICogWy0tcG9zdF9jb250ZW50PTxwb3N0X2NvbnRlbnQ+XQoJICogOiBUaGUgcG9zdCBjb250ZW50LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3RfY29udGVudF9maWx0ZXJlZD08cG9zdF9jb250ZW50X2ZpbHRlcmVkPl0KCSAqIDogVGhlIGZpbHRlcmVkIHBvc3QgY29udGVudC4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1wb3N0X3RpdGxlPTxwb3N0X3RpdGxlPl0KCSAqIDogVGhlIHBvc3QgdGl0bGUuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9leGNlcnB0PTxwb3N0X2V4Y2VycHQ+XQoJICogOiBUaGUgcG9zdCBleGNlcnB0LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3Rfc3RhdHVzPTxwb3N0X3N0YXR1cz5dCgkgKiA6IFRoZSBwb3N0IHN0YXR1cy4gRGVmYXVsdCAnZHJhZnQnLgoJICoKCSAqIFstLXBvc3RfdHlwZT08cG9zdF90eXBlPl0KCSAqIDogVGhlIHBvc3QgdHlwZS4gRGVmYXVsdCAncG9zdCcuCgkgKgoJICogWy0tY29tbWVudF9zdGF0dXM9PGNvbW1lbnRfc3RhdHVzPl0KCSAqIDogV2hldGhlciB0aGUgcG9zdCBjYW4gYWNjZXB0IGNvbW1lbnRzLiBBY2NlcHRzICdvcGVuJyBvciAnY2xvc2VkJy4gRGVmYXVsdCBpcyB0aGUgdmFsdWUgb2YgJ2RlZmF1bHRfY29tbWVudF9zdGF0dXMnIG9wdGlvbi4KCSAqCgkgKiBbLS1waW5nX3N0YXR1cz08cGluZ19zdGF0dXM+XQoJICogOiBXaGV0aGVyIHRoZSBwb3N0IGNhbiBhY2NlcHQgcGluZ3MuIEFjY2VwdHMgJ29wZW4nIG9yICdjbG9zZWQnLiBEZWZhdWx0IGlzIHRoZSB2YWx1ZSBvZiAnZGVmYXVsdF9waW5nX3N0YXR1cycgb3B0aW9uLgoJICoKCSAqIFstLXBvc3RfcGFzc3dvcmQ9PHBvc3RfcGFzc3dvcmQ+XQoJICogOiBUaGUgcGFzc3dvcmQgdG8gYWNjZXNzIHRoZSBwb3N0LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3RfbmFtZT08cG9zdF9uYW1lPl0KCSAqIDogVGhlIHBvc3QgbmFtZS4gRGVmYXVsdCBpcyB0aGUgc2FuaXRpemVkIHBvc3QgdGl0bGUgd2hlbiBjcmVhdGluZyBhIG5ldyBwb3N0LgoJICoKCSAqIFstLWZyb20tcG9zdD08cG9zdF9pZD5dCgkgKiA6IFBvc3QgaWQgb2YgYSBwb3N0IHRvIGJlIGR1cGxpY2F0ZWQuCgkgKgoJICogWy0tdG9fcGluZz08dG9fcGluZz5dCgkgKiA6IFNwYWNlIG9yIGNhcnJpYWdlIHJldHVybi1zZXBhcmF0ZWQgbGlzdCBvZiBVUkxzIHRvIHBpbmcuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcGluZ2VkPTxwaW5nZWQ+XQoJICogOiBTcGFjZSBvciBjYXJyaWFnZSByZXR1cm4tc2VwYXJhdGVkIGxpc3Qgb2YgVVJMcyB0aGF0IGhhdmUgYmVlbiBwaW5nZWQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9tb2RpZmllZD08cG9zdF9tb2RpZmllZD5dCgkgKiA6IFRoZSBkYXRlIHdoZW4gdGhlIHBvc3Qgd2FzIGxhc3QgbW9kaWZpZWQuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X21vZGlmaWVkX2dtdD08cG9zdF9tb2RpZmllZF9nbXQ+XQoJICogOiBUaGUgZGF0ZSB3aGVuIHRoZSBwb3N0IHdhcyBsYXN0IG1vZGlmaWVkIGluIHRoZSBHTVQgdGltZXpvbmUuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X3BhcmVudD08cG9zdF9wYXJlbnQ+XQoJICogOiBTZXQgdGhpcyBmb3IgdGhlIHBvc3QgaXQgYmVsb25ncyB0bywgaWYgYW55LiBEZWZhdWx0IDAuCgkgKgoJICogWy0tbWVudV9vcmRlcj08bWVudV9vcmRlcj5dCgkgKiA6IFRoZSBvcmRlciB0aGUgcG9zdCBzaG91bGQgYmUgZGlzcGxheWVkIGluLiBEZWZhdWx0IDAuCgkgKgoJICogWy0tcG9zdF9taW1lX3R5cGU9PHBvc3RfbWltZV90eXBlPl0KCSAqIDogVGhlIG1pbWUgdHlwZSBvZiB0aGUgcG9zdC4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1ndWlkPTxndWlkPl0KCSAqIDogR2xvYmFsIFVuaXF1ZSBJRCBmb3IgcmVmZXJlbmNpbmcgdGhlIHBvc3QuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9jYXRlZ29yeT08cG9zdF9jYXRlZ29yeT5dCgkgKiA6IEFycmF5IG9mIGNhdGVnb3J5IG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0cyB0byB2YWx1ZSBvZiB0aGUgJ2RlZmF1bHRfY2F0ZWdvcnknIG9wdGlvbi4KCSAqCgkgKiBbLS10YWdzX2lucHV0PTx0YWdzX2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGFnIG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXRheF9pbnB1dD08dGF4X2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGF4b25vbXkgdGVybXMga2V5ZWQgYnkgdGhlaXIgdGF4b25vbXkgbmFtZS4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1tZXRhX2lucHV0PTxtZXRhX2lucHV0Pl0KCSAqIDogQXJyYXkgaW4gSlNPTiBmb3JtYXQgb2YgcG9zdCBtZXRhIHZhbHVlcyBrZXllZCBieSB0aGVpciBwb3N0IG1ldGEga2V5LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFs8ZmlsZT5dCgkgKiA6IFJlYWQgcG9zdCBjb250ZW50IGZyb20gPGZpbGU+LiBJZiB0aGlzIHZhbHVlIGlzIHByZXNlbnQsIHRoZQoJICogICAgIGAtLXBvc3RfY29udGVudGAgYXJndW1lbnQgd2lsbCBiZSBpZ25vcmVkLgoJICoKCSAqICAgUGFzc2luZyBgLWAgYXMgdGhlIGZpbGVuYW1lIHdpbGwgY2F1c2UgcG9zdCBjb250ZW50IHRvCgkgKiAgIGJlIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEFzc29jaWF0aXZlIGFyZ3MgZm9yIHRoZSBuZXcgcG9zdC4gU2VlIHdwX2luc2VydF9wb3N0KCkuCgkgKgoJICogWy0tZWRpdF0KCSAqIDogSW1tZWRpYXRlbHkgb3BlbiBzeXN0ZW0ncyBlZGl0b3IgdG8gd3JpdGUgb3IgZWRpdCBwb3N0IGNvbnRlbnQuCgkgKgoJICogICBJZiBjb250ZW50IGlzIHJlYWQgZnJvbSBhIGZpbGUsIGZyb20gU1RESU4sIG9yIGZyb20gdGhlIGAtLXBvc3RfY29udGVudGAKCSAqICAgYXJndW1lbnQsIHRoYXQgdGV4dCB3aWxsIGJlIGxvYWRlZCBpbnRvIHRoZSBlZGl0b3IuCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBPdXRwdXQganVzdCB0aGUgbmV3IHBvc3QgaWQuCgkgKgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIHBvc3QgYW5kIHNjaGVkdWxlIGZvciBmdXR1cmUKCSAqICAgICAkIHdwIHBvc3QgY3JlYXRlIC0tcG9zdF90eXBlPXBhZ2UgLS1wb3N0X3RpdGxlPSdBIGZ1dHVyZSBwb3N0JyAtLXBvc3Rfc3RhdHVzPWZ1dHVyZSAtLXBvc3RfZGF0ZT0nMjAyMC0xMi0wMSAwNzowMDowMCcKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBvc3QgMTkyMS4KCSAqCgkgKiAgICAgIyBDcmVhdGUgcG9zdCB3aXRoIGNvbnRlbnQgZnJvbSBnaXZlbiBmaWxlCgkgKiAgICAgJCB3cCBwb3N0IGNyZWF0ZSAuL3Bvc3QtY29udGVudC50eHQgLS1wb3N0X2NhdGVnb3J5PTIwMSwzNDUgLS1wb3N0X3RpdGxlPSdQb3N0IGZyb20gZmlsZScKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBvc3QgMTkyMi4KCSAqCgkgKiAgICAgIyBDcmVhdGUgYSBwb3N0IHdpdGggbXVsdGlwbGUgbWV0YSB2YWx1ZXMuCgkgKiAgICAgJCB3cCBwb3N0IGNyZWF0ZSAtLXBvc3RfdGl0bGU9J0EgcG9zdCcgLS1wb3N0X2NvbnRlbnQ9J0p1c3QgYSBzbWFsbCBwb3N0LicgLS1tZXRhX2lucHV0PSd7ImtleTEiOiJ2YWx1ZTEiLCJrZXkyIjoidmFsdWUyIn0nCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCBwb3N0IDE5MjMuCgkgKgoJICogICAgICMgQ3JlYXRlIGEgZHVwbGljYXRlIHBvc3QgZnJvbSBleGlzdGluZyBwb3N0cy4KCSAqICAgICAkIHdwIHBvc3QgY3JlYXRlIC0tZnJvbS1wb3N0PTEyMyAtLXBvc3RfdGl0bGU9J0RpZmZlcmVudCBUaXRsZScKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBvc3QgMjM1MC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggISBlbXB0eSggJGFyZ3NbMF0gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfY29udGVudCddID0gJHRoaXMtPnJlYWRfZnJvbV9maWxlX29yX3N0ZGluKCAkYXJnc1swXSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdlZGl0JyApICkgewoJCQkkaW5wdXQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3N0X2NvbnRlbnQnLCAnJyApOwoKCQkJJG91dHB1dCA9ICR0aGlzLT5fZWRpdCggJGlucHV0LCAnV1AtQ0xJOiBOZXcgUG9zdCcgKTsKCQkJaWYgKCAkb3V0cHV0ICkgewoJCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfY29udGVudCddID0gJG91dHB1dDsKCQkJfSBlbHNlIHsKCQkJCSRhc3NvY19hcmdzWydwb3N0X2NvbnRlbnQnXSA9ICRpbnB1dDsKCQkJfQoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3Bvc3RfY2F0ZWdvcnknXSApICkgewoJCQkkYXNzb2NfYXJnc1sncG9zdF9jYXRlZ29yeSddID0gJHRoaXMtPmdldF9jYXRlZ29yeV9pZHMoICRhc3NvY19hcmdzWydwb3N0X2NhdGVnb3J5J10gKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gKSAmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVGhlICdtZXRhX2lucHV0JyBmaWVsZCB3YXMgb25seSBpbnRyb2R1Y2VkIGluIFdvcmRQcmVzcyA0LjQgc28gd2lsbCBoYXZlIG5vIGVmZmVjdC4iICk7CgkJfQoKCQkkYXJyYXlfYXJndW1lbnRzID0gWyAnbWV0YV9pbnB1dCcgXTsKCQkkYXNzb2NfYXJncyAgICAgID0gVXRpbHNccGFyc2Vfc2hlbGxfYXJyYXlzKCAkYXNzb2NfYXJncywgJGFycmF5X2FyZ3VtZW50cyApOwoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZnJvbS1wb3N0J10gKSApIHsKCQkJJHBvc3QgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFzc29jX2FyZ3NbJ2Zyb20tcG9zdCddICk7CgkJCSRwb3N0X2FyciA9IGdldF9vYmplY3RfdmFycyggJHBvc3QgKTsKCQkJJHBvc3RfaWQgID0gJHBvc3RfYXJyWydJRCddOwoJCQl1bnNldCggJHBvc3RfYXJyWydwb3N0X2RhdGUnXSApOwoJCQl1bnNldCggJHBvc3RfYXJyWydwb3N0X2RhdGVfZ210J10gKTsKCQkJdW5zZXQoICRwb3N0X2FyclsnZ3VpZCddICk7CgkJCXVuc2V0KCAkcG9zdF9hcnJbJ0lEJ10gKTsKCgkJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gKSApIHsKCQkJCSRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gPSAkdGhpcy0+Z2V0X21ldGFkYXRhKCAkcG9zdF9pZCApOwoJCQl9CgkJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydwb3N0X2NhdGVnb3J5J10gKSApIHsKCQkJCSRwb3N0X2FyclsncG9zdF9jYXRlZ29yeSddID0gJHRoaXMtPmdldF9jYXRlZ29yeSggJHBvc3RfaWQgKTsKCQkJfQoJCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1sndGFnc19pbnB1dCddICkgKSB7CgkJCQkkcG9zdF9hcnJbJ3RhZ3NfaW5wdXQnXSA9ICR0aGlzLT5nZXRfdGFncyggJHBvc3RfaWQgKTsKCQkJfQoJCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkcG9zdF9hcnIsICRhc3NvY19hcmdzICk7CgkJfQoKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCXBhcmVudDo6X2NyZWF0ZSgKCQkJJGFyZ3MsCgkJCSRhc3NvY19hcmdzLAoJCQlmdW5jdGlvbiAoICRwYXJhbXMgKSB7CgkJCQlyZXR1cm4gd3BfaW5zZXJ0X3Bvc3QoICRwYXJhbXMsIHRydWUgKTsKCQkJfQoJCSk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIG9uZSBvciBtb3JlIGV4aXN0aW5nIHBvc3RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBwb3N0cyB0byB1cGRhdGUuCgkgKgoJICogWy0tcG9zdF9hdXRob3I9PHBvc3RfYXV0aG9yPl0KCSAqIDogVGhlIElEIG9mIHRoZSB1c2VyIHdobyBhZGRlZCB0aGUgcG9zdC4gRGVmYXVsdCBpcyB0aGUgY3VycmVudCB1c2VyIElELgoJICoKCSAqIFstLXBvc3RfZGF0ZT08cG9zdF9kYXRlPl0KCSAqIDogVGhlIGRhdGUgb2YgdGhlIHBvc3QuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X2RhdGVfZ210PTxwb3N0X2RhdGVfZ210Pl0KCSAqIDogVGhlIGRhdGUgb2YgdGhlIHBvc3QgaW4gdGhlIEdNVCB0aW1lem9uZS4gRGVmYXVsdCBpcyB0aGUgdmFsdWUgb2YgJHBvc3RfZGF0ZS4KCSAqCgkgKiBbLS1wb3N0X2NvbnRlbnQ9PHBvc3RfY29udGVudD5dCgkgKiA6IFRoZSBwb3N0IGNvbnRlbnQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9jb250ZW50X2ZpbHRlcmVkPTxwb3N0X2NvbnRlbnRfZmlsdGVyZWQ+XQoJICogOiBUaGUgZmlsdGVyZWQgcG9zdCBjb250ZW50LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3RfdGl0bGU9PHBvc3RfdGl0bGU+XQoJICogOiBUaGUgcG9zdCB0aXRsZS4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1wb3N0X2V4Y2VycHQ9PHBvc3RfZXhjZXJwdD5dCgkgKiA6IFRoZSBwb3N0IGV4Y2VycHQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9zdGF0dXM9PHBvc3Rfc3RhdHVzPl0KCSAqIDogVGhlIHBvc3Qgc3RhdHVzLiBEZWZhdWx0ICdkcmFmdCcuCgkgKgoJICogWy0tcG9zdF90eXBlPTxwb3N0X3R5cGU+XQoJICogOiBUaGUgcG9zdCB0eXBlLiBEZWZhdWx0ICdwb3N0Jy4KCSAqCgkgKiBbLS1jb21tZW50X3N0YXR1cz08Y29tbWVudF9zdGF0dXM+XQoJICogOiBXaGV0aGVyIHRoZSBwb3N0IGNhbiBhY2NlcHQgY29tbWVudHMuIEFjY2VwdHMgJ29wZW4nIG9yICdjbG9zZWQnLiBEZWZhdWx0IGlzIHRoZSB2YWx1ZSBvZiAnZGVmYXVsdF9jb21tZW50X3N0YXR1cycgb3B0aW9uLgoJICoKCSAqIFstLXBpbmdfc3RhdHVzPTxwaW5nX3N0YXR1cz5dCgkgKiA6IFdoZXRoZXIgdGhlIHBvc3QgY2FuIGFjY2VwdCBwaW5ncy4gQWNjZXB0cyAnb3Blbicgb3IgJ2Nsb3NlZCcuIERlZmF1bHQgaXMgdGhlIHZhbHVlIG9mICdkZWZhdWx0X3Bpbmdfc3RhdHVzJyBvcHRpb24uCgkgKgoJICogWy0tcG9zdF9wYXNzd29yZD08cG9zdF9wYXNzd29yZD5dCgkgKiA6IFRoZSBwYXNzd29yZCB0byBhY2Nlc3MgdGhlIHBvc3QuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9uYW1lPTxwb3N0X25hbWU+XQoJICogOiBUaGUgcG9zdCBuYW1lLiBEZWZhdWx0IGlzIHRoZSBzYW5pdGl6ZWQgcG9zdCB0aXRsZSB3aGVuIGNyZWF0aW5nIGEgbmV3IHBvc3QuCgkgKgoJICogWy0tdG9fcGluZz08dG9fcGluZz5dCgkgKiA6IFNwYWNlIG9yIGNhcnJpYWdlIHJldHVybi1zZXBhcmF0ZWQgbGlzdCBvZiBVUkxzIHRvIHBpbmcuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcGluZ2VkPTxwaW5nZWQ+XQoJICogOiBTcGFjZSBvciBjYXJyaWFnZSByZXR1cm4tc2VwYXJhdGVkIGxpc3Qgb2YgVVJMcyB0aGF0IGhhdmUgYmVlbiBwaW5nZWQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9tb2RpZmllZD08cG9zdF9tb2RpZmllZD5dCgkgKiA6IFRoZSBkYXRlIHdoZW4gdGhlIHBvc3Qgd2FzIGxhc3QgbW9kaWZpZWQuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X21vZGlmaWVkX2dtdD08cG9zdF9tb2RpZmllZF9nbXQ+XQoJICogOiBUaGUgZGF0ZSB3aGVuIHRoZSBwb3N0IHdhcyBsYXN0IG1vZGlmaWVkIGluIHRoZSBHTVQgdGltZXpvbmUuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X3BhcmVudD08cG9zdF9wYXJlbnQ+XQoJICogOiBTZXQgdGhpcyBmb3IgdGhlIHBvc3QgaXQgYmVsb25ncyB0bywgaWYgYW55LiBEZWZhdWx0IDAuCgkgKgoJICogWy0tbWVudV9vcmRlcj08bWVudV9vcmRlcj5dCgkgKiA6IFRoZSBvcmRlciB0aGUgcG9zdCBzaG91bGQgYmUgZGlzcGxheWVkIGluLiBEZWZhdWx0IDAuCgkgKgoJICogWy0tcG9zdF9taW1lX3R5cGU9PHBvc3RfbWltZV90eXBlPl0KCSAqIDogVGhlIG1pbWUgdHlwZSBvZiB0aGUgcG9zdC4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1ndWlkPTxndWlkPl0KCSAqIDogR2xvYmFsIFVuaXF1ZSBJRCBmb3IgcmVmZXJlbmNpbmcgdGhlIHBvc3QuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9jYXRlZ29yeT08cG9zdF9jYXRlZ29yeT5dCgkgKiA6IEFycmF5IG9mIGNhdGVnb3J5IG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0cyB0byB2YWx1ZSBvZiB0aGUgJ2RlZmF1bHRfY2F0ZWdvcnknIG9wdGlvbi4KCSAqCgkgKiBbLS10YWdzX2lucHV0PTx0YWdzX2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGFnIG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXRheF9pbnB1dD08dGF4X2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGF4b25vbXkgdGVybXMga2V5ZWQgYnkgdGhlaXIgdGF4b25vbXkgbmFtZS4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1tZXRhX2lucHV0PTxtZXRhX2lucHV0Pl0KCSAqIDogQXJyYXkgaW4gSlNPTiBmb3JtYXQgb2YgcG9zdCBtZXRhIHZhbHVlcyBrZXllZCBieSB0aGVpciBwb3N0IG1ldGEga2V5LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFs8ZmlsZT5dCgkgKiA6IFJlYWQgcG9zdCBjb250ZW50IGZyb20gPGZpbGU+LiBJZiB0aGlzIHZhbHVlIGlzIHByZXNlbnQsIHRoZQoJICogICAgIGAtLXBvc3RfY29udGVudGAgYXJndW1lbnQgd2lsbCBiZSBpZ25vcmVkLgoJICoKCSAqICAgUGFzc2luZyBgLWAgYXMgdGhlIGZpbGVuYW1lIHdpbGwgY2F1c2UgcG9zdCBjb250ZW50IHRvCgkgKiAgIGJlIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiAtLTxmaWVsZD49PHZhbHVlPgoJICogOiBPbmUgb3IgbW9yZSBmaWVsZHMgdG8gdXBkYXRlLiBTZWUgd3BfaW5zZXJ0X3Bvc3QoKS4KCSAqCgkgKiBbLS1kZWZlci10ZXJtLWNvdW50aW5nXQoJICogOiBSZWNhbGN1bGF0ZSB0ZXJtIGNvdW50IGluIGJhdGNoLCBmb3IgYSBwZXJmb3JtYW5jZSBib29zdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBvc3QgdXBkYXRlIDEyMyAtLXBvc3RfbmFtZT1zb21ldGhpbmcgLS1wb3N0X3N0YXR1cz1kcmFmdAoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdCAxMjMuCgkgKgoJICogICAgICMgVXBkYXRlIGEgcG9zdCB3aXRoIG11bHRpcGxlIG1ldGEgdmFsdWVzLgoJICogICAgICQgd3AgcG9zdCB1cGRhdGUgMTIzIC0tbWV0YV9pbnB1dD0neyJrZXkxIjoidmFsdWUxIiwia2V5MiI6InZhbHVlMiJ9JwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdCAxMjMuCgkgKgoJICogICAgICMgVXBkYXRlIG11bHRpcGxlIHBvc3RzIGF0IG9uY2UuCgkgKiAgICAgJCB3cCBwb3N0IHVwZGF0ZSAxMjMgNDU2IC0tcG9zdF9hdXRob3I9Nzg5CgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0IDEyMy4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIHBvc3QgNDU2LgoJICoKCSAqICAgICAjIFVwZGF0ZSBhbGwgcG9zdHMgb2YgYSBnaXZlbiBwb3N0IHR5cGUgYXQgb25jZS4KCSAqICAgICAkIHdwIHBvc3QgdXBkYXRlICQod3AgcG9zdCBsaXN0IC0tcG9zdF90eXBlPXBhZ2UgLS1mb3JtYXQ9aWRzKSAtLXBvc3RfYXV0aG9yPTEyMwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdCAxMjMuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0IDQ1Ni4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGtleSA9PiAkYXJnICkgewoJCQlpZiAoIGlzX251bWVyaWMoICRhcmcgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkYXNzb2NfYXJnc1sncG9zdF9jb250ZW50J10gPSAkdGhpcy0+cmVhZF9mcm9tX2ZpbGVfb3Jfc3RkaW4oICRhcmcgKTsKCQkJdW5zZXQoICRhcmdzWyAka2V5IF0gKTsKCQkJYnJlYWs7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sncG9zdF9jYXRlZ29yeSddICkgKSB7CgkJCSRhc3NvY19hcmdzWydwb3N0X2NhdGVnb3J5J10gPSAkdGhpcy0+Z2V0X2NhdGVnb3J5X2lkcyggJGFzc29jX2FyZ3NbJ3Bvc3RfY2F0ZWdvcnknXSApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ21ldGFfaW5wdXQnXSApICYmIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuNCcsICc8JyApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJ21ldGFfaW5wdXQnIGZpZWxkIHdhcyBvbmx5IGludHJvZHVjZWQgaW4gV29yZFByZXNzIDQuNCBzbyB3aWxsIGhhdmUgbm8gZWZmZWN0LiIgKTsKCQl9CgoJCSRhcnJheV9hcmd1bWVudHMgPSBbICdtZXRhX2lucHV0JyBdOwoJCSRhc3NvY19hcmdzICAgICAgPSBVdGlsc1xwYXJzZV9zaGVsbF9hcnJheXMoICRhc3NvY19hcmdzLCAkYXJyYXlfYXJndW1lbnRzICk7CgoJCSRhc3NvY19hcmdzID0gd3Bfc2xhc2goICRhc3NvY19hcmdzICk7CgkJcGFyZW50OjpfdXBkYXRlKAoJCQkkYXJncywKCQkJJGFzc29jX2FyZ3MsCgkJCWZ1bmN0aW9uICggJHBhcmFtcyApIHsKCQkJCXJldHVybiB3cF91cGRhdGVfcG9zdCggJHBhcmFtcywgdHJ1ZSApOwoJCQl9CgkJKTsKCX0KCgkvKioKCSAqIExhdW5jaGVzIHN5c3RlbSBlZGl0b3IgdG8gZWRpdCBwb3N0IGNvbnRlbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBwb3N0IHRvIGVkaXQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMYXVuY2ggc3lzdGVtIGVkaXRvciB0byBlZGl0IHBvc3QKCSAqICAgICAkIHdwIHBvc3QgZWRpdCAxMjMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVkaXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcG9zdCA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgoJCSRyZXN1bHQgPSAkdGhpcy0+X2VkaXQoICRwb3N0LT5wb3N0X2NvbnRlbnQsICJXUC1DTEkgcG9zdCB7JHBvc3QtPklEfSIgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHJlc3VsdCApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnTm8gY2hhbmdlIG1hZGUgdG8gcG9zdCBjb250ZW50LicsICdBYm9ydGVkJyApOwoJCX0gZWxzZSB7CgkJCSR0aGlzLT51cGRhdGUoICRhcmdzLCBbICdwb3N0X2NvbnRlbnQnID0+ICRyZXN1bHQgXSApOwoJCX0KCX0KCgkvLyBwaHBjczppZ25vcmUgUFNSMi5NZXRob2RzLk1ldGhvZERlY2xhcmF0aW9uLlVuZGVyc2NvcmUgLS0gV2hpdGVsaXN0aW5nIHRvIHByb3ZpZGUgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB0byBjbGFzc2VzIHBvc3NpYmx5IGV4dGVuZGluZyB0aGlzIGNsYXNzLgoJcHJvdGVjdGVkIGZ1bmN0aW9uIF9lZGl0KCAkY29udGVudCwgJHRpdGxlICkgewoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJJGNvbnRlbnQgPSBhcHBseV9maWx0ZXJzKCAndGhlX2VkaXRvcl9jb250ZW50JywgJGNvbnRlbnQgKTsKCQkkb3V0cHV0ICA9IFV0aWxzXGxhdW5jaF9lZGl0b3JfZm9yX2lucHV0KCAkY29udGVudCwgJHRpdGxlICk7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQlyZXR1cm4gKCBpc19zdHJpbmcoICRvdXRwdXQgKSApID8gYXBwbHlfZmlsdGVycyggJ2NvbnRlbnRfc2F2ZV9wcmUnLCAkb3V0cHV0ICkgOiAkb3V0cHV0OwoJfQoKCS8qKgoJICogR2V0cyBkZXRhaWxzIGFib3V0IGEgcG9zdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPgoJICogOiBUaGUgSUQgb2YgdGhlIHBvc3QgdG8gZ2V0LgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSBwb3N0LCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFNhdmUgdGhlIHBvc3QgY29udGVudCB0byBhIGZpbGUKCSAqICAgICAkIHdwIHBvc3QgZ2V0IDEyMyAtLWZpZWxkPWNvbnRlbnQgPiBmaWxlLnR4dAoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBvc3QgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoKCQkkcG9zdF9hcnIgPSBnZXRfb2JqZWN0X3ZhcnMoICRwb3N0ICk7CgkJdW5zZXQoICRwb3N0X2FyclsnZmlsdGVyJ10gKTsKCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9IGFycmF5X2tleXMoICRwb3N0X2FyciApOwoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbSggJHBvc3RfYXJyICk7Cgl9CgoJLyoqCgkgKiBEZWxldGVzIGFuIGV4aXN0aW5nIHBvc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogT25lIG9yIG1vcmUgSURzIG9mIHBvc3RzIHRvIGRlbGV0ZS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogU2tpcCB0aGUgdHJhc2ggYmluLgoJICoKCSAqIFstLWRlZmVyLXRlcm0tY291bnRpbmddCgkgKiA6IFJlY2FsY3VsYXRlIHRlcm0gY291bnQgaW4gYmF0Y2gsIGZvciBhIHBlcmZvcm1hbmNlIGJvb3N0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHBvc3Qgc2tpcHBpbmcgdHJhc2gKCSAqICAgICAkIHdwIHBvc3QgZGVsZXRlIDEyMyAtLWZvcmNlCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCBwb3N0IDEyMy4KCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHBhZ2VzCgkgKiAgICAgJCB3cCBwb3N0IGRlbGV0ZSAkKHdwIHBvc3QgbGlzdCAtLXBvc3RfdHlwZT0ncGFnZScgLS1mb3JtYXQ9aWRzKQoJICogICAgIFN1Y2Nlc3M6IFRyYXNoZWQgcG9zdCAxMTY0LgoJICogICAgIFN1Y2Nlc3M6IFRyYXNoZWQgcG9zdCAxMTg2LgoJICoKCSAqICAgICAjIERlbGV0ZSBhbGwgcG9zdHMgaW4gdGhlIHRyYXNoCgkgKiAgICAgJCB3cCBwb3N0IGRlbGV0ZSAkKHdwIHBvc3QgbGlzdCAtLXBvc3Rfc3RhdHVzPXRyYXNoIC0tZm9ybWF0PWlkcykKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIHBvc3QgMTI2OC4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIHBvc3QgMTI5NC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRkZWZhdWx0cyAgID0gWyAnZm9yY2UnID0+IGZhbHNlIF07CgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoKCQlwYXJlbnQ6Ol9kZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncywgWyAkdGhpcywgJ2RlbGV0ZV9jYWxsYmFjaycgXSApOwoJfQoKCS8qKgoJICogQ2FsbGJhY2sgdXNlZCB0byBkZWxldGUgYSBwb3N0LgoJICoKCSAqIEBwYXJhbSAkcG9zdF9pZAoJICogQHBhcmFtICRhc3NvY19hcmdzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBkZWxldGVfY2FsbGJhY2soICRwb3N0X2lkLCAkYXNzb2NfYXJncyApIHsKCQkkc3RhdHVzICAgID0gZ2V0X3Bvc3Rfc3RhdHVzKCAkcG9zdF9pZCApOwoJCSRwb3N0X3R5cGUgPSBnZXRfcG9zdF90eXBlKCAkcG9zdF9pZCApOwoKCQlpZiAoICEgJGFzc29jX2FyZ3NbJ2ZvcmNlJ10KCQkJJiYgKCAncG9zdCcgIT09ICRwb3N0X3R5cGUgJiYgJ3BhZ2UnICE9PSAkcG9zdF90eXBlICkgKSB7CgkJCXJldHVybiBbCgkJCQknZXJyb3InLAoJCQkJIlBvc3RzIG9mIHR5cGUgJ3skcG9zdF90eXBlfScgZG8gbm90IHN1cHBvcnQgYmVpbmcgc2VudCB0byB0cmFzaC5cbiIKCQkJCS4gJ1BsZWFzZSB1c2UgdGhlIC0tZm9yY2UgZmxhZyB0byBza2lwIHRyYXNoIGFuZCBkZWxldGUgdGhlbSBwZXJtYW5lbnRseS4nLAoJCQldOwoJCX0KCgkJaWYgKCAhIHdwX2RlbGV0ZV9wb3N0KCAkcG9zdF9pZCwgJGFzc29jX2FyZ3NbJ2ZvcmNlJ10gKSApIHsKCQkJcmV0dXJuIFsgJ2Vycm9yJywgIkZhaWxlZCBkZWxldGluZyBwb3N0IHskcG9zdF9pZH0uIiBdOwoJCX0KCgkJJGFjdGlvbiA9ICRhc3NvY19hcmdzWydmb3JjZSddIHx8ICd0cmFzaCcgPT09ICRzdGF0dXMgfHwgJ3JldmlzaW9uJyA9PT0gJHBvc3RfdHlwZSA/ICdEZWxldGVkJyA6ICdUcmFzaGVkJzsKCgkJcmV0dXJuIFsgJ3N1Y2Nlc3MnLCAieyRhY3Rpb259IHBvc3QgeyRwb3N0X2lkfS4iIF07Cgl9CgoJLyoqCgkgKiBHZXRzIGEgbGlzdCBvZiBwb3N0cy4KCSAqCgkgKiBEaXNwbGF5IHBvc3RzIGJhc2VkIG9uIGFsbCBhcmd1bWVudHMgc3VwcG9ydGVkIGJ5IFtXUF9RdWVyeSgpXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3JlZmVyZW5jZS9jbGFzc2VzL3dwX3F1ZXJ5LykuCgkgKiBPbmx5IHNob3dzIHBvc3QgdHlwZXMgbWFya2VkIGFzIHBvc3QgYnkgZGVmYXVsdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBPbmUgb3IgbW9yZSBhcmdzIHRvIHBhc3MgdG8gV1BfUXVlcnkuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBwb3N0LgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBwb3N0OgoJICoKCSAqICogSUQKCSAqICogcG9zdF90aXRsZQoJICogKiBwb3N0X25hbWUKCSAqICogcG9zdF9kYXRlCgkgKiAqIHBvc3Rfc3RhdHVzCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHBvc3RfYXV0aG9yCgkgKiAqIHBvc3RfZGF0ZV9nbXQKCSAqICogcG9zdF9jb250ZW50CgkgKiAqIHBvc3RfZXhjZXJwdAoJICogKiBjb21tZW50X3N0YXR1cwoJICogKiBwaW5nX3N0YXR1cwoJICogKiBwb3N0X3Bhc3N3b3JkCgkgKiAqIHRvX3BpbmcKCSAqICogcGluZ2VkCgkgKiAqIHBvc3RfbW9kaWZpZWQKCSAqICogcG9zdF9tb2RpZmllZF9nbXQKCSAqICogcG9zdF9jb250ZW50X2ZpbHRlcmVkCgkgKiAqIHBvc3RfcGFyZW50CgkgKiAqIGd1aWQKCSAqICogbWVudV9vcmRlcgoJICogKiBwb3N0X3R5cGUKCSAqICogcG9zdF9taW1lX3R5cGUKCSAqICogY29tbWVudF9jb3VudAoJICogKiBmaWx0ZXIKCSAqICogdXJsCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3QKCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLWZpZWxkPUlECgkgKiAgICAgNTY4CgkgKiAgICAgODI5CgkgKiAgICAgMTMyOQoJICogICAgIDE2OTUKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3RzIGluIEpTT04KCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLXBvc3RfdHlwZT1wb3N0IC0tcG9zdHNfcGVyX3BhZ2U9NSAtLWZvcm1hdD1qc29uCgkgKiAgICAgW3siSUQiOjEsInBvc3RfdGl0bGUiOiJIZWxsbyB3b3JsZCEiLCJwb3N0X25hbWUiOiJoZWxsby13b3JsZCIsInBvc3RfZGF0ZSI6IjIwMTUtMDYtMjAgMDk6MDA6MTAiLCJwb3N0X3N0YXR1cyI6InB1Ymxpc2gifSx7IklEIjoxMTc4LCJwb3N0X3RpdGxlIjoiTWFya3VwOiBIVE1MIFRhZ3MgYW5kIEZvcm1hdHRpbmciLCJwb3N0X25hbWUiOiJtYXJrdXAtaHRtbC10YWdzLWFuZC1mb3JtYXR0aW5nIiwicG9zdF9kYXRlIjoiMjAxMy0wMS0xMSAyMDoyMjoxOSIsInBvc3Rfc3RhdHVzIjoiZHJhZnQifV0KCSAqCgkgKiAgICAgIyBMaXN0IGFsbCBwYWdlcwoJICogICAgICQgd3AgcG9zdCBsaXN0IC0tcG9zdF90eXBlPXBhZ2UgLS1maWVsZHM9cG9zdF90aXRsZSxwb3N0X3N0YXR1cwoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBwb3N0X3RpdGxlICB8IHBvc3Rfc3RhdHVzIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgU2FtcGxlIFBhZ2UgfCBwdWJsaXNoICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBMaXN0IGlkcyBvZiBhbGwgcGFnZXMgYW5kIHBvc3RzCgkgKiAgICAgJCB3cCBwb3N0IGxpc3QgLS1wb3N0X3R5cGU9cGFnZSxwb3N0IC0tZm9ybWF0PWlkcwoJICogICAgIDE1IDI1IDM0IDM3IDE5OAoJICoKCSAqICAgICAjIExpc3QgZ2l2ZW4gcG9zdHMKCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLXBvc3RfX2luPTEsMwoJICogICAgICstLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBJRCB8IHBvc3RfdGl0bGUgICB8IHBvc3RfbmFtZSAgIHwgcG9zdF9kYXRlICAgICAgICAgICB8IHBvc3Rfc3RhdHVzIHwKCSAqICAgICArLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMyAgfCBMb3JlbSBJcHN1bSAgfCBsb3JlbS1pcHN1bSB8IDIwMTYtMDYtMDEgMTQ6MzQ6MzYgfCBwdWJsaXNoICAgICB8CgkgKiAgICAgfCAxICB8IEhlbGxvIHdvcmxkISB8IGhlbGxvLXdvcmxkIHwgMjAxNi0wNi0wMSAxNDozMToxMiB8IHB1Ymxpc2ggICAgIHwKCSAqICAgICArLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIExpc3QgZ2l2ZW4gcG9zdCBieSBhIHNwZWNpZmljIGF1dGhvcgoJICogICAgICQgd3AgcG9zdCBsaXN0IC0tYXV0aG9yPTIKCSAqICAgICArLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBJRCB8IHBvc3RfdGl0bGUgICAgICAgIHwgcG9zdF9uYW1lICAgICAgICAgfCBwb3N0X2RhdGUgICAgICAgICAgIHwgcG9zdF9zdGF0dXMgfAoJICogICAgICstLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IDE0IHwgTmV3IGRvY3VtZW50YXRpb24gfCBuZXctZG9jdW1lbnRhdGlvbiB8IDIwMjEtMDYtMTggMjE6MDU6MTEgfCBwdWJsaXNoICAgICB8CgkgKiAgICAgKy0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoKCQkkZGVmYXVsdHMgICA9IFsKCQkJJ3Bvc3RzX3Blcl9wYWdlJyA9PiAtMSwKCQkJJ3Bvc3Rfc3RhdHVzJyAgICA9PiAnYW55JywKCQldOwoJCSRxdWVyeV9hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCQkkcXVlcnlfYXJncyA9IHNlbGY6OnByb2Nlc3NfY3N2X2FyZ3VtZW50c190b19hcnJheXMoICRxdWVyeV9hcmdzICk7CgkJaWYgKCBpc3NldCggJHF1ZXJ5X2FyZ3NbJ3Bvc3RfdHlwZSddICkgJiYgJ2FueScgIT09ICRxdWVyeV9hcmdzWydwb3N0X3R5cGUnXSApIHsKCQkJJHF1ZXJ5X2FyZ3NbJ3Bvc3RfdHlwZSddID0gZXhwbG9kZSggJywnLCAkcXVlcnlfYXJnc1sncG9zdF90eXBlJ10gKTsKCQl9CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJHF1ZXJ5X2FyZ3NbJ2ZpZWxkcyddID0gJ2lkcyc7CgkJCSRxdWVyeSAgICAgICAgICAgICAgICA9IG5ldyBXUF9RdWVyeSggJHF1ZXJ5X2FyZ3MgKTsKCQkJZWNobyBpbXBsb2RlKCAnICcsICRxdWVyeS0+cG9zdHMgKTsKCQl9IGVsc2VpZiAoICdjb3VudCcgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJHF1ZXJ5X2FyZ3NbJ2ZpZWxkcyddID0gJ2lkcyc7CgkJCSRxdWVyeSAgICAgICAgICAgICAgICA9IG5ldyBXUF9RdWVyeSggJHF1ZXJ5X2FyZ3MgKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHF1ZXJ5LT5wb3N0cyApOwoJCX0gZWxzZSB7CgkJCSRxdWVyeSA9IG5ldyBXUF9RdWVyeSggJHF1ZXJ5X2FyZ3MgKTsKCQkJJHBvc3RzID0gYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24oICRwb3N0ICkgewoJCQkJCQkkcG9zdC0+dXJsID0gZ2V0X3Blcm1hbGluayggJHBvc3QtPklEICk7CgkJCQkJCXJldHVybiAkcG9zdDsKCQkJCX0sCgkJCQkkcXVlcnktPnBvc3RzCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRwb3N0cyApOwoJCX0KCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzb21lIHBvc3RzLgoJICoKCSAqIENyZWF0ZXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIG5ldyBwb3N0cyB3aXRoIGR1bW15IGRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWNvdW50PTxudW1iZXI+XQoJICogOiBIb3cgbWFueSBwb3N0cyB0byBnZW5lcmF0ZT8KCSAqIC0tLQoJICogZGVmYXVsdDogMTAwCgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3R5cGU9PHR5cGU+XQoJICogOiBUaGUgdHlwZSBvZiB0aGUgZ2VuZXJhdGVkIHBvc3RzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwb3N0CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3N0YXR1cz08c3RhdHVzPl0KCSAqIDogVGhlIHN0YXR1cyBvZiB0aGUgZ2VuZXJhdGVkIHBvc3RzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwdWJsaXNoCgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3RpdGxlPTxwb3N0X3RpdGxlPl0KCSAqIDogVGhlIHBvc3QgdGl0bGUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X2F1dGhvcj08bG9naW4+XQoJICogOiBUaGUgYXV0aG9yIG9mIHRoZSBnZW5lcmF0ZWQgcG9zdHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X2RhdGU9PHl5eXktbW0tZGQtaGgtaWktc3M+XQoJICogOiBUaGUgZGF0ZSBvZiB0aGUgZ2VuZXJhdGVkIHBvc3RzLiBEZWZhdWx0OiBjdXJyZW50IGRhdGUKCSAqCgkgKiBbLS1wb3N0X2RhdGVfZ210PTx5eXl5LW1tLWRkLWhoLWlpLXNzPl0KCSAqIDogVGhlIEdNVCBkYXRlIG9mIHRoZSBnZW5lcmF0ZWQgcG9zdHMuIERlZmF1bHQ6IHZhbHVlIG9mIHBvc3RfZGF0ZSAob3IgY3VycmVudCBkYXRlIGlmIGl0J3Mgbm90IHNldCkKCSAqCgkgKiBbLS1wb3N0X2NvbnRlbnRdCgkgKiA6IElmIHNldCwgdGhlIGNvbW1hbmQgcmVhZHMgdGhlIHBvc3RfY29udGVudCBmcm9tIFNURElOLgoJICoKCSAqIFstLW1heF9kZXB0aD08bnVtYmVyPl0KCSAqIDogRm9yIGhpZXJhcmNoaWNhbCBwb3N0IHR5cGVzLCBnZW5lcmF0ZSBjaGlsZCBwb3N0cyBkb3duIHRvIGEgY2VydGFpbiBkZXB0aC4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHByb2dyZXNzCgkgKiBvcHRpb25zOgoJICogICAtIHByb2dyZXNzCgkgKiAgIC0gaWRzCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdlbmVyYXRlIHBvc3RzLgoJICogICAgICQgd3AgcG9zdCBnZW5lcmF0ZSAtLWNvdW50PTEwIC0tcG9zdF90eXBlPXBhZ2UgLS1wb3N0X2RhdGU9MTk5OS0wMS0wNAoJICogICAgIEdlbmVyYXRpbmcgcG9zdHMgIDEwMCUgWz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PV0gMDowMSAvIDA6MDQKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBwb3N0cyB3aXRoIGZldGNoZWQgY29udGVudC4KCSAqICAgICAkIGN1cmwgLU4gaHR0cDovL2xvcmlwc3VtLm5ldC9hcGkvNSB8IHdwIHBvc3QgZ2VuZXJhdGUgLS1wb3N0X2NvbnRlbnQgLS1jb3VudD0xMAoJICogICAgICAgJSBUb3RhbCAgICAlIFJlY2VpdmVkICUgWGZlcmQgIEF2ZXJhZ2UgU3BlZWQgICBUaW1lICAgIFRpbWUgICAgIFRpbWUgIEN1cnJlbnQKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEbG9hZCAgVXBsb2FkICAgVG90YWwgICBTcGVudCAgICBMZWZ0ICBTcGVlZAoJICogICAgIDEwMCAgMjUwOSAgMTAwICAyNTA5ICAgIDAgICAgIDAgICAgNjE2ICAgICAgMCAgMDowMDowNCAgMDowMDowNCAtLTotLTotLSAgIDYxNgoJICogICAgIEdlbmVyYXRpbmcgcG9zdHMgIDEwMCUgWz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PV0gMDowMSAvIDA6MDQKCSAqCgkgKiAgICAgIyBBZGQgbWV0YSB0byBldmVyeSBnZW5lcmF0ZWQgcG9zdHMuCgkgKiAgICAgJCB3cCBwb3N0IGdlbmVyYXRlIC0tZm9ybWF0PWlkcyB8IHhhcmdzIC1kICcgJyAtSSAlIHdwIHBvc3QgbWV0YSBhZGQgJSBmb28gYmFyCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJGRlZmF1bHRzID0gWwoJCQknY291bnQnICAgICAgICAgPT4gMTAwLAoJCQknbWF4X2RlcHRoJyAgICAgPT4gMSwKCQkJJ3Bvc3RfdHlwZScgICAgID0+ICdwb3N0JywKCQkJJ3Bvc3Rfc3RhdHVzJyAgID0+ICdwdWJsaXNoJywKCQkJJ3Bvc3RfYXV0aG9yJyAgID0+IGZhbHNlLAoJCQkncG9zdF9kYXRlJyAgICAgPT4gZmFsc2UsCgkJCSdwb3N0X2RhdGVfZ210JyA9PiBmYWxzZSwKCQkJJ3Bvc3RfY29udGVudCcgID0+ICcnLAoJCQkncG9zdF90aXRsZScgICAgPT4gJycsCgkJXTsKCgkJJHBvc3RfZGF0YSA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSRjYWxsX3RpbWUgPSBjdXJyZW50X3RpbWUoICdteXNxbCcgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHBvc3RfZGF0YVsncG9zdF9kYXRlX2dtdCddICkgewoJCQkkcG9zdF9kYXRhWydwb3N0X2RhdGVfZ210J10gPSAkcG9zdF9kYXRhWydwb3N0X2RhdGUnXSA/OiAkY2FsbF90aW1lOwoJCX0KCgkJaWYgKCBmYWxzZSA9PT0gJHBvc3RfZGF0YVsncG9zdF9kYXRlJ10gKSB7CgkJCSRwb3N0X2RhdGFbJ3Bvc3RfZGF0ZSddID0gJHBvc3RfZGF0YVsncG9zdF9kYXRlX2dtdCddID86ICRjYWxsX3RpbWU7CgkJfQoKCQlpZiAoICEgcG9zdF90eXBlX2V4aXN0cyggJHBvc3RfZGF0YVsncG9zdF90eXBlJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIid7JHBvc3RfZGF0YVsncG9zdF90eXBlJ119JyBpcyBub3QgYSByZWdpc3RlcmVkIHBvc3QgdHlwZS4iICk7CgkJfQoKCQlpZiAoICRwb3N0X2RhdGFbJ3Bvc3RfYXV0aG9yJ10gKSB7CgkJCSR1c2VyX2ZldGNoZXIgICAgICAgICAgICAgPSBuZXcgVXNlckZldGNoZXIoKTsKCQkJJHBvc3RfZGF0YVsncG9zdF9hdXRob3InXSA9ICR1c2VyX2ZldGNoZXItPmdldF9jaGVjayggJHBvc3RfZGF0YVsncG9zdF9hdXRob3InXSApLT5JRDsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncG9zdF9jb250ZW50JyApICkgewoJCQlpZiAoICEgRW50aXR5VXRpbHM6Omhhc19zdGRpbigpICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RoZSBwYXJhbWV0ZXIgYHBvc3RfY29udGVudGAgcmVhZHMgZnJvbSBTVERJTi4nICk7CgkJCX0KCgkJCSRwb3N0X2RhdGFbJ3Bvc3RfY29udGVudCddID0gZmlsZV9nZXRfY29udGVudHMoICdwaHA6Ly9zdGRpbicgKTsKCQl9CgoJCS8vIEdldCB0aGUgdG90YWwgbnVtYmVyIG9mIHBvc3RzLgoJCSR0b3RhbCA9ICR3cGRiLT5nZXRfdmFyKCAkd3BkYi0+cHJlcGFyZSggIlNFTEVDVCBDT1VOVCgqKSBGUk9NICR3cGRiLT5wb3N0cyBXSEVSRSBwb3N0X3R5cGUgPSAlcyIsICRwb3N0X2RhdGFbJ3Bvc3RfdHlwZSddICkgKTsKCgkJJGxhYmVsID0gISBlbXB0eSggJHBvc3RfZGF0YVsncG9zdF90aXRsZSddICkKCQkJPyAkcG9zdF9kYXRhWydwb3N0X3RpdGxlJ10KCQkJOiBnZXRfcG9zdF90eXBlX29iamVjdCggJHBvc3RfZGF0YVsncG9zdF90eXBlJ10gKS0+bGFiZWxzLT5zaW5ndWxhcl9uYW1lOwoKCQkkaGllcmFyY2hpY2FsID0gZ2V0X3Bvc3RfdHlwZV9vYmplY3QoICRwb3N0X2RhdGFbJ3Bvc3RfdHlwZSddICktPmhpZXJhcmNoaWNhbDsKCgkJJGxpbWl0ID0gJHBvc3RfZGF0YVsnY291bnQnXSArICR0b3RhbDsKCgkJJGZvcm1hdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcsICdwcm9ncmVzcycgKTsKCgkJJG5vdGlmeSA9IGZhbHNlOwoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeSA9IFV0aWxzXG1ha2VfcHJvZ3Jlc3NfYmFyKCAnR2VuZXJhdGluZyBwb3N0cycsICRwb3N0X2RhdGFbJ2NvdW50J10gKTsKCQl9CgoJCSRwcmV2aW91c19wb3N0X2lkID0gMDsKCQkkY3VycmVudF9kZXB0aCAgICA9IDE7CgkJJGN1cnJlbnRfcGFyZW50ICAgPSAwOwoKCQlmb3IgKCAkaW5kZXggPSAkdG90YWw7ICRpbmRleCA8ICRsaW1pdDsgJGluZGV4KysgKSB7CgoJCQlpZiAoICRoaWVyYXJjaGljYWwgKSB7CgoJCQkJaWYgKCAkdGhpcy0+bWF5YmVfbWFrZV9jaGlsZCgpICYmICRjdXJyZW50X2RlcHRoIDwgJHBvc3RfZGF0YVsnbWF4X2RlcHRoJ10gKSB7CgoJCQkJCSRjdXJyZW50X3BhcmVudCA9ICRwcmV2aW91c19wb3N0X2lkOwoJCQkJCSRjdXJyZW50X2RlcHRoKys7CgoJCQkJfSBlbHNlaWYgKCAkdGhpcy0+bWF5YmVfcmVzZXRfZGVwdGgoKSApIHsKCgkJCQkJJGN1cnJlbnRfZGVwdGggID0gMTsKCQkJCQkkY3VycmVudF9wYXJlbnQgPSAwOwoKCQkJCX0KCQkJfQoKCQkJJGFyZ3MgPSBbCgkJCQkncG9zdF90eXBlJyAgICAgPT4gJHBvc3RfZGF0YVsncG9zdF90eXBlJ10sCgkJCQkncG9zdF90aXRsZScgICAgPT4gKCAhIGVtcHR5KCAkcG9zdF9kYXRhWydwb3N0X3RpdGxlJ10gKSAmJiAkaW5kZXggPT09ICR0b3RhbCApCgkJCQkJPyAkbGFiZWwKCQkJCQk6ICJ7JGxhYmVsfSB7JGluZGV4fSIsCgkJCQkncG9zdF9zdGF0dXMnICAgPT4gJHBvc3RfZGF0YVsncG9zdF9zdGF0dXMnXSwKCQkJCSdwb3N0X2F1dGhvcicgICA9PiAkcG9zdF9kYXRhWydwb3N0X2F1dGhvciddLAoJCQkJJ3Bvc3RfcGFyZW50JyAgID0+ICRjdXJyZW50X3BhcmVudCwKCQkJCSdwb3N0X25hbWUnICAgICA9PiAhIGVtcHR5KCAkcG9zdF9kYXRhWydwb3N0X3RpdGxlJ10gKQoJCQkJCT8gc2FuaXRpemVfdGl0bGUoICRwb3N0X2RhdGFbJ3Bvc3RfdGl0bGUnXSAuICggJGluZGV4ID09PSAkdG90YWwgPyAnJyA6ICIteyRpbmRleH0iICkgKQoJCQkJCTogInBvc3QteyRpbmRleH0iLAoJCQkJJ3Bvc3RfZGF0ZScgICAgID0+ICRwb3N0X2RhdGFbJ3Bvc3RfZGF0ZSddLAoJCQkJJ3Bvc3RfZGF0ZV9nbXQnID0+ICRwb3N0X2RhdGFbJ3Bvc3RfZGF0ZV9nbXQnXSwKCQkJCSdwb3N0X2NvbnRlbnQnICA9PiAkcG9zdF9kYXRhWydwb3N0X2NvbnRlbnQnXSwKCQkJXTsKCgkJCSRwb3N0X2lkID0gd3BfaW5zZXJ0X3Bvc3QoICRhcmdzLCB0cnVlICk7CgkJCWlmICggaXNfd3BfZXJyb3IoICRwb3N0X2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRwb3N0X2lkICk7CgkJCX0gZWxzZSB7CgkJCQkkcHJldmlvdXNfcG9zdF9pZCA9ICRwb3N0X2lkOwoJCQkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdCApIHsKCQkJCQllY2hvICRwb3N0X2lkOwoJCQkJCWlmICggJGluZGV4IDwgJGxpbWl0IC0gMSApIHsKCQkJCQkJZWNobyAnICc7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCQkkbm90aWZ5LT50aWNrKCk7CgkJCX0KCQl9CgkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkkbm90aWZ5LT5maW5pc2goKTsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtYXliZV9tYWtlX2NoaWxkKCkgewoJCS8vIDUwJSBjaGFuY2Ugb2YgbWFraW5nIGNoaWxkIHBvc3QuCgkJcmV0dXJuICggd3BfcmFuZCggMSwgMiApID09PSAxICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtYXliZV9yZXNldF9kZXB0aCgpIHsKCQkvLyAxMCUgY2hhbmNlIG9mIHJlc2V0aW5nIHRvIHJvb3QgZGVwdGgsCgkJcmV0dXJuICggd3BfcmFuZCggMSwgMTAgKSA9PT0gNyApOwoJfQoKCS8qKgoJICogUmVhZCBwb3N0IGNvbnRlbnQgZnJvbSBmaWxlIG9yIFNURElOCgkgKgoJICogQHBhcmFtIHN0cmluZyAkYXJnIFN1cHBsaWVkIGFyZ3VtZW50CgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlYWRfZnJvbV9maWxlX29yX3N0ZGluKCAkYXJnICkgewoJCWlmICggJy0nICE9PSAkYXJnICkgewoJCQkkcmVhZGZpbGUgPSAkYXJnOwoJCQlpZiAoICEgZmlsZV9leGlzdHMoICRyZWFkZmlsZSApIHx8ICEgaXNfZmlsZSggJHJlYWRmaWxlICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiVW5hYmxlIHRvIHJlYWQgY29udGVudCBmcm9tICd7JHJlYWRmaWxlfScuIiApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHJlYWRmaWxlID0gJ3BocDovL3N0ZGluJzsKCQl9CgkJcmV0dXJuIGZpbGVfZ2V0X2NvbnRlbnRzKCAkcmVhZGZpbGUgKTsKCX0KCgkvKioKCSAqIFJlc29sdmVzIHBvc3RfY2F0ZWdvcnkgYXJnIGludG8gYW4gYXJyYXkgb2YgY2F0ZWdvcnkgaWRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGFyZyBTdXBwbGllZCBhcmd1bWVudC4KCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY2F0ZWdvcnlfaWRzKCAkYXJnICkgewoKCQkkY2F0ZWdvcmllcyAgID0gZXhwbG9kZSggJywnLCAkYXJnICk7CgkJJGNhdGVnb3J5X2lkcyA9IFtdOwoJCWZvcmVhY2ggKCAkY2F0ZWdvcmllcyBhcyAkcG9zdF9jYXRlZ29yeSApIHsKCQkJaWYgKCB0cmltKCAkcG9zdF9jYXRlZ29yeSApICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAkcG9zdF9jYXRlZ29yeSApICYmIChpbnQpICRwb3N0X2NhdGVnb3J5ICkgewoJCQkJCSRjYXRlZ29yeV9pZCA9IGNhdGVnb3J5X2V4aXN0cyggKGludCkgJHBvc3RfY2F0ZWdvcnkgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJGNhdGVnb3J5X2lkID0gY2F0ZWdvcnlfZXhpc3RzKCAkcG9zdF9jYXRlZ29yeSApOwoJCQkJfQoJCQkJaWYgKCAhICRjYXRlZ29yeV9pZCApIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAiTm8gc3VjaCBwb3N0IGNhdGVnb3J5ICd7JHBvc3RfY2F0ZWdvcnl9Jy4iICk7CgkJCQl9CgkJCQkkY2F0ZWdvcnlfaWRzW10gPSAkY2F0ZWdvcnlfaWQ7CgkJCX0KCQl9CgkJLy8gSWYgbm8gY2F0ZWdvcnkgaWRzIGZvdW5kLCByZXR1cm4gZXhwbG9kZWQgYXJyYXkgZm9yIGNvbXBhdCB3aXRoIHByZXZpb3VzIFdQLUNMSSB2ZXJzaW9ucy4KCQlyZXR1cm4gJGNhdGVnb3J5X2lkcyA/OiAkY2F0ZWdvcmllczsKCX0KCgkvKioKCSAqIEdldCBwb3N0IG1ldGFkYXRhLgoJICoKCSAqIEBwYXJhbSAkcG9zdF9pZCBJRCBvZiB0aGUgcG9zdC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X21ldGFkYXRhKCAkcG9zdF9pZCApIHsKCQkkbWV0YWRhdGEgPSBnZXRfbWV0YWRhdGEoICdwb3N0JywgJHBvc3RfaWQgKTsKCQkkaXRlbXMgICAgPSBbXTsKCQlmb3JlYWNoICggJG1ldGFkYXRhIGFzICRrZXkgPT4gJHZhbHVlcyApIHsKCQkJZm9yZWFjaCAoICR2YWx1ZXMgYXMgJGl0ZW1fdmFsdWUgKSB7CgkJCQkkaXRlbV92YWx1ZSAgICA9IG1heWJlX3Vuc2VyaWFsaXplKCAkaXRlbV92YWx1ZSApOwoJCQkJJGl0ZW1zWyAka2V5IF0gPSAkaXRlbV92YWx1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuICRpdGVtczsKCX0KCgkvKioKCSAqIEdldCBDYXRlZ29yaWVzIG9mIGEgcG9zdC4KCSAqCgkgKiBAcGFyYW0gJHBvc3RfaWQgSUQgb2YgdGhlIHBvc3QuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jYXRlZ29yeSggJHBvc3RfaWQgKSB7CgkJJGNhdGVnb3J5X2RhdGEgPSBnZXRfdGhlX2NhdGVnb3J5KCAkcG9zdF9pZCApOwoJCSRjYXRlZ29yeV9hcnIgID0gW107CgkJZm9yZWFjaCAoICRjYXRlZ29yeV9kYXRhIGFzICRjYXQgKSB7CgkJCWFycmF5X3B1c2goICRjYXRlZ29yeV9hcnIsICRjYXQtPnRlcm1faWQgKTsKCQl9CgoJCXJldHVybiAkY2F0ZWdvcnlfYXJyOwoJfQoKCS8qKgoJICogR2V0IFRhZ3Mgb2YgYSBwb3N0LgoJICoKCSAqIEBwYXJhbSAkcG9zdF9pZCBJRCBvZiB0aGUgcG9zdC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3RhZ3MoICRwb3N0X2lkICkgewoJCSR0YWdfZGF0YSA9IGdldF90aGVfdGFncyggJHBvc3RfaWQgKTsKCQkkdGFnX2FyciAgPSBbXTsKCQlpZiAoICR0YWdfZGF0YSApIHsKCQkJZm9yZWFjaCAoICR0YWdfZGF0YSBhcyAkdGFnICkgewoJCQkJYXJyYXlfcHVzaCggJHRhZ19hcnIsICR0YWctPnNsdWcgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICR0YWdfYXJyOwoJfQoKCS8qKgoJICogVmVyaWZpZXMgd2hldGhlciBhIHBvc3QgZXhpc3RzLgoJICoKCSAqIERpc3BsYXlzIGEgc3VjY2VzcyBtZXNzYWdlIGlmIHRoZSBwb3N0IGRvZXMgZXhpc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBwb3N0IHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVGhlIHBvc3QgZXhpc3RzLgoJICogICAgICQgd3AgcG9zdCBleGlzdHMgMTMzNwoJICogICAgIFN1Y2Nlc3M6IFBvc3Qgd2l0aCBJRCAxMzM3IGV4aXN0cy4KCSAqICAgICAkIGVjaG8gJD8KCSAqICAgICAwCgkgKgoJICogICAgICMgVGhlIHBvc3QgZG9lcyBub3QgZXhpc3QuCgkgKiAgICAgJCB3cCBwb3N0IGV4aXN0cyAxMDAwMAoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4aXN0cyggJGFyZ3MgKSB7CgkJaWYgKCAkdGhpcy0+ZmV0Y2hlci0+Z2V0KCAkYXJnc1swXSApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJQb3N0IHdpdGggSUQgeyRhcmdzWzBdfSBleGlzdHMuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aE1ldGE7CnVzZSBXUF9DTElcRmV0Y2hlcnNcQ29tbWVudCBhcyBDb21tZW50RmV0Y2hlcjsKCi8qKgogKiBBZGRzLCB1cGRhdGVzLCBkZWxldGVzLCBhbmQgbGlzdHMgY29tbWVudCBjdXN0b20gZmllbGRzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBTZXQgY29tbWVudCBtZXRhCiAqICAgICAkIHdwIGNvbW1lbnQgbWV0YSBzZXQgMTIzIGRlc2NyaXB0aW9uICJNYXJ5IGlzIGEgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnZGVzY3JpcHRpb24nLgogKgogKiAgICAgIyBHZXQgY29tbWVudCBtZXRhCiAqICAgICAkIHdwIGNvbW1lbnQgbWV0YSBnZXQgMTIzIGRlc2NyaXB0aW9uCiAqICAgICBNYXJ5IGlzIGEgV29yZFByZXNzIGRldmVsb3Blci4KICoKICogICAgICMgVXBkYXRlIGNvbW1lbnQgbWV0YQogKiAgICAgJCB3cCBjb21tZW50IG1ldGEgdXBkYXRlIDEyMyBkZXNjcmlwdGlvbiAiTWFyeSBpcyBhbiBhd2Vzb21lIFdvcmRQcmVzcyBkZXZlbG9wZXIuIgogKiAgICAgU3VjY2VzczogVXBkYXRlZCBjdXN0b20gZmllbGQgJ2Rlc2NyaXB0aW9uJy4KICoKICogICAgICMgRGVsZXRlIGNvbW1lbnQgbWV0YQogKiAgICAgJCB3cCBjb21tZW50IG1ldGEgZGVsZXRlIDEyMyBkZXNjcmlwdGlvbgogKiAgICAgU3VjY2VzczogRGVsZXRlZCBjdXN0b20gZmllbGQuCiAqLwpjbGFzcyBDb21tZW50X01ldGFfQ29tbWFuZCBleHRlbmRzIENvbW1hbmRXaXRoTWV0YSB7Cglwcm90ZWN0ZWQgJG1ldGFfdHlwZSA9ICdjb21tZW50JzsKCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBhZGRfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gYm9vbCAgICR1bmlxdWUgICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBXaGV0aGVyIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbWV0YWRhdGEga2V5IHNob3VsZCBiZSB1bmlxdWUgZm9yIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuIElmIHRydWUsIGFuZCB0aGUgb2JqZWN0IGFscmVhZHkgaGFzIGEKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgbWV0YWRhdGEga2V5LCBubyBjaGFuZ2UKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBtYWRlLgoJICoKCSAqIEByZXR1cm4gaW50fGZhbHNlIFRoZSBtZXRhIElEIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBhZGRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgPSBmYWxzZSApIHsKCQlyZXR1cm4gYWRkX2NvbW1lbnRfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIHVwZGF0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBtaXhlZCAgJHByZXZfdmFsdWUgT3B0aW9uYWwuIElmIHNwZWNpZmllZCwgb25seSB1cGRhdGUgZXhpc3RpbmcKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgZW50cmllcyB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIE90aGVyd2lzZSwgdXBkYXRlIGFsbCBlbnRyaWVzLgoJICoKCSAqIEByZXR1cm4gaW50fGJvb2wgTWV0YSBJRCBpZiB0aGUga2V5IGRpZG4ndCBleGlzdCwgdHJ1ZSBvbiBzdWNjZXNzZnVsCgkgKiAgICAgICAgICAgICAgICAgIHVwZGF0ZSwgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHByZXZfdmFsdWUgPSAnJyApIHsKCQlyZXR1cm4gdXBkYXRlX2NvbW1lbnRfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHByZXZfdmFsdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBnZXRfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgIE9wdGlvbmFsLiBNZXRhZGF0YSBrZXkuIElmIG5vdCBzcGVjaWZpZWQsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0cmlldmUgYWxsIG1ldGFkYXRhIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdC4KCSAqIEBwYXJhbSBib29sICAgJHNpbmdsZSAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gSWYgdHJ1ZSwgcmV0dXJuIG9ubHkKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZmlyc3QgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBtZXRhX2tleS4gVGhpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IGlmIG1ldGFfa2V5IGlzIG5vdAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZC4KCSAqCgkgKiBAcmV0dXJuIG1peGVkIFNpbmdsZSBtZXRhZGF0YSB2YWx1ZSwgb3IgYXJyYXkgb2YgdmFsdWVzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXkgPSAnJywgJHNpbmdsZSA9IGZhbHNlICkgewoJCXJldHVybiBnZXRfY29tbWVudF9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRzaW5nbGUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBkZWxldGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgbWV0YWRhdGEgaXMgZm9yCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleQoJICogQHBhcmFtIG1peGVkICRtZXRhX3ZhbHVlICBPcHRpb25hbC4gTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vbi1zY2FsYXIuIElmIHNwZWNpZmllZCwgb25seSBkZWxldGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgZW50cmllcyB3aXRoIHRoaXMgdmFsdWUuIE90aGVyd2lzZSwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGFsbCBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCBtZXRhX2tleS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFzcyBgbnVsbCwgYGZhbHNlYCwgb3IgYW4gZW1wdHkgc3RyaW5nIHRvIHNraXAKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBjaGVjay4gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIGl0IGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBwb3NzaWJsZSB0byBwYXNzIGFuIGVtcHR5IHN0cmluZyB0byBkZWxldGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhvc2UgZW50cmllcyB3aXRoIGFuIGVtcHR5IHN0cmluZyBmb3IgYSB2YWx1ZS4KCSAqCgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBvbiBzdWNjZXNzZnVsIGRlbGV0ZSwgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGRlbGV0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSA9ICcnICkgewoJCXJldHVybiBkZWxldGVfY29tbWVudF9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlICk7Cgl9CgoJLyoqCgkgKiBDaGVjayB0aGF0IHRoZSBjb21tZW50IElEIGV4aXN0cwoJICoKCSAqIEBwYXJhbSBpbnQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApIHsKCQkkZmV0Y2hlciA9IG5ldyBDb21tZW50RmV0Y2hlcigpOwoJCSRjb21tZW50ID0gJGZldGNoZXItPmdldF9jaGVjayggJG9iamVjdF9pZCApOwoJCXJldHVybiAkY29tbWVudC0+Y29tbWVudF9JRDsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aERCT2JqZWN0Owp1c2UgV1BfQ0xJXEZldGNoZXJzXENvbW1lbnQgYXMgQ29tbWVudEZldGNoZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQ3JlYXRlcywgdXBkYXRlcywgZGVsZXRlcywgYW5kIG1vZGVyYXRlcyBjb21tZW50cy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgQ3JlYXRlIGEgbmV3IGNvbW1lbnQuCiAqICAgICAkIHdwIGNvbW1lbnQgY3JlYXRlIC0tY29tbWVudF9wb3N0X0lEPTE1IC0tY29tbWVudF9jb250ZW50PSJoZWxsbyBibG9nIiAtLWNvbW1lbnRfYXV0aG9yPSJ3cC1jbGkiCiAqICAgICBTdWNjZXNzOiBDcmVhdGVkIGNvbW1lbnQgOTMyLgogKgogKiAgICAgIyBVcGRhdGUgYW4gZXhpc3RpbmcgY29tbWVudC4KICogICAgICQgd3AgY29tbWVudCB1cGRhdGUgMTIzIC0tY29tbWVudF9hdXRob3I9J1RoYXQgR3V5JwogKiAgICAgU3VjY2VzczogVXBkYXRlZCBjb21tZW50IDEyMy4KICoKICogICAgICMgRGVsZXRlIGFuIGV4aXN0aW5nIGNvbW1lbnQuCiAqICAgICAkIHdwIGNvbW1lbnQgZGVsZXRlIDEzMzcgLS1mb3JjZQogKiAgICAgU3VjY2VzczogRGVsZXRlZCBjb21tZW50IDEzMzcuCiAqCiAqICAgICAjIERlbGV0ZSBhbGwgc3BhbSBjb21tZW50cy4KICogICAgICQgd3AgY29tbWVudCBkZWxldGUgJCh3cCBjb21tZW50IGxpc3QgLS1zdGF0dXM9c3BhbSAtLWZvcm1hdD1pZHMpCiAqICAgICBTdWNjZXNzOiBEZWxldGVkIGNvbW1lbnQgMjY0LgogKiAgICAgU3VjY2VzczogRGVsZXRlZCBjb21tZW50IDI2Mi4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBDb21tZW50X0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aERCT2JqZWN0IHsKCglwcm90ZWN0ZWQgJG9ial90eXBlICAgPSAnY29tbWVudCc7Cglwcm90ZWN0ZWQgJG9ial9pZF9rZXkgPSAnY29tbWVudF9JRCc7Cglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBbCgkJJ2NvbW1lbnRfSUQnLAoJCSdjb21tZW50X3Bvc3RfSUQnLAoJCSdjb21tZW50X2RhdGUnLAoJCSdjb21tZW50X2FwcHJvdmVkJywKCQknY29tbWVudF9hdXRob3InLAoJCSdjb21tZW50X2F1dGhvcl9lbWFpbCcsCgldOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQkkdGhpcy0+ZmV0Y2hlciA9IG5ldyBDb21tZW50RmV0Y2hlcigpOwoJfQoKCS8qKgoJICogQ3JlYXRlcyBhIG5ldyBjb21tZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEFzc29jaWF0aXZlIGFyZ3MgZm9yIHRoZSBuZXcgY29tbWVudC4gU2VlIHdwX2luc2VydF9jb21tZW50KCkuCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBPdXRwdXQganVzdCB0aGUgbmV3IGNvbW1lbnQgaWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDcmVhdGUgY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgY3JlYXRlIC0tY29tbWVudF9wb3N0X0lEPTE1IC0tY29tbWVudF9jb250ZW50PSJoZWxsbyBibG9nIiAtLWNvbW1lbnRfYXV0aG9yPSJ3cC1jbGkiCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCBjb21tZW50IDkzMi4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhc3NvY19hcmdzID0gd3Bfc2xhc2goICRhc3NvY19hcmdzICk7CgkJcGFyZW50OjpfY3JlYXRlKAoJCQkkYXJncywKCQkJJGFzc29jX2FyZ3MsCgkJCWZ1bmN0aW9uICggJHBhcmFtcyApIHsKCQkJCWlmICggaXNzZXQoICRwYXJhbXNbJ2NvbW1lbnRfcG9zdF9JRCddICkgKSB7CgkJCQkJJHBvc3RfaWQgPSAkcGFyYW1zWydjb21tZW50X3Bvc3RfSUQnXTsKCQkJCQkkcG9zdCAgICA9IGdldF9wb3N0KCAkcG9zdF9pZCApOwoJCQkJCWlmICggISAkcG9zdCApIHsKCQkJCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ25vX3Bvc3QnLCAiQ2FuJ3QgZmluZCBwb3N0IHskcG9zdF9pZH0uIiApOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJLy8gTWFrZSBzdXJlIGl0J3Mgc2V0IGZvciBvbGRlciBXUCB2ZXJzaW9ucyBlbHNlIGdldCB1bmRlZmluZWQgUEhQIG5vdGljZS4KCQkJCQkkcGFyYW1zWydjb21tZW50X3Bvc3RfSUQnXSA9IDA7CgkJCQl9CgoJCQkJLy8gV2UgdXNlIHdwX2luc2VydF9jb21tZW50KCkgaW5zdGVhZCBvZiB3cF9uZXdfY29tbWVudCgpIHRvIHN0YXkgYXQgYSBsb3cgbGV2ZWwgYW5kCgkJCQkvLyBhdm9pZCB3cF9kaWUoKSBmb3JtYXR0ZWQgbWVzc2FnZXMgb3Igbm90aWZpY2F0aW9ucwoJCQkJJGNvbW1lbnRfaWQgPSB3cF9pbnNlcnRfY29tbWVudCggJHBhcmFtcyApOwoKCQkJCWlmICggISAkY29tbWVudF9pZCApIHsKCQkJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnZGJfZXJyb3InLCAnQ291bGQgbm90IGNyZWF0ZSBjb21tZW50LicgKTsKCQkJCX0KCgkJCQlyZXR1cm4gJGNvbW1lbnRfaWQ7CgkJCX0KCQkpOwoJfQoKCS8qKgoJICogVXBkYXRlcyBvbmUgb3IgbW9yZSBjb21tZW50cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2YgY29tbWVudHMgdG8gdXBkYXRlLgoJICoKCSAqIC0tPGZpZWxkPj08dmFsdWU+CgkgKiA6IE9uZSBvciBtb3JlIGZpZWxkcyB0byB1cGRhdGUuIFNlZSB3cF91cGRhdGVfY29tbWVudCgpLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVXBkYXRlIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IHVwZGF0ZSAxMjMgLS1jb21tZW50X2F1dGhvcj0nVGhhdCBHdXknCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBjb21tZW50IDEyMy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhc3NvY19hcmdzID0gd3Bfc2xhc2goICRhc3NvY19hcmdzICk7CgkJcGFyZW50OjpfdXBkYXRlKAoJCQkkYXJncywKCQkJJGFzc29jX2FyZ3MsCgkJCWZ1bmN0aW9uICggJHBhcmFtcyApIHsKCQkJCWlmICggISB3cF91cGRhdGVfY29tbWVudCggJHBhcmFtcyApICkgewoJCQkJCXJldHVybiBuZXcgV1BfRXJyb3IoICdDb3VsZCBub3QgdXBkYXRlIGNvbW1lbnQuJyApOwoJCQkJfQoKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzb21lIG51bWJlciBvZiBuZXcgZHVtbXkgY29tbWVudHMuCgkgKgoJICogQ3JlYXRlcyBhIHNwZWNpZmllZCBudW1iZXIgb2YgbmV3IGNvbW1lbnRzIHdpdGggZHVtbXkgZGF0YS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tY291bnQ9PG51bWJlcj5dCgkgKiA6IEhvdyBtYW55IGNvbW1lbnRzIHRvIGdlbmVyYXRlPwoJICogLS0tCgkgKiBkZWZhdWx0OiAxMDAKCSAqIC0tLQoJICoKCSAqIFstLXBvc3RfaWQ9PHBvc3QtaWQ+XQoJICogOiBBc3NpZ24gY29tbWVudHMgdG8gYSBzcGVjaWZpYyBwb3N0LgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiBwcm9ncmVzcwoJICogb3B0aW9uczoKCSAqICAgLSBwcm9ncmVzcwoJICogICAtIGlkcwoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBjb21tZW50cyBmb3IgdGhlIGdpdmVuIHBvc3QuCgkgKiAgICAgJCB3cCBjb21tZW50IGdlbmVyYXRlIC0tZm9ybWF0PWlkcyAtLWNvdW50PTMgLS1wb3N0X2lkPTEyMwoJICogICAgIDEzOCAxMzkgMTQwCgkgKgoJICogICAgICMgQWRkIG1ldGEgdG8gZXZlcnkgZ2VuZXJhdGVkIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IGdlbmVyYXRlIC0tZm9ybWF0PWlkcyAtLWNvdW50PTMgfCB4YXJncyAtZCAnICcgLUkgJSB3cCBjb21tZW50IG1ldGEgYWRkICUgZm9vIGJhcgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2VuZXJhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdjb3VudCcgICA9PiAxMDAsCgkJCSdwb3N0X2lkJyA9PiAwLAoJCV07CgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoKCQkkZm9ybWF0ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JywgJ3Byb2dyZXNzJyApOwoKCQkkbm90aWZ5ID0gZmFsc2U7CgkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkkbm90aWZ5ID0gVXRpbHNcbWFrZV9wcm9ncmVzc19iYXIoICdHZW5lcmF0aW5nIGNvbW1lbnRzJywgJGFzc29jX2FyZ3NbJ2NvdW50J10gKTsKCQl9CgoJCSRjb21tZW50X2NvdW50ID0gd3BfY291bnRfY29tbWVudHMoKTsKCQkkdG90YWwgICAgICAgICA9IChpbnQpICRjb21tZW50X2NvdW50LT50b3RhbF9jb21tZW50czsKCQkkbGltaXQgICAgICAgICA9ICR0b3RhbCArICRhc3NvY19hcmdzWydjb3VudCddOwoKCQlmb3IgKCAkaW5kZXggPSAkdG90YWw7ICRpbmRleCA8ICRsaW1pdDsgJGluZGV4KysgKSB7CgkJCSRjb21tZW50X2lkID0gd3BfaW5zZXJ0X2NvbW1lbnQoCgkJCQlbCgkJCQkJJ2NvbW1lbnRfY29udGVudCcgPT4gIkNvbW1lbnQgeyRpbmRleH0iLAoJCQkJCSdjb21tZW50X3Bvc3RfSUQnID0+ICRhc3NvY19hcmdzWydwb3N0X2lkJ10sCgkJCQldCgkJCSk7CgkJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJCSRub3RpZnktPnRpY2soKTsKCQkJfSBlbHNlaWYgKCAnaWRzJyA9PT0gJGZvcm1hdCApIHsKCQkJCWVjaG8gJGNvbW1lbnRfaWQ7CgkJCQlpZiAoICRpbmRleCA8ICRsaW1pdCAtIDEgKSB7CgkJCQkJZWNobyAnICc7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeS0+ZmluaXNoKCk7CgkJfQoKCX0KCgkvKioKCSAqIEdldHMgdGhlIGRhdGEgb2YgYSBzaW5nbGUgY29tbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPgoJICogOiBUaGUgY29tbWVudCB0byBnZXQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogSW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIHdob2xlIGNvbW1lbnQsIHJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuIERlZmF1bHRzIHRvIGFsbCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IGdldCAyMSAtLWZpZWxkPWNvbnRlbnQKCSAqICAgICBUaGFua3MgZm9yIGFsbCB0aGUgY29tbWVudHMsIGV2ZXJ5b25lIQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGNvbW1lbnRfaWQgPSAoaW50KSAkYXJnc1swXTsKCQkkY29tbWVudCAgICA9IGdldF9jb21tZW50KCAkY29tbWVudF9pZCApOwoJCWlmICggZW1wdHkoICRjb21tZW50ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIGNvbW1lbnQgSUQuJyApOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRjb21tZW50X2FycmF5ICAgICAgICA9IGdldF9vYmplY3RfdmFycyggJGNvbW1lbnQgKTsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gYXJyYXlfa2V5cyggJGNvbW1lbnRfYXJyYXkgKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICRjb21tZW50ICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgbGlzdCBvZiBjb21tZW50cy4KCSAqCgkgKiBEaXNwbGF5IGNvbW1lbnRzIGJhc2VkIG9uIGFsbCBhcmd1bWVudHMgc3VwcG9ydGVkIGJ5CgkgKiBbV1BfQ29tbWVudF9RdWVyeSgpXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3JlZmVyZW5jZS9jbGFzc2VzL1dQX0NvbW1lbnRfUXVlcnkvX19jb25zdHJ1Y3QvKS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBPbmUgb3IgbW9yZSBhcmdzIHRvIHBhc3MgdG8gV1BfQ29tbWVudF9RdWVyeS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIGNvbW1lbnQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gaWRzCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIGNvbW1lbnQ6CgkgKgoJICogKiBjb21tZW50X0lECgkgKiAqIGNvbW1lbnRfcG9zdF9JRAoJICogKiBjb21tZW50X2RhdGUKCSAqICogY29tbWVudF9hcHByb3ZlZAoJICogKiBjb21tZW50X2F1dGhvcgoJICogKiBjb21tZW50X2F1dGhvcl9lbWFpbAoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjb21tZW50X2F1dGhvcl91cmwKCSAqICogY29tbWVudF9hdXRob3JfSVAKCSAqICogY29tbWVudF9kYXRlX2dtdAoJICogKiBjb21tZW50X2NvbnRlbnQKCSAqICogY29tbWVudF9rYXJtYQoJICogKiBjb21tZW50X2FnZW50CgkgKiAqIGNvbW1lbnRfdHlwZQoJICogKiBjb21tZW50X3BhcmVudAoJICogKiB1c2VyX2lkCgkgKiAqIHVybAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBjb21tZW50IElEcy4KCSAqICAgICAkIHdwIGNvbW1lbnQgbGlzdCAtLWZpZWxkPUlECgkgKiAgICAgMjIKCSAqICAgICAyMwoJICogICAgIDI0CgkgKgoJICogICAgICMgTGlzdCBjb21tZW50cyBvZiBhIHBvc3QuCgkgKiAgICAgJCB3cCBjb21tZW50IGxpc3QgLS1wb3N0X2lkPTEgLS1maWVsZHM9SUQsY29tbWVudF9kYXRlLGNvbW1lbnRfYXV0aG9yCgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGNvbW1lbnRfSUQgfCBjb21tZW50X2RhdGUgICAgICAgIHwgY29tbWVudF9hdXRob3IgfAoJICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCAxICAgICAgICAgIHwgMjAxNS0wNi0yMCAwOTowMDoxMCB8IE1yIFdvcmRQcmVzcyAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIExpc3QgYXBwcm92ZWQgY29tbWVudHMuCgkgKiAgICAgJCB3cCBjb21tZW50IGxpc3QgLS1udW1iZXI9MyAtLXN0YXR1cz1hcHByb3ZlIC0tZmllbGRzPUlELGNvbW1lbnRfZGF0ZSxjb21tZW50X2F1dGhvcgoJICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBjb21tZW50X0lEIHwgY29tbWVudF9kYXRlICAgICAgICB8IGNvbW1lbnRfYXV0aG9yIHwKCSAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMSAgICAgICAgICB8IDIwMTUtMDYtMjAgMDk6MDA6MTAgfCBNciBXb3JkUHJlc3MgICB8CgkgKiAgICAgfCAzMCAgICAgICAgIHwgMjAxMy0wMy0xNCAxMjozNTowNyB8IEpvaG4gRG9lICAgICAgIHwKCSAqICAgICB8IDI5ICAgICAgICAgfCAyMDEzLTAzLTE0IDExOjU2OjA4IHwgSmFuZSBEb2UgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJ2NvbW1lbnRfSUQnOwoJCX0KCgkJJGFzc29jX2FyZ3MgPSBzZWxmOjpwcm9jZXNzX2Nzdl9hcmd1bWVudHNfdG9fYXJyYXlzKCAkYXNzb2NfYXJncyApOwoKCQlpZiAoICdjb3VudCcgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJGFzc29jX2FyZ3NbJ2NvdW50J10gPSB0cnVlOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snY29tbWVudF9faW4nXSApCgkJCSYmICEgZW1wdHkoICRhc3NvY19hcmdzWydvcmRlcmJ5J10gKQoJCQkmJiAnY29tbWVudF9faW4nID09PSAkYXNzb2NfYXJnc1snb3JkZXJieSddCgkJCSYmIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuNCcsICc8JyApICkgewoJCQkkY29tbWVudHMgPSBbXTsKCQkJZm9yZWFjaCAoICRhc3NvY19hcmdzWydjb21tZW50X19pbiddIGFzICRjb21tZW50X2lkICkgewoJCQkJJGNvbW1lbnQgPSBnZXRfY29tbWVudCggJGNvbW1lbnRfaWQgKTsKCQkJCWlmICggJGNvbW1lbnQgKSB7CgkJCQkJJGNvbW1lbnRzW10gPSAkY29tbWVudDsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiSW52YWxpZCBjb21tZW50IHskY29tbWVudF9pZH0uIiApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJJHF1ZXJ5ICAgID0gbmV3IFdQX0NvbW1lbnRfUXVlcnkoKTsKCQkJJGNvbW1lbnRzID0gJHF1ZXJ5LT5xdWVyeSggJGFzc29jX2FyZ3MgKTsKCQl9CgoJCWlmICggJ2NvdW50JyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQllY2hvICRjb21tZW50czsKCQl9IGVsc2UgewoJCQlpZiAoICdpZHMnID09PSAkZm9ybWF0dGVyLT5mb3JtYXQgKSB7CgkJCQkkY29tbWVudHMgPSB3cF9saXN0X3BsdWNrKCAkY29tbWVudHMsICdjb21tZW50X0lEJyApOwoJCQl9IGVsc2VpZiAoIGlzX2FycmF5KCAkY29tbWVudHMgKSApIHsKCQkJCSRjb21tZW50cyA9IGFycmF5X21hcCgKCQkJCQlmdW5jdGlvbiggJGNvbW1lbnQgKSB7CgkJCQkJCQkkY29tbWVudC0+dXJsID0gZ2V0X2NvbW1lbnRfbGluayggJGNvbW1lbnQtPmNvbW1lbnRfSUQgKTsKCQkJCQkJCXJldHVybiAkY29tbWVudDsKCQkJCQl9LAoJCQkJCSRjb21tZW50cwoJCQkJKTsKCQkJfQoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkY29tbWVudHMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGVzIGEgY29tbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2YgY29tbWVudHMgdG8gZGVsZXRlLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBTa2lwIHRoZSB0cmFzaCBiaW4uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWxldGUgY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgZGVsZXRlIDEzMzcgLS1mb3JjZQoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY29tbWVudCAxMzM3LgoJICoKCSAqICAgICAjIERlbGV0ZSBtdWx0aXBsZSBjb21tZW50cy4KCSAqICAgICAkIHdwIGNvbW1lbnQgZGVsZXRlIDEzMzcgMjM0MSAtLWZvcmNlCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCBjb21tZW50IDEzMzcuCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCBjb21tZW50IDIzNDEuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlwYXJlbnQ6Ol9kZWxldGUoCgkJCSRhcmdzLAoJCQkkYXNzb2NfYXJncywKCQkJZnVuY3Rpb24gKCAkY29tbWVudF9pZCwgJGFzc29jX2FyZ3MgKSB7CgkJCQkkZm9yY2UgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKTsKCgkJCQkkc3RhdHVzID0gd3BfZ2V0X2NvbW1lbnRfc3RhdHVzKCAkY29tbWVudF9pZCApOwoJCQkJJHJlc3VsdCA9IHdwX2RlbGV0ZV9jb21tZW50KCAkY29tbWVudF9pZCwgJGZvcmNlICk7CgoJCQkJaWYgKCAhICRyZXN1bHQgKSB7CgkJCQkJcmV0dXJuIFsgJ2Vycm9yJywgIkZhaWxlZCBkZWxldGluZyBjb21tZW50IHskY29tbWVudF9pZH0uIiBdOwoJCQkJfQoKCQkJCSR2ZXJiID0gKCAkZm9yY2UgfHwgJ3RyYXNoJyA9PT0gJHN0YXR1cyApID8gJ0RlbGV0ZWQnIDogJ1RyYXNoZWQnOwoJCQkJcmV0dXJuIFsgJ3N1Y2Nlc3MnLCAieyR2ZXJifSBjb21tZW50IHskY29tbWVudF9pZH0uIiBdOwoJCQl9CgkJKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNhbGwoICRhcmdzLCAkc3RhdHVzLCAkc3VjY2VzcywgJGZhaWx1cmUgKSB7CgkJJGNvbW1lbnRfaWQgPSBhYnNpbnQoICRhcmdzICk7CgoJCSRmdW5jID0gIndwX3skc3RhdHVzfV9jb21tZW50IjsKCgkJaWYgKCAhICRmdW5jKCAkY29tbWVudF9pZCApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAkZmFpbHVyZSwgImNvbW1lbnQgeyRjb21tZW50X2lkfSIgKSApOwoJCX0KCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICRzdWNjZXNzLCAiY29tbWVudCB7JGNvbW1lbnRfaWR9IiApICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzZXRfc3RhdHVzKCAkYXJncywgJHN0YXR1cywgJHN1Y2Nlc3MgKSB7CgkJJGNvbW1lbnQgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJncyApOwoKCQkkcmVzdWx0ID0gd3Bfc2V0X2NvbW1lbnRfc3RhdHVzKCAkY29tbWVudC0+Y29tbWVudF9JRCwgJHN0YXR1cywgdHJ1ZSApOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRyZXN1bHQgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggInskc3VjY2Vzc30gY29tbWVudCB7JGNvbW1lbnQtPmNvbW1lbnRfSUR9LiIgKTsKCX0KCgkvKioKCSAqIFdhcm5zIGlmIGAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXWAgbm90IHNldCBhcyB1c2VkIGluIGVtYWlsIGZyb20tYWRkcmVzcyBzZW50IHRvIHBvc3QgYXV0aG9yIGluIGB3cF9ub3RpZnlfcG9zdGF1dGhvcigpYC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19zZXJ2ZXJfbmFtZSgpIHsKCQlpZiAoIGVtcHR5KCAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdTaXRlIHVybCBub3Qgc2V0IC0gZGVmYXVsdGluZyB0byBcJ2V4YW1wbGUuY29tXCcuIEFueSBub3RpZmljYXRpb24gZW1haWxzIHNlbnQgdG8gcG9zdCBhdXRob3IgbWF5IGFwcGVhciB0byBjb21lIGZyb20gXCdleGFtcGxlLmNvbVwnLicgKTsKCQkJJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gPSAnZXhhbXBsZS5jb20nOwoJCX0KCX0KCgkvKioKCSAqIFRyYXNoZXMgYSBjb21tZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IFRoZSBJRHMgb2YgdGhlIGNvbW1lbnRzIHRvIHRyYXNoLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVHJhc2ggY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgdHJhc2ggMTMzNwoJICogICAgIFN1Y2Nlc3M6IFRyYXNoZWQgY29tbWVudCAxMzM3LgoJICovCglwdWJsaWMgZnVuY3Rpb24gdHJhc2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGlkICkgewoJCQkkdGhpcy0+Y2FsbCggJGlkLCBfX0ZVTkNUSU9OX18sICdUcmFzaGVkICVzLicsICdGYWlsZWQgdHJhc2hpbmcgJXMuJyApOwoJCX0KCX0KCgkvKioKCSAqIFVudHJhc2hlcyBhIGNvbW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogVGhlIElEcyBvZiB0aGUgY29tbWVudHMgdG8gdW50cmFzaC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVudHJhc2ggY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgdW50cmFzaCAxMzM3CgkgKiAgICAgU3VjY2VzczogVW50cmFzaGVkIGNvbW1lbnQgMTMzNy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVudHJhc2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+Y2hlY2tfc2VydmVyX25hbWUoKTsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGlkICkgewoJCQkkdGhpcy0+Y2FsbCggJGlkLCBfX0ZVTkNUSU9OX18sICdVbnRyYXNoZWQgJXMuJywgJ0ZhaWxlZCB1bnRyYXNoaW5nICVzLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBNYXJrcyBhIGNvbW1lbnQgYXMgc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBUaGUgSURzIG9mIHRoZSBjb21tZW50cyB0byBtYXJrIGFzIHNwYW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTcGFtIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IHNwYW0gMTMzNwoJICogICAgIFN1Y2Nlc3M6IE1hcmtlZCBhcyBzcGFtIGNvbW1lbnQgMTMzNy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNwYW0oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGlkICkgewoJCQkkdGhpcy0+Y2FsbCggJGlkLCBfX0ZVTkNUSU9OX18sICdNYXJrZWQgJXMgYXMgc3BhbS4nLCAnRmFpbGVkIG1hcmtpbmcgJXMgYXMgc3BhbS4nICk7CgkJfQoJfQoKCS8qKgoJICogVW5tYXJrcyBhIGNvbW1lbnQgYXMgc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBUaGUgSURzIG9mIHRoZSBjb21tZW50cyB0byB1bm1hcmsgYXMgc3BhbS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVuc3BhbSBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCB1bnNwYW0gMTMzNwoJICogICAgIFN1Y2Nlc3M6IFVuc3BhbW1lZCBjb21tZW50IDEzMzcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bnNwYW0oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+Y2hlY2tfc2VydmVyX25hbWUoKTsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGlkICkgewoJCQkkdGhpcy0+Y2FsbCggJGlkLCBfX0ZVTkNUSU9OX18sICdVbnNwYW1tZWQgJXMuJywgJ0ZhaWxlZCB1bnNwYW1taW5nICVzLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBcHByb3ZlcyBhIGNvbW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogVGhlIElEcyBvZiB0aGUgY29tbWVudHMgdG8gYXBwcm92ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFwcHJvdmUgY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgYXBwcm92ZSAxMzM3CgkgKiAgICAgU3VjY2VzczogQXBwcm92ZWQgY29tbWVudCAxMzM3LgoJICovCglwdWJsaWMgZnVuY3Rpb24gYXBwcm92ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0aGlzLT5jaGVja19zZXJ2ZXJfbmFtZSgpOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkaWQgKSB7CgkJCSR0aGlzLT5zZXRfc3RhdHVzKCAkaWQsICdhcHByb3ZlJywgJ0FwcHJvdmVkJyApOwoJCX0KCX0KCgkvKioKCSAqIFVuYXBwcm92ZXMgYSBjb21tZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IFRoZSBJRHMgb2YgdGhlIGNvbW1lbnRzIHRvIHVuYXBwcm92ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVuYXBwcm92ZSBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCB1bmFwcHJvdmUgMTMzNwoJICogICAgIFN1Y2Nlc3M6IFVuYXBwcm92ZWQgY29tbWVudCAxMzM3LgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5hcHByb3ZlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRoaXMtPmNoZWNrX3NlcnZlcl9uYW1lKCk7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRpZCApIHsKCQkJJHRoaXMtPnNldF9zdGF0dXMoICRpZCwgJ2hvbGQnLCAnVW5hcHByb3ZlZCcgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDb3VudHMgY29tbWVudHMsIG9uIHdob2xlIGJsb2cgb3Igb24gYSBnaXZlbiBwb3N0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBvc3QtaWQ+XQoJICogOiBUaGUgSUQgb2YgdGhlIHBvc3QgdG8gY291bnQgY29tbWVudHMgaW4uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDb3VudCBjb21tZW50cyBvbiB3aG9sZSBibG9nLgoJICogICAgICQgd3AgY29tbWVudCBjb3VudAoJICogICAgIGFwcHJvdmVkOiAgICAgICAgMzMKCSAqICAgICBzcGFtOiAgICAgICAgICAgIDMKCSAqICAgICB0cmFzaDogICAgICAgICAgIDEKCSAqICAgICBwb3N0LXRyYXNoZWQ6ICAgIDAKCSAqICAgICBhbGw6ICAgICAgICAgICAgIDM0CgkgKiAgICAgbW9kZXJhdGVkOiAgICAgICAxCgkgKiAgICAgdG90YWxfY29tbWVudHM6ICAzNwoJICoKCSAqICAgICAjIENvdW50IGNvbW1lbnRzIGluIGEgcG9zdC4KCSAqICAgICAkIHdwIGNvbW1lbnQgY291bnQgNDIKCSAqICAgICBhcHByb3ZlZDogICAgICAgIDE5CgkgKiAgICAgc3BhbTogICAgICAgICAgICAwCgkgKiAgICAgdHJhc2g6ICAgICAgICAgICAwCgkgKiAgICAgcG9zdC10cmFzaGVkOiAgICAwCgkgKiAgICAgYWxsOiAgICAgICAgICAgICAxOQoJICogICAgIG1vZGVyYXRlZDogICAgICAgMAoJICogICAgIHRvdGFsX2NvbW1lbnRzOiAgMTkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNvdW50KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBvc3RfaWQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFyZ3MsIDAsIDAgKTsKCgkJJGNvdW50ID0gd3BfY291bnRfY29tbWVudHMoICRwb3N0X2lkICk7CgoJCS8vIE1vdmUgdG90YWxfY29tbWVudHMgdG8gdGhlIGVuZCBvZiB0aGUgb2JqZWN0CgkJJHRvdGFsID0gJGNvdW50LT50b3RhbF9jb21tZW50czsKCQl1bnNldCggJGNvdW50LT50b3RhbF9jb21tZW50cyApOwoJCSRjb3VudC0+dG90YWxfY29tbWVudHMgPSAkdG90YWw7CgoJCWZvcmVhY2ggKCAkY291bnQgYXMgJHN0YXR1cyA9PiAkY291bnQgKSB7CgkJCVdQX0NMSTo6bGluZSggc3RyX3BhZCggIiRzdGF0dXM6IiwgMTcgKSAuICRjb3VudCApOwoJCX0KCX0KCgkvKioKCSAqIFJlY2FsY3VsYXRlcyB0aGUgY29tbWVudF9jb3VudCB2YWx1ZSBmb3Igb25lIG9yIG1vcmUgcG9zdHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogSURzIGZvciBvbmUgb3IgbW9yZSBwb3N0cyB0byB1cGRhdGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZWNvdW50IGNvbW1lbnQgZm9yIHRoZSBwb3N0LgoJICogICAgICQgd3AgY29tbWVudCByZWNvdW50IDEyMwoJICogICAgIFVwZGF0ZWQgcG9zdCAxMjMgY29tbWVudCBjb3VudCB0byA2Ny4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlY291bnQoICRhcmdzICkgewoJCWZvcmVhY2ggKCAkYXJncyBhcyAkaWQgKSB7CgkJCXdwX3VwZGF0ZV9jb21tZW50X2NvdW50KCAkaWQgKTsKCQkJJHBvc3QgPSBnZXRfcG9zdCggJGlkICk7CgkJCWlmICggJHBvc3QgKSB7CgkJCQlXUF9DTEk6OmxvZyggIlVwZGF0ZWQgcG9zdCB7JHBvc3QtPklEfSBjb21tZW50IGNvdW50IHRvIHskcG9zdC0+Y29tbWVudF9jb3VudH0uIiApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiUG9zdCB7JHBvc3QtPklEfSBkb2Vzbid0IGV4aXN0LiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEdldHMgdGhlIHN0YXR1cyBvZiBhIGNvbW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBjb21tZW50IHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHN0YXR1cyBvZiBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCBzdGF0dXMgMTMzNwoJICogICAgIGFwcHJvdmVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdGF0dXMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkY29tbWVudF9pZCApID0gJGFyZ3M7CgoJCSRzdGF0dXMgPSB3cF9nZXRfY29tbWVudF9zdGF0dXMoICRjb21tZW50X2lkICk7CgoJCWlmICggZmFsc2UgPT09ICRzdGF0dXMgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgY2hlY2sgc3RhdHVzIG9mIGNvbW1lbnQgeyRjb21tZW50X2lkfS4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpsaW5lKCAkc3RhdHVzICk7CgkJfQoJfQoKCS8qKgoJICogVmVyaWZpZXMgd2hldGhlciBhIGNvbW1lbnQgZXhpc3RzLgoJICoKCSAqIERpc3BsYXlzIGEgc3VjY2VzcyBtZXNzYWdlIGlmIHRoZSBjb21tZW50IGRvZXMgZXhpc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBjb21tZW50IHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgd2hldGhlciBjb21tZW50IGV4aXN0cy4KCSAqICAgICAkIHdwIGNvbW1lbnQgZXhpc3RzIDEzMzcKCSAqICAgICBTdWNjZXNzOiBDb21tZW50IHdpdGggSUQgMTMzNyBleGlzdHMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBleGlzdHMoICRhcmdzICkgewoJCWlmICggJHRoaXMtPmZldGNoZXItPmdldCggJGFyZ3NbMF0gKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQ29tbWVudCB3aXRoIElEIHskYXJnc1swXX0gZXhpc3RzLiIgKTsKCQl9Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhEQk9iamVjdDsKdXNlIFdQX0NMSVxGZXRjaGVyc1xTaXRlIGFzIFNpdGVGZXRjaGVyOwp1c2UgV1BfQ0xJXEl0ZXJhdG9yc1xRdWVyeSBhcyBRdWVyeUl0ZXJhdG9yOwp1c2UgV1BfQ0xJXEl0ZXJhdG9yc1xUYWJsZSBhcyBUYWJsZUl0ZXJhdG9yOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKCi8qKgogKiBDcmVhdGVzLCBkZWxldGVzLCBlbXB0aWVzLCBtb2RlcmF0ZXMsIGFuZCBsaXN0cyBvbmUgb3IgbW9yZSBzaXRlcyBvbiBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBzaXRlCiAqICAgICAkIHdwIHNpdGUgY3JlYXRlIC0tc2x1Zz1leGFtcGxlCiAqICAgICBTdWNjZXNzOiBTaXRlIDMgY3JlYXRlZDogd3d3LmV4YW1wbGUuY29tL2V4YW1wbGUvCiAqCiAqICAgICAjIE91dHB1dCBhIHNpbXBsZSBsaXN0IG9mIHNpdGUgVVJMcwogKiAgICAgJCB3cCBzaXRlIGxpc3QgLS1maWVsZD11cmwKICogICAgIGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vCiAqICAgICBodHRwOi8vd3d3LmV4YW1wbGUuY29tL3N1YmRpci8KICoKICogICAgICMgRGVsZXRlIHNpdGUKICogICAgICQgd3Agc2l0ZSBkZWxldGUgMTIzCiAqICAgICBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoZSAnaHR0cDovL3d3dy5leGFtcGxlLmNvbS9leGFtcGxlJyBzaXRlPyBbeS9uXSB5CiAqICAgICBTdWNjZXNzOiBUaGUgc2l0ZSBhdCAnaHR0cDovL3d3dy5leGFtcGxlLmNvbS9leGFtcGxlJyB3YXMgZGVsZXRlZC4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBTaXRlX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aERCT2JqZWN0IHsKCglwcm90ZWN0ZWQgJG9ial90eXBlICAgPSAnc2l0ZSc7Cglwcm90ZWN0ZWQgJG9ial9pZF9rZXkgPSAnYmxvZ19pZCc7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFNpdGVGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBEZWxldGUgY29tbWVudHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZW1wdHlfY29tbWVudHMoKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBFbXB0eSBjb21tZW50cyBhbmQgY29tbWVudCBjYWNoZQoJCSRjb21tZW50X2lkcyA9ICR3cGRiLT5nZXRfY29sKCAiU0VMRUNUIGNvbW1lbnRfSUQgRlJPTSAkd3BkYi0+Y29tbWVudHMiICk7CgkJZm9yZWFjaCAoICRjb21tZW50X2lkcyBhcyAkY29tbWVudF9pZCApIHsKCQkJd3BfY2FjaGVfZGVsZXRlKCAkY29tbWVudF9pZCwgJ2NvbW1lbnQnICk7CgkJCXdwX2NhY2hlX2RlbGV0ZSggJGNvbW1lbnRfaWQsICdjb21tZW50X21ldGEnICk7CgkJfQoJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR3cGRiLT5jb21tZW50cyIgKTsKCQkkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkd3BkYi0+Y29tbWVudG1ldGEiICk7Cgl9CgoJLyoqCgkgKiBEZWxldGUgYWxsIHBvc3RzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGVtcHR5X3Bvc3RzKCkgewoJCWdsb2JhbCAkd3BkYjsKCgkJLy8gRW1wdHkgcG9zdHMgYW5kIHBvc3QgY2FjaGUKCQkkcG9zdHNfcXVlcnkgPSAiU0VMRUNUIElEIEZST00gJHdwZGItPnBvc3RzIjsKCQkkcG9zdHMgICAgICAgPSBuZXcgUXVlcnlJdGVyYXRvciggJHBvc3RzX3F1ZXJ5LCAxMDAwMCApOwoKCQkkdGF4b25vbWllcyA9IGdldF90YXhvbm9taWVzKCk7CgoJCXdoaWxlICggJHBvc3RzLT52YWxpZCgpICkgewoJCQkkcG9zdF9pZCA9ICRwb3N0cy0+Y3VycmVudCgpLT5JRDsKCgkJCXdwX2NhY2hlX2RlbGV0ZSggJHBvc3RfaWQsICdwb3N0cycgKTsKCQkJd3BfY2FjaGVfZGVsZXRlKCAkcG9zdF9pZCwgJ3Bvc3RfbWV0YScgKTsKCQkJZm9yZWFjaCAoICR0YXhvbm9taWVzIGFzICR0YXhvbm9teSApIHsKCQkJCXdwX2NhY2hlX2RlbGV0ZSggJHBvc3RfaWQsICJ7JHRheG9ub215fV9yZWxhdGlvbnNoaXBzIiApOwoJCQl9CgkJCXdwX2NhY2hlX2RlbGV0ZSggJHdwZGItPmJsb2dpZCAuICctJyAuICRwb3N0X2lkLCAnZ2xvYmFsLXBvc3RzJyApOwoKCQkJJHBvc3RzLT5uZXh0KCk7CgkJfQoJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR3cGRiLT5wb3N0cyIgKTsKCQkkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkd3BkYi0+cG9zdG1ldGEiICk7Cgl9CgoJLyoqCgkgKiBEZWxldGUgdGVybXMsIHRheG9ub21pZXMsIGFuZCB0YXggcmVsYXRpb25zaGlwcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBlbXB0eV90YXhvbm9taWVzKCkgewoJCWdsb2JhbCAkd3BkYjsKCgkJLy8gRW1wdHkgdGF4b25vbWllcyBhbmQgdGVybXMKCQkkdGVybXMgICAgICA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIlNFTEVDVCB0ZXJtX2lkLCB0YXhvbm9teSBGUk9NICR3cGRiLT50ZXJtX3RheG9ub215IiApOwoJCSR0YXhvbm9taWVzID0gW107CgkJZm9yZWFjaCAoIChhcnJheSkgJHRlcm1zIGFzICR0ZXJtICkgewoJCQkkdGF4b25vbWllc1tdID0gJHRlcm0tPnRheG9ub215OwoJCQl3cF9jYWNoZV9kZWxldGUoICR0ZXJtLT50ZXJtX2lkLCAkdGVybS0+dGF4b25vbXkgKTsKCQl9CgoJCSR0YXhvbm9taWVzID0gYXJyYXlfdW5pcXVlKCAkdGF4b25vbWllcyApOwoJCSRjbGVhbmVkICAgID0gW107CgkJZm9yZWFjaCAoICR0YXhvbm9taWVzIGFzICR0YXhvbm9teSApIHsKCQkJaWYgKCBpc3NldCggJGNsZWFuZWRbICR0YXhvbm9teSBdICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkkY2xlYW5lZFsgJHRheG9ub215IF0gPSB0cnVlOwoKCQkJd3BfY2FjaGVfZGVsZXRlKCAnYWxsX2lkcycsICR0YXhvbm9teSApOwoJCQl3cF9jYWNoZV9kZWxldGUoICdnZXQnLCAkdGF4b25vbXkgKTsKCQkJZGVsZXRlX29wdGlvbiggInskdGF4b25vbXl9X2NoaWxkcmVuIiApOwoJCX0KCQkkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkd3BkYi0+dGVybXMiICk7CgkJJHdwZGItPnF1ZXJ5KCAiVFJVTkNBVEUgJHdwZGItPnRlcm1fdGF4b25vbXkiICk7CgkJJHdwZGItPnF1ZXJ5KCAiVFJVTkNBVEUgJHdwZGItPnRlcm1fcmVsYXRpb25zaGlwcyIgKTsKCQlpZiAoICEgZW1wdHkoICR3cGRiLT50ZXJtbWV0YSApICkgewoJCQkkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkd3BkYi0+dGVybW1ldGEiICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlIGFsbCBsaW5rcywgbGlua19jYXRlZ29yeSB0ZXJtcywgYW5kIHJlbGF0ZWQgY2FjaGUuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZW1wdHlfbGlua3MoKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBSZW1vdmUgbGlua3MgYW5kIHJlbGF0ZWQgY2FjaGVkIGRhdGEuCgkJJGxpbmtzX3F1ZXJ5ID0gIlNFTEVDVCBsaW5rX2lkIEZST00geyR3cGRiLT5saW5rc30iOwoJCSRsaW5rcyAgICAgICA9IG5ldyBRdWVyeUl0ZXJhdG9yKCAkbGlua3NfcXVlcnksIDEwMDAwICk7CgoJCS8vIFJlbW92ZSBib29rbWFya3MgY2FjaGUgZ3JvdXAuCgkJd3BfY2FjaGVfZGVsZXRlKCAnZ2V0X2Jvb2ttYXJrcycsICdib29rbWFyaycgKTsKCgkJd2hpbGUgKCAkbGlua3MtPnZhbGlkKCkgKSB7CgkJCSRsaW5rX2lkID0gJGxpbmtzLT5jdXJyZW50KCktPmxpbmtfaWQ7CgoJCQkvLyBSZW1vdmUgY2FjaGUgZm9yIHRoZSBsaW5rLgoJCQl3cF9kZWxldGVfb2JqZWN0X3Rlcm1fcmVsYXRpb25zaGlwcyggJGxpbmtfaWQsICdsaW5rX2NhdGVnb3J5JyApOwoJCQl3cF9jYWNoZV9kZWxldGUoICRsaW5rX2lkLCAnYm9va21hcmsnICk7CgkJCWNsZWFuX29iamVjdF90ZXJtX2NhY2hlKCAkbGlua19pZCwgJ2xpbmsnICk7CgoJCQkkbGlua3MtPm5leHQoKTsKCQl9CgoJCS8vIEVtcHR5IHRoZSB0YWJsZSBvbmNlIGxpbmsgcmVsYXRlZCBjYWNoZSBhbmQgdGVybSBpcyByZW1vdmVkLgoJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFIHskd3BkYi0+bGlua3N9IiApOwoJfQoKCS8qKgoJICogSW5zZXJ0IGRlZmF1bHQgdGVybXMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaW5zZXJ0X2RlZmF1bHRfdGVybXMoKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBEZWZhdWx0IGNhdGVnb3J5CgkJJGNhdF9uYW1lID0gX18oICdVbmNhdGVnb3JpemVkJyApOwoKCQkvKiB0cmFuc2xhdG9yczogRGVmYXVsdCBjYXRlZ29yeSBzbHVnICovCgkJJGNhdF9zbHVnID0gc2FuaXRpemVfdGl0bGUoIF94KCAnVW5jYXRlZ29yaXplZCcsICdEZWZhdWx0IGNhdGVnb3J5IHNsdWcnICkgKTsKCgkJaWYgKCBnbG9iYWxfdGVybXNfZW5hYmxlZCgpICkgewoJCQkkY2F0X2lkID0gJHdwZGItPmdldF92YXIoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUIGNhdF9JRCBGUk9NIHskd3BkYi0+c2l0ZWNhdGVnb3JpZXN9IFdIRVJFIGNhdGVnb3J5X25pY2VuYW1lID0gJXMiLCAkY2F0X3NsdWcgKSApOwoJCQlpZiAoIG51bGwgPT09ICRjYXRfaWQgKSB7CgkJCQkkd3BkYi0+aW5zZXJ0KAoJCQkJCSR3cGRiLT5zaXRlY2F0ZWdvcmllcywKCQkJCQlbCgkJCQkJCSdjYXRfSUQnICAgICAgICAgICAgPT4gMCwKCQkJCQkJJ2NhdF9uYW1lJyAgICAgICAgICA9PiAkY2F0X25hbWUsCgkJCQkJCSdjYXRlZ29yeV9uaWNlbmFtZScgPT4gJGNhdF9zbHVnLAoJCQkJCQknbGFzdF91cGRhdGVkJyAgICAgID0+IGN1cnJlbnRfdGltZSgKCQkJCQkJCSdteXNxbCcsCgkJCQkJCQl0cnVlCgkJCQkJCSksCgkJCQkJXQoJCQkJKTsKCQkJCSRjYXRfaWQgPSAkd3BkYi0+aW5zZXJ0X2lkOwoJCQl9CgkJCXVwZGF0ZV9vcHRpb24oICdkZWZhdWx0X2NhdGVnb3J5JywgJGNhdF9pZCApOwoJCX0gZWxzZSB7CgkJCSRjYXRfaWQgPSAxOwoJCX0KCgkJJHdwZGItPmluc2VydCgKCQkJJHdwZGItPnRlcm1zLAoJCQlbCgkJCQkndGVybV9pZCcgICAgPT4gJGNhdF9pZCwKCQkJCSduYW1lJyAgICAgICA9PiAkY2F0X25hbWUsCgkJCQknc2x1ZycgICAgICAgPT4gJGNhdF9zbHVnLAoJCQkJJ3Rlcm1fZ3JvdXAnID0+IDAsCgkJCV0KCQkpOwoJCSR3cGRiLT5pbnNlcnQoCgkJCSR3cGRiLT50ZXJtX3RheG9ub215LAoJCQlbCgkJCQkndGVybV9pZCcgICAgID0+ICRjYXRfaWQsCgkJCQkndGF4b25vbXknICAgID0+ICdjYXRlZ29yeScsCgkJCQknZGVzY3JpcHRpb24nID0+ICcnLAoJCQkJJ3BhcmVudCcgICAgICA9PiAwLAoJCQkJJ2NvdW50JyAgICAgICA9PiAwLAoJCQldCgkJKTsKCX0KCgkvKioKCSAqIFJlc2V0IG9wdGlvbiB2YWx1ZXMgdG8gZGVmYXVsdC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiByZXNldF9vcHRpb25zKCkgewoJCS8vIFJlc2V0IFByaXZhY3kgUG9saWN5IHZhbHVlIHRvIHByZXZlbnQgZXJyb3IuCgkJdXBkYXRlX29wdGlvbiggJ3dwX3BhZ2VfZm9yX3ByaXZhY3lfcG9saWN5JywgMCApOwoKCQkvLyBSZXNldCBzdGlja3kgcG9zdHMgb3B0aW9uLgoJCXVwZGF0ZV9vcHRpb24oICdzdGlja3lfcG9zdHMnLCBbXSApOwoJfQoKCS8qKgoJICogRW1wdGllcyBhIHNpdGUgb2YgaXRzIGNvbnRlbnQgKHBvc3RzLCBjb21tZW50cywgdGVybXMsIGFuZCBtZXRhKS4KCSAqCgkgKiBUcnVuY2F0ZXMgcG9zdHMsIGNvbW1lbnRzLCBhbmQgdGVybXMgdGFibGVzIHRvIGVtcHR5IGEgc2l0ZSBvZiBpdHMKCSAqIGNvbnRlbnQuIERvZXNuJ3QgYWZmZWN0IHNpdGUgY29uZmlndXJhdGlvbiAob3B0aW9ucykgb3IgdXNlcnMuCgkgKgoJICogSWYgcnVubmluZyBhIHBlcnNpc3RlbnQgb2JqZWN0IGNhY2hlLCBtYWtlIHN1cmUgdG8gZmx1c2ggdGhlIGNhY2hlCgkgKiBhZnRlciBlbXB0eWluZyB0aGUgc2l0ZSwgYXMgdGhlIGNhY2hlIHZhbHVlcyB3aWxsIGJlIGludmFsaWQgb3RoZXJ3aXNlLgoJICoKCSAqIFRvIGFsc28gZW1wdHkgY3VzdG9tIGRhdGFiYXNlIHRhYmxlcywgeW91J2xsIG5lZWQgdG8gaG9vayBpbnRvIGNvbW1hbmQKCSAqIGV4ZWN1dGlvbjoKCSAqCgkgKiBgYGAKCSAqIFdQX0NMSTo6YWRkX2hvb2soICdhZnRlcl9pbnZva2U6c2l0ZSBlbXB0eScsIGZ1bmN0aW9uKCl7CgkgKiAgICAgZ2xvYmFsICR3cGRiOwoJICogICAgIGZvcmVhY2goIGFycmF5KCAncDJwJywgJ3AycG1ldGEnICkgYXMgJHRhYmxlICkgewoJICogICAgICAgICAkdGFibGUgPSAkd3BkYi0+JHRhYmxlOwoJICogICAgICAgICAkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkdGFibGUiICk7CgkgKiAgICAgfQoJICogfSk7CgkgKiBgYGAKCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tdXBsb2Fkc10KCSAqIDogQWxzbyBkZWxldGUgKmFsbCogZmlsZXMgaW4gdGhlIHNpdGUncyB1cGxvYWRzIGRpcmVjdG9yeS4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IFByb2NlZWQgdG8gZW1wdHkgdGhlIHNpdGUgd2l0aG91dCBhIGNvbmZpcm1hdGlvbiBwcm9tcHQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzaXRlIGVtcHR5CgkgKiAgICAgQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGVtcHR5IHRoZSBzaXRlIGF0IGh0dHA6Ly93d3cuZXhhbXBsZS5jb20gb2YgYWxsIHBvc3RzLCBsaW5rcywgY29tbWVudHMsIGFuZCB0ZXJtcz8gW3kvbl0geQoJICogICAgIFN1Y2Nlc3M6IFRoZSBzaXRlIGF0ICdodHRwOi8vd3d3LmV4YW1wbGUuY29tJyB3YXMgZW1wdGllZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBlbXB0eQoJICovCglwdWJsaWMgZnVuY3Rpb24gZW1wdHlfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSR1cGxvYWRfbWVzc2FnZSA9ICcnOwoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndXBsb2FkcycgKSApIHsKCQkJJHVwbG9hZF9tZXNzYWdlID0gJywgYW5kIGRlbGV0ZSBpdHMgdXBsb2FkcyBkaXJlY3RvcnknOwoJCX0KCgkJV1BfQ0xJOjpjb25maXJtKCAiQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGVtcHR5IHRoZSBzaXRlIGF0ICciIC4gc2l0ZV91cmwoKSAuICInIG9mIGFsbCBwb3N0cywgbGlua3MsIGNvbW1lbnRzLCBhbmQgdGVybXMiIC4gJHVwbG9hZF9tZXNzYWdlIC4gJz8nLCAkYXNzb2NfYXJncyApOwoKCQkkdGhpcy0+ZW1wdHlfcG9zdHMoKTsKCQkkdGhpcy0+ZW1wdHlfbGlua3MoKTsKCQkkdGhpcy0+ZW1wdHlfY29tbWVudHMoKTsKCQkkdGhpcy0+ZW1wdHlfdGF4b25vbWllcygpOwoJCSR0aGlzLT5pbnNlcnRfZGVmYXVsdF90ZXJtcygpOwoJCSR0aGlzLT5yZXNldF9vcHRpb25zKCk7CgoJCWlmICggISBlbXB0eSggJHVwbG9hZF9tZXNzYWdlICkgKSB7CgkJCSR1cGxvYWRfZGlyID0gd3BfdXBsb2FkX2RpcigpOwoJCQkkZmlsZXMgICAgICA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKAoJCQkJbmV3IFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKCAkdXBsb2FkX2RpclsnYmFzZWRpciddLCBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6U0tJUF9ET1RTICksCgkJCQlSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yOjpDSElMRF9GSVJTVAoJCQkpOwoKCQkJJGZpbGVzX3RvX3VubGluayAgICAgICA9IFtdOwoJCQkkZGlyZWN0b3JpZXNfdG9fZGVsZXRlID0gW107CgkJCSRpc19tYWluX3NpdGUgICAgICAgICAgPSBpc19tYWluX3NpdGUoKTsKCQkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZWluZm8gKSB7CgkJCQkkcmVhbHBhdGggPSAkZmlsZWluZm8tPmdldFJlYWxQYXRoKCk7CgkJCQkvLyBEb24ndCBjbG9iYmVyIHN1YnNpdGVzIHdoZW4gb3BlcmF0aW5nIG9uIHRoZSBtYWluIHNpdGUKCQkJCWlmICggJGlzX21haW5fc2l0ZSAmJiBmYWxzZSAhPT0gc3RyaXBvcyggJHJlYWxwYXRoLCAnL3NpdGVzLycgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWlmICggJGZpbGVpbmZvLT5pc0RpcigpICkgewoJCQkJCSRkaXJlY3Rvcmllc190b19kZWxldGVbXSA9ICRyZWFscGF0aDsKCQkJCX0gZWxzZSB7CgkJCQkJJGZpbGVzX3RvX3VubGlua1tdID0gJHJlYWxwYXRoOwoJCQkJfQoJCQl9CgkJCWZvcmVhY2ggKCAkZmlsZXNfdG9fdW5saW5rIGFzICRmaWxlICkgewoJCQkJdW5saW5rKCAkZmlsZSApOwoJCQl9CgkJCWZvcmVhY2ggKCAkZGlyZWN0b3JpZXNfdG9fZGVsZXRlIGFzICRkaXJlY3RvcnkgKSB7CgkJCQkvLyBEaXJlY3RvcnkgY291bGQgYmUgbWFpbiBzaXRlcyBkaXJlY3RvcnkgJy9zaXRlcycgd2hpY2ggbWF5IGJlIG5vbi1lbXB0eS4KCQkJCUBybWRpciggJGRpcmVjdG9yeSApOwoJCQl9CgkJCS8vIE1heSBiZSBub24tZW1wdHkgaWYgJy9zaXRlcycgc3RpbGwgYXJvdW5kLgoJCQlAcm1kaXIoICR1cGxvYWRfZGlyWydiYXNlZGlyJ10gKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIlRoZSBzaXRlIGF0ICciIC4gc2l0ZV91cmwoKSAuICInIHdhcyBlbXB0aWVkLiIgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgYSBzaXRlIGluIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxzaXRlLWlkPl0KCSAqIDogVGhlIGlkIG9mIHRoZSBzaXRlIHRvIGRlbGV0ZS4gSWYgbm90IHByb3ZpZGVkLCB5b3UgbXVzdCBzZXQgdGhlIC0tc2x1ZyBwYXJhbWV0ZXIuCgkgKgoJICogWy0tc2x1Zz08c2x1Zz5dCgkgKiA6IFBhdGggb2YgdGhlIGJsb2cgdG8gYmUgZGVsZXRlZC4gU3ViZG9tYWluIG9uIHN1YmRvbWFpbiBpbnN0YWxscywgZGlyZWN0b3J5IG9uIHN1YmRpcmVjdG9yeSBpbnN0YWxscy4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IEFuc3dlciB5ZXMgdG8gdGhlIGNvbmZpcm1hdGlvbiBtZXNzYWdlLgoJICoKCSAqIFstLWtlZXAtdGFibGVzXQoJICogOiBEZWxldGUgdGhlIGJsb2cgZnJvbSB0aGUgbGlzdCwgYnV0IGRvbid0IGRyb3AgaXQncyB0YWJsZXMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzaXRlIGRlbGV0ZSAxMjMKCSAqICAgICBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGUgc2l0ZT8gW3kvbl0geQoJICogICAgIFN1Y2Nlc3M6IFRoZSBzaXRlIGF0ICdodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGUnIHdhcyBkZWxldGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydzbHVnJ10gKSApIHsKCQkJJGJsb2cgPSBnZXRfYmxvZ19kZXRhaWxzKCB0cmltKCAkYXNzb2NfYXJnc1snc2x1ZyddLCAnLycgKSApOwoJCX0gZWxzZSB7CgkJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnTmVlZCB0byBzcGVjaWZ5IGEgYmxvZyBpZC4nICk7CgkJCX0KCgkJCSRibG9nX2lkID0gJGFyZ3NbMF07CgoJCQlpZiAoIGlzX21haW5fc2l0ZSggJGJsb2dfaWQgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdZb3UgY2Fubm90IGRlbGV0ZSB0aGUgcm9vdCBzaXRlLicgKTsKCQkJfQoKCQkJJGJsb2cgPSBnZXRfYmxvZ19kZXRhaWxzKCAkYmxvZ19pZCApOwoJCX0KCgkJaWYgKCAhICRibG9nICkgewoJCQlXUF9DTEk6OmVycm9yKCAnU2l0ZSBub3QgZm91bmQuJyApOwoJCX0KCgkJJHNpdGVfdXJsID0gdHJhaWxpbmdzbGFzaGl0KCAkYmxvZy0+c2l0ZXVybCApOwoKCQlXUF9DTEk6OmNvbmZpcm0oICJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoZSAneyRzaXRlX3VybH0nIHNpdGU/IiwgJGFzc29jX2FyZ3MgKTsKCgkJd3BtdV9kZWxldGVfYmxvZyggJGJsb2ctPmJsb2dfaWQsICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAna2VlcC10YWJsZXMnICkgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAiVGhlIHNpdGUgYXQgJ3skc2l0ZV91cmx9JyB3YXMgZGVsZXRlZC4iICk7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGEgc2l0ZSBpbiBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIC0tc2x1Zz08c2x1Zz4KCSAqIDogUGF0aCBmb3IgdGhlIG5ldyBzaXRlLiBTdWJkb21haW4gb24gc3ViZG9tYWluIGluc3RhbGxzLCBkaXJlY3Rvcnkgb24gc3ViZGlyZWN0b3J5IGluc3RhbGxzLgoJICoKCSAqIFstLXRpdGxlPTx0aXRsZT5dCgkgKiA6IFRpdGxlIG9mIHRoZSBuZXcgc2l0ZS4gRGVmYXVsdDogcHJldHRpZmllZCBzbHVnLgoJICoKCSAqIFstLWVtYWlsPTxlbWFpbD5dCgkgKiA6IEVtYWlsIGZvciBhZG1pbiB1c2VyLiBVc2VyIHdpbGwgYmUgY3JlYXRlZCBpZiBub25lIGV4aXN0cy4gQXNzaWdubWVudCB0byBzdXBlciBhZG1pbiBpZiBub3QgaW5jbHVkZWQuCgkgKgoJICogWy0tbmV0d29ya19pZD08bmV0d29yay1pZD5dCgkgKiA6IE5ldHdvcmsgdG8gYXNzb2NpYXRlIG5ldyBzaXRlIHdpdGguIERlZmF1bHRzIHRvIGN1cnJlbnQgbmV0d29yayAodHlwaWNhbGx5IDEpLgoJICoKCSAqIFstLXByaXZhdGVdCgkgKiA6IElmIHNldCwgdGhlIG5ldyBzaXRlIHdpbGwgYmUgbm9uLXB1YmxpYyAobm90IGluZGV4ZWQpCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBJZiBzZXQsIG9ubHkgdGhlIHNpdGUgaWQgd2lsbCBiZSBvdXRwdXQgb24gc3VjY2Vzcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgY3JlYXRlIC0tc2x1Zz1leGFtcGxlCgkgKiAgICAgU3VjY2VzczogU2l0ZSAzIGNyZWF0ZWQ6IGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZS8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkJfQoKCQlnbG9iYWwgJHdwZGIsICRjdXJyZW50X3NpdGU7CgoJCSRiYXNlICA9ICRhc3NvY19hcmdzWydzbHVnJ107CgkJJHRpdGxlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndGl0bGUnLCB1Y2ZpcnN0KCAkYmFzZSApICk7CgoJCSRlbWFpbCA9IGVtcHR5KCAkYXNzb2NfYXJnc1snZW1haWwnXSApID8gJycgOiAkYXNzb2NfYXJnc1snZW1haWwnXTsKCgkJLy8gTmV0d29yawoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ25ldHdvcmtfaWQnXSApICkgewoJCQkkbmV0d29yayA9ICR0aGlzLT5nZXRfbmV0d29yayggJGFzc29jX2FyZ3NbJ25ldHdvcmtfaWQnXSApOwoJCQlpZiAoIGZhbHNlID09PSAkbmV0d29yayApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJOZXR3b3JrIHdpdGggaWQgeyRhc3NvY19hcmdzWyduZXR3b3JrX2lkJ119IGRvZXMgbm90IGV4aXN0LiIgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRuZXR3b3JrID0gJGN1cnJlbnRfc2l0ZTsKCQl9CgoJCSRwdWJsaWMgPSAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ByaXZhdGUnICk7CgoJCS8vIFNhbml0aXplCgkJaWYgKCBwcmVnX21hdGNoKCAnfF4oW2EtekEtWjAtOS1dKSskfCcsICRiYXNlICkgKSB7CgkJCSRiYXNlID0gc3RydG9sb3dlciggJGJhc2UgKTsKCQl9CgoJCS8vIElmIG5vdCBhIHN1YmRvbWFpbiBpbnN0YWxsLCBtYWtlIHN1cmUgdGhlIGRvbWFpbiBpc24ndCBhIHJlc2VydmVkIHdvcmQKCQlpZiAoICEgaXNfc3ViZG9tYWluX2luc3RhbGwoKSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIFdvcmRQcmVzcyBuYXRpdmUgaG9vay4KCQkJJHN1YmRpcmVjdG9yeV9yZXNlcnZlZF9uYW1lcyA9IGFwcGx5X2ZpbHRlcnMoICdzdWJkaXJlY3RvcnlfcmVzZXJ2ZWRfbmFtZXMnLCBbICdwYWdlJywgJ2NvbW1lbnRzJywgJ2Jsb2cnLCAnZmlsZXMnLCAnZmVlZCcgXSApOwoJCQlpZiAoIGluX2FycmF5KCAkYmFzZSwgJHN1YmRpcmVjdG9yeV9yZXNlcnZlZF9uYW1lcywgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RoZSBmb2xsb3dpbmcgd29yZHMgYXJlIHJlc2VydmVkIGFuZCBjYW5ub3QgYmUgdXNlZCBhcyBibG9nIG5hbWVzOiAnIC4gaW1wbG9kZSggJywgJywgJHN1YmRpcmVjdG9yeV9yZXNlcnZlZF9uYW1lcyApICk7CgkJCX0KCQl9CgoJCS8vIENoZWNrIGZvciB2YWxpZCBlbWFpbCwgaWYgbm90LCB1c2UgdGhlIGZpcnN0IHN1cGVyIGFkbWluIGZvdW5kCgkJLy8gUHJvYmFibHkgYSBtb3JlIGVmZmljaWVudCB3YXkgdG8gZG8gdGhpcyBzbyB3ZSBkb250IHF1ZXJ5IGZvciB0aGUKCQkvLyBVc2VyIHR3aWNlIGlmIHN1cGVyIGFkbWluCgkJJGVtYWlsID0gc2FuaXRpemVfZW1haWwoICRlbWFpbCApOwoJCWlmICggZW1wdHkoICRlbWFpbCApIHx8ICEgaXNfZW1haWwoICRlbWFpbCApICkgewoJCQkkc3VwZXJfYWRtaW5zID0gZ2V0X3N1cGVyX2FkbWlucygpOwoJCQkkZW1haWwgICAgICAgID0gJyc7CgkJCWlmICggISBlbXB0eSggJHN1cGVyX2FkbWlucyApICYmIGlzX2FycmF5KCAkc3VwZXJfYWRtaW5zICkgKSB7CgkJCQkvLyBKdXN0IGdldCB0aGUgZmlyc3Qgb25lCgkJCQkkc3VwZXJfbG9naW4gPSAkc3VwZXJfYWRtaW5zWzBdOwoJCQkJJHN1cGVyX3VzZXIgID0gZ2V0X3VzZXJfYnkoICdsb2dpbicsICRzdXBlcl9sb2dpbiApOwoJCQkJaWYgKCAkc3VwZXJfdXNlciApIHsKCQkJCQkkZW1haWwgPSAkc3VwZXJfdXNlci0+dXNlcl9lbWFpbDsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCBpc19zdWJkb21haW5faW5zdGFsbCgpICkgewoJCQkkbmV3ZG9tYWluID0gJGJhc2UgLiAnLicgLiBwcmVnX3JlcGxhY2UoICd8Xnd3d1wufCcsICcnLCAkY3VycmVudF9zaXRlLT5kb21haW4gKTsKCQkJJHBhdGggICAgICA9ICRjdXJyZW50X3NpdGUtPnBhdGg7CgkJfSBlbHNlIHsKCQkJJG5ld2RvbWFpbiA9ICRjdXJyZW50X3NpdGUtPmRvbWFpbjsKCQkJJHBhdGggICAgICA9ICRjdXJyZW50X3NpdGUtPnBhdGggLiAkYmFzZSAuICcvJzsKCQl9CgoJCSR1c2VyX2lkID0gZW1haWxfZXhpc3RzKCAkZW1haWwgKTsKCQlpZiAoICEgJHVzZXJfaWQgKSB7IC8vIENyZWF0ZSBhIG5ldyB1c2VyIHdpdGggYSByYW5kb20gcGFzc3dvcmQKCQkJJHBhc3N3b3JkID0gd3BfZ2VuZXJhdGVfcGFzc3dvcmQoIDEyLCBmYWxzZSApOwoJCQkkdXNlcl9pZCAgPSB3cG11X2NyZWF0ZV91c2VyKCAkYmFzZSwgJHBhc3N3b3JkLCAkZW1haWwgKTsKCQkJaWYgKCBmYWxzZSA9PT0gJHVzZXJfaWQgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ2FuJ3QgY3JlYXRlIHVzZXIuIiApOwoJCQl9IGVsc2UgewoJCQkJVXNlcl9Db21tYW5kOjp3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAkcGFzc3dvcmQgKTsKCQkJfQoJCX0KCgkJJHdwZGItPmhpZGVfZXJyb3JzKCk7CgkJJHRpdGxlID0gd3Bfc2xhc2goICR0aXRsZSApOwoJCSRpZCAgICA9IHdwbXVfY3JlYXRlX2Jsb2coICRuZXdkb21haW4sICRwYXRoLCAkdGl0bGUsICR1c2VyX2lkLCBbICdwdWJsaWMnID0+ICRwdWJsaWMgXSwgJG5ldHdvcmstPmlkICk7CgkJJHdwZGItPnNob3dfZXJyb3JzKCk7CgkJaWYgKCAhIGlzX3dwX2Vycm9yKCAkaWQgKSApIHsKCQkJaWYgKCAhIGlzX3N1cGVyX2FkbWluKCAkdXNlcl9pZCApICYmICEgZ2V0X3VzZXJfb3B0aW9uKCAncHJpbWFyeV9ibG9nJywgJHVzZXJfaWQgKSApIHsKCQkJCXVwZGF0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICdwcmltYXJ5X2Jsb2cnLCAkaWQsIHRydWUgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRpZC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCVdQX0NMSTo6bGluZSggJGlkICk7CgkJfSBlbHNlIHsKCQkJJHNpdGVfdXJsID0gdHJhaWxpbmdzbGFzaGl0KCBnZXRfc2l0ZV91cmwoICRpZCApICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlNpdGUgeyRpZH0gY3JlYXRlZDogeyRzaXRlX3VybH0iICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyBuZXR3b3JrIGRhdGEgZm9yIGEgZ2l2ZW4gaWQuCgkgKgoJICogQHBhcmFtIGludCAgICAgJG5ldHdvcmtfaWQKCSAqIEByZXR1cm4gYm9vbHxhcnJheSBGYWxzZSBpZiBubyBuZXR3b3JrIGZvdW5kIHdpdGggZ2l2ZW4gaWQsIGFycmF5IG90aGVyd2lzZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9uZXR3b3JrKCAkbmV0d29ya19pZCApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIExvYWQgbmV0d29yayBkYXRhCgkJJG5ldHdvcmtzID0gJHdwZGItPmdldF9yZXN1bHRzKAoJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCSJTRUxFQ1QgKiBGUk9NICR3cGRiLT5zaXRlIFdIRVJFIGlkID0gJWQiLAoJCQkJJG5ldHdvcmtfaWQKCQkJKQoJCSk7CgoJCWlmICggISBlbXB0eSggJG5ldHdvcmtzICkgKSB7CgkJCS8vIE9ubHkgY2FyZSBhYm91dCBkb21haW4gYW5kIHBhdGggd2hpY2ggYXJlIHNldCBoZXJlCgkJCXJldHVybiAkbmV0d29ya3NbMF07CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBMaXN0cyBhbGwgc2l0ZXMgaW4gYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1uZXR3b3JrPTxpZD5dCgkgKiA6IFRoZSBuZXR3b3JrIHRvIHdoaWNoIHRoZSBzaXRlcyBiZWxvbmcuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzIChzZWUgIkF2YWlsYWJsZSBGaWVsZHMiIHNlY3Rpb24pLiBIb3dldmVyLAoJICogJ3VybCcgaXNuJ3QgYW4gYXZhaWxhYmxlIGZpbHRlciwgYmVjYXVzZSBpdCdzIGNyZWF0ZWQgZnJvbSBkb21haW4gKyBwYXRoLgoJICoKCSAqIFstLXNpdGVfX2luPTx2YWx1ZT5dCgkgKiA6IE9ubHkgbGlzdCB0aGUgc2l0ZXMgd2l0aCB0aGVzZSBibG9nX2lkIHZhbHVlcyAoY29tbWEtc2VwYXJhdGVkKS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHNpdGUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBmaWVsZHMgdG8gc2hvdy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBjb3VudAoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggc2l0ZToKCSAqCgkgKiAqIGJsb2dfaWQKCSAqICogdXJsCgkgKiAqIGxhc3RfdXBkYXRlZAoJICogKiByZWdpc3RlcmVkCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHNpdGVfaWQKCSAqICogZG9tYWluCgkgKiAqIHBhdGgKCSAqICogcHVibGljCgkgKiAqIGFyY2hpdmVkCgkgKiAqIG1hdHVyZQoJICogKiBzcGFtCgkgKiAqIGRlbGV0ZWQKCSAqICogbGFuZ19pZAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgT3V0cHV0IGEgc2ltcGxlIGxpc3Qgb2Ygc2l0ZSBVUkxzCgkgKiAgICAgJCB3cCBzaXRlIGxpc3QgLS1maWVsZD11cmwKCSAqICAgICBodHRwOi8vd3d3LmV4YW1wbGUuY29tLwoJICogICAgIGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vc3ViZGlyLwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCWdsb2JhbCAkd3BkYjsKCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9IHByZWdfc3BsaXQoICcvLFsgXHRdKi8nLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKTsKCQl9CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknZm9ybWF0JyA9PiAndGFibGUnLAoJCQknZmllbGRzJyA9PiBbICdibG9nX2lkJywgJ3VybCcsICdsYXN0X3VwZGF0ZWQnLCAncmVnaXN0ZXJlZCcgXSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJJHdoZXJlICA9IFtdOwoJCSRhcHBlbmQgPSAnJzsKCgkJJHNpdGVfY29scyA9IFsgJ2Jsb2dfaWQnLCAnbGFzdF91cGRhdGVkJywgJ3JlZ2lzdGVyZWQnLCAnc2l0ZV9pZCcsICdkb21haW4nLCAncGF0aCcsICdwdWJsaWMnLCAnYXJjaGl2ZWQnLCAnbWF0dXJlJywgJ3NwYW0nLCAnZGVsZXRlZCcsICdsYW5nX2lkJyBdOwoJCWZvcmVhY2ggKCAkc2l0ZV9jb2xzIGFzICRjb2wgKSB7CgkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkY29sIF0gKSApIHsKCQkJCSR3aGVyZVsgJGNvbCBdID0gJGFzc29jX2FyZ3NbICRjb2wgXTsKCQkJfQoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3NpdGVfX2luJ10gKSApIHsKCQkJJHdoZXJlWydibG9nX2lkJ10gPSBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydzaXRlX19pbiddICk7CgkJCSRhcHBlbmQgICAgICAgICAgID0gJ09SREVSIEJZIEZJRUxEKCBibG9nX2lkLCAnIC4gaW1wbG9kZSggJywnLCBhcnJheV9tYXAoICdpbnR2YWwnLCAkd2hlcmVbJ2Jsb2dfaWQnXSApICkgLiAnICknOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ25ldHdvcmsnXSApICkgewoJCQkkd2hlcmVbJ3NpdGVfaWQnXSA9ICRhc3NvY19hcmdzWyduZXR3b3JrJ107CgkJfQoKCQkkaXRlcmF0b3JfYXJncyA9IFsKCQkJJ3RhYmxlJyAgPT4gJHdwZGItPmJsb2dzLAoJCQknd2hlcmUnICA9PiAkd2hlcmUsCgkJCSdhcHBlbmQnID0+ICRhcHBlbmQsCgkJXTsKCgkJJGl0ZXJhdG9yID0gbmV3IFRhYmxlSXRlcmF0b3IoICRpdGVyYXRvcl9hcmdzICk7CgoJCSRpdGVyYXRvciA9IFV0aWxzXGl0ZXJhdG9yX21hcCgKCQkJJGl0ZXJhdG9yLAoJCQlmdW5jdGlvbiggJGJsb2cgKSB7CgkJCQkkYmxvZy0+dXJsID0gdHJhaWxpbmdzbGFzaGl0KCBnZXRfaG9tZV91cmwoICRibG9nLT5ibG9nX2lkICkgKTsKCQkJCXJldHVybiAkYmxvZzsKCQkJfQoJCSk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgJiYgJ2lkcycgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJJHNpdGVzICAgICA9IGl0ZXJhdG9yX3RvX2FycmF5KCAkaXRlcmF0b3IgKTsKCQkJJGlkcyAgICAgICA9IHdwX2xpc3RfcGx1Y2soICRzaXRlcywgJ2Jsb2dfaWQnICk7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgbnVsbCwgJ3NpdGUnICk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpZHMgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIG51bGwsICdzaXRlJyApOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaXRlcmF0b3IgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBcmNoaXZlcyBvbmUgb3IgbW9yZSBzaXRlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gYXJjaGl2ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgYXJjaGl2ZSAxMjMKCSAqICAgICBTdWNjZXNzOiBTaXRlIDEyMyBhcmNoaXZlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFyY2hpdmUoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAnYXJjaGl2ZWQnLCAxICk7Cgl9CgoJLyoqCgkgKiBVbmFyY2hpdmVzIG9uZSBvciBtb3JlIHNpdGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byB1bmFyY2hpdmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzaXRlIHVuYXJjaGl2ZSAxMjMKCSAqICAgICBTdWNjZXNzOiBTaXRlIDEyMyB1bmFyY2hpdmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5hcmNoaXZlKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ2FyY2hpdmVkJywgMCApOwoJfQoKCS8qKgoJICogQWN0aXZhdGVzIG9uZSBvciBtb3JlIHNpdGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBhY3RpdmF0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgYWN0aXZhdGUgMTIzCgkgKiAgICAgU3VjY2VzczogU2l0ZSAxMjMgYWN0aXZhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWN0aXZhdGUoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAnZGVsZXRlZCcsIDAgKTsKCX0KCgkvKioKCSAqIERlYWN0aXZhdGVzIG9uZSBvciBtb3JlIHNpdGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBkZWFjdGl2YXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBkZWFjdGl2YXRlIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIGRlYWN0aXZhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZSggJGFyZ3MgKSB7CgkJJHRoaXMtPnVwZGF0ZV9zaXRlX3N0YXR1cyggJGFyZ3MsICdkZWxldGVkJywgMSApOwoJfQoKCS8qKgoJICogTWFya3Mgb25lIG9yIG1vcmUgc2l0ZXMgYXMgc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gYmUgbWFya2VkIGFzIHNwYW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzaXRlIHNwYW0gMTIzCgkgKiAgICAgU3VjY2VzczogU2l0ZSAxMjMgbWFya2VkIGFzIHNwYW0uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzcGFtKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ3NwYW0nLCAxICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIG9uZSBvciBtb3JlIHNpdGVzIGZyb20gc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gcmVtb3ZlIGZyb20gc3BhbS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgdW5zcGFtIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIHJlbW92ZWQgZnJvbSBzcGFtLgoJICoKCSAqIEBzdWJjb21tYW5kIHVuc3BhbQoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zcGFtKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ3NwYW0nLCAwICk7Cgl9CgoJLyoqCgkgKiBTZXRzIG9uZSBvciBtb3JlIHNpdGVzIGFzIG1hdHVyZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gc2V0IGFzIG1hdHVyZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgbWF0dXJlIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIG1hcmtlZCBhcyBtYXR1cmUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtYXR1cmUoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAnbWF0dXJlJywgMSApOwoJfQoKCS8qKgoJICogU2V0cyBvbmUgb3IgbW9yZSBzaXRlcyBhcyBpbW1hdHVyZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gc2V0IGFzIHVubWF0dXJlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBnZW5lcmFsIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIG1hcmtlZCBhcyB1bm1hdHVyZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVubWF0dXJlKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ21hdHVyZScsIDAgKTsKCX0KCgkvKioKCSAqIFNldHMgb25lIG9yIG1vcmUgc2l0ZXMgYXMgcHVibGljLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBzZXQgYXMgcHVibGljLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBwdWJsaWMgMTIzCgkgKiAgICAgU3VjY2VzczogU2l0ZSAxMjMgbWFya2VkIGFzIHB1YmxpYy4KCSAqCgkgKiBAc3ViY29tbWFuZCBwdWJsaWMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldF9wdWJsaWMoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAncHVibGljJywgMSApOwoJfQoKCS8qKgoJICogU2V0cyBvbmUgb3IgbW9yZSBzaXRlcyBhcyBwcml2YXRlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBzZXQgYXMgcHJpdmF0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgcHJpdmF0ZSAxMjMKCSAqICAgICBTdWNjZXNzOiBTaXRlIDEyMyBtYXJrZWQgYXMgcHJpdmF0ZS4KCSAqCgkgKiBAc3ViY29tbWFuZCBwcml2YXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfcHJpdmF0ZSggJGFyZ3MgKSB7CgkJJHRoaXMtPnVwZGF0ZV9zaXRlX3N0YXR1cyggJGFyZ3MsICdwdWJsaWMnLCAwICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiB1cGRhdGVfc2l0ZV9zdGF0dXMoICRpZHMsICRwcmVmLCAkdmFsdWUgKSB7CgkJJHZhbHVlID0gKGludCkgJHZhbHVlOwoKCQlzd2l0Y2ggKCAkcHJlZiApIHsKCQkJY2FzZSAnYXJjaGl2ZWQnOgoJCQkJJGFjdGlvbiA9ICR2YWx1ZSA/ICdhcmNoaXZlZCcgOiAndW5hcmNoaXZlZCc7CgkJCQlicmVhazsKCQkJY2FzZSAnZGVsZXRlZCc6CgkJCQkkYWN0aW9uID0gJHZhbHVlID8gJ2RlYWN0aXZhdGVkJyA6ICdhY3RpdmF0ZWQnOwoJCQkJYnJlYWs7CgkJCWNhc2UgJ21hdHVyZSc6CgkJCQkkYWN0aW9uID0gJHZhbHVlID8gJ21hcmtlZCBhcyBtYXR1cmUnIDogJ21hcmtlZCBhcyB1bm1hdHVyZSc7CgkJCQlicmVhazsKCQkJY2FzZSAncHVibGljJzoKCQkJCSRhY3Rpb24gPSAkdmFsdWUgPyAnbWFya2VkIGFzIHB1YmxpYycgOiAnbWFya2VkIGFzIHByaXZhdGUnOwoJCQkJYnJlYWs7CgkJCWNhc2UgJ3NwYW0nOgoJCQkJJGFjdGlvbiA9ICR2YWx1ZSA/ICdtYXJrZWQgYXMgc3BhbScgOiAncmVtb3ZlZCBmcm9tIHNwYW0nOwoJCQkJYnJlYWs7CgkJfQoKCQlmb3JlYWNoICggJGlkcyBhcyAkc2l0ZV9pZCApIHsKCQkJJHNpdGUgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkc2l0ZV9pZCApOwoKCQkJaWYgKCBpc19tYWluX3NpdGUoICRzaXRlLT5ibG9nX2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdZb3UgYXJlIG5vdCBhbGxvd2VkIHRvIGNoYW5nZSB0aGUgbWFpbiBzaXRlLicgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkb2xkX3ZhbHVlID0gKGludCkgZ2V0X2Jsb2dfc3RhdHVzKCAkc2l0ZS0+YmxvZ19pZCwgJHByZWYgKTsKCgkJCWlmICggJHZhbHVlID09PSAkb2xkX3ZhbHVlICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiU2l0ZSB7JHNpdGUtPmJsb2dfaWR9IGFscmVhZHkgeyRhY3Rpb259LiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQl1cGRhdGVfYmxvZ19zdGF0dXMoICRzaXRlLT5ibG9nX2lkLCAkcHJlZiwgJHZhbHVlICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlNpdGUgeyRzaXRlLT5ibG9nX2lkfSB7JGFjdGlvbn0uIiApOwoJCX0KCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxFeGl0RXhjZXB0aW9uOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFVzZXIgYXMgVXNlckZldGNoZXI7CnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIENyZWF0ZXMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGxpc3RzIGFuZCByZXRyaWV2ZXMgYXBwbGljYXRpb24gcGFzc3dvcmRzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IHVzZXIgYXBwbGljYXRpb24gcGFzc3dvcmRzIGFuZCBvbmx5IHNob3cgYXBwIG5hbWUgYW5kIHBhc3N3b3JkIGhhc2gKICogICAgICQgd3AgdXNlciBhcHBsaWNhdGlvbi1wYXNzd29yZHMgbGlzdCAxMjMgLS1maWVsZHM9bmFtZSxwYXNzd29yZAogKiAgICAgKy0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbmFtZSAgIHwgcGFzc3dvcmQgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICAgICArLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBteWFwcCAgfCAkUCRCVkdlb3UxQ1VvdDExNFlvaEllbWdwd3hRQ3piOE8vIHwKICogICAgICstLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqCiAqICAgICAjIEdldCBhIHNwZWNpZmljIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGFuZCBvbmx5IHNob3cgYXBwIG5hbWUgYW5kIGNyZWF0ZWQgdGltZXN0YW1wCiAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIGdldCAxMjMgNjYzMzgyNGQtYzFkNy00Zjc5LTlkZDUtNDU4NmY3MzRkNjllIC0tZmllbGRzPW5hbWUsY3JlYXRlZAogKiAgICAgKy0tLS0tLS0tKy0tLS0tLS0tLS0tLSsKICogICAgIHwgbmFtZSAgIHwgY3JlYXRlZCAgICB8CiAqICAgICArLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwogKiAgICAgfCBteWFwcCAgfCAxNjM4Mzk1NjExIHwKICogICAgICstLS0tLS0tLSstLS0tLS0tLS0tLS0rCiAqCiAqICAgICAjIENyZWF0ZSB1c2VyIGFwcGxpY2F0aW9uIHBhc3N3b3JkCiAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIGNyZWF0ZSAxMjMgbXlhcHAKICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgYXBwbGljYXRpb24gcGFzc3dvcmQuCiAqICAgICBQYXNzd29yZDogWkcxYnhkeGR6alR3aHNZOHZLOGwxQzY1CiAqCiAqICAgICAjIE9ubHkgcHJpbnQgdGhlIHBhc3N3b3JkIHdpdGhvdXQgYW55IGNocm9tZQogKiAgICAgJCB3cCB1c2VyIGFwcGxpY2F0aW9uLXBhc3N3b3JkcyBjcmVhdGUgMTIzIG15YXBwIC0tcG9yY2VsYWluCiAqICAgICBaRzFieGR4ZHpqVHdoc1k4dks4bDFDNjUKICoKICogICAgICMgVXBkYXRlIGFuIGV4aXN0aW5nIGFwcGxpY2F0aW9uIHBhc3N3b3JkCiAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIHVwZGF0ZSAxMjMgNjYzMzgyNGQtYzFkNy00Zjc5LTlkZDUtNDU4NmY3MzRkNjllIC0tbmFtZT1uZXdhcHBuYW1lCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGFwcGxpY2F0aW9uIHBhc3N3b3JkLgogKgogKiAgICAgIyBDaGVjayBpZiBhbiBhcHBsaWNhdGlvbiBwYXNzd29yZCBmb3IgYSBnaXZlbiBhcHBsaWNhdGlvbiBleGlzdHMKICogICAgICQgd3AgdXNlciBhcHBsaWNhdGlvbi1wYXNzd29yZHMgZXhpc3RzIDEyMyBteWFwcAogKiAgICAgJCBlY2hvICQ/CiAqICAgICAxCiAqCiAqICAgICAjIEJhc2ggc2NyaXB0IGZvciBjaGVja2luZyB3aGV0aGVyIGFuIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGV4aXN0cyBhbmQgY3JlYXRpbmcgb25lIGlmIG5vdAogKiAgICAgaWYgISB3cCB1c2VyIGFwcGxpY2F0aW9uLXBhc3N3b3JkIGV4aXN0cyAxMjMgbXlhcHA7IHRoZW4KICogICAgICAgICBQQVNTV09SRD0kKHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmQgY3JlYXRlIDEyMyBteWFwcCAtLXBvcmNlbGFpbikKICogICAgIGZpCiAqLwpmaW5hbCBjbGFzcyBVc2VyX0FwcGxpY2F0aW9uX1Bhc3N3b3JkX0NvbW1hbmQgewoKCS8qKgoJICogTGlzdCBvZiBhcHBsaWNhdGlvbiBwYXNzd29yZCBmaWVsZHMuCgkgKgoJICogQHZhciBhcnJheTxzdHJpbmc+CgkgKi8KCWNvbnN0IEFQUExJQ0FUSU9OX1BBU1NXT1JEX0ZJRUxEUyA9IFsKCQkndXVpZCcsCgkJJ2FwcF9pZCcsCgkJJ25hbWUnLAoJCSdwYXNzd29yZCcsCgkJJ2NyZWF0ZWQnLAoJCSdsYXN0X3VzZWQnLAoJCSdsYXN0X2lwJywKCV07CgoJLyoqCgkgKiBMaXN0cyBhbGwgYXBwbGljYXRpb24gcGFzc3dvcmRzIGFzc29jaWF0ZWQgd2l0aCBhIHVzZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byBnZXQgYXBwbGljYXRpb24gcGFzc3dvcmRzIGZvci4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEZpbHRlciB0aGUgbGlzdCBieSBhIHNwZWNpZmljIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiBbLS1vcmRlcmJ5PTxmaWVsZHM+XQoJICogOiBTZXQgb3JkZXJieSB3aGljaCBmaWVsZC4KCSAqIC0tLQoJICogZGVmYXVsdDogY3JlYXRlZAoJICogb3B0aW9uczoKCSAqICAtIHV1aWQKCSAqICAtIGFwcF9pZAoJICogIC0gbmFtZQoJICogIC0gcGFzc3dvcmQKCSAqICAtIGNyZWF0ZWQKCSAqICAtIGxhc3RfdXNlZAoJICogIC0gbGFzdF9pcAoJICogLS0tCgkgKgoJICogWy0tb3JkZXI9PG9yZGVyPl0KCSAqIDogU2V0IGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIG9yZGVyLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZXNjCgkgKiBvcHRpb25zOgoJICogIC0gYXNjCgkgKiAgLSBkZXNjCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdXNlciBhcHBsaWNhdGlvbiBwYXNzd29yZHMgYW5kIG9ubHkgc2hvdyBhcHAgbmFtZSBhbmQgcGFzc3dvcmQgaGFzaAoJICogICAgICQgd3AgdXNlciBhcHBsaWNhdGlvbi1wYXNzd29yZHMgbGlzdCAxMjMgLS1maWVsZHM9bmFtZSxwYXNzd29yZAoJICogICAgICstLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgfCBwYXNzd29yZCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbXlhcHAgIHwgJFAkQlZHZW91MUNVb3QxMTRZb2hJZW1ncHd4UUN6YjhPLyB8CgkgKiAgICAgKy0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgIEluZGV4ZWQgYXJyYXkgb2YgcG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIHRoZSB1c2VyIGNvdWxkIG5vdCBiZSBmb3VuZC9wYXJzZWQuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkcyBjb3VsZCBub3QgYmUgcmV0cmlldmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJncyA9ICR0aGlzLT5yZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKTsKCgkJbGlzdCggJHVzZXJfaWQgKSA9ICRhcmdzOwoKCQkkYXBwbGljYXRpb25fcGFzc3dvcmRzID0gV1BfQXBwbGljYXRpb25fUGFzc3dvcmRzOjpnZXRfdXNlcl9hcHBsaWNhdGlvbl9wYXNzd29yZHMoICR1c2VyX2lkICk7CgoJCWlmICggJGFwcGxpY2F0aW9uX3Bhc3N3b3JkcyBpbnN0YW5jZW9mIFdQX0Vycm9yICkgewoJCQlXUF9DTEk6OmVycm9yKCAkYXBwbGljYXRpb25fcGFzc3dvcmRzICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXBwbGljYXRpb25fcGFzc3dvcmRzICkgKSB7CgkJCSRhcHBsaWNhdGlvbl9wYXNzd29yZHMgPSBbXTsKCQl9CgoJCSRvcmRlciAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnb3JkZXInICk7CgkJJG9yZGVyYnkgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdvcmRlcmJ5JyApOwoKCQl1c29ydCgKCQkJJGFwcGxpY2F0aW9uX3Bhc3N3b3JkcywKCQkJc3RhdGljIGZ1bmN0aW9uICggJGEsICRiICkgdXNlICggJG9yZGVyYnksICRvcmRlciApIHsKCQkJCS8vIFNvcnQgYXJyYXkuCgkJCQlyZXR1cm4gJ2FzYycgPT09ICRvcmRlcgoJCQkJCT8gJGFbICRvcmRlcmJ5IF0gPiAkYlsgJG9yZGVyYnkgXQoJCQkJCTogJGFbICRvcmRlcmJ5IF0gPCAkYlsgJG9yZGVyYnkgXTsKCQkJfQoJCSk7CgoJCSRmaWVsZHMgPSBzZWxmOjpBUFBMSUNBVElPTl9QQVNTV09SRF9GSUVMRFM7CgoJCS8vIEF2b2lkIGNvbmZ1c2lvbiByZWdhcmRpbmcgdGhlIGRhc2gvdW5kZXJzY29yZSB1c2FnZS4KCQlmb3JlYWNoICggWyAnYXBwLWlkJywgJ2xhc3QtdXNlZCcsICdsYXN0LWlwJyBdIGFzICRmbGFnICkgewoJCQlpZiAoIGFycmF5X2tleV9leGlzdHMoICRmbGFnLCAkYXNzb2NfYXJncyApICkgewoJCQkJJHVuZGVyc2NvcmVkX2ZsYWcgICAgICAgICAgICAgICAgPSBzdHJfcmVwbGFjZSggJy0nLCAnXycsICRmbGFnICk7CgkJCQkkYXNzb2NfYXJnc1sgJHVuZGVyc2NvcmVkX2ZsYWcgXSA9ICRhc3NvY19hcmdzWyAkZmxhZyBdOwoJCQkJdW5zZXQoICRhc3NvY19hcmdzWyAkZmxhZyBdICk7CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCAkZmllbGRzIGFzICRmaWVsZCApIHsKCQkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRmaWVsZCwgJGFzc29jX2FyZ3MgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdmFsdWUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICRmaWVsZCApOwoKCQkJJGFwcGxpY2F0aW9uX3Bhc3N3b3JkcyA9IGFycmF5X2ZpbHRlcigKCQkJCSRhcHBsaWNhdGlvbl9wYXNzd29yZHMsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCAkYXBwbGljYXRpb25fcGFzc3dvcmQgKSB1c2UgKCAkZmllbGQsICR2YWx1ZSApIHsKCQkJCQlyZXR1cm4gJGFwcGxpY2F0aW9uX3Bhc3N3b3JkWyAkZmllbGQgXSA9PT0gJHZhbHVlOwoJCQkJfQoJCQkpOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJJGZpZWxkcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICRmaWVsZHMgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkYXBwbGljYXRpb25fcGFzc3dvcmRzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgc3BlY2lmaWMgYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byBnZXQgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGZvci4KCSAqCgkgKiA8dXVpZD4KCSAqIDogVGhlIHVuaXZlcnNhbGx5IHVuaXF1ZSBJRCBvZiB0aGUgYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGEgc3BlY2lmaWMgYXBwbGljYXRpb24gcGFzc3dvcmQgYW5kIG9ubHkgc2hvdyBhcHAgbmFtZSBhbmQgY3JlYXRlZCB0aW1lc3RhbXAKCSAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIGdldCAxMjMgNjYzMzgyNGQtYzFkNy00Zjc5LTlkZDUtNDU4NmY3MzRkNjllIC0tZmllbGRzPW5hbWUsY3JlYXRlZAoJICogICAgICstLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgfCBjcmVhdGVkICAgIHwKCSAqICAgICArLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbXlhcHAgIHwgMTYzODM5NTYxMSB8CgkgKiAgICAgKy0tLS0tLS0tKy0tLS0tLS0tLS0tLSsKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgICAgICAgSW5kZXhlZCBhcnJheSBvZiBwb3NpdGlvbmFsIGFyZ3VtZW50cy4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhc3NvY2lhdGl2ZSBhcmd1bWVudHMuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkcyBjb3VsZCBub3QgYmUgcmV0cmlldmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFyZ3MgPSAkdGhpcy0+cmVwbGFjZV9sb2dpbl93aXRoX3VzZXJfaWQoICRhcmdzICk7CgoJCWxpc3QoICR1c2VyX2lkLCAkdXVpZCApID0gJGFyZ3M7CgoJCSRhcHBsaWNhdGlvbl9wYXNzd29yZCA9IFdQX0FwcGxpY2F0aW9uX1Bhc3N3b3Jkczo6Z2V0X3VzZXJfYXBwbGljYXRpb25fcGFzc3dvcmQoICR1c2VyX2lkLCAkdXVpZCApOwoKCQlpZiAoICRhcHBsaWNhdGlvbl9wYXNzd29yZCBpbnN0YW5jZW9mIFdQX0Vycm9yICkgewoJCQlXUF9DTEk6OmVycm9yKCAkYXBwbGljYXRpb25fcGFzc3dvcmQgKTsKCQl9CgoJCWlmICggbnVsbCA9PT0gJGFwcGxpY2F0aW9uX3Bhc3N3b3JkICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gYXBwbGljYXRpb24gcGFzc3dvcmQgZm91bmQgZm9yIHRoaXMgdXNlciBJRCBhbmQgVVVJRC4nICk7CgkJfQoKCQkkZmllbGRzID0gc2VsZjo6QVBQTElDQVRJT05fUEFTU1dPUkRfRklFTERTOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkZmllbGRzID0gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJGZpZWxkcyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoIFsgJGFwcGxpY2F0aW9uX3Bhc3N3b3JkIF0gKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byBjcmVhdGUgYSBuZXcgYXBwbGljYXRpb24gcGFzc3dvcmQgZm9yLgoJICoKCSAqIDxhcHAtbmFtZT4KCSAqIDogVW5pcXVlIG5hbWUgb2YgdGhlIGFwcGxpY2F0aW9uIHRvIGNyZWF0ZSBhbiBhcHBsaWNhdGlvbiBwYXNzd29yZCBmb3IuCgkgKgoJICogWy0tYXBwLWlkPTxhcHAtaWQ+XQoJICogOiBBcHBsaWNhdGlvbiBJRCB0byBhdHRyaWJ1dGUgdG8gdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkLgoJICoKCSAqIFstLXBvcmNlbGFpbl0KCSAqIDogT3V0cHV0IGp1c3QgdGhlIG5ldyBwYXNzd29yZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSB1c2VyIGFwcGxpY2F0aW9uIHBhc3N3b3JkCgkgKiAgICAgJCB3cCB1c2VyIGFwcGxpY2F0aW9uLXBhc3N3b3JkcyBjcmVhdGUgMTIzIG15YXBwCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCBhcHBsaWNhdGlvbiBwYXNzd29yZC4KCSAqICAgICBQYXNzd29yZDogWkcxYnhkeGR6alR3aHNZOHZLOGwxQzY1CgkgKgoJICogICAgICMgT25seSBwcmludCB0aGUgcGFzc3dvcmQgd2l0aG91dCBhbnkgY2hyb21lCgkgKiAgICAgJCB3cCB1c2VyIGFwcGxpY2F0aW9uLXBhc3N3b3JkcyBjcmVhdGUgMTIzIG15YXBwIC0tcG9yY2VsYWluCgkgKiAgICAgWkcxYnhkeGR6alR3aHNZOHZLOGwxQzY1CgkgKgoJICogICAgICMgQ3JlYXRlIHVzZXIgYXBwbGljYXRpb24gd2l0aCBhIGN1c3RvbSBhcHBsaWNhdGlvbiBJRCBmb3IgaW50ZXJuYWwgdHJhY2tpbmcKCSAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIGNyZWF0ZSAxMjMgbXlhcHAgLS1hcHAtaWQ9NDIgLS1wb3JjZWxhaW4KCSAqICAgICBaRzFieGR4ZHpqVHdoc1k4dks4bDFDNjUKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgICAgICAgSW5kZXhlZCBhcnJheSBvZiBwb3NpdGlvbmFsIGFyZ3VtZW50cy4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhc3NvY2lhdGl2ZSBhcmd1bWVudHMuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGNvdWxkIG5vdCBiZSBjcmVhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gY3JlYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFyZ3MgPSAkdGhpcy0+cmVwbGFjZV9sb2dpbl93aXRoX3VzZXJfaWQoICRhcmdzICk7CgoJCWxpc3QoICR1c2VyX2lkLCAkYXBwX25hbWUgKSA9ICRhcmdzOwoKCQkkYXBwX2lkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYXBwLWlkJywgJycgKTsKCgkJJGFyZ3VtZW50cyA9IFsKCQkJJ25hbWUnICAgPT4gJGFwcF9uYW1lLAoJCQknYXBwX2lkJyA9PiAkYXBwX2lkLAoJCV07CgoJCSRyZXN1bHQgPSBXUF9BcHBsaWNhdGlvbl9QYXNzd29yZHM6OmNyZWF0ZV9uZXdfYXBwbGljYXRpb25fcGFzc3dvcmQoICR1c2VyX2lkLCAkYXJndW1lbnRzICk7CgoJCWlmICggJHJlc3VsdCBpbnN0YW5jZW9mIFdQX0Vycm9yICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0ICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicsIGZhbHNlICkgKSB7CgkJCVdQX0NMSTo6bGluZSggJHJlc3VsdFswXSApOwoJCQlXUF9DTEk6OmhhbHQoIDAgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0NyZWF0ZWQgYXBwbGljYXRpb24gcGFzc3dvcmQuJyApOwoJCVdQX0NMSTo6bGluZSggIlBhc3N3b3JkOiB7JHJlc3VsdFswXX0iICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIGFuIGV4aXN0aW5nIGFwcGxpY2F0aW9uIHBhc3N3b3JkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gdXBkYXRlIHRoZSBhcHBsaWNhdGlvbiBwYXNzd29yZCBmb3IuCgkgKgoJICogPHV1aWQ+CgkgKiA6IFRoZSB1bml2ZXJzYWxseSB1bmlxdWUgSUQgb2YgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkLgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogVXBkYXRlIHRoZSA8ZmllbGQ+IHdpdGggYSBuZXcgPHZhbHVlPi4gQ3VycmVudGx5IHN1cHBvcnRlZCBmaWVsZHM6IG5hbWUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgYW4gZXhpc3RpbmcgYXBwbGljYXRpb24gcGFzc3dvcmQKCSAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIHVwZGF0ZSAxMjMgNjYzMzgyNGQtYzFkNy00Zjc5LTlkZDUtNDU4NmY3MzRkNjllIC0tbmFtZT1uZXdhcHBuYW1lCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBhcHBsaWNhdGlvbiBwYXNzd29yZC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgICAgICAgSW5kZXhlZCBhcnJheSBvZiBwb3NpdGlvbmFsIGFyZ3VtZW50cy4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhc3NvY2lhdGl2ZSBhcmd1bWVudHMuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGNvdWxkIG5vdCBiZSBjcmVhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFyZ3MgPSAkdGhpcy0+cmVwbGFjZV9sb2dpbl93aXRoX3VzZXJfaWQoICRhcmdzICk7CgoJCWxpc3QoICR1c2VyX2lkLCAkdXVpZCApID0gJGFyZ3M7CgoJCSRyZXN1bHQgPSBXUF9BcHBsaWNhdGlvbl9QYXNzd29yZHM6OnVwZGF0ZV9hcHBsaWNhdGlvbl9wYXNzd29yZCggJHVzZXJfaWQsICR1dWlkLCAkYXNzb2NfYXJncyApOwoKCQlpZiAoICRyZXN1bHQgaW5zdGFuY2VvZiBXUF9FcnJvciApIHsKCQkJV1BfQ0xJOjplcnJvciggJHJlc3VsdCApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAnVXBkYXRlZCBhcHBsaWNhdGlvbiBwYXNzd29yZC4nICk7Cgl9CgoJLyoqCgkgKiBSZWNvcmQgdXNhZ2Ugb2YgYW4gYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byB1cGRhdGUgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGZvci4KCSAqCgkgKiA8dXVpZD4KCSAqIDogVGhlIHVuaXZlcnNhbGx5IHVuaXF1ZSBJRCBvZiB0aGUgYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZWNvcmQgdXNhZ2Ugb2YgYW4gYXBwbGljYXRpb24gcGFzc3dvcmQKCSAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIHJlY29yZC11c2FnZSAxMjMgNjYzMzgyNGQtYzFkNy00Zjc5LTlkZDUtNDU4NmY3MzRkNjllCgkgKiAgICAgU3VjY2VzczogUmVjb3JkZWQgYXBwbGljYXRpb24gcGFzc3dvcmQgdXNhZ2UuCgkgKgoJICogQHN1YmNvbW1hbmQgcmVjb3JkLXVzYWdlCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgIEluZGV4ZWQgYXJyYXkgb2YgcG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIHRoZSBhcHBsaWNhdGlvbiBwYXNzd29yZCBjb3VsZCBub3QgYmUgY3JlYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlY29yZF91c2FnZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcmdzID0gJHRoaXMtPnJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApOwoKCQlsaXN0KCAkdXNlcl9pZCwgJHV1aWQgKSA9ICRhcmdzOwoKCQkkcmVzdWx0ID0gV1BfQXBwbGljYXRpb25fUGFzc3dvcmRzOjpyZWNvcmRfYXBwbGljYXRpb25fcGFzc3dvcmRfdXNhZ2UoICR1c2VyX2lkLCAkdXVpZCApOwoKCQlpZiAoICRyZXN1bHQgaW5zdGFuY2VvZiBXUF9FcnJvciApIHsKCQkJV1BfQ0xJOjplcnJvciggJHJlc3VsdCApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAnUmVjb3JkZWQgYXBwbGljYXRpb24gcGFzc3dvcmQgdXNhZ2UuJyApOwoJfQoKCS8qKgoJICogRGVsZXRlIGFuIGV4aXN0aW5nIGFwcGxpY2F0aW9uIHBhc3N3b3JkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gZGVsZXRlIHRoZSBhcHBsaWNhdGlvbiBwYXNzd29yZCBmb3IuCgkgKgoJICogWzx1dWlkPi4uLl0KCSAqIDogQ29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgVVVJRHMgb2YgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkcyB0byBkZWxldGUuCgkgKgoJICogWy0tYWxsXQoJICogOiBEZWxldGUgYWxsIG9mIHRoZSB1c2VyJ3MgYXBwbGljYXRpb24gcGFzc3dvcmQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZWNvcmQgdXNhZ2Ugb2YgYW4gYXBwbGljYXRpb24gcGFzc3dvcmQKCSAqICAgICAkIHdwIHVzZXIgYXBwbGljYXRpb24tcGFzc3dvcmRzIHJlY29yZC11c2FnZSAxMjMgNjYzMzgyNGQtYzFkNy00Zjc5LTlkZDUtNDU4NmY3MzRkNjllCgkgKiAgICAgU3VjY2VzczogUmVjb3JkZWQgYXBwbGljYXRpb24gcGFzc3dvcmQgdXNhZ2UuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgIEluZGV4ZWQgYXJyYXkgb2YgcG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIHRoZSBhcHBsaWNhdGlvbiBwYXNzd29yZCBjb3VsZCBub3QgYmUgY3JlYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcmdzID0gJHRoaXMtPnJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApOwoKCQkkdXNlcl9pZCA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSRhbGwgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkY291bnQgICA9IGNvdW50KCAkYXJncyApOwoKCQlpZiAoICggMCA8ICRjb3VudCAmJiB0cnVlID09PSAkYWxsICkgfHwgKCAwID09PSAkY291bnQgJiYgdHJ1ZSAhPT0gJGFsbCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnWW91IG5lZWQgdG8gc3BlY2lmeSBlaXRoZXIgb25lIG9yIG1vcmUgVVVJRFMgb3IgcHJvdmlkZSB0aGUgLS1hbGwgZmxhZycgKTsKCQl9CgoJCWlmICggdHJ1ZSA9PT0gJGFsbCApIHsKCQkJJHJlc3VsdCA9IFdQX0FwcGxpY2F0aW9uX1Bhc3N3b3Jkczo6ZGVsZXRlX2FsbF9hcHBsaWNhdGlvbl9wYXNzd29yZHMoICR1c2VyX2lkICk7CgoJCQlpZiAoICRyZXN1bHQgaW5zdGFuY2VvZiBXUF9FcnJvciApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRyZXN1bHQgKTsKCQkJfQoKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnRGVsZXRlZCBhbGwgYXBwbGljYXRpb24gcGFzc3dvcmRzLicgKTsKCQkJV1BfQ0xJOjpoYWx0KCAwICk7CgkJfQoKCQkkZXJyb3JzID0gMDsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJHV1aWQgKSB7CgkJCSRyZXN1bHQgPSBXUF9BcHBsaWNhdGlvbl9QYXNzd29yZHM6OmRlbGV0ZV9hcHBsaWNhdGlvbl9wYXNzd29yZCggJHVzZXJfaWQsICR1dWlkICk7CgoJCQlpZiAoICRyZXN1bHQgaW5zdGFuY2VvZiBXUF9FcnJvciApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkZhaWxlZCB0byBkZWxldGUgVVVJRCB7JHV1aWR9OiAiIC4gJHJlc3VsdC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCQkJJGVycm9ycysrOwoJCQl9CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoCgkJCXNwcmludGYoCgkJCQknRGVsZXRlZCAlZCBvZiAlZCBhcHBsaWNhdGlvbiAlcy4nLAoJCQkJJGNvdW50IC0gJGVycm9ycywKCQkJCSRjb3VudCwKCQkJCVV0aWxzXHBsdXJhbGl6ZSggJ3Bhc3N3b3JkJywgJGNvdW50ICkKCQkJKQoJCSk7CgoJCVdQX0NMSTo6aGFsdCggMCA9PT0gJGVycm9ycyA/IDAgOiAxICk7Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciBhbiBhcHBsaWNhdGlvbiBwYXNzd29yZCBmb3IgYSBnaXZlbiBhcHBsaWNhdGlvbiBleGlzdHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byBjaGVjayB0aGUgZXhpc3RlbmNlIG9mIGFuIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGZvci4KCSAqCgkgKiA8YXBwLW5hbWU+CgkgKiA6IE5hbWUgb2YgdGhlIGFwcGxpY2F0aW9uIHRvIGNoZWNrIHRoZSBleGlzdGVuY2Ugb2YgYW4gYXBwbGljYXRpb24gcGFzc3dvcmQgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgaWYgYW4gYXBwbGljYXRpb24gcGFzc3dvcmQgZm9yIGEgZ2l2ZW4gYXBwbGljYXRpb24gZXhpc3RzCgkgKiAgICAgJCB3cCB1c2VyIGFwcGxpY2F0aW9uLXBhc3N3b3JkcyBleGlzdHMgMTIzIG15YXBwCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqICAgICAjIEJhc2ggc2NyaXB0IGZvciBjaGVja2luZyB3aGV0aGVyIGFuIGFwcGxpY2F0aW9uIHBhc3N3b3JkIGV4aXN0cyBhbmQgY3JlYXRpbmcgb25lIGlmIG5vdAoJICogICAgIGlmICEgd3AgdXNlciBhcHBsaWNhdGlvbi1wYXNzd29yZCBleGlzdHMgMTIzIG15YXBwOyB0aGVuCgkgKiAgICAgICAgIFBBU1NXT1JEPSQod3AgdXNlciBhcHBsaWNhdGlvbi1wYXNzd29yZCBjcmVhdGUgMTIzIG15YXBwIC0tcG9yY2VsYWluKQoJICogICAgIGZpCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgIEluZGV4ZWQgYXJyYXkgb2YgcG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIHRoZSBhcHBsaWNhdGlvbiBwYXNzd29yZCBjb3VsZCBub3QgYmUgY3JlYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4aXN0cyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcmdzID0gJHRoaXMtPnJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApOwoKCQlsaXN0KCAkdXNlcl9pZCwgJGFwcF9uYW1lICkgPSAkYXJnczsKCgkJJHJlc3VsdCA9ICR0aGlzLT5hcHBsaWNhdGlvbl9uYW1lX2V4aXN0c19mb3JfdXNlciggJHVzZXJfaWQsICRhcHBfbmFtZSApOwoKCQlpZiAoICRyZXN1bHQgaW5zdGFuY2VvZiBXUF9FcnJvciApIHsKCQkJV1BfQ0xJOjplcnJvciggJHJlc3VsdCApOwoJCX0KCgkJV1BfQ0xJOjpoYWx0KCAkcmVzdWx0ID8gMCA6IDEgKTsKCX0KCgkvKioKCSAqIFJlcGxhY2VzIHVzZXJfbG9naW4gdmFsdWUgd2l0aCB1c2VyIElELgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhcmd1bWVudHMuCgkgKiBAcmV0dXJuIGFycmF5IEFzc29jaWF0aXZlIGFycmF5IG9mIGFyZ3VtZW50cyB3aXRoIHRoZSB1c2VyIGxvZ2luIHJlcGxhY2VkIHdpdGggYW4gSUQuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIHVzZXIgaXMgbm90IGZvdW5kLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApIHsKCQkkdXNlciAgICA9ICggbmV3IFVzZXJGZXRjaGVyKCkgKS0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSRhcmdzWzBdID0gJHVzZXItPklEOwoKCQlyZXR1cm4gJGFyZ3M7Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYXBwbGljYXRpb24gbmFtZSBleGlzdHMgZm9yIHRoZSBnaXZlbiB1c2VyLgoJICoKCSAqIFRoaXMgaXMgYSBwb2x5ZmlsbCBmb3IgV1BfQXBwbGljYXRpb25fUGFzc3dvcmRzOjpnZXRfdXNlcl9hcHBsaWNhdGlvbl9wYXNzd29yZHMoKSwgd2hpY2ggd2FzIG9ubHkgYWRkZWQgZm9yCgkgKiBXb3JkUHJlc3MgNS43KywgYnV0IHdlJ3JlIGFscmVhZHkgc3VwcG9ydGluZyBhcHBsaWNhdGlvbiBwYXNzd29yZHMgZm9yIFdvcmRQcmVzcyA1LjYrLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJHVzZXJfaWQgIFVzZXIgSUQgdG8gY2hlY2sgdGhlIGFwcGxpY2F0aW9uIHBhc3N3b3JkcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRhcHBfbmFtZSBBcHBsaWNhdGlvbiBuYW1lIHRvIGxvb2sgZm9yLgoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYXBwbGljYXRpb25fbmFtZV9leGlzdHNfZm9yX3VzZXIoICR1c2VyX2lkLCAkYXBwX25hbWUgKSB7CgkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc1LjcnLCAnPCcgKSApIHsKCQkJJHBhc3N3b3JkcyA9IFdQX0FwcGxpY2F0aW9uX1Bhc3N3b3Jkczo6Z2V0X3VzZXJfYXBwbGljYXRpb25fcGFzc3dvcmRzKCAkdXNlcl9pZCApOwoKCQkJZm9yZWFjaCAoICRwYXNzd29yZHMgYXMgJHBhc3N3b3JkICkgewoJCQkJaWYgKCBzdHJ0b2xvd2VyKCAkcGFzc3dvcmRbJ25hbWUnXSApID09PSBzdHJ0b2xvd2VyKCAkbmFtZSApICkgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gV1BfQXBwbGljYXRpb25fUGFzc3dvcmRzOjphcHBsaWNhdGlvbl9uYW1lX2V4aXN0c19mb3JfdXNlciggJHVzZXJfaWQsICRhcHBfbmFtZSApOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoVGVybXM7CnVzZSBXUF9DTElcRmV0Y2hlcnNcUG9zdCBhcyBQb3N0RmV0Y2hlcjsKCi8qKgogKiBBZGRzLCB1cGRhdGVzLCByZW1vdmVzLCBhbmQgbGlzdHMgcG9zdCB0ZXJtcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHBvc3QgdGVybXMKICogICAgICQgd3AgcG9zdCB0ZXJtIHNldCAxMjMgdGVzdCBjYXRlZ29yeQogKiAgICAgU3VjY2VzczogU2V0IHRlcm1zLgogKi8KY2xhc3MgUG9zdF9UZXJtX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aFRlcm1zIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAncG9zdCc7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFBvc3RGZXRjaGVyKCk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9vYmplY3RfdHlwZSgpIHsKCQkkcG9zdCA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICR0aGlzLT5nZXRfb2JqX2lkKCkgKTsKCgkJcmV0dXJuICRwb3N0LT5wb3N0X3R5cGU7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRmV0Y2hlcnNcVXNlciBhcyBVc2VyRmV0Y2hlcjsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogRGVzdHJveXMgYW5kIGxpc3RzIGEgdXNlcidzIHNlc3Npb25zLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGEgdXNlcidzIHNlc3Npb25zLgogKiAgICAgJCB3cCB1c2VyIHNlc3Npb24gbGlzdCBhZG1pbkBleGFtcGxlLmNvbSAtLWZvcm1hdD1jc3YKICogICAgIGxvZ2luX3RpbWUsZXhwaXJhdGlvbl90aW1lLGlwLHVhCiAqICAgICAiMjAxNi0wMS0wMSAxMjozNDo1NiIsIjIwMTYtMDItMDEgMTI6MzQ6NTYiLDEyNy4wLjAuMSwiTW96aWxsYS81LjAuLi4iCiAqCiAqICAgICAjIERlc3Ryb3kgdGhlIG1vc3QgcmVjZW50IHNlc3Npb24gb2YgdGhlIGdpdmVuIHVzZXIuCiAqICAgICAkIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IGFkbWluCiAqICAgICBTdWNjZXNzOiBEZXN0cm95ZWQgc2Vzc2lvbi4gMyBzZXNzaW9ucyByZW1haW5pbmcuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgVXNlcl9TZXNzaW9uX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gWwoJCSd0b2tlbicsCgkJJ2xvZ2luX3RpbWUnLAoJCSdleHBpcmF0aW9uX3RpbWUnLAoJCSdpcCcsCgkJJ3VhJywKCV07CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFVzZXJGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBEZXN0cm95IGEgc2Vzc2lvbiBmb3IgdGhlIGdpdmVuIHVzZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBVc2VyIElELCB1c2VyIGVtYWlsLCBvciB1c2VyIGxvZ2luLgoJICoKCSAqIFs8dG9rZW4+XQoJICogOiBUaGUgdG9rZW4gb2YgdGhlIHNlc3Npb24gdG8gZGVzdHJveS4gRGVmYXVsdHMgdG8gdGhlIG1vc3QgcmVjZW50bHkgY3JlYXRlZCBzZXNzaW9uLgoJICoKCSAqIFstLWFsbF0KCSAqIDogRGVzdHJveSBhbGwgb2YgdGhlIHVzZXIncyBzZXNzaW9ucy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlc3Ryb3kgdGhlIG1vc3QgcmVjZW50IHNlc3Npb24gb2YgdGhlIGdpdmVuIHVzZXIuCgkgKiAgICAgJCB3cCB1c2VyIHNlc3Npb24gZGVzdHJveSBhZG1pbgoJICogICAgIFN1Y2Nlc3M6IERlc3Ryb3llZCBzZXNzaW9uLiAzIHNlc3Npb25zIHJlbWFpbmluZy4KCSAqCgkgKiAgICAgIyBEZXN0cm95IGEgc3BlY2lmaWMgc2Vzc2lvbiBvZiB0aGUgZ2l2ZW4gdXNlci4KCSAqICAgICAkIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IGFkbWluIGUwNzNhZDg1NDBhOWMyLi4uCgkgKiAgICAgU3VjY2VzczogRGVzdHJveWVkIHNlc3Npb24uIDIgc2Vzc2lvbnMgcmVtYWluaW5nLgoJICoKCSAqICAgICAjIERlc3Ryb3kgYWxsIHRoZSBzZXNzaW9ucyBvZiB0aGUgZ2l2ZW4gdXNlci4KCSAqICAgICAkIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IGFkbWluIC0tYWxsCgkgKiAgICAgU3VjY2VzczogRGVzdHJveWVkIGFsbCBzZXNzaW9ucy4KCSAqCgkgKiAgICAgIyBEZXN0cm95IGFsbCBzZXNzaW9ucyBmb3IgYWxsIHVzZXJzLgoJICogICAgICQgd3AgdXNlciBsaXN0IC0tZmllbGQ9SUQgfCB4YXJncyAtbiAxIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IC0tYWxsCgkgKiAgICAgU3VjY2VzczogRGVzdHJveWVkIGFsbCBzZXNzaW9ucy4KCSAqICAgICBTdWNjZXNzOiBEZXN0cm95ZWQgYWxsIHNlc3Npb25zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVzdHJveSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkdG9rZW4gICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXJncywgMSwgbnVsbCApOwoJCSRhbGwgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkbWFuYWdlciA9IFdQX1Nlc3Npb25fVG9rZW5zOjpnZXRfaW5zdGFuY2UoICR1c2VyLT5JRCApOwoKCQlpZiAoICR0b2tlbiAmJiAkYWxsICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlIC0tYWxsIGZsYWcgY2Fubm90IGJlIHNwZWNpZmllZCBhbG9uZyB3aXRoIGEgc2Vzc2lvbiB0b2tlbi4nICk7CgkJfQoKCQlpZiAoICRhbGwgKSB7CgkJCSRtYW5hZ2VyLT5kZXN0cm95X2FsbCgpOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdEZXN0cm95ZWQgYWxsIHNlc3Npb25zLicgKTsKCQkJcmV0dXJuOwoJCX0KCgkJJHNlc3Npb25zID0gJHRoaXMtPmdldF9hbGxfc2Vzc2lvbnMoICRtYW5hZ2VyICk7CgoJCWlmICggISAkdG9rZW4gKSB7CgkJCWlmICggZW1wdHkoICRzZXNzaW9ucyApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnTm8gc2Vzc2lvbnMgdG8gZGVzdHJveS4nICk7CgkJCX0KCQkJJGxhc3QgID0gZW5kKCAkc2Vzc2lvbnMgKTsKCQkJJHRva2VuID0gJGxhc3RbJ3Rva2VuJ107CgkJfQoKCQlpZiAoICEgaXNzZXQoICRzZXNzaW9uc1sgJHRva2VuIF0gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1Nlc3Npb24gbm90IGZvdW5kLicgKTsKCQl9CgoJCSR0aGlzLT5kZXN0cm95X3Nlc3Npb24oICRtYW5hZ2VyLCAkdG9rZW4gKTsKCQkkcmVtYWluaW5nID0gY291bnQoICRtYW5hZ2VyLT5nZXRfYWxsKCkgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAiRGVzdHJveWVkIHNlc3Npb24uIHskcmVtYWluaW5nfSByZW1haW5pbmcuIiApOwoJfQoKCS8qKgoJICogTGlzdCBzZXNzaW9ucyBmb3IgdGhlIGdpdmVuIHVzZXIuCgkgKgoJICogTm90ZTogVGhlIGB0b2tlbmAgZmllbGQgZG9lcyBub3QgcmV0dXJuIHRoZSBhY3R1YWwgdG9rZW4sIGJ1dCBhIGhhc2ggb2YKCSAqIGl0LiBUaGUgcmVhbCB0b2tlbiBpcyBub3QgcGVyc2lzdGVkIGFuZCBjYW4gb25seSBiZSBmb3VuZCBpbiB0aGUKCSAqIGNvcnJlc3BvbmRpbmcgY29va2llcyBvbiB0aGUgY2xpZW50IHNpZGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBVc2VyIElELCB1c2VyIGVtYWlsLCBvciB1c2VyIGxvZ2luLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqICAgLSBjb3VudAoJICogICAtIGlkcwoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHNlc3Npb246CgkgKgoJICogKiB0b2tlbgoJICogKiBsb2dpbl90aW1lCgkgKiAqIGV4cGlyYXRpb25fdGltZQoJICogKiBpcAoJICogKiB1YQoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBleHBpcmF0aW9uCgkgKiAqIGxvZ2luCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGEgdXNlcidzIHNlc3Npb25zLgoJICogICAgICQgd3AgdXNlciBzZXNzaW9uIGxpc3QgYWRtaW5AZXhhbXBsZS5jb20gLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbG9naW5fdGltZSxleHBpcmF0aW9uX3RpbWUsaXAsdWEKCSAqICAgICAiMjAxNi0wMS0wMSAxMjozNDo1NiIsIjIwMTYtMDItMDEgMTI6MzQ6NTYiLDEyNy4wLjAuMSwiTW96aWxsYS81LjAuLi4iCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdXNlciAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJG1hbmFnZXIgICA9IFdQX1Nlc3Npb25fVG9rZW5zOjpnZXRfaW5zdGFuY2UoICR1c2VyLT5JRCApOwoJCSRzZXNzaW9ucyAgPSAkdGhpcy0+Z2V0X2FsbF9zZXNzaW9ucyggJG1hbmFnZXIgKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQllY2hvIGltcGxvZGUoICcgJywgYXJyYXlfa2V5cyggJHNlc3Npb25zICkgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkc2Vzc2lvbnMgKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9hbGxfc2Vzc2lvbnMoIFdQX1Nlc3Npb25fVG9rZW5zICRtYW5hZ2VyICkgewoJCS8vIE1ha2UgdGhlIHByaXZhdGUgc2Vzc2lvbiBkYXRhIGFjY2Vzc2libGUgdG8gV1AtQ0xJCgkJJGdldF9zZXNzaW9ucyA9IG5ldyBSZWZsZWN0aW9uTWV0aG9kKCAkbWFuYWdlciwgJ2dldF9zZXNzaW9ucycgKTsKCQkkZ2V0X3Nlc3Npb25zLT5zZXRBY2Nlc3NpYmxlKCB0cnVlICk7CgkJJHNlc3Npb25zID0gJGdldF9zZXNzaW9ucy0+aW52b2tlKCAkbWFuYWdlciApOwoKCQlhcnJheV93YWxrKAoJCQkkc2Vzc2lvbnMsCgkJCWZ1bmN0aW9uKCAmJHNlc3Npb24sICR0b2tlbiApIHsKCQkJCSRzZXNzaW9uWyd0b2tlbiddICAgICAgICAgICA9ICR0b2tlbjsKCQkJCSRzZXNzaW9uWydsb2dpbl90aW1lJ10gICAgICA9IGRhdGUoICdZLW0tZCBIOmk6cycsICRzZXNzaW9uWydsb2dpbiddICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkJCSRzZXNzaW9uWydleHBpcmF0aW9uX3RpbWUnXSA9IGRhdGUoICdZLW0tZCBIOmk6cycsICRzZXNzaW9uWydleHBpcmF0aW9uJ10gKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCQl9CgkJKTsKCgkJcmV0dXJuICRzZXNzaW9uczsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzdHJveV9zZXNzaW9uKCBXUF9TZXNzaW9uX1Rva2VucyAkbWFuYWdlciwgJHRva2VuICkgewoJCSR1cGRhdGVfc2Vzc2lvbiA9IG5ldyBSZWZsZWN0aW9uTWV0aG9kKCAkbWFuYWdlciwgJ3VwZGF0ZV9zZXNzaW9uJyApOwoJCSR1cGRhdGVfc2Vzc2lvbi0+c2V0QWNjZXNzaWJsZSggdHJ1ZSApOwoJCXJldHVybiAkdXBkYXRlX3Nlc3Npb24tPmludm9rZSggJG1hbmFnZXIsICR0b2tlbiwgbnVsbCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmZpZWxkcyApOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxFbnRpdHlcUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlcjsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcRW50aXR5XFV0aWxzIGFzIEVudGl0eVV0aWxzOwoKLyoqCiAqIEFkZHMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGFuZCBsaXN0cyBzaXRlIG9wdGlvbnMgaW4gYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBHZXQgc2l0ZSByZWdpc3RyYXRpb24KICogICAgICQgd3Agc2l0ZSBvcHRpb24gZ2V0IHJlZ2lzdHJhdGlvbgogKiAgICAgbm9uZQogKgogKiAgICAgIyBBZGQgc2l0ZSBvcHRpb24KICogICAgICQgd3Agc2l0ZSBvcHRpb24gYWRkIG15X29wdGlvbiBmb29iYXIKICogICAgIFN1Y2Nlc3M6IEFkZGVkICdteV9vcHRpb24nIHNpdGUgb3B0aW9uLgogKgogKiAgICAgIyBVcGRhdGUgc2l0ZSBvcHRpb24KICogICAgICQgd3Agc2l0ZSBvcHRpb24gdXBkYXRlIG15X29wdGlvbiAneyJmb28iOiAiYmFyIn0nIC0tZm9ybWF0PWpzb24KICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ215X29wdGlvbicgc2l0ZSBvcHRpb24uCiAqCiAqICAgICAjIERlbGV0ZSBzaXRlIG9wdGlvbgogKiAgICAgJCB3cCBzaXRlIG9wdGlvbiBkZWxldGUgbXlfb3B0aW9uCiAqICAgICBTdWNjZXNzOiBEZWxldGVkICdteV9vcHRpb24nIHNpdGUgb3B0aW9uLgogKi8KY2xhc3MgU2l0ZV9PcHRpb25fQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIEdldHMgYSBzaXRlIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogS2V5IGZvciB0aGUgc2l0ZSBvcHRpb24uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBHZXQgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdmFyX2V4cG9ydAoJICogb3B0aW9uczoKCSAqICAgLSB2YXJfZXhwb3J0CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHNpdGUgdXBsb2FkIGZpbGV0eXBlcwoJICogICAgICQgd3Agc2l0ZSBvcHRpb24gZ2V0IHVwbG9hZF9maWxldHlwZXMKCSAqICAgICBqcGcganBlZyBwbmcgZ2lmIG1vdiBhdmkgbXBnCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5ICkgPSAkYXJnczsKCgkJJHZhbHVlID0gZ2V0X3NpdGVfb3B0aW9uKCAka2V5ICk7CgoJCWlmICggZmFsc2UgPT09ICR2YWx1ZSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoKCQlXUF9DTEk6OnByaW50X3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgc2l0ZSBvcHRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBzaXRlIG9wdGlvbiB0byBhZGQuCgkgKgoJICogWzx2YWx1ZT5dCgkgKiA6IFRoZSB2YWx1ZSBvZiB0aGUgc2l0ZSBvcHRpb24gdG8gYWRkLiBJZiBvbW1pdGVkLCB0aGUgdmFsdWUgaXMgcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSBhIHNpdGUgb3B0aW9uIGJ5IHJlYWRpbmcgYSBKU09OIGZpbGUKCSAqICAgICAkIHdwIHNpdGUgb3B0aW9uIGFkZCBteV9vcHRpb24gLS1mb3JtYXQ9anNvbiA8IGNvbmZpZy5qc29uCgkgKiAgICAgU3VjY2VzczogQWRkZWQgJ215X29wdGlvbicgc2l0ZSBvcHRpb24uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkka2V5ID0gJGFyZ3NbMF07CgoJCSR2YWx1ZSA9IFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgMSApOwoJCSR2YWx1ZSA9IFdQX0NMSTo6cmVhZF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoKCQlpZiAoICEgYWRkX3NpdGVfb3B0aW9uKCAka2V5LCAkdmFsdWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBhZGQgc2l0ZSBvcHRpb24gJ3ska2V5fScuIERvZXMgaXQgYWxyZWFkeSBleGlzdD8iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQWRkZWQgJ3ska2V5fScgc2l0ZSBvcHRpb24uIiApOwoJCX0KCX0KCgkvKioKCSAqIExpc3RzIHNpdGUgb3B0aW9ucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tc2VhcmNoPTxwYXR0ZXJuPl0KCSAqIDogVXNlIHdpbGRjYXJkcyAoICogYW5kID8gKSB0byBtYXRjaCBvcHRpb24gbmFtZS4KCSAqCgkgKiBbLS1zaXRlX2lkPTxpZD5dCgkgKiA6IExpbWl0IG9wdGlvbnMgdG8gdGhvc2Ugb2YgYSBwYXJ0aWN1bGFyIHNpdGUgaWQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLiB0b3RhbF9ieXRlcyBkaXNwbGF5cyB0aGUgdG90YWwgc2l6ZSBvZiBtYXRjaGluZyBvcHRpb25zIGluIGJ5dGVzLgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGpzb24KCSAqICAgLSBjc3YKCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqICAgLSB0b3RhbF9ieXRlcwoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoaXMgZmllbGQgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBtYXRjaGluZyBvcHRpb246CgkgKgoJICogKiBtZXRhX2tleQoJICogKiBtZXRhX3ZhbHVlCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIG1ldGFfaWQKCSAqICogc2l0ZV9pZAoJICogKiBzaXplX2J5dGVzCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGFsbCBzaXRlIG9wdGlvbnMgYmVnaW5pbmcgd2l0aCAiaTJmXyIKCSAqICAgICAkIHdwIHNpdGUgb3B0aW9uIGxpc3QgLS1zZWFyY2g9ImkyZl8qIgoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbWV0YV9rZXkgICAgfCBtZXRhX3ZhbHVlICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgaTJmX3ZlcnNpb24gfCAwLjEuMCAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWdsb2JhbCAkd3BkYjsKCQkkcGF0dGVybiAgICA9ICclJzsKCQkkZmllbGRzICAgICA9IFsgJ21ldGFfa2V5JywgJ21ldGFfdmFsdWUnIF07CgkJJHNpemVfcXVlcnkgPSAnLExFTkdUSChtZXRhX3ZhbHVlKSBBUyBgc2l6ZV9ieXRlc2AnOwoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snc2VhcmNoJ10gKSApIHsKCQkJJHBhdHRlcm4gPSBzZWxmOjplc2NfbGlrZSggJGFzc29jX2FyZ3NbJ3NlYXJjaCddICk7CgkJCS8vIHN1YnN0aXR1dGUgd2lsZGNhcmRzCgkJCSRwYXR0ZXJuID0gc3RyX3JlcGxhY2UoICcqJywgJyUnLCAkcGF0dGVybiApOwoJCQkkcGF0dGVybiA9IHN0cl9yZXBsYWNlKCAnPycsICdfJywgJHBhdHRlcm4gKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkZmllbGRzID0gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApID09PSAndG90YWxfYnl0ZXMnICkgewoJCQkkZmllbGRzICAgICA9IFsgJ3NpemVfYnl0ZXMnIF07CgkJCSRzaXplX3F1ZXJ5ID0gJyxTVU0oTEVOR1RIKG1ldGFfdmFsdWUpKSBBUyBgc2l6ZV9ieXRlc2AnOwoJCX0KCgkJJHF1ZXJ5ID0gJHdwZGItPnByZXBhcmUoCgkJCSdTRUxFQ1QgYG1ldGFfaWRgLCBgc2l0ZV9pZGAsIGBtZXRhX2tleWAsYG1ldGFfdmFsdWVgJwoJCQkJLiAkc2l6ZV9xdWVyeSAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIEhhcmQtY29kZWQgcGFydGlhbCBxdWVyeSB3aXRob3V0IHVzZXIgaW5wdXQuCgkJCQkuICIgRlJPTSBgJHdwZGItPnNpdGVtZXRhYCBXSEVSRSBgbWV0YV9rZXlgIExJS0UgJXMiLAoJCQkkcGF0dGVybgoJCSk7CgoJCSRzaXRlX2lkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2l0ZV9pZCcgKTsKCQlpZiAoICRzaXRlX2lkICkgewoJCQkkcXVlcnkgLj0gJHdwZGItPnByZXBhcmUoICcgQU5EIHNpdGVfaWQ9JWQnLCAkc2l0ZV9pZCApOwoJCX0KCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tICRxdWVyeSBpcyBhbHJlYWR5IHByZXBhcmVkIGFib3ZlLgoJCSRyZXN1bHRzID0gJHdwZGItPmdldF9yZXN1bHRzKCAkcXVlcnkgKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgPT09ICd0b3RhbF9ieXRlcycgKSB7CgkJCVdQX0NMSTo6bGluZSggJHJlc3VsdHNbMF0tPnNpemVfYnl0ZXMgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcigKCQkJCSRhc3NvY19hcmdzLAoJCQkJJGZpZWxkcwoJCQkpOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkcmVzdWx0cyApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgYSBzaXRlIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIHNpdGUgb3B0aW9uIHRvIHVwZGF0ZS4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIG5ldyB2YWx1ZS4gSWYgb21taXRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgYSBzaXRlIG9wdGlvbiBieSByZWFkaW5nIGZyb20gYSBmaWxlCgkgKiAgICAgJCB3cCBzaXRlIG9wdGlvbiB1cGRhdGUgbXlfb3B0aW9uIDwgdmFsdWUudHh0CgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnbXlfb3B0aW9uJyBzaXRlIG9wdGlvbi4KCSAqCgkgKiBAYWxpYXMgc2V0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkka2V5ID0gJGFyZ3NbMF07CgoJCSR2YWx1ZSA9IFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgMSApOwoJCSR2YWx1ZSA9IFdQX0NMSTo6cmVhZF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoKCQkkdmFsdWUgICAgID0gc2FuaXRpemVfb3B0aW9uKCAka2V5LCAkdmFsdWUgKTsKCQkkb2xkX3ZhbHVlID0gc2FuaXRpemVfb3B0aW9uKCAka2V5LCBnZXRfc2l0ZV9vcHRpb24oICRrZXkgKSApOwoKCQlpZiAoICR2YWx1ZSA9PT0gJG9sZF92YWx1ZSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVmFsdWUgcGFzc2VkIGZvciAneyRrZXl9JyBzaXRlIG9wdGlvbiBpcyB1bmNoYW5nZWQuIiApOwoJCX0gZWxzZSB7CgkJCWlmICggdXBkYXRlX3NpdGVfb3B0aW9uKCAka2V5LCAkdmFsdWUgKSApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIlVwZGF0ZWQgJ3ska2V5fScgc2l0ZSBvcHRpb24uIiApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCB1cGRhdGUgc2l0ZSBvcHRpb24gJ3ska2V5fScuIiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlcyBhIHNpdGUgb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBLZXkgZm9yIHRoZSBzaXRlIG9wdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgb3B0aW9uIGRlbGV0ZSBteV9vcHRpb24KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICdteV9vcHRpb24nIHNpdGUgb3B0aW9uLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncyApIHsKCQlsaXN0KCAka2V5ICkgPSAkYXJnczsKCgkJaWYgKCAhIGRlbGV0ZV9zaXRlX29wdGlvbiggJGtleSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGRlbGV0ZSAneyRrZXl9JyBzaXRlIG9wdGlvbi4gRG9lcyBpdCBleGlzdD8iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiRGVsZXRlZCAneyRrZXl9JyBzaXRlIG9wdGlvbi4iICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyBhIG5lc3RlZCB2YWx1ZSBmcm9tIGFuIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG9wdGlvbiBuYW1lLgoJICoKCSAqIDxrZXktcGF0aD4uLi4KCSAqIDogVGhlIG5hbWUocykgb2YgdGhlIGtleXMgd2l0aGluIHRoZSB2YWx1ZSB0byBsb2NhdGUgdGhlIHZhbHVlIHRvIHBsdWNrLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIG91dHB1dCBmb3JtYXQgb2YgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBsdWNrKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSApID0gJGFyZ3M7CgoJCSR2YWx1ZSA9IGdldF9zaXRlX29wdGlvbiggJGtleSApOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCgkJJGtleV9wYXRoID0gYXJyYXlfbWFwKAoJCQlmdW5jdGlvbiggJGtleSApIHsKCQkJCWlmICggaXNfbnVtZXJpYyggJGtleSApICYmICggKHN0cmluZykgaW50dmFsKCAka2V5ICkgPT09ICRrZXkgKSApIHsKCQkJCQlyZXR1cm4gKGludCkgJGtleTsKCQkJCX0KCQkJCQlyZXR1cm4gJGtleTsKCQkJfSwKCQkJYXJyYXlfc2xpY2UoICRhcmdzLCAxICkKCQkpOwoKCQkkdHJhdmVyc2VyID0gbmV3IFJlY3Vyc2l2ZURhdGFTdHJ1Y3R1cmVUcmF2ZXJzZXIoICR2YWx1ZSApOwoKCQl0cnkgewoJCQkkdmFsdWUgPSAkdHJhdmVyc2VyLT5nZXQoICRrZXlfcGF0aCApOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJZGllKCAxICk7CgkJfQoKCQlXUF9DTEk6OnByaW50X3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIGEgbmVzdGVkIHZhbHVlIGluIGFuIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGFjdGlvbj4KCSAqIDogUGF0Y2ggYWN0aW9uIHRvIHBlcmZvcm0uCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0gaW5zZXJ0CgkgKiAgIC0gdXBkYXRlCgkgKiAgIC0gZGVsZXRlCgkgKiAtLS0KCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgb3B0aW9uIG5hbWUuCgkgKgoJICogPGtleS1wYXRoPi4uLgoJICogOiBUaGUgbmFtZShzKSBvZiB0aGUga2V5cyB3aXRoaW4gdGhlIHZhbHVlIHRvIGxvY2F0ZSB0aGUgdmFsdWUgdG8gcGF0Y2guCgkgKgoJICogWzx2YWx1ZT5dCgkgKiA6IFRoZSBuZXcgdmFsdWUuIElmIG9taXR0ZWQsIHRoZSB2YWx1ZSBpcyByZWFkIGZyb20gU1RESU4uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0Y2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkYWN0aW9uLCAka2V5ICkgPSAkYXJnczsKCQkka2V5X3BhdGggICAgICAgICAgICAgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAka2V5ICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAka2V5ICkgJiYgKCAoc3RyaW5nKSBpbnR2YWwoICRrZXkgKSA9PT0gJGtleSApICkgewoJCQkJCXJldHVybiAoaW50KSAka2V5OwoJCQkJfQoJCQkJCXJldHVybiAka2V5OwoJCQl9LAoJCQlhcnJheV9zbGljZSggJGFyZ3MsIDIgKQoJCSk7CgoJCWlmICggJ2RlbGV0ZScgPT09ICRhY3Rpb24gKSB7CgkJCSRwYXRjaF92YWx1ZSA9IG51bGw7CgkJfSBlbHNlIHsKCQkJJHN0ZGluX3ZhbHVlID0gRW50aXR5VXRpbHM6Omhhc19zdGRpbigpCgkJCQk/IHRyaW0oIFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgLTEgKSApCgkJCQk6IG51bGw7CgkJCSRwYXRjaF92YWx1ZSA9ICEgZW1wdHkoICRzdGRpbl92YWx1ZSApCgkJCQk/IFdQX0NMSTo6cmVhZF92YWx1ZSggJHN0ZGluX3ZhbHVlLCAkYXNzb2NfYXJncyApCgkJCQk6IFdQX0NMSTo6cmVhZF92YWx1ZSggYXJyYXlfcG9wKCAka2V5X3BhdGggKSwgJGFzc29jX2FyZ3MgKTsKCQl9CgoJCS8qIE5lZWQgdG8gbWFrZSBhIGNvcHkgb2YgJGN1cnJlbnRfdmFsdWUgaGVyZSBhcyBpdCBpcyBtb2RpZmllZCBieSByZWZlcmVuY2UgKi8KCQkkb2xkX3ZhbHVlICAgICA9IHNhbml0aXplX29wdGlvbiggJGtleSwgZ2V0X3NpdGVfb3B0aW9uKCAka2V5ICkgKTsKCQkkY3VycmVudF92YWx1ZSA9ICRvbGRfdmFsdWU7CgkJaWYgKCBpc19vYmplY3QoICRjdXJyZW50X3ZhbHVlICkgKSB7CgkJCSRvbGRfdmFsdWUgPSBjbG9uZSAkY3VycmVudF92YWx1ZTsKCQl9CgoJCSR0cmF2ZXJzZXIgPSBuZXcgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciggJGN1cnJlbnRfdmFsdWUgKTsKCgkJdHJ5IHsKCQkJJHRyYXZlcnNlci0+JGFjdGlvbiggJGtleV9wYXRoLCAkcGF0Y2hfdmFsdWUgKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRleGNlcHRpb24tPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJJHBhdGNoZWRfdmFsdWUgPSBzYW5pdGl6ZV9vcHRpb24oICRrZXksICR0cmF2ZXJzZXItPnZhbHVlKCkgKTsKCgkJaWYgKCAkcGF0Y2hlZF92YWx1ZSA9PT0gJG9sZF92YWx1ZSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVmFsdWUgcGFzc2VkIGZvciAneyRrZXl9JyBzaXRlIG9wdGlvbiBpcyB1bmNoYW5nZWQuIiApOwoJCX0gZWxzZSB7CgkJCWlmICggdXBkYXRlX3NpdGVfb3B0aW9uKCAka2V5LCAkcGF0Y2hlZF92YWx1ZSApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVXBkYXRlZCAneyRrZXl9JyBzaXRlIG9wdGlvbi4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHVwZGF0ZSBzaXRlIG9wdGlvbiAneyRrZXl9Jy4iICk7CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX2xpa2UoICRvbGQgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBSZW1vdmUgbm90aWNlcyBpbiA0LjAgYW5kIHN1cHBvcnQgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkKCQlpZiAoIG1ldGhvZF9leGlzdHMoICR3cGRiLCAnZXNjX2xpa2UnICkgKSB7CgkJCS8vIDQuMAoJCQkkb2xkID0gJHdwZGItPmVzY19saWtlKCAkb2xkICk7CgkJfSBlbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkRnVuY3Rpb25zLmxpa2VfZXNjYXBlRm91bmQgLS0gY2FsbGVkIGluIFdvcmRQcmVzcyAzLjkgb3IgbGVzcy4KCQkJJG9sZCA9IGxpa2VfZXNjYXBlKCBlc2Nfc3FsKCAkb2xkICkgKTsKCQl9CgoJCXJldHVybiAkb2xkOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoTWV0YTsKdXNlIFdQX0NMSVxGZXRjaGVyc1xVc2VyIGFzIFVzZXJGZXRjaGVyOwoKLyoqCiAqIEFkZHMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGFuZCBsaXN0cyB1c2VyIGN1c3RvbSBmaWVsZHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEFkZCB1c2VyIG1ldGEKICogICAgICQgd3AgdXNlciBtZXRhIGFkZCAxMjMgYmlvICJNYXJ5IGlzIGFuIFdvcmRQcmVzcyBkZXZlbG9wZXIuIgogKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgogKgogKiAgICAgIyBMaXN0IHVzZXIgbWV0YQogKiAgICAgJCB3cCB1c2VyIG1ldGEgbGlzdCAxMjMgLS1rZXlzPW5pY2tuYW1lLGRlc2NyaXB0aW9uLHdwX2NhcGFiaWxpdGllcwogKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgdXNlcl9pZCB8IG1ldGFfa2V5ICAgICAgICB8IG1ldGFfdmFsdWUgICAgICAgICAgICAgICAgICAgICB8CiAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCAxMjMgICAgIHwgbmlja25hbWUgICAgICAgIHwgc3VwZXJ2aXNvciAgICAgICAgICAgICAgICAgICAgIHwKICogICAgIHwgMTIzICAgICB8IGRlc2NyaXB0aW9uICAgICB8IE1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLiB8CiAqICAgICB8IDEyMyAgICAgfCB3cF9jYXBhYmlsaXRpZXMgfCB7ImFkbWluaXN0cmF0b3IiOnRydWV9ICAgICAgICAgfAogKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICoKICogICAgICMgVXBkYXRlIHVzZXIgbWV0YQogKiAgICAgJCB3cCB1c2VyIG1ldGEgdXBkYXRlIDEyMyBiaW8gIk1hcnkgaXMgYW4gYXdlc29tZSBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY3VzdG9tIGZpZWxkICdiaW8nLgogKgogKiAgICAgIyBEZWxldGUgdXNlciBtZXRhCiAqICAgICAkIHdwIHVzZXIgbWV0YSBkZWxldGUgMTIzIGJpbwogKiAgICAgU3VjY2VzczogRGVsZXRlZCBjdXN0b20gZmllbGQuCiAqLwpjbGFzcyBVc2VyX01ldGFfQ29tbWFuZCBleHRlbmRzIENvbW1hbmRXaXRoTWV0YSB7Cglwcm90ZWN0ZWQgJG1ldGFfdHlwZSA9ICd1c2VyJzsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgVXNlckZldGNoZXIoKTsKCX0KCgkvKioKCSAqIExpc3RzIGFsbCBtZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGggYSB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gZ2V0IG1ldGFkYXRhIGZvci4KCSAqCgkgKiBbLS1rZXlzPTxrZXlzPl0KCSAqIDogTGltaXQgb3V0cHV0IHRvIG1ldGFkYXRhIG9mIHNwZWNpZmljIGtleXMuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIHJvdyBmaWVsZHMuIERlZmF1bHRzIHRvIGlkLG1ldGFfa2V5LG1ldGFfdmFsdWUuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogWy0tb3JkZXJieT08ZmllbGRzPl0KCSAqIDogU2V0IG9yZGVyYnkgd2hpY2ggZmllbGQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGlkCgkgKiBvcHRpb25zOgoJICogIC0gaWQKCSAqICAtIG1ldGFfa2V5CgkgKiAgLSBtZXRhX3ZhbHVlCgkgKiAtLS0KCSAqCgkgKiBbLS1vcmRlcj08b3JkZXI+XQoJICogOiBTZXQgYXNjZW5kaW5nIG9yIGRlc2NlbmRpbmcgb3JkZXIuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGFzYwoJICogb3B0aW9uczoKCSAqICAtIGFzYwoJICogIC0gZGVzYwoJICogLS0tCgkgKgoJICogWy0tdW5zZXJpYWxpemVdCgkgKiA6IFVuc2VyaWFsaXplIG1ldGFfdmFsdWUgb3V0cHV0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCB1c2VyIG1ldGEKCSAqICAgICAkIHdwIHVzZXIgbWV0YSBsaXN0IDEyMyAtLWtleXM9bmlja25hbWUsZGVzY3JpcHRpb24sd3BfY2FwYWJpbGl0aWVzCgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IHVzZXJfaWQgfCBtZXRhX2tleSAgICAgICAgfCBtZXRhX3ZhbHVlICAgICAgICAgICAgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCAxMjMgICAgIHwgbmlja25hbWUgICAgICAgIHwgc3VwZXJ2aXNvciAgICAgICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IDEyMyAgICAgfCBkZXNjcmlwdGlvbiAgICAgfCBNYXJ5IGlzIGEgV29yZFByZXNzIGRldmVsb3Blci4gfAoJICogICAgIHwgMTIzICAgICB8IHdwX2NhcGFiaWxpdGllcyB8IHsiYWRtaW5pc3RyYXRvciI6dHJ1ZX0gICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcmdzID0gJHRoaXMtPnJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApOwoJCXBhcmVudDo6bGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogR2V0cyBtZXRhIGZpZWxkIHZhbHVlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gZ2V0IG1ldGFkYXRhIGZvci4KCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgbWV0YWRhdGEga2V5LgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCB1c2VyIG1ldGEKCSAqICAgICAkIHdwIHVzZXIgbWV0YSBnZXQgMTIzIGJpbwoJICogICAgIE1hcnkgaXMgYW4gV29yZFByZXNzIGRldmVsb3Blci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcmdzID0gJHRoaXMtPnJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApOwoJCXBhcmVudDo6Z2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgYSBtZXRhIGZpZWxkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gZGVsZXRlIG1ldGFkYXRhIGZyb20uCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG1ldGFkYXRhIGtleS4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIHZhbHVlIHRvIGRlbGV0ZS4gSWYgb21pdHRlZCwgYWxsIHJvd3Mgd2l0aCBrZXkgd2lsbCBkZWxldGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHVzZXIgbWV0YQoJICogICAgICQgd3AgdXNlciBtZXRhIGRlbGV0ZSAxMjMgYmlvCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCBjdXN0b20gZmllbGQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJncyA9ICR0aGlzLT5yZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKTsKCQlwYXJlbnQ6OmRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgbWV0YSBmaWVsZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsLCBvciB1c2VyIElEIG9mIHRoZSB1c2VyIHRvIGFkZCBtZXRhZGF0YSBmb3IuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG1ldGFkYXRhIGtleS4KCSAqCgkgKiA8dmFsdWU+CgkgKiA6IFRoZSBuZXcgbWV0YWRhdGEgdmFsdWUuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQWRkIHVzZXIgbWV0YQoJICogICAgICQgd3AgdXNlciBtZXRhIGFkZCAxMjMgYmlvICJNYXJ5IGlzIGFuIFdvcmRQcmVzcyBkZXZlbG9wZXIuIgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcmdzID0gJHRoaXMtPnJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApOwoJCXBhcmVudDo6YWRkKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgYSBtZXRhIGZpZWxkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gdXBkYXRlIG1ldGFkYXRhIGZvci4KCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgbWV0YWRhdGEga2V5LgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVGhlIG5ldyBtZXRhZGF0YSB2YWx1ZS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgdXNlciBtZXRhCgkgKiAgICAgJCB3cCB1c2VyIG1ldGEgdXBkYXRlIDEyMyBiaW8gIk1hcnkgaXMgYW4gYXdlc29tZSBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnYmlvJy4KCSAqCgkgKiBAYWxpYXMgc2V0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJncyA9ICR0aGlzLT5yZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKTsKCQlwYXJlbnQ6OnVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgYWRkX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIGJvb2wgICAkdW5pcXVlICAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gV2hldGhlciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSBzaG91bGQgYmUgdW5pcXVlIGZvciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LiBJZiB0cnVlLCBhbmQgdGhlIG9iamVjdCBhbHJlYWR5IGhhcyBhCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSwgbm8gY2hhbmdlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgbWFkZS4KCSAqCgkgKiBAcmV0dXJuIGludHxmYWxzZSBUaGUgbWV0YSBJRCBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGFkZF91c2VyX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciB1cGRhdGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gbWl4ZWQgICRwcmV2X3ZhbHVlIE9wdGlvbmFsLiBJZiBzcGVjaWZpZWQsIG9ubHkgdXBkYXRlIGV4aXN0aW5nCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBPdGhlcndpc2UsIHVwZGF0ZSBhbGwgZW50cmllcy4KCSAqCgkgKiBAcmV0dXJuIGludHxib29sIE1ldGEgSUQgaWYgdGhlIGtleSBkaWRuJ3QgZXhpc3QsIHRydWUgb24gc3VjY2Vzc2Z1bAoJICogICAgICAgICAgICAgICAgICB1cGRhdGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIHVwZGF0ZV91c2VyX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZ2V0X21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICBPcHRpb25hbC4gTWV0YWRhdGEga2V5LiBJZiBub3Qgc3BlY2lmaWVkLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHJldHJpZXZlIGFsbCBtZXRhZGF0YSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCgkgKiBAcGFyYW0gYm9vbCAgICRzaW5nbGUgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIElmIHRydWUsIHJldHVybiBvbmx5CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZpcnN0IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuIFRoaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBpZiBtZXRhX2tleSBpcyBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQuCgkgKgoJICogQHJldHVybiBtaXhlZCBTaW5nbGUgbWV0YWRhdGEgdmFsdWUsIG9yIGFycmF5IG9mIHZhbHVlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5ID0gJycsICRzaW5nbGUgPSBmYWxzZSApIHsKCQlyZXR1cm4gZ2V0X3VzZXJfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkc2luZ2xlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZGVsZXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IG1ldGFkYXRhIGlzIGZvcgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkKCSAqIEBwYXJhbSBtaXhlZCAkbWV0YV92YWx1ZSAgT3B0aW9uYWwuIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBub24tc2NhbGFyLiBJZiBzcGVjaWZpZWQsIG9ubHkgZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGlzIHZhbHVlLiBPdGhlcndpc2UsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhbGwgZW50cmllcyB3aXRoIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhc3MgYG51bGwsIGBmYWxzZWAsIG9yIGFuIGVtcHR5IHN0cmluZyB0byBza2lwCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgY2hlY2suIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBpdCBpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub3QgcG9zc2libGUgdG8gcGFzcyBhbiBlbXB0eSBzdHJpbmcgdG8gZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRob3NlIGVudHJpZXMgd2l0aCBhbiBlbXB0eSBzdHJpbmcgZm9yIGEgdmFsdWUuCgkgKgoJICogQHJldHVybiBib29sIFRydWUgb24gc3VjY2Vzc2Z1bCBkZWxldGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBkZWxldGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgPSAnJyApIHsKCQlyZXR1cm4gZGVsZXRlX3VzZXJfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSApOwoJfQoKCS8qKgoJICogUmVwbGFjZXMgdXNlcl9sb2dpbiB2YWx1ZSB3aXRoIHVzZXIgSUQKCSAqIHVzZXIgbWV0YSBpcyBhIHNwZWNpYWwgY2FzZSB0aGF0IGFsc28gc3VwcG9ydHMgdXNlcl9sb2dpbgoJICoKCSAqIEBwYXJhbSBhcnJheQoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlcGxhY2VfbG9naW5fd2l0aF91c2VyX2lkKCAkYXJncyApIHsKCQkkdXNlciAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgkJJGFyZ3NbMF0gPSAkdXNlci0+SUQ7CgkJcmV0dXJuICRhcmdzOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTGlzdHMsIGNyZWF0ZXMsIGFzc2lnbnMsIGFuZCBkZWxldGVzIHRoZSBhY3RpdmUgdGhlbWUncyBuYXZpZ2F0aW9uIG1lbnVzLgogKgogKiBTZWUgdGhlIFtOYXZpZ2F0aW9uIE1lbnVzXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9mdW5jdGlvbmFsaXR5L25hdmlnYXRpb24tbWVudXMvKSByZWZlcmVuY2UgaW4gdGhlIFRoZW1lIEhhbmRib29rLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBDcmVhdGUgYSBuZXcgbWVudQogKiAgICAgJCB3cCBtZW51IGNyZWF0ZSAiTXkgTWVudSIKICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgbWVudSAyMDAuCiAqCiAqICAgICAjIExpc3QgZXhpc3RpbmcgbWVudXMKICogICAgICQgd3AgbWVudSBsaXN0CiAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tKwogKiAgICAgfCB0ZXJtX2lkIHwgbmFtZSAgICAgfCBzbHVnICAgICB8IGxvY2F0aW9ucyB8IGNvdW50IHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0rCiAqICAgICB8IDIwMCAgICAgfCBNeSBNZW51ICB8IG15LW1lbnUgIHwgICAgICAgICAgIHwgMCAgICAgfAogKiAgICAgfCAxNzcgICAgIHwgVG9wIE1lbnUgfCB0b3AtbWVudSB8IHByaW1hcnkgICB8IDcgICAgIHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0rCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBtZW51IGxpbmsgaXRlbQogKiAgICAgJCB3cCBtZW51IGl0ZW0gYWRkLWN1c3RvbSBteS1tZW51IEFwcGxlIGh0dHA6Ly9hcHBsZS5jb20gLS1wb3JjZWxhaW4KICogICAgIDE5MjIKICoKICogICAgICMgQXNzaWduIHRoZSAnbXktbWVudScgbWVudSB0byB0aGUgJ3ByaW1hcnknIGxvY2F0aW9uCiAqICAgICAkIHdwIG1lbnUgbG9jYXRpb24gYXNzaWduIG15LW1lbnUgcHJpbWFyeQogKiAgICAgU3VjY2VzczogQXNzaWduZWQgbG9jYXRpb24gdG8gbWVudS4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBNZW51X0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJvdGVjdGVkICRvYmpfdHlwZSAgID0gJ25hdl9tZW51JzsKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IFsKCQkndGVybV9pZCcsCgkJJ25hbWUnLAoJCSdzbHVnJywKCQknbG9jYXRpb25zJywKCQknY291bnQnLAoJXTsKCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgbWVudS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnUtbmFtZT4KCSAqIDogQSBkZXNjcmlwdGl2ZSBuYW1lIGZvciB0aGUgbWVudS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgbWVudSBpZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1lbnUgY3JlYXRlICJNeSBNZW51IgoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgbWVudSAyMDAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjcmVhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJG1lbnVfaWQgPSB3cF9jcmVhdGVfbmF2X21lbnUoICRhcmdzWzBdICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRtZW51X2lkICkgKSB7CgoJCQlXUF9DTEk6OmVycm9yKCAkbWVudV9pZC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoKCQl9IGVsc2UgewoKCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICRtZW51X2lkICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDcmVhdGVkIG1lbnUgeyRtZW51X2lkfS4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGVzIG9uZSBvciBtb3JlIG1lbnVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bWVudT4uLi4KCSAqIDogVGhlIG5hbWUsIHNsdWcsIG9yIHRlcm0gSUQgZm9yIHRoZSBtZW51KHMpLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBkZWxldGUgIk15IE1lbnUiCgkgKiAgICAgU3VjY2VzczogMSBtZW51IGRlbGV0ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvdW50ICA9IDA7CgkJJGVycm9ycyA9IDA7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgkJCSRyZXQgPSB3cF9kZWxldGVfbmF2X21lbnUoICRhcmcgKTsKCQkJaWYgKCAhICRyZXQgfHwgaXNfd3BfZXJyb3IoICRyZXQgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IGRlbGV0ZSBtZW51ICd7JGFyZ30nLiIgKTsKCQkJCSRlcnJvcnMrKzsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAiRGVsZXRlZCBtZW51ICd7JGFyZ30nLiIgKTsKCQkJCSRjb3VudCsrOwoJCQl9CgkJfQoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdtZW51JywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIEdldHMgYSBsaXN0IG9mIG1lbnVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSBpZHMKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggbWVudToKCSAqCgkgKiAqIHRlcm1faWQKCSAqICogbmFtZQoJICogKiBzbHVnCgkgKiAqIGNvdW50CgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHRlcm1fZ3JvdXAKCSAqICogdGVybV90YXhvbm9teV9pZAoJICogKiB0YXhvbm9teQoJICogKiBkZXNjcmlwdGlvbgoJICogKiBwYXJlbnQKCSAqICogbG9jYXRpb25zCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGxpc3QKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tKwoJICogICAgIHwgdGVybV9pZCB8IG5hbWUgICAgIHwgc2x1ZyAgICAgfCBsb2NhdGlvbnMgfCBjb3VudCB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqICAgICB8IDIwMCAgICAgfCBNeSBNZW51ICB8IG15LW1lbnUgIHwgICAgICAgICAgIHwgMCAgICAgfAoJICogICAgIHwgMTc3ICAgICB8IFRvcCBNZW51IHwgdG9wLW1lbnUgfCBwcmltYXJ5ICAgfCA3ICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkbWVudXMgPSB3cF9nZXRfbmF2X21lbnVzKCk7CgoJCSRtZW51X2xvY2F0aW9ucyA9IGdldF9uYXZfbWVudV9sb2NhdGlvbnMoKTsKCQlmb3JlYWNoICggJG1lbnVzIGFzICYkbWVudSApIHsKCgkJCSRtZW51LT5sb2NhdGlvbnMgPSBbXTsKCQkJZm9yZWFjaCAoICRtZW51X2xvY2F0aW9ucyBhcyAkbG9jYXRpb24gPT4gJHRlcm1faWQgKSB7CgoJCQkJaWYgKCAkdGVybV9pZCA9PT0gJG1lbnUtPnRlcm1faWQgKSB7CgkJCQkJJG1lbnUtPmxvY2F0aW9uc1tdID0gJGxvY2F0aW9uOwoJCQkJfQoJCQl9CgoJCQkvLyBOb3JtYWxpemUgdGhlIGRhdGEgZm9yIHNvbWUgb3V0cHV0IGZvcm1hdHMuCgkJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgfHwgaW5fYXJyYXkoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgWyAnY3N2JywgJ3RhYmxlJyBdLCB0cnVlICkgKSB7CgkJCQkkbWVudS0+bG9jYXRpb25zID0gaW1wbG9kZSggJywnLCAkbWVudS0+bG9jYXRpb25zICk7CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQkkaWRzID0gYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24oICRvICkgewoJCQkJCXJldHVybiAkby0+dGVybV9pZDsKCQkJCX0sCgkJCQkkbWVudXMKCQkJKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGlkcyApOwoJCX0gZWxzZSB7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRtZW51cyApOwoJCX0KCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPm9ial9maWVsZHMsICR0aGlzLT5vYmpfdHlwZSApOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aE1ldGE7CgovKioKICogQWRkcywgdXBkYXRlcywgZGVsZXRlcywgYW5kIGxpc3RzIHRlcm0gY3VzdG9tIGZpZWxkcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHRlcm0gbWV0YQogKiAgICAgJCB3cCB0ZXJtIG1ldGEgc2V0IDEyMyBiaW8gIk1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY3VzdG9tIGZpZWxkICdiaW8nLgogKgogKiAgICAgIyBHZXQgdGVybSBtZXRhCiAqICAgICAkIHdwIHRlcm0gbWV0YSBnZXQgMTIzIGJpbwogKiAgICAgTWFyeSBpcyBhIFdvcmRQcmVzcyBkZXZlbG9wZXIuCiAqCiAqICAgICAjIFVwZGF0ZSB0ZXJtIG1ldGEKICogICAgICQgd3AgdGVybSBtZXRhIHVwZGF0ZSAxMjMgYmlvICJNYXJ5IGlzIGFuIGF3ZXNvbWUgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnYmlvJy4KICoKICogICAgICMgRGVsZXRlIHRlcm0gbWV0YQogKiAgICAgJCB3cCB0ZXJtIG1ldGEgZGVsZXRlIDEyMyBiaW8KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY3VzdG9tIGZpZWxkLgogKi8KY2xhc3MgVGVybV9NZXRhX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aE1ldGEgewoJcHJvdGVjdGVkICRtZXRhX3R5cGUgPSAndGVybSc7CgoJLyoqCgkgKiBDaGVjayB0aGF0IHRoZSB0ZXJtIElEIGV4aXN0cwoJICoKCSAqIEBwYXJhbSBpbnQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApIHsKCQkkdGVybSA9IGdldF90ZXJtKCAkb2JqZWN0X2lkICk7CgkJaWYgKCAhICR0ZXJtICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGZpbmQgdGhlIHRlcm0gd2l0aCBJRCB7JG9iamVjdF9pZH0uIiApOwoJCX0KCQlyZXR1cm4gJHRlcm0tPnRlcm1faWQ7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgYWRkX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIGJvb2wgICAkdW5pcXVlICAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gV2hldGhlciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSBzaG91bGQgYmUgdW5pcXVlIGZvciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LiBJZiB0cnVlLCBhbmQgdGhlIG9iamVjdCBhbHJlYWR5IGhhcyBhCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSwgbm8gY2hhbmdlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgbWFkZS4KCSAqCgkgKiBAcmV0dXJuIGludHxmYWxzZSBUaGUgbWV0YSBJRCBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGFkZF90ZXJtX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciB1cGRhdGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gbWl4ZWQgICRwcmV2X3ZhbHVlIE9wdGlvbmFsLiBJZiBzcGVjaWZpZWQsIG9ubHkgdXBkYXRlIGV4aXN0aW5nCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBPdGhlcndpc2UsIHVwZGF0ZSBhbGwgZW50cmllcy4KCSAqCgkgKiBAcmV0dXJuIGludHxib29sIE1ldGEgSUQgaWYgdGhlIGtleSBkaWRuJ3QgZXhpc3QsIHRydWUgb24gc3VjY2Vzc2Z1bAoJICogICAgICAgICAgICAgICAgICB1cGRhdGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIHVwZGF0ZV90ZXJtX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZ2V0X21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICBPcHRpb25hbC4gTWV0YWRhdGEga2V5LiBJZiBub3Qgc3BlY2lmaWVkLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHJldHJpZXZlIGFsbCBtZXRhZGF0YSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCgkgKiBAcGFyYW0gYm9vbCAgICRzaW5nbGUgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIElmIHRydWUsIHJldHVybiBvbmx5CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZpcnN0IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuIFRoaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBpZiBtZXRhX2tleSBpcyBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQuCgkgKgoJICogQHJldHVybiBtaXhlZCBTaW5nbGUgbWV0YWRhdGEgdmFsdWUsIG9yIGFycmF5IG9mIHZhbHVlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5ID0gJycsICRzaW5nbGUgPSBmYWxzZSApIHsKCQlyZXR1cm4gZ2V0X3Rlcm1fbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkc2luZ2xlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZGVsZXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IG1ldGFkYXRhIGlzIGZvcgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkKCSAqIEBwYXJhbSBtaXhlZCAkbWV0YV92YWx1ZSAgT3B0aW9uYWwuIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBub24tc2NhbGFyLiBJZiBzcGVjaWZpZWQsIG9ubHkgZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGlzIHZhbHVlLiBPdGhlcndpc2UsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhbGwgZW50cmllcyB3aXRoIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhc3MgYG51bGwsIGBmYWxzZWAsIG9yIGFuIGVtcHR5IHN0cmluZyB0byBza2lwCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgY2hlY2suIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBpdCBpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub3QgcG9zc2libGUgdG8gcGFzcyBhbiBlbXB0eSBzdHJpbmcgdG8gZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRob3NlIGVudHJpZXMgd2l0aCBhbiBlbXB0eSBzdHJpbmcgZm9yIGEgdmFsdWUuCgkgKgoJICogQHJldHVybiBib29sIFRydWUgb24gc3VjY2Vzc2Z1bCBkZWxldGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBkZWxldGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgPSAnJyApIHsKCQlyZXR1cm4gZGVsZXRlX3Rlcm1fbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSApOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBBc3NpZ25zLCByZW1vdmVzLCBhbmQgbGlzdHMgYSBtZW51J3MgbG9jYXRpb25zLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGF2YWlsYWJsZSBtZW51IGxvY2F0aW9ucwogKiAgICAgJCB3cCBtZW51IGxvY2F0aW9uIGxpc3QKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqICAgICB8IGxvY2F0aW9uIHwgZGVzY3JpcHRpb24gICAgICAgfAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgcHJpbWFyeSAgfCBQcmltYXJ5IE1lbnUgICAgICB8CiAqICAgICB8IHNvY2lhbCAgIHwgU29jaWFsIExpbmtzIE1lbnUgfAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKICoKICogICAgICMgQXNzaWduIHRoZSAncHJpbWFyeS1tZW51JyBtZW51IHRvIHRoZSAncHJpbWFyeScgbG9jYXRpb24KICogICAgICQgd3AgbWVudSBsb2NhdGlvbiBhc3NpZ24gcHJpbWFyeS1tZW51IHByaW1hcnkKICogICAgIFN1Y2Nlc3M6IEFzc2lnbmVkIGxvY2F0aW9uIHRvIG1lbnUuCiAqCiAqICAgICAjIFJlbW92ZSB0aGUgJ3ByaW1hcnktbWVudScgbWVudSBmcm9tIHRoZSAncHJpbWFyeScgbG9jYXRpb24KICogICAgICQgd3AgbWVudSBsb2NhdGlvbiByZW1vdmUgcHJpbWFyeS1tZW51IHByaW1hcnkKICogICAgIFN1Y2Nlc3M6IFJlbW92ZWQgbG9jYXRpb24gZnJvbSBtZW51LgogKi8KY2xhc3MgTWVudV9Mb2NhdGlvbl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogTGlzdHMgbG9jYXRpb25zIGZvciB0aGUgY3VycmVudCB0aGVtZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogICAtIGlkcwoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIGxvY2F0aW9uOgoJICoKCSAqICogbmFtZQoJICogKiBkZXNjcmlwdGlvbgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBsb2NhdGlvbiBsaXN0CgkgKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGxvY2F0aW9uIHwgZGVzY3JpcHRpb24gICAgICAgfAoJICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBwcmltYXJ5ICB8IFByaW1hcnkgTWVudSAgICAgIHwKCSAqICAgICB8IHNvY2lhbCAgIHwgU29jaWFsIExpbmtzIE1lbnUgfAoJICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGxvY2F0aW9ucyAgICAgPSBnZXRfcmVnaXN0ZXJlZF9uYXZfbWVudXMoKTsKCQkkbG9jYXRpb25fb2JqcyA9IFtdOwoJCWZvcmVhY2ggKCAkbG9jYXRpb25zIGFzICRsb2NhdGlvbiA9PiAkZGVzY3JpcHRpb24gKSB7CgkJCSRsb2NhdGlvbl9vYmogICAgICAgICAgICAgID0gbmV3IHN0ZENsYXNzKCk7CgkJCSRsb2NhdGlvbl9vYmotPmxvY2F0aW9uICAgID0gJGxvY2F0aW9uOwoJCQkkbG9jYXRpb25fb2JqLT5kZXNjcmlwdGlvbiA9ICRkZXNjcmlwdGlvbjsKCQkJJGxvY2F0aW9uX29ianNbXSAgICAgICAgICAgPSAkbG9jYXRpb25fb2JqOwoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCBbICdsb2NhdGlvbicsICdkZXNjcmlwdGlvbicgXSApOwoKCQlpZiAoICdpZHMnID09PSAkZm9ybWF0dGVyLT5mb3JtYXQgKSB7CgkJCSRpZHMgPSBhcnJheV9tYXAoCgkJCQlmdW5jdGlvbiggJG8gKSB7CgkJCQkJcmV0dXJuICRvLT5sb2NhdGlvbjsKCQkJCX0sCgkJCQkkbG9jYXRpb25fb2JqcwoJCQkpOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaWRzICk7CgkJfSBlbHNlIHsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGxvY2F0aW9uX29ianMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBc3NpZ25zIGEgbG9jYXRpb24gdG8gYSBtZW51LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bWVudT4KCSAqIDogVGhlIG5hbWUsIHNsdWcsIG9yIHRlcm0gSUQgZm9yIHRoZSBtZW51LgoJICoKCSAqIDxsb2NhdGlvbj4KCSAqIDogTG9jYXRpb24ncyBzbHVnLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBsb2NhdGlvbiBhc3NpZ24gcHJpbWFyeS1tZW51IHByaW1hcnkKCSAqICAgICBTdWNjZXNzOiBBc3NpZ25lZCBsb2NhdGlvbiBwcmltYXJ5IHRvIG1lbnUgcHJpbWFyeS1tZW51LgoJICoKCSAqIEBzdWJjb21tYW5kIGFzc2lnbgoJICovCglwdWJsaWMgZnVuY3Rpb24gYXNzaWduKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWxpc3QoICRtZW51LCAkbG9jYXRpb24gKSA9ICRhcmdzOwoKCQkkbWVudV9vYmogPSB3cF9nZXRfbmF2X21lbnVfb2JqZWN0KCAkbWVudSApOwoJCWlmICggISAkbWVudV9vYmogKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJJbnZhbGlkIG1lbnUgeyRtZW51fS4iICk7CgkJfQoKCQkkbG9jYXRpb25zID0gZ2V0X3JlZ2lzdGVyZWRfbmF2X21lbnVzKCk7CgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRsb2NhdGlvbiwgJGxvY2F0aW9ucyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCBsb2NhdGlvbiB7JGxvY2F0aW9ufS4iICk7CgkJfQoKCQkkbG9jYXRpb25zICAgICAgICAgICAgICA9IGdldF9uYXZfbWVudV9sb2NhdGlvbnMoKTsKCQkkbG9jYXRpb25zWyAkbG9jYXRpb24gXSA9ICRtZW51X29iai0+dGVybV9pZDsKCgkJc2V0X3RoZW1lX21vZCggJ25hdl9tZW51X2xvY2F0aW9ucycsICRsb2NhdGlvbnMgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAiQXNzaWduZWQgbG9jYXRpb24geyRsb2NhdGlvbn0gdG8gbWVudSB7JG1lbnV9LiIgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgYSBsb2NhdGlvbiBmcm9tIGEgbWVudS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnU+CgkgKiA6IFRoZSBuYW1lLCBzbHVnLCBvciB0ZXJtIElEIGZvciB0aGUgbWVudS4KCSAqCgkgKiA8bG9jYXRpb24+CgkgKiA6IExvY2F0aW9uJ3Mgc2x1Zy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1lbnUgbG9jYXRpb24gcmVtb3ZlIHByaW1hcnktbWVudSBwcmltYXJ5CgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCBsb2NhdGlvbiBmcm9tIG1lbnUuCgkgKgoJICogQHN1YmNvbW1hbmQgcmVtb3ZlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW1vdmUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJG1lbnUsICRsb2NhdGlvbiApID0gJGFyZ3M7CgoJCSRtZW51ID0gd3BfZ2V0X25hdl9tZW51X29iamVjdCggJG1lbnUgKTsKCQlpZiAoICEgJG1lbnUgfHwgaXNfd3BfZXJyb3IoICRtZW51ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIG1lbnUuJyApOwoJCX0KCgkJJGxvY2F0aW9ucyA9IGdldF9uYXZfbWVudV9sb2NhdGlvbnMoKTsKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkbG9jYXRpb25zLCAkbG9jYXRpb24gKSAhPT0gJG1lbnUtPnRlcm1faWQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJNZW51IGlzbid0IGFzc2lnbmVkIHRvIGxvY2F0aW9uLiIgKTsKCQl9CgoJCSRsb2NhdGlvbnNbICRsb2NhdGlvbiBdID0gMDsKCQlzZXRfdGhlbWVfbW9kKCAnbmF2X21lbnVfbG9jYXRpb25zJywgJGxvY2F0aW9ucyApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdSZW1vdmVkIGxvY2F0aW9uIGZyb20gbWVudS4nICk7CgoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTWFuYWdlcyB0YXhvbm9teSB0ZXJtcyBhbmQgdGVybSBtZXRhLCB3aXRoIGNyZWF0ZSwgZGVsZXRlLCBhbmQgbGlzdCBjb21tYW5kcy4KICoKICogU2VlIHJlZmVyZW5jZSBmb3IgW3RheG9ub21pZXMgYW5kIHRoZWlyIHRlcm1zXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvVGF4b25vbWllcykuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyB0ZXJtLgogKiAgICAgJCB3cCB0ZXJtIGNyZWF0ZSBjYXRlZ29yeSBBcHBsZSAtLWRlc2NyaXB0aW9uPSJBIHR5cGUgb2YgZnJ1aXQiCiAqICAgICBTdWNjZXNzOiBDcmVhdGVkIGNhdGVnb3J5IDE5OS4KICoKICogICAgICMgR2V0IGRldGFpbHMgYWJvdXQgYSB0ZXJtLgogKiAgICAgJCB3cCB0ZXJtIGdldCBjYXRlZ29yeSAxOTkgLS1mb3JtYXQ9anNvbiAtLWZpZWxkcz10ZXJtX2lkLG5hbWUsc2x1Zyxjb3VudAogKiAgICAgeyJ0ZXJtX2lkIjoxOTksIm5hbWUiOiJBcHBsZSIsInNsdWciOiJhcHBsZSIsImNvdW50IjoxfQogKgogKiAgICAgIyBVcGRhdGUgYW4gZXhpc3RpbmcgdGVybS4KICogICAgICQgd3AgdGVybSB1cGRhdGUgY2F0ZWdvcnkgMTUgLS1uYW1lPUFwcGxlCiAqICAgICBTdWNjZXNzOiBUZXJtIHVwZGF0ZWQuCiAqCiAqICAgICAjIEdldCB0aGUgdGVybSdzIFVSTC4KICogICAgICQgd3AgdGVybSBsaXN0IHBvc3RfdGFnIC0taW5jbHVkZT0xMjMgLS1maWVsZD11cmwKICogICAgIGh0dHA6Ly9leGFtcGxlLmNvbS90YWcvdGlwcy1hbmQtdHJpY2tzCiAqCiAqICAgICAjIERlbGV0ZSBwb3N0IGNhdGVnb3J5CiAqICAgICAkIHdwIHRlcm0gZGVsZXRlIGNhdGVnb3J5IDE1CiAqICAgICBTdWNjZXNzOiBEZWxldGVkIGNhdGVnb3J5IDE1LgogKgogKiAgICAgIyBSZWNvdW50IHBvc3RzIGFzc2lnbmVkIHRvIGVhY2ggY2F0ZWdvcmllcyBhbmQgdGFncwogKiAgICAgJCB3cCB0ZXJtIHJlY291bnQgY2F0ZWdvcnkgcG9zdF90YWcKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY2F0ZWdvcnkgdGVybSBjb3VudAogKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0X3RhZyB0ZXJtIGNvdW50CiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgVGVybV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGZpZWxkcyA9IFsKCQkndGVybV9pZCcsCgkJJ3Rlcm1fdGF4b25vbXlfaWQnLAoJCSduYW1lJywKCQknc2x1ZycsCgkJJ2Rlc2NyaXB0aW9uJywKCQkncGFyZW50JywKCQknY291bnQnLAoJXTsKCgkvKioKCSAqIExpc3RzIHRlcm1zIGluIGEgdGF4b25vbXkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0YXhvbm9teT4uLi4KCSAqIDogTGlzdCB0ZXJtcyBvZiBvbmUgb3IgbW9yZSB0YXhvbm9taWVzCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzIChzZWUgZ2V0X3Rlcm1zKCkgJGFyZ3MgcGFyYW1ldGVyIGZvciBhIGxpc3Qgb2YgZmllbGRzKS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHRlcm0uCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0gaWRzCgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHRlcm06CgkgKgoJICogKiB0ZXJtX2lkCgkgKiAqIHRlcm1fdGF4b25vbXlfaWQKCSAqICogbmFtZQoJICogKiBzbHVnCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIHBhcmVudAoJICogKiBjb3VudAoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiB1cmwKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgcG9zdCBjYXRlZ29yaWVzCgkgKiAgICAgJCB3cCB0ZXJtIGxpc3QgY2F0ZWdvcnkgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgdGVybV9pZCx0ZXJtX3RheG9ub215X2lkLG5hbWUsc2x1ZyxkZXNjcmlwdGlvbixwYXJlbnQsY291bnQKCSAqICAgICAyLDIsYWNpZm9ybSxhY2lmb3JtLCwwLDEKCSAqICAgICAzLDMsYW50aXF1YXJpYW5pc20sYW50aXF1YXJpYW5pc20sLDAsMQoJICogICAgIDQsNCxhcnJhbmdlbWVudCxhcnJhbmdlbWVudCwsMCwxCgkgKiAgICAgNSw1LGFzbW9kZXVzLGFzbW9kZXVzLCwwLDEKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3QgdGFncwoJICogICAgICQgd3AgdGVybSBsaXN0IHBvc3RfdGFnIC0tZmllbGRzPW5hbWUsc2x1ZwoJICogICAgICstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICAgIHwgc2x1ZyAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgOEJJVCAgICAgIHwgOGJpdCAgICAgICAgfAoJICogICAgIHwgYWxpZ25tZW50IHwgYWxpZ25tZW50LTIgfAoJICogICAgIHwgQXJ0aWNsZXMgIHwgYXJ0aWNsZXMgICAgfAoJICogICAgIHwgYXNpZGUgICAgIHwgYXNpZGUgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZm9yZWFjaCAoICRhcmdzIGFzICR0YXhvbm9teSApIHsKCQkJaWYgKCAhIHRheG9ub215X2V4aXN0cyggJHRheG9ub215ICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiVGF4b25vbXkgeyR0YXhvbm9teX0gZG9lc24ndCBleGlzdC4iICk7CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdoaWRlX2VtcHR5JyA9PiBmYWxzZSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1sndGVybV9pZCddICkgKSB7CgkJCSR0ZXJtICA9IGdldF90ZXJtX2J5KCAnaWQnLCAkYXNzb2NfYXJnc1sndGVybV9pZCddLCAkYXJnc1swXSApOwoJCQkkdGVybXMgPSBbICR0ZXJtIF07CgkJfSBlbHNlaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snaW5jbHVkZSddICkKCQkJJiYgISBlbXB0eSggJGFzc29jX2FyZ3NbJ29yZGVyYnknXSApCgkJCSYmICdpbmNsdWRlJyA9PT0gJGFzc29jX2FyZ3NbJ29yZGVyYnknXQoJCQkmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjcnLCAnPCcgKSApIHsKCQkJJHRlcm1zICAgID0gW107CgkJCSR0ZXJtX2lkcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2luY2x1ZGUnXSApOwoJCQlmb3JlYWNoICggJHRlcm1faWRzIGFzICR0ZXJtX2lkICkgewoJCQkJJHRlcm0gPSBnZXRfdGVybV9ieSggJ2lkJywgJHRlcm1faWQsICRhcmdzWzBdICk7CgkJCQlpZiAoICR0ZXJtICYmICEgaXNfd3BfZXJyb3IoICR0ZXJtICkgKSB7CgkJCQkJJHRlcm1zW10gPSAkdGVybTsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiSW52YWxpZCB0ZXJtIHskdGVybV9pZH0uIiApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJJHRlcm1zID0gZ2V0X3Rlcm1zKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQl9CgoJCSR0ZXJtcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICR0ZXJtICkgewoJCQkJCSR0ZXJtLT5jb3VudCAgPSAoaW50KSAkdGVybS0+Y291bnQ7CgkJCQkJJHRlcm0tPnBhcmVudCA9IChpbnQpICR0ZXJtLT5wYXJlbnQ7CgkJCQkJJHRlcm0tPnVybCAgICA9IGdldF90ZXJtX2xpbmsoICR0ZXJtICk7CgkJCQkJcmV0dXJuICR0ZXJtOwoJCQl9LAoJCQkkdGVybXMKCQkpOwoKCQlpZiAoICdpZHMnID09PSAkZm9ybWF0dGVyLT5mb3JtYXQgKSB7CgkJCSR0ZXJtcyA9IHdwX2xpc3RfcGx1Y2soICR0ZXJtcywgJ3Rlcm1faWQnICk7CgkJCWVjaG8gaW1wbG9kZSggJyAnLCAkdGVybXMgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdGVybXMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IHRlcm0uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGF4b25vbXkgZm9yIHRoZSBuZXcgdGVybS4KCSAqCgkgKiA8dGVybT4KCSAqIDogQSBuYW1lIGZvciB0aGUgbmV3IHRlcm0uCgkgKgoJICogWy0tc2x1Zz08c2x1Zz5dCgkgKiA6IEEgdW5pcXVlIHNsdWcgZm9yIHRoZSBuZXcgdGVybS4gRGVmYXVsdHMgdG8gc2FuaXRpemVkIHZlcnNpb24gb2YgbmFtZS4KCSAqCgkgKiBbLS1kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBBIGRlc2NyaXB0aW9uIGZvciB0aGUgbmV3IHRlcm0uCgkgKgoJICogWy0tcGFyZW50PTx0ZXJtLWlkPl0KCSAqIDogQSBwYXJlbnQgZm9yIHRoZSBuZXcgdGVybS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgdGVybSBpZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSBhIG5ldyBjYXRlZ29yeSAiQXBwbGUiIHdpdGggYSBkZXNjcmlwdGlvbi4KCSAqICAgICAkIHdwIHRlcm0gY3JlYXRlIGNhdGVnb3J5IEFwcGxlIC0tZGVzY3JpcHRpb249IkEgdHlwZSBvZiBmcnVpdCIKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIGNhdGVnb3J5IDE5OS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkdGF4b25vbXksICR0ZXJtICkgPSAkYXJnczsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdzbHVnJyAgICAgICAgPT4gc2FuaXRpemVfdGl0bGUoICR0ZXJtICksCgkJCSdkZXNjcmlwdGlvbicgPT4gJycsCgkJCSdwYXJlbnQnICAgICAgPT4gMCwKCQldOwoJCSRhc3NvY19hcmdzID0gd3BfcGFyc2VfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApOwoKCQkkcG9yY2VsYWluID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncG9yY2VsYWluJyApOwoJCXVuc2V0KCAkYXNzb2NfYXJnc1sncG9yY2VsYWluJ10gKTsKCgkJLy8gQ29tcGF0aWJpbGl0eSBmb3IgPCBXUCA0LjAKCQlpZiAoICRhc3NvY19hcmdzWydwYXJlbnQnXSA+IDAgJiYgISB0ZXJtX2V4aXN0cyggKGludCkgJGFzc29jX2FyZ3NbJ3BhcmVudCddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQYXJlbnQgdGVybSBkb2VzIG5vdCBleGlzdC4nICk7CgkJfQoKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCSR0ZXJtICAgICAgID0gd3Bfc2xhc2goICR0ZXJtICk7CgkJJHJlc3VsdCAgICAgPSB3cF9pbnNlcnRfdGVybSggJHRlcm0sICR0YXhvbm9teSwgJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJfSBlbHNlIHsKCQkJaWYgKCAkcG9yY2VsYWluICkgewoJCQkJV1BfQ0xJOjpsaW5lKCAkcmVzdWx0Wyd0ZXJtX2lkJ10gKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIkNyZWF0ZWQgeyR0YXhvbm9teX0geyRyZXN1bHRbJ3Rlcm1faWQnXX0uIiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogR2V0cyBkZXRhaWxzIGFib3V0IGEgdGVybS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRheG9ub215PgoJICogOiBUYXhvbm9teSBvZiB0aGUgdGVybSB0byBnZXQKCSAqCgkgKiA8dGVybT4KCSAqIDogSUQgb3Igc2x1ZyBvZiB0aGUgdGVybSB0byBnZXQKCSAqCgkgKiBbLS1ieT08ZmllbGQ+XQoJICogOiBFeHBsaWNpdGx5IGhhbmRsZSB0aGUgdGVybSB2YWx1ZSBhcyBhIHNsdWcgb3IgaWQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGlkCgkgKiBvcHRpb25zOgoJICogICAtIHNsdWcKCSAqICAgLSBpZAoJICogLS0tCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogSW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIHdob2xlIHRlcm0sIHJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuIERlZmF1bHRzIHRvIGFsbCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGRldGFpbHMgYWJvdXQgYSBjYXRlZ29yeSB3aXRoIGlkIDE5OS4KCSAqICAgICAkIHdwIHRlcm0gZ2V0IGNhdGVnb3J5IDE5OSAtLWZvcm1hdD1qc29uCgkgKiAgICAgeyJ0ZXJtX2lkIjoxOTksIm5hbWUiOiJBcHBsZSIsInNsdWciOiJhcHBsZSIsInRlcm1fZ3JvdXAiOjAsInRlcm1fdGF4b25vbXlfaWQiOjE5OSwidGF4b25vbXkiOiJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIjoiQSB0eXBlIG9mIGZydWl0IiwicGFyZW50IjowLCJjb3VudCI6MCwiZmlsdGVyIjoicmF3In0KCSAqCgkgKiAgICAgIyBHZXQgZGV0YWlscyBhYm91dCBhIGNhdGVnb3J5IHdpdGggc2x1ZyBhcHBsZS4KCSAqICAgICAkIHdwIHRlcm0gZ2V0IGNhdGVnb3J5IGFwcGxlIC0tYnk9c2x1ZyAtLWZvcm1hdD1qc29uCgkgKiAgICAgeyJ0ZXJtX2lkIjoxOTksIm5hbWUiOiJBcHBsZSIsInNsdWciOiJhcHBsZSIsInRlcm1fZ3JvdXAiOjAsInRlcm1fdGF4b25vbXlfaWQiOjE5OSwidGF4b25vbXkiOiJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIjoiQSB0eXBlIG9mIGZydWl0IiwicGFyZW50IjowLCJjb3VudCI6MCwiZmlsdGVyIjoicmF3In0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkdGF4b25vbXksICR0ZXJtICkgPSAkYXJnczsKCgkJJHRlcm0gPSBnZXRfdGVybV9ieSggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYnknICksICR0ZXJtLCAkdGF4b25vbXkgKTsKCgkJaWYgKCAhICR0ZXJtICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGVybSBkb2Vzbid0IGV4aXN0LiIgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkdGVybV9hcnJheSAgICAgICAgICAgPSBnZXRfb2JqZWN0X3ZhcnMoICR0ZXJtICk7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9IGFycmF5X2tleXMoICR0ZXJtX2FycmF5ICk7CgkJfQoKCQkkdGVybS0+Y291bnQgID0gKGludCkgJHRlcm0tPmNvdW50OwoJCSR0ZXJtLT5wYXJlbnQgPSAoaW50KSAkdGVybS0+cGFyZW50OwoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtKCAkdGVybSApOwoJfQoKCS8qKgoJICogVXBkYXRlcyBhbiBleGlzdGluZyB0ZXJtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGF4b25vbXk+CgkgKiA6IFRheG9ub215IG9mIHRoZSB0ZXJtIHRvIHVwZGF0ZS4KCSAqCgkgKiA8dGVybT4KCSAqIDogSUQgb3Igc2x1ZyBmb3IgdGhlIHRlcm0gdG8gdXBkYXRlLgoJICoKCSAqIFstLWJ5PTxmaWVsZD5dCgkgKiA6IEV4cGxpY2l0bHkgaGFuZGxlIHRoZSB0ZXJtIHZhbHVlIGFzIGEgc2x1ZyBvciBpZC4KCSAqIC0tLQoJICogZGVmYXVsdDogaWQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gc2x1ZwoJICogICAtIGlkCgkgKiAtLS0KCSAqCgkgKiBbLS1uYW1lPTxuYW1lPl0KCSAqIDogQSBuZXcgbmFtZSBmb3IgdGhlIHRlcm0uCgkgKgoJICogWy0tc2x1Zz08c2x1Zz5dCgkgKiA6IEEgbmV3IHNsdWcgZm9yIHRoZSB0ZXJtLgoJICoKCSAqIFstLWRlc2NyaXB0aW9uPTxkZXNjcmlwdGlvbj5dCgkgKiA6IEEgbmV3IGRlc2NyaXB0aW9uIGZvciB0aGUgdGVybS4KCSAqCgkgKiBbLS1wYXJlbnQ9PHRlcm0taWQ+XQoJICogOiBBIG5ldyBwYXJlbnQgZm9yIHRoZSB0ZXJtLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hhbmdlIGNhdGVnb3J5IHdpdGggaWQgMTUgdG8gdXNlIHRoZSBuYW1lICJBcHBsZSIKCSAqICAgICAkIHdwIHRlcm0gdXBkYXRlIGNhdGVnb3J5IDE1IC0tbmFtZT1BcHBsZQoJICogICAgIFN1Y2Nlc3M6IFRlcm0gdXBkYXRlZC4KCSAqCgkgKiAgICAgIyBDaGFuZ2UgY2F0ZWdvcnkgd2l0aCBzbHVnIGFwcGxlIHRvIHVzZSB0aGUgbmFtZSAiQXBwbGUiCgkgKiAgICAgJCB3cCB0ZXJtIHVwZGF0ZSBjYXRlZ29yeSBhcHBsZSAtLWJ5PXNsdWcgLS1uYW1lPUFwcGxlCgkgKiAgICAgU3VjY2VzczogVGVybSB1cGRhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWxpc3QoICR0YXhvbm9teSwgJHRlcm0gKSA9ICRhcmdzOwoKCQkkZGVmYXVsdHMgICA9IFsKCQkJJ25hbWUnICAgICAgICA9PiBudWxsLAoJCQknc2x1ZycgICAgICAgID0+IG51bGwsCgkJCSdkZXNjcmlwdGlvbicgPT4gbnVsbCwKCQkJJ3BhcmVudCcgICAgICA9PiBudWxsLAoJCV07CgkJJGFzc29jX2FyZ3MgPSB3cF9wYXJzZV9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICk7CgoJCWZvcmVhY2ggKCAkYXNzb2NfYXJncyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJaWYgKCBudWxsID09PSAkdmFsdWUgKSB7CgkJCQl1bnNldCggJGFzc29jX2FyZ3NbICRrZXkgXSApOwoJCQl9CgkJfQoKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoKCQkkdGVybSA9IGdldF90ZXJtX2J5KCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdieScgKSwgJHRlcm0sICR0YXhvbm9teSApOwoKCQlpZiAoICEgJHRlcm0gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUZXJtIGRvZXNuJ3QgZXhpc3QuIiApOwoJCX0KCgkJLy8gVXBkYXRlIHRlcm0uCgkJJHJlc3VsdCA9IHdwX3VwZGF0ZV90ZXJtKCAkdGVybS0+dGVybV9pZCwgJHRheG9ub215LCAkYXNzb2NfYXJncyApOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRyZXN1bHQtPmdldF9lcnJvcl9tZXNzYWdlKCkgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdUZXJtIHVwZGF0ZWQuJyApOwoJCX0KCX0KCgkvKioKCSAqIERlbGV0ZXMgYW4gZXhpc3RpbmcgdGVybS4KCSAqCgkgKiBFcnJvcnMgaWYgdGhlIHRlcm0gZG9lc24ndCBleGlzdCwgb3IgdGhlcmUgd2FzIGEgcHJvYmxlbSBpbiBkZWxldGluZyBpdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRheG9ub215PgoJICogOiBUYXhvbm9teSBvZiB0aGUgdGVybSB0byBkZWxldGUuCgkgKgoJICogPHRlcm0+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvciBzbHVncyBvZiB0ZXJtcyB0byBkZWxldGUuCgkgKgoJICogWy0tYnk9PGZpZWxkPl0KCSAqIDogRXhwbGljaXRseSBoYW5kbGUgdGhlIHRlcm0gdmFsdWUgYXMgYSBzbHVnIG9yIGlkLgoJICogLS0tCgkgKiBkZWZhdWx0OiBpZAoJICogb3B0aW9uczoKCSAqICAgLSBzbHVnCgkgKiAgIC0gaWQKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHBvc3QgY2F0ZWdvcnkgYnkgaWQKCSAqICAgICAkIHdwIHRlcm0gZGVsZXRlIGNhdGVnb3J5IDE1CgkgKiAgICAgRGVsZXRlZCBjYXRlZ29yeSAxNS4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIDEgb2YgMSB0ZXJtcy4KCSAqCgkgKiAgICAgIyBEZWxldGUgcG9zdCBjYXRlZ29yeSBieSBzbHVnCgkgKiAgICAgJCB3cCB0ZXJtIGRlbGV0ZSBjYXRlZ29yeSBhcHBsZSAtLWJ5PXNsdWcKCSAqICAgICBEZWxldGVkIGNhdGVnb3J5IDE1LgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMSBvZiAxIHRlcm1zLgoJICoKCSAqICAgICAjIERlbGV0ZSBhbGwgcG9zdCB0YWdzCgkgKiAgICAgJCB3cCB0ZXJtIGxpc3QgcG9zdF90YWcgLS1maWVsZD10ZXJtX2lkIHwgeGFyZ3Mgd3AgdGVybSBkZWxldGUgcG9zdF90YWcKCSAqICAgICBEZWxldGVkIHBvc3RfdGFnIDE1OS4KCSAqICAgICBEZWxldGVkIHBvc3RfdGFnIDE2MC4KCSAqICAgICBEZWxldGVkIHBvc3RfdGFnIDE2MS4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIDMgb2YgMyB0ZXJtcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0YXhvbm9teSA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJHRlcm1faWQgKSB7CgoJCQkkdGVybSA9ICR0ZXJtX2lkOwoKCQkJLy8gR2V0IHRlcm0gYnkgc3BlY2lmaWVkIGFyZ3VtZW50IG90aGVyd2lzZSBnZXQgdGVybSBieSBpZC4KCQkJJGZpZWxkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYnknICk7CgkJCWlmICggJ3NsdWcnID09PSAkZmllbGQgKSB7CgoJCQkJLy8gR2V0IHRlcm0gYnkgc2x1Zy4KCQkJCSR0ZXJtID0gZ2V0X3Rlcm1fYnkoICRmaWVsZCwgJHRlcm0sICR0YXhvbm9teSApOwoKCQkJCS8vIElmIHRlcm0gbm90IGZvdW5kLCB0aGVuIHNob3cgZXJyb3IgbWVzc2FnZSBhbmQgc2tpcCB0aGUgaXRlcmF0aW9uLgoJCQkJaWYgKCAhICR0ZXJtICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggInskdGF4b25vbXl9IHskdGVybV9pZH0gZG9lc24ndCBleGlzdC4iICk7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJLy8gR2V0IHRoZSB0ZXJtIGlkOwoJCQkJJHRlcm1faWQgPSAkdGVybS0+dGVybV9pZDsKCgkJCX0KCgkJCSRyZXN1bHQgPSB3cF9kZWxldGVfdGVybSggJHRlcm1faWQsICR0YXhvbm9teSApOwoKCQkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkcmVzdWx0ICk7CgkJCQkkZXJyb3JzKys7CgkJCX0gZWxzZWlmICggJHJlc3VsdCApIHsKCQkJCVdQX0NMSTo6bG9nKCAiRGVsZXRlZCB7JHRheG9ub215fSB7JHRlcm1faWR9LiIgKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6d2FybmluZyggInskdGF4b25vbXl9IHskdGVybV9pZH0gZG9lc24ndCBleGlzdC4iICk7CgkJCX0KCQl9CgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAndGVybScsICdkZWxldGUnLCBjb3VudCggJGFyZ3MgKSwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIHNvbWUgdGVybXMuCgkgKgoJICogQ3JlYXRlcyBhIHNwZWNpZmllZCBudW1iZXIgb2YgbmV3IHRlcm1zIHdpdGggZHVtbXkgZGF0YS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRheG9ub215PgoJICogOiBUaGUgdGF4b25vbXkgZm9yIHRoZSBnZW5lcmF0ZWQgdGVybXMuCgkgKgoJICogWy0tY291bnQ9PG51bWJlcj5dCgkgKiA6IEhvdyBtYW55IHRlcm1zIHRvIGdlbmVyYXRlPwoJICogLS0tCgkgKiBkZWZhdWx0OiAxMDAKCSAqIC0tLQoJICoKCSAqIFstLW1heF9kZXB0aD08bnVtYmVyPl0KCSAqIDogR2VuZXJhdGUgY2hpbGQgdGVybXMgZG93biB0byBhIGNlcnRhaW4gZGVwdGguCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDEKCSAqIC0tLQoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiBwcm9ncmVzcwoJICogb3B0aW9uczoKCSAqICAgLSBwcm9ncmVzcwoJICogICAtIGlkcwoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBwb3N0IGNhdGVnb3JpZXMuCgkgKiAgICAgJCB3cCB0ZXJtIGdlbmVyYXRlIGNhdGVnb3J5IC0tY291bnQ9MTAKCSAqICAgICBHZW5lcmF0aW5nIHRlcm1zICAxMDAlIFs9PT09PT09PT1dIDA6MDIgLyAwOjAyCgkgKgoJICogICAgICMgQWRkIG1ldGEgdG8gZXZlcnkgZ2VuZXJhdGVkIHRlcm0uCgkgKiAgICAgJCB3cCB0ZXJtIGdlbmVyYXRlIGNhdGVnb3J5IC0tZm9ybWF0PWlkcyAtLWNvdW50PTMgfCB4YXJncyAtZCAnICcgLUkgJSB3cCB0ZXJtIG1ldGEgYWRkICUgZm9vIGJhcgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2VuZXJhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCWxpc3QgKCAkdGF4b25vbXkgKSA9ICRhcmdzOwoKCQkkZGVmYXVsdHMgPSBbCgkJCSdjb3VudCcgICAgID0+IDEwMCwKCQkJJ21heF9kZXB0aCcgPT4gMSwKCQldOwoKCQkkZmluYWxfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgkJJGNvdW50ICAgICAgPSAkZmluYWxfYXJnc1snY291bnQnXTsKCQkkbWF4X2RlcHRoICA9ICRmaW5hbF9hcmdzWydtYXhfZGVwdGgnXTsKCgkJaWYgKCAhIHRheG9ub215X2V4aXN0cyggJHRheG9ub215ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICIneyR0YXhvbm9teX0nIGlzIG5vdCBhIHJlZ2lzdGVyZWQgdGF4b25vbXkuIiApOwoJCX0KCgkJJGxhYmVsID0gZ2V0X3RheG9ub215KCAkdGF4b25vbXkgKS0+bGFiZWxzLT5zaW5ndWxhcl9uYW1lOwoJCSRzbHVnICA9IHNhbml0aXplX3RpdGxlX3dpdGhfZGFzaGVzKCAkbGFiZWwgKTsKCgkJJGhpZXJhcmNoaWNhbCA9IGdldF90YXhvbm9teSggJHRheG9ub215ICktPmhpZXJhcmNoaWNhbDsKCgkJJGZvcm1hdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcsICdwcm9ncmVzcycgKTsKCgkJJG5vdGlmeSA9IGZhbHNlOwoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeSA9IFV0aWxzXG1ha2VfcHJvZ3Jlc3NfYmFyKCAnR2VuZXJhdGluZyB0ZXJtcycsICRjb3VudCApOwoJCX0KCgkJJHByZXZpb3VzX3Rlcm1faWQgPSAwOwoJCSRjdXJyZW50X3BhcmVudCAgID0gMDsKCQkkY3VycmVudF9kZXB0aCAgICA9IDE7CgoJCSRtYXhfaWQgPSAoaW50KSAkd3BkYi0+Z2V0X3ZhciggIlNFTEVDVCB0ZXJtX3RheG9ub215X2lkIEZST00geyR3cGRiLT50ZXJtX3RheG9ub215fSBPUkRFUiBCWSB0ZXJtX3RheG9ub215X2lkIERFU0MgTElNSVQgMSIgKTsKCgkJJHN1c3BlbmRfY2FjaGVfaW52YWxpZGF0aW9uID0gd3Bfc3VzcGVuZF9jYWNoZV9pbnZhbGlkYXRpb24oIHRydWUgKTsKCQkkY3JlYXRlZCAgICAgICAgICAgICAgICAgICAgPSBbXTsKCgkJZm9yICggJGluZGV4ID0gJG1heF9pZCArIDE7ICRpbmRleCA8PSAkbWF4X2lkICsgJGNvdW50OyAkaW5kZXgrKyApIHsKCgkJCWlmICggJGhpZXJhcmNoaWNhbCApIHsKCgkJCQlpZiAoICRwcmV2aW91c190ZXJtX2lkICYmICR0aGlzLT5tYXliZV9tYWtlX2NoaWxkKCkgJiYgJGN1cnJlbnRfZGVwdGggPCAkbWF4X2RlcHRoICkgewoKCQkJCQkkY3VycmVudF9wYXJlbnQgPSAkcHJldmlvdXNfdGVybV9pZDsKCQkJCQkkY3VycmVudF9kZXB0aCsrOwoKCQkJCX0gZWxzZWlmICggJHRoaXMtPm1heWJlX3Jlc2V0X2RlcHRoKCkgKSB7CgoJCQkJCSRjdXJyZW50X3BhcmVudCA9IDA7CgkJCQkJJGN1cnJlbnRfZGVwdGggID0gMTsKCgkJCQl9CgkJCX0KCgkJCSRhcmdzID0gWwoJCQkJJ3BhcmVudCcgPT4gJGN1cnJlbnRfcGFyZW50LAoJCQkJJ3NsdWcnICAgPT4gJHNsdWcgLiAiLXskaW5kZXh9IiwKCQkJXTsKCgkJCSRuYW1lID0gInskbGFiZWx9IHskaW5kZXh9IjsKCQkJJHRlcm0gPSB3cF9pbnNlcnRfdGVybSggJG5hbWUsICR0YXhvbm9teSwgJGFyZ3MgKTsKCQkJaWYgKCBpc193cF9lcnJvciggJHRlcm0gKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJHRlcm0gKTsKCQkJfSBlbHNlIHsKCQkJCSRjcmVhdGVkW10gICAgICAgID0gJHRlcm1bJ3Rlcm1faWQnXTsKCQkJCSRwcmV2aW91c190ZXJtX2lkID0gJHRlcm1bJ3Rlcm1faWQnXTsKCQkJCWlmICggJ2lkcycgPT09ICRmb3JtYXQgKSB7CgkJCQkJZWNobyAkdGVybVsndGVybV9pZCddOwoJCQkJCWlmICggJGluZGV4IDwgJG1heF9pZCArICRjb3VudCApIHsKCQkJCQkJZWNobyAnICc7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCQkkbm90aWZ5LT50aWNrKCk7CgkJCX0KCQl9CgoJCXdwX3N1c3BlbmRfY2FjaGVfaW52YWxpZGF0aW9uKCAkc3VzcGVuZF9jYWNoZV9pbnZhbGlkYXRpb24gKTsKCQljbGVhbl90ZXJtX2NhY2hlKCAkY3JlYXRlZCwgJHRheG9ub215ICk7CgoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeS0+ZmluaXNoKCk7CgkJfQoJfQoKCS8qKgoJICogUmVjYWxjdWxhdGVzIG51bWJlciBvZiBwb3N0cyBhc3NpZ25lZCB0byBlYWNoIHRlcm0uCgkgKgoJICogSW4gaW5zdGFuY2VzIHdoZXJlIG1hbnVhbCB1cGRhdGVzIGFyZSBtYWRlIHRvIHRoZSB0ZXJtcyBhc3NpZ25lZCB0bwoJICogcG9zdHMgaW4gdGhlIGRhdGFiYXNlLCB0aGUgbnVtYmVyIG9mIHBvc3RzIGFzc29jaWF0ZWQgd2l0aCBhIHRlcm0KCSAqIGNhbiBiZWNvbWUgb3V0LW9mLXN5bmMgd2l0aCB0aGUgYWN0dWFsIG51bWJlciBvZiBwb3N0cy4KCSAqCgkgKiBUaGlzIGNvbW1hbmQgcnVucyB3cF91cGRhdGVfdGVybV9jb3VudCgpIG9uIHRoZSB0YXhvbm9teSdzIHRlcm1zCgkgKiB0byBicmluZyB0aGUgY291bnQgYmFjayB0byB0aGUgY29ycmVjdCB2YWx1ZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRheG9ub215Pi4uLgoJICogOiBPbmUgb3IgbW9yZSB0YXhvbm9taWVzIHRvIHJlY2FsY3VsYXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVjb3VudCBwb3N0cyBhc3NpZ25lZCB0byBlYWNoIGNhdGVnb3JpZXMgYW5kIHRhZ3MKCSAqICAgICAkIHdwIHRlcm0gcmVjb3VudCBjYXRlZ29yeSBwb3N0X3RhZwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY2F0ZWdvcnkgdGVybSBjb3VudC4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIHBvc3RfdGFnIHRlcm0gY291bnQuCgkgKgoJICogICAgICMgUmVjb3VudCBhbGwgbGlzdGVkIHRheG9ub21pZXMKCSAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1maWVsZD1uYW1lIHwgeGFyZ3Mgd3AgdGVybSByZWNvdW50CgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBjYXRlZ29yeSB0ZXJtIGNvdW50LgoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdF90YWcgdGVybSBjb3VudC4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIG5hdl9tZW51IHRlcm0gY291bnQuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBsaW5rX2NhdGVnb3J5IHRlcm0gY291bnQuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0X2Zvcm1hdCB0ZXJtIGNvdW50LgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVjb3VudCggJGFyZ3MgKSB7CgkJZm9yZWFjaCAoICRhcmdzIGFzICR0YXhvbm9teSApIHsKCgkJCWlmICggISB0YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVGF4b25vbXkgeyR0YXhvbm9teX0gZG9lcyBub3QgZXhpc3QuIiApOwoJCQl9IGVsc2UgewoKCQkJCSR0ZXJtcyAgICAgICAgICAgICA9IGdldF90ZXJtcyggJHRheG9ub215LCBbICdoaWRlX2VtcHR5JyA9PiBmYWxzZSBdICk7CgkJCQkkdGVybV90YXhvbm9teV9pZHMgPSB3cF9saXN0X3BsdWNrKCAkdGVybXMsICd0ZXJtX3RheG9ub215X2lkJyApOwoKCQkJCXdwX3VwZGF0ZV90ZXJtX2NvdW50KCAkdGVybV90YXhvbm9teV9pZHMsICR0YXhvbm9teSApOwoKCQkJCVdQX0NMSTo6c3VjY2VzcyggIlVwZGF0ZWQgeyR0YXhvbm9teX0gdGVybSBjb3VudC4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBNaWdyYXRlIGEgdGVybSBvZiBhIHRheG9ub215IHRvIGFub3RoZXIgdGF4b25vbXkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0ZXJtPgoJICogOiBTbHVnIG9yIElEIG9mIHRoZSB0ZXJtIHRvIG1pZ3JhdGUuCgkgKgoJICogWy0tYnk9PGZpZWxkPl0KCSAqIDogRXhwbGljaXRseSBoYW5kbGUgdGhlIHRlcm0gdmFsdWUgYXMgYSBzbHVnIG9yIGlkLgoJICogLS0tCgkgKiBkZWZhdWx0OiBpZAoJICogb3B0aW9uczoKCSAqICAgLSBzbHVnCgkgKiAgIC0gaWQKCSAqIC0tLQoJICoKCSAqIFstLWZyb209PHRheG9ub215Pl0KCSAqIDogVGF4b25vbXkgc2x1ZyBvZiB0aGUgdGVybSB0byBtaWdyYXRlLgoJICoKCSAqIFstLXRvPTx0YXhvbm9teT5dCgkgKiA6IFRheG9ub215IHNsdWcgdG8gbWlncmF0ZSB0by4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIE1pZ3JhdGUgYSBjYXRlZ29yeSdzIHRlcm0gKHZpZGVvKSB0byB0YWcgdGF4b25vbXkuCgkgKiAgICAgJCB3cCB0ZXJtIG1pZ3JhdGUgOTE5MCAtLWZyb209Y2F0ZWdvcnkgLS10bz1wb3N0X3RhZwoJICogICAgIFRlcm0gJzkxOTAnIG1pZ3JhdGVkIQoJICogICAgIE9sZCBpbnN0YW5jZSBvZiB0ZXJtICc5MTkwJyByZW1vdmVkIGZyb20gaXRzIG9yaWdpbmFsIHRheG9ub215LgoJICogICAgIFN1Y2Nlc3M6IE1pZ3JhdGVkIHRoZSB0ZXJtICc5MTkwJyBmcm9tIHRheG9ub215ICdjYXRlZ29yeScgdG8gdGF4b25vbXkgJ3Bvc3RfdGFnJyBmb3IgMSBwb3N0cwoJICovCglwdWJsaWMgZnVuY3Rpb24gbWlncmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0ZXJtX3JlZmVyZW5jZSAgICAgICA9ICRhcmdzWzBdOwoJCSRvcmlnaW5hbF90YXhvbm9teSAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zyb20nICk7CgkJJGRlc3RpbmF0aW9uX3RheG9ub215ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndG8nICk7CgoJCSR0ZXJtID0gZ2V0X3Rlcm1fYnkoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2J5JyApLCAkdGVybV9yZWZlcmVuY2UsICRvcmlnaW5hbF90YXhvbm9teSApOwoKCQlpZiAoICEgJHRlcm0gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUYXhvbm9teSB0ZXJtICd7JHRlcm1fcmVmZXJlbmNlfScgZm9yIHRheG9ub215ICd7JG9yaWdpbmFsX3RheG9ub215fScgZG9lc24ndCBleGlzdC4iICk7CgkJfQoKCQkkb3JpZ2luYWxfdGF4b25vbXkgPSBnZXRfdGF4b25vbXkoICRvcmlnaW5hbF90YXhvbm9teSApOwoKCQkkaWQgPSB3cF9pbnNlcnRfdGVybSgKCQkJJHRlcm0tPm5hbWUsCgkJCSRkZXN0aW5hdGlvbl90YXhvbm9teSwKCQkJWwoJCQkJJ3NsdWcnICAgICAgICA9PiAkdGVybS0+c2x1ZywKCQkJCSdwYXJlbnQnICAgICAgPT4gMCwKCQkJCSdkZXNjcmlwdGlvbicgPT4gJHRlcm0tPmRlc2NyaXB0aW9uLAoJCQldCgkJKTsKCgkJaWYgKCBpc193cF9lcnJvciggJGlkICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRpZC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCX0KCgkJJHBvc3RfaWRzID0gZ2V0X29iamVjdHNfaW5fdGVybSggJHRlcm0tPnRlcm1faWQsICRvcmlnaW5hbF90YXhvbm9teS0+bmFtZSApOwoKCQlmb3JlYWNoICggJHBvc3RfaWRzIGFzICRwb3N0X2lkICkgewoJCQkkdHlwZSA9IGdldF9wb3N0X3R5cGUoICRwb3N0X2lkICk7CgkJCWlmICggaW5fYXJyYXkoICR0eXBlLCAkb3JpZ2luYWxfdGF4b25vbXktPm9iamVjdF90eXBlLCB0cnVlICkgKSB7CgkJCQkkdGVybV90YXhvbm9teV9pZCA9IHdwX3NldF9vYmplY3RfdGVybXMoICRwb3N0X2lkLCAkaWRbJ3Rlcm1faWQnXSwgJGRlc3RpbmF0aW9uX3RheG9ub215LCB0cnVlICk7CgoJCQkJaWYgKCBpc193cF9lcnJvciggJHRlcm1fdGF4b25vbXlfaWQgKSApIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAiRmFpbGVkIHRvIGFzc2lnbiB0aGUgdGVybSAneyR0ZXJtLT5zbHVnfScgdG8gdGhlIHBvc3QgeyRwb3N0X2lkfS4gUmVhc29uOiAiIC4gJHRlcm1fdGF4b25vbXlfaWQtPmdldF9lcnJvcl9tZXNzYWdlKCkgKTsKCQkJCX0KCgkJCQlXUF9DTEk6OmxvZyggIlRlcm0gJ3skdGVybS0+c2x1Z30nIGFzc2lnbmVkIHRvIHBvc3QgeyRwb3N0X2lkfS4iICk7CgkJCX0KCgkJCWNsZWFuX3Bvc3RfY2FjaGUoICRwb3N0X2lkICk7CgkJfQoKCQljbGVhbl90ZXJtX2NhY2hlKCAkdGVybS0+dGVybV9pZCApOwoKCQlXUF9DTEk6OmxvZyggIlRlcm0gJ3skdGVybS0+c2x1Z30nIG1pZ3JhdGVkLiIgKTsKCgkJJGRlbCA9IHdwX2RlbGV0ZV90ZXJtKCAkdGVybS0+dGVybV9pZCwgJG9yaWdpbmFsX3RheG9ub215LT5uYW1lICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRkZWwgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkZhaWxlZCB0byBkZWxldGUgdGhlIHRlcm0gJ3skdGVybS0+c2x1Z30nLiBSZWFzb246ICIgLiAkZGVsLT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJfQoKCQlXUF9DTEk6OmxvZyggIk9sZCBpbnN0YW5jZSBvZiB0ZXJtICd7JHRlcm0tPnNsdWd9JyByZW1vdmVkIGZyb20gaXRzIG9yaWdpbmFsIHRheG9ub215LiIgKTsKCQkkcG9zdF9jb3VudCAgPSBjb3VudCggJHBvc3RfaWRzICk7CgkJJHBvc3RfcGx1cmFsID0gVXRpbHNccGx1cmFsaXplKCAncG9zdCcsICRwb3N0X2NvdW50ICk7CgkJV1BfQ0xJOjpzdWNjZXNzKCAiTWlncmF0ZWQgdGhlIHRlcm0gJ3skdGVybS0+c2x1Z30nIGZyb20gdGF4b25vbXkgJ3skb3JpZ2luYWxfdGF4b25vbXktPm5hbWV9JyB0byB0YXhvbm9teSAneyRkZXN0aW5hdGlvbl90YXhvbm9teX0nIGZvciB7JHBvc3RfY291bnR9IHskcG9zdF9wbHVyYWx9LiIgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIG1heWJlX21ha2VfY2hpbGQoKSB7CgkJLy8gNTAlIGNoYW5jZSBvZiBtYWtpbmcgY2hpbGQgdGVybS4KCQlyZXR1cm4gKCB3cF9yYW5kKCAxLCAyICkgPT09IDEgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIG1heWJlX3Jlc2V0X2RlcHRoKCkgewoJCS8vIDEwJSBjaGFuY2Ugb2YgcmVzZXRpbmcgdG8gcm9vdCBkZXB0aC4KCQlyZXR1cm4gKCB3cF9yYW5kKCAxLCAxMCApID09PSA3ICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzLCAndGVybScgKTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxFbnRpdHlcUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlcjsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcRW50aXR5XFV0aWxzIGFzIEVudGl0eVV0aWxzOwoKLyoqCiAqIFJldHJpZXZlcyBhbmQgc2V0cyBzaXRlIG9wdGlvbnMsIGluY2x1ZGluZyBwbHVnaW4gYW5kIFdvcmRQcmVzcyBzZXR0aW5ncy4KICoKICogU2VlIHRoZSBbUGx1Z2luIFNldHRpbmdzIEFQSV0oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9wbHVnaW5zL3NldHRpbmdzL3NldHRpbmdzLWFwaS8pIGFuZCB0aGUgW1RoZW1lIE9wdGlvbnNdKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvdGhlbWVzL2N1c3RvbWl6ZS1hcGkvKSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBhZGRpbmcgY3VzdG9taXplZCBvcHRpb25zLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBHZXQgc2l0ZSBVUkwuCiAqICAgICAkIHdwIG9wdGlvbiBnZXQgc2l0ZXVybAogKiAgICAgaHR0cDovL2V4YW1wbGUuY29tCiAqCiAqICAgICAjIEFkZCBvcHRpb24uCiAqICAgICAkIHdwIG9wdGlvbiBhZGQgbXlfb3B0aW9uIGZvb2JhcgogKiAgICAgU3VjY2VzczogQWRkZWQgJ215X29wdGlvbicgb3B0aW9uLgogKgogKiAgICAgIyBVcGRhdGUgb3B0aW9uLgogKiAgICAgJCB3cCBvcHRpb24gdXBkYXRlIG15X29wdGlvbiAneyJmb28iOiAiYmFyIn0nIC0tZm9ybWF0PWpzb24KICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ215X29wdGlvbicgb3B0aW9uLgogKgogKiAgICAgIyBEZWxldGUgb3B0aW9uLgogKiAgICAgJCB3cCBvcHRpb24gZGVsZXRlIG15X29wdGlvbgogKiAgICAgU3VjY2VzczogRGVsZXRlZCAnbXlfb3B0aW9uJyBvcHRpb24uCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgT3B0aW9uX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBHZXRzIHRoZSB2YWx1ZSBmb3IgYW4gb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBLZXkgZm9yIHRoZSBvcHRpb24uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBHZXQgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdmFyX2V4cG9ydAoJICogb3B0aW9uczoKCSAqICAgLSB2YXJfZXhwb3J0CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IG9wdGlvbi4KCSAqICAgICAkIHdwIG9wdGlvbiBnZXQgaG9tZQoJICogICAgIGh0dHA6Ly9leGFtcGxlLmNvbQoJICoKCSAqICAgICAjIEdldCBibG9nIGRlc2NyaXB0aW9uLgoJICogICAgICQgd3Agb3B0aW9uIGdldCBibG9nZGVzY3JpcHRpb24KCSAqICAgICBBIHJhbmRvbSBibG9nIGRlc2NyaXB0aW9uCgkgKgoJICogICAgICMgR2V0IGJsb2cgbmFtZQoJICogICAgICQgd3Agb3B0aW9uIGdldCBibG9nbmFtZQoJICogICAgIEEgcmFuZG9tIGJsb2cgbmFtZQoJICoKCSAqICAgICAjIEdldCBhZG1pbiBlbWFpbC4KCSAqICAgICAkIHdwIG9wdGlvbiBnZXQgYWRtaW5fZW1haWwKCSAqICAgICBzb21lb25lQGV4YW1wbGUuY29tCgkgKgoJICogICAgICMgR2V0IG9wdGlvbiBpbiBKU09OIGZvcm1hdC4KCSAqICAgICAkIHdwIG9wdGlvbiBnZXQgYWN0aXZlX3BsdWdpbnMgLS1mb3JtYXQ9anNvbgoJICogICAgIHsiMCI6ImR5bmFtaWNhbGx5LWR5bmFtaWMtc2lkZWJhclwvZHluYW1pY2FsbHktZHluYW1pYy1zaWRlYmFyLnBocCIsIjEiOiJtb25zdGVyLXdpZGdldFwvbW9uc3Rlci13aWRnZXQucGhwIiwiMiI6InNob3ctY3VycmVudC10ZW1wbGF0ZVwvc2hvdy1jdXJyZW50LXRlbXBsYXRlLnBocCIsIjMiOiJ0aGVtZS1jaGVja1wvdGhlbWUtY2hlY2sucGhwIiwiNSI6IndvcmRwcmVzcy1pbXBvcnRlclwvd29yZHByZXNzLWltcG9ydGVyLnBocCJ9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5ICkgPSAkYXJnczsKCgkJJHZhbHVlID0gZ2V0X29wdGlvbiggJGtleSApOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgZ2V0ICd7JGtleX0nIG9wdGlvbi4gRG9lcyBpdCBleGlzdD8iICk7CgkJfQoKCQlXUF9DTEk6OnByaW50X3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgbmV3IG9wdGlvbiB2YWx1ZS4KCSAqCgkgKiBFcnJvcnMgaWYgdGhlIG9wdGlvbiBhbHJlYWR5IGV4aXN0cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIG9wdGlvbiB0byBhZGQuCgkgKgoJICogWzx2YWx1ZT5dCgkgKiA6IFRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uIHRvIGFkZC4gSWYgb21taXRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKgoJICogWy0tYXV0b2xvYWQ9PGF1dG9sb2FkPl0KCSAqIDogU2hvdWxkIHRoaXMgb3B0aW9uIGJlIGF1dG9tYXRpY2FsbHkgbG9hZGVkLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtICd5ZXMnCgkgKiAgIC0gJ25vJwoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDcmVhdGUgYW4gb3B0aW9uIGJ5IHJlYWRpbmcgYSBKU09OIGZpbGUuCgkgKiAgICAgJCB3cCBvcHRpb24gYWRkIG15X29wdGlvbiAtLWZvcm1hdD1qc29uIDwgY29uZmlnLmpzb24KCSAqICAgICBTdWNjZXNzOiBBZGRlZCAnbXlfb3B0aW9uJyBvcHRpb24uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkka2V5ID0gJGFyZ3NbMF07CgoJCSR2YWx1ZSA9IFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgMSApOwoJCSR2YWx1ZSA9IFdQX0NMSTo6cmVhZF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2F1dG9sb2FkJyApID09PSAnbm8nICkgewoJCQkkYXV0b2xvYWQgPSAnbm8nOwoJCX0gZWxzZSB7CgkJCSRhdXRvbG9hZCA9ICd5ZXMnOwoJCX0KCgkJaWYgKCAhIGFkZF9vcHRpb24oICRrZXksICR2YWx1ZSwgJycsICRhdXRvbG9hZCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGFkZCBvcHRpb24gJ3ska2V5fScuIERvZXMgaXQgYWxyZWFkeSBleGlzdD8iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQWRkZWQgJ3ska2V5fScgb3B0aW9uLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBMaXN0cyBvcHRpb25zIGFuZCB0aGVpciB2YWx1ZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXNlYXJjaD08cGF0dGVybj5dCgkgKiA6IFVzZSB3aWxkY2FyZHMgKCAqIGFuZCA/ICkgdG8gbWF0Y2ggb3B0aW9uIG5hbWUuCgkgKgoJICogWy0tZXhjbHVkZT08cGF0dGVybj5dCgkgKiA6IFBhdHRlcm4gdG8gZXhjbHVkZS4gVXNlIHdpbGRjYXJkcyAoICogYW5kID8gKSB0byBtYXRjaCBvcHRpb24gbmFtZS4KCSAqCgkgKiBbLS1hdXRvbG9hZD08dmFsdWU+XQoJICogOiBNYXRjaCBvbmx5IGF1dG9sb2FkIG9wdGlvbnMgd2hlbiB2YWx1ZSBpcyBvbiwgYW5kIG9ubHkgbm90LWF1dG9sb2FkIG9wdGlvbiB3aGVuIG9mZi4KCSAqCgkgKiBbLS10cmFuc2llbnRzXQoJICogOiBMaXN0IG9ubHkgdHJhbnNpZW50cy4gVXNlIGAtLW5vLXRyYW5zaWVudHNgIHRvIGlnbm9yZSBhbGwgdHJhbnNpZW50cy4KCSAqCgkgKiBbLS11bnNlcmlhbGl6ZV0KCSAqIDogVW5zZXJpYWxpemUgb3B0aW9uIHZhbHVlcyBpbiBvdXRwdXQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLiB0b3RhbF9ieXRlcyBkaXNwbGF5cyB0aGUgdG90YWwgc2l6ZSBvZiBtYXRjaGluZyBvcHRpb25zIGluIGJ5dGVzLgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGpzb24KCSAqICAgLSBjc3YKCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqICAgLSB0b3RhbF9ieXRlcwoJICogLS0tCgkgKgoJICogWy0tb3JkZXJieT08ZmllbGRzPl0KCSAqIDogU2V0IG9yZGVyYnkgd2hpY2ggZmllbGQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IG9wdGlvbl9pZAoJICogb3B0aW9uczoKCSAqICAtIG9wdGlvbl9pZAoJICogIC0gb3B0aW9uX25hbWUKCSAqICAtIG9wdGlvbl92YWx1ZQoJICogLS0tCgkgKgoJICogWy0tb3JkZXI9PG9yZGVyPl0KCSAqIDogU2V0IGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIG9yZGVyLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhc2MKCSAqIG9wdGlvbnM6CgkgKiAgLSBhc2MKCSAqICAtIGRlc2MKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGlzIGZpZWxkIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggbWF0Y2hpbmcgb3B0aW9uOgoJICoKCSAqICogb3B0aW9uX25hbWUKCSAqICogb3B0aW9uX3ZhbHVlCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIGF1dG9sb2FkCgkgKiAqIHNpemVfYnl0ZXMKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCB0aGUgdG90YWwgc2l6ZSBvZiBhbGwgYXV0b2xvYWQgb3B0aW9ucy4KCSAqICAgICAkIHdwIG9wdGlvbiBsaXN0IC0tYXV0b2xvYWQ9b24gLS1mb3JtYXQ9dG90YWxfYnl0ZXMKCSAqICAgICAzMzE5OAoJICoKCSAqICAgICAjIEZpbmQgYmlnZ2VzdCB0cmFuc2llbnRzLgoJICogICAgICQgd3Agb3B0aW9uIGxpc3QgLS1zZWFyY2g9IipfdHJhbnNpZW50XyoiIC0tZmllbGRzPW9wdGlvbl9uYW1lLHNpemVfYnl0ZXMgfCBzb3J0IC1uIC1rIDIgfCB0YWlsCgkgKiAgICAgb3B0aW9uX25hbWUgc2l6ZV9ieXRlcwoJICogICAgIF9zaXRlX3RyYW5zaWVudF90aW1lb3V0X3RoZW1lX3Jvb3RzIDEwCgkgKiAgICAgX3NpdGVfdHJhbnNpZW50X3RoZW1lX3Jvb3RzIDc2CgkgKiAgICAgX3NpdGVfdHJhbnNpZW50X3VwZGF0ZV90aGVtZXMgICAxODEKCSAqICAgICBfc2l0ZV90cmFuc2llbnRfdXBkYXRlX2NvcmUgODA4CgkgKiAgICAgX3NpdGVfdHJhbnNpZW50X3VwZGF0ZV9wbHVnaW5zICA2NjQ1CgkgKgoJICogICAgICMgTGlzdCBhbGwgb3B0aW9ucyBiZWdpbm5pbmcgd2l0aCAiaTJmXyIuCgkgKiAgICAgJCB3cCBvcHRpb24gbGlzdCAtLXNlYXJjaD0iaTJmXyoiCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBvcHRpb25fbmFtZSB8IG9wdGlvbl92YWx1ZSB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBpMmZfdmVyc2lvbiB8IDAuMS4wICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCBvcHRpb25zIGJlZ2lubmluZyB3aXRoICJ0aGVtZV9tb2RzXyIuCgkgKiAgICAgJCB3cCBvcHRpb24gbGlzdCAtLXNlYXJjaD0idGhlbWVfbW9kc18qIiAtLWZpZWxkPW9wdGlvbl9uYW1lIHwgeGFyZ3MgLUkgJSB3cCBvcHRpb24gZGVsZXRlICUKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICd0aGVtZV9tb2RzX3R3ZW50eXNpeHRlZW4nIG9wdGlvbi4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICd0aGVtZV9tb2RzX3R3ZW50eWZpZnRlZW4nIG9wdGlvbi4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICd0aGVtZV9tb2RzX3R3ZW50eWZvdXJ0ZWVuJyBvcHRpb24uCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJZ2xvYmFsICR3cGRiOwoJCSRwYXR0ZXJuICAgICAgICA9ICclJzsKCQkkZXhjbHVkZSAgICAgICAgPSAnJzsKCQkkZmllbGRzICAgICAgICAgPSBhcnJheSggJ29wdGlvbl9uYW1lJywgJ29wdGlvbl92YWx1ZScgKTsKCQkkc2l6ZV9xdWVyeSAgICAgPSAnLExFTkdUSChvcHRpb25fdmFsdWUpIEFTIGBzaXplX2J5dGVzYCc7CgkJJGF1dG9sb2FkX3F1ZXJ5ID0gJyc7CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydzZWFyY2gnXSApICkgewoJCQkkcGF0dGVybiA9IHNlbGY6OmVzY19saWtlKCAkYXNzb2NfYXJnc1snc2VhcmNoJ10gKTsKCQkJLy8gc3Vic3RpdHV0ZSB3aWxkY2FyZHMKCQkJJHBhdHRlcm4gPSBzdHJfcmVwbGFjZSggJyonLCAnJScsICRwYXR0ZXJuICk7CgkJCSRwYXR0ZXJuID0gc3RyX3JlcGxhY2UoICc/JywgJ18nLCAkcGF0dGVybiApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2V4Y2x1ZGUnXSApICkgewoJCQkkZXhjbHVkZSA9IHNlbGY6OmVzY19saWtlKCAkYXNzb2NfYXJnc1snZXhjbHVkZSddICk7CgkJCSRleGNsdWRlID0gc3RyX3JlcGxhY2UoICcqJywgJyUnLCAkZXhjbHVkZSApOwoJCQkkZXhjbHVkZSA9IHN0cl9yZXBsYWNlKCAnPycsICdfJywgJGV4Y2x1ZGUgKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkZmllbGRzID0gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApID09PSAndG90YWxfYnl0ZXMnICkgewoJCQkkZmllbGRzICAgICA9IGFycmF5KCAnc2l6ZV9ieXRlcycgKTsKCQkJJHNpemVfcXVlcnkgPSAnLFNVTShMRU5HVEgob3B0aW9uX3ZhbHVlKSkgQVMgYHNpemVfYnl0ZXNgJzsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydhdXRvbG9hZCddICkgKSB7CgkJCWlmICggJ29uJyA9PT0gJGFzc29jX2FyZ3NbJ2F1dG9sb2FkJ10gKSB7CgkJCQkkYXV0b2xvYWRfcXVlcnkgPSAiIEFORCBhdXRvbG9hZD0neWVzJyI7CgkJCX0gZWxzZWlmICggJ29mZicgPT09ICRhc3NvY19hcmdzWydhdXRvbG9hZCddICkgewoJCQkJJGF1dG9sb2FkX3F1ZXJ5ID0gIiBBTkQgYXV0b2xvYWQ9J25vJyI7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiVmFsdWUgb2YgJy0tYXV0b2xvYWQnIHNob3VsZCBiZSBvbiBvciBvZmYuIiApOwoJCQl9CgkJfQoKCQkvLyBCeSBkZWZhdWx0IHdlIGRvbid0IHdhbnQgdG8gZGlzcGxheSB0cmFuc2llbnRzLgoJCSRzaG93X3RyYW5zaWVudHMgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd0cmFuc2llbnRzJywgZmFsc2UgKTsKCgkJaWYgKCAkc2hvd190cmFuc2llbnRzICkgewoJCQkkdHJhbnNpZW50c19xdWVyeSA9ICIgQU5EIG9wdGlvbl9uYW1lIExJS0UgJ1xfdHJhbnNpZW50XF8lJwoJCQlPUiBvcHRpb25fbmFtZSBMSUtFICdcX3NpdGVcX3RyYW5zaWVudFxfJSciOwoJCX0gZWxzZSB7CgkJCSR0cmFuc2llbnRzX3F1ZXJ5ID0gIiBBTkQgb3B0aW9uX25hbWUgTk9UIExJS0UgJ1xfdHJhbnNpZW50XF8lJwoJCQlBTkQgb3B0aW9uX25hbWUgTk9UIExJS0UgJ1xfc2l0ZVxfdHJhbnNpZW50XF8lJyI7CgkJfQoKCQkkd2hlcmUgPSAnJzsKCQlpZiAoICRwYXR0ZXJuICkgewoJCQkkd2hlcmUgLj0gJHdwZGItPnByZXBhcmUoICdXSEVSRSBgb3B0aW9uX25hbWVgIExJS0UgJXMnLCAkcGF0dGVybiApOwoJCX0KCgkJaWYgKCAkZXhjbHVkZSApIHsKCQkJJHdoZXJlIC49ICR3cGRiLT5wcmVwYXJlKCAnIEFORCBgb3B0aW9uX25hbWVgIE5PVCBMSUtFICVzJywgJGV4Y2x1ZGUgKTsKCQl9CgkJJHdoZXJlIC49ICRhdXRvbG9hZF9xdWVyeSAuICR0cmFuc2llbnRzX3F1ZXJ5OwoKCQkvLyBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTCAtLSBIYXJkY29kZWQgcXVlcnkgcGFydHMgd2l0aG91dCB1c2VyIGlucHV0LgoJCSRyZXN1bHRzID0gJHdwZGItPmdldF9yZXN1bHRzKAoJCQknU0VMRUNUIGBvcHRpb25fbmFtZWAsYG9wdGlvbl92YWx1ZWAsYGF1dG9sb2FkYCcgLiAkc2l6ZV9xdWVyeQoJCQkuICIgRlJPTSBgJHdwZGItPm9wdGlvbnNgIHskd2hlcmV9IgoJCSk7CgkJLy8gcGhwY3M6ZW5hYmxlCgoJCSRvcmRlcmJ5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnb3JkZXJieScgKTsKCQkkb3JkZXIgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ29yZGVyJyApOwoKCQkvLyBTb3J0IHJlc3VsdC4KCQlpZiAoICdvcHRpb25faWQnICE9PSAkb3JkZXJieSApIHsKCQkJdXNvcnQoCgkJCQkkcmVzdWx0cywKCQkJCWZ1bmN0aW9uICggJGEsICRiICkgdXNlICggJG9yZGVyYnksICRvcmRlciApIHsKCQkJCQkvLyBTb3J0IGFycmF5LgoJCQkJCXJldHVybiAnYXNjJyA9PT0gJG9yZGVyCgkJCQkJCT8gJGEtPiRvcmRlcmJ5ID4gJGItPiRvcmRlcmJ5CgkJCQkJCTogJGEtPiRvcmRlcmJ5IDwgJGItPiRvcmRlcmJ5OwoJCQkJfQoJCQkpOwoJCX0gZWxzZWlmICggJ29wdGlvbl9pZCcgPT09ICRvcmRlcmJ5ICYmICdkZXNjJyA9PT0gJG9yZGVyICkgeyAvLyBTb3J0IGJ5IGRlZmF1bHQgZGVzY2VuZGluZy4KCQkJa3Jzb3J0KCAkcmVzdWx0cyApOwoJCX0KCgkJaWYgKCB0cnVlID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd1bnNlcmlhbGl6ZScsIG51bGwgKSApIHsKCQkJZm9yZWFjaCAoICRyZXN1bHRzIGFzICRrID0+ICYkdiApIHsKCQkJCWlmICggISBlbXB0eSggJHYtPm9wdGlvbl92YWx1ZSApICkgewoJCQkJCSR2LT5vcHRpb25fdmFsdWUgPSBtYXliZV91bnNlcmlhbGl6ZSggJHYtPm9wdGlvbl92YWx1ZSApOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKSA9PT0gJ3RvdGFsX2J5dGVzJyApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkcmVzdWx0c1swXS0+c2l6ZV9ieXRlcyApOwoJCX0gZWxzZSB7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKAoJCQkJJGFzc29jX2FyZ3MsCgkJCQkkZmllbGRzCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRyZXN1bHRzICk7CgkJfQoJfQoKCS8qKgoJICogVXBkYXRlcyBhbiBvcHRpb24gdmFsdWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBvcHRpb24gdG8gdXBkYXRlLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgbmV3IHZhbHVlLiBJZiBvbW1pdGVkLCB0aGUgdmFsdWUgaXMgcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWF1dG9sb2FkPTxhdXRvbG9hZD5dCgkgKiA6IFJlcXVpcmVzIFdQIDQuMi4gU2hvdWxkIHRoaXMgb3B0aW9uIGJlIGF1dG9tYXRpY2FsbHkgbG9hZGVkLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtICd5ZXMnCgkgKiAgIC0gJ25vJwoJICogLS0tCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVXBkYXRlIGFuIG9wdGlvbiBieSByZWFkaW5nIGZyb20gYSBmaWxlLgoJICogICAgICQgd3Agb3B0aW9uIHVwZGF0ZSBteV9vcHRpb24gPCB2YWx1ZS50eHQKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdteV9vcHRpb24nIG9wdGlvbi4KCSAqCgkgKiAgICAgIyBVcGRhdGUgb25lIG9wdGlvbiBvbiBtdWx0aXBsZSBzaXRlcyB1c2luZyB4YXJncy4KCSAqICAgICAkIHdwIHNpdGUgbGlzdCAtLWZpZWxkPXVybCB8IHhhcmdzIC1uMSAtSSB7fSBzaCAtYyAnd3AgLS11cmw9e30gb3B0aW9uIHVwZGF0ZSBteV9vcHRpb24gbXlfdmFsdWUnCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnbXlfb3B0aW9uJyBvcHRpb24uCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnbXlfb3B0aW9uJyBvcHRpb24uCgkgKgoJICogICAgICMgVXBkYXRlIHNpdGUgYmxvZyBuYW1lLgoJICogICAgICQgd3Agb3B0aW9uIHVwZGF0ZSBibG9nbmFtZSAiUmFuZG9tIGJsb2cgbmFtZSIKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdibG9nbmFtZScgb3B0aW9uLgoJICoKCSAqICAgICAjIFVwZGF0ZSBzaXRlIGJsb2cgZGVzY3JpcHRpb24uCgkgKiAgICAgJCB3cCBvcHRpb24gdXBkYXRlIGJsb2dkZXNjcmlwdGlvbiAiU29tZSByYW5kb20gYmxvZyBkZXNjcmlwdGlvbiIKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdibG9nZGVzY3JpcHRpb24nIG9wdGlvbi4KCSAqCgkgKiAgICAgIyBVcGRhdGUgYWRtaW4gZW1haWwgYWRkcmVzcy4KCSAqICAgICAkIHdwIG9wdGlvbiB1cGRhdGUgYWRtaW5fZW1haWwgc29tZW9uZUBleGFtcGxlLmNvbQoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ2FkbWluX2VtYWlsJyBvcHRpb24uCgkgKgoJICogICAgICMgU2V0IHRoZSBkZWZhdWx0IHJvbGUuCgkgKiAgICAgJCB3cCBvcHRpb24gdXBkYXRlIGRlZmF1bHRfcm9sZSBhdXRob3IKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdkZWZhdWx0X3JvbGUnIG9wdGlvbi4KCSAqCgkgKiAgICAgIyBTZXQgdGhlIHRpbWV6b25lIHN0cmluZy4KCSAqICAgICAkIHdwIG9wdGlvbiB1cGRhdGUgdGltZXpvbmVfc3RyaW5nICJBbWVyaWNhL05ld19Zb3JrIgoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ3RpbWV6b25lX3N0cmluZycgb3B0aW9uLgoJICoKCSAqIEBhbGlhcyBzZXQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRrZXkgPSAkYXJnc1swXTsKCgkJJHZhbHVlID0gV1BfQ0xJOjpnZXRfdmFsdWVfZnJvbV9hcmdfb3Jfc3RkaW4oICRhcmdzLCAxICk7CgkJJHZhbHVlID0gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7CgoJCSRhdXRvbG9hZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2F1dG9sb2FkJyApOwoJCWlmICggISBpbl9hcnJheSggJGF1dG9sb2FkLCBbICd5ZXMnLCAnbm8nIF0sIHRydWUgKSApIHsKCQkJJGF1dG9sb2FkID0gbnVsbDsKCQl9CgoJCSR2YWx1ZSA9IHNhbml0aXplX29wdGlvbiggJGtleSwgJHZhbHVlICk7CgkJLy8gU2FuaXRpemF0aW9uIFdvcmRQcmVzcyBub3JtYWxseSBwZXJmb3JtcyB3aGVuIGdldHRpbmcgYW4gb3B0aW9uCgkJaWYgKCBpbl9hcnJheSggJGtleSwgWyAnc2l0ZXVybCcsICdob21lJywgJ2NhdGVnb3J5X2Jhc2UnLCAndGFnX2Jhc2UnIF0sIHRydWUgKSApIHsKCQkJJHZhbHVlID0gdW50cmFpbGluZ3NsYXNoaXQoICR2YWx1ZSApOwoJCX0KCQkkb2xkX3ZhbHVlID0gc2FuaXRpemVfb3B0aW9uKCAka2V5LCBnZXRfb3B0aW9uKCAka2V5ICkgKTsKCgkJaWYgKCAkdmFsdWUgPT09ICRvbGRfdmFsdWUgJiYgbnVsbCA9PT0gJGF1dG9sb2FkICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJWYWx1ZSBwYXNzZWQgZm9yICd7JGtleX0nIG9wdGlvbiBpcyB1bmNoYW5nZWQuIiApOwoJCX0gZWxzZSB7CgkJCWlmICggdXBkYXRlX29wdGlvbiggJGtleSwgJHZhbHVlLCAkYXV0b2xvYWQgKSApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIlVwZGF0ZWQgJ3ska2V5fScgb3B0aW9uLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgdXBkYXRlIG9wdGlvbiAneyRrZXl9Jy4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGVzIGFuIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4uLi4KCSAqIDogS2V5IGZvciB0aGUgb3B0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGFuIG9wdGlvbi4KCSAqICAgICAkIHdwIG9wdGlvbiBkZWxldGUgbXlfb3B0aW9uCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAnbXlfb3B0aW9uJyBvcHRpb24uCgkgKgoJICogICAgICMgRGVsZXRlIG11bHRpcGxlIG9wdGlvbnMuCgkgKiAgICAgJCB3cCBvcHRpb24gZGVsZXRlIG9wdGlvbl9vbmUgb3B0aW9uX3R3byBvcHRpb25fdGhyZWUKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkICdvcHRpb25fb25lJyBvcHRpb24uCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAnb3B0aW9uX3R3bycgb3B0aW9uLgoJICogICAgIFdhcm5pbmc6IENvdWxkIG5vdCBkZWxldGUgJ29wdGlvbl90aHJlZScgb3B0aW9uLiBEb2VzIGl0IGV4aXN0PwoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncyApIHsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGFyZyApIHsKCQkJaWYgKCAhIGRlbGV0ZV9vcHRpb24oICRhcmcgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkIG5vdCBkZWxldGUgJ3skYXJnfScgb3B0aW9uLiBEb2VzIGl0IGV4aXN0PyIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIkRlbGV0ZWQgJ3skYXJnfScgb3B0aW9uLiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEdldHMgYSBuZXN0ZWQgdmFsdWUgZnJvbSBhbiBvcHRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBvcHRpb24gbmFtZS4KCSAqCgkgKiA8a2V5LXBhdGg+Li4uCgkgKiA6IFRoZSBuYW1lKHMpIG9mIHRoZSBrZXlzIHdpdGhpbiB0aGUgdmFsdWUgdG8gbG9jYXRlIHRoZSB2YWx1ZSB0byBwbHVjay4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBvdXRwdXQgZm9ybWF0IG9mIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBsdWNrKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSApID0gJGFyZ3M7CgoJCSR2YWx1ZSA9IGdldF9vcHRpb24oICRrZXkgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9CgoJCSRrZXlfcGF0aCA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRrZXkgKSB7CgkJCQlpZiAoIGlzX251bWVyaWMoICRrZXkgKSAmJiAoIChzdHJpbmcpIGludHZhbCggJGtleSApID09PSAka2V5ICkgKSB7CgkJCQkJcmV0dXJuIChpbnQpICRrZXk7CgkJCQl9CgkJCQkJcmV0dXJuICRrZXk7CgkJCX0sCgkJCWFycmF5X3NsaWNlKCAkYXJncywgMSApCgkJKTsKCgkJJHRyYXZlcnNlciA9IG5ldyBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyKCAkdmFsdWUgKTsKCgkJdHJ5IHsKCQkJJHZhbHVlID0gJHRyYXZlcnNlci0+Z2V0KCAka2V5X3BhdGggKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCWRpZSggMSApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogVXBkYXRlcyBhIG5lc3RlZCB2YWx1ZSBpbiBhbiBvcHRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxhY3Rpb24+CgkgKiA6IFBhdGNoIGFjdGlvbiB0byBwZXJmb3JtLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIGluc2VydAoJICogICAtIHVwZGF0ZQoJICogICAtIGRlbGV0ZQoJICogLS0tCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG9wdGlvbiBuYW1lLgoJICoKCSAqIDxrZXktcGF0aD4uLi4KCSAqIDogVGhlIG5hbWUocykgb2YgdGhlIGtleXMgd2l0aGluIHRoZSB2YWx1ZSB0byBsb2NhdGUgdGhlIHZhbHVlIHRvIHBhdGNoLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgbmV3IHZhbHVlLiBJZiBvbWl0dGVkLCB0aGUgdmFsdWUgaXMgcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGFjdGlvbiwgJGtleSApID0gJGFyZ3M7CgkJJGtleV9wYXRoICAgICAgICAgICAgID0gYXJyYXlfbWFwKAoJCQlmdW5jdGlvbiggJGtleSApIHsKCQkJCWlmICggaXNfbnVtZXJpYyggJGtleSApICYmICggKHN0cmluZykgaW50dmFsKCAka2V5ICkgPT09ICRrZXkgKSApIHsKCQkJCQlyZXR1cm4gKGludCkgJGtleTsKCQkJCX0KCQkJCQlyZXR1cm4gJGtleTsKCQkJfSwKCQkJYXJyYXlfc2xpY2UoICRhcmdzLCAyICkKCQkpOwoKCQlpZiAoICdkZWxldGUnID09PSAkYWN0aW9uICkgewoJCQkkcGF0Y2hfdmFsdWUgPSBudWxsOwoJCX0gZWxzZSB7CgkJCSRzdGRpbl92YWx1ZSA9IEVudGl0eVV0aWxzOjpoYXNfc3RkaW4oKQoJCQkJPyB0cmltKCBXUF9DTEk6OmdldF92YWx1ZV9mcm9tX2FyZ19vcl9zdGRpbiggJGFyZ3MsIC0xICkgKQoJCQkJOiBudWxsOwoJCQkkcGF0Y2hfdmFsdWUgPSAhIGVtcHR5KCAkc3RkaW5fdmFsdWUgKQoJCQkJPyBXUF9DTEk6OnJlYWRfdmFsdWUoICRzdGRpbl92YWx1ZSwgJGFzc29jX2FyZ3MgKQoJCQkJOiBXUF9DTEk6OnJlYWRfdmFsdWUoIGFycmF5X3BvcCggJGtleV9wYXRoICksICRhc3NvY19hcmdzICk7CgkJfQoKCQkvKiBOZWVkIHRvIG1ha2UgYSBjb3B5IG9mICRjdXJyZW50X3ZhbHVlIGhlcmUgYXMgaXQgaXMgbW9kaWZpZWQgYnkgcmVmZXJlbmNlICovCgkJJG9sZF92YWx1ZSAgICAgPSBzYW5pdGl6ZV9vcHRpb24oICRrZXksIGdldF9vcHRpb24oICRrZXkgKSApOwoJCSRjdXJyZW50X3ZhbHVlID0gJG9sZF92YWx1ZTsKCQlpZiAoIGlzX29iamVjdCggJGN1cnJlbnRfdmFsdWUgKSApIHsKCQkJJG9sZF92YWx1ZSA9IGNsb25lICRjdXJyZW50X3ZhbHVlOwoJCX0KCgkJJHRyYXZlcnNlciA9IG5ldyBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyKCAkY3VycmVudF92YWx1ZSApOwoKCQl0cnkgewoJCQkkdHJhdmVyc2VyLT4kYWN0aW9uKCAka2V5X3BhdGgsICRwYXRjaF92YWx1ZSApOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQkkcGF0Y2hlZF92YWx1ZSA9IHNhbml0aXplX29wdGlvbiggJGtleSwgJHRyYXZlcnNlci0+dmFsdWUoKSApOwoKCQlpZiAoICRwYXRjaGVkX3ZhbHVlID09PSAkb2xkX3ZhbHVlICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJWYWx1ZSBwYXNzZWQgZm9yICd7JGtleX0nIG9wdGlvbiBpcyB1bmNoYW5nZWQuIiApOwoJCX0gZWxzZSB7CgkJCWlmICggdXBkYXRlX29wdGlvbiggJGtleSwgJHBhdGNoZWRfdmFsdWUgKSApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIlVwZGF0ZWQgJ3ska2V5fScgb3B0aW9uLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgdXBkYXRlIG9wdGlvbiAneyRrZXl9Jy4iICk7CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX2xpa2UoICRvbGQgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBSZW1vdmUgbm90aWNlcyBpbiA0LjAgYW5kIHN1cHBvcnQgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkKCQlpZiAoIG1ldGhvZF9leGlzdHMoICR3cGRiLCAnZXNjX2xpa2UnICkgKSB7CgkJCS8vIDQuMAoJCQkkb2xkID0gJHdwZGItPmVzY19saWtlKCAkb2xkICk7CgkJfSBlbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkRnVuY3Rpb25zLmxpa2VfZXNjYXBlRm91bmQgLS0gY2FsbGVkIGluIFdvcmRQcmVzcyAzLjkgb3IgbGVzcy4KCQkJJG9sZCA9IGxpa2VfZXNjYXBlKCBlc2Nfc3FsKCAkb2xkICkgKTsKCQl9CgoJCXJldHVybiAkb2xkOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoTWV0YTsKCi8qKgogKiBHZXRzLCBhZGRzLCB1cGRhdGVzLCBkZWxldGVzLCBhbmQgbGlzdHMgbmV0d29yayBjdXN0b20gZmllbGRzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBHZXQgYSBsaXN0IG9mIHN1cGVyLWFkbWlucwogKiAgICAgJCB3cCBuZXR3b3JrIG1ldGEgZ2V0IDEgc2l0ZV9hZG1pbnMKICogICAgIGFycmF5ICgKICogICAgICAgMCA9PiAnc3VwZXJ2aXNvcicsCiAqICAgICApCiAqLwpjbGFzcyBOZXR3b3JrX01ldGFfQ29tbWFuZCBleHRlbmRzIENvbW1hbmRXaXRoTWV0YSB7Cglwcm90ZWN0ZWQgJG1ldGFfdHlwZSA9ICdzaXRlJzsKfQo8P3BocAoKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHJlZ2lzdGVyZWQgdGF4b25vbWllcy4KICoKICogU2VlIHJlZmVyZW5jZXMgZm9yIFtidWlsdC1pbiB0YXhvbm9taWVzXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9iYXNpY3MvY2F0ZWdvcmllcy10YWdzLWN1c3RvbS10YXhvbm9taWVzLykgYW5kIFtjdXN0b20gdGF4b25vbWllc10oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9wbHVnaW5zL3RheG9ub21pZXMvd29ya2luZy13aXRoLWN1c3RvbS10YXhvbm9taWVzLykuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgYWxsIHRheG9ub21pZXMgd2l0aCAncG9zdCcgb2JqZWN0IHR5cGUuCiAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1vYmplY3RfdHlwZT1wb3N0IC0tZmllbGRzPW5hbWUscHVibGljCiAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKICogICAgIHwgbmFtZSAgICAgICAgfCBwdWJsaWMgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCiAqICAgICB8IGNhdGVnb3J5ICAgIHwgMSAgICAgIHwKICogICAgIHwgcG9zdF90YWcgICAgfCAxICAgICAgfAogKiAgICAgfCBwb3N0X2Zvcm1hdCB8IDEgICAgICB8CiAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKICoKICogICAgICMgR2V0IGNhcGFiaWxpdGllcyBvZiAncG9zdF90YWcnIHRheG9ub215LgogKiAgICAgJCB3cCB0YXhvbm9teSBnZXQgcG9zdF90YWcgLS1maWVsZD1jYXAKICogICAgIHsibWFuYWdlX3Rlcm1zIjoibWFuYWdlX2NhdGVnb3JpZXMiLCJlZGl0X3Rlcm1zIjoibWFuYWdlX2NhdGVnb3JpZXMiLCJkZWxldGVfdGVybXMiOiJtYW5hZ2VfY2F0ZWdvcmllcyIsImFzc2lnbl90ZXJtcyI6ImVkaXRfcG9zdHMifQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFRheG9ub215X0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gYXJyYXkoCgkJJ25hbWUnLAoJCSdsYWJlbCcsCgkJJ2Rlc2NyaXB0aW9uJywKCQknb2JqZWN0X3R5cGUnLAoJCSdzaG93X3RhZ2Nsb3VkJywKCQknaGllcmFyY2hpY2FsJywKCQkncHVibGljJywKCSk7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggMy43LCAnPCcgKSApIHsKCQkJLy8gcmVtb3ZlIGRlc2NyaXB0aW9uIGZvciB3cCA8PSAzLjcKCQkJJHRoaXMtPmZpZWxkcyA9IGFycmF5X3ZhbHVlcyggYXJyYXlfZGlmZiggJHRoaXMtPmZpZWxkcywgYXJyYXkoICdkZXNjcmlwdGlvbicgKSApICk7CgkJfQoKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB0ZXJtIGNvdW50cyBmb3IgZWFjaCBzdXBwbGllZCB0YXhvbm9teS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHRheG9ub21pZXMgVGF4b25vbWllcyB0byBmZXRjaCBjb3VudHMgZm9yLgoJICogQHJldHVybiBhcnJheSBBc3NvY2lhdGl2ZSBhcnJheSBvZiB0ZXJtIGNvdW50cyBrZXllZCBieSB0YXhvbm9teS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9jb3VudHMoICR0YXhvbm9taWVzICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJaWYgKCBjb3VudCggJHRheG9ub21pZXMgKSA8PSAwICkgewoJCQlyZXR1cm4gW107CgkJfQoKCQkkcXVlcnkgPSAkd3BkYi0+cHJlcGFyZSgKCQkJIlNFTEVDVCBgdGF4b25vbXlgLCBDT1VOVCgqKSBBUyBgY291bnRgCgkJCUZST00gJHdwZGItPnRlcm1fdGF4b25vbXkKCQkJV0hFUkUgYHRheG9ub215YCBJTiAoIiAuIGltcGxvZGUoICcsJywgYXJyYXlfZmlsbCggMCwgY291bnQoICR0YXhvbm9taWVzICksICclcycgKSApIC4gJykKCQkJR1JPVVAgQlkgYHRheG9ub215YCcsCgkJCSR0YXhvbm9taWVzCgkJKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tICRxdWVyeSBpcyBhbHJlYWR5IHByZXBhcmVkIGFib3ZlLgoJCSRjb3VudHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICRxdWVyeSApOwoKCQkvLyBNYWtlIHN1cmUgdGhlcmUncyBhIGNvdW50IGZvciBldmVyeSBpdGVtLgoJCSRjb3VudHMgPSBhcnJheV9tZXJnZSgKCQkJYXJyYXlfZmlsbF9rZXlzKCAkdGF4b25vbWllcywgMCApLAoJCQl3cF9saXN0X3BsdWNrKCAkY291bnRzLCAnY291bnQnLCAndGF4b25vbXknICkKCQkpOwoKCQlyZXR1cm4gJGNvdW50czsKCX0KCgkvKioKCSAqIExpc3RzIHJlZ2lzdGVyZWQgdGF4b25vbWllcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzIChzZWUgZ2V0X3RheG9ub21pZXMoKSBmaXJzdCBwYXJhbWV0ZXIgZm9yIGEgbGlzdCBvZiBhdmFpbGFibGUgZmllbGRzKS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHRheG9ub215LgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyB0YXhvbm9teSBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHRlcm06CgkgKgoJICogKiBuYW1lCgkgKiAqIGxhYmVsCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIG9iamVjdF90eXBlCgkgKiAqIHNob3dfdGFnY2xvdWQKCSAqICogaGllcmFyY2hpY2FsCgkgKiAqIHB1YmxpYwoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjb3VudAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBhbGwgdGF4b25vbWllcy4KCSAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbmFtZSxsYWJlbCxkZXNjcmlwdGlvbixvYmplY3RfdHlwZSxzaG93X3RhZ2Nsb3VkLGhpZXJhcmNoaWNhbCxwdWJsaWMKCSAqICAgICBjYXRlZ29yeSxDYXRlZ29yaWVzLCxwb3N0LDEsMSwxCgkgKiAgICAgcG9zdF90YWcsVGFncywscG9zdCwxLCwxCgkgKiAgICAgbmF2X21lbnUsIk5hdmlnYXRpb24gTWVudXMiLCxuYXZfbWVudV9pdGVtLCwsCgkgKiAgICAgbGlua19jYXRlZ29yeSwiTGluayBDYXRlZ29yaWVzIiwsbGluaywxLCwKCSAqICAgICBwb3N0X2Zvcm1hdCxGb3JtYXQsLHBvc3QsLCwxCgkgKgoJICogICAgICMgTGlzdCBhbGwgdGF4b25vbWllcyB3aXRoICdwb3N0JyBvYmplY3QgdHlwZS4KCSAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1vYmplY3RfdHlwZT1wb3N0IC0tZmllbGRzPW5hbWUscHVibGljCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICB8IHB1YmxpYyB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBjYXRlZ29yeSAgICB8IDEgICAgICB8CgkgKiAgICAgfCBwb3N0X3RhZyAgICB8IDEgICAgICB8CgkgKiAgICAgfCBwb3N0X2Zvcm1hdCB8IDEgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgoJCS8vIENoZWNrIGlmIGl0J3Mgc3RyaWN0IG1vZGUgb3Igbm90LgoJCSRzdHJpY3QgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzdHJpY3QnLCBmYWxzZSApOwoKCQl1bnNldCggJGFzc29jX2FyZ3NbJ3N0cmljdCddICk7CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydvYmplY3RfdHlwZSddICkgKSB7CgkJCSRhc3NvY19hcmdzWydvYmplY3RfdHlwZSddID0gYXJyYXkoICRhc3NvY19hcmdzWydvYmplY3RfdHlwZSddICk7CgkJCSR0YXhvbm9teV9vYmplY3QgICAgICAgICAgID0gJGFzc29jX2FyZ3NbJ29iamVjdF90eXBlJ107CgkJfSBlbHNlIHsKCQkJJHRheG9ub215X29iamVjdCA9IGdldF9wb3N0X3R5cGVzKCk7CgkJfQoKCQkkZmllbGRzICAgICA9ICRmb3JtYXR0ZXItPmZpZWxkczsKCQkkdGF4b25vbWllcyA9ICggaXNzZXQoICR0YXhvbm9teV9vYmplY3QgKSAmJiAhICRzdHJpY3QgKQoJCQk/IGdldF9vYmplY3RfdGF4b25vbWllcyggJHRheG9ub215X29iamVjdCwgJ29iamVjdHMnICkKCQkJOiBnZXRfdGF4b25vbWllcyggJGFzc29jX2FyZ3MsICdvYmplY3RzJyApOwoKCQkkY291bnRzID0gW107CgoJCWlmICggY291bnQoICR0YXhvbm9taWVzICkgPiAwICYmIGluX2FycmF5KCAnY291bnQnLCAkZmllbGRzLCB0cnVlICkgKSB7CgkJCSRjb3VudHMgPSAkdGhpcy0+Z2V0X2NvdW50cyggd3BfbGlzdF9wbHVjayggJHRheG9ub21pZXMsICduYW1lJyApICk7CgkJfQoKCQkkdGF4b25vbWllcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICR0YXhvbm9teSApIHVzZSAoICRjb3VudHMgKSB7CgkJCQkJJHRheG9ub215LT5vYmplY3RfdHlwZSA9IGltcGxvZGUoICcsICcsICR0YXhvbm9teS0+b2JqZWN0X3R5cGUgKTsKCQkJCQkkdGF4b25vbXktPmNvdW50ICAgICAgID0gaXNzZXQoICRjb3VudHNbICR0YXhvbm9teS0+bmFtZSBdICkgPyAkY291bnRzWyAkdGF4b25vbXktPm5hbWUgXSA6IDA7CgkJCQkJcmV0dXJuICR0YXhvbm9teTsKCQkJfSwKCQkJJHRheG9ub21pZXMKCQkpOwoKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdGF4b25vbWllcyApOwoJfQoKCS8qKgoJICogR2V0cyBkZXRhaWxzIGFib3V0IGEgcmVnaXN0ZXJlZCB0YXhvbm9teS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRheG9ub215PgoJICogOiBUYXhvbm9teSBzbHVnLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSB0YXhvbm9teSwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciB0aGUgc3BlY2lmaWVkIHRheG9ub215OgoJICoKCSAqICogbmFtZQoJICogKiBsYWJlbAoJICogKiBkZXNjcmlwdGlvbgoJICogKiBvYmplY3RfdHlwZQoJICogKiBzaG93X3RhZ2Nsb3VkCgkgKiAqIGhpZXJhcmNoaWNhbAoJICogKiBwdWJsaWMKCSAqICogbGFiZWxzCgkgKiAqIGNhcAoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjb3VudAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGRldGFpbHMgb2YgYGNhdGVnb3J5YCB0YXhvbm9teS4KCSAqICAgICAkIHdwIHRheG9ub215IGdldCBjYXRlZ29yeSAtLWZpZWxkcz1uYW1lLGxhYmVsLG9iamVjdF90eXBlCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICogICAgIHwgRmllbGQgICAgICAgfCBWYWx1ZSAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICB8IGNhdGVnb3J5ICAgfAoJICogICAgIHwgbGFiZWwgICAgICAgfCBDYXRlZ29yaWVzIHwKCSAqICAgICB8IG9iamVjdF90eXBlIHwgWyJwb3N0Il0gICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIEdldCBjYXBhYmlsaXRpZXMgb2YgJ3Bvc3RfdGFnJyB0YXhvbm9teS4KCSAqICAgICAkIHdwIHRheG9ub215IGdldCBwb3N0X3RhZyAtLWZpZWxkPWNhcAoJICogICAgIHsibWFuYWdlX3Rlcm1zIjoibWFuYWdlX2NhdGVnb3JpZXMiLCJlZGl0X3Rlcm1zIjoibWFuYWdlX2NhdGVnb3JpZXMiLCJkZWxldGVfdGVybXMiOiJtYW5hZ2VfY2F0ZWdvcmllcyIsImFzc2lnbl90ZXJtcyI6ImVkaXRfcG9zdHMifQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRheG9ub215ID0gZ2V0X3RheG9ub215KCAkYXJnc1swXSApOwoKCQlpZiAoICEgJHRheG9ub215ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGF4b25vbXkgeyRhcmdzWzBdfSBkb2Vzbid0IGV4aXN0LiIgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkZGVmYXVsdF9maWVsZHMgPSBhcnJheV9tZXJnZSgKCQkJCSR0aGlzLT5maWVsZHMsCgkJCQlhcnJheSgKCQkJCQknbGFiZWxzJywKCQkJCQknY2FwJywKCQkJCSkKCQkJKTsKCgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9ICRkZWZhdWx0X2ZpZWxkczsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZmllbGRzICAgID0gJGZvcm1hdHRlci0+ZmllbGRzOwoJCSRjb3VudCAgICAgPSAwOwoKCQlpZiAoIGluX2FycmF5KCAnY291bnQnLCAkZmllbGRzLCB0cnVlICkgKSB7CgkJCSRjb3VudCA9ICR0aGlzLT5nZXRfY291bnRzKCBbICR0YXhvbm9teS0+bmFtZSBdICk7CgkJCSRjb3VudCA9ICRjb3VudFsgJHRheG9ub215LT5uYW1lIF07CgkJfQoKCQkkZGF0YSA9IGFycmF5KAoJCQknbmFtZScgICAgICAgICAgPT4gJHRheG9ub215LT5uYW1lLAoJCQknbGFiZWwnICAgICAgICAgPT4gJHRheG9ub215LT5sYWJlbCwKCQkJJ2Rlc2NyaXB0aW9uJyAgID0+ICR0YXhvbm9teS0+ZGVzY3JpcHRpb24sCgkJCSdvYmplY3RfdHlwZScgICA9PiAkdGF4b25vbXktPm9iamVjdF90eXBlLAoJCQknc2hvd190YWdjbG91ZCcgPT4gJHRheG9ub215LT5zaG93X3RhZ2Nsb3VkLAoJCQknaGllcmFyY2hpY2FsJyAgPT4gJHRheG9ub215LT5oaWVyYXJjaGljYWwsCgkJCSdwdWJsaWMnICAgICAgICA9PiAkdGF4b25vbXktPnB1YmxpYywKCQkJJ2xhYmVscycgICAgICAgID0+ICR0YXhvbm9teS0+bGFiZWxzLAoJCQknY2FwJyAgICAgICAgICAgPT4gJHRheG9ub215LT5jYXAsCgkJCSdjb3VudCcgICAgICAgICA9PiAkY291bnQsCgkJKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICRkYXRhICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzLCAndGF4b25vbXknICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhUZXJtczsKCi8qKgogKiBBZGRzLCB1cGRhdGVzLCByZW1vdmVzLCBhbmQgbGlzdHMgdXNlciB0ZXJtcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHVzZXIgdGVybXMKICogICAgICQgd3AgdXNlciB0ZXJtIHNldCAxMjMgdGVzdCBjYXRlZ29yeQogKiAgICAgU3VjY2VzczogU2V0IHRlcm1zLgogKi8KY2xhc3MgVXNlcl9UZXJtX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aFRlcm1zIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAndXNlcic7Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhNZXRhOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFNpdGUgYXMgU2l0ZUZldGNoZXI7CgovKioKICogQWRkcywgdXBkYXRlcywgZGVsZXRlcywgYW5kIGxpc3RzIHNpdGUgY3VzdG9tIGZpZWxkcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHNpdGUgbWV0YQogKiAgICAgJCB3cCBzaXRlIG1ldGEgc2V0IDEyMyBiaW8gIk1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY3VzdG9tIGZpZWxkICdiaW8nLgogKgogKiAgICAgIyBHZXQgc2l0ZSBtZXRhCiAqICAgICAkIHdwIHNpdGUgbWV0YSBnZXQgMTIzIGJpbwogKiAgICAgTWFyeSBpcyBhIFdvcmRQcmVzcyBkZXZlbG9wZXIuCiAqCiAqICAgICAjIFVwZGF0ZSBzaXRlIG1ldGEKICogICAgICQgd3Agc2l0ZSBtZXRhIHVwZGF0ZSAxMjMgYmlvICJNYXJ5IGlzIGFuIGF3ZXNvbWUgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnYmlvJy4KICoKICogICAgICMgRGVsZXRlIHNpdGUgbWV0YQogKiAgICAgJCB3cCBzaXRlIG1ldGEgZGVsZXRlIDEyMyBiaW8KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY3VzdG9tIGZpZWxkLgogKi8KY2xhc3MgU2l0ZV9NZXRhX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aE1ldGEgewoJcHJvdGVjdGVkICRtZXRhX3R5cGUgPSAnYmxvZyc7CgoJLyoqCgkgKiBDaGVjayB0aGF0IHRoZSBzaXRlIElEIGV4aXN0cwoJICoKCSAqIEBwYXJhbSBpbnQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApIHsKCQkkZmV0Y2hlciA9IG5ldyBTaXRlRmV0Y2hlcigpOwoJCSRzaXRlICAgID0gJGZldGNoZXItPmdldF9jaGVjayggJG9iamVjdF9pZCApOwoJCXJldHVybiAkc2l0ZS0+YmxvZ19pZDsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBhZGRfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gYm9vbCAgICR1bmlxdWUgICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBXaGV0aGVyIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbWV0YWRhdGEga2V5IHNob3VsZCBiZSB1bmlxdWUgZm9yIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuIElmIHRydWUsIGFuZCB0aGUgb2JqZWN0IGFscmVhZHkgaGFzIGEKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgbWV0YWRhdGEga2V5LCBubyBjaGFuZ2UKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBtYWRlLgoJICoKCSAqIEByZXR1cm4gaW50fGZhbHNlIFRoZSBtZXRhIElEIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBhZGRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgPSBmYWxzZSApIHsKCQlyZXR1cm4gYWRkX3NpdGVfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIHVwZGF0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBtaXhlZCAgJHByZXZfdmFsdWUgT3B0aW9uYWwuIElmIHNwZWNpZmllZCwgb25seSB1cGRhdGUgZXhpc3RpbmcKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgZW50cmllcyB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIE90aGVyd2lzZSwgdXBkYXRlIGFsbCBlbnRyaWVzLgoJICoKCSAqIEByZXR1cm4gaW50fGJvb2wgTWV0YSBJRCBpZiB0aGUga2V5IGRpZG4ndCBleGlzdCwgdHJ1ZSBvbiBzdWNjZXNzZnVsCgkgKiAgICAgICAgICAgICAgICAgIHVwZGF0ZSwgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHByZXZfdmFsdWUgPSAnJyApIHsKCQlyZXR1cm4gdXBkYXRlX3NpdGVfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHByZXZfdmFsdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBnZXRfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgIE9wdGlvbmFsLiBNZXRhZGF0YSBrZXkuIElmIG5vdCBzcGVjaWZpZWQsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0cmlldmUgYWxsIG1ldGFkYXRhIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdC4KCSAqIEBwYXJhbSBib29sICAgJHNpbmdsZSAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gSWYgdHJ1ZSwgcmV0dXJuIG9ubHkKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZmlyc3QgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBtZXRhX2tleS4gVGhpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IGlmIG1ldGFfa2V5IGlzIG5vdAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZC4KCSAqCgkgKiBAcmV0dXJuIG1peGVkIFNpbmdsZSBtZXRhZGF0YSB2YWx1ZSwgb3IgYXJyYXkgb2YgdmFsdWVzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXkgPSAnJywgJHNpbmdsZSA9IGZhbHNlICkgewoJCXJldHVybiBnZXRfc2l0ZV9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRzaW5nbGUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBkZWxldGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgbWV0YWRhdGEgaXMgZm9yCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleQoJICogQHBhcmFtIG1peGVkICRtZXRhX3ZhbHVlICBPcHRpb25hbC4gTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vbi1zY2FsYXIuIElmIHNwZWNpZmllZCwgb25seSBkZWxldGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgZW50cmllcyB3aXRoIHRoaXMgdmFsdWUuIE90aGVyd2lzZSwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGFsbCBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCBtZXRhX2tleS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFzcyBgbnVsbCwgYGZhbHNlYCwgb3IgYW4gZW1wdHkgc3RyaW5nIHRvIHNraXAKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBjaGVjay4gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIGl0IGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBwb3NzaWJsZSB0byBwYXNzIGFuIGVtcHR5IHN0cmluZyB0byBkZWxldGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhvc2UgZW50cmllcyB3aXRoIGFuIGVtcHR5IHN0cmluZyBmb3IgYSB2YWx1ZS4KCSAqCgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBvbiBzdWNjZXNzZnVsIGRlbGV0ZSwgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGRlbGV0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSA9ICcnICkgewoJCXJldHVybiBkZWxldGVfc2l0ZV9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlICk7Cgl9Cgp9Cjw/cGhwCgp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKCi8qKgogKiBSZXRyaWV2ZXMgZGV0YWlscyBvbiB0aGUgc2l0ZSdzIHJlZ2lzdGVyZWQgcG9zdCB0eXBlcy4KICoKICogR2V0IGluZm9ybWF0aW9uIG9uIFdvcmRQcmVzcycgYnVpbHQtaW4gYW5kIHRoZSBzaXRlJ3MgW2N1c3RvbSBwb3N0IHR5cGVzXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3BsdWdpbnMvcG9zdC10eXBlcy8pLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBHZXQgZGV0YWlscyBhYm91dCBhIHBvc3QgdHlwZQogKiAgICAgJCB3cCBwb3N0LXR5cGUgZ2V0IHBhZ2UgLS1maWVsZHM9bmFtZSxsYWJlbCxoaWVyYXJjaGljYWwgLS1mb3JtYXQ9anNvbgogKiAgICAgeyJuYW1lIjoicGFnZSIsImxhYmVsIjoiUGFnZXMiLCJoaWVyYXJjaGljYWwiOnRydWV9CiAqCiAqICAgICAjIExpc3QgcG9zdCB0eXBlcyB3aXRoICdwb3N0JyBjYXBhYmlsaXR5IHR5cGUKICogICAgICQgd3AgcG9zdC10eXBlIGxpc3QgLS1jYXBhYmlsaXR5X3R5cGU9cG9zdCAtLWZpZWxkcz1uYW1lLHB1YmxpYwogKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKICogICAgIHwgbmFtZSAgICAgICAgICB8IHB1YmxpYyB8CiAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwogKiAgICAgfCBwb3N0ICAgICAgICAgIHwgMSAgICAgIHwKICogICAgIHwgYXR0YWNobWVudCAgICB8IDEgICAgICB8CiAqICAgICB8IHJldmlzaW9uICAgICAgfCAgICAgICAgfAogKiAgICAgfCBuYXZfbWVudV9pdGVtIHwgICAgICAgIHwKICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgUG9zdF9UeXBlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gYXJyYXkoCgkJJ25hbWUnLAoJCSdsYWJlbCcsCgkJJ2Rlc2NyaXB0aW9uJywKCQknaGllcmFyY2hpY2FsJywKCQkncHVibGljJywKCQknY2FwYWJpbGl0eV90eXBlJywKCSk7CgoJLyoqCgkgKiBHZXRzIHRoZSBwb3N0IGNvdW50cyBmb3IgZWFjaCBzdXBwbGllZCBwb3N0IHR5cGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICRwb3N0X3R5cGVzIFBvc3QgdHlwZXMgdG8gZmV0Y2ggY291bnRzIGZvci4KCSAqIEByZXR1cm4gYXJyYXkgQXNzb2NpYXRpdmUgYXJyYXkgb2YgcG9zdCBjb3VudHMga2V5ZWQgYnkgcG9zdCB0eXBlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2NvdW50cyggJHBvc3RfdHlwZXMgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQlpZiAoIGNvdW50KCAkcG9zdF90eXBlcyApIDw9IDAgKSB7CgkJCXJldHVybiBbXTsKCQl9CgoJCSRxdWVyeSA9ICR3cGRiLT5wcmVwYXJlKAoJCQkiU0VMRUNUIGBwb3N0X3R5cGVgLCBDT1VOVCgqKSBBUyBgY291bnRgCgkJCUZST00gJHdwZGItPnBvc3RzCgkJCVdIRVJFIGBwb3N0X3R5cGVgIElOICgiIC4gaW1wbG9kZSggJywnLCBhcnJheV9maWxsKCAwLCBjb3VudCggJHBvc3RfdHlwZXMgKSwgJyVzJyApICkgLiAnKQoJCQlHUk9VUCBCWSBgcG9zdF90eXBlYCcsCgkJCSRwb3N0X3R5cGVzCgkJKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tICRxdWVyeSBpcyBhbHJlYWR5IHByZXBhcmVkIGFib3ZlLgoJCSRjb3VudHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICRxdWVyeSApOwoKCQkvLyBNYWtlIHN1cmUgdGhlcmUncyBhIGNvdW50IGZvciBldmVyeSBpdGVtLgoJCSRjb3VudHMgPSBhcnJheV9tZXJnZSgKCQkJYXJyYXlfZmlsbF9rZXlzKCAkcG9zdF90eXBlcywgMCApLAoJCQl3cF9saXN0X3BsdWNrKCAkY291bnRzLCAnY291bnQnLCAncG9zdF90eXBlJyApCgkJKTsKCgkJcmV0dXJuICRjb3VudHM7Cgl9CgoJLyoqCgkgKiBMaXN0cyByZWdpc3RlcmVkIHBvc3QgdHlwZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmlsdGVyIGJ5IG9uZSBvciBtb3JlIGZpZWxkcyAoc2VlIGdldF9wb3N0X3R5cGVzKCkgZmlyc3QgcGFyYW1ldGVyIGZvciBhIGxpc3Qgb2YgYXZhaWxhYmxlIGZpZWxkcykuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBwb3N0IHR5cGUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIHBvc3QgdHlwZSBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHBvc3QgdHlwZToKCSAqCgkgKiAqIG5hbWUKCSAqICogbGFiZWwKCSAqICogZGVzY3JpcHRpb24KCSAqICogaGllcmFyY2hpY2FsCgkgKiAqIHB1YmxpYwoJICogKiBjYXBhYmlsaXR5X3R5cGUKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogY291bnQKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgcmVnaXN0ZXJlZCBwb3N0IHR5cGVzCgkgKiAgICAgJCB3cCBwb3N0LXR5cGUgbGlzdCAtLWZvcm1hdD1jc3YKCSAqICAgICBuYW1lLGxhYmVsLGRlc2NyaXB0aW9uLGhpZXJhcmNoaWNhbCxwdWJsaWMsY2FwYWJpbGl0eV90eXBlCgkgKiAgICAgcG9zdCxQb3N0cywsLDEscG9zdAoJICogICAgIHBhZ2UsUGFnZXMsLDEsMSxwYWdlCgkgKiAgICAgYXR0YWNobWVudCxNZWRpYSwsLDEscG9zdAoJICogICAgIHJldmlzaW9uLFJldmlzaW9ucywsLCxwb3N0CgkgKiAgICAgbmF2X21lbnVfaXRlbSwiTmF2aWdhdGlvbiBNZW51IEl0ZW1zIiwsLCxwb3N0CgkgKgoJICogICAgICMgTGlzdCBwb3N0IHR5cGVzIHdpdGggJ3Bvc3QnIGNhcGFiaWxpdHkgdHlwZQoJICogICAgICQgd3AgcG9zdC10eXBlIGxpc3QgLS1jYXBhYmlsaXR5X3R5cGU9cG9zdCAtLWZpZWxkcz1uYW1lLHB1YmxpYwoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgIHwgcHVibGljIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwoJICogICAgIHwgcG9zdCAgICAgICAgICB8IDEgICAgICB8CgkgKiAgICAgfCBhdHRhY2htZW50ICAgIHwgMSAgICAgIHwKCSAqICAgICB8IHJldmlzaW9uICAgICAgfCAgICAgICAgfAoJICogICAgIHwgbmF2X21lbnVfaXRlbSB8ICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJJGZpZWxkcyA9ICRmb3JtYXR0ZXItPmZpZWxkczsKCQkkdHlwZXMgID0gZ2V0X3Bvc3RfdHlwZXMoICRhc3NvY19hcmdzLCAnb2JqZWN0cycgKTsKCQkkY291bnRzID0gW107CgoJCWlmICggY291bnQoICR0eXBlcyApID4gMCAmJiBpbl9hcnJheSggJ2NvdW50JywgJGZpZWxkcywgdHJ1ZSApICkgewoJCQkkY291bnRzID0gJHRoaXMtPmdldF9jb3VudHMoIHdwX2xpc3RfcGx1Y2soICR0eXBlcywgJ25hbWUnICkgKTsKCQl9CgoJCSR0eXBlcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICR0eXBlICkgdXNlICggJGNvdW50cyApIHsKCQkJCQkkdHlwZS0+Y291bnQgPSBpc3NldCggJGNvdW50c1sgJHR5cGUtPm5hbWUgXSApID8gJGNvdW50c1sgJHR5cGUtPm5hbWUgXSA6IDA7CgkJCQkJcmV0dXJuICR0eXBlOwoJCQl9LAoJCQkkdHlwZXMKCQkpOwoKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdHlwZXMgKTsKCX0KCgkvKioKCSAqIEdldHMgZGV0YWlscyBhYm91dCBhIHJlZ2lzdGVyZWQgcG9zdCB0eXBlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cG9zdC10eXBlPgoJICogOiBQb3N0IHR5cGUgc2x1ZwoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSB0YXhvbm9teSwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciB0aGUgc3BlY2lmaWVkIHBvc3QgdHlwZToKCSAqCgkgKiAqIG5hbWUKCSAqICogbGFiZWwKCSAqICogZGVzY3JpcHRpb24KCSAqICogaGllcmFyY2hpY2FsCgkgKiAqIHB1YmxpYwoJICogKiBjYXBhYmlsaXR5X3R5cGUKCSAqICogbGFiZWxzCgkgKiAqIGNhcAoJICogKiBzdXBwb3J0cwoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjb3VudAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGRldGFpbHMgYWJvdXQgdGhlICdwYWdlJyBwb3N0IHR5cGUuCgkgKiAgICAgJCB3cCBwb3N0LXR5cGUgZ2V0IHBhZ2UgLS1maWVsZHM9bmFtZSxsYWJlbCxoaWVyYXJjaGljYWwgLS1mb3JtYXQ9anNvbgoJICogICAgIHsibmFtZSI6InBhZ2UiLCJsYWJlbCI6IlBhZ2VzIiwiaGllcmFyY2hpY2FsIjp0cnVlfQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBvc3RfdHlwZSA9IGdldF9wb3N0X3R5cGVfb2JqZWN0KCAkYXJnc1swXSApOwoKCQlpZiAoICEgJHBvc3RfdHlwZSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlBvc3QgdHlwZSB7JGFyZ3NbMF19IGRvZXNuJ3QgZXhpc3QuIiApOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRkZWZhdWx0X2ZpZWxkcyA9IGFycmF5X21lcmdlKAoJCQkJJHRoaXMtPmZpZWxkcywKCQkJCWFycmF5KAoJCQkJCSdsYWJlbHMnLAoJCQkJCSdjYXAnLAoJCQkJCSdzdXBwb3J0cycsCgkJCQkpCgkJCSk7CgoJCQkkYXNzb2NfYXJnc1snZmllbGRzJ10gPSAkZGVmYXVsdF9maWVsZHM7CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZpZWxkcyAgICA9ICRmb3JtYXR0ZXItPmZpZWxkczsKCQkkY291bnQgICAgID0gMDsKCgkJaWYgKCBpbl9hcnJheSggJ2NvdW50JywgJGZpZWxkcywgdHJ1ZSApICkgewoJCQkkY291bnQgPSAkdGhpcy0+Z2V0X2NvdW50cyggWyAkcG9zdF90eXBlLT5uYW1lIF0gKTsKCQkJJGNvdW50ID0gJGNvdW50WyAkcG9zdF90eXBlLT5uYW1lIF07CgkJfQoKCQkkZGF0YSA9IGFycmF5KAoJCQknbmFtZScgICAgICAgICAgICA9PiAkcG9zdF90eXBlLT5uYW1lLAoJCQknbGFiZWwnICAgICAgICAgICA9PiAkcG9zdF90eXBlLT5sYWJlbCwKCQkJJ2Rlc2NyaXB0aW9uJyAgICAgPT4gJHBvc3RfdHlwZS0+ZGVzY3JpcHRpb24sCgkJCSdoaWVyYXJjaGljYWwnICAgID0+ICRwb3N0X3R5cGUtPmhpZXJhcmNoaWNhbCwKCQkJJ3B1YmxpYycgICAgICAgICAgPT4gJHBvc3RfdHlwZS0+cHVibGljLAoJCQknY2FwYWJpbGl0eV90eXBlJyA9PiAkcG9zdF90eXBlLT5jYXBhYmlsaXR5X3R5cGUsCgkJCSdsYWJlbHMnICAgICAgICAgID0+ICRwb3N0X3R5cGUtPmxhYmVscywKCQkJJ2NhcCcgICAgICAgICAgICAgPT4gJHBvc3RfdHlwZS0+Y2FwLAoJCQknc3VwcG9ydHMnICAgICAgICA9PiBnZXRfYWxsX3Bvc3RfdHlwZV9zdXBwb3J0cyggJHBvc3RfdHlwZS0+bmFtZSApLAoJCQknY291bnQnICAgICAgICAgICA9PiAkY291bnQsCgkJKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICRkYXRhICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzLCAncG9zdC10eXBlJyApOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2VudGl0eV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9lbnRpdHlfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9lbnRpdHlfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NvbW1lbnQnLCAnQ29tbWVudF9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY29tbWVudCBtZXRhJywgJ0NvbW1lbnRfTWV0YV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnbWVudScsICdNZW51X0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdtZW51IGl0ZW0nLCAnTWVudV9JdGVtX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdtZW51IGxvY2F0aW9uJywgJ01lbnVfTG9jYXRpb25fQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSduZXR3b3JrIG1ldGEnLAoJJ05ldHdvcmtfTWV0YV9Db21tYW5kJywKCWFycmF5KAoJCSdiZWZvcmVfaW52b2tlJyA9PiBmdW5jdGlvbiAoKSB7CgkJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCQl9CgkJfSwKCSkKKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ29wdGlvbicsICdPcHRpb25fQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3Bvc3QnLCAnUG9zdF9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAncG9zdCBtZXRhJywgJ1Bvc3RfTWV0YV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAncG9zdCB0ZXJtJywgJ1Bvc3RfVGVybV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAncG9zdC10eXBlJywgJ1Bvc3RfVHlwZV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2l0ZScsICdTaXRlX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoCgknc2l0ZSBtZXRhJywKCSdTaXRlX01ldGFfQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24oKSB7CgkJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCQl9CgkJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICdpc19zaXRlX21ldGFfc3VwcG9ydGVkJyApIHx8ICEgaXNfc2l0ZV9tZXRhX3N1cHBvcnRlZCgpICkgewoJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ1RoZSAlcyB0YWJsZSBpcyBub3QgaW5zdGFsbGVkLiBQbGVhc2UgcnVuIHRoZSBuZXR3b3JrIGRhdGFiYXNlIHVwZ3JhZGUuJywgJEdMT0JBTFNbJ3dwZGInXS0+YmxvZ21ldGEgKSApOwoJCQl9CgkJfSwKCSkKKTsKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdzaXRlIG9wdGlvbicsCgknU2l0ZV9PcHRpb25fQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24oKSB7CgkJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCQl9CgkJfSwKCSkKKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3RheG9ub215JywgJ1RheG9ub215X0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd0ZXJtJywgJ1Rlcm1fQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSd0ZXJtIG1ldGEnLAoJJ1Rlcm1fTWV0YV9Db21tYW5kJywKCWFycmF5KAoJCSdiZWZvcmVfaW52b2tlJyA9PiBmdW5jdGlvbigpIHsKCQkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdSZXF1aXJlcyBXb3JkUHJlc3MgNC40IG9yIGdyZWF0ZXIuJyApOwoJCQl9CgkJfSwKCSkKKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3VzZXInLCAnVXNlcl9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ3VzZXIgYXBwbGljYXRpb24tcGFzc3dvcmQnLAoJJ1VzZXJfQXBwbGljYXRpb25fUGFzc3dvcmRfQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24oKSB7CgkJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNS42JywgJzwnICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnUmVxdWlyZXMgV29yZFByZXNzIDUuNiBvciBncmVhdGVyLicgKTsKCQkJfQoJCX0sCgkpCik7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd1c2VyIG1ldGEnLCAnVXNlcl9NZXRhX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoCgkndXNlciBzZXNzaW9uJywKCSdVc2VyX1Nlc3Npb25fQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24oKSB7CgkJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC4wJywgJzwnICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnUmVxdWlyZXMgV29yZFByZXNzIDQuMCBvciBncmVhdGVyLicgKTsKCQkJfQoJCX0sCgkpCik7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd1c2VyIHRlcm0nLCAnVXNlcl9UZXJtX0NvbW1hbmQnICk7CgppZiAoIGNsYXNzX2V4aXN0cyggJ1dQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmROYW1lc3BhY2UnICkgKSB7CglXUF9DTEk6OmFkZF9jb21tYW5kKCAnbmV0d29yaycsICdOZXR3b3JrX05hbWVzcGFjZScgKTsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xQaHBDb2RlOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBXUF9DTEk7CgpmaW5hbCBjbGFzcyBQaHBDb2RlRXh0cmFjdG9yIGV4dGVuZHMgUGhwQ29kZSB7Cgl1c2UgSXRlcmFibGVDb2RlRXh0cmFjdG9yOwoKCXB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCgkJJ2V4dHJhY3RDb21tZW50cycgPT4gWyAndHJhbnNsYXRvcnMnLCAnVHJhbnNsYXRvcnMnIF0sCgkJJ2NvbnN0YW50cycgICAgICAgPT4gW10sCgkJJ2Z1bmN0aW9ucycgICAgICAgPT4gWwoJCQknX18nICAgICAgICAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2F0dHJfXycgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2h0bWxfXycgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX3htbF9fJyAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknX2UnICAgICAgICAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2F0dHJfZScgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2h0bWxfZScgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX3htbF9lJyAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknX3gnICAgICAgICAgICAgICA9PiAndGV4dF9jb250ZXh0X2RvbWFpbicsCgkJCSdfZXgnICAgICAgICAgICAgID0+ICd0ZXh0X2NvbnRleHRfZG9tYWluJywKCQkJJ2VzY19hdHRyX3gnICAgICAgPT4gJ3RleHRfY29udGV4dF9kb21haW4nLAoJCQknZXNjX2h0bWxfeCcgICAgICA9PiAndGV4dF9jb250ZXh0X2RvbWFpbicsCgkJCSdlc2NfeG1sX3gnICAgICAgID0+ICd0ZXh0X2NvbnRleHRfZG9tYWluJywKCQkJJ19uJyAgICAgICAgICAgICAgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2RvbWFpbicsCgkJCSdfbngnICAgICAgICAgICAgID0+ICdzaW5nbGVfcGx1cmFsX251bWJlcl9jb250ZXh0X2RvbWFpbicsCgkJCSdfbl9ub29wJyAgICAgICAgID0+ICdzaW5nbGVfcGx1cmFsX2RvbWFpbicsCgkJCSdfbnhfbm9vcCcgICAgICAgID0+ICdzaW5nbGVfcGx1cmFsX2NvbnRleHRfZG9tYWluJywKCgkJCS8vIENvbXBhdC4KCQkJJ18nICAgICAgICAgICAgICAgPT4gJ2dldHRleHQnLCAvLyBTYW1lIGFzICd0ZXh0X2RvbWFpbicuCgoJCQkvLyBEZXByZWNhdGVkLgoJCQknX2MnICAgICAgICAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknX25jJyAgICAgICAgICAgICA9PiAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJywKCQkJJ19fbmdldHRleHQnICAgICAgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2RvbWFpbicsCgkJCSdfX25nZXR0ZXh0X25vb3AnID0+ICdzaW5nbGVfcGx1cmFsX2RvbWFpbicsCgkJXSwKCV07CgoJcHJvdGVjdGVkIHN0YXRpYyAkZnVuY3Rpb25zU2Nhbm5lckNsYXNzID0gJ1dQX0NMSVxJMThuXFBocEZ1bmN0aW9uc1NjYW5uZXInOwoKCS8qKgoJICoge0Bpbmhlcml0ZG9jfQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoICRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdICkgewoJCVdQX0NMSTo6ZGVidWcoICJQYXJzaW5nIGZpbGUgeyRvcHRpb25zWydmaWxlJ119IiwgJ21ha2UtcG90JyApOwoKCQl0cnkgewoJCQlzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZSggJHN0cmluZywgWyAkdHJhbnNsYXRpb25zIF0sICRvcHRpb25zICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknQ291bGQgbm90IHBhcnNlIGZpbGUgJTEkczogJTIkcycsCgkJCQkJJG9wdGlvbnNbJ2ZpbGUnXSwKCQkJCQkkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfQoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxFeHRyYWN0b3JzXEV4dHJhY3RvcjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xFeHRyYWN0b3JJbnRlcmZhY2U7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFdQX0NMSTsKCmZpbmFsIGNsYXNzIEJsb2NrRXh0cmFjdG9yIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlIHsKCXVzZSBJdGVyYWJsZUNvZGVFeHRyYWN0b3I7CgoJLyoqCgkgKiBAaW5oZXJpdGRvYwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoICRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdICkgewoJCSRmaWxlID0gJG9wdGlvbnNbJ2ZpbGUnXTsKCQlXUF9DTEk6OmRlYnVnKCAiUGFyc2luZyBmaWxlIHskZmlsZX0iLCAnbWFrZS1wb3QnICk7CgoJCSRmaWxlX2RhdGEgPSBqc29uX2RlY29kZSggJHN0cmluZywgdHJ1ZSApOwoKCQlpZiAoIG51bGwgPT09ICRmaWxlX2RhdGEgKSB7CgkJCVdQX0NMSTo6ZGVidWcoCgkJCQlzcHJpbnRmKAoJCQkJCSdDb3VsZCBub3QgcGFyc2UgZmlsZSAlMSRzOiBlcnJvciBjb2RlICUyJHMnLAoJCQkJCSRmaWxlLAoJCQkJCWpzb25fbGFzdF9lcnJvcigpCgkJCQkpLAoJCQkJJ21ha2UtcG90JwoJCQkpOwoKCQkJcmV0dXJuOwoJCX0KCgkJJGRvbWFpbiA9IGlzc2V0KCAkZmlsZV9kYXRhWyd0ZXh0ZG9tYWluJ10gKSA/ICRmaWxlX2RhdGFbJ3RleHRkb21haW4nXSA6IG51bGw7CgoJCS8vIEFsd2F5cyBhbGxvdyBtaXNzaW5nIGRvbWFpbiBvciB3aGVuIC0taWdub3JlLWRvbWFpbiBpcyB1c2VkLCBidXQgc2tpcCBpZiBkb21haW5zIGRvbid0IG1hdGNoLgoJCWlmICggbnVsbCAhPT0gJHRyYW5zbGF0aW9ucy0+Z2V0RG9tYWluKCkgJiYgbnVsbCAhPT0gJGRvbWFpbiAmJiAkZG9tYWluICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJGFkZF9yZWZlcmVuY2UgPSAhIGVtcHR5KCAkb3B0aW9uc1snYWRkUmVmZXJlbmNlcyddICk7CgoJCWZvcmVhY2ggKCAkZmlsZV9kYXRhIGFzICRrZXkgPT4gJG9yaWdpbmFsICkgewoJCQlzd2l0Y2ggKCAka2V5ICkgewoJCQkJY2FzZSAndGl0bGUnOgoJCQkJY2FzZSAnZGVzY3JpcHRpb24nOgoJCQkJCSR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCggc3ByaW50ZiggJ2Jsb2NrICVzJywgJGtleSApLCAkb3JpZ2luYWwgKTsKCQkJCQlpZiAoICRhZGRfcmVmZXJlbmNlICkgewoJCQkJCQkkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSggJGZpbGUgKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICdrZXl3b3Jkcyc6CgkJCQkJaWYgKCAhIGlzX2FycmF5KCAkb3JpZ2luYWwgKSApIHsKCQkJCQkJY29udGludWUgMjsKCQkJCQl9CgoJCQkJCWZvcmVhY2ggKCAkb3JpZ2luYWwgYXMgJG1zZyApIHsKCQkJCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCAnYmxvY2sga2V5d29yZCcsICRtc2cgKTsKCQkJCQkJaWYgKCAkYWRkX3JlZmVyZW5jZSApIHsKCQkJCQkJCSR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCAkZmlsZSApOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQlicmVhazsKCQkJCWNhc2UgJ3N0eWxlcyc6CgkJCQkJaWYgKCAhIGlzX2FycmF5KCAkb3JpZ2luYWwgKSApIHsKCQkJCQkJY29udGludWUgMjsKCQkJCQl9CgoJCQkJCWZvcmVhY2ggKCAkb3JpZ2luYWwgYXMgJG1zZyApIHsKCQkJCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCAnYmxvY2sgc3R5bGUgbGFiZWwnLCAkbXNnWydsYWJlbCddICk7CgkJCQkJCWlmICggJGFkZF9yZWZlcmVuY2UgKSB7CgkJCQkJCQkkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSggJGZpbGUgKTsKCQkJCQkJfQoJCQkJCX0KCQkJfQoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xKc0NvZGU7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFBlYXN0XFN5bnRheFxFeGNlcHRpb24gYXMgUGVhc3RFeGNlcHRpb247CnVzZSBXUF9DTEk7CgpmaW5hbCBjbGFzcyBNYXBDb2RlRXh0cmFjdG9yIGV4dGVuZHMgSnNDb2RlIHsKCXVzZSBJdGVyYWJsZUNvZGVFeHRyYWN0b3I7CgoJcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKCQknZXh0cmFjdENvbW1lbnRzJyA9PiBbICd0cmFuc2xhdG9ycycsICdUcmFuc2xhdG9ycycgXSwKCQknY29uc3RhbnRzJyAgICAgICA9PiBbXSwKCQknZnVuY3Rpb25zJyAgICAgICA9PiBbCgkJCSdfXycgID0+ICd0ZXh0X2RvbWFpbicsCgkJCSdfeCcgID0+ICd0ZXh0X2NvbnRleHRfZG9tYWluJywKCQkJJ19uJyAgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2RvbWFpbicsCgkJCSdfbngnID0+ICdzaW5nbGVfcGx1cmFsX251bWJlcl9jb250ZXh0X2RvbWFpbicsCgkJXSwKCV07CgoJLyoqCgkgKiB7QGluaGVyaXRkb2N9CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZyggJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICdmaWxlJywgJG9wdGlvbnMgKSB8fCBzdWJzdHIoICRvcHRpb25zWydmaWxlJ10sIC03ICkgIT09ICcuanMubWFwJyApIHsKCQkJcmV0dXJuOwoJCX0KCQkkb3B0aW9uc1snZmlsZSddID0gc3Vic3RyKCAkb3B0aW9uc1snZmlsZSddLCAwLCAtNyApIC4gJy5qcyc7CgoJCXRyeSB7CgkJCSRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgoJCQkkbWFwX29iamVjdCA9IGpzb25fZGVjb2RlKCAkc3RyaW5nICk7CgoJCQlpZiAoICEgaXNzZXQoICRtYXBfb2JqZWN0LT5zb3VyY2VzQ29udGVudCApIHx8ICEgaXNfYXJyYXkoICRtYXBfb2JqZWN0LT5zb3VyY2VzQ29udGVudCApICkgewoJCQkJcmV0dXJuOwoJCQl9CgoJCQkkc3RyaW5nID0gaW1wbG9kZSggIlxuIiwgJG1hcF9vYmplY3QtPnNvdXJjZXNDb250ZW50ICk7CgoJCQlXUF9DTEk6OmRlYnVnKCAiUGFyc2luZyBmaWxlIHskb3B0aW9uc1snZmlsZSddfSIsICdtYWtlLXBvdCcgKTsKCgkJCSRmdW5jdGlvbnMgPSBuZXcgSnNGdW5jdGlvbnNTY2FubmVyKCAkc3RyaW5nICk7CgoJCQkkZnVuY3Rpb25zLT5lbmFibGVDb21tZW50c0V4dHJhY3Rpb24oICRvcHRpb25zWydleHRyYWN0Q29tbWVudHMnXSApOwoJCQkkZnVuY3Rpb25zLT5zYXZlR2V0dGV4dEZ1bmN0aW9ucyggJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMgKTsKCQl9IGNhdGNoICggUGVhc3RFeGNlcHRpb24gJGUgKSB7CgkJCVdQX0NMSTo6ZGVidWcoCgkJCQlzcHJpbnRmKAoJCQkJCSdDb3VsZCBub3QgcGFyc2UgZmlsZSAlMSRzLm1hcDogJTIkcyAobGluZSAlMyRkLCBjb2x1bW4gJTQkZCBpbiB0aGUgY29uY2F0ZW5hdGVkIHNvdXJjZXNDb250ZW50KScsCgkJCQkJJG9wdGlvbnNbJ2ZpbGUnXSwKCQkJCQkkZS0+Z2V0TWVzc2FnZSgpLAoJCQkJCSRlLT5nZXRQb3NpdGlvbigpLT5nZXRMaW5lKCksCgkJCQkJJGUtPmdldFBvc2l0aW9uKCktPmdldENvbHVtbigpCgkJCQkpLAoJCQkJJ21ha2UtcG90JwoJCQkpOwoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFJlY3Vyc2l2ZUNhbGxiYWNrRmlsdGVySXRlcmF0b3I7CnVzZSBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjsKdXNlIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I7CnVzZSBTcGxGaWxlSW5mbzsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxVdGlsczsKCnRyYWl0IEl0ZXJhYmxlQ29kZUV4dHJhY3RvciB7CgoJcHJpdmF0ZSBzdGF0aWMgJGRpciA9ICcnOwoKCS8qKgoJICogRXh0cmFjdCB0aGUgdHJhbnNsYXRpb25zIGZyb20gYSBmaWxlLgoJICoKCSAqIEBwYXJhbSBhcnJheXxzdHJpbmcgJGZpbGVfb3JfZmlsZXMgQSBwYXRoIG9mIGEgZmlsZSBvciBmaWxlcwoJICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zICBUaGUgdHJhbnNsYXRpb25zIGluc3RhbmNlIHRvIGFwcGVuZCB0aGUgbmV3IHRyYW5zbGF0aW9ucy4KCSAqIEBwYXJhbSBhcnJheSAgICAgICAgJG9wdGlvbnMgICAgICB7CgkgKiAgICAgT3B0aW9uYWwuIEFuIGFycmF5IG9mIG9wdGlvbnMgcGFzc2VkIGRvd24gdG8gc3RhdGljOjpmcm9tU3RyaW5nKCkKCSAqCgkgKiAgICAgQHR5cGUgYm9vbCAgJHdwRXh0cmFjdFRlbXBsYXRlcyBFeHRyYWN0ICdUZW1wbGF0ZSBOYW1lJyBoZWFkZXJzIGluIHRoZW1lIGZpbGVzLiBEZWZhdWx0ICdmYWxzZScuCgkgKiAgICAgQHR5cGUgYXJyYXkgJHJlc3RyaWN0RmlsZU5hbWVzICBTa2lwIGFsbCBmaWxlcyB3aGljaCBhcmUgbm90IGluY2x1ZGVkIGluIHRoaXMgYXJyYXkuCgkgKiB9CgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tRmlsZSggJGZpbGVfb3JfZmlsZXMsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdICkgewoJCWZvcmVhY2ggKCBzdGF0aWM6OmdldEZpbGVzKCAkZmlsZV9vcl9maWxlcyApIGFzICRmaWxlICkgewoJCQlpZiAoICEgZW1wdHkoICRvcHRpb25zWydyZXN0cmljdEZpbGVOYW1lcyddICkgKSB7CgkJCQkkYmFzZW5hbWUgPSBVdGlsc1xiYXNlbmFtZSggJGZpbGUgKTsKCQkJCWlmICggISBpbl9hcnJheSggJGJhc2VuYW1lLCAkb3B0aW9uc1sncmVzdHJpY3RGaWxlTmFtZXMnXSwgdHJ1ZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQl9CgoJCQkvLyBNYWtlIHN1cmUgYSByZWxhdGl2ZSBmaWxlIHBhdGggaXMgYWRkZWQgYXMgYSBjb21tZW50LgoJCQkkb3B0aW9uc1snZmlsZSddID0gbHRyaW0oIHN0cl9yZXBsYWNlKCBzdGF0aWM6OiRkaXIsICcnLCBVdGlsc1xub3JtYWxpemVfcGF0aCggJGZpbGUgKSApLCAnLycgKTsKCgkJCSRzdHJpbmcgPSBmaWxlX2dldF9jb250ZW50cyggJGZpbGUgKTsKCgkJCWlmICggISAkc3RyaW5nICkgewoJCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCQlzcHJpbnRmKAoJCQkJCQknQ291bGQgbm90IGxvYWQgZmlsZSAlMXMnLAoJCQkJCQkkZmlsZQoJCQkJCSksCgkJCQkJJ21ha2UtcG90JwoJCQkJKTsKCgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkb3B0aW9uc1snd3BFeHRyYWN0VGVtcGxhdGVzJ10gKSApIHsKCQkJCSRoZWFkZXJzID0gTWFrZVBvdENvbW1hbmQ6OmdldF9maWxlX2RhdGFfZnJvbV9zdHJpbmcoICRzdHJpbmcsIFsgJ1RlbXBsYXRlIE5hbWUnID0+ICdUZW1wbGF0ZSBOYW1lJyBdICk7CgoJCQkJaWYgKCAhIGVtcHR5KCAkaGVhZGVyc1snVGVtcGxhdGUgTmFtZSddICkgKSB7CgkJCQkJJHRyYW5zbGF0aW9uID0gbmV3IFRyYW5zbGF0aW9uKCAnJywgJGhlYWRlcnNbJ1RlbXBsYXRlIE5hbWUnXSApOwoJCQkJCSR0cmFuc2xhdGlvbi0+YWRkRXh0cmFjdGVkQ29tbWVudCggJ1RlbXBsYXRlIE5hbWUgb2YgdGhlIHRoZW1lJyApOwoKCQkJCQkkdHJhbnNsYXRpb25zW10gPSAkdHJhbnNsYXRpb247CgkJCQl9CgkJCX0KCgkJCXN0YXRpYzo6ZnJvbVN0cmluZyggJHN0cmluZywgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBFeHRyYWN0IHRoZSB0cmFuc2xhdGlvbnMgZnJvbSBhIGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZGlyICAgICAgICAgICAgICAgIFJvb3QgcGF0aCB0byBzdGFydCB0aGUgcmVjdXJzaXZlIHRyYXZlcnNhbCBpbi4KCSAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucyBUaGUgdHJhbnNsYXRpb25zIGluc3RhbmNlIHRvIGFwcGVuZCB0aGUgbmV3IHRyYW5zbGF0aW9ucy4KCSAqIEBwYXJhbSBhcnJheSAgICAgICAgJG9wdGlvbnMgICAgICB7CgkgKiAgICAgT3B0aW9uYWwuIEFuIGFycmF5IG9mIG9wdGlvbnMgcGFzc2VkIGRvd24gdG8gc3RhdGljOjpmcm9tU3RyaW5nKCkKCSAqCgkgKiAgICAgQHR5cGUgYm9vbCAkd3BFeHRyYWN0VGVtcGxhdGVzIEV4dHJhY3QgJ1RlbXBsYXRlIE5hbWUnIGhlYWRlcnMgaW4gdGhlbWUgZmlsZXMuIERlZmF1bHQgJ2ZhbHNlJy4KCSAqICAgICBAdHlwZSBhcnJheSAkZXhjbHVkZSAgICAgICAgICAgQSBsaXN0IG9mIHBhdGggdG8gZXhjbHVkZS4gRGVmYXVsdCBbXS4KCSAqICAgICBAdHlwZSBhcnJheSAkZXh0ZW5zaW9ucyAgICAgICAgQSBsaXN0IG9mIGV4dGVuc2lvbnMgdG8gcHJvY2Vzcy4gRGVmYXVsdCBbXS4KCSAqIH0KCSAqIEByZXR1cm4gbnVsbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21EaXJlY3RvcnkoICRkaXIsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdICkgewoJCSRkaXIgPSBVdGlsc1xub3JtYWxpemVfcGF0aCggJGRpciApOwoKCQlzdGF0aWM6OiRkaXIgPSAkZGlyOwoKCQkkaW5jbHVkZSA9IGlzc2V0KCAkb3B0aW9uc1snaW5jbHVkZSddICkgPyAkb3B0aW9uc1snaW5jbHVkZSddIDogW107CgkJJGV4Y2x1ZGUgPSBpc3NldCggJG9wdGlvbnNbJ2V4Y2x1ZGUnXSApID8gJG9wdGlvbnNbJ2V4Y2x1ZGUnXSA6IFtdOwoKCQkkZmlsZXMgPSBzdGF0aWM6OmdldEZpbGVzRnJvbURpcmVjdG9yeSggJGRpciwgJGluY2x1ZGUsICRleGNsdWRlLCAkb3B0aW9uc1snZXh0ZW5zaW9ucyddICk7CgoJCWlmICggISBlbXB0eSggJGZpbGVzICkgKSB7CgkJCXN0YXRpYzo6ZnJvbUZpbGUoICRmaWxlcywgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMgKTsKCQl9CgoJCXN0YXRpYzo6JGRpciA9ICcnOwoJfQoKCS8qKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgZmlsZSBpcyB2YWxpZCBiYXNlZCBvbiBnaXZlbiBtYXRjaGVycy4KCSAqCgkgKiBAcGFyYW0gU3BsRmlsZUluZm8gJGZpbGUgICAgIEZpbGUgb3IgZGlyZWN0b3J5LgoJICogQHBhcmFtIGFycmF5ICAgICAgICRtYXRjaGVycyBMaXN0IG9mIGZpbGVzIGFuZCBkaXJlY3RvcmllcyB0byBtYXRjaC4KCSAqIEByZXR1cm4gaW50IEhvdyBzdHJvbmdseSB0aGUgZmlsZSBpcyBtYXRjaGVkLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGNhbGN1bGF0ZU1hdGNoU2NvcmUoIFNwbEZpbGVJbmZvICRmaWxlLCBhcnJheSAkbWF0Y2hlcnMgPSBbXSApIHsKCQlpZiAoIGVtcHR5KCAkbWF0Y2hlcnMgKSApIHsKCQkJcmV0dXJuIDA7CgkJfQoKCQlpZiAoIGluX2FycmF5KCAkZmlsZS0+Z2V0QmFzZW5hbWUoKSwgJG1hdGNoZXJzLCB0cnVlICkgKSB7CgkJCXJldHVybiAxMDsKCQl9CgoJCS8vIENoZWNrIGZvciBtb3JlIGNvbXBsZXggcGF0aHMsIGUuZy4gL3NvbWUvc3ViL2ZvbGRlci4KCQkkcm9vdF9yZWxhdGl2ZV9wYXRoID0gc3RyX3JlcGxhY2UoIHN0YXRpYzo6JGRpciwgJycsICRmaWxlLT5nZXRQYXRobmFtZSgpICk7CgoJCWZvcmVhY2ggKCAkbWF0Y2hlcnMgYXMgJHBhdGhfb3JfZmlsZSApIHsKCQkJJHBhdHRlcm4gPSBwcmVnX3F1b3RlKCBzdHJfcmVwbGFjZSggJyonLCAnX193aWxkY2FyZF9fJywgJHBhdGhfb3JfZmlsZSApLCAnLycgKTsKCQkJJHBhdHRlcm4gPSAnKF58LyknIC4gc3RyX3JlcGxhY2UoICdfX3dpbGRjYXJkX18nLCAnKC4rKScsICRwYXR0ZXJuICk7CgoJCQkvLyBCYXNlIHNjb3JlIGlzIHRoZSBhbW91bnQgb2YgbmVzdGVkIGRpcmVjdG9yaWVzLCBkaXNjb3VudGluZyB3aWxkY2FyZHMuCgkJCSRiYXNlX3Njb3JlID0gY291bnQoCgkJCQlhcnJheV9maWx0ZXIoCgkJCQkJZXhwbG9kZSggJy8nLCAkcGF0aF9vcl9maWxlICksCgkJCQkJc3RhdGljIGZ1bmN0aW9uICggJGNvbXBvbmVudCApIHsKCQkJCQkJcmV0dXJuICcqJyAhPT0gJGNvbXBvbmVudDsKCQkJCQl9CgkJCQkpCgkJCSk7CgkJCWlmICggMCA9PT0gJGJhc2Vfc2NvcmUgKSB7CgkJCQkvLyBJZiB0aGUgbWF0Y2hlciBpcyBzaW1wbHkgKiBpdCBnZXRzIGEgc2NvcmUgYWJvdmUgdGhlIGltcGxpY2l0IHNjb3JlIGJ1dCBiZWxvdyAxLgoJCQkJJGJhc2Vfc2NvcmUgPSAwLjI7CgkJCX0KCgkJCS8vIElmIHRoZSBtYXRjaGVyIGNvbnRhaW5zIG5vIHdpbGRjYXJkcyBhbmQgbWF0Y2hlcyB0aGUgZW5kIG9mIHRoZSBwYXRoLgoJCQlpZiAoCgkJCQlmYWxzZSA9PT0gc3RycG9zKCAkcGF0aF9vcl9maWxlLCAnKicgKSAmJgoJCQkJZmFsc2UgIT09IG1iX2VyZWcoICRwYXR0ZXJuIC4gJyQnLCAkcm9vdF9yZWxhdGl2ZV9wYXRoICkKCQkJKSB7CgkJCQlyZXR1cm4gJGJhc2Vfc2NvcmUgKiAxMDsKCQkJfQoKCQkJLy8gSWYgdGhlIG1hdGNoZXIgbWF0Y2hlcyB0aGUgZW5kIG9mIHRoZSBwYXRoIG9yIGEgZnVsbCBkaXJlY3RvcnkgY29udGFpbmVkLgoJCQlpZiAoIGZhbHNlICE9PSBtYl9lcmVnKCAkcGF0dGVybiAuICcoL3wkKScsICRyb290X3JlbGF0aXZlX3BhdGggKSApIHsKCQkJCXJldHVybiAkYmFzZV9zY29yZTsKCQkJfQoJCX0KCgkJcmV0dXJuIDA7Cgl9CgoJLyoqCgkgKiBEZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IGEgZGlyZWN0b3J5IGhhcyBjaGlsZHJlbiB0aGF0IG1heSBiZSBtYXRjaGVkLgoJICoKCSAqIEBwYXJhbSBTcGxGaWxlSW5mbyAkZGlyICAgICAgRGlyZWN0b3J5LgoJICogQHBhcmFtIGFycmF5ICAgICAgICRtYXRjaGVycyBMaXN0IG9mIGZpbGVzIGFuZCBkaXJlY3RvcmllcyB0byBtYXRjaC4KCSAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIG9yIG5vdCB0aGVyZSBhcmUgYW55IG1hdGNoZXJzIGZvciBjaGlsZHJlbiBvZiB0aGlzIGRpcmVjdG9yeS4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjb250YWluc01hdGNoaW5nQ2hpbGRyZW4oIFNwbEZpbGVJbmZvICRkaXIsIGFycmF5ICRtYXRjaGVycyA9IFtdICkgewoJCWlmICggZW1wdHkoICRtYXRjaGVycyApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKiogQHZhciBzdHJpbmcgJHJvb3RfcmVsYXRpdmVfcGF0aCAqLwoJCSRyb290X3JlbGF0aXZlX3BhdGggPSBzdHJfcmVwbGFjZSggc3RhdGljOjokZGlyLCAnJywgJGRpci0+Z2V0UGF0aG5hbWUoKSApOwoKCQlmb3JlYWNoICggJG1hdGNoZXJzIGFzICRwYXRoX29yX2ZpbGUgKSB7CgkJCS8vIElmIHRoZSBtYXRjaGVyIGNvbnRhaW5zIG5vIHdpbGRjYXJkcyBhbmQgdGhlIHBhdGggbWF0Y2hlcyB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXIuCgkJCWlmICgKCQkJCScnICE9PSAkcm9vdF9yZWxhdGl2ZV9wYXRoICYmCgkJCQlmYWxzZSA9PT0gc3RycG9zKCAkcGF0aF9vcl9maWxlLCAnKicgKSAmJgoJCQkJMCA9PT0gc3RycG9zKCAkcGF0aF9vcl9maWxlIC4gJy8nLCAkcm9vdF9yZWxhdGl2ZV9wYXRoICkKCQkJKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJJGJhc2UgPSBjdXJyZW50KCBleHBsb2RlKCAnKicsICRwYXRoX29yX2ZpbGUgKSApOwoKCQkJLy8gSWYgc3RhcnQgb2YgdGhlIHBhdGggbWF0Y2hlcyB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXIgdW50aWwgdGhlIGZpcnN0IHdpbGRjYXJkLgoJCQkvLyBPciB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXIgdW50aWwgdGhlIGZpcnN0IHdpbGRjYXJkIG1hdGNoZXMgdGhlIHN0YXJ0IG9mIHRoZSBwYXRoLgoJCQlpZiAoCgkJCQkoICcnICE9PSAkcm9vdF9yZWxhdGl2ZV9wYXRoICYmIDAgPT09IHN0cnBvcyggJGJhc2UsICRyb290X3JlbGF0aXZlX3BhdGggKSApIHx8CgkJCQkoICcnICE9PSAkYmFzZSAmJiAwID09PSBzdHJwb3MoICRyb290X3JlbGF0aXZlX3BhdGgsICRiYXNlICkgKQoJCQkpIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZWN1cnNpdmVseSBnZXRzIGFsbCBQSFAgZmlsZXMgd2l0aGluIGEgZGlyZWN0b3J5LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGRpciBBIHBhdGggb2YgYSBkaXJlY3RvcnkuCgkgKiBAcGFyYW0gYXJyYXkgJGluY2x1ZGUgTGlzdCBvZiBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgdG8gaW5jbHVkZS4KCSAqIEBwYXJhbSBhcnJheSAkZXhjbHVkZSBMaXN0IG9mIGZpbGVzIGFuZCBkaXJlY3RvcmllcyB0byBza2lwLgoJICogQHBhcmFtIGFycmF5ICRleHRlbnNpb25zIExpc3Qgb2YgZmlsZW5hbWUgZXh0ZW5zaW9ucyB0byBwcm9jZXNzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgRmlsZSBsaXN0LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEZpbGVzRnJvbURpcmVjdG9yeSggJGRpciwgYXJyYXkgJGluY2x1ZGUgPSBbXSwgYXJyYXkgJGV4Y2x1ZGUgPSBbXSwgJGV4dGVuc2lvbnMgPSBbXSApIHsKCQkkZmlsdGVyZWRfZmlsZXMgPSBbXTsKCgkJJGZpbGVzID0gbmV3IFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IoCgkJCW5ldyBSZWN1cnNpdmVDYWxsYmFja0ZpbHRlckl0ZXJhdG9yKAoJCQkJbmV3IFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKCAkZGlyLCBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6U0tJUF9ET1RTIHwgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlVOSVhfUEFUSFMgfCBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6Rk9MTE9XX1NZTUxJTktTICksCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCAkZmlsZSwgJGtleSwgJGl0ZXJhdG9yICkgdXNlICggJGluY2x1ZGUsICRleGNsdWRlLCAkZXh0ZW5zaW9ucyApIHsKCQkJCQkvKiogQHZhciBSZWN1cnNpdmVDYWxsYmFja0ZpbHRlckl0ZXJhdG9yICRpdGVyYXRvciAqLwoJCQkJCS8qKiBAdmFyIFNwbEZpbGVJbmZvICRmaWxlICovCgoJCQkJCS8vIE5vcm1hbGl6ZSBpbmNsdWRlIGFuZCBleGNsdWRlIHBhdGhzLgoJCQkJCSRpbmNsdWRlID0gYXJyYXlfbWFwKCAnc3RhdGljOjp0cmltX2xlYWRpbmdfc2xhc2gnLCAkaW5jbHVkZSApOwoJCQkJCSRleGNsdWRlID0gYXJyYXlfbWFwKCAnc3RhdGljOjp0cmltX2xlYWRpbmdfc2xhc2gnLCAkZXhjbHVkZSApOwoKCQkJCQkvLyBJZiBubyAkaW5jbHVkZSBpcyBwYXNzZWQgZXZlcnl0aGluZyBnZXRzIHRoZSB3ZWFrZXN0IHBvc3NpYmxlIG1hdGNoaW5nIHNjb3JlLgoJCQkJCSRpbmNsdXNpb25fc2NvcmUgPSBlbXB0eSggJGluY2x1ZGUgKSA/IDAuMSA6IHN0YXRpYzo6Y2FsY3VsYXRlTWF0Y2hTY29yZSggJGZpbGUsICRpbmNsdWRlICk7CgkJCQkJJGV4Y2x1c2lvbl9zY29yZSA9IHN0YXRpYzo6Y2FsY3VsYXRlTWF0Y2hTY29yZSggJGZpbGUsICRleGNsdWRlICk7CgoJCQkJCS8vIEFsd2F5cyBpbmNsdWRlIGRpcmVjdG9yaWVzIHRoYXQgYXJlbid0IGV4Y2x1ZGVkLgoJCQkJCWlmICggMCA9PT0gJGV4Y2x1c2lvbl9zY29yZSAmJiAkaXRlcmF0b3ItPmhhc0NoaWxkcmVuKCkgKSB7CgkJCQkJCXJldHVybiB0cnVlOwoJCQkJCX0KCgkJCQkJaWYgKCAoIDAgPT09ICRpbmNsdXNpb25fc2NvcmUgfHwgJGV4Y2x1c2lvbl9zY29yZSA+ICRpbmNsdXNpb25fc2NvcmUgKSAmJiAkaXRlcmF0b3ItPmhhc0NoaWxkcmVuKCkgKSB7CgkJCQkJCS8vIEFsd2F5cyBpbmNsdWRlIGRpcmVjdG9yaWVzIHRoYXQgbWF5IGhhdmUgbWF0Y2hpbmcgY2hpbGRyZW4gZXZlbiBpZiB0aGV5IGFyZSBleGNsdWRlZC4KCQkJCQkJcmV0dXJuIHN0YXRpYzo6Y29udGFpbnNNYXRjaGluZ0NoaWxkcmVuKCAkZmlsZSwgJGluY2x1ZGUgKTsKCQkJCQl9CgoJCQkJCWlmICggISAkZmlsZS0+aXNGaWxlKCkgfHwgISBpbl9hcnJheSggJGZpbGUtPmdldEV4dGVuc2lvbigpLCAkZXh0ZW5zaW9ucywgdHJ1ZSApICkgewoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoKCQkJCQlyZXR1cm4gJGluY2x1c2lvbl9zY29yZSA+ICRleGNsdXNpb25fc2NvcmU7CgkJCQl9CgkJCSksCgkJCVJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OkNISUxEX0ZJUlNUCgkJKTsKCgkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJLyoqIEB2YXIgU3BsRmlsZUluZm8gJGZpbGUgKi8KCQkJaWYgKCAhICRmaWxlLT5pc0ZpbGUoKSB8fCAhIGluX2FycmF5KCAkZmlsZS0+Z2V0RXh0ZW5zaW9uKCksICRleHRlbnNpb25zLCB0cnVlICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGZpbHRlcmVkX2ZpbGVzW10gPSBVdGlsc1xub3JtYWxpemVfcGF0aCggJGZpbGUtPmdldFBhdGhuYW1lKCkgKTsKCQl9CgoJCXNvcnQoICRmaWx0ZXJlZF9maWxlcywgU09SVF9OQVRVUkFMIHwgU09SVF9GTEFHX0NBU0UgKTsKCgkJcmV0dXJuICRmaWx0ZXJlZF9maWxlczsKCX0KCgkvKioKCSAqIFRyaW0gbGVhZGluZyBzbGFzaCBmcm9tIGEgcGF0aC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gdHJpbS4KCSAqIEByZXR1cm4gc3RyaW5nIFRyaW1tZWQgcGF0aC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdHJpbV9sZWFkaW5nX3NsYXNoKCAkcGF0aCApIHsKCQlyZXR1cm4gbHRyaW0oICRwYXRoLCAnLycgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcVXRpbHNcSnNGdW5jdGlvbnNTY2FubmVyIGFzIEdldHRleHRKc0Z1bmN0aW9uc1NjYW5uZXI7CnVzZSBHZXR0ZXh0XFV0aWxzXFBhcnNlZENvbW1lbnQ7CnVzZSBQZWFzdFxQZWFzdDsKdXNlIFBlYXN0XFN5bnRheFxOb2RlOwp1c2UgUGVhc3RcVHJhdmVyc2VyOwoKZmluYWwgY2xhc3MgSnNGdW5jdGlvbnNTY2FubmVyIGV4dGVuZHMgR2V0dGV4dEpzRnVuY3Rpb25zU2Nhbm5lciB7CgoJLyoqCgkgKiBJZiBub3QgZmFsc2UsIGNvbW1lbnRzIHdpbGwgYmUgZXh0cmFjdGVkLgoJICoKCSAqIEB2YXIgc3RyaW5nfGZhbHNlfGFycmF5CgkgKi8KCXByaXZhdGUgJGV4dHJhY3RfY29tbWVudHMgPSBmYWxzZTsKCgkvKioKCSAqIEhvbGRzIGEgbGlzdCBvZiBzb3VyY2UgY29kZSBjb21tZW50cyBhbHJlYWR5IGFkZGVkIHRvIGEgc3RyaW5nLgoJICoKCSAqIFByZXZlbnRzIGFzc29jaWF0aW5nIHRoZSBzYW1lIGNvbW1lbnQgdG8gbXVsdGlwbGUgc3RyaW5ncy4KCSAqCgkgKiBAdmFyIE5vZGVcQ29tbWVudFtdICRjb21tZW50c19jYWNoZQoJICovCglwcml2YXRlICRjb21tZW50c19jYWNoZSA9IFtdOwoKCS8qKgoJICogRW5hYmxlIGV4dHJhY3RpbmcgY29tbWVudHMgdGhhdCBzdGFydCB3aXRoIGEgdGFnIChpZiAkdGFnIGlzIGVtcHR5IGFsbCB0aGUgY29tbWVudHMgd2lsbCBiZSBleHRyYWN0ZWQpLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkdGFnCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlbmFibGVDb21tZW50c0V4dHJhY3Rpb24oICR0YWcgPSAnJyApIHsKCQkkdGhpcy0+ZXh0cmFjdF9jb21tZW50cyA9ICR0YWc7Cgl9CgoJLyoqCgkgKiBEaXNhYmxlIGNvbW1lbnRzIGV4dHJhY3Rpb24uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkaXNhYmxlQ29tbWVudHNFeHRyYWN0aW9uKCkgewoJCSR0aGlzLT5leHRyYWN0X2NvbW1lbnRzID0gZmFsc2U7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXRkb2N9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzYXZlR2V0dGV4dEZ1bmN0aW9ucyggJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgKSB7CgkJLy8gSWdub3JlIG11bHRpcGxlIHRyYW5zbGF0aW9ucyBmb3Igbm93LgoJCS8vIEB0b2RvIEFkZCBwcm9wZXIgc3VwcG9ydCBmb3IgbXVsdGlwbGUgdHJhbnNsYXRpb25zLgoJCWlmICggaXNfYXJyYXkoICR0cmFuc2xhdGlvbnMgKSApIHsKCQkJJHRyYW5zbGF0aW9ucyA9ICR0cmFuc2xhdGlvbnNbMF07CgkJfQoKCQkkcGVhc3Rfb3B0aW9ucyA9IFsKCQkJJ3NvdXJjZVR5cGUnID0+IFBlYXN0OjpTT1VSQ0VfVFlQRV9NT0RVTEUsCgkJCSdjb21tZW50cycgICA9PiBmYWxzZSAhPT0gJHRoaXMtPmV4dHJhY3RfY29tbWVudHMsCgkJCSdqc3gnICAgICAgICA9PiB0cnVlLAoJCV07CgkJJGFzdCAgICAgICAgICAgPSBQZWFzdDo6bGF0ZXN0KCAkdGhpcy0+Y29kZSwgJHBlYXN0X29wdGlvbnMgKS0+cGFyc2UoKTsKCgkJJHRyYXZlcnNlciA9IG5ldyBUcmF2ZXJzZXIoKTsKCgkJJGFsbF9jb21tZW50cyA9IFtdOwoKCQkvKioKCQkgKiBUcmF2ZXJzZSB0aHJvdWdoIEpTIGNvZGUgdG8gZmluZCBhbmQgZXh0cmFjdCBnZXR0ZXh0IGZ1bmN0aW9ucy4KCQkgKgoJCSAqIE1ha2Ugc3VyZSB0cmFuc2xhdG9yIGNvbW1lbnRzIGluIGZyb250IG9mIHZhcmlhYmxlIGRlY2xhcmF0aW9ucwoJCSAqIGFuZCBpbnNpZGUgbmVzdGVkIGNhbGwgZXhwcmVzc2lvbnMgYXJlIGF2YWlsYWJsZSB3aGVuIHBhcnNpbmcgdGhlIGZ1bmN0aW9uIGNhbGwuCgkJICovCgkJJHRyYXZlcnNlci0+YWRkRnVuY3Rpb24oCgkJCWZ1bmN0aW9uICggJG5vZGUgKSB1c2UgKCAmJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMsICYkYWxsX2NvbW1lbnRzICkgewoJCQkJJGZ1bmN0aW9ucyAgICAgPSAkb3B0aW9uc1snZnVuY3Rpb25zJ107CgkJCQkkZmlsZSAgICAgICAgICA9ICRvcHRpb25zWydmaWxlJ107CgkJCQkkYWRkX3JlZmVyZW5jZSA9ICEgZW1wdHkoICRvcHRpb25zWydhZGRSZWZlcmVuY2VzJ10gKTsKCgkJCQkvKiogQHZhciBOb2RlXE5vZGUgJG5vZGUgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0TGVhZGluZ0NvbW1lbnRzKCkgYXMgJGNvbW1lbnQgKSB7CgkJCQkJJGFsbF9jb21tZW50c1tdID0gJGNvbW1lbnQ7CgkJCQl9CgoJCQkJLyoqIEB2YXIgTm9kZVxDYWxsRXhwcmVzc2lvbiAkbm9kZSAqLwoJCQkJaWYgKCAnQ2FsbEV4cHJlc3Npb24nICE9PSAkbm9kZS0+Z2V0VHlwZSgpICkgewoJCQkJCXJldHVybjsKCQkJCX0KCgkJCQkkY2FsbGVlID0gJHRoaXMtPnJlc29sdmVFeHByZXNzaW9uQ2FsbGVlKCAkbm9kZSApOwoKCQkJCWlmICggISAkY2FsbGVlIHx8ICEgaXNzZXQoICRmdW5jdGlvbnNbICRjYWxsZWVbJ25hbWUnXSBdICkgKSB7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCS8qKiBAdmFyIE5vZGVcQ2FsbEV4cHJlc3Npb24gJG5vZGUgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50ICkgewoJCQkJCS8vIFN1cHBvcnQgbmVzdGVkIGZ1bmN0aW9uIGNhbGxzLgoJCQkJCSRhcmd1bWVudC0+c2V0TGVhZGluZ0NvbW1lbnRzKCAkYXJndW1lbnQtPmdldExlYWRpbmdDb21tZW50cygpICsgJG5vZGUtPmdldExlYWRpbmdDb21tZW50cygpICk7CgkJCQl9CgoJCQkJZm9yZWFjaCAoICRjYWxsZWVbJ2NvbW1lbnRzJ10gYXMgJGNvbW1lbnQgKSB7CgkJCQkJJGFsbF9jb21tZW50c1tdID0gJGNvbW1lbnQ7CgkJCQl9CgoJCQkJJGRvbWFpbiAgID0gbnVsbDsKCQkJCSRvcmlnaW5hbCA9IG51bGw7CgkJCQkkY29udGV4dCAgPSBudWxsOwoJCQkJJHBsdXJhbCAgID0gbnVsbDsKCQkJCSRhcmdzICAgICA9IFtdOwoKCQkJCS8qKiBAdmFyIE5vZGVcTm9kZSAkYXJndW1lbnQgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50ICkgewoJCQkJCWZvcmVhY2ggKCAkYXJndW1lbnQtPmdldExlYWRpbmdDb21tZW50cygpIGFzICRjb21tZW50ICkgewoJCQkJCQkkYWxsX2NvbW1lbnRzW10gPSAkY29tbWVudDsKCQkJCQl9CgoJCQkJCWlmICgKCQkJCQkJJ0lkZW50aWZpZXInID09PSAkYXJndW1lbnQtPmdldFR5cGUoKSB8fAoJCQkJCQknRXhwcmVzc2lvbicgPT09IHN1YnN0ciggJGFyZ3VtZW50LT5nZXRUeXBlKCksIC1zdHJsZW4oICdFeHByZXNzaW9uJyApICkKCQkJCQkpIHsKCQkJCQkJJGFyZ3NbXSA9ICcnOyAvLyBUaGUgdmFsdWUgZG9lc24ndCBtYXR0ZXIgYXMgaXQncyB1bnVzZWQuCgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCgkJCQkJaWYgKCAnTGl0ZXJhbCcgPT09ICRhcmd1bWVudC0+Z2V0VHlwZSgpICkgewoJCQkJCQkvKiogQHZhciBOb2RlXExpdGVyYWwgJGFyZ3VtZW50ICovCgkJCQkJCSRhcmdzW10gPSAkYXJndW1lbnQtPmdldFZhbHVlKCk7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCgkJCQkJaWYgKCAnVGVtcGxhdGVMaXRlcmFsJyA9PT0gJGFyZ3VtZW50LT5nZXRUeXBlKCkgJiYgMCA9PT0gY291bnQoICRhcmd1bWVudC0+Z2V0RXhwcmVzc2lvbnMoKSApICkgewoJCQkJCQkvKiogQHZhciBOb2RlXFRlbXBsYXRlTGl0ZXJhbCAkYXJndW1lbnQgKi8KCQkJCQkJLyoqIEB2YXIgTm9kZVxUZW1wbGF0ZUVsZW1lbnRbXSAkcGFydHMgKi8KCgkJCQkJCS8vIFNpbmNlIHRoZXJlIGFyZSBubyBleHByZXNzaW9ucyB3aXRoaW4gdGhlIFRlbXBsYXRlTGl0ZXJhbCwgdGhlcmUgaXMgb25seSBvbmUgVGVtcGxhdGVFbGVtZW50LgoJCQkJCQkkcGFydHMgID0gJGFyZ3VtZW50LT5nZXRQYXJ0cygpOwoJCQkJCQkkYXJnc1tdID0gJHBhcnRzWzBdLT5nZXRWYWx1ZSgpOwoJCQkJCQljb250aW51ZTsKCQkJCQl9CgoJCQkJCS8vIElmIHdlIHJlYWNoIHRoaXMsIGFuIHVuc3VwcG9ydGVkIGFyZ3VtZW50IHR5cGUgaGFzIGJlZW4gZW5jb3VudGVyZWQuCgkJCQkJLy8gRG8gbm90IHRyeSB0byBwYXJzZSB0aGlzIGZ1bmN0aW9uIGNhbGwgYXQgYWxsLgoJCQkJCXJldHVybjsKCQkJCX0KCgkJCQlzd2l0Y2ggKCAkZnVuY3Rpb25zWyAkY2FsbGVlWyduYW1lJ10gXSApIHsKCQkJCQljYXNlICd0ZXh0X2RvbWFpbic6CgkJCQkJY2FzZSAnZ2V0dGV4dCc6CgkJCQkJCWxpc3QoICRvcmlnaW5hbCwgJGRvbWFpbiApID0gYXJyYXlfcGFkKCAkYXJncywgMiwgbnVsbCApOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAndGV4dF9jb250ZXh0X2RvbWFpbic6CgkJCQkJCWxpc3QoICRvcmlnaW5hbCwgJGNvbnRleHQsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDMsIG51bGwgKTsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2RvbWFpbic6CgkJCQkJCWxpc3QoICRvcmlnaW5hbCwgJHBsdXJhbCwgJG51bWJlciwgJGRvbWFpbiApID0gYXJyYXlfcGFkKCAkYXJncywgNCwgbnVsbCApOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnc2luZ2xlX3BsdXJhbF9udW1iZXJfY29udGV4dF9kb21haW4nOgoJCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRudW1iZXIsICRjb250ZXh0LCAkZG9tYWluICkgPSBhcnJheV9wYWQoICRhcmdzLCA1LCBudWxsICk7CgkJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWlmICggJycgPT09IChzdHJpbmcpICRvcmlnaW5hbCApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJaWYgKCAkZG9tYWluICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSAmJiBudWxsICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJaWYgKCBpc3NldCggJG9wdGlvbnNbJ2xpbmUnXSApICkgewoJCQkJCSRsaW5lID0gJG9wdGlvbnNbJ2xpbmUnXTsKCQkJCX0gZWxzZSB7CgkJCQkJJGxpbmUgPSAkbm9kZS0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKS0+Z2V0TGluZSgpOwoJCQkJfQoKCQkJCSR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCggJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCApOwoJCQkJaWYgKCAkYWRkX3JlZmVyZW5jZSApIHsKCQkJCQkkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSggJGZpbGUsICRsaW5lICk7CgkJCQl9CgoJCQkJLyoqIEB2YXIgTm9kZVxDb21tZW50ICRjb21tZW50ICovCgkJCQlmb3JlYWNoICggJGFsbF9jb21tZW50cyBhcyAkY29tbWVudCApIHsKCQkJCQkvLyBDb21tZW50cyBzaG91bGQgYmUgYmVmb3JlIHRoZSB0cmFuc2xhdGlvbi4KCQkJCQlpZiAoICEgJHRoaXMtPmNvbW1lbnRQcmVjZWRlc05vZGUoICRjb21tZW50LCAkbm9kZSApICkgewoJCQkJCQljb250aW51ZTsKCQkJCQl9CgoJCQkJCWlmICggaW5fYXJyYXkoICRjb21tZW50LCAkdGhpcy0+Y29tbWVudHNfY2FjaGUsIHRydWUgKSApIHsKCQkJCQkJY29udGludWU7CgkJCQkJfQoKCQkJCQkkcGFyc2VkX2NvbW1lbnQgPSBQYXJzZWRDb21tZW50OjpjcmVhdGUoICRjb21tZW50LT5nZXRSYXdUZXh0KCksICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRMaW5lKCkgKTsKCQkJCQkkcHJlZml4ZXMgICAgICAgPSBhcnJheV9maWx0ZXIoIChhcnJheSkgJHRoaXMtPmV4dHJhY3RfY29tbWVudHMgKTsKCgkJCQkJaWYgKCAkcGFyc2VkX2NvbW1lbnQtPmNoZWNrUHJlZml4ZXMoICRwcmVmaXhlcyApICkgewoJCQkJCQkkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoICRwYXJzZWRfY29tbWVudC0+Z2V0Q29tbWVudCgpICk7CgoJCQkJCQkkdGhpcy0+Y29tbWVudHNfY2FjaGVbXSA9ICRjb21tZW50OwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoIGlzc2V0KCAkcGFyc2VkX2NvbW1lbnQgKSApIHsKCQkJCQkkYWxsX2NvbW1lbnRzID0gW107CgkJCQl9CgkJCX0KCQkpOwoKCQkvKioKCQkgKiBUcmF2ZXJzZSB0aHJvdWdoIEpTIGNvZGUgY29udGFpbmVkIHdpdGhpbiBldmFsKCkgdG8gZmluZCBhbmQgZXh0cmFjdCBnZXR0ZXh0IGZ1bmN0aW9ucy4KCQkgKi8KCQkkc2Nhbm5lciA9ICR0aGlzOwoJCSR0cmF2ZXJzZXItPmFkZEZ1bmN0aW9uKAoJCQlmdW5jdGlvbiAoICRub2RlICkgdXNlICggJiR0cmFuc2xhdGlvbnMsICRvcHRpb25zLCAkc2Nhbm5lciApIHsKCQkJCS8qKiBAdmFyIE5vZGVcQ2FsbEV4cHJlc3Npb24gJG5vZGUgKi8KCQkJCWlmICggJ0NhbGxFeHByZXNzaW9uJyAhPT0gJG5vZGUtPmdldFR5cGUoKSApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJJGNhbGxlZSA9ICR0aGlzLT5yZXNvbHZlRXhwcmVzc2lvbkNhbGxlZSggJG5vZGUgKTsKCgkJCQlpZiAoICEgJGNhbGxlZSB8fCAnZXZhbCcgIT09ICRjYWxsZWVbJ25hbWUnXSApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJJGV2YWxfY29udGVudHMgPSAnJzsKCQkJCS8qKiBAdmFyIE5vZGVcTm9kZSAkYXJndW1lbnQgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50ICkgewoJCQkJCWlmICggJ0xpdGVyYWwnID09PSAkYXJndW1lbnQtPmdldFR5cGUoKSApIHsKCQkJCQkJLyoqIEB2YXIgTm9kZVxMaXRlcmFsICRhcmd1bWVudCAqLwoJCQkJCQkkZXZhbF9jb250ZW50cyA9ICRhcmd1bWVudC0+Z2V0VmFsdWUoKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoKCQkJCWlmICggISAkZXZhbF9jb250ZW50cyApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJLy8gT3ZlcnJpZGUgdGhlIGxpbmUgbG9jYXRpb24gdG8gYmUgdGhhdCBvZiB0aGUgZXZhbCgpLgoJCQkJJG9wdGlvbnNbJ2xpbmUnXSA9ICRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRMaW5lKCk7CgoJCQkJJGNsYXNzID0gZ2V0X2NsYXNzKCAkc2Nhbm5lciApOwoJCQkJJGV2YWxzID0gbmV3ICRjbGFzcyggJGV2YWxfY29udGVudHMgKTsKCQkJCSRldmFscy0+ZW5hYmxlQ29tbWVudHNFeHRyYWN0aW9uKCAkb3B0aW9uc1snZXh0cmFjdENvbW1lbnRzJ10gKTsKCQkJCSRldmFscy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoICR0cmFuc2xhdGlvbnMsICRvcHRpb25zICk7CgkJCX0KCQkpOwoKCQkkdHJhdmVyc2VyLT50cmF2ZXJzZSggJGFzdCApOwoJfQoKCS8qKgoJICogUmVzb2x2ZSB0aGUgY2FsbGVlIG9mIGEgY2FsbCBleHByZXNzaW9uIHVzaW5nIGtub3duIGZvcm1hdHMuCgkgKgoJICogQHBhcmFtIE5vZGVcQ2FsbEV4cHJlc3Npb24gJG5vZGUgVGhlIGNhbGwgZXhwcmVzc2lvbiB3aG9zZSBjYWxsZWUgdG8gcmVzb2x2ZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5fGJvb2wgQXJyYXkgY29udGFpbmluZyB0aGUgbmFtZSBhbmQgY29tbWVudHMgb2YgdGhlIGlkZW50aWZpZXIgaWYgcmVzb2x2ZWQuIEZhbHNlIGlmIG5vdC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiByZXNvbHZlRXhwcmVzc2lvbkNhbGxlZSggTm9kZVxDYWxsRXhwcmVzc2lvbiAkbm9kZSApIHsKCQkkY2FsbGVlID0gJG5vZGUtPmdldENhbGxlZSgpOwoKCQkvLyBJZiB0aGUgY2FsbGVlIGlzIGEgc2ltcGxlIGlkZW50aWZpZXIgaXQgY2FuIHNpbXBseSBiZSByZXR1cm5lZC4KCQkvLyBGb3IgZXhhbXBsZTogX18oICJ0cmFuc2xhdGlvbiIgKS4KCQlpZiAoICdJZGVudGlmaWVyJyA9PT0gJGNhbGxlZS0+Z2V0VHlwZSgpICkgewoJCQlyZXR1cm4gWwoJCQkJJ25hbWUnICAgICA9PiAkY2FsbGVlLT5nZXROYW1lKCksCgkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldExlYWRpbmdDb21tZW50cygpLAoJCQldOwoJCX0KCgkJLy8gSWYgdGhlIGNhbGxlZSBpcyBhIG1lbWJlciBleHByZXNzaW9uIHJlc29sdmUgaXQgdG8gdGhlIHByb3BlcnR5LgoJCS8vIEZvciBleGFtcGxlOiB3cC5pMThuLl9fKCAidHJhbnNsYXRpb24iICkgb3IgdS5fXyggInRyYW5zbGF0aW9uIiApLgoJCWlmICgKCQkJJ01lbWJlckV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRUeXBlKCkgJiYKCQkJJ0lkZW50aWZpZXInID09PSAkY2FsbGVlLT5nZXRQcm9wZXJ0eSgpLT5nZXRUeXBlKCkKCQkpIHsKCQkJLy8gTWFrZSBzdXJlIHRvIHVucGFjayB3cC5pMThuIHdoaWNoIGlzIGEgbmVzdGVkIE1lbWJlckV4cHJlc3Npb24uCgkJCSRjb21tZW50cyA9ICdNZW1iZXJFeHByZXNzaW9uJyA9PT0gJGNhbGxlZS0+Z2V0T2JqZWN0KCktPmdldFR5cGUoKQoJCQkJPyAkY2FsbGVlLT5nZXRPYmplY3QoKS0+Z2V0T2JqZWN0KCktPmdldExlYWRpbmdDb21tZW50cygpCgkJCQk6ICRjYWxsZWUtPmdldE9iamVjdCgpLT5nZXRMZWFkaW5nQ29tbWVudHMoKTsKCgkJCXJldHVybiBbCgkJCQknbmFtZScgICAgID0+ICRjYWxsZWUtPmdldFByb3BlcnR5KCktPmdldE5hbWUoKSwKCQkJCSdjb21tZW50cycgPT4gJGNvbW1lbnRzLAoJCQldOwoJCX0KCgkJLy8gSWYgdGhlIGNhbGxlZSBpcyBhIGNhbGwgZXhwcmVzc2lvbiBhcyBjcmVhdGVkIGJ5IFdlYnBhY2sgcmVzb2x2ZSBpdC4KCQkvLyBGb3IgZXhhbXBsZTogT2JqZWN0KHUuX18pKCAidHJhbnNsYXRpb24iICkuCgkJaWYgKAoJCQknQ2FsbEV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRUeXBlKCkgJiYKCQkJJ0lkZW50aWZpZXInID09PSAkY2FsbGVlLT5nZXRDYWxsZWUoKS0+Z2V0VHlwZSgpICYmCgkJCSdPYmplY3QnID09PSAkY2FsbGVlLT5nZXRDYWxsZWUoKS0+Z2V0TmFtZSgpICYmCgkJCVtdICE9PSAkY2FsbGVlLT5nZXRBcmd1bWVudHMoKSAmJgoJCQknTWVtYmVyRXhwcmVzc2lvbicgPT09ICRjYWxsZWUtPmdldEFyZ3VtZW50cygpWzBdLT5nZXRUeXBlKCkKCQkpIHsKCQkJJHByb3BlcnR5ID0gJGNhbGxlZS0+Z2V0QXJndW1lbnRzKClbMF0tPmdldFByb3BlcnR5KCk7CgoJCQkvLyBNYXRjaGVzIG1pbmlmaWVkIHdlYnBhY2sgc3RhdGVtZW50czogT2JqZWN0KHUuX18pKCAidHJhbnNsYXRpb24iICkuCgkJCWlmICggJ0lkZW50aWZpZXInID09PSAkcHJvcGVydHktPmdldFR5cGUoKSApIHsKCQkJCXJldHVybiBbCgkJCQkJJ25hbWUnICAgICA9PiAkcHJvcGVydHktPmdldE5hbWUoKSwKCQkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldENhbGxlZSgpLT5nZXRMZWFkaW5nQ29tbWVudHMoKSwKCQkJCV07CgkJCX0KCgkJCS8vIE1hdGNoZXMgdW5taW5pZmllZCB3ZWJwYWNrIHN0YXRlbWVudHM6CgkJCS8vIE9iamVjdChfd29yZHByZXNzX2kxOG5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzdfX1siX18iXSkoICJ0cmFuc2xhdGlvbiIgKTsKCQkJaWYgKCAnTGl0ZXJhbCcgPT09ICRwcm9wZXJ0eS0+Z2V0VHlwZSgpICkgewoJCQkJJG5hbWUgPSAkcHJvcGVydHktPmdldFZhbHVlKCk7CgoJCQkJLy8gTWF0Y2hlcyBtYW5nbGVkIHdlYnBhY2sgc3RhdGVtZW50OgoJCQkJLy8gT2JqZWN0KF93b3JkcHJlc3NfaTE4bl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfN19fWy8qIF9fICovICJhIl0pKCAidHJhbnNsYXRpb24iICk7CgkJCQkkbGVhZGluZ19wcm9wZXJ0eV9jb21tZW50cyA9ICRwcm9wZXJ0eS0+Z2V0TGVhZGluZ0NvbW1lbnRzKCk7CgkJCQlpZiAoIGNvdW50KCAkbGVhZGluZ19wcm9wZXJ0eV9jb21tZW50cyApID09PSAxICYmICRsZWFkaW5nX3Byb3BlcnR5X2NvbW1lbnRzWzBdLT5nZXRLaW5kKCkgPT09ICdtdWx0aWxpbmUnICkgewoJCQkJCSRuYW1lID0gdHJpbSggJGxlYWRpbmdfcHJvcGVydHlfY29tbWVudHNbMF0tPmdldFRleHQoKSApOwoJCQkJfQoKCQkJCXJldHVybiBbCgkJCQkJJ25hbWUnICAgICA9PiAkbmFtZSwKCQkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldENhbGxlZSgpLT5nZXRMZWFkaW5nQ29tbWVudHMoKSwKCQkJCV07CgkJCX0KCQl9CgoJCS8vIElmIHRoZSBjYWxsZWUgaXMgYW4gaW5kaXJlY3QgZnVuY3Rpb24gY2FsbCBhcyBjcmVhdGVkIGJ5IGJhYmVsLCByZXNvbHZlIGl0LgoJCS8vIEZvciBleGFtcGxlOiBgKDAsIHUuX18pKCAidHJhbnNsYXRpb24iIClgLgoJCWlmICgKCQkJJ1BhcmVudGhlc2l6ZWRFeHByZXNzaW9uJyA9PT0gJGNhbGxlZS0+Z2V0VHlwZSgpCgkJCSYmICdTZXF1ZW5jZUV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldFR5cGUoKQoJCQkmJiAyID09PSBjb3VudCggJGNhbGxlZS0+Z2V0RXhwcmVzc2lvbigpLT5nZXRFeHByZXNzaW9ucygpICkKCQkJJiYgJ0xpdGVyYWwnID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMF0tPmdldFR5cGUoKQoJCQkmJiBbXSAhPT0gJG5vZGUtPmdldEFyZ3VtZW50cygpCgkJKSB7CgkJCS8vIE1hdGNoZXMgYW55IGdlbmVyYWwgaW5kaXJlY3QgZnVuY3Rpb24gY2FsbDogYCgwLCBfXykoICJ0cmFuc2xhdGlvbiIgKWAuCgkJCWlmICggJ0lkZW50aWZpZXInID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMV0tPmdldFR5cGUoKSApIHsKCQkJCXJldHVybiBbCgkJCQkJJ25hbWUnICAgICA9PiAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMV0tPmdldE5hbWUoKSwKCQkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldExlYWRpbmdDb21tZW50cygpLAoJCQkJXTsKCQkJfQoKCQkJLy8gTWF0Y2hlcyBpbmRpcmVjdCBmdW5jdGlvbiBjYWxscyB1c2VkIGJ5IGJhYmVsIGZvciBtb2R1bGUgaW1wb3J0czogYCgwLCBfaTE4bi5fXykoICJ0cmFuc2xhdGlvbiIgKWAuCgkJCWlmICggJ01lbWJlckV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMV0tPmdldFR5cGUoKSApIHsKCQkJCSRwcm9wZXJ0eSA9ICRjYWxsZWUtPmdldEV4cHJlc3Npb24oKS0+Z2V0RXhwcmVzc2lvbnMoKVsxXS0+Z2V0UHJvcGVydHkoKTsKCgkJCQlpZiAoICdJZGVudGlmaWVyJyA9PT0gJHByb3BlcnR5LT5nZXRUeXBlKCkgKSB7CgkJCQkJcmV0dXJuIFsKCQkJCQkJJ25hbWUnICAgICA9PiAkcHJvcGVydHktPmdldE5hbWUoKSwKCQkJCQkJJ2NvbW1lbnRzJyA9PiAkY2FsbGVlLT5nZXRMZWFkaW5nQ29tbWVudHMoKSwKCQkJCQldOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBVbmtub3duIGZvcm1hdC4KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHdldGhlciBvciBub3QgYSBjb21tZW50IHByZWNlZGVzIGEgbm9kZS4KCSAqIFRoZSBjb21tZW50IG11c3QgYmUgYmVmb3JlIHRoZSBub2RlIGFuZCBvbiB0aGUgc2FtZSBsaW5lIG9yIHRoZSBvbmUgYmVmb3JlLgoJICoKCSAqIEBwYXJhbSBOb2RlXENvbW1lbnQgJGNvbW1lbnQgVGhlIGNvbW1lbnQuCgkgKiBAcGFyYW0gTm9kZVxOb2RlICAgICRub2RlICAgIFRoZSBub2RlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIG9yIG5vdCB0aGUgY29tbWVudCBwcmVjZWRlcyB0aGUgbm9kZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjb21tZW50UHJlY2VkZXNOb2RlKCBOb2RlXENvbW1lbnQgJGNvbW1lbnQsIE5vZGVcTm9kZSAkbm9kZSApIHsKCQkvLyBDb21tZW50cyBzaG91bGQgYmUgb24gdGhlIHNhbWUgb3IgYW4gZWFybGllciBsaW5lIHRoYW4gdGhlIHRyYW5zbGF0aW9uLgoJCWlmICggJG5vZGUtPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCktPmdldExpbmUoKSAtICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKS0+Z2V0TGluZSgpID4gMSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gQ29tbWVudHMgb24gdGhlIHNhbWUgbGluZSBzaG91bGQgYmUgYmVmb3JlIHRoZSB0cmFuc2xhdGlvbi4KCQlpZiAoCgkJCSRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRMaW5lKCkgPT09ICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKS0+Z2V0TGluZSgpICYmCgkJCSRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRDb2x1bW4oKSA8ICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRDb2x1bW4oKQoJCSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xKc0NvZGU7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFBlYXN0XFN5bnRheFxFeGNlcHRpb24gYXMgUGVhc3RFeGNlcHRpb247CnVzZSBXUF9DTEk7CgpmaW5hbCBjbGFzcyBKc0NvZGVFeHRyYWN0b3IgZXh0ZW5kcyBKc0NvZGUgewoJdXNlIEl0ZXJhYmxlQ29kZUV4dHJhY3RvcjsKCglwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwoJCSdleHRyYWN0Q29tbWVudHMnID0+IFsgJ3RyYW5zbGF0b3JzJywgJ1RyYW5zbGF0b3JzJyBdLAoJCSdjb25zdGFudHMnICAgICAgID0+IFtdLAoJCSdmdW5jdGlvbnMnICAgICAgID0+IFsKCQkJJ19fJyAgPT4gJ3RleHRfZG9tYWluJywKCQkJJ194JyAgPT4gJ3RleHRfY29udGV4dF9kb21haW4nLAoJCQknX24nICA9PiAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJywKCQkJJ19ueCcgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2NvbnRleHRfZG9tYWluJywKCQldLAoJXTsKCglwcm90ZWN0ZWQgc3RhdGljICRmdW5jdGlvbnNTY2FubmVyQ2xhc3MgPSAnV1BfQ0xJXEkxOG5cSnNGdW5jdGlvbnNTY2FubmVyJzsKCgkvKioKCSAqIEBpbmhlcml0ZG9jCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZyggJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJV1BfQ0xJOjpkZWJ1ZyggIlBhcnNpbmcgZmlsZSB7JG9wdGlvbnNbJ2ZpbGUnXX0iLCAnbWFrZS1wb3QnICk7CgoJCXRyeSB7CgkJCXN0YXRpYzo6ZnJvbVN0cmluZ011bHRpcGxlKCAkc3RyaW5nLCBbICR0cmFuc2xhdGlvbnMgXSwgJG9wdGlvbnMgKTsKCQl9IGNhdGNoICggUGVhc3RFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCXNwcmludGYoCgkJCQkJJ0NvdWxkIG5vdCBwYXJzZSBmaWxlICUxJHM6ICUyJHMgKGxpbmUgJTMkZCwgY29sdW1uICU0JGQpJywKCQkJCQkkb3B0aW9uc1snZmlsZSddLAoJCQkJCSRleGNlcHRpb24tPmdldE1lc3NhZ2UoKSwKCQkJCQkkZXhjZXB0aW9uLT5nZXRQb3NpdGlvbigpLT5nZXRMaW5lKCksCgkJCQkJJGV4Y2VwdGlvbi0+Z2V0UG9zaXRpb24oKS0+Z2V0Q29sdW1uKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknQ291bGQgbm90IHBhcnNlIGZpbGUgJTEkczogJTIkcycsCgkJCQkJJG9wdGlvbnNbJ2ZpbGUnXSwKCQkJCQkkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfQoJfQoKCS8qKgoJICogQGluaGVyaXREb2MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoICRzdHJpbmcsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCgkJLyoqIEB2YXIgSnNGdW5jdGlvbnNTY2FubmVyICRmdW5jdGlvbnMgKi8KCQkkZnVuY3Rpb25zID0gbmV3IHN0YXRpYzo6JGZ1bmN0aW9uc1NjYW5uZXJDbGFzcyggJHN0cmluZyApOwoJCSRmdW5jdGlvbnMtPmVuYWJsZUNvbW1lbnRzRXh0cmFjdGlvbiggJG9wdGlvbnNbJ2V4dHJhY3RDb21tZW50cyddICk7CgkJJGZ1bmN0aW9ucy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoICR0cmFuc2xhdGlvbnMsICRvcHRpb25zICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlIGFzIEJhc2VDb21tYW5kTmFtZXNwYWNlOwoKLyoqCiAqIFByb3ZpZGVzIGludGVybmF0aW9uYWxpemF0aW9uIHRvb2xzIGZvciBXb3JkUHJlc3MgcHJvamVjdHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIFBPVCBmaWxlIGZvciB0aGUgV29yZFByZXNzIHBsdWdpbi90aGVtZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkKICogICAgICQgd3AgaTE4biBtYWtlLXBvdCAuIGxhbmd1YWdlcy9teS1wbHVnaW4ucG90CiAqCiAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCiAqLwpjbGFzcyBDb21tYW5kTmFtZXNwYWNlIGV4dGVuZHMgQmFzZUNvbW1hbmROYW1lc3BhY2Ugewp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxVdGlsc1xQaHBGdW5jdGlvbnNTY2FubmVyIGFzIEdldHRleHRQaHBGdW5jdGlvbnNTY2FubmVyOwoKY2xhc3MgUGhwRnVuY3Rpb25zU2Nhbm5lciBleHRlbmRzIEdldHRleHRQaHBGdW5jdGlvbnNTY2FubmVyIHsKCgkvKioKCSAqIHtAaW5oZXJpdGRvY30KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNhdmVHZXR0ZXh0RnVuY3Rpb25zKCAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyApIHsKCQkvLyBJZ25vcmUgbXVsdGlwbGUgdHJhbnNsYXRpb25zIGZvciBub3cuCgkJLy8gQHRvZG8gQWRkIHByb3BlciBzdXBwb3J0IGZvciBtdWx0aXBsZSB0cmFuc2xhdGlvbnMuCgkJaWYgKCBpc19hcnJheSggJHRyYW5zbGF0aW9ucyApICkgewoJCQkkdHJhbnNsYXRpb25zID0gJHRyYW5zbGF0aW9uc1swXTsKCQl9CgoJCSRmdW5jdGlvbnMgICAgID0gJG9wdGlvbnNbJ2Z1bmN0aW9ucyddOwoJCSRmaWxlICAgICAgICAgID0gJG9wdGlvbnNbJ2ZpbGUnXTsKCQkkYWRkX3JlZmVyZW5jZSA9ICEgZW1wdHkoICRvcHRpb25zWydhZGRSZWZlcmVuY2VzJ10gKTsKCgkJZm9yZWFjaCAoICR0aGlzLT5nZXRGdW5jdGlvbnMoICRvcHRpb25zWydjb25zdGFudHMnXSApIGFzICRmdW5jdGlvbiApIHsKCQkJbGlzdCggJG5hbWUsICRsaW5lLCAkYXJncyApID0gJGZ1bmN0aW9uOwoKCQkJaWYgKCAhIGlzc2V0KCAkZnVuY3Rpb25zWyAkbmFtZSBdICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJG9yaWdpbmFsID0gbnVsbDsKCQkJJGRvbWFpbiAgID0gbnVsbDsKCQkJJGNvbnRleHQgID0gbnVsbDsKCQkJJHBsdXJhbCAgID0gbnVsbDsKCgkJCXN3aXRjaCAoICRmdW5jdGlvbnNbICRuYW1lIF0gKSB7CgkJCQljYXNlICd0ZXh0X2RvbWFpbic6CgkJCQljYXNlICdnZXR0ZXh0JzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDIsIG51bGwgKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICd0ZXh0X2NvbnRleHRfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRjb250ZXh0LCAkZG9tYWluICkgPSBhcnJheV9wYWQoICRhcmdzLCAzLCBudWxsICk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRudW1iZXIsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDQsIG51bGwgKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICdzaW5nbGVfcGx1cmFsX251bWJlcl9jb250ZXh0X2RvbWFpbic6CgkJCQkJbGlzdCggJG9yaWdpbmFsLCAkcGx1cmFsLCAkbnVtYmVyLCAkY29udGV4dCwgJGRvbWFpbiApID0gYXJyYXlfcGFkKCAkYXJncywgNSwgbnVsbCApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgJ3NpbmdsZV9wbHVyYWxfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDMsIG51bGwgKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICdzaW5nbGVfcGx1cmFsX2NvbnRleHRfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRjb250ZXh0LCAkZG9tYWluICkgPSBhcnJheV9wYWQoICRhcmdzLCA0LCBudWxsICk7CgkJCQkJYnJlYWs7CgoJCQkJZGVmYXVsdDoKCQkJCQkvLyBTaG91bGQgbmV2ZXIgaGFwcGVuLgoJCQkJCVxXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW50ZXJuYWwgZXJyb3I6IHVua25vd24gZnVuY3Rpb24gbWFwICclcycgZm9yICclcycuIiwgJGZ1bmN0aW9uc1sgJG5hbWUgXSwgJG5hbWUgKSApOwoJCQl9CgoJCQlpZiAoICcnID09PSAoc3RyaW5nKSAkb3JpZ2luYWwgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAkZG9tYWluICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSAmJiBudWxsICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb25zLT5pbnNlcnQoICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwgKTsKCQkJaWYgKCAkYWRkX3JlZmVyZW5jZSApIHsKCQkJCSR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCAkZmlsZSwgJGxpbmUgKTsKCQkJfQoKCQkJaWYgKCBpc3NldCggJGZ1bmN0aW9uWzNdICkgKSB7CgkJCQlmb3JlYWNoICggJGZ1bmN0aW9uWzNdIGFzICRleHRyYWN0ZWRfY29tbWVudCApIHsKCQkJCQkkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoICRleHRyYWN0ZWRfY29tbWVudCApOwoJCQkJfQoJCQl9CgkJfQoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxFeHRyYWN0b3JzXEV4dHJhY3RvcjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xFeHRyYWN0b3JJbnRlcmZhY2U7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxVdGlsczsKCmZpbmFsIGNsYXNzIFRoZW1lSnNvbkV4dHJhY3RvciBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZSB7Cgl1c2UgSXRlcmFibGVDb2RlRXh0cmFjdG9yOwoKCS8qKgoJICogU291cmNlIFVSTCBmcm9tIHdoaWNoIHRvIGRvd25sb2FkIHRoZSBsYXRlc3QgdGhlbWUtaTE4bi5qc29uIGZpbGUuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgVEhFTUVfSlNPTl9TT1VSQ0UgPSAnaHR0cHM6Ly9kZXZlbG9wLnN2bi53b3JkcHJlc3Mub3JnL3RydW5rL3NyYy93cC1pbmNsdWRlcy90aGVtZS1pMThuLmpzb24nOwoKCS8qKgoJICogQGluaGVyaXRkb2MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCAkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSApIHsKCQkkZmlsZSA9ICRvcHRpb25zWydmaWxlJ107CgkJV1BfQ0xJOjpkZWJ1ZyggIlBhcnNpbmcgZmlsZSB7JGZpbGV9IiwgJ21ha2UtcG90JyApOwoKCQkkdGhlbWVfanNvbiA9IGpzb25fZGVjb2RlKCAkc3RyaW5nLCB0cnVlICk7CgoJCWlmICggbnVsbCA9PT0gJHRoZW1lX2pzb24gKSB7CgkJCVdQX0NMSTo6ZGVidWcoCgkJCQlzcHJpbnRmKAoJCQkJCSdDb3VsZCBub3QgcGFyc2UgZmlsZSAlMSRzOiBlcnJvciBjb2RlICUyJHMnLAoJCQkJCSRmaWxlLAoJCQkJCWpzb25fbGFzdF9lcnJvcigpCgkJCQkpLAoJCQkJJ21ha2UtcG90JwoJCQkpOwoKCQkJcmV0dXJuOwoJCX0KCgkJJGZpZWxkcyA9IHNlbGY6OmdldF9maWVsZHNfdG9fdHJhbnNsYXRlKCk7CgkJZm9yZWFjaCAoICRmaWVsZHMgYXMgJGZpZWxkICkgewoJCQkkcGF0aCAgICA9ICRmaWVsZFsncGF0aCddOwoJCQkka2V5ICAgICA9ICRmaWVsZFsna2V5J107CgkJCSRjb250ZXh0ID0gJGZpZWxkWydjb250ZXh0J107CgoJCQkvKgoJCQkgKiBXZSBuZWVkIHRvIHByb2Nlc3MgdGhlIHBhdGhzIHRoYXQgaW5jbHVkZSAnKicgc2VwYXJhdGVseS4KCQkJICogT25lIGV4YW1wbGUgb2Ygc3VjaCBhIHBhdGggd291bGQgYmU6CgkJCSAqIFsgJ3NldHRpbmdzJywgJ2Jsb2NrcycsICcqJywgJ2NvbG9yJywgJ3BhbGV0dGUnIF0KCQkJICovCgkJCSRub2Rlc190b19pdGVyYXRlID0gYXJyYXlfa2V5cyggJHBhdGgsICcqJywgdHJ1ZSApOwoJCQlpZiAoICEgZW1wdHkoICRub2Rlc190b19pdGVyYXRlICkgKSB7CgkJCQkvKgoJCQkJICogQXQgdGhlIG1vbWVudCwgd2Ugb25seSBuZWVkIHRvIHN1cHBvcnQgb25lICcqJyBpbiB0aGUgcGF0aCwgc28gdGFrZSBpdCBkaXJlY3RseS4KCQkJCSAqIC0gYmFzZSB3aWxsIGJlIFsgJ3NldHRpbmdzJywgJ2Jsb2NrcycgXQoJCQkJICogLSBkYXRhIHdpbGwgYmUgWyAnY29sb3InLCAncGFsZXR0ZScgXQoJCQkJICovCgkJCQkkYmFzZV9wYXRoID0gYXJyYXlfc2xpY2UoICRwYXRoLCAwLCAkbm9kZXNfdG9faXRlcmF0ZVswXSApOwoJCQkJJGRhdGFfcGF0aCA9IGFycmF5X3NsaWNlKCAkcGF0aCwgJG5vZGVzX3RvX2l0ZXJhdGVbMF0gKyAxICk7CgkJCQkkYmFzZV90cmVlID0gc2VsZjo6YXJyYXlfZ2V0KCAkdGhlbWVfanNvbiwgJGJhc2VfcGF0aCwgW10gKTsKCQkJCWZvcmVhY2ggKCAkYmFzZV90cmVlIGFzICRub2RlX2RhdGEgKSB7CgkJCQkJJGFycmF5X3RvX3RyYW5zbGF0ZSA9IHNlbGY6OmFycmF5X2dldCggJG5vZGVfZGF0YSwgJGRhdGFfcGF0aCApOwoJCQkJCWlmICggbnVsbCA9PT0gJGFycmF5X3RvX3RyYW5zbGF0ZSApIHsKCQkJCQkJY29udGludWU7CgkJCQkJfQoKCQkJCQlmb3JlYWNoICggJGFycmF5X3RvX3RyYW5zbGF0ZSBhcyAkaXRlbV90b190cmFuc2xhdGUgKSB7CgkJCQkJCWlmICggZW1wdHkoICRpdGVtX3RvX3RyYW5zbGF0ZVsgJGtleSBdICkgKSB7CgkJCQkJCQljb250aW51ZTsKCQkJCQkJfQoKCQkJCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCAkY29udGV4dCwgJGl0ZW1fdG9fdHJhbnNsYXRlWyAka2V5IF0gKTsKCQkJCQkJJHRyYW5zbGF0aW9uLT5hZGRSZWZlcmVuY2UoICRmaWxlICk7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJGFycmF5X3RvX3RyYW5zbGF0ZSA9IHNlbGY6OmFycmF5X2dldCggJHRoZW1lX2pzb24sICRwYXRoICk7CgkJCQlpZiAoIG51bGwgPT09ICRhcnJheV90b190cmFuc2xhdGUgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJZm9yZWFjaCAoICRhcnJheV90b190cmFuc2xhdGUgYXMgJGl0ZW1fdG9fdHJhbnNsYXRlICkgewoJCQkJCWlmICggZW1wdHkoICRpdGVtX3RvX3RyYW5zbGF0ZVsgJGtleSBdICkgKSB7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCgkJCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCAkY29udGV4dCwgJGl0ZW1fdG9fdHJhbnNsYXRlWyAka2V5IF0gKTsKCQkJCQkkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSggJGZpbGUgKTsKCQkJCX0KCQkJfQoJCX0KCX0KCgkvKioKCSAqIEdpdmVuIGEgcmVtb3RlIFVSTCwgZmV0Y2hlcyBpdCByZW1vdGVseSBhbmQgcmV0dXJucyBpdHMgY29udGVudC4KCSAqCgkgKiBSZXR1cm5zIGFuIGVtcHR5IHN0cmluZyBpbiBjYXNlIG9mIGVycm9yLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgb2YgdGhlIGZpbGUgdG8gZmV0Y2guCgkgKgoJICogQHJldHVybiBzdHJpbmcgQ29udGVudHMgb2YgdGhlIGZpbGUuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHJlbW90ZV9nZXQoICR1cmwgKSB7CgkJaWYgKCAhICR1cmwgKSB7CgkJCXJldHVybiAnJzsKCQl9CgoJCSRoZWFkZXJzICA9IFsgJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vanNvbicgXTsKCQkkb3B0aW9ucyAgPSBbICdoYWx0X29uX2Vycm9yJyA9PiBmYWxzZSBdOwoJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICR1cmwsIG51bGwsICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQlpZiAoCgkJCSEgJHJlc3BvbnNlLT5zdWNjZXNzCgkJCXx8IDIwMCA+IChpbnQpICRyZXNwb25zZS0+c3RhdHVzX2NvZGUKCQkJfHwgMzAwIDw9ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUKCQkpIHsKCQkJV1BfQ0xJOjpkZWJ1ZyggIkZhaWxlZCB0byBkb3dubG9hZCBmcm9tIFVSTCB7JHVybH0iLCAnbWFrZS1wb3QnICk7CgkJCXJldHVybiAnJzsKCQl9CgoJCXJldHVybiB0cmltKCAkcmVzcG9uc2UtPmJvZHkgKTsKCX0KCgkvKioKCSAqIFJldHVybnMgYSBkYXRhIHN0cnVjdHVyZSB0byBoZWxwIHNldHRpbmcgdXAgdHJhbnNsYXRpb25zIGZvciB0aGVtZS5qc29uIGRhdGEuCgkgKgoJICogWwoJICogICAgIFsKCSAqICAgICAgICAgJ3BhdGgnICAgID0+IFsgJ3NldHRpbmdzJywgJ2NvbG9yJywgJ3BhbGV0dGUnIF0sCgkgKiAgICAgICAgICdrZXknICAgICA9PiAna2V5LXRoYXQtc3RvcmVzLXRoZS1zdHJpbmctdG8tdHJhbnNsYXRlJywKCSAqICAgICAgICAgJ2NvbnRleHQnID0+ICd0cmFuc2xhdGlvbi1jb250ZXh0JywKCSAqICAgICBdLAoJICogICAgIFsKCSAqICAgICAgICAgJ3BhdGgnICAgID0+ICdldGMnLAoJICogICAgICAgICAna2V5JyAgICAgPT4gJ2V0YycsCgkgKiAgICAgICAgICdjb250ZXh0JyA9PiAnZXRjJywKCSAqICAgICBdLAoJICogXQoJICoKCSAqIFBvcnRlZCBmcm9tIHRoZSBjb3JlIGNsYXNzIGBXUF9UaGVtZV9KU09OX1Jlc29sdmVyYC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFuIGFycmF5IG9mIHRoZW1lLmpzb24gZmllbGRzIHRoYXQgYXJlIHRyYW5zbGF0YWJsZSBhbmQgdGhlIGtleXMgdGhhdCBhcmUgdHJhbnNsYXRhYmxlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfZmllbGRzX3RvX3RyYW5zbGF0ZSgpIHsKCQkkanNvbiA9IHNlbGY6OnJlbW90ZV9nZXQoIHNlbGY6OlRIRU1FX0pTT05fU09VUkNFICk7CgoJCWlmICggZW1wdHkoICRqc29uICkgKSB7CgkJCVdQX0NMSTo6ZGVidWcoICdSZW1vdGUgZmlsZSBjb3VsZCBub3QgYmUgYWNjZXNzZWQsIHdpbGwgdXNlIGxvY2FsIGZpbGUgYXMgZmFsbGJhY2snLCAnbWFrZS1wb3QnICk7CgkJCSRqc29uID0gZmlsZV9nZXRfY29udGVudHMoIF9fRElSX18gLiAnLy4uL2Fzc2V0cy90aGVtZS1pMThuLmpzb24nICk7CgkJfQoKCQkkZmlsZV9zdHJ1Y3R1cmUgPSBqc29uX2RlY29kZSggJGpzb24sIHRydWUgKTsKCgkJaWYgKCBKU09OX0VSUk9SX05PTkUgIT09IGpzb25fbGFzdF9lcnJvcigpICkgewoJCQlXUF9DTEk6OmRlYnVnKCAnRXJyb3Igd2hlbiBkZWNvZGluZyB0aGVtZS1pMThuLmpzb24gZmlsZScsICdtYWtlLXBvdCcgKTsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJaWYgKCAhIGlzX2FycmF5KCAkZmlsZV9zdHJ1Y3R1cmUgKSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJcmV0dXJuIHNlbGY6OmV4dHJhY3RfcGF0aHNfdG9fdHJhbnNsYXRlKCAkZmlsZV9zdHJ1Y3R1cmUgKTsKCX0KCgkvKioKCSAqIENvbnZlcnRzIGEgdHJlZSBhcyBpbiB0aGVtZS1pMTguanNvbiBmaWxlIGludG8gYSBsaW5lYXIgYXJyYXkKCSAqIGNvbnRhaW5pbmcgbWV0YWRhdGEgdG8gdHJhbnNsYXRlIGEgdGhlbWUuanNvbiBmaWxlLgoJICoKCSAqIEZvciBleGFtcGxlLCBnaXZlbiB0aGlzIGlucHV0OgoJICoKCSAqICAgICB7CgkgKiAgICAgICAic2V0dGluZ3MiOiB7CgkgKiAgICAgICAgICIqIjogewoJICogICAgICAgICAgICJ0eXBvZ3JhcGh5IjogewoJICogICAgICAgICAgICAgImZvbnRTaXplcyI6IFsgeyAibmFtZSI6ICJGb250IHNpemUgbmFtZSIgfSBdLAoJICogICAgICAgICAgICAgImZvbnRTdHlsZXMiOiBbIHsgIm5hbWUiOiAiRm9udCBzaXplIG5hbWUiIH0gXQoJICogICAgICAgICAgIH0KCSAqICAgICAgICAgfQoJICogICAgICAgfQoJICogICAgIH0KCSAqCgkgKiB3aWxsIHJldHVybiB0aGlzIG91dHB1dDoKCSAqCgkgKiAgICAgWwoJICogICAgICAgMCA9PiBbCgkgKiAgICAgICAgICdwYXRoJyAgICA9PiBbICdzZXR0aW5ncycsICcqJywgJ3R5cG9ncmFwaHknLCAnZm9udFNpemVzJyBdLAoJICogICAgICAgICAna2V5JyAgICAgPT4gJ25hbWUnLAoJICogICAgICAgICAnY29udGV4dCcgPT4gJ0ZvbnQgc2l6ZSBuYW1lJwoJICogICAgICAgXSwKCSAqICAgICAgIDEgPT4gWwoJICogICAgICAgICAncGF0aCcgICAgPT4gWyAnc2V0dGluZ3MnLCAnKicsICd0eXBvZ3JhcGh5JywgJ2ZvbnRTdHlsZXMnIF0sCgkgKiAgICAgICAgICdrZXknICAgICA9PiAnbmFtZScsCgkgKiAgICAgICAgICdjb250ZXh0JyA9PiAnRm9udCBzdHlsZSBuYW1lJwoJICogICAgICAgXQoJICogICAgIF0KCSAqCgkgKiBQb3J0ZWQgZnJvbSB0aGUgY29yZSBjbGFzcyBgV1BfVGhlbWVfSlNPTl9SZXNvbHZlcmAuCgkgKgoJICogQHBhcmFtIGFycmF5ICRpMThuX3BhcnRpYWwgQSB0cmVlIHRoYXQgZm9sbG93cyB0aGUgZm9ybWF0IG9mIHRoZW1lLWkxOG4uanNvbi4KCSAqIEBwYXJhbSBhcnJheSAkY3VycmVudF9wYXRoIEtlZXBzIHRyYWNrIG9mIHRoZSBwYXRoIGFzIHdlIHdhbGsgZG93biB0aGUgZ2l2ZW4gdHJlZS4KCSAqIEByZXR1cm4gYXJyYXkgQSBsaW5lYXIgYXJyYXkgY29udGFpbmluZyB0aGUgcGF0aHMgdG8gdHJhbnNsYXRlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0X3BhdGhzX3RvX3RyYW5zbGF0ZSggJGkxOG5fcGFydGlhbCwgJGN1cnJlbnRfcGF0aCA9IFtdICkgewoJCSRyZXN1bHQgPSBbXTsKCQlmb3JlYWNoICggJGkxOG5fcGFydGlhbCBhcyAkcHJvcGVydHkgPT4gJHBhcnRpYWxfY2hpbGQgKSB7CgkJCWlmICggaXNfbnVtZXJpYyggJHByb3BlcnR5ICkgKSB7CgkJCQlmb3JlYWNoICggJHBhcnRpYWxfY2hpbGQgYXMgJGtleSA9PiAkY29udGV4dCApIHsKCQkJCQkkcmVzdWx0W10gPSBbCgkJCQkJCSdwYXRoJyAgICA9PiAkY3VycmVudF9wYXRoLAoJCQkJCQkna2V5JyAgICAgPT4gJGtleSwKCQkJCQkJJ2NvbnRleHQnID0+ICRjb250ZXh0LAoJCQkJCV07CgkJCQl9CgkJCQlyZXR1cm4gJHJlc3VsdDsKCQkJfQoJCQkkcmVzdWx0ID0gYXJyYXlfbWVyZ2UoCgkJCQkkcmVzdWx0LAoJCQkJc2VsZjo6ZXh0cmFjdF9wYXRoc190b190cmFuc2xhdGUoICRwYXJ0aWFsX2NoaWxkLCBhcnJheV9tZXJnZSggJGN1cnJlbnRfcGF0aCwgWyAkcHJvcGVydHkgXSApICkKCQkJKTsKCQl9CgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJLyoqCgkgKiBBY2Nlc3NlcyBhbiBhcnJheSBpbiBkZXB0aCBiYXNlZCBvbiBhIHBhdGggb2Yga2V5cy4KCSAqCgkgKiBJdCBpcyB0aGUgUEhQIGVxdWl2YWxlbnQgb2YgSmF2YVNjcmlwdCdzIGBsb2Rhc2guZ2V0KClgIGFuZCBtaXJyb3JpbmcgaXQgbWF5IGhlbHAgb3RoZXIgY29tcG9uZW50cwoJICogcmV0YWluIHNvbWUgc3ltbWV0cnkgYmV0d2VlbiBjbGllbnQgYW5kIHNlcnZlciBpbXBsZW1lbnRhdGlvbnMuCgkgKgoJICogRXhhbXBsZSB1c2FnZToKCSAqCgkgKiAgICAgJGFycmF5ID0gWwoJICogICAgICAgICAnYScgPT4gWwoJICogICAgICAgICAgICAgJ2InID0+IFsKCSAqICAgICAgICAgICAgICAgICAnYycgPT4gMSwKCSAqICAgICAgICAgICAgIF0sCgkgKiAgICAgICAgIF0sCgkgKiAgICAgXTsKCSAqICAgICBhcnJheV9nZXQoICRhcnJheSwgWyAnYScsICdiJywgJ2MnIF0gKTsKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFycmF5ICAgQW4gYXJyYXkgZnJvbSB3aGljaCB3ZSB3YW50IHRvIHJldHJpZXZlIHNvbWUgaW5mb3JtYXRpb24uCgkgKiBAcGFyYW0gYXJyYXkgJHBhdGggICAgQW4gYXJyYXkgb2Yga2V5cyBkZXNjcmliaW5nIHRoZSBwYXRoIHdpdGggd2hpY2ggdG8gcmV0cmlldmUgaW5mb3JtYXRpb24uCgkgKiBAcGFyYW0gbWl4ZWQgJGRlZmF1bHQgVGhlIHJldHVybiB2YWx1ZSBpZiB0aGUgcGF0aCBkb2VzIG5vdCBleGlzdCB3aXRoaW4gdGhlIGFycmF5LAoJICogICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIGAkYXJyYXlgIG9yIGAkcGF0aGAgYXJlIG5vdCBhcnJheXMuCgkgKiBAcmV0dXJuIG1peGVkIFRoZSB2YWx1ZSBmcm9tIHRoZSBwYXRoIHNwZWNpZmllZC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYXJyYXlfZ2V0KCAkYXJyYXksICRwYXRoLCAkZGVmYXVsdCA9IG51bGwgKSB7CgkJLy8gQ29uZmlybSAkcGF0aCBpcyB2YWxpZC4KCQlpZiAoICEgaXNfYXJyYXkoICRwYXRoICkgfHwgMCA9PT0gY291bnQoICRwYXRoICkgKSB7CgkJCXJldHVybiAkZGVmYXVsdDsKCQl9CgoJCWZvcmVhY2ggKCAkcGF0aCBhcyAkcGF0aF9lbGVtZW50ICkgewoJCQlpZiAoCgkJCQkhIGlzX2FycmF5KCAkYXJyYXkgKSB8fAoJCQkJKCAhIGlzX3N0cmluZyggJHBhdGhfZWxlbWVudCApICYmICEgaXNfaW50ZWdlciggJHBhdGhfZWxlbWVudCApICYmIG51bGwgIT09ICRwYXRoX2VsZW1lbnQgKSB8fAoJCQkJISBhcnJheV9rZXlfZXhpc3RzKCAkcGF0aF9lbGVtZW50LCAkYXJyYXkgKQoJCQkpIHsKCQkJCXJldHVybiAkZGVmYXVsdDsKCQkJfQoJCQkkYXJyYXkgPSAkYXJyYXlbICRwYXRoX2VsZW1lbnQgXTsKCQl9CgoJCXJldHVybiAkYXJyYXk7Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxFeHRyYWN0b3JzXFBvOwp1c2UgR2V0dGV4dFxNZXJnZTsKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcUGFyc2VkQ29tbWVudDsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgRGlyZWN0b3J5SXRlcmF0b3I7CnVzZSBJdGVyYXRvckl0ZXJhdG9yOwoKY2xhc3MgTWFrZVBvdENvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgkvKioKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkc291cmNlOwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRkZXN0aW5hdGlvbjsKCgkvKioKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRtZXJnZSA9IFtdOwoKCS8qKgoJICogQHZhciBUcmFuc2xhdGlvbnNbXQoJICovCglwcm90ZWN0ZWQgJGV4Y2VwdGlvbnMgPSBbXTsKCgkvKioKCSAqIEB2YXIgYm9vbAoJICovCglwcm90ZWN0ZWQgJHN1YnRyYWN0X2FuZF9tZXJnZTsKCgkvKioKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRpbmNsdWRlID0gW107CgoJLyoqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkZXhjbHVkZSA9IFsgJ25vZGVfbW9kdWxlcycsICcuZ2l0JywgJy5zdm4nLCAnLkNWUycsICcuaGcnLCAndmVuZG9yJywgJ0dydW50ZmlsZS5qcycsICd3ZWJwYWNrLmNvbmZpZy5qcycsICcqLm1pbi5qcycgXTsKCgkvKioKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkc2x1ZzsKCgkvKioKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRtYWluX2ZpbGVfZGF0YSA9IFtdOwoKCS8qKgoJICogQHZhciBib29sCgkgKi8KCXByb3RlY3RlZCAkc2tpcF9qcyA9IGZhbHNlOwoKCS8qKgoJICogQHZhciBib29sCgkgKi8KCXByb3RlY3RlZCAkc2tpcF9waHAgPSBmYWxzZTsKCgkvKioKCSAqIEB2YXIgYm9vbAoJICovCglwcm90ZWN0ZWQgJHNraXBfYmxvY2tfanNvbiA9IGZhbHNlOwoKCS8qKgoJICogQHZhciBib29sCgkgKi8KCXByb3RlY3RlZCAkc2tpcF90aGVtZV9qc29uID0gZmFsc2U7CgoJLyoqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJvdGVjdGVkICRza2lwX2F1ZGl0ID0gZmFsc2U7CgoJLyoqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJvdGVjdGVkICRsb2NhdGlvbiA9IHRydWU7CgoJLyoqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkaGVhZGVycyA9IFtdOwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRkb21haW47CgoJLyoqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHBhY2thZ2VfbmFtZTsKCgkvKioKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkZmlsZV9jb21tZW50OwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRwcm9qZWN0X3R5cGUgPSAnZ2VuZXJpYyc7CgoJLyoqCgkgKiBUaGVzZSBSZWdleGVzIGNvcGllZCBmcm9tIGh0dHA6Ly9waHAubmV0L21hbnVhbC9lbi9mdW5jdGlvbi5zcHJpbnRmLnBocCM5MzU1MgoJICogYW5kIGFkanVzdGVkIGZvciBiZXR0ZXIgcHJlY2lzaW9uIGFuZCB1cGRhdGVkIHNwZWNzLgoJICovCgljb25zdCBTUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYID0gJy8oPzoKCQkoPzwhJSkgICAgICAgICAgICAgICAgICAgICAjIERvblwndCBtYXRjaCBhIGxpdGVyYWwgJSAoJSUpLgoJCSgKCQkJJSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBTdGFydCBvZiBwbGFjZWhvbGRlci4KCQkJKD86WzAtOV0rXCQpPyAgICAgICAgICAgICAgIyBPcHRpb25hbCBvcmRlcmluZyBvZiB0aGUgcGxhY2Vob2xkZXJzLgoJCQlbKy1dPyAgICAgICAgICAgICAgICAgICAgICAjIE9wdGlvbmFsIHNpZ24gc3BlY2lmaWVyLgoJCQkoPzoKCQkJCSg/OjB8XCcuKT8gICAgICAgICAgICAgICAgICMgT3B0aW9uYWwgcGFkZGluZyBzcGVjaWZpZXIgLSBleGNsdWRpbmcgdGhlIHNwYWNlLgoJCQkJLT8gICAgICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBhbGlnbm1lbnQgc3BlY2lmaWVyLgoJCQkJWzAtOV0qICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCB3aWR0aCBzcGVjaWZpZXIuCgkJCQkoPzpcLig/OlsgMF18XCcuKT9bMC05XSspPyAjIE9wdGlvbmFsIHByZWNpc2lvbiBzcGVjaWZpZXIgd2l0aCBvcHRpb25hbCBwYWRkaW5nIGNoYXJhY3Rlci4KCQkJCXwgICAgICAgICAgICAgICAgICAgICAgIyBPbmx5IHJlY29nbml6ZSB0aGUgc3BhY2UgYXMgcGFkZGluZyBpbiBjb21iaW5hdGlvbiB3aXRoIGEgd2lkdGggc3BlY2lmaWVyLgoJCQkJKD86WyBdKT8gICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBzcGFjZSBwYWRkaW5nIHNwZWNpZmllci4KCQkJCS0/ICAgICAgICAgICAgICAgICAgICAgICAgICMgT3B0aW9uYWwgYWxpZ25tZW50IHNwZWNpZmllci4KCQkJCVswLTldKyAgICAgICAgICAgICAgICAgICAgICMgV2lkdGggc3BlY2lmaWVyLgoJCQkJKD86XC4oPzpbIDBdfFwnLik/WzAtOV0rKT8gIyBPcHRpb25hbCBwcmVjaXNpb24gc3BlY2lmaWVyIHdpdGggb3B0aW9uYWwgcGFkZGluZyBjaGFyYWN0ZXIuCgkJCSkKCQkJW2JjZGVFZkZnR29zdXhYXSAgICAgICAgICAgIyBUeXBlIHNwZWNpZmllci4KCQkpCgkpL3gnOwoKCS8qKgoJICogIlVub3JkZXJlZCIgbWVhbnMgdGhlcmUncyBubyBwb3NpdGlvbiBzcGVjaWZpZXI6ICclcycsIG5vdCAnJTIkcycuCgkgKi8KCWNvbnN0IFVOT1JERVJFRF9TUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYID0gJy8oPzoKCQkoPzwhJSkgICAgICAgICAgICAgICAgICAgICAjIERvblwndCBtYXRjaCBhIGxpdGVyYWwgJSAoJSUpLgoJCSUgICAgICAgICAgICAgICAgICAgICAgICAgICMgU3RhcnQgb2YgcGxhY2Vob2xkZXIuCgkJWystXT8gICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBzaWduIHNwZWNpZmllci4KCQkoPzoKCQkJKD86MHxcJy4pPyAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBwYWRkaW5nIHNwZWNpZmllciAtIGV4Y2x1ZGluZyB0aGUgc3BhY2UuCgkJCS0/ICAgICAgICAgICAgICAgICAgICAgICAgICMgT3B0aW9uYWwgYWxpZ25tZW50IHNwZWNpZmllci4KCQkJWzAtOV0qICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCB3aWR0aCBzcGVjaWZpZXIuCgkJCSg/OlwuKD86WyAwXXxcJy4pP1swLTldKyk/ICMgT3B0aW9uYWwgcHJlY2lzaW9uIHNwZWNpZmllciB3aXRoIG9wdGlvbmFsIHBhZGRpbmcgY2hhcmFjdGVyLgoJCQl8ICAgICAgICAgICAgICAgICAgICAgICMgT25seSByZWNvZ25pemUgdGhlIHNwYWNlIGFzIHBhZGRpbmcgaW4gY29tYmluYXRpb24gd2l0aCBhIHdpZHRoIHNwZWNpZmllci4KCQkJKD86WyBdKT8gICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBzcGFjZSBwYWRkaW5nIHNwZWNpZmllci4KCQkJLT8gICAgICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBhbGlnbm1lbnQgc3BlY2lmaWVyLgoJCQlbMC05XSsgICAgICAgICAgICAgICAgICAgICAjIFdpZHRoIHNwZWNpZmllci4KCQkJKD86XC4oPzpbIDBdfFwnLik/WzAtOV0rKT8gIyBPcHRpb25hbCBwcmVjaXNpb24gc3BlY2lmaWVyIHdpdGggb3B0aW9uYWwgcGFkZGluZyBjaGFyYWN0ZXIuCgkJKQoJCVtiY2RlRWZGZ0dvc3V4WF0gICAgICAgICAgICMgVHlwZSBzcGVjaWZpZXIuCgkpL3gnOwoKCS8qKgoJICogQ3JlYXRlIGEgUE9UIGZpbGUgZm9yIGEgV29yZFByZXNzIHByb2plY3QuCgkgKgoJICogU2NhbnMgUEhQIGFuZCBKYXZhU2NyaXB0IGZpbGVzIGZvciB0cmFuc2xhdGFibGUgc3RyaW5ncywgYXMgd2VsbCBhcyB0aGVtZSBzdHlsZXNoZWV0cyBhbmQgcGx1Z2luIGZpbGVzCgkgKiBpZiB0aGUgc291cmNlIGRpcmVjdG9yeSBpcyBkZXRlY3RlZCBhcyBlaXRoZXIgYSBwbHVnaW4gb3IgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzb3VyY2U+CgkgKiA6IERpcmVjdG9yeSB0byBzY2FuIGZvciBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqCgkgKiBbPGRlc3RpbmF0aW9uPl0KCSAqIDogTmFtZSBvZiB0aGUgcmVzdWx0aW5nIFBPVCBmaWxlLgoJICoKCSAqIFstLXNsdWc9PHNsdWc+XQoJICogOiBQbHVnaW4gb3IgdGhlbWUgc2x1Zy4gRGVmYXVsdHMgdG8gdGhlIHNvdXJjZSBkaXJlY3RvcnkncyBiYXNlbmFtZS4KCSAqCgkgKiBbLS1kb21haW49PGRvbWFpbj5dCgkgKiA6IFRleHQgZG9tYWluIHRvIGxvb2sgZm9yIGluIHRoZSBzb3VyY2UgY29kZSwgdW5sZXNzIHRoZSBgLS1pZ25vcmUtZG9tYWluYCBvcHRpb24gaXMgdXNlZC4KCSAqIEJ5IGRlZmF1bHQsIHRoZSAiVGV4dCBEb21haW4iIGhlYWRlciBvZiB0aGUgcGx1Z2luIG9yIHRoZW1lIGlzIHVzZWQuCgkgKiBJZiBub25lIGlzIHByb3ZpZGVkLCBpdCBmYWxscyBiYWNrIHRvIHRoZSBwcm9qZWN0IHNsdWcuCgkgKgoJICogWy0taWdub3JlLWRvbWFpbl0KCSAqIDogSWdub3JlIHRoZSB0ZXh0IGRvbWFpbiBjb21wbGV0ZWx5IGFuZCBleHRyYWN0IHN0cmluZ3Mgd2l0aCBhbnkgdGV4dCBkb21haW4uCgkgKgoJICogWy0tbWVyZ2VbPTxwYXRocz5dXQoJICogOiBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBQT1QgZmlsZXMgd2hvc2UgY29udGVudHMgc2hvdWxkIGJlIG1lcmdlZCB3aXRoIHRoZSBleHRyYWN0ZWQgc3RyaW5ncy4KCSAqIElmIGxlZnQgZW1wdHksIGRlZmF1bHRzIHRvIHRoZSBkZXN0aW5hdGlvbiBQT1QgZmlsZS4gUE9UIGZpbGUgaGVhZGVycyB3aWxsIGJlIGlnbm9yZWQuCgkgKgoJICogWy0tc3VidHJhY3Q9PHBhdGhzPl0KCSAqIDogQ29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgUE9UIGZpbGVzIHdob3NlIGNvbnRlbnRzIHNob3VsZCBhY3QgYXMgc29tZSBzb3J0IG9mIGRlbnlsaXN0IGZvciBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqIEFueSBzdHJpbmcgd2hpY2ggaXMgZm91bmQgb24gdGhhdCBkZW55bGlzdCB3aWxsIG5vdCBiZSBleHRyYWN0ZWQuCgkgKiBUaGlzIGNhbiBiZSB1c2VmdWwgd2hlbiB5b3Ugd2FudCB0byBjcmVhdGUgbXVsdGlwbGUgUE9UIGZpbGVzIGZyb20gdGhlIHNhbWUgc291cmNlIGRpcmVjdG9yeSB3aXRoIHNsaWdodGx5CgkgKiBkaWZmZXJlbnQgY29udGVudCBhbmQgbm8gZHVwbGljYXRlIHN0cmluZ3MgYmV0d2VlbiB0aGVtLgoJICoKCSAqIFstLXN1YnRyYWN0LWFuZC1tZXJnZV0KCSAqIDogV2hldGhlciBzb3VyY2UgY29kZSByZWZlcmVuY2VzIGFuZCBjb21tZW50cyBmcm9tIHRoZSBnZW5lcmF0ZWQgUE9UIGZpbGUgc2hvdWxkIGJlIGluc3RlYWQgYWRkZWQgdG8gdGhlIFBPVCBmaWxlCgkgKiB1c2VkIGZvciBzdWJ0cmFjdGlvbi4gV2FybmluZzogdGhpcyBtb2RpZmllcyB0aGUgZmlsZXMgcGFzc2VkIHRvIGAtLXN1YnRyYWN0YCEKCSAqCgkgKiBbLS1pbmNsdWRlPTxwYXRocz5dCgkgKiA6IENvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGZpbGVzIGFuZCBwYXRocyB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqIElmIHByb3ZpZGVkLCBvbmx5IHRoZXNlIGZpbGVzIGFuZCBmb2xkZXJzIHdpbGwgYmUgdGFrZW4gaW50byBhY2NvdW50IGZvciBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqIEZvciBleGFtcGxlLCBgLS1pbmNsdWRlPSJzcmMsbXktZmlsZS5waHBgIHdpbGwgaWdub3JlIGFueXRoaW5nIGJlc2lkZXMgYG15LWZpbGUucGhwYCBhbmQgZmlsZXMgaW4gdGhlIGBzcmNgCgkgKiBkaXJlY3RvcnkuIFNpbXBsZSBnbG9iIHBhdHRlcm5zIGNhbiBiZSB1c2VkLCBpLmUuIGAtLWluY2x1ZGU9Zm9vLSoucGhwYCBpbmNsdWRlcyBhbnkgUEhQIGZpbGUgd2l0aCB0aGUgYGZvby1gCgkgKiBwcmVmaXguIExlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgYXJlIGlnbm9yZWQsIGkuZS4gYC9teS9kaXJlY3RvcnkvYCBpcyB0aGUgc2FtZSBhcyBgbXkvZGlyZWN0b3J5YC4KCSAqCgkgKiBbLS1leGNsdWRlPTxwYXRocz5dCgkgKiA6IENvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGZpbGVzIGFuZCBwYXRocyB0aGF0IHNob3VsZCBiZSBza2lwcGVkIGZvciBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqIEZvciBleGFtcGxlLCBgLS1leGNsdWRlPSIuZ2l0aHViLG15ZmlsZS5waHBgIHdvdWxkIGlnbm9yZSBhbnkgc3RyaW5ncyBmb3VuZCB3aXRoaW4gYG15ZmlsZS5waHBgIG9yIHRoZSBgLmdpdGh1YmAKCSAqIGZvbGRlci4gU2ltcGxlIGdsb2IgcGF0dGVybnMgY2FuIGJlIHVzZWQsIGkuZS4gYC0tZXhjbHVkZT1mb28tKi5waHBgIGV4Y2x1ZGVzIGFueSBQSFAgZmlsZSB3aXRoIHRoZSBgZm9vLWAKCSAqIHByZWZpeC4gTGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyBhcmUgaWdub3JlZCwgaS5lLiBgL215L2RpcmVjdG9yeS9gIGlzIHRoZSBzYW1lIGFzIGBteS9kaXJlY3RvcnlgLiBUaGUKCSAqIGZvbGxvd2luZyBmaWxlcyBhbmQgZm9sZGVycyBhcmUgYWx3YXlzIGV4Y2x1ZGVkOiBub2RlX21vZHVsZXMsIC5naXQsIC5zdm4sIC5DVlMsIC5oZywgdmVuZG9yLCAqLm1pbi5qcy4KCSAqCgkgKiBbLS1oZWFkZXJzPTxoZWFkZXJzPl0KCSAqIDogQXJyYXkgaW4gSlNPTiBmb3JtYXQgb2YgY3VzdG9tIGhlYWRlcnMgd2hpY2ggd2lsbCBiZSBhZGRlZCB0byB0aGUgUE9UIGZpbGUuIERlZmF1bHRzIHRvIGVtcHR5IGFycmF5LgoJICoKCSAqIFstLWxvY2F0aW9uXQoJICogOiBXaGV0aGVyIHRvIHdyaXRlIGAjOiBmaWxlbmFtZTpsaW5lYCBsaW5lcy4KCSAqIERlZmF1bHRzIHRvIHRydWUsIHVzZSBgLS1uby1sb2NhdGlvbmAgdG8gc2tpcCB0aGUgcmVtb3ZhbC4KCSAqIE5vdGUgdGhhdCBkaXNhYmxpbmcgdGhpcyBvcHRpb24gbWFrZXMgaXQgaGFyZGVyIGZvciB0ZWNobmljYWxseSBza2lsbGVkIHRyYW5zbGF0b3JzIHRvIHVuZGVyc3RhbmQgZWFjaCBtZXNzYWdl4oCZcyBjb250ZXh0LgoJICoKCSAqIFstLXNraXAtanNdCgkgKiA6IFNraXBzIEphdmFTY3JpcHQgc3RyaW5nIGV4dHJhY3Rpb24uIFVzZWZ1bCB3aGVuIHRoaXMgaXMgZG9uZSBpbiBhbm90aGVyIGJ1aWxkIHN0ZXAsIGUuZy4gdGhyb3VnaCBCYWJlbC4KCSAqCgkgKiBbLS1za2lwLXBocF0KCSAqIDogU2tpcHMgUEhQIHN0cmluZyBleHRyYWN0aW9uLgoJICoKCSAqIFstLXNraXAtYmxvY2stanNvbl0KCSAqIDogU2tpcHMgc3RyaW5nIGV4dHJhY3Rpb24gZnJvbSBibG9jay5qc29uIGZpbGVzLgoJICoKCSAqIFstLXNraXAtdGhlbWUtanNvbl0KCSAqIDogU2tpcHMgc3RyaW5nIGV4dHJhY3Rpb24gZnJvbSB0aGVtZS5qc29uIGZpbGVzLgoJICoKCSAqIFstLXNraXAtYXVkaXRdCgkgKiA6IFNraXBzIHN0cmluZyBhdWRpdCB3aGVyZSBpdCB0cmllcyB0byBmaW5kIHBvc3NpYmxlIG1pc3Rha2VzIGluIHRyYW5zbGF0YWJsZSBzdHJpbmdzLiBVc2VmdWwgd2hlbiBydW5uaW5nIGluIGFuCgkgKiBhdXRvbWF0ZWQgZW52aXJvbm1lbnQuCgkgKgoJICogWy0tZmlsZS1jb21tZW50PTxmaWxlLWNvbW1lbnQ+XQoJICogOiBTdHJpbmcgdGhhdCBzaG91bGQgYmUgYWRkZWQgYXMgYSBjb21tZW50IHRvIHRoZSB0b3Agb2YgdGhlIHJlc3VsdGluZyBQT1QgZmlsZS4KCSAqIEJ5IGRlZmF1bHQsIGEgY29weXJpZ2h0IGNvbW1lbnQgaXMgYWRkZWQgZm9yIFdvcmRQcmVzcyBwbHVnaW5zIGFuZCB0aGVtZXMgaW4gdGhlIGZvbGxvd2luZyBtYW5uZXI6CgkgKgoJICogICAgICBgYGAKCSAqICAgICAgQ29weXJpZ2h0IChDKSAyMDE4IEV4YW1wbGUgUGx1Z2luIEF1dGhvcgoJICogICAgICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHNhbWUgbGljZW5zZSBhcyB0aGUgRXhhbXBsZSBQbHVnaW4gcGFja2FnZS4KCSAqICAgICAgYGBgCgkgKgoJICogICAgICBJZiBhIHBsdWdpbiBvciB0aGVtZSBzcGVjaWZpZXMgYSBsaWNlbnNlIGluIHRoZWlyIG1haW4gcGx1Z2luIGZpbGUgb3Igc3R5bGVzaGVldCwgdGhlIGNvbW1lbnQgbG9va3MgbGlrZQoJICogICAgICB0aGlzOgoJICoKCSAqICAgICAgYGBgCgkgKiAgICAgIENvcHlyaWdodCAoQykgMjAxOCBFeGFtcGxlIFBsdWdpbiBBdXRob3IKCSAqICAgICAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBHUEx2Mi4KCSAqICAgICAgYGBgCgkgKgoJICogWy0tcGFja2FnZS1uYW1lPTxuYW1lPl0KCSAqIDogTmFtZSB0byB1c2UgZm9yIHBhY2thZ2UgbmFtZSBpbiB0aGUgcmVzdWx0aW5nIFBPVCBmaWxlJ3MgYFByb2plY3QtSWQtVmVyc2lvbmAgaGVhZGVyLgoJICogT3ZlcnJpZGVzIHBsdWdpbiBvciB0aGVtZSBuYW1lLCBpZiBhcHBsaWNhYmxlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIGEgUE9UIGZpbGUgZm9yIHRoZSBXb3JkUHJlc3MgcGx1Z2luL3RoZW1lIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeQoJICogICAgICQgd3AgaTE4biBtYWtlLXBvdCAuIGxhbmd1YWdlcy9teS1wbHVnaW4ucG90CgkgKgoJICogICAgICMgQ3JlYXRlIGEgUE9UIGZpbGUgZm9yIHRoZSBjb250aW5lbnRzIGFuZCBjaXRpZXMgbGlzdCBpbiBXb3JkUHJlc3MgY29yZS4KCSAqICAgICAkIHdwIGkxOG4gbWFrZS1wb3QgLiBjb250aW5lbnRzLWFuZC1jaXRpZXMucG90IC0taW5jbHVkZT0id3AtYWRtaW4vaW5jbHVkZXMvY29udGluZW50cy1jaXRpZXMucGhwIgoJICogICAgIC0taWdub3JlLWRvbWFpbgoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKgoJICogQHRocm93cyBXUF9DTElcRXhpdEV4Y2VwdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+aGFuZGxlX2FyZ3VtZW50cyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgoJCSR0cmFuc2xhdGlvbnMgPSAkdGhpcy0+ZXh0cmFjdF9zdHJpbmdzKCk7CgoJCWlmICggISAkdHJhbnNsYXRpb25zICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdObyBzdHJpbmdzIGZvdW5kJyApOwoJCX0KCgkJJHRyYW5zbGF0aW9uc19jb3VudCA9IGNvdW50KCAkdHJhbnNsYXRpb25zICk7CgoJCWlmICggMSA9PT0gJHRyYW5zbGF0aW9uc19jb3VudCApIHsKCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ0V4dHJhY3RlZCAlZCBzdHJpbmcnLCAkdHJhbnNsYXRpb25zX2NvdW50ICksICdtYWtlLXBvdCcgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmRlYnVnKCBzcHJpbnRmKCAnRXh0cmFjdGVkICVkIHN0cmluZ3MnLCAkdHJhbnNsYXRpb25zX2NvdW50ICksICdtYWtlLXBvdCcgKTsKCQl9CgoJCWlmICggISBQb3RHZW5lcmF0b3I6OnRvRmlsZSggJHRyYW5zbGF0aW9ucywgJHRoaXMtPmRlc3RpbmF0aW9uICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDb3VsZCBub3QgZ2VuZXJhdGUgYSBQT1QgZmlsZSEnICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdQT1QgZmlsZSBzdWNjZXNzZnVsbHkgZ2VuZXJhdGVkIScgKTsKCX0KCgkvKioKCSAqIFByb2Nlc3MgYXJndW1lbnRzIGZyb20gY29tbWFuZC1saW5lIGluIGEgcmV1c2FibGUgd2F5LgoJICoKCSAqIEB0aHJvd3MgV1BfQ0xJXEV4aXRFeGNlcHRpb24KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgICAgICAgQ29tbWFuZCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gaGFuZGxlX2FyZ3VtZW50cyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhcnJheV9hcmd1bWVudHMgPSBhcnJheSggJ2hlYWRlcnMnICk7CgkJJGFzc29jX2FyZ3MgICAgICA9IFV0aWxzXHBhcnNlX3NoZWxsX2FycmF5cyggJGFzc29jX2FyZ3MsICRhcnJheV9hcmd1bWVudHMgKTsKCgkJJHRoaXMtPnNvdXJjZSAgICAgICAgICA9IHJlYWxwYXRoKCAkYXJnc1swXSApOwoJCSR0aGlzLT5zbHVnICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzbHVnJywgVXRpbHNcYmFzZW5hbWUoICR0aGlzLT5zb3VyY2UgKSApOwoJCSR0aGlzLT5za2lwX2pzICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWpzJywgJHRoaXMtPnNraXBfanMgKTsKCQkkdGhpcy0+c2tpcF9waHAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1waHAnLCAkdGhpcy0+c2tpcF9waHAgKTsKCQkkdGhpcy0+c2tpcF9ibG9ja19qc29uID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1ibG9jay1qc29uJywgJHRoaXMtPnNraXBfYmxvY2tfanNvbiApOwoJCSR0aGlzLT5za2lwX3RoZW1lX2pzb24gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXRoZW1lLWpzb24nLCAkdGhpcy0+c2tpcF90aGVtZV9qc29uICk7CgkJJHRoaXMtPnNraXBfYXVkaXQgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtYXVkaXQnLCAkdGhpcy0+c2tpcF9hdWRpdCApOwoJCSR0aGlzLT5oZWFkZXJzICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoZWFkZXJzJywgJHRoaXMtPmhlYWRlcnMgKTsKCQkkdGhpcy0+ZmlsZV9jb21tZW50ICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZmlsZS1jb21tZW50JyApOwoJCSR0aGlzLT5wYWNrYWdlX25hbWUgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwYWNrYWdlLW5hbWUnICk7CgkJJHRoaXMtPmxvY2F0aW9uICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2xvY2F0aW9uJywgdHJ1ZSApOwoKCQkkaWdub3JlX2RvbWFpbiA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2lnbm9yZS1kb21haW4nLCBmYWxzZSApOwoKCQlpZiAoICEgJHRoaXMtPnNvdXJjZSB8fCAhIGlzX2RpciggJHRoaXMtPnNvdXJjZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm90IGEgdmFsaWQgc291cmNlIGRpcmVjdG9yeSEnICk7CgkJfQoKCQkkdGhpcy0+bWFpbl9maWxlX2RhdGEgPSAkdGhpcy0+Z2V0X21haW5fZmlsZV9kYXRhKCk7CgoJCWlmICggJGlnbm9yZV9kb21haW4gKSB7CgkJCVdQX0NMSTo6ZGVidWcoICdFeHRyYWN0aW5nIGFsbCBzdHJpbmdzIHJlZ2FyZGxlc3Mgb2YgdGV4dCBkb21haW4nLCAnbWFrZS1wb3QnICk7CgkJfQoKCQlpZiAoICEgJGlnbm9yZV9kb21haW4gKSB7CgkJCSR0aGlzLT5kb21haW4gPSAkdGhpcy0+c2x1ZzsKCgkJCWlmICggISBlbXB0eSggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUZXh0IERvbWFpbiddICkgKSB7CgkJCQkkdGhpcy0+ZG9tYWluID0gJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUZXh0IERvbWFpbiddOwoJCQl9CgoJCQkkdGhpcy0+ZG9tYWluID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZG9tYWluJywgJHRoaXMtPmRvbWFpbiApOwoKCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ0V4dHJhY3RpbmcgYWxsIHN0cmluZ3Mgd2l0aCB0ZXh0IGRvbWFpbiAiJXMiJywgJHRoaXMtPmRvbWFpbiApLCAnbWFrZS1wb3QnICk7CgkJfQoKCQkvLyBEZXRlcm1pbmUgZGVzdGluYXRpb24uCgkJJHRoaXMtPmRlc3RpbmF0aW9uID0gInskdGhpcy0+c291cmNlfS97JHRoaXMtPnNsdWd9LnBvdCI7CgoJCWlmICggISBlbXB0eSggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydEb21haW4gUGF0aCddICkgKSB7CgkJCS8vIERvbWFpbiBQYXRoIGluc2lkZSBzb3VyY2UgZm9sZGVyLgoJCQkkdGhpcy0+ZGVzdGluYXRpb24gPSBzcHJpbnRmKAoJCQkJJyVzLyVzLyVzLnBvdCcsCgkJCQkkdGhpcy0+c291cmNlLAoJCQkJJHRoaXMtPnVuc2xhc2hpdCggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydEb21haW4gUGF0aCddICksCgkJCQkkdGhpcy0+c2x1ZwoJCQkpOwoJCX0KCgkJaWYgKCBpc3NldCggJGFyZ3NbMV0gKSApIHsKCQkJJHRoaXMtPmRlc3RpbmF0aW9uID0gJGFyZ3NbMV07CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCBzcHJpbnRmKCAnRGVzdGluYXRpb246ICVzJywgJHRoaXMtPmRlc3RpbmF0aW9uICksICdtYWtlLXBvdCcgKTsKCgkJLy8gVHdvIGlzX2RpcigpIGNoZWNrcyBpbiBjYXNlIG9mIGEgcmFjZSBjb25kaXRpb24uCgkJaWYgKCAhIGlzX2RpciggZGlybmFtZSggJHRoaXMtPmRlc3RpbmF0aW9uICkgKQoJCQkmJiAhIG1rZGlyKCBkaXJuYW1lKCAkdGhpcy0+ZGVzdGluYXRpb24gKSwgMDc3NywgdHJ1ZSApCgkJCSYmICEgaXNfZGlyKCBkaXJuYW1lKCAkdGhpcy0+ZGVzdGluYXRpb24gKSApCgkJKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDb3VsZCBub3QgY3JlYXRlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSEnICk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snbWVyZ2UnXSApICkgewoJCQlpZiAoIHRydWUgPT09ICRhc3NvY19hcmdzWydtZXJnZSddICkgewoJCQkJJHRoaXMtPm1lcmdlID0gWyAkdGhpcy0+ZGVzdGluYXRpb24gXTsKCQkJfSBlbHNlaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snbWVyZ2UnXSApICkgewoJCQkJJHRoaXMtPm1lcmdlID0gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snbWVyZ2UnXSApOwoJCQl9CgoJCQkkdGhpcy0+bWVyZ2UgPSBhcnJheV9maWx0ZXIoCgkJCQkkdGhpcy0+bWVyZ2UsCgkJCQlmdW5jdGlvbiAoICRmaWxlICkgewoJCQkJCWlmICggISBmaWxlX2V4aXN0cyggJGZpbGUgKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnSW52YWxpZCBmaWxlIHByb3ZpZGVkIHRvIC0tbWVyZ2U6ICVzJywgJGZpbGUgKSApOwoKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCSk7CgoJCQlpZiAoICEgZW1wdHkoICR0aGlzLT5tZXJnZSApICkgewoJCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCQlzcHJpbnRmKAoJCQkJCQknTWVyZ2luZyB3aXRoIGV4aXN0aW5nIFBPVCAlczogJXMnLAoJCQkJCQlXUF9DTElcVXRpbHNccGx1cmFsaXplKCAnZmlsZScsIGNvdW50KCAkdGhpcy0+bWVyZ2UgKSApLAoJCQkJCQlpbXBsb2RlKCAnLCcsICR0aGlzLT5tZXJnZSApCgkJCQkJKSwKCQkJCQknbWFrZS1wb3QnCgkJCQkpOwoJCQl9CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snc3VidHJhY3QnXSApICkgewoJCQkkdGhpcy0+c3VidHJhY3RfYW5kX21lcmdlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc3VidHJhY3QtYW5kLW1lcmdlJywgZmFsc2UgKTsKCgkJCSRmaWxlcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ3N1YnRyYWN0J10gKTsKCgkJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGUgKSB7CgkJCQlpZiAoICEgZmlsZV9leGlzdHMoICRmaWxlICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnSW52YWxpZCBmaWxlIHByb3ZpZGVkIHRvIC0tc3VidHJhY3Q6ICVzJywgJGZpbGUgKSApOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdJZ25vcmluZyBhbnkgc3RyaW5nIGFscmVhZHkgZXhpc3RpbmcgaW46ICVzJywgJGZpbGUgKSwgJ21ha2UtcG90JyApOwoKCQkJCSR0aGlzLT5leGNlcHRpb25zWyAkZmlsZSBdID0gbmV3IFRyYW5zbGF0aW9ucygpOwoJCQkJUG86OmZyb21GaWxlKCAkZmlsZSwgJHRoaXMtPmV4Y2VwdGlvbnNbICRmaWxlIF0gKTsKCQkJfQoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2luY2x1ZGUnXSApICkgewoJCQkkdGhpcy0+aW5jbHVkZSA9IGFycmF5X2ZpbHRlciggZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snaW5jbHVkZSddICkgKTsKCQkJJHRoaXMtPmluY2x1ZGUgPSBhcnJheV9tYXAoIFsgJHRoaXMsICd1bnNsYXNoaXQnIF0sICR0aGlzLT5pbmNsdWRlICk7CgkJCSR0aGlzLT5pbmNsdWRlID0gYXJyYXlfdW5pcXVlKCAkdGhpcy0+aW5jbHVkZSApOwoKCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ09ubHkgaW5jbHVkaW5nIHRoZSBmb2xsb3dpbmcgZmlsZXM6ICVzJywgaW1wbG9kZSggJywnLCAkdGhpcy0+aW5jbHVkZSApICksICdtYWtlLXBvdCcgKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydleGNsdWRlJ10gKSApIHsKCQkJJHRoaXMtPmV4Y2x1ZGUgPSBhcnJheV9maWx0ZXIoIGFycmF5X21lcmdlKCAkdGhpcy0+ZXhjbHVkZSwgZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snZXhjbHVkZSddICkgKSApOwoJCQkkdGhpcy0+ZXhjbHVkZSA9IGFycmF5X21hcCggWyAkdGhpcywgJ3Vuc2xhc2hpdCcgXSwgJHRoaXMtPmV4Y2x1ZGUgKTsKCQkJJHRoaXMtPmV4Y2x1ZGUgPSBhcnJheV91bmlxdWUoICR0aGlzLT5leGNsdWRlICk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCBzcHJpbnRmKCAnRXhjbHVkaW5nIHRoZSBmb2xsb3dpbmcgZmlsZXM6ICVzJywgaW1wbG9kZSggJywnLCAkdGhpcy0+ZXhjbHVkZSApICksICdtYWtlLXBvdCcgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyBvZiBhIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgV2hhdCB0byBhZGQgYW5kIHJlbW92ZSBzbGFzaGVzIGZyb20uCgkgKiBAcmV0dXJuIHN0cmluZyBTdHJpbmcgd2l0aG91dCBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdW5zbGFzaGl0KCAkc3RyaW5nICkgewoJCXJldHVybiBsdHJpbSggcnRyaW0oIHRyaW0oICRzdHJpbmcgKSwgJy9cXCcgKSwgJy9cXCcgKTsKCX0KCgkvKioKCSAqIFJldHJpZXZlcyB0aGUgbWFpbiBmaWxlIGRhdGEgb2YgdGhlIHBsdWdpbiBvciB0aGVtZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfbWFpbl9maWxlX2RhdGEoKSB7CgkJJGZpbGVzID0gbmV3IEl0ZXJhdG9ySXRlcmF0b3IoIG5ldyBEaXJlY3RvcnlJdGVyYXRvciggJHRoaXMtPnNvdXJjZSApICk7CgoJCS8qKiBAdmFyIERpcmVjdG9yeUl0ZXJhdG9yICRmaWxlICovCgkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJLy8gd3AtY29udGVudC90aGVtZXMvbXktdGhlbWUvc3R5bGUuY3NzCgkJCWlmICggJGZpbGUtPmlzRmlsZSgpICYmICdzdHlsZScgPT09ICRmaWxlLT5nZXRCYXNlbmFtZSggJy5jc3MnICkgJiYgJGZpbGUtPmlzUmVhZGFibGUoKSApIHsKCQkJCSR0aGVtZV9kYXRhID0gc3RhdGljOjpnZXRfZmlsZV9kYXRhKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSwgYXJyYXlfY29tYmluZSggJHRoaXMtPmdldF9maWxlX2hlYWRlcnMoICd0aGVtZScgKSwgJHRoaXMtPmdldF9maWxlX2hlYWRlcnMoICd0aGVtZScgKSApICk7CgoJCQkJLy8gU3RvcCB3aGVuIGl0IGNvbnRhaW5zIGEgdmFsaWQgVGhlbWUgTmFtZSBoZWFkZXIuCgkJCQlpZiAoICEgZW1wdHkoICR0aGVtZV9kYXRhWydUaGVtZSBOYW1lJ10gKSApIHsKCQkJCQlXUF9DTEk6OmxvZyggJ1RoZW1lIHN0eWxlc2hlZXQgZGV0ZWN0ZWQuJyApOwoJCQkJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdUaGVtZSBzdHlsZXNoZWV0OiAlcycsICRmaWxlLT5nZXRSZWFsUGF0aCgpICksICdtYWtlLXBvdCcgKTsKCgkJCQkJJHRoaXMtPnByb2plY3RfdHlwZSA9ICd0aGVtZSc7CgoJCQkJCXJldHVybiAkdGhlbWVfZGF0YTsKCQkJCX0KCQkJfQoKCQkJLy8gd3AtY29udGVudC90aGVtZXMvbXktdGhlbWVzL3RoZW1lLWEvc3R5bGUuY3NzCgkJCWlmICggJGZpbGUtPmlzRGlyKCkgJiYgISAkZmlsZS0+aXNEb3QoKSAmJiBpc19yZWFkYWJsZSggJGZpbGUtPmdldFJlYWxQYXRoKCkgLiAnL3N0eWxlLmNzcycgKSApIHsKCQkJCSR0aGVtZV9kYXRhID0gc3RhdGljOjpnZXRfZmlsZV9kYXRhKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSAuICcvc3R5bGUuY3NzJywgYXJyYXlfY29tYmluZSggJHRoaXMtPmdldF9maWxlX2hlYWRlcnMoICd0aGVtZScgKSwgJHRoaXMtPmdldF9maWxlX2hlYWRlcnMoICd0aGVtZScgKSApICk7CgoJCQkJLy8gU3RvcCB3aGVuIGl0IGNvbnRhaW5zIGEgdmFsaWQgVGhlbWUgTmFtZSBoZWFkZXIuCgkJCQlpZiAoICEgZW1wdHkoICR0aGVtZV9kYXRhWydUaGVtZSBOYW1lJ10gKSApIHsKCQkJCQlXUF9DTEk6OmxvZyggJ1RoZW1lIHN0eWxlc2hlZXQgZGV0ZWN0ZWQuJyApOwoJCQkJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdUaGVtZSBzdHlsZXNoZWV0OiAlcycsICRmaWxlLT5nZXRSZWFsUGF0aCgpIC4gJy9zdHlsZS5jc3MnICksICdtYWtlLXBvdCcgKTsKCgkJCQkJJHRoaXMtPnByb2plY3RfdHlwZSA9ICd0aGVtZSc7CgoJCQkJCXJldHVybiAkdGhlbWVfZGF0YTsKCQkJCX0KCQkJfQoKCQkJLy8gd3AtY29udGVudC9wbHVnaW5zL215LXBsdWdpbi9teS1wbHVnaW4ucGhwCgkJCWlmICggJGZpbGUtPmlzRmlsZSgpICYmICRmaWxlLT5pc1JlYWRhYmxlKCkgJiYgJ3BocCcgPT09ICRmaWxlLT5nZXRFeHRlbnNpb24oKSApIHsKCQkJCSRwbHVnaW5fZGF0YSA9IHN0YXRpYzo6Z2V0X2ZpbGVfZGF0YSggJGZpbGUtPmdldFJlYWxQYXRoKCksIGFycmF5X2NvbWJpbmUoICR0aGlzLT5nZXRfZmlsZV9oZWFkZXJzKCAncGx1Z2luJyApLCAkdGhpcy0+Z2V0X2ZpbGVfaGVhZGVycyggJ3BsdWdpbicgKSApICk7CgoJCQkJLy8gU3RvcCB3aGVuIHdlIGZpbmQgYSBmaWxlIHdpdGggYSB2YWxpZCBQbHVnaW4gTmFtZSBoZWFkZXIuCgkJCQlpZiAoICEgZW1wdHkoICRwbHVnaW5fZGF0YVsnUGx1Z2luIE5hbWUnXSApICkgewoJCQkJCVdQX0NMSTo6bG9nKCAnUGx1Z2luIGZpbGUgZGV0ZWN0ZWQuJyApOwoJCQkJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdQbHVnaW4gZmlsZTogJXMnLCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSApLCAnbWFrZS1wb3QnICk7CgoJCQkJCSR0aGlzLT5wcm9qZWN0X3R5cGUgPSAncGx1Z2luJzsKCgkJCQkJcmV0dXJuICRwbHVnaW5fZGF0YTsKCQkJCX0KCQkJfQoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ05vIHZhbGlkIHRoZW1lIHN0eWxlc2hlZXQgb3IgcGx1Z2luIGZpbGUgZm91bmQsIHRyZWF0aW5nIGFzIGEgcmVndWxhciBwcm9qZWN0LicsICdtYWtlLXBvdCcgKTsKCgkJcmV0dXJuIFtdOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgZmlsZSBoZWFkZXJzIGZvciB0aGVtZXMgYW5kIHBsdWdpbnMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdHlwZSBTb3VyY2UgdHlwZSwgZWl0aGVyIHRoZW1lIG9yIHBsdWdpbi4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IExpc3Qgb2YgZmlsZSBoZWFkZXJzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2ZpbGVfaGVhZGVycyggJHR5cGUgKSB7CgkJc3dpdGNoICggJHR5cGUgKSB7CgkJCWNhc2UgJ3BsdWdpbic6CgkJCQlyZXR1cm4gWwoJCQkJCSdQbHVnaW4gTmFtZScsCgkJCQkJJ1BsdWdpbiBVUkknLAoJCQkJCSdEZXNjcmlwdGlvbicsCgkJCQkJJ0F1dGhvcicsCgkJCQkJJ0F1dGhvciBVUkknLAoJCQkJCSdWZXJzaW9uJywKCQkJCQknTGljZW5zZScsCgkJCQkJJ0RvbWFpbiBQYXRoJywKCQkJCQknVGV4dCBEb21haW4nLAoJCQkJXTsKCQkJY2FzZSAndGhlbWUnOgoJCQkJcmV0dXJuIFsKCQkJCQknVGhlbWUgTmFtZScsCgkJCQkJJ1RoZW1lIFVSSScsCgkJCQkJJ0Rlc2NyaXB0aW9uJywKCQkJCQknQXV0aG9yJywKCQkJCQknQXV0aG9yIFVSSScsCgkJCQkJJ1ZlcnNpb24nLAoJCQkJCSdMaWNlbnNlJywKCQkJCQknRG9tYWluIFBhdGgnLAoJCQkJCSdUZXh0IERvbWFpbicsCgkJCQldOwoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIFtdOwoJCX0KCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBQT1QgZmlsZSBhbmQgc3RvcmVzIGl0IG9uIGRpc2suCgkgKgoJICogQHRocm93cyBXUF9DTElcRXhpdEV4Y2VwdGlvbgoJICoKCSAqIEByZXR1cm4gVHJhbnNsYXRpb25zIEEgVHJhbnNsYXRpb24gc2V0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZXh0cmFjdF9zdHJpbmdzKCkgewoJCSR0cmFuc2xhdGlvbnMgPSBuZXcgVHJhbnNsYXRpb25zKCk7CgoJCS8vIEFkZCBleGlzdGluZyBzdHJpbmdzIGZpcnN0IGJ1dCBkb24ndCBrZWVwIGhlYWRlcnMuCgkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+bWVyZ2UgKSApIHsKCQkJJGV4aXN0aW5nX3RyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoKTsKCQkJUG86OmZyb21GaWxlKCAkdGhpcy0+bWVyZ2UsICRleGlzdGluZ190cmFuc2xhdGlvbnMgKTsKCQkJJHRyYW5zbGF0aW9ucy0+bWVyZ2VXaXRoKCAkZXhpc3RpbmdfdHJhbnNsYXRpb25zLCBNZXJnZTo6QUREIHwgTWVyZ2U6OlJFTU9WRSApOwoJCX0KCgkJUG90R2VuZXJhdG9yOjpzZXRDb21tZW50QmVmb3JlSGVhZGVycyggJHRoaXMtPmdldF9maWxlX2NvbW1lbnQoKSApOwoKCQkkdGhpcy0+c2V0X2RlZmF1bHRfaGVhZGVycyggJHRyYW5zbGF0aW9ucyApOwoKCQkvLyBQT1QgZmlsZXMgaGF2ZSBubyBMYW5ndWFnZSBoZWFkZXIuCgkJJHRyYW5zbGF0aW9ucy0+ZGVsZXRlSGVhZGVyKCBUcmFuc2xhdGlvbnM6OkhFQURFUl9MQU5HVUFHRSApOwoKCQkvLyBPbmx5IHJlbGV2YW50IGZvciBQTyBmaWxlcywgbm90IFBPVCBmaWxlcy4KCQkkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoICdQTy1SZXZpc2lvbi1EYXRlJywgJ1lFQVItTU8tREEgSE86TUkrWk9ORScgKTsKCgkJaWYgKCAkdGhpcy0+ZG9tYWluICkgewoJCQkkdHJhbnNsYXRpb25zLT5zZXREb21haW4oICR0aGlzLT5kb21haW4gKTsKCQl9CgoJCXVuc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1ZlcnNpb24nXSwgJHRoaXMtPm1haW5fZmlsZV9kYXRhWydMaWNlbnNlJ10sICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnRG9tYWluIFBhdGgnXSwgJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUZXh0IERvbWFpbiddICk7CgoJCS8vIFNldCBlbnRyaWVzIGZyb20gbWFpbiBmaWxlIGRhdGEuCgkJZm9yZWFjaCAoICR0aGlzLT5tYWluX2ZpbGVfZGF0YSBhcyAkaGVhZGVyID0+ICRkYXRhICkgewoJCQlpZiAoIGVtcHR5KCAkZGF0YSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSR0cmFuc2xhdGlvbiA9IG5ldyBUcmFuc2xhdGlvbiggJycsICRkYXRhICk7CgoJCQlpZiAoIGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1RoZW1lIE5hbWUnXSApICkgewoJCQkJJHRyYW5zbGF0aW9uLT5hZGRFeHRyYWN0ZWRDb21tZW50KCBzcHJpbnRmKCAnJXMgb2YgdGhlIHRoZW1lJywgJGhlYWRlciApICk7CgkJCX0gZWxzZSB7CgkJCQkkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoIHNwcmludGYoICclcyBvZiB0aGUgcGx1Z2luJywgJGhlYWRlciApICk7CgkJCX0KCgkJCSR0cmFuc2xhdGlvbnNbXSA9ICR0cmFuc2xhdGlvbjsKCQl9CgoJCXRyeSB7CgkJCWlmICggISAkdGhpcy0+c2tpcF9waHAgKSB7CgkJCQkkb3B0aW9ucyA9IFsKCQkJCQkvLyBFeHRyYWN0ICdUZW1wbGF0ZSBOYW1lJyBoZWFkZXJzIGluIHRoZW1lIGZpbGVzLgoJCQkJCSd3cEV4dHJhY3RUZW1wbGF0ZXMnID0+IGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1RoZW1lIE5hbWUnXSApLAoJCQkJCSdpbmNsdWRlJyAgICAgICAgICAgID0+ICR0aGlzLT5pbmNsdWRlLAoJCQkJCSdleGNsdWRlJyAgICAgICAgICAgID0+ICR0aGlzLT5leGNsdWRlLAoJCQkJCSdleHRlbnNpb25zJyAgICAgICAgID0+IFsgJ3BocCcgXSwKCQkJCQknYWRkUmVmZXJlbmNlcycgICAgICA9PiAkdGhpcy0+bG9jYXRpb24sCgkJCQldOwoJCQkJUGhwQ29kZUV4dHJhY3Rvcjo6ZnJvbURpcmVjdG9yeSggJHRoaXMtPnNvdXJjZSwgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMgKTsKCQkJfQoKCQkJaWYgKCAhICR0aGlzLT5za2lwX2pzICkgewoJCQkJSnNDb2RlRXh0cmFjdG9yOjpmcm9tRGlyZWN0b3J5KAoJCQkJCSR0aGlzLT5zb3VyY2UsCgkJCQkJJHRyYW5zbGF0aW9ucywKCQkJCQlbCgkJCQkJCSdpbmNsdWRlJyAgICAgICA9PiAkdGhpcy0+aW5jbHVkZSwKCQkJCQkJJ2V4Y2x1ZGUnICAgICAgID0+ICR0aGlzLT5leGNsdWRlLAoJCQkJCQknZXh0ZW5zaW9ucycgICAgPT4gWyAnanMnLCAnanN4JyBdLAoJCQkJCQknYWRkUmVmZXJlbmNlcycgPT4gJHRoaXMtPmxvY2F0aW9uLAoJCQkJCV0KCQkJCSk7CgoJCQkJTWFwQ29kZUV4dHJhY3Rvcjo6ZnJvbURpcmVjdG9yeSgKCQkJCQkkdGhpcy0+c291cmNlLAoJCQkJCSR0cmFuc2xhdGlvbnMsCgkJCQkJWwoJCQkJCQknaW5jbHVkZScgICAgICAgPT4gJHRoaXMtPmluY2x1ZGUsCgkJCQkJCSdleGNsdWRlJyAgICAgICA9PiAkdGhpcy0+ZXhjbHVkZSwKCQkJCQkJJ2V4dGVuc2lvbnMnICAgID0+IFsgJ21hcCcgXSwKCQkJCQkJJ2FkZFJlZmVyZW5jZXMnID0+ICR0aGlzLT5sb2NhdGlvbiwKCQkJCQldCgkJCQkpOwoJCQl9CgoJCQlpZiAoICEgJHRoaXMtPnNraXBfYmxvY2tfanNvbiApIHsKCQkJCUJsb2NrRXh0cmFjdG9yOjpmcm9tRGlyZWN0b3J5KAoJCQkJCSR0aGlzLT5zb3VyY2UsCgkJCQkJJHRyYW5zbGF0aW9ucywKCQkJCQlbCgkJCQkJCS8vIE9ubHkgbG9vayBmb3IgYmxvY2suanNvbiBmaWxlcywgbm90aGluZyBlbHNlLgoJCQkJCQkncmVzdHJpY3RGaWxlTmFtZXMnID0+IFsgJ2Jsb2NrLmpzb24nIF0sCgkJCQkJCSdpbmNsdWRlJyAgICAgICAgICAgPT4gJHRoaXMtPmluY2x1ZGUsCgkJCQkJCSdleGNsdWRlJyAgICAgICAgICAgPT4gJHRoaXMtPmV4Y2x1ZGUsCgkJCQkJCSdleHRlbnNpb25zJyAgICAgICAgPT4gWyAnanNvbicgXSwKCQkJCQkJJ2FkZFJlZmVyZW5jZXMnICAgICA9PiAkdGhpcy0+bG9jYXRpb24sCgkJCQkJXQoJCQkJKTsKCQkJfQoKCQkJaWYgKCAhICR0aGlzLT5za2lwX3RoZW1lX2pzb24gKSB7CgkJCQlUaGVtZUpzb25FeHRyYWN0b3I6OmZyb21EaXJlY3RvcnkoCgkJCQkJJHRoaXMtPnNvdXJjZSwKCQkJCQkkdHJhbnNsYXRpb25zLAoJCQkJCVsKCQkJCQkJLy8gT25seSBsb29rIGZvciB0aGVtZS5qc29uIGZpbGVzLCBub3RoaW5nIGVsc2UuCgkJCQkJCSdyZXN0cmljdEZpbGVOYW1lcycgPT4gWyAndGhlbWUuanNvbicgXSwKCQkJCQkJJ2luY2x1ZGUnICAgICAgICAgICA9PiAkdGhpcy0+aW5jbHVkZSwKCQkJCQkJJ2V4Y2x1ZGUnICAgICAgICAgICA9PiAkdGhpcy0+ZXhjbHVkZSwKCQkJCQkJJ2V4dGVuc2lvbnMnICAgICAgICA9PiBbICdqc29uJyBdLAoJCQkJCV0KCQkJCSk7CgkJCX0KCQl9IGNhdGNoICggXEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJZm9yZWFjaCAoICR0aGlzLT5leGNlcHRpb25zIGFzICRmaWxlID0+ICRleGNlcHRpb25fdHJhbnNsYXRpb25zICkgewoJCQkvKiogQHZhciBUcmFuc2xhdGlvbiAkZXhjZXB0aW9uX3RyYW5zbGF0aW9uICovCgkJCWZvcmVhY2ggKCAkZXhjZXB0aW9uX3RyYW5zbGF0aW9ucyBhcyAkZXhjZXB0aW9uX3RyYW5zbGF0aW9uICkgewoJCQkJaWYgKCAhICR0cmFuc2xhdGlvbnMtPmZpbmQoICRleGNlcHRpb25fdHJhbnNsYXRpb24gKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoICR0aGlzLT5zdWJ0cmFjdF9hbmRfbWVyZ2UgKSB7CgkJCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uc1sgJGV4Y2VwdGlvbl90cmFuc2xhdGlvbi0+Z2V0SWQoKSBdOwoJCQkJCSRleGNlcHRpb25fdHJhbnNsYXRpb24tPm1lcmdlV2l0aCggJHRyYW5zbGF0aW9uICk7CgkJCQl9CgoJCQkJdW5zZXQoICR0cmFuc2xhdGlvbnNbICRleGNlcHRpb25fdHJhbnNsYXRpb24tPmdldElkKCkgXSApOwoJCQl9CgoJCQlpZiAoICR0aGlzLT5zdWJ0cmFjdF9hbmRfbWVyZ2UgKSB7CgkJCQlQb3RHZW5lcmF0b3I6OnRvRmlsZSggJGV4Y2VwdGlvbl90cmFuc2xhdGlvbnMsICRmaWxlICk7CgkJCX0KCQl9CgoJCWlmICggISAkdGhpcy0+c2tpcF9hdWRpdCApIHsKCQkJJHRoaXMtPmF1ZGl0X3N0cmluZ3MoICR0cmFuc2xhdGlvbnMgKTsKCQl9CgoJCXJldHVybiAkdHJhbnNsYXRpb25zOwoJfQoKCS8qKgoJICogQXVkaXRzIHN0cmluZ3MuCgkgKgoJICogR29lcyB0aHJvdWdoIGFsbCBleHRyYWN0ZWQgc3RyaW5ncyB0byBmaW5kIHBvc3NpYmxlIG1pc3Rha2VzLgoJICoKCSAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucyBUcmFuc2xhdGlvbnMgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYXVkaXRfc3RyaW5ncyggJHRyYW5zbGF0aW9ucyApIHsKCQlmb3JlYWNoICggJHRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24gKSB7CgkJCS8qKiBAdmFyIFRyYW5zbGF0aW9uICR0cmFuc2xhdGlvbiAqLwoKCQkJJHJlZmVyZW5jZXMgPSAkdHJhbnNsYXRpb24tPmdldFJlZmVyZW5jZXMoKTsKCgkJCS8vIEZpbGUgaGVhZGVycyBkb24ndCBoYXZlIGFueSBmaWxlIHJlZmVyZW5jZXMuCgkJCSRsb2NhdGlvbiA9ICR0cmFuc2xhdGlvbi0+aGFzUmVmZXJlbmNlcygpID8gJygnIC4gaW1wbG9kZSggJzonLCBhcnJheV9zaGlmdCggJHJlZmVyZW5jZXMgKSApIC4gJyknIDogJyc7CgoJCQkvLyBDaGVjayAxOiBGbGFnIHN0cmluZ3Mgd2l0aCBwbGFjZWhvbGRlcnMgdGhhdCBzaG91bGQgaGF2ZSB0cmFuc2xhdG9yIGNvbW1lbnRzLgoJCQlpZiAoCgkJCQkhICR0cmFuc2xhdGlvbi0+aGFzRXh0cmFjdGVkQ29tbWVudHMoKSAmJgoJCQkJcHJlZ19tYXRjaCggc2VsZjo6U1BSSU5URl9QTEFDRUhPTERFUl9SRUdFWCwgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLCAkcGxhY2Vob2xkZXJzICkgPj0gMQoJCQkpIHsKCQkJCSRtZXNzYWdlID0gc3ByaW50ZigKCQkJCQknVGhlIHN0cmluZyAiJTEkcyIgY29udGFpbnMgcGxhY2Vob2xkZXJzIGJ1dCBoYXMgbm8gInRyYW5zbGF0b3JzOiIgY29tbWVudCB0byBjbGFyaWZ5IHRoZWlyIG1lYW5pbmcuICUyJHMnLAoJCQkJCSR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKSwKCQkJCQkkbG9jYXRpb24KCQkJCSk7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRtZXNzYWdlICk7CgkJCX0KCgkJCS8vIENoZWNrIDI6IEZsYWcgc3RyaW5ncyB3aXRoIGRpZmZlcmVudCB0cmFuc2xhdG9yIGNvbW1lbnRzLgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzRXh0cmFjdGVkQ29tbWVudHMoKSApIHsKCQkJCSRjb21tZW50cyA9ICR0cmFuc2xhdGlvbi0+Z2V0RXh0cmFjdGVkQ29tbWVudHMoKTsKCgkJCQkvLyBSZW1vdmUgcGx1Z2luIGhlYWRlciBpbmZvcm1hdGlvbiBmcm9tIGNvbW1lbnRzLgoJCQkJJGNvbW1lbnRzID0gYXJyYXlfZmlsdGVyKAoJCQkJCSRjb21tZW50cywKCQkJCQlmdW5jdGlvbiAoICRjb21tZW50ICkgewoJCQkJCQkvKiogQHZhciBQYXJzZWRDb21tZW50fHN0cmluZyAkY29tbWVudCAqLwoJCQkJCQkvKiogQHZhciBzdHJpbmcgJGZpbGVfaGVhZGVyICovCgkJCQkJCWZvcmVhY2ggKCAkdGhpcy0+Z2V0X2ZpbGVfaGVhZGVycyggJHRoaXMtPnByb2plY3RfdHlwZSApIGFzICRmaWxlX2hlYWRlciApIHsKCQkJCQkJCWlmICggMCA9PT0gc3RycG9zKCAoICRjb21tZW50IGluc3RhbmNlb2YgUGFyc2VkQ29tbWVudCA/ICRjb21tZW50LT5nZXRDb21tZW50KCkgOiAkY29tbWVudCApLCAkZmlsZV9oZWFkZXIgKSApIHsKCQkJCQkJCQlyZXR1cm4gbnVsbDsKCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJcmV0dXJuICRjb21tZW50OwoJCQkJCX0KCQkJCSk7CgoJCQkJJHVuaXF1ZV9jb21tZW50cyA9IGFycmF5KCk7CgoJCQkJLy8gUmVtb3ZlIGR1cGxpY2F0ZSBjb21tZW50cy4KCQkJCSRjb21tZW50cyA9IGFycmF5X2ZpbHRlcigKCQkJCQkkY29tbWVudHMsCgkJCQkJZnVuY3Rpb24gKCAkY29tbWVudCApIHVzZSAoICYkdW5pcXVlX2NvbW1lbnRzICkgewoJCQkJCQkvKiogQHZhciBQYXJzZWRDb21tZW50fHN0cmluZyAkY29tbWVudCAqLwoJCQkJCQlpZiAoIGluX2FycmF5KCAoICRjb21tZW50IGluc3RhbmNlb2YgUGFyc2VkQ29tbWVudCA/ICRjb21tZW50LT5nZXRDb21tZW50KCkgOiAkY29tbWVudCApLCAkdW5pcXVlX2NvbW1lbnRzLCB0cnVlICkgKSB7CgkJCQkJCQlyZXR1cm4gbnVsbDsKCQkJCQkJfQoKCQkJCQkJJHVuaXF1ZV9jb21tZW50c1tdID0gKCAkY29tbWVudCBpbnN0YW5jZW9mIFBhcnNlZENvbW1lbnQgPyAkY29tbWVudC0+Z2V0Q29tbWVudCgpIDogJGNvbW1lbnQgKTsKCgkJCQkJCXJldHVybiAkY29tbWVudDsKCQkJCQl9CgkJCQkpOwoKCQkJCSRjb21tZW50c19jb3VudCA9IGNvdW50KCAkY29tbWVudHMgKTsKCgkJCQlpZiAoICRjb21tZW50c19jb3VudCA+IDEgKSB7CgkJCQkJJG1lc3NhZ2UgPSBzcHJpbnRmKAoJCQkJCQknVGhlIHN0cmluZyAiJTEkcyIgaGFzICUyJGQgZGlmZmVyZW50IHRyYW5zbGF0b3IgY29tbWVudHMuICUzJHMnLAoJCQkJCQkkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCksCgkJCQkJCSRjb21tZW50c19jb3VudCwKCQkJCQkJJGxvY2F0aW9uCgkJCQkJKTsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICRtZXNzYWdlICk7CgkJCQl9CgkJCX0KCgkJCSRub25fcGxhY2Vob2xkZXJfY29udGVudCA9IHRyaW0oIHByZWdfcmVwbGFjZSggJ2BeKFtcJyJdKSguKilcMSRgRHMnLCAnJDInLCAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCkgKSApOwoJCQkkbm9uX3BsYWNlaG9sZGVyX2NvbnRlbnQgPSBwcmVnX3JlcGxhY2UoIHNlbGY6OlNQUklOVEZfUExBQ0VIT0xERVJfUkVHRVgsICcnLCAkbm9uX3BsYWNlaG9sZGVyX2NvbnRlbnQgKTsKCgkJCS8vIENoZWNrIDM6IEZsYWcgZW1wdHkgc3RyaW5ncyB3aXRob3V0IGFueSB0cmFuc2xhdGFibGUgY29udGVudC4KCQkJaWYgKCAnJyA9PT0gJG5vbl9wbGFjZWhvbGRlcl9jb250ZW50ICkgewoJCQkJJG1lc3NhZ2UgPSBzcHJpbnRmKAoJCQkJCSdGb3VuZCBzdHJpbmcgd2l0aG91dCB0cmFuc2xhdGFibGUgY29udGVudC4gJXMnLAoJCQkJCSRsb2NhdGlvbgoJCQkJKTsKCQkJCVdQX0NMSTo6d2FybmluZyggJG1lc3NhZ2UgKTsKCQkJfQoKCQkJLy8gQ2hlY2sgNDogRmxhZyBzdHJpbmdzIHdpdGggbXVsdGlwbGUgdW5vcmRlcmVkIHBsYWNlaG9sZGVycyAoJXMgJXMgJXMgdnMuICUxJHMgJTIkcyAlMyRzKS4KCQkJJHVub3JkZXJlZF9tYXRjaGVzX2NvdW50ID0gcHJlZ19tYXRjaF9hbGwoIHNlbGY6OlVOT1JERVJFRF9TUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYLCAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCksICR1bm9yZGVyZWRfbWF0Y2hlcyApOwoJCQkkdW5vcmRlcmVkX21hdGNoZXMgICAgICAgPSAkdW5vcmRlcmVkX21hdGNoZXNbMF07CgoJCQlpZiAoICR1bm9yZGVyZWRfbWF0Y2hlc19jb3VudCA+PSAyICkgewoJCQkJJG1lc3NhZ2UgPSBzcHJpbnRmKAoJCQkJCSdNdWx0aXBsZSBwbGFjZWhvbGRlcnMgc2hvdWxkIGJlIG9yZGVyZWQuICVzJywKCQkJCQkkbG9jYXRpb24KCQkJCSk7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRtZXNzYWdlICk7CgkJCX0KCgkJCWlmICggJHRyYW5zbGF0aW9uLT5oYXNQbHVyYWwoKSApIHsKCQkJCXByZWdfbWF0Y2hfYWxsKCBzZWxmOjpTUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYLCAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCksICRzaW5nbGVfcGxhY2Vob2xkZXJzICk7CgkJCQkkc2luZ2xlX3BsYWNlaG9sZGVycyA9ICRzaW5nbGVfcGxhY2Vob2xkZXJzWzBdOwoKCQkJCXByZWdfbWF0Y2hfYWxsKCBzZWxmOjpTUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYLCAkdHJhbnNsYXRpb24tPmdldFBsdXJhbCgpLCAkcGx1cmFsX3BsYWNlaG9sZGVycyApOwoJCQkJJHBsdXJhbF9wbGFjZWhvbGRlcnMgPSAkcGx1cmFsX3BsYWNlaG9sZGVyc1swXTsKCgkJCQkvLyBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9wbHVnaW5zL2ludGVybmF0aW9uYWxpemF0aW9uL2hvdy10by1pbnRlcm5hdGlvbmFsaXplLXlvdXItcGx1Z2luLyNwbHVyYWxzCgkJCQlpZiAoIGNvdW50KCAkc2luZ2xlX3BsYWNlaG9sZGVycyApIDwgY291bnQoICRwbHVyYWxfcGxhY2Vob2xkZXJzICkgKSB7CgkJCQkJLy8gQ2hlY2sgNTogRmxhZyB0aGluZ3MgbGlrZSBfbiggJ09uZSBjb21tZW50JywgJyVzIENvbW1lbnRzJyApCgkJCQkJJG1lc3NhZ2UgPSBzcHJpbnRmKAoJCQkJCQknTWlzc2luZyBzaW5ndWxhciBwbGFjZWhvbGRlciwgbmVlZGVkIGZvciBzb21lIGxhbmd1YWdlcy4gU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvcGx1Z2lucy9pbnRlcm5hdGlvbmFsaXphdGlvbi9ob3ctdG8taW50ZXJuYXRpb25hbGl6ZS15b3VyLXBsdWdpbi8jcGx1cmFscyAlcycsCgkJCQkJCSRsb2NhdGlvbgoJCQkJCSk7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkbWVzc2FnZSApOwoJCQkJfSBlbHNlIHsKCQkJCQkvLyBSZW9yZGVyaW5nIGlzIGZpbmUsIGJ1dCBtaXNtYXRjaGVkIHBsYWNlaG9sZGVycyBpcyBwcm9iYWJseSB3cm9uZy4KCQkJCQlzb3J0KCAkc2luZ2xlX3BsYWNlaG9sZGVycyApOwoJCQkJCXNvcnQoICRwbHVyYWxfcGxhY2Vob2xkZXJzICk7CgoJCQkJCS8vIENoZWNrIDY6IEZsYWcgdGhpbmdzIGxpa2UgX24oICclcyBDb21tZW50ICglZCknLCAnJXMgQ29tbWVudHMgKCVzKScgKQoJCQkJCWlmICggJHNpbmdsZV9wbGFjZWhvbGRlcnMgIT09ICRwbHVyYWxfcGxhY2Vob2xkZXJzICkgewoJCQkJCQkkbWVzc2FnZSA9IHNwcmludGYoCgkJCQkJCQknTWlzbWF0Y2hlZCBwbGFjZWhvbGRlcnMgZm9yIHNpbmd1bGFyIGFuZCBwbHVyYWwgc3RyaW5nLiAlcycsCgkJCQkJCQkkbG9jYXRpb24KCQkJCQkJKTsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkbWVzc2FnZSApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGNvcHlyaWdodCBjb21tZW50IGZvciB0aGUgZ2l2ZW4gcGFja2FnZS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBGaWxlIGNvbW1lbnQuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZmlsZV9jb21tZW50KCkgewoJCWlmICggJycgPT09ICR0aGlzLT5maWxlX2NvbW1lbnQgKSB7CgkJCXJldHVybiAnJzsKCQl9CgoJCWlmICggaXNzZXQoICR0aGlzLT5maWxlX2NvbW1lbnQgKSApIHsKCQkJcmV0dXJuIGltcGxvZGUoICJcbiIsIGV4cGxvZGUoICdcbicsICR0aGlzLT5maWxlX2NvbW1lbnQgKSApOwoJCX0KCgkJaWYgKCBpc3NldCggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUaGVtZSBOYW1lJ10gKSApIHsKCQkJaWYgKCBpc3NldCggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydMaWNlbnNlJ10gKSApIHsKCQkJCXJldHVybiBzcHJpbnRmKAoJCQkJCSJDb3B5cmlnaHQgKEMpICUxXCRzICUyXCRzXG5UaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlICUzXCRzLiIsCgkJCQkJZGF0ZSggJ1knICksIC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkJCQkkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0F1dGhvciddLAoJCQkJCSR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnTGljZW5zZSddCgkJCQkpOwoJCQl9CgoJCQlyZXR1cm4gc3ByaW50ZigKCQkJCSJDb3B5cmlnaHQgKEMpICUxXCRzICUyXCRzXG5UaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHNhbWUgbGljZW5zZSBhcyB0aGUgJTNcJHMgdGhlbWUuIiwKCQkJCWRhdGUoICdZJyApLCAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJCQkkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0F1dGhvciddLAoJCQkJJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUaGVtZSBOYW1lJ10KCQkJKTsKCQl9CgoJCWlmICggaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnUGx1Z2luIE5hbWUnXSApICkgewoJCQlpZiAoIGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0xpY2Vuc2UnXSApICYmICEgZW1wdHkoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnTGljZW5zZSddICkgKSB7CgkJCQlyZXR1cm4gc3ByaW50ZigKCQkJCQkiQ29weXJpZ2h0IChDKSAlMVwkcyAlMlwkc1xuVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSAlM1wkcy4iLAoJCQkJCWRhdGUoICdZJyApLCAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJCQkJJHRoaXMtPm1haW5fZmlsZV9kYXRhWydBdXRob3InXSwKCQkJCQkkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0xpY2Vuc2UnXQoJCQkJKTsKCQkJfQoKCQkJcmV0dXJuIHNwcmludGYoCgkJCQkiQ29weXJpZ2h0IChDKSAlMVwkcyAlMlwkc1xuVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBzYW1lIGxpY2Vuc2UgYXMgdGhlICUzXCRzIHBsdWdpbi4iLAoJCQkJZGF0ZSggJ1knICksIC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkJCSR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnQXV0aG9yJ10sCgkJCQkkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1BsdWdpbiBOYW1lJ10KCQkJKTsKCQl9CgoJCXJldHVybiAnJzsKCX0KCgkvKioKCSAqIFNldHMgZGVmYXVsdCBQT1QgZmlsZSBoZWFkZXJzIGZvciB0aGUgcHJvamVjdC4KCSAqCgkgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMgVHJhbnNsYXRpb25zIG9iamVjdC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9kZWZhdWx0X2hlYWRlcnMoICR0cmFuc2xhdGlvbnMgKSB7CgkJJG5hbWUgICAgICAgICA9IG51bGw7CgkJJHZlcnNpb24gICAgICA9ICR0aGlzLT5nZXRfd3BfdmVyc2lvbigpOwoJCSRidWdzX2FkZHJlc3MgPSBudWxsOwoKCQlpZiAoICEgJHZlcnNpb24gJiYgaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVmVyc2lvbiddICkgKSB7CgkJCSR2ZXJzaW9uID0gJHRoaXMtPm1haW5fZmlsZV9kYXRhWydWZXJzaW9uJ107CgkJfQoKCQlpZiAoIGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1RoZW1lIE5hbWUnXSApICkgewoJCQkkbmFtZSAgICAgICAgID0gJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUaGVtZSBOYW1lJ107CgkJCSRidWdzX2FkZHJlc3MgPSBzcHJpbnRmKCAnaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3N1cHBvcnQvdGhlbWUvJXMnLCAkdGhpcy0+c2x1ZyApOwoJCX0gZWxzZWlmICggaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnUGx1Z2luIE5hbWUnXSApICkgewoJCQkkbmFtZSAgICAgICAgID0gJHRoaXMtPm1haW5fZmlsZV9kYXRhWydQbHVnaW4gTmFtZSddOwoJCQkkYnVnc19hZGRyZXNzID0gc3ByaW50ZiggJ2h0dHBzOi8vd29yZHByZXNzLm9yZy9zdXBwb3J0L3BsdWdpbi8lcycsICR0aGlzLT5zbHVnICk7CgkJfQoKCQlpZiAoIG51bGwgIT09ICR0aGlzLT5wYWNrYWdlX25hbWUgKSB7CgkJCSRuYW1lID0gJHRoaXMtPnBhY2thZ2VfbmFtZTsKCQl9CgoJCWlmICggbnVsbCAhPT0gJG5hbWUgKSB7CgkJCSR0cmFuc2xhdGlvbnMtPnNldEhlYWRlciggJ1Byb2plY3QtSWQtVmVyc2lvbicsICRuYW1lIC4gKCAkdmVyc2lvbiA/ICcgJyAuICR2ZXJzaW9uIDogJycgKSApOwoJCX0KCgkJaWYgKCBudWxsICE9PSAkYnVnc19hZGRyZXNzICkgewoJCQkkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoICdSZXBvcnQtTXNnaWQtQnVncy1UbycsICRidWdzX2FkZHJlc3MgKTsKCQl9CgoJCSR0cmFuc2xhdGlvbnMtPnNldEhlYWRlciggJ0xhc3QtVHJhbnNsYXRvcicsICdGVUxMIE5BTUUgPEVNQUlMQEFERFJFU1M+JyApOwoJCSR0cmFuc2xhdGlvbnMtPnNldEhlYWRlciggJ0xhbmd1YWdlLVRlYW0nLCAnTEFOR1VBR0UgPExMQGxpLm9yZz4nICk7CgkJJHRyYW5zbGF0aW9ucy0+c2V0SGVhZGVyKCAnWC1HZW5lcmF0b3InLCAnV1AtQ0xJICcgLiBXUF9DTElfVkVSU0lPTiApOwoKCQlmb3JlYWNoICggJHRoaXMtPmhlYWRlcnMgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCSR0cmFuc2xhdGlvbnMtPnNldEhlYWRlciggJGtleSwgJHZhbHVlICk7CgkJfQoJfQoKCS8qKgoJICogRXh0cmFjdHMgdGhlIFdvcmRQcmVzcyB2ZXJzaW9uIG51bWJlciBmcm9tIHdwLWluY2x1ZGVzL3ZlcnNpb24ucGhwLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFZlcnNpb24gbnVtYmVyIG9uIHN1Y2Nlc3MsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF93cF92ZXJzaW9uKCkgewoJCSR2ZXJzaW9uX3BocCA9ICR0aGlzLT5zb3VyY2UgLiAnL3dwLWluY2x1ZGVzL3ZlcnNpb24ucGhwJzsKCQlpZiAoICEgZmlsZV9leGlzdHMoICR2ZXJzaW9uX3BocCApIHx8ICEgaXNfcmVhZGFibGUoICR2ZXJzaW9uX3BocCApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gcHJlZ19tYXRjaCggJy9cJHdwX3ZlcnNpb25ccyo9XHMqXCcoLio/KVwnOy8nLCBmaWxlX2dldF9jb250ZW50cyggJHZlcnNpb25fcGhwICksICRtYXRjaGVzICkgPyAkbWF0Y2hlc1sxXSA6IGZhbHNlOwoJfQoKCS8qKgoJICogUmV0cmlldmVzIG1ldGFkYXRhIGZyb20gYSBmaWxlLgoJICoKCSAqIFNlYXJjaGVzIGZvciBtZXRhZGF0YSBpbiB0aGUgZmlyc3QgOGtpQiBvZiBhIGZpbGUsIHN1Y2ggYXMgYSBwbHVnaW4gb3IgdGhlbWUuCgkgKiBFYWNoIHBpZWNlIG9mIG1ldGFkYXRhIG11c3QgYmUgb24gaXRzIG93biBsaW5lLiBGaWVsZHMgY2FuIG5vdCBzcGFuIG11bHRpcGxlCgkgKiBsaW5lcywgdGhlIHZhbHVlIHdpbGwgZ2V0IGN1dCBhdCB0aGUgZW5kIG9mIHRoZSBmaXJzdCBsaW5lLgoJICoKCSAqIElmIHRoZSBmaWxlIGRhdGEgaXMgbm90IHdpdGhpbiB0aGF0IGZpcnN0IDhraUIsIHRoZW4gdGhlIGF1dGhvciBzaG91bGQgY29ycmVjdAoJICogdGhlaXIgcGx1Z2luIGZpbGUgYW5kIG1vdmUgdGhlIGRhdGEgaGVhZGVycyB0byB0aGUgdG9wLgoJICoKCSAqIEBzZWUgZ2V0X2ZpbGVfZGF0YSgpCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZmlsZSBQYXRoIHRvIHRoZSBmaWxlLgoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIExpc3Qgb2YgaGVhZGVycywgaW4gdGhlIGZvcm1hdCBhcnJheSgnSGVhZGVyS2V5JyA9PiAnSGVhZGVyIE5hbWUnKS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIGZpbGUgaGVhZGVycyBpbiBgSGVhZGVyS2V5ID0+IEhlYWRlciBWYWx1ZWAgZm9ybWF0LgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF9maWxlX2RhdGEoICRmaWxlLCAkaGVhZGVycyApIHsKCQkvLyBXZSBkb24ndCBuZWVkIHRvIHdyaXRlIHRvIHRoZSBmaWxlLCBzbyBqdXN0IG9wZW4gZm9yIHJlYWRpbmcuCgkJJGZwID0gZm9wZW4oICRmaWxlLCAncmInICk7CgoJCS8vIFB1bGwgb25seSB0aGUgZmlyc3QgOGtpQiBvZiB0aGUgZmlsZSBpbi4KCQkkZmlsZV9kYXRhID0gZnJlYWQoICRmcCwgODE5MiApOwoKCQkvLyBQSFAgd2lsbCBjbG9zZSBmaWxlIGhhbmRsZSwgYnV0IHdlIGFyZSBnb29kIGNpdGl6ZW5zLgoJCWZjbG9zZSggJGZwICk7CgoJCS8vIE1ha2Ugc3VyZSB3ZSBjYXRjaCBDUi1vbmx5IGxpbmUgZW5kaW5ncy4KCQkkZmlsZV9kYXRhID0gc3RyX3JlcGxhY2UoICJcciIsICJcbiIsICRmaWxlX2RhdGEgKTsKCgkJcmV0dXJuIHN0YXRpYzo6Z2V0X2ZpbGVfZGF0YV9mcm9tX3N0cmluZyggJGZpbGVfZGF0YSwgJGhlYWRlcnMgKTsKCX0KCgkvKioKCSAqIFJldHJpZXZlcyBtZXRhZGF0YSBmcm9tIGEgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBTdHJpbmcgdG8gbG9vayBmb3IgbWV0YWRhdGEgaW4uCgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgTGlzdCBvZiBoZWFkZXJzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgb2YgZmlsZSBoZWFkZXJzIGluIGBIZWFkZXJLZXkgPT4gSGVhZGVyIFZhbHVlYCBmb3JtYXQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X2ZpbGVfZGF0YV9mcm9tX3N0cmluZyggJHN0cmluZywgJGhlYWRlcnMgKSB7CgkJZm9yZWFjaCAoICRoZWFkZXJzIGFzICRmaWVsZCA9PiAkcmVnZXggKSB7CgkJCWlmICggcHJlZ19tYXRjaCggJy9eWyBcdFwvKiNAXSonIC4gcHJlZ19xdW90ZSggJHJlZ2V4LCAnLycgKSAuICc6KC4qKSQvbWknLCAkc3RyaW5nLCAkbWF0Y2ggKSAmJiAkbWF0Y2hbMV0gKSB7CgkJCQkkaGVhZGVyc1sgJGZpZWxkIF0gPSBzdGF0aWM6Ol9jbGVhbnVwX2hlYWRlcl9jb21tZW50KCAkbWF0Y2hbMV0gKTsKCQkJfSBlbHNlIHsKCQkJCSRoZWFkZXJzWyAkZmllbGQgXSA9ICcnOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGhlYWRlcnM7Cgl9CgoJLyoqCgkgKiBTdHJpcCBjbG9zZSBjb21tZW50IGFuZCBjbG9zZSBwaHAgdGFncyBmcm9tIGZpbGUgaGVhZGVycyB1c2VkIGJ5IFdQLgoJICoKCSAqIEBzZWUgX2NsZWFudXBfaGVhZGVyX2NvbW1lbnQoKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0ciBIZWFkZXIgY29tbWVudCB0byBjbGVhbiB1cC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIF9jbGVhbnVwX2hlYWRlcl9jb21tZW50KCAkc3RyICkgeyAvLyBwaHBjczppZ25vcmUgUFNSMi5NZXRob2RzLk1ldGhvZERlY2xhcmF0aW9uLlVuZGVyc2NvcmUgLS0gTm90IGNoYW5naW5nIGJlY2F1c2UgdGhpcmQtcGFydHkgY29tbWFuZHMgbWlnaHQgdXNlL2V4dGVuZC4KCQlyZXR1cm4gdHJpbSggcHJlZ19yZXBsYWNlKCAnL1xzKig/OlwqXC98XD8+KS4qLycsICcnLCAkc3RyICkgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcR2VuZXJhdG9yc1xQbyBhcyBQb0dlbmVyYXRvcjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xQYXJzZWRDb21tZW50OwoKLyoqCiAqIFBPVCBmaWxlIGdlbmVyYXRvci4KICoKICogVGhlIG9ubHkgZGlmZmVyZW5jZSB0byB0aGUgZXhpc3RpbmcgUE8gZmlsZSBnZW5lcmF0b3IgaXMgdGhhdCB0aGlzCiAqIGFkZHMgc29tZSBjb21tZW50cyBhdCB0aGUgdmVyeSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUuCiAqLwpjbGFzcyBQb3RHZW5lcmF0b3IgZXh0ZW5kcyBQb0dlbmVyYXRvciB7Cglwcm90ZWN0ZWQgc3RhdGljICRjb21tZW50c19iZWZvcmVfaGVhZGVycyA9IFtdOwoKCS8qKgoJICogVGV4dCB0byBpbmNsdWRlIGFzIGEgY29tbWVudCBiZWZvcmUgdGhlIHN0YXJ0IG9mIHRoZSBQTyBjb250ZW50cwoJICoKCSAqIERvZXNuJ3QgbmVlZCB0byBpbmNsdWRlICMgaW4gdGhlIGJlZ2lubmluZyBvZiBsaW5lcywgdGhlc2UgYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29tbWVudCBGaWxlIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0Q29tbWVudEJlZm9yZUhlYWRlcnMoICRjb21tZW50ICkgewoJCSRjb21tZW50cyA9IGV4cGxvZGUoICJcbiIsICRjb21tZW50ICk7CgoJCWZvcmVhY2ggKCAkY29tbWVudHMgYXMgJGxpbmUgKSB7CgkJCWlmICggJycgIT09IHRyaW0oICRsaW5lICkgKSB7CgkJCQlzdGF0aWM6OiRjb21tZW50c19iZWZvcmVfaGVhZGVyc1tdID0gJyMgJyAuICRsaW5lOwoJCQl9CgkJfQoJfQoKCS8qKgoJICoge0BwYXJlbnREb2N9LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSApIHsKCQkkbGluZXMgICA9IHN0YXRpYzo6JGNvbW1lbnRzX2JlZm9yZV9oZWFkZXJzOwoJCSRsaW5lc1tdID0gJ21zZ2lkICIiJzsKCQkkbGluZXNbXSA9ICdtc2dzdHIgIiInOwoKCQkkcGx1cmFsX2Zvcm0gPSAkdHJhbnNsYXRpb25zLT5nZXRQbHVyYWxGb3JtcygpOwoJCSRwbHVyYWxfc2l6ZSA9IGlzX2FycmF5KCAkcGx1cmFsX2Zvcm0gKSA/ICggJHBsdXJhbF9mb3JtWzBdIC0gMSApIDogMTsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUgKSB7CgkJCSRsaW5lc1tdID0gc3ByaW50ZiggJyIlczogJXNcXG4iJywgJG5hbWUsICR2YWx1ZSApOwoJCX0KCgkJJGxpbmVzW10gPSAnJzsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uICkgewoJCQkvKiogQHZhciBcR2V0dGV4dFxUcmFuc2xhdGlvbiAkdHJhbnNsYXRpb24gKi8KCQkJaWYgKCAkdHJhbnNsYXRpb24tPmhhc0NvbW1lbnRzKCkgKSB7CgkJCQlmb3JlYWNoICggJHRyYW5zbGF0aW9uLT5nZXRDb21tZW50cygpIGFzICRjb21tZW50ICkgewoJCQkJCSRsaW5lc1tdID0gJyMgJyAuICRjb21tZW50OwoJCQkJfQoJCQl9CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzRXh0cmFjdGVkQ29tbWVudHMoKSApIHsKCQkJCSR1bmlxdWVfY29tbWVudHMgPSBhcnJheSgpOwoKCQkJCS8qKiBAdmFyIFBhcnNlZENvbW1lbnR8c3RyaW5nICRjb21tZW50ICovCgkJCQlmb3JlYWNoICggJHRyYW5zbGF0aW9uLT5nZXRFeHRyYWN0ZWRDb21tZW50cygpIGFzICRjb21tZW50ICkgewoJCQkJCSRjb21tZW50ID0gKCAkY29tbWVudCBpbnN0YW5jZW9mIFBhcnNlZENvbW1lbnQgPyAkY29tbWVudC0+Z2V0Q29tbWVudCgpIDogJGNvbW1lbnQgKTsKCQkJCQlpZiAoICEgaW5fYXJyYXkoICRjb21tZW50LCAkdW5pcXVlX2NvbW1lbnRzLCB0cnVlICkgKSB7CgkJCQkJCSRsaW5lc1tdICAgICAgICAgICA9ICcjLiAnIC4gJGNvbW1lbnQ7CgkJCQkJCSR1bmlxdWVfY29tbWVudHNbXSA9ICRjb21tZW50OwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbi0+Z2V0UmVmZXJlbmNlcygpIGFzICRyZWZlcmVuY2UgKSB7CgkJCQkkbGluZXNbXSA9ICcjOiAnIC4gJHJlZmVyZW5jZVswXSAuICggbnVsbCAhPT0gJHJlZmVyZW5jZVsxXSA/ICc6JyAuICRyZWZlcmVuY2VbMV0gOiAnJyApOwoJCQl9CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzRmxhZ3MoKSApIHsKCQkJCSRsaW5lc1tdID0gJyMsICcgLiBpbXBsb2RlKCAnLCcsICR0cmFuc2xhdGlvbi0+Z2V0RmxhZ3MoKSApOwoJCQl9CgoJCQkkcHJlZml4ID0gJHRyYW5zbGF0aW9uLT5pc0Rpc2FibGVkKCkgPyAnI34gJyA6ICcnOwoKCQkJaWYgKCAkdHJhbnNsYXRpb24tPmhhc0NvbnRleHQoKSApIHsKCQkJCSRsaW5lc1tdID0gJHByZWZpeCAuICdtc2djdHh0ICcgLiBzZWxmOjpjb252ZXJ0U3RyaW5nKCAkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKSApOwoJCQl9CgoJCQlzZWxmOjphZGRMaW5lcyggJGxpbmVzLCAkcHJlZml4IC4gJ21zZ2lkJywgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpICk7CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsKCkgKSB7CgkJCQlzZWxmOjphZGRMaW5lcyggJGxpbmVzLCAkcHJlZml4IC4gJ21zZ2lkX3BsdXJhbCcsICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsKCkgKTsKCgkJCQlmb3IgKCAkaSA9IDA7ICRpIDw9ICRwbHVyYWxfc2l6ZTsgJGkgKysgKSB7CgkJCQkJc2VsZjo6YWRkTGluZXMoICRsaW5lcywgJHByZWZpeCAuICdtc2dzdHJbJyAuICRpIC4gJ10nLCAnJyApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJc2VsZjo6YWRkTGluZXMoICRsaW5lcywgJHByZWZpeCAuICdtc2dzdHInLCAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCkgKTsKCQkJfQoKCQkJJGxpbmVzW10gPSAnJzsKCQl9CgoJCXJldHVybiBpbXBsb2RlKCAiXG4iLCAkbGluZXMgKTsKCX0KCgkvKioKCSAqIEVzY2FwZXMgYW5kIGFkZHMgZG91YmxlIHF1b3RlcyB0byBhIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgTXVsdGlsaW5lIHN0cmluZy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ1tdCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gbXVsdGlsaW5lUXVvdGUoICRzdHJpbmcgKSB7CgkJJGxpbmVzID0gZXhwbG9kZSggIlxuIiwgJHN0cmluZyApOwoJCSRsYXN0ICA9IGNvdW50KCAkbGluZXMgKSAtIDE7CgoJCWZvcmVhY2ggKCAkbGluZXMgYXMgJGsgPT4gJGxpbmUgKSB7CgkJCWlmICggJGsgPT09ICRsYXN0ICkgewoJCQkJJGxpbmVzWyAkayBdID0gc2VsZjo6Y29udmVydFN0cmluZyggJGxpbmUgKTsKCQkJfSBlbHNlIHsKCQkJCSRsaW5lc1sgJGsgXSA9IHNlbGY6OmNvbnZlcnRTdHJpbmcoICRsaW5lIC4gIlxuIiApOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGxpbmVzOwoJfQoKCS8qKgoJICogQWRkIG9uZSBvciBtb3JlIGxpbmVzIGRlcGVuZGluZyB3aGV0aGVyIHRoZSBzdHJpbmcgaXMgbXVsdGlsaW5lIG9yIG5vdC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICYkbGluZXMgQXJyYXkgbGluZXMgc2hvdWxkIGJlIGFkZGVkIHRvLgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSAgIE5hbWUgb2YgdGhlIGxpbmUsIGUuZy4gbXNnc3RyIG9yIG1zZ2lkX3BsdXJhbC4KCSAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlICBUaGUgbGluZSB0byBhZGQuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gYWRkTGluZXMoIGFycmF5ICYkbGluZXMsICRuYW1lLCAkdmFsdWUgKSB7CgkJJG5ld2xpbmVzID0gc2VsZjo6bXVsdGlsaW5lUXVvdGUoICR2YWx1ZSApOwoKCQlpZiAoIGNvdW50KCAkbmV3bGluZXMgKSA9PT0gMSApIHsKCQkJJGxpbmVzW10gPSAkbmFtZSAuICcgJyAuICRuZXdsaW5lc1swXTsKCQl9IGVsc2UgewoJCQkkbGluZXNbXSA9ICRuYW1lIC4gJyAiIic7CgoJCQlmb3JlYWNoICggJG5ld2xpbmVzIGFzICRsaW5lICkgewoJCQkJJGxpbmVzW10gPSAkbGluZTsKCQkJfQoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xQbyBhcyBQb0V4dHJhY3RvcjsKdXNlIEdldHRleHRcR2VuZXJhdG9yc1xQbyBhcyBQb0dlbmVyYXRvcjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgRGlyZWN0b3J5SXRlcmF0b3I7CnVzZSBJdGVyYXRvckl0ZXJhdG9yOwp1c2UgU3BsRmlsZUluZm87CgpjbGFzcyBNYWtlSnNvbkNvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgkvKioKCSAqIE9wdGlvbnMgcGFzc2VkIHRvIGpzb25fZW5jb2RlKCkuCgkgKgoJICogQHZhciBpbnQgSlNPTiBvcHRpb25zLgoJICovCglwcm90ZWN0ZWQgJGpzb25fb3B0aW9ucyA9IDA7CgoJLyoqCgkgKiBFeHRyYWN0IEphdmFTY3JpcHQgc3RyaW5ncyBmcm9tIFBPIGZpbGVzIGFuZCBhZGQgdGhlbSB0byBpbmRpdmlkdWFsIEpTT04gZmlsZXMuCgkgKgoJICogRm9yIEphdmFTY3JpcHQgaW50ZXJuYXRpb25hbGl6YXRpb24gcHVycG9zZXMsIFdvcmRQcmVzcyByZXF1aXJlcyB0cmFuc2xhdGlvbnMgdG8gYmUgc3BsaXQgdXAgaW50bwoJICogb25lIEplZC1mb3JtYXR0ZWQgSlNPTiBmaWxlIHBlciBKYXZhU2NyaXB0IHNvdXJjZSBmaWxlLgoJICoKCSAqIFNlZSBodHRwczovL21ha2Uud29yZHByZXNzLm9yZy9jb3JlLzIwMTgvMTEvMDkvbmV3LWphdmFzY3JpcHQtaTE4bi1zdXBwb3J0LWluLXdvcmRwcmVzcy8gdG8gbGVhcm4gbW9yZQoJICogYWJvdXQgV29yZFByZXNzIEphdmFTY3JpcHQgaW50ZXJuYXRpb25hbGl6YXRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzb3VyY2U+CgkgKiA6IFBhdGggdG8gYW4gZXhpc3RpbmcgUE8gZmlsZSBvciBhIGRpcmVjdG9yeSBjb250YWluaW5nIG11bHRpcGxlIFBPIGZpbGVzLgoJICoKCSAqIFs8ZGVzdGluYXRpb24+XQoJICogOiBQYXRoIHRvIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZm9yIHRoZSByZXN1bHRpbmcgSlNPTiBmaWxlcy4gRGVmYXVsdHMgdG8gdGhlIHNvdXJjZSBkaXJlY3RvcnkuCgkgKgoJICogWy0tcHVyZ2VdCgkgKiA6IFdoZXRoZXIgdG8gcHVyZ2UgdGhlIHN0cmluZ3MgdGhhdCB3ZXJlIGV4dHJhY3RlZCBmcm9tIHRoZSBvcmlnaW5hbCBzb3VyY2UgZmlsZS4gRGVmYXVsdHMgdG8gdHJ1ZSwgdXNlIGAtLW5vLXB1cmdlYCB0byBza2lwIHRoZSByZW1vdmFsLgoJICoKCSAqIFstLXVwZGF0ZS1tby1maWxlc10KCSAqIDogV2hldGhlciBNTyBmaWxlcyBzaG91bGQgYmUgdXBkYXRlZCBhcyB3ZWxsIGFmdGVyIHVwZGF0aW5nIFBPIGZpbGVzLgoJICogT25seSBoYXMgYW4gZWZmZWN0IHdoZW4gdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGAtLXB1cmdlYC4KCSAqCgkgKiBbLS1wcmV0dHktcHJpbnRdCgkgKiA6IFByZXR0eS1wcmludCByZXN1bHRpbmcgSlNPTiBmaWxlcy4KCSAqCgkgKiBbLS11c2UtbWFwPTxwYXRoc19vcl9tYXBzPl0KCSAqIDogV2hldGhlciB0byB1c2UgYSBtYXBwaW5nIGZpbGUgZm9yIHRoZSBzdHJpbmdzLCBhcyBhIEpTT04gdmFsdWUsIGFycmF5IHRvIHNwZWNpZnkgbXVsdGlwbGUuCgkgKiBFYWNoIGVsZW1lbnQgY2FuIGVpdGhlciBiZSBhIHN0cmluZyAoZmlsZSBwYXRoKSBvciBvYmplY3QgKG1hcCkuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDcmVhdGUgSlNPTiBmaWxlcyBmb3IgYWxsIFBPIGZpbGVzIGluIHRoZSBsYW5ndWFnZXMgZGlyZWN0b3J5CgkgKiAgICAgJCB3cCBpMThuIG1ha2UtanNvbiBsYW5ndWFnZXMKCSAqCgkgKiAgICAgIyBDcmVhdGUgSlNPTiBmaWxlcyBmb3IgbXktcGx1Z2luLWRlX0RFLnBvIGFuZCBsZWF2ZSB0aGUgUE8gZmlsZSB1bnRvdWNoZWQuCgkgKiAgICAgJCB3cCBpMThuIG1ha2UtanNvbiBteS1wbHVnaW4tZGVfREUucG8gL3RtcCAtLW5vLXB1cmdlCgkgKgoJICogICAgICMgQ3JlYXRlIEpTT04gZmlsZXMgd2l0aCBtYXBwaW5nCgkgKiAgICAgJCB3cCBpMThuIG1ha2UtanNvbiBsYW5ndWFnZXMgLS11c2UtbWFwPWJ1aWxkL21hcC5qc29uCgkgKgoJICogICAgICMgQ3JlYXRlIEpTT04gZmlsZXMgd2l0aCBtdWx0aXBsZSBtYXBwaW5ncwoJICogICAgICQgd3AgaTE4biBtYWtlLWpzb24gbGFuZ3VhZ2VzICctLXVzZS1tYXA9WyJidWlsZC9tYXAuanNvbiIsImJ1aWxkL21hcDIuanNvbiJdJwoJICoKCSAqICAgICAjIENyZWF0ZSBKU09OIGZpbGVzIHdpdGggb2JqZWN0IG1hcHBpbmcKCSAqICAgICAkIHdwIGkxOG4gbWFrZS1qc29uIGxhbmd1YWdlcyAnLS11c2UtbWFwPXsic291cmNlL2luZGV4LmpzIjoiYnVpbGQvaW5kZXguanMifScKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICoKCSAqIEB0aHJvd3MgV1BfQ0xJXEV4aXRFeGNlcHRpb24KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFzc29jX2FyZ3MgICAgICA9IFV0aWxzXHBhcnNlX3NoZWxsX2FycmF5cyggJGFzc29jX2FyZ3MsIGFycmF5KCAndXNlLW1hcCcgKSApOwoJCSRwdXJnZSAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwdXJnZScsIHRydWUgKTsKCQkkdXBkYXRlX21vX2ZpbGVzID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndXBkYXRlLW1vLWZpbGVzJywgdHJ1ZSApOwoJCSRtYXBfcGF0aHMgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd1c2UtbWFwJywgZmFsc2UgKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwcmV0dHktcHJpbnQnLCBmYWxzZSApICkgewoJCQkkdGhpcy0+anNvbl9vcHRpb25zIHw9IEpTT05fUFJFVFRZX1BSSU5UOwoJCX0KCgkJJHNvdXJjZSA9IHJlYWxwYXRoKCAkYXJnc1swXSApOwoKCQlpZiAoICEgJHNvdXJjZSB8fCAoICEgaXNfZmlsZSggJHNvdXJjZSApICYmICEgaXNfZGlyKCAkc291cmNlICkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1NvdXJjZSBmaWxlIG9yIGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdCEnICk7CgkJfQoKCQkkZGVzdGluYXRpb24gPSBpc19maWxlKCAkc291cmNlICkgPyBkaXJuYW1lKCAkc291cmNlICkgOiAkc291cmNlOwoKCQlpZiAoIGlzc2V0KCAkYXJnc1sxXSApICkgewoJCQkkZGVzdGluYXRpb24gPSAkYXJnc1sxXTsKCQl9CgoJCSRtYXAgPSAkdGhpcy0+YnVpbGRfbWFwKCAkbWFwX3BhdGhzICk7CgkJaWYgKCBpc19hcnJheSggJG1hcCApICYmIGVtcHR5KCAkbWFwICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyB2YWxpZCBrZXlzIGZvdW5kLiBObyBmaWxlIHdhcyBjcmVhdGVkLicgKTsKCQl9CgoJCS8vIFR3byBpc19kaXIoKSBjaGVja3MgaW4gY2FzZSBvZiBhIHJhY2UgY29uZGl0aW9uLgoJCWlmICggISBpc19kaXIoICRkZXN0aW5hdGlvbiApCgkJCSYmICEgbWtkaXIoICRkZXN0aW5hdGlvbiwgMDc3NywgdHJ1ZSApCgkJCSYmICEgaXNfZGlyKCAkZGVzdGluYXRpb24gKQoJCSkgewoJCQlXUF9DTEk6OmVycm9yKCAnQ291bGQgbm90IGNyZWF0ZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkhJyApOwoJCX0KCgkJJHJlc3VsdF9jb3VudCA9IDA7CgoJCWlmICggaXNfZmlsZSggJHNvdXJjZSApICkgewoJCQkkZmlsZXMgPSBbIG5ldyBTcGxGaWxlSW5mbyggJHNvdXJjZSApIF07CgkJfSBlbHNlIHsKCQkJJGZpbGVzID0gbmV3IEl0ZXJhdG9ySXRlcmF0b3IoIG5ldyBEaXJlY3RvcnlJdGVyYXRvciggJHNvdXJjZSApICk7CgkJfQoKCQkvKiogQHZhciBEaXJlY3RvcnlJdGVyYXRvciAkZmlsZSAqLwoJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGUgKSB7CgkJCWlmICggJGZpbGUtPmlzRmlsZSgpICYmICRmaWxlLT5pc1JlYWRhYmxlKCkgJiYgJ3BvJyA9PT0gJGZpbGUtPmdldEV4dGVuc2lvbigpICkgewoJCQkJJHJlc3VsdCAgICAgICAgPSAkdGhpcy0+bWFrZV9qc29uKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSwgJGRlc3RpbmF0aW9uLCAkbWFwICk7CgkJCQkkcmVzdWx0X2NvdW50ICs9IGNvdW50KCAkcmVzdWx0ICk7CgoJCQkJaWYgKCAkcHVyZ2UgKSB7CgkJCQkJJHJlbW92ZWQgPSAkdGhpcy0+cmVtb3ZlX2pzX3N0cmluZ3NfZnJvbV9wb19maWxlKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSApOwoKCQkJCQlpZiAoICEgJHJlbW92ZWQgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0NvdWxkIG5vdCB1cGRhdGUgZmlsZSAlcycsIGJhc2VuYW1lKCAkc291cmNlICkgKSApOwoJCQkJCQljb250aW51ZTsKCQkJCQl9CgoJCQkJCWlmICggJHVwZGF0ZV9tb19maWxlcyApIHsKCQkJCQkJJGZpbGVfYmFzZW5hbWUgICAgPSBiYXNlbmFtZSggJGZpbGUtPmdldEZpbGVuYW1lKCksICcucG8nICk7CgkJCQkJCSRkZXN0aW5hdGlvbl9maWxlID0gInskZGVzdGluYXRpb259L3skZmlsZV9iYXNlbmFtZX0ubW8iOwoKCQkJCQkJJHRyYW5zbGF0aW9ucyA9IFRyYW5zbGF0aW9uczo6ZnJvbVBvRmlsZSggJGZpbGUtPmdldFBhdGhuYW1lKCkgKTsKCQkJCQkJaWYgKCAhICR0cmFuc2xhdGlvbnMtPnRvTW9GaWxlKCAkZGVzdGluYXRpb25fZmlsZSApICkgewoJCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IGNyZWF0ZSBmaWxlIHskZGVzdGluYXRpb25fZmlsZX0iICk7CgkJCQkJCQljb250aW51ZTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAnQ3JlYXRlZCAlZCAlcy4nLCAkcmVzdWx0X2NvdW50LCBVdGlsc1xwbHVyYWxpemUoICdmaWxlJywgJHJlc3VsdF9jb3VudCApICkgKTsKCX0KCgkvKioKCSAqIENvbGxlY3QgbWFwcyBmcm9tIHBhdGhzLCBub3JtYWxpemUgYW5kIG1lcmdlCgkgKgoJICogQHBhcmFtIHN0cmluZ3xhcnJheXxib29sICRwYXRoc19vcl9tYXBzIGFyZ3VtZW50LiBGYWxzZSB0byBkbyBub3RoaW5nLgoJICogQHJldHVybiBhcnJheXxudWxsICAgICAgIE1hcHBpbmcgYXJyYXkuIE51bGwgaWYgbm8gbWFwcyBzcGVjaWZpZWQuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBidWlsZF9tYXAoICRwYXRoc19vcl9tYXBzICkgewoJCWlmICggZmFsc2UgPT09ICRwYXRoc19vcl9tYXBzICkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCSRtYXAgPSBbXTsKCgkJLy8gbm90IGFuIGFycmF5OiBzaW5nbGUgdmFsdWUgY291bGQgYWxzbyBiZSBvYmplY3QgKGFzc29jaWF0aXZlIGFycmF5KQoJCWlmICggISBpc19hcnJheSggJHBhdGhzX29yX21hcHMgKSB8fCBlbXB0eSggYXJyYXlfZmlsdGVyKCBhcnJheV9rZXlzKCAkcGF0aHNfb3JfbWFwcyApLCAnaXNfaW50JyApICkgKSB7CgkJCSRwYXRoc19vcl9tYXBzID0gWyAkcGF0aHNfb3JfbWFwcyBdOwoJCX0KCQkkcGF0aHMgPSBhcnJheV9maWx0ZXIoICRwYXRoc19vcl9tYXBzLCAnaXNfc3RyaW5nJyApOwoJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdVc2luZyAlZCBtYXAgZmlsZXM6ICVzJywgY291bnQoICRwYXRocyApLCBpbXBsb2RlKCAnLCAnLCAkcGF0aHMgKSApLCAnbWFrZS1qc29uJyApOwoJCSRtYXBzID0gYXJyYXlfZmlsdGVyKCAkcGF0aHNfb3JfbWFwcywgJ2lzX2FycmF5JyApOwoJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdVc2luZyAlZCBpbmxpbmUgbWFwIG9iamVjdHMnLCBjb3VudCggJG1hcHMgKSApLCAnbWFrZS1qc29uJyApOwoJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdEcm9wcGluZyAlZCBpbnZhbGlkIHZhbHVlcyBmcm9tIG1hcCBhcmd1bWVudCcsIGNvdW50KCAkcGF0aHNfb3JfbWFwcyApIC0gY291bnQoICRwYXRocyApIC0gY291bnQoICRtYXBzICkgKSwgJ21ha2UtanNvbicgKTsKCgkJJHRvX3RyYW5zZm9ybSA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24gKCAkdmFsdWUsICRpbmRleCApIHsKCQkJCXJldHVybiBbICR2YWx1ZSwgc3ByaW50ZiggJ2lubGluZSBvYmplY3QgJWQnLCAkaW5kZXggKSBdOwoJCQl9LAoJCQkkbWFwcywKCQkJYXJyYXlfa2V5cyggJG1hcHMgKQoJCSk7CgoJCWZvcmVhY2ggKCAkcGF0aHMgYXMgJHBhdGggKSB7CgkJCWlmICggISBmaWxlX2V4aXN0cyggJHBhdGggKSB8fCBpc19kaXIoICRwYXRoICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdNYXAgZmlsZSAlcyBkb2VzIG5vdCBleGlzdCcsICRwYXRoICkgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkanNvbiA9IGpzb25fZGVjb2RlKCBmaWxlX2dldF9jb250ZW50cyggJHBhdGggKSwgdHJ1ZSApOwoJCQlpZiAoICEgaXNfYXJyYXkoICRqc29uICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdNYXAgZmlsZSAlcyBpbnZhbGlkJywgJHBhdGggKSApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCSR0b190cmFuc2Zvcm1bXSA9IFsgJGpzb24sICRwYXRoIF07CgkJfQoKCQlmb3JlYWNoICggJHRvX3RyYW5zZm9ybSBhcyAkdHJhbnNmb3JtICkgewoJCQlsaXN0KCAkanNvbiwgJGZpbGUgKSA9ICR0cmFuc2Zvcm07CgkJCSRrZXlfbnVtICAgICAgICAgICAgID0gY291bnQoICRqc29uICk7CgkJCS8vIG5vcm1hbGl6ZSBjb250ZW50cyB0byBzdHJpbmdbXQoJCQkkanNvbiA9IGFycmF5X21hcCgKCQkJCWZ1bmN0aW9uICggJHZhbHVlICkgewoJCQkJCWlmICggaXNfYXJyYXkoICR2YWx1ZSApICkgewoJCQkJCQkkdmFsdWUgPSBhcnJheV92YWx1ZXMoIGFycmF5X2ZpbHRlciggJHZhbHVlLCAnaXNfc3RyaW5nJyApICk7CgkJCQkJCWlmICggISBlbXB0eSggJHZhbHVlICkgKSB7CgkJCQkJCQlyZXR1cm4gJHZhbHVlOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQlpZiAoIGlzX3N0cmluZyggJHZhbHVlICkgKSB7CgkJCQkJCXJldHVybiBbICR2YWx1ZSBdOwoJCQkJCX0KCgkJCQkJcmV0dXJuIG51bGw7CgkJCQl9LAoJCQkJJGpzb24KCQkJKTsKCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ0Ryb3BwZWQgJWQga2V5cyBmcm9tICVzJywgY291bnQoICRqc29uICkgLSAka2V5X251bSwgJGZpbGUgKSwgJ21ha2UtanNvbicgKTsKCgkJCSRtYXAgPSBhcnJheV9tZXJnZV9yZWN1cnNpdmUoICRtYXAsICRqc29uICk7CgkJfQoKCQlyZXR1cm4gJG1hcDsKCX0KCgkvKioKCSAqIFNwbGl0cyBhIHNpbmdsZSBQTyBmaWxlIGludG8gbXVsdGlwbGUgSlNPTiBmaWxlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICAkc291cmNlX2ZpbGUgUGF0aCB0byB0aGUgc291cmNlIGZpbGUuCgkgKiBAcGFyYW0gc3RyaW5nICAgICAkZGVzdGluYXRpb24gUGF0aCB0byB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5LgoJICogQHBhcmFtIGFycmF5fG51bGwgJG1hcCAgICAgICAgICAgICAgIFNvdXJjZSB0byBidWlsZCBmaWxlIG1hcHBpbmcuCgkgKiBAcmV0dXJuIGFycmF5ICAgICBMaXN0IG9mIGNyZWF0ZWQgSlNPTiBmaWxlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIG1ha2VfanNvbiggJHNvdXJjZV9maWxlLCAkZGVzdGluYXRpb24sICRtYXAgKSB7CgkJLyoqIEB2YXIgVHJhbnNsYXRpb25zW10gJG1hcHBpbmcgKi8KCQkkbWFwcGluZyAgICAgID0gW107CgkJJHRyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoKTsKCQkkcmVzdWx0ICAgICAgID0gW107CgoJCVBvRXh0cmFjdG9yOjpmcm9tRmlsZSggJHNvdXJjZV9maWxlLCAkdHJhbnNsYXRpb25zICk7CgoJCSRiYXNlX2ZpbGVfbmFtZSA9IGJhc2VuYW1lKCAkc291cmNlX2ZpbGUsICcucG8nICk7CgoJCWZvcmVhY2ggKCAkdHJhbnNsYXRpb25zIGFzICRpbmRleCA9PiAkdHJhbnNsYXRpb24gKSB7CgkJCS8qKiBAdmFyIFRyYW5zbGF0aW9uICR0cmFuc2xhdGlvbiAqLwoKCQkJLy8gRmluZCBhbGwgdW5pcXVlIHNvdXJjZXMgdGhpcyB0cmFuc2xhdGlvbiBvcmlnaW5hdGVzIGZyb20uCgkJCSRzb3VyY2VzID0gYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24gKCAkcmVmZXJlbmNlICkgewoJCQkJCSRmaWxlID0gJHJlZmVyZW5jZVswXTsKCgkJCQkJaWYgKCBzdWJzdHIoICRmaWxlLCAtIDcgKSA9PT0gJy5taW4uanMnICkgewoJCQkJCQlyZXR1cm4gc3Vic3RyKCAkZmlsZSwgMCwgLSA3ICkgLiAnLmpzJzsKCQkJCQl9CgoJCQkJCWlmICggc3Vic3RyKCAkZmlsZSwgLSAzICkgPT09ICcuanMnICkgewoJCQkJCQlyZXR1cm4gJGZpbGU7CgkJCQkJfQoKCQkJCQlyZXR1cm4gbnVsbDsKCQkJCX0sCgkJCQkkdGhpcy0+cmVmZXJlbmNlX21hcCggJHRyYW5zbGF0aW9uLT5nZXRSZWZlcmVuY2VzKCksICRtYXAgKQoJCQkpOwoKCQkJJHNvdXJjZXMgPSBhcnJheV91bmlxdWUoIGFycmF5X2ZpbHRlciggJHNvdXJjZXMgKSApOwoKCQkJZm9yZWFjaCAoICRzb3VyY2VzIGFzICRzb3VyY2UgKSB7CgkJCQlpZiAoICEgaXNzZXQoICRtYXBwaW5nWyAkc291cmNlIF0gKSApIHsKCQkJCQkkbWFwcGluZ1sgJHNvdXJjZSBdID0gbmV3IFRyYW5zbGF0aW9ucygpOwoKCQkJCQkvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkNvbW1lbnRlZE91dENvZGUuRm91bmQgLS0gUHJvdmlkZSBjb2RlIHRoYXQgaXMgbWVhbnQgdG8gYmUgdXNlZCBvbmNlIHRoZSBidWcgaXMgZml4ZWQuCgkJCQkJLy8gU2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzQ1NDQxCgkJCQkJLy8gJG1hcHBpbmdbICRzb3VyY2UgXS0+c2V0RG9tYWluKCAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSApOwoKCQkJCQkkbWFwcGluZ1sgJHNvdXJjZSBdLT5zZXRIZWFkZXIoICdMYW5ndWFnZScsICR0cmFuc2xhdGlvbnMtPmdldExhbmd1YWdlKCkgKTsKCQkJCQkkbWFwcGluZ1sgJHNvdXJjZSBdLT5zZXRIZWFkZXIoICdQTy1SZXZpc2lvbi1EYXRlJywgJHRyYW5zbGF0aW9ucy0+Z2V0SGVhZGVyKCAnUE8tUmV2aXNpb24tRGF0ZScgKSApOwoKCQkJCQkkcGx1cmFsX2Zvcm1zID0gJHRyYW5zbGF0aW9ucy0+Z2V0UGx1cmFsRm9ybXMoKTsKCgkJCQkJaWYgKCAkcGx1cmFsX2Zvcm1zICkgewoJCQkJCQlsaXN0KCAkY291bnQsICRydWxlICkgPSAkcGx1cmFsX2Zvcm1zOwoJCQkJCQkkbWFwcGluZ1sgJHNvdXJjZSBdLT5zZXRQbHVyYWxGb3JtcyggJGNvdW50LCAkcnVsZSApOwoJCQkJCX0KCQkJCX0KCgkJCQkkbWFwcGluZ1sgJHNvdXJjZSBdW10gPSAkdHJhbnNsYXRpb247CgkJCX0KCQl9CgoJCSRyZXN1bHQgKz0gJHRoaXMtPmJ1aWxkX2pzb25fZmlsZXMoICRtYXBwaW5nLCAkYmFzZV9maWxlX25hbWUsICRkZXN0aW5hdGlvbiApOwoKCQlyZXR1cm4gJHJlc3VsdDsKCX0KCgkvKioKCSAqIFRha2VzIHRoZSByZWZlcmVuY2VzIGFuZCBhcHBsaWVzIG1hcCwgaWYgZ2l2ZW4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICAgICAkcmVmZXJlbmNlcyB0cmFuc2xhdGlvbiByZWZlcmVuY2VzCgkgKiBAcGFyYW0gYXJyYXl8bnVsbCAkbWFwIGZpbGUgbWFwcGluZwoJICogQHJldHVybiBhcnJheSAgICAgbWFwcGVkIHJlZmVyZW5jZXMKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJlZmVyZW5jZV9tYXAoICRyZWZlcmVuY2VzLCAkbWFwICkgewoJCWlmICggaXNfbnVsbCggJG1hcCApICkgewoJCQlyZXR1cm4gJHJlZmVyZW5jZXM7CgkJfQoKCQkvLyB0cmFuc2xhdGUgdXNpbmcgbWFwCgkJJHRlbXAgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uICggJHJlZmVyZW5jZSApIHVzZSAoICYkbWFwICkgewoJCQkJJGZpbGUgPSAkcmVmZXJlbmNlWzBdOwoKCQkJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJGZpbGUsICRtYXAgKSApIHsKCQkJCQlyZXR1cm4gJG1hcFsgJGZpbGUgXTsKCQkJCX0KCgkJCQlyZXR1cm4gbnVsbDsKCQkJfSwKCQkJJHJlZmVyZW5jZXMKCQkpOwoJCS8vIHRoaXMgaXMgbm93IGFuIGFycmF5IG9mIGFycmF5cyBvZiBzb3VyY2VzLCB0cmFuc2xhdGUgdG8gYXJyYXkgb2Ygc291cmNlcwoJCSRyZWZlcmVuY2VzID0gW107CgkJZm9yZWFjaCAoICR0ZW1wIGFzICRzb3VyY2VzICkgewoJCQlpZiAoIGlzX251bGwoICRzb3VyY2VzICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkkcmVmZXJlbmNlcyA9IGFycmF5X21lcmdlKCAkcmVmZXJlbmNlcywgJHNvdXJjZXMgKTsKCQl9CgkJLy8gYW5kIHdyYXAgdG8gYXJyYXkKCQkkcmVmZXJlbmNlcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24gKCAkdmFsdWUgKSB7CgkJCQlyZXR1cm4gWyAkdmFsdWUgXTsKCQkJfSwKCQkJJHJlZmVyZW5jZXMKCQkpOwoJCXJldHVybiAkcmVmZXJlbmNlczsKCX0KCgkvKioKCSAqIEJ1aWxkcyBhIG1hcHBpbmcgb2YgSlMgZmlsZSBuYW1lcyB0byB0cmFuc2xhdGlvbiBlbnRyaWVzLgoJICoKCSAqIEV4cG9ydHMgdHJhbnNsYXRpb25zIGZvciBlYWNoIEpTIGZpbGUgdG8gYSBzZXBhcmF0ZSB0cmFuc2xhdGlvbiBmaWxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJG1hcHBpbmcgICAgICAgIEEgbWFwcGluZyBvZiBmaWxlcyB0byB0cmFuc2xhdGlvbiBlbnRyaWVzLgoJICogQHBhcmFtIHN0cmluZyAkYmFzZV9maWxlX25hbWUgQmFzZSBmaWxlIG5hbWUgZm9yIEpTT04gZmlsZXMuCgkgKiBAcGFyYW0gc3RyaW5nICRkZXN0aW5hdGlvbiAgICBQYXRoIHRvIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuCgkgKgoJICogQHJldHVybiBhcnJheSBMaXN0IG9mIGNyZWF0ZWQgSlNPTiBmaWxlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGJ1aWxkX2pzb25fZmlsZXMoICRtYXBwaW5nLCAkYmFzZV9maWxlX25hbWUsICRkZXN0aW5hdGlvbiApIHsKCQkkcmVzdWx0ID0gW107CgoJCWZvcmVhY2ggKCAkbWFwcGluZyBhcyAkZmlsZSA9PiAkdHJhbnNsYXRpb25zICkgewoJCQkvKiogQHZhciBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucyAqLwoKCQkJJGhhc2ggICAgICAgICAgICAgPSBtZDUoICRmaWxlICk7CgkJCSRkZXN0aW5hdGlvbl9maWxlID0gIiR7ZGVzdGluYXRpb259L3skYmFzZV9maWxlX25hbWV9LXskaGFzaH0uanNvbiI7CgoJCQkkc3VjY2VzcyA9IEplZEdlbmVyYXRvcjo6dG9GaWxlKAoJCQkJJHRyYW5zbGF0aW9ucywKCQkJCSRkZXN0aW5hdGlvbl9maWxlLAoJCQkJWwoJCQkJCSdqc29uJyAgID0+ICR0aGlzLT5qc29uX29wdGlvbnMsCgkJCQkJJ3NvdXJjZScgPT4gJGZpbGUsCgkJCQldCgkJCSk7CgoJCQlpZiAoICEgJHN1Y2Nlc3MgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdDb3VsZCBub3QgY3JlYXRlIGZpbGUgJXMnLCBiYXNlbmFtZSggJGRlc3RpbmF0aW9uX2ZpbGUsICcuanNvbicgKSApICk7CgoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyZXN1bHRbXSA9ICRkZXN0aW5hdGlvbl9maWxlOwoJCX0KCgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIHN0cmluZ3MgZnJvbSBQTyBmaWxlIHRoYXQgb25seSBvY2N1ciBpbiBKYXZhU2NyaXB0IGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc291cmNlX2ZpbGUgUGF0aCB0byB0aGUgUE8gZmlsZS4KCSAqIEByZXR1cm4gYm9vbCBUcnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbW92ZV9qc19zdHJpbmdzX2Zyb21fcG9fZmlsZSggJHNvdXJjZV9maWxlICkgewoJCS8qKiBAdmFyIFRyYW5zbGF0aW9uc1tdICRtYXBwaW5nICovCgkJJHRyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoKTsKCgkJUG9FeHRyYWN0b3I6OmZyb21GaWxlKCAkc291cmNlX2ZpbGUsICR0cmFuc2xhdGlvbnMgKTsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMtPmdldEFycmF5Q29weSgpIGFzICR0cmFuc2xhdGlvbiApIHsKCQkJLyoqIEB2YXIgVHJhbnNsYXRpb24gJHRyYW5zbGF0aW9uICovCgoJCQlpZiAoICEgJHRyYW5zbGF0aW9uLT5oYXNSZWZlcmVuY2VzKCkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbi0+Z2V0UmVmZXJlbmNlcygpIGFzICRyZWZlcmVuY2UgKSB7CgkJCQkkZmlsZSA9ICRyZWZlcmVuY2VbMF07CgoJCQkJaWYgKCBzdWJzdHIoICRmaWxlLCAtIDMgKSAhPT0gJy5qcycgKSB7CgkJCQkJY29udGludWUgMjsKCQkJCX0KCQkJfQoKCQkJdW5zZXQoICR0cmFuc2xhdGlvbnNbICR0cmFuc2xhdGlvbi0+Z2V0SWQoKSBdICk7CgkJfQoKCQlyZXR1cm4gUG9HZW5lcmF0b3I6OnRvRmlsZSggJHRyYW5zbGF0aW9ucywgJHNvdXJjZV9maWxlICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBHZXR0ZXh0XEdlbmVyYXRvcnNcSmVkOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKLyoqCiAqIEplZCBmaWxlIGdlbmVyYXRvci4KICoKICogQWRkcyBzb21lIG1vcmUgbWV0YSBkYXRhIHRvIEpFRCB0cmFuc2xhdGlvbiBmaWxlcyB0aGFuIHRoZSBkZWZhdWx0IGdlbmVyYXRvci4KICovCmNsYXNzIEplZEdlbmVyYXRvciBleHRlbmRzIEplZCB7CgkvKioKCSAqIHtAcGFyZW50RG9jfS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyggVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCQkkZG9tYWluICAgPSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSA/OiAnbWVzc2FnZXMnOwoJCSRtZXNzYWdlcyA9IHN0YXRpYzo6YnVpbGRNZXNzYWdlcyggJHRyYW5zbGF0aW9ucyApOwoKCQkkY29uZmlndXJhdGlvbiA9IFsKCQkJJycgPT4gWwoJCQkJJ2RvbWFpbicgICAgICAgPT4gJGRvbWFpbiwKCQkJCSdsYW5nJyAgICAgICAgID0+ICR0cmFuc2xhdGlvbnMtPmdldExhbmd1YWdlKCkgPzogJ2VuJywKCQkJCSdwbHVyYWwtZm9ybXMnID0+ICR0cmFuc2xhdGlvbnMtPmdldEhlYWRlciggJ1BsdXJhbC1Gb3JtcycgKSA/OiAnbnBsdXJhbHM9MjsgcGx1cmFsPShuICE9IDEpOycsCgkJCV0sCgkJXTsKCgkJJGRhdGEgPSBbCgkJCSd0cmFuc2xhdGlvbi1yZXZpc2lvbi1kYXRlJyA9PiAkdHJhbnNsYXRpb25zLT5nZXRIZWFkZXIoICdQTy1SZXZpc2lvbi1EYXRlJyApLAoJCQknZ2VuZXJhdG9yJyAgICAgICAgICAgICAgICAgPT4gJ1dQLUNMSS8nIC4gV1BfQ0xJX1ZFUlNJT04sCgkJCSdzb3VyY2UnICAgICAgICAgICAgICAgICAgICA9PiAkb3B0aW9uc1snc291cmNlJ10sCgkJCSdkb21haW4nICAgICAgICAgICAgICAgICAgICA9PiAkZG9tYWluLAoJCQknbG9jYWxlX2RhdGEnICAgICAgICAgICAgICAgPT4gWwoJCQkJJGRvbWFpbiA9PiAkY29uZmlndXJhdGlvbiArICRtZXNzYWdlcywKCQkJXSwKCQldOwoKCQlyZXR1cm4ganNvbl9lbmNvZGUoICRkYXRhLCAkb3B0aW9uc1snanNvbiddICk7Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgYW4gYXJyYXkgd2l0aCBhbGwgdHJhbnNsYXRpb25zLgoJICoKCSAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBidWlsZE1lc3NhZ2VzKCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucyApIHsKCQkkcGx1cmFsX2Zvcm1zICAgICAgPSAkdHJhbnNsYXRpb25zLT5nZXRQbHVyYWxGb3JtcygpOwoJCSRudW1iZXJfb2ZfcGx1cmFscyA9IGlzX2FycmF5KCAkcGx1cmFsX2Zvcm1zICkgPyAoICRwbHVyYWxfZm9ybXNbMF0gLSAxICkgOiBudWxsOwoJCSRtZXNzYWdlcyAgICAgICAgICA9IFtdOwoJCSRjb250ZXh0X2dsdWUgICAgICA9IGNociggNCApOwoKCQlmb3JlYWNoICggJHRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24gKSB7CgkJCS8qKiBAdmFyIFRyYW5zbGF0aW9uICR0cmFuc2xhdGlvbiAqLwoKCQkJaWYgKCAkdHJhbnNsYXRpb24tPmlzRGlzYWJsZWQoKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkka2V5ID0gJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpOwoKCQkJaWYgKCAkdHJhbnNsYXRpb24tPmhhc0NvbnRleHQoKSApIHsKCQkJCSRrZXkgPSAkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKSAuICRjb250ZXh0X2dsdWUgLiAka2V5OwoJCQl9CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsVHJhbnNsYXRpb25zKCB0cnVlICkgKSB7CgkJCQkkbWVzc2FnZSA9ICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCAkbnVtYmVyX29mX3BsdXJhbHMgKTsKCQkJCWFycmF5X3Vuc2hpZnQoICRtZXNzYWdlLCAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCkgKTsKCQkJfSBlbHNlIHsKCQkJCSRtZXNzYWdlID0gWyAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCkgXTsKCQkJfQoKCQkJJG1lc3NhZ2VzWyAka2V5IF0gPSAkbWVzc2FnZTsKCQl9CgoJCXJldHVybiAkbWVzc2FnZXM7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBEaXJlY3RvcnlJdGVyYXRvcjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgSXRlcmF0b3JJdGVyYXRvcjsKdXNlIFNwbEZpbGVJbmZvOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJX0NvbW1hbmQ7CgpjbGFzcyBNYWtlTW9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoJLyoqCgkgKiBDcmVhdGUgTU8gZmlsZXMgZnJvbSBQTyBmaWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNvdXJjZT4KCSAqIDogUGF0aCB0byBhbiBleGlzdGluZyBQTyBmaWxlIG9yIGEgZGlyZWN0b3J5IGNvbnRhaW5pbmcgbXVsdGlwbGUgUE8gZmlsZXMuCgkgKgoJICogWzxkZXN0aW5hdGlvbj5dCgkgKiA6IFBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBmb3IgdGhlIHJlc3VsdGluZyBNTyBmaWxlcy4gRGVmYXVsdHMgdG8gdGhlIHNvdXJjZSBkaXJlY3RvcnkuCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRzb3VyY2UgPSByZWFscGF0aCggJGFyZ3NbMF0gKTsKCQlpZiAoICEgJHNvdXJjZSB8fCAoICEgaXNfZmlsZSggJHNvdXJjZSApICYmICEgaXNfZGlyKCAkc291cmNlICkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1NvdXJjZSBmaWxlIG9yIGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdCEnICk7CgkJfQoKCQkkZGVzdGluYXRpb24gPSBpc19maWxlKCAkc291cmNlICkgPyBkaXJuYW1lKCAkc291cmNlICkgOiAkc291cmNlOwoJCWlmICggaXNzZXQoICRhcmdzWzFdICkgKSB7CgkJCSRkZXN0aW5hdGlvbiA9ICRhcmdzWzFdOwoJCX0KCgkJLy8gVHdvIGlzX2RpcigpIGNoZWNrcyBpbiBjYXNlIG9mIGEgcmFjZSBjb25kaXRpb24uCgkJaWYgKCAhIGlzX2RpciggJGRlc3RpbmF0aW9uICkKCQkJJiYgISBta2RpciggJGRlc3RpbmF0aW9uLCAwNzc3LCB0cnVlICkKCQkJJiYgISBpc19kaXIoICRkZXN0aW5hdGlvbiApCgkJKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDb3VsZCBub3QgY3JlYXRlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSEnICk7CgkJfQoKCQlpZiAoIGlzX2ZpbGUoICRzb3VyY2UgKSApIHsKCQkJJGZpbGVzID0gWyBuZXcgU3BsRmlsZUluZm8oICRzb3VyY2UgKSBdOwoJCX0gZWxzZSB7CgkJCSRmaWxlcyA9IG5ldyBJdGVyYXRvckl0ZXJhdG9yKCBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRzb3VyY2UgKSApOwoJCX0KCgkJJHJlc3VsdF9jb3VudCA9IDA7CgkJLyoqIEB2YXIgRGlyZWN0b3J5SXRlcmF0b3IgJGZpbGUgKi8KCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlICkgewoJCQlpZiAoICdwbycgIT09ICRmaWxlLT5nZXRFeHRlbnNpb24oKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICEgJGZpbGUtPmlzRmlsZSgpIHx8ICEgJGZpbGUtPmlzUmVhZGFibGUoKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0NvdWxkIG5vdCByZWFkIGZpbGUgJXMnLCAkZmlsZS0+Z2V0RmlsZW5hbWUoKSApICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGZpbGVfYmFzZW5hbWUgICAgPSBiYXNlbmFtZSggJGZpbGUtPmdldEZpbGVuYW1lKCksICcucG8nICk7CgkJCSRkZXN0aW5hdGlvbl9maWxlID0gInskZGVzdGluYXRpb259L3skZmlsZV9iYXNlbmFtZX0ubW8iOwoKCQkJJHRyYW5zbGF0aW9ucyA9IFRyYW5zbGF0aW9uczo6ZnJvbVBvRmlsZSggJGZpbGUtPmdldFBhdGhuYW1lKCkgKTsKCQkJaWYgKCAhICR0cmFuc2xhdGlvbnMtPnRvTW9GaWxlKCAkZGVzdGluYXRpb25fZmlsZSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnQ291bGQgbm90IGNyZWF0ZSBmaWxlICVzJywgJGRlc3RpbmF0aW9uX2ZpbGUgKSApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyZXN1bHRfY291bnQrKzsKCQl9CgoJCVdQX0NMSTo6c3VjY2Vzcyggc3ByaW50ZiggJ0NyZWF0ZWQgJWQgJXMuJywgJHJlc3VsdF9jb3VudCwgVXRpbHNccGx1cmFsaXplKCAnZmlsZScsICRyZXN1bHRfY291bnQgKSApICk7Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9pMThuX2F1dG9sb2FkZXIgPSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9pMThuX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfaTE4bl9hdXRvbG9hZGVyOwp9CgppZiAoIGNsYXNzX2V4aXN0cyggJ1dQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmROYW1lc3BhY2UnICkgKSB7CglXUF9DTEk6OmFkZF9jb21tYW5kKCAnaTE4bicsICdcV1BfQ0xJXEkxOG5cQ29tbWFuZE5hbWVzcGFjZScgKTsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdpMThuIG1ha2UtcG90JywKCSdcV1BfQ0xJXEkxOG5cTWFrZVBvdENvbW1hbmQnLAoJYXJyYXkoCgkJJ2JlZm9yZV9pbnZva2UnID0+IHN0YXRpYyBmdW5jdGlvbigpIHsKCQkJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ21iX2VyZWcnICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVGhlIG1ic3RyaW5nIGV4dGVuc2lvbiBpcyByZXF1aXJlZCBmb3Igc3RyaW5nIGV4dHJhY3Rpb24gdG8gd29yayByZWxpYWJseS4nICk7CgkJCX0KCQl9LAoJKQopOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2kxOG4gbWFrZS1qc29uJywgJ1xXUF9DTElcSTE4blxNYWtlSnNvbkNvbW1hbmQnICk7CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnaTE4biBtYWtlLW1vJywgJ1xXUF9DTElcSTE4blxNYWtlTW9Db21tYW5kJyApOwo8P3BocAoKdXNlIFdQX0NMSVxFeGl0RXhjZXB0aW9uOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXFdwT3JnQXBpOwoKLyoqCiAqIEdlbmVyYXRlcyBhbmQgcmVhZHMgdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KICovCmNsYXNzIENvbmZpZ19Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogTGlzdCBvZiBjaGFyYWN0ZXJzIHRoYXQgYXJlIHZhbGlkIGZvciBhIGtleSBuYW1lLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFZBTElEX0tFWV9DSEFSQUNURVJTID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5IUAjJCVeJiooKS1fIFtde308Pn5gKz0sLjs6Lz98JzsKCgkvKioKCSAqIExpc3Qgb2YgZGVmYXVsdCBjb25zdGFudHMgdGhhdCBhcmUgZ2VuZXJhdGVkIGJ5IFdvcmRQcmVzcyBDb3JlLgoJICoKCSAqIEBzdHJpbmcKCSAqLwoJY29uc3QgREVGQVVMVF9TQUxUX0NPTlNUQU5UUyA9IFsKCQknQVVUSF9LRVknLAoJCSdTRUNVUkVfQVVUSF9LRVknLAoJCSdMT0dHRURfSU5fS0VZJywKCQknTk9OQ0VfS0VZJywKCQknQVVUSF9TQUxUJywKCQknU0VDVVJFX0FVVEhfU0FMVCcsCgkJJ0xPR0dFRF9JTl9TQUxUJywKCQknTk9OQ0VfU0FMVCcsCgldOwoKCS8qKgoJICogUmV0cmlldmUgdGhlIGluaXRpYWwgbG9jYWxlIGZyb20gdGhlIFdvcmRQcmVzcyB2ZXJzaW9uIGZpbGUuCgkgKgoJICogQHJldHVybiBzdHJpbmcgSW5pdGlhbCBsb2NhbGUgaWYgcHJlc2VudCwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vdC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2luaXRpYWxfbG9jYWxlKCkgewoJCWdsb2JhbCAkd3BfbG9jYWxfcGFja2FnZTsKCgkJaW5jbHVkZSBBQlNQQVRIIC4gJy93cC1pbmNsdWRlcy92ZXJzaW9uLnBocCc7CgoJCWlmICggISBlbXB0eSggJHdwX2xvY2FsX3BhY2thZ2UgKSApIHsKCQkJcmV0dXJuICR3cF9sb2NhbF9wYWNrYWdlOwoJCX0KCgkJcmV0dXJuICcnOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIGEgd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqIENyZWF0ZXMgYSBuZXcgd3AtY29uZmlnLnBocCB3aXRoIGRhdGFiYXNlIGNvbnN0YW50cywgYW5kIHZlcmlmaWVzIHRoYXQKCSAqIHRoZSBkYXRhYmFzZSBjb25zdGFudHMgYXJlIGNvcnJlY3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIC0tZGJuYW1lPTxkYm5hbWU+CgkgKiA6IFNldCB0aGUgZGF0YWJhc2UgbmFtZS4KCSAqCgkgKiAtLWRidXNlcj08ZGJ1c2VyPgoJICogOiBTZXQgdGhlIGRhdGFiYXNlIHVzZXIuCgkgKgoJICogWy0tZGJwYXNzPTxkYnBhc3M+XQoJICogOiBTZXQgdGhlIGRhdGFiYXNlIHVzZXIgcGFzc3dvcmQuCgkgKgoJICogWy0tZGJob3N0PTxkYmhvc3Q+XQoJICogOiBTZXQgdGhlIGRhdGFiYXNlIGhvc3QuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGxvY2FsaG9zdAoJICogLS0tCgkgKgoJICogWy0tZGJwcmVmaXg9PGRicHJlZml4Pl0KCSAqIDogU2V0IHRoZSBkYXRhYmFzZSB0YWJsZSBwcmVmaXguCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHdwXwoJICogLS0tCgkgKgoJICogWy0tZGJjaGFyc2V0PTxkYmNoYXJzZXQ+XQoJICogOiBTZXQgdGhlIGRhdGFiYXNlIGNoYXJzZXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHV0ZjgKCSAqIC0tLQoJICoKCSAqIFstLWRiY29sbGF0ZT08ZGJjb2xsYXRlPl0KCSAqIDogU2V0IHRoZSBkYXRhYmFzZSBjb2xsYXRpb24uCgkgKiAtLS0KCSAqIGRlZmF1bHQ6CgkgKiAtLS0KCSAqCgkgKiBbLS1sb2NhbGU9PGxvY2FsZT5dCgkgKiA6IFNldCB0aGUgV1BMQU5HIGNvbnN0YW50LiBEZWZhdWx0cyB0byAkd3BfbG9jYWxfcGFja2FnZSB2YXJpYWJsZS4KCSAqCgkgKiBbLS1leHRyYS1waHBdCgkgKiA6IElmIHNldCwgdGhlIGNvbW1hbmQgY29waWVzIGFkZGl0aW9uYWwgUEhQIGNvZGUgaW50byB3cC1jb25maWcucGhwIGZyb20gU1RESU4uCgkgKgoJICogWy0tc2tpcC1zYWx0c10KCSAqIDogSWYgc2V0LCBrZXlzIGFuZCBzYWx0cyB3b24ndCBiZSBnZW5lcmF0ZWQsIGJ1dCBzaG91bGQgaW5zdGVhZCBiZSBwYXNzZWQgdmlhIGAtLWV4dHJhLXBocGAuCgkgKgoJICogWy0tc2tpcC1jaGVja10KCSAqIDogSWYgc2V0LCB0aGUgZGF0YWJhc2UgY29ubmVjdGlvbiBpcyBub3QgY2hlY2tlZC4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogT3ZlcndyaXRlcyBleGlzdGluZyBmaWxlcywgaWYgcHJlc2VudC4KCSAqCgkgKiBbLS1jb25maWctZmlsZT08cGF0aD5dCgkgKiA6IFNwZWNpZnkgdGhlIGZpbGUgcGF0aCB0byB0aGUgY29uZmlnIGZpbGUgdG8gYmUgY3JlYXRlZC4gRGVmYXVsdHMgdG8gdGhlIHJvb3Qgb2YgdGhlCgkgKiBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGFuZCB0aGUgZmlsZW5hbWUgIndwLWNvbmZpZy5waHAiLgoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSBBUEkgZG93bmxvYWQgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGlmIFRMUyBoYW5kc2hha2UgZmFpbHMuIE5vdGU6IFRoaXMgbWFrZXMgdGhlIHJlcXVlc3QgdnVsbmVyYWJsZSB0byBhIE1JVE0gYXR0YWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU3RhbmRhcmQgd3AtY29uZmlnLnBocCBmaWxlCgkgKiAgICAgJCB3cCBjb25maWcgY3JlYXRlIC0tZGJuYW1lPXRlc3RpbmcgLS1kYnVzZXI9d3AgLS1kYnBhc3M9c2VjdXJlcHN3ZCAtLWxvY2FsZT1yb19STwoJICogICAgIFN1Y2Nlc3M6IEdlbmVyYXRlZCAnd3AtY29uZmlnLnBocCcgZmlsZS4KCSAqCgkgKiAgICAgIyBFbmFibGUgV1BfREVCVUcgYW5kIFdQX0RFQlVHX0xPRwoJICogICAgICQgd3AgY29uZmlnIGNyZWF0ZSAtLWRibmFtZT10ZXN0aW5nIC0tZGJ1c2VyPXdwIC0tZGJwYXNzPXNlY3VyZXBzd2QgLS1leHRyYS1waHAgPDxQSFAKCSAqICAgICBkZWZpbmUoICdXUF9ERUJVRycsIHRydWUgKTsKCSAqICAgICBkZWZpbmUoICdXUF9ERUJVR19MT0cnLCB0cnVlICk7CgkgKiAgICAgUEhQCgkgKiAgICAgU3VjY2VzczogR2VuZXJhdGVkICd3cC1jb25maWcucGhwJyBmaWxlLgoJICoKCSAqICAgICAjIEF2b2lkIGRpc2Nsb3NpbmcgcGFzc3dvcmQgdG8gYmFzaCBoaXN0b3J5IGJ5IHJlYWRpbmcgZnJvbSBwYXNzd29yZC50eHQKCSAqICAgICAjIFVzaW5nIC0tcHJvbXB0PWRicGFzcyB3aWxsIHByb21wdCBmb3IgdGhlICdkYnBhc3MnIGFyZ3VtZW50CgkgKiAgICAgJCB3cCBjb25maWcgY3JlYXRlIC0tZGJuYW1lPXRlc3RpbmcgLS1kYnVzZXI9d3AgLS1wcm9tcHQ9ZGJwYXNzIDwgcGFzc3dvcmQudHh0CgkgKiAgICAgU3VjY2VzczogR2VuZXJhdGVkICd3cC1jb25maWcucGhwJyBmaWxlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gY3JlYXRlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApICkgewoJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snY29uZmlnLWZpbGUnXSApICYmIGZpbGVfZXhpc3RzKCAkYXNzb2NfYXJnc1snY29uZmlnLWZpbGUnXSApICkgewoJCQkJJHRoaXMtPmNvbmZpZ19maWxlX2FscmVhZHlfZXhpc3RfZXJyb3IoIGJhc2VuYW1lKCAkYXNzb2NfYXJnc1snY29uZmlnLWZpbGUnXSApICk7CgkJCX0gZWxzZWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbJ2NvbmZpZy1maWxlJ10gKSAmJiBVdGlsc1xsb2NhdGVfd3BfY29uZmlnKCkgKSB7CgkJCQkkdGhpcy0+Y29uZmlnX2ZpbGVfYWxyZWFkeV9leGlzdF9lcnJvciggJ3dwLWNvbmZpZy5waHAnICk7CgkJCX0KCQl9CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknZGJob3N0JyAgICAgID0+ICdsb2NhbGhvc3QnLAoJCQknZGJwYXNzJyAgICAgID0+ICcnLAoJCQknZGJwcmVmaXgnICAgID0+ICd3cF8nLAoJCQknZGJjaGFyc2V0JyAgID0+ICd1dGY4JywKCQkJJ2RiY29sbGF0ZScgICA9PiAnJywKCQkJJ2xvY2FsZScgICAgICA9PiBzZWxmOjpnZXRfaW5pdGlhbF9sb2NhbGUoKSwKCQkJJ2NvbmZpZy1maWxlJyA9PiBydHJpbSggQUJTUEFUSCwgJy9cXCcgKSAuICcvd3AtY29uZmlnLnBocCcsCgkJXTsKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgkJaWYgKCBwcmVnX21hdGNoKCAnfFteYS16MC05X118aScsICRhc3NvY19hcmdzWydkYnByZWZpeCddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICctLWRicHJlZml4IGNhbiBvbmx5IGNvbnRhaW4gbnVtYmVycywgbGV0dGVycywgYW5kIHVuZGVyc2NvcmVzLicgKTsKCQl9CgoJCSRteXNxbF9kYl9jb25uZWN0aW9uX2FyZ3MgPSBbCgkJCSdleGVjdXRlJyA9PiAnOycsCgkJCSdob3N0JyAgICA9PiAkYXNzb2NfYXJnc1snZGJob3N0J10sCgkJCSd1c2VyJyAgICA9PiAkYXNzb2NfYXJnc1snZGJ1c2VyJ10sCgkJCSdwYXNzJyAgICA9PiAkYXNzb2NfYXJnc1snZGJwYXNzJ10sCgkJXTsKCgkJLy8gQ2hlY2sgREIgY29ubmVjdGlvbi4KCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1jaGVjaycgKSApIHsKCQkJVXRpbHNccnVuX215c3FsX2NvbW1hbmQoICcvdXNyL2Jpbi9lbnYgbXlzcWwgLS1uby1kZWZhdWx0cycsICRteXNxbF9kYl9jb25uZWN0aW9uX2FyZ3MgKTsKCQl9CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXNhbHRzJyApICkgewoJCQl0cnkgewoJCQkJJGFzc29jX2FyZ3NbJ2tleXMtYW5kLXNhbHRzJ10gICAgPSB0cnVlOwoJCQkJJGFzc29jX2FyZ3NbJ2F1dGgta2V5J10gICAgICAgICAgPSBzZWxmOjp1bmlxdWVfa2V5KCk7CgkJCQkkYXNzb2NfYXJnc1snc2VjdXJlLWF1dGgta2V5J10gICA9IHNlbGY6OnVuaXF1ZV9rZXkoKTsKCQkJCSRhc3NvY19hcmdzWydsb2dnZWQtaW4ta2V5J10gICAgID0gc2VsZjo6dW5pcXVlX2tleSgpOwoJCQkJJGFzc29jX2FyZ3NbJ25vbmNlLWtleSddICAgICAgICAgPSBzZWxmOjp1bmlxdWVfa2V5KCk7CgkJCQkkYXNzb2NfYXJnc1snYXV0aC1zYWx0J10gICAgICAgICA9IHNlbGY6OnVuaXF1ZV9rZXkoKTsKCQkJCSRhc3NvY19hcmdzWydzZWN1cmUtYXV0aC1zYWx0J10gID0gc2VsZjo6dW5pcXVlX2tleSgpOwoJCQkJJGFzc29jX2FyZ3NbJ2xvZ2dlZC1pbi1zYWx0J10gICAgPSBzZWxmOjp1bmlxdWVfa2V5KCk7CgkJCQkkYXNzb2NfYXJnc1snbm9uY2Utc2FsdCddICAgICAgICA9IHNlbGY6OnVuaXF1ZV9rZXkoKTsKCQkJCSRhc3NvY19hcmdzWyd3cC1jYWNoZS1rZXktc2FsdCddID0gc2VsZjo6dW5pcXVlX2tleSgpOwoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJJGFzc29jX2FyZ3NbJ2tleXMtYW5kLXNhbHRzJ10gICAgID0gZmFsc2U7CgkJCQkkYXNzb2NfYXJnc1sna2V5cy1hbmQtc2FsdHMtYWx0J10gPSBzZWxmOjpmZXRjaF9yZW1vdGVfc2FsdHMoCgkJCQkJKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKQoJCQkJKTsKCQkJfQoJCX0KCgkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjAnLCAnPCcgKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2FkZC13cGxhbmcnXSA9IHRydWU7CgkJfSBlbHNlIHsKCQkJJGFzc29jX2FyZ3NbJ2FkZC13cGxhbmcnXSA9IGZhbHNlOwoJCX0KCgkJZm9yZWFjaCAoICRhc3NvY19hcmdzIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQkkYXNzb2NfYXJnc1sgJGtleSBdID0gJHRoaXMtPmVzY2FwZV9jb25maWdfdmFsdWUoICRrZXksICR2YWx1ZSApOwoJCX0KCgkJLy8gJ2V4dHJhLXBocCcgZnJvbSBTVERJTiBpcyByZXRyaWV2ZWQgYWZ0ZXIgZXNjYXBpbmcgdG8gYXZvaWQgYnJlYWtpbmcKCQkvLyB0aGUgUEhQIGNvZGUuCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdleHRyYS1waHAnICkgPT09IHRydWUgKSB7CgkJCSRhc3NvY19hcmdzWydleHRyYS1waHAnXSA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAncGhwOi8vc3RkaW4nICk7CgkJfQoKCQkkY29tbWFuZF9yb290ID0gVXRpbHNccGhhcl9zYWZlX3BhdGgoIGRpcm5hbWUoIF9fRElSX18gKSApOwoJCSRvdXQgICAgICAgICAgPSBVdGlsc1xtdXN0YWNoZV9yZW5kZXIoICJ7JGNvbW1hbmRfcm9vdH0vdGVtcGxhdGVzL3dwLWNvbmZpZy5tdXN0YWNoZSIsICRhc3NvY19hcmdzICk7CgoJCSR3cF9jb25maWdfZmlsZV9uYW1lID0gYmFzZW5hbWUoICRhc3NvY19hcmdzWydjb25maWctZmlsZSddICk7CgkJJGJ5dGVzX3dyaXR0ZW4gICAgICAgPSBmaWxlX3B1dF9jb250ZW50cyggJGFzc29jX2FyZ3NbJ2NvbmZpZy1maWxlJ10sICRvdXQgKTsKCQlpZiAoICEgJGJ5dGVzX3dyaXR0ZW4gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgY3JlYXRlIG5ldyAneyR3cF9jb25maWdfZmlsZV9uYW1lfScgZmlsZS4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiR2VuZXJhdGVkICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHaXZlcyBlcnJvciB3aGVuIHdwLWNvbmZpZyBhbHJlYWR5IGV4aXN0IGFuZCB0cnkgdG8gY3JlYXRlIGl0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdwX2NvbmZpZ19maWxlX25hbWUgQ29uZmlnIGZpbGUgbmFtZS4KCSAqIEByZXR1cm4gdm9pZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNvbmZpZ19maWxlX2FscmVhZHlfZXhpc3RfZXJyb3IoICR3cF9jb25maWdfZmlsZV9uYW1lICkgewoJCVdQX0NMSTo6ZXJyb3IoICJUaGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUgYWxyZWFkeSBleGlzdHMuIiApOwoJfQoKCS8qKgoJICogTGF1bmNoZXMgc3lzdGVtIGVkaXRvciB0byBlZGl0IHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWNvbmZpZy1maWxlPTxwYXRoPl0KCSAqIDogU3BlY2lmeSB0aGUgZmlsZSBwYXRoIHRvIHRoZSBjb25maWcgZmlsZSB0byBiZSBlZGl0ZWQuIERlZmF1bHRzIHRvIHRoZSByb290IG9mIHRoZQoJICogV29yZFByZXNzIGluc3RhbGxhdGlvbiBhbmQgdGhlIGZpbGVuYW1lICJ3cC1jb25maWcucGhwIi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExhdW5jaCBzeXN0ZW0gZWRpdG9yIHRvIGVkaXQgd3AtY29uZmlnLnBocCBmaWxlCgkgKiAgICAgJCB3cCBjb25maWcgZWRpdAoJICoKCSAqICAgICAjIEVkaXQgd3AtY29uZmlnLnBocCBmaWxlIGluIGEgc3BlY2lmaWMgZWRpdG9yCgkgKiAgICAgJCBFRElUT1I9dmltIHdwIGNvbmZpZyBlZGl0CgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVkaXQoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkcGF0aCAgICAgICAgICAgICAgICA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoICRhc3NvY19hcmdzICk7CgkJJHdwX2NvbmZpZ19maWxlX25hbWUgPSBiYXNlbmFtZSggJHBhdGggKTsKCQkkY29udGVudHMgICAgICAgICAgICA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkcGF0aCApOwoJCSRyICAgICAgICAgICAgICAgICAgID0gVXRpbHNcbGF1bmNoX2VkaXRvcl9mb3JfaW5wdXQoICRjb250ZW50cywgJHdwX2NvbmZpZ19maWxlX25hbWUsICdwaHAnICk7CgkJaWYgKCBmYWxzZSA9PT0gJHIgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggIk5vIGNoYW5nZXMgbWFkZSB0byB7JHdwX2NvbmZpZ19maWxlX25hbWV9LCBhYm9ydGVkLiIgKTsKCQl9IGVsc2UgewoJCQlmaWxlX3B1dF9jb250ZW50cyggJHBhdGgsICRyICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyB0aGUgcGF0aCB0byB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgd3AtY29uZmlnLnBocCBmaWxlIHBhdGgKCSAqICAgICAkIHdwIGNvbmZpZyBwYXRoCgkgKiAgICAgL2hvbWUvcGVyc29uL2h0ZG9jcy9wcm9qZWN0L3dwLWNvbmZpZy5waHAKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0aCgpIHsKCQlXUF9DTEk6OmxpbmUoICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoIGFycmF5KCkgKSApOwoJfQoKCS8qKgoJICogTGlzdHMgdmFyaWFibGVzLCBjb25zdGFudHMsIGFuZCBmaWxlIGluY2x1ZGVzIGRlZmluZWQgaW4gd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGZpbHRlcj4uLi5dCgkgKiA6IE5hbWUgb3IgcGFydGlhbCBuYW1lIHRvIGZpbHRlciB0aGUgbGlzdCBieS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogRG90ZW52IGlzIGxpbWl0ZWQgdG8gbm9uLW9iamVjdCB2YWx1ZXMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqICAgLSBkb3RlbnYKCSAqIC0tLQoJICoKCSAqIFstLXN0cmljdF0KCSAqIDogRW5mb3JjZSBzdHJpY3QgbWF0Y2hpbmcgd2hlbiBhIGZpbHRlciBpcyBwcm92aWRlZC4KCSAqCgkgKiBbLS1jb25maWctZmlsZT08cGF0aD5dCgkgKiA6IFNwZWNpZnkgdGhlIGZpbGUgcGF0aCB0byB0aGUgY29uZmlnIGZpbGUgdG8gYmUgcmVhZC4gRGVmYXVsdHMgdG8gdGhlIHJvb3Qgb2YgdGhlCgkgKiBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGFuZCB0aGUgZmlsZW5hbWUgIndwLWNvbmZpZy5waHAiLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBjb25zdGFudHMgYW5kIHZhcmlhYmxlcyBkZWZpbmVkIGluIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqICAgICAkIHdwIGNvbmZpZyBsaXN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IGtleSAgICAgICAgICAgICAgfCB2YWx1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgdHlwZSAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCB0YWJsZV9wcmVmaXggICAgIHwgd3BfICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHZhcmlhYmxlIHwKCSAqICAgICB8IERCX05BTUUgICAgICAgICAgfCB3cF9jbGlfdGVzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgY29uc3RhbnQgfAoJICogICAgIHwgREJfVVNFUiAgICAgICAgICB8IHJvb3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBjb25zdGFudCB8CgkgKiAgICAgfCBEQl9QQVNTV09SRCAgICAgIHwgcm9vdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGNvbnN0YW50IHwKCSAqICAgICB8IEFVVEhfS0VZICAgICAgICAgfCByNitAc2hQMXlPJiQpMWdkdS5obFsvajs3WnJ2bXR+bzsjV3hTc2EwbWxRT2kyNGoyY1IsN2krUU0vIzdTOm9eIHwgY29uc3RhbnQgfAoJICogICAgIHwgU0VDVVJFX0FVVEhfS0VZICB8IGlPLXohX20tLVlIJFR4MnRmLyZWLFlXKjEzWl9IaVJMcWkpZD8kby10TWRZKzgycEskYFQuTllXfmlUTFc7eHAgfCBjb25zdGFudCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBMaXN0IG9ubHkgZGF0YWJhc2UgdXNlciBhbmQgcGFzc3dvcmQgZnJvbSB3cC1jb25maWcucGhwIGZpbGUuCgkgKiAgICAgJCB3cCBjb25maWcgbGlzdCBEQl9VU0VSIERCX1BBU1NXT1JEIC0tc3RyaWN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBrZXkgICAgICAgICAgICAgIHwgdmFsdWUgfCB0eXBlICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBEQl9VU0VSICAgICAgICAgIHwgcm9vdCAgfCBjb25zdGFudCB8CgkgKiAgICAgfCBEQl9QQVNTV09SRCAgICAgIHwgcm9vdCAgfCBjb25zdGFudCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgTGlzdCBhbGwgc2FsdHMgZnJvbSB3cC1jb25maWcucGhwIGZpbGUuCgkgKiAgICAgJCB3cCBjb25maWcgbGlzdCBfU0FMVAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBrZXkgICAgICAgICAgICAgIHwgdmFsdWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHR5cGUgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgQVVUSF9TQUxUICAgICAgICB8IG46XVhkaXRrK183PlFpPT5CbXRaSGlILTYvRWNydmwoVjVjZWVHUDp7Pj87QlRePVtCMy0wPix+RjV6JCgrUSQgfCBjb25zdGFudCB8CgkgKiAgICAgfCBTRUNVUkVfQVVUSF9TQUxUIHwgP1ovcHxYaER3M3d9P2MueiV8K0JBcnwoSXYqSCUlVStEdSZrS1IgeT9jSk9ZeVJWUkJlQlsyekYtYCg+K0xDQyB8IGNvbnN0YW50IHwKCSAqICAgICB8IExPR0dFRF9JTl9TQUxUICAgfCArJEAoMXtiflp+c31Dcz44WV02W202flRub0NEcEU+TyVlNzV1fSY2a1VIIT5xOjd1TTRseGJCNlsxcGFfWCxxIHwgY29uc3RhbnQgfAoJICogICAgIHwgTk9OQ0VfU0FMVCAgICAgICB8IF94K0YgbGl8UUw/ME9TUW5zMV9KWnt8SXgzSmxlb3gtNzFrbS9naWZueXo4a21vPXctO0BBRThXLChmUDxOfTIgfCBjb25zdGFudCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGF0aCAgICAgICAgICAgICAgICA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoICRhc3NvY19hcmdzICk7CgkJJHdwX2NvbmZpZ19maWxlX25hbWUgPSBiYXNlbmFtZSggJHBhdGggKTsKCQkkc3RyaWN0ICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0cmljdCcgKTsKCQlpZiAoICRzdHJpY3QgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgLS1zdHJpY3Qgb3B0aW9uIGNhbiBvbmx5IGJlIHVzZWQgaW4gY29tYmluYXRpb24gd2l0aCBhIGZpbHRlci4nICk7CgkJfQoKCQkkZGVmYXVsdF9maWVsZHMgPSBbCgkJCSduYW1lJywKCQkJJ3ZhbHVlJywKCQkJJ3R5cGUnLAoJCV07CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ2ZpZWxkcycgPT4gaW1wbG9kZSggJywnLCAkZGVmYXVsdF9maWVsZHMgKSwKCQkJJ2Zvcm1hdCcgPT4gJ3RhYmxlJywKCQldOwoKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSR2YWx1ZXMgPSBzZWxmOjpnZXRfd3BfY29uZmlnX3ZhcnMoICRwYXRoICk7CgoJCWlmICggISBlbXB0eSggJGFyZ3MgKSApIHsKCQkJJHZhbHVlcyA9ICR0aGlzLT5maWx0ZXJfdmFsdWVzKCAkdmFsdWVzLCAkYXJncywgJHN0cmljdCApOwoJCX0KCgkJaWYgKCBlbXB0eSggJHZhbHVlcyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiTm8gbWF0Y2hpbmcgZW50cmllcyBmb3VuZCBpbiAneyR3cF9jb25maWdfZmlsZV9uYW1lfScuIiApOwoJCX0KCgkJaWYgKCAnZG90ZW52JyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQlyZXR1cm4gYXJyYXlfd2FsayggJHZhbHVlcywgYXJyYXkoICR0aGlzLCAncHJpbnRfZG90ZW52JyApICk7CgkJfQoKCQlVdGlsc1xmb3JtYXRfaXRlbXMoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgJHZhbHVlcywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmljIGNvbnN0YW50IG9yIHZhcmlhYmxlIGRlZmluZWQgaW4gd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bmFtZT4KCSAqIDogTmFtZSBvZiB0aGUgd3AtY29uZmlnLnBocCBjb25zdGFudCBvciB2YXJpYWJsZS4KCSAqCgkgKiBbLS10eXBlPTx0eXBlPl0KCSAqIDogVHlwZSBvZiBjb25maWcgdmFsdWUgdG8gcmV0cmlldmUuIERlZmF1bHRzIHRvICdhbGwnLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhbGwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gY29uc3RhbnQKCSAqICAgLSB2YXJpYWJsZQoJICogICAtIGFsbAoJICogLS0tCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBHZXQgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIERvdGVudiBpcyBsaW1pdGVkIHRvIG5vbi1vYmplY3QgdmFsdWVzLgoJICogLS0tCgkgKiBkZWZhdWx0OiB2YXJfZXhwb3J0CgkgKiBvcHRpb25zOgoJICogICAtIHZhcl9leHBvcnQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogICAtIGRvdGVudgoJICogLS0tCgkgKgoJICogWy0tY29uZmlnLWZpbGU9PHBhdGg+XQoJICogOiBTcGVjaWZ5IHRoZSBmaWxlIHBhdGggdG8gdGhlIGNvbmZpZyBmaWxlIHRvIGJlIHJlYWQuIERlZmF1bHRzIHRvIHRoZSByb290IG9mIHRoZQoJICogV29yZFByZXNzIGluc3RhbGxhdGlvbiBhbmQgdGhlIGZpbGVuYW1lICJ3cC1jb25maWcucGhwIi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCB0aGUgdGFibGVfcHJlZml4IGFzIGRlZmluZWQgaW4gd3AtY29uZmlnLnBocCBmaWxlLgoJICogICAgICQgd3AgY29uZmlnIGdldCB0YWJsZV9wcmVmaXgKCSAqICAgICB3cF8KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBhdGggICAgICAgICAgICAgICAgPSAkdGhpcy0+Z2V0X2NvbmZpZ19wYXRoKCAkYXNzb2NfYXJncyApOwoJCSR3cF9jb25maWdfZmlsZV9uYW1lID0gYmFzZW5hbWUoICRwYXRoICk7CgkJbGlzdCggJG5hbWUgKSAgICAgICAgPSAkYXJnczsKCQkkdHlwZSAgICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3R5cGUnICk7CgoJCSR2YWx1ZSA9ICR0aGlzLT5yZXR1cm5fdmFsdWUoICRuYW1lLCAkdHlwZSwgc2VsZjo6Z2V0X3dwX2NvbmZpZ192YXJzKCAkcGF0aCApLCAkd3BfY29uZmlnX2ZpbGVfbmFtZSApOwoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgYXJyYXkgb2Ygd3AtY29uZmlnLnBocCBjb25zdGFudHMgYW5kIHZhcmlhYmxlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3cF9jb25maWdfcGF0aCBDb25maWcgZmlsZSBwYXRoCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfd3BfY29uZmlnX3ZhcnMoICR3cF9jb25maWdfcGF0aCA9ICcnICkgewoJCSR3cF9jbGlfb3JpZ2luYWxfZGVmaW5lZF9jb25zdGFudHMgPSBnZXRfZGVmaW5lZF9jb25zdGFudHMoKTsKCQkkd3BfY2xpX29yaWdpbmFsX2RlZmluZWRfdmFycyAgICAgID0gZ2V0X2RlZmluZWRfdmFycygpOwoJCSR3cF9jbGlfb3JpZ2luYWxfaW5jbHVkZXMgICAgICAgICAgPSBnZXRfaW5jbHVkZWRfZmlsZXMoKTsKCgkJLy8gcGhwY3M6aWdub3JlIFNxdWl6LlBIUC5FdmFsLkRpc2NvdXJhZ2VkIC0tIERvbid0IGhhdmUgYW5vdGhlciB3YXkuCgkJZXZhbCggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmdldF93cF9jb25maWdfY29kZSggJHdwX2NvbmZpZ19wYXRoICkgKTsKCgkJJHdwX2NvbmZpZ192YXJzICAgICAgPSBzZWxmOjpnZXRfd3BfY29uZmlnX2RpZmYoIGdldF9kZWZpbmVkX3ZhcnMoKSwgJHdwX2NsaV9vcmlnaW5hbF9kZWZpbmVkX3ZhcnMsICd2YXJpYWJsZScsIFsgJ3dwX2NsaV9vcmlnaW5hbF9kZWZpbmVkX3ZhcnMnIF0gKTsKCQkkd3BfY29uZmlnX2NvbnN0YW50cyA9IHNlbGY6OmdldF93cF9jb25maWdfZGlmZiggZ2V0X2RlZmluZWRfY29uc3RhbnRzKCksICR3cF9jbGlfb3JpZ2luYWxfZGVmaW5lZF9jb25zdGFudHMsICdjb25zdGFudCcgKTsKCgkJZm9yZWFjaCAoICR3cF9jb25maWdfdmFycyBhcyAkbmFtZSA9PiAkdmFsdWUgKSB7CgkJCWlmICggJ3dwX2NsaV9vcmlnaW5hbF9pbmNsdWRlcycgPT09ICR2YWx1ZVsnbmFtZSddICkgewoJCQkJJG5hbWVfYmFja3VwID0gJG5hbWU7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJdW5zZXQoICR3cF9jb25maWdfdmFyc1sgJG5hbWVfYmFja3VwIF0gKTsKCQkkd3BfY29uZmlnX3ZhcnMgICAgICAgICAgID0gYXJyYXlfdmFsdWVzKCAkd3BfY29uZmlnX3ZhcnMgKTsKCQkkd3BfY29uZmlnX2luY2x1ZGVzICAgICAgID0gYXJyYXlfZGlmZiggZ2V0X2luY2x1ZGVkX2ZpbGVzKCksICR3cF9jbGlfb3JpZ2luYWxfaW5jbHVkZXMgKTsKCQkkd3BfY29uZmlnX2luY2x1ZGVzX2FycmF5ID0gW107CgoJCWZvcmVhY2ggKCAkd3BfY29uZmlnX2luY2x1ZGVzIGFzICRuYW1lID0+ICR2YWx1ZSApIHsKCQkJJHdwX2NvbmZpZ19pbmNsdWRlc19hcnJheVtdID0gWwoJCQkJJ25hbWUnICA9PiBiYXNlbmFtZSggJHZhbHVlICksCgkJCQkndmFsdWUnID0+ICR2YWx1ZSwKCQkJCSd0eXBlJyAgPT4gJ2luY2x1ZGVzJywKCQkJXTsKCQl9CgoJCXJldHVybiBhcnJheV9tZXJnZSggJHdwX2NvbmZpZ192YXJzLCAkd3BfY29uZmlnX2NvbnN0YW50cywgJHdwX2NvbmZpZ19pbmNsdWRlc19hcnJheSApOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpYyBjb25zdGFudCBvciB2YXJpYWJsZSBkZWZpbmVkIGluIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG5hbWU+CgkgKiA6IE5hbWUgb2YgdGhlIHdwLWNvbmZpZy5waHAgY29uc3RhbnQgb3IgdmFyaWFibGUuCgkgKgoJICogPHZhbHVlPgoJICogOiBWYWx1ZSB0byBzZXQgdGhlIHdwLWNvbmZpZy5waHAgY29uc3RhbnQgb3IgdmFyaWFibGUgdG8uCgkgKgoJICogWy0tYWRkXQoJICogOiBBZGQgdGhlIHZhbHVlIGlmIGl0IGRvZXNuJ3QgZXhpc3QgeWV0LgoJICogVGhpcyBpcyB0aGUgZGVmYXVsdCBiZWhhdmlvciwgb3ZlcnJpZGUgd2l0aCAtLW5vLWFkZC4KCSAqCgkgKiBbLS1yYXddCgkgKiA6IFBsYWNlIHRoZSB2YWx1ZSBpbnRvIHRoZSB3cC1jb25maWcucGhwIGZpbGUgYXMgaXMsIGluc3RlYWQgb2YgYXMgYSBxdW90ZWQgc3RyaW5nLgoJICoKCSAqIFstLWFuY2hvcj08YW5jaG9yPl0KCSAqIDogQW5jaG9yIHN0cmluZyB3aGVyZSBhZGRpdGlvbnMgb2YgbmV3IHZhbHVlcyBhcmUgYW5jaG9yZWQgYXJvdW5kLgoJICogRGVmYXVsdHMgdG8gIi8qIFRoYXQncyBhbGwsIHN0b3AgZWRpdGluZyEiLgoJICogVGhlIHNwZWNpYWwgY2FzZSAiRU9GIiBzdHJpbmcgdXNlcyB0aGUgZW5kIG9mIHRoZSBmaWxlIGFzIHRoZSBhbmNob3IuCgkgKgoJICogWy0tcGxhY2VtZW50PTxwbGFjZW1lbnQ+XQoJICogOiBXaGVyZSB0byBwbGFjZSB0aGUgbmV3IHZhbHVlcyBpbiByZWxhdGlvbiB0byB0aGUgYW5jaG9yIHN0cmluZy4KCSAqIC0tLQoJICogZGVmYXVsdDogJ2JlZm9yZScKCSAqIG9wdGlvbnM6CgkgKiAgIC0gYmVmb3JlCgkgKiAgIC0gYWZ0ZXIKCSAqIC0tLQoJICoKCSAqIFstLXNlcGFyYXRvcj08c2VwYXJhdG9yPl0KCSAqIDogU2VwYXJhdG9yIHN0cmluZyB0byBwdXQgYmV0d2VlbiBhbiBhZGRlZCB2YWx1ZSBhbmQgaXRzIGFuY2hvciBzdHJpbmcuCgkgKiBUaGUgZm9sbG93aW5nIGVzY2FwZSBzZXF1ZW5jZXMgd2lsbCBiZSByZWNvZ25pemVkIGFuZCBwcm9wZXJseSBpbnRlcnByZXRlZDogJ1xuJyA9PiBuZXdsaW5lLCAnXHInID0+IGNhcnJpYWdlIHJldHVybiwgJ1x0JyA9PiB0YWIuCgkgKiBEZWZhdWx0cyB0byBhIHNpbmdsZSBFT0wgKCJcbiIgb24gKm5peCBhbmQgIlxyXG4iIG9uIFdpbmRvd3MpLgoJICoKCSAqIFstLXR5cGU9PHR5cGU+XQoJICogOiBUeXBlIG9mIHRoZSBjb25maWcgdmFsdWUgdG8gc2V0LiBEZWZhdWx0cyB0byAnYWxsJy4KCSAqIC0tLQoJICogZGVmYXVsdDogYWxsCgkgKiBvcHRpb25zOgoJICogICAtIGNvbnN0YW50CgkgKiAgIC0gdmFyaWFibGUKCSAqICAgLSBhbGwKCSAqIC0tLQoJICoKCSAqIFstLWNvbmZpZy1maWxlPTxwYXRoPl0KCSAqIDogU3BlY2lmeSB0aGUgZmlsZSBwYXRoIHRvIHRoZSBjb25maWcgZmlsZSB0byBiZSBtb2RpZmllZC4gRGVmYXVsdHMgdG8gdGhlIHJvb3Qgb2YgdGhlCgkgKiBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGFuZCB0aGUgZmlsZW5hbWUgIndwLWNvbmZpZy5waHAiLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2V0IHRoZSBXUF9ERUJVRyBjb25zdGFudCB0byB0cnVlLgoJICogICAgICQgd3AgY29uZmlnIHNldCBXUF9ERUJVRyB0cnVlIC0tcmF3CgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRwYXRoICAgICAgICAgICAgICAgICA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoICRhc3NvY19hcmdzICk7CgkJJHdwX2NvbmZpZ19maWxlX25hbWUgID0gYmFzZW5hbWUoICRwYXRoICk7CgkJbGlzdCggJG5hbWUsICR2YWx1ZSApID0gJGFyZ3M7CgkJJHR5cGUgICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndHlwZScgKTsKCgkJJG9wdGlvbnMgPSBbXTsKCgkJJG9wdGlvbl9mbGFncyA9IFsKCQkJJ3JhdycgICAgICAgPT4gZmFsc2UsCgkJCSdhZGQnICAgICAgID0+IHRydWUsCgkJCSdhbmNob3InICAgID0+IG51bGwsCgkJCSdwbGFjZW1lbnQnID0+IG51bGwsCgkJCSdzZXBhcmF0b3InID0+IG51bGwsCgkJXTsKCgkJZm9yZWFjaCAoICRvcHRpb25fZmxhZ3MgYXMgJG9wdGlvbiA9PiAkZGVmYXVsdCApIHsKCQkJJG9wdGlvbl92YWx1ZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJG9wdGlvbiwgJGRlZmF1bHQgKTsKCQkJaWYgKCBudWxsICE9PSAkb3B0aW9uX3ZhbHVlICkgewoJCQkJJG9wdGlvbnNbICRvcHRpb24gXSA9ICRvcHRpb25fdmFsdWU7CgkJCQlpZiAoICdzZXBhcmF0b3InID09PSAkb3B0aW9uICkgewoJCQkJCSRvcHRpb25zWydzZXBhcmF0b3InXSA9ICR0aGlzLT5wYXJzZV9zZXBhcmF0b3IoICRvcHRpb25zWydzZXBhcmF0b3InXSApOwoJCQkJfQoJCQl9CgkJfQoKCQkkYWRkaW5nID0gZmFsc2U7CgkJdHJ5IHsKCQkJJGNvbmZpZ190cmFuc2Zvcm1lciA9IG5ldyBXUENvbmZpZ1RyYW5zZm9ybWVyKCAkcGF0aCApOwoKCQkJc3dpdGNoICggJHR5cGUgKSB7CgkJCQljYXNlICdhbGwnOgoJCQkJCSRoYXNfY29uc3RhbnQgPSAkY29uZmlnX3RyYW5zZm9ybWVyLT5leGlzdHMoICdjb25zdGFudCcsICRuYW1lICk7CgkJCQkJJGhhc192YXJpYWJsZSA9ICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJ3ZhcmlhYmxlJywgJG5hbWUgKTsKCQkJCQlpZiAoICRoYXNfY29uc3RhbnQgJiYgJGhhc192YXJpYWJsZSApIHsKCQkJCQkJV1BfQ0xJOjplcnJvciggIkZvdW5kIGJvdGggYSBjb25zdGFudCBhbmQgYSB2YXJpYWJsZSAneyRuYW1lfScgaW4gdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlLiBVc2UgLS10eXBlPTx0eXBlPiB0byBkaXNhbWJpZ3VhdGUuIiApOwoJCQkJCX0KCQkJCQlpZiAoICEgJGhhc19jb25zdGFudCAmJiAhICRoYXNfdmFyaWFibGUgKSB7CgkJCQkJCWlmICggISAkb3B0aW9uc1snYWRkJ10gKSB7CgkJCQkJCQkkbWVzc2FnZSA9ICJUaGUgY29uc3RhbnQgb3IgdmFyaWFibGUgJ3skbmFtZX0nIGlzIG5vdCBkZWZpbmVkIGluIHRoZSAneyR3cF9jb25maWdfZmlsZV9uYW1lfScgZmlsZS4iOwoJCQkJCQkJV1BfQ0xJOjplcnJvciggJG1lc3NhZ2UgKTsKCQkJCQkJfQoJCQkJCQkkdHlwZSAgID0gJ2NvbnN0YW50JzsKCQkJCQkJJGFkZGluZyA9IHRydWU7CgkJCQkJfSBlbHNlIHsKCQkJCQkJJHR5cGUgPSAkaGFzX2NvbnN0YW50ID8gJ2NvbnN0YW50JyA6ICd2YXJpYWJsZSc7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnY29uc3RhbnQnOgoJCQkJY2FzZSAndmFyaWFibGUnOgoJCQkJCWlmICggISAkY29uZmlnX3RyYW5zZm9ybWVyLT5leGlzdHMoICR0eXBlLCAkbmFtZSApICkgewoJCQkJCQlpZiAoICEgJG9wdGlvbnNbJ2FkZCddICkgewoJCQkJCQkJV1BfQ0xJOjplcnJvciggIlRoZSB7JHR5cGV9ICd7JG5hbWV9JyBpcyBub3QgZGVmaW5lZCBpbiB0aGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUuIiApOwoJCQkJCQl9CgkJCQkJCSRhZGRpbmcgPSB0cnVlOwoJCQkJCX0KCQkJfQoKCQkJJGNvbmZpZ190cmFuc2Zvcm1lci0+dXBkYXRlKCAkdHlwZSwgJG5hbWUsICR2YWx1ZSwgJG9wdGlvbnMgKTsKCgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHByb2Nlc3MgdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyB0cmFuc2Zvcm1hdGlvbi5cblJlYXNvbjogeyRleGNlcHRpb24tPmdldE1lc3NhZ2UoKX0iICk7CgkJfQoKCQkkcmF3ID0gJG9wdGlvbnNbJ3JhdyddID8gJ3JhdyAnIDogJyc7CgkJaWYgKCAkYWRkaW5nICkgewoJCQkkbWVzc2FnZSA9ICJBZGRlZCB0aGUgeyR0eXBlfSAneyRuYW1lfScgdG8gdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlIHdpdGggdGhlIHskcmF3fXZhbHVlICd7JHZhbHVlfScuIjsKCQl9IGVsc2UgewoJCQkkbWVzc2FnZSA9ICJVcGRhdGVkIHRoZSB7JHR5cGV9ICd7JG5hbWV9JyBpbiB0aGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUgd2l0aCB0aGUgeyRyYXd9dmFsdWUgJ3skdmFsdWV9Jy4iOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAkbWVzc2FnZSApOwoJfQoKCS8qKgoJICogRGVsZXRlcyBhIHNwZWNpZmljIGNvbnN0YW50IG9yIHZhcmlhYmxlIGZyb20gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG5hbWU+CgkgKiA6IE5hbWUgb2YgdGhlIHdwLWNvbmZpZy5waHAgY29uc3RhbnQgb3IgdmFyaWFibGUuCgkgKgoJICogWy0tdHlwZT08dHlwZT5dCgkgKiA6IFR5cGUgb2YgdGhlIGNvbmZpZyB2YWx1ZSB0byBkZWxldGUuIERlZmF1bHRzIHRvICdhbGwnLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhbGwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gY29uc3RhbnQKCSAqICAgLSB2YXJpYWJsZQoJICogICAtIGFsbAoJICogLS0tCgkgKgoJICogWy0tY29uZmlnLWZpbGU9PHBhdGg+XQoJICogOiBTcGVjaWZ5IHRoZSBmaWxlIHBhdGggdG8gdGhlIGNvbmZpZyBmaWxlIHRvIGJlIG1vZGlmaWVkLiBEZWZhdWx0cyB0byB0aGUgcm9vdCBvZiB0aGUKCSAqIFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gYW5kIHRoZSBmaWxlbmFtZSAid3AtY29uZmlnLnBocCIuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWxldGUgdGhlIENPT0tJRV9ET01BSU4gY29uc3RhbnQgZnJvbSB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICogICAgICQgd3AgY29uZmlnIGRlbGV0ZSBDT09LSUVfRE9NQUlOCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRwYXRoICAgICAgICAgICAgICAgID0gJHRoaXMtPmdldF9jb25maWdfcGF0aCggJGFzc29jX2FyZ3MgKTsKCQkkd3BfY29uZmlnX2ZpbGVfbmFtZSA9IGJhc2VuYW1lKCAkcGF0aCApOwoJCWxpc3QoICRuYW1lICkgICAgICAgID0gJGFyZ3M7CgkJJHR5cGUgICAgICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd0eXBlJyApOwoKCQl0cnkgewoJCQkkY29uZmlnX3RyYW5zZm9ybWVyID0gbmV3IFdQQ29uZmlnVHJhbnNmb3JtZXIoICRwYXRoICk7CgoJCQlzd2l0Y2ggKCAkdHlwZSApIHsKCQkJCWNhc2UgJ2FsbCc6CgkJCQkJJGhhc19jb25zdGFudCA9ICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJ2NvbnN0YW50JywgJG5hbWUgKTsKCQkJCQkkaGFzX3ZhcmlhYmxlID0gJGNvbmZpZ190cmFuc2Zvcm1lci0+ZXhpc3RzKCAndmFyaWFibGUnLCAkbmFtZSApOwoJCQkJCWlmICggJGhhc19jb25zdGFudCAmJiAkaGFzX3ZhcmlhYmxlICkgewoJCQkJCQlXUF9DTEk6OmVycm9yKCAiRm91bmQgYm90aCBhIGNvbnN0YW50IGFuZCBhIHZhcmlhYmxlICd7JG5hbWV9JyBpbiB0aGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUuIFVzZSAtLXR5cGU9PHR5cGU+IHRvIGRpc2FtYmlndWF0ZS4iICk7CgkJCQkJfQoJCQkJCWlmICggISAkaGFzX2NvbnN0YW50ICYmICEgJGhhc192YXJpYWJsZSApIHsKCQkJCQkJV1BfQ0xJOjplcnJvciggIlRoZSBjb25zdGFudCBvciB2YXJpYWJsZSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlLiIgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkkdHlwZSA9ICRoYXNfY29uc3RhbnQgPyAnY29uc3RhbnQnIDogJ3ZhcmlhYmxlJzsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICdjb25zdGFudCc6CgkJCQljYXNlICd2YXJpYWJsZSc6CgkJCQkJaWYgKCAhICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJHR5cGUsICRuYW1lICkgKSB7CgkJCQkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgeyR0eXBlfSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlLiIgKTsKCQkJCQl9CgkJCX0KCgkJCSRjb25maWdfdHJhbnNmb3JtZXItPnJlbW92ZSggJHR5cGUsICRuYW1lICk7CgoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBwcm9jZXNzIHRoZSAneyR3cF9jb25maWdfZmlsZV9uYW1lfScgdHJhbnNmb3JtYXRpb24uXG5SZWFzb246IHskZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCl9IiApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiRGVsZXRlZCB0aGUgeyR0eXBlfSAneyRuYW1lfScgZnJvbSB0aGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUuIiApOwoJfQoKCS8qKgoJICogQ2hlY2tzIHdoZXRoZXIgYSBzcGVjaWZpYyBjb25zdGFudCBvciB2YXJpYWJsZSBleGlzdHMgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG5hbWU+CgkgKiA6IE5hbWUgb2YgdGhlIHdwLWNvbmZpZy5waHAgY29uc3RhbnQgb3IgdmFyaWFibGUuCgkgKgoJICogWy0tdHlwZT08dHlwZT5dCgkgKiA6IFR5cGUgb2YgdGhlIGNvbmZpZyB2YWx1ZSB0byBzZXQuIERlZmF1bHRzIHRvICdhbGwnLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhbGwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gY29uc3RhbnQKCSAqICAgLSB2YXJpYWJsZQoJICogICAtIGFsbAoJICogLS0tCgkgKgoJICogWy0tY29uZmlnLWZpbGU9PHBhdGg+XQoJICogOiBTcGVjaWZ5IHRoZSBmaWxlIHBhdGggdG8gdGhlIGNvbmZpZyBmaWxlIHRvIGJlIGNoZWNrZWQuIERlZmF1bHRzIHRvIHRoZSByb290IG9mIHRoZQoJICogV29yZFByZXNzIGluc3RhbGxhdGlvbiBhbmQgdGhlIGZpbGVuYW1lICJ3cC1jb25maWcucGhwIi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgdGhlIERCX1BBU1NXT1JEIGNvbnN0YW50IGV4aXN0cyBpbiB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICogICAgICQgd3AgY29uZmlnIGhhcyBEQl9QQVNTV09SRAoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBoYXMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGF0aCAgICAgICAgICAgICAgICA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoICRhc3NvY19hcmdzICk7CgkJJHdwX2NvbmZpZ19maWxlX25hbWUgPSBiYXNlbmFtZSggJHBhdGggKTsKCQlsaXN0KCAkbmFtZSApICAgICAgICA9ICRhcmdzOwoJCSR0eXBlICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndHlwZScgKTsKCgkJdHJ5IHsKCQkJJGNvbmZpZ190cmFuc2Zvcm1lciA9IG5ldyBXUENvbmZpZ1RyYW5zZm9ybWVyKCAkcGF0aCApOwoKCQkJc3dpdGNoICggJHR5cGUgKSB7CgkJCQljYXNlICdhbGwnOgoJCQkJCSRoYXNfY29uc3RhbnQgPSAkY29uZmlnX3RyYW5zZm9ybWVyLT5leGlzdHMoICdjb25zdGFudCcsICRuYW1lICk7CgkJCQkJJGhhc192YXJpYWJsZSA9ICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJ3ZhcmlhYmxlJywgJG5hbWUgKTsKCQkJCQlpZiAoICRoYXNfY29uc3RhbnQgJiYgJGhhc192YXJpYWJsZSApIHsKCQkJCQkJV1BfQ0xJOjplcnJvciggIkZvdW5kIGJvdGggYSBjb25zdGFudCBhbmQgYSB2YXJpYWJsZSAneyRuYW1lfScgaW4gdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlLiBVc2UgLS10eXBlPTx0eXBlPiB0byBkaXNhbWJpZ3VhdGUuIiApOwoJCQkJCX0KCQkJCQlpZiAoICEgJGhhc19jb25zdGFudCAmJiAhICRoYXNfdmFyaWFibGUgKSB7CgkJCQkJCVdQX0NMSTo6aGFsdCggMSApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCVdQX0NMSTo6aGFsdCggMCApOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgJ2NvbnN0YW50JzoKCQkJCWNhc2UgJ3ZhcmlhYmxlJzoKCQkJCQlpZiAoICEgJGNvbmZpZ190cmFuc2Zvcm1lci0+ZXhpc3RzKCAkdHlwZSwgJG5hbWUgKSApIHsKCQkJCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJCQkJfQoJCQkJCVdQX0NMSTo6aGFsdCggMCApOwoJCQl9CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHByb2Nlc3MgdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyB0cmFuc2Zvcm1hdGlvbi5cblJlYXNvbjogeyRleGNlcHRpb24tPmdldE1lc3NhZ2UoKX0iICk7CgkJfQoJfQoKCS8qKgoJICogUmVmcmVzaGVzIHRoZSBzYWx0cyBkZWZpbmVkIGluIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8a2V5cz4uLi5dCgkgKiA6IE9uZSBvcmUgbW9yZSBrZXlzIHRvIHNodWZmbGUuIElmIG5vbmUgYXJlIHByb3ZpZGVkLCB0aGlzIGZhbGxzIGJhY2sgdG8gdGhlIGRlZmF1bHQgV29yZFByZXNzIENvcmUgc2FsdCBrZXlzLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBJZiBhbiB1bmtub3duIGtleSBpcyByZXF1ZXN0ZWQgdG8gYmUgc2h1ZmZsZWQsIGFkZCBpdCBpbnN0ZWFkIG9mIHRocm93aW5nIGEgd2FybmluZy4KCSAqCgkgKiBbLS1jb25maWctZmlsZT08cGF0aD5dCgkgKiA6IFNwZWNpZnkgdGhlIGZpbGUgcGF0aCB0byB0aGUgY29uZmlnIGZpbGUgdG8gYmUgbW9kaWZpZWQuIERlZmF1bHRzIHRvIHRoZSByb290IG9mIHRoZQoJICogV29yZFByZXNzIGluc3RhbGxhdGlvbiBhbmQgdGhlIGZpbGVuYW1lICJ3cC1jb25maWcucGhwIi4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgQVBJIGRvd25sb2FkIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBuZXcgc2FsdHMgZm9yIHlvdXIgd3AtY29uZmlnLnBocCBmaWxlCgkgKiAgICAgJCB3cCBjb25maWcgc2h1ZmZsZS1zYWx0cwoJICogICAgIFN1Y2Nlc3M6IFNodWZmbGVkIHRoZSBzYWx0IGtleXMuCgkgKgoJICogICAgICMgQWRkIGEgY2FjaGUga2V5IHNhbHQgdG8gdGhlIHdwLWNvbmZpZy5waHAgZmlsZQoJICogICAgICQgd3AgY29uZmlnIHNodWZmbGUtc2FsdHMgV1BfQ0FDSEVfS0VZX1NBTFQgLS1mb3JjZQoJICoKCSAqIEBzdWJjb21tYW5kIHNodWZmbGUtc2FsdHMKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaHVmZmxlX3NhbHRzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRrZXlzICA9ICRhcmdzOwoJCSRmb3JjZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJywgZmFsc2UgKTsKCgkJaWYgKCBlbXB0eSggJGtleXMgKSApIHsKCQkJJGtleXMgPSBzZWxmOjpERUZBVUxUX1NBTFRfQ09OU1RBTlRTOwoJCX0KCgkJJHNlY3JldF9rZXlzID0gW107CgoJCXRyeSB7CgkJCWZvcmVhY2ggKCAka2V5cyBhcyAka2V5ICkgewoJCQkJaWYgKCAhICRmb3JjZSAmJiAhIGluX2FycmF5KCAka2V5LCBzZWxmOjpERUZBVUxUX1NBTFRfQ09OU1RBTlRTLCB0cnVlICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IHNodWZmbGUgdGhlIHVua25vd24ga2V5ICd7JGtleX0nLiIgKTsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCSRzZWNyZXRfa2V5c1sgJGtleSBdID0gdHJpbSggc2VsZjo6dW5pcXVlX2tleSgpICk7CgkJCX0KCQl9IGNhdGNoICggRXhjZXB0aW9uICRleCApIHsKCQkJZm9yZWFjaCAoICRrZXlzIGFzICRrZXkgKSB7CgkJCQlpZiAoICEgaW5fYXJyYXkoICRrZXksIHNlbGY6OkRFRkFVTFRfU0FMVF9DT05TVEFOVFMsIHRydWUgKSApIHsKCQkJCQlpZiAoICRmb3JjZSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IGFkZCB0aGUga2V5ICd7JGtleX0nIGJlY2F1c2UgJ3JhbmRvbV9pbnQoKScgaXMgbm90IHN1cHBvcnRlZC4iICk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IHNodWZmbGUgdGhlIHVua25vd24ga2V5ICd7JGtleX0nLiIgKTsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCSRyZW1vdGVfc2FsdHMgPSBzZWxmOjpmZXRjaF9yZW1vdGVfc2FsdHMoIChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpbnNlY3VyZScsIGZhbHNlICkgKTsKCQkJJHJlbW90ZV9zYWx0cyA9IGV4cGxvZGUoICJcbiIsICRyZW1vdGVfc2FsdHMgKTsKCQkJZm9yZWFjaCAoICRyZW1vdGVfc2FsdHMgYXMgJGsgPT4gJHNhbHQgKSB7CgkJCQlpZiAoICEgZW1wdHkoICRzYWx0ICkgKSB7CgkJCQkJJGtleSA9IHNlbGY6OkRFRkFVTFRfU0FMVF9DT05TVEFOVFNbICRrIF07CgkJCQkJaWYgKCBpbl9hcnJheSggJGtleSwgJGtleXMsIHRydWUgKSApIHsKCQkJCQkJJHNlY3JldF9rZXlzWyAka2V5IF0gPSB0cmltKCBzdWJzdHIoICRzYWx0LCAyOCwgNjQgKSApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJJHBhdGggPSAkdGhpcy0+Z2V0X2NvbmZpZ19wYXRoKCAkYXNzb2NfYXJncyApOwoKCQl0cnkgewoJCQkkY29uZmlnX3RyYW5zZm9ybWVyID0gbmV3IFdQQ29uZmlnVHJhbnNmb3JtZXIoICRwYXRoICk7CgkJCWZvcmVhY2ggKCAkc2VjcmV0X2tleXMgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCQkkY29uZmlnX3RyYW5zZm9ybWVyLT51cGRhdGUoICdjb25zdGFudCcsICRrZXksIChzdHJpbmcpICR2YWx1ZSApOwoJCQl9CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQkkd3BfY29uZmlnX2ZpbGVfbmFtZSA9IGJhc2VuYW1lKCAkcGF0aCApOwoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHByb2Nlc3MgdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyB0cmFuc2Zvcm1hdGlvbi5cblJlYXNvbjogeyRleGNlcHRpb24tPmdldE1lc3NhZ2UoKX0iICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdTaHVmZmxlZCB0aGUgc2FsdCBrZXlzLicgKTsKCgl9CgoJLyoqCgkgKiBGaWx0ZXJzIHdwLWNvbmZpZy5waHAgZmlsZSBjb25maWd1cmF0aW9ucy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGxpc3QKCSAqIEBwYXJhbSBhcnJheSAkcHJldmlvdXNfbGlzdAoJICogQHBhcmFtIHN0cmluZyAkdHlwZQoJICogQHBhcmFtIGFycmF5ICRleGNsdWRlX2xpc3QKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3dwX2NvbmZpZ19kaWZmKCAkbGlzdCwgJHByZXZpb3VzX2xpc3QsICR0eXBlLCAkZXhjbHVkZV9saXN0ID0gW10gKSB7CgkJJHJlc3VsdCA9IFtdOwoJCWZvcmVhY2ggKCAkbGlzdCBhcyAkbmFtZSA9PiAkdmFsICkgewoJCQlpZiAoIGFycmF5X2tleV9leGlzdHMoICRuYW1lLCAkcHJldmlvdXNfbGlzdCApIHx8IGluX2FycmF5KCAkbmFtZSwgJGV4Y2x1ZGVfbGlzdCwgdHJ1ZSApICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJJG91dCAgICAgICAgICA9IFtdOwoJCQkkb3V0WyduYW1lJ10gID0gJG5hbWU7CgkJCSRvdXRbJ3ZhbHVlJ10gPSAkdmFsOwoJCQkkb3V0Wyd0eXBlJ10gID0gJHR5cGU7CgkJCSRyZXN1bHRbXSAgICAgPSAkb3V0OwoJCX0KCQlyZXR1cm4gJHJlc3VsdDsKCX0KCgkvKioKCSAqIFJlYWQgdGhlIHNhbHRzIGZyb20gdGhlIFdvcmRQcmVzcy5vcmcgQVBJLgoJICoKCSAqIEBwYXJhbSBib29sICAgJGluc2VjdXJlIE9wdGlvbmFsLiBXaGV0aGVyIHRvIHJldHJ5IHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBvbiBUTFMgaGFuZHNoYWtlIGZhaWx1cmUuCgkgKiBAcmV0dXJuIHN0cmluZyBTdHJpbmcgd2l0aCBhIHNldCBvZiBQSFAgZGVmaW5lKCkgc3RhdGVtZW50cyB0byBkZWZpbmUgdGhlIHNhbHRzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlsZWQuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGZldGNoX3JlbW90ZV9zYWx0cyggJGluc2VjdXJlID0gZmFsc2UgKSB7CgkJdHJ5IHsKCQkJJHNhbHRzID0gKHN0cmluZykgKCBuZXcgV3BPcmdBcGkoIFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXSApICktPmdldF9zYWx0cygpOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggJGV4Y2VwdGlvbiApOwoJCX0KCgkJLy8gQWRhcHQgd2hpdGVzcGFjZSB0byBhZGhlcmUgdG8gV1BDUy4KCQkkc2FsdHMgPSBwcmVnX3JlcGxhY2UoICcvZGVmaW5lXChcJyguKj8pXCdcKTsvJywgJ2RlZmluZSggXCckMVwnICk7JywgJHNhbHRzICk7CgoJCXJldHVybiAkc2FsdHM7Cgl9CgoJLyoqCgkgKiBQcmludHMgdGhlIHZhbHVlIG9mIGEgY29uc3RhbnQgb3IgdmFyaWFibGUgZGVmaW5lZCBpbiB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqIElmIHRoZSBjb25zdGFudCBvciB2YXJpYWJsZSBpcyBub3QgZGVmaW5lZCBpbiB0aGUgd3AtY29uZmlnIGZpbGUgdGhlbiBhbiBlcnJvciB3aWxsIGJlIHJldHVybmVkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKCSAqIEBwYXJhbSBzdHJpbmcgJHdwX2NvbmZpZ19maWxlX25hbWUgQ29uZmlnIGZpbGUgbmFtZQoJICogQHJldHVybiBzdHJpbmcgVGhlIHZhbHVlIG9mIHRoZSByZXF1ZXN0ZWQgY29uc3RhbnQgb3IgdmFyaWFibGUgYXMgZGVmaW5lZCBpbiB0aGUgd3AtY29uZmlnLnBocCBmaWxlOyBpZiB0aGUKCSAqICAgICAgICAgICAgICAgIHJlcXVlc3RlZCBjb25zdGFudCBvciB2YXJpYWJsZSBpcyBub3QgZGVmaW5lZCB0aGVuIHRoZSBmdW5jdGlvbiB3aWxsIHByaW50IGFuIGVycm9yIGFuZCBleGl0LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJldHVybl92YWx1ZSggJG5hbWUsICR0eXBlLCAkdmFsdWVzLCAkd3BfY29uZmlnX2ZpbGVfbmFtZSApIHsKCQkkcmVzdWx0cyA9IFtdOwoJCWZvcmVhY2ggKCAkdmFsdWVzIGFzICR2YWx1ZSApIHsKCQkJaWYgKCAkbmFtZSA9PT0gJHZhbHVlWyduYW1lJ10gJiYgKCAnYWxsJyA9PT0gJHR5cGUgfHwgJHR5cGUgPT09ICR2YWx1ZVsndHlwZSddICkgKSB7CgkJCQkkcmVzdWx0c1tdID0gJHZhbHVlOwoJCQl9CgkJfQoKCQlpZiAoIGNvdW50KCAkcmVzdWx0cyApID4gMSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkZvdW5kIGJvdGggYSBjb25zdGFudCBhbmQgYSB2YXJpYWJsZSAneyRuYW1lfScgaW4gdGhlICd7JHdwX2NvbmZpZ19maWxlX25hbWV9JyBmaWxlLiBVc2UgLS10eXBlPTx0eXBlPiB0byBkaXNhbWJpZ3VhdGUuIiApOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkcmVzdWx0cyApICkgewoJCQlyZXR1cm4gJHJlc3VsdHNbMF1bJ3ZhbHVlJ107CgkJfQoKCQkkdHlwZSAgICAgID0gJ2FsbCcgPT09ICR0eXBlID8gJ2NvbnN0YW50IG9yIHZhcmlhYmxlJyA6ICR0eXBlOwoJCSRuYW1lcyAgICAgPSBhcnJheV9jb2x1bW4oICR2YWx1ZXMsICduYW1lJyApOwoJCSRjYW5kaWRhdGUgPSBVdGlsc1xnZXRfc3VnZ2VzdGlvbiggJG5hbWUsICRuYW1lcyApOwoKCQlpZiAoICEgZW1wdHkoICRjYW5kaWRhdGUgKSAmJiAkY2FuZGlkYXRlICE9PSAkbmFtZSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlRoZSB7JHR5cGV9ICd7JG5hbWV9JyBpcyBub3QgZGVmaW5lZCBpbiB0aGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUuXG5EaWQgeW91IG1lYW4gJ3skY2FuZGlkYXRlfSc/IiApOwoJCX0KCgkJV1BfQ0xJOjplcnJvciggIlRoZSB7JHR5cGV9ICd7JG5hbWV9JyBpcyBub3QgZGVmaW5lZCBpbiB0aGUgJ3skd3BfY29uZmlnX2ZpbGVfbmFtZX0nIGZpbGUuIiApOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIGEgdW5pcXVlIGtleS9zYWx0IGZvciB0aGUgd3AtY29uZmlnIGZpbGUuCgkgKgoJICogQHRocm93cyBFeGNlcHRpb24KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB1bmlxdWVfa2V5KCkgewoJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICdyYW5kb21faW50JyApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiJ3JhbmRvbV9pbnQnIGRvZXMgbm90IGV4aXN0IiApOwoJCX0KCgkJJGNoYXJzID0gc2VsZjo6VkFMSURfS0VZX0NIQVJBQ1RFUlM7CgkJJGtleSAgID0gJyc7CgoJCWZvciAoICRpID0gMDsgJGkgPCA2NDsgJGkrKyApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuRnVuY3Rpb25Vc2UuTmV3RnVuY3Rpb25zLnJhbmRvbV9pbnRGb3VuZCAtLSBXaWxsIGJlIGNhbGxlZCBvbmx5IGlmIGZ1bmN0aW9uIGV4aXN0cy4KCQkJJGtleSAuPSBzdWJzdHIoICRjaGFycywgcmFuZG9tX2ludCggMCwgc3RybGVuKCAkY2hhcnMgKSAtIDEgKSwgMSApOwoJCX0KCgkJcmV0dXJuICRrZXk7Cgl9CgoJLyoqCgkgKiBGaWx0ZXJzIHRoZSB2YWx1ZXMgYmFzZWQgb24gYSBwcm92aWRlciBmaWx0ZXIga2V5LgoJICoKCSAqIEBwYXJhbSBhcnJheSAkdmFsdWVzCgkgKiBAcGFyYW0gYXJyYXkgJGZpbHRlcnMKCSAqIEBwYXJhbSBib29sICRzdHJpY3QKCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZmlsdGVyX3ZhbHVlcyggJHZhbHVlcywgJGZpbHRlcnMsICRzdHJpY3QgKSB7CgkJJHJlc3VsdCA9IFtdOwoKCQlmb3JlYWNoICggJHZhbHVlcyBhcyAkdmFsdWUgKSB7CgkJCWZvcmVhY2ggKCAkZmlsdGVycyBhcyAkZmlsdGVyICkgewoJCQkJaWYgKCAkc3RyaWN0ICYmICRmaWx0ZXIgIT09ICR2YWx1ZVsnbmFtZSddICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggZmFsc2UgPT09IHN0cnBvcyggJHZhbHVlWyduYW1lJ10sICRmaWx0ZXIgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkcmVzdWx0W10gPSAkdmFsdWU7CgkJCX0KCQl9CgoJCXJldHVybiAkcmVzdWx0OwoJfQoKCS8qKgoJICogR2V0cyB0aGUgcGF0aCB0byB0aGUgd3AtY29uZmlnLnBocCBmaWxlIG9yIGdpdmVzIGEgaGVscGZ1bCBlcnJvciBpZiBub25lIGZvdW5kLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBhc3NvY2lhdGl2ZSBhcmd1bWVudHMgZ2l2ZW4gd2hpbGUgY2FsbGluZyB3cCBjb25maWcgc3ViY29tbWFuZAoJICogQHJldHVybiBzdHJpbmcgUGF0aCB0byB3cC1jb25maWcucGhwIGZpbGUuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbmZpZ19wYXRoKCAkYXNzb2NfYXJncyApIHsKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snY29uZmlnLWZpbGUnXSApICkgewoJCQkkcGF0aCA9ICRhc3NvY19hcmdzWydjb25maWctZmlsZSddOwoJCQlpZiAoICEgZmlsZV9leGlzdHMoICRwYXRoICkgKSB7CgkJCQkkdGhpcy0+Y29uZmlnX2ZpbGVfbm90X2ZvdW5kX2Vycm9yKCBiYXNlbmFtZSggJGFzc29jX2FyZ3NbJ2NvbmZpZy1maWxlJ10gKSApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHBhdGggPSBVdGlsc1xsb2NhdGVfd3BfY29uZmlnKCk7CgkJCWlmICggISAkcGF0aCApIHsKCQkJCSR0aGlzLT5jb25maWdfZmlsZV9ub3RfZm91bmRfZXJyb3IoICd3cC1jb25maWcucGhwJyApOwoJCQl9CgkJfQoJCXJldHVybiAkcGF0aDsKCX0KCgkvKioKCSAqIEdpdmVzIGVycm9yIHRoZSB3cC1jb25maWcgZmlsZSBub3QgZm91bmQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3cF9jb25maWdfZmlsZV9uYW1lIENvbmZpZyBmaWxlIG5hbWUuCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjb25maWdfZmlsZV9ub3RfZm91bmRfZXJyb3IoICR3cF9jb25maWdfZmlsZV9uYW1lICkgewoJCVdQX0NMSTo6ZXJyb3IoICIneyR3cF9jb25maWdfZmlsZV9uYW1lfScgbm90IGZvdW5kLlxuRWl0aGVyIGNyZWF0ZSBvbmUgbWFudWFsbHkgb3IgdXNlIGB3cCBjb25maWcgY3JlYXRlYC4iICk7Cgl9CgkvKioKCSAqIFBhcnNlcyB0aGUgc2VwYXJhdG9yIGFyZ3VtZW50LCB0byBhbGxvdyBmb3Igc3BlY2lhbCBjaGFyYWN0ZXIgaGFuZGxpbmcuCgkgKgoJICogRG9lcyB0aGUgZm9sbG93aW5nIHRyYW5zZm9ybWF0aW9uczoKCSAqIC0gJ1xuJyA9PiAiXG4iIChuZXdsaW5lKQoJICogLSAnXHInID0+ICJcciIgKGNhcnJpYWdlIHJldHVybikKCSAqIC0gJ1x0JyA9PiAiXHQiICh0YWIpCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2VwYXJhdG9yIFNlcGFyYXRvciBzdHJpbmcgdG8gcGFyc2UuCgkgKgoJICogQHJldHVybiBtaXhlZCBQYXJzZWQgc2VwYXJhdG9yIHN0cmluZy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZV9zZXBhcmF0b3IoICRzZXBhcmF0b3IgKSB7CgkJJHNlcGFyYXRvciA9IHN0cl9yZXBsYWNlKAoJCQlbICdcbicsICdccicsICdcdCcgXSwKCQkJWyAiXG4iLCAiXHIiLCAiXHQiIF0sCgkJCSRzZXBhcmF0b3IKCQkpOwoKCQlyZXR1cm4gJHNlcGFyYXRvcjsKCX0KCgkvKioKCSAqIFdyaXRlcyBhIHByb3ZpZGVkIHZhcmlhYmxlJ3Mga2V5IGFuZCB2YWx1ZSB0byBzdGRvdXQsIGluIGRvdGVudiBmb3JtYXQuCgkgKgoJICogQHBhcmFtIGFycmF5ICR2YWx1ZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIHByaW50X2RvdGVudiggYXJyYXkgJHZhbHVlICkgewoJCWlmICggISBpc3NldCggJHZhbHVlWyduYW1lJ10gKSB8fCAhIGlzc2V0KCAkdmFsdWVbJ3R5cGUnXSApIHx8ICdjb25zdGFudCcgIT09ICR2YWx1ZVsndHlwZSddICkgewoJCQlyZXR1cm47CgkJfQoKCQkkbmFtZSAgICAgICAgICAgPSBzdHJ0b3VwcGVyKCAkdmFsdWVbJ25hbWUnXSApOwoJCSR2YXJpYWJsZV92YWx1ZSA9IGlzc2V0KCAkdmFsdWVbJ3ZhbHVlJ10gKSA/ICR2YWx1ZVsndmFsdWUnXSA6ICcnOwoKCQkkdmFyaWFibGVfdmFsdWUgPSBzdHJfcmVwbGFjZSggIiciLCAiXCciLCAkdmFyaWFibGVfdmFsdWUgKTsKCgkJaWYgKCAhIGlzX251bWVyaWMoICR2YXJpYWJsZV92YWx1ZSApICkgewoJCQkkdmFyaWFibGVfdmFsdWUgPSAiJ3skdmFyaWFibGVfdmFsdWV9JyI7CgkJfQoKCQlXUF9DTEk6OmxpbmUoICJ7JG5hbWV9PXskdmFyaWFibGVfdmFsdWV9IiApOwoJfQoKCS8qKgoJICogRXNjYXBlIGEgY29uZmlnIHZhbHVlIHNvIGl0IGNhbiBiZSBzYWZlbHkgdXNlZCB3aXRoaW4gc2luZ2xlIHF1b3Rlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgICBLZXkgaW50byB0aGUgYXJndW1lbnRzIGFycmF5LgoJICogQHBhcmFtIG1peGVkICAkdmFsdWUgVmFsdWUgdG8gZXNjYXBlLgoJICogQHJldHVybiBtaXhlZCBFc2NhcGVkIHZhbHVlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGVzY2FwZV9jb25maWdfdmFsdWUoICRrZXksICR2YWx1ZSApIHsKCQkvLyBTa2lwICdleHRyYS1waHAnLCBpdCBtdXN0bid0IGJlIGVzY2FwZWQuCgkJaWYgKCAnZXh0cmEtcGhwJyA9PT0gJGtleSApIHsKCQkJcmV0dXJuICR2YWx1ZTsKCQl9CgoJCS8vIFNraXAgJ2tleXMtYW5kLXNhbHRzLWFsdCcgYW5kIGFzc3VtZSB0aGV5IGFyZSBzYWZlLgoJCWlmICggJ2tleXMtYW5kLXNhbHRzLWFsdCcgPT09ICRrZXkgJiYgISBlbXB0eSggJHZhbHVlICkgKSB7CgkJCXJldHVybiAkdmFsdWU7CgkJfQoKCQlpZiAoIGlzX3N0cmluZyggJHZhbHVlICkgKSB7CgkJCXJldHVybiBhZGRzbGFzaGVzKCAkdmFsdWUgKTsKCQl9CgoJCXJldHVybiAkdmFsdWU7Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9jb25maWdfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfY29uZmlnX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfY29uZmlnX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjb25maWcnLCAnQ29uZmlnX0NvbW1hbmQnICk7Cjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKCi8qKgogKiBMaXN0cyByZWdpc3RlcmVkIHNpZGViYXJzLgogKgogKiBBIFtzaWRlYmFyXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9mdW5jdGlvbmFsaXR5L3NpZGViYXJzLykgaXMgYW55IHdpZGdldGl6ZWQgYXJlYSBvZiB5b3VyIHRoZW1lLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IHNpZGViYXJzCiAqICAgICAkIHdwIHNpZGViYXIgbGlzdCAtLWZpZWxkcz1uYW1lLGlkIC0tZm9ybWF0PWNzdgogKiAgICAgbmFtZSxpZAogKiAgICAgIldpZGdldCBBcmVhIixzaWRlYmFyLTEKICogICAgICJJbmFjdGl2ZSBXaWRnZXRzIix3cF9pbmFjdGl2ZV93aWRnZXRzCiAqLwpjbGFzcyBTaWRlYmFyX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gWwoJCSduYW1lJywKCQknaWQnLAoJCSdkZXNjcmlwdGlvbicsCgldOwoKCS8qKgoJICogTGlzdHMgcmVnaXN0ZXJlZCBzaWRlYmFycy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGlkcwoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHNpZGViYXI6CgkgKgoJICogKiBuYW1lCgkgKiAqIGlkCgkgKiAqIGRlc2NyaXB0aW9uCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIGNsYXNzCgkgKiAqIGJlZm9yZV93aWRnZXQKCSAqICogYWZ0ZXJfd2lkZ2V0CgkgKiAqIGJlZm9yZV90aXRsZQoJICogKiBhZnRlcl90aXRsZQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2lkZWJhciBsaXN0IC0tZmllbGRzPW5hbWUsaWQgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbmFtZSxpZAoJICogICAgICJXaWRnZXQgQXJlYSIsc2lkZWJhci0xCgkgKiAgICAgIkluYWN0aXZlIFdpZGdldHMiLHdwX2luYWN0aXZlX3dpZGdldHMKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFyczsKCgkJVXRpbHNcd3BfcmVnaXN0ZXJfdW51c2VkX3NpZGViYXIoKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiAnaWRzJyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkkc2lkZWJhcnMgPSB3cF9saXN0X3BsdWNrKCAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFycywgJ2lkJyApOwoJCX0gZWxzZSB7CgkJCSRzaWRlYmFycyA9ICR3cF9yZWdpc3RlcmVkX3NpZGViYXJzOwoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHNpZGViYXJzICk7Cgl9Cgp9Cjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKCi8qKgogKiBNYW5hZ2VzIHdpZGdldHMsIGluY2x1ZGluZyBhZGRpbmcgYW5kIG1vdmluZyB0aGVtIHdpdGhpbiBzaWRlYmFycy4KICoKICogQSBbd2lkZ2V0XShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9mdW5jdGlvbmFsaXR5L3dpZGdldHMvKSBhZGRzIGNvbnRlbnQgYW5kIGZlYXR1cmVzIHRvIGEgd2lkZ2V0IGFyZWEgKGFsc28gY2FsbGVkIGEgW3NpZGViYXJdKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvdGhlbWVzL2Z1bmN0aW9uYWxpdHkvc2lkZWJhcnMvKSkuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3Qgd2lkZ2V0cyBvbiBhIGdpdmVuIHNpZGViYXIKICogICAgICQgd3Agd2lkZ2V0IGxpc3Qgc2lkZWJhci0xCiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBuYW1lICAgICB8IGlkICAgICAgICAgfCBwb3NpdGlvbiB8IG9wdGlvbnMgICAgICAgICAgICAgIHwKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqICAgICB8IG1ldGEgICAgIHwgbWV0YS02ICAgICB8IDEgICAgICAgIHwgeyJ0aXRsZSI6Ik1ldGEifSAgICAgfAogKiAgICAgfCBjYWxlbmRhciB8IGNhbGVuZGFyLTIgfCAyICAgICAgICB8IHsidGl0bGUiOiJDYWxlbmRhciJ9IHwKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqCiAqICAgICAjIEFkZCBhIGNhbGVuZGFyIHdpZGdldCB0byB0aGUgc2Vjb25kIHBvc2l0aW9uIG9uIHRoZSBzaWRlYmFyCiAqICAgICAkIHdwIHdpZGdldCBhZGQgY2FsZW5kYXIgc2lkZWJhci0xIDIKICogICAgIFN1Y2Nlc3M6IEFkZGVkIHdpZGdldCB0byBzaWRlYmFyLgogKgogKiAgICAgIyBVcGRhdGUgb3B0aW9uKHMpIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIHdpZGdldAogKiAgICAgJCB3cCB3aWRnZXQgdXBkYXRlIGNhbGVuZGFyLTEgLS10aXRsZT0iQ2FsZW5kYXIiCiAqICAgICBTdWNjZXNzOiBXaWRnZXQgdXBkYXRlZC4KICoKICogICAgICMgRGVsZXRlIG9uZSBvciBtb3JlIHdpZGdldHMgZW50aXJlbHkKICogICAgICQgd3Agd2lkZ2V0IGRlbGV0ZSBjYWxlbmRhci0yIGFyY2hpdmUtMQogKiAgICAgU3VjY2VzczogMiB3aWRnZXRzIHJlbW92ZWQgZnJvbSBzaWRlYmFyLgogKi8KY2xhc3MgV2lkZ2V0X0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gWwoJCSduYW1lJywKCQknaWQnLAoJCSdwb3NpdGlvbicsCgkJJ29wdGlvbnMnLAoJXTsKCgkvKioKCSAqIExpc3RzIHdpZGdldHMgYXNzb2NpYXRlZCB3aXRoIGEgc2lkZWJhci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNpZGViYXItaWQ+CgkgKiA6IElEIGZvciB0aGUgY29ycmVzcG9uZGluZyBzaWRlYmFyLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCB3aWRnZXQ6CgkgKgoJICogKiBuYW1lCgkgKiAqIGlkCgkgKiAqIHBvc2l0aW9uCgkgKiAqIG9wdGlvbnMKCSAqCgkgKiBUaGVyZSBhcmUgbm8gb3B0aW9uYWxseSBhdmFpbGFibGUgZmllbGRzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agd2lkZ2V0IGxpc3Qgc2lkZWJhci0xIC0tZmllbGRzPW5hbWUsaWQgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbmFtZSxpZAoJICogICAgIG1ldGEsbWV0YS01CgkgKiAgICAgc2VhcmNoLHNlYXJjaC0zCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJHNpZGViYXJfaWQgKSA9ICRhcmdzOwoKCQkkdGhpcy0+dmFsaWRhdGVfc2lkZWJhciggJHNpZGViYXJfaWQgKTsKCgkJJG91dHB1dF93aWRnZXRzID0gJHRoaXMtPmdldF9zaWRlYmFyX3dpZGdldHMoICRzaWRlYmFyX2lkICk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgJiYgJ2lkcycgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJJG91dHB1dF93aWRnZXRzID0gd3BfbGlzdF9wbHVjayggJG91dHB1dF93aWRnZXRzLCAnaWQnICk7CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkb3V0cHV0X3dpZGdldHMgKTsKCgl9CgoJLyoqCgkgKiBBZGRzIGEgd2lkZ2V0IHRvIGEgc2lkZWJhci4KCSAqCgkgKiBDcmVhdGVzIGEgbmV3IHdpZGdldCBlbnRyeSBpbiB0aGUgZGF0YWJhc2UsIGFuZCBhc3NvY2lhdGVzIGl0IHdpdGggdGhlCgkgKiBzaWRlYmFyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bmFtZT4KCSAqIDogV2lkZ2V0IG5hbWUuCgkgKgoJICogPHNpZGViYXItaWQ+CgkgKiA6IElEIGZvciB0aGUgY29ycmVzcG9uZGluZyBzaWRlYmFyLgoJICoKCSAqIFs8cG9zaXRpb24+XQoJICogOiBXaWRnZXQncyBjdXJyZW50IHBvc2l0aW9uIHdpdGhpbiB0aGUgc2lkZWJhci4gRGVmYXVsdHMgdG8gbGFzdAoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogV2lkZ2V0IG9wdGlvbiB0byBhZGQsIHdpdGggaXRzIG5ldyB2YWx1ZQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQWRkIGEgbmV3IGNhbGVuZGFyIHdpZGdldCB0byBzaWRlYmFyLTEgd2l0aCB0aXRsZSAiQ2FsZW5kYXIiCgkgKiAgICAgJCB3cCB3aWRnZXQgYWRkIGNhbGVuZGFyIHNpZGViYXItMSAyIC0tdGl0bGU9IkNhbGVuZGFyIgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIHdpZGdldCB0byBzaWRlYmFyLgoJICoKCSAqIEBzdWJjb21tYW5kIGFkZAoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJG5hbWUsICRzaWRlYmFyX2lkICkgPSAkYXJnczsKCgkJJHRoaXMtPnZhbGlkYXRlX3NpZGViYXIoICRzaWRlYmFyX2lkICk7CgoJCSRwb3NpdGlvbiA9IGNvdW50KCAkYXJncyApID4gMgoJCQk/ICRhcmdzWzJdIC0gMQoJCQk6IGNvdW50KCAkdGhpcy0+Z2V0X3NpZGViYXJfd2lkZ2V0cyggJHNpZGViYXJfaWQgKSApOwoKCQkkd2lkZ2V0ID0gJHRoaXMtPmdldF93aWRnZXRfb2JqKCAkbmFtZSApOwoJCWlmICggZmFsc2UgPT09ICR3aWRnZXQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIHdpZGdldCB0eXBlLicgKTsKCQl9CgoJCS8qCgkJICogQWRkaW5nIGEgd2lkZ2V0IGlzIGFzIGVhc3kgYXM6CgkJICogMS4gQ3JlYXRpbmcgYSBuZXcgd2lkZ2V0IG9wdGlvbgoJCSAqIDIuIEFkZGluZyB0aGUgd2lkZ2V0IHRvIHRoZSBzaWRlYmFyCgkJICogMy4gUG9zaXRpb25pbmcgYXBwcm9wcmlhdGVseQoJCSAqLwoJCSR3aWRnZXRfb3B0aW9ucyA9ICR0aGlzLT5nZXRfd2lkZ2V0X29wdGlvbnMoICRuYW1lICk7CgkJJG9wdGlvbl9rZXlzICAgID0gJHdpZGdldF9vcHRpb25zOwoJCWlmICggISBpc3NldCggJHdpZGdldF9vcHRpb25zWydfbXVsdGl3aWRnZXQnXSApICkgewoJCQkkd2lkZ2V0X29wdGlvbnNbJ19tdWx0aXdpZGdldCddID0gMTsKCQl9CgkJdW5zZXQoICRvcHRpb25fa2V5c1snX211bHRpd2lkZ2V0J10gKTsKCQkkb3B0aW9uX2tleXMgICAgICAgICAgICAgICAgICAgICA9IGFycmF5X2tleXMoICRvcHRpb25fa2V5cyApOwoJCSRsYXN0X2tleSAgICAgICAgICAgICAgICAgICAgICAgID0gYXJyYXlfcG9wKCAkb3B0aW9uX2tleXMgKTsKCQkkb3B0aW9uX2luZGV4ICAgICAgICAgICAgICAgICAgICA9ICRsYXN0X2tleSArIDE7CgkJJHdpZGdldF9vcHRpb25zWyAkb3B0aW9uX2luZGV4IF0gPSAkdGhpcy0+c2FuaXRpemVfd2lkZ2V0X29wdGlvbnMoICRuYW1lLCAkYXNzb2NfYXJncywgYXJyYXkoKSApOwoJCSR0aGlzLT51cGRhdGVfd2lkZ2V0X29wdGlvbnMoICRuYW1lLCAkd2lkZ2V0X29wdGlvbnMgKTsKCgkJJHdpZGdldF9pZCA9ICRuYW1lIC4gJy0nIC4gJG9wdGlvbl9pbmRleDsKCQkkdGhpcy0+bW92ZV9zaWRlYmFyX3dpZGdldCggJHdpZGdldF9pZCwgbnVsbCwgJHNpZGViYXJfaWQsIG51bGwsICRwb3NpdGlvbiApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdBZGRlZCB3aWRnZXQgdG8gc2lkZWJhci4nICk7CgoJfQoKCS8qKgoJICogVXBkYXRlcyBvcHRpb25zIGZvciBhbiBleGlzdGluZyB3aWRnZXQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx3aWRnZXQtaWQ+CgkgKiA6IFVuaXF1ZSBJRCBmb3IgdGhlIHdpZGdldAoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmllbGQgdG8gdXBkYXRlLCB3aXRoIGl0cyBuZXcgdmFsdWUKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoYW5nZSBjYWxlbmRhci0xIHdpZGdldCB0aXRsZSB0byAiT3VyIENhbGVuZGFyIgoJICogICAgICQgd3Agd2lkZ2V0IHVwZGF0ZSBjYWxlbmRhci0xIC0tdGl0bGU9Ik91ciBDYWxlbmRhciIKCSAqICAgICBTdWNjZXNzOiBXaWRnZXQgdXBkYXRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCB1cGRhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkd2lkZ2V0X2lkICkgPSAkYXJnczsKCQlpZiAoICEgJHRoaXMtPnZhbGlkYXRlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJXaWRnZXQgZG9lc24ndCBleGlzdC4iICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gb3B0aW9ucyBzcGVjaWZpZWQgdG8gdXBkYXRlLicgKTsKCQl9CgoJCWxpc3QoICRuYW1lLCAkb3B0aW9uX2luZGV4ICkgPSAkdGhpcy0+Z2V0X3dpZGdldF9kYXRhKCAkd2lkZ2V0X2lkICk7CgoJCSR3aWRnZXRfb3B0aW9ucyAgICAgICAgICAgICAgICAgID0gJHRoaXMtPmdldF93aWRnZXRfb3B0aW9ucyggJG5hbWUgKTsKCQkkY2xlYW5fb3B0aW9ucyAgICAgICAgICAgICAgICAgICA9ICR0aGlzLT5zYW5pdGl6ZV93aWRnZXRfb3B0aW9ucyggJG5hbWUsICRhc3NvY19hcmdzLCAkd2lkZ2V0X29wdGlvbnNbICRvcHRpb25faW5kZXggXSApOwoJCSR3aWRnZXRfb3B0aW9uc1sgJG9wdGlvbl9pbmRleCBdID0gYXJyYXlfbWVyZ2UoIChhcnJheSkgJHdpZGdldF9vcHRpb25zWyAkb3B0aW9uX2luZGV4IF0sICRjbGVhbl9vcHRpb25zICk7CgkJJHRoaXMtPnVwZGF0ZV93aWRnZXRfb3B0aW9ucyggJG5hbWUsICR3aWRnZXRfb3B0aW9ucyApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdXaWRnZXQgdXBkYXRlZC4nICk7CgoJfQoKCS8qKgoJICogTW92ZXMgdGhlIHBvc2l0aW9uIG9mIGEgd2lkZ2V0LgoJICoKCSAqIENoYW5nZXMgdGhlIG9yZGVyIG9mIGEgd2lkZ2V0IGluIGl0cyBleGlzdGluZyBzaWRlYmFyLCBvciBtb3ZlcyBpdCB0byBhCgkgKiBuZXcgc2lkZWJhci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHdpZGdldC1pZD4KCSAqIDogVW5pcXVlIElEIGZvciB0aGUgd2lkZ2V0CgkgKgoJICogWy0tcG9zaXRpb249PHBvc2l0aW9uPl0KCSAqIDogQXNzaWduIHRoZSB3aWRnZXQgdG8gYSBuZXcgcG9zaXRpb24uCgkgKgoJICogWy0tc2lkZWJhci1pZD08c2lkZWJhci1pZD5dCgkgKiA6IEFzc2lnbiB0aGUgd2lkZ2V0IHRvIGEgbmV3IHNpZGViYXIKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoYW5nZSBwb3NpdGlvbiBvZiB3aWRnZXQKCSAqICAgICAkIHdwIHdpZGdldCBtb3ZlIHJlY2VudC1jb21tZW50cy0yIC0tcG9zaXRpb249MgoJICogICAgIFN1Y2Nlc3M6IFdpZGdldCBtb3ZlZC4KCSAqCgkgKiAgICAgIyBNb3ZlIHdpZGdldCB0byBJbmFjdGl2ZSBXaWRnZXRzCgkgKiAgICAgJCB3cCB3aWRnZXQgbW92ZSByZWNlbnQtY29tbWVudHMtMiAtLXNpZGViYXItaWQ9d3BfaW5hY3RpdmVfd2lkZ2V0cwoJICogICAgIFN1Y2Nlc3M6IFdpZGdldCBtb3ZlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBtb3ZlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtb3ZlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWxpc3QoICR3aWRnZXRfaWQgKSA9ICRhcmdzOwoJCWlmICggISAkdGhpcy0+dmFsaWRhdGVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIldpZGdldCBkb2Vzbid0IGV4aXN0LiIgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydwb3NpdGlvbiddICkgJiYgZW1wdHkoICRhc3NvY19hcmdzWydzaWRlYmFyLWlkJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0EgbmV3IHBvc2l0aW9uIG9yIG5ldyBzaWRlYmFyIG11c3QgYmUgc3BlY2lmaWVkLicgKTsKCQl9CgoJCWxpc3QoICRuYW1lLCAkb3B0aW9uX2luZGV4LCAkY3VycmVudF9zaWRlYmFyX2lkLCAkY3VycmVudF9zaWRlYmFyX2luZGV4ICkgPSAkdGhpcy0+Z2V0X3dpZGdldF9kYXRhKCAkd2lkZ2V0X2lkICk7CgoJCSRuZXdfc2lkZWJhcl9pZCA9ICEgZW1wdHkoICRhc3NvY19hcmdzWydzaWRlYmFyLWlkJ10gKSA/ICRhc3NvY19hcmdzWydzaWRlYmFyLWlkJ10gOiAkY3VycmVudF9zaWRlYmFyX2lkOwoJCSR0aGlzLT52YWxpZGF0ZV9zaWRlYmFyKCAkbmV3X3NpZGViYXJfaWQgKTsKCgkJJG5ld19zaWRlYmFyX2luZGV4ID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ3Bvc2l0aW9uJ10gKSA/ICRhc3NvY19hcmdzWydwb3NpdGlvbiddIC0gMSA6ICRjdXJyZW50X3NpZGViYXJfaW5kZXg7CgkJLy8gTW92aW5nIGJldHdlZW4gc2lkZWJhcnMgYWRkcyB0byB0aGUgdG9wLgoJCWlmICggJG5ld19zaWRlYmFyX2lkICE9PSAkY3VycmVudF9zaWRlYmFyX2lkICYmICRuZXdfc2lkZWJhcl9pbmRleCA9PT0gJGN1cnJlbnRfc2lkZWJhcl9pbmRleCApIHsKCQkJLy8gSHVtYW4tcmVhZGFibGUgcG9zaXRpb25zIGFyZSBkaWZmZXJlbnQgdGhhbiBudW1lcmljYWxseSBpbmRleGVkIGFycmF5LgoJCQkkbmV3X3NpZGViYXJfaW5kZXggPSAwOwoJCX0KCgkJJHRoaXMtPm1vdmVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQsICRjdXJyZW50X3NpZGViYXJfaWQsICRuZXdfc2lkZWJhcl9pZCwgJGN1cnJlbnRfc2lkZWJhcl9pbmRleCwgJG5ld19zaWRlYmFyX2luZGV4ICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1dpZGdldCBtb3ZlZC4nICk7CgoJfQoKCS8qKgoJICogRGVhY3RpdmF0ZXMgb25lIG9yIG1vcmUgd2lkZ2V0cyBmcm9tIGFuIGFjdGl2ZSBzaWRlYmFyLgoJICoKCSAqIE1vdmVzIHdpZGdldHMgdG8gSW5hY3RpdmUgV2lkZ2V0cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHdpZGdldC1pZD4uLi4KCSAqIDogVW5pcXVlIElEIGZvciB0aGUgd2lkZ2V0KHMpCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWFjdGl2YXRlIHRoZSByZWNlbnQtY29tbWVudHMtMiB3aWRnZXQuCgkgKiAgICAgJCB3cCB3aWRnZXQgZGVhY3RpdmF0ZSByZWNlbnQtY29tbWVudHMtMgoJICogICAgIFN1Y2Nlc3M6IDEgd2lkZ2V0IGRlYWN0aXZhdGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGRlYWN0aXZhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlYWN0aXZhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvdW50ICA9IDA7CgkJJGVycm9ycyA9IDA7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkd2lkZ2V0X2lkICkgewoJCQlpZiAoICEgJHRoaXMtPnZhbGlkYXRlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJXaWRnZXQgJ3skd2lkZ2V0X2lkfScgZG9lc24ndCBleGlzdC4iICk7CgkJCQkkZXJyb3JzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJbGlzdCggJG5hbWUsICRvcHRpb25faW5kZXgsICRzaWRlYmFyX2lkLCAkc2lkZWJhcl9pbmRleCApID0gJHRoaXMtPmdldF93aWRnZXRfZGF0YSggJHdpZGdldF9pZCApOwoJCQlpZiAoICd3cF9pbmFjdGl2ZV93aWRnZXRzJyA9PT0gJHNpZGViYXJfaWQgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICInJXMnIGlzIGFscmVhZHkgZGVhY3RpdmF0ZWQuIiwgJHdpZGdldF9pZCApICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHRoaXMtPm1vdmVfc2lkZWJhcl93aWRnZXQoCgkJCQkkd2lkZ2V0X2lkLAoJCQkJJHNpZGViYXJfaWQsCgkJCQknd3BfaW5hY3RpdmVfd2lkZ2V0cycsCgkJCQkkc2lkZWJhcl9pbmRleCwKCQkJCWNvdW50KCAkdGhpcy0+Z2V0X3NpZGViYXJfd2lkZ2V0cyggJ3dwX2luYWN0aXZlX3dpZGdldHMnICkgKQoJCQkpOwoKCQkJJGNvdW50Kys7CgoJCX0KCgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnd2lkZ2V0JywgJ2RlYWN0aXZhdGUnLCBjb3VudCggJGFyZ3MgKSwgJGNvdW50LCAkZXJyb3JzICk7Cgl9CgoJLyoqCgkgKiBEZWxldGVzIG9uZSBvciBtb3JlIHdpZGdldHMgZnJvbSBhIHNpZGViYXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx3aWRnZXQtaWQ+Li4uCgkgKiA6IFVuaXF1ZSBJRCBmb3IgdGhlIHdpZGdldChzKQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHRoZSByZWNlbnQtY29tbWVudHMtMiB3aWRnZXQgZnJvbSBpdHMgc2lkZWJhci4KCSAqICAgICAkIHdwIHdpZGdldCBkZWxldGUgcmVjZW50LWNvbW1lbnRzLTIKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIDEgb2YgMSB3aWRnZXRzLgoJICoKCSAqIEBzdWJjb21tYW5kIGRlbGV0ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRjb3VudCAgPSAwOwoJCSRlcnJvcnMgPSAwOwoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJHdpZGdldF9pZCApIHsKCQkJaWYgKCAhICR0aGlzLT52YWxpZGF0ZV9zaWRlYmFyX3dpZGdldCggJHdpZGdldF9pZCApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiV2lkZ2V0ICd7JHdpZGdldF9pZH0nIGRvZXNuJ3QgZXhpc3QuIiApOwoJCQkJJGVycm9ycysrOwoJCQkJY29udGludWU7CgkJCX0KCgkJCS8vIFJlbW92ZSB0aGUgd2lkZ2V0J3Mgc2V0dGluZ3MuCgkJCWxpc3QoICRuYW1lLCAkb3B0aW9uX2luZGV4LCAkc2lkZWJhcl9pZCwgJHNpZGViYXJfaW5kZXggKSA9ICR0aGlzLT5nZXRfd2lkZ2V0X2RhdGEoICR3aWRnZXRfaWQgKTsKCQkJJHdpZGdldF9vcHRpb25zID0gJHRoaXMtPmdldF93aWRnZXRfb3B0aW9ucyggJG5hbWUgKTsKCQkJdW5zZXQoICR3aWRnZXRfb3B0aW9uc1sgJG9wdGlvbl9pbmRleCBdICk7CgkJCSR0aGlzLT51cGRhdGVfd2lkZ2V0X29wdGlvbnMoICRuYW1lLCAkd2lkZ2V0X29wdGlvbnMgKTsKCgkJCS8vIFJlbW92ZSB0aGUgd2lkZ2V0IGZyb20gdGhlIHNpZGViYXIuCgkJCSRhbGxfd2lkZ2V0cyA9ICR0aGlzLT53cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpOwoJCQl1bnNldCggJGFsbF93aWRnZXRzWyAkc2lkZWJhcl9pZCBdWyAkc2lkZWJhcl9pbmRleCBdICk7CgkJCSRhbGxfd2lkZ2V0c1sgJHNpZGViYXJfaWQgXSA9IGFycmF5X3ZhbHVlcyggJGFsbF93aWRnZXRzWyAkc2lkZWJhcl9pZCBdICk7CgkJCXVwZGF0ZV9vcHRpb24oICdzaWRlYmFyc193aWRnZXRzJywgJGFsbF93aWRnZXRzICk7CgoJCQkkY291bnQrKzsKCQl9CgoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ3dpZGdldCcsICdkZWxldGUnLCBjb3VudCggJGFyZ3MgKSwgJGNvdW50LCAkZXJyb3JzICk7Cgl9CgoJLyoqCgkgKiBSZXNldHMgc2lkZWJhci4KCSAqCgkgKiBSZW1vdmVzIGFsbCB3aWRnZXRzIGZyb20gdGhlIHNpZGViYXIgYW5kIHBsYWNlcyB0aGVtIGluIEluYWN0aXZlIFdpZGdldHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8c2lkZWJhci1pZD4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHNpZGViYXJzIHRvIHJlc2V0LgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgc2lkZWJhcnMgd2lsbCBiZSByZXNldC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFJlc2V0IGEgc2lkZWJhcgoJICogICAgICQgd3Agd2lkZ2V0IHJlc2V0IHNpZGViYXItMQoJICogICAgIFN1Y2Nlc3M6IFNpZGViYXIgJ3NpZGViYXItMScgcmVzZXQuCgkgKgoJICogICAgICMgUmVzZXQgbXVsdGlwbGUgc2lkZWJhcnMKCSAqICAgICAkIHdwIHdpZGdldCByZXNldCBzaWRlYmFyLTEgc2lkZWJhci0yCgkgKiAgICAgU3VjY2VzczogU2lkZWJhciAnc2lkZWJhci0xJyByZXNldC4KCSAqICAgICBTdWNjZXNzOiBTaWRlYmFyICdzaWRlYmFyLTInIHJlc2V0LgoJICoKCSAqICAgICAjIFJlc2V0IGFsbCBzaWRlYmFycwoJICogICAgICQgd3Agd2lkZ2V0IHJlc2V0IC0tYWxsCgkgKiAgICAgU3VjY2VzczogU2lkZWJhciAnc2lkZWJhci0xJyByZXNldC4KCSAqICAgICBTdWNjZXNzOiBTaWRlYmFyICdzaWRlYmFyLTInIHJlc2V0LgoJICogICAgIFN1Y2Nlc3M6IFNpZGViYXIgJ3NpZGViYXItMycgcmVzZXQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXNldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlnbG9iYWwgJHdwX3JlZ2lzdGVyZWRfc2lkZWJhcnM7CgoJCSRhbGwgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQkvLyBCYWlsIGlmIG5vIGFyZ3VtZW50cyBhbmQgbm8gYWxsIGZsYWcuCgkJaWYgKCAhICRhbGwgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSBzaWRlYmFycywgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCS8vIEZldGNoIGFsbCBzaWRlYmFycyBpZiBhbGwgZmxhZyBpcyBzZXQuCgkJaWYgKCAkYWxsICkgewoJCQkkYXJncyA9IGFycmF5X2tleXMoICR3cF9yZWdpc3RlcmVkX3NpZGViYXJzICk7CgkJfQoKCQkvLyBTaWRlYmFyIElEIHdwX2luYWN0aXZlX3dpZGdldHMgaXMgcmVzZXJ2ZWQgYnkgV1AgY29yZSBmb3IgaW5hY3RpdmUgd2lkZ2V0cy4KCQlpZiAoIGlzc2V0KCAkYXJnc1snd3BfaW5hY3RpdmVfd2lkZ2V0cyddICkgKSB7CgkJCXVuc2V0KCAkYXJnc1snd3BfaW5hY3RpdmVfd2lkZ2V0cyddICk7CgkJfQoKCQkvLyBDaGVjayBpZiBubyByZWdpc3RlcmVkIHNpZGViYXIuCgkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ05vIHNpZGViYXIgcmVnaXN0ZXJlZC4nICk7CgkJfQoKCQkkY291bnQgID0gMDsKCQkkZXJyb3JzID0gMDsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJHNpZGViYXJfaWQgKSB7CgkJCWlmICggISBhcnJheV9rZXlfZXhpc3RzKCAkc2lkZWJhcl9pZCwgJHdwX3JlZ2lzdGVyZWRfc2lkZWJhcnMgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0ludmFsaWQgc2lkZWJhcjogJXMnLCAkc2lkZWJhcl9pZCApICk7CgkJCQkkZXJyb3JzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHdpZGdldHMgPSAkdGhpcy0+Z2V0X3NpZGViYXJfd2lkZ2V0cyggJHNpZGViYXJfaWQgKTsKCQkJaWYgKCBlbXB0eSggJHdpZGdldHMgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggIlNpZGViYXIgJyVzJyBpcyBhbHJlYWR5IGVtcHR5LiIsICRzaWRlYmFyX2lkICkgKTsKCQkJfSBlbHNlIHsKCQkJCWZvcmVhY2ggKCAkd2lkZ2V0cyBhcyAkd2lkZ2V0ICkgewoJCQkJCSR3aWRnZXRfaWQgPSAkd2lkZ2V0LT5pZDsKCQkJCQlsaXN0KCAkbmFtZSwgJG9wdGlvbl9pbmRleCwgJG5ld19zaWRlYmFyX2lkLCAkc2lkZWJhcl9pbmRleCApID0gJHRoaXMtPmdldF93aWRnZXRfZGF0YSggJHdpZGdldF9pZCApOwoJCQkJCSR0aGlzLT5tb3ZlX3NpZGViYXJfd2lkZ2V0KAoJCQkJCQkkd2lkZ2V0X2lkLAoJCQkJCQkkbmV3X3NpZGViYXJfaWQsCgkJCQkJCSd3cF9pbmFjdGl2ZV93aWRnZXRzJywKCQkJCQkJJHNpZGViYXJfaW5kZXgsCgkJCQkJCWNvdW50KCAkdGhpcy0+Z2V0X3NpZGViYXJfd2lkZ2V0cyggJ3dwX2luYWN0aXZlX3dpZGdldHMnICkgKQoJCQkJCSk7CgkJCQl9CgkJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggIlNpZGViYXIgJyVzJyByZXNldC4iLCAkc2lkZWJhcl9pZCApICk7CgkJCQkkY291bnQrKzsKCQkJfQoJCX0KCgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnc2lkZWJhcicsICdyZXNldCcsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIGEgc2lkZWJhciBpcyBhIHZhbGlkIHNpZGViYXIKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzaWRlYmFyX2lkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVfc2lkZWJhciggJHNpZGViYXJfaWQgKSB7CgkJZ2xvYmFsICR3cF9yZWdpc3RlcmVkX3NpZGViYXJzOwoKCQlVdGlsc1x3cF9yZWdpc3Rlcl91bnVzZWRfc2lkZWJhcigpOwoKCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJHNpZGViYXJfaWQsICR3cF9yZWdpc3RlcmVkX3NpZGViYXJzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIHNpZGViYXIuJyApOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgd2lkZ2V0IGlzIG9uIHRoZSBzaWRlYmFyCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd2lkZ2V0X2lkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQgKSB7CgoJCSRzaWRlYmFyc193aWRnZXRzID0gJHRoaXMtPndwX2dldF9zaWRlYmFyc193aWRnZXRzKCk7CgoJCSR3aWRnZXRfZXhpc3RzID0gZmFsc2U7CgkJZm9yZWFjaCAoICRzaWRlYmFyc193aWRnZXRzIGFzICRzaWRlYmFyX2lkID0+ICR3aWRnZXRzICkgewoKCQkJaWYgKCBpbl9hcnJheSggJHdpZGdldF9pZCwgJHdpZGdldHMsIHRydWUgKSApIHsKCQkJCSR3aWRnZXRfZXhpc3RzID0gdHJ1ZTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXJldHVybiAkd2lkZ2V0X2V4aXN0czsKCX0KCgkvKioKCSAqIEdldHMgdGhlIHdpZGdldHMgKGFuZCB0aGVpciBhc3NvY2lhdGVkIGRhdGEpIGZvciBhIGdpdmVuIHNpZGViYXIKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzaWRlYmFyX2lkCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3NpZGViYXJfd2lkZ2V0cyggJHNpZGViYXJfaWQgKSB7CgoJCSRhbGxfd2lkZ2V0cyA9ICR0aGlzLT53cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpOwoKCQlpZiAoIGVtcHR5KCAkYWxsX3dpZGdldHNbICRzaWRlYmFyX2lkIF0gKSApIHsKCQkJcmV0dXJuIGFycmF5KCk7CgkJfQoKCQkkcHJlcGFyZWRfd2lkZ2V0cyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICRhbGxfd2lkZ2V0c1sgJHNpZGViYXJfaWQgXSBhcyAka2V5ID0+ICR3aWRnZXRfaWQgKSB7CgoJCQkkcHJlcGFyZWRfd2lkZ2V0ID0gbmV3IHN0ZENsYXNzKCk7CgoJCQkkcGFydHMgICAgICAgID0gZXhwbG9kZSggJy0nLCAkd2lkZ2V0X2lkICk7CgkJCSRvcHRpb25faW5kZXggPSBhcnJheV9wb3AoICRwYXJ0cyApOwoJCQkkd2lkZ2V0X25hbWUgID0gaW1wbG9kZSggJy0nLCAkcGFydHMgKTsKCgkJCSRwcmVwYXJlZF93aWRnZXQtPm5hbWUgICAgID0gJHdpZGdldF9uYW1lOwoJCQkkcHJlcGFyZWRfd2lkZ2V0LT5pZCAgICAgICA9ICR3aWRnZXRfaWQ7CgkJCSRwcmVwYXJlZF93aWRnZXQtPnBvc2l0aW9uID0gJGtleSArIDE7CgkJCSR3aWRnZXRfb3B0aW9ucyAgICAgICAgICAgID0gZ2V0X29wdGlvbiggJ3dpZGdldF8nIC4gJHdpZGdldF9uYW1lICk7CgkJCSRwcmVwYXJlZF93aWRnZXQtPm9wdGlvbnMgID0gJHdpZGdldF9vcHRpb25zWyAkb3B0aW9uX2luZGV4IF07CgoJCQkkcHJlcGFyZWRfd2lkZ2V0c1tdID0gJHByZXBhcmVkX3dpZGdldDsKCQl9CgoJCXJldHVybiAkcHJlcGFyZWRfd2lkZ2V0czsKCX0KCgkvKioKCSAqIFJlLWltcGxlbWVudGF0aW9uIG9mIHdwX2dldF9zaWRlYmFyc193aWRnZXRzKCkKCSAqIGJlY2F1c2UgdGhlIG9yaWdpbmFsIGhhcyBhIG5hc3R5IGdsb2JhbCBjb21wb25lbnQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB3cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpIHsKCQkkc2lkZWJhcnNfd2lkZ2V0cyA9IGdldF9vcHRpb24oICdzaWRlYmFyc193aWRnZXRzJywgYXJyYXkoKSApOwoKCQlpZiAoIGlzX2FycmF5KCAkc2lkZWJhcnNfd2lkZ2V0cyApICYmIGlzc2V0KCAkc2lkZWJhcnNfd2lkZ2V0c1snYXJyYXlfdmVyc2lvbiddICkgKSB7CgkJCXVuc2V0KCAkc2lkZWJhcnNfd2lkZ2V0c1snYXJyYXlfdmVyc2lvbiddICk7CgkJfQoKCQlyZXR1cm4gJHNpZGViYXJzX3dpZGdldHM7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB3aWRnZXQncyBuYW1lLCBvcHRpb24gaW5kZXgsIHNpZGViYXIsIGFuZCBzaWRlYmFyIGluZGV4IGZyb20gaXRzIElECgkgKgoJICogQHBhcmFtIHN0cmluZyAkd2lkZ2V0X2lkCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3dpZGdldF9kYXRhKCAkd2lkZ2V0X2lkICkgewoKCQkkcGFydHMgICAgICAgID0gZXhwbG9kZSggJy0nLCAkd2lkZ2V0X2lkICk7CgkJJG9wdGlvbl9pbmRleCA9IGFycmF5X3BvcCggJHBhcnRzICk7CgkJJG5hbWUgICAgICAgICA9IGltcGxvZGUoICctJywgJHBhcnRzICk7CgoJCSRzaWRlYmFyX2lkICAgID0gZmFsc2U7CgkJJHNpZGViYXJfaW5kZXggPSBmYWxzZTsKCQkkYWxsX3dpZGdldHMgICA9ICR0aGlzLT53cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpOwoJCWZvcmVhY2ggKCAkYWxsX3dpZGdldHMgYXMgJHNfaWQgPT4gJiR3aWRnZXRzICkgewoKCQkJJGtleSA9IGFycmF5X3NlYXJjaCggJHdpZGdldF9pZCwgJHdpZGdldHMsIHRydWUgKTsKCQkJaWYgKCBmYWxzZSAhPT0gJGtleSApIHsKCQkJCSRzaWRlYmFyX2lkICAgID0gJHNfaWQ7CgkJCQkkc2lkZWJhcl9pbmRleCA9ICRrZXk7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJcmV0dXJuIGFycmF5KCAkbmFtZSwgJG9wdGlvbl9pbmRleCwgJHNpZGViYXJfaWQsICRzaWRlYmFyX2luZGV4ICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBvcHRpb25zIGZvciBhIGdpdmVuIHdpZGdldAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfd2lkZ2V0X29wdGlvbnMoICRuYW1lICkgewoJCXJldHVybiBnZXRfb3B0aW9uKCAnd2lkZ2V0XycgLiAkbmFtZSwgYXJyYXkoKSApOwoJfQoKCS8qKgoJICogVXBkYXRlcyB0aGUgb3B0aW9ucyBmb3IgYSBnaXZlbiB3aWRnZXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lCgkgKiBAcGFyYW0gbWl4ZWQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB1cGRhdGVfd2lkZ2V0X29wdGlvbnMoICRuYW1lLCAkdmFsdWUgKSB7CgkJdXBkYXRlX29wdGlvbiggJ3dpZGdldF8nIC4gJG5hbWUsICR2YWx1ZSApOwoJfQoKCS8qKgoJICogUmVwb3NpdGlvbnMgYSB3aWRnZXQgd2l0aGluIGEgc2lkZWJhciBvciBtb3ZlIHRvIGFub3RoZXIgc2lkZWJhci4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3aWRnZXRfaWQKCSAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY3VycmVudF9zaWRlYmFyX2lkCgkgKiBAcGFyYW0gc3RyaW5nICRuZXdfc2lkZWJhcl9pZAoJICogQHBhcmFtIGludHxudWxsICRjdXJyZW50X2luZGV4CgkgKiBAcGFyYW0gaW50ICRuZXdfaW5kZXgKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBtb3ZlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkLCAkY3VycmVudF9zaWRlYmFyX2lkLCAkbmV3X3NpZGViYXJfaWQsICRjdXJyZW50X2luZGV4LCAkbmV3X2luZGV4ICkgewoKCQkkYWxsX3dpZGdldHMgICAgID0gJHRoaXMtPndwX2dldF9zaWRlYmFyc193aWRnZXRzKCk7CgkJJG5lZWRzX3BsYWNlbWVudCA9IHRydWU7CgkJLy8gRXhpc3Rpbmcgd2lkZ2V0CgkJaWYgKCAkY3VycmVudF9zaWRlYmFyX2lkICYmICEgaXNfbnVsbCggJGN1cnJlbnRfaW5kZXggKSApIHsKCgkJCSR3aWRnZXRzID0gJGFsbF93aWRnZXRzWyAkY3VycmVudF9zaWRlYmFyX2lkIF07CgkJCWlmICggJGN1cnJlbnRfc2lkZWJhcl9pZCAhPT0gJG5ld19zaWRlYmFyX2lkICkgewoKCQkJCXVuc2V0KCAkd2lkZ2V0c1sgJGN1cnJlbnRfaW5kZXggXSApOwoKCQkJfSBlbHNlIHsKCgkJCQkkcGFydCA9IGFycmF5X3NwbGljZSggJHdpZGdldHMsICRjdXJyZW50X2luZGV4LCAxICk7CgkJCQlhcnJheV9zcGxpY2UoICR3aWRnZXRzLCAkbmV3X2luZGV4LCAwLCAkcGFydCApOwoKCQkJCSRuZWVkc19wbGFjZW1lbnQgPSBmYWxzZTsKCgkJCX0KCgkJCSRhbGxfd2lkZ2V0c1sgJGN1cnJlbnRfc2lkZWJhcl9pZCBdID0gYXJyYXlfdmFsdWVzKCAkd2lkZ2V0cyApOwoKCQl9CgoJCWlmICggJG5lZWRzX3BsYWNlbWVudCApIHsKCQkJJHdpZGdldHMgICAgICAgICAgICAgICAgICAgICAgICA9ICEgZW1wdHkoICRhbGxfd2lkZ2V0c1sgJG5ld19zaWRlYmFyX2lkIF0gKSA/ICRhbGxfd2lkZ2V0c1sgJG5ld19zaWRlYmFyX2lkIF0gOiBhcnJheSgpOwoJCQkkYmVmb3JlICAgICAgICAgICAgICAgICAgICAgICAgID0gYXJyYXlfc2xpY2UoICR3aWRnZXRzLCAwLCAkbmV3X2luZGV4LCB0cnVlICk7CgkJCSRhZnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgPSBhcnJheV9zbGljZSggJHdpZGdldHMsICRuZXdfaW5kZXgsIGNvdW50KCAkd2lkZ2V0cyApLCB0cnVlICk7CgkJCSR3aWRnZXRzICAgICAgICAgICAgICAgICAgICAgICAgPSBhcnJheV9tZXJnZSggJGJlZm9yZSwgYXJyYXkoICR3aWRnZXRfaWQgKSwgJGFmdGVyICk7CgkJCSRhbGxfd2lkZ2V0c1sgJG5ld19zaWRlYmFyX2lkIF0gPSBhcnJheV92YWx1ZXMoICR3aWRnZXRzICk7CgkJfQoKCQl1cGRhdGVfb3B0aW9uKCAnc2lkZWJhcnNfd2lkZ2V0cycsICRhbGxfd2lkZ2V0cyApOwoKCX0KCgkvKioKCSAqIEdldHMgYSB3aWRnZXQncyBpbnN0YW50aWF0ZWQgb2JqZWN0IGJhc2VkIG9uIGl0cyBuYW1lCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaWRfYmFzZSBOYW1lIG9mIHRoZSB3aWRnZXQKCSAqIEByZXR1cm4gV1BfV2lkZ2V0fGZhbHNlCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3dpZGdldF9vYmooICRpZF9iYXNlICkgewoJCWdsb2JhbCAkd3Bfd2lkZ2V0X2ZhY3Rvcnk7CgoJCSR3aWRnZXQgPSB3cF9maWx0ZXJfb2JqZWN0X2xpc3QoICR3cF93aWRnZXRfZmFjdG9yeS0+d2lkZ2V0cywgYXJyYXkoICdpZF9iYXNlJyA9PiAkaWRfYmFzZSApICk7CgkJaWYgKCBlbXB0eSggJHdpZGdldCApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gYXJyYXlfcG9wKCAkd2lkZ2V0ICk7Cgl9CgoJLyoqCgkgKiBDbGVhbnMgdXAgYSB3aWRnZXQncyBvcHRpb25zIGJhc2VkIG9uIGl0cyB1cGRhdGUgY2FsbGJhY2sKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRpZF9iYXNlIE5hbWUgb2YgdGhlIHdpZGdldAoJICogQHBhcmFtIG1peGVkICRkaXJ0eV9vcHRpb25zCgkgKiBAcGFyYW0gbWl4ZWQgJG9sZF9vcHRpb25zCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gc2FuaXRpemVfd2lkZ2V0X29wdGlvbnMoICRpZF9iYXNlLCAkZGlydHlfb3B0aW9ucywgJG9sZF9vcHRpb25zICkgewoKCQkkd2lkZ2V0ID0gJHRoaXMtPmdldF93aWRnZXRfb2JqKCAkaWRfYmFzZSApOwoJCWlmICggZW1wdHkoICR3aWRnZXQgKSApIHsKCQkJcmV0dXJuIGFycmF5KCk7CgkJfQoKCQkvLyBObyBlYXN5IHdheSB0byBkZXRlcm1pbmUgZXhwZWN0ZWQgYXJyYXkga2V5cyBmb3IgJGRpcnR5X29wdGlvbnMKCQkvLyBiZWNhdXNlIFdpZGdldCBBUEkgZGVwZW5kZW50IG9uIHRoZSBmb3JtIGZpZWxkcwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuUEhQLk5vU2lsZW5jZWRFcnJvcnMuRGlzY291cmFnZWQgLS0gV2hpdGVsaXN0aW5nIGR1ZSB0byBhYm92ZSByZWFzb24uCgkJcmV0dXJuIEAkd2lkZ2V0LT51cGRhdGUoICRkaXJ0eV9vcHRpb25zLCAkb2xkX29wdGlvbnMgKTsKCgl9Cgp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfd2lkZ2V0X2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX3dpZGdldF9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX3dpZGdldF9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnd2lkZ2V0JywgJ1dpZGdldF9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2lkZWJhcicsICdTaWRlYmFyX0NvbW1hbmQnICk7Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXE1haW50ZW5hbmNlTW9kZTsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElfQ29tbWFuZDsKdXNlIFdQX1VwZ3JhZGVyOwp1c2UgV1BfRmlsZXN5c3RlbV9CYXNlOwoKLyoqCiAqIEFjdGl2YXRlcywgZGVhY3RpdmF0ZXMgb3IgY2hlY2tzIHRoZSBzdGF0dXMgb2YgdGhlIG1haW50ZW5hbmNlIG1vZGUgb2YgYSBzaXRlLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBBY3RpdmF0ZSBNYWludGVuYW5jZSBtb2RlLgogKiAgICAgJCB3cCBtYWludGVuYW5jZS1tb2RlIGFjdGl2YXRlCiAqICAgICBFbmFibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCiAqICAgICBTdWNjZXNzOiBBY3RpdmF0ZWQgTWFpbnRlbmFuY2UgbW9kZS4KICoKICogICAgICMgRGVhY3RpdmF0ZSBNYWludGVuYW5jZSBtb2RlLgogKiAgICAgJCB3cCBtYWludGVuYW5jZS1tb2RlIGRlYWN0aXZhdGUKICogICAgIERpc2FibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCiAqICAgICBTdWNjZXNzOiBEZWFjdGl2YXRlZCBNYWludGVuYW5jZSBtb2RlLgogKgogKiAgICAgIyBEaXNwbGF5IE1haW50ZW5hbmNlIG1vZGUgc3RhdHVzLgogKiAgICAgJCB3cCBtYWludGVuYW5jZS1tb2RlIHN0YXR1cwogKiAgICAgTWFpbnRlbmFuY2UgbW9kZSBpcyBhY3RpdmUuCiAqCiAqICAgICAjIEdldCBNYWludGVuYW5jZSBtb2RlIHN0YXR1cyBmb3Igc2NyaXB0aW5nIHB1cnBvc2UuCiAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgaXMtYWN0aXZlCiAqICAgICAkIGVjaG8gJD8KICogICAgIDEKICoKICogQHdoZW4gICAgYWZ0ZXJfd3BfbG9hZAogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIE1haW50ZW5hbmNlTW9kZUNvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoKCS8qKgoJICogSW5zdGFuY2Ugb2YgV1BfVXBncmFkZXIuCgkgKgoJICogQHZhciBXUF9VcGdyYWRlcgoJICovCglwcml2YXRlICR1cGdyYWRlcjsKCgkvKioKCSAqIEluc3RhbnRpYXRlIGEgTWFpbnRlbmFuY2VNb2RlQ29tbWFuZCBvYmplY3QuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQlpZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfVXBncmFkZXInICkgKSB7CgkJCXJlcXVpcmVfb25jZSBBQlNQQVRIIC4gJ3dwLWFkbWluL2luY2x1ZGVzL2NsYXNzLXdwLXVwZ3JhZGVyLnBocCc7CgkJfQoJCSR0aGlzLT51cGdyYWRlciA9IG5ldyBXUF9VcGdyYWRlciggbmV3IFdQX0NMSVxVcGdyYWRlclNraW4oKSApOwoJCSR0aGlzLT51cGdyYWRlci0+aW5pdCgpOwoJfQoKCS8qKgoJICogQWN0aXZhdGVzIG1haW50ZW5hbmNlIG1vZGUuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IEZvcmNlIG1haW50ZW5hbmNlIG1vZGUgYWN0aXZhdGlvbiBvcGVyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtYWludGVuYW5jZS1tb2RlIGFjdGl2YXRlCgkgKiAgICAgRW5hYmxpbmcgTWFpbnRlbmFuY2UgbW9kZS4uLgoJICogICAgIFN1Y2Nlc3M6IEFjdGl2YXRlZCBNYWludGVuYW5jZSBtb2RlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWN0aXZhdGUoICRfLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICR0aGlzLT5nZXRfbWFpbnRlbmFuY2VfbW9kZV9zdGF0dXMoKSAmJiAhIFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ01haW50ZW5hbmNlIG1vZGUgYWxyZWFkeSBhY3RpdmF0ZWQuJyApOwoJCX0KCgkJJHRoaXMtPnVwZ3JhZGVyLT5tYWludGVuYW5jZV9tb2RlKCB0cnVlICk7CgkJV1BfQ0xJOjpzdWNjZXNzKCAnQWN0aXZhdGVkIE1haW50ZW5hbmNlIG1vZGUuJyApOwoJfQoKCS8qKgoJICogRGVhY3RpdmF0ZXMgbWFpbnRlbmFuY2UgbW9kZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgZGVhY3RpdmF0ZQoJICogICAgIERpc2FibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCgkgKiAgICAgU3VjY2VzczogRGVhY3RpdmF0ZWQgTWFpbnRlbmFuY2UgbW9kZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlYWN0aXZhdGUoKSB7CgkJaWYgKCAhICR0aGlzLT5nZXRfbWFpbnRlbmFuY2VfbW9kZV9zdGF0dXMoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ01haW50ZW5hbmNlIG1vZGUgYWxyZWFkeSBkZWFjdGl2YXRlZC4nICk7CgkJfQoKCQkkdGhpcy0+dXBncmFkZXItPm1haW50ZW5hbmNlX21vZGUoIGZhbHNlICk7CgkJV1BfQ0xJOjpzdWNjZXNzKCAnRGVhY3RpdmF0ZWQgTWFpbnRlbmFuY2UgbW9kZS4nICk7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5cyBtYWludGVuYW5jZSBtb2RlIHN0YXR1cy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgc3RhdHVzCgkgKiAgICAgTWFpbnRlbmFuY2UgbW9kZSBpcyBhY3RpdmUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdGF0dXMoKSB7CgkJJHN0YXR1cyA9ICR0aGlzLT5nZXRfbWFpbnRlbmFuY2VfbW9kZV9zdGF0dXMoKSA/ICdhY3RpdmUnIDogJ25vdCBhY3RpdmUnOwoJCVdQX0NMSTo6bGluZSggIk1haW50ZW5hbmNlIG1vZGUgaXMgeyRzdGF0dXN9LiIgKTsKCX0KCgkvKioKCSAqIERldGVjdHMgbWFpbnRlbmFuY2UgbW9kZSBzdGF0dXMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtYWludGVuYW5jZS1tb2RlIGlzLWFjdGl2ZQoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiBAc3ViY29tbWFuZCBpcy1hY3RpdmUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2FjdGl2ZSgpIHsKCQlXUF9DTEk6OmhhbHQoICR0aGlzLT5nZXRfbWFpbnRlbmFuY2VfbW9kZV9zdGF0dXMoKSA/IDAgOiAxICk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHN0YXR1cyBvZiBtYWludGVuYW5jZSBtb2RlLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9tYWludGVuYW5jZV9tb2RlX3N0YXR1cygpIHsKCQkkd3BfZmlsZXN5c3RlbSA9ICR0aGlzLT5pbml0X3dwX2ZpbGVzeXN0ZW0oKTsKCgkJJG1haW50ZW5hbmNlX2ZpbGUgPSB0cmFpbGluZ3NsYXNoaXQoICR3cF9maWxlc3lzdGVtLT5hYnNwYXRoKCkgKSAuICcubWFpbnRlbmFuY2UnOwoKCQlyZXR1cm4gJHdwX2ZpbGVzeXN0ZW0tPmV4aXN0cyggJG1haW50ZW5hbmNlX2ZpbGUgKTsKCX0KCgkvKioKCSAqIEluaXRpYWxpemVzIFdQX0ZpbGVzeXN0ZW0uCgkgKgoJICogQHJldHVybiBXUF9GaWxlc3lzdGVtX0Jhc2UKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRfd3BfZmlsZXN5c3RlbSgpIHsKCQlnbG9iYWwgJHdwX2ZpbGVzeXN0ZW07CgkJV1BfRmlsZXN5c3RlbSgpOwoKCQlyZXR1cm4gJHdwX2ZpbGVzeXN0ZW07Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9tYWludGVuYW5jZV9tb2RlX2F1dG9sb2FkZXIgPSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9tYWludGVuYW5jZV9tb2RlX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfbWFpbnRlbmFuY2VfbW9kZV9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnbWFpbnRlbmFuY2UtbW9kZScsICdcV1BfQ0xJXE1haW50ZW5hbmNlTW9kZVxNYWludGVuYW5jZU1vZGVDb21tYW5kJyApOwo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxTaGVsbDsKCnVzZSBXUF9DTEk7CgpjbGFzcyBSRVBMIHsKCglwcml2YXRlICRwcm9tcHQ7CgoJcHJpdmF0ZSAkaGlzdG9yeV9maWxlOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJHByb21wdCApIHsKCQkkdGhpcy0+cHJvbXB0ID0gJHByb21wdDsKCgkJJHRoaXMtPnNldF9oaXN0b3J5X2ZpbGUoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gc3RhcnQoKSB7CgkJd2hpbGUgKCB0cnVlICkgewoJCQkkbGluZSA9ICR0aGlzLT5wcm9tcHQoKTsKCgkJCWlmICggJycgPT09ICRsaW5lICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRsaW5lID0gcnRyaW0oICRsaW5lLCAnOycgKSAuICc7JzsKCgkJCWlmICggc2VsZjo6c3RhcnRzX3dpdGgoIHNlbGY6Om5vbl9leHByZXNzaW9ucygpLCAkbGluZSApICkgewoJCQkJb2Jfc3RhcnQoKTsKCQkJCS8vIHBocGNzOmlnbm9yZSBTcXVpei5QSFAuRXZhbC5EaXNjb3VyYWdlZCAtLSBUaGlzIGlzIG1lYW50IHRvIGJlIGEgUkVQTCwgbm8gd2F5IHRvIGF2b2lkIGV2YWwuCgkJCQlldmFsKCAkbGluZSApOwoJCQkJJG91dCA9IG9iX2dldF9jbGVhbigpOwoJCQkJaWYgKCAwIDwgc3RybGVuKCAkb3V0ICkgKSB7CgkJCQkJJG91dCA9IHJ0cmltKCAkb3V0LCAiXG4iICkgLiAiXG4iOwoJCQkJfQoJCQkJZndyaXRlKCBTVERPVVQsICRvdXQgKTsKCQkJfSBlbHNlIHsKCQkJCWlmICggISBzZWxmOjpzdGFydHNfd2l0aCggJ3JldHVybicsICRsaW5lICkgKSB7CgkJCQkJJGxpbmUgPSAncmV0dXJuICcgLiAkbGluZTsKCQkJCX0KCgkJCQkvLyBXcml0ZSBkaXJlY3RseSB0byBTVERPVVQsIHRvIHNpZGVzdGVwIGFueSBvdXRwdXQgYnVmZmVycyBjcmVhdGVkIGJ5IHBsdWdpbnMKCQkJCW9iX3N0YXJ0KCk7CgkJCQkvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkV2YWwuRGlzY291cmFnZWQgLS0gVGhpcyBpcyBtZWFudCB0byBiZSBhIFJFUEwsIG5vIHdheSB0byBhdm9pZCBldmFsLgoJCQkJJGV2bCA9IGV2YWwoICRsaW5lICk7CgkJCQkkb3V0ID0gb2JfZ2V0X2NsZWFuKCk7CgkJCQlpZiAoIDAgPCBzdHJsZW4oICRvdXQgKSApIHsKCQkJCQllY2hvIHJ0cmltKCAkb3V0LCAiXG4iICkgLiAiXG4iOwoJCQkJfQoJCQkJZWNobyAnPT4gJzsKCQkJCXZhcl9kdW1wKCAkZXZsICk7CgkJCQlmd3JpdGUoIFNURE9VVCwgb2JfZ2V0X2NsZWFuKCkgKTsKCQkJfQoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBub25fZXhwcmVzc2lvbnMoKSB7CgkJcmV0dXJuIGltcGxvZGUoCgkJCSd8JywKCQkJYXJyYXkoCgkJCQknZWNobycsCgkJCQknZ2xvYmFsJywKCQkJCSd1bnNldCcsCgkJCQknZnVuY3Rpb24nLAoJCQkJJ3doaWxlJywKCQkJCSdmb3InLAoJCQkJJ2ZvcmVhY2gnLAoJCQkJJ2lmJywKCQkJCSdzd2l0Y2gnLAoJCQkJJ2luY2x1ZGUnLAoJCQkJJ2luY2x1ZGVcX29uY2UnLAoJCQkJJ3JlcXVpcmUnLAoJCQkJJ3JlcXVpcmVcX29uY2UnLAoJCQkpCgkJKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHByb21wdCgpIHsKCQkkZnVsbF9saW5lID0gZmFsc2U7CgoJCSRkb25lID0gZmFsc2U7CgkJZG8gewoJCQkkcHJvbXB0ID0gKCAhICRkb25lICYmIGZhbHNlICE9PSAkZnVsbF9saW5lICkgPyAnLS0+ICcgOiAkdGhpcy0+cHJvbXB0OwoKCQkJJGZwID0gcG9wZW4oIHNlbGY6OmNyZWF0ZV9wcm9tcHRfY21kKCAkcHJvbXB0LCAkdGhpcy0+aGlzdG9yeV9maWxlICksICdyJyApOwoKCQkJJGxpbmUgPSBmZ2V0cyggJGZwICk7CgoJCQlwY2xvc2UoICRmcCApOwoKCQkJaWYgKCAhICRsaW5lICkgewoJCQkJYnJlYWs7CgkJCX0KCgkJCSRsaW5lID0gcnRyaW0oICRsaW5lLCAiXG4iICk7CgoJCQlpZiAoICRsaW5lICYmICdcXCcgPT09ICRsaW5lWyBzdHJsZW4oICRsaW5lICkgLSAxIF0gKSB7CgkJCQkkbGluZSA9IHN1YnN0ciggJGxpbmUsIDAsIC0xICk7CgkJCX0gZWxzZSB7CgkJCQkkZG9uZSA9IHRydWU7CgkJCX0KCgkJCSRmdWxsX2xpbmUgLj0gJGxpbmU7CgoJCX0gd2hpbGUgKCAhICRkb25lICk7CgoJCWlmICggZmFsc2UgPT09ICRmdWxsX2xpbmUgKSB7CgkJCXJldHVybiAnZXhpdCc7CgkJfQoKCQlyZXR1cm4gJGZ1bGxfbGluZTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVfcHJvbXB0X2NtZCggJHByb21wdCwgJGhpc3RvcnlfcGF0aCApIHsKCQkkcHJvbXB0ICAgICAgID0gZXNjYXBlc2hlbGxhcmcoICRwcm9tcHQgKTsKCQkkaGlzdG9yeV9wYXRoID0gZXNjYXBlc2hlbGxhcmcoICRoaXN0b3J5X3BhdGggKTsKCQlpZiAoIGdldGVudiggJ1dQX0NMSV9DVVNUT01fU0hFTEwnICkgKSB7CgkJCSRzaGVsbF9iaW5hcnkgPSBnZXRlbnYoICdXUF9DTElfQ1VTVE9NX1NIRUxMJyApOwoJCX0gZWxzZSB7CgkJCSRzaGVsbF9iaW5hcnkgPSAnL2Jpbi9iYXNoJzsKCQl9CgoJCWlmICggISBpc19maWxlKCAkc2hlbGxfYmluYXJ5ICkgfHwgISBpc19yZWFkYWJsZSggJHNoZWxsX2JpbmFyeSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlIHNoZWxsIGJpbmFyeSAneyRzaGVsbF9iaW5hcnl9JyBpcyBub3QgdmFsaWQuIFlvdSBjYW4gb3ZlcnJpZGUgdGhlIHNoZWxsIHRvIGJlIHVzZWQgdGhyb3VnaCB0aGUgV1BfQ0xJX0NVU1RPTV9TSEVMTCBlbnZpcm9ubWVudCB2YXJpYWJsZS4iICk7CgkJfQoKCQkkc2hlbGxfYmluYXJ5ID0gZXNjYXBlc2hlbGxhcmcoICRzaGVsbF9iaW5hcnkgKTsKCgkJJGNtZCA9ICdzZXQgLWY7ICcKCQkJLiAiaGlzdG9yeSAtciB7JGhpc3RvcnlfcGF0aH07ICIKCQkJLiAnTElORT0iIjsgJwoJCQkuICJyZWFkIC1yZSAtcCB7JHByb21wdH0gTElORTsgIgoJCQkuICdbICQ/IC1lcSAwIF0gfHwgZXhpdDsgJwoJCQkuICdoaXN0b3J5IC1zICIkTElORSI7ICcKCQkJLiAiaGlzdG9yeSAtdyB7JGhpc3RvcnlfcGF0aH07ICIKCQkJLiAnZWNobyAkTElORTsgJzsKCgkJcmV0dXJuICJ7JHNoZWxsX2JpbmFyeX0gLWMgIiAuIGVzY2FwZXNoZWxsYXJnKCAkY21kICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzZXRfaGlzdG9yeV9maWxlKCkgewoJCSRkYXRhID0gZ2V0Y3dkKCkgLiBnZXRfY3VycmVudF91c2VyKCk7CgoJCSR0aGlzLT5oaXN0b3J5X2ZpbGUgPSBcV1BfQ0xJXFV0aWxzXGdldF90ZW1wX2RpcigpIC4gJ3dwLWNsaS1oaXN0b3J5LScgLiBtZDUoICRkYXRhICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc3RhcnRzX3dpdGgoICR0b2tlbnMsICRsaW5lICkgewoJCXJldHVybiBwcmVnX21hdGNoKCAiL14oJHRva2VucylbXChcc10rLyIsICRsaW5lICk7Cgl9Cn0KCjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwoKY2xhc3MgU2hlbGxfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIE9wZW5zIGFuIGludGVyYWN0aXZlIFBIUCBjb25zb2xlIGZvciBydW5uaW5nIGFuZCB0ZXN0aW5nIFBIUCBjb2RlLgoJICoKCSAqIGB3cCBzaGVsbGAgYWxsb3dzIHlvdSB0byBldmFsdWF0ZSBQSFAgc3RhdGVtZW50cyBhbmQgZXhwcmVzc2lvbnMKCSAqIGludGVyYWN0aXZlbHksIGZyb20gd2l0aGluIGEgV29yZFByZXNzIGVudmlyb25tZW50LiBUeXBlIGEgYml0IG9mIGNvZGUsCgkgKiBoaXQgZW50ZXIsIGFuZCBzZWUgdGhlIGNvZGUgZXhlY3V0ZSByaWdodCBiZWZvcmUgeW91LiBCZWNhdXNlIFdvcmRQcmVzcwoJICogaXMgbG9hZGVkLCB5b3UgaGF2ZSBhY2Nlc3MgdG8gYWxsIHRoZSBmdW5jdGlvbnMsIGNsYXNzZXMgYW5kIGdsb2JhbHMKCSAqIHRoYXQgeW91IGNhbiB1c2Ugd2l0aGluIGEgV29yZFByZXNzIHBsdWdpbiwgZm9yIGV4YW1wbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWJhc2ljXQoJICogOiBGb3JjZSB0aGUgdXNlIG9mIFdQLUNMSSdzIGJ1aWx0LWluIFBIUCBSRVBMLCBldmVuIGlmIHRoZSBCb3JpcyBvcgoJICogUHN5U0ggUEhQIFJFUExzIGFyZSBhdmFpbGFibGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDYWxsIGdldF9ibG9naW5mbygpIHRvIGdldCB0aGUgbmFtZSBvZiB0aGUgc2l0ZS4KCSAqICAgICAkIHdwIHNoZWxsCgkgKiAgICAgd3A+IGdldF9ibG9naW5mbyggJ25hbWUnICk7CgkgKiAgICAgPT4gc3RyaW5nKDYpICJXUC1DTEkiCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJF8sICRhc3NvY19hcmdzICkgewoJCSRpbXBsZW1lbnRhdGlvbnMgPSBhcnJheSgKCQkJJ1BzeVxcU2hlbGwnLAoJCQknQm9yaXNcXEJvcmlzJywKCQkJJ1dQX0NMSVxcU2hlbGxcXFJFUEwnLAoJCSk7CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYmFzaWMnICkgKSB7CgkJCSRjbGFzcyA9ICdXUF9DTElcXFNoZWxsXFxSRVBMJzsKCQl9IGVsc2UgewoJCQlmb3JlYWNoICggJGltcGxlbWVudGF0aW9ucyBhcyAkY2FuZGlkYXRlICkgewoJCQkJaWYgKCBjbGFzc19leGlzdHMoICRjYW5kaWRhdGUgKSApIHsKCQkJCQkkY2xhc3MgPSAkY2FuZGlkYXRlOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICdQc3lcXFNoZWxsJyA9PT0gJGNsYXNzICkgewoJCQkkc2hlbGwgPSBuZXcgUHN5XFNoZWxsKCk7CgkJCSRzaGVsbC0+cnVuKCk7CgkJfSBlbHNlIHsKCQkJJHJlcGwgPSBuZXcgJGNsYXNzKCAnd3A+ICcgKTsKCQkJJHJlcGwtPnN0YXJ0KCk7CgkJfQoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfc2hlbGxfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfc2hlbGxfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9zaGVsbF9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2hlbGwnLCAnU2hlbGxfQ29tbWFuZCcgKTsKIyEvdXNyL2Jpbi9lbnYgc2gKCiMgU3BlY2lhbCBjYXNlIGZvciAqQU1QIGluc3RhbGxlcnMsIHNpbmNlIHRoZXkgbm9ybWFsbHkgZG9uJ3Qgc2V0IHRoZW1zZWx2ZXMKIyBhcyB0aGUgZGVmYXVsdCBjbGkgcGhwIG91dCBvZiB0aGUgYm94Lgpmb3IgYW1wX3BocCBpbiAkKGNhdCAkKGRpcm5hbWUgJDApL2FtcC1wYXRocy50eHQpOyBkbwoJaWYgWyAteCAkYW1wX3BocCBdOyB0aGVuCgkJZWNobyAkYW1wX3BocAoJCWV4aXQKCWZpCmRvbmUKCndoaWNoIHBocCB8fCB3aGljaCBwaHAtY2xpCgppZiBbICQ/IC1lcSAwIF07IHRoZW4KCWV4aXQKZmkKCmVjaG8gIm5vIFBIUCBiaW5hcnkgZm91bmQiID4mMgpleGl0IDEKPD9waHAKLyoqCiAqIExpc3QgYWxsIGNvbnRyaWJ1dG9ycyB0byB0aGlzIHJlbGVhc2UuCiAqCiAqIFVzYWdlOiB3cCAtLXJlcXVpcmU9dXRpbHMvY29udHJpYi1saXN0LnBocCBjb250cmliLWxpc3QKICoKICogSWYgeW91IHJ1biBpbnRvIEdpdEh1YiBBUEkgcmF0ZSBsaW1pdCBpc3N1ZXMsIHNldCBhIEdJVEhVQl9UT0tFTgogKiBlbnZpcm9ubWVudCB2YXJpYWJsZS4KICovCgp1c2UgV1BfQ0xJXFV0aWxzOwoKY2xhc3MgQ29udHJpYl9MaXN0X0NvbW1hbmQgewoKCS8qKgoJICogTGlzdCBhbGwgY29udHJpYnV0b3JzIHRvIHRoaXMgcmVsZWFzZS4KCSAqCgkgKiBSdW4gd2l0aGluIHRoZSBtYWluIFdQLUNMSSBwcm9qZWN0IHJlcG9zaXRvcnkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHNwZWNpZmljIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogbWFya2Rvd24KCSAqIG9wdGlvbnM6CgkgKiAgIC0gbWFya2Rvd24KCSAqICAgLSBodG1sCgkgKiAtLS0KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRfLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbnRyaWJ1dG9ycyAgICAgICA9IGFycmF5KCk7CgkJJGNvbnRyaWJ1dG9yX2NvdW50ICA9IDA7CgkJJHB1bGxfcmVxdWVzdF9jb3VudCA9IDA7CgoJCS8vIEdldCB0aGUgY29udHJpYnV0b3JzIHRvIHRoZSBjdXJyZW50IG9wZW4gbGFyZ2UgcHJvamVjdCBtaWxlc3RvbmVzCgkJZm9yZWFjaCAoIGFycmF5KCAnd3AtY2xpL3dwLWNsaScsICd3cC1jbGkvaGFuZGJvb2snLCAnd3AtY2xpL3dwLWNsaS5naXRodWIuY29tJyApIGFzICRyZXBvICkgewoJCQkkbWlsZXN0b25lcyA9IHNlbGY6OmdldF9wcm9qZWN0X21pbGVzdG9uZXMoICRyZXBvICk7CgkJCS8vIENoZWFwIHdheSB0byBnZXQgdGhlIGxhdGVzdCBtaWxlc3RvbmUKCQkJJG1pbGVzdG9uZSA9IGFycmF5X3NoaWZ0KCAkbWlsZXN0b25lcyApOwoJCQlXUF9DTEk6OmxvZyggJ0N1cnJlbnQgb3BlbiAnIC4gJHJlcG8gLiAnIG1pbGVzdG9uZTogJyAuICRtaWxlc3RvbmUtPnRpdGxlICk7CgkJCSRwdWxsX3JlcXVlc3RzICAgICA9IHNlbGY6OmdldF9wcm9qZWN0X21pbGVzdG9uZV9wdWxsX3JlcXVlc3RzKCAkcmVwbywgJG1pbGVzdG9uZS0+bnVtYmVyICk7CgkJCSRyZXBvX2NvbnRyaWJ1dG9ycyA9IHNlbGY6OnBhcnNlX2NvbnRyaWJ1dG9yc19mcm9tX3B1bGxfcmVxdWVzdHMoICRwdWxsX3JlcXVlc3RzICk7CgkJCVdQX0NMSTo6bG9nKCAnIC0gQ29udHJpYnV0b3JzOiAnIC4gY291bnQoICRyZXBvX2NvbnRyaWJ1dG9ycyApICk7CgkJCVdQX0NMSTo6bG9nKCAnIC0gUHVsbCByZXF1ZXN0czogJyAuIGNvdW50KCAkcHVsbF9yZXF1ZXN0cyApICk7CgkJCSRwdWxsX3JlcXVlc3RfY291bnQgKz0gY291bnQoICRwdWxsX3JlcXVlc3RzICk7CgkJCSRjb250cmlidXRvcnMgICAgICAgID0gYXJyYXlfbWVyZ2UoICRjb250cmlidXRvcnMsICRyZXBvX2NvbnRyaWJ1dG9ycyApOwoJCX0KCgkJLy8gSWRlbnRpZnkgYWxsIGNvbW1hbmQgZGVwZW5kZW5jaWVzIGFuZCB0aGVpciBjb250cmlidXRvcnMKCQkkbWlsZXN0b25lcyA9IHNlbGY6OmdldF9wcm9qZWN0X21pbGVzdG9uZXMoICd3cC1jbGkvd3AtY2xpJywgYXJyYXkoICdzdGF0ZScgPT4gJ2Nsb3NlZCcgKSApOwoJCS8vIENoZWFwIHdheSB0byBnZXQgdGhlIGxhdGVzdCBjbG9zZWQgbWlsZXN0b25lCgkJJG1pbGVzdG9uZSAgICAgICAgID0gYXJyYXlfc2hpZnQoICRtaWxlc3RvbmVzICk7CgkJJGNvbXBvc2VyX2xvY2tfdXJsID0gc3ByaW50ZiggJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS93cC1jbGkvd3AtY2xpL3Ylcy9jb21wb3Nlci5sb2NrJywgJG1pbGVzdG9uZS0+dGl0bGUgKTsKCQlXUF9DTEk6OmxvZyggJ0ZldGNoaW5nICcgLiAkY29tcG9zZXJfbG9ja191cmwgKTsKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkY29tcG9zZXJfbG9ja191cmwgKTsKCQlpZiAoIDIwMCAhPT0gJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0NvdWxkIG5vdCBmZXRjaCBjb21wb3Nlci5qc29uIChIVFRQIGNvZGUgJWQpJywgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApICk7CgkJfQoJCSRjb21wb3Nlcl9qc29uID0ganNvbl9kZWNvZGUoICRyZXNwb25zZS0+Ym9keSwgdHJ1ZSApOwoJCWZvcmVhY2ggKCAkY29tcG9zZXJfanNvblsncGFja2FnZXMnXSBhcyAkcGFja2FnZSApIHsKCQkJJHBhY2thZ2VfbmFtZSAgICAgICA9ICRwYWNrYWdlWyduYW1lJ107CgkJCSR2ZXJzaW9uX2NvbnN0cmFpbnQgPSBzdHJfcmVwbGFjZSggJ3YnLCAnJywgJHBhY2thZ2VbJ3ZlcnNpb24nXSApOwoJCQlpZiAoICEgcHJlZ19tYXRjaCggJyNed3AtY2xpLy4rLWNvbW1hbmQkIycsICRwYWNrYWdlX25hbWUgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCS8vIENsb3NlZCBtaWxlc3RvbmVzIGRlbm90ZSBhIHRhZ2dlZCByZWxlYXNlCgkJCSRtaWxlc3RvbmVzICAgICAgID0gc2VsZjo6Z2V0X3Byb2plY3RfbWlsZXN0b25lcyggJHBhY2thZ2VfbmFtZSwgYXJyYXkoICdzdGF0ZScgPT4gJ2Nsb3NlZCcgKSApOwoJCQkkbWlsZXN0b25lX2lkcyAgICA9IGFycmF5KCk7CgkJCSRtaWxlc3RvbmVfdGl0bGVzID0gYXJyYXkoKTsKCQkJZm9yZWFjaCAoICRtaWxlc3RvbmVzIGFzICRtaWxlc3RvbmUgKSB7CgkJCQlpZiAoICEgdmVyc2lvbl9jb21wYXJlKCAkbWlsZXN0b25lLT50aXRsZSwgJHZlcnNpb25fY29uc3RyYWludCwgJz4nICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkbWlsZXN0b25lX2lkc1tdICAgID0gJG1pbGVzdG9uZS0+bnVtYmVyOwoJCQkJJG1pbGVzdG9uZV90aXRsZXNbXSA9ICRtaWxlc3RvbmUtPnRpdGxlOwoJCQl9CgkJCS8vIE5vIHNoaXBwZWQgcmVsZWFzZXMgZm9yIHRoaXMgbWlsZXN0b25lLgoJCQlpZiAoIGVtcHR5KCAkbWlsZXN0b25lX2lkcyApICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJV1BfQ0xJOjpsb2coICdDbG9zZWQgJyAuICRwYWNrYWdlX25hbWUgLiAnIG1pbGVzdG9uZShzKTogJyAuIGltcGxvZGUoICcsICcsICRtaWxlc3RvbmVfdGl0bGVzICkgKTsKCQkJZm9yZWFjaCAoICRtaWxlc3RvbmVfaWRzIGFzICRtaWxlc3RvbmVfaWQgKSB7CgkJCQkkcHVsbF9yZXF1ZXN0cyAgICAgPSBzZWxmOjpnZXRfcHJvamVjdF9taWxlc3RvbmVfcHVsbF9yZXF1ZXN0cyggJHBhY2thZ2VfbmFtZSwgJG1pbGVzdG9uZV9pZCApOwoJCQkJJHJlcG9fY29udHJpYnV0b3JzID0gc2VsZjo6cGFyc2VfY29udHJpYnV0b3JzX2Zyb21fcHVsbF9yZXF1ZXN0cyggJHB1bGxfcmVxdWVzdHMgKTsKCQkJCVdQX0NMSTo6bG9nKCAnIC0gQ29udHJpYnV0b3JzOiAnIC4gY291bnQoICRyZXBvX2NvbnRyaWJ1dG9ycyApICk7CgkJCQlXUF9DTEk6OmxvZyggJyAtIFB1bGwgcmVxdWVzdHM6ICcgLiBjb3VudCggJHB1bGxfcmVxdWVzdHMgKSApOwoJCQkJJHB1bGxfcmVxdWVzdF9jb3VudCArPSBjb3VudCggJHB1bGxfcmVxdWVzdHMgKTsKCQkJCSRjb250cmlidXRvcnMgICAgICAgID0gYXJyYXlfbWVyZ2UoICRjb250cmlidXRvcnMsICRyZXBvX2NvbnRyaWJ1dG9ycyApOwoJCQl9CgkJfQoKCQlXUF9DTEk6OmxvZyggJ1RvdGFsIGNvbnRyaWJ1dG9yczogJyAuIGNvdW50KCAkY29udHJpYnV0b3JzICkgKTsKCQlXUF9DTEk6OmxvZyggJ1RvdGFsIHB1bGwgcmVxdWVzdHM6ICcgLiAkcHVsbF9yZXF1ZXN0X2NvdW50ICk7CgoJCS8vIFNvcnQgYW5kIHJlbmRlciB0aGUgY29udHJpYnV0b3IgbGlzdAoJCWFzb3J0KCAkY29udHJpYnV0b3JzLCBTT1JUX05BVFVSQUwgfCBTT1JUX0ZMQUdfQ0FTRSApOwoJCWlmICggaW5fYXJyYXkoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgYXJyYXkoICdtYXJrZG93bicsICdodG1sJyApLCB0cnVlICkgKSB7CgkJCSRjb250cmliX2xpc3QgPSAnJzsKCQkJZm9yZWFjaCAoICRjb250cmlidXRvcnMgYXMgJHVybCA9PiAkbG9naW4gKSB7CgkJCQlpZiAoICdtYXJrZG93bicgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJCQkkY29udHJpYl9saXN0IC49ICdbJyAuICRsb2dpbiAuICddKCcgLiAkdXJsIC4gJyksICc7CgkJCQl9IGVsc2VpZiAoICdodG1sJyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkJCSRjb250cmliX2xpc3QgLj0gJzxhIGhyZWY9IicgLiAkdXJsIC4gJyI+JyAuICRsb2dpbiAuICc8L2E+LCAnOwoJCQkJfQoJCQl9CgkJCSRjb250cmliX2xpc3QgPSBydHJpbSggJGNvbnRyaWJfbGlzdCwgJywgJyApOwoJCQlXUF9DTEk6OmxvZyggJGNvbnRyaWJfbGlzdCApOwoJCX0KCX0KCgkvKioKCSAqIEdldCB0aGUgbWlsZXN0b25lcyBmb3IgYSBnaXZlbiBwcm9qZWN0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkcHJvamVjdAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfcHJvamVjdF9taWxlc3RvbmVzKCAkcHJvamVjdCwgJGFyZ3MgPSBhcnJheSgpICkgewoJCSRyZXF1ZXN0X3VybCAgICAgICAgICAgID0gc3ByaW50ZiggJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJXMvbWlsZXN0b25lcycsICRwcm9qZWN0ICk7CgkJbGlzdCggJGJvZHksICRoZWFkZXJzICkgPSBzZWxmOjptYWtlX2dpdGh1Yl9hcGlfcmVxdWVzdCggJHJlcXVlc3RfdXJsLCAkYXJncyApOwoJCXJldHVybiAkYm9keTsKCX0KCgkvKioKCSAqIEdldCB0aGUgcHVsbCByZXF1ZXN0cyBhc3NpZ25lZCB0byBhIG1pbGVzdG9uZSBvZiBhIGdpdmVuIHByb2plY3QKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwcm9qZWN0CgkgKiBAcGFyYW0gaW50ZWdlciAkbWlsZXN0b25lX2lkCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9wcm9qZWN0X21pbGVzdG9uZV9wdWxsX3JlcXVlc3RzKCAkcHJvamVjdCwgJG1pbGVzdG9uZV9pZCApIHsKCQkkcmVxdWVzdF91cmwgICA9IHNwcmludGYoICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zLyVzL2lzc3VlcycsICRwcm9qZWN0ICk7CgkJJGFyZ3MgICAgICAgICAgPSBhcnJheSgKCQkJJ21pbGVzdG9uZScgPT4gJG1pbGVzdG9uZV9pZCwKCQkJJ3N0YXRlJyAgICAgPT4gJ2FsbCcsCgkJKTsKCQkkcHVsbF9yZXF1ZXN0cyA9IGFycmF5KCk7CgkJZG8gewoJCQlsaXN0KCAkYm9keSwgJGhlYWRlcnMgKSA9IHNlbGY6Om1ha2VfZ2l0aHViX2FwaV9yZXF1ZXN0KCAkcmVxdWVzdF91cmwsICRhcmdzICk7CgkJCWZvcmVhY2ggKCAkYm9keSBhcyAkaXNzdWUgKSB7CgkJCQlpZiAoICEgZW1wdHkoICRpc3N1ZS0+cHVsbF9yZXF1ZXN0ICkgKSB7CgkJCQkJJHB1bGxfcmVxdWVzdHNbXSA9ICRpc3N1ZTsKCQkJCX0KCQkJfQoJCQkkYXJncyAgICAgICAgPSBhcnJheSgpOwoJCQkkcmVxdWVzdF91cmwgPSBmYWxzZTsKCQkJLy8gU2V0ICRyZXF1ZXN0X3VybCB0byAncmVsPSJuZXh0IiBpZiBwcmVzZW50JwoJCQlpZiAoICEgZW1wdHkoICRoZWFkZXJzWydMaW5rJ10gKSApIHsKCQkJCSRiaXRzID0gdHJpbSggZXhwbG9kZSggJywnLCAkaGVhZGVyc1snTGluayddICkgKTsKCQkJCWZvcmVhY2ggKCAkYml0cyBhcyAkYml0ICkgewoJCQkJCWlmICggZmFsc2UgIT09IHN0cmlwb3MoICRiaXQsICdyZWw9Im5leHQiJyApICkgewoJCQkJCQkkaHJlZmFuZHJlbCAgPSBleHBsb2RlKCAnOyAnLCAkYml0ICk7CgkJCQkJCSRyZXF1ZXN0X3VybCA9IHRyaW0oICRocmVmYW5kcmVsWzBdLCAnPD4nICk7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0gd2hpbGUgKCAkcmVxdWVzdF91cmwgKTsKCQlyZXR1cm4gJHB1bGxfcmVxdWVzdHM7Cgl9CgoJLyoqCgkgKiBQYXJzZSB0aGUgY29udHJpYnV0b3JzIGZyb20gcHVsbCByZXF1ZXN0IG9iamVjdHMKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHB1bGxfcmVxdWVzdHMKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcGFyc2VfY29udHJpYnV0b3JzX2Zyb21fcHVsbF9yZXF1ZXN0cyggJHB1bGxfcmVxdWVzdHMgKSB7CgkJJGNvbnRyaWJ1dG9ycyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICRwdWxsX3JlcXVlc3RzIGFzICRwdWxsX3JlcXVlc3QgKSB7CgkJCWlmICggISBlbXB0eSggJHB1bGxfcmVxdWVzdC0+dXNlciApICkgewoJCQkJJGNvbnRyaWJ1dG9yc1sgJHB1bGxfcmVxdWVzdC0+dXNlci0+aHRtbF91cmwgXSA9ICRwdWxsX3JlcXVlc3QtPnVzZXItPmxvZ2luOwoJCQl9CgkJfQoJCXJldHVybiAkY29udHJpYnV0b3JzOwoJfQoKCS8qKgoJICogTWFrZSBhIHJlcXVlc3QgdG8gdGhlIEdpdEh1YiBBUEkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBzdHJpbmcgJGFyZ3MKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gbWFrZV9naXRodWJfYXBpX3JlcXVlc3QoICR1cmwsICRhcmdzID0gYXJyYXkoKSApIHsKCQkkaGVhZGVycyA9IGFycmF5KAoJCQknQWNjZXB0JyAgICAgPT4gJ2FwcGxpY2F0aW9uL3ZuZC5naXRodWIudjMranNvbicsCgkJCSdVc2VyLUFnZW50JyA9PiAnV1AtQ0xJJywKCQkpOwoJCSR0b2tlbiAgID0gZ2V0ZW52KCAnR0lUSFVCX1RPS0VOJyApOwoJCWlmICggZmFsc2UgIT09ICR0b2tlbiApIHsKCQkJJGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9ICd0b2tlbiAnIC4gJHRva2VuOwoJCX0KCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkdXJsLCAkYXJncywgJGhlYWRlcnMgKTsKCQlpZiAoIDIwMCAhPT0gJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0dpdEh1YiBBUEkgcmV0dXJuZWQ6ICVzIChIVFRQIGNvZGUgJWQpJywgJHJlc3BvbnNlLT5ib2R5LCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlICkgKTsKCQl9CgkJcmV0dXJuIGFycmF5KCBqc29uX2RlY29kZSggJHJlc3BvbnNlLT5ib2R5ICksICRyZXNwb25zZS0+aGVhZGVycyApOwoJfQoKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NvbnRyaWItbGlzdCcsICdDb250cmliX0xpc3RfQ29tbWFuZCcgKTsKPD9waHAKCiRmaWxlID0gJGFyZ3ZbMV07CmlmICggISBmaWxlX2V4aXN0cyggJGZpbGUgKSApIHsKCWVjaG8gJ0ZpbGUgZG9lcyBub3QgZXhpc3QuJzsKCWV4aXQoIDEgKTsKfQoKJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoICRmaWxlICk7CiRjb21wb3NlciA9IGpzb25fZGVjb2RlKCAkY29udGVudHMgKTsKCmlmICggZW1wdHkoICRjb21wb3NlciApIHx8ICEgaXNfb2JqZWN0KCAkY29tcG9zZXIgKSApIHsKCWVjaG8gJ0ludmFsaWQgY29tcG9zZXIuanNvbiBmb3IgcGFja2FnZS4nOwoJZXhpdCggMSApOwp9CgppZiAoIGVtcHR5KCAkY29tcG9zZXItPmF1dG9sb2FkLT5maWxlcyApICkgewoJZWNobyAnY29tcG9zZXIuanNvbiBtdXN0IHNwZWNpZnkgdmFsaWQgImF1dG9sb2FkIiA9PiAiZmlsZXMiJzsKCWV4aXQoIDEgKTsKfQoKZWNobyBpbXBsb2RlKCBQSFBfRU9MLCAkY29tcG9zZXItPmF1dG9sb2FkLT5maWxlcyApOwpleGl0KCAwICk7Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIEFycmF5T2JqZWN0Owp1c2UgRXhjZXB0aW9uOwoKY2xhc3MgU2VhcmNoUmVwbGFjZXIgewoKCXByaXZhdGUgJGZyb207Cglwcml2YXRlICR0bzsKCXByaXZhdGUgJHJlY3Vyc2Vfb2JqZWN0czsKCXByaXZhdGUgJHJlZ2V4OwoJcHJpdmF0ZSAkcmVnZXhfZmxhZ3M7Cglwcml2YXRlICRyZWdleF9kZWxpbWl0ZXI7Cglwcml2YXRlICRyZWdleF9saW1pdDsKCXByaXZhdGUgJGxvZ2dpbmc7Cglwcml2YXRlICRsb2dfZGF0YTsKCXByaXZhdGUgJG1heF9yZWN1cnNpb247CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICAkZnJvbSAgICAgICAgICAgIFN0cmluZyB3ZSdyZSBsb29raW5nIHRvIHJlcGxhY2UuCgkgKiBAcGFyYW0gc3RyaW5nICAkdG8gICAgICAgICAgICAgIFdoYXQgd2Ugd2FudCBpdCB0byBiZSByZXBsYWNlZCB3aXRoLgoJICogQHBhcmFtIGJvb2wgICAgJHJlY3Vyc2Vfb2JqZWN0cyBTaG91bGQgb2JqZWN0cyBiZSByZWN1cnNpdmVseSByZXBsYWNlZD8KCSAqIEBwYXJhbSBib29sICAgICRyZWdleCAgICAgICAgICAgV2hldGhlciBgJGZyb21gIGlzIGEgcmVndWxhciBleHByZXNzaW9uLgoJICogQHBhcmFtIHN0cmluZyAgJHJlZ2V4X2ZsYWdzICAgICBGbGFncyBmb3IgcmVndWxhciBleHByZXNzaW9uLgoJICogQHBhcmFtIHN0cmluZyAgJHJlZ2V4X2RlbGltaXRlciBEZWxpbWl0ZXIgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbi4KCSAqIEBwYXJhbSBib29sICAgICRsb2dnaW5nICAgICAgICAgV2hldGhlciBsb2dnaW5nLgoJICogQHBhcmFtIGludGVnZXIgJHJlZ2V4X2xpbWl0ICAgICBUaGUgbWF4aW11bSBwb3NzaWJsZSByZXBsYWNlbWVudHMgZm9yIGVhY2ggcGF0dGVybiBpbiBlYWNoIHN1YmplY3Qgc3RyaW5nLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRmcm9tLCAkdG8sICRyZWN1cnNlX29iamVjdHMgPSBmYWxzZSwgJHJlZ2V4ID0gZmFsc2UsICRyZWdleF9mbGFncyA9ICcnLCAkcmVnZXhfZGVsaW1pdGVyID0gJy8nLCAkbG9nZ2luZyA9IGZhbHNlLCAkcmVnZXhfbGltaXQgPSAtMSApIHsKCQkkdGhpcy0+ZnJvbSAgICAgICAgICAgID0gJGZyb207CgkJJHRoaXMtPnRvICAgICAgICAgICAgICA9ICR0bzsKCQkkdGhpcy0+cmVjdXJzZV9vYmplY3RzID0gJHJlY3Vyc2Vfb2JqZWN0czsKCQkkdGhpcy0+cmVnZXggICAgICAgICAgID0gJHJlZ2V4OwoJCSR0aGlzLT5yZWdleF9mbGFncyAgICAgPSAkcmVnZXhfZmxhZ3M7CgkJJHRoaXMtPnJlZ2V4X2RlbGltaXRlciA9ICRyZWdleF9kZWxpbWl0ZXI7CgkJJHRoaXMtPnJlZ2V4X2xpbWl0ICAgICA9ICRyZWdleF9saW1pdDsKCQkkdGhpcy0+bG9nZ2luZyAgICAgICAgID0gJGxvZ2dpbmc7CgkJJHRoaXMtPmNsZWFyX2xvZ19kYXRhKCk7CgoJCS8vIEdldCB0aGUgWERlYnVnIG5lc3RpbmcgbGV2ZWwuIFdpbGwgYmUgemVybyAobm8gbGltaXQpIGlmIG5vIHZhbHVlIGlzIHNldAoJCSR0aGlzLT5tYXhfcmVjdXJzaW9uID0gaW50dmFsKCBpbmlfZ2V0KCAneGRlYnVnLm1heF9uZXN0aW5nX2xldmVsJyApICk7Cgl9CgoJLyoqCgkgKiBUYWtlIGEgc2VyaWFsaXNlZCBhcnJheSBhbmQgdW5zZXJpYWxpc2UgaXQgcmVwbGFjaW5nIGVsZW1lbnRzIGFzIG5lZWRlZCBhbmQKCSAqIHVuc2VyaWFsaXNpbmcgYW55IHN1Ym9yZGluYXRlIGFycmF5cyBhbmQgcGVyZm9ybWluZyB0aGUgcmVwbGFjZSBvbiB0aG9zZSB0b28uCgkgKiBJZ25vcmVzIGFueSBzZXJpYWxpemVkIG9iamVjdHMgdW5sZXNzICRyZWN1cnNlX29iamVjdHMgaXMgc2V0IHRvIHRydWUuCgkgKgoJICogQHBhcmFtIGFycmF5fHN0cmluZyAkZGF0YSAgICAgICAgICAgIFRoZSBkYXRhIHRvIG9wZXJhdGUgb24uCgkgKiBAcGFyYW0gYm9vbCAgICAgICAgICRzZXJpYWxpc2VkICAgICAgRG9lcyB0aGUgdmFsdWUgb2YgJGRhdGEgbmVlZCB0byBiZSB1bnNlcmlhbGl6ZWQ/CgkgKgoJICogQHJldHVybiBhcnJheSAgICAgICBUaGUgb3JpZ2luYWwgYXJyYXkgd2l0aCBhbGwgZWxlbWVudHMgcmVwbGFjZWQgYXMgbmVlZGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcnVuKCAkZGF0YSwgJHNlcmlhbGlzZWQgPSBmYWxzZSApIHsKCQlyZXR1cm4gJHRoaXMtPnJ1bl9yZWN1cnNpdmVseSggJGRhdGEsICRzZXJpYWxpc2VkICk7Cgl9CgoJLyoqCgkgKiBAcGFyYW0gaW50ICAgICAgICAgICRyZWN1cnNpb25fbGV2ZWwgQ3VycmVudCByZWN1cnNpb24gZGVwdGggd2l0aGluIHRoZSBvcmlnaW5hbCBkYXRhLgoJICogQHBhcmFtIGFycmF5ICAgICAgICAkdmlzaXRlZF9kYXRhICAgIERhdGEgdGhhdCBoYXMgYmVlbiBzZWVuIGluIHByZXZpb3VzIHJlY3Vyc2lvbiBpdGVyYXRpb25zLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJ1bl9yZWN1cnNpdmVseSggJGRhdGEsICRzZXJpYWxpc2VkLCAkcmVjdXJzaW9uX2xldmVsID0gMCwgJHZpc2l0ZWRfZGF0YSA9IGFycmF5KCkgKSB7CgoJCS8vIHNvbWUgdW5zZXJpbGlhc2VkIGRhdGEgY2Fubm90IGJlIHJlLXNlcmlhbGlzZWQgZWcuIFNpbXBsZVhNTEVsZW1lbnRzCgkJdHJ5IHsKCgkJCWlmICggJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cyApIHsKCgkJCQkvLyBJZiB3ZSd2ZSByZWFjaGVkIHRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBsZXZlbCwgc2hvcnQgY2lyY3VpdAoJCQkJaWYgKCAwICE9PSAkdGhpcy0+bWF4X3JlY3Vyc2lvbiAmJiAkcmVjdXJzaW9uX2xldmVsID49ICR0aGlzLT5tYXhfcmVjdXJzaW9uICkgewoJCQkJCXJldHVybiAkZGF0YTsKCQkJCX0KCgkJCQlpZiAoIGlzX2FycmF5KCAkZGF0YSApIHx8IGlzX29iamVjdCggJGRhdGEgKSApIHsKCQkJCQkvLyBJZiB3ZSd2ZSBzZWVuIHRoaXMgZXhhY3Qgb2JqZWN0IG9yIGFycmF5IGJlZm9yZSwgc2hvcnQgY2lyY3VpdAoJCQkJCWlmICggaW5fYXJyYXkoICRkYXRhLCAkdmlzaXRlZF9kYXRhLCB0cnVlICkgKSB7CgkJCQkJCXJldHVybiAkZGF0YTsgLy8gQXZvaWQgaW5maW5pdGUgbG9vcHMgd2hlbiB0aGVyZSdzIGEgY3ljbGUKCQkJCQl9CgkJCQkJLy8gQWRkIHRoaXMgZGF0YSB0byB0aGUgbGlzdCBvZgoJCQkJCSR2aXNpdGVkX2RhdGFbXSA9ICRkYXRhOwoJCQkJfQoJCQl9CgoJCQkkdW5zZXJpYWxpemVkID0gaXNfc3RyaW5nKCAkZGF0YSApID8gQHVuc2VyaWFsaXplKCAkZGF0YSApIDogZmFsc2U7CgkJCWlmICggZmFsc2UgIT09ICR1bnNlcmlhbGl6ZWQgKSB7CgkJCQkkZGF0YSA9ICR0aGlzLT5ydW5fcmVjdXJzaXZlbHkoICR1bnNlcmlhbGl6ZWQsIHRydWUsICRyZWN1cnNpb25fbGV2ZWwgKyAxICk7CgkJCX0gZWxzZWlmICggaXNfYXJyYXkoICRkYXRhICkgKSB7CgkJCQkka2V5cyA9IGFycmF5X2tleXMoICRkYXRhICk7CgkJCQlmb3JlYWNoICggJGtleXMgYXMgJGtleSApIHsKCQkJCQkkZGF0YVsgJGtleSBdID0gJHRoaXMtPnJ1bl9yZWN1cnNpdmVseSggJGRhdGFbICRrZXkgXSwgZmFsc2UsICRyZWN1cnNpb25fbGV2ZWwgKyAxLCAkdmlzaXRlZF9kYXRhICk7CgkJCQl9CgkJCX0gZWxzZWlmICggJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cyAmJiAoIGlzX29iamVjdCggJGRhdGEgKSB8fCAkZGF0YSBpbnN0YW5jZW9mIFxfX1BIUF9JbmNvbXBsZXRlX0NsYXNzICkgKSB7CgkJCQlpZiAoICRkYXRhIGluc3RhbmNlb2YgXF9fUEhQX0luY29tcGxldGVfQ2xhc3MgKSB7CgkJCQkJJGFycmF5ID0gbmV3IEFycmF5T2JqZWN0KCAkZGF0YSApOwoJCQkJCVxXUF9DTEk6Ondhcm5pbmcoCgkJCQkJCXNwcmludGYoCgkJCQkJCQknU2tpcHBpbmcgYW4gdW5pbml0aWFsaXplZCBjbGFzcyAiJXMiLCByZXBsYWNlbWVudHMgbWlnaHQgbm90IGJlIGNvbXBsZXRlLicsCgkJCQkJCQkkYXJyYXlbJ19fUEhQX0luY29tcGxldGVfQ2xhc3NfTmFtZSddCgkJCQkJCSkKCQkJCQkpOwoJCQkJfSBlbHNlIHsKCQkJCQlmb3JlYWNoICggJGRhdGEgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCQkJCSRkYXRhLT4ka2V5ID0gJHRoaXMtPnJ1bl9yZWN1cnNpdmVseSggJHZhbHVlLCBmYWxzZSwgJHJlY3Vyc2lvbl9sZXZlbCArIDEsICR2aXNpdGVkX2RhdGEgKTsKCQkJCQl9CgkJCQl9CgkJCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkZGF0YSApICkgewoJCQkJaWYgKCAkdGhpcy0+bG9nZ2luZyApIHsKCQkJCQkkb2xkX2RhdGEgPSAkZGF0YTsKCQkJCX0KCQkJCWlmICggJHRoaXMtPnJlZ2V4ICkgewoJCQkJCSRzZWFyY2hfcmVnZXggID0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlcjsKCQkJCQkkc2VhcmNoX3JlZ2V4IC49ICR0aGlzLT5mcm9tOwoJCQkJCSRzZWFyY2hfcmVnZXggLj0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlcjsKCQkJCQkkc2VhcmNoX3JlZ2V4IC49ICR0aGlzLT5yZWdleF9mbGFnczsKCgkJCQkJJHJlc3VsdCA9IHByZWdfcmVwbGFjZSggJHNlYXJjaF9yZWdleCwgJHRoaXMtPnRvLCAkZGF0YSwgJHRoaXMtPnJlZ2V4X2xpbWl0ICk7CgkJCQkJaWYgKCBudWxsID09PSAkcmVzdWx0IHx8IFBSRUdfTk9fRVJST1IgIT09IHByZWdfbGFzdF9lcnJvcigpICkgewoJCQkJCQlcV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCQkJc3ByaW50ZigKCQkJCQkJCQknVGhlIHByb3ZpZGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aHJldyBhIFBDUkUgZXJyb3IgLSAlcycsCgkJCQkJCQkJJHRoaXMtPnByZWdfZXJyb3JfbWVzc2FnZSggJHJlc3VsdCApCgkJCQkJCQkpCgkJCQkJCSk7CgkJCQkJfQoJCQkJCSRkYXRhID0gJHJlc3VsdDsKCQkJCX0gZWxzZSB7CgkJCQkJJGRhdGEgPSBzdHJfcmVwbGFjZSggJHRoaXMtPmZyb20sICR0aGlzLT50bywgJGRhdGEgKTsKCQkJCX0KCQkJCWlmICggJHRoaXMtPmxvZ2dpbmcgJiYgJG9sZF9kYXRhICE9PSAkZGF0YSApIHsKCQkJCQkkdGhpcy0+bG9nX2RhdGFbXSA9ICRvbGRfZGF0YTsKCQkJCX0KCQkJfQoKCQkJaWYgKCAkc2VyaWFsaXNlZCApIHsKCQkJCXJldHVybiBzZXJpYWxpemUoICRkYXRhICk7CgkJCX0KCQl9IGNhdGNoICggRXhjZXB0aW9uICRlcnJvciApIHsgLy8gcGhwY3M6aWdub3JlIEdlbmVyaWMuQ29kZUFuYWx5c2lzLkVtcHR5U3RhdGVtZW50LkRldGVjdGVkQ2F0Y2ggLS0gRGVsaWJlcmFsbHkgZW1wdHkuCgoJCX0KCgkJcmV0dXJuICRkYXRhOwoJfQoKCS8qKgoJICogR2V0cyBleGlzdGluZyBkYXRhIHNhdmVkIGZvciB0aGlzIHJ1biB3aGVuIGxvZ2dpbmcuCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIGRhdGEgc3RyaW5ncywgcHJpb3IgdG8gcmVwbGFjZW1lbnRzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2xvZ19kYXRhKCkgewoJCXJldHVybiAkdGhpcy0+bG9nX2RhdGE7Cgl9CgoJLyoqCgkgKiBDbGVhcnMgZGF0YSBzdG9yZWQgZm9yIGxvZ2dpbmcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjbGVhcl9sb2dfZGF0YSgpIHsKCQkkdGhpcy0+bG9nX2RhdGEgPSBhcnJheSgpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBQQ1JFIGVycm9yIGNvbnN0YW50IG5hbWUgZnJvbSBhbiBlcnJvciB2YWx1ZS4KCSAqCgkgKiBAcGFyYW0gIGludGVnZXIgJGVycm9yIEVycm9yIGNvZGUuCgkgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgIEVycm9yIGNvbnN0YW50IG5hbWUuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcHJlZ19lcnJvcl9tZXNzYWdlKCAkZXJyb3IgKSB7CgkJc3RhdGljICRlcnJvcl9uYW1lcyA9IG51bGw7CgoJCWlmICggbnVsbCA9PT0gJGVycm9yX25hbWVzICkgewoJCQkkZGVmaW5pdGlvbnMgICAgPSBnZXRfZGVmaW5lZF9jb25zdGFudHMoIHRydWUgKTsKCQkJJHBjcmVfY29uc3RhbnRzID0gYXJyYXlfa2V5X2V4aXN0cyggJ3BjcmUnLCAkZGVmaW5pdGlvbnMgKQoJCQkJPyAkZGVmaW5pdGlvbnNbJ3BjcmUnXQoJCQkJOiBhcnJheSgpOwoJCQkkZXJyb3JfbmFtZXMgICAgPSBhcnJheV9mbGlwKCAkcGNyZV9jb25zdGFudHMgKTsKCQl9CgoJCXJldHVybiBpc3NldCggJGVycm9yX25hbWVzWyAkZXJyb3IgXSApCgkJCT8gJGVycm9yX25hbWVzWyAkZXJyb3IgXQoJCQk6ICc8dW5rbm93biBlcnJvcj4nOwoJfQp9Cjw/cGhwCgp1c2UgY2xpXENvbG9yczsKdXNlIGNsaVxUYWJsZTsKdXNlIFdQX0NMSVxJdGVyYXRvcnM7CnVzZSBXUF9DTElcU2VhcmNoUmVwbGFjZXI7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBmdW5jdGlvbiBjbGlcc2FmZV9zdWJzdHI7CgpjbGFzcyBTZWFyY2hfUmVwbGFjZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGRyeV9ydW47Cglwcml2YXRlICRleHBvcnRfaGFuZGxlID0gZmFsc2U7Cglwcml2YXRlICRleHBvcnRfaW5zZXJ0X3NpemU7Cglwcml2YXRlICRyZWN1cnNlX29iamVjdHM7Cglwcml2YXRlICRyZWdleDsKCXByaXZhdGUgJHJlZ2V4X2ZsYWdzOwoJcHJpdmF0ZSAkcmVnZXhfZGVsaW1pdGVyOwoJcHJpdmF0ZSAkcmVnZXhfbGltaXQgPSAtMTsKCXByaXZhdGUgJHNraXBfdGFibGVzOwoJcHJpdmF0ZSAkc2tpcF9jb2x1bW5zOwoJcHJpdmF0ZSAkaW5jbHVkZV9jb2x1bW5zOwoJcHJpdmF0ZSAkZm9ybWF0OwoJcHJpdmF0ZSAkcmVwb3J0OwoJcHJpdmF0ZSAkdmVyYm9zZTsKCglwcml2YXRlICRyZXBvcnRfY2hhbmdlZF9vbmx5OwoJcHJpdmF0ZSAkbG9nX2hhbmRsZSAgICAgICAgID0gbnVsbDsKCXByaXZhdGUgJGxvZ19iZWZvcmVfY29udGV4dCA9IDQwOwoJcHJpdmF0ZSAkbG9nX2FmdGVyX2NvbnRleHQgID0gNDA7Cglwcml2YXRlICRsb2dfcHJlZml4ZXMgICAgICAgPSBhcnJheSggJzwgJywgJz4gJyApOwoJcHJpdmF0ZSAkbG9nX2NvbG9yczsKCXByaXZhdGUgJGxvZ19lbmNvZGluZzsKCgkvKioKCSAqIFNlYXJjaGVzL3JlcGxhY2VzIHN0cmluZ3MgaW4gdGhlIGRhdGFiYXNlLgoJICoKCSAqIFNlYXJjaGVzIHRocm91Z2ggYWxsIHJvd3MgaW4gYSBzZWxlY3Rpb24gb2YgdGFibGVzIGFuZCByZXBsYWNlcwoJICogYXBwZWFyYW5jZXMgb2YgdGhlIGZpcnN0IHN0cmluZyB3aXRoIHRoZSBzZWNvbmQgc3RyaW5nLgoJICoKCSAqIEJ5IGRlZmF1bHQsIHRoZSBjb21tYW5kIHVzZXMgdGFibGVzIHJlZ2lzdGVyZWQgdG8gdGhlIGAkd3BkYmAgb2JqZWN0LiBPbgoJICogbXVsdGlzaXRlLCB0aGlzIHdpbGwganVzdCBiZSB0aGUgdGFibGVzIGZvciB0aGUgY3VycmVudCBzaXRlIHVubGVzcwoJICogYC0tbmV0d29ya2AgaXMgc3BlY2lmaWVkLgoJICoKCSAqIFNlYXJjaC9yZXBsYWNlIGludGVsbGlnZW50bHkgaGFuZGxlcyBQSFAgc2VyaWFsaXplZCBkYXRhLCBhbmQgZG9lcyBub3QKCSAqIGNoYW5nZSBwcmltYXJ5IGtleSB2YWx1ZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxvbGQ+CgkgKiA6IEEgc3RyaW5nIHRvIHNlYXJjaCBmb3Igd2l0aGluIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiA8bmV3PgoJICogOiBSZXBsYWNlIGluc3RhbmNlcyBvZiB0aGUgZmlyc3Qgc3RyaW5nIHdpdGggdGhpcyBuZXcgc3RyaW5nLgoJICoKCSAqIFs8dGFibGU+Li4uXQoJICogOiBMaXN0IG9mIGRhdGFiYXNlIHRhYmxlcyB0byByZXN0cmljdCB0aGUgcmVwbGFjZW1lbnQgdG8uIFdpbGRjYXJkcyBhcmUKCSAqIHN1cHBvcnRlZCwgZS5nLiBgJ3dwXypvcHRpb25zJ2Agb3IgYCd3cF9wb3N0KidgLgoJICoKCSAqIFstLWRyeS1ydW5dCgkgKiA6IFJ1biB0aGUgZW50aXJlIHNlYXJjaC9yZXBsYWNlIG9wZXJhdGlvbiBhbmQgc2hvdyByZXBvcnQsIGJ1dCBkb24ndCBzYXZlCgkgKiBjaGFuZ2VzIHRvIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBTZWFyY2gvcmVwbGFjZSB0aHJvdWdoIGFsbCB0aGUgdGFibGVzIHJlZ2lzdGVyZWQgdG8gJHdwZGIgaW4gYQoJICogbXVsdGlzaXRlIGluc3RhbGwuCgkgKgoJICogWy0tYWxsLXRhYmxlcy13aXRoLXByZWZpeF0KCSAqIDogRW5hYmxlIHJlcGxhY2VtZW50IG9uIGFueSB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgdGFibGUgcHJlZml4IGV2ZW4gaWYKCSAqIG5vdCByZWdpc3RlcmVkIG9uICR3cGRiLgoJICoKCSAqIFstLWFsbC10YWJsZXNdCgkgKiA6IEVuYWJsZSByZXBsYWNlbWVudCBvbiBBTEwgdGFibGVzIGluIHRoZSBkYXRhYmFzZSwgcmVnYXJkbGVzcyBvZiB0aGUKCSAqIHByZWZpeCwgYW5kIGV2ZW4gaWYgbm90IHJlZ2lzdGVyZWQgb24gJHdwZGIuIE92ZXJyaWRlcyAtLW5ldHdvcmsKCSAqIGFuZCAtLWFsbC10YWJsZXMtd2l0aC1wcmVmaXguCgkgKgoJICogWy0tZXhwb3J0Wz08ZmlsZT5dXQoJICogOiBXcml0ZSB0cmFuc2Zvcm1lZCBkYXRhIGFzIFNRTCBmaWxlIGluc3RlYWQgb2Ygc2F2aW5nIHJlcGxhY2VtZW50cyB0bwoJICogdGhlIGRhdGFiYXNlLiBJZiA8ZmlsZT4gaXMgbm90IHN1cHBsaWVkLCB3aWxsIG91dHB1dCB0byBTVERPVVQuCgkgKgoJICogWy0tZXhwb3J0X2luc2VydF9zaXplPTxyb3dzPl0KCSAqIDogRGVmaW5lIG51bWJlciBvZiByb3dzIGluIHNpbmdsZSBJTlNFUlQgc3RhdGVtZW50IHdoZW4gZG9pbmcgU1FMIGV4cG9ydC4KCSAqIFlvdSBtaWdodCB3YW50IHRvIGNoYW5nZSB0aGlzIGRlcGVuZGluZyBvbiB5b3VyIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24KCSAqIChlLmcuIGlmIHlvdSBuZWVkIHRvIGRvIGZld2VyIHF1ZXJpZXMpLiBEZWZhdWx0OiA1MAoJICoKCSAqIFstLXNraXAtdGFibGVzPTx0YWJsZXM+XQoJICogOiBEbyBub3QgcGVyZm9ybSB0aGUgcmVwbGFjZW1lbnQgb24gc3BlY2lmaWMgdGFibGVzLiBVc2UgY29tbWFzIHRvCgkgKiBzcGVjaWZ5IG11bHRpcGxlIHRhYmxlcy4gV2lsZGNhcmRzIGFyZSBzdXBwb3J0ZWQsIGUuZy4gYCd3cF8qb3B0aW9ucydgIG9yIGAnd3BfcG9zdConYC4KCSAqCgkgKiBbLS1za2lwLWNvbHVtbnM9PGNvbHVtbnM+XQoJICogOiBEbyBub3QgcGVyZm9ybSB0aGUgcmVwbGFjZW1lbnQgb24gc3BlY2lmaWMgY29sdW1ucy4gVXNlIGNvbW1hcyB0bwoJICogc3BlY2lmeSBtdWx0aXBsZSBjb2x1bW5zLgoJICoKCSAqIFstLWluY2x1ZGUtY29sdW1ucz08Y29sdW1ucz5dCgkgKiA6IFBlcmZvcm0gdGhlIHJlcGxhY2VtZW50IG9uIHNwZWNpZmljIGNvbHVtbnMuIFVzZSBjb21tYXMgdG8KCSAqIHNwZWNpZnkgbXVsdGlwbGUgY29sdW1ucy4KCSAqCgkgKiBbLS1wcmVjaXNlXQoJICogOiBGb3JjZSB0aGUgdXNlIG9mIFBIUCAoaW5zdGVhZCBvZiBTUUwpIHdoaWNoIGlzIG1vcmUgdGhvcm91Z2gsCgkgKiBidXQgc2xvd2VyLgoJICoKCSAqIFstLXJlY3Vyc2Utb2JqZWN0c10KCSAqIDogRW5hYmxlIHJlY3Vyc2luZyBpbnRvIG9iamVjdHMgdG8gcmVwbGFjZSBzdHJpbmdzLiBEZWZhdWx0cyB0byB0cnVlOwoJICogcGFzcyAtLW5vLXJlY3Vyc2Utb2JqZWN0cyB0byBkaXNhYmxlLgoJICoKCSAqIFstLXZlcmJvc2VdCgkgKiA6IFByaW50cyByb3dzIHRvIHRoZSBjb25zb2xlIGFzIHRoZXkncmUgdXBkYXRlZC4KCSAqCgkgKiBbLS1yZWdleF0KCSAqIDogUnVucyB0aGUgc2VhcmNoIHVzaW5nIGEgcmVndWxhciBleHByZXNzaW9uICh3aXRob3V0IGRlbGltaXRlcnMpLgoJICogV2FybmluZzogc2VhcmNoLXJlcGxhY2Ugd2lsbCB0YWtlIGFib3V0IDE1LTIweCBsb25nZXIgd2hlbiB1c2luZyAtLXJlZ2V4LgoJICoKCSAqIFstLXJlZ2V4LWZsYWdzPTxyZWdleC1mbGFncz5dCgkgKiA6IFBhc3MgUENSRSBtb2RpZmllcnMgdG8gcmVnZXggc2VhcmNoLXJlcGxhY2UgKGUuZy4gJ2knIGZvciBjYXNlLWluc2Vuc2l0aXZpdHkpLgoJICoKCSAqIFstLXJlZ2V4LWRlbGltaXRlcj08cmVnZXgtZGVsaW1pdGVyPl0KCSAqIDogVGhlIGRlbGltaXRlciB0byB1c2UgZm9yIHRoZSByZWdleC4gSXQgbXVzdCBiZSBlc2NhcGVkIGlmIGl0IGFwcGVhcnMgaW4gdGhlIHNlYXJjaCBzdHJpbmcuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSByZXN1bHQgb2YgYGNocigxKWAuCgkgKgoJICogWy0tcmVnZXgtbGltaXQ9PHJlZ2V4LWxpbWl0Pl0KCSAqIDogVGhlIG1heGltdW0gcG9zc2libGUgcmVwbGFjZW1lbnRzIGZvciB0aGUgcmVnZXggcGVyIHJvdyAob3IgcGVyIHVuc2VyaWFsaXplZCBkYXRhIGJpdCBwZXIgcm93KS4gRGVmYXVsdHMgdG8gLTEgKG5vIGxpbWl0KS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjb3VudAoJICogLS0tCgkgKgoJICogWy0tcmVwb3J0XQoJICogOiBQcm9kdWNlIHJlcG9ydC4gRGVmYXVsdHMgdG8gdHJ1ZS4KCSAqCgkgKiBbLS1yZXBvcnQtY2hhbmdlZC1vbmx5XQoJICogOiBSZXBvcnQgY2hhbmdlZCBmaWVsZHMgb25seS4gRGVmYXVsdHMgdG8gZmFsc2UsIHVubGVzcyBsb2dnaW5nLCB3aGVuIGl0IGRlZmF1bHRzIHRvIHRydWUuCgkgKgoJICogWy0tbG9nWz08ZmlsZT5dXQoJICogOiBMb2cgdGhlIGl0ZW1zIGNoYW5nZWQuIElmIDxmaWxlPiBpcyBub3Qgc3VwcGxpZWQgb3IgaXMgIi0iLCB3aWxsIG91dHB1dCB0byBTVERPVVQuCgkgKiBXYXJuaW5nOiBjYXVzZXMgYSBzaWduaWZpY2FudCBzbG93IGRvd24sIHNpbWlsYXIgb3Igd29yc2UgdG8gZW5hYmxpbmcgLS1wcmVjaXNlIG9yIC0tcmVnZXguCgkgKgoJICogWy0tYmVmb3JlX2NvbnRleHQ9PG51bT5dCgkgKiA6IEZvciBsb2dnaW5nLCBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBkaXNwbGF5IGJlZm9yZSB0aGUgb2xkIG1hdGNoIGFuZCB0aGUgbmV3IHJlcGxhY2VtZW50LiBEZWZhdWx0IDQwLiBJZ25vcmVkIGlmIG5vdCBsb2dnaW5nLgoJICoKCSAqIFstLWFmdGVyX2NvbnRleHQ9PG51bT5dCgkgKiA6IEZvciBsb2dnaW5nLCBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBkaXNwbGF5IGFmdGVyIHRoZSBvbGQgbWF0Y2ggYW5kIHRoZSBuZXcgcmVwbGFjZW1lbnQuIERlZmF1bHQgNDAuIElnbm9yZWQgaWYgbm90IGxvZ2dpbmcuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTZWFyY2ggYW5kIHJlcGxhY2UgYnV0IHNraXAgb25lIGNvbHVtbgoJICogICAgICQgd3Agc2VhcmNoLXJlcGxhY2UgJ2h0dHA6Ly9leGFtcGxlLnRlc3QnICdodHRwOi8vZXhhbXBsZS5jb20nIC0tc2tpcC1jb2x1bW5zPWd1aWQKCSAqCgkgKiAgICAgIyBSdW4gc2VhcmNoL3JlcGxhY2Ugb3BlcmF0aW9uIGJ1dCBkb250IHNhdmUgaW4gZGF0YWJhc2UKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlICdmb28nICdiYXInIHdwX3Bvc3RzIHdwX3Bvc3RtZXRhIHdwX3Rlcm1zIC0tZHJ5LXJ1bgoJICoKCSAqICAgICAjIFJ1biBjYXNlLWluc2Vuc2l0aXZlIHJlZ2V4IHNlYXJjaC9yZXBsYWNlIG9wZXJhdGlvbiAoc2xvdykKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlICdcW2ZvbyBpZD0iKFswLTldKykiJyAnW2JhciBpZD0iXDEiJyAtLXJlZ2V4IC0tcmVnZXgtZmxhZ3M9J2knCgkgKgoJICogICAgICMgVHVybiB5b3VyIHByb2R1Y3Rpb24gbXVsdGlzaXRlIGRhdGFiYXNlIGludG8gYSBsb2NhbCBkZXYgZGF0YWJhc2UKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlIC0tdXJsPWV4YW1wbGUuY29tIGV4YW1wbGUuY29tIGV4YW1wbGUudGVzdCAnd3BfKm9wdGlvbnMnIHdwX2Jsb2dzCgkgKgoJICogICAgICMgU2VhcmNoL3JlcGxhY2UgdG8gYSBTUUwgZmlsZSB3aXRob3V0IHRyYW5zZm9ybWluZyB0aGUgZGF0YWJhc2UKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlIGZvbyBiYXIgLS1leHBvcnQ9ZGF0YWJhc2Uuc3FsCgkgKgoJICogICAgICMgQmFzaCBzY3JpcHQ6IFNlYXJjaC9yZXBsYWNlIHByb2R1Y3Rpb24gdG8gZGV2ZWxvcG1lbnQgdXJsIChtdWx0aXNpdGUgY29tcGF0aWJsZSkKCSAqICAgICAjIS9iaW4vYmFzaAoJICogICAgIGlmICQod3AgLS11cmw9aHR0cDovL2V4YW1wbGUuY29tIGNvcmUgaXMtaW5zdGFsbGVkIC0tbmV0d29yayk7IHRoZW4KCSAqICAgICAgICAgd3Agc2VhcmNoLXJlcGxhY2UgLS11cmw9aHR0cDovL2V4YW1wbGUuY29tICdodHRwOi8vZXhhbXBsZS5jb20nICdodHRwOi8vZXhhbXBsZS50ZXN0JyAtLXJlY3Vyc2Utb2JqZWN0cyAtLW5ldHdvcmsgLS1za2lwLWNvbHVtbnM9Z3VpZCAtLXNraXAtdGFibGVzPXdwX3VzZXJzCgkgKiAgICAgZWxzZQoJICogICAgICAgICB3cCBzZWFyY2gtcmVwbGFjZSAnaHR0cDovL2V4YW1wbGUuY29tJyAnaHR0cDovL2V4YW1wbGUudGVzdCcgLS1yZWN1cnNlLW9iamVjdHMgLS1za2lwLWNvbHVtbnM9Z3VpZCAtLXNraXAtdGFibGVzPXdwX3VzZXJzCgkgKiAgICAgZmkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoJCSRvbGQgICAgICAgICAgICAgICAgICAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkbmV3ICAgICAgICAgICAgICAgICAgID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJHRvdGFsICAgICAgICAgICAgICAgICA9IDA7CgkJJHJlcG9ydCAgICAgICAgICAgICAgICA9IGFycmF5KCk7CgkJJHRoaXMtPmRyeV9ydW4gICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RyeS1ydW4nICk7CgkJJHBocF9vbmx5ICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ByZWNpc2UnICk7CgkJJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cyA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3JlY3Vyc2Utb2JqZWN0cycsIHRydWUgKTsKCQkkdGhpcy0+dmVyYm9zZSAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndmVyYm9zZScgKTsKCQkkdGhpcy0+Zm9ybWF0ICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApOwoJCSR0aGlzLT5yZWdleCAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWdleCcsIGZhbHNlICk7CgoJCWlmICggbnVsbCAhPT0gJHRoaXMtPnJlZ2V4ICkgewoJCQkkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgPSBmYWxzZTsKCQkJJHRoaXMtPnJlZ2V4X2ZsYWdzICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgtZmxhZ3MnLCBmYWxzZSApOwoJCQkkdGhpcy0+cmVnZXhfZGVsaW1pdGVyICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWdleC1kZWxpbWl0ZXInLCAnJyApOwoJCQlpZiAoICcnID09PSAkdGhpcy0+cmVnZXhfZGVsaW1pdGVyICkgewoJCQkJJHRoaXMtPnJlZ2V4X2RlbGltaXRlciAgID0gY2hyKCAxICk7CgkJCQkkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgPSB0cnVlOwoJCQl9CgkJfQoKCQkkcmVnZXhfbGltaXQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWdleC1saW1pdCcgKTsKCQlpZiAoIG51bGwgIT09ICRyZWdleF9saW1pdCApIHsKCQkJaWYgKCAhIHByZWdfbWF0Y2goICcvXig/OlswLTldK3wtMSkkLycsICRyZWdleF9saW1pdCApIHx8IDAgPT09IChpbnQpICRyZWdleF9saW1pdCApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdgLS1yZWdleC1saW1pdGAgZXhwZWN0cyBhIG5vbi16ZXJvIHBvc2l0aXZlIGludGVnZXIgb3IgLTEuJyApOwoJCQl9CgkJCSR0aGlzLT5yZWdleF9saW1pdCA9IChpbnQpICRyZWdleF9saW1pdDsKCQl9CgoJCWlmICggISBlbXB0eSggJHRoaXMtPnJlZ2V4ICkgKSB7CgkJCWlmICggJycgPT09ICR0aGlzLT5yZWdleF9kZWxpbWl0ZXIgKSB7CgkJCQkkdGhpcy0+cmVnZXhfZGVsaW1pdGVyID0gY2hyKCAxICk7CgkJCX0KCQkJJHNlYXJjaF9yZWdleCAgPSAkdGhpcy0+cmVnZXhfZGVsaW1pdGVyOwoJCQkkc2VhcmNoX3JlZ2V4IC49ICRvbGQ7CgkJCSRzZWFyY2hfcmVnZXggLj0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlcjsKCQkJJHNlYXJjaF9yZWdleCAuPSAkdGhpcy0+cmVnZXhfZmxhZ3M7CgoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5Ob1NpbGVuY2VkRXJyb3JzLkRpc2NvdXJhZ2VkIC0tIFByZXZlbnRpbmcgYSB3YXJuaW5nIHdoZW4gdGVzdGluZyB0aGUgcmVnZXguCgkJCWlmICggZmFsc2UgPT09IEBwcmVnX21hdGNoKCAkc2VhcmNoX3JlZ2V4LCAnJyApICkgewoJCQkJJGVycm9yICAgICAgICAgICAgICA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQkkcHJlZ19lcnJvcl9tZXNzYWdlID0gKCAhIGVtcHR5KCAkZXJyb3IgKSAmJiBhcnJheV9rZXlfZXhpc3RzKCAnbWVzc2FnZScsICRlcnJvciApICkgPyAiXG57JGVycm9yWydtZXNzYWdlJ119LiIgOiAnJzsKCQkJCWlmICggJGRlZmF1bHRfcmVnZXhfZGVsaW1pdGVyICkgewoJCQkJCSRmbGFnc19tc2cgPSAkdGhpcy0+cmVnZXhfZmxhZ3MgPyAiZmxhZ3MgJyR0aGlzLT5yZWdleF9mbGFncyciIDogJ25vIGZsYWdzJzsKCQkJCQkkbXNnICAgICAgID0gIlRoZSByZWdleCBwYXR0ZXJuICckb2xkJyB3aXRoIGRlZmF1bHQgZGVsaW1pdGVyICdjaHIoMSknIGFuZCB7JGZsYWdzX21zZ30gZmFpbHMuIjsKCQkJCX0gZWxzZSB7CgkJCQkJJG1zZyA9ICJUaGUgcmVnZXggJyRzZWFyY2hfcmVnZXgnIGZhaWxzLiI7CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCAkbXNnIC4gJHByZWdfZXJyb3JfbWVzc2FnZSApOwoJCQl9CgkJfQoKCQkkdGhpcy0+c2tpcF9jb2x1bW5zICAgID0gZXhwbG9kZSggJywnLCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWNvbHVtbnMnICkgKTsKCQkkdGhpcy0+c2tpcF90YWJsZXMgICAgID0gZXhwbG9kZSggJywnLCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXRhYmxlcycgKSApOwoJCSR0aGlzLT5pbmNsdWRlX2NvbHVtbnMgPSBhcnJheV9maWx0ZXIoIGV4cGxvZGUoICcsJywgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5jbHVkZS1jb2x1bW5zJyApICkgKTsKCgkJaWYgKCAkb2xkID09PSAkbmV3ICYmICEgJHRoaXMtPnJlZ2V4ICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJSZXBsYWNlbWVudCB2YWx1ZSAneyRvbGR9JyBpcyBpZGVudGljYWwgdG8gc2VhcmNoIHZhbHVlICd7JG5ld30nLiBTa2lwcGluZyBvcGVyYXRpb24uIiApOwoJCQlleGl0OwoJCX0KCgkJJGV4cG9ydCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2V4cG9ydCcgKTsKCQlpZiAoIG51bGwgIT09ICRleHBvcnQgKSB7CgkJCWlmICggJHRoaXMtPmRyeV9ydW4gKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnWW91IGNhbm5vdCBzdXBwbHkgLS1kcnktcnVuIGFuZCAtLWV4cG9ydCBhdCB0aGUgc2FtZSB0aW1lLicgKTsKCQkJfQoJCQlpZiAoIHRydWUgPT09ICRleHBvcnQgKSB7CgkJCQkkdGhpcy0+ZXhwb3J0X2hhbmRsZSA9IFNURE9VVDsKCQkJCSR0aGlzLT52ZXJib3NlICAgICAgID0gZmFsc2U7CgkJCX0gZWxzZSB7CgkJCQkkdGhpcy0+ZXhwb3J0X2hhbmRsZSA9IEBmb3BlbiggJGFzc29jX2FyZ3NbJ2V4cG9ydCddLCAndycgKTsKCQkJCWlmICggZmFsc2UgPT09ICR0aGlzLT5leHBvcnRfaGFuZGxlICkgewoJCQkJCSRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ1VuYWJsZSB0byBvcGVuIGV4cG9ydCBmaWxlICIlcyIgZm9yIHdyaXRpbmc6ICVzLicsICRhc3NvY19hcmdzWydleHBvcnQnXSwgJGVycm9yWydtZXNzYWdlJ10gKSApOwoJCQkJfQoJCQl9CgkJCSRleHBvcnRfaW5zZXJ0X3NpemUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdleHBvcnRfaW5zZXJ0X3NpemUnLCA1MCApOwoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5TdHJpY3RDb21wYXJpc29ucy5Mb29zZUNvbXBhcmlzb24gLS0gU2VlIHRoZSBjb2RlLCB0aGlzIGlzIGRlbGliZXJhdGUuCgkJCWlmICggKGludCkgJGV4cG9ydF9pbnNlcnRfc2l6ZSA9PSAkZXhwb3J0X2luc2VydF9zaXplICYmICRleHBvcnRfaW5zZXJ0X3NpemUgPiAwICkgewoJCQkJJHRoaXMtPmV4cG9ydF9pbnNlcnRfc2l6ZSA9ICRleHBvcnRfaW5zZXJ0X3NpemU7CgkJCX0KCQkJJHBocF9vbmx5ID0gdHJ1ZTsKCQl9CgoJCSRsb2cgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsb2cnICk7CgkJaWYgKCBudWxsICE9PSAkbG9nICkgewoJCQlpZiAoIHRydWUgPT09ICRsb2cgfHwgJy0nID09PSAkbG9nICkgewoJCQkJJHRoaXMtPmxvZ19oYW5kbGUgPSBTVERPVVQ7CgkJCX0gZWxzZSB7CgkJCQkkdGhpcy0+bG9nX2hhbmRsZSA9IEBmb3BlbiggJGFzc29jX2FyZ3NbJ2xvZyddLCAndycgKTsKCQkJCWlmICggZmFsc2UgPT09ICR0aGlzLT5sb2dfaGFuZGxlICkgewoJCQkJCSRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ1VuYWJsZSB0byBvcGVuIGxvZyBmaWxlICIlcyIgZm9yIHdyaXRpbmc6ICVzLicsICRhc3NvY19hcmdzWydsb2cnXSwgJGVycm9yWydtZXNzYWdlJ10gKSApOwoJCQkJfQoJCQl9CgkJCWlmICggJHRoaXMtPmxvZ19oYW5kbGUgKSB7CgkJCQkkYmVmb3JlX2NvbnRleHQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdiZWZvcmVfY29udGV4dCcgKTsKCQkJCWlmICggbnVsbCAhPT0gJGJlZm9yZV9jb250ZXh0ICYmIHByZWdfbWF0Y2goICcvXlswLTldKyQvJywgJGJlZm9yZV9jb250ZXh0ICkgKSB7CgkJCQkJJHRoaXMtPmxvZ19iZWZvcmVfY29udGV4dCA9IChpbnQpICRiZWZvcmVfY29udGV4dDsKCQkJCX0KCgkJCQkkYWZ0ZXJfY29udGV4dCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FmdGVyX2NvbnRleHQnICk7CgkJCQlpZiAoIG51bGwgIT09ICRhZnRlcl9jb250ZXh0ICYmIHByZWdfbWF0Y2goICcvXlswLTldKyQvJywgJGFmdGVyX2NvbnRleHQgKSApIHsKCQkJCQkkdGhpcy0+bG9nX2FmdGVyX2NvbnRleHQgPSAoaW50KSAkYWZ0ZXJfY29udGV4dDsKCQkJCX0KCgkJCQkkbG9nX3ByZWZpeGVzID0gZ2V0ZW52KCAnV1BfQ0xJX1NFQVJDSF9SRVBMQUNFX0xPR19QUkVGSVhFUycgKTsKCQkJCWlmICggZmFsc2UgIT09ICRsb2dfcHJlZml4ZXMgJiYgcHJlZ19tYXRjaCggJy9eKFteLF0qKSwoW14sXSopJC8nLCAkbG9nX3ByZWZpeGVzLCAkbWF0Y2hlcyApICkgewoJCQkJCSR0aGlzLT5sb2dfcHJlZml4ZXMgPSBhcnJheSggJG1hdGNoZXNbMV0sICRtYXRjaGVzWzJdICk7CgkJCQl9CgoJCQkJaWYgKCBTVERPVVQgPT09ICR0aGlzLT5sb2dfaGFuZGxlICkgewoJCQkJCSRkZWZhdWx0X2xvZ19jb2xvcnMgPSBhcnJheSgKCQkJCQkJJ2xvZ190YWJsZV9jb2x1bW5faWQnID0+ICclQicsCgkJCQkJCSdsb2dfb2xkJyAgICAgICAgICAgICA9PiAnJVInLAoJCQkJCQknbG9nX25ldycgICAgICAgICAgICAgPT4gJyVHJywKCQkJCQkpOwoJCQkJfSBlbHNlIHsKCQkJCQkkZGVmYXVsdF9sb2dfY29sb3JzID0gYXJyYXkoCgkJCQkJCSdsb2dfdGFibGVfY29sdW1uX2lkJyA9PiAnJywKCQkJCQkJJ2xvZ19vbGQnICAgICAgICAgICAgID0+ICcnLAoJCQkJCQknbG9nX25ldycgICAgICAgICAgICAgPT4gJycsCgkJCQkJKTsKCQkJCX0KCgkJCQkkbG9nX2NvbG9ycyA9IGdldGVudiggJ1dQX0NMSV9TRUFSQ0hfUkVQTEFDRV9MT0dfQ09MT1JTJyApOwoJCQkJaWYgKCBmYWxzZSAhPT0gJGxvZ19jb2xvcnMgJiYgcHJlZ19tYXRjaCggJy9eKFteLF0qKSwoW14sXSopLChbXixdKikkLycsICRsb2dfY29sb3JzLCAkbWF0Y2hlcyApICkgewoJCQkJCSRkZWZhdWx0X2xvZ19jb2xvcnMgPSBhcnJheSgKCQkJCQkJJ2xvZ190YWJsZV9jb2x1bW5faWQnID0+ICRtYXRjaGVzWzFdLAoJCQkJCQknbG9nX29sZCcgICAgICAgICAgICAgPT4gJG1hdGNoZXNbMl0sCgkJCQkJCSdsb2dfbmV3JyAgICAgICAgICAgICA9PiAkbWF0Y2hlc1szXSwKCQkJCQkpOwoJCQkJfQoKCQkJCSR0aGlzLT5sb2dfY29sb3JzICAgPSAkdGhpcy0+Z2V0X2NvbG9ycyggJGFzc29jX2FyZ3MsICRkZWZhdWx0X2xvZ19jb2xvcnMgKTsKCQkJCSR0aGlzLT5sb2dfZW5jb2RpbmcgPSAwID09PSBzdHJwb3MoICR3cGRiLT5jaGFyc2V0LCAndXRmOCcgKSA/ICdVVEYtOCcgOiBmYWxzZTsKCQkJfQoJCX0KCgkJJHRoaXMtPnJlcG9ydCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3JlcG9ydCcsIHRydWUgKTsKCQkvLyBEZWZhdWx0cyB0byB0cnVlIGlmIGxvZ2dpbmcsIGVsc2UgZGVmYXVsdHMgdG8gZmFsc2UuCgkJJHRoaXMtPnJlcG9ydF9jaGFuZ2VkX29ubHkgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZXBvcnQtY2hhbmdlZC1vbmx5JywgbnVsbCAhPT0gJHRoaXMtPmxvZ19oYW5kbGUgKTsKCgkJaWYgKCAkdGhpcy0+cmVnZXhfZmxhZ3MgKSB7CgkJCSRwaHBfb25seSA9IHRydWU7CgkJfQoKCQkvLyBuZXZlciBtZXNzIHdpdGggaGFzaGVkIHBhc3N3b3JkcwoJCSR0aGlzLT5za2lwX2NvbHVtbnNbXSA9ICd1c2VyX3Bhc3MnOwoKCQkvLyBHZXQgdGFibGUgbmFtZXMgYmFzZWQgb24gbGVmdG92ZXIgJGFyZ3Mgb3Igc3VwcGxpZWQgJGFzc29jX2FyZ3MKCQkkdGFibGVzID0gVXRpbHNcd3BfZ2V0X3RhYmxlX25hbWVzKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCgkJZm9yZWFjaCAoICR0YWJsZXMgYXMgJHRhYmxlICkgewoKCQkJZm9yZWFjaCAoICR0aGlzLT5za2lwX3RhYmxlcyBhcyAkc2tpcF90YWJsZSApIHsKCQkJCWlmICggZm5tYXRjaCggJHNraXBfdGFibGUsICR0YWJsZSApICkgewoJCQkJCWNvbnRpbnVlIDI7CgkJCQl9CgkJCX0KCgkJCSR0YWJsZV9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCgkJCWlmICggJHRoaXMtPmV4cG9ydF9oYW5kbGUgKSB7CgkJCQlmd3JpdGUoICR0aGlzLT5leHBvcnRfaGFuZGxlLCAiXG5EUk9QIFRBQkxFIElGIEVYSVNUUyAkdGFibGVfc3FsO1xuIiApOwoKCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkJCSRyb3cgPSAkd3BkYi0+Z2V0X3JvdyggIlNIT1cgQ1JFQVRFIFRBQkxFICR0YWJsZV9zcWwiLCBBUlJBWV9OICk7CgoJCQkJZndyaXRlKCAkdGhpcy0+ZXhwb3J0X2hhbmRsZSwgJHJvd1sxXSAuICI7XG4iICk7CgkJCQlsaXN0KCAkdGFibGVfcmVwb3J0LCAkdG90YWxfcm93cyApID0gJHRoaXMtPnBocF9leHBvcnRfdGFibGUoICR0YWJsZSwgJG9sZCwgJG5ldyApOwoJCQkJaWYgKCAkdGhpcy0+cmVwb3J0ICkgewoJCQkJCSRyZXBvcnQgPSBhcnJheV9tZXJnZSggJHJlcG9ydCwgJHRhYmxlX3JlcG9ydCApOwoJCQkJfQoJCQkJJHRvdGFsICs9ICR0b3RhbF9yb3dzOwoJCQkJLy8gRG9uJ3QgcGVyZm9ybSByZXBsYWNlbWVudHMgb24gdGhlIGFjdHVhbCBkYXRhYmFzZQoJCQkJY29udGludWU7CgkJCX0KCgkJCWxpc3QoICRwcmltYXJ5X2tleXMsICRjb2x1bW5zLCAkYWxsX2NvbHVtbnMgKSA9IHNlbGY6OmdldF9jb2x1bW5zKCAkdGFibGUgKTsKCgkJCS8vIHNpbmNlIHdlJ2xsIGJlIHVwZGF0aW5nIG9uZSByb3cgYXQgYSB0aW1lLAoJCQkvLyB3ZSBuZWVkIGEgcHJpbWFyeSBrZXkgdG8gaWRlbnRpZnkgdGhlIHJvdwoJCQlpZiAoIGVtcHR5KCAkcHJpbWFyeV9rZXlzICkgKSB7CgoJCQkJLy8gd2Fzbid0IHVwZGF0ZWQsIHNvIHNraXAgdG8gdGhlIG5leHQgdGFibGUKCQkJCWlmICggJHRoaXMtPnJlcG9ydF9jaGFuZ2VkX29ubHkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlpZiAoICR0aGlzLT5yZXBvcnQgKSB7CgkJCQkJJHJlcG9ydFtdID0gYXJyYXkoICR0YWJsZSwgJycsICdza2lwcGVkJywgJycgKTsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkYWxsX2NvbHVtbnMgPyAiTm8gcHJpbWFyeSBrZXlzIGZvciB0YWJsZSAnJHRhYmxlJy4iIDogIk5vIHN1Y2ggdGFibGUgJyR0YWJsZScuIiApOwoJCQkJfQoJCQkJY29udGludWU7CgkJCX0KCgkJCWZvcmVhY2ggKCAkY29sdW1ucyBhcyAkY29sICkgewoJCQkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+aW5jbHVkZV9jb2x1bW5zICkgJiYgISBpbl9hcnJheSggJGNvbCwgJHRoaXMtPmluY2x1ZGVfY29sdW1ucywgdHJ1ZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggaW5fYXJyYXkoICRjb2wsICR0aGlzLT5za2lwX2NvbHVtbnMsIHRydWUgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoICR0aGlzLT52ZXJib3NlICYmICdjb3VudCcgIT09ICR0aGlzLT5mb3JtYXQgKSB7CgkJCQkJJHRoaXMtPnN0YXJ0X3RpbWUgPSBtaWNyb3RpbWUoIHRydWUgKTsKCQkJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ0NoZWNraW5nOiAlcy4lcycsICR0YWJsZSwgJGNvbCApICk7CgkJCQl9CgoJCQkJaWYgKCAhICRwaHBfb25seSAmJiAhICR0aGlzLT5yZWdleCApIHsKCQkJCQkkY29sX3NxbCAgICAgICAgICA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICRjb2wgKTsKCQkJCQkkd3BkYi0+bGFzdF9lcnJvciA9ICcnOwoKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIGVzY2FwZWQgdGhyb3VnaCBzZWxmOjplc2Nfc3FsX2lkZW50CgkJCQkJJHNlcmlhbF9yb3cgPSAkd3BkYi0+Z2V0X3JvdyggIlNFTEVDVCAqIEZST00gJHRhYmxlX3NxbCBXSEVSRSAkY29sX3NxbCBSRUdFWFAgJ15bYWlPXTpbMS05XScgTElNSVQgMSIgKTsKCgkJCQkJLy8gV2hlbiB0aGUgcmVnZXggdHJpZ2dlcnMgYW4gZXJyb3IsIHdlIHNob3VsZCBmYWxsIGJhY2sgdG8gUEhQCgkJCQkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkd3BkYi0+bGFzdF9lcnJvciwgJ0VSUk9SIDExMzknICkgKSB7CgkJCQkJCSRzZXJpYWxfcm93ID0gdHJ1ZTsKCQkJCQl9CgkJCQl9CgoJCQkJaWYgKCAkcGhwX29ubHkgfHwgJHRoaXMtPnJlZ2V4IHx8IG51bGwgIT09ICRzZXJpYWxfcm93ICkgewoJCQkJCSR0eXBlICA9ICdQSFAnOwoJCQkJCSRjb3VudCA9ICR0aGlzLT5waHBfaGFuZGxlX2NvbCggJGNvbCwgJHByaW1hcnlfa2V5cywgJHRhYmxlLCAkb2xkLCAkbmV3ICk7CgkJCQl9IGVsc2UgewoJCQkJCSR0eXBlICA9ICdTUUwnOwoJCQkJCSRjb3VudCA9ICR0aGlzLT5zcWxfaGFuZGxlX2NvbCggJGNvbCwgJHByaW1hcnlfa2V5cywgJHRhYmxlLCAkb2xkLCAkbmV3ICk7CgkJCQl9CgoJCQkJaWYgKCAkdGhpcy0+cmVwb3J0ICYmICggJGNvdW50IHx8ICEgJHRoaXMtPnJlcG9ydF9jaGFuZ2VkX29ubHkgKSApIHsKCQkJCQkkcmVwb3J0W10gPSBhcnJheSggJHRhYmxlLCAkY29sLCAkY291bnQsICR0eXBlICk7CgkJCQl9CgoJCQkJJHRvdGFsICs9ICRjb3VudDsKCQkJfQoJCX0KCgkJaWYgKCAkdGhpcy0+ZXhwb3J0X2hhbmRsZSAmJiBTVERPVVQgIT09ICR0aGlzLT5leHBvcnRfaGFuZGxlICkgewoJCQlmY2xvc2UoICR0aGlzLT5leHBvcnRfaGFuZGxlICk7CgkJfQoKCQkvLyBPbmx5IGluZm9ybWF0aW9uYWwgb3V0cHV0IGFmdGVyIHRoaXMgcG9pbnQKCQlpZiAoIFdQX0NMSTo6Z2V0X2NvbmZpZyggJ3F1aWV0JyApIHx8IFNURE9VVCA9PT0gJHRoaXMtPmV4cG9ydF9oYW5kbGUgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggJ2NvdW50JyA9PT0gJHRoaXMtPmZvcm1hdCApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkdG90YWwgKTsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAkdGhpcy0+cmVwb3J0ICYmICEgZW1wdHkoICRyZXBvcnQgKSApIHsKCQkJJHRhYmxlID0gbmV3IFRhYmxlKCk7CgkJCSR0YWJsZS0+c2V0SGVhZGVycyggYXJyYXkoICdUYWJsZScsICdDb2x1bW4nLCAnUmVwbGFjZW1lbnRzJywgJ1R5cGUnICkgKTsKCQkJJHRhYmxlLT5zZXRSb3dzKCAkcmVwb3J0ICk7CgkJCSR0YWJsZS0+ZGlzcGxheSgpOwoJCX0KCgkJaWYgKCAhICR0aGlzLT5kcnlfcnVuICkgewoJCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydleHBvcnQnXSApICkgewoJCQkJJHN1Y2Nlc3NfbWVzc2FnZSA9IDEgPT09ICR0b3RhbCA/ICJNYWRlIDEgcmVwbGFjZW1lbnQgYW5kIGV4cG9ydGVkIHRvIHskYXNzb2NfYXJnc1snZXhwb3J0J119LiIgOiAiTWFkZSB7JHRvdGFsfSByZXBsYWNlbWVudHMgYW5kIGV4cG9ydGVkIHRvIHskYXNzb2NfYXJnc1snZXhwb3J0J119LiI7CgkJCX0gZWxzZSB7CgkJCQkkc3VjY2Vzc19tZXNzYWdlID0gMSA9PT0gJHRvdGFsID8gJ01hZGUgMSByZXBsYWNlbWVudC4nIDogIk1hZGUgJHRvdGFsIHJlcGxhY2VtZW50cy4iOwoJCQkJaWYgKCAkdG90YWwgJiYgJ0RlZmF1bHQnICE9PSBVdGlsc1x3cF9nZXRfY2FjaGVfdHlwZSgpICkgewoJCQkJCSRzdWNjZXNzX21lc3NhZ2UgLj0gJyBQbGVhc2UgcmVtZW1iZXIgdG8gZmx1c2ggeW91ciBwZXJzaXN0ZW50IG9iamVjdCBjYWNoZSB3aXRoIGB3cCBjYWNoZSBmbHVzaGAuJzsKCQkJCX0KCQkJfQoJCQlXUF9DTEk6OnN1Y2Nlc3MoICRzdWNjZXNzX21lc3NhZ2UgKTsKCQl9IGVsc2UgewoJCQkkc3VjY2Vzc19tZXNzYWdlID0gKCAxID09PSAkdG90YWwgKSA/ICclZCByZXBsYWNlbWVudCB0byBiZSBtYWRlLicgOiAnJWQgcmVwbGFjZW1lbnRzIHRvIGJlIG1hZGUuJzsKCQkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAkc3VjY2Vzc19tZXNzYWdlLCAkdG90YWwgKSApOwoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIHBocF9leHBvcnRfdGFibGUoICR0YWJsZSwgJG9sZCwgJG5ldyApIHsKCQlsaXN0KCAkcHJpbWFyeV9rZXlzLCAkY29sdW1ucywgJGFsbF9jb2x1bW5zICkgPSBzZWxmOjpnZXRfY29sdW1ucyggJHRhYmxlICk7CgoJCSRjaHVua19zaXplID0gZ2V0ZW52KCAnQkVIQVRfUlVOJyApID8gMTAgOiAxMDAwOwoJCSRhcmdzICAgICAgID0gYXJyYXkoCgkJCSd0YWJsZScgICAgICA9PiAkdGFibGUsCgkJCSdmaWVsZHMnICAgICA9PiAkYWxsX2NvbHVtbnMsCgkJCSdjaHVua19zaXplJyA9PiAkY2h1bmtfc2l6ZSwKCQkpOwoKCQkkcmVwbGFjZXIgICA9IG5ldyBTZWFyY2hSZXBsYWNlciggJG9sZCwgJG5ldywgJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cywgJHRoaXMtPnJlZ2V4LCAkdGhpcy0+cmVnZXhfZmxhZ3MsICR0aGlzLT5yZWdleF9kZWxpbWl0ZXIsIGZhbHNlLCAkdGhpcy0+cmVnZXhfbGltaXQgKTsKCQkkY29sX2NvdW50cyA9IGFycmF5X2ZpbGxfa2V5cyggJGFsbF9jb2x1bW5zLCAwICk7CgkJaWYgKCAkdGhpcy0+dmVyYm9zZSAmJiAndGFibGUnID09PSAkdGhpcy0+Zm9ybWF0ICkgewoJCQkkdGhpcy0+c3RhcnRfdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApOwoJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ0NoZWNraW5nOiAlcycsICR0YWJsZSApICk7CgkJfQoKCQkkcm93cyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoIG5ldyBJdGVyYXRvcnNcVGFibGUoICRhcmdzICkgYXMgJGkgPT4gJHJvdyApIHsKCQkJJHJvd19maWVsZHMgPSBhcnJheSgpOwoJCQlmb3JlYWNoICggJGFsbF9jb2x1bW5zIGFzICRjb2wgKSB7CgkJCQkkdmFsdWUgPSAkcm93LT4kY29sOwoJCQkJaWYgKCAkdmFsdWUgJiYgISBpbl9hcnJheSggJGNvbCwgJHByaW1hcnlfa2V5cywgdHJ1ZSApICYmICEgaW5fYXJyYXkoICRjb2wsICR0aGlzLT5za2lwX2NvbHVtbnMsIHRydWUgKSApIHsKCQkJCQkkbmV3X3ZhbHVlID0gJHJlcGxhY2VyLT5ydW4oICR2YWx1ZSApOwoJCQkJCWlmICggJG5ld192YWx1ZSAhPT0gJHZhbHVlICkgewoJCQkJCQkkY29sX2NvdW50c1sgJGNvbCBdKys7CgkJCQkJCSR2YWx1ZSA9ICRuZXdfdmFsdWU7CgkJCQkJfQoJCQkJfQoJCQkJJHJvd19maWVsZHNbICRjb2wgXSA9ICR2YWx1ZTsKCQkJfQoJCQkkcm93c1tdID0gJHJvd19maWVsZHM7CgkJfQoJCSR0aGlzLT53cml0ZV9zcWxfcm93X2ZpZWxkcyggJHRhYmxlLCAkcm93cyApOwoKCQkkdGFibGVfcmVwb3J0ID0gYXJyYXkoKTsKCQkkdG90YWxfcm93cyAgID0gMDsKCQkkdG90YWxfY29scyAgID0gMDsKCQlmb3JlYWNoICggJGNvbF9jb3VudHMgYXMgJGNvbCA9PiAkY29sX2NvdW50ICkgewoJCQlpZiAoICR0aGlzLT5yZXBvcnQgJiYgKCAkY29sX2NvdW50IHx8ICEgJHRoaXMtPnJlcG9ydF9jaGFuZ2VkX29ubHkgKSApIHsKCQkJCSR0YWJsZV9yZXBvcnRbXSA9IGFycmF5KCAkdGFibGUsICRjb2wsICRjb2xfY291bnQsICdQSFAnICk7CgkJCX0KCQkJaWYgKCAkY29sX2NvdW50ICkgewoJCQkJJHRvdGFsX2NvbHMrKzsKCQkJCSR0b3RhbF9yb3dzICs9ICRjb2xfY291bnQ7CgkJCX0KCQl9CgoJCWlmICggJHRoaXMtPnZlcmJvc2UgJiYgJ3RhYmxlJyA9PT0gJHRoaXMtPmZvcm1hdCApIHsKCQkJJHRpbWUgPSByb3VuZCggbWljcm90aW1lKCB0cnVlICkgLSAkdGhpcy0+c3RhcnRfdGltZSwgMyApOwoJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJyVkIGNvbHVtbnMgYW5kICVkIHRvdGFsIHJvd3MgYWZmZWN0ZWQgdXNpbmcgUEhQIChpbiAlc3MpLicsICR0b3RhbF9jb2xzLCAkdG90YWxfcm93cywgJHRpbWUgKSApOwoJCX0KCgkJcmV0dXJuIGFycmF5KCAkdGFibGVfcmVwb3J0LCAkdG90YWxfcm93cyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc3FsX2hhbmRsZV9jb2woICRjb2wsICRwcmltYXJ5X2tleXMsICR0YWJsZSwgJG9sZCwgJG5ldyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSR0YWJsZV9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCQkkY29sX3NxbCAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGNvbCApOwoJCWlmICggJHRoaXMtPmRyeV9ydW4gKSB7CgkJCWlmICggJHRoaXMtPmxvZ19oYW5kbGUgKSB7CgkJCQkkY291bnQgPSAkdGhpcy0+bG9nX3NxbF9kaWZmKCAkY29sLCAkcHJpbWFyeV9rZXlzLCAkdGFibGUsICRvbGQsICRuZXcgKTsKCQkJfSBlbHNlIHsKCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkJCSRjb3VudCA9ICR3cGRiLT5nZXRfdmFyKCAkd3BkYi0+cHJlcGFyZSggIlNFTEVDVCBDT1VOVCgkY29sX3NxbCkgRlJPTSAkdGFibGVfc3FsIFdIRVJFICRjb2xfc3FsIExJS0UgQklOQVJZICVzOyIsICclJyAuIHNlbGY6OmVzY19saWtlKCAkb2xkICkgLiAnJScgKSApOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKCAkdGhpcy0+bG9nX2hhbmRsZSApIHsKCQkJCSR0aGlzLT5sb2dfc3FsX2RpZmYoICRjb2wsICRwcmltYXJ5X2tleXMsICR0YWJsZSwgJG9sZCwgJG5ldyApOwoJCQl9CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkJJGNvdW50ID0gJHdwZGItPnF1ZXJ5KCAkd3BkYi0+cHJlcGFyZSggIlVQREFURSAkdGFibGVfc3FsIFNFVCAkY29sX3NxbCA9IFJFUExBQ0UoJGNvbF9zcWwsICVzLCAlcyk7IiwgJG9sZCwgJG5ldyApICk7CgkJfQoKCQlpZiAoICR0aGlzLT52ZXJib3NlICYmICd0YWJsZScgPT09ICR0aGlzLT5mb3JtYXQgKSB7CgkJCSR0aW1lID0gcm91bmQoIG1pY3JvdGltZSggdHJ1ZSApIC0gJHRoaXMtPnN0YXJ0X3RpbWUsIDMgKTsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICclZCByb3dzIGFmZmVjdGVkIHVzaW5nIFNRTCAoaW4gJXNzKS4nLCAkY291bnQsICR0aW1lICkgKTsKCQl9CgkJcmV0dXJuICRjb3VudDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHBocF9oYW5kbGVfY29sKCAkY29sLCAkcHJpbWFyeV9rZXlzLCAkdGFibGUsICRvbGQsICRuZXcgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkY291bnQgICAgPSAwOwoJCSRyZXBsYWNlciA9IG5ldyBTZWFyY2hSZXBsYWNlciggJG9sZCwgJG5ldywgJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cywgJHRoaXMtPnJlZ2V4LCAkdGhpcy0+cmVnZXhfZmxhZ3MsICR0aGlzLT5yZWdleF9kZWxpbWl0ZXIsIG51bGwgIT09ICR0aGlzLT5sb2dfaGFuZGxlLCAkdGhpcy0+cmVnZXhfbGltaXQgKTsKCgkJJHRhYmxlX3NxbCAgICAgICAgICAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJHRhYmxlICk7CgkJJGNvbF9zcWwgICAgICAgICAgICAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGNvbCApOwoJCSR3aGVyZSAgICAgICAgICAgICAgICA9ICR0aGlzLT5yZWdleCA/ICcnIDogIiBXSEVSRSAkY29sX3NxbCIgLiAkd3BkYi0+cHJlcGFyZSggJyBMSUtFIEJJTkFSWSAlcycsICclJyAuIHNlbGY6OmVzY19saWtlKCAkb2xkICkgLiAnJScgKTsKCQkkZXNjYXBlZF9wcmltYXJ5X2tleXMgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkcHJpbWFyeV9rZXlzICk7CgkJJHByaW1hcnlfa2V5c19zcWwgICAgID0gaW1wbG9kZSggJywnLCAkZXNjYXBlZF9wcmltYXJ5X2tleXMgKTsKCQkkb3JkZXJfYnlfa2V5cyAgICAgICAgPSBhcnJheV9tYXAoCgkJCXN0YXRpYyBmdW5jdGlvbiAoICRrZXkgKSB7CgkJCQlyZXR1cm4gInska2V5fSBBU0MiOwoJCQl9LAoJCQkkZXNjYXBlZF9wcmltYXJ5X2tleXMKCQkpOwoJCSRvcmRlcl9ieV9zcWwgICAgICAgICA9ICdPUkRFUiBCWSAnIC4gaW1wbG9kZSggJywnLCAkb3JkZXJfYnlfa2V5cyApOwoJCSRsaW1pdCAgICAgICAgICAgICAgICA9IDEwMDA7CgkJJG9mZnNldCAgICAgICAgICAgICAgID0gMDsKCgkJLy8gVXBkYXRlcyBoYXZlIHRvIGJlIGRlZmVycmVkIHRvIGFmdGVyIHRoZSBjaHVua2luZyBpcyBjb21wbGV0ZWQsIGFzCgkJLy8gdGhlIG9mZnNldCB3aWxsIG90aGVyd2lzZSBub3Qgd29yayBjb3JyZWN0bHkuCgkJJHVwZGF0ZXMgPSBbXTsKCgkJLy8gMiBlcnJvcnM6CgkJLy8gLSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkvLyAtIFdvcmRQcmVzcy5Db2RlQW5hbHlzaXMuQXNzaWdubWVudEluQ29uZGl0aW9uIC0tIG5vIHJlYXNvbiB0byBkbyBjb3B5LXBhc3RlIGZvciBhIHNpbmdsZSB2YWxpZCBhc3NpZ25tZW50IGluIHdoaWxlCgkJLy8gcGhwY3M6aWdub3JlCgkJd2hpbGUgKCAkcm93cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIlNFTEVDVCB7JHByaW1hcnlfa2V5c19zcWx9IEZST00geyR0YWJsZV9zcWx9IHskd2hlcmV9IHskb3JkZXJfYnlfc3FsfSBMSU1JVCB7JGxpbWl0fSBPRkZTRVQgeyRvZmZzZXR9IiApICkgewoJCQlmb3JlYWNoICggJHJvd3MgYXMgJGtleXMgKSB7CgkJCQkkd2hlcmVfc3FsID0gJyc7CgkJCQlmb3JlYWNoICggKGFycmF5KSAka2V5cyBhcyAkayA9PiAkdiApIHsKCQkJCQlpZiAoICcnICE9PSAkd2hlcmVfc3FsICkgewoJCQkJCQkkd2hlcmVfc3FsIC49ICcgQU5EICc7CgkJCQkJfQoJCQkJCSR3aGVyZV9zcWwgLj0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGsgKSAuICcgPSAnIC4gc2VsZjo6ZXNjX3NxbF92YWx1ZSggJHYgKTsKCQkJCX0KCgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIGVzY2FwZWQgdGhyb3VnaCBzZWxmOjplc2Nfc3FsX2lkZW50CgkJCQkkY29sX3ZhbHVlID0gJHdwZGItPmdldF92YXIoICJTRUxFQ1QgeyRjb2xfc3FsfSBGUk9NIHskdGFibGVfc3FsfSBXSEVSRSB7JHdoZXJlX3NxbH0iICk7CgoJCQkJaWYgKCAnJyA9PT0gJGNvbF92YWx1ZSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkdmFsdWUgPSAkcmVwbGFjZXItPnJ1biggJGNvbF92YWx1ZSApOwoKCQkJCWlmICggJHZhbHVlID09PSAkY29sX3ZhbHVlICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggJHRoaXMtPmxvZ19oYW5kbGUgKSB7CgkJCQkJJHRoaXMtPmxvZ19waHBfZGlmZiggJGNvbCwgJGtleXMsICR0YWJsZSwgJG9sZCwgJG5ldywgJHJlcGxhY2VyLT5nZXRfbG9nX2RhdGEoKSApOwoJCQkJCSRyZXBsYWNlci0+Y2xlYXJfbG9nX2RhdGEoKTsKCQkJCX0KCgkJCQkkY291bnQrKzsKCQkJCWlmICggISAkdGhpcy0+ZHJ5X3J1biApIHsKCQkJCQkkdXBkYXRlX3doZXJlID0gYXJyYXkoKTsKCQkJCQlmb3JlYWNoICggKGFycmF5KSAka2V5cyBhcyAkayA9PiAkdiApIHsKCQkJCQkJJHVwZGF0ZV93aGVyZVsgJGsgXSA9ICR2OwoJCQkJCX0KCgkJCQkJJHVwZGF0ZXNbXSA9IFsgJHRhYmxlLCBhcnJheSggJGNvbCA9PiAkdmFsdWUgKSwgJHVwZGF0ZV93aGVyZSBdOwoJCQkJfQoJCQl9CgoJCQkkb2Zmc2V0ICs9ICRsaW1pdDsKCQl9CgoJCWZvcmVhY2ggKCAkdXBkYXRlcyBhcyAkdXBkYXRlICkgewoJCQkkd3BkYi0+dXBkYXRlKCAuLi4kdXBkYXRlICk7CgkJfQoKCQlpZiAoICR0aGlzLT52ZXJib3NlICYmICd0YWJsZScgPT09ICR0aGlzLT5mb3JtYXQgKSB7CgkJCSR0aW1lID0gcm91bmQoIG1pY3JvdGltZSggdHJ1ZSApIC0gJHRoaXMtPnN0YXJ0X3RpbWUsIDMgKTsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICclZCByb3dzIGFmZmVjdGVkIHVzaW5nIFBIUCAoaW4gJXNzKS4nLCAkY291bnQsICR0aW1lICkgKTsKCQl9CgoJCXJldHVybiAkY291bnQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZV9zcWxfcm93X2ZpZWxkcyggJHRhYmxlLCAkcm93cyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCWlmICggZW1wdHkoICRyb3dzICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCSR0YWJsZV9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCgkJJGluc2VydCAgPSAiSU5TRVJUIElOVE8gJHRhYmxlX3NxbCAoIjsKCQkkaW5zZXJ0IC49IGpvaW4oICcsICcsIHNlbGY6OmVzY19zcWxfaWRlbnQoIGFycmF5X2tleXMoICRyb3dzWzBdICkgKSApOwoJCSRpbnNlcnQgLj0gJykgVkFMVUVTICc7CgkJJGluc2VydCAuPSAiXG4iOwoKCQkkc3FsICAgID0gJGluc2VydDsKCQkkdmFsdWVzID0gYXJyYXkoKTsKCgkJJGluZGV4ICAgICAgICAgICAgICA9IDE7CgkJJGNvdW50ICAgICAgICAgICAgICA9IGNvdW50KCAkcm93cyApOwoJCSRleHBvcnRfaW5zZXJ0X3NpemUgPSAkdGhpcy0+ZXhwb3J0X2luc2VydF9zaXplOwoKCQlmb3JlYWNoICggJHJvd3MgYXMgJHJvd19maWVsZHMgKSB7CgkJCSRzdWJzID0gYXJyYXkoKTsKCgkJCWZvcmVhY2ggKCAkcm93X2ZpZWxkcyBhcyAkZmllbGRfdmFsdWUgKSB7CgkJCQlpZiAoIG51bGwgPT09ICRmaWVsZF92YWx1ZSApIHsKCQkJCQkkc3Vic1tdID0gJ05VTEwnOwoJCQkJfSBlbHNlIHsKCQkJCQkkc3Vic1tdICAgPSAnJXMnOwoJCQkJCSR2YWx1ZXNbXSA9ICRmaWVsZF92YWx1ZTsKCQkJCX0KCQkJfQoKCQkJJHNxbCAuPSAnKCcgLiBqb2luKCAnLCAnLCAkc3VicyApIC4gJyknOwoKCQkJLy8gQWRkIG5ldyBpbnNlcnQgc3RhdGVtZW50IGlmIG5lZWRlZC4gQmVmb3JlIHRoaXMgd2UgY2xvc2UgdGhlIHByZXZpb3VzIHdpdGggc2VtaWNvbG9uIGFuZCB3cml0ZSBzdGF0ZW1lbnQgdG8gc3FsLWZpbGUuCgkJCS8vICJTdGF0ZW1lbnQgYnJlYWsiIGlzIG5lZWRlZDoKCQkJLy8JCTEuIFdoZW4gdGhlIGxvb3AgaXMgcnVubmluZyBldmVyeSBudGggdGltZSAod2hlcmUgbiBpcyBpbnNlcnQgc3RhdGVtZW50IHNpemUsICRleHBvcnRfaW5kZXhfc2l6ZSkuIFJlbWFpbmRlciBpcyB6ZXJvIGFsc28gb24gZmlyc3Qgcm91bmQsIHNvIGl0IGhhdmUgdG8gYmUgZXhjbHVkZWQuCgkJCS8vCQkJJGluZGV4ICUgJGV4cG9ydF9pbnNlcnRfc2l6ZSA9PSAwICYmICRpbmRleCA+IDAKCQkJLy8JCTIuIE9yIHdoZW4gdGhlIGxvb3AgaXMgcnVubmluZyBsYXN0IHRpbWUKCQkJLy8JCQkkaW5kZXggPT0gJGNvdW50CgkJCWlmICggKCAwID09PSAkaW5kZXggJSAkZXhwb3J0X2luc2VydF9zaXplICYmICRpbmRleCA+IDAgKSB8fCAkaW5kZXggPT09ICRjb3VudCApIHsKCQkJCSRzcWwgLj0gIjtcbiI7CgoJCQkJaWYgKCBtZXRob2RfZXhpc3RzKCAkd3BkYiwgJ3JlbW92ZV9wbGFjZWhvbGRlcl9lc2NhcGUnICkgKSB7CgkJCQkJLy8gc2luY2UgNC44LjMKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIHZlcmlmaWVkIGlucHV0cyBhYm92ZQoJCQkJCSRzcWwgPSAkd3BkYi0+cmVtb3ZlX3BsYWNlaG9sZGVyX2VzY2FwZSggJHdwZGItPnByZXBhcmUoICRzcWwsIGFycmF5X3ZhbHVlcyggJHZhbHVlcyApICkgKTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gNC44LjIgb3IgbGVzcwoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gdmVyaWZpZWQgaW5wdXRzIGFib3ZlCgkJCQkJJHNxbCA9ICR3cGRiLT5wcmVwYXJlKCAkc3FsLCBhcnJheV92YWx1ZXMoICR2YWx1ZXMgKSApOwoJCQkJfQoKCQkJCWZ3cml0ZSggJHRoaXMtPmV4cG9ydF9oYW5kbGUsICRzcWwgKTsKCgkJCQkvLyBJZiB0aGVyZSBpcyBzdGlsbCByb3dzIHRvIGxvb3AsIHJlc2V0ICRzcWwgYW5kICR2YWx1ZXMgdmFyaWFibGVzLgoJCQkJaWYgKCAkY291bnQgPiAkaW5kZXggKSB7CgkJCQkJJHNxbCAgICA9ICRpbnNlcnQ7CgkJCQkJJHZhbHVlcyA9IGFycmF5KCk7CgkJCQl9CgkJCX0gZWxzZSB7IC8vIE90aGVyd2lzZSBqdXN0IGFkZCBjb21tYSBhbmQgbmV3IGxpbmUKCQkJCSRzcWwgLj0gIixcbiI7CgkJCX0KCgkJCSRpbmRleCsrOwoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfY29sdW1ucyggJHRhYmxlICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJHRhYmxlX3NxbCAgICAgICA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICR0YWJsZSApOwoJCSRwcmltYXJ5X2tleXMgICAgPSBhcnJheSgpOwoJCSR0ZXh0X2NvbHVtbnMgICAgPSBhcnJheSgpOwoJCSRhbGxfY29sdW1ucyAgICAgPSBhcnJheSgpOwoJCSRzdXBwcmVzc19lcnJvcnMgPSAkd3BkYi0+c3VwcHJlc3NfZXJyb3JzKCk7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIkRFU0NSSUJFICR0YWJsZV9zcWwiICk7CgoJCWlmICggISBlbXB0eSggJHJlc3VsdHMgKSApIHsKCQkJZm9yZWFjaCAoICRyZXN1bHRzIGFzICRjb2wgKSB7CgkJCQlpZiAoICdQUkknID09PSAkY29sLT5LZXkgKSB7CgkJCQkJJHByaW1hcnlfa2V5c1tdID0gJGNvbC0+RmllbGQ7CgkJCQl9CgkJCQlpZiAoIHNlbGY6OmlzX3RleHRfY29sKCAkY29sLT5UeXBlICkgKSB7CgkJCQkJJHRleHRfY29sdW1uc1tdID0gJGNvbC0+RmllbGQ7CgkJCQl9CgkJCQkkYWxsX2NvbHVtbnNbXSA9ICRjb2wtPkZpZWxkOwoJCQl9CgkJfQoJCSR3cGRiLT5zdXBwcmVzc19lcnJvcnMoICRzdXBwcmVzc19lcnJvcnMgKTsKCQlyZXR1cm4gYXJyYXkoICRwcmltYXJ5X2tleXMsICR0ZXh0X2NvbHVtbnMsICRhbGxfY29sdW1ucyApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzX3RleHRfY29sKCAkdHlwZSApIHsKCQlmb3JlYWNoICggYXJyYXkoICd0ZXh0JywgJ3ZhcmNoYXInICkgYXMgJHRva2VuICkgewoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICR0eXBlLCAkdG9rZW4gKSApIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX2xpa2UoICRvbGQgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBSZW1vdmUgbm90aWNlcyBpbiA0LjAgYW5kIHN1cHBvcnQgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkKCQlpZiAoIG1ldGhvZF9leGlzdHMoICR3cGRiLCAnZXNjX2xpa2UnICkgKSB7CgkJCS8vIDQuMAoJCQkkb2xkID0gJHdwZGItPmVzY19saWtlKCAkb2xkICk7CgkJfSBlbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkRnVuY3Rpb25zLmxpa2VfZXNjYXBlRm91bmQgLS0gQkMtbGF5ZXIgZm9yIFdQIDMuOSBvciBsZXNzLgoJCQkkb2xkID0gbGlrZV9lc2NhcGUoIGVzY19zcWwoICRvbGQgKSApOyAvLyBOb3RlOiB0aGlzIGRvdWJsZSBlc2NhcGluZyBpcyBhY3R1YWxseSBuZWNlc3NhcnksIGV2ZW4gdGhvdWdoIGBlc2NfbGlrZSgpYCB3aWxsIGJlIHVzZWQgaW4gYSBgcHJlcGFyZSgpYC4KCQl9CgoJCXJldHVybiAkb2xkOwoJfQoKCS8qKgoJICogRXNjYXBlcyAoYmFja3RpY2tzKSBNeVNRTCBpZGVudGlmaWVycyAoYWthIHNjaGVtYSBvYmplY3QgbmFtZXMpIC0gaS5lLiBjb2x1bW4gbmFtZXMsIHRhYmxlIG5hbWVzLCBhbmQgZGF0YWJhc2UvaW5kZXgvYWxpYXMvdmlldyBldGMgbmFtZXMuCgkgKiBTZWUgaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNS41L2VuL2lkZW50aWZpZXJzLmh0bWwKCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRpZGVudHMgQSBzaW5nbGUgaWRlbnRpZmllciBvciBhbiBhcnJheSBvZiBpZGVudGlmaWVycy4KCSAqIEByZXR1cm4gc3RyaW5nfGFycmF5IEFuIGVzY2FwZWQgc3RyaW5nIGlmIGdpdmVuIGEgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBlc2NhcGVkIHN0cmluZ3MgaWYgZ2l2ZW4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX3NxbF9pZGVudCggJGlkZW50cyApIHsKCQkkYmFja3RpY2sgPSBzdGF0aWMgZnVuY3Rpb24gKCAkdiApIHsKCQkJLy8gRXNjYXBlIGFueSBiYWNrdGlja3MgaW4gdGhlIGlkZW50aWZpZXIgYnkgZG91YmxpbmcuCgkJCXJldHVybiAnYCcgLiBzdHJfcmVwbGFjZSggJ2AnLCAnYGAnLCAkdiApIC4gJ2AnOwoJCX07CgkJaWYgKCBpc19zdHJpbmcoICRpZGVudHMgKSApIHsKCQkJcmV0dXJuICRiYWNrdGljayggJGlkZW50cyApOwoJCX0KCQlyZXR1cm4gYXJyYXlfbWFwKCAkYmFja3RpY2ssICRpZGVudHMgKTsKCX0KCgkvKioKCSAqIFB1dHMgTXlTUUwgc3RyaW5nIHZhbHVlcyBpbiBzaW5nbGUgcXVvdGVzLCB0byBhdm9pZCB0aGVtIGJlaW5nIGludGVycHJldGVkIGFzIGNvbHVtbiBuYW1lcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICR2YWx1ZXMgQSBzaW5nbGUgdmFsdWUgb3IgYW4gYXJyYXkgb2YgdmFsdWVzLgoJICogQHJldHVybiBzdHJpbmd8YXJyYXkgQSBxdW90ZWQgc3RyaW5nIGlmIGdpdmVuIGEgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBxdW90ZWQgc3RyaW5ncyBpZiBnaXZlbiBhbiBhcnJheSBvZiBzdHJpbmdzLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBlc2Nfc3FsX3ZhbHVlKCAkdmFsdWVzICkgewoJCSRxdW90ZSA9IHN0YXRpYyBmdW5jdGlvbiAoICR2ICkgewoJCQkvLyBEb24ndCBxdW90ZSBpbnRlZ2VyIHZhbHVlcyB0byBhdm9pZCBNeVNRTCdzIGltcGxpY2l0IHR5cGUgY29udmVyc2lvbi4KCQkJaWYgKCBwcmVnX21hdGNoKCAnL15bKy1dP1swLTldezEsMjB9JC8nLCAkdiApICkgeyAvLyBNeVNRTCBCSUdJTlQgVU5TSUdORUQgbWF4IDE4NDQ2NzQ0MDczNzA5NTUxNjE1ICgyMCBkaWdpdHMpLgoJCQkJcmV0dXJuIGVzY19zcWwoICR2ICk7CgkJCX0KCgkJCS8vIFB1dCBhbnkgc3RyaW5nIHZhbHVlcyBiZXR3ZWVuIHNpbmdsZSBxdW90ZXMuCgkJCXJldHVybiAiJyIgLiBlc2Nfc3FsKCAkdiApIC4gIiciOwoJCX07CgoJCWlmICggaXNfYXJyYXkoICR2YWx1ZXMgKSApIHsKCQkJcmV0dXJuIGFycmF5X21hcCggJHF1b3RlLCAkdmFsdWVzICk7CgkJfQoKCQlyZXR1cm4gJHF1b3RlKCAkdmFsdWVzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBjb2xvciBjb2RlcyBmcm9tIHRoZSBvcHRpb25zIGlmIGFueSwgYW5kIHJldHVybnMgdGhlIHBhc3NlZCBpbiBhcnJheSBjb2xvcml6ZWQgd2l0aCAyIGVsZW1lbnRzIHBlciBlbnRyeSwgYSBjb2xvciBjb2RlIChvciAnJykgYW5kIGEgcmVzZXQgKG9yICcnKS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgVGhlIGFzc29jaWF0aXZlIGFyZ3VtZW50IGFycmF5IHBhc3NlZCB0byB0aGUgY29tbWFuZC4KCSAqIEBwYXJhbSBhcnJheSAkY29sb3JzIEFycmF5IG9mIGRlZmF1bHQgcGVyY2VudCBjb2xvciBjb2RlIHN0cmluZ3Mga2V5ZWQgYnkgdGhlIGNvbG9yIGNvbnRleHRzLgoJICogQHJldHVybiBhcnJheSBBcnJheSBjb250YWluaW5nIDItZWxlbWVudCBhcnJheXMga2V5ZWQgdG8gdGhlIGlucHV0ICRjb2xvcnMgYXJyYXkuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbG9ycyggJGFzc29jX2FyZ3MsICRjb2xvcnMgKSB7CgkJJGNvbG9yX3Jlc2V0ID0gV1BfQ0xJOjpjb2xvcml6ZSggJyVuJyApOwoKCQkkY29sb3JfY29kZV9jYWxsYmFjayA9IHN0YXRpYyBmdW5jdGlvbiAoICR2ICkgewoJCQlyZXR1cm4gc3Vic3RyKCAkdiwgMSApOwoJCX07CgoJCSRjb2xvcl9jb2RlcyA9IGFycmF5X2tleXMoIENvbG9yczo6Z2V0Q29sb3JzKCkgKTsKCQkkY29sb3JfY29kZXMgPSBhcnJheV9tYXAoICRjb2xvcl9jb2RlX2NhbGxiYWNrLCAkY29sb3JfY29kZXMgKTsKCQkkY29sb3JfY29kZXMgPSBpbXBsb2RlKCAnJywgJGNvbG9yX2NvZGVzICk7CgoJCSRjb2xvcl9jb2Rlc19yZWdleCA9ICcvXig/OiVbJyAuICRjb2xvcl9jb2RlcyAuICddKSokLyc7CgoJCWZvcmVhY2ggKCBhcnJheV9rZXlzKCAkY29sb3JzICkgYXMgJGNvbG9yX2NvbCApIHsKCQkJJGNvbF9jb2xvcl9mbGFnID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAkY29sb3JfY29sIC4gJ19jb2xvcicgKTsKCQkJaWYgKCBudWxsICE9PSAkY29sX2NvbG9yX2ZsYWcgKSB7CgkJCQlpZiAoICEgcHJlZ19tYXRjaCggJGNvbG9yX2NvZGVzX3JlZ2V4LCAkY29sX2NvbG9yX2ZsYWcsICRtYXRjaGVzICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVW5yZWNvZ25pemVkIHBlcmNlbnQgY29sb3IgY29kZSAnJGNvbF9jb2xvcl9mbGFnJyBmb3IgJ3skY29sb3JfY29sfV9jb2xvcicuIiApOwoJCQkJfSBlbHNlIHsKCQkJCQkkY29sb3JzWyAkY29sb3JfY29sIF0gPSAkbWF0Y2hlc1swXTsKCQkJCX0KCQkJfQoJCQkkY29sb3JzWyAkY29sb3JfY29sIF0gPSAkY29sb3JzWyAkY29sb3JfY29sIF0gPyBhcnJheSggV1BfQ0xJOjpjb2xvcml6ZSggJGNvbG9yc1sgJGNvbG9yX2NvbCBdICksICRjb2xvcl9yZXNldCApIDogYXJyYXkoICcnLCAnJyApOwoJCX0KCgkJcmV0dXJuICRjb2xvcnM7Cgl9CgoJLyoKCSAqIExvZ3MgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBvbGQgbWF0Y2ggYW5kIG5ldyByZXBsYWNlbWVudCBmb3IgU1FMIHJlcGxhY2VtZW50LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbCBDb2x1bW4gYmVpbmcgcHJvY2Vzc2VkLgoJICogQHBhcmFtIGFycmF5ICRwcmltYXJ5X2tleXMgUHJpbWFyeSBrZXlzIGZvciB0YWJsZS4KCSAqIEBwYXJhbSBzdHJpbmcgJHRhYmxlIFRhYmxlIGJlaW5nIHByb2Nlc3NlZC4KCSAqIEBwYXJhbSBzdHJpbmcgJG9sZCBPbGQgdmFsdWUgdG8gbWF0Y2guCgkgKiBAcGFyYW0gc3RyaW5nICRuZXcgTmV3IHZhbHVlIHRvIHJlcGxhY2UgdGhlIG9sZCB2YWx1ZSB3aXRoLgoJICogQHJldHVybiBpbnQgQ291bnQgb2YgY2hhbmdlZCByb3dzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGxvZ19zcWxfZGlmZiggJGNvbCwgJHByaW1hcnlfa2V5cywgJHRhYmxlLCAkb2xkLCAkbmV3ICkgewoJCWdsb2JhbCAkd3BkYjsKCQlpZiAoICRwcmltYXJ5X2tleXMgKSB7CgkJCSRlc2NfcHJpbWFyeV9rZXlzID0gaW1wbG9kZSggJywgJywgc2VsZjo6ZXNjX3NxbF9pZGVudCggJHByaW1hcnlfa2V5cyApICk7CgkJCSRwcmltYXJ5X2tleXNfc3FsID0gY291bnQoICRwcmltYXJ5X2tleXMgKSA+IDEgPyAiQ09OQ0FUX1dTKCcsJywgeyRlc2NfcHJpbWFyeV9rZXlzfSksICIgOiAieyRlc2NfcHJpbWFyeV9rZXlzfSwgIjsKCQl9IGVsc2UgewoJCQkkcHJpbWFyeV9rZXlzX3NxbCA9ICcnOwoJCX0KCgkJJHRhYmxlX3NxbCA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICR0YWJsZSApOwoJCSRjb2xfc3FsICAgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkY29sICk7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggJHdwZGItPnByZXBhcmUoICJTRUxFQ1QgeyRwcmltYXJ5X2tleXNfc3FsfXskY29sX3NxbH0gRlJPTSB7JHRhYmxlX3NxbH0gV0hFUkUgeyRjb2xfc3FsfSBMSUtFIEJJTkFSWSAlcyIsICclJyAuIHNlbGY6OmVzY19saWtlKCAkb2xkICkgLiAnJScgKSwgQVJSQVlfTiApOwoKCQlpZiAoIGVtcHR5KCAkcmVzdWx0cyApICkgewoJCQlyZXR1cm4gMDsKCQl9CgoJCSRzZWFyY2hfcmVnZXggPSAnLycgLiBwcmVnX3F1b3RlKCAkb2xkLCAnLycgKSAuICcvJzsKCgkJZm9yZWFjaCAoICRyZXN1bHRzIGFzICRyZXN1bHQgKSB7CgkJCWxpc3QoICRrZXlzLCAkZGF0YSApID0gJHByaW1hcnlfa2V5cyA/IGFycmF5KCAkcmVzdWx0WzBdLCAkcmVzdWx0WzFdICkgOiBhcnJheSggbnVsbCwgJHJlc3VsdFswXSApOwoJCQlpZiAoIHByZWdfbWF0Y2hfYWxsKCAkc2VhcmNoX3JlZ2V4LCAkZGF0YSwgJG1hdGNoZXMsIFBSRUdfT0ZGU0VUX0NBUFRVUkUgKSApIHsKCQkJCWxpc3QoICRvbGRfYml0cywgJG5ld19iaXRzICkgPSAkdGhpcy0+bG9nX2JpdHMoICRzZWFyY2hfcmVnZXgsICRkYXRhLCAkbWF0Y2hlcywgJG5ldyApOwoJCQkJJHRoaXMtPmxvZ193cml0ZSggJGNvbCwgJGtleXMsICR0YWJsZSwgJG9sZF9iaXRzLCAkbmV3X2JpdHMgKTsKCQkJfQoJCX0KCQlyZXR1cm4gY291bnQoICRyZXN1bHRzICk7Cgl9CgoJLyoKCSAqIExvZ3MgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBvbGQgbWF0Y2hlcyBhbmQgbmV3IHJlcGxhY2VtZW50cyBhdCB0aGUgZW5kIG9mIGEgUEhQIChyZWdleCkgcmVwbGFjZW1lbnQgb2YgYSBkYXRhYmFzZSByb3cuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29sIENvbHVtbiBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gYXJyYXkgJGtleXMgQXNzb2NpYXRpdmUgYXJyYXkgKG9yIG9iamVjdCkgb2YgcHJpbWFyeSBrZXkgbmFtZXMgYW5kIHRoZWlyIHZhbHVlcyBmb3IgdGhlIHJvdyBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gc3RyaW5nICR0YWJsZSBUYWJsZSBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gc3RyaW5nICRvbGQgT2xkIHZhbHVlIHRvIG1hdGNoLgoJICogQHBhcmFtIHN0cmluZyAkbmV3IE5ldyB2YWx1ZSB0byByZXBsYWNlIHRoZSBvbGQgdmFsdWUgd2l0aC4KCSAqIEBwYXJhbSBhcnJheSAkbG9nX2RhdGEgQXJyYXkgb2YgZGF0YSBzdHJpbmdzIGJlZm9yZSByZXBsYWNlbWVudHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gbG9nX3BocF9kaWZmKCAkY29sLCAka2V5cywgJHRhYmxlLCAkb2xkLCAkbmV3LCAkbG9nX2RhdGEgKSB7CgkJaWYgKCAkdGhpcy0+cmVnZXggKSB7CgkJCSRzZWFyY2hfcmVnZXggPSAkdGhpcy0+cmVnZXhfZGVsaW1pdGVyIC4gJG9sZCAuICR0aGlzLT5yZWdleF9kZWxpbWl0ZXIgLiAkdGhpcy0+cmVnZXhfZmxhZ3M7CgkJfSBlbHNlIHsKCQkJJHNlYXJjaF9yZWdleCA9ICcvJyAuIHByZWdfcXVvdGUoICRvbGQsICcvJyApIC4gJy8nOwoJCX0KCgkJJG9sZF9iaXRzID0gYXJyYXkoKTsKCQkkbmV3X2JpdHMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkbG9nX2RhdGEgYXMgJGRhdGEgKSB7CgkJCWlmICggcHJlZ19tYXRjaF9hbGwoICRzZWFyY2hfcmVnZXgsICRkYXRhLCAkbWF0Y2hlcywgUFJFR19PRkZTRVRfQ0FQVFVSRSApICkgewoJCQkJJGJpdHMgICAgID0gJHRoaXMtPmxvZ19iaXRzKCAkc2VhcmNoX3JlZ2V4LCAkZGF0YSwgJG1hdGNoZXMsICRuZXcgKTsKCQkJCSRvbGRfYml0cyA9IGFycmF5X21lcmdlKCAkb2xkX2JpdHMsICRiaXRzWzBdICk7CgkJCQkkbmV3X2JpdHMgPSBhcnJheV9tZXJnZSggJG5ld19iaXRzLCAkYml0c1sxXSApOwoJCQl9CgkJfQoJCWlmICggJG9sZF9iaXRzICkgewoJCQkkdGhpcy0+bG9nX3dyaXRlKCAkY29sLCAka2V5cywgJHRhYmxlLCAkb2xkX2JpdHMsICRuZXdfYml0cyApOwoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGFycmF5cyBvZiBvbGQgbWF0Y2hlcyBhbmQgbmV3IHJlcGxhY2VtZW50cyBiYXNlZCBvbiB0aGUgcGFzc2VkLWluIG1hdGNoZXMsIHdpdGggY29udGV4dC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzZWFyY2hfcmVnZXggVGhlIHNlYXJjaCByZWd1bGFyIGV4cHJlc3Npb24uCgkgKiBAcGFyYW0gc3RyaW5nICRvbGRfZGF0YSBFeGlzdGluZyBkYXRhIGJlaW5nIHByb2Nlc3NlZC4KCSAqIEBwYXJhbSBhcnJheSAkb2xkX21hdGNoZXMgT2xkIG1hdGNoZXMgYXJyYXkgcmV0dXJuZWQgYnkgYHByZWdfbWF0Y2hfYWxsKClgLgoJICogQHBhcmFtIHN0cmluZyAkbmV3IE5ldyB2YWx1ZSB0byByZXBsYWNlIHRoZSBvbGQgdmFsdWUgd2l0aC4KCSAqIEByZXR1cm4gYXJyYXkgVHdvIGVsZW1lbnQgYXJyYXkgY29udGFpbmluZyB0aGUgYXJyYXkgb2Ygb2xkIG1hdGNoIGxvZyBzdHJpbmdzIGFuZCB0aGUgYXJyYXkgb2YgbmV3IHJlcGxhY2VtZW50IGxvZyBzdHJpbmdzIHdpdGggYmVmb3JlL2FmdGVyIGNvbnRleHRzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGxvZ19iaXRzKCAkc2VhcmNoX3JlZ2V4LCAkb2xkX2RhdGEsICRvbGRfbWF0Y2hlcywgJG5ldyApIHsKCQkkZW5jb2RpbmcgPSAkdGhpcy0+bG9nX2VuY29kaW5nOwoJCWlmICggISAkZW5jb2RpbmcgJiYgKCAkdGhpcy0+bG9nX2JlZm9yZV9jb250ZXh0IHx8ICR0aGlzLT5sb2dfYWZ0ZXJfY29udGV4dCApICYmIGZ1bmN0aW9uX2V4aXN0cyggJ21iX2RldGVjdF9lbmNvZGluZycgKSApIHsKCQkJJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCAkb2xkX2RhdGEsIG51bGwsIHRydWUgLypzdHJpY3QqLyApOwoJCX0KCgkJLy8gR2VuZXJhdGUgYSBuZXcgZGF0YSBtYXRjaGVzIGFuYWxvZyBvZiB0aGUgb2xkIGRhdGEgbWF0Y2hlcyBieSBzaW11bGF0aW5nIGEgYHByZWdfcmVwbGFjZSgpYC4KCQkkaXNfcmVnZXggICAgPSAkdGhpcy0+cmVnZXg7CgkJJGkgICAgICAgICAgID0gMDsKCQkkZGlmZiAgICAgICAgPSAwOwoJCSRuZXdfbWF0Y2hlcyA9IGFycmF5KCk7CgkJJG5ld19kYXRhICAgID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAoJCQkkc2VhcmNoX3JlZ2V4LAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkbWF0Y2hlcyApIHVzZSAoICRvbGRfbWF0Y2hlcywgJG5ldywgJGlzX3JlZ2V4LCAmJG5ld19tYXRjaGVzLCAmJGksICYkZGlmZiApIHsKCQkJCWlmICggJGlzX3JlZ2V4ICkgewoJCQkJCS8vIFN1YiBpbiBhbnkgYmFjayByZWZlcmVuY2VzLCAiJDEiLCAiXDIiIGV0YywgaW4gdGhlIHJlcGxhY2VtZW50IHN0cmluZy4KCQkJCQkkbmV3ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAoJCQkJCQknLyg/PCFcXFxcKSg/OlxcXFxcXFxcKSooKD86XFxcXHxcXCQpWzAtOV17MSwyfXxcXCR7WzAtOV17MSwyfVxcfSkvJywKCQkJCQkJc3RhdGljIGZ1bmN0aW9uICggJG0gKSB1c2UgKCAkbWF0Y2hlcyApIHsKCQkJCQkJCSRpZHggPSAoaW50KSBzdHJfcmVwbGFjZSggYXJyYXkoICdcXCcsICckJywgJ3snLCAnfScgKSwgJycsICRtWzBdICk7CgkJCQkJCQlyZXR1cm4gaXNzZXQoICRtYXRjaGVzWyAkaWR4IF0gKSA/ICRtYXRjaGVzWyAkaWR4IF0gOiAnJzsKCQkJCQkJfSwKCQkJCQkJJG5ldwoJCQkJCSk7CgkJCQkJJG5ldyA9IHN0cl9yZXBsYWNlKCAnXFxcXCcsICdcXCcsICRuZXcgKTsgLy8gVW5lc2NhcGUgYW55IGJhY2tzbGFzaGVkIGJhY2tzbGFzaGVzLgoJCQkJfQoKCQkJCSRuZXdfbWF0Y2hlc1swXVsgJGkgXVswXSA9ICRuZXc7CgkJCQkkbmV3X21hdGNoZXNbMF1bICRpIF1bMV0gPSAkb2xkX21hdGNoZXNbMF1bICRpIF1bMV0gKyAkZGlmZjsKCgkJCQkkZGlmZiArPSBzdHJsZW4oICRuZXcgKSAtIHN0cmxlbiggJG9sZF9tYXRjaGVzWzBdWyAkaSBdWzBdICk7CgkJCQkkaSsrOwoJCQkJcmV0dXJuICRuZXc7CgkJCX0sCgkJCSRvbGRfZGF0YSwKCQkJJHRoaXMtPnJlZ2V4X2xpbWl0LAoJCQkkbWF0Y2hfY250CgkJKTsKCgkJJG9sZF9iaXRzICAgICAgICA9IGFycmF5KCk7CgkJJG5ld19iaXRzICAgICAgICA9IGFycmF5KCk7CgkJJGFwcGVuZF9uZXh0ICAgICA9IGZhbHNlOwoJCSRsYXN0X29sZF9vZmZzZXQgPSAwOwoJCSRsYXN0X25ld19vZmZzZXQgPSAwOwoJCWZvciAoICRpID0gMDsgJGkgPCAkbWF0Y2hfY250OyAkaSsrICkgewoJCQkkb2xkX21hdGNoICA9ICRvbGRfbWF0Y2hlc1swXVsgJGkgXVswXTsKCQkJJG9sZF9vZmZzZXQgPSAkb2xkX21hdGNoZXNbMF1bICRpIF1bMV07CgkJCSRuZXdfbWF0Y2ggID0gJG5ld19tYXRjaGVzWzBdWyAkaSBdWzBdOwoJCQkkbmV3X29mZnNldCA9ICRuZXdfbWF0Y2hlc1swXVsgJGkgXVsxXTsKCgkJCSRvbGRfbG9nID0gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ19vbGQnXVswXSAuICRvbGRfbWF0Y2ggLiAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX29sZCddWzFdOwoJCQkkbmV3X2xvZyA9ICR0aGlzLT5sb2dfY29sb3JzWydsb2dfbmV3J11bMF0gLiAkbmV3X21hdGNoIC4gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ19uZXcnXVsxXTsKCgkJCSRvbGRfYmVmb3JlICAgICAgPSAnJzsKCQkJJG9sZF9hZnRlciAgICAgICA9ICcnOwoJCQkkbmV3X2JlZm9yZSAgICAgID0gJyc7CgkJCSRuZXdfYWZ0ZXIgICAgICAgPSAnJzsKCQkJJGFmdGVyX3Nob3J0ZW5lZCA9IGZhbHNlOwoKCQkJLy8gT2Zmc2V0cyBhcmUgaW4gYnl0ZXMsIHNvIG5lZWQgdG8gdXNlIGBzdHJsZW4oKWAgYW5kIGBzdWJzdHIoKWAgYmVmb3JlIHVzaW5nIGBzYWZlX3N1YnN0cigpYC4KCQkJaWYgKCAkdGhpcy0+bG9nX2JlZm9yZV9jb250ZXh0ICYmICRvbGRfb2Zmc2V0ICYmICEgJGFwcGVuZF9uZXh0ICkgewoJCQkJJG9sZF9iZWZvcmUgPSBzYWZlX3N1YnN0ciggc3Vic3RyKCAkb2xkX2RhdGEsICRsYXN0X29sZF9vZmZzZXQsICRvbGRfb2Zmc2V0IC0gJGxhc3Rfb2xkX29mZnNldCApLCAtJHRoaXMtPmxvZ19iZWZvcmVfY29udGV4dCwgbnVsbCAvKmxlbmd0aCovLCBmYWxzZSAvKmlzX3dpZHRoKi8sICRlbmNvZGluZyApOwoJCQkJJG5ld19iZWZvcmUgPSBzYWZlX3N1YnN0ciggc3Vic3RyKCAkbmV3X2RhdGEsICRsYXN0X25ld19vZmZzZXQsICRuZXdfb2Zmc2V0IC0gJGxhc3RfbmV3X29mZnNldCApLCAtJHRoaXMtPmxvZ19iZWZvcmVfY29udGV4dCwgbnVsbCAvKmxlbmd0aCovLCBmYWxzZSAvKmlzX3dpZHRoKi8sICRlbmNvZGluZyApOwoJCQl9CgkJCWlmICggJHRoaXMtPmxvZ19hZnRlcl9jb250ZXh0ICkgewoJCQkJJG9sZF9lbmRfb2Zmc2V0ID0gJG9sZF9vZmZzZXQgKyBzdHJsZW4oICRvbGRfbWF0Y2ggKTsKCQkJCSRuZXdfZW5kX29mZnNldCA9ICRuZXdfb2Zmc2V0ICsgc3RybGVuKCAkbmV3X21hdGNoICk7CgkJCQkkb2xkX2FmdGVyICAgICAgPSBzYWZlX3N1YnN0ciggc3Vic3RyKCAkb2xkX2RhdGEsICRvbGRfZW5kX29mZnNldCApLCAwLCAkdGhpcy0+bG9nX2FmdGVyX2NvbnRleHQsIGZhbHNlIC8qaXNfd2lkdGgqLywgJGVuY29kaW5nICk7CgkJCQkkbmV3X2FmdGVyICAgICAgPSBzYWZlX3N1YnN0ciggc3Vic3RyKCAkbmV3X2RhdGEsICRuZXdfZW5kX29mZnNldCApLCAwLCAkdGhpcy0+bG9nX2FmdGVyX2NvbnRleHQsIGZhbHNlIC8qaXNfd2lkdGgqLywgJGVuY29kaW5nICk7CgkJCQkvLyBUbyBsZXNzZW4gY29udGV4dCBkdXBsaWNhdGlvbiBpbiBvdXRwdXQsIHNob3J0ZW4gdGhlIGFmdGVyIGNvbnRleHQgaWYgaXQgb3ZlcmxhcHMgd2l0aCB0aGUgbmV4dCBtYXRjaC4KCQkJCWlmICggJGkgKyAxIDwgJG1hdGNoX2NudCAmJiAkb2xkX2VuZF9vZmZzZXQgKyBzdHJsZW4oICRvbGRfYWZ0ZXIgKSA+ICRvbGRfbWF0Y2hlc1swXVsgJGkgKyAxIF1bMV0gKSB7CgkJCQkJJG9sZF9hZnRlciAgICAgICA9IHN1YnN0ciggJG9sZF9hZnRlciwgMCwgJG9sZF9tYXRjaGVzWzBdWyAkaSArIDEgXVsxXSAtICRvbGRfZW5kX29mZnNldCApOwoJCQkJCSRuZXdfYWZ0ZXIgICAgICAgPSBzdWJzdHIoICRuZXdfYWZ0ZXIsIDAsICRuZXdfbWF0Y2hlc1swXVsgJGkgKyAxIF1bMV0gLSAkbmV3X2VuZF9vZmZzZXQgKTsKCQkJCQkkYWZ0ZXJfc2hvcnRlbmVkID0gdHJ1ZTsKCQkJCQkvLyBPbiB0aGUgbmV4dCBpdGVyYXRpb24sIHdpbGwgYXBwZW5kIHdpdGggbm8gYmVmb3JlIGNvbnRleHQuCgkJCQl9CgkJCX0KCgkJCWlmICggJGFwcGVuZF9uZXh0ICkgewoJCQkJJGNudCAgICAgICAgICAgICAgICAgICA9IGNvdW50KCAkb2xkX2JpdHMgKTsKCQkJCSRvbGRfYml0c1sgJGNudCAtIDEgXSAuPSAkb2xkX2xvZyAuICRvbGRfYWZ0ZXI7CgkJCQkkbmV3X2JpdHNbICRjbnQgLSAxIF0gLj0gJG5ld19sb2cgLiAkbmV3X2FmdGVyOwoJCQl9IGVsc2UgewoJCQkJJG9sZF9iaXRzW10gPSAkb2xkX2JlZm9yZSAuICRvbGRfbG9nIC4gJG9sZF9hZnRlcjsKCQkJCSRuZXdfYml0c1tdID0gJG5ld19iZWZvcmUgLiAkbmV3X2xvZyAuICRuZXdfYWZ0ZXI7CgkJCX0KCQkJJGFwcGVuZF9uZXh0ICAgICA9ICRhZnRlcl9zaG9ydGVuZWQ7CgkJCSRsYXN0X29sZF9vZmZzZXQgPSAkb2xkX29mZnNldDsKCQkJJGxhc3RfbmV3X29mZnNldCA9ICRuZXdfb2Zmc2V0OwoJCX0KCgkJcmV0dXJuIGFycmF5KCAkb2xkX2JpdHMsICRuZXdfYml0cyApOwoJfQoKCS8qCgkgKiBPdXRwdXRzIHRoZSBsb2cgc3RyaW5ncy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb2wgQ29sdW1uIGJlaW5nIHByb2Nlc3NlZC4KCSAqIEBwYXJhbSBhcnJheSAka2V5cyBBc3NvY2lhdGl2ZSBhcnJheSAob3Igb2JqZWN0KSBvZiBwcmltYXJ5IGtleSBuYW1lcyBhbmQgdGhlaXIgdmFsdWVzIGZvciB0aGUgcm93IGJlaW5nIHByb2Nlc3NlZC4KCSAqIEBwYXJhbSBzdHJpbmcgJHRhYmxlIFRhYmxlIGJlaW5nIHByb2Nlc3NlZC4KCSAqIEBwYXJhbSBhcnJheSAkb2xkX2JpdHMgQXJyYXkgb2Ygb2xkIG1hdGNoIGxvZyBzdHJpbmdzLgoJICogQHBhcmFtIGFycmF5ICRuZXdfYml0cyBBcnJheSBvZiBuZXcgcmVwbGFjZW1lbnQgbG9nIHN0cmluZ3MuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gbG9nX3dyaXRlKCAkY29sLCAka2V5cywgJHRhYmxlLCAkb2xkX2JpdHMsICRuZXdfYml0cyApIHsKCQkkaWRfbG9nICAgICAgICAgICAgICA9ICRrZXlzID8gKCAnOicgLiBpbXBsb2RlKCAnLCcsIChhcnJheSkgJGtleXMgKSApIDogJyc7CgkJJHRhYmxlX2NvbHVtbl9pZF9sb2cgPSAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX3RhYmxlX2NvbHVtbl9pZCddWzBdIC4gJHRhYmxlIC4gJy4nIC4gJGNvbCAuICRpZF9sb2cgLiAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX3RhYmxlX2NvbHVtbl9pZCddWzFdOwoKCQkkb2xkX2xvZyA9IHN0cl9yZXBsYWNlKCBhcnJheSggIlxyXG4iLCAiXG4iICksICcgJywgaW1wbG9kZSggJyBbLi4uXSAnLCAkb2xkX2JpdHMgKSApOwoJCSRuZXdfbG9nID0gc3RyX3JlcGxhY2UoIGFycmF5KCAiXHJcbiIsICJcbiIgKSwgJyAnLCBpbXBsb2RlKCAnIFsuLi5dICcsICRuZXdfYml0cyApICk7CgoJCWlmICggJHRoaXMtPmxvZ19wcmVmaXhlc1swXSApIHsKCQkJJG9sZF9sb2cgPSAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX29sZCddWzBdIC4gJHRoaXMtPmxvZ19wcmVmaXhlc1swXSAuICR0aGlzLT5sb2dfY29sb3JzWydsb2dfb2xkJ11bMV0gLiAkb2xkX2xvZzsKCQl9CgkJaWYgKCAkdGhpcy0+bG9nX3ByZWZpeGVzWzFdICkgewoJCQkkbmV3X2xvZyA9ICR0aGlzLT5sb2dfY29sb3JzWydsb2dfbmV3J11bMF0gLiAkdGhpcy0+bG9nX3ByZWZpeGVzWzFdIC4gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ19uZXcnXVsxXSAuICRuZXdfbG9nOwoJCX0KCgkJZndyaXRlKCAkdGhpcy0+bG9nX2hhbmRsZSwgInskdGFibGVfY29sdW1uX2lkX2xvZ31cbnskb2xkX2xvZ31cbnskbmV3X2xvZ31cbiIgKTsKCX0KCn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9zZWFyY2hfcmVwbGFjZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9zZWFyY2hfcmVwbGFjZV9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX3NlYXJjaF9yZXBsYWNlX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdzZWFyY2gtcmVwbGFjZScsICdTZWFyY2hfUmVwbGFjZV9Db21tYW5kJyApOwo8P3BocAoKLyoKICogV1BfQ0xJOiBDb3BpZWQgYW5kIGFkYXB0ZWQgZnJvbSB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0pzb24vSnNvbk1hbmlwdWxhdG9yLnBocC4gQ2hhbmdlcyBtYXJrZWQgYFdQX0NMSWAuCiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgV1BfQ0xJOyAvLyBXUF9DTEkKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOyAvLyBXUF9DTEkKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5OwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEpzb25NYW5pcHVsYXRvcgp7CiAgICBwcml2YXRlIHN0YXRpYyAkREVGSU5FUyA9ICcoPyhERUZJTkUpCiAgICAgICAoPzxudW1iZXI+ICAgLT8gKD89IFsxLTldfDAoPyFcZCkgKSBcZCsgKFwuXGQrKT8gKFtlRV0gWystXT8gXGQrKT8gKQogICAgICAgKD88Ym9vbGVhbj4gICB0cnVlIHwgZmFsc2UgfCBudWxsICkKICAgICAgICg/PHN0cmluZz4gICAgIiAoW14iXFxcXF0qIHwgXFxcXCBbIlxcXFxiZm5ydFwvXSB8IFxcXFwgdSBbMC05YS1mXXs0fSApKiAiICkKICAgICAgICg/PGFycmF5PiAgICAgXFsgICg/OiAgKD8manNvbikgXHMqICg/OiAsICg/Jmpzb24pIFxzKiApKiAgKT8gIFxzKiBcXSApCiAgICAgICAoPzxwYWlyPiAgICAgIFxzKiAoPyZzdHJpbmcpIFxzKiA6ICg/Jmpzb24pIFxzKiApCiAgICAgICAoPzxvYmplY3Q+ICAgIFx7ICAoPzogICg/JnBhaXIpICAoPzogLCAoPyZwYWlyKSAgKSogICk/ICBccyogXH0gKQogICAgICAgKD88anNvbj4gICBccyogKD86ICg/Jm51bWJlcikgfCAoPyZib29sZWFuKSB8ICg/JnN0cmluZykgfCAoPyZhcnJheSkgfCAoPyZvYmplY3QpICkgKQogICAgKSc7CgogICAgcHJpdmF0ZSAkY29udGVudHM7CiAgICBwcml2YXRlICRuZXdsaW5lOwogICAgcHJpdmF0ZSAkaW5kZW50OwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29udGVudHMpCiAgICB7CiAgICAgICAgJGNvbnRlbnRzID0gdHJpbSgkY29udGVudHMpOwogICAgICAgIGlmICgkY29udGVudHMgPT09ICcnKSB7CiAgICAgICAgICAgICRjb250ZW50cyA9ICd7fSc7CiAgICAgICAgfQogICAgICAgIGlmICghJHRoaXMtPnByZWdNYXRjaCgnI15ceyguKilcfSQjcycsICRjb250ZW50cykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBqc29uIGZpbGUgbXVzdCBiZSBhbiBvYmplY3QgKHt9KScpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+bmV3bGluZSA9IGZhbHNlICE9PSBzdHJwb3MoJGNvbnRlbnRzLCAiXHJcbiIpID8gIlxyXG4iIDogIlxuIjsKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkY29udGVudHMgPT09ICd7fScgPyAneycgLiAkdGhpcy0+bmV3bGluZSAuICd9JyA6ICRjb250ZW50czsKICAgICAgICAkdGhpcy0+ZGV0ZWN0SW5kZW50aW5nKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRlbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRlbnRzIC4gJHRoaXMtPm5ld2xpbmU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZExpbmsoJHR5cGUsICRwYWNrYWdlLCAkY29uc3RyYWludCwgJHNvcnRQYWNrYWdlcyA9IGZhbHNlLCAkY2FzZUluc2Vuc2l0aXZlID0gZmFsc2UpIC8vIFdQX0NMSTogY2FzZUluc2Vuc2l0aXZlLgogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAvLyBubyBsaW5rIG9mIHRoYXQgdHlwZSB5ZXQKICAgICAgICBpZiAoIWlzc2V0KCRkZWNvZGVkWyR0eXBlXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRNYWluS2V5KCR0eXBlLCBhcnJheSgkcGFja2FnZSA9PiAkY29uc3RyYWludCkpOwogICAgICAgIH0KCiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PlxzKlx7XHMqKD86KD8mc3RyaW5nKVxzKjpccyooPyZqc29uKVxzKixccyopKj8pJy4KICAgICAgICAgICAgJyg/UDxwcm9wZXJ0eT4nLnByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkdHlwZSkpLidccyo6XHMqKSg/UDx2YWx1ZT4oPyZqc29uKSkoP1A8ZW5kPi4qKX1zeCc7CiAgICAgICAgaWYgKCEkdGhpcy0+cHJlZ01hdGNoKCRyZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCgkJLy8gV1BfQ0xJOiBiZWdpbiBjYXNlSW5zZW5zaXRpdmUuCgkJaWYgKCRjYXNlSW5zZW5zaXRpdmUpIHsKCQkJLy8gSnVzdCB6YXAgYW55IGV4aXN0aW5nIHBhY2thZ2VzIGZpcnN0IGluIGEgY2FzZSBpbnNlbnNpdGl2ZSBtYW5uZXIuCgkJCSR0aGlzLT5yZW1vdmVTdWJOb2RlKCR0eXBlLCAkcGFja2FnZSwgJGNhc2VJbnNlbnNpdGl2ZSk7CgkJCXJldHVybiAkdGhpcy0+YWRkTGluaygkdHlwZSwgJHBhY2thZ2UsICRjb25zdHJhaW50LCAkc29ydFBhY2thZ2VzKTsKCQl9CgkJLy8gV1BfQ0xJOiBlbmQgY2FzZUluc2Vuc2l0aXZlLgoKICAgICAgICAkbGlua3MgPSAkbWF0Y2hlc1sndmFsdWUnXTsKCiAgICAgICAgLy8gdHJ5IHRvIGZpbmQgZXhpc3RpbmcgbGluawogICAgICAgICRwYWNrYWdlUmVnZXggPSBzdHJfcmVwbGFjZSgnLycsICdcXFxcPy8nLCBwcmVnX3F1b3RlKCRwYWNrYWdlKSk7CiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLiciKD9QPHBhY2thZ2U+Jy4kcGFja2FnZVJlZ2V4LicpIihccyo6XHMqKSg/JnN0cmluZyl9aXgnOwogICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCRyZWdleCwgJGxpbmtzLCAkcGFja2FnZU1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBleGlzdGluZyBsaW5rCiAgICAgICAgICAgICRleGlzdGluZ1BhY2thZ2UgPSAkcGFja2FnZU1hdGNoZXNbJ3BhY2thZ2UnXTsKICAgICAgICAgICAgJHBhY2thZ2VSZWdleCA9IHN0cl9yZXBsYWNlKCcvJywgJ1xcXFw/LycsIHByZWdfcXVvdGUoJGV4aXN0aW5nUGFja2FnZSkpOwogICAgICAgICAgICAkbGlua3MgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJ3snLnNlbGY6OiRERUZJTkVTLiciJy4kcGFja2FnZVJlZ2V4LiciKD9QPHNlcGFyYXRvcj5ccyo6XHMqKSg/JnN0cmluZyl9aXgnLCBmdW5jdGlvbiAoJG0pIHVzZSAoJGV4aXN0aW5nUGFja2FnZSwgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBKc29uRmlsZTo6ZW5jb2RlKHN0cl9yZXBsYWNlKCdcXC8nLCAnLycsICRleGlzdGluZ1BhY2thZ2UpKSAuICRtWydzZXBhcmF0b3InXSAuICciJyAuICRjb25zdHJhaW50IC4gJyInOwogICAgICAgICAgICB9LCAkbGlua3MpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCcjXlxzKlx7XHMqXFMrLio/KFxzKlx9XHMqKSQjcycsICRsaW5rcywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgLy8gbGluayBtaXNzaW5nIGJ1dCBub24gZW1wdHkgbGlua3MKICAgICAgICAgICAgICAgICRsaW5rcyA9IHByZWdfcmVwbGFjZSgKICAgICAgICAgICAgICAgICAgICAneycucHJlZ19xdW90ZSgkbWF0Y2hbMV0pLickfScsCiAgICAgICAgICAgICAgICAgICAgLy8gYWRkY3NsYXNoZXMgaXMgdXNlZCB0byBkb3VibGUgdXAgYmFja3NsYXNoZXMvJCBzaW5jZSBwcmVnX3JlcGxhY2UgcmVzb2x2ZXMgdGhlbSBhcyBiYWNrIHJlZmVyZW5jZXMgb3RoZXJ3aXNlLCBzZWUgIzE1ODgKICAgICAgICAgICAgICAgICAgICBhZGRjc2xhc2hlcygnLCcgLiAkdGhpcy0+bmV3bGluZSAuICR0aGlzLT5pbmRlbnQgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgkcGFja2FnZSkuJzogJy5Kc29uRmlsZTo6ZW5jb2RlKCRjb25zdHJhaW50KSAuICRtYXRjaFsxXSwgJ1xcJCcpLAogICAgICAgICAgICAgICAgICAgICRsaW5rcwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGxpbmtzIGVtcHR5CiAgICAgICAgICAgICAgICAkbGlua3MgPSAneycgLiAkdGhpcy0+bmV3bGluZSAuCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGVudCAuICR0aGlzLT5pbmRlbnQgLiBKc29uRmlsZTo6ZW5jb2RlKCRwYWNrYWdlKS4nOiAnLkpzb25GaWxlOjplbmNvZGUoJGNvbnN0cmFpbnQpIC4gJHRoaXMtPm5ld2xpbmUgLgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRlbnQgLiAnfSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICh0cnVlID09PSAkc29ydFBhY2thZ2VzKSB7CiAgICAgICAgICAgICRyZXF1aXJlbWVudHMgPSBqc29uX2RlY29kZSgkbGlua3MsIHRydWUpOwogICAgICAgICAgICAkdGhpcy0+c29ydFBhY2thZ2VzKCRyZXF1aXJlbWVudHMpOwogICAgICAgICAgICAkbGlua3MgPSAkdGhpcy0+Zm9ybWF0KCRyZXF1aXJlbWVudHMpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gJG1hdGNoZXNbJ3N0YXJ0J10gLiAkbWF0Y2hlc1sncHJvcGVydHknXSAuICRsaW5rcyAuICRtYXRjaGVzWydlbmQnXTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb3J0cyBwYWNrYWdlcyBieSBpbXBvcnRhbmNlIChwbGF0Zm9ybSBwYWNrYWdlcyBmaXJzdCwgdGhlbiBQSFAgZGVwZW5kZW5jaWVzKSBhbmQgYWxwaGFiZXRpY2FsbHkuCiAgICAgKgogICAgICogQGxpbmsgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAyLWxpYnJhcmllcy5tZCNwbGF0Zm9ybS1wYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkcGFja2FnZXMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzb3J0UGFja2FnZXMoYXJyYXkgJiRwYWNrYWdlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHByZWZpeCA9IGZ1bmN0aW9uICgkcmVxdWlyZW1lbnQpIHsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goUGxhdGZvcm1SZXBvc2l0b3J5OjpQTEFURk9STV9QQUNLQUdFX1JFR0VYLCAkcmVxdWlyZW1lbnQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnL15waHAvJywKICAgICAgICAgICAgICAgICAgICAgICAgJy9eaGh2bS8nLAogICAgICAgICAgICAgICAgICAgICAgICAnL15leHQvJywKICAgICAgICAgICAgICAgICAgICAgICAgJy9ebGliLycsCiAgICAgICAgICAgICAgICAgICAgICAgICcvXlxELycsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJzAtJDAnLAogICAgICAgICAgICAgICAgICAgICAgICAnMS0kMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcyLSQwJywKICAgICAgICAgICAgICAgICAgICAgICAgJzMtJDAnLAogICAgICAgICAgICAgICAgICAgICAgICAnNC0kMCcsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZW1lbnQKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAnNS0nLiRyZXF1aXJlbWVudDsKICAgICAgICB9OwoKICAgICAgICB1a3NvcnQoJHBhY2thZ2VzLCBmdW5jdGlvbiAoJGEsICRiKSB1c2UgKCRwcmVmaXgpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cm5hdGNtcCgkcHJlZml4KCRhKSwgJHByZWZpeCgkYikpOwogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZXBvc2l0b3J5KCRuYW1lLCAkY29uZmlnKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgncmVwb3NpdG9yaWVzJywgJG5hbWUsICRjb25maWcpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVSZXBvc2l0b3J5KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgncmVwb3NpdG9yaWVzJywgJG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb25maWdTZXR0aW5nKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRTdWJOb2RlKCdjb25maWcnLCAkbmFtZSwgJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlQ29uZmlnU2V0dGluZygkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbW92ZVN1Yk5vZGUoJ2NvbmZpZycsICRuYW1lKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHJvcGVydHkoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoc3Vic3RyKCRuYW1lLCAwLCA2KSA9PT0gJ2V4dHJhLicpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRTdWJOb2RlKCdleHRyYScsIHN1YnN0cigkbmFtZSwgNiksICR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE1haW5LZXkoJG5hbWUsICR2YWx1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KCRuYW1lKQogICAgewogICAgICAgIGlmIChzdWJzdHIoJG5hbWUsIDAsIDYpID09PSAnZXh0cmEuJykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlbW92ZVN1Yk5vZGUoJ2V4dHJhJywgc3Vic3RyKCRuYW1lLCA2KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbW92ZU1haW5LZXkoJG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTdWJOb2RlKCRtYWluTm9kZSwgJG5hbWUsICR2YWx1ZSwgJGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlKSAvLyBXUF9DTEk6IGNhc2VJbnNlbnNpdGl2ZS4KICAgIHsKICAgICAgICAkZGVjb2RlZCA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgJHN1Yk5hbWUgPSBudWxsOwogICAgICAgIGlmIChpbl9hcnJheSgkbWFpbk5vZGUsIGFycmF5KCdjb25maWcnLCAnZXh0cmEnKSkgJiYgZmFsc2UgIT09IHN0cnBvcygkbmFtZSwgJy4nKSkgewogICAgICAgICAgICBsaXN0KCRuYW1lLCAkc3ViTmFtZSkgPSBleHBsb2RlKCcuJywgJG5hbWUsIDIpOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gbWFpbiBub2RlIHlldAogICAgICAgIGlmICghaXNzZXQoJGRlY29kZWRbJG1haW5Ob2RlXSkpIHsKICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTWFpbktleSgkbWFpbk5vZGUsIGFycmF5KCRuYW1lID0+IGFycmF5KCRzdWJOYW1lID0+ICR2YWx1ZSkpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRNYWluS2V5KCRtYWluTm9kZSwgYXJyYXkoJG5hbWUgPT4gJHZhbHVlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbWFpbiBub2RlIGNvbnRlbnQgbm90IG1hdGNoLWFibGUKICAgICAgICAkbm9kZVJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PiBccyogXHsgXHMqICg/OiAoPyZzdHJpbmcpIFxzKiA6ICg/Jmpzb24pIFxzKiAsIFxzKiApKj8nLgogICAgICAgICAgICBwcmVnX3F1b3RlKEpzb25GaWxlOjplbmNvZGUoJG1haW5Ob2RlKSkuJ1xzKjpccyopKD9QPGNvbnRlbnQ+KD8mb2JqZWN0KSkoP1A8ZW5kPi4qKX1zeCc7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPnByZWdNYXRjaCgkbm9kZVJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpID09PSBQUkVHX0JBQ0tUUkFDS19MSU1JVF9FUlJPUikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCgkJLy8gV1BfQ0xJOiBiZWdpbiBjYXNlSW5zZW5zaXRpdmUuCgkJaWYgKCRjYXNlSW5zZW5zaXRpdmUpIHsKCQkJLy8gSnVzdCB6YXAgYW55IGV4aXN0aW5nIG5hbWVzIGZpcnN0IGluIGEgY2FzZSBpbnNlbnNpdGl2ZSBtYW5uZXIuCgkJCSR0aGlzLT5yZW1vdmVTdWJOb2RlKCRtYWluTm9kZSwgJG5hbWUsICRjYXNlSW5zZW5zaXRpdmUpOwoJCQlyZXR1cm4gJHRoaXMtPmFkZFN1Yk5vZGUoJG1haW5Ob2RlLCAkbmFtZSwgJHZhbHVlKTsKCQl9CgkJLy8gV1BfQ0xJOiBlbmQgY2FzZUluc2Vuc2l0aXZlLgoKICAgICAgICAkY2hpbGRyZW4gPSAkbWF0Y2hbJ2NvbnRlbnQnXTsKICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgkY2hpbGRyZW4pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICR0aGF0ID0gJHRoaXM7CgogICAgICAgIC8vIGNoaWxkIGV4aXN0cwogICAgICAgICRjaGlsZFJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLicoP1A8c3RhcnQ+IicucHJlZ19xdW90ZSgkbmFtZSkuJyJccyo6XHMqKSg/UDxjb250ZW50Pig/Jmpzb24pKSg/UDxlbmQ+LD8pfXgnOwogICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCRjaGlsZFJlZ2V4LCAkY2hpbGRyZW4sICRtYXRjaGVzKSkgewogICAgICAgICAgICAkY2hpbGRyZW4gPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJGNoaWxkUmVnZXgsIGZ1bmN0aW9uICgkbWF0Y2hlcykgdXNlICgkbmFtZSwgJHN1Yk5hbWUsICR2YWx1ZSwgJHRoYXQpIHsKICAgICAgICAgICAgICAgIGlmICgkc3ViTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICRjdXJWYWwgPSBqc29uX2RlY29kZSgkbWF0Y2hlc1snY29udGVudCddLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRjdXJWYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjdXJWYWwgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkY3VyVmFsWyRzdWJOYW1lXSA9ICR2YWx1ZTsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAkY3VyVmFsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkbWF0Y2hlc1snc3RhcnQnXSAuICR0aGF0LT5mb3JtYXQoJHZhbHVlLCAxKSAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICAgICAgfSwgJGNoaWxkcmVuKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cHJlZ01hdGNoKCcjXnsgXHMqPyAoP1A8Y29udGVudD5cUysuKj8pPyAoP1A8dHJhaWxpbmdzcGFjZT5ccyopIH0kI3N4JywgJGNoaWxkcmVuLCAkbWF0Y2gpOwoKICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSAnJzsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbJ3RyYWlsaW5nc3BhY2UnXSkpIHsKICAgICAgICAgICAgICAgICR3aGl0ZXNwYWNlID0gJG1hdGNoWyd0cmFpbGluZ3NwYWNlJ107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoWydjb250ZW50J10pKSB7CiAgICAgICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBhcnJheSgkc3ViTmFtZSA9PiAkdmFsdWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNoaWxkIG1pc3NpbmcgYnV0IG5vbiBlbXB0eSBjaGlsZHJlbgogICAgICAgICAgICAgICAgJGNoaWxkcmVuID0gcHJlZ19yZXBsYWNlKAogICAgICAgICAgICAgICAgICAgICcjJy4kd2hpdGVzcGFjZS4nfSQjJywKICAgICAgICAgICAgICAgICAgICBhZGRjc2xhc2hlcygnLCcgLiAkdGhpcy0+bmV3bGluZSAuICR0aGlzLT5pbmRlbnQgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgkbmFtZSkuJzogJy4kdGhpcy0+Zm9ybWF0KCR2YWx1ZSwgMSkgLiAkd2hpdGVzcGFjZSAuICd9JywgJ1xcJCcpLAogICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgkc3ViTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IGFycmF5KCRzdWJOYW1lID0+ICR2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gY2hpbGRyZW4gcHJlc2VudCBidXQgZW1wdHkKICAgICAgICAgICAgICAgICRjaGlsZHJlbiA9ICd7JyAuICR0aGlzLT5uZXdsaW5lIC4gJHRoaXMtPmluZGVudCAuICR0aGlzLT5pbmRlbnQgLiBKc29uRmlsZTo6ZW5jb2RlKCRuYW1lKS4nOiAnLiR0aGlzLT5mb3JtYXQoJHZhbHVlLCAxKSAuICR3aGl0ZXNwYWNlIC4gJ30nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJG5vZGVSZWdleCwgZnVuY3Rpb24gKCRtKSB1c2UgKCRjaGlsZHJlbikgewogICAgICAgICAgICByZXR1cm4gJG1bJ3N0YXJ0J10gLiAkY2hpbGRyZW4gLiAkbVsnZW5kJ107CiAgICAgICAgfSwgJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVN1Yk5vZGUoJG1haW5Ob2RlLCAkbmFtZSwgJGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlKSAvLyBXUF9DTEk6IGNhc2VJbnNlbnNpdGl2ZS4KICAgIHsKICAgICAgICAkZGVjb2RlZCA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgLy8gbm8gbm9kZSBvciBlbXB0eSBub2RlCiAgICAgICAgaWYgKGVtcHR5KCRkZWNvZGVkWyRtYWluTm9kZV0pKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCgkJLy8gV1BfQ0xJOiBiZWdpbiBjYXNlSW5zZW5zaXRpdmUuCgkJaWYgKCAkY2FzZUluc2Vuc2l0aXZlICkgewoJCQkvLyBUaGlzIGlzIG1vcmUgb3IgbGVzcyBhIGNvcHkgb2YgdGhlIGNvZGUgYXQgdGhlIHN0YXJ0IG9mIGBhZGRMaW5rKClgIGFib3ZlLgoJCQkkcmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+XHMqXHtccyooPzooPyZzdHJpbmcpXHMqOlxzKig/Jmpzb24pXHMqLFxzKikqPyknLgoJCQkJJyg/UDxwcm9wZXJ0eT4nLnByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkbWFpbk5vZGUpKS4nXHMqOlxzKikoP1A8dmFsdWU+KD8manNvbikpKD9QPGVuZD4uKil9c3gnOwoJCQlpZiAoISR0aGlzLT5wcmVnTWF0Y2goJHJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaGVzKSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCSR2YWx1ZSA9ICRtYXRjaGVzWyd2YWx1ZSddOyAvLyBSZW5hbWVkIGZyb20gYCRsaW5rc2AgaW4gYGFkZExpbmsoKWAgY2FzZSBhYm92ZS4KCgkJCS8vIHRyeSB0byBmaW5kIGV4aXN0aW5nIHZhbHVlcwoJCQkkbmFtZVJlZ2V4ID0gc3RyX3JlcGxhY2UoJy8nLCAnXFxcXD8vJywgcHJlZ19xdW90ZSgkbmFtZSkpOyAvLyBSZW5hbWVkIGZyb20gYCRwYWNrYWdlUmVnZXhgIGluIGBhZGRMaW5rKClgIGNhc2UgYWJvdmUuCgkJCSRyZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nIig/UDxuYW1lPicuJG5hbWVSZWdleC4nKSIoXHMqOlxzKikoPyZqc29uKX1peCc7IC8vIE5lZWQgYCg/Jmpzb24pYCBQQ1JFIHN1YnJvdXRpbmUgaGVyZSwgYXMgb3Bwb3NlZCB0byBgKD8mc3RyaW5nKWAgaW4gYGFkZExpbmsoKWAgY2FzZS4KCQkJaWYgKHByZWdfbWF0Y2hfYWxsKCRyZWdleCwgJHZhbHVlLCAkbmFtZU1hdGNoZXMpKSB7CgkJCQkvLyBKdXN0IHphcCB0aGVtIGFsbCBpbmRpdmlkdWFsbHkgaW4gYSBjYXNlIHNlbnNpdGl2ZSBtYW5uZXIuCgkJCQlmb3JlYWNoICggJG5hbWVNYXRjaGVzWyduYW1lJ10gYXMgJG5hbWVNYXRjaCApIHsKCQkJCQkkdGhpcy0+cmVtb3ZlU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lTWF0Y2gpOwoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJLy8gV1BfQ0xJOiBlbmQgY2FzZUluc2Vuc2l0aXZlLgoKICAgICAgICAvLyBubyBub2RlIGNvbnRlbnQgbWF0Y2gtYWJsZQogICAgICAgICRub2RlUmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+IFxzKiBceyBccyogKD86ICg/JnN0cmluZykgXHMqIDogKD8manNvbikgXHMqICwgXHMqICkqPycuCiAgICAgICAgICAgIHByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkbWFpbk5vZGUpKS4nXHMqOlxzKikoP1A8Y29udGVudD4oPyZvYmplY3QpKSg/UDxlbmQ+LiopfXN4JzsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5wcmVnTWF0Y2goJG5vZGVSZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGUtPmdldENvZGUoKSA9PT0gUFJFR19CQUNLVFJBQ0tfTElNSVRfRVJST1IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgICRjaGlsZHJlbiA9ICRtYXRjaFsnY29udGVudCddOwoKICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgkY2hpbGRyZW4sIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRzdWJOYW1lID0gbnVsbDsKICAgICAgICBpZiAoaW5fYXJyYXkoJG1haW5Ob2RlLCBhcnJheSgnY29uZmlnJywgJ2V4dHJhJykpICYmIGZhbHNlICE9PSBzdHJwb3MoJG5hbWUsICcuJykpIHsKICAgICAgICAgICAgbGlzdCgkbmFtZSwgJHN1Yk5hbWUpID0gZXhwbG9kZSgnLicsICRuYW1lLCAyKTsKICAgICAgICB9CgogICAgICAgIC8vIG5vIG5vZGUgdG8gcmVtb3ZlCiAgICAgICAgaWYgKCFpc3NldCgkZGVjb2RlZFskbWFpbk5vZGVdWyRuYW1lXSkgfHwgKCRzdWJOYW1lICYmICFpc3NldCgkZGVjb2RlZFskbWFpbk5vZGVdWyRuYW1lXVskc3ViTmFtZV0pKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIHRyeSBhbmQgZmluZCBhIG1hdGNoIGZvciB0aGUgc3Via2V5CiAgICAgICAgaWYgKCR0aGlzLT5wcmVnTWF0Y2goJ3siJy5wcmVnX3F1b3RlKCRuYW1lKS4nIlxzKjp9aScsICRjaGlsZHJlbikpIHsKICAgICAgICAgICAgLy8gZmluZCBiZXN0IG1hdGNoIGZvciB0aGUgdmFsdWUgb2YgIm5hbWUiCiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoX2FsbCgneycuc2VsZjo6JERFRklORVMuJyInLnByZWdfcXVvdGUoJG5hbWUpLiciXHMqOlxzKig/Oig/Jmpzb24pKX14JywgJGNoaWxkcmVuLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICRiZXN0TWF0Y2ggPSAnJzsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzWzBdIGFzICRtYXRjaCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oJGJlc3RNYXRjaCkgPCBzdHJsZW4oJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYmVzdE1hdGNoID0gJG1hdGNoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gcHJlZ19yZXBsYWNlKCd7LFxzKicucHJlZ19xdW90ZSgkYmVzdE1hdGNoKS4nfScsICcnLCAkY2hpbGRyZW4sIC0xLCAkY291bnQpOyAvLyBXUF9DTEk6IEFzIHRoZSBwcmVnX21hdGNoX2FsbCgpIGFib3ZlIGlzIGNhc2Utc2Vuc2l0aXZlLCBzbyBzaG91bGQgdGhpcyBiZS4KICAgICAgICAgICAgICAgIGlmICgxICE9PSAkY291bnQpIHsKICAgICAgICAgICAgICAgICAgICAkY2hpbGRyZW5DbGVhbiA9IHByZWdfcmVwbGFjZSgneycucHJlZ19xdW90ZSgkYmVzdE1hdGNoKS4nXHMqLD9ccyp9JywgJycsICRjaGlsZHJlbkNsZWFuLCAtMSwgJGNvdW50KTsgLy8gV1BfQ0xJOiBkaXR0by4KICAgICAgICAgICAgICAgICAgICBpZiAoMSAhPT0gJGNvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY2hpbGRyZW5DbGVhbiA9ICRjaGlsZHJlbjsKICAgICAgICB9CgogICAgICAgIC8vIG5vIGNoaWxkIGRhdGEgbGVmdCwgJG5hbWUgd2FzIHRoZSBvbmx5IGtleSBpbgogICAgICAgICR0aGlzLT5wcmVnTWF0Y2goJyNeeyBccyo/ICg/UDxjb250ZW50PlxTKy4qPyk/ICg/UDx0cmFpbGluZ3NwYWNlPlxzKikgfSQjc3gnLCAkY2hpbGRyZW5DbGVhbiwgJG1hdGNoKTsKICAgICAgICBpZiAoZW1wdHkoJG1hdGNoWydjb250ZW50J10pKSB7CiAgICAgICAgICAgICRuZXdsaW5lID0gJHRoaXMtPm5ld2xpbmU7CiAgICAgICAgICAgICRpbmRlbnQgPSAkdGhpcy0+aW5kZW50OwoKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCRub2RlUmVnZXgsIGZ1bmN0aW9uICgkbWF0Y2hlcykgdXNlICgkaW5kZW50LCAkbmV3bGluZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWydzdGFydCddIC4gJ3snIC4gJG5ld2xpbmUgLiAkaW5kZW50IC4gJ30nIC4gJG1hdGNoZXNbJ2VuZCddOwogICAgICAgICAgICB9LCAkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAgICAgLy8gd2UgaGF2ZSBhIHN1Ym5hbWUsIHNvIHdlIHJlc3RvcmUgdGhlIHJlc3Qgb2YgJG5hbWUKICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkY3VyVmFsID0ganNvbl9kZWNvZGUoJGNoaWxkcmVuLCB0cnVlKTsKICAgICAgICAgICAgICAgIHVuc2V0KCRjdXJWYWxbJG5hbWVdWyRzdWJOYW1lXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lLCAkY3VyVmFsWyRuYW1lXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoYXQgPSAkdGhpczsKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJG5vZGVSZWdleCwgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCR0aGF0LCAkbmFtZSwgJHN1Yk5hbWUsICRjaGlsZHJlbkNsZWFuKSB7CiAgICAgICAgICAgIGlmICgkc3ViTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJGN1clZhbCA9IGpzb25fZGVjb2RlKCRtYXRjaGVzWydjb250ZW50J10sIHRydWUpOwogICAgICAgICAgICAgICAgdW5zZXQoJGN1clZhbFskbmFtZV1bJHN1Yk5hbWVdKTsKICAgICAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gJHRoYXQtPmZvcm1hdCgkY3VyVmFsLCAwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWydzdGFydCddIC4gJGNoaWxkcmVuQ2xlYW4gLiAkbWF0Y2hlc1snZW5kJ107CiAgICAgICAgfSwgJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZE1haW5LZXkoJGtleSwgJGNvbnRlbnQpCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CiAgICAgICAgJGNvbnRlbnQgPSAkdGhpcy0+Zm9ybWF0KCRjb250ZW50KTsKCiAgICAgICAgLy8ga2V5IGV4aXN0cyBhbHJlYWR5CiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PlxzKlx7XHMqKD86KD8mc3RyaW5nKVxzKjpccyooPyZqc29uKVxzKixccyopKj8pJy4KICAgICAgICAgICAgJyg/UDxrZXk+Jy5wcmVnX3F1b3RlKEpzb25GaWxlOjplbmNvZGUoJGtleSkpLidccyo6XHMqKD8manNvbikpKD9QPGVuZD4uKil9c3gnOwogICAgICAgIGlmIChpc3NldCgkZGVjb2RlZFska2V5XSkgJiYgJHRoaXMtPnByZWdNYXRjaCgkcmVnZXgsICR0aGlzLT5jb250ZW50cywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIGludmFsaWQgbWF0Y2ggZHVlIHRvIHVuLXJlZ2V4YWJsZSBjb250ZW50LCBhYm9ydAogICAgICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgneycuJG1hdGNoZXNbJ2tleSddLid9JykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gJG1hdGNoZXNbJ3N0YXJ0J10gLiBKc29uRmlsZTo6ZW5jb2RlKCRrZXkpLic6ICcuJGNvbnRlbnQgLiAkbWF0Y2hlc1snZW5kJ107CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGVuZCBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlIGFuZCBrZWVwIHdoaXRlc3BhY2UKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgnI1tee1xzXShccyopXH0kIycsICR0aGlzLT5jb250ZW50cywgJG1hdGNoKSkgewogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAnIycuJG1hdGNoWzFdLidcfSQjJywKICAgICAgICAgICAgICAgIGFkZGNzbGFzaGVzKCcsJyAuICR0aGlzLT5uZXdsaW5lIC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuICc6ICcuICRjb250ZW50IC4gJHRoaXMtPm5ld2xpbmUgLiAnfScsICdcXCQnKSwKICAgICAgICAgICAgICAgICR0aGlzLT5jb250ZW50cwogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBhcHBlbmQgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZQogICAgICAgICR0aGlzLT5jb250ZW50cyA9IHByZWdfcmVwbGFjZSgKICAgICAgICAgICAgJyNcfSQjJywKICAgICAgICAgICAgYWRkY3NsYXNoZXMoJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuICc6ICcuJGNvbnRlbnQgLiAkdGhpcy0+bmV3bGluZSAuICd9JywgJ1xcJCcpLAogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMKICAgICAgICApOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlTWFpbktleSgka2V5KQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICBpZiAoIWlzc2V0KCRkZWNvZGVkWyRrZXldKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGtleSBleGlzdHMgYWxyZWFkeQogICAgICAgICRyZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nXig/UDxzdGFydD5ccypce1xzKig/Oig/JnN0cmluZylccyo6XHMqKD8manNvbilccyosXHMqKSo/KScuCiAgICAgICAgICAgICcoP1A8cmVtb3ZhbD4nLnByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgka2V5KSkuJ1xzKjpccyooPyZqc29uKSlccyosP1xzKig/UDxlbmQ+LiopfXN4JzsKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgkcmVnZXgsICR0aGlzLT5jb250ZW50cywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIGludmFsaWQgbWF0Y2ggZHVlIHRvIHVuLXJlZ2V4YWJsZSBjb250ZW50LCBhYm9ydAogICAgICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgneycuJG1hdGNoZXNbJ3JlbW92YWwnXS4nfScpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgd2UgYXJlIG5vdCBsZWF2aW5nIGEgZGFuZ2xpbmcgY29tbWEgb24gdGhlIHByZXZpb3VzIGxpbmUgaWYgdGhlIGxhc3QgbGluZSB3YXMgcmVtb3ZlZAogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnIyxccyokIycsICRtYXRjaGVzWydzdGFydCddKSAmJiBwcmVnX21hdGNoKCcjXlx9JCMnLCAkbWF0Y2hlc1snZW5kJ10pKSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlc1snc3RhcnQnXSA9IHJ0cmltKHByZWdfcmVwbGFjZSgnIywoXHMqKSQjJywgJyQxJywgJG1hdGNoZXNbJ3N0YXJ0J10pLCAkdGhpcy0+aW5kZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gJG1hdGNoZXNbJ3N0YXJ0J10gLiAkbWF0Y2hlc1snZW5kJ107CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcjXlx7XHMqXH1ccyokIycsICR0aGlzLT5jb250ZW50cykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb250ZW50cyA9ICJ7XG59IjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZvcm1hdCgkZGF0YSwgJGRlcHRoID0gMCkKICAgIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJGRhdGEpKSB7CiAgICAgICAgICAgIHJlc2V0KCRkYXRhKTsKCiAgICAgICAgICAgIGlmIChpc19udW1lcmljKGtleSgkZGF0YSkpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGF0YSBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YVska2V5XSA9ICR0aGlzLT5mb3JtYXQoJHZhbCwgJGRlcHRoICsgMSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICdbJy5pbXBsb2RlKCcsICcsICRkYXRhKS4nXSc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRvdXQgPSAneycgLiAkdGhpcy0+bmV3bGluZTsKICAgICAgICAgICAgJGVsZW1zID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRhdGEgYXMgJGtleSA9PiAkdmFsKSB7CiAgICAgICAgICAgICAgICAkZWxlbXNbXSA9IHN0cl9yZXBlYXQoJHRoaXMtPmluZGVudCwgJGRlcHRoICsgMikgLiBKc29uRmlsZTo6ZW5jb2RlKCRrZXkpLiAnOiAnLiR0aGlzLT5mb3JtYXQoJHZhbCwgJGRlcHRoICsgMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkb3V0IC4gaW1wbG9kZSgnLCcuJHRoaXMtPm5ld2xpbmUsICRlbGVtcykgLiAkdGhpcy0+bmV3bGluZSAuIHN0cl9yZXBlYXQoJHRoaXMtPmluZGVudCwgJGRlcHRoICsgMSkgLiAnfSc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gSnNvbkZpbGU6OmVuY29kZSgkZGF0YSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRldGVjdEluZGVudGluZygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5wcmVnTWF0Y2goJ3teKFsgXHRdKykifW0nLCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCkpIHsKICAgICAgICAgICAgJHRoaXMtPmluZGVudCA9ICRtYXRjaFsxXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+aW5kZW50ID0gJyAgICAnOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJlZ01hdGNoKCRyZSwgJHN0ciwgJiRtYXRjaGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkY291bnQgPSBwcmVnX21hdGNoKCRyZSwgJHN0ciwgJG1hdGNoZXMpOwoKICAgICAgICBpZiAoJGNvdW50ID09PSBmYWxzZSkgewogICAgICAgICAgICBzd2l0Y2ggKHByZWdfbGFzdF9lcnJvcigpKSB7CiAgICAgICAgICAgICAgICBjYXNlIFBSRUdfTk9fRVJST1I6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19OT19FUlJPUicsIFBSRUdfTk9fRVJST1IpOwogICAgICAgICAgICAgICAgY2FzZSBQUkVHX0lOVEVSTkFMX0VSUk9SOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfSU5URVJOQUxfRVJST1InLCBQUkVHX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgIGNhc2UgUFJFR19CQUNLVFJBQ0tfTElNSVRfRVJST1I6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19CQUNLVFJBQ0tfTElNSVRfRVJST1InLCBQUkVHX0JBQ0tUUkFDS19MSU1JVF9FUlJPUik7CiAgICAgICAgICAgICAgICBjYXNlIFBSRUdfUkVDVVJTSU9OX0xJTUlUX0VSUk9SOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfUkVDVVJTSU9OX0xJTUlUX0VSUk9SJywgUFJFR19SRUNVUlNJT05fTElNSVRfRVJST1IpOwogICAgICAgICAgICAgICAgY2FzZSBQUkVHX0JBRF9VVEY4X0VSUk9SOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfQkFEX1VURjhfRVJST1InLCBQUkVHX0JBRF9VVEY4X0VSUk9SKTsKICAgICAgICAgICAgICAgIGNhc2UgUFJFR19CQURfVVRGOF9PRkZTRVRfRVJST1I6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19CQURfVVRGOF9PRkZTRVRfRVJST1InLCBQUkVHX0JBRF9VVEY4X09GRlNFVF9FUlJPUik7CiAgICAgICAgICAgICAgICBjYXNlIDY6IC8vIFBSRUdfSklUX1NUQUNLTElNSVRfRVJST1IKICAgICAgICAgICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPiA3MDAwMCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX0pJVF9TVEFDS0xJTUlUX0VSUk9SJywgNik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoCgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBVbmtub3duIGVycm9yJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY291bnQ7CiAgICB9Cn0KPD9waHAKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENvbmZpZ1xKc29uQ29uZmlnU291cmNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFBvb2w7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUmVxdWVzdDsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudDsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJT1xOdWxsSU87CnVzZSBDb21wb3NlclxJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uU2VsZWN0b3I7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NpdGVSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NlclJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIFdQX0NMSVxDb21wb3NlcklPOwp1c2UgV1BfQ0xJXEV4dHJhY3RvcjsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxKc29uTWFuaXB1bGF0b3I7CnVzZSBXUF9DTElcUGFja2FnZU1hbmFnZXJFdmVudFN1YnNjcmliZXI7CgovKioKICogTGlzdHMsIGluc3RhbGxzLCBhbmQgcmVtb3ZlcyBXUC1DTEkgcGFja2FnZXMuCiAqCiAqIFdQLUNMSSBwYWNrYWdlcyBhcmUgY29tbXVuaXR5LW1haW50YWluZWQgcHJvamVjdHMgYnVpbHQgb24gV1AtQ0xJLiBUaGV5IGNhbgogKiBjb250YWluIFdQLUNMSSBjb21tYW5kcywgYnV0IHRoZXkgY2FuIGFsc28ganVzdCBleHRlbmQgV1AtQ0xJIGluIHNvbWUgd2F5LgogKgogKiBMZWFybiBob3cgdG8gY3JlYXRlIHlvdXIgb3duIGNvbW1hbmQgZnJvbSB0aGUKICogW0NvbW1hbmRzIENvb2tib29rXShodHRwczovL21ha2Uud29yZHByZXNzLm9yZy9jbGkvaGFuZGJvb2svY29tbWFuZHMtY29va2Jvb2svKQogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGluc3RhbGxlZCBwYWNrYWdlcwogKiAgICAgJCB3cCBwYWNrYWdlIGxpc3QKICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0rCiAqICAgICB8IG5hbWUgICAgICAgICAgICAgICAgICB8IGRlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhdXRob3JzIHwgdmVyc2lvbiAgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLSsKICogICAgIHwgd3AtY2xpL3NlcnZlci1jb21tYW5kIHwgU3RhcnQgYSBkZXZlbG9wbWVudCBzZXJ2ZXIgZm9yIFdvcmRQcmVzcyB8ICAgICAgICAgfCBkZXYtbWFpbiB8CiAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSstLS0tLS0tLS0tKwogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBsYXRlc3QgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiB0aGUgcGFja2FnZQogKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgd3AtY2xpL3NlcnZlci1jb21tYW5kCiAqICAgICBJbnN0YWxsaW5nIHBhY2thZ2Ugd3AtY2xpL3NlcnZlci1jb21tYW5kIChkZXYtbWFpbikKICogICAgIFVwZGF0aW5nIC9ob21lL3BlcnNvbi8ud3AtY2xpL3BhY2thZ2VzL2NvbXBvc2VyLmpzb24gdG8gcmVxdWlyZSB0aGUgcGFja2FnZS4uLgogKiAgICAgVXNpbmcgQ29tcG9zZXIgdG8gaW5zdGFsbCB0aGUgcGFja2FnZS4uLgogKiAgICAgLS0tCiAqICAgICBMb2FkaW5nIGNvbXBvc2VyIHJlcG9zaXRvcmllcyB3aXRoIHBhY2thZ2UgaW5mb3JtYXRpb24KICogICAgIFVwZGF0aW5nIGRlcGVuZGVuY2llcwogKiAgICAgUmVzb2x2aW5nIGRlcGVuZGVuY2llcyB0aHJvdWdoIFNBVAogKiAgICAgRGVwZW5kZW5jeSByZXNvbHV0aW9uIGNvbXBsZXRlZCBpbiAwLjAwNSBzZWNvbmRzCiAqICAgICBBbmFseXplZCA3MzIgcGFja2FnZXMgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMKICogICAgIEFuYWx5emVkIDEwMzQgcnVsZXMgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMKICogICAgICAtIEluc3RhbGxpbmcgcGFja2FnZQogKiAgICAgV3JpdGluZyBsb2NrIGZpbGUKICogICAgIEdlbmVyYXRpbmcgYXV0b2xvYWQgZmlsZXMKICogICAgIC0tLQogKiAgICAgU3VjY2VzczogUGFja2FnZSBpbnN0YWxsZWQuCiAqCiAqICAgICAjIFVuaW5zdGFsbCBwYWNrYWdlCiAqICAgICAkIHdwIHBhY2thZ2UgdW5pbnN0YWxsIHdwLWNsaS9zZXJ2ZXItY29tbWFuZAogKiAgICAgUmVtb3ZpbmcgcmVxdWlyZSBzdGF0ZW1lbnQgZnJvbSAvaG9tZS9wZXJzb24vLndwLWNsaS9wYWNrYWdlcy9jb21wb3Nlci5qc29uCiAqICAgICBEZWxldGluZyBwYWNrYWdlIGRpcmVjdG9yeSAvaG9tZS9wZXJzb24vLndwLWNsaS9wYWNrYWdlcy92ZW5kb3Ivd3AtY2xpL3NlcnZlci1jb21tYW5kCiAqICAgICBSZWdlbmVyYXRpbmcgQ29tcG9zZXIgYXV0b2xvYWQuCiAqICAgICBTdWNjZXNzOiBVbmluc3RhbGxlZCBwYWNrYWdlLgogKgogKiBAcGFja2FnZSBXUC1DTEkKICoKICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKICovCmNsYXNzIFBhY2thZ2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgljb25zdCBQQUNLQUdFX0lOREVYX1VSTCA9ICdodHRwczovL3dwLWNsaS5vcmcvcGFja2FnZS1pbmRleC8nOwoJY29uc3QgU1NMX0NFUlRJRklDQVRFICAgPSAnL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1RyYW5zcG9ydC9jYWNlcnQucGVtJzsKCgljb25zdCBERUZBVUxUX0RFVl9CUkFOQ0hfQ09OU1RSQUlOVFMgPSAnZGV2LW1haW4gfHwgZGV2LW1hc3RlciB8fCBkZXYtdHJ1bmsnOwoKCXByaXZhdGUgJHZlcnNpb25fc2VsZWN0b3IgPSBmYWxzZTsKCgkvKioKCSAqIERlZmF1bHQgYXV0aG9yIGRhdGEgdXNlZCB3aGlsZSBjcmVhdGluZyBkZWZhdWx0IFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkYXV0aG9yX2RhdGEgPSBbCgkJJ25hbWUnICA9PiAnV1AtQ0xJJywKCQknZW1haWwnID0+ICdub3JlcGx5QHdwY2xpLm9yZycsCgldOwoKCS8qKgoJICogRGVmYXVsdCByZXBvc2l0b3J5IGRhdGEgdXNlZCB3aGlsZSBjcmVhdGluZyBkZWZhdWx0IFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uLgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRjb21wb3Nlcl90eXBlX3BhY2thZ2UgPSBbCgkJJ3R5cGUnID0+ICdjb21wb3NlcicsCgkJJ3VybCcgID0+IHNlbGY6OlBBQ0tBR0VfSU5ERVhfVVJMLAoJXTsKCgkvKioKCSAqIEJyb3dzZXMgV1AtQ0xJIHBhY2thZ2VzIGF2YWlsYWJsZSBmb3IgaW5zdGFsbGF0aW9uLgoJICoKCSAqIExpc3RzIHBhY2thZ2VzIGF2YWlsYWJsZSBmb3IgaW5zdGFsbGF0aW9uIGZyb20gdGhlIFtQYWNrYWdlIEluZGV4XShodHRwOi8vd3AtY2xpLm9yZy9wYWNrYWdlLWluZGV4LykuCgkgKiBBbHRob3VnaCB0aGUgcGFja2FnZSBpbmRleCB3aWxsIHJlbWFpbiBpbiBwbGFjZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZWFzb25zLCBpdCBoYXMgYmVlbgoJICogZGVwcmVjYXRlZCBhbmQgd2lsbCBub3QgYmUgdXBkYXRlZCBmdXJ0aGVyLiBQbGVhc2UgcmVmZXIgdG8gaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS9pZGVhcy9pc3N1ZXMvNTEKCSAqIHRvIHJlYWQgYWJvdXQgaXRzIHBvdGVudGlhbCByZXBsYWNlbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHBhY2thZ2U6CgkgKgoJICogKiBuYW1lCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIGF1dGhvcnMKCSAqICogdmVyc2lvbgoJICoKCSAqIFRoZXJlIGFyZSBubyBvcHRpb25hbGx5IGF2YWlsYWJsZSBmaWVsZHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwYWNrYWdlIGJyb3dzZSAtLWZvcm1hdD15YW1sCgkgKiAgICAgLS0tCgkgKiAgICAgMTB1cC9tdS1taWdyYXRpb246CgkgKiAgICAgICBuYW1lOiAxMHVwL211LW1pZ3JhdGlvbgoJICogICAgICAgZGVzY3JpcHRpb246IEEgc2V0IG9mIFdQLUNMSSBjb21tYW5kcyB0byBzdXBwb3J0IHRoZSBtaWdyYXRpb24gb2Ygc2luZ2xlIFdvcmRQcmVzcyBpbnN0YW5jZXMgdG8gbXVsdGlzaXRlCgkgKiAgICAgICBhdXRob3JzOiBOw61jaG9sYXMgQW5kcsOpCgkgKiAgICAgICB2ZXJzaW9uOiBkZXYtbWFpbiwgZGV2LWRldmVsb3AKCSAqICAgICBhYWVtbm5vc3R0di93cC1jbGktZG90ZW52LWNvbW1hbmQ6CgkgKiAgICAgICBuYW1lOiBhYWVtbm5vc3R0di93cC1jbGktZG90ZW52LWNvbW1hbmQKCSAqICAgICAgIGRlc2NyaXB0aW9uOiBEb3RlbnYgY29tbWFuZHMgZm9yIFdQLUNMSQoJICogICAgICAgYXV0aG9yczogRXZhbiBNYXR0c29uCgkgKiAgICAgICB2ZXJzaW9uOiB2MC4xLCB2MC4xLWJldGEuMSwgdjAuMiwgZGV2LW1haW4sIGRldi1kZXYsIGRldi1kZXZlbG9wLCBkZXYtdGVzdHMvYmVoYXQKCSAqICAgICBhYWVtbm5vc3R0di93cC1jbGktaHR0cC1jb21tYW5kOgoJICogICAgICAgbmFtZTogYWFlbW5ub3N0dHYvd3AtY2xpLWh0dHAtY29tbWFuZAoJICogICAgICAgZGVzY3JpcHRpb246IFdQLUNMSSBjb21tYW5kIGZvciB1c2luZyB0aGUgV29yZFByZXNzIEhUVFAgQVBJCgkgKiAgICAgICBhdXRob3JzOiBFdmFuIE1hdHRzb24KCSAqICAgICAgIHZlcnNpb246IGRldi1tYWluCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBicm93c2UoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+c2V0X2NvbXBvc2VyX2F1dGhfZW52X3ZhcigpOwoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHx8ICd0YWJsZScgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJV1BfQ0xJOjpsaW5lKCBXUF9DTEk6OmNvbG9yaXplKCAnJUNBbHRob3VnaCB0aGUgcGFja2FnZSBpbmRleCB3aWxsIHJlbWFpbiBpbiBwbGFjZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZWFzb25zLCBpdCBoYXMgYmVlbiBkZXByZWNhdGVkIGFuZCB3aWxsIG5vdCBiZSB1cGRhdGVkIGZ1cnRoZXIuIFBsZWFzZSByZWZlciB0byBodHRwczovL2dpdGh1Yi5jb20vd3AtY2xpL2lkZWFzL2lzc3Vlcy81MSB0byByZWFkIGFib3V0IGl0cyBwb3RlbnRpYWwgcmVwbGFjZW1lbnQuJW4nICkgKTsKCQl9CgkJJHRoaXMtPnNob3dfcGFja2FnZXMoICdicm93c2UnLCAkdGhpcy0+Z2V0X2NvbW11bml0eV9wYWNrYWdlcygpLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogSW5zdGFsbHMgYSBXUC1DTEkgcGFja2FnZS4KCSAqCgkgKiBQYWNrYWdlcyBhcmUgcmVxdWlyZWQgdG8gYmUgYSB2YWxpZCBDb21wb3NlciBwYWNrYWdlLCBhbmQgY2FuIGJlCgkgKiBzcGVjaWZpZWQgYXM6CgkgKgoJICogKiBQYWNrYWdlIG5hbWUgZnJvbSBXUC1DTEkncyBwYWNrYWdlIGluZGV4LgoJICogKiBHaXQgVVJMIGFjY2Vzc2libGUgYnkgdGhlIGN1cnJlbnQgc2hlbGwgdXNlci4KCSAqICogUGF0aCB0byBhIGRpcmVjdG9yeSBvbiB0aGUgbG9jYWwgbWFjaGluZS4KCSAqICogTG9jYWwgb3IgcmVtb3RlIC56aXAgZmlsZS4KCSAqCgkgKiBQYWNrYWdlcyBhcmUgaW5zdGFsbGVkIHRvIGB+Ly53cC1jbGkvcGFja2FnZXMvYCBieSBkZWZhdWx0LiBVc2UgdGhlCgkgKiBgV1BfQ0xJX1BBQ0tBR0VTX0RJUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gcHJvdmlkZSBhIGN1c3RvbSBwYXRoLgoJICoKCSAqIFdoZW4gaW5zdGFsbGluZyBhIGxvY2FsIGRpcmVjdG9yeSwgV1AtQ0xJIHNpbXBseSByZWdpc3RlcnMgYQoJICogcmVmZXJlbmNlIHRvIHRoZSBkaXJlY3RvcnkuIElmIHlvdSBtb3ZlIG9yIGRlbGV0ZSB0aGUgZGlyZWN0b3J5LCBXUC1DTEkncwoJICogcmVmZXJlbmNlIGJyZWFrcy4KCSAqCgkgKiBXaGVuIGluc3RhbGxpbmcgYSAuemlwIGZpbGUsIFdQLUNMSSBleHRyYWN0cyB0aGUgcGFja2FnZSB0bwoJICogYH4vLndwLWNsaS9wYWNrYWdlcy9sb2NhbC88cGFja2FnZS1uYW1lPmAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxuYW1lfGdpdHxwYXRofHppcD4KCSAqIDogTmFtZSwgZ2l0IFVSTCwgZGlyZWN0b3J5IHBhdGgsIG9yIC56aXAgZmlsZSBmb3IgdGhlIHBhY2thZ2UgdG8gaW5zdGFsbC4KCSAqIE5hbWVzIGNhbiBvcHRpb25hbGx5IGluY2x1ZGUgYSB2ZXJzaW9uIGNvbnN0cmFpbnQKCSAqIChlLmcuIHdwLWNsaS9zZXJ2ZXItY29tbWFuZDpAc3RhYmxlKS4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWRzIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEluc3RhbGwgYSBwYWNrYWdlIGhvc3RlZCBhdCBhIGdpdCBVUkwuCgkgKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgcnVuY29tbWFuZC9ob29rCgkgKgoJICogICAgICMgSW5zdGFsbCB0aGUgbGF0ZXN0IHN0YWJsZSB2ZXJzaW9uLgoJICogICAgICQgd3AgcGFja2FnZSBpbnN0YWxsIHdwLWNsaS9zZXJ2ZXItY29tbWFuZDpAc3RhYmxlCgkgKgoJICogICAgICMgSW5zdGFsbCBhIHBhY2thZ2UgaG9zdGVkIGF0IGEgR2l0TGFiLmNvbSBVUkwuCgkgKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgaHR0cHM6Ly9naXRsYWIuY29tL2Zvby93cC1jbGktYmFyLWNvbW1hbmQuZ2l0CgkgKgoJICogICAgICMgSW5zdGFsbCBhIHBhY2thZ2UgaW4gYSAuemlwIGZpbGUuCgkgKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgZ29vZ2xlLXNpdGVtYXAtZ2VuZXJhdG9yLWNsaS56aXAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkcGFja2FnZV9uYW1lICkgPSAkYXJnczsKCgkJJGluc2VjdXJlID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCgkJJHRoaXMtPnNldF9jb21wb3Nlcl9hdXRoX2Vudl92YXIoKTsKCQkkZ2l0X3BhY2thZ2UgPSBmYWxzZTsKCQkkZGlyX3BhY2thZ2UgPSBmYWxzZTsKCQkkdmVyc2lvbiAgICAgPSAnJzsKCQlpZiAoICR0aGlzLT5pc19naXRfcmVwb3NpdG9yeSggJHBhY2thZ2VfbmFtZSApICkgewoJCQlpZiAoICcnID09PSAkdmVyc2lvbiApIHsKCQkJCSR2ZXJzaW9uID0gImRldi17JHRoaXMtPmdldF9naXRodWJfZGVmYXVsdF9icmFuY2goICRwYWNrYWdlX25hbWUsICRpbnNlY3VyZSApfSI7CgkJCX0KCQkJJGdpdF9wYWNrYWdlID0gJHBhY2thZ2VfbmFtZTsKCQkJJG1hdGNoZXMgICAgID0gW107CgkJCWlmICggcHJlZ19tYXRjaCggJyMoW146XC9dK1wvW15cL10rKVwuZ2l0IycsICRwYWNrYWdlX25hbWUsICRtYXRjaGVzICkgKSB7CgkJCQkkcGFja2FnZV9uYW1lID0gJHRoaXMtPmNoZWNrX2dpdF9wYWNrYWdlX25hbWUoICRtYXRjaGVzWzFdLCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiwgJGluc2VjdXJlICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgcGFyc2UgcGFja2FnZSBuYW1lIGZyb20gZXhwZWN0ZWQgcGF0aCAnPG5hbWU+LzxwYWNrYWdlPicuIiApOwoJCQl9CgkJfSBlbHNlaWYgKCAoIGZhbHNlICE9PSBzdHJwb3MoICRwYWNrYWdlX25hbWUsICc6Ly8nICkgJiYgZmFsc2UgIT09IHN0cmlwb3MoICRwYWNrYWdlX25hbWUsICcuemlwJyApICkKCQkJfHwgKCBwYXRoaW5mbyggJHBhY2thZ2VfbmFtZSwgUEFUSElORk9fRVhURU5TSU9OICkgPT09ICd6aXAnICYmIGlzX2ZpbGUoICRwYWNrYWdlX25hbWUgKSApICkgewoJCQkvLyBEb3dubG9hZCB0aGUgcmVtb3RlIFpJUCBmaWxlIHRvIGEgdGVtcCBkaXJlY3RvcnkKCQkJJHRlbXAgPSBmYWxzZTsKCQkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkcGFja2FnZV9uYW1lLCAnOi8vJyApICkgewoJCQkJJHRlbXAgICAgID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkgLiB1bmlxaWQoICd3cC1jbGktcGFja2FnZV8nLCB0cnVlIC8qbW9yZV9lbnRyb3B5Ki8gKSAuICcuemlwJzsKCQkJCSRvcHRpb25zICA9IFsKCQkJCQkndGltZW91dCcgID0+IDYwMCwKCQkJCQknZmlsZW5hbWUnID0+ICR0ZW1wLAoJCQkJCSdpbnNlY3VyZScgPT4gJGluc2VjdXJlLAoJCQkJXTsKCQkJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICRwYWNrYWdlX25hbWUsIG51bGwsIFtdLCAkb3B0aW9ucyApOwoJCQkJaWYgKCAyMCAhPT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCQkJQHVubGluayggJHRlbXAgKTsgLy8gQGNvZGluZ1N0YW5kYXJkc0lnbm9yZUxpbmUKCQkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiQ291bGRuJ3QgZG93bmxvYWQgcGFja2FnZSBmcm9tICclcycgKEhUVFAgY29kZSAlZCkuIiwgJHBhY2thZ2VfbmFtZSwgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApICk7CgkJCQl9CgkJCQkkcGFja2FnZV9uYW1lID0gJHRlbXA7CgkJCX0KCQkJJGRpcl9wYWNrYWdlID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkgLiB1bmlxaWQoICd3cC1jbGktcGFja2FnZV8nLCB0cnVlIC8qbW9yZV9lbnRyb3B5Ki8gKTsKCQkJdHJ5IHsKCQkJCS8vIEV4dHJhY3QgdGhlIHBhY2thZ2UgdG8gZ2V0IHRoZSBwYWNrYWdlIG5hbWUKCQkJCUV4dHJhY3Rvcjo6ZXh0cmFjdCggJHBhY2thZ2VfbmFtZSwgJGRpcl9wYWNrYWdlICk7CgkJCQlpZiAoICR0ZW1wICkgewoJCQkJCXVubGluayggJHRlbXAgKTsKCQkJCQkkdGVtcCA9IGZhbHNlOwoJCQkJfQoJCQkJbGlzdCggJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24gKSA9IHNlbGY6OmdldF9wYWNrYWdlX25hbWVfYW5kX3ZlcnNpb25fZnJvbV9kaXJfcGFja2FnZSggJGRpcl9wYWNrYWdlICk7CgkJCQkvLyBNb3ZlIHRvIGEgbG9jYXRpb24gYmFzZWQgb24gdGhlIHBhY2thZ2UgbmFtZQoJCQkJJGxvY2FsX2RpciAgICAgICAgICA9IHJ0cmltKCBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Z2V0X3BhY2thZ2VzX2Rpcl9wYXRoKCksICcvJyApIC4gJy9sb2NhbC8nOwoJCQkJJGFjdHVhbF9kaXJfcGFja2FnZSA9ICRsb2NhbF9kaXIgLiBzdHJfcmVwbGFjZSggJy8nLCAnLScsICRwYWNrYWdlX25hbWUgKTsKCQkJCUV4dHJhY3Rvcjo6Y29weV9vdmVyd3JpdGVfZmlsZXMoICRkaXJfcGFja2FnZSwgJGFjdHVhbF9kaXJfcGFja2FnZSApOwoJCQkJRXh0cmFjdG9yOjpybWRpciggJGRpcl9wYWNrYWdlICk7CgkJCQkvLyBCZWhvbGQsIHRoZSBleHRyYWN0ZWQgcGFja2FnZQoJCQkJJGRpcl9wYWNrYWdlID0gJGFjdHVhbF9kaXJfcGFja2FnZTsKCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJCWlmICggJHRlbXAgKSB7CgkJCQkJdW5saW5rKCAkdGVtcCApOwoJCQkJfQoJCQkJaWYgKCBmaWxlX2V4aXN0cyggJGRpcl9wYWNrYWdlICkgKSB7CgkJCQkJdHJ5IHsKCQkJCQkJRXh0cmFjdG9yOjpybWRpciggJGRpcl9wYWNrYWdlICk7CgkJCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkcm1kaXJfZSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkcm1kaXJfZS0+Z2V0TWVzc2FnZSgpICk7CgkJCQkJfQoJCQkJfQoJCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCQl9CgkJfSBlbHNlaWYgKCBpc19kaXIoICRwYWNrYWdlX25hbWUgKSAmJiBmaWxlX2V4aXN0cyggJHBhY2thZ2VfbmFtZSAuICcvY29tcG9zZXIuanNvbicgKSApIHsKCQkJJGRpcl9wYWNrYWdlID0gJHBhY2thZ2VfbmFtZTsKCQkJaWYgKCAhIFV0aWxzXGlzX3BhdGhfYWJzb2x1dGUoICRkaXJfcGFja2FnZSApICkgewoJCQkJJGRpcl9wYWNrYWdlID0gZ2V0Y3dkKCkgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJGRpcl9wYWNrYWdlOwoJCQl9CgkJCWxpc3QoICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uICkgPSBzZWxmOjpnZXRfcGFja2FnZV9uYW1lX2FuZF92ZXJzaW9uX2Zyb21fZGlyX3BhY2thZ2UoICRkaXJfcGFja2FnZSApOwoJCX0gZWxzZSB7CgkJCWlmICggZmFsc2UgIT09IHN0cnBvcyggJHBhY2thZ2VfbmFtZSwgJzonICkgKSB7CgkJCQlsaXN0KCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiApID0gZXhwbG9kZSggJzonLCAkcGFja2FnZV9uYW1lICk7CgkJCX0KCQkJJHBhY2thZ2UgPSAkdGhpcy0+Z2V0X3BhY2thZ2VfYnlfc2hvcnRlbmVkX2lkZW50aWZpZXIoICRwYWNrYWdlX25hbWUgKTsKCQkJaWYgKCAhICRwYWNrYWdlICkgewoJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkludmFsaWQgcGFja2FnZTogc2hvcnRlbmVkIGlkZW50aWZpZXIgJyVzJyBub3QgZm91bmQuIiwgJHBhY2thZ2VfbmFtZSApICk7CgkJCX0KCQkJaWYgKCBpc19zdHJpbmcoICRwYWNrYWdlICkgKSB7CgkJCQlpZiAoICR0aGlzLT5pc19naXRfcmVwb3NpdG9yeSggJHBhY2thZ2UgKSApIHsKCQkJCQkkZ2l0X3BhY2thZ2UgPSAkcGFja2FnZTsKCgkJCQkJaWYgKCAnJyA9PT0gJHZlcnNpb24gKSB7CgkJCQkJCSR2ZXJzaW9uID0gImRldi17JHRoaXMtPmdldF9naXRodWJfZGVmYXVsdF9icmFuY2goICRwYWNrYWdlX25hbWUsICRpbnNlY3VyZSApfSI7CgkJCQkJfQoKCQkJCQlpZiAoICdAc3RhYmxlJyA9PT0gJHZlcnNpb24gKSB7CgkJCQkJCSR0YWcgICAgID0gJHRoaXMtPmdldF9naXRodWJfbGF0ZXN0X3JlbGVhc2VfdGFnKCAkcGFja2FnZV9uYW1lLCAkaW5zZWN1cmUgKTsKCQkJCQkJJHZlcnNpb24gPSAkdGhpcy0+Z3Vlc3NfdmVyc2lvbl9jb25zdHJhaW50X2Zyb21fdGFnKCAkdGFnICk7CgkJCQkJfQoJCQkJCSRwYWNrYWdlX25hbWUgPSAkdGhpcy0+Y2hlY2tfZ2l0aHViX3BhY2thZ2VfbmFtZSggJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24sICRpbnNlY3VyZSApOwoJCQkJfQoJCQl9IGVsc2VpZiAoICRwYWNrYWdlX25hbWUgIT09ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkgKSB7CgkJCQkvLyBCQyBzdXBwb3J0IGZvciBzcGVjaWZ5aW5nIGxvd2VyY2FzZSBuYW1lcyBmb3IgbWl4ZWQtY2FzZSBwYWNrYWdlIGluZGV4IHBhY2thZ2VzIC0gZG9uJ3QgYm90aGVyIHdhcm5pbmcuCgkJCQkkcGFja2FnZV9uYW1lID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKCQkJfQoJCX0KCgkJaWYgKCAkdGhpcy0+aXNfY29tcG9zZXJfdjIoKSApIHsKCQkJJHBhY2thZ2VfbmFtZSA9IGZ1bmN0aW9uX2V4aXN0cyggJ21iX3N0cnRvbG93ZXInICkKCQkJCT8gbWJfc3RydG9sb3dlciggJHBhY2thZ2VfbmFtZSApCgkJCQk6IHN0cnRvbG93ZXIoICRwYWNrYWdlX25hbWUgKTsKCQl9CgoJCWlmICggJycgPT09ICR2ZXJzaW9uICkgewoJCQkkdmVyc2lvbiA9IHNlbGY6OkRFRkFVTFRfREVWX0JSQU5DSF9DT05TVFJBSU5UUzsKCQl9CgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnSW5zdGFsbGluZyBwYWNrYWdlICVzICglcyknLCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiApICk7CgoJCS8vIFJlYWQgdGhlIFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uIGFuZCBkbyBzb21lIGluaXRpYWwgZXJyb3IgY2hlY2tpbmcuCgkJbGlzdCggJGpzb25fcGF0aCwgJGNvbXBvc2VyX2JhY2t1cCwgJGNvbXBvc2VyX2JhY2t1cF9kZWNvZGVkICkgPSAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb25fcGF0aF9iYWNrdXBfZGVjb2RlZCgpOwoKCQkvLyBSZXZlcnQgb24gc2h1dGRvd24gaWYgYCRyZXZlcnRgIGlzIHRydWUgKHNldCB0byBmYWxzZSBvbiBzdWNjZXNzKS4KCQkkcmV2ZXJ0ID0gdHJ1ZTsKCQkkdGhpcy0+cmVnaXN0ZXJfcmV2ZXJ0X3NodXRkb3duX2Z1bmN0aW9uKCAkanNvbl9wYXRoLCAkY29tcG9zZXJfYmFja3VwLCAkcmV2ZXJ0ICk7CgoJCS8vIEFkZCB0aGUgJ3JlcXVpcmUnIHRvIGNvbXBvc2VyLmpzb24KCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ1VwZGF0aW5nICVzIHRvIHJlcXVpcmUgdGhlIHBhY2thZ2UuLi4nLCAkanNvbl9wYXRoICkgKTsKCQkkanNvbl9tYW5pcHVsYXRvciA9IG5ldyBKc29uTWFuaXB1bGF0b3IoICRjb21wb3Nlcl9iYWNrdXAgKTsKCQkkanNvbl9tYW5pcHVsYXRvci0+YWRkTWFpbktleSggJ25hbWUnLCAnd3AtY2xpL3dwLWNsaScgKTsKCQkkanNvbl9tYW5pcHVsYXRvci0+YWRkTWFpbktleSggJ3ZlcnNpb24nLCBzZWxmOjpnZXRfd3BfY2xpX3ZlcnNpb25fY29tcG9zZXIoKSApOwoJCSRqc29uX21hbmlwdWxhdG9yLT5hZGRMaW5rKCAncmVxdWlyZScsICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uLCBmYWxzZSAvKnNvcnRQYWNrYWdlcyovLCB0cnVlIC8qY2FzZUluc2Vuc2l0aXZlKi8gKTsKCQkkanNvbl9tYW5pcHVsYXRvci0+YWRkQ29uZmlnU2V0dGluZyggJ3NlY3VyZS1odHRwJywgdHJ1ZSApOwoKCQkkcGFja2FnZV9hcmdzID0gW107CgkJaWYgKCAkZ2l0X3BhY2thZ2UgKSB7CgkJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnUmVnaXN0ZXJpbmcgJXMgYXMgYSBWQ1MgcmVwb3NpdG9yeS4uLicsICRnaXRfcGFja2FnZSApICk7CgkJCSRwYWNrYWdlX2FyZ3MgPSBbCgkJCQkndHlwZScgPT4gJ3ZjcycsCgkJCQkndXJsJyAgPT4gJGdpdF9wYWNrYWdlLAoJCQldOwoJCQkkanNvbl9tYW5pcHVsYXRvci0+YWRkU3ViTm9kZSgKCQkJCSdyZXBvc2l0b3JpZXMnLAoJCQkJJHBhY2thZ2VfbmFtZSwKCQkJCSRwYWNrYWdlX2FyZ3MsCgkJCQl0cnVlIC8qY2FzZUluc2Vuc2l0aXZlKi8KCQkJKTsKCQl9IGVsc2VpZiAoICRkaXJfcGFja2FnZSApIHsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdSZWdpc3RlcmluZyAlcyBhcyBhIHBhdGggcmVwb3NpdG9yeS4uLicsICRkaXJfcGFja2FnZSApICk7CgkJCSRwYWNrYWdlX2FyZ3MgPSBbCgkJCQkndHlwZScgPT4gJ3BhdGgnLAoJCQkJJ3VybCcgID0+ICRkaXJfcGFja2FnZSwKCQkJXTsKCQkJJGpzb25fbWFuaXB1bGF0b3ItPmFkZFN1Yk5vZGUoCgkJCQkncmVwb3NpdG9yaWVzJywKCQkJCSRwYWNrYWdlX25hbWUsCgkJCQkkcGFja2FnZV9hcmdzLAoJCQkJdHJ1ZSAvKmNhc2VJbnNlbnNpdGl2ZSovCgkJCSk7CgkJfQoJCS8vIElmIHRoZSBjb21wb3NlciBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdGhlIGN1cnJlbnQgcGFja2FnZSBpbmRleCByZXBvc2l0b3J5LCByZWZyZXNoIHRoZSByZXBvc2l0b3J5IGRlZmluaXRpb24uCgkJaWYgKCBlbXB0eSggJGNvbXBvc2VyX2JhY2t1cF9kZWNvZGVkWydyZXBvc2l0b3JpZXMnXVsnd3AtY2xpJ11bJ3VybCddICkgfHwgc2VsZjo6UEFDS0FHRV9JTkRFWF9VUkwgIT09ICRjb21wb3Nlcl9iYWNrdXBfZGVjb2RlZFsncmVwb3NpdG9yaWVzJ11bJ3dwLWNsaSddWyd1cmwnXSApIHsKCQkJV1BfQ0xJOjpsb2coICdVcGRhdGluZyBwYWNrYWdlIGluZGV4IHJlcG9zaXRvcnkgdXJsLi4uJyApOwoJCQkkcGFja2FnZV9hcmdzID0gJHRoaXMtPmNvbXBvc2VyX3R5cGVfcGFja2FnZTsKCQkJJGpzb25fbWFuaXB1bGF0b3ItPmFkZFJlcG9zaXRvcnkoCgkJCQknd3AtY2xpJywKCQkJCSRwYWNrYWdlX2FyZ3MKCQkJKTsKCQl9CgoJCWZpbGVfcHV0X2NvbnRlbnRzKCAkanNvbl9wYXRoLCAkanNvbl9tYW5pcHVsYXRvci0+Z2V0Q29udGVudHMoKSApOwoJCSRjb21wb3NlciA9ICR0aGlzLT5nZXRfY29tcG9zZXIoKTsKCgkJLy8gU2V0IHVwIHRoZSBFdmVudFN1YnNjcmliZXIKCQkkZXZlbnRfc3Vic2NyaWJlciA9IG5ldyBQYWNrYWdlTWFuYWdlckV2ZW50U3Vic2NyaWJlcigpOwoJCSRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmFkZFN1YnNjcmliZXIoICRldmVudF9zdWJzY3JpYmVyICk7CgkJLy8gU2V0IHVwIHRoZSBpbnN0YWxsZXIKCQkkaW5zdGFsbCA9IEluc3RhbGxlcjo6Y3JlYXRlKCBuZXcgQ29tcG9zZXJJTygpLCAkY29tcG9zZXIgKTsKCQkkaW5zdGFsbC0+c2V0VXBkYXRlKCB0cnVlICk7IC8vIEluc3RhbGxlciBjbGFzcyB3aWxsIG9ubHkgb3ZlcnJpZGUgY29tcG9zZXIubG9jayB3aXRoIHRoaXMgZmxhZwoJCSRpbnN0YWxsLT5zZXRQcmVmZXJTb3VyY2UoIHRydWUgKTsgLy8gVXNlIFZDUyB3aGVuIFZDUyBmb3IgZWFzaWVyIGNvbnRyaWJ1dGlvbnMuCgoJCS8vIFRyeSBydW5uaW5nIHRoZSBpbnN0YWxsZXIsIGJ1dCByZXZlcnQgY29tcG9zZXIuanNvbiBpZiBmYWlsZWQKCQlXUF9DTEk6OmxvZyggJ1VzaW5nIENvbXBvc2VyIHRvIGluc3RhbGwgdGhlIHBhY2thZ2UuLi4nICk7CgkJV1BfQ0xJOjpsb2coICctLS0nICk7CgkJJHJlcyA9IGZhbHNlOwoJCXRyeSB7CgkJCSRyZXMgPSAkaW5zdGFsbC0+cnVuKCk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQkvLyBUT0RPOiBUaGUgLS1pbnNlY3VyZSBmbGFnIHNob3VsZCBjYXVzZSBhbm90aGVyIENvbXBvc2VyIHJ1biB3aXRoIHZlcmlmeSBkaXNhYmxlZC4KCgkJV1BfQ0xJOjpsb2coICctLS0nICk7CgoJCWlmICggMCA9PT0gJHJlcyApIHsKCQkJJHJldmVydCA9IGZhbHNlOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdQYWNrYWdlIGluc3RhbGxlZC4nICk7CgkJfSBlbHNlIHsKCQkJJHJlc19tc2cgPSAkcmVzID8gIiAoQ29tcG9zZXIgcmV0dXJuIGNvZGUgeyRyZXN9KSIgOiAnJzsgLy8gJHJlcyBtYXkgYmUgbnVsbCBhcHBhcmVudGx5LgoJCQlXUF9DTEk6OmRlYnVnKCAiY29tcG9zZXIuanNvbiBjb250ZW50OlxuIiAuIGZpbGVfZ2V0X2NvbnRlbnRzKCAkanNvbl9wYXRoICksICdwYWNrYWdlcycgKTsKCQkJV1BfQ0xJOjplcnJvciggIlBhY2thZ2UgaW5zdGFsbGF0aW9uIGZhaWxlZHskcmVzX21zZ30uIiApOwoJCX0KCX0KCgkvKioKCSAqIExpc3RzIGluc3RhbGxlZCBXUC1DTEkgcGFja2FnZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuIERlZmF1bHRzIHRvIGFsbCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0gaWRzCgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBwYWNrYWdlOgoJICoKCSAqICogbmFtZQoJICogKiBhdXRob3JzCgkgKiAqIHZlcnNpb24KCSAqICogdXBkYXRlCgkgKiAqIHVwZGF0ZV92ZXJzaW9uCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIGRlc2NyaXB0aW9uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwYWNrYWdlIGxpc3QKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICAgICAgICAgICAgICAgIHwgZGVzY3JpcHRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGF1dGhvcnMgfCB2ZXJzaW9uICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IHdwLWNsaS9zZXJ2ZXItY29tbWFuZCB8IFN0YXJ0IGEgZGV2ZWxvcG1lbnQgc2VydmVyIGZvciBXb3JkUHJlc3MgfCAgICAgICAgIHwgZGV2LW1haW4gfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+c2V0X2NvbXBvc2VyX2F1dGhfZW52X3ZhcigpOwoJCSR0aGlzLT5zaG93X3BhY2thZ2VzKCAnbGlzdCcsICR0aGlzLT5nZXRfaW5zdGFsbGVkX3BhY2thZ2VzKCksICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBwYXRoIHRvIGFuIGluc3RhbGxlZCBXUC1DTEkgcGFja2FnZSwgb3IgdGhlIHBhY2thZ2UgZGlyZWN0b3J5LgoJICoKCSAqIElmIHlvdSB3YW50IHRvIGNvbnRyaWJ1dGUgdG8gYSBwYWNrYWdlLCB0aGlzIGlzIGEgZ3JlYXQgd2F5IHRvIGp1bXAgdG8gaXQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8bmFtZT5dCgkgKiA6IE5hbWUgb2YgdGhlIHBhY2thZ2UgdG8gZ2V0IHRoZSBkaXJlY3RvcnkgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHBhY2thZ2UgcGF0aAoJICogICAgICQgd3AgcGFja2FnZSBwYXRoCgkgKiAgICAgL2hvbWUvcGVyc29uLy53cC1jbGkvcGFja2FnZXMvCgkgKgoJICogICAgICMgQ2hhbmdlIGRpcmVjdG9yeSB0byBwYWNrYWdlIHBhdGgKCSAqICAgICAkIGNkICQod3AgcGFja2FnZSBwYXRoKSAmJiBwd2QKCSAqICAgICAvaG9tZS92YWdyYW50Ly53cC1jbGkvcGFja2FnZXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGgoICRhcmdzICkgewoJCSRwYWNrYWdlc19kaXIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Z2V0X3BhY2thZ2VzX2Rpcl9wYXRoKCk7CgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICkgewoJCQkkcGFja2FnZXNfZGlyIC49ICd2ZW5kb3IvJyAuICRhcmdzWzBdOwoJCQlpZiAoICEgaXNfZGlyKCAkcGFja2FnZXNfZGlyICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBwYWNrYWdlIG5hbWUuJyApOwoJCQl9CgkJfQoJCVdQX0NMSTo6bGluZSggJHBhY2thZ2VzX2RpciApOwoJfQoKCS8qKgoJICogVXBkYXRlcyBhbGwgaW5zdGFsbGVkIFdQLUNMSSBwYWNrYWdlcyB0byB0aGVpciBsYXRlc3QgdmVyc2lvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBhY2thZ2UgdXBkYXRlCgkgKiAgICAgVXNpbmcgQ29tcG9zZXIgdG8gdXBkYXRlIHBhY2thZ2VzLi4uCgkgKiAgICAgLS0tCgkgKiAgICAgTG9hZGluZyBjb21wb3NlciByZXBvc2l0b3JpZXMgd2l0aCBwYWNrYWdlIGluZm9ybWF0aW9uCgkgKiAgICAgVXBkYXRpbmcgZGVwZW5kZW5jaWVzCgkgKiAgICAgUmVzb2x2aW5nIGRlcGVuZGVuY2llcyB0aHJvdWdoIFNBVAoJICogICAgIERlcGVuZGVuY3kgcmVzb2x1dGlvbiBjb21wbGV0ZWQgaW4gMC4wNzQgc2Vjb25kcwoJICogICAgIEFuYWx5emVkIDEwNjIgcGFja2FnZXMgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMKCSAqICAgICBBbmFseXplZCAyMjM4MyBydWxlcyB0byByZXNvbHZlIGRlcGVuZGVuY2llcwoJICogICAgIFdyaXRpbmcgbG9jayBmaWxlCgkgKiAgICAgR2VuZXJhdGluZyBhdXRvbG9hZCBmaWxlcwoJICogICAgIC0tLQoJICogICAgIFN1Y2Nlc3M6IFBhY2thZ2VzIHVwZGF0ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoKSB7CgkJJHRoaXMtPnNldF9jb21wb3Nlcl9hdXRoX2Vudl92YXIoKTsKCQkkY29tcG9zZXIgPSAkdGhpcy0+Z2V0X2NvbXBvc2VyKCk7CgoJCS8vIFNldCB1cCB0aGUgRXZlbnRTdWJzY3JpYmVyCgkJJGV2ZW50X3N1YnNjcmliZXIgPSBuZXcgUGFja2FnZU1hbmFnZXJFdmVudFN1YnNjcmliZXIoKTsKCQkkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5hZGRTdWJzY3JpYmVyKCAkZXZlbnRfc3Vic2NyaWJlciApOwoKCQkvLyBTZXQgdXAgdGhlIGluc3RhbGxlcgoJCSRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoIG5ldyBDb21wb3NlcklPKCksICRjb21wb3NlciApOwoJCSRpbnN0YWxsLT5zZXRVcGRhdGUoIHRydWUgKTsgLy8gSW5zdGFsbGVyIGNsYXNzIHdpbGwgb25seSBvdmVycmlkZSBjb21wb3Nlci5sb2NrIHdpdGggdGhpcyBmbGFnCgkJJGluc3RhbGwtPnNldFByZWZlclNvdXJjZSggdHJ1ZSApOyAvLyBVc2UgVkNTIHdoZW4gVkNTIGZvciBlYXNpZXIgY29udHJpYnV0aW9ucy4KCQlXUF9DTEk6OmxvZyggJ1VzaW5nIENvbXBvc2VyIHRvIHVwZGF0ZSBwYWNrYWdlcy4uLicgKTsKCQlXUF9DTEk6OmxvZyggJy0tLScgKTsKCQkkcmVzID0gZmFsc2U7CgkJdHJ5IHsKCQkJJHJlcyA9ICRpbnN0YWxsLT5ydW4oKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgkJV1BfQ0xJOjpsb2coICctLS0nICk7CgoJCS8vIFRPRE86IFRoZSAtLWluc2VjdXJlICh0byBiZSBhZGRlZCBoZXJlKSBmbGFnIHNob3VsZCBjYXVzZSBhbm90aGVyIENvbXBvc2VyIHJ1biB3aXRoIHZlcmlmeSBkaXNhYmxlZC4KCgkJaWYgKCAwID09PSAkcmVzICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdQYWNrYWdlcyB1cGRhdGVkLicgKTsKCQl9IGVsc2UgewoJCQkkcmVzX21zZyA9ICRyZXMgPyAiIChDb21wb3NlciByZXR1cm4gY29kZSB7JHJlc30pIiA6ICcnOyAvLyAkcmVzIG1heSBiZSBudWxsIGFwcGFyZW50bHkuCgkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gdXBkYXRlIHBhY2thZ2VzeyRyZXNfbXNnfS4iICk7CgkJfQoJfQoKCS8qKgoJICogVW5pbnN0YWxscyBhIFdQLUNMSSBwYWNrYWdlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bmFtZT4KCSAqIDogTmFtZSBvZiB0aGUgcGFja2FnZSB0byB1bmluc3RhbGwuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkcyB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwYWNrYWdlIHVuaW5zdGFsbCB3cC1jbGkvc2VydmVyLWNvbW1hbmQKCSAqICAgICBSZW1vdmluZyByZXF1aXJlIHN0YXRlbWVudCBmcm9tIC9ob21lL3BlcnNvbi8ud3AtY2xpL3BhY2thZ2VzL2NvbXBvc2VyLmpzb24KCSAqICAgICBEZWxldGluZyBwYWNrYWdlIGRpcmVjdG9yeSAvaG9tZS9wZXJzb24vLndwLWNsaS9wYWNrYWdlcy92ZW5kb3Ivd3AtY2xpL3NlcnZlci1jb21tYW5kCgkgKiAgICAgUmVnZW5lcmF0aW5nIENvbXBvc2VyIGF1dG9sb2FkLgoJICogICAgIFN1Y2Nlc3M6IFVuaW5zdGFsbGVkIHBhY2thZ2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkcGFja2FnZV9uYW1lICkgPSAkYXJnczsKCgkJJGluc2VjdXJlID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCgkJJHRoaXMtPnNldF9jb21wb3Nlcl9hdXRoX2Vudl92YXIoKTsKCQkkcGFja2FnZSA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX3BhY2thZ2VfYnlfbmFtZSggJHBhY2thZ2VfbmFtZSApOwoJCWlmICggZmFsc2UgPT09ICRwYWNrYWdlICkgewoJCQkkcGFja2FnZV9uYW1lID0gJHRoaXMtPmdldF9wYWNrYWdlX2J5X3Nob3J0ZW5lZF9pZGVudGlmaWVyKCAkcGFja2FnZV9uYW1lICk7CgkJCWlmICggZmFsc2UgPT09ICRwYWNrYWdlX25hbWUgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnUGFja2FnZSBub3QgaW5zdGFsbGVkLicgKTsKCQkJfQoJCQkkdmVyc2lvbiA9ICJkZXYteyR0aGlzLT5nZXRfZ2l0aHViX2RlZmF1bHRfYnJhbmNoKCAkcGFja2FnZV9uYW1lLCAkaW5zZWN1cmUgKX0iOwoJCQkkbWF0Y2hlcyA9IFtdOwoJCQlpZiAoIHByZWdfbWF0Y2goICcjXig/Omh0dHBzPzovL2dpdGh1YlwuY29tL3xnaXRAZ2l0aHViXC5jb206KSg/PHJlcG9fbmFtZT4uKj8pLmdpdCQjJywgJHBhY2thZ2VfbmFtZSwgJG1hdGNoZXMgKSApIHsKCQkJCSRwYWNrYWdlX25hbWUgPSAkdGhpcy0+Y2hlY2tfZ2l0X3BhY2thZ2VfbmFtZSggJG1hdGNoZXNbJ3JlcG9fbmFtZSddLCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiwgJGluc2VjdXJlICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkcGFja2FnZV9uYW1lID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsgLy8gTWFrZSBzdXJlIHBhY2thZ2UgbmFtZSBpcyB3aGF0J3MgaW4gY29tcG9zZXIuanNvbi4KCQl9CgoJCS8vIFJlYWQgdGhlIFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uIGFuZCBkbyBzb21lIGluaXRpYWwgZXJyb3IgY2hlY2tpbmcuCgkJbGlzdCggJGpzb25fcGF0aCwgJGNvbXBvc2VyX2JhY2t1cCwgJGNvbXBvc2VyX2JhY2t1cF9kZWNvZGVkICkgPSAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb25fcGF0aF9iYWNrdXBfZGVjb2RlZCgpOwoKCQkvLyBSZXZlcnQgb24gc2h1dGRvd24gaWYgYCRyZXZlcnRgIGlzIHRydWUgKHNldCB0byBmYWxzZSBvbiBzdWNjZXNzKS4KCQkkcmV2ZXJ0ID0gdHJ1ZTsKCQkkdGhpcy0+cmVnaXN0ZXJfcmV2ZXJ0X3NodXRkb3duX2Z1bmN0aW9uKCAkanNvbl9wYXRoLCAkY29tcG9zZXJfYmFja3VwLCAkcmV2ZXJ0ICk7CgoJCS8vIFJlbW92ZSB0aGUgJ3JlcXVpcmUnIGZyb20gY29tcG9zZXIuanNvbi4KCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ1JlbW92aW5nIHJlcXVpcmUgc3RhdGVtZW50IGZvciBwYWNrYWdlIFwnJXNcJyBmcm9tICVzJywgJHBhY2thZ2VfbmFtZSwgJGpzb25fcGF0aCApICk7CgkJJG1hbmlwdWxhdG9yID0gbmV3IEpzb25NYW5pcHVsYXRvciggJGNvbXBvc2VyX2JhY2t1cCApOwoJCSRtYW5pcHVsYXRvci0+cmVtb3ZlU3ViTm9kZSggJ3JlcXVpcmUnLCAkcGFja2FnZV9uYW1lLCB0cnVlIC8qY2FzZUluc2Vuc2l0aXZlKi8gKTsKCgkJLy8gUmVtb3ZlIHRoZSAncmVwb3NpdG9yeScgZGV0YWlscyBmcm9tIGNvbXBvc2VyLmpzb24uCgkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdSZW1vdmluZyByZXBvc2l0b3J5IGRldGFpbHMgZnJvbSAlcycsICRqc29uX3BhdGggKSApOwoJCSRtYW5pcHVsYXRvci0+cmVtb3ZlU3ViTm9kZSggJ3JlcG9zaXRvcmllcycsICRwYWNrYWdlX25hbWUsIHRydWUgLypjYXNlSW5zZW5zaXRpdmUqLyApOwoKCQlmaWxlX3B1dF9jb250ZW50cyggJGpzb25fcGF0aCwgJG1hbmlwdWxhdG9yLT5nZXRDb250ZW50cygpICk7CgkJJGNvbXBvc2VyID0gJHRoaXMtPmdldF9jb21wb3NlcigpOwoKCQkvLyBTZXQgdXAgdGhlIGluc3RhbGxlci4KCQkkaW5zdGFsbCA9IEluc3RhbGxlcjo6Y3JlYXRlKCBuZXcgTnVsbElPKCksICRjb21wb3NlciApOwoJCSRpbnN0YWxsLT5zZXRVcGRhdGUoIHRydWUgKTsgLy8gSW5zdGFsbGVyIGNsYXNzIHdpbGwgb25seSBvdmVycmlkZSBjb21wb3Nlci5sb2NrIHdpdGggdGhpcyBmbGFnCgkJJGluc3RhbGwtPnNldFByZWZlclNvdXJjZSggdHJ1ZSApOyAvLyBVc2UgVkNTIHdoZW4gVkNTIGZvciBlYXNpZXIgY29udHJpYnV0aW9ucy4KCgkJV1BfQ0xJOjpsb2coICdSZW1vdmluZyBwYWNrYWdlIGRpcmVjdG9yaWVzIGFuZCByZWdlbmVyYXRpbmcgYXV0b2xvYWRlci4uLicgKTsKCQkkcmVzID0gZmFsc2U7CgkJdHJ5IHsKCQkJJHJlcyA9ICRpbnN0YWxsLT5ydW4oKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgoJCWlmICggMCA9PT0gJHJlcyApIHsKCQkJJHJldmVydCA9IGZhbHNlOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdVbmluc3RhbGxlZCBwYWNrYWdlLicgKTsKCQl9IGVsc2UgewoJCQkkcmVzX21zZyA9ICRyZXMgPyAiIChDb21wb3NlciByZXR1cm4gY29kZSB7JHJlc30pIiA6ICcnOyAvLyAkcmVzIG1heSBiZSBudWxsIGFwcGFyZW50bHkuCgkJCVdQX0NMSTo6ZXJyb3IoICJQYWNrYWdlIHJlbW92YWwgZmFpbGVkeyRyZXNfbXNnfS4iICk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2tzIHdoZXRoZXIgYSBwYWNrYWdlIGlzIGEgV1AtQ0xJIGNvbW11bml0eSBwYWNrYWdlIGJhc2VkCgkgKiBvbiBtZW1iZXJzaGlwIGluIG91ciBwYWNrYWdlIGluZGV4LgoJICoKCSAqIEBwYXJhbSBvYmplY3QgICAgICAkcGFja2FnZSAgICAgQSBwYWNrYWdlIG9iamVjdAoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaXNfY29tbXVuaXR5X3BhY2thZ2UoICRwYWNrYWdlICkgewoJCXJldHVybiAkdGhpcy0+cGFja2FnZV9pbmRleCgpLT5oYXNQYWNrYWdlKCAkcGFja2FnZSApOwoJfQoKCS8qKgoJICogR2V0cyBhIENvbXBvc2VyIGluc3RhbmNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb21wb3NlcigpIHsKCQkkdGhpcy0+YXZvaWRfY29tcG9zZXJfY2FfYnVuZGxlKCk7CgkJdHJ5IHsKCQkJJGNvbXBvc2VyX3BhdGggPSAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb25fcGF0aCgpOwoKCQkJLy8gQ29tcG9zZXIncyBhdXRvLWxvYWQgZ2VuZXJhdGluZyBjb2RlIG1ha2VzIHNvbWUgYXNzdW1wdGlvbnMgYWJvdXQgd2hlcmUKCQkJLy8gdGhlICd2ZW5kb3ItZGlyJyBpcywgYW5kIHdoZXJlIENvbXBvc2VyIGlzIHJ1bm5pbmcgZnJvbS4KCQkJLy8gQmVzdCB0byBqdXN0IHByZXRlbmQgd2UncmUgaW5zdGFsbGluZyBhIHBhY2thZ2UgZnJvbSB+Ly53cC1jbGkgb3Igc2ltaWxhcgoJCQljaGRpciggcGF0aGluZm8oICRjb21wb3Nlcl9wYXRoLCBQQVRISU5GT19ESVJOQU1FICkgKTsKCgkJCS8vIFByZXZlbnQgRGF0ZVRpbWUgZXJyb3Ivd2FybmluZyB3aGVuIG5vIHRpbWV6b25lIHNldC4KCQkJLy8gTm90ZTogVGhlIHBhY2thZ2UgaXMgbG9hZGVkIGJlZm9yZSBXb3JkUHJlc3MgbG9hZCwgRm9yIGVudmlyb25tZW50cyB0aGF0IGRvbid0IGhhdmUgc2V0IHRpbWUgaW4gcGhwLmluaS4KCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLnRpbWV6b25lX2NoYW5nZV9kYXRlX2RlZmF1bHRfdGltZXpvbmVfc2V0LFdvcmRQcmVzcy5QSFAuTm9TaWxlbmNlZEVycm9ycy5EaXNjb3VyYWdlZAoJCQlkYXRlX2RlZmF1bHRfdGltZXpvbmVfc2V0KCBAZGF0ZV9kZWZhdWx0X3RpbWV6b25lX2dldCgpICk7CgoJCQkkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGUoIG5ldyBOdWxsSU8oKSwgJGNvbXBvc2VyX3BhdGggKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnRmFpbGVkIHRvIGdldCBjb21wb3NlciBpbnN0YW5jZTogJXMnLCAkZS0+Z2V0TWVzc2FnZSgpICkgKTsKCQl9CgkJcmV0dXJuICRjb21wb3NlcjsKCX0KCgkvKioKCSAqIEdldHMgYWxsIG9mIHRoZSBjb21tdW5pdHkgcGFja2FnZXMuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb21tdW5pdHlfcGFja2FnZXMoKSB7CgkJc3RhdGljICRjb21tdW5pdHlfcGFja2FnZXM7CgoJCWlmICggbnVsbCA9PT0gJGNvbW11bml0eV9wYWNrYWdlcyApIHsKCQkJJHRoaXMtPmF2b2lkX2NvbXBvc2VyX2NhX2J1bmRsZSgpOwoJCQl0cnkgewoJCQkJJGNvbW11bml0eV9wYWNrYWdlcyA9ICR0aGlzLT5wYWNrYWdlX2luZGV4KCktPmdldFBhY2thZ2VzKCk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGUgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJCX0KCQl9CgoJCXJldHVybiAkY29tbXVuaXR5X3BhY2thZ2VzOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgcGFja2FnZSBpbmRleCBpbnN0YW5jZQoJICoKCSAqIFdlIG5lZWQgdG8gY29uc3RydWN0IHRoZSBpbnN0YW5jZSBtYW51YWxseSwgYmVjYXVzZSB0aGVyZSdzIG5vIHdheSB0byBzZWxlY3QKCSAqIGEgcGFydGljdWxhciBpbnN0YW5jZSB1c2luZyAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCkKCSAqCgkgKiBAcmV0dXJuIENvbXBvc2VyUmVwb3NpdG9yeQoJICovCglwcml2YXRlIGZ1bmN0aW9uIHBhY2thZ2VfaW5kZXgoKSB7CgkJc3RhdGljICRwYWNrYWdlX2luZGV4OwoKCQlpZiAoICEgJHBhY2thZ2VfaW5kZXggKSB7CgkJCSRjb25maWdfYXJncyA9IFsKCQkJCSdjb25maWcnID0+IFsKCQkJCQknc2VjdXJlLWh0dHAnID0+IHRydWUsCgkJCQkJJ2hvbWUnICAgICAgICA9PiBkaXJuYW1lKCAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb25fcGF0aCgpICksCgkJCQldLAoJCQldOwoJCQkkY29uZmlnICAgICAgPSBuZXcgQ29uZmlnKCk7CgkJCSRjb25maWctPm1lcmdlKCAkY29uZmlnX2FyZ3MgKTsKCQkJJGNvbmZpZy0+c2V0Q29uZmlnU291cmNlKCBuZXcgSnNvbkNvbmZpZ1NvdXJjZSggJHRoaXMtPmdldF9jb21wb3Nlcl9qc29uKCkgKSApOwoKCQkJJGlvID0gbmV3IE51bGxJTygpOwoJCQl0cnkgewoJCQkJaWYgKCAkdGhpcy0+aXNfY29tcG9zZXJfdjIoKSApIHsKCQkJCQkkaHR0cF9kb3dubG9hZGVyID0gbmV3IEh0dHBEb3dubG9hZGVyKCAkaW8sICRjb25maWcgKTsKCQkJCQkkcGFja2FnZV9pbmRleCAgID0gbmV3IENvbXBvc2VyUmVwb3NpdG9yeSggWyAndXJsJyA9PiBzZWxmOjpQQUNLQUdFX0lOREVYX1VSTCBdLCAkaW8sICRjb25maWcsICRodHRwX2Rvd25sb2FkZXIgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJHBhY2thZ2VfaW5kZXggPSBuZXcgQ29tcG9zZXJSZXBvc2l0b3J5KCBbICd1cmwnID0+IHNlbGY6OlBBQ0tBR0VfSU5ERVhfVVJMIF0sICRpbywgJGNvbmZpZyApOwoJCQkJfQoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHBhY2thZ2VfaW5kZXg7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5cyBhIHNldCBvZiBwYWNrYWdlcwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKCSAqIEBwYXJhbSBhcnJheQoJICogQHBhcmFtIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gc2hvd19wYWNrYWdlcyggJGNvbnRleHQsICRwYWNrYWdlcywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAnbGlzdCcgPT09ICRjb250ZXh0ICkgewoJCQkkZGVmYXVsdF9maWVsZHMgPSBbCgkJCQknbmFtZScsCgkJCQknYXV0aG9ycycsCgkJCQkndmVyc2lvbicsCgkJCQkndXBkYXRlJywKCQkJCSd1cGRhdGVfdmVyc2lvbicsCgkJCV07CgkJfSBlbHNlaWYgKCAnYnJvd3NlJyA9PT0gJGNvbnRleHQgKSB7CgkJCSRkZWZhdWx0X2ZpZWxkcyA9IFsKCQkJCSduYW1lJywKCQkJCSdkZXNjcmlwdGlvbicsCgkJCQknYXV0aG9ycycsCgkJCQkndmVyc2lvbicsCgkJCV07CgkJfQoJCSRkZWZhdWx0cyAgID0gWwoJCQknZmllbGRzJyA9PiBpbXBsb2RlKCAnLCcsICRkZWZhdWx0X2ZpZWxkcyApLAoJCQknZm9ybWF0JyA9PiAndGFibGUnLAoJCV07CgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoKCQkkY29tcG9zZXIgPSAkdGhpcy0+Z2V0X2NvbXBvc2VyKCk7CgkJJGxpc3QgICAgID0gW107CgkJZm9yZWFjaCAoICRwYWNrYWdlcyBhcyAkcGFja2FnZSApIHsKCQkJJG5hbWUgPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwoJCQlpZiAoIGlzc2V0KCAkbGlzdFsgJG5hbWUgXSApICkgewoJCQkJJGxpc3RbICRuYW1lIF1bJ3ZlcnNpb24nXVtdID0gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKCQkJfSBlbHNlIHsKCQkJCSRwYWNrYWdlX291dHB1dCAgICAgICAgICAgICAgICA9IFtdOwoJCQkJJHBhY2thZ2Vfb3V0cHV0WyduYW1lJ10gICAgICAgID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKCQkJCSRwYWNrYWdlX291dHB1dFsnZGVzY3JpcHRpb24nXSA9ICRwYWNrYWdlLT5nZXREZXNjcmlwdGlvbigpOwoJCQkJJHBhY2thZ2Vfb3V0cHV0WydhdXRob3JzJ10gICAgID0gaW1wbG9kZSggJywgJywgYXJyYXlfY29sdW1uKCAoYXJyYXkpICRwYWNrYWdlLT5nZXRBdXRob3JzKCksICduYW1lJyApICk7CgkJCQkkcGFja2FnZV9vdXRwdXRbJ3ZlcnNpb24nXSAgICAgPSBbICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgXTsKCQkJCSR1cGRhdGUgICAgICAgICAgICAgICAgICAgICAgICA9ICdub25lJzsKCQkJCSR1cGRhdGVfdmVyc2lvbiAgICAgICAgICAgICAgICA9ICcnOwoJCQkJaWYgKCAnbGlzdCcgPT09ICRjb250ZXh0ICkgewoJCQkJCXRyeSB7CgkJCQkJCSRsYXRlc3QgPSAkdGhpcy0+ZmluZF9sYXRlc3RfcGFja2FnZSggJHBhY2thZ2UsICRjb21wb3NlciwgbnVsbCApOwoJCQkJCQlpZiAoICRsYXRlc3QgJiYgJGxhdGVzdC0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAhPT0gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkgKSB7CgkJCQkJCQkkdXBkYXRlICAgICAgICAgPSAnYXZhaWxhYmxlJzsKCQkJCQkJCSR1cGRhdGVfdmVyc2lvbiA9ICRsYXRlc3QtPmdldFByZXR0eVZlcnNpb24oKTsKCQkJCQkJfQoJCQkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGUgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggJGUtPmdldE1lc3NhZ2UoKSApOwoJCQkJCQkkdXBkYXRlICAgICAgICAgPSAnZXJyb3InOwoJCQkJCQkkdXBkYXRlX3ZlcnNpb24gPSAkdXBkYXRlOwoJCQkJCX0KCQkJCX0KCQkJCSRwYWNrYWdlX291dHB1dFsndXBkYXRlJ10gICAgICAgICA9ICR1cGRhdGU7CgkJCQkkcGFja2FnZV9vdXRwdXRbJ3VwZGF0ZV92ZXJzaW9uJ10gPSAkdXBkYXRlX3ZlcnNpb247CgkJCQkkcGFja2FnZV9vdXRwdXRbJ3ByZXR0eV9uYW1lJ10gICAgPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOyAvLyBEZXByZWNhdGVkIGJ1dCBrZXB0IGZvciBCQyB3aXRoIHBhY2thZ2UtY29tbWFuZCAxLjAuOC4KCQkJCSRsaXN0WyAkcGFja2FnZV9vdXRwdXRbJ25hbWUnXSBdICA9ICRwYWNrYWdlX291dHB1dDsKCQkJfQoJCX0KCgkJJGxpc3QgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAkcGFja2FnZSApIHsKCQkJCSRwYWNrYWdlWyd2ZXJzaW9uJ10gPSBpbXBsb2RlKCAnLCAnLCAkcGFja2FnZVsndmVyc2lvbiddICk7CgkJCQlyZXR1cm4gJHBhY2thZ2U7CgkJCX0sCgkJCSRsaXN0CgkJKTsKCgkJa3NvcnQoICRsaXN0ICk7CgkJaWYgKCAnaWRzJyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkkbGlzdCA9IGFycmF5X2tleXMoICRsaXN0ICk7CgkJfQoJCVV0aWxzXGZvcm1hdF9pdGVtcyggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCAkbGlzdCwgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgcGFja2FnZSBieSBpdHMgc2hvcnRlbmVkIGlkZW50aWZpZXIuCgkgKgoJICogQSBzaG9ydGVuZWQgaWRlbnRpZmllciBoYXMgdGhlIGZvcm0gYDx2ZW5kb3I+LzxwYWNrYWdlPmAuCgkgKgoJICogVGhpcyBtZXRob2QgZmlyc3QgY2hlY2tzIHRoZSBkZXByZWNhdGVkIHBhY2thZ2UgaW5kZXgsIGZvciBCQyByZWFzb25zLAoJICogYW5kIHRoZW4gZmFsbHMgYmFjayB0byB0aGUgY29ycmVzcG9uZGluZyBHaXRIdWIgVVJMLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VfbmFtZSBOYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGdldC4KCSAqIEBwYXJhbSBib29sICAgJGluc2VjdXJlICAgICBPcHRpb25hbC4gV2hldGhlciB0byBpbnNlY3VyZWx5IHJldHJ5IGRvd25sb2FkcyB0aGF0IGZhaWxlZCBUTFMgaGFuZHNoYWtlLiBEZWZhdWx0cwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGZhbHNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9wYWNrYWdlX2J5X3Nob3J0ZW5lZF9pZGVudGlmaWVyKCAkcGFja2FnZV9uYW1lLCAkaW5zZWN1cmUgPSBmYWxzZSApIHsKCQkvLyBDaGVjayB0aGUgcGFja2FnZSBpbmRleCBmaXJzdCwgc28gd2UgZG9uJ3QgYnJlYWsgZXhpc3RpbmcgYmVoYXZpb3IuCgkJJGxjX3BhY2thZ2VfbmFtZSA9IHN0cnRvbG93ZXIoICRwYWNrYWdlX25hbWUgKTsgLy8gRm9yIEJDIGNoZWNrLgoJCWZvcmVhY2ggKCAkdGhpcy0+Z2V0X2NvbW11bml0eV9wYWNrYWdlcygpIGFzICRwYWNrYWdlICkgewoJCQlpZiAoICRwYWNrYWdlX25hbWUgPT09ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkgKSB7CgkJCQlyZXR1cm4gJHBhY2thZ2U7CgkJCX0KCQkJLy8gRm9yIEJDIGFsbG93IGdldHRpbmcgYnkgbG93ZXJjYXNlIG5hbWUuCgkJCWlmICggJGxjX3BhY2thZ2VfbmFtZSA9PT0gJHBhY2thZ2UtPmdldE5hbWUoKSApIHsKCQkJCXJldHVybiAkcGFja2FnZTsKCQkJfQoJCX0KCgkJJG9wdGlvbnMgPSBbICdpbnNlY3VyZScgPT4gJGluc2VjdXJlIF07CgoJCS8vIENoZWNrIGlmIHRoZSBwYWNrYWdlIGV4aXN0cyBvbiBQYWNrYWdpc3QuCgkJJHVybCAgICAgID0gImh0dHBzOi8vcmVwby5wYWNrYWdpc3Qub3JnL3AveyRwYWNrYWdlX25hbWV9Lmpzb24iOwoJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICR1cmwsIG51bGwsIFtdLCAkb3B0aW9ucyApOwoJCWlmICggMjAgPT09IChpbnQpIHN1YnN0ciggJHJlc3BvbnNlLT5zdGF0dXNfY29kZSwgMCwgMiApICkgewoJCQlyZXR1cm4gJHBhY2thZ2VfbmFtZTsKCQl9CgoJCS8vIEZhbGwgYmFjayB0byBHaXRIdWIgVVJMIGlmIHdlIGhhZCBubyBtYXRjaCB5ZXQuCgkJJHVybCAgICAgICAgICA9ICJodHRwczovL2dpdGh1Yi5jb20veyRwYWNrYWdlX25hbWV9LmdpdCI7CgkJJGdpdGh1Yl90b2tlbiA9IGdldGVudiggJ0dJVEhVQl9UT0tFTicgKTsgLy8gVXNlIEdJVEhVQl9UT0tFTiBpZiBhdmFpbGFibGUgdG8gYXZvaWQgYXV0aG9yaXphdGlvbiBmYWlsdXJlcyBvciByYXRlLWxpbWl0aW5nLgoJCSRoZWFkZXJzICAgICAgPSAkZ2l0aHViX3Rva2VuID8gWyAnQXV0aG9yaXphdGlvbicgPT4gJ3Rva2VuICcgLiAkZ2l0aHViX3Rva2VuIF0gOiBbXTsKCQkkcmVzcG9uc2UgICAgID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHVybCwgbnVsbCAvKmRhdGEqLywgJGhlYWRlcnMsICRvcHRpb25zICk7CgkJaWYgKCAyMCA9PT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCXJldHVybiAkdXJsOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgaW5zdGFsbGVkIGNvbW11bml0eSBwYWNrYWdlcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfaW5zdGFsbGVkX3BhY2thZ2VzKCkgewoJCSRjb21wb3NlciA9ICR0aGlzLT5nZXRfY29tcG9zZXIoKTsKCgkJJHJlcG8gICAgICAgICAgICAgICAgICAgPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwoJCSRleGlzdGluZyAgICAgICAgICAgICAgID0ganNvbl9kZWNvZGUoIGZpbGVfZ2V0X2NvbnRlbnRzKCAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb25fcGF0aCgpICksIHRydWUgKTsKCQkkaW5zdGFsbGVkX3BhY2thZ2Vfa2V5cyA9ICEgZW1wdHkoICRleGlzdGluZ1sncmVxdWlyZSddICkgPyBhcnJheV9rZXlzKCAkZXhpc3RpbmdbJ3JlcXVpcmUnXSApIDogW107CgkJaWYgKCBlbXB0eSggJGluc3RhbGxlZF9wYWNrYWdlX2tleXMgKSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCQkvLyBGb3IgdXNlIGJ5IGxlZ2FjeSBpbmNvcnJlY3QgbmFtZSBjaGVjay4KCQkkbGNfaW5zdGFsbGVkX3BhY2thZ2Vfa2V5cyA9IGFycmF5X21hcCggJ3N0cnRvbG93ZXInLCAkaW5zdGFsbGVkX3BhY2thZ2Vfa2V5cyApOwoJCSRpbnN0YWxsZWRfcGFja2FnZXMgICAgICAgID0gW107CgkJZm9yZWFjaCAoICRyZXBvLT5nZXRDYW5vbmljYWxQYWNrYWdlcygpIGFzICRwYWNrYWdlICkgewoJCQkkaWR4ID0gYXJyYXlfc2VhcmNoKCAkcGFja2FnZS0+Z2V0TmFtZSgpLCAkbGNfaW5zdGFsbGVkX3BhY2thZ2Vfa2V5cywgdHJ1ZSApOwoJCQkvLyBVc2UgcHJldHR5IG5hbWUgYXMgaXQncyBjYXNlIHNlbnNpdGl2ZSBhbmQgd2hhdCdzIGluIGNvbXBvc2VyLmpzb24gKG9yIGF0IGxlYXN0IHNob3VsZCBiZSkuCgkJCWlmICggaW5fYXJyYXkoICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksICRpbnN0YWxsZWRfcGFja2FnZV9rZXlzLCB0cnVlICkgKSB7CgkJCQkkaW5zdGFsbGVkX3BhY2thZ2VzW10gPSAkcGFja2FnZTsKCQkJfSBlbHNlaWYgKCBmYWxzZSAhPT0gJGlkeCApIHsgLy8gTGVnYWN5IGluY29ycmVjdCBuYW1lIGNoZWNrLgoJCQkJaWYgKCAhICR0aGlzLT5pc19jb21wb3Nlcl92MigpICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggIkZvdW5kIHBhY2thZ2UgJyVzJyBtaXNuYW1lZCAnJXMnIGluICclcycuIiwgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJGluc3RhbGxlZF9wYWNrYWdlX2tleXNbICRpZHggXSwgJHRoaXMtPmdldF9jb21wb3Nlcl9qc29uX3BhdGgoKSApICk7CgkJCQl9CgkJCQkkaW5zdGFsbGVkX3BhY2thZ2VzW10gPSAkcGFja2FnZTsKCQkJfQoJCX0KCQlyZXR1cm4gJGluc3RhbGxlZF9wYWNrYWdlczsKCX0KCgkvKioKCSAqIEdldHMgYW4gaW5zdGFsbGVkIHBhY2thZ2UgYnkgaXRzIG5hbWUuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2luc3RhbGxlZF9wYWNrYWdlX2J5X25hbWUoICRwYWNrYWdlX25hbWUgKSB7CgkJZm9yZWFjaCAoICR0aGlzLT5nZXRfaW5zdGFsbGVkX3BhY2thZ2VzKCkgYXMgJHBhY2thZ2UgKSB7CgkJCWlmICggJHBhY2thZ2VfbmFtZSA9PT0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSApIHsKCQkJCXJldHVybiAkcGFja2FnZTsKCQkJfQoJCQkvLyBBbHNvIGNoZWNrIG5vbi1wcmV0dHkgKGxvd2VyY2FzZSkgbmFtZSBpbiBjYXNlIG9mIGxlZ2FjeSBpbmNvcnJlY3QgbmFtZS4KCQkJaWYgKCAkcGFja2FnZV9uYW1lID09PSAkcGFja2FnZS0+Z2V0TmFtZSgpICkgewoJCQkJcmV0dXJuICRwYWNrYWdlOwoJCQl9CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIENoZWNrcyBpZiB0aGUgcGFja2FnZSBuYW1lIHByb3ZpZGVkIGlzIGFscmVhZHkgaW5zdGFsbGVkLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX3BhY2thZ2VfaW5zdGFsbGVkKCAkcGFja2FnZV9uYW1lICkgewoJCWlmICggJHRoaXMtPmdldF9pbnN0YWxsZWRfcGFja2FnZV9ieV9uYW1lKCAkcGFja2FnZV9uYW1lICkgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0gZWxzZSB7CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIGZyb20gdGhlIGNvbXBvc2VyLmpzb24gaW4gYSBkaXJlY3RvcnkgcGF0aAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGRpcl9wYWNrYWdlCgkgKiBAcmV0dXJuIGFycmF5IFR3by1lbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgcGFja2FnZSBuYW1lIGFuZCB2ZXJzaW9uLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfcGFja2FnZV9uYW1lX2FuZF92ZXJzaW9uX2Zyb21fZGlyX3BhY2thZ2UoICRkaXJfcGFja2FnZSApIHsKCQkkY29tcG9zZXJfZmlsZSA9ICRkaXJfcGFja2FnZSAuICcvY29tcG9zZXIuanNvbic7CgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkY29tcG9zZXJfZmlsZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW52YWxpZCBwYWNrYWdlOiBjb21wb3Nlci5qc29uIGZpbGUgJyVzJyBub3QgZm91bmQuIiwgJGNvbXBvc2VyX2ZpbGUgKSApOwoJCX0KCQkkY29tcG9zZXJfZGF0YSA9IGpzb25fZGVjb2RlKCBmaWxlX2dldF9jb250ZW50cyggJGNvbXBvc2VyX2ZpbGUgKSwgdHJ1ZSApOwoJCWlmICggbnVsbCA9PT0gJGNvbXBvc2VyX2RhdGEgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJJbnZhbGlkIHBhY2thZ2U6IGZhaWxlZCB0byBwYXJzZSBjb21wb3Nlci5qc29uIGZpbGUgJyVzJyBhcyBqc29uLiIsICRjb21wb3Nlcl9maWxlICkgKTsKCQl9CgkJaWYgKCBlbXB0eSggJGNvbXBvc2VyX2RhdGFbJ25hbWUnXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW52YWxpZCBwYWNrYWdlOiBubyBuYW1lIGluIGNvbXBvc2VyLmpzb24gZmlsZSAnJXMnLiIsICRjb21wb3Nlcl9maWxlICkgKTsKCQl9CgkJJHBhY2thZ2VfbmFtZSA9ICRjb21wb3Nlcl9kYXRhWyduYW1lJ107CgkJJHZlcnNpb24gICAgICA9IHNlbGY6OkRFRkFVTFRfREVWX0JSQU5DSF9DT05TVFJBSU5UUzsKCQlpZiAoICEgZW1wdHkoICRjb21wb3Nlcl9kYXRhWyd2ZXJzaW9uJ10gKSApIHsKCQkJJHZlcnNpb24gPSAkY29tcG9zZXJfZGF0YVsndmVyc2lvbiddOwoJCX0KCQlyZXR1cm4gWyAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiBdOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24gb2JqZWN0LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb21wb3Nlcl9qc29uKCkgewoJCXJldHVybiBuZXcgSnNvbkZpbGUoICR0aGlzLT5nZXRfY29tcG9zZXJfanNvbl9wYXRoKCkgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGFic29sdXRlIHBhdGggdG8gdGhlIFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb21wb3Nlcl9qc29uX3BhdGgoKSB7CgkJc3RhdGljICRjb21wb3Nlcl9wYXRoOwoKCQlpZiAoIG51bGwgPT09ICRjb21wb3Nlcl9wYXRoIHx8IGdldGVudiggJ1dQX0NMSV9URVNUX1BBQ0tBR0VfR0VUX0NPTVBPU0VSX0pTT05fUEFUSCcgKSApIHsKCgkJCWlmICggZ2V0ZW52KCAnV1BfQ0xJX1BBQ0tBR0VTX0RJUicgKSApIHsKCQkJCSRjb21wb3Nlcl9wYXRoID0gVXRpbHNcdHJhaWxpbmdzbGFzaGl0KCBnZXRlbnYoICdXUF9DTElfUEFDS0FHRVNfRElSJyApICkgLiAnY29tcG9zZXIuanNvbic7CgkJCX0gZWxzZSB7CgkJCQkkY29tcG9zZXJfcGF0aCA9IFV0aWxzXHRyYWlsaW5nc2xhc2hpdCggVXRpbHNcZ2V0X2hvbWVfZGlyKCkgKSAuICcud3AtY2xpL3BhY2thZ2VzL2NvbXBvc2VyLmpzb24nOwoJCQl9CgoJCQkvLyBgY29tcG9zZXIuanNvbmAgYW5kIGl0cyBkaXJlY3RvcnkgbWlnaHQgbmVlZCB0byBiZSBjcmVhdGVkCgkJCWlmICggISBmaWxlX2V4aXN0cyggJGNvbXBvc2VyX3BhdGggKSApIHsKCQkJCSRjb21wb3Nlcl9wYXRoID0gJHRoaXMtPmNyZWF0ZV9kZWZhdWx0X2NvbXBvc2VyX2pzb24oICRjb21wb3Nlcl9wYXRoICk7CgkJCX0gZWxzZSB7CgkJCQkkY29tcG9zZXJfcGF0aCA9IHJlYWxwYXRoKCAkY29tcG9zZXJfcGF0aCApOwoJCQkJaWYgKCBmYWxzZSA9PT0gJGNvbXBvc2VyX3BhdGggKSB7CgkJCQkJJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiQ29tcG9zZXIgcGF0aCAnJXMnIGZvciBwYWNrYWdlcy9jb21wb3Nlci5qc29uIG5vdCBmb3VuZDogJXMiLCAkY29tcG9zZXJfcGF0aCwgJGVycm9yWydtZXNzYWdlJ10gKSApOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gJGNvbXBvc2VyX3BhdGg7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBXUC1DTEkgdmVyc2lvbiBmb3IgY29tcG9zZXIuanNvbgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfd3BfY2xpX3ZlcnNpb25fY29tcG9zZXIoKSB7CgkJcHJlZ19tYXRjaCggJyNeWzAtOVwuXSsoLShhbHBoYXxiZXRhKVteLV17MCx9KT8jJywgV1BfQ0xJX1ZFUlNJT04sICRtYXRjaGVzICk7CgkJJHZlcnNpb24gPSBpc3NldCggJG1hdGNoZXNbMF0gKSA/ICRtYXRjaGVzWzBdIDogJyc7CgkJcmV0dXJuICR2ZXJzaW9uOwoJfQoKCS8qKgoJICogQ3JlYXRlcyBhIGRlZmF1bHQgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29tcG9zZXJfcGF0aCBXaGVyZSB0aGUgY29tcG9zZXIuanNvbiBzaG91bGQgYmUgY3JlYXRlZAoJICogQHJldHVybiBzdHJpbmcgUmV0dXJucyB0aGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgbmV3bHkgY3JlYXRlZCBkZWZhdWx0IFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZV9kZWZhdWx0X2NvbXBvc2VyX2pzb24oICRjb21wb3Nlcl9wYXRoICkgewoKCQkkY29tcG9zZXJfZGlyID0gcGF0aGluZm8oICRjb21wb3Nlcl9wYXRoLCBQQVRISU5GT19ESVJOQU1FICk7CgkJaWYgKCAhIGlzX2RpciggJGNvbXBvc2VyX2RpciApICkgewoJCQlpZiAoICEgQG1rZGlyKCAkY29tcG9zZXJfZGlyLCAwNzc3LCB0cnVlICkgKSB7IC8vIEBjb2RpbmdTdGFuZGFyZHNJZ25vcmVMaW5lCgkJCQkkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwoJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkNvbXBvc2VyIGRpcmVjdG9yeSAnJXMnIGZvciBwYWNrYWdlcyBjb3VsZG4ndCBiZSBjcmVhdGVkOiAlcyIsICRjb21wb3Nlcl9kaXIsICRlcnJvclsnbWVzc2FnZSddICkgKTsKCQkJfQoJCX0KCgkJJGNvbXBvc2VyX2RpciA9IHJlYWxwYXRoKCAkY29tcG9zZXJfZGlyICk7CgkJaWYgKCBmYWxzZSA9PT0gJGNvbXBvc2VyX2RpciApIHsKCQkJJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkNvbXBvc2VyIGRpcmVjdG9yeSAnJXMnIGZvciBwYWNrYWdlcyBub3QgZm91bmQ6ICVzIiwgJGNvbXBvc2VyX2RpciwgJGVycm9yWydtZXNzYWdlJ10gKSApOwoJCX0KCgkJJGNvbXBvc2VyX3BhdGggPSBVdGlsc1x0cmFpbGluZ3NsYXNoaXQoICRjb21wb3Nlcl9kaXIgKSAuIFV0aWxzXGJhc2VuYW1lKCAkY29tcG9zZXJfcGF0aCApOwoKCQkkanNvbl9maWxlID0gbmV3IEpzb25GaWxlKCAkY29tcG9zZXJfcGF0aCApOwoKCQkkcmVwb3NpdG9yaWVzID0gKG9iamVjdCkgWwoJCQknd3AtY2xpJyA9PiAob2JqZWN0KSAkdGhpcy0+Y29tcG9zZXJfdHlwZV9wYWNrYWdlLAoJCV07CgoJCSRvcHRpb25zID0gWwoJCQknbmFtZScgICAgICAgICAgICAgID0+ICd3cC1jbGkvd3AtY2xpJywKCQkJJ2Rlc2NyaXB0aW9uJyAgICAgICA9PiAnSW5zdGFsbGVkIGNvbW11bml0eSBwYWNrYWdlcyB1c2VkIGJ5IFdQLUNMSScsCgkJCSd2ZXJzaW9uJyAgICAgICAgICAgPT4gc2VsZjo6Z2V0X3dwX2NsaV92ZXJzaW9uX2NvbXBvc2VyKCksCgkJCSdhdXRob3JzJyAgICAgICAgICAgPT4gWyAob2JqZWN0KSAkdGhpcy0+YXV0aG9yX2RhdGEgXSwKCQkJJ2hvbWVwYWdlJyAgICAgICAgICA9PiBzZWxmOjpQQUNLQUdFX0lOREVYX1VSTCwKCQkJJ3JlcXVpcmUnICAgICAgICAgICA9PiBuZXcgc3RkQ2xhc3MoKSwKCQkJJ3JlcXVpcmUtZGV2JyAgICAgICA9PiBuZXcgc3RkQ2xhc3MoKSwKCQkJJ21pbmltdW0tc3RhYmlsaXR5JyA9PiAnZGV2JywKCQkJJ3ByZWZlci1zdGFibGUnICAgICA9PiB0cnVlLAoJCQknbGljZW5zZScgICAgICAgICAgID0+ICdNSVQnLAoJCQkncmVwb3NpdG9yaWVzJyAgICAgID0+ICRyZXBvc2l0b3JpZXMsCgkJXTsKCgkJdHJ5IHsKCQkJJGpzb25fZmlsZS0+d3JpdGUoICRvcHRpb25zICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJcmV0dXJuICRjb21wb3Nlcl9wYXRoOwoJfQoKCS8qKgoJICogR2l2ZW4gYSBwYWNrYWdlLCB0aGlzIGZpbmRzIHRoZSBsYXRlc3QgcGFja2FnZSBtYXRjaGluZyBpdAoJICoKCSAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQoJICogQHBhcmFtICBDb21wb3NlciAgICAgICAgICRjb21wb3NlcgoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRwaHBWZXJzaW9uCgkgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgJG1pbm9yT25seQoJICoKCSAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZXxudWxsCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZmluZF9sYXRlc3RfcGFja2FnZSggUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgQ29tcG9zZXIgJGNvbXBvc2VyLCAkcGhwX3ZlcnNpb24sICRtaW5vcl9vbmx5ID0gZmFsc2UgKSB7CgkJLy8gRmluZCB0aGUgbGF0ZXN0IHZlcnNpb24gYWxsb3dlZCBpbiB0aGlzIHBvb2wvcmVwb3NpdG9yeSBzZXQuCgkJJG5hbWUgICAgICAgICAgICAgPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwoJCSR2ZXJzaW9uX3NlbGVjdG9yID0gJHRoaXMtPmdldF92ZXJzaW9uX3NlbGVjdG9yKCAkY29tcG9zZXIgKTsKCQkkc3RhYmlsaXR5ICAgICAgICA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCk7CgkJJGZsYWdzICAgICAgICAgICAgPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKTsKCQlpZiAoIGlzc2V0KCAkZmxhZ3NbICRuYW1lIF0gKSApIHsKCQkJJHN0YWJpbGl0eSA9IGFycmF5X3NlYXJjaCggJGZsYWdzWyAkbmFtZSBdLCBCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzLCB0cnVlICk7CgkJfQoJCSRiZXN0X3N0YWJpbGl0eSA9ICRzdGFiaWxpdHk7CgkJaWYgKCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0UHJlZmVyU3RhYmxlKCkgKSB7CgkJCSRiZXN0X3N0YWJpbGl0eSA9ICRwYWNrYWdlLT5nZXRTdGFiaWxpdHkoKTsKCQl9CgkJJHRhcmdldF92ZXJzaW9uID0gbnVsbDsKCQlpZiAoIDAgPT09IHN0cnBvcyggJHBhY2thZ2UtPmdldFZlcnNpb24oKSwgJ2Rldi0nICkgKSB7CgkJCSR0YXJnZXRfdmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CgkJfQoJCWlmICggbnVsbCA9PT0gJHRhcmdldF92ZXJzaW9uICYmICRtaW5vcl9vbmx5ICkgewoJCQkkdGFyZ2V0X3ZlcnNpb24gPSAnXicgLiAkcGFja2FnZS0+Z2V0VmVyc2lvbigpOwoJCX0KCgkJaWYgKCAkdGhpcy0+aXNfY29tcG9zZXJfdjIoKSApIHsKCQkJcmV0dXJuICR2ZXJzaW9uX3NlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSggJG5hbWUsICR0YXJnZXRfdmVyc2lvbiwgJGJlc3Rfc3RhYmlsaXR5ICk7CgkJfQoKCQlyZXR1cm4gJHZlcnNpb25fc2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCAkbmFtZSwgJHRhcmdldF92ZXJzaW9uLCAkcGhwX3ZlcnNpb24sICRiZXN0X3N0YWJpbGl0eSApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3ZlcnNpb25fc2VsZWN0b3IoIENvbXBvc2VyICRjb21wb3NlciApIHsKCQlpZiAoICEgJHRoaXMtPnZlcnNpb25fc2VsZWN0b3IgKSB7CgkJCWlmICggJHRoaXMtPmlzX2NvbXBvc2VyX3YyKCkgKSB7CgkJCQkkcmVwb3NpdG9yeV9zZXQgPSBuZXcgUmVwb3NpdG9yeVxSZXBvc2l0b3J5U2V0KAoJCQkJCSRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCksCgkJCQkJJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldFN0YWJpbGl0eUZsYWdzKCkKCQkJCSk7CgkJCQkkcmVwb3NpdG9yeV9zZXQtPmFkZFJlcG9zaXRvcnkoIG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpICkgKTsKCQkJCSR0aGlzLT52ZXJzaW9uX3NlbGVjdG9yID0gbmV3IFZlcnNpb25TZWxlY3RvciggJHJlcG9zaXRvcnlfc2V0ICk7CgkJCX0gZWxzZSB7CgkJCQkkcG9vbCA9IG5ldyBQb29sKCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0TWluaW11bVN0YWJpbGl0eSgpLCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKSApOwoJCQkJJHBvb2wtPmFkZFJlcG9zaXRvcnkoIG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpICkgKTsKCQkJCSR0aGlzLT52ZXJzaW9uX3NlbGVjdG9yID0gbmV3IFZlcnNpb25TZWxlY3RvciggJHBvb2wgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICR0aGlzLT52ZXJzaW9uX3NlbGVjdG9yOwoJfQoKCS8qKgoJICogQ2hlY2tzIHdoZXRoZXIgYSBnaXZlbiBwYWNrYWdlIGlzIGEgZ2l0IHJlcG9zaXRvcnkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGFja2FnZSBQYWNrYWdlIG5hbWUgdG8gY2hlY2suCgkgKgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHBhY2thZ2UgaXMgYSBnaXQgcmVwb3NpdG9yeS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpc19naXRfcmVwb3NpdG9yeSggJHBhY2thZ2UgKSB7CgkJcmV0dXJuICcuZ2l0JyA9PT0gc3RydG9sb3dlciggc3Vic3RyKCAkcGFja2FnZSwgLTQsIDQgKSApOwoJfQoKCS8qKgoJICogQ2hlY2tzIHRoYXQgYCRwYWNrYWdlX25hbWVgIG1hdGNoZXMgdGhlIG5hbWUgaW4gY29tcG9zZXIuanNvbiBhdCBHaXRodWIuY29tLCBhbmQgcmV0dXJuIGNvcnJlY3RlZCB2YWx1ZSBpZiBub3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGFja2FnZV9uYW1lIFBhY2thZ2UgbmFtZSB0byBjaGVjay4KCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gICAgICBPcHRpb25hbC4gUGFja2FnZSB2ZXJzaW9uLiBEZWZhdWx0cyB0byBlbXB0eSBzdHJpbmcuCgkgKiBAcGFyYW0gYm9vbCAgICRpbnNlY3VyZSAgICAgT3B0aW9uYWwuIFdoZXRoZXIgdG8gaW5zZWN1cmVseSByZXRyeSBkb3dubG9hZHMgdGhhdCBmYWlsZWQgVExTIGhhbmRzaGFrZS4gRGVmYXVsdHMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBmYWxzZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19naXRodWJfcGFja2FnZV9uYW1lKCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiA9ICcnLCAkaW5zZWN1cmUgPSBmYWxzZSApIHsKCQkkZ2l0aHViX3Rva2VuID0gZ2V0ZW52KCAnR0lUSFVCX1RPS0VOJyApOyAvLyBVc2UgR0lUSFVCX1RPS0VOIGlmIGF2YWlsYWJsZSB0byBhdm9pZCBhdXRob3JpemF0aW9uIGZhaWx1cmVzIG9yIHJhdGUtbGltaXRpbmcuCgkJJGhlYWRlcnMgICAgICA9ICRnaXRodWJfdG9rZW4gPyBbICdBdXRob3JpemF0aW9uJyA9PiAndG9rZW4gJyAuICRnaXRodWJfdG9rZW4gXSA6IFtdOwoJCSRvcHRpb25zICAgICAgPSBbICdpbnNlY3VyZScgPT4gJGluc2VjdXJlIF07CgoJCS8vIEdlbmVyYXRlIHJhdyBnaXQgVVJMIG9mIGNvbXBvc2VyLmpzb24gZmlsZS4KCQkkcmF3X2NvbnRlbnRfdXJsID0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS97JHBhY2thZ2VfbmFtZX0veyR0aGlzLT5nZXRfcmF3X2dpdF92ZXJzaW9uKCAkdmVyc2lvbiApfS9jb21wb3Nlci5qc29uIjsKCgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHJhd19jb250ZW50X3VybCwgbnVsbCAvKmRhdGEqLywgJGhlYWRlcnMsICRvcHRpb25zICk7CgkJaWYgKCAyMCAhPT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCS8vIENvdWxkIG5vdCBnZXQgY29tcG9zZXIuanNvbi4gUG9zc2libHkgcHJpdmF0ZSBzbyB3YXJuIGFuZCByZXR1cm4gYmVzdCBndWVzcyBmcm9tIGlucHV0IChhbHdheXMgeHh4L3h4eCkuCgkJCVdQX0NMSTo6d2FybmluZygKCQkJCXNwcmludGYoCgkJCQkJIkNvdWxkbid0IGRvd25sb2FkIGNvbXBvc2VyLmpzb24gZmlsZSBmcm9tICclcycgKEhUVFAgY29kZSAlZCkuIFByZXN1bWluZyBwYWNrYWdlIG5hbWUgaXMgJyVzJy4iLAoJCQkJCSRyYXdfY29udGVudF91cmwsCgkJCQkJJHJlc3BvbnNlLT5zdGF0dXNfY29kZSwKCQkJCQkkcGFja2FnZV9uYW1lCgkJCQkpCgkJCSk7CgkJCXJldHVybiAkcGFja2FnZV9uYW1lOwoJCX0KCgkJLy8gQ29udmVydCBjb21wb3Nlci5qc29uIEpTT04gdG8gQXJyYXkuCgkJJGNvbXBvc2VyX2NvbnRlbnRfYXNfYXJyYXkgPSBqc29uX2RlY29kZSggJHJlc3BvbnNlLT5ib2R5LCB0cnVlICk7CgkJaWYgKCBudWxsID09PSAkY29tcG9zZXJfY29udGVudF9hc19hcnJheSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkZhaWxlZCB0byBwYXJzZSAnJXMnIGFzIGpzb24uIiwgJHJhd19jb250ZW50X3VybCApICk7CgkJfQoJCWlmICggZW1wdHkoICRjb21wb3Nlcl9jb250ZW50X2FzX2FycmF5WyduYW1lJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkludmFsaWQgcGFja2FnZTogbm8gbmFtZSBpbiBjb21wb3Nlci5qc29uIGZpbGUgJyVzJy4iLCAkcmF3X2NvbnRlbnRfdXJsICkgKTsKCQl9CgoJCS8vIFBhY2thZ2UgbmFtZSBpbiBjb21wb3Nlci5qc29uIHRoYXQgaXMgaG9zdGVkIG9uIEdpdEh1Yi4KCQkkcGFja2FnZV9uYW1lX29uX3JlcG8gPSAkY29tcG9zZXJfY29udGVudF9hc19hcnJheVsnbmFtZSddOwoKCQkvLyBJZiBwYWNrYWdlIG5hbWUgYW5kIHJlcG9zaXRvcnkgbmFtZSBhcmUgbm90IGlkZW50aWNhbCwgdGhlbiBmaXggaXQuCgkJaWYgKCAkcGFja2FnZV9uYW1lICE9PSAkcGFja2FnZV9uYW1lX29uX3JlcG8gKSB7CgkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggIlBhY2thZ2UgbmFtZSBtaXNtYXRjaC4uLlVwZGF0aW5nIGZyb20gZ2l0IG5hbWUgJyVzJyB0byBjb21wb3Nlci5qc29uIG5hbWUgJyVzJy4iLCAkcGFja2FnZV9uYW1lLCAkcGFja2FnZV9uYW1lX29uX3JlcG8gKSApOwoJCQkkcGFja2FnZV9uYW1lID0gJHBhY2thZ2VfbmFtZV9vbl9yZXBvOwoJCX0KCgkJcmV0dXJuICRwYWNrYWdlX25hbWU7Cgl9CgoJLyoqCgkgKiBDaGVja3MgdGhhdCBgJHBhY2thZ2VfbmFtZWAgbWF0Y2hlcyB0aGUgbmFtZSBpbiBjb21wb3Nlci5qc29uIGF0IHRoZSBjb3JyZXNwb25kaW5nIHVwc3RyZWFtIHJlcG9zaXRvcnksIGFuZCByZXR1cm4gY29ycmVjdGVkIHZhbHVlIGlmIG5vdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlX25hbWUgUGFja2FnZSBuYW1lIHRvIGNoZWNrLgoJICogQHBhcmFtIHN0cmluZyAkdXJsICAgICAgICAgIFVSTCB0byBmZXRjaCB0aGUgcGFja2FnZSBmcm9tLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiAgICAgIE9wdGlvbmFsLiBQYWNrYWdlIHZlcnNpb24uIERlZmF1bHRzIHRvIGVtcHR5IHN0cmluZy4KCSAqIEBwYXJhbSBib29sICAgJGluc2VjdXJlICAgICBPcHRpb25hbC4gV2hldGhlciB0byBpbnNlY3VyZWx5IHJldHJ5IGRvd25sb2FkcyB0aGF0IGZhaWxlZCBUTFMgaGFuZHNoYWtlLiBEZWZhdWx0cwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGZhbHNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2dpdF9wYWNrYWdlX25hbWUoICRwYWNrYWdlX25hbWUsICR1cmwgPSAnJywgJHZlcnNpb24gPSAnJywgJGluc2VjdXJlID0gZmFsc2UgKSB7CgkJaWYgKCAkdXJsICYmICggc3RycG9zKCAkdXJsLCAnOi8vZ2l0bGFiLmNvbS8nICkgIT09IGZhbHNlICkgfHwgKCBzdHJwb3MoICR1cmwsICdnaXRAZ2l0bGFiLmNvbTonICkgIT09IGZhbHNlICkgKSB7CgkJCXJldHVybiAkdGhpcy0+Y2hlY2tfZ2l0bGFiX3BhY2thZ2VfbmFtZSggJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24sICRpbnNlY3VyZSApOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5jaGVja19naXRodWJfcGFja2FnZV9uYW1lKCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiwgJGluc2VjdXJlICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgdGhhdCBgJHBhY2thZ2VfbmFtZWAgbWF0Y2hlcyB0aGUgbmFtZSBpbiBjb21wb3Nlci5qc29uIGF0IEdpdExhYi5jb20sIGFuZCByZXR1cm4gY29ycmVjdGVkIHZhbHVlIGlmIG5vdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlX25hbWUgUGFja2FnZSBuYW1lIHRvIGNoZWNrLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiAgICAgIE9wdGlvbmFsLiBQYWNrYWdlIHZlcnNpb24uIERlZmF1bHRzIHRvIGVtcHR5IHN0cmluZy4KCSAqIEBwYXJhbSBib29sICAgJGluc2VjdXJlICAgICBPcHRpb25hbC4gV2hldGhlciB0byBpbnNlY3VyZWx5IHJldHJ5IGRvd25sb2FkcyB0aGF0IGZhaWxlZCBUTFMgaGFuZHNoYWtlLiBEZWZhdWx0cwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGZhbHNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2dpdGxhYl9wYWNrYWdlX25hbWUoICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uID0gJycsICRpbnNlY3VyZSA9IGZhbHNlICkgewoJCS8vIEdlbmVyYXRlIHJhdyBnaXQgVVJMIG9mIGNvbXBvc2VyLmpzb24gZmlsZS4KCQkkcmF3X2NvbnRlbnRfcHVibGljX3VybCAgPSAnaHR0cHM6Ly9naXRsYWIuY29tLycgLiAkcGFja2FnZV9uYW1lIC4gJy8tL3Jhdy8nIC4gJHRoaXMtPmdldF9yYXdfZ2l0X3ZlcnNpb24oICR2ZXJzaW9uICkgLiAnL2NvbXBvc2VyLmpzb24nOwoJCSRyYXdfY29udGVudF9wcml2YXRlX3VybCA9ICdodHRwczovL2dpdGxhYi5jb20vYXBpL3Y0L3Byb2plY3RzLycgLiByYXd1cmxlbmNvZGUoICRwYWNrYWdlX25hbWUgKSAuICcvcmVwb3NpdG9yeS9maWxlcy9jb21wb3Nlci5qc29uL3Jhdz9yZWY9JyAuICR0aGlzLT5nZXRfcmF3X2dpdF92ZXJzaW9uKCAkdmVyc2lvbiApOwoKCQkkb3B0aW9ucyA9IFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXTsKCgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHJhd19jb250ZW50X3B1YmxpY191cmwsIG51bGwgLypkYXRhKi8sIFtdLCAkb3B0aW9ucyApOwoJCWlmICggJHJlc3BvbnNlLT5zdGF0dXNfY29kZSA8IDIwMCB8fCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlID49IDMwMCApIHsKCQkJLy8gQ291bGQgbm90IGdldCBjb21wb3Nlci5qc29uLiBQb3NzaWJseSBwcml2YXRlIHNvIHdhcm4gYW5kIHJldHVybiBiZXN0IGd1ZXNzIGZyb20gaW5wdXQgKGFsd2F5cyB4eHgveHh4KS4KCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiQ291bGRuJ3QgZG93bmxvYWQgY29tcG9zZXIuanNvbiBmaWxlIGZyb20gJyVzJyAoSFRUUCBjb2RlICVkKS4gUHJlc3VtaW5nIHBhY2thZ2UgbmFtZSBpcyAnJXMnLiIsICRyYXdfY29udGVudF9wdWJsaWNfdXJsLCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAkcGFja2FnZV9uYW1lICkgKTsKCQkJcmV0dXJuICRwYWNrYWdlX25hbWU7CgkJfQoKCQlpZiAoIHN0cnBvcyggJHJlc3BvbnNlLT5oZWFkZXJzWydjb250ZW50LXR5cGUnXSwgJ3RleHQvaHRtbCcgKSA9PT0gMCApIHsKCQkJJGdpdGxhYl90b2tlbiA9IGdldGVudiggJ0dJVExBQl9UT0tFTicgKTsgLy8gVXNlIEdJVExBQl9UT0tFTiBpZiBhdmFpbGFibGUgdG8gYXZvaWQgYXV0aG9yaXphdGlvbiBmYWlsdXJlcyBvciByYXRlLWxpbWl0aW5nLgoJCQkkaGVhZGVycyAgICAgID0gJGdpdGxhYl90b2tlbiA/IFsgJ1BSSVZBVEUtVE9LRU4nID0+ICRnaXRsYWJfdG9rZW4gXSA6IFtdOwoJCQkkcmVzcG9uc2UgICAgID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHJhd19jb250ZW50X3ByaXZhdGVfdXJsLCBudWxsIC8qZGF0YSovLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCgkJCWlmICggJHJlc3BvbnNlLT5zdGF0dXNfY29kZSA8IDIwMCB8fCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlID49IDMwMCApIHsKCQkJCS8vIENvdWxkIG5vdCBnZXQgY29tcG9zZXIuanNvbi4gUG9zc2libHkgcHJpdmF0ZSBzbyB3YXJuIGFuZCByZXR1cm4gYmVzdCBndWVzcyBmcm9tIGlucHV0IChhbHdheXMgeHh4L3h4eCkuCgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJDb3VsZG4ndCBkb3dubG9hZCBjb21wb3Nlci5qc29uIGZpbGUgZnJvbSAnJXMnIChIVFRQIGNvZGUgJWQpLiBQcmVzdW1pbmcgcGFja2FnZSBuYW1lIGlzICclcycuIiwgJHJhd19jb250ZW50X3ByaXZhdGVfdXJsLCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAkcGFja2FnZV9uYW1lICkgKTsKCQkJCXJldHVybiAkcGFja2FnZV9uYW1lOwoJCQl9CgkJfQoKCQkvLyBDb252ZXJ0IGNvbXBvc2VyLmpzb24gSlNPTiB0byBBcnJheS4KCQkkY29tcG9zZXJfY29udGVudF9hc19hcnJheSA9IGpzb25fZGVjb2RlKCAkcmVzcG9uc2UtPmJvZHksIHRydWUgKTsKCQlpZiAoIG51bGwgPT09ICRjb21wb3Nlcl9jb250ZW50X2FzX2FycmF5ICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiRmFpbGVkIHRvIHBhcnNlICclcycgYXMganNvbi4iLCAkcmVzcG9uc2UtPnVybCApICk7CgkJfQoJCWlmICggZW1wdHkoICRjb21wb3Nlcl9jb250ZW50X2FzX2FycmF5WyduYW1lJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkludmFsaWQgcGFja2FnZTogbm8gbmFtZSBpbiBjb21wb3Nlci5qc29uIGZpbGUgJyVzJy4iLCAkcmVzcG9uc2UtPnVybCApICk7CgkJfQoKCQkvLyBQYWNrYWdlIG5hbWUgaW4gY29tcG9zZXIuanNvbiB0aGF0IGlzIGhvc3RlZCBvbiBHaXRsYWIuCgkJJHBhY2thZ2VfbmFtZV9vbl9yZXBvID0gJGNvbXBvc2VyX2NvbnRlbnRfYXNfYXJyYXlbJ25hbWUnXTsKCgkJLy8gSWYgcGFja2FnZSBuYW1lIGFuZCByZXBvc2l0b3J5IG5hbWUgYXJlIG5vdCBpZGVudGljYWwsIHRoZW4gZml4IGl0LgoJCWlmICggJHBhY2thZ2VfbmFtZSAhPT0gJHBhY2thZ2VfbmFtZV9vbl9yZXBvICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJQYWNrYWdlIG5hbWUgbWlzbWF0Y2guLi5VcGRhdGluZyBmcm9tIGdpdCBuYW1lICclcycgdG8gY29tcG9zZXIuanNvbiBuYW1lICclcycuIiwgJHBhY2thZ2VfbmFtZSwgJHBhY2thZ2VfbmFtZV9vbl9yZXBvICkgKTsKCQkJJHBhY2thZ2VfbmFtZSA9ICRwYWNrYWdlX25hbWVfb25fcmVwbzsKCQl9CgkJcmV0dXJuICRwYWNrYWdlX25hbWU7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHZlcnNpb24gdG8gdXNlIGZvciByYXcgR2l0SHViIHJlcXVlc3QuIFZlcnkgYmFzaWMuCgkgKgoJICogQHN0cmluZyAkdmVyc2lvbiBQYWNrYWdlIHZlcnNpb24uCgkgKiBAc3RyaW5nIFZlcnNpb24gdG8gdXNlIGZvciBHaXRIdWIgcmVxdWVzdC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcmF3X2dpdF92ZXJzaW9uKCAkdmVyc2lvbiApIHsKCQlpZiAoICcnID09PSAkdmVyc2lvbiApIHsKCQkJcmV0dXJuICdtYXN0ZXInOwoJCX0KCgkJLy8gSWYgQ29tcG9zZXIgaGFzaCBnaXZlbiB0aGVuIGp1c3QgdXNlIHdoYXRldmVyJ3MgYWZ0ZXIgaXQuCgkJJGhhc2hfcG9zID0gc3RycG9zKCAkdmVyc2lvbiwgJyMnICk7CgkJaWYgKCBmYWxzZSAhPT0gJGhhc2hfcG9zICkgewoJCQlyZXR1cm4gc3Vic3RyKCAkdmVyc2lvbiwgJGhhc2hfcG9zICsgMSApOwoJCX0KCgkJLy8gU3RyaXAgYW55IENvbXBvc2VyICdkZXYtJyBwcmVmaXguCgkJaWYgKCAwID09PSBzdHJuY21wKCAkdmVyc2lvbiwgJ2Rldi0nLCA0ICkgKSB7CgkJCSR2ZXJzaW9uID0gc3Vic3RyKCAkdmVyc2lvbiwgNCApOwoJCX0KCgkJLy8gSWdub3JlL3N0cmlwIGFueSByZWxhdGl2ZSBzdWZmaXhlcy4KCQlyZXR1cm4gc3RyX3JlcGxhY2UoIFsgJ14nLCAnficgXSwgJycsICR2ZXJzaW9uICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSByZWxlYXNlIHRhZyBmb3IgdGhlIGxhdGVzdCBzdGFibGUgcmVsZWFzZSBvZiBhIEdpdEh1YiByZXBvc2l0b3J5LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VfbmFtZSBOYW1lIG9mIHRoZSByZXBvc2l0b3J5LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFJlbGVhc2UgdGFnLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9naXRodWJfbGF0ZXN0X3JlbGVhc2VfdGFnKCAkcGFja2FnZV9uYW1lLCAkaW5zZWN1cmUgKSB7CgkJJHVybCAgICAgID0gImh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MveyRwYWNrYWdlX25hbWV9L3JlbGVhc2VzL2xhdGVzdCI7CgkJJG9wdGlvbnMgID0gWyAnaW5zZWN1cmUnID0+ICRpbnNlY3VyZSBdOwoJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICR1cmwsIG51bGwsIFtdLCAkb3B0aW9ucyApOwoJCWlmICggMjAgIT09IChpbnQpIHN1YnN0ciggJHJlc3BvbnNlLT5zdGF0dXNfY29kZSwgMCwgMiApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdDb3VsZCBub3QgZ3Vlc3Mgc3RhYmxlIHZlcnNpb24gZnJvbSBHaXRIdWIgcmVwb3NpdG9yeSwgZmFsbGluZyBiYWNrIHRvIG1hc3RlciBicmFuY2gnICk7CgkJCXJldHVybiAnbWFzdGVyJzsKCQl9CgoJCSRwYWNrYWdlX2RhdGEgPSBqc29uX2RlY29kZSggJHJlc3BvbnNlLT5ib2R5ICk7CgkJaWYgKCBKU09OX0VSUk9SX05PTkUgIT09IGpzb25fbGFzdF9lcnJvcigpICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdDb3VsZCBub3QgZ3Vlc3Mgc3RhYmxlIHZlcnNpb24gZnJvbSBHaXRIdWIgcmVwb3NpdG9yeSwgZmFsbGluZyBiYWNrIHRvIG1hc3RlciBicmFuY2gnICk7CgkJCXJldHVybiAnbWFzdGVyJzsKCQl9CgoJCSR0YWcgPSAkcGFja2FnZV9kYXRhLT50YWdfbmFtZTsKCQlXUF9DTEk6OmRlYnVnKCAiRXh0cmFjdGVkIGxhdGVzdCBzdGFibGUgcmVsZWFzZSB0YWc6IHskdGFnfSIsICdwYWNrYWdlcycgKTsKCgkJcmV0dXJuICR0YWc7Cgl9CgoJLyoqCgkgKiBHdWVzc2VzIHRoZSB2ZXJzaW9uIGNvbnN0cmFpbnQgZnJvbSBhIHJlbGVhc2UgdGFnLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRhZyBSZWxlYXNlIHRhZyB0byBndWVzcyB0aGUgdmVyc2lvbiBjb25zdHJhaW50IGZyb20uCgkgKgoJICogQHJldHVybiBzdHJpbmcgVmVyc2lvbiBjb25zdHJhaW50LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGd1ZXNzX3ZlcnNpb25fY29uc3RyYWludF9mcm9tX3RhZyggJHRhZyApIHsKCQkkbWF0Y2hlcyA9IFtdOwoJCWlmICggMSAhPT0gcHJlZ19tYXRjaCggJy8oPzp2ZXJzaW9ufHYpXHMqKCg/OlswLTldK1wuPykrKSg/Oi0uKikvaScsICR0YWcsICRtYXRjaGVzICkgKSB7CgkJCXJldHVybiAkdGFnOwoJCX0KCgkJJGNvbnN0cmFpbnQgPSAiXnskbWF0Y2hlc1sxXX0iOwoJCVdQX0NMSTo6ZGVidWcoICJHdWVzc2luZyB2ZXJzaW9uIGNvbnN0cmFpbnQgdG8gdXNlOiB7JGNvbnN0cmFpbnR9IiwgJ3BhY2thZ2VzJyApOwoKCQlyZXR1cm4gJGNvbnN0cmFpbnQ7Cgl9CgoJLyoqCgkgKiBTZXRzIGBDT01QT1NFUl9BVVRIYCBlbnZpcm9ubWVudCB2YXJpYWJsZSAod2hpY2ggQ29tcG9zZXIgbWVyZ2VzIGludG8gdGhlIGNvbmZpZyBzZXR1cCBpbiBgQ29tcG9zZXJcRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKClgKSBkZXBlbmRpbmcgb24gYXZhaWxhYmxlIGVudmlyb25tZW50IHZhcmlhYmxlcy4KCSAqIEF2b2lkcyBhdXRob3JpemF0aW9uIGZhaWx1cmVzIHdoZW4gYWNjZXNzaW5nIHZhcmlvdXMgc2l0ZXMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gc2V0X2NvbXBvc2VyX2F1dGhfZW52X3ZhcigpIHsKCQkkY2hhbmdlZCAgICAgICA9IGZhbHNlOwoJCSRjb21wb3Nlcl9hdXRoID0gZ2V0ZW52KCAnQ09NUE9TRVJfQVVUSCcgKTsKCQlpZiAoIGZhbHNlICE9PSAkY29tcG9zZXJfYXV0aCApIHsKCQkJJGNvbXBvc2VyX2F1dGggPSBqc29uX2RlY29kZSggJGNvbXBvc2VyX2F1dGgsIHRydWUgLyphc3NvYyovICk7CgkJfQoJCWlmICggZW1wdHkoICRjb21wb3Nlcl9hdXRoICkgfHwgISBpc19hcnJheSggJGNvbXBvc2VyX2F1dGggKSApIHsKCQkJJGNvbXBvc2VyX2F1dGggPSBbXTsKCQl9CgkJJGdpdGh1Yl90b2tlbiA9IGdldGVudiggJ0dJVEhVQl9UT0tFTicgKTsKCQlpZiAoICEgaXNzZXQoICRjb21wb3Nlcl9hdXRoWydnaXRodWItb2F1dGgnXSApICYmIGlzX3N0cmluZyggJGdpdGh1Yl90b2tlbiApICkgewoJCQkkY29tcG9zZXJfYXV0aFsnZ2l0aHViLW9hdXRoJ10gPSBbICdnaXRodWIuY29tJyA9PiAkZ2l0aHViX3Rva2VuIF07CgkJCSRjaGFuZ2VkICAgICAgICAgICAgICAgICAgICAgICA9IHRydWU7CgkJfQoJCWlmICggJGNoYW5nZWQgKSB7CgkJCXB1dGVudiggJ0NPTVBPU0VSX0FVVEg9JyAuIGpzb25fZW5jb2RlKCAkY29tcG9zZXJfYXV0aCApICk7CgkJfQoJfQoKCS8qKgoJICogQXZvaWQgdXNpbmcgZGVmYXVsdCBDb21wb3NlciBDQSBidW5kbGUgaWYgaW4gcGhhciBhcyB3ZSBkb24ndCBpbmNsdWRlIGl0LgoJICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jYS1idW5kbGUvYmxvYi8xLjEuMC9zcmMvQ2FCdW5kbGUucGhwI0w2NAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGF2b2lkX2NvbXBvc2VyX2NhX2J1bmRsZSgpIHsKCQlpZiAoIFV0aWxzXGluc2lkZV9waGFyKCkgJiYgISBnZXRlbnYoICdTU0xfQ0VSVF9GSUxFJyApICYmICEgZ2V0ZW52KCAnU1NMX0NFUlRfRElSJyApICYmICEgaW5pX2dldCggJ29wZW5zc2wuY2FmaWxlJyApICYmICEgaW5pX2dldCggJ29wZW5zc2wuY2FwYXRoJyApICkgewoJCQkkY2VydGlmaWNhdGUgPSBVdGlsc1xleHRyYWN0X2Zyb21fcGhhciggV1BfQ0xJX1ZFTkRPUl9ESVIgLiBzZWxmOjpTU0xfQ0VSVElGSUNBVEUgKTsKCQkJcHV0ZW52KCAiU1NMX0NFUlRfRklMRT17JGNlcnRpZmljYXRlfSIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZWFkcyB0aGUgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24sIGNoZWNraW5nIHZhbGlkaXR5IGFuZCByZXR1cm5pbmcgYXJyYXkgY29udGFpbmluZyBpdHMgcGF0aCwgY29udGVudHMsIGFuZCBkZWNvZGVkIGNvbnRlbnRzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgSW5kZXhlZCBhcnJheSBjb250YWluaW5nIHRoZSBwYXRoLCB0aGUgY29udGVudHMsIGFuZCB0aGUgZGVjb2RlZCBjb250ZW50cyBvZiB0aGUgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24uCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbXBvc2VyX2pzb25fcGF0aF9iYWNrdXBfZGVjb2RlZCgpIHsKCQkkY29tcG9zZXJfanNvbl9vYmogPSAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb24oKTsKCQkkanNvbl9wYXRoICAgICAgICAgPSAkY29tcG9zZXJfanNvbl9vYmotPmdldFBhdGgoKTsKCQkkY29tcG9zZXJfYmFja3VwICAgPSBmaWxlX2dldF9jb250ZW50cyggJGpzb25fcGF0aCApOwoJCWlmICggZmFsc2UgPT09ICRjb21wb3Nlcl9iYWNrdXAgKSB7CgkJCSRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJGYWlsZWQgdG8gcmVhZCAnJXMnOiAlcyIsICRqc29uX3BhdGgsICRlcnJvclsnbWVzc2FnZSddICkgKTsKCQl9CgkJdHJ5IHsKCQkJJGNvbXBvc2VyX2JhY2t1cF9kZWNvZGVkID0gJGNvbXBvc2VyX2pzb25fb2JqLT5yZWFkKCk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkZhaWxlZCB0byBwYXJzZSAnJXMnIGFzIGpzb246ICVzIiwgJGpzb25fcGF0aCwgJGUtPmdldE1lc3NhZ2UoKSApICk7CgkJfQoKCQlyZXR1cm4gWyAkanNvbl9wYXRoLCAkY29tcG9zZXJfYmFja3VwLCAkY29tcG9zZXJfYmFja3VwX2RlY29kZWQgXTsKCX0KCgkvKioKCSAqIFJlZ2lzdGVycyBhIFBIUCBzaHV0ZG93biBmdW5jdGlvbiB0byByZXZlcnQgY29tcG9zZXIuanNvbiB1bmxlc3MKCSAqIHJlZmVyZW5jZWQgYCRyZXZlcnRgIGZsYWcgaXMgZmFsc2UuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkanNvbl9wYXRoICAgICAgIFBhdGggdG8gY29tcG9zZXIuanNvbi4KCSAqIEBwYXJhbSBzdHJpbmcgJGNvbXBvc2VyX2JhY2t1cCBPcmlnaW5hbCBjb250ZW50cyBvZiBjb21wb3Nlci5qc29uLgoJICogQHBhcmFtIGJvb2wgICAmJHJldmVydCAgICAgICAgIEZsYWdzIHdoZXRoZXIgdG8gcmV2ZXJ0IG9yIG5vdC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiByZWdpc3Rlcl9yZXZlcnRfc2h1dGRvd25fZnVuY3Rpb24oICRqc29uX3BhdGgsICRjb21wb3Nlcl9iYWNrdXAsICYkcmV2ZXJ0ICkgewoJCS8vIEFsbG9jYXRlIGFsbCBuZWVkZWQgbWVtb3J5IGJlZm9yZWhhbmQgYXMgbXVjaCBhcyBwb3NzaWJsZS4KCQkkcmV2ZXJ0X21zZyAgICAgID0gIlJldmVydGVkIGNvbXBvc2VyLmpzb24uXG4iOwoJCSRyZXZlcnRfZmFpbF9tc2cgPSAiRmFpbGVkIHRvIHJldmVydCBjb21wb3Nlci5qc29uLlxuIjsKCQkkbWVtb3J5X21zZyAgICAgID0gIldQLUNMSSByYW4gb3V0IG9mIG1lbW9yeS4gUGxlYXNlIHNlZSBodHRwczovL2JpdC5seS93cGNsaW1lbSBmb3IgZnVydGhlciBoZWxwLlxuIjsKCQkkbWVtb3J5X3N0cmluZyAgID0gJ0FsbG93ZWQgbWVtb3J5IHNpemUgb2YnOwoJCSRlcnJvcl9hcnJheSAgICAgPSBbCgkJCSd0eXBlJyAgICA9PiA0MiwKCQkJJ21lc3NhZ2UnID0+ICdTb21lIHJhbmRvbSBkdW1teSBzdHJpbmcgdG8gdGFrZSB1cCBtZW1vcnknLAoJCQknZmlsZScgICAgPT4gJ0Fub3RoZXIgcmFuZG9tIHN0cmluZywgd2hpY2ggd291bGQgYmUgYSBmaWxlbmFtZSB0aGlzIHRpbWUnLAoJCQknbGluZScgICAgPT4gMzE0LAoJCV07CgoJCXJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgdXNlICgKCQkJCSRqc29uX3BhdGgsCgkJCQkkY29tcG9zZXJfYmFja3VwLAoJCQkJJiRyZXZlcnQsCgkJCQkkcmV2ZXJ0X21zZywKCQkJCSRyZXZlcnRfZmFpbF9tc2csCgkJCQkkbWVtb3J5X21zZywKCQkJCSRtZW1vcnlfc3RyaW5nLAoJCQkJJGVycm9yX2FycmF5CgkJCSkgewoJCQkJaWYgKCAkcmV2ZXJ0ICkgewoJCQkJCWlmICggZmFsc2UgIT09IGZpbGVfcHV0X2NvbnRlbnRzKCAkanNvbl9wYXRoLCAkY29tcG9zZXJfYmFja3VwICkgKSB7CgkJCQkJCWZ3cml0ZSggU1RERVJSLCAkcmV2ZXJ0X21zZyApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWZ3cml0ZSggU1RERVJSLCAkcmV2ZXJ0X2ZhaWxfbXNnICk7CgkJCQkJfQoJCQkJfQoKCQkJCSRlcnJvcl9hcnJheSA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQlpZiAoIGlzX2FycmF5KCAkZXJyb3JfYXJyYXkgKSAmJiBmYWxzZSAhPT0gc3RycG9zKCAkZXJyb3JfYXJyYXlbJ21lc3NhZ2UnXSwgJG1lbW9yeV9zdHJpbmcgKSApIHsKCQkJCQlmd3JpdGUoIFNUREVSUiwgJG1lbW9yeV9tc2cgKTsKCQkJCX0KCQkJfQoJCSk7Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIHdlIGFyZSBkZWFsaW5nIHdpdGggQ29tcG9zZXIgdmVyc2lvbiAyLjAuMCsuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaXNfY29tcG9zZXJfdjIoKSB7CgkJcmV0dXJuIHZlcnNpb25fY29tcGFyZSggQ29tcG9zZXI6OmdldFZlcnNpb24oKSwgJzIuMC4wJywgJz49JyApOwoJfQoKCS8qKgoJICogVHJ5IHRvIHJldHJpZXZlIGRlZmF1bHQgYnJhbmNoIHZpYSBHaXRIdWIgQVBJLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VfbmFtZSBHaXRIdWIgcGFja2FnZSBuYW1lIHRvIHJldHJpZXZlIHRoZSBkZWZhdWx0IGJyYW5jaCBmcm9tLgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgICAgIE9wdGlvbmFsLiBXaGV0aGVyIHRvIGluc2VjdXJlbHkgcmV0cnkgZG93bmxvYWRzIHRoYXQgZmFpbGVkIFRMUyBoYW5kc2hha2UuIERlZmF1bHRzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZmFsc2UuCgkgKiBAcmV0dXJuIHN0cmluZyBEZWZhdWx0IGJyYW5jaCwgb3IgJ21hc3RlcicgaWYgaXQgY291bGQgbm90IGJlIHJldHJpZXZlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZ2l0aHViX2RlZmF1bHRfYnJhbmNoKCAkcGFja2FnZV9uYW1lLCAkaW5zZWN1cmUgPSBmYWxzZSApIHsKCQkkZ2l0aHViX3Rva2VuID0gZ2V0ZW52KCAnR0lUSFVCX1RPS0VOJyApOyAvLyBVc2UgR0lUSFVCX1RPS0VOIGlmIGF2YWlsYWJsZSB0byBhdm9pZCBhdXRob3JpemF0aW9uIGZhaWx1cmVzIG9yIHJhdGUtbGltaXRpbmcuCgkJJGhlYWRlcnMgICAgICA9ICRnaXRodWJfdG9rZW4gPyBbICdBdXRob3JpemF0aW9uJyA9PiAndG9rZW4gJyAuICRnaXRodWJfdG9rZW4gXSA6IFtdOwoJCSRvcHRpb25zICAgICAgPSBbICdpbnNlY3VyZScgPT4gJGluc2VjdXJlIF07CgoJCSRtYXRjaGVzID0gW107CgkJaWYgKCBwcmVnX21hdGNoKCAnI14oPzpodHRwcz86Ly9naXRodWJcLmNvbS98Z2l0QGdpdGh1YlwuY29tOikoPzxyZXBvX25hbWU+Lio/KS5naXQkIycsICRwYWNrYWdlX25hbWUsICRtYXRjaGVzICkgKSB7CgkJCSRwYWNrYWdlX25hbWUgPSAkbWF0Y2hlc1sncmVwb19uYW1lJ107CgkJfQoKCQkkZ2l0aHViX2FwaV9yZXBvX3VybCA9ICJodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL3skcGFja2FnZV9uYW1lfSI7CgkJJHJlc3BvbnNlICAgICAgICAgICAgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkZ2l0aHViX2FwaV9yZXBvX3VybCwgbnVsbCAvKmRhdGEqLywgJGhlYWRlcnMsICRvcHRpb25zICk7CgkJaWYgKCAyMCAhPT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZygKCQkJCXNwcmludGYoCgkJCQkJIkNvdWxkbid0IGZldGNoIGRlZmF1bHQgYnJhbmNoIGZvciBwYWNrYWdlICclcycgKEhUVFAgY29kZSAlZCkuIFByZXN1bWluZyBkZWZhdWx0IGJyYW5jaCBpcyAnbWFzdGVyJy4iLAoJCQkJCSRwYWNrYWdlX25hbWUsCgkJCQkJJHJlc3BvbnNlLT5zdGF0dXNfY29kZQoJCQkJKQoJCQkpOwoJCQlyZXR1cm4gJ21hc3Rlcic7CgkJfQoKCQkkcGFja2FnZV9kYXRhID0ganNvbl9kZWNvZGUoICRyZXNwb25zZS0+Ym9keSApOwoKCQlpZiAoIEpTT05fRVJST1JfTk9ORSAhPT0ganNvbl9sYXN0X2Vycm9yKCkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IGZldGNoIGRlZmF1bHQgYnJhbmNoIGZvciBwYWNrYWdlICclcycgKGZhaWxlZCB0byBkZWNvZGUgSlNPTiByZXNwb25zZSkuIFByZXN1bWluZyBkZWZhdWx0IGJyYW5jaCBpcyAnbWFzdGVyJy4iICk7CgkJCXJldHVybiAnbWFzdGVyJzsKCQl9CgoJCSRkZWZhdWx0X2JyYW5jaCA9ICRwYWNrYWdlX2RhdGEtPmRlZmF1bHRfYnJhbmNoOwoKCQlpZiAoICEgaXNfc3RyaW5nKCAkZGVmYXVsdF9icmFuY2ggKSB8fCBlbXB0eSggJGRlZmF1bHRfYnJhbmNoICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZygKCQkJCXNwcmludGYoCgkJCQkJIkNvdWxkbid0IGZldGNoIGRlZmF1bHQgYnJhbmNoIGZvciBwYWNrYWdlICclcycuIFByZXN1bWluZyBkZWZhdWx0IGJyYW5jaCBpcyAnbWFzdGVyJy4iLAoJCQkJCSRwYWNrYWdlX25hbWUKCQkJCSkKCQkJKTsKCQkJcmV0dXJuICdtYXN0ZXInOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggIkRldGVjdGVkIHBhY2thZ2UgZGVmYXVsdCBicmFuY2g6IHskZGVmYXVsdF9icmFuY2h9IiwgJ3BhY2thZ2VzJyApOwoKCQlyZXR1cm4gJGRlZmF1bHRfYnJhbmNoOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfcGFja2FnZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9wYWNrYWdlX2F1dG9sb2FkZXIgKSAmJiAhIGNsYXNzX2V4aXN0cyggJ1BhY2thZ2VfQ29tbWFuZCcgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfcGFja2FnZV9hdXRvbG9hZGVyOwp9CldQX0NMSTo6YWRkX2NvbW1hbmQoICdwYWNrYWdlJywgJ1BhY2thZ2VfQ29tbWFuZCcgKTsKPD9waHAKLyoqCiAqIEFuIGV4YW1wbGUgYXBwbGljYXRpb24gdXNpbmcgcGhwLWNsaS10b29scyBhbmQgQnV6egogKi8KCnJlcXVpcmVfb25jZSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCmRlZmluZSgnQlVaWl9QQVRIJywgcmVhbHBhdGgoJy4uL0J1enonKSk7CmRlZmluZSgnU0NSSVBUX05BTUUnLCBhcnJheV9zaGlmdCgkYXJndikpOwoKcmVxdWlyZV9vbmNlIEJVWlpfUEFUSCAuICcvbGliL0J1enovQ2xhc3NMb2FkZXIucGhwJzsKQnV6elxDbGFzc0xvYWRlcjo6cmVnaXN0ZXIoKTsKCmNsYXNzIEh0dHBDb25zb2xlIHsKICAgIHByb3RlY3RlZCAkX2hvc3Q7CiAgICBwcm90ZWN0ZWQgJF9wcm9tcHQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRob3N0KSB7CiAgICAgICAgJHRoaXMtPl9ob3N0ID0gJ2h0dHA6Ly8nIC4gJGhvc3Q7CiAgICAgICAgJHRoaXMtPl9wcm9tcHQgPSAnJUsnIC4gJHRoaXMtPl9ob3N0IC4gJyVuLyVLPiVuICc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3QoJHR5cGUsICRwYXRoKSB7CiAgICAgICAgJHJlcXVlc3QgPSBuZXcgQnV6elxNZXNzYWdlXFJlcXVlc3QoJHR5cGUsICRwYXRoLCAkdGhpcy0+X2hvc3QpOwogICAgICAgICRyZXNwb25zZSA9IG5ldyBCdXp6XE1lc3NhZ2VcUmVzcG9uc2U7CgogICAgICAgICRjbGllbnQgPSBuZXcgQnV6elxDbGllbnRcRmlsZUdldENvbnRlbnRzKCk7CiAgICAgICAgJGNsaWVudC0+c2VuZCgkcmVxdWVzdCwgJHJlc3BvbnNlKTsKCiAgICAgICAgLy8gRGlzcGxheSBoZWFkZXJzCiAgICAgICAgZm9yZWFjaCAoJHJlc3BvbnNlLT5nZXRIZWFkZXJzKCkgYXMgJGkgPT4gJGhlYWRlcikgewogICAgICAgICAgICBpZiAoJGkgPT0gMCkgewogICAgICAgICAgICAgICAgXGNsaVxsaW5lKCclR3s6aGVhZGVyfSVuJywgY29tcGFjdCgnaGVhZGVyJykpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxpc3QoJGtleSwgJHZhbHVlKSA9IGV4cGxvZGUoJzogJywgJGhlYWRlciwgMik7CiAgICAgICAgICAgIFxjbGlcbGluZSgnJVd7OmtleX0lbjogezp2YWx1ZX0nLCBjb21wYWN0KCdrZXknLCAndmFsdWUnKSk7CiAgICAgICAgfQogICAgICAgIFxjbGlcbGluZSgiXG4iKTsKICAgICAgICBwcmludCAkcmVzcG9uc2UtPmdldENvbnRlbnQoKSAuICJcbiI7CgogICAgICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJ1bigpIHsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAkY21kID0gXGNsaVxwcm9tcHQoJHRoaXMtPl9wcm9tcHQsIGZhbHNlLCBudWxsKTsKCiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXihIRUFEfEdFVHxQT1NUfFBVVHxERUxFVEUpIChcUyspJC8nLCAkY21kLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5oYW5kbGVSZXF1ZXN0KCRtYXRjaGVzWzFdLCAkbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjbWQgPT0gJ1xxJykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnRyeSB7CiAgICAkY29uc29sZSA9IG5ldyBIdHRwQ29uc29sZShhcnJheV9zaGlmdCgkYXJndikgPzogJzEyNy4wLjAuMTo4MCcpOwogICAgJGNvbnNvbGUtPnJ1bigpOwp9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICBcY2xpXGVycigiXG5cbiVSIiAuICRlLT5nZXRNZXNzYWdlKCkgLiAiJW5cbiIpOwp9Cgo/Pgo8P3BocAoKZXJyb3JfcmVwb3J0aW5nKC0xKTsKcmVxdWlyZV9vbmNlIF9fRElSX18gLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwoKCiRhcmdzID0gbmV3IGNsaVxBcmd1bWVudHMoYXJyYXkoCgknZmxhZ3MnID0+IGFycmF5KAoJCSd2ZXJib3NlJyA9PiBhcnJheSgKCQkJJ2Rlc2NyaXB0aW9uJyA9PiAnVHVybiBvbiB2ZXJib3NlIG1vZGUnLAoJCQknYWxpYXNlcycgICAgID0+IGFycmF5KCd2JykKCQkpLAoJCSdjJyA9PiBhcnJheSgKCQkJJ2Rlc2NyaXB0aW9uJyA9PiAnQSBjb3VudGVyIHRvIHRlc3Qgc3RhY2thYmxlJywKCQkJJ3N0YWNrYWJsZScgICA9PiB0cnVlCgkJKQoJKSwKCSdvcHRpb25zJyA9PiBhcnJheSgKCQkndXNlcicgPT4gYXJyYXkoCgkJCSdkZXNjcmlwdGlvbicgPT4gJ1VzZXJuYW1lIGZvciBhdXRoZW50aWNhdGlvbicsCgkJCSdhbGlhc2VzJyAgICAgPT4gYXJyYXkoJ3UnKQoJCSkKCSksCgknc3RyaWN0JyA9PiB0cnVlCikpOwoKdHJ5IHsKICAgICRhcmdzLT5wYXJzZSgpOwp9IGNhdGNoIChjbGlcSW52YWxpZEFyZ3VtZW50cyAkZSkgewogICAgZWNobyAkZS0+Z2V0TWVzc2FnZSgpIC4gIlxuXG4iOwp9CgpwcmludF9yKCRhcmdzLT5nZXRBcmd1bWVudHMoKSk7Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGk7CgovKioKICogQSBtb3JlIGNvbXBsZXggdHlwZSBvZiBOb3RpZmllciwgYFByb2dyZXNzYCBOb3RpZmllcnMgYWx3YXlzIGhhdmUgYSBtYXhpbQogKiB2YWx1ZSBhbmQgZ2VuZXJhbGx5IHNob3cgc29tZSBmb3JtIG9mIHBlcmNlbnQgY29tcGxldGUgb3IgZXN0aW1hdGVkIHRpbWUKICogdG8gY29tcGxldGlvbiBhbG9uZyB3aXRoIHRoZSBzdGFuZGFyZCBOb3RpZmllciBkaXNwbGF5cy4KICoKICogQHNlZSBjbGlcTm90aWZ5CiAqLwphYnN0cmFjdCBjbGFzcyBQcm9ncmVzcyBleHRlbmRzIFxjbGlcTm90aWZ5IHsKCXByb3RlY3RlZCAkX3RvdGFsID0gMDsKCgkvKioKCSAqIEluc3RhbnRpYXRlcyBhIFByb2dyZXNzIE5vdGlmaWVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRtc2cgICAgICAgVGhlIHRleHQgdG8gZGlzcGxheSBuZXh0IHRvIHRoZSBOb3RpZmllci4KCSAqIEBwYXJhbSBpbnQgICAgICR0b3RhbCAgICAgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyB3ZSB3aWxsIGJlIHBlcmZvcm1pbmcuCgkgKiBAcGFyYW0gaW50ICAgICAkaW50ZXJ2YWwgIFRoZSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiB1cGRhdGVzLgoJICogQHNlZSBjbGlcUHJvZ3Jlc3M6OnNldFRvdGFsKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtc2csICR0b3RhbCwgJGludGVydmFsID0gMTAwKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkbXNnLCAkaW50ZXJ2YWwpOwoJCSR0aGlzLT5zZXRUb3RhbCgkdG90YWwpOwoJfQoKCS8qKgoJICogU2V0IHRoZSBtYXggaW5jcmVtZW50cyBmb3IgdGhpcyBwcm9ncmVzcyBub3RpZmllci4KCSAqCgkgKiBAcGFyYW0gaW50ICAkdG90YWwgIFRoZSB0b3RhbCBudW1iZXIgb2YgdGltZXMgdGhpcyBpbmRpY2F0b3Igc2hvdWxkIGJlIGB0aWNrYGVkLgoJICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICBUaHJvd24gaWYgdGhlIGAkdG90YWxgIGlzIGxlc3MgdGhhbiAwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0VG90YWwoJHRvdGFsKSB7CgkJJHRoaXMtPl90b3RhbCA9IChpbnQpJHRvdGFsOwoKCQlpZiAoJHRoaXMtPl90b3RhbCA8IDApIHsKCQkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ01heGltdW0gdmFsdWUgb3V0IG9mIHJhbmdlLCBtdXN0IGJlIHBvc2l0aXZlLicpOwoJCX0KCX0KCgkvKioKCSAqIFJlc2V0IHRoZSBwcm9ncmVzcyBzdGF0ZSBzbyB0aGUgc2FtZSBpbnN0YW5jZSBjYW4gYmUgdXNlZCBpbiBtdWx0aXBsZSBsb29wcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlc2V0KCR0b3RhbCA9IG51bGwpIHsKCQlwYXJlbnQ6OnJlc2V0KCk7CgoJCWlmICgkdG90YWwpIHsKCQkJJHRoaXMtPnNldFRvdGFsKCR0b3RhbCk7CgkJfQoJfQoKCS8qKgoJICogQmVoYXZlcyBpbiBhIHNpbWlsYXIgbWFubmVyIHRvIGBjbGlcTm90aWZ5OjpjdXJyZW50KClgLCBidXQgdGhlIG91dHB1dAoJICogaXMgcGFkZGVkIHRvIG1hdGNoIHRoZSBsZW5ndGggb2YgYGNsaVxQcm9ncmVzczo6dG90YWwoKWAuCgkgKgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgYW5kIHBhZGRlZCB0aWNrIGNvdW50LgoJICogQHNlZSBjbGlcUHJvZ3Jlc3M6OnRvdGFsKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJJHNpemUgPSBzdHJsZW4oJHRoaXMtPnRvdGFsKCkpOwoJCXJldHVybiBzdHJfcGFkKHBhcmVudDo6Y3VycmVudCgpLCAkc2l6ZSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgdG90YWwgZXhwZWN0ZWQgdGlja3MuCgkgKgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgdG90YWwgdGlja3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0b3RhbCgpIHsKCQlyZXR1cm4gbnVtYmVyX2Zvcm1hdCgkdGhpcy0+X3RvdGFsKTsKCX0KCgkvKioKCSAqIENhbGN1bGF0ZXMgdGhlIGVzdGltYXRlZCB0b3RhbCB0aW1lIGZvciB0aGUgdGljayBjb3VudCB0byByZWFjaCB0aGUKCSAqIHRvdGFsIHRpY2tzIGdpdmVuLgoJICoKCSAqIEByZXR1cm4gaW50ICBUaGUgZXN0aW1hdGVkIHRvdGFsIG51bWJlciBvZiBzZWNvbmRzIGZvciBhbGwgdGlja3MgdG8gYmUKCSAqICAgICAgICAgICAgICBjb21wbGV0ZWQuIFRoaXMgaXMgbm90IHRoZSBlc3RpbWF0ZWQgdGltZSBsZWZ0LCBidXQgdG90YWwuCgkgKiBAc2VlIGNsaVxOb3RpZnk6OnNwZWVkKCkKCSAqIEBzZWUgY2xpXE5vdGlmeTo6ZWxhcHNlZCgpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlc3RpbWF0ZWQoKSB7CgkJJHNwZWVkID0gJHRoaXMtPnNwZWVkKCk7CgkJaWYgKCEkc3BlZWQgfHwgISR0aGlzLT5lbGFwc2VkKCkpIHsKCQkJcmV0dXJuIDA7CgkJfQoKCQkkZXN0aW1hdGVkID0gcm91bmQoJHRoaXMtPl90b3RhbCAvICRzcGVlZCk7CgkJcmV0dXJuICRlc3RpbWF0ZWQ7Cgl9CgoJLyoqCgkgKiBGb3JjZXMgdGhlIGN1cnJlbnQgdGljayBjb3VudCB0byB0aGUgdG90YWwgdGlja3MgZ2l2ZW4gYXQgaW5zdGF0aWF0aW9uCgkgKiB0aW1lIGJlZm9yZSBwYXNzaW5nIG9uIHRvIGBjbGlcTm90aWZ5OjpmaW5pc2goKWAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmaW5pc2goKSB7CgkJJHRoaXMtPl9jdXJyZW50ID0gJHRoaXMtPl90b3RhbDsKCQlwYXJlbnQ6OmZpbmlzaCgpOwoJfQoKCS8qKgoJICogSW5jcmVtZW50cyBhcmUgdGljayBjb3VudGVyIGJ5IHRoZSBnaXZlbiBhbW91bnQuIElmIG5vIGFtb3VudCBpcyBwcm92aWRlZCwKCSAqIHRoZSB0aWNrZXIgaXMgaW5jcmVtZW50ZWQgYnkgMS4KCSAqCgkgKiBAcGFyYW0gaW50ICAkaW5jcmVtZW50ICBUaGUgYW1vdW50IHRvIGluY3JlbWVudCBieS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluY3JlbWVudCgkaW5jcmVtZW50ID0gMSkgewoJCSR0aGlzLT5fY3VycmVudCA9IG1pbigkdGhpcy0+X3RvdGFsLCAkdGhpcy0+X2N1cnJlbnQgKyAkaW5jcmVtZW50KTsKCX0KCgkvKioKCSAqIENhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBjb21wbGV0ZWQuCgkgKgoJICogQHJldHVybiBmbG9hdCAgVGhlIHBlcmNlbnQgY29tcGxldGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcGVyY2VudCgpIHsKCQlpZiAoJHRoaXMtPl90b3RhbCA9PSAwKSB7CgkJCXJldHVybiAxOwoJCX0KCgkJcmV0dXJuICgkdGhpcy0+X2N1cnJlbnQgLyAkdGhpcy0+X3RvdGFsKTsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKLyoqCiAqIFRoZSBgU2hlbGxgIGNsYXNzIGlzIGEgdXRpbGl0eSBjbGFzcyBmb3Igc2hlbGwgcmVsYXRlZCB0YXNrcyBzdWNoIGFzCiAqIGluZm9ybWF0aW9uIG9uIHdpZHRoLgogKi8KY2xhc3MgU2hlbGwgewoKCS8qKgoJICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgdGhlIGN1cnJlbnQgc2hlbGwgaGFzIGZvciBkaXNwbGF5LgoJICoKCSAqIEByZXR1cm4gaW50ICBUaGUgbnVtYmVyIG9mIGNvbHVtbnMuCgkgKiBAdG9kbyBUZXN0IG9uIG1vcmUgc3lzdGVtcy4KCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBjb2x1bW5zKCkgewoJCXN0YXRpYyAkY29sdW1uczsKCgkJaWYgKCBnZXRlbnYoICdQSFBfQ0xJX1RPT0xTX1RFU1RfU0hFTExfQ09MVU1OU19SRVNFVCcgKSApIHsKCQkJJGNvbHVtbnMgPSBudWxsOwoJCX0KCQlpZiAoIG51bGwgPT09ICRjb2x1bW5zICkgewoJCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ2V4ZWMnICkgKSB7CgkJCQlpZiAoIHNlbGY6OmlzX3dpbmRvd3MoKSApIHsKCQkJCQkvLyBDYXRlciBmb3Igc2hlbGxzIHN1Y2ggYXMgQ3lnd2luIGFuZCBHaXQgYmFzaCB3aGVyZSBgbW9kZSBDT05gIHJldHVybnMgYW4gaW5jb3JyZWN0IHZhbHVlIGZvciBjb2x1bW5zLgoJCQkJCWlmICggKCAkc2hlbGwgPSBnZXRlbnYoICdTSEVMTCcgKSApICYmIHByZWdfbWF0Y2goICcvKD86YmFzaHx6c2gpKD86XC5leGUpPyQvJywgJHNoZWxsICkgJiYgZ2V0ZW52KCAnVEVSTScgKSApIHsKCQkJCQkJJGNvbHVtbnMgPSAoaW50KSBleGVjKCAndHB1dCBjb2xzJyApOwoJCQkJCX0KCQkJCQlpZiAoICEgJGNvbHVtbnMgKSB7CgkJCQkJCSRyZXR1cm5fdmFyID0gLTE7CgkJCQkJCSRvdXRwdXQgPSBhcnJheSgpOwoJCQkJCQlleGVjKCAnbW9kZSBDT04nLCAkb3V0cHV0LCAkcmV0dXJuX3ZhciApOwoJCQkJCQlpZiAoIDAgPT09ICRyZXR1cm5fdmFyICYmICRvdXRwdXQgKSB7CgkJCQkJCQkvLyBMb29rIGZvciBzZWNvbmQgbGluZSBlbmRpbmcgaW4gIjogPG51bWJlcj4iIChzZWFyY2hpbmcgZm9yICJDb2x1bW5zOiIgd2lsbCBmYWlsIG9uIG5vbi1FbmdsaXNoIGxvY2FsZXMpLgoJCQkJCQkJaWYgKCBwcmVnX21hdGNoKCAnLzpccypbMC05XStcblteOl0rOlxzKihbMC05XSspXG4vJywgaW1wbG9kZSggIlxuIiwgJG91dHB1dCApLCAkbWF0Y2hlcyApICkgewoJCQkJCQkJCSRjb2x1bW5zID0gKGludCkgJG1hdGNoZXNbMV07CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCWlmICggISAoICRjb2x1bW5zID0gKGludCkgZ2V0ZW52KCAnQ09MVU1OUycgKSApICkgewoJCQkJCQkkc2l6ZSA9IGV4ZWMoICcvdXNyL2Jpbi9lbnYgc3R0eSBzaXplIDI+L2Rldi9udWxsJyApOwoJCQkJCQlpZiAoICcnICE9PSAkc2l6ZSAmJiBwcmVnX21hdGNoKCAnL1swLTldKyAoWzAtOV0rKS8nLCAkc2l6ZSwgJG1hdGNoZXMgKSApIHsKCQkJCQkJCSRjb2x1bW5zID0gKGludCkgJG1hdGNoZXNbMV07CgkJCQkJCX0KCQkJCQkJaWYgKCAhICRjb2x1bW5zICkgewoJCQkJCQkJaWYgKCBnZXRlbnYoICdURVJNJyApICkgewoJCQkJCQkJCSRjb2x1bW5zID0gKGludCkgZXhlYyggJy91c3IvYmluL2VudiB0cHV0IGNvbHMgMj4vZGV2L251bGwnICk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWlmICggISAkY29sdW1ucyApIHsKCQkJCSRjb2x1bW5zID0gODA7IC8vIGRlZmF1bHQgd2lkdGggb2YgY21kIHdpbmRvdyBvbiBXaW5kb3dzIE9TCgkJCX0KCQl9CgoJCXJldHVybiAkY29sdW1uczsKCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIHRoZSBvdXRwdXQgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGlzIGEgVFRZIG9yIGEgcGlwZSAvIHJlZGlyZWN0CgkgKgoJICogUmV0dXJucyB0cnVlIGlmIFNURE9VVCBvdXRwdXQgaXMgYmVpbmcgcmVkaXJlY3RlZCB0byBhIHBpcGUgb3IgYSBmaWxlOyBmYWxzZSBpcwoJICogb3V0cHV0IGlzIGJlaW5nIHNlbnQgZGlyZWN0bHkgdG8gdGhlIHRlcm1pbmFsLgoJICoKCSAqIElmIGFuIGVudiB2YXJpYWJsZSBTSEVMTF9QSVBFIGV4aXN0cywgcmV0dXJuZWQgcmVzdWx0IGRlcGVuZHMgaXQncwoJICogdmFsdWUuIFN0cmluZ3MgbGlrZSAxLCAwLCB5ZXMsIG5vLCB0aGF0IHZhbGlkYXRlIHRvIGJvb2xlYW5zIGFyZSBhY2NlcHRlZC4KCSAqCgkgKiBUbyBlbmFibGUgQVNDSUkgZm9ybWF0dGluZyBldmVuIHdoZW4gc2hlbGwgaXMgcGlwZWQsIHVzZSB0aGUKCSAqIEVOViB2YXJpYWJsZSBTSEVMTF9QSVBFPTAKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBpc1BpcGVkKCkgewoJCSRzaGVsbFBpcGUgPSBnZXRlbnYoJ1NIRUxMX1BJUEUnKTsKCgkJaWYgKCRzaGVsbFBpcGUgIT09IGZhbHNlKSB7CgkJCXJldHVybiBmaWx0ZXJfdmFyKCRzaGVsbFBpcGUsIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKTsKCQl9IGVsc2UgewoJCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cygnc3RyZWFtX2lzYXR0eScpICkgewoJCQkJcmV0dXJuICFzdHJlYW1faXNhdHR5KFNURE9VVCk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gKGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfaXNhdHR5JykgJiYgIXBvc2l4X2lzYXR0eShTVERPVVQpKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFVzZXMgYHN0dHlgIHRvIGhpZGUgaW5wdXQvb3V0cHV0IGNvbXBsZXRlbHkuCgkgKiBAcGFyYW0gYm9vbGVhbiAkaGlkZGVuIFdpbGwgaGlkZS9zaG93IHRoZSBuZXh0IGRhdGEuIERlZmF1bHRzIHRvIHRydWUuCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gaGlkZSgkaGlkZGVuID0gdHJ1ZSkgewoJCXN5c3RlbSggJ3N0dHkgJyAuICggJGhpZGRlbj8gJy1lY2hvJyA6ICdlY2hvJyApICk7Cgl9CgoJLyoqCgkgKiBJcyB0aGlzIHNoZWxsIGluIFdpbmRvd3M/CgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXN0YXRpYyBwcml2YXRlIGZ1bmN0aW9uIGlzX3dpbmRvd3MoKSB7CgkJcmV0dXJuIHN0cnRvdXBwZXIoc3Vic3RyKFBIUF9PUywgMCwgMykpID09PSAnV0lOJzsKCX0KCn0KCj8+Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlccHJvZ3Jlc3M7Cgp1c2UgY2xpOwp1c2UgY2xpXE5vdGlmeTsKdXNlIGNsaVxQcm9ncmVzczsKdXNlIGNsaVxTaGVsbDsKdXNlIGNsaVxTdHJlYW1zOwoKLyoqCiAqIERpc3BsYXlzIGEgcHJvZ3Jlc3MgYmFyIHNwYW5uaW5nIHRoZSBlbnRpcmUgc2hlbGwuCiAqCiAqIEJhc2ljIGZvcm1hdDoKICoKICogICBeTVNHICBQRVIlIFs9PT09PT09PT09PT09PT09PT09PT09PSAgICAgICAgICAgIF0gIDAwOjAwIC8gMDA6MDAkCiAqLwpjbGFzcyBCYXIgZXh0ZW5kcyBQcm9ncmVzcyB7Cglwcm90ZWN0ZWQgJF9iYXJzID0gJz0+JzsKCXByb3RlY3RlZCAkX2Zvcm1hdE1lc3NhZ2UgPSAnezptc2d9ICB7OnBlcmNlbnR9JSBbJzsKCXByb3RlY3RlZCAkX2Zvcm1hdFRpbWluZyA9ICddIHs6ZWxhcHNlZH0gLyB7OmVzdGltYXRlZH0nOwoJcHJvdGVjdGVkICRfZm9ybWF0ID0gJ3s6bXNnfXs6YmFyfXs6dGltaW5nfSc7CgoJLyoqCgkgKiBQcmludHMgdGhlIHByb2dyZXNzIGJhciB0byB0aGUgc2NyZWVuIHdpdGggcGVyY2VudCBjb21wbGV0ZSwgZWxhcHNlZCB0aW1lCgkgKiBhbmQgZXN0aW1hdGVkIHRvdGFsIHRpbWUuCgkgKgoJICogQHBhcmFtIGJvb2xlYW4gICRmaW5pc2ggIGB0cnVlYCBpZiB0aGlzIHdhcyBjYWxsZWQgZnJvbQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIGBjbGlcTm90aWZ5OjpmaW5pc2goKWAsIGBmYWxzZWAgb3RoZXJ3aXNlLgoJICogQHNlZSBjbGlcb3V0KCkKCSAqIEBzZWUgY2xpXE5vdGlmeTo6Zm9ybWF0VGltZSgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OmVsYXBzZWQoKQoJICogQHNlZSBjbGlcUHJvZ3Jlc3M6OmVzdGltYXRlZCgpOwoJICogQHNlZSBjbGlcUHJvZ3Jlc3M6OnBlcmNlbnQoKQoJICogQHNlZSBjbGlcU2hlbGw6OmNvbHVtbnMoKQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGlzcGxheSgkZmluaXNoID0gZmFsc2UpIHsKCQkkX3BlcmNlbnQgPSAkdGhpcy0+cGVyY2VudCgpOwoKCQkkcGVyY2VudCA9IHN0cl9wYWQoZmxvb3IoJF9wZXJjZW50ICogMTAwKSwgMyk7CgkJJG1zZyA9ICR0aGlzLT5fbWVzc2FnZTsKCQkkbXNnID0gU3RyZWFtczo6cmVuZGVyKCR0aGlzLT5fZm9ybWF0TWVzc2FnZSwgY29tcGFjdCgnbXNnJywgJ3BlcmNlbnQnKSk7CgoJCSRlc3RpbWF0ZWQgPSAkdGhpcy0+Zm9ybWF0VGltZSgkdGhpcy0+ZXN0aW1hdGVkKCkpOwoJCSRlbGFwc2VkICAgPSBzdHJfcGFkKCR0aGlzLT5mb3JtYXRUaW1lKCR0aGlzLT5lbGFwc2VkKCkpLCBzdHJsZW4oJGVzdGltYXRlZCkpOwoJCSR0aW1pbmcgICAgPSBTdHJlYW1zOjpyZW5kZXIoJHRoaXMtPl9mb3JtYXRUaW1pbmcsIGNvbXBhY3QoJ2VsYXBzZWQnLCAnZXN0aW1hdGVkJykpOwoKCQkkc2l6ZSA9IFNoZWxsOjpjb2x1bW5zKCk7CgkJJHNpemUgLT0gc3RybGVuKCRtc2cgLiAkdGltaW5nKTsKCQlpZiAoICRzaXplIDwgMCApIHsKCQkJJHNpemUgPSAwOwoJCX0KCgkJJGJhciA9IHN0cl9yZXBlYXQoJHRoaXMtPl9iYXJzWzBdLCBmbG9vcigkX3BlcmNlbnQgKiAkc2l6ZSkpIC4gJHRoaXMtPl9iYXJzWzFdOwoJCS8vIHN1YnN0ciBpcyBuZWVkZWQgdG8gdHJpbSBvZmYgdGhlIGJhciBjYXAgYXQgMTAwJQoJCSRiYXIgPSBzdWJzdHIoc3RyX3BhZCgkYmFyLCAkc2l6ZSwgJyAnKSwgMCwgJHNpemUpOwoKCQlTdHJlYW1zOjpvdXQoJHRoaXMtPl9mb3JtYXQsIGNvbXBhY3QoJ21zZycsICdiYXInLCAndGltaW5nJykpOwoJfQoKCS8qKgoJICogVGhpcyBtZXRob2QgYXVnbWVudHMgdGhlIGJhc2UgZGVmaW5pdGlvbiBmcm9tIGNsaVxOb3RpZnkgdG8gb3B0aW9uYWxseQoJICogYWxsb3cgcGFzc2luZyBhIG5ldyBtZXNzYWdlLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJGluY3JlbWVudCBUaGUgYW1vdW50IHRvIGluY3JlbWVudCBieS4KCSAqIEBwYXJhbSBzdHJpbmcgJG1zZyAgICAgICBUaGUgdGV4dCB0byBkaXNwbGF5IG5leHQgdG8gdGhlIE5vdGlmaWVyLiAob3B0aW9uYWwpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OnRpY2soKQoJICovCglwdWJsaWMgZnVuY3Rpb24gdGljaygkaW5jcmVtZW50ID0gMSwgJG1zZyA9IG51bGwpIHsKCQlpZiAoJG1zZykgewoJCQkkdGhpcy0+X21lc3NhZ2UgPSAkbXNnOwoJCX0KCQlOb3RpZnk6OnRpY2soJGluY3JlbWVudCk7Cgl9Cn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaVxub3RpZnk7Cgp1c2UgY2xpXE5vdGlmeTsKdXNlIGNsaVxTdHJlYW1zOwoKLyoqCiAqIFRoZSBgU3Bpbm5lcmAgTm90aWZpZXIgZGlzcGxheXMgYW4gQVNDSUkgc3Bpbm5lci4KICovCmNsYXNzIFNwaW5uZXIgZXh0ZW5kcyBOb3RpZnkgewoJcHJvdGVjdGVkICRfY2hhcnMgPSAnLVx8Lyc7Cglwcm90ZWN0ZWQgJF9mb3JtYXQgPSAnezptc2d9IHs6Y2hhcn0gICh7OmVsYXBzZWR9LCB7OnNwZWVkfS9zKSc7Cglwcm90ZWN0ZWQgJF9pdGVyYXRpb24gPSAwOwoKCS8qKgoJICogUHJpbnRzIHRoZSBjdXJyZW50IHNwaW5uZXIgcG9zaXRpb24gdG8gYFNURE9VVGAgd2l0aCB0aGUgdGltZSBlbGFwc2VkCgkgKiBhbmQgdGljayBzcGVlZC4KCSAqCgkgKiBAcGFyYW0gYm9vbGVhbiAgJGZpbmlzaCAgYHRydWVgIGlmIHRoaXMgd2FzIGNhbGxlZCBmcm9tCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNsaVxOb3RpZnk6OmZpbmlzaCgpYCwgYGZhbHNlYCBvdGhlcndpc2UuCgkgKiBAc2VlIGNsaVxvdXRfcGFkZGVkKCkKCSAqIEBzZWUgY2xpXE5vdGlmeTo6Zm9ybWF0VGltZSgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OnNwZWVkKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BsYXkoJGZpbmlzaCA9IGZhbHNlKSB7CgkJJG1zZyA9ICR0aGlzLT5fbWVzc2FnZTsKCQkkaWR4ID0gJHRoaXMtPl9pdGVyYXRpb24rKyAlIHN0cmxlbigkdGhpcy0+X2NoYXJzKTsKCQkkY2hhciA9ICR0aGlzLT5fY2hhcnNbJGlkeF07CgkJJHNwZWVkID0gbnVtYmVyX2Zvcm1hdChyb3VuZCgkdGhpcy0+c3BlZWQoKSkpOwoJCSRlbGFwc2VkID0gJHRoaXMtPmZvcm1hdFRpbWUoJHRoaXMtPmVsYXBzZWQoKSk7CgoJCVN0cmVhbXM6Om91dF9wYWRkZWQoJHRoaXMtPl9mb3JtYXQsIGNvbXBhY3QoJ21zZycsICdjaGFyJywgJ2VsYXBzZWQnLCAnc3BlZWQnKSk7Cgl9Cn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaVxub3RpZnk7Cgp1c2UgY2xpXE5vdGlmeTsKdXNlIGNsaVxTdHJlYW1zOwoKLyoqCiAqIEEgTm90aWZlciB0aGF0IGRpc3BsYXlzIGEgc3RyaW5nIG9mIHBlcmlvZHMuCiAqLwpjbGFzcyBEb3RzIGV4dGVuZHMgTm90aWZ5IHsKCXByb3RlY3RlZCAkX2RvdHM7Cglwcm90ZWN0ZWQgJF9mb3JtYXQgPSAnezptc2d9ezpkb3RzfSAgKHs6ZWxhcHNlZH0sIHs6c3BlZWR9L3MpJzsKCXByb3RlY3RlZCAkX2l0ZXJhdGlvbjsKCgkvKioKCSAqIEluc3RhdGlhdGVzIGEgTm90aWZpY2F0aW9uIG9iamVjdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkbXNnICAgICAgIFRoZSB0ZXh0IHRvIGRpc3BsYXkgbmV4dCB0byB0aGUgTm90aWZpZXIuCgkgKiBAcGFyYW0gaW50ICAgICAkZG90cyAgICAgIFRoZSBudW1iZXIgb2YgZG90cyB0byBpdGVyYXRlIHRocm91Z2guCgkgKiBAcGFyYW0gaW50ICAgICAkaW50ZXJ2YWwgIFRoZSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiB1cGRhdGVzLgoJICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbXNnLCAkZG90cyA9IDMsICRpbnRlcnZhbCA9IDEwMCkgewoJCXBhcmVudDo6X19jb25zdHJ1Y3QoJG1zZywgJGludGVydmFsKTsKCQkkdGhpcy0+X2RvdHMgPSAoaW50KSRkb3RzOwoKCQlpZiAoJHRoaXMtPl9kb3RzIDw9IDApIHsKCQkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0RvdCBjb3VudCBvdXQgb2YgcmFuZ2UsIG11c3QgYmUgcG9zaXRpdmUuJyk7CgkJfQoJfQoKCS8qKgoJICogUHJpbnRzIHRoZSBjb3JyZWN0IG51bWJlciBvZiBkb3RzIHRvIGBTVERPVVRgIHdpdGggdGhlIHRpbWUgZWxhcHNlZCBhbmQKCSAqIHRpY2sgc3BlZWQuCgkgKgoJICogQHBhcmFtIGJvb2xlYW4gICRmaW5pc2ggIGB0cnVlYCBpZiB0aGlzIHdhcyBjYWxsZWQgZnJvbQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIGBjbGlcTm90aWZ5OjpmaW5pc2goKWAsIGBmYWxzZWAgb3RoZXJ3aXNlLgoJICogQHNlZSBjbGlcb3V0X3BhZGRlZCgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OmZvcm1hdFRpbWUoKQoJICogQHNlZSBjbGlcTm90aWZ5OjpzcGVlZCgpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5KCRmaW5pc2ggPSBmYWxzZSkgewoJCSRyZXBlYXQgPSAkdGhpcy0+X2RvdHM7CgkJaWYgKCEkZmluaXNoKSB7CgkJCSRyZXBlYXQgPSAkdGhpcy0+X2l0ZXJhdGlvbisrICUgJHJlcGVhdDsKCQl9CgoJCSRtc2cgPSAkdGhpcy0+X21lc3NhZ2U7CgkJJGRvdHMgPSBzdHJfcGFkKHN0cl9yZXBlYXQoJy4nLCAkcmVwZWF0KSwgJHRoaXMtPl9kb3RzKTsKCQkkc3BlZWQgPSBudW1iZXJfZm9ybWF0KHJvdW5kKCR0aGlzLT5zcGVlZCgpKSk7CgkJJGVsYXBzZWQgPSAkdGhpcy0+Zm9ybWF0VGltZSgkdGhpcy0+ZWxhcHNlZCgpKTsKCgkJU3RyZWFtczo6b3V0X3BhZGRlZCgkdGhpcy0+X2Zvcm1hdCwgY29tcGFjdCgnbXNnJywgJ2RvdHMnLCAnc3BlZWQnLCAnZWxhcHNlZCcpKTsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKLyoqCiAqIENoYW5nZSB0aGUgY29sb3Igb2YgdGV4dC4KICoKICogUmVmZXJlbmNlOiBodHRwOi8vZ3JhcGhjb21wLmNvbS9pbmZvL3NwZWNzL2Fuc2lfY29sLmh0bWwjY29sb3JzCiAqLwpjbGFzcyBDb2xvcnMgewoJc3RhdGljIHByb3RlY3RlZCAkX2NvbG9ycyA9IGFycmF5KAoJCSdjb2xvcicgPT4gYXJyYXkoCgkJCSdibGFjaycgICA9PiAzMCwKCQkJJ3JlZCcJID0+IDMxLAoJCQknZ3JlZW4nICAgPT4gMzIsCgkJCSd5ZWxsb3cnICA9PiAzMywKCQkJJ2JsdWUnCT0+IDM0LAoJCQknbWFnZW50YScgPT4gMzUsCgkJCSdjeWFuJwk9PiAzNiwKCQkJJ3doaXRlJyAgID0+IDM3CgkJKSwKCQknc3R5bGUnID0+IGFycmF5KAoJCQknYnJpZ2h0JwkgPT4gMSwKCQkJJ2RpbScJCT0+IDIsCgkJCSd1bmRlcmxpbmUnID0+IDQsCgkJCSdibGluaycJICA9PiA1LAoJCQkncmV2ZXJzZScJPT4gNywKCQkJJ2hpZGRlbicJID0+IDgKCQkpLAoJCSdiYWNrZ3JvdW5kJyA9PiBhcnJheSgKCQkJJ2JsYWNrJyAgID0+IDQwLAoJCQkncmVkJwkgPT4gNDEsCgkJCSdncmVlbicgICA9PiA0MiwKCQkJJ3llbGxvdycgID0+IDQzLAoJCQknYmx1ZScJPT4gNDQsCgkJCSdtYWdlbnRhJyA9PiA0NSwKCQkJJ2N5YW4nCT0+IDQ2LAoJCQknd2hpdGUnICAgPT4gNDcKCQkpCgkpOwoJc3RhdGljIHByb3RlY3RlZCAkX2VuYWJsZWQgPSBudWxsOwoKCXN0YXRpYyBwcm90ZWN0ZWQgJF9zdHJpbmdfY2FjaGUgPSBhcnJheSgpOwoKCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlKCRmb3JjZSA9IHRydWUpIHsKCQlzZWxmOjokX2VuYWJsZWQgPSAkZm9yY2UgPT09IHRydWUgPyB0cnVlIDogbnVsbDsKCX0KCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoJGZvcmNlID0gdHJ1ZSkgewoJCXNlbGY6OiRfZW5hYmxlZCA9ICRmb3JjZSA9PT0gdHJ1ZSA/IGZhbHNlIDogbnVsbDsKCX0KCgkvKioKCSAqIENoZWNrIGlmIHdlIHNob3VsZCBjb2xvcml6ZSBvdXRwdXQgYmFzZWQgb24gbG9jYWwgZmxhZ3MgYW5kIHNoZWxsIHR5cGUuCgkgKgoJICogT25seSBjaGVjayB0aGUgc2hlbGwgdHlwZSBpZiBgQ29sb3JzOjokX2VuYWJsZWRgIGlzIG51bGwgYW5kIGAkY29sb3JlZGAgaXMgbnVsbC4KCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBzaG91bGRDb2xvcml6ZSgkY29sb3JlZCA9IG51bGwpIHsKCQlyZXR1cm4gc2VsZjo6JF9lbmFibGVkID09PSB0cnVlIHx8CgkJCShzZWxmOjokX2VuYWJsZWQgIT09IGZhbHNlICYmCgkJCQkoJGNvbG9yZWQgPT09IHRydWUgfHwKCQkJCQkoJGNvbG9yZWQgIT09IGZhbHNlICYmIFN0cmVhbXM6OmlzVHR5KCkpKSk7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGNvbG9yLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRjb2xvciAgVGhlIG5hbWUgb2YgdGhlIGNvbG9yIG9yIHN0eWxlIHRvIHNldC4KICAgICAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gY29sb3IoJGNvbG9yKSB7CgkJaWYgKCFpc19hcnJheSgkY29sb3IpKSB7CgkJCSRjb2xvciA9IGNvbXBhY3QoJ2NvbG9yJyk7CgkJfQoKCQkkY29sb3IgKz0gYXJyYXkoJ2NvbG9yJyA9PiBudWxsLCAnc3R5bGUnID0+IG51bGwsICdiYWNrZ3JvdW5kJyA9PiBudWxsKTsKCgkJaWYgKCRjb2xvclsnY29sb3InXSA9PSAncmVzZXQnKSB7CgkJCXJldHVybiAiXDAzM1swbSI7CgkJfQoKCQkkY29sb3JzID0gYXJyYXkoKTsKCQlmb3JlYWNoIChhcnJheSgnY29sb3InLCAnc3R5bGUnLCAnYmFja2dyb3VuZCcpIGFzICR0eXBlKSB7CgkJCSRjb2RlID0gJGNvbG9yWyR0eXBlXTsKCQkJaWYgKGlzc2V0KHNlbGY6OiRfY29sb3JzWyR0eXBlXVskY29kZV0pKSB7CgkJCQkkY29sb3JzW10gPSBzZWxmOjokX2NvbG9yc1skdHlwZV1bJGNvZGVdOwoJCQl9CgkJfQoKCQlpZiAoZW1wdHkoJGNvbG9ycykpIHsKCQkJJGNvbG9yc1tdID0gMDsKCQl9CgoJCXJldHVybiAiXDAzM1siIC4gam9pbignOycsICRjb2xvcnMpIC4gIm0iOwoJfQoKCS8qKgoJICogQ29sb3JpemUgYSBzdHJpbmcgdXNpbmcgaGVscGZ1bCBzdHJpbmcgZm9ybWF0dGVycy4gSWYgdGhlIGBTdHJlYW1zOjokb3V0YCBwb2ludHMgdG8gYSBUVFkgY29sb3Jpbmcgd2lsbCBiZSBlbmFibGVkLAoJICogb3RoZXJ3aXNlIGRpc2FibGVkLiBZb3UgY2FuIGNvbnRyb2wgdGhpcyBjaGVjayB3aXRoIHRoZSBgJGNvbG9yZWRgIHBhcmFtZXRlci4KCSAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHN0cmluZwoJICogQHBhcmFtIGJvb2xlYW4gICRjb2xvcmVkICBGb3JjZSBlbmFibGUgb3IgZGlzYWJsZSB0aGUgY29sb3JpemVkIG91dHB1dC4gSWYgbGVmdCBhcyBgbnVsbGAgdGhlIFRUWSB3aWxsIGNvbnRyb2wgY29sb3JpbmcuCiAgICAgKiBAcmV0dXJuIHN0cmluZwoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGNvbG9yaXplKCRzdHJpbmcsICRjb2xvcmVkID0gbnVsbCkgewoJCSRwYXNzZWQgPSAkc3RyaW5nOwoKCQlpZiAoIXNlbGY6OnNob3VsZENvbG9yaXplKCRjb2xvcmVkKSkgewoJCQkkcmV0dXJuID0gc2VsZjo6ZGVjb2xvcml6ZSggJHBhc3NlZCwgMiAvKmtlZXBfZW5jb2RpbmdzKi8gKTsKCQkJc2VsZjo6Y2FjaGVTdHJpbmcoJHBhc3NlZCwgJHJldHVybik7CgkJCXJldHVybiAkcmV0dXJuOwoJCX0KCgkJJG1kNSA9IG1kNSgkcGFzc2VkKTsKCQlpZiAoaXNzZXQoc2VsZjo6JF9zdHJpbmdfY2FjaGVbJG1kNV1bJ2NvbG9yaXplZCddKSkgewoJCQlyZXR1cm4gc2VsZjo6JF9zdHJpbmdfY2FjaGVbJG1kNV1bJ2NvbG9yaXplZCddOwoJCX0KCgkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCclJScsICclwr4nLCAkc3RyaW5nKTsKCgkJZm9yZWFjaCAoc2VsZjo6Z2V0Q29sb3JzKCkgYXMgJGtleSA9PiAkdmFsdWUpIHsKCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCRrZXksIHNlbGY6OmNvbG9yKCR2YWx1ZSksICRzdHJpbmcpOwoJCX0KCgkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCclwr4nLCAnJScsICRzdHJpbmcpOwoJCXNlbGY6OmNhY2hlU3RyaW5nKCRwYXNzZWQsICRzdHJpbmcpOwoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCgkvKioKCSAqIFJlbW92ZSBjb2xvciBpbmZvcm1hdGlvbiBmcm9tIGEgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBBIHN0cmluZyB3aXRoIGNvbG9yIGluZm9ybWF0aW9uLgoJICogQHBhcmFtIGludCAgICAka2VlcCAgIE9wdGlvbmFsLiBJZiB0aGUgMSBiaXQgaXMgc2V0LCBjb2xvciB0b2tlbnMgKGVnICIlbiIpIHdvbid0IGJlIHN0cmlwcGVkLiBJZiB0aGUgMiBiaXQgaXMgc2V0LCBjb2xvciBlbmNvZGluZ3MgKEFOU0kgZXNjYXBlcykgd29uJ3QgYmUgc3RyaXBwZWQuIERlZmF1bHQgMC4KCSAqIEByZXR1cm4gc3RyaW5nIEEgc3RyaW5nIHdpdGggY29sb3IgaW5mb3JtYXRpb24gcmVtb3ZlZC4KCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBkZWNvbG9yaXplKCAkc3RyaW5nLCAka2VlcCA9IDAgKSB7CgkJaWYgKCAhICggJGtlZXAgJiAxICkgKSB7CgkJCS8vIEdldCByaWQgb2YgY29sb3IgdG9rZW5zIGlmIHRoZXkgZXhpc3QKCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCclJScsICclwr4nLCAkc3RyaW5nKTsKCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKGFycmF5X2tleXMoc2VsZjo6Z2V0Q29sb3JzKCkpLCAnJywgJHN0cmluZyk7CgkJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnJcK+JywgJyUnLCAkc3RyaW5nKTsKCQl9CgoJCWlmICggISAoICRrZWVwICYgMiApICkgewoJCQkvLyBSZW1vdmUgY29sb3IgZW5jb2RpbmcgaWYgaXQgZXhpc3RzCgkJCWZvcmVhY2ggKHNlbGY6OmdldENvbG9ycygpIGFzICRrZXkgPT4gJHZhbHVlKSB7CgkJCQkkc3RyaW5nID0gc3RyX3JlcGxhY2Uoc2VsZjo6Y29sb3IoJHZhbHVlKSwgJycsICRzdHJpbmcpOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCgkvKioKCSAqIENhY2hlIHRoZSBvcmlnaW5hbCwgY29sb3JpemVkLCBhbmQgZGVjb2xvcml6ZWQgdmVyc2lvbnMgb2YgYSBzdHJpbmcuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGFzc2VkIFRoZSBvcmlnaW5hbCBzdHJpbmcgYmVmb3JlIGNvbG9yaXphdGlvbi4KCSAqIEBwYXJhbSBzdHJpbmcgJGNvbG9yaXplZCBUaGUgc3RyaW5nIGFmdGVyIHJ1bm5pbmcgdGhyb3VnaCBzZWxmOjpjb2xvcml6ZS4KCSAqIEBwYXJhbSBzdHJpbmcgJGRlcHJlY2F0ZWQgT3B0aW9uYWwuIE5vdCB1c2VkLiBEZWZhdWx0IG51bGwuCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gY2FjaGVTdHJpbmcoICRwYXNzZWQsICRjb2xvcml6ZWQsICRkZXByZWNhdGVkID0gbnVsbCApIHsKCQlzZWxmOjokX3N0cmluZ19jYWNoZVttZDUoJHBhc3NlZCldID0gYXJyYXkoCgkJCSdwYXNzZWQnICAgICAgPT4gJHBhc3NlZCwKCQkJJ2NvbG9yaXplZCcgICA9PiAkY29sb3JpemVkLAoJCQknZGVjb2xvcml6ZWQnID0+IHNlbGY6OmRlY29sb3JpemUoJHBhc3NlZCksIC8vIE5vdCB2ZXJ5IHVzZWZ1bCBidXQga2VlcCBmb3IgQkMuCgkJKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgd2l0aG91dCBjb2xvciBjb2Rlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkc3RyaW5nICB0aGUgc3RyaW5nIHRvIG1lYXN1cmUKICAgICAqIEByZXR1cm4gaW50CgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gbGVuZ3RoKCRzdHJpbmcpIHsKCQlyZXR1cm4gc2FmZV9zdHJsZW4oIHNlbGY6OmRlY29sb3JpemUoICRzdHJpbmcgKSApOwoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSB3aWR0aCAobGVuZ3RoIGluIGNoYXJhY3RlcnMpIG9mIHRoZSBzdHJpbmcgd2l0aG91dCBjb2xvciBjb2RlcyBpZiBlbmFibGVkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAgICAkc3RyaW5nICAgICAgICBUaGUgc3RyaW5nIHRvIG1lYXN1cmUuCgkgKiBAcGFyYW0gYm9vbCAgICAgICAgJHByZV9jb2xvcml6ZWQgT3B0aW9uYWwuIFNldCBpZiB0aGUgc3RyaW5nIGlzIHByZS1jb2xvcml6ZWQuIERlZmF1bHQgZmFsc2UuCgkgKiBAcGFyYW0gc3RyaW5nfGJvb2wgJGVuY29kaW5nICAgICAgT3B0aW9uYWwuIFRoZSBlbmNvZGluZyBvZiB0aGUgc3RyaW5nLiBEZWZhdWx0IGZhbHNlLgogICAgICogQHJldHVybiBpbnQKCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiB3aWR0aCggJHN0cmluZywgJHByZV9jb2xvcml6ZWQgPSBmYWxzZSwgJGVuY29kaW5nID0gZmFsc2UgKSB7CgkJcmV0dXJuIHN0cndpZHRoKCAkcHJlX2NvbG9yaXplZCB8fCBzZWxmOjpzaG91bGRDb2xvcml6ZSgpID8gc2VsZjo6ZGVjb2xvcml6ZSggJHN0cmluZywgJHByZV9jb2xvcml6ZWQgPyAxIC8qa2VlcF90b2tlbnMqLyA6IDAgKSA6ICRzdHJpbmcsICRlbmNvZGluZyApOwoJfQoKCS8qKgoJICogUGFkIHRoZSBzdHJpbmcgdG8gYSBjZXJ0YWluIGRpc3BsYXkgbGVuZ3RoLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAgICAkc3RyaW5nICAgICAgICBUaGUgc3RyaW5nIHRvIHBhZC4KCSAqIEBwYXJhbSBpbnQgICAgICAgICAkbGVuZ3RoICAgICAgICBUaGUgZGlzcGxheSBsZW5ndGguCgkgKiBAcGFyYW0gYm9vbCAgICAgICAgJHByZV9jb2xvcml6ZWQgT3B0aW9uYWwuIFNldCBpZiB0aGUgc3RyaW5nIGlzIHByZS1jb2xvcml6ZWQuIERlZmF1bHQgZmFsc2UuCgkgKiBAcGFyYW0gc3RyaW5nfGJvb2wgJGVuY29kaW5nICAgICAgT3B0aW9uYWwuIFRoZSBlbmNvZGluZyBvZiB0aGUgc3RyaW5nLiBEZWZhdWx0IGZhbHNlLgoJICogQHBhcmFtIGludCAgICAgICAgICRwYWRfdHlwZSAgICAgIE9wdGlvbmFsLiBDYW4gYmUgU1RSX1BBRF9SSUdIVCwgU1RSX1BBRF9MRUZULCBvciBTVFJfUEFEX0JPVEguIElmIHBhZF90eXBlIGlzIG5vdCBzcGVjaWZpZWQgaXQgaXMgYXNzdW1lZCB0byBiZSBTVFJfUEFEX1JJR0hULgogICAgICogQHJldHVybiBzdHJpbmcKCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBwYWQoICRzdHJpbmcsICRsZW5ndGgsICRwcmVfY29sb3JpemVkID0gZmFsc2UsICRlbmNvZGluZyA9IGZhbHNlLCAkcGFkX3R5cGUgPSBTVFJfUEFEX1JJR0hUICkgewoJCSRyZWFsX2xlbmd0aCA9IHNlbGY6OndpZHRoKCAkc3RyaW5nLCAkcHJlX2NvbG9yaXplZCwgJGVuY29kaW5nICk7CgkJJGRpZmYgPSBzdHJsZW4oICRzdHJpbmcgKSAtICRyZWFsX2xlbmd0aDsKCQkkbGVuZ3RoICs9ICRkaWZmOwoKCQlyZXR1cm4gc3RyX3BhZCggJHN0cmluZywgJGxlbmd0aCwgJyAnLCAkcGFkX3R5cGUgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29sb3IgbWFwcGluZyBhcnJheS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIGNvbG9yIHRva2VucyBtYXBwZWQgdG8gY29sb3JzIGFuZCBzdHlsZXMuCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29sb3JzKCkgewoJCXJldHVybiBhcnJheSgKCQkJJyV5JyA9PiBhcnJheSgnY29sb3InID0+ICd5ZWxsb3cnKSwKCQkJJyVnJyA9PiBhcnJheSgnY29sb3InID0+ICdncmVlbicpLAoJCQknJWInID0+IGFycmF5KCdjb2xvcicgPT4gJ2JsdWUnKSwKCQkJJyVyJyA9PiBhcnJheSgnY29sb3InID0+ICdyZWQnKSwKCQkJJyVwJyA9PiBhcnJheSgnY29sb3InID0+ICdtYWdlbnRhJyksCgkJCSclbScgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnbWFnZW50YScpLAoJCQknJWMnID0+IGFycmF5KCdjb2xvcicgPT4gJ2N5YW4nKSwKCQkJJyV3JyA9PiBhcnJheSgnY29sb3InID0+ICd3aGl0ZScpLAoJCQknJWsnID0+IGFycmF5KCdjb2xvcicgPT4gJ2JsYWNrJyksCgkJCSclbicgPT4gYXJyYXkoJ2NvbG9yJyA9PiAncmVzZXQnKSwKCQkJJyVZJyA9PiBhcnJheSgnY29sb3InID0+ICd5ZWxsb3cnLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVHJyA9PiBhcnJheSgnY29sb3InID0+ICdncmVlbicsICdzdHlsZScgPT4gJ2JyaWdodCcpLAoJCQknJUInID0+IGFycmF5KCdjb2xvcicgPT4gJ2JsdWUnLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVSJyA9PiBhcnJheSgnY29sb3InID0+ICdyZWQnLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVQJyA9PiBhcnJheSgnY29sb3InID0+ICdtYWdlbnRhJywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclTScgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnbWFnZW50YScsICdzdHlsZScgPT4gJ2JyaWdodCcpLAoJCQknJUMnID0+IGFycmF5KCdjb2xvcicgPT4gJ2N5YW4nLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVXJyA9PiBhcnJheSgnY29sb3InID0+ICd3aGl0ZScsICdzdHlsZScgPT4gJ2JyaWdodCcpLAoJCQknJUsnID0+IGFycmF5KCdjb2xvcicgPT4gJ2JsYWNrJywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclTicgPT4gYXJyYXkoJ2NvbG9yJyA9PiAncmVzZXQnLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyUzJyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ3llbGxvdycpLAoJCQknJTInID0+IGFycmF5KCdiYWNrZ3JvdW5kJyA9PiAnZ3JlZW4nKSwKCQkJJyU0JyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ2JsdWUnKSwKCQkJJyUxJyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ3JlZCcpLAoJCQknJTUnID0+IGFycmF5KCdiYWNrZ3JvdW5kJyA9PiAnbWFnZW50YScpLAoJCQknJTYnID0+IGFycmF5KCdiYWNrZ3JvdW5kJyA9PiAnY3lhbicpLAoJCQknJTcnID0+IGFycmF5KCdiYWNrZ3JvdW5kJyA9PiAnd2hpdGUnKSwKCQkJJyUwJyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ2JsYWNrJyksCgkJCSclRicgPT4gYXJyYXkoJ3N0eWxlJyA9PiAnYmxpbmsnKSwKCQkJJyVVJyA9PiBhcnJheSgnc3R5bGUnID0+ICd1bmRlcmxpbmUnKSwKCQkJJyU4JyA9PiBhcnJheSgnc3R5bGUnID0+ICdyZXZlcnNlJyksCgkJCSclOScgPT4gYXJyYXkoJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclXycgPT4gYXJyYXkoJ3N0eWxlJyA9PiAnYnJpZ2h0JykKCQkpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjYWNoZWQgc3RyaW5nIHZhbHVlcy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IFRoZSBjYWNoZWQgc3RyaW5nIHZhbHVlcy4KCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBnZXRTdHJpbmdDYWNoZSgpIHsKCQlyZXR1cm4gc2VsZjo6JF9zdHJpbmdfY2FjaGU7Cgl9CgoJLyoqCgkgKiBDbGVhciB0aGUgc3RyaW5nIGNhY2hlLgoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGNsZWFyU3RyaW5nQ2FjaGUoKSB7CgkJc2VsZjo6JF9zdHJpbmdfY2FjaGUgPSBhcnJheSgpOwoJfQp9Cjw/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+aXNWYWx1ZSkgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCSR0aGlzWyRvcHRpb24tPmtleV0gPSBqb2luKCcgJywgJHZhbHVlcyk7CgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaTsKCnVzZSBjbGlcU2hlbGw7CnVzZSBjbGlcU3RyZWFtczsKdXNlIGNsaVx0YWJsZVxBc2NpaTsKdXNlIGNsaVx0YWJsZVxSZW5kZXJlcjsKdXNlIGNsaVx0YWJsZVxUYWJ1bGFyOwoKLyoqCiAqIFRoZSBgVGFibGVgIGNsYXNzIGlzIHVzZWQgdG8gZGlzcGxheSBkYXRhIGluIGEgdGFidWxhciBmb3JtYXQuCiAqLwpjbGFzcyBUYWJsZSB7Cglwcm90ZWN0ZWQgJF9yZW5kZXJlcjsKCXByb3RlY3RlZCAkX2hlYWRlcnMgPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfZm9vdGVycyA9IGFycmF5KCk7Cglwcm90ZWN0ZWQgJF93aWR0aCA9IGFycmF5KCk7Cglwcm90ZWN0ZWQgJF9yb3dzID0gYXJyYXkoKTsKCgkvKioKCSAqIEluaXRpYWxpemVzIHRoZSBgVGFibGVgIGNsYXNzLgoJICoKCSAqIFRoZXJlIGFyZSAzIHdheXMgdG8gaW5zdGFudGlhdGUgdGhpcyBjbGFzczoKCSAqCgkgKiAgMS4gUGFzcyBhbiBhcnJheSBvZiBzdHJpbmdzIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIgZm9yIHRoZSBjb2x1bW4gaGVhZGVycwoJICogICAgIGFuZCBhIDItZGltZW5zaW9uYWwgYXJyYXkgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgZm9yIHRoZSBkYXRhIHJvd3MuCgkgKiAgMi4gUGFzcyBhbiBhcnJheSBvZiBoYXNoIHRhYmxlcyAoc3RyaW5nIGluZGV4ZXMgaW5zdGVhZCBvZiBudW1lcmljYWwpCgkgKiAgICAgd2hlcmUgZWFjaCBoYXNoIHRhYmxlIGlzIGEgcm93IGFuZCB0aGUgaW5kZXhlcyBvZiB0aGUgKmZpcnN0KiBoYXNoCgkgKiAgICAgdGFibGUgYXJlIHVzZWQgYXMgdGhlIGhlYWRlciB2YWx1ZXMuCgkgKiAgMy4gUGFzcyBub3RoaW5nIGFuZCB1c2UgYHNldEhlYWRlcnMoKWAgYW5kIGBhZGRSb3coKWAgb3IgYHNldFJvd3MoKWAuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkaGVhZGVycyAgSGVhZGVycyB1c2VkIGluIHRoaXMgdGFibGUuIE9wdGlvbmFsLgoJICogQHBhcmFtIGFycmF5ICAkcm93cyAgICAgVGhlIHJvd3Mgb2YgZGF0YSBmb3IgdGhpcyB0YWJsZS4gT3B0aW9uYWwuCgkgKiBAcGFyYW0gYXJyYXkgICRmb290ZXJzICBGb290ZXJzIHVzZWQgaW4gdGhpcyB0YWJsZS4gT3B0aW9uYWwuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkaGVhZGVycyA9IG51bGwsIGFycmF5ICRyb3dzID0gbnVsbCwgYXJyYXkgJGZvb3RlcnMgPSBudWxsKSB7CgkJaWYgKCFlbXB0eSgkaGVhZGVycykpIHsKCQkJLy8gSWYgYWxsIHRoZSByb3dzIGlzIGdpdmVuIGluICRoZWFkZXJzIHdlIHVzZSB0aGUga2V5cyBmcm9tIHRoZQoJCQkvLyBmaXJzdCByb3cgZm9yIHRoZSBoZWFkZXIgdmFsdWVzCgkJCWlmICgkcm93cyA9PT0gbnVsbCkgewoJCQkJJHJvd3MgPSAkaGVhZGVyczsKCQkJCSRrZXlzID0gYXJyYXlfa2V5cyhhcnJheV9zaGlmdCgkaGVhZGVycykpOwoJCQkJJGhlYWRlcnMgPSBhcnJheSgpOwoKCQkJCWZvcmVhY2ggKCRrZXlzIGFzICRoZWFkZXIpIHsKCQkJCQkkaGVhZGVyc1skaGVhZGVyXSA9ICRoZWFkZXI7CgkJCQl9CgkJCX0KCgkJCSR0aGlzLT5zZXRIZWFkZXJzKCRoZWFkZXJzKTsKCQkJJHRoaXMtPnNldFJvd3MoJHJvd3MpOwoJCX0KCgkJaWYgKCFlbXB0eSgkZm9vdGVycykpIHsKCQkJJHRoaXMtPnNldEZvb3RlcnMoJGZvb3RlcnMpOwoJCX0KCgkJaWYgKFNoZWxsOjppc1BpcGVkKCkpIHsKCQkJJHRoaXMtPnNldFJlbmRlcmVyKG5ldyBUYWJ1bGFyKCkpOwoJCX0gZWxzZSB7CgkJCSR0aGlzLT5zZXRSZW5kZXJlcihuZXcgQXNjaWkoKSk7CgkJfQoJfQoKCXB1YmxpYyBmdW5jdGlvbiByZXNldFRhYmxlKCkKCXsKCQkkdGhpcy0+X2hlYWRlcnMgPSBhcnJheSgpOwoJCSR0aGlzLT5fd2lkdGggPSBhcnJheSgpOwoJCSR0aGlzLT5fcm93cyA9IGFycmF5KCk7CgkJJHRoaXMtPl9mb290ZXJzID0gYXJyYXkoKTsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSByZW5kZXJlciB1c2VkIGJ5IHRoaXMgdGFibGUuCgkgKgoJICogQHBhcmFtIHRhYmxlXFJlbmRlcmVyICAkcmVuZGVyZXIgIFRoZSByZW5kZXJlciB0byB1c2UgZm9yIG91dHB1dC4KCSAqIEBzZWUgICB0YWJsZVxSZW5kZXJlcgoJICogQHNlZSAgIHRhYmxlXEFzY2lpCgkgKiBAc2VlICAgdGFibGVcVGFidWxhcgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0UmVuZGVyZXIoUmVuZGVyZXIgJHJlbmRlcmVyKSB7CgkJJHRoaXMtPl9yZW5kZXJlciA9ICRyZW5kZXJlcjsKCX0KCgkvKioKCSAqIExvb3BzIHRocm91Z2ggdGhlIHJvdyBhbmQgc2V0cyB0aGUgbWF4aW11bSB3aWR0aCBmb3IgZWFjaCBjb2x1bW4uCgkgKgoJICogQHBhcmFtIGFycmF5ICAkcm93ICBUaGUgdGFibGUgcm93LgogICAgICogQHJldHVybiBhcnJheSAkcm93CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBjaGVja1JvdyhhcnJheSAkcm93KSB7CgkJZm9yZWFjaCAoJHJvdyBhcyAkY29sdW1uID0+ICRzdHIpIHsKCQkJJHdpZHRoID0gQ29sb3JzOjp3aWR0aCggJHN0ciwgJHRoaXMtPmlzQXNjaWlQcmVDb2xvcml6ZWQoICRjb2x1bW4gKSApOwoJCQlpZiAoIWlzc2V0KCR0aGlzLT5fd2lkdGhbJGNvbHVtbl0pIHx8ICR3aWR0aCA+ICR0aGlzLT5fd2lkdGhbJGNvbHVtbl0pIHsKCQkJCSR0aGlzLT5fd2lkdGhbJGNvbHVtbl0gPSAkd2lkdGg7CgkJCX0KCQl9CgoJCXJldHVybiAkcm93OwoJfQoKCS8qKgoJICogT3V0cHV0IHRoZSB0YWJsZSB0byBgU1RET1VUYCB1c2luZyBgY2xpXGxpbmUoKWAuCgkgKgoJICogSWYgU1RET1VUIGlzIGEgcGlwZSBvciByZWRpcmVjdGVkIHRvIGEgZmlsZSwgc2hvdWxkIG91dHB1dCBzaW1wbGUKCSAqIHRhYi1zZXBhcmF0ZWQgdGV4dC4gT3RoZXJ3aXNlLCByZW5kZXJzIHRhYmxlIHdpdGggQVNDSUkgdGFibGUgYm9yZGVycwoJICoKCSAqIEB1c2VzIGNsaVxTaGVsbDo6aXNQaXBlZCgpIERldGVybWluZSB3aGF0IGZvcm1hdCB0byBvdXRwdXQKCSAqCgkgKiBAc2VlIGNsaVxUYWJsZTo6cmVuZGVyUm93KCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BsYXkoKSB7CgkJZm9yZWFjaCggJHRoaXMtPmdldERpc3BsYXlMaW5lcygpIGFzICRsaW5lICkgewoJCQlTdHJlYW1zOjpsaW5lKCAkbGluZSApOwoJCX0KCX0KCgkvKioKCSAqIEdldCB0aGUgdGFibGUgbGluZXMgdG8gb3V0cHV0LgoJICoKCSAqIEBzZWUgY2xpXFRhYmxlOjpkaXNwbGF5KCkKCSAqIEBzZWUgY2xpXFRhYmxlOjpyZW5kZXJSb3coKQoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldERpc3BsYXlMaW5lcygpIHsKCQkkdGhpcy0+X3JlbmRlcmVyLT5zZXRXaWR0aHMoJHRoaXMtPl93aWR0aCwgJGZhbGxiYWNrID0gdHJ1ZSk7CgkJJGJvcmRlciA9ICR0aGlzLT5fcmVuZGVyZXItPmJvcmRlcigpOwoKCQkkb3V0ID0gYXJyYXkoKTsKCQlpZiAoaXNzZXQoJGJvcmRlcikpIHsKCQkJJG91dFtdID0gJGJvcmRlcjsKCQl9CgkJJG91dFtdID0gJHRoaXMtPl9yZW5kZXJlci0+cm93KCR0aGlzLT5faGVhZGVycyk7CgkJaWYgKGlzc2V0KCRib3JkZXIpKSB7CgkJCSRvdXRbXSA9ICRib3JkZXI7CgkJfQoKCQlmb3JlYWNoICgkdGhpcy0+X3Jvd3MgYXMgJHJvdykgewoJCQkkcm93ID0gJHRoaXMtPl9yZW5kZXJlci0+cm93KCRyb3cpOwoJCQkkcm93ID0gZXhwbG9kZSggUEhQX0VPTCwgJHJvdyApOwoJCQkkb3V0ID0gYXJyYXlfbWVyZ2UoICRvdXQsICRyb3cgKTsKCQl9CgoJCWlmIChpc3NldCgkYm9yZGVyKSkgewoJCQkkb3V0W10gPSAkYm9yZGVyOwoJCX0KCgkJaWYgKCR0aGlzLT5fZm9vdGVycykgewoJCQkkb3V0W10gPSAkdGhpcy0+X3JlbmRlcmVyLT5yb3coJHRoaXMtPl9mb290ZXJzKTsKCQkJaWYgKGlzc2V0KCRib3JkZXIpKSB7CgkJCQkkb3V0W10gPSAkYm9yZGVyOwoJCQl9CgkJfQoJCXJldHVybiAkb3V0OwoJfQoKCS8qKgoJICogU29ydCB0aGUgdGFibGUgYnkgYSBjb2x1bW4uIE11c3QgYmUgY2FsbGVkIGJlZm9yZSBgY2xpXFRhYmxlOjpkaXNwbGF5KClgLgoJICoKCSAqIEBwYXJhbSBpbnQgICRjb2x1bW4gIFRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHNvcnQgYnkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzb3J0KCRjb2x1bW4pIHsKCQlpZiAoIWlzc2V0KCR0aGlzLT5faGVhZGVyc1skY29sdW1uXSkpIHsKCQkJdHJpZ2dlcl9lcnJvcignTm8gY29sdW1uIHdpdGggaW5kZXggJyAuICRjb2x1bW4sIEVfVVNFUl9OT1RJQ0UpOwoJCQlyZXR1cm47CgkJfQoKCQl1c29ydCgkdGhpcy0+X3Jvd3MsIGZ1bmN0aW9uKCRhLCAkYikgdXNlICgkY29sdW1uKSB7CgkJCXJldHVybiBzdHJjbXAoJGFbJGNvbHVtbl0sICRiWyRjb2x1bW5dKTsKCQl9KTsKCX0KCgkvKioKCSAqIFNldCB0aGUgaGVhZGVycyBvZiB0aGUgdGFibGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkaGVhZGVycyAgQW4gYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIGNvbHVtbiBoZWFkZXIgbmFtZXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRIZWFkZXJzKGFycmF5ICRoZWFkZXJzKSB7CgkJJHRoaXMtPl9oZWFkZXJzID0gJHRoaXMtPmNoZWNrUm93KCRoZWFkZXJzKTsKCX0KCgkvKioKCSAqIFNldCB0aGUgZm9vdGVycyBvZiB0aGUgdGFibGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkZm9vdGVycyAgQW4gYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIGNvbHVtbiBmb290ZXJzIG5hbWVzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0Rm9vdGVycyhhcnJheSAkZm9vdGVycykgewoJCSR0aGlzLT5fZm9vdGVycyA9ICR0aGlzLT5jaGVja1JvdygkZm9vdGVycyk7Cgl9CgoKCS8qKgoJICogQWRkIGEgcm93IHRvIHRoZSB0YWJsZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRyb3cgIFRoZSByb3cgZGF0YS4KCSAqIEBzZWUgY2xpXFRhYmxlOjpjaGVja1JvdygpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRSb3coYXJyYXkgJHJvdykgewoJCSR0aGlzLT5fcm93c1tdID0gJHRoaXMtPmNoZWNrUm93KCRyb3cpOwoJfQoKCS8qKgoJICogQ2xlYXJzIGFsbCBwcmV2aW91cyByb3dzIGFuZCBhZGRzIHRoZSBnaXZlbiByb3dzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHJvd3MgIEEgMi1kaW1lbnNpb25hbCBhcnJheSBvZiByb3cgZGF0YS4KCSAqIEBzZWUgY2xpXFRhYmxlOjphZGRSb3coKQoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0Um93cyhhcnJheSAkcm93cykgewoJCSR0aGlzLT5fcm93cyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoJHJvd3MgYXMgJHJvdykgewoJCQkkdGhpcy0+YWRkUm93KCRyb3cpOwoJCX0KCX0KCglwdWJsaWMgZnVuY3Rpb24gY291bnRSb3dzKCkgewoJCXJldHVybiBjb3VudCgkdGhpcy0+X3Jvd3MpOwoJfQoKCS8qKgoJICogU2V0IHdoZXRoZXIgaXRlbXMgaW4gYW4gQXNjaWkgdGFibGUgYXJlIHByZS1jb2xvcml6ZWQuCgkgKgoJICogQHBhcmFtIGJvb2x8YXJyYXkgJHByZWNvbG9yaXplZCBBIGJvb2xlYW4gdG8gc2V0IGFsbCBjb2x1bW5zIGluIHRoZSB0YWJsZSBhcyBwcmUtY29sb3JpemVkLCBvciBhbiBhcnJheSBvZiBib29sZWFucyBrZXllZCBieSBjb2x1bW4gaW5kZXggKG51bWJlcikgdG8gc2V0IGluZGl2aWR1YWwgY29sdW1ucyBhcyBwcmUtY29sb3JpemVkLgoJICogQHNlZSBjbGlcQXNjaWk6OnNldFByZUNvbG9yaXplZCgpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRBc2NpaVByZUNvbG9yaXplZCggJHByZV9jb2xvcml6ZWQgKSB7CgkJaWYgKCAkdGhpcy0+X3JlbmRlcmVyIGluc3RhbmNlb2YgQXNjaWkgKSB7CgkJCSR0aGlzLT5fcmVuZGVyZXItPnNldFByZUNvbG9yaXplZCggJHByZV9jb2xvcml6ZWQgKTsKCQl9Cgl9CgoJLyoqCgkgKiBJcyBhIGNvbHVtbiBpbiBhbiBBc2NpaSB0YWJsZSBwcmUtY29sb3JpemVkPwoJICoKCSAqIEBwYXJhbSBpbnQgJGNvbHVtbiBDb2x1bW4gaW5kZXggdG8gY2hlY2suCgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB3aG9sZSBBc2NpaSB0YWJsZSBpcyBtYXJrZWQgYXMgcHJlLWNvbG9yaXplZCwgb3IgaWYgdGhlIGluZGl2aWR1YWwgY29sdW1uIGlzIHByZS1jb2xvcml6ZWQ7IGVsc2UgZmFsc2UuCgkgKiBAc2VlIGNsaVxBc2NpaTo6aXNQcmVDb2xvcml6ZWQoKQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzQXNjaWlQcmVDb2xvcml6ZWQoICRjb2x1bW4gKSB7CgkJaWYgKCAkdGhpcy0+X3JlbmRlcmVyIGluc3RhbmNlb2YgQXNjaWkgKSB7CgkJCXJldHVybiAkdGhpcy0+X3JlbmRlcmVyLT5pc1ByZUNvbG9yaXplZCggJGNvbHVtbiApOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBjbGk7CgpjbGFzcyBTdHJlYW1zIHsKCglwcm90ZWN0ZWQgc3RhdGljICRvdXQgPSBTVERPVVQ7Cglwcm90ZWN0ZWQgc3RhdGljICRpbiA9IFNURElOOwoJcHJvdGVjdGVkIHN0YXRpYyAkZXJyID0gU1RERVJSOwoKCXN0YXRpYyBmdW5jdGlvbiBfY2FsbCggJGZ1bmMsICRhcmdzICkgewoJCSRtZXRob2QgPSBfX0NMQVNTX18gLiAnOjonIC4gJGZ1bmM7CgkJcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KCAkbWV0aG9kLCAkYXJncyApOwoJfQoKCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gaXNUdHkoKSB7CgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoJ3N0cmVhbV9pc2F0dHknKSApIHsKCQkJcmV0dXJuICFzdHJlYW1faXNhdHR5KHN0YXRpYzo6JG91dCk7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIChmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2lzYXR0eScpICYmICFwb3NpeF9pc2F0dHkoc3RhdGljOjokb3V0KSk7CgkJfQoJfQoKCS8qKgoJICogSGFuZGxlcyByZW5kZXJpbmcgc3RyaW5ncy4gSWYgZXh0cmEgc2NhbGFyIGFyZ3VtZW50cyBhcmUgZ2l2ZW4gYWZ0ZXIgdGhlIGAkbXNnYAoJICogdGhlIHN0cmluZyB3aWxsIGJlIHJlbmRlcmVkIHdpdGggYHNwcmludGZgLiBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGBhcnJheWAKCSAqIHRoZW4gZWFjaCBrZXkgaW4gdGhlIGFycmF5IHdpbGwgYmUgdGhlIHBsYWNlaG9sZGVyIG5hbWUuIFBsYWNlaG9sZGVycyBhcmUgb2YgdGhlCgkgKiBmb3JtYXQgezprZXl9LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAkbXNnICBUaGUgbWVzc2FnZSB0byByZW5kZXIuCgkgKiBAcGFyYW0gbWl4ZWQgICAgLi4uICAgRWl0aGVyIHNjYWxhciBhcmd1bWVudHMgb3IgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIHJlbmRlcmVkIHN0cmluZy4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZW5kZXIoICRtc2cgKSB7CgkJJGFyZ3MgPSBmdW5jX2dldF9hcmdzKCk7CgoJCS8vIE5vIHN0cmluZyByZXBsYWNlbWVudCBpcyBuZWVkZWQKCQlpZiggY291bnQoICRhcmdzICkgPT0gMSB8fCAoIGlzX3N0cmluZyggJGFyZ3NbMV0gKSAmJiAnJyA9PT0gJGFyZ3NbMV0gKSApIHsKCQkJcmV0dXJuIENvbG9yczo6c2hvdWxkQ29sb3JpemUoKSA/IENvbG9yczo6Y29sb3JpemUoICRtc2cgKSA6ICRtc2c7CgkJfQoKCQkvLyBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgbm90IGFuIGFycmF5IGp1c3QgcGFzcyB0byBzcHJpbnRmCgkJaWYoICFpc19hcnJheSggJGFyZ3NbMV0gKSApIHsKCQkJLy8gQ29sb3JpemUgdGhlIG1lc3NhZ2UgZmlyc3Qgc28gc3ByaW50ZiBkb2Vzbid0IGJpdGNoIGF0IHVzCgkJCWlmICggQ29sb3JzOjpzaG91bGRDb2xvcml6ZSgpICkgewoJCQkJJGFyZ3NbMF0gPSBDb2xvcnM6OmNvbG9yaXplKCAkYXJnc1swXSApOwoJCQl9CgoJCQkvLyBFc2NhcGUgcGVyY2VudCBjaGFyYWN0ZXJzIGZvciBzcHJpbnRmCgkJCSRhcmdzWzBdID0gcHJlZ19yZXBsYWNlKCcvKCUoW15cd118JCkpLycsICIlJDEiLCAkYXJnc1swXSk7CgoJCQlyZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoICdzcHJpbnRmJywgJGFyZ3MgKTsKCQl9CgoJCS8vIEhlcmUgd2UgZG8gbmFtZWQgcmVwbGFjZW1lbnQgc28gZm9ybWF0dGluZyBzdHJpbmdzIGFyZSBtb3JlIHVuZGVyc3RhbmRhYmxlCgkJZm9yZWFjaCggJGFyZ3NbMV0gYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCSRtc2cgPSBzdHJfcmVwbGFjZSggJ3s6JyAuICRrZXkgLiAnfScsICR2YWx1ZSwgJG1zZyApOwoJCX0KCQlyZXR1cm4gQ29sb3JzOjpzaG91bGRDb2xvcml6ZSgpID8gQ29sb3JzOjpjb2xvcml6ZSggJG1zZyApIDogJG1zZzsKCX0KCgkvKioKCSAqIFNob3J0Y3V0IGZvciBwcmludGluZyB0byBgU1RET1VUYC4gVGhlIG1lc3NhZ2UgYW5kIHBhcmFtZXRlcnMgYXJlIHBhc3NlZAoJICogdGhyb3VnaCBgc3ByaW50ZmAgYmVmb3JlIG91dHB1dC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkbXNnICBUaGUgbWVzc2FnZSB0byBvdXRwdXQgaW4gYHByaW50ZmAgZm9ybWF0LgoJICogQHBhcmFtIG1peGVkICAgLi4uICAgRWl0aGVyIHNjYWxhciBhcmd1bWVudHMgb3IgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIHZvaWQKCSAqIEBzZWUgXGNsaVxyZW5kZXIoKQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG91dCggJG1zZyApIHsKCQlmd3JpdGUoIHN0YXRpYzo6JG91dCwgc2VsZjo6X2NhbGwoICdyZW5kZXInLCBmdW5jX2dldF9hcmdzKCkgKSApOwoJfQoKCS8qKgoJICogUGFkcyBgJG1zZ2AgdG8gdGhlIHdpZHRoIG9mIHRoZSBzaGVsbCBiZWZvcmUgcGFzc2luZyB0byBgY2xpXG91dGAuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gcGFkIGFuZCBwYXNzIG9uLgoJICogQHBhcmFtIG1peGVkICAgLi4uICAgRWl0aGVyIHNjYWxhciBhcmd1bWVudHMgb3IgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIHZvaWQKCSAqIEBzZWUgY2xpXG91dCgpCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gb3V0X3BhZGRlZCggJG1zZyApIHsKCQkkbXNnID0gc2VsZjo6X2NhbGwoICdyZW5kZXInLCBmdW5jX2dldF9hcmdzKCkgKTsKCQlzZWxmOjpvdXQoIHN0cl9wYWQoICRtc2csIFxjbGlcU2hlbGw6OmNvbHVtbnMoKSApICk7Cgl9CgoJLyoqCgkgKiBQcmludHMgYSBtZXNzYWdlIHRvIGBTVERPVVRgIHdpdGggYSBuZXdsaW5lIGFwcGVuZGVkLiBTZWUgYFxjbGlcb3V0YCBmb3IKCSAqIG1vcmUgZG9jdW1lbnRhdGlvbi4KCSAqCgkgKiBAc2VlIGNsaVxvdXQoKQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxpbmUoICRtc2cgPSAnJyApIHsKCQkvLyBmdW5jX2dldF9hcmdzIGlzIGVtcHR5IGlmIG5vIGFyZ3MgYXJlIHBhc3NlZCBldmVuIHdpdGggdGhlIGRlZmF1bHQgYWJvdmUuCgkJJGFyZ3MgPSBhcnJheV9tZXJnZSggZnVuY19nZXRfYXJncygpLCBhcnJheSggJycgKSApOwoJCSRhcmdzWzBdIC49ICJcbiI7CgoJCXNlbGY6Ol9jYWxsKCAnb3V0JywgJGFyZ3MgKTsKCX0KCgkvKioKCSAqIFNob3J0Y3V0IGZvciBwcmludGluZyB0byBgU1RERVJSYC4gVGhlIG1lc3NhZ2UgYW5kIHBhcmFtZXRlcnMgYXJlIHBhc3NlZAoJICogdGhyb3VnaCBgc3ByaW50ZmAgYmVmb3JlIG91dHB1dC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkbXNnICBUaGUgbWVzc2FnZSB0byBvdXRwdXQgaW4gYHByaW50ZmAgZm9ybWF0LiBXaXRoIG5vIHN0cmluZywKCSAqICAgICAgICAgICAgICAgICAgICAgIGEgbmV3bGluZSBpcyBwcmludGVkLgoJICogQHBhcmFtIG1peGVkICAgLi4uICAgRWl0aGVyIHNjYWxhciBhcmd1bWVudHMgb3IgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcnIoICRtc2cgPSAnJyApIHsKCQkvLyBmdW5jX2dldF9hcmdzIGlzIGVtcHR5IGlmIG5vIGFyZ3MgYXJlIHBhc3NlZCBldmVuIHdpdGggdGhlIGRlZmF1bHQgYWJvdmUuCgkJJGFyZ3MgPSBhcnJheV9tZXJnZSggZnVuY19nZXRfYXJncygpLCBhcnJheSggJycgKSApOwoJCSRhcmdzWzBdIC49ICJcbiI7CgkJZndyaXRlKCBzdGF0aWM6OiRlcnIsIHNlbGY6Ol9jYWxsKCAncmVuZGVyJywgJGFyZ3MgKSApOwoJfQoKCS8qKgoJICogVGFrZXMgaW5wdXQgZnJvbSBgU1RESU5gIGluIHRoZSBnaXZlbiBmb3JtYXQuIElmIGFuIGVuZCBvZiB0cmFuc21pc3Npb24KCSAqIGNoYXJhY3RlciBpcyBzZW50ICheRCksIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJGZvcm1hdCAgQSB2YWxpZCBpbnB1dCBmb3JtYXQuIFNlZSBgZnNjYW5mYCBmb3IgZG9jdW1lbnRhdGlvbi4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgIElmIG5vbmUgaXMgZ2l2ZW4sIGFsbCBpbnB1dCB1cCB0byB0aGUgZmlyc3QgbmV3bGluZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgaXMgYWNjZXB0ZWQuCgkgKiBAcGFyYW0gYm9vbGVhbiAkaGlkZSAgICBJZiB0cnVlIHdpbGwgaGlkZSB3aGF0IHRoZSB1c2VyIHR5cGVzIGluLgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBpbnB1dCB3aXRoIHdoaXRlc3BhY2UgdHJpbW1lZC4KCSAqIEB0aHJvd3MgXEV4Y2VwdGlvbiAgVGhyb3duIGlmIGN0cmwtRCAoRU9UKSBpcyBzZW50IGFzIGlucHV0LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlucHV0KCAkZm9ybWF0ID0gbnVsbCwgJGhpZGUgPSBmYWxzZSApIHsKCQlpZiAoICRoaWRlICkKCQkJU2hlbGw6OmhpZGUoKTsKCgkJaWYoICRmb3JtYXQgKSB7CgkJCWZzY2FuZiggc3RhdGljOjokaW4sICRmb3JtYXQgLiAiXG4iLCAkbGluZSApOwoJCX0gZWxzZSB7CgkJCSRsaW5lID0gZmdldHMoIHN0YXRpYzo6JGluICk7CgkJfQoKCQlpZiAoICRoaWRlICkgewoJCQlTaGVsbDo6aGlkZSggZmFsc2UgKTsKCQkJZWNobyAiXG4iOwoJCX0KCgkJaWYoICRsaW5lID09PSBmYWxzZSApIHsKCQkJdGhyb3cgbmV3IFxFeGNlcHRpb24oICdDYXVnaHQgXkQgZHVyaW5nIGlucHV0JyApOwoJCX0KCgkJcmV0dXJuIHRyaW0oICRsaW5lICk7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5cyBhbiBpbnB1dCBwcm9tcHQuIElmIG5vIGRlZmF1bHQgdmFsdWUgaXMgcHJvdmlkZWQgdGhlIHByb21wdCB3aWxsCgkgKiBjb250aW51ZSBkaXNwbGF5aW5nIHVudGlsIGlucHV0IGlzIHJlY2VpdmVkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAgICAkcXVlc3Rpb24gVGhlIHF1ZXN0aW9uIHRvIGFzayB0aGUgdXNlci4KCSAqIEBwYXJhbSBib29sfHN0cmluZyAkZGVmYXVsdCAgQSBkZWZhdWx0IHZhbHVlIGlmIHRoZSB1c2VyIHByb3ZpZGVzIG5vIGlucHV0LgoJICogQHBhcmFtIHN0cmluZyAgICAgICRtYXJrZXIgICBBIHN0cmluZyB0byBhcHBlbmQgdG8gdGhlIHF1ZXN0aW9uIGFuZCBkZWZhdWx0IHZhbHVlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uIGRpc3BsYXkuCgkgKiBAcGFyYW0gYm9vbGVhbiAgICAgJGhpZGUgICAgIE9wdGlvbmFsbHkgaGlkZXMgd2hhdCB0aGUgdXNlciB0eXBlcyBpbi4KCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgdXNlcnMgaW5wdXQuCgkgKiBAc2VlIGNsaVxpbnB1dCgpCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvbXB0KCAkcXVlc3Rpb24sICRkZWZhdWx0ID0gbnVsbCwgJG1hcmtlciA9ICc6ICcsICRoaWRlID0gZmFsc2UgKSB7CgkJaWYoICRkZWZhdWx0ICYmIHN0cnBvcyggJHF1ZXN0aW9uLCAnWycgKSA9PT0gZmFsc2UgKSB7CgkJCSRxdWVzdGlvbiAuPSAnIFsnIC4gJGRlZmF1bHQgLiAnXSc7CgkJfQoKCQl3aGlsZSggdHJ1ZSApIHsKCQkJc2VsZjo6b3V0KCAkcXVlc3Rpb24gLiAkbWFya2VyICk7CgkJCSRsaW5lID0gc2VsZjo6aW5wdXQoIG51bGwsICRoaWRlICk7CgoJCQlpZiAoIHRyaW0oICRsaW5lICkgIT09ICcnICkKCQkJCXJldHVybiAkbGluZTsKCQkJaWYoICRkZWZhdWx0ICE9PSBmYWxzZSApCgkJCQlyZXR1cm4gJGRlZmF1bHQ7CgkJfQoJfQoKCS8qKgoJICogUHJlc2VudHMgYSB1c2VyIHdpdGggYSBtdWx0aXBsZSBjaG9pY2UgcXVlc3Rpb24sIHVzZWZ1bCBmb3IgJ3llcy9ubycgdHlwZQoJICogcXVlc3Rpb25zICh3aGljaCB0aGlzIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZGVmYXVsdHMgdG9vKS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkcXVlc3Rpb24gIFRoZSBxdWVzdGlvbiB0byBhc2sgdGhlIHVzZXIuCgkgKiBAcGFyYW0gc3RyaW5nICAkY2hvaWNlICAgIEEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgYWxsb3dlZCBhcyBhIHJlc3BvbnNlLiBDYXNlIGlzIGlnbm9yZWQuCgkgKiBAcGFyYW0gc3RyaW5nICAkZGVmYXVsdCAgIFRoZSBkZWZhdWx0IGNob2ljZS4gTlVMTCBpZiBhIGRlZmF1bHQgaXMgbm90IGFsbG93ZWQuCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIHVzZXJzIGNob2ljZS4KCSAqIEBzZWUgY2xpXHByb21wdCgpCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2hvb3NlKCAkcXVlc3Rpb24sICRjaG9pY2UgPSAneW4nLCAkZGVmYXVsdCA9ICduJyApIHsKCQlpZiggIWlzX3N0cmluZyggJGNob2ljZSApICkgewoJCQkkY2hvaWNlID0gam9pbiggJycsICRjaG9pY2UgKTsKCQl9CgoJCS8vIE1ha2UgZXZlcnkgY2hvaWNlIGNoYXJhY3RlciBsb3dlcmNhc2UgZXhjZXB0IHRoZSBkZWZhdWx0CgkJJGNob2ljZSA9IHN0cl9pcmVwbGFjZSggJGRlZmF1bHQsIHN0cnRvdXBwZXIoICRkZWZhdWx0ICksIHN0cnRvbG93ZXIoICRjaG9pY2UgKSApOwoJCS8vIFNlcGVyYXRlIGVhY2ggY2hvaWNlIHdpdGggYSBmb3J3YXJkLXNsYXNoCgkJJGNob2ljZXMgPSB0cmltKCBqb2luKCAnLycsIHByZWdfc3BsaXQoICcvLycsICRjaG9pY2UgKSApLCAnLycgKTsKCgkJd2hpbGUoIHRydWUgKSB7CgkJCSRsaW5lID0gc2VsZjo6cHJvbXB0KCBzcHJpbnRmKCAnJXM/IFslc10nLCAkcXVlc3Rpb24sICRjaG9pY2VzICksICRkZWZhdWx0LCAnJyApOwoKCQkJaWYoIHN0cmlwb3MoICRjaG9pY2UsICRsaW5lICkgIT09IGZhbHNlICkgewoJCQkJcmV0dXJuIHN0cnRvbG93ZXIoICRsaW5lICk7CgkJCX0KCQkJaWYoICFlbXB0eSggJGRlZmF1bHQgKSApIHsKCQkJCXJldHVybiBzdHJ0b2xvd2VyKCAkZGVmYXVsdCApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogRGlzcGxheXMgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhcyBhIG1lbnUgd2hlcmUgYSB1c2VyIGNhbiBlbnRlciBhIG51bWJlciB0bwoJICogY2hvb3NlIGFuIG9wdGlvbi4gVGhlIGFycmF5IG11c3QgYmUgYSBzaW5nbGUgZGltZW5zaW9uIHdpdGggZWl0aGVyIHN0cmluZ3MKCSAqIG9yIG9iamVjdHMgd2l0aCBhIGBfX3RvU3RyaW5nKClgIG1ldGhvZC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICAkaXRlbXMgICAgVGhlIGxpc3Qgb2YgaXRlbXMgdGhlIHVzZXIgY2FuIGNob29zZSBmcm9tLgoJICogQHBhcmFtIHN0cmluZyAgJGRlZmF1bHQgIFRoZSBpbmRleCBvZiB0aGUgZGVmYXVsdCBpdGVtLgoJICogQHBhcmFtIHN0cmluZyAgJHRpdGxlICAgIFRoZSBtZXNzYWdlIGRpc3BsYXllZCB0byB0aGUgdXNlciB3aGVuIHByb21wdGVkLgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBpbmRleCBvZiB0aGUgY2hvc2VuIGl0ZW0uCgkgKiBAc2VlIGNsaVxsaW5lKCkKCSAqIEBzZWUgY2xpXGlucHV0KCkKCSAqIEBzZWUgY2xpXGVycigpCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWVudSggJGl0ZW1zLCAkZGVmYXVsdCA9IG51bGwsICR0aXRsZSA9ICdDaG9vc2UgYW4gaXRlbScgKSB7CgkJJG1hcCA9IGFycmF5X3ZhbHVlcyggJGl0ZW1zICk7CgoJCWlmKCAkZGVmYXVsdCAmJiBzdHJwb3MoICR0aXRsZSwgJ1snICkgPT09IGZhbHNlICYmIGlzc2V0KCAkaXRlbXNbJGRlZmF1bHRdICkgKSB7CgkJCSR0aXRsZSAuPSAnIFsnIC4gJGl0ZW1zWyRkZWZhdWx0XSAuICddJzsKCQl9CgoJCWZvcmVhY2goICRtYXAgYXMgJGlkeCA9PiAkaXRlbSApIHsKCQkJc2VsZjo6bGluZSggJyAgJWQuICVzJywgJGlkeCArIDEsIChzdHJpbmcpJGl0ZW0gKTsKCQl9CgkJc2VsZjo6bGluZSgpOwoKCQl3aGlsZSggdHJ1ZSApIHsKCQkJZndyaXRlKCBzdGF0aWM6OiRvdXQsIHNwcmludGYoICclczogJywgJHRpdGxlICkgKTsKCQkJJGxpbmUgPSBzZWxmOjppbnB1dCgpOwoKCQkJaWYoIGlzX251bWVyaWMoICRsaW5lICkgKSB7CgkJCQkkbGluZS0tOwoJCQkJaWYoIGlzc2V0KCAkbWFwWyRsaW5lXSApICkgewoJCQkJCXJldHVybiBhcnJheV9zZWFyY2goICRtYXBbJGxpbmVdLCAkaXRlbXMgKTsKCQkJCX0KCgkJCQlpZiggJGxpbmUgPCAwIHx8ICRsaW5lID49IGNvdW50KCAkbWFwICkgKSB7CgkJCQkJc2VsZjo6ZXJyKCAnSW52YWxpZCBtZW51IHNlbGVjdGlvbjogb3V0IG9mIHJhbmdlJyApOwoJCQkJfQoJCQl9IGVsc2UgaWYoIGlzc2V0KCAkZGVmYXVsdCApICkgewoJCQkJcmV0dXJuICRkZWZhdWx0OwoJCQl9CgkJfQoJfQoKCS8qKgoJICogU2V0cyBvbmUgb2YgdGhlIHN0cmVhbXMgKGlucHV0LCBvdXRwdXQsIG9yIGVycm9yKSB0byBhIGBzdHJlYW1gIHR5cGUgcmVzb3VyY2UuCgkgKgoJICogVmFsaWQgJHdoaWNoU3RyZWFtIHZhbHVlcyBhcmU6CgkgKiAgICAtICdpbicgICAoZGVmYXVsdDogU1RESU4pCgkgKiAgICAtICdvdXQnICAoZGVmYXVsdDogU1RET1VUKQoJICogICAgLSAnZXJyJyAgKGRlZmF1bHQ6IFNUREVSUikKCSAqCgkgKiBBbnkgY3VzdG9tIHN0cmVhbXMgd2lsbCBiZSBjbG9zZWQgZm9yIHlvdSBvbiBzaHV0ZG93biwgc28gcGxlYXNlIGRvbid0IGNsb3NlIHN0cmVhbQoJICogcmVzb3VyY2VzIHVzZWQgd2l0aCB0aGlzIG1ldGhvZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICR3aGljaFN0cmVhbSAgVGhlIHN0cmVhbSBwcm9wZXJ0eSB0byB1cGRhdGUKCSAqIEBwYXJhbSByZXNvdXJjZSAgJHN0cmVhbSAgICAgICBUaGUgbmV3IHN0cmVhbSByZXNvdXJjZSB0byB1c2UKCSAqIEByZXR1cm4gdm9pZAoJICogQHRocm93cyBcRXhjZXB0aW9uIFRocm93biBpZiAkc3RyZWFtIGlzIG5vdCBhIHJlc291cmNlIG9mIHRoZSAnc3RyZWFtJyB0eXBlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldFN0cmVhbSggJHdoaWNoU3RyZWFtLCAkc3RyZWFtICkgewoJCWlmKCAhaXNfcmVzb3VyY2UoICRzdHJlYW0gKSB8fCBnZXRfcmVzb3VyY2VfdHlwZSggJHN0cmVhbSApICE9PSAnc3RyZWFtJyApIHsKCQkJdGhyb3cgbmV3IFxFeGNlcHRpb24oICdJbnZhbGlkIHJlc291cmNlIHR5cGUhJyApOwoJCX0KCQlpZiggcHJvcGVydHlfZXhpc3RzKCBfX0NMQVNTX18sICR3aGljaFN0cmVhbSApICkgewoJCQlzdGF0aWM6OiR7JHdoaWNoU3RyZWFtfSA9ICRzdHJlYW07CgkJfQoJCXJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKCBmdW5jdGlvbigpIHVzZSAoJHN0cmVhbSkgewoJCQlmY2xvc2UoICRzdHJlYW0gKTsKCQl9ICk7Cgl9Cgp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcYXJndW1lbnRzOwoKLyoqCiAqIFRocm93biB3aGVuIHVuZGVmaW5lZCBhcmd1bWVudHMgYXJlIGRldGVjdGVkIGluIHN0cmljdCBtb2RlLgogKi8KY2xhc3MgSW52YWxpZEFyZ3VtZW50cyBleHRlbmRzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gewoJcHJvdGVjdGVkICRhcmd1bWVudHM7CgoJLyoqCgkgKiBAcGFyYW0gYXJyYXkgICRhcmd1bWVudHMgIEEgbGlzdCBvZiBhcmd1bWVudHMgdGhhdCBkbyBub3QgZml0IHRoZSBwcm9maWxlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGFyZ3VtZW50cykgewoJCSR0aGlzLT5hcmd1bWVudHMgPSAkYXJndW1lbnRzOwoJCSR0aGlzLT5tZXNzYWdlID0gJHRoaXMtPl9nZW5lcmF0ZU1lc3NhZ2UoKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgYXJndW1lbnRzIHRoYXQgY2F1c2VkIHRoZSBleGNlcHRpb24uCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRzKCkgewoJCXJldHVybiAkdGhpcy0+YXJndW1lbnRzOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX2dlbmVyYXRlTWVzc2FnZSgpIHsKCQlyZXR1cm4gJ3Vua25vd24gYXJndW1lbnQnIC4KCQkJKGNvdW50KCR0aGlzLT5hcmd1bWVudHMpID4gMSA/ICdzJyA6ICcnKSAuCgkJCSc6ICcgLiBqb2luKCcsICcsICR0aGlzLT5hcmd1bWVudHMpOwoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcYXJndW1lbnRzOwoKdXNlIGNsaVxNZW1vaXplOwoKLyoqCiAqIFJlcHJlc2VudHMgYW4gQXJndW1lbnQgb3IgYSB2YWx1ZSBhbmQgcHJvdmlkZXMgc2V2ZXJhbCBoZWxwZXJzIHJlbGF0ZWQgdG8gcGFyc2luZyBhbiBhcmd1bWVudCBsaXN0LgogKi8KY2xhc3MgQXJndW1lbnQgZXh0ZW5kcyBNZW1vaXplIHsKCS8qKgoJICogVGhlIGNhbm9uaWNhbCBuYW1lIG9mIHRoaXMgYXJndW1lbnQsIHVzZWQgZm9yIGFsaWFzaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcKCSAqLwoJcHVibGljICRrZXk7CgoJcHJpdmF0ZSAkX2FyZ3VtZW50OwoJcHJpdmF0ZSAkX3JhdzsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgICRhcmd1bWVudCAgVGhlIHJhdyBhcmd1bWVudCwgbGVhZGluZyBkYXNoZXMgaW5jbHVkZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYXJndW1lbnQpIHsKCQkkdGhpcy0+X3JhdyA9ICRhcmd1bWVudDsKCQkkdGhpcy0+a2V5ID0mICR0aGlzLT5fYXJndW1lbnQ7CgoJCWlmICgkdGhpcy0+aXNMb25nKSB7CgkJCSR0aGlzLT5fYXJndW1lbnQgPSBzdWJzdHIoJHRoaXMtPl9yYXcsIDIpOwoJCX0gZWxzZSBpZiAoJHRoaXMtPmlzU2hvcnQpIHsKCQkJJHRoaXMtPl9hcmd1bWVudCA9IHN1YnN0cigkdGhpcy0+X3JhdywgMSk7CgkJfSBlbHNlIHsKCQkJJHRoaXMtPl9hcmd1bWVudCA9ICR0aGlzLT5fcmF3OwoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJhdyBpbnB1dCBhcyBhIHN0cmluZy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpIHsKCQlyZXR1cm4gKHN0cmluZykkdGhpcy0+X3JhdzsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGZvcm1hdHRlZCBhcmd1bWVudCBzdHJpbmcuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHZhbHVlKCkgewoJCXJldHVybiAkdGhpcy0+X2FyZ3VtZW50OwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcmF3IGlucHV0LgoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJhdygpIHsKCQlyZXR1cm4gJHRoaXMtPl9yYXc7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBtYXRjaGVzIHRoZSBwYXR0ZXJuIGZvciBsb25nIGFyZ3VtZW50cy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzTG9uZygpIHsKCQlyZXR1cm4gKDAgPT0gc3RybmNtcCgkdGhpcy0+X3JhdywgJy0tJywgMikpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBzdHJpbmcgbWF0Y2hlcyB0aGUgcGF0dGVybiBmb3Igc2hvcnQgYXJndW1lbnRzLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNTaG9ydCgpIHsKCQlyZXR1cm4gISR0aGlzLT5pc0xvbmcgJiYgKDAgPT0gc3RybmNtcCgkdGhpcy0+X3JhdywgJy0nLCAxKSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBtYXRjaGVzIHRoZSBwYXR0ZXJuIGZvciBhcmd1bWVudHMuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc0FyZ3VtZW50KCkgewoJCXJldHVybiAkdGhpcy0+aXNTaG9ydCgpIHx8ICR0aGlzLT5pc0xvbmcoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3RyaW5nIG1hdGNoZXMgdGhlIHBhdHRlcm4gZm9yIHZhbHVlcy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzVmFsdWUoKSB7CgkJcmV0dXJuICEkdGhpcy0+aXNBcmd1bWVudDsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXJndW1lbnQgaXMgc2hvcnQgYnV0IGNvbnRhaW5zIHNldmVyYWwgY2hhcmFjdGVycy4gRWFjaAoJICogY2hhcmFjdGVyIGlzIGNvbnNpZGVyZWQgYSBzZXBhcmF0ZSBhcmd1bWVudC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNhbkV4cGxvZGUoKSB7CgkJcmV0dXJuICR0aGlzLT5pc1Nob3J0ICYmIHN0cmxlbigkdGhpcy0+X2FyZ3VtZW50KSA+IDE7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFsbCBidXQgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgYXJndW1lbnQsIHJlbW92aW5nIHRoZW0gZnJvbSB0aGUKCSAqIG9iamVjdHMgcmVwcmVzZW50YXRpb24gYXQgdGhlIHNhbWUgdGltZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBleHBsb2RlZCgpIHsKCQkkZXhwbG9kZWQgPSBhcnJheSgpOwoKCQlmb3IgKCRpID0gc3RybGVuKCR0aGlzLT5fYXJndW1lbnQpOyAkaSA+IDA7ICRpLS0pIHsKCQkJYXJyYXlfcHVzaCgkZXhwbG9kZWQsICR0aGlzLT5fYXJndW1lbnRbJGkgLSAxXSk7CgkJfQoKCQkkdGhpcy0+X2FyZ3VtZW50ID0gYXJyYXlfcG9wKCRleHBsb2RlZCk7CgkJJHRoaXMtPl9yYXcgICAgICA9ICctJyAuICR0aGlzLT5fYXJndW1lbnQ7CgkJcmV0dXJuICRleHBsb2RlZDsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXGFyZ3VtZW50czsKCnVzZSBjbGlcTWVtb2l6ZTsKCmNsYXNzIExleGVyIGV4dGVuZHMgTWVtb2l6ZSBpbXBsZW1lbnRzIFxJdGVyYXRvciB7Cglwcml2YXRlICRfaXRlbXMgPSBhcnJheSgpOwoJcHJpdmF0ZSAkX2luZGV4ID0gMDsKCXByaXZhdGUgJF9sZW5ndGggPSAwOwoJcHJpdmF0ZSAkX2ZpcnN0ID0gdHJ1ZTsKCgkvKioKCSAqIEBwYXJhbSBhcnJheSAgJGl0ZW1zICBBIGxpc3Qgb2Ygc3RyaW5ncyB0byBwcm9jZXNzIGFzIHRva2Vucy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRpdGVtcykgewoJCSR0aGlzLT5faXRlbXMgPSAkaXRlbXM7CgkJJHRoaXMtPl9sZW5ndGggPSBjb3VudCgkaXRlbXMpOwoJfQoKCS8qKgoJICogVGhlIGN1cnJlbnQgdG9rZW4uCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJcmV0dXJuICR0aGlzLT5faXRlbTsKCX0KCgkvKioKCSAqIFBlZWsgYWhlYWQgdG8gdGhlIG5leHQgdG9rZW4gd2l0aG91dCBtb3ZpbmcgdGhlIGN1cnNvci4KCSAqCgkgKiBAcmV0dXJuIEFyZ3VtZW50CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwZWVrKCkgewoJCXJldHVybiBuZXcgQXJndW1lbnQoJHRoaXMtPl9pdGVtc1swXSk7Cgl9CgoJLyoqCgkgKiBNb3ZlIHRoZSBjdXJzb3IgZm9yd2FyZCAxIGVsZW1lbnQgaWYgaXQgaXMgdmFsaWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBuZXh0KCkgewoJCWlmICgkdGhpcy0+dmFsaWQoKSkgewoJCQkkdGhpcy0+X3NoaWZ0KCk7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBjdXJzb3IuCgkgKgoJICogQHJldHVybiBpbnQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGtleSgpIHsKCQlyZXR1cm4gJHRoaXMtPl9pbmRleDsKCX0KCgkvKioKCSAqIE1vdmUgZm9yd2FyZCAxIGVsZW1lbnQgYW5kLCBpZiB0aGUgbWV0aG9kIGhhc24ndCBiZWVuIGNhbGxlZCBiZWZvcmUsIHJlc2V0CgkgKiB0aGUgY3Vyc29yJ3MgcG9zaXRpb24gdG8gMC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJld2luZCgpIHsKCQkkdGhpcy0+X3NoaWZ0KCk7CgkJaWYgKCR0aGlzLT5fZmlyc3QpIHsKCQkJJHRoaXMtPl9pbmRleCA9IDA7CgkJCSR0aGlzLT5fZmlyc3QgPSBmYWxzZTsKCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnNvciBoYXMgbm90IHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgbGlzdC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHZhbGlkKCkgewoJCXJldHVybiAoJHRoaXMtPl9pbmRleCA8ICR0aGlzLT5fbGVuZ3RoKTsKCX0KCgkvKioKCSAqIFB1c2ggYW4gZWxlbWVudCB0byB0aGUgZnJvbnQgb2YgdGhlIHN0YWNrLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAgJGl0ZW0gIFRoZSB2YWx1ZSB0byBzZXQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuc2hpZnQoJGl0ZW0pIHsKCQlhcnJheV91bnNoaWZ0KCR0aGlzLT5faXRlbXMsICRpdGVtKTsKCQkkdGhpcy0+X2xlbmd0aCArPSAxOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBjdXJzb3IgaXMgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVuZCgpIHsKCQlyZXR1cm4gKCR0aGlzLT5faW5kZXggKyAxKSA9PSAkdGhpcy0+X2xlbmd0aDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9zaGlmdCgpIHsKCQkkdGhpcy0+X2l0ZW0gPSBuZXcgQXJndW1lbnQoYXJyYXlfc2hpZnQoJHRoaXMtPl9pdGVtcykpOwoJCSR0aGlzLT5faW5kZXggKz0gMTsKCQkkdGhpcy0+X2V4cGxvZGUoKTsKCQkkdGhpcy0+X3VubWVtbygncGVlaycpOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX2V4cGxvZGUoKSB7CgkJaWYgKCEkdGhpcy0+X2l0ZW0tPmNhbkV4cGxvZGUpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJZm9yZWFjaCAoJHRoaXMtPl9pdGVtLT5leHBsb2RlZCBhcyAkcGllY2UpIHsKCQkJJHRoaXMtPnVuc2hpZnQoJy0nIC4gJHBpZWNlKTsKCQl9Cgl9Cn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaVxhcmd1bWVudHM7Cgp1c2UgY2xpXEFyZ3VtZW50czsKCi8qKgogKiBBcmd1bWVudHMgaGVscCBzY3JlZW4gcmVuZGVyZXIKICovCmNsYXNzIEhlbHBTY3JlZW4gewoJcHJvdGVjdGVkICRfZmxhZ3MgPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfbWF4RmxhZyA9IDA7Cglwcm90ZWN0ZWQgJF9vcHRpb25zID0gYXJyYXkoKTsKCXByb3RlY3RlZCAkX21heE9wdGlvbiA9IDA7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEFyZ3VtZW50cyAkYXJndW1lbnRzKSB7CgkJJHRoaXMtPnNldEFyZ3VtZW50cygkYXJndW1lbnRzKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpIHsKCQlyZXR1cm4gJHRoaXMtPnJlbmRlcigpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudHMoQXJndW1lbnRzICRhcmd1bWVudHMpIHsKCQkkdGhpcy0+Y29uc3VtZUFyZ3VtZW50RmxhZ3MoJGFyZ3VtZW50cyk7CgkJJHRoaXMtPmNvbnN1bWVBcmd1bWVudE9wdGlvbnMoJGFyZ3VtZW50cyk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNvbnN1bWVBcmd1bWVudEZsYWdzKEFyZ3VtZW50cyAkYXJndW1lbnRzKSB7CgkJJGRhdGEgPSAkdGhpcy0+X2NvbnN1bWUoJGFyZ3VtZW50cy0+Z2V0RmxhZ3MoKSk7CgoJCSR0aGlzLT5fZmxhZ3MgPSAkZGF0YVswXTsKCQkkdGhpcy0+X2ZsYWdNYXggPSAkZGF0YVsxXTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY29uc3VtZUFyZ3VtZW50T3B0aW9ucyhBcmd1bWVudHMgJGFyZ3VtZW50cykgewoJCSRkYXRhID0gJHRoaXMtPl9jb25zdW1lKCRhcmd1bWVudHMtPmdldE9wdGlvbnMoKSk7CgoJCSR0aGlzLT5fb3B0aW9ucyA9ICRkYXRhWzBdOwoJCSR0aGlzLT5fb3B0aW9uTWF4ID0gJGRhdGFbMV07Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHJlbmRlcigpIHsKCQkkaGVscCA9IGFycmF5KCk7CgoJCWFycmF5X3B1c2goJGhlbHAsICR0aGlzLT5fcmVuZGVyRmxhZ3MoKSk7CgkJYXJyYXlfcHVzaCgkaGVscCwgJHRoaXMtPl9yZW5kZXJPcHRpb25zKCkpOwoKCQlyZXR1cm4gam9pbigiXG5cbiIsICRoZWxwKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9yZW5kZXJGbGFncygpIHsKCQlpZiAoZW1wdHkoJHRoaXMtPl9mbGFncykpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlyZXR1cm4gIkZsYWdzXG4iIC4gJHRoaXMtPl9yZW5kZXJTY3JlZW4oJHRoaXMtPl9mbGFncywgJHRoaXMtPl9mbGFnTWF4KTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9yZW5kZXJPcHRpb25zKCkgewoJCWlmIChlbXB0eSgkdGhpcy0+X29wdGlvbnMpKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJcmV0dXJuICJPcHRpb25zXG4iIC4gJHRoaXMtPl9yZW5kZXJTY3JlZW4oJHRoaXMtPl9vcHRpb25zLCAkdGhpcy0+X29wdGlvbk1heCk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBfcmVuZGVyU2NyZWVuKCRvcHRpb25zLCAkbWF4KSB7CgkJJGhlbHAgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCRvcHRpb25zIGFzICRvcHRpb24gPT4gJHNldHRpbmdzKSB7CgkJCSRmb3JtYXR0ZWQgPSAnICAnIC4gc3RyX3BhZCgkb3B0aW9uLCAkbWF4KTsKCgkJCSRkbGVuID0gODAgLSA0IC0gJG1heDsKCgkJCSRkZXNjcmlwdGlvbiA9IHN0cl9zcGxpdCgkc2V0dGluZ3NbJ2Rlc2NyaXB0aW9uJ10sICRkbGVuKTsKCQkJJGZvcm1hdHRlZC49ICcgICcgLiBhcnJheV9zaGlmdCgkZGVzY3JpcHRpb24pOwoKCQkJaWYgKCRzZXR0aW5nc1snZGVmYXVsdCddKSB7CgkJCQkkZm9ybWF0dGVkIC49ICcgW2RlZmF1bHQ6ICcgLiAkc2V0dGluZ3NbJ2RlZmF1bHQnXSAuICddJzsKCQkJfQoKCQkJJHBhZCA9IHN0cl9yZXBlYXQoJyAnLCAkbWF4ICsgMyk7CgkJCXdoaWxlICgkZGVzYyA9IGFycmF5X3NoaWZ0KCRkZXNjcmlwdGlvbikpIHsKCQkJCSRmb3JtYXR0ZWQgLj0gIlxuJHtwYWR9JHtkZXNjfSI7CgkJCX0KCgkJCWFycmF5X3B1c2goJGhlbHAsICRmb3JtYXR0ZWQpOwoJCX0KCgkJcmV0dXJuIGpvaW4oIlxuIiwgJGhlbHApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX2NvbnN1bWUoJG9wdGlvbnMpIHsKCQkkbWF4ID0gMDsKCQkkb3V0ID0gYXJyYXkoKTsKCgkJZm9yZWFjaCAoJG9wdGlvbnMgYXMgJG9wdGlvbiA9PiAkc2V0dGluZ3MpIHsKCQkJJG5hbWVzID0gYXJyYXkoJy0tJyAuICRvcHRpb24pOwoKCQkJZm9yZWFjaCAoJHNldHRpbmdzWydhbGlhc2VzJ10gYXMgJGFsaWFzKSB7CgkJCQlhcnJheV9wdXNoKCRuYW1lcywgJy0nIC4gJGFsaWFzKTsKCQkJfQoKCQkJJG5hbWVzID0gam9pbignLCAnLCAkbmFtZXMpOwoJCQkkbWF4ID0gbWF4KHN0cmxlbigkbmFtZXMpLCAkbWF4KTsKCQkJJG91dFskbmFtZXNdID0gJHNldHRpbmdzOwoJCX0KCgkJcmV0dXJuIGFycmF5KCRvdXQsICRtYXgpOwoJfQp9Cgo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKYWJzdHJhY3QgY2xhc3MgTWVtb2l6ZSB7Cglwcm90ZWN0ZWQgJF9tZW1vQ2FjaGUgPSBhcnJheSgpOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkgewoJCWlmIChpc3NldCgkdGhpcy0+X21lbW9DYWNoZVskbmFtZV0pKSB7CgkJCXJldHVybiAkdGhpcy0+X21lbW9DYWNoZVskbmFtZV07CgkJfQoKCQkvLyBIaWRlIHByb2JhYmxlIHByaXZhdGUgbWV0aG9kcwoJCWlmICgwID09IHN0cm5jbXAoJG5hbWUsICdfJywgMSkpIHsKCQkJcmV0dXJuICgkdGhpcy0+X21lbW9DYWNoZVskbmFtZV0gPSBudWxsKTsKCQl9CgoJCWlmICghbWV0aG9kX2V4aXN0cygkdGhpcywgJG5hbWUpKSB7CgkJCXJldHVybiAoJHRoaXMtPl9tZW1vQ2FjaGVbJG5hbWVdID0gbnVsbCk7CgkJfQoKCQkkbWV0aG9kID0gYXJyYXkoJHRoaXMsICRuYW1lKTsKCQkoJHRoaXMtPl9tZW1vQ2FjaGVbJG5hbWVdID0gY2FsbF91c2VyX2Z1bmMoJG1ldGhvZCkpOwoJCXJldHVybiAkdGhpcy0+X21lbW9DYWNoZVskbmFtZV07Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIF91bm1lbW8oJG5hbWUpIHsKCQlpZiAoJG5hbWUgPT09IHRydWUpIHsKCQkJJHRoaXMtPl9tZW1vQ2FjaGUgPSBhcnJheSgpOwoJCX0gZWxzZSB7CgkJCXVuc2V0KCR0aGlzLT5fbWVtb0NhY2hlWyRuYW1lXSk7CgkJfQoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgUnlhbiBTdWxsaXZhbiA8cnN1bGxpdmFuQGNvbm5lY3RzdHVkaW9zLmNvbT4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcdHJlZTsKCi8qKgogKiBUcmVlIHJlbmRlcmVycyBhcmUgdXNlZCB0byBjaGFuZ2UgaG93IGEgdHJlZSBpcyBkaXNwbGF5ZWQuCiAqLwphYnN0cmFjdCBjbGFzcyBSZW5kZXJlciB7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRyZWUKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHJlbmRlcihhcnJheSAkdHJlZSk7Cgp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgUnlhbiBTdWxsaXZhbiA8cnN1bGxpdmFuQGNvbm5lY3RzdHVkaW9zLmNvbT4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcdHJlZTsKCi8qKgogKiBUaGUgQVNDSUkgcmVuZGVyZXIgcmVuZGVycyB0cmVlcyB3aXRoIEFTQ0lJIGxpbmVzLgogKi8KY2xhc3MgQXNjaWkgZXh0ZW5kcyBSZW5kZXJlciB7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRyZWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXIoYXJyYXkgJHRyZWUpCiAgICB7CiAgICAgICAgJG91dHB1dCA9ICcnOwoKICAgICAgICAkdHJlZUl0ZXJhdG9yID0gbmV3IFxSZWN1cnNpdmVUcmVlSXRlcmF0b3IoCiAgICAgICAgICAgIG5ldyBcUmVjdXJzaXZlQXJyYXlJdGVyYXRvcigkdHJlZSksCiAgICAgICAgICAgIFxSZWN1cnNpdmVUcmVlSXRlcmF0b3I6OlNFTEZfRklSU1QKICAgICAgICApOwoKICAgICAgICBmb3JlYWNoICgkdHJlZUl0ZXJhdG9yIGFzICR2YWwpCiAgICAgICAgewogICAgICAgICAgICAkb3V0cHV0IC49ICR2YWwgLiAiXG4iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9Cgp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgUnlhbiBTdWxsaXZhbiA8cnN1bGxpdmFuQGNvbm5lY3RzdHVkaW9zLmNvbT4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcdHJlZTsKCi8qKgogKiBUaGUgQVNDSUkgcmVuZGVyZXIgcmVuZGVycyB0cmVlcyB3aXRoIEFTQ0lJIGxpbmVzLgogKi8KY2xhc3MgTWFya2Rvd24gZXh0ZW5kcyBSZW5kZXJlciB7CgogICAgLyoqCiAgICAgKiBIb3cgbWFueSBzcGFjZXMgdG8gaW5kZW50IGJ5CiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJF9wYWRkaW5nID0gMjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJHBhZGRpbmcgT3B0aW9uYWwuIERlZmF1bHQgMi4KICAgICAqLwogICAgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHBhZGRpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmICgkcGFkZGluZykKICAgICAgICB7CiAgICAgICAgICAgICR0aGlzLT5fcGFkZGluZyA9ICRwYWRkaW5nOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlcnMgdGhlIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRyZWUKICAgICAqIEBwYXJhbSBpbnQgJGxldmVsIE9wdGlvbmFsCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVyKGFycmF5ICR0cmVlLCAkbGV2ZWwgPSAwKQogICAgewogICAgICAgICRvdXRwdXQgPSAnJzsKCiAgICAgICAgZm9yZWFjaCAoJHRyZWUgYXMgJGxhYmVsID0+ICRuZXh0KQogICAgICAgIHsKCiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJG5leHQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAkbGFiZWwgPSAkbmV4dDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gT3V0cHV0IHRoZSBsYWJlbAogICAgICAgICAgICAkb3V0cHV0IC49IHNwcmludGYoIiVzLSAlc1xuIiwgc3RyX3JlcGVhdCgnICcsICRsZXZlbCAqICR0aGlzLT5fcGFkZGluZyksICRsYWJlbCk7CgogICAgICAgICAgICAvLyBOZXh0IGxldmVsCiAgICAgICAgICAgIGlmIChpc19hcnJheSgkbmV4dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICRvdXRwdXQgLj0gJHRoaXMtPnJlbmRlcigkbmV4dCwgJGxldmVsICsgMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG91dHB1dDsKICAgIH0KCn0KPD9waHAKCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGk7CgovKioKICogSGFuZGxlcyByZW5kZXJpbmcgc3RyaW5ncy4gSWYgZXh0cmEgc2NhbGFyIGFyZ3VtZW50cyBhcmUgZ2l2ZW4gYWZ0ZXIgdGhlIGAkbXNnYAogKiB0aGUgc3RyaW5nIHdpbGwgYmUgcmVuZGVyZWQgd2l0aCBgc3ByaW50ZmAuIElmIHRoZSBzZWNvbmQgYXJndW1lbnQgaXMgYW4gYGFycmF5YAogKiB0aGVuIGVhY2gga2V5IGluIHRoZSBhcnJheSB3aWxsIGJlIHRoZSBwbGFjZWhvbGRlciBuYW1lLiBQbGFjZWhvbGRlcnMgYXJlIG9mIHRoZQogKiBmb3JtYXQgezprZXl9LgogKgogKiBAcGFyYW0gc3RyaW5nICAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gcmVuZGVyLgogKiBAcGFyYW0gbWl4ZWQgICAgLi4uICAgRWl0aGVyIHNjYWxhciBhcmd1bWVudHMgb3IgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQuCiAqIEByZXR1cm4gc3RyaW5nICBUaGUgcmVuZGVyZWQgc3RyaW5nLgogKi8KZnVuY3Rpb24gcmVuZGVyKCAkbXNnICkgewoJcmV0dXJuIFN0cmVhbXM6Ol9jYWxsKCAncmVuZGVyJywgZnVuY19nZXRfYXJncygpICk7Cn0KCi8qKgogKiBTaG9ydGN1dCBmb3IgcHJpbnRpbmcgdG8gYFNURE9VVGAuIFRoZSBtZXNzYWdlIGFuZCBwYXJhbWV0ZXJzIGFyZSBwYXNzZWQKICogdGhyb3VnaCBgc3ByaW50ZmAgYmVmb3JlIG91dHB1dC4KICoKICogQHBhcmFtIHN0cmluZyAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gb3V0cHV0IGluIGBwcmludGZgIGZvcm1hdC4KICogQHBhcmFtIG1peGVkICAgLi4uICAgRWl0aGVyIHNjYWxhciBhcmd1bWVudHMgb3IgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQuCiAqIEByZXR1cm4gdm9pZAogKiBAc2VlIFxjbGlccmVuZGVyKCkKICovCmZ1bmN0aW9uIG91dCggJG1zZyApIHsKCVN0cmVhbXM6Ol9jYWxsKCAnb3V0JywgZnVuY19nZXRfYXJncygpICk7Cn0KCi8qKgogKiBQYWRzIGAkbXNnYCB0byB0aGUgd2lkdGggb2YgdGhlIHNoZWxsIGJlZm9yZSBwYXNzaW5nIHRvIGBjbGlcb3V0YC4KICoKICogQHBhcmFtIHN0cmluZyAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gcGFkIGFuZCBwYXNzIG9uLgogKiBAcGFyYW0gbWl4ZWQgICAuLi4gICBFaXRoZXIgc2NhbGFyIGFyZ3VtZW50cyBvciBhIHNpbmdsZSBhcnJheSBhcmd1bWVudC4KICogQHJldHVybiB2b2lkCiAqIEBzZWUgY2xpXG91dCgpCiAqLwpmdW5jdGlvbiBvdXRfcGFkZGVkKCAkbXNnICkgewoJU3RyZWFtczo6X2NhbGwoICdvdXRfcGFkZGVkJywgZnVuY19nZXRfYXJncygpICk7Cn0KCi8qKgogKiBQcmludHMgYSBtZXNzYWdlIHRvIGBTVERPVVRgIHdpdGggYSBuZXdsaW5lIGFwcGVuZGVkLiBTZWUgYFxjbGlcb3V0YCBmb3IKICogbW9yZSBkb2N1bWVudGF0aW9uLgogKgogKiBAc2VlIGNsaVxvdXQoKQogKi8KZnVuY3Rpb24gbGluZSggJG1zZyA9ICcnICkgewoJU3RyZWFtczo6X2NhbGwoICdsaW5lJywgZnVuY19nZXRfYXJncygpICk7Cn0KCi8qKgogKiBTaG9ydGN1dCBmb3IgcHJpbnRpbmcgdG8gYFNUREVSUmAuIFRoZSBtZXNzYWdlIGFuZCBwYXJhbWV0ZXJzIGFyZSBwYXNzZWQKICogdGhyb3VnaCBgc3ByaW50ZmAgYmVmb3JlIG91dHB1dC4KICoKICogQHBhcmFtIHN0cmluZyAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gb3V0cHV0IGluIGBwcmludGZgIGZvcm1hdC4gV2l0aCBubyBzdHJpbmcsCiAqICAgICAgICAgICAgICAgICAgICAgIGEgbmV3bGluZSBpcyBwcmludGVkLgogKiBAcGFyYW0gbWl4ZWQgICAuLi4gICBFaXRoZXIgc2NhbGFyIGFyZ3VtZW50cyBvciBhIHNpbmdsZSBhcnJheSBhcmd1bWVudC4KICogQHJldHVybiB2b2lkCiAqLwpmdW5jdGlvbiBlcnIoICRtc2cgPSAnJyApIHsKCVN0cmVhbXM6Ol9jYWxsKCAnZXJyJywgZnVuY19nZXRfYXJncygpICk7Cn0KCi8qKgogKiBUYWtlcyBpbnB1dCBmcm9tIGBTVERJTmAgaW4gdGhlIGdpdmVuIGZvcm1hdC4gSWYgYW4gZW5kIG9mIHRyYW5zbWlzc2lvbgogKiBjaGFyYWN0ZXIgaXMgc2VudCAoXkQpLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLgogKgogKiBAcGFyYW0gc3RyaW5nICAkZm9ybWF0ICBBIHZhbGlkIGlucHV0IGZvcm1hdC4gU2VlIGBmc2NhbmZgIGZvciBkb2N1bWVudGF0aW9uLgogKiAgICAgICAgICAgICAgICAgICAgICAgICBJZiBub25lIGlzIGdpdmVuLCBhbGwgaW5wdXQgdXAgdG8gdGhlIGZpcnN0IG5ld2xpbmUKICogICAgICAgICAgICAgICAgICAgICAgICAgaXMgYWNjZXB0ZWQuCiAqIEByZXR1cm4gc3RyaW5nICBUaGUgaW5wdXQgd2l0aCB3aGl0ZXNwYWNlIHRyaW1tZWQuCiAqIEB0aHJvd3MgXEV4Y2VwdGlvbiAgVGhyb3duIGlmIGN0cmwtRCAoRU9UKSBpcyBzZW50IGFzIGlucHV0LgogKi8KZnVuY3Rpb24gaW5wdXQoICRmb3JtYXQgPSBudWxsICkgewoJcmV0dXJuIFN0cmVhbXM6OmlucHV0KCAkZm9ybWF0ICk7Cn0KCi8qKgogKiBEaXNwbGF5cyBhbiBpbnB1dCBwcm9tcHQuIElmIG5vIGRlZmF1bHQgdmFsdWUgaXMgcHJvdmlkZWQgdGhlIHByb21wdCB3aWxsCiAqIGNvbnRpbnVlIGRpc3BsYXlpbmcgdW50aWwgaW5wdXQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgICRxdWVzdGlvbiBUaGUgcXVlc3Rpb24gdG8gYXNrIHRoZSB1c2VyLgogKiBAcGFyYW0gc3RyaW5nICAkZGVmYXVsdCAgQSBkZWZhdWx0IHZhbHVlIGlmIHRoZSB1c2VyIHByb3ZpZGVzIG5vIGlucHV0LgogKiBAcGFyYW0gc3RyaW5nICAkbWFya2VyICAgQSBzdHJpbmcgdG8gYXBwZW5kIHRvIHRoZSBxdWVzdGlvbiBhbmQgZGVmYXVsdCB2YWx1ZSBvbiBkaXNwbGF5LgogKiBAcGFyYW0gYm9vbGVhbiAkaGlkZSAgICAgSWYgdGhlIHVzZXIgaW5wdXQgc2hvdWxkIGJlIGhpZGRlbgogKiBAcmV0dXJuIHN0cmluZyAgVGhlIHVzZXJzIGlucHV0LgogKiBAc2VlIGNsaVxpbnB1dCgpCiAqLwpmdW5jdGlvbiBwcm9tcHQoICRxdWVzdGlvbiwgJGRlZmF1bHQgPSBmYWxzZSwgJG1hcmtlciA9ICc6ICcsICRoaWRlID0gZmFsc2UgKSB7CglyZXR1cm4gU3RyZWFtczo6cHJvbXB0KCAkcXVlc3Rpb24sICRkZWZhdWx0LCAkbWFya2VyLCAkaGlkZSApOwp9CgovKioKICogUHJlc2VudHMgYSB1c2VyIHdpdGggYSBtdWx0aXBsZSBjaG9pY2UgcXVlc3Rpb24sIHVzZWZ1bCBmb3IgJ3llcy9ubycgdHlwZQogKiBxdWVzdGlvbnMgKHdoaWNoIHRoaXMgZnVuY3Rpb24gZGVmYXVsdHMgdG9vKS4KICoKICogQHBhcmFtIHN0cmluZyAgICAgICRxdWVzdGlvbiAgIFRoZSBxdWVzdGlvbiB0byBhc2sgdGhlIHVzZXIuCiAqIEBwYXJhbSBzdHJpbmcgICAgICAkY2hvaWNlCiAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZGVmYXVsdCAgICBUaGUgZGVmYXVsdCBjaG9pY2UuIE5VTEwgaWYgYSBkZWZhdWx0IGlzIG5vdCBhbGxvd2VkLgogKiBAaW50ZXJuYWwgcGFyYW0gc3RyaW5nICR2YWxpZCAgQSBzdHJpbmcgb2YgY2hhcmFjdGVycyBhbGxvd2VkIGFzIGEgcmVzcG9uc2UuIENhc2UKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGlnbm9yZWQuCiAqIEByZXR1cm4gc3RyaW5nICBUaGUgdXNlcnMgY2hvaWNlLgogKiBAc2VlICAgICAgY2xpXHByb21wdCgpCiAqLwpmdW5jdGlvbiBjaG9vc2UoICRxdWVzdGlvbiwgJGNob2ljZSA9ICd5bicsICRkZWZhdWx0ID0gJ24nICkgewoJcmV0dXJuIFN0cmVhbXM6OmNob29zZSggJHF1ZXN0aW9uLCAkY2hvaWNlLCAkZGVmYXVsdCApOwp9CgovKioKICogRG9lcyB0aGUgc2FtZSBhcyB7QHNlZSBjaG9vc2UoKX0sIGJ1dCBhbHdheXMgYXNrcyB5ZXMvbm8gYW5kIHJldHVybnMgYSBib29sZWFuCiAqCiAqIEBwYXJhbSBzdHJpbmcgICAgJHF1ZXN0aW9uICBUaGUgcXVlc3Rpb24gdG8gYXNrIHRoZSB1c2VyLgogKiBAcGFyYW0gYm9vbHxudWxsICRkZWZhdWx0ICAgVGhlIGRlZmF1bHQgY2hvaWNlLCBpbiBhIGJvb2xlYW4gZm9ybWF0LgogKiBAcmV0dXJuIGJvb2wKICovCmZ1bmN0aW9uIGNvbmZpcm0oICRxdWVzdGlvbiwgJGRlZmF1bHQgPSBmYWxzZSApIHsKCWlmICggaXNfYm9vbCggJGRlZmF1bHQgKSApIHsKCQkkZGVmYXVsdCA9ICRkZWZhdWx0PyAneScgOiAnbic7Cgl9CgkkcmVzdWx0ICA9IGNob29zZSggJHF1ZXN0aW9uLCAneW4nLCAkZGVmYXVsdCApOwoJcmV0dXJuICRyZXN1bHQgPT0gJ3knOwp9CgovKioKICogRGlzcGxheXMgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhcyBhIG1lbnUgd2hlcmUgYSB1c2VyIGNhbiBlbnRlciBhIG51bWJlciB0bwogKiBjaG9vc2UgYW4gb3B0aW9uLiBUaGUgYXJyYXkgbXVzdCBiZSBhIHNpbmdsZSBkaW1lbnNpb24gd2l0aCBlaXRoZXIgc3RyaW5ncwogKiBvciBvYmplY3RzIHdpdGggYSBgX190b1N0cmluZygpYCBtZXRob2QuCiAqCiAqIEBwYXJhbSBhcnJheSAgJGl0ZW1zICAgVGhlIGxpc3Qgb2YgaXRlbXMgdGhlIHVzZXIgY2FuIGNob29zZSBmcm9tLgogKiBAcGFyYW0gc3RyaW5nICRkZWZhdWx0IFRoZSBpbmRleCBvZiB0aGUgZGVmYXVsdCBpdGVtLgogKiBAcGFyYW0gc3RyaW5nICR0aXRsZSAgIFRoZSBtZXNzYWdlIGRpc3BsYXllZCB0byB0aGUgdXNlciB3aGVuIHByb21wdGVkLgogKiBAcmV0dXJuIHN0cmluZyAgVGhlIGluZGV4IG9mIHRoZSBjaG9zZW4gaXRlbS4KICogQHNlZSBjbGlcbGluZSgpCiAqIEBzZWUgY2xpXGlucHV0KCkKICogQHNlZSBjbGlcZXJyKCkKICovCmZ1bmN0aW9uIG1lbnUoICRpdGVtcywgJGRlZmF1bHQgPSBudWxsLCAkdGl0bGUgPSAnQ2hvb3NlIGFuIGl0ZW0nICkgewoJcmV0dXJuIFN0cmVhbXM6Om1lbnUoICRpdGVtcywgJGRlZmF1bHQsICR0aXRsZSApOwp9CgovKioKICogQXR0ZW1wdHMgYW4gZW5jb2Rpbmctc2FmZSB3YXkgb2YgZ2V0dGluZyBzdHJpbmcgbGVuZ3RoLiBJZiBpbnRsIGV4dGVuc2lvbiBvciBQQ1JFIHdpdGggJ1xYJyBvciBtYl9zdHJpbmcgZXh0ZW5zaW9uIGFyZW4ndAogKiBhdmFpbGFibGUsIGZhbGxzIGJhY2sgdG8gYmFzaWMgc3RybGVuLgogKgogKiBAcGFyYW0gIHN0cmluZyAgICAgICRzdHIgICAgICBUaGUgc3RyaW5nIHRvIGNoZWNrLgogKiBAcGFyYW0gIHN0cmluZ3xib29sICRlbmNvZGluZyBPcHRpb25hbC4gVGhlIGVuY29kaW5nIG9mIHRoZSBzdHJpbmcuIERlZmF1bHQgZmFsc2UuCiAqIEByZXR1cm4gaW50ICBOdW1lcmljIHZhbHVlIHRoYXQgcmVwcmVzZW50cyB0aGUgc3RyaW5nJ3MgbGVuZ3RoCiAqLwpmdW5jdGlvbiBzYWZlX3N0cmxlbiggJHN0ciwgJGVuY29kaW5nID0gZmFsc2UgKSB7CgkvLyBBbGxvdyBmb3Igc2VsZWN0aXZlIHRlc3RpbmdzIC0gIjEiIGJpdCBzZXQgdGVzdHMgZ3JhcGhlbWVfc3RybGVuKCksICIyIiBwcmVnX21hdGNoX2FsbCggJy9cWC91JyApLCAiNCIgbWJfc3RybGVuKCksICJvdGhlciIgc3RybGVuKCkuCgkkdGVzdF9zYWZlX3N0cmxlbiA9IGdldGVudiggJ1BIUF9DTElfVE9PTFNfVEVTVF9TQUZFX1NUUkxFTicgKTsKCgkvLyBBc3N1bWUgVVRGLTggaWYgbm8gZW5jb2RpbmcgZ2l2ZW4gLSBgZ3JhcGhlbWVfc3RybGVuKClgIHdpbGwgcmV0dXJuIG51bGwgaWYgZ2l2ZW4gbm9uLVVURi04IHN0cmluZy4KCWlmICggKCAhICRlbmNvZGluZyB8fCAnVVRGLTgnID09PSAkZW5jb2RpbmcgKSAmJiBjYW5fdXNlX2ljdSgpICYmIG51bGwgIT09ICggJGxlbmd0aCA9IGdyYXBoZW1lX3N0cmxlbiggJHN0ciApICkgKSB7CgkJaWYgKCAhICR0ZXN0X3NhZmVfc3RybGVuIHx8ICggJHRlc3Rfc2FmZV9zdHJsZW4gJiAxICkgKSB7CgkJCXJldHVybiAkbGVuZ3RoOwoJCX0KCX0KCS8vIEFzc3VtZSBVVEYtOCBpZiBubyBlbmNvZGluZyBnaXZlbiAtIGBwcmVnX21hdGNoX2FsbCgpYCB3aWxsIHJldHVybiBmYWxzZSBpZiBnaXZlbiBub24tVVRGLTggc3RyaW5nLgoJaWYgKCAoICEgJGVuY29kaW5nIHx8ICdVVEYtOCcgPT09ICRlbmNvZGluZyApICYmIGNhbl91c2VfcGNyZV94KCkgJiYgZmFsc2UgIT09ICggJGxlbmd0aCA9IHByZWdfbWF0Y2hfYWxsKCAnL1xYL3UnLCAkc3RyLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApICkgKSB7CgkJaWYgKCAhICR0ZXN0X3NhZmVfc3RybGVuIHx8ICggJHRlc3Rfc2FmZV9zdHJsZW4gJiAyICkgKSB7CgkJCXJldHVybiAkbGVuZ3RoOwoJCX0KCX0KCS8vIExlZ2FjeSBlbmNvZGluZ3MgYW5kIG9sZCBQSFBzIHdpbGwgcmVhY2ggaGVyZS4KCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnbWJfc3RybGVuJyApICYmICggJGVuY29kaW5nIHx8IGZ1bmN0aW9uX2V4aXN0cyggJ21iX2RldGVjdF9lbmNvZGluZycgKSApICkgewoJCWlmICggISAkZW5jb2RpbmcgKSB7CgkJCSRlbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZyggJHN0ciwgbnVsbCwgdHJ1ZSAvKnN0cmljdCovICk7CgkJfQoJCSRsZW5ndGggPSAkZW5jb2RpbmcgPyBtYl9zdHJsZW4oICRzdHIsICRlbmNvZGluZyApIDogbWJfc3RybGVuKCAkc3RyICk7IC8vIG1ic3RyaW5nIGZ1bmNzIGNhbiBmYWlsIGlmIGdpdmVuIGAkZW5jb2RpbmdgIGFyZyB0aGF0IGV2YWxzIHRvIGZhbHNlLgoJCWlmICggJ1VURi04JyA9PT0gJGVuY29kaW5nICkgewoJCQkvLyBTdWJ0cmFjdCBjb21iaW5pbmcgY2hhcmFjdGVycy4KCQkJJGxlbmd0aCAtPSBwcmVnX21hdGNoX2FsbCggZ2V0X3VuaWNvZGVfcmVnZXhzKCAnbScgKSwgJHN0ciwgJGR1bW15IC8qbmVlZGVkIGZvciBQSFAgNS4zKi8gKTsKCQl9CgkJaWYgKCAhICR0ZXN0X3NhZmVfc3RybGVuIHx8ICggJHRlc3Rfc2FmZV9zdHJsZW4gJiA0ICkgKSB7CgkJCXJldHVybiAkbGVuZ3RoOwoJCX0KCX0KCXJldHVybiBzdHJsZW4oICRzdHIgKTsKfQoKLyoqCiAqIEF0dGVtcHRzIGFuIGVuY29kaW5nLXNhZmUgd2F5IG9mIGdldHRpbmcgYSBzdWJzdHJpbmcuIElmIGludGwgZXh0ZW5zaW9uIG9yIFBDUkUgd2l0aCAnXFgnIG9yIG1iX3N0cmluZyBleHRlbnNpb24gYXJlbid0CiAqIGF2YWlsYWJsZSwgZmFsbHMgYmFjayB0byBzdWJzdHIoKS4KICogCQkKICogQHBhcmFtICBzdHJpbmcgICAgICAgICRzdHIgICAgICBUaGUgaW5wdXQgc3RyaW5nLgogKiBAcGFyYW0gIGludCAgICAgICAgICAgJHN0YXJ0ICAgIFRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgc3Vic3RyaW5nLgogKiBAcGFyYW0gIGludHxib29sfG51bGwgJGxlbmd0aCAgIE9wdGlvbmFsLCB1bmxlc3MgJGlzX3dpZHRoIGlzIHNldC4gTWF4aW11bSBsZW5ndGggb2YgdGhlIHN1YnN0cmluZy4gRGVmYXVsdCBmYWxzZS4gTmVnYXRpdmUgbm90IHN1cHBvcnRlZC4KICogQHBhcmFtICBpbnR8Ym9vbCAgICAgICRpc193aWR0aCBPcHRpb25hbC4gSWYgc2V0IGFuZCBlbmNvZGluZyBpcyBVVEYtOCwgJGxlbmd0aCAod2hpY2ggbXVzdCBiZSBzcGVjaWZpZWQpIGlzIGludGVycHJldGVkIGFzIHNwYWNpbmcgd2lkdGguIERlZmF1bHQgZmFsc2UuCiAqIEBwYXJhbSAgc3RyaW5nfGJvb2wgICAkZW5jb2RpbmcgT3B0aW9uYWwuIFRoZSBlbmNvZGluZyBvZiB0aGUgc3RyaW5nLiBEZWZhdWx0IGZhbHNlLgogKiBAcmV0dXJuIGJvb2x8c3RyaW5nICBGYWxzZSBpZiBnaXZlbiB1bnN1cHBvcnRlZCBhcmdzLCBvdGhlcndpc2Ugc3Vic3RyaW5nIG9mIHN0cmluZyBzcGVjaWZpZWQgYnkgc3RhcnQgYW5kIGxlbmd0aCBwYXJhbWV0ZXJzCiAqLwpmdW5jdGlvbiBzYWZlX3N1YnN0ciggJHN0ciwgJHN0YXJ0LCAkbGVuZ3RoID0gZmFsc2UsICRpc193aWR0aCA9IGZhbHNlLCAkZW5jb2RpbmcgPSBmYWxzZSApIHsKCS8vIE5lZ2F0aXZlICRsZW5ndGggb3IgJGlzX3dpZHRoIGFuZCAkbGVuZ3RoIG5vdCBzcGVjaWZpZWQgbm90IHN1cHBvcnRlZC4KCWlmICggJGxlbmd0aCA8IDAgfHwgKCAkaXNfd2lkdGggJiYgKCBudWxsID09PSAkbGVuZ3RoIHx8IGZhbHNlID09PSAkbGVuZ3RoICkgKSApIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgkvLyBOZWVkIHRoaXMgZm9yIG5vcm1hbGl6YXRpb24gYmVsb3cgYW5kIG90aGVyIHVzZXMuCgkkc2FmZV9zdHJsZW4gPSBzYWZlX3N0cmxlbiggJHN0ciwgJGVuY29kaW5nICk7CgoJLy8gTm9ybWFsaXplIGAkbGVuZ3RoYCB3aGVuIG5vdCBzcGVjaWZpZWQgLSBQSFAgNS4zIHN1YnN0ciB0YWtlcyBmYWxzZSBhcyBmdWxsIGxlbmd0aCwgUEhQID4gNS4zIHRha2VzIG51bGwuCglpZiAoIG51bGwgPT09ICRsZW5ndGggfHwgZmFsc2UgPT09ICRsZW5ndGggKSB7CgkJJGxlbmd0aCA9ICRzYWZlX3N0cmxlbjsKCX0KCS8vIE5vcm1hbGl6ZSBgJHN0YXJ0YCAtIHZhcmlvdXMgbWV0aG9kcyB0cmVhdCB0aGlzIGRpZmZlcmVudGx5LgoJaWYgKCAkc3RhcnQgPiAkc2FmZV9zdHJsZW4gKSB7CgkJcmV0dXJuICcnOwoJfQoJaWYgKCAkc3RhcnQgPCAwICYmIC0kc3RhcnQgPiAkc2FmZV9zdHJsZW4gKSB7CgkJJHN0YXJ0ID0gMDsKCX0KCgkvLyBBbGxvdyBmb3Igc2VsZWN0aXZlIHRlc3RpbmdzIC0gIjEiIGJpdCBzZXQgdGVzdHMgZ3JhcGhlbWVfc3Vic3RyKCksICIyIiBwcmVnX3NwbGl0KCAnL1xYLycgKSwgIjQiIG1iX3N1YnN0cigpLCAiOCIgc3Vic3RyKCkuCgkkdGVzdF9zYWZlX3N1YnN0ciA9IGdldGVudiggJ1BIUF9DTElfVE9PTFNfVEVTVF9TQUZFX1NVQlNUUicgKTsKCgkvLyBBc3N1bWUgVVRGLTggaWYgbm8gZW5jb2RpbmcgZ2l2ZW4gLSBgZ3JhcGhlbWVfc3Vic3RyKClgIHdpbGwgcmV0dXJuIGZhbHNlIChub3QgbnVsbCBsaWtlIGBncmFwaGVtZV9zdHJsZW4oKWApIGlmIGdpdmVuIG5vbi1VVEYtOCBzdHJpbmcuCglpZiAoICggISAkZW5jb2RpbmcgfHwgJ1VURi04JyA9PT0gJGVuY29kaW5nICkgJiYgY2FuX3VzZV9pY3UoKSAmJiBmYWxzZSAhPT0gKCAkdHJ5ID0gZ3JhcGhlbWVfc3Vic3RyKCAkc3RyLCAkc3RhcnQsICRsZW5ndGggKSApICkgewoJCWlmICggISAkdGVzdF9zYWZlX3N1YnN0ciB8fCAoICR0ZXN0X3NhZmVfc3Vic3RyICYgMSApICkgewoJCQlyZXR1cm4gJGlzX3dpZHRoID8gX3NhZmVfc3Vic3RyX2VhdyggJHRyeSwgJGxlbmd0aCApIDogJHRyeTsKCQl9Cgl9CgkvLyBBc3N1bWUgVVRGLTggaWYgbm8gZW5jb2RpbmcgZ2l2ZW4gLSBgcHJlZ19zcGxpdCgpYCByZXR1cm5zIGEgb25lIGVsZW1lbnQgYXJyYXkgaWYgZ2l2ZW4gbm9uLVVURi04IHN0cmluZyAoUEhQIGJ1Zykgc28gbmVlZCB0byBjaGVjayBgcHJlZ19sYXN0X2Vycm9yKClgLgoJaWYgKCAoICEgJGVuY29kaW5nIHx8ICdVVEYtOCcgPT09ICRlbmNvZGluZyApICYmIGNhbl91c2VfcGNyZV94KCkgKSB7CgkJaWYgKCBmYWxzZSAhPT0gKCAkdHJ5ID0gcHJlZ19zcGxpdCggJy8oXFgpL3UnLCAkc3RyLCAkc2FmZV9zdHJsZW4gKyAxLCBQUkVHX1NQTElUX0RFTElNX0NBUFRVUkUgfCBQUkVHX1NQTElUX05PX0VNUFRZICkgKSAmJiAhIHByZWdfbGFzdF9lcnJvcigpICkgewoJCQkkdHJ5ID0gaW1wbG9kZSggJycsIGFycmF5X3NsaWNlKCAkdHJ5LCAkc3RhcnQsICRsZW5ndGggKSApOwoJCQlpZiAoICEgJHRlc3Rfc2FmZV9zdWJzdHIgfHwgKCAkdGVzdF9zYWZlX3N1YnN0ciAmIDIgKSApIHsKCQkJCXJldHVybiAkaXNfd2lkdGggPyBfc2FmZV9zdWJzdHJfZWF3KCAkdHJ5LCAkbGVuZ3RoICkgOiAkdHJ5OwoJCQl9CgkJfQoJfQoJLy8gTGVnYWN5IGVuY29kaW5ncyBhbmQgb2xkIFBIUHMgd2lsbCByZWFjaCBoZXJlLgoJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdtYl9zdWJzdHInICkgJiYgKCAkZW5jb2RpbmcgfHwgZnVuY3Rpb25fZXhpc3RzKCAnbWJfZGV0ZWN0X2VuY29kaW5nJyApICkgKSB7CgkJaWYgKCAhICRlbmNvZGluZyApIHsKCQkJJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCAkc3RyLCBudWxsLCB0cnVlIC8qc3RyaWN0Ki8gKTsKCQl9CgkJLy8gQnVnOiBub3QgYWRqdXN0aW5nIGZvciBjb21iaW5pbmcgY2hhcnMuCgkJJHRyeSA9ICRlbmNvZGluZyA/IG1iX3N1YnN0ciggJHN0ciwgJHN0YXJ0LCAkbGVuZ3RoLCAkZW5jb2RpbmcgKSA6IG1iX3N1YnN0ciggJHN0ciwgJHN0YXJ0LCAkbGVuZ3RoICk7IC8vIG1ic3RyaW5nIGZ1bmNzIGNhbiBmYWlsIGlmIGdpdmVuIGAkZW5jb2RpbmdgIGFyZyB0aGF0IGV2YWxzIHRvIGZhbHNlLgoJCWlmICggJ1VURi04JyA9PT0gJGVuY29kaW5nICYmICRpc193aWR0aCApIHsKCQkJJHRyeSA9IF9zYWZlX3N1YnN0cl9lYXcoICR0cnksICRsZW5ndGggKTsKCQl9CgkJaWYgKCAhICR0ZXN0X3NhZmVfc3Vic3RyIHx8ICggJHRlc3Rfc2FmZV9zdWJzdHIgJiA0ICkgKSB7CgkJCXJldHVybiAkdHJ5OwoJCX0KCX0KCXJldHVybiBzdWJzdHIoICRzdHIsICRzdGFydCwgJGxlbmd0aCApOwp9CgovKioKICogSW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBieSBgc2FmZV9zdWJzdHIoKWAgdG8gYWRqdXN0IGZvciBFYXN0IEFzaWFuIGRvdWJsZS13aWR0aCBjaGFycy4KICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIF9zYWZlX3N1YnN0cl9lYXcoICRzdHIsICRsZW5ndGggKSB7CgkvLyBTZXQgdGhlIEVhc3QgQXNpYW4gV2lkdGggcmVnZXguCgkkZWF3X3JlZ2V4ID0gZ2V0X3VuaWNvZGVfcmVnZXhzKCAnZWF3JyApOwoKCS8vIElmIHRoZXJlJ3MgYW55IEVhc3QgQXNpYW4gZG91YmxlLXdpZHRoIGNoYXJzLi4uCglpZiAoIHByZWdfbWF0Y2goICRlYXdfcmVnZXgsICRzdHIgKSApIHsKCQkvLyBOb3RlIHRoYXQgaWYgdGhlIGxlbmd0aCBlbmRzIGluIHRoZSBtaWRkbGUgb2YgYSBkb3VibGUtd2lkdGggY2hhciwgdGhlIGNoYXIgaXMgZXhjbHVkZWQsIG5vdCBpbmNsdWRlZC4KCgkJLy8gU2VlIGlmIGl0J3MgYWxsIEVBVy4KCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ21iX3N1YnN0cicgKSAmJiBwcmVnX21hdGNoX2FsbCggJGVhd19yZWdleCwgJHN0ciwgJGR1bW15IC8qbmVlZGVkIGZvciBQSFAgNS4zKi8gKSA9PT0gJGxlbmd0aCApIHsKCQkJLy8gSnVzdCBoYWx2ZSB0aGUgbGVuZ3RoIHNvIChyb3VuZGVkIGRvd24gdG8gYSBtaW5pbXVtIG9mIDEpLgoJCQkkc3RyID0gbWJfc3Vic3RyKCAkc3RyLCAwLCBtYXgoIChpbnQpICggJGxlbmd0aCAvIDIgKSwgMSApLCAnVVRGLTgnICk7CgkJfSBlbHNlIHsKCQkJLy8gRXhwbG9kZSBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBVVEYtOCBjaGFycy4gQmFzZWQgb24gY29yZSBgX21iX3N1YnN0cigpYCBpbiAid3AtaW5jbHVkZXMvY29tcGF0LnBocCIuCgkJCSRjaGFycyA9IHByZWdfc3BsaXQoICcvKFtceDAwLVx4N2ZceGMyLVx4ZjRdW15ceDAwLVx4N2ZceGMyLVx4ZjRdKikvJywgJHN0ciwgJGxlbmd0aCArIDEsIFBSRUdfU1BMSVRfREVMSU1fQ0FQVFVSRSB8IFBSRUdfU1BMSVRfTk9fRU1QVFkgKTsKCQkJJGNudCA9IG1pbiggY291bnQoICRjaGFycyApLCAkbGVuZ3RoICk7CgkJCSR3aWR0aCA9ICRsZW5ndGg7CgoJCQlmb3IgKCAkbGVuZ3RoID0gMDsgJGxlbmd0aCA8ICRjbnQgJiYgJHdpZHRoID4gMDsgJGxlbmd0aCsrICkgewoJCQkJJHdpZHRoIC09IHByZWdfbWF0Y2goICRlYXdfcmVnZXgsICRjaGFyc1sgJGxlbmd0aCBdICkgPyAyIDogMTsKCQkJfQoJCQkvLyBSb3VuZCBkb3duIHRvIGEgbWluaW11bSBvZiAxLgoJCQlpZiAoICR3aWR0aCA8IDAgJiYgJGxlbmd0aCA+IDEgKSB7CgkJCQkkbGVuZ3RoLS07CgkJCX0KCQkJcmV0dXJuIGpvaW4oICcnLCBhcnJheV9zbGljZSggJGNoYXJzLCAwLCAkbGVuZ3RoICkgKTsKCQl9Cgl9CglyZXR1cm4gJHN0cjsKfQoKLyoqCiAqIEFuIGVuY29kaW5nLXNhZmUgd2F5IG9mIHBhZGRpbmcgc3RyaW5nIGxlbmd0aCBmb3IgZGlzcGxheQogKgogKiBAcGFyYW0gIHN0cmluZyAgICAgICRzdHJpbmcgICBUaGUgc3RyaW5nIHRvIHBhZC4KICogQHBhcmFtICBpbnQgICAgICAgICAkbGVuZ3RoICAgVGhlIGxlbmd0aCB0byBwYWQgaXQgdG8uCiAqIEBwYXJhbSAgc3RyaW5nfGJvb2wgJGVuY29kaW5nIE9wdGlvbmFsLiBUaGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmluZy4gRGVmYXVsdCBmYWxzZS4KICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIHNhZmVfc3RyX3BhZCggJHN0cmluZywgJGxlbmd0aCwgJGVuY29kaW5nID0gZmFsc2UgKSB7CgkkcmVhbF9sZW5ndGggPSBzdHJ3aWR0aCggJHN0cmluZywgJGVuY29kaW5nICk7CgkkZGlmZiA9IHN0cmxlbiggJHN0cmluZyApIC0gJHJlYWxfbGVuZ3RoOwoJJGxlbmd0aCArPSAkZGlmZjsKCglyZXR1cm4gc3RyX3BhZCggJHN0cmluZywgJGxlbmd0aCApOwp9CgovKioKICogR2V0IHdpZHRoIG9mIHN0cmluZywgaWUgbGVuZ3RoIGluIGNoYXJhY3RlcnMsIHRha2luZyBpbnRvIGFjY291bnQgbXVsdGktYnl0ZSBhbmQgbWFyayBjaGFyYWN0ZXJzIGZvciBVVEYtOCwgYW5kIG11bHRpLWJ5dGUgZm9yIG5vbi1VVEYtOC4KICoKICogQHBhcmFtICBzdHJpbmcgICAgICAkc3RyaW5nICAgVGhlIHN0cmluZyB0byBjaGVjay4KICogQHBhcmFtICBzdHJpbmd8Ym9vbCAkZW5jb2RpbmcgT3B0aW9uYWwuIFRoZSBlbmNvZGluZyBvZiB0aGUgc3RyaW5nLiBEZWZhdWx0IGZhbHNlLgogKiBAcmV0dXJuIGludCAgVGhlIHN0cmluZydzIHdpZHRoLgogKi8KZnVuY3Rpb24gc3Ryd2lkdGgoICRzdHJpbmcsICRlbmNvZGluZyA9IGZhbHNlICkgewoJLy8gU2V0IHRoZSBFYXN0IEFzaWFuIFdpZHRoIGFuZCBNYXJrIHJlZ2V4cy4KCWxpc3QoICRlYXdfcmVnZXgsICRtX3JlZ2V4ICkgPSBnZXRfdW5pY29kZV9yZWdleHMoKTsKCgkvLyBBbGxvdyBmb3Igc2VsZWN0aXZlIHRlc3RpbmdzIC0gIjEiIGJpdCBzZXQgdGVzdHMgZ3JhcGhlbWVfc3RybGVuKCksICIyIiBwcmVnX21hdGNoX2FsbCggJy9cWC91JyApLCAiNCIgbWJfc3Ryd2lkdGgoKSwgIm90aGVyIiBzYWZlX3N0cmxlbigpLgoJJHRlc3Rfc3Ryd2lkdGggPSBnZXRlbnYoICdQSFBfQ0xJX1RPT0xTX1RFU1RfU1RSV0lEVEgnICk7CgoJLy8gQXNzdW1lIFVURi04IGlmIG5vIGVuY29kaW5nIGdpdmVuIC0gYGdyYXBoZW1lX3N0cmxlbigpYCB3aWxsIHJldHVybiBudWxsIGlmIGdpdmVuIG5vbi1VVEYtOCBzdHJpbmcuCglpZiAoICggISAkZW5jb2RpbmcgfHwgJ1VURi04JyA9PT0gJGVuY29kaW5nICkgJiYgY2FuX3VzZV9pY3UoKSAmJiBudWxsICE9PSAoICR3aWR0aCA9IGdyYXBoZW1lX3N0cmxlbiggJHN0cmluZyApICkgKSB7CgkJaWYgKCAhICR0ZXN0X3N0cndpZHRoIHx8ICggJHRlc3Rfc3Ryd2lkdGggJiAxICkgKSB7CgkJCXJldHVybiAkd2lkdGggKyBwcmVnX21hdGNoX2FsbCggJGVhd19yZWdleCwgJHN0cmluZywgJGR1bW15IC8qbmVlZGVkIGZvciBQSFAgNS4zKi8gKTsKCQl9Cgl9CgkvLyBBc3N1bWUgVVRGLTggaWYgbm8gZW5jb2RpbmcgZ2l2ZW4gLSBgcHJlZ19tYXRjaF9hbGwoKWAgd2lsbCByZXR1cm4gZmFsc2UgaWYgZ2l2ZW4gbm9uLVVURi04IHN0cmluZy4KCWlmICggKCAhICRlbmNvZGluZyB8fCAnVVRGLTgnID09PSAkZW5jb2RpbmcgKSAmJiBjYW5fdXNlX3BjcmVfeCgpICYmIGZhbHNlICE9PSAoICR3aWR0aCA9IHByZWdfbWF0Y2hfYWxsKCAnL1xYL3UnLCAkc3RyaW5nLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApICkgKSB7CgkJaWYgKCAhICR0ZXN0X3N0cndpZHRoIHx8ICggJHRlc3Rfc3Ryd2lkdGggJiAyICkgKSB7CgkJCXJldHVybiAkd2lkdGggKyBwcmVnX21hdGNoX2FsbCggJGVhd19yZWdleCwgJHN0cmluZywgJGR1bW15IC8qbmVlZGVkIGZvciBQSFAgNS4zKi8gKTsKCQl9Cgl9CgkvLyBMZWdhY3kgZW5jb2RpbmdzIGFuZCBvbGQgUEhQcyB3aWxsIHJlYWNoIGhlcmUuCglpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ21iX3N0cndpZHRoJyApICYmICggJGVuY29kaW5nIHx8IGZ1bmN0aW9uX2V4aXN0cyggJ21iX2RldGVjdF9lbmNvZGluZycgKSApICkgewoJCWlmICggISAkZW5jb2RpbmcgKSB7CgkJCSRlbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZyggJHN0cmluZywgbnVsbCwgdHJ1ZSAvKnN0cmljdCovICk7CgkJfQoJCSR3aWR0aCA9ICRlbmNvZGluZyA/IG1iX3N0cndpZHRoKCAkc3RyaW5nLCAkZW5jb2RpbmcgKSA6IG1iX3N0cndpZHRoKCAkc3RyaW5nICk7IC8vIG1ic3RyaW5nIGZ1bmNzIGNhbiBmYWlsIGlmIGdpdmVuIGAkZW5jb2RpbmdgIGFyZyB0aGF0IGV2YWxzIHRvIGZhbHNlLgoJCWlmICggJ1VURi04JyA9PT0gJGVuY29kaW5nICkgewoJCQkvLyBTdWJ0cmFjdCBjb21iaW5pbmcgY2hhcmFjdGVycy4KCQkJJHdpZHRoIC09IHByZWdfbWF0Y2hfYWxsKCAkbV9yZWdleCwgJHN0cmluZywgJGR1bW15IC8qbmVlZGVkIGZvciBQSFAgNS4zKi8gKTsKCQl9CgkJaWYgKCAhICR0ZXN0X3N0cndpZHRoIHx8ICggJHRlc3Rfc3Ryd2lkdGggJiA0ICkgKSB7CgkJCXJldHVybiAkd2lkdGg7CgkJfQoJfQoJcmV0dXJuIHNhZmVfc3RybGVuKCAkc3RyaW5nLCAkZW5jb2RpbmcgKTsKfQoKLyoqCiAqIFJldHVybnMgd2hldGhlciBJQ1UgaXMgbW9kZXJuIGVub3VnaCBub3QgdG8gZmxha2Ugb3V0LgogKgogKiBAcmV0dXJuIGJvb2wKICovCmZ1bmN0aW9uIGNhbl91c2VfaWN1KCkgewoJc3RhdGljICRjYW5fdXNlX2ljdSA9IG51bGw7CgoJaWYgKCBudWxsID09PSAkY2FuX3VzZV9pY3UgKSB7CgkJLy8gQ2hvb3NpbmcgSUNVIDU0LCBVbmljb2RlIDcuMC4KCQkkY2FuX3VzZV9pY3UgPSBkZWZpbmVkKCAnSU5UTF9JQ1VfVkVSU0lPTicgKSAmJiB2ZXJzaW9uX2NvbXBhcmUoIElOVExfSUNVX1ZFUlNJT04sICc1NC4xJywgJz49JyApICYmIGZ1bmN0aW9uX2V4aXN0cyggJ2dyYXBoZW1lX3N0cmxlbicgKSAmJiBmdW5jdGlvbl9leGlzdHMoICdncmFwaGVtZV9zdWJzdHInICk7Cgl9CgoJcmV0dXJuICRjYW5fdXNlX2ljdTsKfQoKLyoqCiAqIFJldHVybnMgd2hldGhlciBQQ1JFIFVuaWNvZGUgZXh0ZW5kZWQgZ3JhcGhlbWUgY2x1c3RlciAnXFgnIGlzIGF2YWlsYWJsZSBmb3IgdXNlLgogKgogKiBAcmV0dXJuIGJvb2wKICovCmZ1bmN0aW9uIGNhbl91c2VfcGNyZV94KCkgewoJc3RhdGljICRjYW5fdXNlX3BjcmVfeCA9IG51bGw7CgoJaWYgKCBudWxsID09PSAkY2FuX3VzZV9wY3JlX3ggKSB7CgkJLy8gJ1xYJyBpbnRyb2R1Y2VkIChhcyBVbmljZGUgZXh0ZW5kZWQgZ3JhcGhlbWUgY2x1c3RlcikgaW4gUENSRSA4LjMyIC0gc2VlIGh0dHBzOi8vdmNzLnBjcmUub3JnL3BjcmUvY29kZS90YWdzL3BjcmUtOC4zMi9DaGFuZ2VMb2c/dmlldz1tYXJrdXAgbGluZSA1My4KCQkvLyBPbGRlciB2ZXJzaW9ucyBvZiBQQ1JFIHdlcmUgYnVuZGxlZCB3aXRoIFBIUCA8PSA1LjMuMjMgJiA8PSA1LjQuMTMuCgkJJHBjcmVfdmVyc2lvbiA9IHN1YnN0ciggUENSRV9WRVJTSU9OLCAwLCBzdHJzcG4oIFBDUkVfVkVSU0lPTiwgJzAxMjM0NTY3ODkuJyApICk7IC8vIFJlbW92ZSBhbnkgdHJhaWxpbmcgZGF0ZSBzdHVmZi4KCQkkY2FuX3VzZV9wY3JlX3ggPSB2ZXJzaW9uX2NvbXBhcmUoICRwY3JlX3ZlcnNpb24sICc4LjMyJywgJz49JyApICYmIGZhbHNlICE9PSBAcHJlZ19tYXRjaCggJy9cWC91JywgJycgKTsKCX0KCglyZXR1cm4gJGNhbl91c2VfcGNyZV94Owp9CgovKioKICogR2V0IHRoZSByZWdleHMgZ2VuZXJhdGVkIGZyb20gVW5pY29kZSBkYXRhLgogKgogKiBAcGFyYW0gc3RyaW5nICRpZHggT3B0aW9uYWwuIFJldHVybiBhIHNwZWNpZmljIHJlZ2V4IG9ubHkuIERlZmF1bHQgbnVsbC4KICogQHJldHVybiBhcnJheXxzdHJpbmcgIFJldHVybnMga2V5ZWQgYXJyYXkgaWYgbm90IGdpdmVuICRpZHggb3IgJGlkeCBkb2Vzbid0IGV4aXN0LCBvdGhlcndpc2UgdGhlIHNwZWNpZmljIHJlZ2V4IHN0cmluZy4KICovCmZ1bmN0aW9uIGdldF91bmljb2RlX3JlZ2V4cyggJGlkeCA9IG51bGwgKSB7CglzdGF0aWMgJGVhd19yZWdleDsgLy8gRWFzdCBBc2lhbiBXaWR0aCByZWdleC4gQ2hhcmFjdGVycyB0aGF0IGNvdW50IGFzIDIgY2hhcmFjdGVycyBhcyB0aGV5J3JlICJ3aWRlIiBvciAiZnVsbHdpZHRoIi4gU2VlIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvcmVwb3J0cy90cjExL3RyMTEtMTkuaHRtbAoJc3RhdGljICRtX3JlZ2V4OyAvLyBNYXJrIGNoYXJhY3RlcnMgcmVnZXggKFVuaWNvZGUgcHJvcGVydHkgIk0iKSAtIG1hcmsgY29tYmluaW5nICJNYyIsIG1hcmsgZW5jbG9zaW5nICJNZSIgYW5kIG1hcmsgbm9uLXNwYWNpbmcgIk1uIiBjaGFycyB0aGF0IHNob3VsZCBiZSBpZ25vcmVkIGZvciBzcGFjaW5nIHB1cnBvc2VzLgoJaWYgKCBudWxsID09PSAkZWF3X3JlZ2V4ICkgewoJCS8vIExvYWQgYm90aCByZWdleHMgZ2VuZXJhdGVkIGZyb20gVW5pY29kZSBkYXRhLgoJCXJlcXVpcmUgX19ESVJfXyAuICcvdW5pY29kZS9yZWdleC5waHAnOwoJfQoKCWlmICggbnVsbCAhPT0gJGlkeCApIHsKCQlpZiAoICdlYXcnID09PSAkaWR4ICkgewoJCQlyZXR1cm4gJGVhd19yZWdleDsKCQl9CgkJaWYgKCAnbScgPT09ICRpZHggKSB7CgkJCXJldHVybiAkbV9yZWdleDsKCQl9Cgl9CgoJcmV0dXJuIGFycmF5KCAkZWF3X3JlZ2V4LCAkbV9yZWdleCwgKTsKfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXHRhYmxlOwoKLyoqCiAqIFRhYmxlIHJlbmRlcmVycyBhcmUgdXNlZCB0byBjaGFuZ2UgaG93IGEgdGFibGUgaXMgZGlzcGxheWVkLgogKi8KYWJzdHJhY3QgY2xhc3MgUmVuZGVyZXIgewoJcHJvdGVjdGVkICRfd2lkdGhzID0gYXJyYXkoKTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHdpZHRocyA9IGFycmF5KCkpIHsKCQkkdGhpcy0+c2V0V2lkdGhzKCR3aWR0aHMpOwoJfQoKCS8qKgoJICogU2V0IHRoZSB3aWR0aHMgb2YgZWFjaCBjb2x1bW4gaW4gdGhlIHRhYmxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHdpZHRocyAgICBUaGUgd2lkdGhzIG9mIHRoZSBjb2x1bW5zLgoJICogQHBhcmFtIGJvb2wgICAkZmFsbGJhY2sgIFdoZXRoZXIgdG8gdXNlIHRoZXNlIHZhbHVlcyBhcyBmYWxsYmFjayBvbmx5LgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0V2lkdGhzKGFycmF5ICR3aWR0aHMsICRmYWxsYmFjayA9IGZhbHNlKSB7CgkJaWYgKCRmYWxsYmFjaykgewoJCQlmb3JlYWNoICggJHRoaXMtPl93aWR0aHMgYXMgJGluZGV4ID0+ICR2YWx1ZSApIHsKCQkJICAgICR3aWR0aHNbJGluZGV4XSA9ICR2YWx1ZTsKCQkJfQoJCX0KCQkkdGhpcy0+X3dpZHRocyA9ICR3aWR0aHM7Cgl9CgoJLyoqCgkgKiBSZW5kZXIgYSBib3JkZXIgZm9yIHRoZSB0b3AgYW5kIGJvdHRvbSBhbmQgc2VwYXJhdGluZyB0aGUgaGVhZGVycyBmcm9tIHRoZQoJICogdGFibGUgcm93cy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIHRhYmxlIGJvcmRlci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGJvcmRlcigpIHsKCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFJlbmRlcnMgYSByb3cgZm9yIG91dHB1dC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRyb3cgIFRoZSB0YWJsZSByb3cuCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIGZvcm1hdHRlZCB0YWJsZSByb3cuCgkgKi8KCWFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiByb3coYXJyYXkgJHJvdyk7Cn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaVx0YWJsZTsKCi8qKgogKiBUaGUgdGFidWxhciByZW5kZXJlciBpcyB1c2VkIGZvciBkaXNwbGF5aW5nIGRhdGEgaW4gYSB0YWJ1bGFyIGZvcm1hdC4KICovCmNsYXNzIFRhYnVsYXIgZXh0ZW5kcyBSZW5kZXJlciB7CgkvKioKCSAqIFJlbmRlcnMgYSByb3cgZm9yIG91dHB1dC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRyb3cgIFRoZSB0YWJsZSByb3cuCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIGZvcm1hdHRlZCB0YWJsZSByb3cuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByb3coYXJyYXkgJHJvdykgewoJCXJldHVybiBpbXBsb2RlKCJcdCIsIGFycmF5X3ZhbHVlcygkcm93KSk7Cgl9Cn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaVx0YWJsZTsKCnVzZSBjbGlcQ29sb3JzOwp1c2UgY2xpXFNoZWxsOwoKLyoqCiAqIFRoZSBBU0NJSSByZW5kZXJlciByZW5kZXJzIHRhYmxlcyB3aXRoIEFTQ0lJIGJvcmRlcnMuCiAqLwpjbGFzcyBBc2NpaSBleHRlbmRzIFJlbmRlcmVyIHsKCXByb3RlY3RlZCAkX2NoYXJhY3RlcnMgPSBhcnJheSgKCQknY29ybmVyJyAgPT4gJysnLAoJCSdsaW5lJyAgICA9PiAnLScsCgkJJ2JvcmRlcicgID0+ICd8JywKCQkncGFkZGluZycgPT4gJyAnLAoJKTsKCXByb3RlY3RlZCAkX2JvcmRlciA9IG51bGw7Cglwcm90ZWN0ZWQgJF9jb25zdHJhaW50V2lkdGggPSBudWxsOwoJcHJvdGVjdGVkICRfcHJlX2NvbG9yaXplZCA9IGZhbHNlOwoKCS8qKgoJICogU2V0IHRoZSB3aWR0aHMgb2YgZWFjaCBjb2x1bW4gaW4gdGhlIHRhYmxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHdpZHRocyAgICBUaGUgd2lkdGhzIG9mIHRoZSBjb2x1bW5zLgoJICogQHBhcmFtIGJvb2wgICAkZmFsbGJhY2sgIFdoZXRoZXIgdG8gdXNlIHRoZXNlIHZhbHVlcyBhcyBmYWxsYmFjayBvbmx5LgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0V2lkdGhzKGFycmF5ICR3aWR0aHMsICRmYWxsYmFjayA9IGZhbHNlKSB7CgkJaWYgKCRmYWxsYmFjaykgewoJCQlmb3JlYWNoICggJHRoaXMtPl93aWR0aHMgYXMgJGluZGV4ID0+ICR2YWx1ZSApIHsKCQkJICAgICR3aWR0aHNbJGluZGV4XSA9ICR2YWx1ZTsKCQkJfQoJCX0KCQkkdGhpcy0+X3dpZHRocyA9ICR3aWR0aHM7CgoJCWlmICggaXNfbnVsbCggJHRoaXMtPl9jb25zdHJhaW50V2lkdGggKSApIHsKCQkJJHRoaXMtPl9jb25zdHJhaW50V2lkdGggPSAoaW50KSBTaGVsbDo6Y29sdW1ucygpOwoJCX0KCQkkY29sX2NvdW50ID0gY291bnQoICR3aWR0aHMgKTsKCQkkY29sX2JvcmRlcnNfY291bnQgPSAkY29sX2NvdW50ID8gKCAoICRjb2xfY291bnQgLSAxICkgKiBzdHJsZW4oICR0aGlzLT5fY2hhcmFjdGVyc1snYm9yZGVyJ10gKSApIDogMDsKCQkkdGFibGVfYm9yZGVyc19jb3VudCA9IHN0cmxlbiggJHRoaXMtPl9jaGFyYWN0ZXJzWydib3JkZXInXSApICogMjsKCQkkY29sX3BhZGRpbmdfY291bnQgPSAkY29sX2NvdW50ICogc3RybGVuKCAkdGhpcy0+X2NoYXJhY3RlcnNbJ3BhZGRpbmcnXSApICogMjsKCQkkbWF4X3dpZHRoID0gJHRoaXMtPl9jb25zdHJhaW50V2lkdGggLSAkY29sX2JvcmRlcnNfY291bnQgLSAkdGFibGVfYm9yZGVyc19jb3VudCAtICRjb2xfcGFkZGluZ19jb3VudDsKCgkJaWYgKCAkd2lkdGhzICYmICRtYXhfd2lkdGggJiYgYXJyYXlfc3VtKCAkd2lkdGhzICkgPiAkbWF4X3dpZHRoICkgewoKCQkJJGF2ZyA9IGZsb29yKCAkbWF4X3dpZHRoIC8gY291bnQoICR3aWR0aHMgKSApOwoJCQkkcmVzaXplX3dpZHRocyA9IGFycmF5KCk7CgkJCSRleHRyYV93aWR0aCA9IDA7CgkJCWZvcmVhY2goICR3aWR0aHMgYXMgJHdpZHRoICkgewoJCQkJaWYgKCAkd2lkdGggPiAkYXZnICkgewoJCQkJCSRyZXNpemVfd2lkdGhzW10gPSAkd2lkdGg7CgkJCQl9IGVsc2UgewoJCQkJCSRleHRyYV93aWR0aCA9ICRleHRyYV93aWR0aCArICggJGF2ZyAtICR3aWR0aCApOwoJCQkJfQoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRyZXNpemVfd2lkdGhzICkgJiYgJGV4dHJhX3dpZHRoICkgewoJCQkJJGF2Z19leHRyYV93aWR0aCA9IGZsb29yKCAkZXh0cmFfd2lkdGggLyBjb3VudCggJHJlc2l6ZV93aWR0aHMgKSApOwoJCQkJZm9yZWFjaCggJHdpZHRocyBhcyAmJHdpZHRoICkgewoJCQkJCWlmICggaW5fYXJyYXkoICR3aWR0aCwgJHJlc2l6ZV93aWR0aHMgKSApIHsKCQkJCQkJJHdpZHRoID0gJGF2ZyArICRhdmdfZXh0cmFfd2lkdGg7CgkJCQkJCWFycmF5X3NoaWZ0KCAkcmVzaXplX3dpZHRocyApOwoJCQkJCQkvLyBMYXN0IGl0ZW0gZ2V0cyB0aGUgY2FrZQoJCQkJCQlpZiAoIGVtcHR5KCAkcmVzaXplX3dpZHRocyApICkgewoJCQkJCQkJJHdpZHRoID0gMDsgLy8gWmVybyBpdCBzbyBub3QgaW4gc3VtLgoJCQkJCQkJJHdpZHRoID0gJG1heF93aWR0aCAtIGFycmF5X3N1bSggJHdpZHRocyApOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgoJCX0KCgkJJHRoaXMtPl93aWR0aHMgPSAkd2lkdGhzOwoJfQoKCS8qKgoJICogU2V0IHRoZSBjb25zdHJhaW50IHdpZHRoIGZvciB0aGUgdGFibGUKCSAqCgkgKiBAcGFyYW0gaW50ICRjb25zdHJhaW50V2lkdGgKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldENvbnN0cmFpbnRXaWR0aCggJGNvbnN0cmFpbnRXaWR0aCApIHsKCQkkdGhpcy0+X2NvbnN0cmFpbnRXaWR0aCA9ICRjb25zdHJhaW50V2lkdGg7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGNoYXJhY3RlcnMgdXNlZCBmb3IgcmVuZGVyaW5nIHRoZSBBc2NpaSB0YWJsZS4KCSAqCgkgKiBUaGUga2V5cyBgY29ybmVyYCwgYGxpbmVgIGFuZCBgYm9yZGVyYCBhcmUgdXNlZCBpbiByZW5kZXJpbmcuCgkgKgoJICogQHBhcmFtICRjaGFyYWN0ZXJzICBhcnJheSAgQ2hhcmFjdGVycyB1c2VkIGluIHJlbmRlcmluZy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldENoYXJhY3RlcnMoYXJyYXkgJGNoYXJhY3RlcnMpIHsKCQkkdGhpcy0+X2NoYXJhY3RlcnMgPSBhcnJheV9tZXJnZSgkdGhpcy0+X2NoYXJhY3RlcnMsICRjaGFyYWN0ZXJzKTsKCX0KCgkvKioKCSAqIFJlbmRlciBhIGJvcmRlciBmb3IgdGhlIHRvcCBhbmQgYm90dG9tIGFuZCBzZXBhcmF0aW5nIHRoZSBoZWFkZXJzIGZyb20gdGhlCgkgKiB0YWJsZSByb3dzLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgdGFibGUgYm9yZGVyLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYm9yZGVyKCkgewoJCWlmICghaXNzZXQoJHRoaXMtPl9ib3JkZXIpKSB7CgkJCSR0aGlzLT5fYm9yZGVyID0gJHRoaXMtPl9jaGFyYWN0ZXJzWydjb3JuZXInXTsKCQkJZm9yZWFjaCAoJHRoaXMtPl93aWR0aHMgYXMgJHdpZHRoKSB7CgkJCQkkdGhpcy0+X2JvcmRlciAuPSBzdHJfcmVwZWF0KCR0aGlzLT5fY2hhcmFjdGVyc1snbGluZSddLCAkd2lkdGggKyAyKTsKCQkJCSR0aGlzLT5fYm9yZGVyIC49ICR0aGlzLT5fY2hhcmFjdGVyc1snY29ybmVyJ107CgkJCX0KCQl9CgoJCXJldHVybiAkdGhpcy0+X2JvcmRlcjsKCX0KCgkvKioKCSAqIFJlbmRlcnMgYSByb3cgZm9yIG91dHB1dC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRyb3cgIFRoZSB0YWJsZSByb3cuCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIGZvcm1hdHRlZCB0YWJsZSByb3cuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByb3coIGFycmF5ICRyb3cgKSB7CgoJCSRleHRyYV9yb3dfY291bnQgPSAwOwoKCQlpZiAoIGNvdW50KCAkcm93ICkgPiAwICkgewoJCQkkZXh0cmFfcm93cyA9IGFycmF5X2ZpbGwoIDAsIGNvdW50KCAkcm93ICksIGFycmF5KCkgKTsKCgkJCWZvcmVhY2goICRyb3cgYXMgJGNvbCA9PiAkdmFsdWUgKSB7CgoJCQkJJHZhbHVlID0gc3RyX3JlcGxhY2UoIGFycmF5KCAiXHJcbiIsICJcbiIgKSwgJyAnLCAkdmFsdWUgKTsKCgkJCQkkY29sX3dpZHRoID0gJHRoaXMtPl93aWR0aHNbICRjb2wgXTsKCQkJCSRlbmNvZGluZyA9IGZ1bmN0aW9uX2V4aXN0cyggJ21iX2RldGVjdF9lbmNvZGluZycgKSA/IG1iX2RldGVjdF9lbmNvZGluZyggJHZhbHVlLCBudWxsLCB0cnVlIC8qc3RyaWN0Ki8gKSA6IGZhbHNlOwoJCQkJJG9yaWdpbmFsX3ZhbF93aWR0aCA9IENvbG9yczo6d2lkdGgoICR2YWx1ZSwgc2VsZjo6aXNQcmVDb2xvcml6ZWQoICRjb2wgKSwgJGVuY29kaW5nICk7CgkJCQlpZiAoICRjb2xfd2lkdGggJiYgJG9yaWdpbmFsX3ZhbF93aWR0aCA+ICRjb2xfd2lkdGggKSB7CgkJCQkJJHJvd1sgJGNvbCBdID0gXGNsaVxzYWZlX3N1YnN0ciggJHZhbHVlLCAwLCAkY29sX3dpZHRoLCB0cnVlIC8qaXNfd2lkdGgqLywgJGVuY29kaW5nICk7CgkJCQkJJHZhbHVlID0gXGNsaVxzYWZlX3N1YnN0ciggJHZhbHVlLCBcY2xpXHNhZmVfc3RybGVuKCAkcm93WyAkY29sIF0sICRlbmNvZGluZyApLCBudWxsIC8qbGVuZ3RoKi8sIGZhbHNlIC8qaXNfd2lkdGgqLywgJGVuY29kaW5nICk7CgkJCQkJJGkgPSAwOwoJCQkJCWRvIHsKCQkJCQkJJGV4dHJhX3ZhbHVlID0gXGNsaVxzYWZlX3N1YnN0ciggJHZhbHVlLCAwLCAkY29sX3dpZHRoLCB0cnVlIC8qaXNfd2lkdGgqLywgJGVuY29kaW5nICk7CgkJCQkJCSR2YWxfd2lkdGggPSBDb2xvcnM6OndpZHRoKCAkZXh0cmFfdmFsdWUsIHNlbGY6OmlzUHJlQ29sb3JpemVkKCAkY29sICksICRlbmNvZGluZyApOwoJCQkJCQlpZiAoICR2YWxfd2lkdGggKSB7CgkJCQkJCQkkZXh0cmFfcm93c1sgJGNvbCBdW10gPSAkZXh0cmFfdmFsdWU7CgkJCQkJCQkkdmFsdWUgPSBcY2xpXHNhZmVfc3Vic3RyKCAkdmFsdWUsIFxjbGlcc2FmZV9zdHJsZW4oICRleHRyYV92YWx1ZSwgJGVuY29kaW5nICksIG51bGwgLypsZW5ndGgqLywgZmFsc2UgLyppc193aWR0aCovLCAkZW5jb2RpbmcgKTsKCQkJCQkJCSRpKys7CgkJCQkJCQlpZiAoICRpID4gJGV4dHJhX3Jvd19jb3VudCApIHsKCQkJCQkJCQkkZXh0cmFfcm93X2NvdW50ID0gJGk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9IHdoaWxlKCAkdmFsdWUgKTsKCQkJCX0KCgkJCX0KCQl9CgoJCSRyb3cgPSBhcnJheV9tYXAoYXJyYXkoJHRoaXMsICdwYWRDb2x1bW4nKSwgJHJvdywgYXJyYXlfa2V5cygkcm93KSk7CgkJYXJyYXlfdW5zaGlmdCgkcm93LCAnJyk7IC8vIEZpcnN0IGJvcmRlcgoJCWFycmF5X3B1c2goJHJvdywgJycpOyAvLyBMYXN0IGJvcmRlcgoKCQkkcmV0ID0gam9pbigkdGhpcy0+X2NoYXJhY3RlcnNbJ2JvcmRlciddLCAkcm93KTsKCQlpZiAoICRleHRyYV9yb3dfY291bnQgKSB7CgkJCWZvcmVhY2goICRleHRyYV9yb3dzIGFzICRjb2wgPT4gJGNvbF92YWx1ZXMgKSB7CgkJCQl3aGlsZSggY291bnQoICRjb2xfdmFsdWVzICkgPCAkZXh0cmFfcm93X2NvdW50ICkgewoJCQkJCSRjb2xfdmFsdWVzW10gPSAnJzsKCQkJCX0KCQkJfQoKCQkJZG8gewoJCQkJJHJvd192YWx1ZXMgPSBhcnJheSgpOwoJCQkJJGhhc19tb3JlID0gZmFsc2U7CgkJCQlmb3JlYWNoKCAkZXh0cmFfcm93cyBhcyAkY29sID0+ICYkY29sX3ZhbHVlcyApIHsKCQkJCQkkcm93X3ZhbHVlc1sgJGNvbCBdID0gYXJyYXlfc2hpZnQoICRjb2xfdmFsdWVzICk7CgkJCQkJaWYgKCBjb3VudCggJGNvbF92YWx1ZXMgKSApIHsKCQkJCQkJJGhhc19tb3JlID0gdHJ1ZTsKCQkJCQl9CgkJCQl9CgoJCQkJJHJvd192YWx1ZXMgPSBhcnJheV9tYXAoYXJyYXkoJHRoaXMsICdwYWRDb2x1bW4nKSwgJHJvd192YWx1ZXMsIGFycmF5X2tleXMoJHJvd192YWx1ZXMpKTsKCQkJCWFycmF5X3Vuc2hpZnQoJHJvd192YWx1ZXMsICcnKTsgLy8gRmlyc3QgYm9yZGVyCgkJCQlhcnJheV9wdXNoKCRyb3dfdmFsdWVzLCAnJyk7IC8vIExhc3QgYm9yZGVyCgoJCQkJJHJldCAuPSBQSFBfRU9MIC4gam9pbigkdGhpcy0+X2NoYXJhY3RlcnNbJ2JvcmRlciddLCAkcm93X3ZhbHVlcyk7CgkJCX0gd2hpbGUoICRoYXNfbW9yZSApOwoJCX0KCQlyZXR1cm4gJHJldDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHBhZENvbHVtbigkY29udGVudCwgJGNvbHVtbikgewoJCXJldHVybiAkdGhpcy0+X2NoYXJhY3RlcnNbJ3BhZGRpbmcnXSAuIENvbG9yczo6cGFkKCAkY29udGVudCwgJHRoaXMtPl93aWR0aHNbICRjb2x1bW4gXSwgJHRoaXMtPmlzUHJlQ29sb3JpemVkKCAkY29sdW1uICkgKSAuICR0aGlzLT5fY2hhcmFjdGVyc1sncGFkZGluZyddOwoJfQoKCS8qKgoJICogU2V0IHdoZXRoZXIgaXRlbXMgYXJlIHByZS1jb2xvcml6ZWQuCgkgKgoJICogQHBhcmFtIGJvb2x8YXJyYXkgJGNvbG9yaXplZCBBIGJvb2xlYW4gdG8gc2V0IGFsbCBjb2x1bW5zIGluIHRoZSB0YWJsZSBhcyBwcmUtY29sb3JpemVkLCBvciBhbiBhcnJheSBvZiBib29sZWFucyBrZXllZCBieSBjb2x1bW4gaW5kZXggKG51bWJlcikgdG8gc2V0IGluZGl2aWR1YWwgY29sdW1ucyBhcyBwcmUtY29sb3JpemVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0UHJlQ29sb3JpemVkKCAkcHJlX2NvbG9yaXplZCApIHsKCQkkdGhpcy0+X3ByZV9jb2xvcml6ZWQgPSAkcHJlX2NvbG9yaXplZDsKCX0KCgkvKioKCSAqIElzIGEgY29sdW1uIHByZS1jb2xvcml6ZWQ/CgkgKgoJICogQHBhcmFtIGludCAkY29sdW1uIENvbHVtbiBpbmRleCB0byBjaGVjay4KCSAqIEByZXR1cm4gYm9vbCBUcnVlIGlmIHdob2xlIHRhYmxlIGlzIG1hcmtlZCBhcyBwcmUtY29sb3JpemVkLCBvciBpZiB0aGUgaW5kaXZpZHVhbCBjb2x1bW4gaXMgcHJlLWNvbG9yaXplZDsgZWxzZSBmYWxzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzUHJlQ29sb3JpemVkKCAkY29sdW1uICkgewoJCWlmICggaXNfYm9vbCggJHRoaXMtPl9wcmVfY29sb3JpemVkICkgKSB7CgkJCXJldHVybiAkdGhpcy0+X3ByZV9jb2xvcml6ZWQ7CgkJfQoJCWlmICggaXNfYXJyYXkoICR0aGlzLT5fcHJlX2NvbG9yaXplZCApICYmIGlzc2V0KCAkdGhpcy0+X3ByZV9jb2xvcml6ZWRbICRjb2x1bW4gXSApICkgewoJCQlyZXR1cm4gJHRoaXMtPl9wcmVfY29sb3JpemVkWyAkY29sdW1uIF07CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIFJ5YW4gU3VsbGl2YW4gPHJzdWxsaXZhbkBjb25uZWN0c3R1ZGlvcy5jb20+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKLyoqCiAqIFRoZSBgVHJlZWAgY2xhc3MgaXMgdXNlZCB0byBkaXNwbGF5IGRhdGEgaW4gYSB0cmVlLWxpa2UgZm9ybWF0LgogKi8KY2xhc3MgVHJlZSB7CgogICAgcHJvdGVjdGVkICRfcmVuZGVyZXI7CiAgICBwcm90ZWN0ZWQgJF9kYXRhID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHJlbmRlcmVyIHVzZWQgYnkgdGhpcyB0cmVlLgogICAgICoKICAgICAqIEBwYXJhbSB0cmVlXFJlbmRlcmVyICAkcmVuZGVyZXIgIFRoZSByZW5kZXJlciB0byB1c2UgZm9yIG91dHB1dC4KICAgICAqIEBzZWUgICB0cmVlXFJlbmRlcmVyCiAgICAgKiBAc2VlICAgdHJlZVxBc2NpaQogICAgICogQHNlZSAgIHRyZWVcTWFya2Rvd24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlbmRlcmVyKHRyZWVcUmVuZGVyZXIgJHJlbmRlcmVyKSB7CiAgICAgICAgJHRoaXMtPl9yZW5kZXJlciA9ICRyZW5kZXJlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgZGF0YS4KICAgICAqIEZvcm1hdDoKICAgICAqICAgICBbCiAgICAgKiAgICAgICAgICdMYWJlbCcgPT4gWwogICAgICogICAgICAgICAgICAgJ1RoaW5nJyA9PiBbJ1RoaW5nJ10sCiAgICAgKiAgICAgICAgIF0sCiAgICAgKiAgICAgICAgICdUaGluZycsCiAgICAgKiAgICAgXQogICAgICogQHBhcmFtIGFycmF5ICRkYXRhCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREYXRhKGFycmF5ICRkYXRhKQogICAgewogICAgICAgICR0aGlzLT5fZGF0YSA9ICRkYXRhOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVyIHRoZSB0cmVlIGFuZCByZXR1cm4gaXQgYXMgYSBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPl9yZW5kZXJlci0+cmVuZGVyKCR0aGlzLT5fZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwbGF5IHRoZSByZW5kZXJlZCB0cmVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5KCkKICAgIHsKICAgICAgICBlY2hvICR0aGlzLT5yZW5kZXIoKTsKICAgIH0KCn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaTsKCnVzZSBjbGlcU3RyZWFtczsKCi8qKgogKiBUaGUgYE5vdGlmeWAgY2xhc3MgaXMgdGhlIGJhc2lzIG9mIGFsbCBmZWVkYmFjayBjbGFzc2VzLCBzdWNoIGFzIEluZGljYXRvcnMKICogYW5kIFByb2dyZXNzIG1ldGVycy4gVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHJlZnJlc2ggb3V0cHV0IGFmdGVyIDEwMG1zCiAqIGhhdmUgcGFzc2VkLiBUaGlzIGlzIGRvbmUgdG8gcHJldmVudGluZyB0aGUgc2NyZWVuIGZyb20gZmxpY2tlcmluZyBhbmQga2VlcAogKiBzbG93ZG93bnMgZnJvbSBvdXRwdXQgdG8gYSBtaW5pbXVtLgogKgogKiBUaGUgbW9zdCBiYXNpYyBmb3JtIG9mIE5vdGlmaWVyIGhhcyBubyBtYXhpbSwgYW5kIHNpbXBseSBkaXNwbGF5cyBhIHNlcmllcwogKiBvZiBjaGFyYWN0ZXJzIHRvIGluZGljYXRlIHByb2dyZXNzIGlzIGJlaW5nIG1hZGUuCiAqLwphYnN0cmFjdCBjbGFzcyBOb3RpZnkgewoJcHJvdGVjdGVkICRfY3VycmVudCA9IDA7Cglwcm90ZWN0ZWQgJF9maXJzdCA9IHRydWU7Cglwcm90ZWN0ZWQgJF9pbnRlcnZhbDsKCXByb3RlY3RlZCAkX21lc3NhZ2U7Cglwcm90ZWN0ZWQgJF9zdGFydDsKCXByb3RlY3RlZCAkX3RpbWVyOwoKCS8qKgoJICogSW5zdGF0aWF0ZXMgYSBOb3RpZmljYXRpb24gb2JqZWN0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRtc2cgICAgICAgVGhlIHRleHQgdG8gZGlzcGxheSBuZXh0IHRvIHRoZSBOb3RpZmllci4KCSAqIEBwYXJhbSBpbnQgICAgICRpbnRlcnZhbCAgVGhlIGludGVydmFsIGluIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHVwZGF0ZXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbXNnLCAkaW50ZXJ2YWwgPSAxMDApIHsKCQkkdGhpcy0+X21lc3NhZ2UgPSAkbXNnOwoJCSR0aGlzLT5faW50ZXJ2YWwgPSAoaW50KSRpbnRlcnZhbDsKCX0KCgkvKioKCSAqIFRoaXMgbWV0aG9kIHNob3VsZCBiZSB1c2VkIHRvIHByaW50IG91dCB0aGUgTm90aWZpZXIuIFRoaXMgbWV0aG9kIGlzCgkgKiBjYWxsZWQgZnJvbSBgY2xpXE5vdGlmeTo6dGljaygpYCBhZnRlciBgY2xpXE5vdGlmeTo6JF9pbnRlcnZhbGAgaGFzIHBhc3NlZC4KCSAqCgkgKiBAYWJzdHJhY3QKCSAqIEBwYXJhbSBib29sZWFuICAkZmluaXNoCgkgKiBAc2VlIGNsaVxOb3RpZnk6OnRpY2soKQoJICovCglhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gZGlzcGxheSgkZmluaXNoID0gZmFsc2UpOwoKCS8qKgoJICogUmVzZXQgdGhlIG5vdGlmaWVyIHN0YXRlIHNvIHRoZSBzYW1lIGluc3RhbmNlIGNhbiBiZSB1c2VkIGluIG11bHRpcGxlIGxvb3BzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVzZXQoKSB7CgkJJHRoaXMtPl9jdXJyZW50ID0gMDsKCQkkdGhpcy0+X2ZpcnN0ID0gdHJ1ZTsKCQkkdGhpcy0+X3N0YXJ0ID0gbnVsbDsKCQkkdGhpcy0+X3RpbWVyID0gbnVsbDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGZvcm1hdHRlZCB0aWNrIGNvdW50LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgZm9ybWF0dGVkIHRpY2sgY291bnQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkgewoJCXJldHVybiBudW1iZXJfZm9ybWF0KCR0aGlzLT5fY3VycmVudCk7Cgl9CgoJLyoqCgkgKiBDYWxjdWxhdGVzIHRoZSB0aW1lIGVsYXBzZWQgc2luY2UgdGhlIE5vdGlmaWVyIHdhcyBmaXJzdCB0aWNrZWQuCgkgKgoJICogQHJldHVybiBpbnQgIFRoZSBlbGFwc2VkIHRpbWUgaW4gc2Vjb25kcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVsYXBzZWQoKSB7CgkJaWYgKCEkdGhpcy0+X3N0YXJ0KSB7CgkJCXJldHVybiAwOwoJCX0KCgkJJGVsYXBzZWQgPSB0aW1lKCkgLSAkdGhpcy0+X3N0YXJ0OwoJCXJldHVybiAkZWxhcHNlZDsKCX0KCgkvKioKCSAqIENhbGN1bGF0ZXMgdGhlIHNwZWVkIChudW1iZXIgb2YgdGlja3MgcGVyIHNlY29uZCkgYXQgd2hpY2ggdGhlIE5vdGlmaWVyCgkgKiBpcyBiZWluZyB1cGRhdGVkLgoJICoKCSAqIEByZXR1cm4gaW50ICBUaGUgbnVtYmVyIG9mIHRpY2tzIHBlcmZvcm1lZCBpbiAxIHNlY29uZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNwZWVkKCkgewoJCXN0YXRpYyAkdGljaywgJGl0ZXJhdGlvbiA9IDAsICRzcGVlZCA9IDA7CgoJCWlmICghJHRoaXMtPl9zdGFydCkgewoJCQlyZXR1cm4gMDsKCQl9IGVsc2UgaWYgKCEkdGljaykgewoJCQkkdGljayA9ICR0aGlzLT5fc3RhcnQ7CgkJfQoKCQkkbm93ID0gbWljcm90aW1lKHRydWUpOwoJCSRzcGFuID0gJG5vdyAtICR0aWNrOwoJCWlmICgkc3BhbiA+IDEpIHsKCQkJJGl0ZXJhdGlvbisrOwoJCQkkdGljayA9ICRub3c7CgkJCSRzcGVlZCA9ICgkdGhpcy0+X2N1cnJlbnQgLyAkaXRlcmF0aW9uKSAvICRzcGFuOwoJCX0KCgkJcmV0dXJuICRzcGVlZDsKCX0KCgkvKioKCSAqIFRha2VzIGEgdGltZSBzcGFuIGdpdmVuIGluIHNlY29uZHMgYW5kIGZvcm1hdHMgaXQgZm9yIGRpc3BsYXkuIFRoZQoJICogcmV0dXJuZWQgc3RyaW5nIHdpbGwgYmUgaW4gTU06U1MgZm9ybS4KCSAqCgkgKiBAcGFyYW0gaW50ICAkdGltZSBUaGUgdGltZSBzcGFuIGluIHNlY29uZHMgdG8gZm9ybWF0LgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgdGltZSBzcGFuLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZm9ybWF0VGltZSgkdGltZSkgewoJCXJldHVybiBmbG9vcigkdGltZSAvIDYwKSAuICc6JyAuIHN0cl9wYWQoJHRpbWUgJSA2MCwgMiwgMCwgU1RSX1BBRF9MRUZUKTsKCX0KCgkvKioKCSAqIEZpbmlzaCBvdXIgTm90aWZpY2F0aW9uIGRpc3BsYXkuIFNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIE5vdGlmaWVyIGlzCgkgKiBubyBsb25nZXIgbmVlZGVkLgoJICoKCSAqIEBzZWUgY2xpXE5vdGlmeTo6ZGlzcGxheSgpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmaW5pc2goKSB7CgkJU3RyZWFtczo6b3V0KCJcciIpOwoJCSR0aGlzLT5kaXNwbGF5KHRydWUpOwoJCVN0cmVhbXM6OmxpbmUoKTsKCX0KCgkvKioKCSAqIEluY3JlbWVudHMgYXJlIHRpY2sgY291bnRlciBieSB0aGUgZ2l2ZW4gYW1vdW50LiBJZiBubyBhbW91bnQgaXMgcHJvdmlkZWQsCgkgKiB0aGUgdGlja2VyIGlzIGluY3JlbWVudGVkIGJ5IDEuCgkgKgoJICogQHBhcmFtIGludCAgJGluY3JlbWVudCAgVGhlIGFtb3VudCB0byBpbmNyZW1lbnQgYnkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbmNyZW1lbnQoJGluY3JlbWVudCA9IDEpIHsKCQkkdGhpcy0+X2N1cnJlbnQgKz0gJGluY3JlbWVudDsKCX0KCgkvKioKCSAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGlzcGxheSBzaG91bGQgYmUgdXBkYXRlZCBvciBub3QgYWNjb3JkaW5nIHRvCgkgKiBvdXIgaW50ZXJ2YWwgc2V0dGluZy4KCSAqCgkgKiBAcmV0dXJuIGJvb2xlYW4gIGB0cnVlYCBpZiB0aGUgZGlzcGxheSBzaG91bGQgYmUgdXBkYXRlZCwgYGZhbHNlYCBvdGhlcndpc2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaG91bGRVcGRhdGUoKSB7CgkJJG5vdyA9IG1pY3JvdGltZSh0cnVlKSAqIDEwMDA7CgoJCWlmIChlbXB0eSgkdGhpcy0+X3RpbWVyKSkgewoJCQkkdGhpcy0+X3N0YXJ0ID0gKGludCkoKCR0aGlzLT5fdGltZXIgPSAkbm93KSAvIDEwMDApOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCWlmICgoJG5vdyAtICR0aGlzLT5fdGltZXIpID4gJHRoaXMtPl9pbnRlcnZhbCkgewoJCQkkdGhpcy0+X3RpbWVyID0gJG5vdzsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFRoaXMgbWV0aG9kIGlzIHRoZSBtZWF0IG9mIGFsbCBOb3RpZmllcnMuIEZpcnN0IHdlIGluY3JlbWVudCB0aGUgdGlja2VyCgkgKiBhbmQgdGhlbiB1cGRhdGUgdGhlIGRpc3BsYXkgaWYgZW5vdWdoIHRpbWUgaGFzIHBhc3NlZCBzaW5jZSBvdXIgbGFzdCB0aWNrLgoJICoKCSAqIEBwYXJhbSBpbnQgICRpbmNyZW1lbnQgIFRoZSBhbW91bnQgdG8gaW5jcmVtZW50IGJ5LgoJICogQHNlZSBjbGlcTm90aWZ5OjppbmNyZW1lbnQoKQoJICogQHNlZSBjbGlcTm90aWZ5OjpzaG91bGRVcGRhdGUoKQoJICogQHNlZSBjbGlcTm90aWZ5OjpkaXNwbGF5KCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRpY2soJGluY3JlbWVudCA9IDEpIHsKCQkkdGhpcy0+aW5jcmVtZW50KCRpbmNyZW1lbnQpOwoKCQlpZiAoJHRoaXMtPnNob3VsZFVwZGF0ZSgpKSB7CgkJCVN0cmVhbXM6Om91dCgiXHIiKTsKCQkJJHRoaXMtPmRpc3BsYXkoKTsKCQl9Cgl9Cn0KPD9waHAKLy8gR2VuZXJhdGVkIGJ5ICJnZW5fZWFzdF9hc2lhbl93aWR0aC5waHAiIGZyb20gImh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLzEwLjAuMC91Y2QvRWFzdEFzaWFuV2lkdGgudHh0Ii4KJGVhd19yZWdleCA9ICcvXHhlMSg/Olx4ODRbXHg4MC1ceGJmXXxceDg1W1x4ODAtXHg5Zl0pfFx4ZTIoPzpceDhjW1x4OWFceDliXHhhOVx4YWFdfFx4OGZbXHhhOS1ceGFjXHhiMFx4YjNdfFx4OTdbXHhiZFx4YmVdfFx4OThbXHg5NFx4OTVdfFx4OTlbXHg4OC1ceDkzXHhiZl18XHg5YVtceDkzXHhhMVx4YWFceGFiXHhiZFx4YmVdfFx4OWJbXHg4NFx4ODVceDhlXHg5NFx4YWFceGIyXHhiM1x4YjVceGJhXHhiZF18XHg5Y1tceDg1XHg4YVx4OGJceGE4XXxceDlkW1x4OGNceDhlXHg5My1ceDk1XHg5N118XHg5ZVtceDk1LVx4OTdceGIwXHhiZl18XHhhY1tceDliXHg5Y118XHhhZFtceDkwXHg5NV18XHhiYVtceDgwLVx4OTlceDliLVx4YmZdfFx4YmJbXHg4MC1ceGIzXXxbXHhiYy1ceGJlXVtceDgwLVx4YmZdfFx4YmZbXHg4MC1ceDk1XHhiMC1ceGJiXSl8XHhlMyg/Olx4ODBbXHg4MC1ceGJlXXxceDgxW1x4ODEtXHhiZl18XHg4MltceDgwLVx4OTZceDk5LVx4YmZdfFx4ODNbXHg4MC1ceGJmXXxceDg0W1x4ODUtXHhhZVx4YjEtXHhiZl18XHg4NVtceDgwLVx4YmZdfFx4ODZbXHg4MC1ceDhlXHg5MC1ceGJhXXxceDg3W1x4ODAtXHhhM1x4YjAtXHhiZl18XHg4OFtceDgwLVx4OWVceGEwLVx4YmZdfFx4ODlbXHg4MC1ceDg3XHg5MC1ceGJmXXxceDhhW1x4ODAtXHhiZl18XHg4YltceDgwLVx4YmVdfFtceDhjLVx4YmZdW1x4ODAtXHhiZl0pfFx4ZTQoPzpbXHg4MC1ceGI2XVtceDgwLVx4YmZdfFtceGI4LVx4YmZdW1x4ODAtXHhiZl0pfFtceGU1LVx4ZTldW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGVhKD86W1x4ODAtXHg5MV1bXHg4MC1ceGJmXXxceDkyW1x4ODAtXHg4Y1x4OTAtXHhiZl18XHg5M1tceDgwLVx4ODZdfFx4YTVbXHhhMC1ceGJjXXxbXHhiMC1ceGJmXVtceDgwLVx4YmZdKXxbXHhlYlx4ZWNdW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGVkKD86W1x4ODAtXHg5ZF1bXHg4MC1ceGJmXXxceDllW1x4ODAtXHhhM10pfFx4ZWYoPzpbXHhhNC1ceGFiXVtceDgwLVx4YmZdfFx4YjhbXHg5MC1ceDk5XHhiMC1ceGJmXXxceGI5W1x4ODAtXHg5Mlx4OTQtXHhhNlx4YTgtXHhhYl18XHhiY1tceDgxLVx4YmZdfFx4YmRbXHg4MC1ceGEwXXxceGJmW1x4YTAtXHhhNl0pfFx4ZjAoPzpceDk2XHhiZltceGEwXHhhMV18XHg5N1tceDgwLVx4YmZdW1x4ODAtXHhiZl18XHg5OCg/OltceDgwLVx4OWVdW1x4ODAtXHhiZl18XHg5ZltceDgwLVx4YWNdfFtceGEwLVx4YWFdW1x4ODAtXHhiZl18XHhhYltceDgwLVx4YjJdKXxceDliKD86W1x4ODAtXHg4M11bXHg4MC1ceGJmXXxceDg0W1x4ODAtXHg5ZV18XHg4NVtceGIwLVx4YmZdfFtceDg2LVx4OGFdW1x4ODAtXHhiZl18XHg4YltceDgwLVx4YmJdKXxceDlmKD86XHg4MFx4ODR8XHg4M1x4OGZ8XHg4NltceDhlXHg5MS1ceDlhXXxceDg4W1x4ODAtXHg4Mlx4OTAtXHhiYl18XHg4OVtceDgwLVx4ODhceDkwXHg5MVx4YTAtXHhhNV18XHg4Y1tceDgwLVx4YTBceGFkLVx4YjVceGI3LVx4YmZdfFx4OGRbXHg4MC1ceGJjXHhiZVx4YmZdfFx4OGVbXHg4MC1ceDkzXHhhMC1ceGJmXXxceDhmW1x4ODAtXHg4YVx4OGYtXHg5M1x4YTAtXHhiMFx4YjRceGI4LVx4YmZdfFx4OTBbXHg4MC1ceGJlXXxceDkxW1x4ODBceDgyLVx4YmZdfFx4OTJbXHg4MC1ceGJmXXxceDkzW1x4ODAtXHhiY1x4YmZdfFx4OTRbXHg4MC1ceGJkXXxceDk1W1x4OGItXHg4ZVx4OTAtXHhhN1x4YmFdfFx4OTZbXHg5NVx4OTZceGE0XXxceDk3W1x4YmItXHhiZl18XHg5OFtceDgwLVx4YmZdfFx4OTlbXHg4MC1ceDhmXXxceDlhW1x4ODAtXHhiZl18XHg5YltceDgwLVx4ODVceDhjXHg5MC1ceDkyXHhhYlx4YWNceGI0LVx4YjhdfFx4YTRbXHg5MC1ceGJlXXxceGE1W1x4ODAtXHg4Y1x4OTAtXHhhYl18XHhhNltceDgwLVx4OTddfFx4YTdbXHg4MFx4OTAtXHhhNl0pfFtceGEwLVx4YWVdW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGFmKD86W1x4ODAtXHhiZV1bXHg4MC1ceGJmXXxceGJmW1x4ODAtXHhiZF0pfFtceGIwLVx4YmVdW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGJmKD86W1x4ODAtXHhiZV1bXHg4MC1ceGJmXXxceGJmW1x4ODAtXHhiZF0pKS8nOyAvLyAxODE3MzggY29kZSBwb2ludHMuCgovLyBHZW5lcmF0ZWQgYnkgImdlbl9jYXRfcmVnZXhfYWx0cy5waHAiIGZyb20gImh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLzEwLjAuMC91Y2QvVW5pY29kZURhdGEudHh0Ii4KJG1fcmVnZXggPSAnL1x4Y2NbXHg4MC1ceGJmXXxceGNkW1x4ODAtXHhhZl18XHhkMltceDgzLVx4ODldfFx4ZDZbXHg5MS1ceGJkXHhiZl18XHhkN1tceDgxXHg4Mlx4ODRceDg1XHg4N118XHhkOFtceDkwLVx4OWFdfFx4ZDlbXHg4Yi1ceDlmXHhiMF18XHhkYltceDk2LVx4OWNceDlmLVx4YTRceGE3XHhhOFx4YWEtXHhhZF18XHhkY1tceDkxXHhiMC1ceGJmXXxceGRkW1x4ODAtXHg4YV18XHhkZVtceGE2LVx4YjBdfFx4ZGZbXHhhYi1ceGIzXXxceGUwKD86XHhhMFtceDk2LVx4OTlceDliLVx4YTNceGE1LVx4YTdceGE5LVx4YWRdfFx4YTFbXHg5OS1ceDliXXxceGEzW1x4OTQtXHhhMVx4YTMtXHhiZl18XHhhNFtceDgwLVx4ODNceGJhLVx4YmNceGJlXHhiZl18XHhhNVtceDgwLVx4OGZceDkxLVx4OTdceGEyXHhhM118XHhhNltceDgxLVx4ODNceGJjXHhiZVx4YmZdfFx4YTdbXHg4MC1ceDg0XHg4N1x4ODhceDhiLVx4OGRceDk3XHhhMlx4YTNdfFx4YThbXHg4MS1ceDgzXHhiY1x4YmVceGJmXXxceGE5W1x4ODAtXHg4Mlx4ODdceDg4XHg4Yi1ceDhkXHg5MVx4YjBceGIxXHhiNV18XHhhYVtceDgxLVx4ODNceGJjXHhiZVx4YmZdfFx4YWJbXHg4MC1ceDg1XHg4Ny1ceDg5XHg4Yi1ceDhkXHhhMlx4YTNceGJhLVx4YmZdfFx4YWNbXHg4MS1ceDgzXHhiY1x4YmVceGJmXXxceGFkW1x4ODAtXHg4NFx4ODdceDg4XHg4Yi1ceDhkXHg5Nlx4OTdceGEyXHhhM118XHhhZVtceDgyXHhiZVx4YmZdfFx4YWZbXHg4MC1ceDgyXHg4Ni1ceDg4XHg4YS1ceDhkXHg5N118XHhiMFtceDgwLVx4ODNceGJlXHhiZl18XHhiMVtceDgwLVx4ODRceDg2LVx4ODhceDhhLVx4OGRceDk1XHg5Nlx4YTJceGEzXXxceGIyW1x4ODEtXHg4M1x4YmNceGJlXHhiZl18XHhiM1tceDgwLVx4ODRceDg2LVx4ODhceDhhLVx4OGRceDk1XHg5Nlx4YTJceGEzXXxceGI0W1x4ODAtXHg4M1x4YmJceGJjXHhiZVx4YmZdfFx4YjVbXHg4MC1ceDg0XHg4Ni1ceDg4XHg4YS1ceDhkXHg5N1x4YTJceGEzXXxceGI2W1x4ODJceDgzXXxceGI3W1x4OGFceDhmLVx4OTRceDk2XHg5OC1ceDlmXHhiMlx4YjNdfFx4YjhbXHhiMVx4YjQtXHhiYV18XHhiOVtceDg3LVx4OGVdfFx4YmFbXHhiMVx4YjQtXHhiOVx4YmJceGJjXXxceGJiW1x4ODgtXHg4ZF18XHhiY1tceDk4XHg5OVx4YjVceGI3XHhiOVx4YmVceGJmXXxceGJkW1x4YjEtXHhiZl18XHhiZVtceDgwLVx4ODRceDg2XHg4N1x4OGQtXHg5N1x4OTktXHhiY118XHhiZlx4ODYpfFx4ZTEoPzpceDgwW1x4YWItXHhiZV18XHg4MVtceDk2LVx4OTlceDllLVx4YTBceGEyLVx4YTRceGE3LVx4YWRceGIxLVx4YjRdfFx4ODJbXHg4Mi1ceDhkXHg4Zlx4OWEtXHg5ZF18XHg4ZFtceDlkLVx4OWZdfFx4OWNbXHg5Mi1ceDk0XHhiMi1ceGI0XXxceDlkW1x4OTJceDkzXHhiMlx4YjNdfFx4OWVbXHhiNC1ceGJmXXxceDlmW1x4ODAtXHg5M1x4OWRdfFx4YTBbXHg4Yi1ceDhkXXxceGEyW1x4ODVceDg2XHhhOV18XHhhNFtceGEwLVx4YWJceGIwLVx4YmJdfFx4YThbXHg5Ny1ceDliXXxceGE5W1x4OTUtXHg5ZVx4YTAtXHhiY1x4YmZdfFx4YWFbXHhiMC1ceGJlXXxceGFjW1x4ODAtXHg4NFx4YjQtXHhiZl18XHhhZFtceDgwLVx4ODRceGFiLVx4YjNdfFx4YWVbXHg4MC1ceDgyXHhhMS1ceGFkXXxceGFmW1x4YTYtXHhiM118XHhiMFtceGE0LVx4YjddfFx4YjNbXHg5MC1ceDkyXHg5NC1ceGE4XHhhZFx4YjItXHhiNFx4YjctXHhiOV18XHhiN1tceDgwLVx4YjlceGJiLVx4YmZdKXxceGUyKD86XHg4M1tceDkwLVx4YjBdfFx4YjNbXHhhZi1ceGIxXXxceGI1XHhiZnxceGI3W1x4YTAtXHhiZl0pfFx4ZTMoPzpceDgwW1x4YWEtXHhhZl18XHg4MltceDk5XHg5YV0pfFx4ZWEoPzpceDk5W1x4YWYtXHhiMlx4YjQtXHhiZF18XHg5YVtceDllXHg5Zl18XHg5YltceGIwXHhiMV18XHhhMFtceDgyXHg4Nlx4OGJceGEzLVx4YTddfFx4YTJbXHg4MFx4ODFceGI0LVx4YmZdfFx4YTNbXHg4MC1ceDg1XHhhMC1ceGIxXXxceGE0W1x4YTYtXHhhZF18XHhhNVtceDg3LVx4OTNdfFx4YTZbXHg4MC1ceDgzXHhiMy1ceGJmXXxceGE3W1x4ODBceGE1XXxceGE4W1x4YTktXHhiNl18XHhhOVtceDgzXHg4Y1x4OGRceGJiLVx4YmRdfFx4YWFbXHhiMFx4YjItXHhiNFx4YjdceGI4XHhiZVx4YmZdfFx4YWJbXHg4MVx4YWItXHhhZlx4YjVceGI2XXxceGFmW1x4YTMtXHhhYVx4YWNceGFkXSl8XHhlZig/Olx4YWNceDllfFx4YjhbXHg4MC1ceDhmXHhhMC1ceGFmXSl8XHhmMCg/Olx4OTAoPzpceDg3XHhiZHxceDhiXHhhMHxceDhkW1x4YjYtXHhiYV18XHhhOFtceDgxLVx4ODNceDg1XHg4Nlx4OGMtXHg4Zlx4YjgtXHhiYVx4YmZdfFx4YWJbXHhhNVx4YTZdKXxceDkxKD86XHg4MFtceDgwLVx4ODJceGI4LVx4YmZdfFx4ODFbXHg4MC1ceDg2XHhiZl18XHg4MltceDgwLVx4ODJceGIwLVx4YmFdfFx4ODRbXHg4MC1ceDgyXHhhNy1ceGI0XXxceDg1XHhiM3xceDg2W1x4ODAtXHg4Mlx4YjMtXHhiZl18XHg4N1tceDgwXHg4YS1ceDhjXXxceDg4W1x4YWMtXHhiN1x4YmVdfFx4OGJbXHg5Zi1ceGFhXXxceDhjW1x4ODAtXHg4M1x4YmNceGJlXHhiZl18XHg4ZFtceDgwLVx4ODRceDg3XHg4OFx4OGItXHg4ZFx4OTdceGEyXHhhM1x4YTYtXHhhY1x4YjAtXHhiNF18XHg5MFtceGI1LVx4YmZdfFx4OTFbXHg4MC1ceDg2XXxceDkyW1x4YjAtXHhiZl18XHg5M1tceDgwLVx4ODNdfFx4OTZbXHhhZi1ceGI1XHhiOC1ceGJmXXxceDk3W1x4ODBceDljXHg5ZF18XHg5OFtceGIwLVx4YmZdfFx4OTlceDgwfFx4OWFbXHhhYi1ceGI3XXxceDljW1x4OWQtXHhhYl18XHhhOFtceDgxLVx4OGFceGIzLVx4YjlceGJiLVx4YmVdfFx4YTlbXHg4N1x4OTEtXHg5Yl18XHhhYVtceDhhLVx4OTldfFx4YjBbXHhhZi1ceGI2XHhiOC1ceGJmXXxceGIyW1x4OTItXHhhN1x4YTktXHhiNl18XHhiNFtceGIxLVx4YjZceGJhXHhiY1x4YmRceGJmXXxceGI1W1x4ODAtXHg4NVx4ODddKXxceDk2KD86XHhhYltceGIwLVx4YjRdfFx4YWNbXHhiMC1ceGI2XXxceGJkW1x4OTEtXHhiZV18XHhiZVtceDhmLVx4OTJdKXxceDliXHhiMltceDlkXHg5ZV18XHg5ZCg/Olx4ODVbXHhhNS1ceGE5XHhhZC1ceGIyXHhiYi1ceGJmXXxceDg2W1x4ODAtXHg4Mlx4ODUtXHg4Ylx4YWEtXHhhZF18XHg4OVtceDgyLVx4ODRdfFx4YThbXHg4MC1ceGI2XHhiYi1ceGJmXXxceGE5W1x4ODAtXHhhY1x4YjVdfFx4YWFbXHg4NFx4OWItXHg5Zlx4YTEtXHhhZl0pfFx4OWUoPzpceDgwW1x4ODAtXHg4Nlx4ODgtXHg5OFx4OWItXHhhMVx4YTNceGE0XHhhNi1ceGFhXXxceGEzW1x4OTAtXHg5Nl18XHhhNVtceDg0LVx4OGFdKSl8XHhmM1x4YTAoPzpbXHg4NC1ceDg2XVtceDgwLVx4YmZdfFx4ODdbXHg4MC1ceGFmXSkvJzsgLy8gMjE3NyBjb2RlIHBvaW50cy4KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRW1iZWRzOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSV9Db21tYW5kOwoKY2xhc3MgRmV0Y2hfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCS8qKgoJICogQXR0ZW1wdHMgdG8gY29udmVydCBhIFVSTCBpbnRvIGVtYmVkIEhUTUwuCgkgKgoJICogSW4gbm9uLXJhdyBtb2RlLCBzdGFydHMgYnkgY2hlY2tpbmcgdGhlIFVSTCBhZ2FpbnN0IHRoZSByZWdleCBvZiB0aGUgcmVnaXN0ZXJlZCBlbWJlZCBoYW5kbGVycy4KCSAqIElmIG5vbmUgb2YgdGhlIHJlZ2V4IG1hdGNoZXMgYW5kIGl0J3MgZW5hYmxlZCwgdGhlbiB0aGUgVVJMIHdpbGwgYmUgZ2l2ZW4gdG8gdGhlIFdQX29FbWJlZCBjbGFzcy4KCSAqCgkgKiBJbiByYXcgbW9kZSwgY2hlY2tzIHRoZSBwcm92aWRlcnMgZGlyZWN0bHkgYW5kIHJldHVybnMgdGhlIGRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1cmw+CgkgKiA6IFVSTCB0byByZXRyaWV2ZSBvRW1iZWQgZGF0YSBmb3IuCgkgKgoJICogWy0td2lkdGg9PHdpZHRoPl0KCSAqIDogV2lkdGggb2YgdGhlIGVtYmVkIGluIHBpeGVscy4KCSAqCgkgKiBbLS1oZWlnaHQ9PGhlaWdodD5dCgkgKiA6IEhlaWdodCBvZiB0aGUgZW1iZWQgaW4gcGl4ZWxzLgoJICoKCSAqIFstLXBvc3QtaWQ9PGlkPl0KCSAqIDogQ2FjaGUgb0VtYmVkIHJlc3BvbnNlIGZvciBhIGdpdmVuIHBvc3QuCgkgKgoJICogWy0tZGlzY292ZXJdCgkgKiA6IEVuYWJsZSBvRW1iZWQgZGlzY292ZXJ5LiBEZWZhdWx0cyB0byB0cnVlLgoJICoKCSAqIFstLXNraXAtY2FjaGVdCgkgKiA6IElnbm9yZSBhbHJlYWR5IGNhY2hlZCBvRW1iZWQgcmVzcG9uc2VzLiBIYXMgbm8gZWZmZWN0IGlmIHVzaW5nIHRoZSAncmF3JyBvcHRpb24sIHdoaWNoIGRvZXNuJ3QgdXNlIHRoZSBjYWNoZS4KCSAqCgkgKiBbLS1za2lwLXNhbml0aXphdGlvbl0KCSAqIDogUmVtb3ZlIHRoZSBmaWx0ZXIgdGhhdCBXb3JkUHJlc3MgZnJvbSA0LjQgb253YXJkcyB1c2VzIHRvIHNhbml0aXplIG9FbWJlZCByZXNwb25zZXMuIEhhcyBubyBlZmZlY3QgaWYgdXNpbmcgdGhlICdyYXcnIG9wdGlvbiwgd2hpY2ggYnktcGFzc2VzIHNhbml0aXphdGlvbi4KCSAqCgkgKiBbLS1kby1zaG9ydGNvZGVdCgkgKiA6IElmIHRoZSBVUkwgaXMgaGFuZGxlZCBieSBhIHJlZ2lzdGVyZWQgZW1iZWQgaGFuZGxlciBhbmQgcmV0dXJucyBhIHNob3J0Y29kZSwgZG8gc2hvcnRjb2RlIGFuZCByZXR1cm4gcmVzdWx0LiBIYXMgbm8gZWZmZWN0IGlmIHVzaW5nIHRoZSAncmF3JyBvcHRpb24sIHdoaWNoIGJ5LXBhc3NlcyBoYW5kbGVycy4KCSAqCgkgKiBbLS1saW1pdC1yZXNwb25zZS1zaXplPTxzaXplPl0KCSAqIDogTGltaXQgdGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBIVE1MIHdoZW4gdXNpbmcgZGlzY292ZXJ5LiBEZWZhdWx0IDE1MCBLQiAodGhlIHN0YW5kYXJkIFdvcmRQcmVzcyBsaW1pdCkuIE5vdCBjb21wYXRpYmxlIHdpdGggJ25vLWRpc2NvdmVyJy4KCSAqCgkgKiBbLS1yYXddCgkgKiA6IFJldHVybiB0aGUgcmF3IG9FbWJlZCByZXNwb25zZSBpbnN0ZWFkIG9mIHRoZSByZXN1bHRpbmcgSFRNTC4gSWdub3JlcyB0aGUgY2FjaGUgYW5kIGRvZXMgbm90IHNhbml0aXplIHJlc3BvbnNlcyBvciB1c2UgcmVnaXN0ZXJlZCBlbWJlZCBoYW5kbGVycy4KCSAqCgkgKiBbLS1yYXctZm9ybWF0PTxqc29ufHhtbD5dCgkgKiA6IFJlbmRlciByYXcgb0VtYmVkIGRhdGEgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4gRGVmYXVsdHMgdG8ganNvbi4gQ2FuIG9ubHkgYmUgc3BlY2lmaWVkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlICdyYXcnIG9wdGlvbi4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBqc29uCgkgKiAgIC0geG1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBlbWJlZCBIVE1MIGZvciBhIGdpdmVuIFVSTC4KCSAqICAgICAkIHdwIGVtYmVkIGZldGNoIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EKCSAqICAgICA8aWZyYW1lIHdpZHRoPSI1MjUiIGhlaWdodD0iMjk1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL2RRdzR3OVdnWGNRP2ZlYXR1cmU9b2VtYmVkIiAuLi4KCSAqCgkgKiAgICAgIyBHZXQgcmF3IG9FbWJlZCBkYXRhIGZvciBhIGdpdmVuIFVSTC4KCSAqICAgICAkIHdwIGVtYmVkIGZldGNoIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EgLS1yYXcKCSAqICAgICB7ImF1dGhvcl91cmwiOiJodHRwczpcL1wvd3d3LnlvdXR1YmUuY29tXC91c2VyXC9SaWNrQXN0bGV5VkVWTyIsIndpZHRoIjo1MjUsInZlcnNpb24iOiIxLjAiLCAuLi4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJLyoqIEB2YXIgXFdQX0VtYmVkICR3cF9lbWJlZCAqLwoJCWdsb2JhbCAkd3BfZW1iZWQ7CgoJCSR1cmwgICAgICAgICAgICAgICAgID0gJGFyZ3NbMF07CgkJJHJhdyAgICAgICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyYXcnICk7CgkJJHJhd19mb3JtYXQgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyYXctZm9ybWF0JyApOwoJCSRwb3N0X2lkICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncG9zdC1pZCcgKTsKCQkkZGlzY292ZXIgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc2NvdmVyJyApOwoJCSRyZXNwb25zZV9zaXplX2xpbWl0ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbGltaXQtcmVzcG9uc2Utc2l6ZScgKTsKCQkkd2lkdGggICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3dpZHRoJyApOwoJCSRoZWlnaHQgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaGVpZ2h0JyApOwoKCQkvLyBUaGUgYCRrZXlfc3VmZml4YCB1c2VkIGZvciBjYWNoaW5nIGlzIHBhcnQgYmFzZWQgb24gc2VyaWFsaXppbmcgdGhlIGF0dHJpYnV0ZXMgYXJyYXkgd2l0aG91dCBub3JtYWxpemluZyBpdCBmaXJzdCBzbyBuZWVkIHRvIHRyeSB0byByZXBsaWNhdGUgdGhhdC4KCQkkb2VtYmVkX2FyZ3MgPSBhcnJheSgpOwoKCQlpZiAoIG51bGwgIT09ICR3aWR0aCApIHsKCQkJJG9lbWJlZF9hcmdzWyd3aWR0aCddID0gJHdpZHRoOyAvLyBLZWVwIGFzIHN0cmluZyBhcyBpZiBmcm9tIGEgc2hvcnRjb2RlIGF0dHJpYnV0ZS4KCQl9CgkJaWYgKCBudWxsICE9PSAkaGVpZ2h0ICkgewoJCQkkb2VtYmVkX2FyZ3NbJ2hlaWdodCddID0gJGhlaWdodDsgLy8gS2VlcCBhcyBzdHJpbmcgYXMgaWYgZnJvbSBhIHNob3J0Y29kZSBhdHRyaWJ1dGUuCgkJfQoJCWlmICggbnVsbCAhPT0gJGRpc2NvdmVyICkgewoJCQkkb2VtYmVkX2FyZ3NbJ2Rpc2NvdmVyJ10gPSAkZGlzY292ZXIgPyAnMScgOiAnMCc7IC8vIE1ha2UgaXQgYSBzdHJpbmcgYXMgaWYgZnJvbSBhIHNob3J0Y29kZSBhdHRyaWJ1dGUuCgkJfQoKCQkkZGlzY292ZXIgPSBudWxsID09PSAkZGlzY292ZXIgPyB0cnVlIDogKGJvb2wpICRkaXNjb3ZlcjsgLy8gV2lsbCB1c2UgdG8gc2V0IGAkb2VtYmVkX2FyZ3NbJ2Rpc2NvdmVyJ11gIHdoZW4gbm90IGNhbGxpbmcgYFdQX0VtYmVkOjpzaG9ydGNvZGUoKWAuCgoJCWlmICggISAkZGlzY292ZXIgJiYgbnVsbCAhPT0gJHJlc3BvbnNlX3NpemVfbGltaXQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgJ2xpbWl0LXJlc3BvbnNlLXNpemUnIG9wdGlvbiBjYW4gb25seSBiZSB1c2VkIHdpdGggZGlzY292ZXJ5LiIgKTsKCQl9CgoJCWlmICggISAkcmF3ICYmIG51bGwgIT09ICRyYXdfZm9ybWF0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlICdyYXctZm9ybWF0JyBvcHRpb24gY2FuIG9ubHkgYmUgdXNlZCB3aXRoIHRoZSAncmF3JyBvcHRpb24uIiApOwoJCX0KCgkJaWYgKCAkcmVzcG9uc2Vfc2l6ZV9saW1pdCApIHsKCQkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjAnLCAnPCcgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlRoZSAnbGltaXQtcmVzcG9uc2Utc2l6ZScgb3B0aW9uIG9ubHkgd29ya3MgZm9yIFdvcmRQcmVzcyA0LjAgb253YXJkcy4iICk7CgkJCQkvLyBGYWxsIHRocm91Z2ggYW55d2F5Li4uCgkJCX0KCQkJYWRkX2ZpbHRlcigKCQkJCSdvZW1iZWRfcmVtb3RlX2dldF9hcmdzJywKCQkJCWZ1bmN0aW9uICggJGFyZ3MgKSB1c2UgKCAkcmVzcG9uc2Vfc2l6ZV9saW1pdCApIHsKCQkJCQkkYXJnc1snbGltaXRfcmVzcG9uc2Vfc2l6ZSddID0gJHJlc3BvbnNlX3NpemVfbGltaXQ7CgoJCQkJCXJldHVybiAkYXJnczsKCQkJCX0sCgkJCQlQSFBfSU5UX01BWAoJCQkpOwoJCX0KCgkJLy8gSWYgcmF3LCBxdWVyeSBwcm92aWRlcnMgZGlyZWN0bHksIGJ5LXBhc3NpbmcgY2FjaGUuCgkJaWYgKCAkcmF3ICkgewoJCQkkb2VtYmVkID0gbmV3IG9FbWJlZCgpOyAvLyBOZWVkcyB0byBiZSBoZXJlIHRvIG1ha2Ugc3VyZSBgX3dwX29lbWJlZF9nZXRfb2JqZWN0KClgIGRlZmluZWQgKGluICJ3cC1pbmNsdWRlcy9jbGFzcy1vZW1iZWQucGhwIiBmb3IgV1AgPCA0LjcpLgoKCQkJJG9lbWJlZF9hcmdzWydkaXNjb3ZlciddID0gJGRpc2NvdmVyOwoKCQkJLy8gTWFrZSAnb2VtYmVkX2RhdGFwYXJzZScgZmlsdGVyIGEgbm8tb3Agc28gZ2V0IHJhdyB1bnNhbml0aXplZCBkYXRhLgoJCQlyZW1vdmVfYWxsX2ZpbHRlcnMoICdvZW1iZWRfZGF0YXBhcnNlJyApOyAvLyBTYXZlIGEgZmV3IGN5Y2xlcy4KCQkJYWRkX2ZpbHRlcigKCQkJCSdvZW1iZWRfZGF0YXBhcnNlJywKCQkJCWZ1bmN0aW9uICggJHJldHVybiwgJGRhdGEsICR1cmwgKSB7CgkJCQkJcmV0dXJuICRkYXRhOwoJCQkJfSwKCQkJCVBIUF9JTlRfTUFYLAoJCQkJMwoJCQkpOwoKCQkJLy8gQWxsb3cgYHdwX2ZpbHRlcl9wcmVfb2VtYmVkX3Jlc3VsdCgpYCB0byBwcm92aWRlIGxvY2FsIFVSTHMgKFdQID49IDQuNS4zKS4KCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBVc2luZyBXUCBDb3JlIGhvb2suCgkJCSRkYXRhID0gYXBwbHlfZmlsdGVycyggJ3ByZV9vZW1iZWRfcmVzdWx0JywgbnVsbCwgJHVybCwgJG9lbWJlZF9hcmdzICk7CgoJCQlpZiAoIG51bGwgPT09ICRkYXRhICkgewoJCQkJJHByb3ZpZGVyID0gJG9lbWJlZC0+Z2V0X3Byb3ZpZGVyKCAkdXJsLCAkb2VtYmVkX2FyZ3MgKTsKCgkJCQlpZiAoICEgJHByb3ZpZGVyICkgewoJCQkJCWlmICggISAkZGlzY292ZXIgKSB7CgkJCQkJCVdQX0NMSTo6ZXJyb3IoICdObyBvRW1iZWQgcHJvdmlkZXIgZm91bmQgZm9yIGdpdmVuIFVSTC4gTWF5YmUgdHJ5IGRpc2NvdmVyeT8nICk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJV1BfQ0xJOjplcnJvciggJ05vIG9FbWJlZCBwcm92aWRlciBmb3VuZCBmb3IgZ2l2ZW4gVVJMLicgKTsKCQkJCQl9CgkJCQl9CgoJCQkJJGRhdGEgPSAkb2VtYmVkLT5mZXRjaCggJHByb3ZpZGVyLCAkdXJsLCAkb2VtYmVkX2FyZ3MgKTsKCQkJfQoKCQkJaWYgKCBmYWxzZSA9PT0gJGRhdGEgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVGhlcmUgd2FzIGFuIGVycm9yIGZldGNoaW5nIHRoZSBvRW1iZWQgZGF0YS4nICk7CgkJCX0KCgkJCWlmICggJ3htbCcgPT09ICRyYXdfZm9ybWF0ICkgewoJCQkJaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1NpbXBsZVhNTEVsZW1lbnQnICkgKSB7CgkJCQkJV1BfQ0xJOjplcnJvciggIlRoZSBQSFAgZXh0ZW5zaW9uICdTaW1wbGVYTUxFbGVtZW50JyBpcyBub3QgYXZhaWxhYmxlIGJ1dCBpcyByZXF1aXJlZCBmb3IgWE1MLWZvcm1hdHRlZCBvdXRwdXQuIiApOwoJCQkJfQoJCQkJV1BfQ0xJOjpsb2coICR0aGlzLT5vZW1iZWRfY3JlYXRlX3htbCggKGFycmF5KSAkZGF0YSApICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZygganNvbl9lbmNvZGUoICRkYXRhICkgKTsKCQkJfQoKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAkcG9zdF9pZCApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZS5Qcm9oaWJpdGVkIC0tIHRoZSByZXF1ZXN0IGlzIGFza2luZyBmb3IgYSBwb3N0IGlkIGRpcmVjdGx5IHNvIG5lZWQgdG8gb3ZlcnJpZGUgdGhlIGdsb2JhbC4KCQkJJEdMT0JBTFNbJ3Bvc3QnXSA9IGdldF9wb3N0KCAkcG9zdF9pZCApOwoJCQlpZiAoIG51bGwgPT09ICRHTE9CQUxTWydwb3N0J10gKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJQb3N0IGlkICclcycgbm90IGZvdW5kLiIsICRwb3N0X2lkICkgKTsKCQkJfQoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXNhbml0aXphdGlvbicgKSApIHsKCQkJcmVtb3ZlX2ZpbHRlciggJ29lbWJlZF9kYXRhcGFyc2UnLCAnd3BfZmlsdGVyX29lbWJlZF9yZXN1bHQnLCAxMCwgMyApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWNhY2hlJyApICkgewoJCQkkd3BfZW1iZWQtPnVzZWNhY2hlID0gZmFsc2U7CgkJCS8vIEluIG9yZGVyIHRvIHNraXAgY2FjaGluZywgYWxzbyBuZWVkIGAkY2FjaGVkX3JlY2VudGx5YCB0byBiZSBmYWxzZSBpbiBgV1BfRW1iZWQ6OnNob3J0Y29kZSgpYCwgc28gc2V0IFRUTCB0byB6ZXJvLgoJCQlhZGRfZmlsdGVyKCAnb2VtYmVkX3R0bCcsICdfX3JldHVybl96ZXJvJywgUEhQX0lOVF9NQVggKTsKCQl9IGVsc2UgewoJCQkkd3BfZW1iZWQtPnVzZWNhY2hlID0gdHJ1ZTsKCQl9CgoJCS8vIGBXUF9FbWJlZDo6c2hvcnRjb2RlKClgIHNldHMgdGhlICdkaXNjb3ZlcicgYXR0cmlidXRlIGJhc2VkIG9uICdlbWJlZF9vZW1iZWRfZGlzY292ZXInIGZpbHRlciwgbm8gbWF0dGVyIHdoYXQncyBwYXNzZWQgdG8gaXQuCgkJYWRkX2ZpbHRlciggJ2VtYmVkX29lbWJlZF9kaXNjb3ZlcicsICRkaXNjb3ZlciA/ICdfX3JldHVybl90cnVlJyA6ICdfX3JldHVybl9mYWxzZScsIFBIUF9JTlRfTUFYICk7CgoJCS8vIEZvciBXUCA8IDQuOSwgYFdQX0VtYmVkOjpzaG9ydGNvZGUoKWAgd29uJ3QgY2hlY2sgcHJvdmlkZXJzIGlmIG5vIHBvc3RfaWQgc3VwcGxpZWQsIHNvIHNldCBgbWF5YmVfbWFrZV9saW5rKClgIHRvIHJldHVybiBmYWxzZSBzbyBjYW4gY2hlY2sgYW5kIGRvIGl0IG91cnNlbHZlcy4KCQkvLyBBbHNvIHNldCBpZiBXUCA8IDQuNCBhbmQgZG9uJ3QgaGF2ZSAndW5maWx0ZXJlZF9odG1sJyBwcml2aWxlZ2VzIG9uIHBvc3QuCgkJJGNoZWNrX3Byb3ZpZGVycyA9IFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuOScsICc8JyApICYmICggISAkcG9zdF9pZCB8fCAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuNCcsICc8JyApICYmICEgYXV0aG9yX2NhbiggJHBvc3RfaWQsICd1bmZpbHRlcmVkX2h0bWwnICkgKSApOwoJCWlmICggJGNoZWNrX3Byb3ZpZGVycyApIHsKCQkJYWRkX2ZpbHRlciggJ2VtYmVkX21heWJlX21ha2VfbGluaycsICdfX3JldHVybl9mYWxzZScsIFBIUF9JTlRfTUFYICk7CgkJfQoKCQkkaHRtbCA9ICR3cF9lbWJlZC0+c2hvcnRjb2RlKCAkb2VtYmVkX2FyZ3MsICR1cmwgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJGh0bWwgJiYgJGNoZWNrX3Byb3ZpZGVycyApIHsKCgkJCS8vIENoZWNrIHByb3ZpZGVycy4KCQkJJG9lbWJlZF9hcmdzWydkaXNjb3ZlciddID0gJGRpc2NvdmVyOwoJCQkkaHRtbCAgICAgICAgICAgICAgICAgICAgPSB3cF9vZW1iZWRfZ2V0KCAkdXJsLCAkb2VtYmVkX2FyZ3MgKTsKCgkJCS8vIGB3cF9vZW1iZWRfZ2V0KClgIHJldHVybnMgemVyby1sZW5ndGggc3RyaW5nIGluc3RlYWQgb2YgZmFsc2Ugb24gZmFpbHVyZSBkdWUgdG8gYF9zdHJpcF9uZXdsaW5lcygpYCAnb2VtYmVkX2RhdGFwYXJzZScgZmlsdGVyIHNvIG1ha2Ugc3VyZSBmYWxzZS4KCQkJaWYgKCAnJyA9PT0gJGh0bWwgKSB7CgkJCQkkaHRtbCA9IGZhbHNlOwoJCQl9CgkJfQoKCQlpZiAoIGZhbHNlICE9PSAkaHRtbCAmJiAnWycgPT09IHN1YnN0ciggJGh0bWwsIDAsIDEgKSAmJiBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkby1zaG9ydGNvZGUnICkgKSB7CgkJCSRodG1sID0gZG9fc2hvcnRjb2RlKCAkaHRtbCwgdHJ1ZSApOwoJCX0KCgkJaWYgKCBmYWxzZSA9PT0gJGh0bWwgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGVyZSB3YXMgYW4gZXJyb3IgZmV0Y2hpbmcgdGhlIG9FbWJlZCBkYXRhLicgKTsKCQl9CgoJCVdQX0NMSTo6bG9nKCAkaHRtbCApOwoJfQoKCS8qKgoJICogQ3JlYXRlcyBhbiBYTUwgc3RyaW5nIGZyb20gYSBnaXZlbiBhcnJheS4KCSAqCgkgKiBTYW1lIGFzIGBcX29lbWJlZF9jcmVhdGVfeG1sKClgIGluICJ3cC1pbmNsdWRlc1xlbWJlZC5waHAiIGludHJvZHVjZWQgaW4gV1AgNC40LjAuIFBvbHlmaWxsZWQgYXMgbWFya2VkIHByaXZhdGUgKGFuZCBhbHNvIHRvIGNhdGVyIGZvciBvbGRlciBXUCB2ZXJzaW9ucykuCgkgKgoJICogQHNlZSBfb2VtYmVkX2NyZWF0ZV94bWwoKQoJICoKCSAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICRkYXRhIFRoZSBvcmlnaW5hbCBvRW1iZWQgcmVzcG9uc2UgZGF0YS4KCSAqIEBwYXJhbSBcU2ltcGxlWE1MRWxlbWVudCAkbm9kZSBPcHRpb25hbC4gWE1MIG5vZGUgdG8gYXBwZW5kIHRoZSByZXN1bHQgdG8gcmVjdXJzaXZlbHkuCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBYTUwgc3RyaW5nIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGVycm9yLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gb2VtYmVkX2NyZWF0ZV94bWwoICRkYXRhLCAkbm9kZSA9IG51bGwgKSB7CgkJaWYgKCAhIGlzX2FycmF5KCAkZGF0YSApIHx8IGVtcHR5KCAkZGF0YSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoIG51bGwgPT09ICRub2RlICkgewoJCQkkbm9kZSA9IG5ldyBcU2ltcGxlWE1MRWxlbWVudCggJzxvZW1iZWQ+PC9vZW1iZWQ+JyApOwoJCX0KCgkJZm9yZWFjaCAoICRkYXRhIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQlpZiAoIGlzX251bWVyaWMoICRrZXkgKSApIHsKCQkJCSRrZXkgPSAnb2VtYmVkJzsKCQkJfQoKCQkJaWYgKCBpc19hcnJheSggJHZhbHVlICkgKSB7CgkJCQkkaXRlbSA9ICRub2RlLT5hZGRDaGlsZCggJGtleSApOwoJCQkJJHRoaXMtPm9lbWJlZF9jcmVhdGVfeG1sKCAkdmFsdWUsICRpdGVtICk7CgkJCX0gZWxzZSB7CgkJCQkkbm9kZS0+YWRkQ2hpbGQoICRrZXksIGVzY19odG1sKCAkdmFsdWUgKSApOwoJCQl9CgkJfQoKCQlyZXR1cm4gJG5vZGUtPmFzWE1MKCk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRW1iZWRzOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxQcm9jZXNzOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSV9Db21tYW5kOwoKLyoqCiAqIEZpbmRzLCB0cmlnZ2VycywgYW5kIGRlbGV0ZXMgb0VtYmVkIGNhY2hlcy4KICovCmNsYXNzIENhY2hlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBEZWxldGVzIGFsbCBvRW1iZWQgY2FjaGVzIGZvciBhIGdpdmVuIHBvc3QuCgkgKgoJICogb0VtYmVkIGNhY2hlcyBmb3IgYSBwb3N0IGFyZSBzdG9yZWQgaW4gdGhlIHBvc3QncyBtZXRhZGF0YS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBvc3RfaWQ+CgkgKiA6IElEIG9mIHRoZSBwb3N0IHRvIGNsZWFyIHRoZSBjYWNoZSBmb3IuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDbGVhciBjYWNoZSBmb3IgYSBwb3N0CgkgKiAgICAgJCB3cCBlbWJlZCBjYWNoZSBjbGVhciAxMjMKCSAqICAgICBTdWNjZXNzOiBDbGVhcmVkIG9FbWJlZCBjYWNoZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNsZWFyKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJLyoqIEB2YXIgXFdQX0VtYmVkICR3cF9lbWJlZCAqLwoJCWdsb2JhbCAkd3BfZW1iZWQ7CgoJCSRwb3N0X2lkID0gJGFyZ3NbMF07CgoJCSRwb3N0X21ldGFzID0gZ2V0X3Bvc3RfY3VzdG9tX2tleXMoICRwb3N0X2lkICk7CgoJCWlmICggJHBvc3RfbWV0YXMgKSB7CgkJCSRwb3N0X21ldGFzID0gYXJyYXlfZmlsdGVyKAoJCQkJJHBvc3RfbWV0YXMsCgkJCQlmdW5jdGlvbiAoICR2ICkgewoJCQkJCXJldHVybiAnX29lbWJlZF8nID09PSBzdWJzdHIoICR2LCAwLCA4ICk7CgkJCQl9CgkJCSk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkcG9zdF9tZXRhcyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gY2FjaGUgdG8gY2xlYXIhJyApOwoJCX0KCgkJJHdwX2VtYmVkLT5kZWxldGVfb2VtYmVkX2NhY2hlcyggJHBvc3RfaWQgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAnQ2xlYXJlZCBvRW1iZWQgY2FjaGUuJyApOwoJfQoKCS8qKgoJICogRmluZHMgYW4gb0VtYmVkIGNhY2hlIHBvc3QgSUQgZm9yIGEgZ2l2ZW4gVVJMLgoJICoKCSAqIFN0YXJ0aW5nIHdpdGggV29yZFByZXNzIDQuOSwgZW1iZWRzIHRoYXQgYXJlbid0IGFzc29jaWF0ZWQgd2l0aCBhIHNwZWNpZmljIHBvc3Qgd2lsbCBiZSBjYWNoZWQgaW4KCSAqIGEgbmV3IG9lbWJlZF9jYWNoZSBwb3N0IHR5cGUuIFRoZXJlIGNhbiBiZSBtb3JlIHRoYW4gb25lIHN1Y2ggZW50cnkgZm9yIGEgdXJsIGRlcGVuZGluZyBvbiBhdHRyaWJ1dGVzIGFuZCBjb250ZXh0LgoJICoKCSAqIE5vdCB0byBiZSBjb25mdXNlZCB3aXRoIG9FbWJlZCBjYWNoZXMgZm9yIGEgZ2l2ZW4gcG9zdCB3aGljaCBhcmUgc3RvcmVkIGluIHRoZSBwb3N0J3MgbWV0YWRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1cmw+CgkgKiA6IFVSTCB0byByZXRyaWV2ZSBvRW1iZWQgZGF0YSBmb3IuCgkgKgoJICogWy0td2lkdGg9PHdpZHRoPl0KCSAqIDogV2lkdGggb2YgdGhlIGVtYmVkIGluIHBpeGVscy4gUGFydCBvZiBjYWNoZSBrZXkgc28gbXVzdCBtYXRjaC4gRGVmYXVsdHMgdG8gYGNvbnRlbnRfd2lkdGhgIGlmIHNldCBlbHNlIDUwMHB4LCBzbyBpcyB0aGVtZSBhbmQgY29udGV4dCBkZXBlbmRlbnQuCgkgKgoJICogWy0taGVpZ2h0PTxoZWlnaHQ+XQoJICogOiBIZWlnaHQgb2YgdGhlIGVtYmVkIGluIHBpeGVscy4gUGFydCBvZiBjYWNoZSBrZXkgc28gbXVzdCBtYXRjaC4gRGVmYXVsdHMgdG8gMS41ICogZGVmYXVsdCB3aWR0aCAoYGNvbnRlbnRfd2lkdGhgIG9yIDUwMHB4KSwgdG8gYSBtYXhpbXVtIG9mIDEwMDBweC4KCSAqCgkgKiBbLS1kaXNjb3Zlcl0KCSAqIDogV2hldGhlciB0byBzZWFyY2ggd2l0aCB0aGUgZGlzY292ZXIgYXR0cmlidXRlIHNldCBvciBub3QuIFBhcnQgb2YgY2FjaGUga2V5IHNvIG11c3QgbWF0Y2guIElmIG5vdCBnaXZlbiwgd2lsbCBzZWFyY2ggd2l0aCBhdHRyaWJ1dGU6IHVuc2V0LCAnMScsICcwJywgcmV0dXJuaW5nIGZpcnN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRmluZCBjYWNoZSBwb3N0IElEIGZvciBhIGdpdmVuIFVSTC4KCSAqICAgICAkIHdwIGVtYmVkIGNhY2hlIGZpbmQgaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUSAtLXdpZHRoPTUwMAoJICogICAgIDEyMwoJICovCglwdWJsaWMgZnVuY3Rpb24gZmluZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC45JywgJzwnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdSZXF1aXJlcyBXb3JkUHJlc3MgNC45IG9yIGdyZWF0ZXIuJyApOwoJCX0KCgkJLyoqIEB2YXIgXFdQX0VtYmVkICR3cF9lbWJlZCAqLwoJCWdsb2JhbCAkd3BfZW1iZWQ7CgoJCSR1cmwgICAgICA9ICRhcmdzWzBdOwoJCSR3aWR0aCAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3dpZHRoJyApOwoJCSRoZWlnaHQgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2hlaWdodCcgKTsKCQkkZGlzY292ZXIgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXNjb3ZlcicgKTsKCgkJLy8gVGhlIGAka2V5X3N1ZmZpeGAgdXNlZCBmb3IgY2FjaGluZyBpcyBwYXJ0IGJhc2VkIG9uIHNlcmlhbGl6aW5nIHRoZSBhdHRyaWJ1dGVzIGFycmF5IHdpdGhvdXQgbm9ybWFsaXppbmcgaXQgZmlyc3Qgc28gbmVlZCB0byB0cnkgdG8gcmVwbGljYXRlIHRoYXQuCgkJJG9lbWJlZF9hcmdzID0gYXJyYXkoKTsKCgkJaWYgKCBudWxsICE9PSAkd2lkdGggKSB7CgkJCSRvZW1iZWRfYXJnc1snd2lkdGgnXSA9ICR3aWR0aDsgLy8gS2VlcCBhcyBzdHJpbmcgYXMgaWYgZnJvbSBhIHNob3J0Y29kZSBhdHRyaWJ1dGUuCgkJfQoJCWlmICggbnVsbCAhPT0gJGhlaWdodCApIHsKCQkJJG9lbWJlZF9hcmdzWydoZWlnaHQnXSA9ICRoZWlnaHQ7IC8vIEtlZXAgYXMgc3RyaW5nIGFzIGlmIGZyb20gYSBzaG9ydGNvZGUgYXR0cmlidXRlLgoJCX0KCQlpZiAoIG51bGwgIT09ICRkaXNjb3ZlciApIHsKCQkJJGRpc2NvdmVycyA9IGFycmF5KCAoICRkaXNjb3ZlciApID8gJzEnIDogJzAnICk7CgkJfSBlbHNlIHsKCQkJJGRpc2NvdmVycyA9IGFycmF5KCBudWxsLCAnMScsICcwJyApOwoJCX0KCgkJJGF0dHIgPSB3cF9wYXJzZV9hcmdzKCAkb2VtYmVkX2FyZ3MsIHdwX2VtYmVkX2RlZmF1bHRzKCAkdXJsICkgKTsKCgkJZm9yZWFjaCAoICRkaXNjb3ZlcnMgYXMgJGRpc2NvdmVyICkgewoJCQlpZiAoIG51bGwgIT09ICRkaXNjb3ZlciApIHsKCQkJCSRhdHRyWydkaXNjb3ZlciddID0gJGRpc2NvdmVyOwoJCQl9CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuUEhQLkRpc2NvdXJhZ2VkUEhQRnVuY3Rpb25zLnNlcmlhbGl6ZV9zZXJpYWxpemUgLS0gbmVlZGVkIHRvIG1pbWljIFdQIENvcmUgYmVoYXZpb3IuIFNlZTogXFdQX0VtYmVkOjpzaG9ydGNvZGUuCgkJCSRrZXlfc3VmZml4ID0gbWQ1KCAkdXJsIC4gc2VyaWFsaXplKCAkYXR0ciApICk7CgoJCQkkY2FjaGVkX3Bvc3RfaWQgPSAkd3BfZW1iZWQtPmZpbmRfb2VtYmVkX3Bvc3RfaWQoICRrZXlfc3VmZml4ICk7CgoJCQlpZiAoICRjYWNoZWRfcG9zdF9pZCApIHsKCQkJCVdQX0NMSTo6bGluZSggJGNhY2hlZF9wb3N0X2lkICk7CgoJCQkJcmV0dXJuOwoJCQl9CgkJfQoKCQlXUF9DTEk6OmVycm9yKCAnTm8gY2FjaGUgcG9zdCBJRCBmb3VuZCEnICk7Cgl9CgoJLyoqCgkgKiBUcmlnZ2VycyB0aGUgY2FjaGluZyBvZiBhbGwgb0VtYmVkIHJlc3VsdHMgZm9yIGEgZ2l2ZW4gcG9zdC4KCSAqCgkgKiBvRW1iZWQgY2FjaGVzIGZvciBhIHBvc3QgYXJlIHN0b3JlZCBpbiB0aGUgcG9zdCdzIG1ldGFkYXRhLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cG9zdF9pZD4KCSAqIDogSUQgb2YgdGhlIHBvc3QgdG8gZG8gdGhlIGNhY2hpbmcgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVHJpZ2dlcnMgY2FjaGUgZm9yIGEgcG9zdAoJICogICAgICQgd3AgZW1iZWQgY2FjaGUgdHJpZ2dlciA0NTYKCSAqICAgICBTdWNjZXNzOiBDYWNoaW5nIHRyaWdnZXJlZCEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRyaWdnZXIoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkvKiogQHZhciBcV1BfRW1iZWQgJHdwX2VtYmVkICovCgkJZ2xvYmFsICR3cF9lbWJlZDsKCgkJJHBvc3RfaWQgICAgPSAkYXJnc1swXTsKCQkkcG9zdCAgICAgICA9IGdldF9wb3N0KCAkcG9zdF9pZCApOwoJCSRwb3N0X3R5cGVzID0gZ2V0X3Bvc3RfdHlwZXMoIGFycmF5KCAnc2hvd191aScgPT4gdHJ1ZSApICk7CgoJCWlmICggZW1wdHkoICRwb3N0LT5JRCApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJQb3N0IGlkICclcycgbm90IGZvdW5kLiIsICRwb3N0X2lkICkgKTsKCgkJCXJldHVybjsKCQl9CgoJCS8qKiBUaGlzIGZpbHRlciBpcyBkb2N1bWVudGVkIGluIHdwLWluY2x1ZGVzL2NsYXNzLXdwLWVtYmVkLnBocCAqLwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gVXNpbmcgV1AgQ29yZSBob29rLgoJCWlmICggISBpbl9hcnJheSggJHBvc3QtPnBvc3RfdHlwZSwgYXBwbHlfZmlsdGVycyggJ2VtYmVkX2NhY2hlX29lbWJlZF90eXBlcycsICRwb3N0X3R5cGVzICksIHRydWUgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiQ2Fubm90IGNhY2hlIG9FbWJlZCByZXN1bHRzIGZvciAnJXMnIHBvc3QgdHlwZSIsICRwb3N0LT5wb3N0X3R5cGUgKSApOwoKCQkJcmV0dXJuOwoJCX0KCgkJJHdwX2VtYmVkLT5jYWNoZV9vZW1iZWQoICRwb3N0X2lkICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0NhY2hpbmcgdHJpZ2dlcmVkIScgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxFbWJlZHM7Cgp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZTsKCi8qKgogKiBJbnNwZWN0cyBvRW1iZWQgcHJvdmlkZXJzLCBjbGVhcnMgZW1iZWQgY2FjaGUsIGFuZCBtb3JlLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIEVtYmVkc19OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxFbWJlZHM7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSV9Db21tYW5kOwoKLyoqCiAqIFJldHJpZXZlcyBlbWJlZCBoYW5kbGVycy4KICovCmNsYXNzIEhhbmRsZXJfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCXByb3RlY3RlZCAkZGVmYXVsdF9maWVsZHMgPSBhcnJheSgKCQknaWQnLAoJCSdyZWdleCcsCgkpOwoKCS8qKgoJICogTGlzdHMgYWxsIGF2YWlsYWJsZSBlbWJlZCBoYW5kbGVycy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogRGlzcGxheSB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQKCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBoYW5kbGVyOgoJICoKCSAqICogaWQKCSAqICogcmVnZXgKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogY2FsbGJhY2sKCSAqICogcHJpb3JpdHkKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgaWQscmVnZXgscHJpb3JpdHkgZmllbGRzIG9mIGF2YWlsYWJsZSBoYW5kbGVycy4KCSAqICAgICAkIHdwIGVtYmVkIGhhbmRsZXIgbGlzdCAtLWZpZWxkcz1wcmlvcml0eSxpZAoJICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBwcmlvcml0eSB8IGlkICAgICAgICAgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMTAgICAgICAgfCB5b3V0dWJlX2VtYmVkX3VybCB8CgkgKiAgICAgfCA5OTk5ICAgICB8IGF1ZGlvICAgICAgICAgICAgIHwKCSAqICAgICB8IDk5OTkgICAgIHwgdmlkZW8gICAgICAgICAgICAgfAoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfaGFuZGxlcnMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkvKiogQHZhciBcV1BfRW1iZWQgJHdwX2VtYmVkICovCgkJZ2xvYmFsICR3cF9lbWJlZDsKCgkJJGFsbF9oYW5kbGVycyA9IGFycmF5KCk7CgoJCWtzb3J0KCAkd3BfZW1iZWQtPmhhbmRsZXJzICk7CgkJZm9yZWFjaCAoICR3cF9lbWJlZC0+aGFuZGxlcnMgYXMgJHByaW9yaXR5ID0+ICRoYW5kbGVycyApIHsKCQkJZm9yZWFjaCAoICRoYW5kbGVycyBhcyAkaWQgPT4gJGhhbmRsZXIgKSB7CgkJCQkkYWxsX2hhbmRsZXJzW10gPSBhcnJheSgKCQkJCQknaWQnICAgICAgID0+ICRpZCwKCQkJCQkncmVnZXgnICAgID0+ICRoYW5kbGVyWydyZWdleCddLAoJCQkJCSdjYWxsYmFjaycgPT4gJGhhbmRsZXJbJ2NhbGxiYWNrJ10sCgkJCQkJJ3ByaW9yaXR5JyA9PiAkcHJpb3JpdHksCgkJCQkpOwoJCQl9CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGFsbF9oYW5kbGVycyApOwoJfQoKCS8qKgoJICogR2V0IEZvcm1hdHRlciBvYmplY3QgYmFzZWQgb24gc3VwcGxpZWQgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZC4gRGV0ZXJtaW5lcyBmb3JtYXR0aW5nLgoJICogQHJldHVybiBcV1BfQ0xJXEZvcm1hdHRlcgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmRlZmF1bHRfZmllbGRzICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRW1iZWRzOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElfQ29tbWFuZDsKCi8qKgogKiBSZXRyaWV2ZXMgb0VtYmVkIHByb3ZpZGVycy4KICovCmNsYXNzIFByb3ZpZGVyX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7Cglwcm90ZWN0ZWQgJGRlZmF1bHRfZmllbGRzID0gYXJyYXkoCgkJJ2Zvcm1hdCcsCgkJJ2VuZHBvaW50JywKCSk7CgoJLyoqCgkgKiBMaXN0cyBhbGwgYXZhaWxhYmxlIG9FbWJlZCBwcm92aWRlcnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IERpc3BsYXkgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiBbLS1mb3JjZS1yZWdleF0KCSAqIDogVHVybiB0aGUgYXN0ZXJpc2stdHlwZSBwcm92aWRlciBVUkxzIGludG8gcmVnZXhlcy4KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggcHJvdmlkZXI6CgkgKgoJICogKiBmb3JtYXQKCSAqICogZW5kcG9pbnQKCSAqCgkgKiBUaGlzIGZpZWxkIGlzIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogcmVnZXgKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgZm9ybWF0LGVuZHBvaW50IGZpZWxkcyBvZiBhdmFpbGFibGUgcHJvdmlkZXJzLgoJICogICAgICQgd3AgZW1iZWQgcHJvdmlkZXIgbGlzdCAtLWZpZWxkcz1mb3JtYXQsZW5kcG9pbnQKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgZm9ybWF0ICAgICAgICAgICAgICAgICAgICAgICB8IGVuZHBvaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8ICNodHRwcz86Ly95b3V0dVwuYmUvLiojaSAgICAgfCBodHRwczovL3d3dy55b3V0dWJlLmNvbS9vZW1iZWQgICAgICAgICAgfAoJICogICAgIHwgI2h0dHBzPzovL2ZsaWNcLmtyLy4qI2kgICAgICB8IGh0dHBzOi8vd3d3LmZsaWNrci5jb20vc2VydmljZXMvb2VtYmVkLyB8CgkgKiAgICAgfCAjaHR0cHM/Oi8vd29yZHByZXNzXC50di8uKiNpIHwgaHR0cHM6Ly93b3JkcHJlc3MudHYvb2VtYmVkLyAgICAgICAgICAgIHwKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0X3Byb3ZpZGVycyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkb2VtYmVkID0gbmV3IG9FbWJlZCgpOwoKCQkkZm9yY2VfcmVnZXggPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZS1yZWdleCcgKTsKCgkJJHByb3ZpZGVycyA9IGFycmF5KCk7CgoJCWZvcmVhY2ggKCAoYXJyYXkpICRvZW1iZWQtPnByb3ZpZGVycyBhcyAkbWF0Y2htYXNrID0+ICRkYXRhICkgewoJCQlsaXN0KCAkcHJvdmlkZXJ1cmwsICRyZWdleCApID0gJGRhdGE7CgoJCQkvLyBUdXJuIHRoZSBhc3Rlcmlzay10eXBlIHByb3ZpZGVyIFVSTHMgaW50byByZWdleAoJCQlpZiAoICRmb3JjZV9yZWdleCAmJiAhICRyZWdleCApIHsKCQkJCSRtYXRjaG1hc2sgPSAnIycgLiBzdHJfcmVwbGFjZSggJ19fX3dpbGRjYXJkX19fJywgJyguKyknLCBwcmVnX3F1b3RlKCBzdHJfcmVwbGFjZSggJyonLCAnX19fd2lsZGNhcmRfX18nLCAkbWF0Y2htYXNrICksICcjJyApICkgLiAnI2knOwoJCQkJJG1hdGNobWFzayA9IHByZWdfcmVwbGFjZSggJ3xeI2h0dHBcXFw6Ly98JywgJyNodHRwcz9cOi8vJywgJG1hdGNobWFzayApOwoJCQl9CgoJCQkkcHJvdmlkZXJzW10gPSBhcnJheSgKCQkJCSdmb3JtYXQnICAgPT4gJG1hdGNobWFzaywKCQkJCSdlbmRwb2ludCcgPT4gJHByb3ZpZGVydXJsLAoJCQkJJ3JlZ2V4JyAgICA9PiAkcmVnZXggPyAnMScgOiAnMCcsCgkJCSk7CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHByb3ZpZGVycyApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgbWF0Y2hpbmcgcHJvdmlkZXIgZm9yIGEgZ2l2ZW4gVVJMLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXJsPgoJICogOiBVUkwgdG8gcmV0cmlldmUgcHJvdmlkZXIgZm9yLgoJICoKCSAqIFstLWRpc2NvdmVyXQoJICogOiBXaGV0aGVyIHRvIHVzZSBvRW1iZWQgZGlzY292ZXJ5IG9yIG5vdC4gRGVmYXVsdHMgdG8gdHJ1ZS4KCSAqCgkgKiBbLS1saW1pdC1yZXNwb25zZS1zaXplPTxzaXplPl0KCSAqIDogTGltaXQgdGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBIVE1MIHdoZW4gdXNpbmcgZGlzY292ZXJ5LiBEZWZhdWx0IDE1MCBLQiAodGhlIHN0YW5kYXJkIFdvcmRQcmVzcyBsaW1pdCkuIE5vdCBjb21wYXRpYmxlIHdpdGggJ25vLWRpc2NvdmVyJy4KCSAqCgkgKiBbLS1saW5rLXR5cGU9PGpzb258eG1sPl0KCSAqIDogV2hldGhlciB0byBhY2NlcHQgb25seSBhIGNlcnRhaW4gbGluayB0eXBlIHdoZW4gdXNpbmcgZGlzY292ZXJ5LiBEZWZhdWx0cyB0byBhbnkgKGpzb24gb3IgeG1sKSwgcHJlZmVycmluZyBqc29uLiBOb3QgY29tcGF0aWJsZSB3aXRoICduby1kaXNjb3ZlcicuCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0ganNvbgoJICogICAtIHhtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgdGhlIG1hdGNoaW5nIHByb3ZpZGVyIGZvciB0aGUgVVJMLgoJICogICAgICQgd3AgZW1iZWQgcHJvdmlkZXIgbWF0Y2ggaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQoJICogICAgIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL29lbWJlZAoJICoKCSAqIEBzdWJjb21tYW5kIG1hdGNoCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtYXRjaF9wcm92aWRlciggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRvZW1iZWQgPSBuZXcgb0VtYmVkKCk7CgoJCSR1cmwgICAgICAgICAgICAgICAgID0gJGFyZ3NbMF07CgkJJGRpc2NvdmVyICAgICAgICAgICAgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc2NvdmVyJywgdHJ1ZSApOwoJCSRyZXNwb25zZV9zaXplX2xpbWl0ID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsaW1pdC1yZXNwb25zZS1zaXplJyApOwoJCSRsaW5rX3R5cGUgICAgICAgICAgID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsaW5rLXR5cGUnICk7CgoJCWlmICggISAkZGlzY292ZXIgJiYgKCBudWxsICE9PSAkcmVzcG9uc2Vfc2l6ZV9saW1pdCB8fCBudWxsICE9PSAkbGlua190eXBlICkgKSB7CgkJCWlmICggbnVsbCAhPT0gJHJlc3BvbnNlX3NpemVfbGltaXQgJiYgbnVsbCAhPT0gJGxpbmtfdHlwZSApIHsKCQkJCSRtc2cgPSAiVGhlICdsaW1pdC1yZXNwb25zZS1zaXplJyBhbmQgJ2xpbmstdHlwZScgb3B0aW9ucyBjYW4gb25seSBiZSB1c2VkIHdpdGggZGlzY292ZXJ5LiI7CgkJCX0gZWxzZWlmICggbnVsbCAhPT0gJHJlc3BvbnNlX3NpemVfbGltaXQgKSB7CgkJCQkkbXNnID0gIlRoZSAnbGltaXQtcmVzcG9uc2Utc2l6ZScgb3B0aW9uIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCBkaXNjb3ZlcnkuIjsKCQkJfSBlbHNlIHsKCQkJCSRtc2cgPSAiVGhlICdsaW5rLXR5cGUnIG9wdGlvbiBjYW4gb25seSBiZSB1c2VkIHdpdGggZGlzY292ZXJ5LiI7CgkJCX0KCQkJV1BfQ0xJOjplcnJvciggJG1zZyApOwoJCX0KCgkJaWYgKCAkcmVzcG9uc2Vfc2l6ZV9saW1pdCApIHsKCQkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjAnLCAnPCcgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlRoZSAnbGltaXQtcmVzcG9uc2Utc2l6ZScgb3B0aW9uIG9ubHkgd29ya3MgZm9yIFdvcmRQcmVzcyA0LjAgb253YXJkcy4iICk7CgkJCQkvLyBGYWxsIHRocm91Z2ggYW55d2F5Li4uCgkJCX0KCQkJYWRkX2ZpbHRlcigKCQkJCSdvZW1iZWRfcmVtb3RlX2dldF9hcmdzJywKCQkJCWZ1bmN0aW9uICggJGFyZ3MgKSB1c2UgKCAkcmVzcG9uc2Vfc2l6ZV9saW1pdCApIHsKCQkJCQkkYXJnc1snbGltaXRfcmVzcG9uc2Vfc2l6ZSddID0gJHJlc3BvbnNlX3NpemVfbGltaXQ7CgkJCQkJcmV0dXJuICRhcmdzOwoJCQkJfQoJCQkpOwoJCX0KCgkJaWYgKCAkbGlua190eXBlICkgewoJCQkvLyBGaWx0ZXIgZGlzY292ZXJ5IHJlc3BvbnNlLgoJCQlhZGRfZmlsdGVyKAoJCQkJJ29lbWJlZF9saW5rdHlwZXMnLAoJCQkJZnVuY3Rpb24gKCAkbGlua3R5cGVzICkgdXNlICggJGxpbmtfdHlwZSApIHsKCQkJCQlmb3JlYWNoICggJGxpbmt0eXBlcyBhcyAkbWltZV90eXBlID0+ICRsaW5rdHlwZV9mb3JtYXQgKSB7CgkJCQkJCWlmICggJGxpbmtfdHlwZSAhPT0gJGxpbmt0eXBlX2Zvcm1hdCApIHsKCQkJCQkJCXVuc2V0KCAkbGlua3R5cGVzWyAkbWltZV90eXBlIF0gKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQlyZXR1cm4gJGxpbmt0eXBlczsKCQkJCX0KCQkJKTsKCQl9CgoJCSRvZW1iZWRfYXJncyA9IGFycmF5KAoJCQknZGlzY292ZXInID0+ICRkaXNjb3ZlciwKCQkpOwoKCQkkcHJvdmlkZXIgPSAkb2VtYmVkLT5nZXRfcHJvdmlkZXIoICR1cmwsICRvZW1iZWRfYXJncyApOwoKCQlpZiAoICEgJHByb3ZpZGVyICkgewoJCQlpZiAoICEgJGRpc2NvdmVyICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ05vIG9FbWJlZCBwcm92aWRlciBmb3VuZCBmb3IgZ2l2ZW4gVVJMLiBNYXliZSB0cnkgZGlzY292ZXJ5PycgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdObyBvRW1iZWQgcHJvdmlkZXIgZm91bmQgZm9yIGdpdmVuIFVSTC4nICk7CgkJCX0KCQl9CgoJCVdQX0NMSTo6bGluZSggJHByb3ZpZGVyICk7Cgl9CgoJLyoqCgkgKiBHZXQgRm9ybWF0dGVyIG9iamVjdCBiYXNlZCBvbiBzdXBwbGllZCBwYXJhbWV0ZXJzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBQYXJhbWV0ZXJzIHBhc3NlZCB0byBjb21tYW5kLiBEZXRlcm1pbmVzIGZvcm1hdHRpbmcuCgkgKiBAcmV0dXJuIFxXUF9DTElcRm9ybWF0dGVyCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZGVmYXVsdF9maWVsZHMgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxFbWJlZHM7CgppZiAoICEgY2xhc3NfZXhpc3RzKCAnXFdQX29FbWJlZCcgKSApIHsKCXJlcXVpcmVfb25jZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLW9lbWJlZC5waHAnOwp9CgovKioKICogUG9seWZpbGwgZm9yIG9sZGVyIFdQIHZlcnNpb25zLgogKi8KY2xhc3Mgb0VtYmVkIGV4dGVuZHMgXFdQX29FbWJlZCB7CgoJLyoqCgkgKiBUYWtlcyBhIFVSTCBhbmQgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBvRW1iZWQgcHJvdmlkZXIncyBVUkwsIGlmIHRoZXJlIGlzIG9uZS4KCSAqCgkgKiBAc2luY2UgNC4wLjAKCSAqCgkgKiBAc2VlIFdQX29FbWJlZDo6ZGlzY292ZXIoKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgICR1cmwgIFRoZSBVUkwgdG8gdGhlIGNvbnRlbnQuCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICAkYXJncyBPcHRpb25hbCBwcm92aWRlciBhcmd1bWVudHMuCgkgKiBAcmV0dXJuIGZhbHNlfHN0cmluZyBGYWxzZSBvbiBmYWlsdXJlLCBvdGhlcndpc2UgdGhlIG9FbWJlZCBwcm92aWRlciBVUkwuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfcHJvdmlkZXIoICR1cmwsICRhcmdzID0gJycgKSB7CgkJaWYgKCBtZXRob2RfZXhpc3RzKCAnV1Bfb0VtYmVkJywgJ2dldF9wcm92aWRlcicgKSApIHsKCQkJcmV0dXJuIHBhcmVudDo6Z2V0X3Byb3ZpZGVyKCAkdXJsLCAkYXJncyApOwoJCX0KCgkJJGFyZ3MgPSB3cF9wYXJzZV9hcmdzKCAkYXJncyApOwoKCQkkcHJvdmlkZXIgPSBmYWxzZTsKCgkJaWYgKCAhIGlzc2V0KCAkYXJnc1snZGlzY292ZXInXSApICkgewoJCQkkYXJnc1snZGlzY292ZXInXSA9IHRydWU7CgkJfQoKCQlmb3JlYWNoICggJHRoaXMtPnByb3ZpZGVycyBhcyAkbWF0Y2htYXNrID0+ICRkYXRhICkgewoJCQlsaXN0KCAkcHJvdmlkZXJ1cmwsICRyZWdleCApID0gJGRhdGE7CgoJCQkvLyBUdXJuIHRoZSBhc3Rlcmlzay10eXBlIHByb3ZpZGVyIFVSTHMgaW50byByZWdleAoJCQlpZiAoICEgJHJlZ2V4ICkgewoJCQkJJG1hdGNobWFzayA9ICcjJyAuIHN0cl9yZXBsYWNlKCAnX19fd2lsZGNhcmRfX18nLCAnKC4rKScsIHByZWdfcXVvdGUoIHN0cl9yZXBsYWNlKCAnKicsICdfX193aWxkY2FyZF9fXycsICRtYXRjaG1hc2sgKSwgJyMnICkgKSAuICcjaSc7CgkJCQkkbWF0Y2htYXNrID0gcHJlZ19yZXBsYWNlKCAnfF4jaHR0cFxcXDovL3wnLCAnI2h0dHBzP1w6Ly8nLCAkbWF0Y2htYXNrICk7CgkJCX0KCgkJCWlmICggcHJlZ19tYXRjaCggJG1hdGNobWFzaywgJHVybCApICkgewoJCQkJJHByb3ZpZGVyID0gc3RyX3JlcGxhY2UoICd7Zm9ybWF0fScsICdqc29uJywgJHByb3ZpZGVydXJsICk7IC8vIEpTT04gaXMgZWFzaWVyIHRvIGRlYWwgd2l0aCB0aGFuIFhNTAoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmICggISAkcHJvdmlkZXIgJiYgJGFyZ3NbJ2Rpc2NvdmVyJ10gKSB7CgkJCSRwcm92aWRlciA9ICR0aGlzLT5kaXNjb3ZlciggJHVybCApOwoJCX0KCgkJcmV0dXJuICRwcm92aWRlcjsKCX0KfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2VtYmVkX2F1dG9sb2FkZXIgPSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9lbWJlZF9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX2VtYmVkX2F1dG9sb2FkZXI7Cn0KCmlmICggY2xhc3NfZXhpc3RzKCAnV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZScgKSApIHsKCVdQX0NMSTo6YWRkX2NvbW1hbmQoICdlbWJlZCcsICdcV1BfQ0xJXEVtYmVkc1xFbWJlZHNfTmFtZXNwYWNlJyApOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnZW1iZWQgZmV0Y2gnLCAnXFdQX0NMSVxFbWJlZHNcRmV0Y2hfQ29tbWFuZCcgKTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdlbWJlZCBwcm92aWRlcicsICdcV1BfQ0xJXEVtYmVkc1xQcm92aWRlcl9Db21tYW5kJyApOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2VtYmVkIGhhbmRsZXInLCAnXFdQX0NMSVxFbWJlZHNcSGFuZGxlcl9Db21tYW5kJyApOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2VtYmVkIGNhY2hlJywgJ1xXUF9DTElcRW1iZWRzXENhY2hlX0NvbW1hbmQnICk7Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfY29yZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9jb3JlX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfY29yZV9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY29yZScsICdDb3JlX0NvbW1hbmQnICk7Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXENvcmU7CgovKioKICogQSBDb3JlIFVwZ3JhZGVyIGNsYXNzIHRoYXQgbGVhdmVzIHBhY2thZ2VzIGludGFjdCBieSBkZWZhdWx0LgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIE5vbkRlc3RydWN0aXZlQ29yZVVwZ3JhZGVyIGV4dGVuZHMgQ29yZVVwZ3JhZGVyIHsKCS8vIHBocGNzOmlnbm9yZSBHZW5lcmljLkNvZGVBbmFseXNpcy5Vc2VsZXNzT3ZlcnJpZGluZ01ldGhvZC5Gb3VuZCAtLSBQcm92aWRlIGRlZmF1bHQgdmFsdWUuCglwdWJsaWMgZnVuY3Rpb24gdW5wYWNrX3BhY2thZ2UoICRwYWNrYWdlLCAkZGVsZXRlX3BhY2thZ2UgPSBmYWxzZSApIHsKCQlyZXR1cm4gcGFyZW50Ojp1bnBhY2tfcGFja2FnZSggJHBhY2thZ2UsICRkZWxldGVfcGFja2FnZSApOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxDb3JlOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIFJlcXVlc3RzX1Jlc3BvbnNlOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfRXJyb3I7CnVzZSBDb3JlX1VwZ3JhZGVyIGFzIERlZmF1bHRDb3JlVXBncmFkZXI7CnVzZSBXUF9GaWxlc3lzdGVtX0Jhc2U7CgovKioKICogQSBDb3JlIFVwZ3JhZGVyIGNsYXNzIHRoYXQgY2FjaGVzIHRoZSBkb3dubG9hZCwgYW5kIHVzZXMgY2FjaGVkIGlmIGF2YWlsYWJsZS4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBDb3JlVXBncmFkZXIgZXh0ZW5kcyBEZWZhdWx0Q29yZVVwZ3JhZGVyIHsKCgkvKioKCSAqIFdoZXRoZXIgdG8gcmV0cnkgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIG9uIFRMUyBoYW5kc2hha2UgZmFpbHVyZS4KCSAqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJpdmF0ZSAkaW5zZWN1cmU7CgoJLyoqCgkgKiBDb3JlVXBncmFkZXIgY29uc3RydWN0b3IuCgkgKgoJICogQHBhcmFtIFdQX1VwZ3JhZGVyX1NraW58bnVsbCAkc2tpbgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRza2luID0gbnVsbCwgJGluc2VjdXJlID0gZmFsc2UgKSB7CgkJJHRoaXMtPmluc2VjdXJlID0gJGluc2VjdXJlOwoJCXBhcmVudDo6X19jb25zdHJ1Y3QoICRza2luICk7Cgl9CgoJLyoqCgkgKiBDYWNoZXMgdGhlIGRvd25sb2FkLCBhbmQgdXNlcyBjYWNoZWQgaWYgYXZhaWxhYmxlLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGFja2FnZSAgICAgICAgICBUaGUgVVJJIG9mIHRoZSBwYWNrYWdlLiBJZiB0aGlzIGlzIHRoZSBmdWxsIHBhdGggdG8gYW4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcgbG9jYWwgZmlsZSwgaXQgd2lsbCBiZSByZXR1cm5lZCB1bnRvdWNoZWQuCgkgKiBAcGFyYW0gYm9vbCAgICRjaGVja19zaWduYXR1cmVzIFdoZXRoZXIgdG8gdmFsaWRhdGUgZmlsZSBzaWduYXR1cmVzLiBEZWZhdWx0IGZhbHNlLgoJICogQHBhcmFtIGFycmF5ICAkaG9va19leHRyYSAgICAgICBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZmlsdGVyIGhvb2tzLiBEZWZhdWx0IGVtcHR5IGFycmF5LgoJICogQHJldHVybiBzdHJpbmd8V1BfRXJyb3IgVGhlIGZ1bGwgcGF0aCB0byB0aGUgZG93bmxvYWRlZCBwYWNrYWdlIGZpbGUsIG9yIGEgV1BfRXJyb3Igb2JqZWN0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWRfcGFja2FnZSggJHBhY2thZ2UsICRjaGVja19zaWduYXR1cmVzID0gZmFsc2UsICRob29rX2V4dHJhID0gW10gKSB7CgoJCS8qKgoJCSAqIEZpbHRlciB3aGV0aGVyIHRvIHJldHVybiB0aGUgcGFja2FnZS4KCQkgKgoJCSAqIEBzaW5jZSAzLjcuMAoJCSAqCgkJICogQHBhcmFtIGJvb2wgICAgJHJlcGx5ICAgV2hldGhlciB0byBiYWlsIHdpdGhvdXQgcmV0dXJuaW5nIHRoZSBwYWNrYWdlLiBEZWZhdWx0IGlzIGZhbHNlLgoJCSAqIEBwYXJhbSBzdHJpbmcgICRwYWNrYWdlIFRoZSBwYWNrYWdlIGZpbGUgbmFtZS4KCQkgKiBAcGFyYW0gb2JqZWN0ICAkdGhpcyAgICBUaGUgV1BfVXBncmFkZXIgaW5zdGFuY2UuCgkJICovCgkJJHJlcGx5ID0gYXBwbHlfZmlsdGVycygKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBPdmVycmlkZSBleGlzdGluZyBob29rIGZyb20gQ29yZS4KCQkJJ3VwZ3JhZGVyX3ByZV9kb3dubG9hZCcsCgkJCWZhbHNlLAoJCQkkcGFja2FnZSwKCQkJJHRoaXMsCgkJCSRob29rX2V4dHJhCgkJKTsKCQlpZiAoIGZhbHNlICE9PSAkcmVwbHkgKSB7CgkJCXJldHVybiAkcmVwbHk7CgkJfQoKCQkvLyBDaGVjayBpZiBwYWNrYWdlIGlzIGEgbG9jYWwgb3IgcmVtb3RlIGZpbGUuIEJhaWwgaWYgaXQncyBsb2NhbC4KCQlpZiAoICEgcHJlZ19tYXRjaCggJyFeKGh0dHB8aHR0cHN8ZnRwKTovLyFpJywgJHBhY2thZ2UgKSAmJiBmaWxlX2V4aXN0cyggJHBhY2thZ2UgKSApIHsKCQkJcmV0dXJuICRwYWNrYWdlOwoJCX0KCgkJaWYgKCBlbXB0eSggJHBhY2thZ2UgKSApIHsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ25vX3BhY2thZ2UnLCAkdGhpcy0+c3RyaW5nc1snbm9fcGFja2FnZSddICk7CgkJfQoKCQkkZmlsZW5hbWUgID0gcGF0aGluZm8oICRwYWNrYWdlLCBQQVRISU5GT19GSUxFTkFNRSApOwoJCSRleHRlbnNpb24gPSBwYXRoaW5mbyggJHBhY2thZ2UsIFBBVEhJTkZPX0VYVEVOU0lPTiApOwoKCQkkdGVtcCA9IFV0aWxzXGdldF90ZW1wX2RpcigpIC4gdW5pcWlkKCAnd3BfJyApIC4gIi57JGV4dGVuc2lvbn0iOwoJCXJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKAoJCQlmdW5jdGlvbiAoKSB1c2UgKCAkdGVtcCApIHsKCQkJCWlmICggZmlsZV9leGlzdHMoICR0ZW1wICkgKSB7CgkJCQkJdW5saW5rKCAkdGVtcCApOwoJCQkJfQoJCQl9CgkJKTsKCgkJJGNhY2hlICAgICAgPSBXUF9DTEk6OmdldF9jYWNoZSgpOwoJCSR1cGRhdGUgICAgID0gJEdMT0JBTFNbJ3dwY2xpX2NvcmVfdXBkYXRlX29iaiddOwoJCSRjYWNoZV9rZXkgID0gImNvcmUveyRmaWxlbmFtZX0teyR1cGRhdGUtPmxvY2FsZX0ueyRleHRlbnNpb259IjsKCQkkY2FjaGVfZmlsZSA9ICRjYWNoZS0+aGFzKCAkY2FjaGVfa2V5ICk7CgoJCWlmICggJGNhY2hlX2ZpbGUgJiYgZmFsc2UgPT09IHN0cmlwb3MoICRwYWNrYWdlLCAnaHR0cHM6Ly93b3JkcHJlc3Mub3JnL25pZ2h0bHktYnVpbGRzLycgKQoJCQkmJiBmYWxzZSA9PT0gc3RyaXBvcyggJHBhY2thZ2UsICdodHRwOi8vd29yZHByZXNzLm9yZy9uaWdodGx5LWJ1aWxkcy8nICkgKSB7CgkJCVdQX0NMSTo6bG9nKCAiVXNpbmcgY2FjaGVkIGZpbGUgJ3skY2FjaGVfZmlsZX0nLi4uIiApOwoJCQljb3B5KCAkY2FjaGVfZmlsZSwgJHRlbXAgKTsKCQkJcmV0dXJuICR0ZW1wOwoJCX0KCgkJLyoKCQkgKiBEb3dubG9hZCB0byBhIHRlbXBvcmFyeSBmaWxlIGJlY2F1c2UgcGlwaW5nIGZyb20gY1VSTCB0byB0YXIgaXMgZmxha3kKCQkgKiBvbiBNaW5HVyAoYW5kIHByb2JhYmx5IGluIG90aGVyIGVudmlyb25tZW50cyB0b28pLgoJCSAqLwoJCSRoZWFkZXJzID0gWyAnQWNjZXB0JyA9PiAnYXBwbGljYXRpb24vanNvbicgXTsKCQkkb3B0aW9ucyA9IFsKCQkJJ3RpbWVvdXQnICAgICAgID0+IDYwMCwgIC8vIDEwIG1pbnV0ZXMgb3VnaHQgdG8gYmUgZW5vdWdoIGZvciBldmVyeWJvZHkuCgkJCSdmaWxlbmFtZScgICAgICA9PiAkdGVtcCwKCQkJJ2hhbHRfb25fZXJyb3InID0+IGZhbHNlLAoJCQknaW5zZWN1cmUnICAgICAgPT4gJHRoaXMtPmluc2VjdXJlLAoJCV07CgoJCSR0aGlzLT5za2luLT5mZWVkYmFjayggJ2Rvd25sb2FkaW5nX3BhY2thZ2UnLCAkcGFja2FnZSApOwoKCQkvKiogQHZhciBSZXF1ZXN0c19SZXNwb25zZXxudWxsICRyZXEgKi8KCQl0cnkgewoJCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkcGFja2FnZSwgbnVsbCwgJGhlYWRlcnMsICRvcHRpb25zICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2Rvd25sb2FkX2ZhaWxlZCcsICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgoJCWlmICggISBpc19udWxsKCAkcmVzcG9uc2UgKSAmJiAyMDAgIT09IChpbnQpICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSB7CgkJCXJldHVybiBuZXcgV1BfRXJyb3IoICdkb3dubG9hZF9mYWlsZWQnLCAkdGhpcy0+c3RyaW5nc1snZG93bmxvYWRfZmFpbGVkJ10gKTsKCQl9CgoJCWlmICggZmFsc2UgPT09IHN0cmlwb3MoICRwYWNrYWdlLCAnaHR0cHM6Ly93b3JkcHJlc3Mub3JnL25pZ2h0bHktYnVpbGRzLycgKSApIHsKCQkJJGNhY2hlLT5pbXBvcnQoICRjYWNoZV9rZXksICR0ZW1wICk7CgkJfQoKCQlyZXR1cm4gJHRlbXA7Cgl9CgoJLyoqCgkgKiBVcGdyYWRlIFdvcmRQcmVzcyBjb3JlLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKgoJICogQGdsb2JhbCBXUF9GaWxlc3lzdGVtX0Jhc2UgJHdwX2ZpbGVzeXN0ZW0gU3ViY2xhc3MKCSAqIEBnbG9iYWwgY2FsbGFibGUgICAgICAgICAgICRfd3BfZmlsZXN5c3RlbV9kaXJlY3RfbWV0aG9kCgkgKgoJICogQHBhcmFtIG9iamVjdCAkY3VycmVudCBSZXNwb25zZSBvYmplY3QgZm9yIHdoZXRoZXIgV29yZFByZXNzIGlzIGN1cnJlbnQuCgkgKiBAcGFyYW0gYXJyYXkgICRhcmdzIHsKCSAqICAgICAgICBPcHRpb25hbC4gQXJndW1lbnRzIGZvciB1cGdyYWRpbmcgV29yZFByZXNzIGNvcmUuIERlZmF1bHQgZW1wdHkgYXJyYXkuCgkgKgoJICogICAgICAgIEB0eXBlIGJvb2wgJHByZV9jaGVja19tZDUgICAgV2hldGhlciB0byBjaGVjayB0aGUgZmlsZSBjaGVja3N1bXMgYmVmb3JlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRlbXB0aW5nIHRoZSB1cGdyYWRlLiBEZWZhdWx0IHRydWUuCgkgKiAgICAgICAgQHR5cGUgYm9vbCAkYXR0ZW1wdF9yb2xsYmFjayBXaGV0aGVyIHRvIGF0dGVtcHQgdG8gcm9sbGJhY2sgdGhlIGNoYW5jZXMgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZXJlIGlzIGEgcHJvYmxlbS4gRGVmYXVsdCBmYWxzZS4KCSAqICAgICAgICBAdHlwZSBib29sICRkb19yb2xsYmFjayAgICAgIFdoZXRoZXIgdG8gcGVyZm9ybSB0aGlzICJ1cGdyYWRlIiBhcyBhIHJvbGxiYWNrLgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCBmYWxzZS4KCSAqIH0KCSAqIEByZXR1cm4gbnVsbHxmYWxzZXxXUF9FcnJvciBGYWxzZSBvciBXUF9FcnJvciBvbiBmYWlsdXJlLCBudWxsIG9uIHN1Y2Nlc3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGdyYWRlKCAkY3VycmVudCwgJGFyZ3MgPSBbXSApIHsKCQlzZXRfZXJyb3JfaGFuZGxlciggWyBfX0NMQVNTX18sICdlcnJvcl9oYW5kbGVyJyBdLCBFX1VTRVJfV0FSTklORyB8IEVfVVNFUl9OT1RJQ0UgKTsKCgkJJHJlc3VsdCA9IHBhcmVudDo6dXBncmFkZSggJGN1cnJlbnQsICRhcmdzICk7CgoJCXJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKCQlyZXR1cm4gJHJlc3VsdDsKCX0KCgkvKioKCSAqIEVycm9yIGhhbmRsZXIgdG8gaWdub3JlIGZhaWx1cmVzIG9uIGFjY2Vzc2luZyBTU0wgImh0dHBzOi8vYXBpLndvcmRwcmVzcy5vcmcvY29yZS9jaGVja3N1bXMvMS4wLyIgaW4gYGdldF9jb3JlX2NoZWNrc3VtcygpYCB3aGljaCBzZWVtIHRvIG9jY3VyIGludGVybWl0dGVudGx5LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVycm9yX2hhbmRsZXIoICRlcnJubywgJGVycnN0ciwgJGVycmZpbGUsICRlcnJsaW5lLCAkZXJyY29udGV4dCA9IG51bGwgKSB7CgkJLy8gSWYgaWdub3JpbmcgRV9VU0VSX1dBUk5JTkcgfCBFX1VTRVJfTk9USUNFLCBkZWZhdWx0LgoJCWlmICggISAoIGVycm9yX3JlcG9ydGluZygpICYgJGVycm5vICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJLy8gSWYgbm90IGluICJ3cC1hZG1pbi9pbmNsdWRlcy91cGRhdGUucGhwIiwgZGVmYXVsdC4KCQkkdXBkYXRlX3BocCA9ICd3cC1hZG1pbi9pbmNsdWRlcy91cGRhdGUucGhwJzsKCQlpZiAoIDAgIT09IHN1YnN0cl9jb21wYXJlKCAkZXJyZmlsZSwgJHVwZGF0ZV9waHAsIC1zdHJsZW4oICR1cGRhdGVfcGhwICkgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBFbHNlIGFzc3VtZSBpdCdzIGluIGBnZXRfY29yZV9jaGVja3N1bXMoKWAgYW5kIGp1c3QgaWdub3JlIGl0LgoJCXJldHVybiB0cnVlOwoJfQp9Cjw/cGhwCgp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBhcmF0b3I7CnVzZSBXUF9DTElcRXh0cmFjdG9yOwp1c2UgV1BfQ0xJXEl0ZXJhdG9yc1xUYWJsZSBhcyBUYWJsZUl0ZXJhdG9yOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxXcE9yZ0FwaTsKCi8qKgogKiBEb3dubG9hZHMsIGluc3RhbGxzLCB1cGRhdGVzLCBhbmQgbWFuYWdlcyBhIFdvcmRQcmVzcyBpbnN0YWxsYXRpb24uCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIERvd25sb2FkIFdvcmRQcmVzcyBjb3JlCiAqICAgICAkIHdwIGNvcmUgZG93bmxvYWQgLS1sb2NhbGU9bmxfTkwKICogICAgIERvd25sb2FkaW5nIFdvcmRQcmVzcyA0LjUuMiAobmxfTkwpLi4uCiAqICAgICBtZDUgaGFzaCB2ZXJpZmllZDogYzUzNjZkMDViNTIxODMxZGQwYjI5ZGZjMzg2ZTU2YTUKICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBkb3dubG9hZGVkLgogKgogKiAgICAgIyBJbnN0YWxsIFdvcmRQcmVzcwogKiAgICAgJCB3cCBjb3JlIGluc3RhbGwgLS11cmw9ZXhhbXBsZS5jb20gLS10aXRsZT1FeGFtcGxlIC0tYWRtaW5fdXNlcj1zdXBlcnZpc29yIC0tYWRtaW5fcGFzc3dvcmQ9c3Ryb25ncGFzc3dvcmQgLS1hZG1pbl9lbWFpbD1pbmZvQGV4YW1wbGUuY29tCiAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4KICoKICogICAgICMgRGlzcGxheSB0aGUgV29yZFByZXNzIHZlcnNpb24KICogICAgICQgd3AgY29yZSB2ZXJzaW9uCiAqICAgICA0LjUuMgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENvcmVfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIENoZWNrcyBmb3IgV29yZFByZXNzIHVwZGF0ZXMgdmlhIFZlcnNpb24gQ2hlY2sgQVBJLgoJICoKCSAqIExpc3RzIHRoZSBtb3N0IHJlY2VudCB2ZXJzaW9ucyB3aGVuIHRoZXJlIGFyZSB1cGRhdGVzIGF2YWlsYWJsZSwKCSAqIG9yIHN1Y2Nlc3MgbWVzc2FnZSB3aGVuIHVwIHRvIGRhdGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLW1pbm9yXQoJICogOiBDb21wYXJlIG9ubHkgdGhlIGZpcnN0IHR3byBwYXJ0cyBvZiB0aGUgdmVyc2lvbiBudW1iZXIuCgkgKgoJICogWy0tbWFqb3JdCgkgKiA6IENvbXBhcmUgb25seSB0aGUgZmlyc3QgcGFydCBvZiB0aGUgdmVyc2lvbiBudW1iZXIuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCB1cGRhdGUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuIERlZmF1bHRzIHRvIHZlcnNpb24sdXBkYXRlX3R5cGUscGFja2FnZV91cmwuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0gY291bnQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBjb3JlIGNoZWNrLXVwZGF0ZQoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgdmVyc2lvbiB8IHVwZGF0ZV90eXBlIHwgcGFja2FnZV91cmwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgNC41LjIgICB8IG1ham9yICAgICAgIHwgaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9yZWxlYXNlL3dvcmRwcmVzcy00LjUuMi56aXAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGNoZWNrLXVwZGF0ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gY2hlY2tfdXBkYXRlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgoJCSR1cGRhdGVzID0gJHRoaXMtPmdldF91cGRhdGVzKCAkYXNzb2NfYXJncyApOwoJCWlmICggJHVwZGF0ZXMgKSB7CgkJCSR1cGRhdGVzICAgPSBhcnJheV9yZXZlcnNlKCAkdXBkYXRlcyApOwoJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcigKCQkJCSRhc3NvY19hcmdzLAoJCQkJWyAndmVyc2lvbicsICd1cGRhdGVfdHlwZScsICdwYWNrYWdlX3VybCcgXQoJCQkpOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdXBkYXRlcyApOwoJCX0gZWxzZWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHx8ICd0YWJsZScgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnV29yZFByZXNzIGlzIGF0IHRoZSBsYXRlc3QgdmVyc2lvbi4nICk7CgkJfQoJfQoKCS8qKgoJICogRG93bmxvYWRzIGNvcmUgV29yZFByZXNzIGZpbGVzLgoJICoKCSAqIERvd25sb2FkcyBhbmQgZXh0cmFjdHMgV29yZFByZXNzIGNvcmUgZmlsZXMgdG8gdGhlIHNwZWNpZmllZCBwYXRoLiBVc2VzCgkgKiBjdXJyZW50IGRpcmVjdG9yeSB3aGVuIG5vIHBhdGggaXMgc3BlY2lmaWVkLiBEb3dubG9hZGVkIGJ1aWxkIGlzIHZlcmlmaWVkCgkgKiB0byBoYXZlIHRoZSBjb3JyZWN0IG1kNSBhbmQgdGhlbiBjYWNoZWQgdG8gdGhlIGxvY2FsIGZpbGVzeXRlbS4KCSAqIFN1YnNlcXVlbnQgdXNlcyBvZiBjb21tYW5kIHdpbGwgdXNlIHRoZSBsb2NhbCBjYWNoZSBpZiBpdCBzdGlsbCBleGlzdHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8ZG93bmxvYWQtdXJsPl0KCSAqIDogRG93bmxvYWQgZGlyZWN0bHkgZnJvbSBhIHByb3ZpZGVkIFVSTCBpbnN0ZWFkIG9mIGZldGNoaW5nIHRoZSBVUkwgZnJvbSB0aGUgd29yZHByZXNzLm9yZyBzZXJ2ZXJzLgoJICoKCSAqIFstLXBhdGg9PHBhdGg+XQoJICogOiBTcGVjaWZ5IHRoZSBwYXRoIGluIHdoaWNoIHRvIGluc3RhbGwgV29yZFByZXNzLiBEZWZhdWx0cyB0byBjdXJyZW50CgkgKiBkaXJlY3RvcnkuCgkgKgoJICogWy0tbG9jYWxlPTxsb2NhbGU+XQoJICogOiBTZWxlY3Qgd2hpY2ggbGFuZ3VhZ2UgeW91IHdhbnQgdG8gZG93bmxvYWQuCgkgKgoJICogWy0tdmVyc2lvbj08dmVyc2lvbj5dCgkgKiA6IFNlbGVjdCB3aGljaCB2ZXJzaW9uIHlvdSB3YW50IHRvIGRvd25sb2FkLiBBY2NlcHRzIGEgdmVyc2lvbiBudW1iZXIsICdsYXRlc3QnIG9yICduaWdodGx5Jy4KCSAqCgkgKiBbLS1za2lwLWNvbnRlbnRdCgkgKiA6IERvd25sb2FkIFdQIHdpdGhvdXQgdGhlIGRlZmF1bHQgdGhlbWVzIGFuZCBwbHVnaW5zLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGVzIGV4aXN0aW5nIGZpbGVzLCBpZiBwcmVzZW50LgoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSBkb3dubG9hZCB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBjb3JlIGRvd25sb2FkIC0tbG9jYWxlPW5sX05MCgkgKiAgICAgRG93bmxvYWRpbmcgV29yZFByZXNzIDQuNS4yIChubF9OTCkuLi4KCSAqICAgICBtZDUgaGFzaCB2ZXJpZmllZDogYzUzNjZkMDViNTIxODMxZGQwYjI5ZGZjMzg2ZTU2YTUKCSAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgZG93bmxvYWRlZC4KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGRvd25sb2FkX2RpciA9ICEgZW1wdHkoICRhc3NvY19hcmdzWydwYXRoJ10gKQoJCQk/ICggcnRyaW0oICRhc3NvY19hcmdzWydwYXRoJ10sICcvXFwnICkgLiAnLycgKQoJCQk6IEFCU1BBVEg7CgoJCSR3b3JkcHJlc3NfcHJlc2VudCA9IGlzX3JlYWRhYmxlKCAkZG93bmxvYWRfZGlyIC4gJ3dwLWxvYWQucGhwJyApOwoKCQlpZiAoICR3b3JkcHJlc3NfcHJlc2VudCAmJiAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnV29yZFByZXNzIGZpbGVzIHNlZW0gdG8gYWxyZWFkeSBiZSBwcmVzZW50IGhlcmUuJyApOwoJCX0KCgkJaWYgKCAhIGlzX2RpciggJGRvd25sb2FkX2RpciApICkgewoJCQlpZiAoICEgaXNfd3JpdGFibGUoIGRpcm5hbWUoICRkb3dubG9hZF9kaXIgKSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkluc3VmZmljaWVudCBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBkaXJlY3RvcnkgJ3skZG93bmxvYWRfZGlyfScuIiApOwoJCQl9CgoJCQlXUF9DTEk6OmxvZyggIkNyZWF0aW5nIGRpcmVjdG9yeSAneyRkb3dubG9hZF9kaXJ9Jy4iICk7CgkJCWlmICggISBAbWtkaXIoICRkb3dubG9hZF9kaXIsIDA3NzcsIHRydWUgLypyZWN1cnNpdmUqLyApICkgewoJCQkJJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAneyRkb3dubG9hZF9kaXJ9JzogeyRlcnJvclsnbWVzc2FnZSddfS4iICk7CgkJCX0KCQl9CgoJCWlmICggISBpc193cml0YWJsZSggJGRvd25sb2FkX2RpciApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiJ3skZG93bmxvYWRfZGlyfScgaXMgbm90IHdyaXRhYmxlIGJ5IGN1cnJlbnQgdXNlci4iICk7CgkJfQoKCQkkbG9jYWxlICAgICAgID0gKHN0cmluZykgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbG9jYWxlJywgJ2VuX1VTJyApOwoJCSRza2lwX2NvbnRlbnQgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1jb250ZW50JywgZmFsc2UgKTsKCQkkaW5zZWN1cmUgICAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCgkJJGRvd25sb2FkX3VybCA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSRmcm9tX3VybCAgICAgPSAhIGVtcHR5KCAkZG93bmxvYWRfdXJsICk7CgoJCWlmICggJGZyb21fdXJsICkgewoJCQkkdmVyc2lvbiA9IG51bGw7CgkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdWZXJzaW9uIG9wdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZvciBVUkwgZG93bmxvYWRzLicgKTsKCQkJfQoJCQlpZiAoICRza2lwX2NvbnRlbnQgfHwgJ2VuX1VTJyAhPT0gJGxvY2FsZSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdTa2lwIGNvbnRlbnQgYW5kIGxvY2FsZSBvcHRpb25zIGFyZSBub3QgYXZhaWxhYmxlIGZvciBVUkwgZG93bmxvYWRzLicgKTsKCQkJfQoJCX0gZWxzZWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSAmJiAnbGF0ZXN0JyAhPT0gJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApIHsKCQkJJHZlcnNpb24gPSAkYXNzb2NfYXJnc1sndmVyc2lvbiddOwoJCQlpZiAoIGluX2FycmF5KCBzdHJ0b2xvd2VyKCAkdmVyc2lvbiApLCBbICd0cnVuaycsICduaWdodGx5JyBdLCB0cnVlICkgKSB7CgkJCQkkdmVyc2lvbiA9ICduaWdodGx5JzsKCQkJfQoKCQkJLy8gTmlnaHRseSBidWlsZHMgYW5kIHNraXAgY29udGVudCBhcmUgb25seSBhdmFpbGFibGUgaW4gLnppcCBmb3JtYXQuCgkJCSRleHRlbnNpb24gPSAoICggJ25pZ2h0bHknID09PSAkdmVyc2lvbiApIHx8ICRza2lwX2NvbnRlbnQgKQoJCQkJPyAnemlwJwoJCQkJOiAndGFyLmd6JzsKCgkJCSRkb3dubG9hZF91cmwgPSAkdGhpcy0+Z2V0X2Rvd25sb2FkX3VybCggJHZlcnNpb24sICRsb2NhbGUsICRleHRlbnNpb24gKTsKCQl9IGVsc2UgewoJCQl0cnkgewoJCQkJJG9mZmVyID0gKCBuZXcgV3BPcmdBcGkoIFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXSApICkKCQkJCQktPmdldF9jb3JlX2Rvd25sb2FkX29mZmVyKCAkbG9jYWxlICk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRleGNlcHRpb24gKTsKCQkJfQoJCQlpZiAoICEgJG9mZmVyICkgewoJCQkJV1BfQ0xJOjplcnJvciggIlRoZSByZXF1ZXN0ZWQgbG9jYWxlICh7JGxvY2FsZX0pIHdhcyBub3QgZm91bmQuIiApOwoJCQl9CgkJCSR2ZXJzaW9uICAgICAgPSAkb2ZmZXJbJ2N1cnJlbnQnXTsKCQkJJGRvd25sb2FkX3VybCA9ICRvZmZlclsnZG93bmxvYWQnXTsKCQkJaWYgKCAhICRza2lwX2NvbnRlbnQgKSB7CgkJCQkkZG93bmxvYWRfdXJsID0gc3RyX3JlcGxhY2UoICcuemlwJywgJy50YXIuZ3onLCAkZG93bmxvYWRfdXJsICk7CgkJCX0KCQl9CgoJCWlmICggJ25pZ2h0bHknID09PSAkdmVyc2lvbiAmJiAnZW5fVVMnICE9PSAkbG9jYWxlICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTmlnaHRseSBidWlsZHMgYXJlIG9ubHkgYXZhaWxhYmxlIGZvciB0aGUgZW5fVVMgbG9jYWxlLicgKTsKCQl9CgoJCSRmcm9tX3ZlcnNpb24gPSAnJzsKCQlpZiAoIGZpbGVfZXhpc3RzKCAkZG93bmxvYWRfZGlyIC4gJ3dwLWluY2x1ZGVzL3ZlcnNpb24ucGhwJyApICkgewoJCQkkd3BfZGV0YWlscyAgID0gc2VsZjo6Z2V0X3dwX2RldGFpbHMoICRkb3dubG9hZF9kaXIgKTsKCQkJJGZyb21fdmVyc2lvbiA9ICR3cF9kZXRhaWxzWyd3cF92ZXJzaW9uJ107CgkJfQoKCQlpZiAoICRmcm9tX3VybCApIHsKCQkJV1BfQ0xJOjpsb2coICJEb3dubG9hZGluZyBmcm9tIHskZG93bmxvYWRfdXJsfSAuLi4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpsb2coICJEb3dubG9hZGluZyBXb3JkUHJlc3MgeyR2ZXJzaW9ufSAoeyRsb2NhbGV9KS4uLiIgKTsKCQl9CgoJCSRwYXRoX3BhcnRzID0gcGF0aGluZm8oICRkb3dubG9hZF91cmwgKTsKCQkkZXh0ZW5zaW9uICA9ICd0YXIuZ3onOwoJCWlmICggJ3ppcCcgPT09ICRwYXRoX3BhcnRzWydleHRlbnNpb24nXSApIHsKCQkJJGV4dGVuc2lvbiA9ICd6aXAnOwoJCQlpZiAoICEgY2xhc3NfZXhpc3RzKCAnWmlwQXJjaGl2ZScgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdFeHRyYWN0aW5nIGEgemlwIGZpbGUgcmVxdWlyZXMgWmlwQXJjaGl2ZS4nICk7CgkJCX0KCQl9CgoJCWlmICggJHNraXBfY29udGVudCAmJiAnemlwJyAhPT0gJGV4dGVuc2lvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1NraXAgY29udGVudCBpcyBvbmx5IGF2YWlsYWJsZSBmb3IgWklQIGZpbGVzLicgKTsKCQl9CgoJCSRjYWNoZSA9IFdQX0NMSTo6Z2V0X2NhY2hlKCk7CgkJaWYgKCAkZnJvbV91cmwgKSB7CgkJCSRjYWNoZV9maWxlID0gbnVsbDsKCQl9IGVsc2UgewoJCQkkY2FjaGVfa2V5ICA9ICJjb3JlL3dvcmRwcmVzcy17JHZlcnNpb259LXskbG9jYWxlfS57JGV4dGVuc2lvbn0iOwoJCQkkY2FjaGVfZmlsZSA9ICRjYWNoZS0+aGFzKCAkY2FjaGVfa2V5ICk7CgkJfQoKCQkkYmFkX2NhY2hlID0gZmFsc2U7CgkJaWYgKCAkY2FjaGVfZmlsZSApIHsKCQkJV1BfQ0xJOjpsb2coICJVc2luZyBjYWNoZWQgZmlsZSAneyRjYWNoZV9maWxlfScuLi4iICk7CgkJCSRza2lwX2NvbnRlbnRfY2FjaGVfZmlsZSA9ICRza2lwX2NvbnRlbnQgPyBzZWxmOjpzdHJpcF9jb250ZW50X2RpciggJGNhY2hlX2ZpbGUgKSA6IG51bGw7CgkJCXRyeSB7CgkJCQlFeHRyYWN0b3I6OmV4dHJhY3QoICRza2lwX2NvbnRlbnRfY2FjaGVfZmlsZSA/OiAkY2FjaGVfZmlsZSwgJGRvd25sb2FkX2RpciApOwoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdFeHRyYWN0aW9uIGZhaWxlZCwgZG93bmxvYWRpbmcgYSBuZXcgY29weS4uLicgKTsKCQkJCSRiYWRfY2FjaGUgPSB0cnVlOwoJCQl9CgkJfQoKCQlpZiAoICEgJGNhY2hlX2ZpbGUgfHwgJGJhZF9jYWNoZSApIHsKCQkJLy8gV2UgbmVlZCB0byB1c2UgYSB0ZW1wb3JhcnkgZmlsZSBiZWNhdXNlIHBpcGluZyBmcm9tIGNVUkwgdG8gdGFyIGlzIGZsYWt5CgkJCS8vIG9uIE1pbkdXIChhbmQgcHJvYmFibHkgaW4gb3RoZXIgZW52aXJvbm1lbnRzIHRvbykuCgkJCSR0ZW1wID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkgLiB1bmlxaWQoICd3cF8nICkgLiAiLnskZXh0ZW5zaW9ufSI7CgkJCXJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKAoJCQkJZnVuY3Rpb24gKCkgdXNlICggJHRlbXAgKSB7CgkJCQkJaWYgKCBmaWxlX2V4aXN0cyggJHRlbXAgKSApIHsKCQkJCQkJdW5saW5rKCAkdGVtcCApOwoJCQkJCX0KCQkJCX0KCQkJKTsKCgkJCSRoZWFkZXJzID0gWyAnQWNjZXB0JyA9PiAnYXBwbGljYXRpb24vanNvbicgXTsKCQkJJG9wdGlvbnMgPSBbCgkJCQkndGltZW91dCcgID0+IDYwMCwgIC8vIDEwIG1pbnV0ZXMgb3VnaHQgdG8gYmUgZW5vdWdoIGZvciBldmVyeWJvZHkKCQkJCSdmaWxlbmFtZScgPT4gJHRlbXAsCgkJCQknaW5zZWN1cmUnID0+ICRpbnNlY3VyZSwKCQkJXTsKCgkJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICRkb3dubG9hZF91cmwsIG51bGwsICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQkJaWYgKCA0MDQgPT09IChpbnQpICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnUmVsZWFzZSBub3QgZm91bmQuIERvdWJsZS1jaGVjayBsb2NhbGUgb3IgdmVyc2lvbi4nICk7CgkJCX0gZWxzZWlmICggMjAgIT09IChpbnQpIHN1YnN0ciggJHJlc3BvbnNlLT5zdGF0dXNfY29kZSwgMCwgMiApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGFjY2VzcyBkb3dubG9hZCBVUkwgKEhUVFAgY29kZSB7JHJlc3BvbnNlLT5zdGF0dXNfY29kZX0pLiIgKTsKCQkJfQoKCQkJaWYgKCAnbmlnaHRseScgIT09ICR2ZXJzaW9uICkgewoJCQkJdW5zZXQoICRvcHRpb25zWydmaWxlbmFtZSddICk7CgkJCQkkbWQ1X3Jlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJGRvd25sb2FkX3VybCAuICcubWQ1JywgbnVsbCwgW10sICRvcHRpb25zICk7CgkJCQlpZiAoICRtZDVfcmVzcG9uc2UtPnN0YXR1c19jb2RlID49IDIwMCAmJiAkbWQ1X3Jlc3BvbnNlLT5zdGF0dXNfY29kZSA8IDMwMCApIHsKCQkJCQkkbWQ1X2ZpbGUgPSBtZDVfZmlsZSggJHRlbXAgKTsKCgkJCQkJaWYgKCAkbWQ1X2ZpbGUgPT09ICRtZDVfcmVzcG9uc2UtPmJvZHkgKSB7CgkJCQkJCVdQX0NMSTo6bG9nKCAnbWQ1IGhhc2ggdmVyaWZpZWQ6ICcgLiAkbWQ1X2ZpbGUgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlXUF9DTEk6OmVycm9yKCAibWQ1IGhhc2ggZm9yIGRvd25sb2FkICh7JG1kNV9maWxlfSkgaXMgZGlmZmVyZW50IHRoYW4gdGhlIHJlbGVhc2UgaGFzaCAoeyRtZDVfcmVzcG9uc2UtPmJvZHl9KS4iICk7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICJDb3VsZG4ndCBhY2Nlc3MgbWQ1IGhhc2ggZm9yIHJlbGVhc2UgKHskZG93bmxvYWRfdXJsfS5tZDUsIEhUVFAgY29kZSB7JG1kNV9yZXNwb25zZS0+c3RhdHVzX2NvZGV9KS4iICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdtZDUgaGFzaCBjaGVja3MgYXJlIG5vdCBhdmFpbGFibGUgZm9yIG5pZ2h0bHkgZG93bmxvYWRzLicgKTsKCQkJfQoKCQkJJHNraXBfY29udGVudF90ZW1wID0gJHNraXBfY29udGVudCA/IHNlbGY6OnN0cmlwX2NvbnRlbnRfZGlyKCAkdGVtcCApIDogbnVsbDsKCgkJCXRyeSB7CgkJCQlFeHRyYWN0b3I6OmV4dHJhY3QoICRza2lwX2NvbnRlbnRfdGVtcCA/OiAkdGVtcCwgJGRvd25sb2FkX2RpciApOwoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgZXh0cmFjdCBXb3JkUHJlc3MgYXJjaGl2ZS4geyRleGNlcHRpb24tPmdldE1lc3NhZ2UoKX0iICk7CgkJCX0KCgkJCS8vIERvIG5vdCB1c2UgdGhlIGNhY2hlIGZvciBuaWdodGx5IGJ1aWxkcyBvciBmb3IgZG93bmxvYWRlZCBVUkxzCgkJCS8vICh0aGUgVVJMIGNvdWxkIGJlIHNvbWV0aGluZyBsaWtlICJsYXRlc3QuemlwIiBvciAibmlnaHRseS56aXAiKS4KCQkJaWYgKCAhICRmcm9tX3VybCAmJiAnbmlnaHRseScgIT09ICR2ZXJzaW9uICkgewoJCQkJJGNhY2hlLT5pbXBvcnQoICRjYWNoZV9rZXksICR0ZW1wICk7CgkJCX0KCQl9CgoJCWlmICggJHdvcmRwcmVzc19wcmVzZW50ICkgewoJCQkkdGhpcy0+Y2xlYW51cF9leHRyYV9maWxlcyggJGZyb21fdmVyc2lvbiwgJHZlcnNpb24sICRsb2NhbGUsICRpbnNlY3VyZSApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAnV29yZFByZXNzIGRvd25sb2FkZWQuJyApOwoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIFdvcmRQcmVzcyBpcyBpbnN0YWxsZWQuCgkgKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIFdvcmRQcmVzcyBpcyBpbnN0YWxsZWQgYnkgY2hlY2tpbmcgaWYgdGhlIHN0YW5kYXJkCgkgKiBkYXRhYmFzZSB0YWJsZXMgYXJlIGluc3RhbGxlZC4gRG9lc24ndCBwcm9kdWNlIG91dHB1dDsgdXNlcyBleGl0IGNvZGVzCgkgKiB0byBjb21tdW5pY2F0ZSB3aGV0aGVyIFdvcmRQcmVzcyBpcyBpbnN0YWxsZWQuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogQ2hlY2sgaWYgdGhpcyBpcyBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIFdvcmRQcmVzcyBpcyBpbnN0YWxsZWQ7IGV4aXQgc3RhdHVzIDAgaWYgaW5zdGFsbGVkLCBvdGhlcndpc2UgMQoJICogICAgICQgd3AgY29yZSBpcy1pbnN0YWxsZWQKCSAqICAgICAkIGVjaG8gJD8KCSAqICAgICAxCgkgKgoJICogICAgICMgQmFzaCBzY3JpcHQgZm9yIGNoZWNraW5nIHdoZXRoZXIgV29yZFByZXNzIGlzIGluc3RhbGxlZCBvciBub3QKCSAqICAgICBpZiAhIHdwIGNvcmUgaXMtaW5zdGFsbGVkOyB0aGVuCgkgKiAgICAgICAgIHdwIGNvcmUgaW5zdGFsbAoJICogICAgIGZpCgkgKgoJICogQHN1YmNvbW1hbmQgaXMtaW5zdGFsbGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc19pbnN0YWxsZWQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoIGlzX2Jsb2dfaW5zdGFsbGVkKCkKCQkJJiYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICkKCQkJCXx8IGlzX211bHRpc2l0ZSgpICkgKSB7CgkJCVdQX0NMSTo6aGFsdCggMCApOwoJCX0KCgkJV1BfQ0xJOjpoYWx0KCAxICk7Cgl9CgoJLyoqCgkgKiBSdW5zIHRoZSBzdGFuZGFyZCBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIHByb2Nlc3MuCgkgKgoJICogQ3JlYXRlcyB0aGUgV29yZFByZXNzIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UgdXNpbmcgdGhlIFVSTCwgdGl0bGUsIGFuZAoJICogZGVmYXVsdCBhZG1pbiB1c2VyIGRldGFpbHMgcHJvdmlkZWQuIFBlcmZvcm1zIHRoZSBmYW1vdXMgNSBtaW51dGUgaW5zdGFsbAoJICogaW4gc2Vjb25kcyBvciBsZXNzLgoJICoKCSAqIE5vdGU6IGlmIHlvdSd2ZSBpbnN0YWxsZWQgV29yZFByZXNzIGluIGEgc3ViZGlyZWN0b3J5LCB0aGVuIHlvdSdsbCBuZWVkCgkgKiB0byBgd3Agb3B0aW9uIHVwZGF0ZSBzaXRldXJsYCBhZnRlciBgd3AgY29yZSBpbnN0YWxsYC4gRm9yIGluc3RhbmNlLCBpZgoJICogV29yZFByZXNzIGlzIGluc3RhbGxlZCBpbiB0aGUgYC93cGAgZGlyZWN0b3J5IGFuZCB5b3VyIGRvbWFpbiBpcyBleGFtcGxlLmNvbSwKCSAqIHRoZW4geW91J2xsIG5lZWQgdG8gcnVuIGB3cCBvcHRpb24gdXBkYXRlIHNpdGV1cmwgaHR0cDovL2V4YW1wbGUuY29tL3dwYCBmb3IKCSAqIHlvdXIgV29yZFByZXNzIGluc3RhbGxhdGlvbiB0byBmdW5jdGlvbiBwcm9wZXJseS4KCSAqCgkgKiBOb3RlOiBXaGVuIHVzaW5nIGN1c3RvbSB1c2VyIHRhYmxlcyAoZS5nLiBgQ1VTVE9NX1VTRVJfVEFCTEVgKSwgdGhlIGFkbWluCgkgKiBlbWFpbCBhbmQgcGFzc3dvcmQgYXJlIGlnbm9yZWQgaWYgdGhlIHVzZXJfbG9naW4gYWxyZWFkeSBleGlzdHMuIElmIHRoZQoJICogdXNlcl9sb2dpbiBkb2Vzbid0IGV4aXN0LCBhIG5ldyB1c2VyIHdpbGwgYmUgY3JlYXRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogLS11cmw9PHVybD4KCSAqIDogVGhlIGFkZHJlc3Mgb2YgdGhlIG5ldyBzaXRlLgoJICoKCSAqIC0tdGl0bGU9PHNpdGUtdGl0bGU+CgkgKiA6IFRoZSB0aXRsZSBvZiB0aGUgbmV3IHNpdGUuCgkgKgoJICogLS1hZG1pbl91c2VyPTx1c2VybmFtZT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIGFkbWluIHVzZXIuCgkgKgoJICogWy0tYWRtaW5fcGFzc3dvcmQ9PHBhc3N3b3JkPl0KCSAqIDogVGhlIHBhc3N3b3JkIGZvciB0aGUgYWRtaW4gdXNlci4gRGVmYXVsdHMgdG8gcmFuZG9tbHkgZ2VuZXJhdGVkIHN0cmluZy4KCSAqCgkgKiAtLWFkbWluX2VtYWlsPTxlbWFpbD4KCSAqIDogVGhlIGVtYWlsIGFkZHJlc3MgZm9yIHRoZSBhZG1pbiB1c2VyLgoJICoKCSAqIFstLXNraXAtZW1haWxdCgkgKiA6IERvbid0IHNlbmQgYW4gZW1haWwgbm90aWZpY2F0aW9uIHRvIHRoZSBuZXcgYWRtaW4gdXNlci4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEluc3RhbGwgV29yZFByZXNzIGluIDUgc2Vjb25kcwoJICogICAgICQgd3AgY29yZSBpbnN0YWxsIC0tdXJsPWV4YW1wbGUuY29tIC0tdGl0bGU9RXhhbXBsZSAtLWFkbWluX3VzZXI9c3VwZXJ2aXNvciAtLWFkbWluX3Bhc3N3b3JkPXN0cm9uZ3Bhc3N3b3JkIC0tYWRtaW5fZW1haWw9aW5mb0BleGFtcGxlLmNvbQoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgoJICoKCSAqICAgICAjIEluc3RhbGwgV29yZFByZXNzIHdpdGhvdXQgZGlzY2xvc2luZyBhZG1pbl9wYXNzd29yZCB0byBiYXNoIGhpc3RvcnkKCSAqICAgICAkIHdwIGNvcmUgaW5zdGFsbCAtLXVybD1leGFtcGxlLmNvbSAtLXRpdGxlPUV4YW1wbGUgLS1hZG1pbl91c2VyPXN1cGVydmlzb3IgLS1hZG1pbl9lbWFpbD1pbmZvQGV4YW1wbGUuY29tIC0tcHJvbXB0PWFkbWluX3Bhc3N3b3JkIDwgYWRtaW5fcGFzc3dvcmQudHh0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAkdGhpcy0+ZG9faW5zdGFsbCggJGFzc29jX2FyZ3MgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnV29yZFByZXNzIGluc3RhbGxlZCBzdWNjZXNzZnVsbHkuJyApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6bG9nKCAnV29yZFByZXNzIGlzIGFscmVhZHkgaW5zdGFsbGVkLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBUcmFuc2Zvcm1zIGFuIGV4aXN0aW5nIHNpbmdsZS1zaXRlIGluc3RhbGxhdGlvbiBpbnRvIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4KCSAqCgkgKiBDcmVhdGVzIHRoZSBtdWx0aXNpdGUgZGF0YWJhc2UgdGFibGVzLCBhbmQgYWRkcyB0aGUgbXVsdGlzaXRlIGNvbnN0YW50cwoJICogdG8gd3AtY29uZmlnLnBocC4KCSAqCgkgKiBGb3IgdGhvc2UgdXNpbmcgV29yZFByZXNzIHdpdGggQXBhY2hlLCByZW1lbWJlciB0byB1cGRhdGUgdGhlIGAuaHRhY2Nlc3NgCgkgKiBmaWxlIHdpdGggdGhlIGFwcHJvcHJpYXRlIG11bHRpc2l0ZSByZXdyaXRlIHJ1bGVzLgoJICoKCSAqIFtSZXZpZXcgdGhlIG11bHRpc2l0ZSBkb2N1bWVudGF0aW9uXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvQ3JlYXRlX0FfTmV0d29yaykKCSAqIGZvciBtb3JlIGRldGFpbHMgYWJvdXQgaG93IG11bHRpc2l0ZSB3b3Jrcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tdGl0bGU9PG5ldHdvcmstdGl0bGU+XQoJICogOiBUaGUgdGl0bGUgb2YgdGhlIG5ldyBuZXR3b3JrLgoJICoKCSAqIFstLWJhc2U9PHVybC1wYXRoPl0KCSAqIDogQmFzZSBwYXRoIGFmdGVyIHRoZSBkb21haW4gbmFtZSB0aGF0IGVhY2ggc2l0ZSB1cmwgd2lsbCBzdGFydCB3aXRoLgoJICogLS0tCgkgKiBkZWZhdWx0OiAvCgkgKiAtLS0KCSAqCgkgKiBbLS1zdWJkb21haW5zXQoJICogOiBJZiBwYXNzZWQsIHRoZSBuZXR3b3JrIHdpbGwgdXNlIHN1YmRvbWFpbnMsIGluc3RlYWQgb2Ygc3ViZGlyZWN0b3JpZXMuIERvZXNuJ3Qgd29yayB3aXRoICdsb2NhbGhvc3QnLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgY29yZSBtdWx0aXNpdGUtY29udmVydAoJICogICAgIFNldCB1cCBtdWx0aXNpdGUgZGF0YWJhc2UgdGFibGVzLgoJICogICAgIEFkZGVkIG11bHRpc2l0ZSBjb25zdGFudHMgdG8gd3AtY29uZmlnLnBocC4KCSAqICAgICBTdWNjZXNzOiBOZXR3b3JrIGluc3RhbGxlZC4gRG9uJ3QgZm9yZ2V0IHRvIHNldCB1cCByZXdyaXRlIHJ1bGVzLgoJICoKCSAqIEBzdWJjb21tYW5kIG11bHRpc2l0ZS1jb252ZXJ0CgkgKiBAYWxpYXMgaW5zdGFsbC1uZXR3b3JrCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtdWx0aXNpdGVfY29udmVydCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGFscmVhZHkgaXMgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCSRhc3NvY19hcmdzID0gc2VsZjo6c2V0X211bHRpc2l0ZV9kZWZhdWx0cyggJGFzc29jX2FyZ3MgKTsKCQlpZiAoICEgaXNzZXQoICRhc3NvY19hcmdzWyd0aXRsZSddICkgKSB7CgkJCS8vIHRyYW5zbGF0b3JzOiBwbGFjZWhvbGRlciBpcyBibG9nIG5hbWUKCQkJJGFzc29jX2FyZ3NbJ3RpdGxlJ10gPSBzcHJpbnRmKCBfeCggJyVzIFNpdGVzJywgJ0RlZmF1bHQgbmV0d29yayBuYW1lJyApLCBnZXRfb3B0aW9uKCAnYmxvZ25hbWUnICkgKTsKCQl9CgoJCWlmICggJHRoaXMtPm11bHRpc2l0ZV9jb252ZXJ0XyggJGFzc29jX2FyZ3MgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiTmV0d29yayBpbnN0YWxsZWQuIERvbid0IGZvcmdldCB0byBzZXQgdXAgcmV3cml0ZSBydWxlcyAoYW5kIGEgLmh0YWNjZXNzIGZpbGUsIGlmIHVzaW5nIEFwYWNoZSkuIiApOwoJCX0KCX0KCgkvKioKCSAqIEluc3RhbGxzIFdvcmRQcmVzcyBtdWx0aXNpdGUgZnJvbSBzY3JhdGNoLgoJICoKCSAqIENyZWF0ZXMgdGhlIFdvcmRQcmVzcyB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlIHVzaW5nIHRoZSBVUkwsIHRpdGxlLCBhbmQKCSAqIGRlZmF1bHQgYWRtaW4gdXNlciBkZXRhaWxzIHByb3ZpZGVkLiBUaGVuLCBjcmVhdGVzIHRoZSBtdWx0aXNpdGUgdGFibGVzCgkgKiBpbiB0aGUgZGF0YWJhc2UgYW5kIGFkZHMgbXVsdGlzaXRlIGNvbnN0YW50cyB0byB0aGUgd3AtY29uZmlnLnBocC4KCSAqCgkgKiBGb3IgdGhvc2UgdXNpbmcgV29yZFByZXNzIHdpdGggQXBhY2hlLCByZW1lbWJlciB0byB1cGRhdGUgdGhlIGAuaHRhY2Nlc3NgCgkgKiBmaWxlIHdpdGggdGhlIGFwcHJvcHJpYXRlIG11bHRpc2l0ZSByZXdyaXRlIHJ1bGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS11cmw9PHVybD5dCgkgKiA6IFRoZSBhZGRyZXNzIG9mIHRoZSBuZXcgc2l0ZS4KCSAqCgkgKiBbLS1iYXNlPTx1cmwtcGF0aD5dCgkgKiA6IEJhc2UgcGF0aCBhZnRlciB0aGUgZG9tYWluIG5hbWUgdGhhdCBlYWNoIHNpdGUgdXJsIGluIHRoZSBuZXR3b3JrIHdpbGwgc3RhcnQgd2l0aC4KCSAqIC0tLQoJICogZGVmYXVsdDogLwoJICogLS0tCgkgKgoJICogWy0tc3ViZG9tYWluc10KCSAqIDogSWYgcGFzc2VkLCB0aGUgbmV0d29yayB3aWxsIHVzZSBzdWJkb21haW5zLCBpbnN0ZWFkIG9mIHN1YmRpcmVjdG9yaWVzLiBEb2Vzbid0IHdvcmsgd2l0aCAnbG9jYWxob3N0Jy4KCSAqCgkgKiAtLXRpdGxlPTxzaXRlLXRpdGxlPgoJICogOiBUaGUgdGl0bGUgb2YgdGhlIG5ldyBzaXRlLgoJICoKCSAqIC0tYWRtaW5fdXNlcj08dXNlcm5hbWU+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBhZG1pbiB1c2VyLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhZG1pbgoJICogLS0tCgkgKgoJICogWy0tYWRtaW5fcGFzc3dvcmQ9PHBhc3N3b3JkPl0KCSAqIDogVGhlIHBhc3N3b3JkIGZvciB0aGUgYWRtaW4gdXNlci4gRGVmYXVsdHMgdG8gcmFuZG9tbHkgZ2VuZXJhdGVkIHN0cmluZy4KCSAqCgkgKiAtLWFkbWluX2VtYWlsPTxlbWFpbD4KCSAqIDogVGhlIGVtYWlsIGFkZHJlc3MgZm9yIHRoZSBhZG1pbiB1c2VyLgoJICoKCSAqIFstLXNraXAtZW1haWxdCgkgKiA6IERvbid0IHNlbmQgYW4gZW1haWwgbm90aWZpY2F0aW9uIHRvIHRoZSBuZXcgYWRtaW4gdXNlci4KCSAqCgkgKiBbLS1za2lwLWNvbmZpZ10KCSAqIDogRG9uJ3QgYWRkIG11bHRpc2l0ZSBjb25zdGFudHMgdG8gd3AtY29uZmlnLnBocC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGNvcmUgbXVsdGlzaXRlLWluc3RhbGwgLS10aXRsZT0iV2VsY29tZSB0byB0aGUgV29yZFByZXNzIiBcCgkgKiAgICAgPiAtLWFkbWluX3VzZXI9ImFkbWluIiAtLWFkbWluX3Bhc3N3b3JkPSJwYXNzd29yZCIgXAoJICogICAgID4gLS1hZG1pbl9lbWFpbD0idXNlckBleGFtcGxlLmNvbSIKCSAqICAgICBTaW5nbGUgc2l0ZSBkYXRhYmFzZSB0YWJsZXMgYWxyZWFkeSBwcmVzZW50LgoJICogICAgIFNldCB1cCBtdWx0aXNpdGUgZGF0YWJhc2UgdGFibGVzLgoJICogICAgIEFkZGVkIG11bHRpc2l0ZSBjb25zdGFudHMgdG8gd3AtY29uZmlnLnBocC4KCSAqICAgICBTdWNjZXNzOiBOZXR3b3JrIGluc3RhbGxlZC4gRG9uJ3QgZm9yZ2V0IHRvIHNldCB1cCByZXdyaXRlIHJ1bGVzLgoJICoKCSAqIEBzdWJjb21tYW5kIG11bHRpc2l0ZS1pbnN0YWxsCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtdWx0aXNpdGVfaW5zdGFsbCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggJHRoaXMtPmRvX2luc3RhbGwoICRhc3NvY19hcmdzICkgKSB7CgkJCVdQX0NMSTo6bG9nKCAnQ3JlYXRlZCBzaW5nbGUgc2l0ZSBkYXRhYmFzZSB0YWJsZXMuJyApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6bG9nKCAnU2luZ2xlIHNpdGUgZGF0YWJhc2UgdGFibGVzIGFscmVhZHkgcHJlc2VudC4nICk7CgkJfQoKCQkkYXNzb2NfYXJncyA9IHNlbGY6OnNldF9tdWx0aXNpdGVfZGVmYXVsdHMoICRhc3NvY19hcmdzICk7CgkJLy8gdHJhbnNsYXRvcnM6IHBsYWNlaG9sZGVyIGlzIHVzZXIgc3VwcGxpZWQgdGl0bGUKCQkkYXNzb2NfYXJnc1sndGl0bGUnXSA9IHNwcmludGYoIF94KCAnJXMgU2l0ZXMnLCAnRGVmYXVsdCBuZXR3b3JrIG5hbWUnICksICRhc3NvY19hcmdzWyd0aXRsZSddICk7CgoJCS8vIE92ZXJ3cml0ZSBydW50aW1lIGFyZ3MsIHRvIGF2b2lkIG1pc21hdGNoZXMuCgkJJGNvbnN0c190b19hcmdzID0gWwoJCQknU1VCRE9NQUlOX0lOU1RBTEwnICAgID0+ICdzdWJkb21haW5zJywKCQkJJ1BBVEhfQ1VSUkVOVF9TSVRFJyAgICA9PiAnYmFzZScsCgkJCSdTSVRFX0lEX0NVUlJFTlRfU0lURScgPT4gJ3NpdGVfaWQnLAoJCQknQkxPR19JRF9DVVJSRU5UX1NJVEUnID0+ICdibG9nX2lkJywKCQldOwoKCQlmb3JlYWNoICggJGNvbnN0c190b19hcmdzIGFzICRjb25zdCA9PiAkYXJnICkgewoJCQlpZiAoIGRlZmluZWQoICRjb25zdCApICkgewoJCQkJJGFzc29jX2FyZ3NbICRhcmcgXSA9IGNvbnN0YW50KCAkY29uc3QgKTsKCQkJfQoJCX0KCgkJaWYgKCAhICR0aGlzLT5tdWx0aXNpdGVfY29udmVydF8oICRhc3NvY19hcmdzICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIERvIHRoZSBzdGVwcyB0aGF0IHdlcmUgc2tpcHBlZCBieSBwb3B1bGF0ZV9uZXR3b3JrKCksCgkJLy8gd2hpY2ggY2hlY2tzIGlzX211bHRpc2l0ZSgpLgoJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRzaXRlX3VzZXIgPSBnZXRfdXNlcl9ieSggJ2VtYWlsJywgJGFzc29jX2FyZ3NbJ2FkbWluX2VtYWlsJ10gKTsKCQkJc2VsZjo6YWRkX3NpdGVfYWRtaW5zKCAkc2l0ZV91c2VyICk7CgkJCSRkb21haW4gPSBzZWxmOjpnZXRfY2xlYW5fYmFzZWRvbWFpbigpOwoJCQlzZWxmOjpjcmVhdGVfaW5pdGlhbF9ibG9nKAoJCQkJJGFzc29jX2FyZ3NbJ3NpdGVfaWQnXSwKCQkJCSRhc3NvY19hcmdzWydibG9nX2lkJ10sCgkJCQkkZG9tYWluLAoJCQkJJGFzc29jX2FyZ3NbJ2Jhc2UnXSwKCQkJCSRhc3NvY19hcmdzWydzdWJkb21haW5zJ10sCgkJCQkkc2l0ZV91c2VyCgkJCSk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJOZXR3b3JrIGluc3RhbGxlZC4gRG9uJ3QgZm9yZ2V0IHRvIHNldCB1cCByZXdyaXRlIHJ1bGVzIChhbmQgYSAuaHRhY2Nlc3MgZmlsZSwgaWYgdXNpbmcgQXBhY2hlKS4iICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc2V0X211bHRpc2l0ZV9kZWZhdWx0cyggJGFzc29jX2FyZ3MgKSB7CgkJJGRlZmF1bHRzID0gWwoJCQknc3ViZG9tYWlucycgPT4gZmFsc2UsCgkJCSdiYXNlJyAgICAgICA9PiAnLycsCgkJCSdzaXRlX2lkJyAgICA9PiAxLAoJCQknYmxvZ19pZCcgICAgPT4gMSwKCQldOwoKCQlyZXR1cm4gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGRvX2luc3RhbGwoICRhc3NvY19hcmdzICkgewoJCWlmICggaXNfYmxvZ19pbnN0YWxsZWQoKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKCB0cnVlID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWVtYWlsJyApICkgewoJCQlpZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAnd3BfbmV3X2Jsb2dfbm90aWZpY2F0aW9uJyApICkgewoJCQkJZnVuY3Rpb24gd3BfbmV3X2Jsb2dfbm90aWZpY2F0aW9uKCkgewoJCQkJCS8vIFNpbGVuY2UgaXMgZ29sZGVuCgkJCQl9CgkJCX0KCQkJLy8gV1AgNC45LjAgLSBza2lwICJOb3RpY2Ugb2YgQWRtaW4gRW1haWwgQ2hhbmdlIiBlbWFpbCBhcyB3ZWxsIChodHRwczovL2NvcmUudHJhYy53b3JkcHJlc3Mub3JnL3RpY2tldC8zOTExNykuCgkJCWFkZF9maWx0ZXIoICdzZW5kX3NpdGVfYWRtaW5fZW1haWxfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCX0KCgkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvdXBncmFkZS5waHAnOwoKCQkkZGVmYXVsdHMgPSBbCgkJCSd0aXRsZScgICAgICAgICAgPT4gJycsCgkJCSdhZG1pbl91c2VyJyAgICAgPT4gJycsCgkJCSdhZG1pbl9lbWFpbCcgICAgPT4gJycsCgkJCSdhZG1pbl9wYXNzd29yZCcgPT4gJycsCgkJXTsKCgkJJGFyZ3MgPSB3cF9wYXJzZV9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICk7CgoJCS8vIFN1cHBvcnQgcHJvbXB0aW5nIGZvciB0aGUgYC0tdXJsPTx1cmw+YCwKCQkvLyB3aGljaCBpcyBub3JtYWxseSBhIHJ1bnRpbWUgYXJndW1lbnQKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndXJsJ10gKSApIHsKCQkJV1BfQ0xJOjpzZXRfdXJsKCAkYXNzb2NfYXJnc1sndXJsJ10gKTsKCQl9CgoJCSRwdWJsaWMgICA9IHRydWU7CgkJJHBhc3N3b3JkID0gZW1wdHkoICRhcmdzWydhZG1pbl9wYXNzd29yZCddICkKCQkJPyB3cF9nZW5lcmF0ZV9wYXNzd29yZCggMTggKQoJCQk6ICRhcmdzWydhZG1pbl9wYXNzd29yZCddOwoKCQlpZiAoICEgaXNfZW1haWwoICRhcmdzWydhZG1pbl9lbWFpbCddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgJ3skYXJnc1snYWRtaW5fZW1haWwnXX0nIGVtYWlsIGFkZHJlc3MgaXMgaW52YWxpZC4iICk7CgkJfQoKCQkkcmVzdWx0ID0gd3BfaW5zdGFsbCgKCQkJJGFyZ3NbJ3RpdGxlJ10sCgkJCSRhcmdzWydhZG1pbl91c2VyJ10sCgkJCSRhcmdzWydhZG1pbl9lbWFpbCddLAoJCQkkcHVibGljLAoJCQknJywKCQkJJHBhc3N3b3JkCgkJKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQkkcmVhc29uID0gV1BfQ0xJOjplcnJvcl90b19zdHJpbmcoICRyZXN1bHQgKTsKCQkJV1BfQ0xJOjplcnJvciggIkluc3RhbGxhdGlvbiBmYWlsZWQgKHskcmVhc29ufSkuIiApOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkR0xPQkFMU1snd3BkYiddLT5sYXN0X2Vycm9yICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnN0YWxsYXRpb24gcHJvZHVjZWQgZGF0YWJhc2UgZXJyb3JzLCBhbmQgbWF5IGhhdmUgcGFydGlhbGx5IG9yIGNvbXBsZXRlbHkgZmFpbGVkLicgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhcmdzWydhZG1pbl9wYXNzd29yZCddICkgKSB7CgkJCVdQX0NMSTo6bG9nKCAiQWRtaW4gcGFzc3dvcmQ6IHskcmVzdWx0WydwYXNzd29yZCddfSIgKTsKCQl9CgoJCS8vIENvbmZpcm0gdGhlIHVwbG9hZHMgZGlyZWN0b3J5IGV4aXN0cwoJCSR1cGxvYWRfZGlyID0gd3BfdXBsb2FkX2RpcigpOwoJCWlmICggISBlbXB0eSggJHVwbG9hZF9kaXJbJ2Vycm9yJ10gKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAkdXBsb2FkX2RpclsnZXJyb3InXSApOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtdWx0aXNpdGVfY29udmVydF8oICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvdXBncmFkZS5waHAnOwoKCQkkZG9tYWluID0gc2VsZjo6Z2V0X2NsZWFuX2Jhc2Vkb21haW4oKTsKCQlpZiAoICdsb2NhbGhvc3QnID09PSAkZG9tYWluICYmICEgZW1wdHkoICRhc3NvY19hcmdzWydzdWJkb21haW5zJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIk11bHRpc2l0ZSB3aXRoIHN1YmRvbWFpbnMgY2Fubm90IGJlIGNvbmZpZ3VyZWQgd2hlbiBkb21haW4gaXMgJ2xvY2FsaG9zdCcuIiApOwoJCX0KCgkJLy8gbmVlZCB0byByZWdpc3RlciB0aGUgbXVsdGlzaXRlIHRhYmxlcyBtYW51YWxseSBmb3Igc29tZSByZWFzb24KCQlmb3JlYWNoICggJHdwZGItPnRhYmxlcyggJ21zX2dsb2JhbCcgKSBhcyAkdGFibGUgPT4gJHByZWZpeGVkX3RhYmxlICkgewoJCQkkd3BkYi0+JHRhYmxlID0gJHByZWZpeGVkX3RhYmxlOwoJCX0KCgkJaW5zdGFsbF9uZXR3b3JrKCk7CgoJCSRyZXN1bHQgPSBwb3B1bGF0ZV9uZXR3b3JrKAoJCQkkYXNzb2NfYXJnc1snc2l0ZV9pZCddLAoJCQkkZG9tYWluLAoJCQlnZXRfb3B0aW9uKCAnYWRtaW5fZW1haWwnICksCgkJCSRhc3NvY19hcmdzWyd0aXRsZSddLAoJCQkkYXNzb2NfYXJnc1snYmFzZSddLAoJCQkkYXNzb2NfYXJnc1snc3ViZG9tYWlucyddCgkJKTsKCgkJJHNpdGVfaWQgPSAkd3BkYi0+Z2V0X3ZhciggIlNFTEVDVCBpZCBGUk9NICR3cGRiLT5zaXRlIiApOwoJCSRzaXRlX2lkID0gKCBudWxsID09PSAkc2l0ZV9pZCApID8gMSA6IChpbnQpICRzaXRlX2lkOwoKCQlpZiAoIHRydWUgPT09ICRyZXN1bHQgKSB7CgkJCVdQX0NMSTo6bG9nKCAnU2V0IHVwIG11bHRpc2l0ZSBkYXRhYmFzZSB0YWJsZXMuJyApOwoJCX0gZWxzZWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJc3dpdGNoICggJHJlc3VsdC0+Z2V0X2Vycm9yX2NvZGUoKSApIHsKCgkJCQljYXNlICdzaXRlaWRfZXhpc3RzJzoKCQkJCQlXUF9DTEk6OmxvZyggJHJlc3VsdC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCQkJCXJldHVybiBmYWxzZTsKCgkJCQljYXNlICdub193aWxkY2FyZF9kbnMnOgoJCQkJCVdQX0NMSTo6d2FybmluZyggX18oICdXaWxkY2FyZCBETlMgbWF5IG5vdCBiZSBjb25maWd1cmVkIGNvcnJlY3RseS4nICkgKTsKCQkJCQlicmVhazsKCgkJCQlkZWZhdWx0OgoJCQkJCVdQX0NMSTo6ZXJyb3IoICRyZXN1bHQgKTsKCQkJfQoJCX0KCgkJLy8gZGVsZXRlX3NpdGVfb3B0aW9uKCkgY2xlYW5zIHRoZSBhbGxvcHRpb25zIGNhY2hlIHRvIHByZXZlbnQgZHVwZSBvcHRpb24KCQlkZWxldGVfc2l0ZV9vcHRpb24oICd1cGxvYWRfc3BhY2VfY2hlY2tfZGlzYWJsZWQnICk7CgkJdXBkYXRlX3NpdGVfb3B0aW9uKCAndXBsb2FkX3NwYWNlX2NoZWNrX2Rpc2FibGVkJywgMSApOwoKCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRzdWJkb21haW5fZXhwb3J0ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc3ViZG9tYWlucycgKSA/ICd0cnVlJyA6ICdmYWxzZSc7CgkJCSRtc19jb25maWcgICAgICAgID0gPDw8RU9UCmRlZmluZSggJ1dQX0FMTE9XX01VTFRJU0lURScsIHRydWUgKTsKZGVmaW5lKCAnTVVMVElTSVRFJywgdHJ1ZSApOwpkZWZpbmUoICdTVUJET01BSU5fSU5TVEFMTCcsIHskc3ViZG9tYWluX2V4cG9ydH0gKTsKXCRiYXNlID0gJ3skYXNzb2NfYXJnc1snYmFzZSddfSc7CmRlZmluZSggJ0RPTUFJTl9DVVJSRU5UX1NJVEUnLCAneyRkb21haW59JyApOwpkZWZpbmUoICdQQVRIX0NVUlJFTlRfU0lURScsICd7JGFzc29jX2FyZ3NbJ2Jhc2UnXX0nICk7CmRlZmluZSggJ1NJVEVfSURfQ1VSUkVOVF9TSVRFJywgeyRzaXRlX2lkfSApOwpkZWZpbmUoICdCTE9HX0lEX0NVUlJFTlRfU0lURScsIDEgKTsKRU9UOwoKCQkJJHdwX2NvbmZpZ19wYXRoID0gVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpOwoJCQlpZiAoIHRydWUgPT09IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtY29uZmlnJyApICkgewoJCQkJV1BfQ0xJOjpsb2coICJBZGRpdGlvbiBvZiBtdWx0aXNpdGUgY29uc3RhbnRzIHRvICd3cC1jb25maWcucGhwJyBza2lwcGVkLiBZb3UgbmVlZCB0byBhZGQgdGhlbSBtYW51YWxseTpcbnskbXNfY29uZmlnfSIgKTsKCQkJfSBlbHNlaWYgKCBpc193cml0YWJsZSggJHdwX2NvbmZpZ19wYXRoICkgJiYgc2VsZjo6bW9kaWZ5X3dwX2NvbmZpZyggJG1zX2NvbmZpZyApICkgewoJCQkJV1BfQ0xJOjpsb2coICJBZGRlZCBtdWx0aXNpdGUgY29uc3RhbnRzIHRvICd3cC1jb25maWcucGhwJy4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJNdWx0aXNpdGUgY29uc3RhbnRzIGNvdWxkIG5vdCBiZSB3cml0dGVuIHRvICd3cC1jb25maWcucGhwJy4gWW91IG1heSBuZWVkIHRvIGFkZCB0aGVtIG1hbnVhbGx5OlxueyRtc19jb25maWd9IiApOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyogTXVsdGlzaXRlIGNvbnN0YW50cyBhcmUgZGVmaW5lZCwgdGhlcmVmb3JlIHdlIGFscmVhZHkgaGF2ZSBhbiBlbXB0eSBzaXRlX2FkbWlucyBzaXRlIG1ldGEuCgkJCSAqCgkJCSAqIENvZGUgYmFzZWQgb24gcGFydHMgb2YgZGVsZXRlX25ldHdvcmtfb3B0aW9uLiAqLwoJCQkkcm93cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIlNFTEVDVCBtZXRhX2lkLCBzaXRlX2lkIEZST00geyR3cGRiLT5zaXRlbWV0YX0gV0hFUkUgbWV0YV9rZXkgPSAnc2l0ZV9hZG1pbnMnIEFORCBtZXRhX3ZhbHVlID0gJyciICk7CgoJCQlmb3JlYWNoICggJHJvd3MgYXMgJHJvdyApIHsKCQkJCXdwX2NhY2hlX2RlbGV0ZSggInskcm93LT5zaXRlX2lkfTpzaXRlX2FkbWlucyIsICdzaXRlLW9wdGlvbnMnICk7CgoJCQkJJHdwZGItPmRlbGV0ZSgKCQkJCQkkd3BkYi0+c2l0ZW1ldGEsCgkJCQkJWyAnbWV0YV9pZCcgPT4gJHJvdy0+bWV0YV9pZCBdCgkJCQkpOwoJCQl9CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvLyBjb3BpZWQgZnJvbSBwb3B1bGF0ZV9uZXR3b3JrKCkKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZV9pbml0aWFsX2Jsb2coICRuZXR3b3JrX2lkLCAkYmxvZ19pZCwgJGRvbWFpbiwgJHBhdGgsCgkJJHN1YmRvbWFpbl9pbnN0YWxsLCAkc2l0ZV91c2VyICkgewoJCWdsb2JhbCAkd3BkYiwgJGN1cnJlbnRfc2l0ZSwgJHdwX3Jld3JpdGU7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBUaGlzIGlzIG1lYW50IHRvIHJlcGxhY2UgQ29yZSBmdW5jdGlvbmFsaXR5LgoJCSRjdXJyZW50X3NpdGUgICAgICAgICAgICA9IG5ldyBzdGRDbGFzcygpOwoJCSRjdXJyZW50X3NpdGUtPmRvbWFpbiAgICA9ICRkb21haW47CgkJJGN1cnJlbnRfc2l0ZS0+cGF0aCAgICAgID0gJHBhdGg7CgkJJGN1cnJlbnRfc2l0ZS0+c2l0ZV9uYW1lID0gdWNmaXJzdCggJGRvbWFpbiApOwoJCSRibG9nX2RhdGEgICAgICAgICAgICAgICA9IFsKCQkJJ3NpdGVfaWQnICAgID0+ICRuZXR3b3JrX2lkLAoJCQknZG9tYWluJyAgICAgPT4gJGRvbWFpbiwKCQkJJ3BhdGgnICAgICAgID0+ICRwYXRoLAoJCQkncmVnaXN0ZXJlZCcgPT4gY3VycmVudF90aW1lKCAnbXlzcWwnICksCgkJXTsKCQkkd3BkYi0+aW5zZXJ0KCAkd3BkYi0+YmxvZ3MsICRibG9nX2RhdGEgKTsKCQkkY3VycmVudF9zaXRlLT5ibG9nX2lkID0gJHdwZGItPmluc2VydF9pZDsKCQkkYmxvZ19pZCAgICAgICAgICAgICAgID0gJHdwZGItPmluc2VydF9pZDsKCQl1cGRhdGVfdXNlcl9tZXRhKCAkc2l0ZV91c2VyLT5JRCwgJ3NvdXJjZV9kb21haW4nLCAkZG9tYWluICk7CgkJdXBkYXRlX3VzZXJfbWV0YSggJHNpdGVfdXNlci0+SUQsICdwcmltYXJ5X2Jsb2cnLCAkYmxvZ19pZCApOwoKCQlpZiAoICRzdWJkb21haW5faW5zdGFsbCApIHsKCQkJJHdwX3Jld3JpdGUtPnNldF9wZXJtYWxpbmtfc3RydWN0dXJlKCAnLyV5ZWFyJS8lbW9udGhudW0lLyVkYXklLyVwb3N0bmFtZSUvJyApOwoJCX0gZWxzZSB7CgkJCSR3cF9yZXdyaXRlLT5zZXRfcGVybWFsaW5rX3N0cnVjdHVyZSggJy9ibG9nLyV5ZWFyJS8lbW9udGhudW0lLyVkYXklLyVwb3N0bmFtZSUvJyApOwoJCX0KCgkJZmx1c2hfcmV3cml0ZV9ydWxlcygpOwoJfQoKCS8vIGNvcGllZCBmcm9tIHBvcHVsYXRlX25ldHdvcmsoKQoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYWRkX3NpdGVfYWRtaW5zKCAkc2l0ZV91c2VyICkgewoJCSRzaXRlX2FkbWlucyA9IFsgJHNpdGVfdXNlci0+dXNlcl9sb2dpbiBdOwoJCSR1c2VycyAgICAgICA9IGdldF91c2VycyggWyAnZmllbGRzJyA9PiBbICdJRCcsICd1c2VyX2xvZ2luJyBdIF0gKTsKCQlpZiAoICR1c2VycyApIHsKCQkJZm9yZWFjaCAoICR1c2VycyBhcyAkdXNlciApIHsKCQkJCWlmICggaXNfc3VwZXJfYWRtaW4oICR1c2VyLT5JRCApCgkJCQkJJiYgISBpbl9hcnJheSggJHVzZXItPnVzZXJfbG9naW4sICRzaXRlX2FkbWlucywgdHJ1ZSApICkgewoJCQkJCSRzaXRlX2FkbWluc1tdID0gJHVzZXItPnVzZXJfbG9naW47CgkJCQl9CgkJCX0KCQl9CgoJCXVwZGF0ZV9zaXRlX29wdGlvbiggJ3NpdGVfYWRtaW5zJywgJHNpdGVfYWRtaW5zICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gbW9kaWZ5X3dwX2NvbmZpZyggJGNvbnRlbnQgKSB7CgkJJHdwX2NvbmZpZ19wYXRoID0gVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpOwoKCQkkdG9rZW4gICAgICAgICAgID0gIi8qIFRoYXQncyBhbGwsIHN0b3AgZWRpdGluZyEiOwoJCSRjb25maWdfY29udGVudHMgPSBmaWxlX2dldF9jb250ZW50cyggJHdwX2NvbmZpZ19wYXRoICk7CgkJaWYgKCBmYWxzZSA9PT0gc3RycG9zKCAkY29uZmlnX2NvbnRlbnRzLCAkdG9rZW4gKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJbGlzdCggJGJlZm9yZSwgJGFmdGVyICkgPSBleHBsb2RlKCAkdG9rZW4sICRjb25maWdfY29udGVudHMgKTsKCgkJJGNvbnRlbnQgPSB0cmltKCAkY29udGVudCApOwoKCQlmaWxlX3B1dF9jb250ZW50cygKCQkJJHdwX2NvbmZpZ19wYXRoLAoJCQkieyRiZWZvcmV9XG5cbnskY29udGVudH1cblxueyR0b2tlbn17JGFmdGVyfSIKCQkpOwoKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfY2xlYW5fYmFzZWRvbWFpbigpIHsKCQkkZG9tYWluID0gcHJlZ19yZXBsYWNlKCAnfGh0dHBzPzovL3wnLCAnJywgZ2V0X29wdGlvbiggJ3NpdGV1cmwnICkgKTsKCQkkc2xhc2ggID0gc3RycG9zKCAkZG9tYWluLCAnLycgKTsKCQlpZiAoIGZhbHNlICE9PSAkc2xhc2ggKSB7CgkJCSRkb21haW4gPSBzdWJzdHIoICRkb21haW4sIDAsICRzbGFzaCApOwoJCX0KCQlyZXR1cm4gJGRvbWFpbjsKCX0KCgkvKioKCSAqIERpc3BsYXlzIHRoZSBXb3JkUHJlc3MgdmVyc2lvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZXh0cmFdCgkgKiA6IFNob3cgZXh0ZW5kZWQgdmVyc2lvbiBpbmZvcm1hdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERpc3BsYXkgdGhlIFdvcmRQcmVzcyB2ZXJzaW9uCgkgKiAgICAgJCB3cCBjb3JlIHZlcnNpb24KCSAqICAgICA0LjUuMgoJICoKCSAqICAgICAjIERpc3BsYXkgV29yZFByZXNzIHZlcnNpb24gYWxvbmcgd2l0aCBvdGhlciBpbmZvcm1hdGlvbgoJICogICAgICQgd3AgY29yZSB2ZXJzaW9uIC0tZXh0cmEKCSAqICAgICBXb3JkUHJlc3MgdmVyc2lvbjogNC41LjIKCSAqICAgICBEYXRhYmFzZSByZXZpc2lvbjogMzY2ODYKCSAqICAgICBUaW55TUNFIHZlcnNpb246ICAgNC4zMTAgKDQzMTAtMjAxNjA0MTgpCgkgKiAgICAgUGFja2FnZSBsYW5ndWFnZTogIGVuX1VTCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHZlcnNpb24oICRhcmdzID0gW10sICRhc3NvY19hcmdzID0gW10gKSB7CgkJJGRldGFpbHMgPSBzZWxmOjpnZXRfd3BfZGV0YWlscygpOwoKCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZXh0cmEnICkgKSB7CgkJCVdQX0NMSTo6bGluZSggJGRldGFpbHNbJ3dwX3ZlcnNpb24nXSApOwoJCQlyZXR1cm47CgkJfQoKCQkkbWF0Y2ggICAgICAgICAgICAgICAgICAgPSBbXTsKCQkkZm91bmRfdmVyc2lvbiAgICAgICAgICAgPSBwcmVnX21hdGNoKCAnLyhcZCkoXGQrKS0vJywgJGRldGFpbHNbJ3RpbnltY2VfdmVyc2lvbiddLCAkbWF0Y2ggKTsKCQkkaHVtYW5fcmVhZGFibGVfdGlueV9tY2UgPSAkZm91bmRfdmVyc2lvbiA/ICJ7JG1hdGNoWzFdfS57JG1hdGNoWzJdfSIgOiAnJzsKCgkJZWNobyBVdGlsc1xtdXN0YWNoZV9yZW5kZXIoCgkJCXNlbGY6OmdldF90ZW1wbGF0ZV9wYXRoKCAndmVyc2lvbnMubXVzdGFjaGUnICksCgkJCVsKCQkJCSd3cC12ZXJzaW9uJyAgICA9PiAkZGV0YWlsc1snd3BfdmVyc2lvbiddLAoJCQkJJ2RiLXZlcnNpb24nICAgID0+ICRkZXRhaWxzWyd3cF9kYl92ZXJzaW9uJ10sCgkJCQknbG9jYWwtcGFja2FnZScgPT4gZW1wdHkoICRkZXRhaWxzWyd3cF9sb2NhbF9wYWNrYWdlJ10gKQoJCQkJCT8gJ2VuX1VTJwoJCQkJCTogJGRldGFpbHNbJ3dwX2xvY2FsX3BhY2thZ2UnXSwKCQkJCSdtY2UtdmVyc2lvbicgICA9PiAkaHVtYW5fcmVhZGFibGVfdGlueV9tY2UKCQkJCQk/ICJ7JGh1bWFuX3JlYWRhYmxlX3RpbnlfbWNlfSAoeyRkZXRhaWxzWyd0aW55bWNlX3ZlcnNpb24nXX0pIgoJCQkJCTogJGRldGFpbHNbJ3RpbnltY2VfdmVyc2lvbiddLAoJCQldCgkJKTsKCX0KCgkvKioKCSAqIEdldHMgdmVyc2lvbiBpbmZvcm1hdGlvbiBmcm9tIGB3cC1pbmNsdWRlcy92ZXJzaW9uLnBocGAuCgkgKgoJICogQHJldHVybiBhcnJheSB7CgkgKiAgICAgQHR5cGUgc3RyaW5nICR3cF92ZXJzaW9uIFRoZSBXb3JkUHJlc3MgdmVyc2lvbi4KCSAqICAgICBAdHlwZSBpbnQgJHdwX2RiX3ZlcnNpb24gVGhlIFdvcmRQcmVzcyBEQiByZXZpc2lvbi4KCSAqICAgICBAdHlwZSBzdHJpbmcgJHRpbnltY2VfdmVyc2lvbiBUaGUgVGlueU1DRSB2ZXJzaW9uLgoJICogICAgIEB0eXBlIHN0cmluZyAkd3BfbG9jYWxfcGFja2FnZSBUaGUgVGlueU1DRSB2ZXJzaW9uLgoJICogfQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfd3BfZGV0YWlscyggJGFic3BhdGggPSBBQlNQQVRIICkgewoJCSR2ZXJzaW9uc19wYXRoID0gJGFic3BhdGggLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnOwoKCQlpZiAoICEgaXNfcmVhZGFibGUoICR2ZXJzaW9uc19wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkiVGhpcyBkb2VzIG5vdCBzZWVtIHRvIGJlIGEgV29yZFByZXNzIGluc3RhbGxhdGlvbi5cbiIgLgoJCQkJJ1Bhc3MgLS1wYXRoPWBwYXRoL3RvL3dvcmRwcmVzc2Agb3IgcnVuIGB3cCBjb3JlIGRvd25sb2FkYC4nCgkJCSk7CgkJfQoKCQkkdmVyc2lvbl9jb250ZW50ID0gZmlsZV9nZXRfY29udGVudHMoICR2ZXJzaW9uc19wYXRoLCBudWxsLCBudWxsLCA2LCAyMDQ4ICk7CgoJCSR2YXJzICAgPSBbICd3cF92ZXJzaW9uJywgJ3dwX2RiX3ZlcnNpb24nLCAndGlueW1jZV92ZXJzaW9uJywgJ3dwX2xvY2FsX3BhY2thZ2UnIF07CgkJJHJlc3VsdCA9IFtdOwoKCQlmb3JlYWNoICggJHZhcnMgYXMgJHZhcl9uYW1lICkgewoJCQkkcmVzdWx0WyAkdmFyX25hbWUgXSA9IHNlbGY6OmZpbmRfdmFyKCAkdmFyX25hbWUsICR2ZXJzaW9uX2NvbnRlbnQgKTsKCQl9CgoJCXJldHVybiAkcmVzdWx0OwoJfQoKCS8qKgoJICogR2V0cyB0aGUgdGVtcGxhdGUgcGF0aCBiYXNlZCBvbiBpbnN0YWxsYXRpb24gdHlwZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3RlbXBsYXRlX3BhdGgoICR0ZW1wbGF0ZSApIHsKCQkkY29tbWFuZF9yb290ICA9IFV0aWxzXHBoYXJfc2FmZV9wYXRoKCBkaXJuYW1lKCBfX0RJUl9fICkgKTsKCQkkdGVtcGxhdGVfcGF0aCA9ICJ7JGNvbW1hbmRfcm9vdH0vdGVtcGxhdGVzL3skdGVtcGxhdGV9IjsKCgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkdGVtcGxhdGVfcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgZmluZCB7JHRlbXBsYXRlfSIgKTsKCQl9CgoJCXJldHVybiAkdGVtcGxhdGVfcGF0aDsKCX0KCgkvKioKCSAqIFNlYXJjaGVzIGZvciB0aGUgdmFsdWUgYXNzaWduZWQgdG8gdmFyaWFibGUgYCR2YXJfbmFtZWAgaW4gUEhQIGNvZGUgYCRjb2RlYC4KCSAqCgkgKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gbWF0Y2hpbmcgdGhlIGBcJFZBUl9OQU1FID0gKFteO10rKWAgcmVndWxhciBleHByZXNzaW9uIGFuZCByZXR1cm5pbmcKCSAqIHRoZSBmaXJzdCBtYXRjaCBlaXRoZXIgYXMgYSBgc3RyaW5nYCBvciBhcyBhbiBgaW50ZWdlcmAgKGRlcGVuZGluZyBpZiBpdCdzIHN1cnJvdW5kZWQgYnkKCSAqIHF1b3RlcyBvciBub3QpLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHZhcl9uYW1lIFZhcmlhYmxlIG5hbWUgdG8gc2VhcmNoIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgUEhQIGNvZGUgdG8gc2VhcmNoIGluLgoJICoKCSAqIEByZXR1cm4gaW50fHN0cmluZ3xudWxsCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGZpbmRfdmFyKCAkdmFyX25hbWUsICRjb2RlICkgewoJCSRzdGFydCA9IHN0cnBvcyggJGNvZGUsICckJyAuICR2YXJfbmFtZSAuICcgPSAnICk7CgoJCWlmICggISAkc3RhcnQgKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJJHN0YXJ0ID0gJHN0YXJ0ICsgc3RybGVuKCAkdmFyX25hbWUgKSArIDM7CgkJJGVuZCAgID0gc3RycG9zKCAkY29kZSwgJzsnLCAkc3RhcnQgKTsKCgkJJHZhbHVlID0gc3Vic3RyKCAkY29kZSwgJHN0YXJ0LCAkZW5kIC0gJHN0YXJ0ICk7CgoJCXJldHVybiB0cmltKCAkdmFsdWUsICIgJyIgKTsKCX0KCgkvKioKCSAqIFNlY3VyaXR5IGNvcHkgb2YgdGhlIGNvcmUgZnVuY3Rpb24gd2l0aCBSZXF1ZXN0cyAtIEdldHMgdGhlIGNoZWNrc3VtcyBmb3IgdGhlIGdpdmVuIHZlcnNpb24gb2YgV29yZFByZXNzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gIFZlcnNpb24gc3RyaW5nIHRvIHF1ZXJ5LgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlICAgTG9jYWxlIHRvIHF1ZXJ5LgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgV2hldGhlciB0byByZXRyeSB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gb24gVExTIGhhbmRzaGFrZSBmYWlsdXJlLgoJICogQHJldHVybiBzdHJpbmd8YXJyYXkgU3RyaW5nIG1lc3NhZ2Ugb24gZmFpbHVyZS4gQW4gYXJyYXkgb2YgY2hlY2tzdW1zIG9uIHN1Y2Nlc3MuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9jb3JlX2NoZWNrc3VtcyggJHZlcnNpb24sICRsb2NhbGUsICRpbnNlY3VyZSApIHsKCQkkcXVlcnkgPSBodHRwX2J1aWxkX3F1ZXJ5KCBjb21wYWN0KCAndmVyc2lvbicsICdsb2NhbGUnICksIG51bGwsICcmJyApOwoJCSR1cmwgICA9ICJodHRwczovL2FwaS53b3JkcHJlc3Mub3JnL2NvcmUvY2hlY2tzdW1zLzEuMC8/eyRxdWVyeX0iOwoKCQkkaGVhZGVycyA9IFsgJ0FjY2VwdCcgPT4gJ2FwcGxpY2F0aW9uL2pzb24nIF07CgkJJG9wdGlvbnMgPSBbCgkJCSd0aW1lb3V0JyAgPT4gMzAsCgkJCSdpbnNlY3VyZScgPT4gJGluc2VjdXJlLAoJCV07CgoJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICR1cmwsIG51bGwsICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQlpZiAoICEgJHJlc3BvbnNlLT5zdWNjZXNzIHx8IDIwMCAhPT0gKGludCkgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJcmV0dXJuICJDaGVja3N1bSByZXF1ZXN0ICd7JHVybH0nIGZhaWxlZCAoSFRUUCB7JHJlc3BvbnNlLT5zdGF0dXNfY29kZX0pLiI7CgkJfQoKCQkkYm9keSA9IHRyaW0oICRyZXNwb25zZS0+Ym9keSApOwoJCSRib2R5ID0ganNvbl9kZWNvZGUoICRib2R5LCB0cnVlICk7CgoJCWlmICggISBpc19hcnJheSggJGJvZHkgKQoJCQl8fCAhIGlzc2V0KCAkYm9keVsnY2hlY2tzdW1zJ10gKQoJCQl8fCAhIGlzX2FycmF5KCAkYm9keVsnY2hlY2tzdW1zJ10gKSApIHsKCQkJcmV0dXJuICJDaGVja3N1bXMgbm90IGF2YWlsYWJsZSBmb3IgV29yZFByZXNzIHskdmVyc2lvbn0veyRsb2NhbGV9LiI7CgkJfQoKCQlyZXR1cm4gJGJvZHlbJ2NoZWNrc3VtcyddOwoJfQoKCS8qKgoJICogVXBkYXRlcyBXb3JkUHJlc3MgdG8gYSBuZXdlciB2ZXJzaW9uLgoJICoKCSAqIERlZmF1bHRzIHRvIHVwZGF0aW5nIFdvcmRQcmVzcyB0byB0aGUgbGF0ZXN0IHZlcnNpb24uCgkgKgoJICogSWYgeW91IHNlZSAiRXJyb3I6IEFub3RoZXIgdXBkYXRlIGlzIGN1cnJlbnRseSBpbiBwcm9ncmVzcy4iLCB5b3UgbWF5CgkgKiBuZWVkIHRvIHJ1biBgd3Agb3B0aW9uIGRlbGV0ZSBjb3JlX3VwZGF0ZXIubG9ja2AgYWZ0ZXIgdmVyaWZ5aW5nIGFub3RoZXIKCSAqIHVwZGF0ZSBpc24ndCBhY3R1YWxseSBydW5uaW5nLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHppcD5dCgkgKiA6IFBhdGggdG8gemlwIGZpbGUgdG8gdXNlLCBpbnN0ZWFkIG9mIGRvd25sb2FkaW5nIGZyb20gd29yZHByZXNzLm9yZy4KCSAqCgkgKiBbLS1taW5vcl0KCSAqIDogT25seSBwZXJmb3JtIHVwZGF0ZXMgZm9yIG1pbm9yIHJlbGVhc2VzIChlLmcuIHVwZGF0ZSBmcm9tIFdQIDQuMyB0byA0LjMuMyBpbnN0ZWFkIG9mIDQuNC4yKS4KCSAqCgkgKiBbLS12ZXJzaW9uPTx2ZXJzaW9uPl0KCSAqIDogVXBkYXRlIHRvIGEgc3BlY2lmaWMgdmVyc2lvbiwgaW5zdGVhZCBvZiB0byB0aGUgbGF0ZXN0IHZlcnNpb24uIEFsdGVybmF0aXZlbHkgYWNjZXB0cyAnbmlnaHRseScuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IFVwZGF0ZSBldmVuIHdoZW4gaW5zdGFsbGVkIFdQIHZlcnNpb24gaXMgZ3JlYXRlciB0aGFuIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbi4KCSAqCgkgKiBbLS1sb2NhbGU9PGxvY2FsZT5dCgkgKiA6IFNlbGVjdCB3aGljaCBsYW5ndWFnZSB5b3Ugd2FudCB0byBkb3dubG9hZC4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWQgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGlmIFRMUyBoYW5kc2hha2UgZmFpbHMuIE5vdGU6IFRoaXMgbWFrZXMgdGhlIHJlcXVlc3QgdnVsbmVyYWJsZSB0byBhIE1JVE0gYXR0YWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVXBkYXRlIFdvcmRQcmVzcwoJICogICAgICQgd3AgY29yZSB1cGRhdGUKCSAqICAgICBVcGRhdGluZyB0byB2ZXJzaW9uIDQuNS4yIChlbl9VUykuLi4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3JlbGVhc2Uvd29yZHByZXNzLTQuNS4yLW5vLWNvbnRlbnQuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBDbGVhbmluZyB1cCBmaWxlcy4uLgoJICogICAgIE5vIGZpbGVzIGZvdW5kIHRoYXQgbmVlZCBjbGVhbmluZyB1cAoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqCgkgKiAgICAgIyBVcGRhdGUgV29yZFByZXNzIHRvIGxhdGVzdCB2ZXJzaW9uIG9mIDMuOCByZWxlYXNlCgkgKiAgICAgJCB3cCBjb3JlIHVwZGF0ZSAtLXZlcnNpb249My44IC4uL2xhdGVzdC56aXAKCSAqICAgICBVcGRhdGluZyB0byB2ZXJzaW9uIDMuOCAoKS4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgQ2xlYW5pbmcgdXAgZmlsZXMuLi4KCSAqICAgICBGaWxlIHJlbW92ZWQ6IHdwLWFkbWluL2pzL3RhZ3MtYm94LmpzCgkgKiAgICAgLi4uCgkgKiAgICAgRmlsZSByZW1vdmVkOiB3cC1hZG1pbi9qcy91cGRhdGVzLm1pbi4KCSAqICAgICAzNzcgZmlsZXMgY2xlYW5lZCB1cAoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqCgkgKiAgICAgIyBVcGRhdGUgV29yZFByZXNzIHRvIDMuMSBmb3JjZWZ1bGx5CgkgKiAgICAgJCB3cCBjb3JlIHVwZGF0ZSAtLXZlcnNpb249My4xIC0tZm9yY2UKCSAqICAgICBVcGRhdGluZyB0byB2ZXJzaW9uIDMuMSAoZW5fVVMpLi4uCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3dvcmRwcmVzcy0zLjEuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBXYXJuaW5nOiBDaGVja3N1bXMgbm90IGF2YWlsYWJsZSBmb3IgV29yZFByZXNzIDMuMS9lbl9VUy4gUGxlYXNlIGNsZWFudXAgZmlsZXMgbWFudWFsbHkuCgkgKiAgICAgU3VjY2VzczogV29yZFByZXNzIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICoKCSAqIEBhbGlhcyB1cGdyYWRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwX3ZlcnNpb247CgoJCSR1cGRhdGUgICA9IG51bGw7CgkJJHVwZ3JhZGVyID0gJ1dQX0NMSVxcQ29yZVxcQ29yZVVwZ3JhZGVyJzsKCgkJaWYgKCAndHJ1bmsnID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2ZXJzaW9uJyApICkgewoJCQkkYXNzb2NfYXJnc1sndmVyc2lvbiddID0gJ25pZ2h0bHknOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkYXJnc1swXSApICkgewoKCQkJLy8gWklQIHBhdGggb3IgVVJMIGlzIGdpdmVuCgkJCSR1cGdyYWRlciA9ICdXUF9DTElcXENvcmVcXE5vbkRlc3RydWN0aXZlQ29yZVVwZ3JhZGVyJzsKCQkJJHZlcnNpb24gID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndmVyc2lvbicgKTsKCgkJCSR1cGRhdGUgPSAob2JqZWN0KSBbCgkJCQkncmVzcG9uc2UnID0+ICd1cGdyYWRlJywKCQkJCSdjdXJyZW50JyAgPT4gJHZlcnNpb24sCgkJCQknZG93bmxvYWQnID0+ICRhcmdzWzBdLAoJCQkJJ3BhY2thZ2VzJyA9PiAob2JqZWN0KSBbCgkJCQkJJ3BhcnRpYWwnICAgICA9PiBudWxsLAoJCQkJCSduZXdfYnVuZGxlZCcgPT4gbnVsbCwKCQkJCQknbm9fY29udGVudCcgID0+IG51bGwsCgkJCQkJJ2Z1bGwnICAgICAgICA9PiAkYXJnc1swXSwKCQkJCV0sCgkJCQkndmVyc2lvbicgID0+ICR2ZXJzaW9uLAoJCQkJJ2xvY2FsZScgICA9PiBudWxsLAoJCQldOwoKCQl9IGVsc2VpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1sndmVyc2lvbiddICkgKSB7CgoJCQkvLyBVcGRhdGUgdG8gbmV4dCByZWxlYXNlCgkJCXdwX3ZlcnNpb25fY2hlY2soKTsKCQkJJGZyb21fYXBpID0gZ2V0X3NpdGVfdHJhbnNpZW50KCAndXBkYXRlX2NvcmUnICk7CgoJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ21pbm9yJyApICkgewoJCQkJZm9yZWFjaCAoICRmcm9tX2FwaS0+dXBkYXRlcyBhcyAkb2ZmZXIgKSB7CgkJCQkJJHNlbV92ZXIgPSBVdGlsc1xnZXRfbmFtZWRfc2VtX3ZlciggJG9mZmVyLT52ZXJzaW9uLCAkd3BfdmVyc2lvbiApOwoJCQkJCWlmICggISAkc2VtX3ZlciB8fCAncGF0Y2gnICE9PSAkc2VtX3ZlciApIHsKCQkJCQkJY29udGludWU7CgkJCQkJfQoJCQkJCSR1cGRhdGUgPSAkb2ZmZXI7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpZiAoIGVtcHR5KCAkdXBkYXRlICkgKSB7CgkJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnV29yZFByZXNzIGlzIGF0IHRoZSBsYXRlc3QgbWlub3IgcmVsZWFzZS4nICk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJaWYgKCAhIGVtcHR5KCAkZnJvbV9hcGktPnVwZGF0ZXMgKSApIHsKCQkJCQlsaXN0KCAkdXBkYXRlICkgPSAkZnJvbV9hcGktPnVwZGF0ZXM7CgkJCQl9CgkJCX0KCQl9IGVsc2VpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSwgJzwnICkKCQkJfHwgJ25pZ2h0bHknID09PSAkYXNzb2NfYXJnc1sndmVyc2lvbiddCgkJCXx8IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApICkgewoKCQkJLy8gU3BlY2lmaWMgdmVyc2lvbiBpcyBnaXZlbgoJCQkkdmVyc2lvbiA9ICRhc3NvY19hcmdzWyd2ZXJzaW9uJ107CgkJCSRsb2NhbGUgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbG9jYWxlJywgZ2V0X2xvY2FsZSgpICk7CgoJCQkkbmV3X3BhY2thZ2UgPSAkdGhpcy0+Z2V0X2Rvd25sb2FkX3VybCggJHZlcnNpb24sICRsb2NhbGUgKTsKCgkJCSR1cGRhdGUgPSAob2JqZWN0KSBbCgkJCQkncmVzcG9uc2UnID0+ICd1cGdyYWRlJywKCQkJCSdjdXJyZW50JyAgPT4gJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSwKCQkJCSdkb3dubG9hZCcgPT4gJG5ld19wYWNrYWdlLAoJCQkJJ3BhY2thZ2VzJyA9PiAob2JqZWN0KSBbCgkJCQkJJ3BhcnRpYWwnICAgICA9PiBudWxsLAoJCQkJCSduZXdfYnVuZGxlZCcgPT4gbnVsbCwKCQkJCQknbm9fY29udGVudCcgID0+IG51bGwsCgkJCQkJJ2Z1bGwnICAgICAgICA9PiAkbmV3X3BhY2thZ2UsCgkJCQldLAoJCQkJJ3ZlcnNpb24nICA9PiAkdmVyc2lvbiwKCQkJCSdsb2NhbGUnICAgPT4gJGxvY2FsZSwKCQkJXTsKCgkJfQoKCQlpZiAoICEgZW1wdHkoICR1cGRhdGUgKQoJCQkmJiAoICR1cGRhdGUtPnZlcnNpb24gIT09ICR3cF92ZXJzaW9uCgkJCXx8IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApICkgKSB7CgoJCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy91cGdyYWRlLnBocCc7CgoJCQlpZiAoICR1cGRhdGUtPnZlcnNpb24gKSB7CgkJCQlXUF9DTEk6OmxvZyggIlVwZGF0aW5nIHRvIHZlcnNpb24geyR1cGRhdGUtPnZlcnNpb259ICh7JHVwZGF0ZS0+bG9jYWxlfSkuLi4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZyggJ1N0YXJ0aW5nIHVwZGF0ZS4uLicgKTsKCQkJfQoKCQkJJGZyb21fdmVyc2lvbiA9ICR3cF92ZXJzaW9uOwoJCQkkaW5zZWN1cmUgICAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCgkJCSRHTE9CQUxTWyd3cGNsaV9jb3JlX3VwZGF0ZV9vYmonXSA9ICR1cGRhdGU7CgkJCSRyZXN1bHQgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFV0aWxzXGdldF91cGdyYWRlciggJHVwZ3JhZGVyLCAkaW5zZWN1cmUgKS0+dXBncmFkZSggJHVwZGF0ZSApOwoJCQl1bnNldCggJEdMT0JBTFNbJ3dwY2xpX2NvcmVfdXBkYXRlX29iaiddICk7CgoJCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCQkkbWVzc2FnZSA9IFdQX0NMSTo6ZXJyb3JfdG9fc3RyaW5nKCAkcmVzdWx0ICk7CgkJCQlpZiAoICd1cF90b19kYXRlJyAhPT0gJHJlc3VsdC0+Z2V0X2Vycm9yX2NvZGUoKSApIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAkbWVzc2FnZSApOwoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICRtZXNzYWdlICk7CgkJCQl9CgkJCX0gZWxzZSB7CgoJCQkJJHRvX3ZlcnNpb24gPSAnJzsKCQkJCWlmICggZmlsZV9leGlzdHMoIEFCU1BBVEggLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnICkgKSB7CgkJCQkJJHdwX2RldGFpbHMgPSBzZWxmOjpnZXRfd3BfZGV0YWlscygpOwoJCQkJCSR0b192ZXJzaW9uID0gJHdwX2RldGFpbHNbJ3dwX3ZlcnNpb24nXTsKCQkJCX0KCgkJCQkkbG9jYWxlID0gKHN0cmluZykgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbG9jYWxlJywgZ2V0X2xvY2FsZSgpICk7CgkJCQkkdGhpcy0+Y2xlYW51cF9leHRyYV9maWxlcyggJGZyb21fdmVyc2lvbiwgJHRvX3ZlcnNpb24sICRsb2NhbGUsICRpbnNlY3VyZSApOwoKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ1dvcmRQcmVzcyB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4nICk7CgkJCX0KCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdXb3JkUHJlc3MgaXMgdXAgdG8gZGF0ZS4nICk7CgkJfQoJfQoKCS8qKgoJICogUnVucyB0aGUgV29yZFByZXNzIGRhdGFiYXNlIHVwZGF0ZSBwcm9jZWR1cmUuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogVXBkYXRlIGRhdGFiYXNlcyBmb3IgYWxsIHNpdGVzIG9uIGEgbmV0d29yawoJICoKCSAqIFstLWRyeS1ydW5dCgkgKiA6IENvbXBhcmUgZGF0YWJhc2UgdmVyc2lvbnMgd2l0aG91dCBwZXJmb3JtaW5nIHRoZSB1cGRhdGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgdGhlIFdvcmRQcmVzcyBkYXRhYmFzZQoJICogICAgICQgd3AgY29yZSB1cGRhdGUtZGIKCSAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgc3VjY2Vzc2Z1bGx5IGZyb20gZGIgdmVyc2lvbiAzNjY4NiB0byAzNTcwMC4KCSAqCgkgKiAgICAgIyBVcGRhdGUgZGF0YWJhc2VzIGZvciBhbGwgc2l0ZXMgb24gYSBuZXR3b3JrCgkgKiAgICAgJCB3cCBjb3JlIHVwZGF0ZS1kYiAtLW5ldHdvcmsKCSAqICAgICBXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgc3VjY2Vzc2Z1bGx5IGZyb20gZGIgdmVyc2lvbiAzNTcwMCB0byAyOTYzMCBvbiBleGFtcGxlLmNvbS8KCSAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgb24gMTIzLzEyMyBzaXRlcwoJICoKCSAqIEBzdWJjb21tYW5kIHVwZGF0ZS1kYgoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlX2RiKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiLCAkd3BfZGJfdmVyc2lvbiwgJHdwX2N1cnJlbnRfZGJfdmVyc2lvbjsKCgkJJG5ldHdvcmsgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduZXR3b3JrJyApOwoJCWlmICggJG5ldHdvcmsgJiYgISBpc19tdWx0aXNpdGUoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkJfQoKCQkkZHJ5X3J1biA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RyeS1ydW4nICk7CgkJaWYgKCAkZHJ5X3J1biApIHsKCQkJV1BfQ0xJOjpsb2coICdQZXJmb3JtaW5nIGEgZHJ5IHJ1biwgd2l0aCBubyBkYXRhYmFzZSBtb2RpZmljYXRpb24uJyApOwoJCX0KCgkJaWYgKCAkbmV0d29yayApIHsKCQkJJGl0ZXJhdG9yX2FyZ3MgPSBbCgkJCQkndGFibGUnID0+ICR3cGRiLT5ibG9ncywKCQkJCSd3aGVyZScgPT4gWwoJCQkJCSdzcGFtJyAgICAgPT4gMCwKCQkJCQknZGVsZXRlZCcgID0+IDAsCgkJCQkJJ2FyY2hpdmVkJyA9PiAwLAoJCQkJXSwKCQkJXTsKCQkJJGl0ICAgICAgICAgICAgPSBuZXcgVGFibGVJdGVyYXRvciggJGl0ZXJhdG9yX2FyZ3MgKTsKCQkJJHN1Y2Nlc3MgICAgICAgPSAwOwoJCQkkdG90YWwgICAgICAgICA9IDA7CgkJCSRzaXRlX2lkcyAgICAgID0gW107CgkJCWZvcmVhY2ggKCAkaXQgYXMgJGJsb2cgKSB7CgkJCQkkdG90YWwrKzsKCQkJCSRzaXRlX2lkc1tdID0gJGJsb2ctPnNpdGVfaWQ7CgkJCQkkdXJsICAgICAgICA9ICRibG9nLT5kb21haW4gLiAkYmxvZy0+cGF0aDsKCQkJCSRjbWQgICAgICAgID0gIi0tdXJsPXskdXJsfSBjb3JlIHVwZGF0ZS1kYiI7CgkJCQlpZiAoICRkcnlfcnVuICkgewoJCQkJCSRjbWQgLj0gJyAtLWRyeS1ydW4nOwoJCQkJfQoJCQkJJHByb2Nlc3MgPSBXUF9DTEk6OnJ1bmNvbW1hbmQoCgkJCQkJJGNtZCwKCQkJCQlbCgkJCQkJCSdyZXR1cm4nICAgICA9PiAnYWxsJywKCQkJCQkJJ2V4aXRfZXJyb3InID0+IGZhbHNlLAoJCQkJCV0KCQkJCSk7CgkJCQlpZiAoIDAgPT09IChpbnQpICRwcm9jZXNzLT5yZXR1cm5fY29kZSApIHsKCQkJCQkvLyBTZWUgaWYgd2UgY2FuIHBhcnNlIHRoZSBzdGRvdXQKCQkJCQlpZiAoIHByZWdfbWF0Y2goICcjU3VjY2VzczogKC4rKSMnLCAkcHJvY2Vzcy0+c3Rkb3V0LCAkbWF0Y2hlcyApICkgewoJCQkJCQkkbWVzc2FnZSA9IHJ0cmltKCAkbWF0Y2hlc1sxXSwgJy4nICk7CgkJCQkJCSRtZXNzYWdlID0gInskbWVzc2FnZX0gb24geyR1cmx9IjsKCQkJCQl9IGVsc2UgewoJCQkJCQkkbWVzc2FnZSA9ICJEYXRhYmFzZSB1cGdyYWRlZCBzdWNjZXNzZnVsbHkgb24geyR1cmx9IjsKCQkJCQl9CgkJCQkJV1BfQ0xJOjpsb2coICRtZXNzYWdlICk7CgkJCQkJJHN1Y2Nlc3MrKzsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiRGF0YWJhc2UgZmFpbGVkIHRvIHVwZ3JhZGUgb24geyR1cmx9IiApOwoJCQkJfQoJCQl9CgkJCWlmICggISAkZHJ5X3J1biAmJiAkdG90YWwgJiYgJHN1Y2Nlc3MgPT09ICR0b3RhbCApIHsKCQkJCWZvcmVhY2ggKCBhcnJheV91bmlxdWUoICRzaXRlX2lkcyApIGFzICRzaXRlX2lkICkgewoJCQkJCXVwZGF0ZV9tZXRhZGF0YSggJ3NpdGUnLCAkc2l0ZV9pZCwgJ3dwbXVfdXBncmFkZV9zaXRlJywgJHdwX2RiX3ZlcnNpb24gKTsKCQkJCX0KCQkJfQoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgb24geyRzdWNjZXNzfS97JHRvdGFsfSBzaXRlcy4iICk7CgkJfSBlbHNlIHsKCQkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvdXBncmFkZS5waHAnOwoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gUmVwbGFjaW5nIFdQIENvcmUgYmVoYXZpb3IgaXMgdGhlIGdvYWwgaGVyZS4KCQkJJHdwX2N1cnJlbnRfZGJfdmVyc2lvbiA9IChpbnQpIF9fZ2V0X29wdGlvbiggJ2RiX3ZlcnNpb24nICk7CgkJCWlmICggJHdwX2RiX3ZlcnNpb24gIT09ICR3cF9jdXJyZW50X2RiX3ZlcnNpb24gKSB7CgkJCQlpZiAoICRkcnlfcnVuICkgewoJCQkJCVdQX0NMSTo6c3VjY2VzcyggIldvcmRQcmVzcyBkYXRhYmFzZSB3aWxsIGJlIHVwZ3JhZGVkIGZyb20gZGIgdmVyc2lvbiB7JHdwX2N1cnJlbnRfZGJfdmVyc2lvbn0gdG8geyR3cF9kYl92ZXJzaW9ufS4iICk7CgkJCQl9IGVsc2UgewoJCQkJCS8vIFdQIHVwZ3JhZGUgaXNuJ3QgdG9vIGZ1c3N5IGFib3V0IGdlbmVyYXRpbmcgTXlTUUwgd2FybmluZ3Mgc3VjaCBhcyAiRHVwbGljYXRlIGtleSBuYW1lIiBkdXJpbmcgYW4gdXBncmFkZSBzbyBzdXBwcmVzcy4KCQkJCQkkd3BkYi0+c3VwcHJlc3NfZXJyb3JzKCk7CgoJCQkJCS8vIFdQIHVwZ3JhZGUgZXhwZWN0cyBgJF9TRVJWRVJbJ0hUVFBfSE9TVCddYCB0byBiZSBzZXQgaW4gYHdwX2d1ZXNzX3VybCgpYCwgb3RoZXJ3aXNlIGdldCBQSFAgbm90aWNlLgoJCQkJCWlmICggISBpc3NldCggJF9TRVJWRVJbJ0hUVFBfSE9TVCddICkgKSB7CgkJCQkJCSRfU0VSVkVSWydIVFRQX0hPU1QnXSA9ICdodHRwOi8vZXhhbXBsZS5jb20nOwoJCQkJCX0KCgkJCQkJd3BfdXBncmFkZSgpOwoKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgc3VjY2Vzc2Z1bGx5IGZyb20gZGIgdmVyc2lvbiB7JHdwX2N1cnJlbnRfZGJfdmVyc2lvbn0gdG8geyR3cF9kYl92ZXJzaW9ufS4iICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXb3JkUHJlc3MgZGF0YWJhc2UgYWxyZWFkeSBhdCBsYXRlc3QgZGIgdmVyc2lvbiB7JHdwX2RiX3ZlcnNpb259LiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEdldHMgZG93bmxvYWQgdXJsIGJhc2VkIG9uIHZlcnNpb24sIGxvY2FsZSBhbmQgZGVzaXJlZCBmaWxlIHR5cGUuCgkgKgoJICogQHBhcmFtICR2ZXJzaW9uCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGVfdHlwZQoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZG93bmxvYWRfdXJsKCAkdmVyc2lvbiwgJGxvY2FsZSA9ICdlbl9VUycsICRmaWxlX3R5cGUgPSAnemlwJyApIHsKCgkJaWYgKCAnbmlnaHRseScgPT09ICR2ZXJzaW9uICkgewoJCQlpZiAoICd6aXAnID09PSAkZmlsZV90eXBlICkgewoJCQkJcmV0dXJuICdodHRwczovL3dvcmRwcmVzcy5vcmcvbmlnaHRseS1idWlsZHMvd29yZHByZXNzLWxhdGVzdC56aXAnOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjplcnJvciggJ05pZ2h0bHkgYnVpbGRzIGFyZSBvbmx5IGF2YWlsYWJsZSBpbiAuemlwIGZvcm1hdC4nICk7CgkJCX0KCQl9CgoJCSRsb2NhbGVfc3ViZG9tYWluID0gJ2VuX1VTJyA9PT0gJGxvY2FsZSA/ICcnIDogc3Vic3RyKCAkbG9jYWxlLCAwLCAyICkgLiAnLic7CgkJJGxvY2FsZV9zdWZmaXggICAgPSAnZW5fVVMnID09PSAkbG9jYWxlID8gJycgOiAiLXskbG9jYWxlfSI7CgoJCXJldHVybiAiaHR0cHM6Ly97JGxvY2FsZV9zdWJkb21haW59d29yZHByZXNzLm9yZy93b3JkcHJlc3MteyR2ZXJzaW9ufXskbG9jYWxlX3N1ZmZpeH0ueyRmaWxlX3R5cGV9IjsKCX0KCgkvKioKCSAqIFJldHVybnMgdXBkYXRlIGluZm9ybWF0aW9uLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF91cGRhdGVzKCAkYXNzb2NfYXJncyApIHsKCQl3cF92ZXJzaW9uX2NoZWNrKCk7CgkJJGZyb21fYXBpID0gZ2V0X3NpdGVfdHJhbnNpZW50KCAndXBkYXRlX2NvcmUnICk7CgkJaWYgKCAhICRmcm9tX2FwaSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJJGNvbXBhcmVfdmVyc2lvbiA9IHN0cl9yZXBsYWNlKCAnLXNyYycsICcnLCAkR0xPQkFMU1snd3BfdmVyc2lvbiddICk7CgoJCSR1cGRhdGVzID0gWwoJCQknbWFqb3InID0+IGZhbHNlLAoJCQknbWlub3InID0+IGZhbHNlLAoJCV07CgkJZm9yZWFjaCAoICRmcm9tX2FwaS0+dXBkYXRlcyBhcyAkb2ZmZXIgKSB7CgoJCQkkdXBkYXRlX3R5cGUgPSBVdGlsc1xnZXRfbmFtZWRfc2VtX3ZlciggJG9mZmVyLT52ZXJzaW9uLCAkY29tcGFyZV92ZXJzaW9uICk7CgkJCWlmICggISAkdXBkYXRlX3R5cGUgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gV29yZFByZXNzIGZvbGxvdyBpdHMgb3duIHZlcnNpb25pbmcgd2hpY2ggaXMgcm91Z2hseSBlcXVpdmFsZW50IHRvIHNlbXZlcgoJCQlpZiAoICdtaW5vcicgPT09ICR1cGRhdGVfdHlwZSApIHsKCQkJCSR1cGRhdGVfdHlwZSA9ICdtYWpvcic7CgkJCX0gZWxzZWlmICggJ3BhdGNoJyA9PT0gJHVwZGF0ZV90eXBlICkgewoJCQkJJHVwZGF0ZV90eXBlID0gJ21pbm9yJzsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkdXBkYXRlc1sgJHVwZGF0ZV90eXBlIF0gKSAmJiAhIENvbXBhcmF0b3I6OmdyZWF0ZXJUaGFuKCAkb2ZmZXItPnZlcnNpb24sICR1cGRhdGVzWyAkdXBkYXRlX3R5cGUgXVsndmVyc2lvbiddICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHVwZGF0ZXNbICR1cGRhdGVfdHlwZSBdID0gWwoJCQkJJ3ZlcnNpb24nICAgICA9PiAkb2ZmZXItPnZlcnNpb24sCgkJCQkndXBkYXRlX3R5cGUnID0+ICR1cGRhdGVfdHlwZSwKCQkJCSdwYWNrYWdlX3VybCcgPT4gISBlbXB0eSggJG9mZmVyLT5wYWNrYWdlcy0+cGFydGlhbCApID8gJG9mZmVyLT5wYWNrYWdlcy0+cGFydGlhbCA6ICRvZmZlci0+cGFja2FnZXMtPmZ1bGwsCgkJCV07CgkJfQoKCQlmb3JlYWNoICggJHVwZGF0ZXMgYXMgJHR5cGUgPT4gJHZhbHVlICkgewoJCQlpZiAoIGVtcHR5KCAkdmFsdWUgKSApIHsKCQkJCXVuc2V0KCAkdXBkYXRlc1sgJHR5cGUgXSApOwoJCQl9CgkJfQoKCQlmb3JlYWNoICggWyAnbWFqb3InLCAnbWlub3InIF0gYXMgJHR5cGUgKSB7CgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAkdHlwZSApICkgewoJCQkJcmV0dXJuICEgZW1wdHkoICR1cGRhdGVzWyAkdHlwZSBdICkKCQkJCQk/IFsgJHVwZGF0ZXNbICR0eXBlIF0gXQoJCQkJCTogZmFsc2U7CgkJCX0KCQl9CgkJcmV0dXJuIGFycmF5X3ZhbHVlcyggJHVwZGF0ZXMgKTsKCX0KCgkvKioKCSAqIENsZWFuIHVwIGV4dHJhIGZpbGVzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb25fZnJvbSBTdGFydGluZyB2ZXJzaW9uIHRoYXQgdGhlIGluc3RhbGxhdGlvbiB3YXMgdXBkYXRlZCBmcm9tLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbl90byAgIFRhcmdldCB2ZXJzaW9uIHRoYXQgdGhlIGluc3RhbGxhdGlvbiBpcyB1cGRhdGVkIHRvLgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlICAgICAgIExvY2FsZSBvZiB0aGUgaW5zdGFsbGF0aW9uLgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgICAgIFdoZXRoZXIgdG8gcmV0cnkgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIG9uIFRMUyBoYW5kc2hha2UgZmFpbHVyZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjbGVhbnVwX2V4dHJhX2ZpbGVzKCAkdmVyc2lvbl9mcm9tLCAkdmVyc2lvbl90bywgJGxvY2FsZSwgJGluc2VjdXJlICkgewoJCWlmICggISAkdmVyc2lvbl9mcm9tIHx8ICEgJHZlcnNpb25fdG8gKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ0ZhaWxlZCB0byBmaW5kIFdvcmRQcmVzcyB2ZXJzaW9uLiBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4nICk7CgkJCXJldHVybjsKCQl9CgoJCSRvbGRfY2hlY2tzdW1zID0gc2VsZjo6Z2V0X2NvcmVfY2hlY2tzdW1zKCAkdmVyc2lvbl9mcm9tLCAkbG9jYWxlID86ICdlbl9VUycsICRpbnNlY3VyZSApOwoJCWlmICggISBpc19hcnJheSggJG9sZF9jaGVja3N1bXMgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRvbGRfY2hlY2tzdW1zfSBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4iICk7CgkJCXJldHVybjsKCQl9CgkJJG5ld19jaGVja3N1bXMgPSBzZWxmOjpnZXRfY29yZV9jaGVja3N1bXMoICR2ZXJzaW9uX3RvLCAkbG9jYWxlID86ICdlbl9VUycsICRpbnNlY3VyZSApOwoJCWlmICggISBpc19hcnJheSggJG5ld19jaGVja3N1bXMgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRuZXdfY2hlY2tzdW1zfSBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4iICk7CgkJCXJldHVybjsKCQl9CgoJCS8vIENvbXBhcmUgdGhlIGZpbGVzIGZyb20gdGhlIG9sZCB2ZXJzaW9uIGFuZCB0aGUgbmV3IHZlcnNpb24gaW4gYSBjYXNlLWluc2Vuc2l0aXZlIG1hbm5lciwKCQkvLyB0byBwcmV2ZW50IGZpbGVzIGJlaW5nIGluY29ycmVjdGx5IGRlbGV0ZWQgb24gc3lzdGVtcyB3aXRoIGNhc2UtaW5zZW5zaXRpdmUgZmlsZXN5c3RlbXMKCQkvLyB3aGVuIGNvcmUgY2hhbmdlcyB0aGUgY2FzZSBvZiBmaWxlbmFtZXMuCgkJLy8gVGhlIG1haW4gbG9naWMgZm9yIHRoaXMgd2FzIHRha2VuIGZyb20gdGhlIEpvb21sYSBwcm9qZWN0IGFuZCBhZGFwdGVkIGZvciBXUC4KCQkvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9qb29tbGEvam9vbWxhLWNtcy9ibG9iL2JiNTM2OGM3ZWY5YzIwMjcwZTZlOWZjYzRiMzY0Y2QwODQ5MDgyYTUvYWRtaW5pc3RyYXRvci9jb21wb25lbnRzL2NvbV9hZG1pbi9zY3JpcHQucGhwI0w4MTU4CgoJCSRvbGRfZmlsZXBhdGhzID0gYXJyYXlfa2V5cyggJG9sZF9jaGVja3N1bXMgKTsKCQkkbmV3X2ZpbGVwYXRocyA9IGFycmF5X2tleXMoICRuZXdfY2hlY2tzdW1zICk7CgoJCSRuZXdfZmlsZXBhdGhzID0gYXJyYXlfY29tYmluZSggYXJyYXlfbWFwKCAnc3RydG9sb3dlcicsICRuZXdfZmlsZXBhdGhzICksICRuZXdfZmlsZXBhdGhzICk7CgoJCSRvbGRfZmlsZXBhdGhzX3RvX2NoZWNrID0gYXJyYXlfZGlmZiggJG9sZF9maWxlcGF0aHMsICRuZXdfZmlsZXBhdGhzICk7CgoJCWZvcmVhY2ggKCAkb2xkX2ZpbGVwYXRoc190b19jaGVjayBhcyAkb2xkX2ZpbGVwYXRoX3RvX2NoZWNrICkgewoJCQkkb2xkX3JlYWxwYXRoID0gcmVhbHBhdGgoIEFCU1BBVEggLiAkb2xkX2ZpbGVwYXRoX3RvX2NoZWNrICk7CgoJCQkvLyBPbiBVbml4IHdpdGhvdXQgaW5jb3JyZWN0bHkgY2FzZWQgZmlsZS4KCQkJaWYgKCBmYWxzZSA9PT0gJG9sZF9yZWFscGF0aCApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkbG93ZXJjYXNlX29sZF9maWxlcGF0aF90b19jaGVjayA9IHN0cnRvbG93ZXIoICRvbGRfZmlsZXBhdGhfdG9fY2hlY2sgKTsKCgkJCWlmICggISBhcnJheV9rZXlfZXhpc3RzKCAkbG93ZXJjYXNlX29sZF9maWxlcGF0aF90b19jaGVjaywgJG5ld19maWxlcGF0aHMgKSApIHsKCQkJCSRmaWxlc190b19yZW1vdmVbXSA9ICRvbGRfZmlsZXBhdGhfdG9fY2hlY2s7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gV2UgYXJlIG5vdyBsZWZ0IHdpdGggb25seSB0aGUgZmlsZXMgdGhhdCBhcmUgc2ltaWxhciBmcm9tIG9sZCB0byBuZXcgZXhjZXB0IGZvciB0aGVpciBjYXNlLgoKCQkJJG9sZF9iYXNlbmFtZSAgICAgID0gYmFzZW5hbWUoICRvbGRfcmVhbHBhdGggKTsKCQkJJG5ld19maWxlcGF0aCAgICAgID0gJG5ld19maWxlcGF0aHNbICRsb3dlcmNhc2Vfb2xkX2ZpbGVwYXRoX3RvX2NoZWNrIF07CgkJCSRleHBlY3RlZF9iYXNlbmFtZSA9IGJhc2VuYW1lKCAkbmV3X2ZpbGVwYXRoICk7CgkJCSRuZXdfcmVhbHBhdGggICAgICA9IHJlYWxwYXRoKCBBQlNQQVRIIC4gJG5ld19maWxlcGF0aCApOwoJCQkkbmV3X2Jhc2VuYW1lICAgICAgPSBiYXNlbmFtZSggJG5ld19yZWFscGF0aCApOwoKCQkJLy8gT24gV2luZG93cyBvciBVbml4IHdpdGggb25seSB0aGUgaW5jb3JyZWN0bHkgY2FzZWQgZmlsZS4KCQkJaWYgKCAkbmV3X2Jhc2VuYW1lICE9PSAkZXhwZWN0ZWRfYmFzZW5hbWUgKSB7CgkJCQlXUF9DTEk6OmRlYnVnKCAiUmVuYW1pbmcgZmlsZSAneyRvbGRfZmlsZXBhdGhfdG9fY2hlY2t9JyA9PiAneyRuZXdfZmlsZXBhdGh9JyIsICdjb3JlJyApOwoKCQkJCXJlbmFtZSggQUJTUEFUSCAuICRvbGRfZmlsZXBhdGhfdG9fY2hlY2ssIEFCU1BBVEggLiAkb2xkX2ZpbGVwYXRoX3RvX2NoZWNrIC4gJy50bXAnICk7CgkJCQlyZW5hbWUoIEFCU1BBVEggLiAkb2xkX2ZpbGVwYXRoX3RvX2NoZWNrIC4gJy50bXAnLCBBQlNQQVRIIC4gJG5ld19maWxlcGF0aCApOwoKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBUaGVyZSBtaWdodCBzdGlsbCBiZSBhbiBpbmNvcnJlY3RseSBjYXNlZCBmaWxlIG9uIG90aGVyIE9TIHRoYW4gV2luZG93cy4KCQkJaWYgKCBiYXNlbmFtZSggJG9sZF9maWxlcGF0aF90b19jaGVjayApID09PSAkb2xkX2Jhc2VuYW1lICkgewoJCQkJLy8gQ2hlY2sgaWYgY2FzZS1pbnNlbnNpdGl2ZSBmaWxlIHN5c3RlbSwgZWcgb24gT1NYLgoJCQkJaWYgKCBmaWxlaW5vZGUoICRvbGRfcmVhbHBhdGggKSA9PT0gZmlsZWlub2RlKCAkbmV3X3JlYWxwYXRoICkgKSB7CgkJCQkJLy8gQ2hlY2sgZGVlcGVyIGJlY2F1c2UgZXZlbiByZWFscGF0aCBvciBnbG9iIG1pZ2h0IG5vdCByZXR1cm4gdGhlIGFjdHVhbCBjYXNlLgoJCQkJCWlmICggISBpbl9hcnJheSggJGV4cGVjdGVkX2Jhc2VuYW1lLCBzY2FuZGlyKCBkaXJuYW1lKCAkbmV3X3JlYWxwYXRoICkgKSwgdHJ1ZSApICkgewoJCQkJCQlXUF9DTEk6OmRlYnVnKCAiUmVuYW1pbmcgZmlsZSAneyRvbGRfZmlsZXBhdGhfdG9fY2hlY2t9JyA9PiAneyRuZXdfZmlsZXBhdGh9JyIsICdjb3JlJyApOwoKCQkJCQkJcmVuYW1lKCBBQlNQQVRIIC4gJG9sZF9maWxlcGF0aF90b19jaGVjaywgQUJTUEFUSCAuICRvbGRfZmlsZXBhdGhfdG9fY2hlY2sgLiAnLnRtcCcgKTsKCQkJCQkJcmVuYW1lKCBBQlNQQVRIIC4gJG9sZF9maWxlcGF0aF90b19jaGVjayAuICcudG1wJywgQUJTUEFUSCAuICRuZXdfZmlsZXBhdGggKTsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCS8vIE9uIFVuaXggd2l0aCBib3RoIGZpbGVzOiBEZWxldGUgdGhlIGluY29ycmVjdGx5IGNhc2VkIGZpbGUuCgkJCQkJJGZpbGVzX3RvX3JlbW92ZVtdID0gJG9sZF9maWxlcGF0aF90b19jaGVjazsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkZmlsZXNfdG9fcmVtb3ZlICkgKSB7CgkJCVdQX0NMSTo6bG9nKCAnQ2xlYW5pbmcgdXAgZmlsZXMuLi4nICk7CgoJCQkkY291bnQgPSAwOwoJCQlmb3JlYWNoICggJGZpbGVzX3RvX3JlbW92ZSBhcyAkZmlsZSApIHsKCgkJCQkvLyB3cC1jb250ZW50IHNob3VsZCBiZSBjb25zaWRlcmVkIHVzZXIgZGF0YQoJCQkJaWYgKCAwID09PSBzdHJpcG9zKCAkZmlsZSwgJ3dwLWNvbnRlbnQnICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaWYgKCBmaWxlX2V4aXN0cyggQUJTUEFUSCAuICRmaWxlICkgKSB7CgkJCQkJdW5saW5rKCBBQlNQQVRIIC4gJGZpbGUgKTsKCQkJCQlXUF9DTEk6OmxvZyggIkZpbGUgcmVtb3ZlZDogeyRmaWxlfSIgKTsKCQkJCQkkY291bnQrKzsKCQkJCX0KCQkJfQoKCQkJaWYgKCAkY291bnQgKSB7CgkJCQlXUF9DTEk6OmxvZyggbnVtYmVyX2Zvcm1hdCggJGNvdW50ICkgLiAnIGZpbGVzIGNsZWFuZWQgdXAuJyApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICdObyBmaWxlcyBmb3VuZCB0aGF0IG5lZWQgY2xlYW5pbmcgdXAuJyApOwoJCQl9CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHN0cmlwX2NvbnRlbnRfZGlyKCAkemlwX2ZpbGUgKSB7CgkJJG5ld196aXBfZmlsZSA9IFV0aWxzXGdldF90ZW1wX2RpcigpIC4gdW5pcWlkKCAnd3BfJyApIC4gJy56aXAnOwoJCXJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKAoJCQlmdW5jdGlvbiAoKSB1c2UgKCAkbmV3X3ppcF9maWxlICkgewoJCQkJaWYgKCBmaWxlX2V4aXN0cyggJG5ld196aXBfZmlsZSApICkgewoJCQkJCXVubGluayggJG5ld196aXBfZmlsZSApOwoJCQkJfQoJCQl9CgkJKTsKCQkvLyBEdXBsaWNhdGUgZmlsZSB0byBhdm9pZCBtb2RpZnlpbmcgdGhlIG9yaWdpbmFsLCB3aGljaCBjb3VsZCBiZSBjYWNoZS4KCQlpZiAoICEgY29weSggJHppcF9maWxlLCAkbmV3X3ppcF9maWxlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdGYWlsZWQgdG8gY29weSBaSVAgZmlsZS4nICk7CgkJfQoJCSR6aXAgPSBuZXcgWmlwQXJjaGl2ZSgpOwoJCSRyZXMgPSAkemlwLT5vcGVuKCAkbmV3X3ppcF9maWxlICk7CgkJaWYgKCB0cnVlID09PSAkcmVzICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlZhbGlkVmFyaWFibGVOYW1lLlVzZWRQcm9wZXJ0eU5vdFNuYWtlQ2FzZQoJCQlmb3IgKCAkaSA9IDA7ICRpIDwgJHppcC0+bnVtRmlsZXM7ICRpKysgKSB7CgkJCQkkaW5mbyA9ICR6aXAtPnN0YXRJbmRleCggJGkgKTsKCQkJCWlmICggZmFsc2UgIT09IHN0cmlwb3MoICRpbmZvWyduYW1lJ10sICd3cC1jb250ZW50LycgKSApIHsKCQkJCQkkemlwLT5kZWxldGVJbmRleCggJGkgKTsKCQkJCX0KCQkJfQoJCQkkemlwLT5jbG9zZSgpOwoJCQlyZXR1cm4gJG5ld196aXBfZmlsZTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAnWmlwQXJjaGl2ZSBmYWlsZWQgdG8gb3BlbiBaSVAgZmlsZS4nICk7CgkJfQoJfQoKfQo8P3BocAoKLyoqCiAqIEFkZHMsIHJlbW92ZXMsIGZldGNoZXMsIGFuZCBmbHVzaGVzIHRoZSBXUCBPYmplY3QgQ2FjaGUgb2JqZWN0LgogKgogKiBCeSBkZWZhdWx0LCB0aGUgV1AgT2JqZWN0IENhY2hlIGV4aXN0cyBpbiBQSFAgbWVtb3J5IGZvciB0aGUgbGVuZ3RoIG9mIHRoZQogKiByZXF1ZXN0IChhbmQgaXMgZW1wdGllZCBhdCB0aGUgZW5kKS4gVXNlIGEgcGVyc2lzdGVudCBvYmplY3QgY2FjaGUgZHJvcC1pbgogKiB0byBwZXJzaXN0IHRoZSBvYmplY3QgY2FjaGUgYmV0d2VlbiByZXF1ZXN0cy4KICoKICogW1JlYWQgdGhlIGNvZGV4IGFydGljbGVdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DbGFzc19SZWZlcmVuY2UvV1BfT2JqZWN0X0NhY2hlKQogKiBmb3IgbW9yZSBkZXRhaWwuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCBjYWNoZS4KICogICAgICQgd3AgY2FjaGUgc2V0IG15X2tleSBteV92YWx1ZSBteV9ncm91cCAzMDAKICogICAgIFN1Y2Nlc3M6IFNldCBvYmplY3QgJ215X2tleScgaW4gZ3JvdXAgJ215X2dyb3VwJy4KICoKICogICAgICMgR2V0IGNhY2hlLgogKiAgICAgJCB3cCBjYWNoZSBnZXQgbXlfa2V5IG15X2dyb3VwCiAqICAgICBteV92YWx1ZQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENhY2hlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBBZGRzIGEgdmFsdWUgdG8gdGhlIG9iamVjdCBjYWNoZS4KCSAqCgkgKiBFcnJvcnMgaWYgYSB2YWx1ZSBhbHJlYWR5IGV4aXN0cyBmb3IgdGhlIGtleSwgd2hpY2ggbWVhbnMgdGhlIHZhbHVlIGNhbid0CgkgKiBiZSBhZGRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVmFsdWUgdG8gYWRkIHRvIHRoZSBrZXkuCgkgKgoJICogWzxncm91cD5dCgkgKiA6IE1ldGhvZCBmb3IgZ3JvdXBpbmcgZGF0YSB3aXRoaW4gdGhlIGNhY2hlIHdoaWNoIGFsbG93cyB0aGUgc2FtZSBrZXkgdG8gYmUgdXNlZCBhY3Jvc3MgZ3JvdXBzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZWZhdWx0CgkgKiAtLS0KCSAqCgkgKiBbPGV4cGlyYXRpb24+XQoJICogOiBEZWZpbmUgaG93IGxvbmcgdG8ga2VlcCB0aGUgdmFsdWUsIGluIHNlY29uZHMuIGAwYCBtZWFucyBhcyBsb25nIGFzIHBvc3NpYmxlLgoJICogLS0tCgkgKiBkZWZhdWx0OiAwCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFkZCBjYWNoZS4KCSAqICAgICAkIHdwIGNhY2hlIGFkZCBteV9rZXkgbXlfZ3JvdXAgbXlfdmFsdWUgMzAwCgkgKiAgICAgU3VjY2VzczogQWRkZWQgb2JqZWN0ICdteV9rZXknIGluIGdyb3VwICdteV92YWx1ZScuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5LCAkdmFsdWUsICRncm91cCwgJGV4cGlyYXRpb24gKSA9ICRhcmdzOwoKCQlpZiAoICEgd3BfY2FjaGVfYWRkKCAka2V5LCAkdmFsdWUsICRncm91cCwgJGV4cGlyYXRpb24gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBhZGQgb2JqZWN0ICcka2V5JyBpbiBncm91cCAnJGdyb3VwJy4gRG9lcyBpdCBhbHJlYWR5IGV4aXN0PyIgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkIG9iamVjdCAnJGtleScgaW4gZ3JvdXAgJyRncm91cCcuIiApOwoJfQoKCS8qKgoJICogRGVjcmVtZW50cyBhIHZhbHVlIGluIHRoZSBvYmplY3QgY2FjaGUuCgkgKgoJICogRXJyb3JzIGlmIHRoZSB2YWx1ZSBjYW4ndCBiZSBkZWNyZW1lbnRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIFs8b2Zmc2V0Pl0KCSAqIDogVGhlIGFtb3VudCBieSB3aGljaCB0byBkZWNyZW1lbnQgdGhlIGl0ZW0ncyB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWzxncm91cD5dCgkgKiA6IE1ldGhvZCBmb3IgZ3JvdXBpbmcgZGF0YSB3aXRoaW4gdGhlIGNhY2hlIHdoaWNoIGFsbG93cyB0aGUgc2FtZSBrZXkgdG8gYmUgdXNlZCBhY3Jvc3MgZ3JvdXBzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZWZhdWx0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlY3JlYXNlIGNhY2hlIHZhbHVlLgoJICogICAgICQgd3AgY2FjaGUgZGVjciBteV9rZXkgMiBteV9ncm91cAoJICogICAgIDQ4CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWNyKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJG9mZnNldCwgJGdyb3VwICkgPSAkYXJnczsKCQkkdmFsdWUgPSB3cF9jYWNoZV9kZWNyKCAka2V5LCAkb2Zmc2V0LCAkZ3JvdXAgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlIHZhbHVlIHdhcyBub3QgZGVjcmVtZW50ZWQuJyApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBhIHZhbHVlIGZyb20gdGhlIG9iamVjdCBjYWNoZS4KCSAqCgkgKiBFcnJvcnMgaWYgdGhlIHZhbHVlIGNhbid0IGJlIGRlbGV0ZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IENhY2hlIGtleS4KCSAqCgkgKiBbPGdyb3VwPl0KCSAqIDogTWV0aG9kIGZvciBncm91cGluZyBkYXRhIHdpdGhpbiB0aGUgY2FjaGUgd2hpY2ggYWxsb3dzIHRoZSBzYW1lIGtleSB0byBiZSB1c2VkIGFjcm9zcyBncm91cHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGRlZmF1bHQKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGNhY2hlLgoJICogICAgICQgd3AgY2FjaGUgZGVsZXRlIG15X2tleSBteV9ncm91cAoJICogICAgIFN1Y2Nlc3M6IE9iamVjdCBkZWxldGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJGdyb3VwICkgPSAkYXJnczsKCQkkcmVzdWx0ICAgICAgICAgICAgICA9IHdwX2NhY2hlX2RlbGV0ZSggJGtleSwgJGdyb3VwICk7CgoJCWlmICggZmFsc2UgPT09ICRyZXN1bHQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgb2JqZWN0IHdhcyBub3QgZGVsZXRlZC4nICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdPYmplY3QgZGVsZXRlZC4nICk7Cgl9CgoJLyoqCgkgKiBGbHVzaGVzIHRoZSBvYmplY3QgY2FjaGUuCgkgKgoJICogRm9yIFdvcmRQcmVzcyBtdWx0aXNpdGUgaW5zdGFuY2VzIHVzaW5nIGEgcGVyc2lzdGVudCBvYmplY3QgY2FjaGUsCgkgKiBmbHVzaGluZyB0aGUgb2JqZWN0IGNhY2hlIHdpbGwgdHlwaWNhbGx5IGZsdXNoIHRoZSBjYWNoZSBmb3IgYWxsIHNpdGVzLgoJICogQmV3YXJlIG9mIHRoZSBwZXJmb3JtYW5jZSBpbXBhY3Qgd2hlbiBmbHVzaGluZyB0aGUgb2JqZWN0IGNhY2hlIGluCgkgKiBwcm9kdWN0aW9uLgoJICoKCSAqIEVycm9ycyBpZiB0aGUgb2JqZWN0IGNhY2hlIGNhbid0IGJlIGZsdXNoZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBGbHVzaCBjYWNoZS4KCSAqICAgICAkIHdwIGNhY2hlIGZsdXNoCgkgKiAgICAgU3VjY2VzczogVGhlIGNhY2hlIHdhcyBmbHVzaGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZmx1c2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdmFsdWUgPSB3cF9jYWNoZV9mbHVzaCgpOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgb2JqZWN0IGNhY2hlIGNvdWxkIG5vdCBiZSBmbHVzaGVkLicgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1RoZSBjYWNoZSB3YXMgZmx1c2hlZC4nICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgdmFsdWUgZnJvbSB0aGUgb2JqZWN0IGNhY2hlLgoJICoKCSAqIEVycm9ycyBpZiB0aGUgdmFsdWUgZG9lc24ndCBleGlzdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIFs8Z3JvdXA+XQoJICogOiBNZXRob2QgZm9yIGdyb3VwaW5nIGRhdGEgd2l0aGluIHRoZSBjYWNoZSB3aGljaCBhbGxvd3MgdGhlIHNhbWUga2V5IHRvIGJlIHVzZWQgYWNyb3NzIGdyb3Vwcy4KCSAqIC0tLQoJICogZGVmYXVsdDogZGVmYXVsdAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgY2FjaGUuCgkgKiAgICAgJCB3cCBjYWNoZSBnZXQgbXlfa2V5IG15X2dyb3VwCgkgKiAgICAgbXlfdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXksICRncm91cCApID0gJGFyZ3M7CgkJJHZhbHVlICAgICAgICAgICAgICAgPSB3cF9jYWNoZV9nZXQoICRrZXksICRncm91cCApOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJPYmplY3Qgd2l0aCBrZXkgJyRrZXknIGFuZCBncm91cCAnJGdyb3VwJyBub3QgZm91bmQuIiApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogSW5jcmVtZW50cyBhIHZhbHVlIGluIHRoZSBvYmplY3QgY2FjaGUuCgkgKgoJICogRXJyb3JzIGlmIHRoZSB2YWx1ZSBjYW4ndCBiZSBpbmNyZW1lbnRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIFs8b2Zmc2V0Pl0KCSAqIDogVGhlIGFtb3VudCBieSB3aGljaCB0byBpbmNyZW1lbnQgdGhlIGl0ZW0ncyB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWzxncm91cD5dCgkgKiA6IE1ldGhvZCBmb3IgZ3JvdXBpbmcgZGF0YSB3aXRoaW4gdGhlIGNhY2hlIHdoaWNoIGFsbG93cyB0aGUgc2FtZSBrZXkgdG8gYmUgdXNlZCBhY3Jvc3MgZ3JvdXBzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZWZhdWx0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEluY3JlYXNlIGNhY2hlIHZhbHVlLgoJICogICAgICQgd3AgY2FjaGUgaW5jciBteV9rZXkgMiBteV9ncm91cAoJICogICAgIDUwCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbmNyKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJG9mZnNldCwgJGdyb3VwICkgPSAkYXJnczsKCQkkdmFsdWUgPSB3cF9jYWNoZV9pbmNyKCAka2V5LCAkb2Zmc2V0LCAkZ3JvdXAgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlIHZhbHVlIHdhcyBub3QgaW5jcmVtZW50ZWQuJyApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogUmVwbGFjZXMgYSB2YWx1ZSBpbiB0aGUgb2JqZWN0IGNhY2hlLCBpZiB0aGUgdmFsdWUgYWxyZWFkeSBleGlzdHMuCgkgKgoJICogRXJyb3JzIGlmIHRoZSB2YWx1ZSBjYW4ndCBiZSByZXBsYWNlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVmFsdWUgdG8gcmVwbGFjZS4KCSAqCgkgKiBbPGdyb3VwPl0KCSAqIDogTWV0aG9kIGZvciBncm91cGluZyBkYXRhIHdpdGhpbiB0aGUgY2FjaGUgd2hpY2ggYWxsb3dzIHRoZSBzYW1lIGtleSB0byBiZSB1c2VkIGFjcm9zcyBncm91cHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGRlZmF1bHQKCSAqIC0tLQoJICoKCSAqIFs8ZXhwaXJhdGlvbj5dCgkgKiA6IERlZmluZSBob3cgbG9uZyB0byBrZWVwIHRoZSB2YWx1ZSwgaW4gc2Vjb25kcy4gYDBgIG1lYW5zIGFzIGxvbmcgYXMgcG9zc2libGUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDAKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVwbGFjZSBjYWNoZS4KCSAqICAgICAkIHdwIGNhY2hlIHJlcGxhY2UgbXlfa2V5IG5ld192YWx1ZSBteV9ncm91cAoJICogICAgIFN1Y2Nlc3M6IFJlcGxhY2VkIG9iamVjdCAnbXlfa2V5JyBpbiBncm91cCAnbXlfZ3JvdXAnLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVwbGFjZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXksICR2YWx1ZSwgJGdyb3VwLCAkZXhwaXJhdGlvbiApID0gJGFyZ3M7CgkJJHJlc3VsdCA9IHdwX2NhY2hlX3JlcGxhY2UoICRrZXksICR2YWx1ZSwgJGdyb3VwLCAkZXhwaXJhdGlvbiApOwoKCQlpZiAoIGZhbHNlID09PSAkcmVzdWx0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHJlcGxhY2Ugb2JqZWN0ICcka2V5JyBpbiBncm91cCAnJGdyb3VwJy4gRG9lcyBpdCBub3QgZXhpc3Q/IiApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiUmVwbGFjZWQgb2JqZWN0ICcka2V5JyBpbiBncm91cCAnJGdyb3VwJy4iICk7Cgl9CgoJLyoqCgkgKiBTZXRzIGEgdmFsdWUgdG8gdGhlIG9iamVjdCBjYWNoZSwgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIGl0IGFscmVhZHkgZXhpc3RzLgoJICoKCSAqIEVycm9ycyBpZiB0aGUgdmFsdWUgY2FuJ3QgYmUgc2V0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBDYWNoZSBrZXkuCgkgKgoJICogPHZhbHVlPgoJICogOiBWYWx1ZSB0byBzZXQgb24gdGhlIGtleS4KCSAqCgkgKiBbPGdyb3VwPl0KCSAqIDogTWV0aG9kIGZvciBncm91cGluZyBkYXRhIHdpdGhpbiB0aGUgY2FjaGUgd2hpY2ggYWxsb3dzIHRoZSBzYW1lIGtleSB0byBiZSB1c2VkIGFjcm9zcyBncm91cHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGRlZmF1bHQKCSAqIC0tLQoJICoKCSAqIFs8ZXhwaXJhdGlvbj5dCgkgKiA6IERlZmluZSBob3cgbG9uZyB0byBrZWVwIHRoZSB2YWx1ZSwgaW4gc2Vjb25kcy4gYDBgIG1lYW5zIGFzIGxvbmcgYXMgcG9zc2libGUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDAKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2V0IGNhY2hlLgoJICogICAgICQgd3AgY2FjaGUgc2V0IG15X2tleSBteV92YWx1ZSBteV9ncm91cCAzMDAKCSAqICAgICBTdWNjZXNzOiBTZXQgb2JqZWN0ICdteV9rZXknIGluIGdyb3VwICdteV9ncm91cCcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5LCAkdmFsdWUsICRncm91cCwgJGV4cGlyYXRpb24gKSA9ICRhcmdzOwoJCSRyZXN1bHQgPSB3cF9jYWNoZV9zZXQoICRrZXksICR2YWx1ZSwgJGdyb3VwLCAkZXhwaXJhdGlvbiApOwoKCQlpZiAoIGZhbHNlID09PSAkcmVzdWx0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGFkZCBvYmplY3QgJyRrZXknIGluIGdyb3VwICckZ3JvdXAnLiIgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIlNldCBvYmplY3QgJyRrZXknIGluIGdyb3VwICckZ3JvdXAnLiIgKTsKCX0KCgkvKioKCSAqIEF0dGVtcHRzIHRvIGRldGVybWluZSB3aGljaCBvYmplY3QgY2FjaGUgaXMgYmVpbmcgdXNlZC4KCSAqCgkgKiBOb3RlIHRoYXQgdGhlIGd1ZXNzZXMgbWFkZSBieSB0aGlzIGZ1bmN0aW9uIGFyZSBiYXNlZCBvbiB0aGUKCSAqIFdQX09iamVjdF9DYWNoZSBjbGFzc2VzIHRoYXQgZGVmaW5lIHRoZSAzcmQgcGFydHkgb2JqZWN0IGNhY2hlIGV4dGVuc2lvbi4KCSAqIENoYW5nZXMgdG8gdGhvc2UgY2xhc3NlcyBjb3VsZCByZW5kZXIgcHJvYmxlbXMgd2l0aCB0aGlzIGZ1bmN0aW9uJ3MKCSAqIGFiaWxpdHkgdG8gZGV0ZXJtaW5lIHdoaWNoIG9iamVjdCBjYWNoZSBpcyBiZWluZyB1c2VkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgY2FjaGUgdHlwZS4KCSAqICAgICAkIHdwIGNhY2hlIHR5cGUKCSAqICAgICBEZWZhdWx0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0eXBlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJG1lc3NhZ2UgPSBXUF9DTElcVXRpbHNcd3BfZ2V0X2NhY2hlX3R5cGUoKTsKCQlXUF9DTEk6OmxpbmUoICRtZXNzYWdlICk7Cgl9Cgp9Cjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIEFkZHMsIGdldHMsIGFuZCBkZWxldGVzIGVudHJpZXMgaW4gdGhlIFdvcmRQcmVzcyBUcmFuc2llbnQgQ2FjaGUuCiAqCiAqIEJ5IGRlZmF1bHQsIHRoZSB0cmFuc2llbnQgY2FjaGUgdXNlcyB0aGUgV29yZFByZXNzIGRhdGFiYXNlIHRvIHBlcnNpc3QgdmFsdWVzCiAqIGJldHdlZW4gcmVxdWVzdHMuIE9uIGEgc2luZ2xlIHNpdGUgaW5zdGFsbGF0aW9uLCB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUKICogYHdwX29wdGlvbnNgIHRhYmxlLiBPbiBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24sIHZhbHVlcyBhcmUgc3RvcmVkIGluIHRoZQogKiBgd3Bfb3B0aW9uc2Agb3IgdGhlIGB3cF9zaXRlbWV0YWAgdGFibGUsIGRlcGVuZGluZyBvbiB1c2Ugb2YgdGhlIGAtLW5ldHdvcmtgCiAqIGZsYWcuCiAqCiAqIFdoZW4gYSBwZXJzaXN0ZW50IG9iamVjdCBjYWNoZSBkcm9wLWluIGlzIGluc3RhbGxlZCAoZS5nLiBSZWRpcyBvciBNZW1jYWNoZWQpLAogKiB0aGUgdHJhbnNpZW50IGNhY2hlIHNraXBzIHRoZSBkYXRhYmFzZSBhbmQgc2ltcGx5IHdyYXBzIHRoZSBXUCBPYmplY3QgQ2FjaGUuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCB0cmFuc2llbnQuCiAqICAgICAkIHdwIHRyYW5zaWVudCBzZXQgc2FtcGxlX2tleSAidGVzdCBkYXRhIiAzNjAwCiAqICAgICBTdWNjZXNzOiBUcmFuc2llbnQgYWRkZWQuCiAqCiAqICAgICAjIEdldCB0cmFuc2llbnQuCiAqICAgICAkIHdwIHRyYW5zaWVudCBnZXQgc2FtcGxlX2tleQogKiAgICAgdGVzdCBkYXRhCiAqCiAqICAgICAjIERlbGV0ZSB0cmFuc2llbnQuCiAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgc2FtcGxlX2tleQogKiAgICAgU3VjY2VzczogVHJhbnNpZW50IGRlbGV0ZWQuCiAqCiAqICAgICAjIERlbGV0ZSBleHBpcmVkIHRyYW5zaWVudHMuCiAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgLS1leHBpcmVkCiAqICAgICBTdWNjZXNzOiAxMiBleHBpcmVkIHRyYW5zaWVudHMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4KICoKICogICAgICMgRGVsZXRlIGFsbCB0cmFuc2llbnRzLgogKiAgICAgJCB3cCB0cmFuc2llbnQgZGVsZXRlIC0tYWxsCiAqICAgICBTdWNjZXNzOiAxNCB0cmFuc2llbnRzIGRlbGV0ZWQgZnJvbSB0aGUgZGF0YWJhc2UuCiAqLwpjbGFzcyBUcmFuc2llbnRfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIEdldHMgYSB0cmFuc2llbnQgdmFsdWUuCgkgKgoJICogRm9yIGEgbW9yZSBjb21wbGV0ZSBleHBsYW5hdGlvbiBvZiB0aGUgdHJhbnNpZW50IGNhY2hlLCBpbmNsdWRpbmcgdGhlCgkgKiBuZXR3b3JrfHNpdGUgY2FjaGUsIHBsZWFzZSBzZWUgZG9jcyBmb3IgYHdwIHRyYW5zaWVudGAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IEtleSBmb3IgdGhlIHRyYW5zaWVudC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogR2V0IHRoZSB2YWx1ZSBvZiBhIG5ldHdvcmt8c2l0ZSB0cmFuc2llbnQuIE9uIHNpbmdsZSBzaXRlLCB0aGlzIGlzCgkgKiBpcyBhIHNwZWNpYWxseS1uYW1lZCBjYWNoZSBrZXkuIE9uIG11bHRpc2l0ZSwgdGhpcyBpcyBhIGdsb2JhbCBjYWNoZQoJICogKGluc3RlYWQgb2YgbG9jYWwgdG8gdGhlIHNpdGUpLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdHJhbnNpZW50IGdldCBzYW1wbGVfa2V5CgkgKiAgICAgdGVzdCBkYXRhCgkgKgoJICogICAgICQgd3AgdHJhbnNpZW50IGdldCByYW5kb21fa2V5CgkgKiAgICAgV2FybmluZzogVHJhbnNpZW50IHdpdGgga2V5ICJyYW5kb21fa2V5IiBpcyBub3Qgc2V0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSApID0gJGFyZ3M7CgoJCSRmdW5jICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICkgPyAnZ2V0X3NpdGVfdHJhbnNpZW50JyA6ICdnZXRfdHJhbnNpZW50JzsKCQkkdmFsdWUgPSAkZnVuYyggJGtleSApOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ1RyYW5zaWVudCB3aXRoIGtleSAiJyAuICRrZXkgLiAnIiBpcyBub3Qgc2V0LicgKTsKCQkJZXhpdDsKCQl9CgoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIFNldHMgYSB0cmFuc2llbnQgdmFsdWUuCgkgKgoJICogYDxleHBpcmF0aW9uPmAgaXMgdGhlIHRpbWUgdW50aWwgZXhwaXJhdGlvbiwgaW4gc2Vjb25kcy4KCSAqCgkgKiBGb3IgYSBtb3JlIGNvbXBsZXRlIGV4cGxhbmF0aW9uIG9mIHRoZSB0cmFuc2llbnQgY2FjaGUsIGluY2x1ZGluZyB0aGUKCSAqIG5ldHdvcmt8c2l0ZSBjYWNoZSwgcGxlYXNlIHNlZSBkb2NzIGZvciBgd3AgdHJhbnNpZW50YC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogS2V5IGZvciB0aGUgdHJhbnNpZW50LgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVmFsdWUgdG8gYmUgc2V0IGZvciB0aGUgdHJhbnNpZW50LgoJICoKCSAqIFs8ZXhwaXJhdGlvbj5dCgkgKiA6IFRpbWUgdW50aWwgZXhwaXJhdGlvbiwgaW4gc2Vjb25kcy4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBTZXQgdGhlIHZhbHVlIG9mIGEgbmV0d29ya3xzaXRlIHRyYW5zaWVudC4gT24gc2luZ2xlIHNpdGUsIHRoaXMgaXMKCSAqIGlzIGEgc3BlY2lhbGx5LW5hbWVkIGNhY2hlIGtleS4gT24gbXVsdGlzaXRlLCB0aGlzIGlzIGEgZ2xvYmFsIGNhY2hlCgkgKiAoaW5zdGVhZCBvZiBsb2NhbCB0byB0aGUgc2l0ZSkuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgc2V0IHNhbXBsZV9rZXkgInRlc3QgZGF0YSIgMzYwMAoJICogICAgIFN1Y2Nlc3M6IFRyYW5zaWVudCBhZGRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXksICR2YWx1ZSApID0gJGFyZ3M7CgoJCSRleHBpcmF0aW9uID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAyLCAwICk7CgoJCSRmdW5jID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKSA/ICdzZXRfc2l0ZV90cmFuc2llbnQnIDogJ3NldF90cmFuc2llbnQnOwoJCWlmICggJGZ1bmMoICRrZXksICR2YWx1ZSwgJGV4cGlyYXRpb24gKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnVHJhbnNpZW50IGFkZGVkLicgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAnVHJhbnNpZW50IGNvdWxkIG5vdCBiZSBzZXQuJyApOwoJCX0KCX0KCgkvKioKCSAqIERlbGV0ZXMgYSB0cmFuc2llbnQgdmFsdWUuCgkgKgoJICogRm9yIGEgbW9yZSBjb21wbGV0ZSBleHBsYW5hdGlvbiBvZiB0aGUgdHJhbnNpZW50IGNhY2hlLCBpbmNsdWRpbmcgdGhlCgkgKiBuZXR3b3JrfHNpdGUgY2FjaGUsIHBsZWFzZSBzZWUgZG9jcyBmb3IgYHdwIHRyYW5zaWVudGAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8a2V5Pl0KCSAqIDogS2V5IGZvciB0aGUgdHJhbnNpZW50LgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IERlbGV0ZSB0aGUgdmFsdWUgb2YgYSBuZXR3b3JrfHNpdGUgdHJhbnNpZW50LiBPbiBzaW5nbGUgc2l0ZSwgdGhpcyBpcwoJICogaXMgYSBzcGVjaWFsbHktbmFtZWQgY2FjaGUga2V5LiBPbiBtdWx0aXNpdGUsIHRoaXMgaXMgYSBnbG9iYWwgY2FjaGUKCSAqIChpbnN0ZWFkIG9mIGxvY2FsIHRvIHRoZSBzaXRlKS4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IERlbGV0ZSBhbGwgdHJhbnNpZW50cy4KCSAqCgkgKiBbLS1leHBpcmVkXQoJICogOiBEZWxldGUgYWxsIGV4cGlyZWQgdHJhbnNpZW50cy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSB0cmFuc2llbnQuCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZGVsZXRlIHNhbXBsZV9rZXkKCSAqICAgICBTdWNjZXNzOiBUcmFuc2llbnQgZGVsZXRlZC4KCSAqCgkgKiAgICAgIyBEZWxldGUgZXhwaXJlZCB0cmFuc2llbnRzLgoJICogICAgICQgd3AgdHJhbnNpZW50IGRlbGV0ZSAtLWV4cGlyZWQKCSAqICAgICBTdWNjZXNzOiAxMiBleHBpcmVkIHRyYW5zaWVudHMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiAgICAgIyBEZWxldGUgZXhwaXJlZCBzaXRlIHRyYW5zaWVudHMuCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZGVsZXRlIC0tZXhwaXJlZCAtLW5ldHdvcmsKCSAqICAgICBTdWNjZXNzOiAxIGV4cGlyZWQgdHJhbnNpZW50IGRlbGV0ZWQgZnJvbSB0aGUgZGF0YWJhc2UuCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCB0cmFuc2llbnRzLgoJICogICAgICQgd3AgdHJhbnNpZW50IGRlbGV0ZSAtLWFsbAoJICogICAgIFN1Y2Nlc3M6IDE0IHRyYW5zaWVudHMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHNpdGUgdHJhbnNpZW50cy4KCSAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgLS1hbGwgLS1uZXR3b3JrCgkgKiAgICAgU3VjY2VzczogMiB0cmFuc2llbnRzIGRlbGV0ZWQgZnJvbSB0aGUgZGF0YWJhc2UuCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCB0cmFuc2llbnRzIGluIGEgbXVsdHNpdGUuCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZGVsZXRlIC0tYWxsIC0tbmV0d29yayAmJiB3cCBzaXRlIGxpc3QgLS1maWVsZD11cmwgfCB4YXJncyAtbjEgLUkgJSB3cCAtLXVybD0lIHRyYW5zaWVudCBkZWxldGUgLS1hbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRrZXkgPSAoICEgZW1wdHkoICRhcmdzICkgKSA/ICRhcmdzWzBdIDogbnVsbDsKCgkJJGFsbCAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICk7CgkJJGV4cGlyZWQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdleHBpcmVkJyApOwoJCSRuZXR3b3JrID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKTsKCgkJaWYgKCB0cnVlID09PSAkYWxsICkgewoJCQkkdGhpcy0+ZGVsZXRlX2FsbCggJG5ldHdvcmsgKTsKCQkJcmV0dXJuOwoJCX0gZWxzZWlmICggdHJ1ZSA9PT0gJGV4cGlyZWQgKSB7CgkJCSR0aGlzLT5kZWxldGVfZXhwaXJlZCggJG5ldHdvcmsgKTsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAhICRrZXkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSB0cmFuc2llbnQga2V5LCBvciB1c2UgLS1hbGwgb3IgLS1leHBpcmVkLicgKTsKCQl9CgoJCSRmdW5jID0gJG5ldHdvcmsgPyAnZGVsZXRlX3NpdGVfdHJhbnNpZW50JyA6ICdkZWxldGVfdHJhbnNpZW50JzsKCgkJaWYgKCAkZnVuYyggJGtleSApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdUcmFuc2llbnQgZGVsZXRlZC4nICk7CgkJfSBlbHNlIHsKCQkJJGZ1bmMgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduZXR3b3JrJyApID8gJ2dldF9zaXRlX3RyYW5zaWVudCcgOiAnZ2V0X3RyYW5zaWVudCc7CgkJCWlmICggJGZ1bmMoICRrZXkgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdUcmFuc2llbnQgd2FzIG5vdCBkZWxldGVkIGV2ZW4gdGhvdWdoIHRoZSB0cmFuc2llbnQgYXBwZWFycyB0byBleGlzdC4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdUcmFuc2llbnQgd2FzIG5vdCBkZWxldGVkOyBob3dldmVyLCB0aGUgdHJhbnNpZW50IGRvZXMgbm90IGFwcGVhciB0byBleGlzdC4nICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBEZXRlcm1pbmVzIHRoZSB0eXBlIG9mIHRyYW5zaWVudHMgaW1wbGVtZW50YXRpb24uCgkgKgoJICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHRyYW5zaWVudHMgQVBJIGlzIHVzaW5nIGFuIG9iamVjdCBjYWNoZSBvciB0aGUKCSAqIGRhdGFiYXNlLgoJICoKCSAqIEZvciBhIG1vcmUgY29tcGxldGUgZXhwbGFuYXRpb24gb2YgdGhlIHRyYW5zaWVudCBjYWNoZSwgaW5jbHVkaW5nIHRoZQoJICogbmV0d29ya3xzaXRlIGNhY2hlLCBwbGVhc2Ugc2VlIGRvY3MgZm9yIGB3cCB0cmFuc2llbnRgLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdHJhbnNpZW50IHR5cGUKCSAqICAgICBUcmFuc2llbnRzIGFyZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0eXBlKCkgewoJCWlmICggd3BfdXNpbmdfZXh0X29iamVjdF9jYWNoZSgpICkgewoJCQkkbWVzc2FnZSA9ICdUcmFuc2llbnRzIGFyZSBzYXZlZCB0byB0aGUgb2JqZWN0IGNhY2hlLic7CgkJfSBlbHNlIHsKCQkJJG1lc3NhZ2UgPSAnVHJhbnNpZW50cyBhcmUgc2F2ZWQgdG8gdGhlIGRhdGFiYXNlLic7CgkJfQoKCQlXUF9DTEk6OmxpbmUoICRtZXNzYWdlICk7Cgl9CgoJLyoqCgkgKiBMaXN0cyB0cmFuc2llbnRzIGFuZCB0aGVpciB2YWx1ZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXNlYXJjaD08cGF0dGVybj5dCgkgKiA6IFVzZSB3aWxkY2FyZHMgKCAqIGFuZCA/ICkgdG8gbWF0Y2ggdHJhbnNpZW50IG5hbWUuCgkgKgoJICogWy0tZXhjbHVkZT08cGF0dGVybj5dCgkgKiA6IFBhdHRlcm4gdG8gZXhjbHVkZS4gVXNlIHdpbGRjYXJkcyAoICogYW5kID8gKSB0byBtYXRjaCB0cmFuc2llbnQgbmFtZS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBHZXQgdGhlIHZhbHVlcyBvZiBuZXR3b3JrfHNpdGUgdHJhbnNpZW50cy4gT24gc2luZ2xlIHNpdGUsIHRoaXMgaXMKCSAqIGEgc3BlY2lhbGx5LW5hbWVkIGNhY2hlIGtleS4gT24gbXVsdGlzaXRlLCB0aGlzIGlzIGEgZ2xvYmFsIGNhY2hlCgkgKiAoaW5zdGVhZCBvZiBsb2NhbCB0byB0aGUgc2l0ZSkuCgkgKgoJICogWy0tdW5zZXJpYWxpemVdCgkgKiA6IFVuc2VyaWFsaXplIHRyYW5zaWVudCB2YWx1ZXMgaW4gb3V0cHV0LgoJICoKCSAqIFstLWh1bWFuLXJlYWRhYmxlXQoJICogOiBIdW1hbi1yZWFkYWJsZSBvdXRwdXQgZm9yIGV4cGlyYXRpb25zLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0ganNvbgoJICogICAtIGNzdgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoaXMgZmllbGQgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBtYXRjaGluZyBvcHRpb246CgkgKgoJICogKiBuYW1lCgkgKiAqIHZhbHVlCgkgKiAqIGV4cGlyYXRpb24KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgYWxsIHRyYW5zaWVudHMKCSAqICAgICAkIHdwIHRyYW5zaWVudCBsaXN0CgkqICAgICAgKy0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0tLS0tLSsKCSogICAgICB8IG5hbWUgfCB2YWx1ZSB8IGV4cGlyYXRpb24gICAgfAoJKiAgICAgICstLS0tLS0rLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0rCgkqICAgICAgfCBmb28gIHwgYmFyICAgfCAzOSBtaW5zICAgICAgIHwKCSogICAgICB8IGZvbzIgfCBiYXIyICB8IG5vIGV4cGlyYXRpb24gfAoJKiAgICAgIHwgZm9vMyB8IGJhcjIgIHwgZXhwaXJlZCAgICAgICB8CgkqICAgICAgfCBmb280IHwgYmFyNCAgfCA0IGhvdXJzICAgICAgIHwKCSogICAgICArLS0tLS0tKy0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkbmV0d29yayAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduZXR3b3JrJywgZmFsc2UgKTsKCQkkdW5zZXJpYWxpemUgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd1bnNlcmlhbGl6ZScsIGZhbHNlICk7CgkJJGh1bWFuX3JlYWRhYmxlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaHVtYW4tcmVhZGFibGUnLCBmYWxzZSApOwoKCQkkZmllbGRzID0gYXJyYXkoICduYW1lJywgJ3ZhbHVlJywgJ2V4cGlyYXRpb24nICk7CgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRmaWVsZHMgPSBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydmaWVsZHMnXSApOwoJCX0KCgkJJHBhdHRlcm4gPSAnJSc7CgkJJGV4Y2x1ZGUgPSAnJzsKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snc2VhcmNoJ10gKSApIHsKCQkJJHBhdHRlcm4gPSBVdGlsc1xlc2NfbGlrZSggJGFzc29jX2FyZ3NbJ3NlYXJjaCddICk7CgkJCS8vIFN1YnN0aXR1dGUgd2lsZGNhcmRzLgoJCQkkcGF0dGVybiA9IHN0cl9yZXBsYWNlKAoJCQkJYXJyYXkoICcqJywgJz8nICksCgkJCQlhcnJheSggJyUnLCAnXycgKSwKCQkJCSRwYXR0ZXJuCgkJCSk7CgkJfQoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydleGNsdWRlJ10gKSApIHsKCQkJJGV4Y2x1ZGUgPSBVdGlsc1xlc2NfbGlrZSggJGFzc29jX2FyZ3NbJ2V4Y2x1ZGUnXSApOwoJCQkvLyBTdWJzdGl0dXRlIHdpbGRjYXJkcy4KCQkJJGV4Y2x1ZGUgPSBzdHJfcmVwbGFjZSgKCQkJCWFycmF5KCAnKicsICc/JyApLAoJCQkJYXJyYXkoICclJywgJ18nICksCgkJCQkkZXhjbHVkZQoJCQkpOwoJCX0KCgkJaWYgKCAkbmV0d29yayApIHsKCQkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJCSR3aGVyZSAgPSAkd3BkYi0+cHJlcGFyZSgKCQkJCQknV0hFUkUgYG1ldGFfa2V5YCBMSUtFICVzJywKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF8nICkgLiAkcGF0dGVybgoJCQkJKTsKCQkJCSR3aGVyZSAuPSAkd3BkYi0+cHJlcGFyZSgKCQkJCQknIEFORCBtZXRhX2tleSBOT1QgTElLRSAlcycsCgkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScKCQkJCSk7CgkJCQlpZiAoICRleGNsdWRlICkgewoJCQkJCSR3aGVyZSAuPSAkd3BkYi0+cHJlcGFyZSgKCQkJCQkJJyBBTkQgbWV0YV9rZXkgTk9UIExJS0UgJXMnLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF8nICkgLiAkZXhjbHVkZQoJCQkJCSk7CgkJCQl9CgoJCQkJJHF1ZXJ5ID0gIlNFTEVDVCBgbWV0YV9rZXlgIGFzIGBuYW1lYCwgYG1ldGFfdmFsdWVgIGFzIGB2YWx1ZWAgRlJPTSB7JHdwZGItPnNpdGVtZXRhfSB7JHdoZXJlfSI7CgkJCX0gZWxzZSB7CgkJCQkkd2hlcmUgID0gJHdwZGItPnByZXBhcmUoCgkJCQkJJ1dIRVJFIGBvcHRpb25fbmFtZWAgTElLRSAlcycsCgkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJHBhdHRlcm4KCQkJCSk7CgkJCQkkd2hlcmUgLj0gJHdwZGItPnByZXBhcmUoCgkJCQkJJyBBTkQgb3B0aW9uX25hbWUgTk9UIExJS0UgJXMnLAoJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50X3RpbWVvdXRfJyApIC4gJyUnCgkJCQkpOwoJCQkJaWYgKCAkZXhjbHVkZSApIHsKCQkJCQkkd2hlcmUgLj0gJHdwZGItPnByZXBhcmUoCgkJCQkJCScgQU5EIG9wdGlvbl9uYW1lIE5PVCBMSUtFICVzJywKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJGV4Y2x1ZGUKCQkJCQkpOwoJCQkJfQoKCQkJCSRxdWVyeSA9ICJTRUxFQ1QgYG9wdGlvbl9uYW1lYCBhcyBgbmFtZWAsIGBvcHRpb25fdmFsdWVgIGFzIGB2YWx1ZWAgRlJPTSB7JHdwZGItPm9wdGlvbnN9IHskd2hlcmV9IjsKCQkJfQoJCX0gZWxzZSB7CgkJCSR3aGVyZSAgPSAkd3BkYi0+cHJlcGFyZSgKCQkJCSdXSEVSRSBgb3B0aW9uX25hbWVgIExJS0UgJXMnLAoJCQkJVXRpbHNcZXNjX2xpa2UoICdfdHJhbnNpZW50XycgKSAuICRwYXR0ZXJuCgkJCSk7CgkJCSR3aGVyZSAuPSAkd3BkYi0+cHJlcGFyZSgKCQkJCScgQU5EIG9wdGlvbl9uYW1lIE5PVCBMSUtFICVzJywKCQkJCVV0aWxzXGVzY19saWtlKCAnX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJwoJCQkpOwoJCQlpZiAoICRleGNsdWRlICkgewoJCQkJJHdoZXJlIC49ICR3cGRiLT5wcmVwYXJlKAoJCQkJCScgQU5EIG9wdGlvbl9uYW1lIE5PVCBMSUtFICVzJywKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfJyApIC4gJGV4Y2x1ZGUKCQkJCSk7CgkJCX0KCgkJCSRxdWVyeSA9ICJTRUxFQ1QgYG9wdGlvbl9uYW1lYCBhcyBgbmFtZWAsIGBvcHRpb25fdmFsdWVgIGFzIGB2YWx1ZWAgRlJPTSB7JHdwZGItPm9wdGlvbnN9IHskd2hlcmV9IjsKCQl9CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gUHJlcGFyZWQgcHJvcGVybHkgYWJvdmUuCgkJJHJlc3VsdHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICRxdWVyeSApOwoKCQlmb3JlYWNoICggJHJlc3VsdHMgYXMgJHJlc3VsdCApIHsKCQkJJHJlc3VsdC0+bmFtZSAgICAgICA9IHN0cl9yZXBsYWNlKCBhcnJheSggJ19zaXRlX3RyYW5zaWVudF8nLCAnX3RyYW5zaWVudF8nICksICcnLCAkcmVzdWx0LT5uYW1lICk7CgkJCSRyZXN1bHQtPmV4cGlyYXRpb24gPSAkdGhpcy0+Z2V0X3RyYW5zaWVudF9leHBpcmF0aW9uKCAkcmVzdWx0LT5uYW1lLCAkbmV0d29yaywgJGh1bWFuX3JlYWRhYmxlICk7CgoJCQlpZiAoICR1bnNlcmlhbGl6ZSApIHsKCQkJCSRyZXN1bHQtPnZhbHVlID0gbWF5YmVfdW5zZXJpYWxpemUoICRyZXN1bHQtPnZhbHVlICk7CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSBuZXcgXFdQX0NMSVxGb3JtYXR0ZXIoCgkJCSRhc3NvY19hcmdzLAoJCQkkZmllbGRzCgkJKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkcmVzdWx0cyApOwoJfQoKCS8qKgoJICogUmV0cmlldmVzIHRoZSBleHBpcmF0aW9uIHRpbWUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSAgICAgICAgICAgICAgVHJhbnNpZW50IG5hbWUuCgkgKiBAcGFyYW0gYm9vbCAgICRpc19zaXRlX3RyYW5zaWVudCBPcHRpb25hbC4gV2hldGhlciB0aGlzIGlzIGEgc2l0ZSB0cmFuc2llbnQuIERlZmF1bHQgZmFsc2UuCgkgKiBAcGFyYW0gYm9vbCAgICRodW1hbl9yZWFkYWJsZSAgICBPcHRpb25hbC4gV2hldGhlciB0byByZXR1cm4gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBub3cgYW5kIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJhdGlvbiB0aW1lIGluIGEgaHVtYW4tcmVhZGFibGUgZm9ybWF0LiBEZWZhdWx0IGZhbHNlLgoJICogQHJldHVybiBzdHJpbmcgRXhwaXJhdGlvbiB0aW1lIHN0cmluZy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfdHJhbnNpZW50X2V4cGlyYXRpb24oICRuYW1lLCAkaXNfc2l0ZV90cmFuc2llbnQgPSBmYWxzZSwgJGh1bWFuX3JlYWRhYmxlID0gZmFsc2UgKSB7CgkJaWYgKCAkaXNfc2l0ZV90cmFuc2llbnQgKSB7CgkJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQkkZXhwaXJhdGlvbiA9IChpbnQpIGdldF9zaXRlX29wdGlvbiggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycgLiAkbmFtZSApOwoJCQl9IGVsc2UgewoJCQkJJGV4cGlyYXRpb24gPSAoaW50KSBnZXRfb3B0aW9uKCAnX3NpdGVfdHJhbnNpZW50X3RpbWVvdXRfJyAuICRuYW1lICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkZXhwaXJhdGlvbiA9IChpbnQpIGdldF9vcHRpb24oICdfdHJhbnNpZW50X3RpbWVvdXRfJyAuICRuYW1lICk7CgkJfQoKCQlpZiAoIDAgPT09ICRleHBpcmF0aW9uICkgewoJCQlyZXR1cm4gJGh1bWFuX3JlYWRhYmxlID8gJ25ldmVyIGV4cGlyZXMnIDogJ2ZhbHNlJzsKCQl9CgoJCWlmICggISAkaHVtYW5fcmVhZGFibGUgKSB7CgkJCXJldHVybiAkZXhwaXJhdGlvbjsKCQl9CgoJCSRub3cgPSB0aW1lKCk7CgoJCWlmICggJG5vdyA+ICRleHBpcmF0aW9uICkgewoJCQlyZXR1cm4gJ2V4cGlyZWQnOwoJCX0KCgkJcmV0dXJuIGh1bWFuX3RpbWVfZGlmZiggJG5vdywgJGV4cGlyYXRpb24gKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgYWxsIGV4cGlyZWQgdHJhbnNpZW50cy4KCSAqCgkgKiBPbmx5IGRlbGV0ZXMgdGhlIGV4cGlyZWQgdHJhbnNpZW50cyBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBAcGFyYW0gYm9vbCAkbmV0d29yayBXaGV0aGVyIHRvIGRlbGV0ZSB0cmFuc2llbnRzIG9yIG5ldHdvcmt8c2l0ZSB0cmFuc2llbnRzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGRlbGV0ZV9leHBpcmVkKCAkbmV0d29yayApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSRjb3VudCA9IDA7CgoJCWlmICggISAkbmV0d29yayApIHsKCQkJJGNvdW50ICs9ICR3cGRiLT5xdWVyeSgKCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCSJERUxFVEUgYSwgYiBGUk9NIHskd3BkYi0+b3B0aW9uc30gYSwgeyR3cGRiLT5vcHRpb25zfSBiCgkJCQkJCVdIRVJFIGEub3B0aW9uX25hbWUgTElLRSAlcwoJCQkJCQlBTkQgYS5vcHRpb25fbmFtZSBOT1QgTElLRSAlcwoJCQkJCQlBTkQgYi5vcHRpb25fbmFtZSA9IENPTkNBVCggJ190cmFuc2llbnRfdGltZW91dF8nLCBTVUJTVFJJTkcoIGEub3B0aW9uX25hbWUsIDEyICkgKQoJCQkJCQlBTkQgYi5vcHRpb25fdmFsdWUgPCAlZCIsCgkJCQkJVXRpbHNcZXNjX2xpa2UoICdfdHJhbnNpZW50XycgKSAuICclJywKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScsCgkJCQkJdGltZSgpCgkJCQkpCgkJCSk7CgkJfSBlbHNlIHsKCQkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQkJLy8gTm9uLU11bHRpc2l0ZSBzdG9yZXMgc2l0ZSB0cmFuc2llbnRzIGluIHRoZSBvcHRpb25zIHRhYmxlLgoJCQkJJGNvdW50ICs9ICR3cGRiLT5xdWVyeSgKCQkJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCQkJIkRFTEVURSBhLCBiIEZST00geyR3cGRiLT5vcHRpb25zfSBhLCB7JHdwZGItPm9wdGlvbnN9IGIKCQkJCQkJCVdIRVJFIGEub3B0aW9uX25hbWUgTElLRSAlcwoJCQkJCQkJQU5EIGEub3B0aW9uX25hbWUgTk9UIExJS0UgJXMKCQkJCQkJCUFORCBiLm9wdGlvbl9uYW1lID0gQ09OQ0FUKCAnX3NpdGVfdHJhbnNpZW50X3RpbWVvdXRfJywgU1VCU1RSSU5HKCBhLm9wdGlvbl9uYW1lLCAxNyApICkKCQkJCQkJCUFORCBiLm9wdGlvbl92YWx1ZSA8ICVkIiwKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJyUnLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJywKCQkJCQkJdGltZSgpCgkJCQkJKQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCS8vIE11bHRpc2l0ZSBzdG9yZXMgc2l0ZSB0cmFuc2llbnRzIGluIHRoZSBzaXRlbWV0YSB0YWJsZS4KCQkJCSRjb3VudCArPSAkd3BkYi0+cXVlcnkoCgkJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJCSJERUxFVEUgYSwgYiBGUk9NIHskd3BkYi0+c2l0ZW1ldGF9IGEsIHskd3BkYi0+c2l0ZW1ldGF9IGIKCQkJCQkJCVdIRVJFIGEubWV0YV9rZXkgTElLRSAlcwoJCQkJCQkJQU5EIGEubWV0YV9rZXkgTk9UIExJS0UgJXMKCQkJCQkJCUFORCBiLm1ldGFfa2V5ID0gQ09OQ0FUKCAnX3NpdGVfdHJhbnNpZW50X3RpbWVvdXRfJywgU1VCU1RSSU5HKCBhLm1ldGFfa2V5LCAxNyApICkKCQkJCQkJCUFORCBiLm1ldGFfdmFsdWUgPCAlZCIsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICclJywKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScsCgkJCQkJCXRpbWUoKQoJCQkJCSkKCQkJCSk7CgkJCX0KCQl9CgoJCS8vIFRoZSBhYm92ZSBxdWVyaWVzIGRlbGV0ZSB0aGUgdHJhbnNpZW50IGFuZCB0aGUgdHJhbnNpZW50IHRpbWVvdXQKCQkvLyB0aHVzIGVhY2ggdHJhbnNpZW50IGlzIGNvdW50ZWQgdHdpY2UuCgkJJGNvdW50ID0gJGNvdW50IC8gMjsKCgkJaWYgKCAkY291bnQgPiAwICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoCgkJCQlzcHJpbnRmKAoJCQkJCSclZCBleHBpcmVkICVzIGRlbGV0ZWQgZnJvbSB0aGUgZGF0YWJhc2UuJywKCQkJCQkkY291bnQsCgkJCQkJVXRpbHNccGx1cmFsaXplKCAndHJhbnNpZW50JywgJGNvdW50ICkKCQkJCSkKCQkJKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdObyBleHBpcmVkIHRyYW5zaWVudHMgZm91bmQuJyApOwoJCX0KCgkJaWYgKCB3cF91c2luZ19leHRfb2JqZWN0X2NhY2hlKCkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ1RyYW5zaWVudHMgYXJlIHN0b3JlZCBpbiBhbiBleHRlcm5hbCBvYmplY3QgY2FjaGUsIGFuZCB0aGlzIGNvbW1hbmQgb25seSBkZWxldGVzIHRob3NlIHN0b3JlZCBpbiB0aGUgZGF0YWJhc2UuIFlvdSBtdXN0IGZsdXNoIHRoZSBjYWNoZSB0byBkZWxldGUgYWxsIHRyYW5zaWVudHMuJyApOwoJCX0KCX0KCgkvKioKCSAqIERlbGV0ZXMgYWxsIHRyYW5zaWVudHMuCgkgKgoJICogT25seSBkZWxldGVzIHRoZSB0cmFuc2llbnRzIGZyb20gdGhlIGRhdGFiYXNlLgoJICoKCSAqIEBwYXJhbSBib29sICRuZXR3b3JrIFdoZXRoZXIgdG8gZGVsZXRlIHRyYW5zaWVudHMgb3IgbmV0d29ya3xzaXRlIHRyYW5zaWVudHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZGVsZXRlX2FsbCggJG5ldHdvcmsgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBUbyBlbnN1cmUgcHJvcGVyIGNvdW50IHZhbHVlcyB3ZSBmaXJzdCBkZWxldGUgYWxsIHRyYW5zaWVudHMgd2l0aCBhIHRpbWVvdXQKCQkvLyBhbmQgdGhlbiB0aGUgcmVtYWluaW5nIHRyYW5zaWVudHMgd2l0aG91dCBhIHRpbWVvdXQuCgkJJGNvdW50ID0gMDsKCgkJaWYgKCAhICRuZXR3b3JrICkgewoJCQkkZGVsZXRlZCA9ICR3cGRiLT5xdWVyeSgKCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCSJERUxFVEUgYSwgYiBGUk9NIHskd3BkYi0+b3B0aW9uc30gYSwgeyR3cGRiLT5vcHRpb25zfSBiCgkJCQkJCVdIRVJFIGEub3B0aW9uX25hbWUgTElLRSAlcwoJCQkJCQlBTkQgYS5vcHRpb25fbmFtZSBOT1QgTElLRSAlcwoJCQkJCQlBTkQgYi5vcHRpb25fbmFtZSA9IENPTkNBVCggJ190cmFuc2llbnRfdGltZW91dF8nLCBTVUJTVFJJTkcoIGEub3B0aW9uX25hbWUsIDEyICkgKSIsCgkJCQkJVXRpbHNcZXNjX2xpa2UoICdfdHJhbnNpZW50XycgKSAuICclJywKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScKCQkJCSkKCQkJKTsKCgkJCSRjb3VudCArPSAkZGVsZXRlZCAvIDI7IC8vIElnbm9yZSBhZmZlY3RlZCByb3dzIGZvciB0aW1lb3V0cy4KCgkJCSRjb3VudCArPSAkd3BkYi0+cXVlcnkoCgkJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCQkiREVMRVRFIEZST00gJHdwZGItPm9wdGlvbnMgV0hFUkUgb3B0aW9uX25hbWUgTElLRSAlcyIsCgkJCQkJVXRpbHNcZXNjX2xpa2UoICdfdHJhbnNpZW50XycgKSAuICclJwoJCQkJKQoJCQkpOwoJCX0gZWxzZSB7CgkJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJCS8vIE5vbi1NdWx0aXNpdGUgc3RvcmVzIHNpdGUgdHJhbnNpZW50cyBpbiB0aGUgb3B0aW9ucyB0YWJsZS4KCQkJCSRkZWxldGVkID0gJHdwZGItPnF1ZXJ5KAoJCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCQkiREVMRVRFIGEsIGIgRlJPTSB7JHdwZGItPm9wdGlvbnN9IGEsIHskd3BkYi0+b3B0aW9uc30gYgoJCQkJCQkJV0hFUkUgYS5vcHRpb25fbmFtZSBMSUtFICVzCgkJCQkJCQlBTkQgYS5vcHRpb25fbmFtZSBOT1QgTElLRSAlcwoJCQkJCQkJQU5EIGIub3B0aW9uX25hbWUgPSBDT05DQVQoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nLCBTVUJTVFJJTkcoIGEub3B0aW9uX25hbWUsIDE3ICkgKSIsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICclJywKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScKCQkJCQkpCgkJCQkpOwoKCQkJCSRjb3VudCArPSAkZGVsZXRlZCAvIDI7IC8vIElnbm9yZSBhZmZlY3RlZCByb3dzIGZvciB0aW1lb3V0cy4KCgkJCQkkY291bnQgKz0gJHdwZGItPnF1ZXJ5KAoJCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCQkiREVMRVRFIEZST00gJHdwZGItPm9wdGlvbnMgV0hFUkUgb3B0aW9uX25hbWUgTElLRSAlcyIsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICclJwoJCQkJCSkKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQkvLyBNdWx0aXNpdGUgc3RvcmVzIHNpdGUgdHJhbnNpZW50cyBpbiB0aGUgc2l0ZW1ldGEgdGFibGUuCgkJCQkkZGVsZXRlZCA9ICR3cGRiLT5xdWVyeSgKCQkJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCQkJIkRFTEVURSBhLCBiIEZST00geyR3cGRiLT5zaXRlbWV0YX0gYSwgeyR3cGRiLT5zaXRlbWV0YX0gYgoJCQkJCQkJV0hFUkUgYS5tZXRhX2tleSBMSUtFICVzCgkJCQkJCQlBTkQgYS5tZXRhX2tleSBOT1QgTElLRSAlcwoJCQkJCQkJQU5EIGIubWV0YV9rZXkgPSBDT05DQVQoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nLCBTVUJTVFJJTkcoIGEubWV0YV9rZXksIDE3ICkgKSIsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICclJywKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScKCQkJCQkpCgkJCQkpOwoKCQkJCSRjb3VudCArPSAkZGVsZXRlZCAvIDI7IC8vIElnbm9yZSBhZmZlY3RlZCByb3dzIGZvciB0aW1lb3V0cy4KCgkJCQkkY291bnQgKz0gJHdwZGItPnF1ZXJ5KAoJCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCQkiREVMRVRFIEZST00gJHdwZGItPnNpdGVtZXRhIFdIRVJFIG1ldGFfa2V5IExJS0UgJXMiLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF8nICkgLiAnJScKCQkJCQkpCgkJCQkpOwoJCQl9CgkJfQoKCQlpZiAoICRjb3VudCA+IDAgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcygKCQkJCXNwcmludGYoCgkJCQkJJyVkICVzIGRlbGV0ZWQgZnJvbSB0aGUgZGF0YWJhc2UuJywKCQkJCQkkY291bnQsCgkJCQkJVXRpbHNccGx1cmFsaXplKCAndHJhbnNpZW50JywgJGNvdW50ICkKCQkJCSkKCQkJKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdObyB0cmFuc2llbnRzIGZvdW5kLicgKTsKCQl9CgoJCWlmICggd3BfdXNpbmdfZXh0X29iamVjdF9jYWNoZSgpICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdUcmFuc2llbnRzIGFyZSBzdG9yZWQgaW4gYW4gZXh0ZXJuYWwgb2JqZWN0IGNhY2hlLCBhbmQgdGhpcyBjb21tYW5kIG9ubHkgZGVsZXRlcyB0aG9zZSBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlLiBZb3UgbXVzdCBmbHVzaCB0aGUgY2FjaGUgdG8gZGVsZXRlIGFsbCB0cmFuc2llbnRzLicgKTsKCQl9Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9jYWNoZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9jYWNoZV9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX2NhY2hlX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjYWNoZScsICdDYWNoZV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAndHJhbnNpZW50JywgJ1RyYW5zaWVudF9Db21tYW5kJyApOwo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBJbXBvcnRzIGZpbGVzIGFzIGF0dGFjaG1lbnRzLCByZWdlbmVyYXRlcyB0aHVtYm5haWxzLCBvciBsaXN0cyByZWdpc3RlcmVkIGltYWdlIHNpemVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBSZS1nZW5lcmF0ZSBhbGwgdGh1bWJuYWlscywgd2l0aG91dCBjb25maXJtYXRpb24uCiAqICAgICAkIHdwIG1lZGlhIHJlZ2VuZXJhdGUgLS15ZXMKICogICAgIEZvdW5kIDMgaW1hZ2VzIHRvIHJlZ2VuZXJhdGUuCiAqICAgICAxLzMgUmVnZW5lcmF0ZWQgdGh1bWJuYWlscyBmb3IgIlN5ZG5leSBIYXJib3IgQnJpZGdlIiAoSUQgNzYwKS4KICogICAgIDIvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiQm9hcmR3YWxrIiAoSUQgNzU3KS4KICogICAgIDMvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiU3VuYnVyc3QgT3ZlciBSaXZlciIgKElEIDc1NikuCiAqICAgICBTdWNjZXNzOiBSZWdlbmVyYXRlZCAzIG9mIDMgaW1hZ2VzLgogKgogKiAgICAgIyBJbXBvcnQgYSBsb2NhbCBpbWFnZSBhbmQgc2V0IGl0IHRvIGJlIHRoZSBmZWF0dXJlZCBpbWFnZSBmb3IgYSBwb3N0LgogKiAgICAgJCB3cCBtZWRpYSBpbXBvcnQgfi9Eb3dubG9hZHMvaW1hZ2UucG5nIC0tcG9zdF9pZD0xMjMgLS10aXRsZT0iQSBkb3dubG9hZGVkIHBpY3R1cmUiIC0tZmVhdHVyZWRfaW1hZ2UKICogICAgIFN1Y2Nlc3M6IEltcG9ydGVkIGZpbGUgJy9ob21lL3BlcnNvbi9Eb3dubG9hZHMvaW1hZ2UucG5nJyBhcyBhdHRhY2htZW50IElEIDE3NTMgYW5kIGF0dGFjaGVkIHRvIHBvc3QgMTIzIGFzIGZlYXR1cmVkIGltYWdlLgogKgogKiAgICAgIyBMaXN0IGFsbCByZWdpc3RlcmVkIGltYWdlIHNpemVzCiAqICAgICAkIHdwIG1lZGlhIGltYWdlLXNpemUKICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tKwogKiAgICAgfCBuYW1lICAgICAgICAgICAgICAgICAgICAgIHwgd2lkdGggfCBoZWlnaHQgfCBjcm9wICB8CiAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLSsKICogICAgIHwgZnVsbCAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgIHwgTi9BICAgfAogKiAgICAgfCB0d2VudHlmb3VydGVlbi1mdWxsLXdpZHRoIHwgMTAzOCAgfCA1NzYgICAgfCBoYXJkICB8CiAqICAgICB8IGxhcmdlICAgICAgICAgICAgICAgICAgICAgfCAxMDI0ICB8IDEwMjQgICB8IHNvZnQgIHwKICogICAgIHwgbWVkaXVtX2xhcmdlICAgICAgICAgICAgICB8IDc2OCAgIHwgMCAgICAgIHwgc29mdCAgfAogKiAgICAgfCBtZWRpdW0gICAgICAgICAgICAgICAgICAgIHwgMzAwICAgfCAzMDAgICAgfCBzb2Z0ICB8CiAqICAgICB8IHRodW1ibmFpbCAgICAgICAgICAgICAgICAgfCAxNTAgICB8IDE1MCAgICB8IGhhcmQgIHwKICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tKwogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIE1lZGlhX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBDbGVhciB0aGUgV1Agb2JqZWN0IGNhY2hlIGFmdGVyIHRoaXMgbWFueSByZWdlbmVyYXRpb25zL2ltcG9ydHMuCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCWNvbnN0IFdQX0NMRUFSX09CSkVDVF9DQUNIRV9JTlRFUlZBTCA9IDUwMDsKCgkvKioKCSAqIFJlZ2VuZXJhdGVzIHRodW1ibmFpbHMgZm9yIG9uZSBvciBtb3JlIGF0dGFjaG1lbnRzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGF0dGFjaG1lbnQtaWQ+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2YgdGhlIGF0dGFjaG1lbnRzIHRvIHJlZ2VuZXJhdGUuCgkgKgoJICogWy0taW1hZ2Vfc2l6ZT08aW1hZ2Vfc2l6ZT5dCgkgKiA6IE5hbWUgb2YgdGhlIGltYWdlIHNpemUgdG8gcmVnZW5lcmF0ZS4gT25seSB0aHVtYm5haWxzIG9mIHRoaXMgaW1hZ2Ugc2l6ZSB3aWxsIGJlIHJlZ2VuZXJhdGVkLCB0aHVtYm5haWxzIG9mIG90aGVyIGltYWdlIHNpemVzIHdpbGwgbm90LgoJICoKCSAqIFstLXNraXAtZGVsZXRlXQoJICogOiBTa2lwIGRlbGV0aW9uIG9mIHRoZSBvcmlnaW5hbCB0aHVtYm5haWxzLiBJZiB5b3VyIHRodW1ibmFpbHMgYXJlIGxpbmtlZCBmcm9tIHNvdXJjZXMgb3V0c2lkZSB5b3VyIGNvbnRyb2wsIGl0J3MgbGlrZWx5IGJlc3QgdG8gbGVhdmUgdGhlbSBhcm91bmQuIERlZmF1bHRzIHRvIGZhbHNlLgoJICoKCSAqIFstLW9ubHktbWlzc2luZ10KCSAqIDogT25seSBnZW5lcmF0ZSB0aHVtYm5haWxzIGZvciBpbWFnZXMgbWlzc2luZyBpbWFnZSBzaXplcy4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IEFuc3dlciB5ZXMgdG8gdGhlIGNvbmZpcm1hdGlvbiBtZXNzYWdlLiBDb25maXJtYXRpb24gb25seSBzaG93cyB3aGVuIG5vIElEcyBwYXNzZWQgYXMgYXJndW1lbnRzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVnZW5lcmF0ZSB0aHVtYm5haWxzIGZvciBnaXZlbiBhdHRhY2htZW50IElEcy4KCSAqICAgICAkIHdwIG1lZGlhIHJlZ2VuZXJhdGUgMTIzIDEyNCAxMjUKCSAqICAgICBGb3VuZCAzIGltYWdlcyB0byByZWdlbmVyYXRlLgoJICogICAgIDEvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiVmVydGljYWwgSW1hZ2UiIChJRCAxMjMpLgoJICogICAgIDIvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiSG9yaXpvbnRhbCBJbWFnZSIgKElEIDEyNCkuCgkgKiAgICAgMy8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJCZWF1dGlmdWwgUGljdHVyZSIgKElEIDEyNSkuCgkgKiAgICAgU3VjY2VzczogUmVnZW5lcmF0ZWQgMyBvZiAzIGltYWdlcy4KCSAqCgkgKiAgICAgIyBSZWdlbmVyYXRlIGFsbCB0aHVtYm5haWxzLCB3aXRob3V0IGNvbmZpcm1hdGlvbi4KCSAqICAgICAkIHdwIG1lZGlhIHJlZ2VuZXJhdGUgLS15ZXMKCSAqICAgICBGb3VuZCAzIGltYWdlcyB0byByZWdlbmVyYXRlLgoJICogICAgIDEvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiU3lkbmV5IEhhcmJvciBCcmlkZ2UiIChJRCA3NjApLgoJICogICAgIDIvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiQm9hcmR3YWxrIiAoSUQgNzU3KS4KCSAqICAgICAzLzMgUmVnZW5lcmF0ZWQgdGh1bWJuYWlscyBmb3IgIlN1bmJ1cnN0IE92ZXIgUml2ZXIiIChJRCA3NTYpLgoJICogICAgIFN1Y2Nlc3M6IFJlZ2VuZXJhdGVkIDMgb2YgMyBpbWFnZXMuCgkgKgoJICogICAgICMgUmUtZ2VuZXJhdGUgYWxsIHRodW1ibmFpbHMgdGhhdCBoYXZlIElEcyBiZXR3ZWVuIDEwMDAgYW5kIDIwMDAuCgkgKiAgICAgJCBzZXEgMTAwMCAyMDAwIHwgeGFyZ3Mgd3AgbWVkaWEgcmVnZW5lcmF0ZQoJICogICAgIEZvdW5kIDQgaW1hZ2VzIHRvIHJlZ2VuZXJhdGUuCgkgKiAgICAgMS80IFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJWZXJ0aWNhbCBGZWF0dXJlZCBJbWFnZSIgKElEIDEwMjcpLgoJICogICAgIDIvNCBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiSG9yaXpvbnRhbCBGZWF0dXJlZCBJbWFnZSIgKElEIDEwMjIpLgoJICogICAgIDMvNCBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiVW5pY29ybiBXYWxscGFwZXIiIChJRCAxMDQ1KS4KCSAqICAgICA0LzQgUmVnZW5lcmF0ZWQgdGh1bWJuYWlscyBmb3IgIkkgQW0gV29ydGggTG92aW5nIFdhbGxwYXBlciIgKElEIDEwMjMpLgoJICogICAgIFN1Y2Nlc3M6IFJlZ2VuZXJhdGVkIDQgb2YgNCBpbWFnZXMuCgkgKgoJICogICAgICMgUmUtZ2VuZXJhdGUgb25seSB0aGUgdGh1bWJuYWlscyBvZiAibGFyZ2UiIGltYWdlIHNpemUgZm9yIGFsbCBpbWFnZXMuCgkgKiAgICAgJCB3cCBtZWRpYSByZWdlbmVyYXRlIC0taW1hZ2Vfc2l6ZT1sYXJnZQoJICogICAgIERvIHlvdSByZWFsbHkgd2FudCB0byByZWdlbmVyYXRlIHRoZSAibGFyZ2UiIGltYWdlIHNpemUgZm9yIGFsbCBpbWFnZXM/IFt5L25dIHkKCSAqICAgICBGb3VuZCAzIGltYWdlcyB0byByZWdlbmVyYXRlLgoJICogICAgIDEvMyBSZWdlbmVyYXRlZCAibGFyZ2UiIHRodW1ibmFpbCBmb3IgIlN5ZG5leSBIYXJib3IgQnJpZGdlIiAoSUQgNzYwKS4KCSAqICAgICAyLzMgTm8gImxhcmdlIiB0aHVtYm5haWwgcmVnZW5lcmF0aW9uIG5lZWRlZCBmb3IgIkJvYXJkd2FsayIgKElEIDc1NykuCgkgKiAgICAgMy8zIFJlZ2VuZXJhdGVkICJsYXJnZSIgdGh1bWJuYWlsIGZvciAiU3VuYnVyc3QgT3ZlciBSaXZlciIgKElEIDc1NikuCgkgKiAgICAgU3VjY2VzczogUmVnZW5lcmF0ZWQgMyBvZiAzIGltYWdlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2VuZXJhdGUoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJJGFzc29jX2FyZ3MgPSB3cF9wYXJzZV9hcmdzKAoJCQkkYXNzb2NfYXJncywKCQkJWyAnaW1hZ2Vfc2l6ZScgPT4gJycgXQoJCSk7CgoJCSRpbWFnZV9zaXplID0gJGFzc29jX2FyZ3NbJ2ltYWdlX3NpemUnXTsKCQlpZiAoICRpbWFnZV9zaXplICYmICEgaW5fYXJyYXkoICRpbWFnZV9zaXplLCBnZXRfaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzKCksIHRydWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ1Vua25vd24gaW1hZ2Ugc2l6ZSAiJXMiLicsICRpbWFnZV9zaXplICkgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCWlmICggJGltYWdlX3NpemUgKSB7CgkJCQlXUF9DTEk6OmNvbmZpcm0oIHNwcmludGYoICdEbyB5b3UgcmVhbGx5IHdhbnQgdG8gcmVnZW5lcmF0ZSB0aGUgIiVzIiBpbWFnZSBzaXplIGZvciBhbGwgaW1hZ2VzPycsICRpbWFnZV9zaXplICksICRhc3NvY19hcmdzICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmNvbmZpcm0oICdEbyB5b3UgcmVhbGx5IHdhbnQgdG8gcmVnZW5lcmF0ZSBhbGwgaW1hZ2VzPycsICRhc3NvY19hcmdzICk7CgkJCX0KCQl9CgoJCSRza2lwX2RlbGV0ZSAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWRlbGV0ZScgKTsKCQkkb25seV9taXNzaW5nID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnb25seS1taXNzaW5nJyApOwoJCWlmICggJG9ubHlfbWlzc2luZyApIHsKCQkJJHNraXBfZGVsZXRlID0gdHJ1ZTsKCQl9CgoJCSRhZGRpdGlvbmFsX21pbWVfdHlwZXMgPSBhcnJheSgpOwoKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuNycsICc+PScgKSApIHsKCQkJJGFkZGl0aW9uYWxfbWltZV90eXBlc1tdID0gJ2FwcGxpY2F0aW9uL3BkZic7CgkJfQoKCQkkaW1hZ2VzID0gJHRoaXMtPmdldF9pbWFnZXMoICRhcmdzLCAkYWRkaXRpb25hbF9taW1lX3R5cGVzICk7CgkJJGNvdW50ICA9ICRpbWFnZXMtPnBvc3RfY291bnQ7CgoJCWlmICggISAkY291bnQgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ05vIGltYWdlcyBmb3VuZC4nICk7CgkJCXJldHVybjsKCQl9CgoJCVdQX0NMSTo6bG9nKAoJCQlzcHJpbnRmKAoJCQkJJ0ZvdW5kICUxJGQgJTIkcyB0byByZWdlbmVyYXRlLicsCgkJCQkkY291bnQsCgkJCQlfbiggJ2ltYWdlJywgJ2ltYWdlcycsICRjb3VudCApCgkJCSkKCQkpOwoKCQlpZiAoICRpbWFnZV9zaXplICkgewoJCQkkaW1hZ2Vfc2l6ZV9maWx0ZXJzID0gJHRoaXMtPmFkZF9pbWFnZV9zaXplX2ZpbHRlcnMoICRpbWFnZV9zaXplICk7CgkJfQoKCQkkbnVtYmVyICAgID0gMDsKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkc2tpcHMgICAgID0gMDsKCQlmb3JlYWNoICggJGltYWdlcy0+cG9zdHMgYXMgJHBvc3QgKSB7CgkJCSRudW1iZXIrKzsKCQkJaWYgKCAwID09PSAkbnVtYmVyICUgc2VsZjo6V1BfQ0xFQVJfT0JKRUNUX0NBQ0hFX0lOVEVSVkFMICkgewoJCQkJVXRpbHNcd3BfY2xlYXJfb2JqZWN0X2NhY2hlKCk7CgkJCX0KCQkJJHRoaXMtPnByb2Nlc3NfcmVnZW5lcmF0aW9uKCAkcG9zdC0+SUQsICRza2lwX2RlbGV0ZSwgJG9ubHlfbWlzc2luZywgJGltYWdlX3NpemUsICRudW1iZXIgLiAnLycgLiAkY291bnQsICRzdWNjZXNzZXMsICRlcnJvcnMsICRza2lwcyApOwoJCX0KCgkJaWYgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJJHRoaXMtPnJlbW92ZV9pbWFnZV9zaXplX2ZpbHRlcnMoICRpbWFnZV9zaXplX2ZpbHRlcnMgKTsKCQl9CgoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ2ltYWdlJywgJ3JlZ2VuZXJhdGUnLCAkY291bnQsICRzdWNjZXNzZXMsICRlcnJvcnMsICRza2lwcyApOwoJfQoKCS8qKgoJICogQ3JlYXRlcyBhdHRhY2htZW50cyBmcm9tIGxvY2FsIGZpbGVzIG9yIFVSTHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxmaWxlPi4uLgoJICogOiBQYXRoIHRvIGZpbGUgb3IgZmlsZXMgdG8gYmUgaW1wb3J0ZWQuIFN1cHBvcnRzIHRoZSBnbG9iKDMpIGNhcGFiaWxpdGllcyBvZiB0aGUgY3VycmVudCBzaGVsbC4KCSAqICAgICBJZiBmaWxlIGlzIHJlY29nbml6ZWQgYXMgYSBVUkwgKGZvciBleGFtcGxlLCB3aXRoIGEgc2NoZW1lIG9mIGh0dHAgb3IgZnRwKSwgdGhlIGZpbGUgd2lsbCBiZQoJICogICAgIGRvd25sb2FkZWQgdG8gYSB0ZW1wIGZpbGUgYmVmb3JlIGJlaW5nIHNpZGVsb2FkZWQuCgkgKgoJICogWy0tcG9zdF9pZD08cG9zdF9pZD5dCgkgKiA6IElEIG9mIHRoZSBwb3N0IHRvIGF0dGFjaCB0aGUgaW1wb3J0ZWQgZmlsZXMgdG8uCgkgKgoJICogWy0tdGl0bGU9PHRpdGxlPl0KCSAqIDogQXR0YWNobWVudCB0aXRsZSAocG9zdCB0aXRsZSBmaWVsZCkuCgkgKgoJICogWy0tY2FwdGlvbj08Y2FwdGlvbj5dCgkgKiA6IENhcHRpb24gZm9yIGF0dGFjaGVudCAocG9zdCBleGNlcnB0IGZpZWxkKS4KCSAqCgkgKiBbLS1hbHQ9PGFsdF90ZXh0Pl0KCSAqIDogQWx0IHRleHQgZm9yIGltYWdlIChzYXZlZCBhcyBwb3N0IG1ldGEpLgoJICoKCSAqIFstLWRlc2M9PGRlc2NyaXB0aW9uPl0KCSAqIDogIkRlc2NyaXB0aW9uIiBmaWVsZCAocG9zdCBjb250ZW50KSBvZiBhdHRhY2htZW50IHBvc3QuCgkgKgoJICogWy0tc2tpcC1jb3B5XQoJICogOiBJZiBzZXQsIG1lZGlhIGZpbGVzIChsb2NhbCBvbmx5KSBhcmUgaW1wb3J0ZWQgdG8gdGhlIGxpYnJhcnkgYnV0IG5vdCBtb3ZlZCBvbiBkaXNrLgoJICogRmlsZSBuYW1lcyB3aWxsIG5vdCBiZSBydW4gdGhyb3VnaCB3cF91bmlxdWVfZmlsZW5hbWUoKSB3aXRoIHRoaXMgc2V0LgoJICoKCSAqIFstLXByZXNlcnZlLWZpbGV0aW1lXQoJICogOiBVc2UgdGhlIGZpbGUgbW9kaWZpZWQgdGltZSBhcyB0aGUgcG9zdCBwdWJsaXNoZWQgJiBtb2RpZmllZCBkYXRlcy4KCSAqIFJlbW90ZSBmaWxlcyB3aWxsIGFsd2F5cyB1c2UgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1mZWF0dXJlZF9pbWFnZV0KCSAqIDogSWYgc2V0LCBzZXQgdGhlIGltcG9ydGVkIGltYWdlIGFzIHRoZSBGZWF0dXJlZCBJbWFnZSBvZiB0aGUgcG9zdCBpdHMgYXR0YWNoZWQgdG8uCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBPdXRwdXQganVzdCB0aGUgbmV3IGF0dGFjaG1lbnQgSUQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbXBvcnQgYWxsIGpwZ3MgaW4gdGhlIGN1cnJlbnQgdXNlcidzICJQaWN0dXJlcyIgZGlyZWN0b3J5LCBub3QgYXR0YWNoZWQgdG8gYW55IHBvc3QuCgkgKiAgICAgJCB3cCBtZWRpYSBpbXBvcnQgfi9QaWN0dXJlcy8qKlwvKi5qcGcKCSAqICAgICBJbXBvcnRlZCBmaWxlICcvaG9tZS9wZXJzb24vUGljdHVyZXMvbGFuZHNjYXBlLXBob3RvLmpwZycgYXMgYXR0YWNobWVudCBJRCAxNzUxLgoJICogICAgIEltcG9ydGVkIGZpbGUgJy9ob21lL3BlcnNvbi9QaWN0dXJlcy9mYXNoaW9uLWljb24uanBnJyBhcyBhdHRhY2htZW50IElEIDE3NTIuCgkgKiAgICAgU3VjY2VzczogSW1wb3J0ZWQgMiBvZiAyIGl0ZW1zLgoJICoKCSAqICAgICAjIEltcG9ydCBhIGxvY2FsIGltYWdlIGFuZCBzZXQgaXQgdG8gYmUgdGhlIHBvc3QgdGh1bWJuYWlsIGZvciBhIHBvc3QuCgkgKiAgICAgJCB3cCBtZWRpYSBpbXBvcnQgfi9Eb3dubG9hZHMvaW1hZ2UucG5nIC0tcG9zdF9pZD0xMjMgLS10aXRsZT0iQSBkb3dubG9hZGVkIHBpY3R1cmUiIC0tZmVhdHVyZWRfaW1hZ2UKCSAqICAgICBJbXBvcnRlZCBmaWxlICcvaG9tZS9wZXJzb24vRG93bmxvYWRzL2ltYWdlLnBuZycgYXMgYXR0YWNobWVudCBJRCAxNzUzIGFuZCBhdHRhY2hlZCB0byBwb3N0IDEyMyBhcyBmZWF0dXJlZCBpbWFnZS4KCSAqICAgICBTdWNjZXNzOiBJbXBvcnRlZCAxIG9mIDEgaW1hZ2VzLgoJICoKCSAqICAgICAjIEltcG9ydCBhIGxvY2FsIGltYWdlLCBidXQgc2V0IGl0IGFzIHRoZSBmZWF0dXJlZCBpbWFnZSBmb3IgYWxsIHBvc3RzLgoJICogICAgICMgMS4gSW1wb3J0IHRoZSBpbWFnZSBhbmQgZ2V0IGl0cyBhdHRhY2htZW50IElELgoJICogICAgICMgMi4gQXNzaWduIHRoZSBhdHRhY2htZW50IElEIGFzIHRoZSBmZWF0dXJlZCBpbWFnZSBmb3IgYWxsIHBvc3RzLgoJICogICAgICQgQVRUQUNITUVOVF9JRD0iJCh3cCBtZWRpYSBpbXBvcnQgfi9Eb3dubG9hZHMvaW1hZ2UucG5nIC0tcG9yY2VsYWluKSIKCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLXBvc3RfdHlwZT1wb3N0IC0tZm9ybWF0PWlkcyB8IHhhcmdzIC1kICcgJyAtSSAlIHdwIHBvc3QgbWV0YSBhZGQgJSBfdGh1bWJuYWlsX2lkICRBVFRBQ0hNRU5UX0lECgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqCgkgKiAgICAgIyBJbXBvcnQgYW4gaW1hZ2UgZnJvbSB0aGUgd2ViLgoJICogICAgICQgd3AgbWVkaWEgaW1wb3J0IGh0dHA6Ly9zLndvcmRwcmVzcy5vcmcvc3R5bGUvaW1hZ2VzL3dwLWhlYWRlci1sb2dvLnBuZyAtLXRpdGxlPSdUaGUgV29yZFByZXNzIGxvZ28nIC0tYWx0PSJTZW1hbnRpYyBwZXJzb25hbCBwdWJsaXNoaW5nIgoJICogICAgIEltcG9ydGVkIGZpbGUgJ2h0dHA6Ly9zLndvcmRwcmVzcy5vcmcvc3R5bGUvaW1hZ2VzL3dwLWhlYWRlci1sb2dvLnBuZycgYXMgYXR0YWNobWVudCBJRCAxNzU1LgoJICogICAgIFN1Y2Nlc3M6IEltcG9ydGVkIDEgb2YgMSBpbWFnZXMuCgkgKgoJICogICAgICMgR2V0IHRoZSBVUkwgZm9yIGFuIGF0dGFjaG1lbnQgYWZ0ZXIgaW1wb3J0LgoJICogICAgICQgd3AgbWVkaWEgaW1wb3J0IGh0dHA6Ly9zLndvcmRwcmVzcy5vcmcvc3R5bGUvaW1hZ2VzL3dwLWhlYWRlci1sb2dvLnBuZyAtLXBvcmNlbGFpbiB8IHhhcmdzIC1JIHt9IHdwIHBvc3QgbGlzdCAtLXBvc3RfX2luPXt9IC0tZmllbGQ9dXJsIC0tcG9zdF90eXBlPWF0dGFjaG1lbnQKCSAqICAgICBodHRwOi8vd29yZHByZXNzLWRldmVsb3AuZGV2L3dwLWhlYWRlci1sb2dvLwoJICovCglwdWJsaWMgZnVuY3Rpb24gaW1wb3J0KCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSRhc3NvY19hcmdzID0gd3BfcGFyc2VfYXJncygKCQkJJGFzc29jX2FyZ3MsCgkJCWFycmF5KAoJCQkJJ3RpdGxlJyAgID0+ICcnLAoJCQkJJ2NhcHRpb24nID0+ICcnLAoJCQkJJ2FsdCcgICAgID0+ICcnLAoJCQkJJ2Rlc2MnICAgID0+ICcnLAoJCQkpCgkJKTsKCgkJLy8gQXNzdW1lIHRoZSBtb3N0IGdlbmVyaWMgdGVybQoJCSRub3VuID0gJ2l0ZW0nOwoKCQkvLyBDdXJyZW50IHNpdGUncyB0aW1lem9uZSBvZmZzZXQuCgkJJGdtdF9vZmZzZXQgPSBnZXRfb3B0aW9uKCAnZ210X29mZnNldCcgKTsKCgkJLy8gVXNlIHRoZSBub3VuIGBpbWFnZWAgd2hlbiBzdXJlIHRoZSBtZWRpYSBmaWxlIGlzIGFuIGltYWdlCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmZWF0dXJlZF9pbWFnZScgKSB8fCAkYXNzb2NfYXJnc1snYWx0J10gKSB7CgkJCSRub3VuID0gJ2ltYWdlJzsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydwb3N0X2lkJ10gKSApIHsKCQkJaWYgKCAhIGdldF9wb3N0KCAkYXNzb2NfYXJnc1sncG9zdF9pZCddICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdJbnZhbGlkIC0tcG9zdF9pZCcgKTsKCQkJCSRhc3NvY19hcmdzWydwb3N0X2lkJ10gPSBmYWxzZTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRhc3NvY19hcmdzWydwb3N0X2lkJ10gPSBmYWxzZTsKCQl9CgoJCSRudW1iZXIgICAgPSAwOwoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkZmlsZSApIHsKCQkJJG51bWJlcisrOwoJCQlpZiAoIDAgPT09ICRudW1iZXIgJSBzZWxmOjpXUF9DTEVBUl9PQkpFQ1RfQ0FDSEVfSU5URVJWQUwgKSB7CgkJCQlVdGlsc1x3cF9jbGVhcl9vYmplY3RfY2FjaGUoKTsKCQkJfQoKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5wYXJzZV91cmxfcGFyc2VfdXJsIC0tIHBhcnNlX3VybCB3aWxsIG9ubHkgYmUgdXNlZCBpbiBhYnNlbmNlIG9mIHdwX3BhcnNlX3VybC4KCQkJJGlzX2ZpbGVfcmVtb3RlID0gZnVuY3Rpb25fZXhpc3RzKCAnd3BfcGFyc2VfdXJsJyApID8gd3BfcGFyc2VfdXJsKCAkZmlsZSwgUEhQX1VSTF9IT1NUICkgOiBwYXJzZV91cmwoICRmaWxlLCBQSFBfVVJMX0hPU1QgKTsKCQkJJG9yaWdfZmlsZW5hbWUgID0gJGZpbGU7CgkJCSRmaWxlX3RpbWUgICAgICA9ICcnOwoKCQkJaWYgKCBlbXB0eSggJGlzX2ZpbGVfcmVtb3RlICkgKSB7CgkJCQlpZiAoICEgZmlsZV9leGlzdHMoICRmaWxlICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVW5hYmxlIHRvIGltcG9ydCBmaWxlICckZmlsZScuIFJlYXNvbjogRmlsZSBkb2Vzbid0IGV4aXN0LiIgKTsKCQkJCQkkZXJyb3JzKys7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtY29weScgKSApIHsKCQkJCQkkdGVtcGZpbGUgPSAkZmlsZTsKCQkJCX0gZWxzZSB7CgkJCQkJJHRlbXBmaWxlID0gJHRoaXMtPm1ha2VfY29weSggJGZpbGUgKTsKCQkJCX0KCQkJCSRuYW1lID0gVXRpbHNcYmFzZW5hbWUoICRmaWxlICk7CgoJCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwcmVzZXJ2ZS1maWxldGltZScgKSApIHsKCQkJCQkkZmlsZV90aW1lID0gQGZpbGVtdGltZSggJGZpbGUgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCSR0ZW1wZmlsZSA9IGRvd25sb2FkX3VybCggJGZpbGUgKTsKCQkJCWlmICggaXNfd3BfZXJyb3IoICR0ZW1wZmlsZSApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQkJc3ByaW50ZigKCQkJCQkJCSJVbmFibGUgdG8gaW1wb3J0IGZpbGUgJyVzJy4gUmVhc29uOiAlcyIsCgkJCQkJCQkkZmlsZSwKCQkJCQkJCWltcGxvZGUoICcsICcsICR0ZW1wZmlsZS0+Z2V0X2Vycm9yX21lc3NhZ2VzKCkgKQoJCQkJCQkpCgkJCQkJKTsKCQkJCQkkZXJyb3JzKys7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkbmFtZSA9IHN0cnRvayggVXRpbHNcYmFzZW5hbWUoICRmaWxlICksICc/JyApOwoJCQl9CgoJCQkkZmlsZV9hcnJheSA9IGFycmF5KAoJCQkJJ3RtcF9uYW1lJyA9PiAkdGVtcGZpbGUsCgkJCQknbmFtZScgICAgID0+ICRuYW1lLAoJCQkpOwoKCQkJJHBvc3RfYXJyYXkgPSBhcnJheSgKCQkJCSdwb3N0X3RpdGxlJyAgID0+ICRhc3NvY19hcmdzWyd0aXRsZSddLAoJCQkJJ3Bvc3RfZXhjZXJwdCcgPT4gJGFzc29jX2FyZ3NbJ2NhcHRpb24nXSwKCQkJCSdwb3N0X2NvbnRlbnQnID0+ICRhc3NvY19hcmdzWydkZXNjJ10sCgkJCSk7CgoJCQlpZiAoICEgZW1wdHkoICRmaWxlX3RpbWUgKSApIHsKCQkJCSRwb3N0X2FycmF5Wydwb3N0X2RhdGUnXSAgICAgICAgID0gZ21kYXRlKCAnWS1tLWQgSDppOnMnLCAkZmlsZV90aW1lICsgKCAkZ210X29mZnNldCAqIEhPVVJfSU5fU0VDT05EUyApICk7CgkJCQkkcG9zdF9hcnJheVsncG9zdF9kYXRlX2dtdCddICAgICA9IGdtZGF0ZSggJ1ktbS1kIEg6aTpzJywgJGZpbGVfdGltZSApOwoJCQkJJHBvc3RfYXJyYXlbJ3Bvc3RfbW9kaWZpZWQnXSAgICAgPSBnbWRhdGUoICdZLW0tZCBIOmk6cycsICRmaWxlX3RpbWUgKyAoICRnbXRfb2Zmc2V0ICogSE9VUl9JTl9TRUNPTkRTICkgKTsKCQkJCSRwb3N0X2FycmF5Wydwb3N0X21vZGlmaWVkX2dtdCddID0gZ21kYXRlKCAnWS1tLWQgSDppOnMnLCAkZmlsZV90aW1lICk7CgkJCX0KCgkJCSRwb3N0X2FycmF5ID0gd3Bfc2xhc2goICRwb3N0X2FycmF5ICk7CgoJCQkvLyB1c2UgaW1hZ2UgZXhpZi9pcHRjIGRhdGEgZm9yIHRpdGxlIGFuZCBjYXB0aW9uIGRlZmF1bHRzIGlmIHBvc3NpYmxlCgkJCWlmICggZW1wdHkoICRwb3N0X2FycmF5Wydwb3N0X3RpdGxlJ10gKSB8fCBlbXB0eSggJHBvc3RfYXJyYXlbJ3Bvc3RfZXhjZXJwdCddICkgKSB7CgkJCQkvLyBAY29kaW5nU3RhbmRhcmRzSWdub3JlU3RhcnQKCQkJCSRpbWFnZV9tZXRhID0gQHdwX3JlYWRfaW1hZ2VfbWV0YWRhdGEoICR0ZW1wZmlsZSApOwoJCQkJLy8gQGNvZGluZ1N0YW5kYXJkc0lnbm9yZUVuZAoJCQkJaWYgKCAhIGVtcHR5KCAkaW1hZ2VfbWV0YSApICkgewoJCQkJCWlmICggZW1wdHkoICRwb3N0X2FycmF5Wydwb3N0X3RpdGxlJ10gKSAmJiB0cmltKCAkaW1hZ2VfbWV0YVsndGl0bGUnXSApICYmICEgaXNfbnVtZXJpYyggc2FuaXRpemVfdGl0bGUoICRpbWFnZV9tZXRhWyd0aXRsZSddICkgKSApIHsKCQkJCQkJJHBvc3RfYXJyYXlbJ3Bvc3RfdGl0bGUnXSA9ICRpbWFnZV9tZXRhWyd0aXRsZSddOwoJCQkJCX0KCgkJCQkJaWYgKCBlbXB0eSggJHBvc3RfYXJyYXlbJ3Bvc3RfZXhjZXJwdCddICkgJiYgdHJpbSggJGltYWdlX21ldGFbJ2NhcHRpb24nXSApICkgewoJCQkJCQkkcG9zdF9hcnJheVsncG9zdF9leGNlcnB0J10gPSAkaW1hZ2VfbWV0YVsnY2FwdGlvbiddOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJaWYgKCBlbXB0eSggJHBvc3RfYXJyYXlbJ3Bvc3RfdGl0bGUnXSApICkgewoJCQkJJHBvc3RfYXJyYXlbJ3Bvc3RfdGl0bGUnXSA9IHByZWdfcmVwbGFjZSggJy9cLlteLl0rJC8nLCAnJywgVXRpbHNcYmFzZW5hbWUoICRmaWxlICkgKTsKCQkJfQoKCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWNvcHknICkgKSB7CgkJCQkkd3BfZmlsZXR5cGUgICAgICAgICAgICAgICAgICA9IHdwX2NoZWNrX2ZpbGV0eXBlKCAkZmlsZSwgbnVsbCApOwoJCQkJJHBvc3RfYXJyYXlbJ3Bvc3RfbWltZV90eXBlJ10gPSAkd3BfZmlsZXR5cGVbJ3R5cGUnXTsKCQkJCSRwb3N0X2FycmF5Wydwb3N0X3N0YXR1cyddICAgID0gJ2luaGVyaXQnOwoKCQkJCSRzdWNjZXNzID0gd3BfaW5zZXJ0X2F0dGFjaG1lbnQoICRwb3N0X2FycmF5LCAkZmlsZSwgJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSApOwoJCQkJaWYgKCBpc193cF9lcnJvciggJHN1Y2Nlc3MgKSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJCXNwcmludGYoCgkJCQkJCQkiVW5hYmxlIHRvIGluc2VydCBmaWxlICclcycuIFJlYXNvbjogJXMiLAoJCQkJCQkJJG9yaWdfZmlsZW5hbWUsCgkJCQkJCQlpbXBsb2RlKCAnLCAnLCAkc3VjY2Vzcy0+Z2V0X2Vycm9yX21lc3NhZ2VzKCkgKQoJCQkJCQkpCgkJCQkJKTsKCQkJCQkkZXJyb3JzKys7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQl3cF91cGRhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJHN1Y2Nlc3MsIHdwX2dlbmVyYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGEoICRzdWNjZXNzLCAkZmlsZSApICk7CgkJCX0gZWxzZSB7CgkJCQkvLyBEZWxldGVzIHRoZSB0ZW1wb3JhcnkgZmlsZS4KCQkJCSRzdWNjZXNzID0gbWVkaWFfaGFuZGxlX3NpZGVsb2FkKCAkZmlsZV9hcnJheSwgJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSwgJGFzc29jX2FyZ3NbJ3RpdGxlJ10sICRwb3N0X2FycmF5ICk7CgkJCQlpZiAoIGlzX3dwX2Vycm9yKCAkc3VjY2VzcyApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQkJc3ByaW50ZigKCQkJCQkJCSJVbmFibGUgdG8gaW1wb3J0IGZpbGUgJyVzJy4gUmVhc29uOiAlcyIsCgkJCQkJCQkkb3JpZ19maWxlbmFtZSwKCQkJCQkJCWltcGxvZGUoICcsICcsICRzdWNjZXNzLT5nZXRfZXJyb3JfbWVzc2FnZXMoKSApCgkJCQkJCSkKCQkJCQkpOwoJCQkJCSRlcnJvcnMrKzsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJfQoKCQkJLy8gU2V0IGFsdCB0ZXh0CgkJCWlmICggJGFzc29jX2FyZ3NbJ2FsdCddICkgewoJCQkJdXBkYXRlX3Bvc3RfbWV0YSggJHN1Y2Nlc3MsICdfd3BfYXR0YWNobWVudF9pbWFnZV9hbHQnLCB3cF9zbGFzaCggJGFzc29jX2FyZ3NbJ2FsdCddICkgKTsKCQkJfQoKCQkJLy8gU2V0IGFzIGZlYXR1cmVkIGltYWdlLCBpZiAtLXBvc3RfaWQgYW5kIC0tZmVhdHVyZWRfaW1hZ2UgYXJlIHNldAoJCQlpZiAoICRhc3NvY19hcmdzWydwb3N0X2lkJ10gJiYgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZmVhdHVyZWRfaW1hZ2UnICkgKSB7CgkJCQl1cGRhdGVfcG9zdF9tZXRhKCAkYXNzb2NfYXJnc1sncG9zdF9pZCddLCAnX3RodW1ibmFpbF9pZCcsICRzdWNjZXNzICk7CgkJCX0KCgkJCSRhdHRhY2htZW50X3N1Y2Nlc3NfdGV4dCA9ICcnOwoJCQlpZiAoICRhc3NvY19hcmdzWydwb3N0X2lkJ10gKSB7CgkJCQkkYXR0YWNobWVudF9zdWNjZXNzX3RleHQgPSAiIGFuZCBhdHRhY2hlZCB0byBwb3N0IHskYXNzb2NfYXJnc1sncG9zdF9pZCddfSI7CgkJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZlYXR1cmVkX2ltYWdlJyApICkgewoJCQkJCSRhdHRhY2htZW50X3N1Y2Nlc3NfdGV4dCAuPSAnIGFzIGZlYXR1cmVkIGltYWdlJzsKCQkJCX0KCQkJfQoKCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICRzdWNjZXNzICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZygKCQkJCQlzcHJpbnRmKAoJCQkJCQkiSW1wb3J0ZWQgZmlsZSAnJXMnIGFzIGF0dGFjaG1lbnQgSUQgJWQlcy4iLAoJCQkJCQkkb3JpZ19maWxlbmFtZSwKCQkJCQkJJHN1Y2Nlc3MsCgkJCQkJCSRhdHRhY2htZW50X3N1Y2Nlc3NfdGV4dAoJCQkJCSkKCQkJCSk7CgkJCX0KCQkJJHN1Y2Nlc3NlcysrOwoJCX0KCgkJLy8gUmVwb3J0IHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJG5vdW4sICdpbXBvcnQnLCBjb3VudCggJGFyZ3MgKSwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJCX0gZWxzZWlmICggJGVycm9ycyApIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoJfQoKCS8qKgoJICogTGlzdHMgaW1hZ2Ugc2l6ZXMgcmVnaXN0ZXJlZCB3aXRoIFdvcmRQcmVzcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBzcGVjaWZpYyBmb3JtYXQKCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBqc29uCgkgKiAgIC0gY3N2CgkgKiAgIC0geWFtbAoJICogICAtIGNvdW50CgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggaW1hZ2Ugc2l6ZToKCSAqICogbmFtZQoJICogKiB3aWR0aAoJICogKiBoZWlnaHQKCSAqICogY3JvcAoJICogKiByYXRpbwoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBhbGwgcmVnaXN0ZXJlZCBpbWFnZSBzaXplcwoJICogICAgICQgd3AgbWVkaWEgaW1hZ2Utc2l6ZQoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgICAgICAgICAgICAgIHwgd2lkdGggfCBoZWlnaHQgfCBjcm9wICB8IHJhdGlvIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tKwoJICogICAgIHwgZnVsbCAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgIHwgTi9BICAgfCBOL0EgICB8CgkgKiAgICAgfCB0d2VudHlmb3VydGVlbi1mdWxsLXdpZHRoIHwgMTAzOCAgfCA1NzYgICAgfCBoYXJkICB8IDE3Mzo5NnwKCSAqICAgICB8IGxhcmdlICAgICAgICAgICAgICAgICAgICAgfCAxMDI0ICB8IDEwMjQgICB8IHNvZnQgIHwgTi9BICAgfAoJICogICAgIHwgbWVkaXVtX2xhcmdlICAgICAgICAgICAgICB8IDc2OCAgIHwgMCAgICAgIHwgc29mdCAgfCBOL0EgICB8CgkgKiAgICAgfCBtZWRpdW0gICAgICAgICAgICAgICAgICAgIHwgMzAwICAgfCAzMDAgICAgfCBzb2Z0ICB8IE4vQSAgIHwKCSAqICAgICB8IHRodW1ibmFpbCAgICAgICAgICAgICAgICAgfCAxNTAgICB8IDE1MCAgICB8IGhhcmQgIHwgMToxICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgaW1hZ2Utc2l6ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gaW1hZ2Vfc2l6ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoCgkJCWFycmF5KAoJCQkJJ2ZpZWxkcycgPT4gJ25hbWUsd2lkdGgsaGVpZ2h0LGNyb3AscmF0aW8nLAoJCQkpLAoJCQkkYXNzb2NfYXJncwoJCSk7CgoJCSRzaXplcyA9ICR0aGlzLT5nZXRfcmVnaXN0ZXJlZF9pbWFnZV9zaXplcygpOwoKCQl1c29ydCgKCQkJJHNpemVzLAoJCQlmdW5jdGlvbiggJGEsICRiICkgewoJCQkJaWYgKCAkYVsnd2lkdGgnXSA9PT0gJGJbJ3dpZHRoJ10gKSB7CgkJCQkJcmV0dXJuIDA7CgkJCQl9CgkJCQlyZXR1cm4gKCAkYVsnd2lkdGgnXSA8ICRiWyd3aWR0aCddICkgPyAxIDogLTE7CgkJCX0KCQkpOwoJCWFycmF5X3Vuc2hpZnQoCgkJCSRzaXplcywKCQkJYXJyYXkoCgkJCQknbmFtZScgICA9PiAnZnVsbCcsCgkJCQknd2lkdGgnICA9PiAnJywKCQkJCSdoZWlnaHQnID0+ICcnLAoJCQkJJ2Nyb3AnICAgPT4gJ04vQScsCgkJCQkncmF0aW8nICA9PiAnTi9BJywKCQkJKQoJCSk7CgkJV1BfQ0xJXFV0aWxzXGZvcm1hdF9pdGVtcyggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCAkc2l6ZXMsIGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9yYXRpbyggJHdpZHRoLCAkaGVpZ2h0ICkgewoJCWlmICggMCA9PT0gJGhlaWdodCApIHsKCQkJcmV0dXJuICIwOnskd2lkdGh9IjsKCQl9CgoJCWlmICggMCA9PT0gJHdpZHRoICkgewoJCQlyZXR1cm4gInskaGVpZ2h0fTowIjsKCQl9CgoJCSRnY2QgICAgICAgICAgPSAkdGhpcy0+Z2NkKCAkd2lkdGgsICRoZWlnaHQgKTsKCQkkd2lkdGhfcmF0aW8gID0gJHdpZHRoIC8gJGdjZDsKCQkkaGVpZ2h0X3JhdGlvID0gJGhlaWdodCAvICRnY2Q7CgoJCXJldHVybiAieyR3aWR0aF9yYXRpb306eyRoZWlnaHRfcmF0aW99IjsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdjZCggJG51bTEsICRudW0yICkgewoJCXdoaWxlICggMCAhPT0gJG51bTIgKSB7CgkJCSR0ICAgID0gJG51bTEgJSAkbnVtMjsKCQkJJG51bTEgPSAkbnVtMjsKCQkJJG51bTIgPSAkdDsKCQl9CgkJcmV0dXJuICRudW0xOwoJfQoKCS8vIHdwX3RlbXBuYW0oKSBpbmV4cGxpY2FibHkgZm9yY2VzIGEgLnRtcCBleHRlbnNpb24sIHdoaWNoIHNwb2lscyBNSU1FIHR5cGUgZGV0ZWN0aW9uCglwcml2YXRlIGZ1bmN0aW9uIG1ha2VfY29weSggJHBhdGggKSB7CgkJJGRpciAgICAgID0gZ2V0X3RlbXBfZGlyKCk7CgkJJGZpbGVuYW1lID0gVXRpbHNcYmFzZW5hbWUoICRwYXRoICk7CgkJaWYgKCBlbXB0eSggJGZpbGVuYW1lICkgKSB7CgkJCSRmaWxlbmFtZSA9IHRpbWUoKTsKCQl9CgoJCSRmaWxlbmFtZSA9ICRkaXIgLiB3cF91bmlxdWVfZmlsZW5hbWUoICRkaXIsICRmaWxlbmFtZSApOwoJCWlmICggISBjb3B5KCAkcGF0aCwgJGZpbGVuYW1lICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgY3JlYXRlIHRlbXBvcmFyeSBmaWxlIGZvciAkcGF0aC4iICk7CgkJfQoKCQlyZXR1cm4gJGZpbGVuYW1lOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gcHJvY2Vzc19yZWdlbmVyYXRpb24oICRpZCwgJHNraXBfZGVsZXRlLCAkb25seV9taXNzaW5nLCAkaW1hZ2Vfc2l6ZSwgJHByb2dyZXNzLCAmJHN1Y2Nlc3NlcywgJiRlcnJvcnMsICYkc2tpcHMgKSB7CgoJCSR0aXRsZSA9IGdldF90aGVfdGl0bGUoICRpZCApOwoJCWlmICggJycgPT09ICR0aXRsZSApIHsKCQkJLy8gSWYgYXVkaW8gb3IgdmlkZW8gY292ZXIgYXJ0IHRoZW4gdGhlIGlkIGlzIHRoZSBzdWIgYXR0YWNobWVudCBpZCwgd2hpY2ggaGFzIG5vIHRpdGxlLgoJCQlpZiAoIG1ldGFkYXRhX2V4aXN0cyggJ3Bvc3QnLCAkaWQsICdfY292ZXJfaGFzaCcgKSApIHsKCQkJCS8vIFVuZm9ydHVuYXRlbHkgdGhlIG9ubHkgd2F5IHRvIGdldCB0aGUgYXR0YWNobWVudCB0aXRsZSB3b3VsZCBiZSB0byBkbyBhIG5vbi1pbmRleGVkIHF1ZXJ5IGFnYWluc3QgdGhlIG1ldGEgdmFsdWUgb2YgYF90aHVtYm5haWxfaWRgLiBTbyBkb24ndC4KCQkJCSRhdHRfZGVzYyA9IHNwcmludGYoICdjb3ZlciBhdHRhY2htZW50IChJRCAlZCknLCAkaWQgKTsKCQkJfSBlbHNlIHsKCQkJCSRhdHRfZGVzYyA9IHNwcmludGYoICciKG5vIHRpdGxlKSIgKElEICVkKScsICRpZCApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJGF0dF9kZXNjID0gc3ByaW50ZiggJyIlMSRzIiAoSUQgJTIkZCknLCAkdGl0bGUsICRpZCApOwoJCX0KCQkkdGh1bWJuYWlsX2Rlc2MgPSAkaW1hZ2Vfc2l6ZSA/IHNwcmludGYoICciJXMiIHRodW1ibmFpbCcsICRpbWFnZV9zaXplICkgOiAndGh1bWJuYWlsJzsKCgkJJGZ1bGxzaXplcGF0aCA9ICR0aGlzLT5nZXRfYXR0YWNoZWRfZmlsZSggJGlkICk7CgoJCWlmICggZmFsc2UgPT09ICRmdWxsc2l6ZXBhdGggfHwgISBmaWxlX2V4aXN0cyggJGZ1bGxzaXplcGF0aCApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJDYW4ndCBmaW5kICRhdHRfZGVzYy4iICk7CgkJCSRlcnJvcnMrKzsKCQkJcmV0dXJuOwoJCX0KCgkJJGlzX3BkZiA9ICdhcHBsaWNhdGlvbi9wZGYnID09PSBnZXRfcG9zdF9taW1lX3R5cGUoICRpZCApOwoKCQkkbmVlZHNfcmVnZW5lcmF0aW9uID0gJHRoaXMtPm5lZWRzX3JlZ2VuZXJhdGlvbiggJGlkLCAkZnVsbHNpemVwYXRoLCAkaXNfcGRmLCAkaW1hZ2Vfc2l6ZSwgJHNraXBfZGVsZXRlLCAkc2tpcF9pdCApOwoKCQlpZiAoICRza2lwX2l0ICkgewoJCQlXUF9DTEk6OmxvZyggIiRwcm9ncmVzcyBTa2lwcGVkICR0aHVtYm5haWxfZGVzYyByZWdlbmVyYXRpb24gZm9yICRhdHRfZGVzYy4iICk7CgkJCSRza2lwcysrOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoICRvbmx5X21pc3NpbmcgJiYgISAkbmVlZHNfcmVnZW5lcmF0aW9uICkgewoJCQlXUF9DTEk6OmxvZyggIiRwcm9ncmVzcyBObyAkdGh1bWJuYWlsX2Rlc2MgcmVnZW5lcmF0aW9uIG5lZWRlZCBmb3IgJGF0dF9kZXNjLiIgKTsKCQkJJHN1Y2Nlc3NlcysrOwoJCQlyZXR1cm47CgkJfQoKCQkkbWV0YWRhdGEgPSB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCAkaWQsICRmdWxsc2l6ZXBhdGggKTsKCQlpZiAoIGlzX3dwX2Vycm9yKCAkbWV0YWRhdGEgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnJXMgKElEICVkKScsICRtZXRhZGF0YS0+Z2V0X2Vycm9yX21lc3NhZ2UoKSwgJGlkICkgKTsKCQkJV1BfQ0xJOjpsb2coICIkcHJvZ3Jlc3MgQ291bGRuJ3QgcmVnZW5lcmF0ZSB0aHVtYm5haWxzIGZvciAkYXR0X2Rlc2MuIiApOwoJCQkkZXJyb3JzKys7CgkJCXJldHVybjsKCQl9CgoJCS8vIE5vdGUgaXQncyBwb3NzaWJsZSBmb3Igbm8gbWV0YWRhdGEgdG8gYmUgZ2VuZXJhdGVkIGZvciBQREZzIGlmIHJlc3RyaWN0ZWQgdG8gYSBzcGVjaWZpYyBpbWFnZSBzaXplLgoJCWlmICggZW1wdHkoICRtZXRhZGF0YSApICYmICEgKCAkaXNfcGRmICYmICRpbWFnZV9zaXplICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ05vIG1ldGFkYXRhLiAoSUQgJWQpJywgJGlkICkgKTsKCQkJV1BfQ0xJOjpsb2coICIkcHJvZ3Jlc3MgQ291bGRuJ3QgcmVnZW5lcmF0ZSB0aHVtYm5haWxzIGZvciAkYXR0X2Rlc2MuIiApOwoJCQkkZXJyb3JzKys7CgkJCXJldHVybjsKCQl9CgoJCWlmICggJGltYWdlX3NpemUgKSB7CgkJCWlmICggJHRoaXMtPnVwZGF0ZV9hdHRhY2htZW50X21ldGFkYXRhX2Zvcl9pbWFnZV9zaXplKCAkaWQsICRtZXRhZGF0YSwgJGltYWdlX3NpemUgKSApIHsKCQkJCVdQX0NMSTo6bG9nKCAiJHByb2dyZXNzIFJlZ2VuZXJhdGVkICR0aHVtYm5haWxfZGVzYyBmb3IgJGF0dF9kZXNjLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAiJHByb2dyZXNzIE5vICR0aHVtYm5haWxfZGVzYyByZWdlbmVyYXRpb24gbmVlZGVkIGZvciAkYXR0X2Rlc2MuIiApOwoJCQl9CgkJfSBlbHNlIHsKCQkJd3BfdXBkYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGEoICRpZCwgJG1ldGFkYXRhICk7CgoJCQlXUF9DTEk6OmxvZyggIiRwcm9ncmVzcyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAkYXR0X2Rlc2MuIiApOwoJCX0KCQkkc3VjY2Vzc2VzKys7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiByZW1vdmVfb2xkX2ltYWdlcyggJG1ldGFkYXRhLCAkZnVsbHNpemVwYXRoLCAkaW1hZ2Vfc2l6ZSApIHsKCgkJaWYgKCBlbXB0eSggJG1ldGFkYXRhWydzaXplcyddICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggJGltYWdlX3NpemUgKSB7CgkJCWlmICggZW1wdHkoICRtZXRhZGF0YVsnc2l6ZXMnXVsgJGltYWdlX3NpemUgXSApICkgewoJCQkJcmV0dXJuOwoJCQl9CgkJCSRtZXRhZGF0YVsnc2l6ZXMnXSA9IGFycmF5KCAkaW1hZ2Vfc2l6ZSA9PiAkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gKTsKCQl9CgoJCSRkaXJfcGF0aCA9IGRpcm5hbWUoICRmdWxsc2l6ZXBhdGggKSAuICcvJzsKCgkJZm9yZWFjaCAoICRtZXRhZGF0YVsnc2l6ZXMnXSBhcyAkc2l6ZV9pbmZvICkgewoJCQkkaW50ZXJtZWRpYXRlX3BhdGggPSAkZGlyX3BhdGggLiAkc2l6ZV9pbmZvWydmaWxlJ107CgoJCQlpZiAoICRpbnRlcm1lZGlhdGVfcGF0aCA9PT0gJGZ1bGxzaXplcGF0aCApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoIGZpbGVfZXhpc3RzKCAkaW50ZXJtZWRpYXRlX3BhdGggKSApIHsKCQkJCXVubGluayggJGludGVybWVkaWF0ZV9wYXRoICk7CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBuZWVkc19yZWdlbmVyYXRpb24oICRhdHRfaWQsICRmdWxsc2l6ZXBhdGgsICRpc19wZGYsICRpbWFnZV9zaXplLCAkc2tpcF9kZWxldGUsICYkc2tpcF9pdCApIHsKCgkJLy8gQXNzdW1lIG5vdCBza2lwcGluZy4KCQkkc2tpcF9pdCA9IGZhbHNlOwoKCQkvLyBOb3RlOiB6ZXJvLWxlbmd0aCBzdHJpbmcgcmV0dXJuZWQgaWYgbm8gbWV0YWRhdGEsIGZvciBpbnN0YW5jZSBpZiBQREYgb3Igbm9uLXN0YW5kYXJkIGltYWdlIChlZyBhbiBTVkcpLgoJCSRtZXRhZGF0YSA9IHdwX2dldF9hdHRhY2htZW50X21ldGFkYXRhKCAkYXR0X2lkICk7CgoJCSRpbWFnZV9zaXplcyA9ICR0aGlzLT5nZXRfaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzX2Zvcl9hdHRhY2htZW50KCAkZnVsbHNpemVwYXRoLCAkaXNfcGRmLCAkbWV0YWRhdGEsICRhdHRfaWQgKTsKCgkJLy8gRmlyc3QgY2hlY2sgaWYgbm8gYXBwbGljYWJsZSBlZGl0b3IgY3VycmVudGx5IGF2YWlsYWJsZSAobm9uLWRlc3RydWN0aXZlIC0gaWUgb2xkIHRodW1ibmFpbHMgbm90IHJlbW92ZWQpLgoJCWlmICggaXNfd3BfZXJyb3IoICRpbWFnZV9zaXplcyApICYmICdpbWFnZV9ub19lZGl0b3InID09PSAkaW1hZ2Vfc2l6ZXMtPmdldF9lcnJvcl9jb2RlKCkgKSB7CgkJCS8vIFdhcm4gdW5sZXNzIFBERiBvciBub24tc3RhbmRhcmQgaW1hZ2UuCgkJCWlmICggISAkaXNfcGRmICYmIGlzX2FycmF5KCAkbWV0YWRhdGEgKSAmJiAhIGVtcHR5KCAkbWV0YWRhdGFbJ3NpemVzJ10gKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJyVzIChJRCAlZCknLCAkaW1hZ2Vfc2l6ZXMtPmdldF9lcnJvcl9tZXNzYWdlKCksICRhdHRfaWQgKSApOwoJCQl9CgkJCSRza2lwX2l0ID0gdHJ1ZTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gSWYgdXBsb2FkZWQgd2hlbiBhcHBsaWNhYmxlIGltYWdlIGVkaXRvciBzdWNoIGFzIEltYWdpY2sgdW5hdmFpbGFibGUsIHRoZSBtZXRhZGF0YSBvciBzaXplcyBtZXRhZGF0YSBtYXkgbm90IGV4aXN0LgoJCWlmICggISBpc19hcnJheSggJG1ldGFkYXRhICkgKSB7CgkJCSRtZXRhZGF0YSA9IGFycmF5KCk7CgkJfQoJCS8vIElmIHNldCBgJG1ldGFkYXRhWydzaXplcyddYCBzaG91bGQgYmUgYXJyYXkgYnV0IGV4cGxpY2l0bHkgY2hlY2sgYXMgZm9sbG93aW5nIGNvZGUgZGVwZW5kcyBvbiBpdC4KCQlpZiAoICEgaXNzZXQoICRtZXRhZGF0YVsnc2l6ZXMnXSApIHx8ICEgaXNfYXJyYXkoICRtZXRhZGF0YVsnc2l6ZXMnXSApICkgewoJCQkkbWV0YWRhdGFbJ3NpemVzJ10gPSBhcnJheSgpOwoJCX0KCgkJLy8gUmVtb3ZlIGFueSBvbGQgdGh1bWJuYWlscyAoc28gbm93IGRlc3RydWN0aXZlKS4KCQlpZiAoICEgJHNraXBfZGVsZXRlICkgewoJCQkkdGhpcy0+cmVtb3ZlX29sZF9pbWFnZXMoICRtZXRhZGF0YSwgJGZ1bGxzaXplcGF0aCwgJGltYWdlX3NpemUgKTsKCQl9CgoJCS8vIENoZWNrIGZvciBhbnkgb3RoZXIgZXJyb3IgKHN1Y2ggYXMgbG9hZCBlcnJvcikgYXBhcnQgZnJvbSBubyBlZGl0b3IgYXZhaWxhYmxlLgoJCWlmICggaXNfd3BfZXJyb3IoICRpbWFnZV9zaXplcyApICkgewoJCQkvLyBXYXJuIGJ1dCBhc3N1bWUgaXQgbWF5IGJlIHBvc3NpYmxlIHRvIHJlZ2VuZXJhdGUgYW5kIGFsbG93IHByb2Nlc3NpbmcgdG8gY29udGludWUgYW5kIHBvc3NpYmx5IGZhaWwuCgkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJyVzIChJRCAlZCknLCAkaW1hZ2Vfc2l6ZXMtPmdldF9lcnJvcl9tZXNzYWdlKCksICRhdHRfaWQgKSApOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCS8vIEhhdmUgc2l6ZXMgLSBjaGVjayB3aGV0aGVyIHRoZXJlJ3JlIG5ldyBvbmVzIG9yIHRoZXkndmUgY2hhbmdlZC4gTm90ZSB0aGF0IGFuIGF0dGFjaG1lbnQgY2FuIGhhdmUgbm8gc2l6ZXMgaWYgaXQncyBvbiBvciBiZWxvdyB0aGUgdGh1bWJuYWlsIHRocmVzaG9sZC4KCgkJaWYgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJaWYgKCBlbXB0eSggJGltYWdlX3NpemVzWyAkaW1hZ2Vfc2l6ZSBdICkgKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkJaWYgKCBlbXB0eSggJG1ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdICkgKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCQkkbWV0YWRhdGFbJ3NpemVzJ10gPSBhcnJheSggJGltYWdlX3NpemUgPT4gJG1ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdICk7CgkJfQoKCQlpZiAoICR0aGlzLT5pbWFnZV9zaXplc19kaWZmZXIoICRpbWFnZV9zaXplcywgJG1ldGFkYXRhWydzaXplcyddICkgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJJGRpcl9wYXRoID0gZGlybmFtZSggJGZ1bGxzaXplcGF0aCApIC4gJy8nOwoKCQkvLyBDaGVjayB0aGF0IHRoZSB0aHVtYm5haWwgZmlsZXMgZXhpc3QuCgkJZm9yZWFjaCAoICRtZXRhZGF0YVsnc2l6ZXMnXSBhcyAkc2l6ZV9pbmZvICkgewoJCQkkaW50ZXJtZWRpYXRlX3BhdGggPSAkZGlyX3BhdGggLiAkc2l6ZV9pbmZvWydmaWxlJ107CgoJCQlpZiAoICRpbnRlcm1lZGlhdGVfcGF0aCA9PT0gJGZ1bGxzaXplcGF0aCApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICEgZmlsZV9leGlzdHMoICRpbnRlcm1lZGlhdGVfcGF0aCApICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8vIFdoZXRoZXIgdGhlcmUncyBuZXcgaW1hZ2Ugc2l6ZXMgb3IgdGhlIHdpZHRoL2hlaWdodCBvZiBleGlzdGluZyBpbWFnZSBzaXplcyBoYXZlIGNoYW5nZWQuCglwcml2YXRlIGZ1bmN0aW9uIGltYWdlX3NpemVzX2RpZmZlciggJGltYWdlX3NpemVzLCAkbWV0YV9zaXplcyApIHsKCQkvLyBDaGVjayBpZiBoYXZlIG5ldyBpbWFnZSBzaXplKHMpLgoJCWlmICggYXJyYXlfZGlmZiggYXJyYXlfa2V5cyggJGltYWdlX3NpemVzICksIGFycmF5X2tleXMoICRtZXRhX3NpemVzICkgKSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCS8vIENoZWNrIGlmIGltYWdlIHNpemVzIGhhdmUgY2hhbmdlZC4KCQlmb3JlYWNoICggJGltYWdlX3NpemVzIGFzICRuYW1lID0+ICRpbWFnZV9zaXplICkgewoJCQlpZiAoICRpbWFnZV9zaXplWyd3aWR0aCddICE9PSAkbWV0YV9zaXplc1sgJG5hbWUgXVsnd2lkdGgnXSB8fCAkaW1hZ2Vfc2l6ZVsnaGVpZ2h0J10gIT09ICRtZXRhX3NpemVzWyAkbmFtZSBdWydoZWlnaHQnXSApIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvLyBMaWtlIFdQJ3MgZ2V0X2ludGVybWVkaWF0ZV9pbWFnZV9zaXplcygpLCBidXQgcmVtb3ZlcyBzaXplcyB0aGF0IHdvbid0IGJlIGdlbmVyYXRlZCBmb3IgYSBwYXJ0aWN1bGFyIGF0dGFjaG1lbnQgZHVlIHRvIGl0cyBiZWluZyBvbiBvciBiZWxvdyB0aGVpciB0aHJlc2hvbGRzLAoJLy8gYW5kIHJldHVybnMgYXNzb2NpYXRpdmUgYXJyYXkgd2l0aCBzaXplIG5hbWUgPT4gd2lkdGgvaGVpZ2h0IGVudHJpZXMsIHJlc29sdmVkIHRvIGNyb3AgdmFsdWVzIGlmIGFwcGxpY2FibGUuCglwcml2YXRlIGZ1bmN0aW9uIGdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXNfZm9yX2F0dGFjaG1lbnQoICRmdWxsc2l6ZXBhdGgsICRpc19wZGYsICRtZXRhZGF0YSwgJGF0dF9pZCApIHsKCgkJLy8gTmVlZCB0byBnZXQgd2lkdGgsIGhlaWdodCBvZiBhdHRhY2htZW50IGZvciBpbWFnZV9yZXNpemVfZGltZW5zaW9ucygpLgoJCSRlZGl0b3IgPSB3cF9nZXRfaW1hZ2VfZWRpdG9yKCAkZnVsbHNpemVwYXRoICk7CgkJaWYgKCBpc193cF9lcnJvciggJGVkaXRvciApICkgewoJCQlyZXR1cm4gJGVkaXRvcjsKCQl9CgkJJHJlc3VsdCA9ICRlZGl0b3ItPmxvYWQoKTsKCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCXVuc2V0KCAkZWRpdG9yICk7CgkJCXJldHVybiAkcmVzdWx0OwoJCX0KCQlsaXN0KCAkd2lkdGgsICRoZWlnaHQgKSA9IGFycmF5X3ZhbHVlcyggJGVkaXRvci0+Z2V0X3NpemUoKSApOwoJCXVuc2V0KCAkZWRpdG9yICk7CgoJCSRzaXplcyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICR0aGlzLT5nZXRfaW50ZXJtZWRpYXRlX3NpemVzKCAkaXNfcGRmLCAkbWV0YWRhdGEsICRhdHRfaWQgKSBhcyAkbmFtZSA9PiAkc2l6ZSApIHsKCQkJLy8gTmVlZCB0byBjaGVjayBkZXN0aW5hdGlvbiBhbmQgb3JpZ2luYWwgd2lkdGggb3IgaGVpZ2h0IGRpZmZlciBiZWZvcmUgY2FsbGluZyBpbWFnZV9yZXNpemVfZGltZW5zaW9ucygpLCBvdGhlcndpc2UgaXQgd2lsbCByZXR1cm4gbm9uLWZhbHNlLgoJCQkkZGltcyA9IGltYWdlX3Jlc2l6ZV9kaW1lbnNpb25zKCAkd2lkdGgsICRoZWlnaHQsICRzaXplWyd3aWR0aCddLCAkc2l6ZVsnaGVpZ2h0J10sICRzaXplWydjcm9wJ10gKTsKCQkJaWYgKCAoICR3aWR0aCAhPT0gJHNpemVbJ3dpZHRoJ10gfHwgJGhlaWdodCAhPT0gJHNpemVbJ2hlaWdodCddICkgJiYgJGRpbXMgKSB7CgkJCQlsaXN0KCAkZHN0X3gsICRkc3RfeSwgJHNyY194LCAkc3JjX3ksICRkc3RfdywgJGRzdF9oLCAkc3JjX3csICRzcmNfaCApID0gJGRpbXM7CgkJCQkkc2l6ZXNbICRuYW1lIF0gPSBhcnJheSgKCQkJCQknd2lkdGgnICA9PiAkZHN0X3csCgkJCQkJJ2hlaWdodCcgPT4gJGRzdF9oLAoJCQkJKTsKCQkJfQoJCX0KCQlyZXR1cm4gJHNpemVzOwoJfQoKCS8vIExpa2UgV1AncyBnZXRfaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzKCksIGJ1dCByZXR1cm5zIGFzc29jaWF0aXZlIGFycmF5IHdpdGggbmFtZSA9PiBzaXplIGluZm8gZW50cmllcyAoYW5kIGNhdGVycyBmb3IgUERGcyBhbHNvKS4KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2ludGVybWVkaWF0ZV9zaXplcyggJGlzX3BkZiwgJG1ldGFkYXRhLCAkYXR0X2lkICkgewoJCWlmICggJGlzX3BkZiApIHsKCQkJLy8gQ29waWVkIGZyb20gd3BfZ2VuZXJhdGVfYXR0YWNobWVudF9tZXRhZGF0YSgpIGluICJ3cC1hZG1pbi9pbmNsdWRlcy9pbWFnZS5waHAiLgoJCQkkZmFsbGJhY2tfc2l6ZXMgPSBhcnJheSgKCQkJCSd0aHVtYm5haWwnLAoJCQkJJ21lZGl1bScsCgkJCQknbGFyZ2UnLAoJCQkpOwoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQkkaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzID0gYXBwbHlfZmlsdGVycyggJ2ZhbGxiYWNrX2ludGVybWVkaWF0ZV9pbWFnZV9zaXplcycsICRmYWxsYmFja19zaXplcywgJG1ldGFkYXRhICk7CgkJfSBlbHNlIHsKCQkJJGludGVybWVkaWF0ZV9pbWFnZV9zaXplcyA9IGdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMoKTsKCQl9CgoJCS8vIEFkYXB0ZWQgZnJvbSB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCkgaW4gIndwLWFkbWluL2luY2x1ZGVzL2ltYWdlLnBocCIuCgoJCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnd3BfZ2V0X2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMnICkgKSB7CgkJCSRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplcyA9IHdwX2dldF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzKCk7CgkJfSBlbHNlIHsKCQkJLy8gRm9yIFdQIDwgNC43LjAuCgkJCWdsb2JhbCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXM7CgkJCWlmICggISAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMgKSB7CgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gVXNlZCBhcyBhIGZhbGxiYWNrIGZvciBXb3JkUHJlc3MgdmVyc2lvbiBsZXNzIHRoYW4gNC43LjAgYXMgZnVuY3Rpb24gd3BfZ2V0X2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMgZGlkbid0IGV4aXN0IHRoZW4uCgkJCQkkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMgPSBhcnJheSgpOwoJCQl9CgkJfQoKCQkkc2l6ZXMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzIGFzICRzICkgewoJCQlpZiAoIGlzc2V0KCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXNbICRzIF1bJ3dpZHRoJ10gKSApIHsKCQkJCSRzaXplc1sgJHMgXVsnd2lkdGgnXSA9IChpbnQpICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplc1sgJHMgXVsnd2lkdGgnXTsKCQkJfSBlbHNlIHsKCQkJCSRzaXplc1sgJHMgXVsnd2lkdGgnXSA9IChpbnQpIGdldF9vcHRpb24oICJ7JHN9X3NpemVfdyIgKTsKCQkJfQoKCQkJaWYgKCBpc3NldCggJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzWyAkcyBdWydoZWlnaHQnXSApICkgewoJCQkJJHNpemVzWyAkcyBdWydoZWlnaHQnXSA9IChpbnQpICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplc1sgJHMgXVsnaGVpZ2h0J107CgkJCX0gZWxzZSB7CgkJCQkkc2l6ZXNbICRzIF1bJ2hlaWdodCddID0gKGludCkgZ2V0X29wdGlvbiggInskc31fc2l6ZV9oIiApOwoJCQl9CgoJCQlpZiAoIGlzc2V0KCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXNbICRzIF1bJ2Nyb3AnXSApICkgewoJCQkJJHNpemVzWyAkcyBdWydjcm9wJ10gPSAoYm9vbCkgJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzWyAkcyBdWydjcm9wJ107CgkJCX0gZWxzZSB7CgkJCQkvLyBGb3JjZSBQREYgdGh1bWJuYWlscyB0byBiZSBzb2Z0IGNyb3BzLgoJCQkJaWYgKCAkaXNfcGRmICYmICd0aHVtYm5haWwnID09PSAkcyApIHsKCQkJCQkkc2l6ZXNbICRzIF1bJ2Nyb3AnXSA9IGZhbHNlOwoJCQkJfSBlbHNlIHsKCQkJCQkkc2l6ZXNbICRzIF1bJ2Nyb3AnXSA9IChib29sKSBnZXRfb3B0aW9uKCAieyRzfV9jcm9wIiApOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBDaGVjayBoZXJlIHRoYXQgbm90IFBERiAoYXMgZmlsdGVyIG5vdCBhcHBsaWVkIGluIGNvcmUgaWYgaXMpIGFuZCBgJG1ldGFkYXRhYCBpcyBhcnJheSAoYXMgbWF5IG5vdCBiZSBhbmQgZmlsdGVyIG9ubHkgYXBwbGllZCBpbiBjb3JlIHdoZW4gaXMpLgoJCWlmICggISAkaXNfcGRmICYmIGlzX2FycmF5KCAkbWV0YWRhdGEgKSApIHsKCQkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc1LjMnLCAnPj0nICkgKSB7CgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQkJJHNpemVzID0gYXBwbHlfZmlsdGVycyggJ2ludGVybWVkaWF0ZV9pbWFnZV9zaXplc19hZHZhbmNlZCcsICRzaXplcywgJG1ldGFkYXRhLCAkYXR0X2lkICk7CgkJCX0gZWxzZSB7CgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQkJJHNpemVzID0gYXBwbHlfZmlsdGVycyggJ2ludGVybWVkaWF0ZV9pbWFnZV9zaXplc19hZHZhbmNlZCcsICRzaXplcywgJG1ldGFkYXRhICk7CgkJCX0KCQl9CgoJCXJldHVybiAkc2l6ZXM7Cgl9CgoJLy8gQWRkIGZpbHRlcnMgdG8gb25seSBwcm9jZXNzIGEgcGFydGljdWxhciBpbnRlcm1lZGlhdGUgaW1hZ2Ugc2l6ZSBpbiB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCkuCglwcml2YXRlIGZ1bmN0aW9uIGFkZF9pbWFnZV9zaXplX2ZpbHRlcnMoICRpbWFnZV9zaXplICkgewoJCSRpbWFnZV9zaXplX2ZpbHRlcnMgPSBhcnJheSgpOwoKCQkvLyBGb3IgaW1hZ2VzLgoJCSRpbWFnZV9zaXplX2ZpbHRlcnNbJ2ludGVybWVkaWF0ZV9pbWFnZV9zaXplc19hZHZhbmNlZCddID0gZnVuY3Rpb24gKCAkc2l6ZXMgKSB1c2UgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJLy8gJHNpemVzIGlzIGFzc29jaWF0aXZlIGFycmF5IG9mIG5hbWUgPT4gc2l6ZSBpbmZvIGVudHJpZXMuCgkJCWlmICggaXNzZXQoICRzaXplc1sgJGltYWdlX3NpemUgXSApICkgewoJCQkJcmV0dXJuIGFycmF5KCAkaW1hZ2Vfc2l6ZSA9PiAkc2l6ZXNbICRpbWFnZV9zaXplIF0gKTsKCQkJfQoJCQlyZXR1cm4gYXJyYXkoKTsKCQl9OwoKCQkvLyBGb3IgUERGIHByZXZpZXdzLgoJCSRpbWFnZV9zaXplX2ZpbHRlcnNbJ2ZhbGxiYWNrX2ludGVybWVkaWF0ZV9pbWFnZV9zaXplcyddID0gZnVuY3Rpb24gKCAkZmFsbGJhY2tfc2l6ZXMgKSB1c2UgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJLy8gJGZhbGxiYWNrX3NpemVzIGlzIGluZGV4ZWQgYXJyYXkgb2Ygc2l6ZSBuYW1lcy4KCQkJaWYgKCBpbl9hcnJheSggJGltYWdlX3NpemUsICRmYWxsYmFja19zaXplcywgdHJ1ZSApICkgewoJCQkJcmV0dXJuIGFycmF5KCAkaW1hZ2Vfc2l6ZSApOwoJCQl9CgkJCXJldHVybiBhcnJheSgpOwoJCX07CgoJCWZvcmVhY2ggKCAkaW1hZ2Vfc2l6ZV9maWx0ZXJzIGFzICRuYW1lID0+ICRmaWx0ZXIgKSB7CgkJCWFkZF9maWx0ZXIoICRuYW1lLCAkZmlsdGVyLCBQSFBfSU5UX01BWCApOwoJCX0KCgkJcmV0dXJuICRpbWFnZV9zaXplX2ZpbHRlcnM7Cgl9CgoJLy8gUmVtb3ZlIGFib3ZlIGludGVybWVkaWF0ZSBpbWFnZSBzaXplIGZpbHRlcnMuCglwcml2YXRlIGZ1bmN0aW9uIHJlbW92ZV9pbWFnZV9zaXplX2ZpbHRlcnMoICRpbWFnZV9zaXplX2ZpbHRlcnMgKSB7CgkJZm9yZWFjaCAoICRpbWFnZV9zaXplX2ZpbHRlcnMgYXMgJG5hbWUgPT4gJGZpbHRlciApIHsKCQkJcmVtb3ZlX2ZpbHRlciggJG5hbWUsICRmaWx0ZXIsIFBIUF9JTlRfTUFYICk7CgkJfQoJfQoKCS8vIFVwZGF0ZSBhdHRhY2htZW50IHNpemVzIG1ldGFkYXRhIGp1c3QgZm9yIGEgcGFydGljdWxhciBpbnRlcm1lZGlhdGUgaW1hZ2Ugc2l6ZS4KCXByaXZhdGUgZnVuY3Rpb24gdXBkYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGFfZm9yX2ltYWdlX3NpemUoICRpZCwgJG5ld19tZXRhZGF0YSwgJGltYWdlX3NpemUgKSB7CgkJJG1ldGFkYXRhID0gd3BfZ2V0X2F0dGFjaG1lbnRfbWV0YWRhdGEoICRpZCApOwoKCQlpZiAoICEgaXNfYXJyYXkoICRtZXRhZGF0YSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBJZiBoYXZlIG1ldGFkYXRhIGZvciBpbWFnZV9zaXplLgoJCWlmICggISBlbXB0eSggJG5ld19tZXRhZGF0YVsnc2l6ZXMnXVsgJGltYWdlX3NpemUgXSApICkgewoJCQkkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gPSAkbmV3X21ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdOwoJCQl3cF91cGRhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkbWV0YWRhdGEgKTsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyBFbHNlIHJlbW92ZSB1bnVzZWQgbWV0YWRhdGEgaWYgYW55LgoJCWlmICggISBlbXB0eSggJG1ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdICkgKSB7CgkJCXVuc2V0KCAkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gKTsKCQkJd3BfdXBkYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGEoICRpZCwgJG1ldGFkYXRhICk7CgkJCS8vIFRyZWF0IHJlbW92aW5nIHVudXNlZCBtZXRhZGF0YSBhcyBubyBjaGFuZ2UuCgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEdldCBpbWFnZXMgZnJvbSB0aGUgaW5zdGFsbGF0aW9uLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyAgICAgICAgICAgICAgICAgIFRoZSBxdWVyeSBhcmd1bWVudHMgdG8gdXNlLiBPcHRpb25hbC4KCSAqIEBwYXJhbSBhcnJheSAkYWRkaXRpb25hbF9taW1lX3R5cGVzIFRoZSBhZGRpdGlvbmFsIG1pbWUgdHlwZXMgdG8gc2VhcmNoIGZvci4gT3B0aW9uYWwuCgkgKgoJICogQHJldHVybiBXUF9RdWVyeSBUaGUgcXVlcnkgcmVzdWx0LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9pbWFnZXMoICRhcmdzID0gYXJyYXkoKSwgJGFkZGl0aW9uYWxfbWltZV90eXBlcyA9IGFycmF5KCkgKSB7CgkJJG1pbWVfdHlwZXMgPSBhcnJheV9tZXJnZSggYXJyYXkoICdpbWFnZScgKSwgJGFkZGl0aW9uYWxfbWltZV90eXBlcyApOwoKCQkkcXVlcnlfYXJncyA9IGFycmF5KAoJCQkncG9zdF90eXBlJyAgICAgID0+ICdhdHRhY2htZW50JywKCQkJJ3Bvc3RfX2luJyAgICAgICA9PiAkYXJncywKCQkJJ3Bvc3RfbWltZV90eXBlJyA9PiAkbWltZV90eXBlcywKCQkJJ3Bvc3Rfc3RhdHVzJyAgICA9PiAnYW55JywKCQkJJ3Bvc3RzX3Blcl9wYWdlJyA9PiAtMSwKCQkpOwoKCQlyZXR1cm4gbmV3IFdQX1F1ZXJ5KCAkcXVlcnlfYXJncyApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBtZXRhZGF0YSBmb3IgdGhlIHBhc3NlZCBpbnRlcm1lZGlhdGUgaW1hZ2Ugc2l6ZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzaXplIFRoZSBpbWFnZSBzaXplIHRvIGdldCB0aGUgbWV0YWRhdGEgZm9yLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgVGhlIGltYWdlIHNpemUgbWV0YWRhdGEuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2ludGVybWVkaWF0ZV9zaXplX21ldGFkYXRhKCAkc2l6ZSApIHsKCQkkd2lkdGggID0gaW50dmFsKCBnZXRfb3B0aW9uKCAieyRzaXplfV9zaXplX3ciICkgKTsKCQkkaGVpZ2h0ID0gaW50dmFsKCBnZXRfb3B0aW9uKCAieyRzaXplfV9zaXplX2giICkgKTsKCQkkY3JvcCAgID0gZ2V0X29wdGlvbiggInskc2l6ZX1fY3JvcCIgKTsKCgkJcmV0dXJuIGFycmF5KAoJCQknbmFtZScgICA9PiAkc2l6ZSwKCQkJJ3dpZHRoJyAgPT4gJHdpZHRoLAoJCQknaGVpZ2h0JyA9PiAkaGVpZ2h0LAoJCQknY3JvcCcgICA9PiBmYWxzZSAhPT0gJGNyb3AgPyAnaGFyZCcgOiAnc29mdCcsCgkJCSdyYXRpbycgID0+IGZhbHNlICE9PSAkY3JvcCA/ICR0aGlzLT5nZXRfcmF0aW8oICR3aWR0aCwgJGhlaWdodCApIDogJ04vQScsCgkJKTsKCX0KCgkvKioKCSAqIEdldCBhbGwgdGhlIHJlZ2lzdGVyZWQgaW1hZ2Ugc2l6ZXMgYWxvbmcgd2l0aCB0aGVpciBkaW1lbnNpb25zLgoJICoKCSAqIEBnbG9iYWwgYXJyYXkgJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzIFRoZSBhZGRpdGlvbmFsIGltYWdlIHNpemVzIHRvIHBhcnNlLgoJICoKCSAqIEBsaW5rIGh0dHBzOi8vd29yZHByZXNzLnN0YWNrZXhjaGFuZ2UuY29tL2EvMjUxNjAyIE9yaWdpbmFsIHNvbHV0aW9uLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgJGltYWdlX3NpemVzIFRoZSBpbWFnZSBzaXplcwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9yZWdpc3RlcmVkX2ltYWdlX3NpemVzKCkgewoJCWdsb2JhbCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXM7CgoJCSRpbWFnZV9zaXplcyAgICAgICAgID0gYXJyYXkoKTsKCQkkZGVmYXVsdF9pbWFnZV9zaXplcyA9IGdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMoKTsKCgkJZm9yZWFjaCAoICRkZWZhdWx0X2ltYWdlX3NpemVzIGFzICRzaXplICkgewoJCQkkaW1hZ2Vfc2l6ZXNbXSA9ICR0aGlzLT5nZXRfaW50ZXJtZWRpYXRlX3NpemVfbWV0YWRhdGEoICRzaXplICk7CgkJfQoKCQlpZiAoIGlzX2FycmF5KCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMgKSApIHsKCQkJZm9yZWFjaCAoICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplcyBhcyAkc2l6ZSA9PiAkc2l6ZV9hcmdzICkgewoJCQkJJGNyb3AgICAgICAgICAgPSBmaWx0ZXJfdmFyKCAkc2l6ZV9hcmdzWydjcm9wJ10sIEZJTFRFUl9WQUxJREFURV9CT09MRUFOICk7CgkJCQkkaW1hZ2Vfc2l6ZXNbXSA9IGFycmF5KAoJCQkJCSduYW1lJyAgID0+ICRzaXplLAoJCQkJCSd3aWR0aCcgID0+ICRzaXplX2FyZ3NbJ3dpZHRoJ10sCgkJCQkJJ2hlaWdodCcgPT4gJHNpemVfYXJnc1snaGVpZ2h0J10sCgkJCQkJJ2Nyb3AnICAgPT4gZW1wdHkoICRjcm9wICkgfHwgaXNfYXJyYXkoICRzaXplX2FyZ3NbJ2Nyb3AnXSApID8gJ3NvZnQnIDogJ2hhcmQnLAoJCQkJCSdyYXRpbycgID0+IGVtcHR5KCAkY3JvcCApIHx8IGlzX2FycmF5KCAkc2l6ZV9hcmdzWydjcm9wJ10gKSA/ICdOL0EnIDogJHRoaXMtPmdldF9yYXRpbyggJHNpemVfYXJnc1snd2lkdGgnXSwgJHNpemVfYXJnc1snaGVpZ2h0J10gKSwKCQkJCSk7CgkJCX0KCQl9CgoJCXJldHVybiAkaW1hZ2Vfc2l6ZXM7Cgl9CgoJLyoqCgkgKiBGaXggaW1hZ2Ugb3JpZW50YXRpb24gZm9yIG9uZSBvciBtb3JlIGF0dGFjaG1lbnRzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGF0dGFjaG1lbnQtaWQ+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2YgdGhlIGF0dGFjaG1lbnRzIHRvIHJlZ2VuZXJhdGUuCgkgKgoJICogWy0tZHJ5LXJ1bl0KCSAqIDogQ2hlY2sgaW1hZ2VzIG5lZWRpbmcgb3JpZW50YXRpb24gd2l0aG91dCBwZXJmb3JtaW5nIHRoZSBvcGVyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBGaXggb3JpZW50YXRpb24gZm9yIGFsbCBpbWFnZXMuCgkgKiAgICAgJCB3cCBtZWRpYSBmaXgtb3JpZW50YXRpb24KCSAqICAgICAxLzMgRml4aW5nIG9yaWVudGF0aW9uIGZvciAiTGFuZHNjYXBlXzQiIChJRCA2MikuCgkgKiAgICAgMi8zIEZpeGluZyBvcmllbnRhdGlvbiBmb3IgIkxhbmRzY2FwZV8zIiAoSUQgNjEpLgoJICogICAgIDMvMyBGaXhpbmcgb3JpZW50YXRpb24gZm9yICJMYW5kc2NhcGVfMiIgKElEIDYwKS4KCSAqICAgICBTdWNjZXNzOiBGaXhlZCAzIG9mIDMgaW1hZ2VzLgoJICoKCSAqICAgICAjIEZpeCBvcmllbnRhdGlvbiBkcnkgcnVuLgoJICogICAgICQgd3AgbWVkaWEgZml4LW9yaWVudGF0aW9uIDYzIC1kcnkgcnVuCgkgKiAgICAgMS8xICJQb3J0cmFpdF82IiAoSUQgNjMpIHdpbGwgYmUgYWZmZWN0ZWQuCgkgKiAgICAgU3VjY2VzczogMSBvZiAxIGltYWdlIHdpbGwgYmUgYWZmZWN0ZWQuCgkgKgoJICogICAgICMgRml4IG9yaWVudGF0aW9uIGZvciBzcGVjaWZpYyBpbWFnZXMuCgkgKiAgICAgJCB3cCBtZWRpYSBmaXgtb3JpZW50YXRpb24gNjMKCSAqICAgICAxLzEgRml4aW5nIG9yaWVudGF0aW9uIGZvciAiUG9ydHJhaXRfNiIgKElEIDYzKS4KCSAqICAgICBTdWNjZXNzOiBGaXhlZCAxIG9mIDEgaW1hZ2VzLgoJICoKCSAqIEBzdWJjb21tYW5kIGZpeC1vcmllbnRhdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gZml4X29yaWVudGF0aW9uKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCS8vIEVYSUYgaXMgcmVxdWlyZWQgdG8gcmVhZCBpbWFnZSBtZXRhZGF0YSBmb3Igb3JpZW50YXRpb24uCgkJaWYgKCAhIGV4dGVuc2lvbl9sb2FkZWQoICdleGlmJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiJ0VYSUYnIGV4dGVuc2lvbiBpcyBub3QgbG9hZGVkLCBpdCBpcyByZXF1aXJlZCBmb3IgdGhpcyBvcGVyYXRpb24uIiApOwoJCX0gZWxzZWlmICggISBmdW5jdGlvbl9leGlzdHMoICdleGlmX3JlYWRfZGF0YScgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkZ1bmN0aW9uICdleGlmX3JlYWRfZGF0YScgZG9lcyBub3QgZXhpc3QsIGl0IGlzIHJlcXVpcmVkIGZvciB0aGlzIG9wZXJhdGlvbi4iICk7CgkJfQoKCQkkaW1hZ2VzICA9ICR0aGlzLT5nZXRfaW1hZ2VzKCAkYXJncyApOwoJCSRjb3VudCAgID0gJGltYWdlcy0+cG9zdF9jb3VudDsKCQkkZHJ5X3J1biA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RyeS1ydW4nICk7CgoJCWlmICggISAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyBpbWFnZXMgZm91bmQuJyApOwoJCX0KCgkJJG51bWJlciAgICA9IDA7CgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJZm9yZWFjaCAoICRpbWFnZXMtPnBvc3RzIGFzICRwb3N0ICkgewoJCQkkbnVtYmVyKys7CgkJCWlmICggMCA9PT0gJG51bWJlciAlIHNlbGY6OldQX0NMRUFSX09CSkVDVF9DQUNIRV9JTlRFUlZBTCApIHsKCQkJCVV0aWxzXHdwX2NsZWFyX29iamVjdF9jYWNoZSgpOwoJCQl9CgkJCSR0aGlzLT5wcm9jZXNzX29yaWVudGF0aW9uX2ZpeCggJHBvc3QtPklELCAieyRudW1iZXJ9L3skY291bnR9IiwgJHN1Y2Nlc3NlcywgJGVycm9ycywgJGRyeV9ydW4gKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHJ5LXJ1bicgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAnJXMgb2YgJXMgJXMgd2lsbCBiZSBhZmZlY3RlZC4nLCAkc3VjY2Vzc2VzLCAkY291bnQsIFV0aWxzXHBsdXJhbGl6ZSggJ2ltYWdlJywgJGNvdW50ICkgKSApOwoJCX0gZWxzZSB7CgkJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ2ltYWdlJywgJ2ZpeCcsICRjb3VudCwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJCX0KCX0KCgkvKioKCSAqIFBlcmZvcm0gb3JpZW50YXRpb24gZml4IG9uIGF0dGFjaG1lbnRzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJGlkICAgICAgICBBdHRhY2htZW50IElkLgoJICogQHBhcmFtIHN0cmluZyAkcHJvZ3Jlc3MgIEN1cnJlbnQgcHJvZ3Jlc3Mgc3RyaW5nLgoJICogQHBhcmFtIGludCAgICAkc3VjY2Vzc2VzIENvdW50IG9mIHN1Y2Nlc3MgaW4gY3VycmVudCBvcGVyYXRpb24uCgkgKiBAcGFyYW0gaW50ICAgICRlcnJvcnMgICAgQ291bnQgb2YgZXJyb3JzIGluIGN1cnJlbnQgb3BlcmF0aW9uLgoJICogQHBhcmFtIGJvb2wgICAkZHJ5X3J1biAgIElzIHRoaXMgYSBkcnkgcnVuPwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHByb2Nlc3Nfb3JpZW50YXRpb25fZml4KCAkaWQsICRwcm9ncmVzcywgJiRzdWNjZXNzZXMsICYkZXJyb3JzLCAkZHJ5X3J1biApIHsKCQkkdGl0bGUgPSBnZXRfdGhlX3RpdGxlKCAkaWQgKTsKCQlpZiAoICcnID09PSAkdGl0bGUgKSB7CgkJCS8vIElmIGF1ZGlvIG9yIHZpZGVvIGNvdmVyIGFydCB0aGVuIHRoZSBpZCBpcyB0aGUgc3ViIGF0dGFjaG1lbnQgaWQsIHdoaWNoIGhhcyBubyB0aXRsZS4KCQkJaWYgKCBtZXRhZGF0YV9leGlzdHMoICdwb3N0JywgJGlkLCAnX2NvdmVyX2hhc2gnICkgKSB7CgkJCQkvLyBVbmZvcnR1bmF0ZWx5IHRoZSBvbmx5IHdheSB0byBnZXQgdGhlIGF0dGFjaG1lbnQgdGl0bGUgd291bGQgYmUgdG8gZG8gYSBub24taW5kZXhlZCBxdWVyeSBhZ2FpbnN0IHRoZSBtZXRhIHZhbHVlIG9mIGBfdGh1bWJuYWlsX2lkYC4gU28gZG9uJ3QuCgkJCQkkYXR0X2Rlc2MgPSBzcHJpbnRmKCAnY292ZXIgYXR0YWNobWVudCAoSUQgJWQpJywgJGlkICk7CgkJCX0gZWxzZSB7CgkJCQkkYXR0X2Rlc2MgPSBzcHJpbnRmKCAnIihubyB0aXRsZSkiIChJRCAlZCknLCAkaWQgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRhdHRfZGVzYyA9IHNwcmludGYoICciJTEkcyIgKElEICUyJGQpJywgJHRpdGxlLCAkaWQgKTsKCQl9CgoJCSRmdWxsX3NpemVfcGF0aCA9ICR0aGlzLT5nZXRfYXR0YWNoZWRfZmlsZSggJGlkICk7CgoJCWlmICggZmFsc2UgPT09ICRmdWxsX3NpemVfcGF0aCB8fCAhIGZpbGVfZXhpc3RzKCAkZnVsbF9zaXplX3BhdGggKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ2FuJ3QgZmluZCB7JGF0dF9kZXNjfS4iICk7CgkJCSRlcnJvcnMrKzsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gR2V0IGN1cnJlbnQgbWV0YWRhdGEgb2YgdGhlIGF0dGFjaG1lbnQuCgkJJG1ldGFkYXRhICAgPSB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCAkaWQsICRmdWxsX3NpemVfcGF0aCApOwoJCSRpbWFnZV9tZXRhID0gISBlbXB0eSggJG1ldGFkYXRhWydpbWFnZV9tZXRhJ10gKSA/ICRtZXRhZGF0YVsnaW1hZ2VfbWV0YSddIDogW107CgoJCWlmICggaXNzZXQoICRpbWFnZV9tZXRhWydvcmllbnRhdGlvbiddICkgJiYgYWJzaW50KCAkaW1hZ2VfbWV0YVsnb3JpZW50YXRpb24nXSApID4gMSApIHsKCQkJaWYgKCAhICRkcnlfcnVuICkgewoJCQkJV1BfQ0xJOjpsb2coICJ7JHByb2dyZXNzfSBGaXhpbmcgb3JpZW50YXRpb24gZm9yIHskYXR0X2Rlc2N9LiIgKTsKCQkJCWlmICggZmFsc2UgIT09ICR0aGlzLT5mbGlwX3JvdGF0ZV9pbWFnZSggJGlkLCAkbWV0YWRhdGEsICRpbWFnZV9tZXRhLCAkZnVsbF9zaXplX3BhdGggKSApIHsKCQkJCQkkc3VjY2Vzc2VzKys7CgkJCQl9IGVsc2UgewoJCQkJCSRlcnJvcnMrKzsKCQkJCQlXUF9DTEk6OmxvZyggIkNvdWxkbid0IGZpeCBvcmllbnRhdGlvbiBmb3IgeyRhdHRfZGVzY30uIiApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICJ7JHByb2dyZXNzfSB7JGF0dF9kZXNjfSB3aWxsIGJlIGFmZmVjdGVkLiIgKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6bG9nKCAieyRwcm9ncmVzc30gTm8gb3JpZW50YXRpb24gZml4IHJlcXVpcmVkIGZvciB7JGF0dF9kZXNjfS4iICk7CgkJfQoJfQoKCS8qKgoJICogUGVyZm9ybSBpbWFnZSByb3RhdGUgb3BlcmF0aW9ucyBvbiB0aGUgaW1hZ2UuCgkgKgoJICogQHBhcmFtIGludCAgICAkaWQgICAgICAgICAgICAgQXR0YWNobWVudCBJZC4KCSAqIEBwYXJhbSBhcnJheSAgJG1ldGFkYXRhICAgICAgIEF0dGFjaG1lbnQgTWV0YWRhdGEuCgkgKiBAcGFyYW0gYXJyYXkgICRpbWFnZV9tZXRhICAgICBgaW1hZ2VfbWV0YWAgaW5mb3JtYXRpb24gZm9yIHRoZSBhdHRhY2htZW50LgoJICogQHBhcmFtIHN0cmluZyAkZnVsbF9zaXplX3BhdGggUGF0aCB0byBvcmlnaW5hbCBpbWFnZS4KCSAqCgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgaW1hZ2Ugcm90YXRpb24gb3BlcmF0aW9uIHN1Y2NlZWRlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBmbGlwX3JvdGF0ZV9pbWFnZSggJGlkLCAkbWV0YWRhdGEsICRpbWFnZV9tZXRhLCAkZnVsbF9zaXplX3BhdGggKSB7CgkJJGVkaXRvciA9IHdwX2dldF9pbWFnZV9lZGl0b3IoICRmdWxsX3NpemVfcGF0aCApOwoKCQlpZiAoICEgaXNfd3BfZXJyb3IoICRlZGl0b3IgKSApIHsKCQkJJG9wZXJhdGlvbnMgPSAkdGhpcy0+Y2FsY3VsYXRlX3RyYW5zZm9ybWF0aW9uKCAoaW50KSAkaW1hZ2VfbWV0YVsnb3JpZW50YXRpb24nXSApOwoKCQkJLy8gUm90YXRlIGltYWdlIGlmIHJlcXVpcmVkLgoJCQlpZiAoIHRydWUgPT09ICRvcGVyYXRpb25zWydyb3RhdGUnXSApIHsKCQkJCSRlZGl0b3ItPnJvdGF0ZSggJG9wZXJhdGlvbnNbJ2RlZ3JlZSddICk7CgkJCX0KCgkJCS8vIEZsaXAgaW1hZ2UgaWYgcmVxdWlyZWQuCgkJCWlmICggZmFsc2UgIT09ICRvcGVyYXRpb25zWydmbGlwJ10gKSB7CgkJCQkkZWRpdG9yLT5mbGlwKCAkb3BlcmF0aW9uc1snZmxpcCddWzBdLCAkb3BlcmF0aW9uc1snZmxpcCddWzFdICk7CgkJCX0KCgkJCS8vIFNhdmUgdGhlIGltYWdlIGFuZCBnZW5lcmF0ZSBtZXRhZGF0YS4KCQkJJGVkaXRvci0+c2F2ZSggJGZ1bGxfc2l6ZV9wYXRoICk7CgkJCSRtZXRhZGF0YSAgID0gd3BfZ2VuZXJhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkZnVsbF9zaXplX3BhdGggKTsKCQkJJGltYWdlX21ldGEgPSBlbXB0eSggJG1ldGFkYXRhWydpbWFnZV9tZXRhJ10gKSA/IFtdIDogJG1ldGFkYXRhWydpbWFnZV9tZXRhJ107CgoJCQkvLyBVcGRhdGUgYXR0YWNobWVudCBtZXRhZGF0YSB3aXRoIG5ld2x5IGdlbmVyYXRlZCBkYXRhLgoJCQl3cF91cGRhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkbWV0YWRhdGEgKTsKCgkJCWlmICggaXNzZXQoICRpbWFnZV9tZXRhWydvcmllbnRhdGlvbiddICkgJiYgYWJzaW50KCAkaW1hZ2VfbWV0YVsnb3JpZW50YXRpb24nXSApID09PSAwICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFJldHVybiBhcnJheSBvZiBvcGVyYXRpb25zIHRvIGJlIGRvbmUgZm9yIHByb3ZpZGVkIG9yaWVudGF0aW9uIHZhbHVlLgoJICoKCSAqIEBwYXJhbSBpbnQgJG9yaWVudGF0aW9uIEVYSUYgb3JpZW50YXRpb24gdmFsdWUuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNhbGN1bGF0ZV90cmFuc2Zvcm1hdGlvbiggJG9yaWVudGF0aW9uICkgewoJCSRyb3RhdGUgPSBmYWxzZTsKCQkkZmxpcCAgID0gZmFsc2U7CgkJJGRlZ3JlZSA9IDA7CgkJc3dpdGNoICggJG9yaWVudGF0aW9uICkgewoJCQljYXNlIDI6CgkJCQkkZmxpcCA9IFsgZmFsc2UsIHRydWUgXTsgLy8gJGZsaXAgaW1hZ2UgYWxvbmcgZ2l2ZW4gYXhpcyBbIGhvcml6b250YWwsIHZlcnRpY2FsIF0KCQkJCWJyZWFrOwoJCQljYXNlIDM6CgkJCQkkZmxpcCA9IFsgdHJ1ZSwgdHJ1ZSBdOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDoKCQkJCSRmbGlwID0gWyB0cnVlLCBmYWxzZSBdOwoJCQkJYnJlYWs7CgkJCWNhc2UgNToKCQkJCSRkZWdyZWUgPSAtOTA7CgkJCQkkcm90YXRlID0gdHJ1ZTsKCQkJCSRmbGlwICAgPSBbIGZhbHNlLCB0cnVlIF07CgkJCQlicmVhazsKCQkJY2FzZSA2OgoJCQkJJGRlZ3JlZSA9IC05MDsKCQkJCSRyb3RhdGUgPSB0cnVlOwoJCQkJYnJlYWs7CgkJCWNhc2UgNzoKCQkJCSRkZWdyZWUgPSA5MDsKCQkJCSRyb3RhdGUgPSB0cnVlOwoJCQkJJGZsaXAgICA9IFsgZmFsc2UsIHRydWUgXTsKCQkJCWJyZWFrOwoJCQljYXNlIDg6CgkJCQkkZGVncmVlID0gOTA7CgkJCQkkcm90YXRlID0gdHJ1ZTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJJGRlZ3JlZSA9IDA7CgkJCQkkcm90YXRlID0gdHJ1ZTsKCQkJCWJyZWFrOwoJCX0KCgkJcmV0dXJuIFsKCQkJJ2ZsaXAnICAgPT4gJGZsaXAsCgkJCSdkZWdyZWUnID0+ICRkZWdyZWUsCgkJCSdyb3RhdGUnID0+ICRyb3RhdGUsCgkJXTsKCX0KCgkvKioKCSAqIEFkZCBjb21wYXRpYmlsaXR5IGluZGlyZWN0aW9uIHRvIGdldF9hdHRhY2hlZF9maWxlKCkuCgkgKgoJICogSW4gV29yZFByZXNzIDUuMywgYmVoYXZpb3IgY2hhbmdlZCB0byBhY2NvdW50IGZvciBhdXRvbWF0aWMgcmVzaXppbmcgb2YKCSAqIGJpZyBpbWFnZSBmaWxlcy4KCSAqCgkgKiBAc2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzQ3ODczCgkgKgoJICogQHBhcmFtIGludCAkYXR0YWNobWVudF9pZCBJRCBvZiB0aGUgYXR0YWNobWVudCB0byBnZXQgdGhlIGZpbGVwYXRoIGZvci4KCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIEZpbGVwYXRoIG9mIHRoZSBhdHRhY2htZW50LCBvciBmYWxzZSBpZiBub3QgZm91bmQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2F0dGFjaGVkX2ZpbGUoICRhdHRhY2htZW50X2lkICkgewoJCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnd3BfZ2V0X29yaWdpbmFsX2ltYWdlX3BhdGgnICkgKSB7CgkJCSRmaWxlcGF0aCA9IHdwX2dldF9vcmlnaW5hbF9pbWFnZV9wYXRoKCAkYXR0YWNobWVudF9pZCApOwoKCQkJaWYgKCBmYWxzZSAhPT0gJGZpbGVwYXRoICkgewoJCQkJcmV0dXJuICRmaWxlcGF0aDsKCQkJfQoJCX0KCgkJcmV0dXJuIGdldF9hdHRhY2hlZF9maWxlKCAkYXR0YWNobWVudF9pZCApOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfbWVkaWFfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfbWVkaWFfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9tZWRpYV9hdXRvbG9hZGVyOwp9CgovKioKICogQ2hlY2sgZm9yIEltYWdpY2sgYW5kIEdEIGV4dGVuc2lvbnMgYXZhaWxhYmlsaXR5LgogKgogKiBAdGhyb3dzIFxXUF9DTElcRXhpdEV4Y2VwdGlvbgogKi8KJHdwY2xpX21lZGlhX2Fzc2VydF9pbWFnZV9lZGl0b3Jfc3VwcG9ydCA9IGZ1bmN0aW9uICgpIHsKCWlmICggISB3cF9pbWFnZV9lZGl0b3Jfc3VwcG9ydHMoKSApIHsKCQlXUF9DTEk6OmVycm9yKAoJCQknTm8gc3VwcG9ydCBmb3IgZ2VuZXJhdGluZyBpbWFnZXMgZm91bmQuICcKCQkJLiAnUGxlYXNlIGluc3RhbGwgdGhlIEltYWdpY2sgb3IgR0QgUEhQIGV4dGVuc2lvbnMuJwoJCSk7Cgl9Cn07CgpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ21lZGlhJywKCSdNZWRpYV9Db21tYW5kJywKCVsgJ2JlZm9yZV9pbnZva2UnID0+ICR3cGNsaV9tZWRpYV9hc3NlcnRfaW1hZ2VfZWRpdG9yX3N1cHBvcnQgXQopOwo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxGZXRjaGVyczsKCi8qKgogKiBGZXRjaCBhIFdvcmRQcmVzcyBwbHVnaW4gYmFzZWQgb24gb25lIG9mIGl0cyBhdHRyaWJ1dGVzLgogKgogKiBUaGlzIGlzIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSBwbHVnaW4gZmV0Y2hlci4gSXQgZG9lc24ndCB1c2UgdGhlCiAqIGBhbGxfcGx1Z2luc2AgZmlsdGVyLCBzbyB0aGF0IHBsdWdpbnMgY2Fubm90IGhpZGUgdGhlbXNlbHZlcyBmcm9tIHRoZQogKiBjaGVja3MuCiAqCiAqLwpjbGFzcyBVbmZpbHRlcmVkUGx1Z2luIGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBAdmFyIHN0cmluZyAkbXNnIEVycm9yIG1lc3NhZ2UgdG8gdXNlIHdoZW4gaW52YWxpZCBkYXRhIGlzIHByb3ZpZGVkCgkgKi8KCXByb3RlY3RlZCAkbXNnID0gIlRoZSAnJXMnIHBsdWdpbiBjb3VsZCBub3QgYmUgZm91bmQuIjsKCgkvKioKCSAqIEdldCBhIHBsdWdpbiBvYmplY3QgYnkgbmFtZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lCgkgKgoJICogQHJldHVybiBvYmplY3R8ZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJG5hbWUgKSB7CgkJZm9yZWFjaCAoIGdldF9wbHVnaW5zKCkgYXMgJGZpbGUgPT4gJF8gKSB7CgkJCWlmICggInskbmFtZX0ucGhwIiA9PT0gJGZpbGUgfHwKCQkJCSggJG5hbWUgJiYgJGZpbGUgPT09ICRuYW1lICkgfHwKCQkJCSggZGlybmFtZSggJGZpbGUgKSA9PT0gJG5hbWUgJiYgJy4nICE9PSAkbmFtZSApICkgewoJCQkJcmV0dXJuIChvYmplY3QpIGNvbXBhY3QoICduYW1lJywgJ2ZpbGUnICk7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KfQoKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQmFzZSBjb21tYW5kIHRoYXQgYWxsIGNoZWNrc3VtIGNvbW1hbmRzIHJlbHkgb24uCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ2hlY2tzdW1fQmFzZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogTm9ybWFsaXplcyBkaXJlY3Rvcnkgc2VwYXJhdG9ycyB0byBzbGFzaGVzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byBjb252ZXJ0LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFBhdGggd2l0aCBhbGwgYmFja3NsYXNoZXMgcmVwbGFjZWQgYnkgc2xhc2hlcy4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBub3JtYWxpemVfZGlyZWN0b3J5X3NlcGFyYXRvcnMoICRwYXRoICkgewoJCXJldHVybiBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCAkcGF0aCApOwoJfQoKCS8qKgoJICogUmVhZCBhIHJlbW90ZSBmaWxlIGFuZCByZXR1cm4gaXRzIGNvbnRlbnRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgb2YgdGhlIHJlbW90ZSBmaWxlIHRvIHJlYWQuCgkgKgoJICogQHJldHVybiBtaXhlZAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIF9yZWFkKCAkdXJsICkgeyAvLyBwaHBjczppZ25vcmUgUFNSMi5NZXRob2RzLk1ldGhvZERlY2xhcmF0aW9uLlVuZGVyc2NvcmUgLS0gQ291bGQgYmUgdXNlZCBpbiBjbGFzc2VzIGV4dGVuZGluZyB0aGlzIGNsYXNzLgoJCSRoZWFkZXJzICA9IGFycmF5KCAnQWNjZXB0JyA9PiAnYXBwbGljYXRpb24vanNvbicgKTsKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoCgkJCSdHRVQnLAoJCQkkdXJsLAoJCQludWxsLAoJCQkkaGVhZGVycywKCQkJYXJyYXkoICd0aW1lb3V0JyA9PiAzMCApCgkJKTsKCQlpZiAoIDIwMCA9PT0gJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJcmV0dXJuICRyZXNwb25zZS0+Ym9keTsKCQl9CgkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGZldGNoIHJlc3BvbnNlIGZyb20geyR1cmx9IChIVFRQIGNvZGUgeyRyZXNwb25zZS0+c3RhdHVzX2NvZGV9KS4iICk7Cgl9CgoJLyoqCgkgKiBSZWN1cnNpdmVseSBnZXQgdGhlIGxpc3Qgb2YgZmlsZXMgZm9yIGEgZ2l2ZW4gcGF0aC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFJvb3QgcGF0aCB0byBzdGFydCB0aGUgcmVjdXJzaXZlIHRyYXZlcnNhbCBpbi4KCSAqCgkgKiBAcmV0dXJuIGFycmF5PHN0cmluZz4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9maWxlcyggJHBhdGggKSB7CgkJJGZpbHRlcmVkX2ZpbGVzID0gYXJyYXkoKTsKCQl0cnkgewoJCQkkZmlsZXMgPSBuZXcgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigKCQkJCW5ldyBSZWN1cnNpdmVDYWxsYmFja0ZpbHRlckl0ZXJhdG9yKAoJCQkJCW5ldyBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigKCQkJCQkJJHBhdGgsCgkJCQkJCVJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMKCQkJCQkpLAoJCQkJCWZ1bmN0aW9uICggJGN1cnJlbnQsICRrZXksICRpdGVyYXRvciApIHVzZSAoICRwYXRoICkgewoJCQkJCQlyZXR1cm4gJHRoaXMtPmZpbHRlcl9maWxlKCBzZWxmOjpub3JtYWxpemVfZGlyZWN0b3J5X3NlcGFyYXRvcnMoIHN1YnN0ciggJGN1cnJlbnQtPmdldFBhdGhuYW1lKCksIHN0cmxlbiggJHBhdGggKSApICkgKTsKCQkJCQl9CgkJCQkpLAoJCQkJUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjo6Q0hJTERfRklSU1QKCQkJKTsKCQkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZV9pbmZvICkgewoJCQkJaWYgKCAkZmlsZV9pbmZvLT5pc0ZpbGUoKSApIHsKCQkJCQkkZmlsdGVyZWRfZmlsZXNbXSA9IHNlbGY6Om5vcm1hbGl6ZV9kaXJlY3Rvcnlfc2VwYXJhdG9ycyggc3Vic3RyKCAkZmlsZV9pbmZvLT5nZXRQYXRobmFtZSgpLCBzdHJsZW4oICRwYXRoICkgKSApOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJcmV0dXJuICRmaWx0ZXJlZF9maWxlczsKCX0KCgkvKioKCSAqIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgZmlsZSBpbiB0aGUgdmVyaWZpY2F0aW9uIG9yIG5vdC4KCSAqCgkgKiBDYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWJjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGVwYXRoIFBhdGggdG8gYSBmaWxlLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZmlsdGVyX2ZpbGUoICRmaWxlcGF0aCApIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxXcE9yZ0FwaTsKCi8qKgogKiBWZXJpZmllcyBjb3JlIGZpbGUgaW50ZWdyaXR5IGJ5IGNvbXBhcmluZyB0byBwdWJsaXNoZWQgY2hlY2tzdW1zLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENoZWNrc3VtX0NvcmVfQ29tbWFuZCBleHRlbmRzIENoZWNrc3VtX0Jhc2VfQ29tbWFuZCB7CgoJLyoqCgkgKiBWZXJpZmllcyBXb3JkUHJlc3MgZmlsZXMgYWdhaW5zdCBXb3JkUHJlc3Mub3JnJ3MgY2hlY2tzdW1zLgoJICoKCSAqIERvd25sb2FkcyBtZDUgY2hlY2tzdW1zIGZvciB0aGUgY3VycmVudCB2ZXJzaW9uIGZyb20gV29yZFByZXNzLm9yZywgYW5kCgkgKiBjb21wYXJlcyB0aG9zZSBjaGVja3N1bXMgYWdhaW5zdCB0aGUgY3VycmVudGx5IGluc3RhbGxlZCBmaWxlcy4KCSAqCgkgKiBGb3Igc2VjdXJpdHksIGF2b2lkcyBsb2FkaW5nIFdvcmRQcmVzcyB3aGVuIHZlcmlmeWluZyBjaGVja3N1bXMuCgkgKgoJICogSWYgeW91IGV4cGVyaWVuY2UgaXNzdWVzIHZlcmlmeWluZyBmcm9tIHRoaXMgY29tbWFuZCwgZW5zdXJlIHlvdSBhcmUKCSAqIHBhc3NpbmcgdGhlIHJlbGV2YW50IGAtLWxvY2FsZWAgYW5kIGAtLXZlcnNpb25gIGFyZ3VtZW50cyBhY2NvcmRpbmcgdG8KCSAqIHRoZSB2YWx1ZXMgZnJvbSB0aGUgYERhc2hib2FyZC0+VXBkYXRlc2AgbWVudSBpbiB0aGUgYWRtaW4gYXJlYSBvZiB0aGUKCSAqIHNpdGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXZlcnNpb249PHZlcnNpb24+XQoJICogOiBWZXJpZnkgY2hlY2tzdW1zIGFnYWluc3QgYSBzcGVjaWZpYyB2ZXJzaW9uIG9mIFdvcmRQcmVzcy4KCSAqCgkgKiBbLS1sb2NhbGU9PGxvY2FsZT5dCgkgKiA6IFZlcmlmeSBjaGVja3N1bXMgYWdhaW5zdCBhIHNwZWNpZmljIGxvY2FsZSBvZiBXb3JkUHJlc3MuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkcyB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBWZXJpZnkgY2hlY2tzdW1zCgkgKiAgICAgJCB3cCBjb3JlIHZlcmlmeS1jaGVja3N1bXMKCSAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIHZlcmlmaWVzIGFnYWluc3QgY2hlY2tzdW1zLgoJICoKCSAqICAgICAjIFZlcmlmeSBjaGVja3N1bXMgZm9yIGdpdmVuIFdvcmRQcmVzcyB2ZXJzaW9uCgkgKiAgICAgJCB3cCBjb3JlIHZlcmlmeS1jaGVja3N1bXMgLS12ZXJzaW9uPTQuMAoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gdmVyaWZpZXMgYWdhaW5zdCBjaGVja3N1bXMuCgkgKgoJICogICAgICMgVmVyaWZ5IGNoZWNrc3VtcyBmb3IgZ2l2ZW4gbG9jYWxlCgkgKiAgICAgJCB3cCBjb3JlIHZlcmlmeS1jaGVja3N1bXMgLS1sb2NhbGU9ZW5fVVMKCSAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIHZlcmlmaWVzIGFnYWluc3QgY2hlY2tzdW1zLgoJICoKCSAqICAgICAjIFZlcmlmeSBjaGVja3N1bXMgZm9yIGdpdmVuIGxvY2FsZQoJICogICAgICQgd3AgY29yZSB2ZXJpZnktY2hlY2tzdW1zIC0tbG9jYWxlPWphCgkgKiAgICAgV2FybmluZzogRmlsZSBkb2Vzbid0IHZlcmlmeSBhZ2FpbnN0IGNoZWNrc3VtOiB3cC1pbmNsdWRlcy92ZXJzaW9uLnBocAoJICogICAgIFdhcm5pbmc6IEZpbGUgZG9lc24ndCB2ZXJpZnkgYWdhaW5zdCBjaGVja3N1bTogcmVhZG1lLmh0bWwKCSAqICAgICBXYXJuaW5nOiBGaWxlIGRvZXNuJ3QgdmVyaWZ5IGFnYWluc3QgY2hlY2tzdW06IHdwLWNvbmZpZy1zYW1wbGUucGhwCgkgKiAgICAgRXJyb3I6IFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gZG9lc24ndCB2ZXJpZnkgYWdhaW5zdCBjaGVja3N1bXMuCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHdwX3ZlcnNpb24gPSAnJzsKCQkkbG9jYWxlICAgICA9ICcnOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSApIHsKCQkJJHdwX3ZlcnNpb24gPSAkYXNzb2NfYXJnc1sndmVyc2lvbiddOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snbG9jYWxlJ10gKSApIHsKCQkJJGxvY2FsZSA9ICRhc3NvY19hcmdzWydsb2NhbGUnXTsKCQl9CgoJCWlmICggZW1wdHkoICR3cF92ZXJzaW9uICkgKSB7CgkJCSRkZXRhaWxzICAgID0gc2VsZjo6Z2V0X3dwX2RldGFpbHMoKTsKCQkJJHdwX3ZlcnNpb24gPSAkZGV0YWlsc1snd3BfdmVyc2lvbiddOwoKCQkJaWYgKCBlbXB0eSggJGxvY2FsZSApICkgewoJCQkJJGxvY2FsZSA9ICRkZXRhaWxzWyd3cF9sb2NhbF9wYWNrYWdlJ107CgkJCX0KCQl9CgoJCSRpbnNlY3VyZSAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCQkkd3Bfb3JnX2FwaSA9IG5ldyBXcE9yZ0FwaSggWyAnaW5zZWN1cmUnID0+ICRpbnNlY3VyZSBdICk7CgoJCXRyeSB7CgkJCSRjaGVja3N1bXMgPSAkd3Bfb3JnX2FwaS0+Z2V0X2NvcmVfY2hlY2tzdW1zKCAkd3BfdmVyc2lvbiwgZW1wdHkoICRsb2NhbGUgKSA/ICdlbl9VUycgOiAkbG9jYWxlICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZXhjZXB0aW9uICk7CgkJfQoKCQlpZiAoICEgaXNfYXJyYXkoICRjaGVja3N1bXMgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGdldCBjaGVja3N1bXMgZnJvbSBXb3JkUHJlc3Mub3JnLiIgKTsKCQl9CgoJCSRoYXNfZXJyb3JzID0gZmFsc2U7CgkJZm9yZWFjaCAoICRjaGVja3N1bXMgYXMgJGZpbGUgPT4gJGNoZWNrc3VtICkgewoJCQkvLyBTa2lwIGZpbGVzIHdoaWNoIGdldCB1cGRhdGVkCgkJCWlmICggJ3dwLWNvbnRlbnQnID09PSBzdWJzdHIoICRmaWxlLCAwLCAxMCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggISBmaWxlX2V4aXN0cyggQUJTUEFUSCAuICRmaWxlICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJGaWxlIGRvZXNuJ3QgZXhpc3Q6IHskZmlsZX0iICk7CgkJCQkkaGFzX2Vycm9ycyA9IHRydWU7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJG1kNV9maWxlID0gbWQ1X2ZpbGUoIEFCU1BBVEggLiAkZmlsZSApOwoJCQlpZiAoICRtZDVfZmlsZSAhPT0gJGNoZWNrc3VtICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiRmlsZSBkb2Vzbid0IHZlcmlmeSBhZ2FpbnN0IGNoZWNrc3VtOiB7JGZpbGV9IiApOwoJCQkJJGhhc19lcnJvcnMgPSB0cnVlOwoJCQl9CgkJfQoKCQkkY29yZV9jaGVja3N1bXNfZmlsZXMgPSBhcnJheV9maWx0ZXIoIGFycmF5X2tleXMoICRjaGVja3N1bXMgKSwgWyAkdGhpcywgJ2ZpbHRlcl9maWxlJyBdICk7CgkJJGNvcmVfZmlsZXMgICAgICAgICAgID0gJHRoaXMtPmdldF9maWxlcyggQUJTUEFUSCApOwoJCSRhZGRpdGlvbmFsX2ZpbGVzICAgICA9IGFycmF5X2RpZmYoICRjb3JlX2ZpbGVzLCAkY29yZV9jaGVja3N1bXNfZmlsZXMgKTsKCgkJaWYgKCAhIGVtcHR5KCAkYWRkaXRpb25hbF9maWxlcyApICkgewoJCQlmb3JlYWNoICggJGFkZGl0aW9uYWxfZmlsZXMgYXMgJGFkZGl0aW9uYWxfZmlsZSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkZpbGUgc2hvdWxkIG5vdCBleGlzdDogeyRhZGRpdGlvbmFsX2ZpbGV9IiApOwoJCQl9CgkJfQoKCQlpZiAoICEgJGhhc19lcnJvcnMgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ1dvcmRQcmVzcyBpbnN0YWxsYXRpb24gdmVyaWZpZXMgYWdhaW5zdCBjaGVja3N1bXMuJyApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGRvZXNuJ3QgdmVyaWZ5IGFnYWluc3QgY2hlY2tzdW1zLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIGZpbGUgaW4gdGhlIHZlcmlmaWNhdGlvbiBvciBub3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZmlsZXBhdGggUGF0aCB0byBhIGZpbGUuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBmaWx0ZXJfZmlsZSggJGZpbGVwYXRoICkgewoJCXJldHVybiAoIDAgPT09IHN0cnBvcyggJGZpbGVwYXRoLCAnd3AtYWRtaW4vJyApCgkJCXx8IDAgPT09IHN0cnBvcyggJGZpbGVwYXRoLCAnd3AtaW5jbHVkZXMvJyApCgkJCXx8IDEgPT09IHByZWdfbWF0Y2goICcvXndwLSg/IWNvbmZpZ1wucGhwKShbXlwvXSopJC8nLCAkZmlsZXBhdGggKQoJCSk7Cgl9CgoJLyoqCgkgKiBHZXRzIHZlcnNpb24gaW5mb3JtYXRpb24gZnJvbSBgd3AtaW5jbHVkZXMvdmVyc2lvbi5waHBgLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgewoJICogICAgIEB0eXBlIHN0cmluZyAkd3BfdmVyc2lvbiBUaGUgV29yZFByZXNzIHZlcnNpb24uCgkgKiAgICAgQHR5cGUgaW50ICR3cF9kYl92ZXJzaW9uIFRoZSBXb3JkUHJlc3MgREIgcmV2aXNpb24uCgkgKiAgICAgQHR5cGUgc3RyaW5nICR0aW55bWNlX3ZlcnNpb24gVGhlIFRpbnlNQ0UgdmVyc2lvbi4KCSAqICAgICBAdHlwZSBzdHJpbmcgJHdwX2xvY2FsX3BhY2thZ2UgVGhlIFRpbnlNQ0UgdmVyc2lvbi4KCSAqIH0KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3dwX2RldGFpbHMoKSB7CgkJJHZlcnNpb25zX3BhdGggPSBBQlNQQVRIIC4gJ3dwLWluY2x1ZGVzL3ZlcnNpb24ucGhwJzsKCgkJaWYgKCAhIGlzX3JlYWRhYmxlKCAkdmVyc2lvbnNfcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKAoJCQkJIlRoaXMgZG9lcyBub3Qgc2VlbSB0byBiZSBhIFdvcmRQcmVzcyBpbnN0YWxsLlxuIiAuCgkJCQknUGFzcyAtLXBhdGg9YHBhdGgvdG8vd29yZHByZXNzYCBvciBydW4gYHdwIGNvcmUgZG93bmxvYWRgLicKCQkJKTsKCQl9CgoJCSR2ZXJzaW9uX2NvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cyggJHZlcnNpb25zX3BhdGgsIG51bGwsIG51bGwsIDYsIDIwNDggKTsKCgkJJHZhcnMgICA9IFsgJ3dwX3ZlcnNpb24nLCAnd3BfZGJfdmVyc2lvbicsICd0aW55bWNlX3ZlcnNpb24nLCAnd3BfbG9jYWxfcGFja2FnZScgXTsKCQkkcmVzdWx0ID0gW107CgoJCWZvcmVhY2ggKCAkdmFycyBhcyAkdmFyX25hbWUgKSB7CgkJCSRyZXN1bHRbICR2YXJfbmFtZSBdID0gc2VsZjo6ZmluZF92YXIoICR2YXJfbmFtZSwgJHZlcnNpb25fY29udGVudCApOwoJCX0KCgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJLyoqCgkgKiBTZWFyY2hlcyBmb3IgdGhlIHZhbHVlIGFzc2lnbmVkIHRvIHZhcmlhYmxlIGAkdmFyX25hbWVgIGluIFBIUCBjb2RlIGAkY29kZWAuCgkgKgoJICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIG1hdGNoaW5nIHRoZSBgXCRWQVJfTkFNRSA9IChbXjtdKylgIHJlZ3VsYXIgZXhwcmVzc2lvbiBhbmQgcmV0dXJuaW5nCgkgKiB0aGUgZmlyc3QgbWF0Y2ggZWl0aGVyIGFzIGEgYHN0cmluZ2Agb3IgYXMgYW4gYGludGVnZXJgIChkZXBlbmRpbmcgaWYgaXQncyBzdXJyb3VuZGVkIGJ5CgkgKiBxdW90ZXMgb3Igbm90KS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR2YXJfbmFtZSBWYXJpYWJsZSBuYW1lIHRvIHNlYXJjaCBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRjb2RlIFBIUCBjb2RlIHRvIHNlYXJjaCBpbi4KCSAqCgkgKiBAcmV0dXJuIGludHxzdHJpbmd8bnVsbAoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBmaW5kX3ZhciggJHZhcl9uYW1lLCAkY29kZSApIHsKCQkkc3RhcnQgPSBzdHJwb3MoICRjb2RlLCAnJCcgLiAkdmFyX25hbWUgLiAnID0gJyApOwoKCQlpZiAoICEgJHN0YXJ0ICkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCSRzdGFydCA9ICRzdGFydCArIHN0cmxlbiggJHZhcl9uYW1lICkgKyAzOwoJCSRlbmQgICA9IHN0cnBvcyggJGNvZGUsICc7JywgJHN0YXJ0ICk7CgoJCSR2YWx1ZSA9IHN1YnN0ciggJGNvZGUsICRzdGFydCwgJGVuZCAtICRzdGFydCApOwoKCQlyZXR1cm4gdHJpbSggJHZhbHVlLCAiJyIgKTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxGZXRjaGVyczsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcV3BPcmdBcGk7CgovKioKICogVmVyaWZpZXMgcGx1Z2luIGZpbGUgaW50ZWdyaXR5IGJ5IGNvbXBhcmluZyB0byBwdWJsaXNoZWQgY2hlY2tzdW1zLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENoZWNrc3VtX1BsdWdpbl9Db21tYW5kIGV4dGVuZHMgQ2hlY2tzdW1fQmFzZV9Db21tYW5kIHsKCgkvKioKCSAqIFVSTCB0ZW1wbGF0ZSB0aGF0IHBvaW50cyB0byB0aGUgQVBJIGVuZHBvaW50IHRvIHVzZS4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcml2YXRlICR1cmxfdGVtcGxhdGUgPSAnaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4tY2hlY2tzdW1zL3tzbHVnfS97dmVyc2lvbn0uanNvbic7CgoJLyoqCgkgKiBDYWNoZWQgcGx1Z2luIGRhdGEgZm9yIGFsbCBpbnN0YWxsZWQgcGx1Z2lucy4KCSAqCgkgKiBAdmFyIGFycmF5fG51bGwKCSAqLwoJcHJpdmF0ZSAkcGx1Z2luc19kYXRhOwoKCS8qKgoJICogQXJyYXkgb2YgZGV0ZWN0ZWQgZXJyb3JzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkZXJyb3JzID0gYXJyYXkoKTsKCgkvKioKCSAqIFZlcmlmaWVzIHBsdWdpbiBmaWxlcyBhZ2FpbnN0IFdvcmRQcmVzcy5vcmcncyBjaGVja3N1bXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgcGx1Z2lucyB0byB2ZXJpZnkuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBwbHVnaW5zIHdpbGwgYmUgdmVyaWZpZWQuCgkgKgoJICogWy0tc3RyaWN0XQoJICogOiBJZiBzZXQsIGV2ZW4gInNvZnQgY2hhbmdlcyIgbGlrZSByZWFkbWUudHh0IGNoYW5nZXMgd2lsbCB0cmlnZ2VyCgkgKiBjaGVja3N1bSBlcnJvcnMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgc3BlY2lmaWMgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGpzb24KCSAqICAgLSBjc3YKCSAqICAgLSB5YW1sCgkgKiAgIC0gY291bnQKCSAqIC0tLQoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSBkb3dubG9hZHMgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGlmIFRMUyBoYW5kc2hha2UgZmFpbHMuIE5vdGU6IFRoaXMgbWFrZXMgdGhlIHJlcXVlc3QgdnVsbmVyYWJsZSB0byBhIE1JVE0gYXR0YWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVmVyaWZ5IHRoZSBjaGVja3N1bXMgb2YgYWxsIGluc3RhbGxlZCBwbHVnaW5zCgkgKiAgICAgJCB3cCBwbHVnaW4gdmVyaWZ5LWNoZWNrc3VtcyAtLWFsbAoJICogICAgIFN1Y2Nlc3M6IFZlcmlmaWVkIDggb2YgOCBwbHVnaW5zLgoJICoKCSAqICAgICAjIFZlcmlmeSB0aGUgY2hlY2tzdW1zIG9mIGEgc2luZ2xlIHBsdWdpbiwgQWtpc21ldCBpbiB0aGlzIGNhc2UKCSAqICAgICAkIHdwIHBsdWdpbiB2ZXJpZnktY2hlY2tzdW1zIGFraXNtZXQKCSAqICAgICBTdWNjZXNzOiBWZXJpZmllZCAxIG9mIDEgcGx1Z2lucy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRmZXRjaGVyICA9IG5ldyBGZXRjaGVyc1xVbmZpbHRlcmVkUGx1Z2luKCk7CgkJJGFsbCAgICAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgkJJHN0cmljdCAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0cmljdCcsIGZhbHNlICk7CgkJJGluc2VjdXJlID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCQkkcGx1Z2lucyAgPSAkZmV0Y2hlci0+Z2V0X21hbnkoICRhbGwgPyAkdGhpcy0+Z2V0X2FsbF9wbHVnaW5fbmFtZXMoKSA6ICRhcmdzICk7CgoJCWlmICggZW1wdHkoICRwbHVnaW5zICkgJiYgISAkYWxsICkgewoJCQlXUF9DTEk6OmVycm9yKCAnWW91IG5lZWQgdG8gc3BlY2lmeSBlaXRoZXIgb25lIG9yIG1vcmUgcGx1Z2luIHNsdWdzIHRvIGNoZWNrIG9yIHVzZSB0aGUgLS1hbGwgZmxhZyB0byBjaGVjayBhbGwgcGx1Z2lucy4nICk7CgkJfQoKCQkkc2tpcHMgPSAwOwoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJHZlcnNpb24gPSAkdGhpcy0+Z2V0X3BsdWdpbl92ZXJzaW9uKCAkcGx1Z2luLT5maWxlICk7CgoJCQlpZiAoIGZhbHNlID09PSAkdmVyc2lvbiApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkIG5vdCByZXRyaWV2ZSB0aGUgdmVyc2lvbiBmb3IgcGx1Z2luIHskcGx1Z2luLT5uYW1lfSwgc2tpcHBpbmcuIiApOwoJCQkJJHNraXBzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHdwX29yZ19hcGkgPSBuZXcgV3BPcmdBcGkoIFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXSApOwoKCQkJdHJ5IHsKCQkJCSRjaGVja3N1bXMgPSAkd3Bfb3JnX2FwaS0+Z2V0X3BsdWdpbl9jaGVja3N1bXMoICRwbHVnaW4tPm5hbWUsICR2ZXJzaW9uICk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCSRjaGVja3N1bXMgPSBmYWxzZTsKCQkJfQoKCQkJaWYgKCBmYWxzZSA9PT0gJGNoZWNrc3VtcyApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkIG5vdCByZXRyaWV2ZSB0aGUgY2hlY2tzdW1zIGZvciB2ZXJzaW9uIHskdmVyc2lvbn0gb2YgcGx1Z2luIHskcGx1Z2luLT5uYW1lfSwgc2tpcHBpbmcuIiApOwoJCQkJJHNraXBzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGZpbGVzID0gJHRoaXMtPmdldF9wbHVnaW5fZmlsZXMoICRwbHVnaW4tPmZpbGUgKTsKCgkJCWZvcmVhY2ggKCAkY2hlY2tzdW1zIGFzICRmaWxlID0+ICRjaGVja3N1bV9hcnJheSApIHsKCQkJCWlmICggISBpbl9hcnJheSggJGZpbGUsICRmaWxlcywgdHJ1ZSApICkgewoJCQkJCSR0aGlzLT5hZGRfZXJyb3IoICRwbHVnaW4tPm5hbWUsICRmaWxlLCAnRmlsZSBpcyBtaXNzaW5nJyApOwoJCQkJfQoJCQl9CgoJCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlICkgewoJCQkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRmaWxlLCAkY2hlY2tzdW1zICkgKSB7CgkJCQkJJHRoaXMtPmFkZF9lcnJvciggJHBsdWdpbi0+bmFtZSwgJGZpbGUsICdGaWxlIHdhcyBhZGRlZCcgKTsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoICEgJHN0cmljdCAmJiAkdGhpcy0+aXNfc29mdF9jaGFuZ2VfZmlsZSggJGZpbGUgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkcmVzdWx0ID0gJHRoaXMtPmNoZWNrX2ZpbGVfY2hlY2tzdW0oIGRpcm5hbWUoICRwbHVnaW4tPmZpbGUgKSAuICcvJyAuICRmaWxlLCAkY2hlY2tzdW1zWyAkZmlsZSBdICk7CgkJCQlpZiAoIHRydWUgIT09ICRyZXN1bHQgKSB7CgkJCQkJJHRoaXMtPmFkZF9lcnJvciggJHBsdWdpbi0+bmFtZSwgJGZpbGUsIGlzX3N0cmluZyggJHJlc3VsdCApID8gJHJlc3VsdCA6ICdDaGVja3N1bSBkb2VzIG5vdCBtYXRjaCcgKTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+ZXJyb3JzICkgKSB7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKAoJCQkJJGFzc29jX2FyZ3MsCgkJCQlhcnJheSggJ3BsdWdpbl9uYW1lJywgJ2ZpbGUnLCAnbWVzc2FnZScgKQoJCQkpOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdGhpcy0+ZXJyb3JzICk7CgkJfQoKCQkkdG90YWwgICAgID0gY291bnQoICRwbHVnaW5zICk7CgkJJGZhaWx1cmVzICA9IGNvdW50KCBhcnJheV91bmlxdWUoIGFycmF5X2NvbHVtbiggJHRoaXMtPmVycm9ycywgJ3BsdWdpbl9uYW1lJyApICkgKTsKCQkkc3VjY2Vzc2VzID0gJHRvdGFsIC0gJGZhaWx1cmVzIC0gJHNraXBzOwoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSdwbHVnaW4nLAoJCQkndmVyaWZ5JywKCQkJJHRvdGFsLAoJCQkkc3VjY2Vzc2VzLAoJCQkkZmFpbHVyZXMsCgkJCSRza2lwcwoJCSk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgbmV3IGVycm9yIHRvIHRoZSBhcnJheSBvZiBkZXRlY3RlZCBlcnJvcnMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGx1Z2luX25hbWUgTmFtZSBvZiB0aGUgcGx1Z2luIHRoYXQgaGFkIHRoZSBlcnJvci4KCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgUmVsYXRpdmUgcGF0aCB0byB0aGUgZmlsZSB0aGF0IGhhZCB0aGUgZXJyb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgZXhwbGFpbmluZyB0aGUgZXJyb3IuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYWRkX2Vycm9yKCAkcGx1Z2luX25hbWUsICRmaWxlLCAkbWVzc2FnZSApIHsKCQkkZXJyb3JbJ3BsdWdpbl9uYW1lJ10gPSAkcGx1Z2luX25hbWU7CgkJJGVycm9yWydmaWxlJ10gICAgICAgID0gJGZpbGU7CgkJJGVycm9yWydtZXNzYWdlJ10gICAgID0gJG1lc3NhZ2U7CgkJJHRoaXMtPmVycm9yc1tdICAgICAgID0gJGVycm9yOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgY3VycmVudGx5IGluc3RhbGxlZCB2ZXJzaW9uIGZvciBhIGdpdmVuIHBsdWdpbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFJlbGF0aXZlIHBhdGggdG8gcGx1Z2luIGZpbGUgdG8gZ2V0IHRoZSB2ZXJzaW9uIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBJbnN0YWxsZWQgdmVyc2lvbiBvZiB0aGUgcGx1Z2luLCBvciBmYWxzZSBpZiBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgIGZvdW5kLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9wbHVnaW5fdmVyc2lvbiggJHBhdGggKSB7CgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+cGx1Z2luc19kYXRhICkgKSB7CgkJCSR0aGlzLT5wbHVnaW5zX2RhdGEgPSBnZXRfcGx1Z2lucygpOwoJCX0KCgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRwYXRoLCAkdGhpcy0+cGx1Z2luc19kYXRhICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkdGhpcy0+cGx1Z2luc19kYXRhWyAkcGF0aCBdWydWZXJzaW9uJ107Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBuYW1lcyBvZiBhbGwgaW5zdGFsbGVkIHBsdWdpbnMuCgkgKgoJICogQHJldHVybiBhcnJheTxzdHJpbmc+IE5hbWVzIG9mIGFsbCBpbnN0YWxsZWQgcGx1Z2lucy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWxsX3BsdWdpbl9uYW1lcygpIHsKCQkkbmFtZXMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCBnZXRfcGx1Z2lucygpIGFzICRmaWxlID0+ICRkZXRhaWxzICkgewoJCQkkbmFtZXNbXSA9IFV0aWxzXGdldF9wbHVnaW5fbmFtZSggJGZpbGUgKTsKCQl9CgoJCXJldHVybiAkbmFtZXM7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBsaXN0IG9mIGZpbGVzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGdpdmVuIHBsdWdpbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFJlbGF0aXZlIHBhdGggdG8gdGhlIG1haW4gcGx1Z2luIGZpbGUuCgkgKgoJICogQHJldHVybiBhcnJheTxzdHJpbmc+IEFycmF5IG9mIGZpbGVzIHdpdGggdGhlaXIgcmVsYXRpdmUgcGF0aHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3BsdWdpbl9maWxlcyggJHBhdGggKSB7CgkJJGZvbGRlciA9IGRpcm5hbWUoICR0aGlzLT5nZXRfYWJzb2x1dGVfcGF0aCggJHBhdGggKSApOwoKCQkvLyBSZXR1cm4gc2luZ2xlIGZpbGUgcGx1Z2lucyBpbW1lZGlhdGVseSwgdG8gYXZvaWQgaXRlcmF0aW5nIG92ZXIgdGhlCgkJLy8gZW50aXJlIHBsdWdpbnMgZm9sZGVyLgoJCWlmICggV1BfUExVR0lOX0RJUiA9PT0gJGZvbGRlciApIHsKCQkJcmV0dXJuIChhcnJheSkgJHBhdGg7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPmdldF9maWxlcyggdHJhaWxpbmdzbGFzaGl0KCAkZm9sZGVyICkgKTsKCX0KCgkvKioKCSAqIENoZWNrcyB0aGUgaW50ZWdyaXR5IG9mIGEgc2luZ2xlIHBsdWdpbiBmaWxlIGJ5IGNvbXBhcmluZyBpdCB0byB0aGUKCSAqIG9mZmljaWFsbHkgcHJvdmlkZWQgY2hlY2tzdW0uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCAgICAgIFJlbGF0aXZlIHBhdGggdG8gdGhlIHBsdWdpbiBmaWxlIHRvIGNoZWNrIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIGludGVncml0eSBvZi4KCSAqIEBwYXJhbSBhcnJheSAgJGNoZWNrc3VtcyBBcnJheSBvZiBwcm92aWRlZCBjaGVja3N1bXMgdG8gY29tcGFyZSBhZ2FpbnN0LgoJICoKCSAqIEByZXR1cm4gdHJ1ZXxzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19maWxlX2NoZWNrc3VtKCAkcGF0aCwgJGNoZWNrc3VtcyApIHsKCQlpZiAoICR0aGlzLT5zdXBwb3J0c19zaGEyNTYoKQoJCQkmJiBhcnJheV9rZXlfZXhpc3RzKCAnc2hhMjU2JywgJGNoZWNrc3VtcyApCgkJKSB7CgkJCSRzaGEyNTYgPSAkdGhpcy0+Z2V0X3NoYTI1NiggJHRoaXMtPmdldF9hYnNvbHV0ZV9wYXRoKCAkcGF0aCApICk7CgoJCQlyZXR1cm4gaW5fYXJyYXkoICRzaGEyNTYsIChhcnJheSkgJGNoZWNrc3Vtc1snc2hhMjU2J10sIHRydWUgKTsKCQl9CgoJCWlmICggISBhcnJheV9rZXlfZXhpc3RzKCAnbWQ1JywgJGNoZWNrc3VtcyApICkgewoJCQlyZXR1cm4gJ05vIG1hdGNoaW5nIGNoZWNrc3VtIGFsZ29yaXRobSBmb3VuZCc7CgkJfQoKCQkkbWQ1ID0gJHRoaXMtPmdldF9tZDUoICR0aGlzLT5nZXRfYWJzb2x1dGVfcGF0aCggJHBhdGggKSApOwoKCQlyZXR1cm4gaW5fYXJyYXkoICRtZDUsIChhcnJheSkgJGNoZWNrc3Vtc1snbWQ1J10sIHRydWUgKTsKCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IGVudmlyb25tZW50IHN1cHBvcnRzIDI1Ni1iaXQgU0hBLTIuCgkgKgoJICogU2hvdWxkIGJlIHN1cHBvcnRlZCBmb3IgUEhQIDUrLCBidXQgd2UgbWlnaHQgZmluZCBlZGdlIGNhc2VzIGRlcGVuZGluZyBvbgoJICogaG9zdC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBzdXBwb3J0c19zaGEyNTYoKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSAyNTYtYml0IFNIQS0yIG9mIGEgZ2l2ZW4gZmlsZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRmaWxlcGF0aCBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBmaWxlIHRvIGNhbGN1bGF0ZSB0aGUgU0hBLTIKCSAqICAgICAgICAgICAgICAgICAgICAgICAgIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9zaGEyNTYoICRmaWxlcGF0aCApIHsKCQlyZXR1cm4gaGFzaF9maWxlKCAnc2hhMjU2JywgJGZpbGVwYXRoICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBNRDUgb2YgYSBnaXZlbiBmaWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGVwYXRoIEFic29sdXRlIHBhdGggdG8gdGhlIGZpbGUgdG8gY2FsY3VsYXRlIHRoZSBNRDUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9tZDUoICRmaWxlcGF0aCApIHsKCQlyZXR1cm4gaGFzaF9maWxlKCAnbWQ1JywgJGZpbGVwYXRoICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBhYnNvbHV0ZSBwYXRoIHRvIGEgcmVsYXRpdmUgcGx1Z2luIGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBSZWxhdGl2ZSBwYXRoIHRvIGdldCB0aGUgYWJzb2x1dGUgcGF0aCBmb3IuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWJzb2x1dGVfcGF0aCggJHBhdGggKSB7CgkJcmV0dXJuIFdQX1BMVUdJTl9ESVIgLiAnLycgLiAkcGF0aDsKCX0KCgkvKioKCSAqIFJldHVybnMgYSBsaXN0IG9mIGZpbGVzIHRoYXQgb25seSB0cmlnZ2VyIGNoZWNrc3VtIGVycm9ycyBpbiBzdHJpY3QgbW9kZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5PHN0cmluZz4gQXJyYXkgb2YgZmlsZSBuYW1lcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfc29mdF9jaGFuZ2VfZmlsZXMoKSB7CgkJc3RhdGljICRmaWxlcyA9IGFycmF5KAoJCQkncmVhZG1lLnR4dCcsCgkJCSdyZWFkbWUubWQnLAoJCSk7CgoJCXJldHVybiAkZmlsZXM7Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciBhIGdpdmVuIGZpbGUgd2lsbCBvbmx5IHRyaWdnZXIgY2hlY2tzdW0gZXJyb3JzIGluIHN0cmljdAoJICogbW9kZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRmaWxlIEZpbGUgdG8gY2hlY2suCgkgKgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGZpbGUgb25seSB0cmlnZ2VycyBjaGVja3N1bSBlcnJvcnMgaW4gc3RyaWN0CgkgKiBtb2RlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX3NvZnRfY2hhbmdlX2ZpbGUoICRmaWxlICkgewoJCXJldHVybiBpbl9hcnJheSggc3RydG9sb3dlciggJGZpbGUgKSwgJHRoaXMtPmdldF9zb2Z0X2NoYW5nZV9maWxlcygpLCB0cnVlICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlOwoKLyoqCiAqIE1hbmFnZXMgcGx1Z2lucywgaW5jbHVkaW5nIGluc3RhbGxzLCBhY3RpdmF0aW9ucywgYW5kIHVwZGF0ZXMuCiAqLwpmaW5hbCBjbGFzcyBQbHVnaW5fQ29tbWFuZF9OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKCn0KPD9waHAKCnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlOwoKLyoqCiAqIERvd25sb2FkcywgaW5zdGFsbHMsIHVwZGF0ZXMsIGFuZCBtYW5hZ2VzIGEgV29yZFByZXNzIGluc3RhbGxhdGlvbi4KICovCmZpbmFsIGNsYXNzIENvcmVfQ29tbWFuZF9OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKCn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9jaGVja3N1bV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9jaGVja3N1bV9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX2NoZWNrc3VtX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjb3JlJywgJ0NvcmVfQ29tbWFuZF9OYW1lc3BhY2UnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdjb3JlIHZlcmlmeS1jaGVja3N1bXMnLCAnQ2hlY2tzdW1fQ29yZV9Db21tYW5kJyApOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3BsdWdpbicsICdQbHVnaW5fQ29tbWFuZF9OYW1lc3BhY2UnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdwbHVnaW4gdmVyaWZ5LWNoZWNrc3VtcycsICdDaGVja3N1bV9QbHVnaW5fQ29tbWFuZCcgKTsKCjw/cGhwIG5hbWVzcGFjZSBNdXN0YW5nb3N0YW5nOwovKioKICAgKiBTcHljIC0tIEEgU2ltcGxlIFBIUCBZQU1MIENsYXNzCiAgICogQHZlcnNpb24gMC42LjIKICAgKiBAYXV0aG9yIFZsYWQgQW5kZXJzZW4gPHZsYWQuYW5kZXJzZW5AZ21haWwuY29tPgogICAqIEBhdXRob3IgQ2hyaXMgV2Fuc3RyYXRoIDxjaHJpc0Bvem1tLm9yZz4KICAgKiBAbGluayBodHRwczovL2dpdGh1Yi5jb20vbXVzdGFuZ29zdGFuZy9zcHljLwogICAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IDIwMDUtMjAwNiBDaHJpcyBXYW5zdHJhdGgsIDIwMDYtMjAxMSBWbGFkIEFuZGVyc2VuCiAgICogQGxpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgTUlUIExpY2Vuc2UKICAgKiBAcGFja2FnZSBTcHljCiAgICovCgovKioKICAgKiBUaGUgU2ltcGxlIFBIUCBZQU1MIENsYXNzLgogICAqCiAgICogVGhpcyBjbGFzcyBjYW4gYmUgdXNlZCB0byByZWFkIGEgWUFNTCBmaWxlIGFuZCBjb252ZXJ0IGl0cyBjb250ZW50cwogICAqIGludG8gYSBQSFAgYXJyYXkuICBJdCBjdXJyZW50bHkgc3VwcG9ydHMgYSB2ZXJ5IGxpbWl0ZWQgc3Vic2VjdGlvbiBvZgogICAqIHRoZSBZQU1MIHNwZWMuCiAgICoKICAgKiBVc2FnZToKICAgKiA8Y29kZT4KICAgKiAgICRTcHljICA9IG5ldyBTcHljOwogICAqICAgJGFycmF5ID0gJFNweWMtPmxvYWQoJGZpbGUpOwogICAqIDwvY29kZT4KICAgKiBvcjoKICAgKiA8Y29kZT4KICAgKiAgICRhcnJheSA9IFNweWM6OllBTUxMb2FkKCRmaWxlKTsKICAgKiA8L2NvZGU+CiAgICogb3I6CiAgICogPGNvZGU+CiAgICogICAkYXJyYXkgPSBzcHljX2xvYWRfZmlsZSgkZmlsZSk7CiAgICogPC9jb2RlPgogICAqIEBwYWNrYWdlIFNweWMKICAgKi8KY2xhc3MgU3B5YyB7CgogIC8vIFNFVFRJTkdTCgogIGNvbnN0IFJFTVBUWSA9ICJcMFwwXDBcMFwwIjsKCiAgLyoqCiAgICogU2V0dGluZyB0aGlzIHRvIHRydWUgd2lsbCBmb3JjZSBZQU1MRHVtcCB0byBlbmNsb3NlIGFueSBzdHJpbmcgdmFsdWUgaW4KICAgKiBxdW90ZXMuICBGYWxzZSBieSBkZWZhdWx0LgogICAqCiAgICogQHZhciBib29sCiAgICovCiAgcHVibGljICRzZXR0aW5nX2R1bXBfZm9yY2VfcXVvdGVzID0gZmFsc2U7CgogIC8qKgogICAqIFNldHRpbmcgdGhpcyB0byB0cnVlIHdpbGwgZm9yc2UgWUFNTExvYWQgdG8gdXNlIHN5Y2tfbG9hZCBmdW5jdGlvbiB3aGVuCiAgICogcG9zc2libGUuIEZhbHNlIGJ5IGRlZmF1bHQuCiAgICogQHZhciBib29sCiAgICovCiAgcHVibGljICRzZXR0aW5nX3VzZV9zeWNrX2lzX3Bvc3NpYmxlID0gZmFsc2U7CgoKCiAgLyoqI0ArCiAgKiBAYWNjZXNzIHByaXZhdGUKICAqIEB2YXIgbWl4ZWQKICAqLwogIHByaXZhdGUgJF9kdW1wSW5kZW50OwogIHByaXZhdGUgJF9kdW1wV29yZFdyYXA7CiAgcHJpdmF0ZSAkX2NvbnRhaW5zR3JvdXBBbmNob3IgPSBmYWxzZTsKICBwcml2YXRlICRfY29udGFpbnNHcm91cEFsaWFzID0gZmFsc2U7CiAgcHJpdmF0ZSAkcGF0aDsKICBwcml2YXRlICRyZXN1bHQ7CiAgcHJpdmF0ZSAkTGl0ZXJhbFBsYWNlSG9sZGVyID0gJ19fX1lBTUxfTGl0ZXJhbF9CbG9ja19fXyc7CiAgcHJpdmF0ZSAkU2F2ZWRHcm91cHMgPSBhcnJheSgpOwogIHByaXZhdGUgJGluZGVudDsKICAvKioKICAgKiBQYXRoIG1vZGlmaWVyIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYWZ0ZXIgYWRkaW5nIGN1cnJlbnQgZWxlbWVudC4KICAgKiBAdmFyIGFycmF5CiAgICovCiAgcHJpdmF0ZSAkZGVsYXllZFBhdGggPSBhcnJheSgpOwoKICAvKiojQCsKICAqIEBhY2Nlc3MgcHVibGljCiAgKiBAdmFyIG1peGVkCiAgKi8KICBwdWJsaWMgJF9ub2RlSWQ7CgovKioKICogTG9hZCBhIHZhbGlkIFlBTUwgc3RyaW5nIHRvIFNweWMuCiAqIEBwYXJhbSBzdHJpbmcgJGlucHV0CiAqIEByZXR1cm4gYXJyYXkKICovCiAgcHVibGljIGZ1bmN0aW9uIGxvYWQgKCRpbnB1dCkgewogICAgcmV0dXJuICR0aGlzLT5fbG9hZFN0cmluZygkaW5wdXQpOwogIH0KCiAvKioKICogTG9hZCBhIHZhbGlkIFlBTUwgZmlsZSB0byBTcHljLgogKiBAcGFyYW0gc3RyaW5nICRmaWxlCiAqIEByZXR1cm4gYXJyYXkKICovCiAgcHVibGljIGZ1bmN0aW9uIGxvYWRGaWxlICgkZmlsZSkgewogICAgcmV0dXJuICR0aGlzLT5fbG9hZCgkZmlsZSk7CiAgfQoKICAvKioKICAgICAqIExvYWQgWUFNTCBpbnRvIGEgUEhQIGFycmF5IHN0YXRpY2FsbHkKICAgICAqCiAgICAgKiBUaGUgbG9hZCBtZXRob2QsIHdoZW4gc3VwcGxpZWQgd2l0aCBhIFlBTUwgc3RyZWFtIChzdHJpbmcgb3IgZmlsZSksCiAgICAgKiB3aWxsIGRvIGl0cyBiZXN0IHRvIGNvbnZlcnQgWUFNTCBpbiBhIGZpbGUgaW50byBhIFBIUCBhcnJheS4gIFByZXR0eQogICAgICogc2ltcGxlLgogICAgICogIFVzYWdlOgogICAgICogIDxjb2RlPgogICAgICogICAkYXJyYXkgPSBTcHljOjpZQU1MTG9hZCgnbHVja3kueWFtbCcpOwogICAgICogICBwcmludF9yKCRhcnJheSk7CiAgICAgKiAgPC9jb2RlPgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFBhdGggb2YgWUFNTCBmaWxlIG9yIHN0cmluZyBjb250YWluaW5nIFlBTUwKICAgICAqLwogIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gWUFNTExvYWQoJGlucHV0KSB7CiAgICAkU3B5YyA9IG5ldyBTcHljOwogICAgcmV0dXJuICRTcHljLT5fbG9hZCgkaW5wdXQpOwogIH0KCiAgLyoqCiAgICAgKiBMb2FkIGEgc3RyaW5nIG9mIFlBTUwgaW50byBhIFBIUCBhcnJheSBzdGF0aWNhbGx5CiAgICAgKgogICAgICogVGhlIGxvYWQgbWV0aG9kLCB3aGVuIHN1cHBsaWVkIHdpdGggYSBZQU1MIHN0cmluZywgd2lsbCBkbyBpdHMgYmVzdAogICAgICogdG8gY29udmVydCBZQU1MIGluIGEgc3RyaW5nIGludG8gYSBQSFAgYXJyYXkuICBQcmV0dHkgc2ltcGxlLgogICAgICoKICAgICAqIE5vdGU6IHVzZSB0aGlzIGZ1bmN0aW9uIGlmIHlvdSBkb24ndCB3YW50IGZpbGVzIGZyb20gdGhlIGZpbGUgc3lzdGVtCiAgICAgKiBsb2FkZWQgYW5kIHByb2Nlc3NlZCBhcyBZQU1MLiAgVGhpcyBpcyBvZiBpbnRlcmVzdCB0byBwZW9wbGUgY29uY2VybmVkCiAgICAgKiBhYm91dCBzZWN1cml0eSB3aG9zZSBpbnB1dCBpcyBmcm9tIGEgc3RyaW5nLgogICAgICoKICAgICAqICBVc2FnZToKICAgICAqICA8Y29kZT4KICAgICAqICAgJGFycmF5ID0gU3B5Yzo6WUFNTExvYWRTdHJpbmcoIi0tLVxuMDogaGVsbG8gd29ybGRcbiIpOwogICAgICogICBwcmludF9yKCRhcnJheSk7CiAgICAgKiAgPC9jb2RlPgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFN0cmluZyBjb250YWluaW5nIFlBTUwKICAgICAqLwogIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gWUFNTExvYWRTdHJpbmcoJGlucHV0KSB7CiAgICAkU3B5YyA9IG5ldyBTcHljOwogICAgcmV0dXJuICRTcHljLT5fbG9hZFN0cmluZygkaW5wdXQpOwogIH0KCiAgLyoqCiAgICAgKiBEdW1wIFlBTUwgZnJvbSBQSFAgYXJyYXkgc3RhdGljYWxseQogICAgICoKICAgICAqIFRoZSBkdW1wIG1ldGhvZCwgd2hlbiBzdXBwbGllZCB3aXRoIGFuIGFycmF5LCB3aWxsIGRvIGl0cyBiZXN0CiAgICAgKiB0byBjb252ZXJ0IHRoZSBhcnJheSBpbnRvIGZyaWVuZGx5IFlBTUwuICBQcmV0dHkgc2ltcGxlLiAgRmVlbCBmcmVlIHRvCiAgICAgKiBzYXZlIHRoZSByZXR1cm5lZCBzdHJpbmcgYXMgbm90aGluZy55YW1sIGFuZCBwYXNzIGl0IGFyb3VuZC4KICAgICAqCiAgICAgKiBPaCwgYW5kIHlvdSBjYW4gZGVjaWRlIGhvdyBiaWcgdGhlIGluZGVudCBpcyBhbmQgd2hhdCB0aGUgd29yZHdyYXAKICAgICAqIGZvciBmb2xkaW5nIGlzLiAgUHJldHR5IGNvb2wgLS0ganVzdCBwYXNzIGluICdmYWxzZScgZm9yIGVpdGhlciBpZgogICAgICogeW91IHdhbnQgdG8gdXNlIHRoZSBkZWZhdWx0LgogICAgICoKICAgICAqIEluZGVudCdzIGRlZmF1bHQgaXMgMiBzcGFjZXMsIHdvcmR3cmFwJ3MgZGVmYXVsdCBpcyA0MCBjaGFyYWN0ZXJzLiAgQW5kCiAgICAgKiB5b3UgY2FuIHR1cm4gb2ZmIHdvcmR3cmFwIGJ5IHBhc3NpbmcgaW4gMC4KICAgICAqCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSBhcnJheXxcc3RkQ2xhc3MgJGFycmF5IFBIUCBhcnJheQogICAgICogQHBhcmFtIGludCAkaW5kZW50IFBhc3MgaW4gZmFsc2UgdG8gdXNlIHRoZSBkZWZhdWx0LCB3aGljaCBpcyAyCiAgICAgKiBAcGFyYW0gaW50ICR3b3Jkd3JhcCBQYXNzIGluIDAgZm9yIG5vIHdvcmR3cmFwLCBmYWxzZSBmb3IgZGVmYXVsdCAoNDApCiAgICAgKiBAcGFyYW0gYm9vbCAkbm9fb3BlbmluZ19kYXNoZXMgRG8gbm90IHN0YXJ0IFlBTUwgZmlsZSB3aXRoICItLS1cbiIKICAgICAqLwogIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gWUFNTER1bXAoJGFycmF5LCAkaW5kZW50ID0gZmFsc2UsICR3b3Jkd3JhcCA9IGZhbHNlLCAkbm9fb3BlbmluZ19kYXNoZXMgPSBmYWxzZSkgewogICAgJHNweWMgPSBuZXcgU3B5YzsKICAgIHJldHVybiAkc3B5Yy0+ZHVtcCgkYXJyYXksICRpbmRlbnQsICR3b3Jkd3JhcCwgJG5vX29wZW5pbmdfZGFzaGVzKTsKICB9CgoKICAvKioKICAgICAqIER1bXAgUEhQIGFycmF5IHRvIFlBTUwKICAgICAqCiAgICAgKiBUaGUgZHVtcCBtZXRob2QsIHdoZW4gc3VwcGxpZWQgd2l0aCBhbiBhcnJheSwgd2lsbCBkbyBpdHMgYmVzdAogICAgICogdG8gY29udmVydCB0aGUgYXJyYXkgaW50byBmcmllbmRseSBZQU1MLiAgUHJldHR5IHNpbXBsZS4gIEZlZWwgZnJlZSB0bwogICAgICogc2F2ZSB0aGUgcmV0dXJuZWQgc3RyaW5nIGFzIHRhc3RlZnVsLnlhbWwgYW5kIHBhc3MgaXQgYXJvdW5kLgogICAgICoKICAgICAqIE9oLCBhbmQgeW91IGNhbiBkZWNpZGUgaG93IGJpZyB0aGUgaW5kZW50IGlzIGFuZCB3aGF0IHRoZSB3b3Jkd3JhcAogICAgICogZm9yIGZvbGRpbmcgaXMuICBQcmV0dHkgY29vbCAtLSBqdXN0IHBhc3MgaW4gJ2ZhbHNlJyBmb3IgZWl0aGVyIGlmCiAgICAgKiB5b3Ugd2FudCB0byB1c2UgdGhlIGRlZmF1bHQuCiAgICAgKgogICAgICogSW5kZW50J3MgZGVmYXVsdCBpcyAyIHNwYWNlcywgd29yZHdyYXAncyBkZWZhdWx0IGlzIDQwIGNoYXJhY3RlcnMuICBBbmQKICAgICAqIHlvdSBjYW4gdHVybiBvZmYgd29yZHdyYXAgYnkgcGFzc2luZyBpbiAwLgogICAgICoKICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtIGFycmF5ICRhcnJheSBQSFAgYXJyYXkKICAgICAqIEBwYXJhbSBpbnQgJGluZGVudCBQYXNzIGluIGZhbHNlIHRvIHVzZSB0aGUgZGVmYXVsdCwgd2hpY2ggaXMgMgogICAgICogQHBhcmFtIGludCAkd29yZHdyYXAgUGFzcyBpbiAwIGZvciBubyB3b3Jkd3JhcCwgZmFsc2UgZm9yIGRlZmF1bHQgKDQwKQogICAgICovCiAgcHVibGljIGZ1bmN0aW9uIGR1bXAoJGFycmF5LCRpbmRlbnQgPSBmYWxzZSwkd29yZHdyYXAgPSBmYWxzZSwgJG5vX29wZW5pbmdfZGFzaGVzID0gZmFsc2UpIHsKICAgIC8vIER1bXBzIHRvIHNvbWUgdmVyeSBjbGVhbiBZQU1MLiAgV2UnbGwgaGF2ZSB0byBhZGQgc29tZSBtb3JlIGZlYXR1cmVzCiAgICAvLyBhbmQgb3B0aW9ucyBzb29uLiAgQW5kIGJldHRlciBzdXBwb3J0IGZvciBmb2xkaW5nLgoKICAgIC8vIE5ldyBmZWF0dXJlcyBhbmQgb3B0aW9ucy4KICAgIGlmICgkaW5kZW50ID09PSBmYWxzZSBvciAhaXNfbnVtZXJpYygkaW5kZW50KSkgewogICAgICAkdGhpcy0+X2R1bXBJbmRlbnQgPSAyOwogICAgfSBlbHNlIHsKICAgICAgJHRoaXMtPl9kdW1wSW5kZW50ID0gJGluZGVudDsKICAgIH0KCiAgICBpZiAoJHdvcmR3cmFwID09PSBmYWxzZSBvciAhaXNfbnVtZXJpYygkd29yZHdyYXApKSB7CiAgICAgICR0aGlzLT5fZHVtcFdvcmRXcmFwID0gNDA7CiAgICB9IGVsc2UgewogICAgICAkdGhpcy0+X2R1bXBXb3JkV3JhcCA9ICR3b3Jkd3JhcDsKICAgIH0KCiAgICAvLyBOZXcgWUFNTCBkb2N1bWVudAogICAgJHN0cmluZyA9ICIiOwogICAgaWYgKCEkbm9fb3BlbmluZ19kYXNoZXMpICRzdHJpbmcgPSAiLS0tXG4iOwoKICAgIC8vIFN0YXJ0IGF0IHRoZSBiYXNlIG9mIHRoZSBhcnJheSBhbmQgbW92ZSB0aHJvdWdoIGl0LgogICAgaWYgKCRhcnJheSkgewogICAgICAkYXJyYXkgPSAoYXJyYXkpJGFycmF5OwogICAgICAkcHJldmlvdXNfa2V5ID0gLTE7CiAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIGlmICghaXNzZXQoJGZpcnN0X2tleSkpICRmaXJzdF9rZXkgPSAka2V5OwogICAgICAgICRzdHJpbmcgLj0gJHRoaXMtPl95YW1saXplKCRrZXksJHZhbHVlLDAsJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSwgJGFycmF5KTsKICAgICAgICAkcHJldmlvdXNfa2V5ID0gJGtleTsKICAgICAgfQogICAgfQogICAgcmV0dXJuICRzdHJpbmc7CiAgfQoKICAvKioKICAgICAqIEF0dGVtcHRzIHRvIGNvbnZlcnQgYSBrZXkgLyB2YWx1ZSBhcnJheSBpdGVtIHRvIFlBTUwKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAka2V5IFRoZSBuYW1lIG9mIHRoZSBrZXkKICAgICAqIEBwYXJhbSAkdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBpdGVtCiAgICAgKiBAcGFyYW0gJGluZGVudCBUaGUgaW5kZW50IG9mIHRoZSBjdXJyZW50IG5vZGUKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX3lhbWxpemUoJGtleSwkdmFsdWUsJGluZGVudCwgJHByZXZpb3VzX2tleSA9IC0xLCAkZmlyc3Rfa2V5ID0gMCwgJHNvdXJjZV9hcnJheSA9IG51bGwpIHsKICAgIGlmKGlzX29iamVjdCgkdmFsdWUpKSAkdmFsdWUgPSAoYXJyYXkpJHZhbHVlOwogICAgaWYgKGlzX2FycmF5KCR2YWx1ZSkpIHsKICAgICAgaWYgKGVtcHR5ICgkdmFsdWUpKQogICAgICAgIHJldHVybiAkdGhpcy0+X2R1bXBOb2RlKCRrZXksIGFycmF5KCksICRpbmRlbnQsICRwcmV2aW91c19rZXksICRmaXJzdF9rZXksICRzb3VyY2VfYXJyYXkpOwogICAgICAvLyBJdCBoYXMgY2hpbGRyZW4uICBXaGF0IHRvIGRvPwogICAgICAvLyBNYWtlIGl0IHRoZSByaWdodCBraW5kIG9mIGl0ZW0KICAgICAgJHN0cmluZyA9ICR0aGlzLT5fZHVtcE5vZGUoJGtleSwgc2VsZjo6UkVNUFRZLCAkaW5kZW50LCAkcHJldmlvdXNfa2V5LCAkZmlyc3Rfa2V5LCAkc291cmNlX2FycmF5KTsKICAgICAgLy8gQWRkIHRoZSBpbmRlbnQKICAgICAgJGluZGVudCArPSAkdGhpcy0+X2R1bXBJbmRlbnQ7CiAgICAgIC8vIFlhbWxpemUgdGhlIGFycmF5CiAgICAgICRzdHJpbmcgLj0gJHRoaXMtPl95YW1saXplQXJyYXkoJHZhbHVlLCRpbmRlbnQpOwogICAgfSBlbHNlaWYgKCFpc19hcnJheSgkdmFsdWUpKSB7CiAgICAgIC8vIEl0IGRvZXNuJ3QgaGF2ZSBjaGlsZHJlbi4gIFlpcC4KICAgICAgJHN0cmluZyA9ICR0aGlzLT5fZHVtcE5vZGUoJGtleSwgJHZhbHVlLCAkaW5kZW50LCAkcHJldmlvdXNfa2V5LCAkZmlyc3Rfa2V5LCAkc291cmNlX2FycmF5KTsKICAgIH0KICAgIHJldHVybiAkc3RyaW5nOwogIH0KCiAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBjb252ZXJ0IGFuIGFycmF5IHRvIFlBTUwKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAkYXJyYXkgVGhlIGFycmF5IHlvdSB3YW50IHRvIGNvbnZlcnQKICAgICAqIEBwYXJhbSAkaW5kZW50IFRoZSBpbmRlbnQgb2YgdGhlIGN1cnJlbnQgbGV2ZWwKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX3lhbWxpemVBcnJheSgkYXJyYXksJGluZGVudCkgewogICAgaWYgKGlzX2FycmF5KCRhcnJheSkpIHsKICAgICAgJHN0cmluZyA9ICcnOwogICAgICAkcHJldmlvdXNfa2V5ID0gLTE7CiAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIGlmICghaXNzZXQoJGZpcnN0X2tleSkpICRmaXJzdF9rZXkgPSAka2V5OwogICAgICAgICRzdHJpbmcgLj0gJHRoaXMtPl95YW1saXplKCRrZXksICR2YWx1ZSwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSwgJGFycmF5KTsKICAgICAgICAkcHJldmlvdXNfa2V5ID0gJGtleTsKICAgICAgfQogICAgICByZXR1cm4gJHN0cmluZzsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CgogIC8qKgogICAgICogUmV0dXJucyBZQU1MIGZyb20gYSBrZXkgYW5kIGEgdmFsdWUKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAka2V5IFRoZSBuYW1lIG9mIHRoZSBrZXkKICAgICAqIEBwYXJhbSAkdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBpdGVtCiAgICAgKiBAcGFyYW0gJGluZGVudCBUaGUgaW5kZW50IG9mIHRoZSBjdXJyZW50IG5vZGUKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX2R1bXBOb2RlKCRrZXksICR2YWx1ZSwgJGluZGVudCwgJHByZXZpb3VzX2tleSA9IC0xLCAkZmlyc3Rfa2V5ID0gMCwgJHNvdXJjZV9hcnJheSA9IG51bGwpIHsKICAgIC8vIGRvIHNvbWUgZm9sZGluZyBoZXJlLCBmb3IgYmxvY2tzCiAgICBpZiAoaXNfc3RyaW5nICgkdmFsdWUpICYmICgoc3RycG9zKCR2YWx1ZSwiXG4iKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiOiAiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiLSAiKSAhPT0gZmFsc2UgfHwKICAgICAgc3RycG9zKCR2YWx1ZSwiKiIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCIjIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIjwiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiPiIpICE9PSBmYWxzZSB8fCBzdHJwb3MgKCR2YWx1ZSwgJyUnKSAhPT0gZmFsc2UgfHwgc3RycG9zICgkdmFsdWUsICcgICcpICE9PSBmYWxzZSB8fAogICAgICBzdHJwb3MoJHZhbHVlLCJbIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIl0iKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwieyIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCJ9IikgIT09IGZhbHNlKSB8fCBzdHJwb3MoJHZhbHVlLCImIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsICInIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsICIhIikgPT09IDAgfHwKICAgICAgc3Vic3RyICgkdmFsdWUsIC0xLCAxKSA9PSAnOicpCiAgICApIHsKICAgICAgJHZhbHVlID0gJHRoaXMtPl9kb0xpdGVyYWxCbG9jaygkdmFsdWUsJGluZGVudCk7CiAgICB9IGVsc2UgewogICAgICAkdmFsdWUgID0gJHRoaXMtPl9kb0ZvbGRpbmcoJHZhbHVlLCRpbmRlbnQpOwogICAgfQoKICAgIGlmICgkdmFsdWUgPT09IGFycmF5KCkpICR2YWx1ZSA9ICdbIF0nOwogICAgaWYgKCR2YWx1ZSA9PT0gIiIpICR2YWx1ZSA9ICciIic7CiAgICBpZiAoc2VsZjo6aXNUcmFuc2xhdGlvbldvcmQoJHZhbHVlKSkgewogICAgICAkdmFsdWUgPSAkdGhpcy0+X2RvTGl0ZXJhbEJsb2NrKCR2YWx1ZSwgJGluZGVudCk7CiAgICB9CiAgICBpZiAodHJpbSAoJHZhbHVlKSAhPSAkdmFsdWUpCiAgICAgICAkdmFsdWUgPSAkdGhpcy0+X2RvTGl0ZXJhbEJsb2NrKCR2YWx1ZSwkaW5kZW50KTsKCiAgICBpZiAoaXNfYm9vbCgkdmFsdWUpKSB7CiAgICAgICAkdmFsdWUgPSAkdmFsdWUgPyAidHJ1ZSIgOiAiZmFsc2UiOwogICAgfQoKICAgIGlmICgkdmFsdWUgPT09IG51bGwpICR2YWx1ZSA9ICdudWxsJzsKICAgIGlmICgkdmFsdWUgPT09ICInIiAuIHNlbGY6OlJFTVBUWSAuICInIikgJHZhbHVlID0gbnVsbDsKCiAgICAkc3BhY2VzID0gc3RyX3JlcGVhdCgnICcsJGluZGVudCk7CgogICAgLy9pZiAoaXNfaW50KCRrZXkpICYmICRrZXkgLSAxID09ICRwcmV2aW91c19rZXkgJiYgJGZpcnN0X2tleT09PTApIHsKICAgIGlmIChpc19hcnJheSAoJHNvdXJjZV9hcnJheSkgJiYgYXJyYXlfa2V5cygkc291cmNlX2FycmF5KSA9PT0gcmFuZ2UoMCwgY291bnQoJHNvdXJjZV9hcnJheSkgLSAxKSkgewogICAgICAvLyBJdCdzIGEgc2VxdWVuY2UKICAgICAgJHN0cmluZyA9ICRzcGFjZXMuJy0gJy4kdmFsdWUuIlxuIjsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGlmICgkZmlyc3Rfa2V5PT09MCkgIHRocm93IG5ldyBcRXhjZXB0aW9uKCdLZXlzIGFyZSBhbGwgc2NyZXd5LiAgVGhlIGZpcnN0IG9uZSB3YXMgemVybywgbm93IGl0XCdzICInLiAka2V5IC4nIicpOwogICAgICAvLyBJdCdzIG1hcHBlZAogICAgICBpZiAoc3RycG9zKCRrZXksICI6IikgIT09IGZhbHNlIHx8IHN0cnBvcygka2V5LCAiIyIpICE9PSBmYWxzZSkgeyAka2V5ID0gJyInIC4gJGtleSAuICciJzsgfQogICAgICAkc3RyaW5nID0gcnRyaW0gKCRzcGFjZXMuJGtleS4nOiAnLiR2YWx1ZSkuIlxuIjsKICAgIH0KICAgIHJldHVybiAkc3RyaW5nOwogIH0KCiAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbGl0ZXJhbCBibG9jayBmb3IgZHVtcGluZwogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtICR2YWx1ZQogICAgICogQHBhcmFtICRpbmRlbnQgaW50IFRoZSB2YWx1ZSBvZiB0aGUgaW5kZW50CiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF9kb0xpdGVyYWxCbG9jaygkdmFsdWUsJGluZGVudCkgewogICAgaWYgKCR2YWx1ZSA9PT0gIlxuIikgcmV0dXJuICdcbic7CiAgICBpZiAoc3RycG9zKCR2YWx1ZSwgIlxuIikgPT09IGZhbHNlICYmIHN0cnBvcygkdmFsdWUsICInIikgPT09IGZhbHNlKSB7CiAgICAgIHJldHVybiBzcHJpbnRmICgiJyVzJyIsICR2YWx1ZSk7CiAgICB9CiAgICBpZiAoc3RycG9zKCR2YWx1ZSwgIlxuIikgPT09IGZhbHNlICYmIHN0cnBvcygkdmFsdWUsICciJykgPT09IGZhbHNlKSB7CiAgICAgIHJldHVybiBzcHJpbnRmICgnIiVzIicsICR2YWx1ZSk7CiAgICB9CiAgICAkZXhwbG9kZWQgPSBleHBsb2RlKCJcbiIsJHZhbHVlKTsKICAgICRuZXdWYWx1ZSA9ICd8JzsKICAgIGlmIChpc3NldCgkZXhwbG9kZWRbMF0pICYmICgkZXhwbG9kZWRbMF0gPT0gInwiIHx8ICRleHBsb2RlZFswXSA9PSAifC0iIHx8ICRleHBsb2RlZFswXSA9PSAiPiIpKSB7CiAgICAgICAgJG5ld1ZhbHVlID0gJGV4cGxvZGVkWzBdOwogICAgICAgIHVuc2V0KCRleHBsb2RlZFswXSk7CiAgICB9CiAgICAkaW5kZW50ICs9ICR0aGlzLT5fZHVtcEluZGVudDsKICAgICRzcGFjZXMgICA9IHN0cl9yZXBlYXQoJyAnLCRpbmRlbnQpOwogICAgZm9yZWFjaCAoJGV4cGxvZGVkIGFzICRsaW5lKSB7CiAgICAgICRsaW5lID0gdHJpbSgkbGluZSk7CiAgICAgIGlmIChzdHJwb3MoJGxpbmUsICciJykgPT09IDAgJiYgc3RycnBvcygkbGluZSwgJyInKSA9PSAoc3RybGVuKCRsaW5lKS0xKSB8fCBzdHJwb3MoJGxpbmUsICInIikgPT09IDAgJiYgc3RycnBvcygkbGluZSwgIiciKSA9PSAoc3RybGVuKCRsaW5lKS0xKSkgewogICAgICAgICRsaW5lID0gc3Vic3RyKCRsaW5lLCAxLCAtMSk7CiAgICAgIH0KICAgICAgJG5ld1ZhbHVlIC49ICJcbiIgLiAkc3BhY2VzIC4gKCRsaW5lKTsKICAgIH0KICAgIHJldHVybiAkbmV3VmFsdWU7CiAgfQoKICAvKioKICAgICAqIEZvbGRzIGEgc3RyaW5nIG9mIHRleHQsIGlmIG5lY2Vzc2FyeQogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtICR2YWx1ZSBUaGUgc3RyaW5nIHlvdSB3aXNoIHRvIGZvbGQKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX2RvRm9sZGluZygkdmFsdWUsJGluZGVudCkgewogICAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgd29yZHdyYXAgaXMgc2V0IHRvIDAKCiAgICBpZiAoJHRoaXMtPl9kdW1wV29yZFdyYXAgIT09IDAgJiYgaXNfc3RyaW5nICgkdmFsdWUpICYmIHN0cmxlbigkdmFsdWUpID4gJHRoaXMtPl9kdW1wV29yZFdyYXApIHsKICAgICAgJGluZGVudCArPSAkdGhpcy0+X2R1bXBJbmRlbnQ7CiAgICAgICRpbmRlbnQgPSBzdHJfcmVwZWF0KCcgJywkaW5kZW50KTsKICAgICAgJHdyYXBwZWQgPSB3b3Jkd3JhcCgkdmFsdWUsJHRoaXMtPl9kdW1wV29yZFdyYXAsIlxuJGluZGVudCIpOwogICAgICAkdmFsdWUgICA9ICI+XG4iLiRpbmRlbnQuJHdyYXBwZWQ7CiAgICB9IGVsc2UgewogICAgICBpZiAoJHRoaXMtPnNldHRpbmdfZHVtcF9mb3JjZV9xdW90ZXMgJiYgaXNfc3RyaW5nICgkdmFsdWUpICYmICR2YWx1ZSAhPT0gc2VsZjo6UkVNUFRZKQogICAgICAgICR2YWx1ZSA9ICciJyAuICR2YWx1ZSAuICciJzsKICAgICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSAmJiBpc19zdHJpbmcoJHZhbHVlKSkKICAgICAgICAkdmFsdWUgPSAnIicgLiAkdmFsdWUgLiAnIic7CiAgICB9CgoKICAgIHJldHVybiAkdmFsdWU7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGlzVHJ1ZVdvcmQoJHZhbHVlKSB7CiAgICAkd29yZHMgPSBzZWxmOjpnZXRUcmFuc2xhdGlvbnMoYXJyYXkoJ3RydWUnLCAnb24nLCAneWVzJywgJ3knKSk7CiAgICByZXR1cm4gaW5fYXJyYXkoJHZhbHVlLCAkd29yZHMsIHRydWUpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBpc0ZhbHNlV29yZCgkdmFsdWUpIHsKICAgICR3b3JkcyA9IHNlbGY6OmdldFRyYW5zbGF0aW9ucyhhcnJheSgnZmFsc2UnLCAnb2ZmJywgJ25vJywgJ24nKSk7CiAgICByZXR1cm4gaW5fYXJyYXkoJHZhbHVlLCAkd29yZHMsIHRydWUpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBpc051bGxXb3JkKCR2YWx1ZSkgewogICAgJHdvcmRzID0gc2VsZjo6Z2V0VHJhbnNsYXRpb25zKGFycmF5KCdudWxsJywgJ34nKSk7CiAgICByZXR1cm4gaW5fYXJyYXkoJHZhbHVlLCAkd29yZHMsIHRydWUpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBpc1RyYW5zbGF0aW9uV29yZCgkdmFsdWUpIHsKICAgIHJldHVybiAoCiAgICAgIHNlbGY6OmlzVHJ1ZVdvcmQoJHZhbHVlKSAgfHwKICAgICAgc2VsZjo6aXNGYWxzZVdvcmQoJHZhbHVlKSB8fAogICAgICBzZWxmOjppc051bGxXb3JkKCR2YWx1ZSkKICAgICk7CiAgfQoKICAvKioKICAgICAqIENvZXJjZSBhIHN0cmluZyBpbnRvIGEgbmF0aXZlIHR5cGUKICAgICAqIFJlZmVyZW5jZTogaHR0cDovL3lhbWwub3JnL3R5cGUvYm9vbC5odG1sCiAgICAgKiBUT0RPOiBVc2Ugb25seSB3b3JkcyBmcm9tIHRoZSBZQU1MIHNwZWMuCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEBwYXJhbSAkdmFsdWUgVGhlIHZhbHVlIHRvIGNvZXJjZQogICAgICovCiAgcHJpdmF0ZSBmdW5jdGlvbiBjb2VyY2VWYWx1ZSgmJHZhbHVlKSB7CiAgICBpZiAoc2VsZjo6aXNUcnVlV29yZCgkdmFsdWUpKSB7CiAgICAgICR2YWx1ZSA9IHRydWU7CiAgICB9IGVsc2UgaWYgKHNlbGY6OmlzRmFsc2VXb3JkKCR2YWx1ZSkpIHsKICAgICAgJHZhbHVlID0gZmFsc2U7CiAgICB9IGVsc2UgaWYgKHNlbGY6OmlzTnVsbFdvcmQoJHZhbHVlKSkgewogICAgICAkdmFsdWUgPSBudWxsOwogICAgfQogIH0KCiAgLyoqCiAgICAgKiBHaXZlbiBhIHNldCBvZiB3b3JkcywgcGVyZm9ybSB0aGUgYXBwcm9wcmlhdGUgdHJhbnNsYXRpb25zIG9uIHRoZW0gdG8KICAgICAqIG1hdGNoIHRoZSBZQU1MIDEuMSBzcGVjaWZpY2F0aW9uIGZvciB0eXBlIGNvZXJjaW5nLgogICAgICogQHBhcmFtICR3b3JkcyBUaGUgd29yZHMgdG8gdHJhbnNsYXRlCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqLwogIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldFRyYW5zbGF0aW9ucyhhcnJheSAkd29yZHMpIHsKICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgZm9yZWFjaCAoJHdvcmRzIGFzICRpKSB7CiAgICAgICRyZXN1bHQgPSBhcnJheV9tZXJnZSgkcmVzdWx0LCBhcnJheSh1Y2ZpcnN0KCRpKSwgc3RydG91cHBlcigkaSksIHN0cnRvbG93ZXIoJGkpKSk7CiAgICB9CiAgICByZXR1cm4gJHJlc3VsdDsKICB9CgovLyBMT0FESU5HIEZVTkNUSU9OUwoKICBwcml2YXRlIGZ1bmN0aW9uIF9sb2FkKCRpbnB1dCkgewogICAgJFNvdXJjZSA9ICR0aGlzLT5sb2FkRnJvbVNvdXJjZSgkaW5wdXQpOwogICAgcmV0dXJuICR0aGlzLT5sb2FkV2l0aFNvdXJjZSgkU291cmNlKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gX2xvYWRTdHJpbmcoJGlucHV0KSB7CiAgICAkU291cmNlID0gJHRoaXMtPmxvYWRGcm9tU3RyaW5nKCRpbnB1dCk7CiAgICByZXR1cm4gJHRoaXMtPmxvYWRXaXRoU291cmNlKCRTb3VyY2UpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkV2l0aFNvdXJjZSgkU291cmNlKSB7CiAgICBpZiAoZW1wdHkgKCRTb3VyY2UpKSByZXR1cm4gYXJyYXkoKTsKICAgIGlmICgkdGhpcy0+c2V0dGluZ191c2Vfc3lja19pc19wb3NzaWJsZSAmJiBmdW5jdGlvbl9leGlzdHMgKCdzeWNrX2xvYWQnKSkgewogICAgICAkYXJyYXkgPSBzeWNrX2xvYWQgKGltcGxvZGUgKCJcbiIsICRTb3VyY2UpKTsKICAgICAgcmV0dXJuIGlzX2FycmF5KCRhcnJheSkgPyAkYXJyYXkgOiBhcnJheSgpOwogICAgfQoKICAgICR0aGlzLT5wYXRoID0gYXJyYXkoKTsKICAgICR0aGlzLT5yZXN1bHQgPSBhcnJheSgpOwoKICAgICRjbnQgPSBjb3VudCgkU291cmNlKTsKICAgIGZvciAoJGkgPSAwOyAkaSA8ICRjbnQ7ICRpKyspIHsKICAgICAgJGxpbmUgPSAkU291cmNlWyRpXTsKCiAgICAgICR0aGlzLT5pbmRlbnQgPSBzdHJsZW4oJGxpbmUpIC0gc3RybGVuKGx0cmltKCRsaW5lKSk7CiAgICAgICR0ZW1wUGF0aCA9ICR0aGlzLT5nZXRQYXJlbnRQYXRoQnlJbmRlbnQoJHRoaXMtPmluZGVudCk7CiAgICAgICRsaW5lID0gc2VsZjo6c3RyaXBJbmRlbnQoJGxpbmUsICR0aGlzLT5pbmRlbnQpOwogICAgICBpZiAoc2VsZjo6aXNDb21tZW50KCRsaW5lKSkgY29udGludWU7CiAgICAgIGlmIChzZWxmOjppc0VtcHR5KCRsaW5lKSkgY29udGludWU7CiAgICAgICR0aGlzLT5wYXRoID0gJHRlbXBQYXRoOwoKICAgICAgJGxpdGVyYWxCbG9ja1N0eWxlID0gc2VsZjo6c3RhcnRzTGl0ZXJhbEJsb2NrKCRsaW5lKTsKICAgICAgaWYgKCRsaXRlcmFsQmxvY2tTdHlsZSkgewogICAgICAgICRsaW5lID0gcnRyaW0gKCRsaW5lLCAkbGl0ZXJhbEJsb2NrU3R5bGUgLiAiIFxuIik7CiAgICAgICAgJGxpdGVyYWxCbG9jayA9ICcnOwogICAgICAgICRsaW5lIC49ICcgJy4kdGhpcy0+TGl0ZXJhbFBsYWNlSG9sZGVyOwogICAgICAgICRsaXRlcmFsX2Jsb2NrX2luZGVudCA9IHN0cmxlbigkU291cmNlWyRpKzFdKSAtIHN0cmxlbihsdHJpbSgkU291cmNlWyRpKzFdKSk7CiAgICAgICAgd2hpbGUgKCsrJGkgPCAkY250ICYmICR0aGlzLT5saXRlcmFsQmxvY2tDb250aW51ZXMoJFNvdXJjZVskaV0sICR0aGlzLT5pbmRlbnQpKSB7CiAgICAgICAgICAkbGl0ZXJhbEJsb2NrID0gJHRoaXMtPmFkZExpdGVyYWxMaW5lKCRsaXRlcmFsQmxvY2ssICRTb3VyY2VbJGldLCAkbGl0ZXJhbEJsb2NrU3R5bGUsICRsaXRlcmFsX2Jsb2NrX2luZGVudCk7CiAgICAgICAgfQogICAgICAgICRpLS07CiAgICAgIH0KCiAgICAgIC8vIFN0cmlwIG91dCBjb21tZW50cwogICAgICBpZiAoc3RycG9zICgkbGluZSwgJyMnKSkgewogICAgICAgICAgJGxpbmUgPSBwcmVnX3JlcGxhY2UoJy9ccyojKFteIlwnXSspJC8nLCcnLCRsaW5lKTsKICAgICAgfQoKICAgICAgd2hpbGUgKCsrJGkgPCAkY250ICYmIHNlbGY6OmdyZWVkaWx5TmVlZE5leHRMaW5lKCRsaW5lKSkgewogICAgICAgICRsaW5lID0gcnRyaW0gKCRsaW5lLCAiIFxuXHRcciIpIC4gJyAnIC4gbHRyaW0gKCRTb3VyY2VbJGldLCAiIFx0Iik7CiAgICAgIH0KICAgICAgJGktLTsKCiAgICAgICRsaW5lQXJyYXkgPSAkdGhpcy0+X3BhcnNlTGluZSgkbGluZSk7CgogICAgICBpZiAoJGxpdGVyYWxCbG9ja1N0eWxlKQogICAgICAgICRsaW5lQXJyYXkgPSAkdGhpcy0+cmV2ZXJ0TGl0ZXJhbFBsYWNlSG9sZGVyICgkbGluZUFycmF5LCAkbGl0ZXJhbEJsb2NrKTsKCiAgICAgICR0aGlzLT5hZGRBcnJheSgkbGluZUFycmF5LCAkdGhpcy0+aW5kZW50KTsKCiAgICAgIGZvcmVhY2ggKCR0aGlzLT5kZWxheWVkUGF0aCBhcyAkaW5kZW50ID0+ICRkZWxheWVkUGF0aCkKICAgICAgICAkdGhpcy0+cGF0aFskaW5kZW50XSA9ICRkZWxheWVkUGF0aDsKCiAgICAgICR0aGlzLT5kZWxheWVkUGF0aCA9IGFycmF5KCk7CgogICAgfQogICAgcmV0dXJuICR0aGlzLT5yZXN1bHQ7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRGcm9tU291cmNlICgkaW5wdXQpIHsKICAgIGlmICghZW1wdHkoJGlucHV0KSAmJiBzdHJwb3MoJGlucHV0LCAiXG4iKSA9PT0gZmFsc2UgJiYgZmlsZV9leGlzdHMoJGlucHV0KSkKICAgICAgJGlucHV0ID0gZmlsZV9nZXRfY29udGVudHMoJGlucHV0KTsKCiAgICByZXR1cm4gJHRoaXMtPmxvYWRGcm9tU3RyaW5nKCRpbnB1dCk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRGcm9tU3RyaW5nICgkaW5wdXQpIHsKICAgICRsaW5lcyA9IGV4cGxvZGUoIlxuIiwkaW5wdXQpOwogICAgZm9yZWFjaCAoJGxpbmVzIGFzICRrID0+ICRfKSB7CiAgICAgICRsaW5lc1ska10gPSBydHJpbSAoJF8sICJcciIpOwogICAgfQogICAgcmV0dXJuICRsaW5lczsKICB9CgogIC8qKgogICAgICogUGFyc2VzIFlBTUwgY29kZSBhbmQgcmV0dXJucyBhbiBhcnJheSBmb3IgYSBub2RlCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUgQSBsaW5lIGZyb20gdGhlIFlBTUwgZmlsZQogICAgICovCiAgcHJpdmF0ZSBmdW5jdGlvbiBfcGFyc2VMaW5lKCRsaW5lKSB7CiAgICBpZiAoISRsaW5lKSByZXR1cm4gYXJyYXkoKTsKICAgICRsaW5lID0gdHJpbSgkbGluZSk7CiAgICBpZiAoISRsaW5lKSByZXR1cm4gYXJyYXkoKTsKCiAgICAkYXJyYXkgPSBhcnJheSgpOwoKICAgICRncm91cCA9ICR0aGlzLT5ub2RlQ29udGFpbnNHcm91cCgkbGluZSk7CiAgICBpZiAoJGdyb3VwKSB7CiAgICAgICR0aGlzLT5hZGRHcm91cCgkbGluZSwgJGdyb3VwKTsKICAgICAgJGxpbmUgPSAkdGhpcy0+c3RyaXBHcm91cCAoJGxpbmUsICRncm91cCk7CiAgICB9CgogICAgaWYgKCR0aGlzLT5zdGFydHNNYXBwZWRTZXF1ZW5jZSgkbGluZSkpCiAgICAgIHJldHVybiAkdGhpcy0+cmV0dXJuTWFwcGVkU2VxdWVuY2UoJGxpbmUpOwoKICAgIGlmICgkdGhpcy0+c3RhcnRzTWFwcGVkVmFsdWUoJGxpbmUpKQogICAgICByZXR1cm4gJHRoaXMtPnJldHVybk1hcHBlZFZhbHVlKCRsaW5lKTsKCiAgICBpZiAoJHRoaXMtPmlzQXJyYXlFbGVtZW50KCRsaW5lKSkKICAgICByZXR1cm4gJHRoaXMtPnJldHVybkFycmF5RWxlbWVudCgkbGluZSk7CgogICAgaWYgKCR0aGlzLT5pc1BsYWluQXJyYXkoJGxpbmUpKQogICAgIHJldHVybiAkdGhpcy0+cmV0dXJuUGxhaW5BcnJheSgkbGluZSk7CgoKICAgIHJldHVybiAkdGhpcy0+cmV0dXJuS2V5VmFsdWVQYWlyKCRsaW5lKTsKCiAgfQoKICAvKioKICAgICAqIEZpbmRzIHRoZSB0eXBlIG9mIHRoZSBwYXNzZWQgdmFsdWUsIHJldHVybnMgdGhlIHZhbHVlIGFzIHRoZSBuZXcgdHlwZS4KICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX3RvVHlwZSgkdmFsdWUpIHsKICAgIGlmICgkdmFsdWUgPT09ICcnKSByZXR1cm4gIiI7CiAgICAkZmlyc3RfY2hhcmFjdGVyID0gJHZhbHVlWzBdOwogICAgJGxhc3RfY2hhcmFjdGVyID0gc3Vic3RyKCR2YWx1ZSwgLTEsIDEpOwoKICAgICRpc19xdW90ZWQgPSBmYWxzZTsKICAgIGRvIHsKICAgICAgaWYgKCEkdmFsdWUpIGJyZWFrOwogICAgICBpZiAoJGZpcnN0X2NoYXJhY3RlciAhPSAnIicgJiYgJGZpcnN0X2NoYXJhY3RlciAhPSAiJyIpIGJyZWFrOwogICAgICBpZiAoJGxhc3RfY2hhcmFjdGVyICE9ICciJyAmJiAkbGFzdF9jaGFyYWN0ZXIgIT0gIiciKSBicmVhazsKICAgICAgJGlzX3F1b3RlZCA9IHRydWU7CiAgICB9IHdoaWxlICgwKTsKCiAgICBpZiAoJGlzX3F1b3RlZCkgewogICAgICAkdmFsdWUgPSBzdHJfcmVwbGFjZSgnXG4nLCAiXG4iLCAkdmFsdWUpOwogICAgICBpZiAoJGZpcnN0X2NoYXJhY3RlciA9PSAiJyIpCiAgICAgICAgcmV0dXJuIHN0cnRyKHN1YnN0ciAoJHZhbHVlLCAxLCAtMSksIGFycmF5ICgnXCdcJycgPT4gJ1wnJywgJ1xcXCcnPT4gJ1wnJykpOwogICAgICByZXR1cm4gc3RydHIoc3Vic3RyICgkdmFsdWUsIDEsIC0xKSwgYXJyYXkgKCdcXCInID0+ICciJywgJ1xcXCcnPT4gJ1wnJykpOwogICAgfQoKICAgIGlmIChzdHJwb3MoJHZhbHVlLCAnICMnKSAhPT0gZmFsc2UgJiYgISRpc19xdW90ZWQpCiAgICAgICR2YWx1ZSA9IHByZWdfcmVwbGFjZSgnL1xzKyMoLispJC8nLCcnLCR2YWx1ZSk7CgogICAgaWYgKCRmaXJzdF9jaGFyYWN0ZXIgPT0gJ1snICYmICRsYXN0X2NoYXJhY3RlciA9PSAnXScpIHsKICAgICAgLy8gVGFrZSBvdXQgc3RyaW5ncyBzZXF1ZW5jZXMgYW5kIG1hcHBpbmdzCiAgICAgICRpbm5lclZhbHVlID0gdHJpbShzdWJzdHIgKCR2YWx1ZSwgMSwgLTEpKTsKICAgICAgaWYgKCRpbm5lclZhbHVlID09PSAnJykgcmV0dXJuIGFycmF5KCk7CiAgICAgICRleHBsb2RlID0gJHRoaXMtPl9pbmxpbmVFc2NhcGUoJGlubmVyVmFsdWUpOwogICAgICAvLyBQcm9wYWdhdGUgdmFsdWUgYXJyYXkKICAgICAgJHZhbHVlICA9IGFycmF5KCk7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICR2KSB7CiAgICAgICAgJHZhbHVlW10gPSAkdGhpcy0+X3RvVHlwZSgkdik7CiAgICAgIH0KICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KCiAgICBpZiAoc3RycG9zKCR2YWx1ZSwnOiAnKSE9PWZhbHNlICYmICRmaXJzdF9jaGFyYWN0ZXIgIT0gJ3snKSB7CiAgICAgICRhcnJheSA9IGV4cGxvZGUoJzogJywkdmFsdWUpOwogICAgICAka2V5ICAgPSB0cmltKCRhcnJheVswXSk7CiAgICAgIGFycmF5X3NoaWZ0KCRhcnJheSk7CiAgICAgICR2YWx1ZSA9IHRyaW0oaW1wbG9kZSgnOiAnLCRhcnJheSkpOwogICAgICAkdmFsdWUgPSAkdGhpcy0+X3RvVHlwZSgkdmFsdWUpOwogICAgICByZXR1cm4gYXJyYXkoJGtleSA9PiAkdmFsdWUpOwogICAgfQoKICAgIGlmICgkZmlyc3RfY2hhcmFjdGVyID09ICd7JyAmJiAkbGFzdF9jaGFyYWN0ZXIgPT0gJ30nKSB7CiAgICAgICRpbm5lclZhbHVlID0gdHJpbShzdWJzdHIgKCR2YWx1ZSwgMSwgLTEpKTsKICAgICAgaWYgKCRpbm5lclZhbHVlID09PSAnJykgcmV0dXJuIGFycmF5KCk7CiAgICAgIC8vIElubGluZSBNYXBwaW5nCiAgICAgIC8vIFRha2Ugb3V0IHN0cmluZ3Mgc2VxdWVuY2VzIGFuZCBtYXBwaW5ncwogICAgICAkZXhwbG9kZSA9ICR0aGlzLT5faW5saW5lRXNjYXBlKCRpbm5lclZhbHVlKTsKICAgICAgLy8gUHJvcGFnYXRlIHZhbHVlIGFycmF5CiAgICAgICRhcnJheSA9IGFycmF5KCk7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICR2KSB7CiAgICAgICAgJFN1YkFyciA9ICR0aGlzLT5fdG9UeXBlKCR2KTsKICAgICAgICBpZiAoZW1wdHkoJFN1YkFycikpIGNvbnRpbnVlOwogICAgICAgIGlmIChpc19hcnJheSAoJFN1YkFycikpIHsKICAgICAgICAgICRhcnJheVtrZXkoJFN1YkFycildID0gJFN1YkFycltrZXkoJFN1YkFycildOyBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJGFycmF5W10gPSAkU3ViQXJyOwogICAgICB9CiAgICAgIHJldHVybiAkYXJyYXk7CiAgICB9CgogICAgaWYgKCR2YWx1ZSA9PSAnbnVsbCcgfHwgJHZhbHVlID09ICdOVUxMJyB8fCAkdmFsdWUgPT0gJ051bGwnIHx8ICR2YWx1ZSA9PSAnJyB8fCAkdmFsdWUgPT0gJ34nKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIGlmICggaXNfbnVtZXJpYygkdmFsdWUpICYmIHByZWdfbWF0Y2ggKCcvXigtfClbMS05XStbMC05XSokLycsICR2YWx1ZSkgKXsKICAgICAgJGludHZhbHVlID0gKGludCkkdmFsdWU7CiAgICAgIGlmICgkaW50dmFsdWUgIT0gUEhQX0lOVF9NQVggJiYgJGludHZhbHVlICE9IH5QSFBfSU5UX01BWCkKICAgICAgICAkdmFsdWUgPSAkaW50dmFsdWU7CiAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgaWYgKCBpc19zdHJpbmcoJHZhbHVlKSAmJiBwcmVnX21hdGNoKCcvXjBbeFhdWzAtOWEtZkEtRl0rJC8nLCAkdmFsdWUpKSB7CiAgICAgIC8vIEhleGFkZWNpbWFsIHZhbHVlLgogICAgICByZXR1cm4gaGV4ZGVjKCR2YWx1ZSk7CiAgICB9CgogICAgJHRoaXMtPmNvZXJjZVZhbHVlKCR2YWx1ZSk7CgogICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSkgewogICAgICBpZiAoJHZhbHVlID09PSAnMCcpIHJldHVybiAwOwogICAgICBpZiAocnRyaW0gKCR2YWx1ZSwgMCkgPT09ICR2YWx1ZSkKICAgICAgICAkdmFsdWUgPSAoZmxvYXQpJHZhbHVlOwogICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIHJldHVybiAkdmFsdWU7CiAgfQoKICAvKioKICAgICAqIFVzZWQgaW4gaW5saW5lcyB0byBjaGVjayBmb3IgbW9yZSBpbmxpbmVzIG9yIHF1b3RlZCBzdHJpbmdzCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX2lubGluZUVzY2FwZSgkaW5saW5lKSB7CiAgICAvLyBUaGVyZSdzIGdvdHRhIGJlIGEgY2xlYW5lciB3YXkgdG8gZG8gdGhpcy4uLgogICAgLy8gV2hpbGUgcHVyZSBzZXF1ZW5jZXMgc2VlbSB0byBiZSBuZXN0aW5nIGp1c3QgZmluZSwKICAgIC8vIHB1cmUgbWFwcGluZ3MgYW5kIG1hcHBpbmdzIHdpdGggc2VxdWVuY2VzIGluc2lkZSBjYW4ndCBnbyB2ZXJ5CiAgICAvLyBkZWVwLiAgVGhpcyBuZWVkcyB0byBiZSBmaXhlZC4KCiAgICAkc2VxcyA9IGFycmF5KCk7CiAgICAkbWFwcyA9IGFycmF5KCk7CiAgICAkc2F2ZWRfc3RyaW5ncyA9IGFycmF5KCk7CiAgICAkc2F2ZWRfZW1wdGllcyA9IGFycmF5KCk7CgogICAgLy8gQ2hlY2sgZm9yIGVtcHR5IHN0cmluZ3MKICAgICRyZWdleCA9ICcvKCIiKXwoXCdcJykvJzsKICAgIGlmIChwcmVnX21hdGNoX2FsbCgkcmVnZXgsJGlubGluZSwkc3RyaW5ncykpIHsKICAgICAgJHNhdmVkX2VtcHRpZXMgPSAkc3RyaW5nc1swXTsKICAgICAgJGlubGluZSAgPSBwcmVnX3JlcGxhY2UoJHJlZ2V4LCdZQU1MRW1wdHknLCRpbmxpbmUpOwogICAgfQogICAgdW5zZXQoJHJlZ2V4KTsKCiAgICAvLyBDaGVjayBmb3Igc3RyaW5ncwogICAgJHJlZ2V4ID0gJy8oPzooIil8KD86XCcpKSgoPygxKVteIl0rfFteXCddKykpKD8oMSkifFwnKS8nOwogICAgaWYgKHByZWdfbWF0Y2hfYWxsKCRyZWdleCwkaW5saW5lLCRzdHJpbmdzKSkgewogICAgICAkc2F2ZWRfc3RyaW5ncyA9ICRzdHJpbmdzWzBdOwogICAgICAkaW5saW5lICA9IHByZWdfcmVwbGFjZSgkcmVnZXgsJ1lBTUxTdHJpbmcnLCRpbmxpbmUpOwogICAgfQogICAgdW5zZXQoJHJlZ2V4KTsKCiAgICAvLyBlY2hvICRpbmxpbmU7CgogICAgJGkgPSAwOwogICAgZG8gewoKICAgIC8vIENoZWNrIGZvciBzZXF1ZW5jZXMKICAgIHdoaWxlIChwcmVnX21hdGNoKCcvXFsoW157fVxbXF1dKylcXS9VJywkaW5saW5lLCRtYXRjaHNlcXMpKSB7CiAgICAgICRzZXFzW10gPSAkbWF0Y2hzZXFzWzBdOwogICAgICAkaW5saW5lID0gcHJlZ19yZXBsYWNlKCcvXFsoW157fVxbXF1dKylcXS9VJywgKCdZQU1MU2VxJyAuIChjb3VudCgkc2VxcykgLSAxKSAuICdzJyksICRpbmxpbmUsIDEpOwogICAgfQoKICAgIC8vIENoZWNrIGZvciBtYXBwaW5ncwogICAgd2hpbGUgKHByZWdfbWF0Y2goJy97KFteXFtcXXt9XSspfS9VJywkaW5saW5lLCRtYXRjaG1hcHMpKSB7CiAgICAgICRtYXBzW10gPSAkbWF0Y2htYXBzWzBdOwogICAgICAkaW5saW5lID0gcHJlZ19yZXBsYWNlKCcveyhbXlxbXF17fV0rKX0vVScsICgnWUFNTE1hcCcgLiAoY291bnQoJG1hcHMpIC0gMSkgLiAncycpLCAkaW5saW5lLCAxKTsKICAgIH0KCiAgICBpZiAoJGkrKyA+PSAxMCkgYnJlYWs7CgogICAgfSB3aGlsZSAoc3RycG9zICgkaW5saW5lLCAnWycpICE9PSBmYWxzZSB8fCBzdHJwb3MgKCRpbmxpbmUsICd7JykgIT09IGZhbHNlKTsKCiAgICAkZXhwbG9kZSA9IGV4cGxvZGUoJywnLCRpbmxpbmUpOwogICAgJGV4cGxvZGUgPSBhcnJheV9tYXAoJ3RyaW0nLCAkZXhwbG9kZSk7CiAgICAkc3RyaW5naSA9IDA7ICRpID0gMDsKCiAgICB3aGlsZSAoMSkgewoKICAgIC8vIFJlLWFkZCB0aGUgc2VxdWVuY2VzCiAgICBpZiAoIWVtcHR5KCRzZXFzKSkgewogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MU2VxJykgIT09IGZhbHNlKSB7CiAgICAgICAgICBmb3JlYWNoICgkc2VxcyBhcyAkc2VxayA9PiAkc2VxKSB7CiAgICAgICAgICAgICRleHBsb2RlWyRrZXldID0gc3RyX3JlcGxhY2UoKCdZQU1MU2VxJy4kc2Vxay4ncycpLCRzZXEsJHZhbHVlKTsKICAgICAgICAgICAgJHZhbHVlID0gJGV4cGxvZGVbJGtleV07CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLy8gUmUtYWRkIHRoZSBtYXBwaW5ncwogICAgaWYgKCFlbXB0eSgkbWFwcykpIHsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICBpZiAoc3RycG9zKCR2YWx1ZSwnWUFNTE1hcCcpICE9PSBmYWxzZSkgewogICAgICAgICAgZm9yZWFjaCAoJG1hcHMgYXMgJG1hcGsgPT4gJG1hcCkgewogICAgICAgICAgICAkZXhwbG9kZVska2V5XSA9IHN0cl9yZXBsYWNlKCgnWUFNTE1hcCcuJG1hcGsuJ3MnKSwgJG1hcCwgJHZhbHVlKTsKICAgICAgICAgICAgJHZhbHVlID0gJGV4cGxvZGVbJGtleV07CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgoKICAgIC8vIFJlLWFkZCB0aGUgc3RyaW5ncwogICAgaWYgKCFlbXB0eSgkc2F2ZWRfc3RyaW5ncykpIHsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICB3aGlsZSAoc3RycG9zKCR2YWx1ZSwnWUFNTFN0cmluZycpICE9PSBmYWxzZSkgewogICAgICAgICAgJGV4cGxvZGVbJGtleV0gPSBwcmVnX3JlcGxhY2UoJy9ZQU1MU3RyaW5nLycsJHNhdmVkX3N0cmluZ3NbJHN0cmluZ2ldLCR2YWx1ZSwgMSk7CiAgICAgICAgICB1bnNldCgkc2F2ZWRfc3RyaW5nc1skc3RyaW5naV0pOwogICAgICAgICAgKyskc3RyaW5naTsKICAgICAgICAgICR2YWx1ZSA9ICRleHBsb2RlWyRrZXldOwogICAgICAgIH0KICAgICAgfQogICAgfQoKCiAgICAvLyBSZS1hZGQgdGhlIGVtcHRpZXMKICAgIGlmICghZW1wdHkoJHNhdmVkX2VtcHRpZXMpKSB7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgd2hpbGUgKHN0cnBvcygkdmFsdWUsJ1lBTUxFbXB0eScpICE9PSBmYWxzZSkgewogICAgICAgICAgJGV4cGxvZGVbJGtleV0gPSBwcmVnX3JlcGxhY2UoJy9ZQU1MRW1wdHkvJywgJycsICR2YWx1ZSwgMSk7CiAgICAgICAgICAkdmFsdWUgPSAkZXhwbG9kZVska2V5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAkZmluaXNoZWQgPSB0cnVlOwogICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgaWYgKHN0cnBvcygkdmFsdWUsJ1lBTUxTZXEnKSAhPT0gZmFsc2UpIHsKICAgICAgICAkZmluaXNoZWQgPSBmYWxzZTsgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKHN0cnBvcygkdmFsdWUsJ1lBTUxNYXAnKSAhPT0gZmFsc2UpIHsKICAgICAgICAkZmluaXNoZWQgPSBmYWxzZTsgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKHN0cnBvcygkdmFsdWUsJ1lBTUxTdHJpbmcnKSAhPT0gZmFsc2UpIHsKICAgICAgICAkZmluaXNoZWQgPSBmYWxzZTsgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKHN0cnBvcygkdmFsdWUsJ1lBTUxFbXB0eScpICE9PSBmYWxzZSkgewogICAgICAgICRmaW5pc2hlZCA9IGZhbHNlOyBicmVhazsKICAgICAgfQogICAgfQogICAgaWYgKCRmaW5pc2hlZCkgYnJlYWs7CgogICAgJGkrKzsKICAgIGlmICgkaSA+IDEwKQogICAgICBicmVhazsgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wcy4KICAgIH0KCgogICAgcmV0dXJuICRleHBsb2RlOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBsaXRlcmFsQmxvY2tDb250aW51ZXMgKCRsaW5lLCAkbGluZUluZGVudCkgewogICAgaWYgKCF0cmltKCRsaW5lKSkgcmV0dXJuIHRydWU7CiAgICBpZiAoc3RybGVuKCRsaW5lKSAtIHN0cmxlbihsdHJpbSgkbGluZSkpID4gJGxpbmVJbmRlbnQpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiByZWZlcmVuY2VDb250ZW50c0J5QWxpYXMgKCRhbGlhcykgewogICAgZG8gewogICAgICBpZiAoIWlzc2V0KCR0aGlzLT5TYXZlZEdyb3Vwc1skYWxpYXNdKSkgeyBlY2hvICJCYWQgZ3JvdXAgbmFtZTogJGFsaWFzLiI7IGJyZWFrOyB9CiAgICAgICRncm91cFBhdGggPSAkdGhpcy0+U2F2ZWRHcm91cHNbJGFsaWFzXTsKICAgICAgJHZhbHVlID0gJHRoaXMtPnJlc3VsdDsKICAgICAgZm9yZWFjaCAoJGdyb3VwUGF0aCBhcyAkaykgewogICAgICAgICR2YWx1ZSA9ICR2YWx1ZVska107CiAgICAgIH0KICAgIH0gd2hpbGUgKGZhbHNlKTsKICAgIHJldHVybiAkdmFsdWU7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGFkZEFycmF5SW5saW5lICgkYXJyYXksICRpbmRlbnQpIHsKICAgICAgJENvbW1vbkdyb3VwUGF0aCA9ICR0aGlzLT5wYXRoOwogICAgICBpZiAoZW1wdHkgKCRhcnJheSkpIHJldHVybiBmYWxzZTsKCiAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAkayA9PiAkXykgewogICAgICAgICR0aGlzLT5hZGRBcnJheShhcnJheSgkayA9PiAkXyksICRpbmRlbnQpOwogICAgICAgICR0aGlzLT5wYXRoID0gJENvbW1vbkdyb3VwUGF0aDsKICAgICAgfQogICAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gYWRkQXJyYXkgKCRpbmNvbWluZ19kYXRhLCAkaW5jb21pbmdfaW5kZW50KSB7CgogICAvLyBwcmludF9yICgkaW5jb21pbmdfZGF0YSk7CgogICAgaWYgKGNvdW50ICgkaW5jb21pbmdfZGF0YSkgPiAxKQogICAgICByZXR1cm4gJHRoaXMtPmFkZEFycmF5SW5saW5lICgkaW5jb21pbmdfZGF0YSwgJGluY29taW5nX2luZGVudCk7CgogICAgJGtleSA9IGtleSAoJGluY29taW5nX2RhdGEpOwogICAgJHZhbHVlID0gaXNzZXQoJGluY29taW5nX2RhdGFbJGtleV0pID8gJGluY29taW5nX2RhdGFbJGtleV0gOiBudWxsOwogICAgaWYgKCRrZXkgPT09ICdfXyFZQU1MWmVybycpICRrZXkgPSAnMCc7CgogICAgaWYgKCRpbmNvbWluZ19pbmRlbnQgPT0gMCAmJiAhJHRoaXMtPl9jb250YWluc0dyb3VwQWxpYXMgJiYgISR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvcikgeyAvLyBTaG9ydGN1dCBmb3Igcm9vdC1sZXZlbCB2YWx1ZXMuCiAgICAgIGlmICgka2V5IHx8ICRrZXkgPT09ICcnIHx8ICRrZXkgPT09ICcwJykgewogICAgICAgICR0aGlzLT5yZXN1bHRbJGtleV0gPSAkdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgJHRoaXMtPnJlc3VsdFtdID0gJHZhbHVlOyBlbmQgKCR0aGlzLT5yZXN1bHQpOyAka2V5ID0ga2V5ICgkdGhpcy0+cmVzdWx0KTsKICAgICAgfQogICAgICAkdGhpcy0+cGF0aFskaW5jb21pbmdfaW5kZW50XSA9ICRrZXk7CiAgICAgIHJldHVybjsKICAgIH0KCgoKICAgICRoaXN0b3J5ID0gYXJyYXkoKTsKICAgIC8vIFVuZm9sZGluZyBpbm5lciBhcnJheSB0cmVlLgogICAgJGhpc3RvcnlbXSA9ICRfYXJyID0gJHRoaXMtPnJlc3VsdDsKICAgIGZvcmVhY2ggKCR0aGlzLT5wYXRoIGFzICRrKSB7CiAgICAgICRoaXN0b3J5W10gPSAkX2FyciA9ICRfYXJyWyRrXTsKICAgIH0KCiAgICBpZiAoJHRoaXMtPl9jb250YWluc0dyb3VwQWxpYXMpIHsKICAgICAgJHZhbHVlID0gJHRoaXMtPnJlZmVyZW5jZUNvbnRlbnRzQnlBbGlhcygkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbGlhcyk7CiAgICAgICR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzID0gZmFsc2U7CiAgICB9CgoKICAgIC8vIEFkZGluZyBzdHJpbmcgb3IgbnVtZXJpYyBrZXkgdG8gdGhlIGlubmVybW9zdCBsZXZlbCBvciAkdGhpcy0+YXJyLgogICAgaWYgKGlzX3N0cmluZygka2V5KSAmJiAka2V5ID09ICc8PCcpIHsKICAgICAgaWYgKCFpc19hcnJheSAoJF9hcnIpKSB7ICRfYXJyID0gYXJyYXkgKCk7IH0KCiAgICAgICRfYXJyID0gYXJyYXlfbWVyZ2UgKCRfYXJyLCAkdmFsdWUpOwogICAgfSBlbHNlIGlmICgka2V5IHx8ICRrZXkgPT09ICcnIHx8ICRrZXkgPT09ICcwJykgewogICAgICBpZiAoIWlzX2FycmF5ICgkX2FycikpCiAgICAgICAgJF9hcnIgPSBhcnJheSAoJGtleT0+JHZhbHVlKTsKICAgICAgZWxzZQogICAgICAgICRfYXJyWyRrZXldID0gJHZhbHVlOwogICAgfSBlbHNlIHsKICAgICAgaWYgKCFpc19hcnJheSAoJF9hcnIpKSB7ICRfYXJyID0gYXJyYXkgKCR2YWx1ZSk7ICRrZXkgPSAwOyB9CiAgICAgIGVsc2UgeyAkX2FycltdID0gJHZhbHVlOyBlbmQgKCRfYXJyKTsgJGtleSA9IGtleSAoJF9hcnIpOyB9CiAgICB9CgogICAgJHJldmVyc2VfcGF0aCA9IGFycmF5X3JldmVyc2UoJHRoaXMtPnBhdGgpOwogICAgJHJldmVyc2VfaGlzdG9yeSA9IGFycmF5X3JldmVyc2UgKCRoaXN0b3J5KTsKICAgICRyZXZlcnNlX2hpc3RvcnlbMF0gPSAkX2FycjsKICAgICRjbnQgPSBjb3VudCgkcmV2ZXJzZV9oaXN0b3J5KSAtIDE7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkY250OyAkaSsrKSB7CiAgICAgICRyZXZlcnNlX2hpc3RvcnlbJGkrMV1bJHJldmVyc2VfcGF0aFskaV1dID0gJHJldmVyc2VfaGlzdG9yeVskaV07CiAgICB9CiAgICAkdGhpcy0+cmVzdWx0ID0gJHJldmVyc2VfaGlzdG9yeVskY250XTsKCiAgICAkdGhpcy0+cGF0aFskaW5jb21pbmdfaW5kZW50XSA9ICRrZXk7CgogICAgaWYgKCR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvcikgewogICAgICAkdGhpcy0+U2F2ZWRHcm91cHNbJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yXSA9ICR0aGlzLT5wYXRoOwogICAgICBpZiAoaXNfYXJyYXkgKCR2YWx1ZSkpIHsKICAgICAgICAkayA9IGtleSAoJHZhbHVlKTsKICAgICAgICBpZiAoIWlzX2ludCAoJGspKSB7CiAgICAgICAgICAkdGhpcy0+U2F2ZWRHcm91cHNbJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yXVskaW5jb21pbmdfaW5kZW50ICsgMl0gPSAkazsKICAgICAgICB9CiAgICAgIH0KICAgICAgJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yID0gZmFsc2U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc3RhcnRzTGl0ZXJhbEJsb2NrICgkbGluZSkgewogICAgJGxhc3RDaGFyID0gc3Vic3RyICh0cmltKCRsaW5lKSwgLTEpOwogICAgaWYgKCRsYXN0Q2hhciAhPSAnPicgJiYgJGxhc3RDaGFyICE9ICd8JykgcmV0dXJuIGZhbHNlOwogICAgaWYgKCRsYXN0Q2hhciA9PSAnfCcpIHJldHVybiAkbGFzdENoYXI7CiAgICAvLyBIVE1MIHRhZ3Mgc2hvdWxkIG5vdCBiZSBjb3VudGVkIGFzIGxpdGVyYWwgYmxvY2tzLgogICAgaWYgKHByZWdfbWF0Y2ggKCcjPC4qPz4kIycsICRsaW5lKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuICRsYXN0Q2hhcjsKICB9CgogIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdyZWVkaWx5TmVlZE5leHRMaW5lKCRsaW5lKSB7CiAgICAkbGluZSA9IHRyaW0gKCRsaW5lKTsKICAgIGlmICghc3RybGVuKCRsaW5lKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKHN1YnN0ciAoJGxpbmUsIC0xLCAxKSA9PSAnXScpIHJldHVybiBmYWxzZTsKICAgIGlmICgkbGluZVswXSA9PSAnWycpIHJldHVybiB0cnVlOwogICAgaWYgKHByZWdfbWF0Y2ggKCcjXlteOl0rPzpccypcWyMnLCAkbGluZSkpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRMaXRlcmFsTGluZSAoJGxpdGVyYWxCbG9jaywgJGxpbmUsICRsaXRlcmFsQmxvY2tTdHlsZSwgJGluZGVudCA9IC0xKSB7CiAgICAkbGluZSA9IHNlbGY6OnN0cmlwSW5kZW50KCRsaW5lLCAkaW5kZW50KTsKICAgIGlmICgkbGl0ZXJhbEJsb2NrU3R5bGUgIT09ICd8JykgewogICAgICAgICRsaW5lID0gc2VsZjo6c3RyaXBJbmRlbnQoJGxpbmUpOwogICAgfQogICAgJGxpbmUgPSBydHJpbSAoJGxpbmUsICJcclxuXHQgIikgLiAiXG4iOwogICAgaWYgKCRsaXRlcmFsQmxvY2tTdHlsZSA9PSAnfCcpIHsKICAgICAgcmV0dXJuICRsaXRlcmFsQmxvY2sgLiAkbGluZTsKICAgIH0KICAgIGlmIChzdHJsZW4oJGxpbmUpID09IDApCiAgICAgIHJldHVybiBydHJpbSgkbGl0ZXJhbEJsb2NrLCAnICcpIC4gIlxuIjsKICAgIGlmICgkbGluZSA9PSAiXG4iICYmICRsaXRlcmFsQmxvY2tTdHlsZSA9PSAnPicpIHsKICAgICAgcmV0dXJuIHJ0cmltICgkbGl0ZXJhbEJsb2NrLCAiIFx0IikgLiAiXG4iOwogICAgfQogICAgaWYgKCRsaW5lICE9ICJcbiIpCiAgICAgICRsaW5lID0gdHJpbSAoJGxpbmUsICJcclxuICIpIC4gIiAiOwogICAgcmV0dXJuICRsaXRlcmFsQmxvY2sgLiAkbGluZTsKICB9CgogICBmdW5jdGlvbiByZXZlcnRMaXRlcmFsUGxhY2VIb2xkZXIgKCRsaW5lQXJyYXksICRsaXRlcmFsQmxvY2spIHsKICAgICBmb3JlYWNoICgkbGluZUFycmF5IGFzICRrID0+ICRfKSB7CiAgICAgIGlmIChpc19hcnJheSgkXykpCiAgICAgICAgJGxpbmVBcnJheVska10gPSAkdGhpcy0+cmV2ZXJ0TGl0ZXJhbFBsYWNlSG9sZGVyICgkXywgJGxpdGVyYWxCbG9jayk7CiAgICAgIGVsc2UgaWYgKHN1YnN0cigkXywgLTEgKiBzdHJsZW4gKCR0aGlzLT5MaXRlcmFsUGxhY2VIb2xkZXIpKSA9PSAkdGhpcy0+TGl0ZXJhbFBsYWNlSG9sZGVyKQoJICAgICAgICRsaW5lQXJyYXlbJGtdID0gcnRyaW0gKCRsaXRlcmFsQmxvY2ssICIgXHJcbiIpOwogICAgIH0KICAgICByZXR1cm4gJGxpbmVBcnJheTsKICAgfQoKICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzdHJpcEluZGVudCAoJGxpbmUsICRpbmRlbnQgPSAtMSkgewogICAgaWYgKCRpbmRlbnQgPT0gLTEpICRpbmRlbnQgPSBzdHJsZW4oJGxpbmUpIC0gc3RybGVuKGx0cmltKCRsaW5lKSk7CiAgICByZXR1cm4gc3Vic3RyICgkbGluZSwgJGluZGVudCk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGdldFBhcmVudFBhdGhCeUluZGVudCAoJGluZGVudCkgewogICAgaWYgKCRpbmRlbnQgPT0gMCkgcmV0dXJuIGFycmF5KCk7CiAgICAkbGluZVBhdGggPSAkdGhpcy0+cGF0aDsKICAgIGRvIHsKICAgICAgZW5kKCRsaW5lUGF0aCk7ICRsYXN0SW5kZW50SW5QYXJlbnRQYXRoID0ga2V5KCRsaW5lUGF0aCk7CiAgICAgIGlmICgkaW5kZW50IDw9ICRsYXN0SW5kZW50SW5QYXJlbnRQYXRoKSBhcnJheV9wb3AgKCRsaW5lUGF0aCk7CiAgICB9IHdoaWxlICgkaW5kZW50IDw9ICRsYXN0SW5kZW50SW5QYXJlbnRQYXRoKTsKICAgIHJldHVybiAkbGluZVBhdGg7CiAgfQoKCiAgcHJpdmF0ZSBmdW5jdGlvbiBjbGVhckJpZ2dlclBhdGhWYWx1ZXMgKCRpbmRlbnQpIHsKCgogICAgaWYgKCRpbmRlbnQgPT0gMCkgJHRoaXMtPnBhdGggPSBhcnJheSgpOwogICAgaWYgKGVtcHR5ICgkdGhpcy0+cGF0aCkpIHJldHVybiB0cnVlOwoKICAgIGZvcmVhY2ggKCR0aGlzLT5wYXRoIGFzICRrID0+ICRfKSB7CiAgICAgIGlmICgkayA+ICRpbmRlbnQpIHVuc2V0ICgkdGhpcy0+cGF0aFska10pOwogICAgfQoKICAgIHJldHVybiB0cnVlOwogIH0KCgogIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzQ29tbWVudCAoJGxpbmUpIHsKICAgIGlmICghJGxpbmUpIHJldHVybiBmYWxzZTsKICAgIGlmICgkbGluZVswXSA9PSAnIycpIHJldHVybiB0cnVlOwogICAgaWYgKHRyaW0oJGxpbmUsICIgXHJcblx0IikgPT0gJy0tLScpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaXNFbXB0eSAoJGxpbmUpIHsKICAgIHJldHVybiAodHJpbSAoJGxpbmUpID09PSAnJyk7CiAgfQoKCiAgcHJpdmF0ZSBmdW5jdGlvbiBpc0FycmF5RWxlbWVudCAoJGxpbmUpIHsKICAgIGlmICghJGxpbmUgfHwgIWlzX3NjYWxhcigkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIGlmIChzdWJzdHIoJGxpbmUsIDAsIDIpICE9ICctICcpIHJldHVybiBmYWxzZTsKICAgIGlmIChzdHJsZW4gKCRsaW5lKSA+IDMpCiAgICAgIGlmIChzdWJzdHIoJGxpbmUsMCwzKSA9PSAnLS0tJykgcmV0dXJuIGZhbHNlOwoKICAgIHJldHVybiB0cnVlOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBpc0hhc2hFbGVtZW50ICgkbGluZSkgewogICAgcmV0dXJuIHN0cnBvcygkbGluZSwgJzonKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gaXNMaXRlcmFsICgkbGluZSkgewogICAgaWYgKCR0aGlzLT5pc0FycmF5RWxlbWVudCgkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIGlmICgkdGhpcy0+aXNIYXNoRWxlbWVudCgkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCgogIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHVucXVvdGUgKCR2YWx1ZSkgewogICAgaWYgKCEkdmFsdWUpIHJldHVybiAkdmFsdWU7CiAgICBpZiAoIWlzX3N0cmluZygkdmFsdWUpKSByZXR1cm4gJHZhbHVlOwogICAgaWYgKCR2YWx1ZVswXSA9PSAnXCcnKSByZXR1cm4gdHJpbSAoJHZhbHVlLCAnXCcnKTsKICAgIGlmICgkdmFsdWVbMF0gPT0gJyInKSByZXR1cm4gdHJpbSAoJHZhbHVlLCAnIicpOwogICAgcmV0dXJuICR2YWx1ZTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gc3RhcnRzTWFwcGVkU2VxdWVuY2UgKCRsaW5lKSB7CiAgICByZXR1cm4gKHN1YnN0cigkbGluZSwgMCwgMikgPT0gJy0gJyAmJiBzdWJzdHIgKCRsaW5lLCAtMSwgMSkgPT0gJzonKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gcmV0dXJuTWFwcGVkU2VxdWVuY2UgKCRsaW5lKSB7CiAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgJGtleSAgICAgICAgID0gc2VsZjo6dW5xdW90ZSh0cmltKHN1YnN0cigkbGluZSwxLC0xKSkpOwogICAgJGFycmF5WyRrZXldID0gYXJyYXkoKTsKICAgICR0aGlzLT5kZWxheWVkUGF0aCA9IGFycmF5KHN0cnBvcyAoJGxpbmUsICRrZXkpICsgJHRoaXMtPmluZGVudCA9PiAka2V5KTsKICAgIHJldHVybiBhcnJheSgkYXJyYXkpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0tleXNJblZhbHVlKCR2YWx1ZSkgewogICAgaWYgKHN0cmNocignW3siXCcnLCAkdmFsdWVbMF0pID09PSBmYWxzZSkgewogICAgICBpZiAoc3RyY2hyKCR2YWx1ZSwgJzogJykgIT09IGZhbHNlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbignVG9vIG1hbnkga2V5czogJy4kdmFsdWUpOwogICAgICB9CiAgICB9CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIHJldHVybk1hcHBlZFZhbHVlICgkbGluZSkgewogICAgJHRoaXMtPmNoZWNrS2V5c0luVmFsdWUoJGxpbmUpOwogICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICRrZXkgICAgICAgICA9IHNlbGY6OnVucXVvdGUgKHRyaW0oc3Vic3RyKCRsaW5lLDAsLTEpKSk7CiAgICAkYXJyYXlbJGtleV0gPSAnJzsKICAgIHJldHVybiAkYXJyYXk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0c01hcHBlZFZhbHVlICgkbGluZSkgewogICAgcmV0dXJuIChzdWJzdHIgKCRsaW5lLCAtMSwgMSkgPT0gJzonKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gaXNQbGFpbkFycmF5ICgkbGluZSkgewogICAgcmV0dXJuICgkbGluZVswXSA9PSAnWycgJiYgc3Vic3RyICgkbGluZSwgLTEsIDEpID09ICddJyk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIHJldHVyblBsYWluQXJyYXkgKCRsaW5lKSB7CiAgICByZXR1cm4gJHRoaXMtPl90b1R5cGUoJGxpbmUpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiByZXR1cm5LZXlWYWx1ZVBhaXIgKCRsaW5lKSB7CiAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgJGtleSA9ICcnOwogICAgaWYgKHN0cnBvcyAoJGxpbmUsICc6ICcpKSB7CiAgICAgIC8vIEl0J3MgYSBrZXkvdmFsdWUgcGFpciBtb3N0IGxpa2VseQogICAgICAvLyBJZiB0aGUga2V5IGlzIGluIGRvdWJsZSBxdW90ZXMgcHVsbCBpdCBvdXQKICAgICAgaWYgKCgkbGluZVswXSA9PSAnIicgfHwgJGxpbmVbMF0gPT0gIiciKSAmJiBwcmVnX21hdGNoKCcvXihbIlwnXSguKilbIlwnXShccykqOikvJywkbGluZSwkbWF0Y2hlcykpIHsKICAgICAgICAkdmFsdWUgPSB0cmltKHN0cl9yZXBsYWNlKCRtYXRjaGVzWzFdLCcnLCRsaW5lKSk7CiAgICAgICAgJGtleSAgID0gJG1hdGNoZXNbMl07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gRG8gc29tZSBndWVzc3dvcmsgYXMgdG8gdGhlIGtleSBhbmQgdGhlIHZhbHVlCiAgICAgICAgJGV4cGxvZGUgPSBleHBsb2RlKCc6ICcsICRsaW5lKTsKICAgICAgICAka2V5ICAgICA9IHRyaW0oYXJyYXlfc2hpZnQoJGV4cGxvZGUpKTsKICAgICAgICAkdmFsdWUgICA9IHRyaW0oaW1wbG9kZSgnOiAnLCAkZXhwbG9kZSkpOwogICAgICAgICR0aGlzLT5jaGVja0tleXNJblZhbHVlKCR2YWx1ZSk7CiAgICAgIH0KICAgICAgLy8gU2V0IHRoZSB0eXBlIG9mIHRoZSB2YWx1ZS4gIEludCwgc3RyaW5nLCBldGMKICAgICAgJHZhbHVlID0gJHRoaXMtPl90b1R5cGUoJHZhbHVlKTsKICAgICAgaWYgKCRrZXkgPT09ICcwJykgJGtleSA9ICdfXyFZQU1MWmVybyc7CiAgICAgICRhcnJheVska2V5XSA9ICR2YWx1ZTsKICAgIH0gZWxzZSB7CiAgICAgICRhcnJheSA9IGFycmF5ICgkbGluZSk7CiAgICB9CiAgICByZXR1cm4gJGFycmF5OwoKICB9CgoKICBwcml2YXRlIGZ1bmN0aW9uIHJldHVybkFycmF5RWxlbWVudCAoJGxpbmUpIHsKICAgICBpZiAoc3RybGVuKCRsaW5lKSA8PSAxKSByZXR1cm4gYXJyYXkoYXJyYXkoKSk7IC8vIFdlaXJkICUpCiAgICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICAkdmFsdWUgICA9IHRyaW0oc3Vic3RyKCRsaW5lLDEpKTsKICAgICAkdmFsdWUgICA9ICR0aGlzLT5fdG9UeXBlKCR2YWx1ZSk7CiAgICAgaWYgKCR0aGlzLT5pc0FycmF5RWxlbWVudCgkdmFsdWUpKSB7CiAgICAgICAkdmFsdWUgPSAkdGhpcy0+cmV0dXJuQXJyYXlFbGVtZW50KCR2YWx1ZSk7CiAgICAgfQogICAgICRhcnJheVtdID0gJHZhbHVlOwogICAgIHJldHVybiAkYXJyYXk7CiAgfQoKCiAgcHJpdmF0ZSBmdW5jdGlvbiBub2RlQ29udGFpbnNHcm91cCAoJGxpbmUpIHsKICAgICRzeW1ib2xzRm9yUmVmZXJlbmNlID0gJ0EtejAtOV9cLSc7CiAgICBpZiAoc3RycG9zKCRsaW5lLCAnJicpID09PSBmYWxzZSAmJiBzdHJwb3MoJGxpbmUsICcqJykgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7IC8vIFBsZWFzZSBkaWUgZmFzdCA7LSkKICAgIGlmICgkbGluZVswXSA9PSAnJicgJiYgcHJlZ19tYXRjaCgnL14oJlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKykvJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgaWYgKCRsaW5lWzBdID09ICcqJyAmJiBwcmVnX21hdGNoKCcvXihcKlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKykvJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgaWYgKHByZWdfbWF0Y2goJy8oJlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKykkLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmIChwcmVnX21hdGNoKCcvKFwqWycuJHN5bWJvbHNGb3JSZWZlcmVuY2UuJ10rJCkvJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgaWYgKHByZWdfbWF0Y2ggKCcjXlxzKjw8XHMqOlxzKihcKlteXHNdKykuKiQjJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgcmV0dXJuIGZhbHNlOwoKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gYWRkR3JvdXAgKCRsaW5lLCAkZ3JvdXApIHsKICAgIGlmICgkZ3JvdXBbMF0gPT0gJyYnKSAkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3IgPSBzdWJzdHIgKCRncm91cCwgMSk7CiAgICBpZiAoJGdyb3VwWzBdID09ICcqJykgJHRoaXMtPl9jb250YWluc0dyb3VwQWxpYXMgPSBzdWJzdHIgKCRncm91cCwgMSk7CiAgICAvL3ByaW50X3IgKCR0aGlzLT5wYXRoKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gc3RyaXBHcm91cCAoJGxpbmUsICRncm91cCkgewogICAgJGxpbmUgPSB0cmltKHN0cl9yZXBsYWNlKCRncm91cCwgJycsICRsaW5lKSk7CiAgICByZXR1cm4gJGxpbmU7CiAgfQp9Cjw/cGhwCi8qKgogICAqIFNweWMgLS0gQSBTaW1wbGUgUEhQIFlBTUwgQ2xhc3MKICAgKiBAdmVyc2lvbiAwLjYuMgogICAqIEBhdXRob3IgVmxhZCBBbmRlcnNlbiA8dmxhZC5hbmRlcnNlbkBnbWFpbC5jb20+CiAgICogQGF1dGhvciBDaHJpcyBXYW5zdHJhdGggPGNocmlzQG96bW0ub3JnPgogICAqIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9tdXN0YW5nb3N0YW5nL3NweWMvCiAgICogQGNvcHlyaWdodCBDb3B5cmlnaHQgMjAwNS0yMDA2IENocmlzIFdhbnN0cmF0aCwgMjAwNi0yMDExIFZsYWQgQW5kZXJzZW4KICAgKiBAbGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBNSVQgTGljZW5zZQogICAqIEBwYWNrYWdlIFNweWMKICAgKi8KCmlmICghY2xhc3NfZXhpc3RzKCdNdXN0YW5nb3N0YW5nXFNweWMnKSkgewogIHJlcXVpcmVfb25jZSBkaXJuYW1lKF9fRklMRV9fKSAuICcvc3JjL1NweWMucGhwJzsKfQoKY2xhc3NfYWxpYXMoJ011c3Rhbmdvc3RhbmdcU3B5YycsICdTcHljJyk7CgpyZXF1aXJlX29uY2UgZGlybmFtZShfX0ZJTEVfXykgLiAnL2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAnOwoKLy8gRW5hYmxlIHVzZSBvZiBTcHljIGZyb20gY29tbWFuZCBsaW5lCi8vIFRoZSBzeW50YXggaXMgdGhlIGZvbGxvd2luZzogcGhwIFNweWMucGhwIHNweWMueWFtbApkbyB7CiAgaWYgKFBIUF9TQVBJICE9ICdjbGknKSBicmVhazsKICBpZiAoZW1wdHkgKCRfU0VSVkVSWydhcmdjJ10pIHx8ICRfU0VSVkVSWydhcmdjJ10gPCAyKSBicmVhazsKICBpZiAoZW1wdHkgKCRfU0VSVkVSWydQSFBfU0VMRiddKSB8fCBGQUxTRSA9PT0gc3RycG9zICgkX1NFUlZFUlsnUEhQX1NFTEYnXSwgJ1NweWMucGhwJykgKSBicmVhazsKICAkZmlsZSA9ICRhcmd2WzFdOwogIGVjaG8ganNvbl9lbmNvZGUgKHNweWNfbG9hZF9maWxlICgkZmlsZSkpOwp9IHdoaWxlICgwKTsKPD9waHAKLyoqCiAgICogU3B5YyAtLSBBIFNpbXBsZSBQSFAgWUFNTCBDbGFzcwogICAqIEB2ZXJzaW9uIDAuNi4yCiAgICogQGF1dGhvciBWbGFkIEFuZGVyc2VuIDx2bGFkLmFuZGVyc2VuQGdtYWlsLmNvbT4KICAgKiBAYXV0aG9yIENocmlzIFdhbnN0cmF0aCA8Y2hyaXNAb3ptbS5vcmc+CiAgICogQGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL211c3Rhbmdvc3Rhbmcvc3B5Yy8KICAgKiBAY29weXJpZ2h0IENvcHlyaWdodCAyMDA1LTIwMDYgQ2hyaXMgV2Fuc3RyYXRoLCAyMDA2LTIwMTEgVmxhZCBBbmRlcnNlbgogICAqIEBsaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIE1JVCBMaWNlbnNlCiAgICogQHBhY2thZ2UgU3B5YwogICAqLwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NweWNfbG9hZCcpKSB7CiAgLyoqCiAgICogUGFyc2VzIFlBTUwgdG8gYXJyYXkuCiAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFlBTUwgc3RyaW5nLgogICAqIEByZXR1cm4gYXJyYXkKICAgKi8KICBmdW5jdGlvbiBzcHljX2xvYWQgKCRzdHJpbmcpIHsKICAgIHJldHVybiBTcHljOjpZQU1MTG9hZFN0cmluZygkc3RyaW5nKTsKICB9Cn0KCmlmICghZnVuY3Rpb25fZXhpc3RzKCdzcHljX2xvYWRfZmlsZScpKSB7CiAgLyoqCiAgICogUGFyc2VzIFlBTUwgdG8gYXJyYXkuCiAgICogQHBhcmFtIHN0cmluZyAkZmlsZSBQYXRoIHRvIFlBTUwgZmlsZS4KICAgKiBAcmV0dXJuIGFycmF5CiAgICovCiAgZnVuY3Rpb24gc3B5Y19sb2FkX2ZpbGUgKCRmaWxlKSB7CiAgICByZXR1cm4gU3B5Yzo6WUFNTExvYWQoJGZpbGUpOwogIH0KfQoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NweWNfZHVtcCcpKSB7CiAgLyoqCiAgICogRHVtcHMgYXJyYXkgdG8gWUFNTC4KICAgKiBAcGFyYW0gYXJyYXkgJGRhdGEgQXJyYXkuCiAgICogQHJldHVybiBzdHJpbmcKICAgKi8KICBmdW5jdGlvbiBzcHljX2R1bXAgKCRkYXRhKSB7CiAgICByZXR1cm4gU3B5Yzo6WUFNTER1bXAoJGRhdGEsIGZhbHNlLCBmYWxzZSwgdHJ1ZSk7CiAgfQp9Cjw/cGhwCi8qKgogICAqIFNweWMgLS0gQSBTaW1wbGUgUEhQIFlBTUwgQ2xhc3MKICAgKiBAdmVyc2lvbiAwLjQuNQogICAqIEBhdXRob3IgVmxhZCBBbmRlcnNlbiA8dmxhZC5hbmRlcnNlbkBnbWFpbC5jb20+CiAgICogQGF1dGhvciBDaHJpcyBXYW5zdHJhdGggPGNocmlzQG96bW0ub3JnPgogICAqIEBsaW5rIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9zcHljLwogICAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IDIwMDUtMjAwNiBDaHJpcyBXYW5zdHJhdGgsIDIwMDYtMjAwOSBWbGFkIEFuZGVyc2VuCiAgICogQGxpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgTUlUIExpY2Vuc2UKICAgKiBAcGFja2FnZSBTcHljCiAgICovCgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnc3B5Y19sb2FkJykpIHsKICAvKioKICAgKiBQYXJzZXMgWUFNTCB0byBhcnJheS4KICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgWUFNTCBzdHJpbmcuCiAgICogQHJldHVybiBhcnJheQogICAqLwogIGZ1bmN0aW9uIHNweWNfbG9hZCAoJHN0cmluZykgewogICAgcmV0dXJuIFNweWM6OllBTUxMb2FkU3RyaW5nKCRzdHJpbmcpOwogIH0KfQoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NweWNfbG9hZF9maWxlJykpIHsKICAvKioKICAgKiBQYXJzZXMgWUFNTCB0byBhcnJheS4KICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlIFBhdGggdG8gWUFNTCBmaWxlLgogICAqIEByZXR1cm4gYXJyYXkKICAgKi8KICBmdW5jdGlvbiBzcHljX2xvYWRfZmlsZSAoJGZpbGUpIHsKICAgIHJldHVybiBTcHljOjpZQU1MTG9hZCgkZmlsZSk7CiAgfQp9CgovKioKICAgKiBUaGUgU2ltcGxlIFBIUCBZQU1MIENsYXNzLgogICAqCiAgICogVGhpcyBjbGFzcyBjYW4gYmUgdXNlZCB0byByZWFkIGEgWUFNTCBmaWxlIGFuZCBjb252ZXJ0IGl0cyBjb250ZW50cwogICAqIGludG8gYSBQSFAgYXJyYXkuICBJdCBjdXJyZW50bHkgc3VwcG9ydHMgYSB2ZXJ5IGxpbWl0ZWQgc3Vic2VjdGlvbiBvZgogICAqIHRoZSBZQU1MIHNwZWMuCiAgICoKICAgKiBVc2FnZToKICAgKiA8Y29kZT4KICAgKiAgICRTcHljICA9IG5ldyBTcHljOwogICAqICAgJGFycmF5ID0gJFNweWMtPmxvYWQoJGZpbGUpOwogICAqIDwvY29kZT4KICAgKiBvcjoKICAgKiA8Y29kZT4KICAgKiAgICRhcnJheSA9IFNweWM6OllBTUxMb2FkKCRmaWxlKTsKICAgKiA8L2NvZGU+CiAgICogb3I6CiAgICogPGNvZGU+CiAgICogICAkYXJyYXkgPSBzcHljX2xvYWRfZmlsZSgkZmlsZSk7CiAgICogPC9jb2RlPgogICAqIEBwYWNrYWdlIFNweWMKICAgKi8KY2xhc3MgU3B5YyB7CgogIC8vIFNFVFRJTkdTCgogIC8qKgogICAqIFNldHRpbmcgdGhpcyB0byB0cnVlIHdpbGwgZm9yY2UgWUFNTER1bXAgdG8gZW5jbG9zZSBhbnkgc3RyaW5nIHZhbHVlIGluCiAgICogcXVvdGVzLiAgRmFsc2UgYnkgZGVmYXVsdC4KICAgKiAKICAgKiBAdmFyIGJvb2wKICAgKi8KICB2YXIgJHNldHRpbmdfZHVtcF9mb3JjZV9xdW90ZXMgPSBmYWxzZTsKCiAgLyoqCiAgICogU2V0dGluZyB0aGlzIHRvIHRydWUgd2lsbCBmb3JzZSBZQU1MTG9hZCB0byB1c2Ugc3lja19sb2FkIGZ1bmN0aW9uIHdoZW4KICAgKiBwb3NzaWJsZS4gRmFsc2UgYnkgZGVmYXVsdC4KICAgKiBAdmFyIGJvb2wKICAgKi8KICB2YXIgJHNldHRpbmdfdXNlX3N5Y2tfaXNfcG9zc2libGUgPSBmYWxzZTsKCgoKICAvKiojQCsKICAqIEBhY2Nlc3MgcHJpdmF0ZQogICogQHZhciBtaXhlZAogICovCiAgdmFyICRfZHVtcEluZGVudDsKICB2YXIgJF9kdW1wV29yZFdyYXA7CiAgdmFyICRfY29udGFpbnNHcm91cEFuY2hvciA9IGZhbHNlOwogIHZhciAkX2NvbnRhaW5zR3JvdXBBbGlhcyA9IGZhbHNlOwogIHZhciAkcGF0aDsKICB2YXIgJHJlc3VsdDsKICB2YXIgJExpdGVyYWxQbGFjZUhvbGRlciA9ICdfX19ZQU1MX0xpdGVyYWxfQmxvY2tfX18nOwogIHZhciAkU2F2ZWRHcm91cHMgPSBhcnJheSgpOwogIHZhciAkaW5kZW50OwogIC8qKgogICAqIFBhdGggbW9kaWZpZXIgdGhhdCBzaG91bGQgYmUgYXBwbGllZCBhZnRlciBhZGRpbmcgY3VycmVudCBlbGVtZW50LgogICAqIEB2YXIgYXJyYXkKICAgKi8KICB2YXIgJGRlbGF5ZWRQYXRoID0gYXJyYXkoKTsKCiAgLyoqI0ArCiAgKiBAYWNjZXNzIHB1YmxpYwogICogQHZhciBtaXhlZAogICovCiAgdmFyICRfbm9kZUlkOwoKLyoqCiAqIExvYWQgYSB2YWxpZCBZQU1MIHN0cmluZyB0byBTcHljLgogKiBAcGFyYW0gc3RyaW5nICRpbnB1dAogKiBAcmV0dXJuIGFycmF5CiAqLwogIGZ1bmN0aW9uIGxvYWQgKCRpbnB1dCkgewogICAgcmV0dXJuICR0aGlzLT5fX2xvYWRTdHJpbmcoJGlucHV0KTsKICB9CgogLyoqCiAqIExvYWQgYSB2YWxpZCBZQU1MIGZpbGUgdG8gU3B5Yy4KICogQHBhcmFtIHN0cmluZyAkZmlsZQogKiBAcmV0dXJuIGFycmF5CiAqLwogIGZ1bmN0aW9uIGxvYWRGaWxlICgkZmlsZSkgewogICAgcmV0dXJuICR0aGlzLT5fX2xvYWQoJGZpbGUpOwogIH0KCiAgLyoqCiAgICAgKiBMb2FkIFlBTUwgaW50byBhIFBIUCBhcnJheSBzdGF0aWNhbGx5CiAgICAgKgogICAgICogVGhlIGxvYWQgbWV0aG9kLCB3aGVuIHN1cHBsaWVkIHdpdGggYSBZQU1MIHN0cmVhbSAoc3RyaW5nIG9yIGZpbGUpLAogICAgICogd2lsbCBkbyBpdHMgYmVzdCB0byBjb252ZXJ0IFlBTUwgaW4gYSBmaWxlIGludG8gYSBQSFAgYXJyYXkuICBQcmV0dHkKICAgICAqIHNpbXBsZS4KICAgICAqICBVc2FnZToKICAgICAqICA8Y29kZT4KICAgICAqICAgJGFycmF5ID0gU3B5Yzo6WUFNTExvYWQoJ2x1Y2t5LnlhbWwnKTsKICAgICAqICAgcHJpbnRfcigkYXJyYXkpOwogICAgICogIDwvY29kZT4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnB1dCBQYXRoIG9mIFlBTUwgZmlsZSBvciBzdHJpbmcgY29udGFpbmluZyBZQU1MCiAgICAgKi8KICBmdW5jdGlvbiBZQU1MTG9hZCgkaW5wdXQpIHsKICAgICRTcHljID0gbmV3IFNweWM7CiAgICByZXR1cm4gJFNweWMtPl9fbG9hZCgkaW5wdXQpOwogIH0KCiAgLyoqCiAgICAgKiBMb2FkIGEgc3RyaW5nIG9mIFlBTUwgaW50byBhIFBIUCBhcnJheSBzdGF0aWNhbGx5CiAgICAgKgogICAgICogVGhlIGxvYWQgbWV0aG9kLCB3aGVuIHN1cHBsaWVkIHdpdGggYSBZQU1MIHN0cmluZywgd2lsbCBkbyBpdHMgYmVzdCAKICAgICAqIHRvIGNvbnZlcnQgWUFNTCBpbiBhIHN0cmluZyBpbnRvIGEgUEhQIGFycmF5LiAgUHJldHR5IHNpbXBsZS4KICAgICAqCiAgICAgKiBOb3RlOiB1c2UgdGhpcyBmdW5jdGlvbiBpZiB5b3UgZG9uJ3Qgd2FudCBmaWxlcyBmcm9tIHRoZSBmaWxlIHN5c3RlbQogICAgICogbG9hZGVkIGFuZCBwcm9jZXNzZWQgYXMgWUFNTC4gIFRoaXMgaXMgb2YgaW50ZXJlc3QgdG8gcGVvcGxlIGNvbmNlcm5lZAogICAgICogYWJvdXQgc2VjdXJpdHkgd2hvc2UgaW5wdXQgaXMgZnJvbSBhIHN0cmluZy4KICAgICAqCiAgICAgKiAgVXNhZ2U6CiAgICAgKiAgPGNvZGU+CiAgICAgKiAgICRhcnJheSA9IFNweWM6OllBTUxMb2FkU3RyaW5nKCItLS1cbjA6IGhlbGxvIHdvcmxkXG4iKTsKICAgICAqICAgcHJpbnRfcigkYXJyYXkpOwogICAgICogIDwvY29kZT4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnB1dCBTdHJpbmcgY29udGFpbmluZyBZQU1MCiAgICAgKi8KICBmdW5jdGlvbiBZQU1MTG9hZFN0cmluZygkaW5wdXQpIHsKICAgICRTcHljID0gbmV3IFNweWM7CiAgICByZXR1cm4gJFNweWMtPl9fbG9hZFN0cmluZygkaW5wdXQpOwogIH0KCiAgLyoqCiAgICAgKiBEdW1wIFlBTUwgZnJvbSBQSFAgYXJyYXkgc3RhdGljYWxseQogICAgICoKICAgICAqIFRoZSBkdW1wIG1ldGhvZCwgd2hlbiBzdXBwbGllZCB3aXRoIGFuIGFycmF5LCB3aWxsIGRvIGl0cyBiZXN0CiAgICAgKiB0byBjb252ZXJ0IHRoZSBhcnJheSBpbnRvIGZyaWVuZGx5IFlBTUwuICBQcmV0dHkgc2ltcGxlLiAgRmVlbCBmcmVlIHRvCiAgICAgKiBzYXZlIHRoZSByZXR1cm5lZCBzdHJpbmcgYXMgbm90aGluZy55YW1sIGFuZCBwYXNzIGl0IGFyb3VuZC4KICAgICAqCiAgICAgKiBPaCwgYW5kIHlvdSBjYW4gZGVjaWRlIGhvdyBiaWcgdGhlIGluZGVudCBpcyBhbmQgd2hhdCB0aGUgd29yZHdyYXAKICAgICAqIGZvciBmb2xkaW5nIGlzLiAgUHJldHR5IGNvb2wgLS0ganVzdCBwYXNzIGluICdmYWxzZScgZm9yIGVpdGhlciBpZgogICAgICogeW91IHdhbnQgdG8gdXNlIHRoZSBkZWZhdWx0LgogICAgICoKICAgICAqIEluZGVudCdzIGRlZmF1bHQgaXMgMiBzcGFjZXMsIHdvcmR3cmFwJ3MgZGVmYXVsdCBpcyA0MCBjaGFyYWN0ZXJzLiAgQW5kCiAgICAgKiB5b3UgY2FuIHR1cm4gb2ZmIHdvcmR3cmFwIGJ5IHBhc3NpbmcgaW4gMC4KICAgICAqCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSBhcnJheSAkYXJyYXkgUEhQIGFycmF5CiAgICAgKiBAcGFyYW0gaW50ICRpbmRlbnQgUGFzcyBpbiBmYWxzZSB0byB1c2UgdGhlIGRlZmF1bHQsIHdoaWNoIGlzIDIKICAgICAqIEBwYXJhbSBpbnQgJHdvcmR3cmFwIFBhc3MgaW4gMCBmb3Igbm8gd29yZHdyYXAsIGZhbHNlIGZvciBkZWZhdWx0ICg0MCkKICAgICAqLwogIGZ1bmN0aW9uIFlBTUxEdW1wKCRhcnJheSwkaW5kZW50ID0gZmFsc2UsJHdvcmR3cmFwID0gZmFsc2UpIHsKICAgICRzcHljID0gbmV3IFNweWM7CiAgICByZXR1cm4gJHNweWMtPmR1bXAoJGFycmF5LCRpbmRlbnQsJHdvcmR3cmFwKTsKICB9CgoKICAvKioKICAgICAqIER1bXAgUEhQIGFycmF5IHRvIFlBTUwKICAgICAqCiAgICAgKiBUaGUgZHVtcCBtZXRob2QsIHdoZW4gc3VwcGxpZWQgd2l0aCBhbiBhcnJheSwgd2lsbCBkbyBpdHMgYmVzdAogICAgICogdG8gY29udmVydCB0aGUgYXJyYXkgaW50byBmcmllbmRseSBZQU1MLiAgUHJldHR5IHNpbXBsZS4gIEZlZWwgZnJlZSB0bwogICAgICogc2F2ZSB0aGUgcmV0dXJuZWQgc3RyaW5nIGFzIHRhc3RlZnVsLnlhbWwgYW5kIHBhc3MgaXQgYXJvdW5kLgogICAgICoKICAgICAqIE9oLCBhbmQgeW91IGNhbiBkZWNpZGUgaG93IGJpZyB0aGUgaW5kZW50IGlzIGFuZCB3aGF0IHRoZSB3b3Jkd3JhcAogICAgICogZm9yIGZvbGRpbmcgaXMuICBQcmV0dHkgY29vbCAtLSBqdXN0IHBhc3MgaW4gJ2ZhbHNlJyBmb3IgZWl0aGVyIGlmCiAgICAgKiB5b3Ugd2FudCB0byB1c2UgdGhlIGRlZmF1bHQuCiAgICAgKgogICAgICogSW5kZW50J3MgZGVmYXVsdCBpcyAyIHNwYWNlcywgd29yZHdyYXAncyBkZWZhdWx0IGlzIDQwIGNoYXJhY3RlcnMuICBBbmQKICAgICAqIHlvdSBjYW4gdHVybiBvZmYgd29yZHdyYXAgYnkgcGFzc2luZyBpbiAwLgogICAgICoKICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtIGFycmF5ICRhcnJheSBQSFAgYXJyYXkKICAgICAqIEBwYXJhbSBpbnQgJGluZGVudCBQYXNzIGluIGZhbHNlIHRvIHVzZSB0aGUgZGVmYXVsdCwgd2hpY2ggaXMgMgogICAgICogQHBhcmFtIGludCAkd29yZHdyYXAgUGFzcyBpbiAwIGZvciBubyB3b3Jkd3JhcCwgZmFsc2UgZm9yIGRlZmF1bHQgKDQwKQogICAgICovCiAgZnVuY3Rpb24gZHVtcCgkYXJyYXksJGluZGVudCA9IGZhbHNlLCR3b3Jkd3JhcCA9IGZhbHNlKSB7CiAgICAvLyBEdW1wcyB0byBzb21lIHZlcnkgY2xlYW4gWUFNTC4gIFdlJ2xsIGhhdmUgdG8gYWRkIHNvbWUgbW9yZSBmZWF0dXJlcwogICAgLy8gYW5kIG9wdGlvbnMgc29vbi4gIEFuZCBiZXR0ZXIgc3VwcG9ydCBmb3IgZm9sZGluZy4KCiAgICAvLyBOZXcgZmVhdHVyZXMgYW5kIG9wdGlvbnMuCiAgICBpZiAoJGluZGVudCA9PT0gZmFsc2Ugb3IgIWlzX251bWVyaWMoJGluZGVudCkpIHsKICAgICAgJHRoaXMtPl9kdW1wSW5kZW50ID0gMjsKICAgIH0gZWxzZSB7CiAgICAgICR0aGlzLT5fZHVtcEluZGVudCA9ICRpbmRlbnQ7CiAgICB9CgogICAgaWYgKCR3b3Jkd3JhcCA9PT0gZmFsc2Ugb3IgIWlzX251bWVyaWMoJHdvcmR3cmFwKSkgewogICAgICAkdGhpcy0+X2R1bXBXb3JkV3JhcCA9IDQwOwogICAgfSBlbHNlIHsKICAgICAgJHRoaXMtPl9kdW1wV29yZFdyYXAgPSAkd29yZHdyYXA7CiAgICB9CgogICAgLy8gTmV3IFlBTUwgZG9jdW1lbnQKICAgICRzdHJpbmcgPSAiLS0tXG4iOwoKICAgIC8vIFN0YXJ0IGF0IHRoZSBiYXNlIG9mIHRoZSBhcnJheSBhbmQgbW92ZSB0aHJvdWdoIGl0LgogICAgaWYgKCRhcnJheSkgewogICAgICAkYXJyYXkgPSAoYXJyYXkpJGFycmF5OwogICAgICAkZmlyc3Rfa2V5ID0ga2V5KCRhcnJheSk7CiAgICAgIAogICAgICAkcHJldmlvdXNfa2V5ID0gLTE7CiAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICRzdHJpbmcgLj0gJHRoaXMtPl95YW1saXplKCRrZXksJHZhbHVlLDAsJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSk7CiAgICAgICAgJHByZXZpb3VzX2tleSA9ICRrZXk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiAkc3RyaW5nOwogIH0KCiAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBjb252ZXJ0IGEga2V5IC8gdmFsdWUgYXJyYXkgaXRlbSB0byBZQU1MCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJGtleSBUaGUgbmFtZSBvZiB0aGUga2V5CiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgaXRlbQogICAgICogQHBhcmFtICRpbmRlbnQgVGhlIGluZGVudCBvZiB0aGUgY3VycmVudCBub2RlCiAgICAgKi8KICBmdW5jdGlvbiBfeWFtbGl6ZSgka2V5LCR2YWx1ZSwkaW5kZW50LCAkcHJldmlvdXNfa2V5ID0gLTEsICRmaXJzdF9rZXkgPSAwKSB7CiAgICBpZiAoaXNfYXJyYXkoJHZhbHVlKSkgewogICAgICBpZiAoZW1wdHkgKCR2YWx1ZSkpCiAgICAgICAgcmV0dXJuICR0aGlzLT5fZHVtcE5vZGUoJGtleSwgYXJyYXkoKSwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSk7CiAgICAgIC8vIEl0IGhhcyBjaGlsZHJlbi4gIFdoYXQgdG8gZG8/CiAgICAgIC8vIE1ha2UgaXQgdGhlIHJpZ2h0IGtpbmQgb2YgaXRlbQogICAgICAkc3RyaW5nID0gJHRoaXMtPl9kdW1wTm9kZSgka2V5LCBOVUxMLCAkaW5kZW50LCAkcHJldmlvdXNfa2V5LCAkZmlyc3Rfa2V5KTsKICAgICAgLy8gQWRkIHRoZSBpbmRlbnQKICAgICAgJGluZGVudCArPSAkdGhpcy0+X2R1bXBJbmRlbnQ7CiAgICAgIC8vIFlhbWxpemUgdGhlIGFycmF5CiAgICAgICRzdHJpbmcgLj0gJHRoaXMtPl95YW1saXplQXJyYXkoJHZhbHVlLCRpbmRlbnQpOwogICAgfSBlbHNlaWYgKCFpc19hcnJheSgkdmFsdWUpKSB7CiAgICAgIC8vIEl0IGRvZXNuJ3QgaGF2ZSBjaGlsZHJlbi4gIFlpcC4KICAgICAgJHN0cmluZyA9ICR0aGlzLT5fZHVtcE5vZGUoJGtleSwgJHZhbHVlLCAkaW5kZW50LCAkcHJldmlvdXNfa2V5LCAkZmlyc3Rfa2V5KTsKICAgIH0KICAgIHJldHVybiAkc3RyaW5nOwogIH0KCiAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBjb252ZXJ0IGFuIGFycmF5IHRvIFlBTUwKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAkYXJyYXkgVGhlIGFycmF5IHlvdSB3YW50IHRvIGNvbnZlcnQKICAgICAqIEBwYXJhbSAkaW5kZW50IFRoZSBpbmRlbnQgb2YgdGhlIGN1cnJlbnQgbGV2ZWwKICAgICAqLwogIGZ1bmN0aW9uIF95YW1saXplQXJyYXkoJGFycmF5LCRpbmRlbnQpIHsKICAgIGlmIChpc19hcnJheSgkYXJyYXkpKSB7CiAgICAgICRzdHJpbmcgPSAnJzsKICAgICAgJHByZXZpb3VzX2tleSA9IC0xOwogICAgICAkZmlyc3Rfa2V5ID0ga2V5KCRhcnJheSk7CiAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICRzdHJpbmcgLj0gJHRoaXMtPl95YW1saXplKCRrZXksICR2YWx1ZSwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSk7CiAgICAgICAgJHByZXZpb3VzX2tleSA9ICRrZXk7CiAgICAgIH0KICAgICAgcmV0dXJuICRzdHJpbmc7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICAvKioKICAgICAqIFJldHVybnMgWUFNTCBmcm9tIGEga2V5IGFuZCBhIHZhbHVlCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJGtleSBUaGUgbmFtZSBvZiB0aGUga2V5CiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgaXRlbQogICAgICogQHBhcmFtICRpbmRlbnQgVGhlIGluZGVudCBvZiB0aGUgY3VycmVudCBub2RlCiAgICAgKi8KICBmdW5jdGlvbiBfZHVtcE5vZGUoJGtleSwgJHZhbHVlLCAkaW5kZW50LCAkcHJldmlvdXNfa2V5ID0gLTEsICRmaXJzdF9rZXkgPSAwKSB7CiAgICAvLyBkbyBzb21lIGZvbGRpbmcgaGVyZSwgZm9yIGJsb2NrcwogICAgaWYgKGlzX3N0cmluZyAoJHZhbHVlKSAmJiAoKHN0cnBvcygkdmFsdWUsIlxuIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIjogIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIi0gIikgIT09IGZhbHNlIHx8CiAgICAgIHN0cnBvcygkdmFsdWUsIioiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiIyIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCI8IikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIj4iKSAhPT0gZmFsc2UgfHwKICAgICAgc3RycG9zKCR2YWx1ZSwiWyIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCJdIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsInsiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwifSIpICE9PSBmYWxzZSkgfHwgc3Vic3RyICgkdmFsdWUsIC0xLCAxKSA9PSAnOicpKSB7CiAgICAgICR2YWx1ZSA9ICR0aGlzLT5fZG9MaXRlcmFsQmxvY2soJHZhbHVlLCRpbmRlbnQpOwogICAgfSBlbHNlIHsKICAgICAgJHZhbHVlICA9ICR0aGlzLT5fZG9Gb2xkaW5nKCR2YWx1ZSwkaW5kZW50KTsKICAgICAgaWYgKGlzX2Jvb2woJHZhbHVlKSkgewogICAgICAgICR2YWx1ZSA9ICgkdmFsdWUpID8gInRydWUiIDogImZhbHNlIjsKICAgICAgfQogICAgfQoKICAgIGlmICgkdmFsdWUgPT09IGFycmF5KCkpICR2YWx1ZSA9ICdbIF0nOwoKICAgICRzcGFjZXMgPSBzdHJfcmVwZWF0KCcgJywkaW5kZW50KTsKCiAgICBpZiAoaXNfaW50KCRrZXkpICYmICRrZXkgLSAxID09ICRwcmV2aW91c19rZXkgJiYgJGZpcnN0X2tleT09PTApIHsKICAgICAgLy8gSXQncyBhIHNlcXVlbmNlCiAgICAgICRzdHJpbmcgPSAkc3BhY2VzLictICcuJHZhbHVlLiJcbiI7CiAgICB9IGVsc2UgewogICAgICBpZiAoJGZpcnN0X2tleT09PTApICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdLZXlzIGFyZSBhbGwgc2NyZXd5LiAgVGhlIGZpcnN0IG9uZSB3YXMgemVybywgbm93IGl0XCdzICInLiAka2V5IC4nIicpOwogICAgICAvLyBJdCdzIG1hcHBlZAogICAgICBpZiAoc3RycG9zKCRrZXksICI6IikgIT09IGZhbHNlKSB7ICRrZXkgPSAnIicgLiAka2V5IC4gJyInOyB9CiAgICAgICRzdHJpbmcgPSAkc3BhY2VzLiRrZXkuJzogJy4kdmFsdWUuIlxuIjsKICAgIH0KICAgIHJldHVybiAkc3RyaW5nOwogIH0KCiAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbGl0ZXJhbCBibG9jayBmb3IgZHVtcGluZwogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtICR2YWx1ZQogICAgICogQHBhcmFtICRpbmRlbnQgaW50IFRoZSB2YWx1ZSBvZiB0aGUgaW5kZW50CiAgICAgKi8KICBmdW5jdGlvbiBfZG9MaXRlcmFsQmxvY2soJHZhbHVlLCRpbmRlbnQpIHsKICAgIGlmIChzdHJwb3MoJHZhbHVlLCAiXG4iKSA9PT0gZmFsc2UgJiYgc3RycG9zKCR2YWx1ZSwgIiciKSA9PT0gZmFsc2UpIHsKICAgICAgcmV0dXJuIHNwcmludGYgKCInJXMnIiwgJHZhbHVlKTsKICAgIH0KICAgIGlmIChzdHJwb3MoJHZhbHVlLCAiXG4iKSA9PT0gZmFsc2UgJiYgc3RycG9zKCR2YWx1ZSwgJyInKSA9PT0gZmFsc2UpIHsKICAgICAgcmV0dXJuIHNwcmludGYgKCciJXMiJywgJHZhbHVlKTsKICAgIH0KICAgICRleHBsb2RlZCA9IGV4cGxvZGUoIlxuIiwkdmFsdWUpOwogICAgJG5ld1ZhbHVlID0gJ3wnOwogICAgJGluZGVudCAgKz0gJHRoaXMtPl9kdW1wSW5kZW50OwogICAgJHNwYWNlcyAgID0gc3RyX3JlcGVhdCgnICcsJGluZGVudCk7CiAgICBmb3JlYWNoICgkZXhwbG9kZWQgYXMgJGxpbmUpIHsKICAgICAgJG5ld1ZhbHVlIC49ICJcbiIgLiAkc3BhY2VzIC4gdHJpbSgkbGluZSk7CiAgICB9CiAgICByZXR1cm4gJG5ld1ZhbHVlOwogIH0KCiAgLyoqCiAgICAgKiBGb2xkcyBhIHN0cmluZyBvZiB0ZXh0LCBpZiBuZWNlc3NhcnkKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAkdmFsdWUgVGhlIHN0cmluZyB5b3Ugd2lzaCB0byBmb2xkCiAgICAgKi8KICBmdW5jdGlvbiBfZG9Gb2xkaW5nKCR2YWx1ZSwkaW5kZW50KSB7CiAgICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiB3b3Jkd3JhcCBpcyBzZXQgdG8gMAoKICAgIGlmICgkdGhpcy0+X2R1bXBXb3JkV3JhcCAhPT0gMCAmJiBpc19zdHJpbmcgKCR2YWx1ZSkgJiYgc3RybGVuKCR2YWx1ZSkgPiAkdGhpcy0+X2R1bXBXb3JkV3JhcCkgewogICAgICAkaW5kZW50ICs9ICR0aGlzLT5fZHVtcEluZGVudDsKICAgICAgJGluZGVudCA9IHN0cl9yZXBlYXQoJyAnLCRpbmRlbnQpOwogICAgICAkd3JhcHBlZCA9IHdvcmR3cmFwKCR2YWx1ZSwkdGhpcy0+X2R1bXBXb3JkV3JhcCwiXG4kaW5kZW50Iik7CiAgICAgICR2YWx1ZSAgID0gIj5cbiIuJGluZGVudC4kd3JhcHBlZDsKICAgIH0gZWxzZSB7CiAgICAgIGlmICgkdGhpcy0+c2V0dGluZ19kdW1wX2ZvcmNlX3F1b3RlcyAmJiBpc19zdHJpbmcgKCR2YWx1ZSkpCiAgICAgICAgJHZhbHVlID0gJyInIC4gJHZhbHVlIC4gJyInOwogICAgfQoKCiAgICByZXR1cm4gJHZhbHVlOwogIH0KCi8vIExPQURJTkcgRlVOQ1RJT05TCgogIGZ1bmN0aW9uIF9fbG9hZCgkaW5wdXQpIHsKICAgICRTb3VyY2UgPSAkdGhpcy0+bG9hZEZyb21Tb3VyY2UoJGlucHV0KTsKICAgIHJldHVybiAkdGhpcy0+bG9hZFdpdGhTb3VyY2UoJFNvdXJjZSk7CiAgfQoKICBmdW5jdGlvbiBfX2xvYWRTdHJpbmcoJGlucHV0KSB7CiAgICAkU291cmNlID0gJHRoaXMtPmxvYWRGcm9tU3RyaW5nKCRpbnB1dCk7CiAgICByZXR1cm4gJHRoaXMtPmxvYWRXaXRoU291cmNlKCRTb3VyY2UpOwogIH0KCiAgZnVuY3Rpb24gbG9hZFdpdGhTb3VyY2UoJFNvdXJjZSkgewogICAgaWYgKGVtcHR5ICgkU291cmNlKSkgcmV0dXJuIGFycmF5KCk7CiAgICBpZiAoJHRoaXMtPnNldHRpbmdfdXNlX3N5Y2tfaXNfcG9zc2libGUgJiYgZnVuY3Rpb25fZXhpc3RzICgnc3lja19sb2FkJykpIHsKICAgICAgJGFycmF5ID0gc3lja19sb2FkIChpbXBsb2RlICgnJywgJFNvdXJjZSkpOwogICAgICByZXR1cm4gaXNfYXJyYXkoJGFycmF5KSA/ICRhcnJheSA6IGFycmF5KCk7CiAgICB9CgogICAgJHRoaXMtPnBhdGggPSBhcnJheSgpOwogICAgJHRoaXMtPnJlc3VsdCA9IGFycmF5KCk7CgogICAgJGNudCA9IGNvdW50KCRTb3VyY2UpOwogICAgZm9yICgkaSA9IDA7ICRpIDwgJGNudDsgJGkrKykgewogICAgICAkbGluZSA9ICRTb3VyY2VbJGldOwogICAgICAKICAgICAgJHRoaXMtPmluZGVudCA9IHN0cmxlbigkbGluZSkgLSBzdHJsZW4obHRyaW0oJGxpbmUpKTsKICAgICAgJHRlbXBQYXRoID0gJHRoaXMtPmdldFBhcmVudFBhdGhCeUluZGVudCgkdGhpcy0+aW5kZW50KTsKICAgICAgJGxpbmUgPSAkdGhpcy0+c3RyaXBJbmRlbnQoJGxpbmUsICR0aGlzLT5pbmRlbnQpOwogICAgICBpZiAoJHRoaXMtPmlzQ29tbWVudCgkbGluZSkpIGNvbnRpbnVlOwogICAgICBpZiAoJHRoaXMtPmlzRW1wdHkoJGxpbmUpKSBjb250aW51ZTsKICAgICAgJHRoaXMtPnBhdGggPSAkdGVtcFBhdGg7CgogICAgICAkbGl0ZXJhbEJsb2NrU3R5bGUgPSAkdGhpcy0+c3RhcnRzTGl0ZXJhbEJsb2NrKCRsaW5lKTsKICAgICAgaWYgKCRsaXRlcmFsQmxvY2tTdHlsZSkgewogICAgICAgICRsaW5lID0gcnRyaW0gKCRsaW5lLCAkbGl0ZXJhbEJsb2NrU3R5bGUgLiAiIFxuIik7CiAgICAgICAgJGxpdGVyYWxCbG9jayA9ICcnOwogICAgICAgICRsaW5lIC49ICR0aGlzLT5MaXRlcmFsUGxhY2VIb2xkZXI7CgogICAgICAgIHdoaWxlICgrKyRpIDwgJGNudCAmJiAkdGhpcy0+bGl0ZXJhbEJsb2NrQ29udGludWVzKCRTb3VyY2VbJGldLCAkdGhpcy0+aW5kZW50KSkgewogICAgICAgICAgJGxpdGVyYWxCbG9jayA9ICR0aGlzLT5hZGRMaXRlcmFsTGluZSgkbGl0ZXJhbEJsb2NrLCAkU291cmNlWyRpXSwgJGxpdGVyYWxCbG9ja1N0eWxlKTsKICAgICAgICB9CiAgICAgICAgJGktLTsKICAgICAgfQoKICAgICAgd2hpbGUgKCsrJGkgPCAkY250ICYmICR0aGlzLT5ncmVlZGlseU5lZWROZXh0TGluZSgkbGluZSkpIHsKICAgICAgICAkbGluZSA9IHJ0cmltICgkbGluZSwgIiBcblx0XHIiKSAuICcgJyAuIGx0cmltICgkU291cmNlWyRpXSwgIiBcdCIpOwogICAgICB9CiAgICAgICRpLS07CgoKCiAgICAgIGlmIChzdHJwb3MgKCRsaW5lLCAnIycpKSB7CiAgICAgICAgaWYgKHN0cnBvcyAoJGxpbmUsICciJykgPT09IGZhbHNlICYmIHN0cnBvcyAoJGxpbmUsICInIikgPT09IGZhbHNlKQogICAgICAgICAgJGxpbmUgPSBwcmVnX3JlcGxhY2UoJy9ccysjKC4rKSQvJywnJywkbGluZSk7CiAgICAgIH0KCiAgICAgICRsaW5lQXJyYXkgPSAkdGhpcy0+X3BhcnNlTGluZSgkbGluZSk7CgogICAgICBpZiAoJGxpdGVyYWxCbG9ja1N0eWxlKQogICAgICAgICRsaW5lQXJyYXkgPSAkdGhpcy0+cmV2ZXJ0TGl0ZXJhbFBsYWNlSG9sZGVyICgkbGluZUFycmF5LCAkbGl0ZXJhbEJsb2NrKTsKCiAgICAgICR0aGlzLT5hZGRBcnJheSgkbGluZUFycmF5LCAkdGhpcy0+aW5kZW50KTsKCiAgICAgIGZvcmVhY2ggKCR0aGlzLT5kZWxheWVkUGF0aCBhcyAkaW5kZW50ID0+ICRkZWxheWVkUGF0aCkKICAgICAgICAkdGhpcy0+cGF0aFskaW5kZW50XSA9ICRkZWxheWVkUGF0aDsKCiAgICAgICR0aGlzLT5kZWxheWVkUGF0aCA9IGFycmF5KCk7CgogICAgfQogICAgcmV0dXJuICR0aGlzLT5yZXN1bHQ7CiAgfQoKICBmdW5jdGlvbiBsb2FkRnJvbVNvdXJjZSAoJGlucHV0KSB7CiAgICBpZiAoIWVtcHR5KCRpbnB1dCkgJiYgc3RycG9zKCRpbnB1dCwgIlxuIikgPT09IGZhbHNlICYmIGZpbGVfZXhpc3RzKCRpbnB1dCkpCiAgICByZXR1cm4gZmlsZSgkaW5wdXQpOwoKICAgIHJldHVybiAkdGhpcy0+bG9hZEZyb21TdHJpbmcoJGlucHV0KTsKICB9CgogIGZ1bmN0aW9uIGxvYWRGcm9tU3RyaW5nICgkaW5wdXQpIHsKICAgICRsaW5lcyA9IGV4cGxvZGUoIlxuIiwkaW5wdXQpOwogICAgZm9yZWFjaCAoJGxpbmVzIGFzICRrID0+ICRfKSB7CiAgICAgICRsaW5lc1ska10gPSBydHJpbSAoJF8sICJcciIpOwogICAgfQogICAgcmV0dXJuICRsaW5lczsKICB9CgogIC8qKgogICAgICogUGFyc2VzIFlBTUwgY29kZSBhbmQgcmV0dXJucyBhbiBhcnJheSBmb3IgYSBub2RlCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUgQSBsaW5lIGZyb20gdGhlIFlBTUwgZmlsZQogICAgICovCiAgZnVuY3Rpb24gX3BhcnNlTGluZSgkbGluZSkgewogICAgaWYgKCEkbGluZSkgcmV0dXJuIGFycmF5KCk7CiAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwoKICAgIGlmICghJGxpbmUpIHJldHVybiBhcnJheSgpOwogICAgJGFycmF5ID0gYXJyYXkoKTsKCiAgICAkZ3JvdXAgPSAkdGhpcy0+bm9kZUNvbnRhaW5zR3JvdXAoJGxpbmUpOwogICAgaWYgKCRncm91cCkgewogICAgICAkdGhpcy0+YWRkR3JvdXAoJGxpbmUsICRncm91cCk7CiAgICAgICRsaW5lID0gJHRoaXMtPnN0cmlwR3JvdXAgKCRsaW5lLCAkZ3JvdXApOwogICAgfQoKICAgIGlmICgkdGhpcy0+c3RhcnRzTWFwcGVkU2VxdWVuY2UoJGxpbmUpKQogICAgICByZXR1cm4gJHRoaXMtPnJldHVybk1hcHBlZFNlcXVlbmNlKCRsaW5lKTsKCiAgICBpZiAoJHRoaXMtPnN0YXJ0c01hcHBlZFZhbHVlKCRsaW5lKSkKICAgICAgcmV0dXJuICR0aGlzLT5yZXR1cm5NYXBwZWRWYWx1ZSgkbGluZSk7CgogICAgaWYgKCR0aGlzLT5pc0FycmF5RWxlbWVudCgkbGluZSkpCiAgICAgcmV0dXJuICR0aGlzLT5yZXR1cm5BcnJheUVsZW1lbnQoJGxpbmUpOwoKICAgIGlmICgkdGhpcy0+aXNQbGFpbkFycmF5KCRsaW5lKSkKICAgICByZXR1cm4gJHRoaXMtPnJldHVyblBsYWluQXJyYXkoJGxpbmUpOyAKICAgICAKICAgICAKICAgIHJldHVybiAkdGhpcy0+cmV0dXJuS2V5VmFsdWVQYWlyKCRsaW5lKTsKCiAgfQoKICAvKioKICAgICAqIEZpbmRzIHRoZSB0eXBlIG9mIHRoZSBwYXNzZWQgdmFsdWUsIHJldHVybnMgdGhlIHZhbHVlIGFzIHRoZSBuZXcgdHlwZS4KICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogIGZ1bmN0aW9uIF90b1R5cGUoJHZhbHVlKSB7CiAgICBpZiAoJHZhbHVlID09PSAnJykgcmV0dXJuIG51bGw7CiAgICAkZmlyc3RfY2hhcmFjdGVyID0gJHZhbHVlWzBdOwogICAgJGxhc3RfY2hhcmFjdGVyID0gc3Vic3RyKCR2YWx1ZSwgLTEsIDEpOwoKICAgICRpc19xdW90ZWQgPSBmYWxzZTsKICAgIGRvIHsKICAgICAgaWYgKCEkdmFsdWUpIGJyZWFrOwogICAgICBpZiAoJGZpcnN0X2NoYXJhY3RlciAhPSAnIicgJiYgJGZpcnN0X2NoYXJhY3RlciAhPSAiJyIpIGJyZWFrOwogICAgICBpZiAoJGxhc3RfY2hhcmFjdGVyICE9ICciJyAmJiAkbGFzdF9jaGFyYWN0ZXIgIT0gIiciKSBicmVhazsKICAgICAgJGlzX3F1b3RlZCA9IHRydWU7CiAgICB9IHdoaWxlICgwKTsKCiAgICBpZiAoJGlzX3F1b3RlZCkKICAgICAgcmV0dXJuIHN0cnRyKHN1YnN0ciAoJHZhbHVlLCAxLCAtMSksIGFycmF5ICgnXFwiJyA9PiAnIicsICdcJ1wnJyA9PiAnXCcnLCAnXFxcJycgPT4gJ1wnJykpOwogICAgCiAgICBpZiAoc3RycG9zKCR2YWx1ZSwgJyAjJykgIT09IGZhbHNlKQogICAgICAkdmFsdWUgPSBwcmVnX3JlcGxhY2UoJy9ccysjKC4rKSQvJywnJywkdmFsdWUpOwoKICAgIGlmICgkZmlyc3RfY2hhcmFjdGVyID09ICdbJyAmJiAkbGFzdF9jaGFyYWN0ZXIgPT0gJ10nKSB7CiAgICAgIC8vIFRha2Ugb3V0IHN0cmluZ3Mgc2VxdWVuY2VzIGFuZCBtYXBwaW5ncwogICAgICAkaW5uZXJWYWx1ZSA9IHRyaW0oc3Vic3RyICgkdmFsdWUsIDEsIC0xKSk7CiAgICAgIGlmICgkaW5uZXJWYWx1ZSA9PT0gJycpIHJldHVybiBhcnJheSgpOwogICAgICAkZXhwbG9kZSA9ICR0aGlzLT5faW5saW5lRXNjYXBlKCRpbm5lclZhbHVlKTsKICAgICAgLy8gUHJvcGFnYXRlIHZhbHVlIGFycmF5CiAgICAgICR2YWx1ZSAgPSBhcnJheSgpOwogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAkdikgewogICAgICAgICR2YWx1ZVtdID0gJHRoaXMtPl90b1R5cGUoJHYpOwogICAgICB9CiAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgaWYgKHN0cnBvcygkdmFsdWUsJzogJykhPT1mYWxzZSAmJiAkZmlyc3RfY2hhcmFjdGVyICE9ICd7JykgewogICAgICAkYXJyYXkgPSBleHBsb2RlKCc6ICcsJHZhbHVlKTsKICAgICAgJGtleSAgID0gdHJpbSgkYXJyYXlbMF0pOwogICAgICBhcnJheV9zaGlmdCgkYXJyYXkpOwogICAgICAkdmFsdWUgPSB0cmltKGltcGxvZGUoJzogJywkYXJyYXkpKTsKICAgICAgJHZhbHVlID0gJHRoaXMtPl90b1R5cGUoJHZhbHVlKTsKICAgICAgcmV0dXJuIGFycmF5KCRrZXkgPT4gJHZhbHVlKTsKICAgIH0KICAgIAogICAgaWYgKCRmaXJzdF9jaGFyYWN0ZXIgPT0gJ3snICYmICRsYXN0X2NoYXJhY3RlciA9PSAnfScpIHsKICAgICAgJGlubmVyVmFsdWUgPSB0cmltKHN1YnN0ciAoJHZhbHVlLCAxLCAtMSkpOwogICAgICBpZiAoJGlubmVyVmFsdWUgPT09ICcnKSByZXR1cm4gYXJyYXkoKTsKICAgICAgLy8gSW5saW5lIE1hcHBpbmcKICAgICAgLy8gVGFrZSBvdXQgc3RyaW5ncyBzZXF1ZW5jZXMgYW5kIG1hcHBpbmdzCiAgICAgICRleHBsb2RlID0gJHRoaXMtPl9pbmxpbmVFc2NhcGUoJGlubmVyVmFsdWUpOwogICAgICAvLyBQcm9wYWdhdGUgdmFsdWUgYXJyYXkKICAgICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJHYpIHsKICAgICAgICAkU3ViQXJyID0gJHRoaXMtPl90b1R5cGUoJHYpOwogICAgICAgIGlmIChlbXB0eSgkU3ViQXJyKSkgY29udGludWU7CiAgICAgICAgaWYgKGlzX2FycmF5ICgkU3ViQXJyKSkgewogICAgICAgICAgJGFycmF5W2tleSgkU3ViQXJyKV0gPSAkU3ViQXJyW2tleSgkU3ViQXJyKV07IGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkYXJyYXlbXSA9ICRTdWJBcnI7CiAgICAgIH0KICAgICAgcmV0dXJuICRhcnJheTsKICAgIH0KCiAgICBpZiAoJHZhbHVlID09ICdudWxsJyB8fCAkdmFsdWUgPT0gJ05VTEwnIHx8ICR2YWx1ZSA9PSAnTnVsbCcgfHwgJHZhbHVlID09ICcnIHx8ICR2YWx1ZSA9PSAnficpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKGludHZhbCgkZmlyc3RfY2hhcmFjdGVyKSA+IDAgJiYgcHJlZ19tYXRjaCAoJy9eWzEtOV0rWzAtOV0qJC8nLCAkdmFsdWUpKSB7CiAgICAgICRpbnR2YWx1ZSA9IChpbnQpJHZhbHVlOwogICAgICBpZiAoJGludHZhbHVlICE9IFBIUF9JTlRfTUFYKQogICAgICAgICR2YWx1ZSA9ICRpbnR2YWx1ZTsKICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KCiAgICBpZiAoaW5fYXJyYXkoJHZhbHVlLAogICAgICAgICAgICAgICAgIGFycmF5KCd0cnVlJywgJ29uJywgJysnLCAneWVzJywgJ3knLCAnVHJ1ZScsICdUUlVFJywgJ09uJywgJ09OJywgJ1lFUycsICdZZXMnLCAnWScpKSkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBpZiAoaW5fYXJyYXkoc3RydG9sb3dlcigkdmFsdWUpLAogICAgICAgICAgICAgICAgIGFycmF5KCdmYWxzZScsICdvZmYnLCAnLScsICdubycsICduJykpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBpZiAoaXNfbnVtZXJpYygkdmFsdWUpKSB7CiAgICAgIGlmICgkdmFsdWUgPT09ICcwJykgcmV0dXJuIDA7CiAgICAgIGlmICh0cmltICgkdmFsdWUsIDApID09PSAkdmFsdWUpCiAgICAgICAgJHZhbHVlID0gKGZsb2F0KSR2YWx1ZTsKICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KICAgIAogICAgcmV0dXJuICR2YWx1ZTsKICB9CgogIC8qKgogICAgICogVXNlZCBpbiBpbmxpbmVzIHRvIGNoZWNrIGZvciBtb3JlIGlubGluZXMgb3IgcXVvdGVkIHN0cmluZ3MKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgZnVuY3Rpb24gX2lubGluZUVzY2FwZSgkaW5saW5lKSB7CiAgICAvLyBUaGVyZSdzIGdvdHRhIGJlIGEgY2xlYW5lciB3YXkgdG8gZG8gdGhpcy4uLgogICAgLy8gV2hpbGUgcHVyZSBzZXF1ZW5jZXMgc2VlbSB0byBiZSBuZXN0aW5nIGp1c3QgZmluZSwKICAgIC8vIHB1cmUgbWFwcGluZ3MgYW5kIG1hcHBpbmdzIHdpdGggc2VxdWVuY2VzIGluc2lkZSBjYW4ndCBnbyB2ZXJ5CiAgICAvLyBkZWVwLiAgVGhpcyBuZWVkcyB0byBiZSBmaXhlZC4KCiAgICAkc2VxcyA9IGFycmF5KCk7CiAgICAkbWFwcyA9IGFycmF5KCk7CiAgICAkc2F2ZWRfc3RyaW5ncyA9IGFycmF5KCk7CgogICAgLy8gQ2hlY2sgZm9yIHN0cmluZ3MKICAgICRyZWdleCA9ICcvKD86KCIpfCg/OlwnKSkoKD8oMSlbXiJdK3xbXlwnXSspKSg/KDEpInxcJykvJzsKICAgIGlmIChwcmVnX21hdGNoX2FsbCgkcmVnZXgsJGlubGluZSwkc3RyaW5ncykpIHsKICAgICAgJHNhdmVkX3N0cmluZ3MgPSAkc3RyaW5nc1swXTsKICAgICAgJGlubGluZSAgPSBwcmVnX3JlcGxhY2UoJHJlZ2V4LCdZQU1MU3RyaW5nJywkaW5saW5lKTsKICAgIH0KICAgIHVuc2V0KCRyZWdleCk7CgogICAgJGkgPSAwOwogICAgZG8gewoKICAgIC8vIENoZWNrIGZvciBzZXF1ZW5jZXMKICAgIHdoaWxlIChwcmVnX21hdGNoKCcvXFsoW157fVxbXF1dKylcXS9VJywkaW5saW5lLCRtYXRjaHNlcXMpKSB7CiAgICAgICRzZXFzW10gPSAkbWF0Y2hzZXFzWzBdOwogICAgICAkaW5saW5lID0gcHJlZ19yZXBsYWNlKCcvXFsoW157fVxbXF1dKylcXS9VJywgKCdZQU1MU2VxJyAuIChjb3VudCgkc2VxcykgLSAxKSAuICdzJyksICRpbmxpbmUsIDEpOwogICAgfQoKICAgIC8vIENoZWNrIGZvciBtYXBwaW5ncwogICAgd2hpbGUgKHByZWdfbWF0Y2goJy97KFteXFtcXXt9XSspfS9VJywkaW5saW5lLCRtYXRjaG1hcHMpKSB7CiAgICAgICRtYXBzW10gPSAkbWF0Y2htYXBzWzBdOwogICAgICAkaW5saW5lID0gcHJlZ19yZXBsYWNlKCcveyhbXlxbXF17fV0rKX0vVScsICgnWUFNTE1hcCcgLiAoY291bnQoJG1hcHMpIC0gMSkgLiAncycpLCAkaW5saW5lLCAxKTsKICAgIH0KCiAgICBpZiAoJGkrKyA+PSAxMCkgYnJlYWs7CgogICAgfSB3aGlsZSAoc3RycG9zICgkaW5saW5lLCAnWycpICE9PSBmYWxzZSB8fCBzdHJwb3MgKCRpbmxpbmUsICd7JykgIT09IGZhbHNlKTsKCiAgICAkZXhwbG9kZSA9IGV4cGxvZGUoJywgJywkaW5saW5lKTsKICAgICRzdHJpbmdpID0gMDsgJGkgPSAwOwoKICAgIHdoaWxlICgxKSB7CgogICAgLy8gUmUtYWRkIHRoZSBzZXF1ZW5jZXMKICAgIGlmICghZW1wdHkoJHNlcXMpKSB7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgaWYgKHN0cnBvcygkdmFsdWUsJ1lBTUxTZXEnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgIGZvcmVhY2ggKCRzZXFzIGFzICRzZXFrID0+ICRzZXEpIHsKICAgICAgICAgICAgJGV4cGxvZGVbJGtleV0gPSBzdHJfcmVwbGFjZSgoJ1lBTUxTZXEnLiRzZXFrLidzJyksJHNlcSwkdmFsdWUpOwogICAgICAgICAgICAkdmFsdWUgPSAkZXhwbG9kZVska2V5XTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyBSZS1hZGQgdGhlIG1hcHBpbmdzCiAgICBpZiAoIWVtcHR5KCRtYXBzKSkgewogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MTWFwJykgIT09IGZhbHNlKSB7CiAgICAgICAgICBmb3JlYWNoICgkbWFwcyBhcyAkbWFwayA9PiAkbWFwKSB7CiAgICAgICAgICAgICRleHBsb2RlWyRrZXldID0gc3RyX3JlcGxhY2UoKCdZQU1MTWFwJy4kbWFway4ncycpLCAkbWFwLCAkdmFsdWUpOwogICAgICAgICAgICAkdmFsdWUgPSAkZXhwbG9kZVska2V5XTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCgogICAgLy8gUmUtYWRkIHRoZSBzdHJpbmdzCiAgICBpZiAoIWVtcHR5KCRzYXZlZF9zdHJpbmdzKSkgewogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIHdoaWxlIChzdHJwb3MoJHZhbHVlLCdZQU1MU3RyaW5nJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAkZXhwbG9kZVska2V5XSA9IHByZWdfcmVwbGFjZSgnL1lBTUxTdHJpbmcvJywkc2F2ZWRfc3RyaW5nc1skc3RyaW5naV0sJHZhbHVlLCAxKTsKICAgICAgICAgIHVuc2V0KCRzYXZlZF9zdHJpbmdzWyRzdHJpbmdpXSk7CiAgICAgICAgICArKyRzdHJpbmdpOwogICAgICAgICAgJHZhbHVlID0gJGV4cGxvZGVbJGtleV07CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgJGZpbmlzaGVkID0gdHJ1ZTsKICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MU2VxJykgIT09IGZhbHNlKSB7CiAgICAgICAgJGZpbmlzaGVkID0gZmFsc2U7IGJyZWFrOwogICAgICB9CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MTWFwJykgIT09IGZhbHNlKSB7CiAgICAgICAgJGZpbmlzaGVkID0gZmFsc2U7IGJyZWFrOwogICAgICB9CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MU3RyaW5nJykgIT09IGZhbHNlKSB7CiAgICAgICAgJGZpbmlzaGVkID0gZmFsc2U7IGJyZWFrOwogICAgICB9CiAgICB9CiAgICBpZiAoJGZpbmlzaGVkKSBicmVhazsKCiAgICAkaSsrOwogICAgaWYgKCRpID4gMTApIAogICAgICBicmVhazsgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wcy4KICAgIH0KCiAgICByZXR1cm4gJGV4cGxvZGU7CiAgfQoKICBmdW5jdGlvbiBsaXRlcmFsQmxvY2tDb250aW51ZXMgKCRsaW5lLCAkbGluZUluZGVudCkgewogICAgaWYgKCF0cmltKCRsaW5lKSkgcmV0dXJuIHRydWU7CiAgICBpZiAoc3RybGVuKCRsaW5lKSAtIHN0cmxlbihsdHJpbSgkbGluZSkpID4gJGxpbmVJbmRlbnQpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgZnVuY3Rpb24gcmVmZXJlbmNlQ29udGVudHNCeUFsaWFzICgkYWxpYXMpIHsKICAgIGRvIHsKICAgICAgaWYgKCFpc3NldCgkdGhpcy0+U2F2ZWRHcm91cHNbJGFsaWFzXSkpIHsgZWNobyAiQmFkIGdyb3VwIG5hbWU6ICRhbGlhcy4iOyBicmVhazsgfQogICAgICAkZ3JvdXBQYXRoID0gJHRoaXMtPlNhdmVkR3JvdXBzWyRhbGlhc107CiAgICAgICR2YWx1ZSA9ICR0aGlzLT5yZXN1bHQ7CiAgICAgIGZvcmVhY2ggKCRncm91cFBhdGggYXMgJGspIHsKICAgICAgICAkdmFsdWUgPSAkdmFsdWVbJGtdOwogICAgICB9CiAgICB9IHdoaWxlIChmYWxzZSk7CiAgICByZXR1cm4gJHZhbHVlOwogIH0KCiAgZnVuY3Rpb24gYWRkQXJyYXlJbmxpbmUgKCRhcnJheSwgJGluZGVudCkgewogICAgICAkQ29tbW9uR3JvdXBQYXRoID0gJHRoaXMtPnBhdGg7CiAgICAgIGlmIChlbXB0eSAoJGFycmF5KSkgcmV0dXJuIGZhbHNlOwogICAgICAKICAgICAgZm9yZWFjaCAoJGFycmF5IGFzICRrID0+ICRfKSB7CiAgICAgICAgJHRoaXMtPmFkZEFycmF5KGFycmF5KCRrID0+ICRfKSwgJGluZGVudCk7CiAgICAgICAgJHRoaXMtPnBhdGggPSAkQ29tbW9uR3JvdXBQYXRoOwogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogIH0KCiAgZnVuY3Rpb24gYWRkQXJyYXkgKCRpbmNvbWluZ19kYXRhLCAkaW5jb21pbmdfaW5kZW50KSB7CgogICAvLyBwcmludF9yICgkaW5jb21pbmdfZGF0YSk7CgogICAgaWYgKGNvdW50ICgkaW5jb21pbmdfZGF0YSkgPiAxKQogICAgICByZXR1cm4gJHRoaXMtPmFkZEFycmF5SW5saW5lICgkaW5jb21pbmdfZGF0YSwgJGluY29taW5nX2luZGVudCk7CiAgICAKICAgICRrZXkgPSBrZXkgKCRpbmNvbWluZ19kYXRhKTsKICAgICR2YWx1ZSA9IGlzc2V0KCRpbmNvbWluZ19kYXRhWyRrZXldKSA/ICRpbmNvbWluZ19kYXRhWyRrZXldIDogbnVsbDsKICAgIGlmICgka2V5ID09PSAnX18hWUFNTFplcm8nKSAka2V5ID0gJzAnOwoKICAgIGlmICgkaW5jb21pbmdfaW5kZW50ID09IDAgJiYgISR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzICYmICEkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3IpIHsgLy8gU2hvcnRjdXQgZm9yIHJvb3QtbGV2ZWwgdmFsdWVzLgogICAgICBpZiAoJGtleSB8fCAka2V5ID09PSAnJyB8fCAka2V5ID09PSAnMCcpIHsKICAgICAgICAkdGhpcy0+cmVzdWx0WyRrZXldID0gJHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgICR0aGlzLT5yZXN1bHRbXSA9ICR2YWx1ZTsgZW5kICgkdGhpcy0+cmVzdWx0KTsgJGtleSA9IGtleSAoJHRoaXMtPnJlc3VsdCk7CiAgICAgIH0KICAgICAgJHRoaXMtPnBhdGhbJGluY29taW5nX2luZGVudF0gPSAka2V5OwogICAgICByZXR1cm47CiAgICB9CgoKICAgIAogICAgJGhpc3RvcnkgPSBhcnJheSgpOwogICAgLy8gVW5mb2xkaW5nIGlubmVyIGFycmF5IHRyZWUuCiAgICAkaGlzdG9yeVtdID0gJF9hcnIgPSAkdGhpcy0+cmVzdWx0OwogICAgZm9yZWFjaCAoJHRoaXMtPnBhdGggYXMgJGspIHsKICAgICAgJGhpc3RvcnlbXSA9ICRfYXJyID0gJF9hcnJbJGtdOwogICAgfQoKICAgIGlmICgkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbGlhcykgewogICAgICAkdmFsdWUgPSAkdGhpcy0+cmVmZXJlbmNlQ29udGVudHNCeUFsaWFzKCR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzKTsKICAgICAgJHRoaXMtPl9jb250YWluc0dyb3VwQWxpYXMgPSBmYWxzZTsKICAgIH0KCgogICAgLy8gQWRkaW5nIHN0cmluZyBvciBudW1lcmljIGtleSB0byB0aGUgaW5uZXJtb3N0IGxldmVsIG9yICR0aGlzLT5hcnIuCiAgICBpZiAoaXNfc3RyaW5nKCRrZXkpICYmICRrZXkgPT0gJzw8JykgewogICAgICBpZiAoIWlzX2FycmF5ICgkX2FycikpIHsgJF9hcnIgPSBhcnJheSAoKTsgfQogICAgICAkX2FyciA9IGFycmF5X21lcmdlICgkX2FyciwgJHZhbHVlKTsKICAgIH0gZWxzZSBpZiAoJGtleSB8fCAka2V5ID09PSAnJyB8fCAka2V5ID09PSAnMCcpIHsKICAgICAgJF9hcnJbJGtleV0gPSAkdmFsdWU7CiAgICB9IGVsc2UgewogICAgICBpZiAoIWlzX2FycmF5ICgkX2FycikpIHsgJF9hcnIgPSBhcnJheSAoJHZhbHVlKTsgJGtleSA9IDA7IH0KICAgICAgZWxzZSB7ICRfYXJyW10gPSAkdmFsdWU7IGVuZCAoJF9hcnIpOyAka2V5ID0ga2V5ICgkX2Fycik7IH0KICAgIH0KCiAgICAkcmV2ZXJzZV9wYXRoID0gYXJyYXlfcmV2ZXJzZSgkdGhpcy0+cGF0aCk7CiAgICAkcmV2ZXJzZV9oaXN0b3J5ID0gYXJyYXlfcmV2ZXJzZSAoJGhpc3RvcnkpOwogICAgJHJldmVyc2VfaGlzdG9yeVswXSA9ICRfYXJyOwogICAgJGNudCA9IGNvdW50KCRyZXZlcnNlX2hpc3RvcnkpIC0gMTsKICAgIGZvciAoJGkgPSAwOyAkaSA8ICRjbnQ7ICRpKyspIHsKICAgICAgJHJldmVyc2VfaGlzdG9yeVskaSsxXVskcmV2ZXJzZV9wYXRoWyRpXV0gPSAkcmV2ZXJzZV9oaXN0b3J5WyRpXTsKICAgIH0KICAgICR0aGlzLT5yZXN1bHQgPSAkcmV2ZXJzZV9oaXN0b3J5WyRjbnRdOwoKICAgICR0aGlzLT5wYXRoWyRpbmNvbWluZ19pbmRlbnRdID0gJGtleTsKCiAgICBpZiAoJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yKSB7CiAgICAgICR0aGlzLT5TYXZlZEdyb3Vwc1skdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3JdID0gJHRoaXMtPnBhdGg7CiAgICAgIGlmIChpc19hcnJheSAoJHZhbHVlKSkgewogICAgICAgICRrID0ga2V5ICgkdmFsdWUpOwogICAgICAgIGlmICghaXNfaW50ICgkaykpIHsKICAgICAgICAgICR0aGlzLT5TYXZlZEdyb3Vwc1skdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3JdWyRpbmNvbWluZ19pbmRlbnQgKyAyXSA9ICRrOwogICAgICAgIH0KICAgICAgfQogICAgICAkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3IgPSBmYWxzZTsKICAgIH0KCiAgfQoKICBmdW5jdGlvbiBzdGFydHNMaXRlcmFsQmxvY2sgKCRsaW5lKSB7CiAgICAkbGFzdENoYXIgPSBzdWJzdHIgKHRyaW0oJGxpbmUpLCAtMSk7CiAgICBpZiAoJGxhc3RDaGFyICE9ICc+JyAmJiAkbGFzdENoYXIgIT0gJ3wnKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoJGxhc3RDaGFyID09ICd8JykgcmV0dXJuICRsYXN0Q2hhcjsKICAgIC8vIEhUTUwgdGFncyBzaG91bGQgbm90IGJlIGNvdW50ZWQgYXMgbGl0ZXJhbCBibG9ja3MuCiAgICBpZiAocHJlZ19tYXRjaCAoJyM8Lio/PiQjJywgJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gJGxhc3RDaGFyOwogIH0KCiAgZnVuY3Rpb24gZ3JlZWRpbHlOZWVkTmV4dExpbmUoJGxpbmUpIHsKICAgICRsaW5lID0gdHJpbSAoJGxpbmUpOwogICAgaWYgKCFzdHJsZW4oJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoc3Vic3RyICgkbGluZSwgLTEsIDEpID09ICddJykgcmV0dXJuIGZhbHNlOwogICAgaWYgKCRsaW5lWzBdID09ICdbJykgcmV0dXJuIHRydWU7CiAgICBpZiAocHJlZ19tYXRjaCAoJyNeW146XSs/OlxzKlxbIycsICRsaW5lKSkgcmV0dXJuIHRydWU7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiBhZGRMaXRlcmFsTGluZSAoJGxpdGVyYWxCbG9jaywgJGxpbmUsICRsaXRlcmFsQmxvY2tTdHlsZSkgewogICAgJGxpbmUgPSAkdGhpcy0+c3RyaXBJbmRlbnQoJGxpbmUpOwogICAgJGxpbmUgPSBydHJpbSAoJGxpbmUsICJcclxuXHQgIikgLiAiXG4iOwogICAgaWYgKCRsaXRlcmFsQmxvY2tTdHlsZSA9PSAnfCcpIHsKICAgICAgcmV0dXJuICRsaXRlcmFsQmxvY2sgLiAkbGluZTsKICAgIH0KICAgIGlmIChzdHJsZW4oJGxpbmUpID09IDApCiAgICAgIHJldHVybiBydHJpbSgkbGl0ZXJhbEJsb2NrLCAnICcpIC4gIlxuIjsKICAgIGlmICgkbGluZSA9PSAiXG4iICYmICRsaXRlcmFsQmxvY2tTdHlsZSA9PSAnPicpIHsKICAgICAgcmV0dXJuIHJ0cmltICgkbGl0ZXJhbEJsb2NrLCAiIFx0IikgLiAiXG4iOwogICAgfQogICAgaWYgKCRsaW5lICE9ICJcbiIpCiAgICAgICRsaW5lID0gdHJpbSAoJGxpbmUsICJcclxuICIpIC4gIiAiOwogICAgcmV0dXJuICRsaXRlcmFsQmxvY2sgLiAkbGluZTsKICB9CgogICBmdW5jdGlvbiByZXZlcnRMaXRlcmFsUGxhY2VIb2xkZXIgKCRsaW5lQXJyYXksICRsaXRlcmFsQmxvY2spIHsKICAgICBmb3JlYWNoICgkbGluZUFycmF5IGFzICRrID0+ICRfKSB7CiAgICAgIGlmIChpc19hcnJheSgkXykpCiAgICAgICAgJGxpbmVBcnJheVska10gPSAkdGhpcy0+cmV2ZXJ0TGl0ZXJhbFBsYWNlSG9sZGVyICgkXywgJGxpdGVyYWxCbG9jayk7CiAgICAgIGVsc2UgaWYgKHN1YnN0cigkXywgLTEgKiBzdHJsZW4gKCR0aGlzLT5MaXRlcmFsUGxhY2VIb2xkZXIpKSA9PSAkdGhpcy0+TGl0ZXJhbFBsYWNlSG9sZGVyKQoJICAgICAgICRsaW5lQXJyYXlbJGtdID0gcnRyaW0gKCRsaXRlcmFsQmxvY2ssICIgXHJcbiIpOwogICAgIH0KICAgICByZXR1cm4gJGxpbmVBcnJheTsKICAgfQoKICBmdW5jdGlvbiBzdHJpcEluZGVudCAoJGxpbmUsICRpbmRlbnQgPSAtMSkgewogICAgaWYgKCRpbmRlbnQgPT0gLTEpICRpbmRlbnQgPSBzdHJsZW4oJGxpbmUpIC0gc3RybGVuKGx0cmltKCRsaW5lKSk7CiAgICByZXR1cm4gc3Vic3RyICgkbGluZSwgJGluZGVudCk7CiAgfQoKICBmdW5jdGlvbiBnZXRQYXJlbnRQYXRoQnlJbmRlbnQgKCRpbmRlbnQpIHsKICAgIGlmICgkaW5kZW50ID09IDApIHJldHVybiBhcnJheSgpOwogICAgJGxpbmVQYXRoID0gJHRoaXMtPnBhdGg7CiAgICBkbyB7CiAgICAgIGVuZCgkbGluZVBhdGgpOyAkbGFzdEluZGVudEluUGFyZW50UGF0aCA9IGtleSgkbGluZVBhdGgpOwogICAgICBpZiAoJGluZGVudCA8PSAkbGFzdEluZGVudEluUGFyZW50UGF0aCkgYXJyYXlfcG9wICgkbGluZVBhdGgpOwogICAgfSB3aGlsZSAoJGluZGVudCA8PSAkbGFzdEluZGVudEluUGFyZW50UGF0aCk7CiAgICByZXR1cm4gJGxpbmVQYXRoOwogIH0KCgogIGZ1bmN0aW9uIGNsZWFyQmlnZ2VyUGF0aFZhbHVlcyAoJGluZGVudCkgewoKCiAgICBpZiAoJGluZGVudCA9PSAwKSAkdGhpcy0+cGF0aCA9IGFycmF5KCk7CiAgICBpZiAoZW1wdHkgKCR0aGlzLT5wYXRoKSkgcmV0dXJuIHRydWU7CgogICAgZm9yZWFjaCAoJHRoaXMtPnBhdGggYXMgJGsgPT4gJF8pIHsKICAgICAgaWYgKCRrID4gJGluZGVudCkgdW5zZXQgKCR0aGlzLT5wYXRoWyRrXSk7CiAgICB9CgogICAgcmV0dXJuIHRydWU7CiAgfQoKCiAgZnVuY3Rpb24gaXNDb21tZW50ICgkbGluZSkgewogICAgaWYgKCEkbGluZSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCRsaW5lWzBdID09ICcjJykgcmV0dXJuIHRydWU7CiAgICBpZiAodHJpbSgkbGluZSwgIiBcclxuXHQiKSA9PSAnLS0tJykgcmV0dXJuIHRydWU7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiBpc0VtcHR5ICgkbGluZSkgewogICAgcmV0dXJuICh0cmltICgkbGluZSkgPT09ICcnKTsKICB9CgoKICBmdW5jdGlvbiBpc0FycmF5RWxlbWVudCAoJGxpbmUpIHsKICAgIGlmICghJGxpbmUpIHJldHVybiBmYWxzZTsKICAgIGlmICgkbGluZVswXSAhPSAnLScpIHJldHVybiBmYWxzZTsKICAgIGlmIChzdHJsZW4gKCRsaW5lKSA+IDMpCiAgICAgIGlmIChzdWJzdHIoJGxpbmUsMCwzKSA9PSAnLS0tJykgcmV0dXJuIGZhbHNlOwogICAgCiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIGZ1bmN0aW9uIGlzSGFzaEVsZW1lbnQgKCRsaW5lKSB7CiAgICByZXR1cm4gc3RycG9zKCRsaW5lLCAnOicpOwogIH0KCiAgZnVuY3Rpb24gaXNMaXRlcmFsICgkbGluZSkgewogICAgaWYgKCR0aGlzLT5pc0FycmF5RWxlbWVudCgkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIGlmICgkdGhpcy0+aXNIYXNoRWxlbWVudCgkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCgogIGZ1bmN0aW9uIHVucXVvdGUgKCR2YWx1ZSkgewogICAgaWYgKCEkdmFsdWUpIHJldHVybiAkdmFsdWU7CiAgICBpZiAoIWlzX3N0cmluZygkdmFsdWUpKSByZXR1cm4gJHZhbHVlOwogICAgaWYgKCR2YWx1ZVswXSA9PSAnXCcnKSByZXR1cm4gdHJpbSAoJHZhbHVlLCAnXCcnKTsKICAgIGlmICgkdmFsdWVbMF0gPT0gJyInKSByZXR1cm4gdHJpbSAoJHZhbHVlLCAnIicpOwogICAgcmV0dXJuICR2YWx1ZTsKICB9CgogIGZ1bmN0aW9uIHN0YXJ0c01hcHBlZFNlcXVlbmNlICgkbGluZSkgewogICAgcmV0dXJuICgkbGluZVswXSA9PSAnLScgJiYgc3Vic3RyICgkbGluZSwgLTEsIDEpID09ICc6Jyk7CiAgfQoKICBmdW5jdGlvbiByZXR1cm5NYXBwZWRTZXF1ZW5jZSAoJGxpbmUpIHsKICAgICRhcnJheSA9IGFycmF5KCk7CiAgICAka2V5ICAgICAgICAgPSAkdGhpcy0+dW5xdW90ZSh0cmltKHN1YnN0cigkbGluZSwxLC0xKSkpOwogICAgJGFycmF5WyRrZXldID0gYXJyYXkoKTsKICAgICR0aGlzLT5kZWxheWVkUGF0aCA9IGFycmF5KHN0cnBvcyAoJGxpbmUsICRrZXkpICsgJHRoaXMtPmluZGVudCA9PiAka2V5KTsKICAgIHJldHVybiBhcnJheSgkYXJyYXkpOwogIH0KCiAgZnVuY3Rpb24gcmV0dXJuTWFwcGVkVmFsdWUgKCRsaW5lKSB7CiAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgJGtleSAgICAgICAgID0gJHRoaXMtPnVucXVvdGUgKHRyaW0oc3Vic3RyKCRsaW5lLDAsLTEpKSk7CiAgICAkYXJyYXlbJGtleV0gPSAnJzsKICAgIHJldHVybiAkYXJyYXk7CiAgfQoKICBmdW5jdGlvbiBzdGFydHNNYXBwZWRWYWx1ZSAoJGxpbmUpIHsKICAgIHJldHVybiAoc3Vic3RyICgkbGluZSwgLTEsIDEpID09ICc6Jyk7CiAgfQogIAogIGZ1bmN0aW9uIGlzUGxhaW5BcnJheSAoJGxpbmUpIHsKICAgIHJldHVybiAoJGxpbmVbMF0gPT0gJ1snICYmIHN1YnN0ciAoJGxpbmUsIC0xLCAxKSA9PSAnXScpOwogIH0KICAKICBmdW5jdGlvbiByZXR1cm5QbGFpbkFycmF5ICgkbGluZSkgewogICAgcmV0dXJuICR0aGlzLT5fdG9UeXBlKCRsaW5lKTsgCiAgfSAgCgogIGZ1bmN0aW9uIHJldHVybktleVZhbHVlUGFpciAoJGxpbmUpIHsKICAgICRhcnJheSA9IGFycmF5KCk7CiAgICAka2V5ID0gJyc7CiAgICBpZiAoc3RycG9zICgkbGluZSwgJzonKSkgewogICAgICAvLyBJdCdzIGEga2V5L3ZhbHVlIHBhaXIgbW9zdCBsaWtlbHkKICAgICAgLy8gSWYgdGhlIGtleSBpcyBpbiBkb3VibGUgcXVvdGVzIHB1bGwgaXQgb3V0CiAgICAgIGlmICgoJGxpbmVbMF0gPT0gJyInIHx8ICRsaW5lWzBdID09ICInIikgJiYgcHJlZ19tYXRjaCgnL14oWyJcJ10oLiopWyJcJ10oXHMpKjopLycsJGxpbmUsJG1hdGNoZXMpKSB7CiAgICAgICAgJHZhbHVlID0gdHJpbShzdHJfcmVwbGFjZSgkbWF0Y2hlc1sxXSwnJywkbGluZSkpOwogICAgICAgICRrZXkgICA9ICRtYXRjaGVzWzJdOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIERvIHNvbWUgZ3Vlc3N3b3JrIGFzIHRvIHRoZSBrZXkgYW5kIHRoZSB2YWx1ZQogICAgICAgICRleHBsb2RlID0gZXhwbG9kZSgnOicsJGxpbmUpOwogICAgICAgICRrZXkgICAgID0gdHJpbSgkZXhwbG9kZVswXSk7CiAgICAgICAgYXJyYXlfc2hpZnQoJGV4cGxvZGUpOwogICAgICAgICR2YWx1ZSAgID0gdHJpbShpbXBsb2RlKCc6JywkZXhwbG9kZSkpOwogICAgICB9CiAgICAgIC8vIFNldCB0aGUgdHlwZSBvZiB0aGUgdmFsdWUuICBJbnQsIHN0cmluZywgZXRjCiAgICAgICR2YWx1ZSA9ICR0aGlzLT5fdG9UeXBlKCR2YWx1ZSk7CiAgICAgIGlmICgka2V5ID09PSAnMCcpICRrZXkgPSAnX18hWUFNTFplcm8nOwogICAgICAkYXJyYXlbJGtleV0gPSAkdmFsdWU7CiAgICB9IGVsc2UgewogICAgICAkYXJyYXkgPSBhcnJheSAoJGxpbmUpOwogICAgfQogICAgcmV0dXJuICRhcnJheTsKCiAgfQoKCiAgZnVuY3Rpb24gcmV0dXJuQXJyYXlFbGVtZW50ICgkbGluZSkgewogICAgIGlmIChzdHJsZW4oJGxpbmUpIDw9IDEpIHJldHVybiBhcnJheShhcnJheSgpKTsgLy8gV2VpcmQgJSkKICAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgICR2YWx1ZSAgID0gdHJpbShzdWJzdHIoJGxpbmUsMSkpOwogICAgICR2YWx1ZSAgID0gJHRoaXMtPl90b1R5cGUoJHZhbHVlKTsKICAgICAkYXJyYXlbXSA9ICR2YWx1ZTsKICAgICByZXR1cm4gJGFycmF5OwogIH0KCgogIGZ1bmN0aW9uIG5vZGVDb250YWluc0dyb3VwICgkbGluZSkgeyAgICAKICAgICRzeW1ib2xzRm9yUmVmZXJlbmNlID0gJ0EtejAtOV9cLSc7CiAgICBpZiAoc3RycG9zKCRsaW5lLCAnJicpID09PSBmYWxzZSAmJiBzdHJwb3MoJGxpbmUsICcqJykgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7IC8vIFBsZWFzZSBkaWUgZmFzdCA7LSkKICAgIGlmICgkbGluZVswXSA9PSAnJicgJiYgcHJlZ19tYXRjaCgnL14oJlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKykvJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgaWYgKCRsaW5lWzBdID09ICcqJyAmJiBwcmVnX21hdGNoKCcvXihcKlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKykvJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgaWYgKHByZWdfbWF0Y2goJy8oJlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKykkLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmIChwcmVnX21hdGNoKCcvKFwqWycuJHN5bWJvbHNGb3JSZWZlcmVuY2UuJ10rJCkvJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgaWYgKHByZWdfbWF0Y2ggKCcjXlxzKjw8XHMqOlxzKihcKlteXHNdKykuKiQjJywgJGxpbmUsICRtYXRjaGVzKSkgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgcmV0dXJuIGZhbHNlOwoKICB9CgogIGZ1bmN0aW9uIGFkZEdyb3VwICgkbGluZSwgJGdyb3VwKSB7CiAgICBpZiAoJGdyb3VwWzBdID09ICcmJykgJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yID0gc3Vic3RyICgkZ3JvdXAsIDEpOwogICAgaWYgKCRncm91cFswXSA9PSAnKicpICR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzID0gc3Vic3RyICgkZ3JvdXAsIDEpOwogICAgLy9wcmludF9yICgkdGhpcy0+cGF0aCk7CiAgfQoKICBmdW5jdGlvbiBzdHJpcEdyb3VwICgkbGluZSwgJGdyb3VwKSB7CiAgICAkbGluZSA9IHRyaW0oc3RyX3JlcGxhY2UoJGdyb3VwLCAnJywgJGxpbmUpKTsKICAgIHJldHVybiAkbGluZTsKICB9Cn0KCi8vIEVuYWJsZSB1c2Ugb2YgU3B5YyBmcm9tIGNvbW1hbmQgbGluZQovLyBUaGUgc3ludGF4IGlzIHRoZSBmb2xsb3dpbmc6IHBocCBzcHljLnBocCBzcHljLnlhbWwKCmRlZmluZSAoJ1NQWUNfRlJPTV9DT01NQU5EX0xJTkUnLCBmYWxzZSk7CgpkbyB7CiAgaWYgKCFTUFlDX0ZST01fQ09NTUFORF9MSU5FKSBicmVhazsKICBpZiAoZW1wdHkgKCRfU0VSVkVSWydhcmdjJ10pIHx8ICRfU0VSVkVSWydhcmdjJ10gPCAyKSBicmVhazsKICBpZiAoZW1wdHkgKCRfU0VSVkVSWydQSFBfU0VMRiddKSB8fCAkX1NFUlZFUlsnUEhQX1NFTEYnXSAhPSAnc3B5Yy5waHAnKSBicmVhazsKICAkZmlsZSA9ICRhcmd2WzFdOwogIHByaW50ZiAoIlNweWMgbG9hZGluZyBmaWxlOiAlc1xuIiwgJGZpbGUpOwogIHByaW50X3IgKHNweWNfbG9hZF9maWxlICgkZmlsZSkpOwp9IHdoaWxlICgwKTs8P3BocAoKcGhwNXRvNCAoIi4uL3NweWMucGhwIiwgJ3NweWMtbGF0ZXN0LnBocDQnKTsKCmZ1bmN0aW9uIHBocDV0bzQgKCRzcmMsICRkZXN0KSB7CiAgJGNvZGUgPSBmaWxlX2dldF9jb250ZW50cyAoJHNyYyk7CiAgJGNvZGUgPSBwcmVnX3JlcGxhY2UgKCcjKHB1YmxpY3xwcml2YXRlfHByb3RlY3RlZClccytcJCNpJywgJ3ZhciBcJCcsICRjb2RlKTsKICAkY29kZSA9IHByZWdfcmVwbGFjZSAoJyMocHVibGljfHByaXZhdGV8cHJvdGVjdGVkKVxzK3N0YXRpY1xzK1wkI2knLCAndmFyIFwkJywgJGNvZGUpOwogICRjb2RlID0gcHJlZ19yZXBsYWNlICgnIyhwdWJsaWN8cHJpdmF0ZXxwcm90ZWN0ZWQpXHMrZnVuY3Rpb24jaScsICdmdW5jdGlvbicsICRjb2RlKTsKICAkY29kZSA9IHByZWdfcmVwbGFjZSAoJyMocHVibGljfHByaXZhdGV8cHJvdGVjdGVkKVxzK3N0YXRpY1xzK2Z1bmN0aW9uI2knLCAnZnVuY3Rpb24nLCAkY29kZSk7CiAgJGNvZGUgPSBwcmVnX3JlcGxhY2UgKCcjdGhyb3cgbmV3IEV4Y2VwdGlvblxcKChbXildKilcXCkjaScsICd0cmlnZ2VyX2Vycm9yKCQxLEVfVVNFUl9FUlJPUiknLCAkY29kZSk7CiAgJGNvZGUgPSBzdHJfcmVwbGFjZSAoJ3NlbGY6OicsICckdGhpcy0+JywgJGNvZGUpOwogICRmID0gZm9wZW4gKCRkZXN0LCAndycpOwogIGZ3cml0ZSgkZiwgJGNvZGUpOwogIGZjbG9zZSAoJGYpOwogIHByaW50ICJXcml0dGVuIHRvICRkZXN0LlxuIjsKfTw/cGhwCiMKIyAgICBTIFAgWSBDCiMgICAgICBhIHNpbXBsZSBwaHAgeWFtbCBjbGFzcwojICAgdjAuMwojCiMgYXV0aG9yOiBbY2hyaXMgd2Fuc3RyYXRoLCBjaHJpc0Bvem1tLm9yZ10KIyB3ZWJzaXRlczogW2h0dHA6Ly93d3cueWFtbC5vcmcsIGh0dHA6Ly9zcHljLnNvdXJjZWZvcmdlLm5ldC9dCiMgbGljZW5zZTogW01JVCBMaWNlbnNlLCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocF0KIyBjb3B5cmlnaHQ6IChjKSAyMDA1LTIwMDYgQ2hyaXMgV2Fuc3RyYXRoCiMKIyBXZSdyZSBnb25uYSBsb2FkIGEgZmlsZSBpbnRvIG1lbW9yeSBhbmQgc2VlIGlmIHdlIGdldCB3aGF0IHdlIGV4cGVjdC4KIyBJZiBub3QsIHdlJ3JlIGdvbm5hIGNvbXBsYWluLgojCiMgUHJldHR5IGxvLWZpLiAgTGV0J3Mgc2VlIGlmIHdlIGNhbid0IGdldCBzb21lIHVuaXQgdGVzdGluZyBnb2luZyBpbiB0aGUgbmV4dCwKIyBJIGR1bm5vLCAyMCBtb250aHM/ICBBbHJpZ2h0LiAgR28gdGVhbS4KIwoKZXJyb3JfcmVwb3J0aW5nKEVfQUxMKTsKCmluY2x1ZGUoJ3NweWMucGhwNCcpOwoKJHlhbWwgPSBTcHljOjpZQU1MTG9hZCgnLi4vc3B5Yy55YW1sJyk7CgovLyBwcmludF9yICgkeWFtbCk7CgojIEFkZGVkIGluIC4yCmlmICgkeWFtbFsxMDQwXSAhPSAiT29vLCBhIG51bWVyaWMga2V5ISIpCglkaWUoJ0tleTogMTA0MCBmYWlsZWQnKTsKCiMgVGVzdCBtYXBwaW5ncyAvIHR5cGVzCmlmICgkeWFtbFsnU3RyaW5nJ10gIT0gIkFueW9uZSdzIG5hbWUsIHJlYWxseS4iKQoJZGllKCdLZXk6IFN0cmluZyBmYWlsZWQnKTsKCmlmICgkeWFtbFsnSW50J10gIT09IDEzKQoJZGllKCdLZXk6IEludCBmYWlsZWQnKTsKCmlmICgkeWFtbFsnVHJ1ZSddICE9PSB0cnVlKQoJZGllKCdLZXk6IFRydWUgZmFpbGVkJyk7CgppZiAoJHlhbWxbJ0ZhbHNlJ10gIT09IGZhbHNlKQoJZGllKCdLZXk6IEZhbHNlIGZhaWxlZCcpOwoKaWYgKCR5YW1sWydaZXJvJ10gIT09IDApCglkaWUoJ0tleTogWmVybyBmYWlsZWQnKTsKCmlmIChpc3NldCgkeWFtbFsnTnVsbCddKSkKCWRpZSgnS2V5OiBOdWxsIGZhaWxlZCcpOwoKaWYgKCR5YW1sWydGbG9hdCddICE9PSA1LjM0KQoJZGllKCdLZXk6IEZsb2F0IGZhaWxlZCcpOwoKCiMgVGVzdCBzZXF1ZW5jZXMKaWYgKCR5YW1sWzBdICE9ICJQSFAgQ2xhc3MiKQoJZGllKCdTZXF1ZW5jZSAwIGZhaWxlZCcpOwoKaWYgKCR5YW1sWzFdICE9ICJCYXNpYyBZQU1MIExvYWRlciIpCglkaWUoJ1NlcXVlbmNlIDEgZmFpbGVkJyk7CgppZiAoJHlhbWxbMl0gIT0gIlZlcnkgQmFzaWMgWUFNTCBEdW1wZXIiKQoJZGllKCdTZXF1ZW5jZSAyIGZhaWxlZCcpOwoKIyBBIHNlcXVlbmNlIG9mIGEgc2VxdWVuY2UKaWYgKCR5YW1sWzNdICE9IGFycmF5KCJZQU1MIGlzIHNvIGVhc3kgdG8gbGVhcm4uIiwKCQkJCQkJCQkJCQkiWW91ciBjb25maWcgZmlsZXMgd2lsbCBuZXZlciBiZSB0aGUgc2FtZS4iKSkKCWRpZSgnU2VxdWVuY2UgMyBmYWlsZWQnKTsKCiMgU2VxdWVuY2Ugb2YgbWFwcGluZ3MKaWYgKCR5YW1sWzRdICE9IGFycmF5KCJjcHUiID0+ICIxLjVnaHoiLCAicmFtIiA9PiAiMSBnaWciLAoJCQkJCQkJCQkJCSJvcyIgPT4gIm9zIHggMTAuNC4xIikpCglkaWUoJ1NlcXVlbmNlIDQgZmFpbGVkJyk7CgojIE1hcHBlZCBzZXF1ZW5jZQppZiAoJHlhbWxbJ2RvbWFpbnMnXSAhPSBhcnJheSgieWFtbC5vcmciLCAicGhwLm5ldCIpKQoJZGllKCJLZXk6ICdkb21haW5zJyBmYWlsZWQiKTsKCiMgQSBzZXF1ZW5jZSBsaWtlIHRoaXMuCmlmICgkeWFtbFs1XSAhPSBhcnJheSgicHJvZ3JhbSIgPT4gIkFkaXVtIiwgInBsYXRmb3JtIiA9PiAiT1MgWCIsCgkJCQkJCQkJCQkJInR5cGUiID0+ICJDaGF0IENsaWVudCIpKQoJZGllKCdTZXF1ZW5jZSA1IGZhaWxlZCcpOwoKIyBBIGZvbGRlZCBibG9jayBhcyBhIG1hcHBlZCB2YWx1ZQppZiAoJHlhbWxbJ25vIHRpbWUnXSAhPSAiVGhlcmUgaXNuJ3QgYW55IHRpbWUgZm9yIHlvdXIgdHJpY2tzIVxuRG8geW91IHVuZGVyc3RhbmQ/IikKCWRpZSgiS2V5OiAnbm8gdGltZScgZmFpbGVkIik7CgojIEEgbGl0ZXJhbCBibG9jayBhcyBhIG1hcHBlZCB2YWx1ZQppZiAoJHlhbWxbJ3NvbWUgdGltZSddICE9ICJUaGVyZSBpcyBub3RoaW5nIGJ1dCB0aW1lXG5mb3IgeW91ciB0cmlja3MuIikKCWRpZSgiS2V5OiAnc29tZSB0aW1lJyBmYWlsZWQiKTsKCiMgQ3JhenkgY29tYmluYXRpb25zCmlmICgkeWFtbFsnZGF0YWJhc2VzJ10gIT0gYXJyYXkoIGFycmF5KCJuYW1lIiA9PiAic3BhcnRhbiIsICJub3RlcyIgPT4KCQkJCQkJCQkJCQkJCQkJCQkJCWFycmF5KCAiTmVlZHMgdG8gYmUgYmFja2VkIHVwIiwKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCSAiTmVlZHMgdG8gYmUgbm9ybWFsaXplZCIgKSwKCQkJCQkJCQkJCQkJCQkJCQkJCSAidHlwZSIgPT4gIm15c3FsIiApKSkKICBkaWUoIktleTogJ2RhdGFiYXNlcycgZmFpbGVkIik7CgojIFlvdSBjYW4gYmUgYSBiaXQgdHJpY2t5CmlmICgkeWFtbFsiaWY6IHlvdSdkIl0gIT0gImxpa2UiKQoJZGllKCJLZXk6ICdpZjogeW91XCdkJyBmYWlsZWQiKTsKCiMgSW5saW5lIHNlcXVlbmNlcwppZiAoJHlhbWxbNl0gIT0gYXJyYXkoIk9uZSIsICJUd28iLCAiVGhyZWUiLCAiRm91ciIpKQoJZGllKCJTZXF1ZW5jZSA2IGZhaWxlZCIpOwoKIyBOZXN0ZWQgSW5saW5lIFNlcXVlbmNlcwppZiAoJHlhbWxbN10gIT0gYXJyYXkoIk9uZSIsIGFycmF5KCJUd28iLCAiQW5kIiwgIlRocmVlIiksICJGb3VyIiwgIkZpdmUiKSkKCWRpZSgiU2VxdWVuY2UgNyBmYWlsZWQiKTsKCiMgTmVzdGVkIE5lc3RlZCBJbmxpbmUgU2VxdWVuY2VzCmlmICgkeWFtbFs4XSAhPSBhcnJheSggIlRoaXMiLCBhcnJheSgiSXMiLCAiR2V0dGluZyIsIGFycmF5KCJSaWRpY3Vsb3VzIiwgIkd1eXMiKSksCgkJCQkJCQkJCSJTZXJpb3VzbHkiLCBhcnJheSgiU2hvdyIsICJNZXJjeSIpKSkKCWRpZSgiU2VxdWVuY2UgOCBmYWlsZWQiKTsKCiMgSW5saW5lIG1hcHBpbmdzCmlmICgkeWFtbFs5XSAhPSBhcnJheSgibmFtZSIgPT4gImNocmlzIiwgImFnZSIgPT4gInlvdW5nIiwgImJyYW5kIiA9PiAibHVja3kgc3RyaWtlIikpCglkaWUoIlNlcXVlbmNlIDkgZmFpbGVkIik7CgojIE5lc3RlZCBpbmxpbmUgbWFwcGluZ3MKaWYgKCR5YW1sWzEwXSAhPSBhcnJheSgibmFtZSIgPT4gIm1hcmsiLCAiYWdlIiA9PiAib2xkZXIgdGhhbiBjaHJpcyIsCgkJCQkJCQkJCQkJICJicmFuZCIgPT4gYXJyYXkoIm1hcmxib3JvIiwgImx1Y2t5IHN0cmlrZSIpKSkKCWRpZSgiU2VxdWVuY2UgMTAgZmFpbGVkIik7CgojIFJlZmVyZW5jZXMgLS0gdGhleSdyZSBzaGFreSwgYnV0IGZ1bmN0aW9uYWwKaWYgKCR5YW1sWydkeW5hbWljIGxhbmd1YWdlcyddICE9IGFycmF5KCdQZXJsJywgJ1B5dGhvbicsICdQSFAnLCAnUnVieScpKQoJZGllKCJLZXk6ICdkeW5hbWljIGxhbmd1YWdlcycgZmFpbGVkIik7CgppZiAoJHlhbWxbJ2NvbXBpbGVkIGxhbmd1YWdlcyddICE9IGFycmF5KCdDL0MrKycsICdKYXZhJykpCglkaWUoIktleTogJ2NvbXBpbGVkIGxhbmd1YWdlcycgZmFpbGVkIik7CgppZiAoJHlhbWxbJ2FsbCBsYW5ndWFnZXMnXSAhPSBhcnJheSgKCQkJCQkJCQkJCQkJCQkJCQkJYXJyYXkoJ1BlcmwnLCAnUHl0aG9uJywgJ1BIUCcsICdSdWJ5JyksCgkJCQkJCQkJCQkJCQkJCQkJCWFycmF5KCdDL0MrKycsICdKYXZhJykKCQkJCQkJCQkJCQkJCQkJCQkgKSkKCWRpZSgiS2V5OiAnYWxsIGxhbmd1YWdlcycgZmFpbGVkIik7CgojIEFkZGVkIGluIC4yLjI6IEVzY2FwZWQgcXVvdGVzCmlmICgkeWFtbFsxMV0gIT0gInlvdSBrbm93LCB0aGlzIHNob3VsZG4ndCB3b3JrLiAgYnV0IGl0IGRvZXMuIikKCWRpZSgiU2VxdWVuY2UgMTEgZmFpbGVkLiIpOwoKaWYgKCR5YW1sWzEyXSAhPSAidGhhdCdzIG15IHZhbHVlLiIpCglkaWUoIlNlcXVlbmNlIDEyIGZhaWxlZC4iKTsKCmlmICgkeWFtbFsxM10gIT0gImFnYWluLCB0aGF0J3MgbXkgdmFsdWUuIikKCWRpZSgiU2VxdWVuY2UgMTMgZmFpbGVkLiIpOwoKaWYgKCR5YW1sWzE0XSAhPSAiaGVyZSdzIHRvIFwicXVvdGVzXCIsIGJvc3MuIikKCWRpZSgiU2VxdWVuY2UgMTQgZmFpbGVkLiIpOwoKaWYgKCR5YW1sWzE1XSAhPSBhcnJheSggJ25hbWUnID0+ICJGb28sIEJhcidzIiwgJ2FnZScgPT4gMjApKQoJZGllKCJTZXF1ZW5jZSAxNSBmYWlsZWQuIik7CgppZiAoJHlhbWxbMTZdICE9IGFycmF5KCAwID0+ICJhIiwgMSA9PiBhcnJheSAoMCA9PiAxLCAxID0+IDIpLCAyID0+ICJiIikpCglkaWUoIlNlcXVlbmNlIDE2IGZhaWxlZC4iKTsKCmlmICgkeWFtbFsnZW5kbG9vcCddICE9ICJEb2VzIHRoaXMgbGluZSBpbiB0aGUgZW5kIGluZGVlZCBtYWtlIFNweWMgZ28gdG8gYW4gaW5maW5pdGUgbG9vcD8iKQoJZGllKCJbZW5kbG9vcF0gZmFpbGVkLiIpOwoKCnByaW50ICJzcHljLnlhbWwgcGFyc2VkIGNvcnJlY3RseVxuIjsKCj8+PD9waHAKCi8qKgogKiBUcmFuc2Zvcm1zIGEgd3AtY29uZmlnLnBocCBmaWxlLgogKi8KY2xhc3MgV1BDb25maWdUcmFuc2Zvcm1lciB7CgkvKioKCSAqIEFwcGVuZCB0byBlbmQgb2YgZmlsZQoJICovCgljb25zdCBBTkNIT1JfRU9GID0gJ0VPRic7CgoJLyoqCgkgKiBQYXRoIHRvIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICR3cF9jb25maWdfcGF0aDsKCgkvKioKCSAqIE9yaWdpbmFsIHNvdXJjZSBvZiB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkd3BfY29uZmlnX3NyYzsKCgkvKioKCSAqIEFycmF5IG9mIHBhcnNlZCBjb25maWdzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICR3cF9jb25maWdzID0gYXJyYXkoKTsKCgkvKioKCSAqIEluc3RhbnRpYXRlcyB0aGUgY2xhc3Mgd2l0aCBhIHZhbGlkIHdwLWNvbmZpZy5waHAuCgkgKgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHdwLWNvbmZpZy5waHAgZmlsZSBpcyBtaXNzaW5nLgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHdwLWNvbmZpZy5waHAgZmlsZSBpcyBub3Qgd3JpdGFibGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd3BfY29uZmlnX3BhdGggUGF0aCB0byBhIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkd3BfY29uZmlnX3BhdGggKSB7CgkJJGJhc2VuYW1lID0gYmFzZW5hbWUoICR3cF9jb25maWdfcGF0aCApOwoKCQlpZiAoICEgZmlsZV9leGlzdHMoICR3cF9jb25maWdfcGF0aCApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAieyRiYXNlbmFtZX0gZG9lcyBub3QgZXhpc3QuIiApOwoJCX0KCgkJaWYgKCAhIGlzX3dyaXRhYmxlKCAkd3BfY29uZmlnX3BhdGggKSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggInskYmFzZW5hbWV9IGlzIG5vdCB3cml0YWJsZS4iICk7CgkJfQoKCQkkdGhpcy0+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+ICR2YXJpYWJsZXNbMF1bICRpbmRleCBdLAoJCQkJCSd2YWx1ZScgPT4gJHZhcmlhYmxlc1s0XVsgJGluZGV4IF0sCgkJCQkJJ3BhcnRzJyA9PiBhcnJheSgKCQkJCQkJJHZhcmlhYmxlc1sxXVsgJGluZGV4IF0sCgkJCQkJCSR2YXJpYWJsZXNbM11bICRpbmRleCBdLAoJCQkJCSksCgkJCQkpOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGNvbmZpZ3M7Cgl9CgoJLyoqCgkgKiBTYXZlcyBuZXcgY29udGVudHMgdG8gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbiBJZiB0aGUgY29uZmlnIGZpbGUgY29udGVudCBwcm92aWRlZCBpcyBlbXB0eS4KCSAqIEB0aHJvd3MgRXhjZXB0aW9uIElmIHRoZXJlIGlzIGEgZmFpbHVyZSB3aGVuIHNhdmluZyB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnRzIE5ldyBjb25maWcgY29udGVudHMuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzYXZlKCAkY29udGVudHMgKSB7CgkJaWYgKCAhIHRyaW0oICRjb250ZW50cyApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnQ2Fubm90IHNhdmUgdGhlIGNvbmZpZyBmaWxlIHdpdGggZW1wdHkgY29udGVudHMuJyApOwoJCX0KCgkJaWYgKCAkY29udGVudHMgPT09ICR0aGlzLT53cF9jb25maWdfc3JjICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkcmVzdWx0ID0gZmlsZV9wdXRfY29udGVudHMoICR0aGlzLT53cF9jb25maWdfcGF0aCwgJGNvbnRlbnRzLCBMT0NLX0VYICk7CgoJCWlmICggZmFsc2UgPT09ICRyZXN1bHQgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICdGYWlsZWQgdG8gdXBkYXRlIHRoZSBjb25maWcgZmlsZS4nICk7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBTY2hlZHVsZXMsIHJ1bnMsIGFuZCBkZWxldGVzIFdQLUNyb24gZXZlbnRzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBTY2hlZHVsZSBhIG5ldyBjcm9uIGV2ZW50CiAqICAgICAkIHdwIGNyb24gZXZlbnQgc2NoZWR1bGUgY3Jvbl90ZXN0CiAqICAgICBTdWNjZXNzOiBTY2hlZHVsZWQgZXZlbnQgd2l0aCBob29rICdjcm9uX3Rlc3QnIGZvciAyMDE2LTA1LTMxIDEwOjE5OjE2IEdNVC4KICoKICogICAgICMgUnVuIGFsbCBjcm9uIGV2ZW50cyBkdWUgcmlnaHQgbm93CiAqICAgICAkIHdwIGNyb24gZXZlbnQgcnVuIC0tZHVlLW5vdwogKiAgICAgU3VjY2VzczogRXhlY3V0ZWQgYSB0b3RhbCBvZiAyIGNyb24gZXZlbnRzLgogKgogKiAgICAgIyBEZWxldGUgYWxsIHNjaGVkdWxlZCBjcm9uIGV2ZW50cyBmb3IgdGhlIGdpdmVuIGhvb2sKICogICAgICQgd3AgY3JvbiBldmVudCBkZWxldGUgY3Jvbl90ZXN0CiAqICAgICBTdWNjZXNzOiBEZWxldGVkIDIgaW5zdGFuY2VzIG9mIHRoZSBjcm9uIGV2ZW50ICdjcm9uX3Rlc3QnLgogKgogKiAgICAgIyBMaXN0IHNjaGVkdWxlZCBjcm9uIGV2ZW50cyBpbiBKU09OCiAqICAgICAkIHdwIGNyb24gZXZlbnQgbGlzdCAtLWZpZWxkcz1ob29rLG5leHRfcnVuIC0tZm9ybWF0PWpzb24KICogICAgIFt7Imhvb2siOiJ3cF92ZXJzaW9uX2NoZWNrIiwibmV4dF9ydW4iOiIyMDE2LTA1LTMxIDEwOjE1OjEzIn0seyJob29rIjoid3BfdXBkYXRlX3BsdWdpbnMiLCJuZXh0X3J1biI6IjIwMTYtMDUtMzEgMTA6MTU6MTMifSx7Imhvb2siOiJ3cF91cGRhdGVfdGhlbWVzIiwibmV4dF9ydW4iOiIyMDE2LTA1LTMxIDEwOjE1OjE0In1dCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ3Jvbl9FdmVudF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGZpZWxkcyA9IGFycmF5KAoJCSdob29rJywKCQknbmV4dF9ydW5fZ210JywKCQknbmV4dF9ydW5fcmVsYXRpdmUnLAoJCSdyZWN1cnJlbmNlJywKCSk7CgoJcHJpdmF0ZSBzdGF0aWMgJHRpbWVfZm9ybWF0ID0gJ1ktbS1kIEg6aTpzJzsKCgkvKioKCSAqIExpc3RzIHNjaGVkdWxlZCBjcm9uIGV2ZW50cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggZXZlbnQuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0gaWRzCgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIGNyb24gZXZlbnQ6CgkgKiAqIGhvb2sKCSAqICogbmV4dF9ydW5fZ210CgkgKiAqIG5leHRfcnVuX3JlbGF0aXZlCgkgKiAqIHJlY3VycmVuY2UKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICogKiB0aW1lCgkgKiAqIHNpZwoJICogKiBhcmdzCgkgKiAqIHNjaGVkdWxlCgkgKiAqIGludGVydmFsCgkgKiAqIG5leHRfcnVuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IHNjaGVkdWxlZCBjcm9uIGV2ZW50cwoJICogICAgICQgd3AgY3JvbiBldmVudCBsaXN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBob29rICAgICAgICAgICAgICB8IG5leHRfcnVuX2dtdCAgICAgICAgfCBuZXh0X3J1bl9yZWxhdGl2ZSAgIHwgcmVjdXJyZW5jZSB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKiAgICAgfCB3cF92ZXJzaW9uX2NoZWNrICB8IDIwMTYtMDUtMzEgMjI6MTU6MTMgfCAxMSBob3VycyA1NyBtaW51dGVzIHwgMTIgaG91cnMgICB8CgkgKiAgICAgfCB3cF91cGRhdGVfcGx1Z2lucyB8IDIwMTYtMDUtMzEgMjI6MTU6MTMgfCAxMSBob3VycyA1NyBtaW51dGVzIHwgMTIgaG91cnMgICB8CgkgKiAgICAgfCB3cF91cGRhdGVfdGhlbWVzICB8IDIwMTYtMDUtMzEgMjI6MTU6MTQgfCAxMSBob3VycyA1NyBtaW51dGVzIHwgMTIgaG91cnMgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgTGlzdCBzY2hlZHVsZWQgY3JvbiBldmVudHMgaW4gSlNPTgoJICogICAgICQgd3AgY3JvbiBldmVudCBsaXN0IC0tZmllbGRzPWhvb2ssbmV4dF9ydW4gLS1mb3JtYXQ9anNvbgoJICogICAgIFt7Imhvb2siOiJ3cF92ZXJzaW9uX2NoZWNrIiwibmV4dF9ydW4iOiIyMDE2LTA1LTMxIDEwOjE1OjEzIn0seyJob29rIjoid3BfdXBkYXRlX3BsdWdpbnMiLCJuZXh0X3J1biI6IjIwMTYtMDUtMzEgMTA6MTU6MTMifSx7Imhvb2siOiJ3cF91cGRhdGVfdGhlbWVzIiwibmV4dF9ydW4iOiIyMDE2LTA1LTMxIDEwOjE1OjE0In1dCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgoJCSRldmVudHMgPSBzZWxmOjpnZXRfY3Jvbl9ldmVudHMoKTsKCgkJaWYgKCBpc193cF9lcnJvciggJGV2ZW50cyApICkgewoJCQkkZXZlbnRzID0gYXJyYXkoKTsKCQl9CgoJCWZvcmVhY2ggKCAkZXZlbnRzIGFzICRrZXkgPT4gJGV2ZW50ICkgewoJCQlmb3JlYWNoICggJHRoaXMtPmZpZWxkcyBhcyAkZmllbGQgKSB7CgkJCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWyAkZmllbGQgXSApICYmICRldmVudC0+eyRmaWVsZH0gIT09ICRhc3NvY19hcmdzWyAkZmllbGQgXSApIHsKCQkJCQl1bnNldCggJGV2ZW50c1sgJGtleSBdICk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJZWNobyBpbXBsb2RlKCAnICcsIHdwX2xpc3RfcGx1Y2soICRldmVudHMsICdob29rJyApICk7CgkJfSBlbHNlIHsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGV2ZW50cyApOwoJCX0KCgl9CgoJLyoqCgkgKiBTY2hlZHVsZXMgYSBuZXcgY3JvbiBldmVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGhvb2s+CgkgKiA6IFRoZSBob29rIG5hbWUuCgkgKgoJICogWzxuZXh0LXJ1bj5dCgkgKiA6IEEgVW5peCB0aW1lc3RhbXAgb3IgYW4gRW5nbGlzaCB0ZXh0dWFsIGRhdGV0aW1lIGRlc2NyaXB0aW9uIGNvbXBhdGlibGUgd2l0aCBgc3RydG90aW1lKClgLiBEZWZhdWx0cyB0byBub3cuCgkgKgoJICogWzxyZWN1cnJlbmNlPl0KCSAqIDogSG93IG9mdGVuIHRoZSBldmVudCBzaG91bGQgcmVjdXIuIFNlZSBgd3AgY3JvbiBzY2hlZHVsZSBsaXN0YCBmb3IgYXZhaWxhYmxlIHNjaGVkdWxlIG5hbWVzLiBEZWZhdWx0cyB0byBubyByZWN1cnJlbmNlLgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogQXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGhvb2sgZm9yIHRoZSBldmVudC4gPGZpZWxkPiBzaG91bGQgYmUgYSBudW1lcmljIGtleSwgbm90IGEgc3RyaW5nLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2NoZWR1bGUgYSBuZXcgY3JvbiBldmVudAoJICogICAgICQgd3AgY3JvbiBldmVudCBzY2hlZHVsZSBjcm9uX3Rlc3QKCSAqICAgICBTdWNjZXNzOiBTY2hlZHVsZWQgZXZlbnQgd2l0aCBob29rICdjcm9uX3Rlc3QnIGZvciAyMDE2LTA1LTMxIDEwOjE5OjE2IEdNVC4KCSAqCgkgKiAgICAgIyBTY2hlZHVsZSBuZXcgY3JvbiBldmVudCB3aXRoIGhvdXJseSByZWN1cnJlbmNlCgkgKiAgICAgJCB3cCBjcm9uIGV2ZW50IHNjaGVkdWxlIGNyb25fdGVzdCBub3cgaG91cmx5CgkgKiAgICAgU3VjY2VzczogU2NoZWR1bGVkIGV2ZW50IHdpdGggaG9vayAnY3Jvbl90ZXN0JyBmb3IgMjAxNi0wNS0zMSAxMDoyMDozMiBHTVQuCgkgKgoJICogICAgICMgU2NoZWR1bGUgbmV3IGNyb24gZXZlbnQgYW5kIHBhc3MgYXJndW1lbnRzCgkgKiAgICAgJCB3cCBjcm9uIGV2ZW50IHNjaGVkdWxlIGNyb25fdGVzdCAnKzEgaG91cicgLS0wPWZpcnN0LWFyZ3VtZW50IC0tMT1zZWNvbmQtYXJndW1lbnQKCSAqICAgICBTdWNjZXNzOiBTY2hlZHVsZWQgZXZlbnQgd2l0aCBob29rICdjcm9uX3Rlc3QnIGZvciAyMDE2LTA1LTMxIDExOjIxOjM1IEdNVC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNjaGVkdWxlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCBjb3VudCggJGFzc29jX2FyZ3MgKSAmJiBjb3VudCggYXJyYXlfZmlsdGVyKCBhcnJheV9rZXlzKCAkYXNzb2NfYXJncyApLCAnaXNfc3RyaW5nJyApICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ051bWVyaWMga2V5cyBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGhvb2sgYXJndW1lbnRzLicgKTsKCQl9CgoJCSRob29rICAgICAgID0gJGFyZ3NbMF07CgkJJG5leHRfcnVuICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFyZ3MsIDEsICdub3cnICk7CgkJJHJlY3VycmVuY2UgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFyZ3MsIDIsIGZhbHNlICk7CgoJCWlmICggZW1wdHkoICRuZXh0X3J1biApICkgewoJCQkkdGltZXN0YW1wID0gdGltZSgpOwoJCX0gZWxzZWlmICggaXNfbnVtZXJpYyggJG5leHRfcnVuICkgKSB7CgkJCSR0aW1lc3RhbXAgPSBhYnNpbnQoICRuZXh0X3J1biApOwoJCX0gZWxzZSB7CgkJCSR0aW1lc3RhbXAgPSBzdHJ0b3RpbWUoICRuZXh0X3J1biApOwoJCX0KCgkJaWYgKCAhICR0aW1lc3RhbXAgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICInJXMnIGlzIG5vdCBhIHZhbGlkIGRhdGV0aW1lLiIsICRuZXh0X3J1biApICk7CgkJfQoKCQlpZiAoICEgZW1wdHkoICRyZWN1cnJlbmNlICkgKSB7CgoJCQkkc2NoZWR1bGVzID0gd3BfZ2V0X3NjaGVkdWxlcygpOwoKCQkJaWYgKCAhIGlzc2V0KCAkc2NoZWR1bGVzWyAkcmVjdXJyZW5jZSBdICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiJyVzJyBpcyBub3QgYSB2YWxpZCBzY2hlZHVsZSBuYW1lIGZvciByZWN1cnJlbmNlLiIsICRyZWN1cnJlbmNlICkgKTsKCQkJfQoKCQkJJGV2ZW50ID0gd3Bfc2NoZWR1bGVfZXZlbnQoICR0aW1lc3RhbXAsICRyZWN1cnJlbmNlLCAkaG9vaywgJGFzc29jX2FyZ3MgKTsKCgkJfSBlbHNlIHsKCgkJCSRldmVudCA9IHdwX3NjaGVkdWxlX3NpbmdsZV9ldmVudCggJHRpbWVzdGFtcCwgJGhvb2ssICRhc3NvY19hcmdzICk7CgoJCX0KCgkJaWYgKCBmYWxzZSAhPT0gJGV2ZW50ICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICJTY2hlZHVsZWQgZXZlbnQgd2l0aCBob29rICclcycgZm9yICVzIEdNVC4iLCAkaG9vaywgZGF0ZSggc2VsZjo6JHRpbWVfZm9ybWF0LCAkdGltZXN0YW1wICkgKSApOyAvL3BocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAnRXZlbnQgbm90IHNjaGVkdWxlZC4nICk7CgkJfQoKCX0KCgkvKioKCSAqIFJ1bnMgdGhlIG5leHQgc2NoZWR1bGVkIGNyb24gZXZlbnQgZm9yIHRoZSBnaXZlbiBob29rLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGhvb2s+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBob29rcyB0byBydW4uCgkgKgoJICogWy0tZHVlLW5vd10KCSAqIDogUnVuIGFsbCBob29rcyBkdWUgcmlnaHQgbm93LgoJICoKCSAqIFstLWFsbF0KCSAqIDogUnVuIGFsbCBob29rcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFJ1biBhbGwgY3JvbiBldmVudHMgZHVlIHJpZ2h0IG5vdwoJICogICAgICQgd3AgY3JvbiBldmVudCBydW4gLS1kdWUtbm93CgkgKiAgICAgU3VjY2VzczogRXhlY3V0ZWQgYSB0b3RhbCBvZiAyIGNyb24gZXZlbnRzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcnVuKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWlmICggZW1wdHkoICRhcmdzICkgJiYgISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkdWUtbm93JyApICYmICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgb25lIG9yIG1vcmUgY3JvbiBldmVudHMsIG9yIHVzZSAtLWR1ZS1ub3cvLS1hbGwuJyApOwoJCX0KCgkJJGV2ZW50cyA9IHNlbGY6OmdldF9jcm9uX2V2ZW50cygpOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkZXZlbnRzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRldmVudHMgKTsKCQl9CgoJCSRob29rcyA9IHdwX2xpc3RfcGx1Y2soICRldmVudHMsICdob29rJyApOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkaG9vayApIHsKCQkJaWYgKCAhIGluX2FycmF5KCAkaG9vaywgJGhvb2tzLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW52YWxpZCBjcm9uIGV2ZW50ICclcyciLCAkaG9vayApICk7CgkJCX0KCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHVlLW5vdycgKSApIHsKCQkJJGR1ZV9ldmVudHMgPSBhcnJheSgpOwoJCQlmb3JlYWNoICggJGV2ZW50cyBhcyAkZXZlbnQgKSB7CgkJCQlpZiAoICEgZW1wdHkoICRhcmdzICkgJiYgISBpbl9hcnJheSggJGV2ZW50LT5ob29rLCAkYXJncywgdHJ1ZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJaWYgKCB0aW1lKCkgPj0gJGV2ZW50LT50aW1lICkgewoJCQkJCSRkdWVfZXZlbnRzW10gPSAkZXZlbnQ7CgkJCQl9CgkJCX0KCQkJJGV2ZW50cyA9ICRkdWVfZXZlbnRzOwoJCX0gZWxzZWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgKSB7CgkJCSRkdWVfZXZlbnRzID0gYXJyYXkoKTsKCQkJZm9yZWFjaCAoICRldmVudHMgYXMgJGV2ZW50ICkgewoJCQkJaWYgKCBpbl9hcnJheSggJGV2ZW50LT5ob29rLCAkYXJncywgdHJ1ZSApICkgewoJCQkJCSRkdWVfZXZlbnRzW10gPSAkZXZlbnQ7CgkJCQl9CgkJCX0KCQkJJGV2ZW50cyA9ICRkdWVfZXZlbnRzOwoJCX0KCgkJJGV4ZWN1dGVkID0gMDsKCQlmb3JlYWNoICggJGV2ZW50cyBhcyAkZXZlbnQgKSB7CgkJCSRzdGFydCAgPSBtaWNyb3RpbWUoIHRydWUgKTsKCQkJJHJlc3VsdCA9IHNlbGY6OnJ1bl9ldmVudCggJGV2ZW50ICk7CgkJCSR0b3RhbCAgPSByb3VuZCggbWljcm90aW1lKCB0cnVlICkgLSAkc3RhcnQsIDMgKTsKCQkJJGV4ZWN1dGVkKys7CgkJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAiRXhlY3V0ZWQgdGhlIGNyb24gZXZlbnQgJyVzJyBpbiAlc3MuIiwgJGV2ZW50LT5ob29rLCAkdG90YWwgKSApOwoJCX0KCgkJJG1lc3NhZ2UgPSAoIDEgPT09ICRleGVjdXRlZCApID8gJ0V4ZWN1dGVkIGEgdG90YWwgb2YgJWQgY3JvbiBldmVudC4nIDogJ0V4ZWN1dGVkIGEgdG90YWwgb2YgJWQgY3JvbiBldmVudHMuJzsKCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICRtZXNzYWdlLCAkZXhlY3V0ZWQgKSApOwoJfQoKCS8qKgoJICogVW5zY2hlZHVsZXMgYWxsIGNyb24gZXZlbnRzIGZvciBhIGdpdmVuIGhvb2suCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxob29rPgoJICogOiBOYW1lIG9mIHRoZSBob29rIGZvciB3aGljaCBhbGwgZXZlbnRzIHNob3VsZCBiZSB1bnNjaGVkdWxlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVuc2NoZWR1bGUgYSBjcm9uIGV2ZW50IG9uIGdpdmVuIGhvb2suCgkgKiAgICAgJCB3cCBjcm9uIGV2ZW50IHVuc2NoZWR1bGUgY3Jvbl90ZXN0CgkgKiAgICAgU3VjY2VzczogVW5zY2hlZHVsZWQgMiBldmVudHMgd2l0aCBob29rICdjcm9uX3Rlc3QnLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zY2hlZHVsZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkaG9vayApID0gJGFyZ3M7CgoJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC45LjAnLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1Vuc2NoZWR1bGluZyBldmVudHMgaXMgb25seSBzdXBwb3J0ZWQgZnJvbSBXb3JkUHJlc3MgNC45LjAgb253YXJkcy4nICk7CgkJfQoKCQkkdW5zY2hlZHVsZWQgPSB3cF91bnNjaGVkdWxlX2hvb2soICRob29rICk7CgoJCWlmICggZW1wdHkoICR1bnNjaGVkdWxlZCApICkgewoJCQkkbWVzc2FnZSA9ICdGYWlsZWQgdG8gdW5zY2hlZHVsZSBldmVudHMgZm9yIGhvb2sgXCclMVwkcy4nOwoKCQkJLy8gSWYgMCBldmVudCBmb3VuZCBvbiBob29rLgoJCQlpZiAoIDAgPT09ICR1bnNjaGVkdWxlZCApIHsKCQkJCSRtZXNzYWdlID0gIk5vIGV2ZW50cyBmb3VuZCBmb3IgaG9vayAnJTFcJHMnLiI7CgkJCX0KCgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICRtZXNzYWdlLCAkaG9vayApICk7CgoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcygKCQkJCXNwcmludGYoCgkJCQkJJ1Vuc2NoZWR1bGVkICUxJGQgJTIkcyBmb3IgaG9vayBcJyUzJHNcJy4nLAoJCQkJCSR1bnNjaGVkdWxlZCwKCQkJCQlVdGlsc1xwbHVyYWxpemUoICdldmVudCcsICR1bnNjaGVkdWxlZCApLAoJCQkJCSRob29rCgkJCQkpCgkJCSk7CgkJfQoKCX0KCgkvKioKCSAqIEV4ZWN1dGVzIGFuIGV2ZW50IGltbWVkaWF0ZWx5LgoJICoKCSAqIEBwYXJhbSBzdGRDbGFzcyAkZXZlbnQgVGhlIGV2ZW50CgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgZXZlbnQgd2FzIHN1Y2Nlc3NmdWxseSBleGVjdXRlZCBvciBub3QuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcnVuX2V2ZW50KCBzdGRDbGFzcyAkZXZlbnQgKSB7CgoJCWlmICggISBkZWZpbmVkKCAnRE9JTkdfQ1JPTicgKSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkQ29uc3RhbnRGb3VuZCAtLSBVc2luZyBuYXRpdmUgV29yZFByZXNzIGNvbnN0YW50LgoJCQlkZWZpbmUoICdET0lOR19DUk9OJywgdHJ1ZSApOwoJCX0KCgkJaWYgKCBmYWxzZSAhPT0gJGV2ZW50LT5zY2hlZHVsZSApIHsKCQkJJG5ld19hcmdzID0gYXJyYXkoICRldmVudC0+dGltZSwgJGV2ZW50LT5zY2hlZHVsZSwgJGV2ZW50LT5ob29rLCAkZXZlbnQtPmFyZ3MgKTsKCQkJY2FsbF91c2VyX2Z1bmNfYXJyYXkoICd3cF9yZXNjaGVkdWxlX2V2ZW50JywgJG5ld19hcmdzICk7CgkJfQoKCQl3cF91bnNjaGVkdWxlX2V2ZW50KCAkZXZlbnQtPnRpbWUsICRldmVudC0+aG9vaywgJGV2ZW50LT5hcmdzICk7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5EeW5hbWljSG9va25hbWVGb3VuZCAtLSBDYW4ndCBwcmVmaXggZHluYW1pYyBob29rcyBoZXJlLCBjYWxsaW5nIHJlZ2lzdGVyZWQgaG9va3MuCgkJZG9fYWN0aW9uX3JlZl9hcnJheSggJGV2ZW50LT5ob29rLCAkZXZlbnQtPmFyZ3MgKTsKCgkJcmV0dXJuIHRydWU7CgoJfQoKCS8qKgoJICogRGVsZXRlcyBhbGwgc2NoZWR1bGVkIGNyb24gZXZlbnRzIGZvciB0aGUgZ2l2ZW4gaG9vay4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGhvb2s+CgkgKiA6IFRoZSBob29rIG5hbWUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHNjaGVkdWxlZCBjcm9uIGV2ZW50cyBmb3IgdGhlIGdpdmVuIGhvb2sKCSAqICAgICAkIHdwIGNyb24gZXZlbnQgZGVsZXRlIGNyb25fdGVzdAoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMiBpbnN0YW5jZXMgb2YgdGhlIGNyb24gZXZlbnQgJ2Nyb25fdGVzdCcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGhvb2sgICA9ICRhcmdzWzBdOwoJCSRldmVudHMgPSBzZWxmOjpnZXRfY3Jvbl9ldmVudHMoKTsKCgkJaWYgKCBpc193cF9lcnJvciggJGV2ZW50cyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZXZlbnRzICk7CgkJfQoKCQkkZGVsZXRlZCA9IDA7CgkJZm9yZWFjaCAoICRldmVudHMgYXMgJGV2ZW50ICkgewoJCQlpZiAoICRldmVudC0+aG9vayA9PT0gJGhvb2sgKSB7CgkJCQkkcmVzdWx0ID0gc2VsZjo6ZGVsZXRlX2V2ZW50KCAkZXZlbnQgKTsKCQkJCWlmICggJHJlc3VsdCApIHsKCQkJCQkkZGVsZXRlZCsrOwoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJGYWlsZWQgdG8gdGhlIGRlbGV0ZSB0aGUgY3JvbiBldmVudCAnJXMnLiIsICRob29rICkgKTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAkZGVsZXRlZCApIHsKCQkJJG1lc3NhZ2UgPSAoIDEgPT09ICRkZWxldGVkICkgPyAiRGVsZXRlZCB0aGUgY3JvbiBldmVudCAnJTJcJHMnLiIgOiAiRGVsZXRlZCAlMVwkZCBpbnN0YW5jZXMgb2YgdGhlIGNyb24gZXZlbnQgJyUyXCRzJy4iOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICRtZXNzYWdlLCAkZGVsZXRlZCwgJGhvb2sgKSApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJJbnZhbGlkIGNyb24gZXZlbnQgJyVzJy4iLCAkaG9vayApICk7CgkJfQoKCX0KCgkvKioKCSAqIERlbGV0ZXMgYSBjcm9uIGV2ZW50LgoJICoKCSAqIEBwYXJhbSBzdGRDbGFzcyAkZXZlbnQgVGhlIGV2ZW50CgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgZXZlbnQgd2FzIHN1Y2Nlc3NmdWxseSBkZWxldGVkIG9yIG5vdC4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBkZWxldGVfZXZlbnQoIHN0ZENsYXNzICRldmVudCApIHsKCQkkY3JvbnMgPSBfZ2V0X2Nyb25fYXJyYXkoKTsKCgkJaWYgKCAhIGlzc2V0KCAkY3JvbnNbICRldmVudC0+dGltZSBdWyAkZXZlbnQtPmhvb2sgXVsgJGV2ZW50LT5zaWcgXSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQl3cF91bnNjaGVkdWxlX2V2ZW50KCAkZXZlbnQtPnRpbWUsICRldmVudC0+aG9vaywgJGV2ZW50LT5hcmdzICk7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBDYWxsYmFjayBmdW5jdGlvbiB0byBmb3JtYXQgYSBjcm9uIGV2ZW50LgoJICoKCSAqIEBwYXJhbSBzdGRDbGFzcyAkZXZlbnQgVGhlIGV2ZW50LgoJICogQHJldHVybiBzdGRDbGFzcyBUaGUgZm9ybWF0dGVkIGV2ZW50IG9iamVjdC4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXRfZXZlbnQoIHN0ZENsYXNzICRldmVudCApIHsKCgkJJGV2ZW50LT5uZXh0X3J1biAgICAgICAgICA9IGdldF9kYXRlX2Zyb21fZ210KCBkYXRlKCAnWS1tLWQgSDppOnMnLCAkZXZlbnQtPnRpbWUgKSwgc2VsZjo6JHRpbWVfZm9ybWF0ICk7IC8vcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCSRldmVudC0+bmV4dF9ydW5fZ210ICAgICAgPSBkYXRlKCBzZWxmOjokdGltZV9mb3JtYXQsICRldmVudC0+dGltZSApOyAvL3BocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkkZXZlbnQtPm5leHRfcnVuX3JlbGF0aXZlID0gc2VsZjo6aW50ZXJ2YWwoICRldmVudC0+dGltZSAtIHRpbWUoKSApOwoJCSRldmVudC0+cmVjdXJyZW5jZSAgICAgICAgPSAoICRldmVudC0+c2NoZWR1bGUgKSA/IHNlbGY6OmludGVydmFsKCAkZXZlbnQtPmludGVydmFsICkgOiAnTm9uLXJlcGVhdGluZyc7CgoJCXJldHVybiAkZXZlbnQ7Cgl9CgoJLyoqCgkgKiBGZXRjaGVzIGFuIGFycmF5IG9mIHNjaGVkdWxlZCBjcm9uIGV2ZW50cy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5fFdQX0Vycm9yIEFuIGFycmF5IG9mIGV2ZW50IG9iamVjdHMsIG9yIGEgV1BfRXJyb3Igb2JqZWN0IGlmIHRoZXJlIGFyZSBubyBldmVudHMgc2NoZWR1bGVkLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF9jcm9uX2V2ZW50cygpIHsKCgkJJGNyb25zICA9IF9nZXRfY3Jvbl9hcnJheSgpOwoJCSRldmVudHMgPSBhcnJheSgpOwoKCQlpZiAoIGVtcHR5KCAkY3JvbnMgKSApIHsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvcigKCQkJCSdub19ldmVudHMnLAoJCQkJJ1lvdSBjdXJyZW50bHkgaGF2ZSBubyBzY2hlZHVsZWQgY3JvbiBldmVudHMuJwoJCQkpOwoJCX0KCgkJZm9yZWFjaCAoICRjcm9ucyBhcyAkdGltZSA9PiAkaG9va3MgKSB7CgkJCWZvcmVhY2ggKCAkaG9va3MgYXMgJGhvb2sgPT4gJGhvb2tfZXZlbnRzICkgewoJCQkJZm9yZWFjaCAoICRob29rX2V2ZW50cyBhcyAkc2lnID0+ICRkYXRhICkgewoKCQkJCQkkZXZlbnRzW10gPSAob2JqZWN0KSBhcnJheSgKCQkJCQkJJ2hvb2snICAgICA9PiAkaG9vaywKCQkJCQkJJ3RpbWUnICAgICA9PiAkdGltZSwKCQkJCQkJJ3NpZycgICAgICA9PiAkc2lnLAoJCQkJCQknYXJncycgICAgID0+ICRkYXRhWydhcmdzJ10sCgkJCQkJCSdzY2hlZHVsZScgPT4gJGRhdGFbJ3NjaGVkdWxlJ10sCgkJCQkJCSdpbnRlcnZhbCcgPT4gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRkYXRhLCAnaW50ZXJ2YWwnICksCgkJCQkJKTsKCgkJCQl9CgkJCX0KCQl9CgoJCSRldmVudHMgPSBhcnJheV9tYXAoICdDcm9uX0V2ZW50X0NvbW1hbmQ6OmZvcm1hdF9ldmVudCcsICRldmVudHMgKTsKCgkJcmV0dXJuICRldmVudHM7CgoJfQoKCS8qKgoJICogQ29udmVydHMgYSB0aW1lIGludGVydmFsIGludG8gaHVtYW4tcmVhZGFibGUgZm9ybWF0LgoJICoKCSAqIFNpbWlsYXIgdG8gV29yZFByZXNzJyBidWlsdC1pbiBgaHVtYW5fdGltZV9kaWZmKClgIGJ1dCByZXR1cm5zIHR3byB0aW1lIHBlcmlvZCBjaHVua3MgaW5zdGVhZCBvZiBqdXN0IG9uZS4KCSAqCgkgKiBAcGFyYW0gaW50ICRzaW5jZSBBbiBpbnRlcnZhbCBvZiB0aW1lIGluIHNlY29uZHMKCSAqIEByZXR1cm4gc3RyaW5nIFRoZSBpbnRlcnZhbCBpbiBodW1hbiByZWFkYWJsZSBmb3JtYXQKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW50ZXJ2YWwoICRzaW5jZSApIHsKCQlpZiAoICRzaW5jZSA8PSAwICkgewoJCQlyZXR1cm4gJ25vdyc7CgkJfQoKCQkkc2luY2UgPSBhYnNpbnQoICRzaW5jZSApOwoKCQkvLyBBcnJheSBvZiB0aW1lIHBlcmlvZCBjaHVua3MuCgkJJGNodW5rcyA9IGFycmF5KAoJCQlhcnJheSggNjAgKiA2MCAqIDI0ICogMzY1LCAneWVhcicgKSwKCQkJYXJyYXkoIDYwICogNjAgKiAyNCAqIDMwLCAnbW9udGgnICksCgkJCWFycmF5KCA2MCAqIDYwICogMjQgKiA3LCAnd2VlaycgKSwKCQkJYXJyYXkoIDYwICogNjAgKiAyNCwgJ2RheScgKSwKCQkJYXJyYXkoIDYwICogNjAsICdob3VyJyApLAoJCQlhcnJheSggNjAsICdtaW51dGUnICksCgkJCWFycmF5KCAxLCAnc2Vjb25kJyApLAoJCSk7CgoJCS8vIHdlIG9ubHkgd2FudCB0byBvdXRwdXQgdHdvIGNodW5rcyBvZiB0aW1lIGhlcmUsIGVnOgoJCS8vIHggeWVhcnMsIHh4IG1vbnRocwoJCS8vIHggZGF5cywgeHggaG91cnMKCQkvLyBzbyB0aGVyZSdzIG9ubHkgdHdvIGJpdHMgb2YgY2FsY3VsYXRpb24gYmVsb3c6CgoJCS8vIHN0ZXAgb25lOiB0aGUgZmlyc3QgY2h1bmsKCQlmb3IgKCAkaSA9IDAsICRqID0gY291bnQoICRjaHVua3MgKTsgJGkgPCAkajsgJGkrKyApIHsKCQkJJHNlY29uZHMgPSAkY2h1bmtzWyAkaSBdWzBdOwoJCQkkbmFtZSAgICA9ICRjaHVua3NbICRpIF1bMV07CgoJCQkvLyBGaW5kaW5nIHRoZSBiaWdnZXN0IGNodW5rIChpZiB0aGUgY2h1bmsgZml0cywgYnJlYWspLgoJCQkkY291bnQgPSBmbG9vciggJHNpbmNlIC8gJHNlY29uZHMgKTsKCQkJaWYgKCBmbG9hdHZhbCggMCApICE9PSAkY291bnQgKSB7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJLy8gU2V0IG91dHB1dCB2YXIuCgkJJG91dHB1dCA9IHNwcmludGYoICclZCAlcycsICRjb3VudCwgVXRpbHNccGx1cmFsaXplKCAkbmFtZSwgYWJzaW50KCAkY291bnQgKSApICk7CgoJCS8vIFN0ZXAgdHdvOiB0aGUgc2Vjb25kIGNodW5rLgoJCWlmICggJGkgKyAxIDwgJGogKSB7CgkJCSRzZWNvbmRzMiA9ICRjaHVua3NbICRpICsgMSBdWzBdOwoJCQkkbmFtZTIgICAgPSAkY2h1bmtzWyAkaSArIDEgXVsxXTsKCgkJCSRjb3VudDIgPSBmbG9vciggKCAkc2luY2UgLSAoICRzZWNvbmRzICogJGNvdW50ICkgKSAvICRzZWNvbmRzMiApOwoJCQlpZiAoIGZsb2F0dmFsKCAwICkgIT09ICRjb3VudDIgKSB7CgkJCQkvLyBBZGQgdG8gb3V0cHV0IHZhci4KCQkJCSRvdXRwdXQgLj0gJyAnIC4gc3ByaW50ZiggJyVkICVzJywgJGNvdW50MiwgVXRpbHNccGx1cmFsaXplKCAkbmFtZTIsIGFic2ludCggJGNvdW50MiApICkgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRvdXRwdXQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICdldmVudCcgKTsKCX0KCn0KPD9waHAKCi8qKgogKiBHZXRzIFdQLUNyb24gc2NoZWR1bGVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGF2YWlsYWJsZSBjcm9uIHNjaGVkdWxlcwogKiAgICAgJCB3cCBjcm9uIHNjaGVkdWxlIGxpc3QKICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwogKiAgICAgfCBuYW1lICAgICAgIHwgZGlzcGxheSAgICAgfCBpbnRlcnZhbCB8CiAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKICogICAgIHwgaG91cmx5ICAgICB8IE9uY2UgSG91cmx5IHwgMzYwMCAgICAgfAogKiAgICAgfCB0d2ljZWRhaWx5IHwgVHdpY2UgRGFpbHkgfCA0MzIwMCAgICB8CiAqICAgICB8IGRhaWx5ICAgICAgfCBPbmNlIERhaWx5ICB8IDg2NDAwICAgIHwKICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwogKi8KY2xhc3MgQ3Jvbl9TY2hlZHVsZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGZpZWxkcyA9IGFycmF5KAoJCSduYW1lJywKCQknZGlzcGxheScsCgkJJ2ludGVydmFsJywKCSk7CgoJLyoqCgkgKiBMaXN0IGF2YWlsYWJsZSBjcm9uIHNjaGVkdWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBzY2hlZHVsZS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIGNyb24gc2NoZWR1bGU6CgkgKgoJICogKiBuYW1lCgkgKiAqIGRpc3BsYXkKCSAqICogaW50ZXJ2YWwKCSAqCgkgKiBUaGVyZSBhcmUgbm8gYWRkaXRpb25hbCBmaWVsZHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGF2YWlsYWJsZSBjcm9uIHNjaGVkdWxlcwoJICogICAgICQgd3AgY3JvbiBzY2hlZHVsZSBsaXN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgIHwgZGlzcGxheSAgICAgfCBpbnRlcnZhbCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBob3VybHkgICAgIHwgT25jZSBIb3VybHkgfCAzNjAwICAgICB8CgkgKiAgICAgfCB0d2ljZWRhaWx5IHwgVHdpY2UgRGFpbHkgfCA0MzIwMCAgICB8CgkgKiAgICAgfCBkYWlseSAgICAgIHwgT25jZSBEYWlseSAgfCA4NjQwMCAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgTGlzdCBpZCBvZiBhdmFpbGFibGUgY3JvbiBzY2hlZHVsZQoJICogICAgICQgd3AgY3JvbiBzY2hlZHVsZSBsaXN0IC0tZmllbGRzPW5hbWUgLS1mb3JtYXQ9aWRzCgkgKiAgICAgaG91cmx5IHR3aWNlZGFpbHkgZGFpbHkKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJJHNjaGVkdWxlcyA9IHNlbGY6OmdldF9zY2hlZHVsZXMoKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQllY2hvIGltcGxvZGUoICcgJywgd3BfbGlzdF9wbHVjayggJHNjaGVkdWxlcywgJ25hbWUnICkgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkc2NoZWR1bGVzICk7CgkJfQoKCX0KCgkvKioKCSAqIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZvcm1hdCBhIGNyb24gc2NoZWR1bGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICRzY2hlZHVsZSBUaGUgc2NoZWR1bGUuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBzY2hlZHVsZSBuYW1lLgoJICogQHJldHVybiBhcnJheSBUaGUgZm9ybWF0dGVkIHNjaGVkdWxlLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdF9zY2hlZHVsZSggYXJyYXkgJHNjaGVkdWxlLCAkbmFtZSApIHsKCQkkc2NoZWR1bGVbJ25hbWUnXSA9ICRuYW1lOwoJCXJldHVybiAkc2NoZWR1bGU7Cgl9CgoJLyoqCgkqIFJldHVybiBhIGxpc3Qgb2YgdGhlIGNyb24gc2NoZWR1bGVzIHNvcnRlZCBhY2NvcmRpbmcgdG8gaW50ZXJ2YWwuCgkqCgkqIEByZXR1cm4gYXJyYXkgVGhlIGFycmF5IG9mIGNyb24gc2NoZWR1bGVzLiBFYWNoIHNjaGVkdWxlIGlzIGl0c2VsZiBhbiBhcnJheS4KCSovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF9zY2hlZHVsZXMoKSB7CgkJJHNjaGVkdWxlcyA9IHdwX2dldF9zY2hlZHVsZXMoKTsKCQlpZiAoICEgZW1wdHkoICRzY2hlZHVsZXMgKSApIHsKCQkJdWFzb3J0KCAkc2NoZWR1bGVzLCAnQ3Jvbl9TY2hlZHVsZV9Db21tYW5kOjpzb3J0JyApOwoJCQkkc2NoZWR1bGVzID0gYXJyYXlfbWFwKCAnQ3Jvbl9TY2hlZHVsZV9Db21tYW5kOjpmb3JtYXRfc2NoZWR1bGUnLCAkc2NoZWR1bGVzLCBhcnJheV9rZXlzKCAkc2NoZWR1bGVzICkgKTsKCQl9CgkJcmV0dXJuICRzY2hlZHVsZXM7Cgl9CgoJLyoqCgkgKiBDYWxsYmFjayBmdW5jdGlvbiB0byBzb3J0IHRoZSBjcm9uIHNjaGVkdWxlIGFycmF5IGJ5IGludGVydmFsLgoJICoKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBzb3J0KCBhcnJheSAkYSwgYXJyYXkgJGIgKSB7CgkJcmV0dXJuICRhWydpbnRlcnZhbCddIC0gJGJbJ2ludGVydmFsJ107Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICdzY2hlZHVsZScgKTsKCX0KCn0KPD9waHAKCi8qKgogKiBUZXN0cywgcnVucywgYW5kIGRlbGV0ZXMgV1AtQ3JvbiBldmVudHM7IG1hbmFnZXMgV1AtQ3JvbiBzY2hlZHVsZXMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFRlc3QgV1AgQ3JvbiBzcGF3bmluZyBzeXN0ZW0KICogICAgICQgd3AgY3JvbiB0ZXN0CiAqICAgICBTdWNjZXNzOiBXUC1Dcm9uIHNwYXduaW5nIGlzIHdvcmtpbmcgYXMgZXhwZWN0ZWQuCiAqLwpjbGFzcyBDcm9uX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBUZXN0cyB0aGUgV1AgQ3JvbiBzcGF3bmluZyBzeXN0ZW0gYW5kIHJlcG9ydHMgYmFjayBpdHMgc3RhdHVzLgoJICoKCSAqIFRoaXMgY29tbWFuZCB0ZXN0cyB0aGUgc3Bhd25pbmcgc3lzdGVtIGJ5IHBlcmZvcm1pbmcgdGhlIGZvbGxvd2luZyBzdGVwczoKCSAqCgkgKiAqIENoZWNrcyB0byBzZWUgaWYgdGhlIGBESVNBQkxFX1dQX0NST05gIGNvbnN0YW50IGlzIHNldDsgZXJyb3JzIGlmIHRydWUKCSAqIGJlY2F1c2UgV1AtQ3JvbiBpcyBkaXNhYmxlZC4KCSAqICogQ2hlY2tzIHRvIHNlZSBpZiB0aGUgYEFMVEVSTkFURV9XUF9DUk9OYCBjb25zdGFudCBpcyBzZXQ7IHdhcm5zIGlmIHRydWUuCgkgKiAqIEF0dGVtcHRzIHRvIHNwYXduIFdQLUNyb24gb3ZlciBIVFRQOyB3YXJucyBpZiBub24gMjAwIHJlc3BvbnNlIGNvZGUgaXMKCSAqIHJldHVybmVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JvbiB0ZXN0IHJ1bnMgc3VjY2Vzc2Z1bGx5LgoJICogICAgICQgd3AgY3JvbiB0ZXN0CgkgKiAgICAgU3VjY2VzczogV1AtQ3JvbiBzcGF3bmluZyBpcyB3b3JraW5nIGFzIGV4cGVjdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdGVzdCgpIHsKCgkJaWYgKCBkZWZpbmVkKCAnRElTQUJMRV9XUF9DUk9OJyApICYmIERJU0FCTEVfV1BfQ1JPTiApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoZSBESVNBQkxFX1dQX0NST04gY29uc3RhbnQgaXMgc2V0IHRvIHRydWUuIFdQLUNyb24gc3Bhd25pbmcgaXMgZGlzYWJsZWQuJyApOwoJCX0KCgkJaWYgKCBkZWZpbmVkKCAnQUxURVJOQVRFX1dQX0NST04nICkgJiYgQUxURVJOQVRFX1dQX0NST04gKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ1RoZSBBTFRFUk5BVEVfV1BfQ1JPTiBjb25zdGFudCBpcyBzZXQgdG8gdHJ1ZS4gV1AtQ3JvbiBzcGF3bmluZyBpcyBub3QgYXN5bmNocm9ub3VzLicgKTsKCQl9CgoJCSRzcGF3biA9IHNlbGY6OmdldF9jcm9uX3NwYXduKCk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRzcGF3biApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnV1AtQ3JvbiBzcGF3biBmYWlsZWQgd2l0aCBlcnJvcjogJXMnLCAkc3Bhd24tPmdldF9lcnJvcl9tZXNzYWdlKCkgKSApOwoJCX0KCgkJJGNvZGUgICAgPSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfY29kZSggJHNwYXduICk7CgkJJG1lc3NhZ2UgPSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfbWVzc2FnZSggJHNwYXduICk7CgoJCWlmICggMjAwID09PSAkY29kZSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnV1AtQ3JvbiBzcGF3bmluZyBpcyB3b3JraW5nIGFzIGV4cGVjdGVkLicgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnV1AtQ3JvbiBzcGF3biByZXR1cm5lZCBIVFRQIHN0YXR1cyBjb2RlOiAlMSRzICUyJHMnLCAkY29kZSwgJG1lc3NhZ2UgKSApOwoJCX0KCgl9CgoJLyoqCgkgKiBTcGF3bnMgYSByZXF1ZXN0IHRvIGB3cC1jcm9uLnBocGAgYW5kIHJldHVybiB0aGUgcmVzcG9uc2UuCgkgKgoJICogVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBtaW1pYyB0aGUgZnVuY3Rpb25hbGl0eSBpbiBgc3Bhd25fY3JvbigpYAoJICogd2l0aCB0aGUgYWRkaXRpb24gb2YgcmV0dXJuaW5nIHRoZSByZXN1bHQgb2YgdGhlIGB3cF9yZW1vdGVfcG9zdCgpYAoJICogcmVxdWVzdC4KCSAqCgkgKiBAcmV0dXJuIFdQX0Vycm9yfGFycmF5IFRoZSByZXNwb25zZSBvciBXUF9FcnJvciBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF9jcm9uX3NwYXduKCkgewoKCQkkc3NsdmVyaWZ5ICAgICA9IFxXUF9DTElcVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCA0LjAsICc8JyApOwoJCSRkb2luZ193cF9jcm9uID0gc3ByaW50ZiggJyUuMjJGJywgbWljcm90aW1lKCB0cnVlICkgKTsKCgkJJGNyb25fcmVxdWVzdF9hcnJheSA9IGFycmF5KAoJCQkndXJsJyAgPT4gc2l0ZV91cmwoICd3cC1jcm9uLnBocD9kb2luZ193cF9jcm9uPScgLiAkZG9pbmdfd3BfY3JvbiApLAoJCQkna2V5JyAgPT4gJGRvaW5nX3dwX2Nyb24sCgkJCSdhcmdzJyA9PiBhcnJheSgKCQkJCSd0aW1lb3V0JyAgID0+IDMsCgkJCQknYmxvY2tpbmcnICA9PiB0cnVlLAoJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQkJCSdzc2x2ZXJpZnknID0+IGFwcGx5X2ZpbHRlcnMoICdodHRwc19sb2NhbF9zc2xfdmVyaWZ5JywgJHNzbHZlcmlmeSApLAoJCQkpLAoJCSk7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJJGNyb25fcmVxdWVzdCA9IGFwcGx5X2ZpbHRlcnMoICdjcm9uX3JlcXVlc3QnLCAkY3Jvbl9yZXF1ZXN0X2FycmF5ICk7CgoJCSMgRW5mb3JjZSBhIGJsb2NraW5nIHJlcXVlc3QgaW4gY2FzZSBzb21ldGhpbmcgdGhhdCdzIGhvb2tlZCBvbnRvIHRoZSAnY3Jvbl9yZXF1ZXN0JyBmaWx0ZXIgc2V0cyBpdCB0byBmYWxzZQoJCSRjcm9uX3JlcXVlc3RbJ2FyZ3MnXVsnYmxvY2tpbmcnXSA9IHRydWU7CgoJCSRyZXN1bHQgPSB3cF9yZW1vdGVfcG9zdCggJGNyb25fcmVxdWVzdFsndXJsJ10sICRjcm9uX3JlcXVlc3RbJ2FyZ3MnXSApOwoKCQlyZXR1cm4gJHJlc3VsdDsKCgl9Cgp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfY3Jvbl9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9jcm9uX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfY3Jvbl9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY3JvbicsICdDcm9uX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdjcm9uIGV2ZW50JywgJ0Nyb25fRXZlbnRfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2Nyb24gc2NoZWR1bGUnLCAnQ3Jvbl9TY2hlZHVsZV9Db21tYW5kJyApOwo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBMaXN0cyBvciBmbHVzaGVzIHRoZSBzaXRlJ3MgcmV3cml0ZSBydWxlcywgdXBkYXRlcyB0aGUgcGVybWFsaW5rIHN0cnVjdHVyZS4KICoKICogU2VlIHRoZSBXb3JkUHJlc3MgW1Jld3JpdGUgQVBJXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvUmV3cml0ZV9BUEkpIGFuZAogKiBbV1AgUmV3cml0ZV0oaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL0NsYXNzX1JlZmVyZW5jZS9XUF9SZXdyaXRlKSBjbGFzcyByZWZlcmVuY2UuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEZsdXNoIHJld3JpdGUgcnVsZXMKICogICAgICQgd3AgcmV3cml0ZSBmbHVzaAogKiAgICAgU3VjY2VzczogUmV3cml0ZSBydWxlcyBmbHVzaGVkLgogKgogKiAgICAgIyBVcGRhdGUgcGVybWFsaW5rIHN0cnVjdHVyZQogKiAgICAgJCB3cCByZXdyaXRlIHN0cnVjdHVyZSAnLyV5ZWFyJS8lbW9udGhudW0lLyVwb3N0bmFtZSUnCiAqICAgICBTdWNjZXNzOiBSZXdyaXRlIHN0cnVjdHVyZSBzZXQuCiAqCiAqICAgICAjIExpc3QgcmV3cml0ZSBydWxlcwogKiAgICAgJCB3cCByZXdyaXRlIGxpc3QgLS1mb3JtYXQ9Y3N2CiAqICAgICBtYXRjaCxxdWVyeSxzb3VyY2UKICogICAgIF53cC1qc29uLz8kLGluZGV4LnBocD9yZXN0X3JvdXRlPS8sb3RoZXIKICogICAgIF53cC1qc29uLyguKik/LGluZGV4LnBocD9yZXN0X3JvdXRlPS8kbWF0Y2hlc1sxXSxvdGhlcgogKiAgICAgY2F0ZWdvcnkvKC4rPykvZmVlZC8oZmVlZHxyZGZ8cnNzfHJzczJ8YXRvbSkvPyQsaW5kZXgucGhwP2NhdGVnb3J5X25hbWU9JG1hdGNoZXNbMV0mZmVlZD0kbWF0Y2hlc1syXSxjYXRlZ29yeQogKiAgICAgY2F0ZWdvcnkvKC4rPykvKGZlZWR8cmRmfHJzc3xyc3MyfGF0b20pLz8kLGluZGV4LnBocD9jYXRlZ29yeV9uYW1lPSRtYXRjaGVzWzFdJmZlZWQ9JG1hdGNoZXNbMl0sY2F0ZWdvcnkKICogICAgIGNhdGVnb3J5LyguKz8pL2VtYmVkLz8kLGluZGV4LnBocD9jYXRlZ29yeV9uYW1lPSRtYXRjaGVzWzFdJmVtYmVkPXRydWUsY2F0ZWdvcnkKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwoKY2xhc3MgUmV3cml0ZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogRmx1c2hlcyByZXdyaXRlIHJ1bGVzLgoJICoKCSAqIFJlc2V0cyBXb3JkUHJlc3MnIHJld3JpdGUgcnVsZXMgYmFzZWQgb24gcmVnaXN0ZXJlZCBwb3N0IHR5cGVzLCBldGMuCgkgKgoJICogVG8gcmVnZW5lcmF0ZSBhIC5odGFjY2VzcyBmaWxlIHdpdGggV1AtQ0xJLCB5b3UnbGwgbmVlZCB0byBhZGQgdGhlIG1vZF9yZXdyaXRlIG1vZHVsZQoJICogdG8geW91ciB3cC1jbGkueW1sIG9yIGNvbmZpZy55bWwuIEZvciBleGFtcGxlOgoJICoKCSAqIGBgYAoJICogYXBhY2hlX21vZHVsZXM6CgkgKiAgIC0gbW9kX3Jld3JpdGUKCSAqIGBgYAoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1oYXJkXQoJICogOiBQZXJmb3JtIGEgaGFyZCBmbHVzaCAtIHVwZGF0ZSBgLmh0YWNjZXNzYCBydWxlcyBhcyB3ZWxsIGFzIHJld3JpdGUgcnVsZXMgaW4gZGF0YWJhc2UuIFdvcmtzIG9ubHkgb24gc2luZ2xlIHNpdGUgaW5zdGFsbHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCByZXdyaXRlIGZsdXNoCgkgKiAgICAgU3VjY2VzczogUmV3cml0ZSBydWxlcyBmbHVzaGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZmx1c2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkvLyBtYWtlIHN1cmUgd2UgZGV0ZWN0IG1vZF9yZXdyaXRlIGlmIGNvbmZpZ3VyZWQgaW4gYXBhY2hlX21vZHVsZXMgaW4gY29uZmlnCgkJc2VsZjo6YXBhY2hlX21vZHVsZXMoKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoYXJkJyApICYmICEgaW5fYXJyYXkoICdtb2RfcmV3cml0ZScsIChhcnJheSkgV1BfQ0xJOjpnZXRfY29uZmlnKCAnYXBhY2hlX21vZHVsZXMnICksIHRydWUgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnUmVnZW5lcmF0aW5nIGEgLmh0YWNjZXNzIGZpbGUgcmVxdWlyZXMgc3BlY2lhbCBjb25maWd1cmF0aW9uLiBTZWUgdXNhZ2UgZG9jcy4nICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2hhcmQnICkgJiYgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggIldvcmRQcmVzcyBjYW4ndCBnZW5lcmF0ZSAuaHRhY2Nlc3MgZmlsZSBmb3IgYSBtdWx0aXNpdGUgaW5zdGFsbC4iICk7CgkJfQoKCQlzZWxmOjpjaGVja19za2lwX3BsdWdpbnNfdGhlbWVzKCk7CgoJCWZsdXNoX3Jld3JpdGVfcnVsZXMoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2hhcmQnICkgKTsKCgkJaWYgKCAhIGdldF9vcHRpb24oICdyZXdyaXRlX3J1bGVzJyApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJSZXdyaXRlIHJ1bGVzIGFyZSBlbXB0eSwgcG9zc2libHkgYmVjYXVzZSBvZiBhIG1pc3NpbmcgcGVybWFsaW5rX3N0cnVjdHVyZSBvcHRpb24uIFVzZSAnd3AgcmV3cml0ZSBsaXN0JyB0byB2ZXJpZnksIG9yICd3cCByZXdyaXRlIHN0cnVjdHVyZScgdG8gdXBkYXRlIHBlcm1hbGlua19zdHJ1Y3R1cmUuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ1Jld3JpdGUgcnVsZXMgZmx1c2hlZC4nICk7CgkJfQoJfQoKCS8qKgoJICogVXBkYXRlcyB0aGUgcGVybWFsaW5rIHN0cnVjdHVyZS4KCSAqCgkgKiBTZXRzIHRoZSBwb3N0IHBlcm1hbGluayBzdHJ1Y3R1cmUgdG8gdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgoJICoKCSAqIFRvIHJlZ2VuZXJhdGUgYSAuaHRhY2Nlc3MgZmlsZSB3aXRoIFdQLUNMSSwgeW91J2xsIG5lZWQgdG8gYWRkCgkgKiB0aGUgbW9kX3Jld3JpdGUgbW9kdWxlIHRvIHlvdXIgW1dQLUNMSSBjb25maWddKGh0dHBzOi8vbWFrZS53b3JkcHJlc3Mub3JnL2NsaS9oYW5kYm9vay9jb25maWcvI2NvbmZpZy1maWxlcykuCgkgKiBGb3IgZXhhbXBsZToKCSAqCgkgKiBgYGAKCSAqIGFwYWNoZV9tb2R1bGVzOgoJICogICAtIG1vZF9yZXdyaXRlCgkgKiBgYGAKCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBlcm1hc3RydWN0PgoJICogOiBUaGUgbmV3IHBlcm1hbGluayBzdHJ1Y3R1cmUgdG8gYXBwbHkuCgkgKgoJICogWy0tY2F0ZWdvcnktYmFzZT08YmFzZT5dCgkgKiA6IFNldCB0aGUgYmFzZSBmb3IgY2F0ZWdvcnkgcGVybWFsaW5rcywgaS5lLiAnL2NhdGVnb3J5LycuCgkgKgoJICogWy0tdGFnLWJhc2U9PGJhc2U+XQoJICogOiBTZXQgdGhlIGJhc2UgZm9yIHRhZyBwZXJtYWxpbmtzLCBpLmUuICcvdGFnLycuCgkgKgoJICogWy0taGFyZF0KCSAqIDogUGVyZm9ybSBhIGhhcmQgZmx1c2ggLSB1cGRhdGUgYC5odGFjY2Vzc2AgcnVsZXMgYXMgd2VsbCBhcyByZXdyaXRlIHJ1bGVzIGluIGRhdGFiYXNlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgcmV3cml0ZSBzdHJ1Y3R1cmUgJy8leWVhciUvJW1vbnRobnVtJS8lcG9zdG5hbWUlLycKCSAqICAgICBTdWNjZXNzOiBSZXdyaXRlIHN0cnVjdHVyZSBzZXQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdHJ1Y3R1cmUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwX3Jld3JpdGU7CgoJCS8vIGNvcHlwYXN0YSBmcm9tIC93cC1hZG1pbi9vcHRpb25zLXBlcm1hbGluay5waHAKCgkJJGJsb2dfcHJlZml4ID0gJyc7CgkJJHByZWZpeCAgICAgID0gJGJsb2dfcHJlZml4OwoJCWlmICggaXNfbXVsdGlzaXRlKCkgJiYgISBpc19zdWJkb21haW5faW5zdGFsbCgpICYmIGlzX21haW5fc2l0ZSgpICkgewoJCQkkYmxvZ19wcmVmaXggPSAnL2Jsb2cnOwoJCX0KCgkJJHBlcm1hbGlua19zdHJ1Y3R1cmUgPSAoICdkZWZhdWx0JyA9PT0gJGFyZ3NbMF0gKSA/ICcnIDogJGFyZ3NbMF07CgoJCWlmICggISBlbXB0eSggJHBlcm1hbGlua19zdHJ1Y3R1cmUgKSApIHsKCQkJJHBlcm1hbGlua19zdHJ1Y3R1cmUgPSBwcmVnX3JlcGxhY2UoICcjLysjJywgJy8nLCAnLycgLiBzdHJfcmVwbGFjZSggJyMnLCAnJywgJHBlcm1hbGlua19zdHJ1Y3R1cmUgKSApOwoJCQlpZiAoICRwcmVmaXggJiYgJGJsb2dfcHJlZml4ICkgewoJCQkJJHBlcm1hbGlua19zdHJ1Y3R1cmUgPSAkcHJlZml4IC4gcHJlZ19yZXBsYWNlKCAnI14vP2luZGV4XC5waHAjJywgJycsICRwZXJtYWxpbmtfc3RydWN0dXJlICk7CgkJCX0gZWxzZSB7CgkJCQkkcGVybWFsaW5rX3N0cnVjdHVyZSA9ICRibG9nX3ByZWZpeCAuICRwZXJtYWxpbmtfc3RydWN0dXJlOwoJCQl9CgkJfQoJCSR3cF9yZXdyaXRlLT5zZXRfcGVybWFsaW5rX3N0cnVjdHVyZSggJHBlcm1hbGlua19zdHJ1Y3R1cmUgKTsKCgkJLy8gVXBkYXRlIGNhdGVnb3J5IG9yIHRhZyBiYXNlcwoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydjYXRlZ29yeS1iYXNlJ10gKSApIHsKCgkJCSRjYXRlZ29yeV9iYXNlID0gJGFzc29jX2FyZ3NbJ2NhdGVnb3J5LWJhc2UnXTsKCQkJaWYgKCAhIGVtcHR5KCAkY2F0ZWdvcnlfYmFzZSApICkgewoJCQkJJGNhdGVnb3J5X2Jhc2UgPSAkYmxvZ19wcmVmaXggLiBwcmVnX3JlcGxhY2UoICcjLysjJywgJy8nLCAnLycgLiBzdHJfcmVwbGFjZSggJyMnLCAnJywgJGNhdGVnb3J5X2Jhc2UgKSApOwoJCQl9CgkJCSR3cF9yZXdyaXRlLT5zZXRfY2F0ZWdvcnlfYmFzZSggJGNhdGVnb3J5X2Jhc2UgKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd0YWctYmFzZSddICkgKSB7CgoJCQkkdGFnX2Jhc2UgPSAkYXNzb2NfYXJnc1sndGFnLWJhc2UnXTsKCQkJaWYgKCAhIGVtcHR5KCAkdGFnX2Jhc2UgKSApIHsKCQkJCSR0YWdfYmFzZSA9ICRibG9nX3ByZWZpeCAuIHByZWdfcmVwbGFjZSggJyMvKyMnLCAnLycsICcvJyAuIHN0cl9yZXBsYWNlKCAnIycsICcnLCAkdGFnX2Jhc2UgKSApOwoJCQl9CgkJCSR3cF9yZXdyaXRlLT5zZXRfdGFnX2Jhc2UoICR0YWdfYmFzZSApOwoJCX0KCgkJLy8gbWFrZSBzdXJlIHdlIGRldGVjdCBtb2RfcmV3cml0ZSBpZiBjb25maWd1cmVkIGluIGFwYWNoZV9tb2R1bGVzIGluIGNvbmZpZwoJCXNlbGY6OmFwYWNoZV9tb2R1bGVzKCk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1Jld3JpdGUgc3RydWN0dXJlIHNldC4nICk7CgoJCS8vIExhdW5jaCBhIG5ldyBwcm9jZXNzIHRvIGZsdXNoIHJld3JpdGVzIGJlY2F1c2UgY29yZSBleHBlY3RzIGZsdXNoCgkJLy8gdG8gaGFwcGVuIGFmdGVyIHJld3JpdGVzIGFyZSBzZXQKCQkkbmV3X2Fzc29jX2FyZ3MgPSBbXTsKCQkkY21kICAgICAgICAgICAgPSAncmV3cml0ZSBmbHVzaCc7CgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoYXJkJyApICkgewoJCQkkY21kICAgICAgICAgICAgICAgICAgIC49ICcgLS1oYXJkJzsKCQkJJG5ld19hc3NvY19hcmdzWydoYXJkJ10gPSB0cnVlOwoJCQlpZiAoICEgaW5fYXJyYXkoICdtb2RfcmV3cml0ZScsIChhcnJheSkgV1BfQ0xJOjpnZXRfY29uZmlnKCAnYXBhY2hlX21vZHVsZXMnICksIHRydWUgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJ1JlZ2VuZXJhdGluZyBhIC5odGFjY2VzcyBmaWxlIHJlcXVpcmVzIHNwZWNpYWwgY29uZmlndXJhdGlvbi4gU2VlIHVzYWdlIGRvY3MuJyApOwoJCQl9CgkJfQoKCQkkcHJvY2Vzc19ydW4gPSBXUF9DTEk6OnJ1bmNvbW1hbmQoICRjbWQgKTsKCQlpZiAoICEgZW1wdHkoICRwcm9jZXNzX3J1bi0+c3RkZXJyICkgKSB7CgkJCS8vIFN0cmlwICJXYXJuaW5nOiAiCgkJCVdQX0NMSTo6d2FybmluZyggc3Vic3RyKCAkcHJvY2Vzc19ydW4tPnN0ZGVyciwgOSApICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyBhIGxpc3Qgb2YgdGhlIGN1cnJlbnQgcmV3cml0ZSBydWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tbWF0Y2g9PHVybD5dCgkgKiA6IFNob3cgcmV3cml0ZSBydWxlcyBtYXRjaGluZyBhIHBhcnRpY3VsYXIgVVJMLgoJICoKCSAqIFstLXNvdXJjZT08c291cmNlPl0KCSAqIDogU2hvdyByZXdyaXRlIHJ1bGVzIGZyb20gYSBwYXJ0aWN1bGFyIHNvdXJjZS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBtYXRjaCxxdWVyeSxzb3VyY2UuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCByZXdyaXRlIGxpc3QgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbWF0Y2gscXVlcnksc291cmNlCgkgKiAgICAgXndwLWpzb24vPyQsaW5kZXgucGhwP3Jlc3Rfcm91dGU9LyxvdGhlcgoJICogICAgIF53cC1qc29uLyguKik/LGluZGV4LnBocD9yZXN0X3JvdXRlPS8kbWF0Y2hlc1sxXSxvdGhlcgoJICogICAgIGNhdGVnb3J5LyguKz8pL2ZlZWQvKGZlZWR8cmRmfHJzc3xyc3MyfGF0b20pLz8kLGluZGV4LnBocD9jYXRlZ29yeV9uYW1lPSRtYXRjaGVzWzFdJmZlZWQ9JG1hdGNoZXNbMl0sY2F0ZWdvcnkKCSAqICAgICBjYXRlZ29yeS8oLis/KS8oZmVlZHxyZGZ8cnNzfHJzczJ8YXRvbSkvPyQsaW5kZXgucGhwP2NhdGVnb3J5X25hbWU9JG1hdGNoZXNbMV0mZmVlZD0kbWF0Y2hlc1syXSxjYXRlZ29yeQoJICogICAgIGNhdGVnb3J5LyguKz8pL2VtYmVkLz8kLGluZGV4LnBocD9jYXRlZ29yeV9uYW1lPSRtYXRjaGVzWzFdJmVtYmVkPXRydWUsY2F0ZWdvcnkKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BfcmV3cml0ZTsKCgkJJHJ1bGVzID0gZ2V0X29wdGlvbiggJ3Jld3JpdGVfcnVsZXMnICk7CgkJaWYgKCAhICRydWxlcyApIHsKCQkJJHJ1bGVzID0gW107CgkJCVdQX0NMSTo6d2FybmluZyggJ05vIHJld3JpdGUgcnVsZXMuJyApOwoJCX0KCgkJc2VsZjo6Y2hlY2tfc2tpcF9wbHVnaW5zX3RoZW1lcygpOwoKCQkkZGVmYXVsdHMgICA9IFsKCQkJJ3NvdXJjZScgPT4gJycsCgkJCSdtYXRjaCcgID0+ICcnLAoJCQknZm9ybWF0JyA9PiAndGFibGUnLAoJCQknZmllbGRzJyA9PiAnbWF0Y2gscXVlcnksc291cmNlJywKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlICAgICAgICAgICAgID0gW107CgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWydwb3N0J10gICAgID0gJHdwX3Jld3JpdGUtPmdlbmVyYXRlX3Jld3JpdGVfcnVsZXMoICR3cF9yZXdyaXRlLT5wZXJtYWxpbmtfc3RydWN0dXJlLCBFUF9QRVJNQUxJTksgKTsKCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbJ2RhdGUnXSAgICAgPSAkd3BfcmV3cml0ZS0+Z2VuZXJhdGVfcmV3cml0ZV9ydWxlcyggJHdwX3Jld3JpdGUtPmdldF9kYXRlX3Blcm1hc3RydWN0KCksIEVQX0RBVEUgKTsKCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbJ3Jvb3QnXSAgICAgPSAkd3BfcmV3cml0ZS0+Z2VuZXJhdGVfcmV3cml0ZV9ydWxlcyggJHdwX3Jld3JpdGUtPnJvb3QgLiAnLycsIEVQX1JPT1QgKTsKCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbJ2NvbW1lbnRzJ10gPSAkd3BfcmV3cml0ZS0+Z2VuZXJhdGVfcmV3cml0ZV9ydWxlcyggJHdwX3Jld3JpdGUtPnJvb3QgLiAkd3BfcmV3cml0ZS0+Y29tbWVudHNfYmFzZSwgRVBfQ09NTUVOVFMsIHRydWUsIHRydWUsIHRydWUsIGZhbHNlICk7CgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWydzZWFyY2gnXSAgID0gJHdwX3Jld3JpdGUtPmdlbmVyYXRlX3Jld3JpdGVfcnVsZXMoICR3cF9yZXdyaXRlLT5nZXRfc2VhcmNoX3Blcm1hc3RydWN0KCksIEVQX1NFQVJDSCApOwoJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZVsnYXV0aG9yJ10gICA9ICR3cF9yZXdyaXRlLT5nZW5lcmF0ZV9yZXdyaXRlX3J1bGVzKCAkd3BfcmV3cml0ZS0+Z2V0X2F1dGhvcl9wZXJtYXN0cnVjdCgpLCBFUF9BVVRIT1JTICk7CgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWydwYWdlJ10gICAgID0gJHdwX3Jld3JpdGUtPnBhZ2VfcmV3cml0ZV9ydWxlcygpOwoKCQkvLyBFeHRyYSBwZXJtYXN0cnVjdHMgaW5jbHVkaW5nIHRhZ3MsIGNhdGVnb3JpZXMsIGV0Yy4KCQlmb3JlYWNoICggJHdwX3Jld3JpdGUtPmV4dHJhX3Blcm1hc3RydWN0cyBhcyAkcGVybWFzdHJ1Y3RuYW1lID0+ICRwZXJtYXN0cnVjdCApIHsKCQkJaWYgKCBpc19hcnJheSggJHBlcm1hc3RydWN0ICkgKSB7CgkJCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbICRwZXJtYXN0cnVjdG5hbWUgXSA9ICR3cF9yZXdyaXRlLT5nZW5lcmF0ZV9yZXdyaXRlX3J1bGVzKCAkcGVybWFzdHJ1Y3RbJ3N0cnVjdCddLCAkcGVybWFzdHJ1Y3RbJ2VwX21hc2snXSwgJHBlcm1hc3RydWN0WydwYWdlZCddLCAkcGVybWFzdHJ1Y3RbJ2ZlZWQnXSwgJHBlcm1hc3RydWN0Wydmb3Jjb21tZW50cyddLCAkcGVybWFzdHJ1Y3RbJ3dhbGtfZGlycyddLCAkcGVybWFzdHJ1Y3RbJ2VuZHBvaW50cyddICk7CgkJCX0gZWxzZSB7CgkJCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbICRwZXJtYXN0cnVjdG5hbWUgXSA9ICR3cF9yZXdyaXRlLT5nZW5lcmF0ZV9yZXdyaXRlX3J1bGVzKCAkcGVybWFzdHJ1Y3QsIEVQX05PTkUgKTsKCQkJfQoJCX0KCgkJLy8gQXBwbHkgdGhlIGZpbHRlcnMgdXNlZCBpbiBjb3JlIGp1c3QgaW4gY2FzZQoJCWZvcmVhY2ggKCAkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2UgYXMgJHNvdXJjZSA9PiAkc291cmNlX3J1bGVzICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuRHluYW1pY0hvb2tuYW1lRm91bmQgLS0gQ2FuJ3QgcHJlZml4IGR5bmFtaWMgaG9va3MgaGVyZSwgY2FsbGluZyBob29rcyBmb3IgY3VzdG9tIHBlcm1hc3RydWN0cy4KCQkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWyAkc291cmNlIF0gPSBhcHBseV9maWx0ZXJzKCAkc291cmNlIC4gJ19yZXdyaXRlX3J1bGVzJywgJHNvdXJjZV9ydWxlcyApOwoJCQlpZiAoICdwb3N0X3RhZycgPT09ICRzb3VyY2UgKSB7CgkJCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzMuMS4wJywgJz49JyApICkgewoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJCQkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWyAkc291cmNlIF0gPSBhcHBseV9maWx0ZXJzKCAncG9zdF90YWdfcmV3cml0ZV9ydWxlcycsICRzb3VyY2VfcnVsZXMgKTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQkJCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbICRzb3VyY2UgXSA9IGFwcGx5X2ZpbHRlcnMoICd0YWdfcmV3cml0ZV9ydWxlcycsICRzb3VyY2VfcnVsZXMgKTsKCQkJCX0KCQkJfQoJCX0KCgkJJHJ1bGVfbGlzdCA9IFtdOwoJCWZvcmVhY2ggKCAkcnVsZXMgYXMgJG1hdGNoID0+ICRxdWVyeSApIHsKCgkJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ21hdGNoJ10gKSAmJiAhIHByZWdfbWF0Y2goICIhXiRtYXRjaCEiLCB0cmltKCAkYXNzb2NfYXJnc1snbWF0Y2gnXSwgJy8nICkgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkc291cmNlID0gJ290aGVyJzsKCQkJZm9yZWFjaCAoICRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZSBhcyAkcnVsZXNfc291cmNlID0+ICRzb3VyY2VfcnVsZXMgKSB7CgkJCQlpZiAoIGFycmF5X2tleV9leGlzdHMoICRtYXRjaCwgJHNvdXJjZV9ydWxlcyApICkgewoJCQkJCSRzb3VyY2UgPSAkcnVsZXNfc291cmNlOwoJCQkJfQoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydzb3VyY2UnXSApICYmICRzb3VyY2UgIT09ICRhc3NvY19hcmdzWydzb3VyY2UnXSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkcnVsZV9saXN0W10gPSBjb21wYWN0KCAnbWF0Y2gnLCAncXVlcnknLCAnc291cmNlJyApOwoJCX0KCgkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAkYXNzb2NfYXJnc1snZm9ybWF0J10sICRydWxlX2xpc3QsIGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKTsKCX0KCgkvKioKCSAqIEV4cG9zZXMgYXBhY2hlIG1vZHVsZXMgaWYgcHJlc2VudCBpbiBjb25maWcKCSAqCgkgKiBJbXBsZW1lbnRhdGlvbiBOb3RlczogVGhpcyBmdW5jdGlvbiBleHBvc2VzIGEgZ2xvYmFsIGZ1bmN0aW9uCgkgKiBhcGFjaGVfZ2V0X21vZHVsZXMgYW5kIGFsc28gc2V0cyB0aGUgJGlzX2FwYWNoZSBnbG9iYWwgdmFyaWFibGUuCgkgKgoJICogVGhpcyBpcyBzbyB0aGF0IGZsdXNoX3Jld3JpdGVfcnVsZXMgd2lsbCBhY3R1YWxseSB3cml0ZSBvdXQgdGhlCgkgKiAuaHRhY2Nlc3MgZmlsZSBmb3IgYXBhY2hlIFdvcmRQcmVzcyBpbnN0YWxsYXRpb25zLiBUaGVyZSBpcyBhIGNoZWNrCgkgKiB0byBzZWU6CgkgKgoJICogMS4gaWYgdGhlICRpc19hcGFjaGUgdmFyaWFibGUgaXMgc2V0LgoJICogMi4gaWYgdGhlIG1vZF9yZXdyaXRlIG1vZHVsZSBpcyByZXR1cm5lZCBmcm9tIHRoZSBhcGFjaGVfZ2V0X21vZHVsZXMKCSAqICAgIGZ1bmN0aW9uLgoJICoKCSAqIFRvIGdldCB0aGlzIHRvIHdvcmsgd2l0aCB3cC1jbGkgeW91J2xsIG5lZWQgdG8gYWRkIHRoZSBtb2RfcmV3cml0ZSBtb2R1bGUKCSAqIHRvIHlvdXIgY29uZmlnLnltbC4gRm9yIGV4YW1wbGUKCSAqCgkgKiBgYGAKCSAqIGFwYWNoZV9tb2R1bGVzOgoJICogICAtIG1vZF9yZXdyaXRlCgkgKiBgYGAKCSAqCgkgKiBJZiB0aGlzIGlzbid0IGRvbmUgdGhlbiB0aGUgLmh0YWNjZXNzIHJld3JpdGUgcnVsZXMgd29uJ3QgYmUgZmx1c2hlZCBvdXQKCSAqIHRvIGRpc2suCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGFwYWNoZV9tb2R1bGVzKCkgewoJCSRtb2RzID0gV1BfQ0xJOjpnZXRfY29uZmlnKCAnYXBhY2hlX21vZHVsZXMnICk7CgkJaWYgKCAhIGVtcHR5KCAkbW9kcyApICYmICEgZnVuY3Rpb25fZXhpc3RzKCAnYXBhY2hlX2dldF9tb2R1bGVzJyApICkgewoJCQlnbG9iYWwgJGlzX2FwYWNoZTsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZS5Qcm9oaWJpdGVkCgkJCSRpc19hcGFjaGUgPSB0cnVlOwoKCQkJLy8gbmVlZGVkIGZvciBnZXRfaG9tZV9wYXRoKCkgYW5kIC5odGFjY2VzcyBsb2NhdGlvbgoJCQkkX1NFUlZFUlsnU0NSSVBUX0ZJTEVOQU1FJ10gPSBBQlNQQVRIOwoKCQkJZnVuY3Rpb24gYXBhY2hlX2dldF9tb2R1bGVzKCkgewoJCQkJcmV0dXJuIFdQX0NMSTo6Z2V0X2NvbmZpZyggJ2FwYWNoZV9tb2R1bGVzJyApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogRGlzcGxheXMgYSB3YXJuaW5nIGlmIC0tc2tpcC1wbHVnaW5zIG9yIC0tc2tpcC10aGVtZXMgYXJlIGluIHVzZS4KCSAqCgkgKiBTa2lwcGluZyB0aGUgbG9hZGluZyBvZiBwbHVnaW5zIG9yIHRoZW1lcyBjYW4gbWVhbiBzb21lIHJld3JpdGUgcnVsZXMKCSAqIGFyZSB1bnJlZ2lzdGVyZWQsIHdoaWNoIG1heSBjYXVzZSBlcnJvbmVvdXMgYmVoYXZpb3IuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNoZWNrX3NraXBfcGx1Z2luc190aGVtZXMoKSB7CgkJJHNraXBwZWQgPSBbXTsKCQlpZiAoIFdQX0NMSTo6Z2V0X2NvbmZpZyggJ3NraXAtcGx1Z2lucycgKSApIHsKCQkJJHNraXBwZWRbXSA9ICdwbHVnaW5zJzsKCQl9CgkJaWYgKCBXUF9DTEk6OmdldF9jb25maWcoICdza2lwLXRoZW1lcycgKSApIHsKCQkJJHNraXBwZWRbXSA9ICd0aGVtZXMnOwoJCX0KCQlpZiAoIGVtcHR5KCAkc2tpcHBlZCApICkgewoJCQlyZXR1cm47CgkJfQoJCSRza2lwcGVkID0gaW1wbG9kZSggJyBhbmQgJywgJHNraXBwZWQgKTsKCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJTb21lIHJld3JpdGUgcnVsZXMgbWF5IGJlIG1pc3NpbmcgYmVjYXVzZSAlcyB3ZXJlbid0IGxvYWRlZC4iLCAkc2tpcHBlZCApICk7Cgl9Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdyZXdyaXRlJywgJ1Jld3JpdGVfQ29tbWFuZCcgKTsKPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9yZXdyaXRlX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX3Jld3JpdGVfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9yZXdyaXRlX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdyZXdyaXRlJywgJ1Jld3JpdGVfQ29tbWFuZCcgKTsKPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9ldmFsX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX2V2YWxfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9ldmFsX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdldmFsJywgJ0V2YWxfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2V2YWwtZmlsZScsICdFdmFsRmlsZV9Db21tYW5kJyApOwo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKCmNsYXNzIEV2YWxGaWxlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBSZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybiB0byBtYXRjaCB0aGUgc2hlbGwgc2hlYmFuZy4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBTSEVCQU5HX1BBVFRFUk4gPSAnL14oIyEuKikkL20nOwoKCS8qKgoJICogTG9hZHMgYW5kIGV4ZWN1dGVzIGEgUEhQIGZpbGUuCgkgKgoJICogTm90ZTogYmVjYXVzZSBjb2RlIGlzIGV4ZWN1dGVkIHdpdGhpbiBhIG1ldGhvZCwgZ2xvYmFsIHZhcmlhYmxlcyBuZWVkCgkgKiB0byBiZSBleHBsaWNpdGx5IGdsb2JhbGl6ZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxmaWxlPgoJICogOiBUaGUgcGF0aCB0byB0aGUgUEhQIGZpbGUgdG8gZXhlY3V0ZS4gIFVzZSAnLScgdG8gcnVuIGNvZGUgZnJvbSBTVERJTi4KCSAqCgkgKiBbPGFyZz4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBmaWxlLiBUaGV5IGFyZSBwbGFjZWQgaW4gdGhlICRhcmdzIHZhcmlhYmxlLgoJICoKCSAqIFstLXNraXAtd29yZHByZXNzXQoJICogOiBMb2FkIGFuZCBleGVjdXRlIGZpbGUgd2l0aG91dCBsb2FkaW5nIFdvcmRQcmVzcy4KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgIHdwIGV2YWwtZmlsZSBteS1jb2RlLnBocCB2YWx1ZTEgdmFsdWUyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRmaWxlID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgoJCWlmICggJy0nICE9PSAkZmlsZSAmJiAhIGZpbGVfZXhpc3RzKCAkZmlsZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiJyRmaWxlJyBkb2VzIG5vdCBleGlzdC4iICk7CgkJfQoKCQlpZiAoIG51bGwgPT09IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtd29yZHByZXNzJyApICkgewoJCQlXUF9DTEk6OmdldF9ydW5uZXIoKS0+bG9hZF93b3JkcHJlc3MoKTsKCQl9CgoJCXNlbGY6OmV4ZWN1dGVfZXZhbCggJGZpbGUsICRhcmdzICk7Cgl9CgoJLyoqCgkgKiBFdmFsdWF0ZSBhIHByb3ZpZGVkIGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZmlsZSBGaWxlcGF0aCB0byBleGVjdXRlLCBvciAtIGZvciBTVERJTi4KCSAqIEBwYXJhbSBtaXhlZCAgJGFyZ3MgQXJyYXkgb2YgcG9zaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZmlsZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXhlY3V0ZV9ldmFsKCAkZmlsZSwgJGFyZ3MgKSB7CgkJaWYgKCAnLScgPT09ICRmaWxlICkgewoJCQlldmFsKCAnPz4nIC4gZmlsZV9nZXRfY29udGVudHMoICdwaHA6Ly9zdGRpbicgKSApOwoJCX0gZWxzZSB7CgkJCSRmaWxlX2NvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoICRmaWxlICk7CgoJCQkvLyBBZGp1c3QgZm9yIF9fRklMRV9fIGFuZCBfX0RJUl9fIG1hZ2ljIGNvbnN0YW50cy4KCQkJJGZpbGVfY29udGVudHMgPSBVdGlsc1xyZXBsYWNlX3BhdGhfY29uc3RzKCAkZmlsZV9jb250ZW50cywgJGZpbGUgKTsKCgkJCS8vIENoZWNrIGZvciBhbmQgcmVtb3ZlIHNoZS1iYW5nLgoJCQlpZiAoIDAgPT09IHN0cm5jbXAoICRmaWxlX2NvbnRlbnRzLCAnIyEnLCAyICkgKSB7CgkJCQkkZmlsZV9jb250ZW50cyA9IHByZWdfcmVwbGFjZSggc3RhdGljOjpTSEVCQU5HX1BBVFRFUk4sICcnLCAkZmlsZV9jb250ZW50cyApOwoJCQl9CgoJCQlldmFsKCAnPz4nIC4gJGZpbGVfY29udGVudHMgKTsKCQl9Cgl9Cn0KCjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwoKY2xhc3MgRXZhbF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogRXhlY3V0ZXMgYXJiaXRyYXJ5IFBIUCBjb2RlLgoJICoKCSAqIE5vdGU6IGJlY2F1c2UgY29kZSBpcyBleGVjdXRlZCB3aXRoaW4gYSBtZXRob2QsIGdsb2JhbCB2YXJpYWJsZXMgbmVlZAoJICogdG8gYmUgZXhwbGljaXRseSBnbG9iYWxpemVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cGhwLWNvZGU+CgkgKiA6IFRoZSBjb2RlIHRvIGV4ZWN1dGUsIGFzIGEgc3RyaW5nLgoJICoKCSAqIFstLXNraXAtd29yZHByZXNzXQoJICogOiBFeGVjdXRlIGNvZGUgd2l0aG91dCBsb2FkaW5nIFdvcmRQcmVzcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERpc3BsYXkgV29yZFByZXNzIGNvbnRlbnQgZGlyZWN0b3J5LgoJICogICAgICQgd3AgZXZhbCAnZWNobyBXUF9DT05URU5UX0RJUjsnCgkgKiAgICAgL3Zhci93d3cvd29yZHByZXNzL3dwLWNvbnRlbnQKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBhIHJhbmRvbSBudW1iZXIuCgkgKiAgICAgJCB3cCBldmFsICdlY2hvIHJhbmQoKTsnIC0tc2tpcC13b3JkcHJlc3MKCSAqICAgICA0Nzk2MjA0MjMKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJaWYgKCBudWxsID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXdvcmRwcmVzcycgKSApIHsKCQkJV1BfQ0xJOjpnZXRfcnVubmVyKCktPmxvYWRfd29yZHByZXNzKCk7CgkJfQoKCQlldmFsKCAkYXJnc1swXSApOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfc2NhZmZvbGRfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfc2NhZmZvbGRfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9zY2FmZm9sZF9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2NhZmZvbGQnLCAnU2NhZmZvbGRfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcSW5mbGVjdG9yOwoKLyoqCiAqIEdlbmVyYXRlcyBjb2RlIGZvciBwb3N0IHR5cGVzLCB0YXhvbm9taWVzLCBwbHVnaW5zLCBjaGlsZCB0aGVtZXMsIGV0Yy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgR2VuZXJhdGUgYSBuZXcgcGx1Z2luIHdpdGggdW5pdCB0ZXN0cwogKiAgICAgJCB3cCBzY2FmZm9sZCBwbHVnaW4gc2FtcGxlLXBsdWdpbgogKiAgICAgU3VjY2VzczogQ3JlYXRlZCBwbHVnaW4gZmlsZXMuCiAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHRlc3QgZmlsZXMuCiAqCiAqICAgICAjIEdlbmVyYXRlIHRoZW1lIGJhc2VkIG9uIF9zCiAqICAgICAkIHdwIHNjYWZmb2xkIF9zIHNhbXBsZS10aGVtZSAtLXRoZW1lX25hbWU9IlNhbXBsZSBUaGVtZSIgLS1hdXRob3I9IkpvaG4gRG9lIgogKiAgICAgU3VjY2VzczogQ3JlYXRlZCB0aGVtZSAnU2FtcGxlIFRoZW1lJy4KICoKICogICAgICMgR2VuZXJhdGUgY29kZSBmb3IgcG9zdCB0eXBlIHJlZ2lzdHJhdGlvbiBpbiBnaXZlbiB0aGVtZQogKiAgICAgJCB3cCBzY2FmZm9sZCBwb3N0LXR5cGUgbW92aWUgLS1sYWJlbD1Nb3ZpZSAtLXRoZW1lPXNpbXBsZS1saWZlCiAqICAgICBTdWNjZXNzOiBDcmVhdGVkIC92YXIvd3d3L2V4YW1wbGUuY29tL3B1YmxpY19odG1sL3dwLWNvbnRlbnQvdGhlbWVzL3NpbXBsZS1saWZlL3Bvc3QtdHlwZXMvbW92aWUucGhwCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgU2NhZmZvbGRfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIEdlbmVyYXRlcyBQSFAgY29kZSBmb3IgcmVnaXN0ZXJpbmcgYSBjdXN0b20gcG9zdCB0eXBlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2x1Zz4KCSAqIDogVGhlIGludGVybmFsIG5hbWUgb2YgdGhlIHBvc3QgdHlwZS4KCSAqCgkgKiBbLS1sYWJlbD08bGFiZWw+XQoJICogOiBUaGUgdGV4dCB1c2VkIHRvIHRyYW5zbGF0ZSB0aGUgdXBkYXRlIG1lc3NhZ2VzLgoJICoKCSAqIFstLXRleHRkb21haW49PHRleHRkb21haW4+XQoJICogOiBUaGUgdGV4dGRvbWFpbiB0byB1c2UgZm9yIHRoZSBsYWJlbHMuCgkgKgoJICogWy0tZGFzaGljb249PGRhc2hpY29uPl0KCSAqIDogVGhlIGRhc2hpY29uIHRvIHVzZSBpbiB0aGUgbWVudS4KCSAqCgkgKiBbLS10aGVtZV0KCSAqIDogQ3JlYXRlIGEgZmlsZSBpbiB0aGUgYWN0aXZlIHRoZW1lIGRpcmVjdG9yeSwgaW5zdGVhZCBvZiBzZW5kaW5nIHRvCgkgKiBTVERPVVQuIFNwZWNpZnkgYSB0aGVtZSB3aXRoIGAtLXRoZW1lPTx0aGVtZT5gIHRvIGhhdmUgdGhlIGZpbGUgcGxhY2VkIGluIHRoYXQgdGhlbWUuCgkgKgoJICogWy0tcGx1Z2luPTxwbHVnaW4+XQoJICogOiBDcmVhdGUgYSBmaWxlIGluIHRoZSBnaXZlbiBwbHVnaW4ncyBkaXJlY3RvcnksIGluc3RlYWQgb2Ygc2VuZGluZyB0byBTVERPVVQuCgkgKgoJICogWy0tcmF3XQoJICogOiBKdXN0IGdlbmVyYXRlIHRoZSBgcmVnaXN0ZXJfcG9zdF90eXBlKClgIGNhbGwgYW5kIG5vdGhpbmcgZWxzZS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogT3ZlcndyaXRlIGZpbGVzIHRoYXQgYWxyZWFkeSBleGlzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdlbmVyYXRlIGEgJ21vdmllJyBwb3N0IHR5cGUgZm9yIHRoZSAnc2ltcGxlLWxpZmUnIHRoZW1lCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBwb3N0LXR5cGUgbW92aWUgLS1sYWJlbD1Nb3ZpZSAtLXRoZW1lPXNpbXBsZS1saWZlCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCAnL3Zhci93d3cvZXhhbXBsZS5jb20vcHVibGljX2h0bWwvd3AtY29udGVudC90aGVtZXMvc2ltcGxlLWxpZmUvcG9zdC10eXBlcy9tb3ZpZS5waHAnLgoJICoKCSAqIEBzdWJjb21tYW5kIHBvc3QtdHlwZQoJICoKCSAqIEBhbGlhcyAgICAgIGNwdAoJICovCglwdWJsaWMgZnVuY3Rpb24gcG9zdF90eXBlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWlmICggc3RybGVuKCAkYXJnc1swXSApID4gMjAgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQb3N0IHR5cGUgc2x1Z3MgY2Fubm90IGV4Y2VlZCAyMCBjaGFyYWN0ZXJzIGluIGxlbmd0aC4nICk7CgkJfQoKCQkkZGVmYXVsdHMgPSBbCgkJCSd0ZXh0ZG9tYWluJyA9PiAnJywKCQkJJ2Rhc2hpY29uJyAgID0+ICdhZG1pbi1wb3N0JywKCQldOwoKCQkkdGVtcGxhdGVzID0gWwoJCQkncG9zdF90eXBlLm11c3RhY2hlJywKCQkJJ3Bvc3RfdHlwZV9leHRlbmRlZC5tdXN0YWNoZScsCgkJXTsKCgkJJHRoaXMtPnNjYWZmb2xkKCAkYXJnc1swXSwgJGFzc29jX2FyZ3MsICRkZWZhdWx0cywgJy9wb3N0LXR5cGVzLycsICR0ZW1wbGF0ZXMgKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBQSFAgY29kZSBmb3IgcmVnaXN0ZXJpbmcgYSBjdXN0b20gdGF4b25vbXkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzbHVnPgoJICogOiBUaGUgaW50ZXJuYWwgbmFtZSBvZiB0aGUgdGF4b25vbXkuCgkgKgoJICogWy0tcG9zdF90eXBlcz08cG9zdC10eXBlcz5dCgkgKiA6IFBvc3QgdHlwZXMgdG8gcmVnaXN0ZXIgZm9yIHVzZSB3aXRoIHRoZSB0YXhvbm9teS4KCSAqCgkgKiBbLS1sYWJlbD08bGFiZWw+XQoJICogOiBUaGUgdGV4dCB1c2VkIHRvIHRyYW5zbGF0ZSB0aGUgdXBkYXRlIG1lc3NhZ2VzLgoJICoKCSAqIFstLXRleHRkb21haW49PHRleHRkb21haW4+XQoJICogOiBUaGUgdGV4dGRvbWFpbiB0byB1c2UgZm9yIHRoZSBsYWJlbHMuCgkgKgoJICogWy0tdGhlbWVdCgkgKiA6IENyZWF0ZSBhIGZpbGUgaW4gdGhlIGFjdGl2ZSB0aGVtZSBkaXJlY3RvcnksIGluc3RlYWQgb2Ygc2VuZGluZyB0bwoJICogU1RET1VULiBTcGVjaWZ5IGEgdGhlbWUgd2l0aCBgLS10aGVtZT08dGhlbWU+YCB0byBoYXZlIHRoZSBmaWxlIHBsYWNlZCBpbiB0aGF0IHRoZW1lLgoJICoKCSAqIFstLXBsdWdpbj08cGx1Z2luPl0KCSAqIDogQ3JlYXRlIGEgZmlsZSBpbiB0aGUgZ2l2ZW4gcGx1Z2luJ3MgZGlyZWN0b3J5LCBpbnN0ZWFkIG9mIHNlbmRpbmcgdG8gU1RET1VULgoJICoKCSAqIFstLXJhd10KCSAqIDogSnVzdCBnZW5lcmF0ZSB0aGUgYHJlZ2lzdGVyX3RheG9ub215KClgIGNhbGwgYW5kIG5vdGhpbmcgZWxzZS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogT3ZlcndyaXRlIGZpbGVzIHRoYXQgYWxyZWFkeSBleGlzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdlbmVyYXRlIFBIUCBjb2RlIGZvciByZWdpc3RlcmluZyBhIGN1c3RvbSB0YXhvbm9teSBhbmQgc2F2ZSBpbiBhIGZpbGUKCSAqICAgICAkIHdwIHNjYWZmb2xkIHRheG9ub215IHZlbnVlIC0tcG9zdF90eXBlcz1ldmVudCxwcmVzZW50YXRpb24gPiB0YXhvbm9teS5waHAKCSAqCgkgKiBAc3ViY29tbWFuZCB0YXhvbm9teQoJICoKCSAqIEBhbGlhcyAgICAgIHRheAoJICovCglwdWJsaWMgZnVuY3Rpb24gdGF4b25vbXkoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZGVmYXVsdHMgPSBbCgkJCSd0ZXh0ZG9tYWluJyA9PiAnJywKCQkJJ3Bvc3RfdHlwZXMnID0+ICIncG9zdCciLAoJCV07CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydwb3N0X3R5cGVzJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfdHlwZXMnXSA9ICR0aGlzLT5xdW90ZV9jb21tYV9saXN0X2VsZW1lbnRzKCAkYXNzb2NfYXJnc1sncG9zdF90eXBlcyddICk7CgkJfQoKCQkkdGVtcGxhdGVzID0gWwoJCQkndGF4b25vbXkubXVzdGFjaGUnLAoJCQkndGF4b25vbXlfZXh0ZW5kZWQubXVzdGFjaGUnLAoJCV07CgoJCSR0aGlzLT5zY2FmZm9sZCggJGFyZ3NbMF0sICRhc3NvY19hcmdzLCAkZGVmYXVsdHMsICcvdGF4b25vbWllcy8nLCAkdGVtcGxhdGVzICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzY2FmZm9sZCggJHNsdWcsICRhc3NvY19hcmdzLCAkZGVmYXVsdHMsICRzdWJkaXIsICR0ZW1wbGF0ZXMgKSB7CgkJJHdwX2ZpbGVzeXN0ZW0gPSAkdGhpcy0+aW5pdF93cF9maWxlc3lzdGVtKCk7CgoJCSRjb250cm9sX2RlZmF1bHRzID0gWwoJCQknbGFiZWwnICA9PiBwcmVnX3JlcGxhY2UoICcvX3wtLycsICcgJywgc3RydG9sb3dlciggJHNsdWcgKSApLAoJCQkndGhlbWUnICA9PiBmYWxzZSwKCQkJJ3BsdWdpbicgPT4gZmFsc2UsCgkJCSdyYXcnICAgID0+IGZhbHNlLAoJCV07CgkJJGNvbnRyb2xfYXJncyAgICAgPSAkdGhpcy0+ZXh0cmFjdF9hcmdzKCAkYXNzb2NfYXJncywgJGNvbnRyb2xfZGVmYXVsdHMgKTsKCgkJJHZhcnMgPSAkdGhpcy0+ZXh0cmFjdF9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICk7CgoJCSRkYXNoaWNvbiA9ICR0aGlzLT5leHRyYWN0X2Rhc2hpY29uKCAkYXNzb2NfYXJncyApOwoJCWlmICggJGRhc2hpY29uICkgewoJCQkkdmFyc1snZGFzaGljb24nXSA9ICRkYXNoaWNvbjsKCQl9CgoJCSR2YXJzWydzbHVnJ10gPSAkc2x1ZzsKCgkJJHZhcnNbJ3RleHRkb21haW4nXSA9ICR0aGlzLT5nZXRfdGV4dGRvbWFpbiggJHZhcnNbJ3RleHRkb21haW4nXSwgJGNvbnRyb2xfYXJncyApOwoKCQkkdmFyc1snbGFiZWwnXSA9ICRjb250cm9sX2FyZ3NbJ2xhYmVsJ107CgoJCSR2YXJzWydsYWJlbF91Y2ZpcnN0J10gICAgICAgID0gdWNmaXJzdCggJHZhcnNbJ2xhYmVsJ10gKTsKCQkkdmFyc1snbGFiZWxfcGx1cmFsJ10gICAgICAgICA9ICR0aGlzLT5wbHVyYWxpemUoICR2YXJzWydsYWJlbCddICk7CgkJJHZhcnNbJ2xhYmVsX3BsdXJhbF91Y2ZpcnN0J10gPSB1Y2ZpcnN0KCAkdmFyc1snbGFiZWxfcGx1cmFsJ10gKTsKCgkJJG1hY2hpbmVfbmFtZSAgICAgICAgPSAkdGhpcy0+Z2VuZXJhdGVfbWFjaGluZV9uYW1lKCAkc2x1ZyApOwoJCSRtYWNoaW5lX25hbWVfcGx1cmFsID0gJHRoaXMtPnBsdXJhbGl6ZSggJHNsdWcgKTsKCgkJbGlzdCggJHJhd190ZW1wbGF0ZSwgJGV4dGVuZGVkX3RlbXBsYXRlICkgPSAkdGVtcGxhdGVzOwoKCQkkcmF3X291dHB1dCA9IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJHJhd190ZW1wbGF0ZSwgJHZhcnMgKTsKCgkJaWYgKCAhICRjb250cm9sX2FyZ3NbJ3JhdyddICkgewoJCQkkdmFyc1snbWFjaGluZV9uYW1lJ10gPSAkbWFjaGluZV9uYW1lOwoJCQkkdmFyc1snb3V0cHV0J10gICAgICAgPSAkcmF3X291dHB1dDsKCgkJCSRmaW5hbF9vdXRwdXQgPSBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICRleHRlbmRlZF90ZW1wbGF0ZSwgJHZhcnMgKTsKCQl9IGVsc2UgewoJCQkkZmluYWxfb3V0cHV0ID0gJHJhd19vdXRwdXQ7CgkJfQoKCQkkcGF0aCA9ICR0aGlzLT5nZXRfb3V0cHV0X3BhdGgoICRjb250cm9sX2FyZ3MsICRzdWJkaXIgKTsKCQlpZiAoIGlzX3N0cmluZyggJHBhdGggKSAmJiAhIGVtcHR5KCAkcGF0aCApICkgewoJCQkkZmlsZW5hbWUgPSAieyRwYXRofXskc2x1Z30ucGhwIjsKCgkJCSRmb3JjZSAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKTsKCQkJJGZpbGVzX3dyaXR0ZW4gICA9ICR0aGlzLT5jcmVhdGVfZmlsZXMoIFsgJGZpbGVuYW1lID0+ICRmaW5hbF9vdXRwdXQgXSwgJGZvcmNlICk7CgkJCSRza2lwX21lc3NhZ2UgICAgPSAiU2tpcHBlZCBjcmVhdGluZyAneyRmaWxlbmFtZX0nLiI7CgkJCSRzdWNjZXNzX21lc3NhZ2UgPSAiQ3JlYXRlZCAneyRmaWxlbmFtZX0nLiI7CgkJCSR0aGlzLT5sb2dfd2hldGhlcl9maWxlc193cml0dGVuKCAkZmlsZXNfd3JpdHRlbiwgJHNraXBfbWVzc2FnZSwgJHN1Y2Nlc3NfbWVzc2FnZSApOwoKCQl9IGVsc2UgewoJCQkvLyBTVERPVVQKCQkJZWNobyAkZmluYWxfb3V0cHV0OwoJCX0KCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBQSFAsIEpTIGFuZCBDU1MgY29kZSBmb3IgcmVnaXN0ZXJpbmcgYSBHdXRlbmJlcmcgYmxvY2sgZm9yIGEgcGx1Z2luIG9yIHRoZW1lLgoJICoKCSAqIEJsb2NrcyBhcmUgdGhlIGZ1bmRhbWVudGFsIGVsZW1lbnQgb2YgdGhlIEd1dGVuYmVyZyBlZGl0b3IuIFRoZXkgYXJlIHRoZSBwcmltYXJ5IHdheSBpbiB3aGljaCBwbHVnaW5zIGFuZCB0aGVtZXMgY2FuIHJlZ2lzdGVyIHRoZWlyIG93biBmdW5jdGlvbmFsaXR5IGFuZCBleHRlbmQgdGhlIGNhcGFiaWxpdGllcyBvZiB0aGUgZWRpdG9yLgoJICoKCSAqIFZpc2l0IHRoZSBbR3V0ZW5iZXJnIGhhbmRib29rXShodHRwczovL3dvcmRwcmVzcy5vcmcvZ3V0ZW5iZXJnL2hhbmRib29rL2Jsb2NrLWFwaS8pIHRvIGxlYXJuIG1vcmUgYWJvdXQgQmxvY2sgQVBJLgoJICoKCSAqIFdoZW4geW91IHNjYWZmb2xkIGEgYmxvY2sgeW91IG11c3QgdXNlIGVpdGhlciB0aGUgdGhlbWUgb3IgcGx1Z2luIG9wdGlvbi4gVGhlIGxhdHRlciBpcyByZWNvbW1lbmRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNsdWc+CgkgKiA6IFRoZSBpbnRlcm5hbCBuYW1lIG9mIHRoZSBibG9jay4KCSAqCgkgKiBbLS10aXRsZT08dGl0bGU+XQoJICogOiBUaGUgZGlzcGxheSB0aXRsZSBmb3IgeW91ciBibG9jay4KCSAqCgkgKiBbLS1kYXNoaWNvbj08ZGFzaGljb24+XQoJICogOiBUaGUgZGFzaGljb24gdG8gbWFrZSBpdCBlYXNpZXIgdG8gaWRlbnRpZnkgeW91ciBibG9jay4KCSAqCgkgKiBbLS1jYXRlZ29yeT08Y2F0ZWdvcnk+XQoJICogOiBUaGUgY2F0ZWdvcnkgbmFtZSB0byBoZWxwIHVzZXJzIGJyb3dzZSBhbmQgZGlzY292ZXIgeW91ciBibG9jay4KCSAqIC0tLQoJICogZGVmYXVsdDogd2lkZ2V0cwoJICogb3B0aW9uczoKCSAqICAgLSBjb21tb24KCSAqICAgLSBlbWJlZAoJICogICAtIGZvcm1hdHRpbmcKCSAqICAgLSBsYXlvdXQKCSAqICAgLSB3aWRnZXRzCgkgKiAtLS0KCSAqCgkgKiBbLS10aGVtZV0KCSAqIDogQ3JlYXRlIGZpbGVzIGluIHRoZSBhY3RpdmUgdGhlbWUgZGlyZWN0b3J5LiBTcGVjaWZ5IGEgdGhlbWUgd2l0aCBgLS10aGVtZT08dGhlbWU+YCB0byBoYXZlIHRoZSBmaWxlIHBsYWNlZCBpbiB0aGF0IHRoZW1lLgoJICoKCSAqIFstLXBsdWdpbj08cGx1Z2luPl0KCSAqIDogQ3JlYXRlIGZpbGVzIGluIHRoZSBnaXZlbiBwbHVnaW4ncyBkaXJlY3RvcnkuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IE92ZXJ3cml0ZSBmaWxlcyB0aGF0IGFscmVhZHkgZXhpc3QuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBhICdtb3ZpZScgYmxvY2sgZm9yIHRoZSAnbW92aWVzJyBwbHVnaW4KCSAqICAgICAkIHdwIHNjYWZmb2xkIGJsb2NrIG1vdmllIC0tdGl0bGU9Ik1vdmllIGJsb2NrIiAtLXBsdWdpbj1tb3ZpZXMKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIGJsb2NrICdNb3ZpZSBibG9jaycuCgkgKgoJICogICAgICMgR2VuZXJhdGUgYSAnbW92aWUnIGJsb2NrIGZvciB0aGUgJ3NpbXBsZS1saWZlJyB0aGVtZQoJICogICAgICQgd3Agc2NhZmZvbGQgYmxvY2sgbW92aWUgLS10aXRsZT0iTW92aWUgYmxvY2siIC0tdGhlbWU9c2ltcGxlLWxpZmUKCSAqICAgICAgU3VjY2VzczogQ3JlYXRlZCBibG9jayAnTW92aWUgYmxvY2snLgoJICoKCSAqICAgICAjIENyZWF0ZSBhIG5ldyBwbHVnaW4gYW5kIGFkZCB0d28gYmxvY2tzCgkgKiAgICAgIyBDcmVhdGUgcGx1Z2luIGNhbGxlZCBib29rcwoJICogICAgICQgd3Agc2NhZmZvbGQgcGx1Z2luIGJvb2tzCgkgKiAgICAgIyBBZGQgYSBibG9jayBjYWxsZWQgYm9vayB0byBwbHVnaW4gYm9va3MKCSAqICAgICAkIHdwIHNjYWZmb2xkIGJsb2NrIGJvb2sgLS10aXRsZT0iQm9vayIgLS1wbHVnaW49Ym9va3MKCSAqICAgICAjIEFkZCBhIHNlY29uZCBibG9jayB0byBwbHVnaW4gY2FsbGVkIGJvb2tzLgoJICogICAgICQgd3Agc2NhZmZvbGQgYmxvY2sgYm9va3MgLS10aXRsZT0iQm9vayBMaXN0IiAtLXBsdWdpbj1ib29rcwoJICoKCSAqIEBzdWJjb21tYW5kIGJsb2NrCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBibG9jayggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkc2x1ZyA9ICRhcmdzWzBdOwoJCWlmICggISBwcmVnX21hdGNoKCAnL15bYS16XVthLXowLTlcLV0qJC8nLCAkc2x1ZyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBibG9jayBzbHVnIHNwZWNpZmllZC4gQmxvY2sgc2x1Z3MgY2FuIGNvbnRhaW4gb25seSBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgb3IgZGFzaGVzLCBhbmQgc3RhcnQgd2l0aCBhIGxldHRlci4nICk7CgkJfQoKCQkkZGVmYXVsdHMgPSBbCgkJCSd0aXRsZScgICAgPT4gc3RyX3JlcGxhY2UoICctJywgJyAnLCAkc2x1ZyApLAoJCQknY2F0ZWdvcnknID0+ICd3aWRnZXRzJywKCQldOwoJCSRkYXRhICAgICA9ICR0aGlzLT5leHRyYWN0X2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCgkJJGRhdGFbJ3NsdWcnXSAgICAgICAgICAgICA9ICRzbHVnOwoJCSRkYXRhWyd0aXRsZV91Y2ZpcnN0J10gICAgPSB1Y2ZpcnN0KCAkZGF0YVsndGl0bGUnXSApOwoJCSRkYXRhWyd0aXRsZV91Y2ZpcnN0X2pzJ10gPSBlc2NfanMoICRkYXRhWyd0aXRsZV91Y2ZpcnN0J10gKTsKCgkJJGRhc2hpY29uID0gJHRoaXMtPmV4dHJhY3RfZGFzaGljb24oICRhc3NvY19hcmdzICk7CgkJaWYgKCAkZGFzaGljb24gKSB7CgkJCSRkYXRhWydkYXNoaWNvbiddID0gJGRhc2hpY29uOwoJCX0KCgkJJGNvbnRyb2xfZGVmYXVsdHMgPSBbCgkJCSdmb3JjZScgID0+IGZhbHNlLAoJCQkncGx1Z2luJyA9PiBmYWxzZSwKCQkJJ3RoZW1lJyAgPT4gZmFsc2UsCgkJXTsKCQkkY29udHJvbF9hcmdzICAgICA9ICR0aGlzLT5leHRyYWN0X2FyZ3MoICRhc3NvY19hcmdzLCAkY29udHJvbF9kZWZhdWx0cyApOwoKCQlpZiAoIGlzc2V0KCAkY29udHJvbF9hcmdzWydwbHVnaW4nXSApICkgewoJCQlpZiAoICEgcHJlZ19tYXRjaCggJy9eW0EtWmEtejAtOVwtXSokLycsICRjb250cm9sX2FyZ3NbJ3BsdWdpbiddICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBwbHVnaW4gbmFtZSBzcGVjaWZpZWQuIFRoZSBibG9jayBlZGl0b3IgY2FuIG9ubHkgcmVnaXN0ZXIgYmxvY2tzIGZvciBwbHVnaW5zIHRoYXQgaGF2ZSBub3RoaW5nIGJ1dCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgb3IgZGFzaGVzIGluIHRoZWlyIHNsdWcuJyApOwoJCQl9CgkJfQoKCQkkZGF0YVsnbmFtZXNwYWNlJ10gICAgPSAkY29udHJvbF9hcmdzWydwbHVnaW4nXSA/ICRjb250cm9sX2FyZ3NbJ3BsdWdpbiddIDogJHRoaXMtPmdldF90aGVtZV9uYW1lKCAkY29udHJvbF9hcmdzWyd0aGVtZSddICk7CgkJJGRhdGFbJ21hY2hpbmVfbmFtZSddID0gJHRoaXMtPmdlbmVyYXRlX21hY2hpbmVfbmFtZSggJHNsdWcgKTsKCQkkZGF0YVsncGx1Z2luJ10gICAgICAgPSAkY29udHJvbF9hcmdzWydwbHVnaW4nXSA/IHRydWUgOiBmYWxzZTsKCQkkZGF0YVsndGhlbWUnXSAgICAgICAgPSAhICRkYXRhWydwbHVnaW4nXTsKCgkJJGJsb2NrX2RpciA9ICR0aGlzLT5nZXRfb3V0cHV0X3BhdGgoICRjb250cm9sX2FyZ3MsICcvYmxvY2tzJyApOwoJCWlmICggISAkYmxvY2tfZGlyICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gcGx1Z2luIG9yIHRoZW1lIHNlbGVjdGVkLicgKTsKCQl9CgoJCSRmaWxlc190b19jcmVhdGUgPSBbCgkJCSJ7JGJsb2NrX2Rpcn0veyRzbHVnfS5waHAiICAgICAgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdibG9jay1waHAubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkieyRibG9ja19kaXJ9L3skc2x1Z30vaW5kZXguanMiICAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAnYmxvY2staW5kZXgtanMubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkieyRibG9ja19kaXJ9L3skc2x1Z30vZWRpdG9yLmNzcyIgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAnYmxvY2stZWRpdG9yLWNzcy5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JGJsb2NrX2Rpcn0veyRzbHVnfS9zdHlsZS5jc3MiICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdibG9jay1zdHlsZS1jc3MubXVzdGFjaGUnLCAkZGF0YSApLAoJCV07CgkJJGZpbGVzX3dyaXR0ZW4gICA9ICR0aGlzLT5jcmVhdGVfZmlsZXMoICRmaWxlc190b19jcmVhdGUsICRjb250cm9sX2FyZ3NbJ2ZvcmNlJ10gKTsKCQkkc2tpcF9tZXNzYWdlICAgID0gJ0FsbCBibG9jayBmaWxlcyB3ZXJlIHNraXBwZWQuJzsKCQkkc3VjY2Vzc19tZXNzYWdlID0gIkNyZWF0ZWQgYmxvY2sgJ3skZGF0YVsndGl0bGVfdWNmaXJzdCddfScuIjsKCQkkdGhpcy0+bG9nX3doZXRoZXJfZmlsZXNfd3JpdHRlbiggJGZpbGVzX3dyaXR0ZW4sICRza2lwX21lc3NhZ2UsICRzdWNjZXNzX21lc3NhZ2UgKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzdGFydGVyIGNvZGUgZm9yIGEgdGhlbWUgYmFzZWQgb24gX3MuCgkgKgoJICogU2VlIHRoZSBbVW5kZXJzY29yZXMgd2Vic2l0ZV0oaHR0cHM6Ly91bmRlcnNjb3Jlcy5tZS8pIGZvciBtb3JlIGRldGFpbHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzbHVnPgoJICogOiBUaGUgc2x1ZyBmb3IgdGhlIG5ldyB0aGVtZSwgdXNlZCBmb3IgcHJlZml4aW5nIGZ1bmN0aW9ucy4KCSAqCgkgKiBbLS1hY3RpdmF0ZV0KCSAqIDogQWN0aXZhdGUgdGhlIG5ld2x5IGRvd25sb2FkZWQgdGhlbWUuCgkgKgoJICogWy0tZW5hYmxlLW5ldHdvcmtdCgkgKiA6IEVuYWJsZSB0aGUgbmV3bHkgZG93bmxvYWRlZCB0aGVtZSBmb3IgdGhlIGVudGlyZSBuZXR3b3JrLgoJICoKCSAqIFstLXRoZW1lX25hbWU9PHRpdGxlPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdUaGVtZSBOYW1lOicgaGVhZGVyIGluICdzdHlsZS5jc3MnLgoJICoKCSAqIFstLWF1dGhvcj08ZnVsbC1uYW1lPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdBdXRob3I6JyBoZWFkZXIgaW4gJ3N0eWxlLmNzcycuCgkgKgoJICogWy0tYXV0aG9yX3VyaT08dXJpPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdBdXRob3IgVVJJOicgaGVhZGVyIGluICdzdHlsZS5jc3MnLgoJICoKCSAqIFstLXNhc3NpZnldCgkgKiA6IEluY2x1ZGUgc3R5bGVzaGVldHMgYXMgU0FTUy4KCSAqCgkgKiBbLS13b29jb21tZXJjZV0KCSAqIDogSW5jbHVkZSBXb29Db21tZXJjZSBib2lsZXJwbGF0ZSBmaWxlcy4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogT3ZlcndyaXRlIGZpbGVzIHRoYXQgYWxyZWFkeSBleGlzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdlbmVyYXRlIGEgdGhlbWUgd2l0aCBuYW1lICJTYW1wbGUgVGhlbWUiIGFuZCBhdXRob3IgIkpvaG4gRG9lIgoJICogICAgICQgd3Agc2NhZmZvbGQgX3Mgc2FtcGxlLXRoZW1lIC0tdGhlbWVfbmFtZT0iU2FtcGxlIFRoZW1lIiAtLWF1dGhvcj0iSm9obiBEb2UiCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCB0aGVtZSAnU2FtcGxlIFRoZW1lJy4KCSAqCgkgKiBAYWxpYXMgX3MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuZGVyc2NvcmVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSR0aGVtZV9zbHVnID0gJGFyZ3NbMF07CgkJJHRoZW1lX3BhdGggPSBXUF9DT05URU5UX0RJUiAuICcvdGhlbWVzJzsKCQkkdXJsICAgICAgICA9ICdodHRwczovL3VuZGVyc2NvcmVzLm1lJzsKCQkkdGltZW91dCAgICA9IDMwOwoKCQlpZiAoICEgcHJlZ19tYXRjaCggJy9eW2Etel9dXHcrJC9pJywgc3RyX3JlcGxhY2UoICctJywgJ18nLCAkdGhlbWVfc2x1ZyApICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIHRoZW1lIHNsdWcgc3BlY2lmaWVkLiBUaGVtZSBzbHVncyBjYW4gb25seSBjb250YWluIGxldHRlcnMsIG51bWJlcnMsIHVuZGVyc2NvcmVzIGFuZCBoeXBoZW5zLCBhbmQgY2FuIG9ubHkgc3RhcnQgd2l0aCBhIGxldHRlciBvciB1bmRlcnNjb3JlLicgKTsKCQl9CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3RoZW1lX25hbWUnID0+IHVjZmlyc3QoICR0aGVtZV9zbHVnICksCgkJCSdhdXRob3InICAgICA9PiAnTWUnLAoJCQknYXV0aG9yX3VyaScgPT4gJycsCgkJXTsKCQkkZGF0YSAgICAgPSB3cF9wYXJzZV9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICk7CgoJCSRfc190aGVtZV9wYXRoID0gIiR0aGVtZV9wYXRoLyRkYXRhW3RoZW1lX25hbWVdIjsKCgkJJGVycm9yX21zZyA9ICR0aGlzLT5jaGVja190YXJnZXRfZGlyZWN0b3J5KCAndGhlbWUnLCAkX3NfdGhlbWVfcGF0aCApOwoJCWlmICggISBlbXB0eSggJGVycm9yX21zZyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB0aGVtZSBzbHVnIHNwZWNpZmllZC4geyRlcnJvcl9tc2d9IiApOwoJCX0KCgkJJGZvcmNlICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICk7CgkJJHNob3VsZF93cml0ZV9maWxlID0gJHRoaXMtPnByb21wdF9pZl9maWxlc193aWxsX2JlX292ZXJ3cml0dGVuKCAkX3NfdGhlbWVfcGF0aCwgJGZvcmNlICk7CgkJaWYgKCAhICRzaG91bGRfd3JpdGVfZmlsZSApIHsKCQkJV1BfQ0xJOjpsb2coICdObyBmaWxlcyBjcmVhdGVkJyApOwoJCQlkaWU7CgkJfQoKCQkkdGhlbWVfZGVzY3JpcHRpb24gPSAiQ3VzdG9tIHRoZW1lOiB7JGRhdGFbJ3RoZW1lX25hbWUnXX0sIGRldmVsb3BlZCBieSB7JGRhdGFbJ2F1dGhvciddfSI7CgoJCSRib2R5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gW107CgkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfbmFtZSddICAgICAgICAgICAgPSAkZGF0YVsndGhlbWVfbmFtZSddOwoJCSRib2R5Wyd1bmRlcnNjb3Jlc21lX3NsdWcnXSAgICAgICAgICAgID0gJHRoZW1lX3NsdWc7CgkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfYXV0aG9yJ10gICAgICAgICAgPSAkZGF0YVsnYXV0aG9yJ107CgkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfYXV0aG9yX3VyaSddICAgICAgPSAkZGF0YVsnYXV0aG9yX3VyaSddOwoJCSRib2R5Wyd1bmRlcnNjb3Jlc21lX2Rlc2NyaXB0aW9uJ10gICAgID0gJHRoZW1lX2Rlc2NyaXB0aW9uOwoJCSRib2R5Wyd1bmRlcnNjb3Jlc21lX2dlbmVyYXRlX3N1Ym1pdCddID0gJ0dlbmVyYXRlJzsKCQkkYm9keVsndW5kZXJzY29yZXNtZV9nZW5lcmF0ZSddICAgICAgICA9ICcxJzsKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3Nhc3NpZnknICkgKSB7CgkJCSRib2R5Wyd1bmRlcnNjb3Jlc21lX3Nhc3MnXSA9IDE7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3dvb2NvbW1lcmNlJyApICkgewoJCQkkYm9keVsndW5kZXJzY29yZXNtZV93b29jb21tZXJjZSddID0gMTsKCQl9CgoJCSR0bXBmbmFtZSAgPSB3cF90ZW1wbmFtKCAkdXJsICk7CgkJJHBvc3RfYXJncyA9IFsKCQkJJ3RpbWVvdXQnICA9PiAkdGltZW91dCwKCQkJJ2JvZHknICAgICA9PiAkYm9keSwKCQkJJ3N0cmVhbScgICA9PiB0cnVlLAoJCQknZmlsZW5hbWUnID0+ICR0bXBmbmFtZSwKCQldOwoKCQkkcmVzcG9uc2UgPSB3cF9yZW1vdGVfcG9zdCggJHVybCwgJHBvc3RfYXJncyApOwoKCQkvLyBXb3JrYXJvdW5kIHRvIGdldCBzY2FmZm9sZGluZyB0byB3b3JrIHdpdGhpbiBUcmF2aXMgQ0kuCgkJLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC9pc3N1ZXMvMTgxCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkKCQkJJiYgZmFsc2UgIT09IHN0cnBvcyggJHJlc3BvbnNlLT5nZXRfZXJyb3JfbWVzc2FnZSgpLCAnZ251dGxzX2hhbmRzaGFrZSgpIGZhaWxlZCcgKQoJCSkgewoJCQkvLyBDZXJ0aWZpY2F0ZSBwcm9ibGVtLCBmYWxsaW5nIGJhY2sgdG8gdW5zZWN1cmVkIHJlcXVlc3QgaW5zdGVhZC4KCQkJJGFsdF91cmwgPSBzdHJfcmVwbGFjZSggJ2h0dHBzOi8vJywgJ2h0dHA6Ly8nLCAkdXJsICk7CgkJCVdQX0NMSTo6d2FybmluZyggIlNlY3VyZWQgcmVxdWVzdCB0byB7JHVybH0gZmFpbGVkLCB1c2luZyB7JGFsdF91cmx9IGFzIGEgZmFsbGJhY2suIiApOwoJCQkkcmVzcG9uc2UgPSB3cF9yZW1vdGVfcG9zdCggJGFsdF91cmwsICRwb3N0X2FyZ3MgKTsKCQl9CgoJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzcG9uc2UgKTsKCQl9CgoJCSRyZXNwb25zZV9jb2RlID0gd3BfcmVtb3RlX3JldHJpZXZlX3Jlc3BvbnNlX2NvZGUoICRyZXNwb25zZSApOwoJCWlmICggMjAwICE9PSAoaW50KSAkcmVzcG9uc2VfY29kZSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGNyZWF0ZSB0aGVtZSAocmVjZWl2ZWQgeyRyZXNwb25zZV9jb2RlfSByZXNwb25zZSkuIiApOwoJCX0KCgkJJHRoaXMtPm1heWJlX2NyZWF0ZV90aGVtZXNfZGlyKCk7CgoJCSR0aGlzLT5pbml0X3dwX2ZpbGVzeXN0ZW0oKTsKCgkJJHVuemlwX3Jlc3VsdCA9IHVuemlwX2ZpbGUoICR0bXBmbmFtZSwgJHRoZW1lX3BhdGggKTsKCQl1bmxpbmsoICR0bXBmbmFtZSApOwoKCQlpZiAoIHRydWUgPT09ICR1bnppcF9yZXN1bHQgKSB7CgkJCSRmaWxlc190b19jcmVhdGUgPSBbCgkJCQkieyR0aGVtZV9wYXRofS97JHRoZW1lX3NsdWd9Ly5lZGl0b3Jjb25maWciID0+IGZpbGVfZ2V0X2NvbnRlbnRzKCBzZWxmOjpnZXRfdGVtcGxhdGVfcGF0aCggJy5lZGl0b3Jjb25maWcnICkgKSwKCQkJXTsKCQkJJHRoaXMtPmNyZWF0ZV9maWxlcyggJGZpbGVzX3RvX2NyZWF0ZSwgZmFsc2UgKTsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQ3JlYXRlZCB0aGVtZSAneyRkYXRhWyd0aGVtZV9uYW1lJ119Jy4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBkZWNvbXByZXNzIHlvdXIgdGhlbWUgZmlsZXMgKCd7JHRtcGZuYW1lfScpIGF0ICd7JHRoZW1lX3BhdGh9JzogeyR1bnppcF9yZXN1bHQtPmdldF9lcnJvcl9tZXNzYWdlKCl9IiApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhY3RpdmF0ZScgKSApIHsKCQkJV1BfQ0xJOjpydW5fY29tbWFuZCggWyAndGhlbWUnLCAnYWN0aXZhdGUnLCAkdGhlbWVfc2x1ZyBdICk7CgkJfSBlbHNlaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdlbmFibGUtbmV0d29yaycgKSApIHsKCQkJV1BfQ0xJOjpydW5fY29tbWFuZCggWyAndGhlbWUnLCAnZW5hYmxlJywgJHRoZW1lX3NsdWcgXSwgWyAnbmV0d29yaycgPT4gdHJ1ZSBdICk7CgkJfQoJfQoKCS8qKgoJICogR2VuZXJhdGVzIGNoaWxkIHRoZW1lIGJhc2VkIG9uIGFuIGV4aXN0aW5nIHRoZW1lLgoJICoKCSAqIENyZWF0ZXMgYSBjaGlsZCB0aGVtZSBmb2xkZXIgd2l0aCBgZnVuY3Rpb25zLnBocGAgYW5kIGBzdHlsZS5jc3NgIGZpbGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2x1Zz4KCSAqIDogVGhlIHNsdWcgZm9yIHRoZSBuZXcgY2hpbGQgdGhlbWUuCgkgKgoJICogLS1wYXJlbnRfdGhlbWU9PHNsdWc+CgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnVGVtcGxhdGU6JyBoZWFkZXIgaW4gJ3N0eWxlLmNzcycuCgkgKgoJICogWy0tdGhlbWVfbmFtZT08dGl0bGU+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ1RoZW1lIE5hbWU6JyBoZWFkZXIgaW4gJ3N0eWxlLmNzcycuCgkgKgoJICogWy0tYXV0aG9yPTxmdWxsLW5hbWU+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0F1dGhvcjonIGhlYWRlciBpbiAnc3R5bGUuY3NzJy4KCSAqCgkgKiBbLS1hdXRob3JfdXJpPTx1cmk+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0F1dGhvciBVUkk6JyBoZWFkZXIgaW4gJ3N0eWxlLmNzcycuCgkgKgoJICogWy0tdGhlbWVfdXJpPTx1cmk+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ1RoZW1lIFVSSTonIGhlYWRlciBpbiAnc3R5bGUuY3NzJy4KCSAqCgkgKiBbLS1hY3RpdmF0ZV0KCSAqIDogQWN0aXZhdGUgdGhlIG5ld2x5IGNyZWF0ZWQgY2hpbGQgdGhlbWUuCgkgKgoJICogWy0tZW5hYmxlLW5ldHdvcmtdCgkgKiA6IEVuYWJsZSB0aGUgbmV3bHkgY3JlYXRlZCBjaGlsZCB0aGVtZSBmb3IgdGhlIGVudGlyZSBuZXR3b3JrLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgYSAnc2FtcGxlLXRoZW1lJyBjaGlsZCB0aGVtZSBiYXNlZCBvbiBUd2VudHlTaXh0ZWVuCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBjaGlsZC10aGVtZSBzYW1wbGUtdGhlbWUgLS1wYXJlbnRfdGhlbWU9dHdlbnR5c2l4dGVlbgoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgJy92YXIvd3d3L2V4YW1wbGUuY29tL3B1YmxpY19odG1sL3dwLWNvbnRlbnQvdGhlbWVzL3NhbXBsZS10aGVtZScuCgkgKgoJICogQHN1YmNvbW1hbmQgY2hpbGQtdGhlbWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNoaWxkX3RoZW1lKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRoZW1lX3NsdWcgPSAkYXJnc1swXTsKCgkJaWYgKCBpbl9hcnJheSggJHRoZW1lX3NsdWcsIFsgJy4nLCAnLi4nIF0sIHRydWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgdGhlbWUgc2x1ZyBzcGVjaWZpZWQuIFRoZSBzbHVnIGNhbm5vdCBiZSAnLicgb3IgJy4uJy4iICk7CgkJfQoKCQkkZGVmYXVsdHMgPSBbCgkJCSd0aGVtZV9uYW1lJyA9PiB1Y2ZpcnN0KCAkdGhlbWVfc2x1ZyApLAoJCQknYXV0aG9yJyAgICAgPT4gJ01lJywKCQkJJ2F1dGhvcl91cmknID0+ICcnLAoJCQkndGhlbWVfdXJpJyAgPT4gJycsCgkJXTsKCgkJJGRhdGEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSB3cF9wYXJzZV9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICk7CgkJJGRhdGFbJ3NsdWcnXSAgICAgICAgICAgICAgICAgICAgICAgPSAkdGhlbWVfc2x1ZzsKCQkkZGF0YVsncGFyZW50X3RoZW1lX2Z1bmN0aW9uX3NhZmUnXSA9IHN0cl9yZXBsYWNlKCBbICcgJywgJy0nIF0sICdfJywgJGRhdGFbJ3BhcmVudF90aGVtZSddICk7CgkJJGRhdGFbJ2Rlc2NyaXB0aW9uJ10gICAgICAgICAgICAgICAgPSB1Y2ZpcnN0KCAkZGF0YVsncGFyZW50X3RoZW1lJ10gKSAuICcgY2hpbGQgdGhlbWUuJzsKCgkJJHRoZW1lX2RpciA9IFdQX0NPTlRFTlRfRElSIC4gIi90aGVtZXMveyR0aGVtZV9zbHVnfSI7CgoJCSRlcnJvcl9tc2cgPSAkdGhpcy0+Y2hlY2tfdGFyZ2V0X2RpcmVjdG9yeSggJ3RoZW1lJywgJHRoZW1lX2RpciApOwoJCWlmICggISBlbXB0eSggJGVycm9yX21zZyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB0aGVtZSBzbHVnIHNwZWNpZmllZC4geyRlcnJvcl9tc2d9IiApOwoJCX0KCgkJJHRoZW1lX3N0eWxlX3BhdGggICAgID0gInskdGhlbWVfZGlyfS9zdHlsZS5jc3MiOwoJCSR0aGVtZV9mdW5jdGlvbnNfcGF0aCA9ICJ7JHRoZW1lX2Rpcn0vZnVuY3Rpb25zLnBocCI7CgoJCSR0aGlzLT5tYXliZV9jcmVhdGVfdGhlbWVzX2RpcigpOwoKCQkkZmlsZXNfdG9fY3JlYXRlID0gWwoJCQkkdGhlbWVfc3R5bGVfcGF0aCAgICAgICAgICAgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ2NoaWxkX3RoZW1lLm11c3RhY2hlJywgJGRhdGEgKSwKCQkJJHRoZW1lX2Z1bmN0aW9uc19wYXRoICAgICAgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdjaGlsZF90aGVtZV9mdW5jdGlvbnMubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkieyR0aGVtZV9kaXJ9Ly5lZGl0b3Jjb25maWciID0+IGZpbGVfZ2V0X2NvbnRlbnRzKCBzZWxmOjpnZXRfdGVtcGxhdGVfcGF0aCggJy5lZGl0b3Jjb25maWcnICkgKSwKCQldOwoJCSRmb3JjZSAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKTsKCQkkZmlsZXNfd3JpdHRlbiAgID0gJHRoaXMtPmNyZWF0ZV9maWxlcyggJGZpbGVzX3RvX2NyZWF0ZSwgJGZvcmNlICk7CgkJJHNraXBfbWVzc2FnZSAgICA9ICdBbGwgdGhlbWUgZmlsZXMgd2VyZSBza2lwcGVkLic7CgkJJHN1Y2Nlc3NfbWVzc2FnZSA9ICJDcmVhdGVkICd7JHRoZW1lX2Rpcn0nLiI7CgkJJHRoaXMtPmxvZ193aGV0aGVyX2ZpbGVzX3dyaXR0ZW4oICRmaWxlc193cml0dGVuLCAkc2tpcF9tZXNzYWdlLCAkc3VjY2Vzc19tZXNzYWdlICk7CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWN0aXZhdGUnICkgKSB7CgkJCVdQX0NMSTo6cnVuX2NvbW1hbmQoIFsgJ3RoZW1lJywgJ2FjdGl2YXRlJywgJHRoZW1lX3NsdWcgXSApOwoJCX0gZWxzZWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlLW5ldHdvcmsnICkgKSB7CgkJCVdQX0NMSTo6cnVuX2NvbW1hbmQoIFsgJ3RoZW1lJywgJ2VuYWJsZScsICR0aGVtZV9zbHVnIF0sIFsgJ25ldHdvcmsnID0+IHRydWUgXSApOwoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9vdXRwdXRfcGF0aCggJGFzc29jX2FyZ3MsICRzdWJkaXIgKSB7CgkJaWYgKCAkYXNzb2NfYXJnc1sndGhlbWUnXSApIHsKCQkJJHRoZW1lID0gJGFzc29jX2FyZ3NbJ3RoZW1lJ107CgkJCWlmICggaXNfc3RyaW5nKCAkdGhlbWUgKSApIHsKCQkJCSRwYXRoID0gZ2V0X3RoZW1lX3Jvb3QoICR0aGVtZSApIC4gIi97JHRoZW1lfSI7CgkJCX0gZWxzZSB7CgkJCQkkcGF0aCA9IGdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpOwoJCQl9CgkJCWlmICggISBpc19kaXIoICRwYXRoICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ2FuJ3QgZmluZCAneyR0aGVtZX0nIHRoZW1lLiIgKTsKCQkJfQoJCX0gZWxzZWlmICggJGFzc29jX2FyZ3NbJ3BsdWdpbiddICkgewoJCQkkcGx1Z2luID0gJGFzc29jX2FyZ3NbJ3BsdWdpbiddOwoJCQkkcGF0aCAgID0gV1BfUExVR0lOX0RJUiAuICIveyRwbHVnaW59IjsKCQkJaWYgKCAhIGlzX2RpciggJHBhdGggKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDYW4ndCBmaW5kICd7JHBsdWdpbn0nIHBsdWdpbi4iICk7CgkJCX0KCQl9IGVsc2UgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkcGF0aCAuPSAkc3ViZGlyOwoKCQlyZXR1cm4gJHBhdGg7Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgc3RhcnRlciBjb2RlIGZvciBhIHBsdWdpbi4KCSAqCgkgKiBUaGUgZm9sbG93aW5nIGZpbGVzIGFyZSBhbHdheXMgZ2VuZXJhdGVkOgoJICoKCSAqICogYHBsdWdpbi1zbHVnLnBocGAgaXMgdGhlIG1haW4gUEhQIHBsdWdpbiBmaWxlLgoJICogKiBgcmVhZG1lLnR4dGAgaXMgdGhlIHJlYWRtZSBmaWxlIGZvciB0aGUgcGx1Z2luLgoJICogKiBgcGFja2FnZS5qc29uYCBuZWVkZWQgYnkgTlBNIGhvbGRzIHZhcmlvdXMgbWV0YWRhdGEgcmVsZXZhbnQgdG8gdGhlIHByb2plY3QuIFBhY2thZ2VzOiBgZ3J1bnRgLCBgZ3J1bnQtd3AtaTE4bmAgYW5kIGBncnVudC13cC1yZWFkbWUtdG8tbWFya2Rvd25gLiBTY3JpcHRzOiBgc3RhcnRgLCBgcmVhZG1lYCwgYGkxOG5gLgoJICogKiBgR3J1bnRmaWxlLmpzYCBpcyB0aGUgSlMgZmlsZSBjb250YWluaW5nIEdydW50IHRhc2tzLiBUYXNrczogYGkxOG5gIGNvbnRhaW5pbmcgYGFkZHRleHRkb21haW5gIGFuZCBgbWFrZXBvdGAsIGByZWFkbWVgIGNvbnRhaW5pbmcgYHdwX3JlYWRtZV90b19tYXJrZG93bmAuCgkgKiAqIGAuZWRpdG9yY29uZmlnYCBpcyB0aGUgY29uZmlndXJhdGlvbiBmaWxlIGZvciBFZGl0b3IuCgkgKiAqIGAuZ2l0aWdub3JlYCB0ZWxscyB3aGljaCBmaWxlcyAob3IgcGF0dGVybnMpIGdpdCBzaG91bGQgaWdub3JlLgoJICogKiBgLmRpc3RpZ25vcmVgIHRlbGxzIHdoaWNoIGZpbGVzIGFuZCBmb2xkZXJzIHNob3VsZCBiZSBpZ25vcmVkIGluIGRpc3RyaWJ1dGlvbi4KCSAqCgkgKiBUaGUgZm9sbG93aW5nIGZpbGVzIGFyZSBhbHNvIGluY2x1ZGVkIHVubGVzcyB0aGUgYC0tc2tpcC10ZXN0c2AgaXMgdXNlZDoKCSAqCgkgKiAqIGBwaHB1bml0LnhtbC5kaXN0YCBpcyB0aGUgY29uZmlndXJhdGlvbiBmaWxlIGZvciBQSFBVbml0LgoJICogKiBgLnRyYXZpcy55bWxgIGlzIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIFRyYXZpcyBDSS4gVXNlIGAtLWNpPTxwcm92aWRlcj5gIHRvIHNlbGVjdCBhIGRpZmZlcmVudCBzZXJ2aWNlLgoJICogKiBgYmluL2luc3RhbGwtd3AtdGVzdHMuc2hgIGNvbmZpZ3VyZXMgdGhlIFdvcmRQcmVzcyB0ZXN0IHN1aXRlIGFuZCBhIHRlc3QgZGF0YWJhc2UuCgkgKiAqIGB0ZXN0cy9ib290c3RyYXAucGhwYCBpcyB0aGUgZmlsZSB0aGF0IG1ha2VzIHRoZSBjdXJyZW50IHBsdWdpbiBhY3RpdmUgd2hlbiBydW5uaW5nIHRoZSB0ZXN0IHN1aXRlLgoJICogKiBgdGVzdHMvdGVzdC1zYW1wbGUucGhwYCBpcyBhIHNhbXBsZSBmaWxlIGNvbnRhaW5pbmcgdGVzdCBjYXNlcy4KCSAqICogYC5waHBjcy54bWwuZGlzdGAgaXMgYSBjb2xsZWN0aW9uIG9mIFBIUF9Db2RlU25pZmZlciBydWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNsdWc+CgkgKiA6IFRoZSBpbnRlcm5hbCBuYW1lIG9mIHRoZSBwbHVnaW4uCgkgKgoJICogWy0tZGlyPTxkaXJuYW1lPl0KCSAqIDogUHV0IHRoZSBuZXcgcGx1Z2luIGluIHNvbWUgYXJiaXRyYXJ5IGRpcmVjdG9yeSBwYXRoLiBQbHVnaW4gZGlyZWN0b3J5IHdpbGwgYmUgcGF0aCBwbHVzIHN1cHBsaWVkIHNsdWcuCgkgKgoJICogWy0tcGx1Z2luX25hbWU9PHRpdGxlPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdQbHVnaW4gTmFtZTonIGhlYWRlci4KCSAqCgkgKiBbLS1wbHVnaW5fZGVzY3JpcHRpb249PGRlc2NyaXB0aW9uPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdEZXNjcmlwdGlvbjonIGhlYWRlci4KCSAqCgkgKiBbLS1wbHVnaW5fYXV0aG9yPTxhdXRob3I+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0F1dGhvcjonIGhlYWRlci4KCSAqCgkgKiBbLS1wbHVnaW5fYXV0aG9yX3VyaT08dXJsPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdBdXRob3IgVVJJOicgaGVhZGVyLgoJICoKCSAqIFstLXBsdWdpbl91cmk9PHVybD5dCgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnUGx1Z2luIFVSSTonIGhlYWRlci4KCSAqCgkgKiBbLS1za2lwLXRlc3RzXQoJICogOiBEb24ndCBnZW5lcmF0ZSBmaWxlcyBmb3IgdW5pdCB0ZXN0aW5nLgoJICoKCSAqIFstLWNpPTxwcm92aWRlcj5dCgkgKiA6IENob29zZSBhIGNvbmZpZ3VyYXRpb24gZmlsZSBmb3IgYSBjb250aW51b3VzIGludGVncmF0aW9uIHByb3ZpZGVyLgoJICogLS0tCgkgKiBkZWZhdWx0OiB0cmF2aXMKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdHJhdmlzCgkgKiAgIC0gY2lyY2xlCgkgKiAgIC0gZ2l0bGFiCgkgKiAtLS0KCSAqCgkgKiBbLS1hY3RpdmF0ZV0KCSAqIDogQWN0aXZhdGUgdGhlIG5ld2x5IGdlbmVyYXRlZCBwbHVnaW4uCgkgKgoJICogWy0tYWN0aXZhdGUtbmV0d29ya10KCSAqIDogTmV0d29yayBhY3RpdmF0ZSB0aGUgbmV3bHkgZ2VuZXJhdGVkIHBsdWdpbi4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogT3ZlcndyaXRlIGZpbGVzIHRoYXQgYWxyZWFkeSBleGlzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNjYWZmb2xkIHBsdWdpbiBzYW1wbGUtcGx1Z2luCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCBwbHVnaW4gZmlsZXMuCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCB0ZXN0IGZpbGVzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcGx1Z2luKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBsdWdpbl9zbHVnICAgID0gJGFyZ3NbMF07CgkJJHBsdWdpbl9uYW1lICAgID0gdWN3b3Jkcyggc3RyX3JlcGxhY2UoICctJywgJyAnLCAkcGx1Z2luX3NsdWcgKSApOwoJCSRwbHVnaW5fcGFja2FnZSA9IHN0cl9yZXBsYWNlKCAnICcsICdfJywgJHBsdWdpbl9uYW1lICk7CgoJCWlmICggaW5fYXJyYXkoICRwbHVnaW5fc2x1ZywgWyAnLicsICcuLicgXSwgdHJ1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCBwbHVnaW4gc2x1ZyBzcGVjaWZpZWQuIFRoZSBzbHVnIGNhbm5vdCBiZSAnLicgb3IgJy4uJy4iICk7CgkJfQoKCQkkZGVmYXVsdHMgPSBbCgkJCSdwbHVnaW5fc2x1ZycgICAgICAgICA9PiAkcGx1Z2luX3NsdWcsCgkJCSdwbHVnaW5fbmFtZScgICAgICAgICA9PiAkcGx1Z2luX25hbWUsCgkJCSdwbHVnaW5fcGFja2FnZScgICAgICA9PiAkcGx1Z2luX3BhY2thZ2UsCgkJCSdwbHVnaW5fZGVzY3JpcHRpb24nICA9PiAnUExVR0lOIERFU0NSSVBUSU9OIEhFUkUnLAoJCQkncGx1Z2luX2F1dGhvcicgICAgICAgPT4gJ1lPVVIgTkFNRSBIRVJFJywKCQkJJ3BsdWdpbl9hdXRob3JfdXJpJyAgID0+ICdZT1VSIFNJVEUgSEVSRScsCgkJCSdwbHVnaW5fdXJpJyAgICAgICAgICA9PiAnUExVR0lOIFNJVEUgSEVSRScsCgkJCSdwbHVnaW5fdGVzdGVkX3VwX3RvJyA9PiBnZXRfYmxvZ2luZm8oICd2ZXJzaW9uJyApLAoJCV07CgkJJGRhdGEgICAgID0gd3BfcGFyc2VfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApOwoKCQkkZGF0YVsndGV4dGRvbWFpbiddID0gJHBsdWdpbl9zbHVnOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydkaXInXSApICkgewoJCQlpZiAoICEgaXNfZGlyKCAkYXNzb2NfYXJnc1snZGlyJ10gKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDYW5ub3QgY3JlYXRlIHBsdWdpbiBpbiBkaXJlY3RvcnkgdGhhdCBkb2Vzbid0IGV4aXN0LiIgKTsKCQkJfQoJCQkkcGx1Z2luX2RpciA9ICJ7JGFzc29jX2FyZ3NbJ2RpciddfS97JHBsdWdpbl9zbHVnfSI7CgkJfSBlbHNlIHsKCQkJJHBsdWdpbl9kaXIgPSBXUF9QTFVHSU5fRElSIC4gIi97JHBsdWdpbl9zbHVnfSI7CgkJCSR0aGlzLT5tYXliZV9jcmVhdGVfcGx1Z2luc19kaXIoKTsKCgkJCSRlcnJvcl9tc2cgPSAkdGhpcy0+Y2hlY2tfdGFyZ2V0X2RpcmVjdG9yeSggJ3BsdWdpbicsICRwbHVnaW5fZGlyICk7CgkJCWlmICggISBlbXB0eSggJGVycm9yX21zZyApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgcGx1Z2luIHNsdWcgc3BlY2lmaWVkLiB7JGVycm9yX21zZ30iICk7CgkJCX0KCQl9CgoJCSRwbHVnaW5fcGF0aCAgICAgICAgPSAieyRwbHVnaW5fZGlyfS97JHBsdWdpbl9zbHVnfS5waHAiOwoJCSRwbHVnaW5fcmVhZG1lX3BhdGggPSAieyRwbHVnaW5fZGlyfS9yZWFkbWUudHh0IjsKCgkJJGZpbGVzX3RvX2NyZWF0ZSA9IFsKCQkJJHBsdWdpbl9wYXRoICAgICAgICAgICAgICAgICAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLm11c3RhY2hlJywgJGRhdGEgKSwKCQkJJHBsdWdpbl9yZWFkbWVfcGF0aCAgICAgICAgICAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLXJlYWRtZS5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JHBsdWdpbl9kaXJ9L3BhY2thZ2UuanNvbiIgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ3BsdWdpbi1wYWNrYWdlcy5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JHBsdWdpbl9kaXJ9L0dydW50ZmlsZS5qcyIgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ3BsdWdpbi1ncnVudGZpbGUubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkieyRwbHVnaW5fZGlyfS8uZ2l0aWdub3JlIiAgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tZ2l0aWdub3JlLm11c3RhY2hlJywgJGRhdGEgKSwKCQkJInskcGx1Z2luX2Rpcn0vLmRpc3RpZ25vcmUiICAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLWRpc3RpZ25vcmUubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkieyRwbHVnaW5fZGlyfS8uZWRpdG9yY29uZmlnIiA9PiBmaWxlX2dldF9jb250ZW50cyggc2VsZjo6Z2V0X3RlbXBsYXRlX3BhdGgoICcuZWRpdG9yY29uZmlnJyApICksCgkJXTsKCQkkZm9yY2UgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICk7CgkJJGZpbGVzX3dyaXR0ZW4gICA9ICR0aGlzLT5jcmVhdGVfZmlsZXMoICRmaWxlc190b19jcmVhdGUsICRmb3JjZSApOwoKCQkkc2tpcF9tZXNzYWdlICAgID0gJ0FsbCBwbHVnaW4gZmlsZXMgd2VyZSBza2lwcGVkLic7CgkJJHN1Y2Nlc3NfbWVzc2FnZSA9ICdDcmVhdGVkIHBsdWdpbiBmaWxlcy4nOwoJCSR0aGlzLT5sb2dfd2hldGhlcl9maWxlc193cml0dGVuKCAkZmlsZXNfd3JpdHRlbiwgJHNraXBfbWVzc2FnZSwgJHN1Y2Nlc3NfbWVzc2FnZSApOwoKCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC10ZXN0cycgKSApIHsKCQkJJGNvbW1hbmRfYXJncyA9IFsKCQkJCSdkaXInICAgPT4gJHBsdWdpbl9kaXIsCgkJCQknY2knICAgID0+IGVtcHR5KCAkYXNzb2NfYXJnc1snY2knXSApID8gJycgOiAkYXNzb2NfYXJnc1snY2knXSwKCQkJCSdmb3JjZScgPT4gJGZvcmNlLAoJCQldOwoJCQlXUF9DTEk6OnJ1bl9jb21tYW5kKCBbICdzY2FmZm9sZCcsICdwbHVnaW4tdGVzdHMnLCAkcGx1Z2luX3NsdWcgXSwgJGNvbW1hbmRfYXJncyApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhY3RpdmF0ZScgKSApIHsKCQkJV1BfQ0xJOjpydW5fY29tbWFuZCggWyAncGx1Z2luJywgJ2FjdGl2YXRlJywgJHBsdWdpbl9zbHVnIF0gKTsKCQl9IGVsc2VpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FjdGl2YXRlLW5ldHdvcmsnICkgKSB7CgkJCVdQX0NMSTo6cnVuX2NvbW1hbmQoIFsgJ3BsdWdpbicsICdhY3RpdmF0ZScsICRwbHVnaW5fc2x1ZyBdLCBbICduZXR3b3JrJyA9PiB0cnVlIF0gKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgZmlsZXMgbmVlZGVkIGZvciBydW5uaW5nIFBIUFVuaXQgdGVzdHMgaW4gYSBwbHVnaW4uCgkgKgoJICogVGhlIGZvbGxvd2luZyBmaWxlcyBhcmUgZ2VuZXJhdGVkIGJ5IGRlZmF1bHQ6CgkgKgoJICogKiBgcGhwdW5pdC54bWwuZGlzdGAgaXMgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBmb3IgUEhQVW5pdC4KCSAqICogYC50cmF2aXMueW1sYCBpcyB0aGUgY29uZmlndXJhdGlvbiBmaWxlIGZvciBUcmF2aXMgQ0kuIFVzZSBgLS1jaT08cHJvdmlkZXI+YCB0byBzZWxlY3QgYSBkaWZmZXJlbnQgc2VydmljZS4KCSAqICogYGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoYCBjb25maWd1cmVzIHRoZSBXb3JkUHJlc3MgdGVzdCBzdWl0ZSBhbmQgYSB0ZXN0IGRhdGFiYXNlLgoJICogKiBgdGVzdHMvYm9vdHN0cmFwLnBocGAgaXMgdGhlIGZpbGUgdGhhdCBtYWtlcyB0aGUgY3VycmVudCBwbHVnaW4gYWN0aXZlIHdoZW4gcnVubmluZyB0aGUgdGVzdCBzdWl0ZS4KCSAqICogYHRlc3RzL3Rlc3Qtc2FtcGxlLnBocGAgaXMgYSBzYW1wbGUgZmlsZSBjb250YWluaW5nIHRoZSBhY3R1YWwgdGVzdHMuCgkgKiAqIGAucGhwY3MueG1sLmRpc3RgIGlzIGEgY29sbGVjdGlvbiBvZiBQSFBfQ29kZVNuaWZmZXIgcnVsZXMuCgkgKgoJICogTGVhcm4gbW9yZSBmcm9tIHRoZSBbcGx1Z2luIHVuaXQgdGVzdHMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9tYWtlLndvcmRwcmVzcy5vcmcvY2xpL2hhbmRib29rL3BsdWdpbi11bml0LXRlc3RzLykuCgkgKgoJICogIyMgRU5WSVJPTk1FTlQKCSAqCgkgKiBUaGUgYHRlc3RzL2Jvb3RzdHJhcC5waHBgIGZpbGUgbG9va3MgZm9yIHRoZSBXUF9URVNUU19ESVIgZW52aXJvbm1lbnQKCSAqIHZhcmlhYmxlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj5dCgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gdG8gZ2VuZXJhdGUgdGVzdCBmaWxlcyBmb3IuCgkgKgoJICogWy0tZGlyPTxkaXJuYW1lPl0KCSAqIDogR2VuZXJhdGUgdGVzdCBmaWxlcyBmb3IgYSBub24tc3RhbmRhcmQgcGx1Z2luIHBhdGguIElmIG5vIHBsdWdpbiBzbHVnIGlzIHNwZWNpZmllZCwgdGhlIGRpcmVjdG9yeSBuYW1lIGlzIHVzZWQuCgkgKgoJICogWy0tY2k9PHByb3ZpZGVyPl0KCSAqIDogQ2hvb3NlIGEgY29uZmlndXJhdGlvbiBmaWxlIGZvciBhIGNvbnRpbnVvdXMgaW50ZWdyYXRpb24gcHJvdmlkZXIuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRyYXZpcwoJICogb3B0aW9uczoKCSAqICAgLSB0cmF2aXMKCSAqICAgLSBjaXJjbGUKCSAqICAgLSBnaXRsYWIKCSAqICAgLSBiaXRidWNrZXQKCSAqIC0tLQoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgdW5pdCB0ZXN0IGZpbGVzIGZvciBwbHVnaW4gJ3NhbXBsZS1wbHVnaW4nLgoJICogICAgICQgd3Agc2NhZmZvbGQgcGx1Z2luLXRlc3RzIHNhbXBsZS1wbHVnaW4KCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHRlc3QgZmlsZXMuCgkgKgoJICogQHN1YmNvbW1hbmQgcGx1Z2luLXRlc3RzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwbHVnaW5fdGVzdHMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+c2NhZmZvbGRfcGx1Z2luX3RoZW1lX3Rlc3RzKCAkYXJncywgJGFzc29jX2FyZ3MsICdwbHVnaW4nICk7Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgZmlsZXMgbmVlZGVkIGZvciBydW5uaW5nIFBIUFVuaXQgdGVzdHMgaW4gYSB0aGVtZS4KCSAqCgkgKiBUaGUgZm9sbG93aW5nIGZpbGVzIGFyZSBnZW5lcmF0ZWQgYnkgZGVmYXVsdDoKCSAqCgkgKiAqIGBwaHB1bml0LnhtbC5kaXN0YCBpcyB0aGUgY29uZmlndXJhdGlvbiBmaWxlIGZvciBQSFBVbml0LgoJICogKiBgLnRyYXZpcy55bWxgIGlzIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIFRyYXZpcyBDSS4gVXNlIGAtLWNpPTxwcm92aWRlcj5gIHRvIHNlbGVjdCBhIGRpZmZlcmVudCBzZXJ2aWNlLgoJICogKiBgYmluL2luc3RhbGwtd3AtdGVzdHMuc2hgIGNvbmZpZ3VyZXMgdGhlIFdvcmRQcmVzcyB0ZXN0IHN1aXRlIGFuZCBhIHRlc3QgZGF0YWJhc2UuCgkgKiAqIGB0ZXN0cy9ib290c3RyYXAucGhwYCBpcyB0aGUgZmlsZSB0aGF0IG1ha2VzIHRoZSBjdXJyZW50IHRoZW1lIGFjdGl2ZSB3aGVuIHJ1bm5pbmcgdGhlIHRlc3Qgc3VpdGUuCgkgKiAqIGB0ZXN0cy90ZXN0LXNhbXBsZS5waHBgIGlzIGEgc2FtcGxlIGZpbGUgY29udGFpbmluZyB0aGUgYWN0dWFsIHRlc3RzLgoJICogKiBgLnBocGNzLnhtbC5kaXN0YCBpcyBhIGNvbGxlY3Rpb24gb2YgUEhQX0NvZGVTbmlmZmVyIHJ1bGVzLgoJICoKCSAqIExlYXJuIG1vcmUgZnJvbSB0aGUgW3BsdWdpbiB1bml0IHRlc3RzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vbWFrZS53b3JkcHJlc3Mub3JnL2NsaS9oYW5kYm9vay9wbHVnaW4tdW5pdC10ZXN0cy8pLgoJICoKCSAqICMjIEVOVklST05NRU5UCgkgKgoJICogVGhlIGB0ZXN0cy9ib290c3RyYXAucGhwYCBmaWxlIGxvb2tzIGZvciB0aGUgV1BfVEVTVFNfRElSIGVudmlyb25tZW50CgkgKiB2YXJpYWJsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT5dCgkgKiA6IFRoZSBuYW1lIG9mIHRoZSB0aGVtZSB0byBnZW5lcmF0ZSB0ZXN0IGZpbGVzIGZvci4KCSAqCgkgKiBbLS1kaXI9PGRpcm5hbWU+XQoJICogOiBHZW5lcmF0ZSB0ZXN0IGZpbGVzIGZvciBhIG5vbi1zdGFuZGFyZCB0aGVtZSBwYXRoLiBJZiBubyB0aGVtZSBzbHVnIGlzIHNwZWNpZmllZCwgdGhlIGRpcmVjdG9yeSBuYW1lIGlzIHVzZWQuCgkgKgoJICogWy0tY2k9PHByb3ZpZGVyPl0KCSAqIDogQ2hvb3NlIGEgY29uZmlndXJhdGlvbiBmaWxlIGZvciBhIGNvbnRpbnVvdXMgaW50ZWdyYXRpb24gcHJvdmlkZXIuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRyYXZpcwoJICogb3B0aW9uczoKCSAqICAgLSB0cmF2aXMKCSAqICAgLSBjaXJjbGUKCSAqICAgLSBnaXRsYWIKCSAqICAgLSBiaXRidWNrZXQKCSAqIC0tLQoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgdW5pdCB0ZXN0IGZpbGVzIGZvciB0aGVtZSAndHdlbnR5c2l4dGVlbmNoaWxkJy4KCSAqICAgICAkIHdwIHNjYWZmb2xkIHRoZW1lLXRlc3RzIHR3ZW50eXNpeHRlZW5jaGlsZAoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgdGVzdCBmaWxlcy4KCSAqCgkgKiBAc3ViY29tbWFuZCB0aGVtZS10ZXN0cwoJICovCglwdWJsaWMgZnVuY3Rpb24gdGhlbWVfdGVzdHMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+c2NhZmZvbGRfcGx1Z2luX3RoZW1lX3Rlc3RzKCAkYXJncywgJGFzc29jX2FyZ3MsICd0aGVtZScgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHNjYWZmb2xkX3BsdWdpbl90aGVtZV90ZXN0cyggJGFyZ3MsICRhc3NvY19hcmdzLCAkdHlwZSApIHsKCQkkd3BfZmlsZXN5c3RlbSA9ICR0aGlzLT5pbml0X3dwX2ZpbGVzeXN0ZW0oKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXJnc1swXSApICkgewoJCQkkc2x1ZyA9ICRhcmdzWzBdOwoJCQlpZiAoIGluX2FycmF5KCAkc2x1ZywgWyAnLicsICcuLicgXSwgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgeyR0eXBlfSBzbHVnIHNwZWNpZmllZC4gVGhlIHNsdWcgY2Fubm90IGJlICcuJyBvciAnLi4nLiIgKTsKCQkJfQoJCQlpZiAoICd0aGVtZScgPT09ICR0eXBlICkgewoJCQkJJHRoZW1lID0gd3BfZ2V0X3RoZW1lKCAkc2x1ZyApOwoJCQkJaWYgKCAkdGhlbWUtPmV4aXN0cygpICkgewoJCQkJCSR0YXJnZXRfZGlyID0gJHRoZW1lLT5nZXRfc3R5bGVzaGVldF9kaXJlY3RvcnkoKTsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgeyR0eXBlfSBzbHVnIHNwZWNpZmllZC4gVGhlIHRoZW1lICd7JHNsdWd9JyBkb2VzIG5vdCBleGlzdC4iICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQkkdGFyZ2V0X2RpciA9IFdQX1BMVUdJTl9ESVIgLiAiL3skc2x1Z30iOwoJCQl9CgkJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydkaXInXSApICYmICEgaXNfZGlyKCAkdGFyZ2V0X2RpciApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgeyR0eXBlfSBzbHVnIHNwZWNpZmllZC4gTm8gc3VjaCB0YXJnZXQgZGlyZWN0b3J5ICd7JHRhcmdldF9kaXJ9Jy4iICk7CgkJCX0KCgkJCSRlcnJvcl9tc2cgPSAkdGhpcy0+Y2hlY2tfdGFyZ2V0X2RpcmVjdG9yeSggJHR5cGUsICR0YXJnZXRfZGlyICk7CgkJCWlmICggISBlbXB0eSggJGVycm9yX21zZyApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgeyR0eXBlfSBzbHVnIHNwZWNpZmllZC4geyRlcnJvcl9tc2d9IiApOwoJCQl9CgkJfQoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydkaXInXSApICkgewoJCQkkdGFyZ2V0X2RpciA9ICRhc3NvY19hcmdzWydkaXInXTsKCQkJaWYgKCAhIGlzX2RpciggJHRhcmdldF9kaXIgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJJbnZhbGlkIHskdHlwZX0gZGlyZWN0b3J5IHNwZWNpZmllZC4gTm8gc3VjaCBkaXJlY3RvcnkgJ3skdGFyZ2V0X2Rpcn0nLiIgKTsKCQkJfQoJCQlpZiAoIGVtcHR5KCAkc2x1ZyApICkgewoJCQkJJHNsdWcgPSBVdGlsc1xiYXNlbmFtZSggJHRhcmdldF9kaXIgKTsKCQkJfQoJCX0KCgkJaWYgKCBlbXB0eSggJHNsdWcgKSB8fCBlbXB0eSggJHRhcmdldF9kaXIgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgeyR0eXBlfSBzcGVjaWZpZWQuIiApOwoJCX0KCgkJJG5hbWUgICAgPSB1Y3dvcmRzKCBzdHJfcmVwbGFjZSggJy0nLCAnICcsICRzbHVnICkgKTsKCQkkcGFja2FnZSA9IHN0cl9yZXBsYWNlKCAnICcsICdfJywgJG5hbWUgKTsKCgkJJHRlc3RzX2RpciA9ICJ7JHRhcmdldF9kaXJ9L3Rlc3RzIjsKCQkkYmluX2RpciAgID0gInskdGFyZ2V0X2Rpcn0vYmluIjsKCgkJJHdwX2ZpbGVzeXN0ZW0tPm1rZGlyKCAkdGVzdHNfZGlyICk7CgkJJHdwX2ZpbGVzeXN0ZW0tPm1rZGlyKCAkYmluX2RpciApOwoKCQkkd3BfdmVyc2lvbnNfdG9fdGVzdCA9IFtdOwoJCS8vIFBhcnNlIHBsdWdpbiByZWFkbWUudHh0CgkJaWYgKCBmaWxlX2V4aXN0cyggInskdGFyZ2V0X2Rpcn0vcmVhZG1lLnR4dCIgKSApIHsKCQkJJHJlYWRtZV9jb250ZW50ID0gZmlsZV9nZXRfY29udGVudHMoICJ7JHRhcmdldF9kaXJ9L3JlYWRtZS50eHQiICk7CgoJCQlwcmVnX21hdGNoKCAnL1JlcXVpcmVzIGF0IGxlYXN0XDooLiopXG4vbScsICRyZWFkbWVfY29udGVudCwgJG1hdGNoZXMgKTsKCQkJaWYgKCBpc3NldCggJG1hdGNoZXNbMV0gKSAmJiAkbWF0Y2hlc1sxXSApIHsKCQkJCSR3cF92ZXJzaW9uc190b190ZXN0W10gPSB0cmltKCAkbWF0Y2hlc1sxXSApOwoJCQl9CgkJfQoJCSR3cF92ZXJzaW9uc190b190ZXN0W10gPSAnbGF0ZXN0JzsKCQkkd3BfdmVyc2lvbnNfdG9fdGVzdFtdID0gJ3RydW5rJzsKCgkJJHRlbXBsYXRlX2RhdGEgPSBbCgkJCSJ7JHR5cGV9X3NsdWciICAgID0+ICRzbHVnLAoJCQkieyR0eXBlfV9wYWNrYWdlIiA9PiAkcGFja2FnZSwKCQldOwoKCQkkZm9yY2UgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICk7CgkJJGZpbGVzX3RvX2NyZWF0ZSA9IFsKCQkJInskdGVzdHNfZGlyfS9ib290c3RyYXAucGhwIiAgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggInskdHlwZX0tYm9vdHN0cmFwLm11c3RhY2hlIiwgJHRlbXBsYXRlX2RhdGEgKSwKCQkJInskdGVzdHNfZGlyfS90ZXN0LXNhbXBsZS5waHAiID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggInskdHlwZX0tdGVzdC1zYW1wbGUubXVzdGFjaGUiLCAkdGVtcGxhdGVfZGF0YSApLAoJCV07CgkJaWYgKCAndHJhdmlzJyA9PT0gJGFzc29jX2FyZ3NbJ2NpJ10gKSB7CgkJCSRmaWxlc190b19jcmVhdGVbICJ7JHRhcmdldF9kaXJ9Ly50cmF2aXMueW1sIiBdID0gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLXRyYXZpcy5tdXN0YWNoZScsIGNvbXBhY3QoICd3cF92ZXJzaW9uc190b190ZXN0JyApICk7CgkJfSBlbHNlaWYgKCAnY2lyY2xlJyA9PT0gJGFzc29jX2FyZ3NbJ2NpJ10gKSB7CgkJCSRmaWxlc190b19jcmVhdGVbICJ7JHRhcmdldF9kaXJ9Ly5jaXJjbGVjaS9jb25maWcueW1sIiBdID0gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLWNpcmNsZS5tdXN0YWNoZScsIGNvbXBhY3QoICd3cF92ZXJzaW9uc190b190ZXN0JyApICk7CgkJfSBlbHNlaWYgKCAnZ2l0bGFiJyA9PT0gJGFzc29jX2FyZ3NbJ2NpJ10gKSB7CgkJCSRmaWxlc190b19jcmVhdGVbICJ7JHRhcmdldF9kaXJ9Ly5naXRsYWItY2kueW1sIiBdID0gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLWdpdGxhYi5tdXN0YWNoZScgKTsKCQl9IGVsc2VpZiAoICdiaXRidWNrZXQnID09PSAkYXNzb2NfYXJnc1snY2knXSApIHsKCQkJJGZpbGVzX3RvX2NyZWF0ZVsgInskdGFyZ2V0X2Rpcn0vYml0YnVja2V0LXBpcGVsaW5lcy55bWwiIF0gPSBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tYml0YnVja2V0Lm11c3RhY2hlJyApOwoJCX0KCgkJJGZpbGVzX3dyaXR0ZW4gPSAkdGhpcy0+Y3JlYXRlX2ZpbGVzKCAkZmlsZXNfdG9fY3JlYXRlLCAkZm9yY2UgKTsKCgkJJHRvX2NvcHkgPSBbCgkJCSdpbnN0YWxsLXdwLXRlc3RzLnNoJyA9PiAkYmluX2RpciwKCQkJJ3BocHVuaXQueG1sLmRpc3QnICAgID0+ICR0YXJnZXRfZGlyLAoJCQknLnBocGNzLnhtbC5kaXN0JyAgICAgPT4gJHRhcmdldF9kaXIsCgkJXTsKCgkJZm9yZWFjaCAoICR0b19jb3B5IGFzICRmaWxlID0+ICRkaXIgKSB7CgkJCSRmaWxlX25hbWUgICAgICAgICA9ICJ7JGRpcn0veyRmaWxlfSI7CgkJCSRmb3JjZSAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApOwoJCQkkc2hvdWxkX3dyaXRlX2ZpbGUgPSAkdGhpcy0+cHJvbXB0X2lmX2ZpbGVzX3dpbGxfYmVfb3ZlcndyaXR0ZW4oICRmaWxlX25hbWUsICRmb3JjZSApOwoJCQlpZiAoICEgJHNob3VsZF93cml0ZV9maWxlICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJJGZpbGVzX3dyaXR0ZW5bXSA9ICRmaWxlX25hbWU7CgoJCQkkd3BfZmlsZXN5c3RlbS0+Y29weSggc2VsZjo6Z2V0X3RlbXBsYXRlX3BhdGgoICRmaWxlICksICRmaWxlX25hbWUsIHRydWUgKTsKCQkJaWYgKCAnaW5zdGFsbC13cC10ZXN0cy5zaCcgPT09ICRmaWxlICkgewoJCQkJaWYgKCAhICR3cF9maWxlc3lzdGVtLT5jaG1vZCggInskZGlyfS97JGZpbGV9IiwgMDc1NSApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IG1hcmsgJ2luc3RhbGwtd3AtdGVzdHMuc2gnIGFzIGV4ZWN1dGFibGUuIiApOwoJCQkJfQoJCQl9CgkJfQoKCQkkc2tpcF9tZXNzYWdlICAgID0gJ0FsbCB0ZXN0IGZpbGVzIHdlcmUgc2tpcHBlZC4nOwoJCSRzdWNjZXNzX21lc3NhZ2UgPSAnQ3JlYXRlZCB0ZXN0IGZpbGVzLic7CgkJJHRoaXMtPmxvZ193aGV0aGVyX2ZpbGVzX3dyaXR0ZW4oICRmaWxlc193cml0dGVuLCAkc2tpcF9tZXNzYWdlLCAkc3VjY2Vzc19tZXNzYWdlICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgdGhhdCB0aGUgYCR0YXJnZXRfZGlyYCBpcyBhIGNoaWxkIGRpcmVjdG9yeSBvZiB0aGUgV1AgdGhlbWVzIG9yIHBsdWdpbnMgZGlyZWN0b3J5LCBkZXBlbmRpbmcgb24gYCR0eXBlYC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlICAgICAgICJ0aGVtZSIgb3IgInBsdWdpbiIKCSAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldF9kaXIgVGhlIHRoZW1lL3BsdWdpbiBkaXJlY3RvcnkgdG8gY2hlY2suCgkgKgoJICogQHJldHVybiBudWxsfHN0cmluZyBSZXR1cm5zIG51bGwgb24gc3VjY2VzcywgZXJyb3IgbWVzc2FnZSBvbiBlcnJvci4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja190YXJnZXRfZGlyZWN0b3J5KCAkdHlwZSwgJHRhcmdldF9kaXIgKSB7CgkJJHBhcmVudF9kaXIgPSBkaXJuYW1lKCBzZWxmOjpjYW5vbmljYWxpemVfcGF0aCggc3RyX3JlcGxhY2UoICdcXCcsICcvJywgJHRhcmdldF9kaXIgKSApICk7CgoJCWlmICggJ3RoZW1lJyA9PT0gJHR5cGUgJiYgc3RyX3JlcGxhY2UoICdcXCcsICcvJywgV1BfQ09OVEVOVF9ESVIgLiAnL3RoZW1lcycgKSAhPT0gJHBhcmVudF9kaXIgKSB7CgkJCXJldHVybiBzcHJpbnRmKCAnVGhlIHRhcmdldCBkaXJlY3RvcnkgXCclMSRzXCcgaXMgbm90IGluIFwnJTIkc1wnLicsICR0YXJnZXRfZGlyLCBXUF9DT05URU5UX0RJUiAuICcvdGhlbWVzJyApOwoJCX0KCgkJaWYgKCAncGx1Z2luJyA9PT0gJHR5cGUgJiYgc3RyX3JlcGxhY2UoICdcXCcsICcvJywgV1BfUExVR0lOX0RJUiApICE9PSAkcGFyZW50X2RpciApIHsKCQkJcmV0dXJuIHNwcmludGYoICdUaGUgdGFyZ2V0IGRpcmVjdG9yeSBcJyUxJHNcJyBpcyBub3QgaW4gXCclMiRzXCcuJywgJHRhcmdldF9kaXIsIFdQX1BMVUdJTl9ESVIgKTsKCQl9CgoJCS8vIFN1Y2Nlc3MuCgkJcmV0dXJuIG51bGw7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZV9maWxlcyggJGZpbGVzX2FuZF9jb250ZW50cywgJGZvcmNlICkgewoJCSR3cF9maWxlc3lzdGVtID0gJHRoaXMtPmluaXRfd3BfZmlsZXN5c3RlbSgpOwoJCSR3cm90ZV9maWxlcyAgID0gW107CgoJCWZvcmVhY2ggKCAkZmlsZXNfYW5kX2NvbnRlbnRzIGFzICRmaWxlbmFtZSA9PiAkY29udGVudHMgKSB7CgkJCSRzaG91bGRfd3JpdGVfZmlsZSA9ICR0aGlzLT5wcm9tcHRfaWZfZmlsZXNfd2lsbF9iZV9vdmVyd3JpdHRlbiggJGZpbGVuYW1lLCAkZm9yY2UgKTsKCQkJaWYgKCAhICRzaG91bGRfd3JpdGVfZmlsZSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkd3BfZmlsZXN5c3RlbS0+bWtkaXIoIGRpcm5hbWUoICRmaWxlbmFtZSApICk7CgoJCQlpZiAoICEgJHdwX2ZpbGVzeXN0ZW0tPnB1dF9jb250ZW50cyggJGZpbGVuYW1lLCAkY29udGVudHMgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJFcnJvciBjcmVhdGluZyBmaWxlOiB7JGZpbGVuYW1lfSIgKTsKCQkJfSBlbHNlaWYgKCAkc2hvdWxkX3dyaXRlX2ZpbGUgKSB7CgkJCQkkd3JvdGVfZmlsZXNbXSA9ICRmaWxlbmFtZTsKCQkJfQoJCX0KCQlyZXR1cm4gJHdyb3RlX2ZpbGVzOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBwcm9tcHRfaWZfZmlsZXNfd2lsbF9iZV9vdmVyd3JpdHRlbiggJGZpbGVuYW1lLCAkZm9yY2UgKSB7CgkJJHNob3VsZF93cml0ZV9maWxlID0gdHJ1ZTsKCQlpZiAoICEgZmlsZV9leGlzdHMoICRmaWxlbmFtZSApICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCVdQX0NMSTo6d2FybmluZyggJ0ZpbGUgYWxyZWFkeSBleGlzdHMuJyApOwoJCVdQX0NMSTo6bG9nKCAkZmlsZW5hbWUgKTsKCQlpZiAoICEgJGZvcmNlICkgewoJCQlkbyB7CgkJCQkkYW5zd2VyICAgICAgPSBjbGlccHJvbXB0KAoJCQkJCSdTa2lwIHRoaXMgZmlsZSwgb3IgcmVwbGFjZSBpdCB3aXRoIHNjYWZmb2xkaW5nPycsCgkJCQkJJGRlZmF1bHQgPSBmYWxzZSwKCQkJCQkkbWFya2VyICA9ICdbcy9yXTogJwoJCQkJKTsKCQkJfSB3aGlsZSAoICEgaW5fYXJyYXkoICRhbnN3ZXIsIFsgJ3MnLCAncicgXSwgdHJ1ZSApICk7CgkJCSRzaG91bGRfd3JpdGVfZmlsZSA9ICdyJyA9PT0gJGFuc3dlcjsKCQl9CgoJCSRvdXRjb21lID0gJHNob3VsZF93cml0ZV9maWxlID8gJ1JlcGxhY2luZycgOiAnU2tpcHBpbmcnOwoJCVdQX0NMSTo6bG9nKCAkb3V0Y29tZSAuIFBIUF9FT0wgKTsKCgkJcmV0dXJuICRzaG91bGRfd3JpdGVfZmlsZTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gbG9nX3doZXRoZXJfZmlsZXNfd3JpdHRlbiggJGZpbGVzX3dyaXR0ZW4sICRza2lwX21lc3NhZ2UsICRzdWNjZXNzX21lc3NhZ2UgKSB7CgkJaWYgKCBlbXB0eSggJGZpbGVzX3dyaXR0ZW4gKSApIHsKCQkJV1BfQ0xJOjpsb2coICRza2lwX21lc3NhZ2UgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICRzdWNjZXNzX21lc3NhZ2UgKTsKCQl9Cgl9CgoJLyoqCgkgKiBFeHRyYWN0cyBkYXNoaWNvbiBuYW1lIHdoZW4gcHJvdmlkZWQgb3IgcmV0dXJuIG51bGwgb3RoZXJ3aXNlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncwoJICogQHJldHVybiBzdHJpbmd8bnVsbAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RfZGFzaGljb24oICRhc3NvY19hcmdzICkgewoJCSRkYXNoaWNvbiA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rhc2hpY29uJyApOwoJCWlmICggISAkZGFzaGljb24gKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCQlyZXR1cm4gcHJlZ19yZXBsYWNlKCAnL2Rhc2hpY29uKC18cy0pLycsICcnLCAkZGFzaGljb24gKTsKCX0KCgkvKioKCSAqIElmIHlvdSdyZSB3cml0aW5nIHlvdXIgZmlsZXMgdG8geW91ciB0aGVtZSBkaXJlY3RvcnkgeW91ciB0ZXh0ZG9tYWluIGFsc28gbmVlZHMgdG8gYmUgdGhlIHNhbWUgYXMgeW91ciB0aGVtZS4KCSAqIFNhbWUgZ29lcyBmb3Igd2hlbiBwbHVnaW4gaXMgYmVpbmcgdXNlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfdGV4dGRvbWFpbiggJHRleHRkb21haW4sICRhcmdzICkgewoJCWlmICggc3RybGVuKCAkdGV4dGRvbWFpbiApICkgewoJCQlyZXR1cm4gJHRleHRkb21haW47CgkJfQoKCQlpZiAoICRhcmdzWyd0aGVtZSddICkgewoJCQlyZXR1cm4gJHRoaXMtPmdldF90aGVtZV9uYW1lKCAkYXJnc1sndGhlbWUnXSApOwoJCX0KCgkJaWYgKCAkYXJnc1sncGx1Z2luJ10gJiYgdHJ1ZSAhPT0gJGFyZ3NbJ3BsdWdpbiddICkgewoJCQlyZXR1cm4gJGFyZ3NbJ3BsdWdpbiddOwoJCX0KCgkJcmV0dXJuICdZT1VSLVRFWFRET01BSU4nOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIHRoZSBtYWNoaW5lIG5hbWUgZm9yIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnIFNsdWcgbmFtZSB0byBjb252ZXJ0LgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZW5lcmF0ZV9tYWNoaW5lX25hbWUoICRzbHVnICkgewoJCXJldHVybiBzdHJfcmVwbGFjZSggJy0nLCAnXycsICRzbHVnICk7Cgl9CgoJLyoqCgkgKiBQbHVyYWxpemVzIGEgbm91bi4KCSAqCgkgKiBAc2VlICAgIEluZmxlY3Rvcjo6cGx1cmFsaXplKCkKCSAqIEBwYXJhbSAgc3RyaW5nICR3b3JkIFdvcmQgdG8gYmUgcGx1cmFsaXplZC4KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcGx1cmFsaXplKCAkd29yZCApIHsKCQlyZXR1cm4gSW5mbGVjdG9yOjpwbHVyYWxpemUoICR3b3JkICk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3RfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApIHsKCQkkb3V0ID0gW107CgoJCWZvcmVhY2ggKCAkZGVmYXVsdHMgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCSRvdXRbICRrZXkgXSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJGtleSwgJHZhbHVlICk7CgkJfQoKCQlyZXR1cm4gJG91dDsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gcXVvdGVfY29tbWFfbGlzdF9lbGVtZW50cyggJGNvbW1hX2xpc3QgKSB7CgkJcmV0dXJuICInIiAuIGltcGxvZGUoICInLCAnIiwgZXhwbG9kZSggJywnLCAkY29tbWFfbGlzdCApICkgLiAiJyI7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIHRoZSB0aGVtZXMgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIG1heWJlX2NyZWF0ZV90aGVtZXNfZGlyKCkgewoKCQkkdGhlbWVzX2RpciA9IFdQX0NPTlRFTlRfRElSIC4gJy90aGVtZXMnOwoJCWlmICggISBpc19kaXIoICR0aGVtZXNfZGlyICkgKSB7CgkJCXdwX21rZGlyX3AoICR0aGVtZXNfZGlyICk7CgkJfQoKCX0KCgkvKioKCSAqIENyZWF0ZXMgdGhlIHBsdWdpbnMgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIG1heWJlX2NyZWF0ZV9wbHVnaW5zX2RpcigpIHsKCgkJaWYgKCAhIGlzX2RpciggV1BfUExVR0lOX0RJUiApICkgewoJCQl3cF9ta2Rpcl9wKCBXUF9QTFVHSU5fRElSICk7CgkJfQoKCX0KCgkvKioKCSAqIEluaXRpYWxpemVzIFdQX0ZpbGVzeXN0ZW0uCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBpbml0X3dwX2ZpbGVzeXN0ZW0oKSB7CgkJZ2xvYmFsICR3cF9maWxlc3lzdGVtOwoJCVdQX0ZpbGVzeXN0ZW0oKTsKCgkJcmV0dXJuICR3cF9maWxlc3lzdGVtOwoJfQoKCS8qKgoJICogTG9jYWxpemVzIHRoZSB0ZW1wbGF0ZSBwYXRoLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBtdXN0YWNoZV9yZW5kZXIoICR0ZW1wbGF0ZSwgJGRhdGEgPSBbXSApIHsKCQlyZXR1cm4gVXRpbHNcbXVzdGFjaGVfcmVuZGVyKCBkaXJuYW1lKCBkaXJuYW1lKCBfX0ZJTEVfXyApICkgLiAiL3RlbXBsYXRlcy97JHRlbXBsYXRlfSIsICRkYXRhICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB0ZW1wbGF0ZSBwYXRoIGJhc2VkIG9uIGluc3RhbGxhdGlvbiB0eXBlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfdGVtcGxhdGVfcGF0aCggJHRlbXBsYXRlICkgewoJCSRjb21tYW5kX3Jvb3QgID0gVXRpbHNccGhhcl9zYWZlX3BhdGgoIGRpcm5hbWUoIF9fRElSX18gKSApOwoJCSR0ZW1wbGF0ZV9wYXRoID0gInskY29tbWFuZF9yb290fS90ZW1wbGF0ZXMveyR0ZW1wbGF0ZX0iOwoKCQlpZiAoICEgZmlsZV9leGlzdHMoICR0ZW1wbGF0ZV9wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBmaW5kIHskdGVtcGxhdGV9IiApOwoJCX0KCgkJcmV0dXJuICR0ZW1wbGF0ZV9wYXRoOwoJfQoKCS8qCgkgKiBSZXR1cm5zIHRoZSBjYW5vbmljYWxpemVkIHBhdGgsIHdpdGggZG90IGFuZCBkb3VibGUgZG90IHNlZ21lbnRzIHJlc29sdmVkLgoJICoKCSAqIENvcGllZCBmcm9tIFN5bWZvbnlcQ29tcG9uZW50XERvbUNyYXdsZXJcQWJzdHJhY3RVcmlFbGVtZW50OjpjYW5vbmljYWxpemVQYXRoKCkuCgkgKiBJbXBsZW1lbnRzIFJGQyAzOTg2LCBzZWN0aW9uIDUuMi40LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGggVGhlIHBhdGggdG8gbWFrZSBjYW5vbmljYWwuCgkgKgoJICogQHJldHVybiBzdHJpbmcgVGhlIGNhbm9uaWNhbGl6ZWQgcGF0aC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY2Fub25pY2FsaXplX3BhdGgoICRwYXRoICkgewoJCWlmICggJycgPT09ICRwYXRoIHx8ICcvJyA9PT0gJHBhdGggKSB7CgkJCXJldHVybiAkcGF0aDsKCQl9CgoJCWlmICggJy4nID09PSBzdWJzdHIoICRwYXRoLCAtMSApICkgewoJCQkkcGF0aCAuPSAnLyc7CgkJfQoKCQkkb3V0cHV0ID0gW107CgoJCWZvcmVhY2ggKCBleHBsb2RlKCAnLycsICRwYXRoICkgYXMgJHNlZ21lbnQgKSB7CgkJCWlmICggJy4uJyA9PT0gJHNlZ21lbnQgKSB7CgkJCQlhcnJheV9wb3AoICRvdXRwdXQgKTsKCQkJfSBlbHNlaWYgKCAnLicgIT09ICRzZWdtZW50ICkgewoJCQkJJG91dHB1dFtdID0gJHNlZ21lbnQ7CgkJCX0KCQl9CgoJCXJldHVybiBpbXBsb2RlKCAnLycsICRvdXRwdXQgKTsKCX0KCgkvKioKCSAqIEdldHMgYW4gYWN0aXZlIHRoZW1lJ3MgbmFtZSB3aGVuIHRydWUgcHJvdmlkZWQgb3IgdGhlIHNhbWUgbmFtZSBvdGhlcndpc2UuCgkgKgoJICogQHBhcmFtIHN0cmluZ3xib29sICR0aGVtZSBUaGVtZSBuYW1lIG9yIHRydWUuCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF90aGVtZV9uYW1lKCAkdGhlbWUgKSB7CgkJaWYgKCB0cnVlID09PSAkdGhlbWUgKSB7CgkJCSR0aGVtZSA9IHdwX2dldF90aGVtZSgpLT50ZW1wbGF0ZTsKCQl9CgkJcmV0dXJuIHN0cnRvbG93ZXIoICR0aGVtZSApOwoJfQp9Cjw/cGhwCi8qKgogKiBGdW5jdGlvbnMgdG8gcmVnaXN0ZXIgY2xpZW50LXNpZGUgYXNzZXRzIChzY3JpcHRzIGFuZCBzdHlsZXNoZWV0cykgZm9yIHRoZQogKiBHdXRlbmJlcmcgYmxvY2suCiAqCiAqIEBwYWNrYWdlIHt7bmFtZXNwYWNlfX0KICovCgovKioKICogUmVnaXN0ZXJzIGFsbCBibG9jayBhc3NldHMgc28gdGhhdCB0aGV5IGNhbiBiZSBlbnF1ZXVlZCB0aHJvdWdoIEd1dGVuYmVyZyBpbgogKiB0aGUgY29ycmVzcG9uZGluZyBjb250ZXh0LgogKgogKiBAc2VlIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svZGVzaWduZXJzLWRldmVsb3BlcnMvZGV2ZWxvcGVycy90dXRvcmlhbHMvYmxvY2stdHV0b3JpYWwvYXBwbHlpbmctc3R5bGVzLXdpdGgtc3R5bGVzaGVldHMvCiAqLwpmdW5jdGlvbiB7e21hY2hpbmVfbmFtZX19X2Jsb2NrX2luaXQoKSB7CgkvLyBTa2lwIGJsb2NrIHJlZ2lzdHJhdGlvbiBpZiBHdXRlbmJlcmcgaXMgbm90IGVuYWJsZWQvbWVyZ2VkLgoJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3JlZ2lzdGVyX2Jsb2NrX3R5cGUnICkgKSB7CgkJcmV0dXJuOwoJfQoJe3sjcGx1Z2lufX0KCSRkaXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApOwoJe3svcGx1Z2lufX0KCXt7I3RoZW1lfX0KCSRkaXIgPSBnZXRfc3R5bGVzaGVldF9kaXJlY3RvcnkoKSAuICcvYmxvY2tzJzsKCXt7L3RoZW1lfX0KCgkkaW5kZXhfanMgPSAne3tzbHVnfX0vaW5kZXguanMnOwoJd3BfcmVnaXN0ZXJfc2NyaXB0KAoJCSd7e3NsdWd9fS1ibG9jay1lZGl0b3InLAoJCXt7I3BsdWdpbn19CgkJcGx1Z2luc191cmwoICRpbmRleF9qcywgX19GSUxFX18gKSwKCQl7ey9wbHVnaW59fQoJCXt7I3RoZW1lfX0KCQlnZXRfc3R5bGVzaGVldF9kaXJlY3RvcnlfdXJpKCkgLiAiL2Jsb2Nrcy97JGluZGV4X2pzfSIsCgkJe3svdGhlbWV9fQoJCVsKCQkJJ3dwLWJsb2NrcycsCgkJCSd3cC1pMThuJywKCQkJJ3dwLWVsZW1lbnQnLAoJCV0sCgkJZmlsZW10aW1lKCAieyRkaXJ9L3skaW5kZXhfanN9IiApCgkpOwoKCSRlZGl0b3JfY3NzID0gJ3t7c2x1Z319L2VkaXRvci5jc3MnOwoJd3BfcmVnaXN0ZXJfc3R5bGUoCgkJJ3t7c2x1Z319LWJsb2NrLWVkaXRvcicsCgkJe3sjcGx1Z2lufX0KCQlwbHVnaW5zX3VybCggJGVkaXRvcl9jc3MsIF9fRklMRV9fICksCgkJe3svcGx1Z2lufX0KCQl7eyN0aGVtZX19CgkJZ2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5X3VyaSgpIC4gIi9ibG9ja3MveyRlZGl0b3JfY3NzfSIsCgkJe3svdGhlbWV9fQoJCVtdLAoJCWZpbGVtdGltZSggInskZGlyfS97JGVkaXRvcl9jc3N9IiApCgkpOwoKCSRzdHlsZV9jc3MgPSAne3tzbHVnfX0vc3R5bGUuY3NzJzsKCXdwX3JlZ2lzdGVyX3N0eWxlKAoJCSd7e3NsdWd9fS1ibG9jaycsCgkJe3sjcGx1Z2lufX0KCQlwbHVnaW5zX3VybCggJHN0eWxlX2NzcywgX19GSUxFX18gKSwKCQl7ey9wbHVnaW59fQoJCXt7I3RoZW1lfX0KCQlnZXRfc3R5bGVzaGVldF9kaXJlY3RvcnlfdXJpKCkgLiAiL2Jsb2Nrcy97JHN0eWxlX2Nzc30iLAoJCXt7L3RoZW1lfX0KCQlbXSwKCQlmaWxlbXRpbWUoICJ7JGRpcn0veyRzdHlsZV9jc3N9IiApCgkpOwoKCXJlZ2lzdGVyX2Jsb2NrX3R5cGUoICd7e25hbWVzcGFjZX19L3t7c2x1Z319JywgWwoJCSdlZGl0b3Jfc2NyaXB0JyA9PiAne3tzbHVnfX0tYmxvY2stZWRpdG9yJywKCQknZWRpdG9yX3N0eWxlJyAgPT4gJ3t7c2x1Z319LWJsb2NrLWVkaXRvcicsCgkJJ3N0eWxlJyAgICAgICAgID0+ICd7e3NsdWd9fS1ibG9jaycsCgldICk7Cn0KCmFkZF9hY3Rpb24oICdpbml0JywgJ3t7bWFjaGluZV9uYW1lfX1fYmxvY2tfaW5pdCcgKTsKPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9zdXBlcl9hZG1pbl9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9zdXBlcl9hZG1pbl9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX3N1cGVyX2FkbWluX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoCgknc3VwZXItYWRtaW4nLAoJJ1N1cGVyX0FkbWluX0NvbW1hbmQnLAoJYXJyYXkoCgkJJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uICgpIHsKCQkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkJCX0KCQl9LAoJKQopOwo8P3BocAoKdXNlIFdQX0NMSVxGZXRjaGVyc1xVc2VyIGFzIFVzZXJGZXRjaGVyOwoKLyoqCiAqIExpc3RzLCBhZGRzLCBvciByZW1vdmVzIHN1cGVyIGFkbWluIHVzZXJzIG9uIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgTGlzdCB1c2VyIHdpdGggc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzCiAqICAgICAkIHdwIHN1cGVyLWFkbWluIGxpc3QKICogICAgIHN1cGVydmlzb3IKICogICAgIGFkbWluaXN0cmF0b3IKICoKICogICAgICMgR3JhbnQgc3VwZXItYWRtaW4gcHJpdmlsZWdlcyB0byB0aGUgdXNlci4KICogICAgICQgd3Agc3VwZXItYWRtaW4gYWRkIHN1cGVyYWRtaW4yCiAqICAgICBTdWNjZXNzOiBHcmFudGVkIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcy4KICoKICogICAgICMgUmV2b2tlIHN1cGVyLWFkbWluIHByaXZpbGVnZXMgdG8gdGhlIHVzZXIuCiAqICAgICAkIHdwIHN1cGVyLWFkbWluIHJlbW92ZSBzdXBlcmFkbWluMgogKiAgICAgU3VjY2VzczogUmV2b2tlZCBzdXBlci1hZG1pbiBjYXBhYmlsaXRpZXMuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgU3VwZXJfQWRtaW5fQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRmaWVsZHMgPSBbCgkJJ3VzZXJfbG9naW4nLAoJXTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgVXNlckZldGNoZXIoKTsKCX0KCgkvKioKCSAqIExpc3RzIHVzZXJzIHdpdGggc3VwZXIgYWRtaW4gY2FwYWJpbGl0aWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogbGlzdAoJICogb3B0aW9uczoKCSAqICAgLSBsaXN0CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdXNlciB3aXRoIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcwoJICogICAgICQgd3Agc3VwZXItYWRtaW4gbGlzdAoJICogICAgIHN1cGVydmlzb3IKCSAqICAgICBhZG1pbmlzdHJhdG9yCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF9zdWJjb21tYW5kKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJJHN1cGVyX2FkbWlucyA9IHNlbGY6OmdldF9hZG1pbnMoKTsKCgkJaWYgKCAnbGlzdCcgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJZm9yZWFjaCAoICRzdXBlcl9hZG1pbnMgYXMgJHVzZXJfbG9naW4gKSB7CgkJCQlXUF9DTEk6OmxpbmUoICR1c2VyX2xvZ2luICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkb3V0cHV0X3VzZXJzID0gW107CgkJCWZvcmVhY2ggKCAkc3VwZXJfYWRtaW5zIGFzICR1c2VyX2xvZ2luICkgewoJCQkJJG91dHB1dF91c2VyID0gbmV3IHN0ZENsYXNzKCk7CgoJCQkJJG91dHB1dF91c2VyLT51c2VyX2xvZ2luID0gJHVzZXJfbG9naW47CgoJCQkJJG91dHB1dF91c2Vyc1tdID0gJG91dHB1dF91c2VyOwoJCQl9CgkJCSRmb3JtYXR0ZXIgPSBuZXcgXFdQX0NMSVxGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzICk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRvdXRwdXRfdXNlcnMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHcmFudHMgc3VwZXIgYWRtaW4gcHJpdmlsZWdlcyB0byBvbmUgb3IgbW9yZSB1c2Vycy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+Li4uCgkgKiA6IE9uZSBvciBtb3JlIHVzZXIgSURzLCB1c2VyIGVtYWlscywgb3IgdXNlciBsb2dpbnMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzdXBlci1hZG1pbiBhZGQgc3VwZXJhZG1pbjIKCSAqICAgICBTdWNjZXNzOiBHcmFudGVkIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJGFyZ3MsICRfICkgewoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkdXNlcnMgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoKCQlpZiAoIGNvdW50KCAkdXNlcnMgKSAhPT0gY291bnQoICRhcmdzICkgKSB7CgkJCSRlcnJvcnMgPSBjb3VudCggJGFyZ3MgKSAtIGNvdW50KCAkdXNlcnMgKTsKCQl9CgoJCSRzdXBlcl9hZG1pbnMgICAgID0gc2VsZjo6Z2V0X2FkbWlucygpOwoJCSRudW1fc3VwZXJfYWRtaW5zID0gY291bnQoICRzdXBlcl9hZG1pbnMgKTsKCgkJJG5ld19zdXBlcl9hZG1pbnMgPSBbXTsKCQlmb3JlYWNoICggJHVzZXJzIGFzICR1c2VyICkgewoJCQlkb19hY3Rpb24oICdncmFudF9zdXBlcl9hZG1pbicsIChpbnQpICR1c2VyLT5JRCApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kCgoJCQlpZiAoIGluX2FycmF5KCAkdXNlci0+dXNlcl9sb2dpbiwgJHN1cGVyX2FkbWlucywgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVXNlciAneyR1c2VyLT51c2VyX2xvZ2lufScgYWxyZWFkeSBoYXMgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzLiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkbmV3X3N1cGVyX2FkbWluc1tdID0gJHVzZXItPklEOwoJCQkkc3VwZXJfYWRtaW5zW10gICAgID0gJHVzZXItPnVzZXJfbG9naW47CgkJCSRzdWNjZXNzZXMrKzsKCQl9CgoJCWlmICggY291bnQoICRzdXBlcl9hZG1pbnMgKSA9PT0gJG51bV9zdXBlcl9hZG1pbnMgKSB7CgkJCWlmICggJGVycm9ycyApIHsKCQkJCSR1c2VyX2NvdW50ID0gY291bnQoICRhcmdzICk7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgZ3JhbnQgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzIHRvIHskZXJyb3JzfSBvZiB7JHVzZXJfY291bnR9IHVzZXJzLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ1N1cGVyIGFkbWlucyByZW1haW4gdW5jaGFuZ2VkLicgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICggdXBkYXRlX3NpdGVfb3B0aW9uKCAnc2l0ZV9hZG1pbnMnLCAkc3VwZXJfYWRtaW5zICkgKSB7CgkJCQlpZiAoICRlcnJvcnMgKSB7CgkJCQkJJHVzZXJfY291bnQgPSBjb3VudCggJGFyZ3MgKTsKCQkJCQlXUF9DTEk6OmVycm9yKCAiT25seSBncmFudGVkIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcyB0byB7JHN1Y2Nlc3Nlc30gb2YgeyR1c2VyX2NvdW50fSB1c2Vycy4iICk7CgkJCQl9IGVsc2UgewoJCQkJCSRtZXNzYWdlID0gJHN1Y2Nlc3NlcyA+IDEgPyAndXNlcnMnIDogJ3VzZXInOwoJCQkJCVdQX0NMSTo6c3VjY2VzcyggIkdyYW50ZWQgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzIHRvIHskc3VjY2Vzc2VzfSB7JG1lc3NhZ2V9LiIgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdTaXRlIG9wdGlvbnMgdXBkYXRlIGZhaWxlZC4nICk7CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCAkbmV3X3N1cGVyX2FkbWlucyBhcyAkdXNlcl9pZCApIHsKCQkJZG9fYWN0aW9uKCAnZ3JhbnRlZF9zdXBlcl9hZG1pbicsIChpbnQpICR1c2VyX2lkICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQKCQl9Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIHN1cGVyIGFkbWluIHByaXZpbGVnZXMgZnJvbSBvbmUgb3IgbW9yZSB1c2Vycy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+Li4uCgkgKiA6IE9uZSBvciBtb3JlIHVzZXIgSURzLCB1c2VyIGVtYWlscywgb3IgdXNlciBsb2dpbnMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzdXBlci1hZG1pbiByZW1vdmUgc3VwZXJhZG1pbjIKCSAqICAgICBTdWNjZXNzOiBSZXZva2VkIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlbW92ZSggJGFyZ3MsICRfICkgewoJCSR1c2VycyAgICAgICAgICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQkkdXNlcl9sb2dpbnMgICAgICAgPSAkdXNlcnMgPyBhcnJheV92YWx1ZXMoIGFycmF5X3VuaXF1ZSggd3BfbGlzdF9wbHVjayggJHVzZXJzLCAndXNlcl9sb2dpbicgKSApICkgOiBbXTsKCQkkdXNlcl9sb2dpbnNfY291bnQgPSBjb3VudCggJHVzZXJfbG9naW5zICk7CgoJCSR1c2VyX2lkcyA9IFtdOwoJCWZvcmVhY2ggKCAkdXNlcnMgYXMgJHVzZXIgKSB7CgkJCSR1c2VyX2lkc1sgJHVzZXItPnVzZXJfbG9naW4gXSA9ICR1c2VyLT5JRDsKCgkJCWRvX2FjdGlvbiggJ3Jldm9rZV9zdXBlcl9hZG1pbicsIChpbnQpICR1c2VyLT5JRCApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kCgkJfQoKCQkkc3VwZXJfYWRtaW5zID0gc2VsZjo6Z2V0X2FkbWlucygpOwoJCWlmICggISAkc3VwZXJfYWRtaW5zICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gc3VwZXIgYWRtaW5zIHRvIHJldm9rZSBzdXBlci1hZG1pbiBwcml2aWxlZ2VzIGZyb20uJyApOwoJCX0KCgkJaWYgKCAkdXNlcl9sb2dpbnNfY291bnQgPCBjb3VudCggJGFyZ3MgKSApIHsKCQkJJGZsaXBwZWRfdXNlcl9sb2dpbnMgPSBhcnJheV9mbGlwKCAkdXNlcl9sb2dpbnMgKTsKCQkJLy8gRmV0Y2hlciBoYXMgYWxyZWFkeSB3YXJuZWQgc28gZG9uJ3QgYm90aGVyIGhlcmUsIGJ1dCBjb250aW51ZSB3aXRoIGFueSBhcmdzIHRoYXQgYXJlIHBvc3NpYmxlIGxvZ2luIG5hbWVzIHRvIGNhdGVyIGZvciBpbnZhbGlkIHVzZXJzIGluIHRoZSBzaXRlIG9wdGlvbnMgbWV0YS4KCgkJCSR1c2VyX2xvZ2lucyAgICAgICA9IGFycmF5X21lcmdlKAoJCQkJJHVzZXJfbG9naW5zLAoJCQkJYXJyYXlfdW5pcXVlKAoJCQkJCWFycmF5X2ZpbHRlcigKCQkJCQkJJGFyZ3MsCgkJCQkJCXN0YXRpYyBmdW5jdGlvbiAoICR2ICkgdXNlICggJGZsaXBwZWRfdXNlcl9sb2dpbnMgKSB7CgkJCQkJCQkvLyBFeGNsdWRlIG51bWVyaWMgYW5kIGVtYWlsLWxpa2UgbG9naW5zIChsb2dpbiBuYW1lcyBjYW4gYmUgZW1haWwtbGlrZSBidXQgaWdub3JlIHRoaXMgZ2l2ZW4gdGhlIGNpcmN1bXN0YW5jZXMpLgoJCQkJCQkJcmV0dXJuICEgaXNzZXQoICRmbGlwcGVkX3VzZXJfbG9naW5zWyAkdiBdICkgJiYgISBpc19udW1lcmljKCAkdiApICYmICEgaXNfZW1haWwoICR2ICk7CgkJCQkJCX0KCQkJCQkpCgkJCQkpCgkJCSk7CgkJCSR1c2VyX2xvZ2luc19jb3VudCA9IGNvdW50KCAkdXNlcl9sb2dpbnMgKTsKCQl9CgkJaWYgKCAhICR1c2VyX2xvZ2lucyApIHsKCQkJV1BfQ0xJOjplcnJvciggJ05vIHZhbGlkIHVzZXIgbG9naW5zIGdpdmVuIHRvIHJldm9rZSBzdXBlci1hZG1pbiBwcml2aWxlZ2VzIGZyb20uJyApOwoJCX0KCgkJJHVwZGF0ZV9zdXBlcl9hZG1pbnMgPSBhcnJheV9kaWZmKCAkc3VwZXJfYWRtaW5zLCAkdXNlcl9sb2dpbnMgKTsKCQlpZiAoICR1cGRhdGVfc3VwZXJfYWRtaW5zID09PSAkc3VwZXJfYWRtaW5zICkgewoJCQlXUF9DTEk6OmVycm9yKCAkdXNlcl9sb2dpbnNfY291bnQgPiAxID8gJ05vbmUgb2YgdGhlIGdpdmVuIHVzZXJzIGlzIGEgc3VwZXIgYWRtaW4uJyA6ICdUaGUgZ2l2ZW4gdXNlciBpcyBub3QgYSBzdXBlciBhZG1pbi4nICk7CgkJfQoKCQl1cGRhdGVfc2l0ZV9vcHRpb24oICdzaXRlX2FkbWlucycsICR1cGRhdGVfc3VwZXJfYWRtaW5zICk7CgoJCSRzdWNjZXNzZXMgPSBjb3VudCggJHN1cGVyX2FkbWlucyApIC0gY291bnQoICR1cGRhdGVfc3VwZXJfYWRtaW5zICk7CgkJaWYgKCAkc3VjY2Vzc2VzID09PSAkdXNlcl9sb2dpbnNfY291bnQgKSB7CgkJCSRtZXNzYWdlID0gJHVzZXJfbG9naW5zX2NvdW50ID4gMSA/ICd1c2VycycgOiAndXNlcic7CgkJCSRtc2cgICAgID0gIlJldm9rZWQgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzIGZyb20geyR1c2VyX2xvZ2luc19jb3VudH0geyRtZXNzYWdlfS4iOwoJCX0gZWxzZSB7CgkJCSRtc2cgPSAiUmV2b2tlZCBzdXBlci1hZG1pbiBjYXBhYmlsaXRpZXMgZnJvbSB7JHN1Y2Nlc3Nlc30gb2YgeyR1c2VyX2xvZ2luc19jb3VudH0gdXNlcnMuIjsKCQl9CgkJaWYgKCAhICR1cGRhdGVfc3VwZXJfYWRtaW5zICkgewoJCQkkbXNnIC49ICcgVGhlcmUgYXJlIG5vIHJlbWFpbmluZyBzdXBlciBhZG1pbnMuJzsKCQl9CgkJV1BfQ0xJOjpzdWNjZXNzKCAkbXNnICk7CgoJCSRyZW1vdmVkX2xvZ2lucyA9IGFycmF5X2ludGVyc2VjdCggJHVzZXJfbG9naW5zLCAkc3VwZXJfYWRtaW5zICk7CgoJCWZvcmVhY2ggKCAkcmVtb3ZlZF9sb2dpbnMgYXMgJHVzZXJfbG9naW4gKSB7CgkJCSR1c2VyX2lkID0gbnVsbDsKCgkJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJHVzZXJfbG9naW4sICR1c2VyX2lkcyApICkgewoJCQkJJHVzZXJfaWQgPSAkdXNlcl9pZHNbICR1c2VyX2xvZ2luIF07CgkJCX0gZWxzZSB7CgkJCQkkdXNlciA9IGdldF91c2VyX2J5KCAnbG9naW4nLCAkdXNlcl9sb2dpbiApOwoJCQkJaWYgKCAkdXNlciBpbnN0YW5jZW9mIFdQX1VzZXIgKSB7CgkJCQkJJHVzZXJfaWQgPSAkdXNlci0+SUQ7CgkJCQl9CgkJCX0KCgkJCWlmICggbnVsbCAhPT0gJHVzZXJfaWQgKSB7CgkJCQlkb19hY3Rpb24oICdyZXZva2VkX3N1cGVyX2FkbWluJywgKGludCkgJHVzZXJfaWRzWyAkdXNlcl9sb2dpbiBdICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQKCQkJfQoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfYWRtaW5zKCkgewoJCS8vIFdlIGRvbid0IHVzZSBnZXRfc3VwZXJfYWRtaW5zKCkgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIG1lc3Mgd2l0aCB0aGUgZ2xvYmFsCgkJcmV0dXJuIChhcnJheSkgZ2V0X3NpdGVfb3B0aW9uKCAnc2l0ZV9hZG1pbnMnLCBbICdhZG1pbicgXSApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSTsKCnRyYWl0IFBhcnNlUGx1Z2luTmFtZUlucHV0IHsKCgkvKioKCSAqIElmIGhhdmUgb3B0aW9uYWwgYXJncyAoWzxwbHVnaW4+Li4uXSkgYW5kIGFuIGFsbCBvcHRpb24sIHRoZW4gY2hlY2sgaGF2ZSBzb21ldGhpbmcgdG8gZG8uCgkgKgoJICogQHBhcmFtIGFycmF5ICAkYXJncyBQYXNzZWQtaW4gYXJndW1lbnRzLgoJICogQHBhcmFtIGJvb2wgICAkYWxsIEFsbCBmbGFnLgoJICogQHBhcmFtIHN0cmluZyAkdmVyYiBPcHRpb25hbC4gVmVyYiB0byB1c2UuIERlZmF1bHRzIHRvICdpbnN0YWxsJy4KCSAqIEByZXR1cm4gYXJyYXkgU2FtZSBhcyAkYXJncyBpZiBub3QgYWxsLCBvdGhlcndpc2UgYWxsIHNsdWdzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIG5laXRoZXIgcGx1Z2luIG5hbWUgbm9yIC0tYWxsIHdlcmUgcHJvdmlkZWQuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBjaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsLCAkdmVyYiA9ICdpbnN0YWxsJyApIHsKCQlpZiAoICRhbGwgKSB7CgkJCSRhcmdzID0gYXJyYXlfbWFwKAoJCQkJJ1xXUF9DTElcVXRpbHNcZ2V0X3BsdWdpbl9uYW1lJywKCQkJCWFycmF5X2tleXMoICR0aGlzLT5nZXRfYWxsX3BsdWdpbnMoKSApCgkJCSk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXJncyApICkgewoJCQlpZiAoICEgJGFsbCApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSBwbHVnaW5zLCBvciB1c2UgLS1hbGwuJyApOwoJCQl9CgoJCQkkcGFzdF90ZW5zZV92ZXJiID0gVXRpbHNccGFzdF90ZW5zZV92ZXJiKCAkdmVyYiApOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJObyBwbHVnaW5zIHskcGFzdF90ZW5zZV92ZXJifS4iICk7IC8vIERvbid0IGVycm9yIGlmIC0tYWxsIGdpdmVuIGZvciBCQy4KCQl9CgoJCXJldHVybiAkYXJnczsKCX0KCgkvKioKCSAqIEdldHMgYWxsIGF2YWlsYWJsZSBwbHVnaW5zLgoJICoKCSAqIFVzZXMgdGhlIHNhbWUgZmlsdGVyIGNvcmUgdXNlcyBpbiBwbHVnaW5zLnBocCB0byBkZXRlcm1pbmUgd2hpY2ggcGx1Z2lucwoJICogc2hvdWxkIGJlIGF2YWlsYWJsZSB0byBtYW5hZ2UgdGhyb3VnaCB0aGUgV1BfUGx1Z2luc19MaXN0X1RhYmxlIGNsYXNzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWxsX3BsdWdpbnMoKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQlyZXR1cm4gYXBwbHlfZmlsdGVycyggJ2FsbF9wbHVnaW5zJywgZ2V0X3BsdWdpbnMoKSApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKLyoqCiAqIEEgcGx1Z2luIHVwZ3JhZGVyIGNsYXNzIHRoYXQgY2xlYXJzIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuCiAqLwpjbGFzcyBEZXN0cnVjdGl2ZVBsdWdpblVwZ3JhZGVyIGV4dGVuZHMgXFBsdWdpbl9VcGdyYWRlciB7CgoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGxfcGFja2FnZSggJGFyZ3MgPSBhcnJheSgpICkgewoJCXBhcmVudDo6dXBncmFkZV9zdHJpbmdzKCk7IC8vIE5lZWRlZCBmb3IgdGhlICdyZW1vdmVfb2xkJyBzdHJpbmcuCgoJCSRhcmdzWydjbGVhcl9kZXN0aW5hdGlvbiddICAgICAgICAgICA9IHRydWU7CgkJJGFyZ3NbJ2Fib3J0X2lmX2Rlc3RpbmF0aW9uX2V4aXN0cyddID0gZmFsc2U7CgkJcmV0dXJuIHBhcmVudDo6aW5zdGFsbF9wYWNrYWdlKCAkYXJncyApOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBBIHRoZW1lIHVwZ3JhZGVyIGNsYXNzIHRoYXQgY2xlYXJzIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuCiAqLwpjbGFzcyBEZXN0cnVjdGl2ZVRoZW1lVXBncmFkZXIgZXh0ZW5kcyBcVGhlbWVfVXBncmFkZXIgewoKCXB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsX3BhY2thZ2UoICRhcmdzID0gYXJyYXkoKSApIHsKCQlwYXJlbnQ6OnVwZ3JhZGVfc3RyaW5ncygpOyAvLyBOZWVkZWQgZm9yIHRoZSAncmVtb3ZlX29sZCcgc3RyaW5nLgoKCQkkYXJnc1snY2xlYXJfZGVzdGluYXRpb24nXSAgICAgICAgICAgPSB0cnVlOwoJCSRhcmdzWydhYm9ydF9pZl9kZXN0aW5hdGlvbl9leGlzdHMnXSA9IGZhbHNlOwoJCXJldHVybiBwYXJlbnQ6Omluc3RhbGxfcGFja2FnZSggJGFyZ3MgKTsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRmV0Y2hlcnM7CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3MgcGx1Z2luIGJhc2VkIG9uIG9uZSBvZiBpdHMgYXR0cmlidXRlcy4KICovCmNsYXNzIFBsdWdpbiBleHRlbmRzIEJhc2UgewoKCS8qKgoJICogQHZhciBzdHJpbmcgJG1zZyBFcnJvciBtZXNzYWdlIHRvIHVzZSB3aGVuIGludmFsaWQgZGF0YSBpcyBwcm92aWRlZAoJICovCglwcm90ZWN0ZWQgJG1zZyA9ICJUaGUgJyVzJyBwbHVnaW4gY291bGQgbm90IGJlIGZvdW5kLiI7CgoJLyoqCgkgKiBHZXQgYSBwbHVnaW4gb2JqZWN0IGJ5IG5hbWUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lCgkgKiBAcmV0dXJuIG9iamVjdHxmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkbmFtZSApIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCWZvcmVhY2ggKCBhcHBseV9maWx0ZXJzKCAnYWxsX3BsdWdpbnMnLCBnZXRfcGx1Z2lucygpICkgYXMgJGZpbGUgPT4gJF8gKSB7CgkJCWlmICggIiRuYW1lLnBocCIgPT09ICRmaWxlIHx8CgkJCQkoICRuYW1lICYmICRmaWxlID09PSAkbmFtZSApIHx8CgkJCQkoIGRpcm5hbWUoICRmaWxlICkgPT09ICRuYW1lICYmICcuJyAhPT0gJG5hbWUgKSApIHsKCQkJCXJldHVybiAob2JqZWN0KSBjb21wYWN0KCAnbmFtZScsICdmaWxlJyApOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEZldGNoZXJzOwoKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBGZXRjaCBhIFdvcmRQcmVzcyB0aGVtZSBiYXNlZCBvbiBvbmUgb2YgaXRzIGF0dHJpYnV0ZXMuCiAqLwpjbGFzcyBUaGVtZSBleHRlbmRzIEJhc2UgewoKCS8qKgoJICogQHZhciBzdHJpbmcgJG1zZyBFcnJvciBtZXNzYWdlIHRvIHVzZSB3aGVuIGludmFsaWQgZGF0YSBpcyBwcm92aWRlZAoJICovCglwcm90ZWN0ZWQgJG1zZyA9ICJUaGUgJyVzJyB0aGVtZSBjb3VsZCBub3QgYmUgZm91bmQuIjsKCgkvKioKCSAqIEdldCBhIHRoZW1lIG9iamVjdCBieSBuYW1lCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZQoJICogQHJldHVybiBvYmplY3R8ZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJG5hbWUgKSB7CgkJLy8gV29ya2Fyb3VuZCB0byBlcXVhbGl6ZSBmb2xkZXIgbmFtaW5nIGNvbnZlbnRpb25zIGFjcm9zcyBXaW4vTWFjL0xpbnV4LgoJCS8vIFJldHVybnMgZmFsc2UgaWYgdGhlbWUgc3R5bGVzaGVldCBkb2Vzbid0IGV4YWN0bHkgbWF0Y2ggZXhpc3RpbmcgdGhlbWVzLgoJCSRleGlzdGluZ190aGVtZXMgICAgICA9IHdwX2dldF90aGVtZXMoIGFycmF5KCAnZXJyb3JzJyA9PiBudWxsICkgKTsKCQkkZXhpc3Rpbmdfc3R5bGVzaGVldHMgPSBhcnJheV9rZXlzKCAkZXhpc3RpbmdfdGhlbWVzICk7CgkJaWYgKCAhIGluX2FycmF5KCAkbmFtZSwgJGV4aXN0aW5nX3N0eWxlc2hlZXRzLCB0cnVlICkgKSB7CgkJCSRpbmV4YWN0X21hdGNoID0gJHRoaXMtPmZpbmRfaW5leGFjdF9tYXRjaCggJG5hbWUsICRleGlzdGluZ190aGVtZXMgKTsKCQkJaWYgKCBmYWxzZSAhPT0gJGluZXhhY3RfbWF0Y2ggKSB7CgkJCQkkdGhpcy0+bXNnIC49IHNwcmludGYoICIgRGlkIHlvdSBtZWFuICclcyc/IiwgJGluZXhhY3RfbWF0Y2ggKTsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkdGhlbWUgPSAkZXhpc3RpbmdfdGhlbWVzWyAkbmFtZSBdOwoKCQlyZXR1cm4gJHRoZW1lOwoJfQoKCS8qKgoJICogRmluZCBhbmQgcmV0dXJuIHRoZSBrZXkgaW4gJGV4aXN0aW5nX3RoZW1lcyB0aGF0IG1hdGNoZXMgJG5hbWUgd2l0aAoJICogYSBjYXNlIGluc2Vuc2l0aXZlIHN0cmluZyBjb21wYXJpc29uLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgTmFtZSBvZiB0aGVtZSByZWNlaXZlZCBieSBjb21tYW5kLgoJICogQHBhcmFtIGFycmF5ICAkZXhpc3RpbmdfdGhlbWVzIEtleS92YWx1ZSBwYWlyIG9mIGV4aXN0aW5nIHRoZW1lcywga2V5IGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjYXNlIHNlbnNpdGl2ZSBuYW1lLgoJICogQHJldHVybiBzdHJpbmd8Ym9vbGVhbiBDYXNlIHNlbnNpdGl2ZSBuYW1lIGlmIG1hdGNoIGZvdW5kLCBvdGhlcndpc2UgZmFsc2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZmluZF9pbmV4YWN0X21hdGNoKCAkbmFtZSwgJGV4aXN0aW5nX3RoZW1lcyApIHsKCQkkdGFyZ2V0ID0gc3RydG9sb3dlciggJG5hbWUgKTsKCQkkdGhlbWVzID0gYXJyYXlfbWFwKCAnc3RydG9sb3dlcicsIGFycmF5X2tleXMoICRleGlzdGluZ190aGVtZXMgKSApOwoKCQlpZiAoIGluX2FycmF5KCAkdGFyZ2V0LCAkdGhlbWVzLCB0cnVlICkgKSB7CgkJCXJldHVybiAkdGFyZ2V0OwoJCX0KCgkJJHN1Z2dlc3Rpb24gPSBVdGlsc1xnZXRfc3VnZ2VzdGlvbiggJHRhcmdldCwgJHRoZW1lcyApOwoKCQlpZiAoICcnICE9PSAkc3VnZ2VzdGlvbiApIHsKCQkJcmV0dXJuICRzdWdnZXN0aW9uOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7Cgp0cmFpdCBQYXJzZVRoZW1lTmFtZUlucHV0IHsKCgkvKioKCSAqIElmIGhhdmUgb3B0aW9uYWwgYXJncyAoWzx0aGVtZT4uLi5dKSBhbmQgYW4gYWxsIG9wdGlvbiwgdGhlbiBjaGVjayBoYXZlIHNvbWV0aGluZyB0byBkby4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRhcmdzIFBhc3NlZC1pbiBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYm9vbCAgICRhbGwgQWxsIGZsYWcuCgkgKiBAcGFyYW0gc3RyaW5nICR2ZXJiIE9wdGlvbmFsLiBWZXJiIHRvIHVzZS4gRGVmYXVsdHMgdG8gJ2luc3RhbGwnLgoJICogQHJldHVybiBhcnJheSBTYW1lIGFzICRhcmdzIGlmIG5vdCBhbGwsIG90aGVyd2lzZSBhbGwgc2x1Z3MuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgbmVpdGhlciBwbHVnaW4gbmFtZSBub3IgLS1hbGwgd2VyZSBwcm92aWRlZC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwsICR2ZXJiID0gJ2luc3RhbGwnICkgewoJCWlmICggJGFsbCApIHsKCQkJJGFyZ3MgPSBhcnJheV9tYXAoCgkJCQknXFdQX0NMSVxVdGlsc1xnZXRfdGhlbWVfbmFtZScsCgkJCQlhcnJheV9rZXlzKCAkdGhpcy0+Z2V0X2FsbF90aGVtZXMoKSApCgkJCSk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXJncyApICkgewoJCQlpZiAoICEgJGFsbCApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSB0aGVtZXMsIG9yIHVzZSAtLWFsbC4nICk7CgkJCX0KCgkJCSRwYXN0X3RlbnNlX3ZlcmIgPSBVdGlsc1xwYXN0X3RlbnNlX3ZlcmIoICR2ZXJiICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggIk5vIHRoZW1lcyB7JHBhc3RfdGVuc2VfdmVyYn0uIiApOyAvLyBEb24ndCBlcnJvciBpZiAtLWFsbCBnaXZlbiBmb3IgQkMuCgkJfQoKCQlyZXR1cm4gJGFyZ3M7Cgl9CgoJLyoqCgkgKiBHZXRzIGFsbCBhdmFpbGFibGUgdGhlbWVzLgoJICoKCSAqIFVzZXMgdGhlIHNhbWUgZmlsdGVyIGNvcmUgdXNlcyBpbiB0aGVtZXMucGhwIHRvIGRldGVybWluZSB3aGljaCB0aGVtZXMKCSAqIHNob3VsZCBiZSBhdmFpbGFibGUgdG8gbWFuYWdlIHRocm91Z2ggdGhlIFdQX1RoZW1lc19MaXN0X1RhYmxlIGNsYXNzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWxsX3RoZW1lcygpIHsKCQkkaXRlbXMgICAgICAgICAgICAgID0gYXJyYXkoKTsKCQkkdGhlbWVfdmVyc2lvbl9pbmZvID0gYXJyYXkoKTsKCgkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJJHNpdGVfZW5hYmxlZCA9IGdldF9vcHRpb24oICdhbGxvd2VkdGhlbWVzJyApOwoJCQlpZiAoIGVtcHR5KCAkc2l0ZV9lbmFibGVkICkgKSB7CgkJCQkkc2l0ZV9lbmFibGVkID0gYXJyYXkoKTsKCQkJfQoKCQkJJG5ldHdvcmtfZW5hYmxlZCA9IGdldF9zaXRlX29wdGlvbiggJ2FsbG93ZWR0aGVtZXMnICk7CgkJCWlmICggZW1wdHkoICRuZXR3b3JrX2VuYWJsZWQgKSApIHsKCQkJCSRuZXR3b3JrX2VuYWJsZWQgPSBhcnJheSgpOwoJCQl9CgkJfQoKCQkkYWxsX3VwZGF0ZV9pbmZvID0gJHRoaXMtPmdldF91cGRhdGVfaW5mbygpOwoJCSRjaGVja2VkX3RoZW1lcyAgPSBpc3NldCggJGFsbF91cGRhdGVfaW5mby0+Y2hlY2tlZCApID8gJGFsbF91cGRhdGVfaW5mby0+Y2hlY2tlZCA6IGFycmF5KCk7CgoJCWlmICggISBlbXB0eSggJGNoZWNrZWRfdGhlbWVzICkgKSB7CgkJCWZvcmVhY2ggKCAkY2hlY2tlZF90aGVtZXMgYXMgJHNsdWcgPT4gJHZlcnNpb24gKSB7CgkJCQkkdGhlbWVfdmVyc2lvbl9pbmZvWyAkc2x1ZyBdID0gJHRoaXMtPmlzX3RoZW1lX3ZlcnNpb25fdmFsaWQoICRzbHVnLCAkdmVyc2lvbiApOwoJCQl9CgkJfQoKCQlmb3JlYWNoICggd3BfZ2V0X3RoZW1lcygpIGFzICRrZXkgPT4gJHRoZW1lICkgewoJCQkkZmlsZSA9ICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5KCk7CgoJCQkkdXBkYXRlX2luZm8gPSAoIGlzc2V0KCAkYWxsX3VwZGF0ZV9pbmZvLT5yZXNwb25zZVsgJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpIF0gKSAmJiBudWxsICE9PSAkYWxsX3VwZGF0ZV9pbmZvLT5yZXNwb25zZVsgJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpIF0gKSA/IChhcnJheSkgJGFsbF91cGRhdGVfaW5mby0+cmVzcG9uc2VbICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSBdIDogbnVsbDsKCgkJCSRpdGVtc1sgJGZpbGUgXSA9IFsKCQkJCSduYW1lJyAgICAgICAgICAgPT4gJGtleSwKCQkJCSdzdGF0dXMnICAgICAgICAgPT4gJHRoaXMtPmdldF9zdGF0dXMoICR0aGVtZSApLAoJCQkJJ3VwZGF0ZScgICAgICAgICA9PiAoYm9vbCkgJHVwZGF0ZV9pbmZvLAoJCQkJJ3VwZGF0ZV92ZXJzaW9uJyA9PiBpc3NldCggJHVwZGF0ZV9pbmZvWyduZXdfdmVyc2lvbiddICkgPyAkdXBkYXRlX2luZm9bJ25ld192ZXJzaW9uJ10gOiBudWxsLAoJCQkJJ3VwZGF0ZV9wYWNrYWdlJyA9PiBpc3NldCggJHVwZGF0ZV9pbmZvWydwYWNrYWdlJ10gKSA/ICR1cGRhdGVfaW5mb1sncGFja2FnZSddIDogbnVsbCwKCQkJCSd2ZXJzaW9uJyAgICAgICAgPT4gJHRoZW1lLT5nZXQoICdWZXJzaW9uJyApLAoJCQkJJ3VwZGF0ZV9pZCcgICAgICA9PiAkdGhlbWUtPmdldF9zdHlsZXNoZWV0KCksCgkJCQkndGl0bGUnICAgICAgICAgID0+ICR0aGVtZS0+Z2V0KCAnTmFtZScgKSwKCQkJCSdkZXNjcmlwdGlvbicgICAgPT4gd29yZHdyYXAoICR0aGVtZS0+Z2V0KCAnRGVzY3JpcHRpb24nICkgKSwKCQkJCSdhdXRob3InICAgICAgICAgPT4gJHRoZW1lLT5nZXQoICdBdXRob3InICksCgkJCV07CgoJCQkvLyBDb21wYXJlIHZlcnNpb24gYW5kIHVwZGF0ZSBpbmZvcm1hdGlvbiBpbiB0aGVtZSBsaXN0LgoJCQlpZiAoIGlzc2V0KCAkdGhlbWVfdmVyc2lvbl9pbmZvWyAka2V5IF0gKSAmJiBmYWxzZSA9PT0gJHRoZW1lX3ZlcnNpb25faW5mb1sgJGtleSBdICkgewoJCQkJJGl0ZW1zWyAkZmlsZSBdWyd1cGRhdGUnXSA9ICd2ZXJzaW9uIGhpZ2hlciB0aGFuIGV4cGVjdGVkJzsKCQkJfQoKCQkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJCWlmICggISBlbXB0eSggJHNpdGVfZW5hYmxlZFsgJGtleSBdICkgJiYgISBlbXB0eSggJG5ldHdvcmtfZW5hYmxlZFsgJGtleSBdICkgKSB7CgkJCQkJJGl0ZW1zWyAkZmlsZSBdWydlbmFibGVkJ10gPSAnbmV0d29yayxzaXRlJzsKCQkJCX0gZWxzZWlmICggISBlbXB0eSggJG5ldHdvcmtfZW5hYmxlZFsgJGtleSBdICkgKSB7CgkJCQkJJGl0ZW1zWyAkZmlsZSBdWydlbmFibGVkJ10gPSAnbmV0d29yayc7CgkJCQl9IGVsc2VpZiAoICEgZW1wdHkoICRzaXRlX2VuYWJsZWRbICRrZXkgXSApICkgewoJCQkJCSRpdGVtc1sgJGZpbGUgXVsnZW5hYmxlZCddID0gJ3NpdGUnOwoJCQkJfSBlbHNlIHsKCQkJCQkkaXRlbXNbICRmaWxlIF1bJ2VuYWJsZWQnXSA9ICdubyc7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiAkaXRlbXM7Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiBjdXJyZW50IHZlcnNpb24gb2YgdGhlIHRoZW1lIGlzIGhpZ2hlciB0aGFuIHRoZSBvbmUgYXZhaWxhYmxlIGF0IFdQLm9yZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnIFRoZW1lIHNsdWcuCgkgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uIFRoZW1lIGN1cnJlbnQgdmVyc2lvbi4KCSAqCgkgKiBAcmV0dXJuIGJvb2x8c3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBpc190aGVtZV92ZXJzaW9uX3ZhbGlkKCAkc2x1ZywgJHZlcnNpb24gKSB7CgkJLy8gR2V0IFRoZW1lIEluZm8uCgkJJHRoZW1lX2luZm8gPSB0aGVtZXNfYXBpKCAndGhlbWVfaW5mb3JtYXRpb24nLCBhcnJheSggJ3NsdWcnID0+ICRzbHVnICkgKTsKCgkJLy8gUmV0dXJuIGVtcHR5IHN0cmluZyBmb3IgdGhlbWVzIG5vdCBvbiBXUC5vcmcuCgkJaWYgKCBpc193cF9lcnJvciggJHRoZW1lX2luZm8gKSApIHsKCQkJcmV0dXJuICcnOwoJCX0KCgkJLy8gQ29tcGFyZSB0aGVtZSB2ZXJzaW9uIGluZm8uCgkJcmV0dXJuICEgdmVyc2lvbl9jb21wYXJlKCAkdmVyc2lvbiwgJHRoZW1lX2luZm8tPnZlcnNpb24sICc+JyApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBzdGF0dXMgZm9yIGEgZ2l2ZW4gdGhlbWUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGhlbWUgVGhlbWUgdG8gZ2V0IHRoZSBzdGF0dXMgZm9yLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFN0YXR1cyBvZiB0aGUgdGhlbWUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfc3RhdHVzKCAkdGhlbWUgKSB7CgkJaWYgKCAkdGhpcy0+aXNfYWN0aXZlX3RoZW1lKCAkdGhlbWUgKSApIHsKCQkJcmV0dXJuICdhY3RpdmUnOwoJCX0KCgkJaWYgKCAkdGhlbWUtPmdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpID09PSBnZXRfdGVtcGxhdGVfZGlyZWN0b3J5KCkgKSB7CgkJCXJldHVybiAncGFyZW50JzsKCQl9CgoJCXJldHVybiAnaW5hY3RpdmUnOwoJfQoKCS8qKgoJICogQ2hlY2sgd2hldGhlciBhIGdpdmVuIHRoZW1lIGlzIHRoZSBhY3RpdmUgdGhlbWUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGhlbWUgVGhlbWUgdG8gY2hlY2suCgkgKgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHByb3ZpZGVkIHRoZW1lIGlzIHRoZSBhY3RpdmUgdGhlbWUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBpc19hY3RpdmVfdGhlbWUoICR0aGVtZSApIHsKCQlyZXR1cm4gJHRoZW1lLT5nZXRfc3R5bGVzaGVldF9kaXJlY3RvcnkoKSA9PT0gZ2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5KCk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGF2YWlsYWJsZSB1cGRhdGUgaW5mby4KCSAqCgkgKiBAcmV0dXJuIG1peGVkIEF2YWlsYWJsZSB1cGRhdGUgaW5mby4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF91cGRhdGVfaW5mbygpIHsKCQlyZXR1cm4gZ2V0X3NpdGVfdHJhbnNpZW50KCAndXBkYXRlX3RoZW1lcycgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29tcGFyYXRvcjsKdXNlIEV4Y2VwdGlvbjsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxGZXRjaGVyczsKdXNlIFdQX0NMSVxMb2dnZXJzOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfRXJyb3I7CgphYnN0cmFjdCBjbGFzcyBDb21tYW5kV2l0aFVwZ3JhZGUgZXh0ZW5kcyBcV1BfQ0xJX0NvbW1hbmQgewoKCXByb3RlY3RlZCAkaXRlbV90eXBlOwoJcHJvdGVjdGVkICRvYmpfZmllbGRzOwoKCXByb3RlY3RlZCAkdXBncmFkZV9yZWZyZXNoOwoJcHJvdGVjdGVkICR1cGdyYWRlX3RyYW5zaWVudDsKCglwcm90ZWN0ZWQgJGNoYWluZWRfY29tbWFuZCA9IGZhbHNlOwoKCS8vIEludmFsaWQgdmVyc2lvbiBtZXNzYWdlLgoJY29uc3QgSU5WQUxJRF9WRVJTSU9OX01FU1NBR0UgPSAndmVyc2lvbiBoaWdoZXIgdGhhbiBleHBlY3RlZCc7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoKCQkvLyBEbyBub3QgYXV0b21hdGljYWxseSBjaGVjayB0cmFuc2xhdGlvbnMgdXBkYXRlcyBhZnRlciB1cGRhdGluZyBwbHVnaW5zL3RoZW1lcy4KCQlhZGRfYWN0aW9uKAoJCQkndXBncmFkZXJfcHJvY2Vzc19jb21wbGV0ZScsCgkJCWZ1bmN0aW9uKCkgewoJCQkJcmVtb3ZlX2FjdGlvbiggJ3VwZ3JhZGVyX3Byb2Nlc3NfY29tcGxldGUnLCBbICdMYW5ndWFnZV9QYWNrX1VwZ3JhZGVyJywgJ2FzeW5jX3VwZ3JhZGUnIF0sIDIwICk7CgkJCX0sCgkJCTEKCQkpOwoKCQlhZGRfZmlsdGVyKAoJCQknaHR0cF9yZXF1ZXN0X3RpbWVvdXQnLAoJCQlmdW5jdGlvbiAoKSB7CgkJCQlyZXR1cm4gMSAqIE1JTlVURV9JTl9TRUNPTkRTOwoJCQl9LAoJCQk5OTkKCQkpOwoKCQkkdGhpcy0+ZmV0Y2hlciA9IG5ldyBGZXRjaGVyc1xQbHVnaW4oKTsKCX0KCglhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3VwZ3JhZGVyX2NsYXNzKCAkZm9yY2UgKTsKCglhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2l0ZW1fbGlzdCgpOwoKCS8qKgoJICogQHBhcmFtIGFycmF5IExpc3Qgb2YgdXBkYXRlIGNhbmRpZGF0ZXMKCSAqIEBwYXJhbSBhcnJheSBMaXN0IG9mIGl0ZW0gbmFtZXMKCSAqIEByZXR1cm4gYXJyYXkgTGlzdCBvZiB1cGRhdGUgY2FuZGlkYXRlcwoJICovCglhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZmlsdGVyX2l0ZW1fbGlzdCggJGl0ZW1zLCAkYXJncyApOwoKCWFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBnZXRfYWxsX2l0ZW1zKCk7CgoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9zdGF0dXMoICRmaWxlICk7CgoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIHN0YXR1c19zaW5nbGUoICRhcmdzICk7CgoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGluc3RhbGxfZnJvbV9yZXBvKCAkc2x1ZywgJGFzc29jX2FyZ3MgKTsKCglwdWJsaWMgZnVuY3Rpb24gc3RhdHVzKCAkYXJncyApIHsKCQkvLyBGb3JjZSBXb3JkUHJlc3MgdG8gY2hlY2sgZm9yIHVwZGF0ZXMuCgkJY2FsbF91c2VyX2Z1bmMoICR0aGlzLT51cGdyYWRlX3JlZnJlc2ggKTsKCgkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJJHRoaXMtPnN0YXR1c19hbGwoKTsKCQl9IGVsc2UgewoJCQkkdGhpcy0+c3RhdHVzX3NpbmdsZSggJGFyZ3MgKTsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzdGF0dXNfYWxsKCkgewoJCSRpdGVtcyA9ICR0aGlzLT5nZXRfYWxsX2l0ZW1zKCk7CgoJCSRuID0gY291bnQoICRpdGVtcyApOwoKCQlXUF9DTEk6OmxvZygKCQkJc3ByaW50ZiggJyVkIGluc3RhbGxlZCAlczonLCAkbiwgVXRpbHNccGx1cmFsaXplKCAkdGhpcy0+aXRlbV90eXBlLCBhYnNpbnQoICRuICkgKSApCgkJKTsKCgkJJHBhZGRpbmcgPSAkdGhpcy0+Z2V0X3BhZGRpbmcoICRpdGVtcyApOwoKCQlmb3JlYWNoICggJGl0ZW1zIGFzICRmaWxlID0+ICRkZXRhaWxzICkgewoJCQlpZiAoICRkZXRhaWxzWyd1cGRhdGUnXSApIHsKCQkJCSRsaW5lID0gJyAleVUlbic7CgkJCX0gZWxzZSB7CgkJCQkkbGluZSA9ICcgICc7CgkJCX0KCgkJCSRsaW5lIC49ICR0aGlzLT5mb3JtYXRfc3RhdHVzKCAkZGV0YWlsc1snc3RhdHVzJ10sICdzaG9ydCcgKTsKCQkJJGxpbmUgLj0gJyAnIC4gc3RyX3BhZCggJGRldGFpbHNbJ25hbWUnXSwgJHBhZGRpbmcgKSAuICclbic7CgkJCWlmICggISBlbXB0eSggJGRldGFpbHNbJ3ZlcnNpb24nXSApICkgewoJCQkJJGxpbmUgLj0gJyAnIC4gJGRldGFpbHNbJ3ZlcnNpb24nXTsKCQkJfQoKCQkJV1BfQ0xJOjpsaW5lKCBXUF9DTEk6OmNvbG9yaXplKCAkbGluZSApICk7CgkJfQoKCQlXUF9DTEk6OmxpbmUoKTsKCgkJJHRoaXMtPnNob3dfbGVnZW5kKCAkaXRlbXMgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9wYWRkaW5nKCAkaXRlbXMgKSB7CgkJJG1heF9sZW4gPSAwOwoKCQlmb3JlYWNoICggJGl0ZW1zIGFzICRkZXRhaWxzICkgewoJCQkkbGVuID0gc3RybGVuKCAkZGV0YWlsc1snbmFtZSddICk7CgoJCQlpZiAoICRsZW4gPiAkbWF4X2xlbiApIHsKCQkJCSRtYXhfbGVuID0gJGxlbjsKCQkJfQoJCX0KCgkJcmV0dXJuICRtYXhfbGVuOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc2hvd19sZWdlbmQoICRpdGVtcyApIHsKCQkkc3RhdHVzZXMgPSBhcnJheV91bmlxdWUoIHdwX2xpc3RfcGx1Y2soICRpdGVtcywgJ3N0YXR1cycgKSApOwoKCQkkbGVnZW5kX2xpbmUgPSBhcnJheSgpOwoKCQlmb3JlYWNoICggJHN0YXR1c2VzIGFzICRzdGF0dXMgKSB7CgkJCSRsZWdlbmRfbGluZVtdID0gc3ByaW50ZigKCQkJCSclcyVzID0gJXMlJW4nLAoJCQkJJHRoaXMtPmdldF9jb2xvciggJHN0YXR1cyApLAoJCQkJJHRoaXMtPm1hcFsnc2hvcnQnXVsgJHN0YXR1cyBdLAoJCQkJJHRoaXMtPm1hcFsnbG9uZyddWyAkc3RhdHVzIF0KCQkJKTsKCQl9CgoJCWlmICggaW5fYXJyYXkoIHRydWUsIHdwX2xpc3RfcGx1Y2soICRpdGVtcywgJ3VwZGF0ZScgKSwgdHJ1ZSApICkgewoJCQkkbGVnZW5kX2xpbmVbXSA9ICcleVUgPSBVcGRhdGUgQXZhaWxhYmxlJW4nOwoJCX0KCgkJV1BfQ0xJOjpsaW5lKCAnTGVnZW5kOiAnIC4gV1BfQ0xJOjpjb2xvcml6ZSggaW1wbG9kZSggJywgJywgJGxlZ2VuZF9saW5lICkgKSApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkc2x1ZyApIHsKCgkJCWlmICggZW1wdHkoICRzbHVnICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdJZ25vcmluZyBhbWJpZ3VvdXMgZW1wdHkgc2x1ZyB2YWx1ZS4nICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJlc3VsdCA9IGZhbHNlOwoKCQkJJGlzX3JlbW90ZSA9IGZhbHNlICE9PSBzdHJwb3MoICRzbHVnLCAnOi8vJyApOwoKCQkJLy8gQ2hlY2sgaWYgYSBVUkwgdG8gYSByZW1vdGUgb3IgbG9jYWwgemlwIGhhcyBiZWVuIHNwZWNpZmllZC4KCQkJaWYgKCAkaXNfcmVtb3RlIHx8ICggcGF0aGluZm8oICRzbHVnLCBQQVRISU5GT19FWFRFTlNJT04gKSA9PT0gJ3ppcCcgJiYgaXNfZmlsZSggJHNsdWcgKSApICkgewoJCQkJLy8gSW5zdGFsbCBmcm9tIGxvY2FsIG9yIHJlbW90ZSB6aXAgZmlsZS4KCQkJCSRmaWxlX3VwZ3JhZGVyID0gJHRoaXMtPmdldF91cGdyYWRlciggJGFzc29jX2FyZ3MgKTsKCgkJCQkkZmlsdGVyID0gZmFsc2U7CgkJCQkvLyBJZiBhIEdpdEh1YiBVUkwsIGRvIHNvbWUgZ3Vlc3NpbmcgYXMgdG8gdGhlIGNvcnJlY3QgcGx1Z2luL3RoZW1lIGRpcmVjdG9yeS4KCQkJCWlmICggJGlzX3JlbW90ZSAmJiAnZ2l0aHViLmNvbScgPT09ICR0aGlzLT5wYXJzZV91cmxfaG9zdF9jb21wb25lbnQoICRzbHVnLCBQSFBfVVJMX0hPU1QgKQoJCQkJCQkvLyBEb24ndCBhdHRlbXB0IHRvIHJlbmFtZSBaSVBzIHVwbG9hZGVkIHRvIHRoZSByZWxlYXNlcyBwYWdlIG9yIGNvbWluZyBmcm9tIGEgcmF3IHNvdXJjZS4KCQkJCQkJJiYgISBwcmVnX21hdGNoKCAnI2dpdGh1YlwuY29tL1teL10rL1teL10rLyg/OnJlbGVhc2VzL2Rvd25sb2FkfHJhdykvIycsICRzbHVnICkgKSB7CgoJCQkJCSRmaWx0ZXIgPSBmdW5jdGlvbiggJHNvdXJjZSwgJHJlbW90ZV9zb3VyY2UsICR1cGdyYWRlciApIHVzZSAoICRzbHVnICkgewoKCQkJCQkJJHNsdWdfZGlyID0gVXRpbHNcYmFzZW5hbWUoICR0aGlzLT5wYXJzZV91cmxfaG9zdF9jb21wb25lbnQoICRzbHVnLCBQSFBfVVJMX1BBVEggKSwgJy56aXAnICk7CgoJCQkJCQkvLyBEb24ndCB1c2UgdGhlIHppcCBuYW1lIGlmIGFyY2hpdmUgYXR0YWNoZWQgdG8gcmVsZWFzZSwgYXMgbmFtZSBsaWtlbHkgdG8gY29udGFpbiB2ZXJzaW9uIHRhZy9icmFuY2guCgkJCQkJCWlmICggcHJlZ19tYXRjaCggJyNnaXRodWJcLmNvbS9bXi9dKy8oW14vXSspL2FyY2hpdmUvIycsICRzbHVnLCAkbWF0Y2hlcyApICkgewoJCQkJCQkJLy8gTm90ZSB0aGlzIHdpbGwgYmUgd3JvbmcgaWYgdGhlIHByb2plY3QgbmFtZSBpc24ndCB0aGUgc2FtZSBhcyB0aGUgcGx1Z2luL3RoZW1lIHNsdWcgbmFtZS4KCQkJCQkJCSRzbHVnX2RpciA9ICRtYXRjaGVzWzFdOwoJCQkJCQl9CgoJCQkJCQkkc291cmNlX2RpciA9IFV0aWxzXGJhc2VuYW1lKCAkc291cmNlICk7IC8vIGAkc291cmNlYCBpcyB0cmFpbGluZy1zbGFzaGVkIHBhdGggdG8gdGhlIHVuemlwcGVkIGFyY2hpdmUgZGlyZWN0b3J5LCBzbyBiYXNlbmFtZSByZXR1cm5zIHRoZSB1bnNsYXNoZWQgZGlyZWN0b3J5LgoJCQkJCQlpZiAoICRzb3VyY2VfZGlyID09PSAkc2x1Z19kaXIgKSB7CgkJCQkJCQlyZXR1cm4gJHNvdXJjZTsKCQkJCQkJfQoJCQkJCQkkbmV3X3BhdGggPSBzdWJzdHJfcmVwbGFjZSggJHNvdXJjZSwgJHNsdWdfZGlyLCBzdHJycG9zKCAkc291cmNlLCAkc291cmNlX2RpciApLCBzdHJsZW4oICRzb3VyY2VfZGlyICkgKTsKCgkJCQkJCWlmICggJEdMT0JBTFNbJ3dwX2ZpbGVzeXN0ZW0nXS0+bW92ZSggJHNvdXJjZSwgJG5ld19wYXRoICkgKSB7CgkJCQkJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggIlJlbmFtZWQgR2l0aHViLWJhc2VkIHByb2plY3QgZnJvbSAnJXMnIHRvICclcycuIiwgJHNvdXJjZV9kaXIsICRzbHVnX2RpciApICk7CgkJCQkJCQlyZXR1cm4gJG5ld19wYXRoOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnd3BjbGlfaW5zdGFsbF9naXRodWInLCAiQ291bGRuJ3QgbW92ZSBHaXRodWItYmFzZWQgcHJvamVjdCB0byBhcHByb3ByaWF0ZSBkaXJlY3RvcnkuIiApOwoJCQkJCX07CgkJCQkJYWRkX2ZpbHRlciggJ3VwZ3JhZGVyX3NvdXJjZV9zZWxlY3Rpb24nLCAkZmlsdGVyLCAxMCwgMyApOwoJCQkJfQoKCQkJCWlmICggJGZpbGVfdXBncmFkZXItPmluc3RhbGwoICRzbHVnICkgKSB7CgkJCQkJJHNsdWcgICA9ICRmaWxlX3VwZ3JhZGVyLT5yZXN1bHRbJ2Rlc3RpbmF0aW9uX25hbWUnXTsKCQkJCQkkcmVzdWx0ID0gdHJ1ZTsKCQkJCQlpZiAoICRmaWx0ZXIgKSB7CgkJCQkJCXJlbW92ZV9maWx0ZXIoICd1cGdyYWRlcl9zb3VyY2Vfc2VsZWN0aW9uJywgJGZpbHRlciwgMTAgKTsKCQkJCQl9CgkJCQkJJHN1Y2Nlc3NlcysrOwoJCQkJfSBlbHNlIHsKCQkJCQkkZXJyb3JzKys7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQkvLyBBc3N1bWUgYSBwbHVnaW4vdGhlbWUgc2x1ZyBmcm9tIHRoZSBXb3JkUHJlc3Mub3JnIHJlcG9zaXRvcnkgaGFzIGJlZW4gc3BlY2lmaWVkLgoJCQkJJHJlc3VsdCA9ICR0aGlzLT5pbnN0YWxsX2Zyb21fcmVwbyggJHNsdWcsICRhc3NvY19hcmdzICk7CgoJCQkJaWYgKCBpc19udWxsKCAkcmVzdWx0ICkgKSB7CgkJCQkJJGVycm9ycysrOwoJCQkJfSBlbHNlaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQkJCSRrZXkgPSAkcmVzdWx0LT5nZXRfZXJyb3JfY29kZSgpOwoJCQkJCWlmICggaW5fYXJyYXkoICRrZXksIFsgJ3BsdWdpbnNfYXBpX2ZhaWxlZCcsICd0aGVtZXNfYXBpX2ZhaWxlZCcgXSwgdHJ1ZSApCgkJCQkJCSYmICEgZW1wdHkoICRyZXN1bHQtPmVycm9yX2RhdGFbICRrZXkgXSApICYmIGluX2FycmF5KCAkcmVzdWx0LT5lcnJvcl9kYXRhWyAka2V5IF0sIFsgJ047JywgJ2I6MDsnIF0sIHRydWUgKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGRuJ3QgZmluZCAnJHNsdWcnIGluIHRoZSBXb3JkUHJlc3Mub3JnIHskdGhpcy0+aXRlbV90eXBlfSBkaXJlY3RvcnkuIiApOwoJCQkJCQkkZXJyb3JzKys7CgkJCQkJfSBlbHNlIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiJHNsdWc6ICIgLiAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJCQkJCWlmICggJ2FscmVhZHlfaW5zdGFsbGVkJyAhPT0gJGtleSApIHsKCQkJCQkJCSRlcnJvcnMrKzsKCQkJCQkJfQoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJJHN1Y2Nlc3NlcysrOwoJCQkJfQoJCQl9CgoJCQkvLyBDaGVjayBleHRlbnNpb24gaXMgYXZhaWxhYmxlIG9yIG5vdC4KCQkJJGV4dGVuc2lvbiA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggYXJyYXkoICRzbHVnICkgKTsKCgkJCS8vIElmIGluc3RhbGxhdGlvbiBnb2VzIHdlbGwgJHJlc3VsdCB3aWxsIGJlIHRydWUuCgkJCSRhbGxvd19hY3RpdmF0aW9uID0gJHJlc3VsdDsKCgkJCS8vIEFsbG93IGluc3RhbGxhdGlvbiBmb3IgaW5zdGFsbGVkIGV4dGVuc2lvbi4KCQkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICYmICdhbHJlYWR5X2luc3RhbGxlZCcgPT09ICRyZXN1bHQtPmdldF9lcnJvcl9jb2RlKCkgKSB7CgkJCQkkYWxsb3dfYWN0aXZhdGlvbiA9IHRydWU7CgkJCX0KCgkJCWlmICggdHJ1ZSA9PT0gJGFsbG93X2FjdGl2YXRpb24gJiYgY291bnQoICRleHRlbnNpb24gKSA+IDAgKSB7CgkJCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gdHJ1ZTsKCQkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWN0aXZhdGUtbmV0d29yaycgKSApIHsKCQkJCQlXUF9DTEk6OmxvZyggIk5ldHdvcmstYWN0aXZhdGluZyAnJHNsdWcnLi4uIiApOwoJCQkJCSR0aGlzLT5hY3RpdmF0ZSggYXJyYXkoICRzbHVnICksIGFycmF5KCAnbmV0d29yaycgPT4gdHJ1ZSApICk7CgkJCQl9CgoJCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhY3RpdmF0ZScgKSApIHsKCQkJCQlXUF9DTEk6OmxvZyggIkFjdGl2YXRpbmcgJyRzbHVnJy4uLiIgKTsKCQkJCQkkdGhpcy0+YWN0aXZhdGUoIGFycmF5KCAkc2x1ZyApICk7CgkJCQl9CgkJCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gZmFsc2U7CgkJCX0KCQl9CgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAkdGhpcy0+aXRlbV90eXBlLCAnaW5zdGFsbCcsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7Cgl9CgoJLyoqCgkgKiBQcmVwYXJlIGFuIEFQSSByZXNwb25zZSBmb3IgZG93bmxvYWRpbmcgYSBwYXJ0aWN1bGFyIHZlcnNpb24gb2YgYW4gaXRlbS4KCSAqCgkgKiBAcGFyYW0gb2JqZWN0ICRyZXNwb25zZSB3b3JkcHJlc3Mub3JnIEFQSSByZXNwb25zZQoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBUaGUgZGVzaXJlZCB2ZXJzaW9uIG9mIHRoZSBwYWNrYWdlCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gYWx0ZXJfYXBpX3Jlc3BvbnNlKCAkcmVzcG9uc2UsICR2ZXJzaW9uICkgewoJCWlmICggJHJlc3BvbnNlLT52ZXJzaW9uID09PSAkdmVyc2lvbiApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gV29yZFByZXNzLm9yZyBmb3JjZXMgaHR0cHMsIGJ1dCBzdGlsbCBzb21ldGltZXMgcmV0dXJucyBodHRwCgkJLy8gU2VlIGh0dHBzOi8vdHdpdHRlci5jb20vbmFjaW4vc3RhdHVzLzUxMjM2MjY5NDIwNTE0MDk5MgoJCSRyZXNwb25zZS0+ZG93bmxvYWRfbGluayA9IHN0cl9yZXBsYWNlKCAnaHR0cDovLycsICdodHRwczovLycsICRyZXNwb25zZS0+ZG93bmxvYWRfbGluayApOwoKCQlsaXN0KCAkbGluayApID0gZXhwbG9kZSggJHJlc3BvbnNlLT5zbHVnLCAkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmsgKTsKCgkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmssICcvdGhlbWUvJyApICkgewoJCQkkZG93bmxvYWRfdHlwZSA9ICd0aGVtZSc7CgkJfSBlbHNlaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmssICcvcGx1Z2luLycgKSApIHsKCQkJJGRvd25sb2FkX3R5cGUgPSAncGx1Z2luJzsKCQl9IGVsc2UgewoJCQkkZG93bmxvYWRfdHlwZSA9ICdwbHVnaW4vdGhlbWUnOwoJCX0KCgkJaWYgKCAnZGV2JyA9PT0gJHZlcnNpb24gKSB7CgkJCSRyZXNwb25zZS0+ZG93bmxvYWRfbGluayA9ICRsaW5rIC4gJHJlc3BvbnNlLT5zbHVnIC4gJy56aXAnOwoJCQkkcmVzcG9uc2UtPnZlcnNpb24gICAgICAgPSAnRGV2ZWxvcG1lbnQgVmVyc2lvbic7CgkJfSBlbHNlIHsKCQkJJHJlc3BvbnNlLT5kb3dubG9hZF9saW5rID0gJGxpbmsgLiAkcmVzcG9uc2UtPnNsdWcgLiAnLicgLiAkdmVyc2lvbiAuICcuemlwJzsKCQkJJHJlc3BvbnNlLT52ZXJzaW9uICAgICAgID0gJHZlcnNpb247CgoJCQkvLyBDaGVjayBpZiB0aGUgcmVxdWVzdGVkIHZlcnNpb24gZXhpc3RzLgoJCQkkcmVzcG9uc2UgICAgICA9IHdwX3JlbW90ZV9oZWFkKCAkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmsgKTsKCQkJJHJlc3BvbnNlX2NvZGUgPSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfY29kZSggJHJlc3BvbnNlICk7CgkJCWlmICggMjAwICE9PSAoaW50KSAkcmVzcG9uc2VfY29kZSApIHsKCQkJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQkJCSRlcnJvcl9tc2cgPSAkcmVzcG9uc2UtPmdldF9lcnJvcl9tZXNzYWdlKCk7CgkJCQl9IGVsc2UgewoJCQkJCSRlcnJvcl9tc2cgPSBzcHJpbnRmKCAnSFRUUCBjb2RlICVkJywgJHJlc3BvbnNlX2NvZGUgKTsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkJc3ByaW50ZigKCQkJCQkJIkNhbid0IGZpbmQgdGhlIHJlcXVlc3RlZCAlcydzIHZlcnNpb24gJXMgaW4gdGhlIFdvcmRQcmVzcy5vcmcgJXMgcmVwb3NpdG9yeSAoJXMpLiIsCgkJCQkJCSRkb3dubG9hZF90eXBlLAoJCQkJCQkkdmVyc2lvbiwKCQkJCQkJJGRvd25sb2FkX3R5cGUsCgkJCQkJCSRlcnJvcl9tc2cKCQkJCQkpCgkJCQkpOwoJCQl9CgkJfQoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXBncmFkZXIoICRhc3NvY19hcmdzICkgewoJCSRmb3JjZSAgICAgICAgICA9IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScsIGZhbHNlICk7CgkJJGluc2VjdXJlICAgICAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCQkkdXBncmFkZXJfY2xhc3MgPSAkdGhpcy0+Z2V0X3VwZ3JhZGVyX2NsYXNzKCAkZm9yY2UgKTsKCQlyZXR1cm4gVXRpbHNcZ2V0X3VwZ3JhZGVyKCAkdXBncmFkZXJfY2xhc3MsICRpbnNlY3VyZSApOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVfbWFueSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWNhbGxfdXNlcl9mdW5jKCAkdGhpcy0+dXBncmFkZV9yZWZyZXNoICk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgJiYgaW5fYXJyYXkoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgWyAnanNvbicsICdjc3YnIF0sIHRydWUgKSApIHsKCQkJJGxvZ2dlciA9IG5ldyBMb2dnZXJzXFF1aWV0KCBXUF9DTEk6OmdldF9ydW5uZXIoKS0+aW5fY29sb3IoKSApOwoJCQlXUF9DTEk6OnNldF9sb2dnZXIoICRsb2dnZXIgKTsKCQl9CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSB7JHRoaXMtPml0ZW1fdHlwZX1zLCBvciB1c2UgLS1hbGwuIiApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdtaW5vcicgKSAmJiBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwYXRjaCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJy0tbWlub3IgYW5kIC0tcGF0Y2ggY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIuJyApOwoJCX0KCgkJJGl0ZW1zID0gJHRoaXMtPmdldF9pdGVtX2xpc3QoKTsKCgkJJGVycm9ycyA9IDA7CgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKSApIHsKCQkJJGl0ZW1zICA9ICR0aGlzLT5maWx0ZXJfaXRlbV9saXN0KCAkaXRlbXMsICRhcmdzICk7CgkJCSRlcnJvcnMgPSBjb3VudCggJGFyZ3MgKSAtIGNvdW50KCAkaXRlbXMgKTsKCQl9CgoJCSRpdGVtc190b191cGRhdGUgPSB3cF9saXN0X2ZpbHRlciggJGl0ZW1zLCBbICd1cGRhdGUnID0+IHRydWUgXSApOwoKCQkkbWlub3IgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbWlub3InLCBmYWxzZSApOwoJCSRwYXRjaCA9IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwYXRjaCcsIGZhbHNlICk7CgoJCWlmICggJ3BsdWdpbicgPT09ICR0aGlzLT5pdGVtX3R5cGUKCQkJJiYgKCAkbWlub3IgfHwgJHBhdGNoICkgKSB7CgkJCSR0eXBlICAgICA9ICRtaW5vciA/ICdtaW5vcicgOiAncGF0Y2gnOwoJCQkkaW5zZWN1cmUgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5zZWN1cmUnLCBmYWxzZSApOwoKCQkJJGl0ZW1zX3RvX3VwZGF0ZSA9IHNlbGY6OmdldF9taW5vcl9vcl9wYXRjaF91cGRhdGVzKCAkaXRlbXNfdG9fdXBkYXRlLCAkdHlwZSwgJGluc2VjdXJlICk7CgkJfQoKCQkkZXhjbHVkZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2V4Y2x1ZGUnICk7CgkJaWYgKCBpc3NldCggJGV4Y2x1ZGUgKSApIHsKCQkJJGV4Y2x1ZGVfaXRlbXMgPSBleHBsb2RlKCAnLCcsIHRyaW0oICRhc3NvY19hcmdzWydleGNsdWRlJ10sICcsJyApICk7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snZXhjbHVkZSddICk7CgkJCWZvcmVhY2ggKCAkZXhjbHVkZV9pdGVtcyBhcyAkaXRlbSApIHsKCQkJCWlmICggJ3BsdWdpbicgPT09ICR0aGlzLT5pdGVtX3R5cGUgKSB7CgkJCQkJJHBsdWdpbiA9ICR0aGlzLT5mZXRjaGVyLT5nZXQoICRpdGVtICk7CgkJCQkJdW5zZXQoICRpdGVtc190b191cGRhdGVbICRwbHVnaW4tPmZpbGUgXSApOwoJCQkJfSBlbHNlaWYgKCAndGhlbWUnID09PSAkdGhpcy0+aXRlbV90eXBlICkgewoJCQkJCSR0aGVtZV9yb290ID0gZ2V0X3RoZW1lX3Jvb3QoKSAuICcvJyAuICRpdGVtOwoJCQkJCXVuc2V0KCAkaXRlbXNfdG9fdXBkYXRlWyAkdGhlbWVfcm9vdCBdICk7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIENoZWNrIGZvciBpdGVtcyB0byB1cGRhdGUgYW5kIHJlbW92ZSBleHRlbnNpb25zIHRoYXQgaGF2ZSB2ZXJzaW9uIGhpZ2hlciB0aGFuIGV4cGVjdGVkLgoJCWZvcmVhY2ggKCAkaXRlbXNfdG9fdXBkYXRlIGFzICRpdGVtX2tleSA9PiAkaXRlbV9pbmZvICkgewoJCQlpZiAoIHN0YXRpYzo6SU5WQUxJRF9WRVJTSU9OX01FU1NBR0UgPT09ICRpdGVtX2luZm9bJ3VwZGF0ZSddICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRpdGVtX2luZm9bJ25hbWUnXX06ICIgLiBzdGF0aWM6OklOVkFMSURfVkVSU0lPTl9NRVNTQUdFIC4gJy4nICk7CgkJCQkkZXJyb3JzKys7CgkJCQl1bnNldCggJGl0ZW1zX3RvX3VwZGF0ZVsgJGl0ZW1fa2V5IF0gKTsKCQkJfQoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkcnktcnVuJyApICkgewoJCQlpZiAoIGVtcHR5KCAkaXRlbXNfdG9fdXBkYXRlICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIk5vIHskdGhpcy0+aXRlbV90eXBlfSB1cGRhdGVzIGF2YWlsYWJsZS4iICk7CgoJCQkJaWYgKCBudWxsICE9PSAkZXhjbHVkZSApIHsKCQkJCQlXUF9DTEk6OmxvZyggIlNraXBwZWQgdXBkYXRlcyBmb3I6ICRleGNsdWRlIiApOwoJCQkJfQoKCQkJCXJldHVybjsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiBpbl9hcnJheSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCBbICdqc29uJywgJ2NzdicgXSwgdHJ1ZSApICkgewoJCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAkYXNzb2NfYXJnc1snZm9ybWF0J10sICRpdGVtc190b191cGRhdGUsIFsgJ25hbWUnLCAnc3RhdHVzJywgJ3ZlcnNpb24nLCAndXBkYXRlX3ZlcnNpb24nIF0gKTsKCQkJfSBlbHNlaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiAnc3VtbWFyeScgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJCVdQX0NMSTo6bG9nKCAiQXZhaWxhYmxlIHskdGhpcy0+aXRlbV90eXBlfSB1cGRhdGVzOiIgKTsKCQkJCWZvcmVhY2ggKCAkaXRlbXNfdG9fdXBkYXRlIGFzICRpdGVtX3RvX3VwZGF0ZSA9PiAkaW5mbyApIHsKCQkJCQlXUF9DTEk6OmxvZyggInskaW5mb1sndGl0bGUnXX0gdXBkYXRlIGZyb20gdmVyc2lvbiB7JGluZm9bJ3ZlcnNpb24nXX0gdG8gdmVyc2lvbiB7JGluZm9bJ3VwZGF0ZV92ZXJzaW9uJ119IiApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICJBdmFpbGFibGUgeyR0aGlzLT5pdGVtX3R5cGV9IHVwZGF0ZXM6IiApOwoJCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAndGFibGUnLCAkaXRlbXNfdG9fdXBkYXRlLCBbICduYW1lJywgJ3N0YXR1cycsICd2ZXJzaW9uJywgJ3VwZGF0ZV92ZXJzaW9uJyBdICk7CgkJCX0KCgkJCWlmICggbnVsbCAhPT0gJGV4Y2x1ZGUgKSB7CgkJCQlXUF9DTEk6OmxvZyggIlNraXBwZWQgdXBkYXRlcyBmb3I6ICRleGNsdWRlIiApOwoJCQl9CgoJCQlyZXR1cm47CgkJfQoKCQkkcmVzdWx0ID0gYXJyYXkoKTsKCgkJLy8gT25seSBhdHRlbXB0IHRvIHVwZGF0ZSBpZiB0aGVyZSBpcyBzb21ldGhpbmcgdG8gdXBkYXRlLgoJCWlmICggISBlbXB0eSggJGl0ZW1zX3RvX3VwZGF0ZSApICkgewoJCQkkY2FjaGVfbWFuYWdlciA9IFdQX0NMSTo6Z2V0X2h0dHBfY2FjaGVfbWFuYWdlcigpOwoJCQlmb3JlYWNoICggJGl0ZW1zX3RvX3VwZGF0ZSBhcyAkaXRlbSApIHsKCQkJCSRjYWNoZV9tYW5hZ2VyLT53aGl0ZWxpc3RfcGFja2FnZSggJGl0ZW1bJ3VwZGF0ZV9wYWNrYWdlJ10sICR0aGlzLT5pdGVtX3R5cGUsICRpdGVtWyduYW1lJ10sICRpdGVtWyd1cGRhdGVfdmVyc2lvbiddICk7CgkJCX0KCQkJJHVwZ3JhZGVyID0gJHRoaXMtPmdldF91cGdyYWRlciggJGFzc29jX2FyZ3MgKTsKCQkJLy8gRW5zdXJlIHRoZSB1cGdyYWRlciB1c2VzIHRoZSBkb3dubG9hZCBvZmZlciBwcmVzZW50IGluIGVhY2ggaXRlbS4KCQkJJHRyYW5zaWVudF9maWx0ZXIgPSBmdW5jdGlvbiggJHRyYW5zaWVudCApIHVzZSAoICRpdGVtc190b191cGRhdGUgKSB7CgkJCQlmb3JlYWNoICggJGl0ZW1zX3RvX3VwZGF0ZSBhcyAkbmFtZSA9PiAkaXRlbV9kYXRhICkgewoJCQkJCWlmICggaXNzZXQoICR0cmFuc2llbnQtPnJlc3BvbnNlWyAkbmFtZSBdICkgKSB7CgkJCQkJCSR0cmFuc2llbnQtPnJlc3BvbnNlWyAkbmFtZSBdLT5uZXdfdmVyc2lvbiA9ICRpdGVtX2RhdGFbJ3VwZGF0ZV92ZXJzaW9uJ107CgkJCQkJCSR0cmFuc2llbnQtPnJlc3BvbnNlWyAkbmFtZSBdLT5wYWNrYWdlICAgICA9ICRpdGVtX2RhdGFbJ3VwZGF0ZV9wYWNrYWdlJ107CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuICR0cmFuc2llbnQ7CgkJCX07CgkJCWFkZF9maWx0ZXIoICdzaXRlX3RyYW5zaWVudF8nIC4gJHRoaXMtPnVwZ3JhZGVfdHJhbnNpZW50LCAkdHJhbnNpZW50X2ZpbHRlciwgOTk5ICk7CgkJCSRyZXN1bHQgPSAkdXBncmFkZXItPmJ1bGtfdXBncmFkZSggd3BfbGlzdF9wbHVjayggJGl0ZW1zX3RvX3VwZGF0ZSwgJ3VwZGF0ZV9pZCcgKSApOwoJCQlyZW1vdmVfZmlsdGVyKCAnc2l0ZV90cmFuc2llbnRfJyAuICR0aGlzLT51cGdyYWRlX3RyYW5zaWVudCwgJHRyYW5zaWVudF9maWx0ZXIsIDk5OSApOwoJCX0KCgkJLy8gTGV0IHRoZSB1c2VyIGtub3cgdGhlIHJlc3VsdHMuCgkJJG51bV90b191cGRhdGUgPSBjb3VudCggJGl0ZW1zX3RvX3VwZGF0ZSApOwoJCSRudW1fdXBkYXRlZCAgID0gY291bnQoCgkJCWFycmF5X2ZpbHRlcigKCQkJCSRyZXN1bHQsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCAkcmVzdWx0ICkgewoJCQkJCXJldHVybiAkcmVzdWx0ICYmICEgaXNfd3BfZXJyb3IoICRyZXN1bHQgKTsKCQkJCX0KCQkJKQoJCSk7CgoJCWlmICggJG51bV90b191cGRhdGUgPiAwICkgewoJCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICYmICdzdW1tYXJ5JyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkJZm9yZWFjaCAoICRpdGVtc190b191cGRhdGUgYXMgJGl0ZW1fdG9fdXBkYXRlID0+ICRpbmZvICkgewoJCQkJCSRtZXNzYWdlID0gbnVsbCAhPT0gJHJlc3VsdFsgJGluZm9bJ3VwZGF0ZV9pZCddIF0gPyAndXBkYXRlZCBzdWNjZXNzZnVsbHknIDogJ2RpZCBub3QgdXBkYXRlJzsKCQkJCQlXUF9DTEk6OmxvZyggInskaW5mb1sndGl0bGUnXX0geyRtZXNzYWdlfSBmcm9tIHZlcnNpb24geyRpbmZvWyd2ZXJzaW9uJ119IHRvIHZlcnNpb24geyRpbmZvWyd1cGRhdGVfdmVyc2lvbiddfSIgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCSRzdGF0dXMgPSBhcnJheSgpOwoJCQkJZm9yZWFjaCAoICRpdGVtc190b191cGRhdGUgYXMgJGl0ZW1fdG9fdXBkYXRlID0+ICRpbmZvICkgewoJCQkJCSRzdGF0dXNbICRpdGVtX3RvX3VwZGF0ZSBdID0gWwoJCQkJCQknbmFtZScgICAgICAgID0+ICRpbmZvWyduYW1lJ10sCgkJCQkJCSdvbGRfdmVyc2lvbicgPT4gJGluZm9bJ3ZlcnNpb24nXSwKCQkJCQkJJ25ld192ZXJzaW9uJyA9PiAkaW5mb1sndXBkYXRlX3ZlcnNpb24nXSwKCQkJCQkJJ3N0YXR1cycgICAgICA9PiAoIG51bGwgIT09ICRyZXN1bHRbICRpbmZvWyd1cGRhdGVfaWQnXSBdICYmICEgaXNfd3BfZXJyb3IoICRyZXN1bHRbICRpbmZvWyd1cGRhdGVfaWQnXSBdICkgKSA/ICdVcGRhdGVkJyA6ICdFcnJvcicsCgkJCQkJXTsKCQkJCQlpZiAoIG51bGwgPT09ICRyZXN1bHRbICRpbmZvWyd1cGRhdGVfaWQnXSBdIHx8IGlzX3dwX2Vycm9yKCAkcmVzdWx0WyAkaW5mb1sndXBkYXRlX2lkJ10gXSApICkgewoJCQkJCQkkZXJyb3JzKys7CgkJCQkJfQoJCQkJfQoKCQkJCSRmb3JtYXQgPSAndGFibGUnOwoJCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiBpbl9hcnJheSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCBbICdqc29uJywgJ2NzdicgXSwgdHJ1ZSApICkgewoJCQkJCSRmb3JtYXQgPSAkYXNzb2NfYXJnc1snZm9ybWF0J107CgkJCQl9CgoJCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAkZm9ybWF0LCAkc3RhdHVzLCBbICduYW1lJywgJ29sZF92ZXJzaW9uJywgJ25ld192ZXJzaW9uJywgJ3N0YXR1cycgXSApOwoJCQl9CgkJfQoKCQkkdG90YWxfdXBkYXRlZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKSA/ICRudW1fdG9fdXBkYXRlIDogY291bnQoICRhcmdzICk7CgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAkdGhpcy0+aXRlbV90eXBlLCAndXBkYXRlJywgJHRvdGFsX3VwZGF0ZWQsICRudW1fdXBkYXRlZCwgJGVycm9ycyApOwoJCWlmICggbnVsbCAhPT0gJGV4Y2x1ZGUgKSB7CgkJCVdQX0NMSTo6bG9nKCAiU2tpcHBlZCB1cGRhdGVzIGZvcjogJGV4Y2x1ZGUiICk7CgkJfQoJfQoKCS8vIHBocGNzOmlnbm9yZSBQU1IyLk1ldGhvZHMuTWV0aG9kRGVjbGFyYXRpb24uVW5kZXJzY29yZSAtLSBXaGl0ZWxpc3RpbmcgdG8gcHJvdmlkZSBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHRvIGNsYXNzZXMgcG9zc2libHkgZXh0ZW5kaW5nIHRoaXMgY2xhc3MuCglwcm90ZWN0ZWQgZnVuY3Rpb24gX2xpc3QoICRfLCAkYXNzb2NfYXJncyApIHsKCgkJLy8gRm9yY2UgV29yZFByZXNzIHRvIGNoZWNrIGZvciB1cGRhdGVzIGlmIGAtLXNraXAtdXBkYXRlLWNoZWNrYCBpcyBub3QgcGFzc2VkLgoJCWlmICggZmFsc2UgPT09IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXVwZGF0ZS1jaGVjaycsIGZhbHNlICkgKSB7CgkJCWNhbGxfdXNlcl9mdW5jKCAkdGhpcy0+dXBncmFkZV9yZWZyZXNoICk7CgkJfQoKCQkkYWxsX2l0ZW1zID0gJHRoaXMtPmdldF9hbGxfaXRlbXMoKTsKCgkJaWYgKCAhIGlzX2FycmF5KCAkYWxsX2l0ZW1zICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJObyB7JHRoaXMtPml0ZW1fdHlwZX1zIGZvdW5kLiIgKTsKCQl9CgoJCWZvcmVhY2ggKCAkYWxsX2l0ZW1zIGFzICRrZXkgPT4gJiRpdGVtICkgewoKCQkJaWYgKCBlbXB0eSggJGl0ZW1bJ3ZlcnNpb24nXSApICkgewoJCQkJJGl0ZW1bJ3ZlcnNpb24nXSA9ICcnOwoJCQl9CgoJCQlmb3JlYWNoICggJGl0ZW0gYXMgJGZpZWxkID0+ICYkdmFsdWUgKSB7CgkJCQlpZiAoIHRydWUgPT09ICR2YWx1ZSApIHsKCQkJCQkkdmFsdWUgPSAnYXZhaWxhYmxlJzsKCQkJCX0gZWxzZWlmICggZmFsc2UgPT09ICR2YWx1ZSApIHsKCQkJCQkkdmFsdWUgPSAnbm9uZSc7CgkJCQl9CgkJCX0KCgkJCWZvcmVhY2ggKCAkdGhpcy0+b2JqX2ZpZWxkcyBhcyAkZmllbGQgKSB7CgkJCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJGZpZWxkLCAkYXNzb2NfYXJncyApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCS8vIFRoaXMgY2FuIGJlIGVpdGhlciBhIHZhbHVlIHRvIGZpbHRlciBieSBvciBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIHZhbHVlcy4KCQkJCS8vIEFsc28sIGl0IGlzIG5vdCBmb3JiaWRkZW4gZm9yIGEgdmFsdWUgdG8gY29udGFpbiBhIGNvbW1hIChpbiB3aGljaCBjYXNlIHdlIGNhbiBmaWx0ZXIgb25seSBieSBvbmUpLgoJCQkJJGZpZWxkX2ZpbHRlciA9ICRhc3NvY19hcmdzWyAkZmllbGQgXTsKCQkJCWlmICgKCQkJCQkkaXRlbVsgJGZpZWxkIF0gIT09ICRmaWVsZF9maWx0ZXIKCQkJCQkmJiAhIGluX2FycmF5KCAkaXRlbVsgJGZpZWxkIF0sIGFycmF5X21hcCggJ3RyaW0nLCBleHBsb2RlKCAnLCcsICRmaWVsZF9maWx0ZXIgKSApLCB0cnVlICkKCQkJCSkgewoJCQkJCXVuc2V0KCAkYWxsX2l0ZW1zWyAka2V5IF0gKTsKCQkJCX0KCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRhbGxfaXRlbXMgKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYW4gaXRlbSBoYXMgYW4gdXBkYXRlIGF2YWlsYWJsZSBvciBub3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2x1ZyBUaGUgcGx1Z2luL3RoZW1lIHNsdWcKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc191cGRhdGUoICRzbHVnICkgewoJCSR1cGRhdGVfbGlzdCA9IGdldF9zaXRlX3RyYW5zaWVudCggJHRoaXMtPnVwZ3JhZGVfdHJhbnNpZW50ICk7CgoJCXJldHVybiBpc3NldCggJHVwZGF0ZV9saXN0LT5yZXNwb25zZVsgJHNsdWcgXSApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhdmFpbGFibGUgdXBkYXRlIGluZm8KCSAqCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXBkYXRlX2luZm8oKSB7CgkJcmV0dXJuIGdldF9zaXRlX3RyYW5zaWVudCggJHRoaXMtPnVwZ3JhZGVfdHJhbnNpZW50ICk7Cgl9CgoJcHJpdmF0ZSAkbWFwID0gWwoJCSdzaG9ydCcgPT4gWwoJCQknaW5hY3RpdmUnICAgICAgID0+ICdJJywKCQkJJ2FjdGl2ZScgICAgICAgICA9PiAnQScsCgkJCSdhY3RpdmUtbmV0d29yaycgPT4gJ04nLAoJCQknbXVzdC11c2UnICAgICAgID0+ICdNJywKCQkJJ3BhcmVudCcgICAgICAgICA9PiAnUCcsCgkJCSdkcm9waW4nICAgICAgICAgPT4gJ0QnLAoJCV0sCgkJJ2xvbmcnICA9PiBbCgkJCSdpbmFjdGl2ZScgICAgICAgPT4gJ0luYWN0aXZlJywKCQkJJ2FjdGl2ZScgICAgICAgICA9PiAnQWN0aXZlJywKCQkJJ2FjdGl2ZS1uZXR3b3JrJyA9PiAnTmV0d29yayBBY3RpdmUnLAoJCQknbXVzdC11c2UnICAgICAgID0+ICdNdXN0IFVzZScsCgkJCSdwYXJlbnQnICAgICAgICAgPT4gJ1BhcmVudCcsCgkJCSdkcm9waW4nICAgICAgICAgPT4gJ0Ryb3AtSW4nLAoJCV0sCgldOwoKCXByb3RlY3RlZCBmdW5jdGlvbiBmb3JtYXRfc3RhdHVzKCAkc3RhdHVzLCAkZm9ybWF0ICkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2NvbG9yKCAkc3RhdHVzICkgLiAkdGhpcy0+bWFwWyAkZm9ybWF0IF1bICRzdGF0dXMgXTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb2xvciggJHN0YXR1cyApIHsKCQlzdGF0aWMgJGNvbG9ycyA9IFsKCQkJJ2luYWN0aXZlJyAgICAgICA9PiAnJywKCQkJJ2FjdGl2ZScgICAgICAgICA9PiAnJWcnLAoJCQknYWN0aXZlLW5ldHdvcmsnID0+ICclZycsCgkJCSdtdXN0LXVzZScgICAgICAgPT4gJyVjJywKCQkJJ3BhcmVudCcgICAgICAgICA9PiAnJXAnLAoJCQknZHJvcGluJyAgICAgICAgID0+ICclQicsCgkJXTsKCgkJcmV0dXJuICRjb2xvcnNbICRzdGF0dXMgXTsKCX0KCgkvKioKCSAqIEdldCB0aGUgbWlub3Igb3IgcGF0Y2ggdmVyc2lvbiBmb3IgcGx1Z2lucyB3aXRoIGF2YWlsYWJsZSB1cGRhdGVzCgkgKgoJICogQHBhcmFtIGFycmF5ICAkaXRlbXMgICAgUGx1Z2lucyB3aXRoIHVwZGF0ZXMuCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlICAgICBFaXRoZXIgJ21pbm9yJyBvciAncGF0Y2gnLgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgV2hldGhlciB0byByZXRyeSB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gb24gVExTIGhhbmRzaGFrZSBmYWlsdXJlLgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9taW5vcl9vcl9wYXRjaF91cGRhdGVzKCAkaXRlbXMsICR0eXBlLCAkaW5zZWN1cmUgKSB7CgkJJHdwX29yZ19hcGkgPSBuZXcgV3BPcmdBcGkoIFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXSApOwoJCWZvcmVhY2ggKCAkaXRlbXMgYXMgJGkgPT4gJGl0ZW0gKSB7CgkJCXRyeSB7CgkJCQkkZGF0YSA9ICR3cF9vcmdfYXBpLT5nZXRfcGx1Z2luX2luZm8oICRpdGVtWyduYW1lJ10gKTsKCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQkJdW5zZXQoICRpdGVtc1sgJGkgXSApOwoJCQkJY29udGludWU7CgkJCX0KCQkJLy8gTm8gbWlub3Igb3IgcGF0Y2ggdmVyc2lvbnMgdG8gYWNjZXNzLgoJCQlpZiAoIGVtcHR5KCAkZGF0YVsndmVyc2lvbnMnXSApICkgewoJCQkJdW5zZXQoICRpdGVtc1sgJGkgXSApOwoJCQkJY29udGludWU7CgkJCX0KCQkJJHVwZGF0ZV92ZXJzaW9uID0gZmFsc2U7CgkJCSR1cGRhdGVfcGFja2FnZSA9IGZhbHNlOwoJCQlmb3JlYWNoICggJGRhdGFbJ3ZlcnNpb25zJ10gYXMgJHZlcnNpb24gPT4gJGRvd25sb2FkX2xpbmsgKSB7CgkJCQkkdXBkYXRlX3R5cGUgPSBVdGlsc1xnZXRfbmFtZWRfc2VtX3ZlciggJHZlcnNpb24sICRpdGVtWyd2ZXJzaW9uJ10gKTsKCQkJCS8vIENvbXBhcmVkIHZlcnNpb24gbXVzdCBiZSBvbGRlci4KCQkJCWlmICggISAkdXBkYXRlX3R5cGUgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkvLyBPbmx5IHBlcm1pdCAncGF0Y2gnIGZvciAncGF0Y2gnLgoJCQkJaWYgKCAncGF0Y2gnID09PSAkdHlwZSAmJiAncGF0Y2gnICE9PSAkdXBkYXRlX3R5cGUgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkvLyBQZXJtaXQgJ21pbm9yJyBvciAncGF0Y2gnIGZvciAnbWlub3InIHBocGNzOmlnbm9yZSBTcXVpei5QSFAuQ29tbWVudGVkT3V0Q29kZS5Gb3VuZCAtLSBGYWxzZSBwb3NpdGl2ZS4KCQkJCWlmICggJ21pbm9yJyA9PT0gJHR5cGUgJiYgISBpbl9hcnJheSggJHVwZGF0ZV90eXBlLCBhcnJheSggJ21pbm9yJywgJ3BhdGNoJyApLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlpZiAoICR1cGRhdGVfdmVyc2lvbiAmJiAhIENvbXBhcmF0b3I6OmdyZWF0ZXJUaGFuKCAkdmVyc2lvbiwgJHVwZGF0ZV92ZXJzaW9uICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkdXBkYXRlX3ZlcnNpb24gPSAkdmVyc2lvbjsKCQkJCSR1cGRhdGVfcGFja2FnZSA9ICRkb3dubG9hZF9saW5rOwoJCQl9CgkJCS8vIElmIHRoZXJlJ3Mgbm90IGEgbWF0Y2hpbmcgdmVyc2lvbiwgYmFpbCBvbiB1cGRhdGVzLgoJCQlpZiAoICEgJHVwZGF0ZV92ZXJzaW9uICkgewoJCQkJdW5zZXQoICRpdGVtc1sgJGkgXSApOwoJCQkJY29udGludWU7CgkJCX0KCQkJJGl0ZW1zWyAkaSBdWyd1cGRhdGVfdmVyc2lvbiddID0gJHVwZGF0ZV92ZXJzaW9uOwoJCQkkaXRlbXNbICRpIF1bJ3VwZGF0ZV9wYWNrYWdlJ10gPSAkdXBkYXRlX3BhY2thZ2U7CgkJfQoJCXJldHVybiAkaXRlbXM7Cgl9CgoJLyoqCgkgKiBTZWFyY2ggd29yZHByZXNzLm9yZyByZXBvLgoJICoKCSAqIEBwYXJhbSAgYXJyYXkgJGFyZ3MgICAgICAgQSBhcmd1bWVudHMgYXJyYXkgY29udGFpbmluZyB0aGUgc2VhcmNoIHRlcm0gaW4gdGhlIGZpcnN0IGVsZW1lbnQuCgkgKiBAcGFyYW0gIGFycmF5ICRhc3NvY19hcmdzIERhdGEgcGFzc2VkIGluIGZyb20gY29tbWFuZC4KCSAqLwoJLy8gcGhwY3M6aWdub3JlIFBTUjIuTWV0aG9kcy5NZXRob2REZWNsYXJhdGlvbi5VbmRlcnNjb3JlIC0tIFdoaXRlbGlzdGluZyB0byBwcm92aWRlIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgdG8gY2xhc3NlcyBwb3NzaWJseSBleHRlbmRpbmcgdGhpcyBjbGFzcy4KCXByb3RlY3RlZCBmdW5jdGlvbiBfc2VhcmNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRlcm0gPSAkYXJnc1swXTsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdwZXItcGFnZScgPT4gMTAsCgkJCSdwYWdlJyAgICAgPT4gMSwKCQkJJ2ZpZWxkcycgICA9PiBpbXBsb2RlKCAnLCcsIFsgJ25hbWUnLCAnc2x1ZycsICdyYXRpbmcnIF0gKSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCQkkZmllbGRzICAgICA9IGFycmF5KCk7CgkJZm9yZWFjaCAoIGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgYXMgJGZpZWxkICkgewoJCQkkZmllbGRzWyAkZmllbGQgXSA9IHRydWU7CgkJfQoKCQkkZm9ybWF0ICAgID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgPyAkYXNzb2NfYXJnc1snZm9ybWF0J10gOiAndGFibGUnOwoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJJGFwaV9hcmdzID0gWwoJCQkncGVyX3BhZ2UnID0+IChpbnQpICRhc3NvY19hcmdzWydwZXItcGFnZSddLAoJCQkncGFnZScgICAgID0+IChpbnQpICRhc3NvY19hcmdzWydwYWdlJ10sCgkJCSdzZWFyY2gnICAgPT4gJHRlcm0sCgkJCSdmaWVsZHMnICAgPT4gJGZpZWxkcywKCQldOwoKCQlpZiAoICdwbHVnaW4nID09PSAkdGhpcy0+aXRlbV90eXBlICkgewoJCQkkYXBpID0gcGx1Z2luc19hcGkoICdxdWVyeV9wbHVnaW5zJywgJGFwaV9hcmdzICk7CgkJfSBlbHNlIHsKCQkJJGFwaSA9IHRoZW1lc19hcGkoICdxdWVyeV90aGVtZXMnLCAkYXBpX2FyZ3MgKTsKCQl9CgoJCWlmICggaXNfd3BfZXJyb3IoICRhcGkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGFwaS0+Z2V0X2Vycm9yX21lc3NhZ2UoKSAuIF9fKCAnIFRyeSBhZ2FpbicgKSApOwoJCX0KCgkJJHBsdXJhbCA9ICR0aGlzLT5pdGVtX3R5cGUgLiAncyc7CgoJCWlmICggISBpc3NldCggJGFwaS0+JHBsdXJhbCApICkgewoJCQlXUF9DTEk6OmVycm9yKCBfXyggJ0FQSSBlcnJvci4gVHJ5IEFnYWluLicgKSApOwoJCX0KCgkJJGl0ZW1zID0gJGFwaS0+JHBsdXJhbDsKCgkJLy8gQWRkIGB1cmxgIGZvciBwbHVnaW4gb3IgdGhlbWUgb24gd29yZHByZXNzLm9yZy4KCQlmb3JlYWNoICggJGl0ZW1zIGFzICRpbmRleCA9PiAkaXRlbV9vYmplY3QgKSB7CgkJCWlmICggJGl0ZW1fb2JqZWN0IGluc3RhbmNlb2YgXHN0ZENsYXNzICkgewoJCQkJJGl0ZW1fb2JqZWN0LT51cmwgPSAiaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3skcGx1cmFsfS97JGl0ZW1fb2JqZWN0LT5zbHVnfS8iOwoJCQl9CgkJfQoKCQlpZiAoICd0YWJsZScgPT09ICRmb3JtYXQgKSB7CgkJCSRjb3VudCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXBpLT5pbmZvLCAncmVzdWx0cycsICd1bmtub3duJyApOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICdTaG93aW5nICVzIG9mICVzICVzLicsIGNvdW50KCAkaXRlbXMgKSwgJGNvdW50LCAkcGx1cmFsICkgKTsKCQl9CgoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpdGVtcyApOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5vYmpfZmllbGRzLCAkdGhpcy0+aXRlbV90eXBlICk7Cgl9CgoJLyoqCgkgKiBFcnJvciBoYW5kbGVyIHRvIGlnbm9yZSBmYWlsdXJlcyBvbiBhY2Nlc3NpbmcgU1NMICJodHRwczovL2FwaS53b3JkcHJlc3Mub3JnL3RoZW1lcy91cGRhdGUtY2hlY2svMS4xLyIgaW4gYHdwX3VwZGF0ZV90aGVtZXMoKWAKCSAqIGFuZCAiaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZy9wbHVnaW5zL3VwZGF0ZS1jaGVjay8xLjEvIiBpbiBgd3BfdXBkYXRlX3BsdWdpbnMoKWAgd2hpY2ggc2VlbSB0byBvY2N1ciBpbnRlcm1pdHRlbnRseS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcnJvcl9oYW5kbGVyKCAkZXJybm8sICRlcnJzdHIsICRlcnJmaWxlLCAkZXJybGluZSwgJGVycmNvbnRleHQgPSBudWxsICkgewoJCS8vIElmIGlnbm9yaW5nIEVfVVNFUl9XQVJOSU5HIHwgRV9VU0VSX05PVElDRSwgZGVmYXVsdC4KCQlpZiAoICEgKCBlcnJvcl9yZXBvcnRpbmcoKSAmICRlcnJubyApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCS8vIElmIG5vdCBpbiAid3AtaW5jbHVkZXMvdXBkYXRlLnBocCIsIGRlZmF1bHQuCgkJJHVwZGF0ZV9waHAgPSAnd3AtaW5jbHVkZXMvdXBkYXRlLnBocCc7CgkJaWYgKCAwICE9PSBzdWJzdHJfY29tcGFyZSggJGVycmZpbGUsICR1cGRhdGVfcGhwLCAtc3RybGVuKCAkdXBkYXRlX3BocCApICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJLy8gRWxzZSBhc3N1bWUgaXQncyBpbiBgd3BfdXBkYXRlX3RoZW1lcygpYCBvciBgd3BfdXBkYXRlX3BsdWdpbnMoKWAgYW5kIGp1c3QgaWdub3JlIGl0LgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogUmV0cmlldmVzIFBIUF9VUkxfSE9TVCBjb21wb25lbnQgZnJvbSBVUkwuCgkgKgoJICogQHBhcmFtIGludCAkY29tcG9uZW50IFRoZSBjb21wb25lbnQgdG8gcmV0cmlldmUuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZV91cmxfaG9zdF9jb21wb25lbnQoICR1cmwsICRjb21wb25lbnQgKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5wYXJzZV91cmxfcGFyc2VfdXJsIC0tIHBhcnNlX3VybCB3aWxsIG9ubHkgYmUgdXNlZCBpbiBhYnNlbmNlIG9mIHdwX3BhcnNlX3VybC4KCQlyZXR1cm4gZnVuY3Rpb25fZXhpc3RzKCAnd3BfcGFyc2VfdXJsJyApID8gd3BfcGFyc2VfdXJsKCAkdXJsLCAkY29tcG9uZW50ICkgOiBwYXJzZV91cmwoICR1cmwsICRjb21wb25lbnQgKTsKCX0KCn0KPD9waHAKCi8qKgogKiBTZXRzLCBnZXRzLCBhbmQgcmVtb3ZlcyB0aGVtZSBtb2RzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBTZXQgdGhlICdiYWNrZ3JvdW5kX2NvbG9yJyB0aGVtZSBtb2QgdG8gJzAwMDAwMCcuCiAqICAgICAkIHdwIHRoZW1lIG1vZCBzZXQgYmFja2dyb3VuZF9jb2xvciAwMDAwMDAKICogICAgIFN1Y2Nlc3M6IFRoZW1lIG1vZCBiYWNrZ3JvdW5kX2NvbG9yIHNldCB0byAwMDAwMDAKICoKICogICAgICMgR2V0IHNpbmdsZSB0aGVtZSBtb2QgaW4gSlNPTiBmb3JtYXQuCiAqICAgICAkIHdwIHRoZW1lIG1vZCBnZXQgYmFja2dyb3VuZF9jb2xvciAtLWZvcm1hdD1qc29uCiAqICAgICBbeyJrZXkiOiJiYWNrZ3JvdW5kX2NvbG9yIiwidmFsdWUiOiJkZDMzMzMifV0KICoKICogICAgICMgUmVtb3ZlIGFsbCB0aGVtZSBtb2RzLgogKiAgICAgJCB3cCB0aGVtZSBtb2QgcmVtb3ZlIC0tYWxsCiAqICAgICBTdWNjZXNzOiBUaGVtZSBtb2RzIHJlbW92ZWQuCiAqLwpjbGFzcyBUaGVtZV9Nb2RfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRmaWVsZHMgPSBbICdrZXknLCAndmFsdWUnIF07CgoJLyoqCgkgKiBHZXRzIG9uZSBvciBtb3JlIHRoZW1lIG1vZHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8bW9kPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgbW9kcyB0byBnZXQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tYWxsXQoJICogOiBMaXN0IGFsbCB0aGVtZSBtb2RzCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0ganNvbgoJICogICAtIGNzdgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGFsbCB0aGVtZSBtb2RzLgoJICogICAgICQgd3AgdGhlbWUgbW9kIGdldCAtLWFsbAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwga2V5ICAgICAgICAgICAgICB8IHZhbHVlICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgYmFja2dyb3VuZF9jb2xvciB8IGRkMzMzMyAgfAoJICogICAgIHwgbGlua19jb2xvciAgICAgICB8ICNkZDk5MzMgfAoJICogICAgIHwgbWFpbl90ZXh0X2NvbG9yICB8ICM4MjI0ZTMgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIEdldCBzaW5nbGUgdGhlbWUgbW9kIGluIEpTT04gZm9ybWF0LgoJICogICAgICQgd3AgdGhlbWUgbW9kIGdldCBiYWNrZ3JvdW5kX2NvbG9yIC0tZm9ybWF0PWpzb24KCSAqICAgICBbeyJrZXkiOiJiYWNrZ3JvdW5kX2NvbG9yIiwidmFsdWUiOiJkZDMzMzMifV0KCSAqCgkgKiAgICAgIyBHZXQgdmFsdWUgb2YgYSBzaW5nbGUgdGhlbWUgbW9kLgoJICogICAgICQgd3AgdGhlbWUgbW9kIGdldCBiYWNrZ3JvdW5kX2NvbG9yIC0tZmllbGQ9dmFsdWUKCSAqICAgICBkZDMzMzMKCSAqCgkgKiAgICAgIyBHZXQgbXVsdGlwbGUgdGhlbWUgbW9kcy4KCSAqICAgICAkIHdwIHRoZW1lIG1vZCBnZXQgYmFja2dyb3VuZF9jb2xvciBoZWFkZXJfdGV4dGNvbG9yCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKCSAqICAgICB8IGtleSAgICAgICAgICAgICAgfCB2YWx1ZSAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBiYWNrZ3JvdW5kX2NvbG9yIHwgZGQzMzMzIHwKCSAqICAgICB8IGhlYWRlcl90ZXh0Y29sb3IgfCAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzID0gYXJyYXkoKSwgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoKCQlpZiAoICEgXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdZb3UgbXVzdCBzcGVjaWZ5IGF0IGxlYXN0IG9uZSBtb2Qgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCWlmICggXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgKSB7CgkJCSRhcmdzID0gYXJyYXkoKTsKCQl9CgoJCSRsaXN0ID0gYXJyYXkoKTsKCQkkbW9kcyA9IGdldF90aGVtZV9tb2RzKCk7CgkJaWYgKCAhIGlzX2FycmF5KCAkbW9kcyApICkgewoJCQkvLyBJZiBubyBtb2RzIGFyZSBzZXQgKHBlcmhhcHMgbmV3IHRoZW1lKSwgbWFrZSBzdXJlIGZvcmVhY2ggc3RpbGwgd29ya3MuCgkJCSRtb2RzID0gYXJyYXkoKTsKCQl9CgkJZm9yZWFjaCAoICRtb2RzIGFzICRrID0+ICR2ICkgewoJCQkvLyBJZiBtb2RzIHdlcmUgZ2l2ZW4sIHNraXAgdGhlIG90aGVycy4KCQkJaWYgKCAhIGVtcHR5KCAkYXJncyApICYmICEgaW5fYXJyYXkoICRrLCAkYXJncywgdHJ1ZSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggaXNfYXJyYXkoICR2ICkgKSB7CgkJCQkkbGlzdFtdID0gWwoJCQkJCSdrZXknICAgPT4gJGssCgkJCQkJJ3ZhbHVlJyA9PiAnPT4nLAoJCQkJXTsKCQkJCWZvcmVhY2ggKCAkdiBhcyAkX2sgPT4gJF92ICkgewoJCQkJCSRsaXN0W10gPSBbCgkJCQkJCSdrZXknICAgPT4gIiAgICAkX2siLAoJCQkJCQkndmFsdWUnID0+ICRfdiwKCQkJCQldOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJGxpc3RbXSA9IFsKCQkJCQkna2V5JyAgID0+ICRrLAoJCQkJCSd2YWx1ZScgPT4gJHYsCgkJCQldOwoJCQl9CgkJfQoKCQkvLyBGb3IgdW5zZXQgbW9kcywgc2hvdyBibGFuayB2YWx1ZS4KCQlmb3JlYWNoICggJGFyZ3MgYXMgJG1vZCApIHsKCQkJaWYgKCAhIGlzc2V0KCAkbW9kc1sgJG1vZCBdICkgKSB7CgkJCQkkbGlzdFtdID0gWwoJCQkJCSdrZXknICAgPT4gJG1vZCwKCQkJCQkndmFsdWUnID0+ICcnLAoJCQkJXTsKCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICd0aGVtZW1vZHMnICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGxpc3QgKTsKCgl9CgoJLyoqCgkgKiBHZXRzIGEgbGlzdCBvZiB0aGVtZSBtb2RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBqc29uCgkgKiAgIC0gY3N2CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXRzIGEgbGlzdCBvZiB0aGVtZSBtb2RzLgoJICogICAgICQgd3AgdGhlbWUgbW9kIGxpc3QKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IGtleSAgICAgICAgICAgICAgfCB2YWx1ZSAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IGJhY2tncm91bmRfY29sb3IgfCBkZDMzMzMgIHwKCSAqICAgICB8IGxpbmtfY29sb3IgICAgICAgfCAjZGQ5OTMzIHwKCSAqICAgICB8IG1haW5fdGV4dF9jb2xvciAgfCAjODIyNGUzIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MgPSBhcnJheSgpLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgoJCSRhc3NvY19hcmdzWydhbGwnXSA9IDE7CgoJCSR0aGlzLT5nZXQoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBvbmUgb3IgbW9yZSB0aGVtZSBtb2RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPG1vZD4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIG1vZHMgdG8gcmVtb3ZlLgoJICoKCSAqIFstLWFsbF0KCSAqIDogUmVtb3ZlIGFsbCB0aGVtZSBtb2RzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVtb3ZlIGFsbCB0aGVtZSBtb2RzLgoJICogICAgICQgd3AgdGhlbWUgbW9kIHJlbW92ZSAtLWFsbAoJICogICAgIFN1Y2Nlc3M6IFRoZW1lIG1vZHMgcmVtb3ZlZC4KCSAqCgkgKiAgICAgIyBSZW1vdmUgc2luZ2xlIHRoZW1lIG1vZC4KCSAqICAgICAkIHdwIHRoZW1lIG1vZCByZW1vdmUgYmFja2dyb3VuZF9jb2xvcgoJICogICAgIFN1Y2Nlc3M6IDEgbW9kIHJlbW92ZWQuCgkgKgoJICogICAgICMgUmVtb3ZlIG11bHRpcGxlIHRoZW1lIG1vZHMuCgkgKiAgICAgJCB3cCB0aGVtZSBtb2QgcmVtb3ZlIGJhY2tncm91bmRfY29sb3IgaGVhZGVyX3RleHRjb2xvcgoJICogICAgIFN1Y2Nlc3M6IDIgbW9kcyByZW1vdmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCAkYXJncyA9IGFycmF5KCksICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCgkJaWYgKCAhIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICYmIGVtcHR5KCAkYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnWW91IG11c3Qgc3BlY2lmeSBhdCBsZWFzdCBvbmUgbW9kIG9yIHVzZSAtLWFsbC4nICk7CgkJfQoKCQlpZiAoIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQlyZW1vdmVfdGhlbWVfbW9kcygpOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdUaGVtZSBtb2RzIHJlbW92ZWQuJyApOwoJCQlyZXR1cm47CgkJfQoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJG1vZCApIHsKCQkJcmVtb3ZlX3RoZW1lX21vZCggJG1vZCApOwoJCX0KCgkJJGNvdW50ICAgICAgICAgICA9IGNvdW50KCAkYXJncyApOwoJCSRzdWNjZXNzX21lc3NhZ2UgPSAoIDEgPT09ICRjb3VudCApID8gJyVkIG1vZCByZW1vdmVkLicgOiAnJWQgbW9kcyByZW1vdmVkLic7CgkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAkc3VjY2Vzc19tZXNzYWdlLCAkY291bnQgKSApOwoKCX0KCgkvKioKCSAqIFNldHMgdGhlIHZhbHVlIG9mIGEgdGhlbWUgbW9kLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bW9kPgoJICogOiBUaGUgbmFtZSBvZiB0aGUgdGhlbWUgbW9kIHRvIHNldCBvciB1cGRhdGUuCgkgKgoJICogPHZhbHVlPgoJICogOiBUaGUgbmV3IHZhbHVlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2V0IHRoZW1lIG1vZAoJICogICAgICQgd3AgdGhlbWUgbW9kIHNldCBiYWNrZ3JvdW5kX2NvbG9yIDAwMDAwMAoJICogICAgIFN1Y2Nlc3M6IFRoZW1lIG1vZCBiYWNrZ3JvdW5kX2NvbG9yIHNldCB0byAwMDAwMDAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldCggJGFyZ3MgPSBhcnJheSgpLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJbGlzdCggJG1vZCwgJHZhbHVlICkgPSAkYXJnczsKCgkJc2V0X3RoZW1lX21vZCggJG1vZCwgJHZhbHVlICk7CgoJCWlmICggZ2V0X3RoZW1lX21vZCggJG1vZCApID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlRoZW1lIG1vZCB7JG1vZH0gc2V0IHRvIHskdmFsdWV9LiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDb3VsZCBub3QgdXBkYXRlIHRoZW1lIG1vZCB7JG1vZH0uIiApOwoJCX0KCX0KCn0KPD9waHAKCnVzZSBXUF9DTElcUGFyc2VQbHVnaW5OYW1lSW5wdXQ7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTWFuYWdlcyBwbHVnaW5zLCBpbmNsdWRpbmcgaW5zdGFsbHMsIGFjdGl2YXRpb25zLCBhbmQgdXBkYXRlcy4KICoKICogU2VlIHRoZSBXb3JkUHJlc3MgW1BsdWdpbiBIYW5kYm9va10oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9wbHVnaW5zLykgZGV2ZWxvcGVyIHJlc291cmNlIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHBsdWdpbnMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEFjdGl2YXRlIHBsdWdpbgogKiAgICAgJCB3cCBwbHVnaW4gYWN0aXZhdGUgaGVsbG8KICogICAgIFBsdWdpbiAnaGVsbG8nIGFjdGl2YXRlZC4KICogICAgIFN1Y2Nlc3M6IEFjdGl2YXRlZCAxIG9mIDEgcGx1Z2lucy4KICoKICogICAgICMgRGVhY3RpdmF0ZSBwbHVnaW4KICogICAgICQgd3AgcGx1Z2luIGRlYWN0aXZhdGUgaGVsbG8KICogICAgIFBsdWdpbiAnaGVsbG8nIGRlYWN0aXZhdGVkLgogKiAgICAgU3VjY2VzczogRGVhY3RpdmF0ZWQgMSBvZiAxIHBsdWdpbnMuCiAqCiAqICAgICAjIERlbGV0ZSBwbHVnaW4KICogICAgICQgd3AgcGx1Z2luIGRlbGV0ZSBoZWxsbwogKiAgICAgRGVsZXRlZCAnaGVsbG8nIHBsdWdpbi4KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMSBvZiAxIHBsdWdpbnMuCiAqCiAqICAgICAjIEluc3RhbGwgdGhlIGxhdGVzdCB2ZXJzaW9uIGZyb20gd29yZHByZXNzLm9yZyBhbmQgYWN0aXZhdGUKICogICAgICQgd3AgcGx1Z2luIGluc3RhbGwgYmJwcmVzcyAtLWFjdGl2YXRlCiAqICAgICBJbnN0YWxsaW5nIGJiUHJlc3MgKDIuNS45KQogKiAgICAgRG93bmxvYWRpbmcgaW5zdGFsbCBwYWNrYWdlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4vYmJwcmVzcy4yLjUuOS56aXAuLi4KICogICAgIFVzaW5nIGNhY2hlZCBmaWxlICcvaG9tZS92YWdyYW50Ly53cC1jbGkvY2FjaGUvcGx1Z2luL2JicHJlc3MtMi41LjkuemlwJy4uLgogKiAgICAgVW5wYWNraW5nIHRoZSBwYWNrYWdlLi4uCiAqICAgICBJbnN0YWxsaW5nIHRoZSBwbHVnaW4uLi4KICogICAgIFBsdWdpbiBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgogKiAgICAgQWN0aXZhdGluZyAnYmJwcmVzcycuLi4KICogICAgIFBsdWdpbiAnYmJwcmVzcycgYWN0aXZhdGVkLgogKiAgICAgU3VjY2VzczogSW5zdGFsbGVkIDEgb2YgMSBwbHVnaW5zLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFBsdWdpbl9Db21tYW5kIGV4dGVuZHMgXFdQX0NMSVxDb21tYW5kV2l0aFVwZ3JhZGUgewoKCXVzZSBQYXJzZVBsdWdpbk5hbWVJbnB1dDsKCglwcm90ZWN0ZWQgJGl0ZW1fdHlwZSAgICAgICAgID0gJ3BsdWdpbic7Cglwcm90ZWN0ZWQgJHVwZ3JhZGVfcmVmcmVzaCAgID0gJ3dwX3VwZGF0ZV9wbHVnaW5zJzsKCXByb3RlY3RlZCAkdXBncmFkZV90cmFuc2llbnQgPSAndXBkYXRlX3BsdWdpbnMnOwoKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IGFycmF5KAoJCSduYW1lJywKCQknc3RhdHVzJywKCQkndXBkYXRlJywKCQkndmVyc2lvbicsCgkpOwoKCS8qKgoJICogUGx1Z2luIGZldGNoZXIgaW5zdGFuY2UuCgkgKgoJICogQHZhciBcV1BfQ0xJXEZldGNoZXJzXFBsdWdpbgoJICovCglwcm90ZWN0ZWQgJGZldGNoZXI7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCXJlcXVpcmVfb25jZSBBQlNQQVRIIC4gJ3dwLWFkbWluL2luY2x1ZGVzL3BsdWdpbi5waHAnOwoJCXJlcXVpcmVfb25jZSBBQlNQQVRIIC4gJ3dwLWFkbWluL2luY2x1ZGVzL3BsdWdpbi1pbnN0YWxsLnBocCc7CgoJCXBhcmVudDo6X19jb25zdHJ1Y3QoKTsKCgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgV1BfQ0xJXEZldGNoZXJzXFBsdWdpbigpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXBncmFkZXJfY2xhc3MoICRmb3JjZSApIHsKCQlyZXR1cm4gJGZvcmNlID8gJ1xcV1BfQ0xJXFxEZXN0cnVjdGl2ZVBsdWdpblVwZ3JhZGVyJyA6ICdQbHVnaW5fVXBncmFkZXInOwoJfQoKCS8qKgoJICogUmV2ZWFscyB0aGUgc3RhdHVzIG9mIG9uZSBvciBhbGwgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+XQoJICogOiBBIHBhcnRpY3VsYXIgcGx1Z2luIHRvIHNob3cgdGhlIHN0YXR1cyBmb3IuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEaXNwbGF5cyBzdGF0dXMgb2YgYWxsIHBsdWdpbnMKCSAqICAgICAkIHdwIHBsdWdpbiBzdGF0dXMKCSAqICAgICA1IGluc3RhbGxlZCBwbHVnaW5zOgoJICogICAgICAgSSBha2lzbWV0ICAgICAgICAgICAgICAgIDMuMS4xMQoJICogICAgICAgSSBlYXN5LWRpZ2l0YWwtZG93bmxvYWRzIDIuNS4xNgoJICogICAgICAgQSB0aGVtZS1jaGVjayAgICAgICAgICAgIDIwMTYwNTIzLjEKCSAqICAgICAgIEkgd2VuLWxvZ28tc2xpZGVyICAgICAgICAyLjAuMwoJICogICAgICAgTSBucy1wYWNrICAgICAgICAgICAgICAgIDEuMC4wCgkgKiAgICAgTGVnZW5kOiBJID0gSW5hY3RpdmUsIEEgPSBBY3RpdmUsIE0gPSBNdXN0IFVzZQoJICoKCSAqICAgICAjIERpc3BsYXlzIHN0YXR1cyBvZiBhIHBsdWdpbgoJICogICAgICQgd3AgcGx1Z2luIHN0YXR1cyB0aGVtZS1jaGVjawoJICogICAgIFBsdWdpbiB0aGVtZS1jaGVjayBkZXRhaWxzOgoJICogICAgICAgICBOYW1lOiBUaGVtZSBDaGVjawoJICogICAgICAgICBTdGF0dXM6IEFjdGl2ZQoJICogICAgICAgICBWZXJzaW9uOiAyMDE2MDUyMy4xCgkgKiAgICAgICAgIEF1dGhvcjogT3R0bzQyLCBwcm9zcwoJICogICAgICAgICBEZXNjcmlwdGlvbjogQSBzaW1wbGUgYW5kIGVhc3kgd2F5IHRvIHRlc3QgeW91ciB0aGVtZSBmb3IgYWxsIHRoZSBsYXRlc3QgV29yZFByZXNzIHN0YW5kYXJkcyBhbmQgcHJhY3RpY2VzLiBBIGdyZWF0IHRoZW1lIGRldmVsb3BtZW50IHRvb2whCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdGF0dXMoICRhcmdzICkgewoJCXBhcmVudDo6c3RhdHVzKCAkYXJncyApOwoJfQoKCS8qKgoJICogU2VhcmNoZXMgdGhlIFdvcmRQcmVzcy5vcmcgcGx1Z2luIGRpcmVjdG9yeS4KCSAqCgkgKiBEaXNwbGF5cyBwbHVnaW5zIGluIHRoZSBXb3JkUHJlc3Mub3JnIHBsdWdpbiBkaXJlY3RvcnkgbWF0Y2hpbmcgYSBnaXZlbgoJICogc2VhcmNoIHF1ZXJ5LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2VhcmNoPgoJICogOiBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuCgkgKgoJICogWy0tcGFnZT08cGFnZT5dCgkgKiA6IE9wdGlvbmFsIHBhZ2UgdG8gZGlzcGxheS4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWy0tcGVyLXBhZ2U9PHBlci1wYWdlPl0KCSAqIDogT3B0aW9uYWwgbnVtYmVyIG9mIHJlc3VsdHMgdG8gZGlzcGxheS4KCSAqIC0tLQoJICogZGVmYXVsdDogMTAKCSAqIC0tLQoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggcGx1Z2luLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogQXNrIGZvciBzcGVjaWZpYyBmaWVsZHMgZnJvbSB0aGUgQVBJLiBEZWZhdWx0cyB0byBuYW1lLHNsdWcsYXV0aG9yX3Byb2ZpbGUscmF0aW5nLiBBY2NlcHRhYmxlIHZhbHVlczoKCSAqCgkgKiAgICAgKipuYW1lKio6IFBsdWdpbiBOYW1lCgkgKiAgICAgKipzbHVnKio6IFBsdWdpbiBTbHVnCgkgKiAgICAgKip2ZXJzaW9uKio6IEN1cnJlbnQgVmVyc2lvbiBOdW1iZXIKCSAqICAgICAqKmF1dGhvcioqOiBQbHVnaW4gQXV0aG9yCgkgKiAgICAgKiphdXRob3JfcHJvZmlsZSoqOiBQbHVnaW4gQXV0aG9yIFByb2ZpbGUKCSAqICAgICAqKmNvbnRyaWJ1dG9ycyoqOiBQbHVnaW4gQ29udHJpYnV0b3JzCgkgKiAgICAgKipyZXF1aXJlcyoqOiBQbHVnaW4gTWluaW11bSBSZXF1aXJlbWVudHMKCSAqICAgICAqKnRlc3RlZCoqOiBQbHVnaW4gVGVzdGVkIFVwIFRvCgkgKiAgICAgKipjb21wYXRpYmlsaXR5Kio6IFBsdWdpbiBDb21wYXRpYmxlIFdpdGgKCSAqICAgICAqKnJhdGluZyoqOiBQbHVnaW4gUmF0aW5nIGluIFBlcmNlbnQgYW5kIFRvdGFsIE51bWJlcgoJICogICAgICoqcmF0aW5ncyoqOiBQbHVnaW4gUmF0aW5ncyBmb3IgZWFjaCBzdGFyICgxLTUpCgkgKiAgICAgKipudW1fcmF0aW5ncyoqOiBOdW1iZXIgb2YgUGx1Z2luIFJhdGluZ3MKCSAqICAgICAqKmhvbWVwYWdlKio6IFBsdWdpbiBBdXRob3IncyBIb21lcGFnZQoJICogICAgICoqZGVzY3JpcHRpb24qKjogUGx1Z2luJ3MgRGVzY3JpcHRpb24KCSAqICAgICAqKnNob3J0X2Rlc2NyaXB0aW9uKio6IFBsdWdpbidzIFNob3J0IERlc2NyaXB0aW9uCgkgKiAgICAgKipzZWN0aW9ucyoqOiBQbHVnaW4gUmVhZG1lIFNlY3Rpb25zOiBkZXNjcmlwdGlvbiwgaW5zdGFsbGF0aW9uLCBGQVEsIHNjcmVlbnNob3RzLCBvdGhlciBub3RlcywgYW5kIGNoYW5nZWxvZwoJICogICAgICoqZG93bmxvYWRlZCoqOiBQbHVnaW4gRG93bmxvYWQgQ291bnQKCSAqICAgICAqKmxhc3RfdXBkYXRlZCoqOiBQbHVnaW4ncyBMYXN0IFVwZGF0ZQoJICogICAgICoqYWRkZWQqKjogUGx1Z2luJ3MgRGF0ZSBBZGRlZCB0byB3b3JkcHJlc3Mub3JnIFJlcG9zaXRvcnkKCSAqICAgICAqKnRhZ3MqKjogUGx1Z2luJ3MgVGFncwoJICogICAgICoqdmVyc2lvbnMqKjogUGx1Z2luJ3MgQXZhaWxhYmxlIFZlcnNpb25zIHdpdGggRC9MIExpbmsKCSAqICAgICAqKmRvbmF0ZV9saW5rKio6IFBsdWdpbidzIERvbmF0aW9uIExpbmsKCSAqICAgICAqKmJhbm5lcnMqKjogUGx1Z2luJ3MgQmFubmVyIEltYWdlIExpbmsKCSAqICAgICAqKmljb25zKio6IFBsdWdpbidzIEljb24gSW1hZ2UgTGluawoJICogICAgICoqYWN0aXZlX2luc3RhbGxzKio6IFBsdWdpbidzIE51bWJlciBvZiBBY3RpdmUgSW5zdGFsbHMKCSAqICAgICAqKmNvbnRyaWJ1dG9ycyoqOiBQbHVnaW4ncyBMaXN0IG9mIENvbnRyaWJ1dG9ycwoJICogICAgICoqdXJsKio6IFBsdWdpbidzIFVSTCBvbiB3b3JkcHJlc3Mub3JnCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0gY291bnQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwbHVnaW4gc2VhcmNoIGRzZ253cmtzIC0tcGVyLXBhZ2U9MjAgLS1mb3JtYXQ9anNvbgoJICogICAgIFN1Y2Nlc3M6IFNob3dpbmcgMyBvZiAzIHBsdWdpbnMuCgkgKiAgICAgW3sibmFtZSI6IkRzZ25XcmtzIEluc3RhZ3JhbSBJbXBvcnRlciBEZWJ1ZyIsInNsdWciOiJkc2dud3Jrcy1pbnN0YWdyYW0taW1wb3J0ZXItZGVidWciLCJyYXRpbmciOjB9LHsibmFtZSI6IkRzZ25XcmtzIEluc3RhZ3JhbSBJbXBvcnRlciIsInNsdWciOiJkc2dud3Jrcy1pbnN0YWdyYW0taW1wb3J0ZXIiLCJyYXRpbmciOjg0fSx7Im5hbWUiOiJEc2duV3JrcyBUd2l0dGVyIEltcG9ydGVyIiwic2x1ZyI6ImRzZ253cmtzLXR3aXR0ZXItaW1wb3J0ZXIiLCJyYXRpbmciOjgwfV0KCSAqCgkgKiAgICAgJCB3cCBwbHVnaW4gc2VhcmNoIGRzZ253cmtzIC0tZmllbGRzPW5hbWUsdmVyc2lvbixzbHVnLHJhdGluZyxudW1fcmF0aW5ncwoJICogICAgIFN1Y2Nlc3M6IFNob3dpbmcgMyBvZiAzIHBsdWdpbnMuCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgdmVyc2lvbiB8IHNsdWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHJhdGluZyB8IG51bV9yYXRpbmdzIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBEc2duV3JrcyBJbnN0YWdyYW0gSW1wb3J0ZXIgRGVidWcgfCAwLjEuNiAgIHwgZHNnbndya3MtaW5zdGFncmFtLWltcG9ydGVyLWRlYnVnIHwgMCAgICAgIHwgMCAgICAgICAgICAgfAoJICogICAgIHwgRHNnbldya3MgSW5zdGFncmFtIEltcG9ydGVyICAgICAgIHwgMS4zLjcgICB8IGRzZ253cmtzLWluc3RhZ3JhbS1pbXBvcnRlciAgICAgICB8IDg0ICAgICB8IDIzICAgICAgICAgIHwKCSAqICAgICB8IERzZ25XcmtzIFR3aXR0ZXIgSW1wb3J0ZXIgICAgICAgICB8IDEuMS4xICAgfCBkc2dud3Jrcy10d2l0dGVyLWltcG9ydGVyICAgICAgICAgfCA4MCAgICAgfCAxICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICovCglwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJcGFyZW50Ojpfc2VhcmNoKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gc3RhdHVzX3NpbmdsZSggJGFyZ3MgKSB7CgkJJHBsdWdpbiA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgkJJGZpbGUgICA9ICRwbHVnaW4tPmZpbGU7CgoJCSRkZXRhaWxzID0gJHRoaXMtPmdldF9kZXRhaWxzKCAkZmlsZSApOwoKCQkkc3RhdHVzID0gJHRoaXMtPmZvcm1hdF9zdGF0dXMoICR0aGlzLT5nZXRfc3RhdHVzKCAkZmlsZSApLCAnbG9uZycgKTsKCgkJJHZlcnNpb24gPSAkZGV0YWlsc1snVmVyc2lvbiddOwoKCQlpZiAoICR0aGlzLT5oYXNfdXBkYXRlKCAkZmlsZSApICkgewoJCQkkdmVyc2lvbiAuPSAnICglZ1VwZGF0ZSBhdmFpbGFibGUlbiknOwoJCX0KCgkJZWNobyBXUF9DTEk6OmNvbG9yaXplKAoJCQlVdGlsc1xtdXN0YWNoZV9yZW5kZXIoCgkJCQlzZWxmOjpnZXRfdGVtcGxhdGVfcGF0aCggJ3BsdWdpbi1zdGF0dXMubXVzdGFjaGUnICksCgkJCQlbCgkJCQkJJ3NsdWcnICAgICAgICA9PiBVdGlsc1xnZXRfcGx1Z2luX25hbWUoICRmaWxlICksCgkJCQkJJ3N0YXR1cycgICAgICA9PiAkc3RhdHVzLAoJCQkJCSd2ZXJzaW9uJyAgICAgPT4gJHZlcnNpb24sCgkJCQkJJ25hbWUnICAgICAgICA9PiAkZGV0YWlsc1snTmFtZSddLAoJCQkJCSdhdXRob3InICAgICAgPT4gJGRldGFpbHNbJ0F1dGhvciddLAoJCQkJCSdkZXNjcmlwdGlvbicgPT4gJGRldGFpbHNbJ0Rlc2NyaXB0aW9uJ10sCgkJCQldCgkJCSkKCQkpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfYWxsX2l0ZW1zKCkgewoJCSRpdGVtcyA9ICR0aGlzLT5nZXRfaXRlbV9saXN0KCk7CgoJCWZvcmVhY2ggKCBnZXRfbXVfcGx1Z2lucygpIGFzICRmaWxlID0+ICRtdV9wbHVnaW4gKSB7CgkJCSRtdV92ZXJzaW9uID0gJyc7CgkJCWlmICggISBlbXB0eSggJG11X3BsdWdpblsnVmVyc2lvbiddICkgKSB7CgkJCQkkbXVfdmVyc2lvbiA9ICRtdV9wbHVnaW5bJ1ZlcnNpb24nXTsKCQkJfQoKCQkJJGl0ZW1zWyAkZmlsZSBdID0gYXJyYXkoCgkJCQknbmFtZScgICAgICAgICAgID0+IFV0aWxzXGdldF9wbHVnaW5fbmFtZSggJGZpbGUgKSwKCQkJCSdzdGF0dXMnICAgICAgICAgPT4gJ211c3QtdXNlJywKCQkJCSd1cGRhdGUnICAgICAgICAgPT4gZmFsc2UsCgkJCQkndXBkYXRlX3ZlcnNpb24nID0+IG51bGwsCgkJCQkndXBkYXRlX3BhY2thZ2UnID0+IG51bGwsCgkJCQkndmVyc2lvbicgICAgICAgID0+ICRtdV92ZXJzaW9uLAoJCQkJJ3VwZGF0ZV9pZCcgICAgICA9PiAnJywKCQkJCSd0aXRsZScgICAgICAgICAgPT4gJycsCgkJCQknZGVzY3JpcHRpb24nICAgID0+ICcnLAoJCQkJJ2ZpbGUnICAgICAgICAgICA9PiAkZmlsZSwKCQkJKTsKCQl9CgoJCSRyYXdfaXRlbXMgPSBnZXRfZHJvcGlucygpOwoJCSRyYXdfZGF0YSAgPSBfZ2V0X2Ryb3BpbnMoKTsKCQlmb3JlYWNoICggJHJhd19pdGVtcyBhcyAkbmFtZSA9PiAkaXRlbV9kYXRhICkgewoJCQkkZGVzY3JpcHRpb24gICAgPSAhIGVtcHR5KCAkcmF3X2RhdGFbICRuYW1lIF1bMF0gKSA/ICRyYXdfZGF0YVsgJG5hbWUgXVswXSA6ICcnOwoJCQkkaXRlbXNbICRuYW1lIF0gPSBbCgkJCQknbmFtZScgICAgICAgICAgID0+ICRuYW1lLAoJCQkJJ3RpdGxlJyAgICAgICAgICA9PiAkaXRlbV9kYXRhWydUaXRsZSddLAoJCQkJJ2Rlc2NyaXB0aW9uJyAgICA9PiAkZGVzY3JpcHRpb24sCgkJCQknc3RhdHVzJyAgICAgICAgID0+ICdkcm9waW4nLAoJCQkJJ3VwZGF0ZScgICAgICAgICA9PiBmYWxzZSwKCQkJCSd1cGRhdGVfdmVyc2lvbicgPT4gbnVsbCwKCQkJCSd1cGRhdGVfcGFja2FnZScgPT4gbnVsbCwKCQkJCSd1cGRhdGVfaWQnICAgICAgPT4gJycsCgkJCQknZmlsZScgICAgICAgICAgID0+ICRuYW1lLAoJCQldOwoJCX0KCgkJcmV0dXJuICRpdGVtczsKCX0KCgkvKioKCSAqIEFjdGl2YXRlcyBvbmUgb3IgbW9yZSBwbHVnaW5zLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gYWN0aXZhdGUuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBwbHVnaW5zIHdpbGwgYmUgYWN0aXZhdGVkLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IElmIHNldCwgdGhlIHBsdWdpbiB3aWxsIGJlIGFjdGl2YXRlZCBmb3IgdGhlIGVudGlyZSBtdWx0aXNpdGUgbmV0d29yay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFjdGl2YXRlIHBsdWdpbgoJICogICAgICQgd3AgcGx1Z2luIGFjdGl2YXRlIGhlbGxvCgkgKiAgICAgUGx1Z2luICdoZWxsbycgYWN0aXZhdGVkLgoJICogICAgIFN1Y2Nlc3M6IEFjdGl2YXRlZCAxIG9mIDEgcGx1Z2lucy4KCSAqCgkgKiAgICAgIyBBY3RpdmF0ZSBwbHVnaW4gaW4gZW50aXJlIG11bHRpc2l0ZSBuZXR3b3JrCgkgKiAgICAgJCB3cCBwbHVnaW4gYWN0aXZhdGUgaGVsbG8gLS1uZXR3b3JrCgkgKiAgICAgUGx1Z2luICdoZWxsbycgbmV0d29yayBhY3RpdmF0ZWQuCgkgKiAgICAgU3VjY2VzczogTmV0d29yayBhY3RpdmF0ZWQgMSBvZiAxIHBsdWdpbnMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhY3RpdmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkbmV0d29ya193aWRlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKTsKCQkkYWxsICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJJHBsdWdpbnMgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQlpZiAoIGNvdW50KCAkcGx1Z2lucyApIDwgY291bnQoICRhcmdzICkgKSB7CgkJCSRlcnJvcnMgPSBjb3VudCggJGFyZ3MgKSAtIGNvdW50KCAkcGx1Z2lucyApOwoJCX0KCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJHN0YXR1cyA9ICR0aGlzLT5nZXRfc3RhdHVzKCAkcGx1Z2luLT5maWxlICk7CgkJCWlmICggJGFsbCAmJiBpbl9hcnJheSggJHN0YXR1cywgWyAnYWN0aXZlJywgJ2FjdGl2ZS1uZXR3b3JrJyBdLCB0cnVlICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkvLyBOZXR3b3JrLWFjdGl2ZSBpcyB0aGUgaGlnaGVzdCBsZXZlbCBvZiBhY3RpdmF0aW9uIHN0YXR1cy4KCQkJaWYgKCAnYWN0aXZlLW5ldHdvcmsnID09PSAkc3RhdHVzICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiUGx1Z2luICd7JHBsdWdpbi0+bmFtZX0nIGlzIGFscmVhZHkgbmV0d29yayBhY3RpdmUuIiApOwoJCQkJY29udGludWU7CgkJCX0KCQkJLy8gRG9uJ3QgcmVhY3RpdmF0ZSBhY3RpdmUgcGx1Z2lucywgYnV0IGRvIGxldCB0aGVtIGJlY29tZSBuZXR3b3JrLWFjdGl2ZS4KCQkJaWYgKCAhICRuZXR3b3JrX3dpZGUgJiYgJ2FjdGl2ZScgPT09ICRzdGF0dXMgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJQbHVnaW4gJ3skcGx1Z2luLT5uYW1lfScgaXMgYWxyZWFkeSBhY3RpdmUuIiApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCS8vIFBsdWdpbnMgbmVlZCB0byBiZSBkZWFjdGl2YXRlZCBiZWZvcmUgYmVpbmcgbmV0d29yayBhY3RpdmF0ZWQuCgkJCWlmICggJG5ldHdvcmtfd2lkZSAmJiAnYWN0aXZlJyA9PT0gJHN0YXR1cyApIHsKCQkJCWRlYWN0aXZhdGVfcGx1Z2lucyggJHBsdWdpbi0+ZmlsZSwgZmFsc2UsIGZhbHNlICk7CgkJCX0KCgkJCSRyZXN1bHQgPSBhY3RpdmF0ZV9wbHVnaW4oICRwbHVnaW4tPmZpbGUsICcnLCAkbmV0d29ya193aWRlICk7CgoJCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCQkkbWVzc2FnZSA9ICRyZXN1bHQtPmdldF9lcnJvcl9tZXNzYWdlKCk7CgkJCQkkbWVzc2FnZSA9IHByZWdfcmVwbGFjZSggJy88YVxzW14+XSs+Lio8XC9hPi9pbScsICcnLCAkbWVzc2FnZSApOwoJCQkJJG1lc3NhZ2UgPSB3cF9zdHJpcF9hbGxfdGFncyggJG1lc3NhZ2UgKTsKCQkJCSRtZXNzYWdlID0gc3RyX3JlcGxhY2UoICdFcnJvcjogJywgJycsICRtZXNzYWdlICk7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJGYWlsZWQgdG8gYWN0aXZhdGUgcGx1Z2luLiB7JG1lc3NhZ2V9IiApOwoJCQl9IGVsc2UgewoJCQkJJHRoaXMtPmFjdGl2ZV9vdXRwdXQoICRwbHVnaW4tPm5hbWUsICRwbHVnaW4tPmZpbGUsICRuZXR3b3JrX3dpZGUsICdhY3RpdmF0ZScgKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAhICR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgKSB7CgkJCSR2ZXJiID0gJG5ldHdvcmtfd2lkZSA/ICduZXR3b3JrIGFjdGl2YXRlJyA6ICdhY3RpdmF0ZSc7CgkJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ3BsdWdpbicsICR2ZXJiLCBjb3VudCggJGFyZ3MgKSwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJCX0KCgl9CgoJLyoqCgkgKiBEZWFjdGl2YXRlcyBvbmUgb3IgbW9yZSBwbHVnaW5zLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gZGVhY3RpdmF0ZS4KCSAqCgkgKiBbLS11bmluc3RhbGxdCgkgKiA6IFVuaW5zdGFsbCB0aGUgcGx1Z2luIGFmdGVyIGRlYWN0aXZhdGlvbi4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgYWxsIHBsdWdpbnMgd2lsbCBiZSBkZWFjdGl2YXRlZC4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gd2lsbCBiZSBkZWFjdGl2YXRlZCBmb3IgdGhlIGVudGlyZSBtdWx0aXNpdGUgbmV0d29yay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlYWN0aXZhdGUgcGx1Z2luCgkgKiAgICAgJCB3cCBwbHVnaW4gZGVhY3RpdmF0ZSBoZWxsbwoJICogICAgIFBsdWdpbiAnaGVsbG8nIGRlYWN0aXZhdGVkLgoJICogICAgIFN1Y2Nlc3M6IERlYWN0aXZhdGVkIDEgb2YgMSBwbHVnaW5zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkbmV0d29ya193aWRlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKTsKCQkkZGlzYWJsZV9hbGwgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApOwoKCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkZGlzYWJsZV9hbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSRwbHVnaW5zICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJaWYgKCBjb3VudCggJHBsdWdpbnMgKSA8IGNvdW50KCAkYXJncyApICkgewoJCQkkZXJyb3JzID0gY291bnQoICRhcmdzICkgLSBjb3VudCggJHBsdWdpbnMgKTsKCQl9CgoJCWZvcmVhY2ggKCAkcGx1Z2lucyBhcyAkcGx1Z2luICkgewoKCQkJJHN0YXR1cyA9ICR0aGlzLT5nZXRfc3RhdHVzKCAkcGx1Z2luLT5maWxlICk7CgkJCWlmICggJGRpc2FibGVfYWxsICYmICEgaW5fYXJyYXkoICRzdGF0dXMsIFsgJ2FjdGl2ZScsICdhY3RpdmUtbmV0d29yaycgXSwgdHJ1ZSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCS8vIE5ldHdvcmsgYWN0aXZlIHBsdWdpbnMgbXVzdCBiZSBleHBsaWNpdGx5IGRlYWN0aXZhdGVkLgoJCQlpZiAoICEgJG5ldHdvcmtfd2lkZSAmJiAnYWN0aXZlLW5ldHdvcmsnID09PSAkc3RhdHVzICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiUGx1Z2luICd7JHBsdWdpbi0+bmFtZX0nIGlzIG5ldHdvcmsgYWN0aXZlIGFuZCBtdXN0IGJlIGRlYWN0aXZhdGVkIHdpdGggLS1uZXR3b3JrIGZsYWcuIiApOwoJCQkJJGVycm9ycysrOwoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggISBpbl9hcnJheSggJHN0YXR1cywgWyAnYWN0aXZlJywgJ2FjdGl2ZS1uZXR3b3JrJyBdLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJQbHVnaW4gJ3skcGx1Z2luLT5uYW1lfScgaXNuJ3QgYWN0aXZlLiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlkZWFjdGl2YXRlX3BsdWdpbnMoICRwbHVnaW4tPmZpbGUsIGZhbHNlLCAkbmV0d29ya193aWRlICk7CgoJCQlpZiAoICEgaXNfbmV0d29ya19hZG1pbigpICkgewoJCQkJdXBkYXRlX29wdGlvbigKCQkJCQkncmVjZW50bHlfYWN0aXZhdGVkJywKCQkJCQlhcnJheSggJHBsdWdpbi0+ZmlsZSA9PiB0aW1lKCkgKSArIChhcnJheSkgZ2V0X29wdGlvbiggJ3JlY2VudGx5X2FjdGl2YXRlZCcgKQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCXVwZGF0ZV9zaXRlX29wdGlvbigKCQkJCQkncmVjZW50bHlfYWN0aXZhdGVkJywKCQkJCQlhcnJheSggJHBsdWdpbi0+ZmlsZSA9PiB0aW1lKCkgKSArIChhcnJheSkgZ2V0X3NpdGVfb3B0aW9uKCAncmVjZW50bHlfYWN0aXZhdGVkJyApCgkJCQkpOwoJCQl9CgoJCQkkdGhpcy0+YWN0aXZlX291dHB1dCggJHBsdWdpbi0+bmFtZSwgJHBsdWdpbi0+ZmlsZSwgJG5ldHdvcmtfd2lkZSwgJ2RlYWN0aXZhdGUnICk7CgkJCSRzdWNjZXNzZXMrKzsKCgkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndW5pbnN0YWxsJyApICkgewoJCQkJV1BfQ0xJOjpsb2coICJVbmluc3RhbGxpbmcgJ3skcGx1Z2luLT5uYW1lfScuLi4iICk7CgkJCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gdHJ1ZTsKCQkJCSR0aGlzLT51bmluc3RhbGwoIGFycmF5KCAkcGx1Z2luLT5uYW1lICkgKTsKCQkJCSR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgPSBmYWxzZTsKCQkJfQoJCX0KCgkJaWYgKCAhICR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgKSB7CgkJCSR2ZXJiID0gJG5ldHdvcmtfd2lkZSA/ICduZXR3b3JrIGRlYWN0aXZhdGUnIDogJ2RlYWN0aXZhdGUnOwoJCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdwbHVnaW4nLCAkdmVyYiwgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCQl9CgoJfQoKCS8qKgoJICogVG9nZ2xlcyBhIHBsdWdpbidzIGFjdGl2YXRpb24gc3RhdGUuCgkgKgoJICogSWYgdGhlIHBsdWdpbiBpcyBhY3RpdmUsIHRoZW4gaXQgd2lsbCBiZSBkZWFjdGl2YXRlZC4gSWYgdGhlIHBsdWdpbiBpcwoJICogaW5hY3RpdmUsIHRoZW4gaXQgd2lsbCBiZSBhY3RpdmF0ZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwbHVnaW4+Li4uCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gdG9nZ2xlLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IElmIHNldCwgdGhlIHBsdWdpbiB3aWxsIGJlIHRvZ2dsZWQgZm9yIHRoZSBlbnRpcmUgbXVsdGlzaXRlIG5ldHdvcmsuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBBa2lzbWV0IGlzIGN1cnJlbnRseSBhY3RpdmF0ZWQKCSAqICAgICAkIHdwIHBsdWdpbiB0b2dnbGUgYWtpc21ldAoJICogICAgIFBsdWdpbiAnYWtpc21ldCcgZGVhY3RpdmF0ZWQuCgkgKiAgICAgU3VjY2VzczogVG9nZ2xlZCAxIG9mIDEgcGx1Z2lucy4KCSAqCgkgKiAgICAgIyBBa2lzbWV0IGlzIGN1cnJlbnRseSBkZWFjdGl2YXRlZAoJICogICAgICQgd3AgcGx1Z2luIHRvZ2dsZSBha2lzbWV0CgkgKiAgICAgUGx1Z2luICdha2lzbWV0JyBhY3RpdmF0ZWQuCgkgKiAgICAgU3VjY2VzczogVG9nZ2xlZCAxIG9mIDEgcGx1Z2lucy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRvZ2dsZSggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkbmV0d29ya193aWRlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKTsKCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJJHBsdWdpbnMgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQlpZiAoIGNvdW50KCAkcGx1Z2lucyApIDwgY291bnQoICRhcmdzICkgKSB7CgkJCSRlcnJvcnMgPSBjb3VudCggJGFyZ3MgKSAtIGNvdW50KCAkcGx1Z2lucyApOwoJCX0KCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gdHJ1ZTsKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJaWYgKCAkdGhpcy0+Y2hlY2tfYWN0aXZlKCAkcGx1Z2luLT5maWxlLCAkbmV0d29ya193aWRlICkgKSB7CgkJCQkkdGhpcy0+ZGVhY3RpdmF0ZSggYXJyYXkoICRwbHVnaW4tPm5hbWUgKSwgJGFzc29jX2FyZ3MgKTsKCQkJfSBlbHNlIHsKCQkJCSR0aGlzLT5hY3RpdmF0ZSggYXJyYXkoICRwbHVnaW4tPm5hbWUgKSwgJGFzc29jX2FyZ3MgKTsKCQkJfQoJCQkkc3VjY2Vzc2VzKys7CgkJfQoJCSR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgPSBmYWxzZTsKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdwbHVnaW4nLCAndG9nZ2xlJywgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIHBhdGggdG8gYSBwbHVnaW4gb3IgdG8gdGhlIHBsdWdpbiBkaXJlY3RvcnkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPl0KCSAqIDogVGhlIHBsdWdpbiB0byBnZXQgdGhlIHBhdGggdG8uIElmIG5vdCBzZXQsIHdpbGwgcmV0dXJuIHRoZSBwYXRoIHRvIHRoZQoJICogcGx1Z2lucyBkaXJlY3RvcnkuCgkgKgoJICogWy0tZGlyXQoJICogOiBJZiBzZXQsIGdldCB0aGUgcGF0aCB0byB0aGUgY2xvc2VzdCBwYXJlbnQgZGlyZWN0b3J5LCBpbnN0ZWFkIG9mIHRoZQoJICogcGx1Z2luIGZpbGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCBjZCAkKHdwIHBsdWdpbiBwYXRoKSAmJiBwd2QKCSAqICAgICAvdmFyL3d3dy93b3JkcHJlc3Mvd3AtY29udGVudC9wbHVnaW5zCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwYXRoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBhdGggPSB1bnRyYWlsaW5nc2xhc2hpdCggV1BfUExVR0lOX0RJUiApOwoKCQlpZiAoICEgZW1wdHkoICRhcmdzICkgKSB7CgkJCSRwbHVnaW4gPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCQkkcGF0aCAgLj0gJy8nIC4gJHBsdWdpbi0+ZmlsZTsKCgkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGlyJyApICkgewoJCQkJJHBhdGggPSBkaXJuYW1lKCAkcGF0aCApOwoJCQl9CgkJfQoKCQlXUF9DTEk6OmxpbmUoICRwYXRoICk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGluc3RhbGxfZnJvbV9yZXBvKCAkc2x1ZywgJGFzc29jX2FyZ3MgKSB7CgkJJGFwaSA9IHBsdWdpbnNfYXBpKCAncGx1Z2luX2luZm9ybWF0aW9uJywgYXJyYXkoICdzbHVnJyA9PiAkc2x1ZyApICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRhcGkgKSApIHsKCQkJcmV0dXJuICRhcGk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndmVyc2lvbiddICkgKSB7CgkJCXNlbGY6OmFsdGVyX2FwaV9yZXNwb25zZSggJGFwaSwgJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApOwoJCX0KCgkJJHN0YXR1cyA9IGluc3RhbGxfcGx1Z2luX2luc3RhbGxfc3RhdHVzKCAkYXBpICk7CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKSAmJiAnaW5zdGFsbCcgIT09ICRzdGF0dXNbJ3N0YXR1cyddICkgewoJCQkvLyBXZSBrbm93IHRoaXMgd2lsbCBmYWlsLCBzbyBhdm9pZCBhIG5lZWRsZXNzIGRvd25sb2FkIG9mIHRoZSBwYWNrYWdlLgoJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnYWxyZWFkeV9pbnN0YWxsZWQnLCAnUGx1Z2luIGFscmVhZHkgaW5zdGFsbGVkLicgKTsKCQl9CgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnSW5zdGFsbGluZyAlcyAoJXMpJywgaHRtbF9lbnRpdHlfZGVjb2RlKCAkYXBpLT5uYW1lLCBFTlRfUVVPVEVTICksICRhcGktPnZlcnNpb24gKSApOwoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndmVyc2lvbicgKSAhPT0gJ2RldicgKSB7CgkJCVdQX0NMSTo6Z2V0X2h0dHBfY2FjaGVfbWFuYWdlcigpLT53aGl0ZWxpc3RfcGFja2FnZSggJGFwaS0+ZG93bmxvYWRfbGluaywgJHRoaXMtPml0ZW1fdHlwZSwgJGFwaS0+c2x1ZywgJGFwaS0+dmVyc2lvbiApOwoJCX0KCgkJLy8gSWdub3JlIGZhaWx1cmVzIG9uIGFjY2Vzc2luZyBTU0wgImh0dHBzOi8vYXBpLndvcmRwcmVzcy5vcmcvcGx1Z2lucy91cGRhdGUtY2hlY2svMS4xLyIgaW4gYHdwX3VwZGF0ZV9wbHVnaW5zKClgIHdoaWNoIHNlZW0gdG8gb2NjdXIgaW50ZXJtaXR0ZW50bHkuCgkJc2V0X2Vycm9yX2hhbmRsZXIoIGFycmF5KCBfX0NMQVNTX18sICdlcnJvcl9oYW5kbGVyJyApLCBFX1VTRVJfV0FSTklORyB8IEVfVVNFUl9OT1RJQ0UgKTsKCgkJJHJlc3VsdCA9ICR0aGlzLT5nZXRfdXBncmFkZXIoICRhc3NvY19hcmdzICktPmluc3RhbGwoICRhcGktPmRvd25sb2FkX2xpbmsgKTsKCgkJcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgoJCXJldHVybiAkcmVzdWx0OwoJfQoKCS8qKgoJICogVXBkYXRlcyBvbmUgb3IgbW9yZSBwbHVnaW5zLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gdXBkYXRlLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgcGx1Z2lucyB0aGF0IGhhdmUgdXBkYXRlcyB3aWxsIGJlIHVwZGF0ZWQuCgkgKgoJICogWy0tZXhjbHVkZT08bmFtZT5dCgkgKiA6IENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIHBsdWdpbiBuYW1lcyB0aGF0IHNob3VsZCBiZSBleGNsdWRlZCBmcm9tIHVwZGF0aW5nLgoJICoKCSAqIFstLW1pbm9yXQoJICogOiBPbmx5IHBlcmZvcm0gdXBkYXRlcyBmb3IgbWlub3IgcmVsZWFzZXMgKGUuZy4gZnJvbSAxLjMgdG8gMS40IGluc3RlYWQgb2YgMi4wKQoJICoKCSAqIFstLXBhdGNoXQoJICogOiBPbmx5IHBlcmZvcm0gdXBkYXRlcyBmb3IgcGF0Y2ggcmVsZWFzZXMgKGUuZy4gZnJvbSAxLjMgdG8gMS4zLjMgaW5zdGVhZCBvZiAxLjQpCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHN1bW1hcnkKCSAqIC0tLQoJICoKCSAqIFstLXZlcnNpb249PHZlcnNpb24+XQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gd2lsbCBiZSB1cGRhdGVkIHRvIHRoZSBzcGVjaWZpZWQgdmVyc2lvbi4KCSAqCgkgKiBbLS1kcnktcnVuXQoJICogOiBQcmV2aWV3IHdoaWNoIHBsdWdpbnMgd291bGQgYmUgdXBkYXRlZC4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWRzIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBsdWdpbiB1cGRhdGUgYmJwcmVzcyAtLXZlcnNpb249ZGV2CgkgKiAgICAgSW5zdGFsbGluZyBiYlByZXNzIChEZXZlbG9wbWVudCBWZXJzaW9uKQoJICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvcGx1Z2luL2JicHJlc3MuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSBwYWNrYWdlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgcGx1Z2luLi4uCgkgKiAgICAgUmVtb3ZpbmcgdGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAxIG9mIDIgcGx1Z2lucy4KCSAqCgkgKiAgICAgJCB3cCBwbHVnaW4gdXBkYXRlIC0tYWxsCgkgKiAgICAgRW5hYmxpbmcgTWFpbnRlbmFuY2UgbW9kZS4uLgoJICogICAgIERvd25sb2FkaW5nIHVwZGF0ZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvcGx1Z2luL2FraXNtZXQuMy4xLjExLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgbGF0ZXN0IHZlcnNpb24uLi4KCSAqICAgICBSZW1vdmluZyB0aGUgb2xkIHZlcnNpb24gb2YgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3BsdWdpbi9uZ2lueC1jaGFtcHVydS4zLjIuMC56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIGxhdGVzdCB2ZXJzaW9uLi4uCgkgKiAgICAgUmVtb3ZpbmcgdGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgRGlzYWJsaW5nIE1haW50ZW5hbmNlIG1vZGUuLi4KCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgICAgICAgICAgIHwgb2xkX3ZlcnNpb24gfCBuZXdfdmVyc2lvbiB8IHN0YXR1cyAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IGFraXNtZXQgICAgICAgICAgICAgICAgfCAzLjEuMyAgICAgICB8IDMuMS4xMSAgICAgIHwgVXBkYXRlZCB8CgkgKiAgICAgfCBuZ2lueC1jYWNoZS1jb250cm9sbGVyIHwgMy4xLjEgICAgICAgfCAzLjIuMCAgICAgICB8IFVwZGF0ZWQgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIDIgb2YgMiBwbHVnaW5zLgoJICoKCSAqICAgICAkIHdwIHBsdWdpbiB1cGRhdGUgLS1hbGwgLS1leGNsdWRlPWFraXNtZXQKCSAqICAgICBFbmFibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4vbmdpbngtY2hhbXB1cnUuMy4yLjAuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFJlbW92aW5nIHRoZSBvbGQgdmVyc2lvbiBvZiB0aGUgcGx1Z2luLi4uCgkgKiAgICAgUGx1Z2luIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIERpc2FibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICAgICAgICAgICAgICAgICB8IG9sZF92ZXJzaW9uIHwgbmV3X3ZlcnNpb24gfCBzdGF0dXMgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuZ2lueC1jYWNoZS1jb250cm9sbGVyIHwgMy4xLjEgICAgICAgfCAzLjIuMCAgICAgICB8IFVwZGF0ZWQgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqCgkgKiBAYWxpYXMgdXBncmFkZQoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSApIHsKCQkJZm9yZWFjaCAoICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKSBhcyAkcGx1Z2luICkgewoJCQkJJGFzc29jX2FyZ3NbJ2ZvcmNlJ10gPSAxOwoJCQkJJHRoaXMtPmluc3RhbGwoIGFycmF5KCAkcGx1Z2luLT5uYW1lICksICRhc3NvY19hcmdzICk7CgkJCX0KCQl9IGVsc2UgewoJCQlwYXJlbnQ6OnVwZGF0ZV9tYW55KCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9pdGVtX2xpc3QoKSB7CgkJJGl0ZW1zICAgICAgICAgICA9IFtdOwoJCSRkdXBsaWNhdGVfbmFtZXMgPSBbXTsKCgkJZm9yZWFjaCAoICR0aGlzLT5nZXRfYWxsX3BsdWdpbnMoKSBhcyAkZmlsZSA9PiAkZGV0YWlscyApIHsKCQkJJGFsbF91cGRhdGVfaW5mbyA9ICR0aGlzLT5nZXRfdXBkYXRlX2luZm8oKTsKCQkJJHVwZGF0ZV9pbmZvICAgICA9ICggaXNzZXQoICRhbGxfdXBkYXRlX2luZm8tPnJlc3BvbnNlWyAkZmlsZSBdICkgJiYgbnVsbCAhPT0gJGFsbF91cGRhdGVfaW5mby0+cmVzcG9uc2VbICRmaWxlIF0gKSA/IChhcnJheSkgJGFsbF91cGRhdGVfaW5mby0+cmVzcG9uc2VbICRmaWxlIF0gOiBudWxsOwoJCQkkbmFtZSAgICAgICAgICAgID0gVXRpbHNcZ2V0X3BsdWdpbl9uYW1lKCAkZmlsZSApOwoKCQkJaWYgKCAhIGlzc2V0KCAkZHVwbGljYXRlX25hbWVzWyAkbmFtZSBdICkgKSB7CgkJCQkkZHVwbGljYXRlX25hbWVzWyAkbmFtZSBdID0gYXJyYXkoKTsKCQkJfQoKCQkJJGR1cGxpY2F0ZV9uYW1lc1sgJG5hbWUgXVtdID0gJGZpbGU7CgkJCSRpdGVtc1sgJGZpbGUgXSAgICAgICAgICAgICA9IFsKCQkJCSduYW1lJyAgICAgICAgICAgPT4gJG5hbWUsCgkJCQknc3RhdHVzJyAgICAgICAgID0+ICR0aGlzLT5nZXRfc3RhdHVzKCAkZmlsZSApLAoJCQkJJ3VwZGF0ZScgICAgICAgICA9PiAoYm9vbCkgJHVwZGF0ZV9pbmZvLAoJCQkJJ3VwZGF0ZV92ZXJzaW9uJyA9PiBpc3NldCggJHVwZGF0ZV9pbmZvICkgJiYgaXNzZXQoICR1cGRhdGVfaW5mb1snbmV3X3ZlcnNpb24nXSApID8gJHVwZGF0ZV9pbmZvWyduZXdfdmVyc2lvbiddIDogbnVsbCwKCQkJCSd1cGRhdGVfcGFja2FnZScgPT4gaXNzZXQoICR1cGRhdGVfaW5mbyApICYmIGlzc2V0KCAkdXBkYXRlX2luZm9bJ3BhY2thZ2UnXSApID8gJHVwZGF0ZV9pbmZvWydwYWNrYWdlJ10gOiBudWxsLAoJCQkJJ3ZlcnNpb24nICAgICAgICA9PiAkZGV0YWlsc1snVmVyc2lvbiddLAoJCQkJJ3VwZGF0ZV9pZCcgICAgICA9PiAkZmlsZSwKCQkJCSd0aXRsZScgICAgICAgICAgPT4gJGRldGFpbHNbJ05hbWUnXSwKCQkJCSdkZXNjcmlwdGlvbicgICAgPT4gd29yZHdyYXAoICRkZXRhaWxzWydEZXNjcmlwdGlvbiddICksCgkJCQknZmlsZScgICAgICAgICAgID0+ICRmaWxlLAoJCQldOwoKCQkJaWYgKCBudWxsID09PSAkdXBkYXRlX2luZm8gKSB7CgoJCQkJLy8gR2V0IGluZm8gZm9yIGFsbCBwbHVnaW5zIHRoYXQgZG9uJ3QgaGF2ZSBhbiB1cGRhdGUuCgkJCQkkcGx1Z2luX3VwZGF0ZV9pbmZvID0gaXNzZXQoICRhbGxfdXBkYXRlX2luZm8tPm5vX3VwZGF0ZVsgJGZpbGUgXSApID8gJGFsbF91cGRhdGVfaW5mby0+bm9fdXBkYXRlWyAkZmlsZSBdIDogbnVsbDsKCgkJCQkvLyBDb21wYXJlIHZlcnNpb24gYW5kIHVwZGF0ZSBpbmZvcm1hdGlvbiBpbiBwbHVnaW4gbGlzdC4KCQkJCWlmICggbnVsbCAhPT0gJHBsdWdpbl91cGRhdGVfaW5mbyAmJiB2ZXJzaW9uX2NvbXBhcmUoICRkZXRhaWxzWydWZXJzaW9uJ10sICRwbHVnaW5fdXBkYXRlX2luZm8tPm5ld192ZXJzaW9uLCAnPicgKSApIHsKCQkJCQkkaXRlbXNbICRmaWxlIF1bJ3VwZGF0ZSddID0gc3RhdGljOjpJTlZBTElEX1ZFUlNJT05fTUVTU0FHRTsKCQkJCX0KCQkJfQoJCX0KCgkJZm9yZWFjaCAoICRkdXBsaWNhdGVfbmFtZXMgYXMgJG5hbWUgPT4gJGZpbGVzICkgewoJCQlpZiAoIGNvdW50KCAkZmlsZXMgKSA8PSAxICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJCSRpdGVtc1sgJGZpbGUgXVsnbmFtZSddID0gc3RyX3JlcGxhY2UoICcuJyAuIHBhdGhpbmZvKCAkZmlsZSwgUEFUSElORk9fRVhURU5TSU9OICksICcnLCAkZmlsZSApOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGl0ZW1zOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBmaWx0ZXJfaXRlbV9saXN0KCAkaXRlbXMsICRhcmdzICkgewoJCSRiYXNlbmFtZXMgPSB3cF9saXN0X3BsdWNrKCAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICksICdmaWxlJyApOwoJCXJldHVybiBVdGlsc1xwaWNrX2ZpZWxkcyggJGl0ZW1zLCAkYmFzZW5hbWVzICk7Cgl9CgoJLyoqCgkgKiBJbnN0YWxscyBvbmUgb3IgbW9yZSBwbHVnaW5zLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cGx1Z2lufHppcHx1cmw+Li4uCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gaW5zdGFsbC4gQWNjZXB0cyBhIHBsdWdpbiBzbHVnLCB0aGUgcGF0aCB0byBhIGxvY2FsIHppcCBmaWxlLCBvciBhIFVSTCB0byBhIHJlbW90ZSB6aXAgZmlsZS4KCSAqCgkgKiBbLS12ZXJzaW9uPTx2ZXJzaW9uPl0KCSAqIDogSWYgc2V0LCBnZXQgdGhhdCBwYXJ0aWN1bGFyIHZlcnNpb24gZnJvbSB3b3JkcHJlc3Mub3JnLCBpbnN0ZWFkIG9mIHRoZQoJICogc3RhYmxlIHZlcnNpb24uCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IElmIHNldCwgdGhlIGNvbW1hbmQgd2lsbCBvdmVyd3JpdGUgYW55IGluc3RhbGxlZCB2ZXJzaW9uIG9mIHRoZSBwbHVnaW4sIHdpdGhvdXQgcHJvbXB0aW5nCgkgKiBmb3IgY29uZmlybWF0aW9uLgoJICoKCSAqIFstLWFjdGl2YXRlXQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gd2lsbCBiZSBhY3RpdmF0ZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgaW5zdGFsbC4KCSAqCgkgKiBbLS1hY3RpdmF0ZS1uZXR3b3JrXQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gd2lsbCBiZSBuZXR3b3JrIGFjdGl2YXRlZCBpbW1lZGlhdGVseSBhZnRlciBpbnN0YWxsCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkcyB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbnN0YWxsIHRoZSBsYXRlc3QgdmVyc2lvbiBmcm9tIHdvcmRwcmVzcy5vcmcgYW5kIGFjdGl2YXRlCgkgKiAgICAgJCB3cCBwbHVnaW4gaW5zdGFsbCBiYnByZXNzIC0tYWN0aXZhdGUKCSAqICAgICBJbnN0YWxsaW5nIGJiUHJlc3MgKDIuNS45KQoJICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvcGx1Z2luL2JicHJlc3MuMi41LjkuemlwLi4uCgkgKiAgICAgVXNpbmcgY2FjaGVkIGZpbGUgJy9ob21lL3ZhZ3JhbnQvLndwLWNsaS9jYWNoZS9wbHVnaW4vYmJwcmVzcy0yLjUuOS56aXAnLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSBwYWNrYWdlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgcGx1Z2luLi4uCgkgKiAgICAgUGx1Z2luIGluc3RhbGxlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgQWN0aXZhdGluZyAnYmJwcmVzcycuLi4KCSAqICAgICBQbHVnaW4gJ2JicHJlc3MnIGFjdGl2YXRlZC4KCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgSW5zdGFsbCB0aGUgZGV2ZWxvcG1lbnQgdmVyc2lvbiBmcm9tIHdvcmRwcmVzcy5vcmcKCSAqICAgICAkIHdwIHBsdWdpbiBpbnN0YWxsIGJicHJlc3MgLS12ZXJzaW9uPWRldgoJICogICAgIEluc3RhbGxpbmcgYmJQcmVzcyAoRGV2ZWxvcG1lbnQgVmVyc2lvbikKCSAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3BsdWdpbi9iYnByZXNzLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgcGx1Z2lucy4KCSAqCgkgKiAgICAgIyBJbnN0YWxsIGZyb20gYSBsb2NhbCB6aXAgZmlsZQoJICogICAgICQgd3AgcGx1Z2luIGluc3RhbGwgLi4vbXktcGx1Z2luLnppcAoJICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgcGx1Z2lucy4KCSAqCgkgKiAgICAgIyBJbnN0YWxsIGZyb20gYSByZW1vdGUgemlwIGZpbGUKCSAqICAgICAkIHdwIHBsdWdpbiBpbnN0YWxsIGh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2J1Y2tldG5hbWUvbXktcGx1Z2luLnppcD9BV1NBY2Nlc3NLZXlJZD0xMjMmRXhwaXJlcz00NTYmU2lnbmF0dXJlPWFiY2RlZgoJICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2J1Y2tldG5hbWUvbXktcGx1Z2luLnppcD9BV1NBY2Nlc3NLZXlJZD0xMjMmRXhwaXJlcz00NTYmU2lnbmF0dXJlPWFiY2RlZgoJICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgcGx1Z2lucy4KCSAqCgkgKiAgICAgIyBVcGRhdGUgZnJvbSBhIHJlbW90ZSB6aXAgZmlsZQoJICogICAgICQgd3AgcGx1Z2luIGluc3RhbGwgaHR0cHM6Ly9naXRodWIuY29tL2VudmF0by93cC1lbnZhdG8tbWFya2V0L2FyY2hpdmUvbWFzdGVyLnppcCAtLWZvcmNlCgkgKiAgICAgRG93bmxvYWRpbmcgaW5zdGFsbCBwYWNrYWdlIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VudmF0by93cC1lbnZhdG8tbWFya2V0L2FyY2hpdmUvbWFzdGVyLnppcAoJICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIHBsdWdpbi4uLgoJICogICAgIFJlbmFtZWQgR2l0aHViLWJhc2VkIHByb2plY3QgZnJvbSAnd3AtZW52YXRvLW1hcmtldC1tYXN0ZXInIHRvICd3cC1lbnZhdG8tbWFya2V0Jy4KCSAqICAgICBQbHVnaW4gdXBkYXRlZCBzdWNjZXNzZnVsbHkKCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgRm9yY2VmdWxseSByZS1pbnN0YWxsIGFsbCBpbnN0YWxsZWQgcGx1Z2lucwoJICogICAgICQgd3AgcGx1Z2luIGluc3RhbGwgJCh3cCBwbHVnaW4gbGlzdCAtLWZpZWxkPW5hbWUpIC0tZm9yY2UKCSAqICAgICBJbnN0YWxsaW5nIEFraXNtZXQgKDMuMS4xMSkKCSAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3BsdWdpbi9ha2lzbWV0LjMuMS4xMS56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBwbHVnaW4uLi4KCSAqICAgICBSZW1vdmluZyB0aGUgb2xkIHZlcnNpb24gb2YgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiB1cGRhdGVkIHN1Y2Nlc3NmdWxseQoJICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgcGx1Z2lucy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJaWYgKCAhIGlzX2RpciggV1BfUExVR0lOX0RJUiApICkgewoJCQl3cF9ta2Rpcl9wKCBXUF9QTFVHSU5fRElSICk7CgkJfQoKCQlwYXJlbnQ6Omluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogR2V0cyBkZXRhaWxzIGFib3V0IGFuIGluc3RhbGxlZCBwbHVnaW4uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwbHVnaW4+CgkgKiA6IFRoZSBwbHVnaW4gdG8gZ2V0LgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSBwbHVnaW4sIHJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuIERlZmF1bHRzIHRvIGFsbCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgcGx1Z2luIGdldCBiYnByZXNzIC0tZm9ybWF0PWpzb24KCSAqICAgICB7Im5hbWUiOiJiYnByZXNzIiwidGl0bGUiOiJiYlByZXNzIiwiYXV0aG9yIjoiVGhlIGJiUHJlc3MgQ29udHJpYnV0b3JzIiwidmVyc2lvbiI6IjIuNi1hbHBoYSIsImRlc2NyaXB0aW9uIjoiYmJQcmVzcyBpcyBmb3J1bSBzb2Z0d2FyZSB3aXRoIGEgdHdpc3QgZnJvbSB0aGUgY3JlYXRvcnMgb2YgV29yZFByZXNzLiIsInN0YXR1cyI6ImFjdGl2ZSJ9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGx1Z2luID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkZmlsZSAgID0gJHBsdWdpbi0+ZmlsZTsKCgkJJHBsdWdpbl9kYXRhID0gZ2V0X3BsdWdpbl9kYXRhKCBXUF9QTFVHSU5fRElSIC4gJy8nIC4gJGZpbGUsIGZhbHNlLCBmYWxzZSApOwoKCQkkcGx1Z2luX29iaiA9IChvYmplY3QpIFsKCQkJJ25hbWUnICAgICAgICA9PiBVdGlsc1xnZXRfcGx1Z2luX25hbWUoICRmaWxlICksCgkJCSd0aXRsZScgICAgICAgPT4gJHBsdWdpbl9kYXRhWydOYW1lJ10sCgkJCSdhdXRob3InICAgICAgPT4gJHBsdWdpbl9kYXRhWydBdXRob3InXSwKCQkJJ3ZlcnNpb24nICAgICA9PiAkcGx1Z2luX2RhdGFbJ1ZlcnNpb24nXSwKCQkJJ2Rlc2NyaXB0aW9uJyA9PiB3b3Jkd3JhcCggJHBsdWdpbl9kYXRhWydEZXNjcmlwdGlvbiddICksCgkJCSdzdGF0dXMnICAgICAgPT4gJHRoaXMtPmdldF9zdGF0dXMoICRmaWxlICksCgkJXTsKCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRwbHVnaW5fYXJyYXkgICAgICAgICA9IGdldF9vYmplY3RfdmFycyggJHBsdWdpbl9vYmogKTsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gYXJyYXlfa2V5cyggJHBsdWdpbl9hcnJheSApOwoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbSggJHBsdWdpbl9vYmogKTsKCX0KCgkvKioKCSAqIFVuaW5zdGFsbHMgb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIHVuaW5zdGFsbC4KCSAqCgkgKiBbLS1kZWFjdGl2YXRlXQoJICogOiBEZWFjdGl2YXRlIHRoZSBwbHVnaW4gYmVmb3JlIHVuaW5zdGFsbGluZy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byB3YXJuIGFuZCBza2lwIGlmIHRoZSBwbHVnaW4gaXMgYWN0aXZlLgoJICoKCSAqIFstLXNraXAtZGVsZXRlXQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gZmlsZXMgd2lsbCBub3QgYmUgZGVsZXRlZC4gT25seSB0aGUgdW5pbnN0YWxsIHByb2NlZHVyZQoJICogd2lsbCBiZSBydW4uCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBwbHVnaW5zIHdpbGwgYmUgdW5pbnN0YWxsZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwbHVnaW4gdW5pbnN0YWxsIGhlbGxvCgkgKiAgICAgVW5pbnN0YWxsZWQgYW5kIGRlbGV0ZWQgJ2hlbGxvJyBwbHVnaW4uCgkgKiAgICAgU3VjY2VzczogVW5pbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgoJCSRhbGwgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQkvLyBDaGVjayBpZiBwbHVnaW4gbmFtZXMgb3IgLS1hbGwgaXMgcGFzc2VkLgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwsICd1bmluc3RhbGwnICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkcGx1Z2lucyAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCWlmICggY291bnQoICRwbHVnaW5zICkgPCBjb3VudCggJGFyZ3MgKSApIHsKCQkJJGVycm9ycyA9IGNvdW50KCAkYXJncyApIC0gY291bnQoICRwbHVnaW5zICk7CgkJfQoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJaWYgKCBpc19wbHVnaW5fYWN0aXZlKCAkcGx1Z2luLT5maWxlICkgJiYgISBXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGVhY3RpdmF0ZScgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlRoZSAneyRwbHVnaW4tPm5hbWV9JyBwbHVnaW4gaXMgYWN0aXZlLiIgKTsKCQkJCSRlcnJvcnMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RlYWN0aXZhdGUnICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIkRlYWN0aXZhdGluZyAneyRwbHVnaW4tPm5hbWV9Jy4uLiIgKTsKCQkJCSR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgPSB0cnVlOwoJCQkJJHRoaXMtPmRlYWN0aXZhdGUoIGFycmF5KCAkcGx1Z2luLT5uYW1lICkgKTsKCQkJCSR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgPSBmYWxzZTsKCQkJfQoKCQkJdW5pbnN0YWxsX3BsdWdpbiggJHBsdWdpbi0+ZmlsZSApOwoKCQkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtZGVsZXRlJyApICYmICR0aGlzLT5kZWxldGVfcGx1Z2luKCAkcGx1Z2luICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIlVuaW5zdGFsbGVkIGFuZCBkZWxldGVkICckcGx1Z2luLT5uYW1lJyBwbHVnaW4uIiApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICJSYW4gdW5pbnN0YWxsIHByb2NlZHVyZSBmb3IgJyRwbHVnaW4tPm5hbWUnIHBsdWdpbiB3aXRob3V0IGRlbGV0aW5nLiIgKTsKCQkJfQoJCQkkc3VjY2Vzc2VzKys7CgkJfQoJCWlmICggISAkdGhpcy0+Y2hhaW5lZF9jb21tYW5kICkgewoJCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdwbHVnaW4nLCAndW5pbnN0YWxsJywgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYSBnaXZlbiBwbHVnaW4gaXMgaW5zdGFsbGVkLgoJICoKCSAqIFJldHVybnMgZXhpdCBjb2RlIDAgd2hlbiBpbnN0YWxsZWQsIDEgd2hlbiB1bmluc3RhbGxlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBsdWdpbj4KCSAqIDogVGhlIHBsdWdpbiB0byBjaGVjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgcGx1Z2luIGlzIGluc3RhbGxlZDsgZXhpdCBzdGF0dXMgMCBpZiBpbnN0YWxsZWQsIG90aGVyd2lzZSAxCgkgKiAgICAgJCB3cCBwbHVnaW4gaXMtaW5zdGFsbGVkIGhlbGxvCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWluc3RhbGxlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfaW5zdGFsbGVkKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCWlmICggJHRoaXMtPmZldGNoZXItPmdldCggJGFyZ3NbMF0gKSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAwICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgZ2l2ZW4gcGx1Z2luIGlzIGFjdGl2ZS4KCSAqCgkgKiBSZXR1cm5zIGV4aXQgY29kZSAwIHdoZW4gYWN0aXZlLCAxIHdoZW4gbm90IGFjdGl2ZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBsdWdpbj4KCSAqIDogVGhlIHBsdWdpbiB0byBjaGVjay4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBJZiBzZXQsIGNoZWNrIGlmIHBsdWdpbiBpcyBuZXR3b3JrLWFjdGl2YXRlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgcGx1Z2luIGlzIEFjdGl2ZTsgZXhpdCBzdGF0dXMgMCBpZiBhY3RpdmUsIG90aGVyd2lzZSAxCgkgKiAgICAgJCB3cCBwbHVnaW4gaXMtYWN0aXZlIGhlbGxvCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWFjdGl2ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfYWN0aXZlKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSRuZXR3b3JrX3dpZGUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduZXR3b3JrJyApOwoKCQkkcGx1Z2luID0gJHRoaXMtPmZldGNoZXItPmdldCggJGFyZ3NbMF0gKTsKCgkJaWYgKCAhICRwbHVnaW4gKSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCgkJJHRoaXMtPmNoZWNrX2FjdGl2ZSggJHBsdWdpbi0+ZmlsZSwgJG5ldHdvcmtfd2lkZSApID8gV1BfQ0xJOjpoYWx0KCAwICkgOiBXUF9DTEk6OmhhbHQoIDEgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgcGx1Z2luIGZpbGVzIHdpdGhvdXQgZGVhY3RpdmF0aW5nIG9yIHVuaW5zdGFsbGluZy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIGRlbGV0ZS4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgYWxsIHBsdWdpbnMgd2lsbCBiZSBkZWxldGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHBsdWdpbgoJICogICAgICQgd3AgcGx1Z2luIGRlbGV0ZSBoZWxsbwoJICogICAgIERlbGV0ZWQgJ2hlbGxvJyBwbHVnaW4uCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAxIG9mIDEgcGx1Z2lucy4KCSAqCgkgKiAgICAgIyBEZWxldGUgaW5hY3RpdmUgcGx1Z2lucwoJICogICAgICQgd3AgcGx1Z2luIGRlbGV0ZSAkKHdwIHBsdWdpbiBsaXN0IC0tc3RhdHVzPWluYWN0aXZlIC0tZmllbGQ9bmFtZSkKCSAqICAgICBEZWxldGVkICd0aW55bWNlLXRlbXBsYXRlcycgcGx1Z2luLgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMSBvZiAxIHBsdWdpbnMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJJGFsbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCS8vIENoZWNrIGlmIHBsdWdpbiBuYW1lcyBvciAtLWFsbCBpcyBwYXNzZWQuCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCwgJ2RlbGV0ZScgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoKCQlmb3JlYWNoICggJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApIGFzICRwbHVnaW4gKSB7CgkJCWlmICggJHRoaXMtPmRlbGV0ZV9wbHVnaW4oICRwbHVnaW4gKSApIHsKCQkJCVdQX0NMSTo6bG9nKCAiRGVsZXRlZCAneyRwbHVnaW4tPm5hbWV9JyBwbHVnaW4uIiApOwoJCQkJJHN1Y2Nlc3NlcysrOwoJCQl9IGVsc2UgewoJCQkJJGVycm9ycysrOwoJCQl9CgkJfQoJCWlmICggISAkdGhpcy0+Y2hhaW5lZF9jb21tYW5kICkgewoJCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdwbHVnaW4nLCAnZGVsZXRlJywgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIGEgbGlzdCBvZiBwbHVnaW5zLgoJICoKCSAqIERpc3BsYXlzIGEgbGlzdCBvZiB0aGUgcGx1Z2lucyBpbnN0YWxsZWQgb24gdGhlIHNpdGUgd2l0aCBhY3RpdmF0aW9uCgkgKiBzdGF0dXMsIHdoZXRoZXIgb3Igbm90IHRoZXJlJ3MgYW4gdXBkYXRlIGF2YWlsYWJsZSwgZXRjLgoJICoKCSAqIFVzZSBgLS1zdGF0dXM9ZHJvcGluYCB0byBsaXN0IGluc3RhbGxlZCBkcm9waW5zIChlLmcuIGBvYmplY3QtY2FjaGUucGhwYCkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmlsdGVyIHJlc3VsdHMgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGEgZmllbGQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBwbHVnaW4uCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0gY291bnQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogWy0tc3RhdHVzPTxzdGF0dXM+XQoJICogOiBGaWx0ZXIgdGhlIG91dHB1dCBieSBwbHVnaW4gc3RhdHVzLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIGFjdGl2ZQoJICogICAtIGFjdGl2ZS1uZXR3b3JrCgkgKiAgIC0gZHJvcGluCgkgKiAgIC0gaW5hY3RpdmUKCSAqICAgLSBtdXN0LXVzZQoJICogLS0tCgkgKgoJICogWy0tc2tpcC11cGRhdGUtY2hlY2tdCgkgKiA6IElmIHNldCwgdGhlIHBsdWdpbiB1cGRhdGUgY2hlY2sgd2lsbCBiZSBza2lwcGVkLgoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBwbHVnaW46CgkgKgoJICogKiBuYW1lCgkgKiAqIHN0YXR1cwoJICogKiB1cGRhdGUKCSAqICogdmVyc2lvbgoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiB1cGRhdGVfdmVyc2lvbgoJICogKiB1cGRhdGVfcGFja2FnZQoJICogKiB1cGRhdGVfaWQKCSAqICogdGl0bGUKCSAqICogZGVzY3JpcHRpb24KCSAqICogZmlsZQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBhY3RpdmUgcGx1Z2lucyBvbiB0aGUgc2l0ZS4KCSAqICAgICAkIHdwIHBsdWdpbiBsaXN0IC0tc3RhdHVzPWFjdGl2ZSAtLWZvcm1hdD1qc29uCgkgKiAgICAgW3sibmFtZSI6ImR5bmFtaWMtaG9zdG5hbWUiLCJzdGF0dXMiOiJhY3RpdmUiLCJ1cGRhdGUiOiJub25lIiwidmVyc2lvbiI6IjAuNC4yIn0seyJuYW1lIjoidGlueW1jZS10ZW1wbGF0ZXMiLCJzdGF0dXMiOiJhY3RpdmUiLCJ1cGRhdGUiOiJub25lIiwidmVyc2lvbiI6IjQuNC4zIn0seyJuYW1lIjoid3AtbXVsdGlieXRlLXBhdGNoIiwic3RhdHVzIjoiYWN0aXZlIiwidXBkYXRlIjoibm9uZSIsInZlcnNpb24iOiIyLjQifSx7Im5hbWUiOiJ3cC10b3RhbC1oYWNrcyIsInN0YXR1cyI6ImFjdGl2ZSIsInVwZGF0ZSI6Im5vbmUiLCJ2ZXJzaW9uIjoiMi4wLjEifV0KCSAqCgkgKiAgICAgIyBMaXN0IHBsdWdpbnMgb24gZWFjaCBzaXRlIGluIGEgbmV0d29yay4KCSAqICAgICAkIHdwIHNpdGUgbGlzdCAtLWZpZWxkPXVybCB8IHhhcmdzIC1JICUgd3AgcGx1Z2luIGxpc3QgLS11cmw9JQoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgIHwgc3RhdHVzICAgICAgICAgfCB1cGRhdGUgfCB2ZXJzaW9uIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgYWtpc21ldCB8IGFjdGl2ZS1uZXR3b3JrIHwgbm9uZSAgIHwgMy4xLjExICB8CgkgKiAgICAgfCBoZWxsbyAgIHwgaW5hY3RpdmUgICAgICAgfCBub25lICAgfCAxLjYgICAgIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgIHwgc3RhdHVzICAgICAgICAgfCB1cGRhdGUgfCB2ZXJzaW9uIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgYWtpc21ldCB8IGFjdGl2ZS1uZXR3b3JrIHwgbm9uZSAgIHwgMy4xLjExICB8CgkgKiAgICAgfCBoZWxsbyAgIHwgaW5hY3RpdmUgICAgICAgfCBub25lICAgfCAxLjYgICAgIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJcGFyZW50OjpfbGlzdCggJF8sICRhc3NvY19hcmdzICk7Cgl9CgoJLyogUFJJVkFURVMgKi8KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2FjdGl2ZSggJGZpbGUsICRuZXR3b3JrX3dpZGUgKSB7CgkJJHJlcXVpcmVkID0gJG5ldHdvcmtfd2lkZSA/ICdhY3RpdmUtbmV0d29yaycgOiAnYWN0aXZlJzsKCgkJcmV0dXJuICRyZXF1aXJlZCA9PT0gJHRoaXMtPmdldF9zdGF0dXMoICRmaWxlICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBhY3RpdmVfb3V0cHV0KCAkbmFtZSwgJGZpbGUsICRuZXR3b3JrX3dpZGUsICRhY3Rpb24gKSB7CgkJJG5ldHdvcmtfd2lkZSA9ICRuZXR3b3JrX3dpZGUgfHwgKCBpc19tdWx0aXNpdGUoKSAmJiBpc19uZXR3b3JrX29ubHlfcGx1Z2luKCAkZmlsZSApICk7CgoJCSRjaGVjayA9ICR0aGlzLT5jaGVja19hY3RpdmUoICRmaWxlLCAkbmV0d29ya193aWRlICk7CgoJCWlmICggKCAnYWN0aXZhdGUnID09PSAkYWN0aW9uICkgPyAkY2hlY2sgOiAhICRjaGVjayApIHsKCQkJaWYgKCAkbmV0d29ya193aWRlICkgewoJCQkJV1BfQ0xJOjpsb2coICJQbHVnaW4gJ3skbmFtZX0nIG5ldHdvcmsgeyRhY3Rpb259ZC4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZyggIlBsdWdpbiAneyRuYW1lfScgeyRhY3Rpb259ZC4iICk7CgkJCX0KCQl9IGVsc2UgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJDb3VsZCBub3QgeyRhY3Rpb259IHRoZSAneyRuYW1lfScgcGx1Z2luLiIgKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9zdGF0dXMoICRmaWxlICkgewoJCWlmICggaXNfcGx1Z2luX2FjdGl2ZV9mb3JfbmV0d29yayggJGZpbGUgKSApIHsKCQkJcmV0dXJuICdhY3RpdmUtbmV0d29yayc7CgkJfQoKCQlpZiAoIGlzX3BsdWdpbl9hY3RpdmUoICRmaWxlICkgKSB7CgkJCXJldHVybiAnYWN0aXZlJzsKCQl9CgoJCXJldHVybiAnaW5hY3RpdmUnOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgdGVtcGxhdGUgcGF0aCBiYXNlZCBvbiBpbnN0YWxsYXRpb24gdHlwZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3RlbXBsYXRlX3BhdGgoICR0ZW1wbGF0ZSApIHsKCQkkY29tbWFuZF9yb290ICA9IFV0aWxzXHBoYXJfc2FmZV9wYXRoKCBkaXJuYW1lKCBfX0RJUl9fICkgKTsKCQkkdGVtcGxhdGVfcGF0aCA9ICJ7JGNvbW1hbmRfcm9vdH0vdGVtcGxhdGVzL3skdGVtcGxhdGV9IjsKCgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkdGVtcGxhdGVfcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgZmluZCB7JHRlbXBsYXRlfSIgKTsKCQl9CgoJCXJldHVybiAkdGVtcGxhdGVfcGF0aDsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGRldGFpbHMgb2YgYSBwbHVnaW4uCgkgKgoJICogQHBhcmFtIG9iamVjdAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9kZXRhaWxzKCAkZmlsZSApIHsKCQkkcGx1Z2luX2ZvbGRlciA9IGdldF9wbHVnaW5zKCAnLycgLiBwbHVnaW5fYmFzZW5hbWUoIGRpcm5hbWUoICRmaWxlICkgKSApOwoJCSRwbHVnaW5fZmlsZSAgID0gVXRpbHNcYmFzZW5hbWUoICRmaWxlICk7CgoJCXJldHVybiAkcGx1Z2luX2ZvbGRlclsgJHBsdWdpbl9maWxlIF07Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBkZWxldGVfcGx1Z2luKCAkcGx1Z2luICkgewoJCSRwbHVnaW5fZGlyID0gZGlybmFtZSggJHBsdWdpbi0+ZmlsZSApOwoJCWlmICggJy4nID09PSAkcGx1Z2luX2RpciApIHsKCQkJJHBsdWdpbl9kaXIgPSAkcGx1Z2luLT5maWxlOwoJCX0KCgkJJHBhdGggPSBwYXRoX2pvaW4oIFdQX1BMVUdJTl9ESVIsICRwbHVnaW5fZGlyICk7CgoJCWlmICggVXRpbHNcaXNfd2luZG93cygpICkgewoJCQkvLyBIYW5kbGVzIHBsdWdpbnMgdGhhdCBhcmUgbm90IGluIG93biBmb2xkZXJzCgkJCS8vIGUuZy4gSGVsbG8gRG9sbHkgLT4gcGx1Z2lucy9oZWxsby5waHAKCQkJaWYgKCBpc19maWxlKCAkcGF0aCApICkgewoJCQkJJGNvbW1hbmQgPSAnZGVsIC9mIC9xICc7CgkJCX0gZWxzZSB7CgkJCQkkY29tbWFuZCA9ICdyZCAvcyAvcSAnOwoJCQl9CgkJCSRwYXRoID0gc3RyX3JlcGxhY2UoICcvJywgJ1xcJywgJHBhdGggKTsKCQl9IGVsc2UgewoJCQkkY29tbWFuZCA9ICdybSAtcmYgJzsKCQl9CgoJCXJldHVybiAhIFdQX0NMSTo6bGF1bmNoKCAkY29tbWFuZCAuIGVzY2FwZXNoZWxsYXJnKCAkcGF0aCApICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRmV0Y2hlcnNcUGx1Z2luOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxQYXJzZVBsdWdpbk5hbWVJbnB1dDsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBNYW5hZ2VzIHBsdWdpbiBhdXRvLXVwZGF0ZXMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEVuYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHBsdWdpbgogKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIGVuYWJsZSBoZWxsbwogKiAgICAgUGx1Z2luIGF1dG8tdXBkYXRlcyBmb3IgJ2hlbGxvJyBlbmFibGVkLgogKiAgICAgU3VjY2VzczogRW5hYmxlZCAxIG9mIDEgcGx1Z2luIGF1dG8tdXBkYXRlcy4KICoKICogICAgICMgRGlzYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHBsdWdpbgogKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIGRpc2FibGUgaGVsbG8KICogICAgIFBsdWdpbiBhdXRvLXVwZGF0ZXMgZm9yICdoZWxsbycgZGlzYWJsZWQuCiAqICAgICBTdWNjZXNzOiBEaXNhYmxlZCAxIG9mIDEgcGx1Z2luIGF1dG8tdXBkYXRlcy4KICoKICogICAgICMgR2V0IHRoZSBzdGF0dXMgb2YgcGx1Z2luIGF1dG8tdXBkYXRlcwogKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIHN0YXR1cyBoZWxsbwogKiAgICAgQXV0by11cGRhdGVzIGZvciBwbHVnaW4gJ2hlbGxvJyBhcmUgZGlzYWJsZWQuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgUGx1Z2luX0F1dG9VcGRhdGVzX0NvbW1hbmQgewoKCXVzZSBQYXJzZVBsdWdpbk5hbWVJbnB1dDsKCgkvKioKCSAqIFNpdGUgb3B0aW9uIHRoYXQgc3RvcmVzIHRoZSBzdGF0dXMgb2YgcGx1Z2luIGF1dG8tdXBkYXRlcy4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBTSVRFX09QVElPTiA9ICdhdXRvX3VwZGF0ZV9wbHVnaW5zJzsKCgkvKioKCSAqIFBsdWdpbiBmZXRjaGVyIGluc3RhbmNlLgoJICoKCSAqIEB2YXIgUGx1Z2luCgkgKi8KCXByb3RlY3RlZCAkZmV0Y2hlcjsKCgkvKioKCSAqIFBsdWdpbl9BdXRvVXBkYXRlc19Db21tYW5kIGNvbnN0cnVjdG9yLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgUGx1Z2luKCk7Cgl9CgoJLyoqCgkgKiBFbmFibGVzIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgcGx1Z2luLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gZW5hYmxlIGF1dG8tdXBkYXRlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF1dG8tdXBkYXRlcyB3aWxsIGJlIGVuYWJsZWQgZm9yIGFsbCBwbHVnaW5zLgoJICoKCSAqIFstLWRpc2FibGVkLW9ubHldCgkgKiA6IElmIHNldCwgZmlsdGVycyBsaXN0IG9mIHBsdWdpbnMgdG8gb25seSBpbmNsdWRlIHRoZSBvbmVzIHRoYXQgaGF2ZQoJICogYXV0by11cGRhdGVzIGRpc2FibGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRW5hYmxlIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgcGx1Z2luCgkgKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIGVuYWJsZSBoZWxsbwoJICogICAgIFBsdWdpbiBhdXRvLXVwZGF0ZXMgZm9yICdoZWxsbycgZW5hYmxlZC4KCSAqICAgICBTdWNjZXNzOiBFbmFibGVkIDEgb2YgMSBwbHVnaW4gYXV0by11cGRhdGVzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZW5hYmxlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoJCSRkaXNhYmxlZF9vbmx5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGlzYWJsZWQtb25seScsIGZhbHNlICk7CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRwbHVnaW5zICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJJGF1dG9fdXBkYXRlcyA9IGdldF9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiApOwoKCQlpZiAoIGZhbHNlID09PSAkYXV0b191cGRhdGVzICkgewoJCQkkYXV0b191cGRhdGVzID0gW107CgkJfQoKCQkkY291bnQgICAgID0gMDsKCQkkc3VjY2Vzc2VzID0gMDsKCgkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRwbHVnaW4gKSB7CgkJCSRlbmFibGVkID0gaW5fYXJyYXkoICRwbHVnaW4tPmZpbGUsICRhdXRvX3VwZGF0ZXMsIHRydWUgKTsKCgkJCWlmICggJGRpc2FibGVkX29ubHkgJiYgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvdW50Kys7CgoJCQlpZiAoICRlbmFibGVkICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCSJBdXRvLXVwZGF0ZXMgYWxyZWFkeSBlbmFibGVkIGZvciBwbHVnaW4geyRwbHVnaW4tPm5hbWV9LiIKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQkkYXV0b191cGRhdGVzW10gPSAkcGx1Z2luLT5maWxlOwoJCQkJJHN1Y2Nlc3NlcysrOwoJCQl9CgkJfQoKCQlpZiAoIDAgPT09ICRjb3VudCApIHsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSdObyBwbHVnaW5zIHByb3ZpZGVkIHRvIGVuYWJsZSBhdXRvLXVwZGF0ZXMgZm9yLicKCQkJKTsKCQl9CgoJCXVwZGF0ZV9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiwgJGF1dG9fdXBkYXRlcyApOwoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSdwbHVnaW4gYXV0by11cGRhdGUnLAoJCQknZW5hYmxlJywKCQkJJGNvdW50LAoJCQkkc3VjY2Vzc2VzLAoJCQkkY291bnQgLSAkc3VjY2Vzc2VzCgkJKTsKCX0KCgkvKioKCSAqIERpc2FibGVzIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgcGx1Z2luLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gZGlzYWJsZSBhdXRvLXVwZGF0ZXMgZm9yLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhdXRvLXVwZGF0ZXMgd2lsbCBiZSBkaXNhYmxlZCBmb3IgYWxsIHBsdWdpbnMuCgkgKgoJICogWy0tZW5hYmxlZC1vbmx5XQoJICogOiBJZiBzZXQsIGZpbHRlcnMgbGlzdCBvZiBwbHVnaW5zIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBlbmFibGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHBsdWdpbgoJICogICAgICQgd3AgcGx1Z2luIGF1dG8tdXBkYXRlcyBkaXNhYmxlIGhlbGxvCgkgKiAgICAgUGx1Z2luIGF1dG8tdXBkYXRlcyBmb3IgJ2hlbGxvJyBkaXNhYmxlZC4KCSAqICAgICBTdWNjZXNzOiBEaXNhYmxlZCAxIG9mIDEgcGx1Z2luIGF1dG8tdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZW5hYmxlZF9vbmx5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlZC1vbmx5JywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHBsdWdpbnMgICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQkkYXV0b191cGRhdGVzID0gZ2V0X3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OICk7CgoJCWlmICggZmFsc2UgPT09ICRhdXRvX3VwZGF0ZXMgKSB7CgkJCSRhdXRvX3VwZGF0ZXMgPSBbXTsKCQl9CgoJCSRjb3VudCAgICAgPSAwOwoJCSRzdWNjZXNzZXMgPSAwOwoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJGVuYWJsZWQgPSBpbl9hcnJheSggJHBsdWdpbi0+ZmlsZSwgJGF1dG9fdXBkYXRlcywgdHJ1ZSApOwoKCQkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICEgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvdW50Kys7CgoJCQlpZiAoICEgJGVuYWJsZWQgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJIkF1dG8tdXBkYXRlcyBhbHJlYWR5IGRpc2FibGVkIGZvciBwbHVnaW4geyRwbHVnaW4tPm5hbWV9LiIKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQkkYXV0b191cGRhdGVzID0gYXJyYXlfZGlmZiggJGF1dG9fdXBkYXRlcywgWyAkcGx1Z2luLT5maWxlIF0gKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAwID09PSAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknTm8gcGx1Z2lucyBwcm92aWRlZCB0byBkaXNhYmxlIGF1dG8tdXBkYXRlcyBmb3IuJwoJCQkpOwoJCX0KCgkJaWYgKCBjb3VudCggJGF1dG9fdXBkYXRlcyApID4gMCApIHsKCQkJdXBkYXRlX3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OLCAkYXV0b191cGRhdGVzICk7CgkJfSBlbHNlIHsKCQkJZGVsZXRlX3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OICk7CgkJfQoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSdwbHVnaW4gYXV0by11cGRhdGUnLAoJCQknZGlzYWJsZScsCgkJCSRjb3VudCwKCQkJJHN1Y2Nlc3NlcywKCQkJJGNvdW50IC0gJHN1Y2Nlc3NlcwoJCSk7Cgl9CgoJLyoqCgkgKiBTaG93cyB0aGUgc3RhdHVzIG9mIGF1dG8tdXBkYXRlcyBmb3IgYSBwbHVnaW4uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgcGx1Z2lucyB0byBzaG93IHRoZSBzdGF0dXMgb2YgdGhlIGF1dG8tdXBkYXRlcyBvZi4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgdGhlIHN0YXR1cyBvZiBhdXRvLXVwZGF0ZXMgZm9yIGFsbCBwbHVnaW5zIHdpbGwgYmUgc2hvd24uCgkgKgoJICogWy0tZW5hYmxlZC1vbmx5XQoJICogOiBJZiBzZXQsIGZpbHRlcnMgbGlzdCBvZiBwbHVnaW5zIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBlbmFibGVkLgoJICoKCSAqIFstLWRpc2FibGVkLW9ubHldCgkgKiA6IElmIHNldCwgZmlsdGVycyBsaXN0IG9mIHBsdWdpbnMgdG8gb25seSBpbmNsdWRlIHRoZSBvbmVzIHRoYXQgaGF2ZQoJICogYXV0by11cGRhdGVzIGRpc2FibGVkLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IE9ubHkgc2hvdyB0aGUgcHJvdmlkZWQgZmllbGQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgdGhlIHN0YXR1cyBvZiBwbHVnaW4gYXV0by11cGRhdGVzCgkgKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIHN0YXR1cyBoZWxsbwoJICogICAgICstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICB8IHN0YXR1cyAgIHwKCSAqICAgICArLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgaGVsbG8gfCBkaXNhYmxlZCB8CgkgKiAgICAgKy0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBHZXQgdGhlIGxpc3Qgb2YgcGx1Z2lucyB0aGF0IGhhdmUgYXV0by11cGRhdGVzIGVuYWJsZWQKCSAqICAgICAkIHdwIHBsdWdpbiBhdXRvLXVwZGF0ZXMgc3RhdHVzIC0tYWxsIC0tZW5hYmxlZC1vbmx5IC0tZmllbGQ9bmFtZQoJICogICAgIGFraXNtZXQKCSAqICAgICBkdXBsaWNhdGUtcG9zdAoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RhdHVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoJCSRlbmFibGVkX29ubHkgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlZC1vbmx5JywgZmFsc2UgKTsKCQkkZGlzYWJsZWRfb25seSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc2FibGVkLW9ubHknLCBmYWxzZSApOwoKCQlpZiAoICRlbmFibGVkX29ubHkgJiYgJGRpc2FibGVkX29ubHkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknLS1lbmFibGVkLW9ubHkgYW5kIC0tZGlzYWJsZWQtb25seSBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGFuZCAnCgkJCQkuICdjYW5ub3QgYmUgdXNlZCBhdCB0aGUgc2FtZSB0aW1lLicKCQkJKTsKCQl9CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRwbHVnaW5zICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJJGF1dG9fdXBkYXRlcyA9IGdldF9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiApOwoKCQlpZiAoIGZhbHNlID09PSAkYXV0b191cGRhdGVzICkgewoJCQkkYXV0b191cGRhdGVzID0gW107CgkJfQoKCQkkcmVzdWx0cyA9IFtdOwoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJGVuYWJsZWQgPSBpbl9hcnJheSggJHBsdWdpbi0+ZmlsZSwgJGF1dG9fdXBkYXRlcywgdHJ1ZSApOwoKCQkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICEgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAkZGlzYWJsZWRfb25seSAmJiAkZW5hYmxlZCApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkcmVzdWx0c1tdID0gWwoJCQkJJ25hbWUnICAgPT4gJHBsdWdpbi0+bmFtZSwKCQkJCSdmaWxlJyAgID0+ICRwbHVnaW4tPmZpbGUsCgkJCQknc3RhdHVzJyA9PiAkZW5hYmxlZCA/ICdlbmFibGVkJyA6ICdkaXNhYmxlZCcsCgkJCV07CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIFsgJ25hbWUnLCAnc3RhdHVzJyBdLCAncGx1Z2luJyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRyZXN1bHRzICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhVcGdyYWRlOwp1c2UgV1BfQ0xJXFBhcnNlVGhlbWVOYW1lSW5wdXQ7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTWFuYWdlcyB0aGVtZXMsIGluY2x1ZGluZyBpbnN0YWxscywgYWN0aXZhdGlvbnMsIGFuZCB1cGRhdGVzLgogKgogKiBTZWUgdGhlIFdvcmRQcmVzcyBbVGhlbWUgSGFuZGJvb2tdKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvdGhlbWVzLykgZGV2ZWxvcGVyIHJlc291cmNlIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZW1lcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgSW5zdGFsbCB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgYSB0aGVtZSBmcm9tIHdvcmRwcmVzcy5vcmcgYW5kIGFjdGl2YXRlCiAqICAgICAkIHdwIHRoZW1lIGluc3RhbGwgdHdlbnR5c2l4dGVlbiAtLWFjdGl2YXRlCiAqICAgICBJbnN0YWxsaW5nIFR3ZW50eSBTaXh0ZWVuICgxLjIpCiAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdGhlbWUvdHdlbnR5c2l4dGVlbi4xLjIuemlwLi4uCiAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KICogICAgIEluc3RhbGxpbmcgdGhlIHRoZW1lLi4uCiAqICAgICBUaGVtZSBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgogKiAgICAgQWN0aXZhdGluZyAndHdlbnR5c2l4dGVlbicuLi4KICogICAgIFN1Y2Nlc3M6IFN3aXRjaGVkIHRvICdUd2VudHkgU2l4dGVlbicgdGhlbWUuCiAqCiAqICAgICAjIEdldCBkZXRhaWxzIG9mIGFuIGluc3RhbGxlZCB0aGVtZQogKiAgICAgJCB3cCB0aGVtZSBnZXQgdHdlbnR5c2l4dGVlbiAtLWZpZWxkcz1uYW1lLHRpdGxlLHZlcnNpb24KICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgRmllbGQgICB8IFZhbHVlICAgICAgICAgIHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbmFtZSAgICB8IFR3ZW50eSBTaXh0ZWVuIHwKICogICAgIHwgdGl0bGUgICB8IFR3ZW50eSBTaXh0ZWVuIHwKICogICAgIHwgdmVyc2lvbiB8IDEuMiAgICAgICAgICAgIHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKICoKICogICAgICMgR2V0IHN0YXR1cyBvZiB0aGVtZQogKiAgICAgJCB3cCB0aGVtZSBzdGF0dXMgdHdlbnR5c2l4dGVlbgogKiAgICAgVGhlbWUgdHdlbnR5c2l4dGVlbiBkZXRhaWxzOgogKiAgICAgICAgICBOYW1lOiBUd2VudHkgU2l4dGVlbgogKiAgICAgICAgICBTdGF0dXM6IEFjdGl2ZQogKiAgICAgICAgICBWZXJzaW9uOiAxLjIKICogICAgICAgICAgQXV0aG9yOiB0aGUgV29yZFByZXNzIHRlYW0KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBUaGVtZV9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhVcGdyYWRlIHsKCgl1c2UgUGFyc2VUaGVtZU5hbWVJbnB1dDsKCglwcm90ZWN0ZWQgJGl0ZW1fdHlwZSAgICAgICAgID0gJ3RoZW1lJzsKCXByb3RlY3RlZCAkdXBncmFkZV9yZWZyZXNoICAgPSAnd3BfdXBkYXRlX3RoZW1lcyc7Cglwcm90ZWN0ZWQgJHVwZ3JhZGVfdHJhbnNpZW50ID0gJ3VwZGF0ZV90aGVtZXMnOwoKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IFsgJ25hbWUnLCAnc3RhdHVzJywgJ3VwZGF0ZScsICd2ZXJzaW9uJyBdOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQlpZiAoIGlzX211bHRpc2l0ZSgpICkgewoJCQkkdGhpcy0+b2JqX2ZpZWxkc1tdID0gJ2VuYWJsZWQnOwoJCX0KCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCk7CgoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFdQX0NMSVxGZXRjaGVyc1xUaGVtZSgpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXBncmFkZXJfY2xhc3MoICRmb3JjZSApIHsKCQlyZXR1cm4gJGZvcmNlID8gJ1xcV1BfQ0xJXFxEZXN0cnVjdGl2ZVRoZW1lVXBncmFkZXInIDogJ1RoZW1lX1VwZ3JhZGVyJzsKCX0KCgkvKioKCSAqIFJldmVhbHMgdGhlIHN0YXR1cyBvZiBvbmUgb3IgYWxsIHRoZW1lcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT5dCgkgKiA6IEEgcGFydGljdWxhciB0aGVtZSB0byBzaG93IHRoZSBzdGF0dXMgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdGhlbWUgc3RhdHVzIHR3ZW50eXNpeHRlZW4KCSAqICAgICBUaGVtZSB0d2VudHlzaXh0ZWVuIGRldGFpbHM6CgkgKiAgICAgICAgICBOYW1lOiBUd2VudHkgU2l4dGVlbgoJICogICAgICAgICAgU3RhdHVzOiBJbmFjdGl2ZQoJICogICAgICAgICAgVmVyc2lvbjogMS4yCgkgKiAgICAgICAgICBBdXRob3I6IHRoZSBXb3JkUHJlc3MgdGVhbQoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RhdHVzKCAkYXJncyApIHsKCQlpZiAoIGlzc2V0KCAkYXJnc1swXSApICkgewoJCQkkdGhlbWUgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkJJGVycm9ycyA9ICR0aGVtZS0+ZXJyb3JzKCk7CgkJCWlmICggaXNfd3BfZXJyb3IoICRlcnJvcnMgKSApIHsKCQkJCSRtZXNzYWdlID0gJGVycm9ycy0+Z2V0X2Vycm9yX21lc3NhZ2UoKTsKCQkJCVdQX0NMSTo6ZXJyb3IoICRtZXNzYWdlICk7CgkJCX0KCQl9CgoJCXBhcmVudDo6c3RhdHVzKCAkYXJncyApOwoJfQoKCS8qKgoJICogU2VhcmNoZXMgdGhlIFdvcmRQcmVzcy5vcmcgdGhlbWUgZGlyZWN0b3J5LgoJICoKCSAqIERpc3BsYXlzIHRoZW1lcyBpbiB0aGUgV29yZFByZXNzLm9yZyB0aGVtZSBkaXJlY3RvcnkgbWF0Y2hpbmcgYSBnaXZlbgoJICogc2VhcmNoIHF1ZXJ5LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2VhcmNoPgoJICogOiBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuCgkgKgoJICogWy0tcGFnZT08cGFnZT5dCgkgKiA6IE9wdGlvbmFsIHBhZ2UgdG8gZGlzcGxheS4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWy0tcGVyLXBhZ2U9PHBlci1wYWdlPl0KCSAqIDogT3B0aW9uYWwgbnVtYmVyIG9mIHJlc3VsdHMgdG8gZGlzcGxheS4gRGVmYXVsdHMgdG8gMTAuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCB0aGVtZS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IEFzayBmb3Igc3BlY2lmaWMgZmllbGRzIGZyb20gdGhlIEFQSS4gRGVmYXVsdHMgdG8gbmFtZSxzbHVnLGF1dGhvcixyYXRpbmcuIEFjY2VwdGFibGUgdmFsdWVzOgoJICoKCSAqICAgICAqKm5hbWUqKjogVGhlbWUgTmFtZQoJICogICAgICoqc2x1ZyoqOiBUaGVtZSBTbHVnCgkgKiAgICAgKip2ZXJzaW9uKio6IEN1cnJlbnQgVmVyc2lvbiBOdW1iZXIKCSAqICAgICAqKmF1dGhvcioqOiBUaGVtZSBBdXRob3IKCSAqICAgICAqKnByZXZpZXdfdXJsKio6IFRoZW1lIFByZXZpZXcgVVJMCgkgKiAgICAgKipzY3JlZW5zaG90X3VybCoqOiBUaGVtZSBTY3JlZW5zaG90IFVSTAoJICogICAgICoqcmF0aW5nKio6IFRoZW1lIFJhdGluZwoJICogICAgICoqbnVtX3JhdGluZ3MqKjogTnVtYmVyIG9mIFRoZW1lIFJhdGluZ3MKCSAqICAgICAqKmhvbWVwYWdlKio6IFRoZW1lIEF1dGhvcidzIEhvbWVwYWdlCgkgKiAgICAgKipkZXNjcmlwdGlvbioqOiBUaGVtZSBEZXNjcmlwdGlvbgoJICogICAgICoqdXJsKio6IFRoZW1lJ3MgVVJMIG9uIHdvcmRwcmVzcy5vcmcKCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHRoZW1lIHNlYXJjaCBwaG90byAtLXBlci1wYWdlPTYKCSAqICAgICBTdWNjZXNzOiBTaG93aW5nIDYgb2YgMjAzIHRoZW1lcy4KCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICAgICAgICAgICAgICAgfCBzbHVnICAgICAgICAgICAgICAgICB8IHJhdGluZyB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKCSAqICAgICB8IFBob3RvcyAgICAgICAgICAgICAgIHwgcGhvdG9zICAgICAgICAgICAgICAgfCAxMDAgICAgfAoJICogICAgIHwgSW5maW5pdGUgUGhvdG9ncmFwaHkgfCBpbmZpbml0ZS1waG90b2dyYXBoeSB8IDEwMCAgICB8CgkgKiAgICAgfCBQaG90b0Jvb2sgICAgICAgICAgICB8IHBob3RvYm9vayAgICAgICAgICAgIHwgMTAwICAgIHwKCSAqICAgICB8IEJHIFBob3RvIEZyYW1lICAgICAgIHwgYmctcGhvdG8tZnJhbWUgICAgICAgfCAwICAgICAgfAoJICogICAgIHwgZlBob3RvZ3JhcGh5ICAgICAgICAgfCBmcGhvdG9ncmFwaHkgICAgICAgICB8IDAgICAgICB8CgkgKiAgICAgfCBQaG90byBQZXJmZWN0ICAgICAgICB8IHBob3RvLXBlcmZlY3QgICAgICAgIHwgOTggICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwoJICovCglwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJcGFyZW50Ojpfc2VhcmNoKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gc3RhdHVzX3NpbmdsZSggJGFyZ3MgKSB7CgkJJHRoZW1lID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJJHN0YXR1cyA9ICR0aGlzLT5mb3JtYXRfc3RhdHVzKCAkdGhpcy0+Z2V0X3N0YXR1cyggJHRoZW1lICksICdsb25nJyApOwoKCQkkdmVyc2lvbiA9ICR0aGVtZS0+Z2V0KCAnVmVyc2lvbicgKTsKCQlpZiAoICR0aGlzLT5oYXNfdXBkYXRlKCAkdGhlbWUtPmdldF9zdHlsZXNoZWV0KCkgKSApIHsKCQkJJHZlcnNpb24gLj0gJyAoJWdVcGRhdGUgYXZhaWxhYmxlJW4pJzsKCQl9CgoJCWVjaG8gV1BfQ0xJOjpjb2xvcml6ZSgKCQkJVXRpbHNcbXVzdGFjaGVfcmVuZGVyKAoJCQkJc2VsZjo6Z2V0X3RlbXBsYXRlX3BhdGgoICd0aGVtZS1zdGF0dXMubXVzdGFjaGUnICksCgkJCQlbCgkJCQkJJ3NsdWcnICAgID0+ICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSwKCQkJCQknc3RhdHVzJyAgPT4gJHN0YXR1cywKCQkJCQkndmVyc2lvbicgPT4gJHZlcnNpb24sCgkJCQkJJ25hbWUnICAgID0+ICR0aGVtZS0+Z2V0KCAnTmFtZScgKSwKCQkJCQknYXV0aG9yJyAgPT4gJHRoZW1lLT5nZXQoICdBdXRob3InICksCgkJCQldCgkJCSkKCQkpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfYWxsX2l0ZW1zKCkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2l0ZW1fbGlzdCgpOwoJfQoKCS8qKgoJICogQWN0aXZhdGVzIGEgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZT4KCSAqIDogVGhlIHRoZW1lIHRvIGFjdGl2YXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdGhlbWUgYWN0aXZhdGUgdHdlbnR5c2l4dGVlbgoJICogICAgIFN1Y2Nlc3M6IFN3aXRjaGVkIHRvICdUd2VudHkgU2l4dGVlbicgdGhlbWUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhY3RpdmF0ZSggJGFyZ3MgPSBhcnJheSgpICkgewoJCSR0aGVtZSA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgoJCSRlcnJvcnMgPSAkdGhlbWUtPmVycm9ycygpOwoJCWlmICggaXNfd3BfZXJyb3IoICRlcnJvcnMgKSApIHsKCQkJJG1lc3NhZ2UgPSAkZXJyb3JzLT5nZXRfZXJyb3JfbWVzc2FnZSgpOwoJCQlXUF9DTEk6OmVycm9yKCAkbWVzc2FnZSApOwoJCX0KCgkJJG5hbWUgPSAkdGhlbWUtPmdldCggJ05hbWUnICk7CgoJCWlmICggJ2FjdGl2ZScgPT09ICR0aGlzLT5nZXRfc3RhdHVzKCAkdGhlbWUgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVGhlICckbmFtZScgdGhlbWUgaXMgYWxyZWFkeSBhY3RpdmUuIiApOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSAhPT0gJHRoZW1lLT5nZXRfdGVtcGxhdGUoKSAmJiAhICR0aGlzLT5mZXRjaGVyLT5nZXQoICR0aGVtZS0+Z2V0X3RlbXBsYXRlKCkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlRoZSAneyR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKX0nIHRoZW1lIGNhbm5vdCBiZSBhY3RpdmF0ZWQgd2l0aG91dCBpdHMgcGFyZW50LCAneyR0aGVtZS0+Z2V0X3RlbXBsYXRlKCl9Jy4iICk7CgkJfQoKCQlzd2l0Y2hfdGhlbWUoICR0aGVtZS0+Z2V0X3RlbXBsYXRlKCksICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSApOwoKCQlpZiAoICR0aGlzLT5pc19hY3RpdmVfdGhlbWUoICR0aGVtZSApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJTd2l0Y2hlZCB0byAnJG5hbWUnIHRoZW1lLiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHN3aXRjaCB0byAnJG5hbWUnIHRoZW1lLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBFbmFibGVzIGEgdGhlbWUgb24gYSBXb3JkUHJlc3MgbXVsdGlzaXRlIGluc3RhbGwuCgkgKgoJICogUGVybWl0cyB0aGVtZSB0byBiZSBhY3RpdmF0ZWQgZnJvbSB0aGUgZGFzaGJvYXJkIG9mIGEgc2l0ZSBvbiBhIFdvcmRQcmVzcwoJICogbXVsdGlzaXRlIGluc3RhbGwuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZT4KCSAqIDogVGhlIHRoZW1lIHRvIGVuYWJsZS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBJZiBzZXQsIHRoZSB0aGVtZSBpcyBlbmFibGVkIGZvciB0aGUgZW50aXJlIG5ldHdvcmsKCSAqCgkgKiBbLS1hY3RpdmF0ZV0KCSAqIDogSWYgc2V0LCB0aGUgdGhlbWUgaXMgYWN0aXZhdGVkIGZvciB0aGUgY3VycmVudCBzaXRlLiBOb3RlIHRoYXQKCSAqIHRoZSAibmV0d29yayIgZmxhZyBoYXMgbm8gaW5mbHVlbmNlIG9uIHRoaXMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBFbmFibGUgdGhlbWUKCSAqICAgICAkIHdwIHRoZW1lIGVuYWJsZSB0d2VudHlzaXh0ZWVuCgkgKiAgICAgU3VjY2VzczogRW5hYmxlZCB0aGUgJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KCSAqCgkgKiAgICAgIyBOZXR3b3JrIGVuYWJsZSB0aGVtZQoJICogICAgICQgd3AgdGhlbWUgZW5hYmxlIHR3ZW50eXNpeHRlZW4gLS1uZXR3b3JrCgkgKiAgICAgU3VjY2VzczogTmV0d29yayBlbmFibGVkIHRoZSAnVHdlbnR5IFNpeHRlZW4nIHRoZW1lLgoJICoKCSAqICAgICAjIE5ldHdvcmsgZW5hYmxlIGFuZCBhY3RpdmF0ZSB0aGVtZSBmb3IgY3VycmVudCBzaXRlCgkgKiAgICAgJCB3cCB0aGVtZSBlbmFibGUgdHdlbnR5c2l4dGVlbiAtLWFjdGl2YXRlCgkgKiAgICAgU3VjY2VzczogRW5hYmxlZCB0aGUgJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KCSAqICAgICBTdWNjZXNzOiBTd2l0Y2hlZCB0byAnVHdlbnR5IFNpeHRlZW4nIHRoZW1lLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZW5hYmxlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCSR0aGVtZSA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgkJJG5hbWUgID0gJHRoZW1lLT5nZXQoICdOYW1lJyApOwoKCQkjIElmIHRoZSAtLW5ldHdvcmsgZmxhZyBpcyBzZXQsIHdlJ2xsIGJlIGNhbGxpbmcgdGhlIChnZXR8dXBkYXRlKV9zaXRlX29wdGlvbiBmdW5jdGlvbnMKCQkkX3NpdGUgPSAhIGVtcHR5KCAkYXNzb2NfYXJnc1snbmV0d29yayddICkgPyAnX3NpdGUnIDogJyc7CgoJCSMgQWRkIHRoZSBjdXJyZW50IHRoZW1lIHRvIHRoZSBhbGxvd2VkIHRoZW1lcyBvcHRpb24gb3Igc2l0ZSBvcHRpb24KCQkkYWxsb3dlZF90aGVtZXMgPSBjYWxsX3VzZXJfZnVuYyggImdldHskX3NpdGV9X29wdGlvbiIsICdhbGxvd2VkdGhlbWVzJyApOwoJCWlmICggZW1wdHkoICRhbGxvd2VkX3RoZW1lcyApICkgewoJCQkkYWxsb3dlZF90aGVtZXMgPSBhcnJheSgpOwoJCX0KCQkkYWxsb3dlZF90aGVtZXNbICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSBdID0gdHJ1ZTsKCQljYWxsX3VzZXJfZnVuYyggInVwZGF0ZXskX3NpdGV9X29wdGlvbiIsICdhbGxvd2VkdGhlbWVzJywgJGFsbG93ZWRfdGhlbWVzICk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ25ldHdvcmsnXSApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJOZXR3b3JrIGVuYWJsZWQgdGhlICckbmFtZScgdGhlbWUuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIkVuYWJsZWQgdGhlICckbmFtZScgdGhlbWUuIiApOwoJCX0KCgkJIyBJZiB0aGUgLS1hY3RpdmF0ZSBmbGFnIGlzIHNldCwgYWN0aXZhdGUgdGhlIHRoZW1lIGZvciB0aGUgY3VycmVudCBzaXRlCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snYWN0aXZhdGUnXSApICkgewoJCQkkdGhpcy0+YWN0aXZhdGUoICRhcmdzICk7CgkJfQoJfQoKCS8qKgoJICogRGlzYWJsZXMgYSB0aGVtZSBvbiBhIFdvcmRQcmVzcyBtdWx0aXNpdGUgaW5zdGFsbC4KCSAqCgkgKiBSZW1vdmVzIGFiaWxpdHkgZm9yIGEgdGhlbWUgdG8gYmUgYWN0aXZhdGVkIGZyb20gdGhlIGRhc2hib2FyZCBvZiBhIHNpdGUKCSAqIG9uIGEgV29yZFByZXNzIG11bHRpc2l0ZSBpbnN0YWxsLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGhlbWU+CgkgKiA6IFRoZSB0aGVtZSB0byBkaXNhYmxlLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IElmIHNldCwgdGhlIHRoZW1lIGlzIGRpc2FibGVkIG9uIHRoZSBuZXR3b3JrIGxldmVsLiBOb3RlIHRoYXQKCSAqIGluZGl2aWR1YWwgc2l0ZXMgbWF5IHN0aWxsIGhhdmUgdGhpcyB0aGVtZSBlbmFibGVkIGlmIGl0IHdhcwoJICogZW5hYmxlZCBmb3IgdGhlbSBpbmRlcGVuZGVudGx5LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzYWJsZSB0aGVtZQoJICogICAgICQgd3AgdGhlbWUgZGlzYWJsZSB0d2VudHlzaXh0ZWVuCgkgKiAgICAgU3VjY2VzczogRGlzYWJsZWQgdGhlICdUd2VudHkgU2l4dGVlbicgdGhlbWUuCgkgKgoJICogICAgICMgRGlzYWJsZSB0aGVtZSBpbiBuZXR3b3JrIGxldmVsCgkgKiAgICAgJCB3cCB0aGVtZSBkaXNhYmxlIHR3ZW50eXNpeHRlZW4gLS1uZXR3b3JrCgkgKiAgICAgU3VjY2VzczogTmV0d29yayBkaXNhYmxlZCB0aGUgJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCX0KCgkJJHRoZW1lID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkbmFtZSAgPSAkdGhlbWUtPmdldCggJ05hbWUnICk7CgoJCSMgSWYgdGhlIC0tbmV0d29yayBmbGFnIGlzIHNldCwgd2UnbGwgYmUgY2FsbGluZyB0aGUgKGdldHx1cGRhdGUpX3NpdGVfb3B0aW9uIGZ1bmN0aW9ucwoJCSRfc2l0ZSA9ICEgZW1wdHkoICRhc3NvY19hcmdzWyduZXR3b3JrJ10gKSA/ICdfc2l0ZScgOiAnJzsKCgkJIyBBZGQgdGhlIGN1cnJlbnQgdGhlbWUgdG8gdGhlIGFsbG93ZWQgdGhlbWVzIG9wdGlvbiBvciBzaXRlIG9wdGlvbgoJCSRhbGxvd2VkX3RoZW1lcyA9IGNhbGxfdXNlcl9mdW5jKCAiZ2V0eyRfc2l0ZX1fb3B0aW9uIiwgJ2FsbG93ZWR0aGVtZXMnICk7CgkJaWYgKCAhIGVtcHR5KCAkYWxsb3dlZF90aGVtZXNbICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSBdICkgKSB7CgkJCXVuc2V0KCAkYWxsb3dlZF90aGVtZXNbICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSBdICk7CgkJfQoJCWNhbGxfdXNlcl9mdW5jKCAidXBkYXRleyRfc2l0ZX1fb3B0aW9uIiwgJ2FsbG93ZWR0aGVtZXMnLCAkYWxsb3dlZF90aGVtZXMgKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snbmV0d29yayddICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIk5ldHdvcmsgZGlzYWJsZWQgdGhlICckbmFtZScgdGhlbWUuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIkRpc2FibGVkIHRoZSAnJG5hbWUnIHRoZW1lLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBwYXRoIHRvIGEgdGhlbWUgb3IgdG8gdGhlIHRoZW1lIGRpcmVjdG9yeS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT5dCgkgKiA6IFRoZSB0aGVtZSB0byBnZXQgdGhlIHBhdGggdG8uIFBhdGggaW5jbHVkZXMgInN0eWxlLmNzcyIgZmlsZS4KCSAqIElmIG5vdCBzZXQsIHdpbGwgcmV0dXJuIHRoZSBwYXRoIHRvIHRoZSB0aGVtZXMgZGlyZWN0b3J5LgoJICoKCSAqIFstLWRpcl0KCSAqIDogSWYgc2V0LCBnZXQgdGhlIHBhdGggdG8gdGhlIGNsb3Nlc3QgcGFyZW50IGRpcmVjdG9yeSwgaW5zdGVhZCBvZiB0aGUKCSAqIHRoZW1lJ3MgInN0eWxlLmNzcyIgZmlsZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCB0aGVtZSBwYXRoCgkgKiAgICAgJCB3cCB0aGVtZSBwYXRoCgkgKiAgICAgL3Zhci93d3cvZXhhbXBsZS5jb20vcHVibGljX2h0bWwvd3AtY29udGVudC90aGVtZXMKCSAqCgkgKiAgICAgIyBDaGFuZ2UgZGlyZWN0b3J5IHRvIHRoZW1lIHBhdGgKCSAqICAgICAkIGNkICQod3AgdGhlbWUgcGF0aCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGgoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoIGVtcHR5KCAkYXJncyApICkgewoJCQkkcGF0aCA9IFdQX0NPTlRFTlRfRElSIC4gJy90aGVtZXMnOwoJCX0gZWxzZSB7CgkJCSR0aGVtZSA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgoJCQkkcGF0aCA9ICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5KCk7CgoJCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGlyJyApICkgewoJCQkJJHBhdGggLj0gJy9zdHlsZS5jc3MnOwoJCQl9CgkJfQoKCQlXUF9DTEk6OmxpbmUoICRwYXRoICk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGluc3RhbGxfZnJvbV9yZXBvKCAkc2x1ZywgJGFzc29jX2FyZ3MgKSB7CgkJJGFwaSA9IHRoZW1lc19hcGkoICd0aGVtZV9pbmZvcm1hdGlvbicsIGFycmF5KCAnc2x1ZycgPT4gJHNsdWcgKSApOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkYXBpICkgKSB7CgkJCXJldHVybiAkYXBpOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICkgewoJCQlzZWxmOjphbHRlcl9hcGlfcmVzcG9uc2UoICRhcGksICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKTsKCQl9CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKSApIHsKCQkJJHRoZW1lID0gd3BfZ2V0X3RoZW1lKCAkc2x1ZyApOwoJCQlpZiAoICR0aGVtZS0+ZXhpc3RzKCkgKSB7CgkJCQkvLyBXZSBrbm93IHRoaXMgd2lsbCBmYWlsLCBzbyBhdm9pZCBhIG5lZWRsZXNzIGRvd25sb2FkIG9mIHRoZSBwYWNrYWdlLgoJCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2FscmVhZHlfaW5zdGFsbGVkJywgJ1RoZW1lIGFscmVhZHkgaW5zdGFsbGVkLicgKTsKCQkJfQoJCQkvLyBDbGVhciBjYWNoZSBzbyBXUF9UaGVtZSBkb2Vzbid0IGNyZWF0ZSBhICJtaXNzaW5nIHRoZW1lIiBvYmplY3QuCgkJCSRjYWNoZV9oYXNoID0gbWQ1KCAkdGhlbWUtPnRoZW1lX3Jvb3QgLiAnLycgLiAkdGhlbWUtPnN0eWxlc2hlZXQgKTsKCQkJZm9yZWFjaCAoIFsgJ3RoZW1lJywgJ3NjcmVlbnNob3QnLCAnaGVhZGVycycsICdwYWdlX3RlbXBsYXRlcycgXSBhcyAka2V5ICkgewoJCQkJd3BfY2FjaGVfZGVsZXRlKCAka2V5IC4gJy0nIC4gJGNhY2hlX2hhc2gsICd0aGVtZXMnICk7CgkJCX0KCQl9CgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnSW5zdGFsbGluZyAlcyAoJXMpJywgaHRtbF9lbnRpdHlfZGVjb2RlKCAkYXBpLT5uYW1lLCBFTlRfUVVPVEVTICksICRhcGktPnZlcnNpb24gKSApOwoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndmVyc2lvbicgKSAhPT0gJ2RldicgKSB7CgkJCVdQX0NMSTo6Z2V0X2h0dHBfY2FjaGVfbWFuYWdlcigpLT53aGl0ZWxpc3RfcGFja2FnZSggJGFwaS0+ZG93bmxvYWRfbGluaywgJHRoaXMtPml0ZW1fdHlwZSwgJGFwaS0+c2x1ZywgJGFwaS0+dmVyc2lvbiApOwoJCX0KCgkJLy8gSWdub3JlIGZhaWx1cmVzIG9uIGFjY2Vzc2luZyBTU0wgImh0dHBzOi8vYXBpLndvcmRwcmVzcy5vcmcvdGhlbWVzL3VwZGF0ZS1jaGVjay8xLjEvIiBpbiBgd3BfdXBkYXRlX3RoZW1lcygpYCB3aGljaCBzZWVtIHRvIG9jY3VyIGludGVybWl0dGVudGx5LgoJCXNldF9lcnJvcl9oYW5kbGVyKCBhcnJheSggX19DTEFTU19fLCAnZXJyb3JfaGFuZGxlcicgKSwgRV9VU0VSX1dBUk5JTkcgfCBFX1VTRVJfTk9USUNFICk7CgoJCSRyZXN1bHQgPSAkdGhpcy0+Z2V0X3VwZ3JhZGVyKCAkYXNzb2NfYXJncyApLT5pbnN0YWxsKCAkYXBpLT5kb3dubG9hZF9saW5rICk7CgoJCXJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKCQlyZXR1cm4gJHJlc3VsdDsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2l0ZW1fbGlzdCgpIHsKCQlyZXR1cm4gJHRoaXMtPmdldF9hbGxfdGhlbWVzKCk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGZpbHRlcl9pdGVtX2xpc3QoICRpdGVtcywgJGFyZ3MgKSB7CgkJJHRoZW1lX2ZpbGVzID0gYXJyYXkoKTsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGFyZyApIHsKCQkJJHRoZW1lX2ZpbGVzW10gPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnICktPmdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpOwoJCX0KCgkJcmV0dXJuIFV0aWxzXHBpY2tfZmllbGRzKCAkaXRlbXMsICR0aGVtZV9maWxlcyApOwoJfQoKCS8qKgoJICogSW5zdGFsbHMgb25lIG9yIG1vcmUgdGhlbWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGhlbWV8emlwfHVybD4uLi4KCSAqIDogT25lIG9yIG1vcmUgdGhlbWVzIHRvIGluc3RhbGwuIEFjY2VwdHMgYSB0aGVtZSBzbHVnLCB0aGUgcGF0aCB0byBhIGxvY2FsIHppcCBmaWxlLCBvciBhIFVSTCB0byBhIHJlbW90ZSB6aXAgZmlsZS4KCSAqCgkgKiBbLS12ZXJzaW9uPTx2ZXJzaW9uPl0KCSAqIDogSWYgc2V0LCBnZXQgdGhhdCBwYXJ0aWN1bGFyIHZlcnNpb24gZnJvbSB3b3JkcHJlc3Mub3JnLCBpbnN0ZWFkIG9mIHRoZQoJICogc3RhYmxlIHZlcnNpb24uCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IElmIHNldCwgdGhlIGNvbW1hbmQgd2lsbCBvdmVyd3JpdGUgYW55IGluc3RhbGxlZCB2ZXJzaW9uIG9mIHRoZSB0aGVtZSwgd2l0aG91dCBwcm9tcHRpbmcKCSAqIGZvciBjb25maXJtYXRpb24uCgkgKgoJICogWy0tYWN0aXZhdGVdCgkgKiA6IElmIHNldCwgdGhlIHRoZW1lIHdpbGwgYmUgYWN0aXZhdGVkIGltbWVkaWF0ZWx5IGFmdGVyIGluc3RhbGwuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkcyB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbnN0YWxsIHRoZSBsYXRlc3QgdmVyc2lvbiBmcm9tIHdvcmRwcmVzcy5vcmcgYW5kIGFjdGl2YXRlCgkgKiAgICAgJCB3cCB0aGVtZSBpbnN0YWxsIHR3ZW50eXNpeHRlZW4gLS1hY3RpdmF0ZQoJICogICAgIEluc3RhbGxpbmcgVHdlbnR5IFNpeHRlZW4gKDEuMikKCSAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdGhlbWUvdHdlbnR5c2l4dGVlbi4xLjIuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSBwYWNrYWdlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgdGhlbWUuLi4KCSAqICAgICBUaGVtZSBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIEFjdGl2YXRpbmcgJ3R3ZW50eXNpeHRlZW4nLi4uCgkgKiAgICAgU3VjY2VzczogU3dpdGNoZWQgdG8gJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KCSAqCgkgKiAgICAgIyBJbnN0YWxsIGZyb20gYSBsb2NhbCB6aXAgZmlsZQoJICogICAgICQgd3AgdGhlbWUgaW5zdGFsbCAuLi9teS10aGVtZS56aXAKCSAqCgkgKiAgICAgIyBJbnN0YWxsIGZyb20gYSByZW1vdGUgemlwIGZpbGUKCSAqICAgICAkIHdwIHRoZW1lIGluc3RhbGwgaHR0cDovL3MzLmFtYXpvbmF3cy5jb20vYnVja2V0bmFtZS9teS10aGVtZS56aXA/QVdTQWNjZXNzS2V5SWQ9MTIzJkV4cGlyZXM9NDU2JlNpZ25hdHVyZT1hYmNkZWYKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJHRoZW1lX3Jvb3QgPSBnZXRfdGhlbWVfcm9vdCgpOwoJCWlmICggJHRoZW1lX3Jvb3QgJiYgISBpc19kaXIoICR0aGVtZV9yb290ICkgKSB7CgkJCXdwX21rZGlyX3AoICR0aGVtZV9yb290ICk7CgkJCXJlZ2lzdGVyX3RoZW1lX2RpcmVjdG9yeSggJHRoZW1lX3Jvb3QgKTsKCQl9CgoJCXBhcmVudDo6aW5zdGFsbCggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGRldGFpbHMgYWJvdXQgYSB0aGVtZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRoZW1lPgoJICogOiBUaGUgdGhlbWUgdG8gZ2V0LgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSB0aGVtZSwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB0aGVtZSBnZXQgdHdlbnR5c2l4dGVlbiAtLWZpZWxkcz1uYW1lLHRpdGxlLHZlcnNpb24KCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBGaWVsZCAgIHwgVmFsdWUgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgfCBUd2VudHkgU2l4dGVlbiB8CgkgKiAgICAgfCB0aXRsZSAgIHwgVHdlbnR5IFNpeHRlZW4gfAoJICogICAgIHwgdmVyc2lvbiB8IDEuMiAgICAgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhlbWUgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoKCQkkZXJyb3JzID0gJHRoZW1lLT5lcnJvcnMoKTsKCQlpZiAoIGlzX3dwX2Vycm9yKCAkZXJyb3JzICkgKSB7CgkJCSRtZXNzYWdlID0gJGVycm9ycy0+Z2V0X2Vycm9yX21lc3NhZ2UoKTsKCQkJV1BfQ0xJOjplcnJvciggJG1lc3NhZ2UgKTsKCQl9CgoJCS8vIFdQX1RoZW1lIG9iamVjdCBlbXBsb3lzIG1hZ2ljIGdldHRlciwgdW5mb3J0dW5hdGVseS4KCQkkdGhlbWVfdmFycyA9IFsKCQkJJ25hbWUnLAoJCQkndGl0bGUnLAoJCQkndmVyc2lvbicsCgkJCSdzdGF0dXMnLAoJCQkncGFyZW50X3RoZW1lJywKCQkJJ3RlbXBsYXRlX2RpcicsCgkJCSdzdHlsZXNoZWV0X2RpcicsCgkJCSd0ZW1wbGF0ZScsCgkJCSdzdHlsZXNoZWV0JywKCQkJJ3NjcmVlbnNob3QnLAoJCQknZGVzY3JpcHRpb24nLAoJCQknYXV0aG9yJywKCQkJJ3RhZ3MnLAoJCQkndGhlbWVfcm9vdCcsCgkJCSd0aGVtZV9yb290X3VyaScsCgkJXTsKCQkkdGhlbWVfb2JqICA9IG5ldyBzdGRDbGFzcygpOwoJCWZvcmVhY2ggKCAkdGhlbWVfdmFycyBhcyAkdmFyICkgewoJCQkkdGhlbWVfb2JqLT4kdmFyID0gJHRoZW1lLT4kdmFyOwoJCX0KCgkJJHRoZW1lX29iai0+c3RhdHVzICAgICAgPSAkdGhpcy0+Z2V0X3N0YXR1cyggJHRoZW1lICk7CgkJJHRoZW1lX29iai0+ZGVzY3JpcHRpb24gPSB3b3Jkd3JhcCggJHRoZW1lX29iai0+ZGVzY3JpcHRpb24gKTsKCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9ICR0aGVtZV92YXJzOwoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbSggJHRoZW1lX29iaiApOwoJfQoKCS8qKgoJICogVXBkYXRlcyBvbmUgb3IgbW9yZSB0aGVtZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGhlbWU+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gdXBkYXRlLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgdGhlbWVzIHRoYXQgaGF2ZSB1cGRhdGVzIHdpbGwgYmUgdXBkYXRlZC4KCSAqCgkgKiBbLS1leGNsdWRlPTx0aGVtZS1uYW1lcz5dCgkgKiA6IENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIHRoZW1lIG5hbWVzIHRoYXQgc2hvdWxkIGJlIGV4Y2x1ZGVkIGZyb20gdXBkYXRpbmcuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHN1bW1hcnkKCSAqIC0tLQoJICoKCSAqIFstLXZlcnNpb249PHZlcnNpb24+XQoJICogOiBJZiBzZXQsIHRoZSB0aGVtZSB3aWxsIGJlIHVwZGF0ZWQgdG8gdGhlIHNwZWNpZmllZCB2ZXJzaW9uLgoJICoKCSAqIFstLWRyeS1ydW5dCgkgKiA6IFByZXZpZXcgd2hpY2ggdGhlbWVzIHdvdWxkIGJlIHVwZGF0ZWQuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkcyB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgbXVsdGlwbGUgdGhlbWVzCgkgKiAgICAgJCB3cCB0aGVtZSB1cGRhdGUgdHdlbnR5ZmlmdGVlbiB0d2VudHlzaXh0ZWVuCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90aGVtZS90d2VudHlmaWZ0ZWVuLjEuNS56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIGxhdGVzdCB2ZXJzaW9uLi4uCgkgKiAgICAgUmVtb3ZpbmcgdGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSB0aGVtZS4uLgoJICogICAgIFRoZW1lIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIERvd25sb2FkaW5nIHVwZGF0ZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdGhlbWUvdHdlbnR5c2l4dGVlbi4xLjIuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFJlbW92aW5nIHRoZSBvbGQgdmVyc2lvbiBvZiB0aGUgdGhlbWUuLi4KCSAqICAgICBUaGVtZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgIHwgb2xkX3ZlcnNpb24gfCBuZXdfdmVyc2lvbiB8IHN0YXR1cyAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IHR3ZW50eWZpZnRlZW4gfCAxLjQgICAgICAgICB8IDEuNSAgICAgICAgIHwgVXBkYXRlZCB8CgkgKiAgICAgfCB0d2VudHlzaXh0ZWVuIHwgMS4xICAgICAgICAgfCAxLjIgICAgICAgICB8IFVwZGF0ZWQgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIDIgb2YgMiB0aGVtZXMuCgkgKgoJICogICAgICMgRXhjbHVkZSB0aGVtZXMgdXBkYXRlcyB3aGVuIGJ1bGsgdXBkYXRpbmcgdGhlIHRoZW1lcwoJICogICAgICQgd3AgdGhlbWUgdXBkYXRlIC0tYWxsIC0tZXhjbHVkZT10d2VudHlmaWZ0ZWVuCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90aGVtZS9hc3RyYS4xLjAuNS4xLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgbGF0ZXN0IHZlcnNpb24uLi4KCSAqICAgICBSZW1vdmluZyB0aGUgb2xkIHZlcnNpb24gb2YgdGhlIHRoZW1lLi4uCgkgKiAgICAgVGhlbWUgdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90aGVtZS90d2VudHlzZXZlbnRlZW4uMS4yLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgbGF0ZXN0IHZlcnNpb24uLi4KCSAqICAgICBSZW1vdmluZyB0aGUgb2xkIHZlcnNpb24gb2YgdGhlIHRoZW1lLi4uCgkgKiAgICAgVGhlbWUgdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgICAgfCBzdGF0dXMgICB8IHZlcnNpb24gfCB1cGRhdGVfdmVyc2lvbiB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBhc3RyYSAgICAgICAgICAgfCBpbmFjdGl2ZSB8IDEuMC4xICAgfCAxLjAuNS4xICAgICAgICB8CgkgKiAgICAgfCB0d2VudHlzZXZlbnRlZW4gfCBpbmFjdGl2ZSB8IDEuMSAgICAgfCAxLjIgICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAyIG9mIDIgdGhlbWVzLgoJICoKCSAqICAgICAjIFVwZGF0ZSBhbGwgdGhlbWVzCgkgKiAgICAgJCB3cCB0aGVtZSB1cGRhdGUgLS1hbGwKCSAqCgkgKiBAYWxpYXMgdXBncmFkZQoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSAmJiBpc3NldCggJGFzc29jX2FyZ3NbJ2RyeS1ydW4nXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnLS1kcnktcnVuIGNhbm5vdCBiZSB1c2VkIHRvZ2V0aGVyIHdpdGggLS12ZXJzaW9uLicgKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSApIHsKCQkJZm9yZWFjaCAoICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKSBhcyAkdGhlbWUgKSB7CgkJCQkkciA9IGRlbGV0ZV90aGVtZSggJHRoZW1lLT5zdHlsZXNoZWV0ICk7CgkJCQlpZiAoIGlzX3dwX2Vycm9yKCAkciApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggJHIgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJGFzc29jX2FyZ3NbJ2ZvcmNlJ10gPSB0cnVlOwoJCQkJCSR0aGlzLT5pbnN0YWxsKCBhcnJheSggJHRoZW1lLT5zdHlsZXNoZWV0ICksICRhc3NvY19hcmdzICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlwYXJlbnQ6OnVwZGF0ZV9tYW55KCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYSBnaXZlbiB0aGVtZSBpcyBpbnN0YWxsZWQuCgkgKgoJICogUmV0dXJucyBleGl0IGNvZGUgMCB3aGVuIGluc3RhbGxlZCwgMSB3aGVuIHVuaW5zdGFsbGVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGhlbWU+CgkgKiA6IFRoZSB0aGVtZSB0byBjaGVjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgdGhlbWUgaXMgaW5zdGFsbGVkOyBleGl0IHN0YXR1cyAwIGlmIGluc3RhbGxlZCwgb3RoZXJ3aXNlIDEKCSAqICAgICAkIHdwIHRoZW1lIGlzLWluc3RhbGxlZCBoZWxsbwoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiBAc3ViY29tbWFuZCBpcy1pbnN0YWxsZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2luc3RhbGxlZCggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkdGhlbWUgPSB3cF9nZXRfdGhlbWUoICRhcmdzWzBdICk7CgoJCWlmICggJHRoZW1lLT5leGlzdHMoKSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAwICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgZ2l2ZW4gdGhlbWUgaXMgYWN0aXZlLgoJICoKCSAqIFJldHVybnMgZXhpdCBjb2RlIDAgd2hlbiBhY3RpdmUsIDEgd2hlbiBub3QgYWN0aXZlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGhlbWU+CgkgKiA6IFRoZSBwbHVnaW4gdG8gY2hlY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIHRoZW1lIGlzIEFjdGl2ZTsgZXhpdCBzdGF0dXMgMCBpZiBhY3RpdmUsIG90aGVyd2lzZSAxCgkgKiAgICAgJCB3cCB0aGVtZSBpcy1hY3RpdmUgdHdlbnR5ZmlmdGVlbgoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiBAc3ViY29tbWFuZCBpcy1hY3RpdmUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2FjdGl2ZSggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkdGhlbWUgPSB3cF9nZXRfdGhlbWUoICRhcmdzWzBdICk7CgoJCWlmICggISAkdGhlbWUtPmV4aXN0cygpICkgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9CgoJCSR0aGlzLT5pc19hY3RpdmVfdGhlbWUoICR0aGVtZSApID8gV1BfQ0xJOjpoYWx0KCAwICkgOiBXUF9DTEk6OmhhbHQoIDEgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgb25lIG9yIG1vcmUgdGhlbWVzLgoJICoKCSAqIFJlbW92ZXMgdGhlIHRoZW1lIG9yIHRoZW1lcyBmcm9tIHRoZSBmaWxlc3lzdGVtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHRoZW1lPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgdGhlbWVzIHRvIGRlbGV0ZS4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgYWxsIHRoZW1lcyB3aWxsIGJlIGRlbGV0ZWQgZXhjZXB0IGFjdGl2ZSB0aGVtZS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogVG8gZGVsZXRlIGFjdGl2ZSB0aGVtZSB1c2UgdGhpcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHRoZW1lIGRlbGV0ZSB0d2VudHl0d2VsdmUKCSAqICAgICBEZWxldGVkICd0d2VudHl0d2VsdmUnIHRoZW1lLgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMSBvZiAxIHRoZW1lcy4KCSAqCgkgKiBAYWxpYXMgdW5pbnN0YWxsCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGFsbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwsICdkZWxldGUnICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkZm9yY2UgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScsIGZhbHNlICk7CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCWZvcmVhY2ggKCAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICkgYXMgJHRoZW1lICkgewoJCQkkdGhlbWVfc2x1ZyA9ICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKTsKCgkJCWlmICggJHRoaXMtPmlzX2FjdGl2ZV90aGVtZSggJHRoZW1lICkgJiYgISAkZm9yY2UgKSB7CgkJCQlpZiAoICEgJGFsbCApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICJDYW4ndCBkZWxldGUgdGhlIGN1cnJlbnRseSBhY3RpdmUgdGhlbWU6ICR0aGVtZV9zbHVnIiApOwoJCQkJCSRlcnJvcnMrKzsKCQkJCX0KCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkciA9IGRlbGV0ZV90aGVtZSggJHRoZW1lX3NsdWcgKTsKCgkJCWlmICggaXNfd3BfZXJyb3IoICRyICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRyICk7CgkJCQkkZXJyb3JzKys7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZyggIkRlbGV0ZWQgJyR0aGVtZV9zbHVnJyB0aGVtZS4iICk7CgkJCQkkc3VjY2Vzc2VzKys7CgkJCX0KCQl9CgkJaWYgKCAhICR0aGlzLT5jaGFpbmVkX2NvbW1hbmQgKSB7CgkJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ3RoZW1lJywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyBhIGxpc3Qgb2YgdGhlbWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEZpbHRlciByZXN1bHRzIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiBhIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggdGhlbWUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogWy0tc3RhdHVzPTxzdGF0dXM+XQoJICogOiBGaWx0ZXIgdGhlIG91dHB1dCBieSB0aGVtZSBzdGF0dXMuCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0gYWN0aXZlCgkgKiAgIC0gcGFyZW50CgkgKiAgIC0gaW5hY3RpdmUKCSAqIC0tLQoJICoKCSAqIFstLXNraXAtdXBkYXRlLWNoZWNrXQoJICogOiBJZiBzZXQsIHRoZSB0aGVtZSB1cGRhdGUgY2hlY2sgd2lsbCBiZSBza2lwcGVkLgoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCB0aGVtZToKCSAqCgkgKiAqIG5hbWUKCSAqICogc3RhdHVzCgkgKiAqIHVwZGF0ZQoJICogKiB2ZXJzaW9uCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHVwZGF0ZV92ZXJzaW9uCgkgKiAqIHVwZGF0ZV9wYWNrYWdlCgkgKiAqIHVwZGF0ZV9pZAoJICogKiB0aXRsZQoJICogKiBkZXNjcmlwdGlvbgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCB0aGVtZXMKCSAqICAgICAkIHdwIHRoZW1lIGxpc3QgLS1zdGF0dXM9aW5hY3RpdmUgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbmFtZSxzdGF0dXMsdXBkYXRlLHZlcnNpb24KCSAqICAgICB0d2VudHlmb3VydGVlbixpbmFjdGl2ZSxub25lLDEuNwoJICogICAgIHR3ZW50eXNpeHRlZW4saW5hY3RpdmUsYXZhaWxhYmxlLDEuMQoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJcGFyZW50OjpfbGlzdCggJF8sICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB0ZW1wbGF0ZSBwYXRoIGJhc2VkIG9uIGluc3RhbGxhdGlvbiB0eXBlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfdGVtcGxhdGVfcGF0aCggJHRlbXBsYXRlICkgewoJCSRjb21tYW5kX3Jvb3QgID0gVXRpbHNccGhhcl9zYWZlX3BhdGgoIGRpcm5hbWUoIF9fRElSX18gKSApOwoJCSR0ZW1wbGF0ZV9wYXRoID0gInskY29tbWFuZF9yb290fS90ZW1wbGF0ZXMveyR0ZW1wbGF0ZX0iOwoKCQlpZiAoICEgZmlsZV9leGlzdHMoICR0ZW1wbGF0ZV9wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBmaW5kIHskdGVtcGxhdGV9IiApOwoJCX0KCgkJcmV0dXJuICR0ZW1wbGF0ZV9wYXRoOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXEZldGNoZXJzXFRoZW1lOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxQYXJzZVRoZW1lTmFtZUlucHV0Owp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIE1hbmFnZXMgdGhlbWUgYXV0by11cGRhdGVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBFbmFibGUgdGhlIGF1dG8tdXBkYXRlcyBmb3IgYSB0aGVtZQogKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZW5hYmxlIHR3ZW50eXNpeHRlZW4KICogICAgIFRoZW1lIGF1dG8tdXBkYXRlcyBmb3IgJ3R3ZW50eXNpeHRlZW4nIGVuYWJsZWQuCiAqICAgICBTdWNjZXNzOiBFbmFibGVkIDEgb2YgMSB0aGVtZSBhdXRvLXVwZGF0ZXMuCiAqCiAqICAgICAjIERpc2FibGUgdGhlIGF1dG8tdXBkYXRlcyBmb3IgYSB0aGVtZQogKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZGlzYWJsZSB0d2VudHlzaXh0ZWVuCiAqICAgICBUaGVtZSBhdXRvLXVwZGF0ZXMgZm9yICd0d2VudHlzaXh0ZWVuJyBkaXNhYmxlZC4KICogICAgIFN1Y2Nlc3M6IERpc2FibGVkIDEgb2YgMSB0aGVtZSBhdXRvLXVwZGF0ZXMuCiAqCiAqICAgICAjIEdldCB0aGUgc3RhdHVzIG9mIHRoZW1lIGF1dG8tdXBkYXRlcwogKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgc3RhdHVzIHR3ZW50eXNpeHRlZW4KICogICAgIEF1dG8tdXBkYXRlcyBmb3IgdGhlbWUgJ3R3ZW50eXNpeHRlZW4nIGFyZSBkaXNhYmxlZC4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBUaGVtZV9BdXRvVXBkYXRlc19Db21tYW5kIHsKCgl1c2UgUGFyc2VUaGVtZU5hbWVJbnB1dDsKCgkvKioKCSAqIFNpdGUgb3B0aW9uIHRoYXQgc3RvcmVzIHRoZSBzdGF0dXMgb2YgdGhlbWUgYXV0by11cGRhdGVzLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFNJVEVfT1BUSU9OID0gJ2F1dG9fdXBkYXRlX3RoZW1lcyc7CgoJLyoqCgkgKiBUaGVtZSBmZXRjaGVyIGluc3RhbmNlLgoJICoKCSAqIEB2YXIgVGhlbWUKCSAqLwoJcHJvdGVjdGVkICRmZXRjaGVyOwoKCS8qKgoJICogVGhlbWVfQXV0b1VwZGF0ZXNfQ29tbWFuZCBjb25zdHJ1Y3Rvci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFRoZW1lKCk7Cgl9CgoJLyoqCgkgKiBFbmFibGVzIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGhlbWU+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gZW5hYmxlIGF1dG8tdXBkYXRlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF1dG8tdXBkYXRlcyB3aWxsIGJlIGVuYWJsZWQgZm9yIGFsbCB0aGVtZXMuCgkgKgoJICogWy0tZGlzYWJsZWQtb25seV0KCSAqIDogSWYgc2V0LCBmaWx0ZXJzIGxpc3Qgb2YgdGhlbWVzIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBkaXNhYmxlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEVuYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHRoZW1lCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZW5hYmxlIHR3ZW50eXNpeHRlZW4KCSAqICAgICBUaGVtZSBhdXRvLXVwZGF0ZXMgZm9yICd0d2VudHlzaXh0ZWVuJyBlbmFibGVkLgoJICogICAgIFN1Y2Nlc3M6IEVuYWJsZWQgMSBvZiAxIHRoZW1lIGF1dG8tdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVuYWJsZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZGlzYWJsZWRfb25seSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc2FibGVkLW9ubHknLCBmYWxzZSApOwoKCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkdGhlbWVzICAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCSRhdXRvX3VwZGF0ZXMgPSBnZXRfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04gKTsKCgkJaWYgKCBmYWxzZSA9PT0gJGF1dG9fdXBkYXRlcyApIHsKCQkJJGF1dG9fdXBkYXRlcyA9IFtdOwoJCX0KCgkJJGNvdW50ICAgICA9IDA7CgkJJHN1Y2Nlc3NlcyA9IDA7CgoJCWZvcmVhY2ggKCAkdGhlbWVzIGFzICR0aGVtZSApIHsKCQkJJGVuYWJsZWQgPSBpbl9hcnJheSggJHRoZW1lLT5zdHlsZXNoZWV0LCAkYXV0b191cGRhdGVzLCB0cnVlICk7CgoJCQlpZiAoICRkaXNhYmxlZF9vbmx5ICYmICRlbmFibGVkICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRjb3VudCsrOwoKCQkJaWYgKCAkZW5hYmxlZCApIHsKCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQkiQXV0by11cGRhdGVzIGFscmVhZHkgZW5hYmxlZCBmb3IgdGhlbWUgeyR0aGVtZS0+c3R5bGVzaGVldH0uIgoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCSRhdXRvX3VwZGF0ZXNbXSA9ICR0aGVtZS0+c3R5bGVzaGVldDsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAwID09PSAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknTm8gdGhlbWVzIHByb3ZpZGVkIHRvIGVuYWJsZSBhdXRvLXVwZGF0ZXMgZm9yLicKCQkJKTsKCQl9CgoJCXVwZGF0ZV9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiwgJGF1dG9fdXBkYXRlcyApOwoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSd0aGVtZSBhdXRvLXVwZGF0ZScsCgkJCSdlbmFibGUnLAoJCQkkY291bnQsCgkJCSRzdWNjZXNzZXMsCgkJCSRjb3VudCAtICRzdWNjZXNzZXMKCQkpOwoJfQoKCS8qKgoJICogRGlzYWJsZXMgdGhlIGF1dG8tdXBkYXRlcyBmb3IgYSB0aGVtZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHRoZW1lcyB0byBkaXNhYmxlIGF1dG8tdXBkYXRlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF1dG8tdXBkYXRlcyB3aWxsIGJlIGRpc2FibGVkIGZvciBhbGwgdGhlbWVzLgoJICoKCSAqIFstLWVuYWJsZWQtb25seV0KCSAqIDogSWYgc2V0LCBmaWx0ZXJzIGxpc3Qgb2YgdGhlbWVzIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBlbmFibGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHRoZW1lCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZGlzYWJsZSB0d2VudHlzaXh0ZWVuCgkgKiAgICAgVGhlbWUgYXV0by11cGRhdGVzIGZvciAndHdlbnR5c2l4dGVlbicgZGlzYWJsZWQuCgkgKiAgICAgU3VjY2VzczogRGlzYWJsZWQgMSBvZiAxIHRoZW1lIGF1dG8tdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZW5hYmxlZF9vbmx5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlZC1vbmx5JywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHRoZW1lcyAgICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQkkYXV0b191cGRhdGVzID0gZ2V0X3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OICk7CgoJCWlmICggZmFsc2UgPT09ICRhdXRvX3VwZGF0ZXMgKSB7CgkJCSRhdXRvX3VwZGF0ZXMgPSBbXTsKCQl9CgoJCSRjb3VudCAgICAgPSAwOwoJCSRzdWNjZXNzZXMgPSAwOwoKCQlmb3JlYWNoICggJHRoZW1lcyBhcyAkdGhlbWUgKSB7CgkJCSRlbmFibGVkID0gaW5fYXJyYXkoICR0aGVtZS0+c3R5bGVzaGVldCwgJGF1dG9fdXBkYXRlcywgdHJ1ZSApOwoKCQkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICEgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvdW50Kys7CgoJCQlpZiAoICEgJGVuYWJsZWQgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJIkF1dG8tdXBkYXRlcyBhbHJlYWR5IGRpc2FibGVkIGZvciB0aGVtZSB7JHRoZW1lLT5zdHlsZXNoZWV0fS4iCgkJCQkpOwoJCQl9IGVsc2UgewoJCQkJJGF1dG9fdXBkYXRlcyA9IGFycmF5X2RpZmYoICRhdXRvX3VwZGF0ZXMsIFsgJHRoZW1lLT5zdHlsZXNoZWV0IF0gKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAwID09PSAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknTm8gdGhlbWVzIHByb3ZpZGVkIHRvIGRpc2FibGUgYXV0by11cGRhdGVzIGZvci4nCgkJCSk7CgkJfQoKCQlpZiAoIGNvdW50KCAkYXV0b191cGRhdGVzICkgPiAwICkgewoJCQl1cGRhdGVfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04sICRhdXRvX3VwZGF0ZXMgKTsKCQl9IGVsc2UgewoJCQlkZWxldGVfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04gKTsKCQl9CgoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cygKCQkJJ3RoZW1lIGF1dG8tdXBkYXRlJywKCQkJJ2Rpc2FibGUnLAoJCQkkY291bnQsCgkJCSRzdWNjZXNzZXMsCgkJCSRjb3VudCAtICRzdWNjZXNzZXMKCQkpOwoJfQoKCS8qKgoJICogU2hvd3MgdGhlIHN0YXR1cyBvZiBhdXRvLXVwZGF0ZXMgZm9yIGEgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGhlbWU+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gc2hvdyB0aGUgc3RhdHVzIG9mIHRoZSBhdXRvLXVwZGF0ZXMgb2YuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIHRoZSBzdGF0dXMgb2YgYXV0by11cGRhdGVzIGZvciBhbGwgdGhlbWVzIHdpbGwgYmUgc2hvd24uCgkgKgoJICogWy0tZW5hYmxlZC1vbmx5XQoJICogOiBJZiBzZXQsIGZpbHRlcnMgbGlzdCBvZiB0aGVtZXMgdG8gb25seSBpbmNsdWRlIHRoZSBvbmVzIHRoYXQgaGF2ZQoJICogYXV0by11cGRhdGVzIGVuYWJsZWQuCgkgKgoJICogWy0tZGlzYWJsZWQtb25seV0KCSAqIDogSWYgc2V0LCBmaWx0ZXJzIGxpc3Qgb2YgdGhlbWVzIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBkaXNhYmxlZC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBPbmx5IHNob3cgdGhlIHByb3ZpZGVkIGZpZWxkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHRoZSBzdGF0dXMgb2YgdGhlbWUgYXV0by11cGRhdGVzCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgc3RhdHVzIHR3ZW50eXNpeHRlZW4KCSAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgIHwgc3RhdHVzICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IHR3ZW50eXNpeHRlZW4gfCBkaXNhYmxlZCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIEdldCB0aGUgbGlzdCBvZiB0aGVtZXMgdGhhdCBoYXZlIGF1dG8tdXBkYXRlcyBlbmFibGVkCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgc3RhdHVzIC0tYWxsIC0tZW5hYmxlZC1vbmx5IC0tZmllbGQ9bmFtZQoJICogICAgIHR3ZW50eXNpeHRlZW4KCSAqICAgICB0d2VudHlzZXZlbnRlZW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHN0YXR1cyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZW5hYmxlZF9vbmx5ICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2VuYWJsZWQtb25seScsIGZhbHNlICk7CgkJJGRpc2FibGVkX29ubHkgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXNhYmxlZC1vbmx5JywgZmFsc2UgKTsKCgkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICRkaXNhYmxlZF9vbmx5ICkgewoJCQlXUF9DTEk6OmVycm9yKAoJCQkJJy0tZW5hYmxlZC1vbmx5IGFuZCAtLWRpc2FibGVkLW9ubHkgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSBhbmQgJwoJCQkJLiAnY2Fubm90IGJlIHVzZWQgYXQgdGhlIHNhbWUgdGltZS4nCgkJCSk7CgkJfQoKCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkdGhlbWVzICAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCSRhdXRvX3VwZGF0ZXMgPSBnZXRfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04gKTsKCgkJaWYgKCBmYWxzZSA9PT0gJGF1dG9fdXBkYXRlcyApIHsKCQkJJGF1dG9fdXBkYXRlcyA9IFtdOwoJCX0KCgkJJHJlc3VsdHMgPSBbXTsKCgkJZm9yZWFjaCAoICR0aGVtZXMgYXMgJHRoZW1lICkgewoJCQkkZW5hYmxlZCA9IGluX2FycmF5KCAkdGhlbWUtPnN0eWxlc2hlZXQsICRhdXRvX3VwZGF0ZXMsIHRydWUgKTsKCgkJCWlmICggJGVuYWJsZWRfb25seSAmJiAhICRlbmFibGVkICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggJGRpc2FibGVkX29ubHkgJiYgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJlc3VsdHNbXSA9IFsKCQkJCSduYW1lJyAgID0+ICR0aGVtZS0+c3R5bGVzaGVldCwKCQkJCSduYW1lCgkJCScgICAgICAgICAgICA9PiAkdGhlbWUtPnN0eWxlc2hlZXQsCgkJCQknc3RhdHVzJyA9PiAkZW5hYmxlZCA/ICdlbmFibGVkJyA6ICdkaXNhYmxlZCcsCgkJCV07CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIFsgJ25hbWUnLCAnc3RhdHVzJyBdLCAndGhlbWUnICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHJlc3VsdHMgKTsKCX0KfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2V4dGVuc2lvbl9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9leHRlbnNpb25fYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9leHRlbnNpb25fYXV0b2xvYWRlcjsKfQoKJHdwY2xpX2V4dGVuc2lvbl9yZXF1aXJlc193cF81XzUgPSBbCgknYmVmb3JlX2ludm9rZScgPT4gc3RhdGljIGZ1bmN0aW9uICgpIHsKCQlpZiAoIFdQX0NMSVxVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc1LjUnLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1JlcXVpcmVzIFdvcmRQcmVzcyA1LjUgb3IgZ3JlYXRlci4nICk7CgkJfQoJfSwKXTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdwbHVnaW4nLCAnUGx1Z2luX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdwbHVnaW4gYXV0by11cGRhdGVzJywgJ1BsdWdpbl9BdXRvVXBkYXRlc19Db21tYW5kJywgJHdwY2xpX2V4dGVuc2lvbl9yZXF1aXJlc193cF81XzUgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3RoZW1lJywgJ1RoZW1lX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd0aGVtZSBhdXRvLXVwZGF0ZXMnLCAnVGhlbWVfQXV0b1VwZGF0ZXNfQ29tbWFuZCcsICR3cGNsaV9leHRlbnNpb25fcmVxdWlyZXNfd3BfNV81ICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd0aGVtZSBtb2QnLCAnVGhlbWVfTW9kX0NvbW1hbmQnICk7Cjw/cGhwCgpjbGFzcyBXUF9NYXBfSXRlcmF0b3IgZXh0ZW5kcyBJdGVyYXRvckl0ZXJhdG9yIHsKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGl0ZXJhdG9yLCAkY2FsbGJhY2sgKSB7CgkJJHRoaXMtPmNhbGxiYWNrID0gJGNhbGxiYWNrOwoJCXBhcmVudDo6X19jb25zdHJ1Y3QoICRpdGVyYXRvciApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkgewoJCSRvcmlnaW5hbF9jdXJyZW50ID0gcGFyZW50OjpjdXJyZW50KCk7CgkJcmV0dXJuIGNhbGxfdXNlcl9mdW5jKCAkdGhpcy0+Y2FsbGJhY2ssICRvcmlnaW5hbF9jdXJyZW50ICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIENoYW5naW5nIGJyZWFrcyBQaGFyIGNvbXBhdC4KZGVmaW5lKCAnV1BfQ0xJX0VYUE9SVF9DT01NQU5EX05PX1NQTElUJywgJy0xJyApOwoKLyoqCiAqIEV4cG9ydHMgV29yZFByZXNzIGNvbnRlbnQgdG8gYSBXWFIgZmlsZS4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgRXhwb3J0IHBvc3RzIHB1Ymxpc2hlZCBieSB0aGUgdXNlciBiZXR3ZWVuIGdpdmVuIHN0YXJ0IGFuZCBlbmQgZGF0ZQogKiAgICAgJCB3cCBleHBvcnQgLS1kaXI9L3RtcC8gLS11c2VyPWFkbWluIC0tcG9zdF90eXBlPXBvc3QgLS1zdGFydF9kYXRlPTIwMTEtMDEtMDEgLS1lbmRfZGF0ZT0yMDExLTEyLTMxCiAqICAgICBTdGFydGluZyBleHBvcnQgcHJvY2Vzcy4uLgogKiAgICAgV3JpdGluZyB0byBmaWxlIC90bXAvc3RhZ2luZy53b3JkcHJlc3MuMjAxNi0wNS0yNC4wMDAueG1sCiAqICAgICBTdWNjZXNzOiBBbGwgZG9uZSB3aXRoIGV4cG9ydC4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBFeHBvcnRfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSogSW5pdGlhbGl6ZSB0aGUgYXJyYXkgb2YgYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBldmVudHVhbGx5IGJlIHBhc3NlZCB0byBleHBvcnRfd3AuCgkqCgkqIEB2YXIgYXJyYXkKCSovCglwdWJsaWMgJGV4cG9ydF9hcmdzID0gW107CgoJcHJpdmF0ZSAkc3Rkb3V0OwoJcHJpdmF0ZSAkbWF4X2ZpbGVfc2l6ZTsKCXByaXZhdGUgJHd4cl9wYXRoOwoKCS8qKgoJICogRXhwb3J0cyBXb3JkUHJlc3MgY29udGVudCB0byBhIFdYUiBmaWxlLgoJICoKCSAqIEdlbmVyYXRlcyBvbmUgb3IgbW9yZSBXWFIgZmlsZXMgY29udGFpbmluZyBhdXRob3JzLCB0ZXJtcywgcG9zdHMsCgkgKiBjb21tZW50cywgYW5kIGF0dGFjaG1lbnRzLiBXWFIgZmlsZXMgZG8gbm90IGluY2x1ZGUgc2l0ZSBjb25maWd1cmF0aW9uCgkgKiAob3B0aW9ucykgb3IgdGhlIGF0dGFjaG1lbnQgZmlsZXMgdGhlbXNlbHZlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGlyPTxkaXJuYW1lPl0KCSAqIDogRnVsbCBwYXRoIHRvIGRpcmVjdG9yeSB3aGVyZSBXWFIgZXhwb3J0IGZpbGVzIHNob3VsZCBiZSBzdG9yZWQuIERlZmF1bHRzCgkgKiB0byBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LgoJICoKCSAqIFstLXN0ZG91dF0KCSAqIDogT3V0cHV0IHRoZSB3aG9sZSBYTUwgdXNpbmcgc3RhbmRhcmQgb3V0cHV0IChpbmNvbXBhdGlibGUgd2l0aCAtLWRpcj0pCgkgKgoJICogWy0tc2tpcF9jb21tZW50c10KCSAqIDogRG9uJ3QgaW5jbHVkZSBjb21tZW50cyBpbiB0aGUgV1hSIGV4cG9ydCBmaWxlLgoJICoKCSAqIFstLW1heF9maWxlX3NpemU9PE1CPl0KCSAqIDogQSBzaW5nbGUgZXhwb3J0IGZpbGUgc2hvdWxkIGhhdmUgdGhpcyBtYW55IG1lZ2FieXRlcy4gLTEgZm9yIHVubGltaXRlZC4KCSAqIC0tLQoJICogZGVmYXVsdDogMTUKCSAqIC0tLQoJICoKCSAqICMjIEZJTFRFUlMKCSAqCgkgKiBbLS1zdGFydF9kYXRlPTxkYXRlPl0KCSAqIDogRXhwb3J0IG9ubHkgcG9zdHMgcHVibGlzaGVkIGFmdGVyIHRoaXMgZGF0ZSwgaW4gZm9ybWF0IFlZWVktTU0tREQuCgkgKgoJICogWy0tZW5kX2RhdGU9PGRhdGU+XQoJICogOiBFeHBvcnQgb25seSBwb3N0cyBwdWJsaXNoZWQgYmVmb3JlIHRoaXMgZGF0ZSwgaW4gZm9ybWF0IFlZWVktTU0tREQuCgkgKgoJICogWy0tcG9zdF90eXBlPTxwb3N0LXR5cGU+XQoJICogOiBFeHBvcnQgb25seSBwb3N0cyB3aXRoIHRoaXMgcG9zdF90eXBlLiBTZXBhcmF0ZSBtdWx0aXBsZSBwb3N0IHR5cGVzIHdpdGggYQoJICogY29tbWEuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGFueQoJICogLS0tCgkgKgoJICogWy0tcG9zdF90eXBlX19ub3RfaW49PHBvc3QtdHlwZT5dCgkgKiA6IEV4cG9ydCBhbGwgcG9zdCB0eXBlcyBleGNlcHQgdGhvc2UgaWRlbnRpZmllZC4gU2VwYXJhdGUgbXVsdGlwbGUgcG9zdCB0eXBlcwoJICogd2l0aCBhIGNvbW1hLiBEZWZhdWx0cyB0byBub25lLgoJICoKCSAqIFstLXBvc3RfX2luPTxwaWQ+XQoJICogOiBFeHBvcnQgYWxsIHBvc3RzIHNwZWNpZmllZCBhcyBhIGNvbW1hLSBvciBzcGFjZS1zZXBhcmF0ZWQgbGlzdCBvZiBJRHMuCgkgKiBQb3N0J3MgYXR0YWNobWVudHMgd29uJ3QgYmUgZXhwb3J0ZWQgdW5sZXNzIC0td2l0aF9hdHRhY2htZW50cyBpcyBzcGVjaWZpZWQuCgkgKgoJICogWy0td2l0aF9hdHRhY2htZW50c10KCSAqIDogRm9yY2UgaW5jbHVkaW5nIGF0dGFjaG1lbnRzIGluIGNhc2UgLS1wb3N0X19pbiBoYXMgYmVlbiBzcGVjaWZpZWQuCgkgKgoJICogWy0tc3RhcnRfaWQ9PHBpZD5dCgkgKiA6IEV4cG9ydCBvbmx5IHBvc3RzIHdpdGggSURzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGlzIHBvc3QgSUQuCgkgKgoJICogWy0tbWF4X251bV9wb3N0cz08bnVtPl0KCSAqIDogRXhwb3J0IG5vIG1vcmUgdGhhbiA8bnVtPiBwb3N0cyAoZXhjbHVkaW5nIGF0dGFjaG1lbnRzKS4KCSAqCgkgKiBbLS1hdXRob3I9PGF1dGhvcj5dCgkgKiA6IEV4cG9ydCBvbmx5IHBvc3RzIGJ5IHRoaXMgYXV0aG9yLiBDYW4gYmUgZWl0aGVyIHVzZXIgbG9naW4gb3IgdXNlciBJRC4KCSAqCgkgKiBbLS1jYXRlZ29yeT08bmFtZXxpZD5dCgkgKiA6IEV4cG9ydCBvbmx5IHBvc3RzIGluIHRoaXMgY2F0ZWdvcnkuCgkgKgoJICogWy0tcG9zdF9zdGF0dXM9PHN0YXR1cz5dCgkgKiA6IEV4cG9ydCBvbmx5IHBvc3RzIHdpdGggdGhpcyBzdGF0dXMuCgkgKgoJICogWy0tZmlsZW5hbWVfZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBVc2UgYSBjdXN0b20gZm9ybWF0IGZvciBleHBvcnQgZmlsZW5hbWVzLiBEZWZhdWx0cyB0byAne3NpdGV9LndvcmRwcmVzcy57ZGF0ZX0ue259LnhtbCcuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBFeHBvcnQgcG9zdHMgcHVibGlzaGVkIGJ5IHRoZSB1c2VyIGJldHdlZW4gZ2l2ZW4gc3RhcnQgYW5kIGVuZCBkYXRlCgkgKiAgICAgJCB3cCBleHBvcnQgLS1kaXI9L3RtcC8gLS11c2VyPWFkbWluIC0tcG9zdF90eXBlPXBvc3QgLS1zdGFydF9kYXRlPTIwMTEtMDEtMDEgLS1lbmRfZGF0ZT0yMDExLTEyLTMxCgkgKiAgICAgU3RhcnRpbmcgZXhwb3J0IHByb2Nlc3MuLi4KCSAqICAgICBXcml0aW5nIHRvIGZpbGUgL3RtcC9zdGFnaW5nLndvcmRwcmVzcy4yMDE2LTA1LTI0LjAwMC54bWwKCSAqICAgICBTdWNjZXNzOiBBbGwgZG9uZSB3aXRoIGV4cG9ydC4KCSAqCgkgKiAgICAgIyBFeHBvcnQgcG9zdHMgYnkgSURzCgkgKiAgICAgJCB3cCBleHBvcnQgLS1kaXI9L3RtcC8gLS1wb3N0X19pbj0xMjMsMTI0LDEyNQoJICogICAgIFN0YXJ0aW5nIGV4cG9ydCBwcm9jZXNzLi4uCgkgKiAgICAgV3JpdGluZyB0byBmaWxlIC90bXAvc3RhZ2luZy53b3JkcHJlc3MuMjAxNi0wNS0yNC4wMDAueG1sCgkgKiAgICAgU3VjY2VzczogQWxsIGRvbmUgd2l0aCBleHBvcnQuCgkgKgoJICogICAgICMgRXhwb3J0IGEgcmFuZG9tIHN1YnNldCBvZiBjb250ZW50CgkgKiAgICAgJCB3cCBleHBvcnQgLS1wb3N0X19pbj0iJCh3cCBwb3N0IGxpc3QgLS1wb3N0X3R5cGU9cG9zdCAtLW9yZGVyYnk9cmFuZCAtLXBvc3RzX3Blcl9wYWdlPTggLS1mb3JtYXQ9aWRzKSIKCSAqICAgICBTdGFydGluZyBleHBvcnQgcHJvY2Vzcy4uLgoJICogICAgIFdyaXRpbmcgdG8gZmlsZSAvdmFyL3d3dy9leGFtcGxlLmNvbS9wdWJsaWNfaHRtbC9zdGFnaW5nLndvcmRwcmVzcy4yMDE2LTA1LTI0LjAwMC54bWwKCSAqICAgICBTdWNjZXNzOiBBbGwgZG9uZSB3aXRoIGV4cG9ydC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJJGRlZmF1bHRzID0gWwoJCQknZGlyJyAgICAgICAgICAgICAgID0+IG51bGwsCgkJCSdzdGRvdXQnICAgICAgICAgICAgPT4gZmFsc2UsCgkJCSdzdGFydF9kYXRlJyAgICAgICAgPT4gbnVsbCwKCQkJJ2VuZF9kYXRlJyAgICAgICAgICA9PiBudWxsLAoJCQkncG9zdF90eXBlJyAgICAgICAgID0+IG51bGwsCgkJCSdwb3N0X3R5cGVfX25vdF9pbicgPT4gbnVsbCwKCQkJJ21heF9udW1fcG9zdHMnICAgICA9PiBudWxsLAoJCQknYXV0aG9yJyAgICAgICAgICAgID0+IG51bGwsCgkJCSdjYXRlZ29yeScgICAgICAgICAgPT4gbnVsbCwKCQkJJ3Bvc3Rfc3RhdHVzJyAgICAgICA9PiBudWxsLAoJCQkncG9zdF9faW4nICAgICAgICAgID0+IG51bGwsCgkJCSd3aXRoX2F0dGFjaG1lbnRzJyAgPT4gdHJ1ZSwgLy8gb3IgRkFMU0UgaWYgdXNlciByZXF1ZXN0ZWQgc29tZSBwb3N0X19pbgoJCQknc3RhcnRfaWQnICAgICAgICAgID0+IG51bGwsCgkJCSdza2lwX2NvbW1lbnRzJyAgICAgPT4gbnVsbCwKCQkJJ21heF9maWxlX3NpemUnICAgICA9PiAxNSwKCQkJJ2ZpbGVuYW1lX2Zvcm1hdCcgICA9PiAne3NpdGV9LndvcmRwcmVzcy57ZGF0ZX0ue259LnhtbCcsCgkJXTsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snc3Rkb3V0J10gKSAmJiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydkaXInXSApIHx8ICEgZW1wdHkoICRhc3NvY19hcmdzWydmaWxlbmFtZV9mb3JtYXQnXSApICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICctLXN0ZG91dCBhbmQgLS1kaXIgY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIuJyApOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1sncG9zdF9faW4nXSApICYmIGVtcHR5KCAkYXNzb2NfYXJnc1snd2l0aF9hdHRhY2htZW50cyddICkgKSB7CgkJCSRkZWZhdWx0c1snd2l0aF9hdHRhY2htZW50cyddID0gZmFsc2U7CgkJfQoKCQkkYXNzb2NfYXJncyA9IHdwX3BhcnNlX2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCgkJJHRoaXMtPnZhbGlkYXRlX2FyZ3MoICRhc3NvY19hcmdzICk7CgoJCSR0aGlzLT5leHBvcnRfYXJnc1snd2l0aF9hdHRhY2htZW50cyddID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoCgkJCSRhc3NvY19hcmdzLAoJCQknd2l0aF9hdHRhY2htZW50cycsCgkJCSRkZWZhdWx0c1snd2l0aF9hdHRhY2htZW50cyddCgkJKTsKCgkJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3dwX2V4cG9ydCcgKSApIHsKCQkJc2VsZjo6bG9hZF9leHBvcnRfYXBpKCk7CgkJfQoKCQlpZiAoICEgJHRoaXMtPnN0ZG91dCApIHsKCQkJV1BfQ0xJOjpsb2coICdTdGFydGluZyBleHBvcnQgcHJvY2Vzcy4uLicgKTsKCQl9CgoJCWFkZF9hY3Rpb24oCgkJCSd3cF9leHBvcnRfbmV3X2ZpbGUnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkZmlsZV9wYXRoICkgewoJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdXcml0aW5nIHRvIGZpbGUgJXMnLCAkZmlsZV9wYXRoICkgKTsKCQkJCVV0aWxzXHdwX2NsZWFyX29iamVjdF9jYWNoZSgpOwoJCQl9CgkJKTsKCgkJdHJ5IHsKCQkJaWYgKCAkdGhpcy0+c3Rkb3V0ICkgewoJCQkJd3BfZXhwb3J0KAoJCQkJCVsKCQkJCQkJJ2ZpbHRlcnMnICAgICA9PiAkdGhpcy0+ZXhwb3J0X2FyZ3MsCgkJCQkJCSd3cml0ZXInICAgICAgPT4gJ1dQX0V4cG9ydF9GaWxlX1dyaXRlcicsCgkJCQkJCSd3cml0ZXJfYXJncycgPT4gJ3BocDovL291dHB1dCcsCgkJCQkJXQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCXdwX2V4cG9ydCgKCQkJCQlbCgkJCQkJCSdmaWx0ZXJzJyAgICAgPT4gJHRoaXMtPmV4cG9ydF9hcmdzLAoJCQkJCQknd3JpdGVyJyAgICAgID0+ICdXUF9FeHBvcnRfU3BsaXRfRmlsZXNfV3JpdGVyJywKCQkJCQkJJ3dyaXRlcl9hcmdzJyA9PiBbCgkJCQkJCQknbWF4X2ZpbGVfc2l6ZScgICAgICAgICA9PiAkdGhpcy0+bWF4X2ZpbGVfc2l6ZSwKCQkJCQkJCSdkZXN0aW5hdGlvbl9kaXJlY3RvcnknID0+ICR0aGlzLT53eHJfcGF0aCwKCQkJCQkJCSdmaWxlbmFtZV90ZW1wbGF0ZScgICAgID0+IHNlbGY6OmdldF9maWxlbmFtZV90ZW1wbGF0ZSggJGFzc29jX2FyZ3NbJ2ZpbGVuYW1lX2Zvcm1hdCddICksCgkJCQkJCV0sCgkJCQkJXQoJCQkJKTsKCQkJfQoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgoJCWlmICggISAkdGhpcy0+c3Rkb3V0ICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdBbGwgZG9uZSB3aXRoIGV4cG9ydC4nICk7CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9maWxlbmFtZV90ZW1wbGF0ZSggJGZpbGVuYW1lX2Zvcm1hdCApIHsKCQkkc2l0ZW5hbWUgPSBzYW5pdGl6ZV9rZXkoIGdldF9ibG9naW5mbyggJ25hbWUnICkgKTsKCQlpZiAoIGVtcHR5KCAkc2l0ZW5hbWUgKSApIHsKCQkJJHNpdGVuYW1lID0gJ3NpdGUnOwoJCX0KCQlyZXR1cm4gc3RyX3JlcGxhY2UoIFsgJ3tzaXRlfScsICd7ZGF0ZX0nLCAne259JyBdLCBbICRzaXRlbmFtZSwgZGF0ZSggJ1ktbS1kJyApLCAnJTAzZCcgXSwgJGZpbGVuYW1lX2Zvcm1hdCApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgl9CgoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBsb2FkX2V4cG9ydF9hcGkoKSB7CgkJcmVxdWlyZSBkaXJuYW1lKCBfX0RJUl9fICkgLiAnL2Z1bmN0aW9ucy5waHAnOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVfYXJncyggJGFyZ3MgKSB7CgkJJGhhc19lcnJvcnMgPSBmYWxzZTsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQlpZiAoIGlzX2NhbGxhYmxlKCBbICR0aGlzLCAnY2hlY2tfJyAuICRrZXkgXSApICkgewoJCQkJJHJlc3VsdCA9IGNhbGxfdXNlcl9mdW5jKCBbICR0aGlzLCAnY2hlY2tfJyAuICRrZXkgXSwgJHZhbHVlICk7CgkJCQlpZiAoIGZhbHNlID09PSAkcmVzdWx0ICkgewoJCQkJCSRoYXNfZXJyb3JzID0gdHJ1ZTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAkYXJnc1snc3Rkb3V0J10gKSB7CgkJCSR0aGlzLT53eHJfcGF0aCA9IG51bGw7CgkJCSR0aGlzLT5zdGRvdXQgICA9IHRydWU7CgkJfQoKCQlpZiAoICRoYXNfZXJyb3JzICkgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19kaXIoICRwYXRoICkgewoJCWlmICggZW1wdHkoICRwYXRoICkgKSB7CgkJCSRwYXRoID0gZ2V0Y3dkKCk7CgkJfSBlbHNlaWYgKCAhIGlzX2RpciggJHBhdGggKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIlRoZSBkaXJlY3RvcnkgJyVzJyBkb2VzIG5vdCBleGlzdC4iLCAkcGF0aCApICk7CgkJfSBlbHNlaWYgKCAhIGlzX3dyaXRhYmxlKCAkcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiVGhlIGRpcmVjdG9yeSAnJXMnIGlzIG5vdCB3cml0YWJsZS4iLCAkcGF0aCApICk7CgkJfQoKCQkkdGhpcy0+d3hyX3BhdGggPSB0cmFpbGluZ3NsYXNoaXQoICRwYXRoICk7CgoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfc3RhcnRfZGF0ZSggJGRhdGUgKSB7CgkJaWYgKCBudWxsID09PSAkZGF0ZSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkdGltZSA9IHN0cnRvdGltZSggJGRhdGUgKTsKCQlpZiAoICEgZW1wdHkoICRkYXRlICkgJiYgISAkdGltZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnVGhlIHN0YXJ0X2RhdGUgJXMgaXMgaW52YWxpZC4nLCAkZGF0ZSApICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJHRoaXMtPmV4cG9ydF9hcmdzWydzdGFydF9kYXRlJ10gPSBkYXRlKCAnWS1tLWQnLCAkdGltZSApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19lbmRfZGF0ZSggJGRhdGUgKSB7CgkJaWYgKCBudWxsID09PSAkZGF0ZSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkdGltZSA9IHN0cnRvdGltZSggJGRhdGUgKTsKCQlpZiAoICEgZW1wdHkoICRkYXRlICkgJiYgISAkdGltZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnVGhlIGVuZF9kYXRlICVzIGlzIGludmFsaWQuJywgJGRhdGUgKSApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCSR0aGlzLT5leHBvcnRfYXJnc1snZW5kX2RhdGUnXSA9IGRhdGUoICdZLW0tZCcsICR0aW1lICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX3Bvc3RfdHlwZSggJHBvc3RfdHlwZSApIHsKCQlpZiAoIG51bGwgPT09ICRwb3N0X3R5cGUgfHwgJ2FueScgPT09ICRwb3N0X3R5cGUgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJJHBvc3RfdHlwZSAgPSBhcnJheV91bmlxdWUoIGFycmF5X2ZpbHRlciggZXhwbG9kZSggJywnLCAkcG9zdF90eXBlICkgKSApOwoJCSRwb3N0X3R5cGVzID0gZ2V0X3Bvc3RfdHlwZXMoKTsKCgkJZm9yZWFjaCAoICRwb3N0X3R5cGUgYXMgJHR5cGUgKSB7CgkJCWlmICggISBpbl9hcnJheSggJHR5cGUsICRwb3N0X3R5cGVzLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJc3ByaW50ZigKCQkJCQkJJ1RoZSBwb3N0IHR5cGUgJXMgZG9lcyBub3QgZXhpc3QuIENob29zZSAiYW55IiBvciBhbnkgb2YgdGhlc2UgZXhpc3RpbmcgcG9zdCB0eXBlcyBpbnN0ZWFkOiAlcycsCgkJCQkJCSR0eXBlLAoJCQkJCQlpbXBsb2RlKCAnLCAnLCAkcG9zdF90eXBlcyApCgkJCQkJKQoJCQkJKTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ3Bvc3RfdHlwZSddID0gJHBvc3RfdHlwZTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX3Bvc3RfdHlwZV9fbm90X2luKCAkcG9zdF90eXBlICkgewoJCWlmICggbnVsbCA9PT0gJHBvc3RfdHlwZSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkcG9zdF90eXBlICA9IGFycmF5X3VuaXF1ZSggYXJyYXlfZmlsdGVyKCBleHBsb2RlKCAnLCcsICRwb3N0X3R5cGUgKSApICk7CgkJJHBvc3RfdHlwZXMgPSBnZXRfcG9zdF90eXBlcygpOwoKCQlmb3JlYWNoICggJHBvc3RfdHlwZSBhcyAkdHlwZSApIHsKCQkJaWYgKCAhIGluX2FycmF5KCAkdHlwZSwgJHBvc3RfdHlwZXMsIHRydWUgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQlzcHJpbnRmKAoJCQkJCQknVGhlIHBvc3QgdHlwZSAlcyBkb2VzIG5vdCBleGlzdC4gVXNlIGFueSBvZiB0aGVzZSBleGlzdGluZyBwb3N0IHR5cGVzIGluc3RlYWQ6ICVzJywKCQkJCQkJJHR5cGUsCgkJCQkJCWltcGxvZGUoICcsICcsICRwb3N0X3R5cGVzICkKCQkJCQkpCgkJCQkpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoJCSR0aGlzLT5leHBvcnRfYXJnc1sncG9zdF90eXBlJ10gPSBhcnJheV9kaWZmKCAkcG9zdF90eXBlcywgJHBvc3RfdHlwZSApOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfcG9zdF9faW4oICRwb3N0X19pbiApIHsKCQlpZiAoIG51bGwgPT09ICRwb3N0X19pbiApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkc2VwYXJhdG9yID0gZmFsc2UgIT09IHN0cmlwb3MoICRwb3N0X19pbiwgJyAnICkgPyAnICcgOiAnLCc7CgkJJHBvc3RfX2luICA9IGFycmF5X2ZpbHRlciggYXJyYXlfdW5pcXVlKCBhcnJheV9tYXAoICdpbnR2YWwnLCBleHBsb2RlKCAkc2VwYXJhdG9yLCAkcG9zdF9faW4gKSApICkgKTsKCQlpZiAoIGVtcHR5KCAkcG9zdF9faW4gKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAncG9zdF9faW4gc2hvdWxkIGJlIGNvbW1hLXNlcGFyYXRlZCBwb3N0IElEcy4nICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJLy8gTmV3IGV4cG9ydGVyIHVzZXMgYSBkaWZmZXJlbnQgYXJndW1lbnQuCgkJJHRoaXMtPmV4cG9ydF9hcmdzWydwb3N0X2lkcyddID0gJHBvc3RfX2luOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfc3RhcnRfaWQoICRzdGFydF9pZCApIHsKCQlpZiAoIG51bGwgPT09ICRzdGFydF9pZCApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkc3RhcnRfaWQgPSAoaW50KSAkc3RhcnRfaWQ7CgoJCS8vIFBvc3QgSURzIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAuCgkJaWYgKCAwID49ICRzdGFydF9pZCApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiSW52YWxpZCBzdGFydCBJRDogeyRzdGFydF9pZH0iICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSR0aGlzLT5leHBvcnRfYXJnc1snc3RhcnRfaWQnXSA9ICRzdGFydF9pZDsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2F1dGhvciggJGF1dGhvciApIHsKCQlpZiAoIG51bGwgPT09ICRhdXRob3IgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkRnVuY3Rpb25zLmdldF91c2Vyc19vZl9ibG9nRm91bmQgLS0gRmFsbGJhY2suCgkJJGF1dGhvcnMgPSBmdW5jdGlvbl9leGlzdHMoICdnZXRfdXNlcnMnICkgPyBnZXRfdXNlcnMoKSA6IGdldF91c2Vyc19vZl9ibG9nKCk7CgkJaWYgKCBlbXB0eSggJGF1dGhvcnMgKSB8fCBpc193cF9lcnJvciggJGF1dGhvcnMgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnQ291bGQgbm90IGZpbmQgYW55IGF1dGhvcnMgaW4gdGhpcyBibG9nLicgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkaGl0ID0gZmFsc2U7CgkJZm9yZWFjaCAoICRhdXRob3JzIGFzICR1c2VyICkgewoJCQlpZiAoICRoaXQgKSB7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoIChpbnQpICRhdXRob3IgPT09ICR1c2VyLT5JRCB8fCAkYXV0aG9yID09PSAkdXNlci0+dXNlcl9sb2dpbiApIHsKCQkJCSRoaXQgPSAkdXNlci0+SUQ7CgkJCX0KCQl9CgkJaWYgKCBmYWxzZSA9PT0gJGhpdCApIHsKCQkJJGF1dGhvcnNfbmljZSA9IFtdOwoJCQlmb3JlYWNoICggJGF1dGhvcnMgYXMgJF9hdXRob3IgKSB7CgkJCQkkYXV0aG9yc19uaWNlW10gPSBzcHJpbnRmKCAnJXMgKCVzKScsICRfYXV0aG9yLT51c2VyX2xvZ2luLCAkX2F1dGhvci0+ZGlzcGxheV9uYW1lICk7CgkJCX0KCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnQ291bGQgbm90IGZpbmQgYSBtYXRjaGluZyBhdXRob3IgZm9yICVzLiBUaGUgZm9sbG93aW5nIGF1dGhvcnMgZXhpc3Q6ICVzJywgJGF1dGhvciwgaW1wbG9kZSggJywgJywgJGF1dGhvcnNfbmljZSApICkgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHRoaXMtPmV4cG9ydF9hcmdzWydhdXRob3InXSA9ICRoaXQ7CgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19tYXhfbnVtX3Bvc3RzKCAkbnVtICkgewoJCWlmICggbnVsbCAhPT0gJG51bSAmJiAoICEgaXNfbnVtZXJpYyggJG51bSApIHx8ICRudW0gPD0gMCApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdtYXhfbnVtX3Bvc3RzIHNob3VsZCBiZSBhIHBvc2l0aXZlIGludGVnZXIuJyApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ21heF9udW1fcG9zdHMnXSA9IChpbnQpICRudW07CgoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfY2F0ZWdvcnkoICRjYXRlZ29yeSApIHsKCQlpZiAoIG51bGwgPT09ICRjYXRlZ29yeSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlpZiAoIGlzX251bWVyaWMoICRjYXRlZ29yeSApICkgewoJCQkkY2F0ZWdvcnkgPSAoaW50KSAkY2F0ZWdvcnk7CgkJfQoKCQkkdGVybSA9IGNhdGVnb3J5X2V4aXN0cyggJGNhdGVnb3J5ICk7CgkJaWYgKCBlbXB0eSggJHRlcm0gKSB8fCBpc193cF9lcnJvciggJHRlcm0gKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnQ291bGQgbm90IGZpbmQgYSBjYXRlZ29yeSBtYXRjaGluZyAlcy4nLCAkY2F0ZWdvcnkgKSApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCSR0aGlzLT5leHBvcnRfYXJnc1snY2F0ZWdvcnknXSA9ICRjYXRlZ29yeTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX3Bvc3Rfc3RhdHVzKCAkc3RhdHVzICkgewoJCWlmICggbnVsbCA9PT0gJHN0YXR1cyApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkc3RhdGkgPSBnZXRfcG9zdF9zdGF0dXNlcygpOwoJCWlmICggZW1wdHkoICRzdGF0aSApIHx8IGlzX3dwX2Vycm9yKCAkc3RhdGkgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnQ291bGQgbm90IGZpbmQgYW55IHBvc3Qgc3RhdGkuJyApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoICEgaXNzZXQoICRzdGF0aVsgJHN0YXR1cyBdICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0NvdWxkIG5vdCBmaW5kIGEgcG9zdF9zdGF0dXMgbWF0Y2hpbmcgJXMuIEhlcmUgaXMgYSBsaXN0IG9mIGF2YWlsYWJsZSBzdGF0aTogJXMnLCAkc3RhdHVzLCBpbXBsb2RlKCAnLCAnLCBhcnJheV9rZXlzKCAkc3RhdGkgKSApICkgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ3N0YXR1cyddID0gJHN0YXR1czsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX3NraXBfY29tbWVudHMoICRza2lwICkgewoJCWlmICggbnVsbCA9PT0gJHNraXAgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJaWYgKCAwICE9PSAoaW50KSAkc2tpcCAmJiAxICE9PSAoaW50KSAkc2tpcCApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnc2tpcF9jb21tZW50cyBuZWVkcyB0byBiZSAwIChubykgb3IgMSAoeWVzKS4nICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJHRoaXMtPmV4cG9ydF9hcmdzWydza2lwX2NvbW1lbnRzJ10gPSAkc2tpcDsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX21heF9maWxlX3NpemUoICRzaXplICkgewoJCWlmICggISBpc19udW1lcmljKCAkc2l6ZSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdtYXhfZmlsZV9zaXplIHNob3VsZCBiZSBudW1lcmljLicgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHRoaXMtPm1heF9maWxlX3NpemUgPSAkc2l6ZTsKCgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogUmVwcmVzZW50cyBhIHNldCBvZiBwb3N0cyBhbmQgb3RoZXIgc2l0ZSBkYXRhIHRvIGJlIGV4cG9ydGVkLgogKgogKiBBbiBpbW11dGFibGUgb2JqZWN0LCB3aGljaCBnYXRoZXJzIGFsbCBkYXRhIG5lZWRlZCBmb3IgdGhlIGV4cG9ydC4KICovCmNsYXNzIFdQX0V4cG9ydF9RdWVyeSB7Cgljb25zdCBRVUVSWV9DSFVOSyA9IDEwMDsKCglwcml2YXRlIHN0YXRpYyAkZGVmYXVsdHMgPSBbCgkJJ3Bvc3RfaWRzJyAgICAgID0+IG51bGwsCgkJJ3Bvc3RfdHlwZScgICAgID0+IG51bGwsCgkJJ3N0YXR1cycgICAgICAgID0+IG51bGwsCgkJJ2F1dGhvcicgICAgICAgID0+IG51bGwsCgkJJ3N0YXJ0X2RhdGUnICAgID0+IG51bGwsCgkJJ2VuZF9kYXRlJyAgICAgID0+IG51bGwsCgkJJ3N0YXJ0X2lkJyAgICAgID0+IG51bGwsCgkJJ21heF9udW1fcG9zdHMnID0+IG51bGwsCgkJJ2NhdGVnb3J5JyAgICAgID0+IG51bGwsCgldOwoKCXByaXZhdGUgJHBvc3RfaWRzOwoJcHJpdmF0ZSAkZmlsdGVyczsKCglwcml2YXRlICR3aGVyZXMgPSBbXTsKCXByaXZhdGUgJGpvaW5zICA9IFtdOwoKCXByaXZhdGUgJGF1dGhvcjsKCXByaXZhdGUgJGNhdGVnb3J5OwoKCXB1YmxpYyAkbWlzc2luZ19wYXJlbnRzID0gZmFsc2U7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZmlsdGVycyA9IFtdICkgewoJCSR0aGlzLT5maWx0ZXJzID0gd3BfcGFyc2VfYXJncyggJGZpbHRlcnMsIHNlbGY6OiRkZWZhdWx0cyApOwoKCQkkdXNlciA9ICR0aGlzLT5maW5kX3VzZXJfZnJvbV9hbnlfb2JqZWN0KCAkdGhpcy0+ZmlsdGVyc1snYXV0aG9yJ10gKTsKCQlpZiAoICR1c2VyICYmICEgaXNfd3BfZXJyb3IoICR1c2VyICkgKSB7CgkJCSR0aGlzLT5hdXRob3IgPSAkdXNlcjsKCQl9CgoJCSR0aGlzLT5wb3N0X2lkcyA9ICR0aGlzLT5jYWxjdWxhdGVfcG9zdF9pZHMoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcG9zdF9pZHMoKSB7CgkJcmV0dXJuICR0aGlzLT5wb3N0X2lkczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY2hhcnNldCgpIHsKCQlyZXR1cm4gZ2V0X2Jsb2dpbmZvKCAnY2hhcnNldCcgKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gc2l0ZV9tZXRhZGF0YSgpIHsKCQkkbWV0YWRhdGEgPSBbCgkJCSduYW1lJyAgICAgICAgPT4gJHRoaXMtPmJsb2dpbmZvX3JzcyggJ25hbWUnICksCgkJCSd1cmwnICAgICAgICAgPT4gJHRoaXMtPmJsb2dpbmZvX3JzcyggJ3VybCcgKSwKCQkJJ2xhbmd1YWdlJyAgICA9PiAkdGhpcy0+YmxvZ2luZm9fcnNzKCAnbGFuZ3VhZ2UnICksCgkJCSdkZXNjcmlwdGlvbicgPT4gJHRoaXMtPmJsb2dpbmZvX3JzcyggJ2Rlc2NyaXB0aW9uJyApLAoJCQkncHViRGF0ZScgICAgID0+IGRhdGUoICdELCBkIE0gWSBIOmk6cyArMDAwMCcgKSwgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCQknc2l0ZV91cmwnICAgID0+IGlzX211bHRpc2l0ZSgpID8gbmV0d29ya19ob21lX3VybCgpIDogJHRoaXMtPmJsb2dpbmZvX3JzcyggJ3VybCcgKSwKCQkJJ2Jsb2dfdXJsJyAgICA9PiAkdGhpcy0+YmxvZ2luZm9fcnNzKCAndXJsJyApLAoJCV07CgkJcmV0dXJuICRtZXRhZGF0YTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gd3BfZ2VuZXJhdG9yX3RhZygpIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCXJldHVybiBhcHBseV9maWx0ZXJzKCAndGhlX2dlbmVyYXRvcicsIGdldF90aGVfZ2VuZXJhdG9yKCAnZXhwb3J0JyApLCAnZXhwb3J0JyApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBhdXRob3JzKCkgewoJCWdsb2JhbCAkd3BkYjsKCgkJLy8gSWYgd2UncmUgZmlsdGVyaW5nIGJ5IGEgc3BlY2lmaWMgYXV0aG9yLCB3ZSBvbmx5IG5lZWQgdG8gaW5jbHVkZSB0aGF0CgkJLy8gYXV0aG9yJ3MgdXNlciBvYmplY3QsIGFuZCBubyBvdGhlciB1c2Vycy4KCQlpZiAoIGlzX29iamVjdCggJHRoaXMtPmF1dGhvciApICYmIHByb3BlcnR5X2V4aXN0cyggJHRoaXMtPmF1dGhvciwgJ0lEJyApICkgewoJCQlyZXR1cm4gWyAkdGhpcy0+YXV0aG9yIF07CgkJfQoKCQkkYXV0aG9ycyAgICA9IFtdOwoJCSRhdXRob3JfaWRzID0gKGFycmF5KSAkd3BkYi0+Z2V0X2NvbCggIlNFTEVDVCBESVNUSU5DVCBwb3N0X2F1dGhvciBGUk9NICR3cGRiLT5wb3N0cyBXSEVSRSBwb3N0X3N0YXR1cyAhPSAnYXV0by1kcmFmdCciICk7CgkJZm9yZWFjaCAoICRhdXRob3JfaWRzIGFzICRhdXRob3JfaWQgKSB7CgkJCSRhdXRob3JzW10gPSBnZXRfdXNlcmRhdGEoICRhdXRob3JfaWQgKTsKCQl9CgkJJGF1dGhvcnMgPSBhcnJheV9maWx0ZXIoICRhdXRob3JzICk7CgkJcmV0dXJuICRhdXRob3JzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjYXRlZ29yaWVzKCkgewoJCWlmICggJHRoaXMtPmNhdGVnb3J5ICkgewoJCQlyZXR1cm4gWyAkdGhpcy0+Y2F0ZWdvcnkgXTsKCQl9CgkJaWYgKCAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10gKSB7CgkJCXJldHVybiBbXTsKCQl9CgkJJGNhdGVnb3JpZXMgPSAoYXJyYXkpIGdldF9jYXRlZ29yaWVzKCBbICdnZXQnID0+ICdhbGwnIF0gKTsKCgkJJHRoaXMtPmNoZWNrX2Zvcl9vcnBoYW5lZF90ZXJtcyggJGNhdGVnb3JpZXMgKTsKCgkJJGNhdGVnb3JpZXMgPSBzZWxmOjp0b3BvbG9naWNhbGx5X3NvcnRfdGVybXMoICRjYXRlZ29yaWVzICk7CgoJCXJldHVybiAkY2F0ZWdvcmllczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdGFncygpIHsKCQlpZiAoICR0aGlzLT5maWx0ZXJzWydwb3N0X3R5cGUnXSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCQkkdGFncyA9IChhcnJheSkgZ2V0X3RhZ3MoIFsgJ2dldCcgPT4gJ2FsbCcgXSApOwoKCQkkdGhpcy0+Y2hlY2tfZm9yX29ycGhhbmVkX3Rlcm1zKCAkdGFncyApOwoKCQlyZXR1cm4gJHRhZ3M7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGN1c3RvbV90YXhvbm9taWVzX3Rlcm1zKCkgewoJCWlmICggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfdHlwZSddICkgewoJCQlyZXR1cm4gW107CgkJfQoJCSRjdXN0b21fdGF4b25vbWllcyA9IGdldF90YXhvbm9taWVzKCBbICdfYnVpbHRpbicgPT4gZmFsc2UgXSApOwoJCSRjdXN0b21fdGVybXMgICAgICA9IChhcnJheSkgZ2V0X3Rlcm1zKCAkY3VzdG9tX3RheG9ub21pZXMsIFsgJ2dldCcgPT4gJ2FsbCcgXSApOwoJCSR0aGlzLT5jaGVja19mb3Jfb3JwaGFuZWRfdGVybXMoICRjdXN0b21fdGVybXMgKTsKCQkkY3VzdG9tX3Rlcm1zID0gc2VsZjo6dG9wb2xvZ2ljYWxseV9zb3J0X3Rlcm1zKCAkY3VzdG9tX3Rlcm1zICk7CgkJcmV0dXJuICRjdXN0b21fdGVybXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG5hdl9tZW51X3Rlcm1zKCkgewoJCSRuYXZfbWVudXMgPSB3cF9nZXRfbmF2X21lbnVzKCk7CgkJZm9yZWFjaCAoICRuYXZfbWVudXMgYXMgJHRlcm0gKSB7CgkJCSR0ZXJtLT5kZXNjcmlwdGlvbiA9ICcnOwoJCX0KCQlyZXR1cm4gJG5hdl9tZW51czsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0aWZ5X3Bvc3QoICRwb3N0ICkgewoJCSRHTE9CQUxTWyd3cF9xdWVyeSddLT5pbl90aGVfbG9vcCA9IHRydWU7CgkJJHByZXZpb3VzX2dsb2JhbF9wb3N0ICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRHTE9CQUxTLCAncG9zdCcgKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gVGVtcG9yYXJ5IG92ZXJyaWRlLgoJCSRHTE9CQUxTWydwb3N0J10gPSAkcG9zdDsKCQlzZXR1cF9wb3N0ZGF0YSggJHBvc3QgKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCSRwb3N0LT5wb3N0X2NvbnRlbnQgPSBhcHBseV9maWx0ZXJzKCAndGhlX2NvbnRlbnRfZXhwb3J0JywgJHBvc3QtPnBvc3RfY29udGVudCApOwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJJHBvc3QtPnBvc3RfZXhjZXJwdCA9IGFwcGx5X2ZpbHRlcnMoICd0aGVfZXhjZXJwdF9leHBvcnQnLCAkcG9zdC0+cG9zdF9leGNlcnB0ICk7CgkJJHBvc3QtPmlzX3N0aWNreSAgICA9IGlzX3N0aWNreSggJHBvc3QtPklEICkgPyAxIDogMDsKCQkkcG9zdC0+dGVybXMgICAgICAgID0gc2VsZjo6Z2V0X3Rlcm1zX2Zvcl9wb3N0KCAkcG9zdCApOwoJCSRwb3N0LT5tZXRhICAgICAgICAgPSBzZWxmOjpnZXRfbWV0YV9mb3JfcG9zdCggJHBvc3QgKTsKCQkkcG9zdC0+Y29tbWVudHMgICAgID0gJHRoaXMtPmdldF9jb21tZW50c19mb3JfcG9zdCggJHBvc3QgKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gUmV2ZXJ0IGJhY2sgdG8gb3JpZ2luYWwuCgkJJEdMT0JBTFNbJ3Bvc3QnXSA9ICRwcmV2aW91c19nbG9iYWxfcG9zdDsKCQlyZXR1cm4gJHBvc3Q7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHBvc3RzKCkgewoJCSRwb3N0c19pdGVyYXRvciA9IG5ldyBXUF9Qb3N0X0lEc19JdGVyYXRvciggJHRoaXMtPnBvc3RfaWRzLCBzZWxmOjpRVUVSWV9DSFVOSyApOwoJCXJldHVybiBuZXcgV1BfTWFwX0l0ZXJhdG9yKCAkcG9zdHNfaXRlcmF0b3IsIFsgJHRoaXMsICdleHBvcnRpZnlfcG9zdCcgXSApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2FsY3VsYXRlX3Bvc3RfaWRzKCkgewoJCWdsb2JhbCAkd3BkYjsKCQlpZiAoIGlzX2FycmF5KCAkdGhpcy0+ZmlsdGVyc1sncG9zdF9pZHMnXSApICkgewoJCQlpZiAoICR0aGlzLT5maWx0ZXJzWyd3aXRoX2F0dGFjaG1lbnRzJ10gKSB7CgkJCQkkYXR0YWNobWVudF9wb3N0X2lkcyAgICAgICA9ICR0aGlzLT5pbmNsdWRlX2F0dGFjaG1lbnRfaWRzKCAkdGhpcy0+ZmlsdGVyc1sncG9zdF9pZHMnXSApOwoJCQkJJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfaWRzJ10gPSBhcnJheV9tZXJnZSggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfaWRzJ10sICRhdHRhY2htZW50X3Bvc3RfaWRzICk7CgkJCX0KCQkJcmV0dXJuICR0aGlzLT5maWx0ZXJzWydwb3N0X2lkcyddOwoJCX0KCQkkdGhpcy0+cG9zdF90eXBlX3doZXJlKCk7CgkJJHRoaXMtPnN0YXR1c193aGVyZSgpOwoJCSR0aGlzLT5hdXRob3Jfd2hlcmUoKTsKCQkkdGhpcy0+c3RhcnRfZGF0ZV93aGVyZSgpOwoJCSR0aGlzLT5lbmRfZGF0ZV93aGVyZSgpOwoJCSR0aGlzLT5zdGFydF9pZF93aGVyZSgpOwoJCSR0aGlzLT5jYXRlZ29yeV93aGVyZSgpOwoKCQkkd2hlcmUgPSBpbXBsb2RlKCAnIEFORCAnLCBhcnJheV9maWx0ZXIoICR0aGlzLT53aGVyZXMgKSApOwoJCWlmICggJHdoZXJlICkgewoJCQkkd2hlcmUgPSAiV0hFUkUgJHdoZXJlIjsKCQl9CgkJJGpvaW4gPSBpbXBsb2RlKCAnICcsIGFycmF5X2ZpbHRlciggJHRoaXMtPmpvaW5zICkgKTsKCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5JbnRlcnBvbGF0ZWROb3RQcmVwYXJlZCAtLSBJbmRpdmlkdWFsIHdoZXJlIGNsYXVzZXMgcnVuIHRocm91Z2ggJHdwZGItPnByZXBhcmUoKS4KCQkkcG9zdF9pZHMgPSAkd3BkYi0+Z2V0X2NvbCggIlNFTEVDVCBJRCBGUk9NIHskd3BkYi0+cG9zdHN9IEFTIHAgeyRqb2lufSB7JHdoZXJlfSB7JHRoaXMtPm1heF9udW1fcG9zdHMoKX0iICk7CgkJaWYgKCAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10gKSB7CgkJCSRwb3N0X2lkcyA9IGFycmF5X21lcmdlKCAkcG9zdF9pZHMsICR0aGlzLT5pbmNsdWRlX2F0dGFjaG1lbnRfaWRzKCAkcG9zdF9pZHMgKSApOwoJCX0KCQlyZXR1cm4gJHBvc3RfaWRzOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gcG9zdF90eXBlX3doZXJlKCkgewoJCSRwb3N0X3R5cGVzX2ZpbHRlcnMgPSBbICdjYW5fZXhwb3J0JyA9PiB0cnVlIF07CgkJaWYgKCAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10gKSB7CgkJCSRwb3N0X3R5cGVzID0gJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfdHlwZSddOwoKCQkJLy8gRmxhdHRlbiBzaW5nbGUgcG9zdCB0eXBlcwoJCQlpZiAoIGlzX2FycmF5KCAkcG9zdF90eXBlcyApICYmIDEgPT09IGNvdW50KCAkcG9zdF90eXBlcyApICkgewoJCQkJJHBvc3RfdHlwZXMgPSBhcnJheV9zaGlmdCggJHBvc3RfdHlwZXMgKTsKCQkJfQoJCQkkcG9zdF90eXBlc19maWx0ZXJzID0gYXJyYXlfbWVyZ2UoICRwb3N0X3R5cGVzX2ZpbHRlcnMsIFsgJ25hbWUnID0+ICRwb3N0X3R5cGVzIF0gKTsKCQl9CgoJCS8vIE11bHRpcGxlIHBvc3QgdHlwZXMKCQlpZiAoIGlzc2V0KCAkcG9zdF90eXBlc19maWx0ZXJzWyduYW1lJ10gKSAmJiBpc19hcnJheSggJHBvc3RfdHlwZXNfZmlsdGVyc1snbmFtZSddICkgKSB7CgkJCSRwb3N0X3R5cGVzID0gW107CgkJCWZvcmVhY2ggKCAkcG9zdF90eXBlc19maWx0ZXJzWyduYW1lJ10gYXMgJHBvc3RfdHlwZSApIHsKCQkJCWlmICggcG9zdF90eXBlX2V4aXN0cyggJHBvc3RfdHlwZSApICkgewoJCQkJCSRwb3N0X3R5cGVzW10gPSAkcG9zdF90eXBlOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJJHBvc3RfdHlwZXMgPSBnZXRfcG9zdF90eXBlcyggJHBvc3RfdHlwZXNfZmlsdGVycyApOwoJCX0KCgkJaWYgKCAhICRwb3N0X3R5cGVzICkgewoJCQkkdGhpcy0+d2hlcmVzW10gPSAncC5wb3N0X3R5cGUgSVMgTlVMTCc7CgkJCXJldHVybjsKCQl9CgoJCWlmICggZmFsc2UgPT09ICR0aGlzLT5maWx0ZXJzWyd3aXRoX2F0dGFjaG1lbnRzJ10gJiYgKCAhICR0aGlzLT5maWx0ZXJzWydwb3N0X3R5cGUnXSB8fCAhIGluX2FycmF5KCAnYXR0YWNobWVudCcsICR0aGlzLT5maWx0ZXJzWydwb3N0X3R5cGUnXSwgdHJ1ZSApICkgKSB7CgkJCXVuc2V0KCAkcG9zdF90eXBlc1snYXR0YWNobWVudCddICk7CgkJfQoKCQkkdGhpcy0+d2hlcmVzW10gPSBfd3BfZXhwb3J0X2J1aWxkX0lOX2NvbmRpdGlvbiggJ3AucG9zdF90eXBlJywgJHBvc3RfdHlwZXMgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHN0YXR1c193aGVyZSgpIHsKCQlnbG9iYWwgJHdwZGI7CgkJaWYgKCAhICR0aGlzLT5maWx0ZXJzWydzdGF0dXMnXSApIHsKCQkJJHRoaXMtPndoZXJlc1tdID0gInAucG9zdF9zdGF0dXMgIT0gJ2F1dG8tZHJhZnQnIjsKCQkJcmV0dXJuOwoJCX0KCQkkdGhpcy0+d2hlcmVzW10gPSAkd3BkYi0+cHJlcGFyZSggJ3AucG9zdF9zdGF0dXMgPSAlcycsICR0aGlzLT5maWx0ZXJzWydzdGF0dXMnXSApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gYXV0aG9yX3doZXJlKCkgewoJCWdsb2JhbCAkd3BkYjsKCQlpZiAoIGlzX29iamVjdCggJHRoaXMtPmF1dGhvciApICYmIHByb3BlcnR5X2V4aXN0cyggJHRoaXMtPmF1dGhvciwgJ0lEJyApICkgewoJCQkkdGhpcy0+d2hlcmVzW10gPSAkd3BkYi0+cHJlcGFyZSggJ3AucG9zdF9hdXRob3IgPSAlZCcsICR0aGlzLT5hdXRob3ItPklEICk7CgkJfQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc3RhcnRfZGF0ZV93aGVyZSgpIHsKCQlnbG9iYWwgJHdwZGI7CgkJJHRpbWVzdGFtcCA9IHN0cnRvdGltZSggJHRoaXMtPmZpbHRlcnNbJ3N0YXJ0X2RhdGUnXSApOwoJCWlmICggISAkdGltZXN0YW1wICkgewoJCQlyZXR1cm47CgkJfQoJCSR0aGlzLT53aGVyZXNbXSA9ICR3cGRiLT5wcmVwYXJlKCAncC5wb3N0X2RhdGUgPj0gJXMnLCBkYXRlKCAnWS1tLWQgMDA6MDA6MDAnLCAkdGltZXN0YW1wICkgKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZW5kX2RhdGVfd2hlcmUoKSB7CgkJZ2xvYmFsICR3cGRiOwoJCWlmICggcHJlZ19tYXRjaCggJy9eXGR7NH0tXGR7Mn0kLycsICR0aGlzLT5maWx0ZXJzWydlbmRfZGF0ZSddICkgKSB7CgkJCSR0aW1lc3RhbXAgPSAkdGhpcy0+Z2V0X3RpbWVzdGFtcF9mb3JfdGhlX2xhc3RfZGF5X29mX2FfbW9udGgoICR0aGlzLT5maWx0ZXJzWydlbmRfZGF0ZSddICk7CgkJfSBlbHNlIHsKCQkJJHRpbWVzdGFtcCA9IHN0cnRvdGltZSggJHRoaXMtPmZpbHRlcnNbJ2VuZF9kYXRlJ10gKTsKCQl9CgkJaWYgKCAhICR0aW1lc3RhbXAgKSB7CgkJCXJldHVybjsKCQl9CgkJJHRoaXMtPndoZXJlc1tdID0gJHdwZGItPnByZXBhcmUoICdwLnBvc3RfZGF0ZSA8PSAlcycsIGRhdGUoICdZLW0tZCAyMzo1OTo1OScsICR0aW1lc3RhbXAgKSApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzdGFydF9pZF93aGVyZSgpIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSRzdGFydF9pZCA9IGFic2ludCggJHRoaXMtPmZpbHRlcnNbJ3N0YXJ0X2lkJ10gKTsKCQlpZiAoIDAgPT09ICRzdGFydF9pZCApIHsKCQkJcmV0dXJuOwoJCX0KCQkkdGhpcy0+d2hlcmVzW10gPSAkd3BkYi0+cHJlcGFyZSggJ3AuSUQgPj0gJWQnLCAkc3RhcnRfaWQgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF90aW1lc3RhbXBfZm9yX3RoZV9sYXN0X2RheV9vZl9hX21vbnRoKCAkeXl5eV9tbSApIHsKCQlyZXR1cm4gc3RydG90aW1lKCAiJHl5eXlfbW0gKzFtb250aCAtMWRheSIgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNhdGVnb3J5X3doZXJlKCkgewoJCWdsb2JhbCAkd3BkYjsKCQlpZiAoICdwb3N0JyAhPT0gJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfdHlwZSddICYmICEgaW5fYXJyYXkoICdwb3N0JywgKGFycmF5KSAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10sIHRydWUgKSApIHsKCQkJcmV0dXJuOwoJCX0KCQkkY2F0ZWdvcnkgPSAkdGhpcy0+ZmluZF9jYXRlZ29yeV9mcm9tX2FueV9vYmplY3QoICR0aGlzLT5maWx0ZXJzWydjYXRlZ29yeSddICk7CgkJaWYgKCAhICRjYXRlZ29yeSApIHsKCQkJcmV0dXJuOwoJCX0KCQkkdGhpcy0+Y2F0ZWdvcnkgPSAkY2F0ZWdvcnk7CgkJJHRoaXMtPmpvaW5zW10gID0gIklOTkVSIEpPSU4geyR3cGRiLT50ZXJtX3JlbGF0aW9uc2hpcHN9IEFTIHRyIE9OIChwLklEID0gdHIub2JqZWN0X2lkKSI7CgkJJHRoaXMtPndoZXJlc1tdID0gJHdwZGItPnByZXBhcmUoICd0ci50ZXJtX3RheG9ub215X2lkID0gJWQnLCAkY2F0ZWdvcnktPnRlcm1fdGF4b25vbXlfaWQgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIG1heF9udW1fcG9zdHMoKSB7CgkJaWYgKCAkdGhpcy0+ZmlsdGVyc1snbWF4X251bV9wb3N0cyddID4gMCApIHsKCQkJcmV0dXJuICJMSU1JVCB7JHRoaXMtPmZpbHRlcnNbJ21heF9udW1fcG9zdHMnXX0iOwoJCX0gZWxzZSB7CgkJCXJldHVybiAnJzsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBpbmNsdWRlX2F0dGFjaG1lbnRfaWRzKCAkcG9zdF9pZHMgKSB7CgkJZ2xvYmFsICR3cGRiOwoJCWlmICggISAkcG9zdF9pZHMgKSB7CgkJCXJldHVybiBbXTsKCQl9CgkJJGF0dGFjaG1lbnRfaWRzID0gW107CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5Db2RlQW5hbHlzaXMuQXNzaWdubWVudEluQ29uZGl0aW9uLkZvdW5kSW5XaGlsZUNvbmRpdGlvbiAtLSBBc3NpZ21lbnQgaXMgcGFydCBvZiB0aGUgYnJlYWsgY29uZGl0aW9uLgoJCXdoaWxlICggJGJhdGNoX29mX3Bvc3RfaWRzID0gYXJyYXlfc3BsaWNlKCAkcG9zdF9pZHMsIDAsIHNlbGY6OlFVRVJZX0NIVU5LICkgKSB7CgkJCSRwb3N0X3BhcmVudF9jb25kaXRpb24gPSBfd3BfZXhwb3J0X2J1aWxkX0lOX2NvbmRpdGlvbiggJ3Bvc3RfcGFyZW50JywgJGJhdGNoX29mX3Bvc3RfaWRzICk7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gRXNjYXBlZCBpbiB3cGNsaV9leHBvcnRfYnVpbGRfaW5fY29uZGl0aW9uKCkgZnVuY3Rpb24uCgkJCSRhdHRhY2htZW50X2lkcyA9IGFycmF5X21lcmdlKCAkYXR0YWNobWVudF9pZHMsIChhcnJheSkgJHdwZGItPmdldF9jb2woICJTRUxFQ1QgSUQgRlJPTSB7JHdwZGItPnBvc3RzfSBXSEVSRSBwb3N0X3R5cGUgPSAnYXR0YWNobWVudCcgQU5EIHskcG9zdF9wYXJlbnRfY29uZGl0aW9ufSIgKSApOwoJCX0KCQlyZXR1cm4gYXJyYXlfbWFwKCAnaW50dmFsJywgJGF0dGFjaG1lbnRfaWRzICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBibG9naW5mb19yc3MoICRzZWN0aW9uICkgewoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJcmV0dXJuIGFwcGx5X2ZpbHRlcnMoICdibG9naW5mb19yc3MnLCBnZXRfYmxvZ2luZm9fcnNzKCAkc2VjdGlvbiApLCAkc2VjdGlvbiApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZmluZF91c2VyX2Zyb21fYW55X29iamVjdCggJHVzZXIgKSB7CgkJaWYgKCBpc19udW1lcmljKCAkdXNlciApICkgewoJCQlyZXR1cm4gZ2V0X3VzZXJfYnkoICdpZCcsICR1c2VyICk7CgkJfSBlbHNlaWYgKCBpc19zdHJpbmcoICR1c2VyICkgKSB7CgkJCXJldHVybiBnZXRfdXNlcl9ieSggJ2xvZ2luJywgJHVzZXIgKTsKCQl9IGVsc2VpZiAoIGlzc2V0KCAkdXNlci0+SUQgKSApIHsKCQkJcmV0dXJuIGdldF91c2VyX2J5KCAnaWQnLCAkdXNlci0+SUQgKTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZmluZF9jYXRlZ29yeV9mcm9tX2FueV9vYmplY3QoICRjYXRlZ29yeSApIHsKCQlpZiAoIGlzX251bWVyaWMoICRjYXRlZ29yeSApICkgewoJCQlyZXR1cm4gZ2V0X3Rlcm0oICRjYXRlZ29yeSwgJ2NhdGVnb3J5JyApOwoJCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkY2F0ZWdvcnkgKSApIHsKCQkJJHRlcm0gPSB0ZXJtX2V4aXN0cyggJGNhdGVnb3J5LCAnY2F0ZWdvcnknICk7CgkJCXJldHVybiBpc3NldCggJHRlcm1bJ3Rlcm1faWQnXSApID8gZ2V0X3Rlcm0oICR0ZXJtWyd0ZXJtX2lkJ10sICdjYXRlZ29yeScgKSA6IGZhbHNlOwoJCX0gZWxzZWlmICggaXNzZXQoICRjYXRlZ29yeS0+dGVybV9pZCApICkgewoJCQlyZXR1cm4gZ2V0X3Rlcm0oICRjYXRlZ29yeS0+dGVybV9pZCwgJ2NhdGVnb3J5JyApOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdG9wb2xvZ2ljYWxseV9zb3J0X3Rlcm1zKCAkdGVybXMgKSB7CgkJJHNvcnRlZCA9IFtdOwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuQ29kZUFuYWx5c2lzLkFzc2lnbm1lbnRJbkNvbmRpdGlvbi5Gb3VuZEluV2hpbGVDb25kaXRpb24gLS0gYXNzaWdubWVudCBpcyB1c2VkIGFzIGJyZWFrIGNvbmRpdGlvbi4KCQl3aGlsZSAoICR0ZXJtID0gYXJyYXlfc2hpZnQoICR0ZXJtcyApICkgewoJCQlpZiAoIDAgPT09IChpbnQpICR0ZXJtLT5wYXJlbnQgfHwgaXNzZXQoICRzb3J0ZWRbICR0ZXJtLT5wYXJlbnQgXSApICkgewoJCQkJJHNvcnRlZFsgJHRlcm0tPnRlcm1faWQgXSA9ICR0ZXJtOwoJCQl9IGVsc2UgewoJCQkJJHRlcm1zW10gPSAkdGVybTsKCQkJfQoJCX0KCQlyZXR1cm4gJHNvcnRlZDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2Zvcl9vcnBoYW5lZF90ZXJtcyggJHRlcm1zICkgewoJCSR0ZXJtX2lkcyAgICA9IFtdOwoJCSRoYXZlX3BhcmVudCA9IFtdOwoKCQlmb3JlYWNoICggJHRlcm1zIGFzICR0ZXJtICkgewoJCQkkdGVybV9pZHNbICR0ZXJtLT50ZXJtX2lkIF0gPSB0cnVlOwoJCQlpZiAoIDAgIT09IChpbnQpICR0ZXJtLT5wYXJlbnQgKSB7CgkJCQkkaGF2ZV9wYXJlbnRbXSA9ICR0ZXJtOwoJCQl9CgkJfQoKCQlmb3JlYWNoICggJGhhdmVfcGFyZW50IGFzICRoYXNfcGFyZW50ICkgewoJCQlpZiAoICEgaXNzZXQoICR0ZXJtX2lkc1sgJGhhc19wYXJlbnQtPnBhcmVudCBdICkgKSB7CgkJCQkkdGhpcy0+bWlzc2luZ19wYXJlbnRzID0gJGhhc19wYXJlbnQ7CgkJCQl0aHJvdyBuZXcgV1BfRXhwb3J0X1Rlcm1fRXhjZXB0aW9uKCAiVGVybSBpcyBtaXNzaW5nIGEgcGFyZW50OiB7JGhhc19wYXJlbnQtPnNsdWd9ICh7JGhhc19wYXJlbnQtPnRlcm1fdGF4b25vbXlfaWR9KSIgKTsKCQkJfQoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfdGVybXNfZm9yX3Bvc3QoICRwb3N0ICkgewoJCSR0YXhvbm9taWVzID0gZ2V0X29iamVjdF90YXhvbm9taWVzKCAkcG9zdC0+cG9zdF90eXBlICk7CgkJaWYgKCBlbXB0eSggJHRheG9ub21pZXMgKSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCQlyZXR1cm4gd3BfZ2V0X29iamVjdF90ZXJtcyggJHBvc3QtPklELCAkdGF4b25vbWllcyApID86IFtdOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9tZXRhX2Zvcl9wb3N0KCAkcG9zdCApIHsKCQlnbG9iYWwgJHdwZGI7CgkJJG1ldGFfZm9yX2V4cG9ydCA9IFtdOwoJCSRtZXRhX2Zyb21fZGIgICAgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUICogRlJPTSAkd3BkYi0+cG9zdG1ldGEgV0hFUkUgcG9zdF9pZCA9ICVkIiwgJHBvc3QtPklEICkgKTsKCQlmb3JlYWNoICggJG1ldGFfZnJvbV9kYiBhcyAkbWV0YSApIHsKCQkJaWYgKCAnX2VkaXRfbG9jaycgPT09ICRtZXRhLT5tZXRhX2tleSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJCWlmICggYXBwbHlfZmlsdGVycyggJ3d4cl9leHBvcnRfc2tpcF9wb3N0bWV0YScsIGZhbHNlLCAkbWV0YS0+bWV0YV9rZXksICRtZXRhICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkkbWV0YV9mb3JfZXhwb3J0W10gPSAkbWV0YTsKCQl9CgkJcmV0dXJuICRtZXRhX2Zvcl9leHBvcnQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29tbWVudHNfZm9yX3Bvc3QoICRwb3N0ICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJaWYgKCBpc3NldCggJHRoaXMtPmZpbHRlcnNbJ3NraXBfY29tbWVudHMnXSApICkgewoJCQlyZXR1cm4gW107CgkJfQoKCQkkY29tbWVudHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUICogRlJPTSAkd3BkYi0+Y29tbWVudHMgV0hFUkUgY29tbWVudF9wb3N0X0lEID0gJWQgQU5EIGNvbW1lbnRfYXBwcm92ZWQgPD4gJ3NwYW0nIiwgJHBvc3QtPklEICkgKTsKCQlmb3JlYWNoICggJGNvbW1lbnRzIGFzICRjb21tZW50ICkgewoJCQkkY29tbWVudC0+bWV0YSA9ICR3cGRiLT5nZXRfcmVzdWx0cyggJHdwZGItPnByZXBhcmUoICJTRUxFQ1QgKiBGUk9NICR3cGRiLT5jb21tZW50bWV0YSBXSEVSRSBjb21tZW50X2lkID0gJWQiLCAkY29tbWVudC0+Y29tbWVudF9JRCApICkgPzogW107CgkJfQoJCXJldHVybiAkY29tbWVudHM7Cgl9Cn0KCjw/cGhwCgpjbGFzcyBXUF9FeHBvcnRfUmV0dXJuZXIgZXh0ZW5kcyBXUF9FeHBvcnRfQmFzZV9Xcml0ZXIgewoJcHJpdmF0ZSAkcmVzdWx0ID0gJyc7CgoJcHVibGljIGZ1bmN0aW9uIGV4cG9ydCgpIHsKCQkkdGhpcy0+cHJpdmF0ZSA9ICcnOwoJCXRyeSB7CgkJCXBhcmVudDo6ZXhwb3J0KCk7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9FeGNlcHRpb24gJGUgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gUG9zc2libHkgdXNlZCBieSB0aGlyZCBwYXJ0eSBleHRlbnNpb24uCgkJCSRtZXNzYWdlID0gYXBwbHlfZmlsdGVycyggJ2V4cG9ydF9lcnJvcl9tZXNzYWdlJywgJGUtPmdldE1lc3NhZ2UoKSApOwoJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnd3AtZXhwb3J0LWVycm9yJywgJG1lc3NhZ2UgKTsKCgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9UZXJtX0V4Y2VwdGlvbiAkZSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBQb3NzaWJseSB1c2VkIGJ5IHRoaXJkIHBhcnR5IGV4dGVuc2lvbnMuCgkJCWRvX2FjdGlvbiggJ2V4cG9ydF90ZXJtX29ycGhhbmVkJywgJHRoaXMtPmZvcm1hdHRlci0+ZXhwb3J0LT5taXNzaW5nX3BhcmVudHMgKTsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBQb3NzaWJseSB1c2VkIGJ5IHRoaXJkIHBhcnR5IGV4dGVuc2lvbi4KCQkJJG1lc3NhZ2UgPSBhcHBseV9maWx0ZXJzKCAnZXhwb3J0X3Rlcm1fZXJyb3JfbWVzc2FnZScsICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ3dwLWV4cG9ydC1lcnJvcicsICRtZXNzYWdlICk7CgkJfQoJCXJldHVybiAkdGhpcy0+cmVzdWx0OwoJfQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlKCAkeG1sICkgewoJCSR0aGlzLT5yZXN1bHQgLj0gJHhtbDsKCX0KfQo8P3BocAoKY2xhc3MgV1BfRXhwb3J0X1Rlcm1fRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Cn0KPD9waHAKCmNsYXNzIFdQX0V4cG9ydF9TcGxpdF9GaWxlc19Xcml0ZXIgZXh0ZW5kcyBXUF9FeHBvcnRfQmFzZV9Xcml0ZXIgewoJcHJpdmF0ZSAkbWF4X2ZpbGVfc2l6ZTsKCXByaXZhdGUgJGRlc3RpbmF0aW9uX2RpcmVjdG9yeTsKCXByaXZhdGUgJGZpbGVuYW1lX3RlbXBsYXRlOwoJcHJpdmF0ZSAkYmVmb3JlX3Bvc3RzX3htbDsKCXByaXZhdGUgJGFmdGVyX3Bvc3RzX3htbDsKCglwcml2YXRlICRmOwoJcHJpdmF0ZSAkbmV4dF9maWxlX251bWJlciAgPSAwOwoJcHJpdmF0ZSAkY3VycmVudF9maWxlX3NpemUgPSAwOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGZvcm1hdHRlciwgJHdyaXRlcl9hcmdzID0gW10gKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCggJGZvcm1hdHRlciApOwoKCQlpZiAoICEgZGVmaW5lZCggJ01CX0lOX0JZVEVTJyApICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIFdvcmRQcmVzcyBuYXRpdmUgY29uc3RhbnRzLgoJCQlkZWZpbmUoICdNQl9JTl9CWVRFUycsIDEwMjQgKiAxMDI0ICk7CgkJfQoKCQkvL1RPRE86IGNoZWNrIGlmIGFyZ3MgYXJlIG5vdCBtaXNzaW5nCgkJaWYgKCBpc19udWxsKCAkd3JpdGVyX2FyZ3NbJ21heF9maWxlX3NpemUnXSApICkgewoJCQkkdGhpcy0+bWF4X2ZpbGVfc2l6ZSA9IDE1ICogTUJfSU5fQllURVM7CgkJfSBlbHNlaWYgKCBXUF9DTElfRVhQT1JUX0NPTU1BTkRfTk9fU1BMSVQgPT09IChzdHJpbmcpICR3cml0ZXJfYXJnc1snbWF4X2ZpbGVfc2l6ZSddICkgewoJCQkkdGhpcy0+bWF4X2ZpbGVfc2l6ZSA9IFdQX0NMSV9FWFBPUlRfQ09NTUFORF9OT19TUExJVDsKCQl9IGVsc2UgewoJCQkkdGhpcy0+bWF4X2ZpbGVfc2l6ZSA9ICR3cml0ZXJfYXJnc1snbWF4X2ZpbGVfc2l6ZSddICogTUJfSU5fQllURVM7CgkJfQoKCQkkdGhpcy0+ZGVzdGluYXRpb25fZGlyZWN0b3J5ID0gJHdyaXRlcl9hcmdzWydkZXN0aW5hdGlvbl9kaXJlY3RvcnknXTsKCQkkdGhpcy0+ZmlsZW5hbWVfdGVtcGxhdGUgICAgID0gJHdyaXRlcl9hcmdzWydmaWxlbmFtZV90ZW1wbGF0ZSddOwoJCSR0aGlzLT5iZWZvcmVfcG9zdHNfeG1sICAgICAgPSAkdGhpcy0+Zm9ybWF0dGVyLT5iZWZvcmVfcG9zdHMoKTsKCQkkdGhpcy0+YWZ0ZXJfcG9zdHNfeG1sICAgICAgID0gJHRoaXMtPmZvcm1hdHRlci0+YWZ0ZXJfcG9zdHMoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0KCkgewoJCSR0aGlzLT5zdGFydF9uZXdfZmlsZSgpOwoJCWZvcmVhY2ggKCAkdGhpcy0+Zm9ybWF0dGVyLT5wb3N0cygpIGFzICRwb3N0X3htbCApIHsKCQkJaWYgKCBXUF9DTElfRVhQT1JUX0NPTU1BTkRfTk9fU1BMSVQgIT09ICR0aGlzLT5tYXhfZmlsZV9zaXplICYmICR0aGlzLT5jdXJyZW50X2ZpbGVfc2l6ZSArIHN0cmxlbiggJHBvc3RfeG1sICkgPiAkdGhpcy0+bWF4X2ZpbGVfc2l6ZSApIHsKCQkJCSR0aGlzLT5zdGFydF9uZXdfZmlsZSgpOwoJCQl9CgkJCSR0aGlzLT53cml0ZSggJHBvc3RfeG1sICk7CgkJfQoJCSR0aGlzLT5jbG9zZV9jdXJyZW50X2ZpbGUoKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoICR4bWwgKSB7CgkJJHJlcyA9IGZ3cml0ZSggJHRoaXMtPmYsICR4bWwgKTsKCQlpZiAoIGZhbHNlID09PSAkcmVzICkgewoJCQl0aHJvdyBuZXcgV1BfRXhwb3J0X0V4Y2VwdGlvbiggJ1dQIEV4cG9ydDogZXJyb3Igd3JpdGluZyB0byBleHBvcnQgZmlsZS4nICk7CgkJfQoJCSR0aGlzLT5jdXJyZW50X2ZpbGVfc2l6ZSArPSBzdHJsZW4oICR4bWwgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0X25ld19maWxlKCkgewoJCWlmICggJHRoaXMtPmYgKSB7CgkJCSR0aGlzLT5jbG9zZV9jdXJyZW50X2ZpbGUoKTsKCQl9CgkJJGZpbGVfcGF0aCA9ICR0aGlzLT5uZXh0X2ZpbGVfcGF0aCgpOwoJCSR0aGlzLT5mICAgPSBmb3BlbiggJGZpbGVfcGF0aCwgJ3cnICk7CgkJaWYgKCAhICR0aGlzLT5mICkgewoJCQl0aHJvdyBuZXcgV1BfRXhwb3J0X0V4Y2VwdGlvbiggIldQIEV4cG9ydDogZXJyb3Igb3BlbmluZyB7JGZpbGVfcGF0aH0gZm9yIHdyaXRpbmcuIiApOwoJCX0KCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFBvc3NpYmx5IHVzZWQgYnkgdGhpcmQgcGFydHkgZXh0ZW5zaW9uLgoJCWRvX2FjdGlvbiggJ3dwX2V4cG9ydF9uZXdfZmlsZScsICRmaWxlX3BhdGggKTsKCQkkdGhpcy0+Y3VycmVudF9maWxlX3NpemUgPSAwOwoJCSR0aGlzLT53cml0ZSggJHRoaXMtPmJlZm9yZV9wb3N0c194bWwgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNsb3NlX2N1cnJlbnRfZmlsZSgpIHsKCQlpZiAoICEgJHRoaXMtPmYgKSB7CgkJCXJldHVybjsKCQl9CgkJJHRoaXMtPndyaXRlKCAkdGhpcy0+YWZ0ZXJfcG9zdHNfeG1sICk7CgkJZmNsb3NlKCAkdGhpcy0+ZiApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gbmV4dF9maWxlX25hbWUoKSB7CgkJJG5leHRfZmlsZV9uYW1lID0gc3ByaW50ZiggJHRoaXMtPmZpbGVuYW1lX3RlbXBsYXRlLCAkdGhpcy0+bmV4dF9maWxlX251bWJlciApOwoJCSR0aGlzLT5uZXh0X2ZpbGVfbnVtYmVyKys7CgkJcmV0dXJuICRuZXh0X2ZpbGVfbmFtZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIG5leHRfZmlsZV9wYXRoKCkgewoJCXJldHVybiB1bnRyYWlsaW5nc2xhc2hpdCggJHRoaXMtPmRlc3RpbmF0aW9uX2RpcmVjdG9yeSApIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICR0aGlzLT5uZXh0X2ZpbGVfbmFtZSgpOwoJfQoKfQo8P3BocAoKY2xhc3MgV1BfRXhwb3J0X0ZpbGVfV3JpdGVyIGV4dGVuZHMgV1BfRXhwb3J0X0Jhc2VfV3JpdGVyIHsKCXByaXZhdGUgJGY7Cglwcml2YXRlICRmaWxlX25hbWU7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZm9ybWF0dGVyLCAkZmlsZV9uYW1lICkgewoJCXBhcmVudDo6X19jb25zdHJ1Y3QoICRmb3JtYXR0ZXIgKTsKCQkkdGhpcy0+ZmlsZV9uYW1lID0gJGZpbGVfbmFtZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0KCkgewoJCSR0aGlzLT5mID0gZm9wZW4oICR0aGlzLT5maWxlX25hbWUsICd3JyApOwoJCWlmICggISAkdGhpcy0+ZiApIHsKCQkJdGhyb3cgbmV3IFdQX0V4cG9ydF9FeGNlcHRpb24oICJXUCBFeHBvcnQ6IGVycm9yIG9wZW5pbmcgeyR0aGlzLT5maWxlX25hbWV9IGZvciB3cml0aW5nLiIgKTsKCQl9CgoJCXRyeSB7CgkJCXBhcmVudDo6ZXhwb3J0KCk7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9FeGNlcHRpb24gJGUgKSB7CgkJCWZjbG9zZSggJHRoaXMtPmYgKTsKCQkJdGhyb3cgJGU7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9UZXJtX0V4Y2VwdGlvbiAkZSApIHsKCQkJZmNsb3NlKCAkdGhpcy0+ZiApOwoJCQl0aHJvdyAkZTsKCQl9CgoJCWZjbG9zZSggJHRoaXMtPmYgKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoICR4bWwgKSB7CgkJJHJlcyA9IGZ3cml0ZSggJHRoaXMtPmYsICR4bWwgKTsKCQlpZiAoIGZhbHNlID09PSAkcmVzICkgewoJCQl0aHJvdyBuZXcgV1BfRXhwb3J0X0V4Y2VwdGlvbiggJ1dQIEV4cG9ydDogZXJyb3Igd3JpdGluZyB0byBleHBvcnQgZmlsZS4nICk7CgkJfQoJfQp9Cjw/cGhwCgpjbGFzcyBXUF9FeHBvcnRfT3h5bWVsIGV4dGVuZHMgT3h5bWVsIHsKCXB1YmxpYyBmdW5jdGlvbiBvcHRpb25hbCggJHRhZ19uYW1lLCAkY29udGVudHMgKSB7CgkJaWYgKCAkY29udGVudHMgKSB7CgkJCSR0aGlzLT4kdGFnX25hbWUoICRjb250ZW50cyApOwoJCX0KCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG9wdGlvbmFsX2NkYXRhKCAkdGFnX25hbWUsICRjb250ZW50cyApIHsKCQlpZiAoICRjb250ZW50cyApIHsKCQkJJHRoaXMtPiR0YWdfbmFtZS0+Y29udGFpbnMtPmNkYXRhKCAkY29udGVudHMgKS0+ZW5kOwoJCX0KCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNkYXRhKCAkdGV4dCApIHsKCQlpZiAoIGlzX3N0cmluZyggJHRleHQgKSAmJiAhIHNlZW1zX3V0ZjgoICR0ZXh0ICkgKSB7CgkJCSR0ZXh0ID0gdXRmOF9lbmNvZGUoICR0ZXh0ICk7CgkJfQoJCXJldHVybiBwYXJlbnQ6OmNkYXRhKCAkdGV4dCApOwoJfQp9Cgo8P3BocAoKYWJzdHJhY3QgY2xhc3MgV1BfRXhwb3J0X0Jhc2VfV3JpdGVyIHsKCXByb3RlY3RlZCAkZm9ybWF0dGVyOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGZvcm1hdHRlciApIHsKCQkkdGhpcy0+Zm9ybWF0dGVyID0gJGZvcm1hdHRlcjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0KCkgewoJCSR0aGlzLT53cml0ZSggJHRoaXMtPmZvcm1hdHRlci0+YmVmb3JlX3Bvc3RzKCkgKTsKCQlmb3JlYWNoICggJHRoaXMtPmZvcm1hdHRlci0+cG9zdHMoKSBhcyAkcG9zdF9pbl93eHIgKSB7CgkJCSR0aGlzLT53cml0ZSggJHBvc3RfaW5fd3hyICk7CgkJfQoJCSR0aGlzLT53cml0ZSggJHRoaXMtPmZvcm1hdHRlci0+YWZ0ZXJfcG9zdHMoKSApOwoJfQoKCWFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSggJHhtbCApOwp9Cjw/cGhwCi8qKgogKiBWZXJzaW9uIG51bWJlciBmb3IgdGhlIGV4cG9ydCBmb3JtYXQuCiAqCiAqIEJ1bXAgdGhpcyB3aGVuIHNvbWV0aGluZyBjaGFuZ2VzIHRoYXQgbWlnaHQgYWZmZWN0IGNvbXBhdGliaWxpdHkuCiAqCiAqIEBzaW5jZSAyLjUuMAogKi8KZGVmaW5lKCAnV1hSX1ZFUlNJT04nLCAnMS4yJyApOyAvL3BocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZENvbnN0YW50Rm91bmQgLS0gV29yZFByZXNzIGNvbnN0YW50LgoKLyoqCiAqIFJlc3BvbnNpYmxlIGZvciBmb3JtYXR0aW5nIHRoZSBkYXRhIGluIFdQX0V4cG9ydF9RdWVyeSB0byBXWFIKICovCmNsYXNzIFdQX0V4cG9ydF9XWFJfRm9ybWF0dGVyIHsKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGV4cG9ydCApIHsKCQkkdGhpcy0+ZXhwb3J0ICAgICAgPSAkZXhwb3J0OwoJCSR0aGlzLT53eHJfdmVyc2lvbiA9IFdYUl9WRVJTSU9OOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBiZWZvcmVfcG9zdHMoICRyZXF1ZXN0ZWRfc2VjdGlvbnMgPSBbXSApIHsKCQkkYXZhaWxhYmxlX3NlY3Rpb25zID0gWwoJCQknaGVhZGVyJywKCQkJJ3NpdGVfbWV0YWRhdGEnLAoJCQknYXV0aG9ycycsCgkJCSdjYXRlZ29yaWVzJywKCQkJJ3RhZ3MnLAoJCQknbmF2X21lbnVfdGVybXMnLAoJCQknY3VzdG9tX3RheG9ub21pZXNfdGVybXMnLAoJCQkncnNzMl9oZWFkX2FjdGlvbicsCgkJXTsKCgkJJGJlZm9yZV9wb3N0c194bWwgPSAnJzsKCgkJZm9yZWFjaCAoICRhdmFpbGFibGVfc2VjdGlvbnMgYXMgJHNlY3Rpb24gKSB7CgkJCWlmICggISAkcmVxdWVzdGVkX3NlY3Rpb25zIHx8IGluX2FycmF5KCAkc2VjdGlvbiwgJHJlcXVlc3RlZF9zZWN0aW9ucywgdHJ1ZSApICkgewoJCQkJJGJlZm9yZV9wb3N0c194bWwgLj0gJHRoaXMtPiRzZWN0aW9uKCk7CgkJCX0KCQl9CgoJCXJldHVybiAkYmVmb3JlX3Bvc3RzX3htbDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcG9zdHMoKSB7CgkJcmV0dXJuIG5ldyBXUF9NYXBfSXRlcmF0b3IoICR0aGlzLT5leHBvcnQtPnBvc3RzKCksIFsgJHRoaXMsICdwb3N0JyBdICk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGFmdGVyX3Bvc3RzKCkgewoJCXJldHVybiAkdGhpcy0+Zm9vdGVyKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGhlYWRlcigpIHsKCQkkb3h5bWVsICAgICAgICAgICA9IG5ldyBPeHltZWwoKTsKCQkkd3BfZ2VuZXJhdG9yX3RhZyA9ICR0aGlzLT5leHBvcnQtPndwX2dlbmVyYXRvcl90YWcoKTsKCQkkY29tbWVudCAgICAgICAgICA9IDw8PENPTU1FTlQKCiBUaGlzIGlzIGEgV29yZFByZXNzIGVYdGVuZGVkIFJTUyBmaWxlIGdlbmVyYXRlZCBieSBXb3JkUHJlc3MgYXMgYW4gZXhwb3J0IG9mIHlvdXIgc2l0ZS4KIEl0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHlvdXIgc2l0ZSdzIHBvc3RzLCBwYWdlcywgY29tbWVudHMsIGNhdGVnb3JpZXMsIGFuZCBvdGhlciBjb250ZW50LgogWW91IG1heSB1c2UgdGhpcyBmaWxlIHRvIHRyYW5zZmVyIHRoYXQgY29udGVudCBmcm9tIG9uZSBzaXRlIHRvIGFub3RoZXIuCiBUaGlzIGZpbGUgaXMgbm90IGludGVuZGVkIHRvIHNlcnZlIGFzIGEgY29tcGxldGUgYmFja3VwIG9mIHlvdXIgc2l0ZS4KCiBUbyBpbXBvcnQgdGhpcyBpbmZvcm1hdGlvbiBpbnRvIGEgV29yZFByZXNzIHNpdGUgZm9sbG93IHRoZXNlIHN0ZXBzOgogMS4gTG9nIGluIHRvIHRoYXQgc2l0ZSBhcyBhbiBhZG1pbmlzdHJhdG9yLgogMi4gR28gdG8gVG9vbHM6IEltcG9ydCBpbiB0aGUgV29yZFByZXNzIGFkbWluIHBhbmVsLgogMy4gSW5zdGFsbCB0aGUgIldvcmRQcmVzcyIgaW1wb3J0ZXIgZnJvbSB0aGUgbGlzdC4KIDQuIEFjdGl2YXRlICYgUnVuIEltcG9ydGVyLgogNS4gVXBsb2FkIHRoaXMgZmlsZSB1c2luZyB0aGUgZm9ybSBwcm92aWRlZCBvbiB0aGF0IHBhZ2UuCiA2LiBZb3Ugd2lsbCBmaXJzdCBiZSBhc2tlZCB0byBtYXAgdGhlIGF1dGhvcnMgaW4gdGhpcyBleHBvcnQgZmlsZSB0byB1c2VycwogICAgb24gdGhlIHNpdGUuIEZvciBlYWNoIGF1dGhvciwgeW91IG1heSBjaG9vc2UgdG8gbWFwIHRvIGFuCiAgICBleGlzdGluZyB1c2VyIG9uIHRoZSBzaXRlIG9yIHRvIGNyZWF0ZSBhIG5ldyB1c2VyLgogNy4gV29yZFByZXNzIHdpbGwgdGhlbiBpbXBvcnQgZWFjaCBvZiB0aGUgcG9zdHMsIHBhZ2VzLCBjb21tZW50cywgY2F0ZWdvcmllcywgZXRjLgogICAgY29udGFpbmVkIGluIHRoaXMgZmlsZSBpbnRvIHlvdXIgc2l0ZS4KCkNPTU1FTlQ7CgkJcmV0dXJuICRveHltZWwKCQkJLT54bWwKCQkJLT5jb21tZW50KCAkY29tbWVudCApCgkJCS0+cmF3KCAkd3BfZ2VuZXJhdG9yX3RhZyApCgkJCS0+b3Blbl9yc3MoCgkJCQlbCgkJCQkJJ3ZlcnNpb24nICAgICAgID0+ICcyLjAnLAoJCQkJCSd4bWxuczpleGNlcnB0JyA9PiAiaHR0cDovL3dvcmRwcmVzcy5vcmcvZXhwb3J0L3skdGhpcy0+d3hyX3ZlcnNpb259L2V4Y2VycHQvIiwKCQkJCQkneG1sbnM6Y29udGVudCcgPT4gJ2h0dHA6Ly9wdXJsLm9yZy9yc3MvMS4wL21vZHVsZXMvY29udGVudC8nLAoJCQkJCSd4bWxuczp3ZncnICAgICA9PiAnaHR0cDovL3dlbGxmb3JtZWR3ZWIub3JnL0NvbW1lbnRBUEkvJywKCQkJCQkneG1sbnM6ZGMnICAgICAgPT4gJ2h0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvJywKCQkJCQkneG1sbnM6d3AnICAgICAgPT4gImh0dHA6Ly93b3JkcHJlc3Mub3JnL2V4cG9ydC97JHRoaXMtPnd4cl92ZXJzaW9ufS8iLAoJCQkJXQoJCQkpCgkJCQktPm9wZW5fY2hhbm5lbAoJCQkJLT50b19zdHJpbmcoKTsKCgl9CgoJcHVibGljIGZ1bmN0aW9uIHNpdGVfbWV0YWRhdGEoKSB7CgkJJG94eW1lbCAgID0gbmV3IE94eW1lbCgpOwoJCSRtZXRhZGF0YSA9ICR0aGlzLT5leHBvcnQtPnNpdGVfbWV0YWRhdGEoKTsKCQlyZXR1cm4gJG94eW1lbAoJCQktPnRpdGxlKCAkbWV0YWRhdGFbJ25hbWUnXSApCgkJCS0+bGluayggJG1ldGFkYXRhWyd1cmwnXSApCgkJCS0+ZGVzY3JpcHRpb24oICRtZXRhZGF0YVsnZGVzY3JpcHRpb24nXSApCgkJCS0+cHViRGF0ZSggJG1ldGFkYXRhWydwdWJEYXRlJ10gKQoJCQktPmxhbmd1YWdlKCAkbWV0YWRhdGFbJ2xhbmd1YWdlJ10gKQoJCQktPnRhZyggJ3dwOnd4cl92ZXJzaW9uJywgJHRoaXMtPnd4cl92ZXJzaW9uICkKCQkJLT50YWcoICd3cDpiYXNlX3NpdGVfdXJsJywgJG1ldGFkYXRhWydzaXRlX3VybCddICkKCQkJLT50YWcoICd3cDpiYXNlX2Jsb2dfdXJsJywgJG1ldGFkYXRhWydibG9nX3VybCddICkKCQkJLT50b19zdHJpbmcoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gYXV0aG9ycygpIHsKCQkkb3h5bWVsICA9IG5ldyBPeHltZWwoKTsKCQkkYXV0aG9ycyA9ICR0aGlzLT5leHBvcnQtPmF1dGhvcnMoKTsKCQlmb3JlYWNoICggJGF1dGhvcnMgYXMgJGF1dGhvciApIHsKCQkJJG94eW1lbAoJCQkJLT50YWcoICd3cDphdXRob3InICktPmNvbnRhaW5zCgkJCQkJLT50YWcoICd3cDphdXRob3JfaWQnLCAkYXV0aG9yLT5JRCApCgkJCQkJLT50YWcoICd3cDphdXRob3JfbG9naW4nLCAkYXV0aG9yLT51c2VyX2xvZ2luICkKCQkJCQktPnRhZyggJ3dwOmF1dGhvcl9lbWFpbCcsICRhdXRob3ItPnVzZXJfZW1haWwgKQoJCQkJCS0+dGFnKCAnd3A6YXV0aG9yX2Rpc3BsYXlfbmFtZScgKS0+Y29udGFpbnMtPmNkYXRhKCAkYXV0aG9yLT5kaXNwbGF5X25hbWUgKS0+ZW5kCgkJCQkJLT50YWcoICd3cDphdXRob3JfZmlyc3RfbmFtZScgKS0+Y29udGFpbnMtPmNkYXRhKCAkYXV0aG9yLT51c2VyX2ZpcnN0bmFtZSApLT5lbmQKCQkJCQktPnRhZyggJ3dwOmF1dGhvcl9sYXN0X25hbWUnICktPmNvbnRhaW5zLT5jZGF0YSggJGF1dGhvci0+dXNlcl9sYXN0bmFtZSApLT5lbmQKCQkJCQktPmVuZDsKCQl9CgkJcmV0dXJuICRveHltZWwtPnRvX3N0cmluZygpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjYXRlZ29yaWVzKCkgewoJCSRveHltZWwgICAgID0gbmV3IFdQX0V4cG9ydF9PeHltZWwoKTsKCQkkY2F0ZWdvcmllcyA9ICR0aGlzLT5leHBvcnQtPmNhdGVnb3JpZXMoKTsKCQlmb3JlYWNoICggJGNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5ICkgewoJCQkkY2F0ZWdvcnktPnBhcmVudF9zbHVnID0gJGNhdGVnb3J5LT5wYXJlbnQgPyAkY2F0ZWdvcmllc1sgJGNhdGVnb3J5LT5wYXJlbnQgXS0+c2x1ZyA6ICcnOwoJCQkkb3h5bWVsLT50YWcoICd3cDpjYXRlZ29yeScgKS0+Y29udGFpbnMKCQkJCS0+dGFnKCAnd3A6dGVybV9pZCcsICRjYXRlZ29yeS0+dGVybV9pZCApCgkJCQktPnRhZyggJ3dwOmNhdGVnb3J5X25pY2VuYW1lJywgJGNhdGVnb3J5LT5zbHVnICkKCQkJCS0+dGFnKCAnd3A6Y2F0ZWdvcnlfcGFyZW50JywgJGNhdGVnb3J5LT5wYXJlbnRfc2x1ZyApCgkJCQktPm9wdGlvbmFsX2NkYXRhKCAnd3A6Y2F0X25hbWUnLCAkY2F0ZWdvcnktPm5hbWUgKQoJCQkJLT5vcHRpb25hbF9jZGF0YSggJ3dwOmNhdGVnb3J5X2Rlc2NyaXB0aW9uJywgJGNhdGVnb3J5LT5kZXNjcmlwdGlvbiApCgkJCQktPmVuZDsKCQl9CgkJcmV0dXJuICRveHltZWwtPnRvX3N0cmluZygpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiB0YWdzKCkgewoJCSRveHltZWwgPSBuZXcgV1BfRXhwb3J0X094eW1lbCgpOwoJCSR0YWdzICAgPSAkdGhpcy0+ZXhwb3J0LT50YWdzKCk7CgkJZm9yZWFjaCAoICR0YWdzIGFzICR0YWcgKSB7CgkJCSRveHltZWwtPnRhZyggJ3dwOnRhZycgKS0+Y29udGFpbnMKCQkJCS0+dGFnKCAnd3A6dGVybV9pZCcsICR0YWctPnRlcm1faWQgKQoJCQkJLT50YWcoICd3cDp0YWdfc2x1ZycsICR0YWctPnNsdWcgKQoJCQkJLT5vcHRpb25hbF9jZGF0YSggJ3dwOnRhZ19uYW1lJywgJHRhZy0+bmFtZSApCgkJCQktPm9wdGlvbmFsX2NkYXRhKCAnd3A6dGFnX2Rlc2NyaXB0aW9uJywgJHRhZy0+ZGVzY3JpcHRpb24gKQoJCQkJLT5lbmQ7CgkJfQoJCXJldHVybiAkb3h5bWVsLT50b19zdHJpbmcoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gbmF2X21lbnVfdGVybXMoKSB7CgkJcmV0dXJuICR0aGlzLT50ZXJtcyggJHRoaXMtPmV4cG9ydC0+bmF2X21lbnVfdGVybXMoKSApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjdXN0b21fdGF4b25vbWllc190ZXJtcygpIHsKCQlyZXR1cm4gJHRoaXMtPnRlcm1zKCAkdGhpcy0+ZXhwb3J0LT5jdXN0b21fdGF4b25vbWllc190ZXJtcygpICk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHJzczJfaGVhZF9hY3Rpb24oKSB7CgkJb2Jfc3RhcnQoKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFdvcmRQcmVzcyBuYXRpdmUgaG9vay4KCQlkb19hY3Rpb24oICdyc3MyX2hlYWQnICk7CgkJcmV0dXJuIG9iX2dldF9jbGVhbigpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBwb3N0KCAkcG9zdCApIHsKCQkkb3h5bWVsICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgV1BfRXhwb3J0X094eW1lbCgpOwoJCSRHTE9CQUxTWyd3cF9xdWVyeSddLT5pbl90aGVfbG9vcCA9IHRydWU7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZS5Qcm9oaWJpdGVkIC0tIEludGVudGlvbmFsLgoJCSRHTE9CQUxTWydwb3N0J10gPSAkcG9zdDsKCQlzZXR1cF9wb3N0ZGF0YSggJHBvc3QgKTsKCgkJJG94eW1lbC0+aXRlbS0+Y29udGFpbnMKCQkJLT50YWcoICd0aXRsZScgKS0+Y29udGFpbnMtPmNkYXRhKCBhcHBseV9maWx0ZXJzKCAndGhlX3RpdGxlX2V4cG9ydCcsICRwb3N0LT5wb3N0X3RpdGxlICkgKS0+ZW5kIC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gV29yZFByZXNzIG5hdGl2ZSBob29rLgoJCQktPmxpbmsoIGVzY191cmwoIGFwcGx5X2ZpbHRlcnMoICd0aGVfcGVybWFsaW5rX3JzcycsIGdldF9wZXJtYWxpbmsoKSApICkgKSAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFdvcmRQcmVzcyBuYXRpdmUgaG9vay4KCQkJLT5wdWJEYXRlKCBteXNxbDJkYXRlKCAnRCwgZCBNIFkgSDppOnMgKzAwMDAnLCBnZXRfcG9zdF90aW1lKCAnWS1tLWQgSDppOnMnLCB0cnVlICksIGZhbHNlICkgKQoJCQktPnRhZyggJ2RjOmNyZWF0b3InLCBnZXRfdGhlX2F1dGhvcl9tZXRhKCAnbG9naW4nICkgKQoJCQktPmd1aWQoIGVzY191cmwoIGdldF90aGVfZ3VpZCgpICksIFsgJ2lzUGVybWFMaW5rJyA9PiAnZmFsc2UnIF0gKQoJCQktPmRlc2NyaXB0aW9uKCAnJyApCgkJCS0+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+ZW5kOwoJCX0KCQlyZXR1cm4gJG94eW1lbDsKCX0KfQo8P3BocAoKY2xhc3MgV1BfSXRlcmF0b3JfRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKfQo8P3BocAoKY2xhc3MgV1BfUG9zdF9JRHNfSXRlcmF0b3IgaW1wbGVtZW50cyBJdGVyYXRvciB7Cglwcml2YXRlICRsaW1pdCA9IDEwMDsKCXByaXZhdGUgJHBvc3RfaWRzOwoJcHJpdmF0ZSAkaWRzX2xlZnQ7Cglwcml2YXRlICRyZXN1bHRzID0gYXJyYXkoKTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRwb3N0X2lkcywgJGxpbWl0ID0gbnVsbCApIHsKCQkkdGhpcy0+ZGIgICAgICAgPSAkR0xPQkFMU1snd3BkYiddOwoJCSR0aGlzLT5wb3N0X2lkcyA9ICRwb3N0X2lkczsKCQkkdGhpcy0+aWRzX2xlZnQgPSAkcG9zdF9pZHM7CgkJaWYgKCAhIGlzX251bGwoICRsaW1pdCApICkgewoJCQkkdGhpcy0+bGltaXQgPSAkbGltaXQ7CgkJfQoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkgewoJCXJldHVybiAkdGhpcy0+cmVzdWx0c1sgJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMgXTsKCX0KCglwdWJsaWMgZnVuY3Rpb24ga2V5KCkgewoJCXJldHVybiAkdGhpcy0+Z2xvYmFsX2luZGV4OwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBuZXh0KCkgewoJCSR0aGlzLT5pbmRleF9pbl9yZXN1bHRzKys7CgkJJHRoaXMtPmdsb2JhbF9pbmRleCsrOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKSB7CgkJJHRoaXMtPnJlc3VsdHMgICAgICAgICAgPSBhcnJheSgpOwoJCSR0aGlzLT5nbG9iYWxfaW5kZXggICAgID0gMDsKCQkkdGhpcy0+aW5kZXhfaW5fcmVzdWx0cyA9IDA7CgkJJHRoaXMtPmlkc19sZWZ0ICAgICAgICAgPSAkdGhpcy0+cG9zdF9pZHM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHZhbGlkKCkgewoJCWlmICggaXNzZXQoICR0aGlzLT5yZXN1bHRzWyAkdGhpcy0+aW5kZXhfaW5fcmVzdWx0cyBdICkgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCQlpZiAoIGVtcHR5KCAkdGhpcy0+aWRzX2xlZnQgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkaGFzX3Bvc3RzID0gJHRoaXMtPmxvYWRfbmV4dF9wb3N0c19mcm9tX2RiKCk7CgkJaWYgKCAhICRoYXNfcG9zdHMgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMgPSAwOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gbG9hZF9uZXh0X3Bvc3RzX2Zyb21fZGIoKSB7CgkJJG5leHRfYmF0Y2hfcG9zdF9pZHMgPSBhcnJheV9zcGxpY2UoICR0aGlzLT5pZHNfbGVmdCwgMCwgJHRoaXMtPmxpbWl0ICk7CgkJJGluX3Bvc3RfaWRzX3NxbCAgICAgPSBfd3BfZXhwb3J0X2J1aWxkX0lOX2NvbmRpdGlvbiggJ0lEJywgJG5leHRfYmF0Y2hfcG9zdF9pZHMgKTsKCQkkdGhpcy0+cmVzdWx0cyAgICAgICA9ICR0aGlzLT5kYi0+Z2V0X3Jlc3VsdHMoICJTRUxFQ1QgKiBGUk9NIHskdGhpcy0+ZGItPnBvc3RzfSBXSEVSRSB7JGluX3Bvc3RfaWRzX3NxbH0iICk7CgkJaWYgKCAhICR0aGlzLT5yZXN1bHRzICkgewoJCQlpZiAoICR0aGlzLT5kYi0+bGFzdF9lcnJvciApIHsKCQkJCXRocm93IG5ldyBXUF9JdGVyYXRvcl9FeGNlcHRpb24oICJEYXRhYmFzZSBlcnJvcjogeyR0aGlzLT5kYi0+bGFzdF9lcnJvcn0iICk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKCmNsYXNzIFdQX0V4cG9ydF9FeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKfQo8P3BocAoKCmNsYXNzIFdQX0V4cG9ydF9YTUxfT3Zlcl9IVFRQIGV4dGVuZHMgV1BfRXhwb3J0X0Jhc2VfV3JpdGVyIHsKCXByaXZhdGUgJGZpbGVfbmFtZTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRmb3JtYXR0ZXIsICRmaWxlX25hbWUgKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCggJGZvcm1hdHRlciApOwoJCSR0aGlzLT5maWxlX25hbWUgPSAkZmlsZV9uYW1lOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBleHBvcnQoKSB7CgkJdHJ5IHsKCQkJJGV4cG9ydCA9ICR0aGlzLT5nZXRfZXhwb3J0KCk7CgkJCSR0aGlzLT5zZW5kX2hlYWRlcnMoKTsKCQkJZWNobyAkZXhwb3J0OwoJCX0gY2F0Y2ggKCBXUF9FeHBvcnRfRXhjZXB0aW9uICRlICkgewoJCQkvLyBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBQb3NzaWJseSB1c2VkIGJ5IHRoaXJkIHBhcnR5IGV4dGVuc2lvbi4KCQkJJG1lc3NhZ2UgPSBhcHBseV9maWx0ZXJzKCAnZXhwb3J0X2Vycm9yX21lc3NhZ2UnLCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJCXdwX2RpZSggJG1lc3NhZ2UsIF9fKCAnRXhwb3J0IEVycm9yJyApLCBbICdiYWNrX2xpbmsnID0+IHRydWUgXSApOwoJCX0gY2F0Y2ggKCBXUF9FeHBvcnRfVGVybV9FeGNlcHRpb24gJGUgKSB7CgkJCWRvX2FjdGlvbiggJ2V4cG9ydF90ZXJtX29ycGhhbmVkJywgJHRoaXMtPmZvcm1hdHRlci0+ZXhwb3J0LT5taXNzaW5nX3BhcmVudHMgKTsKCQkJJG1lc3NhZ2UgPSBhcHBseV9maWx0ZXJzKCAnZXhwb3J0X3Rlcm1fZXJyb3JfbWVzc2FnZScsICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJLy8gcGhwY3M6ZW5hYmxlCgkJCXdwX2RpZSggJG1lc3NhZ2UsIF9fKCAnRXhwb3J0IEVycm9yJyApLCBbICdiYWNrX2xpbmsnID0+IHRydWUgXSApOwoJCX0KCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoICR4bWwgKSB7CgkJJHRoaXMtPnJlc3VsdCAuPSAkeG1sOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZXhwb3J0KCkgewoJCSR0aGlzLT5yZXN1bHQgPSAnJzsKCQlwYXJlbnQ6OmV4cG9ydCgpOwoJCXJldHVybiAkdGhpcy0+cmVzdWx0OwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBzZW5kX2hlYWRlcnMoKSB7CgkJaGVhZGVyKCAnQ29udGVudC1EZXNjcmlwdGlvbjogRmlsZSBUcmFuc2ZlcicgKTsKCQloZWFkZXIoICdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0nIC4gJHRoaXMtPmZpbGVfbmFtZSApOwoJCWhlYWRlciggJ0NvbnRlbnQtVHlwZTogdGV4dC94bWw7IGNoYXJzZXQ9JyAuIGdldF9vcHRpb24oICdibG9nX2NoYXJzZXQnICksIHRydWUgKTsKCX0KfQo8P3BocAoKLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkRnVuY3Rpb25Gb3VuZCAtLSBSZW5hbWluZyBicmVha3MgUGhhciBjb21wYXQuCmZ1bmN0aW9uIHdwX2V4cG9ydCggJGFyZ3MgPSBhcnJheSgpICkgewoJJGRlZmF1bHRzICAgICA9IGFycmF5KAoJCSdmaWx0ZXJzJyAgICAgPT4gYXJyYXkoKSwKCQknZm9ybWF0JyAgICAgID0+ICdXUF9FeHBvcnRfV1hSX0Zvcm1hdHRlcicsCgkJJ3dyaXRlcicgICAgICA9PiAnV1BfRXhwb3J0X1JldHVybmVyJywKCQknd3JpdGVyX2FyZ3MnID0+IG51bGwsCgkpOwoJJGFyZ3MgICAgICAgICA9IHdwX3BhcnNlX2FyZ3MoICRhcmdzLCAkZGVmYXVsdHMgKTsKCSRleHBvcnRfcXVlcnkgPSBuZXcgV1BfRXhwb3J0X1F1ZXJ5KCAkYXJnc1snZmlsdGVycyddICk7CgkkZm9ybWF0dGVyICAgID0gbmV3ICRhcmdzWydmb3JtYXQnXSggJGV4cG9ydF9xdWVyeSApOwoJJHdyaXRlciAgICAgICA9IG5ldyAkYXJnc1snd3JpdGVyJ10oICRmb3JtYXR0ZXIsICRhcmdzWyd3cml0ZXJfYXJncyddICk7Cgl0cnkgewoJCXJldHVybiAkd3JpdGVyLT5leHBvcnQoKTsKCX0gY2F0Y2ggKCBXUF9FeHBvcnRfRXhjZXB0aW9uICRlICkgewoJCXJldHVybiBuZXcgV1BfRXJyb3IoICd3cC1leHBvcnQtZXJyb3InLCAkZS0+Z2V0TWVzc2FnZSgpICk7Cgl9Cn0KCi8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEZ1bmN0aW9uRm91bmQsV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlZhbGlkRnVuY3Rpb25OYW1lLkZ1bmN0aW9uTmFtZUludmFsaWQgLS0gUmVuYW1pbmcgYnJlYWtzIFBoYXIgY29tcGF0LgpmdW5jdGlvbiBfd3BfZXhwb3J0X2J1aWxkX0lOX2NvbmRpdGlvbiggJGNvbHVtbl9uYW1lLCAkdmFsdWVzLCAkZm9ybWF0ID0gJyVzJyApIHsKCWdsb2JhbCAkd3BkYjsKCglpZiAoICEgaXNfYXJyYXkoICR2YWx1ZXMgKSB8fCBlbXB0eSggJHZhbHVlcyApICkgewoJCXJldHVybiAnJzsKCX0KCSRmb3JtYXRzID0gaW1wbG9kZSggJywgJywgYXJyYXlfZmlsbCggMCwgY291bnQoICR2YWx1ZXMgKSwgJGZvcm1hdCApICk7CgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkLFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTFBsYWNlaG9sZGVycy5VbmZpbmlzaGVkUHJlcGFyZSAtLSAkY29sdW1uX25hbWVfc3FsIGVzY2FwZWQgYXMgaWRlbnQsICRmb3JtYXRzIGhhcmRjb2RlZCB2YWx1ZS4KCXJldHVybiAkd3BkYi0+cHJlcGFyZSggInskY29sdW1uX25hbWV9IElOICh7JGZvcm1hdHN9KSIsICR2YWx1ZXMgKTsKfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2V4cG9ydF9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9leHBvcnRfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9leHBvcnRfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2V4cG9ydCcsICdFeHBvcnRfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgpjbGFzcyBTZXJ2ZXJfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIExhdW5jaGVzIFBIUCdzIGJ1aWx0LWluIHdlYiBzZXJ2ZXIgZm9yIGEgc3BlY2lmaWMgV29yZFByZXNzIGluc3RhbGxhdGlvbi4KCSAqCgkgKiBVc2VzIGBwaHAgLVNgIHRvIGxhdW5jaCBhIHdlYiBzZXJ2ZXIgc2VydmluZyB0aGUgV29yZFByZXNzIHdlYnJvb3QuCgkgKiA8aHR0cDovL3BocC5uZXQvbWFudWFsL2VuL2ZlYXR1cmVzLmNvbW1hbmRsaW5lLndlYnNlcnZlci5waHA+CgkgKgoJICogSW1wb3J0YW50bHksIFBIUCdzIGJ1aWx0LWluIHdlYiBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IGAuaHRhY2Nlc3NgIGZpbGVzLgoJICogSWYgdGhpcyBpcyBhIHJlcXVpcmVtZW50LCBwbGVhc2UgdXNlIGEgbW9yZSBhZHZhbmNlZCB3ZWIgc2VydmVyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1ob3N0PTxob3N0Pl0KCSAqIDogVGhlIGhvc3RuYW1lIHRvIGJpbmQgdGhlIHNlcnZlciB0by4KCSAqIC0tLQoJICogZGVmYXVsdDogbG9jYWxob3N0CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3J0PTxwb3J0Pl0KCSAqIDogVGhlIHBvcnQgbnVtYmVyIHRvIGJpbmQgdGhlIHNlcnZlciB0by4KCSAqIC0tLQoJICogZGVmYXVsdDogODA4MAoJICogLS0tCgkgKgoJICogWy0tZG9jcm9vdD08cGF0aD5dCgkgKiA6IFRoZSBwYXRoIHRvIHVzZSBhcyB0aGUgZG9jdW1lbnQgcm9vdC4gSWYgdGhlIHBhdGggZ2xvYmFsIHBhcmFtZXRlciBpcwoJICogc2V0LCB0aGUgZGVmYXVsdCB2YWx1ZSBpcyBpdC4KCSAqCgkgKiBbLS1jb25maWc9PGZpbGU+XQoJICogOiBDb25maWd1cmUgdGhlIHNlcnZlciB3aXRoIGEgc3BlY2lmaWMgLmluaSBmaWxlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTWFrZSB0aGUgaW5zdGFuY2UgYXZhaWxhYmxlIG9uIGFueSBhZGRyZXNzICh3aXRoIHBvcnQgODA4MCkKCSAqICAgICAkIHdwIHNlcnZlciAtLWhvc3Q9MC4wLjAuMAoJICogICAgIFBIUCA1LjYuOSBEZXZlbG9wbWVudCBTZXJ2ZXIgc3RhcnRlZCBhdCBUdWUgTWF5IDI0IDAxOjI3OjExIDIwMTYKCSAqICAgICBMaXN0ZW5pbmcgb24gaHR0cDovLzAuMC4wLjA6ODA4MAoJICogICAgIERvY3VtZW50IHJvb3QgaXMgLwoJICogICAgIFByZXNzIEN0cmwtQyB0byBxdWl0LgoJICoKCSAqICAgICAjIFJ1biBvbiBwb3J0IDgwIChmb3IgbXVsdGlzaXRlKQoJICogICAgICQgd3Agc2VydmVyIC0taG9zdD1sb2NhbGhvc3QubG9jYWxkb21haW4gLS1wb3J0PTgwCgkgKiAgICAgUEhQIDUuNi45IERldmVsb3BtZW50IFNlcnZlciBzdGFydGVkIGF0IFR1ZSBNYXkgMjQgMDE6MzA6MDYgMjAxNgoJICogICAgIExpc3RlbmluZyBvbiBodHRwOi8vbG9jYWxob3N0MS5sb2NhbGRvbWFpbjE6ODAKCSAqICAgICBEb2N1bWVudCByb290IGlzIC8KCSAqICAgICBQcmVzcyBDdHJsLUMgdG8gcXVpdC4KCSAqCgkgKiAgICAgIyBDb25maWd1cmUgdGhlIHNlcnZlciB3aXRoIGEgc3BlY2lmaWMgLmluaSBmaWxlCgkgKiAgICAgJCB3cCBzZXJ2ZXIgLS1jb25maWc9ZGV2ZWxvcG1lbnQuaW5pCgkgKiAgICAgUEhQIDcuMC45IERldmVsb3BtZW50IFNlcnZlciBzdGFydGVkIGF0IE1vbiBBdWcgMjIgMTI6MDk6MDQgMjAxNgoJICogICAgIExpc3RlbmluZyBvbiBodHRwOi8vbG9jYWxob3N0OjgwODAKCSAqICAgICBEb2N1bWVudCByb290IGlzIC8KCSAqICAgICBQcmVzcyBDdHJsLUMgdG8gcXVpdC4KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkZGVmYXVsdHMgICA9IGFycmF5KAoJCQknaG9zdCcgICAgPT4gJ2xvY2FsaG9zdCcsCgkJCSdwb3J0JyAgICA9PiA4MDgwLAoJCQknZG9jcm9vdCcgPT4gISBpc19udWxsKCBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Y29uZmlnWydwYXRoJ10gKSA/IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5jb25maWdbJ3BhdGgnXSA6IGZhbHNlLAoJCQknY29uZmlnJyAgPT4gZ2V0X2NmZ192YXIoICdjZmdfZmlsZV9wYXRoJyApLAoJCSk7CgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoKCQkkZG9jcm9vdCA9ICRhc3NvY19hcmdzWydkb2Nyb290J107CgoJCWlmICggISAkZG9jcm9vdCApIHsKCQkJJGNvbmZpZ19wYXRoID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPnByb2plY3RfY29uZmlnX3BhdGg7CgoJCQlpZiAoICEgJGNvbmZpZ19wYXRoICkgewoJCQkJJGRvY3Jvb3QgPSBBQlNQQVRIOwoJCQl9IGVsc2UgewoJCQkJJGRvY3Jvb3QgPSBkaXJuYW1lKCAkY29uZmlnX3BhdGggKTsKCQkJfQoJCX0KCgkJLy8gR2V0IHRoZSBwYXRoIHRvIHRoZSByb3V0ZXIgZmlsZQoJCSRjb21tYW5kX3Jvb3QgPSBVdGlsc1xwaGFyX3NhZmVfcGF0aCggZGlybmFtZSggX19ESVJfXyApICk7CgkJJHJvdXRlcl9wYXRoICA9ICRjb21tYW5kX3Jvb3QgLiAnL3JvdXRlci5waHAnOwoJCWlmICggISBmaWxlX2V4aXN0cyggJHJvdXRlcl9wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBmaW5kIHJvdXRlci5waHAiICk7CgkJfQoJCSRjbWQgPSBVdGlsc1xlc2NfY21kKAoJCQknJXMgLVMgJXMgLXQgJXMgLWMgJXMgJXMnLAoJCQlXUF9DTEk6OmdldF9waHBfYmluYXJ5KCksCgkJCSRhc3NvY19hcmdzWydob3N0J10gLiAnOicgLiAkYXNzb2NfYXJnc1sncG9ydCddLAoJCQkkZG9jcm9vdCwKCQkJJGFzc29jX2FyZ3NbJ2NvbmZpZyddLAoJCQlVdGlsc1xleHRyYWN0X2Zyb21fcGhhciggJHJvdXRlcl9wYXRoICkKCQkpOwoKCQkkZGVzY3JpcHRvcnMgPSBhcnJheSggU1RESU4sIFNURE9VVCwgU1RERVJSICk7CgoJCS8vIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NjAxODEKCQkkb3B0aW9ucyA9IGFycmF5KCk7CgkJaWYgKCBVdGlsc1xpc193aW5kb3dzKCkgKSB7CgkJCSRvcHRpb25zWydieXBhc3Nfc2hlbGwnXSA9IHRydWU7CgkJfQoKCQlleGl0KCBwcm9jX2Nsb3NlKCBwcm9jX29wZW4oICRjbWQsICRkZXNjcmlwdG9ycywgJHBpcGVzLCBudWxsLCBudWxsLCAkb3B0aW9ucyApICkgKTsKCX0KfQo8P3BocAovLyBVc2VkIGJ5IGB3cCBzZXJ2ZXJgIHRvIHJvdXRlIHJlcXVlc3RzLgoKbmFtZXNwYWNlIFdQX0NMSVxSb3V0ZXI7CgovKioKICogVGhpcyBpcyBhIGNvcHkgb2YgV29yZFByZXNzJ3MgYWRkX2ZpbHRlcigpIGZ1bmN0aW9uLgogKgogKiBXZSBkdXBsaWNhdGUgaXQgYmVjYXVzZSBXb3JkUHJlc3MgaXMgbm90IGxvYWRlZCB5ZXQuCiAqLwpmdW5jdGlvbiBhZGRfZmlsdGVyKCAkdGFnLCAkZnVuY3Rpb25fdG9fYWRkLCAkcHJpb3JpdHkgPSAxMCwgJGFjY2VwdGVkX2FyZ3MgPSAxICkgewoJZ2xvYmFsICR3cF9maWx0ZXIsICRtZXJnZWRfZmlsdGVyczsKCgkkaWR4ID0gX3dwX2ZpbHRlcl9idWlsZF91bmlxdWVfaWQoICR0YWcsICRmdW5jdGlvbl90b19hZGQsICRwcmlvcml0eSApOwoKCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZAoJJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXVsgJGlkeCBdID0gYXJyYXkoCgkJJ2Z1bmN0aW9uJyAgICAgID0+ICRmdW5jdGlvbl90b19hZGQsCgkJJ2FjY2VwdGVkX2FyZ3MnID0+ICRhY2NlcHRlZF9hcmdzLAoJKTsKCXVuc2V0KCAkbWVyZ2VkX2ZpbHRlcnNbICR0YWcgXSApOwoJcmV0dXJuIHRydWU7Cn0KCi8qKgogKiBUaGlzIGlzIGEgY29weSBvZiBXb3JkUHJlc3MncyBfd3BfZmlsdGVyX2J1aWxkX3VuaXF1ZV9pZCgpIGZ1bmN0aW9uLgogKgogKiBXZSBkdXBsaWNhdGUgaXQgYmVjYXVzZSBXb3JkUHJlc3MgaXMgbm90IGxvYWRlZCB5ZXQuCiAqLwpmdW5jdGlvbiBfd3BfZmlsdGVyX2J1aWxkX3VuaXF1ZV9pZCggJHRhZywgJGZ1bmN0aW9uLCAkcHJpb3JpdHkgKSB7CglnbG9iYWwgJHdwX2ZpbHRlcjsKCXN0YXRpYyAkZmlsdGVyX2lkX2NvdW50ID0gMDsKCglpZiAoIGlzX3N0cmluZyggJGZ1bmN0aW9uICkgKSB7CgkJcmV0dXJuICRmdW5jdGlvbjsKCX0KCglpZiAoIGlzX29iamVjdCggJGZ1bmN0aW9uICkgKSB7CgkJLy8gQ2xvc3VyZXMgYXJlIGN1cnJlbnRseSBpbXBsZW1lbnRlZCBhcyBvYmplY3RzCgkJJGZ1bmN0aW9uID0gYXJyYXkoICRmdW5jdGlvbiwgJycgKTsKCX0gZWxzZSB7CgkJJGZ1bmN0aW9uID0gKGFycmF5KSAkZnVuY3Rpb247Cgl9CgoJaWYgKCBpc19vYmplY3QoICRmdW5jdGlvblswXSApICkgewoJCS8vIE9iamVjdCBDbGFzcyBDYWxsaW5nCgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdzcGxfb2JqZWN0X2hhc2gnICkgKSB7CgkJCXJldHVybiBzcGxfb2JqZWN0X2hhc2goICRmdW5jdGlvblswXSApIC4gJGZ1bmN0aW9uWzFdOwoJCX0gZWxzZSB7CgkJCSRvYmpfaWR4ID0gZ2V0X2NsYXNzKCAkZnVuY3Rpb25bMF0gKSAuICRmdW5jdGlvblsxXTsKCQkJaWYgKCAhIGlzc2V0KCAkZnVuY3Rpb25bMF0tPndwX2ZpbHRlcl9pZCApICkgewoJCQkJaWYgKCBmYWxzZSA9PT0gJHByaW9yaXR5ICkgewoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJCSRvYmpfaWR4IC49IGlzc2V0KCAkd3BfZmlsdGVyWyAkdGFnIF1bICRwcmlvcml0eSBdICkKCQkJCQk/IGNvdW50KCAoYXJyYXkpICR3cF9maWx0ZXJbICR0YWcgXVsgJHByaW9yaXR5IF0gKQoJCQkJCTogJGZpbHRlcl9pZF9jb3VudDsKCgkJCQkkZnVuY3Rpb25bMF0tPndwX2ZpbHRlcl9pZCA9ICRmaWx0ZXJfaWRfY291bnQ7CgkJCQkrKyRmaWx0ZXJfaWRfY291bnQ7CgkJCX0gZWxzZSB7CgkJCQkkb2JqX2lkeCAuPSAkZnVuY3Rpb25bMF0tPndwX2ZpbHRlcl9pZDsKCQkJfQoKCQkJcmV0dXJuICRvYmpfaWR4OwoJCX0KCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkZnVuY3Rpb25bMF0gKSApIHsKCQkvLyBTdGF0aWMgQ2FsbGluZwoJCXJldHVybiAkZnVuY3Rpb25bMF0gLiAnOjonIC4gJGZ1bmN0aW9uWzFdOwoJfQp9CgpmdW5jdGlvbiBfZ2V0X2Z1bGxfaG9zdCggJHVybCApIHsKCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuQWx0ZXJuYXRpdmVGdW5jdGlvbnMucGFyc2VfdXJsX3BhcnNlX3VybAoJJHBhcnNlZF91cmwgPSBwYXJzZV91cmwoICR1cmwgKTsKCgkkaG9zdCA9ICRwYXJzZWRfdXJsWydob3N0J107CglpZiAoIGlzc2V0KCAkcGFyc2VkX3VybFsncG9ydCddICkgJiYgODAgIT09ICRwYXJzZWRfdXJsWydwb3J0J10gKSB7CgkJJGhvc3QgLj0gJzonIC4gJHBhcnNlZF91cmxbJ3BvcnQnXTsKCX0KCglyZXR1cm4gJGhvc3Q7Cn0KCi8vIFdlIG5lZWQgdG8gdHJpY2sgV29yZFByZXNzIGludG8gdXNpbmcgdGhlIFVSTCBzZXQgYnkgYHdwIHNlcnZlcmAsIGVzcGVjaWFsbHkgb24gbXVsdGlzaXRlLgphZGRfZmlsdGVyKAoJJ29wdGlvbl9ob21lJywKCWZ1bmN0aW9uICggJHVybCApIHsKCQkkR0xPQkFMU1snd3BjbGlfc2VydmVyX29yaWdpbmFsX3VybCddID0gJHVybDsKCgkJcmV0dXJuICdodHRwOi8vJyAuICRfU0VSVkVSWydIVFRQX0hPU1QnXTsKCX0sCgkyMAopOwoKYWRkX2ZpbHRlcigKCSdvcHRpb25fc2l0ZXVybCcsCglmdW5jdGlvbiAoICR1cmwgKSB7CgkJaWYgKCAhIGlzc2V0KCAkR0xPQkFMU1snd3BjbGlfc2VydmVyX29yaWdpbmFsX3VybCddICkgKSB7CgkJCWdldF9vcHRpb24oICdob21lJyApOyAgLy8gdHJpZ2dlciB0aGUgb3B0aW9uX2hvbWUgZmlsdGVyCgkJfQoKCQkkaG9tZV91cmxfaG9zdCA9IF9nZXRfZnVsbF9ob3N0KCAkR0xPQkFMU1snd3BjbGlfc2VydmVyX29yaWdpbmFsX3VybCddICk7CgkJJHNpdGVfdXJsX2hvc3QgPSBfZ2V0X2Z1bGxfaG9zdCggJHVybCApOwoKCQlpZiAoICRzaXRlX3VybF9ob3N0ID09PSAkaG9tZV91cmxfaG9zdCApIHsKCQkJJHVybCA9IHN0cl9yZXBsYWNlKCAkc2l0ZV91cmxfaG9zdCwgJF9TRVJWRVJbJ0hUVFBfSE9TVCddLCAkdXJsICk7CgkJfQoKCQlyZXR1cm4gJHVybDsKCX0sCgkyMAopOwoKJF9TRVJWRVJbJ1NFUlZFUl9BRERSJ10gPSBnZXRob3N0YnluYW1lKCAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSApOwokd3BjbGlfc2VydmVyX3Jvb3QgICAgICA9ICRfU0VSVkVSWydET0NVTUVOVF9ST09UJ107Ci8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuQWx0ZXJuYXRpdmVGdW5jdGlvbnMucGFyc2VfdXJsX3BhcnNlX3VybAokd3BjbGlfc2VydmVyX3BhdGggPSAnLycgLiBsdHJpbSggcGFyc2VfdXJsKCB1cmxkZWNvZGUoICRfU0VSVkVSWydSRVFVRVNUX1VSSSddICkgKVsncGF0aCddLCAnLycgKTsKCmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9zZXJ2ZXJfcm9vdCAuICR3cGNsaV9zZXJ2ZXJfcGF0aCApICkgewoJaWYgKCBpc19kaXIoICR3cGNsaV9zZXJ2ZXJfcm9vdCAuICR3cGNsaV9zZXJ2ZXJfcGF0aCApICYmIHN1YnN0ciggJHdwY2xpX3NlcnZlcl9wYXRoLCAtMSApICE9PSAnLycgKSB7CgkJaGVhZGVyKCAiTG9jYXRpb246ICR3cGNsaV9zZXJ2ZXJfcGF0aC8iICk7CgkJZXhpdDsKCX0KCglpZiAoIHN0cnBvcyggJHdwY2xpX3NlcnZlcl9wYXRoLCAnLnBocCcgKSAhPT0gZmFsc2UgKSB7CgkJY2hkaXIoIGRpcm5hbWUoICR3cGNsaV9zZXJ2ZXJfcm9vdCAuICR3cGNsaV9zZXJ2ZXJfcGF0aCApICk7CgkJcmVxdWlyZV9vbmNlICR3cGNsaV9zZXJ2ZXJfcm9vdCAuICR3cGNsaV9zZXJ2ZXJfcGF0aDsKCX0gZWxzZSB7CgkJcmV0dXJuIGZhbHNlOwoJfQp9IGVsc2UgewoJY2hkaXIoICR3cGNsaV9zZXJ2ZXJfcm9vdCApOwoJcmVxdWlyZV9vbmNlICdpbmRleC5waHAnOwp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfc2VydmVyX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX3NlcnZlcl9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX3NlcnZlcl9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ3NlcnZlcicsCgknU2VydmVyX0NvbW1hbmQnLAoJYXJyYXkoCgkJJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uKCkgewoJCQkkbWluX3ZlcnNpb24gPSAnNS40JzsKCQkJaWYgKCB2ZXJzaW9uX2NvbXBhcmUoIFBIUF9WRVJTSU9OLCAkbWluX3ZlcnNpb24sICc8JyApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIlRoZSBgd3Agc2VydmVyYCBjb21tYW5kIHJlcXVpcmVzIFBIUCB7JG1pbl92ZXJzaW9ufSBvciBuZXdlci4iICk7CgkJCX0KCQl9LAoJKQopOwo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElfQ29tbWFuZDsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBXUC1DTEkgY29tbWFuZHMgdGhhdCBkZWFsIHdpdGggdHJhbnNsYXRpb25zCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KYWJzdHJhY3QgY2xhc3MgQ29tbWFuZFdpdGhUcmFuc2xhdGlvbiBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCXByb3RlY3RlZCAkb2JqX3R5cGU7CgoJcHJvdGVjdGVkICRvYmpfZmllbGRzOwoKCS8qKgoJICogQ2FsbGJhY2sgdG8gc29ydCBhcnJheSBieSBhICdsYW5ndWFnZScga2V5LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc29ydF90cmFuc2xhdGlvbnNfY2FsbGJhY2soICRhLCAkYiApIHsKCQlyZXR1cm4gc3RybmF0Y2FzZWNtcCggJGFbJ2xhbmd1YWdlJ10sICRiWydsYW5ndWFnZSddICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIGluc3RhbGxlZCBsYW5ndWFnZXMgZm9yIHRoZSBjdXJyZW50IG9iamVjdCB0eXBlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHVwZGF0ZXMgPSAkdGhpcy0+Z2V0X3RyYW5zbGF0aW9uX3VwZGF0ZXMoKTsKCgkJaWYgKCBlbXB0eSggJHVwZGF0ZXMgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnVHJhbnNsYXRpb25zIGFyZSB1cCB0byBkYXRlLicgKTsKCgkJCXJldHVybjsKCQl9CgoJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCSRhcmdzID0gYXJyYXkoIG51bGwgKTsgLy8gVXNlZCBmb3IgY29yZS4KCQl9CgoJCSR1cGdyYWRlciAgICAgID0gJ1dQX0NMSVxcTGFuZ3VhZ2VQYWNrVXBncmFkZXInOwoJCSRyZXN1bHRzICAgICAgID0gYXJyYXkoKTsKCQkkbnVtX3RvX3VwZGF0ZSA9IDA7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkc2x1ZyApIHsKCQkJLy8gR2V0cyBhIGxpc3Qgb2YgYWxsIGxhbmd1YWdlcy4KCQkJJGFsbF9sYW5ndWFnZXMgPSAkdGhpcy0+Z2V0X2FsbF9sYW5ndWFnZXMoICRzbHVnICk7CgoJCQkkdXBkYXRlc19wZXJfdHlwZSA9IGFycmF5KCk7CgoJCQkvLyBGb3JtYXRzIHRoZSB1cGRhdGVzIGxpc3QuCgkJCWZvcmVhY2ggKCAkdXBkYXRlcyBhcyAkdXBkYXRlICkgewoJCQkJaWYgKCBudWxsICE9PSAkc2x1ZyAmJiAkdXBkYXRlLT5zbHVnICE9PSAkc2x1ZyApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkbmFtZSA9ICdXb3JkUHJlc3MnOyAvLyBDb3JlLgoKCQkJCWlmICggJ3BsdWdpbicgPT09ICR1cGRhdGUtPnR5cGUgKSB7CgkJCQkJJHBsdWdpbnMgICAgID0gZ2V0X3BsdWdpbnMoICcvJyAuICR1cGRhdGUtPnNsdWcgKTsKCQkJCQkkcGx1Z2luX2RhdGEgPSBhcnJheV9zaGlmdCggJHBsdWdpbnMgKTsKCQkJCQkkbmFtZSAgICAgICAgPSAkcGx1Z2luX2RhdGFbJ05hbWUnXTsKCQkJCX0gZWxzZWlmICggJ3RoZW1lJyA9PT0gJHVwZGF0ZS0+dHlwZSApIHsKCQkJCQkkdGhlbWVfZGF0YSA9IHdwX2dldF90aGVtZSggJHVwZGF0ZS0+c2x1ZyApOwoJCQkJCSRuYW1lICAgICAgID0gJHRoZW1lX2RhdGFbJ05hbWUnXTsKCQkJCX0KCgkJCQkvLyBHZXRzIHRoZSB0cmFuc2xhdGlvbiBkYXRhLgoJCQkJJHRyYW5zbGF0aW9uID0gd3BfbGlzdF9maWx0ZXIoICRhbGxfbGFuZ3VhZ2VzLCBhcnJheSggJ2xhbmd1YWdlJyA9PiAkdXBkYXRlLT5sYW5ndWFnZSApICk7CgkJCQkkdHJhbnNsYXRpb24gPSAob2JqZWN0KSByZXNldCggJHRyYW5zbGF0aW9uICk7CgoJCQkJJHVwZGF0ZS0+VHlwZSAgICA9IHVjZmlyc3QoICR1cGRhdGUtPnR5cGUgKTsKCQkJCSR1cGRhdGUtPk5hbWUgICAgPSAkbmFtZTsKCQkJCSR1cGRhdGUtPlZlcnNpb24gPSAkdXBkYXRlLT52ZXJzaW9uOwoKCQkJCWlmICggaXNzZXQoICR0cmFuc2xhdGlvbi0+ZW5nbGlzaF9uYW1lICkgKSB7CgkJCQkJJHVwZGF0ZS0+TGFuZ3VhZ2UgPSAkdHJhbnNsYXRpb24tPmVuZ2xpc2hfbmFtZTsKCQkJCX0KCgkJCQlpZiAoICEgaXNzZXQoICR1cGRhdGVzX3Blcl90eXBlWyAkdXBkYXRlLT50eXBlIF0gKSApIHsKCQkJCQkkdXBkYXRlc19wZXJfdHlwZVsgJHVwZGF0ZS0+dHlwZSBdID0gYXJyYXkoKTsKCQkJCX0KCQkJCSR1cGRhdGVzX3Blcl90eXBlWyAkdXBkYXRlLT50eXBlIF1bXSA9ICR1cGRhdGU7CgkJCX0KCgkJCSRvYmpfdHlwZSAgICAgICAgICA9IHJ0cmltKCAkdGhpcy0+b2JqX3R5cGUsICdzJyApOwoJCQkkYXZhaWxhYmxlX3VwZGF0ZXMgPSBpc3NldCggJHVwZGF0ZXNfcGVyX3R5cGVbICRvYmpfdHlwZSBdICkgPyAkdXBkYXRlc19wZXJfdHlwZVsgJG9ial90eXBlIF0gOiBudWxsOwoKCQkJaWYgKCAhIGlzX2FycmF5KCAkYXZhaWxhYmxlX3VwZGF0ZXMgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkbnVtX3RvX3VwZGF0ZSArPSBjb3VudCggJGF2YWlsYWJsZV91cGRhdGVzICk7CgoJCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHJ5LXJ1bicgKSApIHsKCQkJCS8vIFVwZGF0ZSB0cmFuc2xhdGlvbnMuCgkJCQlmb3JlYWNoICggJGF2YWlsYWJsZV91cGRhdGVzIGFzICR1cGRhdGUgKSB7CgkJCQkJV1BfQ0xJOjpsaW5lKCAiVXBkYXRpbmcgJ3skdXBkYXRlLT5MYW5ndWFnZX0nIHRyYW5zbGF0aW9uIGZvciB7JHVwZGF0ZS0+TmFtZX0geyR1cGRhdGUtPlZlcnNpb259Li4uIiApOwoKCQkJCQkkcmVzdWx0ID0gVXRpbHNcZ2V0X3VwZ3JhZGVyKCAkdXBncmFkZXIgKS0+dXBncmFkZSggJHVwZGF0ZSApOwoKCQkJCQkkcmVzdWx0c1tdID0gJHJlc3VsdDsKCQkJCX0KCQkJfQoJCX0KCgkJLy8gT25seSBwcmV2aWV3IHdoaWNoIHRyYW5zbGF0aW9ucyB3b3VsZCBiZSB1cGRhdGVkLgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHJ5LXJ1bicgKSApIHsKCQkJJHVwZGF0ZV9jb3VudCA9IGNvdW50KCAkdXBkYXRlcyApOwoKCQkJV1BfQ0xJOjpsaW5lKAoJCQkJc3ByaW50ZigKCQkJCQknRm91bmQgJWQgdHJhbnNsYXRpb24gJXMgdGhhdCB3b3VsZCBiZSBwcm9jZXNzZWQ6JywKCQkJCQkkdXBkYXRlX2NvdW50LAoJCQkJCVdQX0NMSVxVdGlsc1xwbHVyYWxpemUoICd1cGRhdGUnLCAkdXBkYXRlX2NvdW50ICkKCQkJCSkKCQkJKTsKCgkJCVV0aWxzXGZvcm1hdF9pdGVtcyggJ3RhYmxlJywgJHVwZGF0ZXMsIGFycmF5KCAnVHlwZScsICdOYW1lJywgJ1ZlcnNpb24nLCAnTGFuZ3VhZ2UnICkgKTsKCgkJCXJldHVybjsKCQl9CgoJCSRudW1fdXBkYXRlZCA9IGNvdW50KCBhcnJheV9maWx0ZXIoICRyZXN1bHRzICkgKTsKCgkJJGxpbmUgPSBzcHJpbnRmKCAiVXBkYXRlZCAkbnVtX3VwZGF0ZWQvJG51bV90b191cGRhdGUgJXMuIiwgV1BfQ0xJXFV0aWxzXHBsdXJhbGl6ZSggJ3RyYW5zbGF0aW9uJywgJG51bV91cGRhdGVkICkgKTsKCgkJaWYgKCAkbnVtX3RvX3VwZGF0ZSA9PT0gJG51bV91cGRhdGVkICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICRsaW5lICk7CgkJfSBlbHNlaWYgKCAkbnVtX3VwZGF0ZWQgPiAwICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICRsaW5lICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggJGxpbmUgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXQgYWxsIHVwZGF0ZXMgYXZhaWxhYmxlIGZvciBhbGwgdHJhbnNsYXRpb25zLgoJICoKCSAqIEBzZWUgd3BfZ2V0X3RyYW5zbGF0aW9uX3VwZGF0ZXMoKQoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF90cmFuc2xhdGlvbl91cGRhdGVzKCkgewoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoKTsKCgkJJGZ1bmMgPSBmdW5jdGlvbigpIHVzZSAoICRhdmFpbGFibGUgKSB7CgkJCXJldHVybiAkYXZhaWxhYmxlOwoJCX07CgoJCXN3aXRjaCAoICR0aGlzLT5vYmpfdHlwZSApIHsKCQkJY2FzZSAncGx1Z2lucyc6CgkJCQlhZGRfZmlsdGVyKCAncGx1Z2luc191cGRhdGVfY2hlY2tfbG9jYWxlcycsICRmdW5jICk7CgoJCQkJd3BfY2xlYW5fcGx1Z2luc19jYWNoZSgpOwoJCQkJLy8gQ2hlY2sgZm9yIFBsdWdpbiB0cmFuc2xhdGlvbiB1cGRhdGVzLgoJCQkJd3BfdXBkYXRlX3BsdWdpbnMoKTsKCgkJCQlyZW1vdmVfZmlsdGVyKCAncGx1Z2luc191cGRhdGVfY2hlY2tfbG9jYWxlcycsICRmdW5jICk7CgoJCQkJJHRyYW5zaWVudCA9ICd1cGRhdGVfcGx1Z2lucyc7CgkJCQlicmVhazsKCQkJY2FzZSAndGhlbWVzJzoKCQkJCWFkZF9maWx0ZXIoICd0aGVtZXNfdXBkYXRlX2NoZWNrX2xvY2FsZXMnLCAkZnVuYyApOwoKCQkJCXdwX2NsZWFuX3RoZW1lc19jYWNoZSgpOwoJCQkJLy8gQ2hlY2sgZm9yIFRoZW1lIHRyYW5zbGF0aW9uIHVwZGF0ZXMuCgkJCQl3cF91cGRhdGVfdGhlbWVzKCk7CgoJCQkJcmVtb3ZlX2ZpbHRlciggJ3RoZW1lc191cGRhdGVfY2hlY2tfbG9jYWxlcycsICRmdW5jICk7CgoJCQkJJHRyYW5zaWVudCA9ICd1cGRhdGVfdGhlbWVzJzsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJZGVsZXRlX3NpdGVfdHJhbnNpZW50KCAndXBkYXRlX2NvcmUnICk7CgoJCQkJLy8gQ2hlY2sgZm9yIENvcmUgdHJhbnNsYXRpb24gdXBkYXRlcy4KCQkJCXdwX3ZlcnNpb25fY2hlY2soKTsKCgkJCQkkdHJhbnNpZW50ID0gJ3VwZGF0ZV9jb3JlJzsKCQkJCWJyZWFrOwoJCX0KCgkJJHVwZGF0ZXMgICA9IGFycmF5KCk7CgkJJHRyYW5zaWVudCA9IGdldF9zaXRlX3RyYW5zaWVudCggJHRyYW5zaWVudCApOwoKCQlpZiAoIGVtcHR5KCAkdHJhbnNpZW50LT50cmFuc2xhdGlvbnMgKSApIHsKCQkJcmV0dXJuICR1cGRhdGVzOwoJCX0KCgkJZm9yZWFjaCAoICR0cmFuc2llbnQtPnRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24gKSB7CgkJCSR1cGRhdGVzW10gPSAob2JqZWN0KSAkdHJhbnNsYXRpb247CgkJfQoKCQlyZXR1cm4gJHVwZGF0ZXM7Cgl9CgoJLyoqCgkgKiBEb3dubG9hZCBhIGxhbmd1YWdlIHBhY2suCgkgKgoJICogQHNlZSB3cF9kb3dubG9hZF9sYW5ndWFnZV9wYWNrKCkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkb3dubG9hZCBMYW5ndWFnZSBjb2RlIHRvIGRvd25sb2FkLgoJICogQHBhcmFtIHN0cmluZyAkc2x1ZyBQbHVnaW4gb3IgdGhlbWUgc2x1Zy4gTm90IHVzZWQgZm9yIGNvcmUuCgkgKiBAcmV0dXJuIHN0cmluZ3xcV1BfRXJyb3IgUmV0dXJucyB0aGUgbGFuZ3VhZ2UgY29kZSBpZiBzdWNjZXNzZnVsbHkgZG93bmxvYWRlZCwgb3IgYSBXUF9FcnJvciBvYmplY3Qgb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGRvd25sb2FkX2xhbmd1YWdlX3BhY2soICRkb3dubG9hZCwgJHNsdWcgPSBudWxsICkgewoJCSR0cmFuc2xhdGlvbnMgICAgICAgID0gJHRoaXMtPmdldF9hbGxfbGFuZ3VhZ2VzKCAkc2x1ZyApOwoJCSR0cmFuc2xhdGlvbl90b19sb2FkID0gbnVsbDsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uICkgewoJCQlpZiAoICR0cmFuc2xhdGlvblsnbGFuZ3VhZ2UnXSA9PT0gJGRvd25sb2FkICkgewoJCQkJJHRyYW5zbGF0aW9uX3RvX2xvYWQgPSAkdHJhbnNsYXRpb247CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCAhICR0cmFuc2xhdGlvbl90b19sb2FkICkgewoJCQlyZXR1cm4gbmV3IFxXUF9FcnJvciggJ25vdF9mb3VuZCcsICJMYW5ndWFnZSAneyRkb3dubG9hZH0nIG5vdCBhdmFpbGFibGUuIiApOwoJCX0KCQkkdHJhbnNsYXRpb24gPSAob2JqZWN0KSAkdHJhbnNsYXRpb247CgoJCSR0cmFuc2xhdGlvbi0+dHlwZSA9IHJ0cmltKCAkdGhpcy0+b2JqX3R5cGUsICdzJyApOwoKCQkvLyBNYWtlIHN1cmUgY2FjaGluZyBpbiBMYW5ndWFnZVBhY2tVcGdyYWRlciB3b3Jrcy4KCQlpZiAoICEgaXNzZXQoICR0cmFuc2xhdGlvbi0+c2x1ZyApICkgewoJCQkkdHJhbnNsYXRpb24tPnNsdWcgPSAkc2x1ZzsKCQl9CgoJCSR1cGdyYWRlciA9ICdXUF9DTElcXExhbmd1YWdlUGFja1VwZ3JhZGVyJzsKCQkkcmVzdWx0ICAgPSBVdGlsc1xnZXRfdXBncmFkZXIoICR1cGdyYWRlciApLT51cGdyYWRlKCAkdHJhbnNsYXRpb24sIGFycmF5KCAnY2xlYXJfdXBkYXRlX2NhY2hlJyA9PiBmYWxzZSApICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJcmV0dXJuICRyZXN1bHQ7CgkJfQoKCQlpZiAoICEgJHJlc3VsdCApIHsKCQkJcmV0dXJuIG5ldyBcV1BfRXJyb3IoICdub3RfaW5zdGFsbGVkJywgIkNvdWxkIG5vdCBpbnN0YWxsIGxhbmd1YWdlICd7JGRvd25sb2FkfScuIiApOwoJCX0KCgkJcmV0dXJuICR0cmFuc2xhdGlvbi0+bGFuZ3VhZ2U7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gYSBsaXN0IG9mIGluc3RhbGxlZCBsYW5ndWFnZXMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2x1ZyBPcHRpb25hbC4gUGx1Z2luIG9yIHRoZW1lIHNsdWcuIERlZmF1bHRzIHRvICdkZWZhdWx0JyBmb3IgY29yZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfaW5zdGFsbGVkX2xhbmd1YWdlcyggJHNsdWcgPSAnZGVmYXVsdCcgKSB7CgkJJGF2YWlsYWJsZSAgID0gd3BfZ2V0X2luc3RhbGxlZF90cmFuc2xhdGlvbnMoICR0aGlzLT5vYmpfdHlwZSApOwoJCSRhdmFpbGFibGUgICA9ICEgZW1wdHkoICRhdmFpbGFibGVbICRzbHVnIF0gKSA/IGFycmF5X2tleXMoICRhdmFpbGFibGVbICRzbHVnIF0gKSA6IGFycmF5KCk7CgkJJGF2YWlsYWJsZVtdID0gJ2VuX1VTJzsKCgkJcmV0dXJuICRhdmFpbGFibGU7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gYSBsaXN0IG9mIGFsbCBsYW5ndWFnZXMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2x1ZyBPcHRpb25hbC4gUGx1Z2luIG9yIHRoZW1lIHNsdWcuIE5vdCB1c2VkIGZvciBjb3JlLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9hbGxfbGFuZ3VhZ2VzKCAkc2x1ZyA9IG51bGwgKSB7CgkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnL3dwLWFkbWluL2luY2x1ZGVzL3RyYW5zbGF0aW9uLWluc3RhbGwucGhwJzsKCQlyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvdmVyc2lvbi5waHAnOyAvLyBJbmNsdWRlIGFuIHVubW9kaWZpZWQgJHdwX3ZlcnNpb24KCgkJJGFyZ3MgPSBhcnJheSgKCQkJJ3ZlcnNpb24nID0+ICR3cF92ZXJzaW9uLAoJCSk7CgoJCWlmICggJHNsdWcgKSB7CgkJCSRhcmdzWydzbHVnJ10gPSAkc2x1ZzsKCgkJCWlmICggJ3BsdWdpbnMnID09PSAkdGhpcy0+b2JqX3R5cGUgKSB7CgkJCQkkcGx1Z2lucyAgICAgPSBnZXRfcGx1Z2lucyggJy8nIC4gJHNsdWcgKTsKCQkJCSRwbHVnaW5fZGF0YSA9IGFycmF5X3NoaWZ0KCAkcGx1Z2lucyApOwoJCQkJaWYgKCBpc3NldCggJHBsdWdpbl9kYXRhWydWZXJzaW9uJ10gKSApIHsKCQkJCQkkYXJnc1sndmVyc2lvbiddID0gJHBsdWdpbl9kYXRhWydWZXJzaW9uJ107CgkJCQl9CgkJCX0gZWxzZWlmICggJ3RoZW1lcycgPT09ICR0aGlzLT5vYmpfdHlwZSApIHsKCQkJCSR0aGVtZV9kYXRhID0gd3BfZ2V0X3RoZW1lKCAkc2x1ZyApOwoJCQkJaWYgKCBpc3NldCggJHRoZW1lX2RhdGFbJ1ZlcnNpb24nXSApICkgewoJCQkJCSRhcmdzWyd2ZXJzaW9uJ10gPSAkdGhlbWVfZGF0YVsnVmVyc2lvbiddOwoJCQkJfQoJCQl9CgkJfQoKCQkkcmVzcG9uc2UgPSB0cmFuc2xhdGlvbnNfYXBpKCAkdGhpcy0+b2JqX3R5cGUsICRhcmdzICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzcG9uc2UgKTsKCQl9CgoJCSR0cmFuc2xhdGlvbnMgPSAhIGVtcHR5KCAkcmVzcG9uc2VbJ3RyYW5zbGF0aW9ucyddICkgPyAkcmVzcG9uc2VbJ3RyYW5zbGF0aW9ucyddIDogYXJyYXkoKTsKCgkJJGVuX3VzID0gYXJyYXkoCgkJCSdsYW5ndWFnZScgICAgID0+ICdlbl9VUycsCgkJCSdlbmdsaXNoX25hbWUnID0+ICdFbmdsaXNoIChVbml0ZWQgU3RhdGVzKScsCgkJCSduYXRpdmVfbmFtZScgID0+ICdFbmdsaXNoIChVbml0ZWQgU3RhdGVzKScsCgkJCSd1cGRhdGVkJyAgICAgID0+ICcnLAoJCSk7CgoJCSR0cmFuc2xhdGlvbnNbXSA9ICRlbl91czsKCgkJdWFzb3J0KCAkdHJhbnNsYXRpb25zLCBhcnJheSggJHRoaXMsICdzb3J0X3RyYW5zbGF0aW9uc19jYWxsYmFjaycgKSApOwoKCQlyZXR1cm4gJHRyYW5zbGF0aW9uczsKCX0KCgkvKioKCSAqIEdldCBGb3JtYXR0ZXIgb2JqZWN0IGJhc2VkIG9uIHN1cHBsaWVkIHBhcmFtZXRlcnMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFBhcmFtZXRlcnMgcGFzc2VkIHRvIGNvbW1hbmQuIERldGVybWluZXMgZm9ybWF0dGluZy4KCSAqIEByZXR1cm4gRm9ybWF0dGVyCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+b2JqX2ZpZWxkcywgJHRoaXMtPm9ial90eXBlICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwoKLyoqCiAqIEEgTGFuZ3VhZ2UgUGFjayBVcGdyYWRlciBjbGFzcyB0aGF0IGNhY2hlcyB0aGUgZG93bmxvYWQsIGFuZCB1c2VzIGNhY2hlZCBpZiBhdmFpbGFibGUKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBMYW5ndWFnZVBhY2tVcGdyYWRlciBleHRlbmRzIFxMYW5ndWFnZV9QYWNrX1VwZ3JhZGVyIHsKCS8qKgoJICogSW5pdGlhbGl6ZSB0aGUgdXBncmFkZSBzdHJpbmdzLgoJICoKCSAqIE1ha2VzIHN1cmUgdGhhdCB0aGUgc3RyaW5ncyBhcmUgYWx3YXlzIGluIEVuZ2xpc2guCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGdyYWRlX3N0cmluZ3MoKSB7CgkJJHN3aXRjaGVkX2xvY2FsZSA9IGZ1bmN0aW9uX2V4aXN0cyggJ3N3aXRjaF90b19sb2NhbGUnICkgJiYgc3dpdGNoX3RvX2xvY2FsZSggJ2VuX1VTJyApOwoKCQlwYXJlbnQ6OnVwZ3JhZGVfc3RyaW5ncygpOwoKCQlpZiAoICRzd2l0Y2hlZF9sb2NhbGUgKSB7CgkJCXJlc3RvcmVfcHJldmlvdXNfbG9jYWxlKCk7CgkJfQoJfQoKCS8qKgoJICogSW5pdGlhbGl6ZSB0aGUgZ2VuZXJpYyBzdHJpbmdzLgoJICoKCSAqIE1ha2VzIHN1cmUgdGhhdCB0aGUgc3RyaW5ncyBhcmUgYWx3YXlzIGluIEVuZ2xpc2guCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZW5lcmljX3N0cmluZ3MoKSB7CgkJJHN3aXRjaGVkX2xvY2FsZSA9IGZ1bmN0aW9uX2V4aXN0cyggJ3N3aXRjaF90b19sb2NhbGUnICkgJiYgc3dpdGNoX3RvX2xvY2FsZSggJ2VuX1VTJyApOwoKCQlwYXJlbnQ6OmdlbmVyaWNfc3RyaW5ncygpOwoKCQlpZiAoICRzd2l0Y2hlZF9sb2NhbGUgKSB7CgkJCXJlc3RvcmVfcHJldmlvdXNfbG9jYWxlKCk7CgkJfQoJfQoKCS8qKgoJICogQ2FjaGVzIHRoZSBkb3dubG9hZCwgYW5kIHVzZXMgY2FjaGVkIGlmIGF2YWlsYWJsZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlICAgICAgICAgIFRoZSBVUkkgb2YgdGhlIHBhY2thZ2UuIElmIHRoaXMgaXMgdGhlIGZ1bGwgcGF0aCB0byBhbgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZyBsb2NhbCBmaWxlLCBpdCB3aWxsIGJlIHJldHVybmVkIHVudG91Y2hlZC4KCSAqIEBwYXJhbSBib29sICAgJGNoZWNrX3NpZ25hdHVyZXMgV2hldGhlciB0byB2YWxpZGF0ZSBmaWxlIHNpZ25hdHVyZXMuIERlZmF1bHQgZmFsc2UuCgkgKiBAcGFyYW0gYXJyYXkgICRob29rX2V4dHJhICAgICAgIEV4dHJhIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBmaWx0ZXIgaG9va3MuIERlZmF1bHQgZW1wdHkgYXJyYXkuCgkgKiBAcmV0dXJuIHN0cmluZ3xcV1BfRXJyb3IgVGhlIGZ1bGwgcGF0aCB0byB0aGUgZG93bmxvYWRlZCBwYWNrYWdlIGZpbGUsIG9yIGEgV1BfRXJyb3Igb2JqZWN0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWRfcGFja2FnZSggJHBhY2thZ2UsICRjaGVja19zaWduYXR1cmVzID0gZmFsc2UsICRob29rX2V4dHJhID0gW10gKSB7CgoJCS8qKgoJCSAqIEZpbHRlciB3aGV0aGVyIHRvIHJldHVybiB0aGUgcGFja2FnZS4KCQkgKgoJCSAqIEBzaW5jZSAzLjcuMAoJCSAqIEBzaW5jZSA1LjUuMCBBZGRlZCB0aGUgYCRob29rX2V4dHJhYCBwYXJhbWV0ZXIuCgkJICoKCQkgKiBAcGFyYW0gYm9vbCAgICAgICAgICAkcmVwbHkgICAgICBXaGV0aGVyIHRvIGJhaWwgd2l0aG91dCByZXR1cm5pbmcgdGhlIHBhY2thZ2UuIERlZmF1bHQgaXMgZmFsc2UuCgkJICogQHBhcmFtIHN0cmluZyAgICAgICAgJHBhY2thZ2UgICAgVGhlIHBhY2thZ2UgZmlsZSBuYW1lLgoJCSAqIEBwYXJhbSBcV1BfVXBncmFkZXIgICR0aGlzICAgICAgIFRoZSBXUF9VcGdyYWRlciBpbnN0YW5jZS4KCQkgKiBAcGFyYW0gYXJyYXkgICAgICAgICAkaG9va19leHRyYSBFeHRyYSBhcmd1bWVudHMgcGFzc2VkIHRvIGhvb2tlZCBmaWx0ZXJzLgoJCSAqCgkJICogQHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFVzaW5nIFdQIG5hdGl2ZSBob29rLgoJCSAqLwoJCSRyZXBseSA9IGFwcGx5X2ZpbHRlcnMoICd1cGdyYWRlcl9wcmVfZG93bmxvYWQnLCBmYWxzZSwgJHBhY2thZ2UsICR0aGlzLCAkaG9va19leHRyYSApOwoJCS8vIHBocGNzOmVuYWJsZQoKCQlpZiAoIGZhbHNlICE9PSAkcmVwbHkgKSB7CgkJCXJldHVybiAkcmVwbHk7CgkJfQoKCQkvLyBDaGVjayBpZiBwYWNrYWdlIGlzIGEgbG9jYWwgb3IgcmVtb3RlIGZpbGUuIEJhaWwgaWYgaXQncyBsb2NhbC4KCQlpZiAoICEgcHJlZ19tYXRjaCggJyFeKGh0dHB8aHR0cHN8ZnRwKTovLyFpJywgJHBhY2thZ2UgKSAmJiBmaWxlX2V4aXN0cyggJHBhY2thZ2UgKSApIHsKCQkJcmV0dXJuICRwYWNrYWdlOwoJCX0KCgkJaWYgKCBlbXB0eSggJHBhY2thZ2UgKSApIHsKCQkJcmV0dXJuIG5ldyBcV1BfRXJyb3IoICdub19wYWNrYWdlJywgJHRoaXMtPnN0cmluZ3NbJ25vX3BhY2thZ2UnXSApOwoJCX0KCgkJJGxhbmd1YWdlX3VwZGF0ZSA9ICR0aGlzLT5za2luLT5sYW5ndWFnZV91cGRhdGU7CgkJJHR5cGUgICAgICAgICAgICA9ICRsYW5ndWFnZV91cGRhdGUtPnR5cGU7CgkJJHNsdWcgICAgICAgICAgICA9IGVtcHR5KCAkbGFuZ3VhZ2VfdXBkYXRlLT5zbHVnICkgPyAnZGVmYXVsdCcgOiAkbGFuZ3VhZ2VfdXBkYXRlLT5zbHVnOwoJCSR1cGRhdGVkICAgICAgICAgPSBzdHJ0b3RpbWUoICRsYW5ndWFnZV91cGRhdGUtPnVwZGF0ZWQgKTsKCQkkdmVyc2lvbiAgICAgICAgID0gJGxhbmd1YWdlX3VwZGF0ZS0+dmVyc2lvbjsKCQkkbGFuZ3VhZ2UgICAgICAgID0gJGxhbmd1YWdlX3VwZGF0ZS0+bGFuZ3VhZ2U7CgkJJGV4dCAgICAgICAgICAgICA9IHBhdGhpbmZvKCAkcGFja2FnZSwgUEFUSElORk9fRVhURU5TSU9OICk7CgoJCSR0ZW1wID0gXFdQX0NMSVxVdGlsc1xnZXRfdGVtcF9kaXIoKSAuIHVuaXFpZCggJ3dwXycgKSAuICcuJyAuICRleHQ7CgoJCSRjYWNoZSAgICAgID0gV1BfQ0xJOjpnZXRfY2FjaGUoKTsKCQkkY2FjaGVfa2V5ICA9ICJ0cmFuc2xhdGlvbi97JHR5cGV9LXskc2x1Z30teyR2ZXJzaW9ufS17JGxhbmd1YWdlfS17JHVwZGF0ZWR9LnskZXh0fSI7CgkJJGNhY2hlX2ZpbGUgPSAkY2FjaGUtPmhhcyggJGNhY2hlX2tleSApOwoKCQlpZiAoICRjYWNoZV9maWxlICkgewoJCQlXUF9DTEk6OmxvZyggIlVzaW5nIGNhY2hlZCBmaWxlICckY2FjaGVfZmlsZScuLi4iICk7CgkJCWNvcHkoICRjYWNoZV9maWxlLCAkdGVtcCApOwoJCQlyZXR1cm4gJHRlbXA7CgkJfQoKCQkkdGhpcy0+c2tpbi0+ZmVlZGJhY2soICdkb3dubG9hZGluZ19wYWNrYWdlJywgJHBhY2thZ2UgKTsKCgkJJHRlbXAgPSBkb3dubG9hZF91cmwoICRwYWNrYWdlLCA2MDAgKTsgLy8gMTAgbWludXRlcyBvdWdodCB0byBiZSBlbm91Z2ggZm9yIGV2ZXJ5Ym9keS4KCgkJaWYgKCBpc193cF9lcnJvciggJHRlbXAgKSApIHsKCQkJcmV0dXJuICR0ZW1wOwoJCX0KCgkJJGNhY2hlLT5pbXBvcnQoICRjYWNoZV9rZXksICR0ZW1wICk7CgoJCXJldHVybiAkdGVtcDsKCX0KfQo8P3BocAoKLyoqCiAqIEluc3RhbGxzLCBhY3RpdmF0ZXMsIGFuZCBtYW5hZ2VzIGNvcmUgbGFuZ3VhZ2UgcGFja3MuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEluc3RhbGwgdGhlIER1dGNoIGNvcmUgbGFuZ3VhZ2UgcGFjay4KICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSBpbnN0YWxsIG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSBpbnN0YWxsZWQuCiAqCiAqICAgICAjIEFjdGl2YXRlIHRoZSBEdXRjaCBjb3JlIGxhbmd1YWdlIHBhY2suCiAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgYWN0aXZhdGUgbmxfTkwKICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIGFjdGl2YXRlZC4KICoKICogICAgICMgVW5pbnN0YWxsIHRoZSBEdXRjaCBjb3JlIGxhbmd1YWdlIHBhY2suCiAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgdW5pbnN0YWxsIG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSB1bmluc3RhbGxlZC4KICoKICogICAgICMgTGlzdCBpbnN0YWxsZWQgY29yZSBsYW5ndWFnZSBwYWNrYWdlcy4KICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSBsaXN0IC0tc3RhdHVzPWluc3RhbGxlZAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqICAgICB8IGxhbmd1YWdlIHwgZW5nbGlzaF9uYW1lIHwgbmF0aXZlX25hbWUgfCBzdGF0dXMgICAgfCB1cGRhdGUgICAgfCB1cGRhdGVkICAgICAgICAgICAgIHwKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBubF9OTCAgICB8IER1dGNoICAgICAgICB8IE5lZGVybGFuZHMgIHwgaW5zdGFsbGVkIHwgYXZhaWxhYmxlIHwgMjAxNi0wNS0xMyAwODoxMjo1MCB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICovCmNsYXNzIENvcmVfTGFuZ3VhZ2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSVxDb21tYW5kV2l0aFRyYW5zbGF0aW9uIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAnY29yZSc7CgoJcHJvdGVjdGVkICRvYmpfZmllbGRzID0gYXJyYXkoCgkJJ2xhbmd1YWdlJywKCQknZW5nbGlzaF9uYW1lJywKCQknbmF0aXZlX25hbWUnLAoJCSdzdGF0dXMnLAoJCSd1cGRhdGUnLAoJCSd1cGRhdGVkJywKCSk7CgoJLyoqCgkgKiBMaXN0cyBhbGwgYXZhaWxhYmxlIGxhbmd1YWdlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogRGlzcGxheSB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQKCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEZpbHRlciByZXN1bHRzIGJ5IGtleT12YWx1ZSBwYWlycy4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCB0cmFuc2xhdGlvbjoKCSAqCgkgKiAqIGxhbmd1YWdlCgkgKiAqIGVuZ2xpc2hfbmFtZQoJICogKiBuYXRpdmVfbmFtZQoJICogKiBzdGF0dXMKCSAqICogdXBkYXRlCgkgKiAqIHVwZGF0ZWQKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgbGFuZ3VhZ2UsZW5nbGlzaF9uYW1lLHN0YXR1cyBmaWVsZHMgb2YgYXZhaWxhYmxlIGxhbmd1YWdlcy4KCSAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgbGlzdCAtLWZpZWxkcz1sYW5ndWFnZSxlbmdsaXNoX25hbWUsc3RhdHVzCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbGFuZ3VhZ2UgICAgICAgfCBlbmdsaXNoX25hbWUgICAgICAgICAgICB8IHN0YXR1cyAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBhciAgICAgICAgICAgICB8IEFyYWJpYyAgICAgICAgICAgICAgICAgIHwgdW5pbnN0YWxsZWQgfAoJICogICAgIHwgYXJ5ICAgICAgICAgICAgfCBNb3JvY2NhbiBBcmFiaWMgICAgICAgICB8IHVuaW5zdGFsbGVkIHwKCSAqICAgICB8IGF6ICAgICAgICAgICAgIHwgQXplcmJhaWphbmkgICAgICAgICAgICAgfCB1bmluc3RhbGxlZCB8CgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdHJhbnNsYXRpb25zID0gJHRoaXMtPmdldF9hbGxfbGFuZ3VhZ2VzKCk7CgkJJGF2YWlsYWJsZSAgICA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX2xhbmd1YWdlcygpOwoJCSR1cGRhdGVzICAgICAgPSAkdGhpcy0+Z2V0X3RyYW5zbGF0aW9uX3VwZGF0ZXMoKTsKCgkJJGN1cnJlbnRfbG9jYWxlID0gZ2V0X2xvY2FsZSgpOwoKCQkkdHJhbnNsYXRpb25zID0gYXJyYXlfbWFwKAoJCQlmdW5jdGlvbiggJHRyYW5zbGF0aW9uICkgdXNlICggJGF2YWlsYWJsZSwgJGN1cnJlbnRfbG9jYWxlLCAkdXBkYXRlcyApIHsKCQkJCSR0cmFuc2xhdGlvblsnc3RhdHVzJ10gPSAndW5pbnN0YWxsZWQnOwoJCQkJaWYgKCBpbl9hcnJheSggJHRyYW5zbGF0aW9uWydsYW5ndWFnZSddLCAkYXZhaWxhYmxlLCB0cnVlICkgKSB7CgkJCQkJJHRyYW5zbGF0aW9uWydzdGF0dXMnXSA9ICdpbnN0YWxsZWQnOwoJCQkJfQoKCQkJCWlmICggJGN1cnJlbnRfbG9jYWxlID09PSAkdHJhbnNsYXRpb25bJ2xhbmd1YWdlJ10gKSB7CgkJCQkJJHRyYW5zbGF0aW9uWydzdGF0dXMnXSA9ICdhY3RpdmUnOwoJCQkJfQoKCQkJCSR1cGRhdGUgPSB3cF9saXN0X2ZpbHRlciggJHVwZGF0ZXMsIGFycmF5KCAnbGFuZ3VhZ2UnID0+ICR0cmFuc2xhdGlvblsnbGFuZ3VhZ2UnXSApICk7CgkJCQlpZiAoICR1cGRhdGUgKSB7CgkJCQkJJHRyYW5zbGF0aW9uWyd1cGRhdGUnXSA9ICdhdmFpbGFibGUnOwoJCQkJfSBlbHNlIHsKCQkJCQkkdHJhbnNsYXRpb25bJ3VwZGF0ZSddID0gJ25vbmUnOwoJCQkJfQoKCQkJCXJldHVybiAkdHJhbnNsYXRpb247CgkJCX0sCgkJCSR0cmFuc2xhdGlvbnMKCQkpOwoKCQlmb3JlYWNoICggJHRyYW5zbGF0aW9ucyBhcyAka2V5ID0+ICR0cmFuc2xhdGlvbiApIHsKCQkJZm9yZWFjaCAoIGFycmF5X2tleXMoICR0cmFuc2xhdGlvbiApIGFzICRmaWVsZCApIHsKCQkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkZmllbGQgXSApICYmICRhc3NvY19hcmdzWyAkZmllbGQgXSAhPT0gJHRyYW5zbGF0aW9uWyAkZmllbGQgXSApIHsKCQkJCQl1bnNldCggJHRyYW5zbGF0aW9uc1sgJGtleSBdICk7CgkJCQl9CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdHJhbnNsYXRpb25zICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYSBnaXZlbiBsYW5ndWFnZSBpcyBpbnN0YWxsZWQuCgkgKgoJICogUmV0dXJucyBleGl0IGNvZGUgMCB3aGVuIGluc3RhbGxlZCwgMSB3aGVuIHVuaW5zdGFsbGVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bGFuZ3VhZ2U+CgkgKiA6IFRoZSBsYW5ndWFnZSBjb2RlIHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgd2hldGhlciB0aGUgR2VybWFuIGxhbmd1YWdlIGlzIGluc3RhbGxlZDsgZXhpdCBzdGF0dXMgMCBpZiBpbnN0YWxsZWQsIG90aGVyd2lzZSAxLgoJICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSBpcy1pbnN0YWxsZWQgZGVfREUKCSAqICAgICAkIGVjaG8gJD8KCSAqICAgICAxCgkgKgoJICogQHN1YmNvbW1hbmQgaXMtaW5zdGFsbGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc19pbnN0YWxsZWQoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJbGlzdCggJGxhbmd1YWdlX2NvZGUgKSA9ICRhcmdzOwoJCSRhdmFpbGFibGUgICAgICAgICAgICAgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoKTsKCQlpZiAoIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQlcV1BfQ0xJOjpoYWx0KCAwICk7CgkJfSBlbHNlIHsKCQkJXFdQX0NMSTo6aGFsdCggMSApOwoJCX0KCX0KCgkvKioKCSAqIEluc3RhbGxzIGEgZ2l2ZW4gbGFuZ3VhZ2UuCgkgKgoJICogRG93bmxvYWRzIHRoZSBsYW5ndWFnZSBwYWNrIGZyb20gV29yZFByZXNzLm9yZy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGxhbmd1YWdlPi4uLgoJICogOiBMYW5ndWFnZSBjb2RlIHRvIGluc3RhbGwuCgkgKgoJICogWy0tYWN0aXZhdGVdCgkgKiA6IElmIHNldCwgdGhlIGxhbmd1YWdlIHdpbGwgYmUgYWN0aXZhdGVkIGltbWVkaWF0ZWx5IGFmdGVyIGluc3RhbGwuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbnN0YWxsIHRoZSBKYXBhbmVzZSBsYW5ndWFnZS4KCSAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgaW5zdGFsbCBqYQoJICogICAgIERvd25sb2FkaW5nIHRyYW5zbGF0aW9uIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90cmFuc2xhdGlvbi9jb3JlLzQuOS44L2phLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgbGF0ZXN0IHZlcnNpb24uLi4KCSAqICAgICBUcmFuc2xhdGlvbiB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBMYW5ndWFnZSAnamEnIGluc3RhbGxlZC4KCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIGxhbmd1YWdlcy4KCSAqCgkgKiBAc3ViY29tbWFuZCBpbnN0YWxsCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGxhbmd1YWdlX2NvZGVzID0gKGFycmF5KSAkYXJnczsKCQkkY291bnQgICAgICAgICAgPSBjb3VudCggJGxhbmd1YWdlX2NvZGVzICk7CgoJCWlmICggJGNvdW50ID4gMSAmJiBpbl9hcnJheSggdHJ1ZSwgJGFzc29jX2FyZ3MsIHRydWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ09ubHkgYSBzaW5nbGUgbGFuZ3VhZ2UgY2FuIGJlIGFjdGl2ZS4nICk7CgkJfQoKCQkkYXZhaWxhYmxlID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCk7CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSRza2lwcyAgICAgPSAwOwoJCWZvcmVhY2ggKCAkbGFuZ3VhZ2VfY29kZXMgYXMgJGxhbmd1YWdlX2NvZGUgKSB7CgoJCQlpZiAoIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGFscmVhZHkgaW5zdGFsbGVkLiIgKTsKCQkJCSRza2lwcysrOwoJCQl9IGVsc2UgewoJCQkJJHJlc3BvbnNlID0gJHRoaXMtPmRvd25sb2FkX2xhbmd1YWdlX3BhY2soICRsYW5ndWFnZV9jb2RlICk7CgoJCQkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkgKSB7CgkJCQkJXFdQX0NMSTo6d2FybmluZyggJHJlc3BvbnNlICk7CgkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIG5vdCBpbnN0YWxsZWQuIiApOwoKCQkJCQkvLyBTa2lwIGlmIHRyYW5zbGF0aW9uIGlzIG5vdCB5ZXQgYXZhaWxhYmxlLgoJCQkJCWlmICggJ25vdF9mb3VuZCcgPT09ICRyZXNwb25zZS0+Z2V0X2Vycm9yX2NvZGUoKSApIHsKCQkJCQkJJHNraXBzKys7CgkJCQkJfSBlbHNlIHsKCQkJCQkJJGVycm9ycysrOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGluc3RhbGxlZC4iICk7CgkJCQkJJHN1Y2Nlc3NlcysrOwoJCQkJfQoJCQl9CgoJCQlpZiAoIFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhY3RpdmF0ZScgKSApIHsKCQkJCSR0aGlzLT5hY3RpdmF0ZV9sYW5ndWFnZSggJGxhbmd1YWdlX2NvZGUgKTsKCQkJfQoJCX0KCgkJXFdQX0NMSVxVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdsYW5ndWFnZScsICdpbnN0YWxsJywgJGNvdW50LCAkc3VjY2Vzc2VzLCAkZXJyb3JzLCAkc2tpcHMgKTsKCX0KCgkvKioKCSAqIFVuaW5zdGFsbHMgYSBnaXZlbiBsYW5ndWFnZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGxhbmd1YWdlPi4uLgoJICogOiBMYW5ndWFnZSBjb2RlIHRvIHVuaW5zdGFsbC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgdW5pbnN0YWxsIGphCgkgKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgdW5pbnN0YWxsZWQuCgkgKgoJICogQHN1YmNvbW1hbmQgdW5pbnN0YWxsCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwX2ZpbGVzeXN0ZW07CgoJCSRsYW5ndWFnZV9jb2RlcyA9IChhcnJheSkgJGFyZ3M7CgoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoKTsKCgkJZm9yZWFjaCAoICRsYW5ndWFnZV9jb2RlcyBhcyAkbGFuZ3VhZ2VfY29kZSApIHsKCgkJCWlmICggISBpbl9hcnJheSggJGxhbmd1YWdlX2NvZGUsICRhdmFpbGFibGUsIHRydWUgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdMYW5ndWFnZSBub3QgaW5zdGFsbGVkLicgKTsKCQkJfQoKCQkJJGRpciAgID0gJ2NvcmUnID09PSAkdGhpcy0+b2JqX3R5cGUgPyAnJyA6ICIvJHRoaXMtPm9ial90eXBlIjsKCQkJJGZpbGVzID0gc2NhbmRpciggV1BfTEFOR19ESVIgLiAkZGlyICk7CgkJCWlmICggISAkZmlsZXMgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnTm8gZmlsZXMgZm91bmQgaW4gbGFuZ3VhZ2UgZGlyZWN0b3J5LicgKTsKCQkJfQoKCQkJJGN1cnJlbnRfbG9jYWxlID0gZ2V0X2xvY2FsZSgpOwoJCQlpZiAoICRsYW5ndWFnZV9jb2RlID09PSAkY3VycmVudF9sb2NhbGUgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJ3skbGFuZ3VhZ2VfY29kZX0nIGxhbmd1YWdlIGlzIGFjdGl2ZS4iICk7CgkJCQlleGl0OwoJCQl9CgoJCQkvLyBBcyBvZiBXUCA0LjAsIG5vIEFQSSBmb3IgZGVsZXRpbmcgYSBsYW5ndWFnZSBwYWNrCgkJCVdQX0ZpbGVzeXN0ZW0oKTsKCQkJJGRlbGV0ZWQgPSBmYWxzZTsKCQkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJCWlmICggJy4nID09PSAkZmlsZVswXSB8fCBpc19kaXIoICRmaWxlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkZXh0ZW5zaW9uX2xlbmd0aCA9IHN0cmxlbiggJGxhbmd1YWdlX2NvZGUgKSArIDQ7CgkJCQkkZW5kaW5nICAgICAgICAgICA9IHN1YnN0ciggJGZpbGUsIC0kZXh0ZW5zaW9uX2xlbmd0aCApOwoJCQkJaWYgKCAhIGluX2FycmF5KCAkZmlsZSwgYXJyYXkoICRsYW5ndWFnZV9jb2RlIC4gJy5wbycsICRsYW5ndWFnZV9jb2RlIC4gJy5tbycgKSwgdHJ1ZSApICYmICEgaW5fYXJyYXkoICRlbmRpbmcsIGFycmF5KCAnLScgLiAkbGFuZ3VhZ2VfY29kZSAuICcucG8nLCAnLScgLiAkbGFuZ3VhZ2VfY29kZSAuICcubW8nICksIHRydWUgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkvKiogQHZhciBXUF9GaWxlc3lzdGVtX0Jhc2UgJHdwX2ZpbGVzeXN0ZW0gKi8KCQkJCSRkZWxldGVkID0gJHdwX2ZpbGVzeXN0ZW0tPmRlbGV0ZSggV1BfTEFOR19ESVIgLiAkZGlyIC4gJy8nIC4gJGZpbGUgKTsKCQkJfQoKCQkJaWYgKCAkZGVsZXRlZCApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ0xhbmd1YWdlIHVuaW5zdGFsbGVkLicgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCB1bmluc3RhbGwgbGFuZ3VhZ2UuIiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogVXBkYXRlcyBpbnN0YWxsZWQgbGFuZ3VhZ2VzIGZvciBjb3JlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1kcnktcnVuXQoJICogOiBQcmV2aWV3IHdoaWNoIHRyYW5zbGF0aW9ucyB3b3VsZCBiZSB1cGRhdGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSB1cGRhdGUKCSAqICAgICBVcGRhdGluZyAnSmFwYW5lc2UnIHRyYW5zbGF0aW9uIGZvciBXb3JkUHJlc3MgNC45LjIuLi4KCSAqICAgICBEb3dubG9hZGluZyB0cmFuc2xhdGlvbiBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdHJhbnNsYXRpb24vY29yZS80LjkuMi9qYS56aXAuLi4KCSAqICAgICBUcmFuc2xhdGlvbiB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIDEvMSB0cmFuc2xhdGlvbi4KCSAqCgkgKiBAc3ViY29tbWFuZCB1cGRhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgeyAvLyBwaHBjczppZ25vcmUgR2VuZXJpYy5Db2RlQW5hbHlzaXMuVXNlbGVzc092ZXJyaWRpbmdNZXRob2QuRm91bmQgLS0gT3ZlcnJ1bGluZyB0aGUgZG9jdW1lbnRhdGlvbiwgc28gbm90IHVzZWxlc3MgOy0pLgoJCXBhcmVudDo6dXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEFjdGl2YXRlcyBhIGdpdmVuIGxhbmd1YWdlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bGFuZ3VhZ2U+CgkgKiA6IExhbmd1YWdlIGNvZGUgdG8gYWN0aXZhdGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIGFjdGl2YXRlIGphCgkgKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgYWN0aXZhdGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGFjdGl2YXRlCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhY3RpdmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCVxXUF9DTEk6Ondhcm5pbmcoICdUaGlzIGNvbW1hbmQgaXMgZGVwcmVjYXRlZC4gdXNlIHdwIHNpdGUgc3dpdGNoLWxhbmd1YWdlIGluc3RlYWQnICk7CgoJCWxpc3QoICRsYW5ndWFnZV9jb2RlICkgPSAkYXJnczsKCgkJJHRoaXMtPmFjdGl2YXRlX2xhbmd1YWdlKCAkbGFuZ3VhZ2VfY29kZSApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gYWN0aXZhdGVfbGFuZ3VhZ2UoICRsYW5ndWFnZV9jb2RlICkgewoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoKTsKCgkJaWYgKCAhIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTGFuZ3VhZ2Ugbm90IGluc3RhbGxlZC4nICk7CgkJfQoKCQlpZiAoICdlbl9VUycgPT09ICRsYW5ndWFnZV9jb2RlICkgewoJCQkkbGFuZ3VhZ2VfY29kZSA9ICcnOwoJCX0KCgkJaWYgKCBnZXRfbG9jYWxlKCkgPT09ICRsYW5ndWFnZV9jb2RlICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJMYW5ndWFnZSAneyRsYW5ndWFnZV9jb2RlfScgYWxyZWFkeSBhY3RpdmUuIiApOwoKCQkJcmV0dXJuOwoJCX0KCgkJdXBkYXRlX29wdGlvbiggJ1dQTEFORycsICRsYW5ndWFnZV9jb2RlICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0xhbmd1YWdlIGFjdGl2YXRlZC4nICk7Cgl9Cn0KPD9waHAKCi8qKgogKiBJbnN0YWxscywgYWN0aXZhdGVzLCBhbmQgbWFuYWdlcyBwbHVnaW4gbGFuZ3VhZ2UgcGFja3MuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEluc3RhbGwgdGhlIER1dGNoIHBsdWdpbiBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gaW5zdGFsbCBoZWxsby1kb2xseSBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgaW5zdGFsbGVkLgogKgogKiAgICAgIyBVbmluc3RhbGwgdGhlIER1dGNoIHBsdWdpbiBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gdW5pbnN0YWxsIGhlbGxvLWRvbGx5IG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSB1bmluc3RhbGxlZC4KICoKICogICAgICMgTGlzdCBpbnN0YWxsZWQgcGx1Z2luIGxhbmd1YWdlIHBhY2thZ2VzLgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gbGlzdCAtLXN0YXR1cz1pbnN0YWxsZWQKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBsYW5ndWFnZSB8IGVuZ2xpc2hfbmFtZSB8IG5hdGl2ZV9uYW1lIHwgc3RhdHVzICAgIHwgdXBkYXRlICAgIHwgdXBkYXRlZCAgICAgICAgICAgICB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbmxfTkwgICAgfCBEdXRjaCAgICAgICAgfCBOZWRlcmxhbmRzICB8IGluc3RhbGxlZCB8IGF2YWlsYWJsZSB8IDIwMTYtMDUtMTMgMDg6MTI6NTAgfAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqLwpjbGFzcyBQbHVnaW5fTGFuZ3VhZ2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSVxDb21tYW5kV2l0aFRyYW5zbGF0aW9uIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAncGx1Z2lucyc7CgoJcHJvdGVjdGVkICRvYmpfZmllbGRzID0gYXJyYXkoCgkJJ3BsdWdpbicsCgkJJ2xhbmd1YWdlJywKCQknZW5nbGlzaF9uYW1lJywKCQknbmF0aXZlX25hbWUnLAoJCSdzdGF0dXMnLAoJCSd1cGRhdGUnLAoJCSd1cGRhdGVkJywKCSk7CgoJLyoqCgkgKiBMaXN0cyBhbGwgYXZhaWxhYmxlIGxhbmd1YWdlcyBmb3Igb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+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/cGhwCgp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZTsKCi8qKgogKiBJbnN0YWxscywgYWN0aXZhdGVzLCBhbmQgbWFuYWdlcyBsYW5ndWFnZSBwYWNrcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgSW5zdGFsbCB0aGUgRHV0Y2ggY29yZSBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIGluc3RhbGwgbmxfTkwKICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIGluc3RhbGxlZC4KICoKICogICAgICMgQWN0aXZhdGUgdGhlIER1dGNoIGNvcmUgbGFuZ3VhZ2UgcGFjay4KICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSBhY3RpdmF0ZSBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgYWN0aXZhdGVkLgogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBEdXRjaCBsYW5ndWFnZSBwYWNrIGZvciBUd2VudHkgU2V2ZW50ZWVuLgogKiAgICAgJCB3cCBsYW5ndWFnZSB0aGVtZSBpbnN0YWxsIHR3ZW50eXNldmVudGVlbiBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgaW5zdGFsbGVkLgogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBEdXRjaCBsYW5ndWFnZSBwYWNrIGZvciBBa2lzbWV0LgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gaW5zdGFsbCBha2lzbWV0IG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSBpbnN0YWxsZWQuCiAqLwpjbGFzcyBMYW5ndWFnZV9OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKCn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9sYW5ndWFnZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CgppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfbGFuZ3VhZ2VfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9sYW5ndWFnZV9hdXRvbG9hZGVyOwp9Cgokd3BjbGlfbGFuZ3VhZ2VfY2hlY2tfcmVxdWlyZW1lbnRzID0gZnVuY3Rpb24oKSB7CglpZiAoIFxXUF9DTElcVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC4wJywgJzwnICkgKSB7CgkJV1BfQ0xJOjplcnJvciggJ1JlcXVpcmVzIFdvcmRQcmVzcyA0LjAgb3IgZ3JlYXRlci4nICk7Cgl9Cn07CgpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ2xhbmd1YWdlIGNvcmUnLAoJJ0NvcmVfTGFuZ3VhZ2VfQ29tbWFuZCcsCglhcnJheSggJ2JlZm9yZV9pbnZva2UnID0+ICR3cGNsaV9sYW5ndWFnZV9jaGVja19yZXF1aXJlbWVudHMgKQopOwoKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdsYW5ndWFnZSBwbHVnaW4nLAoJJ1BsdWdpbl9MYW5ndWFnZV9Db21tYW5kJywKCWFycmF5KCAnYmVmb3JlX2ludm9rZScgPT4gJHdwY2xpX2xhbmd1YWdlX2NoZWNrX3JlcXVpcmVtZW50cyApCik7CgpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ2xhbmd1YWdlIHRoZW1lJywKCSdUaGVtZV9MYW5ndWFnZV9Db21tYW5kJywKCWFycmF5KCAnYmVmb3JlX2ludm9rZScgPT4gJHdwY2xpX2xhbmd1YWdlX2NoZWNrX3JlcXVpcmVtZW50cyApCik7CgpXUF9DTEk6OmFkZF9ob29rKAoJJ2FmdGVyX2FkZF9jb21tYW5kOnNpdGUnLAoJZnVuY3Rpb24gKCkgewoJCVdQX0NMSTo6YWRkX2NvbW1hbmQoICdzaXRlIHN3aXRjaC1sYW5ndWFnZScsICdTaXRlX1N3aXRjaF9MYW5ndWFnZV9Db21tYW5kJyApOwoJfQopOwoKaWYgKCBjbGFzc19leGlzdHMoICdXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlJyApICkgewoJV1BfQ0xJOjphZGRfY29tbWFuZCggJ2xhbmd1YWdlJywgJ0xhbmd1YWdlX05hbWVzcGFjZScgKTsKfQo8P3BocAoKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CgovKioKICogQWRkcywgcmVtb3ZlcywgYW5kIGxpc3RzIGNhcGFiaWxpdGllcyBvZiBhIHVzZXIgcm9sZS4KICoKICogU2VlIHJlZmVyZW5jZXMgZm9yIFtSb2xlcyBhbmQgQ2FwYWJpbGl0aWVzXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvUm9sZXNfYW5kX0NhcGFiaWxpdGllcykgYW5kIFtXUCBVc2VyIGNsYXNzXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvQ2xhc3NfUmVmZXJlbmNlL1dQX1VzZXIpLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBBZGQgJ3NwZWN0YXRlJyBjYXBhYmlsaXR5IHRvICdhdXRob3InIHJvbGUuCiAqICAgICAkIHdwIGNhcCBhZGQgJ2F1dGhvcicgJ3NwZWN0YXRlJwogKiAgICAgU3VjY2VzczogQWRkZWQgMSBjYXBhYmlsaXR5IHRvICdhdXRob3InIHJvbGUuCiAqCiAqICAgICAjIEFkZCBhbGwgY2FwcyBmcm9tICdlZGl0b3InIHJvbGUgdG8gJ2F1dGhvcicgcm9sZS4KICogICAgICQgd3AgY2FwIGxpc3QgJ2VkaXRvcicgfCB4YXJncyB3cCBjYXAgYWRkICdhdXRob3InCiAqICAgICBTdWNjZXNzOiBBZGRlZCAyNCBjYXBhYmlsaXRpZXMgdG8gJ2F1dGhvcicgcm9sZS4KICoKICogICAgICMgUmVtb3ZlIGFsbCBjYXBzIGZyb20gJ2VkaXRvcicgcm9sZSB0aGF0IGFsc28gYXBwZWFyIGluICdhdXRob3InIHJvbGUuCiAqICAgICAkIHdwIGNhcCBsaXN0ICdhdXRob3InIHwgeGFyZ3Mgd3AgY2FwIHJlbW92ZSAnZWRpdG9yJwogKiAgICAgU3VjY2VzczogUmVtb3ZlZCAzNCBjYXBhYmlsaXRpZXMgZnJvbSAnZWRpdG9yJyByb2xlLgogKi8KY2xhc3MgQ2FwYWJpbGl0aWVzX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBMaXN0IG9mIGF2YWlsYWJsZSBmaWVsZHMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRmaWVsZHMgPSBbICduYW1lJyBdOwoKCS8qKgoJICogTGlzdHMgY2FwYWJpbGl0aWVzIGZvciBhIGdpdmVuIHJvbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxyb2xlPgoJICogOiBLZXkgZm9yIHRoZSByb2xlLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiBsaXN0CgkgKiBvcHRpb25zOgoJICogICAtIGxpc3QKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqIFstLXNob3ctZ3JhbnRdCgkgKiA6IERpc3BsYXkgYWxsIGNhcGFiaWxpdGllcyBkZWZpbmVkIGZvciBhIHJvbGUgaW5jbHVkaW5nIGdyYW50LgoJICogLS0tCgkgKiBkZWZhdWx0OiBmYWxzZQoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEaXNwbGF5IGFscGhhYmV0aWNhbCBsaXN0IG9mIENvbnRyaWJ1dG9yIGNhcGFiaWxpdGllcy4KCSAqICAgICAkIHdwIGNhcCBsaXN0ICdjb250cmlidXRvcicgfCBzb3J0CgkgKiAgICAgZGVsZXRlX3Bvc3RzCgkgKiAgICAgZWRpdF9wb3N0cwoJICogICAgIGxldmVsXzAKCSAqICAgICBsZXZlbF8xCgkgKiAgICAgcmVhZAoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHJvbGVfb2JqID0gc2VsZjo6Z2V0X3JvbGUoICRhcmdzWzBdICk7CgoJCSRzaG93X2dyYW50ID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ3Nob3ctZ3JhbnQnXSApOwoKCQlpZiAoICRzaG93X2dyYW50ICkgewoJCQlhcnJheV9wdXNoKCAkdGhpcy0+ZmllbGRzLCAnZ3JhbnQnICk7CgkJCSRjYXBhYmlsaXRpZXMgPSAkcm9sZV9vYmotPmNhcGFiaWxpdGllczsKCQl9IGVsc2UgewoJCQkkY2FwYWJpbGl0aWVzID0gYXJyYXlfZmlsdGVyKCAkcm9sZV9vYmotPmNhcGFiaWxpdGllcyApOwoJCX0KCgkJJG91dHB1dF9jYXBzID0gYXJyYXkoKTsKCQlmb3JlYWNoICggJGNhcGFiaWxpdGllcyBhcyAkY2FwID0+ICRncmFudCApIHsKCQkJJG91dHB1dF9jYXAgPSBuZXcgc3RkQ2xhc3MoKTsKCgkJCSRvdXRwdXRfY2FwLT5uYW1lICA9ICRjYXA7CgkJCSRvdXRwdXRfY2FwLT5ncmFudCA9ICRncmFudCA/ICd0cnVlJyA6ICdmYWxzZSc7CgoJCQkkb3V0cHV0X2NhcHNbXSA9ICRvdXRwdXRfY2FwOwoJCX0KCgkJaWYgKCAnbGlzdCcgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJZm9yZWFjaCAoICRvdXRwdXRfY2FwcyBhcyAkY2FwICkgewoJCQkJaWYgKCAkc2hvd19ncmFudCApIHsKCQkJCQlXUF9DTEk6OmxpbmUoIGltcGxvZGUoICcsJywgYXJyYXkoICRjYXAtPm5hbWUsICRjYXAtPmdyYW50ICkgKSApOwoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6OmxpbmUoICRjYXAtPm5hbWUgKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmZpZWxkcyApOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkb3V0cHV0X2NhcHMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBZGRzIGNhcGFiaWxpdGllcyB0byBhIGdpdmVuIHJvbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxyb2xlPgoJICogOiBLZXkgZm9yIHRoZSByb2xlLgoJICoKCSAqIDxjYXA+Li4uCgkgKiA6IE9uZSBvciBtb3JlIGNhcGFiaWxpdGllcyB0byBhZGQuCgkgKgoJICogWy0tZ3JhbnRdCgkgKiA6IEFkZHMgdGhlIGNhcGFiaWxpdHkgYXMgYW4gZXhwbGljaXQgYm9vbGVhbiB2YWx1ZSwgaW5zdGVhZCBvZiBpbXBsaWNpdGx5IGRlZmF1bHRpbmcgdG8gYHRydWVgLgoJICogLS0tCgkgKiBkZWZhdWx0OiB0cnVlCgkgKiBvcHRpb25zOgoJICogICAtIHRydWUKCSAqICAgLSBmYWxzZQoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBBZGQgJ3NwZWN0YXRlJyBjYXBhYmlsaXR5IHRvICdhdXRob3InIHJvbGUuCgkgKiAgICAgJCB3cCBjYXAgYWRkIGF1dGhvciBzcGVjdGF0ZQoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIDEgY2FwYWJpbGl0eSB0byAnYXV0aG9yJyByb2xlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJc2VsZjo6cGVyc2lzdGVuY2VfY2hlY2soKTsKCgkJJHJvbGUgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJJHJvbGVfb2JqID0gc2VsZjo6Z2V0X3JvbGUoICRyb2xlICk7CgoJCSRncmFudCA9ICEgaXNzZXQoICRhc3NvY19hcmdzWydncmFudCddICkgfHwgISBlbXB0eSggJGFzc29jX2FyZ3NbJ2dyYW50J10gKTsKCgkJJGNvdW50ID0gMDsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRjYXAgKSB7CgkJCWlmICggdHJ1ZSA9PT0gJGdyYW50ICYmICRyb2xlX29iai0+aGFzX2NhcCggJGNhcCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggZmFsc2UgPT09ICRncmFudCAmJiBpc3NldCggJHJvbGVfb2JqLT5jYXBhYmlsaXRpZXNbICRjYXAgXSApICYmIGZhbHNlID09PSAkcm9sZV9vYmotPmNhcGFiaWxpdGllc1sgJGNhcCBdICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyb2xlX29iai0+YWRkX2NhcCggJGNhcCwgJGdyYW50ICk7CgoJCQkkY291bnQrKzsKCQl9CgoJCSRjYXBhYmlsaXR5ICAgICAgICAgID0gV1BfQ0xJXFV0aWxzXHBsdXJhbGl6ZSggJ2NhcGFiaWxpdHknLCAkY291bnQgKTsKCQkkZ3JhbnRfcXVhbGlmaWNhdGlvbiA9ICRncmFudCA/ICcnIDogJyBhcyBmYWxzZSc7CgoJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkIHskY291bnR9IHskY2FwYWJpbGl0eX0gdG8gJ3skcm9sZX0nIHJvbGV7JGdyYW50X3F1YWxpZmljYXRpb259LiIgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgY2FwYWJpbGl0aWVzIGZyb20gYSBnaXZlbiByb2xlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cm9sZT4KCSAqIDogS2V5IGZvciB0aGUgcm9sZS4KCSAqCgkgKiA8Y2FwPi4uLgoJICogOiBPbmUgb3IgbW9yZSBjYXBhYmlsaXRpZXMgdG8gcmVtb3ZlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVtb3ZlICdzcGVjdGF0ZScgY2FwYWJpbGl0eSBmcm9tICdhdXRob3InIHJvbGUuCgkgKiAgICAgJCB3cCBjYXAgcmVtb3ZlIGF1dGhvciBzcGVjdGF0ZQoJICogICAgIFN1Y2Nlc3M6IFJlbW92ZWQgMSBjYXBhYmlsaXR5IGZyb20gJ2F1dGhvcicgcm9sZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlbW92ZSggJGFyZ3MgKSB7CgkJc2VsZjo6cGVyc2lzdGVuY2VfY2hlY2soKTsKCgkJJHJvbGUgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJJHJvbGVfb2JqID0gc2VsZjo6Z2V0X3JvbGUoICRyb2xlICk7CgoJCSRjb3VudCA9IDA7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkY2FwICkgewoJCQlpZiAoICEgaXNzZXQoICRyb2xlX29iai0+Y2FwYWJpbGl0aWVzWyAkY2FwIF0gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkcm9sZV9vYmotPnJlbW92ZV9jYXAoICRjYXAgKTsKCgkJCSRjb3VudCsrOwoJCX0KCgkJJGNhcGFiaWxpdHkgPSBXUF9DTElcVXRpbHNccGx1cmFsaXplKCAnY2FwYWJpbGl0eScsICRjb3VudCApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJSZW1vdmVkIHskY291bnR9IHskY2FwYWJpbGl0eX0gZnJvbSAneyRyb2xlfScgcm9sZS4iICk7Cgl9CgoJLyoqCgkgKiBSZXRyaWV2ZSBhIHNwZWNpZmljIHJvbGUgZnJvbSB0aGUgc3lzdGVtLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJvbGUgUm9sZSB0byByZXRyaWV2ZS4KCSAqIEByZXR1cm4gV1BfUm9sZSBSZXF1ZXN0ZWQgcm9sZS4KCSAqIEB0aHJvd3MgXFdQX0NMSVxFeGl0RXhjZXB0aW9uIElmIHRoZSByb2xlIGNvdWxkIG5vdCBiZSBmb3VuZC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3JvbGUoICRyb2xlICkgewoJCWdsb2JhbCAkd3Bfcm9sZXM7CgoJCSRyb2xlX29iaiA9ICR3cF9yb2xlcy0+Z2V0X3JvbGUoICRyb2xlICk7CgoJCWlmICggISAkcm9sZV9vYmogKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICIneyRyb2xlfScgcm9sZSBub3QgZm91bmQuIiApOwoJCX0KCgkJcmV0dXJuICRyb2xlX29iajsKCX0KCgkvKioKCSAqIEFzc2VydCB0aGF0IHRoZSByb2xlcyBhcmUgcGVyc2lzdGVkIHRvIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBAdGhyb3dzIFxXUF9DTElcRXhpdEV4Y2VwdGlvbiBJZiB0aGUgcm9sZXMgYXJlIG5vdCBwZXJzaXN0ZWQgdG8gdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhYmFzZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcGVyc2lzdGVuY2VfY2hlY2soKSB7CgkJZ2xvYmFsICR3cF9yb2xlczsKCgkJaWYgKCAhICR3cF9yb2xlcy0+dXNlX2RiICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUm9sZSBkZWZpbml0aW9ucyBhcmUgbm90IHBlcnNpc3RlbnQuJyApOwoJCX0KCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CgovKioKICogTWFuYWdlcyB1c2VyIHJvbGVzLCBpbmNsdWRpbmcgY3JlYXRpbmcgbmV3IHJvbGVzIGFuZCByZXNldHRpbmcgdG8gZGVmYXVsdHMuCiAqCiAqIFNlZSByZWZlcmVuY2VzIGZvciBbUm9sZXMgYW5kIENhcGFiaWxpdGllc10oaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1JvbGVzX2FuZF9DYXBhYmlsaXRpZXMpIGFuZCBbV1AgVXNlciBjbGFzc10oaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL0NsYXNzX1JlZmVyZW5jZS9XUF9Vc2VyKS4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgTGlzdCByb2xlcy4KICogICAgICQgd3Agcm9sZSBsaXN0IC0tZmllbGRzPXJvbGUgLS1mb3JtYXQ9Y3N2CiAqICAgICByb2xlCiAqICAgICBhZG1pbmlzdHJhdG9yCiAqICAgICBlZGl0b3IKICogICAgIGF1dGhvcgogKiAgICAgY29udHJpYnV0b3IKICogICAgIHN1YnNjcmliZXIKICoKICogICAgICMgQ2hlY2sgdG8gc2VlIGlmIGEgcm9sZSBleGlzdHMuCiAqICAgICAkIHdwIHJvbGUgZXhpc3RzIGVkaXRvcgogKiAgICAgU3VjY2VzczogUm9sZSB3aXRoIElEICdlZGl0b3InIGV4aXN0cy4KICoKICogICAgICMgQ3JlYXRlIGEgbmV3IHJvbGUuCiAqICAgICAkIHdwIHJvbGUgY3JlYXRlIGFwcHJvdmVyIEFwcHJvdmVyCiAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGgga2V5ICdhcHByb3ZlcicgY3JlYXRlZC4KICoKICogICAgICMgRGVsZXRlIGFuIGV4aXN0aW5nIHJvbGUuCiAqICAgICAkIHdwIHJvbGUgZGVsZXRlIGFwcHJvdmVyCiAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGgga2V5ICdhcHByb3ZlcicgZGVsZXRlZC4KICoKICogICAgICMgUmVzZXQgZXhpc3Rpbmcgcm9sZXMgdG8gdGhlaXIgZGVmYXVsdCBjYXBhYmlsaXRpZXMuCiAqICAgICAkIHdwIHJvbGUgcmVzZXQgYWRtaW5pc3RyYXRvciBhdXRob3IgY29udHJpYnV0b3IKICogICAgIFN1Y2Nlc3M6IFJlc2V0IDMvMyByb2xlcy4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBSb2xlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBMaXN0IG9mIGF2YWlsYWJsZSBmaWVsZHMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRmaWVsZHMgPSBbICduYW1lJywgJ3JvbGUnIF07CgoJLyoqCgkgKiBEZWZhdWx0IHJvbGVzIGFzIHByb3ZpZGVkIGJ5IFdvcmRQcmVzcyBDb3JlLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkcm9sZXMgPSBbICdhZG1pbmlzdHJhdG9yJywgJ2VkaXRvcicsICdhdXRob3InLCAnY29udHJpYnV0b3InLCAnc3Vic2NyaWJlcicgXTsKCgkvKioKCSAqIExpc3RzIGFsbCByb2xlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggcm9sZToKCSAqCgkgKiAqIG5hbWUKCSAqICogcm9sZQoJICoKCSAqIFRoZXJlIGFyZSBubyBvcHRpb25hbCBmaWVsZHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IHJvbGVzLgoJICogICAgICQgd3Agcm9sZSBsaXN0IC0tZmllbGRzPXJvbGUgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgcm9sZQoJICogICAgIGFkbWluaXN0cmF0b3IKCSAqICAgICBlZGl0b3IKCSAqICAgICBhdXRob3IKCSAqICAgICBjb250cmlidXRvcgoJICogICAgIHN1YnNjcmliZXIKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3Bfcm9sZXM7CgoJCSRvdXRwdXRfcm9sZXMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkd3Bfcm9sZXMtPnJvbGVzIGFzICRrZXkgPT4gJHJvbGUgKSB7CgkJCSRvdXRwdXRfcm9sZSA9IG5ldyBzdGRDbGFzcygpOwoKCQkJJG91dHB1dF9yb2xlLT5uYW1lID0gJHJvbGVbJ25hbWUnXTsKCQkJJG91dHB1dF9yb2xlLT5yb2xlID0gJGtleTsKCgkJCSRvdXRwdXRfcm9sZXNbXSA9ICRvdXRwdXRfcm9sZTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmZpZWxkcyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRvdXRwdXRfcm9sZXMgKTsKCX0KCgkvKioKCSAqIENoZWNrcyBpZiBhIHJvbGUgZXhpc3RzLgoJICoKCSAqIEV4aXRzIHdpdGggcmV0dXJuIGNvZGUgMCBpZiB0aGUgcm9sZSBleGlzdHMsIDEgaWYgaXQgZG9lcyBub3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxyb2xlLWtleT4KCSAqIDogVGhlIGludGVybmFsIG5hbWUgb2YgdGhlIHJvbGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayBpZiBhIHJvbGUgZXhpc3RzLgoJICogICAgICQgd3Agcm9sZSBleGlzdHMgZWRpdG9yCgkgKiAgICAgU3VjY2VzczogUm9sZSB3aXRoIElEICdlZGl0b3InIGV4aXN0cy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4aXN0cyggJGFyZ3MgKSB7CgkJZ2xvYmFsICR3cF9yb2xlczsKCgkJaWYgKCAhIGluX2FycmF5KCAkYXJnc1swXSwgYXJyYXlfa2V5cyggJHdwX3JvbGVzLT5yb2xlcyApLCB0cnVlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJSb2xlIHdpdGggSUQgJ3skYXJnc1swXX0nIGRvZXMgbm90IGV4aXN0LiIgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIlJvbGUgd2l0aCBJRCAneyRhcmdzWzBdfScgZXhpc3RzLiIgKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgcm9sZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHJvbGUta2V5PgoJICogOiBUaGUgaW50ZXJuYWwgbmFtZSBvZiB0aGUgcm9sZS4KCSAqCgkgKiA8cm9sZS1uYW1lPgoJICogOiBUaGUgcHVibGljbHkgdmlzaWJsZSBuYW1lIG9mIHRoZSByb2xlLgoJICoKCSAqIFstLWNsb25lPTxyb2xlPl0KCSAqIDogQ2xvbmUgY2FwYWJpbGl0aWVzIGZyb20gYW4gZXhpc3Rpbmcgcm9sZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSByb2xlIGZvciBBcHByb3Zlci4KCSAqICAgICAkIHdwIHJvbGUgY3JlYXRlIGFwcHJvdmVyIEFwcHJvdmVyCgkgKiAgICAgU3VjY2VzczogUm9sZSB3aXRoIGtleSAnYXBwcm92ZXInIGNyZWF0ZWQuCgkgKgoJICogICAgICMgQ3JlYXRlIHJvbGUgZm9yIFByb2R1Y3QgQWRtaW5pc3RyYXRvci4KCSAqICAgICAkIHdwIHJvbGUgY3JlYXRlIHByb2R1Y3RhZG1pbiAiUHJvZHVjdCBBZG1pbmlzdHJhdG9yIgoJICogICAgIFN1Y2Nlc3M6IFJvbGUgd2l0aCBrZXkgJ3Byb2R1Y3RhZG1pbicgY3JlYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3Bfcm9sZXM7CgoJCXNlbGY6OnBlcnNpc3RlbmNlX2NoZWNrKCk7CgoJCSRyb2xlX2tleSAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkcm9sZV9uYW1lID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgoJCWlmICggZW1wdHkoICRyb2xlX2tleSApIHx8IGVtcHR5KCAkcm9sZV9uYW1lICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDYW4ndCBjcmVhdGUgcm9sZSwgaW5zdWZmaWNpZW50IGluZm9ybWF0aW9uIHByb3ZpZGVkLiIgKTsKCQl9CgoJCSRjYXBhYmlsaXRpZXMgPSBmYWxzZTsKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydjbG9uZSddICkgKSB7CgkJCSRyb2xlX29iaiA9ICR3cF9yb2xlcy0+Z2V0X3JvbGUoICRhc3NvY19hcmdzWydjbG9uZSddICk7CgkJCWlmICggISAkcm9sZV9vYmogKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiJ3skYXNzb2NfYXJnc1snY2xvbmUnXX0nIHJvbGUgbm90IGZvdW5kLiIgKTsKCQkJfQoJCQkkY2FwYWJpbGl0aWVzID0gYXJyYXlfa2V5cyggJHJvbGVfb2JqLT5jYXBhYmlsaXRpZXMgKTsKCQl9CgoJCWlmICggYWRkX3JvbGUoICRyb2xlX2tleSwgJHJvbGVfbmFtZSApICkgewoJCQlpZiAoICEgZW1wdHkoICRjYXBhYmlsaXRpZXMgKSApIHsKCQkJCSRyb2xlX29iaiA9ICR3cF9yb2xlcy0+Z2V0X3JvbGUoICRyb2xlX2tleSApOwoJCQkJZm9yZWFjaCAoICRjYXBhYmlsaXRpZXMgYXMgJGNhcCApIHsKCQkJCQkkcm9sZV9vYmotPmFkZF9jYXAoICRjYXAgKTsKCQkJCX0KCQkJCVdQX0NMSTo6c3VjY2VzcyggIlJvbGUgd2l0aCBrZXkgJ3skcm9sZV9rZXl9JyBjcmVhdGVkLiBDbG9uZWQgY2FwYWJpbGl0aWVzIGZyb20gJ3skYXNzb2NfYXJnc1snY2xvbmUnXX0nLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggIlJvbGUgd2l0aCBrZXkgJ3skcm9sZV9rZXl9JyBjcmVhdGVkLiIgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJSb2xlIGNvdWxkbid0IGJlIGNyZWF0ZWQuIiApOwoJCX0KCX0KCgkvKioKCSAqIERlbGV0ZXMgYW4gZXhpc3Rpbmcgcm9sZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHJvbGUta2V5PgoJICogOiBUaGUgaW50ZXJuYWwgbmFtZSBvZiB0aGUgcm9sZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSBhcHByb3ZlciByb2xlLgoJICogICAgICQgd3Agcm9sZSBkZWxldGUgYXBwcm92ZXIKCSAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGgga2V5ICdhcHByb3ZlcicgZGVsZXRlZC4KCSAqCgkgKiAgICAgIyBEZWxldGUgcHJvZHVjdGFkbWluIHJvbGUuCgkgKiAgICAgd3Agcm9sZSBkZWxldGUgcHJvZHVjdGFkbWluCgkgKiAgICAgU3VjY2VzczogUm9sZSB3aXRoIGtleSAncHJvZHVjdGFkbWluJyBkZWxldGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncyApIHsKCQlnbG9iYWwgJHdwX3JvbGVzOwoKCQlzZWxmOjpwZXJzaXN0ZW5jZV9jaGVjaygpOwoKCQkkcm9sZV9rZXkgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJaWYgKCBlbXB0eSggJHJvbGVfa2V5ICkgfHwgISBpc3NldCggJHdwX3JvbGVzLT5yb2xlc1sgJHJvbGVfa2V5IF0gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1JvbGUga2V5IG5vdCBwcm92aWRlZCwgb3IgaXMgaW52YWxpZC4nICk7CgkJfQoKCQlyZW1vdmVfcm9sZSggJHJvbGVfa2V5ICk7CgoJCS8vIE5vdGU6IHJlbW92ZV9yb2xlKCkgZG9lc24ndCBpbmRpY2F0ZSBzdWNjZXNzIG9yIG90aGVyd2lzZSwgc28gd2UgaGF2ZSB0bwoJCS8vIGNoZWNrIG91cnNlbHZlcwoJCWlmICggISBpc3NldCggJHdwX3JvbGVzLT5yb2xlc1sgJHJvbGVfa2V5IF0gKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiUm9sZSB3aXRoIGtleSAneyRyb2xlX2tleX0nIGRlbGV0ZWQuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJSb2xlIHdpdGgga2V5ICd7JHJvbGVfa2V5fScgY291bGQgbm90IGJlIGRlbGV0ZWQuIiApOwoJCX0KCgl9CgoJLyoqCgkgKiBSZXNldHMgYW55IGRlZmF1bHQgcm9sZSB0byBkZWZhdWx0IGNhcGFiaWxpdGllcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxyb2xlLWtleT4uLi5dCgkgKiA6IFRoZSBpbnRlcm5hbCBuYW1lIG9mIG9uZSBvciBtb3JlIHJvbGVzIHRvIHJlc2V0LgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgZGVmYXVsdCByb2xlcyB3aWxsIGJlIHJlc2V0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVzZXQgcm9sZS4KCSAqICAgICAkIHdwIHJvbGUgcmVzZXQgYWRtaW5pc3RyYXRvciBhdXRob3IgY29udHJpYnV0b3IKCSAqICAgICBTdWNjZXNzOiBSZXNldCAxLzMgcm9sZXMuCgkgKgoJICogICAgICMgUmVzZXQgYWxsIGRlZmF1bHQgcm9sZXMuCgkgKiAgICAgJCB3cCByb2xlIHJlc2V0IC0tYWxsCgkgKiAgICAgU3VjY2VzczogQWxsIGRlZmF1bHQgcm9sZXMgcmVzZXQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXNldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlzZWxmOjpwZXJzaXN0ZW5jZV9jaGVjaygpOwoKCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICYmIGVtcHR5KCAkYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUm9sZSBrZXkgbm90IHByb3ZpZGVkLCBvciBpcyBpbnZhbGlkLicgKTsKCQl9CgoJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICdwb3B1bGF0ZV9yb2xlcycgKSApIHsKCQkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvc2NoZW1hLnBocCc7CgkJfQoKCQlnbG9iYWwgJHdwX3JvbGVzOwoJCSRhbGxfcm9sZXMgICAgID0gYXJyYXlfa2V5cyggJHdwX3JvbGVzLT5yb2xlcyApOwoJCSRwcmVzZXJ2ZV9hcmdzID0gJGFyZ3M7CgoJCS8vIEdldCBvdXIgZGVmYXVsdCByb2xlcy4KCQkkZGVmYXVsdF9yb2xlcyA9ICR0aGlzLT5yb2xlczsKCQkkcHJlc2VydmUgICAgICA9ICR0aGlzLT5yb2xlczsKCQkkYmVmb3JlICAgICAgICA9IFtdOwoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKSApIHsKCQkJZm9yZWFjaCAoICRkZWZhdWx0X3JvbGVzIGFzICRyb2xlICkgewoJCQkJJGJlZm9yZVsgJHJvbGUgXSA9IGdldF9yb2xlKCAkcm9sZSApOwoJCQkJcmVtb3ZlX3JvbGUoICRyb2xlICk7CgkJCQkkYXJnc1tdID0gJHJvbGU7CgkJCX0KCQkJcG9wdWxhdGVfcm9sZXMoKTsKCQkJJG5vdF9hZmZlY3RlZF9yb2xlcyA9IGFycmF5X2RpZmYoICRhbGxfcm9sZXMsICRkZWZhdWx0X3JvbGVzICk7CgkJCWlmICggISBlbXB0eSggJG5vdF9hZmZlY3RlZF9yb2xlcyApICkgewoJCQkJZm9yZWFjaCAoICRub3RfYWZmZWN0ZWRfcm9sZXMgYXMgJG5vdF9hZmZlY3RlZF9yb2xlICkgewoJCQkJCVdQX0NMSTo6bG9nKCAiQ3VzdG9tIHJvbGUgJ3skbm90X2FmZmVjdGVkX3JvbGV9JyBub3QgYWZmZWN0ZWQuIiApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCgkJCWZvcmVhY2ggKCAkYXJncyBhcyAkayA9PiAkcm9sZV9rZXkgKSB7CgkJCQkka2V5ID0gYXJyYXlfc2VhcmNoKCAkcm9sZV9rZXksICRkZWZhdWx0X3JvbGVzLCB0cnVlICk7CgkJCQlpZiAoIGZhbHNlICE9PSAka2V5ICkgewoJCQkJCXVuc2V0KCAkcHJlc2VydmVbICRrZXkgXSApOwoJCQkJCSRiZWZvcmVbICRyb2xlX2tleSBdID0gZ2V0X3JvbGUoICRyb2xlX2tleSApOwoJCQkJCXJlbW92ZV9yb2xlKCAkcm9sZV9rZXkgKTsKCQkJCX0gZWxzZSB7CgkJCQkJdW5zZXQoICRhcmdzWyAkayBdICk7CgkJCQl9CgkJCX0KCgkJCSRub3RfYWZmZWN0ZWRfcm9sZXMgPSBhcnJheV9kaWZmKCAkcHJlc2VydmVfYXJncywgJGRlZmF1bHRfcm9sZXMgKTsKCQkJaWYgKCAhIGVtcHR5KCAkbm90X2FmZmVjdGVkX3JvbGVzICkgKSB7CgkJCQlmb3JlYWNoICggJG5vdF9hZmZlY3RlZF9yb2xlcyBhcyAkbm90X2FmZmVjdGVkX3JvbGUgKSB7CgkJCQkJV1BfQ0xJOjpsb2coICJDdXN0b20gcm9sZSAneyRub3RfYWZmZWN0ZWRfcm9sZX0nIG5vdCBhZmZlY3RlZC4iICk7CgkJCQl9CgkJCX0KCgkJCS8vIE5vIHJvbGVzIHdlcmUgdW5zZXQsIGJhaWwuCgkJCWlmICggY291bnQoICRkZWZhdWx0X3JvbGVzICkgPT09IGNvdW50KCAkcHJlc2VydmUgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdNdXN0IHNwZWNpZnkgYSBkZWZhdWx0IHJvbGUgdG8gcmVzZXQuJyApOwoJCQl9CgoJCQkvLyBGb3IgdGhlIHJvbGVzIHdlJ3JlIG5vdCByZXNldHRpbmcuCgkJCWZvcmVhY2ggKCAkcHJlc2VydmUgYXMgJGsgPT4gJHJvbGUgKSB7CgkJCQkvKiBzYXZlIHJvbGVzCgkJCQkgKiBpZiBnZXRfcm9sZSBpcyBudWxsCgkJCQkgKiBzYXZlIHJvbGUgbmFtZSBmb3IgcmUtcmVtb3ZhbAoJCQkJICovCgkJCQkkcm9sZW9iaiAgICAgICAgPSBnZXRfcm9sZSggJHJvbGUgKTsKCQkJCSRwcmVzZXJ2ZVsgJGsgXSA9IGlzX251bGwoICRyb2xlb2JqICkgPyAkcm9sZSA6ICRyb2xlb2JqOwoKCQkJCXJlbW92ZV9yb2xlKCAkcm9sZSApOwoJCQl9CgoJCQkvLyBQdXQgYmFjayBhbGwgZGVmYXVsdCByb2xlcyBhbmQgY2FwYWJpbGl0aWVzLgoJCQlwb3B1bGF0ZV9yb2xlcygpOwoKCQkJLy8gUmVzdG9yZSB0aGUgcHJlc2VydmVkIHJvbGVzLgoJCQlmb3JlYWNoICggJHByZXNlcnZlIGFzICRrID0+ICRyb2xlb2JqICkgewoJCQkJLy8gUmUtcmVtb3ZlIGFmdGVyIHBvcHVsYXRpbmcuCgkJCQlpZiAoIGlzX2EoICRyb2xlb2JqLCAnV1BfUm9sZScgKSApIHsKCQkJCQlyZW1vdmVfcm9sZSggJHJvbGVvYmotPm5hbWUgKTsKCQkJCQlhZGRfcm9sZSggJHJvbGVvYmotPm5hbWUsIHVjd29yZHMoICRyb2xlb2JqLT5uYW1lICksICRyb2xlb2JqLT5jYXBhYmlsaXRpZXMgKTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gV2hlbiBub3QgYW4gb2JqZWN0LCB0aGF0IG1lYW5zIHRoZSByb2xlIGRpZG4ndCBleGlzdCBiZWZvcmUuCgkJCQkJcmVtb3ZlX3JvbGUoICRyb2xlb2JqICk7CgkJCQl9CgkJCX0KCQl9CgoJCSRudW1fcmVzZXQgICAgPSAwOwoJCSRhcmdzICAgICAgICAgPSBhcnJheV91bmlxdWUoICRhcmdzICk7CgkJJG51bV90b19yZXNldCA9IGNvdW50KCAkYXJncyApOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkcm9sZV9rZXkgKSB7CgkJCSRhZnRlclsgJHJvbGVfa2V5IF0gPSBnZXRfcm9sZSggJHJvbGVfa2V5ICk7CgoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5TdHJpY3RDb21wYXJpc29ucy5Mb29zZUNvbXBhcmlzb24gLS0gT2JqZWN0IGluc3RhbmNlcyB3b24ndCBiZSBzYW1lLCBzdHJpY3QgY2hlY2sgd2lsbCBmYWlsIGhlcmUuCgkJCWlmICggJGFmdGVyWyAkcm9sZV9rZXkgXSAhPSAkYmVmb3JlWyAkcm9sZV9rZXkgXSApIHsKCQkJCSsrJG51bV9yZXNldDsKCQkJCSRyZXN0b3JlZF9jYXAgICAgICAgPSBhcnJheV9kaWZmX2tleSggJGFmdGVyWyAkcm9sZV9rZXkgXS0+Y2FwYWJpbGl0aWVzLCAkYmVmb3JlWyAkcm9sZV9rZXkgXS0+Y2FwYWJpbGl0aWVzICk7CgkJCQkkcmVtb3ZlZF9jYXAgICAgICAgID0gYXJyYXlfZGlmZl9rZXkoICRiZWZvcmVbICRyb2xlX2tleSBdLT5jYXBhYmlsaXRpZXMsICRhZnRlclsgJHJvbGVfa2V5IF0tPmNhcGFiaWxpdGllcyApOwoJCQkJJHJlc3RvcmVkX2NhcF9jb3VudCA9IGNvdW50KCAkcmVzdG9yZWRfY2FwICk7CgkJCQkkcmVtb3ZlZF9jYXBfY291bnQgID0gY291bnQoICRyZW1vdmVkX2NhcCApOwoJCQkJJHJlc3RvcmVkX3RleHQgICAgICA9ICggMSA9PT0gJHJlc3RvcmVkX2NhcF9jb3VudCApID8gJyVkIGNhcGFiaWxpdHknIDogJyVkIGNhcGFiaWxpdGllcyc7CgkJCQkkcmVtb3ZlZF90ZXh0ICAgICAgID0gKCAxID09PSAkcmVtb3ZlZF9jYXBfY291bnQgKSA/ICclZCBjYXBhYmlsaXR5JyA6ICclZCBjYXBhYmlsaXRpZXMnOwoJCQkJJG1lc3NhZ2UgICAgICAgICAgICA9ICJSZXN0b3JlZCB7JHJlc3RvcmVkX3RleHR9IHRvIGFuZCByZW1vdmVkIHskcmVtb3ZlZF90ZXh0fSBmcm9tICclcycgcm9sZS4iOwoJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICRtZXNzYWdlLCAkcmVzdG9yZWRfY2FwX2NvdW50LCAkcmVtb3ZlZF9jYXBfY291bnQsICRyb2xlX2tleSApICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZyggIk5vIGNoYW5nZXMgbmVjZXNzYXJ5IGZvciAneyRyb2xlX2tleX0nIHJvbGUuIiApOwoJCQl9CgkJfQoJCWlmICggJG51bV9yZXNldCApIHsKCQkJaWYgKCAxID09PSBjb3VudCggJGFyZ3MgKSApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ1JvbGUgcmVzZXQuJyApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAieyRudW1fcmVzZXR9IG9mIHskbnVtX3RvX3Jlc2V0fSByb2xlcyByZXNldC4iICk7CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAoIDEgPT09IGNvdW50KCAkYXJncyApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnUm9sZSBkaWRuXCd0IG5lZWQgcmVzZXR0aW5nLicgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ05vIHJvbGVzIG5lZWRlZCByZXNldHRpbmcuJyApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogQXNzZXJ0IHRoYXQgdGhlIHJvbGVzIGFyZSBwZXJzaXN0ZWQgdG8gdGhlIGRhdGFiYXNlLgoJICoKCSAqIEB0aHJvd3MgXFdQX0NMSVxFeGl0RXhjZXB0aW9uIElmIHRoZSByb2xlcyBhcmUgbm90IHBlcnNpc3RlZCB0byB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFiYXNlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBwZXJzaXN0ZW5jZV9jaGVjaygpIHsKCQlnbG9iYWwgJHdwX3JvbGVzOwoKCQlpZiAoICEgJHdwX3JvbGVzLT51c2VfZGIgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdSb2xlIGRlZmluaXRpb25zIGFyZSBub3QgcGVyc2lzdGVudC4nICk7CgkJfQoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfcm9sZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9yb2xlX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfcm9sZV9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY2FwJywgJ0NhcGFiaWxpdGllc19Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAncm9sZScsICdSb2xlX0NvbW1hbmQnICk7Cjw/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+dXNlcl9sb2dpbjsKCQkJCSRzaG9ydGVzdCA9ICRsZXY7CgkJCX0KCQkJJHNob3J0ZXN0YXZnW10gPSAkbGV2OwoJCX0KCQkvLyBpbiBjYXNlIGFsbCB1c2VybmFtZXMgaGF2ZSBhIGNvbW1vbiBwYXR0ZXJuCgkJaWYgKCAkc2hvcnRlc3QgPiAoIGFycmF5X3N1bSggJHNob3J0ZXN0YXZnICkgLyBjb3VudCggJHNob3J0ZXN0YXZnICkgKSApIHsKCQkJcmV0dXJuICcnOwoJCX0KCgkJcmV0dXJuICRjbG9zZXN0OwoJfQoKfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2ltcG9ydF9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9pbXBvcnRfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9pbXBvcnRfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2ltcG9ydCcsICdJbXBvcnRfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIFBlcmZvcm1zIGJhc2ljIGRhdGFiYXNlIG9wZXJhdGlvbnMgdXNpbmcgY3JlZGVudGlhbHMgc3RvcmVkIGluIHdwLWNvbmZpZy5waHAuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBkYXRhYmFzZS4KICogICAgICQgd3AgZGIgY3JlYXRlCiAqICAgICBTdWNjZXNzOiBEYXRhYmFzZSBjcmVhdGVkLgogKgogKiAgICAgIyBEcm9wIGFuIGV4aXN0aW5nIGRhdGFiYXNlLgogKiAgICAgJCB3cCBkYiBkcm9wIC0teWVzCiAqICAgICBTdWNjZXNzOiBEYXRhYmFzZSBkcm9wcGVkLgogKgogKiAgICAgIyBSZXNldCB0aGUgY3VycmVudCBkYXRhYmFzZS4KICogICAgICQgd3AgZGIgcmVzZXQgLS15ZXMKICogICAgIFN1Y2Nlc3M6IERhdGFiYXNlIHJlc2V0LgogKgogKiAgICAgIyBFeGVjdXRlIGEgU1FMIHF1ZXJ5IHN0b3JlZCBpbiBhIGZpbGUuCiAqICAgICAkIHdwIGRiIHF1ZXJ5IDwgZGVidWcuc3FsCiAqCiAqIEB3aGVuIGFmdGVyX3dwX2NvbmZpZ19sb2FkCiAqLwpjbGFzcyBEQl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogTGVnYWN5IFVURi04IGVuY29kaW5nIGZvciBNeVNRTC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBFTkNPRElOR19VVEY4ID0gJ3V0ZjgnOwoKCS8qKgoJICogU3RhbmRhcmRzLWNvbXBsaWFudCBVVEYtOCBlbmNvZGluZyBmb3IgTXlTUUwuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgRU5DT0RJTkdfVVRGOE1CNCA9ICd1dGY4bWI0JzsKCgkvKioKCSAqIEEgbGlzdCBvZiBpbmNvbXBhdGlibGUgU1FMIG1vZGVzLgoJICoKCSAqIENvcGllZCBvdmVyIGZyb20gV29yZFByZXNzIENvcmUgY29kZS4KCSAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL1dvcmRQcmVzcy93b3JkcHJlc3MtZGV2ZWxvcC9ibG9iLzUuNC4wL3NyYy93cC1pbmNsdWRlcy93cC1kYi5waHAjTDU1OS1MNTcyCgkgKgoJICogQHZhciBzdHJpbmdbXSBBcnJheSBvZiBTUUwgbW9kZSBuYW1lcyB0aGF0IGFyZSBpbmNvbXBhdGlibGUgd2l0aCBXb3JkUHJlc3MuCgkgKi8KCXByb3RlY3RlZCAkc3FsX2luY29tcGF0aWJsZV9tb2RlcyA9IFsKCQknTk9fWkVST19EQVRFJywKCQknT05MWV9GVUxMX0dST1VQX0JZJywKCQknU1RSSUNUX1RSQU5TX1RBQkxFUycsCgkJJ1NUUklDVF9BTExfVEFCTEVTJywKCQknVFJBRElUSU9OQUwnLAoJCSdBTlNJJywKCV07CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IGRhdGFiYXNlLgoJICoKCSAqIFJ1bnMgYENSRUFURV9EQVRBQkFTRWAgU1FMIHN0YXRlbWVudCB1c2luZyBgREJfSE9TVGAsIGBEQl9OQU1FYCwKCSAqIGBEQl9VU0VSYCBhbmQgYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscyBzcGVjaWZpZWQgaW4KCSAqIHdwLWNvbmZpZy5waHAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgZGIgY3JlYXRlCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgY3JlYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJF8sICRhc3NvY19hcmdzICkgewoKCQkkdGhpcy0+cnVuX3F1ZXJ5KCBzZWxmOjpnZXRfY3JlYXRlX3F1ZXJ5KCksICRhc3NvY19hcmdzICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0RhdGFiYXNlIGNyZWF0ZWQuJyApOwoJfQoKCS8qKgoJICogRGVsZXRlcyB0aGUgZXhpc3RpbmcgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgRFJPUF9EQVRBQkFTRWAgU1FMIHN0YXRlbWVudCB1c2luZyBgREJfSE9TVGAsIGBEQl9OQU1FYCwKCSAqIGBEQl9VU0VSYCBhbmQgYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscyBzcGVjaWZpZWQgaW4KCSAqIHdwLWNvbmZpZy5waHAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IEFuc3dlciB5ZXMgdG8gdGhlIGNvbmZpcm1hdGlvbiBtZXNzYWdlLgoJICoKCSAqIFstLWRlZmF1bHRzXQoJICogOiBMb2FkcyB0aGUgZW52aXJvbm1lbnQncyBNeVNRTCBvcHRpb24gZmlsZXMuIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gc2tpcCBsb2FkaW5nIHRoZW0gdG8gYXZvaWQgZmFpbHVyZXMgZHVlIHRvIG1pc2NvbmZpZ3VyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBkYiBkcm9wIC0teWVzCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgZHJvcHBlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRyb3AoICRfLCAkYXNzb2NfYXJncyApIHsKCQlXUF9DTEk6OmNvbmZpcm0oICJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZHJvcCB0aGUgJyIgLiBEQl9OQU1FIC4gIicgZGF0YWJhc2U/IiwgJGFzc29jX2FyZ3MgKTsKCgkJJHRoaXMtPnJ1bl9xdWVyeSggc3ByaW50ZiggJ0RST1AgREFUQUJBU0UgYCVzYCcsIERCX05BTUUgKSwgJGFzc29jX2FyZ3MgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAnRGF0YWJhc2UgZHJvcHBlZC4nICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGFsbCB0YWJsZXMgZnJvbSB0aGUgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgRFJPUF9EQVRBQkFTRWAgYW5kIGBDUkVBVEVfREFUQUJBU0VgIFNRTCBzdGF0ZW1lbnRzIHVzaW5nCgkgKiBgREJfSE9TVGAsIGBEQl9OQU1FYCwgYERCX1VTRVJgIGFuZCBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzCgkgKiBzcGVjaWZpZWQgaW4gd3AtY29uZmlnLnBocC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqIFstLXllc10KCSAqIDogQW5zd2VyIHllcyB0byB0aGUgY29uZmlybWF0aW9uIG1lc3NhZ2UuCgkgKgoJICogWy0tZGVmYXVsdHNdCgkgKiA6IExvYWRzIHRoZSBlbnZpcm9ubWVudCdzIE15U1FMIG9wdGlvbiBmaWxlcy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byBza2lwIGxvYWRpbmcgdGhlbSB0byBhdm9pZCBmYWlsdXJlcyBkdWUgdG8gbWlzY29uZmlndXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIHJlc2V0IC0teWVzCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgcmVzZXQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXNldCggJF8sICRhc3NvY19hcmdzICkgewoJCVdQX0NMSTo6Y29uZmlybSggIkFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byByZXNldCB0aGUgJyIgLiBEQl9OQU1FIC4gIicgZGF0YWJhc2U/IiwgJGFzc29jX2FyZ3MgKTsKCgkJJHRoaXMtPnJ1bl9xdWVyeSggc3ByaW50ZiggJ0RST1AgREFUQUJBU0UgSUYgRVhJU1RTIGAlc2AnLCBEQl9OQU1FICksICRhc3NvY19hcmdzICk7CgkJJHRoaXMtPnJ1bl9xdWVyeSggc2VsZjo6Z2V0X2NyZWF0ZV9xdWVyeSgpLCAkYXNzb2NfYXJncyApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdEYXRhYmFzZSByZXNldC4nICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGFsbCB0YWJsZXMgd2l0aCBgJHRhYmxlX3ByZWZpeGAgZnJvbSB0aGUgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgRFJPUF9UQUJMRWAgZm9yIGVhY2ggdGFibGUgdGhhdCBoYXMgYSBgJHRhYmxlX3ByZWZpeGAgYXMgc3BlY2lmaWVkCgkgKiBpbiB3cC1jb25maWcucGhwLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1kYnVzZXI9PHZhbHVlPl0KCSAqIDogVXNlcm5hbWUgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0teWVzXQoJICogOiBBbnN3ZXIgeWVzIHRvIHRoZSBjb25maXJtYXRpb24gbWVzc2FnZS4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgY3VycmVudCBzaXRlIHByZWZpeC4KCSAqICAgICAkIHdwIGRiIGNsZWFuIC0teWVzCgkgKiAgICAgU3VjY2VzczogVGFibGVzIGRyb3BwZWQuCgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gY2xlYW4oICRfLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCVdQX0NMSTo6Y29uZmlybSgKCQkJc3ByaW50ZigKCQkJCSJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZHJvcCBhbGwgdGhlIHRhYmxlcyBvbiAnJXMnIHRoYXQgdXNlIHRoZSBjdXJyZW50IHNpdGUncyBkYXRhYmFzZSBwcmVmaXggKCclcycpPyIsCgkJCQlEQl9OQU1FLAoJCQkJJHdwZGItPmdldF9ibG9nX3ByZWZpeCgpCgkJCSksCgkJCSRhc3NvY19hcmdzCgkJKTsKCgkJJHRhYmxlcyA9IFV0aWxzXHdwX2dldF90YWJsZV9uYW1lcygKCQkJW10sCgkJCVsgJ2FsbC10YWJsZXMtd2l0aC1wcmVmaXgnID0+IHRydWUgXQoJCSk7CgoJCWZvcmVhY2ggKCAkdGFibGVzIGFzICR0YWJsZSApIHsKCQkJJHRoaXMtPnJ1bl9xdWVyeSgKCQkJCXNwcmludGYoCgkJCQkJJ0RST1AgVEFCTEUgSUYgRVhJU1RTIGAlc2AuYCVzYCcsCgkJCQkJREJfTkFNRSwKCQkJCQkkdGFibGUKCQkJCSksCgkJCQkkYXNzb2NfYXJncwoJCQkpOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAnVGFibGVzIGRyb3BwZWQuJyApOwoJfQoKCS8qKgoJICogQ2hlY2tzIHRoZSBjdXJyZW50IHN0YXR1cyBvZiB0aGUgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgbXlzcWxjaGVja2AgdXRpbGl0eSB3aXRoIGAtLWNoZWNrYCB1c2luZyBgREJfSE9TVGAsCgkgKiBgREJfTkFNRWAsIGBEQl9VU0VSYCBhbmQgYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscwoJICogc3BlY2lmaWVkIGluIHdwLWNvbmZpZy5waHAuCgkgKgoJICogW1NlZSBkb2NzXShodHRwOi8vZGV2Lm15c3FsLmNvbS9kb2MvcmVmbWFuLzUuNy9lbi9jaGVjay10YWJsZS5odG1sKQoJICogZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgYENIRUNLIFRBQkxFYCBzdGF0ZW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsY2hlY2suIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWxjaGVjay4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byBteXNxbGNoZWNrLiBbUmVmZXIgdG8gbXlzcWxjaGVjayBkb2NzXShodHRwczovL2Rldi5teXNxbC5jb20vZG9jL2VuL215c3FsY2hlY2suaHRtbCkuCgkgKgoJICogWy0tZGVmYXVsdHNdCgkgKiA6IExvYWRzIHRoZSBlbnZpcm9ubWVudCdzIE15U1FMIG9wdGlvbiBmaWxlcy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byBza2lwIGxvYWRpbmcgdGhlbSB0byBhdm9pZCBmYWlsdXJlcyBkdWUgdG8gbWlzY29uZmlndXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIGNoZWNrCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgY2hlY2tlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNoZWNrKCAkXywgJGFzc29jX2FyZ3MgKSB7CgoJCSRjb21tYW5kID0gc3ByaW50ZiggJy91c3IvYmluL2VudiBteXNxbGNoZWNrJXMgJXMnLCAkdGhpcy0+Z2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAkYXNzb2NfYXJncyApLCAnJXMnICk7CgkJV1BfQ0xJOjpkZWJ1ZyggIlJ1bm5pbmcgc2hlbGwgY29tbWFuZDogeyRjb21tYW5kfSIsICdkYicgKTsKCgkJJGFzc29jX2FyZ3NbJ2NoZWNrJ10gPSB0cnVlOwoJCXNlbGY6OnJ1bigKCQkJVXRpbHNcZXNjX2NtZCggJGNvbW1hbmQsIERCX05BTUUgKSwKCQkJJGFzc29jX2FyZ3MKCQkpOwoKCQlXUF9DTEk6OmRlYnVnKCAnQXNzb2NpYXRpdmUgYXJndW1lbnRzOiAnIC4ganNvbl9lbmNvZGUoICRhc3NvY19hcmdzICksICdkYicgKTsKCQlXUF9DTEk6OnN1Y2Nlc3MoICdEYXRhYmFzZSBjaGVja2VkLicgKTsKCX0KCgkvKioKCSAqIE9wdGltaXplcyB0aGUgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgbXlzcWxjaGVja2AgdXRpbGl0eSB3aXRoIGAtLW9wdGltaXplPXRydWVgIHVzaW5nIGBEQl9IT1NUYCwKCSAqIGBEQl9OQU1FYCwgYERCX1VTRVJgIGFuZCBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzCgkgKiBzcGVjaWZpZWQgaW4gd3AtY29uZmlnLnBocC4KCSAqCgkgKiBbU2VlIGRvY3NdKGh0dHA6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNS43L2VuL29wdGltaXplLXRhYmxlLmh0bWwpCgkgKiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBgT1BUSU1JWkUgVEFCTEVgIHN0YXRlbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWxjaGVjay4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbGNoZWNrLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEV4dHJhIGFyZ3VtZW50cyB0byBwYXNzIHRvIG15c3FsY2hlY2suIFtSZWZlciB0byBteXNxbGNoZWNrIGRvY3NdKGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvZW4vbXlzcWxjaGVjay5odG1sKS4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgZGIgb3B0aW1pemUKCSAqICAgICBTdWNjZXNzOiBEYXRhYmFzZSBvcHRpbWl6ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvcHRpbWl6ZSggJF8sICRhc3NvY19hcmdzICkgewoKCQkkY29tbWFuZCA9IHNwcmludGYoICcvdXNyL2Jpbi9lbnYgbXlzcWxjaGVjayVzICVzJywgJHRoaXMtPmdldF9kZWZhdWx0c19mbGFnX3N0cmluZyggJGFzc29jX2FyZ3MgKSwgJyVzJyApOwoJCVdQX0NMSTo6ZGVidWcoICJSdW5uaW5nIHNoZWxsIGNvbW1hbmQ6IHskY29tbWFuZH0iLCAnZGInICk7CgoJCSRhc3NvY19hcmdzWydvcHRpbWl6ZSddID0gdHJ1ZTsKCQlzZWxmOjpydW4oCgkJCVV0aWxzXGVzY19jbWQoICRjb21tYW5kLCBEQl9OQU1FICksCgkJCSRhc3NvY19hcmdzCgkJKTsKCgkJV1BfQ0xJOjpkZWJ1ZyggJ0Fzc29jaWF0aXZlIGFyZ3VtZW50czogJyAuIGpzb25fZW5jb2RlKCAkYXNzb2NfYXJncyApLCAnZGInICk7CgkJV1BfQ0xJOjpzdWNjZXNzKCAnRGF0YWJhc2Ugb3B0aW1pemVkLicgKTsKCX0KCgkvKioKCSAqIFJlcGFpcnMgdGhlIGRhdGFiYXNlLgoJICoKCSAqIFJ1bnMgYG15c3FsY2hlY2tgIHV0aWxpdHkgd2l0aCBgLS1yZXBhaXI9dHJ1ZWAgdXNpbmcgYERCX0hPU1RgLAoJICogYERCX05BTUVgLCBgREJfVVNFUmAgYW5kIGBEQl9QQVNTV09SRGAgZGF0YWJhc2UgY3JlZGVudGlhbHMKCSAqIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLgoJICoKCSAqIFtTZWUgZG9jc10oaHR0cDovL2Rldi5teXNxbC5jb20vZG9jL3JlZm1hbi81LjcvZW4vcmVwYWlyLXRhYmxlLmh0bWwpIGZvcgoJICogbW9yZSBkZXRhaWxzIG9uIHRoZSBgUkVQQUlSIFRBQkxFYCBzdGF0ZW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsY2hlY2suIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWxjaGVjay4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byBteXNxbGNoZWNrLiBbUmVmZXIgdG8gbXlzcWxjaGVjayBkb2NzXShodHRwczovL2Rldi5teXNxbC5jb20vZG9jL2VuL215c3FsY2hlY2suaHRtbCkuCgkgKgoJICogWy0tZGVmYXVsdHNdCgkgKiA6IExvYWRzIHRoZSBlbnZpcm9ubWVudCdzIE15U1FMIG9wdGlvbiBmaWxlcy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byBza2lwIGxvYWRpbmcgdGhlbSB0byBhdm9pZCBmYWlsdXJlcyBkdWUgdG8gbWlzY29uZmlndXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIHJlcGFpcgoJICogICAgIFN1Y2Nlc3M6IERhdGFiYXNlIHJlcGFpcmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVwYWlyKCAkXywgJGFzc29jX2FyZ3MgKSB7CgoJCSRjb21tYW5kID0gc3ByaW50ZiggJy91c3IvYmluL2VudiBteXNxbGNoZWNrJXMgJXMnLCAkdGhpcy0+Z2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAkYXNzb2NfYXJncyApLCAnJXMnICk7CgkJV1BfQ0xJOjpkZWJ1ZyggIlJ1bm5pbmcgc2hlbGwgY29tbWFuZDogeyRjb21tYW5kfSIsICdkYicgKTsKCgkJJGFzc29jX2FyZ3NbJ3JlcGFpciddID0gdHJ1ZTsKCQlzZWxmOjpydW4oCgkJCVV0aWxzXGVzY19jbWQoICRjb21tYW5kLCBEQl9OQU1FICksCgkJCSRhc3NvY19hcmdzCgkJKTsKCgkJV1BfQ0xJOjpkZWJ1ZyggJ0Fzc29jaWF0aXZlIGFyZ3VtZW50czogJyAuIGpzb25fZW5jb2RlKCAkYXNzb2NfYXJncyApLCAnZGInICk7CgkJV1BfQ0xJOjpzdWNjZXNzKCAnRGF0YWJhc2UgcmVwYWlyZWQuJyApOwoJfQoKCS8qKgoJICogT3BlbnMgYSBNeVNRTCBjb25zb2xlIHVzaW5nIGNyZWRlbnRpYWxzIGZyb20gd3AtY29uZmlnLnBocAoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1kYXRhYmFzZT08ZGF0YWJhc2U+XQoJICogOiBVc2UgYSBzcGVjaWZpYyBkYXRhYmFzZS4gRGVmYXVsdHMgdG8gREJfTkFNRS4KCSAqCgkgKiBbLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9PGNoYXJhY3Rlci1zZXQ+XQoJICogOiBVc2UgYSBzcGVjaWZpYyBjaGFyYWN0ZXIgc2V0LiBEZWZhdWx0cyB0byBEQl9DSEFSU0VUIHdoZW4gZGVmaW5lZC4KCSAqCgkgKiBbLS1kYnVzZXI9PHZhbHVlPl0KCSAqIDogVXNlcm5hbWUgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byBteXNxbC4gW1JlZmVyIHRvIG15c3FsIGRvY3NdKGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvZW4vbXlzcWwtY29tbWFuZC1vcHRpb25zLmh0bWwpLgoJICoKCSAqIFstLWRlZmF1bHRzXQoJICogOiBMb2FkcyB0aGUgZW52aXJvbm1lbnQncyBNeVNRTCBvcHRpb24gZmlsZXMuIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gc2tpcCBsb2FkaW5nIHRoZW0gdG8gYXZvaWQgZmFpbHVyZXMgZHVlIHRvIG1pc2NvbmZpZ3VyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBPcGVuIE15U1FMIGNvbnNvbGUKCSAqICAgICAkIHdwIGRiIGNsaQoJICogICAgIG15c3FsPgoJICoKCSAqIEBhbGlhcyBjb25uZWN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjbGkoICRfLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbW1hbmQgPSBzcHJpbnRmKCAnL3Vzci9iaW4vZW52IG15c3FsJXMgLS1uby1hdXRvLXJlaGFzaCcsICR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICkgKTsKCQlXUF9DTEk6OmRlYnVnKCAiUnVubmluZyBzaGVsbCBjb21tYW5kOiB7JGNvbW1hbmR9IiwgJ2RiJyApOwoKCQlpZiAoICEgaXNzZXQoICRhc3NvY19hcmdzWydkYXRhYmFzZSddICkgKSB7CgkJCSRhc3NvY19hcmdzWydkYXRhYmFzZSddID0gREJfTkFNRTsKCQl9CgoJCVdQX0NMSTo6ZGVidWcoICdBc3NvY2lhdGl2ZSBhcmd1bWVudHM6ICcgLiBqc29uX2VuY29kZSggJGFzc29jX2FyZ3MgKSwgJ2RiJyApOwoJCXNlbGY6OnJ1biggJGNvbW1hbmQsICRhc3NvY19hcmdzLCBudWxsLCB0cnVlICk7Cgl9CgoJLyoqCgkgKiBFeGVjdXRlcyBhIFNRTCBxdWVyeSBhZ2FpbnN0IHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBFeGVjdXRlcyBhbiBhcmJpdHJhcnkgU1FMIHF1ZXJ5IHVzaW5nIGBEQl9IT1NUYCwgYERCX05BTUVgLCBgREJfVVNFUmAKCSAqICBhbmQgYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscyBzcGVjaWZpZWQgaW4gd3AtY29uZmlnLnBocC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxzcWw+XQoJICogOiBBIFNRTCBxdWVyeS4gSWYgbm90IHBhc3NlZCwgd2lsbCB0cnkgdG8gcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEV4dHJhIGFyZ3VtZW50cyB0byBwYXNzIHRvIG15c3FsLiBbUmVmZXIgdG8gbXlzcWwgZG9jc10oaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9lbi9teXNxbC1jb21tYW5kLW9wdGlvbnMuaHRtbCkuCgkgKgoJICogWy0tZGVmYXVsdHNdCgkgKiA6IExvYWRzIHRoZSBlbnZpcm9ubWVudCdzIE15U1FMIG9wdGlvbiBmaWxlcy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byBza2lwIGxvYWRpbmcgdGhlbSB0byBhdm9pZCBmYWlsdXJlcyBkdWUgdG8gbWlzY29uZmlndXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEV4ZWN1dGUgYSBxdWVyeSBzdG9yZWQgaW4gYSBmaWxlCgkgKiAgICAgJCB3cCBkYiBxdWVyeSA8IGRlYnVnLnNxbAoJICoKCSAqICAgICAjIENoZWNrIGFsbCB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlCgkgKiAgICAgJCB3cCBkYiBxdWVyeSAiQ0hFQ0sgVEFCTEUgJCh3cCBkYiB0YWJsZXMgfCBwYXN0ZSAtcyAtZCwgLSk7IgoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBUYWJsZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgT3AgICAgfCBNc2dfdHlwZSB8IE1zZ190ZXh0IHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX3VzZXJzICAgICAgICAgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfdXNlcm1ldGEgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF9wb3N0cyAgICAgICAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX2NvbW1lbnRzICAgICAgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfbGlua3MgICAgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF9vcHRpb25zICAgICAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX3Bvc3RtZXRhICAgICAgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfdGVybXMgICAgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF90ZXJtX3RheG9ub215ICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX3Rlcm1fcmVsYXRpb25zaGlwcyB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfdGVybW1ldGEgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF9jb21tZW50bWV0YSAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgUGFzcyBleHRyYSBhcmd1bWVudHMgdGhyb3VnaCB0byBNeVNRTAoJICogICAgICQgd3AgZGIgcXVlcnkgJ1NFTEVDVCAqIEZST00gd3Bfb3B0aW9ucyBXSEVSRSBvcHRpb25fbmFtZT0iaG9tZSInIC0tc2tpcC1jb2x1bW4tbmFtZXMKCSAqICAgICArLS0tKy0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0rCgkgKiAgICAgfCAyIHwgaG9tZSB8IGh0dHA6Ly93b3JkcHJlc3MtZGV2ZWxvcC5kZXYgfCB5ZXMgfAoJICogICAgICstLS0rLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLSsKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHF1ZXJ5KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRjb21tYW5kID0gc3ByaW50ZiggJy91c3IvYmluL2VudiBteXNxbCVzIC0tbm8tYXV0by1yZWhhc2gnLCAkdGhpcy0+Z2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAkYXNzb2NfYXJncyApICk7CgkJV1BfQ0xJOjpkZWJ1ZyggIlJ1bm5pbmcgc2hlbGwgY29tbWFuZDogeyRjb21tYW5kfSIsICdkYicgKTsKCgkJJGFzc29jX2FyZ3NbJ2RhdGFiYXNlJ10gPSBEQl9OQU1FOwoKCQkvLyBUaGUgcXVlcnkgbWlnaHQgY29tZSBmcm9tIFNURElOLgoJCWlmICggISBlbXB0eSggJGFyZ3MgKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2V4ZWN1dGUnXSA9ICRhcmdzWzBdOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2V4ZWN1dGUnXSApICkgewoJCQkvLyBFbnN1cmUgdGhhdCB0aGUgU1FMIG1vZGUgaXMgY29tcGF0aWJsZSB3aXRoIFdQREIuCgkJCSRhc3NvY19hcmdzWydleGVjdXRlJ10gPSAkdGhpcy0+Z2V0X3NxbF9tb2RlX3F1ZXJ5KCAkYXNzb2NfYXJncyApIC4gJGFzc29jX2FyZ3NbJ2V4ZWN1dGUnXTsKCQl9CgoJCVdQX0NMSTo6ZGVidWcoICdBc3NvY2lhdGl2ZSBhcmd1bWVudHM6ICcgLiBqc29uX2VuY29kZSggJGFzc29jX2FyZ3MgKSwgJ2RiJyApOwoJCXNlbGY6OnJ1biggJGNvbW1hbmQsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBFeHBvcnRzIHRoZSBkYXRhYmFzZSB0byBhIGZpbGUgb3IgdG8gU1RET1VULgoJICoKCSAqIFJ1bnMgYG15c3FsZHVtcGAgdXRpbGl0eSB1c2luZyBgREJfSE9TVGAsIGBEQl9OQU1FYCwgYERCX1VTRVJgIGFuZAoJICogYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscyBzcGVjaWZpZWQgaW4gd3AtY29uZmlnLnBocC4gQWNjZXB0cyBhbnkgdmFsaWQgYG15c3FsZHVtcGAgZmxhZ3MuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8ZmlsZT5dCgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBTUUwgZmlsZSB0byBleHBvcnQuIElmICctJywgdGhlbiBvdXRwdXRzIHRvIFNURE9VVC4gSWYKCSAqIG9taXR0ZWQsIGl0IHdpbGwgYmUgJ3tkYm5hbWV9LXtZLW0tZH0te3JhbmRvbS1oYXNofS5zcWwnLgoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsZHVtcC4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbGR1bXAuIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRXh0cmEgYXJndW1lbnRzIHRvIHBhc3MgdG8gbXlzcWxkdW1wLiBbUmVmZXIgdG8gbXlzcWxkdW1wIGRvY3NdKGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvZW4vbXlzcWxkdW1wLmh0bWwjbXlzcWxkdW1wLW9wdGlvbi1zdW1tYXJ5KS4KCSAqCgkgKiBbLS10YWJsZXM9PHRhYmxlcz5dCgkgKiA6IFRoZSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBzcGVjaWZpYyB0YWJsZXMgdG8gZXhwb3J0LiBFeGNsdWRpbmcgdGhpcyBwYXJhbWV0ZXIgd2lsbCBleHBvcnQgYWxsIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UuCgkgKgoJICogWy0tZXhjbHVkZV90YWJsZXM9PHRhYmxlcz5dCgkgKiA6IFRoZSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBzcGVjaWZpYyB0YWJsZXMgdGhhdCBzaG91bGQgYmUgc2tpcHBlZCBmcm9tIGV4cG9ydGluZy4gRXhjbHVkaW5nIHRoaXMgcGFyYW1ldGVyIHdpbGwgZXhwb3J0IGFsbCB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlLgoJICoKCSAqIFstLWluY2x1ZGUtdGFibGVzcGFjZXNdCgkgKiA6IFNraXBzIGFkZGluZyB0aGUgZGVmYXVsdCAtLW5vLXRhYmxlc3BhY2VzIG9wdGlvbiB0byBteXNxbGR1bXAuCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBPdXRwdXQgZmlsZW5hbWUgZm9yIHRoZSBleHBvcnRlZCBkYXRhYmFzZS4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRXhwb3J0IGRhdGFiYXNlIHdpdGggZHJvcCBxdWVyeSBpbmNsdWRlZAoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tYWRkLWRyb3AtdGFibGUKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byAnd29yZHByZXNzX2RiYXNlLWRiNzJiYjUuc3FsJy4KCSAqCgkgKiAgICAgIyBFeHBvcnQgY2VydGFpbiB0YWJsZXMKCSAqICAgICAkIHdwIGRiIGV4cG9ydCAtLXRhYmxlcz13cF9vcHRpb25zLHdwX3VzZXJzCgkgKiAgICAgU3VjY2VzczogRXhwb3J0ZWQgdG8gJ3dvcmRwcmVzc19kYmFzZS1kYjcyYmI1LnNxbCcuCgkgKgoJICogICAgICMgRXhwb3J0IGFsbCB0YWJsZXMgbWF0Y2hpbmcgYSB3aWxkY2FyZAoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tdGFibGVzPSQod3AgZGIgdGFibGVzICd3cF91c2VyKicgLS1mb3JtYXQ9Y3N2KQoJICogICAgIFN1Y2Nlc3M6IEV4cG9ydGVkIHRvICd3b3JkcHJlc3NfZGJhc2UtZGI3MmJiNS5zcWwnLgoJICoKCSAqICAgICAjIEV4cG9ydCBhbGwgdGFibGVzIG1hdGNoaW5nIHByZWZpeAoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tdGFibGVzPSQod3AgZGIgdGFibGVzIC0tYWxsLXRhYmxlcy13aXRoLXByZWZpeCAtLWZvcm1hdD1jc3YpCgkgKiAgICAgU3VjY2VzczogRXhwb3J0ZWQgdG8gJ3dvcmRwcmVzc19kYmFzZS1kYjcyYmI1LnNxbCcuCgkgKgoJICogICAgICMgRXhwb3J0IGNlcnRhaW4gcG9zdHMgd2l0aG91dCBjcmVhdGUgdGFibGUgc3RhdGVtZW50cwoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tbm8tY3JlYXRlLWluZm89dHJ1ZSAtLXRhYmxlcz13cF9wb3N0cyAtLXdoZXJlPSJJRCBpbiAoMTAwLDEwMSwxMDIpIgoJICogICAgIFN1Y2Nlc3M6IEV4cG9ydGVkIHRvICd3b3JkcHJlc3NfZGJhc2UtZGI3MmJiNS5zcWwnLgoJICoKCSAqICAgICAjIEV4cG9ydCByZWxhdGluZyBtZXRhIGZvciBjZXJ0YWluIHBvc3RzIHdpdGhvdXQgY3JlYXRlIHRhYmxlIHN0YXRlbWVudHMKCSAqICAgICAkIHdwIGRiIGV4cG9ydCAtLW5vLWNyZWF0ZS1pbmZvPXRydWUgLS10YWJsZXM9d3BfcG9zdG1ldGEgLS13aGVyZT0icG9zdF9pZCBpbiAoMTAwLDEwMSwxMDIpIgoJICogICAgIFN1Y2Nlc3M6IEV4cG9ydGVkIHRvICd3b3JkcHJlc3NfZGJhc2UtZGI3MmJiNS5zcWwnLgoJICoKCSAqICAgICAjIFNraXAgY2VydGFpbiB0YWJsZXMgZnJvbSB0aGUgZXhwb3J0ZWQgZGF0YWJhc2UKCSAqICAgICAkIHdwIGRiIGV4cG9ydCAtLWV4Y2x1ZGVfdGFibGVzPXdwX29wdGlvbnMsd3BfdXNlcnMKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byAnd29yZHByZXNzX2RiYXNlLWRiNzJiYjUuc3FsJy4KCSAqCgkgKiAgICAgIyBTa2lwIGFsbCB0YWJsZXMgbWF0Y2hpbmcgYSB3aWxkY2FyZCBmcm9tIHRoZSBleHBvcnRlZCBkYXRhYmFzZQoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tZXhjbHVkZV90YWJsZXM9JCh3cCBkYiB0YWJsZXMgJ3dwX3VzZXIqJyAtLWZvcm1hdD1jc3YpCgkgKiAgICAgU3VjY2VzczogRXhwb3J0ZWQgdG8gJ3dvcmRwcmVzc19kYmFzZS1kYjcyYmI1LnNxbCcuCgkgKgoJICogICAgICMgU2tpcCBhbGwgdGFibGVzIG1hdGNoaW5nIHByZWZpeCBmcm9tIHRoZSBleHBvcnRlZCBkYXRhYmFzZQoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tZXhjbHVkZV90YWJsZXM9JCh3cCBkYiB0YWJsZXMgLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4IC0tZm9ybWF0PWNzdikKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byAnd29yZHByZXNzX2RiYXNlLWRiNzJiYjUuc3FsJy4KCSAqCgkgKiAgICAgIyBFeHBvcnQgZGF0YWJhc2UgdG8gU1RET1VULgoJICogICAgICQgd3AgZGIgZXhwb3J0IC0KCSAqICAgICAtLSBNeVNRTCBkdW1wIDEwLjEzICBEaXN0cmliIDUuNy4xOSwgZm9yIG9zeDEwLjEyICh4ODZfNjQpCgkgKiAgICAgLS0KCSAqICAgICAtLSBIb3N0OiBsb2NhbGhvc3QgICAgRGF0YWJhc2U6IHdwZGV2CgkgKiAgICAgLS0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkgKiAgICAgLS0gU2VydmVyIHZlcnNpb24gICAgNS43LjE5CgkgKiAgICAgLi4uCgkgKgoJICogQGFsaWFzIGR1bXAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4cG9ydCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggISBlbXB0eSggJGFyZ3NbMF0gKSApIHsKCQkJJHJlc3VsdF9maWxlID0gJGFyZ3NbMF07CgkJfSBlbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5yYW5kX210X3JhbmQgLS0gV29yZFByZXNzIGlzIG5vdCBsb2FkZWQuCgkJCSRoYXNoICAgICAgICA9IHN1YnN0ciggbWQ1KCBtdF9yYW5kKCkgKSwgMCwgNyApOwoJCQkkcmVzdWx0X2ZpbGUgPSBzcHJpbnRmKCAnJXMtJXMtJXMuc3FsJywgREJfTkFNRSwgZGF0ZSggJ1ktbS1kJyApLCAkaGFzaCApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgoJCX0KCQkkc3Rkb3V0ICAgID0gKCAnLScgPT09ICRyZXN1bHRfZmlsZSApOwoJCSRwb3JjZWxhaW4gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICk7CgoJCS8vIEJhaWwgaWYgYm90aCBwb3JjZWxhaW4gYW5kIFNURE9VVCBhcmUgc2V0LgoJCWlmICggJHN0ZG91dCAmJiAkcG9yY2VsYWluICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUG9yY2VsYWluIGlzIG5vdCBhbGxvd2VkIHdoZW4gb3V0cHV0IG1vZGUgaXMgU1RET1VULicgKTsKCQl9CgoJCWlmICggISAkc3Rkb3V0ICkgewoJCQkkYXNzb2NfYXJnc1sncmVzdWx0LWZpbGUnXSA9ICRyZXN1bHRfZmlsZTsKCQl9CgoJCSRteXNxbGR1bXBfYmluYXJ5ID0gVXRpbHNcZm9yY2VfZW52X29uX25peF9zeXN0ZW1zKCAnbXlzcWxkdW1wJyApOwoKCQkkc3VwcG9ydF9jb2x1bW5fc3RhdGlzdGljcyA9IGV4ZWMoICRteXNxbGR1bXBfYmluYXJ5IC4gJyAtLWhlbHAgfCBncmVwICJjb2x1bW4tc3RhdGlzdGljcyInICk7CgoJCS8qCgkJICogSW4gY2FzZSB0aGF0IGAtLWRlZmF1bHQtY2hhcmFjdGVyLXNldGAgaXMgbm90IGdpdmVuIGFuZCBgREJfQ0hBUlNFVGAgaXMgYHV0ZjhgLAoJCSAqIHdlIHRyeSB0byBkZWR1Y2Ugd2hhdCB0aGUgYWN0dWFsIGNoYXJhY3RlciBzZXQgZm9yIHRoZSBwb3N0cyB0YWJsZSBvZiB0aGUKCQkgKiBjdXJyZW50IGRhdGFiYXNlIGlzIGFuZCB1c2UgYHV0ZjhtYjRgIGFzIGEgYGRlZmF1bHQtY2hhcmFjdGVyLXNldGAgaWYgdGhhdAoJCSAqIHNlZW1zIGxpa2UgdGhlIHNhZmVyIGRlZmF1bHQsIHRvIGVuc3VyZSBlbW9qaXMgYXJlIGVuY29kZWQgY29ycmVjdGx5LgoJCSAqLwoJCWlmICgKCQkJISBpc3NldCggJGFzc29jX2FyZ3NbJ2RlZmF1bHQtY2hhcmFjdGVyLXNldCddICkKCQkJJiYKCQkJKCBkZWZpbmVkKCAnREJfQ0hBUlNFVCcgKSAmJiBzZWxmOjpFTkNPRElOR19VVEY4ID09PSBjb25zdGFudCggJ0RCX0NIQVJTRVQnICkgKQoJCQkmJgoJCQlzZWxmOjpFTkNPRElOR19VVEY4TUI0ID09PSAkdGhpcy0+Z2V0X3Bvc3RzX3RhYmxlX2NoYXJzZXQoICRhc3NvY19hcmdzICkKCQkpIHsKCQkJV1BfQ0xJOjpkZWJ1ZyggJ1NldHRpbmcgbWlzc2luZyBkZWZhdWx0IGNoYXJhY3RlciBzZXQgdG8gJyAuIHNlbGY6OkVOQ09ESU5HX1VURjhNQjQsICdkYicgKTsKCQkJJGFzc29jX2FyZ3NbJ2RlZmF1bHQtY2hhcmFjdGVyLXNldCddID0gc2VsZjo6RU5DT0RJTkdfVVRGOE1CNDsKCQl9CgoJCSRpbml0aWFsX2NvbW1hbmQgPSBzcHJpbnRmKCAieyRteXNxbGR1bXBfYmluYXJ5fSVzICIsICR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICkgKTsKCQlXUF9DTEk6OmRlYnVnKCAiUnVubmluZyBpbml0aWFsIHNoZWxsIGNvbW1hbmQ6IHskaW5pdGlhbF9jb21tYW5kfSIsICdkYicgKTsKCgkJJGRlZmF1bHRfYXJndW1lbnRzID0gWyAnJXMnIF07CgoJCWlmICggJHN1cHBvcnRfY29sdW1uX3N0YXRpc3RpY3MgKSB7CgkJCSRkZWZhdWx0X2FyZ3VtZW50c1tdID0gJy0tc2tpcC1jb2x1bW4tc3RhdGlzdGljcyc7CgkJfQoKCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5jbHVkZS10YWJsZXNwYWNlcycsIGZhbHNlICkgKSB7CgkJCSRkZWZhdWx0X2FyZ3VtZW50c1tdID0gJy0tbm8tdGFibGVzcGFjZXMnOwoJCX0KCgkJJGNvbW1hbmQgPSAkaW5pdGlhbF9jb21tYW5kIC4gaW1wbG9kZSggJyAnLCAkZGVmYXVsdF9hcmd1bWVudHMgKTsKCgkJJGNvbW1hbmRfZXNjX2FyZ3MgPSBbIERCX05BTUUgXTsKCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3RhYmxlcyddICkgKSB7CgkJCSR0YWJsZXMgPSBleHBsb2RlKCAnLCcsIHRyaW0oICRhc3NvY19hcmdzWyd0YWJsZXMnXSwgJywnICkgKTsKCQkJdW5zZXQoICRhc3NvY19hcmdzWyd0YWJsZXMnXSApOwoJCQkkY29tbWFuZCAuPSAnIC0tdGFibGVzJzsKCQkJZm9yZWFjaCAoICR0YWJsZXMgYXMgJHRhYmxlICkgewoJCQkJJGNvbW1hbmQgICAgICAgICAgIC49ICcgJXMnOwoJCQkJJGNvbW1hbmRfZXNjX2FyZ3NbXSA9IHRyaW0oICR0YWJsZSApOwoJCQl9CgkJfQoKCQkkZXhjbHVkZV90YWJsZXMgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdleGNsdWRlX3RhYmxlcycgKTsKCQlpZiAoIGlzc2V0KCAkZXhjbHVkZV90YWJsZXMgKSApIHsKCQkJJHRhYmxlcyA9IGV4cGxvZGUoICcsJywgdHJpbSggJGFzc29jX2FyZ3NbJ2V4Y2x1ZGVfdGFibGVzJ10sICcsJyApICk7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snZXhjbHVkZV90YWJsZXMnXSApOwoJCQlmb3JlYWNoICggJHRhYmxlcyBhcyAkdGFibGUgKSB7CgkJCQkkY29tbWFuZCAgICAgICAgICAgLj0gJyAtLWlnbm9yZS10YWJsZSc7CgkJCQkkY29tbWFuZCAgICAgICAgICAgLj0gJyAlcyc7CgkJCQkkY29tbWFuZF9lc2NfYXJnc1tdID0gdHJpbSggREJfTkFNRSAuICcuJyAuICR0YWJsZSApOwoJCQl9CgkJfQoKCQkkZXNjYXBlZF9jb21tYW5kID0gY2FsbF91c2VyX2Z1bmNfYXJyYXkoICdcV1BfQ0xJXFV0aWxzXGVzY19jbWQnLCBhcnJheV9tZXJnZSggWyAkY29tbWFuZCBdLCAkY29tbWFuZF9lc2NfYXJncyApICk7CgoJCS8vIFJlbW92ZSBwYXJhbWV0ZXJzIG5vdCBuZWVkZWQgZm9yIFNRTCBydW4uCgkJdW5zZXQoICRhc3NvY19hcmdzWydwb3JjZWxhaW4nXSApOwoKCQlXUF9DTEk6OmRlYnVnKCAnQXNzb2NpYXRpdmUgYXJndW1lbnRzOiAnIC4ganNvbl9lbmNvZGUoICRhc3NvY19hcmdzICksICdkYicgKTsKCQlzZWxmOjpydW4oICRlc2NhcGVkX2NvbW1hbmQsICRhc3NvY19hcmdzICk7CgoJCWlmICggJHBvcmNlbGFpbiApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkcmVzdWx0X2ZpbGUgKTsKCQl9IGVsc2VpZiAoICEgJHN0ZG91dCApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAiRXhwb3J0ZWQgdG8gJyVzJy4iLCAkcmVzdWx0X2ZpbGUgKSApOwoJCX0KCX0KCgkvKioKCSAqIEdldCB0aGUgY3VycmVudCBjaGFyYWN0ZXIgc2V0IG9mIHRoZSBwb3N0cyB0YWJsZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgQXNzb2NpYXRpdmUgYXJyYXkgb2YgYXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICogQHJldHVybiBzdHJpbmcgUG9zdHMgdGFibGUgY2hhcmFjdGVyIHNldC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcG9zdHNfdGFibGVfY2hhcnNldCggJGFzc29jX2FyZ3MgKSB7CgkJJHF1ZXJ5ID0gJ1NFTEVDVCBDQ1NBLmNoYXJhY3Rlcl9zZXRfbmFtZSAnCgkJCQkuICdGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5gVEFCTEVTYCBULCAnCgkJCQkuICdpbmZvcm1hdGlvbl9zY2hlbWEuYENPTExBVElPTl9DSEFSQUNURVJfU0VUX0FQUExJQ0FCSUxJVFlgIENDU0EgJwoJCQkJLiAnV0hFUkUgQ0NTQS5jb2xsYXRpb25fbmFtZSA9IFQudGFibGVfY29sbGF0aW9uICcKCQkJCS4gJ0FORCBULnRhYmxlX3NjaGVtYSA9ICInIC4gREJfTkFNRSAuICciICcKCQkJCS4gJ0FORCBULnRhYmxlX25hbWUgTElLRSAiJVxfcG9zdHMiOyc7CgoJCWxpc3QoICRzdGRvdXQsICRzdGRlcnIsICRleGl0X2NvZGUgKSA9IHNlbGY6OnJ1bigKCQkJc3ByaW50ZigKCQkJCScvdXNyL2Jpbi9lbnYgbXlzcWwlcyAtLW5vLWF1dG8tcmVoYXNoIC0tYmF0Y2ggLS1za2lwLWNvbHVtbi1uYW1lcycsCgkJCQkkdGhpcy0+Z2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAkYXNzb2NfYXJncyApCgkJCSksCgkJCVsgJ2V4ZWN1dGUnID0+ICRxdWVyeSBdLAoJCQlmYWxzZQoJCSk7CgoJCWlmICggJGV4aXRfY29kZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJJ0ZhaWxlZCB0byBnZXQgY3VycmVudCBjaGFyYWN0ZXIgc2V0IG9mIHRoZSBwb3N0cyB0YWJsZS4nCgkJCQkuICggISBlbXB0eSggJHN0ZGVyciApID8gIiBSZWFzb246IHskc3RkZXJyfSIgOiAnJyApCgkJCSk7CgoJCQlyZXR1cm4gc2VsZjo6RU5DT0RJTkdfVVRGOE1CNDsKCQl9CgoJCSRzdGRvdXQgPSB0cmltKCAkc3Rkb3V0ICk7CgoJCVdQX0NMSTo6ZGVidWcoICJEZXRlY3RlZCBjaGFyYWN0ZXIgc2V0IG9mIHRoZSBwb3N0cyB0YWJsZTogeyRzdGRvdXR9LiIsICdkYicgKTsKCgkJcmV0dXJuICRzdGRvdXQ7Cgl9CgoJLyoqCgkgKiBJbXBvcnRzIGEgZGF0YWJhc2UgZnJvbSBhIGZpbGUgb3IgZnJvbSBTVERJTi4KCSAqCgkgKiBSdW5zIFNRTCBxdWVyaWVzIHVzaW5nIGBEQl9IT1NUYCwgYERCX05BTUVgLCBgREJfVVNFUmAgYW5kCgkgKiBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLiBUaGlzCgkgKiBkb2VzIG5vdCBjcmVhdGUgZGF0YWJhc2UgYnkgaXRzZWxmIGFuZCBvbmx5IHBlcmZvcm1zIHdoYXRldmVyIHRhc2tzIGFyZQoJICogZGVmaW5lZCBpbiB0aGUgU1FMLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGZpbGU+XQoJICogOiBUaGUgbmFtZSBvZiB0aGUgU1FMIGZpbGUgdG8gaW1wb3J0LiBJZiAnLScsIHRoZW4gcmVhZHMgZnJvbSBTVERJTi4gSWYgb21pdHRlZCwgaXQgd2lsbCBsb29rIGZvciAne2RibmFtZX0uc3FsJy4KCSAqCgkgKiBbLS1kYnVzZXI9PHZhbHVlPl0KCSAqIDogVXNlcm5hbWUgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byBteXNxbC4gW1JlZmVyIHRvIG15c3FsIGJpbmFyeSBkb2NzXShodHRwczovL2Rldi5teXNxbC5jb20vZG9jL3JlZm1hbi84LjAvZW4vbXlzcWwtY29tbWFuZC1vcHRpb25zLmh0bWwpLgoJICoKCSAqIFstLXNraXAtb3B0aW1pemF0aW9uXQoJICogOiBXaGVuIHVzaW5nIGFuIFNRTCBmaWxlLCBkbyBub3QgaW5jbHVkZSBzcGVlZCBvcHRpbWl6YXRpb24gc3VjaCBhcyBkaXNhYmxpbmcgYXV0by1jb21taXQgYW5kIGtleSBjaGVja3MuCgkgKgoJICogWy0tZGVmYXVsdHNdCgkgKiA6IExvYWRzIHRoZSBlbnZpcm9ubWVudCdzIE15U1FMIG9wdGlvbiBmaWxlcy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byBza2lwIGxvYWRpbmcgdGhlbSB0byBhdm9pZCBmYWlsdXJlcyBkdWUgdG8gbWlzY29uZmlndXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEltcG9ydCBNeVNRTCBmcm9tIGEgZmlsZS4KCSAqICAgICAkIHdwIGRiIGltcG9ydCB3b3JkcHJlc3NfZGJhc2Uuc3FsCgkgKiAgICAgU3VjY2VzczogSW1wb3J0ZWQgZnJvbSAnd29yZHByZXNzX2RiYXNlLnNxbCcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbXBvcnQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICEgZW1wdHkoICRhcmdzWzBdICkgKSB7CgkJCSRyZXN1bHRfZmlsZSA9ICRhcmdzWzBdOwoJCX0gZWxzZSB7CgkJCSRyZXN1bHRfZmlsZSA9IHNwcmludGYoICclcy5zcWwnLCBEQl9OQU1FICk7CgkJfQoKCQkvLyBQcm9jZXNzIG9wdGlvbnMgdG8gTXlTUUwuCgkJJG15c3FsX2FyZ3MgPSBhcnJheV9tZXJnZSgKCQkJWyAnZGF0YWJhc2UnID0+IERCX05BTUUgXSwKCQkJc2VsZjo6Z2V0X2RidXNlcl9kYnBhc3NfYXJncyggJGFzc29jX2FyZ3MgKSwKCQkJc2VsZjo6Z2V0X215c3FsX2FyZ3MoICRhc3NvY19hcmdzICkKCQkpOwoKCQlpZiAoICctJyAhPT0gJHJlc3VsdF9maWxlICkgewoJCQlpZiAoICEgaXNfcmVhZGFibGUoICRyZXN1bHRfZmlsZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0ltcG9ydCBmaWxlIG1pc3Npbmcgb3Igbm90IHJlYWRhYmxlOiAlcycsICRyZXN1bHRfZmlsZSApICk7CgkJCX0KCgkJCSRxdWVyeSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtb3B0aW1pemF0aW9uJyApCgkJCQk/ICdTT1VSQ0UgJXM7JwoJCQkJOiAnU0VUIGF1dG9jb21taXQgPSAwOyBTRVQgdW5pcXVlX2NoZWNrcyA9IDA7IFNFVCBmb3JlaWduX2tleV9jaGVja3MgPSAwOyBTT1VSQ0UgJXM7IENPTU1JVDsnOwoKCQkJJHF1ZXJ5ID0gJHRoaXMtPmdldF9zcWxfbW9kZV9xdWVyeSggJGFzc29jX2FyZ3MgKSAuICRxdWVyeTsKCgkJCSRteXNxbF9hcmdzWydleGVjdXRlJ10gPSBzcHJpbnRmKCAkcXVlcnksICRyZXN1bHRfZmlsZSApOwoJCX0gZWxzZSB7CgkJCSRyZXN1bHRfZmlsZSA9ICdTVERJTic7CgkJfQoKCQkkY29tbWFuZCA9IHNwcmludGYoICcvdXNyL2Jpbi9lbnYgbXlzcWwlcyAtLW5vLWF1dG8tcmVoYXNoJywgJHRoaXMtPmdldF9kZWZhdWx0c19mbGFnX3N0cmluZyggJGFzc29jX2FyZ3MgKSApOwoJCVdQX0NMSTo6ZGVidWcoICJSdW5uaW5nIHNoZWxsIGNvbW1hbmQ6IHskY29tbWFuZH0iLCAnZGInICk7CgkJV1BfQ0xJOjpkZWJ1ZyggJ0Fzc29jaWF0aXZlIGFyZ3VtZW50czogJyAuIGpzb25fZW5jb2RlKCAkYXNzb2NfYXJncyApLCAnZGInICk7CgoJCXNlbGY6OnJ1biggJGNvbW1hbmQsICRteXNxbF9hcmdzICk7CgoJCVdQX0NMSTo6c3VjY2Vzcyggc3ByaW50ZiggIkltcG9ydGVkIGZyb20gJyVzJy4iLCAkcmVzdWx0X2ZpbGUgKSApOwoJfQoKCS8qKgoJICogTGlzdHMgdGhlIGRhdGFiYXNlIHRhYmxlcy4KCSAqCgkgKiBEZWZhdWx0cyB0byBhbGwgdGFibGVzIHJlZ2lzdGVyZWQgdG8gdGhlICR3cGRiIGRhdGFiYXNlIGhhbmRsZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGFibGU+Li4uXQoJICogOiBMaXN0IHRhYmxlcyBiYXNlZCBvbiB3aWxkY2FyZCBzZWFyY2gsIGUuZy4gJ3dwXypfb3B0aW9ucycgb3IgJ3dwX3Bvc3Q/Jy4KCSAqCgkgKiBbLS1zY29wZT08c2NvcGU+XQoJICogOiBDYW4gYmUgYWxsLCBnbG9iYWwsIG1zX2dsb2JhbCwgYmxvZywgb3Igb2xkIHRhYmxlcy4gRGVmYXVsdHMgdG8gYWxsLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IExpc3QgYWxsIHRoZSB0YWJsZXMgaW4gYSBtdWx0aXNpdGUgaW5zdGFsbC4KCSAqCgkgKiBbLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4XQoJICogOiBMaXN0IGFsbCB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgdGFibGUgcHJlZml4IGV2ZW4gaWYgbm90IHJlZ2lzdGVyZWQgb24gJHdwZGIuIE92ZXJyaWRlcyAtLW5ldHdvcmsuCgkgKgoJICogWy0tYWxsLXRhYmxlc10KCSAqIDogTGlzdCBhbGwgdGFibGVzIGluIHRoZSBkYXRhYmFzZSwgcmVnYXJkbGVzcyBvZiB0aGUgcHJlZml4LCBhbmQgZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCBvbiAkd3BkYi4gT3ZlcnJpZGVzIC0tYWxsLXRhYmxlcy13aXRoLXByZWZpeC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogbGlzdAoJICogb3B0aW9uczoKCSAqICAgLSBsaXN0CgkgKiAgIC0gY3N2CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdGFibGVzIGZvciBhIHNpbmdsZSBzaXRlLCB3aXRob3V0IHNoYXJlZCB0YWJsZXMgbGlrZSAnd3BfdXNlcnMnCgkgKiAgICAgJCB3cCBkYiB0YWJsZXMgLS1zY29wZT1ibG9nIC0tdXJsPXN1Yi5leGFtcGxlLmNvbQoJICogICAgIHdwXzNfcG9zdHMKCSAqICAgICB3cF8zX2NvbW1lbnRzCgkgKiAgICAgd3BfM19vcHRpb25zCgkgKiAgICAgd3BfM19wb3N0bWV0YQoJICogICAgIHdwXzNfdGVybXMKCSAqICAgICB3cF8zX3Rlcm1fdGF4b25vbXkKCSAqICAgICB3cF8zX3Rlcm1fcmVsYXRpb25zaGlwcwoJICogICAgIHdwXzNfdGVybW1ldGEKCSAqICAgICB3cF8zX2NvbW1lbnRtZXRhCgkgKgoJICogICAgICMgRXhwb3J0IG9ubHkgdGFibGVzIGZvciBhIHNpbmdsZSBzaXRlCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS10YWJsZXM9JCh3cCBkYiB0YWJsZXMgLS11cmw9c3ViLmV4YW1wbGUuY29tIC0tZm9ybWF0PWNzdikKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byB3b3JkcHJlc3NfZGJhc2Uuc3FsCgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gdGFibGVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRmb3JtYXQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICk7CgkJdW5zZXQoICRhc3NvY19hcmdzWydmb3JtYXQnXSApOwoKCQlpZiAoIGVtcHR5KCAkYXJncyApICYmIGVtcHR5KCAkYXNzb2NfYXJncyApICkgewoJCQkkYXNzb2NfYXJnc1snc2NvcGUnXSA9ICdhbGwnOwoJCX0KCgkJJHRhYmxlcyA9IFV0aWxzXHdwX2dldF90YWJsZV9uYW1lcyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgoJCWlmICggJ2NzdicgPT09ICRmb3JtYXQgKSB7CgkJCVdQX0NMSTo6bGluZSggaW1wbG9kZSggJywnLCAkdGFibGVzICkgKTsKCQl9IGVsc2UgewoJCQlmb3JlYWNoICggJHRhYmxlcyBhcyAkdGFibGUgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICR0YWJsZSApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogRGlzcGxheXMgdGhlIGRhdGFiYXNlIG5hbWUgYW5kIHNpemUuCgkgKgoJICogRGlzcGxheSB0aGUgZGF0YWJhc2UgbmFtZSBhbmQgc2l6ZSBmb3IgYERCX05BTUVgIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLgoJICogVGhlIHNpemUgZGVmYXVsdHMgdG8gYSBodW1hbi1yZWFkYWJsZSBudW1iZXIuCgkgKgoJICogQXZhaWxhYmxlIHNpemUgZm9ybWF0cyBpbmNsdWRlOgoJICogKiBiIChieXRlcykKCSAqICoga2IgKGtpbG9ieXRlcykKCSAqICogbWIgKG1lZ2FieXRlcykKCSAqICogZ2IgKGdpZ2FieXRlcykKCSAqICogdGIgKHRlcmFieXRlcykKCSAqICogQiAgIChJU08gQnl0ZSBzZXR0aW5nLCB3aXRoIG5vIGNvbnZlcnNpb24pCgkgKiAqIEtCICAoSVNPIEtpbG9ieXRlIHNldHRpbmcsIHdpdGggMSBLQiAgPSAxLDAwMCBCKQoJICogKiBLaUIgKElTTyBLaWJpYnl0ZSBzZXR0aW5nLCB3aXRoIDEgS2lCID0gMSwwMjQgQikKCSAqICogTUIgIChJU08gTWVnYWJ5dGUgc2V0dGluZywgd2l0aCAxIE1CICA9IDEsMDAwIEtCKQoJICogKiBNaUIgKElTTyBNZWJpYnl0ZSBzZXR0aW5nLCB3aXRoIDEgTWlCID0gMSwwMjQgS2lCKQoJICogKiBHQiAgKElTTyBHaWdhYnl0ZSBzZXR0aW5nLCB3aXRoIDEgR0IgID0gMSwwMDAgTUIpCgkgKiAqIEdpQiAoSVNPIEdpYmlieXRlIHNldHRpbmcsIHdpdGggMSBHaUIgPSAxLDAyNCBNaUIpCgkgKiAqIFRCICAoSVNPIFRlcmFieXRlIHNldHRpbmcsIHdpdGggMSBUQiAgPSAxLDAwMCBHQikKCSAqICogVGlCIChJU08gVGViaWJ5dGUgc2V0dGluZywgd2l0aCAxIFRpQiA9IDEsMDI0IEdpQikKCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tc2l6ZV9mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IERpc3BsYXkgdGhlIGRhdGFiYXNlIHNpemUgb25seSwgYXMgYSBiYXJlIG51bWJlci4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBiCgkgKiAgIC0ga2IKCSAqICAgLSBtYgoJICogICAtIGdiCgkgKiAgIC0gdGIKCSAqICAgLSBCCgkgKiAgIC0gS0IKCSAqICAgLSBLaUIKCSAqICAgLSBNQgoJICogICAtIE1pQgoJICogICAtIEdCCgkgKiAgIC0gR2lCCgkgKiAgIC0gVEIKCSAqICAgLSBUaUIKCSAqIC0tLQoJICoKCSAqIFstLXRhYmxlc10KCSAqIDogRGlzcGxheSBlYWNoIHRhYmxlIG5hbWUgYW5kIHNpemUgaW5zdGVhZCBvZiB0aGUgZGF0YWJhc2Ugc2l6ZS4KCSAqCgkgKiBbLS1odW1hbi1yZWFkYWJsZV0KCSAqIDogRGlzcGxheSBkYXRhYmFzZSBzaXplcyBpbiBodW1hbiByZWFkYWJsZSBmb3JtYXRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqIFstLXNjb3BlPTxzY29wZT5dCgkgKiA6IENhbiBiZSBhbGwsIGdsb2JhbCwgbXNfZ2xvYmFsLCBibG9nLCBvciBvbGQgdGFibGVzLiBEZWZhdWx0cyB0byBhbGwuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogTGlzdCBhbGwgdGhlIHRhYmxlcyBpbiBhIG11bHRpc2l0ZSBpbnN0YWxsLgoJICoKCSAqIFstLWRlY2ltYWxzPTxkZWNpbWFscz5dCgkgKiA6IE51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgZGVjaW1hbCBwb2ludC4gRGVmYXVsdHMgdG8gMC4KCSAqCgkgKiBbLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4XQoJICogOiBMaXN0IGFsbCB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgdGFibGUgcHJlZml4IGV2ZW4gaWYgbm90IHJlZ2lzdGVyZWQgb24gJHdwZGIuIE92ZXJyaWRlcyAtLW5ldHdvcmsuCgkgKgoJICogWy0tYWxsLXRhYmxlc10KCSAqIDogTGlzdCBhbGwgdGFibGVzIGluIHRoZSBkYXRhYmFzZSwgcmVnYXJkbGVzcyBvZiB0aGUgcHJlZml4LCBhbmQgZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCBvbiAkd3BkYi4gT3ZlcnJpZGVzIC0tYWxsLXRhYmxlcy13aXRoLXByZWZpeC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIHNpemUKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0rCgkgKiAgICAgfCBOYW1lICAgICAgICAgICAgICB8IFNpemUgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLSsKCSAqICAgICB8IHdvcmRwcmVzc19kZWZhdWx0IHwgNiBNQiB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tKwoJICoKCSAqICAgICAkIHdwIGRiIHNpemUgLS10YWJsZXMKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqICAgICB8IE5hbWUgICAgICAgICAgICAgICAgICB8IFNpemUgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqICAgICB8IHdwX3VzZXJzICAgICAgICAgICAgICB8IDY0IEtCIHwKCSAqICAgICB8IHdwX3VzZXJtZXRhICAgICAgICAgICB8IDQ4IEtCIHwKCSAqICAgICB8IHdwX3Bvc3RzICAgICAgICAgICAgICB8IDgwIEtCIHwKCSAqICAgICB8IHdwX2NvbW1lbnRzICAgICAgICAgICB8IDk2IEtCIHwKCSAqICAgICB8IHdwX2xpbmtzICAgICAgICAgICAgICB8IDMyIEtCIHwKCSAqICAgICB8IHdwX29wdGlvbnMgICAgICAgICAgICB8IDMyIEtCIHwKCSAqICAgICB8IHdwX3Bvc3RtZXRhICAgICAgICAgICB8IDQ4IEtCIHwKCSAqICAgICB8IHdwX3Rlcm1zICAgICAgICAgICAgICB8IDQ4IEtCIHwKCSAqICAgICB8IHdwX3Rlcm1fdGF4b25vbXkgICAgICB8IDQ4IEtCIHwKCSAqICAgICB8IHdwX3Rlcm1fcmVsYXRpb25zaGlwcyB8IDMyIEtCIHwKCSAqICAgICB8IHdwX3Rlcm1tZXRhICAgICAgICAgICB8IDQ4IEtCIHwKCSAqICAgICB8IHdwX2NvbW1lbnRtZXRhICAgICAgICB8IDQ4IEtCIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqCgkgKiAgICAgJCB3cCBkYiBzaXplIC0tc2l6ZV9mb3JtYXQ9YgoJICogICAgIDU4NjU0NzIKCSAqCgkgKiAgICAgJCB3cCBkYiBzaXplIC0tc2l6ZV9mb3JtYXQ9a2IKCSAqICAgICA1NzI4CgkgKgoJICogICAgICQgd3AgZGIgc2l6ZSAtLXNpemVfZm9ybWF0PW1iCgkgKiAgICAgNgoJICoKCSAqIEB3aGVuIGFmdGVyX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNpemUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJZ2xvYmFsICR3cGRiOwoKCQkkZm9ybWF0ICAgICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKTsKCQkkc2l6ZV9mb3JtYXQgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NpemVfZm9ybWF0JyApOwoJCSRodW1hbl9yZWFkYWJsZSAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaHVtYW4tcmVhZGFibGUnLCBmYWxzZSApOwoJCSR0YWJsZXMgICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndGFibGVzJyApOwoJCSR0YWJsZXMgICAgICAgICAgICAgICAgID0gISBlbXB0eSggJHRhYmxlcyApOwoJCSRhbGxfdGFibGVzICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsLXRhYmxlcycgKTsKCQkkYWxsX3RhYmxlc193aXRoX3ByZWZpeCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbC10YWJsZXMtd2l0aC1wcmVmaXgnICk7CgoJCWlmICggISBpc19udWxsKCAkc2l6ZV9mb3JtYXQgKSAmJiAkaHVtYW5fcmVhZGFibGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDYW5ub3QgdXNlIC0tc2l6ZV9mb3JtYXQgYW5kIC0taHVtYW4tcmVhZGFibGUgYXJndW1lbnRzIGF0IHRoZSBzYW1lIHRpbWUuJyApOwoJCX0KCgkJdW5zZXQoICRhc3NvY19hcmdzWydmb3JtYXQnXSApOwoJCXVuc2V0KCAkYXNzb2NfYXJnc1snc2l6ZV9mb3JtYXQnXSApOwoJCXVuc2V0KCAkYXNzb2NfYXJnc1snaHVtYW4tcmVhZGFibGUnXSApOwoJCXVuc2V0KCAkYXNzb2NfYXJnc1sndGFibGVzJ10gKTsKCgkJaWYgKCBlbXB0eSggJGFyZ3MgKSAmJiBlbXB0eSggJGFzc29jX2FyZ3MgKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3Njb3BlJ10gPSAnYWxsJzsKCQl9CgoJCS8vIEJ1aWxkIHJvd3MgZm9yIHRoZSBmb3JtYXR0ZXIuCgkJJHJvd3MgICA9IFtdOwoJCSRmaWVsZHMgPSBbICdOYW1lJywgJ1NpemUnIF07CgoJCSRkZWZhdWx0X3VuaXQgPSAoIGVtcHR5KCAkc2l6ZV9mb3JtYXQgKSAmJiAhICRodW1hbl9yZWFkYWJsZSApID8gJyBCJyA6ICcnOwoKCQlpZiAoICR0YWJsZXMgfHwgJGFsbF90YWJsZXMgfHwgJGFsbF90YWJsZXNfd2l0aF9wcmVmaXggKSB7CgoJCQkvLyBBZGQgYWxsIG9mIHRoZSB0YWJsZSBzaXplcy4KCQkJZm9yZWFjaCAoIFV0aWxzXHdwX2dldF90YWJsZV9uYW1lcyggJGFyZ3MsICRhc3NvY19hcmdzICkgYXMgJHRhYmxlX25hbWUgKSB7CgoJCQkJLy8gR2V0IHRoZSB0YWJsZSBzaXplLgoJCQkJJHRhYmxlX2J5dGVzID0gJHdwZGItPmdldF92YXIoCgkJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJCSdTRUxFQ1QgU1VNKGRhdGFfbGVuZ3RoICsgaW5kZXhfbGVuZ3RoKSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgd2hlcmUgdGFibGVfc2NoZW1hID0gJXMgYW5kIFRhYmxlX05hbWUgPSAlcyBHUk9VUCBCWSBUYWJsZV9OYW1lIExJTUlUIDEnLAoJCQkJCQlEQl9OQU1FLAoJCQkJCQkkdGFibGVfbmFtZQoJCQkJCSkKCQkJCSk7CgoJCQkJLy8gQWRkIHRoZSB0YWJsZSBzaXplIHRvIHRoZSBsaXN0LgoJCQkJJHJvd3NbXSA9IFsKCQkJCQknTmFtZScgPT4gJHRhYmxlX25hbWUsCgkJCQkJJ1NpemUnID0+IHN0cnRvdXBwZXIoICR0YWJsZV9ieXRlcyApIC4gJGRlZmF1bHRfdW5pdCwKCQkJCV07CgkJCX0KCQl9IGVsc2UgewoKCQkJLy8gR2V0IHRoZSBkYXRhYmFzZSBzaXplLgoJCQkkZGJfYnl0ZXMgPSAkd3BkYi0+Z2V0X3ZhcigKCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCSdTRUxFQ1QgU1VNKGRhdGFfbGVuZ3RoICsgaW5kZXhfbGVuZ3RoKSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgd2hlcmUgdGFibGVfc2NoZW1hID0gJXMgR1JPVVAgQlkgdGFibGVfc2NoZW1hOycsCgkJCQkJREJfTkFNRQoJCQkJKQoJCQkpOwoKCQkJLy8gQWRkIHRoZSBkYXRhYmFzZSBzaXplIHRvIHRoZSBsaXN0LgoJCQkkcm93c1tdID0gWwoJCQkJJ05hbWUnID0+IERCX05BTUUsCgkJCQknU2l6ZScgPT4gc3RydG91cHBlciggJGRiX2J5dGVzICkgLiAkZGVmYXVsdF91bml0LAoJCQldOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkc2l6ZV9mb3JtYXQgKSB8fCAkaHVtYW5fcmVhZGFibGUgKSB7CgkJCWZvcmVhY2ggKCAkcm93cyBhcyAkaW5kZXggPT4gJHJvdyApIHsKCQkJCS8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIEJhY2tmaWxsaW5nIFdQIG5hdGl2ZSBjb25zdGFudHMuCgkJCQlpZiAoICEgZGVmaW5lZCggJ0tCX0lOX0JZVEVTJyApICkgewoJCQkJCWRlZmluZSggJ0tCX0lOX0JZVEVTJywgMTAyNCApOwoJCQkJfQoJCQkJaWYgKCAhIGRlZmluZWQoICdNQl9JTl9CWVRFUycgKSApIHsKCQkJCQlkZWZpbmUoICdNQl9JTl9CWVRFUycsIDEwMjQgKiBLQl9JTl9CWVRFUyApOwoJCQkJfQoJCQkJaWYgKCAhIGRlZmluZWQoICdHQl9JTl9CWVRFUycgKSApIHsKCQkJCQlkZWZpbmUoICdHQl9JTl9CWVRFUycsIDEwMjQgKiBNQl9JTl9CWVRFUyApOwoJCQkJfQoJCQkJaWYgKCAhIGRlZmluZWQoICdUQl9JTl9CWVRFUycgKSApIHsKCQkJCQlkZWZpbmUoICdUQl9JTl9CWVRFUycsIDEwMjQgKiBHQl9JTl9CWVRFUyApOwoJCQkJfQoJCQkJLy8gcGhwY3M6ZW5hYmxlCgoJCQkJaWYgKCAkaHVtYW5fcmVhZGFibGUgKSB7CgkJCQkJJHNpemVfa2V5ID0gZmxvb3IoIGxvZyggJHJvd1snU2l6ZSddICkgLyBsb2coIDEwMDAgKSApOwoJCQkJCSRzaXplcyAgICA9IFsgJ0InLCAnS0InLCAnTUInLCAnR0InLCAnVEInIF07CgoJCQkJCSRzaXplX2Zvcm1hdCA9IGlzc2V0KCAkc2l6ZXNbICRzaXplX2tleSBdICkgPyAkc2l6ZXNbICRzaXplX2tleSBdIDogJHNpemVzWzBdOwoJCQkJfQoKCQkJCS8vIERpc3BsYXkgdGhlIGRhdGFiYXNlIHNpemUgYXMgYSBudW1iZXIuCgkJCQlzd2l0Y2ggKCAkc2l6ZV9mb3JtYXQgKSB7CgkJCQkJY2FzZSAnVEInOgoJCQkJCQkkZGl2aXNvciA9IHBvdyggMTAwMCwgNCApOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnR0InOgoJCQkJCQkkZGl2aXNvciA9IHBvdyggMTAwMCwgMyApOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnTUInOgoJCQkJCQkkZGl2aXNvciA9IHBvdyggMTAwMCwgMiApOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnS0InOgoJCQkJCQkkZGl2aXNvciA9IDEwMDA7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICd0Yic6CgkJCQkJY2FzZSAnVGlCJzoKCQkJCQkJJGRpdmlzb3IgPSBUQl9JTl9CWVRFUzsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ2diJzoKCQkJCQljYXNlICdHaUInOgoJCQkJCQkkZGl2aXNvciA9IEdCX0lOX0JZVEVTOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnbWInOgoJCQkJCWNhc2UgJ01pQic6CgkJCQkJCSRkaXZpc29yID0gTUJfSU5fQllURVM7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdrYic6CgkJCQkJY2FzZSAnS2lCJzoKCQkJCQkJJGRpdmlzb3IgPSBLQl9JTl9CWVRFUzsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ2InOgoJCQkJCWNhc2UgJ0InOgoJCQkJCWRlZmF1bHQ6CgkJCQkJCSRkaXZpc29yID0gMTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCQkJJHNpemVfZm9ybWF0X2Rpc3BsYXkgPSBwcmVnX3JlcGxhY2UoICcvSUIkL3UnLCAnaUInLCBzdHJ0b3VwcGVyKCAkc2l6ZV9mb3JtYXQgKSApOwoKCQkJCQkkZGVjaW1hbHMgICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RlY2ltYWxzJywgMCApOwoJCQkJCSRyb3dzWyAkaW5kZXggXVsnU2l6ZSddID0gcm91bmQoICRyb3dbJ1NpemUnXSAvICRkaXZpc29yLCAkZGVjaW1hbHMgKSAuICcgJyAuICRzaXplX2Zvcm1hdF9kaXNwbGF5OwoJCQl9CgkJfQoKCQlpZiAoICEgZW1wdHkoICRzaXplX2Zvcm1hdCApICYmICEgJHRhYmxlcyAmJiAhICRmb3JtYXQgJiYgISAkaHVtYW5fcmVhZGFibGUgJiYgdHJ1ZSAhPT0gJGFsbF90YWJsZXMgJiYgdHJ1ZSAhPT0gJGFsbF90YWJsZXNfd2l0aF9wcmVmaXggKSB7CgkJCVdQX0NMSTo6bGluZSggc3RyX3JlcGxhY2UoICIgeyRzaXplX2Zvcm1hdF9kaXNwbGF5fSIsICcnLCAkcm93c1swXVsnU2l6ZSddICkgKTsKCQl9IGVsc2UgewoJCQkvLyBEaXNwbGF5IHRoZSByb3dzLgoJCQkkYXJncyA9IFsKCQkJCSdmb3JtYXQnID0+ICRmb3JtYXQsCgkJCV07CgoJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFyZ3MsICRmaWVsZHMgKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHJvd3MgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEaXNwbGF5cyB0aGUgZGF0YWJhc2UgdGFibGUgcHJlZml4LgoJICoKCSAqIERpc3BsYXkgdGhlIGRhdGFiYXNlIHRhYmxlIHByZWZpeCwgYXMgZGVmaW5lZCBieSB0aGUgZGF0YWJhc2UgaGFuZGxlcidzIGludGVycHJldGF0aW9uIG9mIHRoZSBjdXJyZW50IHNpdGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBkYiBwcmVmaXgKCSAqICAgICB3cF8KCSAqCgkgKiBAd2hlbiBhZnRlcl93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcmVmaXgoKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQlXUF9DTEk6OmxvZyggJHdwZGItPnByZWZpeCApOwoJfQoKCS8qKgoJICogRmluZHMgYSBzdHJpbmcgaW4gdGhlIGRhdGFiYXNlLgoJICoKCSAqIFNlYXJjaGVzIHRocm91Z2ggYWxsIG9mIHRoZSB0ZXh0IGNvbHVtbnMgaW4gYSBzZWxlY3Rpb24gb2YgZGF0YWJhc2UgdGFibGVzIGZvciBhIGdpdmVuIHN0cmluZywgT3V0cHV0cyBjb2xvcml6ZWQgcmVmZXJlbmNlcyB0byB0aGUgc3RyaW5nLgoJICoKCSAqIERlZmF1bHRzIHRvIHNlYXJjaGluZyB0aHJvdWdoIGFsbCB0YWJsZXMgcmVnaXN0ZXJlZCB0byAkd3BkYi4gT24gbXVsdGlzaXRlLCB0aGlzIGRlZmF1bHQgaXMgbGltaXRlZCB0byB0aGUgdGFibGVzIGZvciB0aGUgY3VycmVudCBzaXRlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2VhcmNoPgoJICogOiBTdHJpbmcgdG8gc2VhcmNoIGZvci4gVGhlIHNlYXJjaCBpcyBjYXNlLWluc2Vuc2l0aXZlIGJ5IGRlZmF1bHQuCgkgKgoJICogWzx0YWJsZXM+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0YWJsZXMgdG8gc2VhcmNoIHRocm91Z2ggZm9yIHRoZSBzdHJpbmcuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogU2VhcmNoIHRocm91Z2ggYWxsIHRoZSB0YWJsZXMgcmVnaXN0ZXJlZCB0byAkd3BkYiBpbiBhIG11bHRpc2l0ZSBpbnN0YWxsLgoJICoKCSAqIFstLWFsbC10YWJsZXMtd2l0aC1wcmVmaXhdCgkgKiA6IFNlYXJjaCB0aHJvdWdoIGFsbCB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgcmVnaXN0ZXJlZCB0YWJsZSBwcmVmaXgsIGV2ZW4gaWYgbm90IHJlZ2lzdGVyZWQgb24gJHdwZGIuIE9uIG9uZSBoYW5kLCBzb21ldGltZXMgcGx1Z2lucyB1c2UgdGFibGVzIHdpdGhvdXQgcmVnaXN0ZXJpbmcgdGhlbSB0byAkd3BkYi4gT24gYW5vdGhlciBoYW5kLCB0aGlzIGNvdWxkIHJldHVybiB0YWJsZXMgeW91IGRvbid0IGV4cGVjdC4gT3ZlcnJpZGVzIC0tbmV0d29yay4KCSAqCgkgKiBbLS1hbGwtdGFibGVzXQoJICogOiBTZWFyY2ggdGhyb3VnaCBBTEwgdGFibGVzIGluIHRoZSBkYXRhYmFzZSwgcmVnYXJkbGVzcyBvZiB0aGUgcHJlZml4LCBhbmQgZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCBvbiAkd3BkYi4gT3ZlcnJpZGVzIC0tbmV0d29yayBhbmQgLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4LgoJICoKCSAqIFstLWJlZm9yZV9jb250ZXh0PTxudW0+XQoJICogOiBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBkaXNwbGF5IGJlZm9yZSB0aGUgbWF0Y2guCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDQwCgkgKiAtLS0KCSAqCgkgKiBbLS1hZnRlcl9jb250ZXh0PTxudW0+XQoJICogOiBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBkaXNwbGF5IGFmdGVyIHRoZSBtYXRjaC4KCSAqIC0tLQoJICogZGVmYXVsdDogNDAKCSAqIC0tLQoJICoKCSAqIFstLXJlZ2V4XQoJICogOiBSdW5zIHRoZSBzZWFyY2ggYXMgYSByZWd1bGFyIGV4cHJlc3Npb24gKHdpdGhvdXQgZGVsaW1pdGVycykuIFRoZSBzZWFyY2ggYmVjb21lcyBjYXNlLXNlbnNpdGl2ZSAoaS5lLiBubyBQQ1JFIGZsYWdzIGFyZSBhZGRlZCkuIERlbGltaXRlcnMgbXVzdCBiZSBlc2NhcGVkIGlmIHRoZXkgb2NjdXIgaW4gdGhlIGV4cHJlc3Npb24uIEJlY2F1c2UgdGhlIHNlYXJjaCBpcyBydW4gb24gaW5kaXZpZHVhbCBjb2x1bW5zLCB5b3UgY2FuIHVzZSB0aGUgYF5gIGFuZCBgJGAgdG9rZW5zIHRvIG1hcmsgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgYSBtYXRjaCwgcmVzcGVjdGl2ZWx5LgoJICoKCSAqIFstLXJlZ2V4LWZsYWdzPTxyZWdleC1mbGFncz5dCgkgKiA6IFBhc3MgUENSRSBtb2RpZmllcnMgdG8gdGhlIHJlZ2V4IHNlYXJjaCAoZS5nLiAnaScgZm9yIGNhc2UtaW5zZW5zaXRpdml0eSkuCgkgKgoJICogWy0tcmVnZXgtZGVsaW1pdGVyPTxyZWdleC1kZWxpbWl0ZXI+XQoJICogOiBUaGUgZGVsaW1pdGVyIHRvIHVzZSBmb3IgdGhlIHJlZ2V4LiBJdCBtdXN0IGJlIGVzY2FwZWQgaWYgaXQgYXBwZWFycyBpbiB0aGUgc2VhcmNoIHN0cmluZy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlIHJlc3VsdCBvZiBgY2hyKDEpYC4KCSAqCgkgKiBbLS10YWJsZV9jb2x1bW5fb25jZV0KCSAqIDogT3V0cHV0IHRoZSAndGFibGU6Y29sdW1uJyBsaW5lIG9uY2UgYmVmb3JlIGFsbCBtYXRjaGluZyByb3cgbGluZXMgaW4gdGhlIHRhYmxlIGNvbHVtbiByYXRoZXIgdGhhbiBiZWZvcmUgZWFjaCBtYXRjaGluZyByb3cuCgkgKgoJICogWy0tb25lX2xpbmVdCgkgKiA6IFBsYWNlIHRoZSAndGFibGU6Y29sdW1uJyBvdXRwdXQgb24gdGhlIHNhbWUgbGluZSBhcyB0aGUgcm93IGlkIGFuZCBtYXRjaCAoJ3RhYmxlOmNvbHVtbjppZDptYXRjaCcpLiBPdmVycmlkZXMgLS10YWJsZV9jb2x1bW5fb25jZS4KCSAqCgkgKiBbLS1tYXRjaGVzX29ubHldCgkgKiA6IE9ubHkgb3V0cHV0IHRoZSBzdHJpbmcgbWF0Y2hlcyAoaW5jbHVkaW5nIGNvbnRleHQpLiBObyAndGFibGU6Y29sdW1uJ3Mgb3Igcm93IGlkcyBhcmUgb3V0cHV0dGVkLgoJICoKCSAqIFstLXN0YXRzXQoJICogOiBPdXRwdXQgc3RhdHMgb24gdGhlIG51bWJlciBvZiBtYXRjaGVzIGZvdW5kLCB0aW1lIHRha2VuLCB0YWJsZXMvY29sdW1ucy9yb3dzIHNlYXJjaGVkLCB0YWJsZXMgc2tpcHBlZC4KCSAqCgkgKiBbLS10YWJsZV9jb2x1bW5fY29sb3I9PGNvbG9yX2NvZGU+XQoJICogOiBQZXJjZW50IGNvbG9yIGNvZGUgdG8gdXNlIGZvciB0aGUgJ3RhYmxlOmNvbHVtbicgb3V0cHV0LiBGb3IgYSBsaXN0IG9mIGF2YWlsYWJsZSBwZXJjZW50IGNvbG9yIGNvZGVzLCBzZWUgYmVsb3cuIERlZmF1bHQgJyVHJyAoYnJpZ2h0IGdyZWVuKS4KCSAqCgkgKiBbLS1pZF9jb2xvcj08Y29sb3JfY29kZT5dCgkgKiA6IFBlcmNlbnQgY29sb3IgY29kZSB0byB1c2UgZm9yIHRoZSByb3cgaWQgb3V0cHV0LiBGb3IgYSBsaXN0IG9mIGF2YWlsYWJsZSBwZXJjZW50IGNvbG9yIGNvZGVzLCBzZWUgYmVsb3cuIERlZmF1bHQgJyVZJyAoYnJpZ2h0IHllbGxvdykuCgkgKgoJICogWy0tbWF0Y2hfY29sb3I9PGNvbG9yX2NvZGU+XQoJICogOiBQZXJjZW50IGNvbG9yIGNvZGUgdG8gdXNlIGZvciB0aGUgbWF0Y2ggKHVubGVzcyBib3RoIGJlZm9yZSBhbmQgYWZ0ZXIgY29udGV4dCBhcmUgMCwgd2hlbiBubyBjb2xvciBjb2RlIGlzIHVzZWQpLiBGb3IgYSBsaXN0IG9mIGF2YWlsYWJsZSBwZXJjZW50IGNvbG9yIGNvZGVzLCBzZWUgYmVsb3cuIERlZmF1bHQgJyUzJWsnIChibGFjayBvbiBhIG11c3RhcmQgYmFja2dyb3VuZCkuCgkgKgoJICogVGhlIHBlcmNlbnQgY29sb3IgY29kZXMgYXZhaWxhYmxlIGFyZToKCSAqCgkgKiB8IENvZGUgfCBDb2xvcgoJICogfCAtLS0tIHwgLS0tLS0KCSAqIHwgICV5ICB8IFllbGxvdyAoZGFyaykgKG11c3RhcmQpCgkgKiB8ICAlZyAgfCBHcmVlbiAoZGFyaykKCSAqIHwgICViICB8IEJsdWUgKGRhcmspCgkgKiB8ICAlciAgfCBSZWQgKGRhcmspCgkgKiB8ICAlbSAgfCBNYWdlbnRhIChkYXJrKQoJICogfCAgJWMgIHwgQ3lhbiAoZGFyaykKCSAqIHwgICV3ICB8IFdoaXRlIChkYXJrKSAobGlnaHQgZ3JheSkKCSAqIHwgICVrICB8IEJsYWNrCgkgKiB8ICAlWSAgfCBZZWxsb3cgKGJyaWdodCkKCSAqIHwgICVHICB8IEdyZWVuIChicmlnaHQpCgkgKiB8ICAlQiAgfCBCbHVlIChicmlnaHQpCgkgKiB8ICAlUiAgfCBSZWQgKGJyaWdodCkKCSAqIHwgICVNICB8IE1hZ2VudGEgKGJyaWdodCkKCSAqIHwgICVDICB8IEN5YW4gKGJyaWdodCkKCSAqIHwgICVXICB8IFdoaXRlCgkgKiB8ICAlSyAgfCBCbGFjayAoYnJpZ2h0KSAoZGFyayBncmF5KQoJICogfCAgJTMgIHwgWWVsbG93IGJhY2tncm91bmQgKGRhcmspIChtdXN0YXJkKQoJICogfCAgJTIgIHwgR3JlZW4gYmFja2dyb3VuZCAoZGFyaykKCSAqIHwgICU0ICB8IEJsdWUgYmFja2dyb3VuZCAoZGFyaykKCSAqIHwgICUxICB8IFJlZCBiYWNrZ3JvdW5kIChkYXJrKQoJICogfCAgJTUgIHwgTWFnZW50YSBiYWNrZ3JvdW5kIChkYXJrKQoJICogfCAgJTYgIHwgQ3lhbiBiYWNrZ3JvdW5kIChkYXJrKQoJICogfCAgJTcgIHwgV2hpdGUgYmFja2dyb3VuZCAoZGFyaykgKGxpZ2h0IGdyYXkpCgkgKiB8ICAlMCAgfCBCbGFjayBiYWNrZ3JvdW5kCgkgKiB8ICAlOCAgfCBSZXZlcnNlCgkgKiB8ICAlVSAgfCBVbmRlcmxpbmUKCSAqIHwgICVGICB8IEJsaW5rICh1bmxpa2VseSB0byB3b3JrKQoJICoKCSAqIFRoZXkgY2FuIGJlIGNvbmNhdGVuYXRlZC4gRm9yIGluc3RhbmNlLCB0aGUgZGVmYXVsdCBtYXRjaCBjb2xvciBvZiBibGFjayBvbiBhIG11c3RhcmQgKGRhcmsgeWVsbG93KSBiYWNrZ3JvdW5kIGAlMyVrYCBjYW4gYmUgbWFkZSBibGFjayBvbiBhIGJyaWdodCB5ZWxsb3cgYmFja2dyb3VuZCB3aXRoIGAlWSUwJThgLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2VhcmNoIHRocm91Z2ggdGhlIGRhdGFiYXNlIGZvciB0aGUgJ3dvcmRwcmVzcy1kZXZlbG9wJyBzdHJpbmcKCSAqICAgICAkIHdwIGRiIHNlYXJjaCB3b3JkcHJlc3MtZGV2ZWxvcAoJICogICAgIHdwX29wdGlvbnM6b3B0aW9uX3ZhbHVlCgkgKiAgICAgMTpodHRwOi8vd29yZHByZXNzLWRldmVsb3AuZGV2CgkgKiAgICAgd3Bfb3B0aW9uczpvcHRpb25fdmFsdWUKCSAqICAgICAxOmh0dHBzOi8vZXhhbXBsZS5jb20vZm9vCgkgKiAgICAgICAgIC4uLgoJICoKCSAqICAgICAjIFNlYXJjaCB0aHJvdWdoIGEgbXVsdGlzaXRlIGRhdGFiYXNlIG9uIHRoZSBzdWJzaXRlICdmb28nIGZvciB0aGUgJ2V4YW1wbGUuY29tJyBzdHJpbmcKCSAqICAgICAkIHdwIGRiIHNlYXJjaCBleGFtcGxlLmNvbSAtLXVybD1leGFtcGxlLmNvbS9mb28KCSAqICAgICB3cF8yX2NvbW1lbnRzOmNvbW1lbnRfYXV0aG9yX3VybAoJICogICAgIDE6aHR0cHM6Ly9leGFtcGxlLmNvbS8KCSAqICAgICB3cF8yX29wdGlvbnM6b3B0aW9uX3ZhbHVlCgkgKiAgICAgICAgIC4uLgoJICoKCSAqICAgICAjIFNlYXJjaCB0aHJvdWdoIHRoZSBkYXRhYmFzZSBmb3IgdGhlICdodHRwcz86Ly8nIHJlZ3VsYXIgZXhwcmVzc2lvbiwgcHJpbnRpbmcgc3RhdHMuCgkgKiAgICAgJCB3cCBkYiBzZWFyY2ggJ2h0dHBzPzovLycgLS1yZWdleCAtLXN0YXRzCgkgKiAgICAgd3BfY29tbWVudHM6Y29tbWVudF9hdXRob3JfdXJsCgkgKiAgICAgMTpodHRwczovL3dvcmRwcmVzcy5vcmcvCgkgKiAgICAgICAgIC4uLgoJICogICAgIFN1Y2Nlc3M6IEZvdW5kIDk5MTQ2IG1hdGNoZXMgaW4gMTAuNzUycyAoMTAuNTU5cyBzZWFyY2hpbmcpLiBTZWFyY2hlZCAxMiB0YWJsZXMsIDUzIGNvbHVtbnMsIDEzNTg5MDcgcm93cy4gMSB0YWJsZSBza2lwcGVkOiB3cF90ZXJtX3JlbGF0aW9uc2hpcHMuCgkgKgoJICogICAgICMgU1FMIHNlYXJjaCBkYXRhYmFzZSB0YWJsZSAnd3Bfb3B0aW9ucycgd2hlcmUgJ29wdGlvbl9uYW1lJyBtYXRjaCAnZm9vJwoJICogICAgIHdwIGRiIHF1ZXJ5ICdTRUxFQ1QgKiBGUk9NIHdwX29wdGlvbnMgV0hFUkUgb3B0aW9uX25hbWUgbGlrZSAiJWZvbyUiJyAtLXNraXAtY29sdW1uLW5hbWVzCgkgKiAgICAgKy0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0rCgkgKiAgICAgfCA5OCB8IGZvb19vcHRpb25zICB8IGE6MTp7czoxMjoiX211bHRpd2lkZ2V0IjtpOjE7fSB8IHllcyB8CgkgKiAgICAgfCA5OSB8IGZvb19zZXR0aW5ncyB8IGE6MDp7fSAgICAgICAgICAgICAgICAgICAgICAgICB8IHllcyB8CgkgKiAgICAgKy0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0rCgkgKgoJICogICAgICMgU1FMIHNlYXJjaCBhbmQgZGVsZXRlIHJlY29yZHMgZnJvbSBkYXRhYmFzZSB0YWJsZSAnd3Bfb3B0aW9ucycgd2hlcmUgJ29wdGlvbl9uYW1lJyBtYXRjaCAnZm9vJwoJICogICAgIHdwIGRiIHF1ZXJ5ICJERUxFVEUgZnJvbSB3cF9vcHRpb25zIHdoZXJlIG9wdGlvbl9pZCBpbiAoJCh3cCBkYiBxdWVyeSAiU0VMRUNUIEdST1VQX0NPTkNBVChvcHRpb25faWQgU0VQQVJBVE9SICcsJykgZnJvbSB3cF9vcHRpb25zIHdoZXJlIG9wdGlvbl9uYW1lIGxpa2UgJyVmb28lJzsiIC0tc2lsZW50IC0tc2tpcC1jb2x1bW4tbmFtZXMpKSIKCSAqCgkgKiBAd2hlbiBhZnRlcl93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZWFyY2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSRzdGFydF9ydW5fdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApOwoKCQkkc2VhcmNoID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgoJCSRiZWZvcmVfY29udGV4dCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2JlZm9yZV9jb250ZXh0JywgNDAgKTsKCQkkYmVmb3JlX2NvbnRleHQgPSAnJyA9PT0gJGJlZm9yZV9jb250ZXh0ID8gJGJlZm9yZV9jb250ZXh0IDogKGludCkgJGJlZm9yZV9jb250ZXh0OwoKCQkkYWZ0ZXJfY29udGV4dCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FmdGVyX2NvbnRleHQnLCA0MCApOwoJCSRhZnRlcl9jb250ZXh0ID0gJycgPT09ICRhZnRlcl9jb250ZXh0ID8gJGFmdGVyX2NvbnRleHQgOiAoaW50KSAkYWZ0ZXJfY29udGV4dDsKCgkJJHJlZ2V4ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgnLCBmYWxzZSApOwoJCWlmICggZmFsc2UgIT09ICRyZWdleCApIHsKCQkJJHJlZ2V4X2ZsYWdzICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgtZmxhZ3MnLCBmYWxzZSApOwoJCQkkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgPSBmYWxzZTsKCQkJJHJlZ2V4X2RlbGltaXRlciAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgtZGVsaW1pdGVyJywgJycgKTsKCQkJaWYgKCAnJyA9PT0gJHJlZ2V4X2RlbGltaXRlciApIHsKCQkJCSRyZWdleF9kZWxpbWl0ZXIgICAgICAgICA9IGNociggMSApOwoJCQkJJGRlZmF1bHRfcmVnZXhfZGVsaW1pdGVyID0gdHJ1ZTsKCQkJfQoJCX0KCgkJJGNvbG9ycyA9IHNlbGY6OmdldF9jb2xvcnMoCgkJCSRhc3NvY19hcmdzLAoJCQlbCgkJCQkndGFibGVfY29sdW1uJyA9PiAnJUcnLAoJCQkJJ2lkJyAgICAgICAgICAgPT4gJyVZJywKCQkJCSdtYXRjaCcgICAgICAgID0+ICRiZWZvcmVfY29udGV4dCB8fCAkYWZ0ZXJfY29udGV4dCA/ICclMyVrJyA6ICcnLAoJCQldCgkJKTsKCgkJJHRhYmxlX2NvbHVtbl9vbmNlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndGFibGVfY29sdW1uX29uY2UnLCBmYWxzZSApOwoJCSRvbmVfbGluZSAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ29uZV9saW5lJywgZmFsc2UgKTsKCQkkbWF0Y2hlc19vbmx5ICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdtYXRjaGVzX29ubHknLCBmYWxzZSApOwoJCSRzdGF0cyAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0YXRzJywgZmFsc2UgKTsKCgkJJGNvbHVtbl9jb3VudCA9IDA7CgkJJHJvd19jb3VudCAgICA9IDA7CgkJJG1hdGNoX2NvdW50ICA9IDA7CgkJJHNraXBwZWQgICAgICA9IFtdOwoKCQlpZiAoICRyZWdleCApIHsKCQkJLy8gTm90ZSB0aGUgdXNlciBtdXN0IGVzY2FwZSB0aGUgZGVsaW1pdGVyIGluIHRoZSBzZWFyY2guCgkJCSRzZWFyY2hfcmVnZXggPSAkcmVnZXhfZGVsaW1pdGVyIC4gJHNlYXJjaCAuICRyZWdleF9kZWxpbWl0ZXI7CgkJCWlmICggJHJlZ2V4X2ZsYWdzICkgewoJCQkJJHNlYXJjaF9yZWdleCAuPSAkcmVnZXhfZmxhZ3M7CgkJCX0KCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuTm9TaWxlbmNlZEVycm9ycy5EaXNjb3VyYWdlZCAtLSBVbnN1cmUgd2h5IHRoaXMgaXMgbmVlZGVkLCBsZWF2aW5nIGluIGZvciBub3cuCgkJCWlmICggZmFsc2UgPT09IEBwcmVnX21hdGNoKCAkc2VhcmNoX3JlZ2V4LCAnJyApICkgewoJCQkJaWYgKCAkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgKSB7CgkJCQkJJGZsYWdzX21zZyA9ICRyZWdleF9mbGFncyA/ICJmbGFncyAnJHJlZ2V4X2ZsYWdzJyIgOiAnbm8gZmxhZ3MnOwoJCQkJCSRtc2cgICAgICAgPSAiVGhlIHJlZ2V4IHBhdHRlcm4gJyRzZWFyY2gnIHdpdGggZGVmYXVsdCBkZWxpbWl0ZXIgJ2NocigxKScgYW5kIHskZmxhZ3NfbXNnfSBmYWlscy4iOwoJCQkJfSBlbHNlIHsKCQkJCQkkbXNnID0gIlRoZSByZWdleCAnJHNlYXJjaF9yZWdleCcgZmFpbHMuIjsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoICRtc2cgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRzZWFyY2hfcmVnZXggICAgPSAnIycgLiBwcmVnX3F1b3RlKCAkc2VhcmNoLCAnIycgKSAuICcjaSc7CgkJCSRlc2NfbGlrZV9zZWFyY2ggPSAnJScgLiBVdGlsc1xlc2NfbGlrZSggJHNlYXJjaCApIC4gJyUnOwoJCX0KCgkJJGVuY29kaW5nID0gbnVsbDsKCQlpZiAoIDAgPT09IHN0cnBvcyggJHdwZGItPmNoYXJzZXQsIHNlbGY6OkVOQ09ESU5HX1VURjggKSApIHsKCQkJJGVuY29kaW5nID0gJ1VURi04JzsKCQl9CgoJCSR0YWJsZXMgPSBVdGlsc1x3cF9nZXRfdGFibGVfbmFtZXMoICRhcmdzLCAkYXNzb2NfYXJncyApOwoKCQkkc3RhcnRfc2VhcmNoX3RpbWUgPSBtaWNyb3RpbWUoIHRydWUgKTsKCgkJZm9yZWFjaCAoICR0YWJsZXMgYXMgJHRhYmxlICkgewoJCQlsaXN0KCAkcHJpbWFyeV9rZXlzLCAkdGV4dF9jb2x1bW5zLCAkYWxsX2NvbHVtbnMgKSA9IHNlbGY6OmdldF9jb2x1bW5zKCAkdGFibGUgKTsKCQkJaWYgKCAhICRhbGxfY29sdW1ucyApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJObyBzdWNoIHRhYmxlICckdGFibGUnLiIgKTsKCQkJfQoJCQlpZiAoICEgJHRleHRfY29sdW1ucyApIHsKCQkJCWlmICggJHN0YXRzICkgewoJCQkJCSRza2lwcGVkW10gPSAkdGFibGU7CgkJCQl9IGVsc2UgewoJCQkJCS8vIERvbid0IGJvdGhlciB3YXJuaW5nIGZvciB0ZXJtIHJlbGF0aW9uc2hpcHMgKHdoaWNoIGlzIGp1c3QgMyBpbnQgY29sdW1ucykuCgkJCQkJaWYgKCAhIHByZWdfbWF0Y2goICcvX3Rlcm1fcmVsYXRpb25zaGlwcyQvJywgJHRhYmxlICkgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggJHByaW1hcnlfa2V5cyA/ICJObyB0ZXh0IGNvbHVtbnMgZm9yIHRhYmxlICckdGFibGUnIC0gc2tpcHBlZC4iIDogIk5vIHByaW1hcnkga2V5IG9yIHRleHQgY29sdW1ucyBmb3IgdGFibGUgJyR0YWJsZScgLSBza2lwcGVkLiIgKTsKCQkJCQl9CgkJCQl9CgkJCQljb250aW51ZTsKCQkJfQoJCQkkdGFibGVfc3FsICAgICA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICR0YWJsZSApOwoJCQkkY29sdW1uX2NvdW50ICs9IGNvdW50KCAkdGV4dF9jb2x1bW5zICk7CgkJCWlmICggISAkcHJpbWFyeV9rZXlzICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiTm8gcHJpbWFyeSBrZXkgZm9yIHRhYmxlICckdGFibGUnLiBObyByb3cgaWRzIHdpbGwgYmUgb3V0cHV0dGVkLiIgKTsKCQkJCSRwcmltYXJ5X2tleSAgICAgPSAnJzsKCQkJCSRwcmltYXJ5X2tleV9zcWwgPSAnJzsKCQkJfSBlbHNlIHsKCQkJCSRwcmltYXJ5X2tleSAgICAgPSBhcnJheV9zaGlmdCggJHByaW1hcnlfa2V5cyApOwoJCQkJJHByaW1hcnlfa2V5X3NxbCA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICRwcmltYXJ5X2tleSApIC4gJywgJzsKCQkJfQoKCQkJZm9yZWFjaCAoICR0ZXh0X2NvbHVtbnMgYXMgJGNvbHVtbiApIHsKCQkJCSRjb2x1bW5fc3FsID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGNvbHVtbiApOwoJCQkJaWYgKCAkcmVnZXggKSB7CgkJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5JbnRlcnBvbGF0ZWROb3RQcmVwYXJlZCAtLSBFc2NhcGVkIHRocm91Z2ggZXNjX3NxbF9pZGVudC9lc2NfbGlrZS4KCQkJCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIlNFTEVDVCB7JHByaW1hcnlfa2V5X3NxbH17JGNvbHVtbl9zcWx9IEZST00geyR0YWJsZV9zcWx9IiApOwoJCQkJfSBlbHNlIHsKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIEVzY2FwZWQgdGhyb3VnaCBlc2Nfc3FsX2lkZW50L2VzY19saWtlLgoJCQkJCSRyZXN1bHRzID0gJHdwZGItPmdldF9yZXN1bHRzKCAkd3BkYi0+cHJlcGFyZSggIlNFTEVDVCB7JHByaW1hcnlfa2V5X3NxbH17JGNvbHVtbl9zcWx9IEZST00geyR0YWJsZV9zcWx9IFdIRVJFIHskY29sdW1uX3NxbH0gTElLRSAlczsiLCAkZXNjX2xpa2Vfc2VhcmNoICkgKTsKCQkJCX0KCQkJCWlmICggJHJlc3VsdHMgKSB7CgkJCQkJJHJvd19jb3VudCAgICAgICAgICAgICAgICAgICs9IGNvdW50KCAkcmVzdWx0cyApOwoJCQkJCSR0YWJsZV9jb2x1bW5fdmFsICAgICAgICAgICAgPSAkY29sb3JzWyd0YWJsZV9jb2x1bW4nXVswXSAuICJ7JHRhYmxlfTp7JGNvbHVtbn0iIC4gJGNvbG9yc1sndGFibGVfY29sdW1uJ11bMV07CgkJCQkJJG91dHB1dHRlZF90YWJsZV9jb2x1bW5fb25jZSA9IGZhbHNlOwoJCQkJCWZvcmVhY2ggKCAkcmVzdWx0cyBhcyAkcmVzdWx0ICkgewoJCQkJCQkkY29sX3ZhbCA9ICRyZXN1bHQtPiRjb2x1bW47CgkJCQkJCWlmICggcHJlZ19tYXRjaF9hbGwoICRzZWFyY2hfcmVnZXgsICRjb2xfdmFsLCAkbWF0Y2hlcywgUFJFR19PRkZTRVRfQ0FQVFVSRSApICkgewoJCQkJCQkJaWYgKCAhICRtYXRjaGVzX29ubHkgJiYgKCAhICR0YWJsZV9jb2x1bW5fb25jZSB8fCAhICRvdXRwdXR0ZWRfdGFibGVfY29sdW1uX29uY2UgKSAmJiAhICRvbmVfbGluZSApIHsKCQkJCQkJCQlXUF9DTEk6OmxvZyggJHRhYmxlX2NvbHVtbl92YWwgKTsKCQkJCQkJCQkkb3V0cHV0dGVkX3RhYmxlX2NvbHVtbl9vbmNlID0gdHJ1ZTsKCQkJCQkJCX0KCQkJCQkJCSRwa192YWwgPSAkcHJpbWFyeV9rZXkgPyAoICRjb2xvcnNbJ2lkJ11bMF0gLiAkcmVzdWx0LT4kcHJpbWFyeV9rZXkgLiAkY29sb3JzWydpZCddWzFdIC4gJzonICkgOiAnJzsKCgkJCQkJCQkkYml0cyAgICAgICAgID0gW107CgkJCQkJCQkkY29sX2VuY29kaW5nID0gJGVuY29kaW5nOwoJCQkJCQkJaWYgKCAhICRjb2xfZW5jb2RpbmcgJiYgKCAkYmVmb3JlX2NvbnRleHQgfHwgJGFmdGVyX2NvbnRleHQgKSAmJiBmdW5jdGlvbl9leGlzdHMoICdtYl9kZXRlY3RfZW5jb2RpbmcnICkgKSB7CgkJCQkJCQkJJGNvbF9lbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZyggJGNvbF92YWwsIG51bGwsIHRydWUgLypzdHJpY3QqLyApOwoJCQkJCQkJfQoJCQkJCQkJJGFwcGVuZF9uZXh0ID0gZmFsc2U7CgkJCQkJCQkkbGFzdF9vZmZzZXQgPSAwOwoJCQkJCQkJJG1hdGNoX2NudCAgID0gY291bnQoICRtYXRjaGVzWzBdICk7CgkJCQkJCQlmb3IgKCAkaSA9IDA7ICRpIDwgJG1hdGNoX2NudDsgJGkrKyApIHsKCQkJCQkJCQkkbWF0Y2ggICAgICAgICAgID0gJG1hdGNoZXNbMF1bICRpIF1bMF07CgkJCQkJCQkJJG9mZnNldCAgICAgICAgICA9ICRtYXRjaGVzWzBdWyAkaSBdWzFdOwoJCQkJCQkJCSRsb2cgICAgICAgICAgICAgPSAkY29sb3JzWydtYXRjaCddWzBdIC4gJG1hdGNoIC4gJGNvbG9yc1snbWF0Y2gnXVsxXTsKCQkJCQkJCQkkYmVmb3JlICAgICAgICAgID0gJyc7CgkJCQkJCQkJJGFmdGVyICAgICAgICAgICA9ICcnOwoJCQkJCQkJCSRhZnRlcl9zaG9ydGVuZWQgPSBmYWxzZTsKCgkJCQkJCQkJLy8gT2Zmc2V0cyBhcmUgaW4gYnl0ZXMsIHNvIG5lZWQgdG8gdXNlIGBzdHJsZW4oKWAgYW5kIGBzdWJzdHIoKWAgYmVmb3JlIHVzaW5nIGBzYWZlX3N1YnN0cigpYC4KCQkJCQkJCQlpZiAoICRiZWZvcmVfY29udGV4dCAmJiAkb2Zmc2V0ICYmICEgJGFwcGVuZF9uZXh0ICkgewoJCQkJCQkJCQkkYmVmb3JlID0gXGNsaVxzYWZlX3N1YnN0ciggc3Vic3RyKCAkY29sX3ZhbCwgJGxhc3Rfb2Zmc2V0LCAkb2Zmc2V0IC0gJGxhc3Rfb2Zmc2V0ICksIC0kYmVmb3JlX2NvbnRleHQsIG51bGwgLypsZW5ndGgqLywgZmFsc2UgLyppc193aWR0aCovLCAkY29sX2VuY29kaW5nICk7CgkJCQkJCQkJfQoJCQkJCQkJCWlmICggJGFmdGVyX2NvbnRleHQgKSB7CgkJCQkJCQkJCSRlbmRfb2Zmc2V0ID0gJG9mZnNldCArIHN0cmxlbiggJG1hdGNoICk7CgkJCQkJCQkJCSRhZnRlciAgICAgID0gXGNsaVxzYWZlX3N1YnN0ciggc3Vic3RyKCAkY29sX3ZhbCwgJGVuZF9vZmZzZXQgKSwgMCwgJGFmdGVyX2NvbnRleHQsIGZhbHNlIC8qaXNfd2lkdGgqLywgJGNvbF9lbmNvZGluZyApOwoJCQkJCQkJCQkvLyBUbyBsZXNzZW4gY29udGV4dCBkdXBsaWNhdGlvbiBpbiBvdXRwdXQsIHNob3J0ZW4gdGhlIGFmdGVyIGNvbnRleHQgaWYgaXQgb3ZlcmxhcHMgd2l0aCB0aGUgbmV4dCBtYXRjaC4KCQkJCQkJCQkJaWYgKCAkaSArIDEgPCAkbWF0Y2hfY250ICYmICRlbmRfb2Zmc2V0ICsgc3RybGVuKCAkYWZ0ZXIgKSA+ICRtYXRjaGVzWzBdWyAkaSArIDEgXVsxXSApIHsKCQkJCQkJCQkJCSRhZnRlciAgICAgICAgICAgPSBzdWJzdHIoICRhZnRlciwgMCwgJG1hdGNoZXNbMF1bICRpICsgMSBdWzFdIC0gJGVuZF9vZmZzZXQgKTsKCQkJCQkJCQkJCSRhZnRlcl9zaG9ydGVuZWQgPSB0cnVlOwoJCQkJCQkJCQkJLy8gT24gdGhlIG5leHQgaXRlcmF0aW9uLCB3aWxsIGFwcGVuZCB3aXRoIG5vIGJlZm9yZSBjb250ZXh0LgoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJCWlmICggJGFwcGVuZF9uZXh0ICkgewoJCQkJCQkJCQkkY250ICAgICAgICAgICAgICAgPSBjb3VudCggJGJpdHMgKTsKCQkJCQkJCQkJJGJpdHNbICRjbnQgLSAxIF0gLj0gJGxvZyAuICRhZnRlcjsKCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQkkYml0c1tdID0gJGJlZm9yZSAuICRsb2cgLiAkYWZ0ZXI7CgkJCQkJCQkJfQoJCQkJCQkJCSRhcHBlbmRfbmV4dCA9ICRhZnRlcl9zaG9ydGVuZWQ7CgkJCQkJCQkJJGxhc3Rfb2Zmc2V0ID0gJG9mZnNldDsKCQkJCQkJCX0KCQkJCQkJCSRtYXRjaF9jb3VudCArPSAkbWF0Y2hfY250OwoJCQkJCQkJJGNvbF92YWwgICAgICA9IGltcGxvZGUoICcgWy4uLl0gJywgJGJpdHMgKTsKCgkJCQkJCQlXUF9DTEk6OmxvZyggJG1hdGNoZXNfb25seSA/ICRjb2xfdmFsIDogKCAkb25lX2xpbmUgPyAieyR0YWJsZV9jb2x1bW5fdmFsfTp7JHBrX3ZhbH17JGNvbF92YWx9IiA6ICJ7JHBrX3ZhbH17JGNvbF92YWx9IiApICk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJHN0YXRzICkgewoJCQkkdGFibGVfY291bnQgICA9IGNvdW50KCAkdGFibGVzICk7CgkJCSRza2lwcGVkX2NvdW50ID0gY291bnQoICRza2lwcGVkICk7CgkJCSRtYXRjaF9zdHIgICAgID0gMSA9PT0gJG1hdGNoX2NvdW50ID8gJ21hdGNoJyA6ICdtYXRjaGVzJzsKCQkJJHRhYmxlX3N0ciAgICAgPSAxID09PSAkdGFibGVfY291bnQgPyAndGFibGUnIDogJ3RhYmxlcyc7CgkJCSRjb2x1bW5fc3RyICAgID0gMSA9PT0gJGNvbHVtbl9jb3VudCA/ICdjb2x1bW4nIDogJ2NvbHVtbnMnOwoJCQkkcm93X3N0ciAgICAgICA9IDEgPT09ICRyb3dfY291bnQgPyAncm93JyA6ICdyb3dzJzsKCQkJJHNraXBwZWRfc3RyICAgPSAxID09PSAkc2tpcHBlZF9jb3VudCA/ICd0YWJsZSBza2lwcGVkJyA6ICd0YWJsZXMgc2tpcHBlZCc7CgkJCWlmICggMCAhPT0gJHNraXBwZWRfY291bnQgKSB7CgkJCQkkc2tpcHBlZF9zdHIgLj0gJzogJyAuIGltcGxvZGUoICcsICcsICRza2lwcGVkICk7CgkJCX0KCQkJJGVuZF90aW1lICAgID0gbWljcm90aW1lKCB0cnVlICk7CgkJCSRydW5fdGltZSAgICA9ICRlbmRfdGltZSAtICRzdGFydF9ydW5fdGltZTsKCQkJJHNlYXJjaF90aW1lID0gJGVuZF90aW1lIC0gJHN0YXJ0X3NlYXJjaF90aW1lOwoJCQkkc3RhdHNfbXNnICAgPSBzcHJpbnRmKAoJCQkJJ0ZvdW5kICVkICVzIGluICUuM2ZzICglLjNmcyBzZWFyY2hpbmcpLiBTZWFyY2hlZCAlZCAlcywgJWQgJXMsICVkICVzLiAlZCAlcy4nLAoJCQkJJG1hdGNoX2NvdW50LAoJCQkJJG1hdGNoX3N0ciwKCQkJCSRydW5fdGltZSwKCQkJCSRzZWFyY2hfdGltZSwKCQkJCSR0YWJsZV9jb3VudCwKCQkJCSR0YWJsZV9zdHIsCgkJCQkkY29sdW1uX2NvdW50LAoJCQkJJGNvbHVtbl9zdHIsCgkJCQkkcm93X2NvdW50LAoJCQkJJHJvd19zdHIsCgkJCQkkc2tpcHBlZF9jb3VudCwKCQkJCSRza2lwcGVkX3N0cgoJCQkpOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICRzdGF0c19tc2cgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEaXNwbGF5cyBpbmZvcm1hdGlvbiBhYm91dCBhIGdpdmVuIHRhYmxlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGFibGU+CgkgKiA6IE5hbWUgb2YgdGhlIGRhdGFiYXNlIHRhYmxlLgoJICoKCSAqIFstLWZvcm1hdF0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIGNvbHVtbnMgd3BfcG9zdHMKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLSstLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8ICAgICAgICAgRmllbGQgICAgICAgICB8ICAgICAgICBUeXBlICAgICAgICAgfCBOdWxsIHwgS2V5IHwgICAgICAgRGVmYXVsdCAgICAgICB8ICAgICBFeHRyYSAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLSstLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IElEICAgICAgICAgICAgICAgICAgICB8IGJpZ2ludCgyMCkgdW5zaWduZWQgfCBOTyAgIHwgUFJJIHwgICAgICAgICAgICAgICAgICAgICB8IGF1dG9faW5jcmVtZW50IHwKCSAqICAgICB8IHBvc3RfYXV0aG9yICAgICAgICAgICB8IGJpZ2ludCgyMCkgdW5zaWduZWQgfCBOTyAgIHwgTVVMIHwgMCAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfZGF0ZSAgICAgICAgICAgICB8IGRhdGV0aW1lICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgMDAwMC0wMC0wMCAwMDowMDowMCB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfZGF0ZV9nbXQgICAgICAgICB8IGRhdGV0aW1lICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgMDAwMC0wMC0wMCAwMDowMDowMCB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfY29udGVudCAgICAgICAgICB8IGxvbmd0ZXh0ICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfdGl0bGUgICAgICAgICAgICB8IHRleHQgICAgICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfZXhjZXJwdCAgICAgICAgICB8IHRleHQgICAgICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3Rfc3RhdHVzICAgICAgICAgICB8IHZhcmNoYXIoMjApICAgICAgICAgfCBOTyAgIHwgICAgIHwgcHVibGlzaCAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IGNvbW1lbnRfc3RhdHVzICAgICAgICB8IHZhcmNoYXIoMjApICAgICAgICAgfCBOTyAgIHwgICAgIHwgb3BlbiAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBpbmdfc3RhdHVzICAgICAgICAgICB8IHZhcmNoYXIoMjApICAgICAgICAgfCBOTyAgIHwgICAgIHwgb3BlbiAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfcGFzc3dvcmQgICAgICAgICB8IHZhcmNoYXIoMjU1KSAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfbmFtZSAgICAgICAgICAgICB8IHZhcmNoYXIoMjAwKSAgICAgICAgfCBOTyAgIHwgTVVMIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHRvX3BpbmcgICAgICAgICAgICAgICB8IHRleHQgICAgICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBpbmdlZCAgICAgICAgICAgICAgICB8IHRleHQgICAgICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfbW9kaWZpZWQgICAgICAgICB8IGRhdGV0aW1lICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgMDAwMC0wMC0wMCAwMDowMDowMCB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfbW9kaWZpZWRfZ210ICAgICB8IGRhdGV0aW1lICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgMDAwMC0wMC0wMCAwMDowMDowMCB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfY29udGVudF9maWx0ZXJlZCB8IGxvbmd0ZXh0ICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfcGFyZW50ICAgICAgICAgICB8IGJpZ2ludCgyMCkgdW5zaWduZWQgfCBOTyAgIHwgTVVMIHwgMCAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IGd1aWQgICAgICAgICAgICAgICAgICB8IHZhcmNoYXIoMjU1KSAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IG1lbnVfb3JkZXIgICAgICAgICAgICB8IGludCgxMSkgICAgICAgICAgICAgfCBOTyAgIHwgICAgIHwgMCAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfdHlwZSAgICAgICAgICAgICB8IHZhcmNoYXIoMjApICAgICAgICAgfCBOTyAgIHwgTVVMIHwgcG9zdCAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IHBvc3RfbWltZV90eXBlICAgICAgICB8IHZhcmNoYXIoMTAwKSAgICAgICAgfCBOTyAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICB8IGNvbW1lbnRfY291bnQgICAgICAgICB8IGJpZ2ludCgyMCkgICAgICAgICAgfCBOTyAgIHwgICAgIHwgMCAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLSstLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiBAd2hlbiBhZnRlcl93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjb2x1bW5zKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkZm9ybWF0ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApOwoKCQlVdGlsc1x3cF9nZXRfdGFibGVfbmFtZXMoIFsgJGFyZ3NbMF0gXSwgWyAnYWxsLXRhYmxlcycgPT4gdHJ1ZSBdICk7CgoJCSRjb2x1bW5zID0gJHdwZGItPmdldF9yZXN1bHRzKAoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIEFzc2VydGVkIHRvIGJlIGEgdmFsaWQgdGFibGUgbmFtZSB0aHJvdWdoIHdwX2dldF90YWJsZV9uYW1lcy4KCQkJJ1NIT1cgQ09MVU1OUyBGUk9NICcgLiAkYXJnc1swXQoJCSk7CgoJCSRmb3JtYXR0ZXJfZmllbGRzID0gWyAnRmllbGQnLCAnVHlwZScsICdOdWxsJywgJ0tleScsICdEZWZhdWx0JywgJ0V4dHJhJyBdOwoJCSRmb3JtYXR0ZXJfYXJncyAgID0gWwoJCQknZm9ybWF0JyA9PiAkZm9ybWF0LAoJCV07CgoJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkZm9ybWF0dGVyX2FyZ3MsICRmb3JtYXR0ZXJfZmllbGRzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGNvbHVtbnMgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfY3JlYXRlX3F1ZXJ5KCkgewoKCQkkY3JlYXRlX3F1ZXJ5ID0gc3ByaW50ZiggJ0NSRUFURSBEQVRBQkFTRSAlcycsIHNlbGY6OmVzY19zcWxfaWRlbnQoIERCX05BTUUgKSApOwoJCWlmICggZGVmaW5lZCggJ0RCX0NIQVJTRVQnICkgJiYgY29uc3RhbnQoICdEQl9DSEFSU0VUJyApICkgewoJCQkkY3JlYXRlX3F1ZXJ5IC49IHNwcmludGYoICcgREVGQVVMVCBDSEFSU0VUICVzJywgc2VsZjo6ZXNjX3NxbF9pZGVudCggREJfQ0hBUlNFVCApICk7CgkJfQoJCWlmICggZGVmaW5lZCggJ0RCX0NPTExBVEUnICkgJiYgY29uc3RhbnQoICdEQl9DT0xMQVRFJyApICkgewoJCQkkY3JlYXRlX3F1ZXJ5IC49IHNwcmludGYoICcgREVGQVVMVCBDT0xMQVRFICVzJywgc2VsZjo6ZXNjX3NxbF9pZGVudCggREJfQ09MTEFURSApICk7CgkJfQoJCXJldHVybiAkY3JlYXRlX3F1ZXJ5OwoJfQoKCS8qKgoJICogUnVuIGEgc2luZ2xlIHF1ZXJ5IHZpYSB0aGUgJ215c3FsJyBiaW5hcnkuCgkgKgoJICogVGhpcyBpbmNsdWRlcyB0aGUgbmVjZXNzYXJ5IHNldHVwIHRvIG1ha2Ugc3VyZSB0aGUgcXVlcmllcyBiZWhhdmUgc2ltaWxhcgoJICogdG8gd2hhdCBXUERCIHByb2R1Y2VzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHF1ZXJ5ICAgICAgUXVlcnkgdG8gZXhlY3V0ZS4KCSAqIEBwYXJhbSBhcnJheSAgJGFzc29jX2FyZ3MgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIGFyZ3VtZW50cy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJ1bl9xdWVyeSggJHF1ZXJ5LCAkYXNzb2NfYXJncyA9IFtdICkgewoJCS8vIEVuc3VyZSB0aGF0IHRoZSBTUUwgbW9kZSBpcyBjb21wYXRpYmxlIHdpdGggV1BEQi4KCQkkcXVlcnkgPSAkdGhpcy0+Z2V0X3NxbF9tb2RlX3F1ZXJ5KCAkYXNzb2NfYXJncyApIC4gJHF1ZXJ5OwoKCQlXUF9DTEk6OmRlYnVnKCAiUXVlcnk6IHskcXVlcnl9IiwgJ2RiJyApOwoKCQkkbXlzcWxfYXJncyA9IGFycmF5X21lcmdlKAoJCQlzZWxmOjpnZXRfZGJ1c2VyX2RicGFzc19hcmdzKCAkYXNzb2NfYXJncyApLAoJCQlzZWxmOjpnZXRfbXlzcWxfYXJncyggJGFzc29jX2FyZ3MgKQoJCSk7CgoJCXNlbGY6OnJ1bigKCQkJc3ByaW50ZigKCQkJCScvdXNyL2Jpbi9lbnYgbXlzcWwlcyAtLW5vLWF1dG8tcmVoYXNoJywKCQkJCSR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICkKCQkJKSwKCQkJYXJyYXlfbWVyZ2UoIFsgJ2V4ZWN1dGUnID0+ICRxdWVyeSBdLCAkbXlzcWxfYXJncyApCgkJKTsKCX0KCgkvKioKCSAqIFJ1biBhIE15U1FMIGNvbW1hbmQgYW5kIG9wdGlvbmFsbHkgcmV0dXJuIHRoZSBvdXRwdXQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY21kICAgICAgICAgICBDb21tYW5kIHRvIHJ1bi4KCSAqIEBwYXJhbSBhcnJheSAgJGFzc29jX2FyZ3MgICAgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIGFyZ3VtZW50cyB0bwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UuCgkgKiBAcGFyYW0gYm9vbCAgICRzZW5kX3RvX3NoZWxsIE9wdGlvbmFsLiBXaGV0aGVyIHRvIHNlbmQgU1RET1VUIGFuZCBTVERFUlIKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlbHkgdG8gdGhlIHNoZWxsLiBEZWZhdWx0cyB0byB0cnVlLgoJICogQHBhcmFtIGJvb2wgICAkaW50ZXJhY3RpdmUgICBPcHRpb25hbC4gV2hldGhlciBNeVNRTCBpcyBtZWFudCB0byBiZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZCBhcyBhbiBpbnRlcmFjdGl2ZSBwcm9jZXNzLiBEZWZhdWx0cwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBmYWxzZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IHsKCSAqICAgICBBc3NvY2lhdGl2ZSBhcnJheSBjb250YWluaW5nIFNURE9VVCBhbmQgU1RERVJSIG91dHB1dC4KCSAqCgkgKiAgICAgQHR5cGUgc3RyaW5nICRzdGRvdXQgICAgT3V0cHV0IHRoYXQgd2FzIHNlbnQgdG8gU1RET1VULgoJICogICAgIEB0eXBlIHN0cmluZyAkc3RkZXJyICAgIE91dHB1dCB0aGF0IHdhcyBzZW50IHRvIFNUREVSUi4KCSAqICAgICBAdHlwZSBpbnQgICAgJGV4aXRfY29kZSBFeGl0IGNvZGUgb2YgdGhlIHByb2Nlc3MuCgkgKiB9CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHJ1biggJGNtZCwgJGFzc29jX2FyZ3MgPSBbXSwgJHNlbmRfdG9fc2hlbGwgPSB0cnVlLCAkaW50ZXJhY3RpdmUgPSBmYWxzZSApIHsKCQkkcmVxdWlyZWQgPSBbCgkJCSdob3N0JyA9PiBEQl9IT1NULAoJCQkndXNlcicgPT4gREJfVVNFUiwKCQkJJ3Bhc3MnID0+IERCX1BBU1NXT1JELAoJCV07CgoJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbJ2RlZmF1bHQtY2hhcmFjdGVyLXNldCddICkKCQkJJiYgZGVmaW5lZCggJ0RCX0NIQVJTRVQnICkgJiYgY29uc3RhbnQoICdEQl9DSEFSU0VUJyApICkgewoJCQkkcmVxdWlyZWRbJ2RlZmF1bHQtY2hhcmFjdGVyLXNldCddID0gY29uc3RhbnQoICdEQl9DSEFSU0VUJyApOwoJCX0KCgkJLy8gVXNpbmcgJ2RidXNlcicgYXMgb3B0aW9uIG5hbWUgdG8gd29ya2Fyb3VuZCBjbGFzaCB3aXRoIFdQLUNMSSdzIGdsb2JhbCBXUCAndXNlcicgcGFyYW1ldGVyLCB3aXRoICdkYnBhc3MnIGFsc28gYXZhaWxhYmxlIGZvciB0aWR5bmVzcy4KCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZGJ1c2VyJ10gKSApIHsKCQkJJHJlcXVpcmVkWyd1c2VyJ10gPSAkYXNzb2NfYXJnc1snZGJ1c2VyJ107CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snZGJ1c2VyJ10gKTsKCQl9CgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2RicGFzcyddICkgKSB7CgkJCSRyZXF1aXJlZFsncGFzcyddID0gJGFzc29jX2FyZ3NbJ2RicGFzcyddOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ2RicGFzcyddLCAkYXNzb2NfYXJnc1sncGFzc3dvcmQnXSApOwoJCX0KCgkJJGZpbmFsX2FyZ3MgPSBhcnJheV9tZXJnZSggJHJlcXVpcmVkLCAkYXNzb2NfYXJncyApOwoKCQkvLyBBZGFwdCBvcmRlcmluZyBvZiBhcmd1bWVudHMuCgkJdWtzb3J0KAoJCQkkZmluYWxfYXJncywKCQkJc3RhdGljIGZ1bmN0aW9uICggJGEsICRiICkgewoJCQkJc3dpdGNoICggJGIgKSB7CgkJCQkJY2FzZSAnZm9yY2UnOgoJCQkJCQlyZXR1cm4gLTE7CgkJCQkJZGVmYXVsdDoKCQkJCQkJcmV0dXJuIDE7CgkJCQl9CgkJCX0KCQkpOwoKCQlyZXR1cm4gVXRpbHNccnVuX215c3FsX2NvbW1hbmQoICRjbWQsICRmaW5hbF9hcmdzLCBudWxsLCAkc2VuZF90b19zaGVsbCwgJGludGVyYWN0aXZlICk7Cgl9CgoJLyoqCgkgKiBIZWxwZXIgdG8gcGx1Y2sgJ2RidXNlcicgYW5kICdkYnBhc3MnIGZyb20gYXNzb2NpYXRpdmUgYXJncyBhcnJheS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXNzb2NpYXRpdmUgYXJncyBhcnJheS4KCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgd2l0aCBgZGJ1c2VyJyBhbmQgJ2RicGFzcycgc2V0IGlmIGluIHBhc3NlZC1pbiBhc3NvY2lhdGl2ZSBhcmdzIGFycmF5LgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfZGJ1c2VyX2RicGFzc19hcmdzKCAkYXNzb2NfYXJncyApIHsKCQkkbXlzcWxfYXJncyA9IFtdOwoJCSRkYnVzZXIgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGJ1c2VyJyApOwoJCWlmICggbnVsbCAhPT0gJGRidXNlciApIHsKCQkJJG15c3FsX2FyZ3NbJ2RidXNlciddID0gJGRidXNlcjsKCQl9CgkJJGRicGFzcyA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RicGFzcycgKTsKCQlpZiAoIG51bGwgIT09ICRkYnBhc3MgKSB7CgkJCSRteXNxbF9hcmdzWydkYnBhc3MnXSA9ICRkYnBhc3M7CgkJfQoJCXJldHVybiAkbXlzcWxfYXJnczsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGNvbHVtbiBuYW1lcyBvZiBhIGRiIHRhYmxlIGRpZmZlcmVudGlhdGVkIGludG8ga2V5IGNvbHVtbnMgYW5kIHRleHQgY29sdW1ucyBhbmQgYWxsIGNvbHVtbnMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGFibGUgVGhlIHRhYmxlIG5hbWUuCgkgKiBAcmV0dXJuIGFycmF5IEEgMyBlbGVtZW50IGFycmF5IGNvbnNpc3Rpbmcgb2YgYW4gYXJyYXkgb2YgcHJpbWFyeSBrZXkgY29sdW1uIG5hbWVzLCBhbiBhcnJheSBvZiB0ZXh0IGNvbHVtbiBuYW1lcywgYW5kIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIGNvbHVtbiBuYW1lcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2NvbHVtbnMoICR0YWJsZSApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSR0YWJsZV9zcWwgICAgICAgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCQkkcHJpbWFyeV9rZXlzICAgID0gW107CgkJJHRleHRfY29sdW1ucyAgICA9IFtdOwoJCSRhbGxfY29sdW1ucyAgICAgPSBbXTsKCQkkc3VwcHJlc3NfZXJyb3JzID0gJHdwZGItPnN1cHByZXNzX2Vycm9ycygpOwoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIEVzY2FwZWQgdGhyb3VnaCBlc2Nfc3FsX2lkZW50L2VzY19saWtlLgoJCSRyZXN1bHRzID0gJHdwZGItPmdldF9yZXN1bHRzKCAiREVTQ1JJQkUgJHRhYmxlX3NxbCIgKTsKCQlpZiAoICRyZXN1bHRzICkgewoJCQlmb3JlYWNoICggJHJlc3VsdHMgYXMgJGNvbCApIHsKCQkJCS8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlZhbGlkVmFyaWFibGVOYW1lLlVzZWRQcm9wZXJ0eU5vdFNuYWtlQ2FzZSAtLSBQcm9wZXJ0eSBuYW1lcyBjb21lIGZyb20gZGF0YWJhc2UuCgkJCQlpZiAoICdQUkknID09PSAkY29sLT5LZXkgKSB7CgkJCQkJJHByaW1hcnlfa2V5c1tdID0gJGNvbC0+RmllbGQ7CgkJCQl9CgkJCQlpZiAoIHNlbGY6OmlzX3RleHRfY29sKCAkY29sLT5UeXBlICkgKSB7CgkJCQkJJHRleHRfY29sdW1uc1tdID0gJGNvbC0+RmllbGQ7CgkJCQl9CgkJCQkkYWxsX2NvbHVtbnNbXSA9ICRjb2wtPkZpZWxkOwoJCQkJLy8gcGhwY3M6ZW5hYmxlCgkJCX0KCQl9CgkJJHdwZGItPnN1cHByZXNzX2Vycm9ycyggJHN1cHByZXNzX2Vycm9ycyApOwoJCXJldHVybiBbICRwcmltYXJ5X2tleXMsICR0ZXh0X2NvbHVtbnMsICRhbGxfY29sdW1ucyBdOwoJfQoKCS8qKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgY29sdW1uIGlzIGNvbnNpZGVyZWQgdGV4dCBvciBub3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyBDb2x1bW4gdHlwZS4KCSAqIEByZXR1cm4gYm9vbCBUcnVlIGlmIHRleHQgY29sdW1uLCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzX3RleHRfY29sKCAkdHlwZSApIHsKCQlmb3JlYWNoICggWyAndGV4dCcsICd2YXJjaGFyJyBdIGFzICR0b2tlbiApIHsKCQkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkdHlwZSwgJHRva2VuICkgKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogRXNjYXBlcyAoYmFja3RpY2tzKSBNeVNRTCBpZGVudGlmaWVycyAoYWthIHNjaGVtYSBvYmplY3QgbmFtZXMpIC0gaS5lLiBjb2x1bW4gbmFtZXMsIHRhYmxlIG5hbWVzLCBhbmQgZGF0YWJhc2UvaW5kZXgvYWxpYXMvdmlldyBldGMgbmFtZXMuCgkgKiBTZWUgaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNS41L2VuL2lkZW50aWZpZXJzLmh0bWwKCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRpZGVudHMgQSBzaW5nbGUgaWRlbnRpZmllciBvciBhbiBhcnJheSBvZiBpZGVudGlmaWVycy4KCSAqIEByZXR1cm4gc3RyaW5nfGFycmF5IEFuIGVzY2FwZWQgc3RyaW5nIGlmIGdpdmVuIGEgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBlc2NhcGVkIHN0cmluZ3MgaWYgZ2l2ZW4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX3NxbF9pZGVudCggJGlkZW50cyApIHsKCQkkYmFja3RpY2sgPSBzdGF0aWMgZnVuY3Rpb24gKCAkdiApIHsKCQkJLy8gRXNjYXBlIGFueSBiYWNrdGlja3MgaW4gdGhlIGlkZW50aWZpZXIgYnkgZG91YmxpbmcuCgkJCXJldHVybiAnYCcgLiBzdHJfcmVwbGFjZSggJ2AnLCAnYGAnLCAkdiApIC4gJ2AnOwoJCX07CgkJaWYgKCBpc19zdHJpbmcoICRpZGVudHMgKSApIHsKCQkJcmV0dXJuICRiYWNrdGljayggJGlkZW50cyApOwoJCX0KCQlyZXR1cm4gYXJyYXlfbWFwKCAkYmFja3RpY2ssICRpZGVudHMgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGNvbG9yIGNvZGVzIGZyb20gdGhlIG9wdGlvbnMgaWYgYW55LCBhbmQgcmV0dXJucyB0aGUgcGFzc2VkIGluIGFycmF5IGNvbG9yaXplZCB3aXRoIDIgZWxlbWVudHMgcGVyIGVudHJ5LCBhIGNvbG9yIGNvZGUgKG9yICcnKSBhbmQgYSByZXNldCAob3IgJycpLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBUaGUgYXNzb2NpYXRpdmUgYXJndW1lbnQgYXJyYXkgcGFzc2VkIHRvIHRoZSBjb21tYW5kLgoJICogQHBhcmFtIGFycmF5ICRjb2xvcnMgQXJyYXkgb2YgZGVmYXVsdCBwZXJjZW50IGNvbG9yIGNvZGUgc3RyaW5ncyBrZXllZCBieSB0aGUgMyBjb2xvciBjb250ZXh0cyAndGFibGVfY29sdW1uJywgJ2lkJywgJ21hdGNoJy4KCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgY29udGFpbmluZyAzIDItZWxlbWVudCBhcnJheXMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbG9ycyggJGFzc29jX2FyZ3MsICRjb2xvcnMgKSB7CgkJJGNvbG9yX3Jlc2V0ID0gV1BfQ0xJOjpjb2xvcml6ZSggJyVuJyApOwoKCQkkY29sb3JfY29kZXMgPSBpbXBsb2RlKAoJCQknJywKCQkJYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24gKCAkdiApIHsKCQkJCQlyZXR1cm4gc3Vic3RyKCAkdiwgMSApOwoJCQkJfSwKCQkJCWFycmF5X2tleXMoIFxjbGlcQ29sb3JzOjpnZXRDb2xvcnMoKSApCgkJCSkKCQkpOwoKCQkkY29sb3JfY29kZXNfcmVnZXggPSAnL14oPzolWycgLiAkY29sb3JfY29kZXMgLiAnXSkqJC8nOwoKCQlmb3JlYWNoICggYXJyYXlfa2V5cyggJGNvbG9ycyApIGFzICRjb2xvcl9jb2wgKSB7CgkJCSRjb2xfY29sb3JfZmxhZyA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJGNvbG9yX2NvbCAuICdfY29sb3InLCBmYWxzZSApOwoJCQlpZiAoIGZhbHNlICE9PSAkY29sX2NvbG9yX2ZsYWcgKSB7CgkJCQlpZiAoICEgcHJlZ19tYXRjaCggJGNvbG9yX2NvZGVzX3JlZ2V4LCAkY29sX2NvbG9yX2ZsYWcsICRtYXRjaGVzICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVW5yZWNvZ25pemVkIHBlcmNlbnQgY29sb3IgY29kZSAnJGNvbF9jb2xvcl9mbGFnJyBmb3IgJ3skY29sb3JfY29sfV9jb2xvcicuIiApOwoJCQkJfSBlbHNlIHsKCQkJCQkkY29sb3JzWyAkY29sb3JfY29sIF0gPSAkbWF0Y2hlc1swXTsKCQkJCX0KCQkJfQoJCQkkY29sb3JzWyAkY29sb3JfY29sIF0gPSAkY29sb3JzWyAkY29sb3JfY29sIF0gPyBbIFdQX0NMSTo6Y29sb3JpemUoICRjb2xvcnNbICRjb2xvcl9jb2wgXSApLCAkY29sb3JfcmVzZXQgXSA6IFsgJycsICcnIF07CgkJfQoKCQlyZXR1cm4gJGNvbG9yczsKCX0KCgkvKioKCSAqIEhlbHBlciB0byBwbHVjayBgbXlzcWxgIG9wdGlvbnMgZnJvbSBhc3NvY2lhdGl2ZSBhcmdzIGFycmF5LgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcmdzIGFycmF5LgoJICogQHJldHVybiBhcnJheSBBcnJheSB3aXRoIGBteXNxbGAgb3B0aW9ucyBzZXQgaWYgaW4gcGFzc2VkLWluIGFzc29jaWF0aXZlIGFyZ3MgYXJyYXkuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9teXNxbF9hcmdzKCAkYXNzb2NfYXJncyApIHsKCgkJJGFsbG93ZWRfbXlzcWxfb3B0aW9ucyA9IFsKCQkJJ2F1dG8tcmVoYXNoJywKCQkJJ2F1dG8tdmVydGljYWwtb3V0cHV0JywKCQkJJ2JhdGNoJywKCQkJJ2JpbmFyeS1hcy1oZXgnLAoJCQknYmluYXJ5LW1vZGUnLAoJCQknYmluZC1hZGRyZXNzJywKCQkJJ2NoYXJhY3Rlci1zZXRzLWRpcicsCgkJCSdjb2x1bW4tbmFtZXMnLAoJCQknY29sdW1uLXR5cGUtaW5mbycsCgkJCSdjb21tZW50cycsCgkJCSdjb21wcmVzcycsCgkJCSdjb25uZWN0LWV4cGlyZWQtcGFzc3dvcmQnLAoJCQknY29ubmVjdF90aW1lb3V0JywKCQkJJ2RhdGFiYXNlJywKCQkJJ2RlYnVnJywKCQkJJ2RlYnVnLWNoZWNrJywKCQkJJ2RlYnVnLWluZm8nLAoJCQknZGVmYXVsdC1hdXRoJywKCQkJJ2RlZmF1bHQtY2hhcmFjdGVyLXNldCcsCgkJCSdkZWZhdWx0cy1leHRyYS1maWxlJywKCQkJJ2RlZmF1bHRzLWZpbGUnLAoJCQknZGVmYXVsdHMtZ3JvdXAtc3VmZml4JywKCQkJJ2RlbGltaXRlcicsCgkJCSdlbmFibGUtY2xlYXJ0ZXh0LXBsdWdpbicsCgkJCSdleGVjdXRlJywKCQkJJ2ZvcmNlJywKCQkJJ2dldC1zZXJ2ZXItcHVibGljLWtleScsCgkJCSdoZWxwJywKCQkJJ2hpc3RpZ25vcmUnLAoJCQknaG9zdCcsCgkJCSdodG1sJywKCQkJJ2lnbm9yZS1zcGFjZXMnLAoJCQknaW5pdC1jb21tYW5kJywKCQkJJ2xpbmUtbnVtYmVycycsCgkJCSdsb2NhbC1pbmZpbGUnLAoJCQknbG9naW4tcGF0aCcsCgkJCSdtYXhfYWxsb3dlZF9wYWNrZXQnLAoJCQknbWF4X2pvaW5fc2l6ZScsCgkJCSduYW1lZC1jb21tYW5kcycsCgkJCSduZXRfYnVmZmVyX2xlbmd0aCcsCgkJCSduby1iZWVwJywKCQkJJ29uZS1kYXRhYmFzZScsCgkJCSdwYWdlcicsCgkJCSdwaXBlJywKCQkJJ3BsdWdpbi1kaXInLAoJCQkncG9ydCcsCgkJCSdwcmludC1kZWZhdWx0cycsCgkJCSdwcm90b2NvbCcsCgkJCSdxdWljaycsCgkJCSdyYXcnLAoJCQkncmVjb25uZWN0JywKCQkJJ2ktYW0tYS1kdW1teScsCgkJCSdzYWZlLXVwZGF0ZXMnLAoJCQknc2VjdXJlLWF1dGgnLAoJCQknc2VsZWN0X2xpbWl0JywKCQkJJ3NlcnZlci1wdWJsaWMta2V5LXBhdGgnLAoJCQknc2hhcmVkLW1lbW9yeS1iYXNlLW5hbWUnLAoJCQknc2hvdy13YXJuaW5ncycsCgkJCSdzaWdpbnQtaWdub3JlJywKCQkJJ3NpbGVudCcsCgkJCSdza2lwLWF1dG8tcmVoYXNoJywKCQkJJ3NraXAtY29sdW1uLW5hbWVzJywKCQkJJ3NraXAtbGluZS1udW1iZXJzJywKCQkJJ3NraXAtbmFtZWQtY29tbWFuZHMnLAoJCQknc2tpcC1wYWdlcicsCgkJCSdza2lwLXJlY29ubmVjdCcsCgkJCSdzb2NrZXQnLAoJCQknc3NsLWNhJywKCQkJJ3NzbC1jYXBhdGgnLAoJCQknc3NsLWNlcnQnLAoJCQknc3NsLWNpcGhlcicsCgkJCSdzc2wtY3JsJywKCQkJJ3NzbC1jcmxwYXRoJywKCQkJJ3NzbC1maXBzLW1vZGUnLAoJCQknc3NsLWtleScsCgkJCSdzc2wtbW9kZScsCgkJCSdzeXNsb2cnLAoJCQkndGFibGUnLAoJCQkndGVlJywKCQkJJ3Rscy12ZXJzaW9uJywKCQkJJ3VuYnVmZmVyZWQnLAoJCQkndmVyYm9zZScsCgkJCSd2ZXJzaW9uJywKCQkJJ3ZlcnRpY2FsJywKCQkJJ3dhaXQnLAoJCQkneG1sJywKCQldOwoKCQkkbXlzcWxfYXJncyA9IFtdOwoKCQlmb3JlYWNoICggJGFzc29jX2FyZ3MgYXMgJG15c3FsX29wdGlvbl9rZXkgPT4gJG15c3FsX29wdGlvbl92YWx1ZSApIHsKCQkJLy8gQ2hlY2sgZmxhZ3MgdG8gbWFrZSBzdXJlIHRoZXkgb25seSBjb250YWluIHZhbGlkIG9wdGlvbnMuCgkJCWlmICggaW5fYXJyYXkoICRteXNxbF9vcHRpb25fa2V5LCAkYWxsb3dlZF9teXNxbF9vcHRpb25zLCB0cnVlICkgJiYgISBlbXB0eSggJG15c3FsX29wdGlvbl92YWx1ZSApICkgewoJCQkJJG15c3FsX2FyZ3NbICRteXNxbF9vcHRpb25fa2V5IF0gPSAkbXlzcWxfb3B0aW9uX3ZhbHVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gJG15c3FsX2FyZ3M7Cgl9CgoJLyoqCgkgKiBXcml0ZXMgb3V0IHRoZSBgLS1uby1kZWZhdWx0c2AgZmxhZyBmb3IgTXlTUUwgY29tbWFuZHMgdW5sZXNzIHRoZSAtLWRlZmF1bHRzIGZsYWcgaXMgc3BlY2lmaWVkIGZvciB0aGUgV1BfQ0xJIGNvbW1hbmQuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEFzc29jaWF0aXZlIGFyZ3MgYXJyYXkuCgkgKiBAcmV0dXJuIHN0cmluZyBFaXRoZXIgdGhlICctLW5vLWRlZmF1bHRzJyBmbGFnIGZvciB1c2UgaW4gdGhlIGNvbW1hbmQgb3IgYW4gZW1wdHkgc3RyaW5nLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAmJGFzc29jX2FyZ3MgKSB7CgoJCSRmbGFnX3N0cmluZyA9ICcgLS1uby1kZWZhdWx0cyc7CgoJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJ2RlZmF1bHRzJywgJGFzc29jX2FyZ3MgKSApIHsKCgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGVmYXVsdHMnICkgKSB7CgkJCQkkZmxhZ19zdHJpbmcgPSAnJzsKCQkJfQoKCQkJdW5zZXQoICRhc3NvY19hcmdzWydkZWZhdWx0cyddICk7CgoJCX0KCgkJcmV0dXJuICRmbGFnX3N0cmluZzsKCX0KCgkvKioKCSAqIEdldCB0aGUgcXVlcnkgdG8gY2hhbmdlIHRoZSBjdXJyZW50IFNRTCBtb2RlLCBhbmQgZW5zdXJlIGl0cyBXb3JkUHJlc3MgY29tcGF0aWJpbGl0eS4KCSAqCgkgKiBJZiBubyBtb2RlcyBhcmUgcGFzc2VkLCBpdCB3aWxsIGVuc3VyZSB0aGUgY3VycmVudCBNeVNRTCBzZXJ2ZXIgbW9kZXMgYXJlCgkgKiBjb21wYXRpYmxlLgoJICoKCSAqIENvcGllZCBhbmQgYWRhcHRlZCBmcm9tIFdvcmRQcmVzcyBDb3JlIGNvZGUuCgkgKgoJICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzL3dvcmRwcmVzcy1kZXZlbG9wL2Jsb2IvNS40LjAvc3JjL3dwLWluY2x1ZGVzL3dwLWRiLnBocCNMODE3LUw4ODAKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgVGhlIGFzc29jaWF0aXZlIGFyZ3VtZW50IGFycmF5IHBhc3NlZCB0byB0aGUgY29tbWFuZC4KCSAqIEBwYXJhbSBhcnJheSAkbW9kZXMgICAgICBPcHRpb25hbC4gQSBsaXN0IG9mIFNRTCBtb2RlcyB0byBzZXQuCgkgKiBAcmV0dXJuIHN0cmluZyBRdWVyeSBzdHJpbmcgdG8gdXNlIGZvciBzZXR0aW5nIHRoZSBTUUwgbW9kZXMgdG8gYQoJICogICAgICAgICAgICAgICAgY29tcGF0aWJsZSBzdGF0ZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9zcWxfbW9kZV9xdWVyeSggJGFzc29jX2FyZ3MsICRtb2RlcyA9IFtdICkgewoJCWlmICggZW1wdHkoICRtb2RlcyApICkgewoJCQkkbW9kZXMgPSAkdGhpcy0+Z2V0X2N1cnJlbnRfc3FsX21vZGVzKCAkYXNzb2NfYXJncyApOwoJCX0KCgkJJG1vZGVzID0gYXJyYXlfY2hhbmdlX2tleV9jYXNlKCAkbW9kZXMsIENBU0VfVVBQRVIgKTsKCgkJJGlzX21vZGVfYWRhcHRhdGlvbl9uZWVkZWQgPSBmYWxzZTsKCQlmb3JlYWNoICggJG1vZGVzIGFzICRpID0+ICRtb2RlICkgewoJCQlpZiAoIGluX2FycmF5KCAkbW9kZSwgJHRoaXMtPnNxbF9pbmNvbXBhdGlibGVfbW9kZXMsIHRydWUgKSApIHsKCQkJCXVuc2V0KCAkbW9kZXNbICRpIF0gKTsKCQkJCSRpc19tb2RlX2FkYXB0YXRpb25fbmVlZGVkID0gdHJ1ZTsKCQkJfQoJCX0KCgkJaWYgKCAhICRpc19tb2RlX2FkYXB0YXRpb25fbmVlZGVkICkgewoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknU1FMIG1vZGVzIGxvb2sgZmluZTogJXMnLAoJCQkJCWpzb25fZW5jb2RlKCAkbW9kZXMgKQoJCQkJKQoJCQkpOwoJCQlyZXR1cm4gJyc7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKAoJCQlzcHJpbnRmKAoJCQkJJ1NRTCBtb2RlIGFkYXB0YXRpb24gaXMgbmVlZGVkOiAlcyA9PiAlcycsCgkJCQlqc29uX2VuY29kZSggJHRoaXMtPmdldF9jdXJyZW50X3NxbF9tb2RlcyggJGFzc29jX2FyZ3MgKSApLAoJCQkJanNvbl9lbmNvZGUoICRtb2RlcyApCgkJCSkKCQkpOwoKCQkkbW9kZXNfc3RyID0gaW1wbG9kZSggJywnLCAkbW9kZXMgKTsKCgkJcmV0dXJuICJTRVQgU0VTU0lPTiBzcWxfbW9kZT0neyRtb2Rlc19zdHJ9JzsiOwoJfQoKCS8qKgoJICogR2V0IHRoZSBsaXN0IG9mIGN1cnJlbnQgU1FMIG1vZGVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBUaGUgYXNzb2NpYXRpdmUgYXJndW1lbnQgYXJyYXkgcGFzc2VkIHRvIHRoZSBjb21tYW5kLgoJICogQHJldHVybiBzdHJpbmdbXSBBcnJheSBvZiBTUUwgbW9kZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfY3VycmVudF9zcWxfbW9kZXMoICRhc3NvY19hcmdzICkgewoJCXN0YXRpYyAkbW9kZXMgPSBudWxsOwoKCQkvLyBNYWtlIHN1cmUgdGhlIHByb3ZpZGVkIGFyZ3VtZW50cyBkb24ndCBpbnRlcmZlcmUgd2l0aCB0aGUgZXhwZWN0ZWQKCQkvLyBvdXRwdXQgaGVyZS4KCQkkYXJncyA9IFtdOwoJCWZvcmVhY2ggKCBbXSBhcyAkYXJnICkgewoJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJGFyZyBdICkgKSB7CgkJCQkkYXJnc1sgJGFyZyBdID0gJGFzc29jX2FyZ3NbICRhcmcgXTsKCQkJfQoJCX0KCgkJaWYgKCBudWxsID09PSAkbW9kZXMgKSB7CgkJCSRtb2RlcyA9IFtdOwoKCQkJbGlzdCggJHN0ZG91dCwgJHN0ZGVyciwgJGV4aXRfY29kZSApID0gc2VsZjo6cnVuKAoJCQkJc3ByaW50ZigKCQkJCQknL3Vzci9iaW4vZW52IG15c3FsJXMgLS1uby1hdXRvLXJlaGFzaCAtLWJhdGNoIC0tc2tpcC1jb2x1bW4tbmFtZXMnLAoJCQkJCSR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICkKCQkJCSksCgkJCQlhcnJheV9tZXJnZSggJGFyZ3MsIFsgJ2V4ZWN1dGUnID0+ICdTRUxFQ1QgQEBTRVNTSU9OLnNxbF9tb2RlJyBdICksCgkJCQlmYWxzZQoJCQkpOwoKCQkJaWYgKCAkZXhpdF9jb2RlICkgewoJCQkJV1BfQ0xJOjplcnJvcigKCQkJCQknRmFpbGVkIHRvIGdldCBjdXJyZW50IFNRTCBtb2Rlcy4nCgkJCQkJLiAoICEgZW1wdHkoICRzdGRlcnIgKSA/ICIgUmVhc29uOiB7JHN0ZGVycn0iIDogJycgKSwKCQkJCQkkZXhpdF9jb2RlCgkJCQkpOwoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRzdGRvdXQgKSApIHsKCQkJCSRtb2RlcyA9IGFycmF5X2ZpbHRlcigKCQkJCQlhcnJheV9tYXAoCgkJCQkJCSd0cmltJywKCQkJCQkJcHJlZ19zcGxpdCggIi9cclxufFxufFxyfCwvIiwgJHN0ZG91dCApCgkJCQkJKQoJCQkJKTsKCQkJfQoKCQkJaWYgKCBmYWxzZSA9PT0gJG1vZGVzICkgewoJCQkJJG1vZGVzID0gW107CgkJCX0KCQl9CgoJCXJldHVybiAkbW9kZXM7Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9kYl9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9kYl9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX2RiX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdkYicsICdEQl9Db21tYW5kJyApOwo8P3BocApjbGFzcyBPeHltZWwgewoJcHJpdmF0ZSAkeG1sOwoJcHJpdmF0ZSAkZG9tOwoJcHJpdmF0ZSAkY3VycmVudF9lbGVtZW50OwoJcHJpdmF0ZSAkbGFzdF9pbnNlcnRlZDsKCXByaXZhdGUgJGdvX2RlZXBfb25fbmV4dF9lbGVtZW50ID0gMDsKCXByaXZhdGUgJGdvX3VwX29uX25leHRfZWxlbWVudCA9IDA7Cglwcml2YXRlICRuZXN0aW5nX2xldmVsID0gMDsKCXByaXZhdGUgJGNvbnRhaW5zX25lc3RpbmdfbGV2ZWwgPSAwOwoJcHJpdmF0ZSAkaW5kZW50YXRpb249ICcgICc7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT54bWwgPSAnJzsKCQkkdGhpcy0+aW5pdF9uZXdfZG9tKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHRvX3N0cmluZygpIHsKCQlyZXR1cm4gJHRoaXMtPnhtbCAuPSAkdGhpcy0+aW5kZW50KCAkdGhpcy0+eG1sX2Zyb21fZG9tKCksICR0aGlzLT5uZXN0aW5nX2xldmVsICk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIF9fY2FsbCggJG5hbWUsICRhcmdzICkgewoJCWFycmF5X3Vuc2hpZnQoICRhcmdzLCAkbmFtZSApOwoJCXJldHVybiBjYWxsX3VzZXJfZnVuY19hcnJheSggYXJyYXkoICR0aGlzLCAndGFnJyApLCAkYXJncyApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBfX2dldCggJG5hbWUgKSB7CgkJcmV0dXJuICR0aGlzLT4kbmFtZSgpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjb250YWlucygpIHsKCQkkdGhpcy0+Y29udGFpbnNfbmVzdGluZ19sZXZlbCsrOwoJCSR0aGlzLT5uZXN0aW5nX2xldmVsKys7CgkJaWYgKCAkdGhpcy0+Z29fZGVlcF9vbl9uZXh0X2VsZW1lbnQgKSB7CgkJCXRocm93IG5ldyBPeHltZWxFeGNlcHRpb24oICdjb250YWlucyBjYW5ub3QgYmUgdXNlZCBjb25zZWN1dGl2ZWx5IG1vcmUgdGhhbiBvbmNlJyApOwoJCX0KCQkkdGhpcy0+Z29fZGVlcF9vbl9uZXh0X2VsZW1lbnQrKzsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGVuZCgpIHsKCQkkdGhpcy0+Y29udGFpbnNfbmVzdGluZ19sZXZlbC0tOwoJCSR0aGlzLT5uZXN0aW5nX2xldmVsLS07CgkJaWYgKCAkdGhpcy0+Y29udGFpbnNfbmVzdGluZ19sZXZlbCA8IDAgKSB7CgkJCXRocm93IG5ldyBPeHltZWxFeGNlcHRpb24oICdlbmQgaXMgdXNlZCB3aXRob3V0IGEgbWF0Y2hpbmcgY29udGFpbnMnICk7CgkJfQoJCSR0aGlzLT5nb191cF9vbl9uZXh0X2VsZW1lbnQrKzsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHRhZyggJG5hbWUsICRjb250ZW50X29yX2F0dHJpYnV0ZXMgPSBudWxsLCAkYXR0cmlidXRlcyA9IGFycmF5KCkgKSB7CgkJbGlzdCggJGNvbnRlbnQsICRhdHRyaWJ1dGVzICkgPSAkdGhpcy0+Z2V0X2NvbnRlbnRfYW5kX2F0dHJpYnV0ZXNfZnJvbV90YWdfYXJncyggJGNvbnRlbnRfb3JfYXR0cmlidXRlcywgJGF0dHJpYnV0ZXMgKTsKCQkkaXNfb3BlbmluZyA9ICAwID09PSBzdHJwb3MoICRuYW1lLCAnb3Blbl8nICk7CgkJJGlzX2Nsb3NpbmcgPSAgMCA9PT0gc3RycG9zKCAkbmFtZSwgJ2Nsb3NlXycgKTsKCQkkbmFtZSA9IHByZWdfcmVwbGFjZSgiL14ob3BlbnxjbG9zZSlfLyIsICcnLCAkbmFtZSApOwoKCQkkZWxlbWVudCA9ICR0aGlzLT5jcmVhdGVfZWxlbWVudCggJG5hbWUsICRjb250ZW50LCAkYXR0cmlidXRlcyApOwoKCQlpZiAoICEkaXNfb3BlbmluZyAmJiAhJGlzX2Nsb3NpbmcgKQoJCQkkdGhpcy0+YWRkX2VsZW1lbnRfdG9fZG9tKCAkZWxlbWVudCApOwoJCWVsc2VpZiAoICRpc19vcGVuaW5nICkKCQkJJHRoaXMtPmFkZF9vcGVuaW5nX3RhZ19mcm9tX2VsZW1lbnQoICRlbGVtZW50ICk7CgkJZWxzZWlmICggJGlzX2Nsb3NpbmcgKQoJCQkkdGhpcy0+YWRkX2Nsb3NpbmdfdGFnX2Zyb21fdGFnX25hbWUoICRuYW1lICk7CgoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY2RhdGEoICR0ZXh0ICkgewoJCSR0aGlzLT5hZGRfZWxlbWVudF90b19kb20oICR0aGlzLT5kb20tPmNyZWF0ZUNEQVRBU2VjdGlvbiggJHRleHQgKSApOwoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdGV4dCggJHRleHQgKSB7CgkJJHRoaXMtPmFkZF9lbGVtZW50X3RvX2RvbSggJHRoaXMtPmRvbS0+Y3JlYXRlVGV4dE5vZGUoICR0ZXh0ICkgKTsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNvbW1lbnQoICR0ZXh0ICkgewoJCSR0aGlzLT5hZGRfZWxlbWVudF90b19kb20oICR0aGlzLT5kb20tPmNyZWF0ZUNvbW1lbnQoICR0ZXh0ICkgKTsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHhtbCgpIHsKCQkkdGhpcy0+YWRkX2VsZW1lbnRfdG9fZG9tKCAkdGhpcy0+ZG9tLT5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oICd4bWwnLCAndmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiJyApICk7CgkJcmV0dXJuICR0aGlzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBveHltZWwoIE94eW1lbCAkb3RoZXIgKSB7CgkJZm9yZWFjaCggJG90aGVyLT5kb20tPmNoaWxkTm9kZXMgYXMgJGNoaWxkICkgewoJCQkkY2hpbGQgPSAkdGhpcy0+ZG9tLT5pbXBvcnROb2RlKCAkY2hpbGQsIHRydWUgKTsKCQkJJHRoaXMtPmFkZF9lbGVtZW50X3RvX2RvbSggJGNoaWxkICk7CgkJfQoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcmF3KCAgJHJhd194bWwgKSB7CgkJaWYgKCAhJHJhd194bWwgKSB7CgkJCXJldHVybiAkdGhpczsKCQl9CgkJJGZyYWdtZW50ID0gJHRoaXMtPmRvbS0+Y3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwoJCSRmcmFnbWVudC0+YXBwZW5kWE1MKCRyYXdfeG1sKTsKCQkkdGhpcy0+YWRkX2VsZW1lbnRfdG9fZG9tKCAkZnJhZ21lbnQgKTsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBhZGRfZWxlbWVudF90b19kb20oICRlbGVtZW50ICkgewoJCSR0aGlzLT5tb3ZlX2N1cnJlbnRfZWxlbWVudF9kZWVwKCk7CgkJJHRoaXMtPm1vdmVfY3VycmVudF9lbGVtZW50X3VwKCk7CgkJJHRoaXMtPmxhc3RfaW5zZXJ0ZWQgPSAkdGhpcy0+Y3VycmVudF9lbGVtZW50LT5hcHBlbmRDaGlsZCgkZWxlbWVudCk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtb3ZlX2N1cnJlbnRfZWxlbWVudF9kZWVwKCkgewoJCWlmICggJHRoaXMtPmdvX2RlZXBfb25fbmV4dF9lbGVtZW50ICkgewoJCQlpZiAoICEkdGhpcy0+bGFzdF9pbnNlcnRlZCApIHsKCQkJCXRocm93IG5ldyBPeHltZWxFeGNlcHRpb24oICdjb250YWlucyBoYXMgYmVlbiB1c2VkIGJlZm9yZSBhZGRpbmcgYW55IHRhZ3MnICk7CgkJCX0KCQkJJHRoaXMtPmN1cnJlbnRfZWxlbWVudCA9ICR0aGlzLT5sYXN0X2luc2VydGVkOwoJCQkkdGhpcy0+Z29fZGVlcF9vbl9uZXh0X2VsZW1lbnQtLTsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtb3ZlX2N1cnJlbnRfZWxlbWVudF91cCgpIHsKCQlpZiAoICR0aGlzLT5nb191cF9vbl9uZXh0X2VsZW1lbnQgKSB7CgkJCXdoaWxlICggJHRoaXMtPmdvX3VwX29uX25leHRfZWxlbWVudCApIHsKCQkJCSR0aGlzLT5jdXJyZW50X2VsZW1lbnQgPSAkdGhpcy0+Y3VycmVudF9lbGVtZW50LT5wYXJlbnROb2RlOwoJCQkJJHRoaXMtPmdvX3VwX29uX25leHRfZWxlbWVudC0tOwoJCQl9CgkJfQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbnRlbnRfYW5kX2F0dHJpYnV0ZXNfZnJvbV90YWdfYXJncyggJGNvbnRlbnRfb3JfYXR0cmlidXRlcywgYXJyYXkgJGF0dHJpYnV0ZXMgKSB7CgkJJGNvbnRlbnQgPSBudWxsOwoJCWlmICggISRhdHRyaWJ1dGVzICkgewoJCQlpZiAoIGlzX2FycmF5KCAkY29udGVudF9vcl9hdHRyaWJ1dGVzICkgKQoJCQkJJGF0dHJpYnV0ZXMgPSAkY29udGVudF9vcl9hdHRyaWJ1dGVzOwoJCQllbHNlCgkJCQkkY29udGVudCA9ICRjb250ZW50X29yX2F0dHJpYnV0ZXM7CgkJfSBlbHNlIHsKCQkJJGNvbnRlbnQgPSAkY29udGVudF9vcl9hdHRyaWJ1dGVzOwoJCX0KCQlyZXR1cm4gYXJyYXkoICRjb250ZW50LCAkYXR0cmlidXRlcyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gaW5pdF9uZXdfZG9tKCkgewoJCXVuc2V0KCAkdGhpcy0+ZG9tLCAkdGhpcy0+Y3VycmVudF9lbGVtZW50ICk7CgkJJHRoaXMtPmRvbSA9IG5ldyBET01Eb2N1bWVudCgpOwoJCSR0aGlzLT5kb20tPmZvcm1hdE91dHB1dCA9IHRydWU7CgkJJHRoaXMtPmN1cnJlbnRfZWxlbWVudCA9ICR0aGlzLT5kb207CgkJJHRoaXMtPmxhc3RfaW5zZXJ0ZWQgPSBudWxsOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24geG1sX2Zyb21fZG9tKCkgewoJCWlmICggMCAhPT0gJHRoaXMtPmNvbnRhaW5zX25lc3RpbmdfbGV2ZWwgKSB7CgkJCXRocm93IG5ldyBPeHltZWxFeGNlcHRpb24oICdjb250YWlucyBhbmQgZW5kIGNhbGxzIGRvIG5vdCBtYXRjaCcgKTsKCQl9CgkJJHhtbCA9ICcnOwoJCWZvcmVhY2goICR0aGlzLT5kb20tPmNoaWxkTm9kZXMgYXMgJGNoaWxkICkgewoJCQkkeG1sIC49ICR0aGlzLT5kb20tPnNhdmVYTUwoICRjaGlsZCApIC4gIlxuIjsKCQl9CgkJcmV0dXJuICR4bWw7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVfZWxlbWVudCggJG5hbWUsICRjb250ZW50LCAkYXR0cmlidXRlcyApIHsKCQlpZiAoICFpc19udWxsKCAkY29udGVudCApICkKCQkJJGVsZW1lbnQgPSAkdGhpcy0+ZG9tLT5jcmVhdGVFbGVtZW50KCAkbmFtZSwgJGNvbnRlbnQgKTsKCQllbHNlCgkJCSRlbGVtZW50ID0gJHRoaXMtPmRvbS0+Y3JlYXRlRWxlbWVudCggJG5hbWUgKTsKCgkJZm9yZWFjaCggJGF0dHJpYnV0ZXMgYXMgJGF0dHJpYnV0ZV9uYW1lID0+ICRhdHRyaWJ1dGVfdmFsdWUgKSB7CgkJCSRlbGVtZW50LT5zZXRBdHRyaWJ1dGUoICRhdHRyaWJ1dGVfbmFtZSwgJGF0dHJpYnV0ZV92YWx1ZSApOwoJCX0KCgkJcmV0dXJuICRlbGVtZW50OwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gYWRkX29wZW5pbmdfdGFnX2Zyb21fZWxlbWVudCggJGVsZW1lbnQgKSB7CgkJJHRoaXMtPnhtbCAuPSAkdGhpcy0+aW5kZW50KCAkdGhpcy0+eG1sX2Zyb21fZG9tKCksICR0aGlzLT5uZXN0aW5nX2xldmVsICk7CgkJJHRhZyA9ICR0aGlzLT5kb20tPnNhdmVYTUwoJGVsZW1lbnQpOwoJCSR0aGlzLT54bWwgLj0gJHRoaXMtPmluZGVudCggc3RyX3JlcGxhY2UoICcvPicsICc+JywgJHRhZyApIC4gIlxuIiwgJHRoaXMtPm5lc3RpbmdfbGV2ZWwgKTsKCQkkdGhpcy0+bmVzdGluZ19sZXZlbCsrOwoJCSR0aGlzLT5pbml0X25ld19kb20oKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGFkZF9jbG9zaW5nX3RhZ19mcm9tX3RhZ19uYW1lKCAkbmFtZSApIHsKCQkkdGhpcy0+eG1sIC49ICR0aGlzLT54bWxfZnJvbV9kb20oKTsKCQkkdGhpcy0+bmVzdGluZ19sZXZlbC0tOwoJCWlmICggJHRoaXMtPm5lc3RpbmdfbGV2ZWwgPCAwICkgewoJCQkkdGhpcy0+eG1sID0gJHRoaXMtPmluZGVudCggJHRoaXMtPnhtbCwgLSR0aGlzLT5uZXN0aW5nX2xldmVsICk7CgkJCSR0aGlzLT5uZXN0aW5nX2xldmVsID0gMDsKCQl9CgkJJHRoaXMtPnhtbCAuPSAkdGhpcy0+aW5kZW50KCAiPC8kbmFtZT5cbiIsICR0aGlzLT5uZXN0aW5nX2xldmVsICk7CgkJJHRoaXMtPmluaXRfbmV3X2RvbSgpOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gaW5kZW50KCAkc3RyaW5nLCAkbGV2ZWwgKSB7CgkJaWYgKCAhJGxldmVsICkgewoJCQlyZXR1cm4gJHN0cmluZzsKCQl9CgkJJGxpbmVzID0gZXhwbG9kZSggIlxuIiwgJHN0cmluZyApOwoJCWZvcmVhY2goICRsaW5lcyBhcyAmJGxpbmUgKSB7CgkJCWlmICggIXRyaW0oICRsaW5lICkgKQoJCQkJY29udGludWU7CgkJCSRsaW5lID0gc3RyX3JlcGVhdCggJHRoaXMtPmluZGVudGF0aW9uLCAkbGV2ZWwgKSAuICRsaW5lOwoJCX0KCQlyZXR1cm4gaW1wbG9kZSggIlxuIiwgJGxpbmVzICk7Cgl9Cn0KCmNsYXNzIE94eW1lbEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7Cn0KPD9waHAKcmVxdWlyZV9vbmNlIGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL094eW1lbC5waHAnOwoKY2xhc3MgT3h5bWVsVGVzdCBleHRlbmRzIFBIUFVuaXRfRnJhbWV3b3JrX1Rlc3RDYXNlIHsKCWZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT54ID0gbmV3IE94eW1lbDsKCX0KCglmdW5jdGlvbiB0ZXN0X3htbF9hZGRzX3Byb2Nlc2luZ19pbnN0cnV0aW9uX3dpdGhfdmVyc2lvbl9hbmRfZW5jb2RpbmcoKSB7CgkJJHRoaXMtPmEoICc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PicsICR0aGlzLT54LT54bWwgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X3NlbGZfY2xvc2luZygpIHsKCQkkdGhpcy0+YSgnPGJhYmEvPicsICR0aGlzLT54LT5iYWJhKTsKCX0KCWZ1bmN0aW9uIHRlc3Rfc2VsZl9jbG9zaW5nX21ldGhvZCgpIHsKCQkkdGhpcy0+YSgnPGJhYmEvPicsICR0aGlzLT54LT5iYWJhKCkpOwoJfQoJZnVuY3Rpb24gdGVzdF9hdHRyaWJ1dGVfbm9fY29udGVudCgpIHsKCQkkdGhpcy0+YSgnPGJhYmEgYT0iYiIgYz0iZCIvPicsICR0aGlzLT54LT5iYWJhKCBhcnJheSggJ2EnID0+ICdiJywgJ2MnID0+ICdkJyApICkgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2NvbnRlbnRfbm9fYXR0cmlidXRlKCkgewoJCSR0aGlzLT5hKCc8YmFiYT5jb250ZW50PC9iYWJhPicsICR0aGlzLT54LT5iYWJhKCAnY29udGVudCcgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfZXNjYXBpaW5nX29mX2NvbnRlbnQoKSB7CgkJJHRoaXMtPmEoJzxiYWJhPiZsdDs8L2JhYmE+JywgJHRoaXMtPngtPmJhYmEoICc8JyApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9lc2NhcGluZ19vZl9hdHRyaWJ1dGVzKCkgewoJCSR0aGlzLT5hKCc8YmFiYSBhPSImbHQ7Ii8+JywgJHRoaXMtPngtPmJhYmEoIGFycmF5KCAnYScgPT4gJzwnICkgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfY29udGVudF9hbmRfYXR0cmlidXRlcygpIHsKCQkkdGhpcy0+YSgnPGJhYmEgYT0iYiIgYz0iZCI+Y29udGVudDwvYmFiYT4nLCAkdGhpcy0+eC0+YmFiYSggJ2NvbnRlbnQnLCBhcnJheSggJ2EnID0+ICdiJywgJ2MnID0+ICdkJyApICkgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2NvbnRlbnRfYW5kX2F0dHJpYnV0ZXNfZXJyb3IoKSB7CgkJJHRoaXMtPnNldEV4cGVjdGVkRXhjZXB0aW9uKCAnUEhQVW5pdF9GcmFtZXdvcmtfRXJyb3InICk7CgkJJHRoaXMtPmEoJzxiYWJhIGE9ImIiIGM9ImQiPmNvbnRlbnQ8L2JhYmE+JywgJHRoaXMtPngtPmJhYmEoIGFycmF5KCAnYScgPT4gJ2InLCAnYycgPT4gJ2QnICksICdjb250ZW50JyApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9nb19kb3duKCkgewoJCSR0aGlzLT5hKCc8YmFiYT4KICA8ZHlhZG8vPgo8L2JhYmE+JywgJHRoaXMtPngtPmJhYmEtPmNvbnRhaW5zLT5keWFkby0+ZW5kICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9nb19kb3duX2FuZF91cCgpIHsKCQkkdGhpcy0+YSgiPGxldmVsMD4KICA8bGV2ZWwxLz4KPC9sZXZlbDA+CjxsZXZlbDAvPiIsICR0aGlzLT54LT5sZXZlbDAtPmNvbnRhaW5zLT5sZXZlbDEtPmVuZC0+bGV2ZWwwICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9jZGF0YSgpIHsKCQkkdGhpcy0+YSgnPGJhYmE+PCFbQ0RBVEFbY29udGVudF1dPjwvYmFiYT4nLCAkdGhpcy0+eC0+YmFiYS0+Y29udGFpbnMtPmNkYXRhKCdjb250ZW50JyktPmVuZCk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9uZXN0ZWRfY2RhdGEoKSB7CgkJJHRoaXMtPmEoICc8IVtDREFUQVt4XV1dXT48IVtDREFUQVs+XV0+JywgJHRoaXMtPngtPmNkYXRhKCAneF1dPicgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfcmF3KCkgewoJCSR0aGlzLT5hKCc8YmFiYT4KICA8ZHlhZG8vPgo8L2JhYmE+JywgJHRoaXMtPngtPmJhYmEtPmNvbnRhaW5zLT5yYXcoJzxkeWFkbz48L2R5YWRvPicpLT5lbmQpOwoJfQoKCWZ1bmN0aW9uIHRlc3RfcmF3X2RvZXNudF9kb19hbnl0aGluZ193aXRoX2VtcHR5X2FyZygpIHsKCQkkdGhpcy0+YSgnPGJhYmEvPicsICR0aGlzLT54LT5iYWJhLT5yYXcoICcnICkgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X294eW1lbF9ucygpIHsKCQkkb3h5bWVsID0gbmV3IE94eW1lbDsKCQkkb3h5bWVsLT50YWcoICd3cDpiYWJhJyApOwoJCSR0aGlzLT5hKCAnPHdwOmJhYmEvPicsICR0aGlzLT54LT5veHltZWwoICRveHltZWwgKSApOwoJfQoKCWZ1bmN0aW9uIHhfdGVzdF9vbmx5X3VwX2Vycm9yKCkgewoJCSR0aGlzLT5hKCcnLCAkdGhpcy0+eC0+ZW5kICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9vcGVuX2luX3RoZV9lbmQoKSB7CgkJJHRoaXMtPmEoIjxiYWJhLz4KPG5ld3RhZz4iLCAkdGhpcy0+eC0+YmFiYS0+b3Blbl9uZXd0YWcgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X29wZW5fd2l0aF9hdHRyaWJ1dGVzKCkgewoJCSR0aGlzLT5hKCI8YmFiYS8+CjxuZXd0YWcgYT1cImJcIj4iLCAkdGhpcy0+eC0+YmFiYS0+b3Blbl9uZXd0YWcoIGFycmF5KCAnYScgPT4gJ2InICkgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfZG9tX29wZW5fZG9tKCkgewoJCSR0aGlzLT5hKCI8YmFiYS8+CjxuZXd0YWc+CiAgPGJhYmEvPiIsICR0aGlzLT54LT5iYWJhLT5vcGVuX25ld3RhZy0+YmFiYSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfY2xvc2VfaW5fdGhlX2JlZ2lubmluZygpIHsKCQkkdGhpcy0+YSgiPC9vbGR0YWc+CjxiYWJhLz4iLCAkdGhpcy0+eC0+Y2xvc2Vfb2xkdGFnLT5iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9kb21fY2xvc2VfZG9tKCkgewoJCSR0aGlzLT5hKCIgIDxiYWJhLz4KPC9vbGR0YWc+CjxiYWJhLz4iLCAkdGhpcy0+eC0+YmFiYS0+Y2xvc2Vfb2xkdGFnLT5iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9iYWJhKCkgewoJCSR0aGlzLT5hKCI8YT5iYWJhPHgvPjwvYT4iLCAkdGhpcy0+eC0+YSgnYmFiYScpLT5jb250YWlucy0+eC0+ZW5kICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9jb21tZW50KCkgewoJCSR0aGlzLT5hKCc8IS0tYmFiYS0tPicsICR0aGlzLT54LT5jb21tZW50KCdiYWJhJykpOwoJfQoKCWZ1bmN0aW9uIHRlc3RfdHdvX2ludm9jYXRpb25zKCkgewoJCSR0aGlzLT54LT5iYWJhKCk7CgkJJHRoaXMtPngtPmR5YWRvKCk7CgkJJHRoaXMtPmEoICI8YmFiYS8+CjxkeWFkby8+IiwgJHRoaXMtPnggKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2RvdWJsZV9lbmQoKSB7CgkJJHRoaXMtPmEoICI8b3V0PgogIDxtaWQ+CiAgICA8aW4vPgogIDwvbWlkPgo8L291dD4KPG5leHRvdXQvPiIsICR0aGlzLT54LT5vdXQtPmNvbnRhaW5zLT5taWQtPmNvbnRhaW5zLT5pbi0+ZW5kLT5lbmQtPm5leHRvdXQgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2VuZF93aXRob3V0X2NvbnRhaW5zKCkgewoJCSR0aGlzLT5zZXRFeHBlY3RlZEV4Y2VwdGlvbiggJ094eW1lbEV4Y2VwdGlvbicgKTsKCQkkdGhpcy0+eC0+ZW5kLT5iYWJhOwoJfQoKCWZ1bmN0aW9uIHRlc3RfbGVhZGluZ19jb250YWlucygpIHsKCQkkdGhpcy0+c2V0RXhwZWN0ZWRFeGNlcHRpb24oICdPeHltZWxFeGNlcHRpb24nICk7CgkJJHRoaXMtPmEoICc8YmFiYS8+JywgJHRoaXMtPngtPmNvbnRhaW5zLT5iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9jb25zZWN1dGl2ZV9jb250YWluc19zaG91bGRfZXJyb3IoKSB7CgkJJHRoaXMtPnNldEV4cGVjdGVkRXhjZXB0aW9uKCAnT3h5bWVsRXhjZXB0aW9uJyApOwoJCSR0aGlzLT54LT5iYWJhLT5jb250YWlucy0+Y29udGFpbnMtPmR5YWRvLT5lbmQtPndpbms7Cgl9CgoJZnVuY3Rpb24gdGVzdF9lbmRfd2l0aG91dF9tYXRoY2luZ19jb250YWluc19idXRfd2l0aF9lbm91Z2hfcGFyZW50cygpIHsKCQkkdGhpcy0+c2V0RXhwZWN0ZWRFeGNlcHRpb24oICdPeHltZWxFeGNlcHRpb24nICk7CgkJJHRoaXMtPngtPmNvbnRhaW5zLT5iYWJhLT5lbmQtPmVuZC0+YmFiYTsKCX0KCglmdW5jdGlvbiB0ZXN0X2NvbnRhaW5zX2FmdGVyX25ld2x5X2luaXRpYWxpemVkX2RvbV9zaG91bGRfZXJyb3IoKSB7CgkJJHRoaXMtPnNldEV4cGVjdGVkRXhjZXB0aW9uKCAnT3h5bWVsRXhjZXB0aW9uJyApOwoJCSR0aGlzLT54LT5iYWJhLT5vcGVuX3Jzcy0+Y29udGFpbnMtPmJhYmEtPmVuZDsKCX0KCglmdW5jdGlvbiB0ZXN0X25lc3RlZF9vcGVuX3RhZ3Nfc2hvdWxkX2JlX2luZGVudGVkKCkgewoJCSR0aGlzLT5hKCAiPGJhYmE+CiAgPGJhYmE+IiwgJHRoaXMtPngtPm9wZW5fYmFiYS0+b3Blbl9iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9ub3JtYWxfeG1sX2JldHdlZW5fdHdvX29wZW5pbmdfdGFnc19zaG91bGRfYmVfaW5kZW50ZWQoKSB7CgkJJHRoaXMtPmEoICI8YmFiYT4KICA8YmFiYS8+CiAgPGJhYmE+IiwgJHRoaXMtPngtPm9wZW5fYmFiYS0+YmFiYS0+b3Blbl9iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9ub3JtYWxfeG1sX2FmdGVyX29wZW5pbmdfdGFnX3Nob3VsZF9iZV9pbmRlbnRlZCgpIHsKCQkkdGhpcy0+YSggIjxiYWJhPgogIDxiYWJhLz4iLCAkdGhpcy0+eC0+b3Blbl9iYWJhLT5iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9ub3JtYWxfeG1sX2JlZm9yZV9jbG9zaW5nX3RhZ19zaG91bGRfYmVfaW5kZW50ZWQoKSB7CgkJJHRoaXMtPmEoICIgIDxiYWJhLz4KPC9iYWJhPiIsICR0aGlzLT54LT5iYWJhLT5jbG9zZV9iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF90ZXh0X3Nob3VsZF9lc2NhcGVfdGhlX2NvbnRlbnRfaW5zaWRlKCkgewoJCSR0aGlzLT5hKCAnYSAmYW1wOyBiJywgJHRoaXMtPngtPnRleHQoICdhICYgYicgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfZGFuZ2xpbmdfY29udGFpbnNfc2hvdWxkX2JlX2NhdWdodF9pbl90aGVfZW5kKCkgewoJCSR0aGlzLT5zZXRFeHBlY3RlZEV4Y2VwdGlvbiggJ094eW1lbEV4Y2VwdGlvbicgKTsKCQkkdGhpcy0+eC0+Y29udGFpbnMtPnRvX3N0cmluZygpOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gYSgkdmFsdWUsICR4KSB7CgkJJHRoaXMtPmFzc2VydEVxdWFscyggJHZhbHVlIC4gIlxuIiwgJHgtPnRvX3N0cmluZygpKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFBzclxMb2c7CgpjbGFzcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCnsKfQo8P3BocAoKbmFtZXNwYWNlIFBzclxMb2c7CgovKioKICogRGVzY3JpYmVzIGEgbG9nZ2VyLWF3YXJlIGluc3RhbmNlLgogKi8KaW50ZXJmYWNlIExvZ2dlckF3YXJlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU2V0cyBhIGxvZ2dlciBpbnN0YW5jZSBvbiB0aGUgb2JqZWN0LgogICAgICoKICAgICAqIEBwYXJhbSBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcgogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9nZ2VyKExvZ2dlckludGVyZmFjZSAkbG9nZ2VyKTsKfQo8P3BocAoKbmFtZXNwYWNlIFBzclxMb2c7CgovKioKICogQmFzaWMgSW1wbGVtZW50YXRpb24gb2YgTG9nZ2VyQXdhcmVJbnRlcmZhY2UuCiAqLwp0cmFpdCBMb2dnZXJBd2FyZVRyYWl0CnsKICAgIC8qKgogICAgICogVGhlIGxvZ2dlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIExvZ2dlckludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbG9nZ2VyOwoKICAgIC8qKgogICAgICogU2V0cyBhIGxvZ2dlci4KICAgICAqCiAgICAgKiBAcGFyYW0gTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvZ2dlcihMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcikKICAgIHsKICAgICAgICAkdGhpcy0+bG9nZ2VyID0gJGxvZ2dlcjsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFBzclxMb2c7CgovKioKICogVGhpcyBpcyBhIHNpbXBsZSBMb2dnZXIgaW1wbGVtZW50YXRpb24gdGhhdCBvdGhlciBMb2dnZXJzIGNhbiBpbmhlcml0IGZyb20uCiAqCiAqIEl0IHNpbXBseSBkZWxlZ2F0ZXMgYWxsIGxvZy1sZXZlbC1zcGVjaWZpYyBtZXRob2RzIHRvIHRoZSBgbG9nYCBtZXRob2QgdG8KICogcmVkdWNlIGJvaWxlcnBsYXRlIGNvZGUgdGhhdCBhIHNpbXBsZSBMb2dnZXIgdGhhdCBkb2VzIHRoZSBzYW1lIHRoaW5nIHdpdGgKICogbWVzc2FnZXMgcmVnYXJkbGVzcyBvZiB0aGUgZXJyb3IgbGV2ZWwgaGFzIHRvIGltcGxlbWVudC4KICovCmFic3RyYWN0IGNsYXNzIEFic3RyYWN0TG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW1lcmdlbmN5KCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6RU1FUkdFTkNZLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkuCiAgICAgKgogICAgICogRXhhbXBsZTogRW50aXJlIHdlYnNpdGUgZG93biwgZGF0YWJhc2UgdW5hdmFpbGFibGUsIGV0Yy4gVGhpcyBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhlIFNNUyBhbGVydHMgYW5kIHdha2UgeW91IHVwLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWxlcnQoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpBTEVSVCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyaXRpY2FsIGNvbmRpdGlvbnMuCiAgICAgKgogICAgICogRXhhbXBsZTogQXBwbGljYXRpb24gY29tcG9uZW50IHVuYXZhaWxhYmxlLCB1bmV4cGVjdGVkIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyaXRpY2FsKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6Q1JJVElDQUwsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW50aW1lIGVycm9ycyB0aGF0IGRvIG5vdCByZXF1aXJlIGltbWVkaWF0ZSBhY3Rpb24gYnV0IHNob3VsZCB0eXBpY2FsbHkKICAgICAqIGJlIGxvZ2dlZCBhbmQgbW9uaXRvcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXJyb3IoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpFUlJPUiwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbmFsIG9jY3VycmVuY2VzIHRoYXQgYXJlIG5vdCBlcnJvcnMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlIG9mIGRlcHJlY2F0ZWQgQVBJcywgcG9vciB1c2Ugb2YgYW4gQVBJLCB1bmRlc2lyYWJsZSB0aGluZ3MKICAgICAqIHRoYXQgYXJlIG5vdCBuZWNlc3NhcmlseSB3cm9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpXQVJOSU5HLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogTm9ybWFsIGJ1dCBzaWduaWZpY2FudCBldmVudHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpOT1RJQ0UsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcmVzdGluZyBldmVudHMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlciBsb2dzIGluLCBTUUwgbG9ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluZm8oJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpJTkZPLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogRGV0YWlsZWQgZGVidWcgaW5mb3JtYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWJ1ZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkRFQlVHLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgUHNyXExvZzsKCi8qKgogKiBEZXNjcmliZXMgYSBsb2dnZXIgaW5zdGFuY2UuCiAqCiAqIFRoZSBtZXNzYWdlIE1VU1QgYmUgYSBzdHJpbmcgb3Igb2JqZWN0IGltcGxlbWVudGluZyBfX3RvU3RyaW5nKCkuCiAqCiAqIFRoZSBtZXNzYWdlIE1BWSBjb250YWluIHBsYWNlaG9sZGVycyBpbiB0aGUgZm9ybToge2Zvb30gd2hlcmUgZm9vCiAqIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIGNvbnRleHQgZGF0YSBpbiBrZXkgImZvbyIuCiAqCiAqIFRoZSBjb250ZXh0IGFycmF5IGNhbiBjb250YWluIGFyYml0cmFyeSBkYXRhLiBUaGUgb25seSBhc3N1bXB0aW9uIHRoYXQKICogY2FuIGJlIG1hZGUgYnkgaW1wbGVtZW50b3JzIGlzIHRoYXQgaWYgYW4gRXhjZXB0aW9uIGluc3RhbmNlIGlzIGdpdmVuCiAqIHRvIHByb2R1Y2UgYSBzdGFjayB0cmFjZSwgaXQgTVVTVCBiZSBpbiBhIGtleSBuYW1lZCAiZXhjZXB0aW9uIi4KICoKICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9waHAtZmlnL2ZpZy1zdGFuZGFyZHMvYmxvYi9tYXN0ZXIvYWNjZXB0ZWQvUFNSLTMtbG9nZ2VyLWludGVyZmFjZS5tZAogKiBmb3IgdGhlIGZ1bGwgaW50ZXJmYWNlIHNwZWNpZmljYXRpb24uCiAqLwppbnRlcmZhY2UgTG9nZ2VySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW1lcmdlbmN5KCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwoKICAgIC8qKgogICAgICogQWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkuCiAgICAgKgogICAgICogRXhhbXBsZTogRW50aXJlIHdlYnNpdGUgZG93biwgZGF0YWJhc2UgdW5hdmFpbGFibGUsIGV0Yy4gVGhpcyBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhlIFNNUyBhbGVydHMgYW5kIHdha2UgeW91IHVwLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWxlcnQoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBDcml0aWNhbCBjb25kaXRpb25zLgogICAgICoKICAgICAqIEV4YW1wbGU6IEFwcGxpY2F0aW9uIGNvbXBvbmVudCB1bmF2YWlsYWJsZSwgdW5leHBlY3RlZCBleGNlcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcml0aWNhbCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIFJ1bnRpbWUgZXJyb3JzIHRoYXQgZG8gbm90IHJlcXVpcmUgaW1tZWRpYXRlIGFjdGlvbiBidXQgc2hvdWxkIHR5cGljYWxseQogICAgICogYmUgbG9nZ2VkIGFuZCBtb25pdG9yZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbmFsIG9jY3VycmVuY2VzIHRoYXQgYXJlIG5vdCBlcnJvcnMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlIG9mIGRlcHJlY2F0ZWQgQVBJcywgcG9vciB1c2Ugb2YgYW4gQVBJLCB1bmRlc2lyYWJsZSB0aGluZ3MKICAgICAqIHRoYXQgYXJlIG5vdCBuZWNlc3NhcmlseSB3cm9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdGljZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIEludGVyZXN0aW5nIGV2ZW50cy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBVc2VyIGxvZ3MgaW4sIFNRTCBsb2dzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5mbygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIERldGFpbGVkIGRlYnVnIGluZm9ybWF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVidWcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICRsZXZlbAogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcUHNyXExvZ1xJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUHNyXExvZzsKCi8qKgogKiBUaGlzIExvZ2dlciBjYW4gYmUgdXNlZCB0byBhdm9pZCBjb25kaXRpb25hbCBsb2cgY2FsbHMuCiAqCiAqIExvZ2dpbmcgc2hvdWxkIGFsd2F5cyBiZSBvcHRpb25hbCwgYW5kIGlmIG5vIGxvZ2dlciBpcyBwcm92aWRlZCB0byB5b3VyCiAqIGxpYnJhcnkgY3JlYXRpbmcgYSBOdWxsTG9nZ2VyIGluc3RhbmNlIHRvIGhhdmUgc29tZXRoaW5nIHRvIHRocm93IGxvZ3MgYXQKICogaXMgYSBnb29kIHdheSB0byBhdm9pZCBsaXR0ZXJpbmcgeW91ciBjb2RlIHdpdGggYGlmICgkdGhpcy0+bG9nZ2VyKSB7IH1gCiAqIGJsb2Nrcy4KICovCmNsYXNzIE51bGxMb2dnZXIgZXh0ZW5kcyBBYnN0cmFjdExvZ2dlcgp7CiAgICAvKioKICAgICAqIExvZ3Mgd2l0aCBhbiBhcmJpdHJhcnkgbGV2ZWwuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxQc3JcTG9nXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9nKCRsZXZlbCwgJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAvLyBub29wCiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKLyoqCiAqIERlc2NyaWJlcyBsb2cgbGV2ZWxzLgogKi8KY2xhc3MgTG9nTGV2ZWwKewogICAgY29uc3QgRU1FUkdFTkNZID0gJ2VtZXJnZW5jeSc7CiAgICBjb25zdCBBTEVSVCAgICAgPSAnYWxlcnQnOwogICAgY29uc3QgQ1JJVElDQUwgID0gJ2NyaXRpY2FsJzsKICAgIGNvbnN0IEVSUk9SICAgICA9ICdlcnJvcic7CiAgICBjb25zdCBXQVJOSU5HICAgPSAnd2FybmluZyc7CiAgICBjb25zdCBOT1RJQ0UgICAgPSAnbm90aWNlJzsKICAgIGNvbnN0IElORk8gICAgICA9ICdpbmZvJzsKICAgIGNvbnN0IERFQlVHICAgICA9ICdkZWJ1Zyc7Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKLyoqCiAqIFRoaXMgaXMgYSBzaW1wbGUgTG9nZ2VyIHRyYWl0IHRoYXQgY2xhc3NlcyB1bmFibGUgdG8gZXh0ZW5kIEFic3RyYWN0TG9nZ2VyCiAqIChiZWNhdXNlIHRoZXkgZXh0ZW5kIGFub3RoZXIgY2xhc3MsIGV0YykgY2FuIGluY2x1ZGUuCiAqCiAqIEl0IHNpbXBseSBkZWxlZ2F0ZXMgYWxsIGxvZy1sZXZlbC1zcGVjaWZpYyBtZXRob2RzIHRvIHRoZSBgbG9nYCBtZXRob2QgdG8KICogcmVkdWNlIGJvaWxlcnBsYXRlIGNvZGUgdGhhdCBhIHNpbXBsZSBMb2dnZXIgdGhhdCBkb2VzIHRoZSBzYW1lIHRoaW5nIHdpdGgKICogbWVzc2FnZXMgcmVnYXJkbGVzcyBvZiB0aGUgZXJyb3IgbGV2ZWwgaGFzIHRvIGltcGxlbWVudC4KICovCnRyYWl0IExvZ2dlclRyYWl0CnsKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVtZXJnZW5jeSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkVNRVJHRU5DWSwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEFjdGlvbiBtdXN0IGJlIHRha2VuIGltbWVkaWF0ZWx5LgogICAgICoKICAgICAqIEV4YW1wbGU6IEVudGlyZSB3ZWJzaXRlIGRvd24sIGRhdGFiYXNlIHVuYXZhaWxhYmxlLCBldGMuIFRoaXMgc2hvdWxkCiAgICAgKiB0cmlnZ2VyIHRoZSBTTVMgYWxlcnRzIGFuZCB3YWtlIHlvdSB1cC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGVydCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkFMRVJULCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JpdGljYWwgY29uZGl0aW9ucy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBBcHBsaWNhdGlvbiBjb21wb25lbnQgdW5hdmFpbGFibGUsIHVuZXhwZWN0ZWQgZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyaXRpY2FsKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6Q1JJVElDQUwsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW50aW1lIGVycm9ycyB0aGF0IGRvIG5vdCByZXF1aXJlIGltbWVkaWF0ZSBhY3Rpb24gYnV0IHNob3VsZCB0eXBpY2FsbHkKICAgICAqIGJlIGxvZ2dlZCBhbmQgbW9uaXRvcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVycm9yKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6RVJST1IsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGNlcHRpb25hbCBvY2N1cnJlbmNlcyB0aGF0IGFyZSBub3QgZXJyb3JzLgogICAgICoKICAgICAqIEV4YW1wbGU6IFVzZSBvZiBkZXByZWNhdGVkIEFQSXMsIHBvb3IgdXNlIG9mIGFuIEFQSSwgdW5kZXNpcmFibGUgdGhpbmdzCiAgICAgKiB0aGF0IGFyZSBub3QgbmVjZXNzYXJpbHkgd3JvbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FybmluZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OldBUk5JTkcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpOT1RJQ0UsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcmVzdGluZyBldmVudHMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlciBsb2dzIGluLCBTUUwgbG9ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbmZvKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6SU5GTywgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIERldGFpbGVkIGRlYnVnIGluZm9ybWF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlYnVnKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6REVCVUcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgJGxldmVsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcUHNyXExvZ1xJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSlNPTiBMaW50IHBhY2thZ2UuCiAqCiAqIChjKSBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU2VsZFxKc29uTGludDsKdXNlIHN0ZENsYXNzOwoKLyoqCiAqIFBhcnNlciBjbGFzcwogKgogKiBFeGFtcGxlOgogKgogKiAkcGFyc2VyID0gbmV3IEpzb25QYXJzZXIoKTsKICogLy8gcmV0dXJucyBudWxsIGlmIGl0J3MgdmFsaWQganNvbiwgb3IgYW4gZXJyb3Igb2JqZWN0CiAqICRwYXJzZXItPmxpbnQoJGpzb24pOwogKiAvLyByZXR1cm5zIHBhcnNlZCBqc29uLCBsaWtlIGpzb25fZGVjb2RlIGRvZXMsIGJ1dCBzbG93ZXIsIHRocm93cyBleGNlcHRpb25zIG9uIGZhaWx1cmUuCiAqICRwYXJzZXItPnBhcnNlKCRqc29uKTsKICoKICogUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3phYWNoL2pzb25saW50CiAqLwpjbGFzcyBKc29uUGFyc2VyCnsKICAgIGNvbnN0IERFVEVDVF9LRVlfQ09ORkxJQ1RTID0gMTsKICAgIGNvbnN0IEFMTE9XX0RVUExJQ0FURV9LRVlTID0gMjsKICAgIGNvbnN0IFBBUlNFX1RPX0FTU09DID0gNDsKCiAgICBwcml2YXRlICRsZXhlcjsKCiAgICBwcml2YXRlICRmbGFnczsKICAgIHByaXZhdGUgJHN0YWNrOwogICAgcHJpdmF0ZSAkdnN0YWNrOyAvLyBzZW1hbnRpYyB2YWx1ZSBzdGFjawogICAgcHJpdmF0ZSAkbHN0YWNrOyAvLyBsb2NhdGlvbiBzdGFjawoKICAgIC8qKgogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHN0cmluZywgaW50PgogICAgICovCiAgICBwcml2YXRlICRzeW1ib2xzID0gYXJyYXkoCiAgICAgICAgJ2Vycm9yJyAgICAgICAgICAgICAgICAgPT4gMiwKICAgICAgICAnSlNPTlN0cmluZycgICAgICAgICAgICA9PiAzLAogICAgICAgICdTVFJJTkcnICAgICAgICAgICAgICAgID0+IDQsCiAgICAgICAgJ0pTT05OdW1iZXInICAgICAgICAgICAgPT4gNSwKICAgICAgICAnTlVNQkVSJyAgICAgICAgICAgICAgICA9PiA2LAogICAgICAgICdKU09OTnVsbExpdGVyYWwnICAgICAgID0+IDcsCiAgICAgICAgJ05VTEwnICAgICAgICAgICAgICAgICAgPT4gOCwKICAgICAgICAnSlNPTkJvb2xlYW5MaXRlcmFsJyAgICA9PiA5LAogICAgICAgICdUUlVFJyAgICAgICAgICAgICAgICAgID0+IDEwLAogICAgICAgICdGQUxTRScgICAgICAgICAgICAgICAgID0+IDExLAogICAgICAgICdKU09OVGV4dCcgICAgICAgICAgICAgID0+IDEyLAogICAgICAgICdKU09OVmFsdWUnICAgICAgICAgICAgID0+IDEzLAogICAgICAgICdFT0YnICAgICAgICAgICAgICAgICAgID0+IDE0LAogICAgICAgICdKU09OT2JqZWN0JyAgICAgICAgICAgID0+IDE1LAogICAgICAgICdKU09OQXJyYXknICAgICAgICAgICAgID0+IDE2LAogICAgICAgICd7JyAgICAgICAgICAgICAgICAgICAgID0+IDE3LAogICAgICAgICd9JyAgICAgICAgICAgICAgICAgICAgID0+IDE4LAogICAgICAgICdKU09OTWVtYmVyTGlzdCcgICAgICAgID0+IDE5LAogICAgICAgICdKU09OTWVtYmVyJyAgICAgICAgICAgID0+IDIwLAogICAgICAgICc6JyAgICAgICAgICAgICAgICAgICAgID0+IDIxLAogICAgICAgICcsJyAgICAgICAgICAgICAgICAgICAgID0+IDIyLAogICAgICAgICdbJyAgICAgICAgICAgICAgICAgICAgID0+IDIzLAogICAgICAgICddJyAgICAgICAgICAgICAgICAgICAgID0+IDI0LAogICAgICAgICdKU09ORWxlbWVudExpc3QnICAgICAgID0+IDI1LAogICAgICAgICckYWNjZXB0JyAgICAgICAgICAgICAgID0+IDAsCiAgICAgICAgJyRlbmQnICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICk7CgogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8aW50LCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJHRlcm1pbmFsc18gPSBhcnJheSgKICAgICAgICAyICAgPT4gImVycm9yIiwKICAgICAgICA0ICAgPT4gIlNUUklORyIsCiAgICAgICAgNiAgID0+ICJOVU1CRVIiLAogICAgICAgIDggICA9PiAiTlVMTCIsCiAgICAgICAgMTAgID0+ICJUUlVFIiwKICAgICAgICAxMSAgPT4gIkZBTFNFIiwKICAgICAgICAxNCAgPT4gIkVPRiIsCiAgICAgICAgMTcgID0+ICJ7IiwKICAgICAgICAxOCAgPT4gIn0iLAogICAgICAgIDIxICA9PiAiOiIsCiAgICAgICAgMjIgID0+ICIsIiwKICAgICAgICAyMyAgPT4gIlsiLAogICAgICAgIDI0ICA9PiAiXSIsCiAgICApOwoKICAgIHByaXZhdGUgJHByb2R1Y3Rpb25zXyA9IGFycmF5KAogICAgICAgIDAsCiAgICAgICAgYXJyYXkoMywgMSksCiAgICAgICAgYXJyYXkoNSwgMSksCiAgICAgICAgYXJyYXkoNywgMSksCiAgICAgICAgYXJyYXkoOSwgMSksCiAgICAgICAgYXJyYXkoOSwgMSksCiAgICAgICAgYXJyYXkoMTIsIDIpLAogICAgICAgIGFycmF5KDEzLCAxKSwKICAgICAgICBhcnJheSgxMywgMSksCiAgICAgICAgYXJyYXkoMTMsIDEpLAogICAgICAgIGFycmF5KDEzLCAxKSwKICAgICAgICBhcnJheSgxMywgMSksCiAgICAgICAgYXJyYXkoMTMsIDEpLAogICAgICAgIGFycmF5KDE1LCAyKSwKICAgICAgICBhcnJheSgxNSwgMyksCiAgICAgICAgYXJyYXkoMjAsIDMpLAogICAgICAgIGFycmF5KDE5LCAxKSwKICAgICAgICBhcnJheSgxOSwgMyksCiAgICAgICAgYXJyYXkoMTYsIDIpLAogICAgICAgIGFycmF5KDE2LCAzKSwKICAgICAgICBhcnJheSgyNSwgMSksCiAgICAgICAgYXJyYXkoMjUsIDMpCiAgICApOwoKICAgIHByaXZhdGUgJHRhYmxlID0gYXJyYXkoYXJyYXkoMyA9PiA1LCA0ID0+IGFycmF5KDEsMTIpLCA1ID0+IDYsIDYgPT4gYXJyYXkoMSwxMyksIDcgPT4gMywgOCA9PiBhcnJheSgxLDkpLCA5ID0+IDQsIDEwID0+IGFycmF5KDEsMTApLCAxMSA9PiBhcnJheSgxLDExKSwgMTIgPT4gMSwgMTMgPT4gMiwgMTUgPT4gNywgMTYgPT4gOCwgMTcgPT4gYXJyYXkoMSwxNCksIDIzID0+IGFycmF5KDEsMTUpKSwgYXJyYXkoIDEgPT4gYXJyYXkoMykpLCBhcnJheSggMTQgPT4gYXJyYXkoMSwxNikpLCBhcnJheSggMTQgPT4gYXJyYXkoMiw3KSwgMTggPT4gYXJyYXkoMiw3KSwgMjIgPT4gYXJyYXkoMiw3KSwgMjQgPT4gYXJyYXkoMiw3KSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDgpLCAxOCA9PiBhcnJheSgyLDgpLCAyMiA9PiBhcnJheSgyLDgpLCAyNCA9PiBhcnJheSgyLDgpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsOSksIDE4ID0+IGFycmF5KDIsOSksIDIyID0+IGFycmF5KDIsOSksIDI0ID0+IGFycmF5KDIsOSkpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwxMCksIDE4ID0+IGFycmF5KDIsMTApLCAyMiA9PiBhcnJheSgyLDEwKSwgMjQgPT4gYXJyYXkoMiwxMCkpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwxMSksIDE4ID0+IGFycmF5KDIsMTEpLCAyMiA9PiBhcnJheSgyLDExKSwgMjQgPT4gYXJyYXkoMiwxMSkpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwxMiksIDE4ID0+IGFycmF5KDIsMTIpLCAyMiA9PiBhcnJheSgyLDEyKSwgMjQgPT4gYXJyYXkoMiwxMikpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwzKSwgMTggPT4gYXJyYXkoMiwzKSwgMjIgPT4gYXJyYXkoMiwzKSwgMjQgPT4gYXJyYXkoMiwzKSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDQpLCAxOCA9PiBhcnJheSgyLDQpLCAyMiA9PiBhcnJheSgyLDQpLCAyNCA9PiBhcnJheSgyLDQpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsNSksIDE4ID0+IGFycmF5KDIsNSksIDIyID0+IGFycmF5KDIsNSksIDI0ID0+IGFycmF5KDIsNSkpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwxKSwgMTggPT4gYXJyYXkoMiwxKSwgMjEgPT4gYXJyYXkoMiwxKSwgMjIgPT4gYXJyYXkoMiwxKSwgMjQgPT4gYXJyYXkoMiwxKSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDIpLCAxOCA9PiBhcnJheSgyLDIpLCAyMiA9PiBhcnJheSgyLDIpLCAyNCA9PiBhcnJheSgyLDIpKSwgYXJyYXkoIDMgPT4gMjAsIDQgPT4gYXJyYXkoMSwxMiksIDE4ID0+IGFycmF5KDEsMTcpLCAxOSA9PiAxOCwgMjAgPT4gMTkgKSwgYXJyYXkoIDMgPT4gNSwgNCA9PiBhcnJheSgxLDEyKSwgNSA9PiA2LCA2ID0+IGFycmF5KDEsMTMpLCA3ID0+IDMsIDggPT4gYXJyYXkoMSw5KSwgOSA9PiA0LCAxMCA9PiBhcnJheSgxLDEwKSwgMTEgPT4gYXJyYXkoMSwxMSksIDEzID0+IDIzLCAxNSA9PiA3LCAxNiA9PiA4LCAxNyA9PiBhcnJheSgxLDE0KSwgMjMgPT4gYXJyYXkoMSwxNSksIDI0ID0+IGFycmF5KDEsMjEpLCAyNSA9PiAyMiApLCBhcnJheSggMSA9PiBhcnJheSgyLDYpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsMTMpLCAxOCA9PiBhcnJheSgyLDEzKSwgMjIgPT4gYXJyYXkoMiwxMyksIDI0ID0+IGFycmF5KDIsMTMpKSwgYXJyYXkoIDE4ID0+IGFycmF5KDEsMjQpLCAyMiA9PiBhcnJheSgxLDI1KSksIGFycmF5KCAxOCA9PiBhcnJheSgyLDE2KSwgMjIgPT4gYXJyYXkoMiwxNikpLCBhcnJheSggMjEgPT4gYXJyYXkoMSwyNikpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwxOCksIDE4ID0+IGFycmF5KDIsMTgpLCAyMiA9PiBhcnJheSgyLDE4KSwgMjQgPT4gYXJyYXkoMiwxOCkpLCBhcnJheSggMjIgPT4gYXJyYXkoMSwyOCksIDI0ID0+IGFycmF5KDEsMjcpKSwgYXJyYXkoIDIyID0+IGFycmF5KDIsMjApLCAyNCA9PiBhcnJheSgyLDIwKSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDE0KSwgMTggPT4gYXJyYXkoMiwxNCksIDIyID0+IGFycmF5KDIsMTQpLCAyNCA9PiBhcnJheSgyLDE0KSksIGFycmF5KCAzID0+IDIwLCA0ID0+IGFycmF5KDEsMTIpLCAyMCA9PiAyOSApLCBhcnJheSggMyA9PiA1LCA0ID0+IGFycmF5KDEsMTIpLCA1ID0+IDYsIDYgPT4gYXJyYXkoMSwxMyksIDcgPT4gMywgOCA9PiBhcnJheSgxLDkpLCA5ID0+IDQsIDEwID0+IGFycmF5KDEsMTApLCAxMSA9PiBhcnJheSgxLDExKSwgMTMgPT4gMzAsIDE1ID0+IDcsIDE2ID0+IDgsIDE3ID0+IGFycmF5KDEsMTQpLCAyMyA9PiBhcnJheSgxLDE1KSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDE5KSwgMTggPT4gYXJyYXkoMiwxOSksIDIyID0+IGFycmF5KDIsMTkpLCAyNCA9PiBhcnJheSgyLDE5KSksIGFycmF5KCAzID0+IDUsIDQgPT4gYXJyYXkoMSwxMiksIDUgPT4gNiwgNiA9PiBhcnJheSgxLDEzKSwgNyA9PiAzLCA4ID0+IGFycmF5KDEsOSksIDkgPT4gNCwgMTAgPT4gYXJyYXkoMSwxMCksIDExID0+IGFycmF5KDEsMTEpLCAxMyA9PiAzMSwgMTUgPT4gNywgMTYgPT4gOCwgMTcgPT4gYXJyYXkoMSwxNCksIDIzID0+IGFycmF5KDEsMTUpKSwgYXJyYXkoIDE4ID0+IGFycmF5KDIsMTcpLCAyMiA9PiBhcnJheSgyLDE3KSksIGFycmF5KCAxOCA9PiBhcnJheSgyLDE1KSwgMjIgPT4gYXJyYXkoMiwxNSkpLCBhcnJheSggMjIgPT4gYXJyYXkoMiwyMSksIDI0ID0+IGFycmF5KDIsMjEpKSwKICAgICk7CgogICAgcHJpdmF0ZSAkZGVmYXVsdEFjdGlvbnMgPSBhcnJheSgKICAgICAgICAxNiA9PiBhcnJheSgyLCA2KQogICAgKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICRpbnB1dCBKU09OIHN0cmluZwogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICAgICAgJGZsYWdzIEJpdG1hc2sgb2YgcGFyc2UvbGludCBvcHRpb25zIChzZWUgY29uc3RhbnRzIG9mIHRoaXMgY2xhc3MpCiAgICAgKiBAcmV0dXJuIG51bGx8UGFyc2luZ0V4Y2VwdGlvbiBudWxsIGlmIG5vIGVycm9yIGlzIGZvdW5kLCBhIFBhcnNpbmdFeGNlcHRpb24gY29udGFpbmluZyBhbGwgZGV0YWlscyBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxpbnQoJGlucHV0LCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5wYXJzZSgkaW5wdXQsICRmbGFncyk7CiAgICAgICAgfSBjYXRjaCAoUGFyc2luZ0V4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICByZXR1cm4gJGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRpbnB1dCBKU09OIHN0cmluZwogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICRmbGFncyBCaXRtYXNrIG9mIHBhcnNlL2xpbnQgb3B0aW9ucyAoc2VlIGNvbnN0YW50cyBvZiB0aGlzIGNsYXNzKQogICAgICogQHJldHVybiBtaXhlZAogICAgICogQHRocm93cyBQYXJzaW5nRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZSgkaW5wdXQsICRmbGFncyA9IDApCiAgICB7CiAgICAgICAgJHRoaXMtPmZhaWxPbkJPTSgkaW5wdXQpOwoKICAgICAgICAkdGhpcy0+ZmxhZ3MgPSAkZmxhZ3M7CgogICAgICAgICR0aGlzLT5zdGFjayA9IGFycmF5KDApOwogICAgICAgICR0aGlzLT52c3RhY2sgPSBhcnJheShudWxsKTsKICAgICAgICAkdGhpcy0+bHN0YWNrID0gYXJyYXkoKTsKCiAgICAgICAgJHl5dGV4dCA9ICcnOwogICAgICAgICR5eWxpbmVubyA9IDA7CiAgICAgICAgJHl5bGVuZyA9IDA7CiAgICAgICAgJHJlY292ZXJpbmcgPSAwOwogICAgICAgICRURVJST1IgPSAyOwogICAgICAgICRFT0YgPSAxOwoKICAgICAgICAkdGhpcy0+bGV4ZXIgPSBuZXcgTGV4ZXIoKTsKICAgICAgICAkdGhpcy0+bGV4ZXItPnNldElucHV0KCRpbnB1dCk7CgogICAgICAgICR5eWxvYyA9ICR0aGlzLT5sZXhlci0+eXlsbG9jOwogICAgICAgICR0aGlzLT5sc3RhY2tbXSA9ICR5eWxvYzsKCiAgICAgICAgJHN5bWJvbCA9IG51bGw7CiAgICAgICAgJHByZUVycm9yU3ltYm9sID0gbnVsbDsKICAgICAgICAkc3RhdGUgPSBudWxsOwogICAgICAgICRhY3Rpb24gPSBudWxsOwogICAgICAgICRhID0gbnVsbDsKICAgICAgICAkciA9IG51bGw7CiAgICAgICAgJHl5dmFsID0gbmV3IHN0ZENsYXNzOwogICAgICAgICRwID0gbnVsbDsKICAgICAgICAkbGVuID0gbnVsbDsKICAgICAgICAkbmV3U3RhdGUgPSBudWxsOwogICAgICAgICRleHBlY3RlZCA9IG51bGw7CiAgICAgICAgJGVyclN0ciA9IG51bGw7CgogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIC8vIHJldHJpZXZlIHN0YXRlIG51bWJlciBmcm9tIHRvcCBvZiBzdGFjawogICAgICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c3RhY2tbXGNvdW50KCR0aGlzLT5zdGFjayktMV07CgogICAgICAgICAgICAvLyB1c2UgZGVmYXVsdCBhY3Rpb25zIGlmIGF2YWlsYWJsZQogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmRlZmF1bHRBY3Rpb25zWyRzdGF0ZV0pKSB7CiAgICAgICAgICAgICAgICAkYWN0aW9uID0gJHRoaXMtPmRlZmF1bHRBY3Rpb25zWyRzdGF0ZV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJHN5bWJvbCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHN5bWJvbCA9ICR0aGlzLT5sZXgoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHJlYWQgYWN0aW9uIGZvciBjdXJyZW50IHN0YXRlIGFuZCBmaXJzdCBpbnB1dAogICAgICAgICAgICAgICAgJGFjdGlvbiA9IGlzc2V0KCR0aGlzLT50YWJsZVskc3RhdGVdWyRzeW1ib2xdKSA/ICR0aGlzLT50YWJsZVskc3RhdGVdWyRzeW1ib2xdIDogZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGhhbmRsZSBwYXJzZSBlcnJvcgogICAgICAgICAgICBpZiAoISRhY3Rpb24gfHwgISRhY3Rpb25bMF0pIHsKICAgICAgICAgICAgICAgIGlmICghJHJlY292ZXJpbmcpIHsKICAgICAgICAgICAgICAgICAgICAvLyBSZXBvcnQgZXJyb3IKICAgICAgICAgICAgICAgICAgICAkZXhwZWN0ZWQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT50YWJsZVskc3RhdGVdIGFzICRwID0+ICRpZ25vcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT50ZXJtaW5hbHNfWyRwXSkgJiYgJHAgPiAyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXhwZWN0ZWRbXSA9ICInIiAuICR0aGlzLT50ZXJtaW5hbHNfWyRwXSAuICInIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGlmIChcaW5fYXJyYXkoIidTVFJJTkcnIiwgJGV4cGVjdGVkKSAmJiBcaW5fYXJyYXkoc3Vic3RyKCR0aGlzLT5sZXhlci0+bWF0Y2gsIDAsIDEpLCBhcnJheSgnIicsICInIikpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIkludmFsaWQgc3RyaW5nIjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCInIiA9PT0gc3Vic3RyKCR0aGlzLT5sZXhlci0+bWF0Y2gsIDAsIDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiLCBpdCBhcHBlYXJzIHlvdSB1c2VkIHNpbmdsZSBxdW90ZXMgaW5zdGVhZCBvZiBkb3VibGUgcXVvdGVzIjsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJ3siLis/KFxcXFxbXiJiZm5ydC9cXFxcdV0oLi4uKT8pfScsICR0aGlzLT5sZXhlci0+Z2V0RnVsbFVwY29taW5nSW5wdXQoKSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gIiwgaXQgYXBwZWFycyB5b3UgaGF2ZSBhbiB1bmVzY2FwZWQgYmFja3NsYXNoIGF0OiAiLiRtYXRjaFsxXTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJ3siKD86W14iXSt8XFxcXCIpKiR9bScsICR0aGlzLT5sZXhlci0+Z2V0RnVsbFVwY29taW5nSW5wdXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICIsIGl0IGFwcGVhcnMgeW91IGZvcmdvdCB0byB0ZXJtaW5hdGUgYSBzdHJpbmcsIG9yIGF0dGVtcHRlZCB0byB3cml0ZSBhIG11bHRpbGluZSBzdHJpbmcgd2hpY2ggaXMgaW52YWxpZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRlcnJTdHIgPSAnUGFyc2UgZXJyb3Igb24gbGluZSAnIC4gKCR5eWxpbmVubysxKSAuICI6XG4iOwogICAgICAgICAgICAgICAgICAgICRlcnJTdHIgLj0gJHRoaXMtPmxleGVyLT5zaG93UG9zaXRpb24oKSAuICJcbiI7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRtZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRlcnJTdHIgLj0gJG1lc3NhZ2U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSAoXGNvdW50KCRleHBlY3RlZCkgPiAxKSA/ICJFeHBlY3RlZCBvbmUgb2Y6ICIgOiAiRXhwZWN0ZWQ6ICI7CiAgICAgICAgICAgICAgICAgICAgICAgICRlcnJTdHIgLj0gaW1wbG9kZSgnLCAnLCAkZXhwZWN0ZWQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCcsJyA9PT0gc3Vic3RyKHRyaW0oJHRoaXMtPmxleGVyLT5nZXRQYXN0SW5wdXQoKSksIC0xKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZXJyU3RyIC49ICIgLSBJdCBhcHBlYXJzIHlvdSBoYXZlIGFuIGV4dHJhIHRyYWlsaW5nIGNvbW1hIjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUVycm9yKCRlcnJTdHIsIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAndGV4dCcgPT4gJHRoaXMtPmxleGVyLT5tYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgJ3Rva2VuJyA9PiAhZW1wdHkoJHRoaXMtPnRlcm1pbmFsc19bJHN5bWJvbF0pID8gJHRoaXMtPnRlcm1pbmFsc19bJHN5bWJvbF0gOiAkc3ltYm9sLAogICAgICAgICAgICAgICAgICAgICAgICAnbGluZScgPT4gJHRoaXMtPmxleGVyLT55eWxpbmVubywKICAgICAgICAgICAgICAgICAgICAgICAgJ2xvYycgPT4gJHl5bG9jLAogICAgICAgICAgICAgICAgICAgICAgICAnZXhwZWN0ZWQnID0+ICRleHBlY3RlZCwKICAgICAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBqdXN0IHJlY292ZXJlZCBmcm9tIGFub3RoZXIgZXJyb3IKICAgICAgICAgICAgICAgIGlmICgkcmVjb3ZlcmluZyA9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRzeW1ib2wgPT0gJEVPRikgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigkZXJyU3RyID86ICdQYXJzaW5nIGhhbHRlZC4nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGRpc2NhcmQgY3VycmVudCBsb29rYWhlYWQgYW5kIGdyYWIgYW5vdGhlcgogICAgICAgICAgICAgICAgICAgICR5eWxlbmcgPSAkdGhpcy0+bGV4ZXItPnl5bGVuZzsKICAgICAgICAgICAgICAgICAgICAkeXl0ZXh0ID0gJHRoaXMtPmxleGVyLT55eXRleHQ7CiAgICAgICAgICAgICAgICAgICAgJHl5bGluZW5vID0gJHRoaXMtPmxleGVyLT55eWxpbmVubzsKICAgICAgICAgICAgICAgICAgICAkeXlsb2MgPSAkdGhpcy0+bGV4ZXItPnl5bGxvYzsKICAgICAgICAgICAgICAgICAgICAkc3ltYm9sID0gJHRoaXMtPmxleCgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHRyeSB0byByZWNvdmVyIGZyb20gZXJyb3IKICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGVycm9yIHJlY292ZXJ5IHJ1bGUgaW4gdGhpcyBzdGF0ZQogICAgICAgICAgICAgICAgICAgIGlmIChcYXJyYXlfa2V5X2V4aXN0cygkVEVSUk9SLCAkdGhpcy0+dGFibGVbJHN0YXRlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkc3RhdGUgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigkZXJyU3RyID86ICdQYXJzaW5nIGhhbHRlZC4nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnBvcFN0YWNrKDEpOwogICAgICAgICAgICAgICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zdGFja1tcY291bnQoJHRoaXMtPnN0YWNrKS0xXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcHJlRXJyb3JTeW1ib2wgPSAkc3ltYm9sOyAvLyBzYXZlIHRoZSBsb29rYWhlYWQgdG9rZW4KICAgICAgICAgICAgICAgICRzeW1ib2wgPSAkVEVSUk9SOyAgICAgICAgIC8vIGluc2VydCBnZW5lcmljIGVycm9yIHN5bWJvbCBhcyBuZXcgbG9va2FoZWFkCiAgICAgICAgICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c3RhY2tbXGNvdW50KCR0aGlzLT5zdGFjayktMV07CiAgICAgICAgICAgICAgICAkYWN0aW9uID0gaXNzZXQoJHRoaXMtPnRhYmxlWyRzdGF0ZV1bJFRFUlJPUl0pID8gJHRoaXMtPnRhYmxlWyRzdGF0ZV1bJFRFUlJPUl0gOiBmYWxzZTsKICAgICAgICAgICAgICAgICRyZWNvdmVyaW5nID0gMzsgLy8gYWxsb3cgMyByZWFsIHN5bWJvbHMgdG8gYmUgc2hpZnRlZCBiZWZvcmUgcmVwb3J0aW5nIGEgbmV3IGVycm9yCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkbid0IGhhcHBlbiwgdW5sZXNzIHJlc29sdmUgZGVmYXVsdHMgYXJlIG9mZgogICAgICAgICAgICBpZiAoXGlzX2FycmF5KCRhY3Rpb25bMF0pICYmIFxjb3VudCgkYWN0aW9uKSA+IDEpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCdQYXJzZSBFcnJvcjogbXVsdGlwbGUgYWN0aW9ucyBwb3NzaWJsZSBhdCBzdGF0ZTogJyAuICRzdGF0ZSAuICcsIHRva2VuOiAnIC4gJHN5bWJvbCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAoJGFjdGlvblswXSkgewogICAgICAgICAgICAgICAgY2FzZSAxOiAvLyBzaGlmdAogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFja1tdID0gJHN5bWJvbDsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dnN0YWNrW10gPSAkdGhpcy0+bGV4ZXItPnl5dGV4dDsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bHN0YWNrW10gPSAkdGhpcy0+bGV4ZXItPnl5bGxvYzsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c3RhY2tbXSA9ICRhY3Rpb25bMV07IC8vIHB1c2ggc3RhdGUKICAgICAgICAgICAgICAgICAgICAkc3ltYm9sID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAoISRwcmVFcnJvclN5bWJvbCkgeyAvLyBub3JtYWwgZXhlY3V0aW9uL25vIGVycm9yCiAgICAgICAgICAgICAgICAgICAgICAgICR5eWxlbmcgPSAkdGhpcy0+bGV4ZXItPnl5bGVuZzsKICAgICAgICAgICAgICAgICAgICAgICAgJHl5dGV4dCA9ICR0aGlzLT5sZXhlci0+eXl0ZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAkeXlsaW5lbm8gPSAkdGhpcy0+bGV4ZXItPnl5bGluZW5vOwogICAgICAgICAgICAgICAgICAgICAgICAkeXlsb2MgPSAkdGhpcy0+bGV4ZXItPnl5bGxvYzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZWNvdmVyaW5nID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlY292ZXJpbmctLTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGVycm9yIGp1c3Qgb2NjdXJyZWQsIHJlc3VtZSBvbGQgbG9va2FoZWFkIGYvIGJlZm9yZSBlcnJvcgogICAgICAgICAgICAgICAgICAgICAgICAkc3ltYm9sID0gJHByZUVycm9yU3ltYm9sOwogICAgICAgICAgICAgICAgICAgICAgICAkcHJlRXJyb3JTeW1ib2wgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIHJlZHVjZQogICAgICAgICAgICAgICAgICAgICRsZW4gPSAkdGhpcy0+cHJvZHVjdGlvbnNfWyRhY3Rpb25bMV1dWzFdOwoKICAgICAgICAgICAgICAgICAgICAvLyBwZXJmb3JtIHNlbWFudGljIGFjdGlvbgogICAgICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSAkdGhpcy0+dnN0YWNrW1xjb3VudCgkdGhpcy0+dnN0YWNrKSAtICRsZW5dOyAvLyBkZWZhdWx0IHRvICQkID0gJDEKICAgICAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IGxvY2F0aW9uLCB1c2VzIGZpcnN0IHRva2VuIGZvciBmaXJzdHMsIGxhc3QgZm9yIGxhc3RzCiAgICAgICAgICAgICAgICAgICAgJHl5dmFsLT5zdG9yZSA9IGFycmF5KCAvLyBfJCA9IHN0b3JlCiAgICAgICAgICAgICAgICAgICAgICAgICdmaXJzdF9saW5lJyA9PiAkdGhpcy0+bHN0YWNrW1xjb3VudCgkdGhpcy0+bHN0YWNrKSAtICgkbGVuID86IDEpXVsnZmlyc3RfbGluZSddLAogICAgICAgICAgICAgICAgICAgICAgICAnbGFzdF9saW5lJyA9PiAkdGhpcy0+bHN0YWNrW1xjb3VudCgkdGhpcy0+bHN0YWNrKSAtIDFdWydsYXN0X2xpbmUnXSwKICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpcnN0X2NvbHVtbicgPT4gJHRoaXMtPmxzdGFja1tcY291bnQoJHRoaXMtPmxzdGFjaykgLSAoJGxlbiA/OiAxKV1bJ2ZpcnN0X2NvbHVtbiddLAogICAgICAgICAgICAgICAgICAgICAgICAnbGFzdF9jb2x1bW4nID0+ICR0aGlzLT5sc3RhY2tbXGNvdW50KCR0aGlzLT5sc3RhY2spIC0gMV1bJ2xhc3RfY29sdW1uJ10sCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAkciA9ICR0aGlzLT5wZXJmb3JtQWN0aW9uKCR5eXZhbCwgJHl5dGV4dCwgJHl5bGVuZywgJHl5bGluZW5vLCAkYWN0aW9uWzFdLCAkdGhpcy0+dnN0YWNrKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkciBpbnN0YW5jZW9mIFVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHI7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJGxlbikgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cG9wU3RhY2soJGxlbik7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c3RhY2tbXSA9ICR0aGlzLT5wcm9kdWN0aW9uc19bJGFjdGlvblsxXV1bMF07ICAgIC8vIHB1c2ggbm9udGVybWluYWwgKHJlZHVjZSkKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dnN0YWNrW10gPSAkeXl2YWwtPnRva2VuOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5sc3RhY2tbXSA9ICR5eXZhbC0+c3RvcmU7CiAgICAgICAgICAgICAgICAgICAgJG5ld1N0YXRlID0gJHRoaXMtPnRhYmxlWyR0aGlzLT5zdGFja1tcY291bnQoJHRoaXMtPnN0YWNrKS0yXV1bJHRoaXMtPnN0YWNrW1xjb3VudCgkdGhpcy0+c3RhY2spLTFdXTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c3RhY2tbXSA9ICRuZXdTdGF0ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIDM6IC8vIGFjY2VwdAoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VFcnJvcigkc3RyLCAkaGFzaCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigkc3RyLCAkaGFzaCk7CiAgICB9CgogICAgLy8gJCQgPSAkdG9rZW5zIC8vIG5lZWRzIHRvIGJlIHBhc3NlZCBieSByZWY/CiAgICAvLyAkID0gJHRva2VuCiAgICAvLyBfJCByZW1vdmVkLCB1c2VsZXNzPwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwZXJmb3JtQWN0aW9uKHN0ZENsYXNzICR5eXZhbCwgJHl5dGV4dCwgJHl5bGVuZywgJHl5bGluZW5vLCAkeXlzdGF0ZSwgJiR0b2tlbnMpCiAgICB7CiAgICAgICAgLy8gJDAgPSAkbGVuCiAgICAgICAgJGxlbiA9IFxjb3VudCgkdG9rZW5zKSAtIDE7CiAgICAgICAgc3dpdGNoICgkeXlzdGF0ZSkgewogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgJHl5dGV4dCA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygneyg/OlxcXFxbImJmbnJ0L1xcXFxdfFxcXFx1W2EtZkEtRjAtOV17NH0pfScsIGFycmF5KCR0aGlzLCAnc3RyaW5nSW50ZXJwb2xhdGlvbicpLCAkeXl0ZXh0KTsKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9ICR5eXRleHQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgaWYgKHN0cnBvcygkeXl0ZXh0LCAnZScpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHl5dGV4dCwgJ0UnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBcZmxvYXR2YWwoJHl5dGV4dCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gc3RycG9zKCR5eXRleHQsICcuJykgPT09IGZhbHNlID8gXGludHZhbCgkeXl0ZXh0KSA6IFxmbG9hdHZhbCgkeXl0ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBudWxsOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSB0cnVlOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBmYWxzZTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gJHl5dmFsLT50b2tlbiA9ICR0b2tlbnNbJGxlbi0xXTsKICAgICAgICBjYXNlIDEzOgogICAgICAgICAgICBpZiAoJHRoaXMtPmZsYWdzICYgc2VsZjo6UEFSU0VfVE9fQVNTT0MpIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBhcnJheSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IG5ldyBzdGRDbGFzczsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE0OgogICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gJHRva2Vuc1skbGVuLTFdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gYXJyYXkoJHRva2Vuc1skbGVuLTJdLCAkdG9rZW5zWyRsZW5dKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNzAxMDApIHsKICAgICAgICAgICAgICAgICRwcm9wZXJ0eSA9ICR0b2tlbnNbJGxlbl1bMF0gPT09ICcnID8gJ19lbXB0eV8nIDogJHRva2Vuc1skbGVuXVswXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcm9wZXJ0eSA9ICR0b2tlbnNbJGxlbl1bMF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5mbGFncyAmIHNlbGY6OlBBUlNFX1RPX0FTU09DKSB7CiAgICAgICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW5bJHByb3BlcnR5XSA9ICR0b2tlbnNbJGxlbl1bMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gbmV3IHN0ZENsYXNzOwogICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlbi0+JHByb3BlcnR5ID0gJHRva2Vuc1skbGVuXVsxXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICBpZiAoJHRoaXMtPmZsYWdzICYgc2VsZjo6UEFSU0VfVE9fQVNTT0MpIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSYgJHRva2Vuc1skbGVuLTJdOwogICAgICAgICAgICAgICAgJGtleSA9ICR0b2tlbnNbJGxlbl1bMF07CiAgICAgICAgICAgICAgICBpZiAoKCR0aGlzLT5mbGFncyAmIHNlbGY6OkRFVEVDVF9LRVlfQ09ORkxJQ1RTKSAmJiBpc3NldCgkdG9rZW5zWyRsZW4tMl1bJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciA9ICdQYXJzZSBlcnJvciBvbiBsaW5lICcgLiAoJHl5bGluZW5vKzEpIC4gIjpcbiI7CiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSAkdGhpcy0+bGV4ZXItPnNob3dQb3NpdGlvbigpIC4gIlxuIjsKICAgICAgICAgICAgICAgICAgICAkZXJyU3RyIC49ICJEdXBsaWNhdGUga2V5OiAiLiR0b2tlbnNbJGxlbl1bMF07CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IER1cGxpY2F0ZUtleUV4Y2VwdGlvbigkZXJyU3RyLCAkdG9rZW5zWyRsZW5dWzBdLCBhcnJheSgnbGluZScgPT4gJHl5bGluZW5vKzEpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgoJHRoaXMtPmZsYWdzICYgc2VsZjo6QUxMT1dfRFVQTElDQVRFX0tFWVMpICYmIGlzc2V0KCR0b2tlbnNbJGxlbi0yXVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkZHVwbGljYXRlQ291bnQgPSAxOwogICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGR1cGxpY2F0ZUtleSA9ICRrZXkgLiAnLicgLiAkZHVwbGljYXRlQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChpc3NldCgkdG9rZW5zWyRsZW4tMl1bJGR1cGxpY2F0ZUtleV0pKTsKICAgICAgICAgICAgICAgICAgICAka2V5ID0gJGR1cGxpY2F0ZUtleTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0b2tlbnNbJGxlbi0yXVska2V5XSA9ICR0b2tlbnNbJGxlbl1bMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gJHRva2Vuc1skbGVuLTJdOwogICAgICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNzAxMDApIHsKICAgICAgICAgICAgICAgICAgICAka2V5ID0gJHRva2Vuc1skbGVuXVswXSA9PT0gJycgPyAnX2VtcHR5XycgOiAkdG9rZW5zWyRsZW5dWzBdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAka2V5ID0gJHRva2Vuc1skbGVuXVswXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgoJHRoaXMtPmZsYWdzICYgc2VsZjo6REVURUNUX0tFWV9DT05GTElDVFMpICYmIGlzc2V0KCR0b2tlbnNbJGxlbi0yXS0+eyRrZXl9KSkgewogICAgICAgICAgICAgICAgICAgICRlcnJTdHIgPSAnUGFyc2UgZXJyb3Igb24gbGluZSAnIC4gKCR5eWxpbmVubysxKSAuICI6XG4iOwogICAgICAgICAgICAgICAgICAgICRlcnJTdHIgLj0gJHRoaXMtPmxleGVyLT5zaG93UG9zaXRpb24oKSAuICJcbiI7CiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSAiRHVwbGljYXRlIGtleTogIi4kdG9rZW5zWyRsZW5dWzBdOwogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBEdXBsaWNhdGVLZXlFeGNlcHRpb24oJGVyclN0ciwgJHRva2Vuc1skbGVuXVswXSwgYXJyYXkoJ2xpbmUnID0+ICR5eWxpbmVubysxKSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoKCR0aGlzLT5mbGFncyAmIHNlbGY6OkFMTE9XX0RVUExJQ0FURV9LRVlTKSAmJiBpc3NldCgkdG9rZW5zWyRsZW4tMl0tPnska2V5fSkpIHsKICAgICAgICAgICAgICAgICAgICAkZHVwbGljYXRlQ291bnQgPSAxOwogICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGR1cGxpY2F0ZUtleSA9ICRrZXkgLiAnLicgLiAkZHVwbGljYXRlQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChpc3NldCgkdG9rZW5zWyRsZW4tMl0tPiRkdXBsaWNhdGVLZXkpKTsKICAgICAgICAgICAgICAgICAgICAka2V5ID0gJGR1cGxpY2F0ZUtleTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0b2tlbnNbJGxlbi0yXS0+JGtleSA9ICR0b2tlbnNbJGxlbl1bMV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxODoKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IGFycmF5KCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTk6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSAkdG9rZW5zWyRsZW4tMV07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjA6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBhcnJheSgkdG9rZW5zWyRsZW5dKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyMToKICAgICAgICAgICAgJHRva2Vuc1skbGVuLTJdW10gPSAkdG9rZW5zWyRsZW5dOwogICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gJHRva2Vuc1skbGVuLTJdOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgVW5kZWZpbmVkKCk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBzdHJpbmdJbnRlcnBvbGF0aW9uKCRtYXRjaCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRtYXRjaFswXSkgewogICAgICAgIGNhc2UgJ1xcXFwnOgogICAgICAgICAgICByZXR1cm4gJ1xcJzsKICAgICAgICBjYXNlICdcIic6CiAgICAgICAgICAgIHJldHVybiAnIic7CiAgICAgICAgY2FzZSAnXGInOgogICAgICAgICAgICByZXR1cm4gXGNocig4KTsKICAgICAgICBjYXNlICdcZic6CiAgICAgICAgICAgIHJldHVybiBcY2hyKDEyKTsKICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgIHJldHVybiAiXG4iOwogICAgICAgIGNhc2UgJ1xyJzoKICAgICAgICAgICAgcmV0dXJuICJcciI7CiAgICAgICAgY2FzZSAnXHQnOgogICAgICAgICAgICByZXR1cm4gIlx0IjsKICAgICAgICBjYXNlICdcLyc6CiAgICAgICAgICAgIHJldHVybiAiLyI7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIGh0bWxfZW50aXR5X2RlY29kZSgnJiN4Jy5sdHJpbShzdWJzdHIoJG1hdGNoWzBdLCAyKSwgJzAnKS4nOycsIEVOVF9RVU9URVMsICdVVEYtOCcpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBvcFN0YWNrKCRuKQogICAgewogICAgICAgICR0aGlzLT5zdGFjayA9IFxhcnJheV9zbGljZSgkdGhpcy0+c3RhY2ssIDAsIC0gKDIgKiAkbikpOwogICAgICAgICR0aGlzLT52c3RhY2sgPSBcYXJyYXlfc2xpY2UoJHRoaXMtPnZzdGFjaywgMCwgLSAkbik7CiAgICAgICAgJHRoaXMtPmxzdGFjayA9IFxhcnJheV9zbGljZSgkdGhpcy0+bHN0YWNrLCAwLCAtICRuKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxleCgpCiAgICB7CiAgICAgICAgJHRva2VuID0gJHRoaXMtPmxleGVyLT5sZXgoKSA/OiAxOyAvLyAkZW5kID0gMQogICAgICAgIC8vIGlmIHRva2VuIGlzbid0IGl0cyBudW1lcmljIHZhbHVlLCBjb252ZXJ0CiAgICAgICAgaWYgKCFpc19udW1lcmljKCR0b2tlbikpIHsKICAgICAgICAgICAgJHRva2VuID0gaXNzZXQoJHRoaXMtPnN5bWJvbHNbJHRva2VuXSkgPyAkdGhpcy0+c3ltYm9sc1skdG9rZW5dIDogJHRva2VuOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0b2tlbjsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZhaWxPbkJPTSgkaW5wdXQpCiAgICB7CiAgICAgICAgLy8gVVRGLTggQnl0ZU9yZGVyTWFyayBzZXF1ZW5jZQogICAgICAgICRib20gPSAiXHhFRlx4QkJceEJGIjsKCiAgICAgICAgaWYgKHN1YnN0cigkaW5wdXQsIDAsIDMpID09PSAkYm9tKSB7CiAgICAgICAgICAgICR0aGlzLT5wYXJzZUVycm9yKCJCT00gZGV0ZWN0ZWQsIG1ha2Ugc3VyZSB5b3VyIGlucHV0IGRvZXMgbm90IGluY2x1ZGUgYSBVbmljb2RlIEJ5dGUtT3JkZXItTWFyayIsIGFycmF5KCkpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpTT04gTGludCBwYWNrYWdlLgogKgogKiAoYykgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFNlbGRcSnNvbkxpbnQ7CgovKioKICogTGV4ZXIgY2xhc3MKICoKICogUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3phYWNoL2pzb25saW50CiAqLwpjbGFzcyBMZXhlcgp7CiAgICBwcml2YXRlICRFT0YgPSAxOwogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8aW50LCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJHJ1bGVzID0gYXJyYXkoCiAgICAgICAgMCA9PiAnL1xHXHMrLycsCiAgICAgICAgMSA9PiAnL1xHLT8oWzAtOV18WzEtOV1bMC05XSspKFwuWzAtOV0rKT8oW2VFXVsrLV0/WzAtOV0rKT9cYi8nLAogICAgICAgIDIgPT4gJ3tcRyIoPz5cXFxcWyJiZm5ydC9cXFxcXXxcXFxcdVthLWZBLUYwLTldezR9fFteXDAtXHgxZlxcXFwiXSsrKSorIn0nLAogICAgICAgIDMgPT4gJy9cR1x7LycsCiAgICAgICAgNCA9PiAnL1xHXH0vJywKICAgICAgICA1ID0+ICcvXEdcWy8nLAogICAgICAgIDYgPT4gJy9cR1xdLycsCiAgICAgICAgNyA9PiAnL1xHLC8nLAogICAgICAgIDggPT4gJy9cRzovJywKICAgICAgICA5ID0+ICcvXEd0cnVlXGIvJywKICAgICAgICAxMCA9PiAnL1xHZmFsc2VcYi8nLAogICAgICAgIDExID0+ICcvXEdudWxsXGIvJywKICAgICAgICAxMiA9PiAnL1xHJC8nLAogICAgICAgIDEzID0+ICcvXEcuLycsCiAgICApOwoKICAgIHByaXZhdGUgJGNvbmRpdGlvbnMgPSBhcnJheSgKICAgICAgICAiSU5JVElBTCIgPT4gYXJyYXkoCiAgICAgICAgICAgICJydWxlcyIgPT4gYXJyYXkoMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMyksCiAgICAgICAgICAgICJpbmNsdXNpdmUiID0+IHRydWUsCiAgICAgICAgKSwKICAgICk7CgogICAgcHJpdmF0ZSAkY29uZGl0aW9uU3RhY2s7CiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJG1vcmU7CiAgICBwcml2YXRlICRkb25lOwogICAgcHJpdmF0ZSAkb2Zmc2V0OwoKICAgIHB1YmxpYyAkbWF0Y2g7CiAgICBwdWJsaWMgJHl5bGluZW5vOwogICAgcHVibGljICR5eWxlbmc7CiAgICBwdWJsaWMgJHl5dGV4dDsKICAgIHB1YmxpYyAkeXlsbG9jOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBsZXgoKQogICAgewogICAgICAgICRyID0gJHRoaXMtPm5leHQoKTsKICAgICAgICBpZiAoISRyIGluc3RhbmNlb2YgVW5kZWZpbmVkKSB7CiAgICAgICAgICAgIHJldHVybiAkcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+bGV4KCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldElucHV0KCRpbnB1dCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5wdXQgPSAkaW5wdXQ7CiAgICAgICAgJHRoaXMtPm1vcmUgPSBmYWxzZTsKICAgICAgICAkdGhpcy0+ZG9uZSA9IGZhbHNlOwogICAgICAgICR0aGlzLT5vZmZzZXQgPSAwOwogICAgICAgICR0aGlzLT55eWxpbmVubyA9ICR0aGlzLT55eWxlbmcgPSAwOwogICAgICAgICR0aGlzLT55eXRleHQgPSAkdGhpcy0+bWF0Y2ggPSAnJzsKICAgICAgICAkdGhpcy0+Y29uZGl0aW9uU3RhY2sgPSBhcnJheSgnSU5JVElBTCcpOwogICAgICAgICR0aGlzLT55eWxsb2MgPSBhcnJheSgnZmlyc3RfbGluZScgPT4gMSwgJ2ZpcnN0X2NvbHVtbicgPT4gMCwgJ2xhc3RfbGluZScgPT4gMSwgJ2xhc3RfY29sdW1uJyA9PiAwKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzaG93UG9zaXRpb24oKQogICAgewogICAgICAgICRwcmUgPSBzdHJfcmVwbGFjZSgiXG4iLCAnJywgJHRoaXMtPmdldFBhc3RJbnB1dCgpKTsKICAgICAgICAkYyA9IHN0cl9yZXBlYXQoJy0nLCBtYXgoMCwgXHN0cmxlbigkcHJlKSAtIDEpKTsgLy8gbmV3IEFycmF5KHByZS5sZW5ndGggKyAxKS5qb2luKCItIik7CgogICAgICAgIHJldHVybiAkcHJlIC4gc3RyX3JlcGxhY2UoIlxuIiwgJycsICR0aGlzLT5nZXRVcGNvbWluZ0lucHV0KCkpIC4gIlxuIiAuICRjIC4gIl4iOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXN0SW5wdXQoKQogICAgewogICAgICAgICRwYXN0TGVuZ3RoID0gJHRoaXMtPm9mZnNldCAtIFxzdHJsZW4oJHRoaXMtPm1hdGNoKTsKCiAgICAgICAgcmV0dXJuICgkcGFzdExlbmd0aCA+IDIwID8gJy4uLicgOiAnJykgLiBzdWJzdHIoJHRoaXMtPmlucHV0LCBtYXgoMCwgJHBhc3RMZW5ndGggLSAyMCksIG1pbigyMCwgJHBhc3RMZW5ndGgpKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBjb21pbmdJbnB1dCgpCiAgICB7CiAgICAgICAgJG5leHQgPSAkdGhpcy0+bWF0Y2g7CiAgICAgICAgaWYgKFxzdHJsZW4oJG5leHQpIDwgMjApIHsKICAgICAgICAgICAgJG5leHQgLj0gc3Vic3RyKCR0aGlzLT5pbnB1dCwgJHRoaXMtPm9mZnNldCwgMjAgLSBcc3RybGVuKCRuZXh0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3Vic3RyKCRuZXh0LCAwLCAyMCkgLiAoXHN0cmxlbigkbmV4dCkgPiAyMCA/ICcuLi4nIDogJycpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdWxsVXBjb21pbmdJbnB1dCgpCiAgICB7CiAgICAgICAgJG5leHQgPSAkdGhpcy0+bWF0Y2g7CiAgICAgICAgaWYgKHN1YnN0cigkbmV4dCwgMCwgMSkgPT09ICciJyAmJiBzdWJzdHJfY291bnQoJG5leHQsICciJykgPT09IDEpIHsKICAgICAgICAgICAgJGxlbiA9IFxzdHJsZW4oJHRoaXMtPmlucHV0KTsKICAgICAgICAgICAgJHN0ckVuZCA9IG1pbihzdHJwb3MoJHRoaXMtPmlucHV0LCAnIicsICR0aGlzLT5vZmZzZXQgKyAxKSA/OiAkbGVuLCBzdHJwb3MoJHRoaXMtPmlucHV0LCAiXG4iLCAkdGhpcy0+b2Zmc2V0ICsgMSkgPzogJGxlbik7CiAgICAgICAgICAgICRuZXh0IC49IHN1YnN0cigkdGhpcy0+aW5wdXQsICR0aGlzLT5vZmZzZXQsICRzdHJFbmQgLSAkdGhpcy0+b2Zmc2V0KTsKICAgICAgICB9IGVsc2VpZiAoXHN0cmxlbigkbmV4dCkgPCAyMCkgewogICAgICAgICAgICAkbmV4dCAuPSBzdWJzdHIoJHRoaXMtPmlucHV0LCAkdGhpcy0+b2Zmc2V0LCAyMCAtIFxzdHJsZW4oJG5leHQpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbmV4dDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VFcnJvcigkc3RyLCAkaGFzaCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigkc3RyKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIG5leHQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZG9uZSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPkVPRjsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5vZmZzZXQgPT09IFxzdHJsZW4oJHRoaXMtPmlucHV0KSkgewogICAgICAgICAgICAkdGhpcy0+ZG9uZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkdG9rZW4gPSBudWxsOwogICAgICAgICRtYXRjaCA9IG51bGw7CiAgICAgICAgJGNvbCA9IG51bGw7CiAgICAgICAgJGxpbmVzID0gbnVsbDsKCiAgICAgICAgaWYgKCEkdGhpcy0+bW9yZSkgewogICAgICAgICAgICAkdGhpcy0+eXl0ZXh0ID0gJyc7CiAgICAgICAgICAgICR0aGlzLT5tYXRjaCA9ICcnOwogICAgICAgIH0KCiAgICAgICAgJHJ1bGVzID0gJHRoaXMtPmdldEN1cnJlbnRSdWxlcygpOwogICAgICAgICRydWxlc0xlbiA9IFxjb3VudCgkcnVsZXMpOwoKICAgICAgICBmb3IgKCRpPTA7ICRpIDwgJHJ1bGVzTGVuOyAkaSsrKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCR0aGlzLT5ydWxlc1skcnVsZXNbJGldXSwgJHRoaXMtPmlucHV0LCAkbWF0Y2gsIDAsICR0aGlzLT5vZmZzZXQpKSB7CiAgICAgICAgICAgICAgICBwcmVnX21hdGNoX2FsbCgnL1xuLiovJywgJG1hdGNoWzBdLCAkbGluZXMpOwogICAgICAgICAgICAgICAgJGxpbmVzID0gJGxpbmVzWzBdOwogICAgICAgICAgICAgICAgaWYgKCRsaW5lcykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT55eWxpbmVubyArPSBcY291bnQoJGxpbmVzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+eXlsbG9jID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ2ZpcnN0X2xpbmUnID0+ICR0aGlzLT55eWxsb2NbJ2xhc3RfbGluZSddLAogICAgICAgICAgICAgICAgICAgICdsYXN0X2xpbmUnID0+ICR0aGlzLT55eWxpbmVubysxLAogICAgICAgICAgICAgICAgICAgICdmaXJzdF9jb2x1bW4nID0+ICR0aGlzLT55eWxsb2NbJ2xhc3RfY29sdW1uJ10sCiAgICAgICAgICAgICAgICAgICAgJ2xhc3RfY29sdW1uJyA9PiAkbGluZXMgPyBcc3RybGVuKCRsaW5lc1tcY291bnQoJGxpbmVzKSAtIDFdKSAtIDEgOiAkdGhpcy0+eXlsbG9jWydsYXN0X2NvbHVtbiddICsgXHN0cmxlbigkbWF0Y2hbMF0pLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICR0aGlzLT55eXRleHQgLj0gJG1hdGNoWzBdOwogICAgICAgICAgICAgICAgJHRoaXMtPm1hdGNoIC49ICRtYXRjaFswXTsKICAgICAgICAgICAgICAgICR0aGlzLT55eWxlbmcgPSBcc3RybGVuKCR0aGlzLT55eXRleHQpOwogICAgICAgICAgICAgICAgJHRoaXMtPm1vcmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICR0aGlzLT5vZmZzZXQgKz0gXHN0cmxlbigkbWF0Y2hbMF0pOwogICAgICAgICAgICAgICAgJHRva2VuID0gJHRoaXMtPnBlcmZvcm1BY3Rpb24oJHJ1bGVzWyRpXSwgJHRoaXMtPmNvbmRpdGlvblN0YWNrW1xjb3VudCgkdGhpcy0+Y29uZGl0aW9uU3RhY2spLTFdKTsKICAgICAgICAgICAgICAgIGlmICgkdG9rZW4pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRva2VuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVW5kZWZpbmVkKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+b2Zmc2V0ID09PSBcc3RybGVuKCR0aGlzLT5pbnB1dCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5FT0Y7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cGFyc2VFcnJvcigKICAgICAgICAgICAgJ0xleGljYWwgZXJyb3Igb24gbGluZSAnIC4gKCR0aGlzLT55eWxpbmVubysxKSAuICIuIFVucmVjb2duaXplZCB0ZXh0LlxuIiAuICR0aGlzLT5zaG93UG9zaXRpb24oKSwKICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAndGV4dCcgPT4gIiIsCiAgICAgICAgICAgICAgICAndG9rZW4nID0+IG51bGwsCiAgICAgICAgICAgICAgICAnbGluZScgPT4gJHRoaXMtPnl5bGluZW5vLAogICAgICAgICAgICApCiAgICAgICAgKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEN1cnJlbnRSdWxlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25kaXRpb25zWyR0aGlzLT5jb25kaXRpb25TdGFja1tcY291bnQoJHRoaXMtPmNvbmRpdGlvblN0YWNrKS0xXV1bJ3J1bGVzJ107CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBwZXJmb3JtQWN0aW9uKCRhdm9pZGluZ19uYW1lX2NvbGxpc2lvbnMsICRZWV9TVEFSVCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRhdm9pZGluZ19uYW1lX2NvbGxpc2lvbnMpIHsKICAgICAgICBjYXNlIDA6Lyogc2tpcCB3aGl0ZXNwYWNlICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIDY7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAkdGhpcy0+eXl0ZXh0ID0gc3Vic3RyKCR0aGlzLT55eXRleHQsIDEsICR0aGlzLT55eWxlbmctMik7CgogICAgICAgICAgICByZXR1cm4gNDsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiAxNzsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiAxODsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiAyMzsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiAyNDsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiAyMjsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiAyMTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiAxMDsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gMTE7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIDg7CiAgICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgcmV0dXJuIDE0OwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgIHJldHVybiAnSU5WQUxJRCc7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSlNPTiBMaW50IHBhY2thZ2UuCiAqCiAqIChjKSBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU2VsZFxKc29uTGludDsKCmNsYXNzIFVuZGVmaW5lZAp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKU09OIExpbnQgcGFja2FnZS4KICoKICogKGMpIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTZWxkXEpzb25MaW50OwoKY2xhc3MgRHVwbGljYXRlS2V5RXhjZXB0aW9uIGV4dGVuZHMgUGFyc2luZ0V4Y2VwdGlvbgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXl7dGV4dD86IHN0cmluZywgdG9rZW4/OiBzdHJpbmcsIGxpbmU/OiBpbnQsIGxvYz86IGFycmF5e2ZpcnN0X2xpbmU6IGludCwgZmlyc3RfY29sdW1uOiBpbnQsIGxhc3RfbGluZTogaW50LCBsYXN0X2NvbHVtbjogaW50fSwgZXhwZWN0ZWQ/OiBzdHJpbmdbXX0gJGRldGFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlLCAka2V5LCBhcnJheSAkZGV0YWlscyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJGRldGFpbHNbJ2tleSddID0gJGtleTsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkZGV0YWlscyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXRhaWxzWydrZXknXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheXt0ZXh0Pzogc3RyaW5nLCB0b2tlbj86IHN0cmluZywgbGluZT86IGludCwgbG9jPzogYXJyYXl7Zmlyc3RfbGluZTogaW50LCBmaXJzdF9jb2x1bW46IGludCwgbGFzdF9saW5lOiBpbnQsIGxhc3RfY29sdW1uOiBpbnR9LCBleHBlY3RlZD86IHN0cmluZ1tdLCBrZXk6IHN0cmluZ30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldGFpbHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV0YWlsczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpTT04gTGludCBwYWNrYWdlLgogKgogKiAoYykgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFNlbGRcSnNvbkxpbnQ7CgpjbGFzcyBQYXJzaW5nRXhjZXB0aW9uIGV4dGVuZHMgXEV4Y2VwdGlvbgp7CiAgICBwcm90ZWN0ZWQgJGRldGFpbHM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheXt0ZXh0Pzogc3RyaW5nLCB0b2tlbj86IHN0cmluZywgbGluZT86IGludCwgbG9jPzogYXJyYXl7Zmlyc3RfbGluZTogaW50LCBmaXJzdF9jb2x1bW46IGludCwgbGFzdF9saW5lOiBpbnQsIGxhc3RfY29sdW1uOiBpbnR9LCBleHBlY3RlZD86IHN0cmluZ1tdfSAkZGV0YWlscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsICRkZXRhaWxzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGV0YWlscyA9ICRkZXRhaWxzOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5e3RleHQ/OiBzdHJpbmcsIHRva2VuPzogc3RyaW5nLCBsaW5lPzogaW50LCBsb2M/OiBhcnJheXtmaXJzdF9saW5lOiBpbnQsIGZpcnN0X2NvbHVtbjogaW50LCBsYXN0X2xpbmU6IGludCwgbGFzdF9jb2x1bW46IGludH0sIGV4cGVjdGVkPzogc3RyaW5nW119CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXRhaWxzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRldGFpbHM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFBIQVIgVXRpbHMuCiAqCiAqIChjKSBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU2VsZFxQaGFyVXRpbHM7CgpjbGFzcyBUaW1lc3RhbXBzCnsKICAgIHByaXZhdGUgJGNvbnRlbnRzOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSBwYXRoIHRvIHRoZSBwaGFyIGZpbGUgdG8gdXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZmlsZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBmaWxlX2dldF9jb250ZW50cygkZmlsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBVcGRhdGVzIGVhY2ggZmlsZSdzIHVuaXggdGltZXN0YW1wcyBpbiB0aGUgUEhBUgogICAgICoKICAgICAqIFRoZSBQSEFSIHNpZ25hdHVyZSBjYW4gdGhlbiBiZSBwcm9kdWNlZCBpbiBhIHJlcHJvZHVjaWJsZSBtYW5uZXIuCiAgICAgKgogICAgICogQHBhcmFtIGludHxcRGF0ZVRpbWVJbnRlcmZhY2V8c3RyaW5nICR0aW1lc3RhbXAgRGF0ZSBzdHJpbmcgb3IgRGF0ZVRpbWUgb3IgdW5peCB0aW1lc3RhbXAgdG8gdXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGVUaW1lc3RhbXBzKCR0aW1lc3RhbXAgPSBudWxsKQogICAgewogICAgICAgIGlmICgkdGltZXN0YW1wIGluc3RhbmNlb2YgXERhdGVUaW1lIHx8ICR0aW1lc3RhbXAgaW5zdGFuY2VvZiBcRGF0ZVRpbWVJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHRpbWVzdGFtcCA9ICR0aW1lc3RhbXAtPmdldFRpbWVzdGFtcCgpOwogICAgICAgIH0gZWxzZWlmIChpc19zdHJpbmcoJHRpbWVzdGFtcCkpIHsKICAgICAgICAgICAgJHRpbWVzdGFtcCA9IHN0cnRvdGltZSgkdGltZXN0YW1wKTsKICAgICAgICB9IGVsc2VpZiAoIWlzX2ludCgkdGltZXN0YW1wKSkgewogICAgICAgICAgICAkdGltZXN0YW1wID0gc3RydG90aW1lKCcxOTg0LTEyLTI0VDAwOjAwOjAwWicpOwogICAgICAgIH0KCiAgICAgICAgLy8gZGV0ZWN0IG1hbmlmZXN0IG9mZnNldCAvIGVuZCBvZiBzdHViCiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7X19IQUxUX0NPTVBJTEVSXChcKTsoPzogK1w/Pik/XHI/XG59JywgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gsIFBSRUdfT0ZGU0VUX0NBUFRVUkUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IGRldGVjdCB0aGUgc3R1YlwncyBlbmQgaW4gdGhlIHBoYXInKTsKICAgICAgICB9CgogICAgICAgIC8vIHNldCBzdGFydGluZyBwb3NpdGlvbiBhbmQgc2tpcCBwYXN0IG1hbmlmZXN0IGxlbmd0aAogICAgICAgICRwb3MgPSAkbWF0Y2hbMF1bMV0gKyBzdHJsZW4oJG1hdGNoWzBdWzBdKTsKICAgICAgICAkc3R1YkVuZCA9ICRwb3MgKyAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CiAgICAgICAgJHBvcyArPSA0OwoKICAgICAgICAkbnVtRmlsZXMgPSAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CiAgICAgICAgJHBvcyArPSA0OwoKICAgICAgICAvLyBza2lwIEFQSSB2ZXJzaW9uIChZT0xPKQogICAgICAgICRwb3MgKz0gMjsKCiAgICAgICAgLy8gc2tpcCBQSEFSIGZsYWdzCiAgICAgICAgJHBvcyArPSA0OwoKICAgICAgICAkYWxpYXNMZW5ndGggPSAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CiAgICAgICAgJHBvcyArPSA0ICsgJGFsaWFzTGVuZ3RoOwoKICAgICAgICAkbWV0YWRhdGFMZW5ndGggPSAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CiAgICAgICAgJHBvcyArPSA0ICsgJG1ldGFkYXRhTGVuZ3RoOwoKICAgICAgICB3aGlsZSAoJHBvcyA8ICRzdHViRW5kKSB7CiAgICAgICAgICAgICRmaWxlbmFtZUxlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAgICAgJHBvcyArPSA0ICsgJGZpbGVuYW1lTGVuZ3RoOwoKICAgICAgICAgICAgLy8gc2tpcCBmaWxlc2l6ZQogICAgICAgICAgICAkcG9zICs9IDQ7CgogICAgICAgICAgICAvLyB1cGRhdGUgdGltZXN0YW1wIHRvIGEgZml4ZWQgdmFsdWUKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gc3Vic3RyX3JlcGxhY2UoJHRoaXMtPmNvbnRlbnRzLCBwYWNrKCdMJywgJHRpbWVzdGFtcCksICRwb3MsIDQpOwoKICAgICAgICAgICAgLy8gc2tpcCB0aW1lc3RhbXAsIGNvbXByZXNzZWQgZmlsZSBzaXplLCBjcmMzMiBjaGVja3N1bSBhbmQgZmlsZSBmbGFncwogICAgICAgICAgICAkcG9zICs9IDQqNDsKCiAgICAgICAgICAgICRtZXRhZGF0YUxlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAgICAgJHBvcyArPSA0ICsgJG1ldGFkYXRhTGVuZ3RoOwoKICAgICAgICAgICAgJG51bUZpbGVzLS07CiAgICAgICAgfQoKICAgICAgICBpZiAoJG51bUZpbGVzICE9PSAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0FsbCBmaWxlcyB3ZXJlIG5vdCBwcm9jZXNzZWQsIHNvbWV0aGluZyBtdXN0IGhhdmUgZ29uZSB3cm9uZycpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNhdmVzIHRoZSB1cGRhdGVkIHBoYXIgZmlsZSwgb3B0aW9uYWxseSB3aXRoIGFuIHVwZGF0ZWQgc2lnbmF0dXJlLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYXRoCiAgICAgKiBAcGFyYW0gIGludCAkc2lnbmF0dXJlQWxnbyBPbmUgb2YgUGhhcjo6TUQ1LCBQaGFyOjpTSEExLCBQaGFyOjpTSEEyNTYgb3IgUGhhcjo6U0hBNTEyCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNhdmUoJHBhdGgsICRzaWduYXR1cmVBbGdvKQogICAgewogICAgICAgICRwb3MgPSAkdGhpcy0+ZGV0ZXJtaW5lU2lnbmF0dXJlQmVnaW4oKTsKCiAgICAgICAgJGFsZ29zID0gYXJyYXkoCiAgICAgICAgICAgIFxQaGFyOjpNRDUgPT4gJ21kNScsCiAgICAgICAgICAgIFxQaGFyOjpTSEExID0+ICdzaGExJywKICAgICAgICAgICAgXFBoYXI6OlNIQTI1NiA9PiAnc2hhMjU2JywKICAgICAgICAgICAgXFBoYXI6OlNIQTUxMiA9PiAnc2hhNTEyJywKICAgICAgICApOwoKICAgICAgICBpZiAoIWlzc2V0KCRhbGdvc1skc2lnbmF0dXJlQWxnb10pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdJbnZhbGlkIGhhc2ggYWxnb3JpdGhtIGdpdmVuOiAnLiRzaWduYXR1cmVBbGdvLicgZXhwZWN0ZWQgb25lIG9mIFBoYXI6Ok1ENSwgUGhhcjo6U0hBMSwgUGhhcjo6U0hBMjU2IG9yIFBoYXI6OlNIQTUxMicpOwogICAgICAgIH0KICAgICAgICAkYWxnbyA9ICRhbGdvc1skc2lnbmF0dXJlQWxnb107CgogICAgICAgIC8vIHJlLXNpZ24gcGhhcgogICAgICAgIC8vICAgICAgICAgICBzaWduYXR1cmUKICAgICAgICAkc2lnbmF0dXJlID0gaGFzaCgkYWxnbywgc3Vic3RyKCR0aGlzLT5jb250ZW50cywgMCwgJHBvcyksIHRydWUpCiAgICAgICAgICAgIC8vIHNpZyB0eXBlCiAgICAgICAgICAgIC4gcGFjaygnTCcsICRzaWduYXR1cmVBbGdvKQogICAgICAgICAgICAvLyBvaGFpIEdyZWcgJiBNYXJjdXMKICAgICAgICAgICAgLiAnR0JNQic7CgogICAgICAgICR0aGlzLT5jb250ZW50cyA9IHN1YnN0cigkdGhpcy0+Y29udGVudHMsIDAsICRwb3MpIC4gJHNpZ25hdHVyZTsKCiAgICAgICAgcmV0dXJuIGZpbGVfcHV0X2NvbnRlbnRzKCRwYXRoLCAkdGhpcy0+Y29udGVudHMpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVhZFVpbnQoJHBvcywgJGJ5dGVzKQogICAgewogICAgICAgICRyZXMgPSB1bnBhY2soJ1YnLCBzdWJzdHIoJHRoaXMtPmNvbnRlbnRzLCAkcG9zLCAkYnl0ZXMpKTsKCiAgICAgICAgcmV0dXJuICRyZXNbMV07CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2lnbmF0dXJlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZGV0ZXJtaW5lU2lnbmF0dXJlQmVnaW4oKQogICAgewogICAgICAgIC8vIGRldGVjdCBzaWduYXR1cmUgcG9zaXRpb24KICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3tfX0hBTFRfQ09NUElMRVJcKFwpOyg/OiArXD8+KT9ccj9cbn0nLCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCwgUFJFR19PRkZTRVRfQ0FQVFVSRSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgZGV0ZWN0IHRoZSBzdHViXCdzIGVuZCBpbiB0aGUgcGhhcicpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2V0IHN0YXJ0aW5nIHBvc2l0aW9uIGFuZCBza2lwIHBhc3QgbWFuaWZlc3QgbGVuZ3RoCiAgICAgICAgJHBvcyA9ICRtYXRjaFswXVsxXSArIHN0cmxlbigkbWF0Y2hbMF1bMF0pOwogICAgICAgICRtYW5pZmVzdEVuZCA9ICRwb3MgKyA0ICsgJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwoKICAgICAgICAkcG9zICs9IDQ7CiAgICAgICAgJG51bUZpbGVzID0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwoKICAgICAgICAkcG9zICs9IDQ7CgogICAgICAgIC8vIHNraXAgQVBJIHZlcnNpb24gKFlPTE8pCiAgICAgICAgJHBvcyArPSAyOwoKICAgICAgICAvLyBza2lwIFBIQVIgZmxhZ3MKICAgICAgICAkcG9zICs9IDQ7CgogICAgICAgICRhbGlhc0xlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAkcG9zICs9IDQgKyAkYWxpYXNMZW5ndGg7CgogICAgICAgICRtZXRhZGF0YUxlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAkcG9zICs9IDQgKyAkbWV0YWRhdGFMZW5ndGg7CgogICAgICAgICRjb21wcmVzc2VkU2l6ZXMgPSAwOwogICAgICAgIHdoaWxlICgoJG51bUZpbGVzID4gMCkgJiYgKCRwb3MgPCAkbWFuaWZlc3RFbmQgLSAyNCkpIHsKICAgICAgICAgICAgJGZpbGVuYW1lTGVuZ3RoID0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwogICAgICAgICAgICAkcG9zICs9IDQgKyAkZmlsZW5hbWVMZW5ndGg7CgogICAgICAgICAgICAvLyBza2lwIGZpbGVzaXplIGFuZCB0aW1lc3RhbXAKICAgICAgICAgICAgJHBvcyArPSAyKjQ7CgogICAgICAgICAgICAkY29tcHJlc3NlZFNpemVzICs9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIGZpbGUgc2l6ZSwgY3JjMzIgY2hlY2tzdW0gYW5kIGZpbGUgZmxhZ3MKICAgICAgICAgICAgJHBvcyArPSAzKjQ7CgogICAgICAgICAgICAkbWV0YWRhdGFMZW5ndGggPSAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CiAgICAgICAgICAgICRwb3MgKz0gNCArICRtZXRhZGF0YUxlbmd0aDsKCiAgICAgICAgICAgICRudW1GaWxlcy0tOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRudW1GaWxlcyAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdBbGwgZmlsZXMgd2VyZSBub3QgcHJvY2Vzc2VkLCBzb21ldGhpbmcgbXVzdCBoYXZlIGdvbmUgd3JvbmcnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWFuaWZlc3RFbmQgKyAkY29tcHJlc3NlZFNpemVzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQSEFSIFV0aWxzLgogKgogKiAoYykgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFNlbGRcUGhhclV0aWxzOwoKY2xhc3MgTGludGVyCnsKICAgIC8qKgogICAgICogTGludHMgYWxsIHBocCBmaWxlcyBpbnNpZGUgYSBnaXZlbiBwaGFyIHdpdGggdGhlIGN1cnJlbnQgUEhQIHZlcnNpb24KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBoYXIgZmlsZSBwYXRoCiAgICAgKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRleGNsdWRlZFBhdGhzIFBhdGhzIHdoaWNoIHNob3VsZCBiZSBza2lwcGVkIGJ5IHRoZSBsaW50ZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBsaW50KCRwYXRoLCBhcnJheSAkZXhjbHVkZWRQYXRocyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHBocCA9IGRlZmluZWQoJ1BIUF9CSU5BUlknKSA/IFBIUF9CSU5BUlkgOiAncGhwJzsKCiAgICAgICAgaWYgKCRpc1dpbmRvd3MgPSBkZWZpbmVkKCdQSFBfV0lORE9XU19WRVJTSU9OX0JVSUxEJykpIHsKICAgICAgICAgICAgJHRtcEZpbGUgPSBAdGVtcG5hbShzeXNfZ2V0X3RlbXBfZGlyKCksICcnKTsKCiAgICAgICAgICAgIGlmICghJHRtcEZpbGUgfHwgIWlzX3dyaXRhYmxlKCR0bXBGaWxlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdVbmFibGUgdG8gY3JlYXRlIHRlbXAgZmlsZScpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGhwID0gc2VsZjo6ZXNjYXBlV2luZG93c1BhdGgoJHBocCk7CiAgICAgICAgICAgICR0bXBGaWxlID0gc2VsZjo6ZXNjYXBlV2luZG93c1BhdGgoJHRtcEZpbGUpOwoKICAgICAgICAgICAgLy8gUEhQIDggZW5jbG9zZXMgdGhlIGNvbW1hbmQgaW4gZG91YmxlLXF1b3RlcwogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gODAwMDApIHsKICAgICAgICAgICAgICAgICRmb3JtYXQgPSAnJXMgLWwgJXMnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGZvcm1hdCA9ICciJXMgLWwgJXMiJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCRmb3JtYXQsICRwaHAsICR0bXBGaWxlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29tbWFuZCA9ICInIi4kcGhwLiInIC1sIjsKICAgICAgICB9CgogICAgICAgICRkZXNjcmlwdG9yc3BlYyA9IGFycmF5KAogICAgICAgICAgICAwID0+IGFycmF5KCdwaXBlJywgJ3InKSwKICAgICAgICAgICAgMSA9PiBhcnJheSgncGlwZScsICd3JyksCiAgICAgICAgICAgIDIgPT4gYXJyYXkoJ3BpcGUnLCAndycpCiAgICAgICAgKTsKCiAgICAgICAgLy8gcGF0aCB0byBwaGFyICsgcGhhcjovLyArIHRyYWlsaW5nIHNsYXNoCiAgICAgICAgJGJhc2VMZW4gPSBzdHJsZW4ocmVhbHBhdGgoJHBhdGgpKSArIDcgKyAxOwogICAgICAgIGZvcmVhY2ggKG5ldyBcUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcihuZXcgXFBoYXIoJHBhdGgpKSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoJGZpbGUtPmlzRGlyKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdWJzdHIoJGZpbGUsIC00KSA9PT0gJy5waHAnKSB7CiAgICAgICAgICAgICAgICAkZmlsZW5hbWUgPSAoc3RyaW5nKSAkZmlsZTsKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheShzdWJzdHIoJGZpbGVuYW1lLCAkYmFzZUxlbiksICRleGNsdWRlZFBhdGhzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRpc1dpbmRvd3MpIHsKICAgICAgICAgICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkdG1wRmlsZSwgZmlsZV9nZXRfY29udGVudHMoJGZpbGVuYW1lKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHByb2Nlc3MgPSBwcm9jX29wZW4oJGNvbW1hbmQsICRkZXNjcmlwdG9yc3BlYywgJHBpcGVzKTsKICAgICAgICAgICAgICAgIGlmIChpc19yZXNvdXJjZSgkcHJvY2VzcykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISRpc1dpbmRvd3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZndyaXRlKCRwaXBlc1swXSwgZmlsZV9nZXRfY29udGVudHMoJGZpbGVuYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZjbG9zZSgkcGlwZXNbMF0pOwoKICAgICAgICAgICAgICAgICAgICAkc3Rkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cygkcGlwZXNbMV0pOwogICAgICAgICAgICAgICAgICAgIGZjbG9zZSgkcGlwZXNbMV0pOwogICAgICAgICAgICAgICAgICAgICRzdGRlcnIgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRwaXBlc1syXSk7CiAgICAgICAgICAgICAgICAgICAgZmNsb3NlKCRwaXBlc1syXSk7CgogICAgICAgICAgICAgICAgICAgICRleGl0Q29kZSA9IHByb2NfY2xvc2UoJHByb2Nlc3MpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJGV4aXRDb2RlICE9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaXNXaW5kb3dzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3RkZXJyID0gc3RyX3JlcGxhY2UoJHRtcEZpbGUsICRmaWxlbmFtZSwgJHN0ZGVycik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0ZhaWxlZCBsaW50aW5nICcuJGZpbGUuJzogJy4kc3RkZXJyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHN0YXJ0IGxpbnRlciBwcm9jZXNzJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkaXNXaW5kb3dzKSB7CiAgICAgICAgICAgIEB1bmxpbmsoJHRtcEZpbGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEVzY2FwZXMgYSBXaW5kb3dzIGZpbGUgcGF0aAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBlc2NhcGVkIHBhdGgKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjYXBlV2luZG93c1BhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgLy8gUXVvdGUgaWYgcGF0aCBjb250YWlucyBzcGFjZXMgb3IgYnJhY2tldHMKICAgICAgICBpZiAoc3RycGJyaygkcGF0aCwgIiAoKSIpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkcGF0aCA9ICciJy4kcGF0aC4nIic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhdGg7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEVudGl0eTsKCnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogQHBhY2thZ2UgSnNvblNjaGVtYVxFbnRpdHkKICoKICogQGF1dGhvciBKb29zdCBOaWpodWlzIDxqbmlqaHVpczgxQGdtYWlsLmNvbT4KICovCmNsYXNzIEpzb25Qb2ludGVyCnsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkZmlsZW5hbWU7CgogICAgLyoqIEB2YXIgc3RyaW5nW10gKi8KICAgIHByaXZhdGUgJHByb3BlcnR5UGF0aHMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciBib29sIFdoZXRoZXIgdGhlIHZhbHVlIGF0IHRoaXMgcGF0aCB3YXMgc2V0IGZyb20gYSBzY2hlbWEgZGVmYXVsdAogICAgICovCiAgICBwcml2YXRlICRmcm9tRGVmYXVsdCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiB3aGVuICR2YWx1ZSBpcyBub3QgYSBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoIWlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1JlZiB2YWx1ZSBtdXN0IGJlIGEgc3RyaW5nJyk7CiAgICAgICAgfQoKICAgICAgICAkc3BsaXRSZWYgPSBleHBsb2RlKCcjJywgJHZhbHVlLCAyKTsKICAgICAgICAkdGhpcy0+ZmlsZW5hbWUgPSAkc3BsaXRSZWZbMF07CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoMSwgJHNwbGl0UmVmKSkgewogICAgICAgICAgICAkdGhpcy0+cHJvcGVydHlQYXRocyA9ICR0aGlzLT5kZWNvZGVQcm9wZXJ0eVBhdGhzKCRzcGxpdFJlZlsxXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJvcGVydHlQYXRoU3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRlY29kZVByb3BlcnR5UGF0aHMoJHByb3BlcnR5UGF0aFN0cmluZykKICAgIHsKICAgICAgICAkcGF0aHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKGV4cGxvZGUoJy8nLCB0cmltKCRwcm9wZXJ0eVBhdGhTdHJpbmcsICcvJykpIGFzICRwYXRoKSB7CiAgICAgICAgICAgICRwYXRoID0gJHRoaXMtPmRlY29kZVBhdGgoJHBhdGgpOwogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRwYXRoKSAmJiAnJyAhPT0gJHBhdGgpIHsKICAgICAgICAgICAgICAgICRwYXRoc1tdID0gJHBhdGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGF0aHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZW5jb2RlUHJvcGVydHlQYXRocygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X21hcCgKICAgICAgICAgICAgYXJyYXkoJHRoaXMsICdlbmNvZGVQYXRoJyksCiAgICAgICAgICAgICR0aGlzLT5nZXRQcm9wZXJ0eVBhdGhzKCkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZGVjb2RlUGF0aCgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gc3RydHIoJHBhdGgsIGFycmF5KCd+MScgPT4gJy8nLCAnfjAnID0+ICd+JywgJyUyNScgPT4gJyUnKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBlbmNvZGVQYXRoKCRwYXRoKQogICAgewogICAgICAgIHJldHVybiBzdHJ0cigkcGF0aCwgYXJyYXkoJy8nID0+ICd+MScsICd+JyA9PiAnfjAnLCAnJScgPT4gJyUyNScpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlbmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5maWxlbmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3BlcnR5UGF0aHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGVydHlQYXRoczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkcHJvcGVydHlQYXRocwogICAgICoKICAgICAqIEByZXR1cm4gSnNvblBvaW50ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdpdGhQcm9wZXJ0eVBhdGhzKGFycmF5ICRwcm9wZXJ0eVBhdGhzKQogICAgewogICAgICAgICRuZXcgPSBjbG9uZSAkdGhpczsKICAgICAgICAkbmV3LT5wcm9wZXJ0eVBhdGhzID0gJHByb3BlcnR5UGF0aHM7CgogICAgICAgIHJldHVybiAkbmV3OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3BlcnR5UGF0aEFzU3RyaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gcnRyaW0oJyMvJyAuIGltcGxvZGUoJy8nLCAkdGhpcy0+ZW5jb2RlUHJvcGVydHlQYXRocygpKSwgJy8nKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldEZpbGVuYW1lKCkgLiAkdGhpcy0+Z2V0UHJvcGVydHlQYXRoQXNTdHJpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hcmsgdGhlIHZhbHVlIGF0IHRoaXMgcGF0aCBhcyBiZWluZyBzZXQgZnJvbSBhIHNjaGVtYSBkZWZhdWx0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGcm9tRGVmYXVsdCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmZyb21EZWZhdWx0ID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIHZhbHVlIGF0IHRoaXMgcGF0aCB3YXMgc2V0IGZyb20gYSBzY2hlbWEgZGVmYXVsdAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZnJvbURlZmF1bHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZnJvbURlZmF1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hOwoKLyoqCiAqIEBwYWNrYWdlIEpzb25TY2hlbWEKICovCmludGVyZmFjZSBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSBhIFVSSQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdXJpICAgICBKU09OIFNjaGVtYSBVUkkKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkYmFzZVVyaQogICAgICoKICAgICAqIEByZXR1cm4gb2JqZWN0IEpTT04gU2NoZW1hIGNvbnRlbnRzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXRyaWV2ZSgkdXJpLCAkYmFzZVVyaSA9IG51bGwpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgSnNvblNjaGVtYTsKCmNsYXNzIFJmYzMzMzkKewogICAgY29uc3QgUkVHRVggPSAnL14oXGR7NH0tXGR7Mn0tXGR7Mn1bVCBdezF9XGR7Mn06XGR7Mn06XGR7Mn0pKFwuXGQrKT8oWnwoWystXVxkezJ9KTo/KFxkezJ9KSkkLyc7CgogICAgLyoqCiAgICAgKiBUcnkgY3JlYXRpbmcgYSBEYXRlVGltZSBpbnN0YW5jZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZwogICAgICoKICAgICAqIEByZXR1cm4gXERhdGVUaW1lfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVGcm9tU3RyaW5nKCRzdHJpbmcpCiAgICB7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKHNlbGY6OlJFR0VYLCBzdHJ0b3VwcGVyKCRzdHJpbmcpLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkZGF0ZUFuZFRpbWUgPSAkbWF0Y2hlc1sxXTsKICAgICAgICAkbWljcm9zZWNvbmRzID0gJG1hdGNoZXNbMl0gPzogJy4wMDAwMDAnOwogICAgICAgICR0aW1lWm9uZSA9ICdaJyAhPT0gJG1hdGNoZXNbM10gPyAkbWF0Y2hlc1s0XSAuICc6JyAuICRtYXRjaGVzWzVdIDogJyswMDowMCc7CiAgICAgICAgJGRhdGVGb3JtYXQgPSBzdHJwb3MoJGRhdGVBbmRUaW1lLCAnVCcpID09PSBmYWxzZSA/ICdZLW0tZCBIOmk6cy51UCcgOiAnWS1tLWRcVEg6aTpzLnVQJzsKICAgICAgICAkZGF0ZVRpbWUgPSBcRGF0ZVRpbWU6OmNyZWF0ZUZyb21Gb3JtYXQoJGRhdGVGb3JtYXQsICRkYXRlQW5kVGltZSAuICRtaWNyb3NlY29uZHMgLiAkdGltZVpvbmUsIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CgogICAgICAgIHJldHVybiAkZGF0ZVRpbWUgPzogbnVsbDsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWE7Cgp1c2UgSnNvblNjaGVtYVxDb25zdHJhaW50c1xCYXNlQ29uc3RyYWludDsKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cVW5yZXNvbHZhYmxlSnNvblBvaW50ZXJFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXFVyaVxVcmlSZXNvbHZlcjsKdXNlIEpzb25TY2hlbWFcVXJpXFVyaVJldHJpZXZlcjsKCmNsYXNzIFNjaGVtYVN0b3JhZ2UgaW1wbGVtZW50cyBTY2hlbWFTdG9yYWdlSW50ZXJmYWNlCnsKICAgIGNvbnN0IElOVEVSTkFMX1BST1ZJREVEX1NDSEVNQV9VUkkgPSAnaW50ZXJuYWw6Ly9wcm92aWRlZC1zY2hlbWEvJzsKCiAgICBwcm90ZWN0ZWQgJHVyaVJldHJpZXZlcjsKICAgIHByb3RlY3RlZCAkdXJpUmVzb2x2ZXI7CiAgICBwcm90ZWN0ZWQgJHNjaGVtYXMgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgKICAgICAgICBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UgJHVyaVJldHJpZXZlciA9IG51bGwsCiAgICAgICAgVXJpUmVzb2x2ZXJJbnRlcmZhY2UgJHVyaVJlc29sdmVyID0gbnVsbAogICAgKSB7CiAgICAgICAgJHRoaXMtPnVyaVJldHJpZXZlciA9ICR1cmlSZXRyaWV2ZXIgPzogbmV3IFVyaVJldHJpZXZlcigpOwogICAgICAgICR0aGlzLT51cmlSZXNvbHZlciA9ICR1cmlSZXNvbHZlciA/OiBuZXcgVXJpUmVzb2x2ZXIoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVXJpUmV0cmlldmVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmlSZXRyaWV2ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJpUmV0cmlldmVyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBVcmlSZXNvbHZlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJpUmVzb2x2ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJpUmVzb2x2ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTY2hlbWEoJGlkLCAkc2NoZW1hID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoaXNfbnVsbCgkc2NoZW1hKSAmJiAkaWQgIT09IHNlbGY6OklOVEVSTkFMX1BST1ZJREVEX1NDSEVNQV9VUkkpIHsKICAgICAgICAgICAgLy8gaWYgdGhlIHNjaGVtYSB3YXMgdXNlci1wcm92aWRlZCB0byBWYWxpZGF0b3IgYW5kIGlzIHN0aWxsIG51bGwsIHRoZW4gYXNzdW1lIHRoaXMgaXMKICAgICAgICAgICAgLy8gd2hhdCB0aGUgdXNlciBpbnRlbmRlZCwgYXMgdGhlcmUncyBubyB3YXkgZm9yIHVzIHRvIHJldHJpZXZlIGFueXRoaW5nIGVsc2UuIFVzZXItc3VwcGxpZWQKICAgICAgICAgICAgLy8gc2NoZW1hcyBkbyBub3QgaGF2ZSBhbiBhc3NvY2lhdGVkIFVSSSB3aGVuIHBhc3NlZCB2aWEgVmFsaWRhdG9yOjp2YWxpZGF0ZSgpLgogICAgICAgICAgICAkc2NoZW1hID0gJHRoaXMtPnVyaVJldHJpZXZlci0+cmV0cmlldmUoJGlkKTsKICAgICAgICB9CgogICAgICAgIC8vIGNhc3QgYXJyYXkgc2NoZW1hcyB0byBvYmplY3QKICAgICAgICBpZiAoaXNfYXJyYXkoJHNjaGVtYSkpIHsKICAgICAgICAgICAgJHNjaGVtYSA9IEJhc2VDb25zdHJhaW50OjphcnJheVRvT2JqZWN0UmVjdXJzaXZlKCRzY2hlbWEpOwogICAgICAgIH0KCiAgICAgICAgLy8gd29ya2Fyb3VuZCBmb3IgYnVnIGluIGRyYWZ0LTAzICYgZHJhZnQtMDQgbWV0YS1zY2hlbWFzIChpZCAmICRyZWYgZGVmaW5lZCB3aXRoIGluY29ycmVjdCBmb3JtYXQpCiAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qc29uLXNjaGVtYS1vcmcvSlNPTi1TY2hlbWEtVGVzdC1TdWl0ZS9pc3N1ZXMvMTc3I2lzc3VlY29tbWVudC0yOTMwNTEzNjcKICAgICAgICBpZiAoaXNfb2JqZWN0KCRzY2hlbWEpICYmIHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnaWQnKSkgewogICAgICAgICAgICBpZiAoJHNjaGVtYS0+aWQgPT0gJ2h0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIycpIHsKICAgICAgICAgICAgICAgICRzY2hlbWEtPnByb3BlcnRpZXMtPmlkLT5mb3JtYXQgPSAndXJpLXJlZmVyZW5jZSc7CiAgICAgICAgICAgIH0gZWxzZWlmICgkc2NoZW1hLT5pZCA9PSAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wMy9zY2hlbWEjJykgewogICAgICAgICAgICAgICAgJHNjaGVtYS0+cHJvcGVydGllcy0+aWQtPmZvcm1hdCA9ICd1cmktcmVmZXJlbmNlJzsKICAgICAgICAgICAgICAgICRzY2hlbWEtPnByb3BlcnRpZXMtPnsnJHJlZid9LT5mb3JtYXQgPSAndXJpLXJlZmVyZW5jZSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHJlc29sdmUgcmVmZXJlbmNlcwogICAgICAgICR0aGlzLT5leHBhbmRSZWZzKCRzY2hlbWEsICRpZCk7CgogICAgICAgICR0aGlzLT5zY2hlbWFzWyRpZF0gPSAkc2NoZW1hOwogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgcmVzb2x2ZSBhbGwgcmVmZXJlbmNlcyBhZ2FpbnN0IHRoZSBwcm92aWRlZCBiYXNlCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXhwYW5kUmVmcygmJHNjaGVtYSwgJGJhc2UgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNfb2JqZWN0KCRzY2hlbWEpKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkc2NoZW1hKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHNjaGVtYSBhcyAmJG1lbWJlcikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5leHBhbmRSZWZzKCRtZW1iZXIsICRiYXNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnaWQnKSAmJiBpc19zdHJpbmcoJHNjaGVtYS0+aWQpICYmICRiYXNlICE9ICRzY2hlbWEtPmlkKSB7CiAgICAgICAgICAgICRiYXNlID0gJHRoaXMtPnVyaVJlc29sdmVyLT5yZXNvbHZlKCRzY2hlbWEtPmlkLCAkYmFzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAocHJvcGVydHlfZXhpc3RzKCRzY2hlbWEsICckcmVmJykgJiYgaXNfc3RyaW5nKCRzY2hlbWEtPnsnJHJlZid9KSkgewogICAgICAgICAgICAkcmVmUG9pbnRlciA9IG5ldyBKc29uUG9pbnRlcigkdGhpcy0+dXJpUmVzb2x2ZXItPnJlc29sdmUoJHNjaGVtYS0+eyckcmVmJ30sICRiYXNlKSk7CiAgICAgICAgICAgICRzY2hlbWEtPnsnJHJlZid9ID0gKHN0cmluZykgJHJlZlBvaW50ZXI7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkc2NoZW1hIGFzICYkbWVtYmVyKSB7CiAgICAgICAgICAgICR0aGlzLT5leHBhbmRSZWZzKCRtZW1iZXIsICRiYXNlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY2hlbWEoJGlkKQogICAgewogICAgICAgIGlmICghYXJyYXlfa2V5X2V4aXN0cygkaWQsICR0aGlzLT5zY2hlbWFzKSkgewogICAgICAgICAgICAkdGhpcy0+YWRkU2NoZW1hKCRpZCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtYXNbJGlkXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVSZWYoJHJlZikKICAgIHsKICAgICAgICAkanNvblBvaW50ZXIgPSBuZXcgSnNvblBvaW50ZXIoJHJlZik7CgogICAgICAgIC8vIHJlc29sdmUgZmlsZW5hbWUgZm9yIHBvaW50ZXIKICAgICAgICAkZmlsZU5hbWUgPSAkanNvblBvaW50ZXItPmdldEZpbGVuYW1lKCk7CiAgICAgICAgaWYgKCFzdHJsZW4oJGZpbGVOYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5yZXNvbHZhYmxlSnNvblBvaW50ZXJFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICJDb3VsZCBub3QgcmVzb2x2ZSBmcmFnbWVudCAnJXMnOiBubyBmaWxlIGlzIGRlZmluZWQiLAogICAgICAgICAgICAgICAgJGpzb25Qb2ludGVyLT5nZXRQcm9wZXJ0eVBhdGhBc1N0cmluZygpCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgLy8gZ2V0ICYgcHJvY2VzcyB0aGUgc2NoZW1hCiAgICAgICAgJHJlZlNjaGVtYSA9ICR0aGlzLT5nZXRTY2hlbWEoJGZpbGVOYW1lKTsKICAgICAgICBmb3JlYWNoICgkanNvblBvaW50ZXItPmdldFByb3BlcnR5UGF0aHMoKSBhcyAkcGF0aCkgewogICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRyZWZTY2hlbWEpICYmIHByb3BlcnR5X2V4aXN0cygkcmVmU2NoZW1hLCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICRyZWZTY2hlbWEgPSAkdGhpcy0+cmVzb2x2ZVJlZlNjaGVtYSgkcmVmU2NoZW1hLT57JHBhdGh9KTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2FycmF5KCRyZWZTY2hlbWEpICYmIGFycmF5X2tleV9leGlzdHMoJHBhdGgsICRyZWZTY2hlbWEpKSB7CiAgICAgICAgICAgICAgICAkcmVmU2NoZW1hID0gJHRoaXMtPnJlc29sdmVSZWZTY2hlbWEoJHJlZlNjaGVtYVskcGF0aF0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVzb2x2YWJsZUpzb25Qb2ludGVyRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0ZpbGU6ICVzIGlzIGZvdW5kLCBidXQgY291bGQgbm90IHJlc29sdmUgZnJhZ21lbnQ6ICVzJywKICAgICAgICAgICAgICAgICAgICAkanNvblBvaW50ZXItPmdldEZpbGVuYW1lKCksCiAgICAgICAgICAgICAgICAgICAgJGpzb25Qb2ludGVyLT5nZXRQcm9wZXJ0eVBhdGhBc1N0cmluZygpCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZWZTY2hlbWE7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNvbHZlUmVmU2NoZW1hKCRyZWZTY2hlbWEpCiAgICB7CiAgICAgICAgaWYgKGlzX29iamVjdCgkcmVmU2NoZW1hKSAmJiBwcm9wZXJ0eV9leGlzdHMoJHJlZlNjaGVtYSwgJyRyZWYnKSAmJiBpc19zdHJpbmcoJHJlZlNjaGVtYS0+eyckcmVmJ30pKSB7CiAgICAgICAgICAgICRuZXdTY2hlbWEgPSAkdGhpcy0+cmVzb2x2ZVJlZigkcmVmU2NoZW1hLT57JyRyZWYnfSk7CiAgICAgICAgICAgICRyZWZTY2hlbWEgPSAob2JqZWN0KSAoZ2V0X29iamVjdF92YXJzKCRyZWZTY2hlbWEpICsgZ2V0X29iamVjdF92YXJzKCRuZXdTY2hlbWEpKTsKICAgICAgICAgICAgdW5zZXQoJHJlZlNjaGVtYS0+eyckcmVmJ30pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZWZTY2hlbWE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqLwpjbGFzcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRXhjZXB0aW9uOwoKLyoqCiAqIFdyYXBwZXIgZm9yIHRoZSBJbnZhbGlkU2NoZW1hTWVkaWFUeXBlCiAqLwpjbGFzcyBJbnZhbGlkU2NoZW1hTWVkaWFUeXBlRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbgogKi8KY2xhc3MgSW52YWxpZENvbmZpZ0V4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIFVyaVJlc29sdmVyRXhjZXB0aW9uCiAqLwpjbGFzcyBVcmlSZXNvbHZlckV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgppbnRlcmZhY2UgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRXhjZXB0aW9uOwoKLyoqCiAqIEBwYWNrYWdlIEpzb25TY2hlbWFcRXhjZXB0aW9uCiAqCiAqIEBhdXRob3IgSm9vc3QgTmlqaHVpcyA8am5pamh1aXM4MUBnbWFpbC5jb20+CiAqLwpjbGFzcyBVbnJlc29sdmFibGVKc29uUG9pbnRlckV4Y2VwdGlvbiBleHRlbmRzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgSW52YWxpZFNjaGVtYU1lZGlhVHlwZQogKi8KY2xhc3MgSW52YWxpZFNjaGVtYUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIEpzb25EZWNvZGluZ0V4Y2VwdGlvbgogKi8KY2xhc3MgSnNvbkRlY29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgp7CiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvZGUgPSBKU09OX0VSUk9SX05PTkUsIFxFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRjb2RlKSB7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9ERVBUSDoKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ1RoZSBtYXhpbXVtIHN0YWNrIGRlcHRoIGhhcyBiZWVuIGV4Y2VlZGVkJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfU1RBVEVfTUlTTUFUQ0g6CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdJbnZhbGlkIG9yIG1hbGZvcm1lZCBKU09OJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfQ1RSTF9DSEFSOgogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnQ29udHJvbCBjaGFyYWN0ZXIgZXJyb3IsIHBvc3NpYmx5IGluY29ycmVjdGx5IGVuY29kZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9VVEY4OgogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnTWFsZm9ybWVkIFVURi04IGNoYXJhY3RlcnMsIHBvc3NpYmx5IGluY29ycmVjdGx5IGVuY29kZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9TWU5UQVg6CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdKU09OIHN5bnRheCBpcyBtYWxmb3JtZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdTeW50YXggZXJyb3InOwogICAgICAgIH0KICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkY29kZSwgJHByZXZpb3VzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRXhjZXB0aW9uOwoKY2xhc3MgVmFsaWRhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIFJ1bnRpbWVFeGNlcHRpb24KICovCmNsYXNzIFJ1bnRpbWVFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbgogKi8KY2xhc3MgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIEludmFsaWRTb3VyY2VVcmlFeGNlcHRpb24KICovCmNsYXNzIEludmFsaWRTb3VyY2VVcmlFeGNlcHRpb24gZXh0ZW5kcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYTsKCi8qKgogKiBAcGFja2FnZSBKc29uU2NoZW1hCiAqLwppbnRlcmZhY2UgVXJpUmVzb2x2ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXNvbHZlcyBhIFVSSQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdXJpICAgICBBYnNvbHV0ZSBvciByZWxhdGl2ZQogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRiYXNlVXJpIE9wdGlvbmFsIGJhc2UgVVJJCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgQWJzb2x1dGUgVVJJCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNvbHZlKCR1cmksICRiYXNlVXJpID0gbnVsbCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwoKLyoqCiAqIFRoZSBCYXNlIENvbnN0cmFpbnRzLCBhbGwgVmFsaWRhdG9ycyBzaG91bGQgZXh0ZW5kIHRoaXMgY2xhc3MKICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgQnJ1bm8gUHJpZXRvIFJlaXMgPGJydW5vLnAucmVpc0BnbWFpbC5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBDb25zdHJhaW50IGV4dGVuZHMgQmFzZUNvbnN0cmFpbnQgaW1wbGVtZW50cyBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIHByb3RlY3RlZCAkaW5saW5lU2NoZW1hUHJvcGVydHkgPSAnJHNjaGVtYSc7CgogICAgY29uc3QgQ0hFQ0tfTU9ERV9OT05FID0gICAgICAgICAgICAgMHgwMDAwMDAwMDsKICAgIGNvbnN0IENIRUNLX01PREVfTk9STUFMID0gICAgICAgICAgIDB4MDAwMDAwMDE7CiAgICBjb25zdCBDSEVDS19NT0RFX1RZUEVfQ0FTVCA9ICAgICAgICAweDAwMDAwMDAyOwogICAgY29uc3QgQ0hFQ0tfTU9ERV9DT0VSQ0VfVFlQRVMgPSAgICAgMHgwMDAwMDAwNDsKICAgIGNvbnN0IENIRUNLX01PREVfQVBQTFlfREVGQVVMVFMgPSAgIDB4MDAwMDAwMDg7CiAgICBjb25zdCBDSEVDS19NT0RFX0VYQ0VQVElPTlMgPSAgICAgICAweDAwMDAwMDEwOwogICAgY29uc3QgQ0hFQ0tfTU9ERV9ESVNBQkxFX0ZPUk1BVCA9ICAgMHgwMDAwMDAyMDsKICAgIGNvbnN0IENIRUNLX01PREVfT05MWV9SRVFVSVJFRF9ERUZBVUxUUyAgID0gMHgwMDAwMDA4MDsKICAgIGNvbnN0IENIRUNLX01PREVfVkFMSURBVEVfU0NIRU1BID0gIDB4MDAwMDAxMDA7CgogICAgLyoqCiAgICAgKiBCdWJibGUgZG93biB0aGUgcGF0aAogICAgICoKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoIEN1cnJlbnQgcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJGkgICAgV2hhdCB0byBhcHBlbmQgdG8gdGhlIHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIEpzb25Qb2ludGVyOwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5jcmVtZW50UGF0aChKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpKQogICAgewogICAgICAgICRwYXRoID0gJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKTsKCiAgICAgICAgaWYgKCRpID09PSBudWxsIHx8ICRpID09PSAnJykgewogICAgICAgICAgICByZXR1cm4gJHBhdGg7CiAgICAgICAgfQoKICAgICAgICAkcGF0aCA9ICRwYXRoLT53aXRoUHJvcGVydHlQYXRocygKICAgICAgICAgICAgYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAkcGF0aC0+Z2V0UHJvcGVydHlQYXRocygpLAogICAgICAgICAgICAgICAgYXJyYXkoJGkpCiAgICAgICAgICAgICkKICAgICAgICApOwoKICAgICAgICByZXR1cm4gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgYW4gYXJyYXkKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tBcnJheSgmJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignY29sbGVjdGlvbicpOwogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKCiAgICAgICAgJHRoaXMtPmFkZEVycm9ycygkdmFsaWRhdG9yLT5nZXRFcnJvcnMoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgYW4gb2JqZWN0CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHByb3BlcnRpZXMKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRhZGRpdGlvbmFsUHJvcGVydGllcwogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHBhdHRlcm5Qcm9wZXJ0aWVzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja09iamVjdCgmJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkcHJvcGVydGllcyA9IG51bGwsCiAgICAgICAgJGFkZGl0aW9uYWxQcm9wZXJ0aWVzID0gbnVsbCwgJHBhdHRlcm5Qcm9wZXJ0aWVzID0gbnVsbCwgJGFwcGxpZWREZWZhdWx0cyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignb2JqZWN0Jyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJHByb3BlcnRpZXMsICRhZGRpdGlvbmFsUHJvcGVydGllcywgJHBhdHRlcm5Qcm9wZXJ0aWVzLCAkYXBwbGllZERlZmF1bHRzKTsKCiAgICAgICAgJHRoaXMtPmFkZEVycm9ycygkdmFsaWRhdG9yLT5nZXRFcnJvcnMoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIHR5cGUgb2YgYSBwcm9wZXJ0eQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja1R5cGUoJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgICR2YWxpZGF0b3IgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ3R5cGUnKTsKICAgICAgICAkdmFsaWRhdG9yLT5jaGVjaygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGEgdW5kZWZpbmVkIGVsZW1lbnQKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tVbmRlZmluZWQoJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsLCAkZnJvbURlZmF1bHQgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdmFsaWRhdG9yID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCd1bmRlZmluZWQnKTsKCiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkdGhpcy0+ZmFjdG9yeS0+Z2V0U2NoZW1hU3RvcmFnZSgpLT5yZXNvbHZlUmVmU2NoZW1hKCRzY2hlbWEpLCAkcGF0aCwgJGksICRmcm9tRGVmYXVsdCk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGEgc3RyaW5nIGVsZW1lbnQKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tTdHJpbmcoJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignc3RyaW5nJyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKCR2YWxpZGF0b3ItPmdldEVycm9ycygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhIG51bWJlciBlbGVtZW50CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlciAkcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja051bWJlcigkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAkdmFsaWRhdG9yID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCdudW1iZXInKTsKICAgICAgICAkdmFsaWRhdG9yLT5jaGVjaygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGEgZW51bSBlbGVtZW50CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrRW51bSgkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAkdmFsaWRhdG9yID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCdlbnVtJyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKCR2YWxpZGF0b3ItPmdldEVycm9ycygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBmb3JtYXQgb2YgYW4gZWxlbWVudAogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0Zvcm1hdCgkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAkdmFsaWRhdG9yID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCdmb3JtYXQnKTsKICAgICAgICAkdmFsaWRhdG9yLT5jaGVjaygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB0eXBlIGNoZWNrIGJhc2VkIG9uIHRoZSBzZXQgY2hlY2sgbW9kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFR5cGVDaGVja1xUeXBlQ2hlY2tJbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFR5cGVDaGVjaygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mYWN0b3J5LT5nZXRUeXBlQ2hlY2soKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlciAkcG9pbnRlcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHByb3BlcnR5IHBhdGgKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnZlcnRKc29uUG9pbnRlckludG9Qcm9wZXJ0eVBhdGgoSnNvblBvaW50ZXIgJHBvaW50ZXIpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9IGFycmF5X21hcCgKICAgICAgICAgICAgZnVuY3Rpb24gKCRwYXRoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50Zihpc19udW1lcmljKCRwYXRoKSA/ICdbJWRdJyA6ICcuJXMnLCAkcGF0aCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICRwb2ludGVyLT5nZXRQcm9wZXJ0eVBhdGhzKCkKICAgICAgICApOwoKICAgICAgICByZXR1cm4gdHJpbShpbXBsb2RlKCcnLCAkcmVzdWx0KSwgJy4nKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFbnRpdHlcSnNvblBvaW50ZXI7CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkU2NoZW1hRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVmFsaWRhdG9yOwoKLyoqCiAqIFRoZSBTY2hlbWFDb25zdHJhaW50IENvbnN0cmFpbnRzLCB2YWxpZGF0ZXMgYW4gZWxlbWVudCBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgU2NoZW1hQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgY29uc3QgREVGQVVMVF9TQ0hFTUFfU1BFQyA9ICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMnOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiRlbGVtZW50LCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRzY2hlbWEgIT09IG51bGwpIHsKICAgICAgICAgICAgLy8gcGFzc2VkIHNjaGVtYQogICAgICAgICAgICAkdmFsaWRhdGlvblNjaGVtYSA9ICRzY2hlbWE7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlFeGlzdHMoJGVsZW1lbnQsICR0aGlzLT5pbmxpbmVTY2hlbWFQcm9wZXJ0eSkpIHsKICAgICAgICAgICAgLy8gaW5saW5lIHNjaGVtYQogICAgICAgICAgICAkdmFsaWRhdGlvblNjaGVtYSA9ICR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlHZXQoJGVsZW1lbnQsICR0aGlzLT5pbmxpbmVTY2hlbWFQcm9wZXJ0eSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignbm8gc2NoZW1hIGZvdW5kIHRvIHZlcmlmeSBhZ2FpbnN0Jyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjYXN0IGFycmF5IHNjaGVtYXMgdG8gb2JqZWN0CiAgICAgICAgaWYgKGlzX2FycmF5KCR2YWxpZGF0aW9uU2NoZW1hKSkgewogICAgICAgICAgICAkdmFsaWRhdGlvblNjaGVtYSA9IEJhc2VDb25zdHJhaW50OjphcnJheVRvT2JqZWN0UmVjdXJzaXZlKCR2YWxpZGF0aW9uU2NoZW1hKTsKICAgICAgICB9CgogICAgICAgIC8vIHZhbGlkYXRlIHNjaGVtYSBhZ2FpbnN0IHdoYXRldmVyIGlzIGRlZmluZWQgaW4gJHZhbGlkYXRpb25TY2hlbWEtPiRzY2hlbWEuIElmIG5vCiAgICAgICAgLy8gc2NoZW1hIGlzIGRlZmluZWQsIGFzc3VtZSBzZWxmOjpERUZBVUxUX1NDSEVNQV9TUEVDIChjdXJyZW50bHkgZHJhZnQtMDQpLgogICAgICAgIGlmICgkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKHNlbGY6OkNIRUNLX01PREVfVkFMSURBVEVfU0NIRU1BKSkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+aXNPYmplY3QoJHZhbGlkYXRpb25TY2hlbWEpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignQ2Fubm90IHZhbGlkYXRlIHRoZSBzY2hlbWEgb2YgYSBub24tb2JqZWN0Jyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlFeGlzdHMoJHZhbGlkYXRpb25TY2hlbWEsICckc2NoZW1hJykpIHsKICAgICAgICAgICAgICAgICRzY2hlbWFTcGVjID0gJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUdldCgkdmFsaWRhdGlvblNjaGVtYSwgJyRzY2hlbWEnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRzY2hlbWFTcGVjID0gc2VsZjo6REVGQVVMVF9TQ0hFTUFfU1BFQzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gZ2V0IHRoZSBzcGVjIHNjaGVtYQogICAgICAgICAgICAkc2NoZW1hU3RvcmFnZSA9ICR0aGlzLT5mYWN0b3J5LT5nZXRTY2hlbWFTdG9yYWdlKCk7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmdldFR5cGVDaGVjaygpLT5pc09iamVjdCgkc2NoZW1hU3BlYykpIHsKICAgICAgICAgICAgICAgICRzY2hlbWFTcGVjID0gJHNjaGVtYVN0b3JhZ2UtPmdldFNjaGVtYSgkc2NoZW1hU3BlYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNhdmUgZXJyb3IgY291bnQsIGNvbmZpZyAmIHN1YnRyYWN0IENIRUNLX01PREVfVkFMSURBVEVfU0NIRU1BCiAgICAgICAgICAgICRpbml0aWFsRXJyb3JDb3VudCA9ICR0aGlzLT5udW1FcnJvcnMoKTsKICAgICAgICAgICAgJGluaXRpYWxDb25maWcgPSAkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKCk7CiAgICAgICAgICAgICRpbml0aWFsQ29udGV4dCA9ICR0aGlzLT5mYWN0b3J5LT5nZXRFcnJvckNvbnRleHQoKTsKICAgICAgICAgICAgJHRoaXMtPmZhY3RvcnktPnJlbW92ZUNvbmZpZyhzZWxmOjpDSEVDS19NT0RFX1ZBTElEQVRFX1NDSEVNQSB8IHNlbGY6OkNIRUNLX01PREVfQVBQTFlfREVGQVVMVFMpOwogICAgICAgICAgICAkdGhpcy0+ZmFjdG9yeS0+YWRkQ29uZmlnKHNlbGY6OkNIRUNLX01PREVfVFlQRV9DQVNUKTsKICAgICAgICAgICAgJHRoaXMtPmZhY3RvcnktPnNldEVycm9yQ29udGV4dChWYWxpZGF0b3I6OkVSUk9SX1NDSEVNQV9WQUxJREFUSU9OKTsKCiAgICAgICAgICAgIC8vIHZhbGlkYXRlIHNjaGVtYQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrKCR2YWxpZGF0aW9uU2NoZW1hLCAkc2NoZW1hU3BlYyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKHNlbGY6OkNIRUNLX01PREVfRVhDRVBUSU9OUykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFNjaGVtYUV4Y2VwdGlvbignU2NoZW1hIGRpZCBub3QgcGFzcyB2YWxpZGF0aW9uJywgMCwgJGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+bnVtRXJyb3JzKCkgPiAkaW5pdGlhbEVycm9yQ291bnQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1NjaGVtYSBpcyBub3QgdmFsaWQnLCAnc2NoZW1hJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlc3RvcmUgdGhlIGluaXRpYWwgY29uZmlnCiAgICAgICAgICAgICR0aGlzLT5mYWN0b3J5LT5zZXRDb25maWcoJGluaXRpYWxDb25maWcpOwogICAgICAgICAgICAkdGhpcy0+ZmFjdG9yeS0+c2V0RXJyb3JDb250ZXh0KCRpbml0aWFsQ29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICAvLyB2YWxpZGF0ZSBlbGVtZW50IGFnYWluc3QgJHZhbGlkYXRpb25TY2hlbWEKICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJGVsZW1lbnQsICR2YWxpZGF0aW9uU2NoZW1hLCAkcGF0aCwgJGkpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKCi8qKgogKiBUaGUgQ29sbGVjdGlvbkNvbnN0cmFpbnQgQ29uc3RyYWludHMsIHZhbGlkYXRlcyBhbiBhcnJheSBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgQ29sbGVjdGlvbkNvbnN0cmFpbnQgZXh0ZW5kcyBDb25zdHJhaW50CnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgIC8vIFZlcmlmeSBtaW5JdGVtcwogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5taW5JdGVtcykgJiYgY291bnQoJHZhbHVlKSA8ICRzY2hlbWEtPm1pbkl0ZW1zKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1RoZXJlIG11c3QgYmUgYSBtaW5pbXVtIG9mICcgLiAkc2NoZW1hLT5taW5JdGVtcyAuICcgaXRlbXMgaW4gdGhlIGFycmF5JywgJ21pbkl0ZW1zJywgYXJyYXkoJ21pbkl0ZW1zJyA9PiAkc2NoZW1hLT5taW5JdGVtcykpOwogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IG1heEl0ZW1zCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPm1heEl0ZW1zKSAmJiBjb3VudCgkdmFsdWUpID4gJHNjaGVtYS0+bWF4SXRlbXMpIHsKICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnVGhlcmUgbXVzdCBiZSBhIG1heGltdW0gb2YgJyAuICRzY2hlbWEtPm1heEl0ZW1zIC4gJyBpdGVtcyBpbiB0aGUgYXJyYXknLCAnbWF4SXRlbXMnLCBhcnJheSgnbWF4SXRlbXMnID0+ICRzY2hlbWEtPm1heEl0ZW1zKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgdW5pcXVlSXRlbXMKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+dW5pcXVlSXRlbXMpICYmICRzY2hlbWEtPnVuaXF1ZUl0ZW1zKSB7CiAgICAgICAgICAgICR1bmlxdWUgPSAkdmFsdWU7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdmFsdWUpICYmIGNvdW50KCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR1bmlxdWUgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhcl9leHBvcnQoJGUsIHRydWUpOwogICAgICAgICAgICAgICAgfSwgJHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY291bnQoYXJyYXlfdW5pcXVlKCR1bmlxdWUpKSAhPSBjb3VudCgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdUaGVyZSBhcmUgbm8gZHVwbGljYXRlcyBhbGxvd2VkIGluIHRoZSBhcnJheScsICd1bmlxdWVJdGVtcycpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgaXRlbXMKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+aXRlbXMpKSB7CiAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZUl0ZW1zKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGl0ZW1zCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gXHN0ZENsYXNzICAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlSXRlbXMoJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgIGlmIChpc19vYmplY3QoJHNjaGVtYS0+aXRlbXMpKSB7CiAgICAgICAgICAgIC8vIGp1c3Qgb25lIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIHdob2xlIGFycmF5CiAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZSBhcyAkayA9PiAmJHYpIHsKICAgICAgICAgICAgICAgICRpbml0RXJyb3JzID0gJHRoaXMtPmdldEVycm9ycygpOwoKICAgICAgICAgICAgICAgIC8vIEZpcnN0IGNoZWNrIGlmIGl0cyBkZWZpbmVkIGluICJpdGVtcyIKICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdiwgJHNjaGVtYS0+aXRlbXMsICRwYXRoLCAkayk7CgogICAgICAgICAgICAgICAgLy8gUmVjaGVjayB3aXRoICJhZGRpdGlvbmFsSXRlbXMiIGlmIHRoZSBmaXJzdCB0ZXN0IGZhaWxzCiAgICAgICAgICAgICAgICBpZiAoY291bnQoJGluaXRFcnJvcnMpIDwgY291bnQoJHRoaXMtPmdldEVycm9ycygpKSAmJiAoaXNzZXQoJHNjaGVtYS0+YWRkaXRpb25hbEl0ZW1zKSAmJiAkc2NoZW1hLT5hZGRpdGlvbmFsSXRlbXMgIT09IGZhbHNlKSkgewogICAgICAgICAgICAgICAgICAgICRzZWNvbmRFcnJvcnMgPSAkdGhpcy0+Z2V0RXJyb3JzKCk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2LCAkc2NoZW1hLT5hZGRpdGlvbmFsSXRlbXMsICRwYXRoLCAkayk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUmVzZXQgZXJyb3JzIGlmIG5lZWRlZAogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzZWNvbmRFcnJvcnMpICYmIGNvdW50KCRzZWNvbmRFcnJvcnMpIDwgY291bnQoJHRoaXMtPmdldEVycm9ycygpKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnMgPSAkc2Vjb25kRXJyb3JzOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRzZWNvbmRFcnJvcnMpICYmIGNvdW50KCRzZWNvbmRFcnJvcnMpID09PSBjb3VudCgkdGhpcy0+Z2V0RXJyb3JzKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9ycyA9ICRpbml0RXJyb3JzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCR2KTsgLyogcmVtb3ZlIGRhbmdsaW5nIHJlZmVyZW5jZSB0byBwcmV2ZW50IGFueSBmdXR1cmUgYnVncwogICAgICAgICAgICAgICAgICAgICAgICAqIGNhdXNlZCBieSBhY2NpZGVudGFsbHkgdXNpbmcgJHYgZWxzZXdoZXJlICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gRGVmaW5lZCBpdGVtIHR5cGUgZGVmaW5pdGlvbnMKICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlIGFzICRrID0+ICYkdikgewogICAgICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJGssICRzY2hlbWEtPml0ZW1zKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdiwgJHNjaGVtYS0+aXRlbXNbJGtdLCAkcGF0aCwgJGspOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIGl0ZW1zCiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnYWRkaXRpb25hbEl0ZW1zJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRzY2hlbWEtPmFkZGl0aW9uYWxJdGVtcyAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdiwgJHNjaGVtYS0+YWRkaXRpb25hbEl0ZW1zLCAkcGF0aCwgJGspOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoLCAnVGhlIGl0ZW0gJyAuICRpIC4gJ1snIC4gJGsgLiAnXSBpcyBub3QgZGVmaW5lZCBhbmQgdGhlIGRlZmluaXRpb24gZG9lcyBub3QgYWxsb3cgYWRkaXRpb25hbCBpdGVtcycsICdhZGRpdGlvbmFsSXRlbXMnLCBhcnJheSgnYWRkaXRpb25hbEl0ZW1zJyA9PiAkc2NoZW1hLT5hZGRpdGlvbmFsSXRlbXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNob3VsZCBiZSB2YWxpZCBhZ2FpbnN0IGFuIGVtcHR5IHNjaGVtYQogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHYsIG5ldyBcc3RkQ2xhc3MoKSwgJHBhdGgsICRrKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5zZXQoJHYpOyAvKiByZW1vdmUgZGFuZ2xpbmcgcmVmZXJlbmNlIHRvIHByZXZlbnQgYW55IGZ1dHVyZSBidWdzCiAgICAgICAgICAgICAgICAgICAgICAgICogY2F1c2VkIGJ5IGFjY2lkZW50YWxseSB1c2luZyAkdiBlbHNld2hlcmUgKi8KCiAgICAgICAgICAgIC8vIFRyZWF0IHdoZW4gd2UgaGF2ZSBtb3JlIHNjaGVtYSBkZWZpbml0aW9ucyB0aGFuIHZhbHVlcywgbm90IGZvciBlbXB0eSBhcnJheXMKICAgICAgICAgICAgaWYgKGNvdW50KCR2YWx1ZSkgPiAwKSB7CiAgICAgICAgICAgICAgICBmb3IgKCRrID0gY291bnQoJHZhbHVlKTsgJGsgPCBjb3VudCgkc2NoZW1hLT5pdGVtcyk7ICRrKyspIHsKICAgICAgICAgICAgICAgICAgICAkdW5kZWZpbmVkSW5zdGFuY2UgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ3VuZGVmaW5lZCcpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdW5kZWZpbmVkSW5zdGFuY2UsICRzY2hlbWEtPml0ZW1zWyRrXSwgJHBhdGgsICRrKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHNcVHlwZUNoZWNrOwoKaW50ZXJmYWNlIFR5cGVDaGVja0ludGVyZmFjZQp7CiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzT2JqZWN0KCR2YWx1ZSk7CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc0FycmF5KCR2YWx1ZSk7CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eUdldCgkdmFsdWUsICRwcm9wZXJ0eSk7CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eVNldCgmJHZhbHVlLCAkcHJvcGVydHksICRkYXRhKTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5RXhpc3RzKCR2YWx1ZSwgJHByb3BlcnR5KTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5Q291bnQoJHZhbHVlKTsKfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHNcVHlwZUNoZWNrOwoKY2xhc3MgU3RyaWN0VHlwZUNoZWNrIGltcGxlbWVudHMgVHlwZUNoZWNrSW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNPYmplY3QoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiBpc19vYmplY3QoJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzQXJyYXkoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiBpc19hcnJheSgkdmFsdWUpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvcGVydHlHZXQoJHZhbHVlLCAkcHJvcGVydHkpCiAgICB7CiAgICAgICAgcmV0dXJuICR2YWx1ZS0+eyRwcm9wZXJ0eX07CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eVNldCgmJHZhbHVlLCAkcHJvcGVydHksICRkYXRhKQogICAgewogICAgICAgICR2YWx1ZS0+eyRwcm9wZXJ0eX0gPSAkZGF0YTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5RXhpc3RzKCR2YWx1ZSwgJHByb3BlcnR5KQogICAgewogICAgICAgIHJldHVybiBwcm9wZXJ0eV9leGlzdHMoJHZhbHVlLCAkcHJvcGVydHkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvcGVydHlDb3VudCgkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCFpc19vYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjb3VudChnZXRfb2JqZWN0X3ZhcnMoJHZhbHVlKSk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzXFR5cGVDaGVjazsKCmNsYXNzIExvb3NlVHlwZUNoZWNrIGltcGxlbWVudHMgVHlwZUNoZWNrSW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNPYmplY3QoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybgogICAgICAgICAgICBpc19vYmplY3QoJHZhbHVlKSB8fAogICAgICAgICAgICAoaXNfYXJyYXkoJHZhbHVlKSAmJiAoY291bnQoJHZhbHVlKSA9PSAwIHx8IHNlbGY6OmlzQXNzb2NpYXRpdmVBcnJheSgkdmFsdWUpKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc0FycmF5KCR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgaXNfYXJyYXkoJHZhbHVlKSAmJgogICAgICAgICAgICAoY291bnQoJHZhbHVlKSA9PSAwIHx8ICFzZWxmOjppc0Fzc29jaWF0aXZlQXJyYXkoJHZhbHVlKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eUdldCgkdmFsdWUsICRwcm9wZXJ0eSkKICAgIHsKICAgICAgICBpZiAoaXNfb2JqZWN0KCR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR2YWx1ZS0+eyRwcm9wZXJ0eX07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlWyRwcm9wZXJ0eV07CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eVNldCgmJHZhbHVlLCAkcHJvcGVydHksICRkYXRhKQogICAgewogICAgICAgIGlmIChpc19vYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICAkdmFsdWUtPnskcHJvcGVydHl9ID0gJGRhdGE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHZhbHVlWyRwcm9wZXJ0eV0gPSAkZGF0YTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eUV4aXN0cygkdmFsdWUsICRwcm9wZXJ0eSkKICAgIHsKICAgICAgICBpZiAoaXNfb2JqZWN0KCR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5X2V4aXN0cygkdmFsdWUsICRwcm9wZXJ0eSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfa2V5X2V4aXN0cygkcHJvcGVydHksICR2YWx1ZSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eUNvdW50KCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoaXNfb2JqZWN0KCR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGNvdW50KGdldF9vYmplY3RfdmFycygkdmFsdWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjb3VudCgkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgdGhlIHByb3ZpZGVkIGFycmF5IGlzIGFzc29jaWF0aXZlIG9yIG5vdAogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkYXJyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzQXNzb2NpYXRpdmVBcnJheSgkYXJyKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9rZXlzKCRhcnIpICE9PSByYW5nZSgwLCBjb3VudCgkYXJyKSAtIDEpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKdXNlIEpzb25TY2hlbWFcUmZjMzMzOTsKCi8qKgogKiBWYWxpZGF0ZXMgYWdhaW5zdCB0aGUgImZvcm1hdCIgcHJvcGVydHkKICoKICogQGF1dGhvciBKdXN0aW4gUmFpbmJvdyA8anVzdGluLnJhaW5ib3dAZ21haWwuY29tPgogKgogKiBAc2VlICAgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvZHJhZnQtenlwLWpzb24tc2NoZW1hLTAzI3NlY3Rpb24tNS4yMwogKi8KY2xhc3MgRm9ybWF0Q29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJGVsZW1lbnQsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCRzY2hlbWEtPmZvcm1hdCkgfHwgJHRoaXMtPmZhY3RvcnktPmdldENvbmZpZyhzZWxmOjpDSEVDS19NT0RFX0RJU0FCTEVfRk9STUFUKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2ggKCRzY2hlbWEtPmZvcm1hdCkgewogICAgICAgICAgICBjYXNlICdkYXRlJzoKICAgICAgICAgICAgICAgIGlmICghJGRhdGUgPSAkdGhpcy0+dmFsaWRhdGVEYXRlVGltZSgkZWxlbWVudCwgJ1ktbS1kJykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsIHNwcmludGYoJ0ludmFsaWQgZGF0ZSAlcywgZXhwZWN0ZWQgZm9ybWF0IFlZWVktTU0tREQnLCBqc29uX2VuY29kZSgkZWxlbWVudCkpLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ3RpbWUnOgogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+dmFsaWRhdGVEYXRlVGltZSgkZWxlbWVudCwgJ0g6aTpzJykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsIHNwcmludGYoJ0ludmFsaWQgdGltZSAlcywgZXhwZWN0ZWQgZm9ybWF0IGhoOm1tOnNzJywganNvbl9lbmNvZGUoJGVsZW1lbnQpKSwgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdkYXRlLXRpbWUnOgogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IFJmYzMzMzk6OmNyZWF0ZUZyb21TdHJpbmcoJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCBzcHJpbnRmKCdJbnZhbGlkIGRhdGUtdGltZSAlcywgZXhwZWN0ZWQgZm9ybWF0IFlZWVktTU0tRERUaGg6bW06c3NaIG9yIFlZWVktTU0tRERUaGg6bW06c3MraGg6bW0nLCBqc29uX2VuY29kZSgkZWxlbWVudCkpLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ3V0Yy1taWxsaXNlYyc6CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZURhdGVUaW1lKCRlbGVtZW50LCAnVScpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCBzcHJpbnRmKCdJbnZhbGlkIHRpbWUgJXMsIGV4cGVjdGVkIGludGVnZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIEVwb2NoJywganNvbl9lbmNvZGUoJGVsZW1lbnQpKSwgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdyZWdleCc6CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZVJlZ2V4KCRlbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgcmVnZXggZm9ybWF0ICcgLiAkZWxlbWVudCwgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdjb2xvcic6CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZUNvbG9yKCRlbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgY29sb3InLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ3N0eWxlJzoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlU3R5bGUoJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCBzdHlsZScsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAncGhvbmUnOgogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+dmFsaWRhdGVQaG9uZSgkZWxlbWVudCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdJbnZhbGlkIHBob25lIG51bWJlcicsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAndXJpJzoKICAgICAgICAgICAgICAgIGlmIChudWxsID09PSBmaWx0ZXJfdmFyKCRlbGVtZW50LCBGSUxURVJfVkFMSURBVEVfVVJMLCBGSUxURVJfTlVMTF9PTl9GQUlMVVJFKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgVVJMIGZvcm1hdCcsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAndXJpcmVmJzoKICAgICAgICAgICAgY2FzZSAndXJpLXJlZmVyZW5jZSc6CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gZmlsdGVyX3ZhcigkZWxlbWVudCwgRklMVEVSX1ZBTElEQVRFX1VSTCwgRklMVEVSX05VTExfT05fRkFJTFVSRSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBGSUxURVJfVkFMSURBVEVfVVJMIGRvZXMgbm90IGNvbmZvcm0gdG8gUkZDLTM5ODYsIGFuZCBjYW5ub3QgaGFuZGxlIHJlbGF0aXZlIFVSTHMsIGJ1dAogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBqc29uLXNjaGVtYSBzcGVjIHVzZXMgUkZDLTM5ODYsIHNvIG5lZWQgYSBiaXQgb2YgaGFja2VyeSB0byBwcm9wZXJseSB2YWxpZGF0ZSB0aGVtLgogICAgICAgICAgICAgICAgICAgIC8vIFNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzk4NiNzZWN0aW9uLTQuMiBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi4KICAgICAgICAgICAgICAgICAgICBpZiAoc3Vic3RyKCRlbGVtZW50LCAwLCAyKSA9PT0gJy8vJykgeyAvLyBuZXR3b3JrLXBhdGggcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICR2YWxpZFVSTCA9IGZpbHRlcl92YXIoJ3NjaGVtZTonIC4gJGVsZW1lbnQsIEZJTFRFUl9WQUxJREFURV9VUkwsIEZJTFRFUl9OVUxMX09OX0ZBSUxVUkUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChzdWJzdHIoJGVsZW1lbnQsIDAsIDEpID09PSAnLycpIHsgLy8gYWJzb2x1dGUtcGF0aCByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbGlkVVJMID0gZmlsdGVyX3Zhcignc2NoZW1lOi8vaG9zdCcgLiAkZWxlbWVudCwgRklMVEVSX1ZBTElEQVRFX1VSTCwgRklMVEVSX05VTExfT05fRkFJTFVSRSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHN0cmxlbigkZWxlbWVudCkpIHsgLy8gcmVsYXRpdmUtcGF0aCByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGhQYXJ0cyA9IGV4cGxvZGUoJy8nLCAkZWxlbWVudCwgMik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJHBhdGhQYXJ0c1swXSwgJzonKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWxpZFVSTCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmFsaWRVUkwgPSBmaWx0ZXJfdmFyKCdzY2hlbWU6Ly9ob3N0LycgLiAkZWxlbWVudCwgRklMVEVSX1ZBTElEQVRFX1VSTCwgRklMVEVSX05VTExfT05fRkFJTFVSRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdmFsaWRVUkwgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHZhbGlkVVJMID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgVVJMIGZvcm1hdCcsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ2VtYWlsJzoKICAgICAgICAgICAgICAgICRmaWx0ZXJGbGFncyA9IEZJTFRFUl9OVUxMX09OX0ZBSUxVUkU7CiAgICAgICAgICAgICAgICBpZiAoZGVmaW5lZCgnRklMVEVSX0ZMQUdfRU1BSUxfVU5JQ09ERScpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBhdmFpbGFibGUgZnJvbSBQSFAgPj0gNy4xLjAsIHNvIGlnbm9yZSBpdCBmb3IgY292ZXJhZ2UgY2hlY2tzCiAgICAgICAgICAgICAgICAgICAgJGZpbHRlckZsYWdzIHw9IGNvbnN0YW50KCdGSUxURVJfRkxBR19FTUFJTF9VTklDT0RFJyk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChudWxsID09PSBmaWx0ZXJfdmFyKCRlbGVtZW50LCBGSUxURVJfVkFMSURBVEVfRU1BSUwsICRmaWx0ZXJGbGFncykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdJbnZhbGlkIGVtYWlsJywgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdpcC1hZGRyZXNzJzoKICAgICAgICAgICAgY2FzZSAnaXB2NCc6CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gZmlsdGVyX3ZhcigkZWxlbWVudCwgRklMVEVSX1ZBTElEQVRFX0lQLCBGSUxURVJfTlVMTF9PTl9GQUlMVVJFIHwgRklMVEVSX0ZMQUdfSVBWNCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdJbnZhbGlkIElQIGFkZHJlc3MnLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ2lwdjYnOgogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IGZpbHRlcl92YXIoJGVsZW1lbnQsIEZJTFRFUl9WQUxJREFURV9JUCwgRklMVEVSX05VTExfT05fRkFJTFVSRSB8IEZJTFRFUl9GTEFHX0lQVjYpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCBJUCBhZGRyZXNzJywgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdob3N0LW5hbWUnOgogICAgICAgICAgICBjYXNlICdob3N0bmFtZSc6CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZUhvc3RuYW1lKCRlbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgaG9zdG5hbWUnLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBFbXB0eSBhcyBpdCBzaG91bGQgYmU6CiAgICAgICAgICAgICAgICAvLyBUaGUgdmFsdWUgb2YgdGhpcyBrZXl3b3JkIGlzIGNhbGxlZCBhIGZvcm1hdCBhdHRyaWJ1dGUuIEl0IE1VU1QgYmUgYSBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBBIGZvcm1hdCBhdHRyaWJ1dGUgY2FuIGdlbmVyYWxseSBvbmx5IHZhbGlkYXRlIGEgZ2l2ZW4gc2V0IG9mIGluc3RhbmNlIHR5cGVzLgogICAgICAgICAgICAgICAgLy8gSWYgdGhlIHR5cGUgb2YgdGhlIGluc3RhbmNlIHRvIHZhbGlkYXRlIGlzIG5vdCBpbiB0aGlzIHNldCwgdmFsaWRhdGlvbiBmb3IKICAgICAgICAgICAgICAgIC8vIHRoaXMgZm9ybWF0IGF0dHJpYnV0ZSBhbmQgaW5zdGFuY2UgU0hPVUxEIHN1Y2NlZWQuCiAgICAgICAgICAgICAgICAvLyBodHRwOi8vanNvbi1zY2hlbWEub3JnL2xhdGVzdC9qc29uLXNjaGVtYS12YWxpZGF0aW9uLmh0bWwjYW5jaG9yMTA1CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlRGF0ZVRpbWUoJGRhdGV0aW1lLCAkZm9ybWF0KQogICAgewogICAgICAgICRkdCA9IFxEYXRlVGltZTo6Y3JlYXRlRnJvbUZvcm1hdCgkZm9ybWF0LCAkZGF0ZXRpbWUpOwoKICAgICAgICBpZiAoISRkdCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRhdGV0aW1lID09PSAkZHQtPmZvcm1hdCgkZm9ybWF0KSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZXMgdGhlIGNhc2Ugd2hlcmUgYSBub24tNiBkaWdpdCBtaWNyb3NlY29uZCBkYXRldGltZSBpcyBwYXNzZWQKICAgICAgICAvLyB3aGljaCB3aWxsIGZhaWwgdGhlIGFib3ZlIHN0cmluZyBjb21wYXJpc29uIGJlY2F1c2UgdGhlIHBhc3NlZAogICAgICAgIC8vICRkYXRldGltZSBtYXkgYmUgJzIwMDAtMDUtMDFUMTI6MTI6MTIuMTIzWicgYnV0IGZvcm1hdCgpIHdpbGwgcmV0dXJuCiAgICAgICAgLy8gJzIwMDAtMDUtMDFUMTI6MTI6MTIuMTIzMDAwWicKICAgICAgICBpZiAoKHN0cnBvcygndScsICRmb3JtYXQpICE9PSAtMSkgJiYgKHByZWdfbWF0Y2goJy9cLlxkK1okLycsICRkYXRldGltZSkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZVJlZ2V4KCRyZWdleCkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2UgIT09IEBwcmVnX21hdGNoKCcvJyAuICRyZWdleCAuICcvdScsICcnKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVDb2xvcigkY29sb3IpCiAgICB7CiAgICAgICAgaWYgKGluX2FycmF5KHN0cnRvbG93ZXIoJGNvbG9yKSwgYXJyYXkoJ2FxdWEnLCAnYmxhY2snLCAnYmx1ZScsICdmdWNoc2lhJywKICAgICAgICAgICAgJ2dyYXknLCAnZ3JlZW4nLCAnbGltZScsICdtYXJvb24nLCAnbmF2eScsICdvbGl2ZScsICdvcmFuZ2UnLCAncHVycGxlJywKICAgICAgICAgICAgJ3JlZCcsICdzaWx2ZXInLCAndGVhbCcsICd3aGl0ZScsICd5ZWxsb3cnKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgnL14jKFthLWYwLTldezN9fFthLWYwLTldezZ9KSQvaScsICRjb2xvcik7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlU3R5bGUoJHN0eWxlKQogICAgewogICAgICAgICRwcm9wZXJ0aWVzICAgICA9IGV4cGxvZGUoJzsnLCBydHJpbSgkc3R5bGUsICc7JykpOwogICAgICAgICRpbnZhbGlkRW50cmllcyA9IHByZWdfZ3JlcCgnL15ccypbLWEtel0rXHMqOlxzKi4rJC9pJywgJHByb3BlcnRpZXMsIFBSRUdfR1JFUF9JTlZFUlQpOwoKICAgICAgICByZXR1cm4gZW1wdHkoJGludmFsaWRFbnRyaWVzKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVQaG9uZSgkcGhvbmUpCiAgICB7CiAgICAgICAgcmV0dXJuIHByZWdfbWF0Y2goJy9eXCs/KFwoXGR7M31cKXxcZHszfSkgXGR7M30gXGR7NH0kLycsICRwaG9uZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlSG9zdG5hbWUoJGhvc3QpCiAgICB7CiAgICAgICAgJGhvc3RuYW1lUmVnZXggPSAnL14oKFthLXpBLVowLTldfFthLXpBLVowLTldW2EtekEtWjAtOVwtXSpbYS16QS1aMC05XSlcLikqKFtBLVphLXowLTldfFtBLVphLXowLTldW0EtWmEtejAtOVwtXSpbQS1aYS16MC05XSkkL2knOwoKICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgkaG9zdG5hbWVSZWdleCwgJGhvc3QpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKCi8qKgogKiBUaGUgTnVtYmVyQ29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIG51bWJlciBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgTnVtYmVyQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJGVsZW1lbnQsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBWZXJpZnkgbWluaW11bQogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5leGNsdXNpdmVNaW5pbXVtKSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bWluaW11bSkpIHsKICAgICAgICAgICAgICAgIGlmICgkc2NoZW1hLT5leGNsdXNpdmVNaW5pbXVtICYmICRlbGVtZW50IDw9ICRzY2hlbWEtPm1pbmltdW0pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGhhdmUgYSBtaW5pbXVtIHZhbHVlIG9mICcgLiAkc2NoZW1hLT5taW5pbXVtLCAnZXhjbHVzaXZlTWluaW11bScsIGFycmF5KCdtaW5pbXVtJyA9PiAkc2NoZW1hLT5taW5pbXVtKSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGVsZW1lbnQgPCAkc2NoZW1hLT5taW5pbXVtKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBoYXZlIGEgbWluaW11bSB2YWx1ZSBvZiAnIC4gJHNjaGVtYS0+bWluaW11bSwgJ21pbmltdW0nLCBhcnJheSgnbWluaW11bScgPT4gJHNjaGVtYS0+bWluaW11bSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnVXNlIG9mIGV4Y2x1c2l2ZU1pbmltdW0gcmVxdWlyZXMgcHJlc2VuY2Ugb2YgbWluaW11bScsICdtaXNzaW5nTWluaW11bScpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRzY2hlbWEtPm1pbmltdW0pICYmICRlbGVtZW50IDwgJHNjaGVtYS0+bWluaW11bSkgewogICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGhhdmUgYSBtaW5pbXVtIHZhbHVlIG9mICcgLiAkc2NoZW1hLT5taW5pbXVtLCAnbWluaW11bScsIGFycmF5KCdtaW5pbXVtJyA9PiAkc2NoZW1hLT5taW5pbXVtKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgbWF4aW11bQogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5leGNsdXNpdmVNYXhpbXVtKSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bWF4aW11bSkpIHsKICAgICAgICAgICAgICAgIGlmICgkc2NoZW1hLT5leGNsdXNpdmVNYXhpbXVtICYmICRlbGVtZW50ID49ICRzY2hlbWEtPm1heGltdW0pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGhhdmUgYSBtYXhpbXVtIHZhbHVlIG9mICcgLiAkc2NoZW1hLT5tYXhpbXVtLCAnZXhjbHVzaXZlTWF4aW11bScsIGFycmF5KCdtYXhpbXVtJyA9PiAkc2NoZW1hLT5tYXhpbXVtKSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGVsZW1lbnQgPiAkc2NoZW1hLT5tYXhpbXVtKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBoYXZlIGEgbWF4aW11bSB2YWx1ZSBvZiAnIC4gJHNjaGVtYS0+bWF4aW11bSwgJ21heGltdW0nLCBhcnJheSgnbWF4aW11bScgPT4gJHNjaGVtYS0+bWF4aW11bSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnVXNlIG9mIGV4Y2x1c2l2ZU1heGltdW0gcmVxdWlyZXMgcHJlc2VuY2Ugb2YgbWF4aW11bScsICdtaXNzaW5nTWF4aW11bScpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRzY2hlbWEtPm1heGltdW0pICYmICRlbGVtZW50ID4gJHNjaGVtYS0+bWF4aW11bSkgewogICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGhhdmUgYSBtYXhpbXVtIHZhbHVlIG9mICcgLiAkc2NoZW1hLT5tYXhpbXVtLCAnbWF4aW11bScsIGFycmF5KCdtYXhpbXVtJyA9PiAkc2NoZW1hLT5tYXhpbXVtKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgZGl2aXNpYmxlQnkgLSBEcmFmdCB2MwogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5kaXZpc2libGVCeSkgJiYgJHRoaXMtPmZtb2QoJGVsZW1lbnQsICRzY2hlbWEtPmRpdmlzaWJsZUJ5KSAhPSAwKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0lzIG5vdCBkaXZpc2libGUgYnkgJyAuICRzY2hlbWEtPmRpdmlzaWJsZUJ5LCAnZGl2aXNpYmxlQnknLCBhcnJheSgnZGl2aXNpYmxlQnknID0+ICRzY2hlbWEtPmRpdmlzaWJsZUJ5KSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgbXVsdGlwbGVPZiAtIERyYWZ0IHY0CiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPm11bHRpcGxlT2YpICYmICR0aGlzLT5mbW9kKCRlbGVtZW50LCAkc2NoZW1hLT5tdWx0aXBsZU9mKSAhPSAwKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ011c3QgYmUgYSBtdWx0aXBsZSBvZiAnIC4gJHNjaGVtYS0+bXVsdGlwbGVPZiwgJ211bHRpcGxlT2YnLCBhcnJheSgnbXVsdGlwbGVPZicgPT4gJHNjaGVtYS0+bXVsdGlwbGVPZikpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNoZWNrRm9ybWF0KCRlbGVtZW50LCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZm1vZCgkbnVtYmVyMSwgJG51bWJlcjIpCiAgICB7CiAgICAgICAgJG1vZHVsdXMgPSAoJG51bWJlcjEgLSByb3VuZCgkbnVtYmVyMSAvICRudW1iZXIyKSAqICRudW1iZXIyKTsKICAgICAgICAkcHJlY2lzaW9uID0gMC4wMDAwMDAwMDAxOwoKICAgICAgICBpZiAoLSRwcmVjaXNpb24gPCAkbW9kdWx1cyAmJiAkbW9kdWx1cyA8ICRwcmVjaXNpb24pIHsKICAgICAgICAgICAgcmV0dXJuIDAuMDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbW9kdWx1czsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFbnRpdHlcSnNvblBvaW50ZXI7CgovKioKICogVGhlIENvbnN0cmFpbnRzIEludGVyZmFjZQogKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICovCmludGVyZmFjZSBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogcmV0dXJucyBhbGwgY29sbGVjdGVkIGVycm9ycwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9ycygpOwoKICAgIC8qKgogICAgICogYWRkcyBlcnJvcnMgdG8gdGhpcyB2YWxpZGF0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGVycm9ycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRXJyb3JzKGFycmF5ICRlcnJvcnMpOwoKICAgIC8qKgogICAgICogYWRkcyBhbiBlcnJvcgogICAgICoKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkbWVzc2FnZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJGNvbnN0cmFpbnQgdGhlIGNvbnN0cmFpbnQvcnVsZSB0aGF0IGlzIGJyb2tlbiwgZS5nLjogJ21pbkxlbmd0aCcKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICRtb3JlICAgICAgIG1vcmUgYXJyYXkgZWxlbWVudHMgdG8gYWRkIHRvIHRoZSBlcnJvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRXJyb3IoSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkbWVzc2FnZSwgJGNvbnN0cmFpbnQ9JycsIGFycmF5ICRtb3JlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBjaGVja3MgaWYgdGhlIHZhbGlkYXRvciBoYXMgbm90IHJhaXNlZCBlcnJvcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmFsaWQoKTsKCiAgICAvKioKICAgICAqIGludm9rZXMgdGhlIHZhbGlkYXRpb24gb2YgYW4gZWxlbWVudAogICAgICoKICAgICAqIEBhYnN0cmFjdAogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRpCiAgICAgKgogICAgICogQHRocm93cyBcSnNvblNjaGVtYVxFeGNlcHRpb25cRXhjZXB0aW9uSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKCi8qKgogKiBUaGUgU3RyaW5nQ29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIHN0cmluZyBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgU3RyaW5nQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJGVsZW1lbnQsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBWZXJpZnkgbWF4TGVuZ3RoCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPm1heExlbmd0aCkgJiYgJHRoaXMtPnN0cmxlbigkZWxlbWVudCkgPiAkc2NoZW1hLT5tYXhMZW5ndGgpIHsKICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBiZSBhdCBtb3N0ICcgLiAkc2NoZW1hLT5tYXhMZW5ndGggLiAnIGNoYXJhY3RlcnMgbG9uZycsICdtYXhMZW5ndGgnLCBhcnJheSgKICAgICAgICAgICAgICAgICdtYXhMZW5ndGgnID0+ICRzY2hlbWEtPm1heExlbmd0aCwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAvL3ZlcmlmeSBtaW5MZW5ndGgKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bWluTGVuZ3RoKSAmJiAkdGhpcy0+c3RybGVuKCRlbGVtZW50KSA8ICRzY2hlbWEtPm1pbkxlbmd0aCkgewogICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGJlIGF0IGxlYXN0ICcgLiAkc2NoZW1hLT5taW5MZW5ndGggLiAnIGNoYXJhY3RlcnMgbG9uZycsICdtaW5MZW5ndGgnLCBhcnJheSgKICAgICAgICAgICAgICAgICdtaW5MZW5ndGgnID0+ICRzY2hlbWEtPm1pbkxlbmd0aCwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgYSByZWdleCBwYXR0ZXJuCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPnBhdHRlcm4pICYmICFwcmVnX21hdGNoKCcjJyAuIHN0cl9yZXBsYWNlKCcjJywgJ1xcIycsICRzY2hlbWEtPnBhdHRlcm4pIC4gJyN1JywgJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0RvZXMgbm90IG1hdGNoIHRoZSByZWdleCBwYXR0ZXJuICcgLiAkc2NoZW1hLT5wYXR0ZXJuLCAncGF0dGVybicsIGFycmF5KAogICAgICAgICAgICAgICAgJ3BhdHRlcm4nID0+ICRzY2hlbWEtPnBhdHRlcm4sCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNoZWNrRm9ybWF0KCRlbGVtZW50LCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gc3RybGVuKCRzdHJpbmcpCiAgICB7CiAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ21ic3RyaW5nJykpIHsKICAgICAgICAgICAgcmV0dXJuIG1iX3N0cmxlbigkc3RyaW5nLCBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0cmluZykpOwogICAgICAgIH0KCiAgICAgICAgLy8gbWJzdHJpbmcgaXMgcHJlc2VudCBvbiBhbGwgdGVzdCBwbGF0Zm9ybXMsIHNvIHN0cmxlbigpIGNhbiBiZSBpZ25vcmVkIGZvciBjb3ZlcmFnZQogICAgICAgIHJldHVybiBzdHJsZW4oJHN0cmluZyk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxTY2hlbWFTdG9yYWdlOwp1c2UgSnNvblNjaGVtYVxTY2hlbWFTdG9yYWdlSW50ZXJmYWNlOwp1c2UgSnNvblNjaGVtYVxVcmlcVXJpUmV0cmlldmVyOwp1c2UgSnNvblNjaGVtYVxVcmlSZXRyaWV2ZXJJbnRlcmZhY2U7CnVzZSBKc29uU2NoZW1hXFZhbGlkYXRvcjsKCi8qKgogKiBGYWN0b3J5IGZvciBjZW50cmFsaXplIGNvbnN0cmFpbnQgaW5pdGlhbGl6YXRpb24uCiAqLwpjbGFzcyBGYWN0b3J5CnsKICAgIC8qKgogICAgICogQHZhciBTY2hlbWFTdG9yYWdlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2NoZW1hU3RvcmFnZTsKCiAgICAvKioKICAgICAqIEB2YXIgVXJpUmV0cmlldmVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdXJpUmV0cmlldmVyOwoKICAgIC8qKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJpdmF0ZSAkY2hlY2tNb2RlID0gQ29uc3RyYWludDo6Q0hFQ0tfTU9ERV9OT1JNQUw7CgogICAgLyoqCiAgICAgKiBAdmFyIFR5cGVDaGVja1xUeXBlQ2hlY2tJbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlICR0eXBlQ2hlY2sgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciBpbnQgVmFsaWRhdGlvbiBjb250ZXh0CiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXJyb3JDb250ZXh0ID0gVmFsaWRhdG9yOjpFUlJPUl9ET0NVTUVOVF9WQUxJREFUSU9OOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnN0cmFpbnRNYXAgPSBhcnJheSgKICAgICAgICAnYXJyYXknID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXENvbGxlY3Rpb25Db25zdHJhaW50JywKICAgICAgICAnY29sbGVjdGlvbicgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcQ29sbGVjdGlvbkNvbnN0cmFpbnQnLAogICAgICAgICdvYmplY3QnID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXE9iamVjdENvbnN0cmFpbnQnLAogICAgICAgICd0eXBlJyA9PiAnSnNvblNjaGVtYVxDb25zdHJhaW50c1xUeXBlQ29uc3RyYWludCcsCiAgICAgICAgJ3VuZGVmaW5lZCcgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcVW5kZWZpbmVkQ29uc3RyYWludCcsCiAgICAgICAgJ3N0cmluZycgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcU3RyaW5nQ29uc3RyYWludCcsCiAgICAgICAgJ251bWJlcicgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcTnVtYmVyQ29uc3RyYWludCcsCiAgICAgICAgJ2VudW0nID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXEVudW1Db25zdHJhaW50JywKICAgICAgICAnZm9ybWF0JyA9PiAnSnNvblNjaGVtYVxDb25zdHJhaW50c1xGb3JtYXRDb25zdHJhaW50JywKICAgICAgICAnc2NoZW1hJyA9PiAnSnNvblNjaGVtYVxDb25zdHJhaW50c1xTY2hlbWFDb25zdHJhaW50JywKICAgICAgICAndmFsaWRhdG9yJyA9PiAnSnNvblNjaGVtYVxWYWxpZGF0b3InCiAgICApOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheTxDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlICRpbnN0YW5jZUNhY2hlID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBTY2hlbWFTdG9yYWdlICAgICAgICAgJHNjaGVtYVN0b3JhZ2UKICAgICAqIEBwYXJhbSBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UgJHVyaVJldHJpZXZlcgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICAkY2hlY2tNb2RlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgKICAgICAgICBTY2hlbWFTdG9yYWdlSW50ZXJmYWNlICRzY2hlbWFTdG9yYWdlID0gbnVsbCwKICAgICAgICBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UgJHVyaVJldHJpZXZlciA9IG51bGwsCiAgICAgICAgJGNoZWNrTW9kZSA9IENvbnN0cmFpbnQ6OkNIRUNLX01PREVfTk9STUFMCiAgICApIHsKICAgICAgICAvLyBzZXQgcHJvdmlkZWQgY29uZmlnIG9wdGlvbnMKICAgICAgICAkdGhpcy0+c2V0Q29uZmlnKCRjaGVja01vZGUpOwoKICAgICAgICAkdGhpcy0+dXJpUmV0cmlldmVyID0gJHVyaVJldHJpZXZlciA/OiBuZXcgVXJpUmV0cmlldmVyKCk7CiAgICAgICAgJHRoaXMtPnNjaGVtYVN0b3JhZ2UgPSAkc2NoZW1hU3RvcmFnZSA/OiBuZXcgU2NoZW1hU3RvcmFnZSgkdGhpcy0+dXJpUmV0cmlldmVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBjb25maWcgdmFsdWVzCiAgICAgKgogICAgICogQHBhcmFtIGludCAkY2hlY2tNb2RlIFNldCBjaGVja01vZGUgb3B0aW9ucyAtIGRvZXMgbm90IHByZXNlcnZlIGV4aXN0aW5nIGZsYWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25maWcoJGNoZWNrTW9kZSA9IENvbnN0cmFpbnQ6OkNIRUNLX01PREVfTk9STUFMKQogICAgewogICAgICAgICR0aGlzLT5jaGVja01vZGUgPSAkY2hlY2tNb2RlOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlIGNoZWNrTW9kZSBmbGFncwogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENvbmZpZygkb3B0aW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+Y2hlY2tNb2RlIHw9ICRvcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogRGlzYWJsZSBjaGVja01vZGUgZmxhZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVDb25maWcoJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNoZWNrTW9kZSAmPSB+JG9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgY2hlY2tNb2RlIG9wdGlvbgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJG9wdGlvbnMgT3B0aW9ucyB0byBnZXQsIGlmIG51bGwgdGhlbiByZXR1cm4gZW50aXJlIGJpdG1hc2sKICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmlnKCRvcHRpb25zID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJG9wdGlvbnMgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jaGVja01vZGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNoZWNrTW9kZSAmICRvcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVyaVJldHJpZXZlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cmlSZXRyaWV2ZXI7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFNjaGVtYVN0b3JhZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2NoZW1hU3RvcmFnZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZUNoZWNrKCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT50eXBlQ2hlY2tbJHRoaXMtPmNoZWNrTW9kZV0pKSB7CiAgICAgICAgICAgICR0aGlzLT50eXBlQ2hlY2tbJHRoaXMtPmNoZWNrTW9kZV0gPSAoJHRoaXMtPmNoZWNrTW9kZSAmIENvbnN0cmFpbnQ6OkNIRUNLX01PREVfVFlQRV9DQVNUKQogICAgICAgICAgICAgICAgPyBuZXcgVHlwZUNoZWNrXExvb3NlVHlwZUNoZWNrKCkKICAgICAgICAgICAgICAgIDogbmV3IFR5cGVDaGVja1xTdHJpY3RUeXBlQ2hlY2soKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dHlwZUNoZWNrWyR0aGlzLT5jaGVja01vZGVdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkY2xhc3MKICAgICAqCiAgICAgKiBAcmV0dXJuIEZhY3RvcnkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbnN0cmFpbnRDbGFzcygkbmFtZSwgJGNsYXNzKQogICAgewogICAgICAgIC8vIEVuc3VyZSBjbGFzcyBleGlzdHMKICAgICAgICBpZiAoIWNsYXNzX2V4aXN0cygkY2xhc3MpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1Vua25vd24gY29uc3RyYWludCAnIC4gJG5hbWUpOwogICAgICAgIH0KICAgICAgICAvLyBFbnN1cmUgY2xhc3MgaXMgYXBwcm9wcmlhdGUKICAgICAgICBpZiAoIWluX2FycmF5KCdKc29uU2NoZW1hXENvbnN0cmFpbnRzXENvbnN0cmFpbnRJbnRlcmZhY2UnLCBjbGFzc19pbXBsZW1lbnRzKCRjbGFzcykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0ludmFsaWQgY2xhc3MgJyAuICRuYW1lKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNvbnN0cmFpbnRNYXBbJG5hbWVdID0gJGNsYXNzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBjb25zdHJhaW50IGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gY29uc3RyYWludCBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN0cmFpbnROYW1lCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgaXMgbm90IHBvc3NpYmxlIGNyZWF0ZSB0aGUgY29uc3RyYWludCBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gQ29uc3RyYWludEludGVyZmFjZXxPYmplY3RDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVJbnN0YW5jZUZvcigkY29uc3RyYWludE5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+Y29uc3RyYWludE1hcFskY29uc3RyYWludE5hbWVdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdVbmtub3duIGNvbnN0cmFpbnQgJyAuICRjb25zdHJhaW50TmFtZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5pbnN0YW5jZUNhY2hlWyRjb25zdHJhaW50TmFtZV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5pbnN0YW5jZUNhY2hlWyRjb25zdHJhaW50TmFtZV0gPSBuZXcgJHRoaXMtPmNvbnN0cmFpbnRNYXBbJGNvbnN0cmFpbnROYW1lXSgkdGhpcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2xvbmUgJHRoaXMtPmluc3RhbmNlQ2FjaGVbJGNvbnN0cmFpbnROYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgZXJyb3IgY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFcnJvckNvbnRleHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3JDb250ZXh0OwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBlcnJvciBjb250ZXh0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmFsaWRhdGlvbkNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVycm9yQ29udGV4dCgkZXJyb3JDb250ZXh0KQogICAgewogICAgICAgICR0aGlzLT5lcnJvckNvbnRleHQgPSAkZXJyb3JDb250ZXh0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKCi8qKgogKiBUaGUgT2JqZWN0Q29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIG9iamVjdCBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgT2JqZWN0Q29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IExpc3Qgb2YgcHJvcGVydGllcyB0byB3aGljaCBhIGRlZmF1bHQgdmFsdWUgaGFzIGJlZW4gYXBwbGllZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFwcGxpZWREZWZhdWx0cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJGVsZW1lbnQsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRwcm9wZXJ0aWVzID0gbnVsbCwKICAgICAgICAkYWRkaXRpb25hbFByb3AgPSBudWxsLCAkcGF0dGVyblByb3BlcnRpZXMgPSBudWxsLCAkYXBwbGllZERlZmF1bHRzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoJGVsZW1lbnQgaW5zdGFuY2VvZiBVbmRlZmluZWRDb25zdHJhaW50KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hcHBsaWVkRGVmYXVsdHMgPSAkYXBwbGllZERlZmF1bHRzOwoKICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRwYXR0ZXJuUHJvcGVydGllcykgewogICAgICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgZWxlbWVudCBwYXR0ZXJuIHByb3BlcnRpZXMKICAgICAgICAgICAgJG1hdGNoZXMgPSAkdGhpcy0+dmFsaWRhdGVQYXR0ZXJuUHJvcGVydGllcygkZWxlbWVudCwgJHBhdGgsICRwYXR0ZXJuUHJvcGVydGllcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByb3BlcnRpZXMpIHsKICAgICAgICAgICAgLy8gdmFsaWRhdGUgdGhlIGVsZW1lbnQgcHJvcGVydGllcwogICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVQcm9wZXJ0aWVzKCRlbGVtZW50LCAkcHJvcGVydGllcywgJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgLy8gdmFsaWRhdGUgYWRkaXRpb25hbCBlbGVtZW50IHByb3BlcnRpZXMgJiBjb25zdHJhaW50cwogICAgICAgICR0aGlzLT52YWxpZGF0ZUVsZW1lbnQoJGVsZW1lbnQsICRtYXRjaGVzLCAkc2NoZW1hLCAkcGF0aCwgJHByb3BlcnRpZXMsICRhZGRpdGlvbmFsUHJvcCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkYXRlUGF0dGVyblByb3BlcnRpZXMoJGVsZW1lbnQsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJHBhdHRlcm5Qcm9wZXJ0aWVzKQogICAgewogICAgICAgICR0cnkgPSBhcnJheSgnLycsICcjJywgJysnLCAnficsICclJyk7CiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYXR0ZXJuUHJvcGVydGllcyBhcyAkcHJlZ2V4ID0+ICRzY2hlbWEpIHsKICAgICAgICAgICAgJGRlbGltaXRlciA9ICcvJzsKICAgICAgICAgICAgLy8gQ2hvb3NlIGRlbGltaXRlci4gTmVjZXNzYXJ5IGZvciBwYXR0ZXJucyBsaWtlIF4vICwgb3RoZXJ3aXNlIHlvdSBnZXQgZXJyb3IKICAgICAgICAgICAgZm9yZWFjaCAoJHRyeSBhcyAkZGVsaW1pdGVyKSB7CiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRwcmVnZXgsICRkZWxpbWl0ZXIpID09PSBmYWxzZSkgeyAvLyBzYWZlIHRvIHVzZQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBWYWxpZGF0ZSB0aGUgcGF0dGVybiBiZWZvcmUgdXNpbmcgaXQgdG8gdGVzdCBmb3IgbWF0Y2hlcwogICAgICAgICAgICBpZiAoQHByZWdfbWF0Y2goJGRlbGltaXRlciAuICRwcmVnZXggLiAkZGVsaW1pdGVyIC4gJ3UnLCAnJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdUaGUgcGF0dGVybiAiJyAuICRwcmVnZXggLiAnIiBpcyBpbnZhbGlkJywgJ3ByZWdleCcsIGFycmF5KCdwcmVnZXgnID0+ICRwcmVnZXgpKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRlbGVtZW50IGFzICRpID0+ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJGRlbGltaXRlciAuICRwcmVnZXggLiAkZGVsaW1pdGVyIC4gJ3UnLCAkaSkpIHsKICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tdID0gJGk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJHNjaGVtYSA/OiBuZXcgXHN0ZENsYXNzKCksICRwYXRoLCAkaSwgaW5fYXJyYXkoJGksICR0aGlzLT5hcHBsaWVkRGVmYXVsdHMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtYXRjaGVzOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBlbGVtZW50IHByb3BlcnRpZXMKICAgICAqCiAgICAgKiBAcGFyYW0gXFN0ZENsYXNzICAgICAgICAkZWxlbWVudCAgICAgICAgRWxlbWVudCB0byB2YWxpZGF0ZQogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgJG1hdGNoZXMgICAgICAgIE1hdGNoZXMgZnJvbSBwYXR0ZXJuUHJvcGVydGllcyAoaWYgYW55KQogICAgICogQHBhcmFtIFxTdGRDbGFzcyAgICAgICAgJHNjaGVtYSAgICAgICAgIE9iamVjdENvbnN0cmFpbnQgZGVmaW5pdGlvbgogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGggICAgICAgICAgIEN1cnJlbnQgdGVzdCBwYXRoCiAgICAgKiBAcGFyYW0gXFN0ZENsYXNzICAgICAgICAkcHJvcGVydGllcyAgICAgUHJvcGVydGllcwogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJGFkZGl0aW9uYWxQcm9wIEFkZGl0aW9uYWwgcHJvcGVydGllcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGVFbGVtZW50KCRlbGVtZW50LCAkbWF0Y2hlcywgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwKICAgICAgICAkcHJvcGVydGllcyA9IG51bGwsICRhZGRpdGlvbmFsUHJvcCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbGlkYXRlTWluTWF4Q29uc3RyYWludCgkZWxlbWVudCwgJHNjaGVtYSwgJHBhdGgpOwoKICAgICAgICBmb3JlYWNoICgkZWxlbWVudCBhcyAkaSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJGRlZmluaXRpb24gPSAkdGhpcy0+Z2V0UHJvcGVydHkoJHByb3BlcnRpZXMsICRpKTsKCiAgICAgICAgICAgIC8vIG5vIGFkZGl0aW9uYWwgcHJvcGVydGllcyBhbGxvd2VkCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJGksICRtYXRjaGVzKSAmJiAkYWRkaXRpb25hbFByb3AgPT09IGZhbHNlICYmICR0aGlzLT5pbmxpbmVTY2hlbWFQcm9wZXJ0eSAhPT0gJGkgJiYgISRkZWZpbml0aW9uKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdUaGUgcHJvcGVydHkgJyAuICRpIC4gJyBpcyBub3QgZGVmaW5lZCBhbmQgdGhlIGRlZmluaXRpb24gZG9lcyBub3QgYWxsb3cgYWRkaXRpb25hbCBwcm9wZXJ0aWVzJywgJ2FkZGl0aW9uYWxQcm9wJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGFkZGl0aW9uYWwgcHJvcGVydGllcyBkZWZpbmVkCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJGksICRtYXRjaGVzKSAmJiAkYWRkaXRpb25hbFByb3AgJiYgISRkZWZpbml0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoJGFkZGl0aW9uYWxQcm9wID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgbnVsbCwgJHBhdGgsICRpLCBpbl9hcnJheSgkaSwgJHRoaXMtPmFwcGxpZWREZWZhdWx0cykpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkYWRkaXRpb25hbFByb3AsICRwYXRoLCAkaSwgaW5fYXJyYXkoJGksICR0aGlzLT5hcHBsaWVkRGVmYXVsdHMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gcHJvcGVydHkgcmVxdWlyZXMgcHJlc2VuY2Ugb2YgYW5vdGhlcgogICAgICAgICAgICAkcmVxdWlyZSA9ICR0aGlzLT5nZXRQcm9wZXJ0eSgkZGVmaW5pdGlvbiwgJ3JlcXVpcmVzJyk7CiAgICAgICAgICAgIGlmICgkcmVxdWlyZSAmJiAhJHRoaXMtPmdldFByb3BlcnR5KCRlbGVtZW50LCAkcmVxdWlyZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1RoZSBwcmVzZW5jZSBvZiB0aGUgcHJvcGVydHkgJyAuICRpIC4gJyByZXF1aXJlcyB0aGF0ICcgLiAkcmVxdWlyZSAuICcgYWxzbyBiZSBwcmVzZW50JywgJ3JlcXVpcmVzJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwcm9wZXJ0eSA9ICR0aGlzLT5nZXRQcm9wZXJ0eSgkZWxlbWVudCwgJGksICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcigndW5kZWZpbmVkJykpOwogICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRwcm9wZXJ0eSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZU1pbk1heENvbnN0cmFpbnQoISgkcHJvcGVydHkgaW5zdGFuY2VvZiBVbmRlZmluZWRDb25zdHJhaW50KSA/ICRwcm9wZXJ0eSA6ICRlbGVtZW50LCAkZGVmaW5pdGlvbiwgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBkZWZpbml0aW9uIHByb3BlcnRpZXMKICAgICAqCiAgICAgKiBAcGFyYW0gXHN0ZENsYXNzICAgICAgICAkZWxlbWVudCAgICBFbGVtZW50IHRvIHZhbGlkYXRlCiAgICAgKiBAcGFyYW0gXHN0ZENsYXNzICAgICAgICAkcHJvcGVydGllcyBQcm9wZXJ0eSBkZWZpbml0aW9ucwogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGggICAgICAgUGF0aD8KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkYXRlUHJvcGVydGllcygmJGVsZW1lbnQsICRwcm9wZXJ0aWVzID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsKQogICAgewogICAgICAgICR1bmRlZmluZWRDb25zdHJhaW50ID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCd1bmRlZmluZWQnKTsKCiAgICAgICAgZm9yZWFjaCAoJHByb3BlcnRpZXMgYXMgJGkgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgICRwcm9wZXJ0eSA9ICYkdGhpcy0+Z2V0UHJvcGVydHkoJGVsZW1lbnQsICRpLCAkdW5kZWZpbmVkQ29uc3RyYWludCk7CiAgICAgICAgICAgICRkZWZpbml0aW9uID0gJHRoaXMtPmdldFByb3BlcnR5KCRwcm9wZXJ0aWVzLCAkaSk7CgogICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRkZWZpbml0aW9uKSkgewogICAgICAgICAgICAgICAgLy8gVW5kZWZpbmVkIGNvbnN0cmFpbnQgd2lsbCBjaGVjayBmb3IgaXNfb2JqZWN0KCkgYW5kIHF1aXQgaWYgaXMgbm90IC0gc28gd2h5IHBhc3MgaXQ/CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHByb3BlcnR5LCAkZGVmaW5pdGlvbiwgJHBhdGgsICRpLCBpbl9hcnJheSgkaSwgJHRoaXMtPmFwcGxpZWREZWZhdWx0cykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogcmV0cmlldmVzIGEgcHJvcGVydHkgZnJvbSBhbiBvYmplY3Qgb3IgYXJyYXkKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRlbGVtZW50ICBFbGVtZW50IHRvIHZhbGlkYXRlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcm9wZXJ0eSBQcm9wZXJ0eSB0byByZXRyaWV2ZQogICAgICogQHBhcmFtIG1peGVkICAkZmFsbGJhY2sgRGVmYXVsdCB2YWx1ZSBpZiBwcm9wZXJ0eSBpcyBub3QgZm91bmQKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiAmZ2V0UHJvcGVydHkoJiRlbGVtZW50LCAkcHJvcGVydHksICRmYWxsYmFjayA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGlzX2FycmF5KCRlbGVtZW50KSAmJiAoaXNzZXQoJGVsZW1lbnRbJHByb3BlcnR5XSkgfHwgYXJyYXlfa2V5X2V4aXN0cygkcHJvcGVydHksICRlbGVtZW50KSkgLyokdGhpcy0+Y2hlY2tNb2RlID09IHNlbGY6OkNIRUNLX01PREVfVFlQRV9DQVNUKi8pIHsKICAgICAgICAgICAgcmV0dXJuICRlbGVtZW50WyRwcm9wZXJ0eV07CiAgICAgICAgfSBlbHNlaWYgKGlzX29iamVjdCgkZWxlbWVudCkgJiYgcHJvcGVydHlfZXhpc3RzKCRlbGVtZW50LCAkcHJvcGVydHkpKSB7CiAgICAgICAgICAgIHJldHVybiAkZWxlbWVudC0+JHByb3BlcnR5OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmYWxsYmFjazsKICAgIH0KCiAgICAvKioKICAgICAqIHZhbGlkYXRpbmcgbWluaW11bSBhbmQgbWF4aW11bSBwcm9wZXJ0eSBjb25zdHJhaW50cyAoaWYgcHJlc2VudCkgYWdhaW5zdCBhbiBlbGVtZW50CiAgICAgKgogICAgICogQHBhcmFtIFxzdGRDbGFzcyAgICAgICAgJGVsZW1lbnQgICAgICAgICAgRWxlbWVudCB0byB2YWxpZGF0ZQogICAgICogQHBhcmFtIFxzdGRDbGFzcyAgICAgICAgJG9iamVjdERlZmluaXRpb24gT2JqZWN0Q29uc3RyYWludCBkZWZpbml0aW9uCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aCAgICAgICAgICAgICBQYXRoIHRvIHRlc3Q/CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZU1pbk1heENvbnN0cmFpbnQoJGVsZW1lbnQsICRvYmplY3REZWZpbml0aW9uLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gVmVyaWZ5IG1pbmltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMKICAgICAgICBpZiAoaXNzZXQoJG9iamVjdERlZmluaXRpb24tPm1pblByb3BlcnRpZXMpICYmICFpc19vYmplY3QoJG9iamVjdERlZmluaXRpb24tPm1pblByb3BlcnRpZXMpKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+Z2V0VHlwZUNoZWNrKCktPnByb3BlcnR5Q291bnQoJGVsZW1lbnQpIDwgJG9iamVjdERlZmluaXRpb24tPm1pblByb3BlcnRpZXMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ011c3QgY29udGFpbiBhIG1pbmltdW0gb2YgJyAuICRvYmplY3REZWZpbml0aW9uLT5taW5Qcm9wZXJ0aWVzIC4gJyBwcm9wZXJ0aWVzJywgJ21pblByb3BlcnRpZXMnLCBhcnJheSgnbWluUHJvcGVydGllcycgPT4gJG9iamVjdERlZmluaXRpb24tPm1pblByb3BlcnRpZXMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBWZXJpZnkgbWF4aW11bSBudW1iZXIgb2YgcHJvcGVydGllcwogICAgICAgIGlmIChpc3NldCgkb2JqZWN0RGVmaW5pdGlvbi0+bWF4UHJvcGVydGllcykgJiYgIWlzX29iamVjdCgkb2JqZWN0RGVmaW5pdGlvbi0+bWF4UHJvcGVydGllcykpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlDb3VudCgkZWxlbWVudCkgPiAkb2JqZWN0RGVmaW5pdGlvbi0+bWF4UHJvcGVydGllcykgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBjb250YWluIG5vIG1vcmUgdGhhbiAnIC4gJG9iamVjdERlZmluaXRpb24tPm1heFByb3BlcnRpZXMgLiAnIHByb3BlcnRpZXMnLCAnbWF4UHJvcGVydGllcycsIGFycmF5KCdtYXhQcm9wZXJ0aWVzJyA9PiAkb2JqZWN0RGVmaW5pdGlvbi0+bWF4UHJvcGVydGllcykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzXFR5cGVDaGVja1xMb29zZVR5cGVDaGVjazsKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cVmFsaWRhdGlvbkV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVXJpXFVyaVJlc29sdmVyOwoKLyoqCiAqIFRoZSBVbmRlZmluZWRDb25zdHJhaW50IENvbnN0cmFpbnRzCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgVW5kZWZpbmVkQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IExpc3Qgb2YgcHJvcGVydGllcyB0byB3aGljaCBhIGRlZmF1bHQgdmFsdWUgaGFzIGJlZW4gYXBwbGllZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFwcGxpZWREZWZhdWx0cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwsICRmcm9tRGVmYXVsdCA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChpc19udWxsKCRzY2hlbWEpIHx8ICFpc19vYmplY3QoJHNjaGVtYSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHBhdGggPSAkdGhpcy0+aW5jcmVtZW50UGF0aCgkcGF0aCA/OiBuZXcgSnNvblBvaW50ZXIoJycpLCAkaSk7CiAgICAgICAgaWYgKCRmcm9tRGVmYXVsdCkgewogICAgICAgICAgICAkcGF0aC0+c2V0RnJvbURlZmF1bHQoKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIHNwZWNpYWwgcHJvcGVydGllcwogICAgICAgICR0aGlzLT52YWxpZGF0ZUNvbW1vblByb3BlcnRpZXMoJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwoKICAgICAgICAvLyBjaGVjayBhbGxPZiwgYW55T2YsIGFuZCBvbmVPZiBwcm9wZXJ0aWVzCiAgICAgICAgJHRoaXMtPnZhbGlkYXRlT2ZQcm9wZXJ0aWVzKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICcnKTsKCiAgICAgICAgLy8gY2hlY2sga25vd24gdHlwZXMKICAgICAgICAkdGhpcy0+dmFsaWRhdGVUeXBlcygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIGFnYWluc3QgdGhlIHR5cGVzCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlciAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZVR5cGVzKCYkdmFsdWUsICRzY2hlbWEsIEpzb25Qb2ludGVyICRwYXRoLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gY2hlY2sgYXJyYXkKICAgICAgICBpZiAoJHRoaXMtPmdldFR5cGVDaGVjaygpLT5pc0FycmF5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrQXJyYXkoJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgb2JqZWN0CiAgICAgICAgaWYgKExvb3NlVHlwZUNoZWNrOjppc09iamVjdCgkdmFsdWUpKSB7IC8vIG9iamVjdCBwcm9jZXNzaW5nIHNob3VsZCBhbHdheXMgYmUgcnVuIG9uIGFzc29jIGFycmF5cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gdXNlIExvb3NlVHlwZUNoZWNrIGhlcmUgZXZlbiBpZiBDSEVDS19NT0RFX1RZUEVfQ0FTVAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBub3Qgc2V0IChpLmUuIGRvbid0IHVzZSAkdGhpcy0+Z2V0VHlwZUNoZWNrKCkgaGVyZSkuCiAgICAgICAgICAgICR0aGlzLT5jaGVja09iamVjdCgKICAgICAgICAgICAgICAgICR2YWx1ZSwKICAgICAgICAgICAgICAgICRzY2hlbWEsCiAgICAgICAgICAgICAgICAkcGF0aCwKICAgICAgICAgICAgICAgIGlzc2V0KCRzY2hlbWEtPnByb3BlcnRpZXMpID8gJHNjaGVtYS0+cHJvcGVydGllcyA6IG51bGwsCiAgICAgICAgICAgICAgICBpc3NldCgkc2NoZW1hLT5hZGRpdGlvbmFsUHJvcGVydGllcykgPyAkc2NoZW1hLT5hZGRpdGlvbmFsUHJvcGVydGllcyA6IG51bGwsCiAgICAgICAgICAgICAgICBpc3NldCgkc2NoZW1hLT5wYXR0ZXJuUHJvcGVydGllcykgPyAkc2NoZW1hLT5wYXR0ZXJuUHJvcGVydGllcyA6IG51bGwsCiAgICAgICAgICAgICAgICAkdGhpcy0+YXBwbGllZERlZmF1bHRzCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBzdHJpbmcKICAgICAgICBpZiAoaXNfc3RyaW5nKCR2YWx1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrU3RyaW5nKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIG51bWVyaWMKICAgICAgICBpZiAoaXNfbnVtZXJpYygkdmFsdWUpKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja051bWJlcigkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBlbnVtCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmVudW0pKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0VudW0oJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyBjb21tb24gcHJvcGVydGllcwogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXIgJHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVDb21tb25Qcm9wZXJ0aWVzKCYkdmFsdWUsICRzY2hlbWEsIEpzb25Qb2ludGVyICRwYXRoLCAkaSA9ICcnKQogICAgewogICAgICAgIC8vIGlmIGl0IGV4dGVuZHMgYW5vdGhlciBzY2hlbWEsIGl0IG11c3QgcGFzcyB0aGF0IHNjaGVtYSBhcyB3ZWxsCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmV4dGVuZHMpKSB7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHNjaGVtYS0+ZXh0ZW5kcykpIHsKICAgICAgICAgICAgICAgICRzY2hlbWEtPmV4dGVuZHMgPSAkdGhpcy0+dmFsaWRhdGVVcmkoJHNjaGVtYSwgJHNjaGVtYS0+ZXh0ZW5kcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX2FycmF5KCRzY2hlbWEtPmV4dGVuZHMpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkc2NoZW1hLT5leHRlbmRzIGFzICRleHRlbmRzKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJGV4dGVuZHMsICRwYXRoLCAkaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkc2NoZW1hLT5leHRlbmRzLCAkcGF0aCwgJGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBBcHBseSBkZWZhdWx0IHZhbHVlcyBmcm9tIHNjaGVtYQogICAgICAgIGlmICghJHBhdGgtPmZyb21EZWZhdWx0KCkpIHsKICAgICAgICAgICAgJHRoaXMtPmFwcGx5RGVmYXVsdFZhbHVlcygkdmFsdWUsICRzY2hlbWEsICRwYXRoKTsKICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSByZXF1aXJlZCB2YWx1ZXMKICAgICAgICBpZiAoJHRoaXMtPmdldFR5cGVDaGVjaygpLT5pc09iamVjdCgkdmFsdWUpKSB7CiAgICAgICAgICAgIGlmICghKCR2YWx1ZSBpbnN0YW5jZW9mIHNlbGYpICYmIGlzc2V0KCRzY2hlbWEtPnJlcXVpcmVkKSAmJiBpc19hcnJheSgkc2NoZW1hLT5yZXF1aXJlZCkpIHsKICAgICAgICAgICAgICAgIC8vIERyYWZ0IDQgLSBSZXF1aXJlZCBpcyBhbiBhcnJheSBvZiBzdHJpbmdzIC0gZS5nLiAicmVxdWlyZWQiOiBbImZvbyIsIC4uLl0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRzY2hlbWEtPnJlcXVpcmVkIGFzICRyZXF1aXJlZCkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUV4aXN0cygkdmFsdWUsICRyZXF1aXJlZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluY3JlbWVudFBhdGgoJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKSwgJHJlcXVpcmVkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgcHJvcGVydHkgJyAuICRyZXF1aXJlZCAuICcgaXMgcmVxdWlyZWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3JlcXVpcmVkJwogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRzY2hlbWEtPnJlcXVpcmVkKSAmJiAhaXNfYXJyYXkoJHNjaGVtYS0+cmVxdWlyZWQpKSB7CiAgICAgICAgICAgICAgICAvLyBEcmFmdCAzIC0gUmVxdWlyZWQgYXR0cmlidXRlIC0gZS5nLiAiZm9vIjogeyJ0eXBlIjogInN0cmluZyIsICJyZXF1aXJlZCI6IHRydWV9CiAgICAgICAgICAgICAgICBpZiAoJHNjaGVtYS0+cmVxdWlyZWQgJiYgJHZhbHVlIGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICAgICAgICAgICRwcm9wZXJ0eVBhdGhzID0gJHBhdGgtPmdldFByb3BlcnR5UGF0aHMoKTsKICAgICAgICAgICAgICAgICAgICAkcHJvcGVydHlOYW1lID0gZW5kKCRwcm9wZXJ0eVBhdGhzKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAnVGhlIHByb3BlcnR5ICcgLiAkcHJvcGVydHlOYW1lIC4gJyBpcyByZXF1aXJlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICdyZXF1aXJlZCcKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIGJvdGggdW5kZWZpbmVkIGFuZCBub3QgcmVxdWlyZWQsIHNraXAgcmVtYWluaW5nIGNoZWNrcwogICAgICAgICAgICAgICAgLy8gaW4gdGhpcyBtZXRob2Qgd2hpY2ggYXNzdW1lIGFuIGFjdHVhbCwgZGVmaW5lZCBpbnN0YW5jZSB3aGVuIHZhbGlkYXRpbmcuCiAgICAgICAgICAgICAgICBpZiAoJHZhbHVlIGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IHR5cGUKICAgICAgICBpZiAoISgkdmFsdWUgaW5zdGFuY2VvZiBzZWxmKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tUeXBlKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSBkaXNhbGxvd2VkIGl0ZW1zCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmRpc2FsbG93KSkgewogICAgICAgICAgICAkaW5pdEVycm9ycyA9ICR0aGlzLT5nZXRFcnJvcnMoKTsKCiAgICAgICAgICAgICR0eXBlU2NoZW1hID0gbmV3IFxzdGRDbGFzcygpOwogICAgICAgICAgICAkdHlwZVNjaGVtYS0+dHlwZSA9ICRzY2hlbWEtPmRpc2FsbG93OwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tUeXBlKCR2YWx1ZSwgJHR5cGVTY2hlbWEsICRwYXRoKTsKCiAgICAgICAgICAgIC8vIGlmIG5vIG5ldyBlcnJvcnMgd2VyZSByYWlzZWQgaXQgbXVzdCBiZSBhIGRpc2FsbG93ZWQgdmFsdWUKICAgICAgICAgICAgaWYgKGNvdW50KCR0aGlzLT5nZXRFcnJvcnMoKSkgPT0gY291bnQoJGluaXRFcnJvcnMpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdEaXNhbGxvd2VkIHZhbHVlIHdhcyBtYXRjaGVkJywgJ2Rpc2FsbG93Jyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzID0gJGluaXRFcnJvcnM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5ub3QpKSB7CiAgICAgICAgICAgICRpbml0RXJyb3JzID0gJHRoaXMtPmdldEVycm9ycygpOwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkc2NoZW1hLT5ub3QsICRwYXRoLCAkaSk7CgogICAgICAgICAgICAvLyBpZiBubyBuZXcgZXJyb3JzIHdlcmUgcmFpc2VkIHRoZW4gdGhlIGluc3RhbmNlIHZhbGlkYXRlZCBhZ2FpbnN0IHRoZSAibm90IiBzY2hlbWEKICAgICAgICAgICAgaWYgKGNvdW50KCR0aGlzLT5nZXRFcnJvcnMoKSkgPT0gY291bnQoJGluaXRFcnJvcnMpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNYXRjaGVkIGEgc2NoZW1hIHdoaWNoIGl0IHNob3VsZCBub3QnLCAnbm90Jyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzID0gJGluaXRFcnJvcnM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSB0aGF0IGRlcGVuZGVuY2llcyBhcmUgbWV0CiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmRlcGVuZGVuY2llcykgJiYgJHRoaXMtPmdldFR5cGVDaGVjaygpLT5pc09iamVjdCgkdmFsdWUpKSB7CiAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZURlcGVuZGVuY2llcygkdmFsdWUsICRzY2hlbWEtPmRlcGVuZGVuY2llcywgJHBhdGgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHdoZXRoZXIgYSBkZWZhdWx0IHNob3VsZCBiZSBhcHBsaWVkIGZvciB0aGlzIHZhbHVlCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICRzY2hlbWEKICAgICAqIEBwYXJhbSBtaXhlZCAkcGFyZW50U2NoZW1hCiAgICAgKiBAcGFyYW0gYm9vbCAgJHJlcXVpcmVkT25seQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNob3VsZEFwcGx5RGVmYXVsdFZhbHVlKCRyZXF1aXJlZE9ubHksICRzY2hlbWEsICRuYW1lID0gbnVsbCwgJHBhcmVudFNjaGVtYSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gcmVxdWlyZWQtb25seSBtb2RlIGlzIG9mZgogICAgICAgIGlmICghJHJlcXVpcmVkT25seSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgLy8gZHJhZnQtMDQgcmVxdWlyZWQgaXMgc2V0CiAgICAgICAgaWYgKAogICAgICAgICAgICAkbmFtZSAhPT0gbnVsbAogICAgICAgICAgICAmJiBpc3NldCgkcGFyZW50U2NoZW1hLT5yZXF1aXJlZCkKICAgICAgICAgICAgJiYgaXNfYXJyYXkoJHBhcmVudFNjaGVtYS0+cmVxdWlyZWQpCiAgICAgICAgICAgICYmIGluX2FycmF5KCRuYW1lLCAkcGFyZW50U2NoZW1hLT5yZXF1aXJlZCkKICAgICAgICApIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIC8vIGRyYWZ0LTAzIHJlcXVpcmVkIGlzIHNldAogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5yZXF1aXJlZCkgJiYgIWlzX2FycmF5KCRzY2hlbWEtPnJlcXVpcmVkKSAmJiAkc2NoZW1hLT5yZXF1aXJlZCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgLy8gZGVmYXVsdCBjYXNlCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQXBwbHkgZGVmYXVsdCB2YWx1ZXMKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyICRwYXRoCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhcHBseURlZmF1bHRWYWx1ZXMoJiR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgpCiAgICB7CiAgICAgICAgLy8gb25seSBhcHBseSBkZWZhdWx0cyBpZiBmZWF0dXJlIGlzIGVuYWJsZWQKICAgICAgICBpZiAoISR0aGlzLT5mYWN0b3J5LT5nZXRDb25maWcoc2VsZjo6Q0hFQ0tfTU9ERV9BUFBMWV9ERUZBVUxUUykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gYXBwbHkgZGVmYXVsdHMgaWYgYXBwcm9wcmlhdGUKICAgICAgICAkcmVxdWlyZWRPbmx5ID0gJHRoaXMtPmZhY3RvcnktPmdldENvbmZpZyhzZWxmOjpDSEVDS19NT0RFX09OTFlfUkVRVUlSRURfREVGQVVMVFMpOwogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5wcm9wZXJ0aWVzKSAmJiBMb29zZVR5cGVDaGVjazo6aXNPYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICAvLyAkdmFsdWUgaXMgYW4gb2JqZWN0IG9yIGFzc29jIGFycmF5LCBhbmQgcHJvcGVydGllcyBhcmUgZGVmaW5lZCAtIHRyZWF0IGFzIGFuIG9iamVjdAogICAgICAgICAgICBmb3JlYWNoICgkc2NoZW1hLT5wcm9wZXJ0aWVzIGFzICRjdXJyZW50UHJvcGVydHkgPT4gJHByb3BlcnR5RGVmaW5pdGlvbikgewogICAgICAgICAgICAgICAgJHByb3BlcnR5RGVmaW5pdGlvbiA9ICR0aGlzLT5mYWN0b3J5LT5nZXRTY2hlbWFTdG9yYWdlKCktPnJlc29sdmVSZWZTY2hlbWEoJHByb3BlcnR5RGVmaW5pdGlvbik7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgIUxvb3NlVHlwZUNoZWNrOjpwcm9wZXJ0eUV4aXN0cygkdmFsdWUsICRjdXJyZW50UHJvcGVydHkpCiAgICAgICAgICAgICAgICAgICAgJiYgcHJvcGVydHlfZXhpc3RzKCRwcm9wZXJ0eURlZmluaXRpb24sICdkZWZhdWx0JykKICAgICAgICAgICAgICAgICAgICAmJiAkdGhpcy0+c2hvdWxkQXBwbHlEZWZhdWx0VmFsdWUoJHJlcXVpcmVkT25seSwgJHByb3BlcnR5RGVmaW5pdGlvbiwgJGN1cnJlbnRQcm9wZXJ0eSwgJHNjaGVtYSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIC8vIGFzc2lnbiBkZWZhdWx0IHZhbHVlCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX29iamVjdCgkcHJvcGVydHlEZWZpbml0aW9uLT5kZWZhdWx0KSkgewogICAgICAgICAgICAgICAgICAgICAgICBMb29zZVR5cGVDaGVjazo6cHJvcGVydHlTZXQoJHZhbHVlLCAkY3VycmVudFByb3BlcnR5LCBjbG9uZSAkcHJvcGVydHlEZWZpbml0aW9uLT5kZWZhdWx0KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBMb29zZVR5cGVDaGVjazo6cHJvcGVydHlTZXQoJHZhbHVlLCAkY3VycmVudFByb3BlcnR5LCAkcHJvcGVydHlEZWZpbml0aW9uLT5kZWZhdWx0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFwcGxpZWREZWZhdWx0c1tdID0gJGN1cnJlbnRQcm9wZXJ0eTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChpc3NldCgkc2NoZW1hLT5pdGVtcykgJiYgTG9vc2VUeXBlQ2hlY2s6OmlzQXJyYXkoJHZhbHVlKSkgewogICAgICAgICAgICAkaXRlbXMgPSBhcnJheSgpOwogICAgICAgICAgICBpZiAoTG9vc2VUeXBlQ2hlY2s6OmlzQXJyYXkoJHNjaGVtYS0+aXRlbXMpKSB7CiAgICAgICAgICAgICAgICAkaXRlbXMgPSAkc2NoZW1hLT5pdGVtczsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRzY2hlbWEtPm1pbkl0ZW1zKSAmJiBjb3VudCgkdmFsdWUpIDwgJHNjaGVtYS0+bWluSXRlbXMpIHsKICAgICAgICAgICAgICAgICRpdGVtcyA9IGFycmF5X2ZpbGwoY291bnQoJHZhbHVlKSwgJHNjaGVtYS0+bWluSXRlbXMgLSBjb3VudCgkdmFsdWUpLCAkc2NoZW1hLT5pdGVtcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gJHZhbHVlIGlzIGFuIGFycmF5LCBhbmQgaXRlbXMgYXJlIGRlZmluZWQgLSB0cmVhdCBhcyBwbGFpbiBhcnJheQogICAgICAgICAgICBmb3JlYWNoICgkaXRlbXMgYXMgJGN1cnJlbnRJdGVtID0+ICRpdGVtRGVmaW5pdGlvbikgewogICAgICAgICAgICAgICAgJGl0ZW1EZWZpbml0aW9uID0gJHRoaXMtPmZhY3RvcnktPmdldFNjaGVtYVN0b3JhZ2UoKS0+cmVzb2x2ZVJlZlNjaGVtYSgkaXRlbURlZmluaXRpb24pOwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICFhcnJheV9rZXlfZXhpc3RzKCRjdXJyZW50SXRlbSwgJHZhbHVlKQogICAgICAgICAgICAgICAgICAgICYmIHByb3BlcnR5X2V4aXN0cygkaXRlbURlZmluaXRpb24sICdkZWZhdWx0JykKICAgICAgICAgICAgICAgICAgICAmJiAkdGhpcy0+c2hvdWxkQXBwbHlEZWZhdWx0VmFsdWUoJHJlcXVpcmVkT25seSwgJGl0ZW1EZWZpbml0aW9uKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc19vYmplY3QoJGl0ZW1EZWZpbml0aW9uLT5kZWZhdWx0KSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdmFsdWVbJGN1cnJlbnRJdGVtXSA9IGNsb25lICRpdGVtRGVmaW5pdGlvbi0+ZGVmYXVsdDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdmFsdWVbJGN1cnJlbnRJdGVtXSA9ICRpdGVtRGVmaW5pdGlvbi0+ZGVmYXVsdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcGF0aC0+c2V0RnJvbURlZmF1bHQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgJHZhbHVlIGluc3RhbmNlb2Ygc2VsZgogICAgICAgICAgICAmJiBwcm9wZXJ0eV9leGlzdHMoJHNjaGVtYSwgJ2RlZmF1bHQnKQogICAgICAgICAgICAmJiAkdGhpcy0+c2hvdWxkQXBwbHlEZWZhdWx0VmFsdWUoJHJlcXVpcmVkT25seSwgJHNjaGVtYSkpIHsKICAgICAgICAgICAgLy8gJHZhbHVlIGlzIGEgbGVhZiwgbm90IGEgY29udGFpbmVyIC0gYXBwbHkgdGhlIGRlZmF1bHQgZGlyZWN0bHkKICAgICAgICAgICAgJHZhbHVlID0gaXNfb2JqZWN0KCRzY2hlbWEtPmRlZmF1bHQpID8gY2xvbmUgJHNjaGVtYS0+ZGVmYXVsdCA6ICRzY2hlbWEtPmRlZmF1bHQ7CiAgICAgICAgICAgICRwYXRoLT5zZXRGcm9tRGVmYXVsdCgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlIGFsbE9mLCBhbnlPZiwgYW5kIG9uZU9mIHByb3BlcnRpZXMKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyICRwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlT2ZQcm9wZXJ0aWVzKCYkdmFsdWUsICRzY2hlbWEsIEpzb25Qb2ludGVyICRwYXRoLCAkaSA9ICcnKQogICAgewogICAgICAgIC8vIFZlcmlmeSB0eXBlCiAgICAgICAgaWYgKCR2YWx1ZSBpbnN0YW5jZW9mIHNlbGYpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmFsbE9mKSkgewogICAgICAgICAgICAkaXNWYWxpZCA9IHRydWU7CiAgICAgICAgICAgIGZvcmVhY2ggKCRzY2hlbWEtPmFsbE9mIGFzICRhbGxPZikgewogICAgICAgICAgICAgICAgJGluaXRFcnJvcnMgPSAkdGhpcy0+Z2V0RXJyb3JzKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkYWxsT2YsICRwYXRoLCAkaSk7CiAgICAgICAgICAgICAgICAkaXNWYWxpZCA9ICRpc1ZhbGlkICYmIChjb3VudCgkdGhpcy0+Z2V0RXJyb3JzKCkpID09IGNvdW50KCRpbml0RXJyb3JzKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkaXNWYWxpZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnRmFpbGVkIHRvIG1hdGNoIGFsbCBzY2hlbWFzJywgJ2FsbE9mJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5hbnlPZikpIHsKICAgICAgICAgICAgJGlzVmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgJHN0YXJ0RXJyb3JzID0gJHRoaXMtPmdldEVycm9ycygpOwogICAgICAgICAgICAkY2F1Z2h0RXhjZXB0aW9uID0gbnVsbDsKICAgICAgICAgICAgZm9yZWFjaCAoJHNjaGVtYS0+YW55T2YgYXMgJGFueU9mKSB7CiAgICAgICAgICAgICAgICAkaW5pdEVycm9ycyA9ICR0aGlzLT5nZXRFcnJvcnMoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJGFueU9mLCAkcGF0aCwgJGkpOwogICAgICAgICAgICAgICAgICAgIGlmICgkaXNWYWxpZCA9IChjb3VudCgkdGhpcy0+Z2V0RXJyb3JzKCkpID09IGNvdW50KCRpbml0RXJyb3JzKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoVmFsaWRhdGlvbkV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgICRpc1ZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkaXNWYWxpZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnRmFpbGVkIHRvIG1hdGNoIGF0IGxlYXN0IG9uZSBzY2hlbWEnLCAnYW55T2YnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnMgPSAkc3RhcnRFcnJvcnM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5vbmVPZikpIHsKICAgICAgICAgICAgJGFsbEVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgICAgICRtYXRjaGVkU2NoZW1hcyA9IDA7CiAgICAgICAgICAgICRzdGFydEVycm9ycyA9ICR0aGlzLT5nZXRFcnJvcnMoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHNjaGVtYS0+b25lT2YgYXMgJG9uZU9mKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdmFsdWUsICRvbmVPZiwgJHBhdGgsICRpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQoJHRoaXMtPmdldEVycm9ycygpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVkU2NoZW1hcysrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkYWxsRXJyb3JzID0gYXJyYXlfbWVyZ2UoJGFsbEVycm9ycywgYXJyYXlfdmFsdWVzKCR0aGlzLT5nZXRFcnJvcnMoKSkpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoVmFsaWRhdGlvbkV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGRlbGliZXJhdGVseSBkbyBub3RoaW5nIGhlcmUgLSB2YWxpZGF0aW9uIGZhaWxlZCwgYnV0IHdlIHdhbnQgdG8gY2hlY2sKICAgICAgICAgICAgICAgICAgICAvLyBvdGhlciBzY2hlbWEgb3B0aW9ucyBpbiB0aGUgT25lT2YgZmllbGQuCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRtYXRjaGVkU2NoZW1hcyAhPT0gMSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9ycyhhcnJheV9tZXJnZSgkYWxsRXJyb3JzLCAkc3RhcnRFcnJvcnMpKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ZhaWxlZCB0byBtYXRjaCBleGFjdGx5IG9uZSBzY2hlbWEnLCAnb25lT2YnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnMgPSAkc3RhcnRFcnJvcnM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZSBkZXBlbmRlbmNpZXMKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJGRlcGVuZGVuY2llcwogICAgICogQHBhcmFtIEpzb25Qb2ludGVyICRwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlRGVwZW5kZW5jaWVzKCR2YWx1ZSwgJGRlcGVuZGVuY2llcywgSnNvblBvaW50ZXIgJHBhdGgsICRpID0gJycpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGRlcGVuZGVuY2llcyBhcyAka2V5ID0+ICRkZXBlbmRlbmN5KSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+Z2V0VHlwZUNoZWNrKCktPnByb3BlcnR5RXhpc3RzKCR2YWx1ZSwgJGtleSkpIHsKICAgICAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJGRlcGVuZGVuY3kpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRHJhZnQgMyBzdHJpbmcgaXMgYWxsb3dlZCAtIGUuZy4gImRlcGVuZGVuY2llcyI6IHsiYmFyIjogImZvbyJ9CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+Z2V0VHlwZUNoZWNrKCktPnByb3BlcnR5RXhpc3RzKCR2YWx1ZSwgJGRlcGVuZGVuY3kpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgIiRrZXkgZGVwZW5kcyBvbiAkZGVwZW5kZW5jeSBhbmQgJGRlcGVuZGVuY3kgaXMgbWlzc2luZyIsICdkZXBlbmRlbmNpZXMnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNfYXJyYXkoJGRlcGVuZGVuY3kpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRHJhZnQgNCBtdXN0IGJlIGFuIGFycmF5IC0gZS5nLiAiZGVwZW5kZW5jaWVzIjogeyJiYXIiOiBbImZvbyJdfQogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRkZXBlbmRlbmN5IGFzICRkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUV4aXN0cygkdmFsdWUsICRkKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAiJGtleSBkZXBlbmRzIG9uICRkIGFuZCAkZCBpcyBtaXNzaW5nIiwgJ2RlcGVuZGVuY2llcycpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX29iamVjdCgkZGVwZW5kZW5jeSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTY2hlbWEgLSBlLmcuICJkZXBlbmRlbmNpZXMiOiB7ImJhciI6IHsicHJvcGVydGllcyI6IHsiZm9vIjogey4uLn19fX0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkZGVwZW5kZW5jeSwgJHBhdGgsICRpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVVcmkoJHNjaGVtYSwgJHNjaGVtYVVyaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHJlc29sdmVyID0gbmV3IFVyaVJlc29sdmVyKCk7CiAgICAgICAgJHJldHJpZXZlciA9ICR0aGlzLT5mYWN0b3J5LT5nZXRVcmlSZXRyaWV2ZXIoKTsKCiAgICAgICAgJGpzb25TY2hlbWEgPSBudWxsOwogICAgICAgIGlmICgkcmVzb2x2ZXItPmlzVmFsaWQoJHNjaGVtYVVyaSkpIHsKICAgICAgICAgICAgJHNjaGVtYUlkID0gcHJvcGVydHlfZXhpc3RzKCRzY2hlbWEsICdpZCcpID8gJHNjaGVtYS0+aWQgOiBudWxsOwogICAgICAgICAgICAkanNvblNjaGVtYSA9ICRyZXRyaWV2ZXItPnJldHJpZXZlKCRzY2hlbWFJZCwgJHNjaGVtYVVyaSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGpzb25TY2hlbWE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uIGFzIFN0YW5kYXJkVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uOwoKLyoqCiAqIFRoZSBUeXBlQ29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIGVsZW1lbnQgYWdhaW5zdCBhIGdpdmVuIHR5cGUKICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgQnJ1bm8gUHJpZXRvIFJlaXMgPGJydW5vLnAucmVpc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBUeXBlQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5fHN0cmluZ1tdIHR5cGUgd29yZGluZ3MgZm9yIHZhbGlkYXRpb24gZXJyb3IgbWVzc2FnZXMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyAkd29yZGluZyA9IGFycmF5KAogICAgICAgICdpbnRlZ2VyJyA9PiAnYW4gaW50ZWdlcicsCiAgICAgICAgJ251bWJlcicgID0+ICdhIG51bWJlcicsCiAgICAgICAgJ2Jvb2xlYW4nID0+ICdhIGJvb2xlYW4nLAogICAgICAgICdvYmplY3QnICA9PiAnYW4gb2JqZWN0JywKICAgICAgICAnYXJyYXknICAgPT4gJ2FuIGFycmF5JywKICAgICAgICAnc3RyaW5nJyAgPT4gJ2Egc3RyaW5nJywKICAgICAgICAnbnVsbCcgICAgPT4gJ2EgbnVsbCcsCiAgICAgICAgJ2FueScgICAgID0+IG51bGwsIC8vIHZhbGlkYXRpb24gb2YgJ2FueScgaXMgYWx3YXlzIHRydWUgc28gaXMgbm90IG5lZWRlZCBpbiBtZXNzYWdlIHdvcmRpbmcKICAgICAgICAwICAgICAgICAgPT4gbnVsbCwgLy8gdmFsaWRhdGlvbiBvZiBhIGZhbHNlLXkgdmFsdWUgaXMgYWx3YXlzIHRydWUsIHNvIG5vdCBuZWVkZWQgYXMgd2VsbAogICAgKTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCYkdmFsdWUgPSBudWxsLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHR5cGUgPSBpc3NldCgkc2NoZW1hLT50eXBlKSA/ICRzY2hlbWEtPnR5cGUgOiBudWxsOwogICAgICAgICRpc1ZhbGlkID0gZmFsc2U7CiAgICAgICAgJHdvcmRpbmcgPSBhcnJheSgpOwoKICAgICAgICBpZiAoaXNfYXJyYXkoJHR5cGUpKSB7CiAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZVR5cGVzQXJyYXkoJHZhbHVlLCAkdHlwZSwgJHdvcmRpbmcsICRpc1ZhbGlkLCAkcGF0aCk7CiAgICAgICAgfSBlbHNlaWYgKGlzX29iamVjdCgkdHlwZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJHR5cGUsICRwYXRoKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaXNWYWxpZCA9ICR0aGlzLT52YWxpZGF0ZVR5cGUoJHZhbHVlLCAkdHlwZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlzVmFsaWQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHR5cGUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVUeXBlTmFtZVdvcmRpbmcoJHR5cGUpOwogICAgICAgICAgICAgICAgJHdvcmRpbmdbXSA9IHNlbGY6OiR3b3JkaW5nWyR0eXBlXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsIHVjd29yZHMoZ2V0dHlwZSgkdmFsdWUpKSAuICcgdmFsdWUgZm91bmQsIGJ1dCAnIC4KICAgICAgICAgICAgICAgICR0aGlzLT5pbXBsb2RlV2l0aCgkd29yZGluZywgJywgJywgJ29yJykgLiAnIGlzIHJlcXVpcmVkJywgJ3R5cGUnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGdpdmVuICR2YWx1ZSBhZ2FpbnN0IHRoZSBhcnJheSBvZiB0eXBlcyBpbiAkdHlwZS4gU2V0cyB0aGUgdmFsdWUKICAgICAqIG9mICRpc1ZhbGlkIHRvIHRydWUsIGlmIGF0IGxlYXN0IG9uZSAkdHlwZSBtYXRlY2hlcyB0aGUgdHlwZSBvZiAkdmFsdWUgb3IgdGhlIHZhbHVlCiAgICAgKiBwYXNzZWQgYXMgJGlzVmFsaWQgaXMgYWxyZWFkeSB0cnVlLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgICAgICAgICAgICAgVmFsdWUgdG8gdmFsaWRhdGUKICAgICAqIEBwYXJhbSBhcnJheSAkdHlwZSAgICAgICAgICAgICAgVHlwZUNvbnN0cmFpbnRzIHRvIGNoZWNrIGFnYWlucwogICAgICogQHBhcmFtIGFycmF5ICR2YWxpZFR5cGVzV29yZGluZyBBbiBhcnJheSBvZiB3b3JkaW5ncyBvZiB0aGUgdmFsaWQgdHlwZXMgb2YgdGhlIGFycmF5ICR0eXBlCiAgICAgKiBAcGFyYW0gYm9vbCAgJGlzVmFsaWQgICAgICAgICAgIFRoZSBjdXJyZW50IHZhbGlkYXRpb24gdmFsdWUKICAgICAqIEBwYXJhbSAkcGF0aAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVUeXBlc0FycmF5KCYkdmFsdWUsIGFycmF5ICR0eXBlLCAmJHZhbGlkVHlwZXNXb3JkaW5nLCAmJGlzVmFsaWQsICRwYXRoKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0eXBlIGFzICR0cCkgewogICAgICAgICAgICAvLyAkdHAgY2FuIGJlIGFuIG9iamVjdCwgaWYgaXQncyBhIHNjaGVtYSBpbnN0ZWFkIG9mIGEgc2ltcGxlIHR5cGUsIHZhbGlkYXRlIGl0CiAgICAgICAgICAgIC8vIHdpdGggYSBuZXcgdHlwZSBjb25zdHJhaW50CiAgICAgICAgICAgIGlmIChpc19vYmplY3QoJHRwKSkgewogICAgICAgICAgICAgICAgaWYgKCEkaXNWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICR2YWxpZGF0b3IgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ3R5cGUnKTsKICAgICAgICAgICAgICAgICAgICAkc3ViU2NoZW1hID0gbmV3IFxzdGRDbGFzcygpOwogICAgICAgICAgICAgICAgICAgICRzdWJTY2hlbWEtPnR5cGUgPSAkdHA7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc3ViU2NoZW1hLCAkcGF0aCwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yID0gJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCk7CiAgICAgICAgICAgICAgICAgICAgJGlzVmFsaWQgPSAhKGJvb2wpICRlcnJvcjsKICAgICAgICAgICAgICAgICAgICAkdmFsaWRUeXBlc1dvcmRpbmdbXSA9IHNlbGY6OiR3b3JkaW5nWydvYmplY3QnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZVR5cGVOYW1lV29yZGluZygkdHApOwogICAgICAgICAgICAgICAgJHZhbGlkVHlwZXNXb3JkaW5nW10gPSBzZWxmOjokd29yZGluZ1skdHBdOwogICAgICAgICAgICAgICAgaWYgKCEkaXNWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICRpc1ZhbGlkID0gJHRoaXMtPnZhbGlkYXRlVHlwZSgkdmFsdWUsICR0cCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbXBsb2RlcyB0aGUgZ2l2ZW4gYXJyYXkgbGlrZSBpbXBsb2RlKCkgd2l0aCB0dXJuZWQgYXJvdW5kIHBhcmFtZXRlcnMgYW5kIHdpdGggdGhlCiAgICAgKiBkaWZmZXJlbmNlLCB0aGF0LCBpZiAkbGlzdEVuZCBpc24ndCBmYWxzZSwgdGhlIGxhc3QgZWxlbWVudCBkZWxpbWl0ZXIgaXMgJGxpc3RFbmQgaW5zdGVhZCBvZgogICAgICogJGRlbGltaXRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICRlbGVtZW50cyAgVGhlIGVsZW1lbnRzIHRvIGltcGxvZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlbGltaXRlciBUaGUgZGVsaW1pdGVyIHRvIHVzZQogICAgICogQHBhcmFtIGJvb2wgICAkbGlzdEVuZCAgIFRoZSBsYXN0IGRlbGltaXRlciB0byB1c2UgKGRlZmF1bHRzIHRvICRkZWxpbWl0ZXIpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGltcGxvZGVXaXRoKGFycmF5ICRlbGVtZW50cywgJGRlbGltaXRlciA9ICcsICcsICRsaXN0RW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRsaXN0RW5kID09PSBmYWxzZSB8fCAhaXNzZXQoJGVsZW1lbnRzWzFdKSkgewogICAgICAgICAgICByZXR1cm4gaW1wbG9kZSgkZGVsaW1pdGVyLCAkZWxlbWVudHMpOwogICAgICAgIH0KICAgICAgICAkbGFzdEVsZW1lbnQgID0gYXJyYXlfc2xpY2UoJGVsZW1lbnRzLCAtMSk7CiAgICAgICAgJGZpcnNFbGVtZW50cyA9IGpvaW4oJGRlbGltaXRlciwgYXJyYXlfc2xpY2UoJGVsZW1lbnRzLCAwLCAtMSkpOwogICAgICAgICRpbXBsb2RlZEVsZW1lbnRzID0gYXJyYXlfbWVyZ2UoYXJyYXkoJGZpcnNFbGVtZW50cyksICRsYXN0RWxlbWVudCk7CgogICAgICAgIHJldHVybiBqb2luKCIgJGxpc3RFbmQgIiwgJGltcGxvZGVkRWxlbWVudHMpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBnaXZlbiAkdHlwZSwgaWYgdGhlcmUncyBhbiBhc3NvY2lhdGVkIHNlbGY6OiR3b3JkaW5nLiBJZiBub3QsIHRocm93cyBhbgogICAgICogZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgVGhlIHR5cGUgdG8gdmFsaWRhdGUKICAgICAqCiAgICAgKiBAdGhyb3dzIFN0YW5kYXJkVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZVR5cGVOYW1lV29yZGluZygkdHlwZSkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiR3b3JkaW5nWyR0eXBlXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0YW5kYXJkVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnTm8gd29yZGluZyBmb3IgJXMgYXZhaWxhYmxlLCBleHBlY3RlZCB3b3JkaW5ncyBhcmU6IFslc10nLAogICAgICAgICAgICAgICAgICAgIHZhcl9leHBvcnQoJHR5cGUsIHRydWUpLAogICAgICAgICAgICAgICAgICAgIGltcGxvZGUoJywgJywgYXJyYXlfZmlsdGVyKHNlbGY6OiR3b3JkaW5nKSkpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmVyaWZpZXMgdGhhdCBhIGdpdmVuIHZhbHVlIGlzIG9mIGEgY2VydGFpbiB0eXBlCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkdmFsdWUgVmFsdWUgdG8gdmFsaWRhdGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgIFR5cGVDb25zdHJhaW50IHRvIGNoZWNrIGFnYWluc3QKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVUeXBlKCYkdmFsdWUsICR0eXBlKQogICAgewogICAgICAgIC8vbW9zdGx5IHRoZSBjYXNlIGZvciBpbmxpbmUgc2NoZW1hCiAgICAgICAgaWYgKCEkdHlwZSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICgnYW55JyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ29iamVjdCcgPT09ICR0eXBlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VHlwZUNoZWNrKCktPmlzT2JqZWN0KCR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ2FycmF5JyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+aXNBcnJheSgkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgJGNvZXJjZSA9ICR0aGlzLT5mYWN0b3J5LT5nZXRDb25maWcoQ29uc3RyYWludDo6Q0hFQ0tfTU9ERV9DT0VSQ0VfVFlQRVMpOwoKICAgICAgICBpZiAoJ2ludGVnZXInID09PSAkdHlwZSkgewogICAgICAgICAgICBpZiAoJGNvZXJjZSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPnRvSW50ZWdlcigkdmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaXNfaW50KCR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ251bWJlcicgPT09ICR0eXBlKSB7CiAgICAgICAgICAgIGlmICgkY29lcmNlKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+dG9OdW1iZXIoJHZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlzX251bWVyaWMoJHZhbHVlKSAmJiAhaXNfc3RyaW5nKCR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ2Jvb2xlYW4nID09PSAkdHlwZSkgewogICAgICAgICAgICBpZiAoJGNvZXJjZSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPnRvQm9vbGVhbigkdmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaXNfYm9vbCgkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdzdHJpbmcnID09PSAkdHlwZSkgewogICAgICAgICAgICByZXR1cm4gaXNfc3RyaW5nKCR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ2VtYWlsJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIGlzX3N0cmluZygkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdudWxsJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIGlzX251bGwoJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oKGlzX29iamVjdCgkdmFsdWUpID8gJ29iamVjdCcgOiAkdmFsdWUpIC4gJyBpcyBhbiBpbnZhbGlkIHR5cGUgZm9yICcgLiAkdHlwZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGJvb2xlYW4uIEZvciBleGFtcGxlLCAidHJ1ZSIgYmVjb21lcyB0cnVlLgogICAgICoKICAgICAqIEBwYXJhbSAkdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYm9vbGVhbgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbHxtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdG9Cb29sZWFuKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoJHZhbHVlID09PSAndHJ1ZScpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHZhbHVlID09PSAnZmFsc2UnKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIG51bWVyaWMgc3RyaW5nIHRvIGEgbnVtYmVyLiBGb3IgZXhhbXBsZSwgIjQiIGJlY29tZXMgNC4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIHRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgbnVtYmVyCiAgICAgKgogICAgICogQHJldHVybiBpbnR8ZmxvYXR8bWl4ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHRvTnVtYmVyKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoaXNfbnVtZXJpYygkdmFsdWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkdmFsdWUgKyAwOyAvLyBjYXN0IHRvIG51bWJlcgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdG9JbnRlZ2VyKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoaXNfbnVtZXJpYygkdmFsdWUpICYmIChpbnQpICR2YWx1ZSA9PSAkdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIChpbnQpICR2YWx1ZTsgLy8gY2FzdCB0byBudW1iZXIKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwoKLyoqCiAqIFRoZSBFbnVtQ29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIGVsZW1lbnQgYWdhaW5zdCBhIGdpdmVuIHNldCBvZiBwb3NzaWJpbGl0aWVzCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgRW51bUNvbnN0cmFpbnQgZXh0ZW5kcyBDb25zdHJhaW50CnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiRlbGVtZW50LCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gT25seSB2YWxpZGF0ZSBlbnVtIGlmIHRoZSBhdHRyaWJ1dGUgZXhpc3RzCiAgICAgICAgaWYgKCRlbGVtZW50IGluc3RhbmNlb2YgVW5kZWZpbmVkQ29uc3RyYWludCAmJiAoIWlzc2V0KCRzY2hlbWEtPnJlcXVpcmVkKSB8fCAhJHNjaGVtYS0+cmVxdWlyZWQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHR5cGUgPSBnZXR0eXBlKCRlbGVtZW50KTsKCiAgICAgICAgZm9yZWFjaCAoJHNjaGVtYS0+ZW51bSBhcyAkZW51bSkgewogICAgICAgICAgICAkZW51bVR5cGUgPSBnZXR0eXBlKCRlbnVtKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5mYWN0b3J5LT5nZXRDb25maWcoc2VsZjo6Q0hFQ0tfTU9ERV9UWVBFX0NBU1QpICYmICR0eXBlID09ICdhcnJheScgJiYgJGVudW1UeXBlID09ICdvYmplY3QnKSB7CiAgICAgICAgICAgICAgICBpZiAoKG9iamVjdCkgJGVsZW1lbnQgPT0gJGVudW0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gZ2V0dHlwZSgkZW51bSkpIHsKICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PSAnb2JqZWN0JykgewogICAgICAgICAgICAgICAgICAgIGlmICgkZWxlbWVudCA9PSAkZW51bSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRlbGVtZW50ID09PSAkZW51bSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnRG9lcyBub3QgaGF2ZSBhIHZhbHVlIGluIHRoZSBlbnVtZXJhdGlvbiAnIC4ganNvbl9lbmNvZGUoJHNjaGVtYS0+ZW51bSksICdlbnVtJywgYXJyYXkoJ2VudW0nID0+ICRzY2hlbWEtPmVudW0pKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFbnRpdHlcSnNvblBvaW50ZXI7CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxWYWxpZGF0aW9uRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CgovKioKICogQSBtb3JlIGJhc2ljIGNvbnN0cmFpbnQgZGVmaW5pdGlvbiAtIHVzZWQgZm9yIHRoZSBwdWJsaWMKICogaW50ZXJmYWNlIHRvIGF2b2lkIGV4cG9zaW5nIGxpYnJhcnkgaW50ZXJuYWxzLgogKi8KY2xhc3MgQmFzZUNvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IEVycm9ycwogICAgICovCiAgICBwcm90ZWN0ZWQgJGVycm9ycyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGludCBBbGwgZXJyb3IgdHlwZXMgd2hpY2ggaGF2ZSBvY2N1cnJlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGVycm9yTWFzayA9IFZhbGlkYXRvcjo6RVJST1JfTk9ORTsKCiAgICAvKioKICAgICAqIEB2YXIgRmFjdG9yeQogICAgICovCiAgICBwcm90ZWN0ZWQgJGZhY3Rvcnk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gRmFjdG9yeSAkZmFjdG9yeQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoRmFjdG9yeSAkZmFjdG9yeSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmZhY3RvcnkgPSAkZmFjdG9yeSA/OiBuZXcgRmFjdG9yeSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRFcnJvcihKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRtZXNzYWdlLCAkY29uc3RyYWludCA9ICcnLCBhcnJheSAkbW9yZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGVycm9yID0gYXJyYXkoCiAgICAgICAgICAgICdwcm9wZXJ0eScgPT4gJHRoaXMtPmNvbnZlcnRKc29uUG9pbnRlckludG9Qcm9wZXJ0eVBhdGgoJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKSksCiAgICAgICAgICAgICdwb2ludGVyJyA9PiBsdHJpbShzdHJ2YWwoJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKSksICcjJyksCiAgICAgICAgICAgICdtZXNzYWdlJyA9PiAkbWVzc2FnZSwKICAgICAgICAgICAgJ2NvbnN0cmFpbnQnID0+ICRjb25zdHJhaW50LAogICAgICAgICAgICAnY29udGV4dCcgPT4gJHRoaXMtPmZhY3RvcnktPmdldEVycm9yQ29udGV4dCgpLAogICAgICAgICk7CgogICAgICAgIGlmICgkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKENvbnN0cmFpbnQ6OkNIRUNLX01PREVfRVhDRVBUSU9OUykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FeGNlcHRpb24oc3ByaW50ZignRXJyb3IgdmFsaWRhdGluZyAlczogJXMnLCAkZXJyb3JbJ3BvaW50ZXInXSwgJGVycm9yWydtZXNzYWdlJ10pKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc19hcnJheSgkbW9yZSkgJiYgY291bnQoJG1vcmUpID4gMCkgewogICAgICAgICAgICAkZXJyb3IgKz0gJG1vcmU7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkZXJyb3I7CiAgICAgICAgJHRoaXMtPmVycm9yTWFzayB8PSAkZXJyb3JbJ2NvbnRleHQnXTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRXJyb3JzKGFycmF5ICRlcnJvcnMpCiAgICB7CiAgICAgICAgaWYgKCRlcnJvcnMpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9ycyA9IGFycmF5X21lcmdlKCR0aGlzLT5lcnJvcnMsICRlcnJvcnMpOwogICAgICAgICAgICAkZXJyb3JNYXNrID0gJiR0aGlzLT5lcnJvck1hc2s7CiAgICAgICAgICAgIGFycmF5X3dhbGsoJGVycm9ycywgZnVuY3Rpb24gKCRlcnJvcikgdXNlICgmJGVycm9yTWFzaykgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRlcnJvclsnY29udGV4dCddKSkgewogICAgICAgICAgICAgICAgICAgICRlcnJvck1hc2sgfD0gJGVycm9yWydjb250ZXh0J107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JzKCRlcnJvckNvbnRleHQgPSBWYWxpZGF0b3I6OkVSUk9SX0FMTCkKICAgIHsKICAgICAgICBpZiAoJGVycm9yQ29udGV4dCA9PT0gVmFsaWRhdG9yOjpFUlJPUl9BTEwpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcnM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfZmlsdGVyKCR0aGlzLT5lcnJvcnMsIGZ1bmN0aW9uICgkZXJyb3IpIHVzZSAoJGVycm9yQ29udGV4dCkgewogICAgICAgICAgICBpZiAoJGVycm9yQ29udGV4dCAmICRlcnJvclsnY29udGV4dCddKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBudW1FcnJvcnMoJGVycm9yQ29udGV4dCA9IFZhbGlkYXRvcjo6RVJST1JfQUxMKQogICAgewogICAgICAgIGlmICgkZXJyb3JDb250ZXh0ID09PSBWYWxpZGF0b3I6OkVSUk9SX0FMTCkgewogICAgICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmVycm9ycyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmdldEVycm9ycygkZXJyb3JDb250ZXh0KSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzVmFsaWQoKQogICAgewogICAgICAgIHJldHVybiAhJHRoaXMtPmdldEVycm9ycygpOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXJzIGFueSByZXBvcnRlZCBlcnJvcnMuICBTaG91bGQgYmUgdXNlZCBiZXR3ZWVuCiAgICAgKiBtdWx0aXBsZSB2YWxpZGF0aW9uIGNoZWNrcy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc2V0KCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+ZXJyb3JNYXNrID0gVmFsaWRhdG9yOjpFUlJPUl9OT05FOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBlcnJvciBtYXNrCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9yTWFzaygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvck1hc2s7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSBjYXN0IGFuIGFzc29jaWF0aXZlIGFycmF5IHRvIGFuIG9iamVjdAogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkYXJyYXkKICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFycmF5VG9PYmplY3RSZWN1cnNpdmUoJGFycmF5KQogICAgewogICAgICAgICRqc29uID0ganNvbl9lbmNvZGUoJGFycmF5KTsKICAgICAgICBpZiAoanNvbl9sYXN0X2Vycm9yKCkgIT09IFxKU09OX0VSUk9SX05PTkUpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAnVW5hYmxlIHRvIGVuY29kZSBzY2hlbWEgYXJyYXkgYXMgSlNPTic7CiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2pzb25fbGFzdF9lcnJvcl9tc2cnKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gJzogJyAuIGpzb25fbGFzdF9lcnJvcl9tc2coKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCRtZXNzYWdlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAob2JqZWN0KSBqc29uX2RlY29kZSgkanNvbik7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEl0ZXJhdG9yOwoKLyoqCiAqIEBwYWNrYWdlIEpzb25TY2hlbWFcSXRlcmF0b3IKICoKICogQGF1dGhvciBKb29zdCBOaWpodWlzIDxqbmlqaHVpczgxQGdtYWlsLmNvbT4KICovCmNsYXNzIE9iamVjdEl0ZXJhdG9yIGltcGxlbWVudHMgXEl0ZXJhdG9yLCBcQ291bnRhYmxlCnsKICAgIC8qKiBAdmFyIG9iamVjdCAqLwogICAgcHJpdmF0ZSAkb2JqZWN0OwoKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkcG9zaXRpb24gPSAwOwoKICAgIC8qKiBAdmFyIGFycmF5ICovCiAgICBwcml2YXRlICRkYXRhID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRpbml0aWFsaXplZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIG9iamVjdCAkb2JqZWN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkb2JqZWN0KQogICAgewogICAgICAgICR0aGlzLT5vYmplY3QgPSAkb2JqZWN0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemUoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5kYXRhWyR0aGlzLT5wb3NpdGlvbl07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBuZXh0KCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwogICAgICAgICR0aGlzLT5wb3NpdGlvbisrOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24ga2V5KCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnBvc2l0aW9uOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CgogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZGF0YVskdGhpcy0+cG9zaXRpb25dKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJld2luZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemUoKTsKICAgICAgICAkdGhpcy0+cG9zaXRpb24gPSAwOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY291bnQoKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CgogICAgICAgIHJldHVybiBjb3VudCgkdGhpcy0+ZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmluaXRpYWxpemVkKSB7CiAgICAgICAgICAgICR0aGlzLT5kYXRhID0gJHRoaXMtPmJ1aWxkRGF0YUZyb21PYmplY3QoJHRoaXMtPm9iamVjdCk7CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG9iamVjdCAkb2JqZWN0CiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGJ1aWxkRGF0YUZyb21PYmplY3QoJG9iamVjdCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKCiAgICAgICAgJHN0YWNrID0gbmV3IFxTcGxTdGFjaygpOwogICAgICAgICRzdGFjay0+cHVzaCgkb2JqZWN0KTsKCiAgICAgICAgd2hpbGUgKCEkc3RhY2stPmlzRW1wdHkoKSkgewogICAgICAgICAgICAkY3VycmVudCA9ICRzdGFjay0+cG9wKCk7CiAgICAgICAgICAgIGlmIChpc19vYmplY3QoJGN1cnJlbnQpKSB7CiAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRyZXN1bHQsICRjdXJyZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldERhdGFGcm9tSXRlbSgkY3VycmVudCkgYXMgJHByb3BlcnR5TmFtZSA9PiAkcHJvcGVydHlWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKGlzX29iamVjdCgkcHJvcGVydHlWYWx1ZSkgfHwgaXNfYXJyYXkoJHByb3BlcnR5VmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHN0YWNrLT5wdXNoKCRwcm9wZXJ0eVZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gb2JqZWN0fGFycmF5ICRpdGVtCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERhdGFGcm9tSXRlbSgkaXRlbSkKICAgIHsKICAgICAgICBpZiAoIWlzX29iamVjdCgkaXRlbSkgJiYgIWlzX2FycmF5KCRpdGVtKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc19vYmplY3QoJGl0ZW0pID8gZ2V0X29iamVjdF92YXJzKCRpdGVtKSA6ICRpdGVtOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxVcmk7Cgp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cVXJpUmVzb2x2ZXJFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXFVyaVJlc29sdmVySW50ZXJmYWNlOwoKLyoqCiAqIFJlc29sdmVzIEpTT04gU2NoZW1hIFVSSXMKICoKICogQGF1dGhvciBTYW5kZXIgQ29vbGVuIDxzYW5kZXJAamliYmVyLm5sPgogKi8KY2xhc3MgVXJpUmVzb2x2ZXIgaW1wbGVtZW50cyBVcmlSZXNvbHZlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFBhcnNlcyBhIFVSSSBpbnRvIGZpdmUgbWFpbiBjb21wb25lbnRzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJpCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2UoJHVyaSkKICAgIHsKICAgICAgICBwcmVnX21hdGNoKCd8XigoW146Lz8jXSspOik/KC8vKFteLz8jXSopKT8oW14/I10qKShcPyhbXiNdKikpPygjKC4qKSk/fCcsICR1cmksICRtYXRjaCk7CgogICAgICAgICRjb21wb25lbnRzID0gYXJyYXkoKTsKICAgICAgICBpZiAoNSA8IGNvdW50KCRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbXBvbmVudHMgPSAgYXJyYXkoCiAgICAgICAgICAgICAgICAnc2NoZW1lJyAgICA9PiAkbWF0Y2hbMl0sCiAgICAgICAgICAgICAgICAnYXV0aG9yaXR5JyA9PiAkbWF0Y2hbNF0sCiAgICAgICAgICAgICAgICAncGF0aCcgICAgICA9PiAkbWF0Y2hbNV0KICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgaWYgKDcgPCBjb3VudCgkbWF0Y2gpKSB7CiAgICAgICAgICAgICRjb21wb25lbnRzWydxdWVyeSddID0gJG1hdGNoWzddOwogICAgICAgIH0KICAgICAgICBpZiAoOSA8IGNvdW50KCRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbXBvbmVudHNbJ2ZyYWdtZW50J10gPSAkbWF0Y2hbOV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbXBvbmVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZHMgYSBVUkkgYmFzZWQgb24gbiBhcnJheSB3aXRoIHRoZSBtYWluIGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2VuZXJhdGUoYXJyYXkgJGNvbXBvbmVudHMpCiAgICB7CiAgICAgICAgJHVyaSA9ICRjb21wb25lbnRzWydzY2hlbWUnXSAuICc6Ly8nCiAgICAgICAgICAgICAuICRjb21wb25lbnRzWydhdXRob3JpdHknXQogICAgICAgICAgICAgLiAkY29tcG9uZW50c1sncGF0aCddOwoKICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygncXVlcnknLCAkY29tcG9uZW50cykgJiYgc3RybGVuKCRjb21wb25lbnRzWydxdWVyeSddKSkgewogICAgICAgICAgICAkdXJpIC49ICc/JyAuICRjb21wb25lbnRzWydxdWVyeSddOwogICAgICAgIH0KICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygnZnJhZ21lbnQnLCAkY29tcG9uZW50cykpIHsKICAgICAgICAgICAgJHVyaSAuPSAnIycgLiAkY29tcG9uZW50c1snZnJhZ21lbnQnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzb2x2ZSgkdXJpLCAkYmFzZVVyaSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gdHJlYXQgbm9uLXVyaSBiYXNlIGFzIGxvY2FsIGZpbGUgcGF0aAogICAgICAgIGlmICgKICAgICAgICAgICAgIWlzX251bGwoJGJhc2VVcmkpICYmCiAgICAgICAgICAgICFmaWx0ZXJfdmFyKCRiYXNlVXJpLCBcRklMVEVSX1ZBTElEQVRFX1VSTCkgJiYKICAgICAgICAgICAgIXByZWdfbWF0Y2goJ3xeW14vXSs6Ly98dScsICRiYXNlVXJpKQogICAgICAgICkgewogICAgICAgICAgICBpZiAoaXNfZmlsZSgkYmFzZVVyaSkpIHsKICAgICAgICAgICAgICAgICRiYXNlVXJpID0gJ2ZpbGU6Ly8nIC4gcmVhbHBhdGgoJGJhc2VVcmkpOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNfZGlyKCRiYXNlVXJpKSkgewogICAgICAgICAgICAgICAgJGJhc2VVcmkgPSAnZmlsZTovLycgLiByZWFscGF0aCgkYmFzZVVyaSkgLiAnLyc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYmFzZVVyaSA9ICdmaWxlOi8vJyAuIGdldGN3ZCgpIC4gJy8nIC4gJGJhc2VVcmk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdXJpID09ICcnKSB7CiAgICAgICAgICAgIHJldHVybiAkYmFzZVVyaTsKICAgICAgICB9CgogICAgICAgICRjb21wb25lbnRzID0gJHRoaXMtPnBhcnNlKCR1cmkpOwogICAgICAgICRwYXRoID0gJGNvbXBvbmVudHNbJ3BhdGgnXTsKCiAgICAgICAgaWYgKCFlbXB0eSgkY29tcG9uZW50c1snc2NoZW1lJ10pKSB7CiAgICAgICAgICAgIHJldHVybiAkdXJpOwogICAgICAgIH0KICAgICAgICAkYmFzZUNvbXBvbmVudHMgPSAkdGhpcy0+cGFyc2UoJGJhc2VVcmkpOwogICAgICAgICRiYXNlUGF0aCA9ICRiYXNlQ29tcG9uZW50c1sncGF0aCddOwoKICAgICAgICAkYmFzZUNvbXBvbmVudHNbJ3BhdGgnXSA9IHNlbGY6OmNvbWJpbmVSZWxhdGl2ZVBhdGhXaXRoQmFzZVBhdGgoJHBhdGgsICRiYXNlUGF0aCk7CiAgICAgICAgaWYgKGlzc2V0KCRjb21wb25lbnRzWydmcmFnbWVudCddKSkgewogICAgICAgICAgICAkYmFzZUNvbXBvbmVudHNbJ2ZyYWdtZW50J10gPSAkY29tcG9uZW50c1snZnJhZ21lbnQnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2VuZXJhdGUoJGJhc2VDb21wb25lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRyaWVzIHRvIGdsdWUgYSByZWxhdGl2ZSBwYXRoIG9udG8gYW4gYWJzb2x1dGUgb25lCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVsYXRpdmVQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlUGF0aAogICAgICoKICAgICAqIEB0aHJvd3MgVXJpUmVzb2x2ZXJFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNZXJnZWQgcGF0aAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbWJpbmVSZWxhdGl2ZVBhdGhXaXRoQmFzZVBhdGgoJHJlbGF0aXZlUGF0aCwgJGJhc2VQYXRoKQogICAgewogICAgICAgICRyZWxhdGl2ZVBhdGggPSBzZWxmOjpub3JtYWxpemVQYXRoKCRyZWxhdGl2ZVBhdGgpOwogICAgICAgIGlmICgkcmVsYXRpdmVQYXRoID09ICcnKSB7CiAgICAgICAgICAgIHJldHVybiAkYmFzZVBhdGg7CiAgICAgICAgfQogICAgICAgIGlmICgkcmVsYXRpdmVQYXRoWzBdID09ICcvJykgewogICAgICAgICAgICByZXR1cm4gJHJlbGF0aXZlUGF0aDsKICAgICAgICB9CgogICAgICAgICRiYXNlUGF0aFNlZ21lbnRzID0gZXhwbG9kZSgnLycsICRiYXNlUGF0aCk7CgogICAgICAgIHByZWdfbWF0Y2goJ3xeLz8oXC5cLi8oPzpcLi8pKikqfCcsICRyZWxhdGl2ZVBhdGgsICRtYXRjaCk7CiAgICAgICAgJG51bUxldmVsVXAgPSBzdHJsZW4oJG1hdGNoWzBdKSAvMyArIDE7CiAgICAgICAgaWYgKCRudW1MZXZlbFVwID49IGNvdW50KCRiYXNlUGF0aFNlZ21lbnRzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVXJpUmVzb2x2ZXJFeGNlcHRpb24oc3ByaW50ZigiVW5hYmxlIHRvIHJlc29sdmUgVVJJICclcycgZnJvbSBiYXNlICclcyciLCAkcmVsYXRpdmVQYXRoLCAkYmFzZVBhdGgpKTsKICAgICAgICB9CgogICAgICAgICRiYXNlUGF0aFNlZ21lbnRzID0gYXJyYXlfc2xpY2UoJGJhc2VQYXRoU2VnbWVudHMsIDAsIC0kbnVtTGV2ZWxVcCk7CiAgICAgICAgJHBhdGggPSBwcmVnX3JlcGxhY2UoJ3xeLz8oXC5cLi8oXC4vKSopKnwnLCAnJywgJHJlbGF0aXZlUGF0aCk7CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcvJywgJGJhc2VQYXRoU2VnbWVudHMpIC4gJy8nIC4gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWxpemVzIGEgVVJJIHBhdGggY29tcG9uZW50IGJ5IHJlbW92aW5nIGRvdC1zbGFzaCBhbmQgZG91YmxlIHNsYXNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gbm9ybWFsaXplUGF0aCgkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9IHByZWdfcmVwbGFjZSgnfCgoPzwhXC4pXC4vKSp8JywgJycsICRwYXRoKTsKICAgICAgICAkcGF0aCA9IHByZWdfcmVwbGFjZSgnfC8vfCcsICcvJywgJHBhdGgpOwoKICAgICAgICByZXR1cm4gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmFsaWQoJHVyaSkKICAgIHsKICAgICAgICAkY29tcG9uZW50cyA9ICR0aGlzLT5wYXJzZSgkdXJpKTsKCiAgICAgICAgcmV0dXJuICFlbXB0eSgkY29tcG9uZW50cyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXFVyaTsKCnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkU2NoZW1hTWVkaWFUeXBlRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cSnNvbkRlY29kaW5nRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnNcRmlsZUdldENvbnRlbnRzOwp1c2UgSnNvblNjaGVtYVxVcmlcUmV0cmlldmVyc1xVcmlSZXRyaWV2ZXJJbnRlcmZhY2U7CnVzZSBKc29uU2NoZW1hXFVyaVJldHJpZXZlckludGVyZmFjZSBhcyBCYXNlVXJpUmV0cmlldmVySW50ZXJmYWNlOwp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CgovKioKICogUmV0cmlldmVzIEpTT04gU2NoZW1hIFVSSXMKICoKICogQGF1dGhvciBUeWxlciBBa2lucyA8ZmlkaWFuQHJ1bWtpbi5jb20+CiAqLwpjbGFzcyBVcmlSZXRyaWV2ZXIgaW1wbGVtZW50cyBCYXNlVXJpUmV0cmlldmVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBhcnJheSBNYXAgb2YgVVJMIHRyYW5zbGF0aW9ucwogICAgICovCiAgICBwcm90ZWN0ZWQgJHRyYW5zbGF0aW9uTWFwID0gYXJyYXkoCiAgICAgICAgLy8gdXNlIGxvY2FsIGNvcGllcyBvZiB0aGUgc3BlYyBzY2hlbWFzCiAgICAgICAgJ3xeaHR0cHM/Oi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LSgwWzM0XSkvc2NoZW1hIz98JyA9PiAncGFja2FnZTovL2Rpc3Qvc2NoZW1hL2pzb24tc2NoZW1hLWRyYWZ0LSQxLmpzb24nCiAgICApOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheSBBIGxpc3Qgb2YgZW5kcG9pbnRzIGZvciBtZWRpYSB0eXBlIGNoZWNrIGV4Y2x1c2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGFsbG93ZWRJbnZhbGlkQ29udGVudFR5cGVFbmRwb2ludHMgPSBhcnJheSgKICAgICAgICAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy8nLAogICAgICAgICdodHRwczovL2pzb24tc2NoZW1hLm9yZy8nCiAgICApOwoKICAgIC8qKgogICAgICogQHZhciBudWxsfFVyaVJldHJpZXZlckludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHVyaVJldHJpZXZlciA9IG51bGw7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5fG9iamVjdFtdCiAgICAgKgogICAgICogQHNlZSBsb2FkU2NoZW1hCiAgICAgKi8KICAgIHByaXZhdGUgJHNjaGVtYUNhY2hlID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEFkZHMgYW4gZW5kcG9pbnQgdG8gdGhlIG1lZGlhIHR5cGUgdmFsaWRhdGlvbiBleGNsdXNpb24gbGlzdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGVuZHBvaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRJbnZhbGlkQ29udGVudFR5cGVFbmRwb2ludCgkZW5kcG9pbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFsbG93ZWRJbnZhbGlkQ29udGVudFR5cGVFbmRwb2ludHNbXSA9ICRlbmRwb2ludDsKICAgIH0KCiAgICAvKioKICAgICAqIEd1YXJhbnRlZSB0aGUgY29ycmVjdCBtZWRpYSB0eXBlIHdhcyBlbmNvdW50ZXJlZAogICAgICoKICAgICAqIEBwYXJhbSBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UgJHVyaVJldHJpZXZlcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAkdXJpCiAgICAgKgogICAgICogQHJldHVybiBib29sfHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbmZpcm1NZWRpYVR5cGUoJHVyaVJldHJpZXZlciwgJHVyaSkKICAgIHsKICAgICAgICAkY29udGVudFR5cGUgPSAkdXJpUmV0cmlldmVyLT5nZXRDb250ZW50VHlwZSgpOwoKICAgICAgICBpZiAoaXNfbnVsbCgkY29udGVudFR5cGUpKSB7CiAgICAgICAgICAgIC8vIFdlbGwsIHdlIGRpZG4ndCBnZXQgYW4gaW52YWxpZCBvbmUKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKGluX2FycmF5KCRjb250ZW50VHlwZSwgYXJyYXkoVmFsaWRhdG9yOjpTQ0hFTUFfTUVESUFfVFlQRSwgJ2FwcGxpY2F0aW9uL2pzb24nKSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFsbG93ZWRJbnZhbGlkQ29udGVudFR5cGVFbmRwb2ludHMgYXMgJGVuZHBvaW50KSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJHVyaSwgJGVuZHBvaW50KSA9PT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBJbnZhbGlkU2NoZW1hTWVkaWFUeXBlRXhjZXB0aW9uKHNwcmludGYoJ01lZGlhIHR5cGUgJXMgZXhwZWN0ZWQnLCBWYWxpZGF0b3I6OlNDSEVNQV9NRURJQV9UWVBFKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBVUkkgUmV0cmlldmVyCiAgICAgKgogICAgICogSWYgbm9uZSBpcyBzcGVjaWZpZWQsIHNldHMgYSBkZWZhdWx0IEZpbGVHZXRDb250ZW50cyByZXRyaWV2ZXIgYW5kCiAgICAgKiByZXR1cm5zIHRoYXQgb2JqZWN0LgogICAgICoKICAgICAqIEByZXR1cm4gVXJpUmV0cmlldmVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmlSZXRyaWV2ZXIoKQogICAgewogICAgICAgIGlmIChpc19udWxsKCR0aGlzLT51cmlSZXRyaWV2ZXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRVcmlSZXRyaWV2ZXIobmV3IEZpbGVHZXRDb250ZW50cygpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dXJpUmV0cmlldmVyOwogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZSBhIHNjaGVtYSBiYXNlZCBvbiBwb2ludGVyCiAgICAgKgogICAgICogVVJJcyBjYW4gaGF2ZSBhIGZyYWdtZW50IGF0IHRoZSBlbmQgaW4gdGhlIGZvcm1hdCBvZgogICAgICogIy9wYXRoL3RvL29iamVjdCBhbmQgd2UgYXJlIHRvIGxvb2sgdXAgdGhlICdwYXRoJyBwcm9wZXJ0eSBvZgogICAgICogdGhlIGZpcnN0IG9iamVjdCB0aGVuIHRoZSAndG8nIGFuZCAnb2JqZWN0JyBwcm9wZXJ0aWVzLgogICAgICoKICAgICAqIEBwYXJhbSBvYmplY3QgJGpzb25TY2hlbWEgSlNPTiBTY2hlbWEgY29udGVudHMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVyaSAgICAgICAgSlNPTiBTY2hlbWEgVVJJCiAgICAgKgogICAgICogQHRocm93cyBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QgSlNPTiBTY2hlbWEgYWZ0ZXIgd2Fsa2luZyBkb3duIHRoZSBmcmFnbWVudCBwaWVjZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVQb2ludGVyKCRqc29uU2NoZW1hLCAkdXJpKQogICAgewogICAgICAgICRyZXNvbHZlciA9IG5ldyBVcmlSZXNvbHZlcigpOwogICAgICAgICRwYXJzZWQgPSAkcmVzb2x2ZXItPnBhcnNlKCR1cmkpOwogICAgICAgIGlmIChlbXB0eSgkcGFyc2VkWydmcmFnbWVudCddKSkgewogICAgICAgICAgICByZXR1cm4gJGpzb25TY2hlbWE7CiAgICAgICAgfQoKICAgICAgICAkcGF0aCA9IGV4cGxvZGUoJy8nLCAkcGFyc2VkWydmcmFnbWVudCddKTsKICAgICAgICB3aGlsZSAoJHBhdGgpIHsKICAgICAgICAgICAgJHBhdGhFbGVtZW50ID0gYXJyYXlfc2hpZnQoJHBhdGgpOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRwYXRoRWxlbWVudCkpIHsKICAgICAgICAgICAgICAgICRwYXRoRWxlbWVudCA9IHN0cl9yZXBsYWNlKCd+MScsICcvJywgJHBhdGhFbGVtZW50KTsKICAgICAgICAgICAgICAgICRwYXRoRWxlbWVudCA9IHN0cl9yZXBsYWNlKCd+MCcsICd+JywgJHBhdGhFbGVtZW50KTsKICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJGpzb25TY2hlbWEtPiRwYXRoRWxlbWVudCkpIHsKICAgICAgICAgICAgICAgICAgICAkanNvblNjaGVtYSA9ICRqc29uU2NoZW1hLT4kcGF0aEVsZW1lbnQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAnRnJhZ21lbnQgIicgLiAkcGFyc2VkWydmcmFnbWVudCddIC4gJyIgbm90IGZvdW5kJwogICAgICAgICAgICAgICAgICAgICAgICAuICcgaW4gJyAuICR1cmkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghaXNfb2JqZWN0KCRqc29uU2NoZW1hKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAnRnJhZ21lbnQgcGFydCAiJyAuICRwYXRoRWxlbWVudCAuICciIGlzIG5vIG9iamVjdCAnCiAgICAgICAgICAgICAgICAgICAgICAgIC4gJyBpbiAnIC4gJHVyaQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkanNvblNjaGVtYTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJldHJpZXZlKCR1cmksICRiYXNlVXJpID0gbnVsbCwgJHRyYW5zbGF0ZSA9IHRydWUpCiAgICB7CiAgICAgICAgJHJlc29sdmVyID0gbmV3IFVyaVJlc29sdmVyKCk7CiAgICAgICAgJHJlc29sdmVkVXJpID0gJGZldGNoVXJpID0gJHJlc29sdmVyLT5yZXNvbHZlKCR1cmksICRiYXNlVXJpKTsKCiAgICAgICAgLy9mZXRjaCBVUkwgd2l0aG91dCAjZnJhZ21lbnQKICAgICAgICAkYXJQYXJ0cyA9ICRyZXNvbHZlci0+cGFyc2UoJHJlc29sdmVkVXJpKTsKICAgICAgICBpZiAoaXNzZXQoJGFyUGFydHNbJ2ZyYWdtZW50J10pKSB7CiAgICAgICAgICAgIHVuc2V0KCRhclBhcnRzWydmcmFnbWVudCddKTsKICAgICAgICAgICAgJGZldGNoVXJpID0gJHJlc29sdmVyLT5nZW5lcmF0ZSgkYXJQYXJ0cyk7CiAgICAgICAgfQoKICAgICAgICAvLyBhcHBseSBVUkkgdHJhbnNsYXRpb25zCiAgICAgICAgaWYgKCR0cmFuc2xhdGUpIHsKICAgICAgICAgICAgJGZldGNoVXJpID0gJHRoaXMtPnRyYW5zbGF0ZSgkZmV0Y2hVcmkpOwogICAgICAgIH0KCiAgICAgICAgJGpzb25TY2hlbWEgPSAkdGhpcy0+bG9hZFNjaGVtYSgkZmV0Y2hVcmkpOwoKICAgICAgICAvLyBVc2UgdGhlIEpTT04gcG9pbnRlciBpZiBzcGVjaWZpZWQKICAgICAgICAkanNvblNjaGVtYSA9ICR0aGlzLT5yZXNvbHZlUG9pbnRlcigkanNvblNjaGVtYSwgJHJlc29sdmVkVXJpKTsKCiAgICAgICAgaWYgKCRqc29uU2NoZW1hIGluc3RhbmNlb2YgXHN0ZENsYXNzKSB7CiAgICAgICAgICAgICRqc29uU2NoZW1hLT5pZCA9ICRyZXNvbHZlZFVyaTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkanNvblNjaGVtYTsKICAgIH0KCiAgICAvKioKICAgICAqIEZldGNoIGEgc2NoZW1hIGZyb20gdGhlIGdpdmVuIFVSSSwganNvbi1kZWNvZGUgaXQgYW5kIHJldHVybiBpdC4KICAgICAqIENhY2hlcyBzY2hlbWEgb2JqZWN0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmZXRjaFVyaSBBYnNvbHV0ZSBVUkkKICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdCBKU09OIHNjaGVtYSBvYmplY3QKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRTY2hlbWEoJGZldGNoVXJpKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+c2NoZW1hQ2FjaGVbJGZldGNoVXJpXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5zY2hlbWFDYWNoZVskZmV0Y2hVcmldOwogICAgICAgIH0KCiAgICAgICAgJHVyaVJldHJpZXZlciA9ICR0aGlzLT5nZXRVcmlSZXRyaWV2ZXIoKTsKICAgICAgICAkY29udGVudHMgPSAkdGhpcy0+dXJpUmV0cmlldmVyLT5yZXRyaWV2ZSgkZmV0Y2hVcmkpOwogICAgICAgICR0aGlzLT5jb25maXJtTWVkaWFUeXBlKCR1cmlSZXRyaWV2ZXIsICRmZXRjaFVyaSk7CiAgICAgICAgJGpzb25TY2hlbWEgPSBqc29uX2RlY29kZSgkY29udGVudHMpOwoKICAgICAgICBpZiAoSlNPTl9FUlJPUl9OT05FIDwgJGVycm9yID0ganNvbl9sYXN0X2Vycm9yKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEpzb25EZWNvZGluZ0V4Y2VwdGlvbigkZXJyb3IpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNjaGVtYUNhY2hlWyRmZXRjaFVyaV0gPSAkanNvblNjaGVtYTsKCiAgICAgICAgcmV0dXJuICRqc29uU2NoZW1hOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBVUkkgUmV0cmlldmVyCiAgICAgKgogICAgICogQHBhcmFtIFVyaVJldHJpZXZlckludGVyZmFjZSAkdXJpUmV0cmlldmVyCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcyBmb3IgY2hhaW5pbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFVyaVJldHJpZXZlcihVcmlSZXRyaWV2ZXJJbnRlcmZhY2UgJHVyaVJldHJpZXZlcikKICAgIHsKICAgICAgICAkdGhpcy0+dXJpUmV0cmlldmVyID0gJHVyaVJldHJpZXZlcjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgVVJJIGludG8gZml2ZSBtYWluIGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZSgkdXJpKQogICAgewogICAgICAgIHByZWdfbWF0Y2goJ3xeKChbXjovPyNdKyk6KT8oLy8oW14vPyNdKikpPyhbXj8jXSopKFw/KFteI10qKSk/KCMoLiopKT98JywgJHVyaSwgJG1hdGNoKTsKCiAgICAgICAgJGNvbXBvbmVudHMgPSBhcnJheSgpOwogICAgICAgIGlmICg1IDwgY291bnQoJG1hdGNoKSkgewogICAgICAgICAgICAkY29tcG9uZW50cyA9ICBhcnJheSgKICAgICAgICAgICAgICAgICdzY2hlbWUnICAgID0+ICRtYXRjaFsyXSwKICAgICAgICAgICAgICAgICdhdXRob3JpdHknID0+ICRtYXRjaFs0XSwKICAgICAgICAgICAgICAgICdwYXRoJyAgICAgID0+ICRtYXRjaFs1XQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKDcgPCBjb3VudCgkbWF0Y2gpKSB7CiAgICAgICAgICAgICRjb21wb25lbnRzWydxdWVyeSddID0gJG1hdGNoWzddOwogICAgICAgIH0KCiAgICAgICAgaWYgKDkgPCBjb3VudCgkbWF0Y2gpKSB7CiAgICAgICAgICAgICRjb21wb25lbnRzWydmcmFnbWVudCddID0gJG1hdGNoWzldOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21wb25lbnRzOwogICAgfQoKICAgIC8qKgogICAgICogQnVpbGRzIGEgVVJJIGJhc2VkIG9uIG4gYXJyYXkgd2l0aCB0aGUgbWFpbiBjb21wb25lbnRzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRjb21wb25lbnRzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdlbmVyYXRlKGFycmF5ICRjb21wb25lbnRzKQogICAgewogICAgICAgICR1cmkgPSAkY29tcG9uZW50c1snc2NoZW1lJ10gLiAnOi8vJwogICAgICAgICAgICAgLiAkY29tcG9uZW50c1snYXV0aG9yaXR5J10KICAgICAgICAgICAgIC4gJGNvbXBvbmVudHNbJ3BhdGgnXTsKCiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3F1ZXJ5JywgJGNvbXBvbmVudHMpKSB7CiAgICAgICAgICAgICR1cmkgLj0gJGNvbXBvbmVudHNbJ3F1ZXJ5J107CiAgICAgICAgfQoKICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygnZnJhZ21lbnQnLCAkY29tcG9uZW50cykpIHsKICAgICAgICAgICAgJHVyaSAuPSAkY29tcG9uZW50c1snZnJhZ21lbnQnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJpOwogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZXMgYSBVUkkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmkgICAgIEFic29sdXRlIG9yIHJlbGF0aXZlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlVXJpIE9wdGlvbmFsIGJhc2UgVVJJCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmUoJHVyaSwgJGJhc2VVcmkgPSBudWxsKQogICAgewogICAgICAgICRjb21wb25lbnRzID0gJHRoaXMtPnBhcnNlKCR1cmkpOwogICAgICAgICRwYXRoID0gJGNvbXBvbmVudHNbJ3BhdGgnXTsKCiAgICAgICAgaWYgKChhcnJheV9rZXlfZXhpc3RzKCdzY2hlbWUnLCAkY29tcG9uZW50cykpICYmICgnaHR0cCcgPT09ICRjb21wb25lbnRzWydzY2hlbWUnXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR1cmk7CiAgICAgICAgfQoKICAgICAgICAkYmFzZUNvbXBvbmVudHMgPSAkdGhpcy0+cGFyc2UoJGJhc2VVcmkpOwogICAgICAgICRiYXNlUGF0aCA9ICRiYXNlQ29tcG9uZW50c1sncGF0aCddOwoKICAgICAgICAkYmFzZUNvbXBvbmVudHNbJ3BhdGgnXSA9IFVyaVJlc29sdmVyOjpjb21iaW5lUmVsYXRpdmVQYXRoV2l0aEJhc2VQYXRoKCRwYXRoLCAkYmFzZVBhdGgpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmdlbmVyYXRlKCRiYXNlQ29tcG9uZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmFsaWQoJHVyaSkKICAgIHsKICAgICAgICAkY29tcG9uZW50cyA9ICR0aGlzLT5wYXJzZSgkdXJpKTsKCiAgICAgICAgcmV0dXJuICFlbXB0eSgkY29tcG9uZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgYSBVUkwgdHJhbnNsYXRpb24gcnVsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhbnNsYXRpb24oJGZyb20sICR0bykKICAgIHsKICAgICAgICAkdGhpcy0+dHJhbnNsYXRpb25NYXBbJGZyb21dID0gJHRvOwogICAgfQoKICAgIC8qKgogICAgICogQXBwbHkgVVJJIHRyYW5zbGF0aW9uIHJ1bGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0cmFuc2xhdGUoJHVyaSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dHJhbnNsYXRpb25NYXAgYXMgJGZyb20gPT4gJHRvKSB7CiAgICAgICAgICAgICR1cmkgPSBwcmVnX3JlcGxhY2UoJGZyb20sICR0bywgJHVyaSk7CiAgICAgICAgfQoKICAgICAgICAvLyB0cmFuc2xhdGUgcmVmZXJlbmNlcyB0byBsb2NhbCBmaWxlcyB3aXRoaW4gdGhlIGpzb24tc2NoZW1hIHBhY2thZ2UKICAgICAgICAkdXJpID0gcHJlZ19yZXBsYWNlKCd8XnBhY2thZ2U6Ly98Jywgc3ByaW50ZignZmlsZTovLyVzLycsIHJlYWxwYXRoKF9fRElSX18gLiAnLy4uLy4uLy4uJykpLCAkdXJpKTsKCiAgICAgICAgcmV0dXJuICR1cmk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzOwoKLyoqCiAqIEludGVyZmFjZSBmb3IgVVJJIHJldHJpZXZlcnMKICoKICogQGF1dGhvciBTYW5kZXIgQ29vbGVuIDxzYW5kZXJAamliYmVyLm5sPgogKi8KaW50ZXJmYWNlIFVyaVJldHJpZXZlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHJpZXZlIGEgc2NoZW1hIGZyb20gdGhlIHNwZWNpZmllZCBVUkkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmkgVVJJIHRoYXQgcmVzb2x2ZXMgdG8gYSBKU09OIHNjaGVtYQogICAgICoKICAgICAqIEB0aHJvd3MgXEpzb25TY2hlbWFcRXhjZXB0aW9uXFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXRyaWV2ZSgkdXJpKTsKCiAgICAvKioKICAgICAqIEdldCBtZWRpYSBjb250ZW50IHR5cGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGVudFR5cGUoKTsKfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnM7Cgp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CgovKioKICogVVJJIHJldHJpZXZlZCBiYXNlZCBvbiBhIHByZWRlZmluZWQgYXJyYXkgb2Ygc2NoZW1hcwogKgogKiBAZXhhbXBsZQogKgogKiAgICAgICRyZXRyaWV2ZXIgPSBuZXcgUHJlZGVmaW5lZEFycmF5KGFycmF5KAogKiAgICAgICAgICAnaHR0cDovL2FjbWUuY29tL3NjaGVtYXMvcGVyc29uIycgID0+ICd7IC4uLiB9JywKICogICAgICAgICAgJ2h0dHA6Ly9hY21lLmNvbS9zY2hlbWFzL2FkZHJlc3MjJyA9PiAneyAuLi4gfScsCiAqICAgICAgKSkKICoKICogICAgICAkc2NoZW1hID0gJHJldHJpZXZlci0+cmV0cmlldmUoJ2h0dHA6Ly9hY21lLmNvbS9zY2hlbWFzL3BlcnNvbiMnKTsKICovCmNsYXNzIFByZWRlZmluZWRBcnJheSBleHRlbmRzIEFic3RyYWN0UmV0cmlldmVyCnsKICAgIC8qKgogICAgICogQ29udGFpbnMgc2NoZW1hcyBhcyBVUkkgPT4gSlNPTgogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSAkc2NoZW1hczsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkc2NoZW1hcwogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudFR5cGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRzY2hlbWFzLCAkY29udGVudFR5cGUgPSBWYWxpZGF0b3I6OlNDSEVNQV9NRURJQV9UWVBFKQogICAgewogICAgICAgICR0aGlzLT5zY2hlbWFzICAgICA9ICRzY2hlbWFzOwogICAgICAgICR0aGlzLT5jb250ZW50VHlwZSA9ICRjb250ZW50VHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzXFVyaVJldHJpZXZlckludGVyZmFjZTo6cmV0cmlldmUoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmV0cmlldmUoJHVyaSkKICAgIHsKICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoJHVyaSwgJHRoaXMtPnNjaGVtYXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSnNvblNjaGVtYVxFeGNlcHRpb25cUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ1RoZSBKU09OIHNjaGVtYSAiJXMiIHdhcyBub3QgZm91bmQuJywKICAgICAgICAgICAgICAgICR1cmkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtYXNbJHVyaV07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzOwoKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXFJlc291cmNlTm90Rm91bmRFeGNlcHRpb247CgovKioKICogVHJpZXMgdG8gcmV0cmlldmUgSlNPTiBzY2hlbWFzIGZyb20gYSBVUkkgdXNpbmcgZmlsZV9nZXRfY29udGVudHMoKQogKgogKiBAYXV0aG9yIFNhbmRlciBDb29sZW4gPHNhbmRlckBqaWJiZXIubmw+CiAqLwpjbGFzcyBGaWxlR2V0Q29udGVudHMgZXh0ZW5kcyBBYnN0cmFjdFJldHJpZXZlcgp7CiAgICBwcm90ZWN0ZWQgJG1lc3NhZ2VCb2R5OwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnNcVXJpUmV0cmlldmVySW50ZXJmYWNlOjpyZXRyaWV2ZSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXRyaWV2ZSgkdXJpKQogICAgewogICAgICAgICRlcnJvck1lc3NhZ2UgPSBudWxsOwogICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKGZ1bmN0aW9uICgkZXJybm8sICRlcnJzdHIpIHVzZSAoJiRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgJGVycm9yTWVzc2FnZSA9ICRlcnJzdHI7CiAgICAgICAgfSk7CiAgICAgICAgJHJlc3BvbnNlID0gZmlsZV9nZXRfY29udGVudHMoJHVyaSk7CiAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgogICAgICAgIGlmICgkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKCRlcnJvck1lc3NhZ2UpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmVzcG9uc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oJ0pTT04gc2NoZW1hIG5vdCBmb3VuZCBhdCAnIC4gJHVyaSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlc3BvbnNlID09ICcnCiAgICAgICAgICAgICYmIHN1YnN0cigkdXJpLCAwLCA3KSA9PSAnZmlsZTovLycgJiYgc3Vic3RyKCR1cmksIC0xKSA9PSAnLycKICAgICAgICApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oJ0pTT04gc2NoZW1hIG5vdCBmb3VuZCBhdCAnIC4gJHVyaSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bWVzc2FnZUJvZHkgPSAkcmVzcG9uc2U7CiAgICAgICAgaWYgKCFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpKSB7CiAgICAgICAgICAgIC8vICRodHRwX3Jlc3BvbnNlX2hlYWRlciBjYW5ub3QgYmUgdGVzdGVkLCBiZWNhdXNlIGl0J3MgZGVmaW5lZCBpbiB0aGUgbWV0aG9kJ3MgbG9jYWwgc2NvcGUKICAgICAgICAgICAgLy8gU2VlIGh0dHA6Ly9waHAubmV0L21hbnVhbC9lbi9yZXNlcnZlZC52YXJpYWJsZXMuaHR0cHJlc3BvbnNlaGVhZGVyLnBocCBmb3IgbW9yZSBpbmZvLgogICAgICAgICAgICAkdGhpcy0+ZmV0Y2hDb250ZW50VHlwZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpOyAvLyBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICAgICAgLy8gQ291bGQgYmUgYSAiZmlsZTovLyIgdXJsIG9yIHNvbWV0aGluZyBlbHNlIC0gZmFrZSB1cCB0aGUgcmVzcG9uc2UKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRUeXBlID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+bWVzc2FnZUJvZHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgSFRUUCBSZXNwb25zZSBIZWFkZXJzCiAgICAgKgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgd2FzIGZvdW5kIG9yIG5vdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZldGNoQ29udGVudFR5cGUoYXJyYXkgJGhlYWRlcnMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICBpZiAoJHRoaXMtPmNvbnRlbnRUeXBlID0gc2VsZjo6Z2V0Q29udGVudFR5cGVNYXRjaEluSGVhZGVyKCRoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkaGVhZGVyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldENvbnRlbnRUeXBlTWF0Y2hJbkhlYWRlcigkaGVhZGVyKQogICAgewogICAgICAgIGlmICgwIDwgcHJlZ19tYXRjaCgiL0NvbnRlbnQtVHlwZTooXFYqKS9pbXMiLCAkaGVhZGVyLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIHJldHVybiB0cmltKCRtYXRjaFsxXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnM7Cgp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVmFsaWRhdG9yOwoKLyoqCiAqIFRyaWVzIHRvIHJldHJpZXZlIEpTT04gc2NoZW1hcyBmcm9tIGEgVVJJIHVzaW5nIGNVUkwgbGlicmFyeQogKgogKiBAYXV0aG9yIFNhbmRlciBDb29sZW4gPHNhbmRlckBqaWJiZXIubmw+CiAqLwpjbGFzcyBDdXJsIGV4dGVuZHMgQWJzdHJhY3RSZXRyaWV2ZXIKewogICAgcHJvdGVjdGVkICRtZXNzYWdlQm9keTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCdjdXJsX2luaXQnKSkgewogICAgICAgICAgICAvLyBDYW5ub3QgdGVzdCB0aGlzLCBiZWNhdXNlIGN1cmxfaW5pdCBpcyBwcmVzZW50IG9uIGFsbCB0ZXN0IHBsYXRmb3JtcyBwbHVzIG1vY2sKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ2NVUkwgbm90IGluc3RhbGxlZCcpOyAvLyBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnNcVXJpUmV0cmlldmVySW50ZXJmYWNlOjpyZXRyaWV2ZSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXRyaWV2ZSgkdXJpKQogICAgewogICAgICAgICRjaCA9IGN1cmxfaW5pdCgpOwoKICAgICAgICBjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfVVJMLCAkdXJpKTsKICAgICAgICBjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfSEVBREVSLCB0cnVlKTsKICAgICAgICBjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsIHRydWUpOwogICAgICAgIGN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9IVFRQSEVBREVSLCBhcnJheSgnQWNjZXB0OiAnIC4gVmFsaWRhdG9yOjpTQ0hFTUFfTUVESUFfVFlQRSkpOwoKICAgICAgICAkcmVzcG9uc2UgPSBjdXJsX2V4ZWMoJGNoKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRyZXNwb25zZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEpzb25TY2hlbWFcRXhjZXB0aW9uXFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oJ0pTT04gc2NoZW1hIG5vdCBmb3VuZCcpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZldGNoTWVzc2FnZUJvZHkoJHJlc3BvbnNlKTsKICAgICAgICAkdGhpcy0+ZmV0Y2hDb250ZW50VHlwZSgkcmVzcG9uc2UpOwoKICAgICAgICBjdXJsX2Nsb3NlKCRjaCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+bWVzc2FnZUJvZHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXNwb25zZSBjVVJMIEhUVFAgcmVzcG9uc2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmZXRjaE1lc3NhZ2VCb2R5KCRyZXNwb25zZSkKICAgIHsKICAgICAgICBwcmVnX21hdGNoKCIvKD86XHJcbil7Mn0oLiopJC9tcyIsICRyZXNwb25zZSwgJG1hdGNoKTsKICAgICAgICAkdGhpcy0+bWVzc2FnZUJvZHkgPSAkbWF0Y2hbMV07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXNwb25zZSBjVVJMIEhUVFAgcmVzcG9uc2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgQ29udGVudC1UeXBlIGhlYWRlciB3YXMgZm91bmQgb3Igbm90CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaENvbnRlbnRUeXBlKCRyZXNwb25zZSkKICAgIHsKICAgICAgICBpZiAoMCA8IHByZWdfbWF0Y2goIi9Db250ZW50LVR5cGU6KFxWKikvaW1zIiwgJHJlc3BvbnNlLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT5jb250ZW50VHlwZSA9IHRyaW0oJG1hdGNoWzFdKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCi8qKgogKiBKc29uU2NoZW1hCiAqCiAqIEBmaWxlc291cmNlCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnM7CgovKioKICogQWJzdHJhY3RSZXRyaWV2ZXIgaW1wbGVtZW50cyB0aGUgZGVmYXVsdCBzaGFyZWQgYmVoYXZpb3IKICogdGhhdCBhbGwgZGVzY2VuZGFudCBSZXRyaWV2ZXJzIHNob3VsZCBpbmhlcml0CiAqCiAqIEBhdXRob3IgU3RldmVuIEdhcmNpYSA8d2Vid2hhbW15QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIEFic3RyYWN0UmV0cmlldmVyIGltcGxlbWVudHMgVXJpUmV0cmlldmVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogTWVkaWEgY29udGVudCB0eXBlCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRjb250ZW50VHlwZTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzXFVyaVJldHJpZXZlckludGVyZmFjZTo6Z2V0Q29udGVudFR5cGUoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGVudFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29udGVudFR5cGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hOwoKdXNlIEpzb25TY2hlbWFcQ29uc3RyYWludHNcQmFzZUNvbnN0cmFpbnQ7CnVzZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzXENvbnN0cmFpbnQ7CgovKioKICogQSBKc29uU2NoZW1hIENvbnN0cmFpbnQKICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgQnJ1bm8gUHJpZXRvIFJlaXMgPGJydW5vLnAucmVpc0BnbWFpbC5jb20+CiAqCiAqIEBzZWUgICAgUkVBRE1FLm1kCiAqLwpjbGFzcyBWYWxpZGF0b3IgZXh0ZW5kcyBCYXNlQ29uc3RyYWludAp7CiAgICBjb25zdCBTQ0hFTUFfTUVESUFfVFlQRSA9ICdhcHBsaWNhdGlvbi9zY2hlbWEranNvbic7CgogICAgY29uc3QgRVJST1JfTk9ORSAgICAgICAgICAgICAgICAgICAgPSAweDAwMDAwMDAwOwogICAgY29uc3QgRVJST1JfQUxMICAgICAgICAgICAgICAgICAgICAgPSAweEZGRkZGRkZGOwogICAgY29uc3QgRVJST1JfRE9DVU1FTlRfVkFMSURBVElPTiAgICAgPSAweDAwMDAwMDAxOwogICAgY29uc3QgRVJST1JfU0NIRU1BX1ZBTElEQVRJT04gICAgICAgPSAweDAwMDAwMDAyOwoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBnaXZlbiBkYXRhIGFnYWluc3QgdGhlIHNjaGVtYSBhbmQgcmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgcmVzdWx0cwogICAgICogQm90aCB0aGUgcGhwIG9iamVjdCBhbmQgdGhlIHNjaGVtYSBhcmUgc3VwcG9zZWQgdG8gYmUgYSByZXN1bHQgb2YgYSBqc29uX2RlY29kZSBjYWxsLgogICAgICogVGhlIHZhbGlkYXRpb24gd29ya3MgYXMgZGVmaW5lZCBieSB0aGUgc2NoZW1hIHByb3Bvc2FsIGluIGh0dHA6Ly9qc29uLXNjaGVtYS5vcmcuCiAgICAgKgogICAgICogTm90ZSB0aGF0IHRoZSBmaXJzdCBhcmd1bWVudCBpcyBwYXNzZWQgYnkgcmVmZXJlbmNlLCBzbyB5b3UgbXVzdCBwYXNzIGluIGEgdmFyaWFibGUuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZSgmJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgJGNoZWNrTW9kZSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gbWFrZSBzdXJlICRzY2hlbWEgaXMgYW4gb2JqZWN0CiAgICAgICAgaWYgKGlzX2FycmF5KCRzY2hlbWEpKSB7CiAgICAgICAgICAgICRzY2hlbWEgPSBzZWxmOjphcnJheVRvT2JqZWN0UmVjdXJzaXZlKCRzY2hlbWEpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2V0IGNoZWNrTW9kZQogICAgICAgICRpbml0aWFsQ2hlY2tNb2RlID0gJHRoaXMtPmZhY3RvcnktPmdldENvbmZpZygpOwogICAgICAgIGlmICgkY2hlY2tNb2RlICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5mYWN0b3J5LT5zZXRDb25maWcoJGNoZWNrTW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBhZGQgcHJvdmlkZWQgc2NoZW1hIHRvIFNjaGVtYVN0b3JhZ2Ugd2l0aCBpbnRlcm5hbCBVUkkgdG8gYWxsb3cgaW50ZXJuYWwgJHJlZiByZXNvbHV0aW9uCiAgICAgICAgaWYgKGlzX29iamVjdCgkc2NoZW1hKSAmJiBwcm9wZXJ0eV9leGlzdHMoJHNjaGVtYSwgJ2lkJykpIHsKICAgICAgICAgICAgJHNjaGVtYVVSSSA9ICRzY2hlbWEtPmlkOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRzY2hlbWFVUkkgPSBTY2hlbWFTdG9yYWdlOjpJTlRFUk5BTF9QUk9WSURFRF9TQ0hFTUFfVVJJOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZmFjdG9yeS0+Z2V0U2NoZW1hU3RvcmFnZSgpLT5hZGRTY2hlbWEoJHNjaGVtYVVSSSwgJHNjaGVtYSk7CgogICAgICAgICR2YWxpZGF0b3IgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ3NjaGVtYScpOwogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKAogICAgICAgICAgICAkdmFsdWUsCiAgICAgICAgICAgICR0aGlzLT5mYWN0b3J5LT5nZXRTY2hlbWFTdG9yYWdlKCktPmdldFNjaGVtYSgkc2NoZW1hVVJJKQogICAgICAgICk7CgogICAgICAgICR0aGlzLT5mYWN0b3J5LT5zZXRDb25maWcoJGluaXRpYWxDaGVja01vZGUpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKGFycmF5X3VuaXF1ZSgkdmFsaWRhdG9yLT5nZXRFcnJvcnMoKSwgU09SVF9SRUdVTEFSKSk7CgogICAgICAgIHJldHVybiAkdmFsaWRhdG9yLT5nZXRFcnJvck1hc2soKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFsaWFzIHRvIHZhbGlkYXRlKCksIHRvIG1haW50YWluIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHdpdGggdGhlIHByZXZpb3VzIEFQSQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJHZhbHVlLCAkc2NoZW1hKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsaWRhdGUoJHZhbHVlLCAkc2NoZW1hKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFsaWFzIHRvIHZhbGlkYXRlKCksIHRvIG1haW50YWluIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHdpdGggdGhlIHByZXZpb3VzIEFQSQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29lcmNlKCYkdmFsdWUsICRzY2hlbWEpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWxpZGF0ZSgkdmFsdWUsICRzY2hlbWEsIENvbnN0cmFpbnQ6OkNIRUNLX01PREVfQ09FUkNFX1RZUEVTKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWE7CgppbnRlcmZhY2UgU2NoZW1hU3RvcmFnZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEFkZHMgc2NoZW1hIHdpdGggZ2l2ZW4gaWRlbnRpZmllcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkCiAgICAgKiBAcGFyYW0gb2JqZWN0ICRzY2hlbWEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFNjaGVtYSgkaWQsICRzY2hlbWEgPSBudWxsKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgc2NoZW1hIGZvciBnaXZlbiBpZGVudGlmaWVyLCBvciBudWxsIGlmIGl0IGRvZXMgbm90IGV4aXN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQKICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2NoZW1hKCRpZCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHNjaGVtYSBmb3IgZ2l2ZW4gcmVmZXJlbmNlIHdpdGggYWxsIHN1Yi1yZWZlcmVuY2VzIHJlc29sdmVkCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVmCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVSZWYoJHJlZik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHNjaGVtYSByZWZlcmVuY2VkIGJ5ICckcmVmJyBwcm9wZXJ0eQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkcmVmU2NoZW1hCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVSZWZTY2hlbWEoJHJlZlNjaGVtYSk7Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0OwoKLyoqCiAqIEludGVyZmFjZSB1c2VkIGJ5IGFsbCB0cmFuc2xhdG9ycy4KICovCmludGVyZmFjZSBUcmFuc2xhdG9ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogUmVnaXN0ZXIgdGhpcyB0cmFuc2xhdG9yIGFzIGdsb2JhbCwgdG8gdXNlIHdpdGggdGhlIGdldHRleHQgZnVuY3Rpb25zIF9fKCksIHBfXygpLCBldGMuCiAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyB0cmFuc2xhdG9yIGlmIGV4aXN0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0b3JJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoKTsKCiAgICAvKioKICAgICAqIE5vb3AsIG1hcmtzIHRoZSBzdHJpbmcgZm9yIHRyYW5zbGF0aW9uIGJ1dCByZXR1cm5zIGl0IHVuY2hhbmdlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub29wKCRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gdXNpbmcgdGhlIG9yaWdpbmFsIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXR0ZXh0KCRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIHBsdXJhbCBmb3JtLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwbHVyYWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5nZXR0ZXh0KCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKCiAgICAvKioKICAgICAqIEdldHMgYSB0cmFuc2xhdGlvbiBjaGVja2luZyB0aGUgZG9tYWluIGFuZCB0aGUgcGx1cmFsIGZvcm0uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICogQHBhcmFtIHN0cmluZyAkcGx1cmFsCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIC8qKgogICAgICogR2V0cyBhIHRyYW5zbGF0aW9uIGNoZWNraW5nIHRoZSBjb250ZXh0IGFuZCB0aGUgcGx1cmFsIGZvcm0uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbnBnZXR0ZXh0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIGNvbnRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGdldHRleHQoJGNvbnRleHQsICRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIGRvbWFpbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkb21haW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRnZXR0ZXh0KCRkb21haW4sICRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIGRvbWFpbiBhbmQgY29udGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkb21haW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRwZ2V0dGV4dCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICAvKioKICAgICAqIEdldHMgYSB0cmFuc2xhdGlvbiBjaGVja2luZyB0aGUgZG9tYWluLCB0aGUgY29udGV4dCBhbmQgdGhlIHBsdXJhbCBmb3JtLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRvbWFpbgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRucGdldHRleHQoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHQ7CgovKioKICogQ2xhc3MgdG8gbWFuYWdlIGEgdHJhbnNsYXRpb24gc3RyaW5nLgogKi8KY2xhc3MgVHJhbnNsYXRpb24KewogICAgcHJvdGVjdGVkICRpZDsKICAgIHByb3RlY3RlZCAkY29udGV4dDsKICAgIHByb3RlY3RlZCAkb3JpZ2luYWw7CiAgICBwcm90ZWN0ZWQgJHRyYW5zbGF0aW9uID0gJyc7CiAgICBwcm90ZWN0ZWQgJHBsdXJhbDsKICAgIHByb3RlY3RlZCAkcGx1cmFsVHJhbnNsYXRpb24gPSBbXTsKICAgIHByb3RlY3RlZCAkcmVmZXJlbmNlcyA9IFtdOwogICAgcHJvdGVjdGVkICRjb21tZW50cyA9IFtdOwogICAgcHJvdGVjdGVkICRleHRyYWN0ZWRDb21tZW50cyA9IFtdOwogICAgcHJvdGVjdGVkICRmbGFncyA9IFtdOwogICAgcHJvdGVjdGVkICRkaXNhYmxlZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIHRoZSBpZCBvZiBhIHRyYW5zbGF0aW9uIChjb250ZXh0ICsgZ2x1ZSArIG9yaWdpbmFsKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVJZCgkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAieyRjb250ZXh0fVwwMDR7JG9yaWdpbmFsfSI7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBUcmFuc2xhdGlvbiBvYmplY3QuCiAgICAgKgogICAgICogVGhpcyBpcyBhIGZhY3RvcnkgbWV0aG9kIHRoYXQgd2lsbCB3b3JrIGV2ZW4gd2hlbiBUcmFuc2xhdGlvbiBpcyBleHRlbmRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0ICBUaGUgY29udGV4dCBvZiB0aGUgdHJhbnNsYXRpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsIFRoZSBvcmlnaW5hbCBzdHJpbmcKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbCAgIFRoZSBvcmlnaW5hbCBwbHVyYWwgc3RyaW5nCiAgICAgKiBAcmV0dXJuIHN0YXRpYyBOZXcgVHJhbnNsYXRpb24gaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGUoJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCA9ICcnKQogICAgewogICAgICAgIHJldHVybiBuZXcgc3RhdGljKCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQgIFRoZSBjb250ZXh0IG9mIHRoZSB0cmFuc2xhdGlvbgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwgVGhlIG9yaWdpbmFsIHN0cmluZwogICAgICogQHBhcmFtIHN0cmluZyAkcGx1cmFsICAgVGhlIG9yaWdpbmFsIHBsdXJhbCBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwgPSAnJykKICAgIHsKICAgICAgICAkdGhpcy0+Y29udGV4dCA9IChzdHJpbmcpICRjb250ZXh0OwogICAgICAgICR0aGlzLT5vcmlnaW5hbCA9IChzdHJpbmcpICRvcmlnaW5hbDsKCiAgICAgICAgJHRoaXMtPnNldFBsdXJhbCgkcGx1cmFsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENsb25lcyB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkY29udGV4dCAgT3B0aW9uYWwgbmV3IGNvbnRleHQKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkb3JpZ2luYWwgT3B0aW9uYWwgbmV3IG9yaWdpbmFsCiAgICAgKgogICAgICogQHJldHVybiBUcmFuc2xhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2xvbmUoJGNvbnRleHQgPSBudWxsLCAkb3JpZ2luYWwgPSBudWxsKQogICAgewogICAgICAgICRuZXcgPSBjbG9uZSAkdGhpczsKCiAgICAgICAgaWYgKCRjb250ZXh0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICRuZXctPmNvbnRleHQgPSAoc3RyaW5nKSAkY29udGV4dDsKICAgICAgICB9CgogICAgICAgIGlmICgkb3JpZ2luYWwgIT09IG51bGwpIHsKICAgICAgICAgICAgJG5ldy0+b3JpZ2luYWwgPSAoc3RyaW5nKSAkb3JpZ2luYWw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5ldzsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlkIG9mIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKiBAd2FybmluZyBUaGUgdXNlIG9mIHRoaXMgZnVuY3Rpb24gdG8gc2V0IGEgY3VzdG9tIElEIHdpbGwgcHJldmVudAogICAgICogIFRyYW5zbGF0aW9uczo6ZmluZCBmcm9tIG1hdGNoaW5nIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElkKCRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICB9CgoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaWQgb2YgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aWQgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHN0YXRpYzo6Z2VuZXJhdGVJZCgkdGhpcy0+Y29udGV4dCwgJHRoaXMtPm9yaWdpbmFsKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSB0cmFuc2xhdGlvbiBtYXRjaGVzIHdpdGggdGhlIGFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXMoJGNvbnRleHQsICRvcmlnaW5hbCA9ICcnKQogICAgewogICAgICAgIHJldHVybiAoKCR0aGlzLT5jb250ZXh0ID09PSAkY29udGV4dCkgJiYgKCR0aGlzLT5vcmlnaW5hbCA9PT0gJG9yaWdpbmFsKSkgPyB0cnVlIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmFibGUgb3IgZGlzYWJsZSB0aGUgdHJhbnNsYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGlzYWJsZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc2FibGVkKCRkaXNhYmxlZCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzYWJsZWQgPSAoYm9vbCkgJGRpc2FibGVkOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHRyYW5zbGF0aW9uIGlzIGRpc2FibGVkCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Rpc2FibGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRpc2FibGVkOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3JpZ2luYWwgc3RyaW5nLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcmlnaW5hbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcmlnaW5hbDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgb3JpZ2luYWwgc3RyaW5nIGlzIGVtcHR5IG9yIG5vdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc09yaWdpbmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gKCR0aGlzLT5vcmlnaW5hbCAhPT0gJycpID8gdHJ1ZSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgdHJhbnNsYXRpb24gc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRyYW5zbGF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFuc2xhdGlvbigkdHJhbnNsYXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPnRyYW5zbGF0aW9uID0gKHN0cmluZykgJHRyYW5zbGF0aW9uOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB0cmFuc2xhdGlvbiBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRyYW5zbGF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRyYW5zbGF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSB0cmFuc2xhdGlvbiBzdHJpbmcgaXMgZW1wdHkgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzVHJhbnNsYXRpb24oKQogICAgewogICAgICAgIHJldHVybiAoJHRoaXMtPnRyYW5zbGF0aW9uICE9PSAnJykgPyB0cnVlIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwbHVyYWwgdHJhbnNsYXRpb24gc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGx1cmFsKCRwbHVyYWwpCiAgICB7CiAgICAgICAgJHRoaXMtPnBsdXJhbCA9IChzdHJpbmcpICRwbHVyYWw7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHBsdXJhbCB0cmFuc2xhdGlvbiBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsdXJhbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wbHVyYWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIHBsdXJhbCB0cmFuc2xhdGlvbiBzdHJpbmcgaXMgZW1wdHkgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGx1cmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gKCR0aGlzLT5wbHVyYWwgIT09ICcnKSA/IHRydWUgOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhIG5ldyBwbHVyYWwgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRwbHVyYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBsdXJhbFRyYW5zbGF0aW9ucyhhcnJheSAkcGx1cmFsKQogICAgewogICAgICAgICR0aGlzLT5wbHVyYWxUcmFuc2xhdGlvbiA9ICRwbHVyYWw7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgYWxsIHBsdXJhbCB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc2l6ZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsdXJhbFRyYW5zbGF0aW9ucygkc2l6ZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRzaXplID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb247CiAgICAgICAgfQoKICAgICAgICAkY3VycmVudCA9IGNvdW50KCR0aGlzLT5wbHVyYWxUcmFuc2xhdGlvbik7CgogICAgICAgIGlmICgkc2l6ZSA+ICRjdXJyZW50KSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb24gKyBhcnJheV9maWxsKDAsICRzaXplLCAnJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHNpemUgPCAkY3VycmVudCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfc2xpY2UoJHRoaXMtPnBsdXJhbFRyYW5zbGF0aW9uLCAwLCAkc2l6ZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnBsdXJhbFRyYW5zbGF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZXJlIGFyZSBhbnkgcGx1cmFsIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjaGVja0NvbnRlbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1BsdXJhbFRyYW5zbGF0aW9ucygkY2hlY2tDb250ZW50ID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRjaGVja0NvbnRlbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGltcGxvZGUoJycsICR0aGlzLT5wbHVyYWxUcmFuc2xhdGlvbikgIT09ICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICFlbXB0eSgkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhbGwgcGx1cmFsIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZVBsdXJhbFRyYW5zbGF0aW9uKCkKICAgIHsKICAgICAgICAkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb24gPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY29udGV4dCBvZiB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb250ZXh0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRleHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGNvbnRleHQgaXMgZW1wdHkgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29udGV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuIChpc3NldCgkdGhpcy0+Y29udGV4dCkgJiYgKCR0aGlzLT5jb250ZXh0ICE9PSAnJykpID8gdHJ1ZSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyByZWZlcmVuY2UgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRmaWxlbmFtZSBUaGUgZmlsZSBwYXRoIHdoZXJlIHRoZSB0cmFuc2xhdGlvbiBoYXMgYmVlbiBmb3VuZAogICAgICogQHBhcmFtIG51bGx8aW50ICRsaW5lICAgICBUaGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIHRyYW5zbGF0aW9uIGhhcyBiZWVuIGZvdW5kCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZWZlcmVuY2UoJGZpbGVuYW1lLCAkbGluZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGtleSA9ICJ7JGZpbGVuYW1lfTp7JGxpbmV9IjsKICAgICAgICAkdGhpcy0+cmVmZXJlbmNlc1ska2V5XSA9IFskZmlsZW5hbWUsICRsaW5lXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSB0cmFuc2xhdGlvbiBoYXMgYW55IHJlZmVyZW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1JlZmVyZW5jZXMoKQogICAgewogICAgICAgIHJldHVybiAhZW1wdHkoJHRoaXMtPnJlZmVyZW5jZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGFsbCByZWZlcmVuY2VzIGZvciB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlZmVyZW5jZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV92YWx1ZXMoJHRoaXMtPnJlZmVyZW5jZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhbGwgcmVmZXJlbmNlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZVJlZmVyZW5jZXMoKQogICAgewogICAgICAgICR0aGlzLT5yZWZlcmVuY2VzID0gW107CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBuZXcgY29tbWVudCBmb3IgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tZW50CiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb21tZW50KCRjb21tZW50KQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJGNvbW1lbnQsICR0aGlzLT5jb21tZW50cywgdHJ1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzW10gPSAkY29tbWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgdHJhbnNsYXRpb24gaGFzIGFueSBjb21tZW50LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29tbWVudHMoKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+Y29tbWVudHNbMF0pOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgY29tbWVudHMgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWVudHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFsbCBjb21tZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUNvbW1lbnRzKCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWVudHMgPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBleHRyYWN0ZWQgY29tbWVudCBmb3IgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tZW50CiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRFeHRyYWN0ZWRDb21tZW50KCRjb21tZW50KQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJGNvbW1lbnQsICR0aGlzLT5leHRyYWN0ZWRDb21tZW50cywgdHJ1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmV4dHJhY3RlZENvbW1lbnRzW10gPSAkY29tbWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgdHJhbnNsYXRpb24gaGFzIGFueSBleHRyYWN0ZWQgY29tbWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0V4dHJhY3RlZENvbW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmV4dHJhY3RlZENvbW1lbnRzWzBdKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIGV4dHJhY3RlZCBjb21tZW50cyBmb3IgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHRyYWN0ZWRDb21tZW50cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0ZWRDb21tZW50czsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgYWxsIGV4dHJhY3RlZCBjb21tZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUV4dHJhY3RlZENvbW1lbnRzKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXh0cmFjdGVkQ29tbWVudHMgPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBmbGFnIGZvciB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZsYWcKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEZsYWcoJGZsYWcpCiAgICB7CiAgICAgICAgaWYgKCFpbl9hcnJheSgkZmxhZywgJHRoaXMtPmZsYWdzLCB0cnVlKSkgewogICAgICAgICAgICAkdGhpcy0+ZmxhZ3NbXSA9ICRmbGFnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSB0cmFuc2xhdGlvbiBoYXMgYW55IGZsYWcuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNGbGFncygpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5mbGFnc1swXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBleHRyYWN0ZWQgZmxhZ3MgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmxhZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmxhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFsbCBmbGFncy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUZsYWdzKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmxhZ3MgPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2VzIHRoaXMgdHJhbnNsYXRpb24gd2l0aCBvdGhlciB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJHRyYW5zbGF0aW9uIFRoZSB0cmFuc2xhdGlvbiB0byBtZXJnZSB3aXRoCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgJG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1lcmdlV2l0aChUcmFuc2xhdGlvbiAkdHJhbnNsYXRpb24sICRvcHRpb25zID0gTWVyZ2U6OkRFRkFVTFRTKQogICAgewogICAgICAgIE1lcmdlOjptZXJnZVRyYW5zbGF0aW9uKCR0cmFuc2xhdGlvbiwgJHRoaXMsICRvcHRpb25zKTsKICAgICAgICBNZXJnZTo6bWVyZ2VSZWZlcmVuY2VzKCR0cmFuc2xhdGlvbiwgJHRoaXMsICRvcHRpb25zKTsKICAgICAgICBNZXJnZTo6bWVyZ2VDb21tZW50cygkdHJhbnNsYXRpb24sICR0aGlzLCAkb3B0aW9ucyk7CiAgICAgICAgTWVyZ2U6Om1lcmdlRXh0cmFjdGVkQ29tbWVudHMoJHRyYW5zbGF0aW9uLCAkdGhpcywgJG9wdGlvbnMpOwogICAgICAgIE1lcmdlOjptZXJnZUZsYWdzKCR0cmFuc2xhdGlvbiwgJHRoaXMsICRvcHRpb25zKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCi8qKgogKiBGdW5jdGlvbiBwYXJzZWQgYnkgUGhwRnVuY3Rpb25zU2Nhbm5lci4KICovCmNsYXNzIFBhcnNlZEZ1bmN0aW9uCnsKICAgIC8qKgogICAgICogVGhlIGZ1bmN0aW9uIG5hbWUuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwoKICAgIC8qKgogICAgICogVGhlIGxpbmUgd2hlcmUgdGhlIGZ1bmN0aW9uIHN0YXJ0cy4KICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxpbmU7CgogICAgLyoqCiAgICAgKiBUaGUgc3RyaW5ncyBleHRyYWN0ZWQgZnJvbSB0aGUgZnVuY3Rpb24gYXJndW1lbnRzLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqLwogICAgcHJvdGVjdGVkICRhcmd1bWVudHM7CgogICAgLyoqCiAgICAgKiBUaGUgY3VycmVudCBpbmRleCBvZiB0aGUgZnVuY3Rpb24gKC0xIGlmIG5vIGFyZ3VtZW50cykuCiAgICAgKgogICAgICogQHZhciBpbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50SW5kZXg7CgogICAgLyoqCiAgICAgKiBTaGFsbCB3ZSBzdG9wIGFkZGluZyBzdHJpbmcgY2h1bmtzIHRvIHRoZSBjdXJyZW50IGFyZ3VtZW50PwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50U3RvcHBlZDsKCiAgICAvKioKICAgICAqIEV4dHJhY3RlZCBjb21tZW50cy4KICAgICAqCiAgICAgKiBAdmFyIFBhcnNlZENvbW1lbnRbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tbWVudHM7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgZnVuY3Rpb24gbmFtZS4KICAgICAqIEBwYXJhbSBpbnQgICAgJGxpbmUgVGhlIGxpbmUgd2hlcmUgdGhlIGZ1bmN0aW9uIHN0YXJ0cy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCAkbGluZSkKICAgIHsKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgICR0aGlzLT5saW5lID0gJGxpbmU7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50cyA9IFtdOwogICAgICAgICR0aGlzLT5hcmd1bWVudEluZGV4ID0gLTE7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50U3RvcHBlZCA9IGZhbHNlOwogICAgICAgICR0aGlzLT5jb21tZW50cyA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9wIGV4dHJhY3Rpbmcgc3RyaW5ncyBmcm9tIHRoZSBjdXJyZW50IGFyZ3VtZW50IChiZWNhdXNlIHdlIGZvdW5kIHNvbWV0aGluZyB0aGF0J3Mgbm90IGEgc3RyaW5nKS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0b3BBcmd1bWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5hcmd1bWVudEluZGV4ID09PSAtMSkgewogICAgICAgICAgICAkdGhpcy0+YXJndW1lbnRJbmRleCA9IDA7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5hcmd1bWVudFN0b3BwZWQgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogR28gdG8gdGhlIG5leHQgYXJndW1lbnQgYmVjYXVzZSB3ZSBhIGNvbW1hIHdhcyBmb3VuZC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5leHRBcmd1bWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5hcmd1bWVudEluZGV4ID09PSAtMSkgewogICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlIG9jY3VyLCBidXQgbGV0J3Mgc3RheSBzYWZlIC0gRHVyaW5nIHRlc3QvZGV2ZWxvcG1lbnQgYW4gRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCiAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudEluZGV4ID0gMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICArKyR0aGlzLT5hcmd1bWVudEluZGV4OwogICAgICAgIH0KICAgICAgICAkdGhpcy0+YXJndW1lbnRTdG9wcGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGQgYSBzdHJpbmcgdG8gdGhlIGN1cnJlbnQgYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjaHVuawogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQXJndW1lbnRDaHVuaygkY2h1bmspCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5hcmd1bWVudFN0b3BwZWQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+YXJndW1lbnRJbmRleCA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudEluZGV4ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmFyZ3VtZW50c1skdGhpcy0+YXJndW1lbnRJbmRleF0pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXJndW1lbnRzWyR0aGlzLT5hcmd1bWVudEluZGV4XSAuPSAkY2h1bms7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXJndW1lbnRzWyR0aGlzLT5hcmd1bWVudEluZGV4XSA9ICRjaHVuazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIGNvbW1lbnQgYXNzb2NpYXRlZCB0byB0aGlzIGZ1bmN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBQYXJzZWRDb21tZW50ICRjb21tZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb21tZW50KCRjb21tZW50KQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMgPT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzID0gW107CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jb21tZW50c1tdID0gJGNvbW1lbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxpbmUgdGhlIGZ1bmN0aW9uIHN0YXJ0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBMaW5lIG51bWJlci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExpbmUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGluZTsKICAgIH0KCiAgICAvKioKICAgICAqIEEgY2xvc2luZyBwYXJlbnRoZXNpcyB3YXMgZm91bmQ6IHJldHVybiB0aGUgZmluYWwgZGF0YS4KICAgICAqIFRoZSBhcnJheSByZXR1cm5lZCBoYXMgdGhlIGZvbGxvd2luZyB2YWx1ZXM6CiAgICAgKiAgMCA9PiBzdHJpbmcgVGhlIGZ1bmN0aW9uIG5hbWUuCiAgICAgKiAgMSA9PiBpbnQgVGhlIGxpbmUgd2hlcmUgdGhlIGZ1bmN0aW9uIHN0YXJ0cy4KICAgICAqICAyID0+IHN0cmluZ1tdIHRoZSBzdHJpbmdzIGV4dHJhY3RlZCBmcm9tIHRoZSBmdW5jdGlvbiBhcmd1bWVudHMuCiAgICAgKiAgMyA9PiBzdHJpbmdbXSB0aGUgY29tbWVudHMgYXNzb2NpYXRlZCB0byB0aGUgZnVuY3Rpb24uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xvc2UoKQogICAgewogICAgICAgICRhcmd1bWVudHMgPSBbXTsKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPD0gJHRoaXMtPmFyZ3VtZW50SW5kZXg7ICsrJGkpIHsKICAgICAgICAgICAgJGFyZ3VtZW50c1skaV0gPSBpc3NldCgkdGhpcy0+YXJndW1lbnRzWyRpXSkgPyAkdGhpcy0+YXJndW1lbnRzWyRpXSA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAkdGhpcy0+bmFtZSwKICAgICAgICAgICAgJHRoaXMtPmxpbmUsCiAgICAgICAgICAgICRhcmd1bWVudHMsCiAgICAgICAgICAgICR0aGlzLT5jb21tZW50cywKICAgICAgICBdOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCnVzZSBFeGNlcHRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCmFic3RyYWN0IGNsYXNzIEZ1bmN0aW9uc1NjYW5uZXIKewogICAgLyoqCiAgICAgKiBTY2FuIGFuZCByZXR1cm5zIHRoZSBmdW5jdGlvbnMgYW5kIHRoZSBhcmd1bWVudHMuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRjb25zdGFudHMgQ29uc3RhbnRzIHVzZWQgaW4gdGhlIGNvZGUgdG8gcmVwbGFjZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGdldEZ1bmN0aW9ucyhhcnJheSAkY29uc3RhbnRzID0gW10pOwoKICAgIC8qKgogICAgICogU2VhcmNoIGZvciBzcGVjaWZpYyBmdW5jdGlvbnMgYW5kIGNyZWF0ZSB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogWW91IGNhbiBwYXNzIG11bHRpcGxlIHRyYW5zbGF0aW9uIHdpdGggZGlmZmVyZW50IGRvbWFpbnMgYW5kIHZhbHVlIGZvdW5kIHdpbGwgYmUgc29ydGVkIHJlc3BlY3RpdmVseS4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zfFRyYW5zbGF0aW9uc1tdICR0cmFuc2xhdGlvbnMgTXVsdGlwbGUgZG9tYWluIHRyYW5zbGF0aW9ucyBpbnN0YW5jZXMgd2hlcmUgdG8gc2F2ZSB0aGUgdmFsdWVzCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgVGhlIGV4dHJhY3RvciBvcHRpb25zCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2F2ZUdldHRleHRGdW5jdGlvbnMoJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRyYW5zbGF0aW9ucyA9IGlzX2FycmF5KCR0cmFuc2xhdGlvbnMpID8gJHRyYW5zbGF0aW9ucyA6IFskdHJhbnNsYXRpb25zXTsKCiAgICAgICAgLyoqIEB2YXIgVHJhbnNsYXRpb25zW10gJHRyYW5zbGF0aW9uQnlEb21haW4gW2RvbWFpbiA9PiB0cmFuc2xhdGlvbnMsIC4uXSAqLwogICAgICAgICR0cmFuc2xhdGlvbkJ5RG9tYWluID0gYXJyYXlfcmVkdWNlKCR0cmFuc2xhdGlvbnMsIGZ1bmN0aW9uICgkY2FycnksIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKSB7CiAgICAgICAgICAgICRjYXJyeVskdHJhbnNsYXRpb25zLT5nZXREb21haW4oKV0gPSAkdHJhbnNsYXRpb25zOwogICAgICAgICAgICByZXR1cm4gJGNhcnJ5OwogICAgICAgIH0sIFtdKTsKCiAgICAgICAgJGZ1bmN0aW9ucyA9ICRvcHRpb25zWydmdW5jdGlvbnMnXTsKICAgICAgICAkZmlsZSA9ICRvcHRpb25zWydmaWxlJ107CgogICAgICAgIC8qKgogICAgICAgICAqIExpc3Qgb2Ygc291cmNlIGNvZGUgY29tbWVudHMgYWxyZWFkeSBhc3NvY2lhdGVkIHdpdGggYSBmdW5jdGlvbi4KICAgICAgICAgKgogICAgICAgICAqIFByZXZlbnRzIGFzc29jaWF0aW5nIHRoZSBzYW1lIGNvbW1lbnQgdG8gbXVsdGlwbGUgZnVuY3Rpb25zLgogICAgICAgICAqCiAgICAgICAgICogQHZhciBQYXJzZWRDb21tZW50W10gJGNvbW1lbnRzQ2FjaGUKICAgICAgICAgKi8KICAgICAgICAkY29tbWVudHNDYWNoZSA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0RnVuY3Rpb25zKCRvcHRpb25zWydjb25zdGFudHMnXSkgYXMgJGZ1bmN0aW9uKSB7CiAgICAgICAgICAgIGxpc3QoJG5hbWUsICRsaW5lLCAkYXJncykgPSAkZnVuY3Rpb247CgogICAgICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2xpbmVPZmZzZXQnXSkpIHsKICAgICAgICAgICAgICAgICRsaW5lICs9ICRvcHRpb25zWydsaW5lT2Zmc2V0J107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJGZ1bmN0aW9uc1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRlY29uc3RydWN0ZWQgPSAkdGhpcy0+ZGVjb25zdHJ1Y3RBcmdzKCRmdW5jdGlvbnNbJG5hbWVdLCAkYXJncyk7CgogICAgICAgICAgICBpZiAoISRkZWNvbnN0cnVjdGVkKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGlzdCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKSA9ICRkZWNvbnN0cnVjdGVkOwoKICAgICAgICAgICAgaWYgKChzdHJpbmcpJG9yaWdpbmFsID09PSAnJykgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpc0RlZmF1bHREb21haW4gPSAkZG9tYWluID09PSBudWxsOwoKICAgICAgICAgICAgJGRvbWFpblRyYW5zbGF0aW9ucyA9IGlzc2V0KCR0cmFuc2xhdGlvbkJ5RG9tYWluWyRkb21haW5dKSA/ICR0cmFuc2xhdGlvbkJ5RG9tYWluWyRkb21haW5dIDogZmFsc2U7CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRvcHRpb25zWydkb21haW5Pbmx5J10pICYmICRpc0RlZmF1bHREb21haW4pIHsKICAgICAgICAgICAgICAgIC8vIElmIHdlIHdhbnQgdG8gZmluZCB0cmFuc2xhdGlvbnMgZm9yIGEgc3BlY2lmaWMgZG9tYWluLCBza2lwIGRlZmF1bHQgZG9tYWluIG1lc3NhZ2VzCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkZG9tYWluVHJhbnNsYXRpb25zKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJGRvbWFpblRyYW5zbGF0aW9ucy0+aW5zZXJ0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwpOwogICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSgkZmlsZSwgJGxpbmUpOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRmdW5jdGlvblszXSkpIHsKICAgICAgICAgICAgICAgIC8qIEB2YXIgUGFyc2VkQ29tbWVudCAkZXh0cmFjdGVkQ29tbWVudCAqLwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGZ1bmN0aW9uWzNdIGFzICRleHRyYWN0ZWRDb21tZW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRleHRyYWN0ZWRDb21tZW50LCAkY29tbWVudHNDYWNoZSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkRXh0cmFjdGVkQ29tbWVudCgkZXh0cmFjdGVkQ29tbWVudC0+Z2V0Q29tbWVudCgpKTsKICAgICAgICAgICAgICAgICAgICAkY29tbWVudHNDYWNoZVtdID0gJGV4dHJhY3RlZENvbW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWNvbnN0cnVjdCBhcmd1bWVudHMgdG8gdHJhbnNsYXRpb24gdmFsdWVzCiAgICAgKgogICAgICogQHBhcmFtICRmdW5jdGlvbgogICAgICogQHBhcmFtICRhcmdzCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZWNvbnN0cnVjdEFyZ3MoJGZ1bmN0aW9uLCAkYXJncykKICAgIHsKICAgICAgICAkZG9tYWluID0gbnVsbDsKICAgICAgICAkY29udGV4dCA9IG51bGw7CiAgICAgICAgJG9yaWdpbmFsID0gbnVsbDsKICAgICAgICAkcGx1cmFsID0gbnVsbDsKCiAgICAgICAgc3dpdGNoICgkZnVuY3Rpb24pIHsKICAgICAgICAgICAgY2FzZSAnbm9vcCc6CiAgICAgICAgICAgIGNhc2UgJ2dldHRleHQnOgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkYXJnc1swXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkb3JpZ2luYWwgPSAkYXJnc1swXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICduZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzFdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJG9yaWdpbmFsLCAkcGx1cmFsKSA9ICRhcmdzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ3BnZXR0ZXh0JzoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGFyZ3NbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbGlzdCgkY29udGV4dCwgJG9yaWdpbmFsKSA9ICRhcmdzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2RnZXR0ZXh0JzoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGFyZ3NbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbGlzdCgkZG9tYWluLCAkb3JpZ2luYWwpID0gJGFyZ3M7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnZHBnZXR0ZXh0JzoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGFyZ3NbMl0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbGlzdCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKSA9ICRhcmdzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ25wZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzJdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCkgPSAkYXJnczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdkbnBnZXR0ZXh0JzoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGFyZ3NbM10pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbGlzdCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKSA9ICRhcmdzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2RuZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzJdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsKSA9ICRhcmdzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHNwcmludGYoJ05vdCB2YWxpZCBmdW5jdGlvbiAlcycsICRmdW5jdGlvbikpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFskZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsXTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7CgpjbGFzcyBKc0Z1bmN0aW9uc1NjYW5uZXIgZXh0ZW5kcyBGdW5jdGlvbnNTY2FubmVyCnsKICAgIHByb3RlY3RlZCAkY29kZTsKICAgIHByb3RlY3RlZCAkc3RhdHVzID0gW107CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb2RlIFRoZSBwaHAgY29kZSB0byBzY2FuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29kZSkKICAgIHsKICAgICAgICAvLyBOb3JtYWxpemUgbmV3bGluZSBjaGFyYWN0ZXJzCiAgICAgICAgJHRoaXMtPmNvZGUgPSBzdHJfcmVwbGFjZShbIlxyXG4iLCAiXG5cciIsICJcciJdLCAiXG4iLCAkY29kZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdW5jdGlvbnMoYXJyYXkgJGNvbnN0YW50cyA9IFtdKQogICAgewogICAgICAgICRsZW5ndGggPSBzdHJsZW4oJHRoaXMtPmNvZGUpOwogICAgICAgICRsaW5lID0gMTsKICAgICAgICAkYnVmZmVyID0gJyc7CiAgICAgICAgJGZ1bmN0aW9ucyA9IFtdOwogICAgICAgICRidWZmZXJGdW5jdGlvbnMgPSBbXTsKICAgICAgICAkY2hhciA9IG51bGw7CgogICAgICAgIGZvciAoJHBvcyA9IDA7ICRwb3MgPCAkbGVuZ3RoOyArKyRwb3MpIHsKICAgICAgICAgICAgJHByZXYgPSAkY2hhcjsKICAgICAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y29kZVskcG9zXTsKICAgICAgICAgICAgJG5leHQgPSBpc3NldCgkdGhpcy0+Y29kZVskcG9zICsgMV0pID8gJHRoaXMtPmNvZGVbJHBvcyArIDFdIDogbnVsbDsKCiAgICAgICAgICAgIHN3aXRjaCAoJGNoYXIpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ1xcJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzaW1wbGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRuZXh0ICE9PSAiJyIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkb3VibGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRuZXh0ICE9PSAnIicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdiYWNrLXRpY2snOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRuZXh0ICE9PSAnYCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcHJldiA9ICRjaGFyOwogICAgICAgICAgICAgICAgICAgICRjaGFyID0gJG5leHQ7CiAgICAgICAgICAgICAgICAgICAgJHBvcysrOwogICAgICAgICAgICAgICAgICAgICRuZXh0ID0gaXNzZXQoJHRoaXMtPmNvZGVbJHBvc10pID8gJHRoaXMtPmNvZGVbJHBvc10gOiBudWxsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgIlxuIjoKICAgICAgICAgICAgICAgICAgICArKyRsaW5lOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnN0YXR1cygnbGluZS1jb21tZW50JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVwU3RhdHVzKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJy8nOgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPnN0YXR1cygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NpbXBsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RvdWJsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2JhY2stdGljayc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2xpbmUtY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Jsb2NrLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwcmV2ID09PSAnKicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXBTdGF0dXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbmV4dCA9PT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRvd25TdGF0dXMoJ2xpbmUtY29tbWVudCcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRuZXh0ID09PSAnKicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZG93blN0YXR1cygnYmxvY2stY29tbWVudCcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgIiciOgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPnN0YXR1cygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NpbXBsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXBTdGF0dXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGluZS1jb21tZW50JzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmxvY2stY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RvdWJsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2JhY2stdGljayc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZG93blN0YXR1cygnc2ltcGxlLXF1b3RlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIic6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZG91YmxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cFN0YXR1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdsaW5lLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdibG9jay1jb21tZW50JzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2ltcGxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmFjay10aWNrJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5kb3duU3RhdHVzKCdkb3VibGUtcXVvdGUnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdgJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdiYWNrLXRpY2snOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVwU3RhdHVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2xpbmUtY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Jsb2NrLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzaW1wbGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkb3VibGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRvd25TdGF0dXMoJ2JhY2stdGljaycpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJygnOgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPnN0YXR1cygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NpbXBsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RvdWJsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2JhY2stdGljayc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2xpbmUtY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Jsb2NrLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRidWZmZXIgJiYgcHJlZ19tYXRjaCgnLyhcdyspJC8nLCAkYnVmZmVyLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZG93blN0YXR1cygnZnVuY3Rpb24nKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRidWZmZXJGdW5jdGlvbnMsIFskbWF0Y2hlc1sxXSwgJGxpbmUsIFtdXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICcnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnKSc6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgkYXJndW1lbnQgPSBzdGF0aWM6OnByZXBhcmVBcmd1bWVudCgkYnVmZmVyKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyRnVuY3Rpb25zWzBdWzJdW10gPSAkYXJndW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkYnVmZmVyRnVuY3Rpb25zKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmdW5jdGlvbnNbXSA9IGFycmF5X3NoaWZ0KCRidWZmZXJGdW5jdGlvbnMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cFN0YXR1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICcnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnLCc6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgkYXJndW1lbnQgPSBzdGF0aWM6OnByZXBhcmVBcmd1bWVudCgkYnVmZmVyKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyRnVuY3Rpb25zWzBdWzJdW10gPSAkYXJndW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICcnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnICc6CiAgICAgICAgICAgICAgICBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZG91YmxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2ltcGxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmFjay10aWNrJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXIgPSAnJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgY2FzZSAnbGluZS1jb21tZW50JzoKICAgICAgICAgICAgICAgIGNhc2UgJ2Jsb2NrLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmdW5jdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBvZiB0aGUgc2Nhbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbnVsbHxzdHJpbmcgJG1hdGNoIFRvIGNoZWNrIHdoZXRoZXIgdGhlIGN1cnJlbnQgc3RhdHVzIGlzIHRoaXMgdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzdGF0dXMoJG1hdGNoID0gbnVsbCkKICAgIHsKICAgICAgICAkc3RhdHVzID0gaXNzZXQoJHRoaXMtPnN0YXR1c1swXSkgPyAkdGhpcy0+c3RhdHVzWzBdIDogbnVsbDsKCiAgICAgICAgaWYgKCRtYXRjaCAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gJHN0YXR1cyA9PT0gJG1hdGNoOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdGF0dXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGQgYSBuZXcgc3RhdHVzIHRvIHRoZSBzdGFjay4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGF0dXMKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvd25TdGF0dXMoJHN0YXR1cykKICAgIHsKICAgICAgICBhcnJheV91bnNoaWZ0KCR0aGlzLT5zdGF0dXMsICRzdGF0dXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhbmQgcmV0dXJuIHRoZSBjdXJyZW50IHN0YXR1cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB1cFN0YXR1cygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X3NoaWZ0KCR0aGlzLT5zdGF0dXMpOwogICAgfQoKICAgIC8qKgogICAgICogUHJlcGFyZXMgdGhlIGFyZ3VtZW50cyBmb3VuZCBpbiBmdW5jdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYXJndW1lbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHByZXBhcmVBcmd1bWVudCgkYXJndW1lbnQpCiAgICB7CiAgICAgICAgaWYgKCRhcmd1bWVudCAmJiBpbl9hcnJheSgkYXJndW1lbnRbMF0sIFsnIicsICInIiwgJ2AnXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN0YXRpYzo6Y29udmVydFN0cmluZyhzdWJzdHIoJGFyZ3VtZW50LCAxLCAtMSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERlY29kZXMgYSBzdHJpbmcgd2l0aCBhbiBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gY29udmVydFN0cmluZygkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkdmFsdWUsICdcXCcpID09PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHByZWdfcmVwbGFjZV9jYWxsYmFjaygKICAgICAgICAgICAgJy9cXFwobnxyfHR8dnxlfGZ8InxcXFwpLycsCiAgICAgICAgICAgIGZ1bmN0aW9uICgkbWF0Y2gpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoJG1hdGNoWzFdWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXG4iOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3InOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxyIjsKICAgICAgICAgICAgICAgICAgICBjYXNlICd0JzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcdCI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXHYiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2UnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxlIjsKICAgICAgICAgICAgICAgICAgICBjYXNlICdmJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcZiI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnIic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnIic7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnXFwnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ1xcJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgJHZhbHVlCiAgICAgICAgKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7CgovKioKICogQ29tbWVudCBwYXJzZWQgYnkgUGhwRnVuY3Rpb25zU2Nhbm5lci4KICovCmNsYXNzIFBhcnNlZENvbW1lbnQKewogICAgLyoqCiAgICAgKiBUaGUgY29tbWVudCBpdHNlbGYuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21tZW50OwoKICAgIC8qKgogICAgICogVGhlIGxpbmUgd2hlcmUgdGhlIGNvbW1lbnQgc3RhcnRzLgogICAgICoKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkZmlyc3RMaW5lOwoKICAgIC8qKgogICAgICogVGhlIGxpbmUgd2hlcmUgdGhlIGNvbW1lbnQgZW5kcy4KICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhc3RMaW5lOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbW1lbnQgVGhlIGNvbW1lbnQgaXRzZWxmLgogICAgICogQHBhcmFtIGludCAgICAkZmlyc3RMaW5lIFRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IHN0YXJ0cy4KICAgICAqIEBwYXJhbSBpbnQgICAgJGxhc3RMaW5lIFRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IGVuZHMuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29tbWVudCwgJGZpcnN0TGluZSwgJGxhc3RMaW5lKQogICAgewogICAgICAgICR0aGlzLT5jb21tZW50ID0gJGNvbW1lbnQ7CiAgICAgICAgJHRoaXMtPmZpcnN0TGluZSA9ICRmaXJzdExpbmU7CiAgICAgICAgJHRoaXMtPmxhc3RMaW5lID0gJGxhc3RMaW5lOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIG5ldyBvYmplY3QgZnJvbSByYXcgY29tbWVudCBkYXRhLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIFRoZSBQSFAgY29tbWVudCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lIFRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IHN0YXJ0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0YXRpYyBUaGUgcGFyc2VkIGNvbW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKCR2YWx1ZSwgJGxpbmUpCiAgICB7CiAgICAgICAgJGxhc3RMaW5lID0gJGxpbmUgKyBzdWJzdHJfY291bnQoJHZhbHVlLCAiXG4iKTsKCiAgICAgICAgJGxpbmVzID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkbGluZSkgewogICAgICAgICAgICBpZiAoJycgPT09IHRyaW0oJGxpbmUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxpbmUgPSBsdHJpbSgkbGluZSwgIiMqLyBcdCIpOwogICAgICAgICAgICAkbGluZSA9IHJ0cmltKCRsaW5lLCAiIyovIFx0Iik7CgogICAgICAgICAgICByZXR1cm4gdHJpbSgkbGluZSk7CiAgICAgICAgfSwgZXhwbG9kZSgiXG4iLCAkdmFsdWUpKTsKCiAgICAgICAgLy8gUmVtb3ZlIGVtcHR5IGxpbmVzLgogICAgICAgICRsaW5lcyA9IGFycmF5X2ZpbHRlcigkbGluZXMpOwogICAgICAgICR2YWx1ZSA9IGltcGxvZGUoJyAnLCAkbGluZXMpOwoKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygkdmFsdWUsICRsaW5lLCAkbGFzdExpbmUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IHN0YXJ0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBMaW5lIG51bWJlci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpcnN0TGluZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5maXJzdExpbmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxpbmUgd2hlcmUgdGhlIGNvbW1lbnQgZW5kcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBMaW5lIG51bWJlci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExhc3RMaW5lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhc3RMaW5lOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBhY3R1YWwgY29tbWVudCBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGNvbW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1lbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRoaXMgY29tbWVudCBpcyByZWxhdGVkIHdpdGggYSBnaXZlbiBmdW5jdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFyc2VkRnVuY3Rpb24gJGZ1bmN0aW9uIFRoZSBmdW5jdGlvbiB0byBjaGVjay4KICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBjb21tZW50IGlzIHJlbGF0ZWQgb3Igbm90LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNSZWxhdGVkV2l0aChQYXJzZWRGdW5jdGlvbiAkZnVuY3Rpb24pCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRMYXN0TGluZSgpID09PSAkZnVuY3Rpb24tPmdldExpbmUoKSB8fCAkdGhpcy0+Z2V0TGFzdExpbmUoKSA9PT0gJGZ1bmN0aW9uLT5nZXRMaW5lKCkgLSAxOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciB0aGUgY29tbWVudCBtYXRjaGVzIHRoZSByZXF1aXJlZCBwcmVmaXhlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHByZWZpeGVzIEFuIGFycmF5IG9mIHByZWZpeGVzIHRvIGNoZWNrLgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGNvbW1lbnQgbWF0Y2hlcyB0aGUgcHJlZml4ZXMgb3Igbm90LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2tQcmVmaXhlcyhhcnJheSAkcHJlZml4ZXMpCiAgICB7CiAgICAgICAgaWYgKCcnID09PSAkdGhpcy0+Y29tbWVudCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoZW1wdHkoJHByZWZpeGVzKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRwcmVmaXhlcyBhcyAkcHJlZml4KSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJHRoaXMtPmNvbW1lbnQsICRwcmVmaXgpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCi8qKgogKiBUcmFpdCB1c2VkIGJ5IGFsbCBnZW5lcmF0b3JzIHRoYXQgZXhwb3J0cyB0aGUgdHJhbnNsYXRpb25zIHRvIHBsYWluIGRpY3Rpb25hcnkgKG9yaWdpbmFsID0+IHNpbmd1bGFyLXRyYW5zbGF0aW9uKS4KICovCnRyYWl0IERpY3Rpb25hcnlUcmFpdAp7CiAgICB1c2UgSGVhZGVyc0dlbmVyYXRvclRyYWl0OwogICAgdXNlIEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBwbGFpbiBkaWN0aW9uYXJ5IHdpdGggdGhlIGZvcm1hdCBbb3JpZ2luYWwgPT4gdHJhbnNsYXRpb25dLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkaW5jbHVkZUhlYWRlcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9BcnJheShUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgJGluY2x1ZGVIZWFkZXJzKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IFtdOwoKICAgICAgICBpZiAoJGluY2x1ZGVIZWFkZXJzKSB7CiAgICAgICAgICAgICRtZXNzYWdlc1snJ10gPSBzdGF0aWM6OmdlbmVyYXRlSGVhZGVycygkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlc1skdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCldID0gJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtZXNzYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgdGhlIGVudHJpZXMgZnJvbSBhIGRpY3Rpb25hcnkuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAkbWVzc2FnZXMKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZyb21BcnJheShhcnJheSAkbWVzc2FnZXMsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAkb3JpZ2luYWwgPT4gJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmICgkb3JpZ2luYWwgPT09ICcnKSB7CiAgICAgICAgICAgICAgICBzdGF0aWM6OmV4dHJhY3RIZWFkZXJzKCR0cmFuc2xhdGlvbiwgJHRyYW5zbGF0aW9ucyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KG51bGwsICRvcmlnaW5hbCktPnNldFRyYW5zbGF0aW9uKCR0cmFuc2xhdGlvbik7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCnVzZSBHZXR0ZXh0XEV4dHJhY3RvcnNcUGhwQ29kZTsKCmNsYXNzIFBocEZ1bmN0aW9uc1NjYW5uZXIgZXh0ZW5kcyBGdW5jdGlvbnNTY2FubmVyCnsKICAgIC8qKgogICAgICogUEhQIHRva2VucyBvZiB0aGUgY29kZSB0byBiZSBwYXJzZWQuCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHRva2VuczsKCiAgICAvKioKICAgICAqIElmIG5vdCBmYWxzZSwgY29tbWVudHMgd2lsbCBiZSBleHRyYWN0ZWQuCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8ZmFsc2V8YXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRleHRyYWN0Q29tbWVudHMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEVuYWJsZSBleHRyYWN0aW5nIGNvbW1lbnRzIHRoYXQgc3RhcnQgd2l0aCBhIHRhZyAoaWYgJHRhZyBpcyBlbXB0eSBhbGwgdGhlIGNvbW1lbnRzIHdpbGwgYmUgZXh0cmFjdGVkKS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHRhZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlQ29tbWVudHNFeHRyYWN0aW9uKCR0YWcgPSAnJykKICAgIHsKICAgICAgICAkdGhpcy0+ZXh0cmFjdENvbW1lbnRzID0gJHRhZzsKICAgIH0KCiAgICAvKioKICAgICAqIERpc2FibGUgY29tbWVudHMgZXh0cmFjdGlvbi4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc2FibGVDb21tZW50c0V4dHJhY3Rpb24oKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Q29tbWVudHMgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgVGhlIHBocCBjb2RlIHRvIHNjYW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb2RlKQogICAgewogICAgICAgICR0aGlzLT50b2tlbnMgPSBhcnJheV92YWx1ZXMoCiAgICAgICAgICAgIGFycmF5X2ZpbHRlcigKICAgICAgICAgICAgICAgIHRva2VuX2dldF9hbGwoJGNvZGUpLAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR0b2tlbikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAhaXNfYXJyYXkoJHRva2VuKSB8fCAkdG9rZW5bMF0gIT09IFRfV0hJVEVTUEFDRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdW5jdGlvbnMoYXJyYXkgJGNvbnN0YW50cyA9IFtdKQogICAgewogICAgICAgICRjb3VudCA9IGNvdW50KCR0aGlzLT50b2tlbnMpOwogICAgICAgIC8qIEB2YXIgUGFyc2VkRnVuY3Rpb25bXSAkYnVmZmVyRnVuY3Rpb25zICovCiAgICAgICAgJGJ1ZmZlckZ1bmN0aW9ucyA9IFtdOwogICAgICAgIC8qIEB2YXIgUGFyc2VkQ29tbWVudFtdICRidWZmZXJDb21tZW50cyAqLwogICAgICAgICRidWZmZXJDb21tZW50cyA9IFtdOwogICAgICAgIC8qIEB2YXIgYXJyYXkgJGZ1bmN0aW9ucyAqLwogICAgICAgICRmdW5jdGlvbnMgPSBbXTsKCiAgICAgICAgZm9yICgkayA9IDA7ICRrIDwgJGNvdW50OyArKyRrKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT50b2tlbnNbJGtdOwoKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGJ1ZmZlckZ1bmN0aW9uc1swXSkpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcsJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPm5leHRBcmd1bWVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJyknOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZ1bmN0aW9uc1tdID0gYXJyYXlfc2hpZnQoJGJ1ZmZlckZ1bmN0aW9ucyktPmNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPnN0b3BBcmd1bWVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAoJHZhbHVlWzBdKSB7CiAgICAgICAgICAgICAgICBjYXNlIFRfQ09OU1RBTlRfRU5DQVBTRURfU1RSSU5HOgogICAgICAgICAgICAgICAgICAgIC8vYWRkIGFuIGFyZ3VtZW50IHRvIHRoZSBjdXJyZW50IGZ1bmN0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRidWZmZXJGdW5jdGlvbnNbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZEFyZ3VtZW50Q2h1bmsoUGhwQ29kZTo6Y29udmVydFN0cmluZygkdmFsdWVbMV0pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBUX1NUUklORzoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGJ1ZmZlckZ1bmN0aW9uc1swXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25zdGFudHNbJHZhbHVlWzFdXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZEFyZ3VtZW50Q2h1bmsoJGNvbnN0YW50c1skdmFsdWVbMV1dKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkdmFsdWVbMV0pID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZEFyZ3VtZW50Q2h1bmsobnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlckZ1bmN0aW9uc1swXS0+c3RvcEFyZ3VtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL25ldyBmdW5jdGlvbiBmb3VuZAogICAgICAgICAgICAgICAgICAgIGZvciAoJGogPSAkayArIDE7ICRqIDwgJGNvdW50OyArKyRqKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRuZXh0VG9rZW4gPSAkdGhpcy0+dG9rZW5zWyRqXTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19hcnJheSgkbmV4dFRva2VuKSAmJiAkbmV4dFRva2VuWzBdID09PSBUX0NPTU1FTlQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5leHRUb2tlbiA9PT0gJygnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmV3RnVuY3Rpb24gPSBuZXcgUGFyc2VkRnVuY3Rpb24oJHZhbHVlWzFdLCAkdmFsdWVbMl0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCBjb21tZW50IHRoYXQgd2FzIG9uIHRoZSBsaW5lIGJlZm9yZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYnVmZmVyQ29tbWVudHNbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbW1lbnQgPSAkYnVmZmVyQ29tbWVudHNbMF07CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY29tbWVudC0+aXNSZWxhdGVkV2l0aCgkbmV3RnVuY3Rpb24pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRuZXdGdW5jdGlvbi0+YWRkQ29tbWVudCgkY29tbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGJ1ZmZlckZ1bmN0aW9ucywgJG5ld0Z1bmN0aW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRrID0gJGo7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgVF9DT01NRU5UOgogICAgICAgICAgICAgICAgICAgICRjb21tZW50ID0gJHRoaXMtPnBhcnNlUGhwQ29tbWVudCgkdmFsdWVbMV0sICR2YWx1ZVsyXSk7CgogICAgICAgICAgICAgICAgICAgIGlmICgkY29tbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRidWZmZXJDb21tZW50cywgJGNvbW1lbnQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNvbW1lbnQgaXMgaW5zaWRlIHRoZSBmdW5jdGlvbiBjYWxsLgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGJ1ZmZlckZ1bmN0aW9uc1swXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZENvbW1lbnQoJGNvbW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRidWZmZXJGdW5jdGlvbnNbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPnN0b3BBcmd1bWVudCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmdW5jdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0IHRoZSBhY3R1YWwgdGV4dCBmcm9tIGEgUEhQIGNvbW1lbnQuCiAgICAgKgogICAgICogSWYgc2V0LCBvbmx5IHJldHVybnMgY29tbWVudHMgdGhhdCBtYXRjaCB0aGUgcHJlZml4KGVzKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBUaGUgUEhQIGNvbW1lbnQuCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lIExpbmUgbnVtYmVyLgogICAgICoKICAgICAqIEByZXR1cm4gbnVsbHxQYXJzZWRDb21tZW50IENvbW1lbnQgb3IgbnVsbCBpZiBjb21tZW50IGV4dHJhY3Rpb24gaXMgZGlzYWJsZWQgb3IgaWYgdGhlcmUgaXMgYSBwcmVmaXggbWlzbWF0Y2guCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVBocENvbW1lbnQoJHZhbHVlLCAkbGluZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmV4dHJhY3RDb21tZW50cyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvL3RoaXMgcmV0dXJucyBhIGNvbW1lbnQgb3IgbnVsbAogICAgICAgICRjb21tZW50ID0gUGFyc2VkQ29tbWVudDo6Y3JlYXRlKCR2YWx1ZSwgJGxpbmUpOwoKICAgICAgICAkcHJlZml4ZXMgPSBhcnJheV9maWx0ZXIoKGFycmF5KSAkdGhpcy0+ZXh0cmFjdENvbW1lbnRzKTsKCiAgICAgICAgaWYgKCRjb21tZW50ICYmICRjb21tZW50LT5jaGVja1ByZWZpeGVzKCRwcmVmaXhlcykpIHsKICAgICAgICAgICAgcmV0dXJuICRjb21tZW50OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XFV0aWxzOwoKY2xhc3MgU3RyaW5nUmVhZGVyCnsKICAgIHB1YmxpYyAkcG9zOwogICAgcHVibGljICRzdHI7CiAgICBwdWJsaWMgJHN0cmxlbjsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBUaGUgc3RyaW5nIHRvIHJlYWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzdHIpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0ciA9ICRzdHI7CiAgICAgICAgJHRoaXMtPnN0cmxlbiA9IHN0cmxlbigkdGhpcy0+c3RyKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlYWQgYW5kIHJldHVybnMgYSBwYXJ0IG9mIHRoZSBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkYnl0ZXMgVGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWQoJGJ5dGVzKQogICAgewogICAgICAgICRkYXRhID0gc3Vic3RyKCR0aGlzLT5zdHIsICR0aGlzLT5wb3MsICRieXRlcyk7CgogICAgICAgICR0aGlzLT5zZWVrdG8oJHRoaXMtPnBvcyArICRieXRlcyk7CgogICAgICAgIHJldHVybiAkZGF0YTsKICAgIH0KCiAgICAvKioKICAgICAqIE1vdmUgdGhlIGN1cnNvciB0byBhIHNwZWNpZmljIHBvc2l0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJHBvcyBUaGUgYW1vdW50IG9mIGJ5dGVzIHRvIG1vdmUKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgbmV3IHBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWVrdG8oJHBvcykKICAgIHsKICAgICAgICAkdGhpcy0+cG9zID0gKCR0aGlzLT5zdHJsZW4gPCAkcG9zKSA/ICR0aGlzLT5zdHJsZW4gOiAkcG9zOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnBvczsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgovKioKICogVHJhaXQgdG8gcHJvdmlkZSB0aGUgZnVuY3Rpb25hbGl0eSBvZiBleHRyYWN0aW5nIGhlYWRlcnMuCiAqLwp0cmFpdCBIZWFkZXJzRXh0cmFjdG9yVHJhaXQKewogICAgLyoqCiAgICAgKiBBZGQgdGhlIGhlYWRlcnMgZm91bmQgdG8gdGhlIHRyYW5zbGF0aW9ucyBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICRoZWFkZXJzCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdEhlYWRlcnMoJGhlYWRlcnMsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgICRoZWFkZXJzID0gZXhwbG9kZSgiXG4iLCAkaGVhZGVycyk7CiAgICAgICAgJGN1cnJlbnRIZWFkZXIgPSBudWxsOwoKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkbGluZSkgewogICAgICAgICAgICAkbGluZSA9IHN0YXRpYzo6Y29udmVydFN0cmluZygkbGluZSk7CgogICAgICAgICAgICBpZiAoJGxpbmUgPT09ICcnKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHN0YXRpYzo6aXNIZWFkZXJEZWZpbml0aW9uKCRsaW5lKSkgewogICAgICAgICAgICAgICAgJGhlYWRlciA9IGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJzonLCAkbGluZSwgMikpOwogICAgICAgICAgICAgICAgJGN1cnJlbnRIZWFkZXIgPSAkaGVhZGVyWzBdOwogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+c2V0SGVhZGVyKCRjdXJyZW50SGVhZGVyLCAkaGVhZGVyWzFdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRlbnRyeSA9ICR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcigkY3VycmVudEhlYWRlcik7CiAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoJGN1cnJlbnRIZWFkZXIsICRlbnRyeS4kbGluZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgaXQgaXMgYSBoZWFkZXIgZGVmaW5pdGlvbiBsaW5lLiBVc2VmdWwgZm9yIGRpc3RndWlzaGluZyBiZXR3ZWVuIGhlYWRlciBkZWZpbml0aW9ucwogICAgICogYW5kIHBvc3NpYmxlIGNvbnRpbnVhdGlvbnMgb2YgYSBoZWFkZXIgZW50cnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGluZSBMaW5lIHRvIHBhcnNlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gaXNIZWFkZXJEZWZpbml0aW9uKCRsaW5lKQogICAgewogICAgICAgIHJldHVybiAoYm9vbCkgcHJlZ19tYXRjaCgnL15bXHctXSs6LycsICRsaW5lKTsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZSBhIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29udmVydFN0cmluZygkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgovKioKICogVHJhaXQgdXNlZCBieSBhbGwgZ2VuZXJhdG9ycyB0aGF0IGV4cG9ydHMgdGhlIHRyYW5zbGF0aW9ucyB0byBtdWx0aWRpbWVuc2lvbmFsIGFycmF5cwogKiAoY29udGV4dCA9PiBbb3JpZ2luYWwgPT4gW3RyYW5zbGF0aW9uLCBwbHVyYWwxLCBwbHVyYWxuLi4uXV0pLgogKi8KdHJhaXQgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQKewogICAgdXNlIEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKICAgIHVzZSBIZWFkZXJzRXh0cmFjdG9yVHJhaXQ7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJGluY2x1ZGVIZWFkZXJzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRmb3JjZUFycmF5CiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvQXJyYXkoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsICRpbmNsdWRlSGVhZGVycywgJGZvcmNlQXJyYXkgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcGx1cmFsRm9ybSA9ICR0cmFuc2xhdGlvbnMtPmdldFBsdXJhbEZvcm1zKCk7CiAgICAgICAgJHBsdXJhbFNpemUgPSBpc19hcnJheSgkcGx1cmFsRm9ybSkgPyAoJHBsdXJhbEZvcm1bMF0gLSAxKSA6IG51bGw7CiAgICAgICAgJG1lc3NhZ2VzID0gW107CgogICAgICAgIGlmICgkaW5jbHVkZUhlYWRlcnMpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzWycnXSA9IFsKICAgICAgICAgICAgICAgICcnID0+IFtzdGF0aWM6OmdlbmVyYXRlSGVhZGVycygkdHJhbnNsYXRpb25zKV0sCiAgICAgICAgICAgIF07CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5pc0Rpc2FibGVkKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29udGV4dCA9ICR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpOwogICAgICAgICAgICAkb3JpZ2luYWwgPSAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCk7CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRtZXNzYWdlc1skY29udGV4dF0pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZXNbJGNvbnRleHRdID0gW107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc1BsdXJhbFRyYW5zbGF0aW9ucyh0cnVlKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzWyRjb250ZXh0XVskb3JpZ2luYWxdID0gJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHBsdXJhbFNpemUpOwogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkbWVzc2FnZXNbJGNvbnRleHRdWyRvcmlnaW5hbF0sICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkZm9yY2VBcnJheSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzWyRjb250ZXh0XVskb3JpZ2luYWxdID0gWyR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZXNbJGNvbnRleHRdWyRvcmlnaW5hbF0gPSAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICdkb21haW4nID0+ICR0cmFuc2xhdGlvbnMtPmdldERvbWFpbigpLAogICAgICAgICAgICAncGx1cmFsLWZvcm1zJyA9PiAkdHJhbnNsYXRpb25zLT5nZXRIZWFkZXIoJ1BsdXJhbC1Gb3JtcycpLAogICAgICAgICAgICAnbWVzc2FnZXMnID0+ICRtZXNzYWdlcywKICAgICAgICBdOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCB0aGUgZW50cmllcyBmcm9tIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRtZXNzYWdlcwogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZnJvbUFycmF5KGFycmF5ICRtZXNzYWdlcywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkbWVzc2FnZXNbJ2RvbWFpbiddKSkgewogICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXREb21haW4oJG1lc3NhZ2VzWydkb21haW4nXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRtZXNzYWdlc1sncGx1cmFsLWZvcm1zJ10pKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPnNldEhlYWRlcihUcmFuc2xhdGlvbnM6OkhFQURFUl9QTFVSQUwsICRtZXNzYWdlc1sncGx1cmFsLWZvcm1zJ10pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzWydtZXNzYWdlcyddIGFzICRjb250ZXh0ID0+ICRjb250ZXh0VHJhbnNsYXRpb25zKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb250ZXh0VHJhbnNsYXRpb25zIGFzICRvcmlnaW5hbCA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICgkY29udGV4dCA9PT0gJycgJiYgJG9yaWdpbmFsID09PSAnJykgewogICAgICAgICAgICAgICAgICAgIHN0YXRpYzo6ZXh0cmFjdEhlYWRlcnMoaXNfYXJyYXkoJHZhbHVlKSA/IGFycmF5X3NoaWZ0KCR2YWx1ZSkgOiAkdmFsdWUsICR0cmFuc2xhdGlvbnMpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0VHJhbnNsYXRpb24oYXJyYXlfc2hpZnQoJHZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRUcmFuc2xhdGlvbigkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCi8qCiAqIFRyYWl0IHRvIHByb3ZpZGUgdGhlIGZ1bmN0aW9uYWxpdHkgb2YgcmVhZC93cml0ZSBjc3YuCiAqLwp0cmFpdCBDc3ZUcmFpdAp7CiAgICBwcm90ZWN0ZWQgc3RhdGljICRjc3ZFc2NhcGVDaGFyOwoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciBzdXBwb3J0IHRoZSBlc2NhcGVfY2hhciBhcmd1bWVudCB0byBmZ2V0Y3N2L2ZwdXRjc3Ygb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHNDc3ZFc2NhcGVDaGFyKCkKICAgIHsKICAgICAgICBpZiAoc3RhdGljOjokY3N2RXNjYXBlQ2hhciA9PT0gbnVsbCkgewogICAgICAgICAgICBzdGF0aWM6OiRjc3ZFc2NhcGVDaGFyID0gdmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNS41LjQnKSA+PSAwOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0YXRpYzo6JGNzdkVzY2FwZUNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJGhhbmRsZQogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZnZXRjc3YoJGhhbmRsZSwgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKHN0YXRpYzo6c3VwcG9ydHNDc3ZFc2NhcGVDaGFyKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZnZXRjc3YoJGhhbmRsZSwgMCwgJG9wdGlvbnNbJ2RlbGltaXRlciddLCAkb3B0aW9uc1snZW5jbG9zdXJlJ10sICRvcHRpb25zWydlc2NhcGVfY2hhciddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmZ2V0Y3N2KCRoYW5kbGUsIDAsICRvcHRpb25zWydkZWxpbWl0ZXInXSwgJG9wdGlvbnNbJ2VuY2xvc3VyZSddKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSByZXNvdXJjZSAkaGFuZGxlCiAgICAgKiBAcGFyYW0gYXJyYXkgJGZpZWxkcwogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBib29sfGludAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZwdXRjc3YoJGhhbmRsZSwgJGZpZWxkcywgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKHN0YXRpYzo6c3VwcG9ydHNDc3ZFc2NhcGVDaGFyKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZwdXRjc3YoJGhhbmRsZSwgJGZpZWxkcywgJG9wdGlvbnNbJ2RlbGltaXRlciddLCAkb3B0aW9uc1snZW5jbG9zdXJlJ10sICRvcHRpb25zWydlc2NhcGVfY2hhciddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmcHV0Y3N2KCRoYW5kbGUsICRmaWVsZHMsICRvcHRpb25zWydkZWxpbWl0ZXInXSwgJG9wdGlvbnNbJ2VuY2xvc3VyZSddKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgovKioKICogVHJhaXQgdG8gcHJvdmlkZSB0aGUgZnVuY3Rpb25hbGl0eSBvZiBleHRyYWN0aW5nIGhlYWRlcnMuCiAqLwp0cmFpdCBIZWFkZXJzR2VuZXJhdG9yVHJhaXQKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBoZWFkZXJzIGFzIGEgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVIZWFkZXJzKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgICRoZWFkZXJzID0gJyc7CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJGhlYWRlcnMgLj0gc3ByaW50ZigiJXM6ICVzXG4iLCAkbmFtZSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaGVhZGVyczsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgpjbGFzcyBQaHBBcnJheSBleHRlbmRzIEdlbmVyYXRvciBpbXBsZW1lbnRzIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICB1c2UgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IHRydWUsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRhcnJheSA9IHN0YXRpYzo6Z2VuZXJhdGUoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwoKICAgICAgICByZXR1cm4gJzw/cGhwIHJldHVybiAnLnZhcl9leHBvcnQoJGFycmF5LCB0cnVlKS4nOyc7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZXMgYW4gYXJyYXkgd2l0aCB0aGUgdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZW5lcmF0ZShUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICByZXR1cm4gc3RhdGljOjp0b0FycmF5KCR0cmFuc2xhdGlvbnMsICRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddLCB0cnVlKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcRGljdGlvbmFyeVRyYWl0Owp1c2UgR2V0dGV4dFxVdGlsc1xDc3ZUcmFpdDsKCmNsYXNzIENzdkRpY3Rpb25hcnkgZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgdXNlIERpY3Rpb25hcnlUcmFpdDsKICAgIHVzZSBDc3ZUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdpbmNsdWRlSGVhZGVycycgPT4gZmFsc2UsCiAgICAgICAgJ2RlbGltaXRlcicgPT4gIiwiLAogICAgICAgICdlbmNsb3N1cmUnID0+ICciJywKICAgICAgICAnZXNjYXBlX2NoYXInID0+ICJcXCIKICAgIF07CgogICAgLyoqCiAgICAgKiB7QHBhcmVudERvY30uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKICAgICAgICAkaGFuZGxlID0gZm9wZW4oJ3BocDovL21lbW9yeScsICd3Jyk7CgogICAgICAgIGZvcmVhY2ggKHN0YXRpYzo6dG9BcnJheSgkdHJhbnNsYXRpb25zLCAkb3B0aW9uc1snaW5jbHVkZUhlYWRlcnMnXSkgYXMgJG9yaWdpbmFsID0+ICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBzdGF0aWM6OmZwdXRjc3YoJGhhbmRsZSwgWyRvcmlnaW5hbCwgJHRyYW5zbGF0aW9uXSwgJG9wdGlvbnMpOwogICAgICAgIH0KCiAgICAgICAgcmV3aW5kKCRoYW5kbGUpOwogICAgICAgICRjc3YgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRoYW5kbGUpOwogICAgICAgIGZjbG9zZSgkaGFuZGxlKTsKCiAgICAgICAgcmV0dXJuICRjc3Y7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXERpY3Rpb25hcnlUcmFpdDsKCmNsYXNzIEpzb25EaWN0aW9uYXJ5IGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnanNvbicgPT4gMCwKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IGZhbHNlLAogICAgXTsKCiAgICAvKioKICAgICAqIHtAcGFyZW50RG9jfS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyhUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICByZXR1cm4ganNvbl9lbmNvZGUoc3RhdGljOjp0b0FycmF5KCR0cmFuc2xhdGlvbnMsICRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddKSwgJG9wdGlvbnNbJ2pzb24nXSk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgpjbGFzcyBKZWQgZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnanNvbicgPT4gMCwKICAgIF07CgogICAgLyoqCiAgICAgKiB7QHBhcmVudERvY30uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJGRvbWFpbiA9ICR0cmFuc2xhdGlvbnMtPmdldERvbWFpbigpID86ICdtZXNzYWdlcyc7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgcmV0dXJuIGpzb25fZW5jb2RlKFsKICAgICAgICAgICAgJGRvbWFpbiA9PiBbCiAgICAgICAgICAgICAgICAnJyA9PiBbCiAgICAgICAgICAgICAgICAgICAgJ2RvbWFpbicgPT4gJGRvbWFpbiwKICAgICAgICAgICAgICAgICAgICAnbGFuZycgPT4gJHRyYW5zbGF0aW9ucy0+Z2V0TGFuZ3VhZ2UoKSA/OiAnZW4nLAogICAgICAgICAgICAgICAgICAgICdwbHVyYWwtZm9ybXMnID0+ICR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcignUGx1cmFsLUZvcm1zJykgPzogJ25wbHVyYWxzPTI7IHBsdXJhbD0obiAhPSAxKTsnLAogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgXSArIHN0YXRpYzo6YnVpbGRNZXNzYWdlcygkdHJhbnNsYXRpb25zKSwKICAgICAgICBdLCAkb3B0aW9uc1snanNvbiddKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdlbmVyYXRlcyBhbiBhcnJheSB3aXRoIGFsbCB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGJ1aWxkTWVzc2FnZXMoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgJHBsdXJhbEZvcm0gPSAkdHJhbnNsYXRpb25zLT5nZXRQbHVyYWxGb3JtcygpOwogICAgICAgICRwbHVyYWxTaXplID0gaXNfYXJyYXkoJHBsdXJhbEZvcm0pID8gKCRwbHVyYWxGb3JtWzBdIC0gMSkgOiBudWxsOwogICAgICAgICRtZXNzYWdlcyA9IFtdOwogICAgICAgICRjb250ZXh0X2dsdWUgPSAnXHUwMDA0JzsKCiAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24pIHsKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aXNEaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGtleSA9ICgkdHJhbnNsYXRpb24tPmhhc0NvbnRleHQoKSA/ICR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpLiRjb250ZXh0X2dsdWUgOiAnJykKICAgICAgICAgICAgICAgIC4kdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCk7CgogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5oYXNQbHVyYWxUcmFuc2xhdGlvbnModHJ1ZSkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHBsdXJhbFNpemUpOwogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkbWVzc2FnZSwgJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gWyR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlc1ska2V5XSA9ICRtZXNzYWdlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtZXNzYWdlczsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBET01Eb2N1bWVudDsKCmNsYXNzIFhsaWZmIGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIGNvbnN0IFVOSVRfSURfUkVHRVhQID0gJy9eWExJRkZfVU5JVF9JRDogKC4qKSQvJzsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyhUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkZG9tID0gbmV3IERPTURvY3VtZW50KCcxLjAnLCAndXRmLTgnKTsKICAgICAgICAkZG9tLT5mb3JtYXRPdXRwdXQgPSB0cnVlOwogICAgICAgICR4bGlmZiA9ICRkb20tPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZUVsZW1lbnQoJ3hsaWZmJykpOwogICAgICAgICR4bGlmZi0+c2V0QXR0cmlidXRlKCd4bWxucycsICd1cm46b2FzaXM6bmFtZXM6dGM6eGxpZmY6ZG9jdW1lbnQ6Mi4wJyk7CiAgICAgICAgJHhsaWZmLT5zZXRBdHRyaWJ1dGUoJ3ZlcnNpb24nLCAnMi4wJyk7CiAgICAgICAgJHhsaWZmLT5zZXRBdHRyaWJ1dGUoJ3NyY0xhbmcnLCAkdHJhbnNsYXRpb25zLT5nZXRMYW5ndWFnZSgpKTsKICAgICAgICAkeGxpZmYtPnNldEF0dHJpYnV0ZSgndHJnTGFuZycsICR0cmFuc2xhdGlvbnMtPmdldExhbmd1YWdlKCkpOwogICAgICAgICRmaWxlID0gJHhsaWZmLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVFbGVtZW50KCdmaWxlJykpOwogICAgICAgICRmaWxlLT5zZXRBdHRyaWJ1dGUoJ2lkJywgJHRyYW5zbGF0aW9ucy0+Z2V0RG9tYWluKCkuJy4nLiR0cmFuc2xhdGlvbnMtPmdldExhbmd1YWdlKCkpOwoKICAgICAgICAvL1NhdmUgaGVhZGVycyBhcyBub3RlcwogICAgICAgICRub3RlcyA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ25vdGVzJyk7CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJG5vdGVzLT5hcHBlbmRDaGlsZChzdGF0aWM6OmNyZWF0ZVRleHROb2RlKCRkb20sICdub3RlJywgJHZhbHVlKSktPnNldEF0dHJpYnV0ZSgnaWQnLCAkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG5vdGVzLT5oYXNDaGlsZE5vZGVzKCkpIHsKICAgICAgICAgICAgJGZpbGUtPmFwcGVuZENoaWxkKCRub3Rlcyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICAvL0ZpbmQgYW4gWExJRkYgdW5pdCBJRCwgaWYgb25lIGlzIGF2YWlsYWJsZTsgb3RoZXJ3aXNlIGdlbmVyYXRlCiAgICAgICAgICAgICR1bml0SWQgPSBzdGF0aWM6OmdldFVuaXRJRCgkdHJhbnNsYXRpb24pPzptZDUoJHRyYW5zbGF0aW9uLT5nZXRDb250ZXh0KCkuJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpKTsKCiAgICAgICAgICAgICR1bml0ID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgndW5pdCcpOwogICAgICAgICAgICAkdW5pdC0+c2V0QXR0cmlidXRlKCdpZCcsICR1bml0SWQpOwoKICAgICAgICAgICAgLy9TYXZlIGNvbW1lbnRzIGFzIG5vdGVzCiAgICAgICAgICAgICRub3RlcyA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ25vdGVzJyk7CgogICAgICAgICAgICAkbm90ZXMtPmFwcGVuZENoaWxkKHN0YXRpYzo6Y3JlYXRlVGV4dE5vZGUoJGRvbSwgJ25vdGUnLCAkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKSkpCiAgICAgICAgICAgICAgICAtPnNldEF0dHJpYnV0ZSgnY2F0ZWdvcnknLCAnY29udGV4dCcpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9uLT5nZXRDb21tZW50cygpIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAvL1NraXAgWExJRkYgdW5pdCBJRCBjb21tZW50cy4KICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKHN0YXRpYzo6VU5JVF9JRF9SRUdFWFAsICRjb21tZW50KSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRub3Rlcy0+YXBwZW5kQ2hpbGQoc3RhdGljOjpjcmVhdGVUZXh0Tm9kZSgkZG9tLCAnbm90ZScsICRjb21tZW50KSkKICAgICAgICAgICAgICAgICAgICAtPnNldEF0dHJpYnV0ZSgnY2F0ZWdvcnknLCAnY29tbWVudCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldEV4dHJhY3RlZENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICRub3Rlcy0+YXBwZW5kQ2hpbGQoc3RhdGljOjpjcmVhdGVUZXh0Tm9kZSgkZG9tLCAnbm90ZScsICRjb21tZW50KSkKICAgICAgICAgICAgICAgICAgICAtPnNldEF0dHJpYnV0ZSgnY2F0ZWdvcnknLCAnZXh0cmFjdGVkLWNvbW1lbnQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9uLT5nZXRGbGFncygpIGFzICRmbGFnKSB7CiAgICAgICAgICAgICAgICAkbm90ZXMtPmFwcGVuZENoaWxkKHN0YXRpYzo6Y3JlYXRlVGV4dE5vZGUoJGRvbSwgJ25vdGUnLCAkZmxhZykpCiAgICAgICAgICAgICAgICAgICAgLT5zZXRBdHRyaWJ1dGUoJ2NhdGVnb3J5JywgJ2ZsYWcnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9uLT5nZXRSZWZlcmVuY2VzKCkgYXMgJHJlZmVyZW5jZSkgewogICAgICAgICAgICAgICAgJG5vdGVzLT5hcHBlbmRDaGlsZChzdGF0aWM6OmNyZWF0ZVRleHROb2RlKCRkb20sICdub3RlJywgJHJlZmVyZW5jZVswXS4nOicuJHJlZmVyZW5jZVsxXSkpCiAgICAgICAgICAgICAgICAgICAgLT5zZXRBdHRyaWJ1dGUoJ2NhdGVnb3J5JywgJ3JlZmVyZW5jZScpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdW5pdC0+YXBwZW5kQ2hpbGQoJG5vdGVzKTsKCiAgICAgICAgICAgICRzZWdtZW50ID0gJHVuaXQtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZUVsZW1lbnQoJ3NlZ21lbnQnKSk7CiAgICAgICAgICAgICRzZWdtZW50LT5hcHBlbmRDaGlsZChzdGF0aWM6OmNyZWF0ZVRleHROb2RlKCRkb20sICdzb3VyY2UnLCAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCkpKTsKICAgICAgICAgICAgJHNlZ21lbnQtPmFwcGVuZENoaWxkKHN0YXRpYzo6Y3JlYXRlVGV4dE5vZGUoJGRvbSwgJ3RhcmdldCcsICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSkpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWxUcmFuc2xhdGlvbnMoKSBhcyAkcGx1cmFsKSB7CiAgICAgICAgICAgICAgICBpZiAoJHBsdXJhbCAhPT0gJycpIHsKICAgICAgICAgICAgICAgICAgICAkc2VnbWVudC0+YXBwZW5kQ2hpbGQoc3RhdGljOjpjcmVhdGVUZXh0Tm9kZSgkZG9tLCAndGFyZ2V0JywgJHBsdXJhbCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkZmlsZS0+YXBwZW5kQ2hpbGQoJHVuaXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkb20tPnNhdmVYTUwoKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZVRleHROb2RlKERPTURvY3VtZW50ICRkb20sICRuYW1lLCAkc3RyaW5nKQogICAgewogICAgICAgICRub2RlID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgkbmFtZSk7CiAgICAgICAgJHRleHQgPSAocHJlZ19tYXRjaCgnL1smPD5dLycsICRzdHJpbmcpID09PSAxKQogICAgICAgICAgICAgPyAkZG9tLT5jcmVhdGVDREFUQVNlY3Rpb24oJHN0cmluZykKICAgICAgICAgICAgIDogJGRvbS0+Y3JlYXRlVGV4dE5vZGUoJHN0cmluZyk7CiAgICAgICAgJG5vZGUtPmFwcGVuZENoaWxkKCR0ZXh0KTsKCiAgICAgICAgcmV0dXJuICRub2RlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdHJhbnNsYXRpb24ncyB1bml0IElELCBpZiBvbmUgaXMgYXZhaWxhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdHJhbnNsYXRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VW5pdElEKFRyYW5zbGF0aW9uICR0cmFuc2xhdGlvbikKICAgIHsKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goc3RhdGljOjpVTklUX0lEX1JFR0VYUCwgJGNvbW1lbnQsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxHZW5lcmF0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKaW50ZXJmYWNlIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFNhdmVzIHRoZSB0cmFuc2xhdGlvbnMgaW4gYSBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkZmlsZQogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvRmlsZShUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgJGZpbGUsIGFycmF5ICRvcHRpb25zID0gW10pOwoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGEgc3RyaW5nIHdpdGggdGhlIHRyYW5zbGF0aW9ucyByZWFkeSB0byBzYXZlIGluIGEgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgJG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcSGVhZGVyc0dlbmVyYXRvclRyYWl0OwoKY2xhc3MgTW8gZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgdXNlIEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdpbmNsdWRlSGVhZGVycycgPT4gdHJ1ZSwKICAgIF07CgogICAgLyoqCiAgICAgKiB7QHBhcmVudERvY30uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKICAgICAgICAkbWVzc2FnZXMgPSBbXTsKCiAgICAgICAgaWYgKCRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddKSB7CiAgICAgICAgICAgICRtZXNzYWdlc1snJ10gPSBzdGF0aWM6OmdlbmVyYXRlSGVhZGVycygkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmICghJHRyYW5zbGF0aW9uLT5oYXNUcmFuc2xhdGlvbigpIHx8ICR0cmFuc2xhdGlvbi0+aXNEaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzQ29udGV4dCgpKSB7CiAgICAgICAgICAgICAgICAkb3JpZ2luYWxTdHJpbmcgPSAkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKS4iXHgwNCIuJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG9yaWdpbmFsU3RyaW5nID0gJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWVzc2FnZXNbJG9yaWdpbmFsU3RyaW5nXSA9ICR0cmFuc2xhdGlvbjsKICAgICAgICB9CgogICAgICAgIGtzb3J0KCRtZXNzYWdlcyk7CiAgICAgICAgJG51bUVudHJpZXMgPSBjb3VudCgkbWVzc2FnZXMpOwogICAgICAgICRvcmlnaW5hbHNUYWJsZSA9ICcnOwogICAgICAgICR0cmFuc2xhdGlvbnNUYWJsZSA9ICcnOwogICAgICAgICRvcmlnaW5hbHNJbmRleCA9IFtdOwogICAgICAgICR0cmFuc2xhdGlvbnNJbmRleCA9IFtdOwogICAgICAgICRwbHVyYWxGb3JtID0gJHRyYW5zbGF0aW9ucy0+Z2V0UGx1cmFsRm9ybXMoKTsKICAgICAgICAkcGx1cmFsU2l6ZSA9IGlzX2FycmF5KCRwbHVyYWxGb3JtKSA/ICgkcGx1cmFsRm9ybVswXSAtIDEpIDogbnVsbDsKCiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzIGFzICRvcmlnaW5hbFN0cmluZyA9PiAkdHJhbnNsYXRpb24pIHsKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdHJhbnNsYXRpb24pKSB7CiAgICAgICAgICAgICAgICAvLyBIZWFkZXJzCiAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25TdHJpbmcgPSAkdHJhbnNsYXRpb247CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBAdmFyICR0cmFuc2xhdGlvbiBcR2V0dGV4dFxUcmFuc2xhdGlvbiAqLwogICAgICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsKCkgJiYgJHRyYW5zbGF0aW9uLT5oYXNQbHVyYWxUcmFuc2xhdGlvbnModHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAkb3JpZ2luYWxTdHJpbmcgLj0gIlx4MDAiLiR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsKCk7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uU3RyaW5nID0gJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpOwogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvblN0cmluZyAuPSAiXHgwMCIuaW1wbG9kZSgiXHgwMCIsICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCRwbHVyYWxTaXplKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvblN0cmluZyA9ICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG9yaWdpbmFsc0luZGV4W10gPSBbCiAgICAgICAgICAgICAgICAncmVsYXRpdmVPZmZzZXQnID0+IHN0cmxlbigkb3JpZ2luYWxzVGFibGUpLAogICAgICAgICAgICAgICAgJ2xlbmd0aCcgPT4gc3RybGVuKCRvcmlnaW5hbFN0cmluZykKICAgICAgICAgICAgXTsKICAgICAgICAgICAgJG9yaWdpbmFsc1RhYmxlIC49ICRvcmlnaW5hbFN0cmluZy4iXHgwMCI7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnNJbmRleFtdID0gWwogICAgICAgICAgICAgICAgJ3JlbGF0aXZlT2Zmc2V0JyA9PiBzdHJsZW4oJHRyYW5zbGF0aW9uc1RhYmxlKSwKICAgICAgICAgICAgICAgICdsZW5ndGgnID0+IHN0cmxlbigkdHJhbnNsYXRpb25TdHJpbmcpCiAgICAgICAgICAgIF07CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnNUYWJsZSAuPSAkdHJhbnNsYXRpb25TdHJpbmcuIlx4MDAiOwogICAgICAgIH0KCiAgICAgICAgLy8gT2Zmc2V0IG9mIHRhYmxlIHdpdGggdGhlIG9yaWdpbmFsIHN0cmluZ3MgaW5kZXg6IHJpZ2h0IGFmdGVyIHRoZSBoZWFkZXIgKHdoaWNoIGlzIDcgd29yZHMpCiAgICAgICAgJG9yaWdpbmFsc0luZGV4T2Zmc2V0ID0gNyAqIDQ7CgogICAgICAgIC8vIFNpemUgb2YgdGFibGUgd2l0aCB0aGUgb3JpZ2luYWwgc3RyaW5ncyBpbmRleAogICAgICAgICRvcmlnaW5hbHNJbmRleFNpemUgPSAkbnVtRW50cmllcyAqICg0ICsgNCk7CgogICAgICAgIC8vIE9mZnNldCBvZiB0YWJsZSB3aXRoIHRoZSB0cmFuc2xhdGlvbiBzdHJpbmdzIGluZGV4OiByaWdodCBhZnRlciB0aGUgb3JpZ2luYWwgc3RyaW5ncyBpbmRleCB0YWJsZQogICAgICAgICR0cmFuc2xhdGlvbnNJbmRleE9mZnNldCA9ICRvcmlnaW5hbHNJbmRleE9mZnNldCArICRvcmlnaW5hbHNJbmRleFNpemU7CgogICAgICAgIC8vIFNpemUgb2YgdGFibGUgd2l0aCB0aGUgdHJhbnNsYXRpb24gc3RyaW5ncyBpbmRleAogICAgICAgICR0cmFuc2xhdGlvbnNJbmRleFNpemUgPSAkbnVtRW50cmllcyAqICg0ICsgNCk7CgogICAgICAgIC8vIEhhc2hpbmcgdGFibGUgc3RhcnRzIGFmdGVyIHRoZSBoZWFkZXIgYW5kIGFmdGVyIHRoZSBpbmRleCB0YWJsZQogICAgICAgICRvcmlnaW5hbHNTdHJpbmdzT2Zmc2V0ID0gJHRyYW5zbGF0aW9uc0luZGV4T2Zmc2V0ICsgJHRyYW5zbGF0aW9uc0luZGV4U2l6ZTsKCiAgICAgICAgLy8gVHJhbnNsYXRpb25zIHN0YXJ0IGFmdGVyIHRoZSBrZXlzCiAgICAgICAgJHRyYW5zbGF0aW9uc1N0cmluZ3NPZmZzZXQgPSAkb3JpZ2luYWxzU3RyaW5nc09mZnNldCArIHN0cmxlbigkb3JpZ2luYWxzVGFibGUpOwoKICAgICAgICAvLyBMZXQncyBnZW5lcmF0ZSB0aGUgLm1vIGZpbGUgYmluYXJ5IGRhdGEKICAgICAgICAkbW8gPSAnJzsKCiAgICAgICAgLy8gTWFnaWMgbnVtYmVyCiAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAweDk1MDQxMmRlKTsKCiAgICAgICAgLy8gRmlsZSBmb3JtYXQgcmV2aXNpb24KICAgICAgICAkbW8gLj0gcGFjaygnTCcsIDApOwoKICAgICAgICAvLyBOdW1iZXIgb2Ygc3RyaW5ncwogICAgICAgICRtbyAuPSBwYWNrKCdMJywgJG51bUVudHJpZXMpOwoKICAgICAgICAvLyBPZmZzZXQgb2YgdGFibGUgd2l0aCBvcmlnaW5hbCBzdHJpbmdzCiAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAkb3JpZ2luYWxzSW5kZXhPZmZzZXQpOwoKICAgICAgICAvLyBPZmZzZXQgb2YgdGFibGUgd2l0aCB0cmFuc2xhdGlvbiBzdHJpbmdzCiAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAkdHJhbnNsYXRpb25zSW5kZXhPZmZzZXQpOwoKICAgICAgICAvLyBTaXplIG9mIGhhc2hpbmcgdGFibGU6IHdlIGRvbid0IHVzZSBpdC4KICAgICAgICAkbW8gLj0gcGFjaygnTCcsIDApOwoKICAgICAgICAvLyBPZmZzZXQgb2YgaGFzaGluZyB0YWJsZTogaXQgd291bGQgc3RhcnQgcmlnaHQgYWZ0ZXIgdGhlIHRyYW5zbGF0aW9ucyBpbmRleCB0YWJsZQogICAgICAgICRtbyAuPSBwYWNrKCdMJywgJHRyYW5zbGF0aW9uc0luZGV4T2Zmc2V0ICsgJHRyYW5zbGF0aW9uc0luZGV4U2l6ZSk7CgogICAgICAgIC8vIFdyaXRlIHRoZSBsZW5ndGhzICYgb2Zmc2V0cyBvZiB0aGUgb3JpZ2luYWwgc3RyaW5ncwogICAgICAgIGZvcmVhY2ggKCRvcmlnaW5hbHNJbmRleCBhcyAkaW5mbykgewogICAgICAgICAgICAkbW8gLj0gcGFjaygnTCcsICRpbmZvWydsZW5ndGgnXSk7CiAgICAgICAgICAgICRtbyAuPSBwYWNrKCdMJywgJG9yaWdpbmFsc1N0cmluZ3NPZmZzZXQgKyAkaW5mb1sncmVsYXRpdmVPZmZzZXQnXSk7CiAgICAgICAgfQoKICAgICAgICAvLyBXcml0ZSB0aGUgbGVuZ3RocyAmIG9mZnNldHMgb2YgdGhlIHRyYW5zbGF0ZWQgc3RyaW5ncwogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnNJbmRleCBhcyAkaW5mbykgewogICAgICAgICAgICAkbW8gLj0gcGFjaygnTCcsICRpbmZvWydsZW5ndGgnXSk7CiAgICAgICAgICAgICRtbyAuPSBwYWNrKCdMJywgJHRyYW5zbGF0aW9uc1N0cmluZ3NPZmZzZXQgKyAkaW5mb1sncmVsYXRpdmVPZmZzZXQnXSk7CiAgICAgICAgfQoKICAgICAgICAvLyBXcml0ZSBvcmlnaW5hbCBzdHJpbmdzCiAgICAgICAgJG1vIC49ICRvcmlnaW5hbHNUYWJsZTsKCiAgICAgICAgLy8gV3JpdGUgdHJhbnNsYXRpb24gc3RyaW5ncwogICAgICAgICRtbyAuPSAkdHJhbnNsYXRpb25zVGFibGU7CgogICAgICAgIHJldHVybiAkbW87CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKdXNlIEdldHRleHRcVXRpbHNcQ3N2VHJhaXQ7CgovKioKICogQ2xhc3MgdG8gZXhwb3J0IHRyYW5zbGF0aW9ucyB0byBjc3YuCiAqLwpjbGFzcyBDc3YgZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgdXNlIEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKICAgIHVzZSBDc3ZUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdpbmNsdWRlSGVhZGVycycgPT4gZmFsc2UsCiAgICAgICAgJ2RlbGltaXRlcicgPT4gIiwiLAogICAgICAgICdlbmNsb3N1cmUnID0+ICciJywKICAgICAgICAnZXNjYXBlX2NoYXInID0+ICJcXCIKICAgIF07CgogICAgLyoqCiAgICAgKiB7QHBhcmVudERvY30uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKICAgICAgICAkaGFuZGxlID0gZm9wZW4oJ3BocDovL21lbW9yeScsICd3Jyk7CgogICAgICAgIGlmICgkb3B0aW9uc1snaW5jbHVkZUhlYWRlcnMnXSkgewogICAgICAgICAgICBzdGF0aWM6OmZwdXRjc3YoJGhhbmRsZSwgWycnLCAnJywgc3RhdGljOjpnZW5lcmF0ZUhlYWRlcnMoJHRyYW5zbGF0aW9ucyldLCAkb3B0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5pc0Rpc2FibGVkKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGluZSA9IFskdHJhbnNsYXRpb24tPmdldENvbnRleHQoKSwgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLCAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCldOwoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsVHJhbnNsYXRpb25zKHRydWUpKSB7CiAgICAgICAgICAgICAgICAkbGluZSA9IGFycmF5X21lcmdlKCRsaW5lLCAkdHJhbnNsYXRpb24tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RhdGljOjpmcHV0Y3N2KCRoYW5kbGUsICRsaW5lLCAkb3B0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICByZXdpbmQoJGhhbmRsZSk7CiAgICAgICAgJGNzdiA9IHN0cmVhbV9nZXRfY29udGVudHMoJGhhbmRsZSk7CiAgICAgICAgZmNsb3NlKCRoYW5kbGUpOwoKICAgICAgICByZXR1cm4gJGNzdjsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgpjbGFzcyBKc29uIGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdqc29uJyA9PiAwLAogICAgICAgICdpbmNsdWRlSGVhZGVycycgPT4gZmFsc2UsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgIHJldHVybiBqc29uX2VuY29kZShzdGF0aWM6OnRvQXJyYXkoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnNbJ2luY2x1ZGVIZWFkZXJzJ10sIHRydWUpLCAkb3B0aW9uc1snanNvbiddKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCmFic3RyYWN0IGNsYXNzIEdlbmVyYXRvciBpbXBsZW1lbnRzIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b0ZpbGUoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsICRmaWxlLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRjb250ZW50ID0gc3RhdGljOjp0b1N0cmluZygkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CgogICAgICAgIGlmIChmaWxlX3B1dF9jb250ZW50cygkZmlsZSwgJGNvbnRlbnQpID09PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcRGljdGlvbmFyeVRyYWl0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcWWFtbFxZYW1sIGFzIFlhbWxEdW1wZXI7CgpjbGFzcyBZYW1sRGljdGlvbmFyeSBleHRlbmRzIEdlbmVyYXRvciBpbXBsZW1lbnRzIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICB1c2UgRGljdGlvbmFyeVRyYWl0OwoKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2luY2x1ZGVIZWFkZXJzJyA9PiBmYWxzZSwKICAgICAgICAnaW5kZW50JyA9PiAyLAogICAgICAgICdpbmxpbmUnID0+IDMsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgIHJldHVybiBZYW1sRHVtcGVyOjpkdW1wKAogICAgICAgICAgICBzdGF0aWM6OnRvQXJyYXkoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnNbJ2luY2x1ZGVIZWFkZXJzJ10pLAogICAgICAgICAgICAkb3B0aW9uc1snaW5saW5lJ10sCiAgICAgICAgICAgICRvcHRpb25zWydpbmRlbnQnXQogICAgICAgICk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXE11bHRpZGltZW5zaW9uYWxBcnJheVRyYWl0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcWWFtbFxZYW1sIGFzIFlhbWxEdW1wZXI7CgpjbGFzcyBZYW1sIGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdpbmNsdWRlSGVhZGVycycgPT4gZmFsc2UsCiAgICAgICAgJ2luZGVudCcgPT4gMiwKICAgICAgICAnaW5saW5lJyA9PiA0LAogICAgXTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyhUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICByZXR1cm4gWWFtbER1bXBlcjo6ZHVtcCgKICAgICAgICAgICAgc3RhdGljOjp0b0FycmF5KCR0cmFuc2xhdGlvbnMsICRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddKSwKICAgICAgICAgICAgJG9wdGlvbnNbJ2lubGluZSddLAogICAgICAgICAgICAkb3B0aW9uc1snaW5kZW50J10KICAgICAgICApOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxHZW5lcmF0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKY2xhc3MgUG8gZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnbm9Mb2NhdGlvbicgPT4gZmFsc2UsCiAgICBdOwoKICAgIC8qKgogICAgICoge0BwYXJlbnREb2N9LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgICRwbHVyYWxGb3JtID0gJHRyYW5zbGF0aW9ucy0+Z2V0UGx1cmFsRm9ybXMoKTsKICAgICAgICAkcGx1cmFsU2l6ZSA9IGlzX2FycmF5KCRwbHVyYWxGb3JtKSA/ICgkcGx1cmFsRm9ybVswXSAtIDEpIDogbnVsbDsKICAgICAgICAkbGluZXMgPSBbJ21zZ2lkICIiJywgJ21zZ3N0ciAiIiddOwoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zLT5nZXRIZWFkZXJzKCkgYXMgJG5hbWUgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgICRsaW5lc1tdID0gc3ByaW50ZignIiVzOiAlc1xcbiInLCAkbmFtZSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgICRsaW5lc1tdID0gJyc7CgogICAgICAgIC8vVHJhbnNsYXRpb25zCiAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24pIHsKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzQ29tbWVudHMoKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9uLT5nZXRDb21tZW50cygpIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmVzW10gPSAnIyAnLiRjb21tZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5oYXNFeHRyYWN0ZWRDb21tZW50cygpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldEV4dHJhY3RlZENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcjLiAnLiRjb21tZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRvcHRpb25zWydub0xvY2F0aW9uJ10gJiYgJHRyYW5zbGF0aW9uLT5oYXNSZWZlcmVuY2VzKCkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbi0+Z2V0UmVmZXJlbmNlcygpIGFzICRyZWZlcmVuY2UpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcjOiAnLiRyZWZlcmVuY2VbMF0uKCFpc19udWxsKCRyZWZlcmVuY2VbMV0pID8gJzonLiRyZWZlcmVuY2VbMV0gOiBudWxsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzRmxhZ3MoKSkgewogICAgICAgICAgICAgICAgJGxpbmVzW10gPSAnIywgJy5pbXBsb2RlKCcsJywgJHRyYW5zbGF0aW9uLT5nZXRGbGFncygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByZWZpeCA9ICR0cmFuc2xhdGlvbi0+aXNEaXNhYmxlZCgpID8gJyN+ICcgOiAnJzsKCiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc0NvbnRleHQoKSkgewogICAgICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4Lidtc2djdHh0ICcuc3RhdGljOjpjb252ZXJ0U3RyaW5nKCR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RhdGljOjphZGRMaW5lcygkbGluZXMsICRwcmVmaXguJ21zZ2lkJywgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpKTsKCiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc1BsdXJhbCgpKSB7CiAgICAgICAgICAgICAgICBzdGF0aWM6OmFkZExpbmVzKCRsaW5lcywgJHByZWZpeC4nbXNnaWRfcGx1cmFsJywgJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWwoKSk7CiAgICAgICAgICAgICAgICBzdGF0aWM6OmFkZExpbmVzKCRsaW5lcywgJHByZWZpeC4nbXNnc3RyWzBdJywgJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygkcGx1cmFsU2l6ZSkgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgICAgICAgICBzdGF0aWM6OmFkZExpbmVzKCRsaW5lcywgJHByZWZpeC4nbXNnc3RyWycuKCRrICsgMSkuJ10nLCAkdik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdGF0aWM6OmFkZExpbmVzKCRsaW5lcywgJHByZWZpeC4nbXNnc3RyJywgJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxpbmVzW10gPSAnJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpbXBsb2RlKCJcbiIsICRsaW5lcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFc2NhcGVzIGFuZCBhZGRzIGRvdWJsZSBxdW90ZXMgdG8gYSBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBtdWx0aWxpbmVRdW90ZSgkc3RyaW5nKQogICAgewogICAgICAgICRsaW5lcyA9IGV4cGxvZGUoIlxuIiwgJHN0cmluZyk7CiAgICAgICAgJGxhc3QgPSBjb3VudCgkbGluZXMpIC0gMTsKCiAgICAgICAgZm9yZWFjaCAoJGxpbmVzIGFzICRrID0+ICRsaW5lKSB7CiAgICAgICAgICAgIGlmICgkayA9PT0gJGxhc3QpIHsKICAgICAgICAgICAgICAgICRsaW5lc1ska10gPSBzdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGxpbmUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGxpbmVzWyRrXSA9IHN0YXRpYzo6Y29udmVydFN0cmluZygkbGluZS4iXG4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRsaW5lczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBvbmUgb3IgbW9yZSBsaW5lcyBkZXBlbmRpbmcgd2hldGhlciB0aGUgc3RyaW5nIGlzIG11bHRpbGluZSBvciBub3QuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAmJGxpbmVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGFkZExpbmVzKGFycmF5ICYkbGluZXMsICRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgJG5ld0xpbmVzID0gc3RhdGljOjptdWx0aWxpbmVRdW90ZSgkdmFsdWUpOwoKICAgICAgICBpZiAoY291bnQoJG5ld0xpbmVzKSA9PT0gMSkgewogICAgICAgICAgICAkbGluZXNbXSA9ICRuYW1lLicgJy4kbmV3TGluZXNbMF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGxpbmVzW10gPSAkbmFtZS4nICIiJzsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRuZXdMaW5lcyBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgJGxpbmVzW10gPSAkbGluZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gaXRzIFBPIHJlcHJlc2VudGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0U3RyaW5nKCR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJyInLnN0cnRyKAogICAgICAgICAgICAkdmFsdWUsCiAgICAgICAgICAgIFsKICAgICAgICAgICAgICAgICJceDAwIiA9PiAnJywKICAgICAgICAgICAgICAgICdcXCcgPT4gJ1xcXFwnLAogICAgICAgICAgICAgICAgIlx0IiA9PiAnXHQnLAogICAgICAgICAgICAgICAgIlxyIiA9PiAnXHInLAogICAgICAgICAgICAgICAgIlxuIiA9PiAnXG4nLAogICAgICAgICAgICAgICAgJyInID0+ICdcXCInLAogICAgICAgICAgICBdCiAgICAgICAgKS4nIic7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0OwoKdXNlIEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlOwp1c2UgQmFkTWV0aG9kQ2FsbEV4Y2VwdGlvbjsKdXNlIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIEFycmF5T2JqZWN0OwoKLyoqCiAqIENsYXNzIHRvIG1hbmFnZSBhIGNvbGxlY3Rpb24gb2YgdHJhbnNsYXRpb25zLgogKgogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQmxhZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21CbGFkZVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tQmxhZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUJsYWRlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQ3N2RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQ3N2U3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Dc3ZGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUNzdlN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvQ3N2RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0cmluZyB0b0NzdlN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQ3N2RGljdGlvbmFyeUZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbUNzdkRpY3Rpb25hcnlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUNzdkRpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUNzdkRpY3Rpb25hcnlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgYm9vbCB0b0NzdkRpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvQ3N2RGljdGlvbmFyeVN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSmVkRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSmVkU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21KZWRGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUplZFN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvSmVkRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0cmluZyB0b0plZFN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSnNDb2RlRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSnNDb2RlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc0NvZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUpzQ29kZVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbUpzb25GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21Kc29uU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc29uRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc29uU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9Kc29uRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0cmluZyB0b0pzb25TdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbUpzb25EaWN0aW9uYXJ5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSnNvbkRpY3Rpb25hcnlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUpzb25EaWN0aW9uYXJ5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc29uRGljdGlvbmFyeVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvSnNvbkRpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvSnNvbkRpY3Rpb25hcnlTdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbU1vRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tTW9TdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbU1vRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Nb1N0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvTW9GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvTW9TdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVBocEFycmF5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tUGhwQXJyYXlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVBocEFycmF5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21QaHBBcnJheVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvUGhwQXJyYXlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvUGhwQXJyYXlTdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVBocENvZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21QaHBDb2RlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21QaHBDb2RlRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21QaHBDb2RlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tUG9GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21Qb1N0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tUG9GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVBvU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9Qb0ZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdHJpbmcgdG9Qb1N0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tVHdpZ0ZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVR3aWdTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVR3aWdGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVR3aWdTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21WdWVKc0ZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVZ1ZUpzU3RyaW5nKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVZ1ZUpzRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21WdWVKc1N0cmluZyhzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tWGxpZmZGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21YbGlmZlN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tWGxpZmZGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVhsaWZmU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9YbGlmZkZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdHJpbmcgdG9YbGlmZlN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tWWFtbEZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVlhbWxTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVlhbWxGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVlhbWxTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgYm9vbCB0b1lhbWxGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvWWFtbFN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tWWFtbERpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21ZYW1sRGljdGlvbmFyeVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tWWFtbERpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVlhbWxEaWN0aW9uYXJ5U3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9ZYW1sRGljdGlvbmFyeUZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdHJpbmcgdG9ZYW1sRGljdGlvbmFyeVN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKi8KY2xhc3MgVHJhbnNsYXRpb25zIGV4dGVuZHMgQXJyYXlPYmplY3QKewogICAgY29uc3QgSEVBREVSX0xBTkdVQUdFID0gJ0xhbmd1YWdlJzsKICAgIGNvbnN0IEhFQURFUl9QTFVSQUwgPSAnUGx1cmFsLUZvcm1zJzsKICAgIGNvbnN0IEhFQURFUl9ET01BSU4gPSAnWC1Eb21haW4nOwoKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2RlZmF1bHRIZWFkZXJzJyA9PiBbCiAgICAgICAgICAgICdQcm9qZWN0LUlkLVZlcnNpb24nID0+ICcnLAogICAgICAgICAgICAnUmVwb3J0LU1zZ2lkLUJ1Z3MtVG8nID0+ICcnLAogICAgICAgICAgICAnTGFzdC1UcmFuc2xhdG9yJyA9PiAnJywKICAgICAgICAgICAgJ0xhbmd1YWdlLVRlYW0nID0+ICcnLAogICAgICAgICAgICAnTUlNRS1WZXJzaW9uJyA9PiAnMS4wJywKICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZScgPT4gJ3RleHQvcGxhaW47IGNoYXJzZXQ9VVRGLTgnLAogICAgICAgICAgICAnQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZycgPT4gJzhiaXQnLAogICAgICAgIF0sCiAgICAgICAgJ2hlYWRlcnNTb3J0aW5nJyA9PiBmYWxzZSwKICAgICAgICAnZGVmYXVsdERhdGVIZWFkZXJzJyA9PiBbCiAgICAgICAgICAgICdQT1QtQ3JlYXRpb24tRGF0ZScsCiAgICAgICAgICAgICdQTy1SZXZpc2lvbi1EYXRlJywKICAgICAgICBdLAogICAgXTsKCiAgICBwcm90ZWN0ZWQgJGhlYWRlcnM7CgogICAgcHJvdGVjdGVkICR0cmFuc2xhdGlvbkNsYXNzOwoKICAgIC8qKgogICAgICogQHNlZSBBcnJheU9iamVjdDo6X19jb25zdHJ1Y3QoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoCiAgICAgICAgJGlucHV0ID0gW10sCiAgICAgICAgJGZsYWdzID0gMCwKICAgICAgICAkaXRlcmF0b3JfY2xhc3MgPSAnQXJyYXlJdGVyYXRvcicsCiAgICAgICAgJHRyYW5zbGF0aW9uQ2xhc3MgPSAnR2V0dGV4dFxUcmFuc2xhdGlvbicKICAgICkgewogICAgICAgICR0aGlzLT5oZWFkZXJzID0gc3RhdGljOjokb3B0aW9uc1snZGVmYXVsdEhlYWRlcnMnXTsKCiAgICAgICAgZm9yZWFjaCAoc3RhdGljOjokb3B0aW9uc1snZGVmYXVsdERhdGVIZWFkZXJzJ10gYXMgJGhlYWRlcikgewogICAgICAgICAgICAkdGhpcy0+aGVhZGVyc1skaGVhZGVyXSA9IGRhdGUoJ2MnKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5oZWFkZXJzW3NlbGY6OkhFQURFUl9MQU5HVUFHRV0gPSAnJzsKCiAgICAgICAgJHRoaXMtPnRyYW5zbGF0aW9uQ2xhc3MgPSAkdHJhbnNsYXRpb25DbGFzczsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW5wdXQsICRmbGFncywgJGl0ZXJhdG9yX2NsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG1ldGhvZCB0byBjcmVhdGUgbmV3IGluc3RhbmNlcyB1c2luZyBleHRyYWN0b3JzCiAgICAgKiBGb3IgZXhhbXBsZTogVHJhbnNsYXRpb25zOjpmcm9tTW9GaWxlKCRmaWxlbmFtZSwgJG9wdGlvbnMpOy4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIF9fY2FsbFN0YXRpYygkbmFtZSwgJGFyZ3VtZW50cykKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9eZnJvbShcdyspKEZpbGV8U3RyaW5nKSQvaScsICRuYW1lLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJhZE1ldGhvZENhbGxFeGNlcHRpb24oIlRoZSBtZXRob2QgJG5hbWUgZG9lcyBub3QgZXhpc3RzIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoW25ldyBzdGF0aWMoKSwgJ2FkZCcudWNmaXJzdCgkbmFtZSldLCAkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG1ldGhvZCB0byBpbXBvcnQvZXhwb3J0IHRoZSB0cmFuc2xhdGlvbnMgdG8gYSBzcGVjaWZpYyBmb3JtYXQKICAgICAqIEZvciBleGFtcGxlOiAkdHJhbnNsYXRpb25zLT50b01vRmlsZSgkZmlsZW5hbWUsICRvcHRpb25zKTsKICAgICAqIEZvciBleGFtcGxlOiAkdHJhbnNsYXRpb25zLT5hZGRGcm9tTW9GaWxlKCRmaWxlbmFtZSwgJG9wdGlvbnMpOy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGZ8Ym9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jYWxsKCRuYW1lLCAkYXJndW1lbnRzKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL14oYWRkRnJvbXx0bykoXHcrKShGaWxlfFN0cmluZykkL2knLCAkbmFtZSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCYWRNZXRob2RDYWxsRXhjZXB0aW9uKCJUaGUgbWV0aG9kICRuYW1lIGRvZXMgbm90IGV4aXN0cyIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRtYXRjaGVzWzFdID09PSAnYWRkRnJvbScpIHsKICAgICAgICAgICAgJGV4dHJhY3RvciA9ICdHZXR0ZXh0XFxFeHRyYWN0b3JzXFwnLiRtYXRjaGVzWzJdLic6OmZyb20nLiRtYXRjaGVzWzNdOwogICAgICAgICAgICAkc291cmNlID0gYXJyYXlfc2hpZnQoJGFyZ3VtZW50cyk7CiAgICAgICAgICAgICRvcHRpb25zID0gYXJyYXlfc2hpZnQoJGFyZ3VtZW50cykgPzogW107CgogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYygkZXh0cmFjdG9yLCAkc291cmNlLCAkdGhpcywgJG9wdGlvbnMpOwoKICAgICAgICAgICAgcmV0dXJuICR0aGlzOwogICAgICAgIH0KCiAgICAgICAgJGdlbmVyYXRvciA9ICdHZXR0ZXh0XFxHZW5lcmF0b3JzXFwnLiRtYXRjaGVzWzJdLic6OnRvJy4kbWF0Y2hlc1szXTsKCiAgICAgICAgYXJyYXlfdW5zaGlmdCgkYXJndW1lbnRzLCAkdGhpcyk7CgogICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuY19hcnJheSgkZ2VuZXJhdG9yLCAkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG1ldGhvZCB0byBjbG9uZSBlYWNoIHRyYW5zbGF0aW9uIG9uIGNsb25lIHRoZSB0cmFuc2xhdGlvbnMgb2JqZWN0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jbG9uZSgpCiAgICB7CiAgICAgICAgJGFycmF5ID0gW107CgogICAgICAgIGZvcmVhY2ggKCR0aGlzIGFzICRrZXkgPT4gJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgICRhcnJheVska2V5XSA9IGNsb25lICR0cmFuc2xhdGlvbjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5leGNoYW5nZUFycmF5KCRhcnJheSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb250cm9sIHRoZSBuZXcgdHJhbnNsYXRpb25zIGFkZGVkLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkaW5kZXgKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEdldHRleHRcVHJhbnNsYXRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvZmZzZXRTZXQoJGluZGV4LCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEoJHZhbHVlIGluc3RhbmNlb2YgVHJhbnNsYXRpb24pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAnT25seSBpbnN0YW5jZXMgb2YgR2V0dGV4dFxcVHJhbnNsYXRpb24gbXVzdCBiZSBhZGRlZCB0byBhIEdldHRleHRcXFRyYW5zbGF0aW9ucycKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRpZCA9ICR2YWx1ZS0+Z2V0SWQoKTsKCiAgICAgICAgaWYgKCR0aGlzLT5vZmZzZXRFeGlzdHMoJGlkKSkgewogICAgICAgICAgICAkdGhpc1skaWRdLT5tZXJnZVdpdGgoJHZhbHVlKTsKCiAgICAgICAgICAgIHJldHVybiAkdGhpc1skaWRdOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpvZmZzZXRTZXQoJGlkLCAkdmFsdWUpOwoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBwbHVyYWwgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICRjb3VudAogICAgICogQHBhcmFtIHN0cmluZyAkcnVsZQogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGx1cmFsRm9ybXMoJGNvdW50LCAkcnVsZSkKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL1thLXpdL2knLCBzdHJfcmVwbGFjZSgnbicsICcnLCAkcnVsZSkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIFBsdXJhbCBmb3JtOiAnIC4gJHJ1bGUpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2V0SGVhZGVyKHNlbGY6OkhFQURFUl9QTFVSQUwsICJucGx1cmFscz17JGNvdW50fTsgcGx1cmFsPXskcnVsZX07Iik7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhcnNlZCBwbHVyYWwgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbnVsbHxhcnJheSBbY291bnQsIHJ1bGVdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQbHVyYWxGb3JtcygpCiAgICB7CiAgICAgICAgJGhlYWRlciA9ICR0aGlzLT5nZXRIZWFkZXIoc2VsZjo6SEVBREVSX1BMVVJBTCk7CgogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcikKICAgICAgICAgICAgJiYgcHJlZ19tYXRjaCgnL15ucGx1cmFsc1xzKj1ccyooXGQrKVxzKjtccypwbHVyYWxccyo9XHMqKFteO10rKVxzKjskLycsICRoZWFkZXIsICRtYXRjaGVzKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gW2ludHZhbCgkbWF0Y2hlc1sxXSksICRtYXRjaGVzWzJdXTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgYSBuZXcgaGVhZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIZWFkZXIoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkbmFtZSA9IHRyaW0oJG5hbWUpOwogICAgICAgICR0aGlzLT5oZWFkZXJzWyRuYW1lXSA9IHRyaW0oJHZhbHVlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGhlYWRlciB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBudWxsfHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVhZGVyKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+aGVhZGVyc1skbmFtZV0pID8gJHRoaXMtPmhlYWRlcnNbJG5hbWVdIDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIGhlYWRlciBmb3IgdGhpcyB0cmFuc2xhdGlvbnMgKGluIGFscGhhYmV0aWMgb3JkZXIpLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlYWRlcnMoKQogICAgewogICAgICAgIGlmIChzdGF0aWM6OiRvcHRpb25zWydoZWFkZXJzU29ydGluZyddKSB7CiAgICAgICAgICAgIGtzb3J0KCR0aGlzLT5oZWFkZXJzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aGVhZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgYWxsIGhlYWRlcnMuCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWxldGVIZWFkZXJzKCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVhZGVycyA9IFtdOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIG9uZSBoZWFkZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVsZXRlSGVhZGVyKCRuYW1lKQogICAgewogICAgICAgIHVuc2V0KCR0aGlzLT5oZWFkZXJzWyRuYW1lXSk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxhbmd1YWdlIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nICRsYW5ndWFnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGFuZ3VhZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SGVhZGVyKHNlbGY6OkhFQURFUl9MQU5HVUFHRSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsYW5ndWFnZSBhbmQgdGhlIHBsdXJhbCBmb3Jtcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsYW5ndWFnZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsYW5ndWFnZSBoYXNuJ3QgYmVlbiByZWNvZ25pemVkCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMYW5ndWFnZSgkbGFuZ3VhZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldEhlYWRlcihzZWxmOjpIRUFERVJfTEFOR1VBR0UsIHRyaW0oJGxhbmd1YWdlKSk7CgogICAgICAgIGlmICgoJGluZm8gPSBMYW5ndWFnZTo6Z2V0QnlJZCgkbGFuZ3VhZ2UpKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnNldFBsdXJhbEZvcm1zKGNvdW50KCRpbmZvLT5jYXRlZ29yaWVzKSwgJGluZm8tPmZvcm11bGEpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgbGFuZ3VhZ2UgIiVzIiBpcyBub3QgdmFsaWQnLCAkbGFuZ3VhZ2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBsYW5ndWFnZSBpcyBlbXB0eSBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNMYW5ndWFnZSgpCiAgICB7CiAgICAgICAgJGxhbmd1YWdlID0gJHRoaXMtPmdldExhbmd1YWdlKCk7CgogICAgICAgIHJldHVybiAoaXNfc3RyaW5nKCRsYW5ndWFnZSkgJiYgKCRsYW5ndWFnZSAhPT0gJycpKSA/IHRydWUgOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhIG5ldyBkb21haW4gZm9yIHRoaXMgdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRvbWFpbgogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RG9tYWluKCRkb21haW4pCiAgICB7CiAgICAgICAgJHRoaXMtPnNldEhlYWRlcihzZWxmOjpIRUFERVJfRE9NQUlOLCB0cmltKCRkb21haW4pKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZG9tYWluLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREb21haW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SGVhZGVyKHNlbGY6OkhFQURFUl9ET01BSU4pOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGRvbWFpbiBpcyBlbXB0eSBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNEb21haW4oKQogICAgewogICAgICAgICRkb21haW4gPSAkdGhpcy0+Z2V0RG9tYWluKCk7CgogICAgICAgIHJldHVybiAoaXNfc3RyaW5nKCRkb21haW4pICYmICgkZG9tYWluICE9PSAnJykpID8gdHJ1ZSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoIGZvciBhIHNwZWNpZmljIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8VHJhbnNsYXRpb24gJGNvbnRleHQgIFRoZSBjb250ZXh0IG9mIHRoZSB0cmFuc2xhdGlvbiBvciBhIHRyYW5zbGF0aW9uIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICRvcmlnaW5hbCBUaGUgb3JpZ2luYWwgc3RyaW5nCiAgICAgKiBAd2FybmluZyBUcmFuc2xhdGlvbnMgd2l0aCBjdXN0b20gaWRlbnRpZmllcnMgKGUuZy4gWExJRkYgdW5pdCBJRHMpIGNhbm5vdCBiZSBmb3VuZCB1c2luZyB0aGlzIGZ1bmN0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gVHJhbnNsYXRpb258ZmFsc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmQoJGNvbnRleHQsICRvcmlnaW5hbCA9ICcnKQogICAgewogICAgICAgIGlmICgkY29udGV4dCBpbnN0YW5jZW9mIFRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgICRpZCA9ICRjb250ZXh0LT5nZXRJZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpZCA9IFRyYW5zbGF0aW9uOjpnZW5lcmF0ZUlkKCRjb250ZXh0LCAkb3JpZ2luYWwpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5vZmZzZXRFeGlzdHMoJGlkKSA/ICR0aGlzWyRpZF0gOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvdW50IGFsbCBlbGVtZW50cyB0cmFuc2xhdGVkCiAgICAgKgogICAgICogQHJldHVybiBpbnRlZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudFRyYW5zbGF0ZWQoKQogICAgewogICAgICAgICRjID0gMDsKICAgICAgICBmb3JlYWNoICgkdGhpcyBhcyAkdikgewogICAgICAgICAgICBpZiAoJHYtPmhhc1RyYW5zbGF0aW9uKCkpIHsKICAgICAgICAgICAgICAgICRjKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbmQgaW5zZXJ0L21lcmdlcyBhIG5ldyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0ICBUaGUgdHJhbnNsYXRpb24gY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwgVGhlIHRyYW5zbGF0aW9uIG9yaWdpbmFsIHN0cmluZwogICAgICogQHBhcmFtIHN0cmluZyAkcGx1cmFsICAgVGhlIHRyYW5zbGF0aW9uIG9yaWdpbmFsIHBsdXJhbCBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9uIFRoZSB0cmFuc2xhdGlvbiBjcmVhdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnNlcnQoJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCA9ICcnKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b2Zmc2V0U2V0KG51bGwsICR0aGlzLT5jcmVhdGVOZXdUcmFuc2xhdGlvbigkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZXMgdGhpcyB0cmFuc2xhdGlvbnMgd2l0aCBvdGhlciB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zIFRoZSB0cmFuc2xhdGlvbnMgaW5zdGFuY2UgdG8gbWVyZ2Ugd2l0aAogICAgICogQHBhcmFtIGludCAgICAgICAgICAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWVyZ2VXaXRoKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyA9IE1lcmdlOjpERUZBVUxUUykKICAgIHsKICAgICAgICBNZXJnZTo6bWVyZ2VIZWFkZXJzKCR0cmFuc2xhdGlvbnMsICR0aGlzLCAkb3B0aW9ucyk7CiAgICAgICAgTWVyZ2U6Om1lcmdlVHJhbnNsYXRpb25zKCR0cmFuc2xhdGlvbnMsICR0aGlzLCAkb3B0aW9ucyk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBhIFRyYW5zbGF0aW9uIG9iamVjdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0ICBUaGUgY29udGV4dCBvZiB0aGUgdHJhbnNsYXRpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsIFRoZSBvcmlnaW5hbCBzdHJpbmcKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbCAgIFRoZSBvcmlnaW5hbCBwbHVyYWwgc3RyaW5nCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9uIE5ldyBUcmFuc2xhdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlTmV3VHJhbnNsYXRpb24oJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCA9ICcnKQogICAgewogICAgICAgICRjbGFzcyA9ICR0aGlzLT50cmFuc2xhdGlvbkNsYXNzOwogICAgICAgIHJldHVybiAkY2xhc3M6OmNyZWF0ZSgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHQ7Cgp1c2UgR2V0dGV4dFxHZW5lcmF0b3JzXFBocEFycmF5OwoKY2xhc3MgVHJhbnNsYXRvciBleHRlbmRzIEJhc2VUcmFuc2xhdG9yIGltcGxlbWVudHMgVHJhbnNsYXRvckludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJGRvbWFpbjsKICAgIHByb3RlY3RlZCAkZGljdGlvbmFyeSA9IFtdOwogICAgcHJvdGVjdGVkICRwbHVyYWxzID0gW107CgogICAgLyoqCiAgICAgKiBMb2FkcyB0cmFuc2xhdGlvbiBmcm9tIGEgVHJhbnNsYXRpb25zIGluc3RhbmNlLCBhIGZpbGUgb24gYW4gYXJyYXkuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uc3xzdHJpbmd8YXJyYXkgJHRyYW5zbGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkVHJhbnNsYXRpb25zKCR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKGlzX29iamVjdCgkdHJhbnNsYXRpb25zKSAmJiAkdHJhbnNsYXRpb25zIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMgPSBQaHBBcnJheTo6Z2VuZXJhdGUoJHRyYW5zbGF0aW9ucywgWydpbmNsdWRlSGVhZGVycycgPT4gZmFsc2VdKTsKICAgICAgICB9IGVsc2VpZiAoaXNfc3RyaW5nKCR0cmFuc2xhdGlvbnMpICYmIGlzX2ZpbGUoJHRyYW5zbGF0aW9ucykpIHsKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucyA9IGluY2x1ZGUgJHRyYW5zbGF0aW9uczsKICAgICAgICB9IGVsc2VpZiAoIWlzX2FycmF5KCR0cmFuc2xhdGlvbnMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgJ0ludmFsaWQgVHJhbnNsYXRvcjogb25seSBhcnJheXMsIGZpbGVzIG9yIGluc3RhbmNlIG9mIFRyYW5zbGF0aW9ucyBhcmUgYWxsb3dlZCcKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hZGRUcmFuc2xhdGlvbnMoJHRyYW5zbGF0aW9ucyk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgZGVmYXVsdCBkb21haW4uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKgogICAgICogQHJldHVybiBzdGF0aWMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlZmF1bHREb21haW4oJGRvbWFpbikKICAgIHsKICAgICAgICAkdGhpcy0+ZG9tYWluID0gJGRvbWFpbjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0dGV4dCgkb3JpZ2luYWwpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kcGdldHRleHQoJHRoaXMtPmRvbWFpbiwgbnVsbCwgJG9yaWdpbmFsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5nZXR0ZXh0KCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZG5wZ2V0dGV4dCgkdGhpcy0+ZG9tYWluLCBudWxsLCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kbnBnZXR0ZXh0KCRkb21haW4sIG51bGwsICRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kbnBnZXR0ZXh0KCR0aGlzLT5kb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZHBnZXR0ZXh0KCR0aGlzLT5kb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwpOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZHBnZXR0ZXh0KCRkb21haW4sIG51bGwsICRvcmlnaW5hbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkcGdldHRleHQoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCkKICAgIHsKICAgICAgICAkdHJhbnNsYXRpb24gPSAkdGhpcy0+Z2V0VHJhbnNsYXRpb24oJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCk7CgogICAgICAgIGlmIChpc3NldCgkdHJhbnNsYXRpb25bMF0pICYmICR0cmFuc2xhdGlvblswXSAhPT0gJycpIHsKICAgICAgICAgICAgcmV0dXJuICR0cmFuc2xhdGlvblswXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3JpZ2luYWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbnBnZXR0ZXh0KCRkb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdHJhbnNsYXRpb24gPSAkdGhpcy0+Z2V0VHJhbnNsYXRpb24oJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCk7CiAgICAgICAgJGtleSA9ICR0aGlzLT5nZXRQbHVyYWxJbmRleCgkZG9tYWluLCAkdmFsdWUsICR0cmFuc2xhdGlvbiA9PT0gZmFsc2UpOwoKICAgICAgICBpZiAoaXNzZXQoJHRyYW5zbGF0aW9uWyRrZXldKSAmJiAkdHJhbnNsYXRpb25bJGtleV0gIT09ICcnKSB7CiAgICAgICAgICAgIHJldHVybiAkdHJhbnNsYXRpb25bJGtleV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKCRrZXkgPT09IDApID8gJG9yaWdpbmFsIDogJHBsdXJhbDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBuZXcgdHJhbnNsYXRpb25zIHRvIHRoZSBkaWN0aW9uYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRUcmFuc2xhdGlvbnMoYXJyYXkgJHRyYW5zbGF0aW9ucykKICAgIHsKICAgICAgICAkZG9tYWluID0gaXNzZXQoJHRyYW5zbGF0aW9uc1snZG9tYWluJ10pID8gJHRyYW5zbGF0aW9uc1snZG9tYWluJ10gOiAnJzsKCiAgICAgICAgLy9TZXQgdGhlIGZpcnN0IGRvbWFpbiBsb2FkZWQgYXMgZGVmYXVsdCBkb21haW4KICAgICAgICBpZiAoJHRoaXMtPmRvbWFpbiA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+ZG9tYWluID0gJGRvbWFpbjsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+ZGljdGlvbmFyeVskZG9tYWluXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmRpY3Rpb25hcnlbJGRvbWFpbl0gPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+ZGljdGlvbmFyeVskZG9tYWluXSwgJHRyYW5zbGF0aW9uc1snbWVzc2FnZXMnXSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR0cmFuc2xhdGlvbnNbJ3BsdXJhbC1mb3JtcyddKSkgewogICAgICAgICAgICBsaXN0KCRjb3VudCwgJGNvZGUpID0gYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnOycsICR0cmFuc2xhdGlvbnNbJ3BsdXJhbC1mb3JtcyddLCAyKSk7CgogICAgICAgICAgICAvLyBleHRyYWN0IGp1c3QgdGhlIGV4cHJlc3Npb24gdHVybiAnbicgaW50byBhIHBocCB2YXJpYWJsZSAnJG4nLgogICAgICAgICAgICAvLyBTbGFwIG9uIGEgcmV0dXJuIGtleXdvcmQgYW5kIHNlbWljb2xvbiBhdCB0aGUgZW5kLgogICAgICAgICAgICAkdGhpcy0+cGx1cmFsc1skZG9tYWluXSA9IFsKICAgICAgICAgICAgICAgICdjb3VudCcgPT4gKGludCkgc3RyX3JlcGxhY2UoJ25wbHVyYWxzPScsICcnLCAkY291bnQpLAogICAgICAgICAgICAgICAgJ2NvZGUnID0+IHN0cl9yZXBsYWNlKCdwbHVyYWw9JywgJ3JldHVybiAnLCBzdHJfcmVwbGFjZSgnbicsICckbicsICRjb2RlKSkuJzsnLAogICAgICAgICAgICBdOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmRpY3Rpb25hcnlbJGRvbWFpbl0gPSAkdHJhbnNsYXRpb25zWydtZXNzYWdlcyddOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoIGFuZCByZXR1cm5zIGEgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRUcmFuc2xhdGlvbigkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZGljdGlvbmFyeVskZG9tYWluXVskY29udGV4dF1bJG9yaWdpbmFsXSkKICAgICAgICAgICAgID8gJHRoaXMtPmRpY3Rpb25hcnlbJGRvbWFpbl1bJGNvbnRleHRdWyRvcmlnaW5hbF0KICAgICAgICAgICAgIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB0aGUgcGx1cmFsIGRlY2lzaW9uIGNvZGUgZ2l2ZW4gdGhlIG51bWJlciB0byBkZWNpZGUgd2hpY2gKICAgICAqIHBsdXJhbCB2ZXJzaW9uIHRvIHRha2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuCiAgICAgKiBAcGFyYW0gYm9vbCAgICRmYWxsYmFjayBzZXQgdG8gdHJ1ZSB0byBnZXQgZmFsbGJhY2sgcGx1cmFsIGluZGV4CiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBsdXJhbEluZGV4KCRkb21haW4sICRuLCAkZmFsbGJhY2spCiAgICB7CiAgICAgICAgLy9Ob3QgbG9hZGVkIGRvbWFpbiBvciB0cmFuc2xhdGlvbiwgdXNlIGEgZmFsbGJhY2sKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5wbHVyYWxzWyRkb21haW5dKSB8fCAkZmFsbGJhY2sgPT09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuICRuID09IDEgPyAwIDogMTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnBsdXJhbHNbJGRvbWFpbl1bJ2Z1bmN0aW9uJ10pKSB7CiAgICAgICAgICAgICRjb2RlID0gc3RhdGljOjpmaXhUZXJzZUlmcygkdGhpcy0+cGx1cmFsc1skZG9tYWluXVsnY29kZSddKTsKICAgICAgICAgICAgJHRoaXMtPnBsdXJhbHNbJGRvbWFpbl1bJ2Z1bmN0aW9uJ10gPSBldmFsKCJyZXR1cm4gZnVuY3Rpb24gKFwkbikgeyAkY29kZSB9OyIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wbHVyYWxzWyRkb21haW5dWydjb3VudCddIDw9IDIpIHsKICAgICAgICAgICAgcmV0dXJuIGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5wbHVyYWxzWyRkb21haW5dWydmdW5jdGlvbiddLCAkbikgPyAxIDogMDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuYygkdGhpcy0+cGx1cmFsc1skZG9tYWluXVsnZnVuY3Rpb24nXSwgJG4pOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiB3aWxsIHJlY3Vyc2l2ZWx5IHdyYXAgZmFpbHVyZSBzdGF0ZXMgaW4gYnJhY2tldHMgaWYgdGhleSBjb250YWluIGEgbmVzdGVkIHRlcnNlIGlmLgogICAgICoKICAgICAqIFRoaXMgYmVjYXVzZSBQSFAgY2FuIG5vdCBoYW5kbGUgbmVzdGVkIHRlcnNlIGlmJ3MgdW5sZXNzIHRoZXkgYXJlIHdyYXBwZWQgaW4gYnJhY2tldHMuCiAgICAgKgogICAgICogVGhpcyBjb2RlIHByb2JhYmx5IG9ubHkgd29ya3MgZm9yIHRoZSBnZXR0ZXh0IHBsdXJhbCBkZWNpc2lvbiBjb2Rlcy4KICAgICAqCiAgICAgKiByZXR1cm4gKCRuPT0xID8gMCA6ICRuJTEwPj0yICYmICRuJTEwPD00ICYmICgkbiUxMDA8MTAgfHwgJG4lMTAwPj0yMCkgPyAxIDogMik7CiAgICAgKiBiZWNvbWVzCiAgICAgKiByZXR1cm4gKCRuPT0xID8gMCA6ICgkbiUxMD49MiAmJiAkbiUxMDw9NCAmJiAoJG4lMTAwPDEwIHx8ICRuJTEwMD49MjApID8gMSA6IDIpKTsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb2RlICB0aGUgdGVyc2UgaWYgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICRpbm5lciBJZiBpbm5lciBpcyB0cnVlIHdlIHdyYXAgaXQgaW4gYnJhY2tldHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIGZvcm1hdHRlZCB0ZXJzZSBJZiB0aGF0IFBIUCBjYW4gd29yayB3aXRoLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBmaXhUZXJzZUlmcygkY29kZSwgJGlubmVyID0gZmFsc2UpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiAoP1A8ZXhwcmVzc2lvbj5bXj9dKykgICBDYXB0dXJlIGV2ZXJ5dGhpbmcgdXAgdG8gPyBhcyAnZXhwcmVzc2lvbicKICAgICAgICAgKiBcPyAgICAgICAgICAgICAgICAgICAgICA/CiAgICAgICAgICogKD9QPHN1Y2Nlc3M+W146XSspICAgICAgQ2FwdHVyZSBldmVyeXRoaW5nIHVwIHRvIDogYXMgJ3N1Y2Nlc3MnCiAgICAgICAgICogOiAgICAgICAgICAgICAgICAgICAgICAgOgogICAgICAgICAqICg/UDxmYWlsdXJlPlteO10rKSAgICAgIENhcHR1cmUgZXZlcnl0aGluZyB1cCB0byA7IGFzICdmYWlsdXJlJwogICAgICAgICAqLwogICAgICAgIHByZWdfbWF0Y2goJy8oP1A8ZXhwcmVzc2lvbj5bXj9dKylcPyg/UDxzdWNjZXNzPlteOl0rKTooP1A8ZmFpbHVyZT5bXjtdKykvJywgJGNvZGUsICRtYXRjaGVzKTsKCiAgICAgICAgLy8gSWYgbm8gbWF0Y2ggd2FzIGZvdW5kIHRoZW4gbm8gdGVyc2UgaWYgd2FzIHByZXNlbnQKICAgICAgICBpZiAoIWlzc2V0KCRtYXRjaGVzWzBdKSkgewogICAgICAgICAgICByZXR1cm4gJGNvZGU7CiAgICAgICAgfQoKICAgICAgICAkZXhwcmVzc2lvbiA9ICRtYXRjaGVzWydleHByZXNzaW9uJ107CiAgICAgICAgJHN1Y2Nlc3MgPSAkbWF0Y2hlc1snc3VjY2VzcyddOwogICAgICAgICRmYWlsdXJlID0gJG1hdGNoZXNbJ2ZhaWx1cmUnXTsKCiAgICAgICAgLy8gR28gbG9vayBmb3IgYW5vdGhlciB0ZXJzZSBpZiBpbiB0aGUgZmFpbHVyZSBzdGF0ZS4KICAgICAgICAkZmFpbHVyZSA9IHN0YXRpYzo6Zml4VGVyc2VJZnMoJGZhaWx1cmUsIHRydWUpOwogICAgICAgICRjb2RlID0gJGV4cHJlc3Npb24uJyA/ICcuJHN1Y2Nlc3MuJyA6ICcuJGZhaWx1cmU7CgogICAgICAgIGlmICgkaW5uZXIpIHsKICAgICAgICAgICAgcmV0dXJuICIoJGNvZGUpIjsKICAgICAgICB9CgogICAgICAgIC8vIG5vdGUgdGhlIHNlbWljb2xvbi4gV2UgbmVlZCB0aGF0IGZvciBleGVjdXRpbmcgdGhlIGNvZGUuCiAgICAgICAgcmV0dXJuICIkY29kZTsiOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dDsKCmNsYXNzIEdldHRleHRUcmFuc2xhdG9yIGV4dGVuZHMgQmFzZVRyYW5zbGF0b3IgaW1wbGVtZW50cyBUcmFuc2xhdG9ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuIERldGVjdHMgdGhlIGN1cnJlbnQgbGFuZ3VhZ2UgdXNpbmcgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsYW5ndWFnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGxhbmd1YWdlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygnZ2V0dGV4dCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhpcyBjbGFzcyByZXF1aXJlIHRoZSBnZXR0ZXh0IGV4dGVuc2lvbiBmb3IgUEhQJyk7CiAgICAgICAgfQoKICAgICAgICAvL2RldGVjdHMgdGhlIGxhbmd1YWdlIGVudmlyb25tZW50IHJlc3BlY3RpbmcgdGhlIHByaW9yaXR5IG9yZGVyCiAgICAgICAgLy9odHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uZ2V0dGV4dC5waHAjMTE0MDYyCiAgICAgICAgaWYgKGVtcHR5KCRsYW5ndWFnZSkpIHsKICAgICAgICAgICAgJGxhbmd1YWdlID0gZ2V0ZW52KCdMQU5HVUFHRScpID86IGdldGVudignTENfQUxMJykgPzogZ2V0ZW52KCdMQ19NRVNTQUdFUycpID86IGdldGVudignTEFORycpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkbGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRMYW5ndWFnZSgkbGFuZ3VhZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERlZmluZSB0aGUgY3VycmVudCBsb2NhbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRsYW5ndWFnZQogICAgICogQHBhcmFtIGludHxudWxsICRjYXRlZ29yeQogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TGFuZ3VhZ2UoJGxhbmd1YWdlLCAkY2F0ZWdvcnkgPSBudWxsKQogICAgewogICAgICAgIGlmICgkY2F0ZWdvcnkgPT09IG51bGwpIHsKICAgICAgICAgICAgJGNhdGVnb3J5ID0gZGVmaW5lZCgnTENfTUVTU0FHRVMnKSA/IExDX01FU1NBR0VTIDogTENfQUxMOwogICAgICAgIH0KCiAgICAgICAgc2V0bG9jYWxlKCRjYXRlZ29yeSwgJGxhbmd1YWdlKTsKICAgICAgICBwdXRlbnYoJ0xBTkdVQUdFPScuJGxhbmd1YWdlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogTG9hZHMgYSBnZXR0ZXh0IGRvbWFpbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkb21haW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqIEBwYXJhbSBib29sICAgJGRlZmF1bHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWREb21haW4oJGRvbWFpbiwgJHBhdGggPSBudWxsLCAkZGVmYXVsdCA9IHRydWUpCiAgICB7CiAgICAgICAgYmluZHRleHRkb21haW4oJGRvbWFpbiwgJHBhdGgpOwogICAgICAgIGJpbmRfdGV4dGRvbWFpbl9jb2Rlc2V0KCRkb21haW4sICdVVEYtOCcpOwoKICAgICAgICBpZiAoJGRlZmF1bHQpIHsKICAgICAgICAgICAgdGV4dGRvbWFpbigkZG9tYWluKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldHRleHQoJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiBnZXR0ZXh0KCRvcmlnaW5hbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBuZ2V0dGV4dCgkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gbmdldHRleHQoJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG5nZXR0ZXh0KCRkb21haW4sICRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiBkbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbnBnZXR0ZXh0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKICAgIHsKICAgICAgICAkbWVzc2FnZSA9ICRjb250ZXh0LiJceDA0Ii4kb3JpZ2luYWw7CiAgICAgICAgJHRyYW5zbGF0aW9uID0gbmdldHRleHQoJG1lc3NhZ2UsICRwbHVyYWwsICR2YWx1ZSk7CgogICAgICAgIHJldHVybiAoJHRyYW5zbGF0aW9uID09PSAkbWVzc2FnZSkgPyAkb3JpZ2luYWwgOiAkdHJhbnNsYXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgICRtZXNzYWdlID0gJGNvbnRleHQuIlx4MDQiLiRvcmlnaW5hbDsKICAgICAgICAkdHJhbnNsYXRpb24gPSBnZXR0ZXh0KCRtZXNzYWdlKTsKCiAgICAgICAgcmV0dXJuICgkdHJhbnNsYXRpb24gPT09ICRtZXNzYWdlKSA/ICRvcmlnaW5hbCA6ICR0cmFuc2xhdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRnZXR0ZXh0KCRkb21haW4sICRvcmlnaW5hbCkKICAgIHsKICAgICAgICByZXR1cm4gZGdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRwZ2V0dGV4dCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgICRtZXNzYWdlID0gJGNvbnRleHQuIlx4MDQiLiRvcmlnaW5hbDsKICAgICAgICAkdHJhbnNsYXRpb24gPSBkZ2V0dGV4dCgkZG9tYWluLCAkbWVzc2FnZSk7CgogICAgICAgIHJldHVybiAoJHRyYW5zbGF0aW9uID09PSAkbWVzc2FnZSkgPyAkb3JpZ2luYWwgOiAkdHJhbnNsYXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbnBnZXR0ZXh0KCRkb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKICAgIHsKICAgICAgICAkbWVzc2FnZSA9ICRjb250ZXh0LiJceDA0Ii4kb3JpZ2luYWw7CiAgICAgICAgJHRyYW5zbGF0aW9uID0gZG5nZXR0ZXh0KCRkb21haW4sICRtZXNzYWdlLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgICAgICByZXR1cm4gKCR0cmFuc2xhdGlvbiA9PT0gJG1lc3NhZ2UpID8gJG9yaWdpbmFsIDogJHRyYW5zbGF0aW9uOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dDsKCi8qKgogKiBTdGF0aWMgY2xhc3Mgd2l0aCBtZXJnZSBjb250YW50cy4KICovCmZpbmFsIGNsYXNzIE1lcmdlCnsKICAgIGNvbnN0IEFERCA9IDE7CiAgICBjb25zdCBSRU1PVkUgPSAyOwoKICAgIGNvbnN0IEhFQURFUlNfQUREID0gNDsKICAgIGNvbnN0IEhFQURFUlNfUkVNT1ZFID0gODsKICAgIGNvbnN0IEhFQURFUlNfT1ZFUlJJREUgPSAxNjsKCiAgICBjb25zdCBMQU5HVUFHRV9PVkVSUklERSA9IDMyOwogICAgY29uc3QgRE9NQUlOX09WRVJSSURFID0gNjQ7CiAgICBjb25zdCBUUkFOU0xBVElPTl9PVkVSUklERSA9IDEyODsKCiAgICBjb25zdCBDT01NRU5UU19PVVJTID0gMjU2OwogICAgY29uc3QgQ09NTUVOVFNfVEhFSVJTID0gNTEyOwoKICAgIGNvbnN0IEVYVFJBQ1RFRF9DT01NRU5UU19PVVJTID0gMTAyNDsKICAgIGNvbnN0IEVYVFJBQ1RFRF9DT01NRU5UU19USEVJUlMgPSAyMDQ4OwoKICAgIGNvbnN0IEZMQUdTX09VUlMgPSA0MDk2OwogICAgY29uc3QgRkxBR1NfVEhFSVJTID0gODE5MjsKCiAgICBjb25zdCBSRUZFUkVOQ0VTX09VUlMgPSAxNjM4NDsKICAgIGNvbnN0IFJFRkVSRU5DRVNfVEhFSVJTID0gMzI3Njg7CgogICAgY29uc3QgREVGQVVMVFMgPSA1OyAvLzEgKyA0CgogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgZmxhZ3Mgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJGZyb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlRmxhZ3MoVHJhbnNsYXRpb24gJGZyb20sIFRyYW5zbGF0aW9uICR0bywgJG9wdGlvbnMgPSBzZWxmOjpERUZBVUxUUykKICAgIHsKICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpGTEFHU19USEVJUlMpIHsKICAgICAgICAgICAgJHRvLT5kZWxldGVGbGFncygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEoJG9wdGlvbnMgJiBzZWxmOjpGTEFHU19PVVJTKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZnJvbS0+Z2V0RmxhZ3MoKSBhcyAkZmxhZykgewogICAgICAgICAgICAgICAgJHRvLT5hZGRGbGFnKCRmbGFnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlIHRoZSBleHRyYWN0ZWQgY29tbWVudHMgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJGZyb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlRXh0cmFjdGVkQ29tbWVudHMoVHJhbnNsYXRpb24gJGZyb20sIFRyYW5zbGF0aW9uICR0bywgJG9wdGlvbnMgPSBzZWxmOjpERUZBVUxUUykKICAgIHsKICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpFWFRSQUNURURfQ09NTUVOVFNfVEhFSVJTKSB7CiAgICAgICAgICAgICR0by0+ZGVsZXRlRXh0cmFjdGVkQ29tbWVudHMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghKCRvcHRpb25zICYgc2VsZjo6RVhUUkFDVEVEX0NPTU1FTlRTX09VUlMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRmcm9tLT5nZXRFeHRyYWN0ZWRDb21tZW50cygpIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAkdG8tPmFkZEV4dHJhY3RlZENvbW1lbnQoJGNvbW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2UgdGhlIGNvbW1lbnRzIG9mIHR3byB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uICRmcm9tCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJHRvCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXJnZUNvbW1lbnRzKFRyYW5zbGF0aW9uICRmcm9tLCBUcmFuc2xhdGlvbiAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6Q09NTUVOVFNfVEhFSVJTKSB7CiAgICAgICAgICAgICR0by0+ZGVsZXRlQ29tbWVudHMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghKCRvcHRpb25zICYgc2VsZjo6Q09NTUVOVFNfT1VSUykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGZyb20tPmdldENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICR0by0+YWRkQ29tbWVudCgkY29tbWVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgcmVmZXJlbmNlcyBvZiB0d28gdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkZnJvbQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uICR0bwogICAgICogQHBhcmFtIGludCAgICAgICAgICRvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWVyZ2VSZWZlcmVuY2VzKFRyYW5zbGF0aW9uICRmcm9tLCBUcmFuc2xhdGlvbiAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6UkVGRVJFTkNFU19USEVJUlMpIHsKICAgICAgICAgICAgJHRvLT5kZWxldGVSZWZlcmVuY2VzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISgkb3B0aW9ucyAmIHNlbGY6OlJFRkVSRU5DRVNfT1VSUykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGZyb20tPmdldFJlZmVyZW5jZXMoKSBhcyAkcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICAgICAkdG8tPmFkZFJlZmVyZW5jZSgkcmVmZXJlbmNlWzBdLCAkcmVmZXJlbmNlWzFdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlIHRoZSB0cmFuc2xhdGlvbnMgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJGZyb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlVHJhbnNsYXRpb24oVHJhbnNsYXRpb24gJGZyb20sIFRyYW5zbGF0aW9uICR0bywgJG9wdGlvbnMgPSBzZWxmOjpERUZBVUxUUykKICAgIHsKICAgICAgICAkb3ZlcnJpZGUgPSAoYm9vbGVhbikgKCRvcHRpb25zICYgc2VsZjo6VFJBTlNMQVRJT05fT1ZFUlJJREUpOwoKICAgICAgICBpZiAoISR0by0+aGFzVHJhbnNsYXRpb24oKSB8fCAoJGZyb20tPmhhc1RyYW5zbGF0aW9uKCkgJiYgJG92ZXJyaWRlKSkgewogICAgICAgICAgICAkdG8tPnNldFRyYW5zbGF0aW9uKCRmcm9tLT5nZXRUcmFuc2xhdGlvbigpKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRvLT5oYXNQbHVyYWwoKSB8fCAoJGZyb20tPmhhc1BsdXJhbCgpICYmICRvdmVycmlkZSkpIHsKICAgICAgICAgICAgJHRvLT5zZXRQbHVyYWwoJGZyb20tPmdldFBsdXJhbCgpKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRvLT5oYXNQbHVyYWxUcmFuc2xhdGlvbnMoKSB8fCAoJGZyb20tPmhhc1BsdXJhbFRyYW5zbGF0aW9ucygpICYmICRvdmVycmlkZSkpIHsKICAgICAgICAgICAgJHRvLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJGZyb20tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgdHJhbnNsYXRpb25zIG9mIHR3byB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkZnJvbQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXJnZVRyYW5zbGF0aW9ucyhUcmFuc2xhdGlvbnMgJGZyb20sIFRyYW5zbGF0aW9ucyAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6UkVNT1ZFKSB7CiAgICAgICAgICAgICRmaWx0ZXJlZCA9IFtdOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHRvIGFzICRlbnRyeSkgewogICAgICAgICAgICAgICAgaWYgKCRmcm9tLT5maW5kKCRlbnRyeSkpIHsKICAgICAgICAgICAgICAgICAgICAkZmlsdGVyZWRbJGVudHJ5LT5nZXRJZCgpXSA9ICRlbnRyeTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRvLT5leGNoYW5nZUFycmF5KCRmaWx0ZXJlZCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkZnJvbSBhcyAkZW50cnkpIHsKICAgICAgICAgICAgaWYgKCgkZXhpc3RpbmcgPSAkdG8tPmZpbmQoJGVudHJ5KSkpIHsKICAgICAgICAgICAgICAgICRleGlzdGluZy0+bWVyZ2VXaXRoKCRlbnRyeSwgJG9wdGlvbnMpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG9wdGlvbnMgJiBzZWxmOjpBREQpIHsKICAgICAgICAgICAgICAgICR0b1tdID0gJGVudHJ5LT5nZXRDbG9uZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2UgdGhlIGhlYWRlcnMgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICRmcm9tCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0bwogICAgICogQHBhcmFtIGludCAgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlSGVhZGVycyhUcmFuc2xhdGlvbnMgJGZyb20sIFRyYW5zbGF0aW9ucyAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6SEVBREVSU19SRU1PVkUpIHsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cygkdG8tPmdldEhlYWRlcnMoKSkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICgkZnJvbS0+Z2V0SGVhZGVyKCRuYW1lKSA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR0by0+ZGVsZXRlSGVhZGVyKCRuYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGZyb20tPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJGN1cnJlbnQgPSAkdG8tPmdldEhlYWRlcigkbmFtZSk7CgogICAgICAgICAgICBpZiAoZW1wdHkoJGN1cnJlbnQpKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpIRUFERVJTX0FERCkgewogICAgICAgICAgICAgICAgICAgICR0by0+c2V0SGVhZGVyKCRuYW1lLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbXB0eSgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICgkbmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSBUcmFuc2xhdGlvbnM6OkhFQURFUl9MQU5HVUFHRToKICAgICAgICAgICAgICAgIGNhc2UgVHJhbnNsYXRpb25zOjpIRUFERVJfUExVUkFMOgogICAgICAgICAgICAgICAgICAgIGlmICgkb3B0aW9ucyAmIHNlbGY6OkxBTkdVQUdFX09WRVJSSURFKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0by0+c2V0SGVhZGVyKCRuYW1lLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFRyYW5zbGF0aW9uczo6SEVBREVSX0RPTUFJTjoKICAgICAgICAgICAgICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpET01BSU5fT1ZFUlJJREUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRvLT5zZXRIZWFkZXIoJG5hbWUsICR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6SEVBREVSU19PVkVSUklERSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdG8tPnNldEhlYWRlcigkbmFtZSwgJHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCnVzZSBHZXR0ZXh0XEJhc2VUcmFuc2xhdG9yOwoKLyoqCiAqIFJldHVybnMgdGhlIHRyYW5zbGF0aW9uIG9mIGEgc3RyaW5nLgogKgogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gX18oJG9yaWdpbmFsKQp7CiAgICAkdGV4dCA9IEJhc2VUcmFuc2xhdG9yOjokY3VycmVudC0+Z2V0dGV4dCgkb3JpZ2luYWwpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDEpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDEpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIE5vb3AsIG1hcmtzIHRoZSBzdHJpbmcgZm9yIHRyYW5zbGF0aW9uIGJ1dCByZXR1cm5zIGl0IHVuY2hhbmdlZC4KICoKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIG5vb3BfXygkb3JpZ2luYWwpCnsKICAgIHJldHVybiAkb3JpZ2luYWw7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSBzaW5ndWxhci9wbHVyYWwgdHJhbnNsYXRpb24gb2YgYSBzdHJpbmcuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gbl9fKCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKQp7CiAgICAkdGV4dCA9IEJhc2VUcmFuc2xhdG9yOjokY3VycmVudC0+bmdldHRleHQoJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDMpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDMpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHRyYW5zbGF0aW9uIG9mIGEgc3RyaW5nIGluIGEgc3BlY2lmaWMgY29udGV4dC4KICoKICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gcF9fKCRjb250ZXh0LCAkb3JpZ2luYWwpCnsKICAgICR0ZXh0ID0gQmFzZVRyYW5zbGF0b3I6OiRjdXJyZW50LT5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICBpZiAoZnVuY19udW1fYXJncygpID09PSAyKSB7CiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgICRhcmdzID0gYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAyKTsKCiAgICByZXR1cm4gaXNfYXJyYXkoJGFyZ3NbMF0pID8gc3RydHIoJHRleHQsICRhcmdzWzBdKSA6IHZzcHJpbnRmKCR0ZXh0LCAkYXJncyk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGRvbWFpbi4KICoKICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBkX18oJGRvbWFpbiwgJG9yaWdpbmFsKQp7CiAgICAkdGV4dCA9IEJhc2VUcmFuc2xhdG9yOjokY3VycmVudC0+ZGdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsKTsKCiAgICBpZiAoZnVuY19udW1fYXJncygpID09PSAyKSB7CiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgICRhcmdzID0gYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAyKTsKCiAgICByZXR1cm4gaXNfYXJyYXkoJGFyZ3NbMF0pID8gc3RydHIoJHRleHQsICRhcmdzWzBdKSA6IHZzcHJpbnRmKCR0ZXh0LCAkYXJncyk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGRvbWFpbiBhbmQgY29udGV4dC4KICoKICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGRwX18oJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCkKewogICAgJHRleHQgPSBCYXNlVHJhbnNsYXRvcjo6JGN1cnJlbnQtPmRwZ2V0dGV4dCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICBpZiAoZnVuY19udW1fYXJncygpID09PSAzKSB7CiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgICRhcmdzID0gYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAzKTsKCiAgICByZXR1cm4gaXNfYXJyYXkoJGFyZ3NbMF0pID8gc3RydHIoJHRleHQsICRhcmdzWzBdKSA6IHZzcHJpbnRmKCR0ZXh0LCAkYXJncyk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSBzaW5ndWxhci9wbHVyYWwgdHJhbnNsYXRpb24gb2YgYSBzdHJpbmcgaW4gYSBzcGVjaWZpYyBkb21haW4uCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGRvbWFpbgogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogKiBAcGFyYW0gc3RyaW5nICRwbHVyYWwKICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGRuX18oJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCnsKICAgICR0ZXh0ID0gQmFzZVRyYW5zbGF0b3I6OiRjdXJyZW50LT5kbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDQpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDQpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHNpbmd1bGFyL3BsdXJhbCB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGNvbnRleHQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICogQHBhcmFtIHN0cmluZyAkcGx1cmFsCiAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBucF9fKCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKewogICAgJHRleHQgPSBCYXNlVHJhbnNsYXRvcjo6JGN1cnJlbnQtPm5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDQpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDQpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHNpbmd1bGFyL3BsdXJhbCB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGRvbWFpbiBhbmQgY29udGV4dC4KICoKICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICogQHBhcmFtIHN0cmluZyAkcGx1cmFsCiAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBkbnBfXygkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCnsKICAgICR0ZXh0ID0gQmFzZVRyYW5zbGF0b3I6OiRjdXJyZW50LT5kbnBnZXR0ZXh0KCRkb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CgogICAgaWYgKGZ1bmNfbnVtX2FyZ3MoKSA9PT0gNSkgewogICAgICAgIHJldHVybiAkdGV4dDsKICAgIH0KCiAgICAkYXJncyA9IGFycmF5X3NsaWNlKGZ1bmNfZ2V0X2FyZ3MoKSwgNSk7CgogICAgcmV0dXJuIGlzX2FycmF5KCRhcmdzWzBdKSA/IHN0cnRyKCR0ZXh0LCAkYXJnc1swXSkgOiB2c3ByaW50ZigkdGV4dCwgJGFyZ3MpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEJhZE1ldGhvZENhbGxFeGNlcHRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIHBocCBmaWxlcyByZXR1cm5pbmcgYXJyYXlzLgogKi8KY2xhc3MgUGhwQXJyYXkgZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgdXNlIE11bHRpZGltZW5zaW9uYWxBcnJheVRyYWl0OwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GaWxlKCRmaWxlLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICBmb3JlYWNoIChzdGF0aWM6OmdldEZpbGVzKCRmaWxlKSBhcyAkZmlsZSkgewogICAgICAgICAgICBzdGF0aWM6OmZyb21BcnJheShpbmNsdWRlKCRmaWxlKSwgJHRyYW5zbGF0aW9ucyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IEJhZE1ldGhvZENhbGxFeGNlcHRpb24oJ1BocEFycmF5Ojpmcm9tU3RyaW5nKCkgY2Fubm90IGJlIGNhbGxlZC4gVXNlIFBocEFycmF5Ojpmcm9tRmlsZSgpJyk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKdXNlIEdldHRleHRcVXRpbHNcQ3N2VHJhaXQ7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIGNzdi4KICovCmNsYXNzIENzdkRpY3Rpb25hcnkgZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgdXNlIEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKICAgIHVzZSBDc3ZUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdkZWxpbWl0ZXInID0+ICIsIiwKICAgICAgICAnZW5jbG9zdXJlJyA9PiAnIicsCiAgICAgICAgJ2VzY2FwZV9jaGFyJyA9PiAiXFwiCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKICAgICAgICAkaGFuZGxlID0gZm9wZW4oJ3BocDovL21lbW9yeScsICd3Jyk7CgogICAgICAgIGZwdXRzKCRoYW5kbGUsICRzdHJpbmcpOwogICAgICAgIHJld2luZCgkaGFuZGxlKTsKCiAgICAgICAgd2hpbGUgKCRyb3cgPSBzdGF0aWM6OmZnZXRjc3YoJGhhbmRsZSwgJG9wdGlvbnMpKSB7CiAgICAgICAgICAgIGxpc3QoJG9yaWdpbmFsLCAkdHJhbnNsYXRpb24pID0gJHJvdyArIFsnJywgJyddOwoKICAgICAgICAgICAgaWYgKCRvcmlnaW5hbCA9PT0gJycpIHsKICAgICAgICAgICAgICAgIHN0YXRpYzo6ZXh0cmFjdEhlYWRlcnMoJHRyYW5zbGF0aW9uLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5pbnNlcnQobnVsbCwgJG9yaWdpbmFsKS0+c2V0VHJhbnNsYXRpb24oJHRyYW5zbGF0aW9uKTsKICAgICAgICB9CgogICAgICAgIGZjbG9zZSgkaGFuZGxlKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFR3aWdfTG9hZGVyX0FycmF5Owp1c2UgVHdpZ19FbnZpcm9ubWVudDsKdXNlIFR3aWdfU291cmNlOwp1c2UgVHdpZ19FeHRlbnNpb25zX0V4dGVuc2lvbl9JMThuOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSB0d2lnIGZpbGVzIHJldHVybmluZyBhcnJheXMuCiAqLwpjbGFzcyBUd2lnIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2V4dHJhY3RDb21tZW50cycgPT4gJ25vdGVzOicsCiAgICAgICAgJ3R3aWcnID0+IG51bGwsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgJHR3aWcgPSAkb3B0aW9uc1sndHdpZyddID86IHN0YXRpYzo6Y3JlYXRlVHdpZygpOwoKICAgICAgICBQaHBDb2RlOjpmcm9tU3RyaW5nKCR0d2lnLT5jb21waWxlU291cmNlKG5ldyBUd2lnX1NvdXJjZSgkc3RyaW5nLCAnJykpLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgVHdpZyBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFR3aWdfRW52aXJvbm1lbnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVUd2lnKCkKICAgIHsKICAgICAgICAkdHdpZyA9IG5ldyBUd2lnX0Vudmlyb25tZW50KG5ldyBUd2lnX0xvYWRlcl9BcnJheShbJycgPT4gJyddKSk7CiAgICAgICAgJHR3aWctPmFkZEV4dGVuc2lvbihuZXcgVHdpZ19FeHRlbnNpb25zX0V4dGVuc2lvbl9JMThuKCkpOwoKICAgICAgICByZXR1cm4gc3RhdGljOjokb3B0aW9uc1sndHdpZyddID0gJHR3aWc7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXERpY3Rpb25hcnlUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gcGxhaW4ganNvbi4KICovCmNsYXNzIEpzb25EaWN0aW9uYXJ5IGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBqc29uX2RlY29kZSgkc3RyaW5nLCB0cnVlKTsKCiAgICAgICAgaWYgKGlzX2FycmF5KCRtZXNzYWdlcykpIHsKICAgICAgICAgICAgc3RhdGljOjpmcm9tQXJyYXkoJG1lc3NhZ2VzLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgppbnRlcmZhY2UgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogRXh0cmFjdCB0aGUgdHJhbnNsYXRpb25zIGZyb20gYSBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheXxzdHJpbmcgJGZpbGUgICAgICAgICBBIHBhdGggb2YgYSBmaWxlIG9yIGZpbGVzCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMgVGhlIHRyYW5zbGF0aW9ucyBpbnN0YW5jZSB0byBhcHBlbmQgdGhlIG5ldyB0cmFuc2xhdGlvbnMuCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUZpbGUoJGZpbGUsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHN0cmluZyBhbmQgYXBwZW5kIHRoZSB0cmFuc2xhdGlvbnMgZm91bmQgaW4gdGhlIFRyYW5zbGF0aW9ucyBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICRzdHJpbmcKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pOwp9Cjw/cGhwCi8qKiBAbm9pbnNwZWN0aW9uIFBocENvbXBvc2VyRXh0ZW5zaW9uU3R1YnNJbnNwZWN0aW9uICovCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIERPTUF0dHI7CnVzZSBET01Eb2N1bWVudDsKdXNlIERPTUVsZW1lbnQ7CnVzZSBET01Ob2RlOwp1c2UgRXhjZXB0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEZ1bmN0aW9uc1NjYW5uZXI7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIFZ1ZUpTIHRlbXBsYXRlIGZpbGVzLgogKi8KY2xhc3MgVnVlSnMgZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UsIEV4dHJhY3Rvck11bHRpSW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2NvbnN0YW50cycgPT4gW10sCgogICAgICAgICdmdW5jdGlvbnMnID0+IFsKICAgICAgICAgICAgJ2dldHRleHQnID0+ICdnZXR0ZXh0JywKICAgICAgICAgICAgJ19fJyA9PiAnZ2V0dGV4dCcsCiAgICAgICAgICAgICduZ2V0dGV4dCcgPT4gJ25nZXR0ZXh0JywKICAgICAgICAgICAgJ25fXycgPT4gJ25nZXR0ZXh0JywKICAgICAgICAgICAgJ3BnZXR0ZXh0JyA9PiAncGdldHRleHQnLAogICAgICAgICAgICAncF9fJyA9PiAncGdldHRleHQnLAogICAgICAgICAgICAnZGdldHRleHQnID0+ICdkZ2V0dGV4dCcsCiAgICAgICAgICAgICdkX18nID0+ICdkZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbmdldHRleHQnID0+ICdkbmdldHRleHQnLAogICAgICAgICAgICAnZG5fXycgPT4gJ2RuZ2V0dGV4dCcsCiAgICAgICAgICAgICdkcGdldHRleHQnID0+ICdkcGdldHRleHQnLAogICAgICAgICAgICAnZHBfXycgPT4gJ2RwZ2V0dGV4dCcsCiAgICAgICAgICAgICducGdldHRleHQnID0+ICducGdldHRleHQnLAogICAgICAgICAgICAnbnBfXycgPT4gJ25wZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbnBnZXR0ZXh0JyA9PiAnZG5wZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbnBfXycgPT4gJ2RucGdldHRleHQnLAogICAgICAgICAgICAnbm9vcCcgPT4gJ25vb3AnLAogICAgICAgICAgICAnbm9vcF9fJyA9PiAnbm9vcCcsCiAgICAgICAgXSwKICAgIF07CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkZnVuY3Rpb25zU2Nhbm5lckNsYXNzID0gJ0dldHRleHRcVXRpbHNcSnNGdW5jdGlvbnNTY2FubmVyJzsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GaWxlTXVsdGlwbGUoJGZpbGUsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc3RhdGljOjpnZXRGaWxlcygkZmlsZSkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ2ZpbGUnXSA9ICRmaWxlOwogICAgICAgICAgICBzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZShzdGF0aWM6OnJlYWRGaWxlKCRmaWxlKSwgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0ZG9jCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgc3RhdGljOjpmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgWyR0cmFuc2xhdGlvbnNdLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgYXJyYXkgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwogICAgICAgICRvcHRpb25zICs9IFsKICAgICAgICAgICAgLy8gSFRNTCBhdHRyaWJ1dGUgcHJlZml4ZXMgd2UgcGFyc2UgYXMgSlMgd2hpY2ggY291bGQgY29udGFpbiB0cmFuc2xhdGlvbnMgKGFyZSBKUyBleHByZXNzaW9ucykKICAgICAgICAgICAgJ2F0dHJpYnV0ZVByZWZpeGVzJyA9PiBbCiAgICAgICAgICAgICAgICAnOicsCiAgICAgICAgICAgICAgICAndi1iaW5kOicsCiAgICAgICAgICAgICAgICAndi1vbjonLAogICAgICAgICAgICAgICAgJ3YtdGV4dCcsCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgIC8vIEhUTUwgVGFncyB0byBwYXJzZQogICAgICAgICAgICAndGFnTmFtZXMnID0+IFsKICAgICAgICAgICAgICAgICd0cmFuc2xhdGUnLAogICAgICAgICAgICBdLAogICAgICAgICAgICAvLyBIVE1MIHRhZ3MgdG8gcGFyc2Ugd2hlbiBhdHRyaWJ1dGUgZXhpc3RzCiAgICAgICAgICAgICd0YWdBdHRyaWJ1dGVzJyA9PiBbCiAgICAgICAgICAgICAgICAndi10cmFuc2xhdGUnLAogICAgICAgICAgICBdLAogICAgICAgICAgICAvLyBDb21tZW50cwogICAgICAgICAgICAnY29tbWVudEF0dHJpYnV0ZXMnID0+IFsKICAgICAgICAgICAgICAgICd0cmFuc2xhdGUtY29tbWVudCcsCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICdjb250ZXh0QXR0cmlidXRlcycgPT4gWwogICAgICAgICAgICAgICAgJ3RyYW5zbGF0ZS1jb250ZXh0JywKICAgICAgICAgICAgXSwKICAgICAgICAgICAgLy8gQXR0cmlidXRlIHdpdGggcGx1cmFsIGNvbnRlbnQKICAgICAgICAgICAgJ3BsdXJhbEF0dHJpYnV0ZXMnID0+IFsKICAgICAgICAgICAgICAgICd0cmFuc2xhdGUtcGx1cmFsJywKICAgICAgICAgICAgXSwKICAgICAgICBdOwoKICAgICAgICAvLyBPaywgdGhpcyBpcyB0aGUgd2VpcmRlc3QgaGFjaywgYnV0IGxldCBtZSBleHBsYWluOgogICAgICAgIC8vIE9uIExpbnV4IChNYWMgaXMgZmluZSksIHdoZW4gY29udmVydGluZyBIVE1MIHRvIERPTSwgbmV3IGxpbmVzIGdldCB0cmltbWVkIGFmdGVyIHRoZSBmaXJzdCB0YWcuCiAgICAgICAgLy8gU28gaWYgdGhlcmUgYXJlIG5ldyBsaW5lcyBiZXR3ZWVuIDx0ZW1wbGF0ZT4gYW5kIG5leHQgZWxlbWVudCwgdGhleSBhcmUgbG9zdAogICAgICAgIC8vIFNvIHdlIGluc2VydCBhICIuIiB3aGljaCBpcyBhIHRleHQgbm9kZSwgYW5kIGl0IHdpbGwgcHJldmVudCB0aGF0IG5ld2xpbmVzIGFyZSBzdHJpcHBlZCBiZXR3ZWVuIGVsZW1lbnRzLgogICAgICAgIC8vIFNhbWUgdGhpbmcgaGFwcGVucyBiZXR3ZWVuIHRlbXBsYXRlIGFuZCBzY3JpcHQgdGFnLgogICAgICAgICRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnPHRlbXBsYXRlPicsICc8dGVtcGxhdGU+LicsICRzdHJpbmcpOwogICAgICAgICRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnPC90ZW1wbGF0ZT4nLCAnPC90ZW1wbGF0ZT4uJywgJHN0cmluZyk7CgogICAgICAgIC8vIE5vcm1hbGl6ZSBuZXdsaW5lcwogICAgICAgICRzdHJpbmcgPSBzdHJfcmVwbGFjZShbIlxyXG4iLCAiXG5cciIsICJcciJdLCAiXG4iLCAkc3RyaW5nKTsKCiAgICAgICAgLy8gVnVlSlMgZmlsZXMgYXJlIHZhbGlkIEhUTUwgZmlsZXMsIHdlIHdpbGwgb3BlcmF0ZSB3aXRoIHRoZSBET00gaGVyZQogICAgICAgICRkb20gPSBzdGF0aWM6OmNvbnZlcnRIdG1sVG9Eb20oJHN0cmluZyk7CgogICAgICAgICRzY3JpcHQgPSBzdGF0aWM6OmV4dHJhY3RTY3JpcHRUYWcoJHN0cmluZyk7CgogICAgICAgIC8vIFBhcnNlIHRoZSBzY3JpcHQgcGFydCBhcyBhIHJlZ3VsYXIgSlMgY29kZQogICAgICAgIGlmICgkc2NyaXB0KSB7CiAgICAgICAgICAgICRzY3JpcHRMaW5lTnVtYmVyID0gJGRvbS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpLT5pdGVtKDApLT5nZXRMaW5lTm8oKTsKICAgICAgICAgICAgc3RhdGljOjpnZXRTY3JpcHRUcmFuc2xhdGlvbnNGcm9tU3RyaW5nKAogICAgICAgICAgICAgICAgJHNjcmlwdCwKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbnMsCiAgICAgICAgICAgICAgICAkb3B0aW9ucywKICAgICAgICAgICAgICAgICRzY3JpcHRMaW5lTnVtYmVyIC0gMQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gVGVtcGxhdGUgcGFydCBpcyBwYXJzZWQgc2VwYXJhdGVseSwgYWxsIHZhcmlhYmxlcyB3aWxsIGJlIGV4dHJhY3RlZAogICAgICAgIC8vIGFuZCBoYW5kbGVkIGFzIGEgcmVndWxhciBKUyBjb2RlCiAgICAgICAgJHRlbXBsYXRlID0gJGRvbS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RlbXBsYXRlJyktPml0ZW0oMCk7CiAgICAgICAgaWYgKCR0ZW1wbGF0ZSkgewogICAgICAgICAgICBzdGF0aWM6OmdldFRlbXBsYXRlVHJhbnNsYXRpb25zKAogICAgICAgICAgICAgICAgJHRlbXBsYXRlLAogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9ucywKICAgICAgICAgICAgICAgICRvcHRpb25zLAogICAgICAgICAgICAgICAgJHRlbXBsYXRlLT5nZXRMaW5lTm8oKSAtIDEKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0cyBzY3JpcHQgdGFnIGNvbnRlbnRzIHVzaW5nIHJlZ2V4IGluc3RlYWQgb2YgRE9NIG9wZXJhdGlvbnMuCiAgICAgKiBJZiB3ZSBwYXJzZSB1c2luZyBET00sIHNvbWUgY29udGVudHMgbWF5IGNoYW5nZSwgZm9yIGV4YW1wbGUsIHRhZ3Mgd2l0aGluIHN0cmluZ3Mgd2lsbCBiZSBzdHJpcHBlZAogICAgICoKICAgICAqIEBwYXJhbSAkc3RyaW5nCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdFNjcmlwdFRhZygkc3RyaW5nKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcjPFxzKj9zY3JpcHRcYltePl0qPiguKj8pPC9zY3JpcHRcYltePl0qPiNzJywgJHN0cmluZywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGh0bWwKICAgICAqIEByZXR1cm4gRE9NRG9jdW1lbnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0SHRtbFRvRG9tKCRodG1sKQogICAgewogICAgICAgICRkb20gPSBuZXcgRE9NRG9jdW1lbnQ7CgogICAgICAgIGxpYnhtbF91c2VfaW50ZXJuYWxfZXJyb3JzKHRydWUpOwoKICAgICAgICAvLyBQcmVwZW5kIHhtbCBlbmNvZGluZyBzbyBET01Eb2N1bWVudCBkb2N1bWVudCBoYW5kbGVzIFVURjggY29ycmVjdGx5LgogICAgICAgIC8vIEFzc3VtaW5nIHRoYXQgdnVlIHRlbXBsYXRlIGZpbGVzIHdpbGwgbm90IGhhdmUgYW55IHhtbCBlbmNvZGluZyB0YWdzLCBiZWNhdXNlIGR1cGxpY2F0ZSB0YWdzIG1heSBiZSBpZ25vcmVkLgogICAgICAgICRkb20tPmxvYWRIVE1MKCc8P3htbCBlbmNvZGluZz0idXRmLTgiPz4nIC4gJGh0bWwpOwoKICAgICAgICBsaWJ4bWxfY2xlYXJfZXJyb3JzKCk7CgogICAgICAgIHJldHVybiAkZG9tOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCB0cmFuc2xhdGlvbnMgZnJvbSBzY3JpcHQgcGFydAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNjcmlwdENvbnRlbnRzIE9ubHkgc2NyaXB0IHRhZyBjb250ZW50cywgbm90IHRoZSB3aG9sZSB0ZW1wbGF0ZQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uc3xUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zIE9uZSBvciBtdWx0aXBsZSBkb21haW4gVHJhbnNsYXRpb24gb2JqZWN0cwogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lT2Zmc2V0IE51bWJlciBvZiBsaW5lcyB0aGUgc2NyaXB0IGlzIG9mZnNldCBpbiB0aGUgdnVlIHRlbXBsYXRlIGZpbGUKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0U2NyaXB0VHJhbnNsYXRpb25zRnJvbVN0cmluZygKICAgICAgICAkc2NyaXB0Q29udGVudHMsCiAgICAgICAgJHRyYW5zbGF0aW9ucywKICAgICAgICBhcnJheSAkb3B0aW9ucyA9IFtdLAogICAgICAgICRsaW5lT2Zmc2V0ID0gMAogICAgKSB7CiAgICAgICAgLyoqIEB2YXIgRnVuY3Rpb25zU2Nhbm5lciAkZnVuY3Rpb25zICovCiAgICAgICAgJGZ1bmN0aW9ucyA9IG5ldyBzdGF0aWM6OiRmdW5jdGlvbnNTY2FubmVyQ2xhc3MoJHNjcmlwdENvbnRlbnRzKTsKICAgICAgICAkb3B0aW9uc1snbGluZU9mZnNldCddID0gJGxpbmVPZmZzZXQ7CiAgICAgICAgJGZ1bmN0aW9ucy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2UgdGVtcGxhdGUgdG8gZXh0cmFjdCBhbGwgdHJhbnNsYXRpb25zIChlbGVtZW50IGNvbnRlbnQgYW5kIGR5bmFtaWMgZWxlbWVudCBhdHRyaWJ1dGVzKQogICAgICoKICAgICAqIEBwYXJhbSBET01Ob2RlICRkb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnN8VHJhbnNsYXRpb25zW10gJHRyYW5zbGF0aW9ucyBPbmUgb3IgbXVsdGlwbGUgZG9tYWluIFRyYW5zbGF0aW9uIG9iamVjdHMKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICogQHBhcmFtIGludCAkbGluZU9mZnNldCBMaW5lIG51bWJlciB3aGVyZSB0aGUgdGVtcGxhdGUgcGFydCBzdGFydHMgaW4gdGhlIHZ1ZSBmaWxlCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldFRlbXBsYXRlVHJhbnNsYXRpb25zKAogICAgICAgIERPTU5vZGUgJGRvbSwKICAgICAgICAkdHJhbnNsYXRpb25zLAogICAgICAgIGFycmF5ICRvcHRpb25zLAogICAgICAgICRsaW5lT2Zmc2V0ID0gMAogICAgKSB7CiAgICAgICAgLy8gQnVpbGQgYSBKUyBzdHJpbmcgZnJvbSBhbGwgdGVtcGxhdGUgYXR0cmlidXRlIGV4cHJlc3Npb25zCiAgICAgICAgJGZha2VBdHRyaWJ1dGVKcyA9IHN0YXRpYzo6Z2V0VGVtcGxhdGVBdHRyaWJ1dGVGYWtlSnMoJG9wdGlvbnMsICRkb20pOwoKICAgICAgICAvLyAxIGxpbmUgb2Zmc2V0IGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHBhcmVudCB0ZW1wbGF0ZSBlbGVtZW50IHdhcyBpZ25vcmVkIHdoZW4gY29udmVydGluZyB0byBET00KICAgICAgICBzdGF0aWM6OmdldFNjcmlwdFRyYW5zbGF0aW9uc0Zyb21TdHJpbmcoJGZha2VBdHRyaWJ1dGVKcywgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMsICRsaW5lT2Zmc2V0KTsKCiAgICAgICAgLy8gQnVpbGQgYSBKUyBzdHJpbmcgZnJvbSB0ZW1wbGF0ZSBlbGVtZW50IGNvbnRlbnQgZXhwcmVzc2lvbnMKICAgICAgICAkZmFrZVRlbXBsYXRlSnMgPSBzdGF0aWM6OmdldFRlbXBsYXRlRmFrZUpzKCRkb20pOwogICAgICAgIHN0YXRpYzo6Z2V0U2NyaXB0VHJhbnNsYXRpb25zRnJvbVN0cmluZygkZmFrZVRlbXBsYXRlSnMsICR0cmFuc2xhdGlvbnMsICRvcHRpb25zLCAkbGluZU9mZnNldCk7CgogICAgICAgIHN0YXRpYzo6Z2V0VGFnVHJhbnNsYXRpb25zKCRvcHRpb25zLCAkZG9tLCAkdHJhbnNsYXRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICogQHBhcmFtIERPTU5vZGUgJGRvbQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uc3xUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0VGFnVHJhbnNsYXRpb25zKGFycmF5ICRvcHRpb25zLCBET01Ob2RlICRkb20sICR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgLy8gU2luY2UgdGFnIHNjYW5uaW5nIGRvZXMgbm90IHN1cHBvcnQgZG9tYWlucywgd2UgYWx3YXlzIHVzZSB0aGUgZmlyc3QgdHJhbnNsYXRpb24gZ2l2ZW4KICAgICAgICAkdHJhbnNsYXRpb25zID0gaXNfYXJyYXkoJHRyYW5zbGF0aW9ucykgPyByZXNldCgkdHJhbnNsYXRpb25zKSA6ICR0cmFuc2xhdGlvbnM7CgogICAgICAgICRjaGlsZHJlbiA9ICRkb20tPmNoaWxkTm9kZXM7CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGNoaWxkcmVuLT5sZW5ndGg7ICRpKyspIHsKICAgICAgICAgICAgJG5vZGUgPSAkY2hpbGRyZW4tPml0ZW0oJGkpOwoKICAgICAgICAgICAgaWYgKCEoJG5vZGUgaW5zdGFuY2VvZiBET01FbGVtZW50KSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0cmFuc2xhdGFibGUgPSBmYWxzZTsKCiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkbm9kZS0+dGFnTmFtZSwgJG9wdGlvbnNbJ3RhZ05hbWVzJ10sIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkdHJhbnNsYXRhYmxlID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGF0dHJMaXN0ID0gJG5vZGUtPmF0dHJpYnV0ZXM7CiAgICAgICAgICAgICRjb250ZXh0ID0gbnVsbDsKICAgICAgICAgICAgJHBsdXJhbCA9ICIiOwogICAgICAgICAgICAkY29tbWVudCA9IG51bGw7CgogICAgICAgICAgICBmb3IgKCRqID0gMDsgJGogPCAkYXR0ckxpc3QtPmxlbmd0aDsgJGorKykgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgRE9NQXR0ciAkZG9tQXR0ciAqLwogICAgICAgICAgICAgICAgJGRvbUF0dHIgPSAkYXR0ckxpc3QtPml0ZW0oJGopOwogICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGR5bmFtaWMgdnVlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRkb21BdHRyLT5uYW1lLCAkb3B0aW9uc1sndGFnQXR0cmlidXRlcyddKSkgewogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGFibGUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRkb21BdHRyLT5uYW1lLCAkb3B0aW9uc1snY29udGV4dEF0dHJpYnV0ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29udGV4dCA9ICRkb21BdHRyLT52YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkZG9tQXR0ci0+bmFtZSwgJG9wdGlvbnNbJ3BsdXJhbEF0dHJpYnV0ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGx1cmFsID0gJGRvbUF0dHItPnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRkb21BdHRyLT5uYW1lLCAkb3B0aW9uc1snY29tbWVudEF0dHJpYnV0ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29tbWVudCA9ICRkb21BdHRyLT52YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGFibGUpIHsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgdHJpbSgkbm9kZS0+dGV4dENvbnRlbnQpLCAkcGx1cmFsKTsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCRvcHRpb25zWydmaWxlJ10sICRub2RlLT5nZXRMaW5lTm8oKSk7CiAgICAgICAgICAgICAgICBpZiAoJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoJGNvbW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG5vZGUtPmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAgICAgc3RhdGljOjpnZXRUYWdUcmFuc2xhdGlvbnMoJG9wdGlvbnMsICRub2RlLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgSlMgZXhwcmVzc2lvbnMgZnJvbSBlbGVtZW50IGF0dHJpYnV0ZSBiaW5kaW5ncyAoZXhjbHVkaW5nIHRleHQgd2l0aGluIGVsZW1lbnRzKQogICAgICogRm9yIGV4YW1wbGU6IDxzcGFuIDp0aXRsZT0iX18oJ2V4dHJhY3QgdGhpcycpIj4gc2tpcCBlbGVtZW50IGNvbnRlbnQgPC9zcGFuPgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICogQHBhcmFtIERPTU5vZGUgJGRvbQogICAgICogQHJldHVybiBzdHJpbmcgSlMgY29kZQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldFRlbXBsYXRlQXR0cmlidXRlRmFrZUpzKGFycmF5ICRvcHRpb25zLCBET01Ob2RlICRkb20pCiAgICB7CiAgICAgICAgJGV4cHJlc3Npb25zQnlMaW5lID0gc3RhdGljOjpnZXRWdWVBdHRyaWJ1dGVFeHByZXNzaW9ucygkb3B0aW9uc1snYXR0cmlidXRlUHJlZml4ZXMnXSwgJGRvbSk7CgogICAgICAgIGlmIChlbXB0eSgkZXhwcmVzc2lvbnNCeUxpbmUpKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgICRtYXhMaW5lcyA9IG1heChhcnJheV9rZXlzKCRleHByZXNzaW9uc0J5TGluZSkpOwogICAgICAgICRmYWtlSnMgPSAnJzsKCiAgICAgICAgZm9yICgkbGluZSA9IDE7ICRsaW5lIDw9ICRtYXhMaW5lczsgJGxpbmUrKykgewogICAgICAgICAgICBpZiAoaXNzZXQoJGV4cHJlc3Npb25zQnlMaW5lWyRsaW5lXSkpIHsKICAgICAgICAgICAgICAgICRmYWtlSnMgLj0gaW1wbG9kZSgiOyAiLCAkZXhwcmVzc2lvbnNCeUxpbmVbJGxpbmVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZmFrZUpzIC49ICJcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZha2VKczsKICAgIH0KCiAgICAvKioKICAgICAqIExvb3AgRE9NIGVsZW1lbnQgcmVjdXJzaXZlbHkgYW5kIHBhcnNlIG91dCBhbGwgZHluYW1pYyB2dWUgYXR0cmlidXRlcyB3aGljaCBhcmUgYmFzaWNhbGx5IEpTIGV4cHJlc3Npb25zCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhdHRyaWJ1dGVQcmVmaXhlcyBMaXN0IG9mIGF0dHJpYnV0ZSBwcmVmaXhlcyB3ZSBwYXJzZSBhcyBKUyAobWF5IGNvbnRhaW4gdHJhbnNsYXRpb25zKQogICAgICogQHBhcmFtIERPTU5vZGUgJGRvbQogICAgICogQHBhcmFtIGFycmF5ICRleHByZXNzaW9uQnlMaW5lIFtsaW5lTnVtYmVyID0+IFtqc0V4cHJlc3Npb24sIC4uXSwgLi5dCiAgICAgKiBAcmV0dXJuIGFycmF5IFtsaW5lTnVtYmVyID0+IFtqc0V4cHJlc3Npb24sIC4uXSwgLi5dCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0VnVlQXR0cmlidXRlRXhwcmVzc2lvbnMoCiAgICAgICAgYXJyYXkgJGF0dHJpYnV0ZVByZWZpeGVzLAogICAgICAgIERPTU5vZGUgJGRvbSwKICAgICAgICBhcnJheSAmJGV4cHJlc3Npb25CeUxpbmUgPSBbXQogICAgKSB7CiAgICAgICAgJGNoaWxkcmVuID0gJGRvbS0+Y2hpbGROb2RlczsKCiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGNoaWxkcmVuLT5sZW5ndGg7ICRpKyspIHsKICAgICAgICAgICAgJG5vZGUgPSAkY2hpbGRyZW4tPml0ZW0oJGkpOwoKICAgICAgICAgICAgaWYgKCEoJG5vZGUgaW5zdGFuY2VvZiBET01FbGVtZW50KSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGF0dHJMaXN0ID0gJG5vZGUtPmF0dHJpYnV0ZXM7CgogICAgICAgICAgICBmb3IgKCRqID0gMDsgJGogPCAkYXR0ckxpc3QtPmxlbmd0aDsgJGorKykgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgRE9NQXR0ciAkZG9tQXR0ciAqLwogICAgICAgICAgICAgICAgJGRvbUF0dHIgPSAkYXR0ckxpc3QtPml0ZW0oJGopOwoKICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBkeW5hbWljIHZ1ZSBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgIGlmIChzdGF0aWM6OmlzQXR0cmlidXRlTWF0Y2hpbmcoJGRvbUF0dHItPm5hbWUsICRhdHRyaWJ1dGVQcmVmaXhlcykpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9ICRkb21BdHRyLT5nZXRMaW5lTm8oKTsKICAgICAgICAgICAgICAgICAgICAkZXhwcmVzc2lvbkJ5TGluZSArPSBbJGxpbmUgPT4gW11dOwogICAgICAgICAgICAgICAgICAgICRleHByZXNzaW9uQnlMaW5lWyRsaW5lXVtdID0gJGRvbUF0dHItPnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG5vZGUtPmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAgICAgJGV4cHJlc3Npb25CeUxpbmUgPSBzdGF0aWM6OmdldFZ1ZUF0dHJpYnV0ZUV4cHJlc3Npb25zKCRhdHRyaWJ1dGVQcmVmaXhlcywgJG5vZGUsICRleHByZXNzaW9uQnlMaW5lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRleHByZXNzaW9uQnlMaW5lOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgdGhpcyBhdHRyaWJ1dGUgbmFtZSBzaG91bGQgYmUgcGFyc2VkIGZvciB0cmFuc2xhdGlvbnMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhdHRyaWJ1dGVOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGF0dHJpYnV0ZVByZWZpeGVzCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBpc0F0dHJpYnV0ZU1hdGNoaW5nKCRhdHRyaWJ1dGVOYW1lLCAkYXR0cmlidXRlUHJlZml4ZXMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGF0dHJpYnV0ZVByZWZpeGVzIGFzICRwcmVmaXgpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygkYXR0cmlidXRlTmFtZSwgJHByZWZpeCkgPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgSlMgZXhwcmVzc2lvbnMgZnJvbSB3aXRoaW4gdGVtcGxhdGUgZWxlbWVudHMgKGV4Y2x1ZGluZyBhdHRyaWJ1dGVzKQogICAgICogRm9yIGV4YW1wbGU6IDxzcGFuIDp0aXRsZT0ic2tpcCBhdHRyaWJ1dGVzIj4ge3tfXygiZXh0cmFjdCBlbGVtZW50IGNvbnRlbnQiKX19IDwvc3Bhbj4KICAgICAqCiAgICAgKiBAcGFyYW0gRE9NTm9kZSAkZG9tCiAgICAgKiBAcmV0dXJuIHN0cmluZyBKUyBjb2RlCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0VGVtcGxhdGVGYWtlSnMoRE9NTm9kZSAkZG9tKQogICAgewogICAgICAgICRmYWtlSnMgPSAnJzsKICAgICAgICAkbGluZXMgPSBleHBsb2RlKCJcbiIsICRkb20tPnRleHRDb250ZW50KTsKCiAgICAgICAgLy8gQnVpbGQgYSBmYWtlIEpTIGZpbGUgZnJvbSB0ZW1wbGF0ZSBieSBleHRyYWN0aW5nIEpTIGV4cHJlc3Npb25zIHdpdGhpbiBlYWNoIHRlbXBsYXRlIGxpbmUKICAgICAgICBmb3JlYWNoICgkbGluZXMgYXMgJGxpbmUpIHsKICAgICAgICAgICAgJGV4cHJlc3Npb25NYXRjaGVkID0gc3RhdGljOjpwYXJzZU9uZVRlbXBsYXRlTGluZSgkbGluZSk7CgogICAgICAgICAgICAkZmFrZUpzIC49IGltcGxvZGUoIjsgIiwgJGV4cHJlc3Npb25NYXRjaGVkKSAuICJcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZha2VKczsKICAgIH0KCiAgICAvKioKICAgICAqIE1hdGNoIEpTIGV4cHJlc3Npb25zIGluIGEgdGVtcGxhdGUgbGluZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBwYXJzZU9uZVRlbXBsYXRlTGluZSgkbGluZSkKICAgIHsKICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwoKICAgICAgICBpZiAoISRsaW5lKSB7CiAgICAgICAgICAgIHJldHVybiBbXTsKICAgICAgICB9CgogICAgICAgICRyZWdleCA9ICcjXHtceyguKj8pXH1cfSMnOwoKICAgICAgICBwcmVnX21hdGNoX2FsbCgkcmVnZXgsICRsaW5lLCAkbWF0Y2hlcyk7CgogICAgICAgICRtYXRjaGVkID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkdikgewogICAgICAgICAgICByZXR1cm4gdHJpbSgkdiwgJ1wnInt9Jyk7CiAgICAgICAgfSwgJG1hdGNoZXNbMV0pOwoKICAgICAgICByZXR1cm4gJG1hdGNoZWQ7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgppbnRlcmZhY2UgRXh0cmFjdG9yTXVsdGlJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdHJpbmcgYW5kIGFwcGVuZCB0aGUgdHJhbnNsYXRpb25zIGZvdW5kIGluIHRoZSBUcmFuc2xhdGlvbnMgaW5zdGFuY2UuCiAgICAgKiBBbGxvd3Mgc2Nhbm5pbmcgZm9yIG11bHRpcGxlIGRvbWFpbnMgYXQgYSB0aW1lIChlYWNoIFRyYW5zbGF0aW9uIGhhcyB0byBoYXZlIGEgZGlmZmVyZW50IGRvbWFpbikKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgYXJyYXkgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdHJpbmcgYW5kIGFwcGVuZCB0aGUgdHJhbnNsYXRpb25zIGZvdW5kIGluIHRoZSBUcmFuc2xhdGlvbnMgaW5zdGFuY2UuCiAgICAgKiBBbGxvd3Mgc2Nhbm5pbmcgZm9yIG11bHRpcGxlIGRvbWFpbnMgYXQgYSB0aW1lIChlYWNoIFRyYW5zbGF0aW9uIGhhcyB0byBoYXZlIGEgZGlmZmVyZW50IGRvbWFpbikKICAgICAqCiAgICAgKiBAcGFyYW0gJGZpbGUKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tRmlsZU11bHRpcGxlKCRmaWxlLCBhcnJheSAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20ganNvbiBmaWxlcy4KICovCmNsYXNzIEplZCBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIHN0YXRpYzo6ZXh0cmFjdChqc29uX2RlY29kZSgkc3RyaW5nLCB0cnVlKSwgJHRyYW5zbGF0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBIYW5kbGUgYW4gYXJyYXkgb2YgdHJhbnNsYXRpb25zIGFuZCBhcHBlbmQgdG8gdGhlIFRyYW5zbGF0aW9ucyBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRjb250ZW50CiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0KGFycmF5ICRjb250ZW50LCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucykKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBjdXJyZW50KCRjb250ZW50KTsKICAgICAgICAkaGVhZGVycyA9IGlzc2V0KCRtZXNzYWdlc1snJ10pID8gJG1lc3NhZ2VzWycnXSA6IG51bGw7CiAgICAgICAgdW5zZXQoJG1lc3NhZ2VzWycnXSk7CgogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcnNbJ2RvbWFpbiddKSkgewogICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXREb21haW4oJGhlYWRlcnNbJ2RvbWFpbiddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcnNbJ2xhbmcnXSkpIHsKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+c2V0TGFuZ3VhZ2UoJGhlYWRlcnNbJ2xhbmcnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRoZWFkZXJzWydwbHVyYWwtZm9ybXMnXSkpIHsKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+c2V0SGVhZGVyKFRyYW5zbGF0aW9uczo6SEVBREVSX1BMVVJBTCwgJGhlYWRlcnNbJ3BsdXJhbC1mb3JtcyddKTsKICAgICAgICB9CgogICAgICAgICRjb250ZXh0X2dsdWUgPSAnXHUwMDA0JzsKCiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzIGFzICRrZXkgPT4gJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgICRrZXkgPSBleHBsb2RlKCRjb250ZXh0X2dsdWUsICRrZXkpOwogICAgICAgICAgICAkY29udGV4dCA9IGlzc2V0KCRrZXlbMV0pID8gYXJyYXlfc2hpZnQoJGtleSkgOiAnJzsKCiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgYXJyYXlfc2hpZnQoJGtleSkpCiAgICAgICAgICAgICAgICAtPnNldFRyYW5zbGF0aW9uKGFycmF5X3NoaWZ0KCR0cmFuc2xhdGlvbikpCiAgICAgICAgICAgICAgICAtPnNldFBsdXJhbFRyYW5zbGF0aW9ucygkdHJhbnNsYXRpb24pOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBTaW1wbGVYTUxFbGVtZW50OwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSB4bGlmZiBmb3JtYXQuCiAqLwpjbGFzcyBYbGlmZiBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAndW5pdGlkX2FzX2lkJyA9PiBmYWxzZQogICAgXTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgICR4bWwgPSBuZXcgU2ltcGxlWE1MRWxlbWVudCgkc3RyaW5nLCBudWxsLCBmYWxzZSk7CgogICAgICAgIGZvcmVhY2ggKCR4bWwtPmZpbGUgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRmaWxlLT5ub3RlcykpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRmaWxlLT5ub3Rlcy0+bm90ZSBhcyAkbm90ZSkgewogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPnNldEhlYWRlcigkbm90ZVsnaWQnXSwgKHN0cmluZykgJG5vdGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkZmlsZS0+dW5pdCBhcyAkdW5pdCkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVuaXQtPnNlZ21lbnQgYXMgJHNlZ21lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0cyA9IFtdOwoKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkc2VnbWVudC0+dGFyZ2V0IGFzICR0YXJnZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRhcmdldHNbXSA9IChzdHJpbmcpICR0YXJnZXQ7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb25zLT5jcmVhdGVOZXdUcmFuc2xhdGlvbihudWxsLCAoc3RyaW5nKSAkc2VnbWVudC0+c291cmNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHVuaXRbJ2lkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR1bml0SWQgPSAoc3RyaW5nKSAkdW5pdFsnaWQnXTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5hZGRDb21tZW50KCJYTElGRl9VTklUX0lEOiAkdW5pdElkIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkb3B0aW9uc1sndW5pdGlkX2FzX2lkJ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0SWQoJHVuaXRJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRUcmFuc2xhdGlvbihhcnJheV9zaGlmdCgkdGFyZ2V0cykpOwogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0UGx1cmFsVHJhbnNsYXRpb25zKCR0YXJnZXRzKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR1bml0LT5ub3RlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVuaXQtPm5vdGVzLT5ub3RlIGFzICRub3RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCRub3RlWydjYXRlZ29yeSddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnY29udGV4dCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbi0+Z2V0Q2xvbmUoKHN0cmluZykgJG5vdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZXh0cmFjdGVkLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoKHN0cmluZykgJG5vdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZmxhZyc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkRmxhZygoc3RyaW5nKSAkbm90ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdyZWZlcmVuY2UnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVmID0gZXhwbG9kZSgnOicsIChzdHJpbmcpICRub3RlLCAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5hZGRSZWZlcmVuY2UoJHJlZlswXSwgaXNzZXQoJHJlZlsxXSkgPyAkcmVmWzFdIDogbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZENvbW1lbnQoKHN0cmluZykgJG5vdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uc1tdID0gJHRyYW5zbGF0aW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xGdW5jdGlvbnNTY2FubmVyOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSBqYXZhc2NyaXB0IGZpbGVzLgogKi8KY2xhc3MgSnNDb2RlIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlLCBFeHRyYWN0b3JNdWx0aUludGVyZmFjZQp7CiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdjb25zdGFudHMnID0+IFtdLAoKICAgICAgICAnZnVuY3Rpb25zJyA9PiBbCiAgICAgICAgICAgICdnZXR0ZXh0JyA9PiAnZ2V0dGV4dCcsCiAgICAgICAgICAgICdfXycgPT4gJ2dldHRleHQnLAogICAgICAgICAgICAnbmdldHRleHQnID0+ICduZ2V0dGV4dCcsCiAgICAgICAgICAgICduX18nID0+ICduZ2V0dGV4dCcsCiAgICAgICAgICAgICdwZ2V0dGV4dCcgPT4gJ3BnZXR0ZXh0JywKICAgICAgICAgICAgJ3BfXycgPT4gJ3BnZXR0ZXh0JywKICAgICAgICAgICAgJ2RnZXR0ZXh0JyA9PiAnZGdldHRleHQnLAogICAgICAgICAgICAnZF9fJyA9PiAnZGdldHRleHQnLAogICAgICAgICAgICAnZG5nZXR0ZXh0JyA9PiAnZG5nZXR0ZXh0JywKICAgICAgICAgICAgJ2RuX18nID0+ICdkbmdldHRleHQnLAogICAgICAgICAgICAnZHBnZXR0ZXh0JyA9PiAnZHBnZXR0ZXh0JywKICAgICAgICAgICAgJ2RwX18nID0+ICdkcGdldHRleHQnLAogICAgICAgICAgICAnbnBnZXR0ZXh0JyA9PiAnbnBnZXR0ZXh0JywKICAgICAgICAgICAgJ25wX18nID0+ICducGdldHRleHQnLAogICAgICAgICAgICAnZG5wZ2V0dGV4dCcgPT4gJ2RucGdldHRleHQnLAogICAgICAgICAgICAnZG5wX18nID0+ICdkbnBnZXR0ZXh0JywKICAgICAgICAgICAgJ25vb3AnID0+ICdub29wJywKICAgICAgICAgICAgJ25vb3BfXycgPT4gJ25vb3AnLAogICAgICAgIF0sCiAgICBdOwoKICAgIHByb3RlY3RlZCBzdGF0aWMgJGZ1bmN0aW9uc1NjYW5uZXJDbGFzcyA9ICdHZXR0ZXh0XFV0aWxzXEpzRnVuY3Rpb25zU2Nhbm5lcic7CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdGRvYwogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIHN0YXRpYzo6ZnJvbVN0cmluZ011bHRpcGxlKCRzdHJpbmcsIFskdHJhbnNsYXRpb25zXSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZ011bHRpcGxlKCRzdHJpbmcsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgLyoqIEB2YXIgRnVuY3Rpb25zU2Nhbm5lciAkZnVuY3Rpb25zICovCiAgICAgICAgJGZ1bmN0aW9ucyA9IG5ldyBzdGF0aWM6OiRmdW5jdGlvbnNTY2FubmVyQ2xhc3MoJHN0cmluZyk7CiAgICAgICAgJGZ1bmN0aW9ucy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUZpbGVNdWx0aXBsZSgkZmlsZSwgYXJyYXkgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICBmb3JlYWNoIChzdGF0aWM6OmdldEZpbGVzKCRmaWxlKSBhcyAkZmlsZSkgewogICAgICAgICAgICAkb3B0aW9uc1snZmlsZSddID0gJGZpbGU7CiAgICAgICAgICAgIHN0YXRpYzo6ZnJvbVN0cmluZ011bHRpcGxlKHN0YXRpYzo6cmVhZEZpbGUoJGZpbGUpLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xTdHJpbmdSZWFkZXI7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIC5tbyBmaWxlcy4KICovCmNsYXNzIE1vIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIGNvbnN0IE1BR0lDMSA9IC0xNzk0ODk1MTM4OwogICAgY29uc3QgTUFHSUMyID0gLTU2OTI0NDUyMzsKICAgIGNvbnN0IE1BR0lDMyA9IDI1MDAwNzIxNTg7CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkc3RyaW5nUmVhZGVyQ2xhc3MgPSAnR2V0dGV4dFxVdGlsc1xTdHJpbmdSZWFkZXInOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgLyoqIEB2YXIgU3RyaW5nUmVhZGVyICRzdHJlYW0gKi8KICAgICAgICAkc3RyZWFtID0gbmV3IHN0YXRpYzo6JHN0cmluZ1JlYWRlckNsYXNzKCRzdHJpbmcpOwogICAgICAgICRtYWdpYyA9IHN0YXRpYzo6cmVhZEludCgkc3RyZWFtLCAnVicpOwoKICAgICAgICBpZiAoKCRtYWdpYyA9PT0gc3RhdGljOjpNQUdJQzEpIHx8ICgkbWFnaWMgPT09IHN0YXRpYzo6TUFHSUMzKSkgeyAvL3RvIG1ha2Ugc3VyZSBpdCB3b3JrcyBmb3IgNjQtYml0IHBsYXRmb3JtcwogICAgICAgICAgICAkYnl0ZU9yZGVyID0gJ1YnOyAvL2xvdyBlbmRpYW4KICAgICAgICB9IGVsc2VpZiAoJG1hZ2ljID09PSAoc3RhdGljOjpNQUdJQzIgJiAweEZGRkZGRkZGKSkgewogICAgICAgICAgICAkYnl0ZU9yZGVyID0gJ04nOyAvL2JpZyBlbmRpYW4KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdOb3QgTU8gZmlsZScpOwogICAgICAgIH0KCiAgICAgICAgc3RhdGljOjpyZWFkSW50KCRzdHJlYW0sICRieXRlT3JkZXIpOwoKICAgICAgICAkdG90YWwgPSBzdGF0aWM6OnJlYWRJbnQoJHN0cmVhbSwgJGJ5dGVPcmRlcik7IC8vdG90YWwgc3RyaW5nIGNvdW50CiAgICAgICAgJG9yaWdpbmFscyA9IHN0YXRpYzo6cmVhZEludCgkc3RyZWFtLCAkYnl0ZU9yZGVyKTsgLy9vZmZzZXQgb2Ygb3JpZ2luYWwgdGFibGUKICAgICAgICAkdHJhbiA9IHN0YXRpYzo6cmVhZEludCgkc3RyZWFtLCAkYnl0ZU9yZGVyKTsgLy9vZmZzZXQgb2YgdHJhbnNsYXRpb24gdGFibGUKCiAgICAgICAgJHN0cmVhbS0+c2Vla3RvKCRvcmlnaW5hbHMpOwogICAgICAgICR0YWJsZV9vcmlnaW5hbHMgPSBzdGF0aWM6OnJlYWRJbnRBcnJheSgkc3RyZWFtLCAkYnl0ZU9yZGVyLCAkdG90YWwgKiAyKTsKCiAgICAgICAgJHN0cmVhbS0+c2Vla3RvKCR0cmFuKTsKICAgICAgICAkdGFibGVfdHJhbnNsYXRpb25zID0gc3RhdGljOjpyZWFkSW50QXJyYXkoJHN0cmVhbSwgJGJ5dGVPcmRlciwgJHRvdGFsICogMik7CgogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICR0b3RhbDsgKyskaSkgewogICAgICAgICAgICAkbmV4dCA9ICRpICogMjsKCiAgICAgICAgICAgICRzdHJlYW0tPnNlZWt0bygkdGFibGVfb3JpZ2luYWxzWyRuZXh0ICsgMl0pOwogICAgICAgICAgICAkb3JpZ2luYWwgPSAkc3RyZWFtLT5yZWFkKCR0YWJsZV9vcmlnaW5hbHNbJG5leHQgKyAxXSk7CgogICAgICAgICAgICAkc3RyZWFtLT5zZWVrdG8oJHRhYmxlX3RyYW5zbGF0aW9uc1skbmV4dCArIDJdKTsKICAgICAgICAgICAgJHRyYW5zbGF0ZWQgPSAkc3RyZWFtLT5yZWFkKCR0YWJsZV90cmFuc2xhdGlvbnNbJG5leHQgKyAxXSk7CgogICAgICAgICAgICBpZiAoJG9yaWdpbmFsID09PSAnJykgewogICAgICAgICAgICAgICAgLy8gSGVhZGVycwogICAgICAgICAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgiXG4iLCAkdHJhbnNsYXRlZCkgYXMgJGhlYWRlckxpbmUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGhlYWRlckxpbmUgPT09ICcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGhlYWRlckNodW5rcyA9IHByZWdfc3BsaXQoJy86XHMqLycsICRoZWFkZXJMaW5lLCAyKTsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoJGhlYWRlckNodW5rc1swXSwgaXNzZXQoJGhlYWRlckNodW5rc1sxXSkgPyAkaGVhZGVyQ2h1bmtzWzFdIDogJycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2h1bmtzID0gZXhwbG9kZSgiXHgwNCIsICRvcmlnaW5hbCwgMik7CgogICAgICAgICAgICBpZiAoaXNzZXQoJGNodW5rc1sxXSkpIHsKICAgICAgICAgICAgICAgICRjb250ZXh0ID0gJGNodW5rc1swXTsKICAgICAgICAgICAgICAgICRvcmlnaW5hbCA9ICRjaHVua3NbMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29udGV4dCA9ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2h1bmtzID0gZXhwbG9kZSgiXHgwMCIsICRvcmlnaW5hbCwgMik7CgogICAgICAgICAgICBpZiAoaXNzZXQoJGNodW5rc1sxXSkpIHsKICAgICAgICAgICAgICAgICRvcmlnaW5hbCA9ICRjaHVua3NbMF07CiAgICAgICAgICAgICAgICAkcGx1cmFsID0gJGNodW5rc1sxXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwbHVyYWwgPSAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwpOwoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGVkID09PSAnJykgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkcGx1cmFsID09PSAnJykgewogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRUcmFuc2xhdGlvbigkdHJhbnNsYXRlZCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHYgPSBleHBsb2RlKCJceDAwIiwgJHRyYW5zbGF0ZWQpOwogICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFRyYW5zbGF0aW9uKGFycmF5X3NoaWZ0KCR2KSk7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0UGx1cmFsVHJhbnNsYXRpb25zKCR2KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gU3RyaW5nUmVhZGVyICRzdHJlYW0KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGJ5dGVPcmRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHJlYWRJbnQoU3RyaW5nUmVhZGVyICRzdHJlYW0sICRieXRlT3JkZXIpCiAgICB7CiAgICAgICAgaWYgKCgkcmVhZCA9ICRzdHJlYW0tPnJlYWQoNCkpID09PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcmVhZCA9IHVucGFjaygkYnl0ZU9yZGVyLCAkcmVhZCk7CgogICAgICAgIHJldHVybiBhcnJheV9zaGlmdCgkcmVhZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gU3RyaW5nUmVhZGVyICRzdHJlYW0KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGJ5dGVPcmRlcgogICAgICogQHBhcmFtIGludCAgICAgICAgICAkY291bnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiByZWFkSW50QXJyYXkoU3RyaW5nUmVhZGVyICRzdHJlYW0sICRieXRlT3JkZXIsICRjb3VudCkKICAgIHsKICAgICAgICByZXR1cm4gdW5wYWNrKCRieXRlT3JkZXIuJGNvdW50LCAkc3RyZWFtLT5yZWFkKDQgKiAkY291bnQpKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcSGVhZGVyc0V4dHJhY3RvclRyYWl0Owp1c2UgR2V0dGV4dFxVdGlsc1xDc3ZUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gY3N2LgogKi8KY2xhc3MgQ3N2IGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBIZWFkZXJzRXh0cmFjdG9yVHJhaXQ7CiAgICB1c2UgQ3N2VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnZGVsaW1pdGVyJyA9PiAiLCIsCiAgICAgICAgJ2VuY2xvc3VyZScgPT4gJyInLAogICAgICAgICdlc2NhcGVfY2hhcicgPT4gIlxcIgogICAgXTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CiAgICAgICAgJGhhbmRsZSA9IGZvcGVuKCdwaHA6Ly9tZW1vcnknLCAndycpOwoKICAgICAgICBmcHV0cygkaGFuZGxlLCAkc3RyaW5nKTsKICAgICAgICByZXdpbmQoJGhhbmRsZSk7CgogICAgICAgIHdoaWxlICgkcm93ID0gc3RhdGljOjpmZ2V0Y3N2KCRoYW5kbGUsICRvcHRpb25zKSkgewogICAgICAgICAgICAkY29udGV4dCA9IGFycmF5X3NoaWZ0KCRyb3cpOwogICAgICAgICAgICAkb3JpZ2luYWwgPSBhcnJheV9zaGlmdCgkcm93KTsKCiAgICAgICAgICAgIGlmICgkY29udGV4dCA9PT0gJycgJiYgJG9yaWdpbmFsID09PSAnJykgewogICAgICAgICAgICAgICAgc3RhdGljOjpleHRyYWN0SGVhZGVycyhhcnJheV9zaGlmdCgkcm93KSwgJHRyYW5zbGF0aW9ucyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCRjb250ZXh0LCAkb3JpZ2luYWwpOwoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkcm93KSkgewogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRUcmFuc2xhdGlvbihhcnJheV9zaGlmdCgkcm93KSk7CiAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFBsdXJhbFRyYW5zbGF0aW9ucygkcm93KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZmNsb3NlKCRoYW5kbGUpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20ganNvbi4KICovCmNsYXNzIEpzb24gZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgdXNlIE11bHRpZGltZW5zaW9uYWxBcnJheVRyYWl0OwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG1lc3NhZ2VzID0ganNvbl9kZWNvZGUoJHN0cmluZywgdHJ1ZSk7CgogICAgICAgIGlmIChpc19hcnJheSgkbWVzc2FnZXMpKSB7CiAgICAgICAgICAgIHN0YXRpYzo6ZnJvbUFycmF5KCRtZXNzYWdlcywgJHRyYW5zbGF0aW9ucyk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xGdW5jdGlvbnNTY2FubmVyOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSBwaHAgZmlsZXMgcmV0dXJuaW5nIGFycmF5cy4KICovCmNsYXNzIFBocENvZGUgZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UsIEV4dHJhY3Rvck11bHRpSW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgLy8gLSBmYWxzZTogdG8gbm90IGV4dHJhY3QgY29tbWVudHMKICAgICAgICAvLyAtIGVtcHR5IHN0cmluZzogdG8gZXh0cmFjdCBhbGwgY29tbWVudHMKICAgICAgICAvLyAtIG5vbi1lbXB0eSBzdHJpbmc6IHRvIGV4dHJhY3QgY29tbWVudHMgdGhhdCBzdGFydCB3aXRoIHRoYXQgc3RyaW5nCiAgICAgICAgLy8gLSBhcnJheSB3aXRoIHN0cmluZ3MgdG8gZXh0cmFjdCBjb21tZW50cyBmb3JtYXQuCiAgICAgICAgJ2V4dHJhY3RDb21tZW50cycgPT4gZmFsc2UsCgogICAgICAgICdjb25zdGFudHMnID0+IFtdLAoKICAgICAgICAnZnVuY3Rpb25zJyA9PiBbCiAgICAgICAgICAgICdnZXR0ZXh0JyA9PiAnZ2V0dGV4dCcsCiAgICAgICAgICAgICdfXycgPT4gJ2dldHRleHQnLAogICAgICAgICAgICAnbmdldHRleHQnID0+ICduZ2V0dGV4dCcsCiAgICAgICAgICAgICduX18nID0+ICduZ2V0dGV4dCcsCiAgICAgICAgICAgICdwZ2V0dGV4dCcgPT4gJ3BnZXR0ZXh0JywKICAgICAgICAgICAgJ3BfXycgPT4gJ3BnZXR0ZXh0JywKICAgICAgICAgICAgJ2RnZXR0ZXh0JyA9PiAnZGdldHRleHQnLAogICAgICAgICAgICAnZF9fJyA9PiAnZGdldHRleHQnLAogICAgICAgICAgICAnZG5nZXR0ZXh0JyA9PiAnZG5nZXR0ZXh0JywKICAgICAgICAgICAgJ2RuX18nID0+ICdkbmdldHRleHQnLAogICAgICAgICAgICAnZHBnZXR0ZXh0JyA9PiAnZHBnZXR0ZXh0JywKICAgICAgICAgICAgJ2RwX18nID0+ICdkcGdldHRleHQnLAogICAgICAgICAgICAnbnBnZXR0ZXh0JyA9PiAnbnBnZXR0ZXh0JywKICAgICAgICAgICAgJ25wX18nID0+ICducGdldHRleHQnLAogICAgICAgICAgICAnZG5wZ2V0dGV4dCcgPT4gJ2RucGdldHRleHQnLAogICAgICAgICAgICAnZG5wX18nID0+ICdkbnBnZXR0ZXh0JywKICAgICAgICAgICAgJ25vb3AnID0+ICdub29wJywKICAgICAgICAgICAgJ25vb3BfXycgPT4gJ25vb3AnLAogICAgICAgIF0sCiAgICBdOwoKICAgIHByb3RlY3RlZCBzdGF0aWMgJGZ1bmN0aW9uc1NjYW5uZXJDbGFzcyA9ICdHZXR0ZXh0XFV0aWxzXFBocEZ1bmN0aW9uc1NjYW5uZXInOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIHN0YXRpYzo6ZnJvbVN0cmluZ011bHRpcGxlKCRzdHJpbmcsIFskdHJhbnNsYXRpb25zXSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZ011bHRpcGxlKCRzdHJpbmcsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgLyoqIEB2YXIgRnVuY3Rpb25zU2Nhbm5lciAkZnVuY3Rpb25zICovCiAgICAgICAgJGZ1bmN0aW9ucyA9IG5ldyBzdGF0aWM6OiRmdW5jdGlvbnNTY2FubmVyQ2xhc3MoJHN0cmluZyk7CgogICAgICAgIGlmICgkb3B0aW9uc1snZXh0cmFjdENvbW1lbnRzJ10gIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRmdW5jdGlvbnMtPmVuYWJsZUNvbW1lbnRzRXh0cmFjdGlvbigkb3B0aW9uc1snZXh0cmFjdENvbW1lbnRzJ10pOwogICAgICAgIH0KCiAgICAgICAgJGZ1bmN0aW9ucy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQGluaGVyaXREb2MKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tRmlsZU11bHRpcGxlKCRmaWxlLCBhcnJheSAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGZvcmVhY2ggKHN0YXRpYzo6Z2V0RmlsZXMoJGZpbGUpIGFzICRmaWxlKSB7CiAgICAgICAgICAgICRvcHRpb25zWydmaWxlJ10gPSAkZmlsZTsKICAgICAgICAgICAgc3RhdGljOjpmcm9tU3RyaW5nTXVsdGlwbGUoc3RhdGljOjpyZWFkRmlsZSgkZmlsZSksICR0cmFuc2xhdGlvbnMsICRvcHRpb25zKTsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogRGVjb2RlcyBhIFRfQ09OU1RBTlRfRU5DQVBTRURfU1RSSU5HIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29udmVydFN0cmluZygkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkdmFsdWUsICdcXCcpID09PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gc3Vic3RyKCR2YWx1ZSwgMSwgLTEpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR2YWx1ZVswXSA9PT0gIiciKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJ0cihzdWJzdHIoJHZhbHVlLCAxLCAtMSksIFsnXFxcXCcgPT4gJ1xcJywgJ1xcXCcnID0+ICdcJyddKTsKICAgICAgICB9CgogICAgICAgICR2YWx1ZSA9IHN1YnN0cigkdmFsdWUsIDEsIC0xKTsKCiAgICAgICAgcmV0dXJuIHByZWdfcmVwbGFjZV9jYWxsYmFjaygKICAgICAgICAgICAgJy9cXFwobnxyfHR8dnxlfGZ8XCR8InxcXFx8eFswLTlBLUZhLWZdezEsMn18dXtbMC05YS1mXXsxLDZ9fXxbMC03XXsxLDN9KS8nLAogICAgICAgICAgICBmdW5jdGlvbiAoJG1hdGNoKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCRtYXRjaFsxXVswXSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJ24nOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxuIjsKICAgICAgICAgICAgICAgICAgICBjYXNlICdyJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcciI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXHQiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlx2IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICdlJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcZSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXGYiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJyQnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJyQnOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJyInOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJyInOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ1xcJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdcXCc7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAneCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaHIoaGV4ZGVjKHN1YnN0cigkbWF0Y2hbMV0sIDEpKSk7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndSc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGF0aWM6OnVuaWNvZGVDaGFyKGhleGRlYyhzdWJzdHIoJG1hdGNoWzFdLCAxKSkpOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaHIob2N0ZGVjKCRtYXRjaFsxXSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAkdmFsdWUKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICRkZWMKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqIEBzZWUgaHR0cDovL3BocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmNoci5waHAjMTE4ODA0CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdW5pY29kZUNoYXIoJGRlYykKICAgIHsKICAgICAgICBpZiAoJGRlYyA8IDB4ODApIHsKICAgICAgICAgICAgcmV0dXJuIGNocigkZGVjKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZGVjIDwgMHgwODAwKSB7CiAgICAgICAgICAgIHJldHVybiBjaHIoMHhDMCArICgkZGVjID4+IDYpKQogICAgICAgICAgICAgICAgLiBjaHIoMHg4MCArICgkZGVjICYgMHgzZikpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRkZWMgPCAweDAxMDAwMCkgewogICAgICAgICAgICByZXR1cm4gY2hyKDB4RTAgKyAoJGRlYyA+PiAxMikpCiAgICAgICAgICAgICAgICAuIGNocigweDgwICsgKCgkZGVjID4+IDYpICYgMHgzZikpCiAgICAgICAgICAgICAgICAuIGNocigweDgwICsgKCRkZWMgJiAweDNmKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRlYyA8IDB4MjAwMDAwKSB7CiAgICAgICAgICAgIHJldHVybiBjaHIoMHhGMCArICgkZGVjID4+IDE4KSkKICAgICAgICAgICAgICAgIC4gY2hyKDB4ODAgKyAoKCRkZWMgPj4gMTIpICYgMHgzZikpCiAgICAgICAgICAgICAgICAuIGNocigweDgwICsgKCgkZGVjID4+IDYpICYgMHgzZikpCiAgICAgICAgICAgICAgICAuIGNocigweDgwICsgKCRkZWMgJiAweDNmKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIElsbHVtaW5hdGVcRmlsZXN5c3RlbVxGaWxlc3lzdGVtOwp1c2UgSWxsdW1pbmF0ZVxWaWV3XENvbXBpbGVyc1xCbGFkZUNvbXBpbGVyOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSBibGFkZS5waHAgZmlsZXMgcmV0dXJuaW5nIGFycmF5cy4KICovCmNsYXNzIEJsYWRlIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRvcHRpb25zWydmYWNhZGUnXSkpIHsKICAgICAgICAgICAgJGNhY2hlUGF0aCA9IGVtcHR5KCRvcHRpb25zWydjYWNoZVBhdGgnXSkgPyBzeXNfZ2V0X3RlbXBfZGlyKCkgOiAkb3B0aW9uc1snY2FjaGVQYXRoJ107CiAgICAgICAgICAgICRibGFkZUNvbXBpbGVyID0gbmV3IEJsYWRlQ29tcGlsZXIobmV3IEZpbGVzeXN0ZW0oKSwgJGNhY2hlUGF0aCk7CgogICAgICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkYmxhZGVDb21waWxlciwgJ3dpdGhvdXRDb21wb25lbnRUYWdzJykpIHsKICAgICAgICAgICAgICAgICRibGFkZUNvbXBpbGVyLT53aXRob3V0Q29tcG9uZW50VGFncygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkc3RyaW5nID0gJGJsYWRlQ29tcGlsZXItPmNvbXBpbGVTdHJpbmcoJHN0cmluZyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHN0cmluZyA9ICRvcHRpb25zWydmYWNhZGUnXTo6Y29tcGlsZVN0cmluZygkc3RyaW5nKTsKICAgICAgICB9CgogICAgICAgIFBocENvZGU6OmZyb21TdHJpbmcoJHN0cmluZywgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xEaWN0aW9uYXJ5VHJhaXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxZYW1sXFlhbWwgYXMgWWFtbFBhcnNlcjsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20geWFtbC4KICovCmNsYXNzIFlhbWxEaWN0aW9uYXJ5IGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBZYW1sUGFyc2VyOjpwYXJzZSgkc3RyaW5nKTsKCiAgICAgICAgaWYgKGlzX2FycmF5KCRtZXNzYWdlcykpIHsKICAgICAgICAgICAgc3RhdGljOjpmcm9tQXJyYXkoJG1lc3NhZ2VzLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgRXhjZXB0aW9uOwp1c2UgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgphYnN0cmFjdCBjbGFzcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUZpbGUoJGZpbGUsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGZvcmVhY2ggKHN0YXRpYzo6Z2V0RmlsZXMoJGZpbGUpIGFzICRmaWxlKSB7CiAgICAgICAgICAgICRvcHRpb25zWydmaWxlJ10gPSAkZmlsZTsKICAgICAgICAgICAgc3RhdGljOjpmcm9tU3RyaW5nKHN0YXRpYzo6cmVhZEZpbGUoJGZpbGUpLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGFuZCByZXR1cm5zIGFsbCBmaWxlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRmaWxlIFRoZSBmaWxlL3MKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBmaWxlIHBhdGhzCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0RmlsZXMoJGZpbGUpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRmaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGVyZSBpcyBub3QgYW55IGZpbGUgZGVmaW5lZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX3N0cmluZygkZmlsZSkpIHsKICAgICAgICAgICAgaWYgKCFpc19maWxlKCRmaWxlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiJyRmaWxlJyBpcyBub3QgYSB2YWxpZCBmaWxlIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNfcmVhZGFibGUoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCInJGZpbGUnIGlzIG5vdCBhIHJlYWRhYmxlIGZpbGUiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFskZmlsZV07CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfYXJyYXkoJGZpbGUpKSB7CiAgICAgICAgICAgICRmaWxlcyA9IFtdOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGZpbGUgYXMgJGYpIHsKICAgICAgICAgICAgICAgICRmaWxlcyA9IGFycmF5X21lcmdlKCRmaWxlcywgc3RhdGljOjpnZXRGaWxlcygkZikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGZpbGVzOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgc3RyaW5nIG9yIGFycmF5Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkcyBhbmQgcmV0dXJucyB0aGUgY29udGVudCBvZiBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcmVhZEZpbGUoJGZpbGUpCiAgICB7CiAgICAgICAgJGxlbmd0aCA9IGZpbGVzaXplKCRmaWxlKTsKCiAgICAgICAgaWYgKCEoJGZkID0gZm9wZW4oJGZpbGUsICdyYicpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW5ub3QgcmVhZCB0aGUgZmlsZSAnJGZpbGUnLCBwcm9iYWJseSBwZXJtaXNzaW9ucyIpOwogICAgICAgIH0KCiAgICAgICAgJGNvbnRlbnQgPSAkbGVuZ3RoID8gZnJlYWQoJGZkLCAkbGVuZ3RoKSA6ICcnOwogICAgICAgIGZjbG9zZSgkZmQpOwoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXE11bHRpZGltZW5zaW9uYWxBcnJheVRyYWl0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcWWFtbFxZYW1sIGFzIFlhbWxQYXJzZXI7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIHlhbWwuCiAqLwpjbGFzcyBZYW1sIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IFlhbWxQYXJzZXI6OnBhcnNlKCRzdHJpbmcpOwoKICAgICAgICBpZiAoaXNfYXJyYXkoJG1lc3NhZ2VzKSkgewogICAgICAgICAgICBzdGF0aWM6OmZyb21BcnJheSgkbWVzc2FnZXMsICR0cmFuc2xhdGlvbnMpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gcGhwIGZpbGVzIHJldHVybmluZyBhcnJheXMuCiAqLwpjbGFzcyBQbyBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICB1c2UgSGVhZGVyc0V4dHJhY3RvclRyYWl0OwoKICAgIC8qKgogICAgICogUGFyc2VzIGEgLnBvIGZpbGUgYW5kIGFwcGVuZCB0aGUgdHJhbnNsYXRpb25zIGZvdW5kIGluIHRoZSBUcmFuc2xhdGlvbnMgaW5zdGFuY2UuCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJGxpbmVzID0gZXhwbG9kZSgiXG4iLCAkc3RyaW5nKTsKICAgICAgICAkaSA9IDA7CgogICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmNyZWF0ZU5ld1RyYW5zbGF0aW9uKCcnLCAnJyk7CgogICAgICAgIGZvciAoJG4gPSBjb3VudCgkbGluZXMpOyAkaSA8ICRuOyArKyRpKSB7CiAgICAgICAgICAgICRsaW5lID0gdHJpbSgkbGluZXNbJGldKTsKICAgICAgICAgICAgJGxpbmUgPSBzdGF0aWM6OmZpeE11bHRpTGluZXMoJGxpbmUsICRsaW5lcywgJGkpOwoKICAgICAgICAgICAgaWYgKCRsaW5lID09PSAnJykgewogICAgICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aXMoJycsICcnKSkgewogICAgICAgICAgICAgICAgICAgIHN0YXRpYzo6ZXh0cmFjdEhlYWRlcnMoJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkdHJhbnNsYXRpb24tPmhhc09yaWdpbmFsKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25zW10gPSAkdHJhbnNsYXRpb247CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+Y3JlYXRlTmV3VHJhbnNsYXRpb24oJycsICcnKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkc3BsaXRMaW5lID0gcHJlZ19zcGxpdCgnL1xzKy8nLCAkbGluZSwgMik7CiAgICAgICAgICAgICRrZXkgPSAkc3BsaXRMaW5lWzBdOwogICAgICAgICAgICAkZGF0YSA9IGlzc2V0KCRzcGxpdExpbmVbMV0pID8gJHNwbGl0TGluZVsxXSA6ICcnOwoKICAgICAgICAgICAgaWYgKCRrZXkgPT09ICcjficpIHsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0RGlzYWJsZWQodHJ1ZSk7CgogICAgICAgICAgICAgICAgJHNwbGl0TGluZSA9IHByZWdfc3BsaXQoJy9ccysvJywgJGRhdGEsIDIpOwogICAgICAgICAgICAgICAgJGtleSA9ICRzcGxpdExpbmVbMF07CiAgICAgICAgICAgICAgICAkZGF0YSA9IGlzc2V0KCRzcGxpdExpbmVbMV0pID8gJHNwbGl0TGluZVsxXSA6ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKCRrZXkpIHsKICAgICAgICAgICAgICAgIGNhc2UgJyMnOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkQ29tbWVudCgkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIy4nOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkRXh0cmFjdGVkQ29tbWVudCgkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIywnOgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJywnLCB0cmltKCRkYXRhKSkpIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZEZsYWcoJHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIzonOgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHByZWdfc3BsaXQoJy9ccysvJywgdHJpbSgkZGF0YSkpIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oLispKDooXGQqKSk/JC9VJywgJHZhbHVlLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCRtYXRjaGVzWzFdLCBpc3NldCgkbWF0Y2hlc1szXSkgPyAkbWF0Y2hlc1szXSA6IG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRhcHBlbmQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ21zZ2N0eHQnOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbi0+Z2V0Q2xvbmUoc3RhdGljOjpjb252ZXJ0U3RyaW5nKCRkYXRhKSk7CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9ICdDb250ZXh0JzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtc2dpZCc6CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uLT5nZXRDbG9uZShudWxsLCBzdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGRhdGEpKTsKICAgICAgICAgICAgICAgICAgICAkYXBwZW5kID0gJ09yaWdpbmFsJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtc2dpZF9wbHVyYWwnOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0UGx1cmFsKHN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICRhcHBlbmQgPSAnUGx1cmFsJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtc2dzdHInOgogICAgICAgICAgICAgICAgY2FzZSAnbXNnc3RyWzBdJzoKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFRyYW5zbGF0aW9uKHN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICRhcHBlbmQgPSAnVHJhbnNsYXRpb24nOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ21zZ3N0clsxXSc6CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoW3N0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSldKTsKICAgICAgICAgICAgICAgICAgICAkYXBwZW5kID0gJ1BsdXJhbFRyYW5zbGF0aW9uJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJGtleSwgJ21zZ3N0clsnKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkcCA9ICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwW10gPSBzdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGRhdGEpOwoKICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHApOwogICAgICAgICAgICAgICAgICAgICAgICAkYXBwZW5kID0gJ1BsdXJhbFRyYW5zbGF0aW9uJzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGFwcGVuZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRhcHBlbmQgPT09ICdDb250ZXh0JykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uLT5nZXRDbG9uZSgkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4iXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkYXBwZW5kID09PSAnT3JpZ2luYWwnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb24tPmdldENsb25lKG51bGwsICR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4iXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkYXBwZW5kID09PSAnUGx1cmFsVHJhbnNsYXRpb24nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcCA9ICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcFtdID0gYXJyYXlfcG9wKCRwKS4iXG4iLnN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFBsdXJhbFRyYW5zbGF0aW9ucygkcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGdldE1ldGhvZCA9ICdnZXQnLiRhcHBlbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICRzZXRNZXRob2QgPSAnc2V0Jy4kYXBwZW5kOwogICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPiRzZXRNZXRob2QoJHRyYW5zbGF0aW9uLT4kZ2V0TWV0aG9kKCkuIlxuIi5zdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGRhdGEpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc09yaWdpbmFsKCkgJiYgIWluX2FycmF5KCR0cmFuc2xhdGlvbiwgaXRlcmF0b3JfdG9fYXJyYXkoJHRyYW5zbGF0aW9ucykpKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnNbXSA9ICR0cmFuc2xhdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIG9uZSBzdHJpbmcgZnJvbSBtdWx0aWxpbmUgc3RyaW5ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lCiAgICAgKiBAcGFyYW0gYXJyYXkgICRsaW5lcwogICAgICogQHBhcmFtIGludCAgICAmJGkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZpeE11bHRpTGluZXMoJGxpbmUsIGFycmF5ICRsaW5lcywgJiRpKQogICAgewogICAgICAgIGZvciAoJGogPSAkaSwgJHQgPSBjb3VudCgkbGluZXMpOyAkaiA8ICR0OyArKyRqKSB7CiAgICAgICAgICAgIGlmIChzdWJzdHIoJGxpbmUsIC0xLCAxKSA9PSAnIicgJiYgaXNzZXQoJGxpbmVzWyRqICsgMV0pKSB7CiAgICAgICAgICAgICAgICAkbmV4dExpbmUgPSB0cmltKCRsaW5lc1skaiArIDFdKTsKICAgICAgICAgICAgICAgIGlmIChzdWJzdHIoJG5leHRMaW5lLCAwLCAxKSA9PSAnIicpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9IHN1YnN0cigkbGluZSwgMCwgLTEpLnN1YnN0cigkbmV4dExpbmUsIDEpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN1YnN0cigkbmV4dExpbmUsIDAsIDQpID09ICcjfiAiJykgewogICAgICAgICAgICAgICAgICAgICRsaW5lID0gc3Vic3RyKCRsaW5lLCAwLCAtMSkuc3Vic3RyKCRuZXh0TGluZSwgNCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGkgPSAkajsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxpbmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0IGEgc3RyaW5nIGZyb20gaXRzIFBPIHJlcHJlc2VudGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0U3RyaW5nKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoISR2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHZhbHVlWzBdID09PSAnIicpIHsKICAgICAgICAgICAgJHZhbHVlID0gc3Vic3RyKCR2YWx1ZSwgMSwgLTEpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0cnRyKAogICAgICAgICAgICAkdmFsdWUsCiAgICAgICAgICAgIFsKICAgICAgICAgICAgICAgICdcXFxcJyA9PiAnXFwnLAogICAgICAgICAgICAgICAgJ1xcYScgPT4gIlx4MDciLAogICAgICAgICAgICAgICAgJ1xcYicgPT4gIlx4MDgiLAogICAgICAgICAgICAgICAgJ1xcdCcgPT4gIlx0IiwKICAgICAgICAgICAgICAgICdcXG4nID0+ICJcbiIsCiAgICAgICAgICAgICAgICAnXFx2JyA9PiAiXHgwYiIsCiAgICAgICAgICAgICAgICAnXFxmJyA9PiAiXHgwYyIsCiAgICAgICAgICAgICAgICAnXFxyJyA9PiAiXHIiLAogICAgICAgICAgICAgICAgJ1xcIicgPT4gJyInLAogICAgICAgICAgICBdCiAgICAgICAgKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHQ7CgphYnN0cmFjdCBjbGFzcyBCYXNlVHJhbnNsYXRvciBpbXBsZW1lbnRzIFRyYW5zbGF0b3JJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgVHJhbnNsYXRvckludGVyZmFjZSAqLwogICAgcHVibGljIHN0YXRpYyAkY3VycmVudDsKCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm9vcCgkb3JpZ2luYWwpCiAgICB7CiAgICAgICAgcmV0dXJuICRvcmlnaW5hbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoKQogICAgewogICAgICAgICRwcmV2aW91cyA9IHN0YXRpYzo6JGN1cnJlbnQ7CgogICAgICAgIHN0YXRpYzo6JGN1cnJlbnQgPSAkdGhpczsKCiAgICAgICAgc3RhdGljOjppbmNsdWRlRnVuY3Rpb25zKCk7CgogICAgICAgIHJldHVybiAkcHJldmlvdXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbmNsdWRlIHRoZSBnZXR0ZXh0IGZ1bmN0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGluY2x1ZGVGdW5jdGlvbnMoKQogICAgewogICAgICAgIGluY2x1ZGVfb25jZSBfX0RJUl9fLicvdHJhbnNsYXRvcl9mdW5jdGlvbnMucGhwJzsKICAgIH0KfQo8P3BocAoKc3BsX2F1dG9sb2FkX3JlZ2lzdGVyKGZ1bmN0aW9uICgkY2xhc3MpIHsKICAgIGlmIChzdHJwb3MoJGNsYXNzLCAnR2V0dGV4dFxcJykgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgJGZpbGUgPSBfX0RJUl9fLnN0cl9yZXBsYWNlKCdcXCcsIERJUkVDVE9SWV9TRVBBUkFUT1IsIHN1YnN0cigkY2xhc3MsIHN0cmxlbignR2V0dGV4dCcpKSkuJy5waHAnOwoKICAgIGlmIChpc19maWxlKCRmaWxlKSkgewogICAgICAgIHJlcXVpcmVfb25jZSAkZmlsZTsKICAgIH0KfSk7Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXM7Cgp1c2UgRXhjZXB0aW9uOwoKLyoqCiAqIEhvbGRzIHRoZSBDTERSIGRhdGEuCiAqLwpjbGFzcyBDbGRyRGF0YQp7CiAgICAvKioKICAgICAqIFN1cGVyLXNwZWNpYWwgcGx1cmFsIGNhdGVnb3J5OiB0aGlzIHNob3VsZCBhbHdheXMgYmUgcHJlc2VudCBmb3IgYW55IGxhbmd1YWdlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IE9USEVSX0NBVEVHT1JZID0gJ290aGVyJzsKCiAgICAvKioKICAgICAqIFRoZSBsaXN0IG9mIHRoZSBwbHVyYWwgY2F0ZWdvcmllcywgc29ydGVkIGZyb20gJ3plcm8nIHRvICdvdGhlcicuCiAgICAgKgogICAgICogQHZhciBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljICRjYXRlZ29yaWVzID0gYXJyYXkoJ3plcm8nLCAnb25lJywgJ3R3bycsICdmZXcnLCAnbWFueScsIHNlbGY6Ok9USEVSX0NBVEVHT1JZKTsKCiAgICAvKioKICAgICAqIFRoZSBsb2FkZWQgQ0xEUiBkYXRhLgogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGRhdGE7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRwbHVyYWxzOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyB0aGUgbGFuZ3VhZ2UgbmFtZXMuCiAgICAgKiBUaGUga2V5cyBhcmUgdGhlIGxhbmd1YWdlIGlkZW50aWZpZXJzLgogICAgICogVGhlIHZhbHVlcyBhcmUgdGhlIGxhbmd1YWdlIG5hbWVzIGluIFVTIEVuZ2xpc2guCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldExhbmd1YWdlTmFtZXMoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpnZXREYXRhKCdsYW5ndWFnZXMnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIGRpY3Rpb25hcnkgY29udGFpbmluZyB0aGUgdGVycml0b3J5IG5hbWVzIChpbiBVUyBFbmdsaXNoKS4KICAgICAqIFRoZSBrZXlzIGFyZSB0aGUgdGVycml0b3J5IGlkZW50aWZpZXJzLgogICAgICogVGhlIHZhbHVlcyBhcmUgdGhlIHRlcnJpdG9yeSBuYW1lcyBpbiBVUyBFbmdsaXNoLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRUZXJyaXRvcnlOYW1lcygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmdldERhdGEoJ3RlcnJpdG9yaWVzJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBkaWN0aW9uYXJ5IGNvbnRhaW5pbmcgdGhlIHNjcmlwdCBuYW1lcyAoaW4gVVMgRW5nbGlzaCkuCiAgICAgKiBUaGUga2V5cyBhcmUgdGhlIHNjcmlwdCBpZGVudGlmaWVycy4KICAgICAqIFRoZSB2YWx1ZXMgYXJlIHRoZSBzY3JpcHQgbmFtZXMgaW4gVVMgRW5nbGlzaC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkc3RhbmRBbG9uZSBzZXQgdG8gdHJ1ZSB0byByZXRyaWV2ZSB0aGUgc3RhbmQtYWxvbmUgc2NyaXB0IG5hbWVzLCBmYWxzZSBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0U2NyaXB0TmFtZXMoJHN0YW5kQWxvbmUpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmdldERhdGEoJHN0YW5kQWxvbmUgPyAnc3RhbmRBbG9uZVNjcmlwdHMnIDogJ3NjcmlwdHMnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEEgZGljdGlvbmFyeSBjb250YWluaW5nIHRoZSBwbHVyYWwgcnVsZXMuCiAgICAgKiBUaGUga2V5cyBhcmUgdGhlIGxhbmd1YWdlIGlkZW50aWZpZXJzLgogICAgICogVGhlIHZhbHVlcyBhcmUgYXJyYXlzIHdob3NlIGtleXMgYXJlIHRoZSBDTERSIGNhdGVnb3J5IG5hbWVzIGFuZCB0aGUgdmFsdWVzIGFyZSB0aGUgQ0xEUiBjYXRlZ29yeSBkZWZpbml0aW9uLgogICAgICoKICAgICAqIEBleGFtcGxlIFRoZSBFbmdsaXNoIGtleS12YWx1ZSBwYWlyIGlzIHNvbWV0aGluayBsaWtlIHRoaXM6CiAgICAgKiA8Y29kZT48cHJlPgogICAgICogImVuIjogewogICAgICogICAgICJwbHVyYWxSdWxlLWNvdW50LW9uZSI6ICJpID0gMSBhbmQgdiA9IDAgQGludGVnZXIgMSIsCiAgICAgKiAgICAgInBsdXJhbFJ1bGUtY291bnQtb3RoZXIiOiAiIEBpbnRlZ2VyIDAsIDJ+MTYsIDEwMCwgMTAwMCwgMTAwMDAsIDEwMDAwMCwgMTAwMDAwMCwg4oCmIEBkZWNpbWFsIDAuMH4xLjUsIDEwLjAsIDEwMC4wLCAxMDAwLjAsIDEwMDAwLjAsIDEwMDAwMC4wLCAxMDAwMDAwLjAsIOKApiIKICAgICAqIH0KICAgICAqIDwvcHJlPjwvY29kZT4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UGx1cmFscygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmdldERhdGEoJ3BsdXJhbHMnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIGxpc3Qgb2Ygc3VwZXJzZWRlZCBsYW5ndWFnZSBjb2Rlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IGtleXMgYXJlIHRoZSBmb3JtZXIgbGFuZ3VhZ2UgY29kZXMsIHZhbHVlcyBhcmUgdGhlIG5ldyBsYW5ndWFnZS9sb2NhbGUgY29kZXMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTdXBlcnNlZGVkTGFuZ3VhZ2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0RGF0YSgnc3VwZXJzZWRlZExhbmd1YWdlcycpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmUgdGhlIG5hbWUgb2YgYSBsYW5ndWFnZSwgYXMgd2VsbCBhcyBpZiBhIGxhbmd1YWdlIGNvZGUgaXMgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBhbm90aGVyIGxhbmd1YWdlIGNvZGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgdGhlIGxhbmd1YWdlIGlkZW50aWZpZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwgUmV0dXJucyBhbiBhcnJheSB3aXRoIHRoZSBrZXlzICdpZCcgKG5vcm1hbGl6ZWQpLCAnbmFtZScsICdzdXBlcnNlZGVkQnknIChvcHRpb25hbCksICd0ZXJyaXRvcnknIChvcHRpb25hbCksICdzY3JpcHQnIChvcHRpb25hbCksICdiYXNlTGFuZ3VhZ2UnIChvcHRpb25hbCksICdjYXRlZ29yaWVzJy4gSWYgJGlkIGlzIG5vdCB2YWxpZCByZXR1cm5zIG51bGwuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0TGFuZ3VhZ2VJbmZvKCRpZCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gbnVsbDsKICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKFthLXpdezIsM30pKD86W19cLV0oW2Etel17NH0pKT8oPzpbX1wtXShbYS16XXsyfXxbMC05XXszfSkpPyg/OiR8LSkvaScsICRpZCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICRsYW5ndWFnZUlkID0gc3RydG9sb3dlcigkbWF0Y2hlc1sxXSk7CiAgICAgICAgICAgICRzY3JpcHRJZCA9IChpc3NldCgkbWF0Y2hlc1syXSkgJiYgKCRtYXRjaGVzWzJdICE9PSAnJykpID8gdWNmaXJzdChzdHJ0b2xvd2VyKCRtYXRjaGVzWzJdKSkgOiBudWxsOwogICAgICAgICAgICAkdGVycml0b3J5SWQgPSAoaXNzZXQoJG1hdGNoZXNbM10pICYmICgkbWF0Y2hlc1szXSAhPT0gJycpKSA/IHN0cnRvdXBwZXIoJG1hdGNoZXNbM10pIDogbnVsbDsKICAgICAgICAgICAgJG5vcm1hbGl6ZWRJZCA9ICRsYW5ndWFnZUlkOwogICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdElkKSkgewogICAgICAgICAgICAgICAgJG5vcm1hbGl6ZWRJZCAuPSAnXycgLiAkc2NyaXB0SWQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZXJyaXRvcnlJZCkpIHsKICAgICAgICAgICAgICAgICRub3JtYWxpemVkSWQgLj0gJ18nIC4gJHRlcnJpdG9yeUlkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFN0cnVjdHVyZSBwcmVjZWRlbmNlOiBzZWUgTGlrZWx5IFN1YnRhZ3MgLSBodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvdHIzNS90cjM1LTMxL3RyMzUuaHRtbCNMaWtlbHlfU3VidGFncwogICAgICAgICAgICAkdmFyaWFudHMgPSBhcnJheSgpOwogICAgICAgICAgICAkdmFyaWFudHNXaXRoU2NyaXB0ID0gYXJyYXkoKTsKICAgICAgICAgICAgJHZhcmlhbnRzV2l0aFRlcnJpdG9yeSA9IGFycmF5KCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkc2NyaXB0SWQpICYmIGlzc2V0KCR0ZXJyaXRvcnlJZCkpIHsKICAgICAgICAgICAgICAgICR2YXJpYW50c1dpdGhUZXJyaXRvcnlbXSA9ICR2YXJpYW50c1dpdGhTY3JpcHRbXSA9ICR2YXJpYW50c1tdID0gInskbGFuZ3VhZ2VJZH1feyRzY3JpcHRJZH1feyR0ZXJyaXRvcnlJZH0iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkc2NyaXB0SWQpKSB7CiAgICAgICAgICAgICAgICAkdmFyaWFudHNXaXRoU2NyaXB0W10gPSAkdmFyaWFudHNbXSA9ICJ7JGxhbmd1YWdlSWR9X3skc2NyaXB0SWR9IjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJHRlcnJpdG9yeUlkKSkgewogICAgICAgICAgICAgICAgJHZhcmlhbnRzV2l0aFRlcnJpdG9yeVtdID0gJHZhcmlhbnRzW10gPSAieyRsYW5ndWFnZUlkfV97JHRlcnJpdG9yeUlkfSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZhcmlhbnRzW10gPSAkbGFuZ3VhZ2VJZDsKICAgICAgICAgICAgJGFsbEdvb2QgPSB0cnVlOwogICAgICAgICAgICAkc2NyaXB0TmFtZSA9IG51bGw7CiAgICAgICAgICAgICRzY3JpcHRTdGFuZEFsb25lTmFtZSA9IG51bGw7CiAgICAgICAgICAgIGlmIChpc3NldCgkc2NyaXB0SWQpKSB7CiAgICAgICAgICAgICAgICAkc2NyaXB0TmFtZXMgPSBzZWxmOjpnZXRTY3JpcHROYW1lcyhmYWxzZSk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdE5hbWVzWyRzY3JpcHRJZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHNjcmlwdE5hbWUgPSAkc2NyaXB0TmFtZXNbJHNjcmlwdElkXTsKICAgICAgICAgICAgICAgICAgICAkc2NyaXB0U3RhbmRBbG9uZU5hbWVzID0gc2VsZjo6Z2V0U2NyaXB0TmFtZXModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgJHNjcmlwdFN0YW5kQWxvbmVOYW1lID0gJHNjcmlwdFN0YW5kQWxvbmVOYW1lc1skc2NyaXB0SWRdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkYWxsR29vZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0ZXJyaXRvcnlOYW1lID0gbnVsbDsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZXJyaXRvcnlJZCkpIHsKICAgICAgICAgICAgICAgICR0ZXJyaXRvcnlOYW1lcyA9IHNlbGY6OmdldFRlcnJpdG9yeU5hbWVzKCk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRlcnJpdG9yeU5hbWVzWyR0ZXJyaXRvcnlJZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0ZXJyaXRvcnlJZCAhPT0gJzAwMScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRlcnJpdG9yeU5hbWUgPSAkdGVycml0b3J5TmFtZXNbJHRlcnJpdG9yeUlkXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRhbGxHb29kID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxhbmd1YWdlTmFtZSA9IG51bGw7CiAgICAgICAgICAgICRsYW5ndWFnZU5hbWVzID0gc2VsZjo6Z2V0TGFuZ3VhZ2VOYW1lcygpOwogICAgICAgICAgICBmb3JlYWNoICgkdmFyaWFudHMgYXMgJHZhcmlhbnQpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbGFuZ3VhZ2VOYW1lc1skdmFyaWFudF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGxhbmd1YWdlTmFtZSA9ICRsYW5ndWFnZU5hbWVzWyR2YXJpYW50XTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdE5hbWUpICYmICghaW5fYXJyYXkoJHZhcmlhbnQsICR2YXJpYW50c1dpdGhTY3JpcHQpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGFuZ3VhZ2VOYW1lID0gJHNjcmlwdE5hbWUgLiAnICcgLiAkbGFuZ3VhZ2VOYW1lOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRlcnJpdG9yeU5hbWUpICYmICghaW5fYXJyYXkoJHZhcmlhbnQsICR2YXJpYW50c1dpdGhUZXJyaXRvcnkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGFuZ3VhZ2VOYW1lIC49ICcgKCcgLiAkdGVycml0b3J5TmFtZXNbJHRlcnJpdG9yeUlkXSAuICcpJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkbGFuZ3VhZ2VOYW1lKSkgewogICAgICAgICAgICAgICAgJGFsbEdvb2QgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkYmFzZUxhbmd1YWdlID0gbnVsbDsKICAgICAgICAgICAgaWYgKGlzc2V0KCRzY3JpcHRJZCkgfHwgaXNzZXQoJHRlcnJpdG9yeUlkKSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZU5hbWVzWyRsYW5ndWFnZUlkXSkgJiYgKCRsYW5ndWFnZU5hbWVzWyRsYW5ndWFnZUlkXSAhPT0gJGxhbmd1YWdlTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkYmFzZUxhbmd1YWdlID0gJGxhbmd1YWdlTmFtZXNbJGxhbmd1YWdlSWRdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRwbHVyYWwgPSBudWxsOwogICAgICAgICAgICAkcGx1cmFscyA9IHNlbGY6OmdldFBsdXJhbHMoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHZhcmlhbnRzIGFzICR2YXJpYW50KSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBsdXJhbHNbJHZhcmlhbnRdKSkgewogICAgICAgICAgICAgICAgICAgICRwbHVyYWwgPSAkcGx1cmFsc1skdmFyaWFudF07CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkcGx1cmFsKSkgewogICAgICAgICAgICAgICAgJGFsbEdvb2QgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc3VwZXJzZWRlZEJ5ID0gbnVsbDsKICAgICAgICAgICAgJHN1cGVyc2VkZWRCeXMgPSBzZWxmOjpnZXRTdXBlcnNlZGVkTGFuZ3VhZ2VzKCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR2YXJpYW50cyBhcyAkdmFyaWFudCkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzdXBlcnNlZGVkQnlzWyR2YXJpYW50XSkpIHsKICAgICAgICAgICAgICAgICAgICAkc3VwZXJzZWRlZEJ5ID0gJHN1cGVyc2VkZWRCeXNbJHZhcmlhbnRdOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkYWxsR29vZCkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAkcmVzdWx0WydpZCddID0gJG5vcm1hbGl6ZWRJZDsKICAgICAgICAgICAgICAgICRyZXN1bHRbJ25hbWUnXSA9ICRsYW5ndWFnZU5hbWU7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHN1cGVyc2VkZWRCeSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WydzdXBlcnNlZGVkQnknXSA9ICRzdXBlcnNlZGVkQnk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdFN0YW5kQWxvbmVOYW1lKSkgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJ3NjcmlwdCddID0gJHNjcmlwdFN0YW5kQWxvbmVOYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZXJyaXRvcnlOYW1lKSkgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJ3RlcnJpdG9yeSddID0gJHRlcnJpdG9yeU5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGJhc2VMYW5ndWFnZSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WydiYXNlTGFuZ3VhZ2UnXSA9ICRiYXNlTGFuZ3VhZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcmVzdWx0WydjYXRlZ29yaWVzJ10gPSAkcGx1cmFsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvYWRlZCBDTERSIGRhdGEuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5IENhbiBiZSAnbGFuZ3VhZ2VzJywgJ3RlcnJpdG9yaWVzJywgJ3BsdXJhbHMnLCAnc3VwZXJzZWRlZExhbmd1YWdlcycsICdzY3JpcHRzJywgJ3N0YW5kQWxvbmVTY3JpcHRzJwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0RGF0YSgka2V5KQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGRhdGEpKSB7CiAgICAgICAgICAgICRmaXhLZXlzID0gZnVuY3Rpb24gKCRsaXN0LCAmJHN0YW5kQWxvbmUgPSBudWxsKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICRzdGFuZEFsb25lID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICRtYXRjaCA9IG51bGw7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGlzdCBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICR2YXJpYW50ID0gJyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKC4rKS1hbHQtKHNob3J0fHZhcmlhbnR8c3RhbmQtYWxvbmV8bG9uZ3xtZW51KSQvJywgJGtleSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAka2V5ID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgICAgICAgICAkdmFyaWFudCA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGtleSA9IHN0cl9yZXBsYWNlKCctJywgJ18nLCAka2V5KTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCRrZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAncm9vdCc6IC8vIExhbmd1YWdlOiBSb290CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3VuZCc6IC8vIExhbmd1YWdlOiBVbmtub3duIExhbmd1YWdlCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3p4eCc6IC8vIExhbmd1YWdlOiBObyBsaW5ndWlzdGljIGNvbnRlbnQKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnWlonOiAvLyBUZXJyaXRvcnk6IFVua25vd24gUmVnaW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1ppbmgnOiAvLyBTY3JpcHQ6IEluaGVyaXRlZAogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdabXRoJzogLy8gU2NyaXB0OiBNYXRoZW1hdGljYWwgTm90YXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnWnN5bSc6IC8vIFNjcmlwdDogU3ltYm9scwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdaeHh4JzogLy8gU2NyaXB0OiBVbndyaXR0ZW4KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnWnl5eSc6IC8vIFNjcmlwdDogQ29tbW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1p6enonOiAvLyBTY3JpcHQ6IFVua25vd24gU2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJHZhcmlhbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzdGFuZC1hbG9uZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzdGFuZEFsb25lWyRrZXldID0gJHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WyRrZXldID0gJHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgJGRhdGEgPSBhcnJheSgpOwogICAgICAgICAgICAkanNvbiA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKF9fRElSX18gLiAnL2NsZHItZGF0YS9tYWluL2VuLVVTL2xhbmd1YWdlcy5qc29uJyksIHRydWUpOwogICAgICAgICAgICAkZGF0YVsnbGFuZ3VhZ2VzJ10gPSAkZml4S2V5cygkanNvblsnbWFpbiddWydlbi1VUyddWydsb2NhbGVEaXNwbGF5TmFtZXMnXVsnbGFuZ3VhZ2VzJ10pOwogICAgICAgICAgICAkanNvbiA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKF9fRElSX18gLiAnL2NsZHItZGF0YS9tYWluL2VuLVVTL3RlcnJpdG9yaWVzLmpzb24nKSwgdHJ1ZSk7CiAgICAgICAgICAgICRkYXRhWyd0ZXJyaXRvcmllcyddID0gJGZpeEtleXMoJGpzb25bJ21haW4nXVsnZW4tVVMnXVsnbG9jYWxlRGlzcGxheU5hbWVzJ11bJ3RlcnJpdG9yaWVzJ10pOwogICAgICAgICAgICAkanNvbiA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKF9fRElSX18gLiAnL2NsZHItZGF0YS9zdXBwbGVtZW50YWwvcGx1cmFscy5qc29uJyksIHRydWUpOwogICAgICAgICAgICAkZGF0YVsncGx1cmFscyddID0gJGZpeEtleXMoJGpzb25bJ3N1cHBsZW1lbnRhbCddWydwbHVyYWxzLXR5cGUtY2FyZGluYWwnXSk7CiAgICAgICAgICAgICRqc29uID0ganNvbl9kZWNvZGUoZmlsZV9nZXRfY29udGVudHMoX19ESVJfXyAuICcvY2xkci1kYXRhL21haW4vZW4tVVMvc2NyaXB0cy5qc29uJyksIHRydWUpOwogICAgICAgICAgICAkZGF0YVsnc2NyaXB0cyddID0gJGZpeEtleXMoJGpzb25bJ21haW4nXVsnZW4tVVMnXVsnbG9jYWxlRGlzcGxheU5hbWVzJ11bJ3NjcmlwdHMnXSwgJGRhdGFbJ3N0YW5kQWxvbmVTY3JpcHRzJ10pOwogICAgICAgICAgICAkZGF0YVsnc3RhbmRBbG9uZVNjcmlwdHMnXSA9IGFycmF5X21lcmdlKCRkYXRhWydzY3JpcHRzJ10sICRkYXRhWydzdGFuZEFsb25lU2NyaXB0cyddKTsKICAgICAgICAgICAgJGRhdGFbJ3NjcmlwdHMnXSA9IGFycmF5X21lcmdlKCRkYXRhWydzdGFuZEFsb25lU2NyaXB0cyddLCAkZGF0YVsnc2NyaXB0cyddKTsKICAgICAgICAgICAgJGRhdGFbJ3N1cGVyc2VkZWRMYW5ndWFnZXMnXSA9IGFycmF5KCk7CiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgbGFuZ3VhZ2VzIGZvciB3aGljaCB3ZSBkb24ndCBoYXZlIHBsdXJhbHMKICAgICAgICAgICAgJG0gPSBudWxsOwogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9rZXlzKGFycmF5X2RpZmZfa2V5KCRkYXRhWydsYW5ndWFnZXMnXSwgJGRhdGFbJ3BsdXJhbHMnXSkpIGFzICRtaXNzaW5nUGx1cmFsKSB7CiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oW2Etel17MiwzfSlfLycsICRtaXNzaW5nUGx1cmFsLCAkbSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWydwbHVyYWxzJ11bJG1bMV1dKSkgewogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkZGF0YVsnbGFuZ3VhZ2VzJ11bJG1pc3NpbmdQbHVyYWxdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRkYXRhWydsYW5ndWFnZXMnXVskbWlzc2luZ1BsdXJhbF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEZpeCB0aGUgbGFuZ3VhZ2VzIGZvciB3aGljaCB3ZSBoYXZlIHBsdXJhbHMKICAgICAgICAgICAgJGZvcm1lckNvZGVzID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnaW4nID0+ICdpZCcsIC8vIGZvcm1lciBJbmRvbmVzaWFuCiAgICAgICAgICAgICAgICAnaXcnID0+ICdoZScsIC8vIGZvcm1lciBIZWJyZXcKICAgICAgICAgICAgICAgICdqaScgPT4gJ3lpJywgLy8gZm9ybWVyIFlpZGRpc2gKICAgICAgICAgICAgICAgICdqdycgPT4gJ2p2JywgLy8gZm9ybWVyIEphdmFuZXNlCiAgICAgICAgICAgICAgICAnbW8nID0+ICdyb19NRCcsIC8vIGZvcm1lciBNb2xkYXZpYW4KICAgICAgICAgICAgKTsKICAgICAgICAgICAgJGtub3duTWlzc2luZ0xhbmd1YWdlcyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ2d1dycgPT4gJ0d1bicsCiAgICAgICAgICAgICAgICAnaG5qJyA9PiAnTW9uZyBOanVhJywKICAgICAgICAgICAgICAgICduYWgnID0+ICdOYWh1YXRsJywKICAgICAgICAgICAgICAgICdzbWknID0+ICdTYW1pJywKICAgICAgICAgICAgKTsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cyhhcnJheV9kaWZmX2tleSgkZGF0YVsncGx1cmFscyddLCAkZGF0YVsnbGFuZ3VhZ2VzJ10pKSBhcyAkbWlzc2luZ0xhbmd1YWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGZvcm1lckNvZGVzWyRtaXNzaW5nTGFuZ3VhZ2VdKSAmJiBpc3NldCgkZGF0YVsnbGFuZ3VhZ2VzJ11bJGZvcm1lckNvZGVzWyRtaXNzaW5nTGFuZ3VhZ2VdXSkpIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YVsnbGFuZ3VhZ2VzJ11bJG1pc3NpbmdMYW5ndWFnZV0gPSAkZGF0YVsnbGFuZ3VhZ2VzJ11bJGZvcm1lckNvZGVzWyRtaXNzaW5nTGFuZ3VhZ2VdXTsKICAgICAgICAgICAgICAgICAgICAkZGF0YVsnc3VwZXJzZWRlZExhbmd1YWdlcyddWyRtaXNzaW5nTGFuZ3VhZ2VdID0gJGZvcm1lckNvZGVzWyRtaXNzaW5nTGFuZ3VhZ2VdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGtub3duTWlzc2luZ0xhbmd1YWdlc1skbWlzc2luZ0xhbmd1YWdlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ2xhbmd1YWdlcyddWyRtaXNzaW5nTGFuZ3VhZ2VdID0gJGtub3duTWlzc2luZ0xhbmd1YWdlc1skbWlzc2luZ0xhbmd1YWdlXTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJXZSBoYXZlIHRoZSBwbHVyYWwgcnVsZSBmb3IgdGhlIGxhbmd1YWdlICd7JG1pc3NpbmdMYW5ndWFnZX0nIGJ1dCB3ZSBkb24ndCBoYXZlIGl0cyBsYW5ndWFnZSBuYW1lIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGtzb3J0KCRkYXRhWydsYW5ndWFnZXMnXSwgU09SVF9TVFJJTkcpOwogICAgICAgICAgICBrc29ydCgkZGF0YVsndGVycml0b3JpZXMnXSwgU09SVF9TVFJJTkcpOwogICAgICAgICAgICBrc29ydCgkZGF0YVsncGx1cmFscyddLCBTT1JUX1NUUklORyk7CiAgICAgICAgICAgIGtzb3J0KCRkYXRhWydzY3JpcHRzJ10sIFNPUlRfU1RSSU5HKTsKICAgICAgICAgICAga3NvcnQoJGRhdGFbJ3N0YW5kQWxvbmVTY3JpcHRzJ10sIFNPUlRfU1RSSU5HKTsKICAgICAgICAgICAga3NvcnQoJGRhdGFbJ3N1cGVyc2VkZWRMYW5ndWFnZXMnXSwgU09SVF9TVFJJTkcpOwogICAgICAgICAgICBzZWxmOjokZGF0YSA9ICRkYXRhOwogICAgICAgIH0KICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRkYXRhWyRrZXldKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJJbnZhbGlkIENMRFIgZGF0YSBrZXk6ICd7JGtleX0nIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGRhdGFbJGtleV07CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlczsKCnVzZSBFeGNlcHRpb247CgovKioKICogQSBoZWxwZXIgY2xhc3MgdGhhdCBoYW5kbGVzIGEgc2luZ2xlIGNhdGVnb3J5IHJ1bGVzIChlZyAnemVybycsICdvbmUnLCAuLi4pIGFuZCBpdHMgZm9ybXVsYSBhbmQgZXhhbXBsZXMuCiAqLwpjbGFzcyBDYXRlZ29yeQp7CiAgICAvKioKICAgICAqIFRoZSBjYXRlZ29yeSBpZGVudGlmaWVyIChlZyAnemVybycsICdvbmUnLCAuLi4sICdvdGhlcicpLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkaWQ7CgogICAgLyoqCiAgICAgKiBUaGUgZ2V0dGV4dCBmb3JtdWxhIHRoYXQgaWRlbnRpZmllcyB0aGlzIGNhdGVnb3J5IChudWxsIGlmIGFuZCBvbmx5IGlmIHRoZSBjYXRlZ29yeSBpcyAnb3RoZXInKS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyAkZm9ybXVsYTsKCiAgICAvKioKICAgICAqIFRoZSBDTERSIHJlcHJlc2VudGF0aW9uIG9mIHNvbWUgZXhlbXBsYXIgbnVtZXJpYyByYW5nZXMgdGhhdCBzYXRpc2Z5IHRoaXMgY2F0ZWdvcnkuCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgJGV4YW1wbGVzOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZSB0aGUgaW5zdGFuY2UgYW5kIHBhcnNlIHRoZSBmb3JtdWxhLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsZHJDYXRlZ29yeUlkIHRoZSBDTERSIGNhdGVnb3J5IGlkZW50aWZpZXIgKGVnICdwbHVyYWxSdWxlLWNvdW50LW9uZScpCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjbGRyRm9ybXVsYUFuZEV4YW1wbGVzIHRoZSBDTERSIGZvcm11bGEgYW5kIGV4YW1wbGVzIChlZyAnaSA9IDEgYW5kIHYgPSAwIEBpbnRlZ2VyIDEnKQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNsZHJDYXRlZ29yeUlkLCAkY2xkckZvcm11bGFBbmRFeGFtcGxlcykKICAgIHsKICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvXnBsdXJhbFJ1bGUtY291bnQtKC4rKSQvJywgJGNsZHJDYXRlZ29yeUlkLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBDTERSIGNhdGVnb3J5OiAneyRjbGRyQ2F0ZWdvcnlJZH0nIik7CiAgICAgICAgfQogICAgICAgIGlmICghaW5fYXJyYXkoJG1hdGNoZXNbMV0sIENsZHJEYXRhOjokY2F0ZWdvcmllcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBDTERSIGNhdGVnb3J5OiAneyRjbGRyQ2F0ZWdvcnlJZH0nIik7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5pZCA9ICRtYXRjaGVzWzFdOwogICAgICAgICRjbGRyRm9ybXVsYUFuZEV4YW1wbGVzTm9ybWFsaXplZCA9IHRyaW0ocHJlZ19yZXBsYWNlKCcvXHMrLycsICcgJywgJGNsZHJGb3JtdWxhQW5kRXhhbXBsZXMpKTsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9eKFteQF0qKSg/OkBpbnRlZ2VyKFteQF0rKSk/KD86QGRlY2ltYWwoPzpbXkBdKykpPyQvJywgJGNsZHJGb3JtdWxhQW5kRXhhbXBsZXNOb3JtYWxpemVkLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBDTERSIGNhdGVnb3J5IHJ1bGU6IHskY2xkckZvcm11bGFBbmRFeGFtcGxlc30iKTsKICAgICAgICB9CiAgICAgICAgJGNsZHJGb3JtdWxhID0gdHJpbSgkbWF0Y2hlc1sxXSk7CiAgICAgICAgJHMgPSBpc3NldCgkbWF0Y2hlc1syXSkgPyB0cmltKCRtYXRjaGVzWzJdKSA6ICcnOwogICAgICAgICR0aGlzLT5leGFtcGxlcyA9ICgkcyA9PT0gJycpID8gbnVsbCA6ICRzOwogICAgICAgIHN3aXRjaCAoJHRoaXMtPmlkKSB7CiAgICAgICAgICAgIGNhc2UgQ2xkckRhdGE6Ok9USEVSX0NBVEVHT1JZOgogICAgICAgICAgICAgICAgaWYgKCRjbGRyRm9ybXVsYSAhPT0gJycpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgJyIgLiBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlkgLiAiJyBjYXRlZ29yeSBzaG91bGQgbm90IGhhdmUgYW55IGZvcm11bGEsIGJ1dCBpdCBoYXMgJ3skY2xkckZvcm11bGF9JyIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmZvcm11bGEgPSBudWxsOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpZiAoJGNsZHJGb3JtdWxhID09PSAnJykgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSAneyR0aGlzLT5pZH0nIGNhdGVnb3J5IGRvZXMgbm90IGhhdmUgYSBmb3JtdWxhIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+Zm9ybXVsYSA9IEZvcm11bGFDb252ZXJ0ZXI6OmNvbnZlcnRGb3JtdWxhKCRjbGRyRm9ybXVsYSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBsaXN0IG9mIG51bWJlcnMgY29ycmVzcG9uZGluZyB0byB0aGUgJGV4YW1wbGVzIHZhbHVlLgogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiB0aHJvd3MgYW4gRXhjZXB0aW9uIGlmIHdlIHdlcmVuJ3QgYWJsZSB0byBleHBhbmQgdGhlIGV4YW1wbGVzCiAgICAgKgogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhhbXBsZUludGVnZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6ZXhwYW5kRXhhbXBsZXMoJHRoaXMtPmV4YW1wbGVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4cGFuZCBhIGxpc3Qgb2YgZXhhbXBsZXMgYXMgZGVmaW5lZCBieSBDTERSLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGV4YW1wbGVzIEEgc3RyaW5nIGxpa2UgJzEsIDIsIDUuLi43LCDigKYnLgogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiB0aHJvd3MgYW4gRXhjZXB0aW9uIGlmIHdlIHdlcmVuJ3QgYWJsZSB0byBleHBhbmQgJGV4YW1wbGVzCiAgICAgKgogICAgICogQHJldHVybiBpbnRbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4cGFuZEV4YW1wbGVzKCRleGFtcGxlcykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICAkbSA9IG51bGw7CiAgICAgICAgaWYgKHN1YnN0cigkZXhhbXBsZXMsIC1zdHJsZW4oJywg4oCmJykpID09PSAnLCDigKYnKSB7CiAgICAgICAgICAgICRleGFtcGxlcyA9IHN1YnN0cigkZXhhbXBsZXMsIDAsIHN0cmxlbigkZXhhbXBsZXMpIC0gc3RybGVuKCcsIOKApicpKTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnLCcsIHN0cl9yZXBsYWNlKCcgJywgJycsICRleGFtcGxlcykpIGFzICRyYW5nZSkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oPzxudW0+XGQrKSgoY3xlKSg/PGV4cD5cZCspKT8kLycsICRyYW5nZSwgJG0pKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAoaW50KSAoaXNzZXQoJG1bJ2V4cCddKSA/ICgkbVsnbnVtJ10gLiBzdHJfcmVwZWF0KCcwJywgKGludCkgJG1bJ2V4cCddKSkgOiAkcmFuZ2UpOwogICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgnL14oXGQrKX4oXGQrKSQvJywgJHJhbmdlLCAkbSkpIHsKICAgICAgICAgICAgICAgICRmcm9tID0gKGludCkgJG1bMV07CiAgICAgICAgICAgICAgICAkdG8gPSAoaW50KSAkbVsyXTsKICAgICAgICAgICAgICAgICRkZWx0YSA9ICR0byAtICRmcm9tOwogICAgICAgICAgICAgICAgJHN0ZXAgPSAoaW50KSBtYXgoMSwgJGRlbHRhIC8gMTAwKTsKICAgICAgICAgICAgICAgIGZvciAoJGkgPSAkZnJvbTsgJGkgPCAkdG87ICRpICs9ICRzdGVwKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gJGk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkdG87CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmhhbmRsZWQgdGVzdCByYW5nZSAneyRyYW5nZX0nIGluICd7JGV4YW1wbGVzfSciKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJHJlc3VsdCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiTm8gdGVzdCBudW1iZXJzIGZyb20gJ3skZXhhbXBsZXN9JyIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlczsKCnVzZSBFeGNlcHRpb247CgovKioKICogQSBoZWxwZXIgY2xhc3MgdG8gY29udmVydCBhIENMRFIgZm9ybXVsYSB0byBhIGdldHRleHQgZm9ybXVsYS4KICovCmNsYXNzIEZvcm11bGFDb252ZXJ0ZXIKewogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIGZvcm11bGEgZnJvbSB0aGUgQ0xEUiByZXByZXNlbnRhdGlvbiB0byB0aGUgZ2V0dGV4dCByZXByZXNlbnRhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjbGRyRm9ybXVsYSB0aGUgQ0xEUiBmb3JtdWxhIHRvIGNvbnZlcnQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2V0dGV4dCB3aWxsIGFsd2F5cyBldmFsdWF0ZSB0byB0cnVlLCBmYWxzZSBpZiBnZXR0ZXh0IHdpbGwgYWx3YXlzIGV2YWx1YXRlIHRvIGZhbHNlLCByZXR1cm4gdGhlIGdldHRleHQgZm9ybXVsYSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0Rm9ybXVsYSgkY2xkckZvcm11bGEpCiAgICB7CiAgICAgICAgaWYgKHN0cnBicmsoJGNsZHJGb3JtdWxhLCAnKCknKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5hYmxlIHRvIGNvbnZlcnQgdGhlIGZvcm11bGEgJ3skY2xkckZvcm11bGF9JzogcGFyZW50aGVzaXMgaGFuZGxpbmcgbm90IGltcGxlbWVudGVkIik7CiAgICAgICAgfQogICAgICAgICRvclNlcGFyYXRlZENodW5rcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnIG9yICcsICRjbGRyRm9ybXVsYSkgYXMgJGNsZHJGb3JtdWxhQ2h1bmspIHsKICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSBudWxsOwogICAgICAgICAgICAkYW5kU2VwYXJhdGVkQ2h1bmtzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnIGFuZCAnLCAkY2xkckZvcm11bGFDaHVuaykgYXMgJGNsZHJBdG9tKSB7CiAgICAgICAgICAgICAgICAkZ2V0dGV4dEF0b20gPSBzZWxmOjpjb252ZXJ0QXRvbSgkY2xkckF0b20pOwogICAgICAgICAgICAgICAgaWYgKCRnZXR0ZXh0QXRvbSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAvLyBPbmUgYXRvbSBqb2luZWQgYnkgJ2FuZCcgYWx3YXlzIGV2YWx1YXRlcyB0byBmYWxzZSA9PiB0aGUgd2hvbGUgJ2FuZCcgZ3JvdXAgaXMgYWx3YXlzIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkZ2V0dGV4dEF0b20gIT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkYW5kU2VwYXJhdGVkQ2h1bmtzW10gPSAkZ2V0dGV4dEF0b207CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkZ2V0dGV4dEZvcm11bGFDaHVuaykpIHsKICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkYW5kU2VwYXJhdGVkQ2h1bmtzKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEFsbCB0aGUgYXRvbXMgam9pbmVkIGJ5ICdhbmQnIGFsd2F5cyBldmFsdWF0ZSB0byB0cnVlID0+IHRoZSB3aG9sZSAnYW5kJyBncm91cCBpcyBhbHdheXMgdHJ1ZQogICAgICAgICAgICAgICAgICAgICRnZXR0ZXh0Rm9ybXVsYUNodW5rID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSBpbXBsb2RlKCcgJiYgJywgJGFuZFNlcGFyYXRlZENodW5rcyk7CiAgICAgICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlcyBzaW1wbGlmaWNhdGlvbgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJGdldHRleHRGb3JtdWxhQ2h1bmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbiA+PSAwICYmIG4gPD0gMiAmJiBuICE9IDInOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSAnbiA9PSAwIHx8IG4gPT0gMSc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRnZXR0ZXh0Rm9ybXVsYUNodW5rID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAvLyBPbmUgcGFydCBvZiB0aGUgZm9ybXVsYSBqb2luZWQgd2l0aCB0aGUgb3RoZXJzIGJ5ICdvcicgYWx3YXlzIGV2YWx1YXRlcyB0byB0cnVlID0+IHRoZSB3aG9sZSBmb3JtdWxhIGFsd2F5cyBldmFsdWF0ZXMgdG8gdHJ1ZQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRnZXR0ZXh0Rm9ybXVsYUNodW5rICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJG9yU2VwYXJhdGVkQ2h1bmtzW10gPSAkZ2V0dGV4dEZvcm11bGFDaHVuazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJG9yU2VwYXJhdGVkQ2h1bmtzKSkgewogICAgICAgICAgICAvLyBBbGwgdGhlIHBhcnRzIGpvaW5lZCBieSAnb3InIGFsd2F5cyBldmFsdWF0ZSB0byBmYWxzZSA9PiB0aGUgd2hvbGUgZm9ybXVsYSBhbHdheXMgZXZhbHVhdGVzIHRvIGZhbHNlCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcgfHwgJywgJG9yU2VwYXJhdGVkQ2h1bmtzKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnRzIGFuIGF0b21pYyBwYXJ0IG9mIHRoZSBDTERSIGZvcm11bGEgdG8gaXRzIGdldHRleHQgcmVwcmVzZW50YXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2xkckF0b20gdGhlIENMRFIgZm9ybXVsYSBhdG9tIHRvIGNvbnZlcnQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2V0dGV4dCB3aWxsIGFsd2F5cyBldmFsdWF0ZSB0byB0cnVlLCBmYWxzZSBpZiBnZXR0ZXh0IHdpbGwgYWx3YXlzIGV2YWx1YXRlIHRvIGZhbHNlLCByZXR1cm4gdGhlIGdldHRleHQgZm9ybXVsYSBvdGhlcndpc2UKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY29udmVydEF0b20oJGNsZHJBdG9tKQogICAgewogICAgICAgICRtID0gbnVsbDsKICAgICAgICAkZ2V0dGV4dEF0b20gPSAkY2xkckF0b207CiAgICAgICAgJGdldHRleHRBdG9tID0gc3RyX3JlcGxhY2UoJyA9ICcsICcgPT0gJywgJGdldHRleHRBdG9tKTsKICAgICAgICAkZ2V0dGV4dEF0b20gPSBzdHJfcmVwbGFjZSgnaScsICduJywgJGdldHRleHRBdG9tKTsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15uKCAlIFxkKyk/ICghPXw9PSkgXGQrJC8nLCAkZ2V0dGV4dEF0b20pKSB7CiAgICAgICAgICAgIHJldHVybiAkZ2V0dGV4dEF0b207CiAgICAgICAgfQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXm4oICUgXGQrKT8gKCE9fD09KSBcZCsoLFxkK3xcLlwuXGQrKSskLycsICRnZXR0ZXh0QXRvbSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OmV4cGFuZEF0b20oJGdldHRleHRBdG9tKTsKICAgICAgICB9CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKD86dnx3KSg/OiAlIDEwKyk/ID09IChcZCspKD86XC5cLlxkKyk/JC8nLCAkZ2V0dGV4dEF0b20sICRtKSkgeyAvLyBGb3IgZ2V0dGV4dDogdiA9PSAwLCB3ID09IDAKICAgICAgICAgICAgcmV0dXJuIChpbnQpICRtWzFdID09PSAwID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oPzp2fHcpKD86ICUgMTArKT8gIT0gKFxkKykoPzpcLlwuXGQrKT8kLycsICRnZXR0ZXh0QXRvbSwgJG0pKSB7IC8vIEZvciBnZXR0ZXh0OiB2ID09IDAsIHcgPT0gMAogICAgICAgICAgICByZXR1cm4gKGludCkgJG1bMV0gPT09IDAgPyBmYWxzZSA6IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXig/OmZ8dHxjfGUpKD86ICUgMTArKT8gPT0gKFxkKykoPzpcLlwuXGQrKT8kLycsICRnZXR0ZXh0QXRvbSwgJG0pKSB7IC8vIGYgPT0gZW1wdHksIHQgPT0gZW1wdHksIGMgPT0gZW1wdHksIGUgPT0gZW1wdHkKICAgICAgICAgICAgcmV0dXJuIChpbnQpICRtWzFdID09PSAwID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oPzpmfHR8Y3xlKSg/OiAlIDEwKyk/ICE9IChcZCspKD86XC5cLlxkKyk/JC8nLCAkZ2V0dGV4dEF0b20sICRtKSkgeyAvLyBmID09IGVtcHR5LCB0ID09IGVtcHR5LCBjID09IGVtcHR5LCBlID09IGVtcHR5CiAgICAgICAgICAgIHJldHVybiAoaW50KSAkbVsxXSA9PT0gMCA/IGZhbHNlIDogdHJ1ZTsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5hYmxlIHRvIGNvbnZlcnQgdGhlIGZvcm11bGEgY2h1bmsgJ3skY2xkckF0b219JyBmcm9tIENMRFIgdG8gZ2V0dGV4dCIpOwogICAgfQoKICAgIC8qKgogICAgICogRXhwYW5kcyBhbiBhdG9tIGNvbnRhaW5pbmcgYSByYW5nZSAoZm9yIGluc3RhbmNlOiAnbiA9PSAxLDMuLjUnKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhdG9tCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXhwYW5kQXRvbSgkYXRvbSkKICAgIHsKICAgICAgICAkbSA9IG51bGw7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKG4oPzogJSBcZCspPykgKD09fCE9KSAoXGQrKD86XC5cLlxkK3wsXGQrKSspJC8nLCAkYXRvbSwgJG0pKSB7CiAgICAgICAgICAgICR3aGF0ID0gJG1bMV07CiAgICAgICAgICAgICRvcCA9ICRtWzJdOwogICAgICAgICAgICAkY2h1bmtzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnLCcsICRtWzNdKSBhcyAkcmFuZ2UpIHsKICAgICAgICAgICAgICAgICRjaHVuayA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoKCFpc3NldCgkY2h1bmspKSAmJiBwcmVnX21hdGNoKCcvXlxkKyQvJywgJHJhbmdlKSkgewogICAgICAgICAgICAgICAgICAgICRjaHVuayA9ICJ7JHdoYXR9IHskb3B9IHskcmFuZ2V9IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgoIWlzc2V0KCRjaHVuaykpICYmIHByZWdfbWF0Y2goJy9eKFxkKylcLlwuKFxkKykkLycsICRyYW5nZSwgJG0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGZyb20gPSAoaW50KSAkbVsxXTsKICAgICAgICAgICAgICAgICAgICAkdG8gPSAoaW50KSAkbVsyXTsKICAgICAgICAgICAgICAgICAgICBpZiAoKCR0byAtICRmcm9tKSA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCRvcCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnPT0nOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaHVuayA9ICIoeyR3aGF0fSA9PSB7JGZyb219IHx8IHskd2hhdH0gPT0geyR0b30pIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJyE9JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2h1bmsgPSAieyR3aGF0fSAhPSB7JGZyb219ICYmIHskd2hhdH0gPT0geyR0b30iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkb3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJz09JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2h1bmsgPSAieyR3aGF0fSA+PSB7JGZyb219ICYmIHskd2hhdH0gPD0geyR0b30iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnIT0nOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkd2hhdCA9PT0gJ24nICYmICRmcm9tIDw9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNodW5rID0gInskd2hhdH0gPiB7JHRvfSI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNodW5rID0gIih7JHdoYXR9IDwgeyRmcm9tfSB8fCB7JHdoYXR9ID4geyR0b30pIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRjaHVuaykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmhhbmRsZWQgcmFuZ2UgJ3skcmFuZ2V9JyBpbiAneyRhdG9tfSciKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjaHVua3NbXSA9ICRjaHVuazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY291bnQoJGNodW5rcykgPT09IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY2h1bmtzWzBdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3aXRjaCAoJG9wKSB7CiAgICAgICAgICAgICAgICBjYXNlICc9PSc6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcoJyAuIGltcGxvZGUoJyB8fCAnLCAkY2h1bmtzKSAuICcpJzsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICchPSc6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltcGxvZGUoJyAmJiAnLCAkY2h1bmtzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmFibGUgdG8gZXhwYW5kICd7JGF0b219JyIpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXM7Cgp1c2UgRXhjZXB0aW9uOwoKLyoqCiAqIE1haW4gY2xhc3MgdG8gY29udmVydCB0aGUgcGx1cmFsIHJ1bGVzIG9mIGEgbGFuZ3VhZ2UgZnJvbSBDTERSIHRvIGdldHRleHQuCiAqLwpjbGFzcyBMYW5ndWFnZQp7CiAgICAvKioKICAgICAqIFRoZSBsYW5ndWFnZSBJRC4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJGlkOwoKICAgIC8qKgogICAgICogVGhlIGxhbmd1YWdlIG5hbWUuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRuYW1lOwoKICAgIC8qKgogICAgICogSWYgdGhpcyBsYW5ndWFnZSBpcyBkZXByZWNhdGVkOiB0aGUgZ2V0dGV4dCBjb2RlIG9mIHRoZSBuZXcgbGFuZ3VhZ2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgJHN1cGVyc2VkZWRCeTsKCiAgICAvKioKICAgICAqIFRoZSBzY3JpcHQgbmFtZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyAkc2NyaXB0OwoKICAgIC8qKgogICAgICogVGhlIHRlcnJpdG9yeSBuYW1lLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljICR0ZXJyaXRvcnk7CgogICAgLyoqCiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYmFzZSBsYW5ndWFnZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyAkYmFzZUxhbmd1YWdlOwoKICAgIC8qKgogICAgICogVGhlIGxpc3Qgb2YgY2F0ZWdvcmllcy4KICAgICAqCiAgICAgKiBAdmFyIFxHZXR0ZXh0XExhbmd1YWdlc1xDYXRlZ29yeVtdCiAgICAgKi8KICAgIHB1YmxpYyAkY2F0ZWdvcmllczsKCiAgICAvKioKICAgICAqIFRoZSBnZXR0ZXh0IGZvcm11bGEgdG8gZGVjaWRlIHdoaWNoIGNhdGVnb3J5IHNob3VsZCBiZSBhcHBsaWVkLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkZm9ybXVsYTsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemUgdGhlIGluc3RhbmNlIGFuZCBwYXJzZSB0aGUgbGFuZ3VhZ2UgY29kZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGluZm8gVGhlIHJlc3VsdCBvZiBDbGRyRGF0YTo6Z2V0TGFuZ3VhZ2VJbmZvKCkKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24gdGhyb3dzIGFuIEV4Y2VwdGlvbiBpZiAkZnVsbElkIGlzIG5vdCB2YWxpZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRpbmZvKQogICAgewogICAgICAgICR0aGlzLT5pZCA9ICRpbmZvWydpZCddOwogICAgICAgICR0aGlzLT5uYW1lID0gJGluZm9bJ25hbWUnXTsKICAgICAgICAkdGhpcy0+c3VwZXJzZWRlZEJ5ID0gaXNzZXQoJGluZm9bJ3N1cGVyc2VkZWRCeSddKSA/ICRpbmZvWydzdXBlcnNlZGVkQnknXSA6IG51bGw7CiAgICAgICAgJHRoaXMtPnNjcmlwdCA9IGlzc2V0KCRpbmZvWydzY3JpcHQnXSkgPyAkaW5mb1snc2NyaXB0J10gOiBudWxsOwogICAgICAgICR0aGlzLT50ZXJyaXRvcnkgPSBpc3NldCgkaW5mb1sndGVycml0b3J5J10pID8gJGluZm9bJ3RlcnJpdG9yeSddIDogbnVsbDsKICAgICAgICAkdGhpcy0+YmFzZUxhbmd1YWdlID0gaXNzZXQoJGluZm9bJ2Jhc2VMYW5ndWFnZSddKSA/ICRpbmZvWydiYXNlTGFuZ3VhZ2UnXSA6IG51bGw7CiAgICAgICAgLy8gTGV0J3MgYnVpbGQgdGhlIGNhdGVnb3J5IGxpc3QKICAgICAgICAkdGhpcy0+Y2F0ZWdvcmllcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGluZm9bJ2NhdGVnb3JpZXMnXSBhcyAkY2xkckNhdGVnb3J5SWQgPT4gJGNsZHJGb3JtdWxhQW5kRXhhbXBsZXMpIHsKICAgICAgICAgICAgJGNhdGVnb3J5ID0gbmV3IENhdGVnb3J5KCRjbGRyQ2F0ZWdvcnlJZCwgJGNsZHJGb3JtdWxhQW5kRXhhbXBsZXMpOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y2F0ZWdvcmllcyBhcyAkYykgewogICAgICAgICAgICAgICAgaWYgKCRjYXRlZ29yeS0+aWQgPT09ICRjLT5pZCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBjYXRlZ29yeSAneyRjYXRlZ29yeS0+aWR9JyBpcyBzcGVjaWZpZWQgbW9yZSB0aGFuIG9uY2UiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+Y2F0ZWdvcmllc1tdID0gJGNhdGVnb3J5OwogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNhdGVnb3JpZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBsYW5ndWFnZSAneyRpbmZvWydpZCddfScgZG9lcyBub3QgaGF2ZSBhbnkgcGx1cmFsIGNhdGVnb3J5Iik7CiAgICAgICAgfQogICAgICAgIC8vIExldCdzIHNvcnQgdGhlIGNhdGVnb3JpZXMgZnJvbSAnemVybycgdG8gJ290aGVyJwogICAgICAgIHVzb3J0KCR0aGlzLT5jYXRlZ29yaWVzLCBmdW5jdGlvbiAoQ2F0ZWdvcnkgJGNhdGVnb3J5MSwgQ2F0ZWdvcnkgJGNhdGVnb3J5MikgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfc2VhcmNoKCRjYXRlZ29yeTEtPmlkLCBDbGRyRGF0YTo6JGNhdGVnb3JpZXMpIC0gYXJyYXlfc2VhcmNoKCRjYXRlZ29yeTItPmlkLCBDbGRyRGF0YTo6JGNhdGVnb3JpZXMpOwogICAgICAgIH0pOwogICAgICAgIC8vIFRoZSAnb3RoZXInIGNhdGVnb3J5IHNob3VsZCBhbHdheXMgYmUgdGhlcmUKICAgICAgICBpZiAoJHRoaXMtPmNhdGVnb3JpZXNbY291bnQoJHRoaXMtPmNhdGVnb3JpZXMpIC0gMV0tPmlkICE9PSBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVGhlIGxhbmd1YWdlICd7JGluZm9bJ2lkJ119JyBkb2VzIG5vdCBoYXZlIHRoZSAnIiAuIENsZHJEYXRhOjpPVEhFUl9DQVRFR09SWSAuICInIHBsdXJhbCBjYXRlZ29yeSIpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y2hlY2tBbHdheXNUcnVlQ2F0ZWdvcmllcygpOwogICAgICAgICR0aGlzLT5jaGVja0Fsd2F5c0ZhbHNlQ2F0ZWdvcmllcygpOwogICAgICAgICR0aGlzLT5jaGVja0FsbENhdGVnb3JpZXNXaXRoRXhhbXBsZXMoKTsKICAgICAgICAkdGhpcy0+Zm9ybXVsYSA9ICR0aGlzLT5idWlsZEZvcm11bGEoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIGxpc3Qgb2YgYWxsIGxhbmd1YWdlcyBhdmFpbGFibGUuCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBcR2V0dGV4dFxMYW5ndWFnZXNcTGFuZ3VhZ2VbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEFsbCgpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cyhDbGRyRGF0YTo6Z2V0TGFuZ3VhZ2VOYW1lcygpKSBhcyAkY2xkckxhbmd1YWdlSWQpIHsKICAgICAgICAgICAgJHJlc3VsdFtdID0gbmV3IHNlbGYoQ2xkckRhdGE6OmdldExhbmd1YWdlSW5mbygkY2xkckxhbmd1YWdlSWQpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGEgTGFuZ3VhZ2UgaW5zdGFuY2UgZ2l2ZW4gdGhlIGxhbmd1YWdlIGlkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkCiAgICAgKgogICAgICogQHJldHVybiBcR2V0dGV4dFxMYW5ndWFnZXNcTGFuZ3VhZ2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEJ5SWQoJGlkKQogICAgewogICAgICAgICRyZXN1bHQgPSBudWxsOwogICAgICAgICRpbmZvID0gQ2xkckRhdGE6OmdldExhbmd1YWdlSW5mbygkaWQpOwogICAgICAgIGlmIChpc3NldCgkaW5mbykpIHsKICAgICAgICAgICAgJHJlc3VsdCA9IG5ldyBzZWxmKCRpbmZvKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGNsb25lIG9mIHRoaXMgaW5zdGFuY2Ugd2l0aCBhbGwgdGhlIHN0cmluZ3MgdG8gVVMtQVNDSUkuCiAgICAgKgogICAgICogQHJldHVybiBcR2V0dGV4dFxMYW5ndWFnZXNcTGFuZ3VhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVTQXNjaWlDbG9uZSgpCiAgICB7CiAgICAgICAgJGNsb25lID0gY2xvbmUgJHRoaXM7CiAgICAgICAgc2VsZjo6YXNjaWlmaWVyKCRjbG9uZS0+bmFtZSk7CiAgICAgICAgc2VsZjo6YXNjaWlmaWVyKCRjbG9uZS0+Zm9ybXVsYSk7CiAgICAgICAgJGNsb25lLT5jYXRlZ29yaWVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y2F0ZWdvcmllcyBhcyAkY2F0ZWdvcnkpIHsKICAgICAgICAgICAgJGNhdGVnb3J5Q2xvbmUgPSBjbG9uZSAkY2F0ZWdvcnk7CiAgICAgICAgICAgIHNlbGY6OmFzY2lpZmllcigkY2F0ZWdvcnlDbG9uZS0+ZXhhbXBsZXMpOwogICAgICAgICAgICAkY2xvbmUtPmNhdGVnb3JpZXNbXSA9ICRjYXRlZ29yeUNsb25lOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjbG9uZTsKICAgIH0KCiAgICAvKioKICAgICAqIEJ1aWxkIHRoZSBmb3JtdWxhIHN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnRseSBkZWZpbmVkIGNhdGVnb3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHdpdGhvdXRQYXJlbnRoZXNpcyBUUlVFIHRvIGJ1aWxkIGEgZm9ybXVsYSBpbiBzdGFuZGFyZCBnZXR0ZXh0IGZvcm1hdCwgRkFMU0UgKGRlZmF1bHQpIHRvIGJ1aWxkIGEgUEhQLWNvbXBhdGlibGUgZm9ybXVsYQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBidWlsZEZvcm11bGEoJHdpdGhvdXRQYXJlbnRoZXNpcyA9IGZhbHNlKQogICAgewogICAgICAgICRudW1DYXRlZ29yaWVzID0gY291bnQoJHRoaXMtPmNhdGVnb3JpZXMpOwogICAgICAgIHN3aXRjaCAoJG51bUNhdGVnb3JpZXMpIHsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgLy8gSnVzdCBvbmUgY2F0ZWdvcnkKICAgICAgICAgICAgICAgIHJldHVybiAnMCc7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgIHJldHVybiBzZWxmOjpyZWR1Y2VGb3JtdWxhKHNlbGY6OnJldmVyc2VGb3JtdWxhKCR0aGlzLT5jYXRlZ29yaWVzWzBdLT5mb3JtdWxhKSk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAkZm9ybXVsYSA9IChzdHJpbmcpICgkbnVtQ2F0ZWdvcmllcyAtIDEpOwogICAgICAgICAgICAgICAgZm9yICgkaSA9ICRudW1DYXRlZ29yaWVzIC0gMjsgJGkgPj0gMDsgJGktLSkgewogICAgICAgICAgICAgICAgICAgICRmID0gc2VsZjo6cmVkdWNlRm9ybXVsYSgkdGhpcy0+Y2F0ZWdvcmllc1skaV0tPmZvcm11bGEpOwogICAgICAgICAgICAgICAgICAgIGlmICghJHdpdGhvdXRQYXJlbnRoZXNpcyAmJiAhcHJlZ19tYXRjaCgnL15cKFteKCldK1wpJC8nLCAkZikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGYgPSAiKHskZn0pIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGZvcm11bGEgPSAieyRmfSA/IHskaX0gOiB7JGZvcm11bGF9IjsKICAgICAgICAgICAgICAgICAgICBpZiAoISR3aXRob3V0UGFyZW50aGVzaXMgJiYgJGkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmb3JtdWxhID0gIih7JGZvcm11bGF9KSI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkZm9ybXVsYTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBMZXQncyBsb29rIGZvciBjYXRlZ29yaWVzIHRoYXQgd2lsbCBhbHdheXMgb2NjdXIuCiAgICAgKiBUaGlzIGJlY2F1c2Ugd2l0aCBkZWNpbWFscyAoQ0xEUikgd2UgbWF5IGhhdmUgbW9yZSBjYXNlcywgd2l0aCBpbnRlZ2VycyAoZ2V0dGV4dCkgd2UgaGF2ZSBqdXN0IG9uZSBjYXNlLgogICAgICogSWYgd2UgZm91bmQgdGhhdCAoc2luZ2xlKSBjYXRlZ29yeSB3ZSByZWR1Y2UgdGhlIGNhdGVnb3JpZXMgdG8gdGhhdCBvbmUgb25seS4KICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0Fsd2F5c1RydWVDYXRlZ29yaWVzKCkKICAgIHsKICAgICAgICAkYWx3YXlzVHJ1ZUNhdGVnb3J5ID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y2F0ZWdvcmllcyBhcyAkY2F0ZWdvcnkpIHsKICAgICAgICAgICAgaWYgKCRjYXRlZ29yeS0+Zm9ybXVsYSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY2F0ZWdvcnktPmV4YW1wbGVzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBjYXRlZ29yeSAneyRjYXRlZ29yeS0+aWR9JyBzaG91bGQgYWx3YXlzIG9jY3VyLCBidXQgaXQgZG9lcyBub3QgaGF2ZSBleGFtcGxlcyAoc28gZm9yIENMRFIgaXQgd2lsbCBuZXZlciBvY2N1ciBmb3IgaW50ZWdlcnMhKSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGFsd2F5c1RydWVDYXRlZ29yeSA9ICRjYXRlZ29yeTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkYWx3YXlzVHJ1ZUNhdGVnb3J5KSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y2F0ZWdvcmllcyBhcyAkY2F0ZWdvcnkpIHsKICAgICAgICAgICAgICAgIGlmICgoJGNhdGVnb3J5ICE9PSAkYWx3YXlzVHJ1ZUNhdGVnb3J5KSAmJiBpc3NldCgkY2F0ZWdvcnktPmV4YW1wbGVzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBjYXRlZ29yeSAneyRjYXRlZ29yeS0+aWR9JyBzaG91bGQgbmV2ZXIgb2NjdXIsIGJ1dCBpdCBoYXMgc29tZSBleGFtcGxlcyAoc28gZm9yIENMRFIgaXQgd2lsbCBvY2N1ciEpIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGFsd2F5c1RydWVDYXRlZ29yeS0+aWQgPSBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlk7CiAgICAgICAgICAgICRhbHdheXNUcnVlQ2F0ZWdvcnktPmZvcm11bGEgPSBudWxsOwogICAgICAgICAgICAkdGhpcy0+Y2F0ZWdvcmllcyA9IGFycmF5KCRhbHdheXNUcnVlQ2F0ZWdvcnkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIExldCdzIGxvb2sgZm9yIGNhdGVnb3JpZXMgdGhhdCB3aWxsIG5ldmVyIG9jY3VyLgogICAgICogVGhpcyBiZWNhdXNlIHdpdGggZGVjaW1hbHMgKENMRFIpIHdlIG1heSBoYXZlIG1vcmUgY2FzZXMsIHdpdGggaW50ZWdlcnMgKGdldHRleHQpIHdlIGhhdmUgc29tZSBsZXNzIGNhc2VzLgogICAgICogSWYgd2UgZm91bmQgdGhvc2UgY2F0ZWdvcmllcyB3ZSBzdHJpcCB0aGVtIG91dC4KICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0Fsd2F5c0ZhbHNlQ2F0ZWdvcmllcygpCiAgICB7CiAgICAgICAgJGZpbHRlcmVkID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y2F0ZWdvcmllcyBhcyAkY2F0ZWdvcnkpIHsKICAgICAgICAgICAgaWYgKCRjYXRlZ29yeS0+Zm9ybXVsYSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY2F0ZWdvcnktPmV4YW1wbGVzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBjYXRlZ29yeSAneyRjYXRlZ29yeS0+aWR9JyBzaG91bGQgbmV2ZXIgb2NjdXIsIGJ1dCBpdCBoYXMgZXhhbXBsZXMgKHNvIGZvciBDTERSIGl0IG1heSBvY2N1ciEpIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZmlsdGVyZWRbXSA9ICRjYXRlZ29yeTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y2F0ZWdvcmllcyA9ICRmaWx0ZXJlZDsKICAgIH0KCiAgICAvKioKICAgICAqIExldCdzIGxvb2sgZm9yIGNhdGVnb3JpZXMgdGhhdCBkb24ndCBoYXZlIGV4YW1wbGVzLgogICAgICogVGhpcyBiZWNhdXNlIHdpdGggZGVjaW1hbHMgKENMRFIpIHdlIG1heSBoYXZlIG1vcmUgY2FzZXMsIHdpdGggaW50ZWdlcnMgKGdldHRleHQpIHdlIGhhdmUgc29tZSBsZXNzIGNhc2VzLgogICAgICogSWYgd2UgZm91bmQgdGhvc2UgY2F0ZWdvcmllcywgd2UgY2hlY2sgdGhhdCB0aGV5IG5ldmVyIG9jY3VyIGFuZCB3ZSBzdHJpcCB0aGVtIG91dC4KICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0FsbENhdGVnb3JpZXNXaXRoRXhhbXBsZXMoKQogICAgewogICAgICAgICRhbGxDYXRlZ29yaWVzSWRzID0gYXJyYXkoKTsKICAgICAgICAkZ29vZENhdGVnb3JpZXMgPSBhcnJheSgpOwogICAgICAgICRiYWRDYXRlZ29yaWVzID0gYXJyYXkoKTsKICAgICAgICAkYmFkQ2F0ZWdvcmllc0lkcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgICRhbGxDYXRlZ29yaWVzSWRzW10gPSAkY2F0ZWdvcnktPmlkOwogICAgICAgICAgICBpZiAoaXNzZXQoJGNhdGVnb3J5LT5leGFtcGxlcykpIHsKICAgICAgICAgICAgICAgICRnb29kQ2F0ZWdvcmllc1tdID0gJGNhdGVnb3J5OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGJhZENhdGVnb3JpZXNbXSA9ICRjYXRlZ29yeTsKICAgICAgICAgICAgICAgICRiYWRDYXRlZ29yaWVzSWRzW10gPSAkY2F0ZWdvcnktPmlkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChlbXB0eSgkYmFkQ2F0ZWdvcmllcykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkcmVtb3ZlQ2F0ZWdvcmllc1dpdGhvdXRFeGFtcGxlcyA9IGZhbHNlOwogICAgICAgIHN3aXRjaCAoaW1wbG9kZSgnLCcsICRiYWRDYXRlZ29yaWVzSWRzKSAuICdAJyAuIGltcGxvZGUoJywnLCAkYWxsQ2F0ZWdvcmllc0lkcykpIHsKICAgICAgICAgICAgY2FzZSBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlkgLiAnQG9uZSxmZXcsbWFueSwnIC4gQ2xkckRhdGE6Ok9USEVSX0NBVEVHT1JZOgogICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+YnVpbGRGb3JtdWxhKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICcobiAlIDEwID09IDEgJiYgbiAlIDEwMCAhPSAxMSkgPyAwIDogKChuICUgMTAgPj0gMiAmJiBuICUgMTAgPD0gNCAmJiAobiAlIDEwMCA8IDEyIHx8IG4gJSAxMDAgPiAxNCkpID8gMSA6ICgobiAlIDEwID09IDAgfHwgbiAlIDEwID49IDUgJiYgbiAlIDEwIDw9IDkgfHwgbiAlIDEwMCA+PSAxMSAmJiBuICUgMTAwIDw9IDE0KSA/IDIgOiAzKSknOgogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDAgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDEgYnV0IG5vdCB3aXRoIDExID0+IGNhc2UgMCAoJ29uZScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMTEgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMiBidXQgbm90IHdpdGggMTIgPT4gY2FzZSAxICgnZmV3JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAxMiAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAzIGJ1dCBub3Qgd2l0aCAxMyA9PiBjYXNlIDEgKCdmZXcnKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDEzICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDQgYnV0IG5vdCB3aXRoIDE0ID0+IGNhc2UgMSAoJ2ZldycpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMTQgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggNSAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggNiAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggNyAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggOCAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggOSAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vID0+IHRoZSAnb3RoZXInIGNhc2UgbmV2ZXIgb2NjdXJzOiB1c2UgJ290aGVyJyBmb3IgJ21hbnknCiAgICAgICAgICAgICAgICAgICAgICAgICRyZW1vdmVDYXRlZ29yaWVzV2l0aG91dEV4YW1wbGVzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnKG4gPT0gMSkgPyAwIDogKChuICUgMTAgPj0gMiAmJiBuICUgMTAgPD0gNCAmJiAobiAlIDEwMCA8IDEyIHx8IG4gJSAxMDAgPiAxNCkpID8gMSA6ICgobiAhPSAxICYmIChuICUgMTAgPT0gMCB8fCBuICUgMTAgPT0gMSkgfHwgbiAlIDEwID49IDUgJiYgbiAlIDEwIDw9IDkgfHwgbiAlIDEwMCA+PSAxMiAmJiBuICUgMTAwIDw9IDE0KSA/IDIgOiAzKSknOgogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDAgICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAxIGJ1dCBub3QgbnVtYmVyIDEgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlciAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+IGNhc2UgMCAoJ29uZScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMiBidXQgbm90IHdpdGggMTIgID0+IGNhc2UgMSAoJ2ZldycpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMTIgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDMgYnV0IG5vdCB3aXRoIDEzICA9PiBjYXNlIDEgKCdmZXcnKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDEzICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCA0IGJ1dCBub3Qgd2l0aCAxNCAgPT4gY2FzZSAxICgnZmV3JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAxNCAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggNSAgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDYgICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCA3ICAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggOCAgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDkgICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gPT4gdGhlICdvdGhlcicgY2FzZSBuZXZlciBvY2N1cnM6IHVzZSAnb3RoZXInIGZvciAnbWFueScKICAgICAgICAgICAgICAgICAgICAgICAgJHJlbW92ZUNhdGVnb3JpZXNXaXRob3V0RXhhbXBsZXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCEkcmVtb3ZlQ2F0ZWdvcmllc1dpdGhvdXRFeGFtcGxlcykgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmhhbmRsZWQgY2FzZSBvZiBwbHVyYWwgY2F0ZWdvcmllcyB3aXRob3V0IGV4YW1wbGVzICciIC4gaW1wbG9kZSgnLCAnLCAkYmFkQ2F0ZWdvcmllc0lkcykgLiAiJyBvdXQgb2YgJyIgLiBpbXBsb2RlKCcsICcsICRhbGxDYXRlZ29yaWVzSWRzKSAuICInIik7CiAgICAgICAgfQogICAgICAgIGlmICgkYmFkQ2F0ZWdvcmllc1tjb3VudCgkYmFkQ2F0ZWdvcmllcykgLSAxXS0+aWQgPT09IENsZHJEYXRhOjpPVEhFUl9DQVRFR09SWSkgewogICAgICAgICAgICAvLyBXZSdyZSByZW1vdmluZyB0aGUgJ290aGVyJyBjYWdvcnk6IGxldCdzIGNoYW5nZSB0aGUgbGFzdCBnb29kIGNhdGVnb3J5IHRvICdvdGhlcicKICAgICAgICAgICAgJGxhc3RHb29kID0gJGdvb2RDYXRlZ29yaWVzW2NvdW50KCRnb29kQ2F0ZWdvcmllcykgLSAxXTsKICAgICAgICAgICAgJGxhc3RHb29kLT5pZCA9IENsZHJEYXRhOjpPVEhFUl9DQVRFR09SWTsKICAgICAgICAgICAgJGxhc3RHb29kLT5mb3JtdWxhID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNhdGVnb3JpZXMgPSAkZ29vZENhdGVnb3JpZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXZlcnNlIGEgZm9ybXVsYS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtdWxhCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcmV2ZXJzZUZvcm11bGEoJGZvcm11bGEpCiAgICB7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9ebiggJSBcZCspPyA9PSBcZCsoXC5cLlxkK3wsXGQrKSo/JC8nLCAkZm9ybXVsYSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKCcgPT0gJywgJyAhPSAnLCAkZm9ybXVsYSk7CiAgICAgICAgfQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXm4oICUgXGQrKT8gIT0gXGQrKFwuXC5cZCt8LFxkKykqPyQvJywgJGZvcm11bGEpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgnICE9ICcsICcgPT0gJywgJGZvcm11bGEpOwogICAgICAgIH0KICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15cKD9uID09IFxkKyBcfFx8IG4gPT0gXGQrXCk/JC8nLCAkZm9ybXVsYSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRyaW0oc3RyX3JlcGxhY2UoYXJyYXkoJyA9PSAnLCAnIHx8ICcpLCBhcnJheSgnICE9ICcsICcgJiYgJyksICRmb3JtdWxhKSwgJygpJyk7CiAgICAgICAgfQogICAgICAgICRtID0gbnVsbDsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14obig/OiAlIFxkKyk/KSA9PSAoXGQrKSAmJiAobig/OiAlIFxkKyk/KSAhPSAoXGQrKSQvJywgJGZvcm11bGEsICRtKSkgewogICAgICAgICAgICByZXR1cm4gInskbVsxXX0gIT0geyRtWzJdfSB8fCB7JG1bM119ID09IHskbVs0XX0iOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKCRmb3JtdWxhKSB7CiAgICAgICAgICAgIGNhc2UgJyhuID09IDEgfHwgbiA9PSAyIHx8IG4gPT0gMykgfHwgbiAlIDEwICE9IDQgJiYgbiAlIDEwICE9IDYgJiYgbiAlIDEwICE9IDknOgogICAgICAgICAgICAgICAgcmV0dXJuICduICE9IDEgJiYgbiAhPSAyICYmIG4gIT0gMyAmJiAobiAlIDEwID09IDQgfHwgbiAlIDEwID09IDYgfHwgbiAlIDEwID09IDkpJzsKICAgICAgICAgICAgY2FzZSAnKG4gPT0gMCB8fCBuID09IDEpIHx8IG4gPj0gMTEgJiYgbiA8PSA5OSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ24gPj0gMiAmJiAobiA8IDExIHx8IG4gPiA5OSknOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmFibGUgdG8gcmV2ZXJzZSB0aGUgZm9ybXVsYSAneyRmb3JtdWxhfSciKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZHVjZSBzb21lIGV4Y2Vzc2l2ZWx5IGNvbXBsZXggZm9ybXVsYXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybXVsYQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHJlZHVjZUZvcm11bGEoJGZvcm11bGEpCiAgICB7CiAgICAgICAgJG1hcCA9IGFycmF5KAogICAgICAgICAgICAnbiAhPSAwICYmIG4gIT0gMScgPT4gJ24gPiAxJywKICAgICAgICAgICAgJyhuID09IDAgfHwgbiA9PSAxKSAmJiBuICE9IDAnID0+ICduID09IDEnLAogICAgICAgICk7CgogICAgICAgIHJldHVybiBpc3NldCgkbWFwWyRmb3JtdWxhXSkgPyAkbWFwWyRmb3JtdWxhXSA6ICRmb3JtdWxhOwogICAgfQoKICAgIC8qKgogICAgICogVGFrZSBvbmUgdmFyaWFibGUgYW5kLCBpZiBpdCdzIGEgc3RyaW5nLCB3ZSB0cmFuc2xpdGVyYXRlIGl0IHRvIFVTLUFTQ0lJLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgdGhlIHZhcmlhYmxlIHRvIHdvcmsgb24KICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYXNjaWlmaWVyKCYkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKGlzX3N0cmluZygkdmFsdWUpICYmICR2YWx1ZSAhPT0gJycpIHsKICAgICAgICAgICAgLy8gQXZvaWQgY29udmVydGluZyBmcm9tICfFuCcgdG8gJyJZJywgbGV0J3MgcHJlZmVyICdZJwogICAgICAgICAgICAkdmFsdWUgPSBzdHJ0cigkdmFsdWUsIGFycmF5KAogICAgICAgICAgICAgICAgJ8OAJyA9PiAnQScsICfDgScgPT4gJ0EnLCAnw4InID0+ICdBJywgJ8ODJyA9PiAnQScsICfDhCcgPT4gJ0EnLCAnw4UnID0+ICdBJywKICAgICAgICAgICAgICAgICfDiCcgPT4gJ0UnLCAnw4knID0+ICdFJywgJ8OKJyA9PiAnRScsICfDiycgPT4gJ0UnLAogICAgICAgICAgICAgICAgJ8OMJyA9PiAnSScsICfDjScgPT4gJ0knLCAnw44nID0+ICdJJywgJ8OPJyA9PiAnSScsCiAgICAgICAgICAgICAgICAnw5EnID0+ICdOJywKICAgICAgICAgICAgICAgICfDkicgPT4gJ08nLCAnw5MnID0+ICdPJywgJ8OUJyA9PiAnTycsICfDlScgPT4gJ08nLCAnw5YnID0+ICdPJywKICAgICAgICAgICAgICAgICfDmScgPT4gJ1UnLCAnw5onID0+ICdVJywgJ8ObJyA9PiAnVScsICfDnCcgPT4gJ1UnLAogICAgICAgICAgICAgICAgJ8W4JyA9PiAnWScsICfDnScgPT4gJ1knLAogICAgICAgICAgICAgICAgJ8OgJyA9PiAnYScsICfDoScgPT4gJ2EnLCAnw6InID0+ICdhJywgJ8OjJyA9PiAnYScsICfDpCcgPT4gJ2EnLCAnw6UnID0+ICdhJywKICAgICAgICAgICAgICAgICfDqCcgPT4gJ2UnLCAnw6knID0+ICdlJywgJ8OqJyA9PiAnZScsICfDqycgPT4gJ2UnLAogICAgICAgICAgICAgICAgJ8OsJyA9PiAnaScsICfDrScgPT4gJ2knLCAnw64nID0+ICdpJywgJ8OvJyA9PiAnaScsCiAgICAgICAgICAgICAgICAnw7EnID0+ICduJywgJ8OyJyA9PiAnbycsICfDsycgPT4gJ28nLCAnw7QnID0+ICdvJywgJ8O1JyA9PiAnbycsICfDticgPT4gJ28nLAogICAgICAgICAgICAgICAgJ8O5JyA9PiAndScsICfDuicgPT4gJ3UnLCAnw7snID0+ICd1JywgJ8O8JyA9PiAndScsCiAgICAgICAgICAgICAgICAnw70nID0+ICd5JywgJ8O/JyA9PiAneScsCiAgICAgICAgICAgICAgICAn4oCmJyA9PiAnLi4uJywKICAgICAgICAgICAgICAgICfKvCcgPT4gIiciLCAn4oCZJyA9PiAiJyIsCiAgICAgICAgICAgICkpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKc3BsX2F1dG9sb2FkX3JlZ2lzdGVyKAogICAgZnVuY3Rpb24gKCRjbGFzcykgewogICAgICAgIGlmIChzdHJwb3MoJGNsYXNzLCAnR2V0dGV4dFxcTGFuZ3VhZ2VzXFwnKSAhPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICRmaWxlID0gX19ESVJfXyAuIHN0cl9yZXBsYWNlKCdcXCcsIERJUkVDVE9SWV9TRVBBUkFUT1IsIHN1YnN0cigkY2xhc3MsIHN0cmxlbignR2V0dGV4dFxcTGFuZ3VhZ2VzJykpKSAuICcucGhwJzsKICAgICAgICBpZiAoaXNfZmlsZSgkZmlsZSkpIHsKICAgICAgICAgICAgcmVxdWlyZV9vbmNlICRmaWxlOwogICAgICAgIH0KICAgIH0KKTsKPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlcjsKCmNsYXNzIFhtbCBleHRlbmRzIEV4cG9ydGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjpnZXREZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAnQnVpbGQgYW4gWE1MIGZpbGUgLSBzY2hlbWEgYXZhaWxhYmxlIGF0IGh0dHA6Ly9tbG9jYXRpLmdpdGh1Yi5pby9jbGRyLXRvLWdldHRleHQtcGx1cmFsLXJ1bGVzL0dldHRleHRMYW5ndWFnZXMueHNkJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6dG9TdHJpbmdEbygpCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmdEbygkbGFuZ3VhZ2VzKQogICAgewogICAgICAgICR4bWwgPSBuZXcgXERPTURvY3VtZW50KCcxLjAnLCAnVVRGLTgnKTsKICAgICAgICAkeG1sLT5sb2FkWE1MKCc8bGFuZ3VhZ2VzCiAgICAgICAgICAgIHhtbG5zPSJodHRwczovL2dpdGh1Yi5jb20vbWxvY2F0aS9jbGRyLXRvLWdldHRleHQtcGx1cmFsLXJ1bGVzIgogICAgICAgICAgICB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgogICAgICAgICAgICB4c2k6c2NoZW1hTG9jYXRpb249Imh0dHBzOi8vZ2l0aHViLmNvbS9tbG9jYXRpL2NsZHItdG8tZ2V0dGV4dC1wbHVyYWwtcnVsZXMgaHR0cDovL21sb2NhdGkuZ2l0aHViLmlvL2NsZHItdG8tZ2V0dGV4dC1wbHVyYWwtcnVsZXMvR2V0dGV4dExhbmd1YWdlcy54c2QiCiAgICAgICAgLz4nKTsKICAgICAgICAkeExhbmd1YWdlcyA9ICR4bWwtPmZpcnN0Q2hpbGQ7CiAgICAgICAgZm9yZWFjaCAoJGxhbmd1YWdlcyBhcyAkbGFuZ3VhZ2UpIHsKICAgICAgICAgICAgJHhMYW5ndWFnZSA9ICR4bWwtPmNyZWF0ZUVsZW1lbnQoJ2xhbmd1YWdlJyk7CiAgICAgICAgICAgICR4TGFuZ3VhZ2UtPnNldEF0dHJpYnV0ZSgnaWQnLCAkbGFuZ3VhZ2UtPmlkKTsKICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCduYW1lJywgJGxhbmd1YWdlLT5uYW1lKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+c3VwZXJzZWRlZEJ5KSkgewogICAgICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCdzdXBlcnNlZGVkQnknLCAkbGFuZ3VhZ2UtPnN1cGVyc2VkZWRCeSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+c2NyaXB0KSkgewogICAgICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCdzY3JpcHQnLCAkbGFuZ3VhZ2UtPnNjcmlwdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+dGVycml0b3J5KSkgewogICAgICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCd0ZXJyaXRvcnknLCAkbGFuZ3VhZ2UtPnRlcnJpdG9yeSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+YmFzZUxhbmd1YWdlKSkgewogICAgICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCdiYXNlTGFuZ3VhZ2UnLCAkbGFuZ3VhZ2UtPmJhc2VMYW5ndWFnZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCdmb3JtdWxhJywgJGxhbmd1YWdlLT5mb3JtdWxhKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxhbmd1YWdlLT5jYXRlZ29yaWVzIGFzICRjYXRlZ29yeSkgewogICAgICAgICAgICAgICAgJHhDYXRlZ29yeSA9ICR4bWwtPmNyZWF0ZUVsZW1lbnQoJ2NhdGVnb3J5Jyk7CiAgICAgICAgICAgICAgICAkeENhdGVnb3J5LT5zZXRBdHRyaWJ1dGUoJ2lkJywgJGNhdGVnb3J5LT5pZCk7CiAgICAgICAgICAgICAgICAkeENhdGVnb3J5LT5zZXRBdHRyaWJ1dGUoJ2V4YW1wbGVzJywgJGNhdGVnb3J5LT5leGFtcGxlcyk7CiAgICAgICAgICAgICAgICAkeExhbmd1YWdlLT5hcHBlbmRDaGlsZCgkeENhdGVnb3J5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkeExhbmd1YWdlcy0+YXBwZW5kQ2hpbGQoJHhMYW5ndWFnZSk7CiAgICAgICAgfQogICAgICAgICR4bWwtPmZvcm1hdE91dHB1dCA9IHRydWU7CgogICAgICAgIHJldHVybiAkeG1sLT5zYXZlWE1MKCk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlcjsKCnVzZSBFeGNlcHRpb247CgpjbGFzcyBQcmV0dHlqc29uIGV4dGVuZHMgSnNvbgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6Z2V0RGVzY3JpcHRpb24oKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJ0J1aWxkIGFuIHVuY29tcHJlc3NlZCBKU09OLWVuY29kZWQgZmlsZSAoUEhQIDUuNCBvciBsYXRlciBpcyBuZWVkZWQpJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxKc29uOjpnZXRFbmNvZGVPcHRpb25zKCkKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXRFbmNvZGVPcHRpb25zKCkKICAgIHsKICAgICAgICBpZiAoIShkZWZpbmVkKCdcSlNPTl9QUkVUVFlfUFJJTlQnKSAmJiBkZWZpbmVkKCdcSlNPTl9VTkVTQ0FQRURfU0xBU0hFUycpICYmIGRlZmluZWQoJ1xKU09OX1VORVNDQVBFRF9VTklDT0RFJykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ1BIUCA1LjQgb3IgbGF0ZXIgaXMgcmVxdWlyZWQgdG8gZXhwb3J0IHVuY29tcHJlc3NlZCBKU09OJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXEpTT05fUFJFVFRZX1BSSU5UIHwgXEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBcSlNPTl9VTkVTQ0FQRURfVU5JQ09ERTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgRG9jcyBleHRlbmRzIEh0bWwKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OmlzRm9yUHVibGljVXNlKCkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc0ZvclB1YmxpY1VzZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjpnZXREZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAnQnVpbGQgdGhlIHBhZ2UgaHR0cHM6Ly9waHAtZ2V0dGV4dC5naXRodWIuaW8vTGFuZ3VhZ2VzLyc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OnRvU3RyaW5nRG8oKQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nRG8oJGxhbmd1YWdlcykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gPDw8J0VPVCcKPCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICAgIDxoZWFkPgogICAgICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICAgICAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiPgogICAgICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MSI+CiAgICAgICAgPG1ldGEgbmFtZT0iYXV0aG9yIiBjb250ZW50PSJNaWNoZWxlIExvY2F0aSI+CiAgICAgICAgPHRpdGxlPmdldHRleHQgcGx1cmFsIHJ1bGVzIC0gYnVpbHQgZnJvbSBDTERSPC90aXRsZT4KICAgICAgICA8bWV0YSBuYW1lPSJkZXNjcmlwdGlvbiIgY29udGVudD0iTGlzdCBvZiBhbGwgbGFuZ3VhZ2UgcnVsZXMgZm9yIGdldHRleHQgLnBvIGZpbGVzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGZyb20gdGhlIFVuaWNvZGUgQ0xEUiBkYXRhIiAvPgogICAgICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iLy9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4zLjIvY3NzL2Jvb3RzdHJhcC5taW4uY3NzIj4KICAgICAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9InN0eWxlLmNzcyI+CiAgICA8L2hlYWQ+CiAgICA8Ym9keT4KICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vcGhwLWdldHRleHQvTGFuZ3VhZ2VzIiBjbGFzcz0iaGlkZGVuLXhzIj48aW1nIHN0eWxlPSJwb3NpdGlvbjogZml4ZWQ7IHRvcDogMDsgcmlnaHQ6IDA7IGJvcmRlcjogMDsgei1pbmRleDogMjAwMCIgc3JjPSJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vZ2l0aHViL3JpYmJvbnMvZm9ya21lX3JpZ2h0X3JlZF9hYTAwMDAucG5nIiBhbHQ9IkZvcmsgbWUgb24gR2l0SHViIj48L2E+CiAgICAgICAgPGRpdiBjbGFzcz0iY29udGFpbmVyLWZsdWlkIj4KCkVPVDsKICAgICAgICAkcmVzdWx0IC49IHN0YXRpYzo6YnVpbGRUYWJsZSgkbGFuZ3VhZ2VzLCB0cnVlKTsKICAgICAgICAkcmVzdWx0IC49IDw8PCdFT1QnCgogICAgICAgIDwvZGl2PgogICAgICAgIDxzY3JpcHQgc3JjPSIvL2NvZGUuanF1ZXJ5LmNvbS9qcXVlcnktMS4xMS4yLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICAgICAgPHNjcmlwdCBzcmM9InNjcmlwdC5qcyI+PC9zY3JpcHQ+CiAgICA8L2JvZHk+CjwvaHRtbD4KRU9UOwoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgUGhwIGV4dGVuZHMgRXhwb3J0ZXIKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OmdldERlc2NyaXB0aW9uKCkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICdCdWlsZCBhIFBIUCBhcnJheSc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OnRvU3RyaW5nRG8oKQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nRG8oJGxhbmd1YWdlcykKICAgIHsKICAgICAgICAkbGluZXMgPSBhcnJheSgpOwogICAgICAgICRsaW5lc1tdID0gJzw/cGhwJzsKICAgICAgICAkbGluZXNbXSA9ICdyZXR1cm4gYXJyYXkoJzsKICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2VzIGFzICRsYykgewogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgXCcnIC4gJGxjLT5pZCAuICdcJyA9PiBhcnJheSgnOwogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwnbmFtZVwnID0+IFwnJyAuIGFkZHNsYXNoZXMoJGxjLT5uYW1lKSAuICdcJywnOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5zdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwnc3VwZXJzZWRlZEJ5XCcgPT4gXCcnIC4gJGxjLT5zdXBlcnNlZGVkQnkgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5zY3JpcHQpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwnc2NyaXB0XCcgPT4gXCcnIC4gYWRkc2xhc2hlcygkbGMtPnNjcmlwdCkgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT50ZXJyaXRvcnkpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwndGVycml0b3J5XCcgPT4gXCcnIC4gYWRkc2xhc2hlcygkbGMtPnRlcnJpdG9yeSkgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5iYXNlTGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwnYmFzZUxhbmd1YWdlXCcgPT4gXCcnIC4gYWRkc2xhc2hlcygkbGMtPmJhc2VMYW5ndWFnZSkgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwnZm9ybXVsYVwnID0+IFwnJyAuICRsYy0+Zm9ybXVsYSAuICdcJywnOwogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwncGx1cmFsc1wnID0+ICcgLiBjb3VudCgkbGMtPmNhdGVnb3JpZXMpIC4gJywnOwogICAgICAgICAgICAkY2F0TmFtZXMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbGMtPmNhdGVnb3JpZXMgYXMgJGMpIHsKICAgICAgICAgICAgICAgICRjYXROYW1lc1tdID0gIid7JGMtPmlkfSciOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdjYXNlc1wnID0+IGFycmF5KCcgLiBpbXBsb2RlKCcsICcsICRjYXROYW1lcykgLiAnKSwnOwogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgIFwnZXhhbXBsZXNcJyA9PiBhcnJheSgnOwogICAgICAgICAgICBmb3JlYWNoICgkbGMtPmNhdGVnb3JpZXMgYXMgJGMpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgICAgIFwnJyAuICRjLT5pZCAuICdcJyA9PiBcJycgLiAkYy0+ZXhhbXBsZXMgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgICAgICksJzsKICAgICAgICAgICAgJGxpbmVzW10gPSAnICAgICksJzsKICAgICAgICB9CiAgICAgICAgJGxpbmVzW10gPSAnKTsnOwogICAgICAgICRsaW5lc1tdID0gJyc7CgogICAgICAgIHJldHVybiBpbXBsb2RlKCJcbiIsICRsaW5lcyk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlcjsKCmNsYXNzIEpzb24gZXh0ZW5kcyBFeHBvcnRlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6Z2V0RGVzY3JpcHRpb24oKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJ0J1aWxkIGEgY29tcHJlc3NlZCBKU09OLWVuY29kZWQgZmlsZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG9wdGlvbnMgZm9yIGpzb25fZW5jb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0RW5jb2RlT3B0aW9ucygpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9IDA7CiAgICAgICAgaWYgKGRlZmluZWQoJ1xKU09OX1VORVNDQVBFRF9TTEFTSEVTJykpIHsKICAgICAgICAgICAgJHJlc3VsdCB8PSBcSlNPTl9VTkVTQ0FQRURfU0xBU0hFUzsKICAgICAgICB9CiAgICAgICAgaWYgKGRlZmluZWQoJ1xKU09OX1VORVNDQVBFRF9VTklDT0RFJykpIHsKICAgICAgICAgICAgJHJlc3VsdCB8PSBcSlNPTl9VTkVTQ0FQRURfVU5JQ09ERTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjp0b1N0cmluZ0RvKCkKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZ0RvKCRsYW5ndWFnZXMpCiAgICB7CiAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRsYW5ndWFnZXMgYXMgJGxhbmd1YWdlKSB7CiAgICAgICAgICAgICRpdGVtID0gYXJyYXkoKTsKICAgICAgICAgICAgJGl0ZW1bJ25hbWUnXSA9ICRsYW5ndWFnZS0+bmFtZTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+c3VwZXJzZWRlZEJ5KSkgewogICAgICAgICAgICAgICAgJGl0ZW1bJ3N1cGVyc2VkZWRCeSddID0gJGxhbmd1YWdlLT5zdXBlcnNlZGVkQnk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+c2NyaXB0KSkgewogICAgICAgICAgICAgICAgJGl0ZW1bJ3NjcmlwdCddID0gJGxhbmd1YWdlLT5zY3JpcHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+dGVycml0b3J5KSkgewogICAgICAgICAgICAgICAgJGl0ZW1bJ3RlcnJpdG9yeSddID0gJGxhbmd1YWdlLT50ZXJyaXRvcnk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYW5ndWFnZS0+YmFzZUxhbmd1YWdlKSkgewogICAgICAgICAgICAgICAgJGl0ZW1bJ2Jhc2VMYW5ndWFnZSddID0gJGxhbmd1YWdlLT5iYXNlTGFuZ3VhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGl0ZW1bJ2Zvcm11bGEnXSA9ICRsYW5ndWFnZS0+Zm9ybXVsYTsKICAgICAgICAgICAgJGl0ZW1bJ3BsdXJhbHMnXSA9IGNvdW50KCRsYW5ndWFnZS0+Y2F0ZWdvcmllcyk7CiAgICAgICAgICAgICRpdGVtWydjYXNlcyddID0gYXJyYXkoKTsKICAgICAgICAgICAgJGl0ZW1bJ2V4YW1wbGVzJ10gPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2UtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgICAgICAkaXRlbVsnY2FzZXMnXVtdID0gJGNhdGVnb3J5LT5pZDsKICAgICAgICAgICAgICAgICRpdGVtWydleGFtcGxlcyddWyRjYXRlZ29yeS0+aWRdID0gJGNhdGVnb3J5LT5leGFtcGxlczsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGlzdFskbGFuZ3VhZ2UtPmlkXSA9ICRpdGVtOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGpzb25fZW5jb2RlKCRsaXN0LCBzdGF0aWM6OmdldEVuY29kZU9wdGlvbnMoKSk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlcjsKCnVzZSBFeGNlcHRpb247CgovKioKICogQmFzZSBjbGFzcyBmb3IgYWxsIHRoZSBleHBvcnRlcnMuCiAqLwphYnN0cmFjdCBjbGFzcyBFeHBvcnRlcgp7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGV4cG9ydGVyczsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbGlzdCBvZiBhbGwgdGhlIGF2YWlsYWJsZSBleHBvcnRlcnMuIEtleXMgYXJlIHRoZSBleHBvcnRlciBoYW5kbGVzLCB2YWx1ZXMgYXJlIHRoZSBleHBvcnRlciBjbGFzcyBuYW1lcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkb25seUZvclB1YmxpY1VzZSBpZiB0cnVlLCBpbnRlcm5hbCBleHBvcnRlcnMgd2lsbCBiZSBvbWl0dGVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBmaW5hbCBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEV4cG9ydGVycygkb25seUZvclB1YmxpY1VzZSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGV4cG9ydGVycykpIHsKICAgICAgICAgICAgJGV4cG9ydGVycyA9IGFycmF5KCk7CiAgICAgICAgICAgICRtID0gbnVsbDsKICAgICAgICAgICAgZm9yZWFjaCAoc2NhbmRpcihfX0RJUl9fKSBhcyAkZikgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKFx3KylcLnBocCQvJywgJGYsICRtKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkZiAhPT0gYmFzZW5hbWUoX19GSUxFX18pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRleHBvcnRlcnNbc3RydG9sb3dlcigkbVsxXSldID0gJG1bMV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGY6OiRleHBvcnRlcnMgPSAkZXhwb3J0ZXJzOwogICAgICAgIH0KICAgICAgICBpZiAoJG9ubHlGb3JQdWJsaWNVc2UpIHsKICAgICAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKHNlbGY6OiRleHBvcnRlcnMgYXMgJGhhbmRsZSA9PiAkY2xhc3MpIHsKICAgICAgICAgICAgICAgIGlmIChjYWxsX3VzZXJfZnVuYyhzZWxmOjpnZXRFeHBvcnRlckNsYXNzTmFtZSgkaGFuZGxlKSAuICc6OmlzRm9yUHVibGljVXNlJykgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WyRoYW5kbGVdID0gJGNsYXNzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHJlc3VsdCA9IHNlbGY6OiRleHBvcnRlcnM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgZGVzY3JpcHRpb24gb2YgYSBzcGVjaWZpYyBleHBvcnRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRleHBvcnRlckhhbmRsZSB0aGUgaGFuZGxlIG9mIHRoZSBleHBvcnRlcgogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiB0aHJvd3MgYW4gRXhjZXB0aW9uIGlmICRleHBvcnRlckhhbmRsZSBpcyBub3QgdmFsaWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBmaW5hbCBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEV4cG9ydGVyRGVzY3JpcHRpb24oJGV4cG9ydGVySGFuZGxlKQogICAgewogICAgICAgICRleHBvcnRlcnMgPSBzZWxmOjpnZXRFeHBvcnRlcnMoKTsKICAgICAgICBpZiAoIWlzc2V0KCRleHBvcnRlcnNbJGV4cG9ydGVySGFuZGxlXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBleHBvcnRlciBoYW5kbGU6ICd7JGV4cG9ydGVySGFuZGxlfSciKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuYyhzZWxmOjpnZXRFeHBvcnRlckNsYXNzTmFtZSgkZXhwb3J0ZXJIYW5kbGUpIC4gJzo6Z2V0RGVzY3JpcHRpb24nKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIG9mIGEgZXhwb3J0ZXIgZ2l2ZW4gaXRzIGhhbmRsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRleHBvcnRlckhhbmRsZSB0aGUgZXhwb3J0ZXIgY2xhc3MgaGFuZGxlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgZmluYWwgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRFeHBvcnRlckNsYXNzTmFtZSgkZXhwb3J0ZXJIYW5kbGUpCiAgICB7CiAgICAgICAgcmV0dXJuIF9fTkFNRVNQQUNFX18gLiAnXFwnIC4gdWNmaXJzdChzdHJ0b2xvd2VyKCRleHBvcnRlckhhbmRsZSkpOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydCBhIGxpc3Qgb2YgTGFuZ3VhZ2UgaW5zdGFuY2VzIHRvIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gXEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlW10gJGxhbmd1YWdlcyB0aGUgTGFuZ3VhZ2UgaW5zdGFuY2VzIHRvIGNvbnZlcnQKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICRvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgZmluYWwgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZygkbGFuZ3VhZ2VzLCAkb3B0aW9ucyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zKSAmJiBpc19hcnJheSgkb3B0aW9ucykpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWyd1cy1hc2NpaSddKSAmJiAkb3B0aW9uc1sndXMtYXNjaWknXSkgewogICAgICAgICAgICAgICAgJGFzY2lpTGlzdCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2VzIGFzICRsYW5ndWFnZSkgewogICAgICAgICAgICAgICAgICAgICRhc2NpaUxpc3RbXSA9ICRsYW5ndWFnZS0+Z2V0VVNBc2NpaUNsb25lKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbGFuZ3VhZ2VzID0gJGFzY2lpTGlzdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0YXRpYzo6dG9TdHJpbmdEbygkbGFuZ3VhZ2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNhdmUgdGhlIExhbmd1YWdlIGluc3RhbmNlcyB0byBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIFxHZXR0ZXh0XExhbmd1YWdlc1xMYW5ndWFnZVtdICRsYW5ndWFnZXMgdGhlIExhbmd1YWdlIGluc3RhbmNlcyB0byBjb252ZXJ0CiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAkb3B0aW9ucwogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBmaW5hbCBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvRmlsZSgkbGFuZ3VhZ2VzLCAkZmlsZW5hbWUsICRvcHRpb25zID0gbnVsbCkKICAgIHsKICAgICAgICAkZGF0YSA9IHNlbGY6OnRvU3RyaW5nKCRsYW5ndWFnZXMsICRvcHRpb25zKTsKICAgICAgICBpZiAoQGZpbGVfcHV0X2NvbnRlbnRzKCRmaWxlbmFtZSwgJGRhdGEpID09PSBmYWxzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJFcnJvciB3cml0aW5nIGRhdGEgdG8gJ3skZmlsZW5hbWV9JyIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIElzIHRoaXMgZXhwb3J0ZXIgZm9yIHB1YmxpYyB1c2U/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNGb3JQdWJsaWNVc2UoKQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGV4cG9ydGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oZ2V0X2NhbGxlZF9jbGFzcygpIC4gJyBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlIG1ldGhvZCAnIC4gX19GVU5DVElPTl9fKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnQgYSBsaXN0IG9mIExhbmd1YWdlIGluc3RhbmNlcyB0byBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIFxHZXR0ZXh0XExhbmd1YWdlc1xMYW5ndWFnZVtdICRsYW5ndWFnZXMgdGhlIExhbmd1YWdlIGluc3RhbmNlcyB0byBjb252ZXJ0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZ0RvKCRsYW5ndWFnZXMpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihnZXRfY2FsbGVkX2NsYXNzKCkgLiAnIGRvZXMgbm90IGltcGxlbWVudCB0aGUgbWV0aG9kICcgLiBfX0ZVTkNUSU9OX18pOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXI7CgpjbGFzcyBSdWJ5IGV4dGVuZHMgRXhwb3J0ZXIKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OmdldERlc2NyaXB0aW9uKCkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICdCdWlsZCBhIFJ1YnkgaGFzaCc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OnRvU3RyaW5nRG8oKQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nRG8oJGxhbmd1YWdlcykKICAgIHsKICAgICAgICAkbGluZXMgPSBhcnJheSgpOwogICAgICAgICRsaW5lc1tdID0gJ1BMVVJBTF9SVUxFUyA9IHsnOwogICAgICAgIGZvcmVhY2ggKCRsYW5ndWFnZXMgYXMgJGxjKSB7CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgXCcnIC4gJGxjLT5pZCAuICdcJyA9PiB7JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAnICAgIFwnbmFtZVwnID0+IFwnJyAuIGFkZHNsYXNoZXMoJGxjLT5uYW1lKSAuICdcJywnOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5zdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgXCdzdXBlcnNlZGVkQnlcJyA9PiBcJycgLiAkbGMtPnN1cGVyc2VkZWRCeSAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkbGMtPnNjcmlwdCkpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICBcJ3NjcmlwdFwnID0+IFwnJyAuIGFkZHNsYXNoZXMoJGxjLT5zY3JpcHQpIC4gJ1wnLCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCRsYy0+dGVycml0b3J5KSkgewogICAgICAgICAgICAgICAgJGxpbmVzW10gPSAnICAgIFwndGVycml0b3J5XCcgPT4gXCcnIC4gYWRkc2xhc2hlcygkbGMtPnRlcnJpdG9yeSkgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5iYXNlTGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgXCdiYXNlTGFuZ3VhZ2VcJyA9PiBcJycgLiBhZGRzbGFzaGVzKCRsYy0+YmFzZUxhbmd1YWdlKSAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICBcJ2Zvcm11bGFcJyA9PiBcJycgLiAkbGMtPmZvcm11bGEgLiAnXCcsJzsKICAgICAgICAgICAgJGxpbmVzW10gPSAnICAgIFwncGx1cmFsc1wnID0+ICcgLiBjb3VudCgkbGMtPmNhdGVnb3JpZXMpIC4gJywnOwogICAgICAgICAgICAkY2F0TmFtZXMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbGMtPmNhdGVnb3JpZXMgYXMgJGMpIHsKICAgICAgICAgICAgICAgICRjYXROYW1lc1tdID0gIid7JGMtPmlkfSciOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICBcJ2Nhc2VzXCcgPT4gWycgLiBpbXBsb2RlKCcsICcsICRjYXROYW1lcykgLiAnXSwnOwogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgXCdleGFtcGxlc1wnID0+IHsnOwogICAgICAgICAgICBmb3JlYWNoICgkbGMtPmNhdGVnb3JpZXMgYXMgJGMpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgIFwnJyAuICRjLT5pZCAuICdcJyA9PiBcJycgLiAkYy0+ZXhhbXBsZXMgLiAnXCcsJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgfSwnOwogICAgICAgICAgICAkbGluZXNbXSA9ICcgIH0sJzsKICAgICAgICB9CiAgICAgICAgJGxpbmVzW10gPSAnfSc7CiAgICAgICAgJGxpbmVzW10gPSAnJzsKCiAgICAgICAgcmV0dXJuIGltcGxvZGUoIlxuIiwgJGxpbmVzKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgSHRtbCBleHRlbmRzIEV4cG9ydGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjpnZXREZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAnQnVpbGQgYSBIVE1MIHRhYmxlJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6dG9TdHJpbmdEbygpCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmdEbygkbGFuZ3VhZ2VzKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpidWlsZFRhYmxlKCRsYW5ndWFnZXMsIGZhbHNlKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGgoJHN0cikKICAgIHsKICAgICAgICByZXR1cm4gaHRtbHNwZWNpYWxjaGFycygkc3RyLCBFTlRfQ09NUEFULCAnVVRGLTgnKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGJ1aWxkVGFibGUoJGxhbmd1YWdlcywgJGZvckRvY3MpCiAgICB7CiAgICAgICAgJHByZWZpeCA9ICRmb3JEb2NzID8gJyAgICAgICAgICAgICcgOiAnJzsKICAgICAgICAkbGluZXMgPSBhcnJheSgpOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICc8dGFibGUnIC4gKCRmb3JEb2NzID8gJyBjbGFzcz0idGFibGUgdGFibGUtYm9yZGVyZWQgdGFibGUtY29uZGVuc2VkIHRhYmxlLXN0cmlwZWQiJyA6ICcnKSAuICc+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgIDx0aGVhZD4nOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgIDx0cj4nOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgICAgICA8dGg+TGFuZ3VhZ2UgY29kZTwvdGg+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICAgICAgPHRoPkxhbmd1YWdlIG5hbWU8L3RoPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0aD4jIHBsdXJhbHM8L3RoPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0aD5Gb3JtdWxhPC90aD4nOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgICAgICA8dGg+UGx1cmFsczwvdGg+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICA8L3RyPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICA8L3RoZWFkPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICA8dGJvZHk+JzsKICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2VzIGFzICRsYykgewogICAgICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICA8dHI+JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0ZD4nIC4gJGxjLT5pZCAuICc8L3RkPic7CiAgICAgICAgICAgICRuYW1lID0gc2VsZjo6aCgkbGMtPm5hbWUpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5zdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAkbmFtZSAuPSAnPGJyIC8+PHNtYWxsPjxzcGFuPlN1cGVyc2VkZWQgYnk8L3NwYW4+ICcgLiAkbGMtPnN1cGVyc2VkZWRCeSAuICc8L3NtYWxsPic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0ZD4nIC4gJG5hbWUgLiAnPC90ZD4nOwogICAgICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICAgICAgPHRkPicgLiBjb3VudCgkbGMtPmNhdGVnb3JpZXMpIC4gJzwvdGQ+JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0ZD4nIC4gc2VsZjo6aCgkbGMtPmZvcm11bGEpIC4gJzwvdGQ+JzsKICAgICAgICAgICAgJGNhc2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxjLT5jYXRlZ29yaWVzIGFzICRjKSB7CiAgICAgICAgICAgICAgICAkY2FzZXNbXSA9ICc8bGk+PHNwYW4+JyAuICRjLT5pZCAuICc8L3NwYW4+PGNvZGU+JyAuIHNlbGY6OmgoJGMtPmV4YW1wbGVzKSAuICc8L2NvZGU+PC9saT4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgICAgICA8dGQ+PG9sJyAuICgkZm9yRG9jcyA/ICcgY2xhc3M9ImNhc2VzIicgOiAnJykgLiAnIHN0YXJ0PSIwIj4nIC4gaW1wbG9kZSgnJywgJGNhc2VzKSAuICc8L29sPjwvdGQ+JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgPC90cj4nOwogICAgICAgIH0KICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgIDwvdGJvZHk+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnPC90YWJsZT4nOwoKICAgICAgICByZXR1cm4gaW1wbG9kZSgiXG4iLCAkbGluZXMpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXI7Cgp1c2UgRXhjZXB0aW9uOwoKY2xhc3MgUG8gZXh0ZW5kcyBFeHBvcnRlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6Z2V0RGVzY3JpcHRpb24oKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJ0J1aWxkIGEgc3RyaW5nIHRvIGJlIHVzZWQgZm9yIGdldHRleHQgLnBvIGZpbGVzJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6dG9TdHJpbmdEbygpCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmdEbygkbGFuZ3VhZ2VzKQogICAgewogICAgICAgIGlmIChjb3VudCgkbGFuZ3VhZ2VzKSAhPT0gMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdUaGUgJyAuIGdldF9jYWxsZWRfY2xhc3MoKSAuICcgZXhwb3J0ZXIgY2FuIG9ubHkgZXhwb3J0IG9uZSBsYW5ndWFnZScpOwogICAgICAgIH0KICAgICAgICAkbGFuZ3VhZ2UgPSAkbGFuZ3VhZ2VzWzBdOwogICAgICAgICRsaW5lcyA9IGFycmF5KCk7CiAgICAgICAgJGxpbmVzW10gPSAnIkxhbmd1YWdlOiAnIC4gJGxhbmd1YWdlLT5pZCAuICdcbiInOwogICAgICAgICRsaW5lc1tdID0gJyJQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPScgLiBjb3VudCgkbGFuZ3VhZ2UtPmNhdGVnb3JpZXMpIC4gJzsgcGx1cmFsPScgLiAkbGFuZ3VhZ2UtPmZvcm11bGEgLiAnXG4iJzsKICAgICAgICAkbGluZXNbXSA9ICcnOwoKICAgICAgICByZXR1cm4gaW1wbG9kZSgiXG4iLCAkbGluZXMpOwogICAgfQp9Cjw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3Q7CgovKioKICogTm9kZXMgcmVuZGVyZXIgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUmVuZGVyZXIKewogICAgLyoqCiAgICAgKiBGb3JtYXR0ZXIgdG8gdXNlIGZvciB0aGUgcmVuZGVyaW5nCiAgICAgKiAKICAgICAqIEB2YXIgRm9ybWF0dGVyXEJhc2UKICAgICAqLwogICAgcHJvdGVjdGVkICRmb3JtYXR0ZXI7CiAgICAKICAgIC8qKgogICAgICogUmVuZGVyaW5nIG9wdGlvbnMgdGFrZW4gZnJvbSB0aGUgZm9ybWF0dGVyCiAgICAgKiAKICAgICAqIEB2YXIgb2JqZWN0CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVuZGVyT3B0czsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlIHR5cGVzIHRoYXQgZG9lcyBub3QgcmVxdWlyZSBzZW1pY29sb24gaW5zZXJ0aW9uCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRub1NlbWljb2xvbiA9IGFycmF5KAogICAgICAgICJDbGFzc0RlY2xhcmF0aW9uIiwKICAgICAgICAiRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uIiwKICAgICAgICAiRm9ySW5TdGF0ZW1lbnQiLAogICAgICAgICJGb3JPZlN0YXRlbWVudCIsCiAgICAgICAgIkZvclN0YXRlbWVudCIsCiAgICAgICAgIkZ1bmN0aW9uRGVjbGFyYXRpb24iLAogICAgICAgICJJZlN0YXRlbWVudCIsCiAgICAgICAgIkxhYmVsZWRTdGF0ZW1lbnQiLAogICAgICAgICJTdGF0aWNCbG9jayIsCiAgICAgICAgIlN3aXRjaFN0YXRlbWVudCIsCiAgICAgICAgIlRyeVN0YXRlbWVudCIsCiAgICAgICAgIldoaWxlU3RhdGVtZW50IiwKICAgICAgICAiV2l0aFN0YXRlbWVudCIsCiAgICAgICAgIk1ldGhvZERlZmluaXRpb24iCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGZvcm1hdHRlciB0byB1c2UgZm9yIHRoZSByZW5kZXJpbmcKICAgICAqIAogICAgICogQHBhcmFtIEZvcm1hdHRlclxCYXNlICAgICRmb3JtYXR0ZXIgIEZvcm1hdHRlcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGb3JtYXR0ZXIoRm9ybWF0dGVyXEJhc2UgJGZvcm1hdHRlcikKICAgIHsKICAgICAgICAkdGhpcy0+Zm9ybWF0dGVyID0gJGZvcm1hdHRlcjsKICAgICAgICAKICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cyA9IChvYmplY3QpIGFycmF5KAogICAgICAgICAgICAibmwiID0+ICR0aGlzLT5mb3JtYXR0ZXItPmdldE5ld0xpbmUoKSwKICAgICAgICAgICAgImluZCIgPT4gJHRoaXMtPmZvcm1hdHRlci0+Z2V0SW5kZW50YXRpb24oKSwKICAgICAgICAgICAgIm5sYmMiID0+ICR0aGlzLT5mb3JtYXR0ZXItPmdldE5ld0xpbmVCZWZvcmVDdXJseUJyYWNrZXQoKSwKICAgICAgICAgICAgInNhbyIgPT4gICR0aGlzLT5mb3JtYXR0ZXItPmdldFNwYWNlc0Fyb3VuZE9wZXJhdG9yKCkgPyAiICIgOiAiIiwKICAgICAgICAgICAgInNpcmIiID0+ICR0aGlzLT5mb3JtYXR0ZXItPmdldFNwYWNlc0luc2lkZVJvdW5kQnJhY2tldHMoKSA/ICIgIiA6ICIiLAogICAgICAgICAgICAiYXdiIiA9PiAkdGhpcy0+Zm9ybWF0dGVyLT5nZXRBbHdheXNXcmFwQmxvY2tzKCkKICAgICAgICApOwogICAgICAgIAogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZXIgdG8gdXNlIGZvciB0aGUgcmVuZGVyaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gRm9ybWF0dGVyXEJhc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdHRlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mb3JtYXR0ZXI7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmVuZGVycyB0aGUgZ2l2ZW4gbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBOb2RlIHRvIHJlbmRlcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcihTeW50YXhcTm9kZVxOb2RlICRub2RlKQogICAgewogICAgICAgIC8vVGhyb3cgZXhjZXB0aW9uIGlmIG5vIGZvcm1hdHRlciBoYXMgYmVlbiBzcGVjaWZpZWQKICAgICAgICBpZiAoISR0aGlzLT5mb3JtYXR0ZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oIkZvcm1hdHRlciBub3Qgc2V0Iik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vUmVzZXQgaW5kZW50YXRpb24gbGV2ZWwKICAgICAgICAkdGhpcy0+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+Z2V0Qm9keSgpLCB0cnVlCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiQ29uZGl0aW9uYWxFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRUZXN0KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgIj8iIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldENvbnNlcXVlbnQoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiOiIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0QWx0ZXJuYXRlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiRGVidWdnZXJTdGF0ZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImRlYnVnZ2VyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkRvV2hpbGVTdGF0ZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImRvIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0Qm9keSgpLCBudWxsLCB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICApIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgIndoaWxlIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0VGVzdCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hFbXB0eUV4cHJlc3Npb24iOgogICAgICAgICAgICBjYXNlICJFbXB0eVN0YXRlbWVudCI6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJFeHBvcnRBbGxEZWNsYXJhdGlvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiZXhwb3J0ICoiOwogICAgICAgICAgICAgICAgJGV4cG9ydGVkID0gJG5vZGUtPmdldEV4cG9ydGVkKCk7CiAgICAgICAgICAgICAgICBpZiAoJGV4cG9ydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiBhcyAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJGV4cG9ydGVkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICIgZnJvbSAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldFNvdXJjZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvbiI6CiAgICAgICAgICAgICAgICAkZGVjbGFyYXRpb24gPSAkbm9kZS0+Z2V0RGVjbGFyYXRpb24oKTsKICAgICAgICAgICAgICAgICRjb2RlIC49ICJleHBvcnQgZGVmYXVsdCAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRkZWNsYXJhdGlvbik7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnJlcXVpcmVzU2VtaWNvbG9uKCRkZWNsYXJhdGlvbikpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiOyI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJFeHBvcnROYW1lZERlY2xhcmF0aW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJleHBvcnQiOwogICAgICAgICAgICAgICAgaWYgKCRkZWMgPSAkbm9kZS0+Z2V0RGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIgIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJGRlYyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ7IiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPmdldFNwZWNpZmllcnMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPnNhbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9IjsKICAgICAgICAgICAgICAgICAgICBpZiAoJHNvdXJjZSA9ICRub2RlLT5nZXRTb3VyY2UoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZyb20gIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkV4cG9ydFNwZWNpZmllciI6CiAgICAgICAgICAgICAgICAkbG9jYWwgPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TG9jYWwoKSk7CiAgICAgICAgICAgICAgICAkcmVmID0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEV4cG9ydGVkKCkpOwogICAgICAgICAgICAgICAgJGNvZGUgLj0gJGxvY2FsID09PSAkcmVmID8KICAgICAgICAgICAgICAgICAgICAgICAgICRsb2NhbCA6CiAgICAgICAgICAgICAgICAgICAgICAgICAkbG9jYWwgLiAiIGFzICIgLiAkcmVmOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiRm9ySW5TdGF0ZW1lbnQiOgogICAgICAgICAgICBjYXNlICJGb3JPZlN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAvL0ZvcmNlIHNpbmdsZSBsaW5lIG1vZGUgZm9yIHN1YnN0YXRlbWVudHMKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5mb3JjZVNpbmdsZUxpbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgJGNvZGUgLj0gImZvciIgLgogICAgICAgICAgICAgICAgICAgICAgICAgKCR0eXBlID09PSAiRm9yT2ZTdGF0ZW1lbnQiICYmICRub2RlLT5nZXRBd2FpdCgpID8gIiBhd2FpdCIgOiAiIikgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldExlZnQoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgIiAiIC4gKCR0eXBlID09PSAiRm9ySW5TdGF0ZW1lbnQiID8gImluIiA6ICJvZiIpIC4gIiAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRSaWdodCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKCRub2RlLT5nZXRCb2R5KCkpOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnJlbmRlck9wdHMtPmZvcmNlU2luZ2xlTGluZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJGb3JTdGF0ZW1lbnQiOgogICAgICAgICAgICAgICAgLy9Gb3JjZSBzaW5nbGUgbGluZSBtb2RlIGZvciBzdWJzdGF0ZW1lbnRzCiAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+Zm9yY2VTaW5nbGVMaW5lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICRjb2RlIC49ICJmb3IiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgIigiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiOwogICAgICAgICAgICAgICAgaWYgKCRpbml0ID0gJG5vZGUtPmdldEluaXQoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRpbml0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IiAuICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgICAgICBpZiAoJHRlc3QgPSAkbm9kZS0+Z2V0VGVzdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJHRlc3QpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gIjsiIC4gJHRoaXMtPnJlbmRlck9wdHMtPnNhbzsKICAgICAgICAgICAgICAgIGlmICgkdXBkYXRlID0gJG5vZGUtPmdldFVwZGF0ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJHVwZGF0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKCRub2RlLT5nZXRCb2R5KCkpOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnJlbmRlck9wdHMtPmZvcmNlU2luZ2xlTGluZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJGdW5jdGlvbkRlY2xhcmF0aW9uIjoKICAgICAgICAgICAgY2FzZSAiRnVuY3Rpb25FeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRpZCA9ICRub2RlLT5nZXRJZCgpOwogICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRBc3luYygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gImFzeW5jICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiZnVuY3Rpb24iOwogICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRHZW5lcmF0b3IoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICIqIjsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkaWQpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGlkKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRHZW5lcmF0b3IoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkaWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRQYXJhbXMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIiAuICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8KICAgICAgICAgICAgICAgICAgICAgICAgICkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgIikiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygkbm9kZS0+Z2V0Qm9keSgpLCB0cnVlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkltcG9ydEV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImltcG9ydCgiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRTb3VyY2UoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgIikiOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYSWRlbnRpZmllciI6CiAgICAgICAgICAgIGNhc2UgIklkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldFJhd05hbWUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIklmU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJpZiIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldFRlc3QoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgIikiOwogICAgICAgICAgICAgICAgJGNvbnNlcXVlbnQgPSAkbm9kZS0+Z2V0Q29uc2VxdWVudCgpOwogICAgICAgICAgICAgICAgJGFsdGVybmF0ZSA9ICRub2RlLT5nZXRBbHRlcm5hdGUoKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJGZvcmNlQnJhY2tldHNDb25zZXF1ZW50ID0gJGZvcmNlQnJhY2tldHNBbHRlcm5hdGUgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+cmVuZGVyT3B0cy0+YXdiICYmICRhbHRlcm5hdGUpIHsKICAgICAgICAgICAgICAgICAgICAkZm9yY2VCcmFja2V0c0NvbnNlcXVlbnQgPSAkdGhpcy0+Y2hlY2tJZlBhcnRzQnJhY2tldHNSZXF1aXJlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnNlcXVlbnQKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICRmb3JjZUJyYWNrZXRzQWx0ZXJuYXRlID0gJHRoaXMtPmNoZWNrSWZQYXJ0c0JyYWNrZXRzUmVxdWlyZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICRhbHRlcm5hdGUKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soCiAgICAgICAgICAgICAgICAgICAgJGNvbnNlcXVlbnQsICRmb3JjZUJyYWNrZXRzQ29uc2VxdWVudAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkYWx0ZXJuYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVsc2UiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRhbHRlcm5hdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmb3JjZUJyYWNrZXRzQWx0ZXJuYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkltcG9ydERlY2xhcmF0aW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJpbXBvcnQgIjsKICAgICAgICAgICAgICAgICRzcGVjaWZpZXJzID0gJG5vZGUtPmdldFNwZWNpZmllcnMoKTsKICAgICAgICAgICAgICAgIGlmIChjb3VudCgkc3BlY2lmaWVycykpIHsKICAgICAgICAgICAgICAgICAgICAkc2VwID0gIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPnNhbzsKICAgICAgICAgICAgICAgICAgICAkZ3JvdXBzID0gJHBhcnRzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkc3BlY2lmaWVycyBhcyAkc3BlYykgewogICAgICAgICAgICAgICAgICAgICAgICAkc3BlY1R5cGUgPSAkc3BlYy0+Z2V0VHlwZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRncm91cHNbJHNwZWNUeXBlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRncm91cHNbJHNwZWNUeXBlXSA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGdyb3Vwc1skc3BlY1R5cGVdW10gPSAkc3BlYzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRncm91cHNbIkltcG9ydERlZmF1bHRTcGVjaWZpZXIiXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGdyb3Vwc1siSW1wb3J0RGVmYXVsdFNwZWNpZmllciJdIGFzICRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFydHNbXSA9ICR0aGlzLT5yZW5kZXJOb2RlKCRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGdyb3Vwc1siSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyIl0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRncm91cHNbIkltcG9ydE5hbWVzcGFjZVNwZWNpZmllciJdIGFzICRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFydHNbXSA9ICR0aGlzLT5yZW5kZXJOb2RlKCRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGdyb3Vwc1siSW1wb3J0U3BlY2lmaWVyIl0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpbXBTcGVjID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGdyb3Vwc1siSW1wb3J0U3BlY2lmaWVyIl0gYXMgJHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbXBTcGVjW10gPSAkdGhpcy0+cmVuZGVyTm9kZSgkcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnRzW10gPSAieyIgLiBpbXBsb2RlKCRzZXAsICRpbXBTcGVjKSAuICJ9IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gaW1wbG9kZSgkc2VwLCAkcGFydHMpIC4gIiBmcm9tICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0U291cmNlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSW1wb3J0RGVmYXVsdFNwZWNpZmllciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TG9jYWwoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXIiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gIiogYXMgIiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRMb2NhbCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkltcG9ydFNwZWNpZmllciI6CiAgICAgICAgICAgICAgICAkbG9jYWwgPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TG9jYWwoKSk7CiAgICAgICAgICAgICAgICAkcmVmID0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEltcG9ydGVkKCkpOwogICAgICAgICAgICAgICAgJGNvZGUgLj0gJGxvY2FsID09PSAkcmVmID8KICAgICAgICAgICAgICAgICAgICAgICAgICRsb2NhbCA6CiAgICAgICAgICAgICAgICAgICAgICAgICAkcmVmIC4gIiBhcyAiIC4gJGxvY2FsOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYQXR0cmlidXRlIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXROYW1lKCkpOwogICAgICAgICAgICAgICAgaWYgKCR2YWx1ZSA9ICRub2RlLT5nZXRWYWx1ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIj0iIC4gJHRoaXMtPnJlbmRlck5vZGUoJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWENsb3NpbmdFbGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICI8LyIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TmFtZSgpKSAuICI+IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWENsb3NpbmdGcmFnbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiPC8+IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWEVsZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldE9wZW5pbmdFbGVtZW50KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5qb2luTm9kZXMoJG5vZGUtPmdldENoaWxkcmVuKCksICIiKTsKICAgICAgICAgICAgICAgIGlmICgkY2xvc2luZyA9ICRub2RlLT5nZXRDbG9zaW5nRWxlbWVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJGNsb3NpbmcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYRXhwcmVzc2lvbkNvbnRhaW5lciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAieyIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0RXhwcmVzc2lvbigpKSAuICJ9IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWEZyYWdtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRPcGVuaW5nRnJhZ21lbnQoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2Rlcygkbm9kZS0+Z2V0Q2hpbGRyZW4oKSwgIiIpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRDbG9zaW5nRnJhZ21lbnQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hOYW1lc3BhY2VkTmFtZSI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TmFtZXNwYWNlKCkpIC4gIjoiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXROYW1lKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYT3BlbmluZ0VsZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gIjwiIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICAkYXR0cmlidXRlcyA9ICRub2RlLT5nZXRBdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgICAgICBpZiAoY291bnQoJGF0dHJpYnV0ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiIC4gJHRoaXMtPmpvaW5Ob2RlcygkYXR0cmlidXRlcywgIiAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0U2VsZkNsb3NpbmcoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIvIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICI+IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWE9wZW5pbmdGcmFnbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiPD4iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYU3ByZWFkQXR0cmlidXRlIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ7Li4uIiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRBcmd1bWVudCgpKSAuICJ9IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWFNwcmVhZENoaWxkIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ7Li4uIiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRFeHByZXNzaW9uKCkpIC4gIn0iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiTGFiZWxlZFN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkYm9keSA9ICRub2RlLT5nZXRCb2R5KCk7CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TGFiZWwoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgIjoiOwogICAgICAgICAgICAgICAgaWYgKCRib2R5LT5nZXRUeXBlKCkgPT09ICJCbG9ja1N0YXRlbWVudCIpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJGJvZHksIHRydWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+bmwgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5nZXRJbmRlbnRhdGlvbigpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkYm9keSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnJlcXVpcmVzU2VtaWNvbG9uKCRib2R5KSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWFRleHQiOgogICAgICAgICAgICBjYXNlICJMaXRlcmFsIjoKICAgICAgICAgICAgY2FzZSAiUmVnRXhwTGl0ZXJhbCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkbm9kZS0+Z2V0UmF3KCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hNZW1iZXJFeHByZXNzaW9uIjoKICAgICAgICAgICAgY2FzZSAiTWVtYmVyRXhwcmVzc2lvbiI6CiAgICAgICAgICAgICAgICAkcHJvcGVydHkgPSAkbm9kZS0+Z2V0UHJvcGVydHkoKTsKICAgICAgICAgICAgICAgICRjb21waWxlZFByb3BlcnR5ID0gJHRoaXMtPnJlbmRlck5vZGUoJHByb3BlcnR5KTsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRPYmplY3QoKSk7CiAgICAgICAgICAgICAgICAkb3B0aW9uYWwgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gIk1lbWJlckV4cHJlc3Npb24iKSB7CiAgICAgICAgICAgICAgICAgICAgJG9wdGlvbmFsID0gJG5vZGUtPmdldE9wdGlvbmFsKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcHJvcGVydHlUeXBlID0gJHByb3BlcnR5LT5nZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICJNZW1iZXJFeHByZXNzaW9uIiAmJgogICAgICAgICAgICAgICAgICAgICgkbm9kZS0+Z2V0Q29tcHV0ZWQoKSB8fAogICAgICAgICAgICAgICAgICAgICgkcHJvcGVydHlUeXBlICE9PSAiSWRlbnRpZmllciIgJiYgJHByb3BlcnR5VHlwZSAhPT0gIlByaXZhdGVJZGVudGlmaWVyIikpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gKCRvcHRpb25hbCA/ICI/LiIgOiAiIikgLiAiWyIgLiAkY29tcGlsZWRQcm9wZXJ0eSAuICJdIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gKCRvcHRpb25hbCA/ICI/LiIgOiAiLiIpIC4gJGNvbXBpbGVkUHJvcGVydHk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJNZXRhUHJvcGVydHkiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldE1ldGEoKSAuICIuIiAuICRub2RlLT5nZXRQcm9wZXJ0eSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiTWV0aG9kRGVmaW5pdGlvbiI6CiAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldFN0YXRpYygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gInN0YXRpYyAiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHZhbHVlID0gJG5vZGUtPmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAka2V5ID0gJG5vZGUtPmdldEtleSgpOwogICAgICAgICAgICAgICAgJGtpbmQgPSAkbm9kZS0+Z2V0S2luZCgpOwogICAgICAgICAgICAgICAgaWYgKCRraW5kID09PSAkbm9kZTo6S0lORF9HRVQgfHwgJGtpbmQgPT09ICRub2RlOjpLSU5EX1NFVCkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICRraW5kIC4gIiAiOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHZhbHVlLT5nZXRBc3luYygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJhc3luYyAiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHZhbHVlLT5nZXRHZW5lcmF0b3IoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiKiIgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0Q29tcHV0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJbIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJGtleSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJdIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJGtleSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgIHByZWdfcmVwbGFjZSgiL15bXihdKy8iLCAiIiwgJHRoaXMtPnJlbmRlck5vZGUoJHZhbHVlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJPYmplY3RFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjdXJyZW50SW5kZW50YXRpb24gPSAkdGhpcy0+Z2V0SW5kZW50YXRpb24oKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbCsrOwogICAgICAgICAgICAgICAgJGluZGVudGF0aW9uID0gJHRoaXMtPmdldEluZGVudGF0aW9uKCk7CiAgICAgICAgICAgICAgICAvL0hhbmRsZSBzaW5nbGUgbGluZSBtb2RlCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlbmRlck9wdHMtPmZvcmNlU2luZ2xlTGluZSkpIHsKICAgICAgICAgICAgICAgICAgICAkc3RhcnQgPSAkZW5kID0gIiI7CiAgICAgICAgICAgICAgICAgICAgJHNlcGFyYXRvciA9ICIsIiAuICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRlbmQgPSAkdGhpcy0+cmVuZGVyT3B0cy0+bmwgLiAkY3VycmVudEluZGVudGF0aW9uOwogICAgICAgICAgICAgICAgICAgICRzdGFydCA9ICR0aGlzLT5yZW5kZXJPcHRzLT5ubCAuICRpbmRlbnRhdGlvbjsKICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yID0gIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4gJGluZGVudGF0aW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gInsiOwogICAgICAgICAgICAgICAgJHByb3BlcnRpZXMgPSAkbm9kZS0+Z2V0UHJvcGVydGllcygpOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRwcm9wZXJ0aWVzKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICRzdGFydCAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJvcGVydGllcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICJ9IjsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbC0tOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiT2JqZWN0UGF0dGVybiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAieyIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRQcm9wZXJ0aWVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApIC4KICAgICAgICAgICAgICAgICAgICAgICAgICJ9IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0RXhwcmVzc2lvbigpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJQcml2YXRlSWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiIyIgLiAkbm9kZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiUHJvcGVydHkiOgogICAgICAgICAgICAgICAgJHZhbHVlID0gJG5vZGUtPmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAka2V5ID0gJG5vZGUtPmdldEtleSgpOwogICAgICAgICAgICAgICAgJGNvbXBpbGVkS2V5ID0gJHRoaXMtPnJlbmRlck5vZGUoJGtleSk7CiAgICAgICAgICAgICAgICAkY29tcGlsZWRWYWx1ZSA9ICR0aGlzLT5yZW5kZXJOb2RlKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAka2V5VHlwZSA9ICRrZXktPmdldFR5cGUoKTsKICAgICAgICAgICAgICAgICR2YWx1ZVR5cGUgPSAkdmFsdWUtPmdldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmICgkdmFsdWVUeXBlID09PSAiQXNzaWdubWVudFBhdHRlcm4iICYmCiAgICAgICAgICAgICAgICAgICAgJGNvbXBpbGVkS2V5ID09PSAkdGhpcy0+cmVuZGVyTm9kZSgkdmFsdWUtPmdldExlZnQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkY29tcGlsZWRWYWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGtpbmQgPSAkbm9kZS0+Z2V0S2luZCgpOwogICAgICAgICAgICAgICAgICAgICRnZXR0ZXJTZXR0ZXIgPSAka2luZCA9PT0gJG5vZGU6OktJTkRfR0VUIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRraW5kID09PSAkbm9kZTo6S0lORF9TRVQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRnZXR0ZXJTZXR0ZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJGtpbmQgLiAiICI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR2YWx1ZS0+Z2V0VHlwZSgpID09PSAiRnVuY3Rpb25FeHByZXNzaW9uIiAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmFsdWUtPmdldEdlbmVyYXRvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIqIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0Q29tcHV0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiWyIgLiAkY29tcGlsZWRLZXkgLiAiXSI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJGNvbXBpbGVkS2V5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldE1ldGhvZCgpIHx8ICRnZXR0ZXJTZXR0ZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWdfcmVwbGFjZSgiL15bXihdKy8iLCAiIiwgJGNvbXBpbGVkVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgka2V5VHlwZSAhPT0gIklkZW50aWZpZXIiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWx1ZVR5cGUgIT09ICJJZGVudGlmaWVyIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29tcGlsZWRLZXkgIT09ICRjb21waWxlZFZhbHVlCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICgkbm9kZS0+Z2V0U2hvcnRoYW5kKCkgPyAiPSIgOiAiOiIpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb21waWxlZFZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlByb3BlcnR5RGVmaW5pdGlvbiI6CiAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldFN0YXRpYygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gInN0YXRpYyAiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvbXBpbGVkS2V5ID0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEtleSgpKTsKICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0Q29tcHV0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJbIiAuICRjb21waWxlZEtleSAuICJdIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJGNvbXBpbGVkS2V5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR2YWx1ZSA9ICRub2RlLT5nZXRWYWx1ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIj0iIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiUmVzdEVsZW1lbnQiOgogICAgICAgICAgICBjYXNlICJTcHJlYWRFbGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICIuLi4iIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEFyZ3VtZW50KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiUmV0dXJuU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJyZXR1cm4iOwogICAgICAgICAgICAgICAgaWYgKCRhcmd1bWVudCA9ICRub2RlLT5nZXRBcmd1bWVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlNlcXVlbmNlRXhwcmVzc2lvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPmdldEV4cHJlc3Npb25zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiU3RhdGljQmxvY2siOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gInN0YXRpYyI7CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJvZHkoKSwgdHJ1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJTdXBlciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAic3VwZXIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiU3dpdGNoQ2FzZSI6CiAgICAgICAgICAgICAgICBpZiAoJHRlc3QgPSAkbm9kZS0+Z2V0VGVzdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gImNhc2UgIiAuICR0aGlzLT5yZW5kZXJOb2RlKCR0ZXN0KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gImRlZmF1bHQiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gIjoiOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRub2RlLT5nZXRDb25zZXF1ZW50KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRDb25zZXF1ZW50KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlN3aXRjaFN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAic3dpdGNoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0RGlzY3JpbWluYW50KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPmdldENhc2VzKCksIHRydWUsIGZhbHNlLCBmYWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlRhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0VGFnKCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRRdWFzaSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlRlbXBsYXRlRWxlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkbm9kZS0+Z2V0UmF3VmFsdWUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlRlbXBsYXRlTGl0ZXJhbCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiYCI7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbm9kZS0+Z2V0UGFydHMoKSBhcyAkcGFydCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkcGFydC0+Z2V0VHlwZSgpID09PSAiVGVtcGxhdGVFbGVtZW50IikgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkcGFydCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiQiIC4gInsiIC4gJHRoaXMtPnJlbmRlck5vZGUoJHBhcnQpIC4gIn0iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICJgIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlRoaXNFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ0aGlzIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlRocm93U3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ0aHJvdyAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEFyZ3VtZW50KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiVHJ5U3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ0cnkiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygkbm9kZS0+Z2V0QmxvY2soKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoJGhhbmRsZXIgPSAkbm9kZS0+Z2V0SGFuZGxlcigpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJGhhbmRsZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRmaW5hbGl6ZXIgPSAkbm9kZS0+Z2V0RmluYWxpemVyKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmluYWxseSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygkZmluYWxpemVyLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlVuYXJ5RXhwcmVzc2lvbiI6CiAgICAgICAgICAgIGNhc2UgIlVwZGF0ZUV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJHByZWZpeCA9ICRub2RlLT5nZXRQcmVmaXgoKTsKICAgICAgICAgICAgICAgIGlmICgkcHJlZml4KSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldE9wZXJhdG9yKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goIiNeW2Etel0rJCNpIiwgJG5vZGUtPmdldE9wZXJhdG9yKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0QXJndW1lbnQoKSk7CiAgICAgICAgICAgICAgICBpZiAoISRwcmVmaXgpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkbm9kZS0+Z2V0T3BlcmF0b3IoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlZhcmlhYmxlRGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPmluZExldmVsKys7CiAgICAgICAgICAgICAgICAkaW5kZW50YXRpb24gPSAkdGhpcy0+Z2V0SW5kZW50YXRpb24oKTsKICAgICAgICAgICAgICAgIC8vSGFuZGxlIHNpbmdsZSBsaW5lIG1vZGUKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVuZGVyT3B0cy0+Zm9yY2VTaW5nbGVMaW5lKSkgewogICAgICAgICAgICAgICAgICAgICRzZXBhcmF0b3IgPSAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yID0gIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4gJGluZGVudGF0aW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldEtpbmQoKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiICIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXREZWNsYXJhdGlvbnMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+aW5kTGV2ZWwtLTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlZhcmlhYmxlRGVjbGFyYXRvciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0SWQoKSk7CiAgICAgICAgICAgICAgICBpZiAoJGluaXQgPSAkbm9kZS0+Z2V0SW5pdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIj0iIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkaW5pdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJXaGlsZVN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAid2hpbGUiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgIigiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRUZXN0KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJvZHkoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJXaXRoU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ3aXRoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0T2JqZWN0KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJvZHkoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJZaWVsZEV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gInlpZWxkIjsKICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0RGVsZWdhdGUoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIgKiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGFyZ3VtZW50ID0gJG5vZGUtPmdldEFyZ3VtZW50KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkYXJndW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjb2RlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJlbmRlcnMgYSBub2RlIGFzIGEgYmxvY2sgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBTeW50YXhcTm9kZVxOb2RlfGFycmF5ICAgICRub2RlICAgICAgICAgICAgICAgTm9kZSBvciBhcnJheSBvZiAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMgdG8gcmVuZGVyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAkZm9yY2VCcmFja2V0cyAgICAgIE92ZXJyaWRlcyBicmFja2V0cwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRpbmcgcnVsZXMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRtYW5kYXRvcnlTZXBhcmF0b3IgVHJ1ZSBpZiBhIHN0YXJ0aW5nCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRvciBpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYW5kYXRvcnkKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRhZGRTZW1pY29sb25zICAgICAgU2VtaWNvbG9ucyBhcmUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0ZWQgYXV0b21hdGljYWxseQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0aGlzIHBhcmFtZXRlciBpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3QgZmFsc2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRpbmNJbmRlbnQgICAgICAgICAgSWYgZmFsc2UgaW5kZW50YXRpb24KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwgd29uJ3QgYmUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jcmVtZW50ZWQKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbmRlclN0YXRlbWVudEJsb2NrKAogICAgICAgICRub2RlLCAkZm9yY2VCcmFja2V0cyA9IG51bGwsICRtYW5kYXRvcnlTZXBhcmF0b3IgPSBmYWxzZSwKICAgICAgICAkYWRkU2VtaWNvbG9ucyA9IHRydWUsICRpbmNJbmRlbnQgPSB0cnVlCiAgICApIHsKICAgICAgICAkY29kZSA9ICIiOwogICAgICAgIAogICAgICAgIC8vU3BlY2lhbCBoYW5kbGluZyBvZiBCbG9ja1N0YXRlbWVudCBhbmQgQ2xhc3NCb2R5IG5vZGVzIGJ5IHJlbmRlcmluZwogICAgICAgIC8vdGhlaXIgY2hpbGQgbm9kZXMKICAgICAgICBpZiAoIWlzX2FycmF5KCRub2RlKSAmJgogICAgICAgICAgICBpbl9hcnJheSgkbm9kZS0+Z2V0VHlwZSgpLCBhcnJheSgiQmxvY2tTdGF0ZW1lbnQiLCAiQ2xhc3NCb2R5IikpKSB7CiAgICAgICAgICAgICRub2RlID0gJG5vZGUtPmdldEJvZHkoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JZiAkZm9yY2VCcmFja2V0cyBpcyBub3QgbnVsbCB1c2UgaXRzIHZhbHVlIHRvIG92ZXJyaWRlIGN1cmx5IGJyYWNrZXRzCiAgICAgICAgLy9pbnNlcnRpb24gcnVsZXMKICAgICAgICBpZiAoJGZvcmNlQnJhY2tldHMgIT09IG51bGwpIHsKICAgICAgICAgICAgJGhhc0JyYWNrZXRzID0gJGZvcmNlQnJhY2tldHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9JbnNlcnQgY3VybHkgYnJhY2tldHMgaWYgcmVxdWlyZWQgYnkgdGhlIGZvcm1hdHRlciBvciBpZiB0aGUKICAgICAgICAgICAgLy9udW1iZXIgb2Ygbm9kZXMgdG8gcmVuZGVyIGlzIGRpZmZlcmVudCBmcm9tIG9uZQogICAgICAgICAgICAkaGFzQnJhY2tldHMgPSAkdGhpcy0+cmVuZGVyT3B0cy0+YXdiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgIChpc19hcnJheSgkbm9kZSkgJiYgY291bnQoJG5vZGUpICE9PSAxKTsKICAgICAgICB9CiAgICAgICAgJGN1cnJlbnRJbmRlbnRhdGlvbiA9ICR0aGlzLT5nZXRJbmRlbnRhdGlvbigpOwogICAgICAgIAogICAgICAgIC8vSWYgJGZvcmNlQnJhY2tldHMgaXMgbm90IHNldCB0byBmYWxzZSB0aGVuIHRoZSBub2RlIGNhbiBiZSB3cmFwcGVkIGluCiAgICAgICAgLy9jdXJseSBicmFjZXMsIHNvIGEgc2VwYXJhdG9yIGRlZmluZWQgYnkgZm9ybWF0dGVyIG11c3QgYmUgaW5zZXJ0ZWQKICAgICAgICBpZiAoJGZvcmNlQnJhY2tldHMgIT09IGZhbHNlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+cmVuZGVyT3B0cy0+bmxiYykgewogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4gJGN1cnJlbnRJbmRlbnRhdGlvbjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JbnNlcnQgb3BlbiBjdXJseSBicmFja2V0IGlmIHJlcXVpcmVkCiAgICAgICAgaWYgKCRoYXNCcmFja2V0cykgewogICAgICAgICAgICAkY29kZSAuPSAieyIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+bmw7CiAgICAgICAgfSBlbHNlaWYgKCRtYW5kYXRvcnlTZXBhcmF0b3IpIHsKICAgICAgICAgICAgLy9JZiBicmFja2V0IGlzIG5vdCBpbnNlcnRlZCBidXQgYSBzZXBhcmF0b3IgaXMgc3RpbGwgcmVxdWlyZWQKICAgICAgICAgICAgLy9hIHNwYWNlIGlzIGFkZGVkCiAgICAgICAgICAgICRjb2RlIC49ICIgIjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JbmNyZWFzZSBpbmRlbnRhdGlvbiBsZXZlbAogICAgICAgIGlmICgkaW5jSW5kZW50KSB7CiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbCsrOwogICAgICAgIH0KICAgICAgICAkc3ViSW5kZW50YXRpb24gPSAkdGhpcy0+Z2V0SW5kZW50YXRpb24oKTsKICAgICAgICAKICAgICAgICAvL1JlbmRlciB0aGUgbm9kZSBvciB0aGUgYXJyYXkgb2Ygbm9kZXMKICAgICAgICAkZW1wdHlCb2R5ID0gaXNfYXJyYXkoJG5vZGUpICYmICFjb3VudCgkbm9kZSk7CiAgICAgICAgaWYgKGlzX2FycmF5KCRub2RlKSkgewogICAgICAgICAgICBpZiAoISRlbXB0eUJvZHkpIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICRzdWJJbmRlbnRhdGlvbiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+bmwgLiAkc3ViSW5kZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYWRkU2VtaWNvbG9ucwogICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb2RlIC49ICRzdWJJbmRlbnRhdGlvbiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlKTsKICAgICAgICAgICAgaWYgKCRhZGRTZW1pY29sb25zICYmICR0aGlzLT5yZXF1aXJlc1NlbWljb2xvbigkbm9kZSkpIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1Jlc2V0IHRoZSBpbmRlbnRhdGlvbiBsZXZlbAogICAgICAgIGlmICgkaW5jSW5kZW50KSB7CiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbC0tOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0luc2VydCBjbG9zaW5nIGN1cmx5IGJyYWNrZXQgaWYgcmVxdWlyZWQKICAgICAgICBpZiAoJGhhc0JyYWNrZXRzKSB7CiAgICAgICAgICAgIC8vQWRkIGEgbmV3IGxpbmUgaWYgc29tZXRoaW5nIHdhcyByZW5kZXJlZAogICAgICAgICAgICBpZiAoISRlbXB0eUJvZHkpIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5ubDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY29kZSAuPSAkY3VycmVudEluZGVudGF0aW9uIC4gIn0iOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJGNvZGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSm9pbnMgYW4gYXJyYXkgb2Ygbm9kZXMgd2l0aCB0aGUgZ2l2ZW4gc2VwYXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJG5vZGVzICAgICAgICAgIE5vZGVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICRzZXBhcmF0b3IgICAgICBTZXBhcmF0b3IKICAgICAqIEBwYXJhbSBib29sICAgICAgJGFkZFNlbWljb2xvbnMgIFRydWUgdG8gYWRkIHNlbWljb2xvbnMgYWZ0ZXIgZWFjaCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBqb2luTm9kZXMoJG5vZGVzLCAkc2VwYXJhdG9yLCAkYWRkU2VtaWNvbG9ucz1mYWxzZSkKICAgIHsKICAgICAgICAkcGFydHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRub2RlcyBhcyAkbm9kZSkgewogICAgICAgICAgICBpZiAoISRub2RlKSB7CiAgICAgICAgICAgICAgICAkY29kZSA9ICIiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvZGUgPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICBpZiAoJGFkZFNlbWljb2xvbnMgJiYgJHRoaXMtPnJlcXVpcmVzU2VtaWNvbG9uKCRub2RlKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFydHNbXSA9ICRjb2RlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wbG9kZSgkc2VwYXJhdG9yLCAkcGFydHMpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBjb25zZXF1ZW50IGFuZCBhbHRlcm5hdGUgbm9kZXMgb2YgYW4gSWZTdGF0ZW1lbnQgcmVxdWlyZSB0aGUKICAgICAqIG1hbmRhdG9yeSBpbnNlcnRpb24gb2YgYnJhY2tldHMgYXJvdW5kIHRoZW0gdG8gYXZvaWQgdGhlIHBhdHRlcm4gd2hlcmUKICAgICAqIHRoZSAiZWxzZSIgY29kZSBpcyByZW5kZXJlZCBhcyBwYXJ0IG9mIGFuIGlubmVyIElmU3RhdGVtZW50LgogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBOb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gbnVsbHxib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0lmUGFydHNCcmFja2V0c1JlcXVpcmVtZW50KCRub2RlKQogICAgewogICAgICAgIGlmICgkbm9kZS0+Z2V0VHlwZSgpID09PSAiQmxvY2tTdGF0ZW1lbnQiICYmIGNvdW50KCRub2RlLT5nZXRCb2R5KCkpID4gMSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJGZvcmNlQnJhY2tldHMgPSBudWxsOwogICAgICAgICRvcHRCcmFja2V0Tm9kZXMgPSBhcnJheSgKICAgICAgICAgICAgIkRvV2hpbGVTdGF0ZW1lbnQiLCAiRm9ySW5TdGF0ZW1lbnQiLCAiRm9yT2ZTdGF0ZW1lbnQiLAogICAgICAgICAgICAiRm9yU3RhdGVtZW50IiwgIldoaWxlU3RhdGVtZW50IiwgIldpdGhTdGF0ZW1lbnQiCiAgICAgICAgKTsKICAgICAgICAkY2hlY2tGbiA9IGZ1bmN0aW9uICgkbikgdXNlICgkb3B0QnJhY2tldE5vZGVzLCAmJGZvcmNlQnJhY2tldHMpIHsKICAgICAgICAgICAgJHR5cGUgPSAkbi0+Z2V0VHlwZSgpOwogICAgICAgICAgICBpZiAoJHR5cGUgPT09ICJJZlN0YXRlbWVudCIpIHsKICAgICAgICAgICAgICAgIGlmICghJG4tPmdldEFsdGVybmF0ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGZvcmNlQnJhY2tldHMgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIFRyYXZlcnNlcjo6RE9OVF9UUkFWRVJTRV9DSElMRF9OT0RFUzsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09PSAiQmxvY2tTdGF0ZW1lbnQiKSB7CiAgICAgICAgICAgICAgICBpZiAoY291bnQoJG4tPmdldEJvZHkoKSkgIT09IDEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHJhdmVyc2VyOjpET05UX1RSQVZFUlNFX0NISUxEX05PREVTOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPT09ICJMYWJlbGVkU3RhdGVtZW50IikgewogICAgICAgICAgICAgICAgaWYgKCRuLT5nZXRCb2R5KCktPmdldFR5cGUoKSA9PT0gIkJsb2NrU3RhdGVtZW50IikgewogICAgICAgICAgICAgICAgICAgICRmb3JjZUJyYWNrZXRzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBUcmF2ZXJzZXI6OkRPTlRfVFJBVkVSU0VfQ0hJTERfTk9ERVM7CiAgICAgICAgICAgIH0gZWxzZWlmICghaW5fYXJyYXkoJHR5cGUsICRvcHRCcmFja2V0Tm9kZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVHJhdmVyc2VyOjpET05UX1RSQVZFUlNFX0NISUxEX05PREVTOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICAkbm9kZS0+dHJhdmVyc2UoJGNoZWNrRm4pOwogICAgICAgIHJldHVybiAkZm9yY2VCcmFja2V0czsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gbm9kZSByZXF1aXJlcyBzZW1pY29sb25zIGluc2VydGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBOb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcmVxdWlyZXNTZW1pY29sb24oJG5vZGUpCiAgICB7CiAgICAgICAgcmV0dXJuICFpbl9hcnJheSgkbm9kZS0+Z2V0VHlwZSgpLCAkdGhpcy0+bm9TZW1pY29sb24pOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgaW5kZW50YXRpb24gc3RyaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRJbmRlbnRhdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIHN0cl9yZXBlYXQoCiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmQsCiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbAogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0OwoKLyoqCiAqIE1haW4gY2xhc3Mgb2YgUGVhc3QgbGlicmFyeS4KICogRXZlcnkgZnVuY3Rpb24gb2YgdGhpcyBjbGFzcyB0YWtlcyB0d28gYXJndW1lbnRzOgogKiAtIFRoZSBzb3VyY2UgY29kZSB0byBwYXJzZQogKiAtIFRoZSBvcHRpb25zIGFycmF5IHRoYXQgaXMgYW4gYXNzb2NpYXRpdmUgYXJyYXkgb2YgcGFyc2VyIHNldHRpbmdzLgogKiAgIEF2YWlsYWJsZSBvcHRpb25zIGFyZToKICogICAgICAtICJzb3VyY2VUeXBlIjogb25lIG9mIHRoZSBzb3VyY2UgdHlwZSBjb25zdGFudHMgZGVjbGFyZWQgaW4gdGhpcyBjbGFzcy4KICogICAgICAgIFRoaXMgb3B0aW9uIHRlbGxzIHRoZSBwYXJzZXIgdG8gcGFyc2UgdGhlIHNvdXJjZSBpbiBzY3JpcHQgb3IgbW9kdWxlCiAqICAgICAgICBtb2RlLiBJZiB0aGlzIG9wdGlvbiBpcyBub3QgcHJvdmlkZWQgdGhlIHBhcnNlciB3aWxsIHdvcmsgaW4gc2NyaXB0CiAqICAgICAgICBtb2RlLgogKiAgICAgIC0gInNvdXJjZUVuY29kaW5nIjogdGhlIGVuY29kaW5nIG9mIHRoZSBzb3VyY2UuIElmIG5vdCBzcGVjaWZpZWQgdGhlCiAqICAgICAgICBwYXJzZXIgd2lsbCBhc3N1bWUgVVRGLTguCiAqICAgICAgLSAic3RyaWN0RW5jb2RpbmciOiBpZiBmYWxzZSB0aGUgcGFyc2VyIHdpbGwgaGFuZGxlIGludmFsaWQgVVRGOAogKiAgICAgICAgY2hhcmFjdGVycyBpbiB0aGUgc291cmNlIGNvZGUgYnkgcmVwbGFjaW5nIHRoZW0gd2l0aCB0aGUgY2hhcmFjdGVyCiAqICAgICAgICBkZWZpbmVkIGluIHRoZSAibWJzdHJpbmcuc3Vic3RpdHV0ZV9jaGFyYWN0ZXIiIGluaSBzZXR0aW5nLCBvdGhlcndpc2UKICogICAgICAgIGl0IHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uLgogKiAgICAgIC0gImNvbW1lbnRzIjogaWYgdHJ1ZSBpdCBlbmFibGVzIGNvbW1lbnRzIHBhcnNpbmcuCiAqICAgICAgLSAianN4IjogaWYgdHJ1ZSBpdCBlbmFibGVzIHBhcnNpbmcgb2YgSlNYIHN5bnRheC4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDE1KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTUgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgdGhlIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVM2KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTUgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzIwMTYoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAxNiBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTNyhzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDE2IGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDE3KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTcgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzgoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAxNyBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMjAxOChzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDE4IGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVM5KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTggZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzIwMTkoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAxOSBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMTAoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAxOSBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDIwKHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMjAgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKgogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMTEoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAyMCBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDIxKHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMjEgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKgogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMTIoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAyMSBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDIyKHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMjIgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKgogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMTMoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAyMiBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgbGF0ZXN0KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgdGhlIGxhdGVzdCBwYXJzZXIgdmVyc2lvbiBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlCiAqIFBlYXN0IGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFBlYXN0CnsKICAgIC8vU291cmNlIHR5cGUgY29uc3RhbnRzCiAgICAvKioKICAgICAqIFRoaXMgc291cmNlIHR5cGUgaW5kaWNhdGVzIHRoYXQgdGhlIHNvdXJjZSBpcyBhIHNjcmlwdCBhbmQgaW1wb3J0CiAgICAgKiBhbmQgZXhwb3J0IGtleXdvcmRzIGFyZSBub3QgcGFyc2VkLgogICAgICovCiAgICBjb25zdCBTT1VSQ0VfVFlQRV9TQ1JJUFQgPSAic2NyaXB0IjsKICAgIAogICAgLyoqCiAgICAgKiBUaGlzIHNvdXJjZSB0eXBlIGluZGljYXRlcyB0aGF0IHRoZSBzb3VyY2UgaXMgYSBtb2R1bGUsIHRoaXMgZW5hYmxlcwogICAgICogdGhlIHBhcnNpbmcgb2YgaW1wb3J0IGFuZCBleHBvcnQga2V5d29yZHMuCiAgICAgKi8KICAgIGNvbnN0IFNPVVJDRV9UWVBFX01PRFVMRSA9ICJtb2R1bGUiOwogICAgCiAgICAvKioKICAgICAqIFZhbGlkIHZlcnNpb25zIGFuZCBhbGlhc2VzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgc3RhdGljIHByb3RlY3RlZCAkdmVyc2lvbnMgPSBhcnJheSgKICAgICAgICAiRVM2IiA9PiAiRVMyMDE1IiwKICAgICAgICAiRVM3IiA9PiAiRVMyMDE2IiwKICAgICAgICAiRVM4IiA9PiAiRVMyMDE3IiwKICAgICAgICAiRVM5IiA9PiAiRVMyMDE4IiwKICAgICAgICAiRVMxMCIgPT4gIkVTMjAxOSIsCiAgICAgICAgIkVTMTEiID0+ICJFUzIwMjAiLAogICAgICAgICJFUzEyIiA9PiAiRVMyMDIxIiwKICAgICAgICAiRVMxMyIgPT4gIkVTMjAyMiIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTWFnaWMgbWV0aG9kIHRoYXQgZXhwb3NlcyBhbGwgdGhlIGZ1bmN0aW9ucyB0byBhY2Nlc3MgcGFyc2VyIHdpdGgKICAgICAqIHNwZWNpZmljIGZlYXR1cmVzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJHZlcnNpb24gICBQYXJzZXIgdmVyc2lvbgogICAgICogQHBhcmFtIGFycmF5ICAgICAkYXJncyAgICAgIFBhcnNlciBhcmd1bWVudHMKICAgICAqIAogICAgICogQHJldHVybiBTeW50YXhcUGFyc2VyCiAgICAgKiAKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIF9fY2FsbFN0YXRpYygkdmVyc2lvbiwgJGFyZ3MpCiAgICB7CiAgICAgICAgJHNvdXJjZSA9ICRhcmdzWzBdOwogICAgICAgICRvcHRpb25zID0gaXNzZXQoJGFyZ3NbMV0pID8gJGFyZ3NbMV0gOiBhcnJheSgpOwogICAgICAgIAogICAgICAgIGlmICghaW5fYXJyYXkoJHZlcnNpb24sIHNlbGY6OiR2ZXJzaW9ucykpIHsKICAgICAgICAgICAgaWYgKCR2ZXJzaW9uID09PSAibGF0ZXN0IikgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSBlbmQoc2VsZjo6JHZlcnNpb25zKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KHNlbGY6OiR2ZXJzaW9uc1skdmVyc2lvbl0pKSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9IHNlbGY6OiR2ZXJzaW9uc1skdmVyc2lvbl07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCB2ZXJzaW9uICR2ZXJzaW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJGZlYXR1cmVzQ2xhc3MgPSAiXFxQZWFzdFxcU3ludGF4XFwkdmVyc2lvblxcRmVhdHVyZXMiOwogICAgICAgIHJldHVybiBuZXcgU3ludGF4XFBhcnNlcigKICAgICAgICAgICAgJHNvdXJjZSwgbmV3ICRmZWF0dXJlc0NsYXNzLCAkb3B0aW9ucwogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0OwoKLyoqCiAqIE5vZGVzIHF1ZXJ5IGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFF1ZXJ5IGltcGxlbWVudHMgXEl0ZXJhdG9yQWdncmVnYXRlLCBcQ291bnRhYmxlCnsKICAgIC8qKgogICAgICogQ3VycmVudCBtYXRjaGVzCiAgICAgKgogICAgICogQHZhciBTZWxlY3RvclxNYXRjaGVzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbWF0Y2hlczsKCiAgICAvKioKICAgICAqIE9wdGlvbnMgYXJyYXkKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3B0aW9uczsKCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yLiBBdmFpbGFibGUgb3B0aW9ucyBhcmU6CiAgICAgKiAtIGVuY29kaW5nOiBzZWxlY3RvcnMgZW5jb2RpbmcuIElmIG5vdCBzcGVjaWZpZWQgdGhlCiAgICAgKiAgIHBhcnNlciB3aWxsIGFzc3VtZSBVVEYtOC4KICAgICAqCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcUHJvZ3JhbSAkcm9vdCAgICAgUm9vdCBub2RlCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICAgICAkb3B0aW9ucyAgT3B0aW9ucyBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoU3ludGF4XE5vZGVcUHJvZ3JhbSAkcm9vdCwgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5tYXRjaGVzID0gbmV3IFNlbGVjdG9yXE1hdGNoZXMoKTsKICAgICAgICAkdGhpcy0+bWF0Y2hlcy0+YWRkTWF0Y2goJHJvb3QpOwogICAgICAgICR0aGlzLT5vcHRpb25zID0gJG9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kcyBub2RlcyBtYXRjaGluZyB0aGUgZ2l2ZW4gc2VsZWN0b3Igc3RhcnRpbmcgZnJvbSB0aGUKICAgICAqIGN1cnJlbnQgbWF0Y2hlZCBub2RlcywgaWYgYW55LCBvciBmcm9tIHRoZSByb290CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc2VsZWN0b3IgU2VsZWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBTZWxlY3RvclxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmQoJHNlbGVjdG9yKQogICAgewogICAgICAgICRwYXJzZXIgPSBuZXcgU2VsZWN0b3JcUGFyc2VyKCRzZWxlY3RvciwgJHRoaXMtPm9wdGlvbnMpOwogICAgICAgICRzZWxlY3RvciA9ICRwYXJzZXItPnBhcnNlKCk7CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSAkc2VsZWN0b3ItPmV4ZWMoJHRoaXMtPm1hdGNoZXMpOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHRoZSBnaXZlbiBzZWxlY3RvciBvbiB0aGUgY3VycmVudCBub2RlcyBhbmQgZmlsdGVycwogICAgICogb3V0IHRoZSBub2RlcyB3aGljaCBkb24ndCBtYXRjaAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNlbGVjdG9yIFNlbGVjdG9yCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgU2VsZWN0b3JcRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoJHNlbGVjdG9yKQogICAgewogICAgICAgICRwYXJzZXIgPSBuZXcgU2VsZWN0b3JcUGFyc2VyKCRzZWxlY3RvciwgJHRoaXMtPm9wdGlvbnMpOwogICAgICAgICRzZWxlY3RvciA9ICRwYXJzZXItPnBhcnNlKHRydWUpOwogICAgICAgICR0aGlzLT5tYXRjaGVzLT5maWx0ZXIoZnVuY3Rpb24gKCRub2RlLCAkcGFyZW50KSB1c2UgKCRzZWxlY3RvcikgewogICAgICAgICAgICAkbmV3TWF0Y2ggPSBuZXcgU2VsZWN0b3JcTWF0Y2hlcygpOwogICAgICAgICAgICAkbmV3TWF0Y2gtPmFkZE1hdGNoKCRub2RlLCAkcGFyZW50KTsKICAgICAgICAgICAgcmV0dXJuICRzZWxlY3Rvci0+ZXhlYygkbmV3TWF0Y2gpLT5nZXRNYXRjaGVzKCk7CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIG1hdGNoZWQgbm9kZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaGVzLT5jb3VudCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXgKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRpbmRleCBJbmRleAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkaW5kZXgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaGVzLT5nZXQoJGluZGV4KVswXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5vZGVzIGl0ZXJhdG9yCiAgICAgKgogICAgICogQHJldHVybiBcQXJyYXlJdGVyYXRvcgogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJdGVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBcQXJyYXlJdGVyYXRvcigkdGhpcy0+bWF0Y2hlcy0+Z2V0Tm9kZXMoKSk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwoKLyoqCiAqIFNlbGVjdG9yIHBhcnQgYmFzZSBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgUGFydAp7CiAgICAvKioKICAgICAqIFByaW9yaXR5CiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmlvcml0eSA9IDU7CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFByaW9yaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByaW9yaXR5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZWxlY3RvciBwYXJ0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUsCiAgICAgKiBmYWxzZSBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcGFyYW0gTm9kZSAkbm9kZSAgICBOb2RlCiAgICAgKiBAcGFyYW0gTm9kZSAkcGFyZW50ICBQYXJlbnQgbm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBhYnN0cmFjdAogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gY2hlY2soTm9kZSAkbm9kZSwgTm9kZSAkcGFyZW50ID0gbnVsbCk7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwp1c2UgUGVhc3RcU3ludGF4XFV0aWxzOwoKLyoqCiAqIFNlbGVjdG9yIHBhcnQgaW5kZXggcHNldWRvIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFBzZXVkb0luZGV4IGV4dGVuZHMgUHNldWRvCnsKICAgIC8qKgogICAgICogUHJpb3JpdHkKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByaW9yaXR5ID0gMjsKCiAgICAvKioKICAgICAqIFN0ZXAKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0ZXAgPSAwOwoKICAgIC8qKgogICAgICogT2Zmc2V0CiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRvZmZzZXQgPSAwOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgc3RlcAogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJHN0ZXAgU3RlcAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0ZXAoJHN0ZXApCiAgICB7CiAgICAgICAgJHRoaXMtPnN0ZXAgPSAkc3RlcDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBvZmZzZXQKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRvZmZzZXQgT2Zmc2V0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T2Zmc2V0KCRvZmZzZXQpCiAgICB7CiAgICAgICAgJHRoaXMtPm9mZnNldCA9ICRvZmZzZXQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZWxlY3RvciBwYXJ0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUsCiAgICAgKiBmYWxzZSBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcGFyYW0gTm9kZSAkbm9kZSAgICBOb2RlCiAgICAgKiBAcGFyYW0gTm9kZSAkcGFyZW50ICBQYXJlbnQgbm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soTm9kZSAkbm9kZSwgTm9kZSAkcGFyZW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkcHJvcHMgPSBVdGlsczo6Z2V0RXhwYW5kZWROb2RlUHJvcGVydGllcygkcGFyZW50KTsKICAgICAgICAkY291bnQgPSBjb3VudCgkcHJvcHMpOwogICAgICAgICRyZXZlcnNlID0gJHRoaXMtPm5hbWUgPT09ICJudGgtbGFzdC1jaGlsZCI7CiAgICAgICAgaWYgKCRyZXZlcnNlKSB7CiAgICAgICAgICAgICRzdGFydCA9ICRjb3VudCAtIDEgLSAoJHRoaXMtPm9mZnNldCAtIDEpOwogICAgICAgICAgICAkc3RlcCA9ICR0aGlzLT5zdGVwICogLTE7CiAgICAgICAgICAgIGlmICgkc3RlcCA+IDApIHsKICAgICAgICAgICAgICAgICRyZXZlcnNlID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkc3RhcnQgPSAkdGhpcy0+b2Zmc2V0IC0gMTsKICAgICAgICAgICAgJHN0ZXAgPSAkdGhpcy0+c3RlcDsKICAgICAgICAgICAgaWYgKCRzdGVwIDwgMCkgewogICAgICAgICAgICAgICAgJHJldmVyc2UgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vU3RlcCAwIHdpbGwgY2F1c2UgYW4gaW5maW5pdGUgbG9vcCwgc28gaXQgbXVzdCBiZSBzZXQgdG8gdGhlCiAgICAgICAgLy9udW1iZXIgb2YgcHJvcHMgc28gdGhhdCBpdCB3aWxsIGV4ZWN1dGUgb25seSBvbmUgaXRlcmF0aW9uCiAgICAgICAgaWYgKCEkc3RlcCkgewogICAgICAgICAgICAkc3RlcCA9ICRyZXZlcnNlID8gLSRjb3VudCA6ICRjb3VudDsKICAgICAgICB9CiAgICAgICAgZm9yICgkaSA9ICRzdGFydDsgKCRyZXZlcnNlICYmICRpID49IDApICB8fCAoISRyZXZlcnNlICYmICRpIDwgJGNvdW50KTsgJGkgKz0gJHN0ZXApIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRwcm9wc1skaV0pICYmICRwcm9wc1skaV0gPT09ICRub2RlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwp1c2UgUGVhc3RcU3ludGF4XE5vZGVcUGF0dGVybjsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXFN0YXRlbWVudDsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb247CnVzZSBQZWFzdFxTeW50YXhcTm9kZVxEZWNsYXJhdGlvbjsKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBTZWxlY3RvciBwYXJ0IHNpbXBsZSBwc2V1ZG8gY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUHNldWRvU2ltcGxlIGV4dGVuZHMgUHNldWRvCnsKICAgIC8qKgogICAgICogUHJpb3JpdHkKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByaW9yaXR5ID0gMzsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VsZWN0b3IgcGFydCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlLAogICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHBhcmFtIE5vZGUgJG5vZGUgICAgTm9kZQogICAgICogQHBhcmFtIE5vZGUgJHBhcmVudCAgUGFyZW50IG5vZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKE5vZGUgJG5vZGUsIE5vZGUgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+bmFtZSkgewogICAgICAgICAgICBjYXNlICJwYXR0ZXJuIjoKICAgICAgICAgICAgICAgIHJldHVybiAkbm9kZSBpbnN0YW5jZW9mIFBhdHRlcm47CiAgICAgICAgICAgIGNhc2UgInN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGUgaW5zdGFuY2VvZiBTdGF0ZW1lbnQ7CiAgICAgICAgICAgIGNhc2UgImV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgcmV0dXJuICRub2RlIGluc3RhbmNlb2YgRXhwcmVzc2lvbjsKICAgICAgICAgICAgY2FzZSAiZGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgcmV0dXJuICRub2RlIGluc3RhbmNlb2YgRGVjbGFyYXRpb247CiAgICAgICAgICAgIGNhc2UgImxhc3QtY2hpbGQiOgogICAgICAgICAgICBjYXNlICJmaXJzdC1jaGlsZCI6CiAgICAgICAgICAgICAgICAkZmlyc3QgPSAkdGhpcy0+bmFtZSA9PT0gImZpcnN0LWNoaWxkIjsKICAgICAgICAgICAgICAgICRwcm9wcyA9IFV0aWxzOjpnZXRFeHBhbmRlZE5vZGVQcm9wZXJ0aWVzKCRwYXJlbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuIGNvdW50KCRwcm9wcykgPiAwICYmICgKICAgICAgICAgICAgICAgICAgICAkZmlyc3QgPyAkcHJvcHNbMF0gPT09ICRub2RlIDogYXJyYXlfcG9wKCRwcm9wcykgPT09ICRub2RlCiAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3JcTm9kZVxQYXJ0OwoKdXNlIFBlYXN0XFNlbGVjdG9yXE1hdGNoZXM7CnVzZSBQZWFzdFxTZWxlY3RvclxOb2RlXFNlbGVjdG9yOwp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBTZWxlY3RvciBwYXJ0IHNlbGVjdG9yIHBzZXVkbyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBQc2V1ZG9TZWxlY3RvciBleHRlbmRzIFBzZXVkbwp7CiAgICAvKioKICAgICAqIFByaW9yaXR5CiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmlvcml0eSA9IDE7CgogICAgLyoqCiAgICAgKiBTZWxlY3RvcgogICAgICoKICAgICAqIEB2YXIgU2VsZWN0b3IKICAgICAqLwogICAgcHJvdGVjdGVkICRzZWxlY3RvcjsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHNlbGVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIFNlbGVjdG9yICRzZWxlY3RvciBTZWxlY3RvcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNlbGVjdG9yKFNlbGVjdG9yICRzZWxlY3RvcikKICAgIHsKICAgICAgICAkdGhpcy0+c2VsZWN0b3IgPSAkc2VsZWN0b3I7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZWxlY3RvciBwYXJ0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUsCiAgICAgKiBmYWxzZSBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcGFyYW0gTm9kZSAkbm9kZSAgICBOb2RlCiAgICAgKiBAcGFyYW0gTm9kZSAkcGFyZW50ICBQYXJlbnQgbm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soTm9kZSAkbm9kZSwgTm9kZSAkcGFyZW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkbWF0Y2ggPSBuZXcgTWF0Y2hlcygpOwogICAgICAgICRtYXRjaC0+YWRkTWF0Y2goJG5vZGUsICRwYXJlbnQpOwogICAgICAgICRyZXMgPSAkdGhpcy0+c2VsZWN0b3ItPmV4ZWMoJG1hdGNoKS0+Y291bnQoKTsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWUgPT09ICJub3QiID8gJHJlcyA9PT0gMCA6ICRyZXMgIT09IDA7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCi8qKgogKiBTZWxlY3RvciBwc2V1ZG8gcGFydCBiYXNlIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogQGFic3RyYWN0CiAqLwphYnN0cmFjdCBjbGFzcyBQc2V1ZG8gZXh0ZW5kcyBQYXJ0CnsKICAgIC8qKgogICAgICogU2VsZWN0b3IgbmFtZQogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbmFtZTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIG5hbWUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIE5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvclxOb2RlXFBhcnQ7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBTZWxlY3RvciBwYXJ0IGF0dHJpYnV0ZSBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBdHRyaWJ1dGUgZXh0ZW5kcyBQYXJ0CnsKICAgIC8qKgogICAgICogUHJpb3JpdHkKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByaW9yaXR5ID0gNDsKCiAgICAvKioKICAgICAqIEF0dHJpYnV0ZSBuYW1lcwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgbWF0Y2ggb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0b3IgPSBudWxsOwoKICAgIC8qKgogICAgICogQXR0cmlidXRlIHZhbHVlCiAgICAgKgogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlID0gbnVsbDsKCiAgICAvKioKICAgICAqIENhc2UgaW5zZW5zaXRpdmUgZmxhZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogUmVnZXggZmxhZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlZ2V4ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmFtZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgTmFtZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWVzW10gPSAkbmFtZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBvcGVyYXRvcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIE9wZXJhdG9yCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB2YWx1ZQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNhc2UgaW5zZW5zaXRpdmUgZmxhZwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjYXNlSW5zZW5zaXRpdmUgQ2FzZSBpbnNlbnNpdGl2ZSBmbGFnCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2FzZUluc2Vuc2l0aXZlKCRjYXNlSW5zZW5zaXRpdmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhc2VJbnNlbnNpdGl2ZSA9ICRjYXNlSW5zZW5zaXRpdmU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmVnZXggZmxhZwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRyZWdleCBSZWdleCBmbGFnCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVnZXgoJHJlZ2V4KQogICAgewogICAgICAgICR0aGlzLT5yZWdleCA9ICRyZWdleDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNlbGVjdG9yIHBhcnQgbWF0Y2hlcyB0aGUgZ2l2ZW4gbm9kZSwKICAgICAqIGZhbHNlIG90aGVyd2lzZQogICAgICoKICAgICAqIEBwYXJhbSBOb2RlICRub2RlICAgIE5vZGUKICAgICAqIEBwYXJhbSBOb2RlICRwYXJlbnQgIFBhcmVudCBub2RlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjayhOb2RlICRub2RlLCBOb2RlICRwYXJlbnQgPSBudWxsKQogICAgewogICAgICAgICRhdHRyID0gJG5vZGU7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm5hbWVzIGFzICRuYW1lKSB7CiAgICAgICAgICAgICRhdHRyRm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCRhdHRyIGluc3RhbmNlb2YgTm9kZSkgewogICAgICAgICAgICAgICAgJHByb3BzID0gVXRpbHM6OmdldE5vZGVQcm9wZXJ0aWVzKCRhdHRyKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwcm9wcyBhcyAkcHJvcCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkcHJvcFsibmFtZSJdID09PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYXR0ckZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGF0dHIgPSAkYXR0ci0+eyRwcm9wWyJnZXR0ZXIiXX0oKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGF0dHJGb3VuZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRib3RoU3RyaW5ncyA9IGlzX3N0cmluZygkYXR0cikgJiYgaXNfc3RyaW5nKCR0aGlzLT52YWx1ZSk7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+b3BlcmF0b3IpIHsKICAgICAgICAgICAgY2FzZSAiPSI6CiAgICAgICAgICAgICAgICBpZiAoJGJvdGhTdHJpbmdzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5yZWdleCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgkdGhpcy0+dmFsdWUsICRhdHRyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wYXJlU3RyKAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dmFsdWUsICRhdHRyLCAkdGhpcy0+Y2FzZUluc2Vuc2l0aXZlLCB0cnVlLCB0cnVlCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc19pbnQoJGF0dHIpICYmIGlzX2Zsb2F0KCR0aGlzLT52YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZsb2F0KSAkYXR0ciA9PT0gJHRoaXMtPnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRhdHRyID09PSAkdGhpcy0+dmFsdWU7CiAgICAgICAgICAgIGNhc2UgIjwiOgogICAgICAgICAgICAgICAgaWYgKGlzX2Zsb2F0KCR0aGlzLT52YWx1ZSkgJiYgIWlzX2Zsb2F0KCRhdHRyKSAmJiAhaXNfaW50KCRhdHRyKSAmJiAhaXNfc3RyaW5nKCRhdHRyKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAkYXR0ciA8ICR0aGlzLT52YWx1ZTsKICAgICAgICAgICAgY2FzZSAiPiI6CiAgICAgICAgICAgICAgICBpZiAoaXNfZmxvYXQoJHRoaXMtPnZhbHVlKSAmJiAhaXNfZmxvYXQoJGF0dHIpICYmICFpc19pbnQoJGF0dHIpICYmICFpc19zdHJpbmcoJGF0dHIpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRhdHRyID4gJHRoaXMtPnZhbHVlOwogICAgICAgICAgICBjYXNlICI8PSI6CiAgICAgICAgICAgICAgICBpZiAoaXNfZmxvYXQoJHRoaXMtPnZhbHVlKSAmJiAhaXNfZmxvYXQoJGF0dHIpICYmICFpc19pbnQoJGF0dHIpICYmICFpc19zdHJpbmcoJGF0dHIpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRhdHRyIDw9ICR0aGlzLT52YWx1ZTsKICAgICAgICAgICAgY2FzZSAiPj0iOgogICAgICAgICAgICAgICAgaWYgKGlzX2Zsb2F0KCR0aGlzLT52YWx1ZSkgJiYgIWlzX2Zsb2F0KCRhdHRyKSAmJiAhaXNfaW50KCRhdHRyKSAmJiAhaXNfc3RyaW5nKCRhdHRyKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAkYXR0ciA+PSAkdGhpcy0+dmFsdWU7CiAgICAgICAgICAgIGNhc2UgIl49IjoKICAgICAgICAgICAgY2FzZSAiJD0iOgogICAgICAgICAgICBjYXNlICIqPSI6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBhcmVTdHIoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZhbHVlLCAkYXR0ciwgJHRoaXMtPmNhc2VJbnNlbnNpdGl2ZSwKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPT09ICJePSIsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZXJhdG9yID09PSAiJD0iCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2MSAgICAgICAgICAgICAgICBTZWFyY2ggdmFsdWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHYyICAgICAgICAgICAgICAgIENvbXBhcmUgdmFsdWUKICAgICAqIEBwYXJhbSBib29sICAgJGNhc2VJbnNlbnNpdGl2ZSAgIFRydWUgaWYgdGhlIHNlYXJjaCBtdXN0IGJlIGNhc2UgaW5zZW5zaXRpdmUKICAgICAqIEBwYXJhbSBib29sICAgJG1hdGNoU3RhcnQgICAgICAgIFRydWUgaWYgdGhlIHNlYXJjaCBtdXN0IGJlIGV4ZWN1dGVkIGZyb20gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZwogICAgICogQHBhcmFtIGJvb2wgICAkbWF0Y2hFbmQgICAgICAgICAgVHJ1ZSBpZiB0aGUgc2VhcmNoIG11c3QgYmUgZXhlY3V0ZWQgZnJvbSB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCBvZiB0aGUgc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb21wYXJlU3RyKCR2MSwgJHYyLCAkY2FzZUluc2Vuc2l0aXZlLCAkbWF0Y2hTdGFydCwgJG1hdGNoRW5kKQogICAgewogICAgICAgICRyZWdleCA9ICIjIiAuCiAgICAgICAgICAgICAgICAgKCRtYXRjaFN0YXJ0ID8gIl4iIDogIiIpIC4KICAgICAgICAgICAgICAgICBwcmVnX3F1b3RlKCR2MSkgLgogICAgICAgICAgICAgICAgICgkbWF0Y2hFbmQgPyAiJCIgOiAiIikgLgogICAgICAgICAgICAgICAgICIjdSIgLgogICAgICAgICAgICAgICAgICgkY2FzZUluc2Vuc2l0aXZlID8gImkiIDogIiIpOwogICAgICAgIHJldHVybiAoYm9vbCkgcHJlZ19tYXRjaCgkcmVnZXgsICR2Mik7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwoKLyoqCiAqIFNlbGVjdG9yIHBhcnQgdHlwZSBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUeXBlIGV4dGVuZHMgUGFydAp7CiAgICAvKioKICAgICAqIFNlbGVjdG9yIHR5cGUKICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJHR5cGU7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzZWxlY3RvciB0eXBlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSBUeXBlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHlwZSgkdHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+dHlwZSA9ICR0eXBlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VsZWN0b3IgcGFydCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlLAogICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHBhcmFtIE5vZGUgJG5vZGUgICAgTm9kZQogICAgICogQHBhcmFtIE5vZGUgJHBhcmVudCAgUGFyZW50IG5vZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKE5vZGUgJG5vZGUsIE5vZGUgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICRub2RlLT5nZXRUeXBlKCkgPT09ICR0aGlzLT50eXBlOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvclxOb2RlOwoKdXNlIFBlYXN0XFNlbGVjdG9yXE1hdGNoZXM7CgovKioKICogU2VsZWN0b3IgZ3JvdXAgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgR3JvdXAKewogICAgLyoqCiAgICAgKiBTZWxlY3RvciBjb21iaW5hdG9ycwogICAgICoKICAgICAqIEB2YXIgQ29tYmluYXRvcltdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tYmluYXRvcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQWRkcyBhIGNvbWJpbmF0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gQ29tYmluYXRvciAkY29tYmluYXRvcnMgQ29tYmluYXRvcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENvbWJpbmF0b3IoQ29tYmluYXRvciAkY29tYmluYXRvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbWJpbmF0b3JzW10gPSAkY29tYmluYXRvcnM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGN1cnJlbnQgZ3JvdXAgb24gdGhlIGdpdmVuIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlcyAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjKE1hdGNoZXMgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbWJpbmF0b3JzIGFzICRjb21iaW5hdG9yKSB7CiAgICAgICAgICAgICRjb21iaW5hdG9yLT5leGVjKCRtYXRjaGVzKTsKICAgICAgICB9CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGU7Cgp1c2UgUGVhc3RcU2VsZWN0b3JcTWF0Y2hlczsKCi8qKgogKiBTZWxlY3RvciBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBTZWxlY3Rvcgp7CiAgICAvKioKICAgICAqIFNlbGVjdG9yIGdyb3VwcwogICAgICoKICAgICAqIEB2YXIgR3JvdXBbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGdyb3VwcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmV3IGdyb3VwCiAgICAgKgogICAgICogQHBhcmFtIEdyb3VwICRncm91cCBHcm91cAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEdyb3VwKEdyb3VwICRncm91cCkKICAgIHsKICAgICAgICAkdGhpcy0+Z3JvdXBzW10gPSAkZ3JvdXA7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGN1cnJlbnQgc2VsZWN0b3Igb24gdGhlIGdpdmVuIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlcyAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKgogICAgICogQHJldHVybiBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjKE1hdGNoZXMgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgJHJldE1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ncm91cHMgYXMgJGdyb3VwKSB7CiAgICAgICAgICAgICRjbG9uZWRNYXRjaGVzID0gJG1hdGNoZXMtPmNyZWF0ZUNsb25lKCk7CiAgICAgICAgICAgICRncm91cC0+ZXhlYygkY2xvbmVkTWF0Y2hlcyk7CiAgICAgICAgICAgICRyZXRNYXRjaGVzW10gPSAkY2xvbmVkTWF0Y2hlczsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50KCRyZXRNYXRjaGVzKSA+IDEpIHsKICAgICAgICAgICAgJHJldE1hdGNoZXNbMF0tPm1lcmdlKGFycmF5X3NsaWNlKCRyZXRNYXRjaGVzLCAxKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0TWF0Y2hlc1swXTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3JcTm9kZTsKCnVzZSBQZWFzdFxTZWxlY3RvclxNYXRjaGVzOwp1c2UgUGVhc3RcU3ludGF4XFV0aWxzOwp1c2UgUGVhc3RcVHJhdmVyc2VyOwoKLyoqCiAqIFNlbGVjdG9yIGNvbWJpbmF0b3IgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tYmluYXRvcgp7CiAgICAvKioKICAgICAqIE9wZXJhdG9yCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwoKICAgIC8qKgogICAgICogU2VsZWN0b3IgcGFydHMKICAgICAqCiAgICAgKiBAdmFyIFBhcnRcUGFydFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcGFydHMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3BlcmF0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvciBPcGVyYXRvcgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmV3IHNlbGVjdG9yIHBhcnQKICAgICAqCiAgICAgKiBAcGFyYW0gUGFydFxQYXJ0ICRwYXJ0IFBhcnQKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhcnQoUGFydFxQYXJ0ICRwYXJ0KQogICAgewogICAgICAgICR0aGlzLT5wYXJ0c1tdID0gJHBhcnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGN1cnJlbnQgZ3JvdXAgb24gdGhlIGdpdmVuIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlcyAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjKE1hdGNoZXMgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgJHBhcnRzID0gJHRoaXMtPnBhcnRzOwogICAgICAgIC8vU29ydCB0aGUgcGFydHMgYnkgcHJpb3JpdHkgdG8gZXhlY3V0ZSBmYXN0ZXIgY2hlY2tzIGZpcnN0CiAgICAgICAgdXNvcnQoJHBhcnRzLCBmdW5jdGlvbiAoJHAxLCAkcDIpIHsKICAgICAgICAgICAgJHByMSA9ICRwMS0+Z2V0UHJpb3JpdHkoKTsKICAgICAgICAgICAgJHByMiA9ICRwMi0+Z2V0UHJpb3JpdHkoKTsKICAgICAgICAgICAgaWYgKCRwcjEgPT09ICRwcjIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9IGVsc2VpZiAoJHByMSA8ICRwcjIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgJGZpbHRlciA9IGZ1bmN0aW9uICgkbm9kZSwgJHBhcmVudCkgdXNlICgkcGFydHMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhcnRzIGFzICRwYXJ0KSB7CiAgICAgICAgICAgICAgICBpZiAoISRwYXJ0LT5jaGVjaygkbm9kZSwgJHBhcmVudCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKICAgICAgICBzd2l0Y2ggKCR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBjYXNlICIgIjoKICAgICAgICAgICAgY2FzZSAiPiI6CiAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSAkdGhpcy0+b3BlcmF0b3IgPT09ICI+IjsKICAgICAgICAgICAgICAgICRtYXRjaGVzLT5tYXAoZnVuY3Rpb24gKCRjdXJOb2RlKSB1c2UgKCRmaWx0ZXIsICRjaGlsZHJlbikgewogICAgICAgICAgICAgICAgICAgICRyZXQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICRjdXJOb2RlLT50cmF2ZXJzZSgKICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCRub2RlLCAkcGFyZW50KSB1c2UgKCRmaWx0ZXIsICRjaGlsZHJlbiwgJiRyZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZmlsdGVyKCRub2RlLCAkcGFyZW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXRbXSA9IGFycmF5KCRub2RlLCAkcGFyZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHJhdmVyc2VyOjpET05UX1RSQVZFUlNFX0NISUxEX05PREVTOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJza2lwU3RhcnRpbmdOb2RlIiA9PiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhc3NQYXJlbnROb2RlIiA9PiB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcmV0OwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ+IjoKICAgICAgICAgICAgY2FzZSAiKyI6CiAgICAgICAgICAgICAgICAkYWRqYWNlbnQgPSAkdGhpcy0+b3BlcmF0b3IgPT09ICIrIjsKICAgICAgICAgICAgICAgICRtYXRjaGVzLT5tYXAoZnVuY3Rpb24gKCRub2RlLCAkcGFyZW50KSB1c2UgKCRmaWx0ZXIsICRhZGphY2VudCkgewogICAgICAgICAgICAgICAgICAgICRyZXQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICRldmFsdWF0ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICRwcm9wcyA9ICRwYXJlbnQgPyBVdGlsczo6Z2V0RXhwYW5kZWROb2RlUHJvcGVydGllcygkcGFyZW50KSA6IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHByb3BzIGFzICRwcm9wTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGV2YWx1YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHByb3BOb2RlICYmICRmaWx0ZXIoJHByb3BOb2RlLCAkcGFyZW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXRbXSA9IGFycmF5KCRwcm9wTm9kZSwgJHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGFkamFjZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcE5vZGUgPT09ICRub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXZhbHVhdGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcmV0OwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgJG1hdGNoZXMtPmZpbHRlcigkZmlsdGVyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvcjsKCi8qKgogKiBTZWxlY3RvciBwYXJzZXIgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUGFyc2VyCnsKICAgIC8qKgogICAgICogU2VsZWN0b3Igc3RyaW5nCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRzZWxlY3RvcjsKCiAgICAvKioKICAgICAqIEN1cnJlbnQgcGFyc2VyIGluZGV4CiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRpbmRleCA9IDA7CgogICAgLyoqCiAgICAgKiBTZWxlY3RvciBsZW5ndGgKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxlbmd0aDsKCiAgICAvKioKICAgICAqIFdoaXRlc3BhY2VzCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHdoaXRlc3BhY2VzID0gYXJyYXkoIiAiLCAiXHQiLCAiXG4iLCAiXHIiLCAiXGYiKTsKCiAgICAvKioKICAgICAqIENvbWJpbmF0b3JzCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbWJpbmF0b3JzID0gYXJyYXkoIj4iLCAiKyIsICJ+Iik7CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgc2VsZWN0b3Igb3BlcmF0b3IgY2hhcmFjdGVycwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRhdHRyT3BlcmF0b3JDaGFycyA9IGFycmF5KCI9IiwgIjwiLCAiPiIsICJeIiwgIiQiLCAiKiIpOwoKICAgIC8qKgogICAgICogQXR0cmlidXRlIHNlbGVjdG9yIG9wZXJhdG9ycwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRhdHRyT3BlcmF0b3JzID0gYXJyYXkoIj0iLCAiPCIsICI+IiwgIjw9IiwgIj49IiwgIl49IiwgIiQ9IiwgIio9Iik7CgogICAgLyoqCiAgICAgKiBWYWxpZCBwc2V1ZG8gc2VsZWN0b3JzLiBUaGUgdmFsdWUgaW5kaWNhdGVzIHRoZSBhcmd1bWVudCB0eXBlOgogICAgICogLSAwOiBubyBhcmd1bWVudHMKICAgICAqIC0gMTogaW5kZXggZm9ybXVsYSAoQW4rQiBzeW50YXgpCiAgICAgKiAtIDI6IHNlbGVjdG9yCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkdmFsaWRQc2V1ZG8gPSBhcnJheSgKICAgICAgICAicGF0dGVybiIgPT4gMCwgInN0YXRlbWVudCIgPT4gMCwgImV4cHJlc3Npb24iID0+IDAsICJkZWNsYXJhdGlvbiIgPT4gMCwKICAgICAgICAiZmlyc3QtY2hpbGQiID0+IDAsICJsYXN0LWNoaWxkIiA9PiAwLAogICAgICAgICJudGgtY2hpbGQiID0+IDEsICJudGgtbGFzdC1jaGlsZCIgPT4gMSwKICAgICAgICAiaGFzIiA9PiAyLCAiaXMiID0+IDIsICJub3QiID0+IDIKICAgICk7CgogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNlbGVjdG9yICBTZWxlY3RvciBzdHJpbmcKICAgICAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgICBPcHRpb25zIGFycmF5LiBTZWUgUXVlcnkgY2xhc3MKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudGF0aW9uIGZvciBhdmFpbGFibGUgb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNlbGVjdG9yLCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJGVuY29kaW5nID0gaXNzZXQoJG9wdGlvbnNbImVuY29kaW5nIl0pID8gJG9wdGlvbnNbImVuY29kaW5nIl0gOiBudWxsOwogICAgICAgIGlmICgkZW5jb2RpbmcgJiYgIXByZWdfbWF0Y2goIi9VVEYtPzgvaSIsICRlbmNvZGluZykpIHsKICAgICAgICAgICAgJHNlbGVjdG9yID0gbWJfY29udmVydF9lbmNvZGluZygkc2VsZWN0b3IsICJVVEYtOCIsICRlbmNvZGluZyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5zZWxlY3RvciA9ICRzZWxlY3RvcjsKICAgICAgICAkdGhpcy0+bGVuZ3RoID0gc3RybGVuKCRzZWxlY3Rvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdGFydHMgdGhlIHBhcnNpbmcgYW5kIHJldHVybnMgdGhlIHBhcnNlZCBzZWxlY3RvcgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRmaWx0ZXIgVHJ1ZSBpZiB0aGUgc2VsZWN0b3IgbXVzdCBiZSB1c2VkIGZvciBhIGZpbHRlcgogICAgICoKICAgICAqIEByZXR1cm4gTm9kZVxTZWxlY3RvcgogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZSgkZmlsdGVyID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHNlbGVjdG9yID0gJHRoaXMtPnBhcnNlU2VsZWN0b3IoJGZpbHRlcik7CiAgICAgICAgLy9UaHJvdyBhbiBleGNlcHRpb24gaWYgdGhlIGVuZCBoYXMgbm90IGJlZW4gcmVhY2hlZAogICAgICAgIGlmICgoJGNoYXIgPSAkdGhpcy0+Z2V0Q2hhcigpKSAhPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJJbnZhbGlkIHN5bnRheCAnJGNoYXInIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkc2VsZWN0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzZWxlY3RvcgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRmaWx0ZXIgVHJ1ZSBpZiB0aGUgc2VsZWN0b3IgbXVzdCBiZSB1c2VkIGZvciBhIGZpbHRlcgogICAgICoKICAgICAqIEByZXR1cm4gTm9kZVxTZWxlY3RvcgogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZVNlbGVjdG9yKCRmaWx0ZXIgPSBmYWxzZSkKICAgIHsKICAgICAgICAkc2VsZWN0b3IgPSBuZXcgTm9kZVxTZWxlY3RvcjsKICAgICAgICBkbyB7CiAgICAgICAgICAgICRmaXJzdCA9IHRydWU7CiAgICAgICAgICAgICRncm91cCA9IG5ldyBOb2RlXEdyb3VwOwogICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgJGNvbWJpbmF0b3IgPSAkdGhpcy0+Y29uc3VtZUNvbWJpbmF0b3IoKTsKICAgICAgICAgICAgICAgIGlmICghJGZpcnN0ICYmICEkY29tYmluYXRvcikgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhcnRzID0gJHRoaXMtPnBhcnNlU2VsZWN0b3JQYXJ0cygpOwogICAgICAgICAgICAgICAgaWYgKCFjb3VudCgkcGFydHMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiTWlzc2luZyBzZWxlY3RvciBhZnRlciBjb21iaW5hdG9yIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICRzZWxDb21iaW5hdG9yID0gbmV3IE5vZGVcQ29tYmluYXRvcjsKICAgICAgICAgICAgICAgICRzZWxDb21iaW5hdG9yLT5zZXRPcGVyYXRvcigKICAgICAgICAgICAgICAgICAgICAkY29tYmluYXRvciA/OiAoJGZpbHRlciA/IG51bGwgOiAiICIpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhcnRzIGFzICRwYXJ0KSB7CiAgICAgICAgICAgICAgICAgICAgJHNlbENvbWJpbmF0b3ItPmFkZFBhcnQoJHBhcnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGdyb3VwLT5hZGRDb21iaW5hdG9yKCRzZWxDb21iaW5hdG9yKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc2VsZWN0b3ItPmFkZEdyb3VwKCRncm91cCk7CiAgICAgICAgICAgICR0aGlzLT5jb25zdW1lV2hpdGVzcGFjZXMoKTsKICAgICAgICB9IHdoaWxlICgkdGhpcy0+Y29uc3VtZSgiLCIpKTsKICAgICAgICByZXR1cm4gJHNlbGVjdG9yOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgc2V0IG9mIHNlbGVjdG9yIHBhdHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU2VsZWN0b3JQYXJ0cygpCiAgICB7CiAgICAgICAgJHBhcnRzID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAoJHBhcnQgPSAkdGhpcy0+cGFyc2VTZWxlY3RvclBhcnRUeXBlKCkpIHx8CiAgICAgICAgICAgICAgICAoJHBhcnQgPSAkdGhpcy0+cGFyc2VTZWxlY3RvclBhcnRBdHRyaWJ1dGUoKSkgfHwKICAgICAgICAgICAgICAgICgkcGFydCA9ICR0aGlzLT5wYXJzZVNlbGVjdG9yUGFydFBzZXVkbygpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRwYXJ0c1tdID0gJHBhcnQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJHBhcnRzOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgdHlwZSBzZWxlY3RvciBwYXJ0CiAgICAgKgogICAgICogQHJldHVybiBOb2RlXFBhcnRcVHlwZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVNlbGVjdG9yUGFydFR5cGUoKQogICAgewogICAgICAgICR0eXBlID0gJHRoaXMtPmNvbnN1bWVXb3JkKCk7CiAgICAgICAgaWYgKCR0eXBlKSB7CiAgICAgICAgICAgICRwYXJ0ID0gbmV3IE5vZGVcUGFydFxUeXBlOwogICAgICAgICAgICAkcGFydC0+c2V0VHlwZSgkdHlwZSk7CiAgICAgICAgICAgIHJldHVybiAkcGFydDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXR0cmlidXRlIHNlbGVjdG9yIHBhcnQKICAgICAqCiAgICAgKiBAcmV0dXJuIE5vZGVcUGFydFxBdHRyaWJ1dGV8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVNlbGVjdG9yUGFydEF0dHJpYnV0ZSgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+Y29uc3VtZSgiWyIpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y29uc3VtZVdoaXRlc3BhY2VzKCk7CiAgICAgICAgJHBhcnQgPSBuZXcgTm9kZVxQYXJ0XEF0dHJpYnV0ZTsKICAgICAgICBpZiAoISgkbmFtZSA9ICR0aGlzLT5jb25zdW1lV29yZCgpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJNaXNzaW5nIGF0dHJpYnV0ZSBuYW1lIik7CiAgICAgICAgfQogICAgICAgICRwYXJ0LT5hZGROYW1lKCRuYW1lKTsKICAgICAgICB3aGlsZSAoJHRoaXMtPmNvbnN1bWUoIi4iKSkgewogICAgICAgICAgICBpZiAoISgkbmFtZSA9ICR0aGlzLT5jb25zdW1lV29yZCgpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiTWlzc2luZyBhdHRyaWJ1dGUgbmFtZSBhZnRlciBkb3QiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFydC0+YWRkTmFtZSgkbmFtZSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jb25zdW1lV2hpdGVzcGFjZXMoKTsKICAgICAgICAkb3BlcmF0b3IgPSAkdGhpcy0+Y29uc3VtZUFueSgkdGhpcy0+YXR0ck9wZXJhdG9yQ2hhcnMpOwogICAgICAgIGlmICgkb3BlcmF0b3IpIHsKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkb3BlcmF0b3IsICR0aGlzLT5hdHRyT3BlcmF0b3JzKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBhdHRyaWJ1dGUgb3BlcmF0b3IgJyRvcGVyYXRvciciKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFydC0+c2V0T3BlcmF0b3IoJG9wZXJhdG9yKTsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgICAgICBpZiAoISgkdmFsdWUgPSAkdGhpcy0+cGFyc2VMaXRlcmFsKCkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJNaXNzaW5nIGF0dHJpYnV0ZSB2YWx1ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYXJ0LT5zZXRWYWx1ZSgkdmFsdWVbMF0pOwogICAgICAgICAgICBpZiAoJHZhbHVlWzFdKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdG9yICE9ICI9IikgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJPbmx5ICc9JyBvcGVyYXRvciBpcyB2YWxpZCBmb3IgYXR0cmlidXRlIHJlZ2V4IG1hdGNoIgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcGFydC0+c2V0UmVnZXgodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgICAgICBpZiAoJHRoaXMtPmNvbnN1bWUoImkiKSkgewogICAgICAgICAgICAgICAgaWYgKCFpc19zdHJpbmcoJHZhbHVlWzBdKSB8fCAkdmFsdWVbMV0pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FzZSBpbnNlbnNpdGl2ZSBmbGFnIGNhbiBiZSB1c2VkIG9ubHkgZm9yIHN0cmluZyB2YWx1ZXMiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYXJ0LT5zZXRDYXNlSW5zZW5zaXRpdmUodHJ1ZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVdoaXRlc3BhY2VzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCEkdGhpcy0+Y29uc3VtZSgiXSIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlVudGVybWluYXRlZCBhdHRyaWJ1dGUgc2VsZWN0b3IiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRwYXJ0OwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgcHNldWRvIHNlbGVjdG9yIHBhcnQKICAgICAqCiAgICAgKiBAcmV0dXJuIE5vZGVcUGFydFxQc2V1ZG98bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVNlbGVjdG9yUGFydFBzZXVkbygpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+Y29uc3VtZSgiOiIpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkbmFtZSA9ICR0aGlzLT5jb25zdW1lV29yZCgiLSIpOwogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnZhbGlkUHNldWRvWyRuYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgcHNldWRvIHNlbGVjdG9yICckbmFtZSciKTsKICAgICAgICB9CiAgICAgICAgJGFyZ3NUeXBlID0gJHRoaXMtPnZhbGlkUHNldWRvWyRuYW1lXTsKICAgICAgICAkZXJyb3IgPSBmYWxzZTsKICAgICAgICBpZiAoJGFyZ3NUeXBlID09PSAxKSB7CiAgICAgICAgICAgICRwYXJ0ID0gbmV3IE5vZGVcUGFydFxQc2V1ZG9JbmRleDsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+Y29uc3VtZSgiKCIpKSB7CiAgICAgICAgICAgICAgICAkZXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGVycm9yKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVdoaXRlc3BhY2VzKCk7CiAgICAgICAgICAgICAgICBpZiAoJGluZGljZXMgPSAkdGhpcy0+Y29uc3VtZVJlZ2V4KCItP1xkKm4oPzpcK1xkKyk/fFxkKyIpKSB7CiAgICAgICAgICAgICAgICAgICAgJGluZGljZXMgPSBleHBsb2RlKCJuIiwgJGluZGljZXMpOwogICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCgkaW5kaWNlcykgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnQtPnNldE9mZnNldCgoaW50KSAkaW5kaWNlc1swXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkaW5kaWNlc1swXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiIjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFydC0+c2V0U3RlcCgxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiLSI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnQtPnNldFN0ZXAoLTEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0LT5zZXRTdGVwKChpbnQpICRpbmRpY2VzWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaW5kaWNlc1sxXSAhPT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0LT5zZXRPZmZzZXQoKGludCkgJGluZGljZXNbMV0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKAogICAgICAgICAgICAgICAgICAgICgkd29yZCA9ICR0aGlzLT5jb25zdW1lV29yZCgpKSAmJgogICAgICAgICAgICAgICAgICAgICgkd29yZCA9PT0gImV2ZW4iIHx8ICR3b3JkID09PSAib2RkIikKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICRwYXJ0LT5zZXRTdGVwKDIpOwogICAgICAgICAgICAgICAgICAgIGlmICgkd29yZCA9PT0gIm9kZCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnQtPnNldE9mZnNldCgxKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVdoaXRlc3BhY2VzKCk7CiAgICAgICAgICAgICAgICBpZiAoISRlcnJvciAmJiAhJHRoaXMtPmNvbnN1bWUoIikiKSkgewogICAgICAgICAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJGFyZ3NUeXBlID09PSAyKSB7CiAgICAgICAgICAgICRwYXJ0ID0gbmV3IE5vZGVcUGFydFxQc2V1ZG9TZWxlY3RvcjsKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCRzZWxlY3RvciA9ICR0aGlzLT5wYXJzZVNlbGVjdG9yKCRuYW1lICE9PSAiaGFzIikpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uc3VtZSgiKSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJHBhcnQtPnNldFNlbGVjdG9yKCRzZWxlY3Rvcik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhcnQgPSBuZXcgTm9kZVxQYXJ0XFBzZXVkb1NpbXBsZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRlcnJvcikgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgYXJndW1lbnQgZm9yIHBzZXVkbyBzZWxlY3RvciAnJG5hbWUnIgogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICAkcGFydC0+c2V0TmFtZSgkbmFtZSk7CiAgICAgICAgcmV0dXJuICRwYXJ0OwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgbGl0ZXJhbCB2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxpdGVyYWwoKQogICAgewogICAgICAgIGlmICgKICAgICAgICAgICAgKCRsaXRlcmFsID0gJHRoaXMtPnBhcnNlTGl0ZXJhbEJvb2xOdWxsKCkpICE9PSAwIHx8CiAgICAgICAgICAgICgkbGl0ZXJhbCA9ICR0aGlzLT5wYXJzZUxpdGVyYWxTdHJpbmcoKSkgIT09IG51bGwgfHwKICAgICAgICAgICAgKCRsaXRlcmFsID0gJHRoaXMtPnBhcnNlTGl0ZXJhbE51bWJlcigpKSAhPT0gbnVsbAogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJGxpdGVyYWwsIGZhbHNlKTsKICAgICAgICB9IGVsc2VpZiAoJGxpdGVyYWwgPSAkdGhpcy0+cGFyc2VMaXRlcmFsUmVnZXgoKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJGxpdGVyYWwsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxpdGVyYWwgYm9vbGVhbiBvciBudWxsIHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBpbnR8Ym9vbHxudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbEJvb2xOdWxsKCkKICAgIHsKICAgICAgICAkd29yZCA9ICR0aGlzLT5jb25zdW1lV29yZCgpOwogICAgICAgIGlmICghJHdvcmQpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlaWYgKCR3b3JkID09PSAidHJ1ZSIpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlaWYgKCR3b3JkID09PSAiZmFsc2UiKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2VpZiAoJHdvcmQgPT09ICJudWxsIikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBhdHRyaWJ1dGUgdmFsdWUgJyR3b3JkJyIpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgbGl0ZXJhbCBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbFN0cmluZygpCiAgICB7CiAgICAgICAgaWYgKCEoJHF1b3RlID0gJHRoaXMtPmNvbnN1bWVBbnkoYXJyYXkoIiciLCAnIicpLCB0cnVlKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIGlmICgoJHN0ciA9ICR0aGlzLT5jb25zdW1lVW50aWwoJHF1b3RlKSkgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIHN0cmluZyBpbiBhdHRyaWJ1dGUgdmFsdWUiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRzdHI7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsaXRlcmFsIG51bWJlcgogICAgICoKICAgICAqIEByZXR1cm4gaW50fGZsb2F0fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbE51bWJlcigpCiAgICB7CiAgICAgICAgaWYgKAogICAgICAgICAgICAkdGhpcy0+Z2V0Q2hhcigpID09PSAiMCIgJiYKICAgICAgICAgICAgKCR2YWwgPSAkdGhpcy0+Y29uc3VtZVJlZ2V4KCIwW3hYXVthLWZBLUZdK3wwW2JCXVswMV0rfDBbb09dWzAtN10rIikpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRmb3JtID0gc3RydG9sb3dlcigkdmFsWzFdKTsKICAgICAgICAgICAgJHZhbCA9IHN1YnN0cigkdmFsLCAyKTsKICAgICAgICAgICAgaWYgKCRmb3JtID09PSAieCIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoZXhkZWMoJHZhbCk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkZm9ybSA9PT0gIm8iKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2N0ZGVjKCR2YWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBiaW5kZWMoJHZhbCk7CiAgICAgICAgfQogICAgICAgICRyZWcgPSAiLT9cZCsoPzpcLlxkKyk/KD86W2VFXVsrLV0/XGQrKT98LT9cLlxkKyg/OltlRV1bKy1dP1xkKyk/IjsKICAgICAgICBpZiAoISgkdmFsID0gJHRoaXMtPmNvbnN1bWVSZWdleCgkcmVnKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoZmxvYXQpICR2YWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsaXRlcmFsIHJlZ2V4CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxpdGVyYWxSZWdleCgpCiAgICB7CiAgICAgICAgaWYgKCEoJHNlcCA9ICR0aGlzLT5jb25zdW1lKCIvIikpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAoKCRyZWcgPSAkdGhpcy0+Y29uc3VtZVVudGlsKCRzZXAsIGZhbHNlLCB0cnVlKSkgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIHJlZ2V4IGluIGF0dHJpYnV0ZSB2YWx1ZSIpOwogICAgICAgIH0KICAgICAgICAkbW9kaWZpZXJzID0gJHRoaXMtPmNvbnN1bWVXb3JkKCk7CiAgICAgICAgcmV0dXJuICRzZXAgLiAkcmVnIC4gKCRtb2RpZmllcnMgPzogIiIpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3VtZXMgdGhlIGdpdmVuIHJlZ2V4CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVnZXggUmVnZXggdG8gY29uc3VtZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uc3VtZVJlZ2V4KCRyZWdleCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdldENoYXIoKSA9PT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCIjXigkcmVnZXgpIyIsIHN1YnN0cigkdGhpcy0+c2VsZWN0b3IsICR0aGlzLT5pbmRleCksICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmluZGV4ICs9IHN0cmxlbigkbWF0Y2hlc1sxXSk7CiAgICAgICAgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3VtZXMgYWxsIHRoZSBjaGFyYWN0ZXJzIHVudGlsIHRoZSBnaXZlbiBvbmUgaXMgcmVhY2hlZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0b3AgICAgICAgICAgU3RvcCBjaGFyYWN0ZXIKICAgICAqIEBwYXJhbSBib29sICAgJHJlbW92ZUVzY2FwZXMgSWYgZmFsc2UgZXNjYXBlIGNoYXJhY3RlcnMgd29uJ3QgYmUgcmVtb3ZlZAogICAgICogQHBhcmFtIGZhbHNlICAkaW5jbHVkZVN0b3AgICBJZiB0cnVlIHN0b3AgY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lVW50aWwoJHN0b3AsICRyZW1vdmVFc2NhcGVzID0gdHJ1ZSwgJGluY2x1ZGVTdG9wID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGJ1ZmZlciA9ICIiOwogICAgICAgICRlc2NhcGVkID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5nZXRDaGFyKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAxOwogICAgICAgICAgICBpZiAoISRlc2NhcGVkKSB7CiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICJcXCIpIHsKICAgICAgICAgICAgICAgICAgICAkZXNjYXBlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkcmVtb3ZlRXNjYXBlcykgewogICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkY2hhciA9PT0gJHN0b3ApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGluY2x1ZGVTdG9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICRlc2NhcGVkID0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3VtZXMgYSB3b3JkIGNvbXBvc2VkIGJ5IGNoYXJhY3RlcnMgYS16CiAgICAgKgogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRleHRyYUNoYXIgRXh0cmEgY2hhcmFjdGVyIHRvIG1hdGNoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVXb3JkKCRleHRyYUNoYXIgPSBudWxsKQogICAgewogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICB3aGlsZSAoJGNoYXIgPSAkdGhpcy0+Z2V0Q2hhcigpKSB7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICgkY2hhciA+PSAiYSIgJiYgJGNoYXIgPD0gInoiKSB8fAogICAgICAgICAgICAgICAgKCRjaGFyID49ICJBIiAmJiAkY2hhciA8PSAiWiIpIHx8CiAgICAgICAgICAgICAgICAoJGV4dHJhQ2hhciAhPT0gbnVsbCAmJiAkY2hhciA9PT0gJGV4dHJhQ2hhcikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGJ1ZmZlcjsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgY29tYmluYXRvcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVDb21iaW5hdG9yKCkKICAgIHsKICAgICAgICAvL0luaXRpYWwgd3MgY2FuIGJlIHRyaW1tZWQgaWYgZm9sbG93ZWQgYnkgYW5vdGhlciBjb21iaW5hdG9yCiAgICAgICAgJHdzID0gJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgIGlmICgkY29tYmluYXRvciA9ICR0aGlzLT5jb25zdW1lQW55KCR0aGlzLT5jb21iaW5hdG9ycywgdHJ1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgIH0gZWxzZWlmICgkd3MpIHsKICAgICAgICAgICAgLy9JZiB0aGVyZSdzIG5vIG90aGVyIGNvbWJpbmF0b3JzIHVzZSB0aGUgc3BhY2UKICAgICAgICAgICAgJGNvbWJpbmF0b3IgPSAiICI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNvbWJpbmF0b3IgPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGNvbWJpbmF0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhcyBtdWNoIHdoaXRlc3BhY2VzIGFzIHBvc3NpYmxlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVXaGl0ZXNwYWNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25zdW1lQW55KCR0aGlzLT53aGl0ZXNwYWNlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdW1lcyB0aGUgZ2l2ZW4gY2hhcmFjdGVycwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkY2hhcnMgICAgICAgQ2hhcmFjdGVycyB0byBjb25zdW1lCiAgICAgKiBAcGFyYW0gZmFsc2UgJHN0b3BBdEZpcnN0IElmIHRydWUgb25seSB0aGUgZmlyc3QgbWF0Y2hpbmcgY2hhcmFjdGVyCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGNvbnN1bWVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVBbnkoJGNoYXJzLCAkc3RvcEF0Rmlyc3QgPSBmYWxzZSkKICAgIHsKICAgICAgICAkYnVmZmVyID0gIiI7CiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5nZXRDaGFyKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkY2hhciwgJGNoYXJzKSkgewogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgaWYgKCRzdG9wQXRGaXJzdCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRidWZmZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdW1lcyB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaWYgaXQgaXMgZXF1YWwgdG8gdGhlCiAgICAgKiBnaXZlbiBvbmUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyIENoYXJhY3RlciB0byBjb21wYXJlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uc3VtZSgkY2hhcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdldENoYXIoKSA9PT0gJGNoYXIpIHsKICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgIHJldHVybiAkY2hhcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGNoYXJhY3RlciBvciBudWxsIGlmIHRoZSBlbmQKICAgICAqIGhhdmUgYmVlbiByZWFjaGVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q2hhcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pbmRleCA8ICR0aGlzLT5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5zZWxlY3RvclskdGhpcy0+aW5kZXhdOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3I7CgovKioKICogU2VsZWN0b3IgZXhjZXB0aW9uIGNsYXNzLiBTeW50YXggZXJyb3JzIGluIHNlbGVjdG9ycyBhcmUgdGhyb3duCiAqIHVzaW5nIHRoaXMgZXhjZXB0aW9uIGNsYXNzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBFeGNlcHRpb24gZXh0ZW5kcyBcRXhjZXB0aW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3I7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBTZWxlY3RvciBtYXRjaGVzIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIE1hdGNoZXMKewogICAgLyoqCiAgICAgKiBNYXRjaGVzIGFycmF5CiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJG1hdGNoZXM7CgogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWF0Y2hlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSAkbWF0Y2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBuZXcgbWF0Y2gKICAgICAqCiAgICAgKiBAcGFyYW0gTm9kZSAkbm9kZQogICAgICogQHBhcmFtIE5vZGV8bnVsbCAkcGFyZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRNYXRjaChOb2RlICRub2RlLCBOb2RlICRwYXJlbnQgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5tYXRjaGVzW10gPSBhcnJheSgkbm9kZSwgJHBhcmVudCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtYXRjaGVzCiAgICAgKgogICAgICogQHJldHVybnMgYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1hdGNoZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWF0Y2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1hdGNoZWQgbm9kZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROb2RlcygpIHsKICAgICAgICByZXR1cm4gYXJyYXlfbWFwKGZ1bmN0aW9uICgkbSkgewogICAgICAgICAgICByZXR1cm4gJG1bMF07CiAgICAgICAgfSwgJHRoaXMtPm1hdGNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogRmlsdGVycyB0aGUgbWF0Y2hlcyB1c2luZyB0aGUgZ2l2ZW4gZnVuY3Rpb24sIGlmIGl0IHJldHVybnMKICAgICAqIGEgZmFsc2UgdmFsdWUgdGhlIG1hdGNoIHdpbGwgYmUgcmVtb3ZlZC4gVGhlIGZ1bmN0aW9uIHdpbGwKICAgICAqIHJlY2VpdmUgdGhlIG5vZGUgYW5kIGl0cyBwYXJlbnQgYXMgYXJndW1lbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkZm4gRmlsdGVyIGZ1bmN0aW9uCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoY2FsbGFibGUgJGZuKQogICAgewogICAgICAgICRuZXdNYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+bWF0Y2hlcyBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgaWYgKCRmbigkbWF0Y2hbMF0sICRtYXRjaFsxXSkpIHsKICAgICAgICAgICAgICAgICRuZXdNYXRjaGVzW10gPSAkbWF0Y2g7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSAkbmV3TWF0Y2hlczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBsYWNlcyBhbGwgdGhlIG1hdGNoZXMgd2l0aCB0aGUgcmVzdWx0IG9mIHRoZSBnaXZlbiBmdW5jdGlvbi4KICAgICAqIFRoZSBmdW5jdGlvbiB3aWxsIHJlY2VpdmUgdGhlIG5vZGUgYW5kIGl0cyBwYXJlbnQgYXMgYXJndW1lbnRzCiAgICAgKiBhbmQgbXVzdCByZXR1cm4gYW4gYXJyYXkgb2YgbWF0Y2hlcwogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkZm4gTWFwIGZ1bmN0aW9uCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFwKGNhbGxhYmxlICRmbikKICAgIHsKICAgICAgICAkbmV3TWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm1hdGNoZXMgYXMgJG1hdGNoKSB7CiAgICAgICAgICAgICRyZXMgPSAkZm4oJG1hdGNoWzBdLCAkbWF0Y2hbMV0pOwogICAgICAgICAgICBpZiAoJHJlcykgewogICAgICAgICAgICAgICAgJG5ld01hdGNoZXMgPSBhcnJheV9tZXJnZSgkbmV3TWF0Y2hlcywgJHJlcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSAkbmV3TWF0Y2hlczsKICAgICAgICByZXR1cm4gJHRoaXMtPnVuaXF1ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2VzIHRoZSBjdXJyZW50IG9iamVjdCB3aXRoIHRoZSBvdGhlciBnaXZlbiBNYXRjaGVzIG9iamVjdHMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlc1tdICRtYXRjaGVzQXJyIEFycmF5IG9mIE1hdGNoZXMgdG8gbWVyZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtZXJnZSgkbWF0Y2hlc0FycikKICAgIHsKICAgICAgICBmb3JlYWNoICgkbWF0Y2hlc0FyciBhcyAkbWF0Y2hlcykgewogICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcy0+Z2V0TWF0Y2hlcygpIGFzICRtYXRjaCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZE1hdGNoKCRtYXRjaFswXSwgJG1hdGNoWzFdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPnVuaXF1ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlIGFsbCBkdXBsaWNhdGVkIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmlxdWUoKQogICAgewogICAgICAgICRuZXdNYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICAkbmV3Tm9kZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5tYXRjaGVzIGFzICRtYXRjaCkgewogICAgICAgICAgICBpZiAoIWluX2FycmF5KCRtYXRjaFswXSwgJG5ld05vZGVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJG5ld01hdGNoZXNbXSA9ICRtYXRjaDsKICAgICAgICAgICAgICAgICRuZXdOb2Rlc1tdID0gJG1hdGNoWzBdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR0aGlzLT5tYXRjaGVzID0gJG5ld01hdGNoZXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGNsb25lIG9mIHRoZSBjdXJyZW50IG9iamVjdAogICAgICoKICAgICAqIEByZXR1cm4gTWF0Y2hlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlQ2xvbmUoKQogICAgewogICAgICAgIHJldHVybiBuZXcgc2VsZigkdGhpcy0+bWF0Y2hlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgbWF0Y2hlcwogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvdW50KCR0aGlzLT5tYXRjaGVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1hdGNoIGF0IHRoZSBnaXZlbiBpbmRleAogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGluZGV4IEluZGV4CiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0KCRpbmRleCkKICAgIHsKICAgICAgICAkaW5kZXggPSAoaW50KSAkaW5kZXg7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+bWF0Y2hlc1skaW5kZXhdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCBpbmRleCAkaW5kZXgiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaGVzWyRpbmRleF07CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0OwoKLyoqCiAqIE5vZGVzIHRyYXZlcnNlciBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUcmF2ZXJzZXIKewogICAgLyoqCiAgICAgKiBJZiBhIGZ1bmN0aW9uIHJldHVybiB0aGlzIHZhbHVlLCB0aGUgY3VycmVudCBub2RlIHdpbGwgYmUgcmVtb3ZlZAogICAgICovCiAgICBjb25zdCBSRU1PVkVfTk9ERSA9IDE7CiAgICAKICAgIC8qKgogICAgICogSWYgYSBmdW5jdGlvbiByZXR1cm4gdGhpcyB2YWx1ZSwgdGhlIGN1cnJlbnQgbm9kZSdzIGNoaWxkcmVuIHdvbid0IGJlCiAgICAgKiB0cmF2ZXJzZWQKICAgICAqLwogICAgY29uc3QgRE9OVF9UUkFWRVJTRV9DSElMRF9OT0RFUyA9IDI7CiAgICAKICAgIC8qKgogICAgICogSWYgYSBmdW5jdGlvbiByZXR1cm4gdGhpcyB2YWx1ZSwgdGhlIHRyYXZlcnNlciB3aWxsIHN0b3AgcnVubmluZwogICAgICovCiAgICBjb25zdCBTVE9QX1RSQVZFUlNJTkcgPSA0OwogICAgCiAgICAvKioKICAgICAqIEFycmF5IG9mIGZ1bmN0aW9ucyB0byBjYWxsIG9uIGVhY2ggbm9kZQogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkZnVuY3Rpb25zID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFBhc3MgcGFyZW50IG5vZGUgZmxhZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhc3NQYXJlbnROb2RlID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBTa2lwIHN0YXJ0aW5nIG5vZGUgZmxhZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNraXBTdGFydGluZ05vZGUgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yLiBBdmFpbGFibGUgb3B0aW9ucyBhcmU6CiAgICAgKiAtIHNraXBTdGFydGluZ05vZGU6IGlmIHRydWUgdGhlIHN0YXJ0aW5nIG5vZGUgd2lsbCBiZSBza2lwcGVkCiAgICAgKiAtIHBhc3NQYXJlbnROb2RlOiBpZiB0cnVlIHRoZSBwYXJlbnQgbm9kZSBvZiBlYWNoIG5vZGUgd2lsbCBiZQogICAgICogICBwYXNzZWQgYXMgc2Vjb25kIGFyZ3VtZW50IHdoZW4gdGhlIGZ1bmN0aW9ucyBhcmUgY2FsbGVkLiBOb3RlCiAgICAgKiAgIHRoYXQgdGhlIHBhcmVudCBub2RlIGlzIGNhbGN1bGF0ZWQgZHVyaW5nIHRyYXZlcnNpbmcsIHNvIGZvcgogICAgICogICB0aGUgc3RhcnRpbmcgbm9kZSBpdCB3aWxsIGFsd2F5cyBiZSBudWxsLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBPcHRpb25zIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWyJwYXNzUGFyZW50Tm9kZSJdKSkgewogICAgICAgICAgICAkdGhpcy0+cGFzc1BhcmVudE5vZGUgPSAoYm9vbCkgJG9wdGlvbnNbInBhc3NQYXJlbnROb2RlIl07CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1sic2tpcFN0YXJ0aW5nTm9kZSJdKSkgewogICAgICAgICAgICAkdGhpcy0+c2tpcFN0YXJ0aW5nTm9kZSA9IChib29sKSAkb3B0aW9uc1sic2tpcFN0YXJ0aW5nTm9kZSJdOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBBZGRzIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaCBub2RlIGluIHRoZSB0cmVlLiBUaGUKICAgICAqIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0aGUgY3VycmVudCBub2RlIGFzIGFyZ3VtZW50LiBUaGUgYWN0aW9uIHRoYXQgd2lsbAogICAgICogYmUgZXhlY3V0ZWQgb24gdGhlIG5vZGUgYnkgdGhlIHRyYXZlcnNlciBkZXBlbmRzIG9uIHRoZSByZXR1cm5lZCB2YWx1ZQogICAgICogb2YgdGhlIGZ1bmN0aW9uOgogICAgICogLSBhIG5vZGU6IGl0IHdpbGwgcmVwbGFjZSB0aGUgbm9kZSB3aXRoIHRoZSByZXR1cm5lZCBvbmUKICAgICAqIC0gYSBudW1lcmljIHZhbHVlIHRoYXQgaXMgYSBjb21iaW5hdGlvbiBvZiB0aGUgY29uc3RhbnRzIGRlZmluZWQgaW4gdGhpcwogICAgICogICBjbGFzczogaXQgd2lsbCBleGVjdXRlIHRoZSBmdW5jdGlvbiByZWxhdGVkIHRvIGVhY2ggY29uc3RhbnQKICAgICAqIC0gYW4gYXJyYXkgd2hlcmUgdGhlIGZpcnN0IGVsZW1lbnQgaXMgYSBub2RlIGFuZCB0aGUgc2Vjb25kIGVsZW1lbnQgaXMgYQogICAgICogICBudW1lcmljIHZhbHVlIHRoYXQgaXMgYSBjb21iaW5hdGlvbiBvZiB0aGUgY29uc3RhbnRzIGRlZmluZWQgaW4gdGhpcwogICAgICogICBjbGFzczogaXQgd2lsbCByZXBsYWNlIHRoZSBub2RlIHdpdGggdGhlIHJldHVybmVkIG9uZSBhbmQgIGl0IHdpbGwKICAgICAqICAgZXhlY3V0ZSB0aGUgZnVuY3Rpb24gcmVsYXRlZCB0byBlYWNoIGNvbnN0YW50IChSRU1PVkVfTk9ERSB3aWxsIGJlCiAgICAgKiAgIGlnbm9yZWQgc2luY2UgaXQgZG9lcyBub3QgbWFrZSBhbnkgc2Vuc2UgaW4gdGhpcyBjYXNlKQogICAgICogLSBvdGhlcjogbm90aGluZwogICAgICogCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGZuIEZ1bmN0aW9uIHRvIGFkZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRGdW5jdGlvbihjYWxsYWJsZSAkZm4pCiAgICB7CiAgICAgICAgJHRoaXMtPmZ1bmN0aW9uc1tdID0gJGZuOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTdGFydHMgdGhlIHRyYXZlcnNpbmcKICAgICAqIAogICAgICogQHBhcmFtIFN5bnRheFxOb2RlXE5vZGUgICRub2RlICAgU3RhcnRpbmcgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFN5bnRheFxOb2RlXE5vZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRyYXZlcnNlKFN5bnRheFxOb2RlXE5vZGUgJG5vZGUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5za2lwU3RhcnRpbmdOb2RlKSB7CiAgICAgICAgICAgICR0aGlzLT50cmF2ZXJzZUNoaWxkcmVuKCRub2RlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+ZXhlY0Z1bmN0aW9ucygkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkbm9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBFeGVjdXRlcyBhbGwgZnVuY3Rpb25zIG9uIHRoZSBnaXZlbiBub2RlIGFuZCwgaWYgcmVxdWlyZWQsIHN0YXJ0cwogICAgICogdHJhdmVyc2luZyBpdHMgY2hpbGRyZW4uIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhbiBhcnJheSB3aGVyZSB0aGUgZmlyc3QKICAgICAqIHZhbHVlIGlzIHRoZSBub2RlIG9yIG51bGwgaWYgaXQgaGFzIGJlZW4gcmVtb3ZlZCBhbmQgdGhlIHNlY29uZCB2YWx1ZSBpcwogICAgICogYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIHRyYXZlcnNlciBtdXN0IGNvbnRpbnVlIHRoZSB0cmF2ZXJzaW5nIG9yIG5vdAogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgICAgICAkbm9kZSAgICAgTm9kZQogICAgICogQHBhcmFtIFN5bnRheFxOb2RlXE5vZGV8bnVsbCAgJHBhcmVudCAgIFBhcmVudCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWNGdW5jdGlvbnMoJG5vZGUsICRwYXJlbnQgPSBudWxsKQogICAgewogICAgICAgICR0cmF2ZXJzZUNoaWxkcmVuID0gdHJ1ZTsKICAgICAgICAkY29udGludWVUcmF2ZXJzaW5nID0gdHJ1ZTsKICAgICAgICAKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZnVuY3Rpb25zIGFzICRmbikgewogICAgICAgICAgICAkcmV0ID0gJHRoaXMtPnBhc3NQYXJlbnROb2RlID8gJGZuKCRub2RlLCAkcGFyZW50KSA6ICRmbigkbm9kZSk7CiAgICAgICAgICAgIGlmICgkcmV0KSB7CiAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHJldCkgJiYgJHJldFswXSBpbnN0YW5jZW9mIFN5bnRheFxOb2RlXE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICRyZXRbMF07CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXRbMV0pICYmIGlzX251bWVyaWMoJHJldFsxXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXRbMV0gJiBzZWxmOjpET05UX1RSQVZFUlNFX0NISUxEX05PREVTKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhdmVyc2VDaGlsZHJlbiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcmV0WzFdICYgc2VsZjo6U1RPUF9UUkFWRVJTSU5HKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGludWVUcmF2ZXJzaW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHJldCBpbnN0YW5jZW9mIFN5bnRheFxOb2RlXE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICRyZXQ7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNfbnVtZXJpYygkcmV0KSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkcmV0ICYgc2VsZjo6RE9OVF9UUkFWRVJTRV9DSElMRF9OT0RFUykgewogICAgICAgICAgICAgICAgICAgICAgICAkdHJhdmVyc2VDaGlsZHJlbiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHJldCAmIHNlbGY6OlNUT1BfVFJBVkVSU0lORykgewogICAgICAgICAgICAgICAgICAgICAgICAkY29udGludWVUcmF2ZXJzaW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkcmV0ICYgc2VsZjo6UkVNT1ZFX05PREUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAkdHJhdmVyc2VDaGlsZHJlbiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKCR0cmF2ZXJzZUNoaWxkcmVuICYmICRjb250aW51ZVRyYXZlcnNpbmcpIHsKICAgICAgICAgICAgJGNvbnRpbnVlVHJhdmVyc2luZyA9ICR0aGlzLT50cmF2ZXJzZUNoaWxkcmVuKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIGFycmF5KCRub2RlLCAkY29udGludWVUcmF2ZXJzaW5nKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUcmF2ZXJzZXMgbm9kZSBjaGlsZHJlbi4gSXQgcmV0dXJucyBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUKICAgICAqIHRyYXZlcnNpbmcgbXVzdCBjb250aW51ZSBvciBub3QKICAgICAqIAogICAgICogQHBhcmFtIFN5bnRheFxOb2RlXE5vZGUgICRub2RlICAgTm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHRyYXZlcnNlQ2hpbGRyZW4oU3ludGF4XE5vZGVcTm9kZSAkbm9kZSkKICAgIHsKICAgICAgICAkY29udGludWUgPSB0cnVlOwogICAgICAgIAogICAgICAgIGZvcmVhY2ggKFN5bnRheFxVdGlsczo6Z2V0Tm9kZVByb3BlcnRpZXMoJG5vZGUsIHRydWUpIGFzICRwcm9wKSB7CiAgICAgICAgICAgICRnZXR0ZXIgPSAkcHJvcFsiZ2V0dGVyIl07CiAgICAgICAgICAgICRzZXR0ZXIgPSAkcHJvcFsic2V0dGVyIl07CiAgICAgICAgICAgICRjaGlsZCA9ICRub2RlLT4kZ2V0dGVyKCk7CiAgICAgICAgICAgIGlmICghJGNoaWxkKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2FycmF5KCRjaGlsZCkpIHsKICAgICAgICAgICAgICAgICRuZXdDaGlsZHJlbiA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkY2hpbGQgYXMgJGMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISRjIHx8ICEkY29udGludWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5ld0NoaWxkcmVuW10gPSAkYzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0KCRjLCAkY29udGludWUpID0gJHRoaXMtPmV4ZWNGdW5jdGlvbnMoJGMsICRub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmV3Q2hpbGRyZW5bXSA9ICRjOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG5vZGUtPiRzZXR0ZXIoJG5ld0NoaWxkcmVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxpc3QoJGNoaWxkLCAkY29udGludWUpID0gJHRoaXMtPmV4ZWNGdW5jdGlvbnMoJGNoaWxkLCAkbm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+JHNldHRlcigkY2hpbGQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoISRjb250aW51ZSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuICRjb250aW51ZTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XEVTMjAyMTsKCi8qKgogKiBFUzIwMjEgZmVhdHVyZXMgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKiAKICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogKi8KY2xhc3MgRmVhdHVyZXMgZXh0ZW5kcyBcUGVhc3RcU3ludGF4XEVTMjAyMFxGZWF0dXJlcwp7CiAgICAvKioKICAgICAqIExvZ2ljYWwgYXNzaWdubWVudCBvcGVyYXRvcnMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRsb2dpY2FsQXNzaWdubWVudE9wZXJhdG9ycyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBOdW1lcmljIGxpdGVyYWwgc2VwYXJhdG9yCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkbnVtZXJpY0xpdGVyYWxTZXBhcmF0b3IgPSB0cnVlOwp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXg7CgovKioKICogQmFzZSBjbGFzcyBmb3Igc2Nhbm5lcnMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFNjYW5uZXIKewogICAgdXNlIEpTWFxTY2FubmVyOwoKICAgIC8qKgogICAgICogU2Nhbm5lciBmZWF0dXJlcwogICAgICogCiAgICAgKiBAdmFyIEZlYXR1cmVzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZmVhdHVyZXM7CgogICAgLyoqCiAgICAgKiBDdXJyZW50IGNvbHVtbgogICAgICogCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbHVtbiA9IDA7CiAgICAKICAgIC8qKgogICAgICogQ3VycmVudCBsaW5lCiAgICAgKiAKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGluZSA9IDE7CiAgICAKICAgIC8qKgogICAgICogQ3VycmVudCBpbmRleAogICAgICogCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGluZGV4ID0gMDsKICAgIAogICAgLyoqCiAgICAgKiBTb3VyY2UgbGVuZ3RoCiAgICAgKiAKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGVuZ3RoOwogICAgCiAgICAvKioKICAgICAqIFNvdXJjZSBjaGFyYWN0ZXJzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRzb3VyY2U7CiAgICAKICAgIC8qKgogICAgICogQ29uc3VtZWQgcG9zaXRpb24KICAgICAqIAogICAgICogQHZhciBQb3NpdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJHBvc2l0aW9uOwogICAgCiAgICAvKioKICAgICAqIEN1cnJlbnQgdG9rZW4KICAgICAqIAogICAgICogQHZhciBUb2tlbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRjdXJyZW50VG9rZW47CiAgICAKICAgIC8qKgogICAgICogTmV4dCB0b2tlbgogICAgICogCiAgICAgKiBAdmFyIFRva2VuIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG5leHRUb2tlbjsKICAgIAogICAgLyoqCiAgICAgKiBTdHJpY3QgbW9kZSBmbGFnCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRzdHJpY3RNb2RlID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogVHJ1ZSB0byByZWdpc3RlciB0b2tlbnMgaW4gdGhlIHRva2VucyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVnaXN0ZXJUb2tlbnMgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBNb2R1bGUgbW9kZQogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaXNNb2R1bGUgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyBoYW5kbGluZwogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tbWVudHMgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBJbnRlcm5hbCBKU1ggc2NhbiBmbGFnCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGpzeCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJlZ2lzdGVyZWQgdG9rZW5zIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdG9rZW5zID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyB0byB0b2tlbnMgbWFwCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tbWVudHNNYXAgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIEV2ZW50cyBlbWl0dGVyCiAgICAgKgogICAgICogQHZhciBFdmVudHNFbWl0dGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXZlbnRzRW1pdHRlcjsKICAgIAogICAgLyoqCiAgICAgKiBSZWdleCB0byBtYXRjaCBpZGVudGlmaWVycyBzdGFydHMKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaWRTdGFydFJlZ2V4ID0gIi9bXHB7THV9XHB7TGx9XHB7THR9XHB7TG19XHB7TG99XHB7Tmx9XHh7MTg4NX1ceHsxODg2fVx4ezIxMTh9XHh7MjEyRX1ceHszMDlCfVx4ezMwOUN9XS91IjsKICAgIAogICAgLyoqCiAgICAgKiBSZWdleCB0byBtYXRjaCBpZGVudGlmaWVycyBwYXJ0cwogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRpZFBhcnRSZWdleCA9ICIvW1xwe0x1fVxwe0xsfVxwe0x0fVxwe0xtfVxwe0xvfVxwe05sfVx4ezE4ODV9XHh7MTg4Nn1ceHsyMTE4fVx4ezIxMkV9XHh7MzA5Qn1ceHszMDlDfVxwe01ufVxwe01jfVxwe05kfVxwe1BjfVx4ezAwQjd9XHh7MDM4N31ceHsxMzY5fVx4ezEzNkF9XHh7MTM2Qn1ceHsxMzZDfVx4ezEzNkR9XHh7MTM2RX1ceHsxMzZGfVx4ezEzNzB9XHh7MTM3MX1ceHsxOURBfVx4ezIwMEN9XHh7MjAwRH1dL3UiOwogICAgCiAgICAvKioKICAgICAqIEtleXdvcmRzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2V5d29yZHMgPSBhcnJheSgKICAgICAgICAiYnJlYWsiLCAiZG8iLCAiaW4iLCAidHlwZW9mIiwgImNhc2UiLCAiZWxzZSIsICJpbnN0YW5jZW9mIiwgInZhciIsCiAgICAgICAgImNhdGNoIiwgImV4cG9ydCIsICJuZXciLCAidm9pZCIsICJjbGFzcyIsICJleHRlbmRzIiwgInJldHVybiIsICJ3aGlsZSIsCiAgICAgICAgImNvbnN0IiwgImZpbmFsbHkiLCAic3VwZXIiLCAid2l0aCIsICJjb250aW51ZSIsICJmb3IiLCAic3dpdGNoIiwKICAgICAgICAiZGVidWdnZXIiLCAiZnVuY3Rpb24iLCAidGhpcyIsICJkZWZhdWx0IiwgImlmIiwgInRocm93IiwKICAgICAgICAiZGVsZXRlIiwgImltcG9ydCIsICJ0cnkiLCAiZW51bSIsICJhd2FpdCIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2Ygd29yZHMgdGhhdCBhcmUga2V5d29yZHMgb25seSBpbiBzdHJpY3QgbW9kZQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0cmljdE1vZGVLZXl3b3JkcyA9IGFycmF5KAogICAgICAgICJpbXBsZW1lbnRzIiwgImludGVyZmFjZSIsICJwYWNrYWdlIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwgInB1YmxpYyIsCiAgICAgICAgInN0YXRpYyIsICJsZXQiLCAieWllbGQiCiAgICApOwoKICAgIC8qKgogICAgICogUHVuY3R1YXRvcnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwdW5jdHVhdG9ycyA9IGFycmF5KAogICAgICAgICIuIiwgIjsiLCAiLCIsICI8IiwgIj4iLCAiPD0iLCAiPj0iLCAiPT0iLCAiIT0iLCAiPT09IiwgIiE9PSIsICIrIiwKICAgICAgICAiLSIsICIqIiwgIiUiLCAiKysiLCAiLS0iLCAiPDwiLCAiPj4iLCAiPj4+IiwgIiYiLCAifCIsICJeIiwgIiEiLCAifiIsCiAgICAgICAgIiYmIiwgInx8IiwgIj8iLCAiOiIsICI9IiwgIis9IiwgIi09IiwgIio9IiwgIiU9IiwgIjw8PSIsICI+Pj0iLCAiPj4+PSIsCiAgICAgICAgIiY9IiwgInw9IiwgIl49IiwgIj0+IiwgIi4uLiIsICIvIiwgIi89IiwgIioqIiwgIioqPSIsICI/PyIsICI/LiIsCiAgICAgICAgIiYmPSIsICJ8fD0iLCAiPz89IgogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBQdW5jdHVhdG9ycyBMU00KICAgICAqIAogICAgICogQHZhciBMU00gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHVuY3R1YXRvcnNMU007CiAgICAKICAgIC8qKgogICAgICogU3RyaW5ncyBzdG9wcyBMU00KICAgICAqIAogICAgICogQHZhciBMU00gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3RyaW5nc1N0b3BzTFNNOwogICAgCiAgICAvKioKICAgICAqIEJyYWNrZXRzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYnJhY2tldHMgPSBhcnJheSgKICAgICAgICAiKCIgPT4gIiIsICJbIiA9PiAiIiwgInsiID0+ICIiLCAiKSIgPT4gIigiLCAiXSIgPT4gIlsiLCAifSIgPT4gInsiCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE9wZW4gYnJhY2tldHMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRvcGVuQnJhY2tldHMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIE9wZW4gdGVtcGxhdGVzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlblRlbXBsYXRlcyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogV2hpdGVzcGFjZXMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICR3aGl0ZXNwYWNlcyA9IGFycmF5KAogICAgICAgICIgIiwgIlx0IiwgIlxuIiwgIlxyIiwgIlxmIiwgIlx2IiwgMHgwMEEwLCAweEZFRkYsIDB4MDBBMCwKICAgICAgICAweDE2ODAsIDB4MjAwMCwgMHgyMDAxLCAweDIwMDIsIDB4MjAwMywgMHgyMDA0LCAweDIwMDUsIDB4MjAwNiwKICAgICAgICAweDIwMDcsIDB4MjAwOCwgMHgyMDA5LCAweDIwMEEsIDB4MjAyRiwgMHgyMDVGLCAweDMwMDAsIDB4MjAyOCwKICAgICAgICAweDIwMjkKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTGluZSB0ZXJtaW5hdG9ycyBjaGFyYWN0ZXJzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKiAKICAgICAqIEBzdGF0aWMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyAkbGluZVRlcm1pbmF0b3JzQ2hhcnMgPSBhcnJheSgiXG4iLCAiXHIiLCAweDIwMjgsIDB4MjAyOSk7CiAgICAKICAgIC8qKgogICAgICogTGluZSB0ZXJtaW5hdG9ycyBzZXF1ZW5jZXMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICogCiAgICAgKiBAc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgJGxpbmVUZXJtaW5hdG9yc1NlcXVlbmNlcyA9IGFycmF5KCJcclxuIik7CiAgICAKICAgIC8qKgogICAgICogUmVnZXggdG8gc3BsaXQgdGV4dHMgdXNpbmcgdmFsaWQgRVMgbGluZSB0ZXJtaW5hdG9ycwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxpbmVzU3BsaXR0ZXI7CiAgICAKICAgIC8qKgogICAgICogQ29uY2F0ZW5hdGlvbiBvZiBsaW5lIHRlcm1pbmF0b3JzIGNoYXJhY3RlcnMgYW5kIGxpbmUgdGVybWluYXRvcnMKICAgICAqIHNlcXVlbmNlcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxpbmVUZXJtaW5hdG9yczsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0aWVzIHRvIGNvcHkgd2hlbiBnZXR0aW5nIHRoZSBzY2FubmVyIHN0YXRlCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRzdGF0ZVByb3BzID0gYXJyYXkoInBvc2l0aW9uIiwgImluZGV4IiwgImNvbHVtbiIsICJsaW5lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjdXJyZW50VG9rZW4iLCAibmV4dFRva2VuIiwgInN0cmljdE1vZGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wZW5CcmFja2V0cyIsICJvcGVuVGVtcGxhdGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tZW50c01hcCIpOwogICAgCiAgICAvKioKICAgICAqIERlY2ltYWwgbnVtYmVycwogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkbnVtYmVycyA9IGFycmF5KCIwIiwgIjEiLCAiMiIsICIzIiwgIjQiLCAiNSIsICI2IiwgIjciLCAiOCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOSIpOwogICAgCiAgICAvKioKICAgICAqIEhleGFkZWNpbWFsIG51bWJlcnMKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHhudW1iZXJzID0gYXJyYXkoIjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1IiwgIjYiLCAiNyIsICI4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOSIsICJhIiwgImIiLCAiYyIsICJkIiwgImUiLCAiZiIsICJBIiwgIkIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDIiwgIkQiLCAiRSIsICJGIik7CgogICAgLyoqCiAgICAgKiBPY3RhbCBudW1iZXJzCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJG9udW1iZXJzID0gYXJyYXkoIjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1IiwgIjYiLCAiNyIpOwoKICAgIC8qKgogICAgICogQmluYXJ5IG51bWJlcnMKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm51bWJlcnMgPSBhcnJheSgiMCIsICIxIik7CgogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHNvdXJjZSAgIFNvdXJjZSBjb2RlCiAgICAgKiBAcGFyYW0gRmVhdHVyZXMgJGZlYXR1cmVzIFNjYW5uZXIgZmVhdHVyZXMKICAgICAqIEBwYXJhbSBhcnJheSAgICAkb3B0aW9ucyAgUGFyc2luZyBvcHRpb25zCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9fY29uc3RydWN0KAogICAgICAgICRzb3VyY2UsIEZlYXR1cmVzICRmZWF0dXJlcywgJG9wdGlvbnMKICAgICkgewogICAgICAgICR0aGlzLT5mZWF0dXJlcyA9ICRmZWF0dXJlczsKCiAgICAgICAgJGVuY29kaW5nID0gaXNzZXQoJG9wdGlvbnNbInNvdXJjZUVuY29kaW5nIl0pID8KICAgICAgICAgICAgICAgICAgICAkb3B0aW9uc1sic291cmNlRW5jb2RpbmciXSA6CiAgICAgICAgICAgICAgICAgICAgbnVsbDsKICAgICAgICAKICAgICAgICAvL1N0cmlwIEJPTSBjaGFyYWN0ZXJzIGZyb20gdGhlIHNvdXJjZQogICAgICAgICR0aGlzLT5zdHJpcEJPTSgkc291cmNlLCAkZW5jb2RpbmcpOwogICAgICAgIAogICAgICAgIC8vQ29udmVydCB0byBVVEY4IGlmIG5lZWRlZAogICAgICAgIGlmICgkZW5jb2RpbmcgJiYgIXByZWdfbWF0Y2goIi9VVEYtPzgvaSIsICRlbmNvZGluZykpIHsKICAgICAgICAgICAgJHNvdXJjZSA9IG1iX2NvbnZlcnRfZW5jb2RpbmcoJHNvdXJjZSwgIlVURi04IiwgJGVuY29kaW5nKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JbnN0ZWFkIG9mIHVzaW5nIG1iX3N1YnN0ciBmb3IgZWFjaCBjaGFyYWN0ZXIsIHNwbGl0IHRoZSBzb3VyY2UKICAgICAgICAvL2ludG8gYW4gYXJyYXkgb2YgVVRGOCBjaGFyYWN0ZXJzIGZvciBwZXJmb3JtYW5jZSByZWFzb25zCiAgICAgICAgJHRoaXMtPnNvdXJjZSA9IFV0aWxzOjpzdHJpbmdUb1VURjhBcnJheSgKICAgICAgICAgICAgJHNvdXJjZSwKICAgICAgICAgICAgIWlzc2V0KCRvcHRpb25zWyJzdHJpY3RFbmNvZGluZyJdKSB8fCAkb3B0aW9uc1sic3RyaWN0RW5jb2RpbmciXQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmxlbmd0aCA9IGNvdW50KCR0aGlzLT5zb3VyY2UpOwogICAgICAgIAogICAgICAgIC8vQ29udmVydCBjaGFyYWN0ZXIgY29kZXMgdG8gVVRGOCBjaGFyYWN0ZXJzIGluIHdoaXRlc3BhY2VzIGFuZCBsaW5lCiAgICAgICAgLy90ZXJtaW5hdG9ycwogICAgICAgICR0aGlzLT5saW5lVGVybWluYXRvcnMgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgc2VsZjo6JGxpbmVUZXJtaW5hdG9yc1NlcXVlbmNlcywgc2VsZjo6JGxpbmVUZXJtaW5hdG9yc0NoYXJzCiAgICAgICAgKTsKICAgICAgICBmb3JlYWNoIChhcnJheSgid2hpdGVzcGFjZXMiLCAibGluZVRlcm1pbmF0b3JzIikgYXMgJGtleSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+JGtleSBhcyAkaSA9PiAkY2hhcikgewogICAgICAgICAgICAgICAgaWYgKGlzX2ludCgkY2hhcikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+eyRrZXl9WyRpXSA9IFV0aWxzOjp1bmljb2RlVG9VdGY4KCRjaGFyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9SZW1vdmUgZXhwb25lbnRpYXRpb24gb3BlcmF0b3IgaWYgdGhlIGZlYXR1cmUKICAgICAgICAvL2lzIG5vdCBlbmFibGVkCiAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmV4cG9uZW50aWF0aW9uT3BlcmF0b3IpIHsKICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoJHRoaXMtPnB1bmN0dWF0b3JzLCAiKioiKTsKICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoJHRoaXMtPnB1bmN0dWF0b3JzLCAiKio9Iik7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+b3B0aW9uYWxDaGFpbmluZykgewogICAgICAgICAgICBVdGlsczo6cmVtb3ZlQXJyYXlWYWx1ZSgkdGhpcy0+cHVuY3R1YXRvcnMsICI/LiIpOwogICAgICAgIH0KCiAgICAgICAgLy9SZW1vdmUgbG9naWNhbCBhc3NpZ25tZW50IG9wZXJhdG9ycyBpZiB0aGUgZmVhdHVyZQogICAgICAgIC8vaXMgbm90IGVuYWJsZWQKICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+bG9naWNhbEFzc2lnbm1lbnRPcGVyYXRvcnMpIHsKICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoJHRoaXMtPnB1bmN0dWF0b3JzLCAiJiY9Iik7CiAgICAgICAgICAgIFV0aWxzOjpyZW1vdmVBcnJheVZhbHVlKCR0aGlzLT5wdW5jdHVhdG9ycywgInx8PSIpOwogICAgICAgICAgICBVdGlsczo6cmVtb3ZlQXJyYXlWYWx1ZSgkdGhpcy0+cHVuY3R1YXRvcnMsICI/Pz0iKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9DcmVhdGUgYSBMU00gZm9yIHB1bmN0dWF0b3JzIGFycmF5CiAgICAgICAgJHRoaXMtPnB1bmN0dWF0b3JzTFNNID0gbmV3IExTTSgkdGhpcy0+cHVuY3R1YXRvcnMpOwogICAgICAgIAogICAgICAgIC8vQ3JlYXRlIGEgTFNNIGZvciBzdHJpbmdzIHN0b3BzCiAgICAgICAgJHRoaXMtPnN0cmluZ3NTdG9wc0xTTSA9IG5ldyBMU00oJHRoaXMtPmxpbmVUZXJtaW5hdG9ycywgdHJ1ZSk7CiAgICAgICAgCiAgICAgICAgLy9BbGxvdyBwYXJhZ3JhcGggYW5kIGxpbmUgc2VwYXJhdG9ycyBpbiBzdHJpbmdzCiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+cGFyYWdyYXBoTGluZVNlcEluU3RyaW5ncykgewogICAgICAgICAgICAkdGhpcy0+c3RyaW5nc1N0b3BzTFNNLT5yZW1vdmUoVXRpbHM6OnVuaWNvZGVUb1V0ZjgoMHgyMDI4KSk7CiAgICAgICAgICAgICR0aGlzLT5zdHJpbmdzU3RvcHNMU00tPnJlbW92ZShVdGlsczo6dW5pY29kZVRvVXRmOCgweDIwMjkpKTsKICAgICAgICB9CgogICAgICAgIC8vUmVtb3ZlIGF3YWl0IGFzIGtleXdvcmQgaWYgYXN5bmMvYXdhaXQgaXMgZW5hYmxlZAogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQpIHsKICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoJHRoaXMtPmtleXdvcmRzLCAiYXdhaXQiKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPmxpbmVzU3BsaXR0ZXIgPSAiLyIgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbG9kZSgifCIsICR0aGlzLT5saW5lVGVybWluYXRvcnMpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIvdVMiOwogICAgICAgICR0aGlzLT5wb3NpdGlvbiA9IG5ldyBQb3NpdGlvbigwLCAwLCAwKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTdHJpcHMgQk9NIGNoYXJhY3RlcnMgZnJvbSB0aGUgc291cmNlIGFuZCBkZXRlY3RzIHNvdXJjZSBlbmNvZGluZyBpZiBub3QKICAgICAqIGdpdmVuIGJ5IHRoZSB1c2VyCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZSAgIFNvdXJjZQogICAgICogQHBhcmFtIHN0cmluZyAkZW5jb2RpbmcgVXNlciBzcGVjaWZpZWQgZW5jb2RpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0cmlwQk9NKCYkc291cmNlLCAmJGVuY29kaW5nKQogICAgewogICAgICAgICRib21zID0gYXJyYXkoCiAgICAgICAgICAgICJceEVGIiA9PiBhcnJheShhcnJheSgiXHhCQiIsICJceEJGIiksICJVVEYtOCIpLAogICAgICAgICAgICAiXHhGRSIgPT4gYXJyYXkoYXJyYXkoIlx4RkYiKSwgIlVURi0xNkJFIiksCiAgICAgICAgICAgICJceEZGIiA9PiBhcnJheShhcnJheSgiXHhGRSIpLCAiVVRGLTE2TEUiKSwKICAgICAgICApOwogICAgICAgIGlmICghaXNzZXQoJHNvdXJjZVswXSkgfHwgIWlzc2V0KCRib21zWyRzb3VyY2VbMF1dKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICRib20gPSAkYm9tc1skc291cmNlWzBdXTsKICAgICAgICAkbCA9IGNvdW50KCRib21bMF0pOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRsOyAkaSsrKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJHNvdXJjZVskaSArIDFdKSB8fCAkc291cmNlWyRpICsgMV0gIT09ICRib21bMF1bJGldKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHNvdXJjZSA9IHN1YnN0cigkc291cmNlLCAkbCArIDEpOwogICAgICAgIGlmICghJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRlbmNvZGluZyA9ICRib21bMV07CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgbW9kdWxlIHNjYW5uaW5nIG1vZGUKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGVuYWJsZSBUcnVlIHRvIGVuYWJsZSBtb2R1bGUgc2Nhbm5pbmcgbW9kZSwgZmFsc2UgdG8gZGlzYWJsZSBpdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVNb2R1bGVNb2RlKCRlbmFibGUgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5pc01vZHVsZSA9ICRlbmFibGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgY29tbWVudHMgaGFuZGxpbmcKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGVuYWJsZSBUcnVlIHRvIGVuYWJsZSBjb21tZW50cyBoYW5kbGluZywgZmFsc2UgdG8gZGlzYWJsZSBpdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVDb21tZW50cygkZW5hYmxlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWVudHMgPSAkZW5hYmxlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBFbmFibGVzIG9yIGRpc2FibGVzIHRva2VucyByZWdpc3RyYXRpb24gaW4gdGhlIHRva2VuIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRlbmFibGUgVHJ1ZSB0byBlbmFibGUgdG9rZW4gcmVnaXN0cmF0aW9uLCBmYWxzZSB0byBkaXNhYmxlIGl0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZVRva2VuUmVnaXN0cmF0aW9uKCRlbmFibGUgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5yZWdpc3RlclRva2VucyA9ICRlbmFibGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiByZWdpc3RlcmVkIHRva2VucwogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUb2tlbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dG9rZW5zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNjYW5uZXIncyBldmVudCBlbWl0dGVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXZlbnRzRW1pdHRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXZlbnRzRW1pdHRlcigpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZXZlbnRzRW1pdHRlcikgewogICAgICAgICAgICAvL1RoZSBldmVudCBlbWl0dGVyIGlzIGNyZWF0ZWQgaGVyZSBzbyB0aGF0IGl0IHdvbid0IGV4aXN0IGlmIG5vdAogICAgICAgICAgICAvL25lY2Vzc2FyeQogICAgICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciA9IG5ldyBFdmVudHNFbWl0dGVyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPmV2ZW50c0VtaXR0ZXI7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyBzdHJpY3QgbW9kZQogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkc3RyaWN0TW9kZSBTdHJpY3QgbW9kZSBzdGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHJpY3RNb2RlKCRzdHJpY3RNb2RlKQogICAgewogICAgICAgICR0aGlzLT5zdHJpY3RNb2RlID0gJHN0cmljdE1vZGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiBzdHJpY3QgbW9kZSBzdGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0cmljdE1vZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RyaWN0TW9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIHRva2VuIGlzIGEga2V5d29yZCBpbiB0aGUgY3VycmVudCBzdHJpY3QgbW9kZSBzdGF0ZQogICAgICogCiAgICAgKiBAcGFyYW0gVG9rZW4gJHRva2VuIFRva2VuIHRvIGNoZWNrcwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU3RyaWN0TW9kZUtleXdvcmQoJHRva2VuKQogICAgewogICAgICAgIHJldHVybiAkdG9rZW4tPnR5cGUgPT09IFRva2VuOjpUWVBFX0tFWVdPUkQgJiYKICAgICAgICAgICAgICAgKGluX2FycmF5KCR0b2tlbi0+dmFsdWUsICR0aGlzLT5rZXl3b3JkcykgfHwgKAogICAgICAgICAgICAgICAgJHRoaXMtPnN0cmljdE1vZGUgJiYKICAgICAgICAgICAgICAgIGluX2FycmF5KCR0b2tlbi0+dmFsdWUsICR0aGlzLT5zdHJpY3RNb2RlS2V5d29yZHMpKSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzY2FubmVyIHN0YXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXRlKCkKICAgIHsKICAgICAgICAvL0NvbnN1bWUgY3VycmVudCBhbmQgbmV4dCB0b2tlbnMgc28gdGhhdCB0aGV5IHdvbnQnIGJlIHBhcnNlZCBhZ2FpbgogICAgICAgIC8vaWYgdGhlIHN0YXRlIGlzIHJlc3RvcmVkLiBJZiB0aGUgY3VycmVudCB0b2tlbiBpcyBhIHNsYXNoIHRoZSBuZXh0CiAgICAgICAgLy90b2tlbiBpc24ndCBwYXJzZWQsIHRoaXMgcHJldmVudHMgc29tZSBlZGdlIGNhc2VzIHdoZXJlIGEgcmVnZXhwCiAgICAgICAgLy90aGF0IGNvbnRhaW5zIHNvbWV0aGluZyB0aGF0IGNhbiBiZSBpbnRlcnByZXRlZCBhcyBhIGNvbW1lbnQgY2F1c2VzCiAgICAgICAgLy90aGUgY29udGVudCB0byBiZSBwYXJzZWQgYXMgYSByZWFsIGNvbW1lbnQgdG9vCiAgICAgICAgJHRva2VuID0gJHRoaXMtPmN1cnJlbnRUb2tlbiA/OiAkdGhpcy0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoJHRva2VuICYmICR0b2tlbi0+dmFsdWUgIT09ICIvIikgewogICAgICAgICAgICAkdGhpcy0+Z2V0TmV4dFRva2VuKCk7CiAgICAgICAgfQogICAgICAgICRzdGF0ZSA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnN0YXRlUHJvcHMgYXMgJHByb3ApIHsKICAgICAgICAgICAgJHN0YXRlWyRwcm9wXSA9ICR0aGlzLT4kcHJvcDsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5yZWdpc3RlclRva2VucykgewogICAgICAgICAgICAkc3RhdGVbInRva2Vuc051bSJdID0gY291bnQoJHRoaXMtPnRva2Vucyk7CiAgICAgICAgfQogICAgICAgIC8vRW1pdCB0aGUgRnJlZXplU3RhdGUgZXZlbnQgYW5kIHBhc3MgdGhlIGdpdmVuIHN0YXRlIHNvIHRoYXQgbGlzdGVuZXJzCiAgICAgICAgLy9hdHRhY2hlZCB0byB0aGlzIGV2ZW50IGNhbiBhZGQgZGF0YQogICAgICAgICR0aGlzLT5ldmVudHNFbWl0dGVyICYmICR0aGlzLT5ldmVudHNFbWl0dGVyLT5maXJlKAogICAgICAgICAgICAiRnJlZXplU3RhdGUiLCBhcnJheSgmJHN0YXRlKQogICAgICAgICk7CiAgICAgICAgcmV0dXJuICRzdGF0ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHNjYW5uZXIgc3RhdGUKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICRzdGF0ZSBTdGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGF0ZSgkc3RhdGUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5yZWdpc3RlclRva2VucykgewogICAgICAgICAgICAvL0NoZWNrIGlmIHRva2VucyBoYXZlIGJlZW4gYWRkZWQKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT50b2tlbnNbJHN0YXRlWyJ0b2tlbnNOdW0iXV0pKSB7CiAgICAgICAgICAgICAgICAvL1JlbW92ZSBhbGwgYWRkZWQgdG9rZW5zCiAgICAgICAgICAgICAgICBmb3IgKCRpID0gY291bnQoJHRoaXMtPnRva2VucykgLSAxOyAkaSA+PSAkc3RhdGVbInRva2Vuc051bSJdOyAkaS0tKSB7CiAgICAgICAgICAgICAgICAgICAgYXJyYXlfcG9wKCR0aGlzLT50b2tlbnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCRzdGF0ZVsidG9rZW5zTnVtIl0pOwogICAgICAgIH0KICAgICAgICAvL0VtaXQgdGhlIFJlc2V0U3RhdGUgZXZlbnQgYW5kIHBhc3MgdGhlIGdpdmVuIHN0YXRlCiAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICJSZXNldFN0YXRlIiwgYXJyYXkoJiRzdGF0ZSkKICAgICAgICApOwogICAgICAgIGZvcmVhY2ggKCRzdGF0ZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAkdGhpcy0+JGtleSA9ICR2YWx1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgY3VycmVudCBzY2FubmVyIHN0YXRlCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRzY2FuUG9zaXRpb24gQnkgZGVmYXVsdCB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBzY2FubmVyCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN1bWVkIHBvc2l0aW9uLCBpZiB0aGlzIHBhcmFtZXRlciBpcyB0cnVlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBzY2FubmVkIHBvc2l0aW9uIHdpbGwgYmUgcmV0dXJuZWQKICAgICAqIAogICAgICogQHJldHVybiBQb3NpdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UG9zaXRpb24oJHNjYW5Qb3NpdGlvbiA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkc2NhblBvc2l0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUG9zaXRpb24oJHRoaXMtPmxpbmUsICR0aGlzLT5jb2x1bW4sICR0aGlzLT5pbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wb3NpdGlvbjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY3VycmVudCBzY2FuIHBvc2l0aW9uIGF0IHRoZSBnaXZlbiBvbmUKICAgICAqIAogICAgICogQHBhcmFtIFBvc2l0aW9uICRwb3NpdGlvbiBQb3NpdGlvbiBhdCB3aGljaCB0aGUgc2NhbiBwb3NpdGlvbiB3aWxsIGJlIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTY2FuUG9zaXRpb24oUG9zaXRpb24gJHBvc2l0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+bGluZSA9ICRwb3NpdGlvbi0+Z2V0TGluZSgpOwogICAgICAgICR0aGlzLT5jb2x1bW4gPSAkcG9zaXRpb24tPmdldENvbHVtbigpOwogICAgICAgICR0aGlzLT5pbmRleCA9ICRwb3NpdGlvbi0+Z2V0SW5kZXgoKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIGdpdmVuIGluZGV4IGluIHRoZSBzb3VyY2UgY29kZSBvciBudWxsIGlmIHRoZQogICAgICogZW5kIGlzIHJlYWNoZWQuCiAgICAgKiAKICAgICAqIEBwYXJhbSBpbnQgJGluZGV4IEluZGV4LCBpZiBub3QgZ2l2ZW4gaXQgd2lsbCB1c2UgdGhlIGN1cnJlbnQgaW5kZXgKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hhckF0KCRpbmRleCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRpbmRleCA9PT0gbnVsbCkgewogICAgICAgICAgICAkaW5kZXggPSAkdGhpcy0+aW5kZXg7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkaW5kZXggPCAkdGhpcy0+bGVuZ3RoID8gJHRoaXMtPnNvdXJjZVskaW5kZXhdIDogbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUaHJvd3MgYSBzeW50YXggZXJyb3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBFcnJvciBtZXNzYWdlCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICogCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXJyb3IoJG1lc3NhZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICghJG1lc3NhZ2UpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAiVW5leHBlY3RlZCAiIC4gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCRtZXNzYWdlLCAkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBjdXJyZW50IHRva2VuCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbnN1bWVUb2tlbigpCiAgICB7CiAgICAgICAgLy9Nb3ZlIHRoZSBzY2FubmVyIHBvc2l0aW9uIHRvIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgcG9zaXRpb24KICAgICAgICAkdGhpcy0+cG9zaXRpb24gPSAkdGhpcy0+Y3VycmVudFRva2VuLT5sb2NhdGlvbi0+ZW5kOwogICAgICAgIAogICAgICAgIC8vQmVmb3JlIGNvbnN1bWUgdGhlIHRva2VuLCBjb25zdW1lIGNvbW1lbnRzIGFzc29jaWF0ZWQgd2l0aCBpdAogICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVDb21tZW50c0ZvckN1cnJlbnRUb2tlbigpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1JlZ2lzdGVyIHRoZSB0b2tlbiBpZiByZXF1aXJlZAogICAgICAgIGlmICgkdGhpcy0+cmVnaXN0ZXJUb2tlbnMpIHsKICAgICAgICAgICAgJHRoaXMtPnRva2Vuc1tdID0gJHRoaXMtPmN1cnJlbnRUb2tlbjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBUb2tlbkNvbnN1bWVkIGV2ZW50IGZvciB0aGUgY29uc3VtZWQgdG9rZW4KICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgIlRva2VuQ29uc3VtZWQiLCBhcnJheSgkdGhpcy0+Y3VycmVudFRva2VuKQogICAgICAgICk7CiAgICAgICAgCiAgICAgICAgJHRoaXMtPmN1cnJlbnRUb2tlbiA9ICR0aGlzLT5uZXh0VG9rZW47CiAgICAgICAgJHRoaXMtPm5leHRUb2tlbiA9IG51bGw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gc3RyaW5nIGlzIG1hdGNoZWQsIGlmIHNvIGl0IGNvbnN1bWVzIHRoZSB0b2tlbgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRleHBlY3RlZCBTdHJpbmcgdG8gY2hlY2sKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb25zdW1lKCRleHBlY3RlZCkKICAgIHsKICAgICAgICAvL0RvIG5vdCBjYWxsIGdldFRva2VuIGlmIHRoZXJlJ3MgYWxyZWFkeSBhIHBlbmRpbmcgdG9rZW4gZm9yCiAgICAgICAgLy9wZXJmb3JtYW5jZSByZWFzb25zCiAgICAgICAgJHRva2VuID0gJHRoaXMtPmN1cnJlbnRUb2tlbiA/OiAkdGhpcy0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoJHRva2VuICYmICR0b2tlbi0+dmFsdWUgPT09ICRleHBlY3RlZCkgewogICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiAkdG9rZW47CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBvbmUgb2YgdGhlIGdpdmVuIHN0cmluZ3MgaXMgbWF0Y2hlZCwgaWYgc28gaXQgY29uc3VtZXMgdGhlCiAgICAgKiB0b2tlbgogICAgICogCiAgICAgKiBAcGFyYW0gYXJyYXkgJGV4cGVjdGVkIFN0cmluZ3MgdG8gY2hlY2sKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb25zdW1lT25lT2YoJGV4cGVjdGVkKQogICAgewogICAgICAgIC8vRG8gbm90IGNhbGwgZ2V0VG9rZW4gaWYgdGhlcmUncyBhbHJlYWR5IGEgcGVuZGluZyB0b2tlbiBmb3IKICAgICAgICAvL3BlcmZvcm1hbmNlIHJlYXNvbnMKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+Y3VycmVudFRva2VuID86ICR0aGlzLT5nZXRUb2tlbigpOwogICAgICAgIGlmICgkdG9rZW4gJiYgaW5fYXJyYXkoJHRva2VuLT52YWx1ZSwgJGV4cGVjdGVkKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiAkdG9rZW47CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyB0aGF0IHRoZXJlIGFyZSBub3QgbGluZSB0ZXJtaW5hdG9ycyBmb2xsb3dpbmcgdGhlIGN1cnJlbnQgc2NhbgogICAgICogcG9zaXRpb24gYmVmb3JlIG5leHQgdG9rZW4KICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJG5leHRUb2tlbiBCeSBkZWZhdWx0IGl0IGNoZWNrcyB0aGUgY3VycmVudCB0b2tlbiBwb3NpdGlvbgogICAgICogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiwgaWYgdGhpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaXMgdHJ1ZSB0aGUgY2hlY2sgd2lsbCBiZSBkb25lIHJlbGF0aXZlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIHRoZSBuZXh0IHRva2VuCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm9MaW5lVGVybWluYXRvcnMoJG5leHRUb2tlbiA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkbmV4dFRva2VuKSB7CiAgICAgICAgICAgICRuZXh0VG9rZW4gPSAkdGhpcy0+Z2V0TmV4dFRva2VuKCk7CiAgICAgICAgICAgICRyZWZMaW5lID0gISRuZXh0VG9rZW4gPyBudWxsIDoKICAgICAgICAgICAgICAgICAgICAgICAgJG5leHRUb2tlbi0+bG9jYXRpb24tPmVuZC0+Z2V0TGluZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZWZMaW5lID0gJHRoaXMtPmdldFBvc2l0aW9uKCktPmdldExpbmUoKTsKICAgICAgICB9CiAgICAgICAgJHRva2VuID0gJHRoaXMtPmN1cnJlbnRUb2tlbiA/OiAkdGhpcy0+Z2V0VG9rZW4oKTsKICAgICAgICByZXR1cm4gJHRva2VuICYmCiAgICAgICAgICAgICAgICR0b2tlbi0+bG9jYXRpb24tPnN0YXJ0LT5nZXRMaW5lKCkgPT09ICRyZWZMaW5lOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBvbmUgb2YgdGhlIGdpdmVuIHN0cmluZ3MgZm9sbG93cyB0aGUgY3VycmVudCBzY2FuIHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGV4cGVjdGVkICBTdHJpbmcgb3IgYXJyYXkgb2Ygc3RyaW5ncyB0byBjaGVjawogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkbmV4dFRva2VuIFRoaXMgcGFyYW1ldGVyIG11c3QgYmUgdHJ1ZSBpZiB0aGUgZmlyc3QKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaXMgYW4gYXJyYXkgc28gdGhhdCBpdCB3aWxsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2sgYWxzbyBuZXh0IHRva2VucwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQmVmb3JlKCRleHBlY3RlZCwgJG5leHRUb2tlbiA9IGZhbHNlKQogICAgewogICAgICAgICR0b2tlbiA9ICR0aGlzLT5jdXJyZW50VG9rZW4gPzogJHRoaXMtPmdldFRva2VuKCk7CiAgICAgICAgaWYgKCEkdG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkdG9rZW4tPnZhbHVlLCAkZXhwZWN0ZWQpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gZWxzZWlmICghJG5leHRUb2tlbikgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghJHRoaXMtPmdldE5leHRUb2tlbigpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJGV4cGVjdGVkIGFzICR2YWwpIHsKICAgICAgICAgICAgaWYgKCFpc19hcnJheSgkdmFsKSB8fCAkdmFsWzBdICE9PSAkdG9rZW4tPnZhbHVlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0lmIHRoZSBzZWNvbmQgdmFsdWUgaW4gdGhlIGFycmF5IGlzIHRydWUgY2hlY2sgdGhhdCB0aGUgY3VycmVudAogICAgICAgICAgICAvL3Rva2VuIGlzIG5vdCBmb2xsb3dlZCBieSBsaW5lIHRlcm1pbmF0b3JzLCBvdGhlcndpc2UgY29tcGFyZSBpdHMKICAgICAgICAgICAgLy92YWx1ZSB0byB0aGUgbmV4dCB0b2tlbgogICAgICAgICAgICBpZiAoKCR2YWxbMV0gPT09IHRydWUgJiYgJHRoaXMtPm5vTGluZVRlcm1pbmF0b3JzKHRydWUpKSB8fAogICAgICAgICAgICAgICAgKCR2YWxbMV0gIT09IHRydWUgJiYgJHZhbFsxXSA9PT0gJHRoaXMtPm5leHRUb2tlbi0+dmFsdWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbgogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5leHRUb2tlbigpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+bmV4dFRva2VuKSB7CiAgICAgICAgICAgICR0b2tlbiA9ICR0aGlzLT5jdXJyZW50VG9rZW4gPzogJHRoaXMtPmdldFRva2VuKCk7CiAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSBudWxsOwogICAgICAgICAgICAkdGhpcy0+bmV4dFRva2VuID0gJHRoaXMtPmdldFRva2VuKHRydWUpOwogICAgICAgICAgICAkdGhpcy0+Y3VycmVudFRva2VuID0gJHRva2VuOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPm5leHRUb2tlbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHRva2VuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHNraXBFT0ZDaGVja3MgIFRydWUgdG8gc2tpcCBlbmQgb2YgZmlsZSBjaGVja3MKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVuIGlmIHRoZSBlbmQgaXMgcmVhY2hlZAogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRva2VuKCRza2lwRU9GQ2hlY2tzID0gZmFsc2UpCiAgICB7CiAgICAgICAgLy9UaGUgY3VycmVudCB0b2tlbiBpcyByZXR1cm5lZCB1bnRpbCBjb25zdW1lZAogICAgICAgIGlmICgkdGhpcy0+Y3VycmVudFRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y3VycmVudFRva2VuOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkY29tbWVudHMgPSAkdGhpcy0+c2tpcFdoaXRlc3BhY2VzQW5kQ29tbWVudHMoKTsKICAgICAgICAKICAgICAgICAvL0VtaXQgdGhlIFRva2VuQ3JlYXRlZCBldmVudCBmb3IgYWxsIHRoZSBjb21tZW50cyBmb3VuZAogICAgICAgIGlmICgkY29tbWVudHMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbW1lbnRzIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgICAgICAgICAiVG9rZW5DcmVhdGVkIiwgYXJyYXkoJGNvbW1lbnQpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1doZW4gdGhlIGVuZCBvZiB0aGUgc291cmNlIGlzIHJlYWNoZWQKICAgICAgICBpZiAoJHRoaXMtPmluZGV4ID49ICR0aGlzLT5sZW5ndGgpIHsKICAgICAgICAgICAgLy9DaGVjayBpZiB0aGVyZSBhcmUgb3BlbiBicmFja2V0cwogICAgICAgICAgICBpZiAoISRza2lwRU9GQ2hlY2tzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+b3BlbkJyYWNrZXRzIGFzICRicmFja2V0ID0+ICRudW0pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJG51bSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoIlVuY2xvc2VkICRicmFja2V0Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vQ2hlY2sgaWYgdGhlcmUgYXJlIG9wZW4gdGVtcGxhdGVzCiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHRoaXMtPm9wZW5UZW1wbGF0ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCJVbnRlcm1pbmF0ZWQgdGVtcGxhdGUiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy9SZWdpc3RlciBjb21tZW50cyBhbmQgY29uc3VtZSB0aGVtCiAgICAgICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMgJiYgJGNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29tbWVudHNGb3JDdXJyZW50VG9rZW4oJGNvbW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy9FbWl0IHRoZSBFbmRSZWFjaGVkIGV2ZW50IHdoZW4gYXQgdGhlIGVuZCBvZiB0aGUgc291cmNlCiAgICAgICAgICAgICR0aGlzLT5ldmVudHNFbWl0dGVyICYmICR0aGlzLT5ldmVudHNFbWl0dGVyLT5maXJlKAogICAgICAgICAgICAgICAgIkVuZFJlYWNoZWQiCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHN0YXJ0UG9zaXRpb24gPSAkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSk7CiAgICAgICAgJG9yaWdFeGNlcHRpb24gPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL1RyeSB0byBtYXRjaCBhIHRva2VuCiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICgkdGhpcy0+anN4ICYmICgkdG9rZW4gPSAkdGhpcy0+c2NhbkpTWElkZW50aWZpZXIoKSkpIHx8CiAgICAgICAgICAgICAgICAoJHRva2VuID0gJHRoaXMtPnNjYW5UZW1wbGF0ZSgpKSB8fAogICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5zY2FuTnVtYmVyKCkpIHx8CiAgICAgICAgICAgICAgICAoJHRoaXMtPmpzeCAmJiAoJHRva2VuID0gJHRoaXMtPnNjYW5KU1hQdW5jdHVhdG9yKCkpKSB8fAogICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5zY2FuUHVuY3R1YXRvcigpKSB8fAogICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5zY2FuS2V5d29yZE9ySWRlbnRpZmllcigpKSB8fAogICAgICAgICAgICAgICAgKCR0aGlzLT5qc3ggJiYgKCR0b2tlbiA9ICR0aGlzLT5zY2FuSlNYU3RyaW5nKCkpKSB8fAogICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5zY2FuU3RyaW5nKCkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgLy9TZXQgdGhlIHRva2VuIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zCiAgICAgICAgICAgICAgICAkdG9rZW4tPmxvY2F0aW9uLT5zdGFydCA9ICRzdGFydFBvc2l0aW9uOwogICAgICAgICAgICAgICAgJHRva2VuLT5sb2NhdGlvbi0+ZW5kID0gJHRoaXMtPmdldFBvc2l0aW9uKHRydWUpOwogICAgICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUb2tlbiA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vUmVnaXN0ZXIgY29tbWVudHMgaWYgcmVxdWlyZWQKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMgJiYgJGNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzRm9yQ3VycmVudFRva2VuKCRjb21tZW50cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vRW1pdCB0aGUgVG9rZW5DcmVhdGVkIGV2ZW50IGZvciB0aGUgdG9rZW4ganVzdCBjcmVhdGVkCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgICAgICAgICAiVG9rZW5DcmVhdGVkIiwgYXJyYXkoJHRoaXMtPmN1cnJlbnRUb2tlbikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y3VycmVudFRva2VuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkb3JpZ0V4Y2VwdGlvbiA9ICRlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0lmIGxhc3QgdG9rZW4gd2FzICIvIiBkbyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHRva2VuIGhhcyBub3QgYmUKICAgICAgICAvL3JlY29nbml6ZWQgc2luY2UgaXQgY2FuIGJlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gYSByZWdleHAgYW5kIGl0IHdpbGwKICAgICAgICAvL2JlIGNvbnN1bWVkIHdoZW4gdGhlIGN1cnJlbnQgdG9rZW4gd2lsbCBiZSByZWNvbnN1bWVkIGFzIGEgcmVnZXhwCiAgICAgICAgaWYgKCR0aGlzLT5pc0FmdGVyU2xhc2goJHN0YXJ0UG9zaXRpb24pKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRTY2FuUG9zaXRpb24oJHN0YXJ0UG9zaXRpb24pOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9ObyB2YWxpZCB0b2tlbiBmb3VuZC4gSWYgdGhlcmUgd2FzIGEgc2NhbiBlcnJvciwgdGhyb3cgdGhlIHNhbWUKICAgICAgICAvL2V4Y2VwdGlvbiBhZ2Fpbiwgb3RoZXJ3aXNlIHRocm93IGEgbmV3IGVycm9yCiAgICAgICAgaWYgKCRvcmlnRXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHRocm93ICRvcmlnRXhjZXB0aW9uOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB0aGUgb3BlcmF0aW9ucyB0byBoYW5kbGUgdGhlIGVuZCBvZiB0aGUgc291cmNlIHNjYW5uaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbnN1bWVFbmQoKQogICAgewogICAgICAgIC8vQ29uc3VtZSBmaW5hbCBjb21tZW50cwogICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVDb21tZW50c0ZvckN1cnJlbnRUb2tlbigpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0VtaXQgdGhlIEVuZFJlYWNoZWQgZXZlbnQgd2hlbiBhdCB0aGUgZW5kIG9mIHRoZSBzb3VyY2UKICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgIkVuZFJlYWNoZWQiCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogR2V0cyBvciBzZXRzIGNvbW1lbnRzIGZvciB0aGUgY3VycmVudCB0b2tlbi4gSWYgdGhlIHBhcmFtZXRlciBpcyBhbgogICAgICogYXJyYXkgaXQgYXNzb2NpYXRlcyB0aGUgZ2l2ZW4gY29tbWVudHMgYXJyYXkgdG8gdGhlIGN1cnJlbnQgbm9kZSwKICAgICAqIG90aGVyd2lzZSBjb21tZW50cyBmb3IgdGhlIGN1cnJlbnQgdG9rZW4gYXJlIHJldHVybmVkCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheSAkY29tbWVudHMgIENvbW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbW1lbnRzRm9yQ3VycmVudFRva2VuKCRjb21tZW50cyA9IG51bGwpCiAgICB7CiAgICAgICAgJGlkID0gJHRoaXMtPmN1cnJlbnRUb2tlbiA/IHNwbF9vYmplY3RfaGFzaCgkdGhpcy0+Y3VycmVudFRva2VuKSA6ICIiOwogICAgICAgIGlmICgkY29tbWVudHMgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzTWFwWyRpZF0gPSAkY29tbWVudHM7CiAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCR0aGlzLT5jb21tZW50c01hcFskaWRdKSkgewogICAgICAgICAgICAkY29tbWVudHMgPSAkdGhpcy0+Y29tbWVudHNNYXBbJGlkXTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbW1lbnRzTWFwWyRpZF0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGNvbW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIGNvbW1lbnQgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3VycmVudCB0b2tlbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lQ29tbWVudHNGb3JDdXJyZW50VG9rZW4oKQogICAgewogICAgICAgICRjb21tZW50cyA9ICR0aGlzLT5jb21tZW50c0ZvckN1cnJlbnRUb2tlbigpOwogICAgICAgIGlmICgkY29tbWVudHMgJiYgKCR0aGlzLT5yZWdpc3RlclRva2VucyB8fCAkdGhpcy0+ZXZlbnRzRW1pdHRlcikpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbW1lbnRzIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAvL1JlZ2lzdGVyIHRoZSB0b2tlbiBpZiByZXF1aXJlZAogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5yZWdpc3RlclRva2VucykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT50b2tlbnNbXSA9ICRjb21tZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9FbWl0IHRoZSBUb2tlbkNvbnN1bWVkIGV2ZW50IGZvciB0aGUgY29tbWVudAogICAgICAgICAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICAgICAgICAgIlRva2VuQ29uc3VtZWQiLCBhcnJheSgkY29tbWVudCkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgY29uc3VtZWQgb3IgdGhlIHNjYW5uZWQgcG9zaXRpb24gZm9sbG93IGEgc2xhc2guCiAgICAgKiAKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAkcG9zaXRpb24gIEFkZGl0aW9uYWwgcG9zaXRpb24gdG8gY2hlY2sKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc0FmdGVyU2xhc2goJHBvc2l0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkY29uc3VtZWRJbmRleCA9ICR0aGlzLT5nZXRQb3NpdGlvbigpLT5nZXRJbmRleCgpOwogICAgICAgICRjaGVja0luZGljZXMgPSBhcnJheSgkY29uc3VtZWRJbmRleCwgJGNvbnN1bWVkSW5kZXggKyAxKTsKICAgICAgICBpZiAoJHBvc2l0aW9uKSB7CiAgICAgICAgICAgICRjaGVja0luZGljZXNbXSA9ICRwb3NpdGlvbi0+Z2V0SW5kZXgoKSAtIDE7CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRjaGVja0luZGljZXMgYXMgJGkpIHsKICAgICAgICAgICAgaWYgKCRpID49IDAgJiYgJHRoaXMtPmNoYXJBdCgkaSkgPT09ICIvIikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRyaWVzIHRvIHJlY29uc3VtZSB0aGUgY3VycmVudCB0b2tlbiBhcyBhIHJlZ2V4cCBpZiBwb3NzaWJsZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlY29uc3VtZUN1cnJlbnRUb2tlbkFzUmVnZXhwKCkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+Y3VycmVudFRva2VuID86ICR0aGlzLT5nZXRUb2tlbigpOwogICAgICAgICR2YWx1ZSA9ICR0b2tlbiA/ICR0b2tlbi0+dmFsdWUgOiBudWxsOwogICAgICAgIAogICAgICAgIC8vQ2hlY2sgaWYgdGhlIHRva2VuIHN0YXJ0cyB3aXRoICIvIgogICAgICAgIGlmICghJHZhbHVlIHx8ICR2YWx1ZVswXSAhPT0gIi8iKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1Jlc2V0IHRoZSBzY2FubmVyIHBvc2l0aW9uIHRvIHRoZSB0b2tlbidzIHN0YXJ0IHBvc2l0aW9uCiAgICAgICAgJHN0YXJ0UG9zaXRpb24gPSAkdG9rZW4tPmxvY2F0aW9uLT5zdGFydDsKICAgICAgICAkdGhpcy0+c2V0U2NhblBvc2l0aW9uKCRzdGFydFBvc2l0aW9uKTsKICAgICAgICAKICAgICAgICAkYnVmZmVyID0gIi8iOwogICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAkaW5DbGFzcyA9IGZhbHNlOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIC8vSW4gYSBjaGFyYWN0ZXJzIGNsYXNzIHRoZSBkZWxpbWl0ZXIgIi8iIGlzIGFsbG93ZWQgd2l0aG91dCBlc2NhcGUsCiAgICAgICAgICAgIC8vc28gdGhlIGNoYXJhY3RlcnMgY2xhc3MgbXVzdCBiZSBjbG9zZWQgYmVmb3JlIGNsb3NpbmcgdGhlIHJlZ2V4cAogICAgICAgICAgICAkc3RvcHMgPSAkaW5DbGFzcyA/IGFycmF5KCJdIikgOiBhcnJheSgiLyIsICJbIik7CiAgICAgICAgICAgICR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVVbnRpbCgkc3RvcHMpOwogICAgICAgICAgICBpZiAoJHRlbXBCdWZmZXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmICgkaW5DbGFzcykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIlVudGVybWluYXRlZCBjaGFyYWN0ZXIgY2xhc3MgaW4gcmVnZXhwIgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigiVW50ZXJtaW5hdGVkIHJlZ2V4cCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXJbMF07CiAgICAgICAgICAgIGlmICgkdGVtcEJ1ZmZlclsxXSA9PT0gIi8iKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpbkNsYXNzID0gJHRlbXBCdWZmZXJbMV0gPT09ICJbIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0ZsYWdzCiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5jaGFyQXQoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgJGxvd2VyID0gc3RydG9sb3dlcigkY2hhcik7CiAgICAgICAgICAgIGlmICgkbG93ZXIgPj0gImEiICYmICRsb3dlciA8PSAieiIpIHsKICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vSWYgbmV4dCB0b2tlbiBoYXMgYWxyZWFkeSBiZWVuIHBhcnNlZCBhbmQgaXQncyBhIGJyYWNrZXQgZXhjbHVkZSBpdAogICAgICAgIC8vZnJvbSB0aGUgY291bnQgb2Ygb3BlbiBicmFja2V0cwogICAgICAgIGlmICgkdGhpcy0+bmV4dFRva2VuKSB7CiAgICAgICAgICAgICRuZXh0VmFsID0gJHRoaXMtPm5leHRUb2tlbi0+dmFsdWU7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+YnJhY2tldHNbJG5leHRWYWxdKSAmJgogICAgICAgICAgICAgICAgaXNzZXQoJHRoaXMtPm9wZW5CcmFja2V0c1skbmV4dFZhbF0pCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5icmFja2V0c1skbmV4dFZhbF0pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3BlbkJyYWNrZXRzWyRuZXh0VmFsXSsrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3BlbkJyYWNrZXRzWyRuZXh0VmFsXS0tOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5uZXh0VG9rZW4gPSBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0lmIGNvbW1lbnRzIGhhbmRsaW5nIGlzIGVuYWJsZWQsIGdldCB0aGUgY29tbWVudHMgYXNzb2NpYXRlZCB3aXRoIHRoZQogICAgICAgIC8vY3VycmVudCB0b2tlbgogICAgICAgICRjb21tZW50cyA9ICR0aGlzLT5jb21tZW50cyA/ICR0aGlzLT5jb21tZW50c0ZvckN1cnJlbnRUb2tlbigpIDogbnVsbDsKICAgICAgICAgICAgCiAgICAgICAgLy9SZXBsYWNlIHRoZSBjdXJyZW50IHRva2VuIHdpdGggYSByZWdleHAgdG9rZW4KICAgICAgICAkdG9rZW4gPSBuZXcgVG9rZW4oVG9rZW46OlRZUEVfUkVHVUxBUl9FWFBSRVNTSU9OLCAkYnVmZmVyKTsKICAgICAgICAkdG9rZW4tPmxvY2F0aW9uLT5zdGFydCA9ICRzdGFydFBvc2l0aW9uOwogICAgICAgICR0b2tlbi0+bG9jYXRpb24tPmVuZCA9ICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKTsKICAgICAgICAkdGhpcy0+Y3VycmVudFRva2VuID0gJHRva2VuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICBpZiAoJGNvbW1lbnRzKSB7CiAgICAgICAgICAgIC8vQXR0YWNoIHRoZSBjb21tZW50cyB0byB0aGUgbmV3IGN1cnJlbnQgdG9rZW4KICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzRm9yQ3VycmVudFRva2VuKCRjb21tZW50cyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiAkdGhpcy0+Y3VycmVudFRva2VuOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNraXBzIHdoaXRlc3BhY2VzIGFuZCBjb21tZW50cyBmcm9tIHRoZSBjdXJyZW50IHNjYW4gcG9zaXRpb24uIElmCiAgICAgKiBjb21tZW50cyBoYW5kbGluZyBpcyBlbmFibGVkLCB0aGUgYXJyYXkgb2YgcGFyc2VkIGNvbW1lbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNraXBXaGl0ZXNwYWNlc0FuZENvbW1lbnRzKCkKICAgIHsKICAgICAgICAkY29tbWVudHMgPSBbXTsKICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICRzZWNTdGFydElkeCA9ICR0aGlzLT5pbmRleDsKICAgICAgICB3aGlsZSAoKCRjaGFyID0gJHRoaXMtPmNoYXJBdCgpKSAhPT0gbnVsbCkgewogICAgICAgICAgICAvL1doaXRlc3BhY2UKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRjaGFyLCAkdGhpcy0+d2hpdGVzcGFjZXMpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRjb250ZW50IC49ICRjaGFyOwogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfSBlbHNlaWYgKCRjaGFyID09PSAiLyIpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy9Db21tZW50CiAgICAgICAgICAgICAgICAkbmV4dENoYXIgPSAkdGhpcy0+Y2hhckF0KCR0aGlzLT5pbmRleCArIDEpOwogICAgICAgICAgICAgICAgaWYgKCRuZXh0Q2hhciA9PT0gIi8iIHx8ICRuZXh0Q2hhciA9PT0gIioiKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy9JZiBjb21tZW50cyBtdXN0IGJlIGhhbmRsZWQsIGVtcHR5IHRoZSBjdXJyZW50IGNvbnRlbnQgdG9vCiAgICAgICAgICAgICAgICAgICAgLy9hbmQgZ2V0IHRoZSBjb21tZW50IHN0YXJ0IHBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRlbnQgIT09ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRqdXN0Q29sdW1uQW5kTGluZSgkY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRzdGFydCA9ICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJGlubGluZSA9ICRuZXh0Q2hhciA9PT0gIi8iOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAyOwogICAgICAgICAgICAgICAgICAgICRjb250ZW50IC49ICRjaGFyIC4gJG5leHRDaGFyOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGFyID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRpbmxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0lmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBoYXMgYmVlbiByZWFjaGVkIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYSBtdWx0aWxpbmUgY29tbWVudCBpcyBzdGlsbCBvcGVuLCBpdCdzIGFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9lcnJvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigiVW50ZXJtaW5hdGVkIGNvbW1lbnQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpc0VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlzRW5kID0gJGlubGluZSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0lubGluZSBjb21tZW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbl9hcnJheSgkY2hhciwgJHRoaXMtPmxpbmVUZXJtaW5hdG9ycykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9NdWx0aWxpbmUgY29tbWVudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNoYXIgPT09ICIqIiAmJiAkdGhpcy0+Y2hhckF0KCkgPT09ICIvIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpc0VuZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkaW5saW5lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgLj0gIi8iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vRm9yIGlubGluZSBjb21tZW50cyB0aGUgY2xvc2luZyBsaW5lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90ZXJtaW5hdG9yIG11c3QgYmUgZXhjbHVkZWQgZnJvbSBjb21tZW50IHRleHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlubGluZSAmJiAkY2hhciAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgtLTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSBzdWJzdHIoJGNvbnRlbnQsIDAsIC1zdHJsZW4oJGNoYXIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkanVzdENvbHVtbkFuZExpbmUoJGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbiA9IG5ldyBUb2tlbihUb2tlbjo6VFlQRV9DT01NRU5ULCAkY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuLT5sb2NhdGlvbi0+c3RhcnQgPSAkc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuLT5sb2NhdGlvbi0+ZW5kID0gJHRoaXMtPmdldFBvc2l0aW9uKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb21tZW50c1tdID0gJHRva2VuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vRm9yIGlubGluZSBjb21tZW50cyB0aGUgbmV3IGNvbnRlbnQgY29udGFpbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoZSBjbG9zaW5nIGxpbmUgdGVybWluYXRvciBzaW5jZSB0aGUgY2hhciBoYXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FscmVhZHkgYmVlbiBwcm9jZXNzZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaW5saW5lICYmICRjaGFyICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50ID0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5pc01vZHVsZSAmJiAkY2hhciA9PT0gIjwiICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hhckF0KCR0aGlzLT5pbmRleCArIDEpID09PSAiISIgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5jaGFyQXQoJHRoaXMtPmluZGV4ICsgMikgPT09ICItIiAmJgogICAgICAgICAgICAgICAgJHRoaXMtPmNoYXJBdCgkdGhpcy0+aW5kZXggKyAzKSA9PT0gIi0iCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvL0lmIGNvbW1lbnRzIG11c3QgYmUgaGFuZGxlZCwgZW1wdHkgdGhlIGN1cnJlbnQgY29udGVudCB0b28KICAgICAgICAgICAgICAgIC8vYW5kIGdldCB0aGUgY29tbWVudCBzdGFydCBwb3NpdGlvbgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cykgewogICAgICAgICAgICAgICAgICAgIGlmICgkY29udGVudCAhPT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkanVzdENvbHVtbkFuZExpbmUoJGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkc3RhcnQgPSAkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vT3BlbiBodG1sIGNvbW1lbnQKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSA0OwogICAgICAgICAgICAgICAgJGNvbnRlbnQgLj0gIjwhLS0iOwogICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlzRW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICRpc0VuZCA9IGluX2FycmF5KCRjaGFyLCAkdGhpcy0+bGluZVRlcm1pbmF0b3JzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpc0VuZCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1JlbW92ZSB0aGUgY2xvc2luZyBsaW5lIHRlcm1pbmF0b3IgZnJvbSB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29tbWVudCB0ZXh0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNoYXIgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgtLTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9IHN1YnN0cigkY29udGVudCwgMCwgLXN0cmxlbigkY2hhcikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkanVzdENvbHVtbkFuZExpbmUoJGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuID0gbmV3IFRva2VuKFRva2VuOjpUWVBFX0NPTU1FTlQsICRjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbi0+bG9jYXRpb24tPnN0YXJ0ID0gJHN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuLT5sb2NhdGlvbi0+ZW5kID0gJHRoaXMtPmdldFBvc2l0aW9uKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbW1lbnRzW10gPSAkdG9rZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGFyICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+aXNNb2R1bGUgJiYgJGNoYXIgPT09ICItIiAmJgogICAgICAgICAgICAgICAgJHRoaXMtPmNoYXJBdCgkdGhpcy0+aW5kZXggKyAxKSA9PT0gIi0iICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hhckF0KCR0aGlzLT5pbmRleCArIDIpID09PSAiPiIKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vQ2xvc2UgaHRtbCBjb21tZW50CiAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIGl0IGlzIG9uIGl0J3Mgb3duIGxpbmUKICAgICAgICAgICAgICAgICRhbGxvdyA9IGZhbHNlOwogICAgICAgICAgICAgICAgaWYgKCEkc2VjU3RhcnRJZHgpIHsKICAgICAgICAgICAgICAgICAgICAkYWxsb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKCRpbmRleCA9ICR0aGlzLT5pbmRleCAtIDE7ICRpbmRleCA+PSAkc2VjU3RhcnRJZHg7ICRpbmRleC0tKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkdGhpcy0+Y2hhckF0KCRpbmRleCksICR0aGlzLT5saW5lVGVybWluYXRvcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYWxsb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGFsbG93KSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy9JZiBjb21tZW50cyBtdXN0IGJlIGhhbmRsZWQsIGVtcHR5IHRoZSBjdXJyZW50IGNvbnRlbnQgdG9vCiAgICAgICAgICAgICAgICAgICAgLy9hbmQgZ2V0IHRoZSBjb21tZW50IHN0YXJ0IHBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRlbnQgIT09ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRqdXN0Q29sdW1uQW5kTGluZSgkY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRzdGFydCA9ICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDM7CiAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgLj0gIi0tPiI7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpc0VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlzRW5kID0gaW5fYXJyYXkoJGNoYXIsICR0aGlzLT5saW5lVGVybWluYXRvcnMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlzRW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgdGhlIGNsb3NpbmcgbGluZSB0ZXJtaW5hdG9yIGZyb20gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jb21tZW50IHRleHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNoYXIgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4LS07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50ID0gc3Vic3RyKCRjb250ZW50LCAwLCAtc3RybGVuKCRjaGFyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGp1c3RDb2x1bW5BbmRMaW5lKCRjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW4gPSBuZXcgVG9rZW4oVG9rZW46OlRZUEVfQ09NTUVOVCwgJGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbi0+bG9jYXRpb24tPnN0YXJ0ID0gJHN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbi0+bG9jYXRpb24tPmVuZCA9ICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29tbWVudHNbXSA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY2hhciAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICRjaGFyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICgkY29udGVudCAhPT0gIiIpIHsKICAgICAgICAgICAgJHRoaXMtPmFkanVzdENvbHVtbkFuZExpbmUoJGNvbnRlbnQpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJGNvbW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFN0cmluZyBzY2FubmluZyBtZXRob2QKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGhhbmRsZUVzY2FwZSBUcnVlIHRvIGhhbmRsZSBlc2NhcGluZwogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNjYW5TdHJpbmcoJGhhbmRsZUVzY2FwZSA9IHRydWUpCiAgICB7CiAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgaWYgKCRjaGFyID09PSAiJyIgfHwgJGNoYXIgPT09ICciJykgewogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAvL0FkZCB0aGUgcXVvdGUgdG8gdGhlIExTTSBhbmQgdGhlbiByZW1vdmUgaXQgYWZ0ZXIgY29uc3VtaW5nCiAgICAgICAgICAgICR0aGlzLT5zdHJpbmdzU3RvcHNMU00tPmFkZCgkY2hhcik7CiAgICAgICAgICAgICRidWZmZXIgPSAkdGhpcy0+Y29uc3VtZVVudGlsKCR0aGlzLT5zdHJpbmdzU3RvcHNMU00sICRoYW5kbGVFc2NhcGUpOwogICAgICAgICAgICAkdGhpcy0+c3RyaW5nc1N0b3BzTFNNLT5yZW1vdmUoJGNoYXIpOwogICAgICAgICAgICBpZiAoJGJ1ZmZlciA9PT0gbnVsbCB8fCAkYnVmZmVyWzFdICE9PSAkY2hhcikgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCJVbnRlcm1pbmF0ZWQgc3RyaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBUb2tlbihUb2tlbjo6VFlQRV9TVFJJTkdfTElURVJBTCwgJGNoYXIgLiAkYnVmZmVyWzBdKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGVtcGxhdGUgc2Nhbm5pbmcgbWV0aG9kCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2NhblRlbXBsYXRlKCkKICAgIHsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAKICAgICAgICAvL0dldCB0aGUgY3VycmVudCBudW1iZXIgb2Ygb3BlbiBjdXJseSBicmFja2V0cwogICAgICAgICRvcGVuQ3VybHkgPSBpc3NldCgkdGhpcy0+b3BlbkJyYWNrZXRzWyJ7Il0pID8KICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZW5CcmFja2V0c1sieyJdIDoKICAgICAgICAgICAgICAgICAgICAgMDsKICAgICAgICAKICAgICAgICAvL0lmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjdXJseSBicmFja2V0IGNoZWNrIGFuZCB0aGUgbnVtYmVyIG9mIG9wZW4KICAgICAgICAvL2N1cmx5IGJyYWNrZXRzIG1hdGNoZXMgdGhlIGxhc3QgbnVtYmVyIGluIHRoZSBvcGVuIHRlbXBsYXRlcyBzdGFjaywKICAgICAgICAvL3RoZW4gdGhlIGJyYWNrZXQgY2xvc2VzIHRoZSBvcGVuIHRlbXBsYXRlIGV4cHJlc3Npb24KICAgICAgICAkZW5kRXhwcmVzc2lvbiA9IGZhbHNlOwogICAgICAgIGlmICgkY2hhciA9PT0gIn0iKSB7CiAgICAgICAgICAgICRsZW4gPSBjb3VudCgkdGhpcy0+b3BlblRlbXBsYXRlcyk7CiAgICAgICAgICAgIGlmICgkbGVuICYmICR0aGlzLT5vcGVuVGVtcGxhdGVzWyRsZW4gLSAxXSA9PT0gJG9wZW5DdXJseSkgewogICAgICAgICAgICAgICAgJGVuZEV4cHJlc3Npb24gPSB0cnVlOwogICAgICAgICAgICAgICAgYXJyYXlfcG9wKCR0aGlzLT5vcGVuVGVtcGxhdGVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoJGNoYXIgPT09ICJgIiB8fCAkZW5kRXhwcmVzc2lvbikgewogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkYnVmZmVyID0gJGNoYXI7CiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICAkdGVtcEJ1ZmZlciA9ICR0aGlzLT5jb25zdW1lVW50aWwoYXJyYXkoImAiLCAiJCIpKTsKICAgICAgICAgICAgICAgIGlmICghJHRlbXBCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoIlVudGVybWluYXRlZCB0ZW1wbGF0ZSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkdGVtcEJ1ZmZlclswXTsKICAgICAgICAgICAgICAgIGlmICgkdGVtcEJ1ZmZlclsxXSAhPT0gIiQiIHx8ICR0aGlzLT5jaGFyQXQoKSA9PT0gInsiKSB7CiAgICAgICAgICAgICAgICAgICAgLy9JZiAiJHsiIGlzIGZvdW5kIGl0J3MgYSBuZXcgdGVtcGxhdGUgZXhwcmVzc2lvbiwgcmVnaXN0ZXIKICAgICAgICAgICAgICAgICAgICAvL3RoZSBjdXJyZW50IG51bWJlciBvZiBvcGVuIGN1cmx5IGJyYWNrZXRzIGluIHRoZSBvcGVuCiAgICAgICAgICAgICAgICAgICAgLy90ZW1wbGF0ZXMgc3RhY2sKICAgICAgICAgICAgICAgICAgICBpZiAoJHRlbXBCdWZmZXJbMV0gPT09ICIkIikgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICJ7IjsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZW5UZW1wbGF0ZXNbXSA9ICRvcGVuQ3VybHk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfVEVNUExBVEUsICRidWZmZXIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBOdW1iZXIgc2Nhbm5pbmcgbWV0aG9kCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2Nhbk51bWJlcigpCiAgICB7CiAgICAgICAgLy9OdW1iZXJzIGNhbiBzdGFydCB3aXRoIGEgZGVjaW1hbCBudW1iZXIgb3Igd2l0aCBhIGRvdCAoLjUpCiAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgaWYgKCEoKCRjaGFyID49ICIwIiAmJiAkY2hhciA8PSAiOSIpIHx8ICRjaGFyID09PSAiLiIpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGJ1ZmZlciA9ICIiOwogICAgICAgICRhbGxvd2VkRGVjaW1hbHMgPSB0cnVlOwogICAgICAgIAogICAgICAgIC8vUGFyc2UgdGhlIGludGVnZXIgcGFydAogICAgICAgIGlmICgkY2hhciAhPT0gIi4iKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0NvbnN1bWUgYWxsIGRlY2ltYWwgbnVtYmVycwogICAgICAgICAgICAkYnVmZmVyID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCk7CiAgICAgICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+YmlnSW50ICYmICRjaGFyID09PSAibiIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUb2tlbihUb2tlbjo6VFlQRV9CSUdJTlRfTElURVJBTCwgJGJ1ZmZlciAuICRjaGFyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJGxvd2VyID0gJGNoYXIgIT09IG51bGwgPyBzdHJ0b2xvd2VyKCRjaGFyKSA6IG51bGw7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0hhbmRsZSBoZXhhZGVjaW1hbCAoMHgpLCBvY3RhbCAoMG8pIGFuZCBiaW5hcnkgKDBiKSBmb3JtcwogICAgICAgICAgICBpZiAoJGJ1ZmZlciA9PT0gIjAiICYmICRsb3dlciAhPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgaXNzZXQoJHRoaXMtPnskbG93ZXIgLiAibnVtYmVycyJ9KQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgICAgICAkdGVtcEJ1ZmZlciA9ICR0aGlzLT5jb25zdW1lTnVtYmVycygkbG93ZXIpOwogICAgICAgICAgICAgICAgaWYgKCR0ZW1wQnVmZmVyID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCJNaXNzaW5nIG51bWJlcnMgYWZ0ZXIgMCRjaGFyIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyIC4gJHRlbXBCdWZmZXI7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vQ2hlY2sgdGhhdCB0aGVyZSBhcmUgbm90IG51bWJlcnMgbGVmdAogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb25zdW1lTnVtYmVycygpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+YmlnSW50ICYmICR0aGlzLT5jaGFyQXQoKSA9PT0gIm4iKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfQklHSU5UX0xJVEVSQUwsICRidWZmZXIgLiAkY2hhcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfTlVNRVJJQ19MSVRFUkFMLCAkYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy9Db25zdW1lIGV4cG9uZW50IHBhcnQgaWYgcHJlc2VudAogICAgICAgICAgICBpZiAoJHRlbXBCdWZmZXIgPSAkdGhpcy0+Y29uc3VtZUV4cG9uZW50UGFydCgpKSB7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICR0ZW1wQnVmZmVyOwogICAgICAgICAgICAgICAgJGFsbG93ZWREZWNpbWFscyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vUGFyc2UgdGhlIGRlY2ltYWwgcGFydAogICAgICAgIGlmICgkYWxsb3dlZERlY2ltYWxzICYmICR0aGlzLT5jaGFyQXQoKSA9PT0gIi4iKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0NvbnN1bWUgdGhlIGRvdAogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkYnVmZmVyIC49ICIuIjsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ29uc3VtZSBhbGwgZGVjaW1hbCBudW1iZXJzCiAgICAgICAgICAgICR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCk7CiAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXI7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0lmIHRoZSBidWZmZXIgY29udGFpbnMgb25seSB0aGUgZG90IGl0IHNob3VsZCBiZSBwYXJzZWQgYXMKICAgICAgICAgICAgLy9wdW5jdHVhdG9yCiAgICAgICAgICAgIGlmICgkYnVmZmVyID09PSAiLiIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleC0tOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbi0tOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ29uc3VtZSBleHBvbmVudCBwYXJ0IGlmIHByZXNlbnQKICAgICAgICAgICAgaWYgKCgkdGVtcEJ1ZmZlciA9ICR0aGlzLT5jb25zdW1lRXhwb25lbnRQYXJ0KCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICR0ZW1wQnVmZmVyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfTlVNRVJJQ19MSVRFUkFMLCAkYnVmZmVyKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDb25zdW1lcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgZGlnaXRzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgRGlnaXRzIHR5cGUgKGRlY2ltYWwsIGhleGFkZWNpbWFsLCBldGMuLi4pCiAgICAgKiBAcGFyYW0gaW50ICAgICRtYXggIE1heGltdW0gbnVtYmVyIG9mIGRpZ2l0cyB0byBtYXRjaAogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lTnVtYmVycygkdHlwZSA9ICIiLCAkbWF4ID0gbnVsbCkKICAgIHsKICAgICAgICAkYnVmZmVyID0gIiI7CiAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgJGNvdW50ID0gMDsKICAgICAgICAkZXh0cmEgPSAkdGhpcy0+ZmVhdHVyZXMtPm51bWVyaWNMaXRlcmFsU2VwYXJhdG9yID8gIl8iIDogIiI7CiAgICAgICAgd2hpbGUgKAogICAgICAgICAgICBpbl9hcnJheSgkY2hhciwgJHRoaXMtPnskdHlwZSAuICJudW1iZXJzIn0pIHx8CiAgICAgICAgICAgICgkY291bnQgJiYgJGNoYXIgPT09ICRleHRyYSkKICAgICAgICApIHsKICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgJGNvdW50ICsrOwogICAgICAgICAgICBpZiAoJGNvdW50ID09PSAkbWF4KSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRjb3VudCAmJiBzdWJzdHIoJGJ1ZmZlciwgLTEpID09PSAiXyIpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgIk51bWVyaWMgc2VwYXJhdG9ycyBhcmUgbm90IGFsbG93ZWQgYXQgdGhlIGVuZCBvZiBhIG51bWJlciIKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjb3VudCA/ICRidWZmZXIgOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBleHBvbmVudCBwYXJ0IG9mIGEgbnVtYmVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVFeHBvbmVudFBhcnQoKQogICAgewogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICBpZiAoJGNoYXIgIT09IG51bGwgJiYgc3RydG9sb3dlcigkY2hhcikgPT09ICJlIikgewogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAgICAgaWYgKCRjaGFyID09PSAiKyIgfHwgJGNoYXIgPT09ICItIikgewogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCk7CiAgICAgICAgICAgIGlmICgkdGVtcEJ1ZmZlciA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCJNaXNzaW5nIGV4cG9uZW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGJ1ZmZlciAuPSAkdGVtcEJ1ZmZlcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRidWZmZXI7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUHVuY3R1YXRvciBzY2FubmluZyBtZXRob2QKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzY2FuUHVuY3R1YXRvcigpCiAgICB7CiAgICAgICAgJHRva2VuID0gbnVsbDsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAKICAgICAgICAvL0NoZWNrIGlmIHRoZSBuZXh0IGNoYXIgaXMgYSBicmFja2V0CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5icmFja2V0c1skY2hhcl0pKSB7CiAgICAgICAgICAgIC8vQ2hlY2sgaWYgaXQgaXMgYSBjbG9zaW5nIGJyYWNrZXQKICAgICAgICAgICAgaWYgKCR0aGlzLT5icmFja2V0c1skY2hhcl0pIHsKICAgICAgICAgICAgICAgICRvcGVuQnJhY2tldCA9ICR0aGlzLT5icmFja2V0c1skY2hhcl07CiAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZyBvcGVuIGJyYWNrZXQKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPm9wZW5CcmFja2V0c1skb3BlbkJyYWNrZXRdKSB8fAogICAgICAgICAgICAgICAgICAgICEkdGhpcy0+b3BlbkJyYWNrZXRzWyRvcGVuQnJhY2tldF0KICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlzQWZ0ZXJTbGFzaCgkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZW5CcmFja2V0c1skb3BlbkJyYWNrZXRdLS07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5vcGVuQnJhY2tldHNbJGNoYXJdKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vcGVuQnJhY2tldHNbJGNoYXJdID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5vcGVuQnJhY2tldHNbJGNoYXJdKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgJHRva2VuID0gbmV3IFRva2VuKFRva2VuOjpUWVBFX1BVTkNUVUFUT1IsICRjaGFyKTsKICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgIC8vVHJ5IHRvIG1hdGNoIHRoZSBsb25nZXN0IHB1bmN0dWF0b3IKICAgICAgICAgICAgJG1hdGNoID0gJHRoaXMtPnB1bmN0dWF0b3JzTFNNLT5tYXRjaCgkdGhpcywgJHRoaXMtPmluZGV4LCAkY2hhcikKICAgICAgICApIHsKICAgICAgICAgICAgLy9PcHRpb25hbCBjaGFpbmluZyBwdW5jdHVhdG9yIGNhbm5vdCBhcHBlYXIgYmVmb3JlIGEgbnVtYmVyLCBpbiB0aGlzCiAgICAgICAgICAgIC8vY2FzZSBvbmx5IHRoZSBxdWVzdGlvbiBtYXJrIG11c3QgYmUgY29uc3VtZWQKICAgICAgICAgICAgaWYgKCRtYXRjaFsxXSA9PT0gIj8uIiAmJgogICAgICAgICAgICAgICAgKCRuZXh0Q2hhciA9ICR0aGlzLT5jaGFyQXQoJHRoaXMtPmluZGV4ICsgJG1hdGNoWzBdKSkgIT09IG51bGwgJiYKICAgICAgICAgICAgICAgICRuZXh0Q2hhciA+PSAiMCIgJiYgJG5leHRDaGFyIDw9ICI5IgogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRtYXRjaCA9IGFycmF5KDEsICI/Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9ICRtYXRjaFswXTsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbiArPSAkbWF0Y2hbMF07CiAgICAgICAgICAgICR0b2tlbiA9IG5ldyBUb2tlbihUb2tlbjo6VFlQRV9QVU5DVFVBVE9SLCAkbWF0Y2hbMV0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRva2VuOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEtleXdvcmRzIGFuZCBpZGVudGlmaWVycyBzY2FubmluZyBtZXRob2QKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzY2FuS2V5d29yZE9ySWRlbnRpZmllcigpCiAgICB7CiAgICAgICAgLy9DaGVjayBwcml2YXRlIGlkZW50aWZpZXIgc3RhcnQgY2hhcmFjdGVyCiAgICAgICAgaWYgKCRwcml2YXRlID0gJHRoaXMtPmZlYXR1cmVzLT5wcml2YXRlTWV0aG9kc0FuZEZpZWxkcyAmJiAkdGhpcy0+Y2hhckF0KCkgPT09ICIjIikgewogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgIH0KCiAgICAgICAgLy9Db25zdW1lIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgYXJlIHVuaWNvZGUgZXNjYXBlCiAgICAgICAgLy9zZXF1ZW5jZXMgb3IgdmFsaWQgaWRlbnRpZmllciBzdGFydHMgKG9ubHkgdGhlIGZpcnN0IGNoYXJhY3Rlcikgb3IKICAgICAgICAvL3BhcnRzCiAgICAgICAgJGJ1ZmZlciA9ICIiOwogICAgICAgICRzdGFydCA9IHRydWU7CiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5jaGFyQXQoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgKCRjaGFyID49ICJhIiAmJiAkY2hhciA8PSAieiIpIHx8CiAgICAgICAgICAgICAgICAoJGNoYXIgPj0gIkEiICYmICRjaGFyIDw9ICJaIikgfHwKICAgICAgICAgICAgICAgICRjaGFyID09PSAiXyIgfHwgJGNoYXIgPT09ICIkIiB8fAogICAgICAgICAgICAgICAgKCEkc3RhcnQgJiYgJGNoYXIgPj0gIjAiICYmICRjaGFyIDw9ICI5IikgfHwKICAgICAgICAgICAgICAgICR0aGlzLT5pc0lkZW50aWZpZXJDaGFyKCRjaGFyLCAkc3RhcnQpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICB9IGVsc2VpZiAoJGNoYXIgPT09ICJcXCIgJiYgKCRzZXEgPSAkdGhpcy0+Y29uc3VtZVVuaWNvZGVFc2NhcGVTZXF1ZW5jZSgpKSkgewogICAgICAgICAgICAgICAgLy9WZXJpZnkgdGhhdCBpdCdzIGEgdmFsaWQgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pc0lkZW50aWZpZXJDaGFyKCRzZXFbMV0sICRzdGFydCkpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJHNlcVswXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRzdGFydCA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0lkZW50aWZ5IHRva2VuIHR5cGUKICAgICAgICBpZiAoJGJ1ZmZlciA9PT0gIiIpIHsKICAgICAgICAgICAgLy9VbmNvbnN1bWUgdGhlIGhhc2ggaWYgbm90aGluZyB3YXMgZm91bmQgYWZ0ZXIgdGhhdAogICAgICAgICAgICBpZiAoJHByaXZhdGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleC0tOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbi0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0gZWxzZWlmICgkcHJpdmF0ZSkgewogICAgICAgICAgICAkdHlwZSA9IFRva2VuOjpUWVBFX1BSSVZBVEVfSURFTlRJRklFUjsKICAgICAgICAgICAgJGJ1ZmZlciA9ICIjIiAuICRidWZmZXI7CiAgICAgICAgfSBlbHNlaWYgKCRidWZmZXIgPT09ICJudWxsIikgewogICAgICAgICAgICAkdHlwZSA9IFRva2VuOjpUWVBFX05VTExfTElURVJBTDsKICAgICAgICB9IGVsc2VpZiAoJGJ1ZmZlciA9PT0gInRydWUiIHx8ICRidWZmZXIgPT09ICJmYWxzZSIpIHsKICAgICAgICAgICAgJHR5cGUgPSBUb2tlbjo6VFlQRV9CT09MRUFOX0xJVEVSQUw7CiAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCRidWZmZXIsICR0aGlzLT5rZXl3b3JkcykgfHwKICAgICAgICAgICAgaW5fYXJyYXkoJGJ1ZmZlciwgJHRoaXMtPnN0cmljdE1vZGVLZXl3b3JkcykKICAgICAgICApIHsKICAgICAgICAgICAgJHR5cGUgPSBUb2tlbjo6VFlQRV9LRVlXT1JEOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0eXBlID0gVG9rZW46OlRZUEVfSURFTlRJRklFUjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIG5ldyBUb2tlbigkdHlwZSwgJGJ1ZmZlcik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29uc3VtZXMgYW4gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UKICAgICAqIAogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lVW5pY29kZUVzY2FwZVNlcXVlbmNlKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNoYXJBdCgpICE9PSAiXFwiIHx8CiAgICAgICAgICAgICR0aGlzLT5jaGFyQXQoJHRoaXMtPmluZGV4ICsgMSkgIT09ICJ1IgogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHN0YXJ0SW5kZXggPSAkdGhpcy0+aW5kZXg7CiAgICAgICAgJHN0YXJ0Q29sdW1uID0gJHRoaXMtPmNvbHVtbjsKICAgICAgICAkdGhpcy0+aW5kZXggKz0gMjsKICAgICAgICAkdGhpcy0+Y29sdW1uICs9IDI7CiAgICAgICAgJGJyYWNrZXRzID0gZmFsc2U7CiAgICAgICAgaWYgKCR0aGlzLT5jaGFyQXQoKSA9PT0gInsiKSB7CiAgICAgICAgICAgIC8vXHV7RkZGfQogICAgICAgICAgICAkYnJhY2tldHMgPSB0cnVlOwogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkY29kZSA9ICR0aGlzLT5jb25zdW1lTnVtYmVycygieCIpOwogICAgICAgICAgICBpZiAoJGNvZGUgJiYgJHRoaXMtPmNoYXJBdCgpICE9PSAifSIpIHsKICAgICAgICAgICAgICAgICRjb2RlID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9cdUZGRkYKICAgICAgICAgICAgJGNvZGUgPSAkdGhpcy0+Y29uc3VtZU51bWJlcnMoIngiLCA0KTsKICAgICAgICAgICAgaWYgKCRjb2RlICYmIHN0cmxlbigkY29kZSkgIT09IDQpIHsKICAgICAgICAgICAgICAgICRjb2RlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1VuY29uc3VtZSBldmVyeXRoaW5nIGlmIHRoZSBmb3JtYXQgaXMgaW52YWxpZAogICAgICAgIGlmICgkY29kZSA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+aW5kZXggPSAkc3RhcnRJbmRleDsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbiA9ICRzdGFydENvbHVtbjsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vUmV0dXJuIGFuIGFycmF5IHdoZXJlIHRoZSBmaXJzdCBlbGVtZW50IGlzIHRoZSBtYXRjaGVkIHNlcXVlbmNlCiAgICAgICAgLy9hbmQgdGhlIHNlY29uZCBvbmUgaXMgdGhlIGRlY29kZWQgY2hhcmFjdGVyCiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAkYnJhY2tldHMgPyAiXFx1eyIgLiAkY29kZSAuICJ9IiA6ICJcXHUiIC4gJGNvZGUsCiAgICAgICAgICAgIFV0aWxzOjp1bmljb2RlVG9VdGY4KGhleGRlYygkY29kZSkpCiAgICAgICAgKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcyB2YWxpZCBmb3IgYW4gaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyICBDaGFyYWN0ZXIgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBib29sICAgJHN0YXJ0IElmIHRydWUgaXQgd2lsbCBjaGVjayB0aGF0IHRoZSBjaGFyYWN0ZXIgaXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgIHZhbGlkIHRvIHN0YXJ0IGFuIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc0lkZW50aWZpZXJDaGFyKCRjaGFyLCAkc3RhcnQgPSB0cnVlKQogICAgewogICAgICAgIHJldHVybiAoJGNoYXIgPj0gImEiICYmICRjaGFyIDw9ICJ6IikgfHwKICAgICAgICAgICAgICAgKCRjaGFyID49ICJBIiAmJiAkY2hhciA8PSAiWiIpIHx8CiAgICAgICAgICAgICAgICRjaGFyID09PSAiXyIgfHwgJGNoYXIgPT09ICIkIiB8fAogICAgICAgICAgICAgICAoISRzdGFydCAmJiAkY2hhciA+PSAiMCIgJiYgJGNoYXIgPD0gIjkiKSB8fAogICAgICAgICAgICAgICBwcmVnX21hdGNoKCRzdGFydCA/ICR0aGlzLT5pZFN0YXJ0UmVnZXggOiAkdGhpcy0+aWRQYXJ0UmVnZXgsICRjaGFyKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBJbmNyZWFzZXMgY29sdW1ucyBhbmQgbGluZXMgY291bnQgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBzdHJpbmcKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkYnVmZmVyIFN0cmluZyB0byBhbmFseXplCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYWRqdXN0Q29sdW1uQW5kTGluZSgkYnVmZmVyKQogICAgewogICAgICAgICRsaW5lcyA9IHByZWdfc3BsaXQoJHRoaXMtPmxpbmVzU3BsaXR0ZXIsICRidWZmZXIpOwogICAgICAgICRsaW5lc0NvdW50ID0gY291bnQoJGxpbmVzKSAtIDE7CiAgICAgICAgJHRoaXMtPmxpbmUgKz0gJGxpbmVzQ291bnQ7CiAgICAgICAgJGNvbHVtbnMgPSBtYl9zdHJsZW4oJGxpbmVzWyRsaW5lc0NvdW50XSwgIlVURi04Iik7CiAgICAgICAgaWYgKCRsaW5lc0NvdW50KSB7CiAgICAgICAgICAgICR0aGlzLT5jb2x1bW4gPSAkY29sdW1uczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Y29sdW1uICs9ICRjb2x1bW5zOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDb25zdW1lcyBjaGFyYWN0ZXJzIHVudGlsIG9uZSBvZiB0aGUgZ2l2ZW4gY2hhcmFjdGVycyBpcyBmb3VuZAogICAgICogCiAgICAgKiBAcGFyYW0gYXJyYXl8TFNNICRzdG9wcyAgICAgICAgICBDaGFyYWN0ZXJzIHRvIHNlYXJjaAogICAgICogQHBhcmFtIGJvb2wgICAgICAkaGFuZGxlRXNjYXBlICAgVHJ1ZSB0byBoYW5kbGUgZXNjYXBpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgJGNvbGxlY3RTdG9wICAgIFRydWUgdG8gaW5jbHVkZSB0aGUgc3RvcCBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lVW50aWwoCiAgICAgICAgJHN0b3BzLCAkaGFuZGxlRXNjYXBlID0gdHJ1ZSwgJGNvbGxlY3RTdG9wID0gdHJ1ZQogICAgKSB7CiAgICAgICAgJGlzTFNNID0gJHN0b3BzIGluc3RhbmNlb2YgTFNNOwogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICAkZXNjYXBlZCA9IGZhbHNlOwogICAgICAgIHdoaWxlICgoJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICRpbmNySW5kZXggPSAxOwogICAgICAgICAgICAkaXNTdG9wID0gZmFsc2U7CiAgICAgICAgICAgIGlmICgkaXNMU00pIHsKICAgICAgICAgICAgICAgICRtID0gJHN0b3BzLT5tYXRjaCgkdGhpcywgJHRoaXMtPmluZGV4LCAkY2hhcik7CiAgICAgICAgICAgICAgICBpZiAoJG0pIHsKICAgICAgICAgICAgICAgICAgICAkaXNTdG9wID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAkaW5jckluZGV4ID0gJG1bMF07CiAgICAgICAgICAgICAgICAgICAgJGNoYXIgPSAkbVsxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpc1N0b3AgPSBpbl9hcnJheSgkY2hhciwgJHN0b3BzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdmFsaWRTdG9wID0gJGlzU3RvcCAmJiAhJGVzY2FwZWQ7CiAgICAgICAgICAgIGlmICghJHZhbGlkU3RvcCB8fCAkY29sbGVjdFN0b3ApIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAkaW5jckluZGV4OwogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHZhbGlkU3RvcCkgewogICAgICAgICAgICAgICAgaWYgKCEkY29sbGVjdFN0b3AgJiYgJGJ1ZmZlciA9PT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5hZGp1c3RDb2x1bW5BbmRMaW5lKCRidWZmZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRidWZmZXIsICRjaGFyKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCEkZXNjYXBlZCAmJiAkY2hhciA9PT0gIlxcIiAmJiAkaGFuZGxlRXNjYXBlKSB7CiAgICAgICAgICAgICAgICAkZXNjYXBlZCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZXNjYXBlZCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDIyOwoKLyoqCiAqIEVTMjAyMiBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDIxXEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogUHJpdmF0ZSBtZXRob2RzIGFuZCBmaWVsZHMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRwcml2YXRlTWV0aG9kc0FuZEZpZWxkcyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBDbGFzcyBmaWVsZHMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRjbGFzc0ZpZWxkcyA9IHRydWU7CgogICAgLyoqCiAgICAgKiAiaW4iIG9wZXJhdG9yIGZvciBwcml2YXRlIGZpZWxkcwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGNsYXNzRmllbGRzUHJpdmF0ZUluID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIFRvcCBsZXZlbCBhd2FpdAogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHRvcExldmVsQXdhaXQgPSB0cnVlOwoKICAgIC8qKgogICAgICogQ2xhc3Mgc3RhdGljIGJsb2NrCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkY2xhc3NTdGF0aWNCbG9jayA9IHRydWU7CgogICAgLyoqCiAgICAgKiBBcmJpdHJhcnkgbW9kdWxlIG5hbWVzcGFjZSBpZGVudGlmaWVyIG5hbWVzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkYXJiaXRyYXJ5TW9kdWxlTlNOYW1lcyA9IHRydWU7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxFUzIwMTU7CgovKioKICogRVMyMDE1IGZlYXR1cmVzIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICovCmNsYXNzIEZlYXR1cmVzIGV4dGVuZHMgXFBlYXN0XFN5bnRheFxGZWF0dXJlcwp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBwYXJzZXJzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIFBhcnNlckFic3RyYWN0CnsKICAgIC8qKgogICAgICogQXNzb2NpYXRlZCBzY2FubmVyCiAgICAgKiAKICAgICAqIEB2YXIgU2Nhbm5lciAKICAgICAqLwogICAgcHJvdGVjdGVkICRzY2FubmVyOwoKICAgIC8qKgogICAgICogUGFyc2VyIGZlYXR1cmVzCiAgICAgKiAKICAgICAqIEB2YXIgRmVhdHVyZXMKICAgICAqLwogICAgcHJvdGVjdGVkICRmZWF0dXJlczsKICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXIgY29udGV4dAogICAgICogCiAgICAgKiBAdmFyIFxzdGRDbGFzcwogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnRleHQ7CiAgICAKICAgIC8qKgogICAgICogU291cmNlIHR5cGUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlVHlwZTsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyBoYW5kbGluZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbW1lbnRzOwogICAgCiAgICAvKioKICAgICAqIEpTWCBzeW50YXggaGFuZGxpbmcKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRqc3g7CiAgICAKICAgIC8qKgogICAgICogRXZlbnRzIGVtaXR0ZXIKICAgICAqCiAgICAgKiBAdmFyIEV2ZW50c0VtaXR0ZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRldmVudHNFbWl0dGVyOwoKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgICRzb3VyY2UgICBTb3VyY2UgY29kZQogICAgICogQHBhcmFtIEZlYXR1cmVzICRmZWF0dXJlcyBQYXJzZXIgZmVhdHVyZXMKICAgICAqIEBwYXJhbSBhcnJheSAgICAkb3B0aW9ucyAgUGFyc2luZyBvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgKICAgICAgICAkc291cmNlLCBGZWF0dXJlcyAkZmVhdHVyZXMsICRvcHRpb25zID0gYXJyYXkoKQogICAgKSB7CiAgICAgICAgJHRoaXMtPmZlYXR1cmVzID0gJGZlYXR1cmVzOwogICAgICAgIAogICAgICAgICR0aGlzLT5zb3VyY2VUeXBlID0gaXNzZXQoJG9wdGlvbnNbInNvdXJjZVR5cGUiXSkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG9wdGlvbnNbInNvdXJjZVR5cGUiXSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcUGVhc3RcUGVhc3Q6OlNPVVJDRV9UWVBFX1NDUklQVDsKICAgICAgICAKICAgICAgICAvL0NyZWF0ZSB0aGUgc2Nhbm5lcgogICAgICAgICR0aGlzLT5zY2FubmVyID0gbmV3IFNjYW5uZXIoJHNvdXJjZSwgJGZlYXR1cmVzLCAkb3B0aW9ucyk7CiAgICAgICAgCiAgICAgICAgLy9FbmFibGUgbW9kdWxlIHNjYW5uaW5nIGlmIHJlcXVpcmVkCiAgICAgICAgaWYgKCR0aGlzLT5zb3VyY2VUeXBlID09PSBcUGVhc3RcUGVhc3Q6OlNPVVJDRV9UWVBFX01PRFVMRSkgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+ZW5hYmxlTW9kdWxlTW9kZSgpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0VuYWJsZSBjb21tZW50cyBzY2FubmluZwogICAgICAgICR0aGlzLT5jb21tZW50cyA9IGlzc2V0KCRvcHRpb25zWyJjb21tZW50cyJdKSAmJiAkb3B0aW9uc1siY29tbWVudHMiXTsKICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5lbmFibGVDb21tZW50cygpOwogICAgICAgICAgICAvL0NyZWF0ZSB0aGUgY29tbWVudHMgcmVnaXN0cnkKICAgICAgICAgICAgbmV3IENvbW1lbnRzUmVnaXN0cnkoJHRoaXMpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBFbmFibGUganN4IHN5bnRheCBpZiByZXF1aXJlZAogICAgICAgICR0aGlzLT5qc3ggPSBpc3NldCgkb3B0aW9uc1sianN4Il0pICYmICRvcHRpb25zWyJqc3giXTsKICAgICAgICAKICAgICAgICAkdGhpcy0+aW5pdENvbnRleHQoKTsKICAgICAgICAkdGhpcy0+cG9zdEluaXQoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBwYXJzZXIgY29udGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRDb250ZXh0KCk7CiAgICAKICAgIC8qKgogICAgICogUG9zdCBpbml0aWFsaXplIG9wZXJhdGlvbnMKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBwb3N0SW5pdCgpOwogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgc291cmNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlCiAgICAgKiAKICAgICAqIEBhYnN0cmFjdAogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gcGFyc2UoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHBhcnNlZCB0b2tlbnMgZnJvbSB0aGUgc291cmNlIGNvZGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbltdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0b2tlbml6ZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmVuYWJsZVRva2VuUmVnaXN0cmF0aW9uKCk7CiAgICAgICAgJHRoaXMtPnBhcnNlKCk7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbnMoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzY2FubmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGFyc2VyCiAgICAgKiAKICAgICAqIEByZXR1cm4gU2Nhbm5lcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2Nhbm5lcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zY2FubmVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhcnNlciBmZWF0dXJlcyBjbGFzcwogICAgICogCiAgICAgKiBAcmV0dXJuIEZlYXR1cmVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGZWF0dXJlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mZWF0dXJlczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYXJzZXIncyBldmVudHMgZW1pdHRlcgogICAgICogCiAgICAgKiBAcmV0dXJuIEV2ZW50c0VtaXR0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV2ZW50c0VtaXR0ZXIoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmV2ZW50c0VtaXR0ZXIpIHsKICAgICAgICAgICAgLy9UaGUgZXZlbnQgZW1pdHRlciBpcyBjcmVhdGVkIGhlcmUgc28gdGhhdCBpdCB3b24ndCBleGlzdCBpZiBub3QKICAgICAgICAgICAgLy9uZWNlc3NhcnkKICAgICAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgPSBuZXcgRXZlbnRzRW1pdHRlcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5ldmVudHNFbWl0dGVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENhbGxzIGEgbWV0aG9kIHdpdGggYW4gaXNvbGF0ZWQgcGFyc2VyIGNvbnRleHQsIGFwcGx5aW5nIHRoZSBnaXZlbiBmbGFncywKICAgICAqIGJ1dCByZXN0b3JpbmcgdGhlaXIgdmFsdWVzIGFmdGVyIHRoZSBleGVjdXRpb24uCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICAkZmxhZ3MgIEtleS92YWx1ZSBhcnJheSBvZiBjaGFuZ2VzIHRvIGFwcGx5IHRvIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCBmbGFncy4gSWYgaXQncyBudWxsIG9yIHRoZSBmaXJzdAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCBvZiB0aGUgYXJyYXkgaXMgbnVsbCB0aGUgY29udGV4dCB3aWxsCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSByZXNldCBiZWZvcmUgYXBwbHlpbmcgbmV3IHZhbHVlcy4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkZm4gICAgIE1ldGhvZCB0byBjYWxsCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAgJGFyZ3MgICBNZXRob2QgYXJndW1lbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzb2xhdGVDb250ZXh0KCRmbGFncywgJGZuLCAkYXJncyA9IG51bGwpCiAgICB7CiAgICAgICAgLy9TdG9yZSB0aGUgY3VycmVudCBjb250ZXh0CiAgICAgICAgJG9sZENvbnRleHQgPSBjbG9uZSAkdGhpcy0+Y29udGV4dDsKICAgICAgICAKICAgICAgICAvL0lmIGZsYWcgYXJndW1lbnQgaXMgbnVsbCByZXNldCB0aGUgY29udGV4dAogICAgICAgIGlmICgkZmxhZ3MgPT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPmluaXRDb250ZXh0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9BcHBseSBuZXcgdmFsdWVzIHRvIHRoZSBmbGFncwogICAgICAgICAgICBmb3JlYWNoICgkZmxhZ3MgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgICAgIC8vIElmIG51bGwgcmVzZXQgdGhlIGNvbnRleHQKICAgICAgICAgICAgICAgIGlmICgkdiA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbml0Q29udGV4dCgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29udGV4dC0+JGsgPSAkdjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0NhbGwgdGhlIG1ldGhvZCB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMKICAgICAgICAkcmV0ID0gJGFyZ3MgPyBjYWxsX3VzZXJfZnVuY19hcnJheShhcnJheSgkdGhpcywgJGZuKSwgJGFyZ3MpIDogJHRoaXMtPiRmbigpOwogICAgICAgIAogICAgICAgIC8vUmVzdG9yZSBwcmV2aW91cyBjb250ZXh0CiAgICAgICAgJHRoaXMtPmNvbnRleHQgPSAkb2xkQ29udGV4dDsKICAgICAgICAKICAgICAgICByZXR1cm4gJHJldDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRub2RlVHlwZSBOb2RlJ3MgdHlwZQogICAgICogQHBhcmFtIG1peGVkICAkcG9zaXRpb24gTm9kZSdzIHN0YXJ0IHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZU5vZGUoJG5vZGVUeXBlLCAkcG9zaXRpb24pCiAgICB7CiAgICAgICAgLy9Vc2UgdGhlIHJpZ2h0IGNsYXNzIHRvIGdldCBhbiBpbnN0YW5jZSBvZiB0aGUgbm9kZQogICAgICAgICRub2RlQ2xhc3MgPSAiXFxQZWFzdFxcU3ludGF4XFxOb2RlXFwiIC4gJG5vZGVUeXBlOwogICAgICAgICRub2RlID0gbmV3ICRub2RlQ2xhc3M7CiAgICAgICAgCiAgICAgICAgLy9BZGQgdGhlIG5vZGUgc3RhcnQgcG9zaXRpb24KICAgICAgICBpZiAoJHBvc2l0aW9uIGluc3RhbmNlb2YgTm9kZVxOb2RlIHx8ICRwb3NpdGlvbiBpbnN0YW5jZW9mIFRva2VuKSB7CiAgICAgICAgICAgICRwb3NpdGlvbiA9ICRwb3NpdGlvbi0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgIH0gZWxzZWlmIChpc19hcnJheSgkcG9zaXRpb24pKSB7CiAgICAgICAgICAgIGlmIChjb3VudCgkcG9zaXRpb24pKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAkcG9zaXRpb25bMF0tPmxvY2F0aW9uLT5zdGFydDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRub2RlLT5sb2NhdGlvbi0+c3RhcnQgPSAkcG9zaXRpb247CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBOb2RlQ3JlYXRlZCBldmVudCBmb3IgdGhlIG5vZGUKICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgIk5vZGVDcmVhdGVkIiwgYXJyYXkoJG5vZGUpCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJG5vZGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29tcGxldGVzIGEgbm9kZSBieSBhZGRpbmcgdGhlIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gTm9kZVxOb2RlICAgJG5vZGUgICAgIE5vZGUgdG8gY29tcGxldGUKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAgICAkcG9zaXRpb24gTm9kZSdzIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIG1peGVkICAgIEl0IGFjdHVhbGx5IHJldHVybnMgYSBOb2RlIGJ1dCBtaXhlZCBzb2x2ZXMKICAgICAqICAgICAgICAgICAgICAgICAgYSBsb3Qgb2YgUEhQRG9jIHByb2JsZW1zCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbXBsZXRlTm9kZShOb2RlXE5vZGUgJG5vZGUsICRwb3NpdGlvbiA9IG51bGwpCiAgICB7CiAgICAgICAgLy9BZGQgdGhlIG5vZGUgZW5kIHBvc2l0aW9uCiAgICAgICAgJG5vZGUtPmxvY2F0aW9uLT5lbmQgPSAkcG9zaXRpb24gPzogJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCk7CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBOb2RlQ29tcGxldGVkIGV2ZW50IGZvciB0aGUgbm9kZQogICAgICAgICR0aGlzLT5ldmVudHNFbWl0dGVyICYmICR0aGlzLT5ldmVudHNFbWl0dGVyLT5maXJlKAogICAgICAgICAgICAiTm9kZUNvbXBsZXRlZCIsIGFycmF5KCRub2RlKQogICAgICAgICk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuICRub2RlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRocm93cyBhIHN5bnRheCBlcnJvcgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJG1lc3NhZ2UgIEVycm9yIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAkcG9zaXRpb24gRXJyb3IgcG9zaXRpb24KICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKiAKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSA9ICIiLCAkcG9zaXRpb24gPSBudWxsKQogICAgewogICAgICAgIGlmICghJG1lc3NhZ2UpIHsKICAgICAgICAgICAgJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCk7CiAgICAgICAgICAgIGlmICgkdG9rZW4gPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIlVuZXhwZWN0ZWQgZW5kIG9mIGlucHV0IjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9ICR0b2tlbi0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiVW5leHBlY3RlZDogIiAuICR0b2tlbi0+dmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCEkcG9zaXRpb24pIHsKICAgICAgICAgICAgJHBvc2l0aW9uID0gJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJG1lc3NhZ2UsICRwb3NpdGlvbik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQXNzZXJ0cyB0aGF0IGEgdmFsaWQgZW5kIG9mIHN0YXRlbWVudCBmb2xsb3dzIHRoZSBjdXJyZW50IHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICogCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKQogICAgewogICAgICAgIC8vVGhlIGVuZCBvZiBzdGF0ZW1lbnQgaXMgcmVhY2hlZCB3aGVuIGl0IGlzIGZvbGxvd2VkIGJ5IGxpbmUKICAgICAgICAvL3Rlcm1pbmF0b3JzLCBlbmQgb2Ygc291cmNlLCAifSIgb3IgIjsiLiBJbiB0aGUgbGFzdCBjYXNlIHRoZSB0b2tlbgogICAgICAgIC8vbXVzdCBiZSBjb25zdW1lZAogICAgICAgIGlmICghJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI7IikpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgICAgICBpZiAoISR0b2tlbiB8fCAkdG9rZW4tPnZhbHVlID09PSAifSIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGNoYXJhY3RlciBzZXBhcmF0ZWQgbGlzdCBvZiBpbnN0cnVjdGlvbnMgb3IgbnVsbCBpZiB0aGUKICAgICAqIHNlcXVlbmNlIGlzIG5vdCB2YWxpZAogICAgICogCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGZuICAgUGFyc2luZyBpbnN0cnVjdGlvbiBmdW5jdGlvbgogICAgICogQHBhcmFtIHN0cmluZyAgICRjaGFyIFNlcGFyYXRvcgogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiAKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGFyU2VwYXJhdGVkTGlzdE9mKCRmbiwgJGNoYXIgPSAiLCIpCiAgICB7CiAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgd2hpbGUgKCRwYXJhbSA9ICR0aGlzLT4kZm4oKSkgewogICAgICAgICAgICAkbGlzdFtdID0gJHBhcmFtOwogICAgICAgICAgICAkdmFsaWQgPSB0cnVlOwogICAgICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCRjaGFyKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoISR2YWxpZCkgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRsaXN0OwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxUb2tlbjsKCi8qKgogKiBKU1ggc2Nhbm5lciB0cmFpdAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwp0cmFpdCBTY2FubmVyCnsKICAgIC8qKgogICAgICogVHJpZXMgdG8gcmVjb25zdW1lIHRoZSBjdXJyZW50IHRva2VuIGFzIGEganN4IHRleHQgaWYgcG9zc2libGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWNvbnN1bWVDdXJyZW50VG9rZW5Bc0pTWFRleHQoKQogICAgewogICAgICAgIC8vQ3VycmVudCBhbmQgbmV4dCB0b2tlbnMgbXVzdCBiZSByZXNldCBhbmQgdGhlIG9wZW4gYnJhY2tldHMgY291bnQgbXVzdCBiZSBjb3JyZWN0CiAgICAgICAgLy9saWtlIHRoZXkgd2VyZSBuZXZlciBzY2FubmVkCiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJHRoaXMtPmN1cnJlbnRUb2tlbiwgJHRoaXMtPm5leHRUb2tlbikgYXMgJHRva2VuKSB7CiAgICAgICAgICAgIGlmICgkdG9rZW4gJiYgaXNzZXQoJHRoaXMtPmJyYWNrZXRzWyR0b2tlbi0+dmFsdWVdKSkgewogICAgICAgICAgICAgICAgaWYgKCRyZWZCcmFja2V0ID0gJHRoaXMtPmJyYWNrZXRzWyR0b2tlbi0+dmFsdWVdKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZW5CcmFja2V0c1skcmVmQnJhY2tldF0rKzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZW5CcmFja2V0c1skdG9rZW4tPnZhbHVlXS0tOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR0aGlzLT5uZXh0VG9rZW4gPSBudWxsOwogICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSBudWxsOwoKICAgICAgICAkc3RhcnRQb3NpdGlvbiA9ICR0aGlzLT5nZXRQb3NpdGlvbigpOwogICAgICAgICR0aGlzLT5zZXRTY2FuUG9zaXRpb24oJHN0YXJ0UG9zaXRpb24pOwogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y29uc3VtZVVudGlsKGFycmF5KCJ7IiwgIjwiKSwgZmFsc2UsIGZhbHNlKTsKICAgICAgICBpZiAoJHJlc3VsdCkgewogICAgICAgICAgICAkdGhpcy0+Y3VycmVudFRva2VuID0gbmV3IFRva2VuKFRva2VuOjpUWVBFX0pTWF9URVhULCAkcmVzdWx0WzBdKTsKICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUb2tlbi0+bG9jYXRpb24tPnN0YXJ0ID0gJHN0YXJ0UG9zaXRpb247CiAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4tPmxvY2F0aW9uLT5lbmQgPSAkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+Y3VycmVudFRva2VuOwogICAgfQogICAgCiAgICAKICAgIC8qKgogICAgICogUmVjb25zdW1lcyB0aGUgY3VycmVudCB0b2tlbiBpbiBqc3ggbW9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlY29uc3VtZUN1cnJlbnRUb2tlbkluSlNYTW9kZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPmpzeCA9IHRydWU7CiAgICAgICAgJHRoaXMtPm5leHRUb2tlbiA9IG51bGw7CiAgICAgICAgJHRoaXMtPmN1cnJlbnRUb2tlbiA9IG51bGw7CiAgICAgICAgJHN0YXJ0UG9zaXRpb24gPSAkdGhpcy0+Z2V0UG9zaXRpb24oKTsKICAgICAgICAkdGhpcy0+c2V0U2NhblBvc2l0aW9uKCRzdGFydFBvc2l0aW9uKTsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+Z2V0VG9rZW4oKTsKICAgICAgICAkdGhpcy0+anN4ID0gZmFsc2U7CiAgICAgICAgcmV0dXJuICR0b2tlbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTdHJpbmcgc2Nhbm5pbmcgbWV0aG9kIGluIGpzeCBtb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2NhbkpTWFN0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zY2FuU3RyaW5nKGZhbHNlKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTdHJpbmcgcHVuY3R1YXRvciBtZXRob2QgaW4ganN4IG1vZGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzY2FuSlNYUHVuY3R1YXRvcigpCiAgICB7CiAgICAgICAgLy9UaGUgIj4iIGNoYXJhY3RlciBpbiBqc3ggbW9kZSBtdXN0IGJlIGVtaXR0ZWQgaW4gaXRzIG93biB0b2tlbgogICAgICAgIC8vd2l0aG91dCBtYXRjaGluZyBsb25nZXIgc2VxdWVuY2VzIGxpa2UgIj4+IgogICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgIGlmICgkY2hhciA9PT0gIj4iKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgIHJldHVybiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfUFVOQ1RVQVRPUiwgJGNoYXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPnNjYW5QdW5jdHVhdG9yKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSWRlbnRpZmllciBzY2FubmluZyBtZXRob2QgaW4ganN4IG1vZGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzY2FuSlNYSWRlbnRpZmllcigpCiAgICB7CiAgICAgICAgJGJ1ZmZlciA9ICIiOwogICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgIGlmICgkY2hhciAhPT0gbnVsbCAmJiAkdGhpcy0+aXNJZGVudGlmaWVyQ2hhcigkY2hhcikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgICAgICB9IHdoaWxlICgKICAgICAgICAgICAgICAgICRjaGFyICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAoJHRoaXMtPmlzSWRlbnRpZmllckNoYXIoJGNoYXIsIGZhbHNlKSB8fCAkY2hhciA9PT0gIi0iKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJGJ1ZmZlciA9PT0gIiIgPyBudWxsIDogbmV3IFRva2VuKFRva2VuOjpUWVBFX0pTWF9JREVOVElGSUVSLCAkYnVmZmVyKTsKICAgIH0KfQo8P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XFRva2VuOwoKLyoqCiAqIEpTWCBwYXJzZXIgdHJhaXQKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KdHJhaXQgUGFyc2VyCnsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIEpTWCBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5vZGVUeXBlIE5vZGUncyB0eXBlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRwb3NpdGlvbiBOb2RlJ3Mgc3RhcnQgcG9zaXRpb24KICAgICAqIAogICAgICogQHJldHVybiBcUGVhc3RcU3ludGF4XE5vZGVcTm9kZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY3JlYXRlSlNYTm9kZSgkbm9kZVR5cGUsICRwb3NpdGlvbikKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWF0ZU5vZGUoIkpTWFxcJG5vZGVUeXBlIiwgJHBvc2l0aW9uKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBqc3ggZnJhZ21lbnQKICAgICAqIAogICAgICogQHJldHVybiBcUGVhc3RcU3ludGF4XE5vZGVcSlNYXEpTWEZyYWdtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYRnJhZ21lbnQoKQogICAgewogICAgICAgICRzdGFydE9wZW5pbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgIGlmICghJHN0YXJ0T3BlbmluZ1Rva2VuIHx8ICRzdGFydE9wZW5pbmdUb2tlbi0+dmFsdWUgIT09ICI8IikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJGVuZE9wZW5pbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXROZXh0VG9rZW4oKTsKICAgICAgICBpZiAoISRlbmRPcGVuaW5nVG9rZW4gfHwgJGVuZE9wZW5pbmdUb2tlbi0+dmFsdWUgIT09ICI+IikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAKICAgICAgICAkY2hpbGRyZW4gPSAkdGhpcy0+cGFyc2VKU1hDaGlsZHJlbigpOwogICAgICAgIAogICAgICAgIGlmICghKCRzdGFydENsb3NpbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI8IikpIHx8CiAgICAgICAgICAgICEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLyIpIHx8CiAgICAgICAgICAgICEkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCkgfHwKICAgICAgICAgICAgJGVuZE9wZW5pbmdUb2tlbi0+dmFsdWUgIT09ICI+IikgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIAogICAgICAgIC8vT3BlbmluZyB0YWcKICAgICAgICAkb3BlbmluZ05vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgKICAgICAgICAgICAgIkpTWE9wZW5pbmdGcmFnbWVudCIsCiAgICAgICAgICAgICRzdGFydE9wZW5pbmdUb2tlbgogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmNvbXBsZXRlTm9kZSgKICAgICAgICAgICAgJG9wZW5pbmdOb2RlLAogICAgICAgICAgICAkZW5kT3BlbmluZ1Rva2VuLT5sb2NhdGlvbi0+ZW5kCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICAvL0Nsb3NpbmcgdGFnCiAgICAgICAgJGNsb3NpbmdOb2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoCiAgICAgICAgICAgICJKU1hDbG9zaW5nRnJhZ21lbnQiLAogICAgICAgICAgICAkc3RhcnRDbG9zaW5nVG9rZW4KICAgICAgICApOwogICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJGNsb3NpbmdOb2RlKTsKICAgICAgICAKICAgICAgICAvL0ZyYWdtZW50CiAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYRnJhZ21lbnQiLCAkc3RhcnRPcGVuaW5nVG9rZW4pOwogICAgICAgICRub2RlLT5zZXRPcGVuaW5nRnJhZ21lbnQoJG9wZW5pbmdOb2RlKTsKICAgICAgICAkbm9kZS0+c2V0Q2xvc2luZ0ZyYWdtZW50KCRjbG9zaW5nTm9kZSk7CiAgICAgICAgaWYgKCRjaGlsZHJlbikgewogICAgICAgICAgICAkbm9kZS0+c2V0Q2hpbGRyZW4oJGNoaWxkcmVuKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdyb3VwIG9mIGpzeCBjaGlsZHJlbgogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VKU1hDaGlsZHJlbigpCiAgICB7CiAgICAgICAgJGNoaWxkcmVuID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoJGNoaWxkID0gJHRoaXMtPnBhcnNlSlNYQ2hpbGQoKSkgewogICAgICAgICAgICAkY2hpbGRyZW5bXSA9ICRjaGlsZDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvdW50KCRjaGlsZHJlbikgPyAkY2hpbGRyZW4gOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGpzeCBjaGlsZAogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYQ2hpbGQoKQogICAgewogICAgICAgIGlmICgkbm9kZSA9ICR0aGlzLT5wYXJzZUpTWFRleHQoKSkgewogICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgfSBlbHNlaWYgKCRub2RlID0gJHRoaXMtPnBhcnNlSlNYRnJhZ21lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgfSBlbHNlaWYoJG5vZGUgPSAkdGhpcy0+cGFyc2VKU1hFbGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRub2RlOwogICAgICAgIH0gZWxzZWlmICgkc3RhcnRUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgJHNwcmVhZCA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIuLi4iKTsKICAgICAgICAgICAgJGV4cCA9ICR0aGlzLT5wYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7CiAgICAgICAgICAgICRtaWRQb3MgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKTsKICAgICAgICAgICAgaWYgKCgkc3ByZWFkICYmICEkZXhwKSB8fCAhJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgKICAgICAgICAgICAgICAgICRzcHJlYWQgPyAiSlNYU3ByZWFkQ2hpbGQiIDogIkpTWEV4cHJlc3Npb25Db250YWluZXIiLAogICAgICAgICAgICAgICAgJHN0YXJ0VG9rZW4KICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCEkZXhwKSB7CiAgICAgICAgICAgICAgICAkZXhwID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWEVtcHR5RXhwcmVzc2lvbiIsICRtaWRQb3MpOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbXBsZXRlTm9kZSgkZXhwLCAkbWlkUG9zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbm9kZS0+c2V0RXhwcmVzc2lvbigkZXhwKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBqc3ggdGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxKU1hcSlNYVGV4dHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUpTWFRleHQoKQogICAgewogICAgICAgIGlmICghKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5yZWNvbnN1bWVDdXJyZW50VG9rZW5Bc0pTWFRleHQoKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hUZXh0IiwgJHRva2VuKTsKICAgICAgICAkbm9kZS0+c2V0UmF3KCR0b2tlbi0+dmFsdWUpOwogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlLCAkdG9rZW4tPmxvY2F0aW9uLT5lbmQpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGpzeCBlbGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXEpTWFxKU1hFbGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYRWxlbWVudCgpCiAgICB7CiAgICAgICAgJHN0YXJ0T3BlbmluZ1Rva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCk7CiAgICAgICAgaWYgKCEkc3RhcnRPcGVuaW5nVG9rZW4gfHwgJHN0YXJ0T3BlbmluZ1Rva2VuLT52YWx1ZSAhPT0gIjwiKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbmV4dFRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldE5leHRUb2tlbigpOwogICAgICAgIGlmICgkbmV4dFRva2VuICYmICRuZXh0VG9rZW4tPnZhbHVlID09PSAiLyIpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAKICAgICAgICBpZiAoISgkbmFtZSA9ICR0aGlzLT5wYXJzZUpTWElkZW50aWZpZXJPck1lbWJlckV4cHJlc3Npb24oKSkpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRhdHRyaWJ1dGVzID0gJHRoaXMtPnBhcnNlSlNYQXR0cmlidXRlcygpOwogICAgICAgIAogICAgICAgICRzZWxmQ2xvc2luZyA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIvIik7CiAgICAgICAgCiAgICAgICAgJGVuZE9wZW5pbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5yZWNvbnN1bWVDdXJyZW50VG9rZW5JbkpTWE1vZGUoKTsKICAgICAgICBpZiAoISRlbmRPcGVuaW5nVG9rZW4gfHwgJGVuZE9wZW5pbmdUb2tlbi0+dmFsdWUgIT09ICI+IikgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIAogICAgICAgIGlmICghJHNlbGZDbG9zaW5nKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkY2hpbGRyZW4gPSAkdGhpcy0+cGFyc2VKU1hDaGlsZHJlbigpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgKCRzdGFydENsb3NpbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI8IikpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLyIpICYmCiAgICAgICAgICAgICAgICAoJGNsb3NpbmdOYW1lID0gJHRoaXMtPnBhcnNlSlNYSWRlbnRpZmllck9yTWVtYmVyRXhwcmVzc2lvbigpKSAmJgogICAgICAgICAgICAgICAgKCRlbmRDbG9zaW5nVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCkpICYmCiAgICAgICAgICAgICAgICAoJGVuZENsb3NpbmdUb2tlbi0+dmFsdWUgPT09ICI+IikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pc1NhbWVKU1hFbGVtZW50TmFtZSgkbmFtZSwgJGNsb3NpbmdOYW1lKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigiQ2xvc2luZyB0YWcgZG9lcyBub3QgbWF0Y2ggb3BlbmluZyB0YWciKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL09wZW5pbmcgdGFnCiAgICAgICAgJG9wZW5pbmdOb2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoCiAgICAgICAgICAgICJKU1hPcGVuaW5nRWxlbWVudCIsCiAgICAgICAgICAgICRzdGFydE9wZW5pbmdUb2tlbgogICAgICAgICk7CiAgICAgICAgJG9wZW5pbmdOb2RlLT5zZXROYW1lKCRuYW1lKTsKICAgICAgICAkb3BlbmluZ05vZGUtPnNldFNlbGZDbG9zaW5nKCRzZWxmQ2xvc2luZyk7CiAgICAgICAgaWYgKCRhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICRvcGVuaW5nTm9kZS0+c2V0QXR0cmlidXRlcygkYXR0cmlidXRlcyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoCiAgICAgICAgICAgICRvcGVuaW5nTm9kZSwKICAgICAgICAgICAgJGVuZE9wZW5pbmdUb2tlbi0+bG9jYXRpb24tPmVuZAogICAgICAgICk7CiAgICAgICAgCiAgICAgICAgLy9DbG9zaW5nIHRhZwogICAgICAgICRjbG9zaW5nTm9kZSA9IG51bGw7CiAgICAgICAgaWYgKCEkc2VsZkNsb3NpbmcpIHsKICAgICAgICAgICAgJGNsb3NpbmdOb2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoCiAgICAgICAgICAgICAgICAiSlNYQ2xvc2luZ0VsZW1lbnQiLAogICAgICAgICAgICAgICAgJHN0YXJ0Q2xvc2luZ1Rva2VuCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRjbG9zaW5nTm9kZS0+c2V0TmFtZSgkY2xvc2luZ05hbWUpOwogICAgICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKCRjbG9zaW5nTm9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vRWxlbWVudAogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWEVsZW1lbnQiLCAkc3RhcnRPcGVuaW5nVG9rZW4pOwogICAgICAgICRub2RlLT5zZXRPcGVuaW5nRWxlbWVudCgkb3BlbmluZ05vZGUpOwogICAgICAgIGlmICgkY2xvc2luZ05vZGUpIHsKICAgICAgICAgICAgJG5vZGUtPnNldENsb3NpbmdFbGVtZW50KCRjbG9zaW5nTm9kZSk7CiAgICAgICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRDaGlsZHJlbigkY2hpbGRyZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBqc3ggaWRlbnRpZmllciwgbmFtZXNwYWNlZCBpZGVudGlmaWVyIG9yIG1lbWJlciBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRhbGxvd01lbWJlciBUcnVlIHRvIGFsbG93IG1lbWJlciBleHByZXNzaW9ucwogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYSWRlbnRpZmllck9yTWVtYmVyRXhwcmVzc2lvbigkYWxsb3dNZW1iZXIgPSB0cnVlKQogICAgewogICAgICAgICRpZFRva2VuID0gJHRoaXMtPnNjYW5uZXItPnJlY29uc3VtZUN1cnJlbnRUb2tlbkluSlNYTW9kZSgpOwogICAgICAgIGlmICghJGlkVG9rZW4gfHwgJGlkVG9rZW4tPnR5cGUgIT09IFRva2VuOjpUWVBFX0pTWF9JREVOVElGSUVSKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgCiAgICAgICAgJGlkTm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hJZGVudGlmaWVyIiwgJGlkVG9rZW4pOwogICAgICAgICRpZE5vZGUtPnNldE5hbWUoJGlkVG9rZW4tPnZhbHVlKTsKICAgICAgICAkaWROb2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkaWROb2RlKTsKICAgICAgICAKICAgICAgICAvL05hbWVzcGFjZWQgaWRlbnRpZmllcgogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkaWRUb2tlbjIgPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCk7CiAgICAgICAgICAgIGlmICghJGlkVG9rZW4yIHx8ICRpZFRva2VuMi0+dHlwZSAhPT0gVG9rZW46OlRZUEVfSlNYX0lERU5USUZJRVIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRpZE5vZGUyID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWElkZW50aWZpZXIiLCAkaWRUb2tlbjIpOwogICAgICAgICAgICAkaWROb2RlMi0+c2V0TmFtZSgkaWRUb2tlbjItPnZhbHVlKTsKICAgICAgICAgICAgJGlkTm9kZTIgPSAkdGhpcy0+Y29tcGxldGVOb2RlKCRpZE5vZGUyKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWE5hbWVzcGFjZWROYW1lIiwgJGlkVG9rZW4pOwogICAgICAgICAgICAkbm9kZS0+c2V0TmFtZXNwYWNlKCRpZE5vZGUpOwogICAgICAgICAgICAkbm9kZS0+c2V0TmFtZSgkaWROb2RlMik7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vR2V0IGZvbGxvd2luZyBpZGVudGlmaWVycwogICAgICAgICRuZXh0SWRzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJGFsbG93TWVtYmVyKSB7CiAgICAgICAgICAgIHdoaWxlICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLiIpKSB7CiAgICAgICAgICAgICAgICAkbmV4dElkID0gJHRoaXMtPnNjYW5uZXItPnJlY29uc3VtZUN1cnJlbnRUb2tlbkluSlNYTW9kZSgpOwogICAgICAgICAgICAgICAgaWYgKCEkbmV4dElkIHx8ICRuZXh0SWQtPnR5cGUgIT09IFRva2VuOjpUWVBFX0pTWF9JREVOVElGSUVSKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICAkbmV4dElkc1tdID0gJG5leHRJZDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0NyZWF0ZSB0aGUgbWVtYmVyIGV4cHJlc3Npb24gaWYgcmVxdWlyZWQKICAgICAgICAkb2JqZWN0Tm9kZSA9ICRpZE5vZGU7CiAgICAgICAgZm9yZWFjaCAoJG5leHRJZHMgYXMgJG5pZCkgewogICAgICAgICAgICAkcHJvcEVuZCA9ICRuaWQtPmxvY2F0aW9uLT5lbmQ7CiAgICAgICAgICAgICRwcm9wTm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hJZGVudGlmaWVyIiwgJG5pZCk7CiAgICAgICAgICAgICRwcm9wTm9kZS0+c2V0TmFtZSgkbmlkLT52YWx1ZSk7CiAgICAgICAgICAgICRwcm9wTm9kZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJHByb3BOb2RlLCAkcHJvcEVuZCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hNZW1iZXJFeHByZXNzaW9uIiwgJG9iamVjdE5vZGUpOwogICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRvYmplY3ROb2RlKTsKICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnR5KCRwcm9wTm9kZSk7CiAgICAgICAgICAgICRvYmplY3ROb2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSwgJHByb3BFbmQpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJG9iamVjdE5vZGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEganN4IGF0dHJpYnV0ZXMgbGlzdAogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VKU1hBdHRyaWJ1dGVzKCkKICAgIHsKICAgICAgICAkYXR0cmlidXRlcyA9IGFycmF5KCk7CiAgICAgICAgd2hpbGUgKAogICAgICAgICAgICAoJGF0dHIgPSAkdGhpcy0+cGFyc2VKU1hTcHJlYWRBdHRyaWJ1dGUoKSkgfHwKICAgICAgICAgICAgKCRhdHRyID0gJHRoaXMtPnBhcnNlSlNYQXR0cmlidXRlKCkpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRhdHRyaWJ1dGVzW10gPSAkYXR0cjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvdW50KCRhdHRyaWJ1dGVzKSA/ICRhdHRyaWJ1dGVzIDogbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBqc3ggc3ByZWFkIGF0dHJpYnV0ZQogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxKU1hcSlNYU3ByZWFkQXR0cmlidXRlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYU3ByZWFkQXR0cmlidXRlKCkKICAgIHsKICAgICAgICBpZiAoISgkb3BlblRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICgKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4uLiIpICYmCiAgICAgICAgICAgICgkZXhwID0gJHRoaXMtPnBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKSkgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKQogICAgICAgICkgewogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hTcHJlYWRBdHRyaWJ1dGUiLCAkb3BlblRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRleHApOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGpzeCBzcHJlYWQgYXR0cmlidXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXEpTWFxKU1hTcHJlYWRBdHRyaWJ1dGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VKU1hBdHRyaWJ1dGUoKQogICAgewogICAgICAgIGlmICghKCRuYW1lID0gJHRoaXMtPnBhcnNlSlNYSWRlbnRpZmllck9yTWVtYmVyRXhwcmVzc2lvbihmYWxzZSkpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkdmFsdWUgPSBudWxsOwogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiPSIpKSB7CiAgICAgICAgICAgICRzdHJUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5yZWNvbnN1bWVDdXJyZW50VG9rZW5JbkpTWE1vZGUoKTsKICAgICAgICAgICAgaWYgKCRzdHJUb2tlbiAmJiAkc3RyVG9rZW4tPnR5cGUgPT09IFRva2VuOjpUWVBFX1NUUklOR19MSVRFUkFMKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiU3RyaW5nTGl0ZXJhbCIsICRzdHJUb2tlbik7CiAgICAgICAgICAgICAgICAkdmFsdWUtPnNldFJhdygkc3RyVG9rZW4tPnZhbHVlKTsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRzdGFydEV4cCA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICgkZXhwID0gJHRoaXMtPnBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKSkgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgIkpTWEV4cHJlc3Npb25Db250YWluZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAkc3RhcnRFeHAKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICR2YWx1ZS0+c2V0RXhwcmVzc2lvbigkZXhwKTsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+Y29tcGxldGVOb2RlKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgICAgICEoJHZhbHVlID0gJHRoaXMtPnBhcnNlSlNYRnJhZ21lbnQoKSkgJiYKICAgICAgICAgICAgICAgICEoJHZhbHVlID0gJHRoaXMtPnBhcnNlSlNYRWxlbWVudCgpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWEF0dHJpYnV0ZSIsICRuYW1lKTsKICAgICAgICAkbm9kZS0+c2V0TmFtZSgkbmFtZSk7CiAgICAgICAgaWYgKCR2YWx1ZSkgewogICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyB0aGF0IDIgdGFnIG5hbWVzIGFyZSBlcXVhbAogICAgICogCiAgICAgKiBAcGFyYW0gXFBlYXN0XFN5bnRheFxOb2RlXE5vZGUgICAkbjEgRmlyc3QgbmFtZQogICAgICogQHBhcmFtIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlICAgJG4yIFNlY29uZCBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNTYW1lSlNYRWxlbWVudE5hbWUoJG4xLCAkbjIpCiAgICB7CiAgICAgICAgJHR5cGUgPSAkbjEtPmdldFR5cGUoKTsKICAgICAgICBpZiAoJHR5cGUgIT09ICRuMi0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPT09ICJKU1hOYW1lc3BhY2VkTmFtZSIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pc1NhbWVKU1hFbGVtZW50TmFtZSgKICAgICAgICAgICAgICAgICRuMS0+Z2V0TmFtZXNwYWNlKCksICRuMi0+Z2V0TmFtZXNwYWNlKCkKICAgICAgICAgICAgKSAmJiAkdGhpcy0+aXNTYW1lSlNYRWxlbWVudE5hbWUoCiAgICAgICAgICAgICAgICAkbjEtPmdldE5hbWUoKSwgJG4yLT5nZXROYW1lKCkKICAgICAgICAgICAgKTsKICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPT09ICJKU1hNZW1iZXJFeHByZXNzaW9uIikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmlzU2FtZUpTWEVsZW1lbnROYW1lKAogICAgICAgICAgICAgICAgJG4xLT5nZXRPYmplY3QoKSwgJG4yLT5nZXRPYmplY3QoKQogICAgICAgICAgICApICYmICR0aGlzLT5pc1NhbWVKU1hFbGVtZW50TmFtZSgKICAgICAgICAgICAgICAgICRuMS0+Z2V0UHJvcGVydHkoKSwgJG4yLT5nZXRQcm9wZXJ0eSgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdHlwZSA9PT0gIkpTWElkZW50aWZpZXIiICYmICRuMS0+Z2V0TmFtZSgpID09PSAkbjItPmdldE5hbWUoKTsKICAgIH0KfQo8P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBDb21tZW50cyByZWdpc3RyeSBjbGFzcy4gSW50ZXJuYWwgY2xhc3MgdXNlZCB0byBtYW5hZ2UgY29tbWVudHMKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tbWVudHNSZWdpc3RyeQp7CiAgICAvKioKICAgICAqIE1hcCBvZiB0aGUgaW5kaWNlcyB3aGVyZSBub2RlcyBzdGFydAogICAgICogCiAgICAgKiBAdmFyIGludCAKICAgICAqLwogICAgcHJvdGVjdGVkICRub2Rlc1N0YXJ0TWFwID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBNYXAgb2YgdGhlIGluZGljZXMgd2hlcmUgbm9kZXMgZW5kCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJG5vZGVzRW5kTWFwID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyBidWZmZXIKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJGJ1ZmZlciA9IG51bGw7CiAgICAKICAgIC8qKgogICAgICogTGFzdCB0b2tlbiBpbmRleAogICAgICogCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhc3RUb2tlbkluZGV4ID0gbnVsbDsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyByZWdpc3RyeQogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVnaXN0cnkgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXJzZXIgICAgJHBhcnNlciAgICAgUGFyc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQYXJzZXIgJHBhcnNlcikKICAgIHsKICAgICAgICAkcGFyc2VyLT5nZXRFdmVudHNFbWl0dGVyKCkKICAgICAgICAgICAgICAgLT5hZGRMaXN0ZW5lcigiTm9kZUNvbXBsZXRlZCIsIGFycmF5KCR0aGlzLCAib25Ob2RlQ29tcGxldGVkIikpCiAgICAgICAgICAgICAgIC0+YWRkTGlzdGVuZXIoIkVuZFBhcnNpbmciLCBhcnJheSgkdGhpcywgIm9uRW5kUGFyc2luZyIpKTsKICAgICAgICAKICAgICAgICAkcGFyc2VyLT5nZXRTY2FubmVyKCktPmdldEV2ZW50c0VtaXR0ZXIoKQogICAgICAgICAgICAgICAtPmFkZExpc3RlbmVyKCJUb2tlbkNvbnN1bWVkIiwgYXJyYXkoJHRoaXMsICJvblRva2VuQ29uc3VtZWQiKSkKICAgICAgICAgICAgICAgLT5hZGRMaXN0ZW5lcigiRW5kUmVhY2hlZCIsIGFycmF5KCR0aGlzLCAib25Ub2tlbkNvbnN1bWVkIikpCiAgICAgICAgICAgICAgIC0+YWRkTGlzdGVuZXIoIkZyZWV6ZVN0YXRlIiwgYXJyYXkoJHRoaXMsICJvblNjYW5uZXJGcmVlemVTdGF0ZSIpKQogICAgICAgICAgICAgICAtPmFkZExpc3RlbmVyKCJSZXNldFN0YXRlIiwgYXJyYXkoJHRoaXMsICJvblNjYW5uZXJSZXNldFN0YXRlIikpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIExpc3RlbmVyIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBzY2FubmVyIGNvbXBvc2UgdGhlIGFycmF5IHRoYXQgcmVwcmVzZW50cwogICAgICogaXRzIGN1cnJlbnQgc3RhdGUKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICAgJHN0YXRlICAgU3RhdGUKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvblNjYW5uZXJGcmVlemVTdGF0ZSgmJHN0YXRlKQogICAgewogICAgICAgIC8vUmVnaXN0ZXIgdGhlIGN1cnJlbnQgbGFzdCB0b2tlbiBpbmRleAogICAgICAgICRzdGF0ZVsiY29tbWVudHNMYXN0VG9rZW5JbmRleCJdID0gJHRoaXMtPmxhc3RUb2tlbkluZGV4OwogICAgfQogICAgCiAgICAvKioKICAgICAqIExpc3RlbmVyIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBzY2FubmVyIHJlc2V0IGl0cyBzdGF0ZSB1c2luZyB0aGUgZ2l2ZW4KICAgICAqIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheSAgICRzdGF0ZSAgIFN0YXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25TY2FubmVyUmVzZXRTdGF0ZSgmJHN0YXRlKQogICAgewogICAgICAgIC8vUmVzZXQgdGhlIGxhc3QgdG9rZW4gaW5kZXggYW5kIGRlbGV0ZSBpdCBmcm9tIHRoZSBzdGF0ZSBhcnJheQogICAgICAgICR0aGlzLT5sYXN0VG9rZW5JbmRleCA9ICRzdGF0ZVsiY29tbWVudHNMYXN0VG9rZW5JbmRleCJdOwogICAgICAgIHVuc2V0KCRzdGF0ZVsiY29tbWVudHNMYXN0VG9rZW5JbmRleCJdKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBMaXN0ZW5lciBjYWxsZWQgZXZlcnkgdGltZSBhIHRva2VuIGlzIGNvbnN1bWVkIGFuZCB3aGVuIHRoZSBzY2FubmVyCiAgICAgKiByZWFjaGVzIHRoZSBlbmQgb2YgdGhlIHNvdXJjZQogICAgICogCiAgICAgKiBAcGFyYW0gVG9rZW58bnVsbCAgICR0b2tlbiAgIENvbnN1bWVkIHRva2VuIG9yIG51bGwgaWYgdGhlIGVuZCBoYXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVlbiByZWFjaGVkCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25Ub2tlbkNvbnN1bWVkKFRva2VuICR0b2tlbiA9IG51bGwpCiAgICB7CiAgICAgICAgLy9DaGVjayBpZiBpdCdzIGEgY29tbWVudAogICAgICAgIGlmICgkdG9rZW4gJiYgJHRva2VuLT50eXBlID09PSBUb2tlbjo6VFlQRV9DT01NRU5UKSB7CiAgICAgICAgICAgIC8vSWYgdGhlcmUgaXMgbm90IGFuIG9wZW4gY29tbWVudHMgYnVmZmVyLCBjcmVhdGUgaXQKICAgICAgICAgICAgaWYgKCEkdGhpcy0+YnVmZmVyKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YnVmZmVyID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgInByZXYiID0+ICR0aGlzLT5sYXN0VG9rZW5JbmRleCwKICAgICAgICAgICAgICAgICAgICAibmV4dCIgPT4gbnVsbCwKICAgICAgICAgICAgICAgICAgICAiY29tbWVudHMiID0+IGFycmF5KCkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9BZGQgdGhlIGNvbW1lbnQgdG9rZW4gdG8gdGhlIGJ1ZmZlcgogICAgICAgICAgICAkdGhpcy0+YnVmZmVyWyJjb21tZW50cyJdW10gPSAkdG9rZW47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdG9rZW4pIHsKICAgICAgICAgICAgICAgICRsb2MgPSAkdG9rZW4tPmxvY2F0aW9uOwogICAgICAgICAgICAgICAgLy9TdG9yZSB0aGUgdG9rZW4gZW5kIHBvc2l0aW9uCiAgICAgICAgICAgICAgICAkdGhpcy0+bGFzdFRva2VuSW5kZXggPSAkbG9jLT5lbmQtPmdldEluZGV4KCk7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmJ1ZmZlcikgewogICAgICAgICAgICAgICAgICAgIC8vRmlsbCB0aGUgIm5leHQiIGtleSBvbiB0aGUgY29tbWVudHMgYnVmZmVyIHdpdGggdGhlIHRva2VuCiAgICAgICAgICAgICAgICAgICAgLy9zdGFydCBwb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXJbIm5leHQiXSA9ICRsb2MtPnN0YXJ0LT5nZXRJbmRleCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0lmIHRoZXJlIGlzIGFuIG9wZW4gY29tbWVudCBidWZmZXIsIGNsb3NlIGl0IGFuZCBtb3ZlIGl0IHRvIHRoZQogICAgICAgICAgICAvL3JlZ2lzdHJ5CiAgICAgICAgICAgIGlmICgkYnVmZmVyID0gJHRoaXMtPmJ1ZmZlcikgewogICAgICAgICAgICAgICAgLy9Vc2UgdGhlIGxvY2F0aW9uIGFzIGtleSB0byBhZGQgdGhlIGdyb3VwIG9mIGNvbW1lbnRzIHRvIHRoZQogICAgICAgICAgICAgICAgLy9yZWdpc3RyeSwgaW4gdGhpcyB3YXkgaWYgY29tbWVudHMgYXJlIHJlcHJvY2Vzc2VkIHRoZXkgd29uJ3QKICAgICAgICAgICAgICAgIC8vYmUgZHVwbGljYXRlZAogICAgICAgICAgICAgICAgJGtleSA9IGltcGxvZGUoIi0iLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAkYnVmZmVyWyJwcmV2Il0gIT09IG51bGwgPyAkYnVmZmVyWyJwcmV2Il0gOiAiIiwKICAgICAgICAgICAgICAgICAgICAkYnVmZmVyWyJuZXh0Il0gIT09IG51bGwgPyAkYnVmZmVyWyJuZXh0Il0gOiAiIgogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVnaXN0cnlbJGtleV0gPSAkdGhpcy0+YnVmZmVyOwogICAgICAgICAgICAgICAgJHRoaXMtPmJ1ZmZlciA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIExpc3RlbmVyIGNhbGxlZCBldmVyeSB0aW1lIGEgbm9kZSBpcyBjb21wbGV0ZWQgYnkgdGhlIHBhcnNlcgogICAgICogCiAgICAgKiBAcGFyYW0gTm9kZVxOb2RlICAgJG5vZGUgICAgIENvbXBsZXRlZCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25Ob2RlQ29tcGxldGVkKE5vZGVcTm9kZSAkbm9kZSkKICAgIHsKICAgICAgICAvL0V2ZXJ5IHRpbWUgYSBub2RlIGlzIGNvbXBsZXRlZCwgcmVnaXN0ZXIgaXRzIHN0YXJ0IGFuZCBlbmQgaW5kaWNlcwogICAgICAgIC8vaW4gdGhlIHJlbGF0aXZlIHByb3BlcnRpZXMKICAgICAgICAkbG9jID0gJG5vZGUtPmxvY2F0aW9uOwogICAgICAgIGZvcmVhY2ggKGFycmF5KCJTdGFydCIsICJFbmQiKSBhcyAkcG9zKSB7CiAgICAgICAgICAgICR2YWwgPSAkbG9jLT57ImdldCRwb3MifSgpLT5nZXRJbmRleCgpOwogICAgICAgICAgICAkbWFwID0gJiR0aGlzLT57Im5vZGVzeyRwb3N9TWFwIn07CiAgICAgICAgICAgIGlmICghaXNzZXQoJG1hcFskdmFsXSkpIHsKICAgICAgICAgICAgICAgICRtYXBbJHZhbF0gPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRtYXBbJHZhbF1bXSA9ICRub2RlOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBMaXN0ZW5lciBjYWxsZWQgd2hlbiBwYXJzaW5nIHByb2Nlc3MgZW5kcwogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG9uRW5kUGFyc2luZygpCiAgICB7CiAgICAgICAgLy9SZXR1cm4gaWYgdGhlcmUgYXJlIG5vIGNvbW1lbnRzIHRvIHByb2Nlc3MKICAgICAgICBpZiAoJHRoaXMtPnJlZ2lzdHJ5KSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL01ha2Ugc3VyZSBub2RlcyBzdGFydCBpbmRpY2VzIG1hcCBpcyBzb3J0ZWQKICAgICAgICAgICAga3NvcnQoJHRoaXMtPm5vZGVzU3RhcnRNYXApOwogICAgICAgICAgICAKICAgICAgICAgICAgLy9Mb29wIGFsbCBjb21tZW50IGdyb3VwcyBpbiB0aGUgcmVnaXN0cnkKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlZ2lzdHJ5IGFzICRncm91cCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbmROb2RlRm9yQ29tbWVudHNHcm91cCgkZ3JvdXApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBub2RlIHRvIGF0dGFjaCB0aGUgZ2l2ZW4gY29tbWVudHMgZ3JvdXAKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICAgICRncm91cCAgIENvbW1lbnRzIGdyb3VwCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZE5vZGVGb3JDb21tZW50c0dyb3VwKCRncm91cCkKICAgIHsKICAgICAgICAkbmV4dCA9ICRncm91cFsibmV4dCJdOwogICAgICAgICRwcmV2ID0gJGdyb3VwWyJwcmV2Il07CiAgICAgICAgJGNvbW1lbnRzID0gJGdyb3VwWyJjb21tZW50cyJdOwogICAgICAgICRsZWFkaW5nID0gdHJ1ZTsKICAgICAgICAKICAgICAgICAvL0lmIHRoZSBncm91cCBvZiBjb21tZW50cyBoYXMgYSBuZXh0IHRva2VuIGluZGV4IHRoYXQgYXBwZWFycwogICAgICAgIC8vaW4gdGhlIG1hcCBvZiBzdGFydCBub2RlIGluZGljZXMsIGFkZCB0aGUgZ3JvdXAgdG8gdGhlCiAgICAgICAgLy9jb3JyZXNwb25kaW5nIG5vZGUncyBsZWFkaW5nIGNvbW1lbnRzLiBUaGlzIGFzc29jaWF0ZXMKICAgICAgICAvL2NvbW1lbnRzIHRoYXQgYXBwZWFyIGltbWVkaWF0ZWx5IGJlZm9yZSBhIG5vZGUuCiAgICAgICAgLy9Gb3IgZXhhbXBsZTogLypjb21tZW50Ki8gZm9yICg7Oyl7fQogICAgICAgIGlmIChpc3NldCgkdGhpcy0+bm9kZXNTdGFydE1hcFskbmV4dF0pKSB7CiAgICAgICAgICAgICRub2RlcyA9ICR0aGlzLT5ub2Rlc1N0YXJ0TWFwWyRuZXh0XTsKICAgICAgICB9CiAgICAgICAgLy9JZiB0aGUgZ3JvdXAgb2YgY29tbWVudHMgaGFzIGEgcHJldmlvdXMgdG9rZW4gaW5kZXggdGhhdCBhcHBlYXJzCiAgICAgICAgLy9pbiB0aGUgbWFwIG9mIGVuZCBub2RlIGluZGljZXMsIGFkZCB0aGUgZ3JvdXAgdG8gdGhlCiAgICAgICAgLy9jb3JyZXNwb25kaW5nIG5vZGUncyB0cmFpbGluZyBjb21tZW50cy4gVGhpcyBhc3NvY2lhdGVzCiAgICAgICAgLy9jb21tZW50cyB0aGF0IGFwcGVhciBpbW1lZGlhdGVseSBhZnRlciBhIG5vZGUuCiAgICAgICAgLy9Gb3IgZXhhbXBsZTogZm9yICg7Oyl7fSAvKmNvbW1lbnQqLyAKICAgICAgICBlbHNlaWYgKGlzc2V0KCR0aGlzLT5ub2Rlc0VuZE1hcFskcHJldl0pKSB7CiAgICAgICAgICAgICRub2RlcyA9ICR0aGlzLT5ub2Rlc0VuZE1hcFskcHJldl07CiAgICAgICAgICAgICRsZWFkaW5nID0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIC8vT3RoZXJ3aXNlLCBmaW5kIGEgbm9kZSB0aGF0IHdyYXBzIHRoZSBjb21tZW50cyBwb3NpdGlvbi4KICAgICAgICAvL1RoaXMgYXNzb2NpYXRlcyBpbm5lciBjb21tZW50czoKICAgICAgICAvL0ZvciBleGFtcGxlOiBmb3IgLypjb21tZW50Ki8gKDs7KXt9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vQ2FsY3VsYXRlIGNvbW1lbnRzIGdyb3VwIGJvdW5kYXJpZXMKICAgICAgICAgICAgJHN0YXJ0ID0gJGNvbW1lbnRzWzBdLT5sb2NhdGlvbi0+c3RhcnQtPmdldEluZGV4KCk7CiAgICAgICAgICAgICRlbmQgPSAkY29tbWVudHNbY291bnQoJGNvbW1lbnRzKSAtMV0tPmxvY2F0aW9uLT5lbmQtPmdldEluZGV4KCk7CiAgICAgICAgICAgICRub2RlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0xvb3AgYWxsIHRoZSBlbnRyaWVzIGluIHRoZSBzdGFydCBpbmRleCBtYXAKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm5vZGVzU3RhcnRNYXAgYXMgJGlkeCA9PiAkbnMpIHsKICAgICAgICAgICAgICAgIC8vSWYgdGhlIGluZGV4IGlzIGhpZ2hlciB0aGFuIHRoZSBzdGFydCBpbmRleCBvZiB0aGUgY29tbWVudHMKICAgICAgICAgICAgICAgIC8vZ3JvdXAsIHN0b3AKICAgICAgICAgICAgICAgIGlmICgkaWR4ID4gJHN0YXJ0KSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbnMgYXMgJG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIHRoZSBjb21tZW50cyBncm91cCBpcyBpbnNpZGUgbm9kZSBpbmRpY2VzIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgaWYgKCRub2RlLT5sb2NhdGlvbi0+ZW5kLT5nZXRJbmRleCgpID49ICRlbmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVzW10gPSAkbm9kZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vSWYgY29tbWVudHMgY2FuJ3QgYmUgYXNzb2NpYXRlZCB3aXRoIGFueSBub2RlLCBhc3NvY2lhdGUgaXQgYXMKICAgICAgICAgICAgLy9sZWFkaW5nIGNvbW1lbnRzIG9mIHRoZSBwcm9ncmFtLCB0aGlzIGhhcHBlbnMgd2hlbiB0aGUgc291cmNlIGlzCiAgICAgICAgICAgIC8vZW1wdHkKICAgICAgICAgICAgaWYgKCEkbm9kZXMpIHsKICAgICAgICAgICAgICAgICRmaXJzdE5vZGUgPSBhcnJheV92YWx1ZXMoJHRoaXMtPm5vZGVzU3RhcnRNYXApOwogICAgICAgICAgICAgICAgJG5vZGVzID0gYXJyYXkoJGZpcnN0Tm9kZVswXVswXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgbm9kZXMgdG8gYXNzb2NpYXRlIHRoZSBjb21tZW50cyB0bywKICAgICAgICAvL2ZpbmQgdGhlIHNob3J0ZXN0IG9uZQogICAgICAgIGlmIChjb3VudCgkbm9kZXMpID4gMSkgewogICAgICAgICAgICB1c29ydCgkbm9kZXMsIGFycmF5KCR0aGlzLCAiY29tcGFyZU5vZGVzTGVuZ3RoIikpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+YXNzb2NpYXRlQ29tbWVudHMoJG5vZGVzWzBdLCAkY29tbWVudHMsICRsZWFkaW5nKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDb21wYXJlcyBub2RlIGxlbmd0aCAKICAgICAqIAogICAgICogQHBhcmFtIE5vZGVcTm9kZSAgJG5vZGUxICAgICBGaXJzdCBub2RlCiAgICAgKiBAcGFyYW0gTm9kZVxOb2RlICAkbm9kZTIgICAgIFNlY29uZCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gaW50CiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbXBhcmVOb2Rlc0xlbmd0aCgkbm9kZTEsICRub2RlMikKICAgIHsKICAgICAgICAkbG9jMSA9ICRub2RlMS0+bG9jYXRpb247CiAgICAgICAgJGxlbmd0aDEgPSAkbG9jMS0+ZW5kLT5nZXRJbmRleCgpIC0gJGxvYzEtPnN0YXJ0LT5nZXRJbmRleCgpOwogICAgICAgICRsb2MyID0gJG5vZGUyLT5sb2NhdGlvbjsKICAgICAgICAkbGVuZ3RoMiA9ICRsb2MyLT5lbmQtPmdldEluZGV4KCkgLSAkbG9jMi0+c3RhcnQtPmdldEluZGV4KCk7CiAgICAgICAgLy9JZiB0aGUgbm9kZXMgaGF2ZSB0aGUgc2FtZSBsZW5ndGggbWFrZSBzdXJlIHRvIGNob29zZSBub2RlcwogICAgICAgIC8vZGlmZmVyZW50IGZyb20gUHJvZ3JhbSBub2RlcwogICAgICAgIGlmICgkbGVuZ3RoMSA9PT0gJGxlbmd0aDIpIHsKICAgICAgICAgICAgaWYgKCRub2RlMSBpbnN0YW5jZW9mIE5vZGVcUHJvZ3JhbSkgewogICAgICAgICAgICAgICAgJGxlbmd0aDEgKz0gMTAwMDsKICAgICAgICAgICAgfSBlbHNlaWYgKCRub2RlMiBpbnN0YW5jZW9mIE5vZGVcUHJvZ3JhbSkgewogICAgICAgICAgICAgICAgJGxlbmd0aDIgKz0gMTAwMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGxlbmd0aDEgPCAkbGVuZ3RoMiA/IC0xIDogMTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBBZGRzIGNvbW1lbnRzIHRvIHRoZSBnaXZlbiBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgICAgICRub2RlICAgICAgIE5vZGUKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICRjb21tZW50cyAgIEFycmF5IG9mIGNvbW1lbnRzIHRvIGFkZAogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgJGxlYWRpbmcgICAgVHJ1ZSB0byBhZGQgY29tbWVudHMgYXMgbGVhZGluZyBjb21tZW50cwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgZmFsc2UgdG8gYWRkIHRoZW0gYXMgdHJhaWxpbmcgY29tbWVudHMKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc3NvY2lhdGVDb21tZW50cygkbm9kZSwgJGNvbW1lbnRzLCAkbGVhZGluZykKICAgIHsKICAgICAgICAkZm4gPSAoJGxlYWRpbmcgPyAiTGVhZGluZyIgOiAiVHJhaWxpbmciKSAuICJDb21tZW50cyI7CiAgICAgICAgJGN1cnJlbnRDb21tZW50cyA9ICRub2RlLT57ImdldCRmbiJ9KCk7CiAgICAgICAgZm9yZWFjaCAoJGNvbW1lbnRzIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICRsb2MgPSAkY29tbWVudC0+bG9jYXRpb247CiAgICAgICAgICAgICRjb21tZW50Tm9kZSA9IG5ldyBOb2RlXENvbW1lbnQ7CiAgICAgICAgICAgICRjb21tZW50Tm9kZS0+bG9jYXRpb24tPnN0YXJ0ID0gJGxvYy0+c3RhcnQ7CiAgICAgICAgICAgICRjb21tZW50Tm9kZS0+bG9jYXRpb24tPmVuZCA9ICRsb2MtPmVuZDsKICAgICAgICAgICAgJGNvbW1lbnROb2RlLT5zZXRSYXdUZXh0KCRjb21tZW50LT52YWx1ZSk7CiAgICAgICAgICAgICRjdXJyZW50Q29tbWVudHNbXSA9ICRjb21tZW50Tm9kZTsKICAgICAgICB9CiAgICAgICAgJG5vZGUtPnsic2V0JGZuIn0oJGN1cnJlbnRDb21tZW50cyk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzd2l0Y2ggc3RhdGVtZW50LgogKiBGb3IgZXhhbXBsZTogc3dpdGNoICh0ZXN0KSB7fQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBTd2l0Y2hTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZGlzY3JpbWluYW50IiA9PiB0cnVlLAogICAgICAgICJjYXNlcyIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBEaXNjcmltaW5hbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZGlzY3JpbWluYW50OwogICAgCiAgICAvKioKICAgICAqIENhc2VzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgU3dpdGNoQ2FzZVtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNhc2VzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaXNjcmltaW5hbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc2NyaW1pbmFudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kaXNjcmltaW5hbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGlzY3JpbWluYW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGRpc2NyaW1pbmFudCBEaXNjcmltaW5hbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXNjcmltaW5hbnQoRXhwcmVzc2lvbiAkZGlzY3JpbWluYW50KQogICAgewogICAgICAgICR0aGlzLT5kaXNjcmltaW5hbnQgPSAkZGlzY3JpbWluYW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYXNlcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIFN3aXRjaENhc2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2FzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2FzZXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2FzZXMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIFN3aXRjaENhc2VbXSAkY2FzZXMgQ2FzZXMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2FzZXMoJGNhc2VzKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjYXNlcywgIlN3aXRjaENhc2UiKTsKICAgICAgICAkdGhpcy0+Y2FzZXMgPSAkY2FzZXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgIm5ldyIgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IG5ldyB0ZXN0KCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgTmV3RXhwcmVzc2lvbiBleHRlbmRzIENhbGxFeHByZXNzaW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7Cgp1c2UgUGVhc3RcUXVlcnk7CnVzZSBQZWFzdFxTZWxlY3RvcjsKCi8qKgogKiBSb290IG5vZGUgZm9yIHNjcmlwdHMgYW5kIG1vZHVsZXMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFByb2dyYW0gZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYm9keSIgPT4gdHJ1ZSwKICAgICAgICAic291cmNlVHlwZSIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogU291cmNlIHR5cGUgdGhhdCBpcyBvbmUgb2YgdGhlIHNvdXJjZSB0eXBlIGNvbnN0YW50cyBpbiB0aGUgUGVhc3QgY2xhc3MKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlVHlwZSA9IFxQZWFzdFxQZWFzdDo6U09VUkNFX1RZUEVfU0NSSVBUOwogICAgCiAgICAvKioKICAgICAqIFByb2dyYW0ncyBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50W118TW9kdWxlRGVjbGFyYXRpb25bXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGJvZHkgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSB0eXBlIHRoYXQgaXMgb25lIG9mIHRoZSBzb3VyY2UgdHlwZSBjb25zdGFudHMgaW4gdGhlCiAgICAgKiBQZWFzdCBjbGFzcwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlVHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2VUeXBlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHNvdXJjZSB0eXBlIHRoYXQgaXMgb25lIG9mIHRoZSBzb3VyY2UgdHlwZSBjb25zdGFudHMgaW4gdGhlCiAgICAgKiBQZWFzdCBjbGFzcwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2VUeXBlIFNvdXJjZSB0eXBlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZVR5cGUoJHNvdXJjZVR5cGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnNvdXJjZVR5cGUgPSAkc291cmNlVHlwZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvZ3JhbSdzIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnRbXXxNb2R1bGVEZWNsYXJhdGlvbltdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvZ3JhbSdzIGJvZHkKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudFtdfE1vZHVsZURlY2xhcmF0aW9uW10gJGJvZHkgUHJvZ3JhbSdzIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keSgkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkYm9keSwgYXJyYXkoIlN0YXRlbWVudCIsICJNb2R1bGVEZWNsYXJhdGlvbiIpKTsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIG5vZGVzIG1hdGNoaW5nIHRoZSBnaXZlbiBzZWxlY3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICRzZWxlY3RvciAgIFNlbGVjdG9yCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICRvcHRpb25zICAgIE9wdGlvbnMgYXJyYXkuIFNlZSBRdWVyeSBjbGFzcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudGF0aW9uIGZvciBhdmFpbGFibGUgb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gUXVlcnkKICAgICAqCiAgICAgKiBAdGhyb3dzIFNlbGVjdG9yXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcXVlcnkoJHNlbGVjdG9yLCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHF1ZXJ5ID0gbmV3IFF1ZXJ5KCR0aGlzLCAkb3B0aW9ucyk7CiAgICAgICAgcmV0dXJuICRxdWVyeS0+ZmluZCgkc2VsZWN0b3IpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgc3BlY2lmaWVyIGluIGFuIGltcG9ydCBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGUgInthfSIgaW46IGltcG9ydCB7YX0gZnJvbSAidGVzdCIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSW1wb3J0U3BlY2lmaWVyIGV4dGVuZHMgTW9kdWxlU3BlY2lmaWVyCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiaW1wb3J0ZWQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogSW1wb3J0ZWQgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAdmFyIElkZW50aWZpZXJ8U3RyaW5nTGl0ZXJhbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGltcG9ydGVkOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGltcG9ydGVkIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHJldHVybiBJZGVudGlmaWVyfFN0cmluZ0xpdGVyYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEltcG9ydGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmltcG9ydGVkOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGltcG9ydGVkIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHBhcmFtIElkZW50aWZpZXJ8U3RyaW5nTGl0ZXJhbCAkaW1wb3J0ZWQgSW1wb3J0ZWQgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbXBvcnRlZCgkaW1wb3J0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGltcG9ydGVkLCBhcnJheSgiSWRlbnRpZmllciIsICJTdHJpbmdMaXRlcmFsIikpOwogICAgICAgICR0aGlzLT5pbXBvcnRlZCA9ICRpbXBvcnRlZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlIHRocm93IHN0YXRlbWVudC4KICogRm9yIGV4YW1wbGU6IHRocm93IGVycgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUaHJvd1N0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhcmd1bWVudCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgdGhyb3duIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRocm93biBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgdGhyb3duIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGFyZ3VtZW50IFRoZSBub2RlIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudChFeHByZXNzaW9uICRhcmd1bWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXJndW1lbnQgPSAkYXJndW1lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgZm9yLWluIHN0YXRlbWVudC4KICogRm9yIGV4YW1wbGU6IGZvciAodmFyIGEgaW4gYikge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRm9ySW5TdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAicmlnaHQiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogSXRlcmF0aW9uIHZhcmlhYmxlCiAgICAgKiAKICAgICAqIEB2YXIgVmFyaWFibGVEZWNsYXJhdGlvbnxFeHByZXNzaW9ufFBhdHRlcm4KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIEl0ZXJhdGVkIG9iamVjdAogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRyaWdodDsKICAgIAogICAgLyoqCiAgICAgKiBMb29wIGJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpdGVyYXRpb24gdmFyaWFibGUKICAgICAqIAogICAgICogQHJldHVybiBWYXJpYWJsZURlY2xhcmF0aW9ufEV4cHJlc3Npb258UGF0dGVybgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGVmdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sZWZ0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGl0ZXJhdGlvbiB2YXJpYWJsZQogICAgICogCiAgICAgKiBAcGFyYW0gVmFyaWFibGVEZWNsYXJhdGlvbnxFeHByZXNzaW9ufFBhdHRlcm4gJGxlZnQgSXRlcmF0aW9uIHZhcmlhYmxlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlZnQoJGxlZnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRsZWZ0LCBhcnJheSgiVmFyaWFibGVEZWNsYXJhdGlvbiIsICJFeHByZXNzaW9uIiwgIlBhdHRlcm4iKQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmxlZnQgPSAkbGVmdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaXRlcmF0ZWQgb2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaXRlcmF0ZWQgb2JqZWN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRyaWdodCBJdGVyYXRlZCBvYmplY3QKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmlnaHQoRXhwcmVzc2lvbiAkcmlnaHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnJpZ2h0ID0gJHJpZ2h0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb29wIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsb29wIGJvZHkKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudCAkYm9keSBMb29wIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keShTdGF0ZW1lbnQgJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmJvZHkgPSAkYm9keTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIGNsYXNzIGJvZHkuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFByb3BlcnR5RGVmaW5pdGlvbiBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJrZXkiID0+IHRydWUsCiAgICAgICAgInZhbHVlIiA9PiB0cnVlLAogICAgICAgICJjb21wdXRlZCIgPT4gZmFsc2UsCiAgICAgICAgInN0YXRpYyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogUHJvcGVydHkga2V5CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbnxQcml2YXRlSWRlbnRpZmllcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGtleTsKICAgIAogICAgLyoqCiAgICAgKiBPcHRpb25hbCBwcm9wZXJ0eSB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIFByb3BlcnR5IGNvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHByb3BlcnR5IGlzIGRlY2xhcmVkIHVzaW5nCiAgICAgKiB0aGUgc3F1YXJlIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tcHV0ZWQgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eSBzdGF0aWMgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMgZGVjbGFyZWQgc3RhdGljCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRzdGF0aWMgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBrZXkKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+a2V5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb3BlcnR5IGtleQogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbnxQcml2YXRlSWRlbnRpZmllciAka2V5IFByb3BlcnR5IGtleQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLZXkoJGtleSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgka2V5LCBhcnJheSgiRXhwcmVzc2lvbiIsICJQcml2YXRlSWRlbnRpZmllciIpKTsKICAgICAgICAkdGhpcy0+a2V5ID0gJGtleTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9ufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZhbHVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbHVlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9ufG51bGwgJHZhbHVlIFByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkdmFsdWUsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBjb21wdXRlZCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcwogICAgICogZGVjbGFyZWQgdXNpbmcgdGhlIHNxdWFyZSBicmFja2V0cyBzeW50YXgKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21wdXRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wdXRlZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eSBjb21wdXRlZCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcwogICAgICogZGVjbGFyZWQgdXNpbmcgdGhlIHNxdWFyZSBicmFja2V0cyBzeW50YXgKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGNvbXB1dGVkIFByb3BlcnR5IGNvbXB1dGVkIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tcHV0ZWQoJGNvbXB1dGVkKQogICAgewogICAgICAgICR0aGlzLT5jb21wdXRlZCA9IChib29sKSAkY29tcHV0ZWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IHN0YXRpYyBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcwogICAgICogZGVjbGFyZWQgc3RhdGljCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhdGljKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXRpYzsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eSBzdGF0aWMgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMKICAgICAqIGRlY2xhcmVkIHN0YXRpYwogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkc3RhdGljIFByb3BlcnR5IHN0YXRpYyBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0YXRpYygkc3RhdGljKQogICAgewogICAgICAgICR0aGlzLT5zdGF0aWMgPSAoYm9vbCkgJHN0YXRpYzsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBuYW1lc3BhY2UgaW1wb3J0IHNwZWNpZmllci4KICogRm9yIGV4YW1wbGUgIiogYXMgdGVzdCIgaW46IGltcG9ydCAqIGFzIHRlc3QgZnJvbSAidGVzdC5qcyIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEltcG9ydERlZmF1bHRTcGVjaWZpZXIgZXh0ZW5kcyBNb2R1bGVTcGVjaWZpZXIKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgd2l0aCBzdGF0ZW1lbnQuCiAqIEZvciBleGFtcGxlOiB3aXRoICh0ZXN0KSB7fQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBXaXRoU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm9iamVjdCIgPT4gdHJ1ZSwKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgc3RhdGVtZW50IHN1YmplY3QKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9iamVjdDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgc3RhdGVtZW50IGJvZHkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZW1lbnQgc3ViamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9iamVjdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vYmplY3Q7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc3RhdGVtZW50IHN1YmplY3QKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJG9iamVjdCBTdGF0ZW1lbnQgc3ViamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPYmplY3QoRXhwcmVzc2lvbiAkb2JqZWN0KQogICAgewogICAgICAgICR0aGlzLT5vYmplY3QgPSAkb2JqZWN0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZW1lbnQgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGF0ZW1lbnQgYm9keQogICAgICogCiAgICAgKiBAcGFyYW0gU3RhdGVtZW50ICRib2R5IFN0YXRlbWVudCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoU3RhdGVtZW50ICRib2R5KQogICAgewogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBYnN0cmFjdCBjbGFzcyBmb3IgZnVuY3Rpb25zLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBGdW5jdGlvbl8gZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiaWQiID0+IHRydWUsCiAgICAgICAgInBhcmFtcyIgPT4gdHJ1ZSwKICAgICAgICAiYm9keSIgPT4gdHJ1ZSwKICAgICAgICAiZ2VuZXJhdG9yIiA9PiBmYWxzZSwKICAgICAgICAiYXN5bmMiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEZ1bmN0aW9uIG5hbWUKICAgICAqIAogICAgICogQHZhciBJZGVudGlmaWVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGlkOwogICAgCiAgICAvKioKICAgICAqIEZ1bmN0aW9uIHBhcmFtZXRlcnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBQYXR0ZXJuW10gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcGFyYW1zID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBGdW5jdGlvbiBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgQmxvY2tTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBHZW5lcmF0b3IgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgZnVuY3Rpb24gaXMgYSBnZW5lcmF0b3IKICAgICAqIAogICAgICogQHZhciBib29sIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGdlbmVyYXRvciA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIEFzeW5jIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gaXQgaXMgYW4gYXN5bmMgZnVuY3Rpb24KICAgICAqIAogICAgICogQHZhciBib29sIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFzeW5jID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBmdW5jdGlvbiBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBmdW5jdGlvbiBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyICRpZCBGdW5jdGlvbiBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElkKCRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkaWQsICJJZGVudGlmaWVyIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmlkID0gJGlkOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGZ1bmN0aW9uIHBhcmFtZXRlcnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhcmFtcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXJhbXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBmdW5jdGlvbiBwYXJhbWV0ZXJzIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXR0ZXJuW10gJHBhcmFtcyBGdW5jdGlvbiBwYXJhbWV0ZXJzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhcmFtcygkcGFyYW1zKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRwYXJhbXMsICJQYXR0ZXJuIik7CiAgICAgICAgJHRoaXMtPnBhcmFtcyA9ICRwYXJhbXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgZnVuY3Rpb24gYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBmdW5jdGlvbiBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBCbG9ja1N0YXRlbWVudCAkYm9keSBGdW5jdGlvbiBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGJvZHksICJCbG9ja1N0YXRlbWVudCIpOwogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGdlbmVyYXRvciBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBmdW5jdGlvbiBpcyBhIGdlbmVyYXRvcgogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEdlbmVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZW5lcmF0b3I7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZ2VuZXJhdG9yIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGEgZ2VuZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRnZW5lcmF0b3IgR2VuZXJhdG9yIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0R2VuZXJhdG9yKCRnZW5lcmF0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPmdlbmVyYXRvciA9IChib29sKSAkZ2VuZXJhdG9yOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhc3luYyBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIGl0IGlzIGFuIGFzeW5jIGZ1bmN0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXN5bmMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXN5bmM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgYXN5bmMgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiBpdCBpcyBhbiBhc3luYyBmdW5jdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkYXN5bmMgQXN5bmMgZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBc3luYygkYXN5bmMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzeW5jID0gKGJvb2wpICRhc3luYzsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBiaW5hcnkgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IGEgKyBiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEJpbmFyeUV4cHJlc3Npb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImxlZnQiID0+IHRydWUsCiAgICAgICAgIm9wZXJhdG9yIiA9PiBmYWxzZSwKICAgICAgICAicmlnaHQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT3BlcmF0b3IKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRvcGVyYXRvcjsKICAgIAogICAgLyoqCiAgICAgKiBMZWZ0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGVmdDsKICAgIAogICAgLyoqCiAgICAgKiBSaWdodCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJHJpZ2h0OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRvcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBvcGVyYXRvcgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvciBPcGVyYXRvcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcGVyYXRvcigkb3BlcmF0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wZXJhdG9yID0gJG9wZXJhdG9yOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsZWZ0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMZWZ0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxlZnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbGVmdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyICRsZWZ0IExlZnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZWZ0KCRsZWZ0KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRsZWZ0LCBhcnJheSgiRXhwcmVzc2lvbiIsICJQcml2YXRlSWRlbnRpZmllciIpKTsKICAgICAgICAkdGhpcy0+bGVmdCA9ICRsZWZ0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByaWdodCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgUmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSaWdodChFeHByZXNzaW9uICRyaWdodCkKICAgIHsKICAgICAgICAkdGhpcy0+cmlnaHQgPSAkcmlnaHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgZm9yIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRm9yU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImluaXQiID0+IHRydWUsCiAgICAgICAgInRlc3QiID0+IHRydWUsCiAgICAgICAgInVwZGF0ZSIgPT4gdHJ1ZSwKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcgogICAgICogCiAgICAgKiBAdmFyIFZhcmlhYmxlRGVjbGFyYXRpb258RXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGluaXQ7CiAgICAKICAgIC8qKgogICAgICogVGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR0ZXN0OwogICAgCiAgICAvKioKICAgICAqIFVwZGF0ZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR1cGRhdGU7CiAgICAKICAgIC8qKgogICAgICogTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGJvZHk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5pdGlhbGl6ZXIKICAgICAqIAogICAgICogQHJldHVybiBWYXJpYWJsZURlY2xhcmF0aW9ufEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluaXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5pdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbml0aWFsaXplcgogICAgICogCiAgICAgKiBAcGFyYW0gVmFyaWFibGVEZWNsYXJhdGlvbnxFeHByZXNzaW9uICRpbml0IEluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEluaXQoJGluaXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRpbml0LAogICAgICAgICAgICBhcnJheSgiVmFyaWFibGVEZWNsYXJhdGlvbiIsICJFeHByZXNzaW9uIiksCiAgICAgICAgICAgIHRydWUKICAgICAgICApOwogICAgICAgICR0aGlzLT5pbml0ID0gJGluaXQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRlc3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGVzdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0ZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHRlc3QgVGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlc3QoJHRlc3QpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHRlc3QsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnRlc3QgPSAkdGVzdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdXBkYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcGRhdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXBkYXRlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHVwZGF0ZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR1cGRhdGUgVXBkYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXBkYXRlKCR1cGRhdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHVwZGF0ZSwgIkV4cHJlc3Npb24iLCB0cnVlKTsKICAgICAgICAkdGhpcy0+dXBkYXRlID0gJHVwZGF0ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoU3RhdGVtZW50ICRib2R5KQogICAgewogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSByZXN0IGVsZW1lbnQgaW4gYXJyYXkgYmluZGluZyBwYXR0ZXJucyBvciBmdW5jdGlvbgogKiBwYXJhbWV0ZXJzLgogKiBGb3IgZXhhbXBsZSAiLi4ucmVzdCIgaW46IFthLCAuLi5yZXN0XSA9IGIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUmVzdEVsZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgUGF0dGVybgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImFyZ3VtZW50IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBub2RlJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHZhciBQYXR0ZXJuCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gUGF0dGVybgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXR0ZXJuICRhcmd1bWVudCBOb2RlJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoUGF0dGVybiAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50ID0gJGFyZ3VtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIG51bWVyaWMgbGl0ZXJhbC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgTnVtZXJpY0xpdGVyYWwgZXh0ZW5kcyBMaXRlcmFsCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZm9ybWF0IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLy9Gb3JtYXQgY29uc3RhbnRzCiAgICAvKioKICAgICAqIERlY2ltYWwgbnVtYmVyIGZvcm1hdAogICAgICovCiAgICBjb25zdCBERUNJTUFMID0gImRlY2ltYWwiOwogICAgCiAgICAvKioKICAgICAqIEhleGFkZWNpbWFsIG51bWJlciBmb3JtYXQKICAgICAqLwogICAgY29uc3QgSEVYQURFQ0lNQUwgPSAiaGV4YWRlY2ltYWwiOwogICAgCiAgICAvKioKICAgICAqIE9jdGFsIG51bWJlciBmb3JtYXQKICAgICAqLwogICAgY29uc3QgT0NUQUwgPSAib2N0YWwiOwogICAgCiAgICAvKioKICAgICAqIEJpbmFyeSBudW1iZXIgZm9ybWF0CiAgICAgKi8KICAgIGNvbnN0IEJJTkFSWSA9ICJiaW5hcnkiOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyBudW1lcmljIGZvcm1hdAogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJGZvcm1hdCA9IHNlbGY6OkRFQ0lNQUw7CiAgICAKICAgIC8qKgogICAgICogTnVtZXJpYyBmb3JtcyBjb252ZXJzaW9uIHJ1bGVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRmb3JtcyA9IGFycmF5KAogICAgICAgICJiIiA9PiBhcnJheSgKICAgICAgICAgICAgImNoZWNrIiA9PiAiL14wYlswMV0rWzAxX10qJC9pIiwKICAgICAgICAgICAgImNvbnYiID0+ICJiaW5kZWMiLAogICAgICAgICAgICAiZm9ybWF0IiA9PiBzZWxmOjpCSU5BUlkKICAgICAgICApLAogICAgICAgICJvIiA9PiBhcnJheSgKICAgICAgICAgICAgImNoZWNrIiA9PiAiL14wb1swLTddK1swLTdfXSokL2kiLAogICAgICAgICAgICAiY29udiIgPT4gIm9jdGRlYyIsCiAgICAgICAgICAgICJmb3JtYXQiID0+IHNlbGY6Ok9DVEFMCiAgICAgICAgKSwKICAgICAgICAieCIgPT4gYXJyYXkoCiAgICAgICAgICAgICJjaGVjayIgPT4gIi9eMHhbMC05YS1mXStbMC05YS1mX10qJC9pIiwKICAgICAgICAgICAgImNvbnYiID0+ICJoZXhkZWMiLAogICAgICAgICAgICAiZm9ybWF0IiA9PiBzZWxmOjpIRVhBREVDSU1BTAogICAgICAgICksCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBmbG9hdCAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgICR2YWx1ZSA9IChmbG9hdCkgJHZhbHVlOwogICAgICAgICRpbnRWYWx1ZSA9IChpbnQpICR2YWx1ZTsKICAgICAgICBpZiAoJHZhbHVlID09ICRpbnRWYWx1ZSkgewogICAgICAgICAgICAkdmFsdWUgPSAkaW50VmFsdWU7CiAgICAgICAgfQogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKICAgICAgICAvL0ZvcmNlIHJlY2FsY3VsYXRpb24gb2YgdGhlIHJhdyB2YWx1ZQogICAgICAgIHJldHVybiAkdGhpcy0+c2V0Rm9ybWF0KCR0aGlzLT5mb3JtYXQpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHJhdyBSYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICogCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJhdygkcmF3KQogICAgewogICAgICAgICR2YWx1ZSA9ICRyYXc7CiAgICAgICAgJGZvcm1hdCA9IHNlbGY6OkRFQ0lNQUw7CiAgICAgICAgaWYgKGlzX3N0cmluZygkdmFsdWUpICYmICR2YWx1ZSAhPT0gIiIpIHsKICAgICAgICAgICAgLy9IZXhhZGVjaW1hbCwgYmluYXJ5IG9yIG9jdGFsCiAgICAgICAgICAgICRzdGFydFplcm8gPSAkdmFsdWVbMF0gPT09ICIwIjsKICAgICAgICAgICAgJGZvcm0gPSAkc3RhcnRaZXJvICYmIGlzc2V0KCR2YWx1ZVsxXSkgPyBzdHJ0b2xvd2VyKCR2YWx1ZVsxXSkgOiBudWxsOwogICAgICAgICAgICAvL051bWVyaWMgc2VwYXJhdG9yIGNhbm5vdCBhcHBlYXIgYXQgdGhlIGJlZ2lubmluZyBvciBhdCB0aGUgZW5kIG9mIHRoZSBudW1iZXIKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goIi9eX3xfJC8iLCAkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCBudW1lcmljIHZhbHVlIik7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkdGhpcy0+Zm9ybXNbJGZvcm1dKSkgewogICAgICAgICAgICAgICAgJGZvcm1EZWYgPSAkdGhpcy0+Zm9ybXNbJGZvcm1dOwogICAgICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCRmb3JtRGVmWyJjaGVjayJdLCAkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oIkludmFsaWQgIiAuICRmb3JtRGVmWyJmb3JtYXQiXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdHJfcmVwbGFjZSgiXyIsICIiLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgJHZhbHVlID0gJGZvcm1EZWZbImNvbnYiXSgkdmFsdWUpOwogICAgICAgICAgICAgICAgJGZvcm1hdCA9ICRmb3JtRGVmWyJmb3JtYXQiXTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRzdGFydFplcm8gJiYgcHJlZ19tYXRjaCgiL14wWzAtN19dKyQvIiwgJHZhbHVlKSkgewogICAgICAgICAgICAgICAgLy9MZWdhY3kgb2N0YWwgZm9ybQogICAgICAgICAgICAgICAgJHZhbHVlID0gc3RyX3JlcGxhY2UoIl8iLCAiIiwgJHZhbHVlKTsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IG9jdGRlYygkdmFsdWUpOwogICAgICAgICAgICAgICAgJGZvcm1hdCA9IHNlbGY6Ok9DVEFMOwogICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICBwcmVnX21hdGNoKCIvXihbXGRfXSpcLj9bXGRfXSopKD86ZVsrXC1dP1tcZF9dKyk/JC9pIiwgJHZhbHVlLCAkbWF0Y2gpICYmCiAgICAgICAgICAgICAgICAkbWF0Y2hbMV0gIT09ICIiICYmCiAgICAgICAgICAgICAgICAkbWF0Y2hbMV0gIT09ICIuIiAmJgogICAgICAgICAgICAgICAgIXByZWdfbWF0Y2goIi9fZXxlWystXT9ffF8kLyIsICR2YWx1ZSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdHJfcmVwbGFjZSgiXyIsICIiLCAkdmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oIkludmFsaWQgbnVtZXJpYyB2YWx1ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCFpc19pbnQoJHZhbHVlKSAmJiAhaXNfZmxvYXQoJHZhbHVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCBudW1lcmljIHZhbHVlIik7CiAgICAgICAgfQogICAgICAgICR2YWx1ZSA9IChmbG9hdCkgJHZhbHVlOwogICAgICAgICRpbnRWYWx1ZSA9IChpbnQpICR2YWx1ZTsKICAgICAgICBpZiAoJHZhbHVlID09ICRpbnRWYWx1ZSkgewogICAgICAgICAgICAkdmFsdWUgPSAkaW50VmFsdWU7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5mb3JtYXQgPSAkZm9ybWF0OwogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKICAgICAgICAkdGhpcy0+cmF3ID0gJHJhdzsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgbnVtZXJpYyBmb3JtYXQKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mb3JtYXQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgbnVtZXJpYyBmb3JtYXQKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybWF0IEZvcm1hdCwgb25lIG9mIHRoZSBmb3JtYXQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZvcm1hdCgkZm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5mb3JtYXQgPSAkZm9ybWF0OwogICAgICAgIHN3aXRjaCAoJGZvcm1hdCkgewogICAgICAgICAgICBjYXNlIHNlbGY6OkJJTkFSWToKICAgICAgICAgICAgICAgICR0aGlzLT5yYXcgPSAiMGIiIC4gZGVjYmluKCR0aGlzLT52YWx1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHNlbGY6Ok9DVEFMOgogICAgICAgICAgICAgICAgJHRoaXMtPnJhdyA9ICIwbyIgLiBkZWNvY3QoJHRoaXMtPnZhbHVlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6SEVYQURFQ0lNQUw6CiAgICAgICAgICAgICAgICAkdGhpcy0+cmF3ID0gIjB4IiAuIGRlY2hleCgkdGhpcy0+dmFsdWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICR0aGlzLT5yYXcgPSAoc3RyaW5nKSAkdGhpcy0+dmFsdWU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSB1bmFyeSBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogIWEKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVW5hcnlFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhcmd1bWVudCIgPT4gdHJ1ZSwKICAgICAgICAib3BlcmF0b3IiID0+IGZhbHNlLAogICAgICAgICJwcmVmaXgiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEV4cHJlc3Npb24ncyBvcGVyYXRvcgogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwogICAgCiAgICAvKioKICAgICAqIFByZWZpeCBmbGFnIHRoYXQgaXMgYWx3YXlzIHRydWUgc2luY2UgdGhlIG9wZXJhdG9yIHByZWNlZGVzIHRoZSBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmVmaXggPSB0cnVlOwogICAgCiAgICAvKioKICAgICAqIEV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRvcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3Mgb3BlcmF0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkb3BlcmF0b3IgT3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJlZml4IGZsYWcgdGhhdCBpcyBhbHdheXMgdHJ1ZSBzaW5jZSB0aGUgb3BlcmF0b3IgcHJlY2VkZXMKICAgICAqIHRoZSBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZWZpeCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcmVmaXg7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGhpcyBtZXRob2QgZG9lcyBub3RoaW5nIHNpbmNlIHRoZSBwcmVmaXggZmxhZyBpcyBhbHdheXMgdHJ1ZSBmb3IKICAgICAqIHVuYXJ5IGV4cHJlc3Npb25zCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRwcmVmaXggUHJlZml4IGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmaXgoJHByZWZpeCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbidzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRhcmd1bWVudCBBcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudChFeHByZXNzaW9uICRhcmd1bWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXJndW1lbnQgPSAkYXJndW1lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdHJ5LWNhdGNoIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVHJ5U3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImJsb2NrIiA9PiB0cnVlLAogICAgICAgICJoYW5kbGVyIiA9PiB0cnVlLAogICAgICAgICJmaW5hbGl6ZXIiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogV3JhcHBlZCBibG9jawogICAgICogCiAgICAgKiBAdmFyIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkYmxvY2s7CiAgICAKICAgIC8qKgogICAgICogQ2F0Y2ggY2xhdXNlCiAgICAgKiAKICAgICAqIEB2YXIgQ2F0Y2hDbGF1c2UgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaGFuZGxlcjsKICAgIAogICAgLyoqCiAgICAgKiAiZmluYWxseSIgYmxvY2sKICAgICAqIAogICAgICogQHZhciBCbG9ja1N0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRmaW5hbGl6ZXI7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBibG9jawogICAgICogCiAgICAgKiBAcmV0dXJuIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCbG9jaygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ibG9jazsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB3cmFwcGVkIGJsb2NrCiAgICAgKiAKICAgICAqIEBwYXJhbSBCbG9ja1N0YXRlbWVudCAkYmxvY2sgV3JhcHBlZCBibG9jawogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCbG9jayhCbG9ja1N0YXRlbWVudCAkYmxvY2spCiAgICB7CiAgICAgICAgJHRoaXMtPmJsb2NrID0gJGJsb2NrOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiBDYXRjaENsYXVzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGFuZGxlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYW5kbGVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNhdGNoIGNsYXVzZQogICAgICogCiAgICAgKiBAcGFyYW0gQ2F0Y2hDbGF1c2UgJGhhbmRsZXIgQ2F0Y2ggY2xhdXNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhhbmRsZXIoJGhhbmRsZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGhhbmRsZXIsICJDYXRjaENsYXVzZSIsIHRydWUpOwogICAgICAgICR0aGlzLT5oYW5kbGVyID0gJGhhbmRsZXI7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlICJmaW5hbGx5IiBibG9jawogICAgICogCiAgICAgKiBAcmV0dXJuIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaW5hbGl6ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmluYWxpemVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlICJmaW5hbGx5IiBibG9jawogICAgICogCiAgICAgKiBAcGFyYW0gQmxvY2tTdGF0ZW1lbnQgJGZpbmFsaXplciBUaGUgImZpbmFsbHkiIGJsb2NrCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZpbmFsaXplcigkZmluYWxpemVyKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRmaW5hbGl6ZXIsICJCbG9ja1N0YXRlbWVudCIsIHRydWUpOwogICAgICAgICR0aGlzLT5maW5hbGl6ZXIgPSAkZmluYWxpemVyOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfQo8P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBkZWZhdWx0IGltcG9ydCBzcGVjaWZpZXIuCiAqIEZvciBleGFtcGxlICJ0ZXN0IiBpbjogaW1wb3J0IHRlc3QgZnJvbSAidGVzdC5qcyIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEltcG9ydE5hbWVzcGFjZVNwZWNpZmllciBleHRlbmRzIE1vZHVsZVNwZWNpZmllcgp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gYXdhaXQgZXhwcmVzc2lvbi4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQXdhaXRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhcmd1bWVudCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgQXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoRXhwcmVzc2lvbiAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50ID0gJGFyZ3VtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBleHBvcnQgbmFtZWQgZGVjbGFyYXRpb24uCiAqIEZvciBleGFtcGxlOiBleHBvcnQge2Zvb30gZnJvbSAiYmFyIgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBFeHBvcnROYW1lZERlY2xhcmF0aW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIE1vZHVsZURlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZGVjbGFyYXRpb24iID0+IHRydWUsCiAgICAgICAgInNwZWNpZmllcnMiID0+IHRydWUsCiAgICAgICAgInNvdXJjZSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHBvcnRlZCBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAdmFyIERlY2xhcmF0aW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGRlY2xhcmF0aW9uOwogICAgCiAgICAvKioKICAgICAqIEV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHZhciBFeHBvcnRTcGVjaWZpZXJbXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRzcGVjaWZpZXJzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgZXhwb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAdmFyIExpdGVyYWwgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRGVjbGFyYXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlY2xhcmF0aW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBEZWNsYXJhdGlvbiAkZGVjbGFyYXRpb24gRXhwb3J0ZWQgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjbGFyYXRpb24oJGRlY2xhcmF0aW9uKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRkZWNsYXJhdGlvbiwgIkRlY2xhcmF0aW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmRlY2xhcmF0aW9uID0gJGRlY2xhcmF0aW9uOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHJldHVybiBFeHBvcnRTcGVjaWZpZXJbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3BlY2lmaWVycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zcGVjaWZpZXJzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHBhcmFtIEV4cG9ydFNwZWNpZmllcltdICRzcGVjaWZpZXJzIEV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3BlY2lmaWVycygkc3BlY2lmaWVycykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkc3BlY2lmaWVycywgIkV4cG9ydFNwZWNpZmllciIpOwogICAgICAgICR0aGlzLT5zcGVjaWZpZXJzID0gJHNwZWNpZmllcnM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHJldHVybiBMaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHBhcmFtIExpdGVyYWwgJHNvdXJjZSBFeHBvcnQgc291cmNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZSgkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRzb3VyY2UsICJMaXRlcmFsIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnNvdXJjZSA9ICRzb3VyY2U7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFycmF5IGxpdGVyYWwuCiAqIEZvciBleGFtcGxlOiBbYSwgYiwgY10KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQXJyYXlFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJlbGVtZW50cyIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBBcnJheSBlbGVtZW50cwogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10KICAgICAqLwogICAgcHJvdGVjdGVkICRlbGVtZW50cyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhcnJheSBlbGVtZW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVsZW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVsZW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgYXJyYXkgZWxlbWVudHMKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10gJGVsZW1lbnRzIEFycmF5IGVsZW1lbnRzIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbGVtZW50cygkZWxlbWVudHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoCiAgICAgICAgICAgICRlbGVtZW50cywKICAgICAgICAgICAgYXJyYXkoIkV4cHJlc3Npb24iLCAiU3ByZWFkRWxlbWVudCIpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZWxlbWVudHMgPSAkZWxlbWVudHM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgZnVuY3Rpb24gZGVjbGFyYXRpb24KICogRm9yIGV4YW1wbGU6IGZ1bmN0aW9uIHRlc3QgKCkge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRnVuY3Rpb25EZWNsYXJhdGlvbiBleHRlbmRzIEZ1bmN0aW9uXyBpbXBsZW1lbnRzIERlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogU2V0cyB0aGUgZnVuY3Rpb24gaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkaWQgRnVuY3Rpb24gaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZCgkaWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGlkLCAiSWRlbnRpZmllciIpOwogICAgICAgICR0aGlzLT5pZCA9ICRpZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBtZXRhIHByb3BlcnR5LgogKiBGb3IgZXhhbXBsZTogbmV3LnRhcmdldAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBNZXRhUHJvcGVydHkgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm1ldGEiID0+IGZhbHNlLAogICAgICAgICJwcm9wZXJ0eSIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogU3ViamVjdAogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRtZXRhOwogICAgCiAgICAvKioKICAgICAqIFByb3BlcnR5CiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnR5OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN1YmplY3QKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1ldGEoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWV0YTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdWJqZWN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1ldGEgU3ViamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNZXRhKCRtZXRhKQogICAgewogICAgICAgICR0aGlzLT5tZXRhID0gJG1ldGE7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9wZXJ0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9wZXJ0eTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcm9wZXJ0eSBQcm9wZXJ0eQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm9wZXJ0eSgkcHJvcGVydHkpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb3BlcnR5ID0gJHByb3BlcnR5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBpZiBzdGF0ZW1lbnQuCiAqIEZvciBleGFtcGxlOiBpZiAodGVzdCkge30gZWxzZSB7fQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBJZlN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJ0ZXN0IiA9PiB0cnVlLAogICAgICAgICJjb25zZXF1ZW50IiA9PiB0cnVlLAogICAgICAgICJhbHRlcm5hdGUiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdGVzdDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgc3RhdGVtZW50IHRoYXQgaXMgYWN0aXZhdGVkIGlmIHRoZSB0ZXN0IGV4cHJlc3Npb24gaXMgdHJ1ZQogICAgICogCiAgICAgKiBAdmFyIFN0YXRlbWVudHxGdW5jdGlvbkRlY2xhcmF0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uc2VxdWVudDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgImVsc2UiIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAdmFyIFN0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRhbHRlcm5hdGU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkdGVzdCBUZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVzdChFeHByZXNzaW9uICR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YXRlbWVudCB0aGF0IGlzIGFjdGl2YXRlZCBpZiB0aGUgdGVzdCBleHByZXNzaW9uIGlzIHRydWUKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnR8RnVuY3Rpb25EZWNsYXJhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uc2VxdWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25zZXF1ZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHN0YXRlbWVudCB0aGF0IGlzIGFjdGl2YXRlZCBpZiB0aGUgdGVzdCBleHByZXNzaW9uIGlzIHRydWUKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudHxGdW5jdGlvbkRlY2xhcmF0aW9uICRjb25zZXF1ZW50IFRoZSBjb25zZXF1ZW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgKICAgICAgICAgICAgJGNvbnNlcXVlbnQsCiAgICAgICAgICAgIGFycmF5KCJTdGF0ZW1lbnQiLCAiRnVuY3Rpb25EZWNsYXJhdGlvbiIpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+Y29uc2VxdWVudCA9ICRjb25zZXF1ZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSAiZWxzZSIgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbHRlcm5hdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWx0ZXJuYXRlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlICJlbHNlIiBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudHxGdW5jdGlvbkRlY2xhcmF0aW9uICRhbHRlcm5hdGUgVGhlICJlbHNlIiBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWx0ZXJuYXRlKCRhbHRlcm5hdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRhbHRlcm5hdGUsCiAgICAgICAgICAgIGFycmF5KCJTdGF0ZW1lbnQiLCAiRnVuY3Rpb25EZWNsYXJhdGlvbiIpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+YWx0ZXJuYXRlID0gJGFsdGVybmF0ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjbGFzcyBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGU6IGNsYXNzIHRlc3Qge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ2xhc3NEZWNsYXJhdGlvbiBleHRlbmRzIENsYXNzXyBpbXBsZW1lbnRzIERlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2xhc3MgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkaWQgQ2xhc3MgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZCgkaWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGlkLCAiSWRlbnRpZmllciIpOwogICAgICAgICR0aGlzLT5pZCA9ICRpZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBkZWNsYXJhdGlvbiBpbiBhIFZhcmlhYmxlRGVjbGFyYXRpb24gbm9kZS4KICogRm9yIGV4YW1wbGUgImE9MSIgaW46IHZhciBhID0gMQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBWYXJpYWJsZURlY2xhcmF0b3IgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiaWQiID0+IHRydWUsCiAgICAgICAgImluaXQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogRGVjbGFyYXRpb24gaWRlbnRpZmllciBvciBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEB2YXIgUGF0dGVybiAKICAgICAqLwogICAgcHJvdGVjdGVkICRpZDsKICAgIAogICAgLyoqCiAgICAgKiBPcHRpb25hbCBpbml0aWFsaXplcgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5pdDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWNsYXJhdGlvbiBpZGVudGlmaWVyIG9yIHBhdHRlcm4KICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZWNsYXJhdGlvbiBpZGVudGlmaWVyIG9yIHBhdHRlcm4KICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm4gJGlkIERlY2xhcmF0aW9uIGlkZW50aWZpZXIgb3IgcGF0dGVybgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZChQYXR0ZXJuICRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5pdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbml0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRpbml0IEluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEluaXQoJGluaXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGluaXQsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmluaXQgPSAkaW5pdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBwcml2YXRlIGlkZW50aWZpZXIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFByaXZhdGVJZGVudGlmaWVyIGV4dGVuZHMgTm9kZQp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm5hbWUiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBpZGVudGlmaWVyJ3MgbmFtZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJG5hbWU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaWRlbnRpZmllcidzIG5hbWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmFtZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpZGVudGlmaWVyJ3MgbmFtZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBuYW1lIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcSWRlbnRpZmllcjsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIGlkZW50aWZpZXIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWElkZW50aWZpZXIgZXh0ZW5kcyBJZGVudGlmaWVyCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBhdHRyaWJ1dGUuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEF0dHJpYnV0ZSBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJuYW1lIiA9PiB0cnVlLAogICAgICAgICJ2YWx1ZSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgbmFtZQogICAgICogCiAgICAgKiBAdmFyIEpTWElkZW50aWZpZXJ8SlNYTmFtZXNwYWNlZE5hbWUKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwogICAgCiAgICAvKioKICAgICAqIEF0dHJpYnV0ZSB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZSBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyfEpTWE5hbWVzcGFjZWROYW1lICRuYW1lIEF0dHJpYnV0ZSBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJG5hbWUsIGFycmF5KCJKU1hcXEpTWElkZW50aWZpZXIiLCAiSlNYXFxKU1hOYW1lc3BhY2VkTmFtZSIpKTsKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBOb2RlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZhbHVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbHVlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZSB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gTm9kZXxudWxsICR2YWx1ZSBBdHRyaWJ1dGUgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKAogICAgICAgICAgICAkdmFsdWUsCiAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgIkxpdGVyYWwiLCAiSlNYXFxKU1hFeHByZXNzaW9uQ29udGFpbmVyIiwKICAgICAgICAgICAgICAgICJKU1hcXEpTWEVsZW1lbnQiLCAiSlNYXFxKU1hGcmFnbWVudCIKICAgICAgICAgICAgKSwKICAgICAgICAgICAgdHJ1ZQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXFNwcmVhZEVsZW1lbnQ7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBzcHJlYWQgYXR0cmlidXRlLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBKU1hTcHJlYWRBdHRyaWJ1dGUgZXh0ZW5kcyBTcHJlYWRFbGVtZW50CnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggY2xvc2luZyBlbGVtZW50IHRhZy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYQ2xvc2luZ0VsZW1lbnQgZXh0ZW5kcyBKU1hCb3VuZGFyeUVsZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGV4cHJlc3Npb24gY29udGFpbmVyIGluIEpTWC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYRXhwcmVzc2lvbkNvbnRhaW5lciBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBcUGVhc3RcU3ludGF4XE5vZGVcRXhwcmVzc2lvbnxKU1hFbXB0eUV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9uOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9ufEpTWEVtcHR5RXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHByZXNzaW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gXFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb258SlNYRW1wdHlFeHByZXNzaW9uICRleHByZXNzaW9uIFdyYXBwZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKCRleHByZXNzaW9uKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKAogICAgICAgICAgICAkZXhwcmVzc2lvbiwKICAgICAgICAgICAgYXJyYXkoIkV4cHJlc3Npb24iLCAiSlNYXFxKU1hFbXB0eUV4cHJlc3Npb24iKQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAkZXhwcmVzc2lvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwp1c2UgUGVhc3RcU3ludGF4XE5vZGVcRXhwcmVzc2lvbjsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgc3ByZWFkIGNoaWxkIGV4cHJlc3Npb24gaW4gSlNYLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBKU1hTcHJlYWRDaGlsZCBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXhwcmVzc2lvbjsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRleHByZXNzaW9uIFdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gJGV4cHJlc3Npb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAkZXhwcmVzc2lvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggY2xvc2luZyBmcmFnbWVudCB0YWcuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWFRleHQgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidmFsdWUiID0+IGZhbHNlLAogICAgICAgICJyYXciID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIG1peGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdmFsdWU7CiAgICAKICAgIC8qKgogICAgICogTm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJHJhdzsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dmFsdWUgPSAkdmFsdWU7CiAgICAgICAgJHRoaXMtPnJhdyA9ICR2YWx1ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIG5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJhdygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yYXc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkcmF3IFJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSYXcoJHJhdykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNldFZhbHVlKCRyYXcpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIG9wZW5pbmcgZnJhZ21lbnQgdGFnLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBKU1hPcGVuaW5nRnJhZ21lbnQgZXh0ZW5kcyBOb2RlCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CnVzZSBQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9uOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggZnJhZ21lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEZyYWdtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJvcGVuaW5nRnJhZ21lbnQiID0+IHRydWUsCiAgICAgICAgImNoaWxkcmVuIiA9PiB0cnVlLAogICAgICAgICJjbG9zaW5nRnJhZ21lbnQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT3BlbmluZyBmcmFnbWVudCBub2RlCiAgICAgKiAKICAgICAqIEB2YXIgSlNYT3BlbmluZ0ZyYWdtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlbmluZ0ZyYWdtZW50OwogICAgCiAgICAvKioKICAgICAqIENoaWxkcmVuIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgTm9kZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY2hpbGRyZW4gPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIENsb3NpbmcgZnJhZ21lbnQgbm9kZQogICAgICogCiAgICAgKiBAdmFyIEpTWENsb3NpbmdGcmFnbWVudAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNsb3NpbmdGcmFnbWVudDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBvcGVuaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBKU1hPcGVuaW5nRnJhZ21lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZW5pbmdGcmFnbWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVuaW5nRnJhZ21lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3BlbmluZyBmcmFnbWVudCBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hPcGVuaW5nRnJhZ21lbnQgJG9wZW5pbmdGcmFnbWVudCBPcGVuaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlbmluZ0ZyYWdtZW50KEpTWE9wZW5pbmdGcmFnbWVudCAkb3BlbmluZ0ZyYWdtZW50KQogICAgewogICAgICAgICR0aGlzLT5vcGVuaW5nRnJhZ21lbnQgPSAkb3BlbmluZ0ZyYWdtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZHJlbiBub2RlcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2hpbGRyZW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hpbGRyZW47CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIE5vZGVbXSAkY2hpbGRyZW4gQ2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2hpbGRyZW4oJGNoaWxkcmVuKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjaGlsZHJlbiwgYXJyYXkoCiAgICAgICAgICAgICJKU1hcXEpTWFRleHQiLCAiSlNYXFxKU1hFeHByZXNzaW9uQ29udGFpbmVyIiwgIkpTWFxcSlNYU3ByZWFkQ2hpbGQiLAogICAgICAgICAgICAiSlNYXFxKU1hFbGVtZW50IiwgIkpTWFxcSlNYRnJhZ21lbnQiCiAgICAgICAgKSk7CiAgICAgICAgJHRoaXMtPmNoaWxkcmVuID0gJGNoaWxkcmVuOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjbG9zaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBKU1hDbG9zaW5nRnJhZ21lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENsb3NpbmdGcmFnbWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jbG9zaW5nRnJhZ21lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2xvc2luZyBmcmFnbWVudCBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hDbG9zaW5nRnJhZ21lbnQgJGNsb3NpbmdGcmFnbWVudCBDbG9zaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2xvc2luZ0ZyYWdtZW50KEpTWENsb3NpbmdGcmFnbWVudCAkY2xvc2luZ0ZyYWdtZW50KQogICAgewogICAgICAgICR0aGlzLT5jbG9zaW5nRnJhZ21lbnQgPSAkY2xvc2luZ0ZyYWdtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBjbG9zaW5nIGZyYWdtZW50IHRhZy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYQ2xvc2luZ0ZyYWdtZW50IGV4dGVuZHMgTm9kZQp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwp1c2UgUGVhc3RcU3ludGF4XE5vZGVcRXhwcmVzc2lvbjsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIGVsZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEVsZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm9wZW5pbmdFbGVtZW50IiA9PiB0cnVlLAogICAgICAgICJjaGlsZHJlbiIgPT4gdHJ1ZSwKICAgICAgICAiY2xvc2luZ0VsZW1lbnQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT3BlbmluZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHZhciBKU1hPcGVuaW5nRWxlbWVudAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZW5pbmdFbGVtZW50OwogICAgCiAgICAvKioKICAgICAqIENoaWxkcmVuIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgTm9kZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY2hpbGRyZW4gPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIENsb3NpbmcgZWxlbWVudCBub2RlCiAgICAgKiAKICAgICAqIEB2YXIgSlNYQ2xvc2luZ0VsZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNsb3NpbmdFbGVtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wZW5pbmcgZWxlbWVudCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYT3BlbmluZ0VsZW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZW5pbmdFbGVtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZW5pbmdFbGVtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG9wZW5pbmcgZWxlbWVudCBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hPcGVuaW5nRWxlbWVudCAkb3BlbmluZ0VsZW1lbnQgT3BlbmluZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlbmluZ0VsZW1lbnQoSlNYT3BlbmluZ0VsZW1lbnQgJG9wZW5pbmdFbGVtZW50KQogICAgewogICAgICAgICR0aGlzLT5vcGVuaW5nRWxlbWVudCA9ICRvcGVuaW5nRWxlbWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBOb2RlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoaWxkcmVuKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNoaWxkcmVuOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNoaWxkcmVuIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlW10gJGNoaWxkcmVuIENoaWxkcmVuIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENoaWxkcmVuKCRjaGlsZHJlbikKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkY2hpbGRyZW4sIGFycmF5KAogICAgICAgICAgICAiSlNYXFxKU1hUZXh0IiwgIkpTWFxcSlNYRXhwcmVzc2lvbkNvbnRhaW5lciIsICJKU1hcXEpTWFNwcmVhZENoaWxkIiwKICAgICAgICAgICAgIkpTWFxcSlNYRWxlbWVudCIsICJKU1hcXEpTWEZyYWdtZW50IgogICAgICAgICkpOwogICAgICAgICR0aGlzLT5jaGlsZHJlbiA9ICRjaGlsZHJlbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2xvc2luZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBKU1hDbG9zaW5nRWxlbWVudHxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDbG9zaW5nRWxlbWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jbG9zaW5nRWxlbWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjbG9zaW5nIGVsZW1lbnQgbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gSlNYQ2xvc2luZ0VsZW1lbnR8bnVsbCAkY2xvc2luZ0VsZW1lbnQgQ2xvc2luZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2xvc2luZ0VsZW1lbnQoJGNsb3NpbmdFbGVtZW50KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRjbG9zaW5nRWxlbWVudCwgIkpTWFxcSlNYQ2xvc2luZ0VsZW1lbnQiLCB0cnVlKTsKICAgICAgICAkdGhpcy0+Y2xvc2luZ0VsZW1lbnQgPSAkY2xvc2luZ0VsZW1lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIGVtcHR5IGV4cHJlc3Npb24uCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEVtcHR5RXhwcmVzc2lvbiBleHRlbmRzIE5vZGUKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb247CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBuYW1lc3BhY2VkIG5hbWUuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWE5hbWVzcGFjZWROYW1lIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJuYW1lc3BhY2UiID0+IGZhbHNlLAogICAgICAgICJuYW1lIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgbmFtZXNwYWNlCiAgICAgKiAKICAgICAqIEB2YXIgSlNYSWRlbnRpZmllcgogICAgICovCiAgICBwcm90ZWN0ZWQgJG5hbWVzcGFjZTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgbmFtZQogICAgICogCiAgICAgKiBAdmFyIEpTWElkZW50aWZpZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgbm9kZSdzIG5hbWVzcGFjZQogICAgICogCiAgICAgKiBAcmV0dXJuIEpTWElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWVzcGFjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lc3BhY2U7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgbmFtZXNwYWNlCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyICRuYW1lc3BhY2UgTmFtZXNwYWNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWVzcGFjZSgkbmFtZXNwYWNlKQogICAgewogICAgICAgICR0aGlzLT5uYW1lc3BhY2UgPSAkbmFtZXNwYWNlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gbm9kZSdzIG5hbWUKICAgICAqIAogICAgICogQHJldHVybiBKU1hJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgbmFtZQogICAgICogCiAgICAgKiBAcGFyYW0gSlNYSWRlbnRpZmllciAkbmFtZSBOYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWUgPSAkbmFtZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIG9wZW5pbmcgZWxlbWVudCB0YWcuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWE9wZW5pbmdFbGVtZW50IGV4dGVuZHMgSlNYQm91bmRhcnlFbGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXR0cmlidXRlcyIgPT4gdHJ1ZSwKICAgICAgICAic2VsZkNsb3NpbmciID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIENoaWxkcmVuIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgSlNYQXR0cmlidXRlW118SlNYU3ByZWFkQXR0cmlidXRlW10KICAgICAqLwogICAgcHJvdGVjdGVkICRhdHRyaWJ1dGVzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBTZWxmIGNsb3NpbmcgdGFnIG1vZGUKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2VsZkNsb3NpbmcgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZHJlbiBhdHRyaWJ1dGVzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYQXR0cmlidXRlW118SlNYU3ByZWFkQXR0cmlidXRlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF0dHJpYnV0ZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXR0cmlidXRlczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhdHRyaWJ1dGVzIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hBdHRyaWJ1dGVbXXxKU1hTcHJlYWRBdHRyaWJ1dGVbXSAkYXR0cmlidXRlcyBBdHRyaWJ1dGVzIG5vZGVzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF0dHJpYnV0ZXMoJGF0dHJpYnV0ZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGF0dHJpYnV0ZXMsIGFycmF5KAogICAgICAgICAgICAiSlNYXFxKU1hBdHRyaWJ1dGUiLCAiSlNYXFxKU1hTcHJlYWRBdHRyaWJ1dGUiCiAgICAgICAgKSk7CiAgICAgICAgJHRoaXMtPmF0dHJpYnV0ZXMgPSAkYXR0cmlidXRlczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2VsZiBjbG9zaW5nIHRhZyBtb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2VsZkNsb3NpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2VsZkNsb3Npbmc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc2VsZiBjbG9zaW5nIHRhZyBtb2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRzZWxmQ2xvc2luZyBTZWxmIGNsb3NpbmcgdGFnIG1vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U2VsZkNsb3NpbmcoJHNlbGZDbG9zaW5nKQogICAgewogICAgICAgICR0aGlzLT5zZWxmQ2xvc2luZyA9IChib29sKSAkc2VsZkNsb3Npbmc7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIGJhc2UgY2xhc3MgZm9yIGJvdW5kYXJ5IGVsZW1lbnRzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIEpTWEJvdW5kYXJ5RWxlbWVudCBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJuYW1lIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEVsZW1lbnQgbmFtZQogICAgICogCiAgICAgKiBAdmFyIEpTWElkZW50aWZpZXJ8SlNYTWVtYmVyRXhwcmVzc2lvbnxKU1hOYW1lc3BhY2VkTmFtZQogICAgICovCiAgICBwcm90ZWN0ZWQgJG5hbWU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYSWRlbnRpZmllcnxKU1hNZW1iZXJFeHByZXNzaW9ufEpTWE5hbWVzcGFjZWROYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZWxlbWVudCBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyfEpTWE1lbWJlckV4cHJlc3Npb258SlNYTmFtZXNwYWNlZE5hbWUgJG5hbWUgRWxlbWVudAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICBhcnJheSgiSlNYXFxKU1hJZGVudGlmaWVyIiwgIkpTWFxcSlNYTWVtYmVyRXhwcmVzc2lvbiIsICJKU1hcXEpTWE5hbWVzcGFjZWROYW1lIikKICAgICAgICApOwogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb247CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBtZW1iZXIgZXhwcmVzc2lvbi4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYTWVtYmVyRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAib2JqZWN0IiA9PiB0cnVlLAogICAgICAgICJwcm9wZXJ0eSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEB2YXIgSlNYTWVtYmVyRXhwcmVzc2lvbnxKU1hJZGVudGlmaWVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9iamVjdDsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgcHJvcGVydHkKICAgICAqIAogICAgICogQHZhciBKU1hJZGVudGlmaWVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydHk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIG9iamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuIEpTWE1lbWJlckV4cHJlc3Npb258SlNYSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T2JqZWN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9iamVjdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hNZW1iZXJFeHByZXNzaW9ufEpTWElkZW50aWZpZXIgJG9iamVjdCBPYmplY3QKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T2JqZWN0KCRvYmplY3QpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJG9iamVjdCwgYXJyYXkoIkpTWFxcSlNYTWVtYmVyRXhwcmVzc2lvbiIsICJKU1hcXEpTWElkZW50aWZpZXIiKSk7CiAgICAgICAgJHRoaXMtPm9iamVjdCA9ICRvYmplY3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBwcm9wZXJ0eQogICAgICogCiAgICAgKiBAcmV0dXJuIEpTWElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3BlcnR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb3BlcnR5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb24ncyBwcm9wZXJ0eQogICAgICogCiAgICAgKiBAcGFyYW0gSlNYSWRlbnRpZmllciAkcHJvcGVydHkgUHJvcGVydHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvcGVydHkoSlNYSWRlbnRpZmllciAkcHJvcGVydHkpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb3BlcnR5ID0gJHByb3BlcnR5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIG1ldGhvZCBkZWNsYXJhdGlvbiBpbiBjbGFzc2VzIGFuZCBvYmplY3QgbGl0ZXJhbHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIE1ldGhvZERlZmluaXRpb24gZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAia2V5IiA9PiB0cnVlLAogICAgICAgICJ2YWx1ZSIgPT4gdHJ1ZSwKICAgICAgICAia2luZCIgPT4gZmFsc2UsCiAgICAgICAgImNvbXB1dGVkIiA9PiBmYWxzZSwKICAgICAgICAic3RhdGljIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLy9LaW5kIGNvbnN0YW50cwogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBtZXRob2QKICAgICAqLwogICAgY29uc3QgS0lORF9DT05TVFJVQ1RPUiA9ICJjb25zdHJ1Y3RvciI7CiAgICAKICAgIC8qKgogICAgICogU3RhbmRhcmQgbWV0aG9kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfTUVUSE9EID0gIm1ldGhvZCI7CiAgICAKICAgIC8qKgogICAgICogR2V0dGVyIG1ldGhvZAogICAgICovCiAgICBjb25zdCBLSU5EX0dFVCA9ICJnZXQiOwogICAgCiAgICAvKioKICAgICAqIFNldHRlciBtZXRob2QKICAgICAqLwogICAgY29uc3QgS0lORF9TRVQgPSAic2V0IjsKICAgIAogICAgLyoqCiAgICAgKiBNZXRob2QncyBrZXkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2V5OwogICAgCiAgICAvKioKICAgICAqIE1ldGhvZCdzIHZhbHVlCiAgICAgKiAKICAgICAqIEB2YXIgRnVuY3Rpb25FeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIE1ldGhvZCdzIGtpbmQgdGhhdCBpcyBvbmUgb2YgdGhlIGtpbmQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGtpbmQgPSBzZWxmOjpLSU5EX01FVEhPRDsKICAgIAogICAgLyoqCiAgICAgKiBDb21wdXRlZCBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiBtZXRob2QncyBrZXkgaXMgZGVjbGFyZWQgdXNpbmcgc3F1YXJlCiAgICAgKiBicmFja2V0cyBzeW50YXgKICAgICAqIAogICAgICogQHZhciBib29sIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbXB1dGVkID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogU3RhdGljIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBtZXRob2QgaXMgc3RhdGljCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRzdGF0aWMgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtZXRob2QncyBrZXkKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+a2V5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1ldGhvZCdzIGtleQogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbnxQcml2YXRlSWRlbnRpZmllciAka2V5IE1ldGhvZCdzIGtleQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLZXkoJGtleSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgka2V5LCBhcnJheSgiRXhwcmVzc2lvbiIsICJQcml2YXRlSWRlbnRpZmllciIpKTsKICAgICAgICAkdGhpcy0+a2V5ID0gJGtleTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWV0aG9kJ3MgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBGdW5jdGlvbkV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZhbHVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbHVlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1ldGhvZCdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBGdW5jdGlvbkV4cHJlc3Npb24gJHZhbHVlIE1ldGhvZCdzIHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKEZ1bmN0aW9uRXhwcmVzc2lvbiAkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtZXRob2QncyBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2luZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5raW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1ldGhvZCdzIGtpbmQgdGhhdCBpcyBvbmUgb2YgdGhlIGtpbmQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtpbmQgTWV0aG9kJ3Mga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgICR0aGlzLT5raW5kID0gJGtpbmQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIGlmIG1ldGhvZCdzIGtleSBpcyBkZWNsYXJlZCB1c2luZwogICAgICogc3F1YXJlIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXB1dGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXB1dGVkOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIGlmIG1ldGhvZCdzIGtleSBpcyBkZWNsYXJlZCB1c2luZwogICAgICogc3F1YXJlIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkY29tcHV0ZWQgQ29tcHV0ZWQgZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb21wdXRlZCgkY29tcHV0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXB1dGVkID0gKGJvb2wpICRjb21wdXRlZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3RhdGljIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBtZXRob2QgaXMgc3RhdGljCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhdGljKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnsic3RhdGljIn07CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc3RhdGljIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBtZXRob2QgaXMgc3RhdGljCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRzdGF0aWMgU3RhdGljIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3RhdGljKCRzdGF0aWMpCiAgICB7CiAgICAgICAgJHRoaXMtPnsic3RhdGljIn0gPSAoYm9vbCkgJHN0YXRpYzsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gZXhwcmVzc2lvbiBzdGF0ZW1lbnQgYW5kIHdyYXBzIGFub3RoZXIgZXhwcmVzc2lvbi4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRXhwcmVzc2lvblN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXhwcmVzc2lvbjsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRleHByZXNzaW9uIFdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gJGV4cHJlc3Npb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAkZXhwcmVzc2lvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjbGFzcyBib2R5LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDbGFzc0JvZHkgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBDbGFzcyBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgTWV0aG9kRGVmaW5pdGlvbltdfFByb3BlcnR5RGVmaW5pdGlvbltdfFN0YXRpY0Jsb2NrW10KICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5ID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGNsYXNzIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHJldHVybiBNZXRob2REZWZpbml0aW9uW118UHJvcGVydHlEZWZpbml0aW9uW118U3RhdGljQmxvY2tbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgY2xhc3MgbWV0aG9kcyBhbmQgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAcGFyYW0gTWV0aG9kRGVmaW5pdGlvbltdfFByb3BlcnR5RGVmaW5pdGlvbltdfFN0YXRpY0Jsb2NrW10gJGJvZHkgQ2xhc3MgbWV0aG9kcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KCRib2R5KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKAogICAgICAgICAgICAkYm9keSwKICAgICAgICAgICAgYXJyYXkoIk1ldGhvZERlZmluaXRpb24iLCAiUHJvcGVydHlEZWZpbml0aW9uIiwgIlN0YXRpY0Jsb2NrIikKICAgICAgICApOwogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbnVsbCBsaXRlcmFsLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBOdWxsTGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlID0gbnVsbDsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmF3ID0gIm51bGwiOwogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGRvLXdoaWxlIGxvb3AuCiAqIEZvciBleGFtcGxlOiBkbyB7fSB3aGlsZSAodGVzdCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRG9XaGlsZVN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJib2R5IiA9PiB0cnVlLAogICAgICAgICJ0ZXN0IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBsb29wIGJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgbG9vcCBjb25kaXRpb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHRlc3Q7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoU3RhdGVtZW50ICRib2R5KQogICAgewogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvb3AgY29uZGl0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxvb3AgY29uZGl0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR0ZXN0IExvb3AKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVzdChFeHByZXNzaW9uICR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIG9iamVjdCBiaW5kaW5nIHBhdHRlcm4uCiAqIEZvciBleGFtcGxlOiB2YXIge2EsIGIsIGN9ID0gZAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBPYmplY3RQYXR0ZXJuIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFBhdHRlcm4KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJwcm9wZXJ0aWVzIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgUHJvcGVydHlbXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gUHJvcGVydHlbXSAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3BlcnRpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGVydGllczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEBwYXJhbSBQcm9wZXJ0eVtdICRwcm9wZXJ0aWVzIE9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByb3BlcnRpZXMoJHByb3BlcnRpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJHByb3BlcnRpZXMsIGFycmF5KCJBc3NpZ25tZW50UHJvcGVydHkiLCAiUmVzdEVsZW1lbnQiKSk7CiAgICAgICAgJHRoaXMtPnByb3BlcnRpZXMgPSAkcHJvcGVydGllczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlICJmb3IuLi5vZiIgc3RhdGVtZW50LgogKiBGb3IgZXhhbXBsZTogZm9yICh2YXIgYSBvZiBiKSB7fQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBGb3JPZlN0YXRlbWVudCBleHRlbmRzIEZvckluU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAicmlnaHQiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUsCiAgICAgICAgImF3YWl0IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBBc3luYyBpdGVyYXRpb24gZmxhZwogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRhd2FpdCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFzeW5jIGl0ZXJhdGlvbiBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXdhaXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXdhaXQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgYXN5bmMgaXRlcmF0aW9uIGZsYWcKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGF3YWl0IEFzeW5jIGl0ZXJhdGlvbiBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF3YWl0KCRhd2FpdCkKICAgIHsKICAgICAgICAkdGhpcy0+YXdhaXQgPSAoYm9vbCkgJGF3YWl0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogSW50ZXJmYWNlIHRoYXQgZXZlcnkgcGF0dGVybiBub2RlIG11c3QgaW1wbGVtZW50LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgUGF0dGVybgp7Cn08P3BocCAvKiogQG5vaW5zcGVjdGlvbiBQaHBFbGVtZW50SXNOb3RBdmFpbGFibGVJbkN1cnJlbnRQaHBWZXJzaW9uSW5zcGVjdGlvbiAqLwoKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCnVzZSBQZWFzdFxTeW50YXhcU291cmNlTG9jYXRpb247CnVzZSBQZWFzdFxTeW50YXhcUG9zaXRpb247CgovKioKICogQmFzZSBjbGFzcyBmb3IgYWxsIHRoZSBub2RlcyBnZW5lcmF0ZWQgYnkgUGVhc3QuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgTm9kZSBpbXBsZW1lbnRzIFxKU09OU2VyaWFsaXphYmxlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidHlwZSIgPT4gZmFsc2UsCiAgICAgICAgImxvY2F0aW9uIiA9PiBmYWxzZSwKICAgICAgICAibGVhZGluZ0NvbW1lbnRzIiA9PiBmYWxzZSwKICAgICAgICAidHJhaWxpbmdDb21tZW50cyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTm9kZSBsb2NhdGlvbiBpbiB0aGUgc291cmNlIGNvZGUKICAgICAqIAogICAgICogQHZhciBTb3VyY2VMb2NhdGlvbgogICAgICovCiAgICBwdWJsaWMgJGxvY2F0aW9uOwogICAgCiAgICAvKioKICAgICAqIExlYWRpbmcgY29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAdmFyIENvbW1lbnRbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGxlYWRpbmdDb21tZW50cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBUcmFpbGluZyBjb21tZW50cyBhcnJheQogICAgICoKICAgICAqIEB2YXIgQ29tbWVudFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdHJhaWxpbmdDb21tZW50cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzLT5sb2NhdGlvbiA9IG5ldyBTb3VyY2VMb2NhdGlvbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgJGNsYXNzID0gZXhwbG9kZSgiXFwiLCBnZXRfY2xhc3MoJHRoaXMpKTsKICAgICAgICByZXR1cm4gYXJyYXlfcG9wKCRjbGFzcyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBsZWFkaW5nIGNvbW1lbnRzIGFycmF5CiAgICAgKgogICAgICogQHBhcmFtIENvbW1lbnRbXSAkY29tbWVudHMgQ29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZWFkaW5nQ29tbWVudHMoJGNvbW1lbnRzKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjb21tZW50cywgIkNvbW1lbnQiKTsKICAgICAgICAkdGhpcy0+bGVhZGluZ0NvbW1lbnRzID0gJGNvbW1lbnRzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgbGVhZGluZyBjb21tZW50cyBhcnJheQogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWVudFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMZWFkaW5nQ29tbWVudHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGVhZGluZ0NvbW1lbnRzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0cmFpbGluZyBjb21tZW50cyBhcnJheQogICAgICoKICAgICAqIEBwYXJhbSBDb21tZW50W10gJGNvbW1lbnRzIENvbW1lbnRzIGFycmF5CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhaWxpbmdDb21tZW50cygkY29tbWVudHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGNvbW1lbnRzLCAiQ29tbWVudCIpOwogICAgICAgICR0aGlzLT50cmFpbGluZ0NvbW1lbnRzID0gJGNvbW1lbnRzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJhaWxpbmcgY29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1lbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHJhaWxpbmdDb21tZW50cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50cmFpbGluZ0NvbW1lbnRzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlIGxvY2F0aW9uIGluIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFNvdXJjZUxvY2F0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NhdGlvbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgbm9kZSBpbiB0aGUgc291cmNlIGNvZGUKICAgICAqIAogICAgICogQHBhcmFtIFBvc2l0aW9uICRwb3NpdGlvbiBTdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGFydFBvc2l0aW9uKFBvc2l0aW9uICRwb3NpdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+bG9jYXRpb24tPnN0YXJ0ID0gJHBvc2l0aW9uOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAkcG9zaXRpb24gU3RhcnQgcG9zaXRpb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RW5kUG9zaXRpb24oUG9zaXRpb24gJHBvc2l0aW9uKQogICAgewogICAgICAgICR0aGlzLT5sb2NhdGlvbi0+ZW5kID0gJHBvc2l0aW9uOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUcmF2ZXJzZXMgdGhlIGN1cnJlbnQgbm9kZSBhbmQgYWxsIGl0cyBjaGlsZCBub2RlcyB1c2luZyB0aGUgZ2l2ZW4KICAgICAqIGZ1bmN0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkZm4gICAgICBGdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIG9uIGVhY2ggbm9kZQogICAgICogQHBhcmFtIGFycmF5ICAgICRvcHRpb25zIE9wdGlvbnMgYXJyYXkuIFNlZSBUcmF2ZXJzZXIgY2xhc3MKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudGF0aW9uIGZvciBhdmFpbGFibGUgb3B0aW9ucwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0cmF2ZXJzZShjYWxsYWJsZSAkZm4sICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdHJhdmVyc2VyID0gbmV3IFxQZWFzdFxUcmF2ZXJzZXIoJG9wdGlvbnMpOwogICAgICAgICR0cmF2ZXJzZXItPmFkZEZ1bmN0aW9uKCRmbiktPnRyYXZlcnNlKCR0aGlzKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNlcmlhbGl6YWJsZSB2ZXJzaW9uIG9mIHRoZSBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24ganNvblNlcmlhbGl6ZSgpCiAgICB7CiAgICAgICAgJHJldCA9IGFycmF5KCk7CiAgICAgICAgJHByb3BzID0gXFBlYXN0XFN5bnRheFxVdGlsczo6Z2V0Tm9kZVByb3BlcnRpZXMoJHRoaXMpOwogICAgICAgIGZvcmVhY2ggKCRwcm9wcyBhcyAkcHJvcCkgewogICAgICAgICAgICAkcmV0WyRwcm9wWyJuYW1lIl1dID0gJHRoaXMtPnskcHJvcFsiZ2V0dGVyIl19KCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJlbmRlcnMgdGhlIGN1cnJlbnQgbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gXFBlYXN0XEZvcm1hdHRlclxCYXNlICRmb3JtYXR0ZXIgRm9ybWF0dGVyIHRvIHVzZSBmb3IgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXIoXFBlYXN0XEZvcm1hdHRlclxCYXNlICRmb3JtYXR0ZXIpCiAgICB7CiAgICAgICAgJHJlbmRlcmVyID0gbmV3IFxQZWFzdFxSZW5kZXJlcigpOwogICAgICAgIHJldHVybiAkcmVuZGVyZXItPnNldEZvcm1hdHRlcigkZm9ybWF0dGVyKS0+cmVuZGVyKCR0aGlzKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBBc3NlcnRzIHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGFycmF5IG9mIGRlZmluZWQgdHlwZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICRwYXJhbXMgICAgVmFsdWUgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGNsYXNzZXMgICBDbGFzcyBvciBhcnJheSBvZiBjbGFzc2VzIHRvIGNoZWNrIGFnYWluc3QKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJGFsbG93TnVsbCBJZiB0cnVlLCBudWxsIHZhbHVlcyBhcmUgYWxsb3dlZAogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIAogICAgICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXNzZXJ0QXJyYXlPZigkcGFyYW1zLCAkY2xhc3NlcywgJGFsbG93TnVsbCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghaXNfYXJyYXkoJGNsYXNzZXMpKSB7CiAgICAgICAgICAgICRjbGFzc2VzID0gYXJyYXkoJGNsYXNzZXMpOwogICAgICAgIH0KICAgICAgICBpZiAoIWlzX2FycmF5KCRwYXJhbXMpKSB7CiAgICAgICAgICAgICR0aGlzLT50eXBlRXJyb3IoJHBhcmFtcywgJGNsYXNzZXMsICRhbGxvd051bGwsIHRydWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYXJhbXMgYXMgJHBhcmFtKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkY2xhc3NlcyBhcyAkY2xhc3MpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBhcmFtID09PSBudWxsICYmICRhbGxvd051bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkYyA9ICJQZWFzdFxcU3ludGF4XFxOb2RlXFwkY2xhc3MiOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBhcmFtIGluc3RhbmNlb2YgJGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+dHlwZUVycm9yKCRwYXJhbSwgJGNsYXNzZXMsICRhbGxvd051bGwsIHRydWUsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgcmVzcGVjdHMgdGhlIGRlZmluZWQgdHlwZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICRwYXJhbSAgICAgVmFsdWUgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGNsYXNzZXMgICBDbGFzcyBvciBhcnJheSBvZiBjbGFzc2VzIHRvIGNoZWNrIGFnYWluc3QKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJGFsbG93TnVsbCBJZiB0cnVlLCBudWxsIHZhbHVlcyBhcmUgYWxsb3dlZAogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIAogICAgICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXNzZXJ0VHlwZSgkcGFyYW0sICRjbGFzc2VzLCAkYWxsb3dOdWxsID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCFpc19hcnJheSgkY2xhc3NlcykpIHsKICAgICAgICAgICAgJGNsYXNzZXMgPSBhcnJheSgkY2xhc3Nlcyk7CiAgICAgICAgfQogICAgICAgIGlmICgkcGFyYW0gPT09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCEkYWxsb3dOdWxsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dHlwZUVycm9yKCRwYXJhbSwgJGNsYXNzZXMsICRhbGxvd051bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNsYXNzZXMgYXMgJGNsYXNzKSB7CiAgICAgICAgICAgICAgICAkYyA9ICJQZWFzdFxcU3ludGF4XFxOb2RlXFwkY2xhc3MiOwogICAgICAgICAgICAgICAgaWYgKCRwYXJhbSBpbnN0YW5jZW9mICRjKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT50eXBlRXJyb3IoJHBhcmFtLCAkY2xhc3NlcywgJGFsbG93TnVsbCk7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIFRocm93cyBhbiBlcnJvciBpZiB0aGUgZGVmaW5lZCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgYgogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHBhcmFtICAgICAgICBUaGUgdmFsdWUgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBtaXhlZCAkYWxsb3dlZFR5cGVzIENsYXNzIG9yIGFycmF5IG9mIGNsYXNzZXMgdG8gY2hlY2sgYWdhaW5zdAogICAgICogQHBhcmFtIGJvb2wgICRhbGxvd051bGwgICAgSWYgdHJ1ZSwgbnVsbCB2YWx1ZXMgYXJlIGFsbG93ZWQKICAgICAqIEBwYXJhbSBib29sICAkYXJyYXkgICAgICAgIElmIHRydWUsIHRoZSB2YWx1ZSBtdXN0IGJlIGFuIGFycmF5CiAgICAgKiBAcGFyYW0gYm9vbCAgJGluQXJyYXkgICAgICBJZiB0cnVlLCB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgYnV0IHRoZSBjb250ZW50CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2VzIG5vdCByZXNwZWN0cyB0aGUgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIAogICAgICogQHRocm93cyBcVHlwZUVycm9yCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHR5cGVFcnJvcigKICAgICAgICAkcGFyYW0sICRhbGxvd2VkVHlwZXMsICRhbGxvd051bGwgPSBmYWxzZSwgJGFycmF5ID0gZmFsc2UsCiAgICAgICAgJGluQXJyYXkgPSBmYWxzZQogICAgKSB7CiAgICAgICAgJGJhY2t0cmFjZSA9IGRlYnVnX2JhY2t0cmFjZShERUJVR19CQUNLVFJBQ0VfSUdOT1JFX0FSR1MpOwogICAgICAgICRtZXRob2QgPSAkYmFja3RyYWNlWzJdWyJjbGFzcyJdIC4gIjo6IiAuICRiYWNrdHJhY2VbMl1bImZ1bmN0aW9uIl07CiAgICAgICAgJG1zZyA9ICJBcmd1bWVudCAwIHBhc3NlZCB0byAkbWV0aG9kIG11c3QgYmUgIjsKICAgICAgICBpZiAoJGFycmF5KSB7CiAgICAgICAgICAgICRtc2cgLj0gImFuIGFycmF5IG9mICI7CiAgICAgICAgfQogICAgICAgICRtc2cgLj0gaW1wbG9kZSgiIG9yICIsICRhbGxvd2VkVHlwZXMpOwogICAgICAgIGlmICgkYWxsb3dOdWxsKSB7CiAgICAgICAgICAgICRtc2cgLj0gIiBvciBudWxsIjsKICAgICAgICB9CiAgICAgICAgaWYgKGlzX29iamVjdCgkcGFyYW0pKSB7CiAgICAgICAgICAgICRwYXJ0cyA9IGV4cGxvZGUoIlxcIiwgZ2V0X2NsYXNzKCRwYXJhbSkpOwogICAgICAgICAgICAkdHlwZSA9IGFycmF5X3BvcCgkcGFydHMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0eXBlID0gZ2V0dHlwZSgkcGFyYW0pOwogICAgICAgIH0KICAgICAgICBpZiAoJGluQXJyYXkpIHsKICAgICAgICAgICAgJHR5cGUgPSAiYXJyYXkgb2YgJHR5cGUiOwogICAgICAgIH0KICAgICAgICAkbXNnIC49ICIsICR0eXBlIGdpdmVuIjsKICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oKSwgJzcnLCAnPj0nKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFR5cGVFcnJvcigkbXNnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCRtc2csIEVfVVNFUl9FUlJPUik7CiAgICAgICAgfQogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdGFnZ2VkIHRlbXBsYXRlIGV4cHJlc3Npb24uCiAqIEZvciBleGFtcGxlOiBmbmB0ZW1wbGF0ZWAKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJ0YWciID0+IHRydWUsCiAgICAgICAgInF1YXNpIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRhZyBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR0YWc7CiAgICAKICAgIC8qKgogICAgICogVGVtcGxhdGUKICAgICAqIAogICAgICogQHZhciBUZW1wbGF0ZUxpdGVyYWwgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcXVhc2k7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGFnIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGFnOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRhZyBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR0YWcgVGFnIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGFnKEV4cHJlc3Npb24gJHRhZykKICAgIHsKICAgICAgICAkdGhpcy0+dGFnID0gJHRhZzsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGVtcGxhdGUKICAgICAqIAogICAgICogQHJldHVybiBUZW1wbGF0ZUxpdGVyYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFF1YXNpKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnF1YXNpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAcGFyYW0gVGVtcGxhdGVMaXRlcmFsICRxdWFzaSBUZW1wbGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRRdWFzaShUZW1wbGF0ZUxpdGVyYWwgJHF1YXNpKQogICAgewogICAgICAgICR0aGlzLT5xdWFzaSA9ICRxdWFzaTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdGVtcGxhdGUgZWxlbWVudC4KICogRm9yIGV4YW1wbGUgYGZvb2AgYW5kIGBiYXJgIGluOiBgZm9vJHtleHB9YmFyYAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUZW1wbGF0ZUVsZW1lbnQgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidmFsdWUiID0+IGZhbHNlLAogICAgICAgICJ0YWlsIiA9PiBmYWxzZSwKICAgICAgICAicmF3VmFsdWUiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICR2YWx1ZTsKICAgIAogICAgLyoqCiAgICAgKiBUYWlsIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIGVsZW1lbnQgaXMgdGhlIHRhaWwgZWxlbWVudCBpbiBhIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICR0YWlsID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogTm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJHJhd1ZhbHVlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybiBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZhbHVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbHVlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKICAgICAgICAkdGhpcy0+cmF3VmFsdWUgPSBVdGlsczo6cXVvdGVMaXRlcmFsU3RyaW5nKCR2YWx1ZSwgImAiKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGFpbCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBlbGVtZW50IGlzIHRoZSB0YWlsIGVsZW1lbnQKICAgICAqIGluIGEgdGVtcGxhdGUKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWlsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRhaWw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgdGFpbCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBlbGVtZW50IGlzIHRoZSB0YWlsIGVsZW1lbnQKICAgICAqIGluIGEgdGVtcGxhdGUKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJHRhaWwgVGFpbCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRhaWwoJHRhaWwpCiAgICB7CiAgICAgICAgJHRoaXMtPnRhaWwgPSAoYm9vbCkgJHRhaWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgbm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmF3VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmF3VmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgcmF3IHZhbHVlIHRoYXQgbXVzdCBiZSB3cmFwcGVkIGluIHRlbXBsYXRlcyBxdW90ZXMuCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJhd1ZhbHVlIFJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSYXdWYWx1ZSgkcmF3VmFsdWUpCiAgICB7CiAgICAgICAgJHJhd1ZhbHVlID0gcHJlZ19yZXBsYWNlKCIjXltgfV18KD86YHxcXFwkXHspJCMiLCAiIiwgJHJhd1ZhbHVlKTsKICAgICAgICAkdGhpcy0+c2V0VmFsdWUoVXRpbHM6OnVucXVvdGVMaXRlcmFsU3RyaW5nKCJgJHJhd1ZhbHVlYCIpKTsKICAgICAgICAkdGhpcy0+cmF3VmFsdWUgPSAkcmF3VmFsdWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdGVtcGxhdGUgbGl0ZXJhbC4KICogRm9yIGV4YW1wbGU6IGB0aGlzIGlzIGEgJHt0ZXN0KCl9IHRlbXBsYXRlYAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUZW1wbGF0ZUxpdGVyYWwgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInBhcnRzIiA9PiB0cnVlLAogICAgICAgICJxdWFzaXMiID0+IGZhbHNlLAogICAgICAgICJleHByZXNzaW9ucyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2YgcXVhc2lzIHRoYXQgYXJlIHRoZSBsaXRlcmFsIHBhcnRzIG9mIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAdmFyIFRlbXBsYXRlRWxlbWVudFtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHF1YXNpcyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2YgZXhwcmVzc2lvbnMgaW5zaWRlIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb25bXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9ucyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgcXVhc2lzIHRoYXQgYXJlIHRoZSBsaXRlcmFsIHBhcnRzIG9mIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRlbXBsYXRlRWxlbWVudFtdIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UXVhc2lzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnF1YXNpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhcnJheSBvZiBxdWFzaXMgdGhhdCBhcmUgdGhlIGxpdGVyYWwgcGFydHMgb2YgdGhlIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEBwYXJhbSBUZW1wbGF0ZUVsZW1lbnRbXSAkcXVhc2lzIFF1YXNpcwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRRdWFzaXMoJHF1YXNpcykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkcXVhc2lzLCAiVGVtcGxhdGVFbGVtZW50Iik7CiAgICAgICAgJHRoaXMtPnF1YXNpcyA9ICRxdWFzaXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIGV4cHJlc3Npb25zIGluc2lkZSB0aGUgdGVtcGxhdGUKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4cHJlc3Npb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb25zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFycmF5IG9mIGV4cHJlc3Npb25zIGluc2lkZSB0aGUgdGVtcGxhdGUKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb25bXSAkZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhwcmVzc2lvbnMoJGV4cHJlc3Npb25zKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRleHByZXNzaW9ucywgIkV4cHJlc3Npb24iKTsKICAgICAgICAkdGhpcy0+ZXhwcmVzc2lvbnMgPSAkZXhwcmVzc2lvbnM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHRlbXBsYXRlIHBhcnRzIChxdWFzaXMgYW5kIGV4cHJlc3Npb25zKQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJ0cygpCiAgICB7CiAgICAgICAgLy8gSXQgbXVzdCBiZSBhIGxpc3Qgb2YgcXVhc2lzIGFuZCBleHByZXNzaW9ucyBhbHRlcm5hdGVkCiAgICAgICAgJHBhcnRzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cXVhc2lzIGFzICRrID0+ICR2YWwpIHsKICAgICAgICAgICAgJHBhcnRzW10gPSAkdmFsOwogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmV4cHJlc3Npb25zWyRrXSkpIHsKICAgICAgICAgICAgICAgICRwYXJ0c1tdID0gJHRoaXMtPmV4cHJlc3Npb25zWyRrXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJHBhcnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFycmF5IG9mIHRoZSB0ZW1wbGF0ZSBwYXJ0cyAocXVhc2lzIGFuZCBleHByZXNzaW9ucykKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5IFRlbXBsYXRlIHBhcnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhcnRzKCRwYXJ0cykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkcGFydHMsIGFycmF5KCJFeHByZXNzaW9uIiwgIlRlbXBsYXRlRWxlbWVudCIpKTsKICAgICAgICAkcXVhc2lzID0gJGV4cHJlc3Npb25zID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFydHMgYXMgJHBhcnQpIHsKICAgICAgICAgICAgaWYgKCRwYXJ0IGluc3RhbmNlb2YgVGVtcGxhdGVFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAkcXVhc2lzW10gPSAkcGFydDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRleHByZXNzaW9uc1tdID0gJHBhcnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRRdWFzaXMoJHF1YXNpcyktPnNldEV4cHJlc3Npb25zKCRleHByZXNzaW9ucyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNlcmlhbGl6YWJsZSB2ZXJzaW9uIG9mIHRoZSBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24ganNvblNlcmlhbGl6ZSgpCiAgICB7CiAgICAgICAgJHJldCA9IHBhcmVudDo6anNvblNlcmlhbGl6ZSgpOwogICAgICAgIHVuc2V0KCRyZXRbInBhcnRzIl0pOwogICAgICAgIHJldHVybiAkcmV0OwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgd2hpbGUgbG9vcC4KICogRm9yIGV4YW1wbGU6IHdoaWxlICh0ZXN0KSB7fQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBXaGlsZVN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJ0ZXN0IiA9PiB0cnVlLAogICAgICAgICJib2R5IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBsb29wIGNvbmRpdGlvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdGVzdDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGJvZHk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9vcCBjb25kaXRpb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUZXN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRlc3Q7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9vcCBjb25kaXRpb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHRlc3QgTG9vcAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZXN0KEV4cHJlc3Npb24gJHRlc3QpCiAgICB7CiAgICAgICAgJHRoaXMtPnRlc3QgPSAkdGVzdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoU3RhdGVtZW50ICRib2R5KQogICAgewogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY2xhc3Mgc3RhdGljIGJsb2NrCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFN0YXRpY0Jsb2NrIGV4dGVuZHMgQmxvY2tTdGF0ZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbG9naWNhbCBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogYSAmJiBiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIExvZ2ljYWxFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJsZWZ0IiA9PiB0cnVlLAogICAgICAgICJvcGVyYXRvciIgPT4gZmFsc2UsCiAgICAgICAgInJpZ2h0IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE9wZXJhdG9yCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0b3I7CiAgICAKICAgIC8qKgogICAgICogTGVmdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGxlZnQ7CiAgICAKICAgIC8qKgogICAgICogUmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRyaWdodDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBvcGVyYXRvcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlcmF0b3I7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3BlcmF0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkb3BlcmF0b3IgT3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGVmdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGVmdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sZWZ0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxlZnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkbGVmdCBMZWZ0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TGVmdChFeHByZXNzaW9uICRsZWZ0KQogICAgewogICAgICAgICR0aGlzLT5sZWZ0ID0gJGxlZnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJpZ2h0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSaWdodCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yaWdodDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSByaWdodCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRyaWdodCBSaWdodCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJpZ2h0KEV4cHJlc3Npb24gJHJpZ2h0KQogICAgewogICAgICAgICR0aGlzLT5yaWdodCA9ICRyaWdodDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBCaWdJbnQgbGl0ZXJhbC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQmlnSW50TGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJiaWdpbnQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIG1peGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYmlnaW50OwogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBmbG9hdCAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgIC8vVmFsdWUsIFJhdyBhbmQgQmlnaW50IGFyZSBhbHdheXMgdGhlIHNhbWUgdmFsdWUKICAgICAgICAkdGhpcy0+dmFsdWUgPSAkdGhpcy0+cmF3ID0gJHRoaXMtPmJpZ2ludCA9ICR2YWx1ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJpZ2ludCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5iaWdpbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkYmlnaW50IFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJpZ2ludCgkYmlnaW50KQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2V0VmFsdWUoJGJpZ2ludCk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjaGFpbiBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogdGVzdD8udGVzdD8uKCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ2hhaW5FeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXhwcmVzc2lvbjsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRleHByZXNzaW9uIFdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gJGV4cHJlc3Npb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAkZXhwcmVzc2lvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjYXNlIGluIGEgc3dpdGNoIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU3dpdGNoQ2FzZSBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJ0ZXN0IiA9PiB0cnVlLAogICAgICAgICJjb25zZXF1ZW50IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRlc3QgZXhwcmVzc2lvbiB0aGF0IGlzIG51bGwgaW4gdGhlICJkZWZhdWx0IiBjYXNlCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR0ZXN0OwogICAgCiAgICAvKioKICAgICAqIENvbnNlcXVlbnQgc3RhdGVtZW50cyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIFN0YXRlbWVudFtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnNlcXVlbnQgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRlc3QgZXhwcmVzc2lvbiB0aGF0IGlzIG51bGwgaW4gdGhlICJkZWZhdWx0IiBjYXNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRlc3QgZXhwcmVzc2lvbiB0aGF0IGlzIG51bGwgaW4gdGhlICJkZWZhdWx0IiBjYXNlCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR0ZXN0IFRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZXN0KCR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCR0ZXN0LCAiRXhwcmVzc2lvbiIsIHRydWUpOwogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnNlcXVlbnQgc3RhdGVtZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIFN0YXRlbWVudFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25zZXF1ZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnNlcXVlbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29uc2VxdWVudCBzdGF0ZW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uW10gJGNvbnNlcXVlbnQgQ29uc2VxdWVudCBzdGF0ZW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbnNlcXVlbnQoJGNvbnNlcXVlbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGNvbnNlcXVlbnQsICJTdGF0ZW1lbnQiKTsKICAgICAgICAkdGhpcy0+Y29uc2VxdWVudCA9ICRjb25zZXF1ZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBsaXRlcmFsLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBSZWdFeHBMaXRlcmFsIGV4dGVuZHMgTGl0ZXJhbAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImZsYWdzIiA9PiBmYWxzZSwKICAgICAgICAicGF0dGVybiIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogUmVnZXggZmxhZ3MKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZmxhZ3MgPSAiIjsKICAgIAogICAgLyoqCiAgICAgKiBSZWdleCBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhdHRlcm4gPSAiIjsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyB0eXBlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gIlJlZ0V4cExpdGVyYWwiOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgcmVnZXggcGF0dGVybgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGF0dGVybigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXR0ZXJuOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgcmVnZXggcGF0dGVybgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXR0ZXJuIFJlZ2V4IHBhdHRlcm4KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGF0dGVybigkcGF0dGVybikKICAgIHsKICAgICAgICAkdGhpcy0+cGF0dGVybiA9ICRwYXR0ZXJuOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHJlZ2V4IGZsYWdzCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGbGFncygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mbGFnczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHJlZ2V4IGZsYWdzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZsYWdzIFJlZ2V4IGZsYWdzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZsYWdzKCRmbGFncykKICAgIHsKICAgICAgICAkdGhpcy0+ZmxhZ3MgPSAkZmxhZ3M7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgbm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmF3KCkKICAgIHsKICAgICAgICByZXR1cm4gIi8iIC4gJHRoaXMtPmdldFBhdHRlcm4oKSAuICIvIiAuICR0aGlzLT5nZXRGbGFncygpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHJhdyB2YWx1ZSB0aGF0IG11c3QgaW5jbHVkZSBkZWxpbWl0ZXJzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJhdyBSYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3KCRyYXcpCiAgICB7CiAgICAgICAgCiAgICAgICAgJHBhcnRzID0gZXhwbG9kZSgiLyIsIHN1YnN0cigkcmF3LCAxKSk7CiAgICAgICAgJGZsYWdzID0gYXJyYXlfcG9wKCRwYXJ0cyk7CiAgICAgICAgJHRoaXMtPnNldFBhdHRlcm4oaW1wbG9kZSgiLyIsICRwYXJ0cykpOwogICAgICAgICR0aGlzLT5zZXRGbGFncygkZmxhZ3MpOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UmF3KCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSBWYWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRSYXcoJHZhbHVlKTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBhcnJvdyBmdW5jdGlvbi4KICogRm9yIGV4YW1wbGU6IHZhciBmbiA9IChhLCBiKSA9PiBjb25zb2xlLmxvZyhhLCBiKQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbiBleHRlbmRzIEZ1bmN0aW9uXyBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGlzIGZsYWcgaXMgdHJ1ZSB3aGVuIGZ1bmN0aW9uIGJvZHkgaXMgd3JhcHBlZCBpbiBjdXJseSBicmFjZXMKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXhwcmVzc2lvbiA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGZ1bmN0aW9uIGJvZHkKICAgICAqIAogICAgICogQHBhcmFtIEJsb2NrU3RhdGVtZW50fEV4cHJlc3Npb24gJGJvZHkgRnVuY3Rpb24gYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KCRib2R5KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRib2R5LCBhcnJheSgiQmxvY2tTdGF0ZW1lbnQiLCAiRXhwcmVzc2lvbiIpKTsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbiBmbGFnCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRleHByZXNzaW9uIEV4cHJlc3Npb24gZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKCRleHByZXNzaW9uKQogICAgewogICAgICAgICR0aGlzLT5leHByZXNzaW9uID0gKGJvb2wpICRleHByZXNzaW9uOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgImNvbnRpbnVlIiBzdGF0ZW1lbnQgaW5zaWRlIGxvb3BzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDb250aW51ZVN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJsYWJlbCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgb3B0aW9uYWwgbGFiZWwgb2YgdGhlIGNvbnRpbnVlIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAdmFyIElkZW50aWZpZXIgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGFiZWw7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbm9kZSdzIGxhYmVsCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGFiZWwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGFiZWw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbm9kZSdzIGxhYmVsCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyICRsYWJlbCBOb2RlJ3MgbGFiZWwKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TGFiZWwoJGxhYmVsKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRsYWJlbCwgIklkZW50aWZpZXIiLCB0cnVlKTsKICAgICAgICAkdGhpcy0+bGFiZWwgPSAkbGFiZWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBYnN0cmFjdCBjbGFzcyBmb3IgbGl0ZXJhbHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIExpdGVyYWwgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInZhbHVlIiA9PiBmYWxzZSwKICAgICAgICAicmF3IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRyYXc7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICJMaXRlcmFsIjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIG5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJhdygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yYXc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkcmF3IFJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSYXcoJHJhdykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNldFZhbHVlKCRyYXcpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY2FsbCBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogdGVzdCgpCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIENhbGxFeHByZXNzaW9uIGV4dGVuZHMgQ2hhaW5FbGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiY2FsbGVlIiA9PiB0cnVlLAogICAgICAgICJhcmd1bWVudHMiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGNhbGxlZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbnxTdXBlciAKICAgICAqLwogICAgcHJvdGVjdGVkICRjYWxsZWU7CiAgICAKICAgIC8qKgogICAgICogVGhlIGFyZ3VtZW50cyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10KICAgICAqLwogICAgcHJvdGVjdGVkICRhcmd1bWVudHMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNhbGxlZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbnxTdXBlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2FsbGVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNhbGxlZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjYWxsZWUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbnxTdXBlciAkY2FsbGVlIENhbGxlZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENhbGxlZSgkY2FsbGVlKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRjYWxsZWUsIGFycmF5KCJFeHByZXNzaW9uIiwgIlN1cGVyIikpOwogICAgICAgICR0aGlzLT5jYWxsZWUgPSAkY2FsbGVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhcmd1bWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uW118U3ByZWFkRWxlbWVudFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFyZ3VtZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbltdfFNwcmVhZEVsZW1lbnRbXSAkYXJndW1lbnRzIEFyZ3VtZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudHMoJGFyZ3VtZW50cykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkYXJndW1lbnRzLCBhcnJheSgiRXhwcmVzc2lvbiIsICJTcHJlYWRFbGVtZW50IikpOwogICAgICAgICR0aGlzLT5hcmd1bWVudHMgPSAkYXJndW1lbnRzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7Cgp1c2UgUGVhc3RcU3ludGF4XFV0aWxzOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gaWRlbnRpZmllci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSWRlbnRpZmllciBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uLCBQYXR0ZXJuCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibmFtZSIgPT4gZmFsc2UsCiAgICAgICAgInJhd05hbWUiID0+IGZhbHNlLAogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgaWRlbnRpZmllcidzIG5hbWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwogICAgCiAgICAvKioKICAgICAqIFRoZSBpZGVudGlmaWVyJ3MgcmF3IG5hbWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRyYXdOYW1lOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGlkZW50aWZpZXIncyBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaWRlbnRpZmllcidzIG5hbWUKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgbmFtZSB0byBzZXQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TmFtZSgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bmFtZSA9ICR0aGlzLT5yYXdOYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGlkZW50aWZpZXIncyByYXcgbmFtZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmF3TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yYXdOYW1lOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlkZW50aWZpZXIncyByYXcgbmFtZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSByYXcgbmFtZSB0byBzZXQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3TmFtZSgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+cmF3TmFtZSA9ICRuYW1lOwogICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICJcXCIpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkdGhpcy0+bmFtZSA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygKICAgICAgICAgICAgICAgICIjXFxcXHUoPzpceyhbYS1mQS1GMC05XSspXH18KFthLWZBLUYwLTldezR9KSkjIiwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVXRpbHM6OnVuaWNvZGVUb1V0ZjgoaGV4ZGVjKCRtYXRjaFsxXSA/IDogJG1hdGNoWzJdKSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgJG5hbWUKICAgICAgICAgICAgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEludGVyZmFjZSB0aGF0IGV2ZXJ5IGV4cHJlc3Npb24gbm9kZSBtdXN0IGltcGxlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIEV4cHJlc3Npb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGluIGltcG9ydCBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGU6IGltcG9ydCBhIGZyb20gIm1vZCIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSW1wb3J0RGVjbGFyYXRpb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgTW9kdWxlRGVjbGFyYXRpb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJzcGVjaWZpZXJzIiA9PiB0cnVlLAogICAgICAgICJzb3VyY2UiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogSW1wb3J0IHNwZWNpZmllcnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHNwZWNpZmllcnMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIEltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHZhciBMaXRlcmFsIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNvdXJjZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbXBvcnQgc3BlY2lmaWVycyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTcGVjaWZpZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNwZWNpZmllcnM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW1wb3J0IHNwZWNpZmllcnMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICRzcGVjaWZpZXJzIEltcG9ydCBzcGVjaWZpZXJzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNwZWNpZmllcnMoJHNwZWNpZmllcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoCiAgICAgICAgICAgICRzcGVjaWZpZXJzLAogICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICJJbXBvcnRTcGVjaWZpZXIiLAogICAgICAgICAgICAgICAgIkltcG9ydERlZmF1bHRTcGVjaWZpZXIiLAogICAgICAgICAgICAgICAgIkltcG9ydE5hbWVzcGFjZVNwZWNpZmllciIKICAgICAgICAgICAgKQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPnNwZWNpZmllcnMgPSAkc3BlY2lmaWVyczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW1wb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAcmV0dXJuIExpdGVyYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2U7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW1wb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAcGFyYW0gTGl0ZXJhbCAkc291cmNlIEltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlKExpdGVyYWwgJHNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gJHNvdXJjZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gYXJyYXkgYmluZGluZyBwYXR0ZXJuLgogKiBGb3IgZXhhbXBsZTogW2EsIGIsIGNdID0gZAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBcnJheVBhdHRlcm4gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgUGF0dGVybgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImVsZW1lbnRzIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEFycmF5IGVsZW1lbnRzCiAgICAgKiAKICAgICAqIEB2YXIgUGF0dGVybltdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZWxlbWVudHMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYXJyYXkgZWxlbWVudHMKICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVsZW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVsZW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgYXJyYXkgZWxlbWVudHMKICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm5bXSAkZWxlbWVudHMgQXJyYXkgZWxlbWVudHMgdG8gc2V0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVsZW1lbnRzKCRlbGVtZW50cykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkZWxlbWVudHMsICJQYXR0ZXJuIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmVsZW1lbnRzID0gJGVsZW1lbnRzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7Cgp1c2UgUGVhc3RcU3ludGF4XFV0aWxzOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzdHJpbmcgbGl0ZXJhbC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU3RyaW5nTGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJmb3JtYXQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvL0Zvcm1hdCBjb25zdGFudHMKICAgIC8qKgogICAgICogRG91YmxlIHF1b3RlZCBzdHJpbmcKICAgICAqLwogICAgY29uc3QgRE9VQkxFX1FVT1RFRCA9ICJkb3VibGUiOwogICAgCiAgICAvKioKICAgICAqIFNpbmdsZSBxdW90ZWQgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFNJTkdMRV9RVU9URUQgPSAic2luZ2xlIjsKICAgIAogICAgLyoqCiAgICAgKiBTdHJpbmcgZm9ybWF0CiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZm9ybWF0ID0gc2VsZjo6RE9VQkxFX1FVT1RFRDsKICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBWYWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gKHN0cmluZykgJHZhbHVlOwogICAgICAgIC8vRm9yY2UgcmVjYWxjdWxhdGlvbiBvZiB0aGUgcmF3IHZhbHVlCiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRGb3JtYXQoJHRoaXMtPmZvcm1hdCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkcmF3IFJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKiAKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3KCRyYXcpCiAgICB7CiAgICAgICAgaWYgKCFpc19zdHJpbmcoJHJhdykgfHwgc3RybGVuKCRyYXcpIDwgMikgewogICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCBzdHJpbmciKTsKICAgICAgICB9CiAgICAgICAgJHN0YXJ0UXVvdGUgPSAkcmF3WzBdOwogICAgICAgICRlbmRRdW90ZSA9IHN1YnN0cigkcmF3LCAtMSk7CiAgICAgICAgaWYgKCgkc3RhcnRRdW90ZSAhPT0gIiciICYmICRzdGFydFF1b3RlICE9PSAnIicpIHx8CiAgICAgICAgICAgICRzdGFydFF1b3RlICE9PSAkZW5kUXVvdGUKICAgICAgICApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oIkludmFsaWQgc3RyaW5nIik7CiAgICAgICAgfQogICAgICAgICR0aGlzLT52YWx1ZSA9IFV0aWxzOjp1bnF1b3RlTGl0ZXJhbFN0cmluZygkcmF3KTsKICAgICAgICAkdGhpcy0+c2V0Rm9ybWF0KCRyYXdbMF0gPT09ICInIiA/CiAgICAgICAgICAgIHNlbGY6OlNJTkdMRV9RVU9URUQgOgogICAgICAgICAgICBzZWxmOjpET1VCTEVfUVVPVEVECiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+cmF3ID0gJHJhdzsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBzdHJpbmcgZm9ybWF0CiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgc3RyaW5nIGZvcm1hdAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtYXQgRm9ybWF0LCBvbmUgb2YgdGhlIGZvcm1hdCBjb25zdGFudHMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0KCRmb3JtYXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdCA9ICRmb3JtYXQ7CiAgICAgICAgJHF1b3RlID0gJGZvcm1hdCA9PT0gc2VsZjo6U0lOR0xFX1FVT1RFRCA/ICInIiA6ICciJzsKICAgICAgICAkdGhpcy0+cmF3ID0gVXRpbHM6OnF1b3RlTGl0ZXJhbFN0cmluZygkdGhpcy0+dmFsdWUsICRxdW90ZSk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSBleHBvcnQgZGVmYXVsdCBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGU6IGV4cG9ydCBkZWZhdWx0IGEKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIE1vZHVsZURlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZGVjbGFyYXRpb24iID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEB2YXIgRGVjbGFyYXRpb258RXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGRlY2xhcmF0aW9uOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRGVjbGFyYXRpb258RXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVjbGFyYXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVjbGFyYXRpb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwb3J0ZWQgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHBhcmFtIERlY2xhcmF0aW9ufEV4cHJlc3Npb24gJGRlY2xhcmF0aW9uIFRoZSBleHBvcnRlZCBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZWNsYXJhdGlvbigkZGVjbGFyYXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGRlY2xhcmF0aW9uLCBhcnJheSgiRGVjbGFyYXRpb24iLCAiRXhwcmVzc2lvbiIpKTsKICAgICAgICAkdGhpcy0+ZGVjbGFyYXRpb24gPSAkZGVjbGFyYXRpb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbGFiZWxlZCBzdGF0ZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIExhYmVsZWRTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGFiZWwiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTGFiZWwKICAgICAqIAogICAgICogQHZhciBJZGVudGlmaWVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhYmVsOwogICAgCiAgICAvKioKICAgICAqIEJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuIElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExhYmVsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhYmVsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxhYmVsCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyICRsYWJlbCBMYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMYWJlbChJZGVudGlmaWVyICRsYWJlbCkKICAgIHsKICAgICAgICAkdGhpcy0+bGFiZWwgPSAkbGFiZWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgQm9keQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KFN0YXRlbWVudCAkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogSW50ZXJmYWNlIHRoYXQgZXZlcnkgc3RhdGVtZW50IG5vZGUgbXVzdCBpbXBsZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBTdGF0ZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBDb21tb24gaW50ZXJmYWNlIGZvciBmdW5jdGlvbiBpbXBvcnQgYW5kIGV4cG9ydCBub2Rlcy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIE1vZHVsZURlY2xhcmF0aW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgY2F0Y2ggY2xhdXNlIGluIGEgdHJ5LWNhdGNoIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ2F0Y2hDbGF1c2UgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAicGFyYW0iID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGNhdGNoIGNsYXVzZSBwYXJhbWV0ZXIKICAgICAqIAogICAgICogQHZhciBQYXR0ZXJuIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhcmFtOwogICAgCiAgICAvKioKICAgICAqIFRoZSBib2R5IG9mIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHZhciBCbG9ja1N0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNhdGNoIGNsYXVzZSBwYXJhbWV0ZXIKICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJhbSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXJhbTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjYXRjaCBjbGF1c2UgcGFyYW1ldGVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXR0ZXJuICRwYXJhbSBDYXRjaCBjbGF1c2UgcGFyYW1ldGVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhcmFtKCRwYXJhbSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkcGFyYW0sICJQYXR0ZXJuIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnBhcmFtID0gJHBhcmFtOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBib2R5IG9mIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiBCbG9ja1N0YXRlbWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGJvZHkgb2YgdGhlIGNhdGNoIGNsYXVzZQogICAgICogCiAgICAgKiBAcGFyYW0gQmxvY2tTdGF0ZW1lbnQgJGJvZHkgVGhlIGJsb2NrIG9mIGNvZGUgaW5zaWRlIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keShCbG9ja1N0YXRlbWVudCAkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhICJ2YXIiLCAiY29uc3QiIG9yICJsZXQiIGRlY2xhcmF0aW9uLgogKiBGb3IgZXhhbXBsZTogdmFyIGEgPSAxCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFZhcmlhYmxlRGVjbGFyYXRpb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRGVjbGFyYXRpb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJkZWNsYXJhdGlvbnMiID0+IHRydWUsCiAgICAgICAgImtpbmQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvL0tpbmQgY29uc3RhbnRzCiAgICAvKioKICAgICAqICJ2YXIiIGtpbmQKICAgICAqLwogICAgY29uc3QgS0lORF9WQVIgPSAidmFyIjsKICAgIAogICAgLyoqCiAgICAgKiAibGV0IiBraW5kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfTEVUID0gImxldCI7CiAgICAKICAgIC8qKgogICAgICogImNvbnN0IiBraW5kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfQ09OU1QgPSAiY29uc3QiOwogICAgCiAgICAvKioKICAgICAqIERlY2xhcmF0aW9ucyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIFZhcmlhYmxlRGVjbGFyYXRvcltdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGRlY2xhcmF0aW9ucyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogRGVjbGFyYXRpb24ga2luZCB0aGF0IGlzIG9uZSBvZiB0aGUga2luZCBjb25zdGFudHMKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2luZCA9IHNlbGY6OktJTkRfVkFSOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlY2xhcmF0aW9ucyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIFZhcmlhYmxlRGVjbGFyYXRvcltdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWNsYXJhdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVjbGFyYXRpb25zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlY2xhcmF0aW9ucyBhcnJheQogICAgICogCiAgICAgKiBAcGFyYW0gVmFyaWFibGVEZWNsYXJhdG9yW10gJGRlY2xhcmF0aW9ucyBEZWNsYXJhdGlvbnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjbGFyYXRpb25zKCRkZWNsYXJhdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGRlY2xhcmF0aW9ucywgIlZhcmlhYmxlRGVjbGFyYXRvciIpOwogICAgICAgICR0aGlzLT5kZWNsYXJhdGlvbnMgPSAkZGVjbGFyYXRpb25zOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWNsYXJhdGlvbiBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2luZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5raW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlY2xhcmF0aW9uIGtpbmQgdGhhdCBpcyBvbmUgb2YgdGhlIGtpbmQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtpbmQgRGVjbGFyYXRpb24ga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgICR0aGlzLT5raW5kID0gJGtpbmQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgYm9vbGVhbiBsaXRlcmFsLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBCb29sZWFuTGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoJHZhbHVlID09PSAidHJ1ZSIpIHsKICAgICAgICAgICAgJHRoaXMtPnZhbHVlID0gdHJ1ZTsKICAgICAgICB9IGVsc2VpZiAoJHZhbHVlID09PSAiZmFsc2UiKSB7CiAgICAgICAgICAgICR0aGlzLT52YWx1ZSA9IGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT52YWx1ZSA9IChib29sKSAkdmFsdWU7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5yYXcgPSAkdGhpcy0+dmFsdWUgPyAidHJ1ZSIgOiAiZmFsc2UiOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBleHByZXNzaW9uIHdyYXBwZWQgaW4gcm91bmQgYnJhY2tldHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGV4cHJlc3Npb247CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHByZXNzaW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkZXhwcmVzc2lvbiBXcmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uICRleHByZXNzaW9uKQogICAgewogICAgICAgICR0aGlzLT5leHByZXNzaW9uID0gJGV4cHJlc3Npb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSAiYnJlYWsiIHN0YXRlbWVudCBpbnNpZGUgbG9vcHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEJyZWFrU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImxhYmVsIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBvcHRpb25hbCBsYWJlbCBvZiB0aGUgYnJlYWsgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEB2YXIgSWRlbnRpZmllciAKICAgICAqLwogICAgcHJvdGVjdGVkICRsYWJlbDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBub2RlJ3MgbGFiZWwKICAgICAqIAogICAgICogQHJldHVybiBJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMYWJlbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sYWJlbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBub2RlJ3MgbGFiZWwKICAgICAqIAogICAgICogQHBhcmFtIElkZW50aWZpZXIgJGxhYmVsIE5vZGUncyBsYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMYWJlbCgkbGFiZWwpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGxhYmVsLCAiSWRlbnRpZmllciIsIHRydWUpOwogICAgICAgICR0aGlzLT5sYWJlbCA9ICRsYWJlbDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSB5aWVsZCBzdGF0ZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFlpZWxkRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXJndW1lbnQiID0+IHRydWUsCiAgICAgICAgImRlbGVnYXRlIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBZaWVsZCBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogRGVsZWdhdGUgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgeWllbGQga2V5d29yZCBpcyBwcmVjZWRlZCBieSAqCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRkZWxlZ2F0ZSA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgeWllbGQgYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hcmd1bWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHlpZWxkIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRhcmd1bWVudCBBcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudCgkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGFyZ3VtZW50LCAiRXhwcmVzc2lvbiIsIHRydWUpOwogICAgICAgICR0aGlzLT5hcmd1bWVudCA9ICRhcmd1bWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVsZWdhdGUgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgeWllbGQga2V5d29yZCBpcwogICAgICogcHJlY2VkZWQgYnkgKgogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlbGVnYXRlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlbGVnYXRlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlbGVnYXRlIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHlpZWxkIGtleXdvcmQgaXMKICAgICAqIHByZWNlZGVkIGJ5ICoKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGRlbGVnYXRlIERlbGVnYXRlIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVsZWdhdGUoJGRlbGVnYXRlKQogICAgewogICAgICAgICR0aGlzLT5kZWxlZ2F0ZSA9IChib29sKSAkZGVsZWdhdGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuICJleHBvcnQgYWxsIiBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGU6IGV4cG9ydCAqIGZyb20gInRlc3QiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEV4cG9ydEFsbERlY2xhcmF0aW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIE1vZHVsZURlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAic291cmNlIiA9PiB0cnVlLAogICAgICAgICJleHBvcnRlZCIgPT4gdHJ1ZQogICAgKTsKCiAgICAvKioKICAgICAqIFRoZSBleHBvcnQgc291cmNlCiAgICAgKgogICAgICogQHZhciBMaXRlcmFsCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlOwoKICAgIC8qKgogICAgICogVGhlIGV4cG9ydGVkIG5hbWUKICAgICAqCiAgICAgKiBAdmFyIElkZW50aWZpZXJ8U3RyaW5nTGl0ZXJhbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGV4cG9ydGVkOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwb3J0IHNvdXJjZQogICAgICoKICAgICAqIEByZXR1cm4gTGl0ZXJhbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNvdXJjZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydCBzb3VyY2UKICAgICAqCiAgICAgKiBAcGFyYW0gTGl0ZXJhbCAkc291cmNlIEV4cG9ydCBzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2UoTGl0ZXJhbCAkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5zb3VyY2UgPSAkc291cmNlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydGVkIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIElkZW50aWZpZXJ8U3RyaW5nTGl0ZXJhbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwb3J0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXhwb3J0ZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHBvcnRlZCBuYW1lCiAgICAgKlcKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyfFN0cmluZ0xpdGVyYWwgJGV4cG9ydGVkIEV4cG9ydGVkIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHBvcnRlZCgkZXhwb3J0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGV4cG9ydGVkLCBhcnJheSgiSWRlbnRpZmllciIsICJTdHJpbmdMaXRlcmFsIiksIHRydWUpOwogICAgICAgICR0aGlzLT5leHBvcnRlZCA9ICRleHBvcnRlZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlICJ0aGlzIiBrZXl3b3JkLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUaGlzRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgc3ByZWFkIGVsZW1lbnQgaW4gYXJyYXkgbGl0ZXJhbHMgb3IgZnVuY3Rpb24KICogY2FsbHMuCiAqIEZvciBleGFtcGxlICIuLi5wYXJhbXMiIGluOiB0ZXN0KC4uLnBhcmFtcykKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU3ByZWFkRWxlbWVudCBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhcmd1bWVudCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgbm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5vZGUncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG5vZGUncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgTm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyZ3VtZW50KEV4cHJlc3Npb24gJGFyZ3VtZW50KQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudCA9ICRhcmd1bWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjaGFpbiBlbGVtZW50LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBDaGFpbkVsZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAib3B0aW9uYWwiID0+IGZhbHNlCiAgICApOwoKICAgIC8qKgogICAgICogT3B0aW9uYWwgZmxhZyB0aGF0IGlzIHRydWUgaWYgdGhlIG5vZGUgaXMgaW4gdGhlIG9wdGlvbmFsCiAgICAgKiBwYXJ0IG9mIGEgY2hhaW4gZXhwcmVzc2lvbgogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wdGlvbmFsID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBvcHRpb25hbCBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiB0aGUgbm9kZSBpcyBpbgogICAgICogdGhlIG9wdGlvbmFsIHBhcnQgb2YgYSBjaGFpbiBleHByZXNzaW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb25hbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcHRpb25hbDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIG9wdGlvbmFsIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBub2RlIGlzIGluCiAgICAgKiB0aGUgb3B0aW9uYWwgcGFydCBvZiBhIGNoYWluIGV4cHJlc3Npb24KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkb3B0aW9uYWwgT3B0aW9uYWwgZmxhZwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbmFsKCRvcHRpb25hbCkKICAgIHsKICAgICAgICAkdGhpcy0+b3B0aW9uYWwgPSAoYm9vbCkgJG9wdGlvbmFsOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHNwZWNpZmllciBpbiBhbiBleHBvcnQgZGVjbGFyYXRpb24uCiAqIEZvciBleGFtcGxlICJ7YX0iIGluOiBleHBvcnQge2F9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEV4cG9ydFNwZWNpZmllciBleHRlbmRzIE1vZHVsZVNwZWNpZmllcgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImV4cG9ydGVkIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEV4cG9ydGVkIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHZhciBJZGVudGlmaWVyfFN0cmluZ0xpdGVyYWwKICAgICAqLwogICAgcHJvdGVjdGVkICRleHBvcnRlZDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHBvcnRlZCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcnxTdHJpbmdMaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHBvcnRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHBvcnRlZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHBvcnRlZCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyfFN0cmluZ0xpdGVyYWwgJGV4cG9ydGVkIEV4cG9ydGVkIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhwb3J0ZWQoJGV4cG9ydGVkKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRleHBvcnRlZCwgYXJyYXkoIklkZW50aWZpZXIiLCAiU3RyaW5nTGl0ZXJhbCIpKTsKICAgICAgICAkdGhpcy0+ZXhwb3J0ZWQgPSAkZXhwb3J0ZWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSAic3VwZXIiIGtleXdvcmQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFN1cGVyIGV4dGVuZHMgTm9kZQp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gZW1wdHkgc3RhdGVtZW50ICg7KS4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRW1wdHlTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGRlYnVnZ2VyIHN0YXRlbWVudC4KICogRm9yIGV4YW1wbGU6IGRlYnVnZ2VyOwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBEZWJ1Z2dlclN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY29tbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tbWVudCBleHRlbmRzIE5vZGUKewogICAgLy9Db21tZW50IGtpbmQgY29uc3RhbnRzCiAgICAvKioKICAgICAqIElubGluZSBjb21tZW50CiAgICAgKi8KICAgIGNvbnN0IEtJTkRfSU5MSU5FID0gImlubGluZSI7CiAgICAKICAgIC8qKgogICAgICogTXVsdGlsaW5lIGNvbW1lbnQKICAgICAqLwogICAgY29uc3QgS0lORF9NVUxUSUxJTkUgPSAibXVsdGlsaW5lIjsKICAgIAogICAgLyoqCiAgICAgKiBIdG1sIG9wZW4gY29tbWVudAogICAgICovCiAgICBjb25zdCBLSU5EX0hUTUxfT1BFTiA9ICJodG1sLW9wZW4iOwogICAgCiAgICAvKioKICAgICAqIEh0bWwgY2xvc2UgY29tbWVudAogICAgICovCiAgICBjb25zdCBLSU5EX0hUTUxfQ0xPU0UgPSAiaHRtbC1jbG9zZSI7CiAgICAKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAia2luZCIgPT4gZmFsc2UsCiAgICAgICAgInRleHQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBjb21tZW50IGtpbmQKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2luZDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgY29tbWVudCB0ZXh0CiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHRleHQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tbWVudCBraW5kCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLaW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmtpbmQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29tbWVudCBraW5kCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtpbmQgQ29tbWVudCBraW5kCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEtpbmQoJGtpbmQpCiAgICB7CiAgICAgICAgJHRoaXMtPmtpbmQgPSAka2luZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tbWVudCB0ZXh0CiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUZXh0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRleHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29tbWVudCB0ZXh0CiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQgQ29tbWVudCB0ZXh0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRleHQoJHRleHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnRleHQgPSAkdGV4dDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tbWVudCByYXcgdGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmF3VGV4dCgpCiAgICB7CiAgICAgICAgJHRleHQgPSAkdGhpcy0+Z2V0VGV4dCgpOwogICAgICAgICRraW5kID0gJHRoaXMtPmdldEtpbmQoKTsKICAgICAgICAKICAgICAgICBpZiAoJGtpbmQgPT09IHNlbGY6OktJTkRfSU5MSU5FKSB7CiAgICAgICAgICAgIHJldHVybiAiLy8iIC4gJHRleHQ7CiAgICAgICAgfSBlbHNlaWYgKCRraW5kID09PSBzZWxmOjpLSU5EX0hUTUxfT1BFTikgewogICAgICAgICAgICByZXR1cm4gIjwhLS0iIC4gJHRleHQ7CiAgICAgICAgfSBlbHNlaWYgKCRraW5kID09PSBzZWxmOjpLSU5EX0hUTUxfQ0xPU0UpIHsKICAgICAgICAgICAgcmV0dXJuICItLT4iIC4gJHRleHQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICIvKiIgLiAkdGV4dCAuICIqLyI7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbW1lbnQgcmF3IHRleHQKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkcmF3VGV4dCBDb21tZW50IHJhdyB0ZXh0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJhd1RleHQoJHJhd1RleHQpCiAgICB7CiAgICAgICAgJHN0YXJ0ID0gc3Vic3RyKCRyYXdUZXh0LCAwLCAyKTsKICAgICAgICBpZiAoJHN0YXJ0ID09PSAiLy8iKSB7CiAgICAgICAgICAgICRraW5kID0gc2VsZjo6S0lORF9JTkxJTkU7CiAgICAgICAgICAgICR0ZXh0ID0gc3Vic3RyKCRyYXdUZXh0LCAyKTsKICAgICAgICB9IGVsc2VpZiAoJHN0YXJ0ID09PSAiLyoiICYmIHN1YnN0cigkcmF3VGV4dCwgLTIpID09PSAiKi8iKSB7CiAgICAgICAgICAgICRraW5kID0gc2VsZjo6S0lORF9NVUxUSUxJTkU7CiAgICAgICAgICAgICR0ZXh0ID0gc3Vic3RyKCRyYXdUZXh0LCAyLCAtMik7CiAgICAgICAgfSBlbHNlaWYgKCRzdGFydCA9PT0gIjwhIiAmJiBzdWJzdHIoJHJhd1RleHQsIDIsIDIpID09PSAiLS0iKSB7CiAgICAgICAgICAgICRraW5kID0gc2VsZjo6S0lORF9IVE1MX09QRU47CiAgICAgICAgICAgICR0ZXh0ID0gc3Vic3RyKCRyYXdUZXh0LCA0KTsKICAgICAgICB9IGVsc2VpZiAoJHN0YXJ0ID09PSAiLS0iICYmIHN1YnN0cigkcmF3VGV4dCwgMiwgMSkgPT09ICI+IikgewogICAgICAgICAgICAka2luZCA9IHNlbGY6OktJTkRfSFRNTF9DTE9TRTsKICAgICAgICAgICAgJHRleHQgPSBzdWJzdHIoJHJhd1RleHQsIDMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJJbnZhbGlkIGNvbW1lbnQiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRLaW5kKCRraW5kKS0+c2V0VGV4dCgkdGV4dCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBsZWFkaW5nIGNvbW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBDb21tZW50W10gJGNvbW1lbnRzIENvbW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlYWRpbmdDb21tZW50cygkY29tbWVudHMpCiAgICB7CiAgICAgICAgLy9Db21tZW50cyBjYW5ub3QgYmUgYXR0YWNoZWQgdG8gb3RoZXIgY29tbWVudHMKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0cmFpbGluZyBjb21tZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcGFyYW0gQ29tbWVudFtdICRjb21tZW50cyBDb21tZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFpbGluZ0NvbW1lbnRzKCRjb21tZW50cykKICAgIHsKICAgICAgICAvL0NvbW1lbnRzIGNhbm5vdCBiZSBhdHRhY2hlZCB0byBvdGhlciBjb21tZW50cwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2VyaWFsaXphYmxlIHZlcnNpb24gb2YgdGhlIG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICAjW1xSZXR1cm5UeXBlV2lsbENoYW5nZV0KICAgIHB1YmxpYyBmdW5jdGlvbiBqc29uU2VyaWFsaXplKCkKICAgIHsKICAgICAgICAkcmV0ID0gcGFyZW50Ojpqc29uU2VyaWFsaXplKCk7CiAgICAgICAgdW5zZXQoJHJldFsibGVhZGluZ0NvbW1lbnRzIl0pOwogICAgICAgIHVuc2V0KCRyZXRbInRyYWlsaW5nQ29tbWVudHMiXSk7CiAgICAgICAgcmV0dXJuICRyZXQ7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzZXF1ZW5jZSBvZiBleHByZXNzaW9ucy4KICogRm9yIGV4YW1wbGU6IGEsIGIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU2VxdWVuY2VFeHByZXNzaW9uICBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZXhwcmVzc2lvbnMiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogRXhwcmVzc2lvbnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uW10KICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9ucyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4cHJlc3Npb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb25zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb25zIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uW10gJGV4cHJlc3Npb25zIEV4cHJlc3Npb25zIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEV4cHJlc3Npb25zKCRleHByZXNzaW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkZXhwcmVzc2lvbnMsICJFeHByZXNzaW9uIik7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb25zID0gJGV4cHJlc3Npb25zOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBvYmplY3QgbGl0ZXJhbC4KICogRm9yIGV4YW1wbGU6IHthOiAxLCBiOiAyLCBjOiAzfQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBPYmplY3RFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJwcm9wZXJ0aWVzIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgUHJvcGVydHlbXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gUHJvcGVydHlbXSAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3BlcnRpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGVydGllczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEBwYXJhbSBQcm9wZXJ0eVtdICRwcm9wZXJ0aWVzIE9iamVjdCBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByb3BlcnRpZXMoJHByb3BlcnRpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJHByb3BlcnRpZXMsIGFycmF5KCJQcm9wZXJ0eSIsICJTcHJlYWRFbGVtZW50IikpOwogICAgICAgICR0aGlzLT5wcm9wZXJ0aWVzID0gJHByb3BlcnRpZXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBYnN0cmFjdCBjbGFzcyB0aGF0IGV4cG9ydCBhbmQgaW1wb3J0IHNwZWNpZmllcnMgbm9kZXMgbXVzdCBleHRlbmQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgTW9kdWxlU3BlY2lmaWVyIGV4dGVuZHMgTm9kZQp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImxvY2FsIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIExvY2FsIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHZhciBJZGVudGlmaWVyfFN0cmluZ0xpdGVyYWwKICAgICAqLwogICAgcHJvdGVjdGVkICRsb2NhbDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcnxTdHJpbmdMaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NhbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsb2NhbCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyfFN0cmluZ0xpdGVyYWwgJGxvY2FsIExvY2FsIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9jYWwoJGxvY2FsKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRsb2NhbCwgYXJyYXkoIklkZW50aWZpZXIiLCAiU3RyaW5nTGl0ZXJhbCIpKTsKICAgICAgICAkdGhpcy0+bG9jYWwgPSAkbG9jYWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY29uZGl0aW9uYWwgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IHRlc3QoKSA/IG9rKCkgOiBmYWlsKCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29uZGl0aW9uYWxFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJ0ZXN0IiA9PiB0cnVlLAogICAgICAgICJjb25zZXF1ZW50IiA9PiB0cnVlLAogICAgICAgICJhbHRlcm5hdGUiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdGVzdDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgY29uc2VxdWVudCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb25zZXF1ZW50OwogICAgCiAgICAvKioKICAgICAqIFRoZSBhbHRlcm5hdGUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYWx0ZXJuYXRlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRlc3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGVzdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0ZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHRlc3QgVGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlc3QoRXhwcmVzc2lvbiAkdGVzdCkKICAgIHsKICAgICAgICAkdGhpcy0+dGVzdCA9ICR0ZXN0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb25zZXF1ZW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25zZXF1ZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnNlcXVlbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29uc2VxdWVudCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRjb25zZXF1ZW50IENvbnNlcXVlbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25zZXF1ZW50KEV4cHJlc3Npb24gJGNvbnNlcXVlbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbnNlcXVlbnQgPSAkY29uc2VxdWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYWx0ZXJuYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbHRlcm5hdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWx0ZXJuYXRlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFsdGVybmF0ZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRhbHRlcm5hdGUgQWx0ZXJuYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWx0ZXJuYXRlKEV4cHJlc3Npb24gJGFsdGVybmF0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YWx0ZXJuYXRlID0gJGFsdGVybmF0ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gdXBkYXRlIGV4cHJlc3Npb24uCiAqIEZvciBleGFtcGxlOiBhKysKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVXBkYXRlRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXJndW1lbnQiID0+IHRydWUsCiAgICAgICAgIm9wZXJhdG9yIiA9PiBmYWxzZSwKICAgICAgICAicHJlZml4IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3Mgb3BlcmF0b3IKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRvcGVyYXRvcjsKICAgIAogICAgLyoqCiAgICAgKiBQcmVmaXggZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgb3BlcmF0b3IgcHJlY2VkZXMgdGhlIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByZWZpeCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIEV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRvcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3Mgb3BlcmF0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkb3BlcmF0b3IgT3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJlZml4IGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIG9wZXJhdG9yIHByZWNlZGVzIHRoZQogICAgICogYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmaXgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJlZml4OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByZWZpeCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBvcGVyYXRvciBwcmVjZWRlcyB0aGUKICAgICAqIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRwcmVmaXggUHJlZml4IGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZml4KCRwcmVmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZpeCA9ICRwcmVmaXg7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgQXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoRXhwcmVzc2lvbiAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50ID0gJGFyZ3VtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBpbXBvcnQgZXhwcmVzc2lvbiAoZHluYW1pYyBpbXBvcnQpLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBJbXBvcnRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJzb3VyY2UiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGNhdGNoIGNsYXVzZSBwYXJhbWV0ZXIKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHNvdXJjZSBJbXBvcnQgc291cmNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZShFeHByZXNzaW9uICRzb3VyY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNvdXJjZSA9ICRzb3VyY2U7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBJbnRlcmZhY2UgdGhhdCBldmVyeSBkZWNsYXJhdGlvbiBub2RlIG11c3QgaW1wbGVtZW50LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgRGVjbGFyYXRpb24gZXh0ZW5kcyBTdGF0ZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgcHJvcGVydHkgaW4gYW4gb2JqZWN0IGxpdGVyYWwuCiAqIEZvciBleGFtcGxlICJiIiBpbjogYSA9IHtiOiAxfQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBQcm9wZXJ0eSBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJrZXkiID0+IHRydWUsCiAgICAgICAgInZhbHVlIiA9PiB0cnVlLAogICAgICAgICJraW5kIiA9PiBmYWxzZSwKICAgICAgICAibWV0aG9kIiA9PiBmYWxzZSwKICAgICAgICAic2hvcnRoYW5kIiA9PiBmYWxzZSwKICAgICAgICAiY29tcHV0ZWQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvL0tpbmQgY29uc3RhbnRzCiAgICAvKioKICAgICAqIFRoZSBkZWZhdWx0IGtpbmQgZm9yIHByb3BlcnRpZXMKICAgICAqLwogICAgY29uc3QgS0lORF9JTklUID0gImluaXQiOwogICAgCiAgICAvKioKICAgICAqIEdldHRlciBwcm9wZXJ0eQogICAgICovCiAgICBjb25zdCBLSU5EX0dFVCA9ICJnZXQiOwogICAgCiAgICAvKioKICAgICAqIFNldHRlciBwcm9wZXJ0eQogICAgICovCiAgICBjb25zdCBLSU5EX1NFVCA9ICJzZXQiOwogICAgCiAgICAvKioKICAgICAqIFByb3BlcnR5IGtleQogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2V5OwogICAgCiAgICAvKioKICAgICAqIFByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR2YWx1ZTsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eSBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJGtpbmQgPSBzZWxmOjpLSU5EX0lOSVQ7CiAgICAKICAgIC8qKgogICAgICogUHJvcGVydHkgbWV0aG9kIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHByb3BlcnR5IGlzIGEgbWV0aG9kCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRtZXRob2QgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eSBzaG9ydGhhbmQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMgZGVjbGFyZWQKICAgICAqIHVzaW5nIGFuIGlkZW50aWZpZXIgYW5kIHdpdGhvdXQgYSB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2hvcnRoYW5kID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogUHJvcGVydHkgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMgZGVjbGFyZWQgdXNpbmcKICAgICAqIHRoZSBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21wdXRlZCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IGtleQogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5rZXk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkga2V5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRrZXkgUHJvcGVydHkga2V5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEtleShFeHByZXNzaW9uICRrZXkpCiAgICB7CiAgICAgICAgJHRoaXMtPmtleSA9ICRrZXk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHZhbHVlIFByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkdmFsdWUsICJFeHByZXNzaW9uIik7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2luZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5raW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb3BlcnR5IGtpbmQgdGhhdCBpcyBvbmUgb2YgdGhlIGtpbmQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtpbmQgUHJvcGVydHkga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgICR0aGlzLT5raW5kID0gJGtpbmQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IG1ldGhvZCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcyBhCiAgICAgKiBtZXRob2QKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNZXRob2QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWV0aG9kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb3BlcnR5IG1ldGhvZCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcyBhIG1ldGhvZAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkbWV0aG9kIE1ldGhvZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1ldGhvZCgkbWV0aG9kKQogICAgewogICAgICAgICR0aGlzLT5tZXRob2QgPSAoYm9vbCkgJG1ldGhvZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydHkgc2hvcnRoYW5kIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHByb3BlcnR5CiAgICAgKiBpcyBkZWNsYXJlZCB1c2luZyBhbiBpZGVudGlmaWVyIGFuZCB3aXRob3V0IGEgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBib29sIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2hvcnRoYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNob3J0aGFuZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eSBzaG9ydGhhbmQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkKICAgICAqIGlzIGRlY2xhcmVkIHVzaW5nIGFuIGlkZW50aWZpZXIgYW5kIHdpdGhvdXQgYSB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkc2hvcnRoYW5kIFByb3BlcnR5IHNob3J0aGFuZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNob3J0aGFuZCgkc2hvcnRoYW5kKQogICAgewogICAgICAgICR0aGlzLT5zaG9ydGhhbmQgPSAoYm9vbCkgJHNob3J0aGFuZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydHkgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMKICAgICAqIGRlY2xhcmVkIHVzaW5nIHRoZSBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcHV0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcHV0ZWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMKICAgICAqIGRlY2xhcmVkIHVzaW5nIHRoZSBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRjb21wdXRlZCBQcm9wZXJ0eSBjb21wdXRlZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbXB1dGVkKCRjb21wdXRlZCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcHV0ZWQgPSAoYm9vbCkgJGNvbXB1dGVkOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIG1lbWJlciBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogZm9vLmJhcgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBNZW1iZXJFeHByZXNzaW9uIGV4dGVuZHMgQ2hhaW5FbGVtZW50IGltcGxlbWVudHMgUGF0dGVybgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm9iamVjdCIgPT4gdHJ1ZSwKICAgICAgICAicHJvcGVydHkiID0+IHRydWUsCiAgICAgICAgImNvbXB1dGVkIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbnxTdXBlciAKICAgICAqLwogICAgcHJvdGVjdGVkICRvYmplY3Q7CiAgICAKICAgIC8qKgogICAgICogRXhwcmVzc2lvbidzIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbnxQcml2YXRlSWRlbnRpZmllcgogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnR5OwogICAgCiAgICAvKioKICAgICAqIENvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWNsYXJlZCB1c2luZyBzcXVhcmUKICAgICAqIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tcHV0ZWQgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbnxTdXBlciAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9iamVjdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vYmplY3Q7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbidzIG9iamVjdAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbnxTdXBlciAkb2JqZWN0IE9iamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPYmplY3QoJG9iamVjdCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkb2JqZWN0LCBhcnJheSgiRXhwcmVzc2lvbiIsICJTdXBlciIpKTsKICAgICAgICAkdGhpcy0+b2JqZWN0ID0gJG9iamVjdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbnxQcml2YXRlSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGVydHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbidzIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9ufFByaXZhdGVJZGVudGlmaWVyICRwcm9wZXJ0eSBQcm9wZXJ0eQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm9wZXJ0eSgkcHJvcGVydHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHByb3BlcnR5LCBhcnJheSgiRXhwcmVzc2lvbiIsICJQcml2YXRlSWRlbnRpZmllciIpKTsKICAgICAgICAkdGhpcy0+cHJvcGVydHkgPSAkcHJvcGVydHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWNsYXJlZAogICAgICogdXNpbmcgc3F1YXJlIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXB1dGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXB1dGVkOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWNsYXJlZAogICAgICogdXNpbmcgc3F1YXJlIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkY29tcHV0ZWQgQ29tcHV0ZWQgZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb21wdXRlZCgkY29tcHV0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXB1dGVkID0gKGJvb2wpICRjb21wdXRlZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBmdW5jdGlvbiBleHByZXNzaW9uCiAqIEZvciBleGFtcGxlOiB2YXIgdGVzdCA9IGZ1bmN0aW9uICgpIHt9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEZ1bmN0aW9uRXhwcmVzc2lvbiBleHRlbmRzIEZ1bmN0aW9uXyBpbXBsZW1lbnRzIEV4cHJlc3Npb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY2xhc3MgZXhwcmVzc2lvbgogKiBGb3IgZXhhbXBsZTogdGVzdCA9IGNsYXNzIHt9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIENsYXNzRXhwcmVzc2lvbiBleHRlbmRzIENsYXNzXyBpbXBsZW1lbnRzIEV4cHJlc3Npb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFzc2lnbm1lbnQgaW4gYSBiaW5kaW5nIGNvbnRleHQuCiAqIEZvciBleGFtcGxlICJhID0gYiIgaW46IHZhciB7YSA9IGJ9ID0gYwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBc3NpZ25tZW50UGF0dGVybiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBQYXR0ZXJuCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAicmlnaHQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGxlZnQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAdmFyIFBhdHRlcm4KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIFRoZSByaWdodCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJHJpZ2h0OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlZnQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIFBhdHRlcm4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExlZnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGVmdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsZWZ0IG5vZGUgb2YgdGhlIGFzc2lnbm1lbnQKICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm4gJGxlZnQgTGVmdCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlZnQoUGF0dGVybiAkbGVmdCkKICAgIHsKICAgICAgICAkdGhpcy0+bGVmdCA9ICRsZWZ0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByaWdodCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgUmlnaHQgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSaWdodChFeHByZXNzaW9uICRyaWdodCkKICAgIHsKICAgICAgICAkdGhpcy0+cmlnaHQgPSAkcmlnaHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSByZXR1cm4gc3RhdGVtZW50IGluc2lkZSBmdW5jdGlvbnMuCiAqIEZvciBleGFtcGxlOiByZXR1cm4gYSArIDEKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUmV0dXJuU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImFyZ3VtZW50IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE9wdGlvbmFsIGV4cHJlc3Npb24gYWZ0ZXIgdGhlIHJldHVybiBrZXl3b3JkCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRhcmd1bWVudDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIGFmdGVyIHRoZSByZXR1cm4ga2V5d29yZAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb24gYWZ0ZXIgdGhlIHJldHVybiBrZXl3b3JkCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRhcmd1bWVudCBUaGUgZXhwcmVzc2lvbiB0byByZXR1cm4KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoJGFyZ3VtZW50KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRhcmd1bWVudCwgIkV4cHJlc3Npb24iLCB0cnVlKTsKICAgICAgICAkdGhpcy0+YXJndW1lbnQgPSAkYXJndW1lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFzc2lnbm1lbnQgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IGEgPSBiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEFzc2lnbm1lbnRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJsZWZ0IiA9PiB0cnVlLAogICAgICAgICJvcGVyYXRvciIgPT4gZmFsc2UsCiAgICAgICAgInJpZ2h0IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBhc3NpZ25tZW50IG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwogICAgCiAgICAvKioKICAgICAqIFRoZSBsZWZ0IG5vZGUgb2YgdGhlIGFzc2lnbm1lbnQKICAgICAqIAogICAgICogQHZhciBQYXR0ZXJufEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIFRoZSByaWdodCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRyaWdodDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhc3NpZ25tZW50IG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRvcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhc3NpZ25tZW50IG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIEFzc2lnbm1lbnQgb3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGVmdCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gUGF0dGVybnxFeHByZXNzaW9uIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGVmdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sZWZ0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxlZnQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcGFyYW0gUGF0dGVybnxFeHByZXNzaW9uICRsZWZ0IFRoZSBub2RlIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZWZ0KCRsZWZ0KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRsZWZ0LCBhcnJheSgiUGF0dGVybiIsICJFeHByZXNzaW9uIikpOwogICAgICAgICR0aGlzLT5sZWZ0ID0gJGxlZnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJpZ2h0IG5vZGUgb2YgdGhlIGFzc2lnbm1lbnQKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgVGhlIG5vZGUgdG8gc2V0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJpZ2h0KEV4cHJlc3Npb24gJHJpZ2h0KQogICAgewogICAgICAgICR0aGlzLT5yaWdodCA9ICRyaWdodDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBwcm9wZXJ0eSBpbiBhbiBvYmplY3QgYmluZGluZyBwYXR0ZXJuLgogKiBGb3IgZXhhbXBsZSAiYSIgaW46IHZhciB7YX0gPSBiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEFzc2lnbm1lbnRQcm9wZXJ0eSBleHRlbmRzIFByb3BlcnR5CnsKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICJQcm9wZXJ0eSI7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm4gJHZhbHVlIFByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkdmFsdWUsICJQYXR0ZXJuIik7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eSBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRraW5kIFByb3BlcnR5IGtpbmQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eSBtZXRob2QgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMgYSBtZXRob2QKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJG1ldGhvZCBNZXRob2QgZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1ldGhvZCgkbWV0aG9kKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGJsb2NrIG9mIGNvZGUgd3JhcHBlZCBpbiBjdXJseSBicmFjZXMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEJsb2NrU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQmxvY2sncyBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50W10gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keSA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBibG9jaydzIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgYmxvY2sncyBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnRbXSAkYm9keSBBcnJheSBvZiBTdGF0ZW1lbnRzIHRoYXQgYXJlIHRoZSBib2R5IG9mIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGJvZHksICJTdGF0ZW1lbnQiKTsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQWJzdHJhY3QgY2xhc3MgZm9yIGNsYXNzZXMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIENsYXNzXyBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJpZCIgPT4gdHJ1ZSwKICAgICAgICAic3VwZXJDbGFzcyIgPT4gdHJ1ZSwKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBDbGFzcyBuYW1lCiAgICAgKiAKICAgICAqIEB2YXIgSWRlbnRpZmllciAKICAgICAqLwogICAgcHJvdGVjdGVkICRpZDsKICAgIAogICAgLyoqCiAgICAgKiBFeHRlbmRlZCBjbGFzcwogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3VwZXJDbGFzczsKICAgIAogICAgLyoqCiAgICAgKiBDbGFzcyBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgQ2xhc3NCb2R5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGJvZHk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBjbGFzcyBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBjbGFzcyBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyICRpZCBDbGFzcyBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElkKCRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkaWQsICJJZGVudGlmaWVyIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmlkID0gJGlkOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGV4dGVuZGVkIGNsYXNzCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3VwZXJDbGFzcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdXBlckNsYXNzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgZXh0ZW5kZWQgY2xhc3MKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHN1cGVyQ2xhc3MgRXh0ZW5kZWQgY2xhc3MKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3VwZXJDbGFzcygkc3VwZXJDbGFzcykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkc3VwZXJDbGFzcywgIkV4cHJlc3Npb24iLCB0cnVlKTsKICAgICAgICAkdGhpcy0+c3VwZXJDbGFzcyA9ICRzdXBlckNsYXNzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGNsYXNzIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBDbGFzc0JvZHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIGNsYXNzIGJvZHkKICAgICAqIAogICAgICogQHBhcmFtIENsYXNzQm9keSAkYm9keSBDbGFzcyBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGJvZHksICJDbGFzc0JvZHkiKTsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIFBhcnNlciBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBQYXJzZXIgZXh0ZW5kcyBQYXJzZXJBYnN0cmFjdAp7CiAgICB1c2UgSlNYXFBhcnNlcjsKICAgIAogICAgLy9JZGVudGlmaWVyIHBhcnNpbmcgbW9kZSBjb25zdGFudHMKICAgIC8qKgogICAgICogRXZlcnl0aGluZyBpcyBhbGxvd2VkIGFzIGlkZW50aWZpZXIsIGluY2x1ZGluZyBrZXl3b3JkcywgbnVsbCBhbmQgYm9vbGVhbnMKICAgICAqLwogICAgY29uc3QgSURfQUxMT1dfQUxMID0gMTsKICAgIAogICAgLyoqCiAgICAgKiBLZXl3b3JkcywgbnVsbCBhbmQgYm9vbGVhbnMgYXJlIG5vdCBhbGxvd2VkIGluIGFueSBzaXR1YXRpb24KICAgICAqLwogICAgY29uc3QgSURfQUxMT1dfTk9USElORyA9IDI7CiAgICAKICAgIC8qKgogICAgICogS2V5d29yZHMsIG51bGwgYW5kIGJvb2xlYW5zIGFyZSBub3QgYWxsb3dlZCBpbiBhbnkgc2l0dWF0aW9uLCBmdXR1cmUKICAgICAqIHJlc2VydmVkIHdvcmRzIGFyZSBhbGxvd2VkIGlmIG5vdCBpbiBzdHJpY3QgbW9kZS4gS2V5d29yZHMgdGhhdCBkZXBlbmQgb24KICAgICAqIHBhcnNlciBjb250ZXh0IGFyZSBldmFsdWF0ZWQgb25seSBpZiB0aGUgcGFyc2VyIGNvbnRleHQgYWxsb3dzIHRoZW0uCiAgICAgKi8KICAgIGNvbnN0IElEX01JWEVEID0gMzsKICAgIAogICAgLyoqCiAgICAgKiBCaW5kaW5nIGlkZW50aWZpZXIgcGFyc2luZyBydWxlCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRiaW5kaW5nSWRlbnRpZmllciA9IHNlbGY6OklEX01JWEVEOwogICAgCiAgICAvKioKICAgICAqIExhYmVsbGVkIGlkZW50aWZpZXIgcGFyc2luZyBydWxlCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRsYWJlbGxlZElkZW50aWZpZXIgPSBzZWxmOjpJRF9NSVhFRDsKICAgIAogICAgLyoqCiAgICAgKiBJZGVudGlmaWVyIHJlZmVyZW5jZSBwYXJzaW5nIHJ1bGUKICAgICAqIAogICAgICogQHZhciBpbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgJGlkZW50aWZpZXJSZWZlcmVuY2UgPSBzZWxmOjpJRF9NSVhFRDsKICAgIAogICAgLyoqCiAgICAgKiBJZGVudGlmaWVyIG5hbWUgcGFyc2luZyBydWxlCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRpZGVudGlmaWVyTmFtZSA9IHNlbGY6OklEX0FMTE9XX0FMTDsKICAgIAogICAgLyoqCiAgICAgKiBJbXBvcnRlZCBiaW5kaW5nIHBhcnNpbmcgcnVsZQogICAgICogCiAgICAgKiBAdmFyIGludCAKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyAkaW1wb3J0ZWRCaW5kaW5nID0gc2VsZjo6SURfQUxMT1dfTk9USElORzsKICAgIAogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9ycwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFzc2lnbm1lbnRPcGVyYXRvcnMgPSBhcnJheSgKICAgICAgICAiPSIsICIrPSIsICItPSIsICIqPSIsICIvPSIsICIlPSIsICI8PD0iLCAiPj49IiwgIj4+Pj0iLCAiJj0iLCAiXj0iLAogICAgICAgICJ8PSIsICIqKj0iLCAiJiY9IiwgInx8PSIsICI/Pz0iCiAgICApOwogICAgCiAgICAvKioKICAgICAqIExvZ2ljYWwgYW5kIGJpbmFyeSBvcGVyYXRvcnMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRsb2dpY2FsQmluYXJ5T3BlcmF0b3JzID0gYXJyYXkoCiAgICAgICAgIj8/IiA9PiAwLAogICAgICAgICJ8fCIgPT4gMCwKICAgICAgICAiJiYiID0+IDEsCiAgICAgICAgInwiID0+IDIsCiAgICAgICAgIl4iID0+IDMsCiAgICAgICAgIiYiID0+IDQsCiAgICAgICAgIj09PSIgPT4gNSwgIiE9PSIgPT4gNSwgIj09IiA9PiA1LCAiIT0iID0+IDUsCiAgICAgICAgIjw9IiA9PiA2LCAiPj0iID0+IDYsICI8IiA9PiA2LCAiPiIgPT4gNiwKICAgICAgICAiaW5zdGFuY2VvZiIgPT4gNiwgImluIiA9PiA2LAogICAgICAgICI+Pj4iID0+IDcsICI8PCIgPT4gNywgIj4+IiA9PiA3LAogICAgICAgICIrIiA9PiA4LCAiLSIgPT4gOCwKICAgICAgICAiKiIgPT4gOSwgIi8iID0+IDksICIlIiA9PiA5LAogICAgICAgICIqKiIgPT4gMTAKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVW5hcnkgb3BlcmF0b3JzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdW5hcnlPcGVyYXRvcnMgPSBhcnJheSgKICAgICAgICAiZGVsZXRlIiwgInZvaWQiLCAidHlwZW9mIiwgIisrIiwgIi0tIiwgIisiLCAiLSIsICJ+IiwgIiEiCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFBvc3RmaXggb3BlcmF0b3JzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcG9zdGZpeE9wZXJhdG9ycyA9IGFycmF5KCItLSIsICIrKyIpOwogICAgCiAgICAvKioKICAgICAqIEFycmF5IG9mIGtleXdvcmRzIHRoYXQgZGVwZW5kcyBvbiBhIGNvbnRleHQgcHJvcGVydHkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb250ZXh0S2V5d29yZHMgPSBhcnJheSgKICAgICAgICAieWllbGQiID0+ICJhbGxvd1lpZWxkIiwKICAgICAgICAiYXdhaXQiID0+ICJhbGxvd0F3YWl0IgogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBwYXJzZXIgY29udGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRDb250ZXh0KCkKICAgIHsKICAgICAgICAkY29udGV4dCA9IGFycmF5KAogICAgICAgICAgICAiYWxsb3dSZXR1cm4iID0+IGZhbHNlLAogICAgICAgICAgICAiYWxsb3dJbiIgPT4gZmFsc2UsCiAgICAgICAgICAgICJhbGxvd1lpZWxkIiA9PiBmYWxzZSwKICAgICAgICAgICAgImFsbG93QXdhaXQiID0+IGZhbHNlCiAgICAgICAgKTsKICAgICAgICAvL0lmIGFzeW5jL2F3YWl0IGlzIG5vdCBlbmFibGVkIHJlbW92ZSB0aGUKICAgICAgICAvL3JlbGF0aXZlIGNvbnRleHQgcHJvcGVydGllcwogICAgICAgIGlmICghJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0KSB7CiAgICAgICAgICAgIHVuc2V0KCRjb250ZXh0WyJhbGxvd0F3YWl0Il0pOwogICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29udGV4dEtleXdvcmRzWyJhd2FpdCJdKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNvbnRleHQgPSAob2JqZWN0KSAkY29udGV4dDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQb3N0IGluaXRpYWxpemUgb3BlcmF0aW9ucwogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBvc3RJbml0KCkKICAgIHsKICAgICAgICAvL1JlbW92ZSBleHBvbmVudGlhdGlvbiBvcGVyYXRvciBpZiB0aGUgZmVhdHVyZQogICAgICAgIC8vaXMgbm90IGVuYWJsZWQKICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+ZXhwb25lbnRpYXRpb25PcGVyYXRvcikgewogICAgICAgICAgICBVdGlsczo6cmVtb3ZlQXJyYXlWYWx1ZSgKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NpZ25tZW50T3BlcmF0b3JzLAogICAgICAgICAgICAgICAgIioqPSIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmxvZ2ljYWxCaW5hcnlPcGVyYXRvcnNbIioqIl0pOwogICAgICAgIH0KCiAgICAgICAgLy9SZW1vdmUgY29hbGVzY2luZyBvcGVyYXRvciBpZiB0aGUgZmVhdHVyZQogICAgICAgIC8vaXMgbm90IGVuYWJsZWQKICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+Y29hbGVzY2luZ09wZXJhdG9yKSB7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5sb2dpY2FsQmluYXJ5T3BlcmF0b3JzWyI/PyJdKTsKICAgICAgICB9CgogICAgICAgIC8vUmVtb3ZlIGxvZ2ljYWwgYXNzaWdubWVudCBvcGVyYXRvcnMgaWYgdGhlCiAgICAgICAgLy9mZWF0dXJlIGlzIG5vdCBlbmFibGVkCiAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmxvZ2ljYWxBc3NpZ25tZW50T3BlcmF0b3JzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCImJj0iLCAifHw9IiwgIj8/PSIpIGFzICRvcCkgewogICAgICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFzc2lnbm1lbnRPcGVyYXRvcnMsCiAgICAgICAgICAgICAgICAgICAgJG9wCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgc291cmNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxQcm9ncmFtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zb3VyY2VUeXBlID09PSBcUGVhc3RcUGVhc3Q6OlNPVVJDRV9UWVBFX01PRFVMRSkgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RyaWN0TW9kZSh0cnVlKTsKICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VNb2R1bGVJdGVtTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50TGlzdCh0cnVlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgIlByb2dyYW0iLCAkYm9keSA/OiAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKQogICAgICAgICk7CiAgICAgICAgJG5vZGUtPnNldFNvdXJjZVR5cGUoJHRoaXMtPnNvdXJjZVR5cGUpOwogICAgICAgIGlmICgkYm9keSkgewogICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgfQogICAgICAgICRwcm9ncmFtID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgCiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpKSB7CiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0V4ZWN1dGUgc2Nhbm5lciBlbmQgb3BlcmF0aW9ucwogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lRW5kKCk7CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBFbmRQYXJzaW5nIGV2ZW50IGFuZCBwYXNzIHRoZSByZXN1bHRpbmcgcHJvZ3JhbSBub2RlIGFzCiAgICAgICAgLy9ldmVudCBkYXRhCiAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICJFbmRQYXJzaW5nIiwgYXJyYXkoJHByb2dyYW0pCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJHByb2dyYW07CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29udmVydHMgYW4gZXhwcmVzc2lvbiBub2RlIHRvIGEgcGF0dGVybiBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgJG5vZGUgVGhlIG5vZGUgdG8gY29udmVydAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhwcmVzc2lvblRvUGF0dGVybigkbm9kZSkKICAgIHsKICAgICAgICBpZiAoJG5vZGUgaW5zdGFuY2VvZiBOb2RlXEFycmF5RXhwcmVzc2lvbikgewogICAgICAgICAgICAKICAgICAgICAgICAgJGxvYyA9ICRub2RlLT5sb2NhdGlvbjsKICAgICAgICAgICAgJGVsZW1zID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJG5vZGUtPmdldEVsZW1lbnRzKCkgYXMgJGVsZW0pIHsKICAgICAgICAgICAgICAgICRlbGVtc1tdID0gJHRoaXMtPmV4cHJlc3Npb25Ub1BhdHRlcm4oJGVsZW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgJHJldE5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQXJyYXlQYXR0ZXJuIiwgJGxvYy0+c3RhcnQpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0RWxlbWVudHMoJGVsZW1zKTsKICAgICAgICAgICAgJHRoaXMtPmNvbXBsZXRlTm9kZSgkcmV0Tm9kZSwgJGxvYy0+ZW5kKTsKICAgICAgICAgICAgCiAgICAgICAgfSBlbHNlaWYgKCRub2RlIGluc3RhbmNlb2YgTm9kZVxPYmplY3RFeHByZXNzaW9uKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbG9jID0gJG5vZGUtPmxvY2F0aW9uOwogICAgICAgICAgICAkcHJvcHMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbm9kZS0+Z2V0UHJvcGVydGllcygpIGFzICRwcm9wKSB7CiAgICAgICAgICAgICAgICAkcHJvcHNbXSA9ICR0aGlzLT5leHByZXNzaW9uVG9QYXR0ZXJuKCRwcm9wKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICRyZXROb2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk9iamVjdFBhdHRlcm4iLCAkbG9jLT5zdGFydCk7CiAgICAgICAgICAgICRyZXROb2RlLT5zZXRQcm9wZXJ0aWVzKCRwcm9wcyk7CiAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJHJldE5vZGUsICRsb2MtPmVuZCk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgkbm9kZSBpbnN0YW5jZW9mIE5vZGVcUHJvcGVydHkpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRsb2MgPSAkbm9kZS0+bG9jYXRpb247CiAgICAgICAgICAgICRyZXROb2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICAgICAiQXNzaWdubWVudFByb3BlcnR5IiwgJGxvYy0+c3RhcnQKICAgICAgICAgICAgKTsKICAgICAgICAgICAgLy8gSWYgaXQncyBhIHNob3J0aGFuZCBwcm9wZXJ0eSBjb252ZXJ0IHRoZSB2YWx1ZSB0byBhbiBhc3NpZ25tZW50CiAgICAgICAgICAgIC8vIHBhdHRlcm4gaWYgbmVjZXNzYXJ5CiAgICAgICAgICAgICR2YWx1ZSA9ICRub2RlLT5nZXRWYWx1ZSgpOwogICAgICAgICAgICAka2V5ID0gJG5vZGUtPmdldEtleSgpOwogICAgICAgICAgICBpZiAoJHZhbHVlICYmICRub2RlLT5nZXRTaG9ydGhhbmQoKSAmJgogICAgICAgICAgICAgICAgISR2YWx1ZSBpbnN0YW5jZW9mIE5vZGVcQXNzaWdubWVudEV4cHJlc3Npb24gJiYKICAgICAgICAgICAgICAgICghJHZhbHVlIGluc3RhbmNlb2YgTm9kZVxJZGVudGlmaWVyIHx8ICgKICAgICAgICAgICAgICAgICRrZXkgaW5zdGFuY2VvZiBOb2RlXElkZW50aWZpZXIgJiYgJGtleS0+Z2V0TmFtZSgpICE9PSAkdmFsdWUtPmdldE5hbWUoKQogICAgICAgICAgICAgICAgKSkpIHsKICAgICAgICAgICAgICAgICRsb2MgPSAkbm9kZS0+bG9jYXRpb247CiAgICAgICAgICAgICAgICAkdmFsTm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBc3NpZ25tZW50UGF0dGVybiIsICRsb2MtPnN0YXJ0KTsKICAgICAgICAgICAgICAgICR2YWxOb2RlLT5zZXRMZWZ0KCRrZXkpOwogICAgICAgICAgICAgICAgJHZhbE5vZGUtPnNldFJpZ2h0KCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKCR2YWxOb2RlLCAkbG9jLT5lbmQpOwogICAgICAgICAgICAgICAgJHZhbHVlID0gJHZhbE5vZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+ZXhwcmVzc2lvblRvUGF0dGVybigkdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXROb2RlLT5zZXRWYWx1ZSgkdmFsdWUpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0S2V5KCRrZXkpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0TWV0aG9kKCRub2RlLT5nZXRNZXRob2QoKSk7CiAgICAgICAgICAgICRyZXROb2RlLT5zZXRTaG9ydGhhbmQoJG5vZGUtPmdldFNob3J0aGFuZCgpKTsKICAgICAgICAgICAgJHJldE5vZGUtPnNldENvbXB1dGVkKCRub2RlLT5nZXRDb21wdXRlZCgpKTsKICAgICAgICAgICAgJHRoaXMtPmNvbXBsZXRlTm9kZSgkcmV0Tm9kZSwgJGxvYy0+ZW5kKTsKICAgICAgICAgICAgCiAgICAgICAgfSBlbHNlaWYgKCRub2RlIGluc3RhbmNlb2YgTm9kZVxTcHJlYWRFbGVtZW50KSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbG9jID0gJG5vZGUtPmxvY2F0aW9uOwogICAgICAgICAgICAkcmV0Tm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJSZXN0RWxlbWVudCIsICRsb2MtPnN0YXJ0KTsKICAgICAgICAgICAgJHJldE5vZGUtPnNldEFyZ3VtZW50KAogICAgICAgICAgICAgICAgJHRoaXMtPmV4cHJlc3Npb25Ub1BhdHRlcm4oJG5vZGUtPmdldEFyZ3VtZW50KCkpCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJHJldE5vZGUsICRsb2MtPmVuZCk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgkbm9kZSBpbnN0YW5jZW9mIE5vZGVcQXNzaWdubWVudEV4cHJlc3Npb24pIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRsb2MgPSAkbm9kZS0+bG9jYXRpb247CiAgICAgICAgICAgICRyZXROb2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFzc2lnbm1lbnRQYXR0ZXJuIiwgJGxvYy0+c3RhcnQpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0TGVmdCgkdGhpcy0+ZXhwcmVzc2lvblRvUGF0dGVybigkbm9kZS0+Z2V0TGVmdCgpKSk7CiAgICAgICAgICAgICRyZXROb2RlLT5zZXRSaWdodCgkbm9kZS0+Z2V0UmlnaHQoKSk7CiAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJHJldE5vZGUsICRsb2MtPmVuZCk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXROb2RlID0gJG5vZGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0Tm9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdGF0ZW1lbnQgbGlzdAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkcGFyc2VEaXJlY3RpdmVQcm9sb2d1ZXMgVHJ1ZSB0byBwYXJzZSBkaXJlY3RpdmUgcHJvbG9ndWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTdGF0ZW1lbnRMaXN0KAogICAgICAgICRwYXJzZURpcmVjdGl2ZVByb2xvZ3VlcyA9IGZhbHNlCiAgICApIHsKICAgICAgICAkaXRlbXMgPSBhcnJheSgpOwogICAgICAgIAogICAgICAgIC8vR2V0IGRpcmVjdGl2ZSBwcm9sb2d1ZXMgYW5kIGNoZWNrIGlmIHN0cmljdCBtb2RlIGlzIHByZXNlbnQKICAgICAgICBpZiAoJHBhcnNlRGlyZWN0aXZlUHJvbG9ndWVzKSB7CiAgICAgICAgICAgICRvbGRTdHJpY3RNb2RlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKTsKICAgICAgICAgICAgaWYgKCRkaXJlY3RpdmVzID0gJHRoaXMtPnBhcnNlRGlyZWN0aXZlUHJvbG9ndWVzKCkpIHsKICAgICAgICAgICAgICAgICRpdGVtcyA9IGFycmF5X21lcmdlKCRpdGVtcywgJGRpcmVjdGl2ZXNbMF0pOwogICAgICAgICAgICAgICAgLy9JZiAidXNlIHN0cmljdCIgaXMgcHJlc2VudCBlbmFibGUgc2Nhbm5lciBzdHJpY3QgbW9kZQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCJ1c2Ugc3RyaWN0IiwgJGRpcmVjdGl2ZXNbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0cmljdE1vZGUodHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgd2hpbGUgKCRpdGVtID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50TGlzdEl0ZW0oKSkgewogICAgICAgICAgICAkaXRlbXNbXSA9ICRpdGVtOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0FwcGx5IHByZXZpb3VzIHN0cmljdCBtb2RlCiAgICAgICAgaWYgKCRwYXJzZURpcmVjdGl2ZVByb2xvZ3VlcykgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RyaWN0TW9kZSgkb2xkU3RyaWN0TW9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBjb3VudCgkaXRlbXMpID8gJGl0ZW1zIDogbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdGF0ZW1lbnQgbGlzdCBpdGVtCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxTdGF0ZW1lbnR8Tm9kZVxEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVN0YXRlbWVudExpc3RJdGVtKCkKICAgIHsKICAgICAgICBpZiAoJGRlY2xhcmF0aW9uID0gJHRoaXMtPnBhcnNlRGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGRlY2xhcmF0aW9uOwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICAvL0hlcmUgdGhlIHRva2VuIHZhbHVlIGlzIGNoZWNrZWQgZm9yIHBlcmZvcm1hbmNlIHNvIHRoYXQgZnVuY3Rpb25zIHdvbid0IGJlCiAgICAgICAgLy9jYWxsZWQgaWYgbm90IG5lY2Vzc2FyeQogICAgICAgICR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgIGlmICghJHRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkdmFsID0gJHRva2VuLT52YWx1ZTsKICAgICAgICBpZiAoJHZhbCA9PT0gInsiICYmICRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VCbG9jaygpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkdmFsID09PSAidmFyIiAmJiAkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlVmFyaWFibGVTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHZhbCA9PT0gIjsiICYmICRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VFbXB0eVN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkdmFsID09PSAiaWYiICYmICRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VJZlN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgKCR2YWwgPT09ICJmb3IiIHx8ICR2YWwgPT09ICJ3aGlsZSIgfHwgJHZhbCA9PT0gImRvIiB8fCAkdmFsID09PSAic3dpdGNoIikgJiYKICAgICAgICAgICAgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUJyZWFrYWJsZVN0YXRlbWVudCgpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkdmFsID09ICJjb250aW51ZSIgJiYgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUNvbnRpbnVlU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKCR2YWwgPT09ICJicmVhayIgJiYgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUJyZWFrU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKAogICAgICAgICAgICAkdGhpcy0+Y29udGV4dC0+YWxsb3dSZXR1cm4gJiYgJHZhbCA9PT0gInJldHVybiIgJiYKICAgICAgICAgICAgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZVJldHVyblN0YXRlbWVudCgpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkdmFsID09PSAid2l0aCIgJiYgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZVdpdGhTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHZhbCA9PT0gInRocm93IiAmJiAkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlVGhyb3dTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHZhbCA9PT0gInRyeSIgJiYgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZVRyeVN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkdmFsID09PSAiZGVidWdnZXIiICYmICRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VEZWJ1Z2dlclN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlTGFiZWxsZWRTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUV4cHJlc3Npb25TdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXERlY2xhcmF0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRGVjbGFyYXRpb24oKQogICAgewogICAgICAgIC8vSGVyZSB0aGUgdG9rZW4gdmFsdWUgaXMgY2hlY2tlZCBmb3IgcGVyZm9ybWFuY2Ugc28gdGhhdCBmdW5jdGlvbnMgd29uJ3QgYmUKICAgICAgICAvL2NhbGxlZCBpZiBub3QgbmVjZXNzYXJ5CiAgICAgICAgJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCk7CiAgICAgICAgaWYgKCEkdG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICR2YWwgPSAkdG9rZW4tPnZhbHVlOwogICAgICAgIGlmICgkZGVjbGFyYXRpb24gPSAkdGhpcy0+cGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGRlY2xhcmF0aW9uOwogICAgICAgIH0gZWxzZWlmICgkdmFsID09PSAiY2xhc3MiICYmICRkZWNsYXJhdGlvbiA9ICR0aGlzLT5wYXJzZUNsYXNzRGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGRlY2xhcmF0aW9uOwogICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgKCR2YWwgPT09ICJsZXQiIHx8ICR2YWwgPT09ICJjb25zdCIpICYmCiAgICAgICAgICAgICRkZWNsYXJhdGlvbiA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlTGV4aWNhbERlY2xhcmF0aW9uIgogICAgICAgICAgICApCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiAkZGVjbGFyYXRpb247CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGJyZWFrYWJsZSBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VCcmVha2FibGVTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlSXRlcmF0aW9uU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VTd2l0Y2hTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgYmxvY2sgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxCbG9ja1N0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUJsb2NrKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJHN0YXRlbWVudHMgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnRMaXN0KCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJCbG9ja1N0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICBpZiAoJHN0YXRlbWVudHMpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkc3RhdGVtZW50cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG1vZHVsZSBpdGVtIGxpc3QKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGVbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU1vZHVsZUl0ZW1MaXN0KCkKICAgIHsKICAgICAgICAkaXRlbXMgPSBhcnJheSgpOwogICAgICAgIHdoaWxlICgkaXRlbSA9ICR0aGlzLT5wYXJzZU1vZHVsZUl0ZW0oKSkgewogICAgICAgICAgICAkaXRlbXNbXSA9ICRpdGVtOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY291bnQoJGl0ZW1zKSA/ICRpdGVtcyA6IG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGVtcHR5IHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcRW1wdHlTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VFbXB0eVN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI7IikpIHsKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRW1wdHlTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGRlYnVnZ2VyIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcRGVidWdnZXJTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VEZWJ1Z2dlclN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJkZWJ1Z2dlciIpKSB7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkRlYnVnZ2VyU3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGlmIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcSWZTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VJZlN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpZiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCR0ZXN0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAgICAgKCRjb25zZXF1ZW50ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkpIHx8CiAgICAgICAgICAgICAgICAgICAgKCEkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpICYmCiAgICAgICAgICAgICAgICAgICAgJGNvbnNlcXVlbnQgPSAkdGhpcy0+cGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRGVjbGFyYXRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBmYWxzZQogICAgICAgICAgICAgICAgICAgICkpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJJZlN0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VGVzdCgkdGVzdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZWxzZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCgkYWx0ZXJuYXRlID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICghJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAkYWx0ZXJuYXRlID0gJHRoaXMtPnBhcnNlRnVuY3Rpb25PckdlbmVyYXRvckRlY2xhcmF0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICkpCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRBbHRlcm5hdGUoJGFsdGVybmF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHRyeS1jYXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFRyeVN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVRyeVN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ0cnkiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRibG9jayA9ICR0aGlzLT5wYXJzZUJsb2NrKCkpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVHJ5U3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCbG9jaygkYmxvY2spOwoKICAgICAgICAgICAgICAgIGlmICgkaGFuZGxlciA9ICR0aGlzLT5wYXJzZUNhdGNoKCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SGFuZGxlcigkaGFuZGxlcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRmaW5hbGl6ZXIgPSAkdGhpcy0+cGFyc2VGaW5hbGx5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RmluYWxpemVyKCRmaW5hbGl6ZXIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkaGFuZGxlciB8fCAkZmluYWxpemVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBjYXRjaCBibG9jayBvZiBhIHRyeS1jYXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXENhdGNoQ2xhdXNlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2F0Y2goKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiY2F0Y2giKSkgewoKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ2F0Y2hDbGF1c2UiLCAkdG9rZW4pOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikpIHsKICAgICAgICAgICAgICAgIGlmICghKCRwYXJhbSA9ICR0aGlzLT5wYXJzZUNhdGNoUGFyYW1ldGVyKCkpIHx8CiAgICAgICAgICAgICAgICAgICAgISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRub2RlLT5zZXRQYXJhbSgkcGFyYW0pOwogICAgICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5mZWF0dXJlcy0+b3B0aW9uYWxDYXRjaEJpbmRpbmcpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISgkYm9keSA9ICR0aGlzLT5wYXJzZUJsb2NrKCkpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIGNhdGNoIHBhcmFtZXRlciBvZiBhIGNhdGNoIGJsb2NrIGluIGEgdHJ5LWNhdGNoIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNhdGNoUGFyYW1ldGVyKCkKICAgIHsKICAgICAgICBpZiAoJHBhcmFtID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRiaW5kaW5nSWRlbnRpZmllcikpIHsKICAgICAgICAgICAgcmV0dXJuICRwYXJhbTsKICAgICAgICB9IGVsc2VpZiAoJHBhcmFtID0gJHRoaXMtPnBhcnNlQmluZGluZ1BhdHRlcm4oKSkgewogICAgICAgICAgICByZXR1cm4gJHBhcmFtOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBmaW5hbGx5IGJsb2NrIGluIGEgdHJ5LWNhdGNoIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQmxvY2tTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGaW5hbGx5KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImZpbmFsbHkiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRibG9jayA9ICR0aGlzLT5wYXJzZUJsb2NrKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYmxvY2s7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjb250aW51ZSBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXENvbnRpbnVlU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ29udGludWVTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiY29udGludWUiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ29udGludWVTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpICYmCiAgICAgICAgICAgICAgICAoJGxhYmVsID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRsYWJlbGxlZElkZW50aWZpZXIpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRMYWJlbCgkbGFiZWwpOwogICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGJyZWFrIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQnJlYWtTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VCcmVha1N0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJicmVhayIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJCcmVha1N0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKCkgJiYKICAgICAgICAgICAgICAgICgkbGFiZWwgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGxhYmVsbGVkSWRlbnRpZmllcikpKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGFiZWwoJGxhYmVsKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSByZXR1cm4gc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxSZXR1cm5TdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VSZXR1cm5TdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgicmV0dXJuIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlJldHVyblN0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKCkpIHsKICAgICAgICAgICAgICAgICRhcmd1bWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCRhcmd1bWVudCkgewogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRBcmd1bWVudCgkYXJndW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgbGFiZWxsZWQgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxMYWJlbGVkU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGFiZWxsZWRTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkbGFiZWwgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGxhYmVsbGVkSWRlbnRpZmllciwgIjoiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjoiKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkpIHx8CiAgICAgICAgICAgICAgICAoJGJvZHkgPSAkdGhpcy0+cGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRGVjbGFyYXRpb24oCiAgICAgICAgICAgICAgICAgICAgZmFsc2UsIGZhbHNlCiAgICAgICAgICAgICAgICApKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy9MYWJlbGxlZCBmdW5jdGlvbnMgYXJlIG5vdCBhbGxvd2VkIGluIHN0cmljdCBtb2RlIAogICAgICAgICAgICAgICAgaWYgKCRib2R5IGluc3RhbmNlb2YgTm9kZVxGdW5jdGlvbkRlY2xhcmF0aW9uICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIkxhYmVsbGVkIGZ1bmN0aW9ucyBhcmUgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGUiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJMYWJlbGVkU3RhdGVtZW50IiwgJGxhYmVsKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRMYWJlbCgkbGFiZWwpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHRocm93IHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVGhyb3dTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VUaHJvd1N0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ0aHJvdyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKCkgJiYKICAgICAgICAgICAgICAgICgkYXJndW1lbnQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVGhyb3dTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB3aXRoIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcV2l0aFN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVdpdGhTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgid2l0aCIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCRvYmplY3QgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiV2l0aFN0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRvYmplY3QpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgc3dpdGNoIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3dpdGNoU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU3dpdGNoU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInN3aXRjaCIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCRkaXNjcmltaW5hbnQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICgkY2FzZXMgPSAkdGhpcy0+cGFyc2VDYXNlQmxvY2soKSkgIT09IG51bGwKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiU3dpdGNoU3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXREaXNjcmltaW5hbnQoJGRpc2NyaW1pbmFudCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q2FzZXMoJGNhc2VzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgY29udGVudCBvZiBhIHN3aXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN3aXRjaENhc2VbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNhc2VCbG9jaygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRwYXJzZWRDYXNlc0FsbCA9IGFycmF5KAogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlQ2FzZUNsYXVzZXMoKSwKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZURlZmF1bHRDbGF1c2UoKSwKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUNhc2VDbGF1c2VzKCkKICAgICAgICAgICAgKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAkY2FzZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhcnNlZENhc2VzQWxsIGFzICRwYXJzZWRDYXNlcykgewogICAgICAgICAgICAgICAgICAgIGlmICgkcGFyc2VkQ2FzZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCRwYXJzZWRDYXNlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYXNlcyA9IGFycmF5X21lcmdlKCRjYXNlcywgJHBhcnNlZENhc2VzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYXNlc1tdID0gJHBhcnNlZENhc2VzOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRjYXNlczsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5wYXJzZURlZmF1bHRDbGF1c2UoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICJNdWx0aXBsZSBkZWZhdWx0IGNsYXVzZSBpbiBzd2l0Y2ggc3RhdGVtZW50IgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBjYXNlcyBpbiBhIHN3aXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN3aXRjaENhc2VbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNhc2VDbGF1c2VzKCkKICAgIHsKICAgICAgICAkY2FzZXMgPSBhcnJheSgpOwogICAgICAgIHdoaWxlICgkY2FzZSA9ICR0aGlzLT5wYXJzZUNhc2VDbGF1c2UoKSkgewogICAgICAgICAgICAkY2FzZXNbXSA9ICRjYXNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY291bnQoJGNhc2VzKSA/ICRjYXNlcyA6IG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgY2FzZSBpbiBhIHN3aXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN3aXRjaENhc2V8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDYXNlQ2xhdXNlKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImNhc2UiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkdGVzdCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjoiKQogICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTd2l0Y2hDYXNlIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKCiAgICAgICAgICAgICAgICBpZiAoJGNvbnNlcXVlbnQgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnRMaXN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGRlZmF1bHQgY2FzZSBpbiBhIHN3aXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN3aXRjaENhc2V8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VEZWZhdWx0Q2xhdXNlKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImRlZmF1bHQiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI6IikpIHsKCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTd2l0Y2hDYXNlIiwgJHRva2VuKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJGNvbnNlcXVlbnQgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnRMaXN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGV4cHJlc3Npb24gc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxFeHByZXNzaW9uU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRXhwcmVzc2lvblN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgJGxvb2thaGVhZFRva2VucyA9IGFycmF5KCJ7IiwgImZ1bmN0aW9uIiwgImNsYXNzIiwgYXJyYXkoImxldCIsICJbIikpOwogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQpIHsKICAgICAgICAgICAgYXJyYXlfc3BsaWNlKAogICAgICAgICAgICAgICAgJGxvb2thaGVhZFRva2VucywgMywgMCwKICAgICAgICAgICAgICAgIGFycmF5KGFycmF5KCJhc3luYyIsIHRydWUpKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5pc0JlZm9yZSgkbG9va2FoZWFkVG9rZW5zLCB0cnVlKSAmJgogICAgICAgICAgICAkZXhwcmVzc2lvbiA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgKQogICAgICAgICkgewogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkV4cHJlc3Npb25TdGF0ZW1lbnQiLCAkZXhwcmVzc2lvbik7CiAgICAgICAgICAgICRub2RlLT5zZXRFeHByZXNzaW9uKCRleHByZXNzaW9uKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBkby13aGlsZSBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXERvV2hpbGVTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VEb1doaWxlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImRvIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgoJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ3aGlsZSIpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpICYmCiAgICAgICAgICAgICAgICAoJHRlc3QgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJEb1doaWxlU3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpOwogICAgICAgICAgICAgICAgcmV0dXJuICRub2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgd2hpbGUgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxXaGlsZVN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVdoaWxlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIndoaWxlIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpICYmCiAgICAgICAgICAgICAgICAoJHRlc3QgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJXaGlsZVN0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VGVzdCgkdGVzdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBmb3IodmFyIC4uLikgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBUb2tlbiAkZm9yVG9rZW4gVG9rZW4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgImZvciIga2V5d29yZAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvclZhclN0YXRlbWVudCgkZm9yVG9rZW4pCiAgICB7CiAgICAgICAgaWYgKCEoJHZhclRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInZhciIpKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwoKICAgICAgICBpZiAoKCRkZWNsID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IGZhbHNlKSwgInBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QiCiAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICgkdmFyRW5kUG9zaXRpb24gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKSkgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKQogICAgICAgICkgewoKICAgICAgICAgICAgJGluaXQgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICJWYXJpYWJsZURlY2xhcmF0aW9uIiwgJHZhclRva2VuCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRpbml0LT5zZXRLaW5kKCRpbml0OjpLSU5EX1ZBUik7CiAgICAgICAgICAgICRpbml0LT5zZXREZWNsYXJhdGlvbnMoJGRlY2wpOwogICAgICAgICAgICAkaW5pdCA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJGluaXQsICR2YXJFbmRQb3NpdGlvbik7CgogICAgICAgICAgICAkdGVzdCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpKSB7CgogICAgICAgICAgICAgICAgJHVwZGF0ZSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvclN0YXRlbWVudCIsICRmb3JUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEluaXQoJGluaXQpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VXBkYXRlKCR1cGRhdGUpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CgogICAgICAgICAgICBpZiAoJGRlY2wgPSAkdGhpcy0+cGFyc2VGb3JCaW5kaW5nKCkpIHsKCiAgICAgICAgICAgICAgICAkaW5pdCA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5mb3JJbkluaXRpYWxpemVyICYmCiAgICAgICAgICAgICAgICAgICAgJGRlY2wtPmdldElkKCktPmdldFR5cGUoKSA9PT0gIklkZW50aWZpZXIiKSB7CiAgICAgICAgICAgICAgICAgICAgJGluaXQgPSAkdGhpcy0+cGFyc2VJbml0aWFsaXplcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkaW5pdCkgewogICAgICAgICAgICAgICAgICAgICRkZWNsLT5zZXRJbml0KCRpbml0KTsKICAgICAgICAgICAgICAgICAgICAkZGVjbC0+bG9jYXRpb24tPmVuZCA9ICRpbml0LT5sb2NhdGlvbi0+ZW5kOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRsZWZ0ID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlZhcmlhYmxlRGVjbGFyYXRpb24iLCAkdmFyVG9rZW4pOwogICAgICAgICAgICAgICAgJGxlZnQtPnNldEtpbmQoJGxlZnQ6OktJTkRfVkFSKTsKICAgICAgICAgICAgICAgICRsZWZ0LT5zZXREZWNsYXJhdGlvbnMoYXJyYXkoJGRlY2wpKTsKICAgICAgICAgICAgICAgICRsZWZ0ID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbGVmdCk7CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbiIpKSB7CgogICAgICAgICAgICAgICAgICAgIGlmICgkaW5pdCAmJiAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGb3ItaW4gdmFyaWFibGUgaW5pdGlhbGl6ZXIgbm90IGFsbG93ZWQgaW4gIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RyaWN0IG1vZGUiCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoKCRyaWdodCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudCgpCiAgICAgICAgICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZvckluU3RhdGVtZW50IiwgJGZvclRva2VuCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRsZWZ0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFJpZ2h0KCRyaWdodCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICghJGluaXQgJiYgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIm9mIikpIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCgkcmlnaHQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm9yT2ZTdGF0ZW1lbnQiLCAkZm9yVG9rZW4KICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldExlZnQoJGxlZnQpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBmb3IobGV0IC4uLikgb3IgZm9yKGNvbnN0IC4uLikgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBUb2tlbiAkZm9yVG9rZW4gVG9rZW4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgImZvciIga2V5d29yZAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvckxldENvbnN0U3RhdGVtZW50KCRmb3JUb2tlbikKICAgIHsKICAgICAgICAkYWZ0ZXJCcmFja2V0U3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICBpZiAoISgkaW5pdCA9ICR0aGlzLT5wYXJzZUZvckRlY2xhcmF0aW9uKCkpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbiIpKSB7CiAgICAgICAgICAgIGlmICgoJHJpZ2h0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudCgpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJGb3JJblN0YXRlbWVudCIsICRmb3JUb2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkaW5pdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgib2YiKSkgewogICAgICAgICAgICBpZiAoKCRyaWdodCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvck9mU3RhdGVtZW50IiwgJGZvclRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRpbml0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRSaWdodCgkcmlnaHQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkYWZ0ZXJCcmFja2V0U3RhdGUpOwogICAgICAgICAgICBpZiAoJGluaXQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IGZhbHNlKSwgInBhcnNlTGV4aWNhbERlY2xhcmF0aW9uIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJHRlc3QgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICR1cGRhdGUgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvclN0YXRlbWVudCIsICRmb3JUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRJbml0KCRpbml0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFRlc3QoJHRlc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VXBkYXRlKCR1cGRhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgZm9yIHN0YXRlbWVudCB0aGF0IGRvZXMgbm90IHN0YXJ0IHdpdGggdmFyLCBsZXQgb3IgY29uc3QKICAgICAqIAogICAgICogQHBhcmFtIFRva2VuICRmb3JUb2tlbiBUb2tlbiB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSAiZm9yIiBrZXl3b3JkCiAgICAgKiBAcGFyYW0gYm9vbCAgJGhhc0F3YWl0IFRydWUgaWYgImZvciIgaXMgZm9sbG93ZWQgYnkgImF3YWl0IgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvck5vdFZhckxldENvbnN0U3RhdGVtZW50KCRmb3JUb2tlbiwgJGhhc0F3YWl0KQogICAgewogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgICRub3RCZWZvcmVTQiA9ICEkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoImxldCIsICJbIikpLCB0cnVlKTsKICAgICAgICAKICAgICAgICBpZiAoJG5vdEJlZm9yZVNCICYmCiAgICAgICAgICAgICgoJGluaXQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gZmFsc2UpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICApKSB8fCB0cnVlKSAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpCiAgICAgICAgKSB7CiAgICAgICAgCiAgICAgICAgICAgICR0ZXN0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICApOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI7IikpIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICR1cGRhdGUgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudCgpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJGb3JTdGF0ZW1lbnQiLCAkZm9yVG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRJbml0KCRpbml0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VGVzdCgkdGVzdCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFVwZGF0ZSgkdXBkYXRlKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgICAgICAkYmVmb3JlTGV0QXN5bmNPZiA9ICR0aGlzLT5zY2FubmVyLT5pc0JlZm9yZShhcnJheSgibGV0IiwgYXJyYXkoImFzeW5jIiwgIm9mIikpLCB0cnVlKTsKICAgICAgICAgICAgJGxlZnQgPSAkdGhpcy0+cGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uKCk7CgogICAgICAgICAgICBpZiAoJGxlZnQgJiYgJGxlZnQtPmdldFR5cGUoKSA9PT0gIkNoYWluRXhwcmVzc2lvbiIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAiT3B0aW9uYWwgY2hhaW4gY2FuJ3QgYXBwZWFyIGluIGxlZnQtaGFuZCBzaWRlIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxlZnQgPSAkdGhpcy0+ZXhwcmVzc2lvblRvUGF0dGVybigkbGVmdCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJG5vdEJlZm9yZVNCICYmICRsZWZ0ICYmICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbiIpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICgoJHJpZ2h0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRm9ySW5TdGF0ZW1lbnQiLCAkZm9yVG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRsZWZ0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoKCRoYXNBd2FpdCB8fCAhJGJlZm9yZUxldEFzeW5jT2YpICYmCiAgICAgICAgICAgICAgICAkbGVmdCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgib2YiKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCgkcmlnaHQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRm9yT2ZTdGF0ZW1lbnQiLCAkZm9yVG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRsZWZ0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBkby13aGlsZSwgd2hpbGUsIGZvciwgZm9yLWluIGFuZCBmb3Itb2Ygc3RhdGVtZW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUl0ZXJhdGlvblN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCRub2RlID0gJHRoaXMtPnBhcnNlV2hpbGVTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgfSBlbHNlaWYgKCRub2RlID0gJHRoaXMtPnBhcnNlRG9XaGlsZVN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkbm9kZTsKICAgICAgICB9IGVsc2VpZiAoJHN0YXJ0Rm9yVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZm9yIikpIHsKCiAgICAgICAgICAgICRmb3JBd2FpdCA9IGZhbHNlOwogICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0l0ZXJhdGlvbkdlbmVyYXRvcnMgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5jb250ZXh0LT5hbGxvd0F3YWl0ICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiYXdhaXQiKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRmb3JBd2FpdCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpICYmICgKICAgICAgICAgICAgICAgICgkbm9kZSA9ICR0aGlzLT5wYXJzZUZvclZhclN0YXRlbWVudCgkc3RhcnRGb3JUb2tlbikpIHx8CiAgICAgICAgICAgICAgICAoJG5vZGUgPSAkdGhpcy0+cGFyc2VGb3JMZXRDb25zdFN0YXRlbWVudCgkc3RhcnRGb3JUb2tlbikpIHx8CiAgICAgICAgICAgICAgICAoJG5vZGUgPSAkdGhpcy0+cGFyc2VGb3JOb3RWYXJMZXRDb25zdFN0YXRlbWVudCgkc3RhcnRGb3JUb2tlbiwgJGZvckF3YWl0KSkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgaWYgKCRmb3JBd2FpdCkgewogICAgICAgICAgICAgICAgICAgIGlmICghJG5vZGUgaW5zdGFuY2VvZiBOb2RlXEZvck9mU3RhdGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3luYyBpdGVyYXRpb24gaXMgYWxsb3dlZCBvbmx5IHdpdGggZm9yLW9mIHN0YXRlbWVudHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHN0YXJ0Rm9yVG9rZW4tPmxvY2F0aW9uLT5zdGFydAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXdhaXQodHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYW4gYXN5bmMgZnVuY3Rpb24gY2FuIHN0YXJ0IGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uIFJldHVybnMKICAgICAqIHRoZSBhc3luYyB0b2tlbiBvciBudWxsIGlmIG5vdCBmb3VuZAogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjaGVja0ZuIElmIGZhbHNlIGl0IHdvbid0IGNoZWNrIGlmIHRoZSBhc3luYyBrZXl3b3JkIGlzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBmb2xsb3dlZCBieSAiZnVuY3Rpb24iCiAgICAgKgogICAgICogQHJldHVybiBUb2tlbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tBc3luY0Z1bmN0aW9uU3RhcnQoJGNoZWNrRm4gPSB0cnVlKQogICAgewogICAgICAgIHJldHVybiAoJGFzeW5jVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKSkgJiYKICAgICAgICAkYXN5bmNUb2tlbi0+dmFsdWUgPT09ICJhc3luYyIgJiYKICAgICAgICAoCiAgICAgICAgICAgICEkY2hlY2tGbiB8fAogICAgICAgICAgICAoKCRuZXh0VG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0TmV4dFRva2VuKCkpICYmCiAgICAgICAgICAgICAgICAkbmV4dFRva2VuLT52YWx1ZSA9PT0gImZ1bmN0aW9uIikKICAgICAgICApICYmCiAgICAgICAgJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKHRydWUpID8KICAgICAgICAgICAgJGFzeW5jVG9rZW4gOgogICAgICAgICAgICBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBmdW5jdGlvbiBvciBnZW5lcmF0b3IgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGRlZmF1bHQgICAgICAgIERlZmF1bHQgbW9kZQogICAgICogQHBhcmFtIGJvb2wgJGFsbG93R2VuZXJhdG9yIFRydWUgdG8gYWxsb3cgcGFyc2luZyBvZiBnZW5lcmF0b3JzCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxGdW5jdGlvbkRlY2xhcmF0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25PckdlbmVyYXRvckRlY2xhcmF0aW9uKAogICAgICAgICRkZWZhdWx0ID0gZmFsc2UsICRhbGxvd0dlbmVyYXRvciA9IHRydWUKICAgICkgewogICAgICAgICRhc3luYyA9IG51bGw7CiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+YXN5bmNBd2FpdCAmJgogICAgICAgICAgICAoJGFzeW5jID0gJHRoaXMtPmNoZWNrQXN5bmNGdW5jdGlvblN0YXJ0KCkpKSB7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jSXRlcmF0aW9uR2VuZXJhdG9ycykgewogICAgICAgICAgICAgICAgJGFsbG93R2VuZXJhdG9yID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJmdW5jdGlvbiIpKSB7CgogICAgICAgICAgICAkZ2VuZXJhdG9yID0gJGFsbG93R2VuZXJhdG9yICYmICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIqIik7CiAgICAgICAgICAgICRpZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpOwoKICAgICAgICAgICAgaWYgKCRnZW5lcmF0b3IgfHwgJGFzeW5jKSB7CiAgICAgICAgICAgICAgICAkZmxhZ3MgPSBhcnJheShudWxsKTsKICAgICAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgJGZsYWdzWyJhbGxvd1lpZWxkIl0gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRhc3luYykgewogICAgICAgICAgICAgICAgICAgICRmbGFnc1siYWxsb3dBd2FpdCJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRmbGFncyA9IG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgoJGRlZmF1bHQgfHwgJGlkKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCRwYXJhbXMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgJGZsYWdzLAogICAgICAgICAgICAgICAgICAgICJwYXJzZUZvcm1hbFBhcmFtZXRlckxpc3QiCiAgICAgICAgICAgICAgICApKSAhPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgKCR0b2tlbkJvZHlTdGFydCA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpICYmCiAgICAgICAgICAgICAgICAoKCRib2R5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgICAgICAkZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXJzZUZ1bmN0aW9uQm9keSIKICAgICAgICAgICAgICAgICAgICApKSB8fCB0cnVlKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKQogICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICAkYm9keS0+bG9jYXRpb24tPnN0YXJ0ID0gJHRva2VuQm9keVN0YXJ0LT5sb2NhdGlvbi0+c3RhcnQ7CiAgICAgICAgICAgICAgICAkYm9keS0+bG9jYXRpb24tPmVuZCA9ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAiRnVuY3Rpb25EZWNsYXJhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgJGFzeW5jID86ICR0b2tlbgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkaWQpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SWQoJGlkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRub2RlLT5zZXRQYXJhbXMoJHBhcmFtcyk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0R2VuZXJhdG9yKCRnZW5lcmF0b3IpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFzeW5jKChib29sKSAkYXN5bmMpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGZ1bmN0aW9uIG9yIGdlbmVyYXRvciBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxGdW5jdGlvbkV4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgJGFsbG93R2VuZXJhdG9yID0gdHJ1ZTsKICAgICAgICAkYXN5bmMgPSBmYWxzZTsKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ICYmCiAgICAgICAgICAgICgkYXN5bmMgPSAkdGhpcy0+Y2hlY2tBc3luY0Z1bmN0aW9uU3RhcnQoKSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+YXN5bmNJdGVyYXRpb25HZW5lcmF0b3JzKSB7CiAgICAgICAgICAgICAgICAkYWxsb3dHZW5lcmF0b3IgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImZ1bmN0aW9uIikpIHsKCiAgICAgICAgICAgICRnZW5lcmF0b3IgPSAkYWxsb3dHZW5lcmF0b3IgJiYgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIioiKTsKCiAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yIHx8ICRhc3luYykgewogICAgICAgICAgICAgICAgJGZsYWdzID0gYXJyYXkobnVsbCk7CiAgICAgICAgICAgICAgICBpZiAoJGdlbmVyYXRvcikgewogICAgICAgICAgICAgICAgICAgICRmbGFnc1siYWxsb3dZaWVsZCJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkYXN5bmMpIHsKICAgICAgICAgICAgICAgICAgICAkZmxhZ3NbImFsbG93QXdhaXQiXSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZmxhZ3MgPSBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaWQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAkZmxhZ3MsCiAgICAgICAgICAgICAgICAicGFyc2VJZGVudGlmaWVyIiwKICAgICAgICAgICAgICAgIGFycmF5KHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKQogICAgICAgICAgICApOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikgJiYKICAgICAgICAgICAgICAgICgkcGFyYW1zID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgICRmbGFncywKICAgICAgICAgICAgICAgICAgICAicGFyc2VGb3JtYWxQYXJhbWV0ZXJMaXN0IgogICAgICAgICAgICAgICAgKSkgIT09IG51bGwgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICgkdG9rZW5Cb2R5U3RhcnQgPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgieyIpKSAmJgogICAgICAgICAgICAgICAgKCgkYm9keSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgJGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAicGFyc2VGdW5jdGlvbkJvZHkiCiAgICAgICAgICAgICAgICAgICAgKSkgfHwgdHJ1ZSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ9IikKICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgJGJvZHktPmxvY2F0aW9uLT5zdGFydCA9ICR0b2tlbkJvZHlTdGFydC0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgICAgICAgICAgJGJvZHktPmxvY2F0aW9uLT5lbmQgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICAgICAgICAgIkZ1bmN0aW9uRXhwcmVzc2lvbiIsCiAgICAgICAgICAgICAgICAgICAgJGFzeW5jID86ICR0b2tlbgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRJZCgkaWQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFBhcmFtcygkcGFyYW1zKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRHZW5lcmF0b3IoJGdlbmVyYXRvcik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXN5bmMoKGJvb2wpICRhc3luYyk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgeWllbGQgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxZaWVsZEV4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VZaWVsZEV4cHJlc3Npb24oKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgieWllbGQiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiWWllbGRFeHByZXNzaW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRkZWxlZ2F0ZSA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIqIik7CiAgICAgICAgICAgICAgICAkYXJndW1lbnQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93WWllbGQiID0+IHRydWUpLCAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldERlbGVnYXRlKCRkZWxlZ2F0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcGFyYW1ldGVyIGxpc3QKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGVbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvcm1hbFBhcmFtZXRlckxpc3QoKQogICAgewogICAgICAgICRoYXNDb21tYSA9IGZhbHNlOwogICAgICAgICRsaXN0ID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoCiAgICAgICAgICAgICgkcGFyYW0gPSAkdGhpcy0+cGFyc2VCaW5kaW5nUmVzdEVsZW1lbnQoKSkgfHwKICAgICAgICAgICAgJHBhcmFtID0gJHRoaXMtPnBhcnNlQmluZGluZ0VsZW1lbnQoKQogICAgICAgICkgewogICAgICAgICAgICAkaGFzQ29tbWEgPSBmYWxzZTsKICAgICAgICAgICAgJGxpc3RbXSA9ICRwYXJhbTsKICAgICAgICAgICAgaWYgKCRwYXJhbS0+Z2V0VHlwZSgpID09PSAiUmVzdEVsZW1lbnQiKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgICAgICRoYXNDb21tYSA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoJGhhc0NvbW1hICYmCiAgICAgICAgICAgICEkdGhpcy0+ZmVhdHVyZXMtPnRyYWlsaW5nQ29tbWFGdW5jdGlvbkNhbGxEZWNsYXJhdGlvbikgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRsaXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGZ1bmN0aW9uIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEJsb2NrU3RhdGVtZW50W118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGdW5jdGlvbkJvZHkoKQogICAgewogICAgICAgICRib2R5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICBhcnJheSgiYWxsb3dSZXR1cm4iID0+IHRydWUpLAogICAgICAgICAgICAicGFyc2VTdGF0ZW1lbnRMaXN0IiwKICAgICAgICAgICAgYXJyYXkodHJ1ZSkKICAgICAgICApOwogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICJCbG9ja1N0YXRlbWVudCIsICRib2R5ID86ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpCiAgICAgICAgKTsKICAgICAgICBpZiAoJGJvZHkpIHsKICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgY2xhc3MgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGRlZmF1bHQgRGVmYXVsdCBtb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxDbGFzc0RlY2xhcmF0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NEZWNsYXJhdGlvbigkZGVmYXVsdCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiY2xhc3MiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgLy9DbGFzcyBkZWNsYXJhdGlvbnMgYXJlIHN0cmljdCBtb2RlIGJ5IGRlZmF1bHQKICAgICAgICAgICAgJHByZXZTdHJpY3QgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpOwogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RyaWN0TW9kZSh0cnVlKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRpZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpOwogICAgICAgICAgICBpZiAoKCRkZWZhdWx0IHx8ICRpZCkgJiYKICAgICAgICAgICAgICAgICR0YWlsID0gJHRoaXMtPnBhcnNlQ2xhc3NUYWlsKCkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkNsYXNzRGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgaWYgKCRpZCkgewogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRJZCgkaWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0YWlsWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFN1cGVyQ2xhc3MoJHRhaWxbMF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJHRhaWxbMV0pOwogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0cmljdE1vZGUoJHByZXZTdHJpY3QpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgY2xhc3MgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQ2xhc3NFeHByZXNzaW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImNsYXNzIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ2xhc3MgZXhwcmVzc2lvbnMgYXJlIHN0cmljdCBtb2RlIGJ5IGRlZmF1bHQKICAgICAgICAgICAgJHByZXZTdHJpY3QgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpOwogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RyaWN0TW9kZSh0cnVlKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRpZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpOwogICAgICAgICAgICAkdGFpbCA9ICR0aGlzLT5wYXJzZUNsYXNzVGFpbCgpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJDbGFzc0V4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICBpZiAoJGlkKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SWQoJGlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHRhaWxbMF0pIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRTdXBlckNsYXNzKCR0YWlsWzBdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkdGFpbFsxXSk7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdHJpY3RNb2RlKCRwcmV2U3RyaWN0KTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIGNvZGUgdGhhdCBjb21lcyBhZnRlciB0aGUgY2xhc3Mga2V5d29yZCBhbmQgY2xhc3MgbmFtZS4gVGhlCiAgICAgKiByZXR1cm4gdmFsdWUgaXMgYW4gYXJyYXkgd2hlcmUgdGhlIGZpcnN0IGl0ZW0gaXMgdGhlIGV4dGVuZGVkIGNsYXNzLCBpZgogICAgICogYW55LCBhbmQgdGhlIHNlY29uZCB2YWx1ZSBpcyB0aGUgY2xhc3MgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NUYWlsKCkKICAgIHsKICAgICAgICAkaGVyaXRhZ2UgPSAkdGhpcy0+cGFyc2VDbGFzc0hlcml0YWdlKCk7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlQ2xhc3NCb2R5KCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAkYm9keS0+bG9jYXRpb24tPnN0YXJ0ID0gJHRva2VuLT5sb2NhdGlvbi0+c3RhcnQ7CiAgICAgICAgICAgICAgICAkYm9keS0+bG9jYXRpb24tPmVuZCA9ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpOwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRoZXJpdGFnZSwgJGJvZHkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgY2xhc3MgZXh0ZW5kcyBwYXJ0CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NIZXJpdGFnZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJleHRlbmRzIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkc3VwZXJDbGFzcyA9ICR0aGlzLT5wYXJzZUxlZnRIYW5kU2lkZUV4cHJlc3Npb24oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRzdXBlckNsYXNzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBjbGFzcyBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxDbGFzc0JvZHl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDbGFzc0JvZHkoKQogICAgewogICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlQ2xhc3NFbGVtZW50TGlzdCgpOwogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICJDbGFzc0JvZHkiLCAkYm9keSA/OiAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKQogICAgICAgICk7CiAgICAgICAgaWYgKCRib2R5KSB7CiAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBjbGFzcyBlbGVtZW50cyBsaXN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxNZXRob2REZWZpbml0aW9uW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDbGFzc0VsZW1lbnRMaXN0KCkKICAgIHsKICAgICAgICAkaXRlbXMgPSBhcnJheSgpOwogICAgICAgIHdoaWxlICgkaXRlbSA9ICR0aGlzLT5wYXJzZUNsYXNzRWxlbWVudCgpKSB7CiAgICAgICAgICAgIGlmICgkaXRlbSAhPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgJGl0ZW1zW10gPSAkaXRlbTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY291bnQoJGl0ZW1zKSA/ICRpdGVtcyA6IG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgY2xhc3MgZWxlbWVudHMKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE1ldGhvZERlZmluaXRpb258Tm9kZVxQcm9wZXJ0eURlZmluaXRpb258Tm9kZVxTdGF0aWNCbG9ja3xib29sfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NFbGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+Y2xhc3NTdGF0aWNCbG9jayAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoInN0YXRpYyIsICJ7IikpLCB0cnVlKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnBhcnNlQ2xhc3NTdGF0aWNCbG9jaygpOwogICAgICAgIH0KICAgICAgICAkc3RhdGljVG9rZW4gPSBudWxsOwogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgIC8vVGhpcyBjb2RlIGhhbmRsZXMgdGhlIGNhc2Ugd2hlcmUgInN0YXRpYyIgaXMgdGhlIG1ldGhvZCBuYW1lCiAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoInN0YXRpYyIsICIoIikpLCB0cnVlKSkgewogICAgICAgICAgICAkc3RhdGljVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgic3RhdGljIik7CiAgICAgICAgfQogICAgICAgIGlmICgkZGVmID0gJHRoaXMtPnBhcnNlTWV0aG9kRGVmaW5pdGlvbigpKSB7CiAgICAgICAgICAgIGlmICgkc3RhdGljVG9rZW4pIHsKICAgICAgICAgICAgICAgICRkZWYtPnNldFN0YXRpYyh0cnVlKTsKICAgICAgICAgICAgICAgICRkZWYtPmxvY2F0aW9uLT5zdGFydCA9ICRzdGF0aWNUb2tlbi0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkZGVmOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmNsYXNzRmllbGRzKSB7CiAgICAgICAgICAgICAgICBpZiAoJGZpZWxkID0gJHRoaXMtPnBhcnNlRmllbGREZWZpbml0aW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHN0YXRpY1Rva2VuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmaWVsZC0+c2V0U3RhdGljKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAkZmllbGQtPmxvY2F0aW9uLT5zdGFydCA9ICRzdGF0aWNUb2tlbi0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkc3RhdGljVG9rZW4pIHsKICAgICAgICAgICAgICAgICAgICAvL0hhbmRsZSB0aGUgY2FzZSB3aGVuICJzdGF0aWMiIGlzIHRoZSBmaWVsZCBuYW1lCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgJGZpZWxkID0gJHRoaXMtPnBhcnNlRmllbGREZWZpbml0aW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gJGZpZWxkOwogICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXRpY1Rva2VuKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsZXQgb3IgY29uc3QgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFZhcmlhYmxlRGVjbGFyYXRpb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VMZXhpY2FsRGVjbGFyYXRpb24oKQogICAgewogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZU9uZU9mKGFycmF5KCJsZXQiLCAiY29uc3QiKSkpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRkZWNsYXJhdGlvbnMgPSAkdGhpcy0+Y2hhclNlcGFyYXRlZExpc3RPZigKICAgICAgICAgICAgICAgICJwYXJzZVZhcmlhYmxlRGVjbGFyYXRpb24iCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJGRlY2xhcmF0aW9ucykgewogICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJWYXJpYWJsZURlY2xhcmF0aW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRLaW5kKCR0b2tlbi0+dmFsdWUpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9ucygkZGVjbGFyYXRpb25zKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gImxldCIgY2FuIGJlIHVzZWQgYXMgdmFyaWFibGUgbmFtZSBpbiBub24tc3RyaWN0IG1vZGUKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5nZXRTdHJpY3RNb2RlKCkgfHwgJHRva2VuLT52YWx1ZSAhPT0gImxldCIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgdmFyIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxWYXJpYWJsZURlY2xhcmF0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlVmFyaWFibGVTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgidmFyIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRkZWNsYXJhdGlvbnMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZVZhcmlhYmxlRGVjbGFyYXRpb25MaXN0IgogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoJGRlY2xhcmF0aW9ucykgewogICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJWYXJpYWJsZURlY2xhcmF0aW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRLaW5kKCRub2RlOjpLSU5EX1ZBUik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RGVjbGFyYXRpb25zKCRkZWNsYXJhdGlvbnMpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIHZhcmlhYmxlIGRlY2xhcmF0aW9ucwogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVmFyaWFibGVEZWNsYXJhdG9yW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uTGlzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jaGFyU2VwYXJhdGVkTGlzdE9mKAogICAgICAgICAgICAicGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uIgogICAgICAgICk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgdmFyaWFibGUgZGVjbGFyYXRpb25zCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxWYXJpYWJsZURlY2xhcmF0b3J8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICBpZiAoJGlkID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRiaW5kaW5nSWRlbnRpZmllcikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlZhcmlhYmxlRGVjbGFyYXRvciIsICRpZCk7CiAgICAgICAgICAgICRub2RlLT5zZXRJZCgkaWQpOwogICAgICAgICAgICBpZiAoJGluaXQgPSAkdGhpcy0+cGFyc2VJbml0aWFsaXplcigpKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SW5pdCgkaW5pdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAKICAgICAgICB9IGVsc2VpZiAoJGlkID0gJHRoaXMtPnBhcnNlQmluZGluZ1BhdHRlcm4oKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRpbml0ID0gJHRoaXMtPnBhcnNlSW5pdGlhbGl6ZXIoKSkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVmFyaWFibGVEZWNsYXJhdG9yIiwgJGlkKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRJZCgkaWQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEluaXQoJGluaXQpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsZXQgb3IgY29uc3QgZGVjbGFyYXRpb24gaW4gYSBmb3Igc3RhdGVtZW50IGRlZmluaXRpb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFZhcmlhYmxlRGVjbGFyYXRpb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGb3JEZWNsYXJhdGlvbigpCiAgICB7CiAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoYXJyYXkoImxldCIsICJjb25zdCIpKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRkZWNsYXJhdGlvbiA9ICR0aGlzLT5wYXJzZUZvckJpbmRpbmcoKSkgewoKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlZhcmlhYmxlRGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEtpbmQoJHRva2VuLT52YWx1ZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RGVjbGFyYXRpb25zKGFycmF5KCRkZWNsYXJhdGlvbikpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyAibGV0IiBjYW4gYmUgdXNlZCBhcyB2YXJpYWJsZSBuYW1lIGluIG5vbi1zdHJpY3QgbW9kZQogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKSB8fCAkdG9rZW4tPnZhbHVlICE9PSAibGV0IikgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBiaW5kaW5nIHBhdHRlcm4gb3IgYW4gaWRlbnRpZmllciB0aGF0IGNvbWUgYWZ0ZXIgYSBjb25zdCBvciBsZXQKICAgICAqIGRlY2xhcmF0aW9uIGluIGEgZm9yIHN0YXRlbWVudCBkZWZpbml0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxWYXJpYWJsZURlY2xhcmF0b3J8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGb3JCaW5kaW5nKCkKICAgIHsKICAgICAgICBpZiAoKCRpZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpKSB8fAogICAgICAgICAgICAoJGlkID0gJHRoaXMtPnBhcnNlQmluZGluZ1BhdHRlcm4oKSkKICAgICAgICApIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlZhcmlhYmxlRGVjbGFyYXRvciIsICRpZCk7CiAgICAgICAgICAgICRub2RlLT5zZXRJZCgkaWQpOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG1vZHVsZSBpdGVtCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTW9kdWxlSXRlbSgpCiAgICB7CiAgICAgICAgaWYgKCRpdGVtID0gJHRoaXMtPnBhcnNlSW1wb3J0RGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGl0ZW07CiAgICAgICAgfSBlbHNlaWYgKCRpdGVtID0gJHRoaXMtPnBhcnNlRXhwb3J0RGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGl0ZW07CiAgICAgICAgfSBlbHNlaWYgKAogICAgICAgICAgICAkaXRlbSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICJhbGxvd1lpZWxkIiA9PiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAiYWxsb3dSZXR1cm4iID0+IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICJhbGxvd0F3YWl0IiA9PiAkdGhpcy0+ZmVhdHVyZXMtPnRvcExldmVsQXdhaXQKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAicGFyc2VTdGF0ZW1lbnRMaXN0SXRlbSIKICAgICAgICAgICAgKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gJGl0ZW07CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgZnJvbSBrZXl3b3JkIGFuZCB0aGUgZm9sbG93aW5nIHN0cmluZyBpbiBpbXBvcnQgYW5kIGV4cG9ydAogICAgICogZGVjbGFyYXRpb25zCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxTdHJpbmdMaXRlcmFsfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRnJvbUNsYXVzZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJmcm9tIikpIHsKICAgICAgICAgICAgaWYgKCRzcGVjID0gJHRoaXMtPnBhcnNlU3RyaW5nTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHNwZWM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBleHBvcnQgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE1vZHVsZURlY2xhcmF0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRXhwb3J0RGVjbGFyYXRpb24oKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZXhwb3J0IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKiIpKSB7CgogICAgICAgICAgICAgICAgJGV4cG9ydGVkID0gbnVsbDsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmV4cG9ydGVkTmFtZUluRXhwb3J0QWxsICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImFzIikpIHsKICAgICAgICAgICAgICAgICAgICAkZXhwb3J0ZWQgPSAkdGhpcy0+cGFyc2VNb2R1bGVFeHBvcnROYW1lKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkZXhwb3J0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJHNvdXJjZSA9ICR0aGlzLT5wYXJzZUZyb21DbGF1c2UoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkV4cG9ydEFsbERlY2xhcmF0aW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0U291cmNlKCRzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRFeHBvcnRlZCgkZXhwb3J0ZWQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImRlZmF1bHQiKSkgewogICAgICAgICAgICAgICAgJGxvb2thaGVhZFRva2VucyA9IGFycmF5KCJmdW5jdGlvbiIsICJjbGFzcyIpOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+YXN5bmNBd2FpdCkgewogICAgICAgICAgICAgICAgICAgICRsb29rYWhlYWRUb2tlbnNbXSA9IGFycmF5KCJhc3luYyIsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCgkZGVjbGFyYXRpb24gPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0F3YWl0IiA9PiAkdGhpcy0+ZmVhdHVyZXMtPnRvcExldmVsQXdhaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAicGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRGVjbGFyYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSh0cnVlKQogICAgICAgICAgICAgICAgICAgICkpIHx8CiAgICAgICAgICAgICAgICAgICAgKCRkZWNsYXJhdGlvbiA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93QXdhaXQiID0+ICR0aGlzLT5mZWF0dXJlcy0+dG9wTGV2ZWxBd2FpdCksCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXJzZUNsYXNzRGVjbGFyYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSh0cnVlKQogICAgICAgICAgICAgICAgICAgICkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXREZWNsYXJhdGlvbigkZGVjbGFyYXRpb24pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0gZWxzZWlmICghJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKAogICAgICAgICAgICAgICAgICAgICAgICAkbG9va2FoZWFkVG9rZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQKICAgICAgICAgICAgICAgICAgICApICYmCiAgICAgICAgICAgICAgICAgICAgKCRkZWNsYXJhdGlvbiA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUsICJhbGxvd0F3YWl0IiA9PiAkdGhpcy0+ZmVhdHVyZXMtPnRvcExldmVsQXdhaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICApKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvbiIsICR0b2tlbgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9uKCRkZWNsYXJhdGlvbik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0gZWxzZWlmICgoJHNwZWNpZmllcnMgPSAkdGhpcy0+cGFyc2VFeHBvcnRDbGF1c2UoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRXhwb3J0TmFtZWREZWNsYXJhdGlvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0U3BlY2lmaWVycygkc3BlY2lmaWVycyk7CiAgICAgICAgICAgICAgICBpZiAoJHNvdXJjZSA9ICR0aGlzLT5wYXJzZUZyb21DbGF1c2UoKSkgewogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRTb3VyY2UoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKCiAgICAgICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgICAgICgkZGVjID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0F3YWl0IiA9PiAkdGhpcy0+ZmVhdHVyZXMtPnRvcExldmVsQXdhaXQpLAogICAgICAgICAgICAgICAgICAgICJwYXJzZVZhcmlhYmxlU3RhdGVtZW50IgogICAgICAgICAgICAgICAgKSkgfHwKICAgICAgICAgICAgICAgICRkZWMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93QXdhaXQiID0+ICR0aGlzLT5mZWF0dXJlcy0+dG9wTGV2ZWxBd2FpdCksCiAgICAgICAgICAgICAgICAgICAgInBhcnNlRGVjbGFyYXRpb24iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkgewoKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkV4cG9ydE5hbWVkRGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9uKCRkZWMpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGV4cG9ydCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEV4cG9ydFNwZWNpZmllcltdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRXhwb3J0Q2xhdXNlKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAoJHNwZWMgPSAkdGhpcy0+cGFyc2VFeHBvcnRTcGVjaWZpZXIoKSkgewogICAgICAgICAgICAgICAgJGxpc3RbXSA9ICRzcGVjOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gZXhwb3J0IHNwZWNpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcRXhwb3J0U3BlY2lmaWVyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRXhwb3J0U3BlY2lmaWVyKCkKICAgIHsKICAgICAgICBpZiAoJGxvY2FsID0gJHRoaXMtPnBhcnNlTW9kdWxlRXhwb3J0TmFtZSgpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJFeHBvcnRTcGVjaWZpZXIiLCAkbG9jYWwpOwogICAgICAgICAgICAkbm9kZS0+c2V0TG9jYWwoJGxvY2FsKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiYXMiKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJGV4cG9ydGVkID0gJHRoaXMtPnBhcnNlTW9kdWxlRXhwb3J0TmFtZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEV4cG9ydGVkKCRleHBvcnRlZCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRFeHBvcnRlZCgkbG9jYWwpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGV4cG9ydCBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxJZGVudGlmaWVyfE5vZGVcU3RyaW5nTGl0ZXJhbHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU1vZHVsZUV4cG9ydE5hbWUoKQogICAgewogICAgICAgIGlmICgkbmFtZSA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllck5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkbmFtZTsKICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmZlYXR1cmVzLT5hcmJpdHJhcnlNb2R1bGVOU05hbWVzICYmCiAgICAgICAgICAgICgkbmFtZSA9ICR0aGlzLT5wYXJzZVN0cmluZ0xpdGVyYWwoKSkKICAgICAgICApIHsKICAgICAgICAgICAgcmV0dXJuICRuYW1lOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gaW1wb3J0IGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxNb2R1bGVEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUltcG9ydERlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICAvL0RlbGF5IHBhcnNpbmcgb2YgZHluYW1pYyBpbXBvcnQgc28gdGhhdCBpdCBpcyBoYW5kbGVkCiAgICAgICAgLy9ieSB0aGUgcmVsYXRpdmUgbWV0aG9kCiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+ZHluYW1pY0ltcG9ydCAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoImltcG9ydCIsICIoIikpLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgLy9EZWxheSBwYXJzaW5nIG9mIGltcG9ydC5tZXRhIHNvIHRoYXQgaXQgaXMgaGFuZGxlZAogICAgICAgIC8vYnkgdGhlIHJlbGF0aXZlIG1ldGhvZAogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmltcG9ydE1ldGEgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KGFycmF5KCJpbXBvcnQiLCAiLiIpKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiaW1wb3J0IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkc291cmNlID0gJHRoaXMtPnBhcnNlU3RyaW5nTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiSW1wb3J0RGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFNvdXJjZSgkc291cmNlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9IGVsc2VpZiAoKCRzcGVjaWZpZXJzID0gJHRoaXMtPnBhcnNlSW1wb3J0Q2xhdXNlKCkpICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAkc291cmNlID0gJHRoaXMtPnBhcnNlRnJvbUNsYXVzZSgpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydERlY2xhcmF0aW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRTcGVjaWZpZXJzKCRzcGVjaWZpZXJzKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRTb3VyY2UoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBpbXBvcnQgY2xhdXNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VJbXBvcnRDbGF1c2UoKQogICAgewogICAgICAgIGlmICgkc3BlYyA9ICR0aGlzLT5wYXJzZU5hbWVTcGFjZUltcG9ydCgpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkc3BlYyk7CiAgICAgICAgfSBlbHNlaWYgKCgkc3BlY3MgPSAkdGhpcy0+cGFyc2VOYW1lZEltcG9ydHMoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuICRzcGVjczsKICAgICAgICB9IGVsc2VpZiAoJHNwZWMgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGltcG9ydGVkQmluZGluZykpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydERlZmF1bHRTcGVjaWZpZXIiLCAkc3BlYyk7CiAgICAgICAgICAgICRub2RlLT5zZXRMb2NhbCgkc3BlYyk7CiAgICAgICAgICAgICRyZXQgPSBhcnJheSgkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIiwiKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJHNwZWMgPSAkdGhpcy0+cGFyc2VOYW1lU3BhY2VJbXBvcnQoKSkgewogICAgICAgICAgICAgICAgICAgICRyZXRbXSA9ICRzcGVjOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcmV0OwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCgkc3BlY3MgPSAkdGhpcy0+cGFyc2VOYW1lZEltcG9ydHMoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfbWVyZ2UoJHJldCwgJHNwZWNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHJldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBuYW1lc3BhY2UgaW1wb3J0CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXJ8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VOYW1lU3BhY2VJbXBvcnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImFzIikgJiYKICAgICAgICAgICAgICAgICRsb2NhbCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllclJlZmVyZW5jZSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXIiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldExvY2FsKCRsb2NhbCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7ICAKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG5hbWVkIGltcG9ydHMKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEltcG9ydFNwZWNpZmllcltdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTmFtZWRJbXBvcnRzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAoJHNwZWMgPSAkdGhpcy0+cGFyc2VJbXBvcnRTcGVjaWZpZXIoKSkgewogICAgICAgICAgICAgICAgJGxpc3RbXSA9ICRzcGVjOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gaW1wb3J0IHNwZWNpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcSW1wb3J0U3BlY2lmaWVyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSW1wb3J0U3BlY2lmaWVyKCkKICAgIHsKICAgICAgICAkcmVxdWlyZWRBcyA9IGZhbHNlOwogICAgICAgICRpbXBvcnRlZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaW1wb3J0ZWRCaW5kaW5nKTsKICAgICAgICBpZiAoISRpbXBvcnRlZCkgewogICAgICAgICAgICAkaW1wb3J0ZWQgPSAkdGhpcy0+cGFyc2VNb2R1bGVFeHBvcnROYW1lKCk7CiAgICAgICAgICAgIGlmICghJGltcG9ydGVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVxdWlyZWRBcyA9IHRydWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydFNwZWNpZmllciIsICRpbXBvcnRlZCk7CiAgICAgICAgJG5vZGUtPnNldEltcG9ydGVkKCRpbXBvcnRlZCk7CiAgICAgICAgCiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJhcyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoISgkbG9jYWwgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGltcG9ydGVkQmluZGluZykpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUtPnNldExvY2FsKCRsb2NhbCk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgkcmVxdWlyZWRBcykgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbm9kZS0+c2V0TG9jYWwoJGltcG9ydGVkKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGJpbmRpbmcgcGF0dGVybgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQXJyYXlQYXR0ZXJufE5vZGVcT2JqZWN0UGF0dGVybnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUJpbmRpbmdQYXR0ZXJuKCkKICAgIHsKICAgICAgICBpZiAoJHBhdHRlcm4gPSAkdGhpcy0+cGFyc2VPYmplY3RCaW5kaW5nUGF0dGVybigpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGF0dGVybjsKICAgICAgICB9IGVsc2VpZiAoJHBhdHRlcm4gPSAkdGhpcy0+cGFyc2VBcnJheUJpbmRpbmdQYXR0ZXJuKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRwYXR0ZXJuOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gZWxpc2lvbnMgc2VxdWVuY2UuIEl0IHJldHVybnMgdGhlIG51bWJlciBvZiBlbGlzaW9ucyBvciBudWxsCiAgICAgKiBpZiBubyBlbGlzaW9uIGhhcyBiZWVuIGZvdW5kCiAgICAgKiAKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUVsaXNpb24oKQogICAgewogICAgICAgICRjb3VudCA9IDA7CiAgICAgICAgd2hpbGUgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgJGNvdW50ICsrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGNvdW50ID86IG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGFycmF5IGJpbmRpbmcgcGF0dGVybgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQXJyYXlQYXR0ZXJufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQXJyYXlCaW5kaW5nUGF0dGVybigpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJbIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRlbGVtZW50cyA9IGFycmF5KCk7CiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGVsaXNpb24gPSAkdGhpcy0+cGFyc2VFbGlzaW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICAkZWxlbWVudHMgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzLCBhcnJheV9maWxsKDAsICRlbGlzaW9uLCBudWxsKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGVsZW1lbnQgPSAkdGhpcy0+cGFyc2VCaW5kaW5nRWxlbWVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAkZWxlbWVudDsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRyZXN0ID0gJHRoaXMtPnBhcnNlQmluZGluZ1Jlc3RFbGVtZW50KCkpIHsKICAgICAgICAgICAgICAgICAgICAkZWxlbWVudHNbXSA9ICRyZXN0OwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJdIikpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFycmF5UGF0dGVybiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RWxlbWVudHMoJGVsZW1lbnRzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSByZXN0IGVsZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFJlc3RFbGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQmluZGluZ1Jlc3RFbGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4uLiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCRhcmd1bWVudCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpKSB8fAogICAgICAgICAgICAgICAgKCRhcmd1bWVudCA9ICR0aGlzLT5wYXJzZUJpbmRpbmdQYXR0ZXJuKCkpKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJSZXN0RWxlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnQoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGJpbmRpbmcgZWxlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQXNzaWdubWVudFBhdHRlcm58Tm9kZVxJZGVudGlmaWVyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQmluZGluZ0VsZW1lbnQoKQogICAgewogICAgICAgIGlmICgkZWwgPSAkdGhpcy0+cGFyc2VTaW5nbGVOYW1lQmluZGluZygpKSB7CiAgICAgICAgICAgIHJldHVybiAkZWw7CiAgICAgICAgfSBlbHNlaWYgKCRsZWZ0ID0gJHRoaXMtPnBhcnNlQmluZGluZ1BhdHRlcm4oKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJHJpZ2h0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VJbml0aWFsaXplciIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRyaWdodCkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQXNzaWdubWVudFBhdHRlcm4iLCAkbGVmdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkbGVmdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbGVmdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgc2luZ2xlIG5hbWUgYmluZGluZwogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQXNzaWdubWVudFBhdHRlcm58Tm9kZVxJZGVudGlmaWVyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU2luZ2xlTmFtZUJpbmRpbmcoKQogICAgewogICAgICAgIGlmICgkbGVmdCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICRyaWdodCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlSW5pdGlhbGl6ZXIiCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICgkcmlnaHQpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFzc2lnbm1lbnRQYXR0ZXJuIiwgJGxlZnQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldExlZnQoJGxlZnQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFJpZ2h0KCRyaWdodCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxlZnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcHJvcGVydHkgbmFtZS4gVGhlIHJldHVybmVkIHZhbHVlIGlzIGFuIGFycmF5IHdoZXJlIHRoZXJlIGZpcnN0CiAgICAgKiBlbGVtZW50IGlzIHRoZSBwcm9wZXJ0eSBuYW1lIGFuZCB0aGUgc2Vjb25kIGVsZW1lbnQgaXMgYSBib29sZWFuCiAgICAgKiBpbmRpY2F0aW5nIGlmIGl0J3MgYSBjb21wdXRlZCBwcm9wZXJ0eQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlUHJvcGVydHlOYW1lKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIlsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkbmFtZSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJdIikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJG5hbWUsIHRydWUsICR0b2tlbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0gZWxzZWlmICgkbmFtZSA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllck5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgZmFsc2UpOwogICAgICAgIH0gZWxzZWlmICgkbmFtZSA9ICR0aGlzLT5wYXJzZVN0cmluZ0xpdGVyYWwoKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJG5hbWUsIGZhbHNlKTsKICAgICAgICB9IGVsc2VpZiAoJG5hbWUgPSAkdGhpcy0+cGFyc2VOdW1lcmljTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHByb3BlcnR5IG5hbWUuIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhbiBhcnJheSB3aGVyZSB0aGVyZSBmaXJzdAogICAgICogZWxlbWVudCBpcyB0aGUgcHJvcGVydHkgbmFtZSBhbmQgdGhlIHNlY29uZCBlbGVtZW50IGlzIGEgYm9vbGVhbgogICAgICogaW5kaWNhdGluZyBpZiBpdCdzIGEgY29tcHV0ZWQgcHJvcGVydHkKICAgICAqIAogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNsYXNzRWxlbWVudE5hbWUoKQogICAgewogICAgICAgIGlmICgKICAgICAgICAgICAgJHRoaXMtPmZlYXR1cmVzLT5wcml2YXRlTWV0aG9kc0FuZEZpZWxkcyAmJgogICAgICAgICAgICAoJG5hbWUgPSAkdGhpcy0+cGFyc2VQcml2YXRlSWRlbnRpZmllcigpKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJG5hbWUsIGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXJzZVByb3BlcnR5TmFtZSgpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgZmllbGQgZGVmaW5pdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3RhdGljQmxvY2sKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NTdGF0aWNCbG9jaygpCiAgICB7CiAgICAgICAgJHN0YXRpY1Rva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInN0YXRpYyIpOwogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7Iik7CiAgICAgICAgJHN0YXRlbWVudHMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgIGFycmF5KCJhbGxvd0F3YWl0IiA9PiB0cnVlKSwgInBhcnNlU3RhdGVtZW50TGlzdCIKICAgICAgICApOwogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlN0YXRpY0Jsb2NrIiwgJHN0YXRpY1Rva2VuKTsKICAgICAgICAgICAgaWYgKCRzdGF0ZW1lbnRzKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkc3RhdGVtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGZpZWxkIGRlZmluaXRpb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFByb3BlcnR5RGVmaW5pdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZpZWxkRGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgaWYgKCRwcm9wID0gJHRoaXMtPnBhcnNlQ2xhc3NFbGVtZW50TmFtZSgpKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlSW5pdGlhbGl6ZXIiCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJQcm9wZXJ0eURlZmluaXRpb24iLCAkcHJvcCk7CiAgICAgICAgICAgICRub2RlLT5zZXRLZXkoJHByb3BbMF0pOwogICAgICAgICAgICBpZiAoJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbm9kZS0+c2V0Q29tcHV0ZWQoJHByb3BbMV0pOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG1ldGhvZCBkZWZpbml0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxNZXRob2REZWZpbml0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTWV0aG9kRGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgJGdlbmVyYXRvciA9ICRlcnJvciA9ICRhc3luYyA9IGZhbHNlOwogICAgICAgICRwb3NpdGlvbiA9IG51bGw7CiAgICAgICAgJGtpbmQgPSBOb2RlXE1ldGhvZERlZmluaXRpb246OktJTkRfTUVUSE9EOwogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZ2V0IikpIHsKICAgICAgICAgICAgJHBvc2l0aW9uID0gJHRva2VuOwogICAgICAgICAgICAka2luZCA9IE5vZGVcTWV0aG9kRGVmaW5pdGlvbjo6S0lORF9HRVQ7CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJzZXQiKSkgewogICAgICAgICAgICAkcG9zaXRpb24gPSAkdG9rZW47CiAgICAgICAgICAgICRraW5kID0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX1NFVDsKICAgICAgICB9IGVsc2VpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIioiKSkgewogICAgICAgICAgICAkcG9zaXRpb24gPSAkdG9rZW47CiAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgICRnZW5lcmF0b3IgPSB0cnVlOwogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQgJiYKICAgICAgICAgICAgICAgICAoJHRva2VuID0gJHRoaXMtPmNoZWNrQXN5bmNGdW5jdGlvblN0YXJ0KGZhbHNlKSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICAkcG9zaXRpb24gPSAkdG9rZW47CiAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgICRhc3luYyA9IHRydWU7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jSXRlcmF0aW9uR2VuZXJhdG9ycyAmJgogICAgICAgICAgICAgICAgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIqIikpKSB7CiAgICAgICAgICAgICAgICAkZ2VuZXJhdG9yID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9IYW5kbGUgdGhlIGNhc2Ugd2hlcmUgZ2V0IGFuZCBzZXQgYXJlIG1ldGhvZHMgbmFtZSBhbmQgbm90IHRoZQogICAgICAgIC8vZGVmaW5pdGlvbiBvZiBhIGdldHRlci9zZXR0ZXIKICAgICAgICBpZiAoJGtpbmQgIT09IE5vZGVcTWV0aG9kRGVmaW5pdGlvbjo6S0lORF9NRVRIT0QgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKQogICAgICAgICkgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICAgICAgJGtpbmQgPSBOb2RlXE1ldGhvZERlZmluaXRpb246OktJTkRfTUVUSE9EOwogICAgICAgICAgICAkZXJyb3IgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkcHJvcCA9ICR0aGlzLT5wYXJzZUNsYXNzRWxlbWVudE5hbWUoKSkgewoKICAgICAgICAgICAgaWYgKCEkcG9zaXRpb24pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IGlzc2V0KCRwcm9wWzJdKSA/ICRwcm9wWzJdIDogJHByb3BbMF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0b2tlbkZuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSkgewoKICAgICAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yIHx8ICRhc3luYykgewogICAgICAgICAgICAgICAgICAgICRmbGFncyA9IGFycmF5KG51bGwpOwogICAgICAgICAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFnc1siYWxsb3dZaWVsZCJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRhc3luYykgewogICAgICAgICAgICAgICAgICAgICAgICAkZmxhZ3NbImFsbG93QXdhaXQiXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZmxhZ3MgPSBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICAkcGFyYW1zID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGlmICgka2luZCA9PT0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX1NFVCkgewogICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsICJwYXJzZUJpbmRpbmdFbGVtZW50IgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRwYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhcmFtcyA9IGFycmF5KCRwYXJhbXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgka2luZCA9PT0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX01FVEhPRCkgewogICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFncywgInBhcnNlRm9ybWFsUGFyYW1ldGVyTGlzdCIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkcGFyYW1zICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgICAgICgkdG9rZW5Cb2R5U3RhcnQgPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgieyIpKSAmJgogICAgICAgICAgICAgICAgICAgICgoJGJvZHkgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFncywgInBhcnNlRnVuY3Rpb25Cb2R5IgogICAgICAgICAgICAgICAgICAgICkpIHx8IHRydWUpICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKQogICAgICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgICAgIGlmICgkcHJvcFswXSBpbnN0YW5jZW9mIE5vZGVcSWRlbnRpZmllciAmJgogICAgICAgICAgICAgICAgICAgICAgICAkcHJvcFswXS0+Z2V0TmFtZSgpID09PSAiY29uc3RydWN0b3IiCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRraW5kID0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX0NPTlNUUlVDVE9SOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGJvZHktPmxvY2F0aW9uLT5zdGFydCA9ICR0b2tlbkJvZHlTdGFydC0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgICAgICAgICAgICAgICRib2R5LT5sb2NhdGlvbi0+ZW5kID0gJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCk7CgogICAgICAgICAgICAgICAgICAgICRub2RlRm4gPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRnVuY3Rpb25FeHByZXNzaW9uIiwgJHRva2VuRm4pOwogICAgICAgICAgICAgICAgICAgICRub2RlRm4tPnNldFBhcmFtcygkcGFyYW1zKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZUZuLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZUZuLT5zZXRHZW5lcmF0b3IoJGdlbmVyYXRvcik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGVGbi0+c2V0QXN5bmMoJGFzeW5jKTsKCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWV0aG9kRGVmaW5pdGlvbiIsICRwb3NpdGlvbik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEtleSgkcHJvcFswXSk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFZhbHVlKCR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGVGbikpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRLaW5kKCRraW5kKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29tcHV0ZWQoJHByb3BbMV0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRlcnJvcikgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHBhcmFtZXRlcnMgaW4gYW4gYXJyb3cgZnVuY3Rpb24uIElmIHRoZSBwYXJhbWV0ZXJzIGFyZSB3cmFwcGVkIGluCiAgICAgKiByb3VuZCBicmFja2V0cywgdGhlIHJldHVybmVkIHZhbHVlIGlzIGFuIGFycmF5IHdoZXJlIHRoZSBmaXJzdCBlbGVtZW50CiAgICAgKiBpcyB0aGUgcGFyYW1ldGVycyBsaXN0IGFuZCB0aGUgc2Vjb25kIGVsZW1lbnQgaXMgdGhlIG9wZW4gcm91bmQgYnJhY2tldHMsCiAgICAgKiB0aGlzIGlzIG5lZWRlZCB0byBrbm93IHRoZSBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcSWRlbnRpZmllcnxhcnJheXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFycm93UGFyYW1ldGVycygpCiAgICB7CiAgICAgICAgaWYgKCRwYXJhbSA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIsICI9PiIpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFyYW07CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRwYXJhbXMgPSAkdGhpcy0+cGFyc2VGb3JtYWxQYXJhbWV0ZXJMaXN0KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHBhcmFtcyAhPT0gbnVsbCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJHBhcmFtcywgJHRva2VuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgYm9keSBvZiBhbiBhcnJvdyBmdW5jdGlvbi4gVGhlIHJldHVybmVkIHZhbHVlIGlzIGFuIGFycmF5CiAgICAgKiB3aGVyZSB0aGUgZmlyc3QgZWxlbWVudCBpcyB0aGUgZnVuY3Rpb24gYm9keSBhbmQgdGhlIHNlY29uZCBlbGVtZW50IGlzCiAgICAgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgYm9keSBpcyB3cmFwcGVkIGluIGN1cmx5IGJyYWNlcwogICAgICoKICAgICAqIEBwYXJhbSBib29sICAkYXN5bmMgIEFzeW5jIGJvZHkgbW9kZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDb25jaXNlQm9keSgkYXN5bmMgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewoKICAgICAgICAgICAgaWYgKCgkYm9keSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAkYXN5bmMgPyBhcnJheShudWxsLCAiYWxsb3dBd2FpdCIgPT4gdHJ1ZSkgOiBudWxsLAogICAgICAgICAgICAgICAgICAgICJwYXJzZUZ1bmN0aW9uQm9keSIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJGJvZHktPmxvY2F0aW9uLT5zdGFydCA9ICR0b2tlbi0+bG9jYXRpb24tPnN0YXJ0OwogICAgICAgICAgICAgICAgJGJvZHktPmxvY2F0aW9uLT5lbmQgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKTsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkYm9keSwgZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5zY2FubmVyLT5pc0JlZm9yZShhcnJheSgieyIpKSAmJgogICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICR0aGlzLT5mZWF0dXJlcy0+YXN5bmNBd2FpdCA/CiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dZaWVsZCIgPT4gZmFsc2UsICJhbGxvd0F3YWl0IiA9PiAkYXN5bmMpIDoKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd1lpZWxkIiA9PiBmYWxzZSksCiAgICAgICAgICAgICAgICAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJGJvZHksIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXJyb3cgZnVuY3Rpb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEFycm93RnVuY3Rpb25FeHByZXNzaW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQXJyb3dGdW5jdGlvbigpCiAgICB7CiAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgJGFzeW5jID0gZmFsc2U7CiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+YXN5bmNBd2FpdCAmJgogICAgICAgICAgICAoJGFzeW5jID0gJHRoaXMtPmNoZWNrQXN5bmNGdW5jdGlvblN0YXJ0KGZhbHNlKSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIH0KICAgICAgICBpZiAoKCRwYXJhbXMgPSAkdGhpcy0+cGFyc2VBcnJvd1BhcmFtZXRlcnMoKSkgIT09IG51bGwpIHsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+bm9MaW5lVGVybWluYXRvcnMoKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIj0+IikKICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgaWYgKCRib2R5ID0gJHRoaXMtPnBhcnNlQ29uY2lzZUJvZHkoKGJvb2wpICRhc3luYykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHBhcmFtcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBvcyA9ICRwYXJhbXNbMV07CiAgICAgICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSAkcGFyYW1zWzBdOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwb3MgPSAkcGFyYW1zOwogICAgICAgICAgICAgICAgICAgICAgICAkcGFyYW1zID0gYXJyYXkoJHBhcmFtcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkYXN5bmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBvcyA9ICRhc3luYzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24iLCAkcG9zKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UGFyYW1zKCRwYXJhbXMpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5WzBdKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RXhwcmVzc2lvbigkYm9keVsxXSk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEFzeW5jKChib29sKSAkYXN5bmMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gb2JqZWN0IGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE9iamVjdEV4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VPYmplY3RMaXRlcmFsKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJHByb3BlcnRpZXMgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAoJHByb3AgPSAkdGhpcy0+cGFyc2VQcm9wZXJ0eURlZmluaXRpb24oKSkgewogICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9ICRwcm9wOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk9iamVjdEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgaWYgKCRwcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnRpZXMoJHByb3BlcnRpZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcHJvcGVydHkgaW4gYW4gb2JqZWN0IGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFByb3BlcnR5fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlUHJvcGVydHlEZWZpbml0aW9uKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5yZXN0U3ByZWFkUHJvcGVydGllcyAmJgogICAgICAgICAgICAoJHByb3AgPSAkdGhpcy0+cGFyc2VTcHJlYWRFbGVtZW50KCkpKSB7CiAgICAgICAgICAgIHJldHVybiAkcHJvcDsKICAgICAgICB9CgogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgIGlmICgoJHByb3BlcnR5ID0gJHRoaXMtPnBhcnNlUHJvcGVydHlOYW1lKCkpICYmCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI6IikKICAgICAgICApIHsKICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCR2YWx1ZSkgewogICAgICAgICAgICAgICAgJHN0YXJ0UG9zID0gaXNzZXQoJHByb3BlcnR5WzJdKSA/ICRwcm9wZXJ0eVsyXSA6ICRwcm9wZXJ0eVswXTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlByb3BlcnR5IiwgJHN0YXJ0UG9zKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRLZXkoJHByb3BlcnR5WzBdKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRWYWx1ZSgkdmFsdWUpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldENvbXB1dGVkKCRwcm9wZXJ0eVsxXSk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgaWYgKCRwcm9wZXJ0eSA9ICR0aGlzLT5wYXJzZU1ldGhvZERlZmluaXRpb24oKSkgewoKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiUHJvcGVydHkiLCAkcHJvcGVydHkpOwogICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRwcm9wZXJ0eS0+Z2V0S2V5KCkpOwogICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHByb3BlcnR5LT5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgJG5vZGUtPnNldENvbXB1dGVkKCRwcm9wZXJ0eS0+Z2V0Q29tcHV0ZWQoKSk7CiAgICAgICAgICAgICRraW5kID0gJHByb3BlcnR5LT5nZXRLaW5kKCk7CiAgICAgICAgICAgIGlmICgka2luZCAhPT0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX0dFVCAmJgogICAgICAgICAgICAgICAgJGtpbmQgIT09IE5vZGVcTWV0aG9kRGVmaW5pdGlvbjo6S0lORF9TRVQKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TWV0aG9kKHRydWUpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEtpbmQoTm9kZVxQcm9wZXJ0eTo6S0lORF9JTklUKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRLaW5kKCRraW5kKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgka2V5ID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRpZGVudGlmaWVyUmVmZXJlbmNlKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiUHJvcGVydHkiLCAka2V5KTsKICAgICAgICAgICAgJG5vZGUtPnNldFNob3J0aGFuZCh0cnVlKTsKICAgICAgICAgICAgJG5vZGUtPnNldEtleSgka2V5KTsKICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VJbml0aWFsaXplciIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJG5vZGUtPnNldFZhbHVlKCR2YWx1ZSA/OiAka2V5KTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSW5pdGlhbGl6ZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiPSIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHZhbHVlID0gJHRoaXMtPnBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBvYmplY3QgYmluZGluZyBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxPYmplY3RQYXR0ZXJufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlT2JqZWN0QmluZGluZ1BhdHRlcm4oKQogICAgewogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgieyIpKSB7CgogICAgICAgICAgICAkcHJvcGVydGllcyA9IGFycmF5KCk7CiAgICAgICAgICAgIHdoaWxlICgkcHJvcCA9ICR0aGlzLT5wYXJzZUJpbmRpbmdQcm9wZXJ0eSgpKSB7CiAgICAgICAgICAgICAgICAkcHJvcGVydGllc1tdID0gJHByb3A7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+cmVzdFNwcmVhZFByb3BlcnRpZXMgJiYKICAgICAgICAgICAgICAgICgkcmVzdCA9ICR0aGlzLT5wYXJzZVJlc3RQcm9wZXJ0eSgpKSkgewogICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9ICRyZXN0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKSkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiT2JqZWN0UGF0dGVybiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICBpZiAoJHByb3BlcnRpZXMpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydGllcygkcHJvcGVydGllcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHJlc3QgcHJvcGVydHkKICAgICAqCiAgICAgKiBAcmV0dXJuIE5vZGVcUmVzdEVsZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VSZXN0UHJvcGVydHkoKQogICAgewogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLi4uIikpIHsKCiAgICAgICAgICAgIGlmICgkYXJndW1lbnQgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiUmVzdEVsZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBwcm9wZXJ0eSBpbiBhbiBvYmplY3QgYmluZGluZyBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxBc3NpZ25tZW50UHJvcGVydHl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VCaW5kaW5nUHJvcGVydHkoKQogICAgewogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgIGlmICgoJGtleSA9ICR0aGlzLT5wYXJzZVByb3BlcnR5TmFtZSgpKSAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpCiAgICAgICAgKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHZhbHVlID0gJHRoaXMtPnBhcnNlQmluZGluZ0VsZW1lbnQoKSkgewogICAgICAgICAgICAgICAgJHN0YXJ0UG9zID0gaXNzZXQoJGtleVsyXSkgPyAka2V5WzJdIDogJGtleVswXTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFzc2lnbm1lbnRQcm9wZXJ0eSIsICRzdGFydFBvcyk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRrZXlbMF0pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldENvbXB1dGVkKCRrZXlbMV0pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFZhbHVlKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgIGlmICgkcHJvcGVydHkgPSAkdGhpcy0+cGFyc2VTaW5nbGVOYW1lQmluZGluZygpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBc3NpZ25tZW50UHJvcGVydHkiLCAkcHJvcGVydHkpOwogICAgICAgICAgICAkbm9kZS0+c2V0U2hvcnRoYW5kKHRydWUpOwogICAgICAgICAgICBpZiAoJHByb3BlcnR5IGluc3RhbmNlb2YgTm9kZVxBc3NpZ25tZW50UGF0dGVybikgewogICAgICAgICAgICAgICAgJG5vZGUtPnNldEtleSgkcHJvcGVydHktPmdldExlZnQoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRwcm9wZXJ0eSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG5vZGUtPnNldFZhbHVlKCRwcm9wZXJ0eSk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICAkbGlzdCA9ICR0aGlzLT5jaGFyU2VwYXJhdGVkTGlzdE9mKCJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIik7CiAgICAgICAgCiAgICAgICAgaWYgKCEkbGlzdCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9IGVsc2VpZiAoY291bnQoJGxpc3QpID09PSAxKSB7CiAgICAgICAgICAgIHJldHVybiAkbGlzdFswXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTZXF1ZW5jZUV4cHJlc3Npb24iLCAkbGlzdCk7CiAgICAgICAgICAgICRub2RlLT5zZXRFeHByZXNzaW9ucygkbGlzdCk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGFzc2lnbm1lbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAoJGV4cHIgPSAkdGhpcy0+cGFyc2VBcnJvd0Z1bmN0aW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHByOwogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+Y29udGV4dC0+YWxsb3dZaWVsZCAmJiAkZXhwciA9ICR0aGlzLT5wYXJzZVlpZWxkRXhwcmVzc2lvbigpKSB7CiAgICAgICAgICAgIHJldHVybiAkZXhwcjsKICAgICAgICB9IGVsc2VpZiAoJGV4cHIgPSAkdGhpcy0+cGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJGV4cHJUeXBlcyA9IGFycmF5KAogICAgICAgICAgICAgICAgIkNvbmRpdGlvbmFsRXhwcmVzc2lvbiIsICJMb2dpY2FsRXhwcmVzc2lvbiIsCiAgICAgICAgICAgICAgICAiQmluYXJ5RXhwcmVzc2lvbiIsICJVcGRhdGVFeHByZXNzaW9uIiwgIlVuYXJ5RXhwcmVzc2lvbiIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJGV4cHItPmdldFR5cGUoKSwgJGV4cHJUeXBlcykpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG9wZXJhdG9ycyA9ICR0aGlzLT5hc3NpZ25tZW50T3BlcmF0b3JzOwogICAgICAgICAgICAgICAgaWYgKCRvcGVyYXRvciA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoJG9wZXJhdG9ycykpIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRleHByLT5nZXRUeXBlKCkgPT09ICJDaGFpbkV4cHJlc3Npb24iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPcHRpb25hbCBjaGFpbiBjYW4ndCBhcHBlYXIgaW4gbGVmdC1oYW5kIHNpZGUiCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcmlnaHQgPSAkdGhpcy0+cGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgkcmlnaHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3NpZ25tZW50RXhwcmVzc2lvbiIsICRleHByCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCR0aGlzLT5leHByZXNzaW9uVG9QYXR0ZXJuKCRleHByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcGVyYXRvcigkb3BlcmF0b3ItPnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFJpZ2h0KCRyaWdodCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRleHByOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjb25kaXRpb25hbCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ29uZGl0aW9uYWxFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAoJHRlc3QgPSAkdGhpcy0+cGFyc2VMb2dpY2FsQmluYXJ5RXhwcmVzc2lvbigpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIj8iKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkY29uc2VxdWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkY29uc2VxdWVudCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpICYmCiAgICAgICAgICAgICAgICAgICAgJGFsdGVybmF0ZSA9ICR0aGlzLT5wYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ29uZGl0aW9uYWxFeHByZXNzaW9uIiwgJHRlc3QpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEFsdGVybmF0ZSgkYWx0ZXJuYXRlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuICR0ZXN0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxvZ2ljYWwgb3IgYSBiaW5hcnkgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxvZ2ljYWxCaW5hcnlFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICAkb3BlcmF0b3JzID0gJHRoaXMtPmxvZ2ljYWxCaW5hcnlPcGVyYXRvcnM7CiAgICAgICAgaWYgKCEkdGhpcy0+Y29udGV4dC0+YWxsb3dJbikgewogICAgICAgICAgICB1bnNldCgkb3BlcmF0b3JzWyJpbiJdKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKCEoJGV4cCA9ICR0aGlzLT5wYXJzZVVuYXJ5RXhwcmVzc2lvbigpKSkgewogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAhJHRoaXMtPmZlYXR1cmVzLT5jbGFzc0ZpZWxkc1ByaXZhdGVJbiB8fAogICAgICAgICAgICAgICAgISR0aGlzLT5jb250ZXh0LT5hbGxvd0luCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9TdXBwb3J0ICIjcHJpdmF0ZSBpbiB4IiBzeW50YXgKICAgICAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICEoJGV4cCA9ICR0aGlzLT5wYXJzZVByaXZhdGVJZGVudGlmaWVyKCkpIHx8CiAgICAgICAgICAgICAgICAhJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KCJpbiIpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICgkZXhwKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbGlzdCA9IGFycmF5KCRleHApOwogICAgICAgICRjb2FsZXNjaW5nRm91bmQgPSAkYW5kT3JGb3VuZCA9IGZhbHNlOwogICAgICAgIHdoaWxlICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZU9uZU9mKGFycmF5X2tleXMoJG9wZXJhdG9ycykpKSB7CiAgICAgICAgICAgICRvcCA9ICR0b2tlbi0+dmFsdWU7CiAgICAgICAgICAgIC8vIENvYWxlc2NpbmcgYW5kIGxvZ2ljYWwgZXhwcmVzc2lvbnMgY2FuJ3QgYmUgdXNlZCB0b2dldGhlcgogICAgICAgICAgICBpZiAoJG9wID09PSAiPz8iKSB7CiAgICAgICAgICAgICAgICAkY29hbGVzY2luZ0ZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRvcCA9PT0gIiYmIiB8fCAkb3AgPT09ICJ8fCIpIHsKICAgICAgICAgICAgICAgICRhbmRPckZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGNvYWxlc2NpbmdGb3VuZCAmJiAkYW5kT3JGb3VuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICJMb2dpY2FsIGV4cHJlc3Npb25zIG11c3QgYmUgd3JhcHBlZCBpbiBwYXJlbnRoZXNlcyB3aGVuICIgLgogICAgICAgICAgICAgICAgICAgICJpbnNpZGUgY29hbGVzY2UgZXhwcmVzc2lvbnMiCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghKCRleHAgPSAkdGhpcy0+cGFyc2VVbmFyeUV4cHJlc3Npb24oKSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaXN0W10gPSAkb3A7CiAgICAgICAgICAgICRsaXN0W10gPSAkZXhwOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbGVuID0gY291bnQoJGxpc3QpOwogICAgICAgIGlmICgkbGVuID4gMSkgewogICAgICAgICAgICAkbWF4R3JhZGUgPSBtYXgoJG9wZXJhdG9ycyk7CiAgICAgICAgICAgIGZvciAoJGdyYWRlID0gJG1heEdyYWRlOyAkZ3JhZGUgPj0gMDsgJGdyYWRlLS0pIHsKICAgICAgICAgICAgICAgICRjbGFzcyA9ICRncmFkZSA8IDIgPyAiTG9naWNhbEV4cHJlc3Npb24iIDogIkJpbmFyeUV4cHJlc3Npb24iOwogICAgICAgICAgICAgICAgJHIybCA9ICRncmFkZSA9PT0gMTA7CiAgICAgICAgICAgICAgICAvL0V4cG9uZW50aWF0aW9uIG9wZXJhdG9yIG11c3QgYmUgcGFyc2VkIHJpZ2h0IHRvIGxlZnQKICAgICAgICAgICAgICAgIGlmICgkcjJsKSB7CiAgICAgICAgICAgICAgICAgICAgJGkgPSAkbGVuIC0gMjsKICAgICAgICAgICAgICAgICAgICAkc3RlcCA9IC0yOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaSA9IDE7CiAgICAgICAgICAgICAgICAgICAgJHN0ZXAgPSAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yICg7ICgkcjJsICYmICRpID4gMCkgfHwgKCEkcjJsICYmICRpIDwgJGxlbik7ICRpICs9ICRzdGVwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRvcGVyYXRvcnNbJGxpc3RbJGldXSA9PT0gJGdyYWRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoJGNsYXNzLCAkbGlzdFskaSAtIDFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldExlZnQoJGxpc3RbJGkgLSAxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcGVyYXRvcigkbGlzdFskaV0pOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJGxpc3RbJGkgKyAxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLCAkbGlzdFskaSArIDFdLT5sb2NhdGlvbi0+ZW5kCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3NwbGljZSgkbGlzdCwgJGkgLSAxLCAzLCBhcnJheSgkbm9kZSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRyMmwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpIC09ICRzdGVwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRsZW4gPSBjb3VudCgkbGlzdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkbGlzdFswXTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB1bmFyeSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlVW5hcnlFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICAkb3BlcmF0b3JzID0gJHRoaXMtPnVuYXJ5T3BlcmF0b3JzOwogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQgJiYgJHRoaXMtPmNvbnRleHQtPmFsbG93QXdhaXQpIHsKICAgICAgICAgICAgJG9wZXJhdG9yc1tdID0gImF3YWl0IjsKICAgICAgICB9CiAgICAgICAgaWYgKCRleHByID0gJHRoaXMtPnBhcnNlUG9zdGZpeEV4cHJlc3Npb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cHI7CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoJG9wZXJhdG9ycykpIHsKICAgICAgICAgICAgaWYgKCRhcmd1bWVudCA9ICR0aGlzLT5wYXJzZVVuYXJ5RXhwcmVzc2lvbigpKSB7CgogICAgICAgICAgICAgICAgJG9wID0gJHRva2VuLT52YWx1ZTsKCiAgICAgICAgICAgICAgICAvL0RlbGV0aW5nIGEgdmFyaWFibGUgd2l0aG91dCBhY2Nlc3NpbmcgaXRzIHByb3BlcnRpZXMgaXMgYQogICAgICAgICAgICAgICAgLy9zeW50YXggZXJyb3IgaW4gc3RyaWN0IG1vZGUKICAgICAgICAgICAgICAgIGlmICgkb3AgPT09ICJkZWxldGUiICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKSAmJgogICAgICAgICAgICAgICAgICAgICRhcmd1bWVudCBpbnN0YW5jZW9mIE5vZGVcSWRlbnRpZmllcikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIkRlbGV0aW5nIGFuIHVucXVhbGlmaWVkIGlkZW50aWZpZXIgaXMgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGUiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ICYmICRvcCA9PT0gImF3YWl0IikgewogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkF3YWl0RXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmICgkb3AgPT09ICIrKyIgfHwgJG9wID09PSAiLS0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkYXJndW1lbnQtPmdldFR5cGUoKSA9PT0gIkNoYWluRXhwcmVzc2lvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3B0aW9uYWwgY2hhaW4gY2FuJ3QgYXBwZWFyIGluIGxlZnQtaGFuZCBzaWRlIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJVcGRhdGVFeHByZXNzaW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFByZWZpeCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJVbmFyeUV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0T3BlcmF0b3IoJG9wKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRub2RlLT5zZXRBcmd1bWVudCgkYXJndW1lbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcG9zdGZpeCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlUG9zdGZpeEV4cHJlc3Npb24oKQogICAgewogICAgICAgIGlmICgkYXJndW1lbnQgPSAkdGhpcy0+cGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uKCkpIHsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+bm9MaW5lVGVybWluYXRvcnMoKSAmJgogICAgICAgICAgICAgICAgJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVPbmVPZigkdGhpcy0+cG9zdGZpeE9wZXJhdG9ycykKICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgaWYgKCRhcmd1bWVudC0+Z2V0VHlwZSgpID09PSAiQ2hhaW5FeHByZXNzaW9uIikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiBsZWZ0LWhhbmQgc2lkZSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJVcGRhdGVFeHByZXNzaW9uIiwgJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcGVyYXRvcigkdG9rZW4tPnZhbHVlKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRBcmd1bWVudCgkYXJndW1lbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJGFyZ3VtZW50OwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsZWZ0IGhhbmQgc2lkZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGVmdEhhbmRTaWRlRXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgJG9iamVjdCA9IG51bGw7CiAgICAgICAgJG5ld1Rva2VucyA9IGFycmF5KCk7CiAgICAgICAgCiAgICAgICAgLy9QYXJzZSBhbGwgb2NjdXJyZW5jZXMgb2YgIm5ldyIKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KCJuZXciKSkpIHsKICAgICAgICAgICAgd2hpbGUgKCRuZXdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJuZXciKSkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIuIikpIHsKICAgICAgICAgICAgICAgICAgICAvL25ldy50YXJnZXQKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ0YXJnZXQiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWV0YVByb3BlcnR5IiwgJG5ld1Rva2VuKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TWV0YSgibmV3Iik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnR5KCJ0YXJnZXQiKTsKICAgICAgICAgICAgICAgICAgICAkb2JqZWN0ID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbmV3VG9rZW5zW10gPSAkbmV3VG9rZW47CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmZlYXR1cmVzLT5pbXBvcnRNZXRhICYmCiAgICAgICAgICAgICR0aGlzLT5zb3VyY2VUeXBlID09PSBcUGVhc3RcUGVhc3Q6OlNPVVJDRV9UWVBFX01PRFVMRSAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoImltcG9ydCIsICIuIikpLCB0cnVlKQogICAgICAgICkgewogICAgICAgICAgICAvL2ltcG9ydC5tZXRhCiAgICAgICAgICAgICRpbXBvcnRUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbXBvcnQiKTsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4iKTsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgibWV0YSIpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJNZXRhUHJvcGVydHkiLCAkaW1wb3J0VG9rZW4pOwogICAgICAgICAgICAkbm9kZS0+c2V0TWV0YSgiaW1wb3J0Iik7CiAgICAgICAgICAgICRub2RlLT5zZXRQcm9wZXJ0eSgibWV0YSIpOwogICAgICAgICAgICAkb2JqZWN0ID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRuZXdUb2tlbnNDb3VudCA9IGNvdW50KCRuZXdUb2tlbnMpOwogICAgICAgIAogICAgICAgIGlmICghJG9iamVjdCAmJgogICAgICAgICAgICAhKCRvYmplY3QgPSAkdGhpcy0+cGFyc2VTdXBlclByb3BlcnR5T3JDYWxsKCkpICYmCiAgICAgICAgICAgICEoJHRoaXMtPmZlYXR1cmVzLT5keW5hbWljSW1wb3J0ICYmCiAgICAgICAgICAgICAgICAoJG9iamVjdCA9ICR0aGlzLT5wYXJzZUltcG9ydENhbGwoKSkKICAgICAgICAgICAgKSAmJgogICAgICAgICAgICAhKCRvYmplY3QgPSAkdGhpcy0+cGFyc2VQcmltYXJ5RXhwcmVzc2lvbigpKQogICAgICAgICkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRuZXdUb2tlbnNDb3VudCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgJG9wdGlvbmFsQ2hhaW4gPSBmYWxzZTsKICAgICAgICAkcHJvcGVydGllcyA9IGFycmF5KCk7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgJG9wdGlvbmFsID0gZmFsc2U7CiAgICAgICAgICAgIGlmICgkb3BUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoYXJyYXkoIj8uIiwgIi4iKSkpIHsKICAgICAgICAgICAgICAgICRpc09wdENoYWluID0gJG9wVG9rZW4tPnZhbHVlID09ICI/LiI7CiAgICAgICAgICAgICAgICBpZiAoJGlzT3B0Q2hhaW4pIHsKICAgICAgICAgICAgICAgICAgICAkb3B0aW9uYWxDaGFpbiA9ICRvcHRpb25hbCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKCR0aGlzLT5mZWF0dXJlcy0+cHJpdmF0ZU1ldGhvZHNBbmRGaWVsZHMgJiYgKCRwcm9wZXJ0eSA9ICR0aGlzLT5wYXJzZVByaXZhdGVJZGVudGlmaWVyKCkpKSB8fAogICAgICAgICAgICAgICAgICAgICgkcHJvcGVydHkgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGlkZW50aWZpZXJOYW1lKSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI9PiAiaWQiLAogICAgICAgICAgICAgICAgICAgICAgICAiaW5mbyIgPT4gJHByb3BlcnR5LAogICAgICAgICAgICAgICAgICAgICAgICAib3B0aW9uYWwiID0+ICRvcHRpb25hbAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR2YWxpZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmICghJGlzT3B0Q2hhaW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiWyIpKSB7CiAgICAgICAgICAgICAgICBpZiAoKCRwcm9wZXJ0eSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIl0iKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAkcHJvcGVydGllc1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIiA9PiAiY29tcHV0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAiaW5mbyIgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJvcGVydHksICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpCiAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb25hbCIgPT4gJG9wdGlvbmFsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcGVydHkgPSAkdGhpcy0+cGFyc2VUZW1wbGF0ZUxpdGVyYWwodHJ1ZSkpIHsKICAgICAgICAgICAgICAgIGlmICgkb3B0aW9uYWxDaGFpbikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiB0YWdnZWQgdGVtcGxhdGUgZXhwcmVzc2lvbnMiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgICAgICAgICAkcHJvcGVydGllc1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgInR5cGUiPT4gInRlbXBsYXRlIiwKICAgICAgICAgICAgICAgICAgICAiaW5mbyIgPT4gJHByb3BlcnR5LAogICAgICAgICAgICAgICAgICAgICJvcHRpb25hbCIgPT4gJG9wdGlvbmFsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2VpZiAoKCRhcmdzID0gJHRoaXMtPnBhcnNlQXJndW1lbnRzKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkdmFsaWQgPSB0cnVlOwogICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICJ0eXBlIj0+ICJhcmdzIiwKICAgICAgICAgICAgICAgICAgICAiaW5mbyIgPT4gYXJyYXkoJGFyZ3MsICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpKSwKICAgICAgICAgICAgICAgICAgICAib3B0aW9uYWwiID0+ICRvcHRpb25hbAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRwcm9wQ291bnQgPSBjb3VudCgkcHJvcGVydGllcyk7CiAgICAgICAgCiAgICAgICAgaWYgKCEkdmFsaWQpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfSBlbHNlaWYgKCEkcHJvcENvdW50ICYmICEkbmV3VG9rZW5zQ291bnQpIHsKICAgICAgICAgICAgcmV0dXJuICRvYmplY3Q7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRub2RlID0gbnVsbDsKICAgICAgICAkZW5kUG9zID0gJG9iamVjdC0+bG9jYXRpb24tPmVuZDsKICAgICAgICAkb3B0aW9uYWxDaGFpblN0YXJ0ZWQgPSBmYWxzZTsKICAgICAgICBmb3JlYWNoICgkcHJvcGVydGllcyBhcyAkaSA9PiAkcHJvcGVydHkpIHsKICAgICAgICAgICAgJGxhc3ROb2RlID0gJG5vZGUgPzogJG9iamVjdDsKICAgICAgICAgICAgaWYgKCRwcm9wZXJ0eVsib3B0aW9uYWwiXSkgewogICAgICAgICAgICAgICAgJG9wdGlvbmFsQ2hhaW5TdGFydGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHByb3BlcnR5WyJ0eXBlIl0gPT09ICJhcmdzIikgewogICAgICAgICAgICAgICAgaWYgKCRuZXdUb2tlbnNDb3VudCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkb3B0aW9uYWxDaGFpblN0YXJ0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiBuZXcgZXhwcmVzc2lvbnMiCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgICJOZXdFeHByZXNzaW9uIiwgYXJyYXlfcG9wKCRuZXdUb2tlbnMpCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAkbmV3VG9rZW5zQ291bnQtLTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ2FsbEV4cHJlc3Npb24iLCAkbGFzdE5vZGUpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcHRpb25hbCgkcHJvcGVydHlbIm9wdGlvbmFsIl0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG5vZGUtPnNldENhbGxlZSgkbGFzdE5vZGUpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50cygkcHJvcGVydHlbImluZm8iXVswXSk7CiAgICAgICAgICAgICAgICAkZW5kUG9zID0gJHByb3BlcnR5WyJpbmZvIl1bMV07CiAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcGVydHlbInR5cGUiXSA9PT0gImlkIikgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWVtYmVyRXhwcmVzc2lvbiIsICRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0T3B0aW9uYWwoJHByb3BlcnR5WyJvcHRpb25hbCJdKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRQcm9wZXJ0eSgkcHJvcGVydHlbImluZm8iXSk7CiAgICAgICAgICAgICAgICAkZW5kUG9zID0gJHByb3BlcnR5WyJpbmZvIl0tPmxvY2F0aW9uLT5lbmQ7CiAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcGVydHlbInR5cGUiXSA9PT0gImNvbXB1dGVkIikgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWVtYmVyRXhwcmVzc2lvbiIsICRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BlcnR5WyJpbmZvIl1bMF0pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldE9wdGlvbmFsKCRwcm9wZXJ0eVsib3B0aW9uYWwiXSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29tcHV0ZWQodHJ1ZSk7CiAgICAgICAgICAgICAgICAkZW5kUG9zID0gJHByb3BlcnR5WyJpbmZvIl1bMV07CiAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcGVydHlbInR5cGUiXSA9PT0gInRlbXBsYXRlIikgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uIiwgJG9iamVjdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VGFnKCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UXVhc2koJHByb3BlcnR5WyJpbmZvIl0pOwogICAgICAgICAgICAgICAgJGVuZFBvcyA9ICRwcm9wZXJ0eVsiaW5mbyJdLT5sb2NhdGlvbi0+ZW5kOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSwgJGVuZFBvcyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vV3JhcCB0aGUgcmVzdWx0IGluIG11bHRpcGxlIE5ld0V4cHJlc3Npb24gaWYgdGhlcmUgYXJlICJuZXciIHRva2VucwogICAgICAgIGlmICgkbmV3VG9rZW5zQ291bnQpIHsKICAgICAgICAgICAgZm9yICgkaSA9ICRuZXdUb2tlbnNDb3VudCAtIDE7ICRpID49IDA7ICRpLS0pIHsKICAgICAgICAgICAgICAgICRsYXN0Tm9kZSA9ICRub2RlID86ICRvYmplY3Q7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJOZXdFeHByZXNzaW9uIiwgJG5ld1Rva2Vuc1skaV0pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldENhbGxlZSgkbGFzdE5vZGUpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9XcmFwIHRoZSByZXN1bHQgaW4gYSBjaGFpbiBleHByZXNzaW9uIGlmIHJlcXVpcmVkCiAgICAgICAgaWYgKCRvcHRpb25hbENoYWluKSB7CiAgICAgICAgICAgICRwcmV2Tm9kZSA9ICRub2RlOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJDaGFpbkV4cHJlc3Npb24iLCAkcHJldk5vZGUpOwogICAgICAgICAgICAkbm9kZS0+c2V0RXhwcmVzc2lvbigkcHJldk5vZGUpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJG5vZGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgc3ByZWFkIGVsZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFNwcmVhZEVsZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTcHJlYWRFbGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4uLiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkYXJndW1lbnQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTcHJlYWRFbGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRBcmd1bWVudCgkYXJndW1lbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGFycmF5IGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEFycmF5RXhwcmVzc2lvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFycmF5TGl0ZXJhbCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJbIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRlbGVtZW50cyA9IGFycmF5KCk7CiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGVsaXNpb24gPSAkdGhpcy0+cGFyc2VFbGlzaW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICAkZWxlbWVudHMgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzLCBhcnJheV9maWxsKDAsICRlbGlzaW9uLCBudWxsKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoKCRlbGVtZW50ID0gJHRoaXMtPnBhcnNlU3ByZWFkRWxlbWVudCgpKSB8fAogICAgICAgICAgICAgICAgICAgICgkZWxlbWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICApKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAkZWxlbWVudDsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJdIikpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFycmF5RXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RWxlbWVudHMoJGVsZW1lbnRzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBhcmd1bWVudHMgbGlzdCB3cmFwcGVkIGluIHJvdW5kIGJyYWNrZXRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VBcmd1bWVudHMoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCRhcmdzID0gJHRoaXMtPnBhcnNlQXJndW1lbnRMaXN0KCkpICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgcmV0dXJuICRhcmdzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGFyZ3VtZW50cyBsaXN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VBcmd1bWVudExpc3QoKQogICAgewogICAgICAgICRsaXN0ID0gYXJyYXkoKTsKICAgICAgICAkaGFzQ29tbWEgPSBmYWxzZTsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAkc3ByZWFkID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4uLiIpOwogICAgICAgICAgICAkZXhwID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICghJGV4cCkgewogICAgICAgICAgICAgICAgLy9JZiB0aGVyZSdzIG5vIGV4cHJlc3Npb24gYW5kIHRoZSBzcHJlYWQgZG90cyBoYXZlIGJlZW4gZm91bmQKICAgICAgICAgICAgICAgIC8vb3IgdGhlcmUgaXMgYSB0cmFpbGluZyBjb21tYSB0aGF0IGlzIG5vdCBhbGxvd2VkLCB0aHJvdyBhbgogICAgICAgICAgICAgICAgLy9lcnJvcgogICAgICAgICAgICAgICAgaWYgKCRzcHJlYWQgfHwKICAgICAgICAgICAgICAgICAgICAoJGhhc0NvbW1hICYmCiAgICAgICAgICAgICAgICAgICAgISR0aGlzLT5mZWF0dXJlcy0+dHJhaWxpbmdDb21tYUZ1bmN0aW9uQ2FsbERlY2xhcmF0aW9uKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkc3ByZWFkKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTcHJlYWRFbGVtZW50IiwgJHNwcmVhZCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnQoJGV4cCk7CiAgICAgICAgICAgICAgICAkbGlzdFtdID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbGlzdFtdID0gJGV4cDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaGFzQ29tbWEgPSB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGxpc3Q7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgc3VwZXIgY2FsbCBvciBhIHN1cGVyIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU3VwZXJQcm9wZXJ0eU9yQ2FsbCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJzdXBlciIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkc3VwZXIgPSAkdGhpcy0+Y29tcGxldGVOb2RlKCR0aGlzLT5jcmVhdGVOb2RlKCJTdXBlciIsICR0b2tlbikpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkYXJncyA9ICR0aGlzLT5wYXJzZUFyZ3VtZW50cygpKSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ2FsbEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50cygkYXJncyk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q2FsbGVlKCRzdXBlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk1lbWJlckV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRzdXBlcik7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4iKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJHByb3BlcnR5ID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRpZGVudGlmaWVyTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BlcnR5KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiWyIpICYmCiAgICAgICAgICAgICAgICAoJHByb3BlcnR5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiXSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BlcnR5KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRDb21wdXRlZCh0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHByaW1hcnkgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVByaW1hcnlFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInRoaXMiKSkgewogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJUaGlzRXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZUZ1bmN0aW9uT3JHZW5lcmF0b3JFeHByZXNzaW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VDbGFzc0V4cHJlc3Npb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllclJlZmVyZW5jZSkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VMaXRlcmFsKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VBcnJheUxpdGVyYWwoKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZU9iamVjdExpdGVyYWwoKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZVJlZ3VsYXJFeHByZXNzaW9uTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkZXhwOwogICAgICAgIH0gZWxzZWlmICgkZXhwID0gJHRoaXMtPnBhcnNlVGVtcGxhdGVMaXRlcmFsKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5qc3ggJiYgKCRleHAgPSAkdGhpcy0+cGFyc2VKU1hGcmFnbWVudCgpKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmpzeCAmJiAoJGV4cCA9ICR0aGlzLT5wYXJzZUpTWEVsZW1lbnQoKSkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgoJGV4cCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiUGFyZW50aGVzaXplZEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEV4cHJlc3Npb24oJGV4cCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHByaXZhdGUgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcUHJpdmF0ZUlkZW50aWZpZXJ8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VQcml2YXRlSWRlbnRpZmllcigpCiAgICB7CiAgICAgICAgJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCk7CiAgICAgICAgaWYgKCEkdG9rZW4gfHwgJHRva2VuLT50eXBlICE9PSBUb2tlbjo6VFlQRV9QUklWQVRFX0lERU5USUZJRVIpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJQcml2YXRlSWRlbnRpZmllciIsICR0b2tlbik7CiAgICAgICAgJG5vZGUtPnNldE5hbWUoc3Vic3RyKCR0b2tlbi0+dmFsdWUsIDEpKTsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHBhcmFtIGludCAgICRtb2RlICAgICAgIFBhcnNpbmcgbW9kZSwgb25lIG9mIHRoZSBpZCBwYXJzaW5nIG1vZGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFmdGVyICAgICBJZiBhIHN0cmluZyBpcyBwYXNzZWQgaW4gdGhpcyBwYXJhbWV0ZXIsIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXIgaXMgcGFyc2VkIG9ubHkgaWYgcHJlY2VkZXMgdGhpcyBzdHJpbmcKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXElkZW50aWZpZXJ8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VJZGVudGlmaWVyKCRtb2RlLCAkYWZ0ZXIgPSBudWxsKQogICAgewogICAgICAgICR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgIGlmICghJHRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAoJGFmdGVyICE9PSBudWxsKSB7CiAgICAgICAgICAgICRuZXh0ID0gJHRoaXMtPnNjYW5uZXItPmdldE5leHRUb2tlbigpOwogICAgICAgICAgICBpZiAoISRuZXh0IHx8ICRuZXh0LT52YWx1ZSAhPT0gJGFmdGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdHlwZSA9ICR0b2tlbi0+dHlwZTsKICAgICAgICBzd2l0Y2ggKCR0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgVG9rZW46OlRZUEVfQk9PTEVBTl9MSVRFUkFMOgogICAgICAgICAgICBjYXNlIFRva2VuOjpUWVBFX05VTExfTElURVJBTDoKICAgICAgICAgICAgICAgIGlmICgkbW9kZSAhPT0gc2VsZjo6SURfQUxMT1dfQUxMKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRva2VuOjpUWVBFX0tFWVdPUkQ6CiAgICAgICAgICAgICAgICBpZiAoJG1vZGUgPT09IHNlbGY6OklEX0FMTE9XX05PVEhJTkcpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkbW9kZSA9PT0gc2VsZjo6SURfTUlYRUQgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+aXNTdHJpY3RNb2RlS2V5d29yZCgkdG9rZW4pCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpZiAoJHR5cGUgIT09IFRva2VuOjpUWVBFX0lERU5USUZJRVIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vRXhjbHVkZSBrZXl3b3JkcyB0aGF0IGRlcGVuZCBvbiBwYXJzZXIgY29udGV4dAogICAgICAgICR2YWx1ZSA9ICR0b2tlbi0+dmFsdWU7CiAgICAgICAgaWYgKCRtb2RlID09PSBzZWxmOjpJRF9NSVhFRCAmJgogICAgICAgICAgICBpc3NldCgkdGhpcy0+Y29udGV4dEtleXdvcmRzWyR2YWx1ZV0pICYmCiAgICAgICAgICAgICR0aGlzLT5jb250ZXh0LT57JHRoaXMtPmNvbnRleHRLZXl3b3Jkc1skdmFsdWVdfQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIklkZW50aWZpZXIiLCAkdG9rZW4pOwogICAgICAgICRub2RlLT5zZXRSYXdOYW1lKCR2YWx1ZSk7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXExpdGVyYWx8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VMaXRlcmFsKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCkpIHsKICAgICAgICAgICAgaWYgKCR0b2tlbi0+dHlwZSA9PT0gVG9rZW46OlRZUEVfTlVMTF9MSVRFUkFMKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJOdWxsTGl0ZXJhbCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdG9rZW4tPnR5cGUgPT09IFRva2VuOjpUWVBFX0JPT0xFQU5fTElURVJBTCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQm9vbGVhbkxpdGVyYWwiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFJhdygkdG9rZW4tPnZhbHVlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRsaXRlcmFsID0gJHRoaXMtPnBhcnNlU3RyaW5nTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpdGVyYWw7CiAgICAgICAgICAgIH0gZWxzZWlmICgkbGl0ZXJhbCA9ICR0aGlzLT5wYXJzZU51bWVyaWNMaXRlcmFsKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbGl0ZXJhbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdHJpbmcgbGl0ZXJhbAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3RyaW5nTGl0ZXJhbHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVN0cmluZ0xpdGVyYWwoKQogICAgewogICAgICAgICR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgIGlmICgkdG9rZW4gJiYgJHRva2VuLT50eXBlID09PSBUb2tlbjo6VFlQRV9TVFJJTkdfTElURVJBTCkgewogICAgICAgICAgICAkdmFsID0gJHRva2VuLT52YWx1ZTsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrSW52YWxpZEVzY2FwZVNlcXVlbmNlcygkdmFsKTsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTdHJpbmdMaXRlcmFsIiwgJHRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldFJhdygkdmFsKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBudW1lcmljIGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE51bWVyaWNMaXRlcmFsfE5vZGVcQmlnSW50TGl0ZXJhbHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU51bWVyaWNMaXRlcmFsKCkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoJHRva2VuICYmICR0b2tlbi0+dHlwZSA9PT0gVG9rZW46OlRZUEVfTlVNRVJJQ19MSVRFUkFMKSB7CiAgICAgICAgICAgICR2YWwgPSAkdG9rZW4tPnZhbHVlOwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tJbnZhbGlkRXNjYXBlU2VxdWVuY2VzKCR2YWwsIHRydWUpOwogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk51bWVyaWNMaXRlcmFsIiwgJHRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldFJhdygkdmFsKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0gZWxzZWlmICgkdG9rZW4gJiYgJHRva2VuLT50eXBlID09PSBUb2tlbjo6VFlQRV9CSUdJTlRfTElURVJBTCkgewogICAgICAgICAgICAkdmFsID0gJHRva2VuLT52YWx1ZTsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrSW52YWxpZEVzY2FwZVNlcXVlbmNlcygkdmFsLCB0cnVlKTsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJCaWdJbnRMaXRlcmFsIiwgJHRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldFJhdygkdmFsKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB0ZW1wbGF0ZSBsaXRlcmFsCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICR0YWdnZWQgVHJ1ZSBpZiB0aGUgdGVtcGxhdGUgaXMgdGFnZ2VkCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxMaXRlcmFsfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlVGVtcGxhdGVMaXRlcmFsKCR0YWdnZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICAKICAgICAgICBpZiAoISR0b2tlbiB8fCAkdG9rZW4tPnR5cGUgIT09IFRva2VuOjpUWVBFX1RFTVBMQVRFKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0RvIG5vdCBwYXJzZSB0ZW1wbGF0ZXMgcGFydHMKICAgICAgICAkdmFsID0gJHRva2VuLT52YWx1ZTsKICAgICAgICBpZiAoJHZhbFswXSAhPT0gImAiKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkcXVhc2lzID0gJGV4cHJlc3Npb25zID0gYXJyYXkoKTsKICAgICAgICAkdmFsaWQgPSBmYWxzZTsKICAgICAgICBkbyB7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgJHZhbCA9ICR0b2tlbi0+dmFsdWU7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0ludmFsaWRFc2NhcGVTZXF1ZW5jZXMoJHZhbCwgZmFsc2UsIHRydWUsICR0YWdnZWQpOwogICAgICAgICAgICAkbGFzdENoYXIgPSBzdWJzdHIoJHZhbCwgLTEpOwogICAgICAgICAgICAKICAgICAgICAgICAgJHF1YXNpID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlRlbXBsYXRlRWxlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICRxdWFzaS0+c2V0UmF3VmFsdWUoJHZhbCk7CiAgICAgICAgICAgIGlmICgkbGFzdENoYXIgPT09ICJgIikgewogICAgICAgICAgICAgICAgJHF1YXNpLT5zZXRUYWlsKHRydWUpOwogICAgICAgICAgICAgICAgJHF1YXNpc1tdID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkcXVhc2kpOwogICAgICAgICAgICAgICAgJHZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHF1YXNpc1tdID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkcXVhc2kpOwogICAgICAgICAgICAgICAgJGV4cCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCRleHApIHsKICAgICAgICAgICAgICAgICAgICAkZXhwcmVzc2lvbnNbXSA9ICRleHA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR2YWxpZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICB9IHdoaWxlICgkdG9rZW4gJiYgJHRva2VuLT50eXBlID09PSBUb2tlbjo6VFlQRV9URU1QTEFURSk7CiAgICAgICAgCiAgICAgICAgaWYgKCR2YWxpZCkgewogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJUZW1wbGF0ZUxpdGVyYWwiLCAkcXVhc2lzWzBdKTsKICAgICAgICAgICAgJG5vZGUtPnNldFF1YXNpcygkcXVhc2lzKTsKICAgICAgICAgICAgJG5vZGUtPnNldEV4cHJlc3Npb25zKCRleHByZXNzaW9ucyk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcmVndWxhciBleHByZXNzaW9uIGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXExpdGVyYWx8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VSZWd1bGFyRXhwcmVzc2lvbkxpdGVyYWwoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuQXNSZWdleHAoKSkgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlJlZ0V4cExpdGVyYWwiLCAkdG9rZW4pOwogICAgICAgICAgICAkbm9kZS0+c2V0UmF3KCR0b2tlbi0+dmFsdWUpOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlIGRpcmVjdGl2ZSBwcm9sb2d1ZXMuIFRoZSByZXN1bHQgaXMgYW4gYXJyYXkgd2hlcmUgdGhlIGZpcnN0IGVsZW1lbnQKICAgICAqIGlzIHRoZSBhcnJheSBvZiBwYXJzZWQgbm9kZXMgYW5kIHRoZSBzZWNvbmQgZWxlbWVudCBpcyB0aGUgYXJyYXkgb2YKICAgICAqIGRpcmVjdGl2ZSBwcm9sb2d1ZXMgdmFsdWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VEaXJlY3RpdmVQcm9sb2d1ZXMoKQogICAgewogICAgICAgICRkaXJlY3RpdmVzID0gJG5vZGVzID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpKSAmJgogICAgICAgICAgICAkdG9rZW4tPnR5cGUgPT09IFRva2VuOjpUWVBFX1NUUklOR19MSVRFUkFMCiAgICAgICAgKSB7CiAgICAgICAgICAgICRkaXJlY3RpdmUgPSBzdWJzdHIoJHRva2VuLT52YWx1ZSwgMSwgLTEpOwogICAgICAgICAgICBpZiAoJGRpcmVjdGl2ZSA9PT0gInVzZSBzdHJpY3QiKSB7CiAgICAgICAgICAgICAgICAkZGlyZWN0aXZlc1tdID0gJGRpcmVjdGl2ZTsKICAgICAgICAgICAgICAgICRkaXJlY3RpdmVOb2RlID0gJHRoaXMtPnBhcnNlU3RyaW5nTGl0ZXJhbCgpOwogICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJFeHByZXNzaW9uU3RhdGVtZW50IiwgJGRpcmVjdGl2ZU5vZGUpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEV4cHJlc3Npb24oJGRpcmVjdGl2ZU5vZGUpOwogICAgICAgICAgICAgICAgJG5vZGVzW10gPSAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb3VudCgkbm9kZXMpID8gYXJyYXkoJG5vZGVzLCAkZGlyZWN0aXZlcykgOiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGltcG9ydCBjYWxsCiAgICAgKgogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VJbXBvcnRDYWxsKCkKICAgIHsKICAgICAgICBpZiAoKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbXBvcnQiKSkgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSkgewoKICAgICAgICAgICAgaWYgKCgkc291cmNlID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFNvdXJjZSgkc291cmNlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gc3RyaW5nIG9yIG51bWJlciBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZXMKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgJHZhbCAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSB0byBjaGVjawogICAgICogQHBhcmFtIGJvb2wgICAgJG51bWJlciAgICAgICAgICAgICAgICAgICBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIG51bWJlcgogICAgICogQHBhcmFtIGJvb2wgICAgJGZvcmNlTGVnYWN5T2N0YWxDaGVjayAgICBUcnVlIHRvIGZvcmNlIGxlZ2FjeSBvY3RhbAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtIGNoZWNrCiAgICAgKiBAcGFyYW0gYm9vbCAgICAkdGFnZ2VkVGVtcGxhdGUgICAgICAgICAgIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgdGFnZ2VkCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tJbnZhbGlkRXNjYXBlU2VxdWVuY2VzKAogICAgICAgICR2YWwsICRudW1iZXIgPSBmYWxzZSwgJGZvcmNlTGVnYWN5T2N0YWxDaGVjayA9IGZhbHNlLAogICAgICAgICR0YWdnZWRUZW1wbGF0ZSA9IGZhbHNlCiAgICApIHsKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5za2lwRXNjYXBlU2VxQ2hlY2tJblRhZ2dlZFRlbXBsYXRlcyAmJgogICAgICAgICAgICAkdGFnZ2VkVGVtcGxhdGUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkY2hlY2tMZWdhY3lPY3RhbCA9ICRmb3JjZUxlZ2FjeU9jdGFsQ2hlY2sgfHwgJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKTsKICAgICAgICBpZiAoJG51bWJlcikgewogICAgICAgICAgICBpZiAoJHZhbCAmJiAkdmFsWzBdID09PSAiMCIgJiYgcHJlZ19tYXRjaCgiI14wWzAtOV9dKyQjIiwgJHZhbCkpIHsKICAgICAgICAgICAgICAgIGlmICgkY2hlY2tMZWdhY3lPY3RhbCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk9jdGFsIGxpdGVyYWxzIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+bnVtZXJpY0xpdGVyYWxTZXBhcmF0b3IgJiYKICAgICAgICAgICAgICAgICAgICBzdHJwb3MoJHZhbCwgJ18nKSAhPT0gZmFsc2UKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk51bWVyaWMgc2VwYXJhdG9ycyBhcmUgbm90IGFsbG93ZWQgaW4gbGVnYWN5IG9jdGFsIG51bWJlcnMiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChzdHJwb3MoJHZhbCwgIlxcIikgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRoZXggPSAiMC05YS1mQS1GIjsKICAgICAgICAgICAgJGludmFsaWRTeW50YXggPSBhcnJheSgKICAgICAgICAgICAgICAgICJ4WyRoZXhdP1teJGhleF0iLAogICAgICAgICAgICAgICAgInhbJGhleF0/JCIsCiAgICAgICAgICAgICAgICAidVx7XH0iLAogICAgICAgICAgICAgICAgInVceyg/OlskaGV4XSpbXiRoZXhcfV0rKStbJGhleF0qXH0iLAogICAgICAgICAgICAgICAgInVce1teXH1dKiQiLAogICAgICAgICAgICAgICAgInUoPyF7KVskaGV4XXswLDN9W14kaGV4XHtdIiwKICAgICAgICAgICAgICAgICJ1WyRoZXhdezAsM30kIgogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoJGNoZWNrTGVnYWN5T2N0YWwpIHsKICAgICAgICAgICAgICAgICRpbnZhbGlkU3ludGF4W10gPSAiXGR7Mn0iOwogICAgICAgICAgICAgICAgJGludmFsaWRTeW50YXhbXSA9ICJbMS03XSI7CiAgICAgICAgICAgICAgICAkaW52YWxpZFN5bnRheFtdID0gIjBbODldIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVnID0gIiMoXFxcXCspKCIgLiBpbXBsb2RlKCJ8IiwgJGludmFsaWRTeW50YXgpIC4gIikjIjsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2hfYWxsKCRyZWcsICR2YWwsICRtYXRjaGVzLCBQUkVHX1NFVF9PUkRFUikpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzIGFzICRtYXRjaCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oJG1hdGNoWzFdKSAlIDIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGZpcnN0ID0gJG1hdGNoWzJdWzBdOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGZpcnN0ID09PSAidSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlcnIgPSAiTWFsZm9ybWVkIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIjsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRmaXJzdCA9PT0gIngiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXJyID0gIk1hbGZvcm1lZCBoZXhhZGVjaW1hbCBlc2NhcGUgc2VxdWVuY2UiOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVyciA9ICJPY3RhbCBsaXRlcmFscyBhcmUgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGUiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcigkZXJyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBQYXJzZXIgZmVhdHVyZXMgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKiAKICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogKi8KY2xhc3MgRmVhdHVyZXMKewogICAgLyoqCiAgICAgKiBFeHBvbmVudGlhdGlvbiBvcGVyYXRvcgogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGV4cG9uZW50aWF0aW9uT3BlcmF0b3IgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEFzeW5jL2F3YWl0CiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkYXN5bmNBd2FpdCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogVHJhaWxpbmcgY29tbWEgaW4gZnVuY3Rpb24gY2FsbHMgYW5kIGRlY2xhcmF0aW9ucwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHRyYWlsaW5nQ29tbWFGdW5jdGlvbkNhbGxEZWNsYXJhdGlvbiA9IGZhbHNlOwoKICAgIC8qKgogICAgICogRm9yLWluIGluaXRpYWxpemVyCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkZm9ySW5Jbml0aWFsaXplciA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQXN5bmMgaXRlcmF0aW9uIGFuZCBnZW5lcmF0b3JzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkYXN5bmNJdGVyYXRpb25HZW5lcmF0b3JzID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBSZXN0L3NwcmVhZCBwcm9wZXJ0aWVzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkcmVzdFNwcmVhZFByb3BlcnRpZXMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFNraXAgZXNjYXBlIHNlcXVlbmNlcyBjaGVja3MgaW4gdGFnZ2VkIHRlbXBsYXRlCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkc2tpcEVzY2FwZVNlcUNoZWNrSW5UYWdnZWRUZW1wbGF0ZXMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIE9wdGlvbmFsIGNhdGNoIGJpbmRpbmcKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRvcHRpb25hbENhdGNoQmluZGluZyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogUGFyYWdyYXBoIGFuZCBsaW5lIHNlcGFyYXRvciBpbiBzdHJpbmdzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkcGFyYWdyYXBoTGluZVNlcEluU3RyaW5ncyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogRHluYW1pYyBpbXBvcnQKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRkeW5hbWljSW1wb3J0ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBCaWdJbnQgbGl0ZXJhbHMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRiaWdJbnQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEV4cG9ydGVkIG5hbWUgZm9yIGV4cG9ydCBhbGwgZGVjbGFyYXRpb25zCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkZXhwb3J0ZWROYW1lSW5FeHBvcnRBbGwgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEltcG9ydC5tZXRhCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkaW1wb3J0TWV0YSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQ29hbGVzY2luZyBvcGVyYXRvcgogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGNvYWxlc2NpbmdPcGVyYXRvciA9IGZhbHNlOwoKICAgIC8qKgogICAgICogT3B0aW9uYWwgY2hhaW5pbmcKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRvcHRpb25hbENoYWluaW5nID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBMb2dpY2FsIGFzc2lnbm1lbnQgb3BlcmF0b3JzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkbG9naWNhbEFzc2lnbm1lbnRPcGVyYXRvcnMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIE51bWVyaWMgbGl0ZXJhbCBzZXBhcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRudW1lcmljTGl0ZXJhbFNlcGFyYXRvciA9IGZhbHNlOwoKICAgIC8qKgogICAgICogUHJpdmF0ZSBtZXRob2RzIGFuZCBmaWVsZHMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRwcml2YXRlTWV0aG9kc0FuZEZpZWxkcyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQ2xhc3MgZmllbGRzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkY2xhc3NGaWVsZHMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqICJpbiIgb3BlcmF0b3IgZm9yIHByaXZhdGUgZmllbGRzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkY2xhc3NGaWVsZHNQcml2YXRlSW4gPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFRvcCBsZXZlbCBhd2FpdAogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHRvcExldmVsQXdhaXQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIENsYXNzIHN0YXRpYyBibG9jawogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGNsYXNzU3RhdGljQmxvY2sgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEFyYml0cmFyeSBtb2R1bGUgbmFtZXNwYWNlIGlkZW50aWZpZXIgbmFtZXMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRhcmJpdHJhcnlNb2R1bGVOU05hbWVzID0gZmFsc2U7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBBIHRva2VuIGVtaXR0ZWQgYnkgdGhlIHRva2VuaXplci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVG9rZW4gaW1wbGVtZW50cyBcSlNPTlNlcmlhbGl6YWJsZQp7CiAgICAvL1R5cGUgY29uc3RhbnRzCiAgICAvKioKICAgICAqIEJvb2xlYW4gbGl0ZXJhbAogICAgICovCiAgICBjb25zdCBUWVBFX0JPT0xFQU5fTElURVJBTCA9ICJCb29sZWFuIjsKICAgIAogICAgLyoqCiAgICAgKiBJZGVudGlmaWVyCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfSURFTlRJRklFUiA9ICJJZGVudGlmaWVyIjsKICAgIAogICAgLyoqCiAgICAgKiBQcml2YXRlIGlkZW50aWZpZXIKICAgICAqLwogICAgY29uc3QgVFlQRV9QUklWQVRFX0lERU5USUZJRVIgPSAiUHJpdmF0ZUlkZW50aWZpZXIiOwogICAgCiAgICAvKioKICAgICAqIEtleXdvcmQKICAgICAqLwogICAgY29uc3QgVFlQRV9LRVlXT1JEID0gIktleXdvcmQiOwogICAgCiAgICAvKioKICAgICAqIE51bGwgbGl0ZXJhbAogICAgICovCiAgICBjb25zdCBUWVBFX05VTExfTElURVJBTCA9ICJOdWxsIjsKICAgIAogICAgLyoqCiAgICAgKiBOdW1lcmljIGxpdGVyYWwKICAgICAqLwogICAgY29uc3QgVFlQRV9OVU1FUklDX0xJVEVSQUwgPSAiTnVtZXJpYyI7CiAgICAKICAgIC8qKgogICAgICogQmlnSW50IGxpdGVyYWwKICAgICAqLwogICAgY29uc3QgVFlQRV9CSUdJTlRfTElURVJBTCA9ICJCaWdJbnQiOwogICAgCiAgICAvKioKICAgICAqIFB1bmN0dWF0b3IKICAgICAqLwogICAgY29uc3QgVFlQRV9QVU5DVFVBVE9SID0gIlB1bmN0dWF0b3IiOwoKICAgIC8vVGhpcyBjb25zdGFudCBpcyBrZXB0IG9ubHkgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgc2luY2UgaXQgd2FzCiAgICAvL2ZpcnN0IHdyaXR0ZW4gd2l0aCBhIHR5cG8KICAgIGNvbnN0IFRZUEVfUFVOQ1RVVEFUT1IgPSAiUHVuY3R1YXRvciI7CiAgICAKICAgIC8qKgogICAgICogU3RyaW5nIGxpdGVyYWwKICAgICAqLwogICAgY29uc3QgVFlQRV9TVFJJTkdfTElURVJBTCA9ICJTdHJpbmciOwogICAgCiAgICAvKioKICAgICAqIFJlZ3VsYXIgZXhwcmVzc2lvbgogICAgICovCiAgICBjb25zdCBUWVBFX1JFR1VMQVJfRVhQUkVTU0lPTiA9ICJSZWd1bGFyRXhwcmVzc2lvbiI7CiAgICAKICAgIC8qKgogICAgICogVGVtcGxhdGUKICAgICAqLwogICAgY29uc3QgVFlQRV9URU1QTEFURSA9ICJUZW1wbGF0ZSI7CiAgICAKICAgIC8qKgogICAgICogQ29tbWVudAogICAgICovCiAgICBjb25zdCBUWVBFX0NPTU1FTlQgPSAiQ29tbWVudCI7CiAgICAKICAgIC8qKgogICAgICogSlNYIHRleHQKICAgICAqLwogICAgY29uc3QgVFlQRV9KU1hfVEVYVCA9ICJKU1hUZXh0IjsKICAgIAogICAgLyoqCiAgICAgKiBKU1ggaWRlbnRpZmllcgogICAgICovCiAgICBjb25zdCBUWVBFX0pTWF9JREVOVElGSUVSID0gIkpTWElkZW50aWZpZXIiOwogICAgCiAgICAvKioKICAgICAqIFRva2VucycgdHlwZSB0aGF0IGlzIG9uZSBvZiB0aGUgdHlwZSBjb25zdGFudHMKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHB1YmxpYyAkdHlwZTsKICAgIAogICAgLyoqCiAgICAgKiBUb2tlbidzIHZhbHVlCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwdWJsaWMgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIFRva2VuJ3MgbG9jYXRpb24gaW4gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEB2YXIgU291cmNlTG9jYXRpb24gCiAgICAgKi8KICAgIHB1YmxpYyAkbG9jYXRpb247CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSAgVG9rZW4ncyB0eXBlCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBUb2tlbidzIHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdHlwZSwgJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT50eXBlID0gJHR5cGU7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgICR0aGlzLT5sb2NhdGlvbiA9IG5ldyBTb3VyY2VMb2NhdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdG9rZW4ncyB0eXBlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRva2VuJ3MgdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdG9rZW4ncyBsb2NhdGlvbiBpbiB0aGUgc291cmNlIGNvZGUKICAgICAqIAogICAgICogQHJldHVybiBTb3VyY2VMb2NhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9jYXRpb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHRva2VuIGluIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0YXJ0UG9zaXRpb24oUG9zaXRpb24gJHBvc2l0aW9uKQogICAgewogICAgICAgICR0aGlzLT5sb2NhdGlvbi0+c3RhcnQgPSAkcG9zaXRpb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGVuZCBwb3NpdGlvbiBvZiB0aGUgdG9rZW4gaW4gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAkcG9zaXRpb24gRW5kIHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVuZFBvc2l0aW9uKFBvc2l0aW9uICRwb3NpdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+bG9jYXRpb24tPmVuZCA9ICRwb3NpdGlvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNlcmlhbGl6YWJsZSB2ZXJzaW9uIG9mIHRoZSBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24ganNvblNlcmlhbGl6ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAidHlwZSIgPT4gJHRoaXMtPnR5cGUsCiAgICAgICAgICAgICJ2YWx1ZSIgPT4gJHRoaXMtPnZhbHVlLAogICAgICAgICAgICAibG9jYXRpb24iID0+ICR0aGlzLT5sb2NhdGlvbgogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIHBvc2l0aW9uIGluIHRoZSBzb3VyY2UgY29kZS4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUG9zaXRpb24gaW1wbGVtZW50cyBcSlNPTlNlcmlhbGl6YWJsZQp7CiAgICAvKioKICAgICAqIFNvdXJjZSBsaW5lCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxpbmU7CiAgICAKICAgIC8qKgogICAgICogU291cmNlIGNvbHVtbgogICAgICogCiAgICAgKiBAdmFyIGludCAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb2x1bW47CiAgICAKICAgIC8qKgogICAgICogU291cmNlIGluZGV4CiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGluZGV4OwogICAgCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBpbnQgJGxpbmUgICBTb3VyY2UgbGluZQogICAgICogQHBhcmFtIGludCAkY29sdW1uIFNvdXJjZSBjb2x1bW4KICAgICAqIEBwYXJhbSBpbnQgJGluZGV4ICBTb3VyY2UgaW5kZXgKICAgICAqLwogICAgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGxpbmUsICRjb2x1bW4sICRpbmRleCkKICAgIHsKICAgICAgICAkdGhpcy0+bGluZSA9ICRsaW5lOwogICAgICAgICR0aGlzLT5jb2x1bW4gPSAkY29sdW1uOwogICAgICAgICR0aGlzLT5pbmRleCA9ICRpbmRleDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzb3VyY2UgbGluZQogICAgICogCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGluZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saW5lOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSBjb2x1bW4KICAgICAqIAogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbHVtbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb2x1bW47CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc291cmNlIGluZGV4CiAgICAgKiAKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbmRleCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmRleDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2VyaWFsaXphYmxlIHZlcnNpb24gb2YgdGhlIG9iamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgICNbXFJldHVyblR5cGVXaWxsQ2hhbmdlXQogICAgcHVibGljIGZ1bmN0aW9uIGpzb25TZXJpYWxpemUoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgImxpbmUiID0+ICR0aGlzLT5nZXRMaW5lKCksCiAgICAgICAgICAgICJjb2x1bW4iID0+ICR0aGlzLT5nZXRDb2x1bW4oKSwKICAgICAgICAgICAgImluZGV4IiA9PiAkdGhpcy0+Z2V0SW5kZXgoKQogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBFdmVudHMgZW1pdHRlciBjbGFzcy4gQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyB1c2VkIGJ5IFBhcnNlciBhbmQgU2Nhbm5lcgogKiB0byBlbWl0IGV2ZW50cyBhbmQgYXR0YWNoIGxpc3RlbmVycyB0byB0aGVtCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEV2ZW50c0VtaXR0ZXIKewogICAgLyoqCiAgICAgKiBFdmVudHMgcmVnaXN0cnkgYXJyYXkKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXZlbnRzUmVnaXN0cnkgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIEF0dGFjaGVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gdGhlIGdpdmVuIGV2ZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJGV2ZW50ICAgICAgRXZlbnQgbmFtZQogICAgICogQHBhcmFtIGNhbGxhYmxlICAkbGlzdGVuZXIgICBMaXN0ZW5lciBmdW5jdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRMaXN0ZW5lcigkZXZlbnQsICRsaXN0ZW5lcikKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5ldmVudHNSZWdpc3RyeVskZXZlbnRdKSkgewogICAgICAgICAgICAkdGhpcy0+ZXZlbnRzUmVnaXN0cnlbJGV2ZW50XSA9IGFycmF5KCk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5ldmVudHNSZWdpc3RyeVskZXZlbnRdW10gPSAkbGlzdGVuZXI7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEZpcmVzIGFuIGV2ZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJGV2ZW50ICBFdmVudCBuYW1lCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICRhcmdzICAgQXJndW1lbnRzIHRvIHBhc3MgdG8gZnVuY3Rpb25zIGF0dGFjaGVkIHRvIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpcmUoJGV2ZW50LCAkYXJncyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5ldmVudHNSZWdpc3RyeVskZXZlbnRdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZXZlbnRzUmVnaXN0cnlbJGV2ZW50XSBhcyAkbGlzdGVuZXIpIHsKICAgICAgICAgICAgICAgIGNhbGxfdXNlcl9mdW5jX2FycmF5KCRsaXN0ZW5lciwgJGFyZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIFN5bnRheCBleGNlcHRpb24gY2xhc3MuIFN5bnRheCBlcnJvcnMgaW4gdGhlIHNvdXJjZSBhcmUgdGhyb3duIHVzaW5nIHRoaXMKICogdXNpbmcgdGhpcyBleGNlcHRpb24gY2xhc3MuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICovCmNsYXNzIEV4Y2VwdGlvbiBleHRlbmRzIFxFeGNlcHRpb24KewogICAgLyoqCiAgICAgKiBFcnJvciBwb3NpdGlvbgogICAgICogCiAgICAgKiBAdmFyIFBvc2l0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcG9zaXRpb247CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgICRtZXNzYWdlICBFcnJvciBtZXNzYWdlCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIEVycm9yIHBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWVzc2FnZSwgUG9zaXRpb24gJHBvc2l0aW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UpOwogICAgICAgICR0aGlzLT5wb3NpdGlvbiA9ICRwb3NpdGlvbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlcnJvciBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQb3NpdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wb3NpdGlvbjsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XEVTMjAxOTsKCi8qKgogKiBFUzIwMTkgZmVhdHVyZXMgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKiAKICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogKi8KY2xhc3MgRmVhdHVyZXMgZXh0ZW5kcyBcUGVhc3RcU3ludGF4XEVTMjAxOFxGZWF0dXJlcwp7CiAgICAvKioKICAgICAqIE9wdGlvbmFsIGNhdGNoIGJpbmRpbmcKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRvcHRpb25hbENhdGNoQmluZGluZyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBQYXJhZ3JhcGggYW5kIGxpbmUgc2VwYXJhdG9yIGluIHN0cmluZ3MKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRwYXJhZ3JhcGhMaW5lU2VwSW5TdHJpbmdzID0gdHJ1ZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIFV0aWxpdGllcyBjbGFzcy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVXRpbHMKewogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBVVEYtOCBjaGFyYWN0ZXJzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciAgICAgICAgICAgIFN0cmluZyB0byBjb252ZXJ0CiAgICAgKiBAcGFyYW0gYm9vbCAgICRzdHJpY3RFbmNvZGluZyBJZiBmYWxzZSBhbmQgdGhlIHN0cmluZyBjb250YWlucyBpbnZhbGlkCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVEYtOCBjaGFyYWN0ZXJzLCBpdCB3aWxsIHJlcGxhY2UgdGhvc2UKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMgd2l0aCB0aGUgb25lIGRlZmluZWQgaW4gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYnN0cmluZy5zdWJzdGl0dXRlX2NoYXJhY3RlciBzZXR0aW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIAogICAgICogQHRocm93cyBFbmNvZGluZ0V4Y2VwdGlvbgogICAgICovCiAgICBzdGF0aWMgcHVibGljIGZ1bmN0aW9uIHN0cmluZ1RvVVRGOEFycmF5KCRzdHIsICRzdHJpY3RFbmNvZGluZyA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKCRzdHIgPT09ICIiKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KICAgICAgICAkcmV0ID0gcHJlZ19zcGxpdCgnLy91JywgJHN0ciwgLTEsIFBSRUdfU1BMSVRfTk9fRU1QVFkpOwogICAgICAgIGlmIChwcmVnX2xhc3RfZXJyb3IoKSA9PT0gUFJFR19CQURfVVRGOF9FUlJPUikgewogICAgICAgICAgICBpZiAoISRzdHJpY3RFbmNvZGluZykgewogICAgICAgICAgICAgICAgJHN0ciA9IG1iX2NvbnZlcnRfZW5jb2RpbmcoJHN0ciwgJ1VURi04JywgJ1VURi04Jyk7CiAgICAgICAgICAgICAgICAkcmV0ID0gc2VsZjo6c3RyaW5nVG9VVEY4QXJyYXkoJHN0ciwgZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVuY29kaW5nRXhjZXB0aW9uKCJTdHJpbmcgY29udGFpbnMgaW52YWxpZCBVVEYtOCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnZlcnRzIGFuIHVuaWNvZGUgY29kZSBwb2ludCB0byBVVEYtOAogICAgICogCiAgICAgKiBAcGFyYW0gaW50ICRudW0gVW5pY29kZSBjb2RlIHBvaW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgc3RhdGljIHB1YmxpYyBmdW5jdGlvbiB1bmljb2RlVG9VdGY4KCRudW0pCiAgICB7CiAgICAgICAgLy9Gcm9tOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE4MDU4MDIvcGhwLWNvbnZlcnQtdW5pY29kZS1jb2RlcG9pbnQtdG8tdXRmLTgjYW5zd2VyLTcxNTMxMzMKICAgICAgICBpZiAoJG51bSA8PSAweDdGKSB7CiAgICAgICAgICAgIHJldHVybiBjaHIoJG51bSk7CiAgICAgICAgfSBlbHNlaWYgKCRudW0gPD0gMHg3RkYpIHsKICAgICAgICAgICAgcmV0dXJuIGNocigoJG51bSA+PiA2KSArIDE5MikgLgogICAgICAgICAgICAgICAgICAgY2hyKCgkbnVtICYgNjMpICsgMTI4KTsKICAgICAgICB9IGVsc2VpZiAoJG51bSA8PSAweEZGRkYpIHsKICAgICAgICAgICAgcmV0dXJuIGNocigoJG51bSA+PiAxMikgKyAyMjQpIC4KICAgICAgICAgICAgICAgICAgIGNocigoKCRudW0gPj4gNikgJiA2MykgKyAxMjgpIC4KICAgICAgICAgICAgICAgICAgIGNocigoJG51bSAmIDYzKSArIDEyOCk7CiAgICAgICAgfSBlbHNlaWYgKCRudW0gPD0gMHgxRkZGRkYpIHsKICAgICAgICAgICAgcmV0dXJuIGNocigoJG51bSA+PiAxOCkgKyAyNDApIC4KICAgICAgICAgICAgICAgICAgIGNocigoKCRudW0gPj4gMTIpICYgNjMpICsgMTI4KSAuCiAgICAgICAgICAgICAgICAgICBjaHIoKCgkbnVtID4+IDYpICYgNjMpICsgMTI4KSAuCiAgICAgICAgICAgICAgICAgICBjaHIoKCRudW0gJiA2MykgKyAxMjgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJyc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29tcGlsZWQgbGluZSB0ZXJtaW5hdG9ycyBjYWNoZQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRsaW5lVGVybWluYXRvcnNDYWNoZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxpbmUgdGVybWluYXRvcnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldExpbmVUZXJtaW5hdG9ycygpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2FjaGUpIHsKICAgICAgICAgICAgc2VsZjo6JGxpbmVUZXJtaW5hdG9yc0NhY2hlID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoU2Nhbm5lcjo6JGxpbmVUZXJtaW5hdG9yc0NoYXJzIGFzICRjaGFyKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2FjaGVbXSA9IGlzX2ludCgkY2hhcikgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmOjp1bmljb2RlVG9VdGY4KCRjaGFyKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaGFyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2FjaGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHN1cnJvZ2F0ZSBwYWlyIG9mIFVuaWNvZGUgY29kZSBwb2ludHMgdG8gVVRGLTgKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkZmlyc3QgIEZpcnN0IFVuaWNvZGUgY29kZSBwb2ludAogICAgICogQHBhcmFtIHN0cmluZyAkc2Vjb25kIFNlY29uZCBVbmljb2RlIGNvZGUgcG9pbnQKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIAogICAgICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICovCiAgICBzdGF0aWMgcHVibGljIGZ1bmN0aW9uIHN1cnJvZ2F0ZVBhaXJUb1V0ZjgoJGZpcnN0LCAkc2Vjb25kKQogICAgewogICAgICAgIC8vRnJvbTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzkyMjY1OTMvaG93LXRvLWNvbnZlcnQtdXRmMTYtc3Vycm9nYXRlLXBhaXJzLXRvLWVxdWl2YWxlbnQtaGV4LWNvZGVwb2ludC1pbi1waHAKICAgICAgICAkdmFsdWUgPSAoKGhleGRlYygkZmlyc3QpICYgMHgzZmYpIDw8IDEwKSB8IChoZXhkZWMoJHNlY29uZCkgJiAweDNmZik7CiAgICAgICAgcmV0dXJuIHNlbGY6OnVuaWNvZGVUb1V0ZjgoJHZhbHVlICsgMHgxMDAwMCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBhIHN0cmluZyBhcyBpdCBhcHBlYXJzIGluIHRoZSBzb3VyY2UgY29kZSBhbmQgcmV0dXJucwogICAgICogYW4gdW5xdW90ZWQgdmVyc2lvbiBvZiBpdAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIgVGhlIHN0cmluZyB0byB1bnF1b3RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gdW5xdW90ZUxpdGVyYWxTdHJpbmcoJHN0cikKICAgIHsKICAgICAgICAvL1JlbW92ZSBxdW90ZXMKICAgICAgICAkc3RyID0gc3Vic3RyKCRzdHIsIDEsIC0xKTsKICAgICAgICAKICAgICAgICAvL1JldHVybiBpbW1lZGlhdGVseSBpZiB0aGUgZXNjYXBlIGNoYXJhY3RlciBpcyBtaXNzaW5nCiAgICAgICAgaWYgKHN0cnBvcygkc3RyLCAiXFwiKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRzdHI7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRsaW5lVGVybWluYXRvcnMgPSBzZWxmOjpnZXRMaW5lVGVybWluYXRvcnMoKTsKICAgICAgICAKICAgICAgICAvL1N1cnJvZ2F0ZSBwYWlycyByZWdleAogICAgICAgICRzdXJyb2dhdGVQYWlyc1JlZyA9IHNwcmludGYoCiAgICAgICAgICAgICd1KD86JTEkc3xceyUxJHNcfSlcXFxcdSg/OiUyJHN8XHslMiRzXH0pJywKICAgICAgICAgICAgIltkRF1bODlhYkFCXVswLTlhLWZBLUZdezJ9IiwgIltkRF1bYy1mQy1GXVswLTlhLWZBLUZdezJ9IgogICAgICAgICk7CiAgICAgICAgCiAgICAgICAgLy9IYW5kbGUgZXNjYXBlcwogICAgICAgICRwYXR0ZXJucyA9IGFycmF5KAogICAgICAgICAgICAkc3Vycm9nYXRlUGFpcnNSZWcsCiAgICAgICAgICAgICJ1XHtbYS1mQS1GMC05XStcfSIsCiAgICAgICAgICAgICJ1W2EtZkEtRjAtOV17NH0iLAogICAgICAgICAgICAieFthLWZBLUYwLTldezJ9IiwKICAgICAgICAgICAgIjBbMC03XXsyfSIsCiAgICAgICAgICAgICJbMS03XVswLTddIiwKICAgICAgICAgICAgIi4iCiAgICAgICAgKTsKICAgICAgICAkcmVnID0gIi9cXFxcKCIgLiBpbXBsb2RlKCJ8IiwgJHBhdHRlcm5zKSAuICIpL3MiOwogICAgICAgICRzaW1wbGVTZXF1ZW5jZSA9IGFycmF5KAogICAgICAgICAgICAibiIgPT4gIlxuIiwKICAgICAgICAgICAgImYiID0+ICJcZiIsCiAgICAgICAgICAgICJyIiA9PiAiXHIiLAogICAgICAgICAgICAidCIgPT4gIlx0IiwKICAgICAgICAgICAgInYiID0+ICJcdiIsCiAgICAgICAgICAgICJiIiA9PiAiXHg4IgogICAgICAgICk7CiAgICAgICAgJHJlcGxhY2VtZW50ID0gZnVuY3Rpb24gKCRtKSB1c2UgKCRzaW1wbGVTZXF1ZW5jZSwgJGxpbmVUZXJtaW5hdG9ycykgewogICAgICAgICAgICAkdHlwZSA9ICRtWzFdWzBdOwogICAgICAgICAgICBpZiAoaXNzZXQoJHNpbXBsZVNlcXVlbmNlWyR0eXBlXSkpIHsKICAgICAgICAgICAgICAgIC8vIFxuLCBcciwgXHQgLi4uCiAgICAgICAgICAgICAgICByZXR1cm4gJHNpbXBsZVNlcXVlbmNlWyR0eXBlXTsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09PSAidSIgfHwgJHR5cGUgPT09ICJ4IikgewogICAgICAgICAgICAgICAgLy9JbnZhbGlkIHVuaWNvZGUgb3IgaGV4YWRlY2ltYWwgc2VxdWVuY2VzCiAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRtWzFdKSA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAiXFwkdHlwZSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBTdXJyb2dhdGUgcGFpcgogICAgICAgICAgICAgICAgaWYgKCR0eXBlID09PSAidSIgJiYgc3RycG9zKCRtWzFdLCAiXFwiKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAkcG9pbnRzID0gZXhwbG9kZSgiXFwiLCAkbVsxXSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzOjpzdXJyb2dhdGVQYWlyVG9VdGY4KAogICAgICAgICAgICAgICAgICAgICAgICBzdHJfcmVwbGFjZShhcnJheSgieyIsICJ9IiwgInUiKSwgIiIsICRwb2ludHNbMF0pLAogICAgICAgICAgICAgICAgICAgICAgICBzdHJfcmVwbGFjZShhcnJheSgieyIsICJ9IiwgInUiKSwgIiIsICRwb2ludHNbMV0pCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFx1RkZGRiwgXHV7RkZGRn0sIFx4RkYKICAgICAgICAgICAgICAgICRjb2RlID0gc3Vic3RyKCRtWzFdLCAxKTsKICAgICAgICAgICAgICAgICRjb2RlID0gc3RyX3JlcGxhY2UoYXJyYXkoInsiLCAifSIpLCAiIiwgJGNvZGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzOjp1bmljb2RlVG9VdGY4KGhleGRlYygkY29kZSkpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPj0gIjAiICYmICR0eXBlIDw9ICI3IikgewogICAgICAgICAgICAgICAgLy9JbnZhbGlkIG9jdGFsIHNlcXVlbmNlcwogICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkbVsxXSkgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxcJHR5cGUiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gXDEyMwogICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzOjp1bmljb2RlVG9VdGY4KG9jdGRlYygkbVsxXSkpOwogICAgICAgICAgICB9IGVsc2VpZiAoaW5fYXJyYXkoJG1bMV0sICRsaW5lVGVybWluYXRvcnMpKSB7CiAgICAgICAgICAgICAgICAvLyBFc2NhcGVkIGxpbmUgdGVybWluYXRvcnMKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIEVzY2FwZWQgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgcmV0dXJuICRtWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCRyZWcsICRyZXBsYWNlbWVudCwgJHN0cik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBjb252ZXJ0cyBhIHN0cmluZyB0byBhIHF1b3RlZCBqYXZhc2NyaXB0IHN0cmluZwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIgICBTdHJpbmcgdG8gcXVvdGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1b3RlIFF1b3RlIGNoYXJhY3RlcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBzdGF0aWMgcHVibGljIGZ1bmN0aW9uIHF1b3RlTGl0ZXJhbFN0cmluZygkc3RyLCAkcXVvdGUpCiAgICB7CiAgICAgICAgJGVzY2FwZSA9IHNlbGY6OmdldExpbmVUZXJtaW5hdG9ycygpOwogICAgICAgICRlc2NhcGVbXSA9ICRxdW90ZTsKICAgICAgICAkZXNjYXBlW10gPSAiXFxcXCI7CiAgICAgICAgJHJlZyA9ICIvKCIgLiBpbXBsb2RlKCJ8IiwgJGVzY2FwZSkgLiAiKS8iOwogICAgICAgICRzdHIgPSBwcmVnX3JlcGxhY2UoJHJlZywgIlxcXFwkMSIsICRzdHIpOwogICAgICAgIHJldHVybiAkcXVvdGUgLiAkc3RyIC4gJHF1b3RlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnRpZXMgbWFwIGZvciB0aGUgZ2l2ZW4gbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJG5vZGUgTm9kZSBvciBjbGFzcyB0byBjb25zaWRlcgogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHN0YXRpYyBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UHJvcGVydGllc01hcCgkbm9kZSkKICAgIHsKICAgICAgICBzdGF0aWMgJGNhY2hlID0gYXJyYXkoKTsKICAgICAgICAKICAgICAgICBpZiAoJG5vZGUgaW5zdGFuY2VvZiBcUmVmbGVjdGlvbkNsYXNzKSB7CiAgICAgICAgICAgICRjbGFzc05hbWUgPSAkbm9kZS0+Z2V0TmFtZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjbGFzc05hbWUgPSBnZXRfY2xhc3MoJG5vZGUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoIWlzc2V0KCRjYWNoZVskY2xhc3NOYW1lXSkpIHsKICAgICAgICAgICAgJGNsYXNzID0gbmV3IFxSZWZsZWN0aW9uQ2xhc3MoJGNsYXNzTmFtZSk7CiAgICAgICAgICAgICRwYXJlbnQgPSAkY2xhc3MtPmdldFBhcmVudENsYXNzKCk7CiAgICAgICAgICAgICRwcm9wcyA9ICRwYXJlbnQgPyBzZWxmOjpnZXRQcm9wZXJ0aWVzTWFwKCRwYXJlbnQpIDogYXJyYXkoKTsKICAgICAgICAgICAgJGRlZmF1bHRzID0gJGNsYXNzLT5nZXREZWZhdWx0UHJvcGVydGllcygpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGRlZmF1bHRzWyJwcm9wZXJ0aWVzTWFwIl0pKSB7CiAgICAgICAgICAgICAgICAkcHJvcHMgPSBhcnJheV9tZXJnZSgkcHJvcHMsICRkZWZhdWx0c1sicHJvcGVydGllc01hcCJdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY2FjaGVbJGNsYXNzTmFtZV0gPSAkcHJvcHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkY2FjaGVbJGNsYXNzTmFtZV07CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydGllcyBsaXN0IGZvciB0aGUgZ2l2ZW4gbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gTm9kZVxOb2RlICRub2RlICAgICAgICBOb2RlIHRvIGNvbnNpZGVyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICR0cmF2ZXJzYWJsZSBJZiB0cnVlIGl0IHJldHVybnMgb25seSB0cmF2ZXJzYWJsZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBnZXROb2RlUHJvcGVydGllcyhOb2RlXE5vZGUgJG5vZGUsICR0cmF2ZXJzYWJsZSA9IGZhbHNlKQogICAgewogICAgICAgICRwcm9wcyA9IHNlbGY6OmdldFByb3BlcnRpZXNNYXAoJG5vZGUpOwogICAgICAgIHJldHVybiBhcnJheV9tYXAoCiAgICAgICAgICAgIGZ1bmN0aW9uICgkcHJvcCkgewogICAgICAgICAgICAgICAgJHVjUHJvcCA9IHVjZmlyc3QoJHByb3ApOwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgICAgICJuYW1lIiA9PiAkcHJvcCwKICAgICAgICAgICAgICAgICAgICAiZ2V0dGVyIiA9PiAiZ2V0JHVjUHJvcCIsCiAgICAgICAgICAgICAgICAgICAgInNldHRlciIgPT4gInNldCR1Y1Byb3AiCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBhcnJheV9rZXlzKCR0cmF2ZXJzYWJsZSA/IGFycmF5X2ZpbHRlcigkcHJvcHMpIDogJHByb3BzKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGV4cGFuZGVkIHZlcnNpb24gb2YgdGhlIHRyYXZlcnNhYmxlIG5vZGUgcHJvcGVydGllcy4KICAgICAqIFRoZSByZXR1cm4gb2YgdGhlIGZ1bmN0aW9uIGlzIGFuIGFycmF5IG9mIG5vZGUgcHJvcGVydGllcwogICAgICogdmFsdWVzIHdpdGggYXJyYXlzIGZsYXR0ZW5lZAogICAgICoKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgJG5vZGUgTm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHBhbmRlZE5vZGVQcm9wZXJ0aWVzKE5vZGVcTm9kZSAkbm9kZSkKICAgIHsKICAgICAgICAkcmV0ID0gYXJyYXkoKTsKICAgICAgICAkcHJvcHMgPSBzZWxmOjpnZXROb2RlUHJvcGVydGllcygkbm9kZSwgdHJ1ZSk7CiAgICAgICAgZm9yZWFjaCAoJHByb3BzIGFzICRwcm9wKSB7CiAgICAgICAgICAgICR2YWwgPSAkbm9kZS0+eyRwcm9wWyJnZXR0ZXIiXX0oKTsKICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWwpKSB7CiAgICAgICAgICAgICAgICAkcmV0ID0gYXJyYXlfbWVyZ2UoJHJldCwgJHZhbCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmV0W10gPSAkdmFsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0OwogICAgfQoKICAgIC8qKgogICAgICogRGVsZXRlIGFuIGFycmF5IGVsZW1lbnQgYnkgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICRhcnJheSBBcnJheQogICAgICogQHBhcmFtIG1peGVkICR2YWwgICBWYWx1ZSB0byByZW1vdmUKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlQXJyYXlWYWx1ZSgmJGFycmF5LCAkdmFsKQogICAgewogICAgICAgIGFycmF5X3NwbGljZSgkYXJyYXksIGFycmF5X3NlYXJjaCgkdmFsLCAkYXJyYXkpLCAxKTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGxvY2F0aW9uIGluIHRoZSBzb3VyY2UgY29kZSB3aXRoIHN0YXJ0IGFuZCBlbmQKICogcG9zaXRpb24uCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFNvdXJjZUxvY2F0aW9uIGltcGxlbWVudHMgXEpTT05TZXJpYWxpemFibGUKewogICAgLyoqCiAgICAgKiBTdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAdmFyIFBvc2l0aW9uIAogICAgICovCiAgICBwdWJsaWMgJHN0YXJ0OwogICAgCiAgICAvKioKICAgICAqIEVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAdmFyIFBvc2l0aW9uIAogICAgICovCiAgICBwdWJsaWMgJGVuZDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGFydCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGFydDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0YXJ0KFBvc2l0aW9uICRwb3NpdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnQgPSAkcG9zaXRpb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIEVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbmQoUG9zaXRpb24gJHBvc2l0aW9uKQogICAgewogICAgICAgICR0aGlzLT5lbmQgPSAkcG9zaXRpb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXJpYWxpemFibGUgdmVyc2lvbiBvZiB0aGUgb2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgI1tcUmV0dXJuVHlwZVdpbGxDaGFuZ2VdCiAgICBwdWJsaWMgZnVuY3Rpb24ganNvblNlcmlhbGl6ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAic3RhcnQiID0+ICR0aGlzLT5zdGFydCwKICAgICAgICAgICAgImVuZCIgPT4gJHRoaXMtPmVuZAogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBMb25nZXN0IFNlcXVlbmNlIE1hdGNoZXIuIFV0aWxpdHkgY2xhc3MgdXNlZCBieSB0aGUgc2Nhbm5lciB0byBjb25zdW1lCiAqIHRoZSBsb25nZXN0IHNlcXVlbmNlIG9mIGNoYXJhY3RlciBnaXZlbiBhIHNldCBvZiBhbGxvd2VkIGNoYXJhY3RlcnMgc2VxdWVuY2VzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBMU00KewogICAgLyoqCiAgICAgKiBJbnRlcm5hbCBzZXF1ZW5jZXMgbWFwCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbWFwID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBFbmNvZGluZyBoYW5kbGUgZmxhZwogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaGFuZGxlRW5jb2RpbmcgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkc2VxdWVuY2VzICAgICAgQWxsb3dlZCBjaGFyYWN0ZXJzIHNlcXVlbmNlcwogICAgICogQHBhcmFtIGJvb2wgICRoYW5kbGVFbmNvZGluZyBUcnVlIHRvIGhhbmRsZSBlbmNvZGluZyB3aGVuIG1hdGNoaW5nCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzZXF1ZW5jZXMsICRoYW5kbGVFbmNvZGluZyA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5oYW5kbGVFbmNvZGluZyA9ICRoYW5kbGVFbmNvZGluZzsKICAgICAgICBmb3JlYWNoICgkc2VxdWVuY2VzIGFzICRzKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGQoJHMpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBBZGRzIGEgc2VxdWVuY2UKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkc2VxdWVuY2UgU2VxdWVuY2UgdG8gYWRkCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZCgkc2VxdWVuY2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5oYW5kbGVFbmNvZGluZykgewogICAgICAgICAgICAkcyA9IFV0aWxzOjpzdHJpbmdUb1VURjhBcnJheSgkc2VxdWVuY2UpOwogICAgICAgICAgICAkZmlyc3QgPSAkc1swXTsKICAgICAgICAgICAgJGxlbiA9IGNvdW50KCRzKTsKICAgICAgICB9IGVsc2UgeyAgICAKICAgICAgICAgICAgJGZpcnN0ID0gJHNlcXVlbmNlWzBdOwogICAgICAgICAgICAkbGVuID0gc3RybGVuKCRzZXF1ZW5jZSk7CiAgICAgICAgfQogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPm1hcFskZmlyc3RdKSkgewogICAgICAgICAgICAkdGhpcy0+bWFwWyRmaXJzdF0gPSBhcnJheSgKICAgICAgICAgICAgICAgICJtYXhMZW4iID0+ICRsZW4sCiAgICAgICAgICAgICAgICAibWFwIiA9PiBhcnJheSgkc2VxdWVuY2UpCiAgICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPm1hcFskZmlyc3RdWyJtYXAiXVtdID0gJHNlcXVlbmNlOwogICAgICAgICAgICAkdGhpcy0+bWFwWyRmaXJzdF1bIm1heExlbiJdID0gbWF4KCR0aGlzLT5tYXBbJGZpcnN0XVsibWF4TGVuIl0sICRsZW4pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmVtb3ZlcyBhIHNlcXVlbmNlCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNlcXVlbmNlIFNlcXVlbmNlIHRvIHJlbW92ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmUoJHNlcXVlbmNlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aGFuZGxlRW5jb2RpbmcpIHsKICAgICAgICAgICAgJHMgPSBVdGlsczo6c3RyaW5nVG9VVEY4QXJyYXkoJHNlcXVlbmNlKTsKICAgICAgICAgICAgJGZpcnN0ID0gJHNbMF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGZpcnN0ID0gJHNlcXVlbmNlWzBdOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm1hcFskZmlyc3RdKSkgewogICAgICAgICAgICAkbGVuID0gJHRoaXMtPmhhbmRsZUVuY29kaW5nID8gY291bnQoJHMpIDogc3RybGVuKCRzZXF1ZW5jZSk7CiAgICAgICAgICAgICR0aGlzLT5tYXBbJGZpcnN0XVsibWFwIl0gPSBhcnJheV9kaWZmKAogICAgICAgICAgICAgICAgJHRoaXMtPm1hcFskZmlyc3RdWyJtYXAiXSwgYXJyYXkoJHNlcXVlbmNlKQogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoIWNvdW50KCR0aGlzLT5tYXBbJGZpcnN0XVsibWFwIl0pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+bWFwWyRmaXJzdF0pOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPm1hcFskZmlyc3RdWyJtYXhMZW4iXSA9PT0gJGxlbikgewogICAgICAgICAgICAgICAgLy8gUmVjYWxjdWxhdGUgdGhlIG1heCBsZW5ndGggaWYgbmVjZXNzYXJ5CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+bWFwWyRmaXJzdF1bIm1hcCJdIGFzICRtKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcFskZmlyc3RdWyJtYXhMZW4iXSA9IG1heCgKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcFskZmlyc3RdWyJtYXhMZW4iXSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKCRtKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHRoZSBtYXRjaC4gSXQgcmV0dXJucyBhbiBhcnJheSB3aGVyZSB0aGUgZmlyc3QgZWxlbWVudCBpcyB0aGUKICAgICAqIG51bWJlciBvZiBjb25zdW1lZCBjaGFyYWN0ZXJzIGFuZCB0aGUgc2Vjb25kIGVsZW1lbnQgaXMgdGhlIG1hdGNoLiBJZgogICAgICogbm8gbWF0Y2ggaXMgZm91bmQgaXQgcmV0dXJucyBudWxsLgogICAgICogCiAgICAgKiBAcGFyYW0gU2Nhbm5lciAgICRzY2FubmVyICAgIFNjYW5uZXIgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBpbnQgICAgICAgJGluZGV4ICAgICAgQ3VycmVudCBpbmRleAogICAgICogQHBhcmFtIHN0cmluZyAgICAkY2hhciAgICAgICBDdXJyZW50IGNoYXJhY3RlcgogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hdGNoKCRzY2FubmVyLCAkaW5kZXgsICRjaGFyKQogICAgewogICAgICAgICRjb25zdW1lZCA9IDE7CiAgICAgICAgJGJlc3RNYXRjaCA9IG51bGw7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5tYXBbJGNoYXJdKSkgewogICAgICAgICAgICAvL0lmIHRoZSBjaGFyYWN0ZXIgaXMgcHJlc2VudCBpbiB0aGUgbWFwIGFuZCBpdCBoYXMgYSBtYXggbGVuZ3RoIG9mCiAgICAgICAgICAgIC8vMSwgbWF0Y2ggaW1tZWRpYXRlbHkKICAgICAgICAgICAgaWYgKCR0aGlzLT5tYXBbJGNoYXJdWyJtYXhMZW4iXSA9PT0gMSkgewogICAgICAgICAgICAgICAgJGJlc3RNYXRjaCA9IGFycmF5KCRjb25zdW1lZCwgJGNoYXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9PdGhlcndpc2UgY29uc3VtZSBhIG51bWJlciBvZiBjaGFyYWN0ZXJzIGVxdWFsIHRvIHRoZSBtYXgKICAgICAgICAgICAgICAgIC8vbGVuZ3RoIGFuZCBmaW5kIHRoZSBsb25nZXN0IG1hdGNoCiAgICAgICAgICAgICAgICAkYnVmZmVyID0gJGNoYXI7CiAgICAgICAgICAgICAgICAkbWFwID0gJHRoaXMtPm1hcFskY2hhcl1bIm1hcCJdOwogICAgICAgICAgICAgICAgJG1heExlbiA9ICR0aGlzLT5tYXBbJGNoYXJdWyJtYXhMZW4iXTsKICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGJ1ZmZlciwgJG1hcCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJlc3RNYXRjaCA9IGFycmF5KCRjb25zdW1lZCwgJGJ1ZmZlcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRuZXh0Q2hhciA9ICRzY2FubmVyLT5jaGFyQXQoJGluZGV4ICsgJGNvbnN1bWVkKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJG5leHRDaGFyID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRuZXh0Q2hhcjsKICAgICAgICAgICAgICAgICAgICAkY29uc3VtZWQrKzsKICAgICAgICAgICAgICAgIH0gd2hpbGUgKCRjb25zdW1lZCA8PSAkbWF4TGVuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGJlc3RNYXRjaDsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIEVuY29kaW5nIGV4Y2VwdGlvbiBjbGFzcy4gRW5jb2RpbmcgZXJyb3JzIHdoaWxlIHNjYW5uaW5nIHRoZSBzb3VyY2UgYXJlCiAqIHRocm93biB1c2luZyB0aGlzIHVzaW5nIHRoaXMgZXhjZXB0aW9uIGNsYXNzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBFbmNvZGluZ0V4Y2VwdGlvbiBleHRlbmRzIFxFeGNlcHRpb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDE4OwoKLyoqCiAqIEVTMjAxOCBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDE3XEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogQXN5bmMgaXRlcmF0aW9uIGFuZCBnZW5lcmF0b3JzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkYXN5bmNJdGVyYXRpb25HZW5lcmF0b3JzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIFJlc3Qvc3ByZWFkIHByb3BlcnRpZXMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRyZXN0U3ByZWFkUHJvcGVydGllcyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBTa2lwIGVzY2FwZSBzZXF1ZW5jZXMgY2hlY2tzIGluIHRhZ2dlZCB0ZW1wbGF0ZQogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHNraXBFc2NhcGVTZXFDaGVja0luVGFnZ2VkVGVtcGxhdGVzID0gdHJ1ZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XEVTMjAxNzsKCi8qKgogKiBFUzIwMTcgZmVhdHVyZXMgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKiAKICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogKi8KY2xhc3MgRmVhdHVyZXMgZXh0ZW5kcyBcUGVhc3RcU3ludGF4XEVTMjAxNlxGZWF0dXJlcwp7CiAgICAvKioKICAgICAqIEFzeW5jL2F3YWl0CiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkYXN5bmNBd2FpdCA9IHRydWU7CgogICAgLyoqCiAgICAgKiBUcmFpbGluZyBjb21tYSBpbiBmdW5jdGlvbiBjYWxscyBhbmQgZGVjbGFyYXRpb25zCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkdHJhaWxpbmdDb21tYUZ1bmN0aW9uQ2FsbERlY2xhcmF0aW9uID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEZvci1pbiBpbml0aWFsaXplcgogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGZvckluSW5pdGlhbGl6ZXIgPSB0cnVlOwp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDE2OwoKLyoqCiAqIEVTMjAxNiBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDE1XEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogRXhwb25lbnRpYXRpb24gb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRleHBvbmVudGlhdGlvbk9wZXJhdG9yID0gdHJ1ZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XEVTMjAyMDsKCi8qKgogKiBFUzIwMjAgZmVhdHVyZXMgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKiAKICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogKi8KY2xhc3MgRmVhdHVyZXMgZXh0ZW5kcyBcUGVhc3RcU3ludGF4XEVTMjAxOVxGZWF0dXJlcwp7CiAgICAvKioKICAgICAqIER5bmFtaWMgaW1wb3J0CiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkZHluYW1pY0ltcG9ydCA9IHRydWU7CgogICAgLyoqCiAgICAgKiBCaWdJbnQgbGl0ZXJhbHMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRiaWdJbnQgPSB0cnVlOwoKICAgIC8qKgogICAgICogRXhwb3J0ZWQgbmFtZSBmb3IgZXhwb3J0IGFsbCBkZWNsYXJhdGlvbnMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRleHBvcnRlZE5hbWVJbkV4cG9ydEFsbCA9IHRydWU7CgogICAgLyoqCiAgICAgKiBJbXBvcnQubWV0YQogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGltcG9ydE1ldGEgPSB0cnVlOwoKICAgIC8qKgogICAgICogQ29hbGVzY2luZyBvcGVyYXRvcgogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGNvYWxlc2NpbmdPcGVyYXRvciA9IHRydWU7CgogICAgLyoqCiAgICAgKiBPcHRpb25hbCBjaGFpbmluZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJG9wdGlvbmFsQ2hhaW5pbmcgPSB0cnVlOwp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxGb3JtYXR0ZXI7CgovKioKICogQ29tcGFjdCBmb3JtYXR0ZXIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEV4cGFuZGVkIGV4dGVuZHMgQmFzZQp7CiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgb3BlbiBjdXJseSBicmFja2V0cyBpbiBjb2RlIGJsb2NrcyBtdXN0IGJlCiAgICAgKiBvbiBhIG5ldyBsaW5lCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJG5ld0xpbmVCZWZvcmVDdXJseUJyYWNrZXQgPSB0cnVlOwogICAgCiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgY29udGVudCBpbnNpZGUgcm91bmQgYnJhY2tldHMgbXVzdCBiZQogICAgICogc3Vycm91bmRlZCBieSBzcGFjZXMKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3BhY2VzSW5zaWRlUm91bmRCcmFja2V0cyA9IHRydWU7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XEZvcm1hdHRlcjsKCi8qKgogKiBDb21wYWN0IGZvcm1hdHRlci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tcGFjdCBleHRlbmRzIEJhc2UKewogICAgLyoqCiAgICAgKiBOZXcgbGluZSBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRuZXdMaW5lID0gIiI7CiAgICAKICAgIC8qKgogICAgICogSW5kZW50YXRpb24gY2hhcmFjdGVyCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5kZW50YXRpb24gPSAiIjsKICAgIAogICAgLyoqCiAgICAgKiBCb29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIG9wZXJhdG9ycyBtdXN0IGJlIHN1cnJvdW5kZWQgYnkgc3BhY2VzCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNwYWNlc0Fyb3VuZE9wZXJhdG9ycyA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgYmxvY2tzIG9mIGNvZGUgbXVzdCBiZSB3cmFwcGVkIGluIGN1cmx5CiAgICAgKiBicmFja2V0cyBhbHNvIGlmIHRoZXkgY29udGFpbiBvbmx5IG9uZSBpbnN0cnVjdGlvbgogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRhbHdheXNXcmFwQmxvY2tzID0gZmFsc2U7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XEZvcm1hdHRlcjsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBmb3JtYXR0ZXJzLCBhbGwgdGhlIGZvcm1hdHRlcnMgbXVzdCBleHRlbmQgdGhpcyBjbGFzcy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKiAKICogQGFic3RyYWN0CiAqLwphYnN0cmFjdCBjbGFzcyBCYXNlCnsKICAgIC8qKgogICAgICogTmV3IGxpbmUgY2hhcmFjdGVyCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbmV3TGluZSA9ICJcbiI7CiAgICAKICAgIC8qKgogICAgICogSW5kZW50YXRpb24gY2hhcmFjdGVyCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5kZW50YXRpb24gPSAiXHQiOwogICAgCiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgb3BlbiBjdXJseSBicmFja2V0cyBpbiBjb2RlIGJsb2NrcyBtdXN0IGJlCiAgICAgKiBvbiBhIG5ldyBsaW5lCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJG5ld0xpbmVCZWZvcmVDdXJseUJyYWNrZXQgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBCb29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIGJsb2NrcyBvZiBjb2RlIG11c3QgYmUgd3JhcHBlZCBpbiBjdXJseQogICAgICogYnJhY2tldHMgYWxzbyBpZiB0aGV5IGNvbnRhaW4gb25seSBvbmUgaW5zdHJ1Y3Rpb24KICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYWx3YXlzV3JhcEJsb2NrcyA9IHRydWU7CiAgICAKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBvcGVyYXRvcnMgbXVzdCBiZSBzdXJyb3VuZGVkIGJ5IHNwYWNlcwogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRzcGFjZXNBcm91bmRPcGVyYXRvcnMgPSB0cnVlOwogICAgCiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgY29udGVudCBpbnNpZGUgcm91bmQgYnJhY2tldHMgbXVzdCBiZQogICAgICogc3Vycm91bmRlZCBieSBzcGFjZXMKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3BhY2VzSW5zaWRlUm91bmRCcmFja2V0cyA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5ldyBsaW5lIGNoYXJhY3RlcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmV3TGluZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uZXdMaW5lOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGluZGVudGF0aW9uIGNoYXJhY3RlcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5kZW50YXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5kZW50YXRpb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIGJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgb3BlbiBjdXJseSBicmFja2V0cyBpbiBjb2RlIGJsb2NrcwogICAgICogbXVzdCBiZSBvbiBhIG5ldyBsaW5lCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmV3TGluZUJlZm9yZUN1cmx5QnJhY2tldCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uZXdMaW5lQmVmb3JlQ3VybHlCcmFja2V0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIGJsb2NrcyBvZiBjb2RlIG11c3QgYmUgd3JhcHBlZCBpbgogICAgICogY3VybHkgYnJhY2tldHMgYWxzbyBpZiB0aGV5IGNvbnRhaW4gb25seSBvbmUgaW5zdHJ1Y3Rpb24KICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbHdheXNXcmFwQmxvY2tzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsd2F5c1dyYXBCbG9ja3M7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIGJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgb3BlcmF0b3JzIG11c3QgYmUgc3Vycm91bmRlZCBieQogICAgICogc3BhY2VzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3BhY2VzQXJvdW5kT3BlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3BhY2VzQXJvdW5kT3BlcmF0b3JzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIGNvbnRlbnQgaW5zaWRlIHJvdW5kIGJyYWNrZXRzIG11c3QgYmUKICAgICAqIHN1cnJvdW5kZWQgYnkgc3BhY2VzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3BhY2VzSW5zaWRlUm91bmRCcmFja2V0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zcGFjZXNJbnNpZGVSb3VuZEJyYWNrZXRzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxGb3JtYXR0ZXI7CgovKioKICogUHJldHR5IHByaW50IGZvcm1hdHRlci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUHJldHR5UHJpbnQgZXh0ZW5kcyBCYXNlCnsKfSMjIE5BTUUKCgl7e25hbWV9fQoKe3sjc2hvcnRkZXNjfX0KIyMgREVTQ1JJUFRJT04KCgl7e3Nob3J0ZGVzY319Cgp7ey9zaG9ydGRlc2N9fQojIyBTWU5PUFNJUwoKCXt7c3lub3BzaXN9fQoKe3sjYWxpYXN9fQojIyBBTElBUwoKCXt7YWxpYXN9fQoKe3svYWxpYXN9fQp7eyNoYXMtc3ViY29tbWFuZHN9fQojIyBTVUJDT01NQU5EUwoKe3sjc3ViY29tbWFuZHN9fQoJe3sufX0Ke3svc3ViY29tbWFuZHN9fQoKe3svaGFzLXN1YmNvbW1hbmRzfX0Ke3sjaXNfc3ViY29tbWFuZH19CgoKe3svaXNfc3ViY29tbWFuZH19Cnt7I2hhc19zdWJjb21tYW5kc319CgoKe3svaGFzX3N1YmNvbW1hbmRzfX0Ke3sjaGFzX3BhcmFtZXRlcnN9fQojIyBHTE9CQUwgUEFSQU1FVEVSUwoKe3sjcGFyYW1ldGVyc319CiAge3tzeW5vcHNpc319CiAgICAgIHt7ZGVzY319Cgp7ey9wYXJhbWV0ZXJzfX0Ke3svaGFzX3BhcmFtZXRlcnN9fQp7eyNyb290X2NvbW1hbmR9fQogIFJ1biAnd3AgaGVscCA8Y29tbWFuZD4nIHRvIGdldCBtb3JlIGluZm9ybWF0aW9uIG9uIGEgc3BlY2lmaWMgY29tbWFuZC4KCnt7L3Jvb3RfY29tbWFuZH19Cjw/cGhwCi8qKgogKiBUaGUgYmFzZSBjb25maWd1cmF0aW9uIGZvciBXb3JkUHJlc3MKICoKICogVGhlIHdwLWNvbmZpZy5waHAgY3JlYXRpb24gc2NyaXB0IHVzZXMgdGhpcyBmaWxlIGR1cmluZyB0aGUgaW5zdGFsbGF0aW9uLgogKiBZb3UgZG9uJ3QgaGF2ZSB0byB1c2UgdGhlIHdlYiBzaXRlLCB5b3UgY2FuIGNvcHkgdGhpcyBmaWxlIHRvICJ3cC1jb25maWcucGhwIgogKiBhbmQgZmlsbCBpbiB0aGUgdmFsdWVzLgogKgogKiBUaGlzIGZpbGUgY29udGFpbnMgdGhlIGZvbGxvd2luZyBjb25maWd1cmF0aW9uczoKICoKICogKiBEYXRhYmFzZSBzZXR0aW5ncwogKiAqIFNlY3JldCBrZXlzCiAqICogRGF0YWJhc2UgdGFibGUgcHJlZml4CiAqICogTG9jYWxpemVkIGxhbmd1YWdlCiAqICogQUJTUEFUSAogKgogKiBAbGluayBodHRwczovL3dvcmRwcmVzcy5vcmcvc3VwcG9ydC9hcnRpY2xlL2VkaXRpbmctd3AtY29uZmlnLXBocC8KICoKICogQHBhY2thZ2UgV29yZFByZXNzCiAqLwoKLy8gKiogRGF0YWJhc2Ugc2V0dGluZ3MgLSBZb3UgY2FuIGdldCB0aGlzIGluZm8gZnJvbSB5b3VyIHdlYiBob3N0ICoqIC8vCi8qKiBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgZm9yIFdvcmRQcmVzcyAqLwpkZWZpbmUoICdEQl9OQU1FJywgJ3t7ZGJuYW1lfX0nICk7CgovKiogRGF0YWJhc2UgdXNlcm5hbWUgKi8KZGVmaW5lKCAnREJfVVNFUicsICd7e2RidXNlcn19JyApOwoKLyoqIERhdGFiYXNlIHBhc3N3b3JkICovCmRlZmluZSggJ0RCX1BBU1NXT1JEJywgJ3t7ZGJwYXNzfX0nICk7CgovKiogRGF0YWJhc2UgaG9zdG5hbWUgKi8KZGVmaW5lKCAnREJfSE9TVCcsICd7e2RiaG9zdH19JyApOwoKLyoqIERhdGFiYXNlIGNoYXJzZXQgdG8gdXNlIGluIGNyZWF0aW5nIGRhdGFiYXNlIHRhYmxlcy4gKi8KZGVmaW5lKCAnREJfQ0hBUlNFVCcsICd7e2RiY2hhcnNldH19JyApOwoKLyoqIFRoZSBkYXRhYmFzZSBjb2xsYXRlIHR5cGUuIERvbid0IGNoYW5nZSB0aGlzIGlmIGluIGRvdWJ0LiAqLwpkZWZpbmUoICdEQl9DT0xMQVRFJywgJ3t7ZGJjb2xsYXRlfX0nICk7CgovKiojQCsKICogQXV0aGVudGljYXRpb24gdW5pcXVlIGtleXMgYW5kIHNhbHRzLgogKgogKiBDaGFuZ2UgdGhlc2UgdG8gZGlmZmVyZW50IHVuaXF1ZSBwaHJhc2VzISBZb3UgY2FuIGdlbmVyYXRlIHRoZXNlIHVzaW5nCiAqIHRoZSB7QGxpbmsgaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZy9zZWNyZXQta2V5LzEuMS9zYWx0LyBXb3JkUHJlc3Mub3JnIHNlY3JldC1rZXkgc2VydmljZX0uCiAqCiAqIFlvdSBjYW4gY2hhbmdlIHRoZXNlIGF0IGFueSBwb2ludCBpbiB0aW1lIHRvIGludmFsaWRhdGUgYWxsIGV4aXN0aW5nIGNvb2tpZXMuCiAqIFRoaXMgd2lsbCBmb3JjZSBhbGwgdXNlcnMgdG8gaGF2ZSB0byBsb2cgaW4gYWdhaW4uCiAqCiAqIEBzaW5jZSAyLjYuMAogKi8Ke3sja2V5cy1hbmQtc2FsdHN9fQpkZWZpbmUoICdBVVRIX0tFWScsICAgICAgICAgICd7e2F1dGgta2V5fX0nICk7CmRlZmluZSggJ1NFQ1VSRV9BVVRIX0tFWScsICAgJ3t7c2VjdXJlLWF1dGgta2V5fX0nICk7CmRlZmluZSggJ0xPR0dFRF9JTl9LRVknLCAgICAgJ3t7bG9nZ2VkLWluLWtleX19JyApOwpkZWZpbmUoICdOT05DRV9LRVknLCAgICAgICAgICd7e25vbmNlLWtleX19JyApOwpkZWZpbmUoICdBVVRIX1NBTFQnLCAgICAgICAgICd7e2F1dGgtc2FsdH19JyApOwpkZWZpbmUoICdTRUNVUkVfQVVUSF9TQUxUJywgICd7e3NlY3VyZS1hdXRoLXNhbHR9fScgKTsKZGVmaW5lKCAnTE9HR0VEX0lOX1NBTFQnLCAgICAne3tsb2dnZWQtaW4tc2FsdH19JyApOwpkZWZpbmUoICdOT05DRV9TQUxUJywgICAgICAgICd7e25vbmNlLXNhbHR9fScgKTsKZGVmaW5lKCAnV1BfQ0FDSEVfS0VZX1NBTFQnLCAne3t3cC1jYWNoZS1rZXktc2FsdH19JyApOwp7ey9rZXlzLWFuZC1zYWx0c319Cnt7a2V5cy1hbmQtc2FsdHMtYWx0fX0KCi8qKiNALSovCgovKioKICogV29yZFByZXNzIGRhdGFiYXNlIHRhYmxlIHByZWZpeC4KICoKICogWW91IGNhbiBoYXZlIG11bHRpcGxlIGluc3RhbGxhdGlvbnMgaW4gb25lIGRhdGFiYXNlIGlmIHlvdSBnaXZlIGVhY2gKICogYSB1bmlxdWUgcHJlZml4LiBPbmx5IG51bWJlcnMsIGxldHRlcnMsIGFuZCB1bmRlcnNjb3JlcyBwbGVhc2UhCiAqLwokdGFibGVfcHJlZml4ID0gJ3t7ZGJwcmVmaXh9fSc7CgovKioKICogRm9yIGRldmVsb3BlcnM6IFdvcmRQcmVzcyBkZWJ1Z2dpbmcgbW9kZS4KICoKICogQ2hhbmdlIHRoaXMgdG8gdHJ1ZSB0byBlbmFibGUgdGhlIGRpc3BsYXkgb2Ygbm90aWNlcyBkdXJpbmcgZGV2ZWxvcG1lbnQuCiAqIEl0IGlzIHN0cm9uZ2x5IHJlY29tbWVuZGVkIHRoYXQgcGx1Z2luIGFuZCB0aGVtZSBkZXZlbG9wZXJzIHVzZSBXUF9ERUJVRwogKiBpbiB0aGVpciBkZXZlbG9wbWVudCBlbnZpcm9ubWVudHMuCiAqCiAqIEZvciBpbmZvcm1hdGlvbiBvbiBvdGhlciBjb25zdGFudHMgdGhhdCBjYW4gYmUgdXNlZCBmb3IgZGVidWdnaW5nLAogKiB2aXNpdCB0aGUgZG9jdW1lbnRhdGlvbi4KICoKICogQGxpbmsgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3N1cHBvcnQvYXJ0aWNsZS9kZWJ1Z2dpbmctaW4td29yZHByZXNzLwogKi8KZGVmaW5lKCAnV1BfREVCVUcnLCBmYWxzZSApOwoKe3sjYWRkLXdwbGFuZ319Ci8qKgogKiBXb3JkUHJlc3MgbG9jYWxpemVkIGxhbmd1YWdlLCBkZWZhdWx0cyB0byBFbmdsaXNoLgogKgogKiBDaGFuZ2UgdGhpcyB0byBsb2NhbGl6ZSBXb3JkUHJlc3MuIEEgY29ycmVzcG9uZGluZyBNTyBmaWxlIGZvciB0aGUgY2hvc2VuCiAqIGxhbmd1YWdlIG11c3QgYmUgaW5zdGFsbGVkIHRvIHdwLWNvbnRlbnQvbGFuZ3VhZ2VzLiBGb3IgZXhhbXBsZSwgaW5zdGFsbAogKiBkZV9ERS5tbyB0byB3cC1jb250ZW50L2xhbmd1YWdlcyBhbmQgc2V0IFdQTEFORyB0byAnZGVfREUnIHRvIGVuYWJsZSBHZXJtYW4KICogbGFuZ3VhZ2Ugc3VwcG9ydC4KICovCmRlZmluZSggJ1dQTEFORycsICd7e2xvY2FsZX19JyApOwp7ey9hZGQtd3BsYW5nfX0KCi8qIEFkZCBhbnkgY3VzdG9tIHZhbHVlcyBiZXR3ZWVuIHRoaXMgbGluZSBhbmQgdGhlICJzdG9wIGVkaXRpbmciIGxpbmUuICovCgp7e2V4dHJhLXBocH19CgovKiBUaGF0J3MgYWxsLCBzdG9wIGVkaXRpbmchIEhhcHB5IHB1Ymxpc2hpbmcuICovCgovKiogQWJzb2x1dGUgcGF0aCB0byB0aGUgV29yZFByZXNzIGRpcmVjdG9yeS4gKi8KaWYgKCAhIGRlZmluZWQoICdBQlNQQVRIJyApICkgewoJZGVmaW5lKCAnQUJTUEFUSCcsIF9fRElSX18gLiAnLycgKTsKfQoKLyoqIFNldHMgdXAgV29yZFByZXNzIHZhcnMgYW5kIGluY2x1ZGVkIGZpbGVzLiAqLwpyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1zZXR0aW5ncy5waHAnOwpXb3JkUHJlc3MgdmVyc2lvbjoge3t3cC12ZXJzaW9ufX0KRGF0YWJhc2UgcmV2aXNpb246IHt7ZGItdmVyc2lvbn19ClRpbnlNQ0UgdmVyc2lvbjogICB7e21jZS12ZXJzaW9ufX0KUGFja2FnZSBsYW5ndWFnZTogIHt7bG9jYWwtcGFja2FnZX19ClRoZW1lICU5e3tzbHVnfX0lbiBkZXRhaWxzOgogICAgTmFtZToge3tuYW1lfX0KICAgIFN0YXR1czoge3tzdGF0dXN9fSVuCiAgICBWZXJzaW9uOiB7e3ZlcnNpb259fQogICAgQXV0aG9yOiB7e2F1dGhvcn19ClBsdWdpbiAlOXt7c2x1Z319JW4gZGV0YWlsczoKICAgIE5hbWU6IHt7bmFtZX19CiAgICBTdGF0dXM6IHt7c3RhdHVzfX0lbgogICAgVmVyc2lvbjoge3t2ZXJzaW9ufX0KICAgIEF1dGhvcjoge3thdXRob3J9fQogICAgRGVzY3JpcHRpb246IHt7ZGVzY3JpcHRpb259fQpUaGVtZSAlOXt7c2x1Z319JW4gZGV0YWlsczoKICAgIE5hbWU6IHt7bmFtZX19CiAgICBTdGF0dXM6IHt7c3RhdHVzfX0lbgogICAgVmVyc2lvbjoge3t2ZXJzaW9ufX0KICAgIEF1dGhvcjoge3thdXRob3J9fQo8P3htbCB2ZXJzaW9uPSIxLjAiPz4KPHBocHVuaXQKCWJvb3RzdHJhcD0idGVzdHMvYm9vdHN0cmFwLnBocCIKCWJhY2t1cEdsb2JhbHM9ImZhbHNlIgoJY29sb3JzPSJ0cnVlIgoJY29udmVydEVycm9yc1RvRXhjZXB0aW9ucz0idHJ1ZSIKCWNvbnZlcnROb3RpY2VzVG9FeGNlcHRpb25zPSJ0cnVlIgoJY29udmVydFdhcm5pbmdzVG9FeGNlcHRpb25zPSJ0cnVlIgoJPgoJPHRlc3RzdWl0ZXM+CgkJPHRlc3RzdWl0ZT4KCQkJPGRpcmVjdG9yeSBwcmVmaXg9InRlc3QtIiBzdWZmaXg9Ii5waHAiPi4vdGVzdHMvPC9kaXJlY3Rvcnk+CgkJCTxleGNsdWRlPi4vdGVzdHMvdGVzdC1zYW1wbGUucGhwPC9leGNsdWRlPgoJCTwvdGVzdHN1aXRlPgoJPC90ZXN0c3VpdGVzPgo8L3BocHVuaXQ+Ci5EU19TdG9yZQpwaHBjcy54bWwKcGhwdW5pdC54bWwKVGh1bWJzLmRiCndwLWNsaS5sb2NhbC55bWwKbm9kZV9tb2R1bGVzLwoqLnNxbAoqLnRhci5negoqLnppcAoKewogICJuYW1lIjogInt7cGx1Z2luX3NsdWd9fSIsCiAgInZlcnNpb24iOiAiMC4xLjAiLAogICJtYWluIjogIkdydW50ZmlsZS5qcyIsCiAgImF1dGhvciI6ICJ7e3BsdWdpbl9hdXRob3J9fSIsCiAgInNjcmlwdHMiIDogewogICAgInN0YXJ0IiA6ICJncnVudCBkZWZhdWx0IiAsCiAgICAicmVhZG1lIiA6ICJncnVudCByZWFkbWUiLAogICAgImkxOG4iIDogImdydW50IGkxOG4iCiAgfSwKICAiZGV2RGVwZW5kZW5jaWVzIjogewogICAgImdydW50IjogIn4wLjQuNSIsCiAgICAiZ3J1bnQtd3AtaTE4biI6ICJ+MC41LjAiLAogICAgImdydW50LXdwLXJlYWRtZS10by1tYXJrZG93biI6ICJ+MS4wLjAiCiAgfQp9Cjw/cGhwCi8qKgogKiBQSFBVbml0IGJvb3RzdHJhcCBmaWxlLgogKgogKiBAcGFja2FnZSB7e3RoZW1lX3BhY2thZ2V9fQogKi8KCmlmICggUEhQX01BSk9SX1ZFUlNJT04gPj0gOCApIHsKCWVjaG8gIlRoZSBzY2FmZm9sZGVkIHRlc3RzIGNhbm5vdCBjdXJyZW50bHkgYmUgcnVuIG9uIFBIUCA4LjArLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL2lzc3Vlcy8yODUiIC4gUEhQX0VPTDsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5TZWN1cml0eS5Fc2NhcGVPdXRwdXQuT3V0cHV0Tm90RXNjYXBlZAoJZXhpdCggMSApOwp9CgokX3Rlc3RzX2RpciA9IGdldGVudiggJ1dQX1RFU1RTX0RJUicgKTsKCmlmICggISAkX3Rlc3RzX2RpciApIHsKCSRfdGVzdHNfZGlyID0gcnRyaW0oIHN5c19nZXRfdGVtcF9kaXIoKSwgJy9cXCcgKSAuICcvd29yZHByZXNzLXRlc3RzLWxpYic7Cn0KCmlmICggISBmaWxlX2V4aXN0cyggJF90ZXN0c19kaXIgLiAnL2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAnICkgKSB7CgllY2hvICJDb3VsZCBub3QgZmluZCB7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAsIGhhdmUgeW91IHJ1biBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCA/IiAuIFBIUF9FT0w7CglleGl0KCAxICk7Cn0KCi8vIEdpdmUgYWNjZXNzIHRvIHRlc3RzX2FkZF9maWx0ZXIoKSBmdW5jdGlvbi4KcmVxdWlyZV9vbmNlICJ7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAiOwoKLyoqCiAqIFJlZ2lzdGVycyB0aGVtZS4KICovCmZ1bmN0aW9uIF9yZWdpc3Rlcl90aGVtZSgpIHsKCgkkdGhlbWVfZGlyICAgICA9IGRpcm5hbWUoIF9fRElSX18gKTsKCSRjdXJyZW50X3RoZW1lID0gYmFzZW5hbWUoICR0aGVtZV9kaXIgKTsKCSR0aGVtZV9yb290ICAgID0gZGlybmFtZSggJHRoZW1lX2RpciApOwoKCWFkZF9maWx0ZXIoICd0aGVtZV9yb290JywgZnVuY3Rpb24gKCkgdXNlICggJHRoZW1lX3Jvb3QgKSB7CgkJcmV0dXJuICR0aGVtZV9yb290OwoJfSApOwoKCXJlZ2lzdGVyX3RoZW1lX2RpcmVjdG9yeSggJHRoZW1lX3Jvb3QgKTsKCglhZGRfZmlsdGVyKCAncHJlX29wdGlvbl90ZW1wbGF0ZScsIGZ1bmN0aW9uICgpIHVzZSAoICRjdXJyZW50X3RoZW1lICkgewoJCXJldHVybiAkY3VycmVudF90aGVtZTsKCX0gKTsKCglhZGRfZmlsdGVyKCAncHJlX29wdGlvbl9zdHlsZXNoZWV0JywgZnVuY3Rpb24gKCkgdXNlICggJGN1cnJlbnRfdGhlbWUgKSB7CgkJcmV0dXJuICRjdXJyZW50X3RoZW1lOwoJfSApOwp9Cgp0ZXN0c19hZGRfZmlsdGVyKCAnbXVwbHVnaW5zX2xvYWRlZCcsICdfcmVnaXN0ZXJfdGhlbWUnICk7CgovLyBTdGFydCB1cCB0aGUgV1AgdGVzdGluZyBlbnZpcm9ubWVudC4KcmVxdWlyZSAieyRfdGVzdHNfZGlyfS9pbmNsdWRlcy9ib290c3RyYXAucGhwIjsKPD9waHAKLyoqCiAqIENsYXNzIFNhbXBsZVRlc3QKICoKICogQHBhY2thZ2Uge3twbHVnaW5fcGFja2FnZX19CiAqLwoKLyoqCiAqIFNhbXBsZSB0ZXN0IGNhc2UuCiAqLwpjbGFzcyBTYW1wbGVUZXN0IGV4dGVuZHMgV1BfVW5pdFRlc3RDYXNlIHsKCgkvKioKCSAqIEEgc2luZ2xlIGV4YW1wbGUgdGVzdC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRlc3Rfc2FtcGxlKCkgewoJCS8vIFJlcGxhY2UgdGhpcyB3aXRoIHNvbWUgYWN0dWFsIHRlc3RpbmcgY29kZS4KCQkkdGhpcy0+YXNzZXJ0VHJ1ZSggdHJ1ZSApOwoJfQp9Cjw/cGhwCgovKioKICogUmVnaXN0ZXJzIHRoZSBge3ttYWNoaW5lX25hbWV9fWAgdGF4b25vbXksCiAqIGZvciB1c2Ugd2l0aCB7e3Bvc3RfdHlwZXN9fS4KICovCmZ1bmN0aW9uIHt7bWFjaGluZV9uYW1lfX1faW5pdCgpIHsKe3tvdXRwdXR9fQp9CgphZGRfYWN0aW9uKCAnaW5pdCcsICd7e21hY2hpbmVfbmFtZX19X2luaXQnICk7CgovKioKICogU2V0cyB0aGUgcG9zdCB1cGRhdGVkIG1lc3NhZ2VzIGZvciB0aGUgYHt7bWFjaGluZV9uYW1lfX1gIHRheG9ub215LgogKgogKiBAcGFyYW0gIGFycmF5ICRtZXNzYWdlcyBQb3N0IHVwZGF0ZWQgbWVzc2FnZXMuCiAqIEByZXR1cm4gYXJyYXkgTWVzc2FnZXMgZm9yIHRoZSBge3ttYWNoaW5lX25hbWV9fWAgdGF4b25vbXkuCiAqLwpmdW5jdGlvbiB7e21hY2hpbmVfbmFtZX19X3VwZGF0ZWRfbWVzc2FnZXMoICRtZXNzYWdlcyApIHsKCgkkbWVzc2FnZXNbJ3t7c2x1Z319J10gPSBbCgkJMCA9PiAnJywgLy8gVW51c2VkLiBNZXNzYWdlcyBzdGFydCBhdCBpbmRleCAxLgoJCTEgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSBhZGRlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJMiA9PiBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IGRlbGV0ZWQuJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCTMgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSB1cGRhdGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQk0ID0+IF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gbm90IGFkZGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQk1ID0+IF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gbm90IHVwZGF0ZWQuJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCTYgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0gZGVsZXRlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgldOwoKCXJldHVybiAkbWVzc2FnZXM7Cn0KCmFkZF9maWx0ZXIoICd0ZXJtX3VwZGF0ZWRfbWVzc2FnZXMnLCAne3ttYWNoaW5lX25hbWV9fV91cGRhdGVkX21lc3NhZ2VzJyApOwo8P3BocAovKioKICogUGx1Z2luIE5hbWU6ICAgICB7e3BsdWdpbl9uYW1lfX0KICogUGx1Z2luIFVSSTogICAgICB7e3BsdWdpbl91cml9fQogKiBEZXNjcmlwdGlvbjogICAgIHt7cGx1Z2luX2Rlc2NyaXB0aW9ufX0KICogQXV0aG9yOiAgICAgICAgICB7e3BsdWdpbl9hdXRob3J9fQogKiBBdXRob3IgVVJJOiAgICAgIHt7cGx1Z2luX2F1dGhvcl91cml9fQogKiBUZXh0IERvbWFpbjogICAgIHt7dGV4dGRvbWFpbn19CiAqIERvbWFpbiBQYXRoOiAgICAgL2xhbmd1YWdlcwogKiBWZXJzaW9uOiAgICAgICAgIDAuMS4wCiAqCiAqIEBwYWNrYWdlICAgICAgICAge3twbHVnaW5fcGFja2FnZX19CiAqLwoKLy8gWW91ciBjb2RlIHN0YXJ0cyBoZXJlLgo8P3htbCB2ZXJzaW9uPSIxLjAiPz4KPHJ1bGVzZXQgbmFtZT0iV29yZFByZXNzIENvZGluZyBTdGFuZGFyZHMgYmFzZWQgY3VzdG9tIHJ1bGVzZXQgZm9yIHlvdXIgcGx1Z2luIj4KCTxkZXNjcmlwdGlvbj5HZW5lcmFsbHktYXBwbGljYWJsZSBzbmlmZnMgZm9yIFdvcmRQcmVzcyBwbHVnaW5zLjwvZGVzY3JpcHRpb24+CgoJPCEtLSBXaGF0IHRvIHNjYW4gLS0+Cgk8ZmlsZT4uPC9maWxlPgoJPGV4Y2x1ZGUtcGF0dGVybj4vdmVuZG9yLzwvZXhjbHVkZS1wYXR0ZXJuPgoJPGV4Y2x1ZGUtcGF0dGVybj4vbm9kZV9tb2R1bGVzLzwvZXhjbHVkZS1wYXR0ZXJuPgoKCTwhLS0gSG93IHRvIHNjYW4gLS0+Cgk8IS0tIFVzYWdlIGluc3RydWN0aW9uczogaHR0cHM6Ly9naXRodWIuY29tL3NxdWl6bGFicy9QSFBfQ29kZVNuaWZmZXIvd2lraS9Vc2FnZSAtLT4KCTwhLS0gQW5ub3RhdGVkIHJ1bGVzZXQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9zcXVpemxhYnMvUEhQX0NvZGVTbmlmZmVyL3dpa2kvQW5ub3RhdGVkLXJ1bGVzZXQueG1sIC0tPgoJPGFyZyB2YWx1ZT0ic3AiLz4gPCEtLSBTaG93IHNuaWZmIGFuZCBwcm9ncmVzcyAtLT4KCTxhcmcgbmFtZT0iYmFzZXBhdGgiIHZhbHVlPSIuLyIvPjwhLS0gU3RyaXAgdGhlIGZpbGUgcGF0aHMgZG93biB0byB0aGUgcmVsZXZhbnQgYml0IC0tPgoJPGFyZyBuYW1lPSJjb2xvcnMiLz4KCTxhcmcgbmFtZT0iZXh0ZW5zaW9ucyIgdmFsdWU9InBocCIvPgoJPGFyZyBuYW1lPSJwYXJhbGxlbCIgdmFsdWU9IjgiLz48IS0tIEVuYWJsZXMgcGFyYWxsZWwgcHJvY2Vzc2luZyB3aGVuIGF2YWlsYWJsZSBmb3IgZmFzdGVyIHJlc3VsdHMuIC0tPgoKCTwhLS0gUnVsZXM6IENoZWNrIFBIUCB2ZXJzaW9uIGNvbXBhdGliaWxpdHkgLS0+Cgk8IS0tIGh0dHBzOi8vZ2l0aHViLmNvbS9QSFBDb21wYXRpYmlsaXR5L1BIUENvbXBhdGliaWxpdHkjc25pZmZpbmcteW91ci1jb2RlLWZvci1jb21wYXRpYmlsaXR5LXdpdGgtc3BlY2lmaWMtcGhwLXZlcnNpb25zIC0tPgoJPGNvbmZpZyBuYW1lPSJ0ZXN0VmVyc2lvbiIgdmFsdWU9IjUuNi0iLz4KCTwhLS0gaHR0cHM6Ly9naXRodWIuY29tL1BIUENvbXBhdGliaWxpdHkvUEhQQ29tcGF0aWJpbGl0eVdQIC0tPgoJPHJ1bGUgcmVmPSJQSFBDb21wYXRpYmlsaXR5V1AiLz4KCgk8IS0tIFJ1bGVzOiBXb3JkUHJlc3MgQ29kaW5nIFN0YW5kYXJkcyAtLT4KCTwhLS0gaHR0cHM6Ly9naXRodWIuY29tL1dvcmRQcmVzcy1Db2RpbmctU3RhbmRhcmRzL1dvcmRQcmVzcy1Db2RpbmctU3RhbmRhcmRzIC0tPgoJPCEtLSBodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvd2lraS9DdXN0b21pemFibGUtc25pZmYtcHJvcGVydGllcyAtLT4KCTxjb25maWcgbmFtZT0ibWluaW11bV9zdXBwb3J0ZWRfd3BfdmVyc2lvbiIgdmFsdWU9IjQuNiIvPgoJPHJ1bGUgcmVmPSJXb3JkUHJlc3MiLz4KCTxydWxlIHJlZj0iV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMiPgoJCTxwcm9wZXJ0aWVzPgoJCQk8IS0tIFZhbHVlOiByZXBsYWNlIHRoZSBmdW5jdGlvbiwgY2xhc3MsIGFuZCB2YXJpYWJsZSBwcmVmaXhlcyB1c2VkLiBTZXBhcmF0ZSBtdWx0aXBsZSBwcmVmaXhlcyB3aXRoIGEgY29tbWEuIC0tPgoJCQk8cHJvcGVydHkgbmFtZT0icHJlZml4ZXMiIHR5cGU9ImFycmF5IiB2YWx1ZT0ibXktcGx1Z2luIi8+CgkJPC9wcm9wZXJ0aWVzPgoJPC9ydWxlPgoJPHJ1bGUgcmVmPSJXb3JkUHJlc3MuV1AuSTE4biI+CgkJPHByb3BlcnRpZXM+CgkJCTwhLS0gVmFsdWU6IHJlcGxhY2UgdGhlIHRleHQgZG9tYWluIHVzZWQuIC0tPgoJCQk8cHJvcGVydHkgbmFtZT0idGV4dF9kb21haW4iIHR5cGU9ImFycmF5IiB2YWx1ZT0ibXktcGx1Z2luIi8+CgkJPC9wcm9wZXJ0aWVzPgoJPC9ydWxlPgoJPHJ1bGUgcmVmPSJXb3JkUHJlc3MuV2hpdGVTcGFjZS5Db250cm9sU3RydWN0dXJlU3BhY2luZyI+CgkJPHByb3BlcnRpZXM+CgkJCTxwcm9wZXJ0eSBuYW1lPSJibGFua19saW5lX2NoZWNrIiB2YWx1ZT0idHJ1ZSIvPgoJCTwvcHJvcGVydGllcz4KCTwvcnVsZT4KPC9ydWxlc2V0Pgptb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCBncnVudCApIHsKCgkndXNlIHN0cmljdCc7CgoJLy8gUHJvamVjdCBjb25maWd1cmF0aW9uCglncnVudC5pbml0Q29uZmlnKCB7CgoJCXBrZzogZ3J1bnQuZmlsZS5yZWFkSlNPTiggJ3BhY2thZ2UuanNvbicgKSwKCgkJYWRkdGV4dGRvbWFpbjogewoJCQlvcHRpb25zOiB7CgkJCQl0ZXh0ZG9tYWluOiAne3t0ZXh0ZG9tYWlufX0nLAoJCQl9LAoJCQl1cGRhdGVfYWxsX2RvbWFpbnM6IHsKCQkJCW9wdGlvbnM6IHsKCQkJCQl1cGRhdGVEb21haW5zOiB0cnVlCgkJCQl9LAoJCQkJc3JjOiBbICcqLnBocCcsICcqKi8qLnBocCcsICchXC5naXQvKiovKicsICchYmluLyoqLyonLCAnIW5vZGVfbW9kdWxlcy8qKi8qJywgJyF0ZXN0cy8qKi8qJyBdCgkJCX0KCQl9LAoKCQl3cF9yZWFkbWVfdG9fbWFya2Rvd246IHsKCQkJeW91cl90YXJnZXQ6IHsKCQkJCWZpbGVzOiB7CgkJCQkJJ1JFQURNRS5tZCc6ICdyZWFkbWUudHh0JwoJCQkJfQoJCQl9LAoJCX0sCgoJCW1ha2Vwb3Q6IHsKCQkJdGFyZ2V0OiB7CgkJCQlvcHRpb25zOiB7CgkJCQkJZG9tYWluUGF0aDogJy9sYW5ndWFnZXMnLAoJCQkJCWV4Y2x1ZGU6IFsgJ1wuZ2l0LyonLCAnYmluLyonLCAnbm9kZV9tb2R1bGVzLyonLCAndGVzdHMvKicgXSwKCQkJCQltYWluRmlsZTogJ3t7cGx1Z2luX3NsdWd9fS5waHAnLAoJCQkJCXBvdEZpbGVuYW1lOiAne3twbHVnaW5fc2x1Z319LnBvdCcsCgkJCQkJcG90SGVhZGVyczogewoJCQkJCQlwb2VkaXQ6IHRydWUsCgkJCQkJCSd4LXBvZWRpdC1rZXl3b3Jkc2xpc3QnOiB0cnVlCgkJCQkJfSwKCQkJCQl0eXBlOiAnd3AtcGx1Z2luJywKCQkJCQl1cGRhdGVUaW1lc3RhbXA6IHRydWUKCQkJCX0KCQkJfQoJCX0sCgl9ICk7CgoJZ3J1bnQubG9hZE5wbVRhc2tzKCAnZ3J1bnQtd3AtaTE4bicgKTsKCWdydW50LmxvYWROcG1UYXNrcyggJ2dydW50LXdwLXJlYWRtZS10by1tYXJrZG93bicgKTsKCWdydW50LnJlZ2lzdGVyVGFzayggJ2RlZmF1bHQnLCBbICdpMThuJywncmVhZG1lJyBdICk7CglncnVudC5yZWdpc3RlclRhc2soICdpMThuJywgWydhZGR0ZXh0ZG9tYWluJywgJ21ha2Vwb3QnXSApOwoJZ3J1bnQucmVnaXN0ZXJUYXNrKCAncmVhZG1lJywgWyd3cF9yZWFkbWVfdG9fbWFya2Rvd24nXSApOwoKCWdydW50LnV0aWwubGluZWZlZWQgPSAnXG4nOwoKfTsKPD9waHAKLyoqCiAqIENsYXNzIFNhbXBsZVRlc3QKICoKICogQHBhY2thZ2Uge3t0aGVtZV9wYWNrYWdlfX0KICovCgovKioKICogU2FtcGxlIHRlc3QgY2FzZS4KICovCmNsYXNzIFNhbXBsZVRlc3QgZXh0ZW5kcyBXUF9Vbml0VGVzdENhc2UgewoKCS8qKgoJICogQSBzaW5nbGUgZXhhbXBsZSB0ZXN0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gdGVzdF9zYW1wbGUoKSB7CgkJLy8gUmVwbGFjZSB0aGlzIHdpdGggc29tZSBhY3R1YWwgdGVzdGluZyBjb2RlLgoJCSR0aGlzLT5hc3NlcnRUcnVlKCB0cnVlICk7Cgl9Cn0KCXJlZ2lzdGVyX3RheG9ub215KCAne3tzbHVnfX0nLCBbIHt7cG9zdF90eXBlc319IF0sIFsKCQknaGllcmFyY2hpY2FsJyAgICAgICAgICA9PiBmYWxzZSwKCQkncHVibGljJyAgICAgICAgICAgICAgICA9PiB0cnVlLAoJCSdzaG93X2luX25hdl9tZW51cycgICAgID0+IHRydWUsCgkJJ3Nob3dfdWknICAgICAgICAgICAgICAgPT4gdHJ1ZSwKCQknc2hvd19hZG1pbl9jb2x1bW4nICAgICA9PiBmYWxzZSwKCQkncXVlcnlfdmFyJyAgICAgICAgICAgICA9PiB0cnVlLAoJCSdyZXdyaXRlJyAgICAgICAgICAgICAgID0+IHRydWUsCgkJJ2NhcGFiaWxpdGllcycgICAgICAgICAgPT4gWwoJCQknbWFuYWdlX3Rlcm1zJyA9PiAnZWRpdF9wb3N0cycsCgkJCSdlZGl0X3Rlcm1zJyAgID0+ICdlZGl0X3Bvc3RzJywKCQkJJ2RlbGV0ZV90ZXJtcycgPT4gJ2VkaXRfcG9zdHMnLAoJCQknYXNzaWduX3Rlcm1zJyA9PiAnZWRpdF9wb3N0cycsCgkJXSwKCQknbGFiZWxzJyAgICAgICAgICAgICAgICA9PiBbCgkJCSduYW1lJyAgICAgICAgICAgICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdzaW5ndWxhcl9uYW1lJyAgICAgICAgICAgICAgPT4gX3goICd7e2xhYmVsX3VjZmlyc3R9fScsICd0YXhvbm9teSBnZW5lcmFsIG5hbWUnLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdzZWFyY2hfaXRlbXMnICAgICAgICAgICAgICAgPT4gX18oICdTZWFyY2gge3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkncG9wdWxhcl9pdGVtcycgICAgICAgICAgICAgID0+IF9fKCAnUG9wdWxhciB7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdhbGxfaXRlbXMnICAgICAgICAgICAgICAgICAgPT4gX18oICdBbGwge3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkncGFyZW50X2l0ZW0nICAgICAgICAgICAgICAgID0+IF9fKCAnUGFyZW50IHt7bGFiZWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkncGFyZW50X2l0ZW1fY29sb24nICAgICAgICAgID0+IF9fKCAnUGFyZW50IHt7bGFiZWxfdWNmaXJzdH19OicsICd7e3RleHRkb21haW59fScgKSwKCQkJJ2VkaXRfaXRlbScgICAgICAgICAgICAgICAgICA9PiBfXyggJ0VkaXQge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSd1cGRhdGVfaXRlbScgICAgICAgICAgICAgICAgPT4gX18oICdVcGRhdGUge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSd2aWV3X2l0ZW0nICAgICAgICAgICAgICAgICAgPT4gX18oICdWaWV3IHt7bGFiZWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQknYWRkX25ld19pdGVtJyAgICAgICAgICAgICAgID0+IF9fKCAnQWRkIE5ldyB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ25ld19pdGVtX25hbWUnICAgICAgICAgICAgICA9PiBfXyggJ05ldyB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ3NlcGFyYXRlX2l0ZW1zX3dpdGhfY29tbWFzJyA9PiBfXyggJ1NlcGFyYXRlIHt7bGFiZWxfcGx1cmFsfX0gd2l0aCBjb21tYXMnLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdhZGRfb3JfcmVtb3ZlX2l0ZW1zJyAgICAgICAgPT4gX18oICdBZGQgb3IgcmVtb3ZlIHt7bGFiZWxfcGx1cmFsfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdjaG9vc2VfZnJvbV9tb3N0X3VzZWQnICAgICAgPT4gX18oICdDaG9vc2UgZnJvbSB0aGUgbW9zdCB1c2VkIHt7bGFiZWxfcGx1cmFsfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdub3RfZm91bmQnICAgICAgICAgICAgICAgICAgPT4gX18oICdObyB7e2xhYmVsX3BsdXJhbH19IGZvdW5kLicsICd7e3RleHRkb21haW59fScgKSwKCQkJJ25vX3Rlcm1zJyAgICAgICAgICAgICAgICAgICA9PiBfXyggJ05vIHt7bGFiZWxfcGx1cmFsfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdtZW51X25hbWUnICAgICAgICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdpdGVtc19saXN0X25hdmlnYXRpb24nICAgICAgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0gbGlzdCBuYXZpZ2F0aW9uJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQknaXRlbXNfbGlzdCcgICAgICAgICAgICAgICAgID0+IF9fKCAne3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19IGxpc3QnLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdtb3N0X3VzZWQnICAgICAgICAgICAgICAgICAgPT4gX3goICdNb3N0IFVzZWQnLCAne3tzbHVnfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdiYWNrX3RvX2l0ZW1zJyAgICAgICAgICAgICAgPT4gX18oICcmbGFycjsgQmFjayB0byB7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJXSwKCQknc2hvd19pbl9yZXN0JyAgICAgICAgICA9PiB0cnVlLAoJCSdyZXN0X2Jhc2UnICAgICAgICAgICAgID0+ICd7e3NsdWd9fScsCgkJJ3Jlc3RfY29udHJvbGxlcl9jbGFzcycgPT4gJ1dQX1JFU1RfVGVybXNfQ29udHJvbGxlcicsCgldICk7CiMgVGhpcyBmaWxlIGlzIGZvciB1bmlmeWluZyB0aGUgY29kaW5nIHN0eWxlIGZvciBkaWZmZXJlbnQgZWRpdG9ycyBhbmQgSURFcwojIGVkaXRvcmNvbmZpZy5vcmcKCiMgV29yZFByZXNzIENvZGluZyBTdGFuZGFyZHMKIyBodHRwczovL21ha2Uud29yZHByZXNzLm9yZy9jb3JlL2hhbmRib29rL2NvZGluZy1zdGFuZGFyZHMvCgpyb290ID0gdHJ1ZQoKWypdCmNoYXJzZXQgPSB1dGYtOAplbmRfb2ZfbGluZSA9IGxmCmluc2VydF9maW5hbF9uZXdsaW5lID0gdHJ1ZQp0cmltX3RyYWlsaW5nX3doaXRlc3BhY2UgPSB0cnVlCmluZGVudF9zdHlsZSA9IHRhYgppbmRlbnRfc2l6ZSA9IDQKClt7LmpzaGludHJjLCouanNvbiwqLnltbH1dCmluZGVudF9zdHlsZSA9IHNwYWNlCmluZGVudF9zaXplID0gMgoKW3sqLnR4dCx3cC1jb25maWctc2FtcGxlLnBocH1dCmVuZF9vZl9saW5lID0gY3JsZgovKioKICogVGhlIGZvbGxvd2luZyBzdHlsZXMgZ2V0IGFwcGxpZWQgaW5zaWRlIHRoZSBlZGl0b3Igb25seS4KICoKICogUmVwbGFjZSB0aGVtIHdpdGggeW91ciBvd24gc3R5bGVzIG9yIHJlbW92ZSB0aGUgZmlsZSBjb21wbGV0ZWx5LgogKi8KCi53cC1ibG9jay17e25hbWVzcGFjZX19LXt7c2x1Z319IHsKCWJvcmRlcjogMXB4IGRvdHRlZCAjZjAwOwp9Ci8qKgogKiBUaGUgZm9sbG93aW5nIHN0eWxlcyBnZXQgYXBwbGllZCBib3RoIG9uIHRoZSBmcm9udCBvZiB5b3VyIHNpdGUgYW5kIGluIHRoZSBlZGl0b3IuCiAqCiAqIFJlcGxhY2UgdGhlbSB3aXRoIHlvdXIgb3duIHN0eWxlcyBvciByZW1vdmUgdGhlIGZpbGUgY29tcGxldGVseS4KICovCgoud3AtYmxvY2ste3tuYW1lc3BhY2V9fS17e3NsdWd9fSB7CgliYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwoJY29sb3I6ICNmZmY7CglwYWRkaW5nOiAycHg7Cn0Kd29ya2Zsb3dzOgogIHZlcnNpb246IDIKICBtYWluOgogICAgam9iczoKICAgICAgLSBwaHA1Ni1idWlsZAogICAgICAtIHBocDcwLWJ1aWxkCiAgICAgIC0gcGhwNzEtYnVpbGQKICAgICAgLSBwaHA3Mi1idWlsZAogICAgICAtIHBocDczLWJ1aWxkCiAgICAgIC0gcGhwNzQtYnVpbGQKCnZlcnNpb246IDIKCmpvYi1yZWZlcmVuY2VzOgogIG15c3FsX2ltYWdlOiAmbXlzcWxfaW1hZ2UKICAgIGNpcmNsZWNpL215c3FsOjUuNgoKICBzZXR1cF9lbnZpcm9ubWVudDogJnNldHVwX2Vudmlyb25tZW50CiAgICBuYW1lOiAiU2V0dXAgRW52aXJvbm1lbnQgVmFyaWFibGVzIgogICAgY29tbWFuZDogfAogICAgICBlY2hvICJleHBvcnQgUEFUSD0kSE9NRS8uY29tcG9zZXIvdmVuZG9yL2JpbjokUEFUSCIgPj4gJEJBU0hfRU5WCiAgICAgIHNvdXJjZSAvaG9tZS9jaXJjbGVjaS8uYmFzaHJjCgogIGluc3RhbGxfZGVwZW5kZW5jaWVzOiAmaW5zdGFsbF9kZXBlbmRlbmNpZXMKICAgIG5hbWU6ICJJbnN0YWxsIERlcGVuZGVuY2llcyIKICAgIGNvbW1hbmQ6IHwKICAgICAgc3VkbyBhcHQtZ2V0IHVwZGF0ZSAmJiBzdWRvIGFwdC1nZXQgaW5zdGFsbCBzdWJ2ZXJzaW9uCiAgICAgIHN1ZG8gLUUgZG9ja2VyLXBocC1leHQtaW5zdGFsbCBteXNxbGkKICAgICAgc3VkbyBzaCAtYyAicHJpbnRmICdcbmRlYiBodHRwOi8vZnRwLnVzLmRlYmlhbi5vcmcvZGViaWFuIHNpZCBtYWluXG4nID4+IC9ldGMvYXB0L3NvdXJjZXMubGlzdCIKICAgICAgc3VkbyBhcHQtZ2V0IHVwZGF0ZSAmJiBzdWRvIGFwdC1nZXQgaW5zdGFsbCBteXNxbC1jbGllbnQtNS43CgogIHBocF9qb2I6ICZwaHBfam9iCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBXUF9URVNUU19ESVI6ICIvdG1wL3dvcmRwcmVzcy10ZXN0cy1saWIiCiAgICAgIC0gV1BfQ09SRV9ESVI6ICIvdG1wL3dvcmRwcmVzcy8iCiAgICBzdGVwczoKICAgICAgLSBjaGVja291dAogICAgICAtIHJ1bjogKnNldHVwX2Vudmlyb25tZW50CiAgICAgIC0gcnVuOiAqaW5zdGFsbF9kZXBlbmRlbmNpZXMKICAgICAgLSBydW46CiAgICAgICAgICBuYW1lOiAiUnVuIFRlc3RzIgogICAgICAgICAgY29tbWFuZDogfAogICAgICAgICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSAicGhwdW5pdC9waHB1bml0PTUuNy4qIgogICAgICAgICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSB3cC1jb2Rpbmctc3RhbmRhcmRzL3dwY3MKICAgICAgICAgICAgcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAkSE9NRS8uY29tcG9zZXIvdmVuZG9yL3dwLWNvZGluZy1zdGFuZGFyZHMvd3BjcwogICAgICAgICAgICBwaHBjcwogICAgICAgICAgICBybSAtcmYgJFdQX1RFU1RTX0RJUiAkV1BfQ09SRV9ESVIKICAgICAgICAgICAgYmFzaCBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCB3b3JkcHJlc3NfdGVzdCByb290ICcnIDEyNy4wLjAuMSBsYXRlc3QKICAgICAgICAgICAgcGhwdW5pdAogICAgICAgICAgICBXUF9NVUxUSVNJVEU9MSBwaHB1bml0Cgpqb2JzOgogIHBocDU2LWJ1aWxkOgogICAgPDw6ICpwaHBfam9iCiAgICBkb2NrZXI6CiAgICAgIC0gaW1hZ2U6IGNpcmNsZWNpL3BocDo1LjYKICAgICAgLSBpbWFnZTogKm15c3FsX2ltYWdlCiAgICBzdGVwczoKICAgICAgLSBjaGVja291dAogICAgICAtIHJ1bjogKnNldHVwX2Vudmlyb25tZW50CiAgICAgIC0gcnVuOiAqaW5zdGFsbF9kZXBlbmRlbmNpZXMKICAgICAgLSBydW46CiAgICAgICAgICBuYW1lOiAiUnVuIFRlc3RzIgogICAgICAgICAgY29tbWFuZDogfAogICAgICAgICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSAicGhwdW5pdC9waHB1bml0PTUuNy4qIgogICAgICAgICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSB3cC1jb2Rpbmctc3RhbmRhcmRzL3dwY3MKICAgICAgICAgICAgcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAkSE9NRS8uY29tcG9zZXIvdmVuZG9yL3dwLWNvZGluZy1zdGFuZGFyZHMvd3BjcwogICAgICAgICAgICBwaHBjcwogICAgICAgICAgICBTS0lQX0RCX0NSRUFURT1mYWxzZQogICAgICAgICAgICB7eyN3cF92ZXJzaW9uc190b190ZXN0fX0KICAgICAgICAgICAgcm0gLXJmICRXUF9URVNUU19ESVIgJFdQX0NPUkVfRElSCiAgICAgICAgICAgIGJhc2ggYmluL2luc3RhbGwtd3AtdGVzdHMuc2ggd29yZHByZXNzX3Rlc3Qgcm9vdCAnJyAxMjcuMC4wLjEge3sufX0gJFNLSVBfREJfQ1JFQVRFCiAgICAgICAgICAgIHBocHVuaXQKICAgICAgICAgICAgV1BfTVVMVElTSVRFPTEgcGhwdW5pdAogICAgICAgICAgICBTS0lQX0RCX0NSRUFURT10cnVlCiAgICAgICAgICAgIHt7L3dwX3ZlcnNpb25zX3RvX3Rlc3R9fQoKICBwaHA3MC1idWlsZDoKICAgIDw8OiAqcGhwX2pvYgogICAgZG9ja2VyOgogICAgICAtIGltYWdlOiBjaXJjbGVjaS9waHA6Ny4wCiAgICAgIC0gaW1hZ2U6ICpteXNxbF9pbWFnZQoKICBwaHA3MS1idWlsZDoKICAgIDw8OiAqcGhwX2pvYgogICAgZG9ja2VyOgogICAgICAtIGltYWdlOiBjaXJjbGVjaS9waHA6Ny4xCiAgICAgIC0gaW1hZ2U6ICpteXNxbF9pbWFnZQoKICBwaHA3Mi1idWlsZDoKICAgIDw8OiAqcGhwX2pvYgogICAgZG9ja2VyOgogICAgICAtIGltYWdlOiBjaXJjbGVjaS9waHA6Ny4yCiAgICAgIC0gaW1hZ2U6ICpteXNxbF9pbWFnZQoKICBwaHA3My1idWlsZDoKICAgIDw8OiAqcGhwX2pvYgogICAgZG9ja2VyOgogICAgICAtIGltYWdlOiBjaXJjbGVjaS9waHA6Ny4zCiAgICAgIC0gaW1hZ2U6ICpteXNxbF9pbWFnZQoKICBwaHA3NC1idWlsZDoKICAgIDw8OiAqcGhwX2pvYgogICAgZG9ja2VyOgogICAgICAtIGltYWdlOiBjaXJjbGVjaS9waHA6Ny40CiAgICAgIC0gaW1hZ2U6ICpteXNxbF9pbWFnZQojIEEgc2V0IG9mIGZpbGVzIHlvdSBwcm9iYWJseSBkb24ndCB3YW50IGluIHlvdXIgV29yZFByZXNzLm9yZyBkaXN0cmlidXRpb24KLmJhYmVscmMKLmRlcGxveWlnbm9yZQouZGlzdGlnbm9yZQouZWRpdG9yY29uZmlnCi5lc2xpbnRpZ25vcmUKLmVzbGludHJjCi5naXQKLmdpdGlnbm9yZQouZ2l0aHViCi5naXRsYWItY2kueW1sCi50cmF2aXMueW1sCi5EU19TdG9yZQpUaHVtYnMuZGIKYmVoYXQueW1sCmJpdGJ1Y2tldC1waXBlbGluZXMueW1sCmJpbgouY2lyY2xlY2kvY29uZmlnLnltbApjb21wb3Nlci5qc29uCmNvbXBvc2VyLmxvY2sKZGVwZW5kZW5jaWVzLnltbApHcnVudGZpbGUuanMKcGFja2FnZS5qc29uCnBhY2thZ2UtbG9jay5qc29uCnBocHVuaXQueG1sCnBocHVuaXQueG1sLmRpc3QKbXVsdGlzaXRlLnhtbAptdWx0aXNpdGUueG1sLmRpc3QKLnBocGNzLnhtbApwaHBjcy54bWwKLnBocGNzLnhtbC5kaXN0CnBocGNzLnhtbC5kaXN0ClJFQURNRS5tZAp3ZWJwYWNrLmNvbmZpZy5qcwp3cC1jbGkubG9jYWwueW1sCnlhcm4ubG9jawp0ZXN0cwp2ZW5kb3IKbm9kZV9tb2R1bGVzCiouc3FsCioudGFyLmd6CiouemlwCiggZnVuY3Rpb24oIHdwICkgewoJLyoqCgkgKiBSZWdpc3RlcnMgYSBuZXcgYmxvY2sgcHJvdmlkZWQgYSB1bmlxdWUgbmFtZSBhbmQgYW4gb2JqZWN0IGRlZmluaW5nIGl0cyBiZWhhdmlvci4KCSAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL2Jsb2NrLWFwaS8jcmVnaXN0ZXJpbmctYS1ibG9jawoJICovCgl2YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7CgkvKioKCSAqIFJldHVybnMgYSBuZXcgZWxlbWVudCBvZiBnaXZlbiB0eXBlLiBFbGVtZW50IGlzIGFuIGFic3RyYWN0aW9uIGxheWVyIGF0b3AgUmVhY3QuCgkgKiBAc2VlIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svZGVzaWduZXJzLWRldmVsb3BlcnMvZGV2ZWxvcGVycy9wYWNrYWdlcy9wYWNrYWdlcy1lbGVtZW50LwoJICovCgl2YXIgZWwgPSB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQ7CgkvKioKCSAqIFJldHJpZXZlcyB0aGUgdHJhbnNsYXRpb24gb2YgdGV4dC4KCSAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL3BhY2thZ2VzL3BhY2thZ2VzLWkxOG4vCgkgKi8KCXZhciBfXyA9IHdwLmkxOG4uX187CgoJLyoqCgkgKiBFdmVyeSBibG9jayBzdGFydHMgYnkgcmVnaXN0ZXJpbmcgYSBuZXcgYmxvY2sgdHlwZSBkZWZpbml0aW9uLgoJICogQHNlZSBodHRwczovL3dvcmRwcmVzcy5vcmcvZ3V0ZW5iZXJnL2hhbmRib29rL2Rlc2lnbmVycy1kZXZlbG9wZXJzL2RldmVsb3BlcnMvYmxvY2stYXBpLyNyZWdpc3RlcmluZy1hLWJsb2NrCgkgKi8KCXJlZ2lzdGVyQmxvY2tUeXBlKCAne3tuYW1lc3BhY2V9fS97e3NsdWd9fScsIHsKCQkvKioKCQkgKiBUaGlzIGlzIHRoZSBkaXNwbGF5IHRpdGxlIGZvciB5b3VyIGJsb2NrLCB3aGljaCBjYW4gYmUgdHJhbnNsYXRlZCB3aXRoIGBpMThuYCBmdW5jdGlvbnMuCgkJICogVGhlIGJsb2NrIGluc2VydGVyIHdpbGwgc2hvdyB0aGlzIG5hbWUuCgkJICovCgkJdGl0bGU6IF9fKCAne3t0aXRsZV91Y2ZpcnN0X2pzfX0nLCAne3tuYW1lc3BhY2V9fScgKSwKCgkJe3sjZGFzaGljb259fQoJCS8qKgoJCSAqIEFuIGljb24gcHJvcGVydHkgc2hvdWxkIGJlIHNwZWNpZmllZCB0byBtYWtlIGl0IGVhc2llciB0byBpZGVudGlmeSBhIGJsb2NrLgoJCSAqIFRoZXNlIGNhbiBiZSBhbnkgb2YgV29yZFByZXNz4oCZIERhc2hpY29ucywgb3IgYSBjdXN0b20gc3ZnIGVsZW1lbnQuCgkJICovCgkJaWNvbjogJ3t7ZGFzaGljb259fScsCgoJCXt7L2Rhc2hpY29ufX0KCQkvKioKCQkgKiBCbG9ja3MgYXJlIGdyb3VwZWQgaW50byBjYXRlZ29yaWVzIHRvIGhlbHAgdXNlcnMgYnJvd3NlIGFuZCBkaXNjb3ZlciB0aGVtLgoJCSAqIFRoZSBjYXRlZ29yaWVzIHByb3ZpZGVkIGJ5IGNvcmUgYXJlIGBjb21tb25gLCBgZW1iZWRgLCBgZm9ybWF0dGluZ2AsIGBsYXlvdXRgIGFuZCBgd2lkZ2V0c2AuCgkJICovCgkJY2F0ZWdvcnk6ICd7e2NhdGVnb3J5fX0nLAoKCQkvKioKCQkgKiBPcHRpb25hbCBibG9jayBleHRlbmRlZCBzdXBwb3J0IGZlYXR1cmVzLgoJCSAqLwoJCXN1cHBvcnRzOiB7CgkJCS8vIFJlbW92ZXMgc3VwcG9ydCBmb3IgYW4gSFRNTCBtb2RlLgoJCQlodG1sOiBmYWxzZSwKCQl9LAoKCQkvKioKCQkgKiBUaGUgZWRpdCBmdW5jdGlvbiBkZXNjcmliZXMgdGhlIHN0cnVjdHVyZSBvZiB5b3VyIGJsb2NrIGluIHRoZSBjb250ZXh0IG9mIHRoZSBlZGl0b3IuCgkJICogVGhpcyByZXByZXNlbnRzIHdoYXQgdGhlIGVkaXRvciB3aWxsIHJlbmRlciB3aGVuIHRoZSBibG9jayBpcyB1c2VkLgoJCSAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL2Jsb2NrLWFwaS9ibG9jay1lZGl0LXNhdmUvI2VkaXQKCQkgKgoJCSAqIEBwYXJhbSB7T2JqZWN0fSBbcHJvcHNdIFByb3BlcnRpZXMgcGFzc2VkIGZyb20gdGhlIGVkaXRvci4KCQkgKiBAcmV0dXJuIHtFbGVtZW50fSAgICAgICBFbGVtZW50IHRvIHJlbmRlci4KCQkgKi8KCQllZGl0OiBmdW5jdGlvbiggcHJvcHMgKSB7CgkJCXJldHVybiBlbCgKCQkJCSdwJywKCQkJCXsgY2xhc3NOYW1lOiBwcm9wcy5jbGFzc05hbWUgfSwKCQkJCV9fKCAnSGVsbG8gZnJvbSB0aGUgZWRpdG9yIScsICd7e25hbWVzcGFjZX19JyApCgkJCSk7CgkJfSwKCgkJLyoqCgkJICogVGhlIHNhdmUgZnVuY3Rpb24gZGVmaW5lcyB0aGUgd2F5IGluIHdoaWNoIHRoZSBkaWZmZXJlbnQgYXR0cmlidXRlcyBzaG91bGQgYmUgY29tYmluZWQKCQkgKiBpbnRvIHRoZSBmaW5hbCBtYXJrdXAsIHdoaWNoIGlzIHRoZW4gc2VyaWFsaXplZCBieSBHdXRlbmJlcmcgaW50byBgcG9zdF9jb250ZW50YC4KCQkgKiBAc2VlIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svZGVzaWduZXJzLWRldmVsb3BlcnMvZGV2ZWxvcGVycy9ibG9jay1hcGkvYmxvY2stZWRpdC1zYXZlLyNzYXZlCgkJICoKCQkgKiBAcmV0dXJuIHtFbGVtZW50fSAgICAgICBFbGVtZW50IHRvIHJlbmRlci4KCQkgKi8KCQlzYXZlOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIGVsKAoJCQkJJ3AnLAoJCQkJe30sCgkJCQlfXyggJ0hlbGxvIGZyb20gdGhlIHNhdmVkIGNvbnRlbnQhJywgJ3t7bmFtZXNwYWNlfX0nICkKCQkJKTsKCQl9Cgl9ICk7Cn0gKSgKCXdpbmRvdy53cAopOwpwaXBlbGluZXM6CiAgZGVmYXVsdDoKICAgIC0gc3RlcDoKICAgICAgICBpbWFnZTogcGhwOjUuNgogICAgICAgIG5hbWU6ICJQSFAgNS42IgogICAgICAgIHNjcmlwdDoKICAgICAgICAgICMgSW5zdGFsbCBEZXBlbmRlbmNpZXMKICAgICAgICAgIC0gZG9ja2VyLXBocC1leHQtaW5zdGFsbCBteXNxbGkKICAgICAgICAgIC0gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IHN1YnZlcnNpb24gLS1uby1pbnN0YWxsLXJlY29tbWVuZHMKCiAgICAgICAgICAjIEluc3RhbGwgUEhQQ1MKICAgICAgICAgIC0gY3VybCAtbyAvdXNyL2xvY2FsL2Jpbi9waHBjcyAtZlNMIGh0dHBzOi8vc3F1aXpsYWJzLmdpdGh1Yi5pby9QSFBfQ29kZVNuaWZmZXIvcGhwY3MucGhhciAmJiBjaG1vZCAreCAvdXNyL2xvY2FsL2Jpbi9waHBjcwogICAgICAgICAgLSBwaHBjcyAtLXZlcnNpb24KCiAgICAgICAgICAjIEluc3RhbGwgV29yZFByZXNzIENvZGluZyBTdGFuZGFyZHMKICAgICAgICAgIC0gV1BDU19WRVJTSU9OPTAuMTQuMQogICAgICAgICAgLSBjdXJsIC1vIHdwY3MudGFyLmd6IC1mU0wgImh0dHBzOi8vZ2l0aHViLmNvbS9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9hcmNoaXZlLyR7V1BDU19WRVJTSU9OfS50YXIuZ3oiCiAgICAgICAgICAtIG1rZGlyIC1wIC92YXIvd3BjcyAmJiB0YXIgLXh6ZiB3cGNzLnRhci5neiAtLWRpcmVjdG9yeSAvdmFyL3dwY3MgLS1zdHJpcC1jb21wb25lbnRzIDEgJiYgcm0gd3Bjcy50YXIuZ3oKICAgICAgICAgIC0gcGhwY3MgLS1jb25maWctc2V0IHNob3dfcHJvZ3Jlc3MgMSAmJiBwaHBjcyAtLWNvbmZpZy1zZXQgY29sb3JzIDEgJiYgcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAvdmFyL3dwY3MKCiAgICAgICAgICAjIyBSdW4gUEhQQ1MKICAgICAgICAgIC0gcGhwY3MKCiAgICAgICAgICAjIEluc3RhbGwgUEhQVW5pdAogICAgICAgICAgLSBQSFBVTklUX1ZFUlNJT049NS43LjI3CiAgICAgICAgICAtIGN1cmwgLW8gL3Vzci9sb2NhbC9iaW4vcGhwdW5pdCAiaHR0cHM6Ly9waGFyLnBocHVuaXQuZGUvcGhwdW5pdC0ke1BIUFVOSVRfVkVSU0lPTn0ucGhhciIgJiYgY2htb2QgK3ggL3Vzci9sb2NhbC9iaW4vcGhwdW5pdAogICAgICAgICAgLSBwaHB1bml0IC0tdmVyc2lvbgoKICAgICAgICAgICMjIFJ1biBQSFBVbml0CiAgICAgICAgICAtIGJhc2ggYmluL2luc3RhbGwtd3AtdGVzdHMuc2ggd29yZHByZXNzX3Rlc3RzIHJvb3Qgcm9vdCAxMjcuMC4wLjEgbGF0ZXN0IHRydWUKICAgICAgICAgIC0gcGhwdW5pdAogICAgICAgIHNlcnZpY2VzOgogICAgICAgICAgLSBkYXRhYmFzZQoKICAgIC0gc3RlcDoKICAgICAgICBpbWFnZTogcGhwOjcuMAogICAgICAgIG5hbWU6ICJQSFAgNy4wIgogICAgICAgIHNjcmlwdDoKICAgICAgICAgICMgSW5zdGFsbCBEZXBlbmRlbmNpZXMKICAgICAgICAgIC0gZG9ja2VyLXBocC1leHQtaW5zdGFsbCBteXNxbGkKICAgICAgICAgIC0gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IHN1YnZlcnNpb24gLS1uby1pbnN0YWxsLXJlY29tbWVuZHMKCiAgICAgICAgICAjIEluc3RhbGwgUEhQQ1MKICAgICAgICAgIC0gY3VybCAtbyAvdXNyL2xvY2FsL2Jpbi9waHBjcyAtZlNMIGh0dHBzOi8vc3F1aXpsYWJzLmdpdGh1Yi5pby9QSFBfQ29kZVNuaWZmZXIvcGhwY3MucGhhciAmJiBjaG1vZCAreCAvdXNyL2xvY2FsL2Jpbi9waHBjcwogICAgICAgICAgLSBwaHBjcyAtLXZlcnNpb24KCiAgICAgICAgICAjIEluc3RhbGwgV29yZFByZXNzIENvZGluZyBTdGFuZGFyZHMKICAgICAgICAgIC0gV1BDU19WRVJTSU9OPTAuMTQuMQogICAgICAgICAgLSBjdXJsIC1vIHdwY3MudGFyLmd6IC1mU0wgImh0dHBzOi8vZ2l0aHViLmNvbS9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9hcmNoaXZlLyR7V1BDU19WRVJTSU9OfS50YXIuZ3oiCiAgICAgICAgICAtIG1rZGlyIC1wIC92YXIvd3BjcyAmJiB0YXIgLXh6ZiB3cGNzLnRhci5neiAtLWRpcmVjdG9yeSAvdmFyL3dwY3MgLS1zdHJpcC1jb21wb25lbnRzIDEgJiYgcm0gd3Bjcy50YXIuZ3oKICAgICAgICAgIC0gcGhwY3MgLS1jb25maWctc2V0IHNob3dfcHJvZ3Jlc3MgMSAmJiBwaHBjcyAtLWNvbmZpZy1zZXQgY29sb3JzIDEgJiYgcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAvdmFyL3dwY3MKCiAgICAgICAgICAjIyBSdW4gUEhQQ1MKICAgICAgICAgIC0gcGhwY3MKCiAgICAgICAgICAjIEluc3RhbGwgUEhQVW5pdAogICAgICAgICAgLSBQSFBVTklUX1ZFUlNJT049Ni41LjYKICAgICAgICAgIC0gY3VybCAtbyAvdXNyL2xvY2FsL2Jpbi9waHB1bml0ICJodHRwczovL3BoYXIucGhwdW5pdC5kZS9waHB1bml0LSR7UEhQVU5JVF9WRVJTSU9OfS5waGFyIiAmJiBjaG1vZCAreCAvdXNyL2xvY2FsL2Jpbi9waHB1bml0CiAgICAgICAgICAtIHBocHVuaXQgLS12ZXJzaW9uCgogICAgICAgICAgIyMgUnVuIFBIUFVuaXQKICAgICAgICAgIC0gYmFzaCBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCB3b3JkcHJlc3NfdGVzdHMgcm9vdCByb290IDEyNy4wLjAuMSBsYXRlc3QgdHJ1ZQogICAgICAgICAgLSBwaHB1bml0CiAgICAgICAgc2VydmljZXM6CiAgICAgICAgICAtIGRhdGFiYXNlCgogICAgLSBzdGVwOgogICAgICAgIGltYWdlOiBwaHA6Ny4xCiAgICAgICAgbmFtZTogIlBIUCA3LjEiCiAgICAgICAgc2NyaXB0OgogICAgICAgICAgIyBJbnN0YWxsIERlcGVuZGVuY2llcwogICAgICAgICAgLSBkb2NrZXItcGhwLWV4dC1pbnN0YWxsIG15c3FsaQogICAgICAgICAgLSBhcHQtZ2V0IHVwZGF0ZSAmJiBhcHQtZ2V0IGluc3RhbGwgLXkgc3VidmVyc2lvbiAtLW5vLWluc3RhbGwtcmVjb21tZW5kcwoKICAgICAgICAgICMgSW5zdGFsbCBQSFBDUwogICAgICAgICAgLSBjdXJsIC1vIC91c3IvbG9jYWwvYmluL3BocGNzIC1mU0wgaHR0cHM6Ly9zcXVpemxhYnMuZ2l0aHViLmlvL1BIUF9Db2RlU25pZmZlci9waHBjcy5waGFyICYmIGNobW9kICt4IC91c3IvbG9jYWwvYmluL3BocGNzCiAgICAgICAgICAtIHBocGNzIC0tdmVyc2lvbgoKICAgICAgICAgICMgSW5zdGFsbCBXb3JkUHJlc3MgQ29kaW5nIFN0YW5kYXJkcwogICAgICAgICAgLSBXUENTX1ZFUlNJT049MC4xNC4xCiAgICAgICAgICAtIGN1cmwgLW8gd3Bjcy50YXIuZ3ogLWZTTCAiaHR0cHM6Ly9naXRodWIuY29tL1dvcmRQcmVzcy1Db2RpbmctU3RhbmRhcmRzL1dvcmRQcmVzcy1Db2RpbmctU3RhbmRhcmRzL2FyY2hpdmUvJHtXUENTX1ZFUlNJT059LnRhci5neiIKICAgICAgICAgIC0gbWtkaXIgLXAgL3Zhci93cGNzICYmIHRhciAteHpmIHdwY3MudGFyLmd6IC0tZGlyZWN0b3J5IC92YXIvd3BjcyAtLXN0cmlwLWNvbXBvbmVudHMgMSAmJiBybSB3cGNzLnRhci5negogICAgICAgICAgLSBwaHBjcyAtLWNvbmZpZy1zZXQgc2hvd19wcm9ncmVzcyAxICYmIHBocGNzIC0tY29uZmlnLXNldCBjb2xvcnMgMSAmJiBwaHBjcyAtLWNvbmZpZy1zZXQgaW5zdGFsbGVkX3BhdGhzIC92YXIvd3BjcwoKICAgICAgICAgICMjIFJ1biBQSFBDUwogICAgICAgICAgLSBwaHBjcwoKICAgICAgICAgICMgSW5zdGFsbCBQSFBVbml0CiAgICAgICAgICAtIFBIUFVOSVRfVkVSU0lPTj02LjUuNgogICAgICAgICAgLSBjdXJsIC1vIC91c3IvbG9jYWwvYmluL3BocHVuaXQgImh0dHBzOi8vcGhhci5waHB1bml0LmRlL3BocHVuaXQtJHtQSFBVTklUX1ZFUlNJT059LnBoYXIiICYmIGNobW9kICt4IC91c3IvbG9jYWwvYmluL3BocHVuaXQKICAgICAgICAgIC0gcGhwdW5pdCAtLXZlcnNpb24KCiAgICAgICAgICAjIyBSdW4gUEhQVW5pdAogICAgICAgICAgLSBiYXNoIGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoIHdvcmRwcmVzc190ZXN0cyByb290IHJvb3QgMTI3LjAuMC4xIGxhdGVzdCB0cnVlCiAgICAgICAgICAtIHBocHVuaXQKICAgICAgICBzZXJ2aWNlczoKICAgICAgICAgIC0gZGF0YWJhc2UKCiAgICAtIHN0ZXA6CiAgICAgICAgaW1hZ2U6IHBocDo3LjIKICAgICAgICBuYW1lOiAiUEhQIDcuMiIKICAgICAgICBzY3JpcHQ6CiAgICAgICAgICAjIEluc3RhbGwgRGVwZW5kZW5jaWVzCiAgICAgICAgICAtIGRvY2tlci1waHAtZXh0LWluc3RhbGwgbXlzcWxpCiAgICAgICAgICAtIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBzdWJ2ZXJzaW9uIC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzCgogICAgICAgICAgIyBJbnN0YWxsIFBIUENTCiAgICAgICAgICAtIGN1cmwgLW8gL3Vzci9sb2NhbC9iaW4vcGhwY3MgLWZTTCBodHRwczovL3NxdWl6bGFicy5naXRodWIuaW8vUEhQX0NvZGVTbmlmZmVyL3BocGNzLnBoYXIgJiYgY2htb2QgK3ggL3Vzci9sb2NhbC9iaW4vcGhwY3MKICAgICAgICAgIC0gcGhwY3MgLS12ZXJzaW9uCgogICAgICAgICAgIyBJbnN0YWxsIFdvcmRQcmVzcyBDb2RpbmcgU3RhbmRhcmRzCiAgICAgICAgICAtIFdQQ1NfVkVSU0lPTj0wLjE0LjEKICAgICAgICAgIC0gY3VybCAtbyB3cGNzLnRhci5neiAtZlNMICJodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvYXJjaGl2ZS8ke1dQQ1NfVkVSU0lPTn0udGFyLmd6IgogICAgICAgICAgLSBta2RpciAtcCAvdmFyL3dwY3MgJiYgdGFyIC14emYgd3Bjcy50YXIuZ3ogLS1kaXJlY3RvcnkgL3Zhci93cGNzIC0tc3RyaXAtY29tcG9uZW50cyAxICYmIHJtIHdwY3MudGFyLmd6CiAgICAgICAgICAtIHBocGNzIC0tY29uZmlnLXNldCBzaG93X3Byb2dyZXNzIDEgJiYgcGhwY3MgLS1jb25maWctc2V0IGNvbG9ycyAxICYmIHBocGNzIC0tY29uZmlnLXNldCBpbnN0YWxsZWRfcGF0aHMgL3Zhci93cGNzCgogICAgICAgICAgIyMgUnVuIFBIUENTCiAgICAgICAgICAtIHBocGNzCgogICAgICAgICAgIyBJbnN0YWxsIFBIUFVuaXQKICAgICAgICAgIC0gUEhQVU5JVF9WRVJTSU9OPTYuNS42CiAgICAgICAgICAtIGN1cmwgLW8gL3Vzci9sb2NhbC9iaW4vcGhwdW5pdCAiaHR0cHM6Ly9waGFyLnBocHVuaXQuZGUvcGhwdW5pdC0ke1BIUFVOSVRfVkVSU0lPTn0ucGhhciIgJiYgY2htb2QgK3ggL3Vzci9sb2NhbC9iaW4vcGhwdW5pdAogICAgICAgICAgLSBwaHB1bml0IC0tdmVyc2lvbgoKICAgICAgICAgICMjIFJ1biBQSFBVbml0CiAgICAgICAgICAtIGJhc2ggYmluL2luc3RhbGwtd3AtdGVzdHMuc2ggd29yZHByZXNzX3Rlc3RzIHJvb3Qgcm9vdCAxMjcuMC4wLjEgbGF0ZXN0IHRydWUKICAgICAgICAgIC0gcGhwdW5pdAogICAgICAgIHNlcnZpY2VzOgogICAgICAgICAgLSBkYXRhYmFzZQoKZGVmaW5pdGlvbnM6CiAgc2VydmljZXM6CiAgICBkYXRhYmFzZToKICAgICAgaW1hZ2U6IG15c3FsOmxhdGVzdAogICAgICBlbnZpcm9ubWVudDoKICAgICAgICBNWVNRTF9EQVRBQkFTRTogJ3dvcmRwcmVzc190ZXN0cycKICAgICAgICBNWVNRTF9ST09UX1BBU1NXT1JEOiAncm9vdCcKPD9waHAKCi8qKgogKiBSZWdpc3RlcnMgdGhlIGB7e21hY2hpbmVfbmFtZX19YCBwb3N0IHR5cGUuCiAqLwpmdW5jdGlvbiB7e21hY2hpbmVfbmFtZX19X2luaXQoKSB7Cnt7b3V0cHV0fX0KfQoKYWRkX2FjdGlvbiggJ2luaXQnLCAne3ttYWNoaW5lX25hbWV9fV9pbml0JyApOwoKLyoqCiAqIFNldHMgdGhlIHBvc3QgdXBkYXRlZCBtZXNzYWdlcyBmb3IgdGhlIGB7e21hY2hpbmVfbmFtZX19YCBwb3N0IHR5cGUuCiAqCiAqIEBwYXJhbSAgYXJyYXkgJG1lc3NhZ2VzIFBvc3QgdXBkYXRlZCBtZXNzYWdlcy4KICogQHJldHVybiBhcnJheSBNZXNzYWdlcyBmb3IgdGhlIGB7e21hY2hpbmVfbmFtZX19YCBwb3N0IHR5cGUuCiAqLwpmdW5jdGlvbiB7e21hY2hpbmVfbmFtZX19X3VwZGF0ZWRfbWVzc2FnZXMoICRtZXNzYWdlcyApIHsKCWdsb2JhbCAkcG9zdDsKCgkkcGVybWFsaW5rID0gZ2V0X3Blcm1hbGluayggJHBvc3QgKTsKCgkkbWVzc2FnZXNbJ3t7c2x1Z319J10gPSBbCgkJMCAgPT4gJycsIC8vIFVudXNlZC4gTWVzc2FnZXMgc3RhcnQgYXQgaW5kZXggMS4KCQkvKiB0cmFuc2xhdG9yczogJXM6IHBvc3QgcGVybWFsaW5rICovCgkJMSAgPT4gc3ByaW50ZiggX18oICd7e2xhYmVsX3VjZmlyc3R9fSB1cGRhdGVkLiA8YSB0YXJnZXQ9Il9ibGFuayIgaHJlZj0iJXMiPlZpZXcge3tsYWJlbH19PC9hPicsICd7e3RleHRkb21haW59fScgKSwgZXNjX3VybCggJHBlcm1hbGluayApICksCgkJMiAgPT4gX18oICdDdXN0b20gZmllbGQgdXBkYXRlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJMyAgPT4gX18oICdDdXN0b20gZmllbGQgZGVsZXRlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJNCAgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSB1cGRhdGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQkvKiB0cmFuc2xhdG9yczogJXM6IGRhdGUgYW5kIHRpbWUgb2YgdGhlIHJldmlzaW9uICovCgkJNSAgPT4gaXNzZXQoICRfR0VUWydyZXZpc2lvbiddICkgPyBzcHJpbnRmKCBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IHJlc3RvcmVkIHRvIHJldmlzaW9uIGZyb20gJXMnLCAne3t0ZXh0ZG9tYWlufX0nICksIHdwX3Bvc3RfcmV2aXNpb25fdGl0bGUoIChpbnQpICRfR0VUWydyZXZpc2lvbiddLCBmYWxzZSApICkgOiBmYWxzZSwgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5TZWN1cml0eS5Ob25jZVZlcmlmaWNhdGlvbi5SZWNvbW1lbmRlZAoJCS8qIHRyYW5zbGF0b3JzOiAlczogcG9zdCBwZXJtYWxpbmsgKi8KCQk2ICA9PiBzcHJpbnRmKCBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IHB1Ymxpc2hlZC4gPGEgaHJlZj0iJXMiPlZpZXcge3tsYWJlbH19PC9hPicsICd7e3RleHRkb21haW59fScgKSwgZXNjX3VybCggJHBlcm1hbGluayApICksCgkJNyAgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSBzYXZlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJLyogdHJhbnNsYXRvcnM6ICVzOiBwb3N0IHBlcm1hbGluayAqLwoJCTggID0+IHNwcmludGYoIF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gc3VibWl0dGVkLiA8YSB0YXJnZXQ9Il9ibGFuayIgaHJlZj0iJXMiPlByZXZpZXcge3tsYWJlbH19PC9hPicsICd7e3RleHRkb21haW59fScgKSwgZXNjX3VybCggYWRkX3F1ZXJ5X2FyZyggJ3ByZXZpZXcnLCAndHJ1ZScsICRwZXJtYWxpbmsgKSApICksCgkJLyogdHJhbnNsYXRvcnM6IDE6IFB1Ymxpc2ggYm94IGRhdGUgZm9ybWF0LCBzZWUgaHR0cHM6Ly9zZWN1cmUucGhwLm5ldC9kYXRlIDI6IFBvc3QgcGVybWFsaW5rICovCgkJOSAgPT4gc3ByaW50ZiggX18oICd7e2xhYmVsX3VjZmlyc3R9fSBzY2hlZHVsZWQgZm9yOiA8c3Ryb25nPiUxJHM8L3N0cm9uZz4uIDxhIHRhcmdldD0iX2JsYW5rIiBocmVmPSIlMiRzIj5QcmV2aWV3IHt7bGFiZWx9fTwvYT4nLCAne3t0ZXh0ZG9tYWlufX0nICksIGRhdGVfaTE4biggX18oICdNIGosIFkgQCBHOmknLCAne3t0ZXh0ZG9tYWlufX0nICksIHN0cnRvdGltZSggJHBvc3QtPnBvc3RfZGF0ZSApICksIGVzY191cmwoICRwZXJtYWxpbmsgKSApLAoJCS8qIHRyYW5zbGF0b3JzOiAlczogcG9zdCBwZXJtYWxpbmsgKi8KCQkxMCA9PiBzcHJpbnRmKCBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IGRyYWZ0IHVwZGF0ZWQuIDxhIHRhcmdldD0iX2JsYW5rIiBocmVmPSIlcyI+UHJldmlldyB7e2xhYmVsfX08L2E+JywgJ3t7dGV4dGRvbWFpbn19JyApLCBlc2NfdXJsKCBhZGRfcXVlcnlfYXJnKCAncHJldmlldycsICd0cnVlJywgJHBlcm1hbGluayApICkgKSwKCV07CgoJcmV0dXJuICRtZXNzYWdlczsKfQoKYWRkX2ZpbHRlciggJ3Bvc3RfdXBkYXRlZF9tZXNzYWdlcycsICd7e21hY2hpbmVfbmFtZX19X3VwZGF0ZWRfbWVzc2FnZXMnICk7CgovKioKICogU2V0cyB0aGUgYnVsayBwb3N0IHVwZGF0ZWQgbWVzc2FnZXMgZm9yIHRoZSBge3ttYWNoaW5lX25hbWV9fWAgcG9zdCB0eXBlLgogKgogKiBAcGFyYW0gIGFycmF5ICRidWxrX21lc3NhZ2VzIEFycmF5cyBvZiBtZXNzYWdlcywgZWFjaCBrZXllZCBieSB0aGUgY29ycmVzcG9uZGluZyBwb3N0IHR5cGUuIE1lc3NhZ2VzIGFyZQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleWVkIHdpdGggJ3VwZGF0ZWQnLCAnbG9ja2VkJywgJ2RlbGV0ZWQnLCAndHJhc2hlZCcsIGFuZCAndW50cmFzaGVkJy4KICogQHBhcmFtICBpbnRbXSAkYnVsa19jb3VudHMgICBBcnJheSBvZiBpdGVtIGNvdW50cyBmb3IgZWFjaCBtZXNzYWdlLCB1c2VkIHRvIGJ1aWxkIGludGVybmF0aW9uYWxpemVkIHN0cmluZ3MuCiAqIEByZXR1cm4gYXJyYXkgQnVsayBtZXNzYWdlcyBmb3IgdGhlIGB7e21hY2hpbmVfbmFtZX19YCBwb3N0IHR5cGUuCiAqLwpmdW5jdGlvbiB7e21hY2hpbmVfbmFtZX19X2J1bGtfdXBkYXRlZF9tZXNzYWdlcyggJGJ1bGtfbWVzc2FnZXMsICRidWxrX2NvdW50cyApIHsKCWdsb2JhbCAkcG9zdDsKCgkkYnVsa19tZXNzYWdlc1sne3tzbHVnfX0nXSA9IFsKCQkvKiB0cmFuc2xhdG9yczogJXM6IE51bWJlciBvZiB7e2xhYmVsX3BsdXJhbH19LiAqLwoJCSd1cGRhdGVkJyAgID0+IF9uKCAnJXMge3tsYWJlbH19IHVwZGF0ZWQuJywgJyVzIHt7bGFiZWxfcGx1cmFsfX0gdXBkYXRlZC4nLCAkYnVsa19jb3VudHNbJ3VwZGF0ZWQnXSwgJ3t7dGV4dGRvbWFpbn19JyApLAoJCSdsb2NrZWQnICAgID0+ICggMSA9PT0gJGJ1bGtfY291bnRzWydsb2NrZWQnXSApID8gX18oICcxIHt7bGFiZWx9fSBub3QgdXBkYXRlZCwgc29tZWJvZHkgaXMgZWRpdGluZyBpdC4nLCAne3t0ZXh0ZG9tYWlufX0nICkgOgoJCQkJCQkvKiB0cmFuc2xhdG9yczogJXM6IE51bWJlciBvZiB7e2xhYmVsX3BsdXJhbH19LiAqLwoJCQkJCQlfbiggJyVzIHt7bGFiZWx9fSBub3QgdXBkYXRlZCwgc29tZWJvZHkgaXMgZWRpdGluZyBpdC4nLCAnJXMge3tsYWJlbF9wbHVyYWx9fSBub3QgdXBkYXRlZCwgc29tZWJvZHkgaXMgZWRpdGluZyB0aGVtLicsICRidWxrX2NvdW50c1snbG9ja2VkJ10sICd7e3RleHRkb21haW59fScgKSwKCQkvKiB0cmFuc2xhdG9yczogJXM6IE51bWJlciBvZiB7e2xhYmVsX3BsdXJhbH19LiAqLwoJCSdkZWxldGVkJyAgID0+IF9uKCAnJXMge3tsYWJlbH19IHBlcm1hbmVudGx5IGRlbGV0ZWQuJywgJyVzIHt7bGFiZWxfcGx1cmFsfX0gcGVybWFuZW50bHkgZGVsZXRlZC4nLCAkYnVsa19jb3VudHNbJ2RlbGV0ZWQnXSwgJ3t7dGV4dGRvbWFpbn19JyApLAoJCS8qIHRyYW5zbGF0b3JzOiAlczogTnVtYmVyIG9mIHt7bGFiZWxfcGx1cmFsfX0uICovCgkJJ3RyYXNoZWQnICAgPT4gX24oICclcyB7e2xhYmVsfX0gbW92ZWQgdG8gdGhlIFRyYXNoLicsICclcyB7e2xhYmVsX3BsdXJhbH19IG1vdmVkIHRvIHRoZSBUcmFzaC4nLCAkYnVsa19jb3VudHNbJ3RyYXNoZWQnXSwgJ3t7dGV4dGRvbWFpbn19JyApLAoJCS8qIHRyYW5zbGF0b3JzOiAlczogTnVtYmVyIG9mIHt7bGFiZWxfcGx1cmFsfX0uICovCgkJJ3VudHJhc2hlZCcgPT4gX24oICclcyB7e2xhYmVsfX0gcmVzdG9yZWQgZnJvbSB0aGUgVHJhc2guJywgJyVzIHt7bGFiZWxfcGx1cmFsfX0gcmVzdG9yZWQgZnJvbSB0aGUgVHJhc2guJywgJGJ1bGtfY291bnRzWyd1bnRyYXNoZWQnXSwgJ3t7dGV4dGRvbWFpbn19JyApLAoJXTsKCglyZXR1cm4gJGJ1bGtfbWVzc2FnZXM7Cn0KCmFkZF9maWx0ZXIoICdidWxrX3Bvc3RfdXBkYXRlZF9tZXNzYWdlcycsICd7e21hY2hpbmVfbmFtZX19X2J1bGtfdXBkYXRlZF9tZXNzYWdlcycsIDEwLCAyICk7Cjw/cGhwCi8qKgogKiBQSFBVbml0IGJvb3RzdHJhcCBmaWxlLgogKgogKiBAcGFja2FnZSB7e3BsdWdpbl9wYWNrYWdlfX0KICovCgokX3Rlc3RzX2RpciA9IGdldGVudiggJ1dQX1RFU1RTX0RJUicgKTsKCmlmICggISAkX3Rlc3RzX2RpciApIHsKCSRfdGVzdHNfZGlyID0gcnRyaW0oIHN5c19nZXRfdGVtcF9kaXIoKSwgJy9cXCcgKSAuICcvd29yZHByZXNzLXRlc3RzLWxpYic7Cn0KCi8vIEZvcndhcmQgY3VzdG9tIFBIUFVuaXQgUG9seWZpbGxzIGNvbmZpZ3VyYXRpb24gdG8gUEhQVW5pdCBib290c3RyYXAgZmlsZS4KJF9waHB1bml0X3BvbHlmaWxsc19wYXRoID0gZ2V0ZW52KCAnV1BfVEVTVFNfUEhQVU5JVF9QT0xZRklMTFNfUEFUSCcgKTsKaWYgKCBmYWxzZSAhPT0gJF9waHB1bml0X3BvbHlmaWxsc19wYXRoICkgewoJZGVmaW5lKCAnV1BfVEVTVFNfUEhQVU5JVF9QT0xZRklMTFNfUEFUSCcsICRfcGhwdW5pdF9wb2x5ZmlsbHNfcGF0aCApOwp9CgppZiAoICEgZmlsZV9leGlzdHMoICJ7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAiICkgKSB7CgllY2hvICJDb3VsZCBub3QgZmluZCB7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAsIGhhdmUgeW91IHJ1biBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCA/IiAuIFBIUF9FT0w7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuU2VjdXJpdHkuRXNjYXBlT3V0cHV0Lk91dHB1dE5vdEVzY2FwZWQKCWV4aXQoIDEgKTsKfQoKLy8gR2l2ZSBhY2Nlc3MgdG8gdGVzdHNfYWRkX2ZpbHRlcigpIGZ1bmN0aW9uLgpyZXF1aXJlX29uY2UgInskX3Rlc3RzX2Rpcn0vaW5jbHVkZXMvZnVuY3Rpb25zLnBocCI7CgovKioKICogTWFudWFsbHkgbG9hZCB0aGUgcGx1Z2luIGJlaW5nIHRlc3RlZC4KICovCmZ1bmN0aW9uIF9tYW51YWxseV9sb2FkX3BsdWdpbigpIHsKCXJlcXVpcmUgZGlybmFtZSggZGlybmFtZSggX19GSUxFX18gKSApIC4gJy97e3BsdWdpbl9zbHVnfX0ucGhwJzsKfQoKdGVzdHNfYWRkX2ZpbHRlciggJ211cGx1Z2luc19sb2FkZWQnLCAnX21hbnVhbGx5X2xvYWRfcGx1Z2luJyApOwoKLy8gU3RhcnQgdXAgdGhlIFdQIHRlc3RpbmcgZW52aXJvbm1lbnQuCnJlcXVpcmUgInskX3Rlc3RzX2Rpcn0vaW5jbHVkZXMvYm9vdHN0cmFwLnBocCI7CnZhcmlhYmxlczoKICAjIENvbmZpZ3VyZSBteXNxbCBzZXJ2aWNlIChodHRwczovL2h1Yi5kb2NrZXIuY29tL18vbXlzcWwvKQogIE1ZU1FMX0RBVEFCQVNFOiB3b3JkcHJlc3NfdGVzdHMKICBNWVNRTF9ST09UX1BBU1NXT1JEOiBteXNxbAoKYmVmb3JlX3NjcmlwdDoKICAjIEluc3RhbGwgZGVwZW5kZW5jaWVzCiAgCiAgIyB1cGRhdGUgdGhlIGRvY2tlcgogIC0gYXB0LWdldCBjbGVhbgogIC0gYXB0LWdldCAteXFxIHVwZGF0ZQoKICAjIGluc3RsbCB0aGUgcmVxdWlyZWQgcGFja2FnZXMgZm9yIHRoZSBydW5uaW5nIENJIHRlc3RzCiAgLSBhcHQtZ2V0IC15cXFmIGluc3RhbGwgemlwIHVuemlwIHN1YnZlcnNpb24gbXlzcWwtY2xpZW50IGxpYm15c3FsY2xpZW50LWRldiAtLWZpeC1taXNzaW5nCgogICMgUEhQIGV4dGVuc2lvbnMKICAtIGRvY2tlci1waHAtZXh0LWVuYWJsZSBtYnN0cmluZyBtY3J5cHQgbXlzcWxpIHBkb19teXNxbCBpbnRsIGdkIHppcCBiejIKCiAgIyBTZXQgdXAgV29yZFByZXNzIHRlc3RzCiAgLSBiYXNoIGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoIHdvcmRwcmVzc190ZXN0cyByb290IG15c3FsIG15c3FsIGxhdGVzdCB0cnVlCgogICMgSW5zdGFsbCBQSFBDUyBhbmQgV1BDUwogIC0gY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgInNxdWl6bGFicy9waHBfY29kZXNuaWZmZXI9KiIKICAtIGNvbXBvc2VyIGdsb2JhbCByZXF1aXJlICJ3cC1jb2Rpbmctc3RhbmRhcmRzL3dwY3MiCiAgLSBwaHBjcyAtLWNvbmZpZy1zZXQgaW5zdGFsbGVkX3BhdGhzICRIT01FLy5jb21wb3Nlci92ZW5kb3Ivd3AtY29kaW5nLXN0YW5kYXJkcy93cGNzCgpQSFB1bml0OlBIUDUuMzpNeVNRTDoKICBpbWFnZTogdGV0cmF3ZWIvcGhwOjUuMwogIHNlcnZpY2VzOgogICAgLSBteXNxbDo1LjYKICBzY3JpcHQ6CiAgLSBwaHBjcwogIC0gcGhwdW5pdAoKUEhQdW5pdDpQSFA1LjY6TXlTUUw6CiAgaW1hZ2U6IHRldHJhd2ViL3BocDo1LjYKICBzZXJ2aWNlczoKICAgIC0gbXlzcWw6NS42CiAgc2NyaXB0OgogIC0gcGhwY3MKICAtIHBocHVuaXQKICAKUEhQdW5pdDpQSFA3LjA6TXlTUUw6CiAgaW1hZ2U6IHRldHJhd2ViL3BocDo3LjAKICBzZXJ2aWNlczoKICAgIC0gbXlzcWw6NS42CiAgc2NyaXB0OgogIC0gcGhwY3MKICAtIHBocHVuaXQKClBIUHVuaXQ6UEhQNy4xOk15U1FMOgogIGltYWdlOiB0ZXRyYXdlYi9waHA6Ny4xCiAgc2VydmljZXM6CiAgICAtIG15c3FsOjUuNgogIHNjcmlwdDoKICAtIHBocGNzCiAgLSBwaHB1bml0CgpQSFB1bml0OlBIUDcuMjpNeVNRTDoKICBpbWFnZTogdGV0cmF3ZWIvcGhwOjcuMgogIHNlcnZpY2VzOgogICAgLSBteXNxbDo1LjYKICBzY3JpcHQ6CiAgLSBwaHBjcwogIC0gcGhwdW5pdAojIS91c3IvYmluL2VudiBiYXNoCgppZiBbICQjIC1sdCAzIF07IHRoZW4KCWVjaG8gInVzYWdlOiAkMCA8ZGItbmFtZT4gPGRiLXVzZXI+IDxkYi1wYXNzPiBbZGItaG9zdF0gW3dwLXZlcnNpb25dIFtza2lwLWRhdGFiYXNlLWNyZWF0aW9uXSIKCWV4aXQgMQpmaQoKREJfTkFNRT0kMQpEQl9VU0VSPSQyCkRCX1BBU1M9JDMKREJfSE9TVD0kezQtbG9jYWxob3N0fQpXUF9WRVJTSU9OPSR7NS1sYXRlc3R9ClNLSVBfREJfQ1JFQVRFPSR7Ni1mYWxzZX0KClRNUERJUj0ke1RNUERJUi0vdG1wfQpUTVBESVI9JChlY2hvICRUTVBESVIgfCBzZWQgLWUgInMvXC8kLy8iKQpXUF9URVNUU19ESVI9JHtXUF9URVNUU19ESVItJFRNUERJUi93b3JkcHJlc3MtdGVzdHMtbGlifQpXUF9DT1JFX0RJUj0ke1dQX0NPUkVfRElSLSRUTVBESVIvd29yZHByZXNzfQoKZG93bmxvYWQoKSB7CiAgICBpZiBbIGB3aGljaCBjdXJsYCBdOyB0aGVuCiAgICAgICAgY3VybCAtcyAiJDEiID4gIiQyIjsKICAgIGVsaWYgWyBgd2hpY2ggd2dldGAgXTsgdGhlbgogICAgICAgIHdnZXQgLW52IC1PICIkMiIgIiQxIgogICAgZmkKfQoKaWYgW1sgJFdQX1ZFUlNJT04gPX4gXlswLTldK1wuWzAtOV0rXC0oYmV0YXxSQylbMC05XSskIF1dOyB0aGVuCglXUF9CUkFOQ0g9JHtXUF9WRVJTSU9OJVwtKn0KCVdQX1RFU1RTX1RBRz0iYnJhbmNoZXMvJFdQX0JSQU5DSCIKCmVsaWYgW1sgJFdQX1ZFUlNJT04gPX4gXlswLTldK1wuWzAtOV0rJCBdXTsgdGhlbgoJV1BfVEVTVFNfVEFHPSJicmFuY2hlcy8kV1BfVkVSU0lPTiIKZWxpZiBbWyAkV1BfVkVSU0lPTiA9fiBbMC05XStcLlswLTldK1wuWzAtOV0rIF1dOyB0aGVuCglpZiBbWyAkV1BfVkVSU0lPTiA9fiBbMC05XStcLlswLTldK1wuWzBdIF1dOyB0aGVuCgkJIyB2ZXJzaW9uIHgueC4wIG1lYW5zIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoZSBtYWpvciB2ZXJzaW9uLCBzbyBzdHJpcCBvZmYgdGhlIC4wIGFuZCBkb3dubG9hZCB2ZXJzaW9uIHgueAoJCVdQX1RFU1RTX1RBRz0idGFncy8ke1dQX1ZFUlNJT04lPz99IgoJZWxzZQoJCVdQX1RFU1RTX1RBRz0idGFncy8kV1BfVkVSU0lPTiIKCWZpCmVsaWYgW1sgJFdQX1ZFUlNJT04gPT0gJ25pZ2h0bHknIHx8ICRXUF9WRVJTSU9OID09ICd0cnVuaycgXV07IHRoZW4KCVdQX1RFU1RTX1RBRz0idHJ1bmsiCmVsc2UKCSMgaHR0cCBzZXJ2ZXMgYSBzaW5nbGUgb2ZmZXIsIHdoZXJlYXMgaHR0cHMgc2VydmVzIG11bHRpcGxlLiB3ZSBvbmx5IHdhbnQgb25lCglkb3dubG9hZCBodHRwOi8vYXBpLndvcmRwcmVzcy5vcmcvY29yZS92ZXJzaW9uLWNoZWNrLzEuNy8gL3RtcC93cC1sYXRlc3QuanNvbgoJZ3JlcCAnWzAtOV0rXC5bMC05XSsoXC5bMC05XSspPycgL3RtcC93cC1sYXRlc3QuanNvbgoJTEFURVNUX1ZFUlNJT049JChncmVwIC1vICcidmVyc2lvbiI6IlteIl0qJyAvdG1wL3dwLWxhdGVzdC5qc29uIHwgc2VkICdzLyJ2ZXJzaW9uIjoiLy8nKQoJaWYgW1sgLXogIiRMQVRFU1RfVkVSU0lPTiIgXV07IHRoZW4KCQllY2hvICJMYXRlc3QgV29yZFByZXNzIHZlcnNpb24gY291bGQgbm90IGJlIGZvdW5kIgoJCWV4aXQgMQoJZmkKCVdQX1RFU1RTX1RBRz0idGFncy8kTEFURVNUX1ZFUlNJT04iCmZpCnNldCAtZXgKCmluc3RhbGxfd3AoKSB7CgoJaWYgWyAtZCAkV1BfQ09SRV9ESVIgXTsgdGhlbgoJCXJldHVybjsKCWZpCgoJbWtkaXIgLXAgJFdQX0NPUkVfRElSCgoJaWYgW1sgJFdQX1ZFUlNJT04gPT0gJ25pZ2h0bHknIHx8ICRXUF9WRVJTSU9OID09ICd0cnVuaycgXV07IHRoZW4KCQlta2RpciAtcCAkVE1QRElSL3dvcmRwcmVzcy10cnVuawoJCXJtIC1yZiAkVE1QRElSL3dvcmRwcmVzcy10cnVuay8qCgkJc3ZuIGV4cG9ydCAtLXF1aWV0IGh0dHBzOi8vY29yZS5zdm4ud29yZHByZXNzLm9yZy90cnVuayAkVE1QRElSL3dvcmRwcmVzcy10cnVuay93b3JkcHJlc3MKCQltdiAkVE1QRElSL3dvcmRwcmVzcy10cnVuay93b3JkcHJlc3MvKiAkV1BfQ09SRV9ESVIKCWVsc2UKCQlpZiBbICRXUF9WRVJTSU9OID09ICdsYXRlc3QnIF07IHRoZW4KCQkJbG9jYWwgQVJDSElWRV9OQU1FPSdsYXRlc3QnCgkJZWxpZiBbWyAkV1BfVkVSU0lPTiA9fiBbMC05XStcLlswLTldKyBdXTsgdGhlbgoJCQkjIGh0dHBzIHNlcnZlcyBtdWx0aXBsZSBvZmZlcnMsIHdoZXJlYXMgaHR0cCBzZXJ2ZXMgc2luZ2xlLgoJCQlkb3dubG9hZCBodHRwczovL2FwaS53b3JkcHJlc3Mub3JnL2NvcmUvdmVyc2lvbi1jaGVjay8xLjcvICRUTVBESVIvd3AtbGF0ZXN0Lmpzb24KCQkJaWYgW1sgJFdQX1ZFUlNJT04gPX4gWzAtOV0rXC5bMC05XStcLlswXSBdXTsgdGhlbgoJCQkJIyB2ZXJzaW9uIHgueC4wIG1lYW5zIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoZSBtYWpvciB2ZXJzaW9uLCBzbyBzdHJpcCBvZmYgdGhlIC4wIGFuZCBkb3dubG9hZCB2ZXJzaW9uIHgueAoJCQkJTEFURVNUX1ZFUlNJT049JHtXUF9WRVJTSU9OJT8/fQoJCQllbHNlCgkJCQkjIG90aGVyd2lzZSwgc2NhbiB0aGUgcmVsZWFzZXMgYW5kIGdldCB0aGUgbW9zdCB1cCB0byBkYXRlIG1pbm9yIHZlcnNpb24gb2YgdGhlIG1ham9yIHJlbGVhc2UKCQkJCWxvY2FsIFZFUlNJT05fRVNDQVBFRD1gZWNobyAkV1BfVkVSU0lPTiB8IHNlZCAncy9cLi9cXFxcLi9nJ2AKCQkJCUxBVEVTVF9WRVJTSU9OPSQoZ3JlcCAtbyAnInZlcnNpb24iOiInJFZFUlNJT05fRVNDQVBFRCdbXiJdKicgJFRNUERJUi93cC1sYXRlc3QuanNvbiB8IHNlZCAncy8idmVyc2lvbiI6Ii8vJyB8IGhlYWQgLTEpCgkJCWZpCgkJCWlmIFtbIC16ICIkTEFURVNUX1ZFUlNJT04iIF1dOyB0aGVuCgkJCQlsb2NhbCBBUkNISVZFX05BTUU9IndvcmRwcmVzcy0kV1BfVkVSU0lPTiIKCQkJZWxzZQoJCQkJbG9jYWwgQVJDSElWRV9OQU1FPSJ3b3JkcHJlc3MtJExBVEVTVF9WRVJTSU9OIgoJCQlmaQoJCWVsc2UKCQkJbG9jYWwgQVJDSElWRV9OQU1FPSJ3b3JkcHJlc3MtJFdQX1ZFUlNJT04iCgkJZmkKCQlkb3dubG9hZCBodHRwczovL3dvcmRwcmVzcy5vcmcvJHtBUkNISVZFX05BTUV9LnRhci5neiAgJFRNUERJUi93b3JkcHJlc3MudGFyLmd6CgkJdGFyIC0tc3RyaXAtY29tcG9uZW50cz0xIC16eG1mICRUTVBESVIvd29yZHByZXNzLnRhci5neiAtQyAkV1BfQ09SRV9ESVIKCWZpCgoJZG93bmxvYWQgaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS9tYXJrb2hlaWpuZW4vd3AtbXlzcWxpL21hc3Rlci9kYi5waHAgJFdQX0NPUkVfRElSL3dwLWNvbnRlbnQvZGIucGhwCn0KCmluc3RhbGxfdGVzdF9zdWl0ZSgpIHsKCSMgcG9ydGFibGUgaW4tcGxhY2UgYXJndW1lbnQgZm9yIGJvdGggR05VIHNlZCBhbmQgTWFjIE9TWCBzZWQKCWlmIFtbICQodW5hbWUgLXMpID09ICdEYXJ3aW4nIF1dOyB0aGVuCgkJbG9jYWwgaW9wdGlvbj0nLWkuYmFrJwoJZWxzZQoJCWxvY2FsIGlvcHRpb249Jy1pJwoJZmkKCgkjIHNldCB1cCB0ZXN0aW5nIHN1aXRlIGlmIGl0IGRvZXNuJ3QgeWV0IGV4aXN0CglpZiBbICEgLWQgJFdQX1RFU1RTX0RJUiBdOyB0aGVuCgkJIyBzZXQgdXAgdGVzdGluZyBzdWl0ZQoJCW1rZGlyIC1wICRXUF9URVNUU19ESVIKCQlybSAtcmYgJFdQX1RFU1RTX0RJUi97aW5jbHVkZXMsZGF0YX0KCQlzdm4gZXhwb3J0IC0tcXVpZXQgLS1pZ25vcmUtZXh0ZXJuYWxzIGh0dHBzOi8vZGV2ZWxvcC5zdm4ud29yZHByZXNzLm9yZy8ke1dQX1RFU1RTX1RBR30vdGVzdHMvcGhwdW5pdC9pbmNsdWRlcy8gJFdQX1RFU1RTX0RJUi9pbmNsdWRlcwoJCXN2biBleHBvcnQgLS1xdWlldCAtLWlnbm9yZS1leHRlcm5hbHMgaHR0cHM6Ly9kZXZlbG9wLnN2bi53b3JkcHJlc3Mub3JnLyR7V1BfVEVTVFNfVEFHfS90ZXN0cy9waHB1bml0L2RhdGEvICRXUF9URVNUU19ESVIvZGF0YQoJZmkKCglpZiBbICEgLWYgd3AtdGVzdHMtY29uZmlnLnBocCBdOyB0aGVuCgkJZG93bmxvYWQgaHR0cHM6Ly9kZXZlbG9wLnN2bi53b3JkcHJlc3Mub3JnLyR7V1BfVEVTVFNfVEFHfS93cC10ZXN0cy1jb25maWctc2FtcGxlLnBocCAiJFdQX1RFU1RTX0RJUiIvd3AtdGVzdHMtY29uZmlnLnBocAoJCSMgcmVtb3ZlIGFsbCBmb3J3YXJkIHNsYXNoZXMgaW4gdGhlIGVuZAoJCVdQX0NPUkVfRElSPSQoZWNobyAkV1BfQ09SRV9ESVIgfCBzZWQgInM6L1wrJDo6IikKCQlzZWQgJGlvcHRpb24gInM6ZGlybmFtZSggX19GSUxFX18gKSAuICcvc3JjLyc6JyRXUF9DT1JFX0RJUi8nOiIgIiRXUF9URVNUU19ESVIiL3dwLXRlc3RzLWNvbmZpZy5waHAKCQlzZWQgJGlvcHRpb24gInM6X19ESVJfXyAuICcvc3JjLyc6JyRXUF9DT1JFX0RJUi8nOiIgIiRXUF9URVNUU19ESVIiL3dwLXRlc3RzLWNvbmZpZy5waHAKCQlzZWQgJGlvcHRpb24gInMveW91cmVtcHR5dGVzdGRibmFtZWhlcmUvJERCX05BTUUvIiAiJFdQX1RFU1RTX0RJUiIvd3AtdGVzdHMtY29uZmlnLnBocAoJCXNlZCAkaW9wdGlvbiAicy95b3VydXNlcm5hbWVoZXJlLyREQl9VU0VSLyIgIiRXUF9URVNUU19ESVIiL3dwLXRlc3RzLWNvbmZpZy5waHAKCQlzZWQgJGlvcHRpb24gInMveW91cnBhc3N3b3JkaGVyZS8kREJfUEFTUy8iICIkV1BfVEVTVFNfRElSIi93cC10ZXN0cy1jb25maWcucGhwCgkJc2VkICRpb3B0aW9uICJzfGxvY2FsaG9zdHwke0RCX0hPU1R9fCIgIiRXUF9URVNUU19ESVIiL3dwLXRlc3RzLWNvbmZpZy5waHAKCWZpCgp9CgpyZWNyZWF0ZV9kYigpIHsKCXNob3B0IC1zIG5vY2FzZW1hdGNoCglpZiBbWyAkMSA9fiBeKHl8eWVzKSQgXV0KCXRoZW4KCQlteXNxbGFkbWluIGRyb3AgJERCX05BTUUgLWYgLS11c2VyPSIkREJfVVNFUiIgLS1wYXNzd29yZD0iJERCX1BBU1MiJEVYVFJBCgkJY3JlYXRlX2RiCgkJZWNobyAiUmVjcmVhdGVkIHRoZSBkYXRhYmFzZSAoJERCX05BTUUpLiIKCWVsc2UKCQllY2hvICJMZWF2aW5nIHRoZSBleGlzdGluZyBkYXRhYmFzZSAoJERCX05BTUUpIGluIHBsYWNlLiIKCWZpCglzaG9wdCAtdSBub2Nhc2VtYXRjaAp9CgpjcmVhdGVfZGIoKSB7CglteXNxbGFkbWluIGNyZWF0ZSAkREJfTkFNRSAtLXVzZXI9IiREQl9VU0VSIiAtLXBhc3N3b3JkPSIkREJfUEFTUyIkRVhUUkEKfQoKaW5zdGFsbF9kYigpIHsKCglpZiBbICR7U0tJUF9EQl9DUkVBVEV9ID0gInRydWUiIF07IHRoZW4KCQlyZXR1cm4gMAoJZmkKCgkjIHBhcnNlIERCX0hPU1QgZm9yIHBvcnQgb3Igc29ja2V0IHJlZmVyZW5jZXMKCWxvY2FsIFBBUlRTPSgke0RCX0hPU1QvL1w6LyB9KQoJbG9jYWwgREJfSE9TVE5BTUU9JHtQQVJUU1swXX07Cglsb2NhbCBEQl9TT0NLX09SX1BPUlQ9JHtQQVJUU1sxXX07Cglsb2NhbCBFWFRSQT0iIgoKCWlmICEgWyAteiAkREJfSE9TVE5BTUUgXSA7IHRoZW4KCQlpZiBbICQoZWNobyAkREJfU09DS19PUl9QT1JUIHwgZ3JlcCAtZSAnXlswLTldXHsxLFx9JCcpIF07IHRoZW4KCQkJRVhUUkE9IiAtLWhvc3Q9JERCX0hPU1ROQU1FIC0tcG9ydD0kREJfU09DS19PUl9QT1JUIC0tcHJvdG9jb2w9dGNwIgoJCWVsaWYgISBbIC16ICREQl9TT0NLX09SX1BPUlQgXSA7IHRoZW4KCQkJRVhUUkE9IiAtLXNvY2tldD0kREJfU09DS19PUl9QT1JUIgoJCWVsaWYgISBbIC16ICREQl9IT1NUTkFNRSBdIDsgdGhlbgoJCQlFWFRSQT0iIC0taG9zdD0kREJfSE9TVE5BTUUgLS1wcm90b2NvbD10Y3AiCgkJZmkKCWZpCgoJIyBjcmVhdGUgZGF0YWJhc2UKCWlmIFsgJChteXNxbCAtLXVzZXI9IiREQl9VU0VSIiAtLXBhc3N3b3JkPSIkREJfUEFTUyIkRVhUUkEgLS1leGVjdXRlPSdzaG93IGRhdGFiYXNlczsnIHwgZ3JlcCBeJERCX05BTUUkKSBdCgl0aGVuCgkJZWNobyAiUmVpbnN0YWxsaW5nIHdpbGwgZGVsZXRlIHRoZSBleGlzdGluZyB0ZXN0IGRhdGFiYXNlICgkREJfTkFNRSkiCgkJcmVhZCAtcCAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIHByb2NlZWQ/IFt5L05dOiAnIERFTEVURV9FWElTVElOR19EQgoJCXJlY3JlYXRlX2RiICRERUxFVEVfRVhJU1RJTkdfREIKCWVsc2UKCQljcmVhdGVfZGIKCWZpCn0KCmluc3RhbGxfd3AKaW5zdGFsbF90ZXN0X3N1aXRlCmluc3RhbGxfZGIKPT09IHt7cGx1Z2luX25hbWV9fSA9PT0KQ29udHJpYnV0b3JzOiAodGhpcyBzaG91bGQgYmUgYSBsaXN0IG9mIHdvcmRwcmVzcy5vcmcgdXNlcmlkJ3MpCkRvbmF0ZSBsaW5rOiBodHRwczovL2V4YW1wbGUuY29tLwpUYWdzOiBjb21tZW50cywgc3BhbQpSZXF1aXJlcyBhdCBsZWFzdDogNC41ClRlc3RlZCB1cCB0bzoge3twbHVnaW5fdGVzdGVkX3VwX3RvfX0KUmVxdWlyZXMgUEhQOiA1LjYKU3RhYmxlIHRhZzogMC4xLjAKTGljZW5zZTogR1BMdjIgb3IgbGF0ZXIKTGljZW5zZSBVUkk6IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC5odG1sCgpIZXJlIGlzIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIHBsdWdpbi4gIFRoaXMgc2hvdWxkIGJlIG5vIG1vcmUgdGhhbiAxNTAgY2hhcmFjdGVycy4gIE5vIG1hcmt1cCBoZXJlLgoKPT0gRGVzY3JpcHRpb24gPT0KClRoaXMgaXMgdGhlIGxvbmcgZGVzY3JpcHRpb24uICBObyBsaW1pdCwgYW5kIHlvdSBjYW4gdXNlIE1hcmtkb3duIChhcyB3ZWxsIGFzIGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMpLgoKRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBpZiB0aGlzIHNlY3Rpb24gaXMgbWlzc2luZywgdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzaG9ydCBkZXNjcmlwdGlvbiB3aWxsIGJlIHVzZWQsIGFuZApNYXJrZG93biBwYXJzZWQuCgpBIGZldyBub3RlcyBhYm91dCB0aGUgc2VjdGlvbnMgYWJvdmU6CgoqICAgIkNvbnRyaWJ1dG9ycyIgaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiB3cC5vcmcvd3AtcGx1Z2lucy5vcmcgdXNlcm5hbWVzCiogICAiVGFncyIgaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiB0YWdzIHRoYXQgYXBwbHkgdG8gdGhlIHBsdWdpbgoqICAgIlJlcXVpcmVzIGF0IGxlYXN0IiBpcyB0aGUgbG93ZXN0IHZlcnNpb24gdGhhdCB0aGUgcGx1Z2luIHdpbGwgd29yayBvbgoqICAgIlRlc3RlZCB1cCB0byIgaXMgdGhlIGhpZ2hlc3QgdmVyc2lvbiB0aGF0IHlvdSd2ZSAqc3VjY2Vzc2Z1bGx5IHVzZWQgdG8gdGVzdCB0aGUgcGx1Z2luKi4gTm90ZSB0aGF0IGl0IG1pZ2h0IHdvcmsgb24KaGlnaGVyIHZlcnNpb25zLi4uIHRoaXMgaXMganVzdCB0aGUgaGlnaGVzdCBvbmUgeW91J3ZlIHZlcmlmaWVkLgoqICAgU3RhYmxlIHRhZyBzaG91bGQgaW5kaWNhdGUgdGhlIFN1YnZlcnNpb24gInRhZyIgb2YgdGhlIGxhdGVzdCBzdGFibGUgdmVyc2lvbiwgb3IgInRydW5rLCIgaWYgeW91IHVzZSBgL3RydW5rL2AgZm9yCnN0YWJsZS4KCiAgICBOb3RlIHRoYXQgdGhlIGByZWFkbWUudHh0YCBvZiB0aGUgc3RhYmxlIHRhZyBpcyB0aGUgb25lIHRoYXQgaXMgY29uc2lkZXJlZCB0aGUgZGVmaW5pbmcgb25lIGZvciB0aGUgcGx1Z2luLCBzbwppZiB0aGUgYC90cnVuay9yZWFkbWUudHh0YCBmaWxlIHNheXMgdGhhdCB0aGUgc3RhYmxlIHRhZyBpcyBgNC4zYCwgdGhlbiBpdCBpcyBgL3RhZ3MvNC4zL3JlYWRtZS50eHRgIHRoYXQnbGwgYmUgdXNlZApmb3IgZGlzcGxheWluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGx1Z2luLiAgSW4gdGhpcyBzaXR1YXRpb24sIHRoZSBvbmx5IHRoaW5nIGNvbnNpZGVyZWQgZnJvbSB0aGUgdHJ1bmsgYHJlYWRtZS50eHRgCmlzIHRoZSBzdGFibGUgdGFnIHBvaW50ZXIuICBUaHVzLCBpZiB5b3UgZGV2ZWxvcCBpbiB0cnVuaywgeW91IGNhbiB1cGRhdGUgdGhlIHRydW5rIGByZWFkbWUudHh0YCB0byByZWZsZWN0IGNoYW5nZXMgaW4KeW91ciBpbi1kZXZlbG9wbWVudCB2ZXJzaW9uLCB3aXRob3V0IGhhdmluZyB0aGF0IGluZm9ybWF0aW9uIGluY29ycmVjdGx5IGRpc2Nsb3NlZCBhYm91dCB0aGUgY3VycmVudCBzdGFibGUgdmVyc2lvbgp0aGF0IGxhY2tzIHRob3NlIGNoYW5nZXMgLS0gYXMgbG9uZyBhcyB0aGUgdHJ1bmsncyBgcmVhZG1lLnR4dGAgcG9pbnRzIHRvIHRoZSBjb3JyZWN0IHN0YWJsZSB0YWcuCgogICAgSWYgbm8gc3RhYmxlIHRhZyBpcyBwcm92aWRlZCwgaXQgaXMgYXNzdW1lZCB0aGF0IHRydW5rIGlzIHN0YWJsZSwgYnV0IHlvdSBzaG91bGQgc3BlY2lmeSAidHJ1bmsiIGlmIHRoYXQncyB3aGVyZQp5b3UgcHV0IHRoZSBzdGFibGUgdmVyc2lvbiwgaW4gb3JkZXIgdG8gZWxpbWluYXRlIGFueSBkb3VidC4KCj09IEluc3RhbGxhdGlvbiA9PQoKVGhpcyBzZWN0aW9uIGRlc2NyaWJlcyBob3cgdG8gaW5zdGFsbCB0aGUgcGx1Z2luIGFuZCBnZXQgaXQgd29ya2luZy4KCmUuZy4KCjEuIFVwbG9hZCBgcGx1Z2luLW5hbWUucGhwYCB0byB0aGUgYC93cC1jb250ZW50L3BsdWdpbnMvYCBkaXJlY3RvcnkKMS4gQWN0aXZhdGUgdGhlIHBsdWdpbiB0aHJvdWdoIHRoZSAnUGx1Z2lucycgbWVudSBpbiBXb3JkUHJlc3MKMS4gUGxhY2UgYDw/cGhwIGRvX2FjdGlvbigncGx1Z2luX25hbWVfaG9vaycpOyA/PmAgaW4geW91ciB0ZW1wbGF0ZXMKCj09IEZyZXF1ZW50bHkgQXNrZWQgUXVlc3Rpb25zID09Cgo9IEEgcXVlc3Rpb24gdGhhdCBzb21lb25lIG1pZ2h0IGhhdmUgPQoKQW4gYW5zd2VyIHRvIHRoYXQgcXVlc3Rpb24uCgo9IFdoYXQgYWJvdXQgZm9vIGJhcj8gPQoKQW5zd2VyIHRvIGZvbyBiYXIgZGlsZW1tYS4KCj09IFNjcmVlbnNob3RzID09CgoxLiBUaGlzIHNjcmVlbiBzaG90IGRlc2NyaXB0aW9uIGNvcnJlc3BvbmRzIHRvIHNjcmVlbnNob3QtMS4ocG5nfGpwZ3xqcGVnfGdpZikuIE5vdGUgdGhhdCB0aGUgc2NyZWVuc2hvdCBpcyB0YWtlbiBmcm9tCnRoZSAvYXNzZXRzIGRpcmVjdG9yeSBvciB0aGUgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgdGhlIHN0YWJsZSByZWFkbWUudHh0ICh0YWdzIG9yIHRydW5rKS4gU2NyZWVuc2hvdHMgaW4gdGhlIC9hc3NldHMKZGlyZWN0b3J5IHRha2UgcHJlY2VkZW5jZS4gRm9yIGV4YW1wbGUsIGAvYXNzZXRzL3NjcmVlbnNob3QtMS5wbmdgIHdvdWxkIHdpbiBvdmVyIGAvdGFncy80LjMvc2NyZWVuc2hvdC0xLnBuZ2AKKG9yIGpwZywganBlZywgZ2lmKS4KMi4gVGhpcyBpcyB0aGUgc2Vjb25kIHNjcmVlbiBzaG90Cgo9PSBDaGFuZ2Vsb2cgPT0KCj0gMS4wID0KKiBBIGNoYW5nZSBzaW5jZSB0aGUgcHJldmlvdXMgdmVyc2lvbi4KKiBBbm90aGVyIGNoYW5nZS4KCj0gMC41ID0KKiBMaXN0IHZlcnNpb25zIGZyb20gbW9zdCByZWNlbnQgYXQgdG9wIHRvIG9sZGVzdCBhdCBib3R0b20uCgo9PSBVcGdyYWRlIE5vdGljZSA9PQoKPSAxLjAgPQpVcGdyYWRlIG5vdGljZXMgZGVzY3JpYmUgdGhlIHJlYXNvbiBhIHVzZXIgc2hvdWxkIHVwZ3JhZGUuICBObyBtb3JlIHRoYW4gMzAwIGNoYXJhY3RlcnMuCgo9IDAuNSA9ClRoaXMgdmVyc2lvbiBmaXhlcyBhIHNlY3VyaXR5IHJlbGF0ZWQgYnVnLiAgVXBncmFkZSBpbW1lZGlhdGVseS4KCj09IEFyYml0cmFyeSBzZWN0aW9uID09CgpZb3UgbWF5IHByb3ZpZGUgYXJiaXRyYXJ5IHNlY3Rpb25zLCBpbiB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIG9uZXMgYWJvdmUuICBUaGlzIG1heSBiZSBvZiB1c2UgZm9yIGV4dHJlbWVseSBjb21wbGljYXRlZApwbHVnaW5zIHdoZXJlIG1vcmUgaW5mb3JtYXRpb24gbmVlZHMgdG8gYmUgY29udmV5ZWQgdGhhdCBkb2Vzbid0IGZpdCBpbnRvIHRoZSBjYXRlZ29yaWVzIG9mICJkZXNjcmlwdGlvbiIgb3IKImluc3RhbGxhdGlvbi4iICBBcmJpdHJhcnkgc2VjdGlvbnMgd2lsbCBiZSBzaG93biBiZWxvdyB0aGUgYnVpbHQtaW4gc2VjdGlvbnMgb3V0bGluZWQgYWJvdmUuCgo9PSBBIGJyaWVmIE1hcmtkb3duIEV4YW1wbGUgPT0KCk9yZGVyZWQgbGlzdDoKCjEuIFNvbWUgZmVhdHVyZQoxLiBBbm90aGVyIGZlYXR1cmUKMS4gU29tZXRoaW5nIGVsc2UgYWJvdXQgdGhlIHBsdWdpbgoKVW5vcmRlcmVkIGxpc3Q6CgoqIHNvbWV0aGluZwoqIHNvbWV0aGluZyBlbHNlCiogdGhpcmQgdGhpbmcKCkhlcmUncyBhIGxpbmsgdG8gW1dvcmRQcmVzc10oaHR0cHM6Ly93b3JkcHJlc3Mub3JnLyAiWW91ciBmYXZvcml0ZSBzb2Z0d2FyZSIpIGFuZCBvbmUgdG8gW01hcmtkb3duJ3MgU3ludGF4IERvY3VtZW50YXRpb25dW21hcmtkb3duIHN5bnRheF0uClRpdGxlcyBhcmUgb3B0aW9uYWwsIG5hdHVyYWxseS4KClttYXJrZG93biBzeW50YXhdOiBodHRwczovL2RhcmluZ2ZpcmViYWxsLm5ldC9wcm9qZWN0cy9tYXJrZG93bi9zeW50YXgKICAgICAgICAgICAgIk1hcmtkb3duIGlzIHdoYXQgdGhlIHBhcnNlciB1c2VzIHRvIHByb2Nlc3MgbXVjaCBvZiB0aGUgcmVhZG1lIGZpbGUiCgpNYXJrZG93biB1c2VzIGVtYWlsIHN0eWxlIG5vdGF0aW9uIGZvciBibG9ja3F1b3RlcyBhbmQgSSd2ZSBiZWVuIHRvbGQ6Cj4gQXN0ZXJpc2tzIGZvciAqZW1waGFzaXMqLiBEb3VibGUgaXQgdXAgIGZvciAqKnN0cm9uZyoqLgoKYDw/cGhwIGNvZGUoKTsgLy8gZ29lcyBpbiBiYWNrdGlja3MgPz5gCi8qClRoZW1lIE5hbWU6ICAgICB7e3RoZW1lX25hbWV9fQpUaGVtZSBVUkk6ICAgICAge3t0aGVtZV91cml9fQpEZXNjcmlwdGlvbjogICAge3tkZXNjcmlwdGlvbn19CkF1dGhvcjogICAgICAgICB7e2F1dGhvcn19CkF1dGhvciBVUkk6ICAgICB7e2F1dGhvcl91cml9fQpUZW1wbGF0ZTogICAgICAge3twYXJlbnRfdGhlbWV9fQpWZXJzaW9uOiAgICAgICAgMC4xLjAKKi8KPD9waHAKLyoqCiAqIHt7dGhlbWVfbmFtZX19IFRoZW1lIGZ1bmN0aW9ucyBhbmQgZGVmaW5pdGlvbnMuCiAqCiAqIEBsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvdGhlbWVzL2Jhc2ljcy90aGVtZS1mdW5jdGlvbnMvCiAqCiAqIEBwYWNrYWdlIHt7c2x1Z319CiAqLwoKYWRkX2FjdGlvbiggJ3dwX2VucXVldWVfc2NyaXB0cycsICd7e3BhcmVudF90aGVtZV9mdW5jdGlvbl9zYWZlfX1fcGFyZW50X3RoZW1lX2VucXVldWVfc3R5bGVzJyApOwoKLyoqCiAqIEVucXVldWUgc2NyaXB0cyBhbmQgc3R5bGVzLgogKi8KZnVuY3Rpb24ge3twYXJlbnRfdGhlbWVfZnVuY3Rpb25fc2FmZX19X3BhcmVudF90aGVtZV9lbnF1ZXVlX3N0eWxlcygpIHsKCXdwX2VucXVldWVfc3R5bGUoICd7e3BhcmVudF90aGVtZX19LXN0eWxlJywgZ2V0X3RlbXBsYXRlX2RpcmVjdG9yeV91cmkoKSAuICcvc3R5bGUuY3NzJyApOwoJd3BfZW5xdWV1ZV9zdHlsZSggJ3t7c2x1Z319LXN0eWxlJywKCQlnZXRfc3R5bGVzaGVldF9kaXJlY3RvcnlfdXJpKCkgLiAnL3N0eWxlLmNzcycsCgkJWyAne3twYXJlbnRfdGhlbWV9fS1zdHlsZScgXQoJKTsKfQoJcmVnaXN0ZXJfcG9zdF90eXBlKAoJCSd7e3NsdWd9fScsCgkJWwoJCQknbGFiZWxzJyAgICAgICAgICAgICAgICA9PiBbCgkJCQknbmFtZScgICAgICAgICAgICAgICAgICA9PiBfXyggJ3t7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdzaW5ndWxhcl9uYW1lJyAgICAgICAgID0+IF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknYWxsX2l0ZW1zJyAgICAgICAgICAgICA9PiBfXyggJ0FsbCB7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknYXJjaGl2ZXMnICAgICAgICAgICAgICA9PiBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IEFyY2hpdmVzJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ2F0dHJpYnV0ZXMnICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSBBdHRyaWJ1dGVzJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ2luc2VydF9pbnRvX2l0ZW0nICAgICAgPT4gX18oICdJbnNlcnQgaW50byB7e2xhYmVsfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQkndXBsb2FkZWRfdG9fdGhpc19pdGVtJyA9PiBfXyggJ1VwbG9hZGVkIHRvIHRoaXMge3tsYWJlbH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ2ZlYXR1cmVkX2ltYWdlJyAgICAgICAgPT4gX3goICdGZWF0dXJlZCBJbWFnZScsICd7e3NsdWd9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdzZXRfZmVhdHVyZWRfaW1hZ2UnICAgID0+IF94KCAnU2V0IGZlYXR1cmVkIGltYWdlJywgJ3t7c2x1Z319JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ3JlbW92ZV9mZWF0dXJlZF9pbWFnZScgPT4gX3goICdSZW1vdmUgZmVhdHVyZWQgaW1hZ2UnLCAne3tzbHVnfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQkndXNlX2ZlYXR1cmVkX2ltYWdlJyAgICA9PiBfeCggJ1VzZSBhcyBmZWF0dXJlZCBpbWFnZScsICd7e3NsdWd9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdmaWx0ZXJfaXRlbXNfbGlzdCcgICAgID0+IF9fKCAnRmlsdGVyIHt7bGFiZWxfcGx1cmFsfX0gbGlzdCcsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdpdGVtc19saXN0X25hdmlnYXRpb24nID0+IF9fKCAne3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19IGxpc3QgbmF2aWdhdGlvbicsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdpdGVtc19saXN0JyAgICAgICAgICAgID0+IF9fKCAne3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19IGxpc3QnLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknbmV3X2l0ZW0nICAgICAgICAgICAgICA9PiBfXyggJ05ldyB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdhZGRfbmV3JyAgICAgICAgICAgICAgID0+IF9fKCAnQWRkIE5ldycsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdhZGRfbmV3X2l0ZW0nICAgICAgICAgID0+IF9fKCAnQWRkIE5ldyB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdlZGl0X2l0ZW0nICAgICAgICAgICAgID0+IF9fKCAnRWRpdCB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSd2aWV3X2l0ZW0nICAgICAgICAgICAgID0+IF9fKCAnVmlldyB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSd2aWV3X2l0ZW1zJyAgICAgICAgICAgID0+IF9fKCAnVmlldyB7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknc2VhcmNoX2l0ZW1zJyAgICAgICAgICA9PiBfXyggJ1NlYXJjaCB7e2xhYmVsX3BsdXJhbH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ25vdF9mb3VuZCcgICAgICAgICAgICAgPT4gX18oICdObyB7e2xhYmVsX3BsdXJhbH19IGZvdW5kJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ25vdF9mb3VuZF9pbl90cmFzaCcgICAgPT4gX18oICdObyB7e2xhYmVsX3BsdXJhbH19IGZvdW5kIGluIHRyYXNoJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ3BhcmVudF9pdGVtX2NvbG9uJyAgICAgPT4gX18oICdQYXJlbnQge3tsYWJlbF91Y2ZpcnN0fX06JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ21lbnVfbmFtZScgICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCV0sCgkJCSdwdWJsaWMnICAgICAgICAgICAgICAgID0+IHRydWUsCgkJCSdoaWVyYXJjaGljYWwnICAgICAgICAgID0+IGZhbHNlLAoJCQknc2hvd191aScgICAgICAgICAgICAgICA9PiB0cnVlLAoJCQknc2hvd19pbl9uYXZfbWVudXMnICAgICA9PiB0cnVlLAoJCQknc3VwcG9ydHMnICAgICAgICAgICAgICA9PiBbICd0aXRsZScsICdlZGl0b3InIF0sCgkJCSdoYXNfYXJjaGl2ZScgICAgICAgICAgID0+IHRydWUsCgkJCSdyZXdyaXRlJyAgICAgICAgICAgICAgID0+IHRydWUsCgkJCSdxdWVyeV92YXInICAgICAgICAgICAgID0+IHRydWUsCgkJCSdtZW51X3Bvc2l0aW9uJyAgICAgICAgID0+IG51bGwsCgkJCSdtZW51X2ljb24nICAgICAgICAgICAgID0+ICdkYXNoaWNvbnMte3tkYXNoaWNvbn19JywKCQkJJ3Nob3dfaW5fcmVzdCcgICAgICAgICAgPT4gdHJ1ZSwKCQkJJ3Jlc3RfYmFzZScgICAgICAgICAgICAgPT4gJ3t7c2x1Z319JywKCQkJJ3Jlc3RfY29udHJvbGxlcl9jbGFzcycgPT4gJ1dQX1JFU1RfUG9zdHNfQ29udHJvbGxlcicsCgkJXQoJKTsKc3VkbzogZmFsc2UKZGlzdDogdHJ1c3R5CgpsYW5ndWFnZTogcGhwCgpub3RpZmljYXRpb25zOgogIGVtYWlsOgogICAgb25fc3VjY2VzczogbmV2ZXIKICAgIG9uX2ZhaWx1cmU6IGNoYW5nZQoKYnJhbmNoZXM6CiAgb25seToKICAgIC0gbWFzdGVyCgpjYWNoZToKICBkaXJlY3RvcmllczoKICAgIC0gJEhPTUUvLmNvbXBvc2VyL2NhY2hlCgptYXRyaXg6CiAgaW5jbHVkZToKICAgIC0gcGhwOiA3LjQKICAgICAgZW52OiBXUF9WRVJTSU9OPWxhdGVzdAogICAgLSBwaHA6IDcuMwogICAgICBlbnY6IFdQX1ZFUlNJT049bGF0ZXN0CiAgICAtIHBocDogNy4yCiAgICAgIGVudjogV1BfVkVSU0lPTj1sYXRlc3QKICAgIC0gcGhwOiA3LjEKICAgICAgZW52OiBXUF9WRVJTSU9OPWxhdGVzdAogICAgLSBwaHA6IDcuMAogICAgICBlbnY6IFdQX1ZFUlNJT049bGF0ZXN0CiAgICB7eyN3cF92ZXJzaW9uc190b190ZXN0fX0KICAgIC0gcGhwOiA1LjYKICAgICAgZW52OiBXUF9WRVJTSU9OPXt7Ln19CiAgICB7ey93cF92ZXJzaW9uc190b190ZXN0fX0KICAgIC0gcGhwOiA1LjYKICAgICAgZW52OiBXUF9UUkFWSVNDST1waHBjcwoKYmVmb3JlX3NjcmlwdDoKICAtIGV4cG9ydCBQQVRIPSIkSE9NRS8uY29tcG9zZXIvdmVuZG9yL2JpbjokUEFUSCIKICAtIHwKICAgIGlmIFsgLWYgfi8ucGhwZW52L3ZlcnNpb25zLyQocGhwZW52IHZlcnNpb24tbmFtZSkvZXRjL2NvbmYuZC94ZGVidWcuaW5pIF07IHRoZW4KICAgICAgcGhwZW52IGNvbmZpZy1ybSB4ZGVidWcuaW5pCiAgICBlbHNlCiAgICAgIGVjaG8gInhkZWJ1Zy5pbmkgZG9lcyBub3QgZXhpc3QiCiAgICBmaQogIC0gfAogICAgaWYgW1sgISAteiAiJFdQX1ZFUlNJT04iIF1dIDsgdGhlbgogICAgICBiYXNoIGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoIHdvcmRwcmVzc190ZXN0IHJvb3QgJycgbG9jYWxob3N0ICRXUF9WRVJTSU9OCiAgICAgIGNvbXBvc2VyIGdsb2JhbCByZXF1aXJlICJwaHB1bml0L3BocHVuaXQ9NC44Lip8NS43LioiCiAgICBmaQogIC0gfAogICAgaWYgW1sgIiRXUF9UUkFWSVNDSSIgPT0gInBocGNzIiBdXSA7IHRoZW4KICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgd3AtY29kaW5nLXN0YW5kYXJkcy93cGNzCiAgICAgIGNvbXBvc2VyIGdsb2JhbCByZXF1aXJlIHBocGNvbXBhdGliaWxpdHkvcGhwLWNvbXBhdGliaWxpdHkKICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgcGhwY29tcGF0aWJpbGl0eS9waHBjb21wYXRpYmlsaXR5LXBhcmFnb25pZQogICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSBwaHBjb21wYXRpYmlsaXR5L3BocGNvbXBhdGliaWxpdHktd3AKICAgICAgcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAkSE9NRS8uY29tcG9zZXIvdmVuZG9yL3dwLWNvZGluZy1zdGFuZGFyZHMvd3BjcywkSE9NRS8uY29tcG9zZXIvdmVuZG9yL3BocGNvbXBhdGliaWxpdHkvcGhwLWNvbXBhdGliaWxpdHksJEhPTUUvLmNvbXBvc2VyL3ZlbmRvci9waHBjb21wYXRpYmlsaXR5L3BocGNvbXBhdGliaWxpdHktcGFyYWdvbmllLCRIT01FLy5jb21wb3Nlci92ZW5kb3IvcGhwY29tcGF0aWJpbGl0eS9waHBjb21wYXRpYmlsaXR5LXdwCiAgICBmaQoKc2NyaXB0OgogIC0gfAogICAgaWYgW1sgISAteiAiJFdQX1ZFUlNJT04iIF1dIDsgdGhlbgogICAgICBwaHB1bml0CiAgICAgIFdQX01VTFRJU0lURT0xIHBocHVuaXQKICAgIGZpCiAgLSB8CiAgICBpZiBbWyAiJFdQX1RSQVZJU0NJIiA9PSAicGhwY3MiIF1dIDsgdGhlbgogICAgICBwaHBjcwogICAgZmkKPD9waHAKCi8vIGF1dG9sb2FkLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpyZXF1aXJlX29uY2UgX19ESVJfXyAuICcvY29tcG9zZXIvYXV0b2xvYWRfcmVhbC5waHAnOwoKcmV0dXJuIENvbXBvc2VyQXV0b2xvYWRlckluaXQwNDExNDExMGFmODdmNTYyNGIzNTgwZWJhNDNiODc3MDo6Z2V0TG9hZGVyKCk7CkNvcHlyaWdodCAoYykgTmlscyBBZGVybWFubiwgSm9yZGkgQm9nZ2lhbm8KClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQKdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgpUSEUgU09GVFdBUkUuCnsKICAgICIkc2NoZW1hIjogImh0dHBzOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMiLAogICAgInRpdGxlIjogIlBhY2thZ2UiLAogICAgInR5cGUiOiAib2JqZWN0IiwKICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICJuYW1lIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUGFja2FnZSBuYW1lLCBpbmNsdWRpbmcgJ3ZlbmRvci1uYW1lLycgcHJlZml4LiIsCiAgICAgICAgICAgICJwYXR0ZXJuIjogIl5bYS16MC05XShbXy4tXT9bYS16MC05XSspKi9bYS16MC05XSgoW18uXT98LXswLDJ9KVthLXowLTldKykqJCIKICAgICAgICB9LAogICAgICAgICJkZXNjcmlwdGlvbiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlNob3J0IHBhY2thZ2UgZGVzY3JpcHRpb24uIgogICAgICAgIH0sCiAgICAgICAgImxpY2Vuc2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYXJyYXkiXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkxpY2Vuc2UgbmFtZS4gT3IgYW4gYXJyYXkgb2YgbGljZW5zZSBuYW1lcy4iCiAgICAgICAgfSwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhY2thZ2UgdHlwZSwgZWl0aGVyICdsaWJyYXJ5JyBmb3IgY29tbW9uIHBhY2thZ2VzLCAnY29tcG9zZXItcGx1Z2luJyBmb3IgcGx1Z2lucywgJ21ldGFwYWNrYWdlJyBmb3IgZW1wdHkgcGFja2FnZXMsIG9yIGEgY3VzdG9tIHR5cGUgKFthLXowLTktXSspIGRlZmluZWQgYnkgd2hhdGV2ZXIgcHJvamVjdCB0aGlzIHBhY2thZ2UgYXBwbGllcyB0by4iLAogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAicGF0dGVybiI6ICJeW2EtejAtOS1dKyQiCiAgICAgICAgfSwKICAgICAgICAiYWJhbmRvbmVkIjogewogICAgICAgICAgICAidHlwZSI6IFsiYm9vbGVhbiIsICJzdHJpbmciXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkluZGljYXRlcyB3aGV0aGVyIHRoaXMgcGFja2FnZSBoYXMgYmVlbiBhYmFuZG9uZWQsIGl0IGNhbiBiZSBib29sZWFuIG9yIGEgcGFja2FnZSBuYW1lL1VSTCBwb2ludGluZyB0byBhIHJlY29tbWVuZGVkIGFsdGVybmF0aXZlLiBEZWZhdWx0cyB0byBmYWxzZS4iCiAgICAgICAgfSwKICAgICAgICAidmVyc2lvbiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhY2thZ2UgdmVyc2lvbiwgc2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wNC1zY2hlbWEubWQjdmVyc2lvbiBmb3IgbW9yZSBpbmZvIG9uIHZhbGlkIHNjaGVtZXMuIiwKICAgICAgICAgICAgInBhdHRlcm4iOiAiXnY/XFxkKyhcXC5cXGQrKXswLDN9fF5kZXYtIgogICAgICAgIH0sCiAgICAgICAgImRlZmF1bHQtYnJhbmNoIjogewogICAgICAgICAgICAidHlwZSI6IFsiYm9vbGVhbiJdLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiSW50ZXJuYWwgdXNlIG9ubHksIGRvIG5vdCBzcGVjaWZ5IHRoaXMgaW4gY29tcG9zZXIuanNvbi4gSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB2ZXJzaW9uIGlzIHRoZSBkZWZhdWx0IGJyYW5jaCBvZiB0aGUgbGlua2VkIFZDUyByZXBvc2l0b3J5LiBEZWZhdWx0cyB0byBmYWxzZS4iCiAgICAgICAgfSwKICAgICAgICAibm9uLWZlYXR1cmUtYnJhbmNoZXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogWyJhcnJheSJdLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBzZXQgb2Ygc3RyaW5nIG9yIHJlZ2V4IHBhdHRlcm5zIGZvciBub24tbnVtZXJpYyBicmFuY2ggbmFtZXMgdGhhdCB3aWxsIG5vdCBiZSBoYW5kbGVkIGFzIGZlYXR1cmUgYnJhbmNoZXMuIiwKICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAia2V5d29yZHMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHRhZy9rZXl3b3JkIHRoYXQgdGhpcyBwYWNrYWdlIHJlbGF0ZXMgdG8uIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVhZG1lIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUmVsYXRpdmUgcGF0aCB0byB0aGUgcmVhZG1lIGRvY3VtZW50LiIKICAgICAgICB9LAogICAgICAgICJ0aW1lIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUGFja2FnZSByZWxlYXNlIGRhdGUsIGluICdZWVlZLU1NLUREJywgJ1lZWVktTU0tREQgSEg6TU06U1MnIG9yICdZWVlZLU1NLUREVEhIOk1NOlNTWicgZm9ybWF0LiIKICAgICAgICB9LAogICAgICAgICJhdXRob3JzIjogewogICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL2F1dGhvcnMiCiAgICAgICAgfSwKICAgICAgICAiaG9tZXBhZ2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJIb21lcGFnZSBVUkwgZm9yIHRoZSBwcm9qZWN0LiIsCiAgICAgICAgICAgICJmb3JtYXQiOiAidXJpIgogICAgICAgIH0sCiAgICAgICAgInN1cHBvcnQiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgImVtYWlsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkVtYWlsIGFkZHJlc3MgZm9yIHN1cHBvcnQuIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogImVtYWlsIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJpc3N1ZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVVJMIHRvIHRoZSBpc3N1ZSB0cmFja2VyLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImZvcnVtIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVSTCB0byB0aGUgZm9ydW0uIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAid2lraSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVUkwgdG8gdGhlIHdpa2kuIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiaXJjIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklSQyBjaGFubmVsIGZvciBzdXBwb3J0LCBhcyBpcmM6Ly9zZXJ2ZXIvY2hhbm5lbC4iLAogICAgICAgICAgICAgICAgICAgICJmb3JtYXQiOiAidXJpIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjaGF0IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVSTCB0byB0aGUgc3VwcG9ydCBjaGF0LiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInNvdXJjZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVUkwgdG8gYnJvd3NlIG9yIGRvd25sb2FkIHRoZSBzb3VyY2VzLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImRvY3MiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVVJMIHRvIHRoZSBkb2N1bWVudGF0aW9uLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInJzcyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVUkwgdG8gdGhlIFJTUyBmZWVkLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJmdW5kaW5nIjogewogICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGxpc3Qgb2Ygb3B0aW9ucyB0byBmdW5kIHRoZSBkZXZlbG9wbWVudCBhbmQgbWFpbnRlbmFuY2Ugb2YgdGhlIHBhY2thZ2UuIiwKICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVHlwZSBvZiBmdW5kaW5nIG9yIHBsYXRmb3JtIHRocm91Z2ggd2hpY2ggZnVuZGluZyBpcyBwb3NzaWJsZS4iCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAidXJsIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVVJMIHRvIGEgd2Vic2l0ZSB3aXRoIGRldGFpbHMgb24gZnVuZGluZyBhbmQgYSB3YXkgdG8gZnVuZCB0aGUgcGFja2FnZS4iLAogICAgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJfY29tbWVudCI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBrZXkgdG8gc3RvcmUgY29tbWVudHMgaW4iCiAgICAgICAgfSwKICAgICAgICAicmVxdWlyZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gb2JqZWN0IG9mIHBhY2thZ2UgbmFtZSAoa2V5cykgYW5kIHZlcnNpb24gY29uc3RyYWludHMgKHZhbHVlcykgdGhhdCBhcmUgcmVxdWlyZWQgdG8gcnVuIHRoaXMgcGFja2FnZS4iLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJyZXF1aXJlLWRldiI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gb2JqZWN0IG9mIHBhY2thZ2UgbmFtZSAoa2V5cykgYW5kIHZlcnNpb24gY29uc3RyYWludHMgKHZhbHVlcykgdGhhdCB0aGlzIHBhY2thZ2UgcmVxdWlyZXMgZm9yIGRldmVsb3BpbmcgaXQgKHRlc3RpbmcgdG9vbHMgYW5kIHN1Y2gpLiIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInJlcGxhY2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGFuIG9iamVjdCBvZiBwYWNrYWdlIG5hbWUgKGtleXMpIGFuZCB2ZXJzaW9uIGNvbnN0cmFpbnRzICh2YWx1ZXMpIHRoYXQgY2FuIGJlIHJlcGxhY2VkIGJ5IHRoaXMgcGFja2FnZS4iLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjb25mbGljdCI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gb2JqZWN0IG9mIHBhY2thZ2UgbmFtZSAoa2V5cykgYW5kIHZlcnNpb24gY29uc3RyYWludHMgKHZhbHVlcykgdGhhdCBjb25mbGljdCB3aXRoIHRoaXMgcGFja2FnZS4iLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJwcm92aWRlIjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBvYmplY3Qgb2YgcGFja2FnZSBuYW1lIChrZXlzKSBhbmQgdmVyc2lvbiBjb25zdHJhaW50cyAodmFsdWVzKSB0aGF0IHRoaXMgcGFja2FnZSBwcm92aWRlcyBpbiBhZGRpdGlvbiB0byB0aGlzIHBhY2thZ2UncyBuYW1lLiIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInN1Z2dlc3QiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGFuIG9iamVjdCBvZiBwYWNrYWdlIG5hbWUgKGtleXMpIGFuZCBkZXNjcmlwdGlvbnMgKHZhbHVlcykgdGhhdCB0aGlzIHBhY2thZ2Ugc3VnZ2VzdHMgd29yayB3ZWxsIHdpdGggaXQgKHRoaXMgd2lsbCBiZSBzdWdnZXN0ZWQgdG8gdGhlIHVzZXIgZHVyaW5nIGluc3RhbGxhdGlvbikuIiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVwb3NpdG9yaWVzIjogewogICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0IiwgImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHNldCBvZiBhZGRpdGlvbmFsIHJlcG9zaXRvcmllcyB3aGVyZSBwYWNrYWdlcyBjYW4gYmUgZm91bmQuIiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgICAgIHsgInR5cGUiOiAiYm9vbGVhbiIsICJlbnVtIjogW2ZhbHNlXSB9CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvcmVwb3NpdG9yeSIgfSwKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsgInR5cGUiOiAiYm9vbGVhbiIsICJlbnVtIjogW2ZhbHNlXSB9LAogICAgICAgICAgICAgICAgICAgICAgICAibWluUHJvcGVydGllcyI6IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICJtYXhQcm9wZXJ0aWVzIjogMQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm1pbmltdW0tc3RhYmlsaXR5IjogewogICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIl0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbWluaW11bSBzdGFiaWxpdHkgdGhlIHBhY2thZ2VzIG11c3QgaGF2ZSB0byBiZSBpbnN0YWxsLWFibGUuIFBvc3NpYmxlIHZhbHVlcyBhcmU6IGRldiwgYWxwaGEsIGJldGEsIFJDLCBzdGFibGUuIiwKICAgICAgICAgICAgImVudW0iOiBbImRldiIsICJhbHBoYSIsICJiZXRhIiwgInJjIiwgIlJDIiwgInN0YWJsZSJdCiAgICAgICAgfSwKICAgICAgICAicHJlZmVyLXN0YWJsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImJvb2xlYW4iXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHNldCB0byB0cnVlLCBzdGFibGUgcGFja2FnZXMgd2lsbCBiZSBwcmVmZXJyZWQgdG8gZGV2IHBhY2thZ2VzIHdoZW4gcG9zc2libGUsIGV2ZW4gaWYgdGhlIG1pbmltdW0tc3RhYmlsaXR5IGFsbG93cyB1bnN0YWJsZSBwYWNrYWdlcy4iCiAgICAgICAgfSwKICAgICAgICAiYXV0b2xvYWQiOiB7CiAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvYXV0b2xvYWQiCiAgICAgICAgfSwKICAgICAgICAiYXV0b2xvYWQtZGV2IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGVzY3JpcHRpb24gb2YgYWRkaXRpb25hbCBhdXRvbG9hZCBydWxlcyBmb3IgZGV2ZWxvcG1lbnQgcHVycG9zZSAoZWcuIGEgdGVzdCBzdWl0ZSkuIiwKICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAicHNyLTAiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBvYmplY3Qgb2YgbmFtZXNwYWNlcyAoa2V5cykgYW5kIHRoZSBkaXJlY3RvcmllcyB0aGV5IGNhbiBiZSBmb3VuZCBpbnRvICh2YWx1ZXMsIGNhbiBiZSBhcnJheXMgb2YgcGF0aHMpIGJ5IHRoZSBhdXRvbG9hZGVyLiIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImFycmF5Il0sCiAgICAgICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHNyLTQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBvYmplY3Qgb2YgbmFtZXNwYWNlcyAoa2V5cykgYW5kIHRoZSBQU1ItNCBkaXJlY3RvcmllcyB0aGV5IGNhbiBtYXAgdG8gKHZhbHVlcywgY2FuIGJlIGFycmF5cyBvZiBwYXRocykgYnkgdGhlIGF1dG9sb2FkZXIuIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYXJyYXkiXSwKICAgICAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjbGFzc21hcCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gYXJyYXkgb2YgcGF0aHMgdGhhdCBjb250YWluIGNsYXNzZXMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIGNsYXNzLW1hcCBnZW5lcmF0aW9uIHByb2Nlc3MuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJmaWxlcyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gYXJyYXkgb2YgZmlsZXMgdGhhdCBhcmUgYWx3YXlzIHJlcXVpcmVkIG9uIGV2ZXJ5IHJlcXVlc3QuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAidGFyZ2V0LWRpciI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRFUFJFQ0FURUQ6IEZvcmNlcyB0aGUgcGFja2FnZSB0byBiZSBpbnN0YWxsZWQgaW50byB0aGUgZ2l2ZW4gc3ViZGlyZWN0b3J5IHBhdGguIFRoaXMgaXMgdXNlZCBmb3IgYXV0b2xvYWRpbmcgUFNSLTAgcGFja2FnZXMgdGhhdCBkbyBub3QgY29udGFpbiB0aGVpciBmdWxsIHBhdGguIFVzZSBmb3J3YXJkIHNsYXNoZXMgZm9yIGNyb3NzLXBsYXRmb3JtIGNvbXBhdGliaWxpdHkuIiwKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImluY2x1ZGUtcGF0aCI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJERVBSRUNBVEVEOiBBIGxpc3Qgb2YgZGlyZWN0b3JpZXMgd2hpY2ggc2hvdWxkIGdldCBhZGRlZCB0byBQSFAncyBpbmNsdWRlIHBhdGguIFRoaXMgaXMgb25seSBwcmVzZW50IHRvIHN1cHBvcnQgbGVnYWN5IHByb2plY3RzLCBhbmQgYWxsIG5ldyBjb2RlIHNob3VsZCBwcmVmZXJhYmx5IHVzZSBhdXRvbG9hZGluZy4iLAogICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJiaW4iOiB7CiAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYXJyYXkiXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgc2V0IG9mIGZpbGVzLCBvciBhIHNpbmdsZSBmaWxlLCB0aGF0IHNob3VsZCBiZSB0cmVhdGVkIGFzIGJpbmFyaWVzIGFuZCBzeW1saW5rZWQgaW50byBiaW4tZGlyIChmcm9tIGNvbmZpZykuIiwKICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiYXJjaGl2ZSI6IHsKICAgICAgICAgICAgInR5cGUiOiBbIm9iamVjdCJdLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT3B0aW9ucyBmb3IgY3JlYXRpbmcgcGFja2FnZSBhcmNoaXZlcyBmb3IgZGlzdHJpYnV0aW9uLiIsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgIm5hbWUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBiYXNlIG5hbWUgZm9yIGFyY2hpdmUuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBsaXN0IG9mIHBhdHRlcm5zIGZvciBwYXRocyB0byBleGNsdWRlIG9yIGluY2x1ZGUgaWYgcHJlZml4ZWQgd2l0aCBhbiBleGNsYW1hdGlvbiBtYXJrLiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNvbmZpZyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkNvbXBvc2VyIG9wdGlvbnMuIiwKICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAicGxhdGZvcm0iOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBvYmplY3Qgb2YgcGFja2FnZSBuYW1lIChrZXlzKSBhbmQgdmVyc2lvbiAodmFsdWVzKSB0aGF0IHdpbGwgYmUgdXNlZCB0byBtb2NrIHRoZSBwbGF0Zm9ybSBwYWNrYWdlcyBvbiB0aGlzIG1hY2hpbmUuIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYm9vbGVhbiJdCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJhbGxvdy1wbHVnaW5zIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJvYmplY3QiLCAiYm9vbGVhbiJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGFuIG9iamVjdCBvZiB7XCJwYXR0ZXJuXCI6IHRydWV8ZmFsc2V9IHdpdGggcGFja2FnZXMgd2hpY2ggYXJlIGFsbG93ZWQgdG8gYmUgbG9hZGVkIGFzIHBsdWdpbnMsIG9yIHRydWUgdG8gYWxsb3cgYWxsLCBmYWxzZSB0byBhbGxvdyBub25lLiBEZWZhdWx0cyB0byB7fSB3aGljaCBwcm9tcHRzIHdoZW4gYW4gdW5rbm93biBwbHVnaW4gaXMgYWRkZWQuIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJib29sZWFuIl0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInByb2Nlc3MtdGltZW91dCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJpbnRlZ2VyIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIHRpbWVvdXQgaW4gc2Vjb25kcyBmb3IgcHJvY2VzcyBleGVjdXRpb25zLCBkZWZhdWx0cyB0byAzMDAgKDVtaW5zKS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInVzZS1pbmNsdWRlLXBhdGgiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHRydWUsIHRoZSBDb21wb3NlciBhdXRvbG9hZGVyIHdpbGwgYWxzbyBsb29rIGZvciBjbGFzc2VzIGluIHRoZSBQSFAgaW5jbHVkZSBwYXRoLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAidXNlLXBhcmVudC1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbInN0cmluZyIsICJib29sZWFuIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIldoZW4gcnVubmluZyBDb21wb3NlciBpbiBhIGRpcmVjdG9yeSB3aGVyZSB0aGVyZSBpcyBubyBjb21wb3Nlci5qc29uLCBpZiB0aGVyZSBpcyBvbmUgcHJlc2VudCBpbiBhIGRpcmVjdG9yeSBhYm92ZSBDb21wb3NlciB3aWxsIGJ5IGRlZmF1bHQgYXNrIHlvdSB3aGV0aGVyIHlvdSB3YW50IHRvIHVzZSB0aGF0IGRpcmVjdG9yeSdzIGNvbXBvc2VyLmpzb24gaW5zdGVhZC4gT25lIG9mOiB0cnVlIChhbHdheXMgdXNlIHBhcmVudCBpZiBuZWVkZWQpLCBmYWxzZSAobmV2ZXIgYXNrIG9yIHVzZSBpdCkgb3IgXCJwcm9tcHRcIiAoYXNrIGV2ZXJ5IHRpbWUpLCBkZWZhdWx0cyB0byBwcm9tcHQuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcmVmZXJyZWQtaW5zdGFsbCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgIm9iamVjdCJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgaW5zdGFsbCBtZXRob2QgQ29tcG9zZXIgd2lsbCBwcmVmZXIgdG8gdXNlLCBkZWZhdWx0cyB0byBhdXRvIGFuZCBjYW4gYmUgYW55IG9mIHNvdXJjZSwgZGlzdCwgYXV0bywgb3IgYW4gb2JqZWN0IG9mIHtcInBhdHRlcm5cIjogXCJwcmVmZXJlbmNlXCJ9LiIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIl0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm5vdGlmeS1vbi1pbnN0YWxsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJDb21wb3NlciBhbGxvd3MgcmVwb3NpdG9yaWVzIHRvIGRlZmluZSBhIG5vdGlmaWNhdGlvbiBVUkwsIHNvIHRoYXQgdGhleSBnZXQgbm90aWZpZWQgd2hlbmV2ZXIgYSBwYWNrYWdlIGZyb20gdGhhdCByZXBvc2l0b3J5IGlzIGluc3RhbGxlZC4gVGhpcyBvcHRpb24gYWxsb3dzIHlvdSB0byBkaXNhYmxlIHRoYXQgYmVoYXZpb3VyLCBkZWZhdWx0cyB0byB0cnVlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZ2l0aHViLXByb3RvY29scyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgbGlzdCBvZiBwcm90b2NvbHMgdG8gdXNlIGZvciBnaXRodWIuY29tIGNsb25lcywgaW4gcHJpb3JpdHkgb3JkZXIsIGRlZmF1bHRzIHRvIFtcImdpdFwiLCBcImh0dHBzXCIsIFwiaHR0cFwiXS4iLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZ2l0aHViLW9hdXRoIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkFuIG9iamVjdCBvZiBkb21haW4gbmFtZSA9PiBnaXRodWIgQVBJIG9hdXRoIHRva2VucywgdHlwaWNhbGx5IHtcImdpdGh1Yi5jb21cIjpcIjx0b2tlbj5cIn0uIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImdpdGxhYi1vYXV0aCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBbiBvYmplY3Qgb2YgZG9tYWluIG5hbWUgPT4gZ2l0bGFiIEFQSSBvYXV0aCB0b2tlbnMsIHR5cGljYWxseSB7XCJnaXRsYWIuY29tXCI6XCI8dG9rZW4+XCJ9LiIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJnaXRsYWItdG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQW4gb2JqZWN0IG9mIGRvbWFpbiBuYW1lID0+IGdpdGxhYiBwcml2YXRlIHRva2VucywgdHlwaWNhbGx5IHtcImdpdGxhYi5jb21cIjpcIjx0b2tlbj5cIn0uIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImdpdGxhYi1wcm90b2NvbCI6IHsKICAgICAgICAgICAgICAgICAgICAiZW51bSI6IFsiZ2l0IiwgImh0dHAiLCAiaHR0cHMiXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBwcm90b2NvbCB0byBmb3JjZSB1c2Ugb2Ygd2hlbiBjcmVhdGluZyBhIHJlcG9zaXRvcnkgVVJMIGZvciB0aGUgYHNvdXJjZWAgdmFsdWUgb2YgdGhlIHBhY2thZ2UgbWV0YWRhdGEuIE9uZSBvZiBgZ2l0YCBvciBgaHR0cGAuIEJ5IGRlZmF1bHQsIENvbXBvc2VyIHdpbGwgZ2VuZXJhdGUgYSBnaXQgVVJMIGZvciBwcml2YXRlIHJlcG9zaXRvcmllcyBhbmQgaHR0cCBvbmUgZm9yIHB1YmxpYyByZXBvcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImJlYXJlciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBbiBvYmplY3Qgb2YgZG9tYWluIG5hbWUgPT4gYmVhcmVyIGF1dGhlbnRpY2F0aW9uIHRva2VuLCBmb3IgZXhhbXBsZSB7XCJleGFtcGxlLmNvbVwiOlwiPHRva2VuPlwifS4iLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGlzYWJsZS10bHMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIGBmYWxzZWAuIElmIHNldCB0byB0cnVlIGFsbCBIVFRQUyBVUkxzIHdpbGwgYmUgdHJpZWQgd2l0aCBIVFRQIGluc3RlYWQgYW5kIG5vIG5ldHdvcmsgbGV2ZWwgZW5jcnlwdGlvbiBpcyBwZXJmb3JtZWQuIEVuYWJsaW5nIHRoaXMgaXMgYSBzZWN1cml0eSByaXNrIGFuZCBpcyBOT1QgcmVjb21tZW5kZWQuIFRoZSBiZXR0ZXIgd2F5IGlzIHRvIGVuYWJsZSB0aGUgcGhwX29wZW5zc2wgZXh0ZW5zaW9uIGluIHBocC5pbmkuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJzZWN1cmUtaHR0cCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGVmYXVsdHMgdG8gYHRydWVgLiBJZiBzZXQgdG8gdHJ1ZSBvbmx5IEhUVFBTIFVSTHMgYXJlIGFsbG93ZWQgdG8gYmUgZG93bmxvYWRlZCB2aWEgQ29tcG9zZXIuIElmIHlvdSByZWFsbHkgYWJzb2x1dGVseSBuZWVkIEhUVFAgYWNjZXNzIHRvIHNvbWV0aGluZyB0aGVuIHlvdSBjYW4gZGlzYWJsZSBpdCwgYnV0IHVzaW5nIFwiTGV0J3MgRW5jcnlwdFwiIHRvIGdldCBhIGZyZWUgU1NMIGNlcnRpZmljYXRlIGlzIGdlbmVyYWxseSBhIGJldHRlciBhbHRlcm5hdGl2ZS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInNlY3VyZS1zdm4tZG9tYWlucyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgbGlzdCBvZiBkb21haW5zIHdoaWNoIHNob3VsZCBiZSB0cnVzdGVkL21hcmtlZCBhcyB1c2luZyBhIHNlY3VyZSBTdWJ2ZXJzaW9uL1NWTiB0cmFuc3BvcnQuIEJ5IGRlZmF1bHQgc3ZuOi8vIHByb3RvY29sIGlzIHNlZW4gYXMgaW5zZWN1cmUgYW5kIHdpbGwgdGhyb3cuIFRoaXMgaXMgYSBiZXR0ZXIvc2FmZXIgYWx0ZXJuYXRpdmUgdG8gZGlzYWJsaW5nIGBzZWN1cmUtaHR0cGAgYWx0b2dldGhlci4iLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY2FmaWxlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgd2F5IHRvIHNldCB0aGUgcGF0aCB0byB0aGUgb3BlbnNzbCBDQSBmaWxlLiBJbiBQSFAgNS42KyB5b3Ugc2hvdWxkIHJhdGhlciBzZXQgdGhpcyB2aWEgb3BlbnNzbC5jYWZpbGUgaW4gcGhwLmluaSwgYWx0aG91Z2ggUEhQIDUuNisgc2hvdWxkIGJlIGFibGUgdG8gZGV0ZWN0IHlvdXIgc3lzdGVtIENBIGZpbGUgYXV0b21hdGljYWxseS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNhcGF0aCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiBjYWZpbGUgaXMgbm90IHNwZWNpZmllZCBvciBpZiB0aGUgY2VydGlmaWNhdGUgaXMgbm90IGZvdW5kIHRoZXJlLCB0aGUgZGlyZWN0b3J5IHBvaW50ZWQgdG8gYnkgY2FwYXRoIGlzIHNlYXJjaGVkIGZvciBhIHN1aXRhYmxlIGNlcnRpZmljYXRlLiBjYXBhdGggbXVzdCBiZSBhIGNvcnJlY3RseSBoYXNoZWQgY2VydGlmaWNhdGUgZGlyZWN0b3J5LiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiaHR0cC1iYXNpYyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBbiBvYmplY3Qgb2YgZG9tYWluIG5hbWUgPT4ge1widXNlcm5hbWVcIjogXCIuLi5cIiwgXCJwYXNzd29yZFwiOiBcIi4uLlwifS4iLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInJlcXVpcmVkIjogWyJ1c2VybmFtZSIsICJwYXNzd29yZCJdLAogICAgICAgICAgICAgICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1c2VybmFtZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgdXNlcm5hbWUgdXNlZCBmb3IgSFRUUCBCYXNpYyBhdXRoZW50aWNhdGlvbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGFzc3dvcmQiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIHBhc3N3b3JkIHVzZWQgZm9yIEhUVFAgQmFzaWMgYXV0aGVudGljYXRpb24iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInN0b3JlLWF1dGhzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYm9vbGVhbiJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJXaGF0IHRvIGRvIGFmdGVyIHByb21wdGluZyBmb3IgYXV0aGVudGljYXRpb24sIG9uZSBvZjogdHJ1ZSAoc3RvcmUpLCBmYWxzZSAoZG8gbm90IHN0b3JlKSBvciBcInByb21wdFwiIChhc2sgZXZlcnkgdGltZSksIGRlZmF1bHRzIHRvIHByb21wdC4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInZlbmRvci1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGxvY2F0aW9uIHdoZXJlIGFsbCBwYWNrYWdlcyBhcmUgaW5zdGFsbGVkLCBkZWZhdWx0cyB0byBcInZlbmRvclwiLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYmluLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgYWxsIGJpbmFyaWVzIGFyZSBsaW5rZWQsIGRlZmF1bHRzIHRvIFwidmVuZG9yL2JpblwiLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGF0YS1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGxvY2F0aW9uIHdoZXJlIG9sZCBwaGFyIGZpbGVzIGFyZSBzdG9yZWQsIGRlZmF1bHRzIHRvIFwiJGhvbWVcIiBleGNlcHQgb24gWERHIEJhc2UgRGlyZWN0b3J5IGNvbXBsaWFudCB1bml4ZXMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGxvY2F0aW9uIHdoZXJlIGFsbCBjYWNoZXMgYXJlIGxvY2F0ZWQsIGRlZmF1bHRzIHRvIFwifi8uY29tcG9zZXIvY2FjaGVcIiBvbiAqbml4IGFuZCBcIiVMT0NBTEFQUERBVEElXFxDb21wb3NlclwiIG9uIHdpbmRvd3MuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS1maWxlcy1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGxvY2F0aW9uIHdoZXJlIGZpbGVzICh6aXAgZG93bmxvYWRzKSBhcmUgY2FjaGVkLCBkZWZhdWx0cyB0byBcInskY2FjaGUtZGlyfS9maWxlc1wiLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY2FjaGUtcmVwby1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGxvY2F0aW9uIHdoZXJlIHJlcG8gKGdpdC9oZyByZXBvIGNsb25lcykgYXJlIGNhY2hlZCwgZGVmYXVsdHMgdG8gXCJ7JGNhY2hlLWRpcn0vcmVwb1wiLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY2FjaGUtdmNzLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgdmNzIGluZm9zIChnaXQgY2xvbmVzLCBnaXRodWIgYXBpIGNhbGxzLCBldGMuIHdoZW4gcmVhZGluZyB2Y3MgcmVwb3MpIGFyZSBjYWNoZWQsIGRlZmF1bHRzIHRvIFwieyRjYWNoZS1kaXJ9L3Zjc1wiLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY2FjaGUtdHRsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImludGVnZXIiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgZGVmYXVsdCBjYWNoZSB0aW1lLXRvLWxpdmUsIGRlZmF1bHRzIHRvIDE1NTUyMDAwICg2IG1vbnRocykuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS1maWxlcy10dGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBjYWNoZSB0aW1lLXRvLWxpdmUgZm9yIGZpbGVzLCBkZWZhdWx0cyB0byB0aGUgdmFsdWUgb2YgY2FjaGUtdHRsLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY2FjaGUtZmlsZXMtbWF4c2l6ZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImludGVnZXIiXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGNhY2hlIG1heCBzaXplIGZvciB0aGUgZmlsZXMgY2FjaGUsIGRlZmF1bHRzIHRvIFwiMzAwTWlCXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS1yZWFkLW9ubHkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImJvb2xlYW4iXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2hldGhlciB0byB1c2UgdGhlIENvbXBvc2VyIGNhY2hlIGluIHJlYWQtb25seSBtb2RlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYmluLWNvbXBhdCI6IHsKICAgICAgICAgICAgICAgICAgICAiZW51bSI6IFsiYXV0byIsICJmdWxsIiwgInByb3h5IiwgInN5bWxpbmsiXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGNvbXBhdGliaWxpdHkgb2YgdGhlIGJpbmFyaWVzLCBkZWZhdWx0cyB0byBcImF1dG9cIiAoYXV0b21hdGljYWxseSBndWVzc2VkKSwgY2FuIGJlIFwiZnVsbFwiIChjb21wYXRpYmxlIHdpdGggYm90aCBXaW5kb3dzIGFuZCBVbml4LWJhc2VkIHN5c3RlbXMpIGFuZCBcInByb3h5XCIgKG9ubHkgYmFzaC1zdHlsZSBwcm94eSkuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJkaXNjYXJkLWNoYW5nZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbInN0cmluZyIsICJib29sZWFuIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBkZWZhdWx0IHN0eWxlIG9mIGhhbmRsaW5nIGRpcnR5IHVwZGF0ZXMsIGRlZmF1bHRzIHRvIGZhbHNlIGFuZCBjYW4gYmUgYW55IG9mIHRydWUsIGZhbHNlIG9yIFwic3Rhc2hcIi4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImF1dG9sb2FkZXItc3VmZml4IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9wdGlvbmFsIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgc3VmZml4IGZvciB0aGUgZ2VuZXJhdGVkIENvbXBvc2VyIGF1dG9sb2FkZXIuIFdoZW4gbnVsbCBhIHJhbmRvbSBvbmUgd2lsbCBiZSBnZW5lcmF0ZWQuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJvcHRpbWl6ZS1hdXRvbG9hZGVyIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBbHdheXMgb3B0aW1pemUgd2hlbiBkdW1waW5nIHRoZSBhdXRvbG9hZGVyLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJlcGVuZC1hdXRvbG9hZGVyIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiBmYWxzZSwgdGhlIGNvbXBvc2VyIGF1dG9sb2FkZXIgd2lsbCBub3QgYmUgcHJlcGVuZGVkIHRvIGV4aXN0aW5nIGF1dG9sb2FkZXJzLCBkZWZhdWx0cyB0byB0cnVlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiSWYgdHJ1ZSwgdGhlIGNvbXBvc2VyIGF1dG9sb2FkZXIgd2lsbCBub3Qgc2NhbiB0aGUgZmlsZXN5c3RlbSBmb3IgY2xhc3NlcyB0aGF0IGFyZSBub3QgZm91bmQgaW4gdGhlIGNsYXNzIG1hcCwgZGVmYXVsdHMgdG8gZmFsc2UuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJhcGN1LWF1dG9sb2FkZXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHRydWUsIHRoZSBDb21wb3NlciBhdXRvbG9hZGVyIHdpbGwgY2hlY2sgZm9yIEFQQ3UgYW5kIHVzZSBpdCB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3NlcyB3aGVuIHRoZSBleHRlbnNpb24gaXMgZW5hYmxlZCwgZGVmYXVsdHMgdG8gZmFsc2UuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJnaXRodWItZG9tYWlucyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgbGlzdCBvZiBkb21haW5zIHRvIHVzZSBpbiBnaXRodWIgbW9kZS4gVGhpcyBpcyB1c2VkIGZvciBHaXRIdWIgRW50ZXJwcmlzZSBzZXR1cHMsIGRlZmF1bHRzIHRvIFtcImdpdGh1Yi5jb21cIl0uIiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImdpdGh1Yi1leHBvc2UtaG9zdG5hbWUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIHRydWUuIElmIHNldCB0byBmYWxzZSwgdGhlIE9BdXRoIHRva2VucyBjcmVhdGVkIHRvIGFjY2VzcyB0aGUgZ2l0aHViIEFQSSB3aWxsIGhhdmUgYSBkYXRlIGluc3RlYWQgb2YgdGhlIG1hY2hpbmUgaG9zdG5hbWUuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJnaXRsYWItZG9tYWlucyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgbGlzdCBvZiBkb21haW5zIHRvIHVzZSBpbiBnaXRsYWIgbW9kZS4gVGhpcyBpcyB1c2VkIGZvciBjdXN0b20gR2l0TGFiIHNldHVwcywgZGVmYXVsdHMgdG8gW1wiZ2l0bGFiLmNvbVwiXS4iLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAidXNlLWdpdGh1Yi1hcGkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIHRydWUuICBJZiBzZXQgdG8gZmFsc2UsIGdsb2JhbGx5IGRpc2FibGVzIHRoZSB1c2Ugb2YgdGhlIEdpdEh1YiBBUEkgZm9yIGFsbCBHaXRIdWIgcmVwb3NpdG9yaWVzIGFuZCBjbG9uZXMgdGhlIHJlcG9zaXRvcnkgYXMgaXQgd291bGQgZm9yIGFueSBvdGhlciByZXBvc2l0b3J5LiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYXJjaGl2ZS1mb3JtYXQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGRlZmF1bHQgYXJjaGl2aW5nIGZvcm1hdCB3aGVuIG5vdCBwcm92aWRlZCBvbiBjbGksIGRlZmF1bHRzIHRvIFwidGFyXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJhcmNoaXZlLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgZGVmYXVsdCBhcmNoaXZlIHBhdGggd2hlbiBub3QgcHJvdmlkZWQgb24gY2xpLCBkZWZhdWx0cyB0byBcIi5cIi4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImh0YWNjZXNzLXByb3RlY3QiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIHRydWUuIElmIHNldCB0byBmYWxzZSwgQ29tcG9zZXIgd2lsbCBub3QgY3JlYXRlIC5odGFjY2VzcyBmaWxlcyBpbiB0aGUgY29tcG9zZXIgaG9tZSwgY2FjaGUsIGFuZCBkYXRhIGRpcmVjdG9yaWVzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAic29ydC1wYWNrYWdlcyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGVmYXVsdHMgdG8gZmFsc2UuIElmIHNldCB0byB0cnVlLCBDb21wb3NlciB3aWxsIHNvcnQgcGFja2FnZXMgd2hlbiBhZGRpbmcvdXBkYXRpbmcgYSBuZXcgZGVwZW5kZW5jeS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImxvY2siOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIHRydWUuIElmIHNldCB0byBmYWxzZSwgQ29tcG9zZXIgd2lsbCBub3QgY3JlYXRlIGEgY29tcG9zZXIubG9jayBmaWxlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicGxhdGZvcm0tY2hlY2siOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImJvb2xlYW4iLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIFwicGhwLW9ubHlcIiB3aGljaCBjaGVja3Mgb25seSB0aGUgUEhQIHZlcnNpb24uIFNldHRpbmcgdG8gdHJ1ZSB3aWxsIGFsc28gY2hlY2sgdGhlIHByZXNlbmNlIG9mIHJlcXVpcmVkIFBIUCBleHRlbnNpb25zLiBJZiBzZXQgdG8gZmFsc2UsIENvbXBvc2VyIHdpbGwgbm90IGNyZWF0ZSBhbmQgcmVxdWlyZSBhIHBsYXRmb3JtX2NoZWNrLnBocCBmaWxlIGFzIHBhcnQgb2YgdGhlIGF1dG9sb2FkZXIgYm9vdHN0cmFwLiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImV4dHJhIjogewogICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0IiwgImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBcmJpdHJhcnkgZXh0cmEgZGF0YSB0aGF0IGNhbiBiZSB1c2VkIGJ5IHBsdWdpbnMsIGZvciBleGFtcGxlLCBwYWNrYWdlIG9mIHR5cGUgY29tcG9zZXItcGx1Z2luIG1heSBoYXZlIGEgJ2NsYXNzJyBrZXkgZGVmaW5pbmcgYW4gaW5zdGFsbGVyIGNsYXNzIG5hbWUuIiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInNjcmlwdHMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogWyJvYmplY3QiXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlNjcmlwdCBsaXN0ZW5lcnMgdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGJlZm9yZS9hZnRlciBzb21lIGV2ZW50cy4iLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJwcmUtaW5zdGFsbC1jbWQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYmVmb3JlIHRoZSBpbnN0YWxsIGNvbW1hbmQgaXMgZXhlY3V0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC1pbnN0YWxsLWNtZCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciB0aGUgaW5zdGFsbCBjb21tYW5kIGlzIGV4ZWN1dGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInByZS11cGRhdGUtY21kIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJhcnJheSIsICJzdHJpbmciXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2NjdXJzIGJlZm9yZSB0aGUgdXBkYXRlIGNvbW1hbmQgaXMgZXhlY3V0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC11cGRhdGUtY21kIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJhcnJheSIsICJzdHJpbmciXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2NjdXJzIGFmdGVyIHRoZSB1cGRhdGUgY29tbWFuZCBpcyBleGVjdXRlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcmUtc3RhdHVzLWNtZCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBiZWZvcmUgdGhlIHN0YXR1cyBjb21tYW5kIGlzIGV4ZWN1dGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBvc3Qtc3RhdHVzLWNtZCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciB0aGUgc3RhdHVzIGNvbW1hbmQgaXMgZXhlY3V0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJlLXBhY2thZ2UtaW5zdGFsbCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBiZWZvcmUgYSBwYWNrYWdlIGlzIGluc3RhbGxlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwb3N0LXBhY2thZ2UtaW5zdGFsbCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciBhIHBhY2thZ2UgaXMgaW5zdGFsbGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInByZS1wYWNrYWdlLXVwZGF0ZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBiZWZvcmUgYSBwYWNrYWdlIGlzIHVwZGF0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC1wYWNrYWdlLXVwZGF0ZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciBhIHBhY2thZ2UgaXMgdXBkYXRlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcmUtcGFja2FnZS11bmluc3RhbGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYmVmb3JlIGEgcGFja2FnZSBoYXMgYmVlbiB1bmluc3RhbGxlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwb3N0LXBhY2thZ2UtdW5pbnN0YWxsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJhcnJheSIsICJzdHJpbmciXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2NjdXJzIGFmdGVyIGEgcGFja2FnZSBoYXMgYmVlbiB1bmluc3RhbGxlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcmUtYXV0b2xvYWQtZHVtcCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBiZWZvcmUgdGhlIGF1dG9sb2FkZXIgaXMgZHVtcGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBvc3QtYXV0b2xvYWQtZHVtcCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciB0aGUgYXV0b2xvYWRlciBpcyBkdW1wZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC1yb290LXBhY2thZ2UtaW5zdGFsbCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciB0aGUgcm9vdC1wYWNrYWdlIGlzIGluc3RhbGxlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwb3N0LWNyZWF0ZS1wcm9qZWN0LWNtZCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciB0aGUgY3JlYXRlLXByb2plY3QgY29tbWFuZCBpcyBleGVjdXRlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2NyaXB0cy1kZXNjcmlwdGlvbnMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogWyJvYmplY3QiXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlc2NyaXB0aW9ucyBmb3IgY3VzdG9tIGNvbW1hbmRzLCBzaG93biBpbiBjb25zb2xlIGhlbHAuIiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKICAgICJkZWZpbml0aW9ucyI6IHsKICAgICAgICAiYXV0aG9ycyI6IHsKICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiTGlzdCBvZiBhdXRob3JzIHRoYXQgY29udHJpYnV0ZWQgdG8gdGhlIHBhY2thZ2UuIFRoaXMgaXMgdHlwaWNhbGx5IHRoZSBtYWluIG1haW50YWluZXJzLCBub3QgdGhlIGZ1bGwgbGlzdC4iLAogICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogZmFsc2UsCiAgICAgICAgICAgICAgICAicmVxdWlyZWQiOiBbICJuYW1lIl0sCiAgICAgICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAibmFtZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZ1bGwgbmFtZSBvZiB0aGUgYXV0aG9yLiIKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICJlbWFpbCI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkVtYWlsIGFkZHJlc3Mgb2YgdGhlIGF1dGhvci4iLAogICAgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogImVtYWlsIgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgImhvbWVwYWdlIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiSG9tZXBhZ2UgVVJMIGZvciB0aGUgYXV0aG9yLiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJmb3JtYXQiOiAidXJpIgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgInJvbGUiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBdXRob3IncyByb2xlIGluIHRoZSBwcm9qZWN0LiIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJhdXRvbG9hZCI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlc2NyaXB0aW9uIG9mIGhvdyB0aGUgcGFja2FnZSBjYW4gYmUgYXV0b2xvYWRlZC4iLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJwc3ItMCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGFuIG9iamVjdCBvZiBuYW1lc3BhY2VzIChrZXlzKSBhbmQgdGhlIGRpcmVjdG9yaWVzIHRoZXkgY2FuIGJlIGZvdW5kIGluICh2YWx1ZXMsIGNhbiBiZSBhcnJheXMgb2YgcGF0aHMpIGJ5IHRoZSBhdXRvbG9hZGVyLiIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImFycmF5Il0sCiAgICAgICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHNyLTQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBvYmplY3Qgb2YgbmFtZXNwYWNlcyAoa2V5cykgYW5kIHRoZSBQU1ItNCBkaXJlY3RvcmllcyB0aGV5IGNhbiBtYXAgdG8gKHZhbHVlcywgY2FuIGJlIGFycmF5cyBvZiBwYXRocykgYnkgdGhlIGF1dG9sb2FkZXIuIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYXJyYXkiXSwKICAgICAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjbGFzc21hcCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gYXJyYXkgb2YgcGF0aHMgdGhhdCBjb250YWluIGNsYXNzZXMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIGNsYXNzLW1hcCBnZW5lcmF0aW9uIHByb2Nlc3MuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJmaWxlcyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gYXJyYXkgb2YgZmlsZXMgdGhhdCBhcmUgYWx3YXlzIHJlcXVpcmVkIG9uIGV2ZXJ5IHJlcXVlc3QuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlLWZyb20tY2xhc3NtYXAiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGFuIGFycmF5IG9mIHBhdHRlcm5zIHRvIGV4Y2x1ZGUgZnJvbSBhdXRvbG9hZCBjbGFzc21hcCBnZW5lcmF0aW9uLiAoZS5nLiBcImV4Y2x1ZGUtZnJvbS1jbGFzc21hcFwiOiBbXCIvdGVzdC9cIiwgXCIvdGVzdHMvXCIsIFwiL1Rlc3RzL1wiXSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInJlcG9zaXRvcnkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9jb21wb3Nlci1yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3Zjcy1yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3BhdGgtcmVwb3NpdG9yeSIgfSwKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9hcnRpZmFjdC1yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3BlYXItcmVwb3NpdG9yeSIgfSwKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wYWNrYWdlLXJlcG9zaXRvcnkiIH0KICAgICAgICAgICAgXQogICAgICAgIH0sCiAgICAgICAgImNvbXBvc2VyLXJlcG9zaXRvcnkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IFsidHlwZSIsICJ1cmwiXSwKICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6IHsgInR5cGUiOiAic3RyaW5nIiwgImVudW0iOiBbImNvbXBvc2VyIl0gfSwKICAgICAgICAgICAgICAgICJ1cmwiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJjYW5vbmljYWwiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAib25seSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB0cnVlCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImFsbG93X3NzbF9kb3duZ3JhZGUiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAiZm9yY2UtbGF6eS1wcm92aWRlcnMiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInZjcy1yZXBvc2l0b3J5IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAicmVxdWlyZWQiOiBbInR5cGUiLCAidXJsIl0sCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJlbnVtIjogWyJ2Y3MiLCAiZ2l0aHViIiwgImdpdCIsICJnaXRsYWIiLCAiYml0YnVja2V0IiwgImdpdC1iaXRidWNrZXQiLCAiaGciLCAiZm9zc2lsIiwgInBlcmZvcmNlIiwgInN2biJdIH0sCiAgICAgICAgICAgICAgICAidXJsIjogeyAidHlwZSI6ICJzdHJpbmciIH0sCiAgICAgICAgICAgICAgICAiY2Fub25pY2FsIjogeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgIm9ubHkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXhjbHVkZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJuby1hcGkiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAic2VjdXJlLWh0dHAiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAic3ZuLWNhY2hlLWNyZWRlbnRpYWxzIjogeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgInRydW5rLXBhdGgiOiB7ICJ0eXBlIjogWyJzdHJpbmciLCAiYm9vbGVhbiJdIH0sCiAgICAgICAgICAgICAgICAiYnJhbmNoZXMtcGF0aCI6IHsgInR5cGUiOiBbInN0cmluZyIsICJib29sZWFuIl0gfSwKICAgICAgICAgICAgICAgICJ0YWdzLXBhdGgiOiB7ICJ0eXBlIjogWyJzdHJpbmciLCAiYm9vbGVhbiJdIH0sCiAgICAgICAgICAgICAgICAicGFja2FnZS1wYXRoIjogeyAidHlwZSI6ICJzdHJpbmciIH0sCiAgICAgICAgICAgICAgICAiZGVwb3QiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJicmFuY2giOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJ1bmlxdWVfcGVyZm9yY2VfY2xpZW50X25hbWUiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJwNHVzZXIiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJwNHBhc3N3b3JkIjogeyAidHlwZSI6ICJzdHJpbmciIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInBhdGgtcmVwb3NpdG9yeSI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgInJlcXVpcmVkIjogWyJ0eXBlIiwgInVybCJdLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogeyAidHlwZSI6ICJzdHJpbmciLCAiZW51bSI6IFsicGF0aCJdIH0sCiAgICAgICAgICAgICAgICAidXJsIjogeyAidHlwZSI6ICJzdHJpbmciIH0sCiAgICAgICAgICAgICAgICAiY2Fub25pY2FsIjogeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgIm9ubHkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXhjbHVkZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJvcHRpb25zIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJzeW1saW5rIjogeyAidHlwZSI6IFsiYm9vbGVhbiIsICJudWxsIl0gfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiYXJ0aWZhY3QtcmVwb3NpdG9yeSI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgInJlcXVpcmVkIjogWyJ0eXBlIiwgInVybCJdLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogeyAidHlwZSI6ICJzdHJpbmciLCAiZW51bSI6IFsiYXJ0aWZhY3QiXSB9LAogICAgICAgICAgICAgICAgInVybCI6IHsgInR5cGUiOiAic3RyaW5nIiB9LAogICAgICAgICAgICAgICAgImNhbm9uaWNhbCI6IHsgInR5cGUiOiAiYm9vbGVhbiIgfSwKICAgICAgICAgICAgICAgICJvbmx5IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImV4Y2x1ZGUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInBlYXItcmVwb3NpdG9yeSI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgInJlcXVpcmVkIjogWyJ0eXBlIiwgInVybCJdLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogeyAidHlwZSI6ICJzdHJpbmciLCAiZW51bSI6IFsicGVhciJdIH0sCiAgICAgICAgICAgICAgICAidXJsIjogeyAidHlwZSI6ICJzdHJpbmciIH0sCiAgICAgICAgICAgICAgICAiY2Fub25pY2FsIjogeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgIm9ubHkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXhjbHVkZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJ2ZW5kb3ItYWxpYXMiOiB7ICJ0eXBlIjogInN0cmluZyIgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicGFja2FnZS1yZXBvc2l0b3J5IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAicmVxdWlyZWQiOiBbInR5cGUiLCAicGFja2FnZSJdLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogeyAidHlwZSI6ICJzdHJpbmciLCAiZW51bSI6IFsicGFja2FnZSJdIH0sCiAgICAgICAgICAgICAgICAiY2Fub25pY2FsIjogeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgIm9ubHkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXhjbHVkZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwYWNrYWdlIjogewogICAgICAgICAgICAgICAgICAgICJvbmVPZiI6IFsKICAgICAgICAgICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL2lubGluZS1wYWNrYWdlIiB9LAogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvaW5saW5lLXBhY2thZ2UiIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImlubGluZS1wYWNrYWdlIjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAicmVxdWlyZWQiOiBbIm5hbWUiLCAidmVyc2lvbiJdLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJuYW1lIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhY2thZ2UgbmFtZSwgaW5jbHVkaW5nICd2ZW5kb3ItbmFtZS8nIHByZWZpeC4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJ0YXJnZXQtZGlyIjogewogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJERVBSRUNBVEVEOiBGb3JjZXMgdGhlIHBhY2thZ2UgdG8gYmUgaW5zdGFsbGVkIGludG8gdGhlIGdpdmVuIHN1YmRpcmVjdG9yeSBwYXRoLiBUaGlzIGlzIHVzZWQgZm9yIGF1dG9sb2FkaW5nIFBTUi0wIHBhY2thZ2VzIHRoYXQgZG8gbm90IGNvbnRhaW4gdGhlaXIgZnVsbCBwYXRoLiBVc2UgZm9yd2FyZCBzbGFzaGVzIGZvciBjcm9zcy1wbGF0Zm9ybSBjb21wYXRpYmlsaXR5LiIsCiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImtleXdvcmRzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImhvbWVwYWdlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInZlcnNpb24iOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJ0aW1lIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAibGljZW5zZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsKICAgICAgICAgICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJhcnJheSIKICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImF1dGhvcnMiOiB7CiAgICAgICAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9hdXRob3JzIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJyZXF1aXJlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJyZXBsYWNlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjb25mbGljdCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJvdmlkZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicmVxdWlyZS1kZXYiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInN1Z2dlc3QiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImV4dHJhIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJvYmplY3QiLCAiYXJyYXkiXSwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB0cnVlCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImF1dG9sb2FkIjogewogICAgICAgICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvYXV0b2xvYWQiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImFyY2hpdmUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbIm9iamVjdCJdLAogICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAiZXhjbHVkZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJiaW4iOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbInN0cmluZyIsICJhcnJheSJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHNldCBvZiBmaWxlcywgb3IgYSBzaW5nbGUgZmlsZSwgdGhhdCBzaG91bGQgYmUgdHJlYXRlZCBhcyBiaW5hcmllcyBhbmQgc3ltbGlua2VkIGludG8gYmluLWRpciAoZnJvbSBjb25maWcpLiIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJpbmNsdWRlLXBhdGgiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5Il0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRFUFJFQ0FURUQ6IEEgbGlzdCBvZiBkaXJlY3RvcmllcyB3aGljaCBzaG91bGQgZ2V0IGFkZGVkIHRvIFBIUCdzIGluY2x1ZGUgcGF0aC4gVGhpcyBpcyBvbmx5IHByZXNlbnQgdG8gc3VwcG9ydCBsZWdhY3kgcHJvamVjdHMsIGFuZCBhbGwgbmV3IGNvZGUgc2hvdWxkIHByZWZlcmFibHkgdXNlIGF1dG9sb2FkaW5nLiIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJzb3VyY2UiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAicmVxdWlyZWQiOiBbInR5cGUiLCAidXJsIiwgInJlZmVyZW5jZSJdLAogICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgInVybCI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgInJlZmVyZW5jZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgIm1pcnJvcnMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGlzdCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJyZXF1aXJlZCI6IFsidHlwZSIsICJ1cmwiXSwKICAgICAgICAgICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICJ1cmwiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICJyZWZlcmVuY2UiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICJzaGFzdW0iOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICJtaXJyb3JzIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHRydWUKICAgICAgICB9CiAgICB9Cn0KIyMKIyMgQnVuZGxlIG9mIENBIFJvb3QgQ2VydGlmaWNhdGVzCiMjCiMjIENlcnRpZmljYXRlIGRhdGEgZnJvbSBNb3ppbGxhIGFzIG9mOiBUdWUgSmFuIDE5IDA0OjEyOjA0IDIwMjEgR01UCiMjCiMjIFRoaXMgaXMgYSBidW5kbGUgb2YgWC41MDkgY2VydGlmaWNhdGVzIG9mIHB1YmxpYyBDZXJ0aWZpY2F0ZSBBdXRob3JpdGllcwojIyAoQ0EpLiBUaGVzZSB3ZXJlIGF1dG9tYXRpY2FsbHkgZXh0cmFjdGVkIGZyb20gTW96aWxsYSdzIHJvb3QgY2VydGlmaWNhdGVzCiMjIGZpbGUgKGNlcnRkYXRhLnR4dCkuICBUaGlzIGZpbGUgY2FuIGJlIGZvdW5kIGluIHRoZSBtb3ppbGxhIHNvdXJjZSB0cmVlOgojIyBodHRwczovL2hnLm1vemlsbGEub3JnL3JlbGVhc2VzL21vemlsbGEtcmVsZWFzZS9yYXctZmlsZS9kZWZhdWx0L3NlY3VyaXR5L25zcy9saWIvY2tmdy9idWlsdGlucy9jZXJ0ZGF0YS50eHQKIyMKIyMgSXQgY29udGFpbnMgdGhlIGNlcnRpZmljYXRlcyBpbiBQRU0gZm9ybWF0IGFuZCB0aGVyZWZvcmUKIyMgY2FuIGJlIGRpcmVjdGx5IHVzZWQgd2l0aCBjdXJsIC8gbGliY3VybCAvIHBocF9jdXJsLCBvciB3aXRoCiMjIGFuIEFwYWNoZSttb2Rfc3NsIHdlYnNlcnZlciBmb3IgU1NMIGNsaWVudCBhdXRoZW50aWNhdGlvbi4KIyMgSnVzdCBjb25maWd1cmUgdGhpcyBmaWxlIGFzIHRoZSBTU0xDQUNlcnRpZmljYXRlRmlsZS4KIyMKIyMgQ29udmVyc2lvbiBkb25lIHdpdGggbWstY2EtYnVuZGxlLnBsIHZlcnNpb24gMS4yOC4KIyMgU0hBMjU2OiAzYmRjNjNkMWRlMjcwNThmZWM5NDNhOTk5YTJhOGEwMWZjYzY4MDZhNjExYjE5MjIxYTc3MjdkM2Q5YmJiZGZkCiMjCgoKR2xvYmFsU2lnbiBSb290IENBCj09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGRUQ0NBbDJnQXdJQkFnSUxCQUFBQUFBQkZVdGF3NVF3RFFZSktvWklodmNOQVFFRkJRQXdWekVMTUFrR0ExVUVCaE1DUWtVeApHVEFYQmdOVkJBb1RFRWRzYjJKaGJGTnBaMjRnYm5ZdGMyRXhFREFPQmdOVkJBc1RCMUp2YjNRZ1EwRXhHekFaQmdOVkJBTVRFa2RzCmIySmhiRk5wWjI0Z1VtOXZkQ0JEUVRBZUZ3MDVPREE1TURFeE1qQXdNREJhRncweU9EQXhNamd4TWpBd01EQmFNRmN4Q3pBSkJnTlYKQkFZVEFrSkZNUmt3RndZRFZRUUtFeEJIYkc5aVlXeFRhV2R1SUc1MkxYTmhNUkF3RGdZRFZRUUxFd2RTYjI5MElFTkJNUnN3R1FZRApWUVFERXhKSGJHOWlZV3hUYVdkdUlGSnZiM1FnUTBFd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURhCkR1YVpqYzZqNDArS2Z2dnhpNE1sYStwSUgvRXFzTG1WRVFTOThHUFI0bWRtenh6ZHp4dElLKzZOaVk2YXJ5bUFaYXZweHkwU3k2c2MKVEhBSG9UMEtNTTBWalUvNDNkU01VQlVjNzFEdXhDNzMvT2xTOHBGOTRHM1ZOVENPWGtOejhrSHAxV3Jqc29rNlZqazRid1k4aUdsYgpLazNGcDFTNGJJbk1tL2s4eXVYOWlmVVNQSko0bHRiY2RHNlRSR0hSamNkR3NuVU9odWdaaXRWdGJOVjRGcFdpNmNnS09PdnlKQk5QCmMxU1RFNFU2Rzd3ZU5MV0xCWXk1ZDR1eDJ4OGdrYXNKVTI2UXpuczNkTGx3UjVFaVVXTVdlYTZ4cmtFbUNNZ1pLOUZHcWtqV1pDclgKZ3pUL0xDckJiQmxEU2dlRjU5Tjg5aUZvNytyeVVwOS9rNURQQWdNQkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVgpIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSZ2UyWWFSUTJYeW9sUUwzMEV6VFNvLy96OVN6QU5CZ2txaGtpRzl3MEJBUVVGCkFBT0NBUUVBMW5QbmZFOTIwSTIvN0xxaXZqVEZLREsxZlB4c25Dd3J2UW1lVTc5clhxb1JTTGJsQ0tPenlqMWhUZE5HQ2JNK3c2RGoKWTFVYjhycnZyVG5oUTdrNG8rWXZpaVk3NzZCUVZ2bkdDdjA0emNRTGNGR1VsNWdFMzhOZmxOVVZ5UlJCbk1SZGRXUVZEZjlWTU95RwpqLzhON3l5NVkwYjJxdnpmdkduOUxoSklaSnJnbGZDbTd5bVBBYkVWdFF3ZHBmNXBMR2trZUI2enB4eHhZdTdLeUplc0YxMkt3dmhICmhtNHF4Rll4bGRCbmlZVXIrV3ltWFVhZERLcUM1SmxSM1hDMzIxWTlZZVJxNFZ6Vzl2NDkza0hNQjY1alVyOVRVL1FyNmNmOXR2ZUMKWDRYU1FSamJnYk1FSE1VZnBJQnZGU0RKM2d5SUNoM1dabFhpL0VqSktTWnA0QT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdsb2JhbFNpZ24gUm9vdCBDQSAtIFIyCj09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEdWpDQ0FxS2dBd0lCQWdJTEJBQUFBQUFCRDRZbTVnMHdEUVlKS29aSWh2Y05BUUVGQlFBd1RERWdNQjRHQTFVRUN4TVhSMnh2ClltRnNVMmxuYmlCU2IyOTBJRU5CSUMwZ1VqSXhFekFSQmdOVkJBb1RDa2RzYjJKaGJGTnBaMjR4RXpBUkJnTlZCQU1UQ2tkc2IySmgKYkZOcFoyNHdIaGNOTURZeE1qRTFNRGd3TURBd1doY05NakV4TWpFMU1EZ3dNREF3V2pCTU1TQXdIZ1lEVlFRTEV4ZEhiRzlpWVd4VAphV2R1SUZKdmIzUWdRMEVnTFNCU01qRVRNQkVHQTFVRUNoTUtSMnh2WW1Gc1UybG5iakVUTUJFR0ExVUVBeE1LUjJ4dlltRnNVMmxuCmJqQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtiUEpBNitMbThvbVVWQ3hLcytJVlNiQzlOL2hIRDYKRXJQTHY0ZGZ4bitHMDdJd1hOYjlyZkY3M09YNFlKWUpraEQxMEZQZSszdCtjNGlzVW9oN1NxYktTYVplcUtlTVdoRzhlb0xydm96cApzNnlXSlFlWFNwa3FCeSswSG5lL2lnKzFBbndibHJqRnVUb3N2TllTdWV0WmZlTFFCb1pmWGtscXRUbGVpRFRzdkhnTUNKaUViS2pOClM3U2dmUXg1VGZDNExjc2h5dFZzVzMzaG9DbUVvZm5UbEVuTEpHS1JJTHpkQzlYWnpQbnFKd29yYzVIR25SdXN5TXZvNEtEMEw1Q0wKVGZ1d05odjJHWHFGNEczeVlST0lYSi9na3dwUmw0cGF6cStyMWZlcUNhcGd2ZHpaWDk5eXFXQVRYZ0FCeVVyNlA2VHFCd01oQW82Qwp5Z1BDbTQ4Q0F3RUFBYU9CbkRDQm1UQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFCkZnUVVtK0lIVjJjY0hzQnFCdDVadEpvdDM5d1poaTR3TmdZRFZSMGZCQzh3TFRBcm9DbWdKNFlsYUhSMGNEb3ZMMk55YkM1bmJHOWkKWVd4emFXZHVMbTVsZEM5eWIyOTBMWEl5TG1OeWJEQWZCZ05WSFNNRUdEQVdnQlNiNGdkWFp4d2V3R29HM2xtMG1pM2YzQm1HTGpBTgpCZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFtWUZUaHh4b2w0YVI3T0JLdUVRTHE0R3NKMC9Xd2JnY1EzaXpESnI4Nml3OGJtRWJUVXNwCjlaOEZIU2JCdU9tREFHSkZ0cWtJazdtcE0wc1ltc0w0aDRoTzI5MXhOQnJCVk5wR1ArRFRLcXR0VkNMMU9tTE5JRys2S1luWDNaSHUKMDF5aVBxRmJRZlhmNVdSRExlblZPYXZTb3QrM2k5REFnQmtjUmNBdGpPajRMYVIwVmtuRkJiVlBGZDV1UkhnNWg2aCt1L041R0pHNwo5Rytkd2ZDTU5ZeGRBZnZEYmJudlJHMTVSakYrQ3Y2cGdzSC83NnR1SU1SUXlWK2RUWnNYakF6bEFjbWdRV3B6VS9xbFVMUnVKUS83ClRCajAvVkxaam1teDZCRVAzb2pZK3gxSjk2cmVsYzhnZU1KZ0V0c2xRSXhxL0g1Q09FQmtFdmVlZ2VHVExnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRW50cnVzdC5uZXQgUHJlbWl1bSAyMDQ4IFNlY3VyZSBTZXJ2ZXIgQ0EKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVLakNDQXhLZ0F3SUJBZ0lFT0dQZStEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERVVNQklHQTFVRUNoTUxSVzUwY25WemRDNXUKWlhReFFEQStCZ05WQkFzVU4zZDNkeTVsYm5SeWRYTjBMbTVsZEM5RFVGTmZNakEwT0NCcGJtTnZjbkF1SUdKNUlISmxaaTRnS0d4cApiV2wwY3lCc2FXRmlMaWt4SlRBakJnTlZCQXNUSENoaktTQXhPVGs1SUVWdWRISjFjM1F1Ym1WMElFeHBiV2wwWldReE16QXhCZ05WCkJBTVRLa1Z1ZEhKMWMzUXVibVYwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVJQ2d5TURRNEtUQWVGdzA1T1RFeU1qUXgKTnpVd05URmFGdzB5T1RBM01qUXhOREUxTVRKYU1JRzBNUlF3RWdZRFZRUUtFd3RGYm5SeWRYTjBMbTVsZERGQU1ENEdBMVVFQ3hRMwpkM2QzTG1WdWRISjFjM1F1Ym1WMEwwTlFVMTh5TURRNElHbHVZMjl5Y0M0Z1lua2djbVZtTGlBb2JHbHRhWFJ6SUd4cFlXSXVLVEVsCk1DTUdBMVVFQ3hNY0tHTXBJREU1T1RrZ1JXNTBjblZ6ZEM1dVpYUWdUR2x0YVhSbFpERXpNREVHQTFVRUF4TXFSVzUwY25WemRDNXUKWlhRZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGtnS0RJd05EZ3BNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QQpNSUlCQ2dLQ0FRRUFyVTFMcVJLR3N1cWpJQWNWRm1RcUswdlJ2d3RLVFk3dGdIYWxaN2Q0UU1CelFzaG93TnRUSzkxZXVIYVlOWk9MCkdwMThFem9PSDF1M0hzL2xKQlFlc1lHcGpYMjR6R3RMQS9FQ0ROeXJwVUFrQUg5MGxLR2RDQ216aUF2MWgzZWRWYzNrdzM3WGFtU3IKaFJTR2xWdVhNbEJ2UGNpNlpnemovTDI0U2NGMmlVa1ovY0Nvdlltalp5L0duN3h4R1dDNExla3N5WkIyWm51VTRxOTQxbVZUWFR6VwpuTExQS1FQNUw2UlFzdFJJemdVeVZZcjlzbVJNRHVTWUIzWGJmOSs1Q0ZWZ2hUQXArWHRJcEdtRzR6VS9Ib1pkZW5vVnZlOEFqaFVpClZCY0FrQ2FUdkE1SmFKRy8rRWZUblpWQ3dRNU4zMjhtejhNWUlXSm1RM0RXMWNBSDRRSURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEUKQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVWZVNCMFJHQXZ0aUp1UWlqTWZtaEpBa1d1WEF3RFFZSgpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFEdWJqMWFiTU9kVG1YeDZlYWRObDljWmxaRDdCaC9LTTN4R1k0K1daaVQ2UUJzaEo4cm1jblB5ClQvNHhtZjNJREV4b1U4YUFnaE9ZK3JhdDJsMDk4YzV1OWhVUmxJSU03aitWcnhHckQ5Y3YzaDhEajFjc0hzbTdtaHBFbGVzWVQ2WWYKelgxWEVDK2JCQWxhaExWdTJCMDY0ZGFlMFd4NVhua2NGTVhqMEV5VE8yVTg3ZDg5dnFibGxSckR0Um5EdlY1YnUvOGo3MmdaeXhLVApKMXdETFc4dzBCNjJHcXplV3ZmUnFxZ25wdjU1Z2NSNW1UTlh1aEt3cWVCQ2JKUEtWdDcrYllRTENJdCtqZXJYbUNIRzgrYzhlUzllCm5ORk1GWTNoN0NJM3pKcERDNWZjZ0pDTnMyZWJiMGdJRlZiUHYvRXJmRjZhZHVsWmtNVjhnelVSWlZFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290Cj09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURkekNDQWwrZ0F3SUJBZ0lFQWdBQXVUQU5CZ2txaGtpRzl3MEJBUVVGQURCYU1Rc3dDUVlEVlFRR0V3SkpSVEVTTUJBR0ExVUUKQ2hNSlFtRnNkR2x0YjNKbE1STXdFUVlEVlFRTEV3cERlV0psY2xSeWRYTjBNU0l3SUFZRFZRUURFeGxDWVd4MGFXMXZjbVVnUTNsaQpaWEpVY25WemRDQlNiMjkwTUI0WERUQXdNRFV4TWpFNE5EWXdNRm9YRFRJMU1EVXhNakl6TlRrd01Gb3dXakVMTUFrR0ExVUVCaE1DClNVVXhFakFRQmdOVkJBb1RDVUpoYkhScGJXOXlaVEVUTUJFR0ExVUVDeE1LUTNsaVpYSlVjblZ6ZERFaU1DQUdBMVVFQXhNWlFtRnMKZEdsdGIzSmxJRU41WW1WeVZISjFjM1FnVW05dmREQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtNRQp1eUtybUQxWDZDWnltclY1MUNuaTRlaVZnTEd3NDF1T0t5bWFaTitoWGUyd0NRVnQyeWd1em1LaVl2NjBpTm9TNnpqcklaM0FRU3NCClVudUlkOU1jajhlNnVZaTFhZ25uYytnUlFLZlJ6TXBpalMzbGp3dW1VTktvVU1NbzZ2V3JKWWVLbXBZY3FXZTRQd3pWOS9sU0V5L0MKRzlWd2NQQ1B3QkxLQnN1YTRkbktNM3AzMXZqc3VmRm9SRUpJRTlMQXdxU3VYbUQrdHFZRi9MVGRCMWtDMUZrWW1HUDFwV1Bna0F4OQpYYklHZXZPRjZ1dlVBNjVlaEQ1Zi94WHRhYno1T1RaeWRjOTNVazN6eVpBc3VUM2x5U05UUHg4a21DRmNCNWtwdmNZNjdPZHVoanByCmwzUmpNNzFvR0RId2VJMTJ2L3llamwwcWhxZE5rTnduR2prQ0F3RUFBYU5GTUVNd0hRWURWUjBPQkJZRUZPV2RXVENDUjFqTXJQb0kKVkRhR2V6cTFCRTN3TUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFNd0RnWURWUjBQQVFIL0JBUURBZ0VHTUEwR0NTcUdTSWIzRFFFQgpCUVVBQTRJQkFRQ0ZERjJPNUc5UmFFSUZvTjI3VHljbGhBTzk5MlQ5TGRjdzQ2UVFGK3ZhS1NtMmVUOTI5aGtUSTdnUUN2bFlwTlJoCmNMMEVZV29TaWhmVkNyM0Z2REI4MXVrTUpZMkdRRS9zektOK09NWTNFVS90M1dneGprelNzd0YwN3I1MVhnZElHbjl3L3haY2hNQjUKaGJnRi9YKytaUkdqRDhBQ3RQaFNOemtFMWFreGVoaS9vQ3IwRXBuM28wV0M0enhlOVoyZXRjaWVmQzdJcEo1T0NCUkxiZjF3YldzYQpZNzFrNWgrM3p2RHlueTY3RzdmeVVJaHprc0xpNHhhTm1qSUNxNDRZM2VrUUVlNStOYXVRcno0d2xIclFNejJuWlEvMS9JNmVZczlIClJDd0JYYnNkdFRMU1I5STRMdEQrZ2R3eWFoNjE3anpWL09lQkhSbkRKRUxxWXptcAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFa1RDQ0EzbWdBd0lCQWdJRVJXdFFWREFOQmdrcWhraUc5dzBCQVFVRkFEQ0JzREVMTUFrR0ExVUVCaE1DVlZNeEZqQVVCZ05WCkJBb1REVVZ1ZEhKMWMzUXNJRWx1WXk0eE9UQTNCZ05WQkFzVE1IZDNkeTVsYm5SeWRYTjBMbTVsZEM5RFVGTWdhWE1nYVc1amIzSncKYjNKaGRHVmtJR0o1SUhKbFptVnlaVzVqWlRFZk1CMEdBMVVFQ3hNV0tHTXBJREl3TURZZ1JXNTBjblZ6ZEN3Z1NXNWpMakV0TUNzRwpBMVVFQXhNa1JXNTBjblZ6ZENCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEEyTVRFeU56SXdNak0wCk1sb1hEVEkyTVRFeU56SXdOVE0wTWxvd2diQXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFLRXcxRmJuUnlkWE4wTENCSmJtTXUKTVRrd053WURWUVFMRXpCM2QzY3VaVzUwY25WemRDNXVaWFF2UTFCVElHbHpJR2x1WTI5eWNHOXlZWFJsWkNCaWVTQnlaV1psY21WdQpZMlV4SHpBZEJnTlZCQXNURmloaktTQXlNREEySUVWdWRISjFjM1FzSUVsdVl5NHhMVEFyQmdOVkJBTVRKRVZ1ZEhKMWMzUWdVbTl2CmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUIKQUxhVnRrTkMrc1p0S205STM1Uk1PVmNGN3NONUVVRm9OdTNzL3BvQmo2RTRLUHozRUVabUxrMGVHckVhVHNiUndKV0lzTW4vTVlzegpBOXUzZzNzK0lJUmU3YkpXS0tmNDRMbEFjVGZGeTBjT2x5cG93Q0tWWWhYYlI5bjEwQ3YvZ2t2SnJUN2VUTnVRZ0ZBL0NZcUVBT3d3CkNqMFl6ZnY5S2xtYUk1VVhMRVdlSDI1RGVXME1YSmorU0tmRkkwZGNYdjF1NXg2MDltaEYwWWFEVzZLS2piSGpLWUQrSlhHSXJiNjgKajZ4U2xrdXFVWTNrRXpFWjZFNU5uOXVzczJyVnZEbFVjY3A2ZW4rUTNYMGRnTm1CdTFrbXdoSCs1cFBpOTREa1pmczBOdzRwZ0hCTgpyemlHTHA1L1Y2K2VGNjdySE1zb0lWKzJITmpub2dRaStkUGEyTXNDQXdFQUFhT0JzRENCclRBT0JnTlZIUThCQWY4RUJBTUNBUVl3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBckJnTlZIUkFFSkRBaWdBOHlNREEyTVRFeU56SXdNak0wTWxxQkR6SXdNall4TVRJM01qQTEKTXpReVdqQWZCZ05WSFNNRUdEQVdnQlJva09SbnBLWlRnTWVHWnFUeDkwdEQrNFM5YlRBZEJnTlZIUTRFRmdRVWFKRGtaNlNtVTRESApobWFrOGZkTFEvdUV2VzB3SFFZSktvWklodlo5QjBFQUJCQXdEaHNJVmpjdU1UbzBMakFEQWdTUU1BMEdDU3FHU0liM0RRRUJCUVVBCkE0SUJBUUNUMURDdzF3TWdLdEQ1WStpUkRBVWdxVjhaeW50eVR0U3gyOUNXKzFSYUdTd01DUGV5dklXb25YOXRPMUt6S3R2bjFJU00KWS9ZUHl5WUJrVkJzOUY4VTRwTjB3Qk9lTURwUTQ3Umd4Unp3SWtTTmNVZXN5QnJKNlp1YUFHQVQvM0IrWHhGTlNSdXpGVko3eVZUYQp2NTJWcjJ1YTJKN3A4ZVJEamVJUlJEcS9yNzJEUW5OU2k2cTdweW5QOVdRY0NrM1J2S3FzbnlyUS8zOS8ybjNxc2Uwd0pjR0UyalRTClczaURWdXljTnNNbTRoSDJaMGtka3F1TSsrdi9ldTZGU3FkUWdQQ25YRXFVTGw4Rm1UeFNRZUROdEdQUEFVTzZuSVBjajJBNzgxcTAKdEh1dTJndVFPSFh2Z1IxbTB2ZFhjRGF6di93b3IzRWxoVnNUL2g1L1dyUTgKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ29tb2RvIEFBQSBTZXJ2aWNlcyByb290Cj09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRU1qQ0NBeHFnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQjdNUXN3Q1FZRFZRUUdFd0pIUWpFYk1Ca0dBMVVFQ0F3UwpSM0psWVhSbGNpQk5ZVzVqYUdWemRHVnlNUkF3RGdZRFZRUUhEQWRUWVd4bWIzSmtNUm93R0FZRFZRUUtEQkZEYjIxdlpHOGdRMEVnClRHbHRhWFJsWkRFaE1COEdBMVVFQXd3WVFVRkJJRU5sY25ScFptbGpZWFJsSUZObGNuWnBZMlZ6TUI0WERUQTBNREV3TVRBd01EQXcKTUZvWERUSTRNVEl6TVRJek5UazFPVm93ZXpFTE1Ba0dBMVVFQmhNQ1IwSXhHekFaQmdOVkJBZ01Fa2R5WldGMFpYSWdUV0Z1WTJobApjM1JsY2pFUU1BNEdBMVVFQnd3SFUyRnNabTl5WkRFYU1CZ0dBMVVFQ2d3UlEyOXRiMlJ2SUVOQklFeHBiV2wwWldReElUQWZCZ05WCkJBTU1HRUZCUVNCRFpYSjBhV1pwWTJGMFpTQlRaWEoyYVdObGN6Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0MKZ2dFQkFMNUFuZlJ1NGVwMmh4eE5SVVNPdmtiSWd3YWR3U3IrR0IrTzVBTDY4NnRkVUlvV01RdWFCdERGY0NMTlNTMVVZOHkyYm1oRwpDMVBxeTB3a3dMeHlUdXJ4RmE3MFZKb1NDc042c2pOZzR0cUpWZk1pV1BQZTNNL3ZnNGFpakpSUG4yanltSkJHaENmSGRyL2p6RFVzCmkxNEhaR1dDd0Vpd3FKSDVZWjkySUZDb2tjZG10ZXQ0WWdOVzhJb2FFK294b3g2Z21mMDQ5dlluTWxodkIvVnJ1UHNVSzYrM3FzelcKWTE5empOb0ZtYWc0cU1zWGVEWlJyT21lOUhnNmpjOFAyVUxpbUF5ckw1OE9BZDd2bjVsSjhTM2ZySFJORzVpMVI4WGxLZEg1a0JqSApZcHkrZzhjbWV6NktKY2ZBM1ozbU5XZ1FJSjJQMk43U3c0U2NEVjdvTDhrQ0F3RUFBYU9Cd0RDQnZUQWRCZ05WSFE0RUZnUVVvQkVLCkl6Nlc4UWZzNHE4cDc0S2xmOUF3cExRd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3ZXdZRFZSMGYKQkhRd2NqQTRvRGFnTklZeWFIUjBjRG92TDJOeWJDNWpiMjF2Wkc5allTNWpiMjB2UVVGQlEyVnlkR2xtYVdOaGRHVlRaWEoyYVdObApjeTVqY213d05xQTBvREtHTUdoMGRIQTZMeTlqY213dVkyOXRiMlJ2TG01bGRDOUJRVUZEWlhKMGFXWnBZMkYwWlZObGNuWnBZMlZ6CkxtTnliREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBQ0ZiOEF2Q2I2UCtrK3RaN3hrU0F6ay9FeGZZQVdNeW10cndVU1dnRWR1am0KN2wzc0FnOWcxbzFRR0U4bVRnSGo1ckNsN3IrOGRGUkJ2LzM4RXJqSFQxcjBpV0FGZjJDM0JVcno5dkhDdjhTNWRJYTJMWDFyek5MegpSdDB2eHVCcXc4TTBBeXg5bHQxYXdnNm5DcG5CQll1ckRDL3pYRHJQYkRkVkNZZmVVMEJzV08vOHRxdGxiZ1QyRzl3ODRGb1Z4cDdaCjhWbElNQ0ZsQTJ6czZTRno3SnNEb2VBM3JhQVZHSS82dWdMT3B5eXBFQk1zMU9VSUpxc2lsMkQ0a0Y1MDFLS2FVNzN5cVdqZ29tN0MKMTJ5eG93K2V2K3RvNTFieXJ2TGpLemc2Q1lHMWE0WFh2aTN0UHhxM3NtUGk5V0lzZ3RScUFFRlE4VG1EbjVYcE5wYVliZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClF1b1ZhZGlzIFJvb3QgQ0EKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjBEQ0NCTGlnQXdJQkFnSUVPclpRaXpBTkJna3Foa2lHOXcwQkFRVUZBREIvTVFzd0NRWURWUVFHRXdKQ1RURVpNQmNHQTFVRQpDaE1RVVhWdlZtRmthWE1nVEdsdGFYUmxaREVsTUNNR0ExVUVDeE1jVW05dmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwCmVURXVNQ3dHQTFVRUF4TWxVWFZ2Vm1Ga2FYTWdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncwd01UQXoKTVRreE9ETXpNek5hRncweU1UQXpNVGN4T0RNek16TmFNSDh4Q3pBSkJnTlZCQVlUQWtKTk1Sa3dGd1lEVlFRS0V4QlJkVzlXWVdScApjeUJNYVcxcGRHVmtNU1V3SXdZRFZRUUxFeHhTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TVM0d0xBWURWUVFECkV5VlJkVzlXWVdScGN5QlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUYKQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2MkcxbFZPNlYvejY4bWNMT2hyZkVZQmtsYlRSdk0xNnovWXBsaTRrVkVBa09QY2FoZHhZVE11awpKMEtYMEorRGlzUGtCZ05iQUtWUkhuQUVkT0xCMURxcjE2MDdCeGdGanYyRHJPcG0yUmdiYUlyMVZ4cVl1dlh0ZGoxODJkNlVhanRMCkY4SFZqNzFsT0RxVjBEMVZOazdmZVZjeEtoN1lXV1ZKV0NDWWZxdGZmcC9wMWszc2czU3B4MnpZN2lsS2hTb0dGUGxVNXRQYVpRZUwKWXpjUzE5RHN3M3NnUVVTajdjdWdGK0Z4WmM0ZFpqSDNkZ0VaeUgwRFdMYVZTUjJtRWlib3hneDI0T05teStwZHBpYnU1Y3hmdldlbgpBU2NPb3NwVXhiRjZsUjF4SGtvcGlnUGNha1hCcEJsZWJ6Yk53Nkt3dC81Y09PSlN2UGhFUSthUXV3SURBUUFCbzRJQ1VqQ0NBazR3ClBRWUlLd1lCQlFVSEFRRUVNVEF2TUMwR0NDc0dBUVVGQnpBQmhpRm9kSFJ3Y3pvdkwyOWpjM0F1Y1hWdmRtRmthWE52Wm1aemFHOXkKWlM1amIyMHdEd1lEVlIwVEFRSC9CQVV3QXdFQi96Q0NBUm9HQTFVZElBU0NBUkV3Z2dFTk1JSUJDUVlKS3dZQkJBRytXQUFCTUlINwpNSUhVQmdnckJnRUZCUWNDQWpDQnh4cUJ4RkpsYkdsaGJtTmxJRzl1SUhSb1pTQlJkVzlXWVdScGN5QlNiMjkwSUVObGNuUnBabWxqCllYUmxJR0o1SUdGdWVTQndZWEowZVNCaGMzTjFiV1Z6SUdGalkyVndkR0Z1WTJVZ2IyWWdkR2hsSUhSb1pXNGdZWEJ3YkdsallXSnMKWlNCemRHRnVaR0Z5WkNCMFpYSnRjeUJoYm1RZ1kyOXVaR2wwYVc5dWN5QnZaaUIxYzJVc0lHTmxjblJwWm1sallYUnBiMjRnY0hKaApZM1JwWTJWekxDQmhibVFnZEdobElGRjFiMVpoWkdseklFTmxjblJwWm1sallYUmxJRkJ2YkdsamVTNHdJZ1lJS3dZQkJRVUhBZ0VXCkZtaDBkSEE2THk5M2QzY3VjWFZ2ZG1Ga2FYTXVZbTB3SFFZRFZSME9CQllFRkl0TGJlM1RLYmtHR2V3NU9hbndsNFJxeSsvZk1JR3UKQmdOVkhTTUVnYVl3Z2FPQUZJdExiZTNUS2JrR0dldzVPYW53bDRScXkrL2ZvWUdFcElHQk1IOHhDekFKQmdOVkJBWVRBa0pOTVJrdwpGd1lEVlFRS0V4QlJkVzlXWVdScGN5Qk1hVzFwZEdWa01TVXdJd1lEVlFRTEV4eFNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwCmFHOXlhWFI1TVM0d0xBWURWUVFERXlWUmRXOVdZV1JwY3lCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNWdnUTYKdGxDTE1BNEdBMVVkRHdFQi93UUVBd0lCQmpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQWl0UVV0ZjcwbXBLbkdkU2tmbklZajlsbwpmRklrM1dkdk9YckVxbDQ5NGxpd1RYQ1loR0hvRytOcEdBN08rMGRRb0U3LzhDUWZ2YkxPOVNmODdDOVRxbk43QXoxMGJ1WVdudXVsCkxzUy9WaWRRSzJLNnZrc2NQRlZjUVIwa3ZvSWdSMTNWUkg1NkZtamZmVTFSY0hoWEhUTWUvUUtabkF6TkNnVlB4N3VPcEhYNlNtMngKZ0k0SlZybWNHbUQrWGNIWGV0d1JlTkRXWGNHMzFhMHltUU02aXN4VUpUa3hnWHNUSWxHNlJteWh1NTc2Qkd4SkpuU1AwblByekRDaQo1dXBaSW9mNGwvVU8vZXJNa3FRV3hGSVk2aUhPc2ZIbWhJSGx1cW1HS1BKRFdsMFNuYXdlMmFqbENtcW5mNkNIS2MveWlVM1U3TVhpCjVuclFOaU9LU25RMitRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKUXVvVmFkaXMgUm9vdCBDQSAyCj09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRnR6Q0NBNStnQXdJQkFnSUNCUWt3RFFZSktvWklodmNOQVFFRkJRQXdSVEVMTUFrR0ExVUVCaE1DUWsweEdUQVhCZ05WQkFvVApFRkYxYjFaaFpHbHpJRXhwYldsMFpXUXhHekFaQmdOVkJBTVRFbEYxYjFaaFpHbHpJRkp2YjNRZ1EwRWdNakFlRncwd05qRXhNalF4Ck9ESTNNREJhRncwek1URXhNalF4T0RJek16TmFNRVV4Q3pBSkJnTlZCQVlUQWtKTk1Sa3dGd1lEVlFRS0V4QlJkVzlXWVdScGN5Qk0KYVcxcGRHVmtNUnN3R1FZRFZRUURFeEpSZFc5V1lXUnBjeUJTYjI5MElFTkJJREl3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQwpEd0F3Z2dJS0FvSUNBUUNhR01wTGxBMEFMYThES1lyd0Q0SElya3daaFIwSW42c3BSSVh6TDRHdE1oNlFScitqaGlZYUh2NStIQmc2ClhKeGdGeW82ZElNek1IMWhWQkhMN2F2ZzV0S2lmdlZyYnhpM0Nnc3QvZWsrN3dyR3N4RHAzTUpHRi9oZC9hVGEvNTVKV3B6bU0rWWsKbHZjL3Vsc3JISG8xd3Rabi9xdG1VSXR0S0dBcjc5ZGd3OGVUdkkwMmtmTi8rTnNSRThTY2QzYkJycmNDYW9GNnFVV0Q0Z1htdVZiQgpsRGVQU0hGakl1d1haUWVWaWt2Zmo4WmFDdVd3NDE5ZWF4R3JEUG1GNjBUcCtBUno4dW4rWEppTTlYT3ZhN1IremRSY0FpdE1PZUd5CmxaVXRRb2ZYMWJPUVE3ZHNFL0hlM2ZiRStJay8wWFgxa3NPUjFZcUkwSkRzM0czZWljSmxjWmFMRFFQOW5MOWJGcXlTMityK2VYeXQKNjYvM0ZzdmJ6U1VyNVIvN21wL2lVY3c2VXd4STVnNjl5YlIyQmxMbUVST0ZjbU1EQk9BRU5pc2dHUUxvZEtjZnRzbFdadkIxSmR4bgp3UTVoWUlpelB0R28vS1BhSGJEUnNTTlUzMFIyYmUxQjJNR3lJclpUSE44MUhkeWhkeW94NUMzMTVlWGJ5T0QvNVlEWEMyT2cvek9oCkQ3b3NGUlhxbDdQU29yVys4b3lXSGhxUEhXeWtZVGU1aG5NejE1ZVduaU45Z3FSTWdlS2gwYnBuWDVVSG95Y1I3aFlRZTd4RlNreXkKQk5Lcjc5WDlERkhPVUdvSU1mbVIyZ3lQWkZ3RHd6cUxJRDl1aldjOU90YitmVnVJeVY3N3pHSGNpek4zMDBReU5RbGlCSklXRU5pZQpKMGY3T3lIaitPc2RXd0lEQVFBQm80R3dNSUd0TUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3Q3dZRFZSMFBCQVFEQWdFR01CMEdBMVVkCkRnUVdCQlFhaEdLOFNFd3pKUVRVN3REMkE4UVpSdEdVYXpCdUJnTlZIU01FWnpCbGdCUWFoR0s4U0V3ekpRVFU3dEQyQThRWlJ0R1UKYTZGSnBFY3dSVEVMTUFrR0ExVUVCaE1DUWsweEdUQVhCZ05WQkFvVEVGRjFiMVpoWkdseklFeHBiV2wwWldReEd6QVpCZ05WQkFNVApFbEYxYjFaaFpHbHpJRkp2YjNRZ1EwRWdNb0lDQlFrd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFENEtGazJmQmx1b3JuRmRMd1V2ClorWVRSWVBFTnZiendDWU1EYlZIWkYzNHRITEpScVVER0NkVmlYaDlkdXFXTklBWElOem5nL2lOL0FlNDJsOU5MbWV5aFAzWlJQeDMKVUlIbWZMVEpEUXR5VS9oMkJ3ZEJSNVlNKytDQ0pwTlZqUDRpSDJCbGZGL25KclAzTXBDWVVOUTNjVlgya2lGNDk1VjUrdmd0Sm9kbQpWakIzcGpkNE0xSVFXSzQvWVk3eWFySHZHSDVLV1dQS2phSlcxYWN2dkZZZnp6bkI0dnNLcUJVc2ZVMTZZOFpzbDBRODBtL0RTaGNLCitKRFNWNklaVWFVdGwwSGFCMCtwVU5xUWpaUkc0VDd3bFAwUUFEajFPK2hBNGJSdVZob2d6RzlZamUwdVJZL1c2Wk0vNTdFczN6clcKSW96Y2hMc2liOUQ0NU1ZNTZRU0lQTU82NjFWNmJZQ1pKUFZzQWZ2NGw3Q1VXK3Y5MG0veGQyZ05OV1FqckxoVm9RUFJUVUlaM1BoMQpXVmFqK2FoSmVmaXZEcmtSb0h5M2F1MDAwTFltWWpnYWh3ejQ2UDB1MDVCL0I1RXFIZForWElXRG1iQTRDRC9wWHZrMUIrVEpZbTVYCmY2ZFFsZmU2eUp2bWpxSUJ4ZFptdjNsaDh6d2M0Ym1DWEYyZ3crbllTTDBab2hFVUdXNnloaHRvUGtnM0dvaTNYWlplbk1mdkoySUkKNHBFWlhOTHhJZDI2RjBLQ2wzR0JVekdwbi9aOVlyOXk0YU9USGN5S0psb0pPTkRPMXcyQUZyUjRwVHFIVEkyS3BkVkdsL0lzRUxtOApWQ0xBQVZCcFE1NzBzdTl0K096YThlT3g3OStSajFRcUN5WEJKaG5FVWhBRlpkV0NFT3JDTWMwdQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpRdW9WYWRpcyBSb290IENBIDMKPT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlHblRDQ0JJV2dBd0lCQWdJQ0JjWXdEUVlKS29aSWh2Y05BUUVGQlFBd1JURUxNQWtHQTFVRUJoTUNRazB4R1RBWEJnTlZCQW9UCkVGRjFiMVpoWkdseklFeHBiV2wwWldReEd6QVpCZ05WQkFNVEVsRjFiMVpoWkdseklGSnZiM1FnUTBFZ016QWVGdzB3TmpFeE1qUXgKT1RFeE1qTmFGdzB6TVRFeE1qUXhPVEEyTkRSYU1FVXhDekFKQmdOVkJBWVRBa0pOTVJrd0Z3WURWUVFLRXhCUmRXOVdZV1JwY3lCTQphVzFwZEdWa01Sc3dHUVlEVlFRREV4SlJkVzlXWVdScGN5QlNiMjkwSUVOQklETXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDCkR3QXdnZ0lLQW9JQ0FRRE1WMElXVkp6bW1OUFRUZTcrN2NlZlF6bEtaYlBvRm9nMDJ3MVprWFRQa3JnRVFLMENTekdydkkyUmFOZ2cKRGhvQjRocDdUaGRkNG9xM1A1a2F6ZXRocThKbHBoKzN0NzIzai96OWNJOExvR2UrQWFKWnozSG1EeWwyLzdGV2VVVXJINTU2Vk9pagpLVFZvcEFGUEQ2UXVOKzhiditPUEVLaHlxMWhYNTFTR3lNbnpXOW9zMmwyT2JqeWpQdHI3Z3VYZDhseXlCVE52aWpiTzBCTk8vNzlLCkREUk1wc01odlZBRVZldXh1NTM3UlI1a0ZkNVZBWXdDZHJYTG9UOUNhYnd2dldoREZsYUpLamRoa2YybXJrN0F5eFJsbERkTGtnYnYKQk5ESW5JamJDM3VCcjdFOUtzUmxPbmkyN3R5QXNkTFRtWnc2N210YWE3T050OVhPbk1LK3BVc3ZGckdlYURzR2I2NTluL2plN013cApwNWlqSlVNdjcvRmZKdUdJVGZoZWJ0ZlpGRzRaTTJtbk80U0prOFJUVlJPaFVYaEErTGpKb3U1N3VsSkNnNTRVN1FWU1dsbFdwNWY4Cm5UOEtLZGpjVDVFT0U3emVsYVRmaTVtK3JKc3ppTysxZ2E4YnhpSlR5UGJIN3BjVXNNVjhlRkxJOE01dWQyQ0VwdWtxZGlEdFdBRVgKTUpQcEdvdmdjMlBaYXBLVVNVNjByVXFGeEtNaU1Qd0o3V2dpYzZhSURGVWhXTVhoT3A4cTNjcmhrT0RaYzZ0c2dMam9DMlNUb0p5TQpHZit6MGd6c2tTYUhpck9pNFhDUExBcmx6VzFvVWV2YVB3Vi9pekxtRTF4ci9sOUE0aUxJdExSa1Q5YTZmVWcrcUdrTTE3dUdjY2x6CnVEODduU1ZMMnY5QTZ3SURBUUFCbzRJQmxUQ0NBWkV3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekNCNFFZRFZSMGdCSUhaTUlIV01JSFQKQmdrckJnRUVBYjVZQUFNd2djVXdnWk1HQ0NzR0FRVUZCd0lDTUlHR0dvR0RRVzU1SUhWelpTQnZaaUIwYUdseklFTmxjblJwWm1sagpZWFJsSUdOdmJuTjBhWFIxZEdWeklHRmpZMlZ3ZEdGdVkyVWdiMllnZEdobElGRjFiMVpoWkdseklGSnZiM1FnUTBFZ015QkRaWEowCmFXWnBZMkYwWlNCUWIyeHBZM2tnTHlCRFpYSjBhV1pwWTJGMGFXOXVJRkJ5WVdOMGFXTmxJRk4wWVhSbGJXVnVkQzR3TFFZSUt3WUIKQlFVSEFnRVdJV2gwZEhBNkx5OTNkM2N1Y1hWdmRtRmthWE5uYkc5aVlXd3VZMjl0TDJOd2N6QUxCZ05WSFE4RUJBTUNBUVl3SFFZRApWUjBPQkJZRUZQTEFFK0NDUXo3NzdpOW5NcFkxWE51NHl3TFFNRzRHQTFVZEl3Um5NR1dBRlBMQUUrQ0NRejc3N2k5bk1wWTFYTnU0Cnl3TFFvVW1rUnpCRk1Rc3dDUVlEVlFRR0V3SkNUVEVaTUJjR0ExVUVDaE1RVVhWdlZtRmthWE1nVEdsdGFYUmxaREViTUJrR0ExVUUKQXhNU1VYVnZWbUZrYVhNZ1VtOXZkQ0JEUVNBemdnSUZ4akFOQmdrcWhraUc5dzBCQVFVRkFBT0NBZ0VBVDYyZ0xFejZ3UEp2OTJaVgpxeU0wN3VjcDJzTmJ0ckNEMmREUTRpSDc4MkNuTzExZ1V5ZWltL1lJSWlybnY2Qnk1WndrYWpHeGtIb24yNFFSaVNlbWQxbzQxNytzCmh2enVYWU84QnNiUmQyc1BiU1F2UzNwc3B3ZVd5dU9FbjYySWl4MnJGbzFiWmhmWkZ2U0xnTkxkK0xKMncvdzRFNm9NM2tKcEsyN3oKUE91QUo5djFwa1FObjFwVldRdlZEVkpJeGE2ZjhpK0F4ZW95VURVU2x5N0I0Zi94STRoUk9KL3labFoyNXc5Umw2VlNERTFKVVpVMgpQYitpU3d3UUhZYVpUS3J6Y2hHVDVPcjJtOXFvWGFkTnQ1NENybk1BeU5vakErajU2aGwwWWdDVXl5SWd2cFNuV2JXQ2FyNlplWHFwCjhrb2tVdmQwL2JwTzVxZ2RBbTZ4RFlCRXdhN1RJemRmdTRWOEs1SXU2SDZsaTkyWjRiOG5ieTFkcW51SC9ncmRTL3lPOVNia2JuQkMKYmpQc01aNTdrOEhreVdrYVBjQnJUaUp0N3F0WVRjYlFRY0VyNms4U2gxN3JSZGhzOVpnQzA2RFlWWW9HbVJtaW9IZlJNSjZzekhYdQpnL1d3WWpuUGJGZmlUTktSQ3c1MUtCdWF2LzBhUS9IS2QvczdqMkc0YVNnV1FnUmVjQ29jSWRpUDRiMGpXeTEwUUpMWll4a05jOTFwCnZHSkh2T0IwSzdMcmZiNUJHN1hBUnNXaElzdGZUc0Vva3Q0WXV0VXFLTHNSaXhlVG1KbGdsRndqejFvbmwxNExCUWFUTng0N2FUYnIKcVo1aEhZOHkybzRNMW5RK2V3a2syZ0YzUjhRN3pUU01tZlhLNFNWaE03SlpHK0p1MXpkWHRnMnBFdG89Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURXakNDQWtLZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREJRTVFzd0NRWURWUVFHRXdKS1VERVlNQllHQTFVRUNoTVAKVTBWRFQwMGdWSEoxYzNRdWJtVjBNU2N3SlFZRFZRUUxFeDVUWldOMWNtbDBlU0JEYjIxdGRXNXBZMkYwYVc5dUlGSnZiM1JEUVRFdwpIaGNOTURNd09UTXdNRFF5TURRNVdoY05Nak13T1RNd01EUXlNRFE1V2pCUU1Rc3dDUVlEVlFRR0V3SktVREVZTUJZR0ExVUVDaE1QClUwVkRUMDBnVkhKMWMzUXVibVYwTVNjd0pRWURWUVFMRXg1VFpXTjFjbWwwZVNCRGIyMXRkVzVwWTJGMGFXOXVJRkp2YjNSRFFURXcKZ2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3pzLzUvMDIyeDd4WjhWNlVNYlhhS0wwdS9aUHRNN29ydwo4eWw4OWYvdUt1RHA2YnBiWkNLYW1tOHNPaVpwVVFXWkp0elZIR3B4eHBwOUhwM2RmR3pHakdkblNqNzRjYkFaSjZrSkRLYVZ2MHVNCkRQcFZtRHZZNkNLaFMzRTRlYXlYa21temlYN3FJV2dHbUJTV2g5SmhOcnh0SjFhZVYrN0F3RmI5TXMrazJZN0NJOWVOcVBQWUpheVgKNUhBNDlMWTZ0SjA3bHlaRG82RzhTVmx5VENNd2h3Rlk5azYrSEdoV1pxL05RVjNJczAwcVZVYXJIOW9lNGtBOTI4MTl1WktBbkRmZApESlprbmR3aTkyU0wzMkhlRlpSU0ZhQjlVc2xMcUNISnhySHR5OE9WWU5FUDhLdHcrTi9MVFg3czF2cXIyYjEvVlBLbDZYbjYyZFoyCkpDaHpBZ01CQUFHalB6QTlNQjBHQTFVZERnUVdCQlNnYzBtWmFOeUZXMlhqbXlndlY1KzlNN3dIU0RBTEJnTlZIUThFQkFNQ0FRWXcKRHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBYUVDcHFMdmtUMTE1c3dXMUY3TmdFK3ZHa2wzZwowZE5xL3Z1K20yMi94d1Z0V1NERUhQQzMyb1JZQW1QNlNCYnZUNlVMOTBxWThqK2VHNjFIYTJQT0NFZnJVajk0bks5TnJ2alZUOCthCm1Db1FRVGxTeE4zWm13N3Zrd0d1c2k3S2FFSWtRbXl3c3pvK3plbmFTTVFWeStuNUJ3K1NVRW1LM1RHWFg4bnBONm83V1dXWGxETEoKczU4K09tSll4VW10WWc1eHBUS3FMOGFKZGtOQUV4Tm5QYUpVSlJETDhUcnkyZnJiU1ZhN3B2Nm5RVFhENEloaHlZakgzellRSXBoWgo2ckJLKzFZV2MyNnNUZmNpb1UrdEhYb3RSU2ZsTU1GZTh0b1R5eVZDVVpWSEE0eHNJY3gwUXUxVC96T0xqdzlYQVJZdno2YnV5WEFpCkZMMzl2bXdMQXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTb25lcmEgQ2xhc3MgMiBSb290IENBCj09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJRENDQWdpZ0F3SUJBZ0lCSFRBTkJna3Foa2lHOXcwQkFRVUZBREE1TVFzd0NRWURWUVFHRXdKR1NURVBNQTBHQTFVRUNoTUcKVTI5dVpYSmhNUmt3RndZRFZRUURFeEJUYjI1bGNtRWdRMnhoYzNNeUlFTkJNQjRYRFRBeE1EUXdOakEzTWprME1Gb1hEVEl4TURRdwpOakEzTWprME1Gb3dPVEVMTUFrR0ExVUVCaE1DUmtreER6QU5CZ05WQkFvVEJsTnZibVZ5WVRFWk1CY0dBMVVFQXhNUVUyOXVaWEpoCklFTnNZWE56TWlCRFFUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUpBWFNqV2R5dkFObHNkRStoWTMKL0VpOXZYK0FMVFU3NFcrb1o2bS9BeHhOakc4eVI5VkJhS1FUQk1FMURKcUVRL3hjSGYrSnMrZ1hHTTJSWC91SjQrcS9UbDE4R3liVApkWG50NW9UalYrV3RLY1QwT2lqbnBYdUVObW16L1Y1MnZhTXRtZE9RVGlNb2ZSaGo4VlE3SnAxMlc1ZENzdit1OEU3czNUbVZUb01HCmYrZEpRTWpGQWJKVVdtWWRQZno1NlR3S25vRzRjUEFCaStRalZIeklydmlRSGdDV2N0UlV6MkVqdk9yN25RS1YwYmE1Y1RwcENEOFAKdE9GQ3g0ajFQNWlvcDdvYzRIRng3MWhYZ1ZCNlhHdDBSZzZEQTVqRGpxaHU4bll5YmllRHduUHozQmpvdEpQcWRVUnJCR0FnY1ZlSApuZk8rb0pBalBZb2s0ZG9oMjhNQ0F3RUFBYU16TURFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBUkJnTlZIUTRFQ2dRSVNxQ3FXSVRUClhqd3dDd1lEVlIwUEJBUURBZ0VHTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFCYXpvZjVGbklWVjBzZDJadm5vaVl3N0pObjM5WXQKMGpTdjl6aWx6cXNXdWFzdmZEWExyTkFQdEV3ci9JRHZhNHlSWHpaMjk5dXpHeG5xOUxJUi9XRnhSTDhvc3pvZHY3TkQ2SisvM0RFSQpjYkNkamRZMFJ6S1F4bVVrOTZCS2ZBUnpqemx2RjR4eXRiMUx5SHI0ZTRQREtFNmNDZXBuUDdKbkJCdkRGTnI0NTBra2tkQWRhdnBoCk9lOXI1eUYxQmdmWUVyUWhJSEJDY1lIYVBKbzJ2cVpiRFdwc21oK1JlL241NzBLNlRrNmV6QXlObE56WlJaeGU3RUpRWTY3MFhjU3gKRXR6S082Z3VuUlJhQlhXMzdOZGo0cm8xdGdRSWtlamFuWnoyWnJVWXJBcW1WQ1kwTTlJYndkUi9HanFPQzZveWJ0djhUeVdmMlRMSApsbHB3ck45TQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpYUmFtcCBHbG9iYWwgQ0EgUm9vdAo9PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRU1EQ0NBeGlnQXdJQkFnSVFVSlJzN0JqcTFaeE4xWmZ2ZFkrZ3JUQU5CZ2txaGtpRzl3MEJBUVVGQURDQmdqRUxNQWtHQTFVRQpCaE1DVlZNeEhqQWNCZ05WQkFzVEZYZDNkeTU0Y21GdGNITmxZM1Z5YVhSNUxtTnZiVEVrTUNJR0ExVUVDaE1iV0ZKaGJYQWdVMlZqCmRYSnBkSGtnVTJWeWRtbGpaWE1nU1c1ak1TMHdLd1lEVlFRREV5UllVbUZ0Y0NCSGJHOWlZV3dnUTJWeWRHbG1hV05oZEdsdmJpQkIKZFhSb2IzSnBkSGt3SGhjTk1EUXhNVEF4TVRjeE5EQTBXaGNOTXpVd01UQXhNRFV6TnpFNVdqQ0JnakVMTUFrR0ExVUVCaE1DVlZNeApIakFjQmdOVkJBc1RGWGQzZHk1NGNtRnRjSE5sWTNWeWFYUjVMbU52YlRFa01DSUdBMVVFQ2hNYldGSmhiWEFnVTJWamRYSnBkSGtnClUyVnlkbWxqWlhNZ1NXNWpNUzB3S3dZRFZRUURFeVJZVW1GdGNDQkhiRzlpWVd3Z1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnAKZEhrd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNZSkI2OUZiUzYzOGVNcFNlMk9BdHA4N1pPcUN3dQpJUjFjUk44aFhYNGpkUDVlZnJSS3Q2YXRINjdnQmhiaW0xdlpaM1JyWFlDUEtaMkdHOW1jRFpodGRoQW9XT1Jsc0g5S21IbWY0TU14CmZvQXJ0WXpBUURzUmh0RExvb1kyWUtUVk1JSnQyVzdRRHhJRU01ZGZUMkZhOE9UNWthdm5IVHU4Nk0vMGF5MDBmT0pJWVJ5TzgyRkUKekcrZ1NxbVVzRTNhNTZrMGVuSTRxRUhNUEpRUmZldklwb3kzaHN2S016dlpQVGVMKzNvK2hpem5jOWNLVjZ4a214bnI5QThFQ0lxcwpBeGNaWlBSYUpTS05OQ3l5OW1nZEVtM1RpaDRVMnNTUHB1SWpoZFY2RGIxcTRPbnM3QmU3UWh0bnFpWHRSWU1oL01ISmZOVmlQdnJ5CnhTM1QvZFJsQWdNQkFBR2pnWjh3Z1p3d0V3WUpLd1lCQkFHQ054UUNCQVllQkFCREFFRXdDd1lEVlIwUEJBUURBZ0dHTUE4R0ExVWQKRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZNWlBvajBHWTRRSm5NNWk1QVNzalZ5MTZiWWJNRFlHQTFVZEh3UXZNQzB3SzZBcApvQ2VHSldoMGRIQTZMeTlqY213dWVISmhiWEJ6WldOMWNtbDBlUzVqYjIwdldFZERRUzVqY213d0VBWUpLd1lCQkFHQ054VUJCQU1DCkFRRXdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBSkVWT1FNQkcyZjdTaHo1Q21CYm9kcE5sMkw1SkZNbjE0SmtUcEF1dzBrYks1cmMKL0toNFp6WHhIZkFSdmJkSTR4RDJEZDgvMHNtMnFsV2tTTG9DMjk1WkxoVmJPNTBXZlVmWE4rcGZUWFlTTnJzZjE2R0JCRVlnb3l4dApxWjRCZmo4cHpnQ1QzLzNKa25PSmlXU2U1eXZrSEpFczBybk9mYzV2TVpuVDVyN1NIcER3Q1JSNVhDT3JUZExhSVI5Tm1YbWQ0YzhuCm54Q2JISWdOc0lwa1FURzREbXlRSktTYlhIR1B1cnQrSEJ2YmFvQVBJYnpwMjZhM1FQU3lpNm14NU8rYUd0QTlhWm51cUNpajRUeXoKOExJUm5NOThRT2JkNTBOOW90ZzZ0YW1OOGpTWnhOUVE0UWI5Q1lRUU8rN0VUUFRzSjN4Q3duUjhnb29KeWJRREpidz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR28gRGFkZHkgQ2xhc3MgMiBDQQo9PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFQURDQ0F1aWdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURCak1Rc3dDUVlEVlFRR0V3SlZVekVoTUI4R0ExVUVDaE1ZClZHaGxJRWR2SUVSaFpHUjVJRWR5YjNWd0xDQkpibU11TVRFd0x3WURWUVFMRXloSGJ5QkVZV1JrZVNCRGJHRnpjeUF5SUVObGNuUnAKWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUI0WERUQTBNRFl5T1RFM01EWXlNRm9YRFRNME1EWXlPVEUzTURZeU1Gb3dZekVMTUFrRwpBMVVFQmhNQ1ZWTXhJVEFmQmdOVkJBb1RHRlJvWlNCSGJ5QkVZV1JrZVNCSGNtOTFjQ3dnU1c1akxqRXhNQzhHQTFVRUN4TW9SMjhnClJHRmtaSGtnUTJ4aGMzTWdNaUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQ0NBU0F3RFFZSktvWklodmNOQVFFQkJRQUQKZ2dFTkFEQ0NBUWdDZ2dFQkFONmQxK3BYR0VtaFcrdlhYMGlHNnI3ZC8rVHZaeHowWldpelYzR2dYbmU3N1p0SjZYQ0FQVllZWXdodgoydkxNMEQ5L0FsUWlWQkRZc29IVXdIVTlTMy9IZDhNK2VLc2FBN1VnYXk5cUs3SEZpSDdFdXg2d3dkaEZKMitxTjFqM2h5YlgyQzMyCnFSZTNIM0kyVHFZWFAyV1lrdHNxYmwyaS9vamdDOTUvNVkwVjRldkxPdFhpRXFJVExkaU9yMThTUGFBSUJRaTJYS1ZsT0FSRm1SNmoKWUdCMHhVR2xjbUliWXNVZmIxOGFRcjRDVVdXb3JpTVlhdng0QTZsTmY0REQrcXRhL0tGQXBNb1pGdjZ5eU85ZWN3M3VkNzJhOW5tWQp2TEVIWjZJVkRkMmdXTVpFZXdvK1lpaGZ1a0VIVTFqUEVYNDRkTVg0LzdWcGtJK0VkT3FYRzY4Q0FRT2pnY0F3Z2Iwd0hRWURWUjBPCkJCWUVGTkxFc05LUjFFd1JjYk5oeXoyaC90Mm9hdFRqTUlHTkJnTlZIU01FZ1lVd2dZS0FGTkxFc05LUjFFd1JjYk5oeXoyaC90Mm8KYXRUam9XZWtaVEJqTVFzd0NRWURWUVFHRXdKVlV6RWhNQjhHQTFVRUNoTVlWR2hsSUVkdklFUmhaR1I1SUVkeWIzVndMQ0JKYm1NdQpNVEV3THdZRFZRUUxFeWhIYnlCRVlXUmtlU0JEYkdGemN5QXlJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNWdnRUFNQXdHCkExVWRFd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBREpMODdMS1BwSDhFc2FoQjR5T2Q2QXpCaFJja0I0WTl3aW0KUFFvWitZZUFFVzVwNUpZWE1QODBrV055T083TUhBR2pIWlFvcERIMmVzUlUxL2JsTVZnRG9zek9ZdHVVUlhPMXYwWEpKTFhWZ2dLdApJM2xwamJpMlRjN1BUTW96SStnY2lLcWRpMEZ1RnNrZzVZbWV6VHZhY1BkK21TWWdGRlFscTI1emhlYWJJWjBLYklJT3FQakNEUG9RCkhteVc3NGNOeEE5aGk2M3VneXVWK0k2U2hISTU2eURxZysyRHpaZHVDTHpyVGlhMmN5dmswL1pNL2laeDRtRVJkRXIvVnhxSEQzVkkKTHM5UmFSZWdBaEpobGRYUlFMSVFUTzdFckJCRHBxV2VDdFdWWXBvTno0aUN4VElNNUN1ZlJlWU5ueWljc2JrcVdsZXROdyt2SFgvYgp2Wjg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClN0YXJmaWVsZCBDbGFzcyAyIENBCj09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFRHpDQ0F2ZWdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURCb01Rc3dDUVlEVlFRR0V3SlZVekVsTUNNR0ExVUVDaE1jClUzUmhjbVpwWld4a0lGUmxZMmh1YjJ4dloybGxjeXdnU1c1akxqRXlNREFHQTFVRUN4TXBVM1JoY21acFpXeGtJRU5zWVhOeklESWcKUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3dIaGNOTURRd05qSTVNVGN6T1RFMldoY05NelF3TmpJNU1UY3pPVEUyV2pCbwpNUXN3Q1FZRFZRUUdFd0pWVXpFbE1DTUdBMVVFQ2hNY1UzUmhjbVpwWld4a0lGUmxZMmh1YjJ4dloybGxjeXdnU1c1akxqRXlNREFHCkExVUVDeE1wVTNSaGNtWnBaV3hrSUVOc1lYTnpJRElnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3dnZ0VnTUEwR0NTcUcKU0liM0RRRUJBUVVBQTRJQkRRQXdnZ0VJQW9JQkFRQzNNc2orNlhHbUJJV3REQkZrMzg1Tjc4Z0RHSWMvb2F2N1BLYWY4TU9oMnRUWQpiaXRUa1Bza3BENkU4SjdvWCt6bEowVDFLS1kvZTk3Z0t2RElyMU12bnNvRkFaTWVqMlljT2FkTitscTJjd1FsWnV0M2YrZFp4a3FaCkpSUlU2eWJIODM4WjFUQndqNit3UmlyL3Jlc3A3ZGVmcWdTSG85VDVpYVUwWDl0RGtZSTIyV1k4c2JpNWd2MmNPajRReUR2dkJtVm0KZXBzWkdEMy9jVkU4TUM1ZnZqMTNjN0pkQm16REkxYWFLNFVta2h5bkFyUGtQdzJ2Q0htQ3VEWTk2cHpUTmJPOGFjcjF6SjNvL1dTTgpGNEF6Ymw1S1habkpIb2UwblJyQTFXNFROU05lMzV0ZlBlL1c5M2JDNmo2N2VBMGNRbWRyQk5qNDF0cHZpL0pFb0FHckFnRURvNEhGCk1JSENNQjBHQTFVZERnUVdCQlMvWDdmUnp0MGZodlJiVmF6YzF4RENEcW1JNXpDQmtnWURWUjBqQklHS01JR0hnQlMvWDdmUnp0MGYKaHZSYlZhemMxeERDRHFtSTU2RnNwR293YURFTE1Ba0dBMVVFQmhNQ1ZWTXhKVEFqQmdOVkJBb1RIRk4wWVhKbWFXVnNaQ0JVWldObwpibTlzYjJkcFpYTXNJRWx1WXk0eE1qQXdCZ05WQkFzVEtWTjBZWEptYVdWc1pDQkRiR0Z6Y3lBeUlFTmxjblJwWm1sallYUnBiMjRnClFYVjBhRzl5YVhSNWdnRUFNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFBV2RQNGlkMGNrYVZhR3MKYWZQeldkcWJBWWNhVDFlcG9Ya0pLdHYzTDdJZXpNZGVhdGlEaDZHWDcwazFQbmNHUVZoaXY0NVl1QXBuUCt5ejNTRm1IOGxVK25MTQpQVXhBMklHdmQ1NkRlcnVpeC9VMEY0N1pFVUQwL0N3cVRSVi9wMkpkTGlYVEFBc2dHaDFvK1JlNDlMMkw3U2haM1UwV2l4ZUR5TEpsCnh5MTZwYXE4VTRadDNWZWt5dmdnUVF0bzhQVDdkTDVXWFhwNTlma2RoZU10bGI3MWNaQkR6STBmbWdBS2h5bnBWU0pZQUNQcTR4SkQKS1Z0SENOMk1RV3BsQnFqbElhcEJ0SlVobGJsOTBUU3JFOWF0dk56aVBUbk52VDUxY0tFWVdRUEpJclNQbk5WZUt0ZWx0dFFLYmZpMwpRQkZHbWg5NURtSy9ENWZzNEM4ZkY1UT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBCj09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHR6Q0NBcCtnQXdJQkFnSVFET2ZnNVJmWVJ2NlA1V0Q4Ry9Bd09UQU5CZ2txaGtpRzl3MEJBUVVGQURCbE1Rc3dDUVlEVlFRRwpFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzZDNjdVpHbG5hV05sY25RdVkyOXRNU1F3CklnWURWUVFERXh0RWFXZHBRMlZ5ZENCQmMzTjFjbVZrSUVsRUlGSnZiM1FnUTBFd0hoY05NRFl4TVRFd01EQXdNREF3V2hjTk16RXgKTVRFd01EQXdNREF3V2pCbE1Rc3dDUVlEVlFRR0V3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTApFeEIzZDNjdVpHbG5hV05sY25RdVkyOXRNU1F3SWdZRFZRUURFeHRFYVdkcFEyVnlkQ0JCYzNOMWNtVmtJRWxFSUZKdmIzUWdRMEV3CmdnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN0RGhYTzVFT0FYTEdIODdkZytYRVNwYTdjSnBTSXF2VE8KOVNBNUtGaGdEUGlBMnFrVmxUSmhQTFd4S0lTS2l0eWZDZ3lERjNxUGtLeUs1M2xUWERHRUt2WVBtREkyZHN6ZTNUeW9vdTlxK3lIeQpVbUhmbnlEWEgrS3gyZjRZWk5JU1cxLzVXQmcxdkVmTm9UYjVhMy9Vc0RnK3dSdkRqRFBaMkM4WS9pZ1BzNmVEMXNOdVJNQmhOWllXCi9sbWNpM1p0MS9HaVN3MHIvd3R5MnA1ZzBJNlFOY1o0VlljZ29jL2xiUXJJU1h3eG1ETnNJdW1IMERKYW9yb1RnaEh0T1JlZG1UcHkKb2ViNnBOblZGekYxcm9WOUlxNC9BVWFHOWloNXlMSGE1RmNYeEg0Y0RyQzBrcVpXczcyeWwrMnFwL0MzeGFnL2xSYlEvNkdXNndoZgpHSGRQQWdNQkFBR2pZekJoTUE0R0ExVWREd0VCL3dRRUF3SUJoakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlJGCjY2S3Y5SkxMZ2pFdFVZdW5weUdkODIzSUR6QWZCZ05WSFNNRUdEQVdnQlJGNjZLdjlKTExnakV0VVl1bnB5R2Q4MjNJRHpBTkJna3EKaGtpRzl3MEJBUVVGQUFPQ0FRRUFvZzY4MytMdDhPTnljM3BrbEwvM2NtYllNdVJDZFdLdWgrdnkxZG5lVnJPZnpNNFVLTGtObDJCYwpFa3hZNU5NOWcwbEZXSmMxYVJxb1IrcFd4bm1yRXRobmdZVGZmd2s4bE9hNEppd2d2VDJ6S0luM1gvOGk0cGVFSCtsbDc0ZmczOEZuClNiTmQ2N0lKS3VzbTdYaStmVDhyODdjbU5XMWZpUUcyU1Z1ZkFRV2JxejBsd2N5MmY4THhiNGJHK21SbzY0RXRsT3RDdC9xTUh0MWkKOGI1UVo3ZHN2ZlB4SDJzTU5nY1dmemQ4cVZ0dGV2RVNSbUNEMXljRXZrdk9sNzdEWnlwb0VkK0E1d3d6WnI4VERSUnU4MzhmWXhBZQorbzBiSlcxc2o2VzNZUUd4MHFNbW9SQnhuYTNpdy9uRG1WRzNLd2NJemk3bVVMS24rZ3BGTDZMdzhnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRGlnaUNlcnQgR2xvYmFsIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURyekNDQXBlZ0F3SUJBZ0lRQ0R2Z1ZwQkNSckdoZFdySldaSEhTakFOQmdrcWhraUc5dzBCQVFVRkFEQmhNUXN3Q1FZRFZRUUcKRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCM2QzY3VaR2xuYVdObGNuUXVZMjl0TVNBdwpIZ1lEVlFRREV4ZEVhV2RwUTJWeWRDQkhiRzlpWVd3Z1VtOXZkQ0JEUVRBZUZ3MHdOakV4TVRBd01EQXdNREJhRncwek1URXhNVEF3Ck1EQXdNREJhTUdFeEN6QUpCZ05WQkFZVEFsVlRNUlV3RXdZRFZRUUtFd3hFYVdkcFEyVnlkQ0JKYm1NeEdUQVhCZ05WQkFzVEVIZDMKZHk1a2FXZHBZMlZ5ZEM1amIyMHhJREFlQmdOVkJBTVRGMFJwWjJsRFpYSjBJRWRzYjJKaGJDQlNiMjkwSUVOQk1JSUJJakFOQmdrcQpoa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTRqdmhFWExlcUtUVG8xZXFVS0tQQzNlUXlhS2w3aExPbGxzQkNTRE1BWk9uClRqQzNVL2REeEdrQVY1M2lqU0xkaHdaQUFJRUp6czRiZzcvZnpUdHhSdUxXWnNjRnMzWW5Gbzk3bmg2VmZlNjNTS01JMnRhdmVndzUKQm1WL1NsMGZ2QmY0cTc3dUtOZDBmM3A0bVZtRmFHNWNJekpMdjA3QTZGcHQ0M0MvZHhDLy9BSDJoZG1vUkJCWU1xbDFHTlhSb3I1SAo0aWRxOUpveitFa0lZSXZVWDdRNmhMK2hxa3BNZlQ3UFQxOXNkbDZnU3plUm50d2k1bTNPRkJxT2Fzdit6Yk1VWkJmSFd5bWVNci95Cjd2clRDMExVcTdkQk10b00xTy80Z2RXN2pWZy90UnZvU1NpaWNOb3hCTjMzc2hieVRBcE9CNmp0U2oxZXRYK2prTU92SndJREFRQUIKbzJNd1lUQU9CZ05WSFE4QkFmOEVCQU1DQVlZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUE5NVFOVmJSVEx0bQo4S1BpR3h2RGw3STkwVlV3SHdZRFZSMGpCQmd3Rm9BVUE5NVFOVmJSVEx0bThLUGlHeHZEbDdJOTBWVXdEUVlKS29aSWh2Y05BUUVGCkJRQURnZ0VCQU11Y042cElFeElLK3QxRW5FOVNzUFRmcmdUMWVYa0lveVFZL0VzcmhNQXR1ZFhIL3ZUQkgxakx1RzJjZW5Ubm1DbXIKRWJYamNLQ2h6VXlJbVpPTWtYRGlxdzhjdnBPcC8yUFY1QWRnMDZPL25Wc0o4ZFdPNDFQMGptUDZQNmZidEdiZlltYlcwVzVCamZJdAp0ZXAzU3ArZFdPSXJXY0JBSSswdEtJSkZQbmxVa2lhWTRJQklxRGZ2OE5aNVlCYmVyT2dPelc2c1JCYzRMMG5hNFVVK0tyazJVODg2ClVBYjNMdWpFVjBsc1lTRVkxUVN0ZUR3c09vQnJwK3V2RlJUcDJJbkJ1VGhzNHBGc2l2OWt1WGNsVnpEQUd5U2o0ZHpwMzBkOHRiUWsKQ0FVdzdDMjlDNzlGdjFDNXFmUHJtQUVTcmNpSXhwZzBYNDBLUE1icDFaV1ZiZDQ9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHhUQ0NBcTJnQXdJQkFnSVFBcXhjSm1vTFFKdVBDM255cmtZbGR6QU5CZ2txaGtpRzl3MEJBUVVGQURCc01Rc3dDUVlEVlFRRwpFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzZDNjdVpHbG5hV05sY25RdVkyOXRNU3N3CktRWURWUVFERXlKRWFXZHBRMlZ5ZENCSWFXZG9JRUZ6YzNWeVlXNWpaU0JGVmlCU2IyOTBJRU5CTUI0WERUQTJNVEV4TURBd01EQXcKTUZvWERUTXhNVEV4TURBd01EQXdNRm93YkRFTE1Ba0dBMVVFQmhNQ1ZWTXhGVEFUQmdOVkJBb1RERVJwWjJsRFpYSjBJRWx1WXpFWgpNQmNHQTFVRUN4TVFkM2QzTG1ScFoybGpaWEowTG1OdmJURXJNQ2tHQTFVRUF4TWlSR2xuYVVObGNuUWdTR2xuYUNCQmMzTjFjbUZ1ClkyVWdSVllnVW05dmRDQkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNYk01WFBtKzlTNzVTMHQKTXFiZjVZRS95YzBsU2JaeEtzUFZsRFJub2dvY3NGOXBwa0N4eExleWo5Q1lwS2xCV1RyVDNKVFdQTnQwT0tSS3pFMGxndmRLcFZNUwpPTzd6U1cxeGtYNWp0cXVtWDhPa2hQaFBZbEcrK01YczJ6aVM0d2JsQ0pFTXhDaEJWZnZMV29rVmZuSG9OYjlOY2drOXZqbzRVRnQzCk1SdU5zOGNrUlpxbnJHMEFGRm9FdDdvVDYxRUttRUZCSWs1bFlZZUJRVkNtZVZ5SjNobEtWOVV1NWwwY1V5eCttTTBhQmhha2FIUFEKTkFRVFhLRngwMXA4VmR0ZVpPRTNoekJXQk9VUnRDbUFFdkY1T1lpaUFoRjhKMmEzaUxkNDhzb0txRGlyQ21UQ3YyWmRsWVRCb1NVZQpoMTBhVUFzZ0VzeEJ1MjRMVVRpNFM4c0NBd0VBQWFOak1HRXdEZ1lEVlIwUEFRSC9CQVFEQWdHR01BOEdBMVVkRXdFQi93UUZNQU1CCkFmOHdIUVlEVlIwT0JCWUVGTEUrdzJrRCtMOUhBZFNZSmhvSUF1OWpaQ3ZETUI4R0ExVWRJd1FZTUJhQUZMRSt3MmtEK0w5SEFkU1kKSmhvSUF1OWpaQ3ZETUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFBY0dnYVgzTmVjbnp5SVpnWUlWeUhiSVVmNEttZXF2eGd5ZGtBUQpWOEdLODNyWkVXV09OZnFlL0VXMW50bE1NVXU0a2VoRExJNnplTTdiNDFONWNkYmxJWlFCMmxXSG1pUms5b3Btek42Y044Mm9OTEZwCm15UElubmdpSzNCRDQxVkhNV0VaNzFqRmhTOU9NUGFnTVJZanlPZmlaUll6eTc4YUc2QTkrTXBlaXpHTFlBaUpMUXdHWEZLM3hQa0sKbU5FVlg1OFN2bncyWXppOVJLUi81Q1lyQ3NTWGFRM3BqT0xBRUZlNHlIWVNrVlh5U0duWXZDb0NXdzlFMUNBeDIvUzZjQ1pka0dDZQp2RXNYQ1MrMHl4NURhTWtISjhIU1hQZnFJYmxvRXB3OG5MK2UvSUJjbTJQTjdFZXFKU2Rub0RmekFJSjlWTmVwK09rdUU2TjM2QjlLCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkRTVCBSb290IENBIFgzCj09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEU2pDQ0FqS2dBd0lCQWdJUVJLK3dnTmFqSjdxSk1EbUdMdmhBYXpBTkJna3Foa2lHOXcwQkFRVUZBREEvTVNRd0lnWURWUVFLCkV4dEVhV2RwZEdGc0lGTnBaMjVoZEhWeVpTQlVjblZ6ZENCRGJ5NHhGekFWQmdOVkJBTVREa1JUVkNCU2IyOTBJRU5CSUZnek1CNFgKRFRBd01Ea3pNREl4TVRJeE9Wb1hEVEl4TURrek1ERTBNREV4TlZvd1B6RWtNQ0lHQTFVRUNoTWJSR2xuYVhSaGJDQlRhV2R1WVhSMQpjbVVnVkhKMWMzUWdRMjh1TVJjd0ZRWURWUVFERXc1RVUxUWdVbTl2ZENCRFFTQllNekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTit2NlpkUUNJTlh0TXhpWmZhUWd1ekgweXhyTU1wYjdObkRmY2RBd1JnVWkrRG9NM1pKS3VNL0lVbVQKckU0T3J6NUl5Mlh1L05NaEQyWFNLdGt5ajR6bDkzZXdFbnUxbGNDSm82bTY3WE11ZWd3R01vT2lmb29VTU0wUm9PRXFPTGw1Q2pIOQpVTDJBWmQrM1VXT0R5T0tJWWVwTFlZSHNVbXU1b3VKTEdpaWZTS09lRE5vSmpqNFhMaDdkSU45YnhpcUtxeTY5Y0szRkN4b2xrSFJ5CnhYdHFxelRXTUluLzVXZ1RlMVFMeU5hdTdGcWNraDQ5WkxPTXh0Ky95VUZ3N0JaeTFTYnNPRlU1UTlEOC9SaGNRUEdYNjlXYW00MGQKdXRvbHVjYlkzOEVWQWpxcjJtN3hQaTcxWEFpY1BOYURhZVFRbXhrcXRpbFg0K1U5bTUvd0FsMENBd0VBQWFOQ01FQXdEd1lEVlIwVApBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwT0JCWUVGTVNuc2FSN0xISDYyK0ZMa0hYL3hCVmdoWWtRCk1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQ2pHaXliRndCY3FSN3VLR1kzT3IrRHh6OUx3d21nbFNCZDQ5bFpSTkkrRFQ2OWlrdWcKZEIvT0VJS2NkQm9kZnBnYTNjc1RTN01nUk9TUjZjejhmYVhiYXVYKzV2M2dUdDIzQURxMWNFbXY4dVhyQXZIUkFvc1p5NVE2WGtqRQpHQjVZR1Y4ZUFscndEUEd4cmFuY1dZYUxidW1SOVliSytybG1NNnBaVzg3aXB4WnpSOHNyekptd04walA0MVpMOWM4UERISXloOGJ3ClJMdFRjbTFEOVNaSW1sSm50MWlyL21kMmNYamJEYUpXRkJNNUpER0ZvcWdDV2pCSDRkMVFCN3dDQ1pBQTYyUmpZSnNXdklqSkV1YlMKZlpHTCtUMHlqV1cwNlh5eFYzYnF4YllvT2I4VlpSekk5bmVXYWdxTmR3dllrUXNFamdmYktiWUs3cDJDTlRVUQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTd2lzc1NpZ24gR29sZCBDQSAtIEcyCj09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ1akNDQTZLZ0F3SUJBZ0lKQUx0QUhFUDFYayt3TUEwR0NTcUdTSWIzRFFFQkJRVUFNRVV4Q3pBSkJnTlZCQVlUQWtOSU1SVXcKRXdZRFZRUUtFd3hUZDJsemMxTnBaMjRnUVVjeEh6QWRCZ05WQkFNVEZsTjNhWE56VTJsbmJpQkhiMnhrSUVOQklDMGdSekl3SGhjTgpNRFl4TURJMU1EZ3pNRE0xV2hjTk16WXhNREkxTURnek1ETTFXakJGTVFzd0NRWURWUVFHRXdKRFNERVZNQk1HQTFVRUNoTU1VM2RwCmMzTlRhV2R1SUVGSE1SOHdIUVlEVlFRREV4WlRkMmx6YzFOcFoyNGdSMjlzWkNCRFFTQXRJRWN5TUlJQ0lqQU5CZ2txaGtpRzl3MEIKQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBcitUdWZvc2tEaEp1cVZBdEZrUTdrcEpjeXJoZGhKSkNFeXE4WlZlQ1FENVhKTTFRaXlVcQp0Mi84NzZMUXdCOENKRW9UbG84akUrWW9XQUNqUjhjR3A0UWpLN3U5bGl0L1ZjeUx3VmNmRG1KbEQ5MDlWb3B6MnE1K2JicUJISDVDCmpDQTEyVU5OaFBxRTIxSXM4dzRuZHd0cnZ4RXZjbmlmTHRnKzVoZzNXaXB5K2RwaWtKS1Z5aCtjNmJNOEs4dnpBUk8vV3MvQnRRcGcKdmQyMW1XUlR1S0NXczIvaUpuZVJqT0JpRUFLZk5BK2sxWkl6VWQ2K2picUVlbUE4YXR1ZksremUzZ0UvYmszbFVJYkx0Sy90UkVERgp5bHFNMnRJcmZLanV2cWJsQ3FvT3BkOEZVcmRWeHlKZE1tcVhsMk1UMjhuYmVUWjdoVHBLeFZLSitTVG5uWGVwZ3Y5VkhLVnhhU3ZSCkFpVHlzeWJVYTlvRVZlWEJDc2R0TURlUUt1U2VGRE5lRmhkVnhWdTF5elNKa3ZHZEpvK2hCOVRHc25oUTJ3d01DM3dMakVIWHVlbmQKaklqM28wMnlNc3pZRjlyTnQ4NW1uZFQ5WHYrOWx6NHBkZWQrcDJKWXJ5VTBwVUhIUGJ3TlVNb0RBdzhJV2grVmMzaGl2Njl5RkdrTwpwZVVERG5pT0ppaEM4QWNMWWlBUVp6bEcrcWtEekFRNGVtYnZJSU8xakVwV2pwRUEvSTVjZ3Q2SW9NUGlhRzU5amU4ODNXWDBYYXhSCjd5U0FycXBXbDIvNXJYM2FZVCtZZHp5bGtiWWNqQ2JhWmFJSmJjSGlWT081eWt4TWdJOTNlMkNhSHQrMjhrZ2VEcnBPVkcyWTRPR2kKR3FKM1VNL0VZNUxzUnhtZDYrWnJ6c0VDQXdFQUFhT0JyRENCcVRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVdwpBd0VCL3pBZEJnTlZIUTRFRmdRVVd5VjdscVJsVVg2NE9mUEFlR1plNkRybjhPNHdId1lEVlIwakJCZ3dGb0FVV3lWN2xxUmxVWDY0Ck9mUEFlR1plNkRybjhPNHdSZ1lEVlIwZ0JEOHdQVEE3QmdsZ2hYUUJXUUVDQVFFd0xqQXNCZ2dyQmdFRkJRY0NBUllnYUhSMGNEb3YKTDNKbGNHOXphWFJ2Y25rdWMzZHBjM056YVdkdUxtTnZiUzh3RFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUNlNjQ1Ujg4YTdBM2hmbQo1ZGpWOVZTd2cvUzd6VjRGZTArZmRXYXZQT2hXZnZ4eWVEZ0QyU3RpR3dDNStPbGd6Y3pPVVlySFVERnU0VXArR0M5cFdiWTlaSUVyCjQ0T0U1aUtIam4zZzdnS1pZYmdlOUxncmlCSVdoTUl4a3ppV01hYTVPMU0vd3lTVFZsdHBrdXpGd2JzNEFPUHNGNm00M01kOEFZT2YKTWtlNlVpSTBIVEo2Q1ZhbmZDVTJxVDFMMnNDQ2J3cTdFc2lIU3ljUitSNHR4NU0vbnR0ZkptdFMyUzZLOFJUR1JJMFZxYmUvdmQ2bQpHdTZ1TGZ0SWR4Zit1K3l2R1BVcVVmQTVoSmVWYkc0Ynd5dkVkR0I1SmJBS0o5L2ZYdEk1ejBWOVFrdmZzeXdleGNaZHlsVTZvSnhwCm1vL2E3N0t3UEorSGJCSXJaWEFWVWpFYUpNOXZNU05RSDR4UGp5UERkRUZqSEZXb0ZOMCs0RkZRei9FYk1GWU9rckNDaGRpRHl5SmsKdkMyNEpkVlVvcmdHNnEyU3BDU2d3WWExU2hOcVI4OHVDMWFWVk12T210dHF0S2F5MjBFSWhpZDM5MnFnUW13TE9NN1hkVkF5a3NMZgpLekFpU05EVlFUZ2xYYVRwWFovR2xIWFFSZjB3bDBPUGtLc0t4NFp6WUVwcExkNmxlTmNHMm1xZVN6NTNPaUFUSWdIUXYyaWVZMkJyCk5VMExiYnFoUGNDVDRIOGpzMVd0Y2lWT1J2blNGdSt3Wk1FQm51bktvR3FZRHMvWVlQSXZTYmprUXVFNE5SYjB5RzVQOTRGVzZMcWoKdmlPdnJ2MXZBK0FDT3pCMitodHRRYzhCc2VtNHlXYjAyeWJ6T3FSMDhra2tXOG13MEZmQitqNTY0WmZKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClN3aXNzU2lnbiBTaWx2ZXIgQ0EgLSBHMgo9PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ2VENDQTZXZ0F3SUJBZ0lJVHh2VUwxUzdMMHN3RFFZSktvWklodmNOQVFFRkJRQXdSekVMTUFrR0ExVUVCaE1DUTBneEZUQVQKQmdOVkJBb1RERk4zYVhOelUybG5iaUJCUnpFaE1COEdBMVVFQXhNWVUzZHBjM05UYVdkdUlGTnBiSFpsY2lCRFFTQXRJRWN5TUI0WApEVEEyTVRBeU5UQTRNekkwTmxvWERUTTJNVEF5TlRBNE16STBObG93UnpFTE1Ba0dBMVVFQmhNQ1EwZ3hGVEFUQmdOVkJBb1RERk4zCmFYTnpVMmxuYmlCQlJ6RWhNQjhHQTFVRUF4TVlVM2RwYzNOVGFXZHVJRk5wYkhabGNpQkRRU0F0SUVjeU1JSUNJakFOQmdrcWhraUcKOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQXhQR0hmOU40TWZjNHlmakRtVU84eC9lOE4rZE9jYnBMajZWekhWeHVtSzREVjY0NApOME12RnowZnlNNW9FTUY0cmhrREt4RDZMSG1EOXVpNWFMbFY4Z1JFcHpuNS9BU0xIdkdpVFNmNVlYdTZ0K1dpRTdicllUN1FiTkhtCisvcGU3UjIwbnFBMVc2R1N5L0JKa3Y2RkNnVSs1dGtMNGsrNzNKVTMvSkhwTWpVaTBSODZUaWVGbmJBVmxETGFZUTFIVFdCQ3JwSkgKNklOYVVGanBpb3U1WGFIYzNabEtIelpudTBqa2c3WTM2MGc2cnc5bmp4Y0g2QVRLNzJveGg5VEF0dm1VY1h0blpMaTJrVXBDZTJVdQpNR29NOVpEdWxlYnl6WUxzMmFGSzdQYXlTK1ZGaGVadGVKTUVMcHlDYlRhcHhERmtINGFEQ3lyME5RcDR5VlhQUWJCSDZUQ2ZtYjVoCnFBYUV1U2g2WHpqWkc2azRzSU4vYzhIRE8wZ3FnZzhobTdqTXFEWERoQnVEc3o2K3BKVnBBVHFKQUhnRTJjbjBtUm1yVm41Ymk0WTUKRlpHa0VDd0pNb0JnczVQQUtyWVlDNTEralVueUVFcC8rZFZHTHhtU281bW5KcXk3akR6bURyeEhCOXh6VWZGd1pDOEkrYlJISFRCcwpST29wTjRXU2FHYThnemorZXprdTAxRHdIL3RlWUxhcHB2b25RZkdiR0hMeTlZUjBTc2xueEZTdVNHVGZqTkZ1c0IzaEI0OElIcG1jCmNlbE0yS1gzUnhJZmRORlJub2J6d3FJalFBdHoyMHVtNTNNR2pNR2c2Y0ZackViNjVpLzR6M0djUm0yNXhCV05PSGtEUlVqdnhGM1gKQ082SE9TS0dzZzBQV0VQM2NhbElMdjNxMWg4Q0F3RUFBYU9CckRDQnFUQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVGNkROd2VSQnRqcGJPOHRGbmIwY3dwajZobGd3SHdZRFZSMGpCQmd3Rm9BVUY2RE53ZVJCCnRqcGJPOHRGbmIwY3dwajZobGd3UmdZRFZSMGdCRDh3UFRBN0JnbGdoWFFCV1FFREFRRXdMakFzQmdnckJnRUZCUWNDQVJZZ2FIUjAKY0RvdkwzSmxjRzl6YVhSdmNua3VjM2RwYzNOemFXZHVMbU52YlM4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFIUEdnZUFuMGkwUAo0SlV3NHBwQmYxQXNYMTlpWWFtR2Fta1lESFJKMWwyRTZrRlNHRzlZclZCV0lHckd2U2hwV0pIY2tSRTFxVG9kdkJxbFlKN1lIMzlGCmtXblpmcnQ0Y3NFR0R5ck9qNFZ3WWF5Z3pRdTRPU2xXaERKT2hyczl4Q3JaMXg5eTd2NVJvU0pCc1hFQ1l4cUNzR0tyWGxjU0g5L0wKM1hXZ3dGMTVrSXdiNEZEbTNqSCttSHR3WDZXUTJLMzRBclp2MDJEZFFFc2l4VDJ0T25xZkdocEhrWGt6dW9MY01ta0RsbTRmUy9CeAovdU5uY3FDeHYxeUw1UHFaSXNlRXVSdU5JNWMvN1NYZ3oyVzc5V0VFNzkwZXNscEJJbHFobjEwczZGdkpiYWtNREhpcVlNWldqd0ZhCkRHaThhUmw1eEI5K2x3Vy94ZWtrVVY3VTFVdFQ3ZGtqV2pZRFphUEJBNjFCTVBOR0c0V1FyMlcxMWJIa0ZsdDRkUjJYZW0xWnFTcVAKZTk3RGg0a1FtVWx6ZU1nOXZWRTFkQ3JWOFg1cEd5cTdPNzBsdUpwYVBYSmhrR2FIN2d6V1RkUVJkQXRxL2dzRC9LTlZWNG4rU3N1dQpXeGNGeVBLTkl6RlRPTkl0YWorQ3VZMElhdmRlUVhSdXd4RitCNndwWUpFL09NcFhFQTI5TUMvSHBlWkJvTnF1QlllYW9LUmxiRXdKCkRJbTZ1Tk81d0pPS01QcU41WnByRlFGT1o2cmFZbFkraEFobTBzUTJmYWMrRVB5STROU0E1UUM5cXZOT0JxTjZhdmxpY3VNSlQrdWIKRGdFajhaKzdmTnpjYkJHWEpiTHl0R01VMGdZcVo0eUQ5YzdxQjlpYWFoN3M1QXE3S2t6ckNXQTV6c3BpMkM1dQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTZWN1cmVUcnVzdCBDQQo9PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHVEQ0NBcUNnQXdJQkFnSVFEUENPWEFnV3BhMUNmL0RySnhoWjBEQU5CZ2txaGtpRzl3MEJBUVVGQURCSU1Rc3dDUVlEVlFRRwpFd0pWVXpFZ01CNEdBMVVFQ2hNWFUyVmpkWEpsVkhKMWMzUWdRMjl5Y0c5eVlYUnBiMjR4RnpBVkJnTlZCQU1URGxObFkzVnlaVlJ5CmRYTjBJRU5CTUI0WERUQTJNVEV3TnpFNU16RXhPRm9YRFRJNU1USXpNVEU1TkRBMU5Wb3dTREVMTUFrR0ExVUVCaE1DVlZNeElEQWUKQmdOVkJBb1RGMU5sWTNWeVpWUnlkWE4wSUVOdmNuQnZjbUYwYVc5dU1SY3dGUVlEVlFRREV3NVRaV04xY21WVWNuVnpkQ0JEUVRDQwpBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUt1a2dlV1Z6ZlgyRkk3Q1Q4clU0bmlWV0p4QjRRMlpRQ1FYCk9aRXpadW0rNFlPdllseUowZndrVzJHejRCRVJRUndkYnZDNHUvamVwNEc2cGtqR254Mjl2bzZwUVQ2NGxPMHBHdFNPMGdNZEErOXQKRFdjY1Y5Y0dyY3JJOWY0T3IyWWxTQVNXQzEyanVoYkRDRS9SUnZnVVhQTElYZ0daYmYySXpJYW93Vzh4UW14U1Btakw4eGswMzd1SApHRmFBSnNUUTNNQnYzOTZnd3BFV29HUVJTMFM4SHZibittUGVacXgycEhHajdEYVVhSHAzcExIbkRpK0JldUsxY29idm9tdUw4QS9iCjAxay91bks4UkNTYzQzT3o5NjlYTDBJbW5hbDB1Z0JTOGt2TlUzeEhDemFGRG1hcENKY1dORmZCWnZlQTQrMXdWTWVUNEM0b0ZWbUgKdXJzQ0F3RUFBYU9CblRDQm1qQVRCZ2tyQmdFRUFZSTNGQUlFQmg0RUFFTUFRVEFMQmdOVkhROEVCQU1DQVlZd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVRaksyRnZvRS9mNWRTM3JEL2ZkTVFCMWFRNjh3TkFZRFZSMGZCQzB3S3pBcG9DZWdKWVlqCmFIUjBjRG92TDJOeWJDNXpaV04xY21WMGNuVnpkQzVqYjIwdlUxUkRRUzVqY213d0VBWUpLd1lCQkFHQ054VUJCQU1DQVFBd0RRWUoKS29aSWh2Y05BUUVGQlFBRGdnRUJBRER0VDByaFdEcFNjbHUxcHFObEdLYTdVVHQzNlozcTA1OWM0RVZsZXczS1crSndVTEtVQlJTdQpTY2VOUVFjU2M1UitEQ01oL2J3UWYyQVFXbkwxbUE2czdMbC8zWHB2WGRNYzlQK0lCV2xDcVFWeHlMZXNKdWd1dEl4cS8zSGN1TEhmCm1ieDhJVlFyNUZpaXUxY3BycDZwb3hrbUQ1a3VDTER2L1duUG1Sb0pqZU9ubnl2Sk5qUjdKTE40VEpVWHBBWW1IclprVWpaZllHZloKbk1VRmRBdm5aeVBTQ1B5STZhNkxmK0V3OURkKy9jWXkyaTJlUkRBd2JPNEgzdEkwL05ML1FQWkw5R1pHQmxTbThqSUtZeVl3YTV2UgozSXRIdXVHNTFXTFFvcUQwWndWNEtXTWFid1RXK01aTW81cXhON1NONVNoTEhaNHN3cmhvdk8wQzdqRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU2VjdXJlIEdsb2JhbCBDQQo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEdkRDQ0FxU2dBd0lCQWdJUUIxWWlwT2pVaW9sTjlCUEk4UGpxcFRBTkJna3Foa2lHOXcwQkFRVUZBREJLTVFzd0NRWURWUVFHCkV3SlZVekVnTUI0R0ExVUVDaE1YVTJWamRYSmxWSEoxYzNRZ1EyOXljRzl5WVhScGIyNHhHVEFYQmdOVkJBTVRFRk5sWTNWeVpTQkgKYkc5aVlXd2dRMEV3SGhjTk1EWXhNVEEzTVRrME1qSTRXaGNOTWpreE1qTXhNVGsxTWpBMldqQktNUXN3Q1FZRFZRUUdFd0pWVXpFZwpNQjRHQTFVRUNoTVhVMlZqZFhKbFZISjFjM1FnUTI5eWNHOXlZWFJwYjI0eEdUQVhCZ05WQkFNVEVGTmxZM1Z5WlNCSGJHOWlZV3dnClEwRXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDdk5TN1lyR3hWYVFaeDVSTm9KTE5QMk13aFIvangKWURpSmlRUHB2ZXBlUmxNSjNGejFXdWozUlNvQzZ6RmgxeWt6VE03SGZBbzNmZys2TXBqaEhaZXZqOGZjeVRpVzg5c2EvRkh0YU1iUQpicVI4Sk5HdVFzaVdVR011NFA1MS9waW5YMGt1bGVNNU0yU09IcVJma05KblBMTFova0c1VmFjSmpuSUZIb3ZkUklXQ1F0Qkp3QjFnCjhORVhMSlhyOXFYQmtxUEZ3cWNJWUExZ0JCQ1dlWjRXTk9hcHR2b2xSVG5JSG1YNWsvV3E4VkxjbVpnOXBZWWFERFV6K2t1bEJBWVYKSERHQTc2b1lhOEo3MTlyTytUTWcxZlc5YWpNdGdRVDdzRnpVbktQaVhCM2pxVUoxWG52VWQrODVWTHJKQ2hnYkVwbEpMNGhML1ZCaQowWFBuajNwREFnTUJBQUdqZ1owd2dab3dFd1lKS3dZQkJBR0NOeFFDQkFZZUJBQkRBRUV3Q3dZRFZSMFBCQVFEQWdHR01BOEdBMVVkCkV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGSzlFQk1KQmZraUQyMDQ1QXV6c2hIcm16c21rTURRR0ExVWRId1F0TUNzd0thQW4Kb0NXR0kyaDBkSEE2THk5amNtd3VjMlZqZFhKbGRISjFjM1F1WTI5dEwxTkhRMEV1WTNKc01CQUdDU3NHQVFRQmdqY1ZBUVFEQWdFQQpNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUJqR2doQWZhUmVVdzEzMkhxdUh3MExVUllEN3hoOHlPT3ZhbGlURkdDUnNvVGNpRTYrCk9ZbzY4K2FDaVYwQk43T3JKS1FWRHBJMVdrcEVYazVYK25YT0gwak9adlE4UUNhU21Hd2I3aVJHREJlelVxWGJwWkdSenpmVGIrY24KQ0RwT0dSODZwMWhjRjg5NVA0dmtwOU1tSTUwbUQxaHAvRWQrc3RDTmk1Ty9LVTlEYVhSMlowdlBCNHptQXZlMTRiUkR0VXN0RkovNQozQ1lOdjZaSGRBYllpTkU2S1RDRXp0STVnR0licU1kWFNieHFWVkZuRlVxK05RZmsxWFdZTjNrd0ZOc3BuV3pGYWN4SFZhSXc5OHhjCmY4TERtQnhyVGhhQTYzcDRaVVdpQUJxdkRBMVZaRFJJdUpLNThiUlFLZkpQSXgvYWJLd2ZST0hkSTNoUlc4Y1cKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRUhUQ0NBd1dnQXdJQkFnSVFUb0V0aW9KbDRBc0M3ajQxQWtibFBUQU5CZ2txaGtpRzl3MEJBUVVGQURDQmdURUxNQWtHQTFVRQpCaE1DUjBJeEd6QVpCZ05WQkFnVEVrZHlaV0YwWlhJZ1RXRnVZMmhsYzNSbGNqRVFNQTRHQTFVRUJ4TUhVMkZzWm05eVpERWFNQmdHCkExVUVDaE1SUTA5TlQwUlBJRU5CSUV4cGJXbDBaV1F4SnpBbEJnTlZCQU1USGtOUFRVOUVUeUJEWlhKMGFXWnBZMkYwYVc5dUlFRjEKZEdodmNtbDBlVEFlRncwd05qRXlNREV3TURBd01EQmFGdzB5T1RFeU16RXlNelU1TlRsYU1JR0JNUXN3Q1FZRFZRUUdFd0pIUWpFYgpNQmtHQTFVRUNCTVNSM0psWVhSbGNpQk5ZVzVqYUdWemRHVnlNUkF3RGdZRFZRUUhFd2RUWVd4bWIzSmtNUm93R0FZRFZRUUtFeEZEClQwMVBSRThnUTBFZ1RHbHRhWFJsWkRFbk1DVUdBMVVFQXhNZVEwOU5UMFJQSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjUKTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEwRUNMaTNMamtSdjNVY0ViVkFTWTA2bS93ZWFLWFR1SAorN3VJemczakx6OEdsdkNpS1ZDWnJ0czdvVmV3ZEZGeHplMUNrVTFCL3FuSTJHcUdkMFM3V1dhWFVGNjAxQ3h3Uk0vYU41VkNhVHd3CnhIR3pVdkFoVGFIWXVqbDhISjZqSkozeWd4YVlxaFo4UTVzVlc3ZXVOSkgrMUdJbUdFYWFQK3ZCK2ZHUVYrdXNlZzJMMjNJd2FtYlYKNEVhamNOeG8yZjhFU0lsMzNyWHArMmR0UWVtOE9iMHkyV0lDOGJHb1BXNDNuT0l2NHRPaUpvdkd1RlZEaU9FalBxWFNKRGxxUjZzQQoxS0d6cVNYK0RUK25IYnJUVWNFTHBOcXNPTzlWVUNRRlpVYVRORTh0amEzRzFDRVowbzdLQldGeEIzTkg1WW9aRXIwRVRjNU9uS1ZJCnJMc205d0lEQVFBQm80R09NSUdMTUIwR0ExVWREZ1FXQkJRTFdPV0x4a3dWTjZSQXFUQ3BJYjVITmxwVy96QU9CZ05WSFE4QkFmOEUKQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QkpCZ05WSFI4RVFqQkFNRDZnUEtBNmhqaG9kSFJ3T2k4dlkzSnNMbU52Ylc5awpiMk5oTG1OdmJTOURUMDFQUkU5RFpYSjBhV1pwWTJGMGFXOXVRWFYwYUc5eWFYUjVMbU55YkRBTkJna3Foa2lHOXcwQkFRVUZBQU9DCkFRRUFQcGllbS9ZYjZkYzV0M2l1SFhJWVNkT0g1RU9DNnovSnF2V290ZTlWZkNGU1pmblZEZUZzOUQ2TWszT1JMZ0xFVGdkeGI4Q1AKT0dFSXFCNkJDc0F2SUM5Qmk1SGNTRVc4OGNiZXVuWnJNOGdBTFRGR1RPM25uYytJbFA4endGYm9KSVltdU5nNE9OOHFhOTBTek1jLwpSeGRNb3NJR2xnblcyLzQvUEVaQjMxamlWZzg4TzhFY2t6WFpPRktzN3Nqc0xqQk9sRFcwSkI5TGVHbmE4Z0k0ekpWU2svQndKVm1jCklHZkU3dm1MVjJIMGtuWjlQNFNOVmJmbzVhelY4ZlVaVnFaYSs1QWNyNVByNVJ6VVo1ZGRCQTYrQzRPbUY0TzVNQktneFRNVkJia04KKzhjRmR1UFlTbzM4TkJlanhpRW92akJGTVI3SGVMNVlZVGlzTytJQlpRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKTmV0d29yayBTb2x1dGlvbnMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRDVqQ0NBczZnQXdJQkFnSVFWOHN6YjhKY0Z1WkhGaGZqa0RGbzREQU5CZ2txaGtpRzl3MEJBUVVGQURCaU1Rc3dDUVlEVlFRRwpFd0pWVXpFaE1COEdBMVVFQ2hNWVRtVjBkMjl5YXlCVGIyeDFkR2x2Ym5NZ1RDNU1Ma011TVRBd0xnWURWUVFERXlkT1pYUjNiM0pyCklGTnZiSFYwYVc5dWN5QkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGt3SGhjTk1EWXhNakF4TURBd01EQXdXaGNOTWpreE1qTXgKTWpNMU9UVTVXakJpTVFzd0NRWURWUVFHRXdKVlV6RWhNQjhHQTFVRUNoTVlUbVYwZDI5eWF5QlRiMngxZEdsdmJuTWdUQzVNTGtNdQpNVEF3TGdZRFZRUURFeWRPWlhSM2IzSnJJRk52YkhWMGFXOXVjeUJEWlhKMGFXWnBZMkYwWlNCQmRYUm9iM0pwZEhrd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEa3ZINlNNRzNHMkk0ckM3eEd6dUFubHQ3ZStmb1Mwend6YzdNRUw3eHgKak9XZnRpSmdQbDlkemduL2dnd2JtbEZRR2lhSjNkVmhYUm5jRWc4dENxSkRYUmZRTkpJZzZuUFBPQ3dHSmdsNmN2ZjZVREw0d3BQVAphYUlqemtHeHpPVFZIemJSaWpyNGpHUGlGRmxwN1EzVGYydm91QVBsVDJybG1HTnBTQVcrTHY4enR1bVhXV240WnhtdWsyR1dSQlhUCmNyQS92R3A5N0VoL2pjT3JxbkVyVTJsQlV6UzFzTG5GQmdyRXNFWDFRVjF1aVVWN1BUc21qSFRDNWRMUmZiSVIxUHRZTWlLYWdNbmMKL1F6cGYxNERsODQ3QUJTSEozQTRxWTV1c3lkMm1GSGdCZU1ocXhyVmhTSThLYldhRnNXQXFQUzdhekNQTDBZQ29yRU1JdURUQWdNQgpBQUdqZ1pjd2daUXdIUVlEVlIwT0JCWUVGQ0V3eWZzQTEwNlkyb2VxS3RDbkxyRkFNYWRNTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUZJR0ExVWRId1JMTUVrd1I2QkZvRU9HUVdoMGRIQTZMeTlqY213dWJtVjBjMjlzYzNOc0xtTnYKYlM5T1pYUjNiM0pyVTI5c2RYUnBiMjV6UTJWeWRHbG1hV05oZEdWQmRYUm9iM0pwZEhrdVkzSnNNQTBHQ1NxR1NJYjNEUUVCQlFVQQpBNElCQVFDN3Jrdm50MWZyZjZvdHQzTkhoV3JCNUtVZDVPYzg2ZlJaWlhlMWVsdGFqU1UyNEhxWExqakFWMkNEbUFhRG43bDJlbTVRCjRMcUlMUHhGekJpd21aVlJEdXdkdUlqL2gxQWNnc0xqNERLQXY2QUxSOGpETWUrWlp6S0FUeGNoZVF4cFhONWVOSzRDdFNicVVOOS8KR0dVc3lmSmo0YWtIL254eEgyc3pKR29lQmZjRmFNQnFFc3N1WG1ITHJpalRmc0swWnBFbVh6d3VKRi9MV0EvcktPeXZFWmJ6M0h0dgp3S2VJOGxOM3MyQmVycTRvMmpVc2J6UkYweWJoM3V4YlR5ZHJGbnk5UkFRWWdyT0plUmNRY1QxNm9oWk85UUhOcEd4bGFLRkpkbHhECnlkaThObWRzcFpTMTFNeTV2V28xVmlIZTJNUHIrOHVrWUV5d1ZhQ2dlMWV5Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ2lUQ0NBZytnQXdJQkFnSVFIMGV2cW1JQWNGQlVUQUdlbTJPWktqQUtCZ2dxaGtqT1BRUURBekNCaFRFTE1Ba0dBMVVFQmhNQwpSMEl4R3pBWkJnTlZCQWdURWtkeVpXRjBaWElnVFdGdVkyaGxjM1JsY2pFUU1BNEdBMVVFQnhNSFUyRnNabTl5WkRFYU1CZ0dBMVVFCkNoTVJRMDlOVDBSUElFTkJJRXhwYldsMFpXUXhLekFwQmdOVkJBTVRJa05QVFU5RVR5QkZRME1nUTJWeWRHbG1hV05oZEdsdmJpQkIKZFhSb2IzSnBkSGt3SGhjTk1EZ3dNekEyTURBd01EQXdXaGNOTXpnd01URTRNak0xT1RVNVdqQ0JoVEVMTUFrR0ExVUVCaE1DUjBJeApHekFaQmdOVkJBZ1RFa2R5WldGMFpYSWdUV0Z1WTJobGMzUmxjakVRTUE0R0ExVUVCeE1IVTJGc1ptOXlaREVhTUJnR0ExVUVDaE1SClEwOU5UMFJQSUVOQklFeHBiV2wwWldReEt6QXBCZ05WQkFNVElrTlBUVTlFVHlCRlEwTWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm8KYjNKcGRIa3dkakFRQmdjcWhrak9QUUlCQmdVcmdRUUFJZ05pQUFRRFIzc3ZkY21DRllYN2RlU1JGdFNyWXBuMVBsSUxCczVCQUgrWAo0UW9rUEIwQkJPNDkwbzBKbHd6Z2RlVDYrM2VLS3ZVRFlFczJpeFlqRnEwSmNmUks5Q2hRdFA2SUhHNC9iQzh2Q1ZsYnBWc0xNNW5pCnd6MkorV29zNzdMVEJ1bWpRakJBTUIwR0ExVWREZ1FXQkJSMWNhY1pTQm04blozcVFVZmZsTVJJZDVuVGVUQU9CZ05WSFE4QkFmOEUKQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QUtCZ2dxaGtqT1BRUURBd05vQURCbEFqRUE3d05iZXF5M2VBcHl0NGpmLzdWRwpGQWtLK3FEbWZRakdHb2U5R0toenZTYktZQXlkenBtZnoxd1BNT0crRkRIcUFqQVU5Sk04U2FjemVwQkdSN05qZlJPYlRyZHZHRGVBClUvN2RJT0ExbWpiUnh3RzU1dHpkOC84ZExEb1dWOW1TT2RZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDZXJ0aWduYQo9PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHFEQ0NBcENnQXdJQkFnSUpBUDdjNHdFUHlVai9NQTBHQ1NxR1NJYjNEUUVCQlFVQU1EUXhDekFKQmdOVkJBWVRBa1pTTVJJdwpFQVlEVlFRS0RBbEVhR2x0ZVc5MGFYTXhFVEFQQmdOVkJBTU1DRU5sY25ScFoyNWhNQjRYRFRBM01EWXlPVEUxTVRNd05Wb1hEVEkzCk1EWXlPVEUxTVRNd05Wb3dOREVMTUFrR0ExVUVCaE1DUmxJeEVqQVFCZ05WQkFvTUNVUm9hVzE1YjNScGN6RVJNQThHQTFVRUF3d0kKUTJWeWRHbG5ibUV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRElhUEhKMXRhek5IVW1naDdzdEw3cQpYT0VtN1JGSFllR2lmQlo0UUNIa1lKNWF5R1BoeExHV2t2OFliV2tqNFN0aTk5M2lOaStSQjdsSXp3N3NlYllzNXpSTGNBZ2xvenlICkd4bnlnUWNQT0pBWjB4SCtoclR5MFY0ZUhwYk5nR3pPT3pHVHR2S2cwS21WRW4ybG1zeHJ5SVJXaWpPcDV5SVZVeGJ3ekJmc1YxL3AKb2dxWUNkN2pYNXh2M0VqamhRc1ZXcWE2bjZ4STR3bXk5L1F5M2w0MHZoeDRYVUpiemc0aWowMlExMzB5R0xNTExHcS9qajhVRVlrZwpEbmNVdFQyVUNJZjNKUjdWc21BQTdHOHFLQ1Z1S2o0WVl4Y2xQejVFSUJiMkpzZ2xyZ1ZLdE9kakxQT01GbE4rWFBzUkdnakJSbUtmCklyanh3bzFwM1BvNldBYmZBZ01CQUFHamdid3dnYmt3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVR3UzK1FUbVEKdENSWnZnSHlVdFZGOWxvNTNCRXdaQVlEVlIwakJGMHdXNEFVR3UzK1FUbVF0Q1JadmdIeVV0VkY5bG81M0JHaE9LUTJNRFF4Q3pBSgpCZ05WQkFZVEFrWlNNUkl3RUFZRFZRUUtEQWxFYUdsdGVXOTBhWE14RVRBUEJnTlZCQU1NQ0VObGNuUnBaMjVoZ2drQS90empBUS9KClNQOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CRUdDV0NHU0FHRytFSUJBUVFFQXdJQUJ6QU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUEKaFFNZWtuSDJRcS9obzJHZTYvUEFEL0tsMU5xVjV0YSthRFk5Zm00ZlRJcnYwUThoYlY2bFVtUE9Fdmp2S3RwdjZ6ZitFd0xIeXpzKwpJbXZhWVM1LzFISTkzVERoSGt4QUdZd1AxNXpSZ3pCN21GbmNmY2E1RENsTW9UT2k2MmM2WllUVGx1THRka1Z3ajdVcjN2a2oxa2x1ClBCUzF4cDgxSGxEUXdZOXFjRVFDWXN1dUhXaEJwNnBYNkZPcUI5SUc5dFVVQmd1UkEzVXNiSEsxWVpXYURZdTVEZWYxMzFUTjN1YlkKMWdrSWwyUGx3UzZ3dDBRbXdDYkFyMVV3bmp2Vk5pb1pCUFJjSHYvUExMZi8wUDJIUUJIVkVTTzdTTUFocWFRb0xmMFYrTEJPSy9RdwpXeUg4RVpFMHZrSHZlNTJYZGYrWGxjQ1dXQy9xdTBiWHUrVFpMZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkN5YmVydHJ1c3QgR2xvYmFsIFJvb3QKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRG9UQ0NBb21nQXdJQkFnSUxCQUFBQUFBQkQ0V3FMVWd3RFFZSktvWklodmNOQVFFRkJRQXdPekVZTUJZR0ExVUVDaE1QUTNsaQpaWEowY25WemRDd2dTVzVqTVI4d0hRWURWUVFERXhaRGVXSmxjblJ5ZFhOMElFZHNiMkpoYkNCU2IyOTBNQjRYRFRBMk1USXhOVEE0Ck1EQXdNRm9YRFRJeE1USXhOVEE0TURBd01Gb3dPekVZTUJZR0ExVUVDaE1QUTNsaVpYSjBjblZ6ZEN3Z1NXNWpNUjh3SFFZRFZRUUQKRXhaRGVXSmxjblJ5ZFhOMElFZHNiMkpoYkNCU2IyOTBNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQQorTWk4dlJSUVpoUC84Tk41N0NQeXR4ckhqb1h4RW5PbUdhb1EyNXlpWlhSYWR6NVJmVmIyM0NPMjFPMWZXTEUzVGRWSkRtNzFhb2ZXCjBvelNKOGJpL3phZm1HV2dFMDdHS21TYjFaQVN6eFFHOUR2ajFDaSs2QTc0cTA1SWxHMk9sVEVRWE8yaUxiM1ZPbTJ5SEx0Z3dFWkwKQWZWSnJuNUdpdEIwamFFTUFzN3UvT2VQdUd0bTgzOUVBTDltSlJRcjNSQXdIUWVXUDAzMmE3aVB0M3NNcFRqcjNrZmIxVjA1L0lpbgo4OWNxZFBIb1dxSTduMUM2cG94Rk5jSlFaWlhjWTRMdjNiOTNUWnhpeVdOekZ0QXBEMG1wU1BDenFyZHN4YWN3T1VCZHJzVGlYU1pUCjhNNGNJd2hocUpRWnVnUmlRT3dmT0hCM0VnWnhwekFZWFNVbnBRSURBUUFCbzRHbE1JR2lNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVAKQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlMyQ0hzTmVzeXNJRXlHVmpKZXo2dHVoUzF3VnpBL0JnTlZIUjhFT0RBMgpNRFNnTXFBd2hpNW9kSFJ3T2k4dmQzZDNNaTV3ZFdKc2FXTXRkSEoxYzNRdVkyOXRMMk55YkM5amRDOWpkSEp2YjNRdVkzSnNNQjhHCkExVWRJd1FZTUJhQUZMWUlldzE2ekt3Z1RJWldNbDdQcTI2RkxYQlhNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUJXN3dvam9GUk8KbFpmSitJbmFSY0hVb3dBbDlCOFRxN2VqaFZocHdqQ3QyQldLTGVQSnpZRmErSE1qV3FkOEJmUDlJanNPMFFiRTJ6Wk1jd1NPNWJBaQo1TVh6THFYWkkrTzRUa29ncDI0Q0pKOGlZR2Q3aXgxeUNjVXhYT2w1bjRCSFBhMmhDd2NVUFVmL0Eya2FEQXRFNTJNbHAzK3l5YmgyCmhPMGo5bjBIcTBWKzA5K3p2K21LdHMyb29tY3JVdFczWmZBNVRHT2drWG1UVWc5VTNZTzduOUdQcDFOenc4di9NT3g4QkxqWVJCK1QKWDNFSklyZHVQdW9jQTA2ZEdpQmgrNEUzN0Y3OENrV3IxK2NYVmRDZzZtQ2JwdmJqakZzcHdnWmdGSjB0bDB5cGt4V2RZY1FCWDBqVwpXTDFXTVJKT0VjZ2g0TE1Sa1dYYnRLYUlPTTVWCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCmVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZzRENDQTVpZ0F3SUJBZ0lRRmNpOVpVZGNyN2lYQUY3a0J0SzhuVEFOQmdrcWhraUc5dzBCQVFVRkFEQmVNUXN3Q1FZRFZRUUcKRXdKVVZ6RWpNQ0VHQTFVRUNnd2FRMmgxYm1kb2QyRWdWR1ZzWldOdmJTQkRieTRzSUV4MFpDNHhLakFvQmdOVkJBc01JV1ZRUzBrZwpVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncwd05ERXlNakF3TWpNeE1qZGFGdzB6TkRFeU1qQXdNak14Ck1qZGFNRjR4Q3pBSkJnTlZCQVlUQWxSWE1TTXdJUVlEVlFRS0RCcERhSFZ1WjJoM1lTQlVaV3hsWTI5dElFTnZMaXdnVEhSa0xqRXEKTUNnR0ExVUVDd3doWlZCTFNTQlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUlDSWpBTkJna3Foa2lHOXcwQgpBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUE0U1VQN28zYmlETjFaODJ0SDMwNlRtMmQweThVODJOMHl3RWhhamZxaEZBSFN5WmJDVU5zCklaNXF5TlVEOVdCcGo4endJdVFmNS9kcUlqRzNMQlh5NFA0QWFrUC9oMlhHdFJyQnAweHRJbkFoaWpIeWwzU0pDUkltSEo3SzJSS2kKbFR6YTZXZS9DS0JrNDlaQ3QwWHZsL1QyOWRlMVNoVUNXSDJZV0V0Z3ZNM1hEWm9UTTFQUllmbDYxZGQ0czVvejl3Q0d6aDFObERpdgpxT3g0VVhDS1hCQ0RVU0gzRVQwMGhsN2xTTTJYZ1lJMVRCbnNaZlpyeFFXaDdrY1Qxck1oSjVRUUN0a2tPN3ErUkJOR01EK1hQTmpYCjEycnVPempqSzlTWERya2I1d2RKZnpjcStYZDR6MVR0VzBhZG80QU9rVVBCMWx0ZkZMcWZwbzBrUjBCWnYzSTRzalpzTi8rWjBWME8KV1FxcmFmZkFzZ1JGZWxRQXJyNVQ5clhuNGZnOG96SFNxZjRoVW1URnBtZndkUWNHbEJTQlZjWW41QUdQRjhGcWNkZStTL3VVV0gxKwpFVE94UXZkaWJCald6d2xvUG45czloNlBZcTJsWTlzSnB4OGlRa0VlYjVtS1B0ZjVQMEI2ZWJDbEFaTFNuVDBJRmFVUUFTMnpNbmFvCmxRMnplcHI3QnhCNEVXL2hqOGU2RHlVYWRDcmxISmhCbWQ4aGgraVZCbW9LczJwSGRtWDJPcytQWWhjWmV3b296UnJTZ3g0aHh5eS8KdnY5aGFMZG5HN3Q0VFkzT1orWGt3WTYzSTJiaW5aQjFOSmlwTml1S21wUzVuZXpNaXJINEpZbGNXcll2akI5dGVTU25VbWpEaERYaQpabzFqRGlWTjFSbXk1bmszcHlLZFZERUNBd0VBQWFOcU1HZ3dIUVlEVlIwT0JCWUVGQjRNOTdabjh1R1NKZ2xGd0ZVNUxuYy9Ra3FpCk1Bd0dBMVVkRXdRRk1BTUJBZjh3T1FZRVp5b0hBQVF4TUM4d0xRSUJBREFKQmdVckRnTUNHZ1VBTUFjR0JXY3FBd0FBQkJSRnNNTEgKQ2xaODdsdDRESlg1R0ZQQnBoellFREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBZ0VBQ2JPRFUxa0JQcFZKdWZHQnV2bDJJQ08xSjJCMAoxR3FaTkY1c0FGUFpuL0ttc1NRSFJHb3F4cVdPZUJMb1I5bFlHeE1xWG5tYm53b3FaNllsUHdacFZuUERpbVpJK3ltQlYzUUd5cHpxCktPZzRaeVlyOGRXMVAyV1QrRFpkam8yTlFDQ0hHZXJ2SjhBOXREa1BKWHRvVUhSVm5BeFpmVm85UVpRbFVnamdSeXdWTVJuVnZ3ZFYKeHJzU3RaZjBYNE9GdW5IQjJXeUJFWFlLQ3JDL2dwZjM2ajM2K3V3dHFTaVVPMWJkMGxFdXJzQzlDQldNZDFJMGx0YWJyTk1kam1FUApOWHVicmpscEMySmdRQ0EyajYvN051NHRDRW9kdUwrYlhQanFwUnVnYzZiWStHN2dNd1JmYUtvbmgrM1p3WkNjN2IzamFqV3ZZOStyCkdObTY1dWxLNmxDS0QyR1RIdUl0R2VJd2xEV1NYUTYyQjY4WmdJOUhrRkZMTGszZGhlTFNDbElLRjVyOEdyQlFBdVVCbzJNM0lVeEUKeEp0Um1SRU9jNXdHajFRdXB5aGVSRG1IVmkwM3ZZVkVsT0VNU3l5Y3c1S0ZOR0hMRDdpYlNrTlMvalE2ZmJqcEtkeDJxY2d3K0JSeApnTVllTmtoMElrRmNoNExvR0hHTFFZbEU1MzVZVzZpNGpSUHBwMnpEUisyekdwMWlybzJDNnBTZTNWa1F3NjNkNGszak1kWEg3T2p5CnNQNlNIaFlLR3Z6WjgvZ250c20rSGJSc1pKQi85T1RFVzljM3JrSU8zYVFhYjN5SVZNVVdidUY2YUM3NE9yOE5wRHlKTzNpblRtT0QKQkNFSVo0M3lna25RVy8yeHpRK0RoTlErSUlYM1NqMHJuUDBxQ2dsTjZvSDRFWnc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCmNlcnRTSUdOIFJPT1QgQ0EKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRE9EQ0NBaUNnQXdJQkFnSUdJQVlGRm5BQ01BMEdDU3FHU0liM0RRRUJCUVVBTURzeEN6QUpCZ05WQkFZVEFsSlBNUkV3RHdZRApWUVFLRXdoalpYSjBVMGxIVGpFWk1CY0dBMVVFQ3hNUVkyVnlkRk5KUjA0Z1VrOVBWQ0JEUVRBZUZ3MHdOakEzTURReE56SXdNRFJhCkZ3MHpNVEEzTURReE56SXdNRFJhTURzeEN6QUpCZ05WQkFZVEFsSlBNUkV3RHdZRFZRUUtFd2hqWlhKMFUwbEhUakVaTUJjR0ExVUUKQ3hNUVkyVnlkRk5KUjA0Z1VrOVBWQ0JEUVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTGN6dVg3SQpKVXFPdGR1MEtCdXFWNURvMFNMVFpMclRrK2pVcklaaFFHcGdWMmhVaEUyOGFsUUNCZi9mbTVvcXJsMEhqMHJES0gvdit5djZlZkhICnJmQVFVeVNRaTJiSnFJaXJyMXFqQU9tK3VrYnVXM043TEJlQ2dWNWlMS0VDWmJPOXhTc0Fmc1Q4QXpOWERlM2krczVkUmRZNHpUVzIKc3NIUW5JRktxdVN5QVZ3ZGoxK1p4TEd0MjRnaDY1QUlnb0R6TUtORDVwQ0NybFVvU2UxYjE2a1FPQTcrajB4Ym0wYnFRZld3Q0hURAowSWd6dG56WGROL2NoTkZERG5VNW9TVkFLT3A0eXc0c0xqbWRqSXR1Rmh3dkpvSVE0dU5sbEFvRXdGNzNYVnY0RU9MUXVucEwrOTQzCkFBQWFXeWpqMHB4elBqS0htS0hKVVMvWDNxd3pzMDhDQXdFQUFhTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEIKQWY4RUJBTUNBY1l3SFFZRFZSME9CQllFRk9DTW05c2xTYlB4ZkliV3NrS0hDOUJyb05ua01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQgpBUUErMGh5SkxqWDgrSFhkNW45bGlQUnlUTWtzMXpKTzg5MFplVWU5amp0Ymt3OVFTU1FUYXhRR2N1OEowNkdoNDBDRXllY1lNblE4ClNHNFBuMHZVOXg3VGs0WmtWSmRqY2xEVlZjLzZJSk1Db3B2REk1Tk9GbFYyb0hCNWJjMGhIODh2TGJ3WjQ0Z3grRmthZ1FuSWw2WjAKeDJERVc4eFhqckoxL1JzQ0NkdFpiM0tUYWZjeFFkYUlPTCtIc3IwV2VmbXE1TDZJSmQxaEp5TWN0VEVIQkRhMEdwQzlvSFJ4VUlsdAp2QlRqRDRhdThhcyt4NkFKektOSTBlRGJaT2VTdGMrdmNrTndpL25EaER3VHFuNlNtMWRUay9wd3dwRU9NZm1iWjEzcGxqaGVYN056ClRvZ1ZaOTZlZGhCaUlMNVZhWlZEQURsTjl1NndXazVKUkZSWVgwS0QKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ3JqQ0NBaldnQXdJQkFnSVFQTEwwU0FvQTR2N3JKRHRlWUQ3RGF6QUtCZ2dxaGtqT1BRUURBekNCbURFTE1Ba0dBMVVFQmhNQwpWVk14RmpBVUJnTlZCQW9URFVkbGIxUnlkWE4wSUVsdVl5NHhPVEEzQmdOVkJBc1RNQ2hqS1NBeU1EQTNJRWRsYjFSeWRYTjBJRWx1Cll5NGdMU0JHYjNJZ1lYVjBhRzl5YVhwbFpDQjFjMlVnYjI1c2VURTJNRFFHQTFVRUF4TXRSMlZ2VkhKMWMzUWdVSEpwYldGeWVTQkQKWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQXRJRWN5TUI0WERUQTNNVEV3TlRBd01EQXdNRm9YRFRNNE1ERXhPREl6TlRrMQpPVm93Z1pneEN6QUpCZ05WQkFZVEFsVlRNUll3RkFZRFZRUUtFdzFIWlc5VWNuVnpkQ0JKYm1NdU1Ua3dOd1lEVlFRTEV6QW9ZeWtnCk1qQXdOeUJIWlc5VWNuVnpkQ0JKYm1NdUlDMGdSbTl5SUdGMWRHaHZjbWw2WldRZ2RYTmxJRzl1YkhreE5qQTBCZ05WQkFNVExVZGwKYjFSeWRYTjBJRkJ5YVcxaGNua2dRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrZ0xTQkhNakIyTUJBR0J5cUdTTTQ5QWdFRwpCU3VCQkFBaUEySUFCQld4NlAwREZVUGxyT3VITnhGaTc5S0RObEo5UlZjTFNvMTdWRHM2Ymw4VkFzQlFwczhsTDMzS1NMakhVR01jCktpRUlmSm8yMkF2KzBTYkZXREV3S0NYelhWMmp1TGFsdEpMdGJDeWY2OTFEaWFJOFMwaVJIVkRzSnQvV1lDNjlJYU5DTUVBd0R3WUQKVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZCVmZOVmRSVmZzbHNxMERhZndCby9xKwpFVlhWTUFvR0NDcUdTTTQ5QkFNREEyY0FNR1FDTUdTV1dhYm9DZDZMdXZwYWlJandINUhUUnFqeVNrd0NZL3RzWHpqYkxrR1RxUTdtCm5kd3hITEtncHhnY2VlSEhOZ0l3T2xhdm1uUnM5dnVENERQVENGK2huTUpibjBiV3RzdVJCbU9pQnVjenJENm9nUkxReTdyUWtndTIKbnBhcUJBK0sKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVmVyaVNpZ24gVW5pdmVyc2FsIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUV1VENDQTZHZ0F3SUJBZ0lRUUJyRVpDR3pFeUVERHJ2a0VockZIVEFOQmdrcWhraUc5dzBCQVFzRkFEQ0J2VEVMTUFrR0ExVUUKQmhNQ1ZWTXhGekFWQmdOVkJBb1REbFpsY21sVGFXZHVMQ0JKYm1NdU1SOHdIUVlEVlFRTEV4WldaWEpwVTJsbmJpQlVjblZ6ZENCTwpaWFIzYjNKck1Ub3dPQVlEVlFRTEV6RW9ZeWtnTWpBd09DQldaWEpwVTJsbmJpd2dTVzVqTGlBdElFWnZjaUJoZFhSb2IzSnBlbVZrCklIVnpaU0J2Ym14NU1UZ3dOZ1lEVlFRREV5OVdaWEpwVTJsbmJpQlZibWwyWlhKellXd2dVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXUKSUVGMWRHaHZjbWwwZVRBZUZ3MHdPREEwTURJd01EQXdNREJhRncwek56RXlNREV5TXpVNU5UbGFNSUc5TVFzd0NRWURWUVFHRXdKVgpVekVYTUJVR0ExVUVDaE1PVm1WeWFWTnBaMjRzSUVsdVl5NHhIekFkQmdOVkJBc1RGbFpsY21sVGFXZHVJRlJ5ZFhOMElFNWxkSGR2CmNtc3hPakE0QmdOVkJBc1RNU2hqS1NBeU1EQTRJRlpsY21sVGFXZHVMQ0JKYm1NdUlDMGdSbTl5SUdGMWRHaHZjbWw2WldRZ2RYTmwKSUc5dWJIa3hPREEyQmdOVkJBTVRMMVpsY21sVGFXZHVJRlZ1YVhabGNuTmhiQ0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMAphRzl5YVhSNU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeDJFM1hyRUJOTnRpMXhXYi8xaGFqQ01qCjFtQ09rZGVRbUlONjVsZ1pPSXpGOXVWa2hiU2ljZnZ0dmJuYXpVMEF0TWd0YzZYSGFYR1ZIems4c2tRSG5PZ08razFLeENIZktXR1AKTWlKaGdzV0hIMjZNZkY4V0lGRkUwWEJQVityakhPUE1lZTVZMkE3Q3MwV1R3Q3pubWhjcmV3QTNla0V6ZU9FejR2TVFHbitITEw3Mgo5ZmRDNHVXL2gyS0pYd0JMMzhYZDVIVkVNa0U2SG5GdWFjc0xkVVlJMGNyU0s1WFF6L3U1UUd0a2pGZE4vQk1SZVlUdFhsVDJOSjhJCkFmTVFKUVlYU3RyeEhYcG1hNWhnWnFUWjc5SXVndkh3N3ducVJNa1ZhdUlEYmpQVHJKOVZBTWYyQ0dxVXVWL2M0RFB4aEdENVd5Y1IKdFB3VzhydFdhb0FsalFJREFRQUJvNEd5TUlHdk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUcwRwpDQ3NHQVFVRkJ3RU1CR0V3WDZGZG9Gc3dXVEJYTUZVV0NXbHRZV2RsTDJkcFpqQWhNQjh3QndZRkt3NERBaG9FRkkvbDB4cUdySTJPCmE4UFBnR3JVU0Jnc2V4a3VNQ1VXSTJoMGRIQTZMeTlzYjJkdkxuWmxjbWx6YVdkdUxtTnZiUzkyYzJ4dloyOHVaMmxtTUIwR0ExVWQKRGdRV0JCUzJkL3BwU0VlZlV4TFZ3dW9ITW5ZSDBaY0hHVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBU3ZqNHNBUG1MR2Q3NUpSMwpZOHh1VFBsOURnM2N5TGsxdVhCUFkvb2srbXlEakVlZE8yUHptdmwyTXBXUnNYZThySnErc2VReEljYUJsVlphRHJIQzFMR21XYXp4Clk4dTRUQjFaa0VydmtCWW9IMXF1RVB1QlVEZ01iTXp4UGNQMVkrT3o0eUhKSkRucC9SVm1SdlFiRWRCTmM2TjlSdms5N2FoZll0VHgKUC9qZ2RGY3JHSjJCdE1RbzJwU1hwWERyckIyK0J4SHcxZHZkNVl6dzFUS3dnK1pYNG8rL3ZxR3F2ejBkdGRRNDZ0ZXdYRHBQYWorUAp3R1pzWTZycDJhUVc5SUhSbFJRT2ZjMlZOTm5TajNCemdYdWNmcjJZWWRoRmg1aVF4ZXVHTU1ZMXYvRC93MVdJZzB2dkJaSUdjZks0Cm1KTzM3TTJDWWZFNDVrK1htQ3BhalE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpOZXRMb2NrIEFyYW55IChDbGFzcyBHb2xkKSBGxZF0YW7DunPDrXR2w6FueQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFRlRDQ0F2MmdBd0lCQWdJR1NVRXM1QUFRTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUduTVFzd0NRWURWUVFHRXdKSVZURVJNQThHCkExVUVCd3dJUW5Wa1lYQmxjM1F4RlRBVEJnTlZCQW9NREU1bGRFeHZZMnNnUzJaMExqRTNNRFVHQTFVRUN3d3VWR0Z1dzdwenc2MTAKZHNPaGJubHJhV0ZrdzdOcklDaERaWEowYVdacFkyRjBhVzl1SUZObGNuWnBZMlZ6S1RFMU1ETUdBMVVFQXd3c1RtVjBURzlqYXlCQgpjbUZ1ZVNBb1EyeGhjM01nUjI5c1pDa2dSc1dSZEdGdXc3cHp3NjEwZHNPaGJua3dIaGNOTURneE1qRXhNVFV3T0RJeFdoY05Namd4Ck1qQTJNVFV3T0RJeFdqQ0JwekVMTUFrR0ExVUVCaE1DU0ZVeEVUQVBCZ05WQkFjTUNFSjFaR0Z3WlhOME1SVXdFd1lEVlFRS0RBeE8KWlhSTWIyTnJJRXRtZEM0eE56QTFCZ05WQkFzTUxsUmhic082YzhPdGRIYkRvVzU1YTJsaFpNT3pheUFvUTJWeWRHbG1hV05oZEdsdgpiaUJUWlhKMmFXTmxjeWt4TlRBekJnTlZCQU1NTEU1bGRFeHZZMnNnUVhKaGJua2dLRU5zWVhOeklFZHZiR1FwSUViRmtYUmhic082CmM4T3RkSGJEb1c1NU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeENSZWM3NUxiUlREb2ZUamw1QnUKMGpCRkhqenVaOWxrNEJxS2Y4b3d5b1BqSU1IajlEclRsRjhhZkZ0dHZ6QlBoQ2Yybng5SnZNYVpDcER5RC9WL1E0UTNZMUdMZXFWdwovSHBZelk2YjdjTkdiSVJ3WGRyekFaQWovRTR3cVg3aEoyUG43V1E4b0xqSk0yUCtGcEQvc0xqOTE2akF3SlJEQzdiVldhYWVWdEFrCkgzQjVyOXM1VkExbGRka1ZRWlFCcjE3czlvM3gvNjFrL2lDYTExenIvcVlmQ0dTamkzWlZyUjQ3S0dBdWh5WG9xcThmeG1SR0lMZHcKZnp6ZVNOdVdVN2M1ZCtRYTRzY1doSGFYV3krN0dSV0YrR21GOVptbnFmSTBwNm0ycGdQOGI0WTlWSHgyQkp0citVQmRBRFRITHBsMQpuZVdJQTZwTitBUFNRbmJBR3dJREFLaUxvMFV3UXpBU0JnTlZIUk1CQWY4RUNEQUdBUUgvQWdFRU1BNEdBMVVkRHdFQi93UUVBd0lCCkJqQWRCZ05WSFE0RUZnUVV6UHBuay9DMnVOQ2x3Qjd6VS8yTVU5K0QxNVl3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUt0Lzdod1cKcVp3OFVRQ2d3QkVJQmFlWjVtOEJpRlJoYnZHNUdLMUtyZjZCUUNPVUwvdDFmQzhvUzJJa2dZSUw5V0h4SEc2NFlUanJnZnBpb1R0YQpZdE9VWmNUaDVtMkMrQzhsY0xJaEpzRnlVUitNTE1PRWtNTmFqN3JQOUtkbHBldVkwZnNGc2taMUZTTnFiNFZqTUlEdzFaNGZLUnpDCmJMQlFXVjJRV3p1b0RURFB2MzEvenZHZGc3M0pSbTRncHZsaFVib2hMM3UrcFJWam9kU1ZoL0dldWZPSjh6MkZ1TGpidnJXNUtmbmEKTndVQVNaUURoRVRudjBNeHozV0xKZEgwcG1UMWt2YXJCZXM5NmFVTE5tTGF6QVpmTm91MlhqRzRLdnRlOW5IZlJDYWV4T1lOa2JRdQpkWldBVVdwTE1LYXdZcUdUOFp2WXpzUmpkVDlaUjdFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpIb25na29uZyBQb3N0IFJvb3QgQ0EgMQo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRE1EQ0NBaGlnQXdJQkFnSUNBK2d3RFFZSktvWklodmNOQVFFRkJRQXdSekVMTUFrR0ExVUVCaE1DU0VzeEZqQVVCZ05WQkFvVApEVWh2Ym1kcmIyNW5JRkJ2YzNReElEQWVCZ05WQkFNVEYwaHZibWRyYjI1bklGQnZjM1FnVW05dmRDQkRRU0F4TUI0WERUQXpNRFV4Ck5UQTFNVE14TkZvWERUSXpNRFV4TlRBME5USXlPVm93UnpFTE1Ba0dBMVVFQmhNQ1NFc3hGakFVQmdOVkJBb1REVWh2Ym1kcmIyNW4KSUZCdmMzUXhJREFlQmdOVkJBTVRGMGh2Ym1kcmIyNW5JRkJ2YzNRZ1VtOXZkQ0JEUVNBeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQXJQODR0dWxtQWtuam9yVGhrUGxBajNuNTRyMTUvZ0s5N2lTU0hTTDIyb1Z5YWY3WFB3blUzWkcxCkFwelFqVnJoVmNOUWhya3BKc0xqMmFEeGFRTW9JSUJGSWkxV3B6dFVsVllpV1I4bzN4OGdQVzJpTnI0am9MRnV0YkVuUHpsVENlcXIKYXVoMHNzSmxYSTYvZk1ONGhNMmVGdnoxTGs4Z0tnaWZkL1BGSHNTYVVtWWVTRjdqRUFhUElwamhaWTRiWFNObU83aWxNbEhJaHFxaApxWjUvZHBUQ3BteTNRZkRWeUFZNDV0UU00dk03VEcxUWpNU0RKOEVUaEZrOW5uVjB0dGdDWGpxUWVzQkNObkxzYWszYzc4UUEzeE1ZClYxOG1lTWpXQ25sM3YvZXZ0M2E1cFF1RUYxMFE2bS9ocTVVUlgyMDhvMXhOZzF2eXN4bUtnSXNMaHdJREFRQUJveVl3SkRBU0JnTlYKSFJNQkFmOEVDREFHQVFIL0FnRURNQTRHQTFVZER3RUIvd1FFQXdJQnhqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFEa2JWUEs3aQpoOWxlZ1lzQ21FRUlqRXk4MnR2dUp4dUM1MnBGN0JhTFQ0V2c4N0p3dlZxV3VzcHViZTVHaTI3bktpNldzeGt6NjdTZnFMSTM3cGlvCmw3WXV0bWNuMUtaSi9SeVRaWGFlUWkvY0lteWFUL0phRlRteGNkY3JVZWh0SEpqQTJTcjBvWUo3MWNsQm9pTUJkRGhWaXcrNUxtZWkKSUFRMzJwd0wweGNoNEkrWGVUUnZoRWdDSURNYjVqUkVuNUZ3OUlCZWhFUENLZEpzRWhUa1lZMnNFSkNlaEZDNzhKWnZSWitLODhwcwpUL29ST2hVVlJzUE5INE5iTFVFUzdWQm5RUk05SWF1VWlxcE9mTUd4KzZmV3RTY3ZsNnR1NEIzaTBSd3NIMFRpL0w2Um9aejcxaWxUCmM0YWZVOWhERGwzV1k0SnhIWUIweXZiaUFtdlpXZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNlY3VyZVNpZ24gUm9vdENBMTEKPT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGJUQ0NBbFdnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQllNUXN3Q1FZRFZRUUdFd0pLVURFck1Da0dBMVVFQ2hNaQpTbUZ3WVc0Z1EyVnlkR2xtYVdOaGRHbHZiaUJUWlhKMmFXTmxjeXdnU1c1akxqRWNNQm9HQTFVRUF4TVRVMlZqZFhKbFUybG5iaUJTCmIyOTBRMEV4TVRBZUZ3MHdPVEEwTURnd05EVTJORGRhRncweU9UQTBNRGd3TkRVMk5EZGFNRmd4Q3pBSkJnTlZCQVlUQWtwUU1Tc3cKS1FZRFZRUUtFeUpLWVhCaGJpQkRaWEowYVdacFkyRjBhVzl1SUZObGNuWnBZMlZ6TENCSmJtTXVNUnd3R2dZRFZRUURFeE5UWldOMQpjbVZUYVdkdUlGSnZiM1JEUVRFeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBL1hlcXBSeVFCVHZMClRKc3ppMW9VUmFUbmtCYlIzMWZTSVJDa0YvM2ZyTllmcCtUYmZQZnMzN2dEMnBSWS9WMXlmSXcvWHdGbmRCV1c0d0k4aDl1dXl3R08Kd3ZObXhvVkY5QUxHT3JWaXNxLzZuTCtrNXRTQU1KanpEYmFUajZuVTJEYnlzUHlLeWl5aEZUT1ZNZHJBRy9MdVlwbUdZeisvM1pNcQpnNmgydVJNZnQ4NU9Rb1dQSXVjdUd2S1ZDYklGdFVST2Q2RWd2YW55VGdwOVVLMzFCUTFGVDBaeC9TZytVL3NFMkMzWFpSMUtHL3JQCk83QXhtalZ1eUlzRzB3Q1I4cFFJWlV5eE5BWUFlb25pOE1jRFdjL1YxdWluTXJQbW1FQ0d4YzBuRW92TWU4NjNFVHhpWUFjalBpdEEKYnBTQUNXMjJzMjkzYnpVSVVQc0NoOFUraVFJREFRQUJvMEl3UURBZEJnTlZIUTRFRmdRVVcvaE5UN0tsaHRRNjB2RmptcUMrQ2ZaWAp0OTR3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBS0NoCk9CWm1McWRXSHlHY0J2b2Q3YmtpeFRnbTJFNVA3S04vZWQ1R0lhR0hkNDhIQ0pxeXBNV3ZEektZQzN4bUtiYWJmU1ZTU1VPclRDNHIKYm5wd3J4WU80d0pzKzBMbUdKMUYyRlhJNkR2ZDUrSDBMZ3NjTkZ4c1dFcjdqSWhRWDVVY3YrMnJJclZsczRXNm5nKzRyZVY2RzRwUQpPaDI5RGJ4N1ZGQUx1VUt2VmFBWWdhMWxtZSsrNUp5L3hJV3JRYkpVYjl3bHplMTQ0bzRNalFsSjNXTjdXbW1XQWlHb3ZWSlo2WDAxCnk4aFN5bitCL3RscjAvY1I3U1hmK09mNXBQcHlsNFJURGFYUU1oaFJkbGtVYkEvcjdGK0FqSFZEZzhPRm1QOU1uaTBONUhlRGswNjEKbGdlTEtCT2JqQm1OUVNkSlFPN2U1aU5FT2R5aEl0YTZBL0k9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVDakNDQXZLZ0F3SUJBZ0lKQU1KK1F3Uk9SejhaTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdDTVFzd0NRWURWUVFHRXdKSVZURVIKTUE4R0ExVUVCd3dJUW5Wa1lYQmxjM1F4RmpBVUJnTlZCQW9NRFUxcFkzSnZjMlZqSUV4MFpDNHhKekFsQmdOVkJBTU1IazFwWTNKdgpjMlZqSUdVdFUzcHBaMjV2SUZKdmIzUWdRMEVnTWpBd09URWZNQjBHQ1NxR1NJYjNEUUVKQVJZUWFXNW1iMEJsTFhONmFXZHVieTVvCmRUQWVGdzB3T1RBMk1UWXhNVE13TVRoYUZ3MHlPVEV5TXpBeE1UTXdNVGhhTUlHQ01Rc3dDUVlEVlFRR0V3SklWVEVSTUE4R0ExVUUKQnd3SVFuVmtZWEJsYzNReEZqQVVCZ05WQkFvTURVMXBZM0p2YzJWaklFeDBaQzR4SnpBbEJnTlZCQU1NSGsxcFkzSnZjMlZqSUdVdApVM3BwWjI1dklGSnZiM1FnUTBFZ01qQXdPVEVmTUIwR0NTcUdTSWIzRFFFSkFSWVFhVzVtYjBCbExYTjZhV2R1Ynk1b2RUQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFPbjRqL05qcmRxRzJLZmdRdnZQa2Q2bUp2aVpwV053clp1dXlqTkEKZlcyV2JxRU9STzdoRTUyVVFsS2F2WFdGZEN5b0RoMlR0aGkzakN5b3ovdGNjYm5hN1A3b2ZvL2tMeDJ5cUhXSDJMZWg1VHZQbVVwRwowSU1aZmNDaEVoeVZiVXIwMk1lbFRUTXVoVGxBZFg0VWZJQVNtRkRIUVdlNG9JQmhWS1pzVGgvZ25RNEg2Y202TStmK3dGVW9MQUtBCnB4bjFudHhWVXdPWGV3ZEkvNW43TjRva3hGbk1VQkJqanFxcEdyQ0VHb2I1WDd1eFVHNmswUXJNMVhGK0g2Y2JmUFZUYmlKZnl5dm0KMUh4ZHJ0YkN4a3psQlFIWjdWZjh3U041L1BySUpJT1Y4N1ZxVVFIUWQ5YnBFcUg1R29QN2dodTVzSmYwZGdZelEwbWcvd3UxK3JVQwpBd0VBQWFPQmdEQitNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCVExEOGJmClFrUE1QY3UxU0NPaEducW1LcnMwYURBZkJnTlZIU01FR0RBV2dCVExEOGJmUWtQTVBjdTFTQ09oR25xbUtyczBhREFiQmdOVkhSRUUKRkRBU2dSQnBibVp2UUdVdGMzcHBaMjV2TG1oMU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRREowUTVlTHRYTXMzdyt5L3c5L3cwbwpsWk1FeUwvYXpYbTRRNUR3cEw3djh1OGhtTHpVMUYwRzl1NUM3REJzb0txcHl2R3Zpdm8vQzNOcVB1b3VRSDRmcmxSaGVlc3VDRGZYCkkvT01uNzRkc2VHa2RkdWc0bFFVc2JvY0thUVk5aEs2b2hRVTR6RTF5RUQvdCtBRmRsZkJIRm55K0wvazdTVmlYSVR3Zm40ZnM3NzUKdHlFUnpBTUJWbkNuRUpJZUd6U0JIcTJjR3NNRVBPMENZZFllQnZOZk9vZnlLL0ZGaCtVOXJOSEhWNFM5YTY3YzJQbTJHMkp3Q3owMgp5VUx5TXRkNlllYlMyejNQeUtuSm05emJXRVRYYnppdmYzalRvNjBhZGJvY3dUWjhqeDV0SE1OMVJxNDFCYWIyWEQwaDdsYnd5WUlpCkxYcFVxM0REZlNKbGduQ1cKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR2xvYmFsU2lnbiBSb290IENBIC0gUjMKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURYekNDQWtlZ0F3SUJBZ0lMQkFBQUFBQUJJVmhUQ0tJd0RRWUpLb1pJaHZjTkFRRUxCUUF3VERFZ01CNEdBMVVFQ3hNWFIyeHYKWW1Gc1UybG5iaUJTYjI5MElFTkJJQzBnVWpNeEV6QVJCZ05WQkFvVENrZHNiMkpoYkZOcFoyNHhFekFSQmdOVkJBTVRDa2RzYjJKaApiRk5wWjI0d0hoY05NRGt3TXpFNE1UQXdNREF3V2hjTk1qa3dNekU0TVRBd01EQXdXakJNTVNBd0hnWURWUVFMRXhkSGJHOWlZV3hUCmFXZHVJRkp2YjNRZ1EwRWdMU0JTTXpFVE1CRUdBMVVFQ2hNS1IyeHZZbUZzVTJsbmJqRVRNQkVHQTFVRUF4TUtSMnh2WW1Gc1UybG4KYmpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTXdsZHBCNUJuZ2lGdlhBZzdhRXlpaWUvUVYyRWNXdAppSEw4UmdKRHg3S0tuUVJmSk1zdVMrRmdna2JoVXFzTWdVZHdiTjFrMGV2MUxLTVBnajBNSzY2WDE3WVVoaEI1dXpzVGdIZU1DT0ZKCjBtcGlMeDllK3BabzM0a25sVGlmQnRjK3ljc21XUTF6M3JESTZTWU9neFhHNzF1TDBnUmd5a21tS1BacE8vYkx5Q2lSNVoyS1lWYzMKckhRVTNIVGdPdTV5THk2Yys5Qzd2L1U5QU9FR00raUNLNjVUcGpvV2M0emRRUTRnT3NDMHA2SHBzaytRTGpKZzZWZkx1UVNTYUdqbApPQ1pnZGJLZmQvK1JGTyt1SUVuOHJVQVZTTkVDTVdFWlhyaVg3NjEzdDJTYWVyOWZ3UlB2bTJMN0RXemdWR2tXcVFQYWJ1bURrM0YyCnhtbUZnaGNDQXdFQUFhTkNNRUF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUUKRkkvd1MzK29Ma1VrcmsxUSttT2FpOTdpM1J1OE1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQkxRTnZBVUtyK3lBenY5NVpVUlVtNwpsZ0FKUWF5ekU0YUdLQWN6eW12bWRMbTZBQzJ1cEFyVDlmSHhENHEvYzJkS2c4ZEVlM2pncjI1c2J3TXBqak01UmNPTzVMbFhiS3I4CkVwYnNVOFl0NUNSc3VaUmorOXhUYUdkV1BvTzR6elVodzhsby9zN2F3bE9xekpDSzZmQmRSb3lWM1hwWUtCb3ZIZDdOQURkQmorMUUKYmRkVEtKZCs4MmNFSGhYWGlwYTAwOTVNSjZSTUczTnpkdlFYbWNJZmVnN2pMUWl0Q2h3cy96eXJWUTRQa1g0MjY4TlhTYjdoTGkxOApZSXZEUVZFVEk1M085ekpybEFHb21lY3NNeDg2T3lYU2hrRE9PeXlHZU1saEx4UzY3dHRWYjkrRTdnVUpUYjBvMkhMTzAySlFaUjdyCmtwZURNZG16dGNwSFdEOWYKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24gRmlybWFwcm9mZXNpb25hbCBDSUYgQTYyNjM0MDY4Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJR0ZEQ0NBL3lnQXdJQkFnSUlVK3c3N3Z1eVNGOHdEUVlKS29aSWh2Y05BUUVGQlFBd1VURUxNQWtHQTFVRUJoTUNSVk14UWpCQQpCZ05WQkFNTU9VRjFkRzl5YVdSaFpDQmtaU0JEWlhKMGFXWnBZMkZqYVc5dUlFWnBjbTFoY0hKdlptVnphVzl1WVd3Z1EwbEdJRUUyCk1qWXpOREEyT0RBZUZ3MHdPVEExTWpBd09ETTRNVFZhRncwek1ERXlNekV3T0RNNE1UVmFNRkV4Q3pBSkJnTlZCQVlUQWtWVE1VSXcKUUFZRFZRUURERGxCZFhSdmNtbGtZV1FnWkdVZ1EyVnlkR2xtYVdOaFkybHZiaUJHYVhKdFlYQnliMlpsYzJsdmJtRnNJRU5KUmlCQgpOakkyTXpRd05qZ3dnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFES2xtdU82dmo3OGFJMTRIOU0ydUREClV0ZDl0aERJQWw2elF5ckVUMnF5eWh4ZEtKcDRFUnBwV1ZldnRTQkM1SXNQNXQ5YnBnT1NML1VSNUdMWE1uRTQyUVFNY2FzOVVYNFAKQjk5akJWenB2NVJ2d1NtQ3dMVGFVYkRCUEx1dE4wcGN5dkZMTmc0a3E3L0RoSGY5cUZEMHNlZkdMOUl0V1kxNkNrNldhVklDcWphWQo3UHo2RklNTU54L0pramQvMTRFdDVjUzU0RDQwL21mMFBtYlIwL1JBejE1aU5BOXdCajRnR0ZyTzkzSWJKV3lUZEJTVG8zT3hEcXFICkVDTlpYeUFGR1VmdGFJNlNFc3BkL05ZcnNwSThJTS9oWDY4Z3ZxQjJmM2JsN0JxR1lUTSs1M3UwUDZBUGpxSzVhbSs1aHladlFXeUkKcGxEOWFtTUw5Wk1XR3htUHN1MmJtOG1ROVFFTTN4azlEejQ0SThrdmp3elJBdjRiVmRaTzBJMDhyMCtrOC82dkt0TUZuWGtJb2N0WApNYlNjeUpDeVovUVlGcE02L0VmWTBYaVdNUis2S3d4ZlhabXRZNGxhSkNCMjJOLzlxMDZtSXFxZFh1WW5pbjFvS2FQbmlyamFFYnNYCkxabWRFeVJHOThYaTJKK09mOGVQZEcxYXN1aHk5YXp1SkJDdEx4VGEveTJhUm5GSHZrTGZ1d0hiOUgvVEtJOHhXVnZUeVFLbXRGTEsKYnBmN1E4VUlKbStLOUx2OW55aXFEZFZGOHhNNkhkakFlSTlCWnp3ZWxHU3Vld3ZGNk5rQmlEa2FsNFprUWRVN2h3eHUrZy9HdlVnVQp2emxOMUo1QnRvK1dIV09XazltVkJuZ3hhSjQzQmp1QWlVVmhPU1BIRzBTakZlVWMrSkl3dXdJREFRQUJvNEh2TUlIc01CSUdBMVVkCkV3RUIvd1FJTUFZQkFmOENBUUV3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlJsemV1ck5SNEFQbjdWZE1BY3RITkgKRGhwa0x6Q0JwZ1lEVlIwZ0JJR2VNSUdiTUlHWUJnUlZIU0FBTUlHUE1DOEdDQ3NHQVFVRkJ3SUJGaU5vZEhSd09pOHZkM2QzTG1acApjbTFoY0hKdlptVnphVzl1WVd3dVkyOXRMMk53Y3pCY0JnZ3JCZ0VGQlFjQ0FqQlFIazRBVUFCaEFITUFaUUJ2QUNBQVpBQmxBQ0FBCmJBQmhBQ0FBUWdCdkFHNEFZUUJ1QUc4QWRnQmhBQ0FBTkFBM0FDQUFRZ0JoQUhJQVl3QmxBR3dBYndCdUFHRUFJQUF3QURnQU1BQXgKQURjd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFCZDlvUG0wM2NYRjY2MUxKTFdoQXF2ZHBZaEtzZzlWU3l0WGpEdmxNZDMreERMeAo1MXRrbGpZeUdPeWxNbmZYNDBTMndCRXFnTGs5YW01OG05T3QvTVBXbytaa0tYelI0VGdlZ2l2L0oyV3YreFlWeEM1eGhPVzEvL3FrClI3MWtNcnYySllTaUowTDFJTERDRXhBUnpSQVZ1a0tRS3RKRTRaWW02ekZJRXYwcTJza0d6M1FlcVV2Vmh5ajVlVFNTUGk1RTZQYVAKVDQ4MVB5V3pPZHhqS3BCcklGL0VVaEpPbHl3cXJKMlgza2p5bzJiYnd0S0RsYVptcDU0bEQra0xNNUZsQ2xyRDJWUVMzYS9EVGc0ZgpKbDROM0xPTjdOV0JjTjdTVHlRRjgyeE85VXhKWm8zUi85SUxKVUZJL2xHRXhrS3ZnQVRQMEg1a1NlVHkzNkxzc1V6QUtoM250TEZsCm9zUzg4WmowcW5BSFk3UzQyanRNK2tBaU1Gc1JwdkFGRHNZQ0EwaXJocHVGM2R2ZDZxSjJnSE45OVp3RXhFV041N2tjaTU3cTEzWFIKY3JIZWRVVG5RbjNpVjJ0OTNKbThQWU1vNm9DVGpjVk1aY0Z3Z2JnNC9FTXhzdllETkVleXJQc2lCc3NlM1JkSEhGOW11ZE1hb3RvUgpzYVM4SThua3ZvZi91WlMyK0YwZ1N0UmY1NzFvZTJYeUZSN1NPcWt0NmRockpLeVhXRVJIclZrWThTRmxjTjdPTkdDb1FQSHpQS1RECktDT00vaWN6UTBDZ0Z6enI2anV3Y3FhanVVcExYaFpJOUxLOHlJeVN4WjJmckhJMnZEU0FOR3VwaTVMQXVCZnQ3SFpUOVNRQmpMTWkKNkV0OFZjYWQrcU1VdTJXRmJtNVBFbjRLUEoyVgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpJemVucGUuY29tCj09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUY4VENDQTltZ0F3SUJBZ0lRQUxDM1doWklYNy9oeS9XTDF4bm1mVEFOQmdrcWhraUc5dzBCQVFzRkFEQTRNUXN3Q1FZRFZRUUcKRXdKRlV6RVVNQklHQTFVRUNnd0xTVnBGVGxCRklGTXVRUzR4RXpBUkJnTlZCQU1NQ2tsNlpXNXdaUzVqYjIwd0hoY05NRGN4TWpFegpNVE13T0RJNFdoY05NemN4TWpFek1EZ3lOekkxV2pBNE1Rc3dDUVlEVlFRR0V3SkZVekVVTUJJR0ExVUVDZ3dMU1ZwRlRsQkZJRk11ClFTNHhFekFSQmdOVkJBTU1Da2w2Wlc1d1pTNWpiMjB3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRREoKMDNyS0R4NnNwNGJvRm1WcXNjSWJSVEp4bGRuK0VGdk1yK2VsZVFHUGljUEs4bFZ4OTNlK2Q1VHpjcVFzUk5pZWtwc1VPcUhuSkpBSwpDbGFPeGRnbWxPSFpTT0V0UHRvS2N0MmptUlhhZ2FLSDlIdHVKbmVKV0szVzZ3eXlRWHB6Ym0zYmVuaEI2UWlJRW42SExtWVJZMnhVCit6eWRjc0M4THYvQ3Q5ME5kdU02MS9lMGFMNmk5ZU9CYnNGR2IxMk40RTNHVkZXSkdqTXhDckZYdWFPS21NUHNPelRGbFVGcGZuWEMKUENERllicFJSNkFna0pPaGtFdnpUbnlGUlZTYTBRVW1RYkMxVFIwenZzUUR5Q1Y4d1hEYk8vUUpMVlFuU0t3djRjU3NQc2pMa2t4VApPVGNqN05NQitlQUpSRTFOWk1EaERWcUhJcnl0RzZQK0pyVVY4NmY4aEJucDdLR0l0RVJwaElQemlkRjBCcW5NQzliQzNpZUZVQ2JLCkY3akplb2RXTEJvQkhteStFNjBRckxVazlUaVJvZFpMMnZHNzB0NUh0Zkc4Z2ZaWmE4OFpVK21ORmN0S3k2bHZST1ViUWMvaGhxZksKMEdxZnZFeU5Cak5hb29YbGtEV2dZbHdXVHZEam92b0RHclFzY2JOWUxONTdDOXNhRCt2ZUlSOEdkd1lEc01udm1mekF1VThMaGlqKwowcm5xNDlxbHcwZHBFdURiOFBZWmkrMTdjTmNDMXUySEdDZ3NCQ1JNZCtSSWlockdPNXJVRDhyNmRkSUJRRnFOZWIrTHowdlBxaGJCCmxlU3RUSW8rRjVIVXNXTGxndVdBQktRRGZvMi8ybitpRDVkUEROTU4rOWZSNVhKK0hNaDMvMXVhRDdldUJVYmw4YWdXN0Vla0Z3SUQKQVFBQm80SDJNSUh6TUlHd0JnTlZIUkVFZ2Fnd2dhV0JEMmx1Wm05QWFYcGxibkJsTG1OdmJhU0JrVENCampGSE1FVUdBMVVFQ2d3KwpTVnBGVGxCRklGTXVRUzRnTFNCRFNVWWdRVEF4TXpNM01qWXdMVkpOWlhKakxsWnBkRzl5YVdFdFIyRnpkR1ZwZWlCVU1UQTFOU0JHCk5qSWdVemd4UXpCQkJnTlZCQWtNT2tGMlpHRWdaR1ZzSUUxbFpHbDBaWEp5WVc1bGJ5QkZkRzl5WW1sa1pXRWdNVFFnTFNBd01UQXgKTUNCV2FYUnZjbWxoTFVkaGMzUmxhWG93RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwTwpCQllFRkIwY1pRNm84aVY3dEpIUDVMR3g1cjFWZEd3Rk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQjRwZ3dXU3A5TWlEckF5dzZsCkZuMmZ1VWhmR0k4TllqYjJ6Umxyckt2VjlwRjlybkh6UDdNT2VJV2JsYVFuSVVkQ1NueElPdlZGZkxNTWpsRjRySlVUM3NiOWZiZ2EKa0V5cmtnUEg3VUlCemcvWXNmcWlrdUZnYmE1NmF3bXF4aW51YUVsbk1JQWtlakVXT1Z0KzhSd3UzV3dKcmZJeHdZSk91YnY1dnI4cQpoVC9BUUtNNldmeFpTendvSk51MEZYV3VEWWk2TG5QQXZWaUg1VUx5NjE3dUhqQWltY3MzMGNRaGJJSHN2bTBtNWh6a1FpQ2VSN0NzCmcxbHdMRFhXcnpZMHRNMDcrREtvNytONGlmdU5SU3phbkxoK1FCeGg1ejZpa2l4TDhzMzZtTFlwLy9QeWU2a2ZMcUNUVnl2ZWhRUDUKYVRmTG5uaHFCYlRGTVhpSjdIcW5oZUc1ZXp6ZXZoNTVoTTZmY0E1WndqVXVrQ294MmVSRmVrR2tMaE9iTkE1bWUwbXJaSmZRUnNONQpuWEpRWTZhWVd3YTlTRzNZT1lOdzZEWHdCZEdxdk9QYnlBTHFmUDJDMnNKYlVqV3VtRHF0dWpXVEk2Y2ZTTjAxUnBpeUVHamtwVEhDCkNsZ3VHWUVReVZCMS9PcGFGczRSMSs3dlVJZ3RZZjgvUW5NRmxFUFZqanhPQVRvWnBSOUdUbmZRWGVXQklpR0gvcFI5aE5pVHJkWm8KUTBpeTIrdHpKT2VSZjFTa3RvQStuYU04VEhMQ1Y4U2cxTXc0Sjg3VkJwNmlTTm5wbjg2Q2NEYVRtanZmbGlIaldiY00ycEUzOFAxWgpXck9aeUdsc1F5WUJOV05nVllrRE9uWFl1a3JaVlAvdTNvRFlMZEU0MVY0dEM1aDlQbXpiL0NhSXh3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUhUekNDQlRlZ0F3SUJBZ0lKQUtQYVFuNmtzYTdhTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUd1TVFzd0NRWURWUVFHRXdKRlZURkQKTUVFR0ExVUVCeE02VFdGa2NtbGtJQ2h6WldVZ1kzVnljbVZ1ZENCaFpHUnlaWE56SUdGMElIZDNkeTVqWVcxbGNtWnBjbTFoTG1OdgpiUzloWkdSeVpYTnpLVEVTTUJBR0ExVUVCUk1KUVRneU56UXpNamczTVJzd0dRWURWUVFLRXhKQlF5QkRZVzFsY21acGNtMWhJRk11ClFTNHhLVEFuQmdOVkJBTVRJRU5vWVcxaVpYSnpJRzltSUVOdmJXMWxjbU5sSUZKdmIzUWdMU0F5TURBNE1CNFhEVEE0TURnd01URXkKTWprMU1Gb1hEVE00TURjek1URXlNamsxTUZvd2dhNHhDekFKQmdOVkJBWVRBa1ZWTVVNd1FRWURWUVFIRXpwTllXUnlhV1FnS0hObApaU0JqZFhKeVpXNTBJR0ZrWkhKbGMzTWdZWFFnZDNkM0xtTmhiV1Z5Wm1seWJXRXVZMjl0TDJGa1pISmxjM01wTVJJd0VBWURWUVFGCkV3bEJPREkzTkRNeU9EY3hHekFaQmdOVkJBb1RFa0ZESUVOaGJXVnlabWx5YldFZ1V5NUJMakVwTUNjR0ExVUVBeE1nUTJoaGJXSmwKY25NZ2IyWWdRMjl0YldWeVkyVWdVbTl2ZENBdElESXdNRGd3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQwpBUUN2QU10d055dUFXa282YkhpVWZhTi9HaC8yTmRXOTI4c05SSEkrSnJLUVVycGpPeWhZYjZXemJaU204OTFrREZYMjl1ZnlJaUtBClh1Rml4cllwNFlGczhyL2xmVEpxVktBeUdWbitINHZYUFdDR2hTUnY0eEd6ZHo0Z2xqVWhhN01JMlhBdVpQZUVrbFBXRHJDUWlvcmoKaDQwRzA3MlFEdUtab1J1R0R0cWFDcnNMWVZBR1V2R2VmM2JzeXcvUUhnM1BtVEE5SE1SRkVGaXMxdFBvMStYcXhRRUhkOVpSNWdOLwppa2lsVFdoMXVlbThuazRaY2ZVeVM1eHRZQmtMKzh5ZGRkeS9KczJQazNnNWVYTmVKUTdLWE90M0VnZkxaRUZIY3BPclVNUHJDWFprCk5OSTV0M1lSQ1ExMlJjU3ByajFxcjdWOVpTK1VXQkRzWEh5dmZ1SzJHTm5RbTA1YVNkK3BaZ3ZNUE1aNGZLZWNIZVBPamxPK0JkNWcKRDJ2bEd0cy80K0VoeVNuQjhlc0huRkliQVVSUlBIc2wxOFRsVWxSZEpRZktGaUM0cmVSQjdub0kvcGx2ZzZhUkFyQnNObFZxNTMzMQpsdWJLZ2RhWDhaU0Q2ZTJ3c1dzU2FSNnMrMTJweFpqcHRGdFllcjQ5b2tRNlkxblVDeVhlRzArOTVRR2V6ZElwMVo4WEdRcHZ2d3lRCjB3bGYyZU9LTmN4NVdrMFpONUszeE1HdHIvUjVKSnF5QVF1eHIxeVc4NEF5KzF3OW1QR2dQMHJldnErVUx0bFZtaGR1WUoxamJMaGoKeWE2QlhCZzE0SkM3dmp4UE55SzVmdXZQbm5jaHBqMDRnZnRJMmpFOUsrT0o5ZEMxdlg3Z1VNUVNpYk1qbWhBeGhkdXViKzg0TXhoMgpFUUlEQVFBQm80SUJiRENDQVdnd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQkREQWRCZ05WSFE0RUZnUVUrU1NzRDdLMStIbkErbUNJCkc4VFpUUUtlRnhrd2dlTUdBMVVkSXdTQjJ6Q0IySUFVK1NTc0Q3SzErSG5BK21DSUc4VFpUUUtlRnhtaGdiU2tnYkV3Z2E0eEN6QUoKQmdOVkJBWVRBa1ZWTVVNd1FRWURWUVFIRXpwTllXUnlhV1FnS0hObFpTQmpkWEp5Wlc1MElHRmtaSEpsYzNNZ1lYUWdkM2QzTG1OaApiV1Z5Wm1seWJXRXVZMjl0TDJGa1pISmxjM01wTVJJd0VBWURWUVFGRXdsQk9ESTNORE15T0RjeEd6QVpCZ05WQkFvVEVrRkRJRU5oCmJXVnlabWx5YldFZ1V5NUJMakVwTUNjR0ExVUVBeE1nUTJoaGJXSmxjbk1nYjJZZ1EyOXRiV1Z5WTJVZ1VtOXZkQ0F0SURJd01EaUMKQ1FDajJrSitwTEd1MmpBT0JnTlZIUThCQWY4RUJBTUNBUVl3UFFZRFZSMGdCRFl3TkRBeUJnUlZIU0FBTUNvd0tBWUlLd1lCQlFVSApBZ0VXSEdoMGRIQTZMeTl3YjJ4cFkza3VZMkZ0WlhKbWFYSnRZUzVqYjIwd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFKQVNyeUkxCndxTTU4QzdlNmJYcGVIeEl2ajk5UlpKZTZkcXhHZndXUEorMFcyYWVhdWZEdVYySTZBK3R6eU1QM2lVNlhzeFBwY0cxTGF3azBsZ0gKM3FMUGFZUmdNK2dRRFJPcEk5Q0Y1WTU3cHA0OWNoTnlNL1dxZmNaakh3ajAvZ0YvSk04ckxGUUozdUlyYlpMR09VOFc2angrZWtiVQpSV3BHcU90MWdsYW5xNkI4YUJNejlwMHc4RzhuT1NRaktwRDlrQ2sxOHBQZk5LWEc5L2p2akE5aVNueXUwL1ZVK0kyMm1sYUhGb0k2Ck02dGFJZ2ozZ3JycUx1QkhtclMxUmFNRk85bmNMa1ZBTytyY2YrZzc2OUhzSnRnMXBEREZPcXhYbnJOMnBTQjcrUjVLQldJQnBpaDEKWUplU0RXNCtUVGRERFpJVm5CZ2l6Vkdab0NrYVBGK0tNak5iTU1lSkwwZVlENk1EeHZieHJOOHk4Tm1CR3VTY3ZmYUFGUERSTExtRgo5ZGlqc2NpbEllVWNFNWZ1RHIzZkthbnZORk5iMCtScUU0UUd0aklDeEZLdUl0TGNzaUZDR3RwQThDbko3QW9NWE9MUXVzeEkwemNLCnpCSUtpbm13UFFOL2FVdjBOQ0I5c3pUcWprdGs5VDc5c3lObkZRMEV1UEF0d1FsUlBMSnNGZkNsSTllRGRPVGxMc24rbUNkQ3hxdkcKbnJEUVd6aWxtMURlZmhpWXRVVTc5bm0wNlBjYWV3YUQrOUNMMnJ2SHZSaXJDRzg4Z0d0QVB4a1p1bVdLNXI3VlhOTTIxKzlBVWlSZwpPR2NFTWV5UDg0TEczcmxWOHpzeGtWcmN0UWdWclhZbENnMTdMb2ZpREtZR3ZDWVFiVGVkN04xNGpIeUF4ZkRaZDBqUQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDgKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlIU1RDQ0JUR2dBd0lCQWdJSkFNbk4wK25WZlNQT01BMEdDU3FHU0liM0RRRUJCUVVBTUlHc01Rc3dDUVlEVlFRR0V3SkZWVEZECk1FRUdBMVVFQnhNNlRXRmtjbWxrSUNoelpXVWdZM1Z5Y21WdWRDQmhaR1J5WlhOeklHRjBJSGQzZHk1allXMWxjbVpwY20xaExtTnYKYlM5aFpHUnlaWE56S1RFU01CQUdBMVVFQlJNSlFUZ3lOelF6TWpnM01Sc3dHUVlEVlFRS0V4SkJReUJEWVcxbGNtWnBjbTFoSUZNdQpRUzR4SnpBbEJnTlZCQU1USGtkc2IySmhiQ0JEYUdGdFltVnljMmxuYmlCU2IyOTBJQzBnTWpBd09EQWVGdzB3T0RBNE1ERXhNak14Ck5EQmFGdzB6T0RBM016RXhNak14TkRCYU1JR3NNUXN3Q1FZRFZRUUdFd0pGVlRGRE1FRUdBMVVFQnhNNlRXRmtjbWxrSUNoelpXVWcKWTNWeWNtVnVkQ0JoWkdSeVpYTnpJR0YwSUhkM2R5NWpZVzFsY21acGNtMWhMbU52YlM5aFpHUnlaWE56S1RFU01CQUdBMVVFQlJNSgpRVGd5TnpRek1qZzNNUnN3R1FZRFZRUUtFeEpCUXlCRFlXMWxjbVpwY20xaElGTXVRUzR4SnpBbEJnTlZCQU1USGtkc2IySmhiQ0JECmFHRnRZbVZ5YzJsbmJpQlNiMjkwSUMwZ01qQXdPRENDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFNRGYKVnRQa09wdDJSYlFUMi8vQnRobUxOMEVZbFZKSDZ4ZWRLWWlPTld3R01pNUhZdk5KQkw5OVJEYXhjY3k5V2dsejFkbUZSUCtSVnlYZgpYamFPY05GY2NVTWQyZHJ2WE5MN0c3MDZ0Y3V0bzh4RXB3MnVJUlUvdVhwYmtuWFlwQkk0aVJtS3Q0RFM0akp2VnB5UjFvZ1FDN04wClpKSjBZUFAyenhoUFlMSWowTWM3em1GTG1ZL0NETkJBc3BqY0RhaE9vN2tLcm1DZ3JVVlNZN3BtdldqZytiNGFxSUc3SGtGNGRkUEIKL2dCVnNJZFU2Q2VRTlIxTU02MlgvSmN1bUlTL0xNbWp2OUdZRVJUdFkvakttSWhZRjVudFJRT1hmanlHSG9pTXZ2S1JoSTlsTk5nQQpUSDIzTVJkYUtYb0tHQ1F3b3plMWVxa0JmU2JXK1E2T1dmSDlHek8xS1RzWE8wRzJJZDNVd0QybG41OGZRMURKdTd4c2VwZVk3czJNCkgvdWNVYTZMY0wwbm4zSEFhNng5a0dibzExMDZEYkRWd28zVnlKMmR3VzNRMEw5UjVPUDR3emcycnRhbmRlYXZoRU5kazVJTWFnZmUKT3gyWUl0YXN3VFhibzZBbC8zSzFkaDNlYmVrc1ppeFNoTkJGa3M0YzVlVXpIZHdIVTFTanFvSTdtamN2M04yZ1pPbm0zYjJ1L0dTRgpIVHlueVFiZWhQOXI2R3NhUE1XaXMwTDdpd2srWHdoU3gyTEUxQVZ4djhSazVQaWhnK2crRXB1b0h0UTJUUzl4OW8wbzlvT3BFOUpoCndaRzdTTUEwajBHTVMwemJhUkwvVUpTY0lJTlpjKzE4b2ZMeC9kMzNTZE5EV0tCV1k4bzlQZVUxVmxucERzb2d6Q3RMa3lrUEFnTUIKQUFHamdnRnFNSUlCWmpBU0JnTlZIUk1CQWY4RUNEQUdBUUgvQWdFTU1CMEdBMVVkRGdRV0JCUzVDY3FjSHR2VGJEcHJydTFVOFZ1VApCalV1WGpDQjRRWURWUjBqQklIWk1JSFdnQlM1Q2NxY0h0dlRiRHBycnUxVThWdVRCalV1WHFHQnNxU0JyekNCckRFTE1Ba0dBMVVFCkJoTUNSVlV4UXpCQkJnTlZCQWNUT2sxaFpISnBaQ0FvYzJWbElHTjFjbkpsYm5RZ1lXUmtjbVZ6Y3lCaGRDQjNkM2N1WTJGdFpYSm0KYVhKdFlTNWpiMjB2WVdSa2NtVnpjeWt4RWpBUUJnTlZCQVVUQ1VFNE1qYzBNekk0TnpFYk1Ca0dBMVVFQ2hNU1FVTWdRMkZ0WlhKbQphWEp0WVNCVExrRXVNU2N3SlFZRFZRUURFeDVIYkc5aVlXd2dRMmhoYldKbGNuTnBaMjRnVW05dmRDQXRJREl3TURpQ0NRREp6ZFBwCjFYMGp6akFPQmdOVkhROEJBZjhFQkFNQ0FRWXdQUVlEVlIwZ0JEWXdOREF5QmdSVkhTQUFNQ293S0FZSUt3WUJCUVVIQWdFV0hHaDAKZEhBNkx5OXdiMnhwWTNrdVkyRnRaWEptYVhKdFlTNWpiMjB3RFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUlDSWYzRGVraWpaQlpSRwovNUJYcWZFdjN4b05hL3A4RGh4SkpIa24yRWFxYnlsWlVvaHdFdXJkUGZXYlUxUnY0V0NpcUFtNTdPdFpmTVkxOGR3WTZmRm41YSs2ClJlQUozc3BFRDhJWERuZVJSWG96WDErV0xHaUx3VWVQbUpzOXdPekw5ZFdDa29RMTBiNDJPRlp5TVZ0SExhb1hwR05SNndvQnJYL3MKZFo3TG9SL3hmeEt4dWVSa2YyZldJeXIwdURsZG1PZ2hwK0c5UFVJYWRKcHdyMmhzVUYxSnovLzdEbDNtTEVmWGdUcFpBTFZ6YTJNZwo5akZGQ0RrTzlIQitRSEJhUDlCclFxbDBQU2d2QW0xMWNwVUpqVWhqeHNZalY1S1RYalhCamZrSzl5eWRZaHoyclh6ZHBqRWV0ckhICmZvVW0rcVJxdGRwak1OSHZremV5Wmk5OUJmZm50MHVZbERYQTJUb3B3WjJ5VURNZFNxbGFwc2tENyszMDU2aHVpclJYaE91a1A5RHUKcXFxSFcyUG9rK0pycU5TNGNuaHJHKzA1NUYzTG02cUgxVTlPQVA3WmFwODhNUThvQWdGOW1PaW5zS0prbm5uNFNQSVZxY3pteUVUcgpQM2laOG50eFBqenhtS2ZGR0JJLzVyc29NMExwUlFwOGJmS0dlUy9GZ2hsOUNZbDhzbFIyaUs3ZXdmUE00VzdiTWRhVHJwbWc3eVZxCmM1aUpXem91RTRnZXY4Q1NsRFFiNHllM2l4NXZRdi9uNlRlYlVCMHRvdmtDN3N0WVdEcHh2R2pqcXNHdkhDZ2ZvdHdqWlQrQjZxNloKMDlnd3p4TU5UeFhKaEx5blNDMzRNQ04zMkVaTGVXMzJqTzA2ZjJBUmVQVHBtNjdWVk1CMGdORUxRcC9CCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdvIERhZGR5IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHhUQ0NBcTJnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFzRkFEQ0JnekVMTUFrR0ExVUVCaE1DVlZNeEVEQU9CZ05WQkFnVApCMEZ5YVhwdmJtRXhFekFSQmdOVkJBY1RDbE5qYjNSMGMyUmhiR1V4R2pBWUJnTlZCQW9URVVkdlJHRmtaSGt1WTI5dExDQkpibU11Ck1URXdMd1lEVlFRREV5aEhieUJFWVdSa2VTQlNiMjkwSUVObGNuUnBabWxqWVhSbElFRjFkR2h2Y21sMGVTQXRJRWN5TUI0WERUQTUKTURrd01UQXdNREF3TUZvWERUTTNNVEl6TVRJek5UazFPVm93Z1lNeEN6QUpCZ05WQkFZVEFsVlRNUkF3RGdZRFZRUUlFd2RCY21sNgpiMjVoTVJNd0VRWURWUVFIRXdwVFkyOTBkSE5rWVd4bE1Sb3dHQVlEVlFRS0V4RkhiMFJoWkdSNUxtTnZiU3dnU1c1akxqRXhNQzhHCkExVUVBeE1vUjI4Z1JHRmtaSGtnVW05dmRDQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGtnTFNCSE1qQ0NBU0l3RFFZSktvWkkKaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMOXhZZ2p4K2xrMDl4dkpHS1AzZ0VsWTZTS0RFNmJGSUVNQk80VHg1b1ZKbnlmcQo5b1FiVHFDMDIzQ1l4eklCc1FVK0IwN3U5UHBQTDFrd0l1ZXJHVlpyNG9BSC9QTVdkWUE1VVh2bCtUVzJkRTZwallJVDVMWS9xUU9ECitxSytpaFZxZjk0THc3WVpGQVhLNnNPb0JKUTdSbnd5RGZNQVppTElqV2x0Tm93UkdMZlRzaHhndERqNkFvek8wOTFHQjk0S1B1dGQKZk1oOCs3QXJVNlNTWW1sUkpRVmhHa1NCakN5cFE1WWozNnc2Z1pvT0tjVWNxZWxkSHJhZW5qQUtPYzd4aUlEN1MxM01NdXlGWWtNbApOQUpXSndHUnREdHdLajl1c2VpY2lBRjluOVQ1MjFOdFlKMi9MT2RZcTdoZlJ2ek94QnNEUEFuclNURmNhVWF6NEVjQ0F3RUFBYU5DCk1FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZEcWFoUWNRWnlpMjcvYTkKQlVGdUlNR1UyZy9lTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDWjIxMTUxZm1YV1djRFlmRitPd1l4ZFMyaElJNVBaWWUwOTZhYwp2TmpwTDlEYld1N1BkSXh6dERoQzJnVjcrQUoxdVAybHNkZXU5dGZlRTh0VEVINktSdEdYK3JjdUt4R3JrTEFuZ1Bub24xcnBONStyCjVOOXNzNFVYblQzWkpFOTVrVFhXWHdUcmdJT3JtZ0l0dFJEMDJKREhCSE5BN1hJbG9LbWY3SjZyYUJLWlY4YVBFam9KcEwxRS9RWVYKTjhHYjVES2o3VGpvMkdUekxINFUvQUxxbjgzL0IyZ1gyeUtRT0MxNmpkRlU4V25qWHpQS2VqMTdDdVBLZjE4NTVlSjF1c1YyR0RQTwpMUEF2VEszM3NlZk9UNmpFbTBwVUJzVi9mZFVJRCtJYy9uNFh1S3hlOXRRV3NrTUpERTMycDJ1MG1ZUmx5bnFJNHVKRXZsejM2aHoxCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEM1RDQ0FzV2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURDQmp6RUxNQWtHQTFVRUJoTUNWVk14RURBT0JnTlZCQWdUCkIwRnlhWHB2Ym1FeEV6QVJCZ05WQkFjVENsTmpiM1IwYzJSaGJHVXhKVEFqQmdOVkJBb1RIRk4wWVhKbWFXVnNaQ0JVWldOb2JtOXMKYjJkcFpYTXNJRWx1WXk0eE1qQXdCZ05WQkFNVEtWTjBZWEptYVdWc1pDQlNiMjkwSUVObGNuUnBabWxqWVhSbElFRjFkR2h2Y21sMAplU0F0SUVjeU1CNFhEVEE1TURrd01UQXdNREF3TUZvWERUTTNNVEl6TVRJek5UazFPVm93Z1k4eEN6QUpCZ05WQkFZVEFsVlRNUkF3CkRnWURWUVFJRXdkQmNtbDZiMjVoTVJNd0VRWURWUVFIRXdwVFkyOTBkSE5rWVd4bE1TVXdJd1lEVlFRS0V4eFRkR0Z5Wm1sbGJHUWcKVkdWamFHNXZiRzluYVdWekxDQkpibU11TVRJd01BWURWUVFERXlsVGRHRnlabWxsYkdRZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwWlNCQgpkWFJvYjNKcGRIa2dMU0JITWpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDN0d1FQODlvLzhBckZ2Clc1OUkyWjE1NHFLM0EyRldHTU5IdHRmS1BUVXVpVVAzb1dtYjNvb2EvUk1nbkxSSmR6SXBWdjI1N0l6ZEl2cHkzQ2RobCs3MldvVHMKYmhtNWlTemNoRnZWZFB0clg4V0pwUkJTaVVaVjlMaDFIT1ovNUZTdVMvaFZjbGNDR2ZnWGNWbnJIaWdIZE1XZFNMNXN0UFNrc1BOawpOM21Td094R1huL2hiVk5NWXEvTkh3dGp1enFkKy94NUFKaGhkTThtZ2tCajg3SnlhaGtObWNyVURuWE1OL3VMaWNGWjhXSi9YN05mClpURDRwN2ROZGxvZWRsNDB3T2lXVnBtS3MvQi9wTTI5M0RJeGZKSFA0RjhSK0d1cVNWelJtWlRSb3VOald3bDJ0VlppNFV0MEhaYlUKSnRRSUJGblFtQTRPNXQ3OHcrd2ZrUEVDQXdFQUFhTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQwpBUVl3SFFZRFZSME9CQllFRkh3TU1oK24yVEIveEgxb28yS29vYzZyQjFzbk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQVJXZm9sClR3TnZsSms3bWgrQ2hUblVkZ1dVWHVFb2syMWlYUW5Db0tqVXNIVTQ4VFJxbmVTZmlvWW1VZVlzMGNZdGJwVWdTcElCN0xpS1ozc3gKNG1jdWpKVURKaTVEblVveDlnNjFETHUzNGpkL0lyb0FvdzU3VXZ0cnV6dkUwM2xSVHMyUTlHY0hHY2c4Um5vTkFYM0ZXT2R0NW9VdwpGNW9reEJEZ0JQZmc4bi9VcWdyL1FoMDM3WlRsWkZrU0lIYzQwekkrT0lGMWxuUDZhSSt4eTg0ZnhlejZuSDdQZnJIeEJ5MjIvTC9LCnBML1Fsd1ZLdk9vWUtBS1F2VlI0Q1NGeDA5RjlIZGtXc0tsaFBkQUtBQ0w4eDN2TENXUkZDenRBZ2ZkOWZETDFtTXBZam4wcTdwQloKYzJUNU5uUmVKYUgxWmdVdWZ6a1ZxU3I3VUl1T2hXbjAKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU3RhcmZpZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ3ekNDQXRlZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBRENCbURFTE1Ba0dBMVVFQmhNQ1ZWTXhFREFPQmdOVkJBZ1QKQjBGeWFYcHZibUV4RXpBUkJnTlZCQWNUQ2xOamIzUjBjMlJoYkdVeEpUQWpCZ05WQkFvVEhGTjBZWEptYVdWc1pDQlVaV05vYm05cwpiMmRwWlhNc0lFbHVZeTR4T3pBNUJnTlZCQU1UTWxOMFlYSm1hV1ZzWkNCVFpYSjJhV05sY3lCU2IyOTBJRU5sY25ScFptbGpZWFJsCklFRjFkR2h2Y21sMGVTQXRJRWN5TUI0WERUQTVNRGt3TVRBd01EQXdNRm9YRFRNM01USXpNVEl6TlRrMU9Wb3dnWmd4Q3pBSkJnTlYKQkFZVEFsVlRNUkF3RGdZRFZRUUlFd2RCY21sNmIyNWhNUk13RVFZRFZRUUhFd3BUWTI5MGRITmtZV3hsTVNVd0l3WURWUVFLRXh4VApkR0Z5Wm1sbGJHUWdWR1ZqYUc1dmJHOW5hV1Z6TENCSmJtTXVNVHN3T1FZRFZRUURFekpUZEdGeVptbGxiR1FnVTJWeWRtbGpaWE1nClVtOXZkQ0JEWlhKMGFXWnBZMkYwWlNCQmRYUm9iM0pwZEhrZ0xTQkhNakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBTlVNT3NRcStVN2k5YjRabDErT2lGT3hIei9MejU4Z0UyMHBPc2dQZlR6M2EzWTRZOWsyWUtpYlhsd0FnTEl2V1gvMgpoL2tsUTRibmFSdFNtcERoY2VQWUxRMU9iL2JJU2RtMjh4cFdyaXUyZEJUcnovc200eHE2SFpZdWFqdFlsSWxIVnY4bG9KTndVNFBhCmhIUVV3MmVlQkdnNjM0NUFXaDFLVHM5RGtUdm5WdFlBY010UzdudDlyanJudkRINVJmYkNZTThUV1FJcmdNdzBSOSs1M3BCbGJRTFAKTEpHbXB1ZmVoUmhKZkdaT296cHRxYlh1TkM2NkRRTzRNOTlINjdGcmpTWFptODZCMFVWR01wWndoOTRDRGtsRGhiWnNjN3RrNm1GQgpyTW5VVk4rSEw4Y2lzaWJNbjFsVWFKLzh2aW92eEZVY2RVQmdGNFVDVlRtTGZ3VUNBd0VBQWFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3CkF3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwT0JCWUVGSnhmQU4rcUFkY3dLemlJb3JodFNwenlFWkdETUEwR0NTcUcKU0liM0RRRUJDd1VBQTRJQkFRQkxOcWFFZDJuZE94bWZaeU1JYnc1aHlmMkUzRi9ZTm9ITjJCdEJMWjlnM2NjYWFOblJib2JoaUNQUApFOTVEeitJMHN3U2RIeW5Wdi9oZXlOWEJ2ZTZTYnpKMDhwR0NMNzJDUW5xdEtyY2dmVTI4ZWxVU3doWHF2ZmRxbFM1c2RKL1BITFR5CnhRR2poZEJ5UHExenF3dWJkUXh0UmJlT2xLeVdON1dnMEk4VlJ3N2o2SVBkai8zdlFRRjN6Q2VwWW9VejhqY0k3M0hQZHdiZXlCa2QKaUVEUGZVWWQveDdINGM3L0k5dkcrbzFWVHFrQzUwY1JSajcwL2IxN0tTYTdxV0ZpTnlpMkxTcjJFSVpreVhDbjBxMjNLWEI1Nmp6YQpZeVdmL1dpM01PeHcrM1dLdDIxZ1o3SWV5TG5wMktodkFvdG5EVTBtVjNIYUlQekJTbENOc1NpNgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBZmZpcm1UcnVzdCBDb21tZXJjaWFsCj09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURURENDQWpTZ0F3SUJBZ0lJZDNjR0p5YXBzWHd3RFFZSktvWklodmNOQVFFTEJRQXdSREVMTUFrR0ExVUVCaE1DVlZNeEZEQVMKQmdOVkJBb01DMEZtWm1seWJWUnlkWE4wTVI4d0hRWURWUVFEREJaQlptWnBjbTFVY25WemRDQkRiMjF0WlhKamFXRnNNQjRYRFRFdwpNREV5T1RFME1EWXdObG9YRFRNd01USXpNVEUwTURZd05sb3dSREVMTUFrR0ExVUVCaE1DVlZNeEZEQVNCZ05WQkFvTUMwRm1abWx5CmJWUnlkWE4wTVI4d0hRWURWUVFEREJaQlptWnBjbTFVY25WemRDQkRiMjF0WlhKamFXRnNNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUYKQUFPQ0FROEFNSUlCQ2dLQ0FRRUE5aHRQWndjcm9SWDFCaUxMSHdHeTQzTkZCa1JKTEx0SkpSVFd6c08zcXl4UHhrRXlsRmY2RXFkYgpEdUtQSHg2R0dhZXF0UzI1WHcyS3dxK0ZOWGt5TGJzY1lqZnlzVnRLUGNyTmNWL3BRcjZVNk1qZStTSklaTWJscThZcmJhMEY4UHJWCkM4K2E1ZkJRcElzN1I2VWpXM3A2K0RNL3VPK1psK01nd2RZb2ljK1UrN2xGN2VOQUZ4SFVkUEFMTWVJckptcWJURmV1ckNBK3VrVjYKQmZPOW0ya1ZybjFPSUdQRU5YWTZCd0xKTi8zSFIrN284WFlkY3hYeWw2UzF5SHA1MlVLcUszOWMvczRtVDZObWdUV3ZSTHBVSGh3dwpNbVdkNWp5VFhsQk9ldU02MUc3TUd2djUwamV1SkNxclZ3TWlLQTFKZFgrM0tOcDF2NDdqM0E1NU1RSURBUUFCbzBJd1FEQWRCZ05WCkhRNEVGZ1FVblpQR1U0dGV5cTgvbng0UDVabVZ2Q1QybEk4d0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUMKQVFZd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFGaXM5QVFPemNBTi93cjkxTG9XWHltOWUyaVpXRW5TdEIwM1RYOG5mVVlHWFVQRwpoaTQrYzdJbWZVK1RxYmJFS3BxcklaY1VzZDZNMDZ1SkZkaHJKTlR4RnE3WXBGelVmMUdPN1JnQnNaTmp2Yno0WVlDYW5ySE9RbkRpCnFYMEdKWDBub2Y1djdMTWVKTnJqUzFVYUFEczF0RHZaMTEwdy9ZRVRpZkxDQml2dFo4U095VU95WEdzVmlRSzhZdnhPOHJVenFySnYKMHdxaVVPUDJPK2d1Uk1MYlpqaXBNMVpJOFcwYk00ME5qRDlnTjUzVHltMStOSDRObjNKMml4dWZjdjFTTlVGRkFwWXZITEthYzBraApzVWxIUlVlMDcybzBFY2xObXN4WnQ5WUNubHBPWmJXVXJodmZLYkFXOGI4QW5nYzZGMlMxQkxVaklaa0tsVHVYZk84PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBZmZpcm1UcnVzdCBOZXR3b3JraW5nCj09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURURENDQWpTZ0F3SUJBZ0lJZkU4RU9SelVtUzB3RFFZSktvWklodmNOQVFFRkJRQXdSREVMTUFrR0ExVUVCaE1DVlZNeEZEQVMKQmdOVkJBb01DMEZtWm1seWJWUnlkWE4wTVI4d0hRWURWUVFEREJaQlptWnBjbTFVY25WemRDQk9aWFIzYjNKcmFXNW5NQjRYRFRFdwpNREV5T1RFME1EZ3lORm9YRFRNd01USXpNVEUwTURneU5Gb3dSREVMTUFrR0ExVUVCaE1DVlZNeEZEQVNCZ05WQkFvTUMwRm1abWx5CmJWUnlkWE4wTVI4d0hRWURWUVFEREJaQlptWnBjbTFVY25WemRDQk9aWFIzYjNKcmFXNW5NSUlCSWpBTkJna3Foa2lHOXcwQkFRRUYKQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0SVRNTXhjdWE1UnNhMkZTb091anozbVVUT1dVZ0puTFZXUkVaWTluWk9JRzQxdzNTZll2bTRTRQpIaTN5WUowd1RzeUVoZUlzeng2ZS9qYXJNM2MxUk5nMWxobzlOdWg2RHRqVlI2RnFhWXZaL0xzNnJubGExZlRXY2J1YWtDTnJtcmVJCmRJY01IbCs1bmkzNnExTXIzTHQyUHBOTUNBaU1IcUlqSE5ScXJTSzZtUUV1YldYTHZpUm1WU1JMUUVTeEc5Zmh3b1hBM2hBL1BlMjQKL1BIeEkxUGN2MldYYjluNVFIR05mYjJWMU02K29GNG5JOTc5cHRBbURnQXA2enhHOEQxZ3Z6OVEwdHdtUVZHZUZEZENCS053VjZnYgpoKzB0K252dWpBcmpxV2FKR2N0QitkMUVObUhQNG5kR3lIMzI5SktCTnYzYk5QRnlmdk1NRnIyMEZRSURBUUFCbzBJd1FEQWRCZ05WCkhRNEVGZ1FVQngvUzU1emF3bTZpUUxTd2VsQVFVSFRFeUwwd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUMKQVFZd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFJbFhzaFo2cU1MOTF0bWJtelRDbkxReUZFMm5wTi9zdnFlKytFUGJrVGZPdERJdQpVRlVhTlU1MlEzRWc3NU4zVGhWd0xvZkR3UjF0M011MUo5UXNWdEZTVXpwRTBuUEl4QnNGWlZwaWtwenVRWTB4MitjMDZsa2gxUUY2CjEyUzRaRG5OeWUydjdVc0RTS2VnbVFHQTNHV2pOcTVsV1VoUGdrdklaZkZYSGVWWkxnby9iTmpSOWVVSnRHeFVBQXJnRlUySGRXMjMKV0paYTNXM1NBS0QwbTBpK3d6ZWt1amJnZkllRmx4b1ZvdDR1b2x1OXJ4ajVrRkROY0ZuNEoyZEh5OGVnQnpwOTBTeGRiQms2WnJWOQovWkZ2Z3JHK0NKUGJGRWZ4b2pmSFJaNDh4M2V2WktpVDMvWnBnNEpnOGtsQ05PMWFBRlNGSEJZMmtneGMrcWF0djlzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBZmZpcm1UcnVzdCBQcmVtaXVtCj09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZSakNDQXk2Z0F3SUJBZ0lJYll3VVJyR21DdTR3RFFZSktvWklodmNOQVFFTUJRQXdRVEVMTUFrR0ExVUVCaE1DVlZNeEZEQVMKQmdOVkJBb01DMEZtWm1seWJWUnlkWE4wTVJ3d0dnWURWUVFEREJOQlptWnBjbTFVY25WemRDQlFjbVZ0YVhWdE1CNFhEVEV3TURFeQpPVEUwTVRBek5sb1hEVFF3TVRJek1URTBNVEF6Tmxvd1FURUxNQWtHQTFVRUJoTUNWVk14RkRBU0JnTlZCQW9NQzBGbVptbHliVlJ5CmRYTjBNUnd3R2dZRFZRUUREQk5CWm1acGNtMVVjblZ6ZENCUWNtVnRhWFZ0TUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEEKTUlJQ0NnS0NBZ0VBeEJMZnFWLytRZDNkOVorSzQvYXM0VHg0bXJ6WThIOTZvRE1xM0kwZ1c2NHRiK2VUMlRad2FtalBqbEdqaFZ0bgpCS0FRSkc5ZEtJTEJsMWZZU0NrVHR1RytrVTNmaFF4VEdKb2VKS0pQai9DaWhRdkw5Q2wvMHFSWTdpWk55YXFvZTVyWitqamVSRmNWCjVmaU15TmxJNGcwV0p4MGV5SU9GSmJlNnFsVkJ6QU1pU3kyUmpZdm1pYTlteCtuL0srazhyTnJTczhQaGFKeUorSG9BVnQ3MFZaVnMKKzdwazNXS0wzd3QzTXV0aXpDYWFtN3VxWW9OTXRBWjZNTWdwdiswR1RaZTVITVF4SzlWZnZGTVNGNXlaVnlsbWQyRWhNUWN1SlVtZApHUEx1OHl0eGpMVzZPUWRKZC96dkxwS1FCWTB0TDNkNzcwTy9OYnVhMlBsenB5enkwRmZ1S0U0bVg0K1FhQWt2dVBqY0J1a3VtajVSCnA5RWl4QXFuT0Voc3Mvbi9mYXVHVitPNjFvVjRkN3BENmtoLzl0aStJMjBldjlFMmJGaGM4ZTZrR1ZRYTlRUFNkdWJoakwwOHM5TkkKUytMSStIK1NxSFpHbkVKbFBxUWV3UWNEV2tZdHVKZnp0OVd5VlNIdnV0eE1BSmY3RkpVbk03L29RMGRHMGdpWkZtQTdtbjdTNXUwNAo2dXdCSGp4SVZra0p4MHczQUo2SURzQno0VzltNlhKSE1ENFE1UXNEeVpwQ0FHekZsSDVoeElyZmY0SWFDMW5FV1RKM3M3eGdhVlk1Ci9iUUdleXpXWkRiWnZVanRoQjkrcFNLUEtyaEM5SUszMUZPUWVFNHRHdjJCYjBUWE93RjBsa0xnQU9JdWErckY3bktzdTcvKzZxcW8KK056MnNubUt0bWNDQXdFQUFhTkNNRUF3SFFZRFZSME9CQllFRkozQVo2WU1JdGttOVVXcnBtVlNFU2ZZUmF4ak1BOEdBMVVkRXdFQgovd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BMEdDU3FHU0liM0RRRUJEQVVBQTRJQ0FRQ3pWMDBRWWs0NjVLenF1Qnl2Ck1pUElzMGxhVVp4MktJMTVxbGRHRjlYMVV2YTNST2dJUkw4WWhOSUxnTTNGRXYwQVZRVmhoMEhjdFNTZVBNVFl5UHR3bmk5NGxvTWcKTnQ1OEQya1RpS1YxTnBnSXBzYmZyTTdqV05hM1B0NjY4K3MwUU5paWdmVjRQeS9WcGZ6Wm90UmVCQTRYcmY1QjhPV3ljdnBFZ2pOQwo2QzFZOTFhTVlqKzZRckNjREZ4K0xtVW1YRk5QQUxKNGZxRU5tUzJOdUIyT29zU3cvV0RRTUtTT3lBUmlxY1R0TmQ1NmwrME9PRjZTCkw1TndwYW1jYjZkOUV4MSt4Z2hJc1Y1bjYxRUlKZW5tSld0U0taR2Mwamx6Q0ZmZW1RYTBXNTBRQnVIQ0FLaTRIRW9DQ2hUUXdVSEsKKzR3MUlYMkNPUEtwVkpFWk5aT1ViV282eGJMUXU0bUdrK2lieVE4NnAzcTRvZkI0UnZyOE55L2xpb1R6My80RTJhRm9vQzhrNGdtVgpCdFdWeXVFa2x1dDg5cE1GdSsxejZTM1JkVG5YNXlUYjJFNWZRNCtlMEJRNXYxVndTSmxYTWJTYzdrcVlBNVl3SDJBRzdoc2ovb0ZnCkl4cEhZb1dsekJrMGdHK3pyQnJqbi9CN1NLM1ZBZGxudHFseWsrb3Racld5dU9ROVBMTHZUSXpxNndlL3F6V2FWWWE4R0thMXFGNjAKZzJ4cmFVRFRuOXp4dzJscnVlRnRDZlR4cWxCMkNucDllaGVoVlpaQ21URUozV0FSalFVd2Z1YU9SdEdkRk5ySEYrUUZsb3pFSkxVYgp6eFFIc2tENG81NUJocndFMEd1V3lDcUFOUDIvN3dhajNWakZoVDArai82ZUtlQzJ1QWxvR1J3WVF3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUIvakNDQVlXZ0F3SUJBZ0lJZEpjbGlzYy9lbFF3Q2dZSUtvWkl6ajBFQXdNd1JURUxNQWtHQTFVRUJoTUNWVk14RkRBU0JnTlYKQkFvTUMwRm1abWx5YlZSeWRYTjBNU0F3SGdZRFZRUUREQmRCWm1acGNtMVVjblZ6ZENCUWNtVnRhWFZ0SUVWRFF6QWVGdzB4TURBeApNamt4TkRJd01qUmFGdzAwTURFeU16RXhOREl3TWpSYU1FVXhDekFKQmdOVkJBWVRBbFZUTVJRd0VnWURWUVFLREF0QlptWnBjbTFVCmNuVnpkREVnTUI0R0ExVUVBd3dYUVdabWFYSnRWSEoxYzNRZ1VISmxiV2wxYlNCRlEwTXdkakFRQmdjcWhrak9QUUlCQmdVcmdRUUEKSWdOaUFBUU5NRjRiRlowRDBLRjVOYmM2UEpKNnloVWN6V0x6bkNaY0J6M2xWUHFqMXN3UzZ2UVVYK2lPR2Fzdkxram1yQmhEZUt6UQpOOE85c3MwczVrZmlHdVpqdUQwdUwzakVUOXYwRDZSb1RGVnlhNVVkVGhoQ2xYak1OenlSNHB0bEt5bWpRakJBTUIwR0ExVWREZ1FXCkJCU2FyeWw2d0JFMU5TWlJNQUREYXY1QTFhN1dQREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQUsKQmdncWhrak9QUVFEQXdObkFEQmtBakFYQ2ZPSGlGQmFyOGpBUXI5SFgvVnNhb2JneENkMDVEaFQxd1YvR3pUanhpK3p5Z2s4TjUzWAo1N2hHOGYyaDRuRUNNRUpaaDBQVVVkKzYwd2t5V3M2SWZsYzluRjlDYS9VSExiWHdncFA1V1crdVpQcFk1WXNlNDJPK3RZSE5id0tNCmVRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEdXpDQ0FxT2dBd0lCQWdJREJFVEFNQTBHQ1NxR1NJYjNEUUVCQlFVQU1INHhDekFKQmdOVkJBWVRBbEJNTVNJd0lBWURWUVFLCkV4bFZibWw2WlhSdklGUmxZMmh1YjJ4dloybGxjeUJUTGtFdU1TY3dKUVlEVlFRTEV4NURaWEowZFcwZ1EyVnlkR2xtYVdOaGRHbHYKYmlCQmRYUm9iM0pwZEhreElqQWdCZ05WQkFNVEdVTmxjblIxYlNCVWNuVnpkR1ZrSUU1bGRIZHZjbXNnUTBFd0hoY05NRGd4TURJeQpNVEl3TnpNM1doY05Namt4TWpNeE1USXdOek0zV2pCK01Rc3dDUVlEVlFRR0V3SlFUREVpTUNBR0ExVUVDaE1aVlc1cGVtVjBieUJVClpXTm9ibTlzYjJkcFpYTWdVeTVCTGpFbk1DVUdBMVVFQ3hNZVEyVnlkSFZ0SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjUKTVNJd0lBWURWUVFERXhsRFpYSjBkVzBnVkhKMWMzUmxaQ0JPWlhSM2IzSnJJRU5CTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQwpBUThBTUlJQkNnS0NBUUVBNC90OW8zSzZ3dkRKRklmMWF3Rk80VzVBQjdwdEoxMS85MXN0czFySFVWK3JwREttWVllMmJnK0cwakFDCmwvalhhVmVoR0RsZGFtUjV4Z0ZackR3eFNqaDgwZ1RTU3lqb0lGODdCNkxNVFhQYjg2NVB4MWJWV3FlV2lmcnpxMmpVSTRaWko4OEoKSjd5c2JuS0RIREJ5MytDaTZkTGhkSFVadlNxZWV4VlVCQnZYUXptdFZTakY0aHE3OU1Ea3JqaEpNOHgyaFo4NVJkS2tudklTakZINApmT1F0Zi9Xc1grc1duN0V0MGJyTWtVSjNUQ1hKa0RodjIvRE0rNDRlbDFrKzFXQk81Z1VvN1VsNUUwdTZTTnN2K1hMVE9jcitIOWcwCmN2VzBRTTh4QWNQczNoRXRGMTBmdUZEUlhobW5hZDRITXlqS1VKWDVwMVRMVklaUVJhbjVTUUlEQVFBQm8wSXdRREFQQmdOVkhSTUIKQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRSWRzM0xCLzhrOXNYTjdidVF2T0tFTjBaMTl6QU9CZ05WSFE4QkFmOEVCQU1DQVFZdwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBS2FvclNMT0FUMm1vLzlpMEVpZGkxNXlzSGhFNDl3Y3J3bjlJMGo2dlNyRXVWVUV0UkNqCmpTZmVDNEpqME83ZUREZDVRVnNpc3JDYVFWeW1jT0RVMEhmTEk5TUE0R3hXTCtGcERRM1pxcjhoZ1ZEWkJxV28vNVUzMEtyKzRyUDEKbVMxRmhJcmxRZ25YZEFJdjk0blltZW04SjlSSGpib05SaHgzenhTa0hMbWtNY1NjS0hRRE5QOHpHU2FsNlExMHR6Nlh4bmJvSjVhagpadDNocnZKQlc4cVlWb056Y09TR0d0SXhRYm92dmkwVFduWnZUdWhPZ1E0L1d3TWlvQksrWmxnUlNzc0R4TFFxS2kyV0YrQTVWTHhJCjAzWW5uWm90QnFiSjdEblNxOXVmbWdzbkFqVXBzVUNWNS9ub25GV0lHVWJXdHpUMWZzNDVtdGs0OFZIM1R5dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVFdDQSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGV6Q0NBbU9nQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQmZNUXN3Q1FZRFZRUUdFd0pVVnpFU01CQUdBMVVFQ2d3SgpWRUZKVjBGT0xVTkJNUkF3RGdZRFZRUUxEQWRTYjI5MElFTkJNU293S0FZRFZRUUREQ0ZVVjBOQklGSnZiM1FnUTJWeWRHbG1hV05oCmRHbHZiaUJCZFhSb2IzSnBkSGt3SGhjTk1EZ3dPREk0TURjeU5ETXpXaGNOTXpBeE1qTXhNVFUxT1RVNVdqQmZNUXN3Q1FZRFZRUUcKRXdKVVZ6RVNNQkFHQTFVRUNnd0pWRUZKVjBGT0xVTkJNUkF3RGdZRFZRUUxEQWRTYjI5MElFTkJNU293S0FZRFZRUUREQ0ZVVjBOQgpJRkp2YjNRZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUN3Zm5LNHBBT1U1cWZlQ1RpUlNoRkFoNmQ4V1dRVWU3VVJFTjMrdjlYQXUxYmloU1gwTlhJUCtGUFFRZUZFQWNLMEhNTXgKUWhaSGhUTWlkcklLYncvbEpWQlBoWWErdjVndUVHY2V2aEVGaGdXUXhGblFmSGdRc0lCY3QrSEhLM1hMZkordXRkR2RJemRqcDl4QwpvaTJTQkJ0UXdYdTRQaHZKVmdTTEwxS2JyYWxXNmNIL3JhbFloekMyZ2ZlWFJmd1pWenNyYitSSDlKbEYvaDN4K0plamlCMDNIRnlQCjRIWWxtbEQ0b0ZUL1JKQjJJOUl5eHNPckJyLzgrNy96clgyU1lnSmJLZE0xbzVPYVEyUmdYYkw2TXY4N0JLOU5RR3I1eCtQdkkvMXIKeStVUGl6Z043Z3I4L2crWW56QXgzV3hTWmZtTGdiNGk0UnhZQTdxUkc0a0hBZ01CQUFHalFqQkFNQTRHQTFVZER3RUIvd1FFQXdJQgpCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlJxT0ZzbWpkNkxXdkpQZWxTREdSampDRFdtdWpBTkJna3Foa2lHCjl3MEJBUVVGQUFPQ0FRRUFQTlYzUGRyZmlicUhEQWhVYWlCUWtyNndRVDI1Sm1TRENpL29RTUNYS0NlQ01FckprLzlxNTZZQWY0bEMKbXRZUjVWUE9MOHp5MmdYRS91SlF4RHFHZmN6YWZoQUpPNUkxS2xPeS91c3JCZGxzWGViUTc5TnFacDRWS0lWNjZJSUFyQjZuQ1dsVwpRdE5vVVJpK1ZKcS9SRUc2U2I0Z3VtbGM3cmgzemM1c0g2MkRsaGg5RHJVVU9ZVHhLT2t0bzU1N0hucHlXb096ZVcvdnRQelFDcVZZClQwYmYrMjE1V2ZLRUlsS3VEOHo3ZkR2bmFzcEhZY042K05PU0JCKzRJSVRoTmxRV3gwRGVPNHB6M04vR0NVemY3TnIvMUZOQ29jbnkKWWgwaWd6eVh4ZmtaWWllc1pTTFgwenpHNVk2eVU4eEp6cnd3L25zT001RDc3ZElVa1I4SHJ3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGR6Q0NBbCtnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFzRkFEQmRNUXN3Q1FZRFZRUUdFd0pLVURFbE1DTUdBMVVFQ2hNYwpVMFZEVDAwZ1ZISjFjM1FnVTNsemRHVnRjeUJEVHk0c1RGUkVMakVuTUNVR0ExVUVDeE1lVTJWamRYSnBkSGtnUTI5dGJYVnVhV05oCmRHbHZiaUJTYjI5MFEwRXlNQjRYRFRBNU1EVXlPVEExTURBek9Wb1hEVEk1TURVeU9UQTFNREF6T1Zvd1hURUxNQWtHQTFVRUJoTUMKU2xBeEpUQWpCZ05WQkFvVEhGTkZRMDlOSUZSeWRYTjBJRk41YzNSbGJYTWdRMDh1TEV4VVJDNHhKekFsQmdOVkJBc1RIbE5sWTNWeQphWFI1SUVOdmJXMTFibWxqWVhScGIyNGdVbTl2ZEVOQk1qQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFOQVZPVkt4VXJPNnhWbUN4RjFTcmpwRFpZQkx4L0tXdk5zMmw5YW1aSXlvWHZEakNoejMzNWM5UzY3Mlhld2h0VUdyemJsK2RwKysKK1Q0Mk5LQTd3Zll4RVVWMGt6MVhnTVg1aVpuSzVhdHExTFhhUVpBUXdkYldRb25Ddi9RNEVwVk1WQVgzTnVSRmczc1VaZGJjREUzUgozbjRNcXp2RUZiNDZWcVphYjNacFVxbDZ1Y2pyYXBwZFV0QXRDbXMxRmdrUWhOQnF5am9HQURkSDVINVhUeitMNjJlNGlLckZ2bE5WCnNwSEVmYm13aFJrR2VDN2JZUnI2aGZWS2thSG5GdFdPb2puZmxMaHdIeWcvaS94QVhtT0RQSU1xR3Bscno5NVphanY4YnhiWEgvMUsKRU90T2doWTZyQ2NNVS9HdDFTU3dhd05Rd1MwOEZ0MUVOQ2NhZGZzQ0F3RUFBYU5DTUVBd0hRWURWUjBPQkJZRUZBcUZxWGRsQlpoOApRSUg0RDVjc09QRUs3RHpQTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCCkN3VUFBNElCQVFCTU9xTkVyTGxGc2NlVGZzZ0xDa0xmWk9vYzdsbHNDTHFKWDJyS1NwV2VlbzhIeGRwRmNvSnhEanJTekcrbnRLRWoKdS9Za244c1gvb3ltenNMUzI4eU4vSEg4QXluQmJGMHpYMlMyWlR1SmJ4aDJlUFhjb2tnZkdUK09rK3Z4K2hmdXpVN2pCQkpWMXVYawozZnMrQlh6aUhWN0dwN3lYVDJnNjlla3VDa08ycjFkY1ltaDh0LzJqaW9TZ3JHSytLd21ITlBCcUFidWJLVlk4L2dBM3p5TnM4VTZxCnRuUkdFbXlSN2pUVjdKcVI1MFMra0RGeTFVa0M5Z0xsOUIvcmZObVdWYW4vN0lyNW1VZi9OVm9DcWdUTGlsdUhjU21SdmFTMGVnMjkKbXZWWEl3QUhJUmMvU2puUkJVa0xwN1kzZ2FWZGpLb3pYb0VvZktkOUorc0FybzAzCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkVDLUFDQwo9PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZWakNDQkQ2Z0F3SUJBZ0lRN2lzOTY5UWgzaFNvWXF3RTg5M0VBVEFOQmdrcWhraUc5dzBCQVFVRkFEQ0I4ekVMTUFrR0ExVUUKQmhNQ1JWTXhPekE1QmdOVkJBb1RNa0ZuWlc1amFXRWdRMkYwWVd4aGJtRWdaR1VnUTJWeWRHbG1hV05oWTJsdklDaE9TVVlnVVMwdwpPREF4TVRjMkxVa3BNU2d3SmdZRFZRUUxFeDlUWlhKMlpXbHpJRkIxWW14cFkzTWdaR1VnUTJWeWRHbG1hV05oWTJsdk1UVXdNd1lEClZRUUxFeXhXWldkbGRTQm9kSFJ3Y3pvdkwzZDNkeTVqWVhSalpYSjBMbTVsZEM5MlpYSmhjbkpsYkNBb1l5a3dNekUxTURNR0ExVUUKQ3hNc1NtVnlZWEp4ZFdsaElFVnVkR2wwWVhSeklHUmxJRU5sY25ScFptbGpZV05wYnlCRFlYUmhiR0Z1WlhNeER6QU5CZ05WQkFNVApCa1ZETFVGRFF6QWVGdzB3TXpBeE1EY3lNekF3TURCYUZ3MHpNVEF4TURjeU1qVTVOVGxhTUlIek1Rc3dDUVlEVlFRR0V3SkZVekU3Ck1Ea0dBMVVFQ2hNeVFXZGxibU5wWVNCRFlYUmhiR0Z1WVNCa1pTQkRaWEowYVdacFkyRmphVzhnS0U1SlJpQlJMVEE0TURFeE56WXQKU1NreEtEQW1CZ05WQkFzVEgxTmxjblpsYVhNZ1VIVmliR2xqY3lCa1pTQkRaWEowYVdacFkyRmphVzh4TlRBekJnTlZCQXNUTEZabApaMlYxSUdoMGRIQnpPaTh2ZDNkM0xtTmhkR05sY25RdWJtVjBMM1psY21GeWNtVnNJQ2hqS1RBek1UVXdNd1lEVlFRTEV5eEtaWEpoCmNuRjFhV0VnUlc1MGFYUmhkSE1nWkdVZ1EyVnlkR2xtYVdOaFkybHZJRU5oZEdGc1lXNWxjekVQTUEwR0ExVUVBeE1HUlVNdFFVTkQKTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFzeUxIVCtLWFFwV0lSNE5BOWgwWDg0TnpKQjVSODVpSwp3NUs0LzBDUUJYQ0hZTWtBcWJXVVpSa2lGUmZDUTJ4bVJKb05CRDQ1YjZWTGVxcGp0NHBFbmRsamtZUm00Q2dQdWtMamJvNzNGQ2VUCmFlNlJEcU5mRHJIclpxSnlUeElUaG1WNlB0dFBCL1NuQ1dEYU9rS1p4N0ovc3hhVkhNZjVOTFdVaGRXWlhxQklvSDduRjJXNG9uVzQKSHZQbFFuMnY3Zk9LU0dSZGdoU1QyTURrLzdOUWN2SjI5ck5kUWxCNTBKUSthd3dBdnRockRrNHE3RDdTeklLaUdHVXpFM2VlbWwwYQpFOWpEMnozSWwzcnVjTzJuNW56YmNjOHRsR0xmYmRiMU9MNC9wWVVLR2JpbzJBbDFRbkRFNnUvTERzZzBxQklpbUF5NEU1UzJTK3p3CjBKRG5Kd0lEQVFBQm80SGpNSUhnTUIwR0ExVWRFUVFXTUJTQkVtVmpYMkZqWTBCallYUmpaWEowTG01bGREQVBCZ05WSFJNQkFmOEUKQlRBREFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVVvTU9MUktvM3BVVy9sNEJhMGZGNG9wdnBYWTB3ZndZRApWUjBnQkhnd2RqQjBCZ3NyQmdFRUFmVjRBUU1CQ2pCbE1Dd0dDQ3NHQVFVRkJ3SUJGaUJvZEhSd2N6b3ZMM2QzZHk1allYUmpaWEowCkxtNWxkQzkyWlhKaGNuSmxiREExQmdnckJnRUZCUWNDQWpBcEdpZFdaV2RsZFNCb2RIUndjem92TDNkM2R5NWpZWFJqWlhKMExtNWwKZEM5MlpYSmhjbkpsYkNBd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFLQklXNElCOWsxSXVEbFZOWnlBZWxPWjFWci9zWEU3ekRrSgpsRjdXMnUrK0FWdGQweDdZL1gxUHphQkI0RFNUdjh2aWhwdzNrcEJXSE56cktRWGx4SjdITmQrS0RNM0ZJVVBwcW9qbE5jQVpRbU5hCkFsNmtTQmc2aFcvY25idy9uWnpCaDdoNllRanBkd3QvY0t0NjNkbVhMR1FlaGIrOGRKYWh3M29TN0F3YWJvTU1QT2h5UnAvN1NOVmUKbCtheG9mams3MFlsbEp5SjIyazR2dXhjRGxiSFpWSGxVSWlJdjBMVkt6M2wrYnFlTHJQSzlIT1NBZ3UrVEdicklQNjV5N1daZithMgpFL3JLUzAzWjdsTkdCanZHVHEyVFdvRitiQ3BMYWdWRmpQSWhwREdRaDJ4bG5KMmxZSlU2VW4vMTBhc0lidlB1Vy9tSVBYNjRiMjRECjVFST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFTVRDQ0F4bWdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURDQmxURUxNQWtHQTFVRUJoTUNSMUl4UkRCQ0JnTlZCQW9UCk8waGxiR3hsYm1saklFRmpZV1JsYldsaklHRnVaQ0JTWlhObFlYSmphQ0JKYm5OMGFYUjFkR2x2Ym5NZ1EyVnlkQzRnUVhWMGFHOXkKYVhSNU1VQXdQZ1lEVlFRREV6ZElaV3hzWlc1cFl5QkJZMkZrWlcxcFl5QmhibVFnVW1WelpXRnlZMmdnU1c1emRHbDBkWFJwYjI1egpJRkp2YjNSRFFTQXlNREV4TUI0WERURXhNVEl3TmpFek5EazFNbG9YRFRNeE1USXdNVEV6TkRrMU1sb3dnWlV4Q3pBSkJnTlZCQVlUCkFrZFNNVVF3UWdZRFZRUUtFenRJWld4c1pXNXBZeUJCWTJGa1pXMXBZeUJoYm1RZ1VtVnpaV0Z5WTJnZ1NXNXpkR2wwZFhScGIyNXoKSUVObGNuUXVJRUYxZEdodmNtbDBlVEZBTUQ0R0ExVUVBeE0zU0dWc2JHVnVhV01nUVdOaFpHVnRhV01nWVc1a0lGSmxjMlZoY21ObwpJRWx1YzNScGRIVjBhVzl1Y3lCU2IyOTBRMEVnTWpBeE1UQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFLbFRBT011cHZhTyttRFlMWlUrK0N3cVZFN051WVJobEZoUGp6Mkw1RVB6ZFltTlVlVEROOUtLaUUxNUhyY1MzVU40U29xUzV0ZEkKMVEra09pbEVOYmdIOW1nZFZjMDRVZkNNSkRHRnI0UEpmZWwzciswYWU1MFgrYk9kT0ZBUHBscDVrWUN2TjY2bTB6SDd0U1lKblR4YQo3MUhGSzkrV1hlc3lIZ0xhY0Vuc2JnekltamVOOS9FMllFc21MSUtlMEhqekRROWpwRkV3NGZrckp4SUgyT3E5R0dLWXNGazNmYjd1Cjh5QlJRbHFENzVPNmFSWHhZcDJmbVRtQ29iZDBMb3ZVeFF0N0wvRElDdG85ZVFxYWt4eWxLSEp6a1VPYXA5Rk5oWVM1cVhTUEZFREgKM042c1FXUnN0Qm1iQW1OdEpHU1BSTElsNnM1ZGRBeGpNbHlOaCtVQ0F3RUFBYU9CaVRDQmhqQVBCZ05WSFJNQkFmOEVCVEFEQVFILwpNQXNHQTFVZER3UUVBd0lCQmpBZEJnTlZIUTRFRmdRVXBwRkMvUk5oU2lPZUNLUXA1ZGdUQkNQdVFTVXdSd1lEVlIwZUJFQXdQcUE4Ck1BV0NBeTVuY2pBRmdnTXVaWFV3Qm9JRUxtVmtkVEFHZ2dRdWIzSm5NQVdCQXk1bmNqQUZnUU11WlhVd0JvRUVMbVZrZFRBR2dRUXUKYjNKbk1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQWY3M2xCNFh0dVA3S01oamRDU2s0Y054Nk5acm9rZ2NsUEVnOGh3QU9YaGlWdApYZE1pS2Foc29nMnA2ejBHVzVrNng4ekRtalIvcXc3SVRoemgrdVRjelEyK3Z5VCtiT2Ryd2czSUJwNU9qV0VvcG1yOTVmWmk2aGc4ClRxQlRuYkk2bk91bG5KRVd0azJDNEF3RlNLbHM5Y3o0eTUxSnRQQUNwZjF3QSsyS0lhV3VFNFpKd3pOenZvYzdkSXNYUlNaTUZwR0QKL21kOXpVMWpaL3J6QXhLV2VBYU5zV2Z0amorK24wOEM5Yk1KTC9OTWg5OHF5NVY4QWN5c05ucS9vbk42OTQvQnRacWhGTEtQTTU4Tgo3eUxjWm51RXZVVVhCajA4eXJsM05JL0s2czgvTVQ3amlPT0FTU1hJbDdXZG1wbE5zRHo0U2dDYlpOMmZPVXZSSjllNAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBY3RhbGlzIEF1dGhlbnRpY2F0aW9uIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGdXpDQ0E2T2dBd0lCQWdJSVZ3b1JsMExFNDh3d0RRWUpLb1pJaHZjTkFRRUxCUUF3YXpFTE1Ba0dBMVVFQmhNQ1NWUXhEakFNCkJnTlZCQWNNQlUxcGJHRnVNU013SVFZRFZRUUtEQnBCWTNSaGJHbHpJRk11Y0M1QkxpOHdNek0xT0RVeU1EazJOekVuTUNVR0ExVUUKQXd3ZVFXTjBZV3hwY3lCQmRYUm9aVzUwYVdOaGRHbHZiaUJTYjI5MElFTkJNQjRYRFRFeE1Ea3lNakV4TWpJd01sb1hEVE13TURreQpNakV4TWpJd01sb3dhekVMTUFrR0ExVUVCaE1DU1ZReERqQU1CZ05WQkFjTUJVMXBiR0Z1TVNNd0lRWURWUVFLREJwQlkzUmhiR2x6CklGTXVjQzVCTGk4d016TTFPRFV5TURrMk56RW5NQ1VHQTFVRUF3d2VRV04wWVd4cGN5QkJkWFJvWlc1MGFXTmhkR2x2YmlCU2IyOTAKSUVOQk1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBcDhiRXBTbWtMTy9sR01Xd1VLTnZVVHVmQ2xySgp3a2c0Q3NJY29CaC9rYldIdVVBLzNSMW9Id2lEMVMwZWlLRDRqMWFQYlprQ2twQVcxVjhJYkluWDRheThJTUt4NElOUmltbE5BSlphCmJ5L0FSSDZqRHVTUnpWanUzUHZISGtWSDNTZTVDQUdmcGlFZDlVRXRMMHo5S0szZ2lxMGl0Rlpsam9aVWo1TkRLZDQ1Um5pak1DTzYKemZCOUUxZkFYZEtEYTBoTXhLdWZnRnBiT3IzSnB5SS9nQ2N6V3c2M2lneGRCemNJeTJ6U2VrY2lSRFhGek13dWp0MHE3YmQ5WmcxZgpZVkVpVlJ2alJ1UGpQZEExWXByYnJ4VElXNkhNaVJ2aE1DYjhvSnNmZ2FkSEh3VHJvem1TQnArWjA3L1Q2azlRbkJuK2xvY2VQR1gyCm94Z2tnNFlRNTFRK3FEcDJKRStCSWNYakR3TDRrNVJISUx2KzFBN1RhTG5keEhxRWd1TlRWSG5kMjV6UzhnZWJMcmE4UHUyRmJlOGwKRWZLWEdrSmg5MHFYNkl1eEVBZjZaWUd5b2puUDl6ei9HUHZHOFZxTFdlSUNySHVTMEU0VVQxbEY5Z3hlS0YrdzZEOUZ6OCt2bTIvNwpoTk4zV3BWdnJKU0VudTY4d0VxUFNwUDRSQ0hpTVVWaFVFNFEyT00xZkV3WnRONEZ2Nk1HbjhpMXplUWYxeGNHRFhxVmRGVU5hQnI4CkVCdGlaSjF0NEpXZ3c1UUhWdzBVNXIwRis3aWY1dCtMNHNibmZwYjJVOFdBTkZBb1dQQVNVSEVYTUxybWVHTzg5TEt0bXl1eS91RTUKakY2NkN5Q1UzbnVEdVAvalZvMjNFZWs3alBLeHdWMmRwQXRNSzlteUdQVzFuMHNDQXdFQUFhTmpNR0V3SFFZRFZSME9CQllFRkZMWQppRHJJbjNobTdZbnplemh3bE1rQ0FqYlFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdId1lEVlIwakJCZ3dGb0FVVXRpSU9zaWZlR2J0CmlmTjdPSENVeVFJQ050QXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQUxlM0tId0dDbVNVeUkKV09ZZGlQY1VaRWltMkZnS0RrOFROZDgxSGRUdEJqSElnVDVxMWQwN0dqTHVrRDBSMGk3MGpzTmpMaU5tc0dlK2I3YkFFemxncXFJMApKWk4xVXQ2bm5hME9oNGxTY1dvV1BCa2RnL2lhS1dXKzlEK2EyZkR6V29jaGNZQk55K0E0bXorNyt1QXdUYytHMDJVUUdSalJsd0t4CkszSkNhS3lndlU1YTJoaS9hNWlCMFAyYXZsNFZTTTBSRmJuQUtWeTA2SWozUGphdXQyTDlIbUxlY0hnUUhFaGIycnlrT0xwbjdWVSsKWGxmZjFBTkFUSUdrMGs5anB3bENDUlQ4QUtuQ2dITlBMc0JBMlJGN1NPcDZBc0RUNnlnQkpsaDB3Y0J6SW0yVGxmMDVmYnNxNC9hQwo0eXlYWDA0ZmtaVDYvaXlqMkhZYXVFMnlPRStiK2gxSVlIa200dlA5cWRDYTZIQ1BTWHJXNWIwS0R0c3Q4NDIvNitPa2ZjdkhsWEhvCjJxTjh4Y0w0ZEpJRUc0YXNwQ0pUUUxhcy9reDJ6L3VVTXNBMW4zWS9idVdRYnFDbUpxSzRMTDdSSzRYOXAyakl1Z0Vyc1d4MEhiaHoKbGVmdXQ4Y2w4QUJNQUxKK3RndUxIUFBBVUo0bHVlQUkzalptL3plbDBidFVaQ3pKSjdWTGtuNWwvOU10NGJsT3ZIK2tRU0dRUVhlbQpPUi9xbnVPZjBHWnZCZXlxZG42L2F4YWc2N1hIL0pKVUx5c1JKeVUzZUV4UmFyRHp6RmhkRlBGcVNCWC93Z2Uyc1kwUGpseFFSck05CnZ3R1lUN0paVkVjK05IdDRiVmFUTG5QcVppaDR6UjBVdjZDUEx5NjRMbzd5RklyTTZiVjgrMnlkREtYaGxnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3RpcyBGUFMgUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEWnpDQ0FrK2dBd0lCQWdJUUd4K3R0aUQ1Sk5NMmEvZkg4WXlnV1RBTkJna3Foa2lHOXcwQkFRVUZBREJGTVFzd0NRWURWUVFHCkV3SkhRakVZTUJZR0ExVUVDaE1QVkhKMWMzUnBjeUJNYVcxcGRHVmtNUnd3R2dZRFZRUUxFeE5VY25WemRHbHpJRVpRVXlCU2IyOTAKSUVOQk1CNFhEVEF6TVRJeU16RXlNVFF3TmxvWERUSTBNREV5TVRFeE16WTFORm93UlRFTE1Ba0dBMVVFQmhNQ1IwSXhHREFXQmdOVgpCQW9URDFSeWRYTjBhWE1nVEdsdGFYUmxaREVjTUJvR0ExVUVDeE1UVkhKMWMzUnBjeUJHVUZNZ1VtOXZkQ0JEUVRDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1WUWU1NDdOZERmeEl6TmpwdnRvOEEybWZSQzZxYytnSU1QcHFkWmg4bVEKUlVOK0FPcUdlU29EdlQwM21ZbG10K1dLVm9hVG5HaExhQVNNazVNQ1BqRFNOem9pWVlrY2hVNTlqOVd2ZXpYMmZpaEhpVEhjRG5sawpINW5TVzdyK2YyQy9yZXZuUERncGFpL2xrUXRWLyt4dldOVXR5ZDVNWm5HUEROY0UyZ2ZtSGhqanZTa0NxUG9jNFZ1NWc2aEJTTHdhCmNZM25ZdVV0c3V2ZmZNL2JxMXJLTWZGTUl2TUZFL2VDK1hONURMN1hTeHpBMFJVOGswRmswZWErSXhjaUFJbGVIMnVsckc2blM0enQKbzNMbXIyTk5MNFhTRkRXYUxrNk02aktZS0lhaGtRbEJPclRoNC9MNjhNa0tva0hkcWVNRHg0Z1ZPeHpVR3BUWG4yUlpFbTBDQXdFQQpBYU5UTUZFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZkJnTlZIU01FR0RBV2dCUzYrbkVsZVl0WFFTVWhoZ3R4NjdKa0Rvc2haekFkCkJnTlZIUTRFRmdRVXV2cHhKWG1MVjBFbElZWUxjZXV5WkE2TElXY3dEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBSDVZLy8wMUdYMmMKR0UrZXNDdThqb3dVL3l5ZzJrZGJ3KytCTGE4RjZuUklXL00rVGdmSGJjV3prODhpTlZ5MlAzVW5Yd21XemFEK3ZrQU1YQkpWK0pPQwp5aW5wWGo5V1Y0czROdmRGR2t3b3paNUJ1TzFXVElTa1FNaTRzS1VyYVhBRWFzUDQxQkl5K1E3RHNkd3loRVFzYjh0R0QrcG1RUTlQCjhWaWxwZzBORDJIZXBaNWRmV1doUEJmbnFGVk83NkRIN2NaRWYxVDFvK0NQOEh4VklvOHB0b0dqNFcxT0xCdUFaK3l0SUo4TVltSFYKbC85RDdTM0IybDBwS29VL3JHWHVoZzhGalpCZjMrNmY5TC91SGZ1WTVIK1FLNFI0RUE1c1NWUHZGVnRsUmtwZHI3cjdPbklkemZZbAppQjZYekNHY0tRRU5aZXRYMmZOWGxydEl6WUU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkJ1eXBhc3MgQ2xhc3MgMiBSb290IENBCj09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGV1RDQ0EwR2dBd0lCQWdJQkFqQU5CZ2txaGtpRzl3MEJBUXNGQURCT01Rc3dDUVlEVlFRR0V3Sk9UekVkTUJzR0ExVUVDZ3dVClFuVjVjR0Z6Y3lCQlV5MDVPRE14TmpNek1qY3hJREFlQmdOVkJBTU1GMEoxZVhCaGMzTWdRMnhoYzNNZ01pQlNiMjkwSUVOQk1CNFgKRFRFd01UQXlOakE0TXpnd00xb1hEVFF3TVRBeU5qQTRNemd3TTFvd1RqRUxNQWtHQTFVRUJoTUNUazh4SFRBYkJnTlZCQW9NRkVKMQplWEJoYzNNZ1FWTXRPVGd6TVRZek16STNNU0F3SGdZRFZRUUREQmRDZFhsd1lYTnpJRU5zWVhOeklESWdVbTl2ZENCRFFUQ0NBaUl3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFOZkhYdmZCQjlSMyswTWg5UFQxYWVUdU1nSGJvNFlmNUZrTnV1ZDEKZzFMcjZoeGhGVWk3SFFmS2pLNnczSmFkNnNOZ2tvYUNLSE9jVmdiL1MyVHdEQ28zU2JYbHp3eDg3dkZLdTNNd1pmUFZMNE8yZnVQbgo5WjZyWVBuVDhaMlNkSXJrSEphc1c0RHB0ZlF4aDZOUi9NZCtvVytPVTNmVWw4RlZNNUkrR0M5MTFLMkdTY3VWcjFRR2JOZ0dFNDFiCi8rRW1HVm5BSkxxQmNYbVFSRkJvSkpSZnVMTVI4U2xCWWFOQnl5TTIxY0h4TWxBUVRuLzBocFBzaE5PT3ZFdS9YQUZPQnozY0ZJcVUKQ3FUcWMvc0xVZWdUQnhqNkR2RXIwVlFWZlR6aDk3UVpRbWRpWG5mZ29sWHN0dGxwRjlVNnIwVHRTc1dlNUhvbmZPVjExNnJMSmVmZgphd3JiRDAyVFRxaWd6WHN1OGxrQmFyY051QWVCZm9zNEd6am1DbGVaUGU0aDZLUDFEQmJkaSt3MGpwd3FIQUFWRjQxb2c5SndueGdJCnpSRm8xY2xyVXMzRVJvL2N0ZlBZVjNNZTZaUTVCTC9UM2pqZXRGUHNhUnlpZnNTUDVCdHdyZktpK2Z2M0ZtUm1hWjlKVWFMaUZSaG4KQmtwLzFXeTFUYk16NEdIclhiN3BtQTh5MXgxTFBDNWFBVktSQ2ZMZjZvM1lCa0JqcWhIay9zTTNuaFJTUC9UaXpQSmhrOUg5WjJ2WApVcTYvYUt0QVE2QlhOVk40OEZQNFlVSUhaTWJYYjV0TU9BMWpyR0t2Tm91aWN3b045U0c5ZEtwTjZuSURTZHZIWHgxaVk4ZjkzWkhzCk0rNzFiYlJ1TUdqZXlOWW1zSFZlZTdRSElKaWhkaks0VFd4UEFnTUJBQUdqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWUQKVlIwT0JCWUVGTW1BZCtCaWtvTDFScHp6dXZkTXc5NjRvNjA1TUE0R0ExVWREd0VCL3dRRUF3SUJCakFOQmdrcWhraUc5dzBCQVFzRgpBQU9DQWdFQVUxOGg5YnF3T2xJNUxKS3diQURKNzg0Zzd3YnlscDdwcEhSL2VoYjh0L1cyK3hVYlA2dW13SEpkRUxGeDdyeFA0NjJzCkEyMHVjUzZ2eE9PdG83ME1FYWUwLzBxeWV4QVFINmRYUWJMQXJ2UXNXZFpIRUlqeklWRXBNTXBnaHE5R3F4M3RPbHV3bE41RTQwRUkKb3NIc0hkYjlUN2JXUjlBVUM4cm15clY3ZDM1QkgxNkR4N2FNT1phd1A1YUJRVzlna09Mbytmc2ljZGw5c3oxR3Y3U0VyNUFjRDQ4UwphcS92N2g1NnJnSktpaGNyZHY2c1ZJa2tMRTgvdHJLblRveW9rWmY3S2NaN1hDMjV5MmEydDZoYkVsR0Z0UWwrWW5ody9xbHFZTFlkCkRua00vY3JxSklCeXc1Yy84bmVyUXlJS3grdTJESVNDTElCclFZb0l3T3VsYTkrWkVzdUsxVjZBREpIZ0pnZzJTTVg2T0JFMS95V0QKTGZKNnY5cjlqdjZseTBVc0g4U0lVNjUzRHRtYWRzV09MQjJqdXRYc01xN0FxcXozMFhwTjY5UUg0a2ozSW82d3BKOXF6bzZ5c21EMApveUxRSSt1VVducHAzUSsvUUZlc2ExbFEyYU9aNFc3K2pRRjVKeU1WM3BLZGV3bE5XdWRMU0RCYUdPWUtiZWFQNE5LNzV0OThiaUdDCndXZzVUYlNZV0daaXpFcVFYc1A2SndTeGVSVjBtY3krclNEZUptQWM2MVpScHFQcTVLTS9wLzloM1BGYVRXd3lJMFB1cktqdTdrb1MKQ1R4ZGNjSytlZnJDaDJnZEMvMWNhY3dHMEpwOVZKa3F5VGthR2E5TEtrUHpZMTFhV09JdjR4M2txZGJRQ3RDZXY5ZUJDZkhKeHlZTgpySmdXVnFBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpCdXlwYXNzIENsYXNzIDMgUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRldUQ0NBMEdnQXdJQkFnSUJBakFOQmdrcWhraUc5dzBCQVFzRkFEQk9NUXN3Q1FZRFZRUUdFd0pPVHpFZE1Cc0dBMVVFQ2d3VQpRblY1Y0dGemN5QkJVeTA1T0RNeE5qTXpNamN4SURBZUJnTlZCQU1NRjBKMWVYQmhjM01nUTJ4aGMzTWdNeUJTYjI5MElFTkJNQjRYCkRURXdNVEF5TmpBNE1qZzFPRm9YRFRRd01UQXlOakE0TWpnMU9Gb3dUakVMTUFrR0ExVUVCaE1DVGs4eEhUQWJCZ05WQkFvTUZFSjEKZVhCaGMzTWdRVk10T1Rnek1UWXpNekkzTVNBd0hnWURWUVFEREJkQ2RYbHdZWE56SUVOc1lYTnpJRE1nVW05dmRDQkRRVENDQWlJdwpEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBS1hhQ3BVV1VPT1Y4bDZkZGpFR01ucWI4UkIydUFDYXRWSTJ6U1JICnNKOFlaTHlhOXZyVmVkaVFZa3dpTDk0NFBkYmdxT2tjTE50NEVlbU9hRkVWY3Nmek00ZmtvRjBMWE9CWEJ5b3c5YzNFTjNjb1RSaVIKNXIvVlV2MXhMWEErNThiRWl1UHdLQXYwZHBpaGk0ZFZzam9UL0xjK0p6ZU9JdU9vVHlydllMczl0em5ERGdGSG1WMFNUOXREK2xlaAo3Zm1kdmhGSEpsc1RtS3RkRm9xd054eFhuVVgvaUpZMnY3dktCM3R2aDJQWDBESnExbDFzRFBHemJqbmlhekV1T1FBbkZONDR3T3daClpvWVM2SjF5RmhOa1VzZXBOeHo5Z2pEdGhCZ2Q5SzVjLzNBVEFPdXg5VE42UzlaVitBV05TMm13OWJNb05sd1V4RkZ6VFdzTDhUUUgKMnhjNTE5d29lMnYxbi9NdXdVOFhLaER6ek1ybzYvMXJxeTZhbnkyQ2JnVFVVZ0dUTFQyRy9INzgzKzlDSGFacjc3a2d4dmU5b0tlVgovYWZtaVNUWXpJdzBiT0lqTDlrU0dpRzVWWkZ2QzVGNUdReXRRSWdMY09KNjBnN1lhRWk3Z2hNNUVGanAyQ29IeGhMYldOdlNPMVVRClJ3VVZaMkorR0dPbVJqOEpEbFF5WHI4Tllub243NERvMjlsTEJsbzNXaVhRQ0JKMzFHOEpVSmM5eUIzRDM0eEZNRmJHMDJTclp2UEEKWHBhY3c4VHZ3M3hyaXpwNWY3Tkp6ejNpaVorZ01FdUZ1WnlVSkhtUGZXdXBSV2dQSzlEeDJoekxhYmpLU1dKdHlOQmpZdDFnRDFpcQpqNkc4QmFWbW9zOGJkcktFWkxGTU9WTEFNTHJ3akVzQ3NMYTNBZ01CQUFHalFqQkFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEClZSME9CQllFRkVlNHpmL2xiKzc0c3V3dlRnNzVKYkNPUEd2RE1BNEdBMVVkRHdFQi93UUVBd0lCQmpBTkJna3Foa2lHOXcwQkFRc0YKQUFPQ0FnRUFBQ0FqUVRVRWtNSkFZbUR2NGpWTTF6K3M0alNRdUtGdmR2b1dGcVJJTnl6cGtNTHlQUGdLbjlpQjVidGIyaVVzcEtkVgpjU1F5OXNnTDhyeHErSk9zc2dmQ1g1L2J6TWlLcXI1cWIrRkpFTXd4MTRDN3U4allvZzVrVitxaTljS3BNUlhTSUdycy9DSUJLTStHCnVJQWVxY3dScFR6eUZyTkhuZnpTZ0NIRXk5QkhjRUdoeW9NWkNDeHQ4bDEzbklvVUU5UTJISkx3NVFZMzNLYm1rSnM0ajF4ckcwYUcKUTBKZlBnRUhVMVJkWlgzM2luT2htbFJhSHlsREZDZkNoUSsxaUhzYU81UzNIV0NudFp6bktXbFhXcHVUZWtNd0d3UFhZc2hBcHFyOApaT1JLMTVGVEFhZ2dpRzZjWDBTNXkyQ0JOT3h2MDMzYVNGL3J0SkM4TGFrY0M2d2MxYUpvSUlBRTF2eXhqeSs3U2pFTlNvWWM2K0kyCktTYjEydGpFOG5WaHozNnVkbU5LZWtCbGs0ZjRIb0NNaHVXRzFvOE8vRk1zWU9nV1lScWlQa043elRsZ1ZHcjE4b2ttQVdpRFNLSXoKNk1rRWtiSVJOQkUrNnRCREdSOERrNUFNLzFFOVYvUkJidUhMb0w3cnlXUE5iY3prK0RhcWFKM3R2VjJYY0VRTnRnNDEzT0VNWGJ1ZwpVWlRMZmhickVTK2pra1hJVEhIWnZNbVpVbGRHTDFEUHZUVnA5RDBWemdhbExBOCs5b0c2bEx2RHU3OWxlTktHZWY5Sk94cUREUERlCmVPekk4azFNR3Q2Q0tmakJXdHJ0N3VZblh1aEYwSjBjVWFob3EwVGowSXRxNC9nN3U5eE4xMlR5VWI3bXFxdGE2VEh1QnJ4enZ4TmkKQ3AvSHVaYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVC1UZWxlU2VjIEdsb2JhbFJvb3QgQ2xhc3MgMwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEd3pDQ0FxdWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUXNGQURDQmdqRUxNQWtHQTFVRUJoTUNSRVV4S3pBcEJnTlZCQW9NCklsUXRVM2x6ZEdWdGN5QkZiblJsY25CeWFYTmxJRk5sY25acFkyVnpJRWR0WWtneEh6QWRCZ05WQkFzTUZsUXRVM2x6ZEdWdGN5QlUKY25WemRDQkRaVzUwWlhJeEpUQWpCZ05WQkFNTUhGUXRWR1ZzWlZObFl5QkhiRzlpWVd4U2IyOTBJRU5zWVhOeklETXdIaGNOTURneApNREF4TVRBeU9UVTJXaGNOTXpNeE1EQXhNak0xT1RVNVdqQ0JnakVMTUFrR0ExVUVCaE1DUkVVeEt6QXBCZ05WQkFvTUlsUXRVM2x6CmRHVnRjeUJGYm5SbGNuQnlhWE5sSUZObGNuWnBZMlZ6SUVkdFlrZ3hIekFkQmdOVkJBc01GbFF0VTNsemRHVnRjeUJVY25WemRDQkQKWlc1MFpYSXhKVEFqQmdOVkJBTU1IRlF0VkdWc1pWTmxZeUJIYkc5aVlXeFNiMjkwSUVOc1lYTnpJRE13Z2dFaU1BMEdDU3FHU0liMwpEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUM5ZFpQd1lpSnZKSzdnZW5hc2ZiM1pKTlc0dC96TjhFTGc2M2lJVmw2Ym1sUWRUUXlLCjl0UFBjUFJTdGRpVEJPTkdobkZCU2l2d0tpeFZBOVpJdytBNU9PM3lYRHcvUkx5VFBXR3JUczBOdnZBZ0oxZ09SSDhFR29lbDE1WVUKTnBEUVNYdWhkZnNhYTNPeCtNNnBDU3p5VTlYREZFUzRocVgyaXlzNTJxTXpWTm42Y2hyM0loVWNpSkZyZjJibHcycUFzQ1R6MzRaRgppUDBaZjNXSEh4K3hHd3B6SkZ1NVplQXNWTWhnMDJZWFArSE1WRE56a1FJNnBuOTdkam1pSDVhMk9LNjF5Sk4wSFo2NXRPVmduUzlXCjBlRHJYbHRNRW5BTWJFUWdxeEhZOUJuMjBweFNOK2Y2dHNJeE8wclVGSm10eHhyMVhWLzZCN2g4RFIvV2d4NnpBZ01CQUFHalFqQkEKTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlMxQS9kMk8yR0NhaEtxR0ZQcgpBeUdVdi83T3lqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFWajN2bE5XOTJuT3lXTDZ1a0syWUo1ZitBYkd3VWdDNFRlUWJJWFFiCmZzRHVYbWtxSmE5YzFoM2Ewbm5KODVjcDRJYUgzZ1JaRC9GWjFHU0ZTNW12SlFRZXlVYXBsOTZDc2h0d241ejJyM0V4M1hzRnBTelQKdWNwSDlzcnk5dWV0dVVnL3ZCYTN3VzMwNmdtdjdQTzE1d1dlcGg2S1UxSFdrNEhNZEpQMnVkcW1KUVYwZVZwK1FENkNTeVlSTUc3aApQMEhIUndBMTFmWFQ5MVErZ1QzYVNXcWFzKzhRUGVicmI5SElJa2ZMek04Qk1aTFpHT01pdmdrZUdqNWFzdVJyREZSNmZVTk91SW1sCmU5ZWlQWmFHelBJbU5DMXFrcDJhR3RBdzRsMU9CTEJmaXlCK2Q4RTlsWUxSUnBvN1BIaTRiNkhRRFdTaWVCNHBUcFBEcEZRVVd3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRC1UUlVTVCBSb290IENsYXNzIDMgQ0EgMiAyMDA5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRU16Q0NBeHVnQXdJQkFnSURDWVB6TUEwR0NTcUdTSWIzRFFFQkN3VUFNRTB4Q3pBSkJnTlZCQVlUQWtSRk1SVXdFd1lEVlFRSwpEQXhFTFZSeWRYTjBJRWR0WWtneEp6QWxCZ05WQkFNTUhrUXRWRkpWVTFRZ1VtOXZkQ0JEYkdGemN5QXpJRU5CSURJZ01qQXdPVEFlCkZ3MHdPVEV4TURVd09ETTFOVGhhRncweU9URXhNRFV3T0RNMU5UaGFNRTB4Q3pBSkJnTlZCQVlUQWtSRk1SVXdFd1lEVlFRS0RBeEUKTFZSeWRYTjBJRWR0WWtneEp6QWxCZ05WQkFNTUhrUXRWRkpWVTFRZ1VtOXZkQ0JEYkdGemN5QXpJRU5CSURJZ01qQXdPVENDQVNJdwpEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTk95U3M5NlIrOTFteVA2T2kvV1VFV0pOVHJHYTl2KzJ3Qm9xT0FECkVSMDNVQWlmVFVwb2xEV3pVOUdVWTZjZ1ZxL2VVWGpzS2ozelNFaFFQZ3JmUmxXTEoyM0RFRTBOa1ZKRDJJZmdYVTQydFNIS1h6bEEKQkY5YmZzeWp4aXVwUUI3Wk5vVFdTUE9TSGpSR0lDVEJwRkdPU2hydlVEOXBYUmwvUmNQSEFZOVJ5U1BvY3E2MHZGWUpmeExMSExHdgpLWkFLeVZYTUQ5TzBHdTFITlZwSzdaeHpCQ0hRcXIwTUU3VUF5aVpzeEdzTWxGcVZsTnBRbXZIL3BTdG1NYVRKT0tEZkhSKzRDUzd6CnAraG5VcXVWSCtCR1B0aWt3OHBheFRHQTZFaWFuNVJwL2huZDJITjhnY3FXM283dHN6SUZaWVEwNXViOVZ4QzFYM2EvTDdBUURjVUMKQXdFQUFhT0NBUm93Z2dFV01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZQM2FGTVNmTU40aHZSNUNPZnlyWXlOSgo0UEdFTUE0R0ExVWREd0VCL3dRRUF3SUJCakNCMHdZRFZSMGZCSUhMTUlISU1JR0FvSDZnZklaNmJHUmhjRG92TDJScGNtVmpkRzl5CmVTNWtMWFJ5ZFhOMExtNWxkQzlEVGoxRUxWUlNWVk5VSlRJd1VtOXZkQ1V5TUVOc1lYTnpKVEl3TXlVeU1FTkJKVEl3TWlVeU1ESXcKTURrc1R6MUVMVlJ5ZFhOMEpUSXdSMjFpU0N4RFBVUkZQMk5sY25ScFptbGpZWFJsY21WMmIyTmhkR2x2Ym14cGMzUXdRNkJCb0QrRwpQV2gwZEhBNkx5OTNkM2N1WkMxMGNuVnpkQzV1WlhRdlkzSnNMMlF0ZEhKMWMzUmZjbTl2ZEY5amJHRnpjMTh6WDJOaFh6SmZNakF3Ck9TNWpjbXd3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUgrWDJ6REkzNlNjZlNGNmdIRE9GQkpwaUJTVllFUUJyTExwTUUrYlVNSm0KMkg2Tk1MVndNZW5pYWNmemNOc2dGWWJRRGZDK3JBRjFoTTUrbjAyL3QyQTduUFBLSGVKZWFOaWpuWmZsUUdEU05pSCswTFM0RjlwMApvMy9VMzdDWUFxeHZhMnNzSlNSeW9XWHVKVnJsNWpMbjh0K3JTZnJ6a0drajJ3VFo1MXhZL0dYVWw3N00vQzRLekNVcU5RVDRZSkVWCmRUMUIveU1mR2NoczY0SlRCS2JrVENKTmpZeTZ6bHR6N0dSVVVHM1JuRlg3YWNNMnc0eThQSVdtYXdvbURlQ1RtR0N1ZnNZa2w0cGgKWDVHT1pwSUpoemJOaTVzdFB2WlIxRkRVV1NpOWcvTE1LSHRUaG0zWUpvaHcxK3FSelQ2NXlzQ1FibHJHWG5SbDExeitvK0k9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVRekNDQXl1Z0F3SUJBZ0lEQ1lQME1BMEdDU3FHU0liM0RRRUJDd1VBTUZBeEN6QUpCZ05WQkFZVEFrUkZNUlV3RXdZRFZRUUsKREF4RUxWUnlkWE4wSUVkdFlrZ3hLakFvQmdOVkJBTU1JVVF0VkZKVlUxUWdVbTl2ZENCRGJHRnpjeUF6SUVOQklESWdSVllnTWpBdwpPVEFlRncwd09URXhNRFV3T0RVd05EWmFGdzB5T1RFeE1EVXdPRFV3TkRaYU1GQXhDekFKQmdOVkJBWVRBa1JGTVJVd0V3WURWUVFLCkRBeEVMVlJ5ZFhOMElFZHRZa2d4S2pBb0JnTlZCQU1NSVVRdFZGSlZVMVFnVW05dmRDQkRiR0Z6Y3lBeklFTkJJRElnUlZZZ01qQXcKT1RDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSm54aERSd3VpKzNNS0NPdlh3RXo3NWl2Sm45Z3BmUwplZ3BubGpnSjloQk9sU0p6bVkzYUZTM25CZndaY3lLM2pwZ0F2RHc5cktGcys5WjVKVXV0OE14azJvZytLYmdQQ2RNMDNUUDFZdEhoCnpSbnA3aGhQVEZpdTRoN1dERnNWV3RnNnVNUVlaQjdqTTdLMWlYZE9ETC9abEdzVGwyOFNvLzZacVFUTUZleGdhRGJ0Q0h1MzliK1QKN1dZeGc0ekdjVFNIVGhmcXI0dVJqUnhXUWE0aU4xNDM4aDNaMFMwTkwybFJwNzVtcG9vNktyM0hHckhoRlBDK09oMjV6MXV4YXY2MApzVVlnb3ZzZU8zRHZrNWg5akhPVzhzWHZoWEN0S1NiOEhnUStIS0RZRDh0U2cySjg3b3RUbFpDcFY2THFZUVhZK1UzRUovcHVyZTM1CjExSDNhNlVDQXdFQUFhT0NBU1F3Z2dFZ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZOT1Vpa3hpRXlvWkxzeXYKY29wOU50ZWFITnhuTUE0R0ExVWREd0VCL3dRRUF3SUJCakNCM1FZRFZSMGZCSUhWTUlIU01JR0hvSUdFb0lHQmhuOXNaR0Z3T2k4dgpaR2x5WldOMGIzSjVMbVF0ZEhKMWMzUXVibVYwTDBOT1BVUXRWRkpWVTFRbE1qQlNiMjkwSlRJd1EyeGhjM01sTWpBekpUSXdRMEVsCk1qQXlKVEl3UlZZbE1qQXlNREE1TEU4OVJDMVVjblZ6ZENVeU1FZHRZa2dzUXoxRVJUOWpaWEowYVdacFkyRjBaWEpsZG05allYUnAKYjI1c2FYTjBNRWFnUktCQ2hrQm9kSFJ3T2k4dmQzZDNMbVF0ZEhKMWMzUXVibVYwTDJOeWJDOWtMWFJ5ZFhOMFgzSnZiM1JmWTJ4aApjM05mTTE5allWOHlYMlYyWHpJd01Ea3VZM0pzTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBMDdYdGFQS1NVaU84YUVYVUhMN1ArClBQb2VVU2JyaC9ZcDN1RHgxTVlrQ2VuQnoxVWJ0RERaemhyK0JsR21GYVF0NzdKTHZ5QW9KVW5ScGpaM05PaGszMUt4RWNkemVzMDUKbnNLdGpIRWg4bHBycjk4OFRsV3Zzb1JsRkltNWQ4c3FNYjdQbzIzUGIwaVVNa1p2NTNHTW9LYUVHVGNIOGdORkNTdUdkWHpmWDJsWApBTnR1MktaeUlrdFExSFdZVnQrM0dQOURRMUN1ZWtSNzhIbFIxME05cDlPQjAvREpUN25heHBlRzBJTEQ1RUp0L3JEaVpFNE9KdWRBCk5DYTFDSW5YQ0dOak9DZDFIalBxYnFqZG41bFBkRTJCaVlCTDNacVhLVnd2dm9GQnVZei82bjFnQnA3TjF6M1RMcU1WdktqbUp1VnYKdzl5NEF5SHFueGJ4TEZTMQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDQSBEaXNpZyBSb290IFIyCj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZhVENDQTFHZ0F3SUJBZ0lKQUpLNGlOdXdpc0ZqTUEwR0NTcUdTSWIzRFFFQkN3VUFNRkl4Q3pBSkJnTlZCQVlUQWxOTE1STXcKRVFZRFZRUUhFd3BDY21GMGFYTnNZWFpoTVJNd0VRWURWUVFLRXdwRWFYTnBaeUJoTG5NdU1Sa3dGd1lEVlFRREV4QkRRU0JFYVhOcApaeUJTYjI5MElGSXlNQjRYRFRFeU1EY3hPVEE1TVRVek1Gb1hEVFF5TURjeE9UQTVNVFV6TUZvd1VqRUxNQWtHQTFVRUJoTUNVMHN4CkV6QVJCZ05WQkFjVENrSnlZWFJwYzJ4aGRtRXhFekFSQmdOVkJBb1RDa1JwYzJsbklHRXVjeTR4R1RBWEJnTlZCQU1URUVOQklFUnAKYzJsbklGSnZiM1FnVWpJd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUNpbzhRQUNkYUZYUzF0RlBiQwp3M09lTmNKeFZYNkIrNnRHVU9EQmZFbDQ1cXQ1V0R6YS8zd2NuOWlYQW5nK2EwRUU2VUc5dmdNc1JmWXZaTlNyWGFOSFBXU2I2V2lhCnhzd2JQN3Erc29zMEFpNllWUm44akcrcVg5cE16azBESWFQWTBqU1RWcGJMVEF3QUZqeGZHczNJeDJ5bXJkTXhwN3pvNWVGbTF0TDcKQTdSQlpja1FyZzRGWThhQWFta3cvZEx1a084Tko5K2ZsWFAwNFNYYWJCYmVRVGcwNm92ODBlZ0VGR0V0UVg2c3gzZE95MUZVKzE2UwpHQnNFV21qR3ljVDZ0eE9nbUxjUks3ZldWOHg4bmhmUnl5WCtoazRrTGxZTWVFMmVBUkttSzZjQlpXNThZaDJFaE4vcXdHdTFwU3FWCmc4TlRFUXh6SFF1eVJwRFJRanJPUUc2VnJmL0dsSzF1bDRTT2ZXK2Vpb0FOU1cxejRudVNIc1B6d2ZQckxnVnYyUnZQTjNZRXlMUmEKNUJlbnk5MTJIOUFaZHVnc0JiUFduRFRZbHR4aGg1RUY1RVFJTThIYXVRaGwxSzZ5TmczcnVqaTZET1dibnV1Tlp0Mlp6OWFKUWZZRQprb29wS1cxck9oem5kWDBDY1E3endPZTl5eG5kbldDeXdtWmd0ckVFN3NubWhybWFaa0NvNXhIdGdVVURpL1puV2VqQkJoRzkzYytBCkFrOWxRSGhjUjFESW0rWWZnWHZrUktoYmhacmkzbHJWeC9rNlJHWkw1REpVZk9Sc25MTU9QUmVpc2pRUzFuNnlxRW03MFhvb1FMNmkKRmgvZjVEY2ZFWFA3a0FwbFE2SU5mUGdHQVZVemZiQU51UFQxcnFWQ1YzdzJFWXg3WHNRRG5ZeDVuUUlEQVFBQm8wSXdRREFQQmdOVgpIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJCakFkQmdOVkhRNEVGZ1FVdFpuNHI3Q1U5ZU1nMWdxdHprNVdwQzV1ClF1MHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBQ1lHWG5EblpUUElnbTdabkJjNkczcG1zZ0gyZUR0cFhpL3EvMDc1S01PWUttRk0KdENRU2luMXRFUlQzbkxYSzVyeWVKNDVNR2NpcHZYckExellPYllWeWJxakdvbTMyK25OamY3eHVlUWdjbllxZkdvcFRwdGk3MlRWVgpzUkhGcVFPelZqdTVoSk1pWG43QjloSlNpK29zWjd6K05rejF1TS9SczBtU085TXBEcGtibHZkaHVEdkVLN1o0YkxRamIvRDkwN0plCmRSK1psYWlzOXRyaHhURjcrOUZHczlLOFo3UmlWTG9KOTJPd2s2S2ErZWxTTG90Z0Vxdjg5V0JXN3hCY2k4UWFRdHlEVzJRT3k3VzgKMWsvQmZEeHVqUk50KzN2ck1ORGNUYS9GMWJhbFRGdHh5ZWd4dnVnNEJraWhHdUxxMHQ0U09WZ2EvNEFPZ25YbXQ4a0hiQTd2L3pqeAptSEhFdDM4T0ZkQWxhYjBpblN2dEJmWkdSNnp0d1BEVU8rTHM3cFpia0JOT0hsWTY2N0R2bHJ1V0l4RzY4a09HZEdTVnlDaDEzeDAxCnV0STNnemhUT0RZN3oyenArV3NPMFBzRTZFOTMxMlVCZUlZTWVqNGhZdkYvWTNFTXlaOUUyNmdub25XK2JvRSsxOERyRzVnUGNGdzAKc29yTXdJVVk2MjU2cy9kYW9RZS9xVUtTODJBaWwrUVVvUWViVG5iQWpuMzlwQ1hIUiszL0gzT3N6TU9sNlc4S2pwdGx3bENGdGFPZwpVeExNVllkaDg0R3VFRVpodlVRaHVNSTlkTTkrSkRYNkhBY09tejBpeXU4eEw0eXNFcjN2UUNqOEtXZWZzaE5QWmlURVV4bnBIaWtWCjcrWnRzSDh0Wi8zemJCdDFScVBsU2hmcHBOY0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQUNDVlJBSVoxCj09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJSDB6Q0NCYnVnQXdJQkFnSUlYc08zcGtOL3BPQXdEUVlKS29aSWh2Y05BUUVGQlFBd1FqRVNNQkFHQTFVRUF3d0pRVU5EVmxKQgpTVm94TVJBd0RnWURWUVFMREFkUVMwbEJRME5XTVEwd0N3WURWUVFLREFSQlEwTldNUXN3Q1FZRFZRUUdFd0pGVXpBZUZ3MHhNVEExCk1EVXdPVE0zTXpkYUZ3MHpNREV5TXpFd09UTTNNemRhTUVJeEVqQVFCZ05WQkFNTUNVRkRRMVpTUVVsYU1URVFNQTRHQTFVRUN3d0gKVUV0SlFVTkRWakVOTUFzR0ExVUVDZ3dFUVVORFZqRUxNQWtHQTFVRUJoTUNSVk13Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQwpEd0F3Z2dJS0FvSUNBUUNicWF1L1lVcVhyeStYWnBwMFg5RFpsdjNQNHVSbTd4OGZSelBDUktQZm10NGZ0VlRkRlh4cE5SRnZ1OGdNCmptb1lIdGlQMlJhOEVFZzJYUEJqczVCYVhDUTMxNlBXeXdseHVmRUJjb1N3ZmR0TmdNMzgwMi9KK05xMkRvTFNSWVdvRzJpb1BlajAKUkd5OW9jTExBNzZNUGhNQWhOOUtTTURqSWdybzZUZW5HRXl4Q1EwalZuOEVUZGtYaEJpbHlOcEFsSFByemc1WFBBT0JPcDBLb1ZkRAphYXhYYlhtUWVPVzF0RHZZdkV5TktLR25vNmU2QWs0bDBTcXU3YTRESXJocklBOHdLRlNWZitEdXpncG1uZEZBTFc0aXI1MGF3UVVaCjBtL0E4cC80ZTdNQ1F2dFFxUjB0a3c4anE4YkJENUwvMEtJVjlWTUpjUnovUlJPRTVpWmUrT0NJSEFyOEZyYW9jd2E0OEdPRUFxREcKV3V6bmROOXdycU9ESmVyV3g1ZUhrNmZHaW9vemwyQTNFRDZYUG00cEZkYWhEOUdJTEJLZmI2cWt4a0xyUWFMamxVUFRBWVZ0anJzNwo4eU0yeC80NzRLRWxCMGlyeVlsMC93aVBnTC9BbG1Yejd1eExhTDJkaU1NeHMwRHg2TS8yT0x1YzVORi8xT1ZZbTN6NjFQTU9tM1dSCjVMcFNMaGwrMGZYTldobjh1Z2IyKzFLb1M1a0UzZmo1dEl0UW8wNWlpZkNISlBxRFFzR0grdFV0S1NwYWNYcGthdGNuWUdNTjI4NUoKOVkwZmtJa3lGL2h6UTdqU1dwT0dZZGJoZFFycWVXWjJpRTl4NndRbDFncGFlcFBsdVVzWFFBK3h0cm4xM2svYzRMT3NPeEZ3WUlSSwpRMjZaSU1BcGNRckFaUUlEQVFBQm80SUN5ekNDQXNjd2ZRWUlLd1lCQlFVSEFRRUVjVEJ2TUV3R0NDc0dBUVVGQnpBQ2hrQm9kSFJ3Ck9pOHZkM2QzTG1GalkzWXVaWE12Wm1sc1pXRmtiV2x1TDBGeVkyaHBkbTl6TDJObGNuUnBabWxqWVdSdmN5OXlZV2w2WVdOamRqRXUKWTNKME1COEdDQ3NHQVFVRkJ6QUJoaE5vZEhSd09pOHZiMk56Y0M1aFkyTjJMbVZ6TUIwR0ExVWREZ1FXQkJUU2g3VGozemNuazFYMgpWdXFCNVRiTWpCNC92VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjhHQTFVZEl3UVlNQmFBRk5LSHRPUGZOeWVUVmZaVzZvSGxOc3lNCkhqKzlNSUlCY3dZRFZSMGdCSUlCYWpDQ0FXWXdnZ0ZpQmdSVkhTQUFNSUlCV0RDQ0FTSUdDQ3NHQVFVRkJ3SUNNSUlCRkI2Q0FSQUEKUVFCMUFIUUFid0J5QUdrQVpBQmhBR1FBSUFCa0FHVUFJQUJEQUdVQWNnQjBBR2tBWmdCcEFHTUFZUUJqQUdrQTh3QnVBQ0FBVWdCaApBTzBBZWdBZ0FHUUFaUUFnQUd3QVlRQWdBRUVBUXdCREFGWUFJQUFvQUVFQVp3QmxBRzRBWXdCcEFHRUFJQUJrQUdVQUlBQlVBR1VBCll3QnVBRzhBYkFCdkFHY0E3UUJoQUNBQWVRQWdBRU1BWlFCeUFIUUFhUUJtQUdrQVl3QmhBR01BYVFEekFHNEFJQUJGQUd3QVpRQmoKQUhRQWNnRHpBRzRBYVFCakFHRUFMQUFnQUVNQVNRQkdBQ0FBVVFBMEFEWUFNQUF4QURFQU5RQTJBRVVBS1FBdUFDQUFRd0JRQUZNQQpJQUJsQUc0QUlBQm9BSFFBZEFCd0FEb0FMd0F2QUhjQWR3QjNBQzRBWVFCakFHTUFkZ0F1QUdVQWN6QXdCZ2dyQmdFRkJRY0NBUllrCmFIUjBjRG92TDNkM2R5NWhZMk4yTG1WekwyeGxaMmx6YkdGamFXOXVYMk11YUhSdE1GVUdBMVVkSHdST01Fd3dTcUJJb0VhR1JHaDAKZEhBNkx5OTNkM2N1WVdOamRpNWxjeTltYVd4bFlXUnRhVzR2UVhKamFHbDJiM012WTJWeWRHbG1hV05oWkc5ekwzSmhhWHBoWTJOMgpNVjlrWlhJdVkzSnNNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVhCZ05WSFJFRUVEQU9nUXhoWTJOMlFHRmpZM1l1WlhNd0RRWUpLb1pJCmh2Y05BUUVGQlFBRGdnSUJBSmN4QXAvbi9VTm5TRVFVNUNtSDdVd29adENQTmRwTlliZEtsMDIxMjVEZ0JTNE94bm5ROHBkcEQ3MEUKUjltKzI3VXAycHZacnFtWjFkTThNSlAxamFHby9BYU5SUFRLRnBWOE05eGlpNmczK0NmWUNTMGI3OGdVSnlDcFpFVC9MdFoxcW14TgpZRUFaU1VOVVk5cml6THBtNVU5RWVsdlphb0VyUU5WLytRRW5XQ3pJN1VpUmZEK21BTS9FS1hNUk50NkdHVDZkN2htS0c5V3c3WTQ5Cm5DckFEZGc5WnVNOERiM1ZsRnppNHFjMUd3UUE5ajlhamVwRHZWK0pIYW5Cc015WjRrMEFDdHJKSjF2bkU1QmM1UFV6b2xWdDNPQUoKVFMreEpsc25kUUFKeEdKM0tRaGZubG1zdG42dG4xUXdJZ1BCSG5Gay92azRDcFlZM1FJVXJDUExCaHdlcEgyTkRkNG5RZWl0MmhXMwpzQ1BkSzZqVDJpV0g3ZWhWUkUySTlEWitoSnA0clBjT1Zra08xak1sMW9SUVFtd2dFaDBxMWI2ODhuQ0JwSEJndmdXMW01NEVSTDVoCkk2enBwU1NNRVlDVVdxS2l1VW5Td2R6UnArMHhFU3llR2FidTRWWGh3T3JQRFlUa0Y3ZWlmS1hlVlNVRzdzekFoMXhBMnN5VlAxWGcKTmNlNGhMNjBYYzE2Z3dGeTdvZm1YeDJ1dFlYR0p0L213WnJwSGdKSG55cW9iYWxieit4RmQzK1lKNW95WFNyamhPN0ZtR1l2bGlBZAozZGpESjlldytmN1pmYzNRbjQ4TEZGaFJueStMd3pndDN1aVAxbzJIcFBWV1F4YVpMUFNrVnJRMHVHRTN5Y0pZZ0J1Z2w2SDhXWTNwCkVmYlJEMHRWTkVZcWk0WTcKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVFdDQSBHbG9iYWwgUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGUVRDQ0F5bWdBd0lCQWdJQ0RMNHdEUVlKS29aSWh2Y05BUUVMQlFBd1VURUxNQWtHQTFVRUJoTUNWRmN4RWpBUUJnTlZCQW9UCkNWUkJTVmRCVGkxRFFURVFNQTRHQTFVRUN4TUhVbTl2ZENCRFFURWNNQm9HQTFVRUF4TVRWRmREUVNCSGJHOWlZV3dnVW05dmRDQkQKUVRBZUZ3MHhNakEyTWpjd05qSTRNek5hRncwek1ERXlNekV4TlRVNU5UbGFNRkV4Q3pBSkJnTlZCQVlUQWxSWE1SSXdFQVlEVlFRSwpFd2xVUVVsWFFVNHRRMEV4RURBT0JnTlZCQXNUQjFKdmIzUWdRMEV4SERBYUJnTlZCQU1URTFSWFEwRWdSMnh2WW1Gc0lGSnZiM1FnClEwRXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDd0Jkdkk2NHpFYm9vaDc0NU5uSEVLSDFKdzdXMkMKbkpmRjEweE9SVW5MUUVLMUVqUnNHY0owcERGZmhRS1g3RU16Q2xQU25JeU90N2g1Mnl2VmF2S09ac1R1S3dFSGt0U3owQUxmVVBaVgpyMllPeStCSFlDOHJNamsxVWpvb2cvaDdGc1lZdUdMV1J5V1J6dkFaRWsydFkvWFRQM1ZmS2ZDaE1Cd3FvSmltRmIzdS9SazI4T0tSClE0LzZ5dFlRSjBsTTc5M0I4WVZ3bThycXFGcEQvRzJHYjNQcE4wV3A4RGJIekloMUhydHNCditiYXo0WDdHR3FjWHpHSGFMM1Nla1YKdFR6V29XSDFFZmNGYngzOUViN1FNQWZDS2JBSlRpYmM0Nktva1dvZndwRkZpRnpsbUxoeHBSVVp5WHgxRWN4d2RFOHRteDJSUlAxVwpLS0QrdTRacXlQcGNDMWpjeGt0MnlLc2kyWE1QcGZSYUFvay9UNTRpZ3U2aWRGTXFQVk1uYVIxc2pqSXNaQUFtWTJFMlRxTkd0ejk5CnN5MnNiWkNpbGFMT3o5cUM1d2MwR1picHVDR3FLWDZtT0w2T0tVb2habmtmczhPMUNXZmUxdFFIUnZNcTJ1WWlOMkRMZ2JZUG9BL3AKeUpWL3YxV1JCWHJQUFJYQWI5NEpsQUdEMXpRYnpFQ2w4TGliWjlXWWtUdW5oSGlWSnFSYUNQZ3JkTFFBQkR6ZnVCU082Titwald4bgprak1kd0xmUzdKTEl2Z20vTENrRmJ3SnJudSs4dnlxOFc4QlFqMEZ3Y1lleVRiY0VxWVNqTXErdTdtc1hpN0t4L216aGtJeUlxSmRJCnpzaE55L01HejE5cUNrS3hIaDUzTDQ2ZzVwSU9CdndGSXRJbTRURlJmVExjRHdJREFRQUJveU13SVRBT0JnTlZIUThCQWY4RUJBTUMKQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQVh6U0JkdStXSGRYbHRka0NZNFFXd2E2ZwpjRkduOTB4SE5jZ0wxeWc5aVhIWnFqTkI2aFFiYkNFQXdHeENHWDZmYVZzZ1F0K2kwdHJFZkpkTGpiRG9yTWp1cFdrRW1RcVNwcXNuCkxocE5nYitFMUhBZXJVZisvVXFkTStEeXVjUkZDQ0VLMm1scGMzSU52alQrbEl1dHd4NDExNktENytVNHg2V0ZINnZQTk93L0tQNE0KOFZlR1RzbFY5eHpVMktWOUJucHYxZDhRMzRGT0lXV3h0dUVYZVpWRkJzNWZ6TnhHaVdOb1JJMlQ5R1J3b0QyZEtBWERPWEM0WW5zZwovZVRiNlFpaHVKNDlDY2RQK3l6NGszWkIzbExnNFZmU25RTzhkNTcrbmlsZTk4RlJZQi9lMmd1eUxYVzNRMGlUNS9aNXhvUmRnRmxnCmxQeDRtSTg4azFIdFFKQUgzMlJqSk10T2NRV2gxNVFhaURMeEluUWlycVdtMkJKcFRHQ2pBdTRyN05SamtndGV2aTkyYTZPMkpyeVAKQTlnSzhreGtScjA1WXVXVzZ6UmpFU2pNbGZHdDcrL2NnRmhJNlV1NDZtV3M2ZnlBdGJYSVJmbXN3Wi9adWVwaWlJN0U4VXVERXEzbQppNFRXbnNMcmd4aWZhcnNiSkdBemNNenM5ekx6WE5sNWZlK2VwUDdKSThNazdoV1NzVDJSVHlhR3ZXWnpKQlBxcEs1andhMTloQU04CkVIaUdHM25qeFBQeUJKVWdyaU9DeExNNkFHSy81allrNFZlNnh4NlFkZFZmUDVWaEs4RTd6ZVd6YUdIUVJpYXBJVkpwTGVzdXgrdDMKenFZNnRRTXpUM2JSNTF4VUFWM0xlUFRKREwvUEVvNFhMU05vbE9lci9xbXlLd2JRQk0wPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUZWxpYVNvbmVyYSBSb290IENBIHYxCj09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZPRENDQXlDZ0F3SUJBZ0lSQUpXK0ZxRDNMa2J4ZXptQ2N2cUx6Wll3RFFZSktvWklodmNOQVFFRkJRQXdOekVVTUJJR0ExVUUKQ2d3TFZHVnNhV0ZUYjI1bGNtRXhIekFkQmdOVkJBTU1GbFJsYkdsaFUyOXVaWEpoSUZKdmIzUWdRMEVnZGpFd0hoY05NRGN4TURFNApNVEl3TURVd1doY05Nekl4TURFNE1USXdNRFV3V2pBM01SUXdFZ1lEVlFRS0RBdFVaV3hwWVZOdmJtVnlZVEVmTUIwR0ExVUVBd3dXClZHVnNhV0ZUYjI1bGNtRWdVbTl2ZENCRFFTQjJNVENDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFNSysKNnlmd0lhUHphU1pWZnAzRlZSYVJYUDN2SWI5VGdIb3QwcEdNWXpIdzdDVHd3NlhTY253UWJmUTN0K1htZkhucWpMV0NpNjVJdHF3QQozR1YxN0NwTlg4R0g5U0JsSzRHb1J6NkpJNVV3RnBCLzZGY0hTT2NacnI5Rlo3RTNHd1lxL3Q3NXJIMkQrMTY2NUkrWFo3NUxqbzFrCkIxYzRWV2swTmowVFNPOVA0dE5tSHFUUEdyZGVOalBVdEFhOUdBSDlkNFJRQUVYMWpGM29JN3grL2pYaDdWQjdxVENOR2RNSmptaG4KWGI4OGx4aFR1eWxpeGNwZWNzSEhsdFRiTGFDMEgya0Q3T3JpVVBFTVBQQ3M4MU10OEJ6MTdXdzVPWE9BRnNoU3NDUE40RDdjM1R4SApvTHMxaXVLWWFJdSs1Yjl5N3RMNnBlMFM3ZnlZR0trbWR0d29TeEFnSE5OL0ZuY3Q3VytBOTBtN1V3VzdYV2pIMU1oMUZqK0pXb3YzCkYwZlVUUEhTaVhrK1RUMllxR0hlT2g3UytGNEQ0TUhKSEl6VGpVM1RsVGF6TjE5alk1c3pGUEF0Sm10VGZJbU1Nc0p1N0QwaEFEbkoKb1dqaVVJTXVzRG9yOHphZ3JDL2tiMkhDVVFrNVBvdFR1YnRuMnR4VHVYWlpOcDFENVNEZ1BUSmdoU0pSdDhjenU5MFZMNlI0cGdkNwpnVVkyQkliZGVUWEhsU3c3c0tNWE5lVnpIN1JjV2UvYTZoQmxlM3JRZjUrenRDbzNPM0NMbTF1NUs3ZnNzbEVTbDFNcFd0VHdFaERjClR3SzdFcEl2WXRRL2FVTjhEZGI4V0hVQmlKMVlGa3ZldXBEL1J3R0pCbXIyWDdLUWFyTUNwZ0tJdjdOSGZpcloxZnBvZURWTkFnTUIKQUFHalB6QTlNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdDd1lEVlIwUEJBUURBZ0VHTUIwR0ExVWREZ1FXQkJUd2oxazRBTFAxajVxVwpETlhyK251cUYrZ1RFakFOQmdrcWhraUc5dzBCQVFVRkFBT0NBZ0VBdnVSY1lrNGs5QXdJLy9EVERHamtrMGtpUDBRbmI3dHQzb05tCnpxak1EZnoxbWdibGR4U1I2NTFCZTVrcWhPWC8vQ0hCWGZEa0gxZTNkYW1oWHdJbS85Zkg5MDdlVC9qM0hFYkFlazlBTENJMThCbXgKMEd0bkxMQ280TUJBTnpYMmhGeGM0NjlDZVA2bnlRMVE2ZzJFZHZaUjc0TlR4bnIvRGxaSkxvOTYxZ3ptSjFUalRRcGdjbUxOa1FmVwpwYi9JbVd2dHhCbm1xMHdST01Wdk1lSnVTY2cvZG9BbUF5WXA0RGIyOWlCVDR4ZHdOQmVkWTJnZWErekRUWWE0RXpBdlhVWU5SMFBWCkc2cFpEcmxjalFaSXJYU0hYOGY4TVZSQkUrTEhJUTZlNEI0TjRjQjdRNFdReFlwWXhtVUtlRmZ5eGlNUEFka2dTOTRQKzVLRmRTcGMKYzQxdGV5V1J5dTVGcmdaTEFNelRzVmxRMmpxSU95bERSbDZYSzFUT1UyK05TdWVXK3I5eERrS0xmUDBvb05CSXl0ckVnVXk3b25PVApKc2pyRE5ZbWlMYkFKTSs3dlZ2cmRYM3BDSTZHTXl4NWR3bHBwWW44czNDUWgzYVAweUs3UXM2OWN3c2dKaXJRbXoxd0hpUnN6WWQyCnFSZVd0ODhOa3Z1T0dLbVlTZEdlL21CRWNpRzVHZTNDOVRIeE9VaUlrQ1IxVkJhdHp2VDRhUlJrT2Z1anVMcHdRTWNuSEwvRVZsUDYKWTJYUTh4d09GdlZyaGxoTkdOVGtEWTZsblZ1UjNIWWtVRC9HS3Z2WnQ1eTExdWJRMmVnWml4VnhTSzIzNnRoWmlOU1F2eGF6MmVtcwpXV0ZVeUJ5NnlzSEs0YmtnVEk4Nms0bWxvTXkvMC9aMXBIV1diVlk9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkUtVHVncmEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJR1N6Q0NCRE9nQXdJQkFnSUlhbWcrbkZHYnkxTXdEUVlKS29aSWh2Y05BUUVMQlFBd2diSXhDekFKQmdOVkJBWVRBbFJTTVE4dwpEUVlEVlFRSERBWkJibXRoY21FeFFEQStCZ05WQkFvTU4wVXRWSFhFbjNKaElFVkNSeUJDYVd4cHhaOXBiU0JVWld0dWIyeHZhbWxzClpYSnBJSFpsSUVocGVtMWxkR3hsY21rZ1FTN0ZuaTR4SmpBa0JnTlZCQXNNSFVVdFZIVm5jbUVnVTJWeWRHbG1hV3RoYzNsdmJpQk4KWlhKclpYcHBNU2d3SmdZRFZRUUREQjlGTFZSMVozSmhJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEV6TURNdwpOVEV5TURrME9Gb1hEVEl6TURNd016RXlNRGswT0Zvd2diSXhDekFKQmdOVkJBWVRBbFJTTVE4d0RRWURWUVFIREFaQmJtdGhjbUV4ClFEQStCZ05WQkFvTU4wVXRWSFhFbjNKaElFVkNSeUJDYVd4cHhaOXBiU0JVWld0dWIyeHZhbWxzWlhKcElIWmxJRWhwZW0xbGRHeGwKY21rZ1FTN0ZuaTR4SmpBa0JnTlZCQXNNSFVVdFZIVm5jbUVnVTJWeWRHbG1hV3RoYzNsdmJpQk5aWEpyWlhwcE1TZ3dKZ1lEVlFRRApEQjlGTFZSMVozSmhJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBCk1JSUNDZ0tDQWdFQTR2VS9rd1ZSSG9WaVZGNTZDL1VZQjRPdWZxOTg5OVNLYTZWalF6bTVTL2ZEeG1TSlBaUXVWSUJTT1RrSFMwdmQKaFFkMmg4eS9MNVZNekgyblBieEhENWh3K0l5RkhuU09rbTBiUU5HWkRidDFic2lwYTVyQWhER3Z5a1BMNnlzMDZJK1hhd0diMVE1SwpDS3Bia25TRlE5T0FycUdJVzY2ejZsN0xGcHAzUk1paDlsUm96dDZQbHl1NlcwQUNER1FYd0xXVHplSHhFMmJPREhudjBaRW9xMStnCkVsSXdjeG1PaitHTUI2TER1MHJ3Nmg4VnFPNGx6S1JHK0JzaTc3TU9RN29zSkxqRkxGelVIUGhkWkwzRGsxNG9wejhuOFk0ZTB5cFEKQmFOVjJjdm5PVlBBbUo2TVZHS0xKckQzZlkxODVNYWVaa0pWZ2tmbnNsaU5admNIZkM0MjVsQWNQOXRESk1XL2hrZDVzM2tjOTFyMApFK3hzK0QvaVdSK1Y3a0krdWEyb01vVkpsMGIrU3pHUFdzdXRkRWNmNlpHMzN5Z0VJcURVRDEzaWVVL3FiSVdHdmFpbXp1VDZ3K0d6CnJ0NDhVZTdMRTN3QmY0UU9YVkdVbmhNTXRpNmxUUGs1Y0Radmxzb3VERVJWeGNyNlhRS2ozOVprakZxekFRcXB0UXBIRi8vdmtVQXEKanFGR09qR1k1Ukg4ekx0SlZvcjh1ZEJobW05bGJPYkR5ejUxU2Y2UHArS0p4V2ZYblVZVFRqRjJPeVN6bmhGbGhxdC83eDNVK0x6bgpyRnBjdDFwSFhGWE9WYlFpY1Z0YkMvRFAzS0JoWk9xcDEyZ0tZNmZnRFQrZ3I5T3Ewbjd2VWFEbVVTdFZraFVYVTh1M1pnNW1UUGo1CmRVeVE1eEp3eDBVQ0F3RUFBYU5qTUdFd0hRWURWUjBPQkJZRUZDN2oyN0pKMEp4VWVWejZKeXIrekU3UzZFNVVNQThHQTFVZEV3RUIKL3dRRk1BTUJBZjh3SHdZRFZSMGpCQmd3Rm9BVUx1UGJza25RbkZSNVhQb25LdjdNVHRMb1RsUXdEZ1lEVlIwUEFRSC9CQVFEQWdFRwpNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUFGTnpyMFRiZEY0a1YxSkkrMmQxTG9ITmdRazJYejhsa0dwRDRlS2V4ZDBkQ3JmT0FLCmtFaDQ3VTZZQTVuK0tHQ1JIVEFkdUdOOHFPWTF0ZnJUWVhibTFnZEx5bW1hc29SNmQ1TkZGeFdmSk5DWUV4TC91NkF1L1U1TWgvak8KWEtxWUd3WGdBRVpLZ29DbE00c28zTzA0MDkvbFB1bisrMW5kWVlSUDBsU1dFMkVUUG8rQWFiNlRSN1UxUTlKYXV6MWM3N05DUjgwNwpWUk1Hc0FuYi9XUDJPb2dLbVc5KzRjNGJVMnBFWmlOUkNIdThXMUtpL1FZM09FQmhqMHFXdUpBMytHYkhlSkFBRlM2THJWRTFVd2VvCmEyaXUrVTQ4QnliTkNBVnd6RGsvZHIybDAyY21BWWFtVTlKZ08zeERmMVdLdkpVYXdTZzVUQjlEMHBIMGNsbUt1VmI4UDdTZDJuQ2MKZGxxTVExRHVqakJ5VGQvL1NmZkdxV2ZaYmF3Q0VlSTZGaVduV0FqTGIxTkJuRWc0UjJnejBkZkhqOVIwSWRUREJaQjYvODZXaUxFVgpLVjBqcTlCZ29SSlAzdlFYelRMbHliL0lRNjM5TG83eHIrTDBtUG9TSHlEWXdLY01oY1dROURzdGxpYXhMTDVNcSt1eDBvckoyM2dUCkR4NEpuVzJQQUo4QzJzSDZIM3A2Q2NSSzVvZ3FsNStKaS8wM1gxODZ6amhaaGt1dmNRdTAyUEp3VDU4eUUrT3dwMWZsMnRwRHk0UTAKOGlqRTZtMzBLdS9CYTNiYSszNjdoVHpTVThKTnZuSGhSZEg5STJjTkUzWDd6MlZuSXAydXNBblJDZjhkTkwvK0k1YzMwam42UFEwRwpDN1RiTzZPcmIxd2R0bjdvczRJMDdRWmNKQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHd6Q0NBcXVnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFzRkFEQ0JnakVMTUFrR0ExVUVCaE1DUkVVeEt6QXBCZ05WQkFvTQpJbFF0VTNsemRHVnRjeUJGYm5SbGNuQnlhWE5sSUZObGNuWnBZMlZ6SUVkdFlrZ3hIekFkQmdOVkJBc01GbFF0VTNsemRHVnRjeUJVCmNuVnpkQ0JEWlc1MFpYSXhKVEFqQmdOVkJBTU1IRlF0VkdWc1pWTmxZeUJIYkc5aVlXeFNiMjkwSUVOc1lYTnpJREl3SGhjTk1EZ3gKTURBeE1UQTBNREUwV2hjTk16TXhNREF4TWpNMU9UVTVXakNCZ2pFTE1Ba0dBMVVFQmhNQ1JFVXhLekFwQmdOVkJBb01JbFF0VTNsegpkR1Z0Y3lCRmJuUmxjbkJ5YVhObElGTmxjblpwWTJWeklFZHRZa2d4SHpBZEJnTlZCQXNNRmxRdFUzbHpkR1Z0Y3lCVWNuVnpkQ0JEClpXNTBaWEl4SlRBakJnTlZCQU1NSEZRdFZHVnNaVk5sWXlCSGJHOWlZV3hTYjI5MElFTnNZWE56SURJd2dnRWlNQTBHQ1NxR1NJYjMKRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDcVg5b2JYK2h6a2VYYVhQU2k1a2ZsODJoVllBVWRBcVN6bTFuekhvcXZOSzM4RGNMWgpTQm51YVkvSklQd2hxZ2NaN2JCY3JHWEhYKzBDZkh0OExSdld1cm1Bd2hpQ0ZvVDZackFJeGxRamdlVE51VWsvOWs5dU4wZ29PQS9GCnZ1ZG9jUDA1bDAzU3g1aVJVS3JFUkxNamZUbEg2VkppMWhLVFhyY3hsa0lGKzNhbkhxUDF3dnpwZXNWc3FYRlA2c3Q0dkdDdng5NzAKMmN1K2ZqT2xicFNEOERUNklhdnFqbktnUDZUZU1GdnZoazFxbFZ0RFJLZ1FGUnpsQVZmRm1QSG1CaWlScWlERnQxTW1VVU95Q3hHVgpXT0hBRDNiWndJMThnZk55Y0o1di9ocU8yVjgxeHJKdk5IeStTRS9pV2puWDJKMTRucCtHUGdOZUdZdEVvdFhIQWdNQkFBR2pRakJBCk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJTL1dTQTJBSG1nb0NKcmpOWHkKWWRLNExNdUNTakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBTVFPaVlRc2ZkT2h5TnNadCtVMmUraUtvNFlGV3o4MjduK3Fya1JrNApyNnA4RlUzenRxT05wZlNPOWtTcHArZ2hsYTArQUdJV2lQQUN1dnhoSStZem16QjZhelppZTYwRUk0UllaZUxiSzRybkpWTTNZbE5mCnZOb0JZaW1pcGlkeDVqb2lmc0Z2SFpWd0lFb0hOTi9xL3hXQTViclhldGhiZFh3RmVpbEhma0NvTVJOM3pVQTd0RkZIZWk0UjQwY1IKM3AxbTBJdlZWR2I2ZzFYcWZNSXBpUnZwYjdQTzRnV0V5UzgrZUlWaWJzbGZ3WGhqZEZqQVNCZ01tVG5ycE13YXRYbGFqUldjMkJRTgo5bm9IVjhjaWd3VXRQSnNsSmowWXM2bERmTWpJcTJTUERxTy9uQnVkTU52YTBCa3Vxanp4K3pPQWR1VE5yUmxQQlNlT0U2RnV3Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkF0b3MgVHJ1c3RlZFJvb3QgMjAxMQo9PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURkekNDQWwrZ0F3SUJBZ0lJWERQTFlpeGZzekl3RFFZSktvWklodmNOQVFFTEJRQXdQREVlTUJ3R0ExVUVBd3dWUVhSdmN5QlUKY25WemRHVmtVbTl2ZENBeU1ERXhNUTB3Q3dZRFZRUUtEQVJCZEc5ek1Rc3dDUVlEVlFRR0V3SkVSVEFlRncweE1UQTNNRGN4TkRVNApNekJhRncwek1ERXlNekV5TXpVNU5UbGFNRHd4SGpBY0JnTlZCQU1NRlVGMGIzTWdWSEoxYzNSbFpGSnZiM1FnTWpBeE1URU5NQXNHCkExVUVDZ3dFUVhSdmN6RUxNQWtHQTFVRUJoTUNSRVV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ1YKaFR1WGJ5bzdManZQcHZNcE5iN1BHS3crcXRuNFRhQStHa2U1dkpyZjh2N01Qa2ZvZXBiQ0pJNDE5S2tNL0lMOWJjRnlZaWU5Nm12cgo1NHJNVkQ2UVVNK0ExSlg3NkxXQzFCVEZ0cWxWSlZmYnNWRDJzR0JrV1hwcHp3TzNidzIreWo1dmRITHFxakFxYzJLK1NaRmh5QkgrCkRnTXE5Mm9nM0FJVkRWNFZhdnpqZ3NHMXhaMWtDV3lqV1pnSEo4Y2JsaXRoZEhGc1EvSDNOWWtRNEo3c1ZhRTNJcUtIQkFVc1IzMjAKSExsaUtXWW95cmZoay9Xa2xBT1p1WENGdGVaSTZvMVEvTm5lekc4SER0MExjcDJBTUJZSGxUOG9EdjNGZFU5VDFuU2F0Q1F1amdLUgp6M2JGbXg1VmRKeDRJYkh3TGZFTG44TFZsaGdmOEZRaWVvd0hBZ01CQUFHamZUQjdNQjBHQTFVZERnUVdCQlNucFFheExLWUpZTzdSCmwrbHdycnc3R1d6YklUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01COEdBMVVkSXdRWU1CYUFGS2VsQnJFc3BnbGc3dEdYNlhDdXZEc1oKYk5zaE1CZ0dBMVVkSUFRUk1BOHdEUVlMS3dZQkJBR3dMUU1FQVFFd0RnWURWUjBQQVFIL0JBUURBZ0dHTUEwR0NTcUdTSWIzRFFFQgpDd1VBQTRJQkFRQW1kelRibEVpR0trR2RMRDRHa0dERWpLd0xWTGdmdVh2VEJ6bmsrajU3c2oxTzdaOGp2WmZ6YTF6djd2MUFwdCtoCms2RUtocXp2SU5CNUFiMTQ5eG5ZSkRFMEJBR211aFdhd3lmYzJFOFB6QmhqLzVrUERwRnJkUmJoSWZ6WUpzZEh0NmJQV0hKeGZycmgKVFpWSE84bXZiYUcwd2V5SjlyUVBPTFhpWk53bHo2YmI2NXBjbWFIRkNONzk1dHJWMWxwRkRNUzN3clVVNzdRUi93NFZ0ZlgxMjhhOQo2MXFuOEZZaXFUeGxWTVlWcUwyR25zMkRsbWg2Y1lHSjRRdmg2aEViYUFqTWFaN3Nua0dlUkRJbWV1S0hDbkU5NitSYXBOTGJ4YzNHCjNtQi91Zk5QUkpMdktyY1lQcWNaMlF0OXNUZEJRckM2WUIzeS9na1JzUENIZTZlZAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpRdW9WYWRpcyBSb290IENBIDEgRzMKPT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGWURDQ0EwaWdBd0lCQWdJVWVGaGZMcTBzR1V2ak53YzFOQk1vdFpiVVpaTXdEUVlKS29aSWh2Y05BUUVMQlFBd1NERUxNQWtHCkExVUVCaE1DUWsweEdUQVhCZ05WQkFvVEVGRjFiMVpoWkdseklFeHBiV2wwWldReEhqQWNCZ05WQkFNVEZWRjFiMVpoWkdseklGSnYKYjNRZ1EwRWdNU0JITXpBZUZ3MHhNakF4TVRJeE56STNORFJhRncwME1qQXhNVEl4TnpJM05EUmFNRWd4Q3pBSkJnTlZCQVlUQWtKTgpNUmt3RndZRFZRUUtFeEJSZFc5V1lXUnBjeUJNYVcxcGRHVmtNUjR3SEFZRFZRUURFeFZSZFc5V1lXUnBjeUJTYjI5MElFTkJJREVnClJ6TXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDZ3ZsQVFqdW55YkVDMEJKeUZ1VEhLM0Mza0Vha0UKUEJ0VndlZFlNQjBrdE1QdmhkNk1MT0hCUGQrQzVrK3RSNGRzN0Z0SndVclZ1NC9zaDZ4L2dwcUc3RDBEbVZJQjBqV2VyTnJ3VThsbQpQTlNzQWdIYUpOTTdxQUpHcjZRYzQvaHpXSGEzOWc2UURiWHd6OHo2K2NaTTVjT0dNQXFORjM0MTY4WGZ1dzZjd0kySDQ0ZzRoV2Y2ClBzZXI0Qk9jQlJpWXo1UDFzWkswL0NQVHo5WEVKMG5nbmp5YkNLT0xYU29oNFB3NXFsUGFmWDdQR2dsVHZGMEZCTStoU28rTGRvSU4Kb2ZqU3h4UjNXNUEyQjRHYlBnYjZVbDVqeGFZQS9xWHBVaHRTdFpJNWNnTUpZcjJ3WUJadXB0MGx3Z05tM2ZNRTBVRGlUb3VHOUcvbApnNkFuaEY0RXdmV1F2VEE5eE8rb2FidzRtNlNrbHRGaTJtbkFBWmF1eThSUk5Pb01xdjhoamxtUFNsemtZWnFuMHVrcWVJMVJQVG9WCjdxSlpqcWxjM3NYNWtDTGxpRVZ4M1pHWmJIcWZQVDJZZkY3MnZoWm9vRjZ1Q3lQOFdnK3FJbll0eWFFUUhlVFRSQ09RaUovR0t1YlgKOVpxeldCNHZNSWtJRzFTaXRaZ2o3QWgzSEpWZFlkSExpWnhmb2txUm11OGhxa2tXQ0tpOVlTZ3h5WFN0aGZiWnhiR0wwZVVRTWsxZgppeUE2UEVrZk00VlpEZHZMQ1hWRGFYUDdhM0Y5OE4vRVRIM0dveTdJbFhuTGM2S09UazBrKzE3a0JMNXlHNlluTFVsYW1YclhYQWtnCnQzK1V1VS94RFJ4ZWlFSWJFYmZua2R1ZWJQUnEzNHdHbUFPdHpDanZwVWZ6VXdJREFRQUJvMEl3UURBUEJnTlZIUk1CQWY4RUJUQUQKQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVW81Zlc4MTZpRU9HclJaODhGMlE4N2dGd25Nd3dEUVlKS29aSQpodmNOQVFFTEJRQURnZ0lCQUJqNlczWDhQbnJIWDNmSHl0L1BYOE1TeEVCZDFES3F1R3JYMVJVVlJwZ2pwZWFRV3hpWlRPT3RRcU9DCk1UYUl6ZW43eEFTV1NJc0J4NDBCejFzekJwWkdablFkVCszQnRybTBEV0hNWTM3WExuZU1saHdxSTJocmhWZDJjRE1UL3VGUHBpTjMKR1BvYWpPaTlaY25QUC9USkY5enJ4N3pBQkM0dFJpOXBac01iai83c1B0UEtsTDkyQ2lVTnFYc0NIS25RTzE4THdJRTZQV1RodjZjdApUcjFOeE5ncHhpSVkwTVdzY2dLQ1A2bzZvam9pbHpIZENHUERkUlM1WUNndFcyamdGcWxtZ2lOUjlldFQyREdiZSttM25VdnJpQmJQCitWMDRpa2t3aiszeDZ4bjBkeG94R0UxblZHd3ZiMlg1Mnozc0lleGU5UFNMeW1CbFZORnhaUFQ1cHFPQk16WXpjZkNrZUY5T3JZTWgKM2pSSmplaFpySjN5ZGxvMjhoUDByK0FKeDJFcWJQZmduYTY3aGtvb2J5N3V0SG5Oa0RQRHMzYjY5ZkJzblFHUStwNlE5cHh5ejBmYQp3eC9rTlNCVDhsVFIzMkdEcGdMaUpUamVoVEl0WG5PUVVsMUN4TTQ5UytINUdZUWQxYUpRekVIN1FSVER2ZGJKV3FOalpnS0F2UVU2Ck8wZWM3QUFtVFBXSVViK29JMzhZQjdBTDdZc21vV1RUWVVyclhKL2VzNjluQTdNZjNXMWRhV2hwcTE0NjdIeHB2TWM3aFU2ZUZibTAKRlUvRGxYcFkxOGxzNld5NTh5bGpYclFzOEMwOTdWcGw0S2xiUU1KSW1ZRnRuaDhHS2p3U3RJc1BtNklrOEthTjFucmdTN1prbG1PVgpoTUpLelJ3dUpJY3pZT1hECi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClF1b1ZhZGlzIFJvb3QgQ0EgMiBHMwo9PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZZRENDQTBpZ0F3SUJBZ0lVUkZjMEpGdUJpWnMxOHM2NEt6dGJweWJ3ZFNnd0RRWUpLb1pJaHZjTkFRRUxCUUF3U0RFTE1Ba0cKQTFVRUJoTUNRazB4R1RBWEJnTlZCQW9URUZGMWIxWmhaR2x6SUV4cGJXbDBaV1F4SGpBY0JnTlZCQU1URlZGMWIxWmhaR2x6SUZKdgpiM1FnUTBFZ01pQkhNekFlRncweE1qQXhNVEl4T0RVNU16SmFGdzAwTWpBeE1USXhPRFU1TXpKYU1FZ3hDekFKQmdOVkJBWVRBa0pOCk1Sa3dGd1lEVlFRS0V4QlJkVzlXWVdScGN5Qk1hVzFwZEdWa01SNHdIQVlEVlFRREV4VlJkVzlXWVdScGN5QlNiMjkwSUVOQklESWcKUnpNd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUNocmlXeUFSamNWNGcvUnV2NXIrTHJJM0hpbXRGaApaaUZmcXE4blVlVnVHeGJVTFgxUXNGTjN2WGc2WU9Ka0FwdDhocHZXR282dC94OFZmOVdWSGhMTDVoU0VCTUhmTnJNV240cmp5ZHVZCk5NN1lNeGNvUnZ5bnlmRFN0TlZOQ1hKSitmS0g0Nm5hZmFGOWE3STZKYWx0VWtTcytMNXUrOXltYzVHUVlhWURGQ0R5NTRlamlLMnQKb0l6L3Bnc2xVaVhuRmdIVnk3ZzFnUXlqTy9EaDRmeGFYYzZBY1czNFNhcytPN3E0MTRBQis2WHJXN1BGWG1BcU1hQ3ZOK2dnT3ArbwpNaXdNekFrZDA1Nk9YYnhNbU83RkdtaDc3Rk9tNlJRMW85L05nSjhNU1BzYzlQRy9Tcmo2MVl4eFNzY2ZyZjVCbXJPRFhmS0VWdStsClYwUE9LYTJNcTFXL3hQdGJBZDBqSWFGWUFJN0QwR29UN1JQakVpdUEzR2ZtbGJMTkhpSnVLdmhCMVBMS0ZBZU5pbFVTeG1uMXVJWm8KTDFOZXNOS3FJY0dZNWpEaloxWEhtMjZzR2FoVnBrVUcwQ002Mit0bFhTb1JFZkE3VDhwdDlEVEVjZVQvQUZyMlhLNGpZSVZ6OGVRUQpzU1d1MVpLN0U4RU00RG5hdERsWHRhczFxbkloTzRNMTV6SGZlaUZ1dURJSWZSMHlrUlZLWW5MUDQzZWh2TlVSRzNZQlp3amdRUXZECjZ4VnUrS1FaMmFLcnIrSW5VbFlyQW9vc0ZDVDV2MElDdnliSXhvL2diamg5VXkzbDdaaXpsV05vZi9rMTlOK0l4V0Exa3NCOGFSeGgKbFJiUTY5NExyejRFRUVWbFdGQTRyMGp5V2JZVzhqd05rQUxHY0M0QnJUd1Yxd0lEQVFBQm8wSXdRREFQQmdOVkhSTUJBZjhFQlRBRApBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJCakFkQmdOVkhRNEVGZ1FVN2VkdmRscS9ZT3hKVzhhbGQ3dHlGbkdieEQwd0RRWUpLb1pJCmh2Y05BUUVMQlFBRGdnSUJBSkhmZ0Q5RENYNXh3dmZyczRpUDRWR3l2RDExK1NoZHlMeVptM3RkcXVYSzRRcjM2TExUbjkxbk1YNjYKQWFySGFrRTdrTlFJWExKZ2FwRHd5TTREWXZtTDdmdHVLdHdHVFR3cEQ0a1dpbGhNU0Evb2hHSHFQSEttZCtSQ3JvaWpRMWg1ZnE3SwpwVk1OcVQxd3ZTQVpZYVJzT1B4RE11SEJSLy80N1BFUklqS1duTUwyVzJtV2V5QU1RMEdhVy9aWkdZamVWWWczVVF0NFhBb2VvMEw5Cng1MklEOER5ZUFJa1ZKT3ZpWWVJeVVxQUhlclFiajVoTGphN05RNG5sdjFtTkR0aGNuUHhGbHhIQmxSSkFIcFlFckFLNzRYOXNiZ3oKZFdxVEhCTG1ZRjV2SFgvSkh5UExoR0dmSG9KRStWK3RZbFVrbWxLWTdWSG5vWDZYT3VZdkh4SGFVNEFzaFo2ck5SRGJJbDlxeFY2WApVL0l5QWdrd28xandEUUhWY3NheGZHbDd3L1UyUmN4aGJsNU1sTVZlcnVnT1hvdS85ODNnN2FFT0d6UHVWQmorRDc3dmZvUnJRK053Cm1OdGRkYklOV1FlRkZTTTUxdkhmcVNZUDFrakhzNllpOVRNM1dwVkhuM3U2R0JWdi85WVVaSU5KMGdwbklkc1BOV05nS0NManNaV0QKellXbTNTOFA1MmRTYnJzdmhYejFTblBueFQ3QXZTRVNCVC84dHdOSkFsdklKZWJpVkRqMWVZZU1IVk95VG9WN0JqakhMUGo0c0hLTgpKZVYzVXZRREhFaW1VRitJSURCdThvSkRxejJYaE9kVCt5SEJUdzhpbW9hNFdTcjJSejBaaUMzb2hlR2U3SVVJYXJGc05Na2Q3RWdyCk8zanRac1NPZVdtRDNuK00KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKUXVvVmFkaXMgUm9vdCBDQSAzIEczCj09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRllEQ0NBMGlnQXdJQkFnSVVMdldiQWlpbjIzci8xYU9wN3IwRG9NOFNhaDB3RFFZSktvWklodmNOQVFFTEJRQXdTREVMTUFrRwpBMVVFQmhNQ1FrMHhHVEFYQmdOVkJBb1RFRkYxYjFaaFpHbHpJRXhwYldsMFpXUXhIakFjQmdOVkJBTVRGVkYxYjFaaFpHbHpJRkp2CmIzUWdRMEVnTXlCSE16QWVGdzB4TWpBeE1USXlNREkyTXpKYUZ3MDBNakF4TVRJeU1ESTJNekphTUVneEN6QUpCZ05WQkFZVEFrSk4KTVJrd0Z3WURWUVFLRXhCUmRXOVdZV1JwY3lCTWFXMXBkR1ZrTVI0d0hBWURWUVFERXhWUmRXOVdZV1JwY3lCU2IyOTBJRU5CSURNZwpSek13Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ3p5dzRRWjQ3cUZKZW5NaW9LVmpaL2FFekhzMjg2Ckl4U1IveGwvcGNxczdyTjJuWHJwaXh1cmF6SGIrZ3RUVEsvRnBScDVQSXBNLzZ6ZkpkNU8yWUl5QzBUZXl0dU1yS051Rm9NN3BtUkwKTW9uN0ZoWTRmdXRENHROMFNzSmlDbk1LM1VtelY5S3dDb1dkY1R6ZW84dkFNdk1CT1NCREd6WFJVN094N3NXVGFZSStGclVvUnFIZQo2b2tKN1VPNEJVYUtodlZaUjc0YmJ3RWhFTG45cWRJb3loQTVDY29UTnMrY3JhMUFkSGtyQWo4MC8vb2dhWDNUN21IMXVyUG5NTkEzCkk0WnlZVVVwU0Zsb2IzZW1Mb0crQjAxdnI4N0VSUk9SRkhBR2p4K2YrSWRwc1E3dnc0a1o2K29jWWZ4NmJJcmMxZ01MbmlhNkV0M1UKVkRtckpxTXo2bldCMmkzTkQwL2tBOUh2RlpjYmE1REZBcENUWmdJaHNVZmVpNXBLZ0xsVmo3V2lMOERXTTJmYWZzU250QVJFNjBmNwo1bGk1OXd6d2V5dXh3SEFwdzBCaUxUdElhZHdqUEVqcmV3bDVxVzNhcURDWXo0QnlBNGltVzBhdWNubDhDQU1oWmE2MzRSeWxzU3FpCk1kNW1CUGZBZE9oeDN2ODlXY3lXSmhLTGhaVlhHcXRyZFF0RVBSRW9QSHRodCtLUFowL2w3RHhNWUlCcFZ6Z2VBVnVOVmVqSDM4RE0KZHlNMFNYVjg5cGdSNnkzZTdVRXVGQVVDZitEK0lPczE1eEdzSXM1WFBkN0pNRzBRQTRYTjhmK01GclhCc2o2SWJHQi9rRStWOS9ZdApyUUU1QndUNmRZQjl2MGxRN2UvSnhId2M2NEIrMjdiUTNSUCt5ZE9jMTdLWHFRSURBUUFCbzBJd1FEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVV4aGZRdktqcUFrUHlHd2FaWFN1UUlMblhuT1F3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dJQkFEUmgyVmExRW9kVlRkMmpOVEZHdTZRSGNyeGZZV0xvcGZzTE43RTh0clA2S1oxL0F2V2t5YWlUdDNweApLR21QYytGU2tOclZ2anJsdDNacVZvQWgzMTNtNlRxZTVUNzJvbW5IS2dxd0dFZmNJSEI5VXFNK1dYekJ1c25JRlVCaHluTFdjS3pTCnQvQWM1SVlwOE03dmFHUFF0U0NLRldHYWZvYVl0TW5DZHZ2TXVqQVd6S05oeG5RVDVXdnZveFhxQS80VGkyVGswOEhTNklUN1NkRVEKVFhsbTY2cjk5STB4SG5BVXJkemVaeE5NZ1JWaHZMZlprWGR4R1lGZ3UvQllwYldjQy9lUElsVW53RXNCYlR1WkRkUWRtMk5uTDlEdQpEY3BtdkpSUHBxM3QvTzVqckZjL1pTWFBzb2FQMEFqL3VIWVVidDdsSit5cmVMVlR1YlkvNkNENTBxaStZVWJLaDR5RTgvbnhvR2liCkloNkJKcHNRQkpGeHdBWWYzS0RUdVZhbjQ1Z3RmNE9kMzR3cm5ES09NcFR3QVR3aUtwOUR3aTdEbURrSE9IdjhYZ0JDSC9NeUpubUQKaFBibDhNRlJFc0FMSGdRakRGU2xUQzlKeFVyUnRtNWdEV3Y4YTR1RkpHUzNpUTZySlVkYlBNOStTYjNINlFyRzJ2ZCtEaGNJMDBpWAowSEdTOEE4NVBqUnFISDNZOGlLdXUybjBNN1NtU0ZYUkR3NG02T3kyQ3kybmhUWE4vVm5JbjlITlBsb3BOTGs5aE02eFpkUlprWkZXCmRTSEJkNTc1ZXVGZ25kT3RCQmowZk90ZWs0OVRTaUlwK0VnclBrMkdyRnQveXdhWldXRFlXR1dWalVUUjkzOStKMzk5cm9EMUIweTIKUHB4eFZKa0VTLzFZK1pqMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEbGpDQ0FuNmdBd0lCQWdJUUM1TWNPdFk1Witwbkk3L0RyNXIwU3pBTkJna3Foa2lHOXcwQkFRc0ZBREJsTVFzd0NRWURWUVFHCkV3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TUXcKSWdZRFZRUURFeHRFYVdkcFEyVnlkQ0JCYzNOMWNtVmtJRWxFSUZKdmIzUWdSekl3SGhjTk1UTXdPREF4TVRJd01EQXdXaGNOTXpndwpNVEUxTVRJd01EQXdXakJsTVFzd0NRWURWUVFHRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMCkV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TUXdJZ1lEVlFRREV4dEVhV2RwUTJWeWRDQkJjM04xY21Wa0lFbEVJRkp2YjNRZ1J6SXcKZ2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFo1eWd2VWo4MmNrbUlrelR6K0dvZU1WU0FuNjFVUWJWSAozNWFvMUsrQUxia0t6M1g5aWFWOUpQcmpJZ3dydkpVWEN6Ty9HVTFCQnBBQXZReE5FUDRIdGVjY2JpSlZNV1dYdmRNWDBoNWk4OXZxCmJGQ01QNFFNbHMrM3l3UGd5bTJoRkV3YmlkM3RBTEJTZksrUmJMRTRFOUhwRWdqQUFMQWNLeEhhZDNBMm02N09lWWZjZ25EbUNYUncKVldtdm8yaWZ2OTIyZWJQeW5YQXBWZlNyLzVWaDg4bEFieDNSdnBPNzA0Z3F1NTIvY2xwV2NUcy8xUFBSQ3Y0bzc2UHUyWm12QTlPUApZTGZ5a3FHeHZZbUpIekROdzZZdVlqT3VGZ0ozUkZybmdRbzhwMFF1ZWJnL0JMeGNvSWZoRzY5UmpzM3NMUHI0L20zd09ueXFpK1JuCmxUR05BZ01CQUFHalFqQkFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01CMEdBMVVkRGdRV0JCVE8KdzBxNW1WWHl1TnRndjZsK3ZWYTFsemFuMWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQXlxVlZqT1BJUVc1cEo2ZDFFZTg4aGpadgowcDNHZURnZGFaYWlrbWt1T0d5YmZRVFVpYVd4TVRlS3lTSE1xMnpOaXh5YTFyOUkwakptd1lyQTh5ODY3OERqMUpHRzBWRGpBOXR6CmQyOUtPVlB0M2liSHRYMnZLMExSZFdMalNpc0N4MUJMNEduaWxtd09SR1lRUkkrdEJldjRlYXltRytnM05KMVR5V0dxb2xLdlNuQVcKaHNJNnlMRVRjRGJZeis3MENqVFZXMHo5QjV5aXV0a0JjbHp6VGNIZERyRWNEY1JqdnEzMEZQdUo3S0pCRGt6TXlGZEEwRzREcXMwTQpqb21abVd6d1BEQ3ZPTjl2dktPK0tTQW5xM1QvRXlKNDNwZFNWUjZEdFZRZ0ErNnV3RTlXM2pmTXczK3FCQ2U3MDNlNFl0c1hmSndvCkloTnpiTThtOVlvcDV3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IEczCj09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ1JqQ0NBYzJnQXdJQkFnSVFDNkZhK2gzZm9MVkpSSy9OSktCczdEQUtCZ2dxaGtqT1BRUURBekJsTVFzd0NRWURWUVFHRXdKVgpVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TUXdJZ1lEClZRUURFeHRFYVdkcFEyVnlkQ0JCYzNOMWNtVmtJRWxFSUZKdmIzUWdSek13SGhjTk1UTXdPREF4TVRJd01EQXdXaGNOTXpnd01URTEKTVRJd01EQXdXakJsTVFzd0NRWURWUVFHRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCMwpkM2N1WkdsbmFXTmxjblF1WTI5dE1TUXdJZ1lEVlFRREV4dEVhV2RwUTJWeWRDQkJjM04xY21Wa0lFbEVJRkp2YjNRZ1J6TXdkakFRCkJnY3Foa2pPUFFJQkJnVXJnUVFBSWdOaUFBUVo1N3lzUkdYdHpiZy9XUHVOc1ZlcFJDMEZGZkx2Qy84UWRKKzFZbEpmWm40ZjVkd2IKUlhrTHpNWlRDcDJOWFFMWnFWbmVBbHIybFNvT2pUaEtpa25Hdk1ZRE9BZGZWZHArQ1c3aWYxN1FSU0FQV1hZUTFxQWs4QzNlTnZKcwpLVG1qUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0dHTUIwR0ExVWREZ1FXQkJUTDBMMnA0WmdGClVhRk5ONktEZWM2TkhTcmtoREFLQmdncWhrak9QUVFEQXdObkFEQmtBakFscElGRkFtc1NTM1YwVDhnajQzRHlkWExlZklud3o1RnkKWVo1ZUVKSlpWcm1EeHhEbk9PbFlKalo5MWVRMGhqa0NNSHcyVS9BdzVXSmpPcG5pdHFNN216VDZIdG9Ra25GZWtST24zYVJ1a3N3eQoxdlVoWnNjdjZwWmphbVZGa3BVQnRBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRGlnaUNlcnQgR2xvYmFsIFJvb3QgRzIKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqakNDQW5hZ0F3SUJBZ0lRQXpyeDVxY1JxYUM3S0dTeEhRbjY1VEFOQmdrcWhraUc5dzBCQVFzRkFEQmhNUXN3Q1FZRFZRUUcKRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCM2QzY3VaR2xuYVdObGNuUXVZMjl0TVNBdwpIZ1lEVlFRREV4ZEVhV2RwUTJWeWRDQkhiRzlpWVd3Z1VtOXZkQ0JITWpBZUZ3MHhNekE0TURFeE1qQXdNREJhRncwek9EQXhNVFV4Ck1qQXdNREJhTUdFeEN6QUpCZ05WQkFZVEFsVlRNUlV3RXdZRFZRUUtFd3hFYVdkcFEyVnlkQ0JKYm1NeEdUQVhCZ05WQkFzVEVIZDMKZHk1a2FXZHBZMlZ5ZEM1amIyMHhJREFlQmdOVkJBTVRGMFJwWjJsRFpYSjBJRWRzYjJKaGJDQlNiMjkwSUVjeU1JSUJJakFOQmdrcQpoa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6Zk5OTng3YThteWFKQ3RTblgvUnJvaENnaU45UmxVeWZ1STIvT3U4anFKCmtUeDY1cXNHR212UHJDM29YZ2trUkxwaW1uN1dvNmgrNEZSMUlBV3NVTGVjWXhwc01OemFIeG14MXg3ZS9kZmd5NVNETjY3c0gwTk8KM1hzczByMHVwUy9rcWJpdE90U1pwTFlsNlp0ckFHQ1NZUDlQSVVrWTkyZVFxMkVHbkkveXV1bTA2Wkl5YTdYelYraGRHODJNSGF1VgpCSlZKOHpVdGx1TkpiZDEzNC90SlM3U3NWUWVwajVXenRDTzdURzFGOFBhcHNwVXd0UDFNVll3blNsY1VmSUtkelhPUzB4WktCZ3lNClVOR1BIZ20rRjZIbUljcjlnK1VRdklPbENzUm5LUFp6RkJROVJuYkRoeFNKSVRSTnJ3OUZES1pKb2JxN25NV3hNNE1waFFJREFRQUIKbzBJd1FEQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCaGpBZEJnTlZIUTRFRmdRVVRpSlVJQmlWNXVOdQo1Zy82K3JrUzdRWVhqemt3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUdCbktKUnZEa2hqNnpIZDZtY1kxWWw5UE1XTFNuL3B2dHNyCkY5K3dYM04zS2pJVE9ZRm5Rb1FqOGtWbk5leUl2L2lQc0dFTU5LU3VJRXlFeHR2NE5lRjIyZCttUXJ2SFJBaUdmelowSkZyYWJBMFUKV1RXOThrbmR0aC9Kc3cxSEtqMlpMN3RjdTdYVUlPR1pYMU5HRmR0b20vRHpNTlUrTWVLTmhKN2ppdHJhbGo0MUU2VmY4UGx3VUhCSApRUkZYR1U3QWo2NEd4SlVURnk4YkpaOTE4ckdPbWFGdkU3RkJjZjZJS3NoUEVDQlYxL01VUmVYZ1JQVHFoNVV5a3c3K1UwYjZMSjMvCml5SzVTOWtKUmFUZXBMaWFXTjBiZlZLZmpsbERpSUdrbmliVmI2M2REY1kzZmUwRGtodmxkMTkyN2p5TnhGMVdXNkxaWm02ek5UZmwKTXJZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMwo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ1B6Q0NBY1dnQXdJQkFnSVFCVlZXdlBKZXBEVTF3NlFQMWF0RmNqQUtCZ2dxaGtqT1BRUURBekJoTVFzd0NRWURWUVFHRXdKVgpVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TQXdIZ1lEClZRUURFeGRFYVdkcFEyVnlkQ0JIYkc5aVlXd2dVbTl2ZENCSE16QWVGdzB4TXpBNE1ERXhNakF3TURCYUZ3MHpPREF4TVRVeE1qQXcKTURCYU1HRXhDekFKQmdOVkJBWVRBbFZUTVJVd0V3WURWUVFLRXd4RWFXZHBRMlZ5ZENCSmJtTXhHVEFYQmdOVkJBc1RFSGQzZHk1awphV2RwWTJWeWRDNWpiMjB4SURBZUJnTlZCQU1URjBScFoybERaWEowSUVkc2IySmhiQ0JTYjI5MElFY3pNSFl3RUFZSEtvWkl6ajBDCkFRWUZLNEVFQUNJRFlnQUUzYWZadTRxNEMvc0xmeUhTOEw2K2MvTXpYUnE4Tk9yZXhwdTgwSlgyOE16UUM3cGhXMUZHZnA0dG4rNk8KWXd3WDdBZHc5YytFTGtDRG5PZy9RVzA3cmRPa0ZGazJlSjBEUSs0UUUyeHkzcTZJcDZGcnRVUE9aOXdqL3dNY28rSStvMEl3UURBUApCZ05WSFJNQkFmOEVCVEFEQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCaGpBZEJnTlZIUTRFRmdRVXM5dElwUG1oeGRpdU5rSE1FV05wCllpbThTOFl3Q2dZSUtvWkl6ajBFQXdNRGFBQXdaUUl4QUsyODhtdy9Fa3JSTFRuRENnbVhjL1NJTm95SUo3dm1pSTFRaGFkaitaNHkKM21hVEQvSE1zUW1QM1d5cittdC9vQUl3T1daYndtU051SjVRM0tqVlNhTHR4OXpSU1g4WEFiaklobzlPaklncnFKcXBpc1hSQUwzNApWT0thNVZ0OHN5Y1gKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0Cj09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmtEQ0NBM2lnQXdJQkFnSVFCWnNiVjU2T0lUTGlPUWU5cDNkMVhEQU5CZ2txaGtpRzl3MEJBUXdGQURCaU1Rc3dDUVlEVlFRRwpFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzZDNjdVpHbG5hV05sY25RdVkyOXRNU0V3Ckh3WURWUVFERXhoRWFXZHBRMlZ5ZENCVWNuVnpkR1ZrSUZKdmIzUWdSelF3SGhjTk1UTXdPREF4TVRJd01EQXdXaGNOTXpnd01URTEKTVRJd01EQXdXakJpTVFzd0NRWURWUVFHRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCMwpkM2N1WkdsbmFXTmxjblF1WTI5dE1TRXdId1lEVlFRREV4aEVhV2RwUTJWeWRDQlVjblZ6ZEdWa0lGSnZiM1FnUnpRd2dnSWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDLzVwQnphTjY3NUYxS1BEQWlNR2t6N01LbkpTN0pJVDN5aXRoWnd1RXAKcHoxWXEzYWF6YTU3RzRRTnhEQWY4eHVrT0JiclZzYVhiUjJyc25ueXloSFM1Ri9XQlR4U0QxSWZ4cDRWcFg2K242bFhGbGxWY3E5bwprM0RDc3JwMW1XcHpNcFRSRUVRUUx0K0M4d2VFNW5RN2JYSGlMUXdiN2lEVnlTQWRZeWt0enV4ZVRzaVQrQ0ZobXpUckJjWmU3RnNhCnZPdkp6ODJzTkVCZnNYcG03bmZJU0tobVYxZWZWRmlPREN1M1Q2Y3cyVmJ1eW50ZDQ2M0pUMTdsTmVjeHk5cVRYdHlPajREYXRwR1kKUUpCNXczakh0ckhFdFdvWU9BTVFqZGpVTjZRdUJYMkk5WUkrRUpGd3ExV0NRVExYMndSekttNlJBWHdoVE5TOHJoc0RkVjE0WnRrNgpNVVNhTTBDL0NOZGFTYVRDNXFtZ1o5MmtKN3loVHptMUVWZ1g5eVJjUm85azk4RnBpSGFZZGoxWlhVSjJoNG1YYVhwSThPQ2lFaHRtCm1uVEsza3NlNXc1anJ1YlU3NUtTT3A0OTNBRGtSU1dKdHBwRUdTdCt3SlMwMG1GdDZ6UFp4ZDlMQkFETWZSeVZ3NC8zSWJLeUViZTcKZi9MVmpIQXNRV0Nxc1dNWVJKVWFkbUorOW9DdysraGtwalBSaVFmaHZiZm1RNlFZdUtaM0FlRVBsQXdoSGJKVUtTV0piT1VPVWxGSApkTDRtckxaQmRkNTZyRitOUDhtODAwRVJFbHZsRUZEck1jWEtjaFlpQ2Q5OFRIVS9ZK3doWDhRZ1VXdHZzYXVHaTAvQzFrVmZuU0Q4Cm9SN0Z3SStpc1g0S0pwbjE1R2t2bUIwdDlkbXBzaDNsR3dJREFRQUJvMEl3UURBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWQKRHdFQi93UUVBd0lCaGpBZEJnTlZIUTRFRmdRVTdOZmpndEp4WFdSTTN5NW5QK2U2bUs0Y0QwOHdEUVlKS29aSWh2Y05BUUVNQlFBRApnZ0lCQUx0aDJYMnBiTDRYeEpFYnc2R2lBSTNqWkdnUFZzOTNybkQ1L1pwS21ibkplRndNREYvazVoUXBWZ3MyU1YxRVkrQ3RuSllZClpoc2pEVDE1NlcxcjFsVDQwanpCUTBDdUhWRDFVdnlRTzd1WW1XbHJ4OEducUdpa0o5eWQrU2V1TUlXNTltZE5PajZQV1RraVUwVHIKeUYwRHl1MVFlbjFpSVFxQXlITm0wYUFGWUYvb3BiU25yNmozYlRXY2ZGcUsxcUk0bWZONGkvUk4waUFMM2dUdWpKdEhnWElOd0JReQo3ekJaTHE3Z2NmSlc1R3FYYjVKUWJaYU5hSHFhc2pZVWVnYnlKTGtKRVZEWENMRzRpWHFFSTJGQ0tlV2p6YUlnUWRmUm5HVFo2aWFoCml4VFhUQm15VUVGeFBUOU5jQ09HREVyY2dkTE1NcFNFRFFnSmx4eFB3TzVySUhRdzB1QTVOQkNGSVJVQkNPaFZNdDV4U2Rrb0YxQk4KNXI1TjBYV3MwTXI3UWJoRHBhclR3d1ZFVHl3Mm0rTDY0a1c0STFOc0JtOW5WWDlHdFV3L2JpaGFlU2JTcEtoaWw5SWU0dTFLaTd3YgovVWRLRGQ5blpuNnlXMEhRTytUME8vUUVZK252d2xRQVVhQ0tLc25PZU16VjZvY0VHTFBPcjBtSXIvT1NtYmF6NW1FUDBvVUE1MUFhCjVCdVZuUm1odVp5eG03RUFIdS9RRDA5Q2JNa0t2TzVEK2pweHBjaE5KcVUxL1lsZHZJVmlIVExTb0N0VTdacFh3ZHY2RU04WnQ0dEsKRzQ4QnRpZVZVK2kyaVcxYnZHalVJK2lMVWFKVytmQ21nS0RXSHJPOER3OVRkU21xNmhOMzVONk1nU0d0QnhCSEVhMkhQUWZSZGJ6UAo4MlorCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjJEQ0NBOENnQXdJQkFnSVFUS3I1eXR0amIrQWY5MDdZV3dPR25UQU5CZ2txaGtpRzl3MEJBUXdGQURDQmhURUxNQWtHQTFVRQpCaE1DUjBJeEd6QVpCZ05WQkFnVEVrZHlaV0YwWlhJZ1RXRnVZMmhsYzNSbGNqRVFNQTRHQTFVRUJ4TUhVMkZzWm05eVpERWFNQmdHCkExVUVDaE1SUTA5TlQwUlBJRU5CSUV4cGJXbDBaV1F4S3pBcEJnTlZCQU1USWtOUFRVOUVUeUJTVTBFZ1EyVnlkR2xtYVdOaGRHbHYKYmlCQmRYUm9iM0pwZEhrd0hoY05NVEF3TVRFNU1EQXdNREF3V2hjTk16Z3dNVEU0TWpNMU9UVTVXakNCaFRFTE1Ba0dBMVVFQmhNQwpSMEl4R3pBWkJnTlZCQWdURWtkeVpXRjBaWElnVFdGdVkyaGxjM1JsY2pFUU1BNEdBMVVFQnhNSFUyRnNabTl5WkRFYU1CZ0dBMVVFCkNoTVJRMDlOVDBSUElFTkJJRXhwYldsMFpXUXhLekFwQmdOVkJBTVRJa05QVFU5RVR5QlNVMEVnUTJWeWRHbG1hV05oZEdsdmJpQkIKZFhSb2IzSnBkSGt3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ1I2RlNTMGdwV3Nhd05KTjNGejBSbgpkSmtyTjZOOUkzQUFjYnhUMzhUNktoS1BTMzhRVnIyZmNISzNZWC9KU3c4WHB6M2pzQVJoN3Y4Umw4ZjBoajRLK2o1YytaUG1OSHJaCkZHdm5uTE9Gb0lKNmRxOXhrTmZzL1EzNm5HejYzN0NDOUJSKytiN0VwaTlQZjVsL3RmeG5RM0s5REFEV2lldHJMTlB0ajVnY0ZLdCsKNWVOdS9OaW81SklrMmtOcllyaFYvZXJCdkd5MmkvTU9qWnJrbTJ4cG1maDRTREJGMWEzaERUeEZZUHd5bGxFbnZHZkR5aTYyYStwRwp4OGNnb0xFZlpkNUlDTHFrVHFueWcwWTNoT3ZveklGSVEyZE9jaXFiWEwxTUd5aUtYQ0o3dEt1WTJlN2dVWVBEQ1VaT2JUNlorcFVYCjJud3pWMEU4alZIdEM3WmNyeXhqR3Q5WHlEKzg2VjNFbTY5Rm1lS2pXaVMwdXFsV1BjOXZxdjlKV0w3d3FQLzB1SzNwTi91NnVQUUwKT3Zub1EwSWVpZGlFeXhQeDJidmhpV0M0akNoV3JCUWRuQXJuY2V2UER0MDlxWmFoU0wwODk2KzFEU0pNd0JHQjdGWTc5dE9pNGx1MwpzZ1FpVXBXQWsybm9qa3hsOFpFRExYQjBBdXFMWnhVcGFWSUN1OWZmVUdwVlJyK2dveWhoZjNEUXc2S3FMQ0dxUjg0b25BWkZkcitDCkdDZTAxYTYweTFEbWEvUk1obkV3NmFiZkZvYmcyUDlBM2Z2UVFvaC9vek02TGx3ZVFSR0JZODRZY1dzcjdLYUt0ekZjT21wSDRNTjUKV2RZZ0dxL3lhcGlxY3J4WFN0SkxuYnNRL0xCTVFlWHRIVDFlS0oyY3pMK3pVZHFuUitXRVV3SURBUUFCbzBJd1FEQWRCZ05WSFE0RQpGZ1FVdTY5K0FqMzZwdkU4aEk2dDdqaVk3Tmt5TXRRd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3CkRRWUpLb1pJaHZjTkFRRU1CUUFEZ2dJQkFBcngxVWFFdDY1UnUyeXlUVUVVQUpOTW5Ndmx3RlRQb0NXT0F2bjlzS0lOOVNDWVBCTXQKckZhaXNOWitFWkxwTHJxZUxwcHlzYjBaUkd4aE5hS2F0QllTYVZxTTRkYytwQnJvTHdQMHJtRWRFQnNxcEl0NnhmNEZwdUhBMXNqKwpucTZQSzdvOW1malljd2xZUm02bW5QVFhKOU9WMmplRGNoelRjK0NpUjVrRE9GM1ZTWGtBS1J6SDdKc2dIQWNrYVZkNHNqbjhPb1NnCnRaeDhqYjh1azJJbnR6bmFGeGl1dlR3SmFQK0VtenpWMWdzRDQxZWVGUGZSNjAvSXZZY2p0N1pKUTNtRlhMcnJrZ3VoeHVob3FFd1cKc1JxWkN1aFRMSks3b1FrWWRReGxxSHZMSTdjYXdpaUZ3eHYvMEN0aTc2UjdDWkdZWjR3VUFjMW9CbXBqSVhVRGdJaUtib0hHaGZLcApwQzNuOUtVa0VFZUR5czMwalhsWXNRYWI1eG9xMlowQjE1Ujk3UU5LeXZEYjZLa0JQdlZXbWNrZWprazl1K1VKdWVCUFNaSTlGb0pBCnpNeFp4dVk2N1JJdWFUeHNsYkg5cWgxN2Y0YStIZzR5UnZ2N0U0OTFmMHlMUzBaai9nQTBRSERCdzdtaDNhWnc0Z1N6UWJ6cGdKSHEKWkp4NjRTSURxWnh1Ync1bFQyeUhoMTd6YnFENWRhV2JRT2hUc2llZFNybkFkeUdOLzRmeTNyeU03eGZmdDBrTDBmSnVNQXNhRGs1Mgo3Ukg4OWVsV3NuMi94MjBLazR5bDBNQzJIYjQ2VHBTaTEyNXNDOEtLZlBvZzg4VGs1YzBOcU11UmtyRjhoZXkxRkdsbURvTG56YzdJCkxhWlJmeUhCTlZPRkJrcGRuNjI3RzE5MAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUYzakNDQThhZ0F3SUJBZ0lRQWYxdE1QeWp5bEdvRzd4a0RqVURMVEFOQmdrcWhraUc5dzBCQVF3RkFEQ0JpREVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDazVsZHlCS1pYSnpaWGt4RkRBU0JnTlZCQWNUQzBwbGNuTmxlU0JEYVhSNU1SNHdIQVlEVlFRSwpFeFZVYUdVZ1ZWTkZVbFJTVlZOVUlFNWxkSGR2Y21zeExqQXNCZ05WQkFNVEpWVlRSVkpVY25WemRDQlNVMEVnUTJWeWRHbG1hV05oCmRHbHZiaUJCZFhSb2IzSnBkSGt3SGhjTk1UQXdNakF4TURBd01EQXdXaGNOTXpnd01URTRNak0xT1RVNVdqQ0JpREVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDazVsZHlCS1pYSnpaWGt4RkRBU0JnTlZCQWNUQzBwbGNuTmxlU0JEYVhSNU1SNHdIQVlEVlFRSwpFeFZVYUdVZ1ZWTkZVbFJTVlZOVUlFNWxkSGR2Y21zeExqQXNCZ05WQkFNVEpWVlRSVkpVY25WemRDQlNVMEVnUTJWeWRHbG1hV05oCmRHbHZiaUJCZFhSb2IzSnBkSGt3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ0FFbVVYTmc3RDJ3aXoKMEt4WERYYnR6U2ZUVEsxUWcySGlxaUJOQ1Mxa0Nkek9pWi9NUGFuczlzL0IzUEhUc2RaN055Z1JLMGZhT2NhOE9obTBYNmE5ZloyagpZMEsyZHZLcE95dVIrT0p2ME93V0lKQUpQdUxvZE1rWXRKSFVZbVRiZjZNRzhZZ1lhcEFpUEx6K0UvQ0hGSHYyNUIrTzFPUlJ4aEZuClJnaFJ5NFlVVkQrOE0vNStiSnovRnAwWXZWR09OYWFuWnNoeVo5c2hackhVbTNnRHdGQTY2TXp3M0x5ZVRQNnZCWlkxSDFkYXQvL08KK1QyM0xMYjJWTjNJNXhJNlRhNU1pcmRjbXJTM0lEM0tmeUkwcm40N2FHWUJST2NCVGtaVG16Tmc5NVMrVXplUWMwUHpNc05UNzl1cQovblJPYWNkcmpHQ1Qzc1RIRE4vaE1xN01renRSZUpWbmkrNDlWdjRNMEdrUEd3L3pKU1pyTTIzM2JrZjZjMFBsZmc2bFpyRXBmREtFClkxV0p4QTNCazFRd0dST3MwMzAzcCt0ZE9tdzFYTnRCMXhMYXFVa0wzOWlBaWdtVFlvNjFaczhsaU0yRXVMRS9wRGtQMlFLZTZ4Sk0KbFh6emF3V3BYaGFEekxobjR1Z1RuY3hiZ3ROTXMrMWIvOTdsYzZ3ak95MEF2elZWZEFsSjJFbFlHbitTTnVaUmtnN3pKbjBjVFJlOAp5ZXhESnRDL1FWOUFxVVJFOUpublY0ZWVVQjlYVktnKy9YUmpMN0ZRWlFubVdFSXVReHBNdFBBbFIxbjZCQjZUMUNaR1NsQ0JzdDYrCmVMZjhaeFhoeVZlRUhnOWoxdWxpdXRaZlZTN3FYTVlvQ0FRbE9iZ09LNm55VEpjY0J6OE5Vdlh0N3krQ0R3SURBUUFCbzBJd1FEQWQKQmdOVkhRNEVGZ1FVVTNtL1dxb3JTczlVZ09IWW04Q2Q4cklEWnNzd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRgpNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRU1CUUFEZ2dJQkFGelVmQTNQOXdGOVFabGxESFBGVXAvTCtNK1pCbjhiMmtNVm41NENWVmVXCkZQRlNQQ2VIbENqdEh6b0JONkoyL0ZOUXdJU2J4bXRPdW93aFQ2S09WV0tSODJrVjJMeUk0OFNxQy8zdnFPbExWU29HSUcxVmVDa1oKN2w4d1hFc2tFVlgvSkpwdVhpb3I3Z3RObjMvM0FUaVVGSlZEQnduN1lLbnVIS3NTaktDYVhxZVlhbGx0aXo4SSs4alJSYThZRldTUQpFZzl6S0M3RjRpUk8vRmpzOFBSRi9pS3o2eStPMHRsRllRWEJsMitvZG5LUGk0dzJyNzhOQmM1eGplYW1ieDlzcG5GaXhkalFnM0lNCjhXY1JpUXljRTB4eU5OKzgxWEhmcW5IZDRibHNqRHdTWFdYYXZWY1N0a05yLytYZVRXWVJVYytacnV3WHR1aHhrWXplU2Y3ZE5YR2kKRlNlVUhNOWg0eWE3YjZObkpTRmQ1dDBkQ3k1b0d6dUNyK3lEWjRYVW1GRjBzYm1aZ0luL2YzZ1pYSGxLWUM2U1FLNU1OeW9zeWNkaQp5QTVkOXpaYnl1QWxKUUcwM1JvSG5IY0FQOURjMWV3OTFQcTdQOHlGMW05L3FTM2Z1UUwzOVplYXRUWGF3MmV3aDBxcEtKNGpqdjljCkoydmhzRS96Qis0QUx0UlpoOHRTUVpYcTlFZlg3bVJCVlh5TldRS1YzV0tkd3JudVdpaDBoS1didDVESERBZmY5WWsyZERMV0tNR3cKc0F2Z25FekRITmI4NDJtMVIwYUJMNktDcTlOalJIREVqZjh0TTdxdGozdTFjSWl1UGhuUFFDalkvTWlRdTEyWkl2VlM1bGpGSDRneApRKzZJSGRmR2pqeERhaDJuR041OVBSYnhZdm5La0tqOQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNqekNDQWhXZ0F3SUJBZ0lRWEl1WnhWcVV4ZEp4VnQ3TmlZRE1KakFLQmdncWhrak9QUVFEQXpDQmlERUxNQWtHQTFVRUJoTUMKVlZNeEV6QVJCZ05WQkFnVENrNWxkeUJLWlhKelpYa3hGREFTQmdOVkJBY1RDMHBsY25ObGVTQkRhWFI1TVI0d0hBWURWUVFLRXhWVQphR1VnVlZORlVsUlNWVk5VSUU1bGRIZHZjbXN4TGpBc0JnTlZCQU1USlZWVFJWSlVjblZ6ZENCRlEwTWdRMlZ5ZEdsbWFXTmhkR2x2CmJpQkJkWFJvYjNKcGRIa3dIaGNOTVRBd01qQXhNREF3TURBd1doY05Nemd3TVRFNE1qTTFPVFU1V2pDQmlERUxNQWtHQTFVRUJoTUMKVlZNeEV6QVJCZ05WQkFnVENrNWxkeUJLWlhKelpYa3hGREFTQmdOVkJBY1RDMHBsY25ObGVTQkRhWFI1TVI0d0hBWURWUVFLRXhWVQphR1VnVlZORlVsUlNWVk5VSUU1bGRIZHZjbXN4TGpBc0JnTlZCQU1USlZWVFJWSlVjblZ6ZENCRlEwTWdRMlZ5ZEdsbWFXTmhkR2x2CmJpQkJkWFJvYjNKcGRIa3dkakFRQmdjcWhrak9QUUlCQmdVcmdRUUFJZ05pQUFRYXJGUmFxZmxvSStkNjFTUnZVOFphMkV1cnh0VzIKMGVaemNhN2RuTllNWWYzYm9Ja0R1QVVVN0ZmTzdsMC80aUd6enZmVWlubmdvNE4rTFpmUVljVHhtZHdsa1dPcmZ6Q2p0SERpeDZFegpuUE8vTGx4VHNWK3pmVEovaWpUamVYbWpRakJBTUIwR0ExVWREZ1FXQkJRNjRRbUcxTThad3BaMmRFbDIzT0ExeG1Oam1qQU9CZ05WCkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QUtCZ2dxaGtqT1BRUURBd05vQURCbEFqQTJaNkVXQ056a2x3QkIKSFU2KzRXTUJ6enVxUWhGa29KMlVPUUlSZVZ4N0hmcGt1ZTRXUXJPL2lzSUp4T3prc1UwQ01RRHBLbUZIakZKS1MwNFljUGJXUk5adQo5WU82YlZpOUpObFdTT3J2eEtKR2dZaHFPa2JScVp0TnlXSGEwVjFYYWhnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQKPT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlCNFRDQ0FZZWdBd0lCQWdJUktqaWtISllLQk41Q3NpaWxDK2cwbUFJd0NnWUlLb1pJemowRUF3SXdVREVrTUNJR0ExVUVDeE1iClIyeHZZbUZzVTJsbmJpQkZRME1nVW05dmRDQkRRU0F0SUZJME1STXdFUVlEVlFRS0V3cEhiRzlpWVd4VGFXZHVNUk13RVFZRFZRUUQKRXdwSGJHOWlZV3hUYVdkdU1CNFhEVEV5TVRFeE16QXdNREF3TUZvWERUTTRNREV4T1RBek1UUXdOMW93VURFa01DSUdBMVVFQ3hNYgpSMnh2WW1Gc1UybG5iaUJGUTBNZ1VtOXZkQ0JEUVNBdElGSTBNUk13RVFZRFZRUUtFd3BIYkc5aVlXeFRhV2R1TVJNd0VRWURWUVFECkV3cEhiRzlpWVd4VGFXZHVNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUV1TVo1MDQ5c0pRNmZMamtaSEFPa3JwcmwKT1FjSkZzcGpzYm1HK0lwWHdWZk9RdnB6b2ZkbFF2OGV3UUN5Ym5NTy84Y2g1UmlrcXRseFA2alV1YzZNSGFOQ01FQXdEZ1lEVlIwUApBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGRlN3ZTYxRnVPSkFmL3NLYnZ1K004azhvNFRWCk1Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lRRGNrcUdnRTZiUEE3RG14Q0dYa1BvVVZ5MEQ3TzQ4MDI3S3FHeDJ2S0xldXdJZ0o2aUYKSnpXYlZzYWo4a2ZTdDI0YkFnQVhxbWVtRlpIZStwVHNld3Y0bjRRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjUKPT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDSGpDQ0FhU2dBd0lCQWdJUllGbEo0Q1l1dTFYNUNuZUtjZmxLMkd3d0NnWUlLb1pJemowRUF3TXdVREVrTUNJR0ExVUVDeE1iClIyeHZZbUZzVTJsbmJpQkZRME1nVW05dmRDQkRRU0F0SUZJMU1STXdFUVlEVlFRS0V3cEhiRzlpWVd4VGFXZHVNUk13RVFZRFZRUUQKRXdwSGJHOWlZV3hUYVdkdU1CNFhEVEV5TVRFeE16QXdNREF3TUZvWERUTTRNREV4T1RBek1UUXdOMW93VURFa01DSUdBMVVFQ3hNYgpSMnh2WW1Gc1UybG5iaUJGUTBNZ1VtOXZkQ0JEUVNBdElGSTFNUk13RVFZRFZRUUtFd3BIYkc5aVlXeFRhV2R1TVJNd0VRWURWUVFECkV3cEhiRzlpWVd4VGFXZHVNSFl3RUFZSEtvWkl6ajBDQVFZRks0RUVBQ0lEWWdBRVIwVU9sdnQ5WGIvcE9kRWgrSjhMdHRWN0hwSTYKU0ZrYzhHSXhMY0I2S1A0YXAxeXp0c3lYNTBYVVdQclJkMjFEb3NDSFpUUUtIM3JkNnp3em9jV2RUYVJ2UVpVNGY4a2VoT3ZSbmttUwpoNVNIRERxRlNtYWZuVm1UVFpkaEJvWktvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkCkJnTlZIUTRFRmdRVVBlWXBTSnZxQjhvaFJFb20zbTdlMG9QUW4xa3dDZ1lJS29aSXpqMEVBd01EYUFBd1pRSXhBT1ZwRXNsdTI4WXgKdWdsQjRaZjQrLzJhNG4wU3llMThaTlBMQlNXTFZ0bWc1MTVkVGd1RG5GdDJLYUFKSmlGcVlnSXdjZEsxajF6cU8rRjRDWVdvZFpJNwp5Rno5U084TmRDS29DT0p1eFVuT3h3eThwMkZwOGZjNzRTckwrU3Z6WnBBMwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTdGFhdCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZkRENDQTF5Z0F3SUJBZ0lFQUppaU9UQU5CZ2txaGtpRzl3MEJBUXNGQURCYU1Rc3dDUVlEVlFRR0V3Sk9UREVlTUJ3R0ExVUUKQ2d3VlUzUmhZWFFnWkdWeUlFNWxaR1Z5YkdGdVpHVnVNU3N3S1FZRFZRUUREQ0pUZEdGaGRDQmtaWElnVG1Wa1pYSnNZVzVrWlc0ZwpVbTl2ZENCRFFTQXRJRWN6TUI0WERURXpNVEV4TkRFeE1qZzBNbG9YRFRJNE1URXhNekl6TURBd01Gb3dXakVMTUFrR0ExVUVCaE1DClRrd3hIakFjQmdOVkJBb01GVk4wWVdGMElHUmxjaUJPWldSbGNteGhibVJsYmpFck1Da0dBMVVFQXd3aVUzUmhZWFFnWkdWeUlFNWwKWkdWeWJHRnVaR1Z1SUZKdmIzUWdRMEVnTFNCSE16Q0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUw0eQpvbFFQY1Bzc1hGbnJiTVNrVWVpRktyUE1TalR5c0YvekRzY2NQVk1laUFobzJHODlyY0tleklKbkJ5ZUhhSEU2bjNXV0lrWUZzTzJ0CngxdWVLdDZjL0RyR2xhZjFGMmNZNXk5SkNBeGN6K2JNTk8xNCsxQ3gzR3N5OEtMK3Rqems3RnFYeHo4ZWNBZ3dvTnpGczIxdjBJSnkKRWF2U2dXaFpnaGUzZUpKZytzemVQNFRyalRnemtBcHlJL28xekNaeE1kRnlLSkxaV3lOdFpyVnRCMExycGpQT2t0dkE5bXhqZU0zSwpUajIxNVZLYjhiNDc1bFJnc0dZZUNhc0gvbFNKRVVMUjl5UzZZSGdhbVBmSkVmMFd3VFVhVkhYdlE5UGxyazdPNTN2RHhrNWhVVXVyCm1rVkxvUjlCdlVoVEZYRmtDNGF6NVM2K3pxUWJ3U21Fb3JYTENDTjJReUlrSHhjRTFHNmN4dngvSzJZYTdJcmwxczlOOVdNSnR4VTUKMW51czYrTjg2VTc4ZFVMSTdWaVZEQVpDb3B6MzVIQ3ozM0p2V2pkQWlkaUZwTmZ4Qzk1REdkUktXQ3lNaWptZXY0U0g4Ulk3Tmd6cAowN1RLYkJsQlVnbWhIYkJxdjRMdmNGRWhNdHdGZG96TDkyVGtBMUN2akpGbnE4WHk3bGpZM3I3MzV6SFBiTWs3Y2NIVmlMVmx2TURvCkZ4Y0hFclZjMHFzZ2s3VG1nb053TnNYTm80MnRpK3lqd1VPSDVrUGlOTDZWaXpYdEJ6bmFxQjE2bnphZUVyQU1aUktRRldEWkprQkUKNDFaZ3BSRFVhano5UWR3T1drZTI3NWRoZFUvWi9zZXlIZFR0WFVtenFXckxab1FUMVZ5ZzNOOXVkd2JSY1hYSVYyK3ZEM2RiQWdNQgpBQUdqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJSVXJmckhrbGV1CnlqV2NMaEw3NUxwZElOeVVWekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBTUptZEJUTElYZzQ3bUFFNmlxVG5CL2Q2K09lYTMxQkQKVTVjcVBjbzhSNWd1NFJWNzhaTHpZZHFRSlJabHdKOVVYUTRETzF0M0FweUV0ZzJZWHpUZE8yUEN3eWlCd3B3cExpbml5TU1COGpQcQpLcXJNQ1FqM1pXZkd6ZC9UdGl1bnZjelJEbkJmdUNQUnk1Rk9DdlRJZXVYWll6YkIxTi84SXBmM1lGM3FLUzlZc3IxWXZZMldUeEIxCnYwaDdQVkdIb1R4MElzTDhCMytBM01Tcy9tckJjREN3Nlk1cDRpeHBnWlFKdXQzK1RjQ0RqSlJZd0VZZ3I1d2ZBdmcxVlVrdlJ0VEEKOEtDV0FnOHp4WEh6bmlOOWxMZjlPdE1KZ3dZaC9XQTlyakxBMHU2TnB2RG50SUo4Q3N4d3lYbUErUDVNOXpXRUdZb3grd3JaMTMrYgo4S0thYThNRlN1MUJZQlF3MGFvUlFtN1RJd0lFQzhabDNkMVNkOXFCYTdLbytnRTR1WmJxS214bmw0bVVucnpoVk5Ya2FuanZTcjByCm1qMUFmc2JBZGRKdSsyZ3c3T3lMbmZsSk5ab2FMTm16bFRuVkhwTDNwcmxsTCtVOWJUcElUQWpjNUNnU0tMNTlOVnpxNEJaK0V4dHEKMXo3WG52d3RkYkxCRk5VakE5dGJid3MrZUM4TjNqT05GcmRJNTRPYWdROTd3VU5OVlFRWE9FcFIxVm1paVhUVG43NGVTOWZHYmJlSQpKRzlna2FTQ2hWdFdRYnpRUkt0cUU3N1JMRmkzRWpOWXNqZGozQlAxbEIwL1FGSDFUL1U2N2NqRjY4SWVIUmFWZXNkK1FuR1Ria3NWCnR6RGZxdTFYaFVpc0hXcmRPV25rNFhsNHZzNEZ2NkVNOTRCN0lXY25NRms9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBSb290IENBCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGY0RDQ0ExaWdBd0lCQWdJRUFKaVdqVEFOQmdrcWhraUc5dzBCQVFzRkFEQllNUXN3Q1FZRFZRUUdFd0pPVERFZU1Cd0dBMVVFCkNnd1ZVM1JoWVhRZ1pHVnlJRTVsWkdWeWJHRnVaR1Z1TVNrd0p3WURWUVFERENCVGRHRmhkQ0JrWlhJZ1RtVmtaWEpzWVc1a1pXNGcKUlZZZ1VtOXZkQ0JEUVRBZUZ3MHhNREV5TURneE1URTVNamxhRncweU1qRXlNRGd4TVRFd01qaGFNRmd4Q3pBSkJnTlZCQVlUQWs1TQpNUjR3SEFZRFZRUUtEQlZUZEdGaGRDQmtaWElnVG1Wa1pYSnNZVzVrWlc0eEtUQW5CZ05WQkFNTUlGTjBZV0YwSUdSbGNpQk9aV1JsCmNteGhibVJsYmlCRlZpQlNiMjkwSUVOQk1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBNDhkK2lma2sKU3pyU000TTFMR25zM0FtazQxR29KU3Q1dUFnOTRKRzZoSVhHaGFUSzVza3VVNlRKSkI3OVZXWnhYU3pGWUdnRXQ5bkNVaVk0aUtUVwpPMENtd3MwL3paaVRzMVFVV0paVjFWRCtocTJrWTM5Y2gvYU81aWVTWnhlU0FnTXMzTlptZE8zZFovL0JZWTFqVHcrYmJSY3dKdStyCjBoOFFvUG5GZnhacGdRTkg3UjVvalhLaFRiSW14cnBzWDIzV3I5R3hFNDZwcmZOZWFYVW1HRDVCS3lGLzdvdGRCd2FkUThRcENpdjgKS2o2R3l6eURPdm5KRGRyRm1lSzhlRUV6ZHVHL0wxM2xwSmhRREJYZDRQcWNmemhvMExLbWVxZlJNYjEraWxnblE3TzZNNUhUcDVnVgpYSnJtMHc5MTJmeEJtSmMrcWlYYmo1SXVzSHNNWC9GanFUZjVtM1ZwVENnbUpkclY4aEp3UlZYajMzTmVOL1VoYkpDT05WckoweVByCjA4QytlS3hDS0ZobXBVWnRjQUxYRVBsTFZQeGRoa3FIejMvS1Jhd1JXclVnVVkwdmlFZVhPY0RQdXNCQ0FVQ1pTQ0VMYTZmUy9aYlYKMGI1R25VbmdDNmFnSWs0NDBNRThNTHh3anl4MXpOREZqRkU3UFpRSVpDWmhmYm5EWlk4VW5DSFFxdjBYY2dPUHZadU01bDVUbnJtZAo3NEs3NGJ6aWNrRmJJWlRUUlRlVTBkOEpPVjNuSTZxYUhjcHRxQXFHaFlxQ3ZrSUgxdkk0Z25QYWgxdmxQTk9lUHFjN252UURzL254CmZSTjBBdis3b2VYNkFIa2NwbVpCaUZ4Z1Y2WXVDY1M2L1pyUHB4OUF3N3ZNV2dwVlN6czRkbEc0WTR1RWxCYm1Wdk1DQXdFQUFhTkMKTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFRlA2ckFKQ1luaVQ4cWN3YQppdnNudUw4d2JxZzdNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUURQZHl4dVZyNU9zN2FFQUpTclI4a04wbmJIaHA4ZEI5TzJ0THNJCmVLOXAwZ3RKM2pQRnJLM0NpQUo5QnJjMUFzRmd5Yi9FNkpUZTFOT3BFeVZhL202aXJuMEYzSDN6YlBCK3BvM3UyZGZPV0Jmb3FTbXUKYzBpSDU1dktiaW1oWkY4WkUvZXVCaEQvVWNhYlRWVWxUNU9aRUFGVGRmRVR6c2VtUVVIU3Y0aWxmMFg4ckxpbHRUTU1nc1Q3Qi9acQo1U1dFWHdiS3dZWTVFZHRZelhjN0xNSk1EMTZhNC9DclBtRWJVQ1RDd1BUeEdmQVJLYmFsR0FLYjEyTk1jSXhIb3dORFhMbGRScUFOCmIvOVpqcjdkbjNMRFd5dmZqRnZPNVF4R2JKS3lDcU5NVkVJWUZSSVl2ZHI4dW5SdS84RzJvR1RZcVY5VnJwOWNhbmFXMkhObmgvdE4KZjF6dWFjcHpFUHVLcWYyZXZUWTRTVW1IOUE0VThPbUh1RCtuVDNwYWpublVrK1M3YUZLRXJHenA4NWh3VlhJeStUU3JLMG0xelNCaQo1RHA2WjJPcmx0eHRycGZzL0o5MlZvZ3VaczlidHNta3NOY0Z1dUVuTDVPN0ppcWlrN0FiODQ2K0hVQ2p1VGFQUG9JYUdsNkk2bEQ0CldlS0RSaWtMNDBSYzRaVzJhWkNhRkcrWHJvSFBhTytabXI2MTUrRi8rUG9UUnhaTXpHMElRT2VMZUc5UWdrUlFQMllHaXF0RGhGWksKRHlBdGhnNzEwdHZTZW9wTHphWG9UdkZlSmlVQldTT2dmdEwyZmlGWDF5ZThGVmRNcEViQjRJTWVERXhOSDA4R0dlTDVxUFE2Z3FHeQplVU41MXExdmVpZVFBNlRxSkljLzJiM1o2ZkpmVUVrYzd1elhMZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCklkZW5UcnVzdCBDb21tZXJjaWFsIFJvb3QgQ0EgMQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZZRENDQTBpZ0F3SUJBZ0lRQ2dGQ2dBQUFBVVVqeUVTMUFBQUFBakFOQmdrcWhraUc5dzBCQVFzRkFEQktNUXN3Q1FZRFZRUUcKRXdKVlV6RVNNQkFHQTFVRUNoTUpTV1JsYmxSeWRYTjBNU2N3SlFZRFZRUURFeDVKWkdWdVZISjFjM1FnUTI5dGJXVnlZMmxoYkNCUwpiMjkwSUVOQklERXdIaGNOTVRRd01URTJNVGd4TWpJeldoY05NelF3TVRFMk1UZ3hNakl6V2pCS01Rc3dDUVlEVlFRR0V3SlZVekVTCk1CQUdBMVVFQ2hNSlNXUmxibFJ5ZFhOME1TY3dKUVlEVlFRREV4NUpaR1Z1VkhKMWMzUWdRMjl0YldWeVkybGhiQ0JTYjI5MElFTkIKSURFd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUNuVUJuZVA1azkxRE5HOFc5UllZS3lxVStQWjRsZApoTmxUM1F3bzJkZncvNjZWUTNLWitiVmRmSXJCUXVFeFVIVFJnUTE4elpzaHEwUGlySzFlaG03ekNZb2ZXaks5b3V1VStlaGNDdXovCm1OS3ZjYk8wVTU5T2grK1N2TDNzVHpJd2lFc1hYbGZFVThMMkFwZU4yV0lydnlRZllvM2Z3N2dwUzBsNFBKTmdpQ0w4bWRvMnlNS2kKMUN4VUFHYzFibk8vQWxqd3BOM2xzS0ltZXNyZ05xVVpGdlg5dCsrdVAwRDFiVm9FL2M0MHlpVGNkQ01iWFRNVEVsM0VBU1gyTU4wQwpYWi9nMVVlOXRPc2JvYnRKU2RpZld3THppdVFra09SaVQwL0JyNHNPZEJlbzBYS0lhbm9CU2N5MFJubkdGN0hhbUI0SFdmcDFJWVZsCjNaQld6dnVycFdDZHhKMzVVckNMdllmNWp5c2pDaU4yTy9jejRja0E4Mm41UzZMZ1RyeCtrem1FQi9kRWNINytCMXJsc2F6UkdNenkKTmVWSlNRaktWc2s5K3c4WWZZczd3UlBDVFkvSlR3NDM2UitoRG1yZllpN0xOUVpSZVN6SUpUajAra3VuaVZ5YzB1TU5PWVpLZEh6VgpXWWZDUDA0TVhGTDBQZmRTZ3ZIcW82ejlTVFFhS1BOQmlEb1Q3dWplLzVrZFg3ckw2Qjd5dVZCZ3dESFRjK1h2dnFEdE13dDB2aUFnCnhHZHM4QWdEZWxXQWYwWk9scWYwSGo3aDl0Z0o0VE5rSzJQWE1sNmYrY0I3RDNodmw3eVRtdm1jRXBCNGVvQ0hGZGR5ZEp4VmRIaXgKdXVGdWNBUzZUNkM2YU1ONy96SHdjejA5bENxeEMwRU9vUDVOaUdWcmVUTzAxd0lEQVFBQm8wSXdRREFPQmdOVkhROEJBZjhFQkFNQwpBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVN1VRWndOUHdCb3Z1cEh1K1F1Y21WTWlPTm5Zd0RRWUpLb1pJCmh2Y05BUUVMQlFBRGdnSUJBQTJ1a0RMMnBrdDhSSFlaWVI0bktNMWVWTzhsdk9NSWtQa3AxNjVvQ09HVUFGanZMaTUrVTFLTXRsd0gKNm9pNm1ZdFFsTmVDZ045aENRQ1RyUTBVNXM3QjhqZVVlTEJmbkxPaWM3aVBCWk00elkwK3NMajd3TSt4OHV3dExSdk03S3FhczZwZwpnaHN0TzhPRVBWZUtsaDZjZGJqVE1NMWdDSU9RMDQ1VThVMW13RjEwQTBDajdvVit3aDkzbkFib3dhY1lYVktWN2NuZEpaNXQrcW50Cm96bzAwRmw3MnUxUTh6Vy83ZXNVVFRISFlQVGE4WWVjNGtqaXhzVTMrd1lRK25WWlpqRkhLZHAybWh6cGdxN3ZtcmxSOTRnam1tbVYKWWp6bFZZQTIxMVFDLy9HNVhjN1VJMi9ZUllSS1cyWHZpUXpkRktjZ3l4aWxKYlFOK1FId290TDBBTWgwanFFcVNJNWwyeFBFNGlVWApmZXUraDFzWElGUlJrMHBUQXd2c1hjb3o3V0w5UmNjdlc5eFlvSUE1NXZyWC9oTVVwdTA5bEVwQ2ROVERkMWx6elk5R3ZsVTQ3L3JvCmtUTHFsMWdFSXQ0NHc4eThiY2t6T21vS2FUK2d5T3B5ajR4amhpTzliVHlXbnBYZ1NVeXFvcmtxRzV3MmdYanR3K2hHNGlaWlJIVWUKMlhXSlVjMFFoSjFoWU10ZCtaY2lUWTZZNXVOLzlsdTdyczNLU29GclhndnpVZUYwSytsK0o2ZlptVWxPK0tXQTJ5VVBIR05paXNregpaMnM4RUlQR3JkNm96UmFPamZBSE4zR2Y4cXY4UWZYQmkrd0FOMTBKNVU2QTcvcXhYRGdHcFJ0SzRkdzRMVHpjcXgrUUd0VktuTzdSCmNHek03dlJYK0JpNmhHNkgKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKSWRlblRydXN0IFB1YmxpYyBTZWN0b3IgUm9vdCBDQSAxCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRlpqQ0NBMDZnQXdJQkFnSVFDZ0ZDZ0FBQUFVVWp6MFo4QUFBQUFqQU5CZ2txaGtpRzl3MEJBUXNGQURCTk1Rc3dDUVlEVlFRRwpFd0pWVXpFU01CQUdBMVVFQ2hNSlNXUmxibFJ5ZFhOME1Tb3dLQVlEVlFRREV5RkpaR1Z1VkhKMWMzUWdVSFZpYkdsaklGTmxZM1J2CmNpQlNiMjkwSUVOQklERXdIaGNOTVRRd01URTJNVGMxTXpNeVdoY05NelF3TVRFMk1UYzFNek15V2pCTk1Rc3dDUVlEVlFRR0V3SlYKVXpFU01CQUdBMVVFQ2hNSlNXUmxibFJ5ZFhOME1Tb3dLQVlEVlFRREV5RkpaR1Z1VkhKMWMzUWdVSFZpYkdsaklGTmxZM1J2Y2lCUwpiMjkwSUVOQklERXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDMklwVDhwRWl2NkVkckN2c25kdVR5ClA0bzdla29zTVNxTWpiQ3B3ekZycUhkMmhDYTJySUZDRFFqclZWaTdldmk4WlgzeW9HMkxxRWZwWW5ZZUVlNElGTkd5UkJiMDZ0RDYKSGk5ZTI4dHpRYTY4QUxCS0swQ3lyT0U3UzhJdG5lU2htK3dhT2g3d0NMUFE1Q1ExQjUrY3RNbFNiZHNIeW8rMVcvQ0Q4MC9ITGFYSQpyY3VWSUtReEtGZFlXdVNORzVxcm5nME04Z296T1NJNUNwY3U4MU4zdVVSRi9ZVExOaUNCV1MyYWIyMUlTR0hLVE45VDBhOVN2RVNmCnF5OXJnM0x2ZFlEYUJqTWJYY2phWThaTnpheG1NYzNSM2o2SEVEYmh1YVI2NzJCUXNzdktwbGJnTjYrck5CTTVKZWc1WnVTWWVxb1MKbUp4WlpvWStyZkd3eWo0R0QzdndFVXMzb0VSdGU4dW9qSEgwMWJXUk5zendGY1lyM2xFWHNaZE1VRDJ4bFZsOEJYMHRJZFVBdndGbgpvbDU3cGx6eTl5THhrQTJUMjZwRVVXYk1mWFlENjJxb0tqZ1psM1lOYTRwaCtiejI3bmI5Y0N2ZEtUejRDaDViUWh5TFZpOVZHeHloCkxyWEhGdWI0cWp5U2ptbTJBY0cxaHAySkR3czRsRlRvNnR5ZVBTVzhVeWJ0MWFzNXFzVkFURlNyc3JUWjJmalhjdHNjdkcyOVpWL3YKaURVcVppL3U5ck5sOERPTmZKaEJhVVlQUXh4cCtwdTEwR0ZxemNwTDJVeVFScXNWV2FGSFZDa3VneWhmSE1LaXEzSVhBQWFPUmV5TAo0ak05ZjlvWlJPUmljc1BmSXNieVZ0VGRYNVZ5N1cxZjkwZ0RXLzNGS3FEMmN5T0VFQnNCNXdJREFRQUJvMEl3UURBT0JnTlZIUThCCkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTQzSGdudGluUXRuYmNaRnJsSlBydzZQUkZLTXcKRFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUVmNjNRcXdFWkU0clUxZDkrVU9sMVFaZ2tpSFZJeXFaSm5ZV3Y2SUFjVllwWm14STFRagp0Mm9kSUZmbEFXSkJGOU1KMjNYTGJsU1FkZjRhbjRFS3d0M1g5d25RVzNJVjVCNEphajB6OHlHYTVoVityVkhWRFJEdGZVTEFqKzdBCm1nalZRZFpjRGlGcGJvQmhEaFhBdU0vRlNSSlN6TDQ2ek5RdU9BWGVOZjBmYjdpQWFKZzlUYURLUUdYU2MzejFpOWtLbFQvWVB5TnQKR3RFcUpCblpoYk1YNzNodXFWalJJOVBIRSsxeUpYOWRzWE53MEg4R2x3bUVLWUJoSGZwZS8zT3NvT09KdUJ4eEZjYmVNWDhTM09GdAptNi9uNko5MWVFeXJSanVhenI4RkdGMU5GVHdXbWhsUUJKcXltbTlsaTFKZlBGZ0VLQ1hBWm1FeGZybmdkYmthcUlIV2NoZXp4UU14Ck5SRjRlS0xnNlRDTWY0RGZXTjg4dWllVzRvQTBiZU9ZMDJRbnJFaCtLSGRjeGlWaEpmaUZER1g2eERJdnBaZ0Y1UGdMWnhZV3hvSzQKTWhuNStibDUzQi9ONjYrckR0MGIyMFhrZXVjQzRwVmQvR253VTJsaGxYVjVDMTVWNWpnY2xLbFpNNTdJY1hSNWYxR0p0c2hxdURESQphampEYnA3aE54YnFCV0pNV3hKSDdhZTBzMWhXeDBuemZ4Sm9DVEZ4OEczNFRrZjcxb1h1eFZoQUdhUWRwL2xMUXpmY2FGcFB6K3ZDClpIVGV0QlhaOUZSVUdpOGMxNWR4VkpDTzJTQ2RVeXQvcTQvaTZqQzhVRGZ2OFVlMWZYd3NCT3hvbmJSSlJCRDBja3NjWk9mODVtdVEKM1dsOWFmMEFWcVczckxhdHQ4bytBZStjCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFUGpDQ0F5YWdBd0lCQWdJRVNsT01LREFOQmdrcWhraUc5dzBCQVFzRkFEQ0J2akVMTUFrR0ExVUVCaE1DVlZNeEZqQVVCZ05WCkJBb1REVVZ1ZEhKMWMzUXNJRWx1WXk0eEtEQW1CZ05WQkFzVEgxTmxaU0IzZDNjdVpXNTBjblZ6ZEM1dVpYUXZiR1ZuWVd3dGRHVnkKYlhNeE9UQTNCZ05WQkFzVE1DaGpLU0F5TURBNUlFVnVkSEoxYzNRc0lFbHVZeTRnTFNCbWIzSWdZWFYwYUc5eWFYcGxaQ0IxYzJVZwpiMjVzZVRFeU1EQUdBMVVFQXhNcFJXNTBjblZ6ZENCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlDMGdSekl3CkhoY05NRGt3TnpBM01UY3lOVFUwV2hjTk16QXhNakEzTVRjMU5UVTBXakNCdmpFTE1Ba0dBMVVFQmhNQ1ZWTXhGakFVQmdOVkJBb1QKRFVWdWRISjFjM1FzSUVsdVl5NHhLREFtQmdOVkJBc1RIMU5sWlNCM2QzY3VaVzUwY25WemRDNXVaWFF2YkdWbllXd3RkR1Z5YlhNeApPVEEzQmdOVkJBc1RNQ2hqS1NBeU1EQTVJRVZ1ZEhKMWMzUXNJRWx1WXk0Z0xTQm1iM0lnWVhWMGFHOXlhWHBsWkNCMWMyVWdiMjVzCmVURXlNREFHQTFVRUF4TXBSVzUwY25WemRDQlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVJQzBnUnpJd2dnRWkKTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDNmhMWnkyNTRNYStLWjZUQUJwM2JxTXJpVlFSckoybUZPV0hMUAovdmFDZWI5ellRWUtwU2ZZczEvVFJVNGNjdFpPTXZKeWlnLzNneG5RYW9DQUFFVWVzTWZubXI4U1Z5Y2NvMmd2Q29lOWFtc09YbVh6CkhIZlYxSVdOY0NHMHN6TG5pNkxWaGprQ3NialNSODdreVVuRU82ZmUrMVI5Vjc3dzZHN0NlYkk2QzFYaVVKZ1dNaE5jTDNoV3djS1UKcy9KYTVDZWFueVRYeHV6UW15V0M0OHpDeEVYRmpKZDZCbXNxRVorcENtNUlPMi9iMUJFWlF2ZVBCNy8xVTErY1B2UVhMT1pwckU0eQpUR0ozNnJmbzViczB2Qm1McnB4UjU3ZCt0Vk94TXlMbGJjOXdQQnI2NHB0bnRvUDBqYVd2WWt4TjRGaXNaRFFTQS9pMmpaUmpKS1J4CkFnTUJBQUdqUWpCQU1BNEdBMVVkRHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJScWNpWjYKMEI3dmZlYzdhVkhVYkkyZmtCSm1xekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBZVo4ZGxzYTJlVDhpallmVGh3TUVZR3BybWk1WgppWE1SckVQUjlSUC9qVGtyd1BLOVQzQ01xUy9xRjhRTFZKN1VHNWFZTXp5b3JXS2lBSGFyV1dsdUJoMSt4TGxFalppdkV0Umgyd29aClJrZno2L2Rqd1VBRlFLWFN0L1MxbWphL3FZaDJpQVJWQkN1Y2gzOGFOengrTGFVYTJOU0pYc3E5ckQxczJHMnYxZk4yRDgwN2lEZ2kKbld5VG1zUTl2NEliWlQrbUQxMnEvT1d5RmNxMXJjYThQZENFNk9vR2NyQk5PVEo0dno0Um5BdWtuWm9oOC9DYkN6QjQyOEhjaDBQKwp2R09heXNYQ0hNbkhqZjg3RWxnSTVyWTk3SG9zVHZ1RGxzNE1QR21IVkhPa2M4S1QvMUVRckJWVUFkajhCYkdKb1g5MGc1cEoxOXhPCmU0cEliNHRGOWc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBFQzEKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDK1RDQ0FvQ2dBd0lCQWdJTkFLYUxlU2tBQUFBQVVOQ1IrVEFLQmdncWhrak9QUVFEQXpDQnZ6RUxNQWtHQTFVRUJoTUNWVk14CkZqQVVCZ05WQkFvVERVVnVkSEoxYzNRc0lFbHVZeTR4S0RBbUJnTlZCQXNUSDFObFpTQjNkM2N1Wlc1MGNuVnpkQzV1WlhRdmJHVm4KWVd3dGRHVnliWE14T1RBM0JnTlZCQXNUTUNoaktTQXlNREV5SUVWdWRISjFjM1FzSUVsdVl5NGdMU0JtYjNJZ1lYVjBhRzl5YVhwbApaQ0IxYzJVZ2IyNXNlVEV6TURFR0ExVUVBeE1xUlc1MGNuVnpkQ0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1CklDMGdSVU14TUI0WERURXlNVEl4T0RFMU1qVXpObG9YRFRNM01USXhPREUxTlRVek5sb3dnYjh4Q3pBSkJnTlZCQVlUQWxWVE1SWXcKRkFZRFZRUUtFdzFGYm5SeWRYTjBMQ0JKYm1NdU1TZ3dKZ1lEVlFRTEV4OVRaV1VnZDNkM0xtVnVkSEoxYzNRdWJtVjBMMnhsWjJGcwpMWFJsY20xek1Ua3dOd1lEVlFRTEV6QW9ZeWtnTWpBeE1pQkZiblJ5ZFhOMExDQkpibU11SUMwZ1ptOXlJR0YxZEdodmNtbDZaV1FnCmRYTmxJRzl1YkhreE16QXhCZ05WQkFNVEtrVnVkSEoxYzNRZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQXQKSUVWRE1UQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQklRVHlkQzZiVUY3NG16UTYxVmZaZ0lhSlBSYmlXbEg0N2pDZmZIeQpBc1dmb1BaYjFZc0dHWVpQVXhCdEJ5UW5vYUQ0MVVjWllVeDl5cE1uNm5RTTcyK1dDZjVqN0hCZE5xMW5kNjdKblh4VlJEcWlZMUVmCjllTmkxS2xIQno3TUlLTkNNRUF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUUKRkxkajV4cmRqZWtJcGxXRHBPQnFVRUZsRVVKSk1Bb0dDQ3FHU000OUJBTURBMmNBTUdRQ01HRjUyT1ZDUjk4Y3JsT1pGN1p2SEgzaAp2eEdVMFFPSWRlU05pYVNLZDBiZWJXSHZBdlg3dGQvTS9rNy8vcW5tcHdJd1c1blhoVGNHdFhzSS9lc25pMHFVK2VINnA0NG1DT2g4CmttaHRjOWh2SnF3aEFyaVp0eVpCV3lWZ3J0QklHdTRHCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkNGQ0EgRVYgUk9PVAo9PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZqVENDQTNXZ0F3SUJBZ0lFR0VyTTFqQU5CZ2txaGtpRzl3MEJBUXNGQURCV01Rc3dDUVlEVlFRR0V3SkRUakV3TUM0R0ExVUUKQ2d3blEyaHBibUVnUm1sdVlXNWphV0ZzSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUlV3RXdZRFZRUUREQXhEUmtOQgpJRVZXSUZKUFQxUXdIaGNOTVRJd09EQTRNRE13TnpBeFdoY05Namt4TWpNeE1ETXdOekF4V2pCV01Rc3dDUVlEVlFRR0V3SkRUakV3Ck1DNEdBMVVFQ2d3blEyaHBibUVnUm1sdVlXNWphV0ZzSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUlV3RXdZRFZRUUQKREF4RFJrTkJJRVZXSUZKUFQxUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFEWFhXdk5FRDhmQlZuVgpCVTAzc1E3c21DdU9GUjM2azBzWGdpRnhFRkxYVVdSd0ZzSlZhVTJPRlcyZnZ3d2J3dUNqWjlZTXJNOGlycTkzVkNwTFRJcFRVbnJECjdpN2VzM0Vsd2VsZFBlNmhMNlAzS2p6Skl4MXFxeDJocC9IejdLRFZSTThWejNJdkhXT1g2Sm41L1pPa1ZJQk1VdFJTcXk1SjM1RE4KdUYrK1A5Nmh5azBnMUNYb2hDbFR0N0dJSC8vNjJwQ2ZDcWt0UVQreDhSZ3A3aFpaTERSSkdxZ0cxNmlJMGdOeWVqTGk2bWhOYml5VwpaWHZLV2ZyeTR0M3VNQ3o3ekVhc3hHUHJiMzgyS3pSekVwUi8zOHdtbnZGeVhWQmxXWTlwczRkZU1tL0RHSXExbFkrd2VqZmVXa1U3Cnh6Ymg3MmZST2RPWFczTmlHVWd0aHh3RyszU1lJRWx6OEFYU0c3R2dvN2NiY05PSWFibGExamowWXR3bGkzaS8rT2grdUZ6SmxVOWYKcHkyNUlHdlBhOTMxRGZTQ3QvU3laaTRRS1BhWFdudVdGbzhCR1Mxc2JuODVXQVprZ3dHRGc4Tk5rdDB5eG9la04ra1d6cW90YUs4SwpnV1U2Y01HYnJVMXRWTW9xTFV1Rkc3T0E1bkJGRFd0ZU5mQi9PN2ljNUFSd2lSSWxrOW9LbVNKZ2FtTmdUbllHbUU2OWc2MGRXSW9sCmhkTEhaUjR0anNiZnRzYmhmNG9FSVJVcGRQQStuSkNkREM3eGlqNWFxZ3dKSHNmVlBLUHRsOE1lTlBvNCtRZ080OEJkSzRQUlZtckoKdHFoVVV5NTRNbWM5Z245MDBQdmh0Z1ZndVhEYmpndjVFMWh2Y1dBUVVoQzV3VUVKNzNJZlp6RjQvNVlGalFJREFRQUJvMk13WVRBZgpCZ05WSFNNRUdEQVdnQlRqL2kzOUtOQUx0YnEyb3NTL0Jxb0ZqSlA3THpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCCi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVTQvNHQvU2pRQzdXNnRxTEV2d2FxQll5VCt5OHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUIKQUNYR3VtdnJoOHZlZ2ptV1BmQkVwMnVFY3dQZW5TdFB1aUIvdkhpeXo1ZXdHNXp6MTNrdTlVaTIwdnNYaU9iVGVqL3RVeFBRNGk5cQplY3NBSXlqbUhqZFhOWW1Fd25aUE5EYXRaOFBPUVFhSXhmZnUyQnE0MWd0L1VQK1RxaGRMak96dFVtQ3lwQWJxVHV2MGF4bjk2L1VhCjRDVXFtdHpIUVRiM3lIUUZoRG1WT2RZTE82UW4rZ2pZWEI3NEJHQlNFU2dvQS8vdlUyWUFwVW8wRm1aOC9RbWtycDVuR205QkMyc0cKRTV1UGhuRUZ0QytOaVdZektYWlVtaEg0Si9xeVA1SGd6ZzBiOHpBYXJiOGlYUnZUdnlVRlRlR1NHbitabnp4RWs4clVRRWxzZ0lmWApCRHJETWxJMURsYjRwZDE5eElzTkVSOVR5eDZ5Rjdab2QxcmcxTXZJQjY3MU9pNk9ON2ZRQVV0REtYZU1PWmVQZ2xyNFVlV0pvQmpuCmFIOWRDaTc3bzBjT1BhWWplc1lCeDQvSVhyOXRnRmEraWlTNk0rcWY0VElSbnZIU1Q0RDJHMEN2T0o0UlVIbHpFaExONW15ZExJaHkKUERDQkJwRWk2bG10MmhrdUlzS051WXlINEdhOGN5TmZJV1JqZ0VqMW9Ed1lQWlRJU0VFZFFMcGUvdjVXT2FISXoxNmVHV1JHRU5vWAprYmNGZ0t5TG1aSjk1NkxZQndzMkorZEllV0NLdzljVFhQaHlRTjlLeTgrWkFBb0FDeEdWMmxaRkE0Z0tuMmZRMVhteHFJMUFiUTNDCmVrRDY4MTlrUjVMTFU3bTdXYzVQL2RBVlV3SFkzK3ZaNW5idjBDTzdPNmw1czlVQ0tjMkpvNVlQU2pYblRrTEFkYzBIeitZczYzc3UKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEdFRDQ0FwMmdBd0lCQWdJUWRyRWdVblR3aFlkR3MvZ2pHdmJDd0RBTkJna3Foa2lHOXcwQkFRc0ZBREJ0TVFzd0NRWURWUVFHCkV3SkRTREVRTUE0R0ExVUVDaE1IVjBsVFpVdGxlVEVpTUNBR0ExVUVDeE1aVDBsVFZFVWdSbTkxYm1SaGRHbHZiaUJGYm1SdmNuTmwKWkRFb01DWUdBMVVFQXhNZlQwbFRWRVVnVjBsVFpVdGxlU0JIYkc5aVlXd2dVbTl2ZENCSFFpQkRRVEFlRncweE5ERXlNREV4TlRBdwpNekphRncwek9URXlNREV4TlRFd016RmFNRzB4Q3pBSkJnTlZCQVlUQWtOSU1SQXdEZ1lEVlFRS0V3ZFhTVk5sUzJWNU1TSXdJQVlEClZRUUxFeGxQU1ZOVVJTQkdiM1Z1WkdGMGFXOXVJRVZ1Wkc5eWMyVmtNU2d3SmdZRFZRUURFeDlQU1ZOVVJTQlhTVk5sUzJWNUlFZHMKYjJKaGJDQlNiMjkwSUVkQ0lFTkJNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTJCZTNIRW9rS3RhWApzY3JpSHZ0OU9PK1k5Ykk1bUU0bnVCRmRlOUlsbElpQ0ZTWnFHekc3cUZzaElTdllEMDZmV3ZHeFd1UjUxaklqSytGVHpKbEZYSHRQCnJieS9oMG9MUzVkYXFQWkk3SDE3RGMwaEJ0K2VGZjFCaWtpM0lQU2hlaHRYMUYxUS83cG4yQ09aSDhnLzQ5Ny9iMXQzc1d0dXVNbGsKOStIS1FVWU9LWEhRdVNQOHlZRmZUdmR2MzcrRXJYTmt1N2RDam1uMjFIWWRmcDJudUZlS1VXZHkxOVNvdUpWVVFITUQ5dXIwNi80bwpRbmMvblNNYnNyWTlnQlFIVEM1UDk5VUtGZzI5WmtNM2ZpTkRlY05BaHZWTUtkcU9tcTBOcFFTSGlCNkY0K2xUMVp2SWl3TmplT3ZnCkdVcHV1eTlyTTJSWWs2MXB2NDhiNzRKSXh3SURBUUFCbzFFd1R6QUxCZ05WSFE4RUJBTUNBWVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIKL3pBZEJnTlZIUTRFRmdRVU5RL0lObU5lNHFQcytUdG1GYzVSVXVPUm1qMHdFQVlKS3dZQkJBR0NOeFVCQkFNQ0FRQXdEUVlKS29aSQpodmNOQVFFTEJRQURnZ0VCQUVCTSs0ZXltWUdRZnAzRnNMQW16WWg3S3pLTmJyZ2hjVmlYZmE0M0ZLOCs1L2VhNG4zMmNaaVpCS3BECmRIaWo0MGxoUG5PTVRaVGcrWEhFdGhZT1UzZ2YxcUtITHdJNWdTazhyeFdZSVREK0tKQUFqTkhoeS9wZXlQMzRFRVk3b25oQ2tSZDAKVlFyZVVHZE5adEduLy8zWndMV29vNHJPWnZVUFE4Mm5LMWQ3WTBacXFpNVMyUFR0NFcydEtaQjRTTHJoSTZxamlleTFxNWJBdEV1aQpIWmVlZXZKdVFISGZhUEZsVGM1OEJkOVRaYW1sOExHWEJIQVZSZ09ZMU5LL1ZMU2dXSDFTYjlwV0ptTFUyTnVKTVc4YzhDTEMwMkljCk5jMU1hUlZVR3BDWTN1c2VYOHAzeDh1T1BVTnBuSnBZMENRNzN4dEFsbjQxcllISFRuRzZpQk09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNaQUZJUiBST09UIENBMgo9PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURjakNDQWxxZ0F3SUJBZ0lVUG9wZEIreFYwakxWdCtPMlh3SHJMZHprMXVRd0RRWUpLb1pJaHZjTkFRRUxCUUF3VVRFTE1Ba0cKQTFVRUJoTUNVRXd4S0RBbUJnTlZCQW9NSDB0eVlXcHZkMkVnU1hwaVlTQlNiM3BzYVdONlpXNXBiM2RoSUZNdVFTNHhHREFXQmdOVgpCQU1NRDFOYVFVWkpVaUJTVDA5VUlFTkJNakFlRncweE5URXdNVGt3TnpRek16QmFGdzB6TlRFd01Ua3dOelF6TXpCYU1GRXhDekFKCkJnTlZCQVlUQWxCTU1TZ3dKZ1lEVlFRS0RCOUxjbUZxYjNkaElFbDZZbUVnVW05NmJHbGplbVZ1YVc5M1lTQlRMa0V1TVJnd0ZnWUQKVlFRRERBOVRXa0ZHU1ZJZ1VrOVBWQ0JEUVRJd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMzdkQ1UQpxRXZOUUxYT1llZVd5clNoMmd3aXNQcTFlM1lBZDR3THozMm9oc3dtVWVRZ1BZVU0xbGpqNS9RcUdKM2EwYTRtN3V0VDNQU1ExaE5LCkRKQTh3L1RhMG80TmtqcmNzYkgvT043RHVpMWZnTGtDdlVxZEd3KzB3OExCWndQZDNCdWNQYk93M2dBZXFEUkh1NXJyL2dzVXZUYUUKMmcwZ3YvcGJ5NmtXSUswNVlPNHZkYmJubDV6NVB2MStUVzlOTCsrSURXcjYzZkU5YmlDbG9CSzBUWEM1enRkeU80bVRwNENFSENkSgpja20xL3p1Vm5zSE15QUhzNkE2S0NwYm5zNmFINWRiNUJTc05sMEJ3UExxc2RWcWMxVTJkQWdyU1M1dG1TMFlIRjJXdG4yeUlBTndpCmllRGhaTlJudkRGNVlUeTd5a0hOWEdvQXlEdzRqbGl2QWdNQkFBR2pRakJBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFAKQVFIL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJRdUZxbEtHTFhMelBWdlVQTWpYL2hkNTZ6d3lEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQwpBUUVBdFhQNEE5eFpXeDEyNmFNcWU1QW9zazNBTTArcW1ySFV1T1FuLzZtV21jNUc0RzE4VEtJNHBBWnc4UFJCRWV3L1I0MC9jb2Y1Ck8vMmtieXRUQU9EL09ibHFCdzdySFJ6Mm9uS1F5NEk5RVlLTDBydWZLcThoNW1PR25Ya1o3L2U3RERXUXc0cnRUdy8xekJMWnBENjcKb1B3Z2xWOVBKaThSSTROT2RRY1B2NXZSdEIzcEVBVCt5bUNQb2t5NHJjL2hrQS9OcmdySFhYdTNVTkxVWWZyVkZkdlhuNGRSVk91bAo0K3ZKaGFBbElEZjdqczRNTklUaFBJR3lkMDVEcFloZmhtZWhQZWEwWEdHMlB0dit0eWpGb2dldXRjcktqU29TNzVmdHdqQ2t5U3A2CisvTk5JeHVaTXpTZ0x2V3BDei9VWGVIUGhKL2lHY0pmaXRZZ0h1Tnp0dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EgMgo9PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUYwakNDQTdxZ0F3SUJBZ0lRSWRiUVNrOGxEOGt5Ti95cVhoS042VEFOQmdrcWhraUc5dzBCQVEwRkFEQ0JnREVMTUFrR0ExVUUKQmhNQ1VFd3hJakFnQmdOVkJBb1RHVlZ1YVhwbGRHOGdWR1ZqYUc1dmJHOW5hV1Z6SUZNdVFTNHhKekFsQmdOVkJBc1RIa05sY25SMQpiU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURWtNQ0lHQTFVRUF4TWJRMlZ5ZEhWdElGUnlkWE4wWldRZ1RtVjBkMjl5CmF5QkRRU0F5TUNJWUR6SXdNVEV4TURBMk1EZ3pPVFUyV2hnUE1qQTBOakV3TURZd09ETTVOVFphTUlHQU1Rc3dDUVlEVlFRR0V3SlEKVERFaU1DQUdBMVVFQ2hNWlZXNXBlbVYwYnlCVVpXTm9ibTlzYjJkcFpYTWdVeTVCTGpFbk1DVUdBMVVFQ3hNZVEyVnlkSFZ0SUVObApjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TVNRd0lnWURWUVFERXh0RFpYSjBkVzBnVkhKMWMzUmxaQ0JPWlhSM2IzSnJJRU5CCklESXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDOStYajQ1dFdBREdTZGhodVdaR2MvSWpvZWRRRjkKNy90Y1o0ekp6RnhycVpIbXVVTGxJRXViMnB0N3VabGQyWnVBUzllRVFDc24wK2k2TUxzK0NScW5TWlh2SzBBa3dwZkhwKzZiSmUrbwpDZ0NYaFZxcW5kd3B5ZUkxQit0d1RVcld3Yk5XdUtGQk9KdlIrekYvaitCZjRiRS9ENDRXU1dEWEJvMFkrYW9tRUtzcTA5RFJaNDBiClJyNUhNTlV1Y3RIRlk5cm5ZM2xFZmt0akpJbUdMalEvS1V4U2l5cW53T0tSS0ltNXdGdjVIZG5uSjYzL21nS1h3Y1pRa3BzQ0xMMnAKdVRSWkNyK0VTdi9mL3JPZjY5bWU0SmdqN0tacmR4WXEyOHl0T3h5a2g5eEdjMTRaWW1oRlYrU1Fna0s3UXRid1llREJvejFtbzEzMApHTzZJeVkwWFJTbVpNblVDTWU0cEpzaHJBdWExWWtWL054VmFJMmlKMUQ3ZVRpZXc4RUFNdkUwWHkwMmlzeDdRQmxyZDlwUFBWM1daCjlmcUdHbWQ0czcrVy9qVGN2ZWRTVnVXejVYVjcxMEdSQmR4ZGFlT1ZEVU81L0lPV09aVjdiSUJhVHhOeXh0ZDlLWHBFdWxLa0t0VkIKUmdrZy9pS2d0bHN3amJ5SkROWFhjUGlIVXYzYTc2eFJMZ2V6VHY3UUNkcHc3NWo2VnVadDI3VlhTOXpsTENVVnlKNHVlRTc0MnB5ZQpoaXpLVi9NYTVjaVNpeHFDbG5yRHZGQVNhZGdPV2thTE91c20raVBKdHJDQnZrSUFwUGpXL2pBdXg5Skc5dVdPZGYzeXpMblFoMXZNCkJoQmd1NE0xdDE1bjNrZnNtVWp4cEtFVi9xMk1ZbzQ1VlU4NUZybXhZNTMvdHdJREFRQUJvMEl3UURBUEJnTlZIUk1CQWY4RUJUQUQKQVFIL01CMEdBMVVkRGdRV0JCUzJvVlE1QXNPZ1A0Nkt2UHJVK0J5bTBUb08vVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEUVlKS29aSQpodmNOQVFFTkJRQURnZ0lCQUhHbERzN2s2YjgvT05XSldzUUNZZnRNeFJRWExZdFBVMnNRRi94bGhNY1FTWkRlMjhjbWs0Z21iM0RXCkFsNDVvUGVQcTVhMXBSTmNnUlJ0RG9HQ0VSdUtUc1pQcGQxaUhrVGZDVm4wVzNjTE4rbUxJTWI0Q2s0dVdCenJNOURQaG1ESjJ2dUEKTDU1TVlJUjRQU0ZrMXZ0Qkh4Z1A1OGwxY2IyOVhONDBoejVCc0E3MnVkWS9DUk9XRkMvZW1oMWF1VmJPTlRxd1gzQk5YdU1wOFNNbwpjbG0ycThLTVppWWNkeXdtZGpXTEtLZHBvUGs3OVNQZGhSQjB5WkFEVnBIbnI3cEgxQktYRVNMam9rbVViT2UzbEV1NkxhVGFNNHRNCnBrVC9XanpHSFdUWXRUSGtwang2cUZjTDIrMWhHc3Z4em5OM1k2U0hiMHhST05ia1g4ZWZ0b0VxNUlWSWVWaGVPL2piQW9KbndUbmIKdzNSTFBUWWUrU21UaUdoYnFFUVpJZkNuNklFTkxPaVROclEzc3Nxd0d5WjZtaVVmbXBxQW5rc3FQL3VqbXY1ek1uSENuc1p5NFlwbwpKL0hrRDdURVRLVmhrL2lYRUFjcU1DV3B1Y2h4dU85b3pDMSs5ZUIrRDRLb2I3YTZiSU5EZDgyS2toZWhubHQ0RmoxRjRqTnkzZUZtCnlwblR5Y1VtL1Exb0JFYXV0dG1iakw0WnZySEc4aG5qWEFMS0xOaHZTZ2ZaeVRYYVFIWHl4S2NaYjU1Q0VKaDE1cFdMWUx6dHhSTFgKaXM3Vm1GeFdsZ1BGN25jR05mL1A1TzQvRTJIdTI5b3RoZkROcnAyeUdBbEZ3NUtoY2hmOFI3YWdDeXp4eE41RGFBaHFYenZ3ZG1QNwp6QVlzcHNiaURyVzV2aVNQCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJR0N6Q0NBL09nQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFzRkFEQ0JwakVMTUFrR0ExVUVCaE1DUjFJeER6QU5CZ05WQkFjVApCa0YwYUdWdWN6RkVNRUlHQTFVRUNoTTdTR1ZzYkdWdWFXTWdRV05oWkdWdGFXTWdZVzVrSUZKbGMyVmhjbU5vSUVsdWMzUnBkSFYwCmFXOXVjeUJEWlhKMExpQkJkWFJvYjNKcGRIa3hRREErQmdOVkJBTVROMGhsYkd4bGJtbGpJRUZqWVdSbGJXbGpJR0Z1WkNCU1pYTmwKWVhKamFDQkpibk4wYVhSMWRHbHZibk1nVW05dmRFTkJJREl3TVRVd0hoY05NVFV3TnpBM01UQXhNVEl4V2hjTk5EQXdOak13TVRBeApNVEl4V2pDQnBqRUxNQWtHQTFVRUJoTUNSMUl4RHpBTkJnTlZCQWNUQmtGMGFHVnVjekZFTUVJR0ExVUVDaE03U0dWc2JHVnVhV01nClFXTmhaR1Z0YVdNZ1lXNWtJRkpsYzJWaGNtTm9JRWx1YzNScGRIVjBhVzl1Y3lCRFpYSjBMaUJCZFhSb2IzSnBkSGt4UURBK0JnTlYKQkFNVE4waGxiR3hsYm1saklFRmpZV1JsYldsaklHRnVaQ0JTWlhObFlYSmphQ0JKYm5OMGFYUjFkR2x2Ym5NZ1VtOXZkRU5CSURJdwpNVFV3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRREMrS2svRzRuOFBEd0VYVDJRTnJDUk9uazhabHJ2CmJUa0JTUnEwdDg5L1RTTlR0NUFBNHhNcUtLWXg4WkVBNHlqc3JpRkJ6aC9hL1gwU1d3R0REN213WDVuaDhoS0RnRTBHUHQrc3IrZWgKaUdzeHIvQ0wwQmd6dU50RmFqVDBBb0FrS0FvQ0ZaVmVkaW9ObVRvVVcvYkx5MU84RTAwQmlEZVVKUnRDdkNMWWpxT1dYanJaTXRzKwo2UEFRWmUxMDRTK25mSzhuTkxzcGZadTJ6d25JNWRNSy9JaGxaWFFLM0hNY1hNMUFzUnpVdG9TTVRGRFBhSTZvV2E3Q0owNkNvalhkCkZQUWYvN0ozMVljdnFtNTlKQ2ZueHNzbTV1WCtad2RqMkVVTjNUcFpaVGxZZXBLWmNqMmNoRjZJSWJqVjlDejgyWEJTVDNpNHZUd3IKaTVXWTliUFJhTThnRkg1TVhGL25pK1gxTllFWk45Y1JDTGRtdnROS3pvTlhBRHJEZ2ZnWHk1STJYZEdqMkhVYjRZc242bnBJUWYxRgpHUWF0SjVsT3dYQkgzYldmZ1ZNUzViR01TRjB4UXhmampNWjZZNVpMS1RCT2hFNWlHVjQ4enBlUXBYOEI2NTNnK0l1SjNTV1lQWksyCmZ1L1o4VkZSZlMwbXlHbFpZZUNzYXJncU5oRUVlbEM5TW9TK0w5eHkxZGNkRmtma1IyWWdQL1NXeGErT0FYcWxEM3BrOVEwWWg5bXUKaU5YNmhNRTZ3R2tvTGZJTmFGR3E0NlYzeHFTUURxRTNpekVqUjhFSkNPdHU5M2liMTRMOGhDQ1pTUm0yRWtheCswVlZGcW1qWmF5YwpCdy9xYTl3ZkxnWnk3SWFJRXVRdDIxOEZMK1R3QTlNbU0rZUF3czFDb1JjMEN3SURBUUFCbzBJd1FEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVVjUlZueU1qSnZYVmRjdEE0R0dxZDgzRWtWQXN3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dJQkFIVzdiVlJMcWhCWVJqVHlZdGNXTmwwSVh0VnN5SWU5dEM1RzhqSDRmT3BDdFpNV1ZkeWhEQktnMm1GKwpEMWhZYzJSeXgraEZqdHlwOGlZL3hubU1zVk1JTTRHd1ZoTys1bEZjMkpzS1QwdWNWbE1DNlUvMkRXRHFUVUpWNkh3YklTSFRHenJNCmQvSzRrUEZveC9sYS92b3Q5TC9KOVVVYnpqZ1FLamVLZWFPMDR3bHNoWWFULzRtV0ozaUJqMmZqUm5SVWp0a05hZUpLOUUxMEEvK3kKZCsyVlo1ZmtzY1dydjJvajZOU1U0a1FvWXNSTDR2RFk0aWxyR25CK0pHR1RlMDhETWlVTlJTUXJsclJHYXI5S0MvZWFqOEdzR3NWbgo4MjgwMHZwelk0enZGckNvcEVZcStPc1M3SEswNy9ncmZveFN3SXVFVlBrdlB1TlZxTnhtc2RuaFg5aXpqRmswV2FTclQyeTdIeGpiCmRhdll5NUxObERoaERnY0dIMHRHRVBFVnZvMkZYRHRLSzRGNUQ3UnBuMGxRbDAzM0RsWmR3SlZxd2piREcyako5U3JjUjVxK3NzN0YKSmVqNkE3bmErUlp1a1lUMUhDakkvQ2JNMXh5UVZxZGZiem9Fdk0xNGlRdU9EeStqcWsraUd4STlGZ2hBRC9GR1ROZXFld2pCQ3ZWdApKOTRDajhyRHRTdks2ZXZJSVZNNHBjdzcySGMzTUtKUDJXL1I4a0N0UVhvWHhkWktOWW0zUWRWOGhuOVZUWU5LcFhNZ3dEcXZrUEdhCkpJN1pqbkhLZTdpRzJyS1BtVDRkRXcwU0VlN1VxL0RwRlhZQzVPRGZxaUFlVzJHRlpFQ3BrSmNOclZQU1doMkhhZ0NYWldLMHZtOXEKcC9Vc1F1MHlyYllobnI2OAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290Q0EgMjAxNQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ3d6Q0NBa3FnQXdJQkFnSUJBREFLQmdncWhrak9QUVFEQWpDQnFqRUxNQWtHQTFVRUJoTUNSMUl4RHpBTkJnTlZCQWNUQmtGMAphR1Z1Y3pGRU1FSUdBMVVFQ2hNN1NHVnNiR1Z1YVdNZ1FXTmhaR1Z0YVdNZ1lXNWtJRkpsYzJWaGNtTm9JRWx1YzNScGRIVjBhVzl1CmN5QkRaWEowTGlCQmRYUm9iM0pwZEhreFJEQkNCZ05WQkFNVE8waGxiR3hsYm1saklFRmpZV1JsYldsaklHRnVaQ0JTWlhObFlYSmoKYUNCSmJuTjBhWFIxZEdsdmJuTWdSVU5ESUZKdmIzUkRRU0F5TURFMU1CNFhEVEUxTURjd056RXdNemN4TWxvWERUUXdNRFl6TURFdwpNemN4TWxvd2dhb3hDekFKQmdOVkJBWVRBa2RTTVE4d0RRWURWUVFIRXdaQmRHaGxibk14UkRCQ0JnTlZCQW9UTzBobGJHeGxibWxqCklFRmpZV1JsYldsaklHRnVaQ0JTWlhObFlYSmphQ0JKYm5OMGFYUjFkR2x2Ym5NZ1EyVnlkQzRnUVhWMGFHOXlhWFI1TVVRd1FnWUQKVlFRREV6dElaV3hzWlc1cFl5QkJZMkZrWlcxcFl5QmhibVFnVW1WelpXRnlZMmdnU1c1emRHbDBkWFJwYjI1eklFVkRReUJTYjI5MApRMEVnTWpBeE5UQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkpLZ1FlaExnb1JjNHZneEVabUdaRTRKSlMrZFFTOEtyalZQCmRKV3lVV1Jyald2bVAzQ1Y4QVZFUjZaeU9GQjJsUUphanE0b252a3RUcG52TEVodlRDVXA2TkZ4Vzk4ZHdYVTN0TmY2ZTNwQ25Hb0sKVmxwOGFRdXFnQWtrYkg3QlJxTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwTwpCQllFRkxRaUM0S1pKQUVPbkx2a0R2Mi8rNWNnazVrcU1Bb0dDQ3FHU000OUJBTUNBMmNBTUdRQ01HZk9GbUk0b3F4aVJhZXBsU1RBCkdpZWNNanZBd05XNnFlZjRCRU5UaGU1U0lkNmQ5U1dEUHA1WVN5L1haeE1PSVFJd0JlRjFBZDVvN1NvZlRVd0pDQTNzUzYxa0Z5am4KZGM1RlpYSWhGOHNpUVE2TUU1ZzRtbFJ0bThyaWZPb0NXQ0tSCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCklTUkcgUm9vdCBYMQo9PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZhekNDQTFPZ0F3SUJBZ0lSQUlJUXo3RFNRT05aUkdQZ3UyT0Npd0F3RFFZSktvWklodmNOQVFFTEJRQXdUekVMTUFrR0ExVUUKQmhNQ1ZWTXhLVEFuQmdOVkJBb1RJRWx1ZEdWeWJtVjBJRk5sWTNWeWFYUjVJRkpsYzJWaGNtTm9JRWR5YjNWd01SVXdFd1lEVlFRRApFd3hKVTFKSElGSnZiM1FnV0RFd0hoY05NVFV3TmpBME1URXdORE00V2hjTk16VXdOakEwTVRFd05ETTRXakJQTVFzd0NRWURWUVFHCkV3SlZVekVwTUNjR0ExVUVDaE1nU1c1MFpYSnVaWFFnVTJWamRYSnBkSGtnVW1WelpXRnlZMmdnUjNKdmRYQXhGVEFUQmdOVkJBTVQKREVsVFVrY2dVbTl2ZENCWU1UQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUszb0pIUDBGRGZ6bTU0cgpWeWdjaDc3Y3Q5ODRrSXh1UE9aWG9IajNkY0tpL3ZWcWJ2WUFUeWpiM21pR2JFU1R0ckZqL1JRU2E3OGYwdW94bXlGKzBUTTh1a2oxCjNYbmZzN2ovRXZFaG1rdkJpb1p4YVVwbVpteVBmanh3djYwcElnYno1TURtZ0s3aVM0KzNtWDZVQTUvVFI1ZDhtVWdqVStnNHJrOEsKYjRNdTBVbFhqSUIwdHRvdjBEaU5ld053SVJ0MThqQTgrbyt1M2RwanErc1dUOEtPRVV0K3p3dm8vN1YzTHZTeWUwcmdUQklsREhDTgpBeW1nNFZNazdCUFo3aG0vRUxOS2pEK0pvMkZSM3F5SEI1VDBZM0hzTHVKdlc1aUI0WWxjTkhsc2R1ODdrR0o1NXR1a21pOG14ZEFRCjRRN2UyUkNPRnZ1Mzk2ajN4K1VDQjVpUE5naVY1K0kzbGcwMmRaNzdEbkt4SFp1OEEvbEpCZGlCM1FXMEt0WkI2YXdCZHBVS0Q5amYKMWIwU0h6VXZLQmRzMHBqQnFBbGtkMjVITjdyT3JGbGVhSjEvY3RhSnhRWkJLVDVaUHQwbTlTVEpFYWRhbzB4QUgwYWhtYlduT2xGdQpoanVlZlhLbkVnVjRXZTArVVhnVkN3T1BqZEF2QmJJK2Uwb2NTM01GRXZ6RzZ1QlFFM3hEazNTenluVG5qaDhCQ05BdzFGdHhOclFICnVzRXdNRnhJdDRJN21LWjlZSXFpb3ltQ3pMcTlnd1Fib29NRFFhSFdCZkVid3Jid3FIeUdPMGFvU0NxSTNIYWFkcjhmYXFVOUdZL3IKT1BOazNzZ3JEUW9vLy9mYjRoVkMxQ0xRSjEzaGVmNFk1M0NJclU3bTJZczZ4dDBuVVc3L3ZHVDFNME5QQWdNQkFBR2pRakJBTUE0RwpBMVVkRHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSNXRGbm1lN2JsNUFGemdBaUl5QnBZCjl1bWJiakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBVlI5WXFieXlxRkRRRExIWUdta2dKeWtJckdGMVhJcHUrSUxsYVMvVjlsWkwKdWJoekVGblRJWmQrNTB4eCs3TFNZSzA1cUF2cUZ5RldoZkZRRGxucnp1Qlo2YnJKRmUrR25ZK0VnUGJrNlpHUTNCZWJZaHRGOEdhVgowbnh2d3VvNzd4L1B5OWF1Si9HcHNNaXUvWDErbXZvaUJPdi8yWC9xa1NzaXNSY09qL0tLTkZ0WTJQd0J5VlM1dUNiTWlvZ3ppVXd0CmhEeUMzKzZXVndXNkxMdjN4TGZIVGp1Q3ZqSElJbk56a3RIQ2dLUTVPUkF6STRKTVBKK0dzbFdZSGI0cGhvd2ltNTdpYXp0WE9vSncKVGR3Sng0bkxDZ2ROYk9oZGpzbnZ6cXZIdTdVclRrWFdTdEFtek9WeXlnaHFwWlhqRmFIM3BPM0pMRitsKy8rc0tBSXV2dGQ3dStOeAplNUFXMHdkZVJsTjhOd2RDak5QRWxwelZtYlVxNEpVYWdFaXVURGtIenN4SHBGS1ZLN3E0KzYzU00xTjk1UjFOYmRXaHNjZENiK1pBCkp6VmNveWkzQjQzbmpUT1E1eU9mKzFDY2VXeEcxYlFWczVadWZwc01sanE0VWkwLzFsdmgrd2pDaFA0a3FLT0oycXhxNFJncXNhaEQKWVZ2VEg5dzdqWGJ5TGVpTmRkOFhNMnc5VS90N3kwRmYvOXlpMEdFNDRaYTRyRjJMTjlkMTFUUEFtUkd1blVIQmNuV0V2Z0pCUWw5bgpKRWlVMFpzbnZnYy91YmhQZ1hSUjRYcTM3WjBqNHI3ZzFTZ0VFend4QTU3ZGVteVB4Z2NZeG4vZVI0NC9LSjRFQnMrbFZEUjN2ZXlKCm0ra1hROTliMjEvK2poNVhvczFBblg1aUl0cmVHQ2M9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFDIFJBSVogRk5NVC1SQ00KPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmd6Q0NBMnVnQXdJQkFnSVBYWk9OTUdjMnlBWWRHc2RVaEdrSE1BMEdDU3FHU0liM0RRRUJDd1VBTURzeEN6QUpCZ05WQkFZVApBa1ZUTVJFd0R3WURWUVFLREFoR1RrMVVMVkpEVFRFWk1CY0dBMVVFQ3d3UVFVTWdVa0ZKV2lCR1RrMVVMVkpEVFRBZUZ3MHdPREV3Ck1qa3hOVFU1TlRaYUZ3MHpNREF4TURFd01EQXdNREJhTURzeEN6QUpCZ05WQkFZVEFrVlRNUkV3RHdZRFZRUUtEQWhHVGsxVUxWSkQKVFRFWk1CY0dBMVVFQ3d3UVFVTWdVa0ZKV2lCR1RrMVVMVkpEVFRDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQwpnZ0lCQUxweGdIcE1obTUveUJOdHdNWjlIQUNYanl3TUk3c1Fta0NwR3JlSGlQaWJWbXI3NW51T2k1S09weVZkV1JIYk5pNjNVUmNmCnFRZ2ZCQmNrV0tvM1NoamY1VG5VVi8zWHdTeVJBWkhpSXRRRHdGajhkMGZzano1MFE3cXNOSTFOT0habmpyREliekF6V0hGY3RQVnIKYnRRQlVMZ1RmbXhLbzBuUklCbnV2TUFwR0dXbjN2N3YzUXFRSWVjYVo1SkNFSmhmVHpDOFBoeEZ0QkRYYUVBVXdFRDY1M2NYZXVZTApqMlZiUE5tYVV0dTF2WjVHenozcmtRVUN3SmF5ZGt4TkVKWTdrdnFjZncrWjM3NGpOVVVlQWx6K3RhaWJtU1hhWHZNaXd6bjE1Q291CjA4WWZ4R3lxeFJ4cUFRVktMOUxGd2FnMEpsMW1wZElDSWZrWXR3YjFUcGx2cUt0TVVlalBVQmpGZDhnNUNTeEpraktacUxzWEYzbXcKV3NYbW84UlpaVWMxZzE2cDZEVUxtYnZrelNER20wb0dPYlZvL0NLNjdsV01LMDdxODdIai9MYVptdFZDK25GTkNNK0hIbXB4ZmZuVAp0T21sY1lGN3drNUhscVgyZG9XaktJL3BnRzZCVTZWdFg3aEkrY0w1TnFZdVNmKzRsc0tNQjdPYmlGajg2eHNjM2kxdzRwZVNNS0dKCjQ3eFZxQ2ZXUysyUXJZdjZZeVZaTGFnMTNjcVhNN3psemNlZDBlenZYZzVLa0FZbVk2MjUyVFV0QjdwMlpTeXNWNDk5OUFlVTE0RUMKbGwyakIwblZldEJYK1J2blUwWjFxckI1UXN0b2NRanBZTDA1YWM3MHI4TldRTWV0VXFJSjVHK0dSNG9mNnlnblhZTWdyd1RKYkZhYQppMGIxQWdNQkFBR2pnWU13Z1lBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFCkZQZDl4ZjNFNkpvYmQyU245UjJnekwrSFlKcHRNRDRHQTFVZElBUTNNRFV3TXdZRVZSMGdBREFyTUNrR0NDc0dBUVVGQndJQkZoMW8KZEhSd09pOHZkM2QzTG1ObGNuUXVabTV0ZEM1bGN5OWtjR056THpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQUI1QkszL01qVHZERApuRkZsbTV3aW9vb01oZk56S1d0Ti9nSGlxUXhqQWI4RVo2V2RtRi85QVJQNjdKcGk2WWIrdG1MU2JreVUrOEIxUlh4bERQaXlOOCtzCkQ4K05iL2taOTQvc0h2SndudkRLdU8rMy8zWTNkbHYyYm9qenIySXlJcE1OT21xT0ZHWU1MVk4wVjJVZTFiTGRJNEU3cFdZakoyY0oKaitGM3FrUE5aVkVJN1ZGWS91WTUrY3RIaEtRVjhYYTdwTzZrTzhSZjc3SXpsaEVZdDhsbHZoamhvNlRjK2hqNTA3d1Rtemw2TkxyVApRZnY2TW9vcXR5dUdDMm1ET0w3TmlpNExjSzJOSnBMdUh2VUJLd3JaMXBlYmJ1Q29HUnc2SVlzTUhrQ3RBK2ZkWm43MXVTQU5BK2lXCitZSkYxRG5nb0FCZDE1am1mWjVuYzhPYUt2ZXJpNkU2Rk84MHZGSU9pWmlhQkVDRUhYNUZhWk5YenV2TytGQjhUeHh1QkVPYitkWTcKSXhqcDZvN1JUVWFOOFR2a2FzcTYreU8zbS9xWkFTbGFXRm90NC9uVWJRNG1yY0Z1Tkx3eStBd0YrbVdqMnpzM2d5THAxdHh5TS8xZAo4aUM5ZGp3ajJpajMrUnZyV1dUVjNGOXlmaUQ4elltMWtHZE5Zbm8vVHEwZHd6bitldlFvRnQ5QjlraUFCZGNQVVhtc0VLdlU3QU5tCjVtcXd1akdTUWtCcXZqclRjdUZxTjFXOHJCMlZ0MmxoOGtPUmRPYWcwd29rUnFFSXI5YmFSUm1XMUZNZFc0UjU4TUQzUisrTGo4VUcKcnAxTVlwMy9SZ1Q0MDhtMkVDVkFkZjRXcXNsS1lJWXZ1dTh3ZCtSVTRyaUVtVmlBcWhPTFVUcFBTUGFMdHJNPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBbWF6b24gUm9vdCBDQSAxCj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQWltZ0F3SUJBZ0lUQm15Zno1bS9qQW81NHZCNGlrUG1salpieWpBTkJna3Foa2lHOXcwQkFRc0ZBREE1TVFzd0NRWUQKVlFRR0V3SlZVekVQTUEwR0ExVUVDaE1HUVcxaGVtOXVNUmt3RndZRFZRUURFeEJCYldGNmIyNGdVbTl2ZENCRFFTQXhNQjRYRFRFMQpNRFV5TmpBd01EQXdNRm9YRFRNNE1ERXhOekF3TURBd01Gb3dPVEVMTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFvVEJrRnRZWHB2CmJqRVpNQmNHQTFVRUF4TVFRVzFoZW05dUlGSnZiM1FnUTBFZ01UQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0MKZ2dFQkFMSjRnSEhLZU5YamNhOUhnRkIwZlc3WTE0aDI5SmxvOTFnaFlQbDBoQUV2ckFJdGh0T2dRM3BPc3FUUU5yb0J2bzNiU01nSApGelpNOU82SUk4Yys2emYxdFJuNFNXaXczdGU1ZGpnZFlaNmsvb0kycGVWS1Z1UkY0Zm45dEJiNmROcWNtelU1TC9xd0lGQUdiSHJRCmdMS20rYS9zUnhtUFVEZ0gzS0tIT1ZqNHV0V3ArVWhuTUpidWxIaGViNG1qVWNBd2htYWhSV2E2Vk91anc1SDVTTnovMGVnd0xYMHQKZEhBMTE0Z2s5NTdFV1c2N2M0Y1g4akpHS0xoRCtyY2Rxc3EwOHA4a0RpMUw5M0ZjWG1uLzZwVUN5emlLcmxBNGI5djdMV0lieGNjZQpWT0YzNEdmSUQ1eUhJOVkvUUNCL0lJREVnRXcrT3lRbWpnU3ViSnJJcWcwQ0F3RUFBYU5DTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCCi96QU9CZ05WSFE4QkFmOEVCQU1DQVlZd0hRWURWUjBPQkJZRUZJUVl6SVUwN0x3TWxKUXVDRm1jeDdJUVRnb0lNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFDWThqZGFRWkNoR3NWMlVTZ2dOaU1PcnVZb3U2cjRsSzVJcERCL0cvd2tqVXUweUtHWDlyYnhlbkRJVTVQTQpDQ2pqbUNYUEk2VDUzaUhUZklVSnJVNmFkVHJDQzJxSmVIWkVSeGhsYkkxQmpqdC9tc3YwdGFkUTF3VXNOK2dEUzYzcFlhQUNidlh5CjhNV3k3VnUzM1BxVVhIZWVFNlYvVXEyVjh2aVRPOTZMWEZ2S1dsSmJZSzhVOTB2dm8vdWZRSlZ0TVZUOFF0UEhSaDhqcmRrUFNIQ2EKMlhWNGNkRnlRelIxYmxkWndnSmNKbUFwenlNWkZvNklRNlhVNU1zSSt5TVJRK2hES1hKaW9hbGRYZ2pVa0s2NDJNNFV3dEJWOG9iMgp4Sk5EZDJaaHdMbm9RZGVYZUdBRGJrcHlycVhSZmJvUW5vWnNHNHE1V1RQNDY4U1F2dkc1Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFtYXpvbiBSb290IENBIDIKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRlFUQ0NBeW1nQXdJQkFnSVRCbXlmMHBZMWhwOEtEK1dHZVBoYkpydUtOekFOQmdrcWhraUc5dzBCQVF3RkFEQTVNUXN3Q1FZRApWUVFHRXdKVlV6RVBNQTBHQTFVRUNoTUdRVzFoZW05dU1Sa3dGd1lEVlFRREV4QkJiV0Y2YjI0Z1VtOXZkQ0JEUVNBeU1CNFhEVEUxCk1EVXlOakF3TURBd01Gb1hEVFF3TURVeU5qQXdNREF3TUZvd09URUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQW9UQmtGdFlYcHYKYmpFWk1CY0dBMVVFQXhNUVFXMWhlbTl1SUZKdmIzUWdRMEVnTWpDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQwpnZ0lCQUsyV255MmNTa3hLZ1hsUm1leUt5MnRnVVJPOFRXMEcvTEFJamQwWkVHckhKZ3cxMk1CdklJVHBsTEdiaFFQRFc5dEs2TWo0CmtIYlpXMC9qVE9nR05rM01tcXc5REpBcmt0UUdHV0NzTjBSNWhZR0NyVm8zNEEzTW5hWk1VbmJxUTUyM0JORlE5bFhnMWRLbVNZWHAKTituS2ZxNWNsVTFJbWordUlGcHRpSlhaTkxoU0drT1FzTDlzQmJtMmVMZnEwT1E2UEJKVFl2OUs4bnUrTlFXcEVqVGo4MlIwWWl3OQpBRWxhS1A0eVJMdUgzV1VuQW5FNzJrcjNIOXJOOXlGVmtFOFA3SzZDNFo5cjJVWFR1L0JmaCswOExEbUcyai9lN0hKVjYzbWpyZHZkCmZMQzZITTc4M2s4MWRzOFArSGdmYWpaUlJpZGhXK21lei9DaVZYMThKWXB2TDdURno0UXVLLzBOVVJCcysxOGJ2QnQreGE0N21BRXgKa3Y4TFYvU2FzcmxYNmF2dkRYYlI4Tzcwem9hbjRHN3B0R21oMzJuMk04WnBMcGNUbnFXSHNGY1FnVGZKVTdPN2YvYVMwWnpRR1BTUwpidHFEVDZaam1VeWwrMTd2SVdSNklGOXNaSVVWeXpmcFlnd0xLaGJjQVM0eTJqNUw5WjQ2OWhkQWxPK2VrUWlHK3I1anFGb3o3TXQwClE1WDViR2xTTnNjcGIveFZBMXdmKzUrOVIrdm5TVWVWQzA2SklnbEo0UFZoSHZHL0xvcHlib0JaLzFjNitYVXlvMDVmN08wb1l0bE4KYy9MTWdSZGc3YzNyM051bnlzVitBcjN5VkFoVS9iUXRDU3dYVkVxWTBWVGhVV2NJMHUxdWZtOC8waTJCV1NsbXk1QTVsUkVlZENmKwozZXV2QWdNQkFBR2pRakJBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnR0dNQjBHQTFVZERnUVdCQlN3CkRQQk1NUFFGV0FKSS9UUGxVcTlMaE9ObVVqQU5CZ2txaGtpRzl3MEJBUXdGQUFPQ0FnRUFxcWlBanc1NG8rQ2kxTTNtOVpoNk8rb0EKQTdDWERwTzhXcWoyTEl4eWg2bXgvSDl6L1dOeGVLV0hXYzh3NFEwUXNoTmFiWUwxYXVhQW42QUZDMmprUjJ2SGF0KzIvWGN5Y3VVWQorZ24wb0pNc1hkS01kWVYyWlpBTUEzbTNNU05qclhpRENZWm9oTXIvK2M4bW1wSjU1ODFMeGVkaHB4Zkw4NmtTazVOcnArZ3ZVNUxFCllGaXd6QUpSR0Z1RmpXSlpZN2F0dE42YSt5YjNBQ2ZBWFZVM2RKbkpVSC9qV1M1RTR5d2w3dXhNTW5lMG54cnBTMTBneGRyOUhJY1cKeGtQbzFMc21ta1Z3WHFrTE4xUGlSbnNuL2VCRzhvbTN6RUsyeXlnbWJ0bWx5VHJJUVJOZzkxQ01GYTZ5YlJvVkdsZDQ1cElxMldXUQpnajlzQXErdUVqb25sallFMXgyaWdHT3BtL0hsdXJSOEZMQk95YkVmZEY4NDlsSHFtL29zb2hIVXFTMG5Ha1d4cjdKT2NRM0FXRWJXCmFRYkxVOHV6L210QnpVRitmVXdQZkhKNWVsbk5Ya29Pckp1cG1ITjVmTFQwekxtNEJ3eXlkRnk0eDIrSW9aQ245S3I1djJjNjlCb1YKWWg2M243NDlzU212WjZFUzhsZ1FHVk1ETUJ1NEdvbjJuTDJYQTQ2akNmTWRpeUh4dE4va0hOR2ZaUUlHNmx6V0U3T0U3NktsWEl4MwpLYWRvd0d1dVFOS290T3JOOEkxTE9Kd1ptaHNvVkxpSmtPL0tkWUUrSHZKa0pNY1lyMDcvUjU0SDlqVmxwTk1LVnYvMUYyUnM3NmdpCkpVbVR0dDhBRjlwWWZsM3V4UnV3MGRGZklSREgrZk82QWdvbkI4WHgxc2ZUNFBzSllHdz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQW1hem9uIFJvb3QgQ0EgMwo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlCdGpDQ0FWdWdBd0lCQWdJVEJteWYxWFNYTm1ZL093dWEyZWllZGdQeVNqQUtCZ2dxaGtqT1BRUURBakE1TVFzd0NRWURWUVFHCkV3SlZVekVQTUEwR0ExVUVDaE1HUVcxaGVtOXVNUmt3RndZRFZRUURFeEJCYldGNmIyNGdVbTl2ZENCRFFTQXpNQjRYRFRFMU1EVXkKTmpBd01EQXdNRm9YRFRRd01EVXlOakF3TURBd01Gb3dPVEVMTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFvVEJrRnRZWHB2YmpFWgpNQmNHQTFVRUF4TVFRVzFoZW05dUlGSnZiM1FnUTBFZ016QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJDbVhwOFpCCmY4QU5tK2dCRzFiRzhsS2x1aTJ5RXVqU0x0ZjZ5Y1hZcW0wZmM0RTdPNWhyT1h3enBjVk9obzZBRjJoaVJWZDlSRmdkc3pmbFp3anIKWnQ2alFqQkFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01CMEdBMVVkRGdRV0JCU3J0dHZYQnA0MwpyRENHQjVGd3g1ekVHYkY0d0RBS0JnZ3Foa2pPUFFRREFnTkpBREJHQWlFQTRJV1NveGUzamZrckJxV1RyQnFZYUdGeSt1R2gwUHNjCmVHQ21RNW5GdU1RQ0lRQ2NBdS94bEp5emx2bnJ4aXI0dGl6K09wQVVGdGVNWXlSSUhOOHdmZFZvT3c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBbWF6b24gUm9vdCBDQSA0Cj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUI4akNDQVhpZ0F3SUJBZ0lUQm15ZjE4RzdFRXdwUStWeGUzc3N5QnJCRGpBS0JnZ3Foa2pPUFFRREF6QTVNUXN3Q1FZRFZRUUcKRXdKVlV6RVBNQTBHQTFVRUNoTUdRVzFoZW05dU1Sa3dGd1lEVlFRREV4QkJiV0Y2YjI0Z1VtOXZkQ0JEUVNBME1CNFhEVEUxTURVeQpOakF3TURBd01Gb1hEVFF3TURVeU5qQXdNREF3TUZvd09URUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQW9UQmtGdFlYcHZiakVaCk1CY0dBMVVFQXhNUVFXMWhlbTl1SUZKdmIzUWdRMEVnTkRCMk1CQUdCeXFHU000OUFnRUdCU3VCQkFBaUEySUFCTktyaWpkUG8xTU4KL3NHS2UwdW9lMFpMWTdCaTlpMGIyd2h4SWRJQTZHTzltaWY3OERsdVhlbzlwY21CcXFOYklKaEZYUmJiL2VnUWJlT2M0T085WDRSaQo4M0JrTTZETEpDOXd1b2loS3FCMStJR3VZZ2JFZ2RzNWJpbXdIdm91WEtOQ01FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WCkhROEJBZjhFQkFNQ0FZWXdIUVlEVlIwT0JCWUVGTlBzeHpwbGJzemgybmFhVnZ1Yzg0WnRWK1dCTUFvR0NDcUdTTTQ5QkFNREEyZ0EKTUdVQ01EcUxJZkc5ZmhHdDBPOVlsaS9XNjUxK2tJMHJ6MlpWd3l6aktLbHdDa2NPOERkWkV2OHRtWlFvVGlwUE5VMHpXZ0l4QU9wMQpBRTQ3eERxVUVwSEpXRWFkSVJOeXA0aWNpdVJNU3R1VzFLeUxhMnRKRWxNenJkZmt2aVQ4dFFwMjFLVzhFQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3VydW0gMQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVZekNDQTB1Z0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCMGpFTE1Ba0dBMVVFQmhNQ1ZGSXhHREFXQmdOVkJBY1QKRDBkbFlucGxJQzBnUzI5allXVnNhVEZDTUVBR0ExVUVDaE01VkhWeWEybDVaU0JDYVd4cGJYTmxiQ0IyWlNCVVpXdHViMnh2YW1scgpJRUZ5WVhOMGFYSnRZU0JMZFhKMWJYVWdMU0JVVlVKSlZFRkxNUzB3S3dZRFZRUUxFeVJMWVcxMUlGTmxjblJwWm1scllYTjViMjRnClRXVnlhMlY2YVNBdElFdGhiWFVnVTAweE5qQTBCZ05WQkFNVExWUlZRa2xVUVVzZ1MyRnRkU0JUVFNCVFUwd2dTMjlySUZObGNuUnAKWm1scllYTnBJQzBnVTNWeWRXMGdNVEFlRncweE16RXhNalV3T0RJMU5UVmFGdzAwTXpFd01qVXdPREkxTlRWYU1JSFNNUXN3Q1FZRApWUVFHRXdKVVVqRVlNQllHQTFVRUJ4TVBSMlZpZW1VZ0xTQkxiMk5oWld4cE1VSXdRQVlEVlFRS0V6bFVkWEpyYVhsbElFSnBiR2x0CmMyVnNJSFpsSUZSbGEyNXZiRzlxYVdzZ1FYSmhjM1JwY20xaElFdDFjblZ0ZFNBdElGUlZRa2xVUVVzeExUQXJCZ05WQkFzVEpFdGgKYlhVZ1UyVnlkR2xtYVd0aGMzbHZiaUJOWlhKclpYcHBJQzBnUzJGdGRTQlRUVEUyTURRR0ExVUVBeE10VkZWQ1NWUkJTeUJMWVcxMQpJRk5OSUZOVFRDQkxiMnNnVTJWeWRHbG1hV3RoYzJrZ0xTQlRkWEoxYlNBeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQXIzVXdNNnE3YTlPWkxCSTNoTm1OZTVlQTAyN24vNXRRbFQ2UWxWWkMxeGw4Sm9TTmt2b0JIVG9QNG1RNHQ0eTgKNklqNWl5U3JMcVAxTitSQWpoZ2xlWU4xSHp2L2JLakZ4bGI0dE8yS1JLT3JiRXo4SGREYzcyaTl6K1NxenZCVjk2STAxSU5yTjN3Ywp3djYxQSt4WHpyeTB0Y1h0QUE5VE55cE45RThNZy91R3o4ditqRTY5aC9tbml5RlhuSHJmQTJlSkxKMlhZYWNRdUZXUWZ3NHRKemgwCjMrZjkyazRTNDAwVklnTEk0T0Q4RDYySzE4bFVVTXc3RDhvV2dJVFFVVmJEamxaL2lTSXpMK2FGQ3IybHFCczIzdFBjTEcwN3h4TzkKV1NNczV1V2s5OWdMN2VxUVFFU29sYnVUMWRDQU5MWkdlQTRmQUpORzRlN3ArZXhQRndJREFRQUJvMEl3UURBZEJnTlZIUTRFRmdRVQpaVC9IaW9iR1BOMDhWRncxK0RydFVneEhWOGd3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKCktvWklodmNOQVFFTEJRQURnZ0VCQUNvLzRmRXlqcTdobUZ4TFhzOXJIbW9KMGlLcEVzZGVWMzF6Vm1TQWhIcVQ1QW01RU0yZktpZmgKQUhlK1NNZzFxSUdmNUxnc3lYOE9zTkpMTjEzcXVkVUxYalM5OUhNcHcrMG1GWngrQ0ZPS1dJM1FTeWpmd2JQZklQUDU0K002Mzh5YwpsTmhPVDhOckY3ZjNjdWl0WmpPMUpWT3I0UGhNcVozOThnMjZycm5acXNacitaTzdycXU0bHp3REdycER4cGE1UlhJNHM2ZWhsajJSCmUzN0FJVk5NaCszeUMxU1ZVWlBWSXFVTml2R1REajVVRHJEWXlVN2M4akV5VnVwaytlcTFuUlptUW5MemY5T3hNVVA4cEk0WDhXMGoKcTVSbStLMzdEd2h1SmkxL0Z3Y0pzb3o3VU1DZmxvM1B0djBBblZvVW1yOENSUFhCd3A4aVhxSVBvZU09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdEQ0EgVHJ1c3RBVVRIIFI1IFJPT1QKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmlEQ0NBM0NnQXdJQkFnSUlmUW1YL3ZCSDZub3dEUVlKS29aSWh2Y05BUUVMQlFBd1lqRUxNQWtHQTFVRUJoTUNRMDR4TWpBdwpCZ05WQkFvTUtVZFZRVTVISUVSUFRrY2dRMFZTVkVsR1NVTkJWRVVnUVZWVVNFOVNTVlJaSUVOUExpeE1WRVF1TVI4d0hRWURWUVFECkRCWkhSRU5CSUZSeWRYTjBRVlZVU0NCU05TQlNUMDlVTUI0WERURTBNVEV5TmpBMU1UTXhOVm9YRFRRd01USXpNVEUxTlRrMU9Wb3cKWWpFTE1Ba0dBMVVFQmhNQ1EwNHhNakF3QmdOVkJBb01LVWRWUVU1SElFUlBUa2NnUTBWU1ZFbEdTVU5CVkVVZ1FWVlVTRTlTU1ZSWgpJRU5QTGl4TVZFUXVNUjh3SFFZRFZRUUREQlpIUkVOQklGUnlkWE4wUVZWVVNDQlNOU0JTVDA5VU1JSUNJakFOQmdrcWhraUc5dzBCCkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQTJhTVc4TWgwZEhlYjd6TU5Pd1orVmZ5MVlJOTJoaEpDZlZabVBvaUM3WEpqRHA2TDNUUXMKQWxGUnd4bjlXVlNFeWZGcnMweXc2ZWhHWFRqR29xY3VFVmU2Z2hXaW5JOXRzSmxLQ3ZMcmlYQmpUbm5FdDF1OW9sMng4a0VDSzYycApPcVBzZVFyc1h6cmovZStBUEswMG14cXJpQ1o3VnFLQ2hoL3JOWW1EZjErdUtVNDl0bTdzcnNId0o1dXU0L1RzNzY1Lzk0WTljbnJyCnBmdFpUcWZybFl3aU9YbmhMUWlQekx5UnVFSDNGTUVqcWNPdG1rVkVzN0xYTE0zR0tlSlFFSzVjeTRLT0Z4ZzJmWmZtaUpxd1RUUUoKOUN5NVdtWXFzQmVibmg1Mm5VcG1NVUhmUC92RkJ1OGJ0bjRhUmpiM1pHTTc0emtZSStkbmRSVFZkVmVTTjcyK2Foc21VUEkySmdhUQp4WEFCWkcxMlp1R1IyMjRId0dHQUxySXVMNHh3cDlFN1BMT1I1RzYyeER0dzhteVNsd25OUjMwWXdQTzduZy9XaTY0SHRsb1B6Z3NNClI2ZmxQcmk5ZmNlYk5hQmhsenBCZFJmTUs1WjNLcEloSHRtVmRpQm5hTThOdmQvV0h3bHFtdUxNYzNHa0wzMFNnTGRUTUVaZVMxU1oKRDJmSnBjanlJTUdDN0owUjM4SUMreG83MGUwZ211OWxaSklRRFNyaTNuRHhHR2VDakdIZXVMelJMNXo3RDlBcjdSdDJ1ZVE1VmZqNApvUjI0cW9BQVRJTG5zbjhKdUx3d29DOE45VktlanZlU3N3b0FIUUJVbHdiZ3NRZlp4dzljWlgwOGJWbFg1TzJsamVsQVU1OFZTNkJ4Cjlob2g0OXB3QmlGWUZJZUZkM21xZ25rQ0F3RUFBYU5DTUVBd0hRWURWUjBPQkJZRUZPTEpRSjlOenVpYW9YelBEajlseFNtSWFobFIKTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnR0dNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUURSU1ZmZwpwOHhvV0xvQkR5c1p6WTJ3WVVXc0VlMWpVR240SDMrK0ZvLzluZXNMcWpKSGR0Sm5KTzI5ZkRNeWx5ckhCWVptRFJkOUZCVWIxT3Y5Ckg1cjJYcGRwdHhvbHBBcXprVDlmTnF5TDdGZW9QdWVCaWhoWE9ZVjBHa0xINlZzVFg0LzVDT21TZEkzMVI5S3JPOWI3ZUdaT05uMzUKNlpMcEJONzlTV1A4YmZzVWNaTm5MMGRLdDduL0hpcHpjRVl3djFyeUwzbWw0WTBNMmZteVl6ZU1OMldGY0dwY1d3bHl1YTFqUExIZAorUHd5dnplRzVMdU9tQ2QrdWg4VzRYQVI4Z1BmSldJeUp5WVlNb1NmL3dBNkU3cWFUZlJQdUJSd0lySEtLNURPS2NGdzlDK2RmL0tRCkh0WmEzN2RHL09hRytzdmdJSFo2dXFiTDlYemVZcVd4aSs3ZWdtYUtUam93SHorQXk2MG51Z3hlMTlDeFZzcDNjYksxZGFGUXFVQkQKRjhJbzJjOVNpMXZJWTlSQ1BxQXpla1l1OXdvZ1JsUithazh4OFlGK1FuUTRaWE1uN3NaOHVJN1hwVHJYbUtHY2pCQlYwOXRMN0VDUQo4czF1VjlKaURueFhrN0duYmMyZGc3c3E1K1cyTzNGWXJmM1JSYnhha2U1VEZXL1RSUWwxYnJxUVhSNEV6emZmSHFobXNZem1JR3J2Ci9FaE9kSmhDcnlsdkxtckgrMzNSWmpFaXpJWUFmbWFEREVMMHZUU1N3eHJxVDhwK2NrMExjSXltU0x1bW9SVDIrMWhFbVJTdXFndVQKYWFBcEpVcWx5eXZkaW1ZSEZuZ1ZWM0ViN1BWSGhQT2VNVGQ2MVg4a3JlUzgvZjNNYm9Qb0RLaTNRV3dIM2IwOGhwY3YwZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRydXN0Q29yIFJvb3RDZXJ0IENBLTEKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRU1EQ0NBeGlnQXdJQkFnSUpBTnFiN0hIekE3QVpNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1JR2tNUXN3Q1FZRFZRUUdFd0pRUVRFUApNQTBHQTFVRUNBd0dVR0Z1WVcxaE1SUXdFZ1lEVlFRSERBdFFZVzVoYldFZ1EybDBlVEVrTUNJR0ExVUVDZ3diVkhKMWMzUkRiM0lnClUzbHpkR1Z0Y3lCVExpQmtaU0JTTGt3dU1TY3dKUVlEVlFRTERCNVVjblZ6ZEVOdmNpQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnAKZEhreEh6QWRCZ05WQkFNTUZsUnlkWE4wUTI5eUlGSnZiM1JEWlhKMElFTkJMVEV3SGhjTk1UWXdNakEwTVRJek1qRTJXaGNOTWpreApNak14TVRjeU16RTJXakNCcERFTE1Ba0dBMVVFQmhNQ1VFRXhEekFOQmdOVkJBZ01CbEJoYm1GdFlURVVNQklHQTFVRUJ3d0xVR0Z1CllXMWhJRU5wZEhreEpEQWlCZ05WQkFvTUcxUnlkWE4wUTI5eUlGTjVjM1JsYlhNZ1V5NGdaR1VnVWk1TUxqRW5NQ1VHQTFVRUN3d2UKVkhKMWMzUkRiM0lnUTJWeWRHbG1hV05oZEdVZ1FYVjBhRzl5YVhSNU1SOHdIUVlEVlFRRERCWlVjblZ6ZEVOdmNpQlNiMjkwUTJWeQpkQ0JEUVMweE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdjQ2M2xlTENKaEpyTXhuSFFGZ0txMW1xCmpRQ2ovSURIVUh1TzFDQW11aklTMkNOVVNTVVFJcGlkUnRMQnlaNU9HeTRzRGpqekdpVm9IS1phQmVZZWkwaS9tSlowUG1uSzZiVjQKcFFhODFRQmVDUXJ5SjNwUy9DM1ZzZXEwaVdFazh4b1QyNm5QVXUwTUpMcTVudXgrQUhUNms2MXNLWkt1VWJTNzAxZS9zL09valp6MApKRXNxMXBtZTlKNyt3SDVDT3VjTGxWUGF0MmdPa0V6N2NEK1BTaXlVOHliZFkybXBsTmdRVHNWSENKQ1pHeGROdVd4dTcyQ1ZFWTRoCmdMVzlvSFBZMExKM3hFWHFXaWI3Wm5aMitBWWZZVzBQVmNXRHR4QldjZ1lIcGZPeEdnTUZaQTZkV29yV2huQWJKTjcrS0lvcjBHcXcKL0hxaTNMSjVEb3RsRHdJREFRQUJvMk13WVRBZEJnTlZIUTRFRmdRVTdtdEpQSG8vRGVPeENiZUt5S3NabjNNelVPY3dId1lEVlIwagpCQmd3Rm9BVTdtdEpQSG8vRGVPeENiZUt5S3NabjNNelVPY3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DCkFZWXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQ1VZMUpHUEUrNlBIaDBSVTlvdFJDa1pvQjVyTVo1TkRwNnRQVnhCYjVVckpLRjUKbURvNE52dTdacDVJLzVDUTd6M1V1SnUwaDNVL0lKdk9jcytoVmNGTlpLSVpCcUVITXd3TEtlWHg2cXVqN0xVS2RKREhmWEx5MTF5ZgprZStSaTdmYzdXYWl6NDVtTzd5Zk9nTGdKOTBXbU1DVjFBcWs1SUdhZFpRMW5KQmZpRGNHclZtVkNyRFJaOU1aeW9ubk1sbzJIRDZDCnFGcVR2c2JRWkpHMno5bTJHTS9iZnRKbG82YkVqaGN4d2Z0K2R0dlRoZU5Zc25kNmRqdHNMMUFjNTl2Mloza2Y5WUtWbWdlbkZLK1AKM0NnaFp3blMxazFhSEJrY2puZGN3NVFrUFRKclMzN1VlSlNEdmpkTnpsL0hIazQ4NElremxRc1BwVExXUEZwNUxCaz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMgo9PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlHTHpDQ0JCZWdBd0lCQWdJSUphSGZ5alBMV1FJd0RRWUpLb1pJaHZjTkFRRUxCUUF3Z2FReEN6QUpCZ05WQkFZVEFsQkJNUTh3CkRRWURWUVFJREFaUVlXNWhiV0V4RkRBU0JnTlZCQWNNQzFCaGJtRnRZU0JEYVhSNU1TUXdJZ1lEVlFRS0RCdFVjblZ6ZEVOdmNpQlQKZVhOMFpXMXpJRk11SUdSbElGSXVUQzR4SnpBbEJnTlZCQXNNSGxSeWRYTjBRMjl5SUVObGNuUnBabWxqWVhSbElFRjFkR2h2Y21sMAplVEVmTUIwR0ExVUVBd3dXVkhKMWMzUkRiM0lnVW05dmRFTmxjblFnUTBFdE1qQWVGdzB4TmpBeU1EUXhNak15TWpOYUZ3MHpOREV5Ck16RXhOekkyTXpsYU1JR2tNUXN3Q1FZRFZRUUdFd0pRUVRFUE1BMEdBMVVFQ0F3R1VHRnVZVzFoTVJRd0VnWURWUVFIREF0UVlXNWgKYldFZ1EybDBlVEVrTUNJR0ExVUVDZ3diVkhKMWMzUkRiM0lnVTNsemRHVnRjeUJUTGlCa1pTQlNMa3d1TVNjd0pRWURWUVFMREI1VQpjblZ6ZEVOdmNpQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGt4SHpBZEJnTlZCQU1NRmxSeWRYTjBRMjl5SUZKdmIzUkRaWEowCklFTkJMVEl3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ25JRzdDS3FKaUpKV1Fkc2c0Zm9EU3E4R2IKWlFXVTlNRUtFTlVDck8yZms4ZUh5TEFuSzBJTVBRbytRVnFlZGQyTnl1Q2I3R2d5cEdtU2FJd0xnUTVXb0Q0YTNTd2xGSUl2bDlOawpSdlJVcWR3NlZDMHhLNW1DOHRrcTErOXhBTGd4cEw1NkpBZkRRaUR5aXRTU0JCdGxWa3hzMVB1MllWcEhJN1RZYWJTM090QjBQQXgxCm9ZeE9kcUhwMnlxbE8vck9zUDkrYWlqOUp4eklzZWtwOFZkdVpMVFF3UlZ0RHI0dURrYklYdlJSL3U4T1l6bzdjYnJQYjFuS0RPT2IKWFVtNFRPSlhzWmlLUWxlY2R1L3Z2ZEZvcU5MMENidDNOYjRsZ2dqRUZpeEVJRmFwUkJGMzcxMjBIYXBlYXo2TE12WUhMMWNFa3NyMQovcDNDNmVpempreExBakhaNUR4SWdpZjNHSUoyU0RweHNST2hPZFV1eFRUQ0hXS0Yzd1ArVGZTdlBkOWNXNDM2Y09HbGZpZkhoaTVxCmp4TEdoRjVEVVZDY0dadDQ1dnoyN1VkK2V6MW03eE1UaUY4OG9XUDcrYXlITlovemdwNmtQd3FjTVdtTG1hU0lTbzV1WmszdkZzUVAKZVNnaFlBMkZGbjNYVkRqeGtsYjl0VE5NZzl6WEVKOUwvY2I0UXIyNmZITUM0UDk5elZ2aDFLeGhlMWZWU250YjFJVllKMTIvK0N0ZwpyS0FtcmhRaEo4WjNtak9BUEY1R1AvZkRzYU9HTThib1hnMjVOU3lxUnNHRkFuV0FvT3NrK3hXcTVHZC9ibmMvOUFTS0wzeDc0eGRoCjhOMEpxU0RJdmdtazBINUV3N0l3U2ppcXFld1ltZ2VDSzl1NG5CaXQydUJHRjZ6UFhRSURBUUFCbzJNd1lUQWRCZ05WSFE0RUZnUVUKMmY0aFFHNlVucnliUFp4OW1DQVo1WXd3WXJJd0h3WURWUjBqQkJnd0ZvQVUyZjRoUUc2VW5yeWJQWng5bUNBWjVZd3dZckl3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBWVl3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUo1Rm5ndzd0dS9oCk9zaDgwUUE5eitMcUJyV3lPcnNHUzJoNjBDT1hkS2NzOEFqWWVWclhXb1NLMkJLYUc5bDlYRTF3eGFYNXErV2ppWW5kQWZyczNmbnAKa3BmYnNFWkM4OU5pcXBYK01XY1VhVmlRQ3FvTDdqY2p4MUJSdFBWK251Tjc5K1RNUWpJdFNRekwvMGtNbXg0MC9XNXVsb3A1QTdadgoyd25ML1Y5bEZEZmhPUFh6WVJaWTVMVnREUXNFR3o5UUxYK3p4M29hRm9CZytJb2Y2UnNxeHZtNkFScHB2OUpZeDFSWENJL2hPV0IzClM2eFpoQnFJOGQzTFQzalg1K0V6TGZ6dVFmb2dzTDdMOXppVXdPSFFoUSs3N1N4enErMytrbllhWkg5YkRUTUpCek43Qmo4UnBGeHcKUElYQXorT1FxSU4zK3R2bXhZeG9aeEJucFZJdDhNU1pqMysvMFd2aXRVZlcyZENGbVUyVW13OUxqZTRBV2tjZEVRT3NRUml2aDdkdgpERHFQeXMvY0E4R2lDY2psL1lCZXlHQkNBUnNhVTFxN042YTN2THFFNlI1c0d0UmsydFJEL3BPTFMvSXNlUllRMUpNTGlJK2gySVlVClJwRkhteWdrNzFkU1RseENuS3IzU2V3bjZFQWVzNmFKSW5LYzlRMHp0RmlqTUR2ZDFHcFVrNzRhVGZPVGxQZjhoQXMvaENCY05BTkUKeGRxdHZBckJBczhlNVpUWjg0NWIyRXp3bmV4aEY3c1VNbFFNQWltVEhwS0c5bi92NTVJRkRsbmRtUWd1THZxY0FGTFR4V1lwNUtlWApSS1FPS0lFVE5jWDJiMlRtUWNUVkw4dzBSU1hQUVFDV1BVb3V3cGFZVDA1S25KZTMyeCtTTXNqL0QxRnUxdXdKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRydXN0Q29yIEVDQS0xCj09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFSURDQ0F3aWdBd0lCQWdJSkFJU0NMRjhjWXRCQU1BMEdDU3FHU0liM0RRRUJDd1VBTUlHY01Rc3dDUVlEVlFRR0V3SlFRVEVQCk1BMEdBMVVFQ0F3R1VHRnVZVzFoTVJRd0VnWURWUVFIREF0UVlXNWhiV0VnUTJsMGVURWtNQ0lHQTFVRUNnd2JWSEoxYzNSRGIzSWcKVTNsemRHVnRjeUJUTGlCa1pTQlNMa3d1TVNjd0pRWURWUVFMREI1VWNuVnpkRU52Y2lCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcApkSGt4RnpBVkJnTlZCQU1NRGxSeWRYTjBRMjl5SUVWRFFTMHhNQjRYRFRFMk1ESXdOREV5TXpJek0xb1hEVEk1TVRJek1URTNNamd3Ck4xb3dnWnd4Q3pBSkJnTlZCQVlUQWxCQk1ROHdEUVlEVlFRSURBWlFZVzVoYldFeEZEQVNCZ05WQkFjTUMxQmhibUZ0WVNCRGFYUjUKTVNRd0lnWURWUVFLREJ0VWNuVnpkRU52Y2lCVGVYTjBaVzF6SUZNdUlHUmxJRkl1VEM0eEp6QWxCZ05WQkFzTUhsUnlkWE4wUTI5eQpJRU5sY25ScFptbGpZWFJsSUVGMWRHaHZjbWwwZVRFWE1CVUdBMVVFQXd3T1ZISjFjM1JEYjNJZ1JVTkJMVEV3Z2dFaU1BMEdDU3FHClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURQaitBUnRaK29kbmJiM3c5VTczTmpLWUt0UjhhamErMytYelA0UTFIcEdqT1IKTVJlZ2RNVFVwd0htc3BJK2FwM3REdmwwbUVEVFB3T0FCb0pBNkxIaXAxR25IWU1tYTZ2ZStoZVJLOWpHckI2eG5oa0IxWmVtNmcyMwp4RlVmSjN6U0NOVjJIeWtWaDBBNTNUaEZFWFhRbXFjMDRML055RklkdVVkK0RiaTd4Z3oyYzFjV1duNURrUjlWT3NadFJBU3FuS21jCnAweUpGNE91b3dSZVVvQ0xIaElsRVJuWERIMTlNVVJCNnR1dnNCenZnZEFzeFpvaG16M3RRanRRSnZMc3puRmhCbUloVkU1L3daMCsKZnlDTWdNc3EySmRpeUlNemtYMndvbG9QVitnN3pQSWxzdFI4TCt4TnhxRTZGWHJudGwwMTlmWklTalpGWnRTNm1GakJBZ01CQUFHagpZekJoTUIwR0ExVWREZ1FXQkJSRW5rajF6RzFJMUtCTGYvNVpKQytEbDVtYWhqQWZCZ05WSFNNRUdEQVdnQlJFbmtqMXpHMUkxS0JMCmYvNVpKQytEbDVtYWhqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCaGpBTkJna3Foa2lHOXcwQkFRc0YKQUFPQ0FRRUFCVDQxWEJWd204bkhjMkZ2Y2l2VXdvL3lRMTBDenNTVXVaUVJnMmRkNG1kc2RYYS91d3lxTnNhdFI1TmozQjUrMXQ0dQovdWtaTWpnRGZ4VDJBSE1zV2JFaEJ1SDdyQmlWREtQL21aYjNLeWViMVNUTUhkM0JPdUNZUkxERTVENTNzWE9wWkN6MkhBRjhQMTFGCmhjQ0Y1eVdQbGR3WDh6eWZHbTZ3eXVNZEt1bE1ZL29rWVdMVzJuNjJIR3oxQWgzVUt0MVZrT3NxRVVjOExsNTBzb0lpcFgxVEgwWHMKSjVGOTV5SVc2TUJvTnRqRzhVK0FSREw1NGRIUkhhcmVxS3VjQksrdElBNWttRTJsYThCSVdKWnBUZHdIakZHVG90K2ZEejJMWUxTQwpqYW9JVG1KRjRQa0wwdURnUEZ2ZVhIRW5KY0xtQTRHTEVGUGp4MVdpdEovWDVnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU1NMLmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGM1RDQ0E4V2dBd0lCQWdJSWV5eWIweGFBTXBrd0RRWUpLb1pJaHZjTkFRRUxCUUF3ZkRFTE1Ba0dBMVVFQmhNQ1ZWTXhEakFNCkJnTlZCQWdNQlZSbGVHRnpNUkF3RGdZRFZRUUhEQWRJYjNWemRHOXVNUmd3RmdZRFZRUUtEQTlUVTB3Z1EyOXljRzl5WVhScGIyNHgKTVRBdkJnTlZCQU1NS0ZOVFRDNWpiMjBnVW05dmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNCU1UwRXdIaGNOTVRZdwpNakV5TVRjek9UTTVXaGNOTkRFd01qRXlNVGN6T1RNNVdqQjhNUXN3Q1FZRFZRUUdFd0pWVXpFT01Bd0dBMVVFQ0F3RlZHVjRZWE14CkVEQU9CZ05WQkFjTUIwaHZkWE4wYjI0eEdEQVdCZ05WQkFvTUQxTlRUQ0JEYjNKd2IzSmhkR2x2YmpFeE1DOEdBMVVFQXd3b1UxTk0KTG1OdmJTQlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVJRkpUUVRDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRApnZ0lQQURDQ0Fnb0NnZ0lCQVBrUDNhTXJmY3ZRS3Y3c1o0V201eTRidW5maDQvV3ZwT3o2U2wyUnhGZEhheGgzYTNieS9aUGtQUS9DCkZwNExac05XbEo0WGc0WE9WdS95RnYwQVl2VWlDVlRvWlJkT1FibmdUMGFYcWh2SXVHNWlYbW14WDlzcUFuNzhiTXJ6UWRqdDBPajgKUDJGSTdiQURGQjBRRGtzWjRMdE83SVpsL3pielhtY0NDNTJHVldIOWVqanQvdUlaQUxkdm9WQmlkWFE4b1BySUpaSzBibm9peC9nZQpvZU95M1pFeHF5c2RCUCtsU2dRMzZZV2tNeXY5NHRaVk5Id1pwRXBveDdLbzA3ZktvWk9JNjhHWHZJejVIZGtpaENSMHh3UTlhcWtwCms4enJ1RnZoL2w4bHFqUll5TUVqVkowYm1CSERPSngrUFlac3BROUFobndDOUZ3Q1R5akxybkdmRHpySU0vNFJKVFhxL0xyRllEM1oKZkJqVnNxblRkWGdEY2lMS09zTWY3eXpsTHFuNm5peTJVVWI5cndQVzZtQm82b1VXTm11RjZSN0FzOTNFSk55QUtvRkJiWlEreU9ESgpnVUVBbmw2L2Y4VUltS0lZTEVKQXMvbHZPQ2RMVG9EMFBZRkg0SWg4Nmh6T3RYVmNVUzRjSzM4YWNpam5BTFhSZE1iWDVKK3RCNU8yClV6VTEvRGZrdy9aZEZyNGhjOTZTQ3ZpZ1kycThscEpxUHZpOFpWV2IzdlVOaVNZRS9DVWFwaVZweThKdHluemlXVitYck92dkxzaTgKMXh0WlBDdk04aG5JazJzbll4blAvT2ttK01weG0zK1QvalJuaEU2WjYveXplQWt6Y0xwbXBuYnRHM1ByR3FVTnhDSVRJSlJXQ2s0cwpiRTZ4L2MrY0NicWlNKzJIQWdNQkFBR2pZekJoTUIwR0ExVWREZ1FXQkJUZEJBa0hvdlY2ZlZKVEVwS1Y3amlBSlEybVdUQVBCZ05WCkhSTUJBZjhFQlRBREFRSC9NQjhHQTFVZEl3UVlNQmFBRk4wRUNRZWk5WHA5VWxNU2twWHVPSUFsRGFaWk1BNEdBMVVkRHdFQi93UUUKQXdJQmhqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFJQmdSbENuN0pwMGNIaDV3WWZHVmNwTnhKSzFvazFpT01xOGJzM0FEL0NVcgpkSVdRUFhocTlMbUxwWmM3dFJpUnV4Nm4rVUJia2ZsVm1hOGVFZEJjSGFkbTQ3R1VCd3d5T2FicUc3QjUyQjJjY0VUaml0M0UrWlVmCmlqaERQd0dGcFVlblBVYXl2T1VpYVBkN25OZ3NQZ29oeUMwenJML0ZnWmt4ZE1GMWNjVytzZkFqUmZTZGEvd1pZNTJqdkFUR0dBc2wKdTFPSkQ3T0FVTjVGN2tSL3E1UjRaSmpUOWlqZGg5aHdaWFQ3RHJrVDY2Y1BZYWt5bHN6ZXUrMWpUQmk3cVVEM29GUnVJSWh4ZFJqcQplclEwY3VBakozZGN0cERxaGlWQXErOHpEOHVmZ3I2aUlQdjJ0UzBhNXNLRnNYUVArOGhsQXFSU0FVZmRTU0xCdjlqcmE2eCszdXhqCk14VzNJd2lQeGcrTlFWcmRqc1c1aitWRlAzamJ1dEliUUxIK2NVMC80SUdpdWw2MDdCWGdrOTBJSDM3aFZaa0xJZDZUbmdyNzVxTkoKdlRZdy91ZDNzcUIxbDdVdGdZZ1haU0QzMnBBQW44bFN6RExLTlh6MVBRL1lLOWYxSm16SkJqU1dGdXB3V1JveWVYa0x0b2gvRDFKSQpQYjlzMktKRUx0Rk90M0pZMDRrVGxmNUVxL2pYaXh0dW5Md3NvRnZWYWdDdlh6ZmgxZm9RQzVpY2h1Y21qODd3N0c2S1Z3dUE0MDZ5CndLQmpZWkM2VldnM2RHcTJrdHVmb1lZaXRtVW5EdXkybjBKZzVHZkN0ZHBCQzhUVGkyRWJ2UG9ma1N2WFJBZGV1aW1zMmNYcDcxTkkKV3V1QThTaFlJYzJ3QmxYN0p6OVRrSENwQkI1WEo3az0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU1NMLmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDalRDQ0FoU2dBd0lCQWdJSWRlYmZ5OEZvVzZnd0NnWUlLb1pJemowRUF3SXdmREVMTUFrR0ExVUVCaE1DVlZNeERqQU1CZ05WCkJBZ01CVlJsZUdGek1SQXdEZ1lEVlFRSERBZEliM1Z6ZEc5dU1SZ3dGZ1lEVlFRS0RBOVRVMHdnUTI5eWNHOXlZWFJwYjI0eE1UQXYKQmdOVkJBTU1LRk5UVEM1amIyMGdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlU0JGUTBNd0hoY05NVFl3TWpFeQpNVGd4TkRBeldoY05OREV3TWpFeU1UZ3hOREF6V2pCOE1Rc3dDUVlEVlFRR0V3SlZVekVPTUF3R0ExVUVDQXdGVkdWNFlYTXhFREFPCkJnTlZCQWNNQjBodmRYTjBiMjR4R0RBV0JnTlZCQW9NRDFOVFRDQkRiM0p3YjNKaGRHbHZiakV4TUM4R0ExVUVBd3dvVTFOTUxtTnYKYlNCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlFVkRRekIyTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQTJJQQpCRVZ1cVZERXBpTTJubDhvalJmTGxpSmtQOXg2amgzTUNMT2ljU1M2amttNUJCdEhsbGlyTFpYSTdaNElOY2duNjRtTVUxanJZb3IrCjhGc1BhekZTWTBFN2ljM3M3TGFOR2RNMEI5eTd4Z1ovd2tXVjdNdC9xQ1BnQ2VtQit2TkgwNk5qTUdFd0hRWURWUjBPQkJZRUZJTFIKaFhNdzV6VUUwNDRDa3Z2bHBOSEVJZWpOTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SHdZRFZSMGpCQmd3Rm9BVWd0R0ZjekRuTlFUVApqZ0tTKytXazBjUWg2TTB3RGdZRFZSMFBBUUgvQkFRREFnR0dNQW9HQ0NxR1NNNDlCQU1DQTJjQU1HUUNNRy9uNjFrUnBHRFBZYkNXCmUrMEYrUzhUa2R6dDVmeFFheEZHUnJNY0lRQml1NzdENStqTkI1bjVEUXRkY2o3RXFnSXdIN3k2QytJd0pQdDhiWUJWQ3BrK2dBMHoKNVdhanM2TzdwZFdMandrc3BsMSs0dkFIQ0dodDBueHBibC9mNVdwbAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUY2ekNDQTlPZ0F3SUJBZ0lJVnJZcHpUUzhlUFl3RFFZSktvWklodmNOQVFFTEJRQXdnWUl4Q3pBSkJnTlZCQVlUQWxWVE1RNHcKREFZRFZRUUlEQVZVWlhoaGN6RVFNQTRHQTFVRUJ3d0hTRzkxYzNSdmJqRVlNQllHQTFVRUNnd1BVMU5NSUVOdmNuQnZjbUYwYVc5dQpNVGN3TlFZRFZRUUREQzVUVTB3dVkyOXRJRVZXSUZKdmIzUWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrZ1VsTkJJRkl5Ck1CNFhEVEUzTURVek1URTRNVFF6TjFvWERUUXlNRFV6TURFNE1UUXpOMW93Z1lJeEN6QUpCZ05WQkFZVEFsVlRNUTR3REFZRFZRUUkKREFWVVpYaGhjekVRTUE0R0ExVUVCd3dIU0c5MWMzUnZiakVZTUJZR0ExVUVDZ3dQVTFOTUlFTnZjbkJ2Y21GMGFXOXVNVGN3TlFZRApWUVFEREM1VFUwd3VZMjl0SUVWV0lGSnZiM1FnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2dVbE5CSUZJeU1JSUNJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQWp6WmxRT0hXVGNEWHRPbEcybXZxTTBmTlRQbDlmYjY5TFQzdzIzamgKaHFYWnVnbFhhTzFYUHFEUUNFR0Q1eWhCSkIvamNoWFFBUnI3WG5BanNzdWZPZVBQeFU3R2ttMG14bnU3czlvbm5RcUc2WUUzQmY3dwpjWEhzd3h6cFk2SVhGSjN2RzJmVGhWVUNBdFpKeWN4YTRiSDNiektmeWRRN2lFR29uTDNMcTl0dGV3a2Zva3h5a05vckNQelBQRlRPClp3K296MTJXR1F2RTQzTHJyZEY5SFNmdmt1c1F2MXZyTzYvUGdOM0IwcFlFVzNwK3BLazhPSGFrWW82Z09WN3FkODlkQUZtUFppdysKQjZLakJTWVJhWmZxaGJjUGxndEx5RURoVUxvdWlzdjNENW9pNTMrYU54UE44azBUYXlIUndNd2k4cUZHOWtScG5NcGhOUWNBYjlaaApDQkhxdXJqMjZiTmc1VTI1N0o4VVpzbFhXTnZOaDJuNGlvWVNBMGUvWmhOMnJIZDlOQ1NGZzgzWHFweVFHcDhoTEg5NHQyUzQyT2ltCjlIaXpWY3VFMGpMRWVLNmpqMkhkemdoVHJleUkvQlhrbWczbW54cDN6a3lQdUJRVlBXS2NoamdHQUdZUzVGbDJXbFBBQXBpaUVDdG8KUkh1T2VjNHpTbmFxVzRFV0c3V0syTkFBZTE1aXRBbldobU1PcGdXVlNib29pNGlUc2pRYzJLUlZicmNjME42WlZUc2o5Q0xnK1NsbQpKdXdnVUhmYlNndVB2dVVDWUhCQlh0U3VVRGtpRkNiTHNqdHpkRlZIQjNtQk9hZ3dFMFRsQklxdWxoTWxRZys1VThTYi9NM2tITjQ4CitxdldCa29mWjZhWU1CemRMTnZjR0pWWFpzYi9YSXRXOVhjQ0F3RUFBYU5qTUdFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZkJnTlYKSFNNRUdEQVdnQlQ1WUx2VTQ5VTA5cmoxQm9BbHAzUGJSbW1vbmpBZEJnTlZIUTRFRmdRVStXQzcxT1BWTlBhNDlRYUFKYWR6MjBacApxSjR3RGdZRFZSMFBBUUgvQkFRREFnR0dNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJXczQ3TENwMUpqcitreEpHN1poY0ZVWmgxCisrVlFMSHFlOFJUNnE5T0tQditSS1k5amk5aTBxVlFCRGI2VGhpLzVTbTNIWHZWWCtjcFZIQksrUnc4MnhkOXF0OXQxd2tjbGY3bngKWS9ob0xWVUUwZktOc0tUUHZEeGVIM2pucGFBZ2NMQUV4YmYzY3FmZUlnMjlNeVZHakdTU0p1TStMbU9XMnB1TVBmZ1lDZGNEekgyRwpndURLQkFkUlVOZi9rdFVNNzlxR241blg2N2V2YU9JNUpwUzZhTGUvZzlQcWVtYzlZbWV1SmVWeTZPTGs3SzRTOWtzclBKL3BzRUR6Ck9GU3ovYmRveU5yR2oxRThzdnVSM0J6bm01M2h0dzF5aitLa3hLbDQrZXNVck1aREJjSmxPU2dZQXNPQ3NwMEZ2bVh0bGw5bGREejcKQ1RVdWU1d1QvUnNQWGNkdGdUcFdEOHc3NGE4Q0x5S3NSc3BHUEtBY1ROWkV0RjR1WEJWbUNlRW1LZjdHVW1HNnNYUC93d3ljNVd4cQpsRDhVeWtBV2xZVHpXYW1zWDB4aGsyM1JPOHlpbFF3aXBtZG5SQzY1MmRLS1FiTm1DMXI3ZlNPbDhocXcvOTZiZzVRdTBUL2ZrcmVSCnJ3VTdaY2VnYkxITlloTERrQnZqSmM0MHZHOTNkckVRdy9jRkdzRFdyM1JpU0JkM2ttbVFZUnplbFlCMFZJOFlITVB6QTlDL3BFTjEKaGxNWWVnb3VDUncybjVIOWdvb2lTOUVPVUNYZHl3TU1GOG1EQUFoT05VMktpKzN3QXBSbUxFUi95NVVubGhldENUQ3N0bkVYYm9zWAo5aHdKMUMwN21LVngwMVFUMldEejlVdG1UL3J4N2lBU2piU3NWN0ZGWTZHc2RxbkMrdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ2xEQ0NBaHFnQXdJQkFnSUlMQ21jV3hidEJaVXdDZ1lJS29aSXpqMEVBd0l3ZnpFTE1Ba0dBMVVFQmhNQ1ZWTXhEakFNQmdOVgpCQWdNQlZSbGVHRnpNUkF3RGdZRFZRUUhEQWRJYjNWemRHOXVNUmd3RmdZRFZRUUtEQTlUVTB3Z1EyOXljRzl5WVhScGIyNHhOREF5CkJnTlZCQU1NSzFOVFRDNWpiMjBnUlZZZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQkZRME13SGhjTk1UWXcKTWpFeU1UZ3hOVEl6V2hjTk5ERXdNakV5TVRneE5USXpXakIvTVFzd0NRWURWUVFHRXdKVlV6RU9NQXdHQTFVRUNBd0ZWR1Y0WVhNeApFREFPQmdOVkJBY01CMGh2ZFhOMGIyNHhHREFXQmdOVkJBb01EMU5UVENCRGIzSndiM0poZEdsdmJqRTBNRElHQTFVRUF3d3JVMU5NCkxtTnZiU0JGVmlCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlFVkRRekIyTUJBR0J5cUdTTTQ5QWdFR0JTdUIKQkFBaUEySUFCS29TUjVDWUcvdnZ3MEFIZ3lCTzhUQ0NvZ2JSOHBLR1lmTDJJV2pLQU1USDZrTUFWSWJjL1IvZkFMaEJZbHpjY0JZeQozaCtaMU16RkI4Z0lIMkVXQjFFOWZWd0hVK00xT0l6ZnpaL1pMZzFLdGhrdVduQmFCdTIrOEtHd3l0QUpLYU5qTUdFd0hRWURWUjBPCkJCWUVGRnZLWHVYZTBvR3F6YWd0WkZHMjJYS2JsK1pQTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SHdZRFZSMGpCQmd3Rm9BVVc4cGUKNWQ3U2dhck5xQzFrVWJiWmNwdVg1azh3RGdZRFZSMFBBUUgvQkFRREFnR0dNQW9HQ0NxR1NNNDlCQU1DQTJnQU1HVUNNUUNLNWtDSgpOK3ZwMVJQWnl0UnJKUE93UFlkR1dCcnNzZDl2KzFhNmNHdkhPTXpvc1l4UEQvZnhaM1lPZzlBZVVZOENNRDMySXlnbVRNWmdoNU1tCm03STFIcnJXOXp6UkhNNzZKVHltR29FVlcvTVNEMnp1WllySmg2ajVCK0JpbW94Y1NnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR2xvYmFsU2lnbiBSb290IENBIC0gUjYKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZnekNDQTJ1Z0F3SUJBZ0lPUmVhN0E0TXp3NFZsU09iL1JWRXdEUVlKS29aSWh2Y05BUUVNQlFBd1RERWdNQjRHQTFVRUN4TVgKUjJ4dlltRnNVMmxuYmlCU2IyOTBJRU5CSUMwZ1VqWXhFekFSQmdOVkJBb1RDa2RzYjJKaGJGTnBaMjR4RXpBUkJnTlZCQU1UQ2tkcwpiMkpoYkZOcFoyNHdIaGNOTVRReE1qRXdNREF3TURBd1doY05NelF4TWpFd01EQXdNREF3V2pCTU1TQXdIZ1lEVlFRTEV4ZEhiRzlpCllXeFRhV2R1SUZKdmIzUWdRMEVnTFNCU05qRVRNQkVHQTFVRUNoTUtSMnh2WW1Gc1UybG5iakVUTUJFR0ExVUVBeE1LUjJ4dlltRnMKVTJsbmJqQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUpVSDZIUEtadm5zRk1wN1BQY05DUEcwUlFzcwpnclJJeHV0YlBLNkR1RUdTTXhTa2IzL3BLc3pHc0locnhiYUowY2F5L3hUT1VSUWg3RXJkRzFyRzFvZnVUVG9WQnUxa1pndVNnTXBFCjNuT1VUdk9uaVg5UGVHTUl5QkpRYlVKbUwwMjVlU2hOVWhxS0dvQzNHWUVPZnNTS3ZHUk1JUnhEYU5jOVBJckZzbWJWa0pxM01RYkYKdnVKdE1nYW1Idm01NjZxanVMKytnbU5RMFBBWWlkL2tEM24xNnFJZkt0SndMbnZudkpPN2JWUGlTSHlNRUFjNC8yYXlkMkYrNE9xTQpQS3EwcFBiemxVb1NCMjM5akxLSno5Q2dZWGZJV0hTdzFDTTY5MTA2eXFMYm5RbmVYVVF0a1BHQnpWZVMrbjY4VUFSak5OOXJreGkrCmF6YXlPZVNzSkRhMzhPKzJIQk5YazdiZXN2amloYmR6b3JnMXFrWHk0SjAyb1c5VWl2RnlWbTR1aU1WUlFrUVZsTzZqeFRpV20wNU8KV2d0SDh3WTJTWGN3dkhFMzVhYnNJUWgxL09aaEZqOTMxZG1SbDRRS2JOUUNUWFRBRk8zOU9mdUQ4bDRVb1FTd0Mrbis3by9oYmd1eQpDTE5oWmdscXNRWTZaWlpad1BBMS9jbmFLSTBhRVlkd2dRcW9tblVkbmpxR0JRQ2UyNERXSmZuY0JaNG5XVXgyT1Z2cSthV2gySU1QCjBmL2ZNQkg1aGM4elNQWEtiV1FVTEhwWVQ5TkxDRW5GbFdRYVl3NTVQZld6ak1wWXJaeENSWGx1RG9jWlhGU3haYmEvakp2Y0Ura04KYjdndTNHZHV5WXNSdFlRVWlnQVpjSU41a1plUjFCb252emNlTWdmWUZHTThLRXl2QWdNQkFBR2pZekJoTUE0R0ExVWREd0VCL3dRRQpBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJTdWJBV2preFBpb3VmaTF4eld4L0IveUdkVG9EQWZCZ05WCkhTTUVHREFXZ0JTdWJBV2preFBpb3VmaTF4eld4L0IveUdkVG9EQU5CZ2txaGtpRzl3MEJBUXdGQUFPQ0FnRUFneVh0Nk5IOWxWTE4KbnNBRW9KRnA1bHpRaE43Y3JhSlA2RWQ0MW1XWXFWdW9QSWQ4QW9yUmJyY1djK1pmd0ZTWTFYUyt3YzNpRVpHdEl4ZzkzZUZ5UkphMApsVjdBZTQ2WmVCWkRFMVpYczZLek83VjMzRUJ5cktQcm16VStzUWdob2VmRVF6ZDVNcjYxNTV3c1RMeERLWm1PTU5Pc0llRGpIZnJZCkJ6TjJWQUFpS3JsTklDNXdhTnJsVS95RFhOT2Q4djlFREVSbTh0TGp2VVlBR20wQ3VpVmRqYUV4VWQxVVJoeE4yNW1XN3hvY0JGeW0KRmU5NDRIbitYZHMrcWt4Vi9ab1ZxVy9ocHZ2ZmNERHB3KzVDUnUzQ2t3V0orbjFqZXovUWNZRjhBT2lZcmc1NE5NTWwrNjhLbnlCcgozVHNUanhLTTRrRWFTSHB6b0hkcHg3WmNmNExJSHY1WUd5Z3JxR3l0WG0zQUJkSjd0K3VBL2lVMy9nS2JhS3hDWGNQdTljemM4RkIxCjBqWnBuT1o3Qk45dUJtbTIzZ29KU0ZtSDYzc1VZSHBrcW1sRDc1SEhUT3dZM1d6dlV5Mk1tZUZlOG5JK3oxVEl2V2ZzcEE5TVJmL1QKdVRBakIweVBFTCtHbHRtWldyU1pWeHlrekxzVmlWTzZMQVVQNU1TZUdiRVlOTlZNbmJydDl4K3ZKSlVFZUtnRHUrNkI1ZHBmZkl0SwpvWkIwSmFlelBrdklMRmE5eDhqdk9PSmNrdkI1OTV5RXVuUXRZUUVnZm43UjhrOEhXVitMTFVOUzYwWU1sT0gxWmtkNWQ5VlVXeCt0CkpEZkxSVnBPb0VSSXlOaXdtY1VWaEFuMjFrbEp3R1c0NWhweGJxQ284WUxvUlQ1czFnTFhDbWVEQlZySnBCQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDYVRDQ0FlK2dBd0lCQWdJUUlTcFdESzdhREt0QVJiOHJvaTA2NmpBS0JnZ3Foa2pPUFFRREF6QnRNUXN3Q1FZRFZRUUdFd0pEClNERVFNQTRHQTFVRUNoTUhWMGxUWlV0bGVURWlNQ0FHQTFVRUN4TVpUMGxUVkVVZ1JtOTFibVJoZEdsdmJpQkZibVJ2Y25ObFpERW8KTUNZR0ExVUVBeE1mVDBsVFZFVWdWMGxUWlV0bGVTQkhiRzlpWVd3Z1VtOXZkQ0JIUXlCRFFUQWVGdzB4TnpBMU1Ea3dPVFE0TXpSYQpGdzAwTWpBMU1Ea3dPVFU0TXpOYU1HMHhDekFKQmdOVkJBWVRBa05JTVJBd0RnWURWUVFLRXdkWFNWTmxTMlY1TVNJd0lBWURWUVFMCkV4bFBTVk5VUlNCR2IzVnVaR0YwYVc5dUlFVnVaRzl5YzJWa01TZ3dKZ1lEVlFRREV4OVBTVk5VUlNCWFNWTmxTMlY1SUVkc2IySmgKYkNCU2IyOTBJRWRESUVOQk1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFVE9sUXdNWVBjaGk4MlBHNnM0bmllVXFqRnFkcgpWQ1RiVWYvcTlBa2t3d3Npbjh0cUo0S0JEZExBcnpIa2RJSnV5aVhaakhXZDhkdlFtcUpMSVg0V3AyT1Ewam5Vc1lkNFh4aVdEMUFiCk5UY1Bhc2JjMlJOTnBJNlFOK2E5V3pHUm8xUXdVakFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWQKQmdOVkhRNEVGZ1FVU0ljVXJPUERucEJnT3RmS2llN1RyWXkwVUdZd0VBWUpLd1lCQkFHQ054VUJCQU1DQVFBd0NnWUlLb1pJemowRQpBd01EYUFBd1pRSXdKc2RwVzl6VjU3TG55QXlNak1QZGVZd2JZOVhKVXBST1RZSktjeDZ5Z0lTcEpjQk1XbTFKS1dCNEUrSitTT3RrCkFqRUEyelFnTWdqL21ra0N0b2plRks5ZGJKbHhqUm8vaTlmZ29qYUdIQWVDT25aVC9jS2k3ZTk3c0lCUFdBOUxVem05Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdUUyBSb290IFIxCj09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGV2pDQ0EwS2dBd0lCQWdJUWJrZXB4VXRIREEzc005Q0p1UnowNFRBTkJna3Foa2lHOXcwQkFRd0ZBREJITVFzd0NRWURWUVFHCkV3SlZVekVpTUNBR0ExVUVDaE1aUjI5dloyeGxJRlJ5ZFhOMElGTmxjblpwWTJWeklFeE1RekVVTUJJR0ExVUVBeE1MUjFSVElGSnYKYjNRZ1VqRXdIaGNOTVRZd05qSXlNREF3TURBd1doY05Nell3TmpJeU1EQXdNREF3V2pCSE1Rc3dDUVlEVlFRR0V3SlZVekVpTUNBRwpBMVVFQ2hNWlIyOXZaMnhsSUZSeWRYTjBJRk5sY25acFkyVnpJRXhNUXpFVU1CSUdBMVVFQXhNTFIxUlRJRkp2YjNRZ1VqRXdnZ0lpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQzJFUUtMSHVPaGQ1czczTCtVUHJlVnAwQThvZjJDK1gweUJvSngKOXZhTWYvdm8yN3hxTHBlWG80eEwrU3Yyc2ZuT2hCMngrY1dYM3UrNThxUHB2QktKWHFlcVVxdjRJeWZMcExHY1k5dlhtWDd3Q2w3cgphS2IweGxwSERVMFFNK05Pc1JPanlCaHNTK3o4Q1pEZm5XUXBKU01Ib2JUU1BTNWc0TS9TQ1llN3pVandUY0xDZW9pS3U3clBXUm5XCnI0K3dCN0NlTWZHQ3djRGZMcVp0YkJrT3RkaCtKaHBGQXoyd2VhU1VLSzBQZnlibHFBaitsdWc4YUpSVDdvTTZpQ3NWbGdteTRIcU0KTG5YV25PdW5WbVNQbGs5b3JqMlh3b1NQd0x4QXdBdGN2ZmFIc3pWc3JCaFFmNFRnVE0yUzB5RHBNN3hTbWE4eXRTbXpKU3EwU1BseQo0Y3BrOSthQ0VJM29uY0tLaVBvNFpvcjhZL2tCK1hqOWUxeDMrbmFIK3V6ZnNRNTVsVmUwdlNidjFnSFI2eFlLdTQ0THRjWEZpbFdyCjA2enFrVXNwekJta01pVk9LdkZsUk5BQ3pxck9TYlRxbjN5RHNFQjc1ME9ycDJ5amozMkpnZnBNcGYvVmpzUE9TK0MxMkxPT1JjOTIKd08xQUsvMVREN0NuMVRzTnNZcWlBOTR4cmN4MzZtOTdQdGJma1NJUzVyNzYyREw4RUdNVVVYTGVYZFlXazcwcGFEUHZPbWJzQjRvbQozeFBYVjJWNEo5NWVTUlFBb2dCL21xZ2h0cW14bGJDbHVRMFdFZHJIYkVnOFFPQitEVnJOVmp6Umx3VzV5MHZ0T1V1Y3hEL1NWUk51CkpMRFdjZnIwd2JyTTdSdjEvb0ZCMkFDWVBUcklybnFZTnhnRmxRSURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WUQKVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVU1SzhySm5FYUswZ25oUzlTWml6djhJa1RjVDR3RFFZSktvWklodmNOQVFFTQpCUUFEZ2dJQkFEaVdDdTQ5dEpZZVgrK2RuQXN6bnl2Z3l2M1NqZ29mUVhTbGZLcUUxT1h5SHVZM1VqS2NDOUZoSGI4b3diWkVLVFYxCmQ1aXlmTm05ZEt5S2FPT3BNUWtwQVdCejQwZDhVNmlRU2lmdlM5ZWZrK2VDTnM2YWFBeUM1OC9VRUJadlh3NlpYUFlmY1gzdjczc3YKZnVvMjFwZHdDeFh1MTF4V2FqT2w0MGs0RExoOSs0MkZwTEZaWHZScTRkMmg5bVJFcnVaUmd5Rm14aEUrODg1SDdwd29IeVhhLzZ4bQpsZDAxRDF6dklDeGkvWkc2cWN6OFdweVRnWU1wbDBwOFduSzBPZEMzZDh0NS9XazZramZ0YmpobFJuN3BZTDE1aUpkZk9CTDA3cTliCmdzaUcxZUdaYll3RThuYTZTZlp1NlcwZVg2RHZKNEoyUVBpbTAxaGNEeXhDMmtMR2U0ZzB4OEhZUlp2QlBzVmhIZGxqVUVuMk5JVnEKNEJqRmJrZXJRVUlwbS9aZ0RkSXgwMk9ZSTVOYUFJRkl0Ty9OaXMzSno1bnUyWjZxTnVGb1MzRkpGRFlvT2owZHpwcVBKZWFBY1dFcgp0WHZNK1NVV2dlRXhYNkdqZmhha25CWnFseGk5ZG5LbEM1NGROdVl2b1MrK2NKRVBxT2JhK01TU1FHd2xmbnV6Q2R5eUY2MkFSUEJvCnBZK1VkZjkwV3Vpb0Fud01DZUtwU3d1Z2hRdGl1ZStoTVpMNzcvWlJCSWxzNktsMG9ic1hzN1g5U1E5OFBPeURHQ0JEVHRXVHVyUTAKc1I4V05oOE01bVE1Rmt6YzRQNGR5S2xpUFVEcXlzVTBBclN1aVlnek5kd3NFM1BZSi9IUWN1NTFPeUxlbUdobVcvSEdZMGRWSExxbApDRkYxcGtnbAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHVFMgUm9vdCBSMgo9PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRldqQ0NBMEtnQXdJQkFnSVFia2VweGxxejV5REZNSm8vYUZMeWJ6QU5CZ2txaGtpRzl3MEJBUXdGQURCSE1Rc3dDUVlEVlFRRwpFd0pWVXpFaU1DQUdBMVVFQ2hNWlIyOXZaMnhsSUZSeWRYTjBJRk5sY25acFkyVnpJRXhNUXpFVU1CSUdBMVVFQXhNTFIxUlRJRkp2CmIzUWdVakl3SGhjTk1UWXdOakl5TURBd01EQXdXaGNOTXpZd05qSXlNREF3TURBd1dqQkhNUXN3Q1FZRFZRUUdFd0pWVXpFaU1DQUcKQTFVRUNoTVpSMjl2WjJ4bElGUnlkWE4wSUZObGNuWnBZMlZ6SUV4TVF6RVVNQklHQTFVRUF4TUxSMVJUSUZKdmIzUWdVakl3Z2dJaQpNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUURPM3YybSsrenNGRFE4QndaYWJGbjNHVFhkOThHZFZhclR6VHVrCmszTHZDdnB0bmZid2hZQmJvVWhTbnpuRnQrNG9yTy9MZG1nVXVkK3RBV3laSDhRaUhaLytjbmZnTEZ1djVBUy9UM0tnR2pTWTZEbG8KN0pVbGUzYWg1bW01aFJtOWlZeityZTAyNm5POC80UGl5MzNCMHM1S3M0MEZub3RKazkvQlc5QnVYdkF1TUM2Qy9QcTh0QmNLU09XSQptOFdiYTk2d3lyUUQ4TnIwa0xobFpQZGNUSzNvZm1aZW1kZTR3ajdJMEJPZHJlN2tSWHVKVmZlS0gySlNoQkt6d2tDWDQ0b2ZSNUdtCmRGclMrTEZqS0JDNHN3bTRWbmRBb2lhWWVjYiszeVh1UHVXZ2Y5UmhEMUZMUEQrTTJ1RndkTmpDYUtINXdRenBvZUovdTFVOGRnYnUKYWs3TWtvZ3dUWnE5VHd0SW1vUzFtS1BWKzNQQlYySGRLRloxRTY2SGp1Y01VUWtRZFloTXZJMzVlenpVSWtnZkt0enJhN3RFc2NzegpjVEpHcjYxSzhZem9kRHFzNXhvaWM0RFNNUGNsUXNjaU96c1NyWll1eHNOMkI2b2d0elZKVittU1NlaDJGbkl4Wnl1V2ZvcWp4NVJXCklyOXFTMzRCSWJJak10L2tta1J0V1Z0ZDlRQ2dISnZHZUplTmtQK2J5S3EwcnhGUk9WN1orMmV0MVZzUm5US2FHNzNWdWx1bHljc2wKYVZOVkoxemd5amJMaUdIN0hyZlF5KzRXKzlPbVRONlNwZFRpMy9VR1ZONHVuVXUwa3pDcWdjN2RHdHhSY3cxUGNPbmx0aFloR1hteQo1b2tMZFdUSzFhdThDY0VZb2YvVVZLR0ZQUDBVSkFPeWg5T2t0d0lEQVFBQm8wSXdRREFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEClZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVdS8vS2ppT2ZUNW5LMitKb3BxVVZKeGNlMlE0d0RRWUpLb1pJaHZjTkFRRU0KQlFBRGdnSUJBTFpwOEtaMy9wN3VDNEd0NGNDcHgvazFIVUNDcStZRXROL0w5eDBQZy9CK0UwMk5qTzdqTXlMRE9meEEzMjVCUzBKVAp2aGFJOGRJNFhzUm9tUnlZVXBPTTUyanRHMnB6ZWdWQVRYOWxPOVpZOGM2RFIyRGovNWVwbkdCM0dGVzFmZ2lUejlEMlBHY0RGV0VKCitZRjU5ZXhUcEovSmp3R0xjOFIzZHR5RG92VU1TUnFvZHQ2U20yVDRzeXpGSjlNSHdBaUFwSmlTNHdHV0Fxb0M3bzg3eGRGdENqTXcKYzNpNVQxUVd2d3NIb2FSYzVzdkpYSVNQRCtBVmR5eCtKbjdheEV2YnB4WjNCN0ROZGVoeVF0YVZoSjJHZy9Ma2tNMEpSOVNMQTNEYQpXc1lEUXZUdE42THdHMUJVU3c3WWhONFpLSm1CUjY0Skd6OUkwY052NHJCZ0YvWHVJd0tsMmdCYmJaQ3I3cUxwR3p2cHgwUW5SWTVyCm4vV2toTHgzK1d1WHJENVJSYUlScHN5RjdncG84ajVRT0hva1loNFhJRGR0YWsyM0NadkovS1JZOWJiN25FNFl1NVVDNTZHdG13ZnUKTm1zazBqbUd3Wk9EVU5LQlJxaGZZbGNzdTJ4a2lBaHU3eE5VWDkwdHhHZGowOCtKTjcrZElQVDdlb09ib0I2QkFGREM1QXdpV1ZJUQo3VU5XaHdENEZGS25IWXVUaktKTlJuOG54bkdiSk43azJvYUxEWDVySU1IQW51RmwyR3FqcHVpRml6b0hDQnk2OVk5Vm1oaDFmdVhzCmdXYlJJWE9oTlVRTGdEMWJuRjV2S2hlVzBZTWppR1p0NW9iaWNESXZVaUxueU9kL3hDeGdYUy9EcjU1RkJjT0VBcmY5TEFoU1Q0TGQKby9EVWhna0MKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR1RTIFJvb3QgUjMKPT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNERENDQVpHZ0F3SUJBZ0lRYmtlcHgyeXBjeVJBaVE4RFZkMk5IVEFLQmdncWhrak9QUVFEQXpCSE1Rc3dDUVlEVlFRR0V3SlYKVXpFaU1DQUdBMVVFQ2hNWlIyOXZaMnhsSUZSeWRYTjBJRk5sY25acFkyVnpJRXhNUXpFVU1CSUdBMVVFQXhNTFIxUlRJRkp2YjNRZwpVak13SGhjTk1UWXdOakl5TURBd01EQXdXaGNOTXpZd05qSXlNREF3TURBd1dqQkhNUXN3Q1FZRFZRUUdFd0pWVXpFaU1DQUdBMVVFCkNoTVpSMjl2WjJ4bElGUnlkWE4wSUZObGNuWnBZMlZ6SUV4TVF6RVVNQklHQTFVRUF4TUxSMVJUSUZKdmIzUWdVak13ZGpBUUJnY3EKaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVFmVHpPSE15bUtvWVRleThjaFdFR0o2bGFkSzB1RnhoMU1KN3gvSmxGeWIrS2YxcVBLekVVVQpSb3V0NzM2R2pPeXhmaS8vcVhHZEdJUkZCRUZWYml2cUpuKzdrQUhqU3htNjVGU1dSUW14MVd5UlJLMkVFNDZhakEyQURETDI0Q2VqClFqQkFNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCVEI4U2E2b0MydWhZSFAKMC9FcUVyMjRDbWY5dkRBS0JnZ3Foa2pPUFFRREF3TnBBREJtQWpFQWdGdWtmQ1BBbGFVczNMNkpieU81bzkxbEFGSmVrYXpJblhKMApnbE1MZmFsQXZXaGd4ZUc0VkR2Qk5oY2wyTUc5QWpFQW5qV1NkSVVsVWZVazdHUlNKRkNsSDl2b3k4bDI3T3lDYnZXRkdGUG91T09hCkthcVcwNE1qeWFSN1liUE1BdWhkCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdUUyBSb290IFI0Cj09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDQ2pDQ0FaR2dBd0lCQWdJUWJrZXB5SXVVdHVpN095cllvckxCbVRBS0JnZ3Foa2pPUFFRREF6QkhNUXN3Q1FZRFZRUUdFd0pWClV6RWlNQ0FHQTFVRUNoTVpSMjl2WjJ4bElGUnlkWE4wSUZObGNuWnBZMlZ6SUV4TVF6RVVNQklHQTFVRUF4TUxSMVJUSUZKdmIzUWcKVWpRd0hoY05NVFl3TmpJeU1EQXdNREF3V2hjTk16WXdOakl5TURBd01EQXdXakJITVFzd0NRWURWUVFHRXdKVlV6RWlNQ0FHQTFVRQpDaE1aUjI5dloyeGxJRlJ5ZFhOMElGTmxjblpwWTJWeklFeE1RekVVTUJJR0ExVUVBeE1MUjFSVElGSnZiM1FnVWpRd2RqQVFCZ2NxCmhrak9QUUlCQmdVcmdRUUFJZ05pQUFUemRIT25hSXRncmtPNE5jV0JNSHRMU1ozN3dXSE81dDVHdld2VllSZzFya0RkYy9lSmtUQmEKNnp6dWhYeWlRSFk3cWNhNFI5Z3E1NUtSYW5QcHNYSTVueW1mb3BqVFgxNVlobVVQb1lSbEJ0SGNpOG5IYzhpTWFpL2x4S3ZSSFlxagpRakJBTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlNBVE5icmRQOUpOcVBWCjJQeTFQc1ZxOEpRZGpEQUtCZ2dxaGtqT1BRUURBd05uQURCa0FqQnFVRkowQ01SdzNKNVFkQ0hvalhvaHcwK1diaFhSSWpWaExmb0kKTis0WmJhM2Jzc3g5QnpUMVlCa3N0VFRaYnlBQ01BTnhzYnFqWUF1Rzdab0lhcFZvbitLejRaTmtmRjZUcHQ5NUxZMkY0NVRQSTExeAp6UEt3VGRiK21jaVVxWFdpNHc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpVQ0EgR2xvYmFsIEcyIFJvb3QKPT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGUmpDQ0F5NmdBd0lCQWdJUVhkK3gybHFqN1YyK1dtVWdaUU9RN3pBTkJna3Foa2lHOXcwQkFRc0ZBREE5TVFzd0NRWURWUVFHCkV3SkRUakVSTUE4R0ExVUVDZ3dJVlc1cFZISjFjM1F4R3pBWkJnTlZCQU1NRWxWRFFTQkhiRzlpWVd3Z1J6SWdVbTl2ZERBZUZ3MHgKTmpBek1URXdNREF3TURCYUZ3MDBNREV5TXpFd01EQXdNREJhTUQweEN6QUpCZ05WQkFZVEFrTk9NUkV3RHdZRFZRUUtEQWhWYm1sVQpjblZ6ZERFYk1Ca0dBMVVFQXd3U1ZVTkJJRWRzYjJKaGJDQkhNaUJTYjI5ME1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBCk1JSUNDZ0tDQWdFQXhlWXJiM3p2SmdVbm80RWsybS9MQWZtWm1xa3l3aUtIWVVHUk84dkRhQnNHeFV5cEs4Rm5GeUlkSyszNUtZbVQKb25pOWttdWdvdzJpZnNxVHM2YlJqRFhWZGZrWDlzOUZ4ZVY2N0hlVG9JOGpyZzRhQTMrKzFORHRMbnVyUmlOYi95em1WSHFVd0NvVgo4TW1Oc0hvN0pPSFhhT0l4UEFZelJyWlVFYWFsTHlKVUtsZ05BUUx4K2hWUloyekErdGUyRzMvUlZvZ3ZHanFOTzd1Q0VlQkhBTkJTCmg2djdobjRQSkd0QW5UUm52STNITFladmVUNk9xVHdYUzMrd21lT3djV0RjQy9Wa3c4NUR2RzF4dWRMZUoxdUs2TmpHcnVGWmZjOG8KTFRXNGxWWWE4YkpZUzdjU044aDhzKzFMZ09HTitqSWp0bSszU0pVSXNVUk9oWXc2QWxRZ0w5Ky9WMDg3T3BBaDE4RW1OVlFnN01jLwpSK3p2V3I5TGVzR3RPeGRRWEdMWUQwdEszQ3Y2YnJ4emtzM3N4MURvUVpiWHFYNXQyT2tkajRxMXVWaVN1a3FTS3d4Vy9ZRHJDUEJlCktXNGJIQXl2ajVPSnJkdTlvNTRoeW9rWjdOKzF3eHJyRnY1NE5reldidEErRnh5UUYyc211dnQ2TDc4UkhCZ09MWE1EajZEbE5hQmEKNGt4MUhYSGhPVGhUZUVETWc1UFhDcDZkVzQrSzVPWGdTT1JJc2tmTlRpcDFLbnZ5SXZiSnZnbVJsbGQ2aUlpczduQ3MrZHdwNHd3YwpPeEpPUk5hblRyQW15UFBaR3BlUmFPcnZqVVlHMGxaRldKbzhEQStEdUFVbHd6blBPNlEwaWJkNUVpOUh4ZWVwbDJuOHBuZG50ZDk3CjhYcGxGZVJoVm1VQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME8KQkJZRUZJSEVqTXoxNUREL3BRd0lYNHdWWnlGMEFkL2ZNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUFUWlNMMWppdXRST1RMLzdsbwo1c09BU0QwRWUvb2pMM3J0TnRxeXptMzI1cDdsWDFpUHl6Y3lvY2hsdHE0NFBUVWJQcnc3dGdUUXZQbEo5WnYzaGNVMnRzdTgrTWc1CjFlUmZCNzBWVkpkMHlzcnRUN3E2WkhhZmdiaUVSVWxNalcraTY3SE0wY09VMmtUQzV1THFHT2lpSHljRnV0ZmwxcW5OM2U5Mm1JMEEKRHMwYitnTzNqb0JZRGljL1V2dVVvc3BlWmNuV2hOcTVOWEh6SnNCUGQrYUJKOUozTzVvVWIzbjA5dERoMDVTNjBGZFJ2U2NGRGNIOQp5Qkl3N20rTkVTc0luZFRVdjRCRkZKcUlSTm93NnJTbjQrN3ZXNExWUHRhdGVKTGJYRHp6MkszNnVHdC94RFlvdGdJVmlsUXNuTEFYCmM0N1FONk1VUEppVkFBd3BCVnVlU1VteFg4Zmp5ODhuWlk0MUY3ZFh5RERaUVZ1NUZMYm93ZytVTWFlVW1NeHE2N1hoSi9VUXFBSG8KamhKaTZJak10WDlHbDhDYkVHWTRHalpHWHlKb1BkL0p4aE1ucTFNR3JLSThoZ1psYjdGK3NTbEVtcU82U1drb2FZL1g1Vit0QklaawpieHFnRE1VSVlzNkFvOUR6N0dqZXZqUEhGMXQvZ01STVRMR21oSXJETzdnSnpSU0J1aGpqVkZjMi90c3ZmRWVoT2pQSStWZzdSRSt4CnlnS0pCSllvYU1WTHVDYUp1OVl6TDFEVi9wcUp1aGd5a2xUR1crQ2QrVjdsRFNLYjl0cml5Q0d5WWlHcWhrQ3lMbVRUWDhqamZoRm4KUlI4Ri91T2k3N09vcy9OOWovZ01IeUlmTFhDMHVBRTBkakFBNVNONHAxYlhVQitLK3diMXdobncwQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QKPT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRldqQ0NBMEtnQXdJQkFnSVFUOUlyai9Wa3lET2VUelJZWmlOd1lEQU5CZ2txaGtpRzl3MEJBUXNGQURCSE1Rc3dDUVlEVlFRRwpFd0pEVGpFUk1BOEdBMVVFQ2d3SVZXNXBWSEoxYzNReEpUQWpCZ05WQkFNTUhGVkRRU0JGZUhSbGJtUmxaQ0JXWVd4cFpHRjBhVzl1CklGSnZiM1F3SGhjTk1UVXdNekV6TURBd01EQXdXaGNOTXpneE1qTXhNREF3TURBd1dqQkhNUXN3Q1FZRFZRUUdFd0pEVGpFUk1BOEcKQTFVRUNnd0lWVzVwVkhKMWMzUXhKVEFqQmdOVkJBTU1IRlZEUVNCRmVIUmxibVJsWkNCV1lXeHBaR0YwYVc5dUlGSnZiM1F3Z2dJaQpNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUNwQ1Fjb0V3S3dtZUJrcWg1REZucHpzWkdnZFQ2byt1TTRBSHJzCmlXb2dENHZGc0pzekExcUd4bGlHMWNHRnUwL0duRUJOeXI3dWFaYTRyWUV3bW55U0Jlc0ZLNXBJMExoMlBwYklJTHZTc1BHUDJLeEYKUnYrcVoyQzBkMzVxSHp3YVVub0VQUWM4aFEyRTBCOTJDdmRxRk45eTR6UjhWMDVXQVQ1NThhb3BPMno2K0k5dFRjZzEzNjdyM0NUdQplVVduaGJZRmlONklYU1Y4bDJSbkNkbS9XaFVGaHZNSkh1eFlNak1SODNka3NIWWY1QkExRnh2eURyRnNwQ3FqYy93Skh4NHlHVk1SCjU5bXpMQzUyTHFHajNuNXFpQW5vOGdlSytMTE5FT2ZpYzBDVHV3alJQK0g4QzVTekplOThwdGZScjUvL2xwcjFrWHVZQzNmVWZ1Z0gKMG1LMWxUbmo4L0Z0RHc1bGhJcGpWTVdBdHVDZVMzMUhKcWNCQ0YzUmlKN1h3ekpFK29KS0NtaFVmemhUQTh5a0FETmtVVmtMbzRLUgplbDdzRnNMekt1WmkyaXJiV1dJUUpVb3FnUXRIQjBNR2NJZlMrcE1SS1hwSVRldVV4M0JOcjJmVlViR0FJQUVCdEhvSXBwQi9UdUR2CkIwR0hyMnFsWG92N3oxQ3ltbFN2dzRtNldDMzFNSml4Tm5JNWZra0UvU21uVEhua0JWZmJsTGtXVTQxR3N4MlZZVmRXZjYvd0ZsdGgKV0c4MlVCRUwyS3dybFJZYURoOEl6VFkwWlJCaVp0V0FYeFFnWHkwTW9IZ0thTllzMStsdks5SktCWlA4bm05clovK0k4VTZsYVVwUwpOd1hxeGhhTjBzU1owWUlyTzdvMWRmZFJVVmp6eUFmZDVMUURmd0lEQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVMlhRNjVEQTlEZmNTCjNINWFCWjhlTkpyMzRSUXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVlZd0RRWUpLb1pJaHZjTkFRRUwKQlFBRGdnSUJBRGFObDh4Q0ZXUXBONXNtTE5iN3JoVnBMR3NhR3ZkZnR2a0hURm5xODhuSXVhN011aTU2M01EMXNDM0FPNitmY0FVUgphcDhsVHdFcGNPUGxET0hxV256Y1NidkJIaXFCOVJaTGNwSElvakc1cXRyOG5SL3pYVUFDRS94T0hBYktzeFNRVkJjWkVocnhIOWNNCmFWcjJjWGowbEgyUkM0N3NrRlNPdkcraFRLdjhkR1Q5Y1pyNFFRZWh6WkhrUEpyZ216STVjNnNxMVduSWVKRW1NWDNpeHpEeC9CUjQKZHhJT0UvVGRGcFMvUzJkN2NGT0Z5ckM3OHpoTkxKQTV3QTNDWFd2cDR1WFZpSTNXTEwrckc3NjFLSWNTRjNSdS9IMzhqOUNISnJBYgorN2xzcStLZVBSWEJPeTVuQWxpUm4rLzRRaDhzdDJqMWRhM1B0ZmIvRVgzQzhDU2xyZFA2b0R5cCtsM2NwYUR2UktTKzF1amw1Qk9XCkYzc0dQakx0eDdkQ3ZIYWoyR1U0S3pnMVVTRU9EbTh1TkJOQTRTdG5ERzFLUVRBWUkxb3lWWm5KRitBODN2YnNlYTByV0JtaXJTd2kKR3BXT3ZwYVFYVUpYeFBrVUF6VXJIQzFSVndpbk90NC81TWkwQTNQQ3dTYUF1d3RDSDYwTnJ5Wnkyc3krczZPRFdBMkN4UjlHVWVPYwpHTXlObTQzc1NldDFVTldNS0ZuS2REVGFqQXNocXg3cUcrWEgvUlUrd0JlcSt5TnVKa2JMK3ZteGNtdHB6eUtFQzJJUHJOa1pBSlNpCmRqelVMWnJ0Qko0dEJtSVFOMUljaFhJYkorWE14akhzTit4aldac0xIWGJNZmpLYWlKVUlObEs3M25aZmRrbEpyWCs5WlNDeXljRXIKZGhoMm4xYXgKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ2VydGlnbmEgUm9vdCBDQQo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlHV3pDQ0JFT2dBd0lCQWdJUkFNcnBHNG54VlFNTm8rWkJiY1RqcHVFd0RRWUpLb1pJaHZjTkFRRUxCUUF3V2pFTE1Ba0dBMVVFCkJoTUNSbEl4RWpBUUJnTlZCQW9NQ1VSb2FXMTViM1JwY3pFY01Cb0dBMVVFQ3d3VE1EQXdNaUEwT0RFME5qTXdPREV3TURBek5qRVoKTUJjR0ExVUVBd3dRUTJWeWRHbG5ibUVnVW05dmRDQkRRVEFlRncweE16RXdNREV3T0RNeU1qZGFGdzB6TXpFd01ERXdPRE15TWpkYQpNRm94Q3pBSkJnTlZCQVlUQWtaU01SSXdFQVlEVlFRS0RBbEVhR2x0ZVc5MGFYTXhIREFhQmdOVkJBc01FekF3TURJZ05EZ3hORFl6Ck1EZ3hNREF3TXpZeEdUQVhCZ05WQkFNTUVFTmxjblJwWjI1aElGSnZiM1FnUTBFd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUMKRHdBd2dnSUtBb0lDQVFETkdEbGxHbG14Nm1RV0RveVVKSlY4ZzlQRk9TYmNETzhXVjQzWDJLeWpRbitDeXUzTlc5c090eTN0UlFnWApzdG16eTlZWFVuSW8yNDVPbm9xMkMvbWVoSnBOZHQ0aUtWelNzOUlHUGpBNXFYU2prbFljb1c5TUNpQnRueU42dE1iYUxPUWRMTnl6CktOQVQ4a3hPQWttaFZFQ2U1dVVGb0MyRXlQK1liTkRyaWhxRUNCNjNhQ1B1STlWd3ptMVJhUkR1b1hyQzBTSXh3b0tGMHZKVmRsQjgKSlhySmhGd0xyTjFDVGl2bmdxSWtpY3VRc3REdUk3cG1UTHRpcFBsVFdtUjdmSmo2bzBpZUQ1V3VweGowYXV3dUEwV3Y4SFQ0S3MxNgpYZEcrUkNZeUtmSHg5V3pNZmdJaEM1OXZwRCsrblZQaXozMnBMSHhZR3BmaFBUYzNHR1lvMGtERlVZcU13eTNPVTRna1dHUXdGc1dxCjROWUtwa0RmZVBiMUJIeHBFNFM4MGRHbkJzOEI5MmpBcUZlN09tR3RCSXlUNDYzODhOdEViVm5jU1ZtdXJKcVpOakJCZTNZeklvZWoKd3BLR2J2bHc3cTZIaDVVYnhIcTlNZlBVMHVXWi83NUk3SFgxZUJZZHBuREJmendib1pMN3o4Zzgxc1dUQ28vMVZUcDJsYzVabUlvSgpsWGN5bW9PNkxBUTZsNzNVTDc3WGJKdWl5bjF0SnNsVjFjL0RlVklJQ1prSEpDMWtKV3VtSVdtYmF0MTBUV3VYZWtHOXF4ZjVrQmRJCmp6YjVMZFhGMis2cWhVVkIrczA2UmJGbzVqWk1tNUJYN0NPNWh3akN4QW54bDRZcUtFM2lkTURheEl6YjMrS2hGMW5PSkZsME1kcC8KL1RCdDJkemhhdUg4WHdJREFRQUJvNElCR2pDQ0FSWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZdwpIUVlEVlIwT0JCWUVGQmlIVnVCdWQrNGtOVHhPYzVvZjF1SGllWDRyTUI4R0ExVWRJd1FZTUJhQUZCaUhWdUJ1ZCs0a05UeE9jNW9mCjF1SGllWDRyTUVRR0ExVWRJQVE5TURzd09RWUVWUjBnQURBeE1DOEdDQ3NHQVFVRkJ3SUJGaU5vZEhSd2N6b3ZMM2QzZDNjdVkyVnkKZEdsbmJtRXVabkl2WVhWMGIzSnBkR1Z6THpCdEJnTlZIUjhFWmpCa01DK2dMYUFyaGlsb2RIUndPaTh2WTNKc0xtTmxjblJwWjI1aApMbVp5TDJObGNuUnBaMjVoY205dmRHTmhMbU55YkRBeG9DK2dMWVlyYUhSMGNEb3ZMMk55YkM1a2FHbHRlVzkwYVhNdVkyOXRMMk5sCmNuUnBaMjVoY205dmRHTmhMbU55YkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQWxMaWVUL0RqbFFnaTU4MW9RZmNjVmRWOEFPSXQKT29sZGFEZ3ZVU0lMU28zTDZidGRQcnRjUGJFby91UlRWUlBQb1pBYkFoMWZaa1lKTXlqaERTU1hjTk1RSCtwa1Y1YTdYZHJueEl4UApUR1JHSFZ5SDQxbmVRdEdicUg2bWlkMlBITWt3Z3UwN25NM0E2Um5nYXRnQ2RUZXI5elFvS0pIeUJBcFBOZU5nSmdINjBCR00rUkZxCjdxODl3MURUajE4emVUeUdxSE5Ga0l3Z3RuSnpGeU8rQjJYbGVKSU51Z0hBNjR3Y1pyK3NobmNCbEEyYzV1azVqUittVVl5WkREbDMKNGJTYitoeG5WMjlxYW82cEsweFhlWHBYSXMvTlgyTkdqVnhaT29iNE1rZGlvMmNOR0pIYys2WnI5VWhoY3lOWmpnS252RVRxOUVtZAo4VlJZK1dDdjJoaWtMeWhGM0hxZ2lJWmQ4enZuL3lrMWdQeGtRNVRtNHh4dnZxME9LbU9aSzhsK2hmWng2QVlEbGY3ZWowZ2NXdFNTCjZDdnU1ekhidWdScWg1am54Vi92ZmFjaTl3SFlUZm1KMEE2YUJWbWtucGpaYnl2S2NMNWt3bFdqOU9tdnc1SXAzSWdXSkprOGpTYVkKdGx1M3pNNjNOd2Y5SnRtWWhTVC9XU01EbXUyZG5hamtYampPMTFJTmI5SS9iYkVGYTBuT2lwRkdjL1QyTC9Db2MzY09aYXloaldaUwphWDVMYUF6SEhqY25nNldNeHdMa0ZNMUpBYkJ6cy8zR2tEcHYwbXp0Tys3c2tiNmlRMTJMQUVwbUpVUncza0FQK0h3Vjk2TE9QTmRlCkU0eUJGeGdYMGIzeGR4QTYxR1U1d1Nlc1Z5d2xWUCtpMmsrS1lUbGVyajFLakwwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgplbVNpZ24gUm9vdCBDQSAtIEcxCj09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURsRENDQW55Z0F3SUJBZ0lLTWZYa1lneHNXTzNXMkRBTkJna3Foa2lHOXcwQkFRc0ZBREJuTVFzd0NRWURWUVFHRXdKSlRqRVQKTUJFR0ExVUVDeE1LWlcxVGFXZHVJRkJMU1RFbE1DTUdBMVVFQ2hNY1pVMTFaR2h5WVNCVVpXTm9ibTlzYjJkcFpYTWdUR2x0YVhSbApaREVjTUJvR0ExVUVBeE1UWlcxVGFXZHVJRkp2YjNRZ1EwRWdMU0JITVRBZUZ3MHhPREF5TVRneE9ETXdNREJhRncwME16QXlNVGd4Ck9ETXdNREJhTUdjeEN6QUpCZ05WQkFZVEFrbE9NUk13RVFZRFZRUUxFd3BsYlZOcFoyNGdVRXRKTVNVd0l3WURWUVFLRXh4bFRYVmsKYUhKaElGUmxZMmh1YjJ4dloybGxjeUJNYVcxcGRHVmtNUnd3R2dZRFZRUURFeE5sYlZOcFoyNGdVbTl2ZENCRFFTQXRJRWN4TUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBazB1NzZXYUs3cDFiMVRTVDBCc2V3K2VldUdRemYyTjRhTFROCkxuRjExNXNneGswcHZMWm9ZSXIzSVpwV05WcnpkcjNZelpyL2sxWkxwVmtHb1pNMEtkMFdOSFZPOG9HMHg1Wk9yUmtWVWtyK1BIQjEKY00ydks2c1Ztak04cXJPTHFzMUQvZlhxY1AvdHp4RTdsTTVPTWhiVEkwQXFkN092UEFFc2JPMlpMSXZaVG1tWXN2ZVBRYkF5ZUdIVwpEVi9EK3FKQWtoMWNGK1p3UGpYbm9yZkNZdUtycERoTXRUazFiK29EYWZvNlZHaUZiZGJ5TDBOVkhwRU5EdGpWYXFTVzBSTThMSGhRCjZEcVMwaGRXNVRVYVFCdytqU3p0T2Q5QzRJTkJkTitqemNLR1lFaG80MmtMVkFDTDVIWnBJUTE1VGpRSVhoVEN6TEczcmRkOGNJckgKaFFJREFRQUJvMEl3UURBZEJnTlZIUTRFRmdRVSsrOE5ocDZ3NDkycHVmRWhGMzgrL1BCM0t4b3dEZ1lEVlIwUEFRSC9CQVFEQWdFRwpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRm4vOG96MWgzMXhQYU9mRzF2UjJ2alRuR3MyCnZadXBZZXZlRml4MFBaN21kZHJYdXFlOFFoZm5QWkhyNVgzZFBwenh6NUtzYkVqTXdpSS9hVHZGdGhVdm96WEdhQ29jVjY4NTc0M1EKTmNNWURIc0FWaHpOaXhsMDNyNFBFdURRcXFFL0FqU3hjTTZkR05ZSUF3bEc3bURnZnJiRVNRUlJmWEJndktxeS8zbHllcVlkUFY4cQorTXJpL1RtM1I3bnJmdDhFSTYvNm5BWUg2ZnRqazRCQXRjWnNDakVvemd5Zno3TWpOWUJCald6RU4zdUJMNENoUUVLRjZkazRqZWloClU4MEJ2Mm5vV2dieVJRdVErcTdodjUzeXJsYzhwYTZ5VnZTTFpVRHAvVEdCTFBRNUNkanVhNmUwcGgwVnBaajNBWUhZaFgzelVWeHgKaU42NnpCK0Fma289Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCmVtU2lnbiBFQ0MgUm9vdCBDQSAtIEczCj09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDVGpDQ0FkT2dBd0lCQWdJS1BQWUhxV2h3RHRxTGhEQUtCZ2dxaGtqT1BRUURBekJyTVFzd0NRWURWUVFHRXdKSlRqRVRNQkVHCkExVUVDeE1LWlcxVGFXZHVJRkJMU1RFbE1DTUdBMVVFQ2hNY1pVMTFaR2h5WVNCVVpXTm9ibTlzYjJkcFpYTWdUR2x0YVhSbFpERWcKTUI0R0ExVUVBeE1YWlcxVGFXZHVJRVZEUXlCU2IyOTBJRU5CSUMwZ1J6TXdIaGNOTVRnd01qRTRNVGd6TURBd1doY05ORE13TWpFNApNVGd6TURBd1dqQnJNUXN3Q1FZRFZRUUdFd0pKVGpFVE1CRUdBMVVFQ3hNS1pXMVRhV2R1SUZCTFNURWxNQ01HQTFVRUNoTWNaVTExClpHaHlZU0JVWldOb2JtOXNiMmRwWlhNZ1RHbHRhWFJsWkRFZ01CNEdBMVVFQXhNWFpXMVRhV2R1SUVWRFF5QlNiMjkwSUVOQklDMGcKUnpNd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVFqcFF5NExSTDFLUE94c3QzaUFoS0FuamxmU1UyZnlTVTBXWFRzdXdZYwo1OEJ5citpdUwrRkJWSWNVcUVxeTZIeUM1bHRxdGR5emRjNkxCdENHSTc5RzFZNFBQd1QwMXh5U2Z2YWxZOEwxWDQ0dVQ2RVlHUUlyCk1ncUNaSDBXazlHalFqQkFNQjBHQTFVZERnUVdCQlI4WFFLRUU5VE1pcHVCemhjY0xpa2VuRWhqUWpBT0JnTlZIUThCQWY4RUJBTUMKQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBS0JnZ3Foa2pPUFFRREF3TnBBREJtQWpFQXZ2Tmh6d0lRSFdTVkI3Z1lib2lGQlMrRApDQmVReWgrS1RPZ05HM3F4cmRXQkNVZnZPNndJQkh4Y21iSHRSd2ZTQWpFQW5icFYvS2xLNk8zdDVuWUJRbnZJK0dEWmpWR0xWVHY3CmpIdnJaUW5EK0piTlI2aUM4aFpWZHlSK0VoQ1ZCQ3lqCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCmVtU2lnbiBSb290IENBIC0gQzEKPT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGN6Q0NBbHVnQXdJQkFnSUxBSzdQQUxyRXp6TDRRN0l3RFFZSktvWklodmNOQVFFTEJRQXdWakVMTUFrR0ExVUVCaE1DVlZNeApFekFSQmdOVkJBc1RDbVZ0VTJsbmJpQlFTMGt4RkRBU0JnTlZCQW9UQzJWTmRXUm9jbUVnU1c1ak1Sd3dHZ1lEVlFRREV4TmxiVk5wCloyNGdVbTl2ZENCRFFTQXRJRU14TUI0WERURTRNREl4T0RFNE16QXdNRm9YRFRRek1ESXhPREU0TXpBd01Gb3dWakVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBc1RDbVZ0VTJsbmJpQlFTMGt4RkRBU0JnTlZCQW9UQzJWTmRXUm9jbUVnU1c1ak1Sd3dHZ1lEVlFRRApFeE5sYlZOcFoyNGdVbTl2ZENCRFFTQXRJRU14TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF6K3VwCnVmR1pCY3pZS0NGSzgzTTBVWVJXRVBXZ1R5d1M0L29UbWlmUXovbDVHblJmSFhrNS9GdjRjSTdna2xMMzVDWDVWSVBaSGRQSVdvVS8KWHNlMkIrNCt3TTZhcjZ4V1FpbzVKWERXdjdWN05xMnM5blBjemRjZGlvT2wreXVRRlRkckhDWkgzRHNwVnBOcXM4RnFPcDA5OWNHWApPRmdGaXh3UjQrUzB1RjJGSFlQK2VGOExSV2dZU0tWR2N6UTcvZy9JZHJ2SEdQTUYwWWJ6aGUzbnVka3lyVldJenFhMmtiQlBySDRWCkk1YjJQL0FnTkJiZUNzYkVCRVY1ZjZmOXZ0S3BwYStjeFNNcTl6d2hiTDJ2ajA3Rk9yTHpOQkw4MzRBYVNhVFVxWlgzbm9sZW9vbXMKbE11b2FKdXZpbVVuelludTNZeTFheWx3UTZCcEMrUzVEd0lEQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVL3FIZ2NCNHFBemxTV2tLKwpYSkdGZWhpcVRiVXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFECmdnRUJBTUpLVnZvVklYc29vdW5sSGZ2NExjUTVsa0ZNT3ljc3hHd1lGWURHcks5SFdTOG1DK00yc084Ny9rT1hTVEtaRWhWYjN4RXAKLzZ0VCtMdkJlQStzbkZPdlY3MW9qRDFwTS9Dam9DTmpPMlJuSWtTdDFYSExWaXA0a3FOUEVqRTJOdUxlL2dERW8yQVBKNjJnc0lxMQpObnBTb2IwbjlDQW5ZdWhObENRVDVBb0U2VHlyTHNoRENVckdZUVRsU1RSKzA4VEk5US9BcXVtNlZGN3pZeXRQVDFEVS9ybDdtWXc5CndDNjhBaXZUeEVEa2lnY3hIcHZPSnBrVCt4SHFtaUlNRVJuSFhodUJVRERJbGhKdTU4dEJmNUU3b2tlM1ZJQWIzQURNbXBEcXc4TlEKQm1JTU1NQVZTS2VvV1h6aHJpS2k0Z3A2RC9waXExSk00ZkhmeXI2RERVST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKZW1TaWduIEVDQyBSb290IENBIC0gQzMKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLekNDQWJHZ0F3SUJBZ0lLZTNHMmdsYTRFbnljcURBS0JnZ3Foa2pPUFFRREF6QmFNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUcKQTFVRUN4TUtaVzFUYVdkdUlGQkxTVEVVTUJJR0ExVUVDaE1MWlUxMVpHaHlZU0JKYm1NeElEQWVCZ05WQkFNVEYyVnRVMmxuYmlCRgpRME1nVW05dmRDQkRRU0F0SUVNek1CNFhEVEU0TURJeE9ERTRNekF3TUZvWERUUXpNREl4T0RFNE16QXdNRm93V2pFTE1Ba0dBMVVFCkJoTUNWVk14RXpBUkJnTlZCQXNUQ21WdFUybG5iaUJRUzBreEZEQVNCZ05WQkFvVEMyVk5kV1JvY21FZ1NXNWpNU0F3SGdZRFZRUUQKRXhkbGJWTnBaMjRnUlVORElGSnZiM1FnUTBFZ0xTQkRNekIyTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQTJJQUJQMmxZYTU3SmhBZAo2YmNpTUs0RzlJR3pzVUp4bFRtODAxTGpyNi81OHBjMWtqWkdEb2VWamJrNVd1bTczOUQreUFkQlBMdFZiNE9qYXZ0aXNJR0pBbkI5ClNNVks0K2tpVkNKTms3dENESzkzbkNPbWZkZGhFYzVseC9oLy92WHlxYU5DTUVBd0hRWURWUjBPQkJZRUZQdGFTTkNBSUVEeXFPa0EKQjJrWmQ2Zm13L1RQTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQW9HQ0NxR1NNNDlCQU1EQTJnQQpNR1VDTVFDMDJDOENpZjIyVEdLNlEwNFRoSEsxcnQwYzN0YTEzRmFQV0VCYUxkNGdUQ0tEeXBPb2Z1NFNRTWZXaDAvNDM0VUNNQndVClpPUjhsb01SbkxEUldtRkxwZzlKMHdEOG9memtwZjkvcmRjdzBNZDNmNzZCQjFVd1VDQVU5VmM0Q3FneFVRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKSG9uZ2tvbmcgUG9zdCBSb290IENBIDMKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ6ekNDQTdlZ0F3SUJBZ0lVQ0JaZmlreWw3QURKazBEZnhNYXVJN2djV3FRd0RRWUpLb1pJaHZjTkFRRUxCUUF3YnpFTE1Ba0cKQTFVRUJoTUNTRXN4RWpBUUJnTlZCQWdUQ1VodmJtY2dTMjl1WnpFU01CQUdBMVVFQnhNSlNHOXVaeUJMYjI1bk1SWXdGQVlEVlFRSwpFdzFJYjI1bmEyOXVaeUJRYjNOME1TQXdIZ1lEVlFRREV4ZEliMjVuYTI5dVp5QlFiM04wSUZKdmIzUWdRMEVnTXpBZUZ3MHhOekEyCk1ETXdNakk1TkRaYUZ3MDBNakEyTURNd01qSTVORFphTUc4eEN6QUpCZ05WQkFZVEFraExNUkl3RUFZRFZRUUlFd2xJYjI1bklFdHYKYm1jeEVqQVFCZ05WQkFjVENVaHZibWNnUzI5dVp6RVdNQlFHQTFVRUNoTU5TRzl1WjJ0dmJtY2dVRzl6ZERFZ01CNEdBMVVFQXhNWApTRzl1WjJ0dmJtY2dVRzl6ZENCU2IyOTBJRU5CSURNd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUN6CmlOZnF6ZzhnVHI3bTFnTnQ3bG44d2xmZktXaWhndzQrYU1kb1dKd2NZRXVKUXd5NTFCV3k3c0ZPZGVtMXArL2w2VFdaNU13YzUwdGYKalRNd0lETlQyYWE3MVQ0VGp1a2ZoMG10VUMxUXloaStBVmlpRTNDV3U0bUlWb0JjK0wwc1BPRk1WNGk3MDdtVjc4dkg5dG94ZENpbQo1bFNKOVVFeHl1VW1HczJDNEhEYU95bTcxUVAxbWJwVjlXVFJZQTZ6aVVtNGlpOEYwb1JGS0h5UGFGQVNlUHdMdFZQTHdwZ2NoS09lCnNMNGpwTnJjeUNzZTJtNUZIb21ZMnZrQUxnYnBERHR3MVZBbGlKbkx6WE5nOTlYL05XZkZvYnhlcTgxS3VFWHJ5R2dlRFEwVVJoTGoKMG1SaWlrS1l2TFRHQ0FqNC9haE1aSngyQWIwdnFXd3pEOWcvS0xnOGFRRkNobjVwd2NrR3l1VjZSbVhwd3RaUVFTNC90K1R0Yk5lLwpKZ0VSb2hZcFNtczBCcERzRTlLMisycDIwanp0OE5ZdDNlRVY3S09iTHl6SlBpdmthVHYvY2lXeE5vWmJ4MzlyaTFVYlNzVWdZVDJ1CnkxRGhDRHErc0k5alFWTXdDRms4bUIxM3VtT1Jlc29RVUdDLzhOZThsWWVQbDhYK2wyb0JsS044VzRVZEtqazYwRlNoMFRseG5mMGgKK2JWNzhPTGdBbzl1bGlRbExLQWVMS2pFaWFmdjdaa0dMN1lLVEUvYm9zdzNHcTlIaFMyS1g4UTBORXdBL1JpVFp4UFJOK1pJdElzRwp4VmQ3R1lZS2Vjc0F5Vkt2UXY4M2orR2pIbm85VUt0akJ1Y1Z0VCsyUlRlVU43Ris4a2pEZjhWMS9wZU5SWThhcHhweUtCcEFEd0lECkFRQUJvMk13WVRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJCakFmQmdOVkhTTUVHREFXZ0JRWG5jMGUKaTlZNUszRFRYTlNndUIrd0FQekZZVEFkQmdOVkhRNEVGZ1FVRjUzTkhvdldPU3R3MDF6VW9MZ2ZzQUQ4eFdFd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnSUJBRmJWZTI3bUlnSFNRcHNZMVE3WFppTmM0LzZneDVMUzZaU3RTNkxHN0JKOGROVkkwbGtVbWNEcnVkSHI5RWd3Clc2Mm5WM09acWRQbHQ5RXVXU1JZM0dndUxtTFlhdVJ3Q3kwZ1VDQ2tNcFhSQUppNzAvMzNNdkpKcnNaNjRFZSticzdMbzNJNkxXbGQKeThqb1JUblUra0xCRVV4M1haTDdhdjlZUk9YcmdaNnZvSm10dnFrQlpzczRIVHpmUXgvMFRXNjB1aGRHL0gzOWg0RjVhZzB6RC9vdgorQlM1Z0xOZFRhcVg0Zm5rR01YNDFUaU1Kano5OGlqaTdscEppQ3pmZVQyT25wQTh2VUZLT3QxYjlwcTB6ajhsTUg4eWZhSURsTkRjCmVxRlMzbTZUalJnbS9WV3N2WStiMHMrdjU0WXN5eDhKYjZOdnFZVFVjNzlOb1hRYlRpTmc4c3dPcW4ra25Fd2xxTEptT3pqLzJaUXcKOW5LRXZtaFZFQS9HY3l3V2FaTUgvckZGN2J1aVZXcXcyclZLQWlVbmhkZTN0NFpFRm9sc2dDcytsNm1jMVg1VlRNYmVSUkFjNnVrNwpud05UN3U1NkFRSVdlTlRvd3I1R2RvZ1RQeUs3U0JJZFVnQzBBbjRoR2g2Y0pmVHpQVjRlMGh6NXN5MjI5emRjeHNzaFRyRDNtVWNZCmhjRXJ1bFd1QnVyUUI3TGNxOUNDbG5YTzBsRCttZWZQTDUvbmR0RmhLdnNodXpIUXFwOUhwTElpeWhZNlVGZkVXME5ueFdWaUEwa0IKNjBQWjJQaWVyYyt4WXc1RjlLQmFMSnN0eGFiQXJhaEg5Q2RNT0EwdUcwazdVdlRvaUlNclZDalU4alZTdERLRFltbGtESkdjbjVmcQpkQmI5SHhFR21wdjAKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdTekNDQkRPZ0F3SUJBZ0lSQU5tMVEzK3ZxVGtQQUFBQUFGVmxyVmd3RFFZSktvWklodmNOQVFFTEJRQXdnYjR4Q3pBSkJnTlYKQkFZVEFsVlRNUll3RkFZRFZRUUtFdzFGYm5SeWRYTjBMQ0JKYm1NdU1TZ3dKZ1lEVlFRTEV4OVRaV1VnZDNkM0xtVnVkSEoxYzNRdQpibVYwTDJ4bFoyRnNMWFJsY20xek1Ua3dOd1lEVlFRTEV6QW9ZeWtnTWpBeE5TQkZiblJ5ZFhOMExDQkpibU11SUMwZ1ptOXlJR0YxCmRHaHZjbWw2WldRZ2RYTmxJRzl1YkhreE1qQXdCZ05WQkFNVEtVVnVkSEoxYzNRZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjEKZEdodmNtbDBlU0F0SUVjME1CNFhEVEUxTURVeU56RXhNVEV4TmxvWERUTTNNVEl5TnpFeE5ERXhObG93Z2I0eEN6QUpCZ05WQkFZVApBbFZUTVJZd0ZBWURWUVFLRXcxRmJuUnlkWE4wTENCSmJtTXVNU2d3SmdZRFZRUUxFeDlUWldVZ2QzZDNMbVZ1ZEhKMWMzUXVibVYwCkwyeGxaMkZzTFhSbGNtMXpNVGt3TndZRFZRUUxFekFvWXlrZ01qQXhOU0JGYm5SeWRYTjBMQ0JKYm1NdUlDMGdabTl5SUdGMWRHaHYKY21sNlpXUWdkWE5sSUc5dWJIa3hNakF3QmdOVkJBTVRLVVZ1ZEhKMWMzUWdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodgpjbWwwZVNBdElFYzBNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQXNld3NRdTdpMFREL3BaSkg0aTNECnVtU1hiY3IzRGJWWndiUExxR2daMksrRWJUQndYWDd6THRKVG1lSCtIMTdaU0s5ZEU0M2IvMk16VGRNQUFyekUrTkVHQ0pSNVdJb1YKM2ltei9mM0VUK2lxNHFBN2VjMi9hME15M2RsMEVMbjM5R2pVdTlDSDFhcExpaXB2S2dTMXNxYkhvSHJtU0t2UzBWbk0xbjRqNXBkcwo4RUxsM0ZGTEZVSHRTVXJKM2hDWDFuYkI3NlcxTmhTWE5kaDRJalZTNzBPOTJ5ZmJZVmFDTk56TGlHQU1DMXJsTEFIR1ZLL1hxc0VRCmU5SUZXcmhBbm9hbnc1Q0dBbFpTQ1hxYzBpZUNVMHBsVW1yMVBPZW84cHl2aTczVER0VFVYbTZIbm1vOVJSM1JYUnYwNlFxc1lKbjcKaWJUL21DelBmQjNwQXFvRW1oNjQzSWh1SmJOc1p2YzhrUE5Yd2JNdjlXM3krOHFoK0NtZFJvdXphdmJtWndlK0xHY0tLaDlhc2o1WAp4Tk1oSVdObFVwRWJzWm1PZVg3bTY0MEEyVnFxNm5Qb3BJSUNSNWIrVzQ1VVlhUHJMMHN3c0lzamRYSjhJVHpJOXZGMDFCeDdvd1ZWCjdydE5PeksrbW5kbW5xeHBrQ0lISDJFNmxyN2xtay9NQlR3b1dkUEJERlNvV1dHOXlISk02TnlmaDMrOW5FZzJYcFdqRHJrNEpGWDgKZFdickF1TUlOQ2xLeHVNckx6T2cycU9HcFJLWC9ZQXIyaFJDNDVLOVB2SmRYbWQwTGh5SVJ5azBYK0l5cUp3bE40eTZtQUNYaTBtVwpIdjBsaXF6YzJ0aGRkRzVtc1A5RTM2RVl4cjVJTHplVWVQaVZTajkvRTE1ZFdmMTBoa05qYzBrQ0F3RUFBYU5DTUVBd0R3WURWUjBUCkFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKODR4Rllqd3pub29IRnM2RlJNNU9nNnNiOW4KTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElDQVFBUzVVS21lNHNQRE9SR3BiWmdRSWVNSlg2dHVHZ3VXOFpBZGp3RCtNbFo5UE9yWXM0UQpqYlJhWkl4b3dMQnlRelRTR3d2MkxGUFN5cEJMaG1iOHFvTWk5SXNhYnlaSXJIWjNDTC9GbUZ6MEpvbWVlOE81WkRJQmY5UEQzVmh0CjdMR3JoRlYwZDRRRUoxSnJoa3pPM2JsbC85YkdYcCthRUpsTGRXcithdW1YSU9Ua2RuckcwQ1Nxa00wZ2tMcEhaUHQvQjdOVGVMVUsKWXZKelE4NUJLNEZxTG9VV2xGUFVhMTl5SXF0UkxVTFZBSnladjk2N2xEdFgvWnIxaHN0V08xdUlBZVY4S0VzRCtVbURmTEovZk9QdApqcUYvWUZPT1ZaMVFOQklQdDVkN2JJZEtST2YxYmV5QU4vQllHVzVLYUhid0g1TGs2cldTMDJGUkVBdXRwOWxmeDEvY0g2TmNqS0YrCm03ZWUwMVp2Wmw0SGxpRHRDM1Q3Wms2TEVSWHBnVWwrYjdEVVVIOGkxMTlsQWcybTlJVWUySzRHUzBxbjBqRm13dmpPNVFpbXBBS1cKUkdoWHhOVXp6eGt2Rk1TVUhIdWsyZkNmRHJHQTR0R2VFV1NwaUJFNmRvTGxZc0tBMktTRDdaUHZmQytRc0RKTWxoVm9TRkxVbVFqQQpKT2djNDdPbElRNlN3SkFmenlCZnlqczR4N2R0T3ZQbVJMZ09NV3VJam5Ecm5CZFNxRUdVTG9lMjU2WVN4WFhmVzhBS2JudWs1RjZHCitUYVUzM2ZENlEzQU9mRjV1MGFPcTBOWko3Y2d1eVBwVmtBaDdERTlaYXBEOGozZmNFVGh1azBtRUR1WW4vUElqaHM0VmlGcVVaUFQKa2NwRzJvbTNQVk9ETEFnZmk0OVQzZitzSHc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpNaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDV1RDQ0FkK2dBd0lCQWdJUVp2STlyNGZlaTdGSzZneFhNUUhDN0RBS0JnZ3Foa2pPUFFRREF6QmxNUXN3Q1FZRFZRUUdFd0pWClV6RWVNQndHQTFVRUNoTVZUV2xqY205emIyWjBJRU52Y25CdmNtRjBhVzl1TVRZd05BWURWUVFERXkxTmFXTnliM052Wm5RZ1JVTkQKSUZKdmIzUWdRMlZ5ZEdsbWFXTmhkR1VnUVhWMGFHOXlhWFI1SURJd01UY3dIaGNOTVRreE1qRTRNak13TmpRMVdoY05OREl3TnpFNApNak14TmpBMFdqQmxNUXN3Q1FZRFZRUUdFd0pWVXpFZU1Cd0dBMVVFQ2hNVlRXbGpjbTl6YjJaMElFTnZjbkJ2Y21GMGFXOXVNVFl3Ck5BWURWUVFERXkxTmFXTnliM052Wm5RZ1JVTkRJRkp2YjNRZ1EyVnlkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVJREl3TVRjd2RqQVEKQmdjcWhrak9QUUlCQmdVcmdRUUFJZ05pQUFUVXZEMENRblZCRXlQTmdBU0dBbEV2YXFpQllndGx6UGJLblI1dlNtWlJvZ1BablpINgp0aGF4akc3ZWZNM2JlYVl2enJ2T2NTL2xwYXNvN0dNRVpwbjQrdktURUFYaGdTaEM0OFpvOU9ZYmhHQktpYS90ZVE4N3p2SDJSUFVCCmVNQ2pWREJTTUE0R0ExVWREd0VCL3dRRUF3SUJoakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlRJeTVseWNGSU0KK09hK3NnUlhLU3JQUWhEdE5UQVFCZ2tyQmdFRUFZSTNGUUVFQXdJQkFEQUtCZ2dxaGtqT1BRUURBd05vQURCbEFqQlk4azNxRFBsZgpYdTVnS2NzNjh0dldNb1FaUDN6Vkw4S3h6Sk91VUxzSk1zYkc3WDdKTnBRUzVHaUZCcUliMEM4Q01RQ1o2UmEwRHZwV1NOU2tNQmFSCmVOdFVqR1VCaXVkUVpzSXh0em02dUJvaUIwNzhhMVFXSVA4cnRlZE1ERTJtVDNNPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpNaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGcURDQ0E1Q2dBd0lCQWdJUUh0T1hDVi9ZdExOSGNCNnF2bjlGc3pBTkJna3Foa2lHOXcwQkFRd0ZBREJsTVFzd0NRWURWUVFHCkV3SlZVekVlTUJ3R0ExVUVDaE1WVFdsamNtOXpiMlowSUVOdmNuQnZjbUYwYVc5dU1UWXdOQVlEVlFRREV5MU5hV055YjNOdlpuUWcKVWxOQklGSnZiM1FnUTJWeWRHbG1hV05oZEdVZ1FYVjBhRzl5YVhSNUlESXdNVGN3SGhjTk1Ua3hNakU0TWpJMU1USXlXaGNOTkRJdwpOekU0TWpNd01ESXpXakJsTVFzd0NRWURWUVFHRXdKVlV6RWVNQndHQTFVRUNoTVZUV2xqY205emIyWjBJRU52Y25CdmNtRjBhVzl1Ck1UWXdOQVlEVlFRREV5MU5hV055YjNOdlpuUWdVbE5CSUZKdmIzUWdRMlZ5ZEdsbWFXTmhkR1VnUVhWMGFHOXlhWFI1SURJd01UY3cKZ2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRREtXNzZVTTR3cGxaRVdDcFc5UjJMQmlmT1pOdDlHa01tbAo3WGhxYjBlUmFQZ25aMUF6SGFHbSsrRGxRNk9FQWxjQlhaeElRSUpURUx5L3h6dG9rTGFDTGVYMFpkRE1iUm5NbGZsN3JFcVVyUTdlClMwTWRod2VTRTVDQWcyUTFPUVQ4NWVsc3M3WWZVSlE0WlZCY0YwYTV0b1cxSExVWDZOWkZuZGl5SnJES3hIQktybUNrM2JQWjdQdzcKMVZkeXZEL0l5YkxlUzJ2NEkyd0R3QVc5bGNmTmN6dG1nR1RqR3F3dStVY0Y4Z2EybTNQMWVETmJ4Nkg3SnlxaHRKcVJqSkhUT29JKwpka0MwelZKaFVYQW9QOFhGV3ZMSmpFbTdGRnROeVA5blRVd1NscTMxL25pb2w0ZlgvVjRnZ055aFN5TDcxSW10dXM1SGwwZFZlNDlGCnlHY29oSlVjYUREdjcwbmdOWHRrNTVpd2xOcE5oVHMrVmNRb3IxZnpuaFBiUmllZkhxSmVSSU9rcGNyVkU3TkxQOFRqd3VhR1lhUlMKTUxsNklFOXZEemhUeXpNTUV5dVAxcHE5S3NndHNSeDlTMUhLUjlGSUozSmRoK3ZWUmVaSVpaMnZVcEM2VzZJWVpWY1NuMmk1MUJWcgpsTVJwSXBqME0rRHQrVkdPUVZESk5FOTJrS3o4T01IWTRYdTU0K09VNFVacHl3NEtVR3NUdXF3UE4xcTNFcldRZ1I1V3JsY2lodG5KCjB0SFhVZU9yTzhaVi9SNE8wM1FLMGRxcTZtbTRseWlQU01RSCtGSkRPdlRLVlRVc3NLWnF3Sno1OG9IaEVtckFSZGxuczg3L0k2S0oKQ2xUVUZMa3FxTmZzK2F2TkpWZ3llWStRVzVnNXhBZ0d3YXgvRGowQXBRSURBUUFCbzFRd1VqQU9CZ05WSFE4QkFmOEVCQU1DQVlZdwpEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVDY3RaZjRheWNJOGF3em5qd05ucHY3dE5zaU13RUFZSkt3WUJCQUdDCk54VUJCQU1DQVFBd0RRWUpLb1pJaHZjTkFRRU1CUUFEZ2dJQkFLeXZQbDNDRVphSmpxUG5rdGFYRmJnVG9xWkNMZ0xORmdWWko4b2cKNkxxNDZCcnNUYWlYVnE1bFE3R1BBSnRTelZYTlV6bHRZa3lMRFZ0OExrUy9neENQODFPQ2dNTlBPc2R1RVQvbTR4YVJoUHR0aEg4MApkSzJKcDg2NTE5ZWZoR1NTdnBXaHJRbFRNOTN1Q3VwS1VZNXZWYXU2dFpSR3JveC8yS0pRSldWZ2dFYmJNd1N1YkxXWWRGUWwzSlBrCitPTlZGVDI0YmNNS3BCTEJhWVZ1MzJUeFU1bmhTblVnblpVUDVOYmNBL0ZaR09oSGliSlhXcFMycWRnWEt4ZEo1WGJMd1ZhWk9qZXgKLzJrc2taR1Q0ZDlNb3pkMlRhR2YrRzBlSGRQNjdQdjBSUjBUYmMvM1dlVWlKM0lyaHZOWHV6RHRKRTNjZlZhN283UDROSG1Kd2VEeQpBbUgzcHZ3UHV4d1hDNjVCMlh5OUo2UDlManJSazVTeGN4MGtpNjliSUltdHQyZG1lZlU2eHFhV00vNVRrc2hHc1JHUnhwbC9qOG5XClpqRWdRUkNITFF6V3dhODBtTXBrZy9zVFY5SEI4RHg2aktYQi9aVWhvSEhCazJkeEV1cVBpQXBwR1dTWkkxYjdyQ291Y0w1bXhBeUUKNytXTDg1TUIrR3FRazJkTHNtaWp0V0tQNlQrTWVqdGVEK2VNdU1aODd6ZjlkT0xJVHpOeTRaUTViYjBTcjc0TVRuQjhHMitOc3pLVApjMFFXYmVqMDkrQ1ZnSStXWFRpazlLdmVDakNIazloTkFIRmlSU2RMT2tLRVczOWx0MmMwVWkyY0ZtdXFxTmg3bzBKTWNjY015ajZECjVLYnZ0d0V3WGxHamVmVndhYVpCUkErR3NDeVJ4ajNxcmcrRQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgplLVN6aWdubyBSb290IENBIDIwMTcKPT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDUURDQ0FlV2dBd0lCQWdJTUFWUkk3eUg5bDFrTjlRUUtNQW9HQ0NxR1NNNDlCQU1DTUhFeEN6QUpCZ05WQkFZVEFraFZNUkV3CkR3WURWUVFIREFoQ2RXUmhjR1Z6ZERFV01CUUdBMVVFQ2d3TlRXbGpjbTl6WldNZ1RIUmtMakVYTUJVR0ExVUVZUXdPVmtGVVNGVXQKTWpNMU9EUTBPVGN4SGpBY0JnTlZCQU1NRldVdFUzcHBaMjV2SUZKdmIzUWdRMEVnTWpBeE56QWVGdzB4TnpBNE1qSXhNakEzTURaYQpGdzAwTWpBNE1qSXhNakEzTURaYU1IRXhDekFKQmdOVkJBWVRBa2hWTVJFd0R3WURWUVFIREFoQ2RXUmhjR1Z6ZERFV01CUUdBMVVFCkNnd05UV2xqY205elpXTWdUSFJrTGpFWE1CVUdBMVVFWVF3T1ZrRlVTRlV0TWpNMU9EUTBPVGN4SGpBY0JnTlZCQU1NRldVdFUzcHAKWjI1dklGSnZiM1FnUTBFZ01qQXhOekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCSmJjUFlyWXNIdHZ4aWUrUkpDeApzMVlWZTQ1REpIMGFoRm51WTJpeXhsNkgwQlZJSHFpUXJiMVRvdHJlT3BDbVlGOW9NcldHUWQrSFd5eDd4ZjU4ZXRxall6QmhNQThHCkExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlNIRVJVSTBhckJlQXl4cjg3R3laRHYKdnpBRXdEQWZCZ05WSFNNRUdEQVdnQlNIRVJVSTBhckJlQXl4cjg3R3laRHZ2ekFFd0RBS0JnZ3Foa2pPUFFRREFnTkpBREJHQWlFQQp0VmZkMTRwVkN6Ymhoa1Q2MU5sb2piamNJNHFLRGRRdmZlcHo3TDlOYktnQ0lRRExwYlFTK3VlMTZNOStrL3p6Tlk5dlRscDh0THhPCnN2eHlxbHRaK2VmY01RPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKY2VydFNJR04gUm9vdCBDQSBHMgo9PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGUnpDQ0F5K2dBd0lCQWdJSkVRQTB0azdHTmkwMk1BMEdDU3FHU0liM0RRRUJDd1VBTUVFeEN6QUpCZ05WQkFZVEFsSlBNUlF3CkVnWURWUVFLRXd0RFJWSlVVMGxIVGlCVFFURWNNQm9HQTFVRUN4TVRZMlZ5ZEZOSlIwNGdVazlQVkNCRFFTQkhNakFlRncweE56QXkKTURZd09USTNNelZhRncwME1qQXlNRFl3T1RJM016VmFNRUV4Q3pBSkJnTlZCQVlUQWxKUE1SUXdFZ1lEVlFRS0V3dERSVkpVVTBsSApUaUJUUVRFY01Cb0dBMVVFQ3hNVFkyVnlkRk5KUjA0Z1VrOVBWQ0JEUVNCSE1qQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQCkFEQ0NBZ29DZ2dJQkFNREZkUm1SZlVSMGRJZitEanVXM05nQkZzenVZNUhuQzIvT093cHBHbnpDNDYrQ2pvYlhYbzlYNjlNaFdmMDUKTjBJd3ZsRHF0ZytwaU5ndUxXa2g1OUUzR0U1OWtkVVdYMnRiQU1JNVF3MDJoVks1VTJVUEhVTGxqODhGMCs3Y0RCclp1SXQ0SW1mawphYkJveFR6a2JGcEc1ODNIK3UvRTdFdTlhcVNzL2N3b1VlK1N0Q21ycXpXYVRPVEVDTVltelBocG4rU2M4Q25UWFBuR0ZpV2VJOE1nCndUMFBQemhBc1A2Q1JEaXFXaHFLYTJOWU9MUVYwN1lSYVhzZVZPNk1HaUtzY3BjL0kxbWJ5U0tFd1FkUHpIL2lWOG9TY0x1bVpmTnAKZFdPOWxmc2JsODNrcUsvMjBVNm8yWXB4Sk0wMlBieVd4UEZzcWE3bHp3MXVLQTJ3RHJYS1VYdDRGTU1nTDMvN0ZGWGhFWm45MVFxaApuZ0xqWWwvck5Vc3N1SExvUGoxUHJDeTdMb2JpbzNhUDVaTXF6NldyeUZ5TlN3Yi9Fa2FzZU1zVUJ6WGdxZCtMNmE4VlR4YUpXNzMyCmpjWlpyb2lGRHNHSjZ4OW54VVdPLzIwM05pdDRab09SVVNzOS8xRjNkbUtoN0djK1BvR0Q0RmFwVUI4ZmVwbXJZNytFRjNmeERUdmYKOTV4aHN6V1lpanF5N0R3YU56OStqNUxQMlJJVVpOb1FBaFZCLzAvRTZ4eWp5ZnFaOTBicDRSalpzYmd5TGNzVURGRFlnMldEN3JsYwp6OHNGV2t6NkdaZHIxbDBUMDhKY1ZMd3ljNkI0OWZGdEhzdWZwYWFmSXR6UlVaNkNlV1JnS1JNK28vMVBjbXFyNHRUbHVDUlZMRVJMCmlvaEVuTXFFMHlvN0FnTUJBQUdqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR0ExVWQKRGdRV0JCU0NJUzFteHRlZzRCWHJ6a3dKZDhSZ25sUnVBekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBWU40YXVPZnlZSUxWQXpPQgp5d2FLOFNKSjZlanFrWC9HTTE1b0dRT0dPME1CendkdzVBZ2VaWVdSNWhFaXQvVUNJNDZ1dVI1OUgzNXM1cjBsMVpVYThnV21yNFVDCmI2NzQxakgvSmNsS3lNZUtxZG1mUzBtYkVWZVpra01SM3JZenBNelhqV1I5MU0wOEtDeTBtcGJxVGZYRVJNUWxxaUNBMkNsVjkrQkIKL0FZbS83azI5VU1VQTJaNDRSR3gyaUJmUmdCNEFDR2xIZ0FvWVhodnFBRUJqNTAwbXYvME9KRDd1Tkd6Y2diSmNlYUJ4WG50QzZaNQo4aE1MblBkZERuc2trN1JJMjRaZjNsQ0dlT2RBNWpHb2tIWndZYStjTnl3UnRZSzNxcTRrTkZ0eURHa056Vm1mOW5Hdm5BdlJDamo1CkJpS0RVeVVNL0ZIRTVyN2lPWlVMSksydjBaWGtsdGQwWkd0eFRnSThxb1h6SUtORE9YWmJiRkQrbXB3VUhtVVVpaFc5bzRKRldrbFcKYXRLY3NXTXk1V0hnVXlJT3B3cEo2c3QrSDZqaVlvRDJFRVZTbUFZWTNxWE5MMytxMU9rK0NITHNJd01DUEthcTJMeG5kRDBVRi90VQpTeGZqMDNrOWJXdEp5U2dPTG5SUXZ3elpSam9RaHNtblArbWc3SC9ycFhkWWFYSG1nd28zOG9aSmFyNTVDSkQyQWhaa1B1WGFUSDRNCk5NbjVYN2F6S0ZHbnB5dXFTZnFOWlNsTzQyc1RwNVNqTFZGdGVBeEV5OS9lQ0cvT28yU3IwNVdFMUxsU1ZISjdsaVhNdkdualNHNE4KME1lZEo1cXErQk9TM1I3Zlk1ODFxUlkyN0l5NGcvUTlpWS9OdEJkZTE3TVhRUkJkSjNOZ2hWZEpJZ2M9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRydXN0d2F2ZSBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjJqQ0NBOEtnQXdJQkFnSU1CZmNPaHRwSjgwWTFMcnF5TUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdJTVFzd0NRWURWUVFHRXdKVgpVekVSTUE4R0ExVUVDQXdJU1d4c2FXNXZhWE14RURBT0JnTlZCQWNNQjBOb2FXTmhaMjh4SVRBZkJnTlZCQW9NR0ZSeWRYTjBkMkYyClpTQkliMnhrYVc1bmN5d2dTVzVqTGpFeE1DOEdBMVVFQXd3b1ZISjFjM1IzWVhabElFZHNiMkpoYkNCRFpYSjBhV1pwWTJGMGFXOXUKSUVGMWRHaHZjbWwwZVRBZUZ3MHhOekE0TWpNeE9UTTBNVEphRncwME1qQTRNak14T1RNME1USmFNSUdJTVFzd0NRWURWUVFHRXdKVgpVekVSTUE4R0ExVUVDQXdJU1d4c2FXNXZhWE14RURBT0JnTlZCQWNNQjBOb2FXTmhaMjh4SVRBZkJnTlZCQW9NR0ZSeWRYTjBkMkYyClpTQkliMnhrYVc1bmN5d2dTVzVqTGpFeE1DOEdBMVVFQXd3b1ZISjFjM1IzWVhabElFZHNiMkpoYkNCRFpYSjBhV1pwWTJGMGFXOXUKSUVGMWRHaHZjbWwwZVRDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBTGxkVVNoTFBEZVMwWUxPdlIyOQp6ZDI0cTg4S1B1RmQ1ZHlxQ2JsWEFqN21ZMkhmOGcrQ1k2Nmo5Nnh6MFh6bnN3dXZDQUFKV1gvTktTcUlrNGNYR0lEdGlMSzB0aEFmCkxkWmZWYUlUWGRIRzZ3WldpWWorckRLZC9WekRCY2R1N29hSnVvZ0RuWEloaHBDdWp3T2wzSitJS011amtra1A3TkFQNG0xRVQ0QnEKc3RUbm9BcFRBYnFPbDVGMmJyejgxV3MyNWtDSTFuc3ZYd1hvTEcwUjgrZXl2cEpFVE5LWHBQN1Njb0ZEQjV6cEVUNzFpeHBaZlI5bwpXTjBFQUN5VzgwT3pmcGdaZE5tY2M5a1l2a0hITkhuWjlHTENRN216SjdBaXkvazlVc2N3UjdQSlByaHE0dWZvZ1hCZVFvdFBKcVgrCk9zSWdicnY0Rm83TkRLbTBHMngyRU9GWWVVWStWTTZBcUZjSk55a2JtUk9QRE1qV0xCejdCZWdJbFQxbFJ0enV6V25pVFkrSEtFNDAKQ3o3UEZObTczYlpRbXExMzFCblcyaHFJeUU0YkozWFlzZ2p4cm9Nd3VSRU96WWZ3aEkwVmNueWg3OHp5aUdHNjlHbTdESXdMZFZjRQp1RTRxRkM0OUR4d2VNcVppTnU1bTRpSzRCVUJqRUNMek14MTBjb29zOVRrcG9OUG5HNENFTGNVOTQwMngvUnB2dW1VSE8xanNRa1VtCis5amFKWExFOWdDeElubTk0M3haWWtxY0JXODl6dWJXUjJPWnhpUnZjaExJckgrUXRBdVJjT2kzNWhZUWNSZk8zZ1pQU0VGOU5VcWoKaWZMSlMzdEJFVzFudHdpWVRPVVJHYTVDZ056N2tBWFUrRkRLdnVTdHg4S1UxeGFkNWhlUHJ6YjdBZ01CQUFHalFqQkFNQThHQTFVZApFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkpuZ0dXY05ZdHQyczlvOXVGdm8vVUxTTVE2SE1BNEdBMVVkRHdFQi93UUVBd0lCCkJqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFtSE53NHJEVDdUbnNUR0RacVJLR0Z4NlcwT2hVS0R0a0xTR20rSjFXRTJwSVBVL0gKUGluYmJWaURWRDJIZlNNRjFPUWMzT2c0WlliRmRhZGEyelVGdlhmZXV5azNRQVVIdzVSU244cGszZkViSzl4R0NoQUNNZjFLYUEwSApaSkRtSHZVcW9haTdQRjM1b3dnTEVRenhQeTBRbEcvKzRqU0hnOWJQNVJzMWJkSUQ0YkFOcUtDcVJpZUNOcWNWdGdpbVFsUlh0cGxhCjRndDVrTmRYRWxFMUdZaEJhQ1hVTnhlRUZmc0JjdHlWM2xJbUlKZ200bmIxSjIvNkFEdEtZZGtOeTFHVEt2MFdCcGFuSTVvalNQNVIKdmJiRXNMRlV6dDVzUWEwV1ozN2IvVGpOdVRoT3NzRmd5NTBYMzFpZWVtS3lKbzkwbFp2a1d4M1NEOTJZSEp0WnVTUFRNYUNtL3pqZAp6eUJQNlZoV09tZkQwZmFabVoyNk5yYUFMNGhIVDRhL1JEcUE1RGNjcHJycWw1Z1IwSVJpUjJRZXF1NUF2elN4bkk5TzRmS1NUeCtPCjg1Nlgzdk9tZVdxSmNVOUxKeGRJL3V6MFVBOVBTWDNNUmVPOWVrREZRZHhoVmljR2FlVnlRWUhUdGdHSm9DODZjbm4rT2pDL1FlekgKWWo2UlM4ZlpNWFpDK2ZjOFkrd21qSE1NZlJvZDZxaDhoNmpDSjN6aE0wRVB6OC84QUtBaWdKNUtwMjhBc0VGRnR5TEthRWpGUXFLdQozUjN5NEc1T0JWaXh3SkFXS3FROUVFQytqMkpqZzZtY2duMHRBdW1ETUh6TEo4bjlIbVlBc0M3VElTK09NeFpzbU8wUXFBZld6SlBQCjI5RnBIT1RLeWVDMm5Pbk9jWEhlYkQ4V3BIaz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDWURDQ0FnZWdBd0lCQWdJTURXcGZDRDhvWEQ1UmxkOWRNQW9HQ0NxR1NNNDlCQU1DTUlHUk1Rc3dDUVlEVlFRR0V3SlZVekVSCk1BOEdBMVVFQ0JNSVNXeHNhVzV2YVhNeEVEQU9CZ05WQkFjVEIwTm9hV05oWjI4eElUQWZCZ05WQkFvVEdGUnlkWE4wZDJGMlpTQkkKYjJ4a2FXNW5jeXdnU1c1akxqRTZNRGdHQTFVRUF4TXhWSEoxYzNSM1lYWmxJRWRzYjJKaGJDQkZRME1nVURJMU5pQkRaWEowYVdacApZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzB4TnpBNE1qTXhPVE0xTVRCYUZ3MDBNakE0TWpNeE9UTTFNVEJhTUlHUk1Rc3dDUVlEClZRUUdFd0pWVXpFUk1BOEdBMVVFQ0JNSVNXeHNhVzV2YVhNeEVEQU9CZ05WQkFjVEIwTm9hV05oWjI4eElUQWZCZ05WQkFvVEdGUnkKZFhOMGQyRjJaU0JJYjJ4a2FXNW5jeXdnU1c1akxqRTZNRGdHQTFVRUF4TXhWSEoxYzNSM1lYWmxJRWRzYjJKaGJDQkZRME1nVURJMQpOaUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJINzdiT1lqCjQzTXlDTXBnNWxPY3VuU05HTEI0a0ZLQTNUakFTaDNScU15VHBKY0dPTW9ORldMR2pnRXFaWjJxM3pTUkxvSEI1RE9TTWNUOUNUcW0KUDYyalF6QkJNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEd1lEVlIwUEFRSC9CQVVEQXdjR0FEQWRCZ05WSFE0RUZnUVVvMEVHckpCdAowVXJyZGFWS0VKbXpzYUdMU3Zjd0NnWUlLb1pJemowRUF3SURSd0F3UkFJZ0IrWlUyZzZnV3JLdUVaK0h4YmIvYWQ0bHZ2aWd0d2p6ClJNNHEzd2doRERjQ0lDMG1BNkFGdld2UjlsejRaY3lHYmJPY05FaGpoQW5GalhjYTRzeWM0WFI3Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRydXN0d2F2ZSBHbG9iYWwgRUNDIFAzODQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ25UQ0NBaVNnQXdJQkFnSU1DTDJGbDJ5Wko2U0FhRWM3TUFvR0NDcUdTTTQ5QkFNRE1JR1JNUXN3Q1FZRFZRUUdFd0pWVXpFUgpNQThHQTFVRUNCTUlTV3hzYVc1dmFYTXhFREFPQmdOVkJBY1RCME5vYVdOaFoyOHhJVEFmQmdOVkJBb1RHRlJ5ZFhOMGQyRjJaU0JJCmIyeGthVzVuY3l3Z1NXNWpMakU2TURnR0ExVUVBeE14VkhKMWMzUjNZWFpsSUVkc2IySmhiQ0JGUTBNZ1VETTROQ0JEWlhKMGFXWnAKWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncweE56QTRNak14T1RNMk5ETmFGdzAwTWpBNE1qTXhPVE0yTkROYU1JR1JNUXN3Q1FZRApWUVFHRXdKVlV6RVJNQThHQTFVRUNCTUlTV3hzYVc1dmFYTXhFREFPQmdOVkJBY1RCME5vYVdOaFoyOHhJVEFmQmdOVkJBb1RHRlJ5CmRYTjBkMkYyWlNCSWIyeGthVzVuY3l3Z1NXNWpMakU2TURnR0ExVUVBeE14VkhKMWMzUjNZWFpsSUVkc2IySmhiQ0JGUTBNZ1VETTQKTkNCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEIyTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQTJJQUJHdmFEWFUxQ0RGSApCYTVGbVZYeEVSTXVTdmdRTVNPamZvUFRmeWdJT2lZYU9zK1hnaCtBdHljSmo5R09NTVFLbXc2c1dBU3I5elo5bENPa213cUtpNnZyCi9Ua2xadkZlL295dWpVRjVuUWxnemlpcDA0cHQ4OVpGMVBLWWhEaGxvS05ETUVFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBUEJnTlYKSFE4QkFmOEVCUU1EQndZQU1CMEdBMVVkRGdRV0JCUlZxWVNKMHNFeXZSakxiS1lIVHNqbm5iNkNrREFLQmdncWhrak9QUVFEQXdObgpBREJrQWpBM0FaS1hSUkorb1BNK3JSazZjdDMwVUpNREVyNUUwazlCcEl5Y25SK2o5c0tTNTBnVS9rNmJwWkZYcnNZM2Nyc0NNR2NsCkNyRU1YdTZwWTVKdjVaQUwvbVlpeWtmOWlqSDNnLzU2dnhDK0dDc2VqL1lwSHBSWjc0NGhOOHRSbUtWdVN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZvakNDQTRxZ0F3SUJBZ0lVQVpRd0hxSUwzZlhGTXlxeFEwUngrTlpRVFEwd0RRWUpLb1pJaHZjTkFRRU1CUUF3YVRFTE1Ba0cKQTFVRUJoTUNTMUl4SmpBa0JnTlZCQW9NSFU1QlZrVlNJRUpWVTBsT1JWTlRJRkJNUVZSR1QxSk5JRU52Y25BdU1USXdNQVlEVlFRRApEQ2xPUVZaRlVpQkhiRzlpWVd3Z1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzB4TnpBNE1UZ3dPRFU0Ck5ESmFGdzB6TnpBNE1UZ3lNelU1TlRsYU1Ha3hDekFKQmdOVkJBWVRBa3RTTVNZd0pBWURWUVFLREIxT1FWWkZVaUJDVlZOSlRrVlQKVXlCUVRFRlVSazlTVFNCRGIzSndMakV5TURBR0ExVUVBd3dwVGtGV1JWSWdSMnh2WW1Gc0lGSnZiM1FnUTJWeWRHbG1hV05oZEdsdgpiaUJCZFhSb2IzSnBkSGt3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQzIxUEdUWExWQWlRcXJEWkJiClVHT3VrSlIwRjBWeTFudGxXaWxMcDFhZ1M3Z3ZRblhwMlhza1dqRmxxeGNYMFRNNjJSSGNRRGFIMzhkcTZTWmVXWXAzNCtoSW5ERVcKK2o2UnNjckpvK0tmemlGVG93STJNTXRTQXVYYU1sM0R4ZWI1N2hISGk4bEVIb1NUR0VxMG4rVVNaR25RSm9WaUFiYkpBaDIrZzFHNwpYTnI0clJWcW1mZVNWUGMwVyttLzZpbUJFdFJUa1phemtWcmQvcEJ6S1Bzd1JyWEtDQWZIY1hMSlp0TTBsL2FNOUJoSzRkQTlXa1cyCmFhY3AreVBPaU5nU25BQklxS1lQc3p1U2pYRU9kTVdMeUV6NTlKdU91RHhwN1c4N1VDOVk3Y1N3MEJ3YmFneml2RVNxMk0wVVhaUjQKWWI4T2J0b3F2QzhNQzNHbXN4WS9uT2I1eko5VE5lSURvS0FZdjd2eHZ2VFdqSWNOUXZjR3VmRnQ3UVNVcVA2MjB3YkdRR0hmblozegpWSGJPVXpvQnBwSkI3QVNqancyaTFRbksxc3VhOGU5RFhjQ3JwVUhQWEZOd2NNbUlwaTNVYTJGelVDYUdZUTVmRzhJcjRvelZ1NTNCCkEwSzZsTnBmcWJES3pFMEs3MGRwQXk4aSsvRW96cjlkVUdXb2tHMnpkTEFJeDZ5bzBlcytuUHhkR29NdUs4dTE4MFNkT3FjWFlaYWkKY2ROd2xoVk50MHh6N2hsY3hWcytRZjZzZFdBN0cyUE9BTjNhQ0pCaXRPVXQ3a2luYXhlWlZMNkhTdU9wWGdSTTZ4QnRWTmJ2OGVqeQpZaGJMZ0d2dFBlMzFIekNscmt2SkUrMktBUUhKdUZGWXdHWTZzV1pMeE5VeEFtTHBkSVFNMjAxR0xRSURBUUFCbzBJd1FEQWRCZ05WCkhRNEVGZ1FVMHArSTM2SE5MTDNzOVRzQkFaTXpKN0xyWUVzd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUIKQWY4d0RRWUpLb1pJaHZjTkFRRU1CUUFEZ2dJQkFETEtnTE9kUFZRRzNkTFNMdkNrQVNFTFowaktiWTdneUtvTnFvMGhWNC9HUG5ySwoyMUhVVXJQVWxvU2xXR0IvNVF1T0gvWGNDaFdCNVR1MnR5SXZDWndURnJGc0REVUliYXRqY3UzY3Z1ekhWK1l3SUhIVzF4REJFMVVCCmpDcEQ1RUh4enpwNlU1TE9vZ01GRFRqZkFyc1FMdGs3MHB0NndLR20rTFV4NXZSMXlibFRtWFZISWxvVUZjZDRHN2FkNlF6NEczYngKaFlUZW9kb1M3NlRpRUpkNmVONE1VWmVvSVVDTGhyME44RjVPU3phN095QWZpa0pXNFFzYXYzdlFJa01zUkl6NzVTcTBiQndjdXBUZwpFMzRoNXByQ3k4VkNaTFFlbEhzSUpjaHh6SWRGVjRYVG55bGlJb05SbHdBWWwzZHFtSkxKZkdCczMyeDlTdVJ3VE1LZXVCMzMwRFRICkQ4ejdwLzhEdnExd2tOb0wzY2h0bDErYWZ3a3lRZjNOb3N4YWJVenlxa24rWnZqcDJEWHJEaWdlN2tndk90QjVDVGg4cGlLQ2s1WFEKQTc2K0FxQUYzU0FpNDI4ZGlEUmd4dVlLdVFsMUMvQUg2R21XTmNmN0k0R09PRG00UlN0RGVLTFJMQlQvRFNoeWNwV2JYZ25iaVVTWQpxcUZKdTNGUzhyLzIveWVoTnErNHRuZUkzVHFrYlpzMGtOd1VYVEMvdCtzWDVJZTNjZENoMTNjVjFFTFg4dk14bVYyYjNSWnRQK29HCkkvaEdvaUx0ay9iZG11WXFoN0dZVlBFaTkydEY0K0tPZGgyYWpjUUdqVGEzRlBPZFZHbTNqanpWcEcyVGdiZXQ5cjFrZThMSmFEbWcKa3B6Tk5JYVJrUHBrVVozKy91dWw5WFhlaWZkeQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUaGF3dGUgU2VydmVyIENBCj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQW55Z0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRUUZBRENCeERFTE1Ba0dBMVVFQmhNQ1drRXhGVEFUQmdOVkJBZ1QKREZkbGMzUmxjbTRnUTJGd1pURVNNQkFHQTFVRUJ4TUpRMkZ3WlNCVWIzZHVNUjB3R3dZRFZRUUtFeFJVYUdGM2RHVWdRMjl1YzNWcwpkR2x1WnlCall6RW9NQ1lHQTFVRUN4TWZRMlZ5ZEdsbWFXTmhkR2x2YmlCVFpYSjJhV05sY3lCRWFYWnBjMmx2YmpFWk1CY0dBMVVFCkF4TVFWR2hoZDNSbElGTmxjblpsY2lCRFFURW1NQ1FHQ1NxR1NJYjNEUUVKQVJZWGMyVnlkbVZ5TFdObGNuUnpRSFJvWVhkMFpTNWoKYjIwd0hoY05PVFl3T0RBeE1EQXdNREF3V2hjTk1qQXhNak14TWpNMU9UVTVXakNCeERFTE1Ba0dBMVVFQmhNQ1drRXhGVEFUQmdOVgpCQWdUREZkbGMzUmxjbTRnUTJGd1pURVNNQkFHQTFVRUJ4TUpRMkZ3WlNCVWIzZHVNUjB3R3dZRFZRUUtFeFJVYUdGM2RHVWdRMjl1CmMzVnNkR2x1WnlCall6RW9NQ1lHQTFVRUN4TWZRMlZ5ZEdsbWFXTmhkR2x2YmlCVFpYSjJhV05sY3lCRWFYWnBjMmx2YmpFWk1CY0cKQTFVRUF4TVFWR2hoZDNSbElGTmxjblpsY2lCRFFURW1NQ1FHQ1NxR1NJYjNEUUVKQVJZWGMyVnlkbVZ5TFdObGNuUnpRSFJvWVhkMApaUzVqYjIwd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFOT2tVRzdJLzFacjVzOWR0dW9NYUhWSG9xckMyb1FsCi9LajBSMUhhaGJVZ2RKU0dIZzkxeWVrSVlmVUdiVEJ1RlJrQzZWTEFZdHRObVo3aWFneEVPTTMrdnVOa0NYREYvckZyS2JZdlNjZzcKMUNjRUpSQ1hMK2VRYmNBb1FwblhURVBldy9VaGJWU2ZYY05ZNGNEazJWdXd1TnkwZTk4Mk9zSzFaaUlTMW9jTkFnTUJBQUdqRXpBUgpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVFQlFBRGdZRUFCL3BNYVZ6N2xjeEc3b1dEVFNFd2pzclpxRzlKCkd1YmFVZU5nY0d5RVlSR2hHc2hJUGxsRGZVK1ZQYUdMdHd0aW1IcDFpdDJJVGs2ZVFOdW96REowdVc4Tnh1T3pSQXZaaW0rYUtadVoKR0NnNzBlTkFLSnBhUE5XMTV5QWJpOHFrcTQzcFVkbmlUQ3hacWRxNXNuVWI5a0x5NzhmeUdQbUp2S1AvaWlNdWNFYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVGhhd3RlIFByZW1pdW0gU2VydmVyIENBCj09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJREp6Q0NBcENnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFRRkFEQ0J6akVMTUFrR0ExVUVCaE1DV2tFeEZUQVRCZ05WQkFnVApERmRsYzNSbGNtNGdRMkZ3WlRFU01CQUdBMVVFQnhNSlEyRndaU0JVYjNkdU1SMHdHd1lEVlFRS0V4UlVhR0YzZEdVZ1EyOXVjM1ZzCmRHbHVaeUJqWXpFb01DWUdBMVVFQ3hNZlEyVnlkR2xtYVdOaGRHbHZiaUJUWlhKMmFXTmxjeUJFYVhacGMybHZiakVoTUI4R0ExVUUKQXhNWVZHaGhkM1JsSUZCeVpXMXBkVzBnVTJWeWRtVnlJRU5CTVNnd0pnWUpLb1pJaHZjTkFRa0JGaGx3Y21WdGFYVnRMWE5sY25abApja0IwYUdGM2RHVXVZMjl0TUI0WERUazJNRGd3TVRBd01EQXdNRm9YRFRJd01USXpNVEl6TlRrMU9Wb3dnYzR4Q3pBSkJnTlZCQVlUCkFscEJNUlV3RXdZRFZRUUlFd3hYWlhOMFpYSnVJRU5oY0dVeEVqQVFCZ05WQkFjVENVTmhjR1VnVkc5M2JqRWRNQnNHQTFVRUNoTVUKVkdoaGQzUmxJRU52Ym5OMWJIUnBibWNnWTJNeEtEQW1CZ05WQkFzVEgwTmxjblJwWm1sallYUnBiMjRnVTJWeWRtbGpaWE1nUkdsMgphWE5wYjI0eElUQWZCZ05WQkFNVEdGUm9ZWGQwWlNCUWNtVnRhWFZ0SUZObGNuWmxjaUJEUVRFb01DWUdDU3FHU0liM0RRRUpBUllaCmNISmxiV2wxYlMxelpYSjJaWEpBZEdoaGQzUmxMbU52YlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQTBqWTIKYW92WHdsdWUyb0ZCWW84NDdra0VWZGJRN3h3YmxSWkg3eGhJTlRwUzlDdHFCbzg3TCtwVzQ2K0dqWjRYOTU2MFpYVUNUZS9MQ2FJaApVZGliMEdmUXVnMlNCaFJ6MUpQTGx5b0FuRnhPREx6NkZWTDg4a1J1MmhGS2JnaWZMeTNqK2FvNmhuTzJSbE5ZeUlrRnZZTVJ1SE0vCnFnZU45RUpONTBDZEhEY0NBd0VBQWFNVE1CRXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUVFGQUFPQmdRQW0KU0N3V3dsajY2QlowREtxcVgxUS84dGZKZUdCZVhtNDNZeUozTm42eUY4UTB1ZlVJaGZ6SkFUai9UYjd5RmtKRDU3dGFSdnZCeGhFZgo4VXF3S0ViSnc4UkNmYno2cTFsdTFiZFJpQkhqcElVWmE0Sk1wQXdTcmVta3JqL3h3MGxsbW96RnlENGx0NVNadTVJeWNRZndobDd0ClVDZW1EYVlqK2J2THBnY1VRZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClZlcmlzaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ1BEQ0NBYVVDRUhDNjVCMFEyU2swdGpqS2V3UE11cjh3RFFZSktvWklodmNOQVFFQ0JRQXdYekVMTUFrR0ExVUVCaE1DVlZNeApGekFWQmdOVkJBb1REbFpsY21sVGFXZHVMQ0JKYm1NdU1UY3dOUVlEVlFRTEV5NURiR0Z6Y3lBeklGQjFZbXhwWXlCUWNtbHRZWEo1CklFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUI0WERUazJNREV5T1RBd01EQXdNRm9YRFRJNE1EZ3dNVEl6TlRrMU9Wb3cKWHpFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBb1REbFpsY21sVGFXZHVMQ0JKYm1NdU1UY3dOUVlEVlFRTEV5NURiR0Z6Y3lBegpJRkIxWW14cFl5QlFjbWx0WVhKNUlFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBCkE0R05BRENCaVFLQmdRREpYRm1lOGh1S0FSUzBFTjhFUU52alY2OXFSVUNQaEF3TDBUUFoyUkhQN2dKWUh5WDNLcWhFQmFyc0F4OTQKZjU2VHVab0FxaU45MXF5Rm9tTkZ4M0luelBSTXhuVngwam52VDBMd2RkOEtrTWFPSUcrWUQvaXNJMTl3S1Rha3lZYm5zWm9neTFPbApoZWM5dm4yYS9pUkZNOXgyRmUwUG9uRmtUR1V1Z1doRnB3SURBUUFCTUEwR0NTcUdTSWIzRFFFQkFnVUFBNEdCQUx0TUVpdlBMQ1lBClR4UVQzYWI3L0FvUmhJenpLQnhua2k5OHRzWDYzL0RvbGJ3ZGoyd3NxRkhNYzlpa3dGUHdUdFltd0hZQlY0R1NYaUh4MGJILzU5QWgKV00xcEYrTkVISndaUkRtSlhOeWNBQTlXalFLWjdhS1FSVXprdXhDa1BmQXlBdzd4enZqb3lWR001bUtmNXAvQWZiZHluTWsyT211ZgpUcWovWkExawotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpWZXJpc2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEQWpDQ0Ftc0NFSDNaL2dmUHFCNjNFSGxuKzZlSk5NWXdEUVlKS29aSWh2Y05BUUVGQlFBd2djRXhDekFKQmdOVkJBWVRBbFZUCk1SY3dGUVlEVlFRS0V3NVdaWEpwVTJsbmJpd2dTVzVqTGpFOE1Eb0dBMVVFQ3hNelEyeGhjM01nTXlCUWRXSnNhV01nVUhKcGJXRnkKZVNCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlU0F0SUVjeU1Ub3dPQVlEVlFRTEV6RW9ZeWtnTVRrNU9DQldaWEpwVTJsbgpiaXdnU1c1akxpQXRJRVp2Y2lCaGRYUm9iM0pwZW1Wa0lIVnpaU0J2Ym14NU1SOHdIUVlEVlFRTEV4WldaWEpwVTJsbmJpQlVjblZ6CmRDQk9aWFIzYjNKck1CNFhEVGs0TURVeE9EQXdNREF3TUZvWERUSTRNRGd3TVRJek5UazFPVm93Z2NFeEN6QUpCZ05WQkFZVEFsVlQKTVJjd0ZRWURWUVFLRXc1V1pYSnBVMmxuYml3Z1NXNWpMakU4TURvR0ExVUVDeE16UTJ4aGMzTWdNeUJRZFdKc2FXTWdVSEpwYldGeQplU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQXRJRWN5TVRvd09BWURWUVFMRXpFb1l5a2dNVGs1T0NCV1pYSnBVMmxuCmJpd2dTVzVqTGlBdElFWnZjaUJoZFhSb2IzSnBlbVZrSUhWelpTQnZibXg1TVI4d0hRWURWUVFMRXhaV1pYSnBVMmxuYmlCVWNuVnoKZENCT1pYUjNiM0pyTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FETVh0RVJYVnhwMEt2VHVXcE1tUjlabURDTwpGb1VnUm0xSFA5U0ZJSVRoYmJQNHBPME04UmNQTy9tbitTWFh3YytFWS9KOFk4K2lSL0xHV3pPT1pFQUVhTUdBdVdRY1JYZkgyRzcxCmxTazhVT2cwMTNnZnFMcHRRNUdWajBWWFhuN0YrOHFrQk92cWx6ZFVNRys3QVVjeU04M2NWNXRrYVdING14MGNpVTljWndJREFRQUIKTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUZGTnpiNWN5NWdabkJXeUFUbDRMazBQWjNCd21jWVFXcFNrVTAxVWJTdXZEVjFBaTJUVAoxKzdlVm1HU1g2YkVIUkJoTnRNc0p6em9LUW01RVdSMHpMVnpueHhJcWJ4aEFlN2lGNllNNDBBSU93N242MFJ6S3ByeGFaTHZjUlRECk9heHhwNUVKYitSeEJyTzZXVmNtZVFEMitBMmlNekFvMUtwWW9KMmRhWkg5Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0Kd3AtY2xpL3dwLWNsaSAyLjYuMCAyMDIyLTAxLTI1VDIzOjU1OjE0KzAwOjAwCmNvbXBvc2VyL2NhLWJ1bmRsZSAxLjMuMSA0YzY3OTE4NmYyYWNhNGFiNmEwZjFiMGI5Y2Y5MjUyZGVjYjQ0ZDBiCmNvbXBvc2VyL2NvbXBvc2VyIDIuMi41IDIyYzQxZWYyNzVjN2JiNjRmYTI4ZmIyYzA4NzFhMzk2NjY4MzJjYjkKY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIgMS4wLjAgYzU0OWQyMzgyOTUzNmYwZDBlOTg0YWFhYmJmMDJhZjkxZjQ0MzIwNwpjb21wb3Nlci9wY3JlIDEuMC4xIDY3YTMyZDdkNmY5ZjU2MGI3MjZhYjI1YTA2MWIzOGZmM2E4MGM1NjAKY29tcG9zZXIvc2VtdmVyIDMuMi43IGRlYWMyNzA1NmI1N2U0NmZhZjEzNmZhZTdiNDQ5ZWVhYTcxNjYxZWUKY29tcG9zZXIvc3BkeC1saWNlbnNlcyAxLjUuNiBhMzBkNDg3MTY5ZDc5OTc0NWNhNzI4MGJjOTBmZGZhNjkzNTM2OTAxCmNvbXBvc2VyL3hkZWJ1Zy1oYW5kbGVyIDIuMC40IDBjMWEzOTI1ZWM1OGE0ZWM5OGU5OTJiOWM3ZDE3MWU5ZTE4NGJlMGEKZ2V0dGV4dC9nZXR0ZXh0IHY0LjguNiBiYmViOGY0ZDMwNzc2NjM3MzlhZWNiNDU1MWIyMmU3MjBjMGU5ZWZlCmdldHRleHQvbGFuZ3VhZ2VzIDIuOS4wIGVkNTZkZDJjN2Y0MDI0Y2M5NTNlZDE4MGQyNWYwMmYyNjQwZTNmZmEKanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYSA1LjIuMTEgMmFiNjc0NGI3Mjk2ZGVkODBmOGNjNGY5NTA5YWJiZmYzOTMzOTlhYQptY2s4OS9wZWFzdCB2MS4xMy4xMSA3OGM1Nzk2NmYzZGE1ZjIyMzYzNmVhMDQxN2Q3MWFjNmZmNjFlNDdmCm11c3RhY2hlL211c3RhY2hlIHYyLjE0LjEgNTc5ZmZhNWM5NmUxZDI5MmMwNjBiM2RkNjI4MTFmZjAxYWQ4YzI0ZQpuYi9veHltZWwgdjAuMS4wIGNiZTYyNmVmNTVkNWM0Y2M5YjVlNmUzOTA0YjM5NTg2MWVhNzZlM2MKcHNyL2xvZyAxLjEuNCBkNDk2OTViOTA5YzNiNzYyOGI2Mjg5ZGI1NDc5YTFjMjA0NjAxZjExCnJlYWN0L3Byb21pc2UgdjIuOC4wIGYzY2ZmOTZhMTk3MzY3MTQ1MjRjYTBkZDFkNDEzMGRlNzNkYmJiYzQKcm1jY3VlL3JlcXVlc3RzIHYxLjguMSA4MmU2OTM2MzY2ZWFjM2FmNGQ4MzZjMThiOWQ4YzMxMDI4ZmU0Y2Q1CnNlbGQvanNvbmxpbnQgMS44LjMgOWFkNmNlNzljMzQyZmJkNDRkZjEwZWE5NTUxMWExYjI0ZGVlNWI1NwpzZWxkL3BoYXItdXRpbHMgMS4yLjAgOWYzNDUyYzkzZmY0MjM0NjljMGQ1NjQ1MDQzMTU2MmNhNDIzZGNlZQpzeW1mb255L2NvbnNvbGUgdjMuNC40NyBhMTBiMWRhNmZjOTMwODBjMTgwYmJhNzIxOWI1ZmY1Yjc1MThmZTgxCnN5bWZvbnkvZGVidWcgdjMuNC40NyBhYjQyODg5ZGU1N2ZkZmNmY2MwNzU5YWIxMDJlMmZkNGVhNzJkY2FlCnN5bWZvbnkvZmlsZXN5c3RlbSB2My40LjQ3IGU1OGQ3ODQxY2RkZmVkNmU4NDY4MjkwNDBkY2EyY2NhMGViYmJiYjMKc3ltZm9ueS9maW5kZXIgdjMuNC40NyBiNmI2YWQzZGIzZWRiMWI0YjFjMTg5NmIxOTc1ZmI2ODQ5OTRkZTZlCnN5bWZvbnkvcG9seWZpbGwtY3R5cGUgdjEuMTkuMCBhZWQ1OTY5MTNiNzBmYWU1N2JlNTNkODZmYWEyZTllZjg1YTIyOTdiCnN5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcgdjEuMTkuMCBiNWY3YjkzMmVlNmZhODAyZmM3OTJlYWJkNzdjNGM4ODA4NDUxN2NlCnN5bWZvbnkvcHJvY2VzcyB2My40LjQ3IGI4NjQ4Y2YxZDVhZjEyYTQ0YTUxZDA3ZWY5YmY5ODA5MjFmMTVmY2EKd3AtY2xpL2NhY2hlLWNvbW1hbmQgdjIuMC45IDA1Mzc4NDQwZDhjNmQ0ZDJhMWE1ZTVjYmMxYmE5MmE1ZTRiZjFjNDAKd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQgdjIuMS4yIGVjNTlhMjRhZjJjYTk3Yjc3MGE0NzA5YjBhMWMyNDFlZWI0YjRjZmYKd3AtY2xpL2NvbmZpZy1jb21tYW5kIHYyLjEuMyBjZGFiYmM0N2RhZTQ2NGE5M2IxMDM2MWI5YTE4ZTg0Y2Y0ZTcyZmUyCndwLWNsaS9jb3JlLWNvbW1hbmQgdjIuMS4xIGE3NWQwNTJlYTAwMGI0ZjBlYzE0MTA2YzExMDgzNmIzNzZlOTVhNGYKd3AtY2xpL2Nyb24tY29tbWFuZCB2Mi4xLjAgYmI5ZmQ5NjQ1ZTlhNTI3NmQwMjRhNTlhZmZlZGEzZTZhYTg1MzBiZQp3cC1jbGkvZGItY29tbWFuZCB2Mi4wLjIwIDcwOWY1OGMzMGQxNzhhZmNkZWNhZjU2MDY4Y2E5ZjVlOTg1ZWQ2YjkKd3AtY2xpL2VtYmVkLWNvbW1hbmQgdjIuMC4xMSAwMGE5MDFhNjZhZWNiNGRhOTRhOGRhY2U2MTBlYjExMzVmYzgyMzg2CndwLWNsaS9lbnRpdHktY29tbWFuZCB2Mi4yLjEgZDdkMDhiMDVjNjc2NTFhYmRlNWQ1NzA4NTFlNDY0OThhMTY0Y2IzNAp3cC1jbGkvZXZhbC1jb21tYW5kIHYyLjEuMiA1MjEzMDQwZWMyMTY3YjI3NDhmMjY4OWZmNmZlMjRiOTJhMDY0YTkwCndwLWNsaS9leHBvcnQtY29tbWFuZCB2Mi4wLjExIDhkZDEzN2UwYzczOWE1OWJiM2QzZGU2ODRhMjE5ZGJiMzQ0NzNlMTEKd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kIHYyLjEuNCA2NDAxZDdlYTUxMDg0ZmFjNDAwMTBjMmZiMzA1YmU2NDA2NzVmMzg1CndwLWNsaS9pMThuLWNvbW1hbmQgdjIuMi4xMyA3N2VjZTllMmM5MTRiYjU2ZWE3MmI5ZWU5ZjAwNTU2ZGVjZTA3YjNmCndwLWNsaS9pbXBvcnQtY29tbWFuZCB2Mi4wLjggYTA5MmUzYWJjY2E4NDNmMWZhYmYyZTliNzA2YTkxMmFlMDc1MzU1Zgp3cC1jbGkvbGFuZ3VhZ2UtY29tbWFuZCB2Mi4wLjEyIGJiZGJhNjkxNzlmYzhkZjU5NzkyODU4NzExMTUwMGM4YWRlNDBhMzgKd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZCB2Mi4wLjggZTY1NTA1Yzk3M2VhOTM0OTI1N2E0ZjMzYWM5ZWRjNzhkYjBiMTg5YQp3cC1jbGkvbWVkaWEtY29tbWFuZCB2Mi4wLjEyIDdjYmYzMmM3ZmE2ODYzMTYxOWY4NWE5YmVhMGZiODBmY2ExMTliYTYKd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5YyAwLjYuMyA2YWEwYjRkYTY5Y2U5ZTlhMmM4NDAyZGFiOGQ0M2NmMzJjNTgxY2M3CndwLWNsaS9wYWNrYWdlLWNvbW1hbmQgdjIuMi4yIDM2YWZkZWUyMWQwMjJlNjI3MDg2N2FhMGNiZmVmNmY0NTMwNDE4MTQKd3AtY2xpL3BocC1jbGktdG9vbHMgdjAuMTEuMTMgYTI4NjY4NTVhYzFhYmM1MzAwNWMxMDJlOTAxNTUzYWQ1NzcyZGMwNAp3cC1jbGkvcmV3cml0ZS1jb21tYW5kIHYyLjAuMTAgNTYyYTBhNWEwZDUxYmUwMDBkZTg3ZDdhOGE4NzBkZTEzMzgzZWNkNgp3cC1jbGkvcm9sZS1jb21tYW5kIHYyLjAuOSA5YWJkOTM5NTI1NjU5MzUwODQxNjBiYzNiZTQ5ZGZiMjQ4M2JiMGI2CndwLWNsaS9zY2FmZm9sZC1jb21tYW5kIHYyLjAuMTYgNmQ5MmZiMzYzYjhlZDc0NzNhZjdmMTJjZjM0MmFhZjlkMmM5NmU4MQp3cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZCB2Mi4wLjE2IGRiZjIxNTYwZmQ5MTcxMGIyOTAwZjU2MzE0NDg2NTdkMjhmMmIzODAKd3AtY2xpL3NlcnZlci1jb21tYW5kIHYyLjAuMTAgNTBjODFmNDVmMWNmMDliYzBhNTJlMzU4MmIzZTU2ZDI3Y2EzYzMzYwp3cC1jbGkvc2hlbGwtY29tbWFuZCB2Mi4wLjExIDI4YTdkZTMxMzRjOWYwNTk5MDBkOGZhNGFlYTFkN2Q2MTg0ODE0NTQKd3AtY2xpL3N1cGVyLWFkbWluLWNvbW1hbmQgdjIuMC4xMCBlNjcwN2YzYWNmZmYwODlkMTljNWM1NWJiYTBmZDY2Y2Q3ZDZjMmZhCndwLWNsaS93aWRnZXQtY29tbWFuZCB2Mi4xLjcgNmFlZGFiNzdmMWNkMmEwZjUxMWI2MjExMGMyNDRjMzJiODRkZDQyOQp3cC1jbGkvd3AtY2xpIHYyLjYuMCBkZWUxM2MyYmFmNmJmOTcyNDg0YTYzZjhiOGRhYjQ4ZjcyMjBmMDk1CndwLWNsaS93cC1jb25maWctdHJhbnNmb3JtZXIgdjEuMy4wIDJlOTBlZWZjNmI4ZjUxNjZmNTNhYTU0MTRmZDhmMWE1NzIxNjRlZjEyLjYuMEgUwCNlv06RJ0m/N6WSNgrl0xihAgAAAEdCTUI=
Base64 mode: content will be decoded on save.
Save
Close
Exit & Reset
Directory Contents
Dirs: 0 × Files: 2
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
wp
6.19 MB
lrwxr-xr-x
2022-04-29 13:44:56
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
wpfix
9.46 KB
lrwxr-xr-x
2022-04-29 13:44:56
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).